diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7a1b66ba0ae7..cbc1c9cb2c57 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -5,14 +5,12 @@ /airbyte-integrations/connectors/destination-qdrant @airbytehq/ai-language-models /airbyte-integrations/connectors/destination-chroma @airbytehq/ai-language-models /airbyte-integrations/connectors/destination-snowflake-cortex @airbytehq/ai-language-models -/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based @airbytehq/ai-language-models # CI/CD /.github/ @airbytehq/dev-tooling /airbyte-ci/ @airbytehq/dev-tooling # Python CDK and Connector Acceptance Tests -/airbyte-cdk/python @airbytehq/python-team /airbyte-integrations/connector-templates/ @airbytehq/dev-marketplace-contributions /airbyte-integrations/bases/connector-acceptance-test/ @airbytehq/dev-tooling @@ -23,27 +21,27 @@ /docs/understanding-airbyte/airbyte-protocol.md @airbytehq/protocol-reviewers # Bulk CDK -/airbyte-cdk/bulk @airbytehq/dbsources @airbytehq/destinations +/airbyte-cdk/bulk @airbytehq/dbsources @airbytehq/move-destinations /airbyte-cdk/bulk/core/extract/ @airbytehq/dbsources -/airbyte-cdk/bulk/core/load/ @airbytehq/destinations +/airbyte-cdk/bulk/core/load/ @airbytehq/move-destinations /airbyte-cdk/bulk/toolkits/extract-*/ @airbytehq/dbsources -/airbyte-cdk/bulk/toolkits/load-*/ @airbytehq/destinations +/airbyte-cdk/bulk/toolkits/load-*/ @airbytehq/move-destinations # Java CDK -/airbyte-cdk/java/airbyte-cdk @airbytehq/dbsources @airbytehq/destinations +/airbyte-cdk/java/airbyte-cdk @airbytehq/dbsources @airbytehq/move-destinations /airbyte-cdk/java/airbyte-cdk/*-sources/ @airbytehq/dbsources -/airbyte-cdk/java/airbyte-cdk/*-destinations/ @airbytehq/destinations -/airbyte-cdk/java/airbyte-cdk/typing-deduping/ @airbytehq/destinations +/airbyte-cdk/java/airbyte-cdk/*-destinations/ @airbytehq/move-destinations +/airbyte-cdk/java/airbyte-cdk/typing-deduping/ @airbytehq/move-destinations # Java connectors catch-all -/buildSrc/ @airbytehq/dbsources @airbytehq/destinations +/buildSrc/ @airbytehq/dbsources @airbytehq/move-destinations /airbyte-integrations/connectors/source-*/**/*.java @airbytehq/dbsources /airbyte-integrations/connectors/source-*/**/*.kt @airbytehq/dbsources /airbyte-integrations/connectors/source-*/**/*.gradle @airbytehq/dbsources /airbyte-integrations/connectors-performance/source-harness/ @airbytehq/dbsources -/airbyte-integrations/connectors/destination-*/**/*.java @airbytehq/destinations -/airbyte-integrations/connectors/destination-*/**/*.kt @airbytehq/destinations -/airbyte-integrations/connectors/destination-*/**/*.gradle @airbytehq/destinations +/airbyte-integrations/connectors/destination-*/**/*.java @airbytehq/move-destinations +/airbyte-integrations/connectors/destination-*/**/*.kt @airbytehq/move-destinations +/airbyte-integrations/connectors/destination-*/**/*.gradle @airbytehq/move-destinations /airbyte-integrations/connectors-performance/destination-harness/ @airbytehq/dbsources # Java-based certified or incubating source connectors @@ -53,12 +51,12 @@ /airbyte-integrations/connectors/source-postgres/ @airbytehq/dbsources # Java-based certified or incubating destination connectors -/airbyte-integrations/connectors/destination-bigquery/ @airbytehq/destinations -/airbyte-integrations/connectors/destination-postgres/ @airbytehq/destinations -/airbyte-integrations/connectors/destination-postgres-strict-encrypt/ @airbytehq/destinations -/airbyte-integrations/connectors/destination-s3/ @airbytehq/destinations -/airbyte-integrations/connectors/destination-snowflake/ @airbytehq/destinations -/airbyte-integrations/connectors/destination-redshift/ @airbytehq/destinations +/airbyte-integrations/connectors/destination-bigquery/ @airbytehq/move-destinations +/airbyte-integrations/connectors/destination-postgres/ @airbytehq/move-destinations +/airbyte-integrations/connectors/destination-postgres-strict-encrypt/ @airbytehq/move-destinations +/airbyte-integrations/connectors/destination-s3/ @airbytehq/move-destinations +/airbyte-integrations/connectors/destination-snowflake/ @airbytehq/move-destinations +/airbyte-integrations/connectors/destination-redshift/ @airbytehq/move-destinations # Python critical connectors /airbyte-integrations/connectors/source-facebook-marketing/ @airbytehq/python-team diff --git a/.github/actions/install-airbyte-ci/action.yml b/.github/actions/install-airbyte-ci/action.yml index d0563331c805..f7646aa7e568 100644 --- a/.github/actions/install-airbyte-ci/action.yml +++ b/.github/actions/install-airbyte-ci/action.yml @@ -30,21 +30,26 @@ runs: - name: "Determine how Airbyte CI should be installed" shell: bash id: determine-install-mode - # When the PR is from a fork, we always install from binary - if: inputs.is_fork == 'false' run: | - if [[ "${{ github.ref }}" != "refs/heads/master" ]] && [[ "${{ steps.changes.outputs.pipelines_any_changed }}" == "true" ]]; then - echo "Making changes to Airbyte CI on a non-master branch. Airbyte-CI will be installed from source." - echo "install-mode=source" >> $GITHUB_OUTPUT - echo "SENTRY_ENVIRONMENT=dev" >> $GITHUB_ENV - else - echo "install-mode=binary" >> $GITHUB_OUTPUT - echo "SENTRY_ENVIRONMENT=production" >> $GITHUB_ENV - fi + echo "install-mode=source" >> $GITHUB_OUTPUT + echo "SENTRY_ENVIRONMENT=dev" >> $GITHUB_ENV + + # When the PR is from a fork, we always install from binary + # if: inputs.is_fork == 'false' + # run: | + # if [[ "${{ github.ref }}" != "refs/heads/master" ]] && [[ "${{ steps.changes.outputs.pipelines_any_changed }}" == "true" ]]; then + # echo "Making changes to Airbyte CI on a non-master branch. Airbyte-CI will be installed from source." + # echo "install-mode=source" >> $GITHUB_OUTPUT + # echo "SENTRY_ENVIRONMENT=dev" >> $GITHUB_ENV + # else + # echo "install-mode=binary" >> $GITHUB_OUTPUT + # echo "SENTRY_ENVIRONMENT=production" >> $GITHUB_ENV + # fi - name: Install Airbyte CI from binary id: install-airbyte-ci-binary - if: steps.determine-install-mode.outputs.install-mode == 'binary' || ${{ inputs.is_fork }} == 'true' + if: false + # if: steps.determine-install-mode.outputs.install-mode == 'binary' || ${{ inputs.is_fork }} == 'true' shell: bash run: | curl -sSL ${{ inputs.airbyte_ci_binary_url }} --output airbyte-ci-bin @@ -54,14 +59,15 @@ runs: - name: Install Python 3.10 id: install-python-3-10 uses: actions/setup-python@v4 - if: steps.determine-install-mode.outputs.install-mode == 'source' + # if: steps.determine-install-mode.outputs.install-mode == 'source' with: python-version: "3.10" token: ${{ inputs.github_token }} - name: Install Airbyte CI from source id: install-airbyte-ci-source - if: steps.determine-install-mode.outputs.install-mode == 'source' + if: true + # if: steps.determine-install-mode.outputs.install-mode == 'source' shell: bash run: | pip install --upgrade pip @@ -69,6 +75,11 @@ runs: pipx ensurepath pipx install ${{ inputs.path_to_airbyte_ci_source }} + - name: Print installed `airbyte-ci` version + shell: bash + run: | + airbyte-ci --version + - name: Get dagger engine image name id: get-dagger-engine-image-name shell: bash diff --git a/.github/actions/run-airbyte-ci/action.yml b/.github/actions/run-airbyte-ci/action.yml index d87c3cad0068..a030a6573aa5 100644 --- a/.github/actions/run-airbyte-ci/action.yml +++ b/.github/actions/run-airbyte-ci/action.yml @@ -107,6 +107,15 @@ runs: id: get-start-timestamp shell: bash run: echo "start-timestamp=$(date +%s)" >> $GITHUB_OUTPUT + - name: Debug-print local paths checked out + shell: bash + run: | + set -x + echo "Working directory: $(pwd)" + ls -la + ls -la airbyte-python-cdk || echo "No airbyte-python-cdk directory" + ls -laL ../airbyte-python-cdk || echo "No airbyte-python-cdk symlink" + - name: Docker login id: docker-login uses: docker/login-action@v3 @@ -186,11 +195,17 @@ runs: shell: bash run: tar cvzf ./dagger_engine_logs.tgz ./dagger_engine_logs + - name: Hash subcommand + id: hash-subcommand + shell: bash + if: always() + run: echo "subcommand_hash=$(echo ${{ inputs.subcommand }} | sha256sum | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT + - name: Upload logs to GitHub id: upload-dagger-engine-logs if: always() uses: actions/upload-artifact@v4 with: - name: ${{ github.job }}_dagger_engine_logs.tgz + name: ${{ github.job }}_${{ steps.hash-subcommand.outputs.subcommand_hash }}_dagger_engine_logs.tgz path: ./dagger_engine_logs.tgz retention-days: 7 diff --git a/.github/workflows/airbyte-ci-release.yml b/.github/workflows/airbyte-ci-release.yml index 026d54801b95..f95d47be56d9 100644 --- a/.github/workflows/airbyte-ci-release.yml +++ b/.github/workflows/airbyte-ci-release.yml @@ -43,6 +43,8 @@ jobs: - name: Install Poetry id: install_poetry uses: snok/install-poetry@v1 + with: + version: 1.8.5 - name: Install Dependencies id: install_dependencies @@ -87,7 +89,7 @@ jobs: if: github.ref == 'refs/heads/master' working-directory: airbyte-ci/connectors/pipelines/ run: | - echo "::set-output name=version::$(poetry version --short)" + echo "version=$(poetry version --short)" >> $GITHUB_OUTPUT - name: Authenticate to Google Cloud Prod id: auth_prod diff --git a/.github/workflows/airbyte-ci-tests.yml b/.github/workflows/airbyte-ci-tests.yml index 91ba110ad681..90320ef96763 100644 --- a/.github/workflows/airbyte-ci-tests.yml +++ b/.github/workflows/airbyte-ci-tests.yml @@ -17,7 +17,7 @@ on: - synchronize jobs: changes: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 outputs: internal_poetry_packages: ${{ steps.changes.outputs.internal_poetry_packages }} @@ -42,7 +42,6 @@ jobs: - airbyte-ci/connectors/erd/** - airbyte-ci/connectors/metadata_service/lib/** - airbyte-ci/connectors/metadata_service/orchestrator/** - - airbyte-cdk/python/** - airbyte-integrations/bases/connector-acceptance-test/** run-tests: @@ -60,6 +59,25 @@ jobs: with: fetch-depth: 0 ref: ${{ github.event.pull_request.head.ref }} + - name: Checkout Airbyte Python CDK + uses: actions/checkout@v4 + with: + repository: airbytehq/airbyte-python-cdk + ref: main + # We can't clone into a parent directory of the repo, so we clone into + # a subdirectory and then move it over as a sibling directory. + # This will be used for the `--use-local-cdk` flag in `airbyte-ci` command + path: airbyte-python-cdk + - name: Move airbyte-python-cdk to sibling directory path + shell: bash + run: mv ./airbyte-python-cdk ../airbyte-python-cdk + - name: Show local paths checked out + shell: bash + run: | + set -x + echo "Current directory: $(pwd)" + ls -la + ls -la ../airbyte-python-cdk || echo "No airbyte-python-cdk directory" - name: Extract branch name [WORKFLOW DISPATCH] shell: bash diff --git a/.github/workflows/approve-and-merge-dispatch.yml b/.github/workflows/approve-and-merge-dispatch.yml index b723f9337c51..85df84d35ea5 100644 --- a/.github/workflows/approve-and-merge-dispatch.yml +++ b/.github/workflows/approve-and-merge-dispatch.yml @@ -4,7 +4,7 @@ on: types: [created] jobs: approveAndMergeDispatch: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Auto Approve Slash Command Dispatch uses: peter-evans/slash-command-dispatch@v3 diff --git a/.github/workflows/approve-regression-tests-command.yml b/.github/workflows/approve-regression-tests-command.yml index f3701cba3e20..e2d0521c3b8b 100644 --- a/.github/workflows/approve-regression-tests-command.yml +++ b/.github/workflows/approve-regression-tests-command.yml @@ -31,7 +31,7 @@ run-name: "Approve Regression Tests #${{ github.event.inputs.pr }}" jobs: approve-regression-tests: name: "Approve Regression Tests" - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Get job variables id: job-vars diff --git a/.github/workflows/assign-issue-to-project.yaml b/.github/workflows/assign-issue-to-project.yaml index 736ae88d1534..40f39964ef13 100644 --- a/.github/workflows/assign-issue-to-project.yaml +++ b/.github/workflows/assign-issue-to-project.yaml @@ -9,7 +9,7 @@ env: jobs: assign_one_project: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 name: Assign to Airbyte Github Project steps: - name: Assign documentation issues to the Documentation Roadmap project diff --git a/.github/workflows/auto_merge.yml b/.github/workflows/auto_merge.yml index 5df20ff06c9f..7183b21d3386 100644 --- a/.github/workflows/auto_merge.yml +++ b/.github/workflows/auto_merge.yml @@ -8,7 +8,7 @@ on: jobs: run_auto_merge: name: Run auto-merge - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@v4 @@ -18,6 +18,8 @@ jobs: python-version: "3.10" - name: Install and configure Poetry uses: snok/install-poetry@v1 + with: + version: 1.8.5 - name: Run auto merge shell: bash working-directory: airbyte-ci/connectors/auto_merge diff --git a/.github/workflows/bump-version-command.yml b/.github/workflows/bump-version-command.yml index a558cb5519a3..9734aa426923 100644 --- a/.github/workflows/bump-version-command.yml +++ b/.github/workflows/bump-version-command.yml @@ -41,7 +41,7 @@ concurrency: jobs: bump-version: name: "Bump version of connectors in this PR" - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Get job variables id: job-vars @@ -100,7 +100,7 @@ jobs: - name: Check for changes id: git-diff run: | - git diff --quiet && echo "No changes to commit" || echo "::set-output name=changes::true" + git diff --quiet && echo "No changes to commit" || echo "changes=true" >> $GITHUB_OUTPUT shell: bash # Commit changes (if any) diff --git a/.github/workflows/cdk_connectors_tests.yml b/.github/workflows/cdk_connectors_tests.yml deleted file mode 100644 index ca64ddf3f610..000000000000 --- a/.github/workflows/cdk_connectors_tests.yml +++ /dev/null @@ -1,95 +0,0 @@ -name: CDK Changes - Connectors Tests - -concurrency: - # This is the name of the concurrency group. It is used to prevent concurrent runs of the same workflow. - # - # - github.head_ref is only defined on PR runs, it makes sure that the concurrency group is unique for pull requests - # ensuring that only one run per pull request is active at a time. - # - # - github.run_id is defined on all runs, it makes sure that the concurrency group is unique for workflow dispatches. - # This allows us to run multiple workflow dispatches in parallel. - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -on: - workflow_dispatch: - pull_request: - types: - - opened - - synchronize -jobs: - cdk_changes: - runs-on: ubuntu-latest - outputs: - python_cdk: ${{ steps.changes.outputs.python_cdk }} - permissions: - statuses: write - steps: - - name: Checkout Airbyte - if: github.event_name != 'pull_request' - uses: actions/checkout@v4 - - id: changes - uses: dorny/paths-filter@v2 - with: - filters: | - python_cdk: - - 'airbyte-cdk/python/airbyte_cdk/**' - - 'airbyte-cdk/python/bin/**' - - 'airbyte-cdk/python/poetry.lock' - - 'airbyte-cdk/python/pyproject.toml' - # The Connector CI Tests is a status check emitted by airbyte-ci - # We make it pass once we have determined that there are no changes to the connectors - - name: "Skip Connectors CI tests" - if: steps.changes.outputs.python_cdk != 'true' && github.event_name == 'pull_request' - run: | - curl --request POST \ - --url https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.event.pull_request.head.sha }} \ - --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \ - --header 'content-type: application/json' \ - --data '{ - "state": "success", - "context": "CDK Changes - Connectors Tests", - "target_url": "${{ github.event.workflow_run.html_url }}" - }' \ - - connectors_ci: - needs: cdk_changes - # We only run the Connectors CI job if there are changes to the connectors on a non-forked PR - # Forked PRs are handled by the community_ci.yml workflow - # If the condition is not met the job will be skipped (it will not fail) - if: (github.event_name == 'pull_request' && needs.cdk_changes.outputs.python_cdk == 'true' && github.event.pull_request.head.repo.fork != true) || github.event_name == 'workflow_dispatch' - name: Connectors CI - runs-on: connector-test-large - timeout-minutes: 360 # 6 hours - steps: - - name: Checkout Airbyte - uses: actions/checkout@v4 - - name: Check PAT rate limits - run: | - ./tools/bin/find_non_rate_limited_PAT \ - ${{ secrets.GH_PAT_MAINTENANCE_OSS }} - - name: Fetch last commit id from remote branch [PULL REQUESTS] - if: github.event_name == 'pull_request' - id: fetch_last_commit_id_pr - run: echo "commit_id=$(git ls-remote --heads origin refs/heads/${{ github.head_ref }} | cut -f 1)" >> $GITHUB_OUTPUT - - name: Fetch last commit id from remote branch [WORKFLOW DISPATCH] - if: github.event_name == 'workflow_dispatch' - id: fetch_last_commit_id_wd - run: echo "commit_id=$(git rev-parse origin/${{ steps.extract_branch.outputs.branch }})" >> $GITHUB_OUTPUT - - name: Test connectors - uses: ./.github/actions/run-airbyte-ci - with: - context: ${{ github.event_name == 'pull_request' && 'pull_request' || 'manual' }} - dagger_cloud_token: ${{ secrets.DAGGER_CLOUD_TOKEN_CACHE_5 }} - docker_hub_password: ${{ secrets.DOCKER_HUB_PASSWORD }} - docker_hub_username: ${{ secrets.DOCKER_HUB_USERNAME }} - gcp_gsm_credentials: ${{ secrets.GCP_GSM_CREDENTIALS }} - sentry_dsn: ${{ secrets.SENTRY_AIRBYTE_CI_DSN }} - git_branch: ${{ github.head_ref }} - git_revision: ${{ github.event_name == 'pull_request' && steps.fetch_last_commit_id_pr.outputs.commit_id || steps.fetch_last_commit_id_wd.outputs.commit_id }} - github_token: ${{ env.PAT }} - gcp_integration_tester_credentials: ${{ secrets.GCLOUD_INTEGRATION_TESTER }} - s3_build_cache_access_key_id: ${{ secrets.SELF_RUNNER_AWS_ACCESS_KEY_ID }} - s3_build_cache_secret_key: ${{ secrets.SELF_RUNNER_AWS_SECRET_ACCESS_KEY }} - # A connector test can't take more than 5 hours to run (5 * 60 * 60 = 18000 seconds) - subcommand: "connectors --use-local-cdk --name source-shopify --name source-zendesk-support --execute-timeout=18000 test --global-status-check-context='CDK Changes - Connectors Tests'" diff --git a/.github/workflows/community_ci.yml b/.github/workflows/community_ci.yml index 5214fa1ad5da..2aa16dce58a5 100644 --- a/.github/workflows/community_ci.yml +++ b/.github/workflows/community_ci.yml @@ -19,7 +19,7 @@ jobs: fail_on_protected_path_changes: name: "Check fork do not change protected paths" if: github.event.pull_request.head.repo.fork == true - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 permissions: pull-requests: read steps: @@ -37,45 +37,6 @@ jobs: echo "The fork has changes in protected paths. This is not allowed." exit 1 - format_check: - # IMPORTANT: This name must match the require check name on the branch protection settings - name: "Check for formatting errors" - if: github.event.pull_request.head.repo.fork == true - environment: community-ci-auto - runs-on: community-tooling-test-small - needs: fail_on_protected_path_changes - timeout-minutes: 30 - env: - MAIN_BRANCH_NAME: "master" - steps: - # This checkouts a fork which can contain untrusted code - # It's deemed safe as the formatter are not executing any checked out code - - name: Checkout fork - uses: actions/checkout@v4 - with: - repository: ${{ github.event.pull_request.head.repo.full_name }} - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 1 - - # This will sync the .github folder of the main repo with the fork - # This allows us to use up to date actions and CI logic from the main repo - - name: Pull .github folder and internal packages from main repository - id: pull_github_folder - run: | - git remote add main https://github.com/airbytehq/airbyte.git - git fetch main ${MAIN_BRANCH_NAME} - git checkout main/${MAIN_BRANCH_NAME} -- .github - git checkout main/${MAIN_BRANCH_NAME} -- airbyte-ci - - - name: Run airbyte-ci format check all - # This path refers to the fork .github folder. - # We make sure its content is in sync with the main repo .github folder by pulling it in the previous step - uses: ./.github/actions/run-airbyte-ci - with: - context: "pull_request" - sentry_dsn: ${{ secrets.SENTRY_AIRBYTE_CI_DSN }} - subcommand: "format check all" - is_fork: "true" connectors_early_ci: name: Run connectors early CI on fork if: github.event.pull_request.head.repo.fork == true diff --git a/.github/workflows/connector-performance-command.yml b/.github/workflows/connector-performance-command.yml index 135d52b0b042..22e74c29bf9e 100644 --- a/.github/workflows/connector-performance-command.yml +++ b/.github/workflows/connector-performance-command.yml @@ -92,7 +92,7 @@ jobs: uuid: name: "Custom UUID of workflow run" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: UUID ${{ inputs.uuid }} run: true @@ -100,7 +100,7 @@ jobs: name: Start Build EC2 Runner needs: uuid timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 outputs: label: ${{ steps.start-ec2-runner.outputs.label }} ec2-instance-id: ${{ steps.start-ec2-runner.outputs.ec2-instance-id }} @@ -262,7 +262,7 @@ jobs: - start-test-runner # required to get output from the start-runner job - performance-test # required to wait when the main job is done - uuid - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 if: ${{ always() }} # required to stop the runner even if the error happened in the previous jobs steps: - name: Configure AWS credentials diff --git a/.github/workflows/connector_code_freeze.yml b/.github/workflows/connector_code_freeze.yml index 03d3bce37a8f..dc7832acc0ce 100644 --- a/.github/workflows/connector_code_freeze.yml +++ b/.github/workflows/connector_code_freeze.yml @@ -18,7 +18,7 @@ env: CODE_FREEZE_END_DATE: "2024-01-02" jobs: code-freeze-check: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 name: Code freeze check permissions: # This is required to be able to comment on PRs and list changed files @@ -35,10 +35,10 @@ jobs: if [ "$current_date" -ge "$start_date" ] && [ "$current_date" -le "$end_date" ]; then echo "Code freeze is in effect" - echo "::set-output name=is_in_code_freeze::true" + echo "is_in_code_freeze=true" >> $GITHUB_OUTPUT else echo "Code freeze is not in effect" - echo "::set-output name=is_in_code_freeze::false" + echo "is_in_code_freeze=false" >> $GITHUB_OUTPUT fi # Use GitHub PR Api to get the list of changed files diff --git a/.github/workflows/connector_teams_review_requirements.yml b/.github/workflows/connector_teams_review_requirements.yml index 201b0164b014..f2238db2243e 100644 --- a/.github/workflows/connector_teams_review_requirements.yml +++ b/.github/workflows/connector_teams_review_requirements.yml @@ -17,7 +17,7 @@ on: jobs: check-review-requirements: name: "Check if a review is required from Connector teams" - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 if: ${{ github.event.pull_request.head.repo.fork == false && github.event.pull_request.draft == false }} steps: diff --git a/.github/workflows/connectors_insights.yml b/.github/workflows/connectors_insights.yml index fd6f3897375b..475b757304aa 100644 --- a/.github/workflows/connectors_insights.yml +++ b/.github/workflows/connectors_insights.yml @@ -31,6 +31,7 @@ jobs: - name: Install Poetry uses: snok/install-poetry@v1 with: + version: 1.8.5 virtualenvs-create: true virtualenvs-in-project: true installer-parallel: true diff --git a/.github/workflows/connectors_tests.yml b/.github/workflows/connectors_tests.yml index f31ca6d88e29..1262e36b85c1 100644 --- a/.github/workflows/connectors_tests.yml +++ b/.github/workflows/connectors_tests.yml @@ -23,7 +23,7 @@ on: - synchronize jobs: changes: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 outputs: connectors: ${{ steps.changes.outputs.connectors }} permissions: @@ -78,7 +78,7 @@ jobs: # If the condition is not met the job will be skipped (it will not fail) if: (github.event_name == 'pull_request' && needs.changes.outputs.connectors == 'true' && github.event.pull_request.head.repo.fork != true) || github.event_name == 'workflow_dispatch' name: Connectors CI - runs-on: connector-test-large + runs-on: linux-20.04-large # Custom runner, defined in GitHub org settings timeout-minutes: 360 # 6 hours steps: - name: Checkout Airbyte diff --git a/.github/workflows/connectors_up_to_date.yml b/.github/workflows/connectors_up_to_date.yml index 4e16eaf02ef6..49a812fdc7b8 100644 --- a/.github/workflows/connectors_up_to_date.yml +++ b/.github/workflows/connectors_up_to_date.yml @@ -11,22 +11,51 @@ on: inputs: connectors-options: description: "Options to pass to the 'airbyte-ci connectors' command group." - default: '--concurrency=10 --language=python --language=low-code --language=manifest-only --metadata-query="''-rc.'' not in data.dockerImageTag" --metadata-query="''source-declarative-manifest'' not in data.dockerRepository"' - auto-merge: - description: "Whether to auto-merge the PRs created by the action." - default: "false" + default: "--language=python --language=low-code --language=manifest-only" jobs: - connectors_up_to_date: + generate_matrix: + name: Generate matrix + runs-on: ubuntu-24.04 + outputs: + generated_matrix: ${{ steps.generate_matrix.outputs.generated_matrix }} + steps: + - name: Checkout Airbyte + uses: actions/checkout@v4 + - name: Run airbyte-ci connectors list [SCHEDULED TRIGGER] + if: github.event_name == 'schedule' + id: airbyte-ci-connectors-list-scheduled + uses: ./.github/actions/run-airbyte-ci + with: + context: "master" + subcommand: 'connectors --language=python --language=low-code --language=manifest-only --metadata-query="\"-rc.\" not in data.dockerImageTag and \"source-declarative-manifest\" not in data.dockerRepository" list --output=selected_connectors.json' + - name: Run airbyte-ci connectors list [MANUAL TRIGGER] + if: github.event_name == 'workflow_dispatch' + id: airbyte-ci-connectors-list-workflow-dispatch + uses: ./.github/actions/run-airbyte-ci + with: + context: "master" + subcommand: 'connectors ${{ github.event.inputs.connectors-options }} --metadata-query="\"-rc.\" not in data.dockerImageTag and \"source-declarative-manifest\" not in data.dockerRepository" list --output=selected_connectors.json' + # We generate a dynamic matrix from the list of selected connectors. + # A matrix is required in this situation because the number of connectors is large and running them all in a single job would exceed the maximum job time limit of 6 hours. + - name: Generate matrix - 100 connectors per job + id: generate_matrix + run: | + matrix=$(jq -c -r '{include: [.[] | "--name=" + .] | to_entries | group_by(.key / 100 | floor) | map(map(.value) | {"connector_names": join(" ")})}' selected_connectors.json) + echo "generated_matrix=$matrix" >> $GITHUB_OUTPUT + + run_connectors_up_to_date: + needs: generate_matrix name: Connectors up-to-date - runs-on: connector-nightly-xlarge + runs-on: connector-up-to-date-medium + continue-on-error: true + strategy: + matrix: ${{fromJson(needs.generate_matrix.outputs.generated_matrix)}} permissions: pull-requests: write - timeout-minutes: 1440 # 24 hours steps: - name: Checkout Airbyte uses: actions/checkout@v4 - name: Run airbyte-ci connectors up-to-date [WORKFLOW] - if: github.event_name == 'workflow_dispatch' id: airbyte-ci-connectors-up-to-date-workflow-dispatch uses: ./.github/actions/run-airbyte-ci with: @@ -40,20 +69,4 @@ jobs: sentry_dsn: ${{ secrets.SENTRY_AIRBYTE_CI_DSN }} s3_build_cache_access_key_id: ${{ secrets.SELF_RUNNER_AWS_ACCESS_KEY_ID }} s3_build_cache_secret_key: ${{ secrets.SELF_RUNNER_AWS_SECRET_ACCESS_KEY }} - subcommand: "connectors ${{ github.event.inputs.connectors-options }} up-to-date --create-prs ${{ github.event.inputs.auto-merge == 'false' && '' || '--auto-merge' }}" - - name: Run airbyte-ci connectors up-to-date [SCHEDULE] - if: github.event_name == 'schedule' - id: airbyte-ci-connectors-up-to-date-schedule - uses: ./.github/actions/run-airbyte-ci - with: - context: "master" - dagger_cloud_token: ${{ secrets.DAGGER_CLOUD_TOKEN_CACHE_3 }} - docker_hub_password: ${{ secrets.DOCKER_HUB_PASSWORD }} - docker_hub_username: ${{ secrets.DOCKER_HUB_USERNAME }} - gcp_gsm_credentials: ${{ secrets.GCP_GSM_CREDENTIALS }} - gcs_credentials: ${{ secrets.METADATA_SERVICE_PROD_GCS_CREDENTIALS }} - github_token: ${{ secrets.GH_PAT_MAINTENANCE_OSS }} - sentry_dsn: ${{ secrets.SENTRY_AIRBYTE_CI_DSN }} - s3_build_cache_access_key_id: ${{ secrets.SELF_RUNNER_AWS_ACCESS_KEY_ID }} - s3_build_cache_secret_key: ${{ secrets.SELF_RUNNER_AWS_SECRET_ACCESS_KEY }} - subcommand: 'connectors --concurrency=10 --language=python --language=low-code --support-level=community --support-level=certified --metadata-query="\"source-declarative-manifest\" not in data.dockerRepository" --metadata-query="\"-rc.\" not in data.dockerImageTag" up-to-date --ignore-connector=source-declarative-manifest --create-prs --auto-merge' + subcommand: "connectors --concurrency=10 ${{ matrix.connector_names}} up-to-date --create-prs --auto-merge" diff --git a/.github/workflows/connectors_version_increment_check.yml b/.github/workflows/connectors_version_increment_check.yml index bde0e7967b1c..efb38521c3b8 100644 --- a/.github/workflows/connectors_version_increment_check.yml +++ b/.github/workflows/connectors_version_increment_check.yml @@ -21,9 +21,9 @@ on: jobs: connectors_ci: name: Connectors Version Increment Check - runs-on: connector-test-large + runs-on: linux-20.04-large # Custom runner, defined in GitHub org settings if: github.event.pull_request.head.repo.fork != true - timeout-minutes: 12 + timeout-minutes: 22 steps: - name: Checkout Airbyte uses: actions/checkout@v4 diff --git a/.github/workflows/contractors_review_requirements.yml b/.github/workflows/contractors_review_requirements.yml index d759538b7d32..7fa843d73fc3 100644 --- a/.github/workflows/contractors_review_requirements.yml +++ b/.github/workflows/contractors_review_requirements.yml @@ -10,7 +10,7 @@ on: jobs: check-review-requirements: name: "Check if a review is required from Connector teams" - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 if: ${{ github.event.pull_request.head.repo.fork == false }} # This workflow cannot run on forks, as the fork's github token does not have `read:org` diff --git a/.github/workflows/format-fix-command.yml b/.github/workflows/format-fix-command.yml index 03988c66d38f..331c4bc52ee1 100644 --- a/.github/workflows/format-fix-command.yml +++ b/.github/workflows/format-fix-command.yml @@ -29,8 +29,8 @@ concurrency: jobs: format-fix: - name: "Run airbyte-ci format fix all" - runs-on: ubuntu-latest + name: "Run pre-commit fix" + runs-on: ubuntu-24.04 steps: - name: Get job variables id: job-vars @@ -67,16 +67,21 @@ jobs: [1]: ${{ steps.job-vars.outputs.run-url }} - - name: Run airbyte-ci format fix all - uses: ./.github/actions/run-airbyte-ci - continue-on-error: true + # Compare the below to the `format_check.yml` workflow + - name: Setup Java + uses: actions/setup-java@v3 + with: + distribution: "zulu" + java-version: "21" + - name: Setup Python + uses: actions/setup-python@v5 with: - context: "manual" - gcs_credentials: ${{ secrets.METADATA_SERVICE_PROD_GCS_CREDENTIALS }} - sentry_dsn: ${{ secrets.SENTRY_AIRBYTE_CI_DSN }} - github_token: ${{ secrets.GH_PAT_MAINTENANCE_OCTAVIA }} - subcommand: "format fix all" - dagger_cloud_token: ${{ secrets.DAGGER_CLOUD_TOKEN_CACHE_2 }} + python-version: "3.10" + cache: "pip" + - name: Run pre-commit + uses: pre-commit/action@v3.0.1 + continue-on-error: true + id: format-fix # This is helpful in the case that we change a previously committed generated file to be ignored by git. - name: Remove any files that have been gitignored @@ -87,7 +92,7 @@ jobs: - name: Check for changes id: git-diff run: | - git diff --quiet && echo "No changes to commit" || echo "::set-output name=changes::true" + git diff --quiet && echo "No changes to commit" || echo "changes=true" >> $GITHUB_OUTPUT shell: bash # Commit changes (if any) diff --git a/.github/workflows/format_check.yml b/.github/workflows/format_check.yml index 4bb83c118312..4dcf3480ce9a 100644 --- a/.github/workflows/format_check.yml +++ b/.github/workflows/format_check.yml @@ -10,53 +10,31 @@ on: jobs: format-check: - # IMPORTANT: This name must match the require check name on the branch protection settings name: "Check for formatting errors" - # Do not run this job on forks - # Forked PRs are handled by the community_ci.yml workflow - if: github.event.pull_request.head.repo.fork != true - runs-on: tooling-test-small + runs-on: ubuntu-24.04 steps: - - name: Checkout Airbyte (with credentials) - uses: actions/checkout@v4 + - uses: actions/checkout@v4 + - name: Setup Java + uses: actions/setup-java@v3 with: - ref: ${{ github.head_ref }} - token: ${{ secrets.GH_PAT_APPROVINGTON_OCTAVIA }} - fetch-depth: 1 - - name: Run airbyte-ci format check [MASTER] - id: airbyte_ci_format_check_all_master - if: github.ref == 'refs/heads/master' - uses: ./.github/actions/run-airbyte-ci - continue-on-error: true + distribution: "zulu" + java-version: "21" + - name: Setup Python + uses: actions/setup-python@v5 with: - context: "master" - sentry_dsn: ${{ secrets.SENTRY_AIRBYTE_CI_DSN }} - subcommand: "format check all" - - - name: Run airbyte-ci format check [PULL REQUEST] - id: airbyte_ci_format_check_all_pr - if: github.event_name == 'pull_request' - uses: ./.github/actions/run-airbyte-ci - continue-on-error: false - with: - context: "pull_request" - sentry_dsn: ${{ secrets.SENTRY_AIRBYTE_CI_DSN }} - subcommand: "format check all" - dagger_cloud_token: ${{ secrets.DAGGER_CLOUD_TOKEN_CACHE_2 }} - - - name: Run airbyte-ci format check [WORKFLOW DISPATCH] - id: airbyte_ci_format_check_all_manual - if: github.event_name == 'workflow_dispatch' - uses: ./.github/actions/run-airbyte-ci - continue-on-error: false + python-version: "3.10" + cache: "pip" + - name: Run pre-commit + uses: pre-commit/action@v3.0.1 + id: format-check with: - context: "manual" - sentry_dsn: ${{ secrets.SENTRY_AIRBYTE_CI_DSN }} - subcommand: "format check all" - dagger_cloud_token: ${{ secrets.DAGGER_CLOUD_TOKEN_CACHE_2 }} + extra_args: --all-files - name: Match GitHub User to Slack User [MASTER] - if: github.ref == 'refs/heads/master' + if: > + always() && steps.format-check.outcome == 'failure' && + github.ref == 'refs/heads/master' && + github.event.pull_request.head.repo.fork == false id: match-github-to-slack-user uses: ./.github/actions/match-github-to-slack-user env: @@ -64,7 +42,10 @@ jobs: GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Format Failure on Master Slack Channel [MASTER] - if: steps.airbyte_ci_format_check_all_master.outcome == 'failure' && github.ref == 'refs/heads/master' + if: > + always() && steps.format-check.outcome == 'failure' && + github.ref == 'refs/heads/master' && + github.event.pull_request.head.repo.fork == false uses: abinoda/slack-action@master env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN_AIRBYTE_TEAM }} diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 6eb8cd56f18e..b730e2f230e9 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -21,7 +21,7 @@ on: jobs: changes: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 outputs: java: ${{ steps.changes.outputs.java }} @@ -49,7 +49,7 @@ jobs: # Any revision upwards should be based on a performance analysis of gradle scans. # See https://github.com/airbytehq/airbyte/pull/36055 for an example of this, # which explains why which we went down from 64 cores to 16. - runs-on: connector-test-large + runs-on: linux-20.04-large # Custom runner, defined in GitHub org settings name: Gradle Check timeout-minutes: 30 steps: @@ -81,7 +81,7 @@ jobs: set-instatus-incident-on-failure: name: Create Instatus Incident on Failure - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: - run-check if: ${{ failure() && github.ref == 'refs/heads/master' }} @@ -94,7 +94,7 @@ jobs: set-instatus-incident-on-success: name: Create Instatus Incident on Success - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: - run-check if: ${{ success() && github.ref == 'refs/heads/master' }} @@ -107,7 +107,7 @@ jobs: notify-failure-slack-channel: name: "Notify Slack Channel on Build Failures" - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: - run-check if: ${{ failure() && github.ref == 'refs/heads/master' }} @@ -136,7 +136,7 @@ jobs: notify-failure-slack-channel-fixed-broken-build: name: "Notify Slack Channel on Build Fixes" - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: - run-check if: ${{ success() && github.event.pull_request.head.repo.fork != true }} diff --git a/.github/workflows/label-github-issues-by-context.yml b/.github/workflows/label-github-issues-by-context.yml index 4d9eac59a7a4..1b6abcbf858e 100644 --- a/.github/workflows/label-github-issues-by-context.yml +++ b/.github/workflows/label-github-issues-by-context.yml @@ -6,7 +6,7 @@ on: jobs: shared-issues: name: "Add Labels to Issues. Safe to Merge on fail" - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Run Issue Command from workflow-actions uses: nick-fields/private-action-loader@v3 diff --git a/.github/workflows/label-github-issues-by-path.yml b/.github/workflows/label-github-issues-by-path.yml index 1b18f9ec5512..5d81f9af38f5 100644 --- a/.github/workflows/label-github-issues-by-path.yml +++ b/.github/workflows/label-github-issues-by-path.yml @@ -8,7 +8,7 @@ on: jobs: add-label-based-on-file-changes: name: "Label PRs based on files changes" - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: "Label PR based on changed files" uses: actions/labeler@v3 diff --git a/.github/workflows/label-prs-by-context.yml b/.github/workflows/label-prs-by-context.yml index bc97babb09a4..8782f86176a0 100644 --- a/.github/workflows/label-prs-by-context.yml +++ b/.github/workflows/label-prs-by-context.yml @@ -8,7 +8,7 @@ on: jobs: shared-pr-labeller: name: "Add Labels to PRs. Safe to Merge on fail" - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Run Issue Command from workflow-actions uses: nick-fields/private-action-loader@v3 diff --git a/.github/workflows/live_tests.yml b/.github/workflows/live_tests.yml index cbe33c48b635..795c3f4f1e21 100644 --- a/.github/workflows/live_tests.yml +++ b/.github/workflows/live_tests.yml @@ -44,7 +44,7 @@ on: jobs: live_tests: name: Live Tests - runs-on: connector-test-large + runs-on: linux-20.04-large # Custom runner, defined in GitHub org settings timeout-minutes: 360 # 6 hours steps: - name: Checkout Airbyte @@ -63,6 +63,8 @@ jobs: - name: Install Poetry id: install_poetry uses: snok/install-poetry@v1 + with: + version: 1.8.5 - name: Make poetry venv in project id: poetry_venv diff --git a/.github/workflows/notify-on-push-to-master.yml b/.github/workflows/notify-on-push-to-master.yml index 3fc787f6cb65..5d9b391633a7 100644 --- a/.github/workflows/notify-on-push-to-master.yml +++ b/.github/workflows/notify-on-push-to-master.yml @@ -8,7 +8,7 @@ on: jobs: repo-sync: name: "Fire a Repo Dispatch event to airbyte-cloud" - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Repository Dispatch uses: peter-evans/repository-dispatch@v2 diff --git a/.github/workflows/publish-bulk-cdk.yml b/.github/workflows/publish-bulk-cdk.yml index a1ef1e716c85..2d89ac71a249 100644 --- a/.github/workflows/publish-bulk-cdk.yml +++ b/.github/workflows/publish-bulk-cdk.yml @@ -25,7 +25,7 @@ env: jobs: publish-bulk-cdk: name: Publish Bulk CDK - runs-on: connector-test-large + runs-on: linux-20.04-large # Custom runner, defined in GitHub org settings timeout-minutes: 30 steps: - name: Checkout Airbyte diff --git a/.github/workflows/publish-cdk-command-manually.yml b/.github/workflows/publish-cdk-command-manually.yml deleted file mode 100644 index d16163df88dd..000000000000 --- a/.github/workflows/publish-cdk-command-manually.yml +++ /dev/null @@ -1,388 +0,0 @@ -name: Publish Python CDK Manually -on: - workflow_dispatch: - inputs: - repo: - description: "Repo to check out code from. Defaults to the main airbyte repo. Set this when building connectors from forked repos." - required: false - default: "airbytehq/airbyte" - gitref: - description: "The git ref to check out from the specified repository." - required: false - default: master - release-type: - type: choice - description: "Choose the type of version upgrade : major|minor|patch" - options: - - none - - major - - minor - - patch - required: true - changelog-message: - description: "Changelog message to be added to CHANGELOG.md" - required: false - -concurrency: - group: publish-airbyte-cdk - cancel-in-progress: false - -jobs: - build-cdk: - runs-on: ubuntu-latest - steps: - - name: Install Python - uses: actions/setup-python@v4 - with: - python-version: "3.10" - - name: Install Poetry - id: install_poetry - uses: snok/install-poetry@v1 - - name: Checkout Airbyte - uses: actions/checkout@v3 - with: - repository: ${{ github.event.inputs.repo }} - ref: ${{ github.event.inputs.gitref }} - - name: Install Dependencies - id: install_dependencies - working-directory: airbyte-cdk/python - run: poetry install - - name: Build CDK Package - working-directory: airbyte-cdk/python - run: poetry run poe build - - name: Post failure to Slack channel dev-connectors-extensibility - if: ${{ failure() }} - uses: slackapi/slack-github-action@v1.23.0 - continue-on-error: true - with: - channel-id: C04J1M66D8B - payload: | - { - "text": "Error during `build-cdk` while publishing Python CDK!", - "blocks": [ - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "Error while publishing Python CDK!" - } - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "See details on \n" - } - } - ] - } - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN_AIRBYTE_TEAM }} - - bump-version: - needs: build-cdk - if: github.event.inputs.release-type != 'none' - runs-on: ubuntu-latest - outputs: - new_cdk_version: ${{ steps.bumpversion.outputs.NEW_VERSION }} - steps: - - uses: actions/setup-python@v4 - with: - python-version: "3.10" - - name: Install Poetry - id: install_poetry - uses: snok/install-poetry@v1 - - name: Checkout Airbyte - uses: actions/checkout@v3 - with: - repository: ${{ github.event.inputs.repo }} - ref: ${{ github.event.inputs.gitref }} - token: ${{ secrets.GH_PAT_MAINTENANCE_OSS }} # This token is what allows us to commit directly to master - - name: "Publish Python CDK: bump Poetry package version" - id: bumpversion - run: | - cd airbyte-cdk/python - # Bump package version - poetry version ${{ github.event.inputs.release-type }} - new_version="$(poetry version -s)" - awk -v NEW_VERSION="$new_version" -v CHANGELOG_MESSAGE="${{ github.event.inputs.changelog-message }}" 'NR==3{print "## " NEW_VERSION "\n" CHANGELOG_MESSAGE "\n"}1' CHANGELOG.md > tmp && mv tmp CHANGELOG.md - echo NEW_VERSION=$new_version >> $GITHUB_OUTPUT - - name: Commit and Push Changes - uses: stefanzweifel/git-auto-commit-action@v4 - with: - file_pattern: airbyte-cdk/python/pyproject.toml airbyte-cdk/python/CHANGELOG.md - commit_message: 🤖 ${{ github.event.inputs.release-type }} bump Python CDK to version ${{ steps.bumpversion.outputs.NEW_VERSION }} - commit_user_name: Octavia Squidington III - commit_user_email: octavia-squidington-iii@users.noreply.github.com - - name: Post failure to Slack channel dev-connectors-extensibility - if: ${{ failure() }} - uses: slackapi/slack-github-action@v1.23.0 - continue-on-error: true - with: - channel-id: C04J1M66D8B - payload: | - { - "text": "Error during `bump-version` while publishing Python CDK!", - "blocks": [ - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "Error while publishing Python CDK!" - } - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "See details on \n" - } - } - ] - } - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN_AIRBYTE_TEAM }} - - publish-cdk: - name: Publish Python CDK to PyPi - needs: bump-version - runs-on: ubuntu-latest - steps: - - name: Checkout Airbyte - uses: actions/checkout@v3 - with: - repository: ${{ github.event.inputs.repo }} - ref: ${{ github.event.inputs.gitref }} - - name: Build and publish to pypi - uses: JRubics/poetry-publish@v2.0 - with: - pypi_token: ${{ secrets.PYPI_TOKEN }} - python_version: "3.10" - package_directory: "airbyte-cdk/python" - - name: Post failure to Slack channel dev-connectors-extensibility - if: ${{ failure() }} - uses: slackapi/slack-github-action@v1.23.0 - continue-on-error: true - with: - channel-id: C04J1M66D8B - payload: | - { - "text": "Error during `publish-cdk` while publishing Python CDK!", - "blocks": [ - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "Error while publishing Python CDK!" - } - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "See details on \n" - } - } - ] - } - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN_AIRBYTE_TEAM }} - - bump-manifest-source: - name: Bump CDK dependency of source-declarative-manifest - needs: - - bump-version - - publish-cdk - runs-on: ubuntu-latest - steps: - - uses: actions/setup-python@v4 - with: - python-version: "3.10" - - name: Install Poetry - id: install_poetry - uses: snok/install-poetry@v1 - - name: Checkout Airbyte - uses: actions/checkout@v3 - with: - repository: ${{ github.event.inputs.repo }} - ref: ${{ github.event.inputs.gitref }} - token: ${{ secrets.GH_PAT_MAINTENANCE_OSS }} # This token is what allows us to commit directly to master - - name: Bump CDK dependency of source-declarative-manifest - timeout-minutes: 10 - run: | - cd airbyte-integrations/connectors/source-declarative-manifest - echo "Attempting to pull the newly published version of airbyte-cdk." - while true; do - # --no-cache to force looking for the new version - poetry add airbyte-cdk==${{needs.bump-version.outputs.new_cdk_version}} --no-cache && break - # Loop to wait for the new version to be available to poetry - echo "Couldn't add new dependency. This is normal if the dependency could not (yet) be found. Retrying in 10 seconds..." - sleep 10 - done - echo "Successfully updated the CDK dependency of source-declarative-manifest to ${{needs.bump-version.outputs.new_cdk_version}}" - - name: Bump version of source-declarative-manifest - uses: ./.github/actions/run-airbyte-ci - with: - context: "master" # TODO: figure out why changing this yells with `The ci_gcs_credentials was not set on this PipelineContext.` - dagger_cloud_token: ${{ secrets.DAGGER_CLOUD_TOKEN_CACHE_5 }} - docker_hub_password: ${{ secrets.DOCKER_HUB_PASSWORD }} - docker_hub_username: ${{ secrets.DOCKER_HUB_USERNAME }} - gcp_gsm_credentials: ${{ secrets.GCP_GSM_CREDENTIALS }} - gcs_credentials: ${{ secrets.METADATA_SERVICE_PROD_GCS_CREDENTIALS }} - github_token: ${{ secrets.GITHUB_TOKEN }} - metadata_service_gcs_credentials: ${{ secrets.METADATA_SERVICE_PROD_GCS_CREDENTIALS }} - sentry_dsn: ${{ secrets.SENTRY_AIRBYTE_CI_DSN }} - slack_webhook_url: ${{ secrets.PUBLISH_ON_MERGE_SLACK_WEBHOOK }} - spec_cache_gcs_credentials: ${{ secrets.SPEC_CACHE_SERVICE_ACCOUNT_KEY_PUBLISH }} - s3_build_cache_access_key_id: ${{ secrets.SELF_RUNNER_AWS_ACCESS_KEY_ID }} - s3_build_cache_secret_key: ${{ secrets.SELF_RUNNER_AWS_SECRET_ACCESS_KEY }} - # There is no pull request number as we do this manually, so will just reference when we started doing it manually for now - subcommand: "connectors --concurrency=1 --execute-timeout=3600 --name=source-declarative-manifest bump-version version:${{needs.bump-version.outputs.new_cdk_version}} 'Bump CDK version to ${{needs.bump-version.outputs.new_cdk_version}}' --pr-number=36501" - python_registry_token: ${{ secrets.PYPI_TOKEN }} - - name: Commit and Push Changes - uses: stefanzweifel/git-auto-commit-action@v4 - with: - file_pattern: docs/integrations/sources/low-code.md airbyte-integrations/connectors/source-declarative-manifest/* - commit_message: 🤖 Cut version ${{needs.bump-version.outputs.new_cdk_version}} of source-declarative-manifest - commit_user_name: Octavia Squidington III - commit_user_email: octavia-squidington-iii@users.noreply.github.com - - name: Post failure to Slack channel dev-connectors-extensibility - if: ${{ failure() }} - uses: slackapi/slack-github-action@v1.23.0 - continue-on-error: true - with: - channel-id: C04J1M66D8B - payload: | - { - "text": ":warning: A new version of Python CDK has been released but `source-declarative-manifest` and Connector Builder haven't been automatically updated", - "blocks": [ - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "A new version of Python CDK has been released with : ${{ github.event.inputs.changelog-message }}\n\n" - } - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": ":warning: Could not bump version of `source-declarative-manifest`.>\n" - } - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "See details on \n" - } - } - ] - } - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN_AIRBYTE_TEAM }} - - update-connector-builder: - needs: - - bump-version - - bump-manifest-source - runs-on: ubuntu-latest - steps: - - uses: actions/setup-python@v4 - with: - python-version: "3.10" - - name: Checkout Airbyte Platform Internal - uses: actions/checkout@v3 - with: - repository: airbytehq/airbyte-platform-internal - token: ${{ secrets.GH_PAT_MAINTENANCE_OCTAVIA }} - - name: Update CDK version - run: | - PREVIOUS_VERSION=$(cat oss/airbyte-connector-builder-resources/CDK_VERSION) - sed -i "s/${PREVIOUS_VERSION}/${{needs.bump-version.outputs.new_cdk_version}}/g" oss/airbyte-connector-builder-server/Dockerfile - sed -i "s/${PREVIOUS_VERSION}/${{needs.bump-version.outputs.new_cdk_version}}/g" cloud/airbyte-connector-builder-server-wrapped/Dockerfile - sed -i "s/airbyte-cdk==${PREVIOUS_VERSION}/airbyte-cdk==${{needs.bump-version.outputs.new_cdk_version}}/g" oss/airbyte-connector-builder-server/requirements.in - echo ${{needs.bump-version.outputs.new_cdk_version}} > oss/airbyte-connector-builder-resources/CDK_VERSION - cd oss/airbyte-connector-builder-server - pip install pip-tools - pip-compile --upgrade - - name: Create Pull Request - id: create-pull-request - uses: peter-evans/create-pull-request@v6 - with: - token: ${{ secrets.GH_PAT_MAINTENANCE_OCTAVIA }} - commit-message: "chore: update CDK version following release" - title: "chore: update CDK version following release" - body: This is an automatically generated PR triggered by a CDK release - branch: automatic-cdk-release - base: master - delete-branch: true - - name: Post success to Slack channel dev-connectors-extensibility - uses: slackapi/slack-github-action@v1.23.0 - continue-on-error: true - with: - channel-id: C04J1M66D8B - payload: | - { - "text": "A new version of Python CDK has been released!", - "blocks": [ - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "A new version of Python CDK has been released with : ${{ github.event.inputs.changelog-message }}\n\n" - } - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "A PR has also been created for the <${{ steps.create-pull-request.outputs.pull-request-url }}|Connector Builder>\n" - } - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "See details on \n" - } - } - ] - } - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN_AIRBYTE_TEAM }} - - name: Post failure to Slack channel dev-connectors-extensibility - if: ${{ failure() }} - uses: slackapi/slack-github-action@v1.23.0 - continue-on-error: true - with: - channel-id: C04J1M66D8B - payload: | - { - "text": ":warning: A new version of Python CDK has been released but Connector Builder hasn't been automatically updated", - "blocks": [ - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "A new version of Python CDK has been released with : ${{ github.event.inputs.changelog-message }}\n\n" - } - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": ":warning: Could not automatically create a PR for Connector Builder>\n" - } - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "See details on \n" - } - } - ] - } - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN_AIRBYTE_TEAM }} diff --git a/.github/workflows/publish-java-cdk-command.yml b/.github/workflows/publish-java-cdk-command.yml index 182cb2c59613..82a9ffac5636 100644 --- a/.github/workflows/publish-java-cdk-command.yml +++ b/.github/workflows/publish-java-cdk-command.yml @@ -61,7 +61,7 @@ env: jobs: publish-cdk: name: Publish Java CDK - runs-on: connector-test-large + runs-on: linux-20.04-large # Custom runner, defined in GitHub org settings timeout-minutes: 30 steps: - name: Link comment to Workflow Run diff --git a/.github/workflows/publish_connectors.yml b/.github/workflows/publish_connectors.yml index 293891394bb0..5e7971f2d360 100644 --- a/.github/workflows/publish_connectors.yml +++ b/.github/workflows/publish_connectors.yml @@ -72,7 +72,7 @@ jobs: notify-failure-slack-channel: name: "Notify Slack Channel on Publish Failures" - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: - publish_connectors if: ${{ always() && contains(needs.*.result, 'failure') && github.ref == 'refs/heads/master' }} @@ -101,7 +101,7 @@ jobs: notify-failure-pager-duty: name: "Notify PagerDuty on Publish Failures" - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: - publish_connectors if: ${{ always() && contains(needs.*.result, 'failure') && github.ref == 'refs/heads/master' }} diff --git a/.github/workflows/regression_tests.yml b/.github/workflows/regression_tests.yml index 4bd5fd68bb4b..c1faff524607 100644 --- a/.github/workflows/regression_tests.yml +++ b/.github/workflows/regression_tests.yml @@ -44,7 +44,7 @@ on: jobs: regression_tests: name: Regression Tests - runs-on: connector-test-large + runs-on: linux-20.04-large # Custom runner, defined in GitHub org settings timeout-minutes: 360 # 6 hours steps: - name: Checkout Airbyte @@ -63,6 +63,8 @@ jobs: - name: Install Poetry id: install_poetry uses: snok/install-poetry@v1 + with: + version: 1.8.5 - name: Make poetry venv in project id: poetry_venv diff --git a/.github/workflows/release-airbyte-os.yml b/.github/workflows/release-airbyte-os.yml index b4fbfc9e3255..4c0ab2c15198 100644 --- a/.github/workflows/release-airbyte-os.yml +++ b/.github/workflows/release-airbyte-os.yml @@ -14,7 +14,7 @@ jobs: start-release-airbyte-runner: name: "Release Airbyte: Start EC2 Runner" timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 outputs: label: ${{ steps.start-ec2-runner.outputs.label }} ec2-instance-id: ${{ steps.start-ec2-runner.outputs.ec2-instance-id }} @@ -37,7 +37,7 @@ jobs: github-token: ${{ env.PAT }} release-airbyte-platform: - # In case of self-hosted EC2 errors, removed the `needs` line and switch back to running on ubuntu-latest. + # In case of self-hosted EC2 errors, removed the `needs` line and switch back to running on ubuntu-24.04. needs: - start-release-airbyte-runner runs-on: ${{ needs.start-release-airbyte-runner.outputs.label }} # run the job on the newly created runner @@ -107,7 +107,7 @@ jobs: tag: v${{ env.NEW_VERSION }} release-airbyte: - # In case of self-hosted EC2 errors, removed the `needs` line and switch back to running on ubuntu-latest. + # In case of self-hosted EC2 errors, removed the `needs` line and switch back to running on ubuntu-24.04. needs: - start-release-airbyte-runner - release-airbyte-platform @@ -174,7 +174,7 @@ jobs: # We are releasing octavia from a separate job because: # - The self hosted runner used in releaseAirbyte does not have the docker buildx command to build multi-arch images release-octavia: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@v3 @@ -205,7 +205,7 @@ jobs: needs: - start-release-airbyte-runner # required to get output from the start-runner job - release-airbyte # required to wait when the main job is done - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 if: ${{ always() }} # required to stop the runner even if the error happened in the previous jobs steps: - name: Configure AWS credentials diff --git a/.github/workflows/run-mypy-on-modified-cdk-files.yml b/.github/workflows/run-mypy-on-modified-cdk-files.yml deleted file mode 100644 index ffdbc94767e4..000000000000 --- a/.github/workflows/run-mypy-on-modified-cdk-files.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Python CDK - Run mypy on modified cdk files - -on: - pull_request: - paths: - - "airbyte-cdk/python/airbyte_cdk/**/*.py" -jobs: - run-mypy-on-modified-cdk-files: - name: "Run mypy on modified cdk files" - runs-on: ubuntu-latest - steps: - - name: Checkout Airbyte - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Install Python - uses: actions/setup-python@v4 - with: - python-version: "3.10" - - run: pip install mypy==1.11.0 - - name: Get Python changed files - id: changed-py-files - uses: tj-actions/changed-files@v43 - with: - files: "airbyte-cdk/python/airbyte_cdk/**/*.py" - - name: Run if any of the listed files above is changed - if: steps.changed-py-files.outputs.any_changed == 'true' - run: mypy ${{ steps.changed-py-files.outputs.all_changed_files }} --config-file airbyte-cdk/python/mypy.ini --install-types --non-interactive diff --git a/.github/workflows/slash-commands.yml b/.github/workflows/slash-commands.yml index 5114f9652b6f..35c18f9da198 100644 --- a/.github/workflows/slash-commands.yml +++ b/.github/workflows/slash-commands.yml @@ -6,7 +6,7 @@ jobs: slashCommandDispatch: # Only allow slash commands on pull request (not on issues) if: ${{ github.event.issue.pull_request }} - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Get PR repo and ref id: getref diff --git a/.github/workflows/stale-community-issues.yaml b/.github/workflows/stale-community-issues.yaml index 8e2a2005a83a..a02fb06afe8d 100644 --- a/.github/workflows/stale-community-issues.yaml +++ b/.github/workflows/stale-community-issues.yaml @@ -5,7 +5,7 @@ on: jobs: close-issues: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 permissions: issues: write steps: @@ -19,8 +19,8 @@ jobs: operations-per-run: 100 ascending: true stale-issue-message: > - At Airbyte, we seek to be clear about the project priorities and roadmap. - This issue has not had any activity for 180 days, suggesting that it's not as critical as others. + At Airbyte, we seek to be clear about the project priorities and roadmap. + This issue has not had any activity for 180 days, suggesting that it's not as critical as others. It's possible it has already been fixed. It is being marked as stale and will be closed in 20 days if there is no activity. To keep it open, please comment to let us know why it is important to you and if it is still reproducible on recent versions of Airbyte. close-issue-message: "This issue was closed because it has been inactive for 20 days since being marked as stale." diff --git a/.github/workflows/stale-routed-issues.yaml b/.github/workflows/stale-routed-issues.yaml index ac829669b8d2..380461953a04 100644 --- a/.github/workflows/stale-routed-issues.yaml +++ b/.github/workflows/stale-routed-issues.yaml @@ -5,7 +5,7 @@ on: jobs: close-issues: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 permissions: issues: write pull-requests: write @@ -17,8 +17,8 @@ jobs: days-before-issue-close: 20 stale-issue-label: "stale" stale-issue-message: > - At Airbyte, we seek to be clear about the project priorities and roadmap. - This issue has not had any activity for 365 days, suggesting that it's not as critical as others. + At Airbyte, we seek to be clear about the project priorities and roadmap. + This issue has not had any activity for 365 days, suggesting that it's not as critical as others. It's possible it has already been fixed. It is being marked as stale and will be closed in 20 days if there is no activity. To keep it open, please comment to let us know why it is important to you and if it is still reproducible on recent versions of Airbyte. close-issue-message: "This issue was closed because it has been inactive for 20 days since being marked as stale." diff --git a/.github/workflows/terminate-zombie-build-instances.yml b/.github/workflows/terminate-zombie-build-instances.yml index cb50d67906e3..15e15f72ac06 100644 --- a/.github/workflows/terminate-zombie-build-instances.yml +++ b/.github/workflows/terminate-zombie-build-instances.yml @@ -11,7 +11,7 @@ on: jobs: terminate: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: List and Terminate Instances Older Than 4 Hours env: @@ -38,7 +38,7 @@ jobs: # See https://docs.aws.amazon.com/cli/latest/reference/ec2/terminate-instances.html for terminate command. echo $to_terminate | jq '.[] | .InstanceId' | xargs --no-run-if-empty --max-args=1 aws ec2 terminate-instances --instance-ids terminate-github-instances: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Checkout Airbyte uses: actions/checkout@v3 diff --git a/.github/workflows/test-command.yml b/.github/workflows/test-command.yml index 113a8558fdbf..4a4922c5fcd9 100644 --- a/.github/workflows/test-command.yml +++ b/.github/workflows/test-command.yml @@ -33,7 +33,7 @@ on: jobs: write-deprecation-message: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Print deprecation message uses: peter-evans/create-or-update-comment@v1 diff --git a/.github/workflows/test-performance-command.yml b/.github/workflows/test-performance-command.yml index 9f459ca84d1f..73cc45700ef9 100644 --- a/.github/workflows/test-performance-command.yml +++ b/.github/workflows/test-performance-command.yml @@ -33,7 +33,7 @@ jobs: start-test-runner: name: Start Build EC2 Runner timeout-minutes: 10 - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 outputs: label: ${{ steps.start-ec2-runner.outputs.label }} ec2-instance-id: ${{ steps.start-ec2-runner.outputs.ec2-instance-id }} @@ -174,7 +174,7 @@ jobs: needs: - start-test-runner # required to get output from the start-runner job - performance-test # required to wait when the main job is done - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 if: ${{ always() }} # required to stop the runner even if the error happened in the previous jobs steps: - name: Configure AWS credentials diff --git a/.github/workflows/upload-metadata-files.yml b/.github/workflows/upload-metadata-files.yml index 7028c461ec8a..6f753f7dfe6c 100644 --- a/.github/workflows/upload-metadata-files.yml +++ b/.github/workflows/upload-metadata-files.yml @@ -6,7 +6,7 @@ on: jobs: deploy-catalog-to-stage: name: "Upload Metadata Files to Metadata Service" - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Checkout Airbyte Cloud uses: actions/checkout@v2 diff --git a/.github/workflows/workflow-cleanup.yml b/.github/workflows/workflow-cleanup.yml index 8c7ea90d9ac8..65fc05751902 100644 --- a/.github/workflows/workflow-cleanup.yml +++ b/.github/workflows/workflow-cleanup.yml @@ -6,7 +6,7 @@ on: jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: checkout repo content uses: actions/checkout@v3 # checkout the repository content to github runner diff --git a/.gitignore b/.gitignore index d58b1cf03727..3e9c9e57c0ec 100644 --- a/.gitignore +++ b/.gitignore @@ -108,3 +108,7 @@ scan-journal.log # mvn target/ + +# CDK load artifacts +airbyte-cdk/bulk/core/load/airbyte-cdk-load/ +airbyte-integrations/connectors/**/airbyte-cdk-load/ \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4fd1a68cdc3b..f98b3cb9b786 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,10 +1,59 @@ +exclude: | + (?x)( + # Python/system files + ^.*/__init__\.py$| + ^.*?/\.venv/.*$| + ^.*?/node_modules/.*$| + + ^.*?/charts/.*$| + ^airbyte-integrations/bases/base-normalization/.*$| + ^.*?/normalization_test_output/.*$| + + ^.*?/pnpm-lock\.yaml$| + ^.*?/source-amplitude/unit_tests/api_data/zipped\.json$| + + # Generated/test files + ^airbyte-ci/connectors/metadata_service/lib/metadata_service/models/generated/.*$| + ^.*?/airbyte-ci/connectors/metadata_service/lib/tests/fixtures/.*/invalid/.*$| + ^airbyte-ci/connectors/metadata_service/lib/tests/fixtures/.*/invalid/.*$| + ^.*?/airbyte-ci/connectors/pipelines/tests/test_format/non_formatted_code/.*$| + ^airbyte-ci/connectors/pipelines/tests/test_format/non_formatted_code/.*$| + ^.*?/airbyte-integrations/connectors/destination-.*/expected-spec\.json$ + ) + repos: + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.8.3 + hooks: + # Run the linter. + - id: ruff + args: + - --fix + - --select=I + + # Run the formatter. + - id: ruff-format + + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v3.0.3 + hooks: + - id: prettier + types_or: [json, yaml] + additional_dependencies: + - prettier@3.0.3 + - repo: local hooks: - - id: format-fix-all-on-push - always_run: true - entry: airbyte-ci --disable-update-check format fix all + - id: addlicense + name: Add license headers + entry: addlicense -c "Airbyte, Inc." -l apache -v -f LICENSE_SHORT + language: golang + additional_dependencies: [github.com/google/addlicense@v1.1.1] + files: \.(java|kt|py)$ + + - id: spotless + name: Format Java files with Spotless + entry: bash -c 'command -v mvn >/dev/null 2>&1 || { if [ -z "$CI" ]; then echo "Maven not installed, skipping spotless" >&2; exit 0; fi }; mvn -f spotless-maven-pom.xml spotless:apply' language: system - name: Run airbyte-ci format fix on git push (~30s) + files: \.(java|kt|gradle)$ pass_filenames: false - stages: [push] diff --git a/.readthedocs.yaml b/.readthedocs.yaml deleted file mode 100644 index 5fb58f45882d..000000000000 --- a/.readthedocs.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# .readthedocs.yaml -# Read the Docs configuration file -# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details - -# Required -version: 2 - -build: - os: ubuntu-20.04 - tools: - python: "3.9" - -# Build documentation in the docs/ directory with Sphinx -sphinx: - builder: html - configuration: airbyte-cdk/python/reference_docs/_source/conf.py - -# Set the version of Python and requirements required to build your docs -python: - install: - - method: pip - path: airbyte-cdk/python - extra_requirements: - - sphinx-docs diff --git a/Makefile b/Makefile index 6a2dd841c970..468f46d5b40a 100644 --- a/Makefile +++ b/Makefile @@ -39,11 +39,11 @@ tools.pre-commit.install.Darwin: @brew install pre-commit @echo "Pre-commit installation complete" -tools.pre-commit.setup: tools.airbyte-ci.install tools.pre-commit.install.$(OS) tools.git-hooks.clean ## Setup pre-commit hooks +tools.git-hooks.install: tools.airbyte-ci.install tools.pre-commit.install.$(OS) tools.git-hooks.clean ## Setup pre-commit hooks @echo "Installing pre-commit hooks..." @pre-commit install --hook-type pre-push @echo "Pre-push hooks installed." -tools.install: tools.airbyte-ci.install tools.pre-commit.setup +tools.install: tools.airbyte-ci.install tools.pre-commit.install.$(OS) -.PHONY: tools.install tools.pre-commit.setup tools.airbyte-ci.install tools.airbyte-ci-dev.install tools.airbyte-ci.check tools.airbyte-ci.clean +.PHONY: tools.install tools.pre-commit.install tools.git-hooks.install tools.git-hooks.clean tools.airbyte-ci.install tools.airbyte-ci-dev.install tools.airbyte-ci.check tools.airbyte-ci.clean diff --git a/airbyte-cdk/bulk/build.gradle b/airbyte-cdk/bulk/build.gradle index b8474f81a507..8552c2e5de43 100644 --- a/airbyte-cdk/bulk/build.gradle +++ b/airbyte-cdk/bulk/build.gradle @@ -33,6 +33,8 @@ allprojects { ksp 'io.micronaut:micronaut-inject-kotlin' kspTest platform('io.micronaut:micronaut-core-bom:4.6.1') kspTest 'io.micronaut:micronaut-inject-kotlin' + + testImplementation("io.mockk:mockk:1.13.13") } if (buildNumberFile.exists()) { diff --git a/airbyte-cdk/bulk/core/base/build.gradle b/airbyte-cdk/bulk/core/base/build.gradle index 5ecf5624885e..885e40adf83f 100644 --- a/airbyte-cdk/bulk/core/base/build.gradle +++ b/airbyte-cdk/bulk/core/base/build.gradle @@ -32,6 +32,7 @@ dependencies { implementation 'org.apache.logging.log4j:log4j-slf4j2-impl' implementation 'org.apache.logging.log4j:log4j-layout-template-json:2.24.0' implementation 'org.bouncycastle:bcprov-jdk18on:1.78.1' + implementation 'net.i2p.crypto:eddsa:0.3.0' implementation 'org.openapi4j:openapi-schema-validator:1.0.7' // this is only needed because of exclusions in airbyte-protocol @@ -50,3 +51,7 @@ dependencies { testFixturesApi 'io.micronaut.test:micronaut-test-junit5:4.5.0' testFixturesApi 'io.github.deblockt:json-diff:1.1.0' } + +test { + environment "PRESENT", "present-value" +} diff --git a/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/ConnectorUncleanExitException.kt b/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/ConnectorUncleanExitException.kt index 626ee21cde29..52117a9865b3 100644 --- a/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/ConnectorUncleanExitException.kt +++ b/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/ConnectorUncleanExitException.kt @@ -6,4 +6,4 @@ package io.airbyte.cdk /** This is used only in tests. */ class ConnectorUncleanExitException(val exitCode: Int) : - Exception("Destination process exited uncleanly: $exitCode") + Exception("Connector process exited uncleanly: $exitCode") diff --git a/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/command/SshTunnelConfiguration.kt b/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/command/SshTunnelConfiguration.kt index 8791a700319c..769669a6c825 100644 --- a/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/command/SshTunnelConfiguration.kt +++ b/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/command/SshTunnelConfiguration.kt @@ -10,6 +10,6 @@ import io.airbyte.cdk.ssh.SshTunnelMethodConfiguration interface SshTunnelConfiguration { val realHost: String val realPort: Int - val sshTunnel: SshTunnelMethodConfiguration + val sshTunnel: SshTunnelMethodConfiguration? val sshConnectionOptions: SshConnectionOptions } diff --git a/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/ssh/TunnelSession.kt b/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/ssh/TunnelSession.kt index 658aef684974..dc2467c379e0 100644 --- a/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/ssh/TunnelSession.kt +++ b/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/ssh/TunnelSession.kt @@ -48,7 +48,7 @@ internal constructor( /** Creates an open [TunnelSession]. */ fun createTunnelSession( remote: SshdSocketAddress, - sshTunnel: SshTunnelMethodConfiguration, + sshTunnel: SshTunnelMethodConfiguration?, connectionOptions: SshConnectionOptions, ): TunnelSession { if (sshTunnel is SshNoTunnelMethod) { @@ -62,7 +62,8 @@ fun createTunnelSession( log.info { "Creating SSH client session." } val connectFuture: ConnectFuture = when (sshTunnel) { - SshNoTunnelMethod -> TODO("unreachable code") + SshNoTunnelMethod, + null -> TODO("unreachable code") is SshKeyAuthTunnelMethod -> client.connect(sshTunnel.user.trim(), sshTunnel.host.trim(), sshTunnel.port) is SshPasswordAuthTunnelMethod -> diff --git a/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/util/Jsons.kt b/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/util/Jsons.kt index c4685c8576b4..3f5cdd0885ae 100644 --- a/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/util/Jsons.kt +++ b/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/util/Jsons.kt @@ -25,6 +25,7 @@ object Jsons : ObjectMapper() { registerModule(AfterburnerModule()) setSerializationInclusion(JsonInclude.Include.NON_NULL) configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true) configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true) } diff --git a/airbyte-cdk/bulk/core/base/src/main/resources/application.yaml b/airbyte-cdk/bulk/core/base/src/main/resources/application.yaml new file mode 100644 index 000000000000..7bad9b3fce29 --- /dev/null +++ b/airbyte-cdk/bulk/core/base/src/main/resources/application.yaml @@ -0,0 +1,12 @@ +airbyte: + file-transfer: + enabled: ${USE_FILE_TRANSFER:false} + staging-path: ${AIRBYTE_STAGING_DIRECTORY:/staging/files} + resources: + disk: + bytes: ${CONNECTOR_STORAGE_LIMIT_BYTES:5368709120} # 5GB + flush: + rate-ms: 900000 # 15 minutes + window-ms: 900000 # 15 minutes + destination: + record-batch-size-override: ${AIRBYTE_DESTINATION_RECORD_BATCH_SIZE_OVERRIDE:null} diff --git a/airbyte-cdk/bulk/core/base/src/test/kotlin/io/airbyte/cdk/initialization/TestApplicationYaml.kt b/airbyte-cdk/bulk/core/base/src/test/kotlin/io/airbyte/cdk/initialization/TestApplicationYaml.kt new file mode 100644 index 000000000000..40b926300377 --- /dev/null +++ b/airbyte-cdk/bulk/core/base/src/test/kotlin/io/airbyte/cdk/initialization/TestApplicationYaml.kt @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.initialization + +import io.micronaut.context.annotation.Bean +import io.micronaut.context.annotation.Factory +import io.micronaut.context.annotation.Value +import io.micronaut.test.extensions.junit5.annotation.MicronautTest +import jakarta.inject.Inject +import kotlin.test.assertEquals +import org.junit.jupiter.api.Test + +@MicronautTest +class TestApplicationYaml { + @Inject lateinit var defaultValueBean: DefaultValueBean + + @Test + fun testMainDefaultValue() { + assertEquals("/staging/files", defaultValueBean.stagingFolder) + assertEquals(false, defaultValueBean.fileTransferEnable) + } +} + +data class DefaultValueBean( + val stagingFolder: String, + val fileTransferEnable: Boolean, +) + +@Factory +class TestFactory { + @Bean + fun defaultValueBean( + @Value("\${airbyte.file-transfer.staging-path}") stagingFolder: String, + @Value("\${airbyte.file-transfer.enabled}") fileTransferEnable: Boolean, + ): DefaultValueBean { + return DefaultValueBean(stagingFolder, fileTransferEnable) + } +} diff --git a/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/FeedBootstrap.kt b/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/FeedBootstrap.kt index 5b0151196d26..6007bef9e8e2 100644 --- a/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/FeedBootstrap.kt +++ b/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/FeedBootstrap.kt @@ -57,7 +57,8 @@ sealed class FeedBootstrap( * to the next. Not doing this generates a lot of garbage and the increased GC activity has a * measurable impact on performance. */ - private inner class EfficientStreamRecordConsumer(val stream: Stream) : StreamRecordConsumer { + private inner class EfficientStreamRecordConsumer(override val stream: Stream) : + StreamRecordConsumer { override fun accept(recordData: ObjectNode, changes: Map?) { if (changes.isNullOrEmpty()) { @@ -214,7 +215,10 @@ sealed class FeedBootstrap( * b) field value changes and the motivating reason for these in the record metadata. * ``` */ -fun interface StreamRecordConsumer { +interface StreamRecordConsumer { + + val stream: Stream + fun accept(recordData: ObjectNode, changes: Map?) } diff --git a/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/FeedReader.kt b/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/FeedReader.kt index 5acc18ce9d83..caca48cd2e76 100644 --- a/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/FeedReader.kt +++ b/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/FeedReader.kt @@ -199,7 +199,14 @@ class FeedReader( } var checkpoint: PartitionReadCheckpoint try { - withTimeout(root.timeout.toKotlinDuration()) { partitionReader.run() } + if (partitionReader is UnlimitedTimePartitionReader) { + partitionReader.run() + } else { + log.info { + "Running partition reader with ${root.timeout.toKotlinDuration()} timeout" + } + withTimeout(root.timeout.toKotlinDuration()) { partitionReader.run() } + } log.info { "completed reading partition $partitionReaderID " + "for '${feed.label}' in round $partitionsCreatorID" diff --git a/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/Partitions.kt b/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/Partitions.kt index b4f604cf36b8..10cc5c09ed10 100644 --- a/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/Partitions.kt +++ b/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/Partitions.kt @@ -154,3 +154,6 @@ data class PartitionReadCheckpoint( val opaqueStateValue: OpaqueStateValue, val numRecords: Long, ) + +/** A [PartitionReader] with no time limit for its execution. */ +interface UnlimitedTimePartitionReader : PartitionReader diff --git a/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/ReadOperation.kt b/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/ReadOperation.kt index 746165650eb3..9bf4901668c4 100644 --- a/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/ReadOperation.kt +++ b/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/ReadOperation.kt @@ -51,11 +51,11 @@ class ReadOperation( partitionsCreatorFactories, ) runBlocking(ThreadRenamingCoroutineName("read") + Dispatchers.Default) { - rootReader.read { feedJobs: Map -> + rootReader.read { feedJobs: Collection -> val rootJob = coroutineContext.job launch(Job()) { var previousJobTree = "" - while (feedJobs.values.any { it.isActive }) { + while (feedJobs.any { it.isActive }) { val currentJobTree: String = renderTree(rootJob) if (currentJobTree != previousJobTree) { log.info { "coroutine state:\n$currentJobTree" } diff --git a/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/Resource.kt b/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/Resource.kt index 8e6fb2aa7cdc..b908dab6b713 100644 --- a/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/Resource.kt +++ b/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/Resource.kt @@ -5,7 +5,6 @@ package io.airbyte.cdk.read import io.airbyte.cdk.command.SourceConfiguration -import io.micronaut.context.annotation.DefaultImplementation import jakarta.inject.Inject import jakarta.inject.Singleton import kotlinx.coroutines.sync.Semaphore @@ -38,18 +37,3 @@ class ConcurrencyResource(maxConcurrency: Int) : Resource { - fun interface AcquiredGlobalLock : Resource.Acquired -} - -@Singleton -class NoOpGlobalLockResource : GlobalLockResource { - - override fun tryAcquire(): GlobalLockResource.AcquiredGlobalLock { - // Always acquire. - return GlobalLockResource.AcquiredGlobalLock {} - } -} diff --git a/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/RootReader.kt b/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/RootReader.kt index 3ef9140a70fd..3f4ac8267407 100644 --- a/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/RootReader.kt +++ b/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/RootReader.kt @@ -1,7 +1,7 @@ /* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ package io.airbyte.cdk.read -import io.airbyte.cdk.ConfigErrorException +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings import io.airbyte.cdk.discover.MetaFieldDecorator import io.airbyte.cdk.output.OutputConsumer import io.airbyte.cdk.util.ThreadRenamingCoroutineName @@ -10,10 +10,8 @@ import java.time.Duration import java.util.concurrent.ConcurrentHashMap import kotlin.coroutines.CoroutineContext import kotlin.time.toKotlinDuration -import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.Job -import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.update @@ -28,6 +26,7 @@ import kotlinx.coroutines.withTimeoutOrNull * * This object exists mainly to facilitate unit testing by keeping dependencies to a minimum. */ +@SuppressFBWarnings(value = ["NP_NONNULL_PARAM_VIOLATION"], justification = "Kotlin coroutines") class RootReader( val stateManager: StateManager, val resourceAcquisitionHeartbeat: Duration, @@ -58,60 +57,44 @@ class RootReader( val streamStatusManager = StreamStatusManager(stateManager.feeds, outputConsumer::accept) /** Reads records from all [Feed]s. */ - suspend fun read(listener: suspend (Map) -> Unit = {}) { + suspend fun read(listener: suspend (Collection) -> Unit = {}) { + readFeeds(listener) + readFeeds(listener) + } + + private suspend inline fun readFeeds( + crossinline listener: suspend (Collection) -> Unit, + ) { + val feeds: List = stateManager.feeds.filterIsInstance() + log.info { "Reading feeds of type ${T::class}." } + val exceptions = ConcurrentHashMap() supervisorScope { - val feeds: List = stateManager.feeds - val exceptions = ConcurrentHashMap() - // Launch one coroutine per feed. - val feedJobs: Map = - feeds.associateWith { feed: Feed -> + // Launch one coroutine per feed of same type. + val feedJobs: List = + feeds.map { feed: T -> val coroutineName = ThreadRenamingCoroutineName(feed.label) val handler = FeedExceptionHandler(feed, streamStatusManager, exceptions) launch(coroutineName + handler) { FeedReader(this@RootReader, feed).read() } } // Call listener hook. listener(feedJobs) - // Join on all global feeds and collect caught exceptions. - val globalExceptions: Map = - feeds.filterIsInstance().associateWith { - feedJobs[it]?.join() - exceptions[it] - } - - // Certain errors on the global feed cause a full stop to all stream reads - if (globalExceptions.values.filterIsInstance().isNotEmpty()) { - this@supervisorScope.cancel() - } - - // Join on all stream feeds and collect caught exceptions. - val streamExceptions: Map = - feeds.filterIsInstance().associateWith { - try { - feedJobs[it]?.join() - exceptions[it] - } catch (_: CancellationException) { - null - } + // Close the supervisorScope to join on all feeds. + } + // Reduce and throw any caught exceptions. + if (exceptions.isNotEmpty()) { + throw feeds + .mapNotNull { exceptions[it] } + .reduce { acc: Throwable, exception: Throwable -> + acc.addSuppressed(exception) + acc } - // Reduce and throw any caught exceptions. - val caughtExceptions: List = - globalExceptions.values.mapNotNull { it } + - streamExceptions.values.mapNotNull { it } - if (caughtExceptions.isNotEmpty()) { - val cause: Throwable = - caughtExceptions.reduce { acc: Throwable, exception: Throwable -> - acc.addSuppressed(exception) - acc - } - throw cause - } } } - class FeedExceptionHandler( - val feed: Feed, + class FeedExceptionHandler( + val feed: T, val streamStatusManager: StreamStatusManager, - private val exceptions: ConcurrentHashMap, + private val exceptions: ConcurrentHashMap, ) : CoroutineExceptionHandler { private val log = KotlinLogging.logger {} diff --git a/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/StateManager.kt b/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/StateManager.kt index d051867c0f74..f054c0cec8ff 100644 --- a/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/StateManager.kt +++ b/airbyte-cdk/bulk/core/extract/src/main/kotlin/io/airbyte/cdk/read/StateManager.kt @@ -4,6 +4,7 @@ package io.airbyte.cdk.read import io.airbyte.cdk.StreamIdentifier import io.airbyte.cdk.asProtocolStreamDescriptor import io.airbyte.cdk.command.OpaqueStateValue +import io.airbyte.cdk.util.Jsons import io.airbyte.protocol.models.v0.AirbyteGlobalState import io.airbyte.protocol.models.v0.AirbyteStateMessage import io.airbyte.protocol.models.v0.AirbyteStateStats @@ -16,6 +17,9 @@ interface StateQuerier { /** Returns the current state value for the given [feed]. */ fun current(feed: Feed): OpaqueStateValue? + + /** Rolls back each feed state. This is required when resyncing CDC from scratch */ + fun resetFeedStates() } /** Singleton object which tracks the state of an ongoing READ operation. */ @@ -36,18 +40,15 @@ class StateManager( .mapKeys { it.key.id } } else { val globalStreams: Map = - global.streams.associateWith { initialStreamStates[it] } + global.streams.associateWith { initialStreamStates[it] } + + initialStreamStates.filterKeys { global.streams.contains(it).not() } this.global = GlobalStateManager( global = global, initialGlobalState = initialGlobalState, initialStreamStates = globalStreams, ) - nonGlobal = - initialStreamStates - .filterKeys { !globalStreams.containsKey(it) } - .mapValues { NonGlobalStreamStateManager(it.key, it.value) } - .mapKeys { it.key.id } + nonGlobal = emptyMap() } } @@ -58,6 +59,10 @@ class StateManager( override fun current(feed: Feed): OpaqueStateValue? = scoped(feed).current() + override fun resetFeedStates() { + feeds.forEach { f -> scoped(f).set(Jsons.objectNode(), 0) } + } + /** Returns a [StateManagerScopedToFeed] instance scoped to this [feed]. */ fun scoped(feed: Feed): StateManagerScopedToFeed = when (feed) { @@ -88,15 +93,19 @@ class StateManager( * Updates the internal state of the [StateManager] to ensure idempotency (no redundant messages * are emitted). */ - fun checkpoint(): List = - listOfNotNull(global?.checkpoint()) + nonGlobal.mapNotNull { it.value.checkpoint() } + fun checkpoint(): List { + return listOfNotNull(global?.checkpoint()) + + nonGlobal + .mapNotNull { it.value.checkpoint() } + .filter { it.stream.streamState.isNull.not() } + } private sealed class BaseStateManager( override val feed: K, initialState: OpaqueStateValue?, ) : StateManagerScopedToFeed { private var currentStateValue: OpaqueStateValue? = initialState - private var pendingStateValue: OpaqueStateValue? = initialState + private var pendingStateValue: OpaqueStateValue? = null private var pendingNumRecords: Long = 0L @Synchronized override fun current(): OpaqueStateValue? = currentStateValue @@ -199,7 +208,14 @@ class StateManager( streamStates.add( AirbyteStreamState() .withStreamDescriptor(streamID.asProtocolStreamDescriptor()) - .withStreamState(streamStateForCheckpoint.opaqueStateValue), + .withStreamState( + when (streamStateForCheckpoint.opaqueStateValue?.isNull) { + null, + true -> Jsons.objectNode() + false -> streamStateForCheckpoint.opaqueStateValue + ?: Jsons.objectNode() + } + ), ) } if (!shouldCheckpoint) { @@ -233,7 +249,9 @@ class StateManager( val airbyteStreamState = AirbyteStreamState() .withStreamDescriptor(feed.id.asProtocolStreamDescriptor()) - .withStreamState(streamStateForCheckpoint.opaqueStateValue) + .withStreamState( + streamStateForCheckpoint.opaqueStateValue ?: Jsons.objectNode() + ) return AirbyteStateMessage() .withType(AirbyteStateMessage.AirbyteStateType.STREAM) .withStream(airbyteStreamState) diff --git a/airbyte-cdk/bulk/core/extract/src/test/kotlin/io/airbyte/cdk/command/ConfigurationSpecificationSupplierTest.kt b/airbyte-cdk/bulk/core/extract/src/test/kotlin/io/airbyte/cdk/command/ConfigurationSpecificationSupplierTest.kt index 30e82dd33668..6d4b2b57cc2a 100644 --- a/airbyte-cdk/bulk/core/extract/src/test/kotlin/io/airbyte/cdk/command/ConfigurationSpecificationSupplierTest.kt +++ b/airbyte-cdk/bulk/core/extract/src/test/kotlin/io/airbyte/cdk/command/ConfigurationSpecificationSupplierTest.kt @@ -24,8 +24,12 @@ class ConfigurationSpecificationSupplierTest { FakeSourceConfigurationSpecification::class.java, supplier.javaClass ) - val expected: String = ResourceUtils.readResource("fakesource/expected-schema.json") - Assertions.assertEquals(Jsons.readTree(expected), supplier.jsonSchema) + val expected: String = + ResourceUtils.readResource("fakesource/expected-schema.json") + .let(Jsons::readTree) + .let(Jsons::writeValueAsString) + val actual: String = Jsons.writeValueAsString(supplier.jsonSchema) + Assertions.assertEquals(expected, actual) } @Test diff --git a/airbyte-cdk/bulk/core/extract/src/test/kotlin/io/airbyte/cdk/read/FeedBootstrapTest.kt b/airbyte-cdk/bulk/core/extract/src/test/kotlin/io/airbyte/cdk/read/FeedBootstrapTest.kt index ae42c7953736..01df86b9311b 100644 --- a/airbyte-cdk/bulk/core/extract/src/test/kotlin/io/airbyte/cdk/read/FeedBootstrapTest.kt +++ b/airbyte-cdk/bulk/core/extract/src/test/kotlin/io/airbyte/cdk/read/FeedBootstrapTest.kt @@ -60,6 +60,10 @@ class FeedBootstrapTest { is Global -> globalStateValue is Stream -> streamStateValue } + + override fun resetFeedStates() { + // no-op + } } fun Feed.bootstrap(stateQuerier: StateQuerier): FeedBootstrap<*> = @@ -140,6 +144,9 @@ class FeedBootstrapTest { object : StateQuerier { override val feeds: List = listOf(stream) override fun current(feed: Feed): OpaqueStateValue? = null + override fun resetFeedStates() { + // no-op + } } val streamBootstrap = stream.bootstrap(stateQuerier) as StreamFeedBootstrap val consumer: StreamRecordConsumer = streamBootstrap.streamRecordConsumer() diff --git a/airbyte-cdk/bulk/core/extract/src/test/kotlin/io/airbyte/cdk/read/StateManagerGlobalStatesTest.kt b/airbyte-cdk/bulk/core/extract/src/test/kotlin/io/airbyte/cdk/read/StateManagerGlobalStatesTest.kt index 6f21a1d532c4..163834dd0653 100644 --- a/airbyte-cdk/bulk/core/extract/src/test/kotlin/io/airbyte/cdk/read/StateManagerGlobalStatesTest.kt +++ b/airbyte-cdk/bulk/core/extract/src/test/kotlin/io/airbyte/cdk/read/StateManagerGlobalStatesTest.kt @@ -78,16 +78,11 @@ class StateManagerGlobalStatesTest { |"global":{"shared_state":{"cdc":"starting"}, |"stream_states":[ |{"stream_descriptor":{"name":"KV","namespace":"PUBLIC"}, - |"stream_state":{"initial_sync":"ongoing"}} + |"stream_state":{"initial_sync":"ongoing"}}, + |{"stream_descriptor":{"name":"EVENTS","namespace":"PUBLIC"}, + |"stream_state":{"full_refresh":"ongoing"}} |]}, - |"sourceStats":{"recordCount":123.0} - |} - """.trimMargin(), - """{ - |"type":"STREAM", - |"stream":{"stream_descriptor":{"name":"EVENTS","namespace":"PUBLIC"}, - |"stream_state":{"full_refresh":"ongoing"}}, - |"sourceStats":{"recordCount":456.0} + |"sourceStats":{"recordCount":579.0} |} """.trimMargin(), ) @@ -124,7 +119,9 @@ class StateManagerGlobalStatesTest { |"global":{"shared_state":{"cdc":"starting"}, |"stream_states":[ |{"stream_descriptor":{"name":"KV","namespace":"PUBLIC"}, - |"stream_state":{"initial_sync":"ongoing"}} + |"stream_state":{"initial_sync":"ongoing"}}, + |{"stream_descriptor":{"name":"EVENTS","namespace":"PUBLIC"}, + |"stream_state":{}} |]},"sourceStats":{"recordCount":123.0} |} """.trimMargin(), @@ -147,7 +144,9 @@ class StateManagerGlobalStatesTest { |"global":{"shared_state":{"cdc":"starting"}, |"stream_states":[ |{"stream_descriptor":{"name":"KV","namespace":"PUBLIC"}, - |"stream_state":{"initial_sync":"completed"}} + |"stream_state":{"initial_sync":"completed"}}, + |{"stream_descriptor":{"name":"EVENTS","namespace":"PUBLIC"}, + |"stream_state":{}} |]},"sourceStats":{"recordCount":1245.0} |} """.trimMargin(), @@ -197,7 +196,9 @@ class StateManagerGlobalStatesTest { |"global":{"shared_state":{"cdc":"starting"}, |"stream_states":[ |{"stream_descriptor":{"name":"KV","namespace":"PUBLIC"}, - |"stream_state":{"initial_sync":"completed"}} + |"stream_state":{"initial_sync":"completed"}}, + |{"stream_descriptor":{"name":"EVENTS","namespace":"PUBLIC"}, + |"stream_state":{}} |]},"sourceStats":{"recordCount":789.0} |} """.trimMargin(), @@ -245,7 +246,9 @@ class StateManagerGlobalStatesTest { |"global":{"shared_state":{"cdc":"ongoing"}, |"stream_states":[ |{"stream_descriptor":{"name":"KV","namespace":"PUBLIC"}, - |"stream_state":{"initial_sync":"completed"}} + |"stream_state":{"initial_sync":"completed"}}, + |{"stream_descriptor":{"name":"EVENTS","namespace":"PUBLIC"}, + |"stream_state":{}} |]}, |"sourceStats":{"recordCount":741.0} |} diff --git a/airbyte-cdk/bulk/core/extract/src/test/kotlin/io/airbyte/cdk/read/StateManagerStreamStatesTest.kt b/airbyte-cdk/bulk/core/extract/src/test/kotlin/io/airbyte/cdk/read/StateManagerStreamStatesTest.kt index 904375096d59..8f67bb901800 100644 --- a/airbyte-cdk/bulk/core/extract/src/test/kotlin/io/airbyte/cdk/read/StateManagerStreamStatesTest.kt +++ b/airbyte-cdk/bulk/core/extract/src/test/kotlin/io/airbyte/cdk/read/StateManagerStreamStatesTest.kt @@ -159,6 +159,11 @@ class StateManagerStreamStatesTest { stateManager.scoped(stream).current(), ) Assertions.assertEquals(listOf(), handler.get()) + + val emptyCheckpoint: List = stateManager.checkpoint() + // check if state manager hasn't set for this stream, state would be null and thus skipped. + Assertions.assertTrue(emptyCheckpoint.isEmpty()) + // update state manager with fake work result stateManager .scoped(stream) diff --git a/airbyte-cdk/bulk/core/extract/src/testFixtures/kotlin/io/airbyte/cdk/read/DynamicDatatypeTestFactory.kt b/airbyte-cdk/bulk/core/extract/src/testFixtures/kotlin/io/airbyte/cdk/read/DynamicDatatypeTestFactory.kt new file mode 100644 index 000000000000..851a346fe495 --- /dev/null +++ b/airbyte-cdk/bulk/core/extract/src/testFixtures/kotlin/io/airbyte/cdk/read/DynamicDatatypeTestFactory.kt @@ -0,0 +1,310 @@ +/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ +package io.airbyte.cdk.read + +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.ObjectNode +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings +import io.airbyte.cdk.ClockFactory +import io.airbyte.cdk.command.CliRunner +import io.airbyte.cdk.command.ConfigurationSpecification +import io.airbyte.cdk.command.SourceConfiguration +import io.airbyte.cdk.command.SourceConfigurationFactory +import io.airbyte.cdk.data.AirbyteSchemaType +import io.airbyte.cdk.discover.MetaField +import io.airbyte.cdk.output.BufferingOutputConsumer +import io.airbyte.cdk.util.Jsons +import io.airbyte.protocol.models.v0.AirbyteLogMessage +import io.airbyte.protocol.models.v0.AirbyteMessage +import io.airbyte.protocol.models.v0.AirbyteRecordMessage +import io.airbyte.protocol.models.v0.AirbyteStateMessage +import io.airbyte.protocol.models.v0.AirbyteStream +import io.airbyte.protocol.models.v0.AirbyteTraceMessage +import io.airbyte.protocol.models.v0.CatalogHelpers +import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog +import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream +import io.airbyte.protocol.models.v0.SyncMode +import io.github.oshai.kotlinlogging.KotlinLogging +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.DynamicContainer +import org.junit.jupiter.api.DynamicNode +import org.junit.jupiter.api.DynamicTest +import org.junit.jupiter.api.function.Executable +import org.testcontainers.containers.GenericContainer + +class DynamicDatatypeTestFactory< + DB : GenericContainer<*>, + CS : ConfigurationSpecification, + C : SourceConfiguration, + F : SourceConfigurationFactory, + T : DatatypeTestCase, +>( + val ops: DatatypeTestOperations, +) { + private val log = KotlinLogging.logger {} + + fun build(dbContainer: DB): Iterable { + val actual = DiscoverAndReadAll(ops) { dbContainer } + val discoverAndReadAllTest: DynamicNode = + DynamicTest.dynamicTest("discover-and-read-all", actual) + val testCases: List = + ops.testCases.map { (id: String, testCase: T) -> + DynamicContainer.dynamicContainer(id, dynamicTests(actual, testCase)) + } + return listOf(discoverAndReadAllTest) + testCases + } + + private fun dynamicTests( + actual: DiscoverAndReadAll, + testCase: T + ): List { + val streamTests: List = + if (!testCase.isStream) emptyList() + else + listOf( + DynamicTest.dynamicTest("discover-stream") { + discover(testCase, actual.streamCatalog[testCase.id]) + }, + DynamicTest.dynamicTest("records-stream") { + records(testCase, actual.streamMessagesByStream[testCase.id]) + }, + ) + val globalTests: List = + if (!ops.withGlobal || !testCase.isGlobal) emptyList() + else + listOf( + DynamicTest.dynamicTest("discover-global") { + discover(testCase, actual.globalCatalog[testCase.id]) + }, + DynamicTest.dynamicTest("records-global") { + records(testCase, actual.globalMessagesByStream[testCase.id]) + }, + ) + return streamTests + globalTests + } + + private fun discover(testCase: T, actualStream: AirbyteStream?) { + Assertions.assertNotNull(actualStream) + log.info { + val streamJson: JsonNode = Jsons.valueToTree(actualStream) + "test case ${testCase.id}: discovered stream $streamJson" + } + val jsonSchema: JsonNode = actualStream!!.jsonSchema?.get("properties")!! + val actualSchema: JsonNode? = jsonSchema[testCase.fieldName] + Assertions.assertNotNull(actualSchema) + val expectedSchema: JsonNode = testCase.expectedAirbyteSchemaType.asJsonSchema() + Assertions.assertEquals(expectedSchema, actualSchema) + } + + private fun records(testCase: T, actualRead: BufferingOutputConsumer?) { + Assertions.assertNotNull(actualRead) + val actualRecords: List = actualRead?.records() ?: emptyList() + val actual: String = + actualRecords + .mapNotNull { actualFieldData(testCase, it) } + .sorted() + .joinToString(separator = ",", prefix = "[", postfix = "]") + log.info { "test case ${testCase.id}: emitted records $actual" } + val expected: String = + testCase.expectedData + .sorted() + .joinToString(separator = ",", prefix = "[", postfix = "]") + Assertions.assertEquals(expected, actual) + } + + private fun actualFieldData(testCase: T, record: AirbyteRecordMessage): String? { + val data: ObjectNode = record.data as? ObjectNode ?: return null + val result: ObjectNode = data.deepCopy() + for (fieldName in data.fieldNames()) { + if (fieldName.equals(testCase.fieldName, ignoreCase = true)) continue + result.remove(fieldName) + } + return Jsons.writeValueAsString(result) + } +} + +interface DatatypeTestOperations< + DB : GenericContainer<*>, + CS : ConfigurationSpecification, + C : SourceConfiguration, + F : SourceConfigurationFactory, + T : DatatypeTestCase, +> { + val withGlobal: Boolean + val globalCursorMetaField: MetaField + fun streamConfigSpec(container: DB): CS + fun globalConfigSpec(container: DB): CS + val configFactory: F + val testCases: Map + fun createStreams(config: C) + fun populateStreams(config: C) +} + +interface DatatypeTestCase { + val id: String + val fieldName: String + val isGlobal: Boolean + val isStream: Boolean + val expectedAirbyteSchemaType: AirbyteSchemaType + val expectedData: List +} + +@SuppressFBWarnings(value = ["NP_NONNULL_RETURN_VIOLATION"], justification = "control flow") +class DiscoverAndReadAll< + DB : GenericContainer<*>, + CS : ConfigurationSpecification, + C : SourceConfiguration, + F : SourceConfigurationFactory, + T : DatatypeTestCase, +>( + val ops: DatatypeTestOperations, + dbContainerSupplier: () -> DB, +) : Executable { + private val log = KotlinLogging.logger {} + private val dbContainer: DB by lazy { dbContainerSupplier() } + + // CDC DISCOVER and READ intermediate values and final results. + // Intermediate values are present here as `lateinit var` instead of local variables + // to make debugging of individual test cases easier. + lateinit var globalConfigSpec: CS + lateinit var globalConfig: C + lateinit var globalCatalog: Map + lateinit var globalConfiguredCatalog: ConfiguredAirbyteCatalog + lateinit var globalInitialReadOutput: BufferingOutputConsumer + lateinit var globalCheckpoint: AirbyteStateMessage + lateinit var globalSubsequentReadOutput: BufferingOutputConsumer + lateinit var globalMessages: List + lateinit var globalMessagesByStream: Map + // Same as above but for JDBC. + lateinit var streamConfigSpec: CS + lateinit var streamConfig: C + lateinit var streamCatalog: Map + lateinit var streamConfiguredCatalog: ConfiguredAirbyteCatalog + lateinit var streamReadOutput: BufferingOutputConsumer + lateinit var streamMessages: List + lateinit var streamMessagesByStream: Map + + override fun execute() { + log.info { "Generating stream-sync config." } + streamConfigSpec = ops.streamConfigSpec(dbContainer) + streamConfig = ops.configFactory.make(streamConfigSpec) + log.info { "Creating empty datatype streams in source." } + ops.createStreams(streamConfig) + log.info { "Executing DISCOVER operation with stream-sync config." } + streamCatalog = discover(streamConfigSpec) + streamConfiguredCatalog = + configuredCatalog(streamCatalog.filterKeys { ops.testCases[it]?.isStream == true }) + if (ops.withGlobal) { + log.info { "Generating global-sync config." } + globalConfigSpec = ops.globalConfigSpec(dbContainer) + globalConfig = ops.configFactory.make(globalConfigSpec) + log.info { "Executing DISCOVER operation with global-sync config." } + globalCatalog = discover(globalConfigSpec) + globalConfiguredCatalog = + configuredCatalog(globalCatalog.filterKeys { ops.testCases[it]?.isGlobal == true }) + log.info { "Running initial global-sync READ operation." } + globalInitialReadOutput = + CliRunner.source("read", globalConfigSpec, globalConfiguredCatalog).run() + Assertions.assertNotEquals( + emptyList(), + globalInitialReadOutput.states() + ) + globalCheckpoint = globalInitialReadOutput.states().last() + Assertions.assertEquals( + emptyList(), + globalInitialReadOutput.records() + ) + Assertions.assertEquals(emptyList(), globalInitialReadOutput.logs()) + } + log.info { "Populating datatype streams in source." } + ops.populateStreams(streamConfig) + if (ops.withGlobal) { + log.info { "Running subsequent global-sync READ operation." } + globalSubsequentReadOutput = + CliRunner.source( + "read", + globalConfigSpec, + globalConfiguredCatalog, + listOf(globalCheckpoint) + ) + .run() + Assertions.assertNotEquals( + emptyList(), + globalSubsequentReadOutput.states() + ) + Assertions.assertNotEquals( + emptyList(), + globalSubsequentReadOutput.records() + ) + Assertions.assertEquals( + emptyList(), + globalSubsequentReadOutput.logs() + ) + globalMessages = globalSubsequentReadOutput.messages() + globalMessagesByStream = byStream(globalConfiguredCatalog, globalMessages) + } + log.info { "Running stream-sync READ operation." } + streamReadOutput = CliRunner.source("read", streamConfigSpec, streamConfiguredCatalog).run() + Assertions.assertNotEquals(emptyList(), streamReadOutput.states()) + Assertions.assertNotEquals(emptyList(), streamReadOutput.records()) + Assertions.assertEquals(emptyList(), streamReadOutput.logs()) + streamMessages = streamReadOutput.messages() + streamMessagesByStream = byStream(streamConfiguredCatalog, streamMessages) + log.info { "Done." } + } + + private fun discover(configSpec: CS): Map { + val output: BufferingOutputConsumer = CliRunner.source("discover", configSpec).run() + val streams: Map = + output.catalogs().firstOrNull()?.streams?.filterNotNull()?.associateBy { it.name } + ?: mapOf() + Assertions.assertFalse(streams.isEmpty()) + return streams + } + + private fun configuredCatalog(streams: Map): ConfiguredAirbyteCatalog { + val configuredStreams: List = + streams.values.map(CatalogHelpers::toDefaultConfiguredStream) + for (configuredStream in configuredStreams) { + if ( + configuredStream.stream.supportedSyncModes.contains(SyncMode.INCREMENTAL) && + configuredStream.stream.sourceDefinedCursor == true + ) { + configuredStream.syncMode = SyncMode.INCREMENTAL + configuredStream.cursorField = listOf(ops.globalCursorMetaField.id) + } else { + configuredStream.syncMode = SyncMode.FULL_REFRESH + } + } + return ConfiguredAirbyteCatalog().withStreams(configuredStreams) + } + + private fun byStream( + configuredCatalog: ConfiguredAirbyteCatalog, + messages: List + ): Map { + val result: Map = + configuredCatalog.streams.associate { + it.stream.name to BufferingOutputConsumer(ClockFactory().fixed()) + } + for (msg in messages) { + result[streamName(msg) ?: continue]?.accept(msg) + } + return result + } + + private fun streamName(msg: AirbyteMessage): String? = + when (msg.type) { + AirbyteMessage.Type.RECORD -> msg.record?.stream + AirbyteMessage.Type.STATE -> msg.state?.stream?.streamDescriptor?.name + AirbyteMessage.Type.TRACE -> + when (msg.trace?.type) { + AirbyteTraceMessage.Type.ERROR -> msg.trace?.error?.streamDescriptor?.name + AirbyteTraceMessage.Type.ESTIMATE -> msg.trace?.estimate?.name + AirbyteTraceMessage.Type.STREAM_STATUS -> + msg.trace?.streamStatus?.streamDescriptor?.name + AirbyteTraceMessage.Type.ANALYTICS -> null + null -> null + } + else -> null + } +} diff --git a/airbyte-cdk/bulk/core/load/build.gradle b/airbyte-cdk/bulk/core/load/build.gradle index 2d175563f41b..8898379c9a2e 100644 --- a/airbyte-cdk/bulk/core/load/build.gradle +++ b/airbyte-cdk/bulk/core/load/build.gradle @@ -21,8 +21,12 @@ dependencies { testFixturesApi testFixtures(project(':airbyte-cdk:bulk:core:bulk-cdk-core-base')) testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1") + testImplementation("io.mockk:mockk:1.13.12") implementation "org.jetbrains.kotlin:kotlin-reflect:2.0.20" testFixturesImplementation "uk.org.webcompere:system-stubs-jupiter:2.1.7" + + implementation 'com.fasterxml.jackson.module:jackson-module-kotlin' + implementation 'com.fasterxml.jackson.module:jackson-module-afterburner' } def integrationTestTask = tasks.register('integrationTest', Test) { @@ -36,12 +40,31 @@ def integrationTestTask = tasks.register('integrationTest', Test) { systemProperties = project.test.systemProperties maxParallelForks = project.test.maxParallelForks maxHeapSize = project.test.maxHeapSize + + testLogging() { + events 'skipped', 'started', 'passed', 'failed' + exceptionFormat 'full' + } } + // These tests are lightweight enough to run on every PR. tasks.named('check').configure { dependsOn integrationTest } +project.tasks.matching { + it.name == 'spotbugsIntegrationTestLegacy' || + it.name == 'spotbugsIntegrationTest' || + it.name == 'spotbugsTest' || + it.name == 'spotbugsMain' +}.configureEach { + enabled = false +} + +test { + systemProperties(["mockk.junit.extension.requireParallelTesting":"true"]) +} + configurations { integrationTestImplementation.extendsFrom testImplementation integrationTestRuntimeOnly.extendsFrom testRuntimeOnly diff --git a/airbyte-cdk/bulk/core/load/src/integrationTest/kotlin/io/airbyte/cdk/load/mock_integration_test/MockBasicFunctionalityIntegrationTest.kt b/airbyte-cdk/bulk/core/load/src/integrationTest/kotlin/io/airbyte/cdk/load/mock_integration_test/MockBasicFunctionalityIntegrationTest.kt index 361eb2156a10..6e3891269cfc 100644 --- a/airbyte-cdk/bulk/core/load/src/integrationTest/kotlin/io/airbyte/cdk/load/mock_integration_test/MockBasicFunctionalityIntegrationTest.kt +++ b/airbyte-cdk/bulk/core/load/src/integrationTest/kotlin/io/airbyte/cdk/load/mock_integration_test/MockBasicFunctionalityIntegrationTest.kt @@ -5,9 +5,11 @@ package io.airbyte.cdk.load.mock_integration_test import io.airbyte.cdk.load.test.util.NoopDestinationCleaner -import io.airbyte.cdk.load.test.util.NoopExpectedRecordMapper import io.airbyte.cdk.load.test.util.NoopNameMapper +import io.airbyte.cdk.load.test.util.UncoercedExpectedRecordMapper import io.airbyte.cdk.load.write.BasicFunctionalityIntegrationTest +import io.airbyte.cdk.load.write.Untyped +import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test class MockBasicFunctionalityIntegrationTest : @@ -16,10 +18,17 @@ class MockBasicFunctionalityIntegrationTest : MockDestinationSpecification::class.java, MockDestinationDataDumper, NoopDestinationCleaner, - NoopExpectedRecordMapper, + UncoercedExpectedRecordMapper, NoopNameMapper, isStreamSchemaRetroactive = false, supportsDedup = true, + stringifySchemalessObjects = false, + promoteUnionToObject = false, + preserveUndeclaredFields = true, + commitDataIncrementally = false, + allTypesBehavior = Untyped, + envVars = emptyMap(), + supportFileTransfer = false, ) { @Test override fun testBasicWrite() { @@ -46,6 +55,16 @@ class MockBasicFunctionalityIntegrationTest : super.testTruncateRefresh() } + @Test + override fun testInterruptedTruncateWithPriorData() { + super.testInterruptedTruncateWithPriorData() + } + + @Test + override fun resumeAfterCancelledTruncate() { + super.resumeAfterCancelledTruncate() + } + @Test override fun testAppend() { super.testAppend() @@ -56,8 +75,24 @@ class MockBasicFunctionalityIntegrationTest : super.testAppendSchemaEvolution() } + @Disabled("flaky") @Test override fun testDedup() { super.testDedup() } + + @Test + override fun testContainerTypes() { + super.testContainerTypes() + } + + @Test + override fun testUnions() { + super.testUnions() + } + + @Test + override fun testBasicTypes() { + super.testBasicTypes() + } } diff --git a/airbyte-cdk/bulk/core/load/src/integrationTest/kotlin/io/airbyte/cdk/load/mock_integration_test/MockDestinationBackend.kt b/airbyte-cdk/bulk/core/load/src/integrationTest/kotlin/io/airbyte/cdk/load/mock_integration_test/MockDestinationBackend.kt index 174d55aad58b..8b1718645da3 100644 --- a/airbyte-cdk/bulk/core/load/src/integrationTest/kotlin/io/airbyte/cdk/load/mock_integration_test/MockDestinationBackend.kt +++ b/airbyte-cdk/bulk/core/load/src/integrationTest/kotlin/io/airbyte/cdk/load/mock_integration_test/MockDestinationBackend.kt @@ -13,9 +13,11 @@ import io.airbyte.cdk.load.test.util.DestinationDataDumper import io.airbyte.cdk.load.test.util.OutputRecord import io.airbyte.cdk.load.test.util.RecordDiffer import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.ConcurrentLinkedQueue object MockDestinationBackend { - private val files: MutableMap> = ConcurrentHashMap() + private val files: ConcurrentHashMap> = + ConcurrentHashMap() fun insert(filename: String, vararg records: OutputRecord) { getFile(filename).addAll(records) @@ -54,13 +56,17 @@ object MockDestinationBackend { // Assume that in dedup mode, we don't have duplicates - so we can just find the first // record with the same PK as the incoming record val existingRecord = - file.firstOrNull { RecordDiffer.comparePks(incomingPk, getPk(it)) == 0 } + file.firstOrNull { + RecordDiffer.comparePks(incomingPk, getPk(it), nullEqualsUnset = false) == 0 + } if (existingRecord == null) { file.add(incomingRecord) } else { val incomingCursor = getCursor(incomingRecord) val existingCursor = getCursor(existingRecord) - val compare = RecordDiffer.valueComparator.compare(incomingCursor, existingCursor) + val compare = + RecordDiffer.getValueComparator(nullEqualsUnset = false) + .compare(incomingCursor, existingCursor) // If the incoming record has a later cursor, // or the same cursor but a later extractedAt, // then upsert. (otherwise discard the incoming record.) @@ -78,8 +84,25 @@ object MockDestinationBackend { } } + fun commitFrom(srcFilename: String, dstFilename: String) { + val src = getFile(srcFilename) + insert(dstFilename, *src.toTypedArray()) + src.clear() + } + + fun commitAndDedupeFrom( + srcFilename: String, + dstFilename: String, + primaryKey: List>, + cursor: List, + ) { + val src = getFile(srcFilename) + upsert(dstFilename, primaryKey, cursor, *src.toTypedArray()) + src.clear() + } + fun readFile(filename: String): List { - return getFile(filename) + return getFile(filename).toList() } fun deleteOldRecords(filename: String, minGenerationId: Long) { @@ -88,8 +111,8 @@ object MockDestinationBackend { } } - private fun getFile(filename: String): MutableList { - return files.getOrPut(filename) { mutableListOf() } + private fun getFile(filename: String): ConcurrentLinkedQueue { + return files.getOrPut(filename) { ConcurrentLinkedQueue() } } } @@ -102,4 +125,12 @@ object MockDestinationDataDumper : DestinationDataDumper { MockStreamLoader.getFilename(stream.descriptor.namespace, stream.descriptor.name) ) } + + override fun dumpFile( + spec: ConfigurationSpecification, + stream: DestinationStream + ): List { + // Not needed since the test is disabled for file transfer + throw NotImplementedError() + } } diff --git a/airbyte-cdk/bulk/core/load/src/integrationTest/kotlin/io/airbyte/cdk/load/mock_integration_test/MockDestinationConfiguration.kt b/airbyte-cdk/bulk/core/load/src/integrationTest/kotlin/io/airbyte/cdk/load/mock_integration_test/MockDestinationConfiguration.kt index af0486d9d0e9..df97498a2693 100644 --- a/airbyte-cdk/bulk/core/load/src/integrationTest/kotlin/io/airbyte/cdk/load/mock_integration_test/MockDestinationConfiguration.kt +++ b/airbyte-cdk/bulk/core/load/src/integrationTest/kotlin/io/airbyte/cdk/load/mock_integration_test/MockDestinationConfiguration.kt @@ -11,8 +11,8 @@ import io.micronaut.context.annotation.Factory import jakarta.inject.Singleton class MockDestinationConfiguration : DestinationConfiguration() { - // override to 10KB instead of 200MB - override val recordBatchSizeBytes = 10 * 1024L + // Micro-batch for testing. + override val recordBatchSizeBytes = 1L } @Singleton diff --git a/airbyte-cdk/bulk/core/load/src/integrationTest/kotlin/io/airbyte/cdk/load/mock_integration_test/MockDestinationWriter.kt b/airbyte-cdk/bulk/core/load/src/integrationTest/kotlin/io/airbyte/cdk/load/mock_integration_test/MockDestinationWriter.kt index e1524187f2ba..efc49f2463cb 100644 --- a/airbyte-cdk/bulk/core/load/src/integrationTest/kotlin/io/airbyte/cdk/load/mock_integration_test/MockDestinationWriter.kt +++ b/airbyte-cdk/bulk/core/load/src/integrationTest/kotlin/io/airbyte/cdk/load/mock_integration_test/MockDestinationWriter.kt @@ -4,19 +4,24 @@ package io.airbyte.cdk.load.mock_integration_test +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings +import io.airbyte.cdk.load.command.Append import io.airbyte.cdk.load.command.Dedupe import io.airbyte.cdk.load.command.DestinationStream import io.airbyte.cdk.load.data.ObjectValue import io.airbyte.cdk.load.message.Batch -import io.airbyte.cdk.load.message.DestinationRecord +import io.airbyte.cdk.load.message.DestinationFile +import io.airbyte.cdk.load.message.DestinationRecordAirbyteValue import io.airbyte.cdk.load.message.SimpleBatch -import io.airbyte.cdk.load.mock_integration_test.MockStreamLoader.Companion.getFilename +import io.airbyte.cdk.load.state.StreamProcessingFailed import io.airbyte.cdk.load.test.util.OutputRecord import io.airbyte.cdk.load.write.DestinationWriter import io.airbyte.cdk.load.write.StreamLoader +import io.github.oshai.kotlinlogging.KotlinLogging import java.time.Instant import java.util.UUID import javax.inject.Singleton +import kotlinx.coroutines.delay @Singleton class MockDestinationWriter : DestinationWriter { @@ -25,24 +30,51 @@ class MockDestinationWriter : DestinationWriter { } } +@SuppressFBWarnings("NP_NONNULL_PARAM_VIOLATION", justification = "Kotlin async continuation") class MockStreamLoader(override val stream: DestinationStream) : StreamLoader { - data class LocalBatch(val records: List) : Batch { - override val state = Batch.State.LOCAL + private val log = KotlinLogging.logger {} + + abstract class MockBatch : Batch { + override val groupId: String? = null + } + + data class LocalBatch(val records: List) : MockBatch() { + override val state = Batch.State.STAGED } - data class PersistedBatch(val records: List) : Batch { - override val state = Batch.State.PERSISTED + data class LocalFileBatch(val file: DestinationFile) : MockBatch() { + override val state = Batch.State.STAGED } - override suspend fun start() { - MockDestinationBackend.deleteOldRecords( - getFilename(stream.descriptor), - stream.minimumGenerationId - ) + override suspend fun close(streamFailure: StreamProcessingFailed?) { + if (streamFailure == null) { + when (val importType = stream.importType) { + is Append -> { + MockDestinationBackend.commitFrom( + getFilename(stream.descriptor, staging = true), + getFilename(stream.descriptor) + ) + } + is Dedupe -> { + MockDestinationBackend.commitAndDedupeFrom( + getFilename(stream.descriptor, staging = true), + getFilename(stream.descriptor), + importType.primaryKey, + importType.cursor, + ) + } + else -> throw IllegalArgumentException("Unsupported import type $importType") + } + MockDestinationBackend.deleteOldRecords( + getFilename(stream.descriptor), + stream.minimumGenerationId + ) + } } override suspend fun processRecords( - records: Iterator, - totalSizeBytes: Long + records: Iterator, + totalSizeBytes: Long, + endOfStream: Boolean ): Batch { return LocalBatch(records.asSequence().toList()) } @@ -50,8 +82,9 @@ class MockStreamLoader(override val stream: DestinationStream) : StreamLoader { override suspend fun processBatch(batch: Batch): Batch { return when (batch) { is LocalBatch -> { + log.info { "Persisting ${batch.records.size} records for ${stream.descriptor}" } batch.records.forEach { - val filename = getFilename(it.stream) + val filename = getFilename(it.stream, staging = true) val record = OutputRecord( UUID.randomUUID(), @@ -60,32 +93,33 @@ class MockStreamLoader(override val stream: DestinationStream) : StreamLoader { stream.generationId, it.data as ObjectValue, OutputRecord.Meta( - changes = it.meta?.changes ?: mutableListOf(), + changes = it.meta?.changes ?: listOf(), syncId = stream.syncId ), ) - val importType = stream.importType - if (importType is Dedupe) { - MockDestinationBackend.upsert( - filename, - importType.primaryKey, - importType.cursor, - record - ) - } else { - MockDestinationBackend.insert(filename, record) - } + // blind insert into the staging area. We'll dedupe on commit. + MockDestinationBackend.insert(filename, record) } - PersistedBatch(batch.records) + // HACK: This destination is too fast and causes a race + // condition between consuming and flushing state messages + // that causes the test to fail. This would not be an issue + // in a real sync, because we would always either get more + // data or an end-of-stream that would force a final flush. + delay(100L) + SimpleBatch(state = Batch.State.COMPLETE) } - is PersistedBatch -> SimpleBatch(state = Batch.State.COMPLETE) else -> throw IllegalStateException("Unexpected batch type: $batch") } } companion object { - fun getFilename(stream: DestinationStream.Descriptor) = - getFilename(stream.namespace, stream.name) - fun getFilename(namespace: String?, name: String) = "(${namespace},${name})" + fun getFilename(stream: DestinationStream.Descriptor, staging: Boolean = false) = + getFilename(stream.namespace, stream.name, staging) + fun getFilename(namespace: String?, name: String, staging: Boolean = false) = + if (staging) { + "(${namespace},${name},staging)" + } else { + "(${namespace},${name})" + } } } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/check/DestinationChecker.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/check/DestinationChecker.kt index de44f79fd389..e46ef32658d3 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/check/DestinationChecker.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/check/DestinationChecker.kt @@ -7,7 +7,7 @@ package io.airbyte.cdk.load.check import io.airbyte.cdk.load.command.Append import io.airbyte.cdk.load.command.DestinationConfiguration import io.airbyte.cdk.load.command.DestinationStream -import io.airbyte.cdk.load.data.NullType +import io.airbyte.cdk.load.data.ObjectTypeWithoutSchema /** * A check operation that is run before the destination is used. @@ -25,7 +25,7 @@ interface DestinationChecker { DestinationStream( descriptor = DestinationStream.Descriptor("testing", "test"), importType = Append, - schema = NullType, + schema = ObjectTypeWithoutSchema, generationId = 1, minimumGenerationId = 0, syncId = 1, diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/command/DestinationCatalog.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/command/DestinationCatalog.kt index b771893960aa..2f84cdf19c86 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/command/DestinationCatalog.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/command/DestinationCatalog.kt @@ -5,6 +5,7 @@ package io.airbyte.cdk.load.command import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog +import io.github.oshai.kotlinlogging.KotlinLogging import io.micronaut.context.annotation.Factory import io.micronaut.context.annotation.Secondary import jakarta.inject.Singleton @@ -14,6 +15,8 @@ import jakarta.inject.Singleton * for usability. */ data class DestinationCatalog(val streams: List = emptyList()) { + private val log = KotlinLogging.logger {} + private val byDescriptor: Map = streams.associateBy { it.descriptor } @@ -23,6 +26,7 @@ data class DestinationCatalog(val streams: List = emptyList() "Catalog must have at least one stream: check that files are in the correct location." ) } + log.info { "Destination catalog initialized: $streams" } } fun getStream(name: String, namespace: String?): DestinationStream { @@ -33,6 +37,8 @@ data class DestinationCatalog(val streams: List = emptyList() fun asProtocolObject(): ConfiguredAirbyteCatalog = ConfiguredAirbyteCatalog().withStreams(streams.map { it.asProtocolObject() }) + + fun size(): Int = streams.size } interface DestinationCatalogFactory { diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/command/DestinationConfiguration.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/command/DestinationConfiguration.kt index 0e5105f227f8..a36d0044c950 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/command/DestinationConfiguration.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/command/DestinationConfiguration.kt @@ -20,6 +20,9 @@ import java.nio.file.Path * * - Add any required custom fields to the spec w/ jackson annotations * + * - Add annotation overrides (note that this will replace the original annotation, so to extend an + * existing annotation, you must copy the original annotation and add the new fields). + * * - Create a class `{MyDestination}Configuration` extending [DestinationConfiguration] * * - Add the corresponding mixin `...ConfigurationProvider`s for any added spec mixins @@ -58,13 +61,14 @@ import java.nio.file.Path * ``` */ abstract class DestinationConfiguration : Configuration { - open val recordBatchSizeBytes: Long = 200L * 1024L * 1024L + open val recordBatchSizeBytes: Long = DEFAULT_RECORD_BATCH_SIZE_BYTES + open val processEmptyFiles: Boolean = false open val tmpFileDirectory: Path = Path.of("airbyte-cdk-load") /** Memory queue settings */ open val maxMessageQueueMemoryUsageRatio: Double = 0.2 // 0 => No limit, 1.0 => 100% of JVM heap open val estimatedRecordMemoryOverheadRatio: Double = - 0.1 // 0 => No overhead, 1.0 => 100% overhead + 1.1 // 1.0 => No overhead, 2.0 => 100% overhead /** * If we have not flushed state checkpoints in this amount of time, make a best-effort attempt @@ -81,6 +85,15 @@ abstract class DestinationConfiguration : Configuration { */ open val gracefulCancellationTimeoutMs: Long = 60 * 1000L // 1 minutes + open val numProcessRecordsWorkers: Int = 2 + open val numProcessBatchWorkers: Int = 5 + open val numProcessBatchWorkersForFileTransfer: Int = 3 + open val batchQueueDepth: Int = 10 + + companion object { + const val DEFAULT_RECORD_BATCH_SIZE_BYTES = 200L * 1024L * 1024L + } + /** * Micronaut factory which glues [ConfigurationSpecificationSupplier] and * [DestinationConfigurationFactory] together to produce a [DestinationConfiguration] singleton. diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/command/DestinationStream.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/command/DestinationStream.kt index bd14ada6491e..04044cbc6e41 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/command/DestinationStream.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/command/DestinationStream.kt @@ -5,14 +5,8 @@ package io.airbyte.cdk.load.command import io.airbyte.cdk.load.data.AirbyteType -import io.airbyte.cdk.load.data.ArrayType -import io.airbyte.cdk.load.data.FieldType -import io.airbyte.cdk.load.data.IntegerType -import io.airbyte.cdk.load.data.ObjectType -import io.airbyte.cdk.load.data.StringType import io.airbyte.cdk.load.data.json.AirbyteTypeToJsonSchema import io.airbyte.cdk.load.data.json.JsonSchemaToAirbyteType -import io.airbyte.cdk.load.message.DestinationRecord import io.airbyte.protocol.models.v0.AirbyteStream import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream import io.airbyte.protocol.models.v0.DestinationSyncMode @@ -51,59 +45,6 @@ data class DestinationStream( * what actually exists, as many destinations have legacy data from before this schema was * adopted. */ - val schemaWithMeta: ObjectType - get() = - ObjectType( - linkedMapOf( - DestinationRecord.Meta.COLUMN_NAME_AB_RAW_ID to - FieldType(StringType, nullable = false), - DestinationRecord.Meta.COLUMN_NAME_AB_EXTRACTED_AT to - FieldType(IntegerType, nullable = false), - DestinationRecord.Meta.COLUMN_NAME_AB_META to - FieldType( - nullable = false, - type = - ObjectType( - linkedMapOf( - "sync_id" to FieldType(IntegerType, nullable = false), - "changes" to - FieldType( - nullable = false, - type = - ArrayType( - FieldType( - nullable = false, - type = - ObjectType( - linkedMapOf( - "field" to - FieldType( - StringType, - nullable = false - ), - "change" to - FieldType( - StringType, - nullable = false - ), - "reason" to - FieldType( - StringType, - nullable = false - ), - ) - ) - ) - ) - ) - ) - ) - ), - DestinationRecord.Meta.COLUMN_NAME_AB_GENERATION_ID to - FieldType(IntegerType, nullable = false), - DestinationRecord.Meta.COLUMN_NAME_DATA to FieldType(schema, nullable = false), - ) - ) /** * This is not fully round-trippable. Destinations don't care about most of the stuff in an diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/config/SyncBeanFactory.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/config/SyncBeanFactory.kt new file mode 100644 index 000000000000..700fcc2c3bc2 --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/config/SyncBeanFactory.kt @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.config + +import io.airbyte.cdk.load.command.DestinationCatalog +import io.airbyte.cdk.load.command.DestinationConfiguration +import io.airbyte.cdk.load.message.BatchEnvelope +import io.airbyte.cdk.load.message.MultiProducerChannel +import io.airbyte.cdk.load.state.ReservationManager +import io.airbyte.cdk.load.task.implementor.FileAggregateMessage +import io.airbyte.cdk.load.task.implementor.FileTransferQueueMessage +import io.github.oshai.kotlinlogging.KotlinLogging +import io.micronaut.context.annotation.Factory +import io.micronaut.context.annotation.Value +import jakarta.inject.Named +import jakarta.inject.Singleton +import kotlin.math.min +import kotlinx.coroutines.channels.Channel + +/** Factory for instantiating beans necessary for the sync process. */ +@Factory +class SyncBeanFactory { + private val log = KotlinLogging.logger {} + + @Singleton + @Named("memoryManager") + fun memoryManager( + config: DestinationConfiguration, + ): ReservationManager { + val memory = config.maxMessageQueueMemoryUsageRatio * Runtime.getRuntime().maxMemory() + + return ReservationManager(memory.toLong()) + } + + @Singleton + @Named("diskManager") + fun diskManager( + @Value("\${airbyte.resources.disk.bytes}") availableBytes: Long, + ): ReservationManager { + return ReservationManager(availableBytes) + } + + /** + * The queue that sits between the aggregation (SpillToDiskTask) and load steps + * (ProcessRecordsTask). + * + * Since we are buffering on disk, we must consider the available disk space in our depth + * configuration. + */ + @Singleton + @Named("fileAggregateQueue") + fun fileAggregateQueue( + @Value("\${airbyte.resources.disk.bytes}") availableBytes: Long, + config: DestinationConfiguration, + catalog: DestinationCatalog + ): MultiProducerChannel { + val streamCount = catalog.size() + // total batches by disk capacity + val maxBatchesThatFitOnDisk = (availableBytes / config.recordBatchSizeBytes).toInt() + // account for batches in flight processing by the workers + val maxBatchesMinusUploadOverhead = + maxBatchesThatFitOnDisk - config.numProcessRecordsWorkers + // ideally we'd allow enough headroom to smooth out rate differences between consumer / + // producer streams + val idealDepth = 4 * config.numProcessRecordsWorkers + // take the smaller of the two—this should be the idealDepth except in corner cases + val capacity = min(maxBatchesMinusUploadOverhead, idealDepth) + log.info { "Creating file aggregate queue with limit $capacity" } + val channel = Channel(capacity) + return MultiProducerChannel(streamCount.toLong(), channel, "fileAggregateQueue") + } + + @Singleton + @Named("batchQueue") + fun batchQueue( + config: DestinationConfiguration, + ): MultiProducerChannel> { + val channel = Channel>(config.batchQueueDepth) + return MultiProducerChannel(config.numProcessRecordsWorkers.toLong(), channel, "batchQueue") + } + + @Singleton + @Named("fileMessageQueue") + fun fileMessageQueue( + config: DestinationConfiguration, + ): MultiProducerChannel { + val channel = Channel(config.batchQueueDepth) + return MultiProducerChannel(1, channel, "fileMessageQueue") + } +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteSchemaIdentityMapper.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteSchemaIdentityMapper.kt index a36c286a03a5..6cffad8e3206 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteSchemaIdentityMapper.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteSchemaIdentityMapper.kt @@ -4,10 +4,17 @@ package io.airbyte.cdk.load.data -interface AirbyteSchemaIdentityMapper { - fun map(schema: AirbyteType): AirbyteType = +interface AirbyteSchemaMapper { + fun map(schema: AirbyteType): AirbyteType +} + +class AirbyteSchemaNoopMapper : AirbyteSchemaMapper { + override fun map(schema: AirbyteType): AirbyteType = schema +} + +interface AirbyteSchemaIdentityMapper : AirbyteSchemaMapper { + override fun map(schema: AirbyteType): AirbyteType = when (schema) { - is NullType -> mapNull(schema) is StringType -> mapString(schema) is BooleanType -> mapBoolean(schema) is IntegerType -> mapInteger(schema) @@ -26,7 +33,6 @@ interface AirbyteSchemaIdentityMapper { is UnknownType -> mapUnknown(schema) } - fun mapNull(schema: NullType): AirbyteType = schema fun mapString(schema: StringType): AirbyteType = schema fun mapBoolean(schema: BooleanType): AirbyteType = schema fun mapInteger(schema: IntegerType): AirbyteType = schema @@ -43,7 +49,7 @@ interface AirbyteSchemaIdentityMapper { fun mapObjectWithoutSchema(schema: ObjectTypeWithoutSchema): AirbyteType = schema fun mapObjectWithEmptySchema(schema: ObjectTypeWithEmptySchema): AirbyteType = schema fun mapUnion(schema: UnionType): AirbyteType { - return UnionType(schema.options.map { map(it) }) + return UnionType.of(schema.options.map { map(it) }) } fun mapDate(schema: DateType): AirbyteType = schema fun mapTimeTypeWithTimezone(schema: TimeTypeWithTimezone): AirbyteType = schema diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteType.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteType.kt index 5093f0597077..9f93ca64409b 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteType.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteType.kt @@ -4,9 +4,9 @@ package io.airbyte.cdk.load.data -sealed interface AirbyteType +import com.fasterxml.jackson.databind.JsonNode -data object NullType : AirbyteType +sealed interface AirbyteType data object StringType : AirbyteType @@ -36,8 +36,21 @@ data object ObjectTypeWithEmptySchema : AirbyteType data object ObjectTypeWithoutSchema : AirbyteType -data class UnionType(val options: List) : AirbyteType +data class UnionType(val options: Set) : AirbyteType { + companion object { + fun of(options: Set): AirbyteType { + if (options.size == 1) { + return options.first() + } + return UnionType(options) + } + + fun of(options: List): AirbyteType = of(options.toSet()) + + fun of(vararg options: AirbyteType): AirbyteType = of(options.toSet()) + } +} -data class UnknownType(val what: String) : AirbyteType +data class UnknownType(val schema: JsonNode) : AirbyteType data class FieldType(val type: AirbyteType, val nullable: Boolean) diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteTypeToAirbyteTypeWithMeta.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteTypeToAirbyteTypeWithMeta.kt new file mode 100644 index 000000000000..4302c7577b7d --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteTypeToAirbyteTypeWithMeta.kt @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data + +import io.airbyte.cdk.load.message.Meta + +class AirbyteTypeToAirbyteTypeWithMeta(private val flatten: Boolean) { + fun convert(schema: AirbyteType): ObjectType { + val properties = + linkedMapOf( + Meta.COLUMN_NAME_AB_RAW_ID to FieldType(StringType, nullable = false), + Meta.COLUMN_NAME_AB_EXTRACTED_AT to FieldType(IntegerType, nullable = false), + Meta.COLUMN_NAME_AB_META to + FieldType( + nullable = false, + type = + ObjectType( + linkedMapOf( + "sync_id" to FieldType(IntegerType, nullable = false), + "changes" to + FieldType( + nullable = false, + type = + ArrayType( + FieldType( + nullable = false, + type = + ObjectType( + linkedMapOf( + "field" to + FieldType( + StringType, + nullable = false + ), + "change" to + FieldType( + StringType, + nullable = false + ), + "reason" to + FieldType( + StringType, + nullable = false + ), + ) + ) + ) + ) + ) + ) + ) + ), + Meta.COLUMN_NAME_AB_GENERATION_ID to FieldType(IntegerType, nullable = false) + ) + if (flatten) { + if (schema is ObjectType) { + schema.properties.forEach { (name, field) -> properties[name] = field } + } else if (schema is ObjectTypeWithEmptySchema) { + // Do nothing: no fields to add + } else { + throw IllegalStateException( + "Cannot flatten without an object schema (schema type: $schema)" + ) + } + } else { + properties[Meta.COLUMN_NAME_DATA] = FieldType(schema, nullable = false) + } + return ObjectType(properties) + } +} + +fun AirbyteType.withAirbyteMeta(flatten: Boolean = false): ObjectType = + AirbyteTypeToAirbyteTypeWithMeta(flatten).convert(this) diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteValue.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteValue.kt index 0e9e2cbd123d..6bf7069822cc 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteValue.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteValue.kt @@ -4,30 +4,33 @@ package io.airbyte.cdk.load.data +import com.fasterxml.jackson.databind.JsonNode import java.math.BigDecimal +import java.math.BigInteger import java.time.LocalDate import java.time.LocalDateTime import java.time.LocalTime import java.time.OffsetDateTime import java.time.OffsetTime -import java.time.ZoneOffset sealed interface AirbyteValue { companion object { fun from(value: Any?): AirbyteValue = when (value) { + is AirbyteValue -> value null -> NullValue is String -> StringValue(value) is Boolean -> BooleanValue(value) is Int -> IntegerValue(value.toLong()) is Long -> IntegerValue(value) + is BigInteger -> IntegerValue(value) is Double -> NumberValue(BigDecimal.valueOf(value)) is BigDecimal -> NumberValue(value) - is LocalDate -> DateValue(value.toString()) - is OffsetDateTime, - is LocalDateTime -> TimestampValue(value.toString()) - is OffsetTime, - is LocalTime -> TimeValue(value.toString()) + is LocalDate -> DateValue(value) + is OffsetDateTime -> TimestampWithTimezoneValue(value) + is LocalDateTime -> TimestampWithoutTimezoneValue(value) + is OffsetTime -> TimeWithTimezoneValue(value) + is LocalTime -> TimeWithoutTimezoneValue(value) is Map<*, *> -> ObjectValue.from(@Suppress("UNCHECKED_CAST") (value as Map)) is List<*> -> ArrayValue.from(value) @@ -58,97 +61,54 @@ value class BooleanValue(val value: Boolean) : AirbyteValue, Comparable { +value class IntegerValue(val value: BigInteger) : AirbyteValue, Comparable { + constructor(value: Long) : this(BigInteger.valueOf(value)) override fun compareTo(other: IntegerValue): Int = value.compareTo(other.value) } @JvmInline -value class IntValue(val value: Int) : AirbyteValue, Comparable { - override fun compareTo(other: IntValue): Int = value.compareTo(other.value) +value class NumberValue(val value: BigDecimal) : AirbyteValue, Comparable { + override fun compareTo(other: NumberValue): Int = value.compareTo(other.value) } @JvmInline -value class NumberValue(val value: BigDecimal) : AirbyteValue, Comparable { - override fun compareTo(other: NumberValue): Int = value.compareTo(other.value) +value class DateValue(val value: LocalDate) : AirbyteValue, Comparable { + constructor(date: String) : this(LocalDate.parse(date)) + override fun compareTo(other: DateValue): Int = value.compareTo(other.value) } @JvmInline -value class DateValue(val value: String) : AirbyteValue, Comparable { - override fun compareTo(other: DateValue): Int { - val thisDate = - try { - LocalDate.parse(value) - } catch (e: Exception) { - LocalDate.MIN - } - val otherDate = - try { - LocalDate.parse(other.value) - } catch (e: Exception) { - LocalDate.MIN - } - return thisDate.compareTo(otherDate) - } +value class TimestampWithTimezoneValue(val value: OffsetDateTime) : + AirbyteValue, Comparable { + constructor(timestamp: String) : this(OffsetDateTime.parse(timestamp)) + override fun compareTo(other: TimestampWithTimezoneValue): Int = value.compareTo(other.value) } @JvmInline -value class TimestampValue(val value: String) : AirbyteValue, Comparable { - override fun compareTo(other: TimestampValue): Int { - // Do all comparisons using OffsetDateTime for convenience. - // First, try directly parsing as OffsetDateTime. - // If that fails, try parsing as LocalDateTime and assume UTC. - // We could maybe have separate value classes for these cases, - // but that comes with its own set of problems - // (mostly around sources declaring bad schemas). - val thisTimestamp = - try { - OffsetDateTime.parse(value) - } catch (e: Exception) { - LocalDateTime.parse(value).atOffset(ZoneOffset.UTC) - } catch (e: Exception) { - LocalDateTime.MIN.atOffset(ZoneOffset.UTC) - } - val otherTimestamp = - try { - OffsetDateTime.parse(other.value) - } catch (e: Exception) { - LocalDateTime.parse(other.value).atOffset(ZoneOffset.UTC) - } catch (e: Exception) { - LocalDateTime.MIN.atOffset(ZoneOffset.UTC) - } - return thisTimestamp.compareTo(otherTimestamp) - } +value class TimestampWithoutTimezoneValue(val value: LocalDateTime) : + AirbyteValue, Comparable { + constructor(timestamp: String) : this(LocalDateTime.parse(timestamp)) + override fun compareTo(other: TimestampWithoutTimezoneValue): Int = value.compareTo(other.value) } @JvmInline -value class TimeValue(val value: String) : AirbyteValue, Comparable { - override fun compareTo(other: TimeValue): Int { - // Similar to TimestampValue, try parsing with/without timezone, - // and do all comparisons using OffsetTime. - val thisTime = - try { - OffsetTime.parse(value) - } catch (e: Exception) { - LocalTime.parse(value).atOffset(ZoneOffset.UTC) - } catch (e: Exception) { - LocalTime.MIN.atOffset(ZoneOffset.UTC) - } - val otherTime = - try { - OffsetTime.parse(other.value) - } catch (e: Exception) { - LocalTime.parse(other.value).atOffset(ZoneOffset.UTC) - } catch (e: Exception) { - LocalTime.MIN.atOffset(ZoneOffset.UTC) - } - return thisTime.compareTo(otherTime) - } +value class TimeWithTimezoneValue(val value: OffsetTime) : + AirbyteValue, Comparable { + constructor(time: String) : this(OffsetTime.parse(time)) + override fun compareTo(other: TimeWithTimezoneValue): Int = value.compareTo(other.value) +} + +@JvmInline +value class TimeWithoutTimezoneValue(val value: LocalTime) : + AirbyteValue, Comparable { + constructor(time: String) : this(LocalTime.parse(time)) + override fun compareTo(other: TimeWithoutTimezoneValue): Int = value.compareTo(other.value) } @JvmInline value class ArrayValue(val values: List) : AirbyteValue { companion object { - fun from(list: List): ArrayValue = ArrayValue(list.map { it as AirbyteValue }) + fun from(list: List): ArrayValue = ArrayValue(list.map { AirbyteValue.from(it) }) } } @@ -160,4 +120,4 @@ value class ObjectValue(val values: LinkedHashMap) : Airby } } -@JvmInline value class UnknownValue(val what: String) : AirbyteValue +@JvmInline value class UnknownValue(val value: JsonNode) : AirbyteValue diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteValueDeepCoercingMapper.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteValueDeepCoercingMapper.kt new file mode 100644 index 000000000000..1d4cdd2ab9fc --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteValueDeepCoercingMapper.kt @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data + +import io.airbyte.cdk.load.util.serializeToString +import java.math.BigDecimal +import java.math.BigInteger +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.LocalTime +import java.time.OffsetDateTime +import java.time.OffsetTime +import java.time.ZoneOffset +import java.time.ZonedDateTime +import java.time.format.DateTimeFormatter + +/** + * A mapper which coerces ALL values against the schema. This mapper MUST NOT be called after any + * mapper that returns non-native-JSON types (date, timestamp, etc.), or any mapper that causes the + * values to become misaligned with the schema (e.g. [AirbyteSchemaNoopMapper] + + * [SchemalessValuesToJsonString]). + * + * If this mapper is included in a [MapperPipeline], it SHOULD be preceded by a [MergeUnions] + * mapper. Not including this mapper may result in strange behavior when coercing union types. + * + * This mapper performs common-sense type coercions. For example, it will promote IntegerValue to + * NumberValue, or parse StringValue to TimestampValue. + */ +class AirbyteValueDeepCoercingMapper : AirbyteValueIdentityMapper() { + override fun mapObject( + value: AirbyteValue, + schema: ObjectType, + context: Context + ): Pair = + // force to object, and then use the superclass recursion + requireType(value, schema, context) { super.mapObject(it, schema, context) } + + override fun mapObjectWithEmptySchema( + value: AirbyteValue, + schema: ObjectTypeWithEmptySchema, + context: Context + ): Pair = requireType(value, schema, context) + + override fun mapObjectWithoutSchema( + value: AirbyteValue, + schema: ObjectTypeWithoutSchema, + context: Context + ): Pair = requireType(value, schema, context) + + override fun mapArray( + value: AirbyteValue, + schema: ArrayType, + context: Context + ): Pair = + // force to array, and then use the superclass recursion + requireType(value, schema, context) { super.mapArray(it, schema, context) } + + override fun mapArrayWithoutSchema( + value: AirbyteValue, + schema: ArrayTypeWithoutSchema, + context: Context + ): Pair = requireType(value, schema, context) + + override fun mapBoolean(value: AirbyteValue, context: Context): Pair = + requireType(value, BooleanType, context) + + override fun mapNumber(value: AirbyteValue, context: Context): Pair = + when (value) { + is NumberValue -> value to context + is IntegerValue -> NumberValue(value.value.toBigDecimal()) to context + is StringValue -> NumberValue(BigDecimal(value.value)) to context + else -> nulledOut(NumberType, context) + } + + override fun mapInteger(value: AirbyteValue, context: Context): Pair = + when (value) { + // Maybe we should truncate non-int values? + // But to match existing behavior, let's just null for now. + is NumberValue -> IntegerValue(value.value.toBigIntegerExact()) to context + is IntegerValue -> value to context + is StringValue -> IntegerValue(BigInteger(value.value)) to context + else -> nulledOut(IntegerType, context) + } + + override fun mapString(value: AirbyteValue, context: Context): Pair { + val stringified = + when (value) { + // this should never happen, because we handle `value is NullValue` + // in the top-level if statement + NullValue -> throw IllegalStateException("Unexpected NullValue") + is StringValue -> value.value + is NumberValue -> value.value.toString() + is IntegerValue -> value.value.toString() + is BooleanValue -> value.value.toString() + is ArrayValue, + is ObjectValue -> value.serializeToString() + // JsonToAirbyteValue never outputs these values, so don't handle them. + is DateValue, + is TimeWithTimezoneValue, + is TimeWithoutTimezoneValue, + is TimestampWithTimezoneValue, + is TimestampWithoutTimezoneValue, + is UnknownValue -> + throw IllegalArgumentException( + "Invalid value type ${value.javaClass.canonicalName}" + ) + } + return StringValue(stringified) to context + } + + override fun mapDate(value: AirbyteValue, context: Context): Pair = + requireType(value, DateType, context) { + DateValue(LocalDate.parse(it.value, DATE_TIME_FORMATTER)) to context + } + + override fun mapTimeWithTimezone( + value: AirbyteValue, + context: Context + ): Pair = + requireType(value, TimeTypeWithTimezone, context) { + val ot = + try { + OffsetTime.parse(it.value, TIME_FORMATTER) + } catch (e: Exception) { + LocalTime.parse(it.value, TIME_FORMATTER).atOffset(ZoneOffset.UTC) + } + TimeWithTimezoneValue(ot) to context + } + + override fun mapTimeWithoutTimezone( + value: AirbyteValue, + context: Context + ): Pair = + requireType(value, TimeTypeWithoutTimezone, context) { + TimeWithoutTimezoneValue(LocalTime.parse(it.value, TIME_FORMATTER)) to context + } + + override fun mapTimestampWithTimezone( + value: AirbyteValue, + context: Context + ): Pair = + requireType(value, TimestampTypeWithTimezone, context) { + TimestampWithTimezoneValue(offsetDateTime(it)) to context + } + + override fun mapTimestampWithoutTimezone( + value: AirbyteValue, + context: Context + ): Pair = + requireType(value, TimestampTypeWithoutTimezone, context) { + TimestampWithoutTimezoneValue(offsetDateTime(it).toLocalDateTime()) to context + } + + private fun offsetDateTime(it: StringValue): OffsetDateTime { + val odt = + try { + ZonedDateTime.parse(it.value, DATE_TIME_FORMATTER).toOffsetDateTime() + } catch (e: Exception) { + LocalDateTime.parse(it.value, DATE_TIME_FORMATTER).atOffset(ZoneOffset.UTC) + } + return odt + } + + override fun mapUnion( + value: AirbyteValue, + schema: UnionType, + context: Context + ): Pair = + if (schema.options.isEmpty()) { + nulledOut(schema, context) + } else { + val option = + schema.options.find { matchesStrictly(value, it) } + ?: schema.options.find { matchesPermissively(value, it) } + ?: throw IllegalArgumentException( + "No matching union option in ${schema.options} for ${value::class.java.canonicalName}", + ) + mapInner(value, option, context) + } + + private fun matchesStrictly(value: AirbyteValue, schema: AirbyteType): Boolean = + when (schema) { + is ArrayType, + is ArrayTypeWithoutSchema -> value is ArrayValue + is BooleanType -> value is BooleanValue + is DateType -> value is StringValue + is IntegerType -> value is IntegerValue + is NumberType -> value is NumberValue + is ObjectType, + is ObjectTypeWithoutSchema, + is ObjectTypeWithEmptySchema -> value is ObjectValue + is StringType -> value is StringValue + is TimeTypeWithTimezone, + is TimeTypeWithoutTimezone, + is TimestampTypeWithTimezone, + is TimestampTypeWithoutTimezone -> value is StringValue + is UnionType -> schema.options.any { matchesStrictly(value, it) } + is UnknownType -> false + } + + private fun matchesPermissively(value: AirbyteValue, schema: AirbyteType): Boolean { + val (mappedValue, _) = mapInner(value, schema, Context(nullable = true)) + return mappedValue !is NullValue + } + + private inline fun requireType( + value: AirbyteValue, + schema: AirbyteType, + context: Context, + f: (T) -> Pair = { value to context }, + ): Pair { + return if (value is T) { + f(value) + } else { + nulledOut(schema, context) + } + } + + companion object { + val DATE_TIME_FORMATTER: DateTimeFormatter = + DateTimeFormatter.ofPattern( + "[yyyy][yy]['-']['/']['.'][' '][MMM][MM][M]['-']['/']['.'][' '][dd][d][[' '][G]][[' ']['T']HH:mm[':'ss[.][SSSSSS][SSSSS][SSSS][SSS][' '][z][zzz][Z][O][x][XXX][XX][X][[' '][G]]]]" + ) + val TIME_FORMATTER: DateTimeFormatter = + DateTimeFormatter.ofPattern( + "HH:mm[':'ss[.][SSSSSS][SSSSS][SSSS][SSS][' '][z][zzz][Z][O][x][XXX][XX][X]]" + ) + } +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteValueIdentityMapper.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteValueIdentityMapper.kt index eaab8330f276..d541f047a285 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteValueIdentityMapper.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/AirbyteValueIdentityMapper.kt @@ -4,114 +4,231 @@ package io.airbyte.cdk.load.data -import io.airbyte.cdk.load.message.DestinationRecord +import io.airbyte.cdk.load.message.Meta import io.airbyte.protocol.models.v0.AirbyteRecordMessageMetaChange.Change import io.airbyte.protocol.models.v0.AirbyteRecordMessageMetaChange.Reason -open class AirbyteValueIdentityMapper( - val meta: DestinationRecord.Meta, -) { - private fun collectFailure( - path: List, +interface AirbyteValueMapper { + fun map( + value: AirbyteValue, + schema: AirbyteType, + changes: List = emptyList() + ): Pair> +} + +/** An optimized identity mapper that just passes through. */ +class AirbyteValueNoopMapper : AirbyteValueMapper { + override fun map( + value: AirbyteValue, + schema: AirbyteType, + changes: List + ): Pair> = value to changes +} + +open class AirbyteValueIdentityMapper : AirbyteValueMapper { + data class Context( + val nullable: Boolean = false, + val path: List = emptyList(), + val changes: MutableSet = mutableSetOf(), + ) + + override fun map( + value: AirbyteValue, + schema: AirbyteType, + changes: List + ): Pair> = + mapInner(value, schema, Context(changes = changes.toMutableSet())).let { + it.first to it.second.changes.toList() + } + + fun nulledOut( + schema: AirbyteType, + context: Context, reason: Reason = Reason.DESTINATION_SERIALIZATION_ERROR - ) { - meta.changes.add(DestinationRecord.Change(path.joinToString("."), Change.NULLED, reason)) + ): Pair { + context.changes.add(Meta.Change(context.path.joinToString("."), Change.NULLED, reason)) + return mapInner(NullValue, schema, context) } - fun map( + fun mapInner( value: AirbyteValue, schema: AirbyteType, - path: List = emptyList() - ): AirbyteValue = - try { - when (schema) { - is ObjectType -> mapObject(value as ObjectValue, schema, path) - is ObjectTypeWithoutSchema -> - mapObjectWithoutSchema(value as ObjectValue, schema, path) - is ObjectTypeWithEmptySchema -> - mapObjectWithEmptySchema(value as ObjectValue, schema, path) - is ArrayType -> mapArray(value as ArrayValue, schema, path) - is ArrayTypeWithoutSchema -> - mapArrayWithoutSchema(value as ArrayValue, schema, path) - is UnionType -> mapUnion(value, schema, path) - is BooleanType -> mapBoolean(value as BooleanValue, path) - is NumberType -> mapNumber(value as NumberValue, path) - is StringType -> mapString(value as StringValue, path) - is IntegerType -> mapInteger(value as IntegerValue, path) - is DateType -> mapDate(value as DateValue, path) - is TimeTypeWithTimezone -> mapTimeWithTimezone(value as TimeValue, path) - is TimeTypeWithoutTimezone -> mapTimeWithoutTimezone(value as TimeValue, path) - is TimestampTypeWithTimezone -> - mapTimestampWithTimezone(value as TimestampValue, path) - is TimestampTypeWithoutTimezone -> - mapTimestampWithoutTimezone(value as TimestampValue, path) - is NullType -> mapNull(path) - is UnknownType -> { - collectFailure(path) - mapNull(path) + context: Context, + ): Pair = + if (value is NullValue) { + if (!context.nullable) { + throw IllegalStateException( + "null value for non-nullable field at path: ${context.path.joinToString(".")}" + ) + } + mapNull(context) + } else + try { + when (schema) { + is ObjectType -> mapObject(value, schema, context) + is ObjectTypeWithoutSchema -> mapObjectWithoutSchema(value, schema, context) + is ObjectTypeWithEmptySchema -> mapObjectWithEmptySchema(value, schema, context) + is ArrayType -> mapArray(value, schema, context) + is ArrayTypeWithoutSchema -> mapArrayWithoutSchema(value, schema, context) + is UnionType -> mapUnion(value, schema, context) + is BooleanType -> mapBoolean(value, context) + is NumberType -> mapNumber(value, context) + is StringType -> mapString(value, context) + is IntegerType -> mapInteger(value, context) + is DateType -> mapDate(value, context) + is TimeTypeWithTimezone -> mapTimeWithTimezone(value, context) + is TimeTypeWithoutTimezone -> mapTimeWithoutTimezone(value, context) + is TimestampTypeWithTimezone -> mapTimestampWithTimezone(value, context) + is TimestampTypeWithoutTimezone -> mapTimestampWithoutTimezone(value, context) + is UnknownType -> mapUnknown(value, context) } + } catch (e: Exception) { + nulledOut(schema, context) } - } catch (e: Exception) { - collectFailure(path) - mapNull(path) - } - open fun mapObject(value: ObjectValue, schema: ObjectType, path: List): AirbyteValue { + open fun mapObject( + value: AirbyteValue, + schema: ObjectType, + context: Context + ): Pair { + if (value !is ObjectValue) { + return value to context + } val values = LinkedHashMap() schema.properties.forEach { (name, field) -> - values[name] = map(value.values[name] ?: NullValue, field.type, path + name) + values[name] = + mapInner( + value.values[name] ?: NullValue, + field.type, + context.copy(path = context.path + name, nullable = field.nullable) + ) + .first } - return ObjectValue(values) + return ObjectValue(values) to context } open fun mapObjectWithoutSchema( - value: ObjectValue, + value: AirbyteValue, schema: ObjectTypeWithoutSchema, - path: List - ): AirbyteValue = value + context: Context + ): Pair = value to context open fun mapObjectWithEmptySchema( - value: ObjectValue, + value: AirbyteValue, schema: ObjectTypeWithEmptySchema, - path: List - ): AirbyteValue = value + context: Context + ): Pair = value to context - open fun mapArray(value: ArrayValue, schema: ArrayType, path: List): AirbyteValue { - return ArrayValue( + open fun mapArray( + value: AirbyteValue, + schema: ArrayType, + context: Context + ): Pair { + if (value !is ArrayValue) { + return value to context + } + val mapped = value.values.mapIndexed { index, element -> - map(element, schema.items.type, path + "[$index]") + mapInner( + element, + schema.items.type, + context.copy( + path = context.path + "[$index]", + nullable = schema.items.nullable + ) + ) + .first } - ) + return ArrayValue(mapped) to context } open fun mapArrayWithoutSchema( - value: ArrayValue, + value: AirbyteValue, schema: ArrayTypeWithoutSchema, - path: List - ): AirbyteValue = value + context: Context + ): Pair = value to context + + open fun mapUnion( + value: AirbyteValue, + schema: UnionType, + context: Context + ): Pair { + /* + This mapper should not perform validation, so make a best-faith effort to recurse, + but if nothing matches the union, pass the value through unchanged. If clients validated + upstream, then this must match. If they did not, they won't have anything any more + wrong than they started with. + */ + schema.options.forEach { + if (optionMatches(it, value)) { + return mapInner(value, it, context) + } + } + return value to context + } - open fun mapUnion(value: AirbyteValue, schema: UnionType, path: List): AirbyteValue = - value + private fun optionMatches(schema: AirbyteType, value: AirbyteValue): Boolean { + return when (schema) { + is StringType -> value is StringValue + is BooleanType -> value is BooleanValue + is IntegerType -> value is IntegerValue + is NumberType -> value is NumberValue + is ArrayTypeWithoutSchema, + is ArrayType -> value is ArrayValue + is ObjectType, + is ObjectTypeWithoutSchema, + is ObjectTypeWithEmptySchema -> value is ObjectValue + is DateType -> value is DateValue + is TimeTypeWithTimezone -> value is TimeWithTimezoneValue + is TimeTypeWithoutTimezone -> value is TimeWithoutTimezoneValue + is TimestampTypeWithTimezone -> value is TimestampWithTimezoneValue + is TimestampTypeWithoutTimezone -> value is TimestampWithoutTimezoneValue + is UnionType -> schema.options.any { optionMatches(it, value) } + is UnknownType -> false + } + } - open fun mapBoolean(value: BooleanValue, path: List): AirbyteValue = value + open fun mapBoolean(value: AirbyteValue, context: Context): Pair = + value to context - open fun mapNumber(value: NumberValue, path: List): AirbyteValue = value + open fun mapNumber(value: AirbyteValue, context: Context): Pair = + value to context - open fun mapString(value: StringValue, path: List): AirbyteValue = value + open fun mapString(value: AirbyteValue, context: Context): Pair = + value to context - open fun mapInteger(value: IntegerValue, path: List): AirbyteValue = value + open fun mapInteger(value: AirbyteValue, context: Context): Pair = + value to context - open fun mapDate(value: DateValue, path: List): AirbyteValue = value + /** + * Time types are only allowed to be strings on the wire, but can be Int/egerValue if passed + * through [TimeStringToInteger]. + */ + open fun mapDate(value: AirbyteValue, context: Context): Pair = + value to context - open fun mapTimeWithTimezone(value: TimeValue, path: List): AirbyteValue = value + open fun mapTimeWithTimezone( + value: AirbyteValue, + context: Context + ): Pair = value to context - open fun mapTimeWithoutTimezone(value: TimeValue, path: List): AirbyteValue = value + open fun mapTimeWithoutTimezone( + value: AirbyteValue, + context: Context + ): Pair = value to context + + open fun mapTimestampWithTimezone( + value: AirbyteValue, + context: Context + ): Pair = value to context - open fun mapTimestampWithTimezone(value: TimestampValue, path: List): AirbyteValue = - value + open fun mapTimestampWithoutTimezone( + value: AirbyteValue, + context: Context + ): Pair = value to context - open fun mapTimestampWithoutTimezone(value: TimestampValue, path: List): AirbyteValue = - value + open fun mapNull(context: Context): Pair = NullValue to context - open fun mapNull(path: List): AirbyteValue = NullValue + open fun mapUnknown(value: AirbyteValue, context: Context): Pair = + value to context } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/DestinationRecordToAirbyteValueWithMeta.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/DestinationRecordToAirbyteValueWithMeta.kt index 84392b1503c3..10cd2ec6e9e8 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/DestinationRecordToAirbyteValueWithMeta.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/DestinationRecordToAirbyteValueWithMeta.kt @@ -4,29 +4,27 @@ package io.airbyte.cdk.load.data -import io.airbyte.cdk.load.command.DestinationCatalog -import io.airbyte.cdk.load.message.DestinationRecord -import io.airbyte.cdk.load.message.DestinationRecord.Meta -import io.micronaut.context.annotation.Secondary -import jakarta.inject.Singleton +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.message.DestinationRecordAirbyteValue +import io.airbyte.cdk.load.message.Meta import java.util.* -@Singleton -@Secondary -class DestinationRecordToAirbyteValueWithMeta(private val catalog: DestinationCatalog) { - fun decorate(record: DestinationRecord): ObjectValue { - val streamActual = catalog.getStream(record.stream.name, record.stream.namespace) - return ObjectValue( +class DestinationRecordToAirbyteValueWithMeta( + val stream: DestinationStream, + private val flatten: Boolean +) { + fun convert(data: AirbyteValue, emittedAtMs: Long, meta: Meta?): ObjectValue { + val properties = linkedMapOf( Meta.COLUMN_NAME_AB_RAW_ID to StringValue(UUID.randomUUID().toString()), - Meta.COLUMN_NAME_AB_EXTRACTED_AT to IntegerValue(record.emittedAtMs), + Meta.COLUMN_NAME_AB_EXTRACTED_AT to IntegerValue(emittedAtMs), Meta.COLUMN_NAME_AB_META to ObjectValue( linkedMapOf( - "sync_id" to IntegerValue(streamActual.syncId), + "sync_id" to IntegerValue(stream.syncId), "changes" to ArrayValue( - record.meta?.changes?.map { + meta?.changes?.map { ObjectValue( linkedMapOf( "field" to StringValue(it.field), @@ -39,9 +37,29 @@ class DestinationRecordToAirbyteValueWithMeta(private val catalog: DestinationCa ) ) ), - Meta.COLUMN_NAME_AB_GENERATION_ID to IntegerValue(streamActual.generationId), - Meta.COLUMN_NAME_DATA to record.data + Meta.COLUMN_NAME_AB_GENERATION_ID to IntegerValue(stream.generationId), ) - ) + if (flatten) { + // Special case: if the top-level schema had no columns, do nothing. + if (stream.schema !is ObjectTypeWithEmptySchema) { + properties.putAll((data as ObjectValue).values) + } + } else { + properties[Meta.COLUMN_NAME_DATA] = data + } + return ObjectValue(properties) } } + +fun Pair>.withAirbyteMeta( + stream: DestinationStream, + emittedAtMs: Long, + flatten: Boolean = false +) = + DestinationRecordToAirbyteValueWithMeta(stream, flatten) + .convert(first, emittedAtMs, Meta(second)) + +fun DestinationRecordAirbyteValue.dataWithAirbyteMeta( + stream: DestinationStream, + flatten: Boolean = false +) = DestinationRecordToAirbyteValueWithMeta(stream, flatten).convert(data, emittedAtMs, meta) diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/MapperPipeline.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/MapperPipeline.kt new file mode 100644 index 000000000000..bda1630319cc --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/MapperPipeline.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data + +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.message.Meta.Change + +class MapperPipeline( + inputSchema: AirbyteType, + schemaValueMapperPairs: List>, +) { + private val schemasWithMappers: List> + + val finalSchema: AirbyteType + + init { + val (schemaMappers, valueMappers) = schemaValueMapperPairs.unzip() + val schemas = + schemaMappers.runningFold(inputSchema) { schema, mapper -> mapper.map(schema) } + schemasWithMappers = schemas.zip(valueMappers) + finalSchema = schemas.last() + } + + fun map(data: AirbyteValue, changes: List? = null): Pair> = + schemasWithMappers.fold(data to (changes ?: emptyList())) { + (value, changes), + (schema, mapper) -> + mapper.map(value, schema, changes) + } +} + +interface MapperPipelineFactory { + fun create(stream: DestinationStream): MapperPipeline +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/MergeUnions.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/MergeUnions.kt index 73ded980ce6f..9d23d865ab1c 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/MergeUnions.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/MergeUnions.kt @@ -9,19 +9,16 @@ class MergeUnions : AirbyteSchemaIdentityMapper { // Map the options first so they're in their final form val mappedOptions = schema.options.map { map(it) } val mergedOptions = mergeOptions(mappedOptions) - if (mergedOptions.size == 1) { - return mergedOptions.first() - } - return UnionType(mergedOptions.toList()) + return UnionType.of(mergedOptions) } - private fun mergeOptions(options: List): Set { + private fun mergeOptions(options: Iterable): Set { val mergedOptions = mutableSetOf() mergeOptions(mergedOptions, options) return mergedOptions } - private fun mergeOptions(into: MutableSet, from: List) { + private fun mergeOptions(into: MutableSet, from: Iterable) { for (option in from) { if (option is UnionType) { // If this is a union of a union, recursively merge the other union's options in @@ -44,11 +41,10 @@ class MergeUnions : AirbyteSchemaIdentityMapper { continue } - if (existingField != field) { - throw IllegalArgumentException( - "Cannot merge unions of objects with different types for the same field" - ) - } + // Combine the fields, recursively merging unions, object fields, etc + val mergedFields = map(UnionType.of(existingField.type, field.type)) + newProperties[name] = + FieldType(mergedFields, existingField.nullable || field.nullable) // If the fields are identical, we can just keep the existing field } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/NullOutOfRangeIntegers.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/NullOutOfRangeIntegers.kt new file mode 100644 index 000000000000..2186019ce46f --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/NullOutOfRangeIntegers.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data + +import io.airbyte.protocol.models.v0.AirbyteRecordMessageMetaChange +import java.math.BigInteger + +/** + * Mapper for nulling out integers that are out of range. The default behavior is to null out + * integers that are outside the range of a 64-bit signed integer. + */ +class NullOutOfRangeIntegers( + private val minValue: BigInteger = Long.MIN_VALUE.toBigInteger(), + private val maxValue: BigInteger = Long.MAX_VALUE.toBigInteger() +) : AirbyteValueIdentityMapper() { + override fun mapInteger(value: AirbyteValue, context: Context): Pair { + value as IntegerValue + if (value.value < minValue || value.value > maxValue) { + return nulledOut( + IntegerType, + context, + AirbyteRecordMessageMetaChange.Reason.DESTINATION_FIELD_SIZE_LIMITATION + ) + } + return super.mapInteger(value, context) + } +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/NullableToUnionNull.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/NullableToUnionNull.kt deleted file mode 100644 index 8b1ea3daa35a..000000000000 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/NullableToUnionNull.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.cdk.load.data - -class NullableToUnionNull : AirbyteSchemaIdentityMapper { - override fun mapField(field: FieldType): FieldType { - if (field.nullable) { - return FieldType(UnionType(listOf(field.type, NullType)), nullable = false) - } - return field - } -} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/SchemalessTypesToJson.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/SchemalessTypesToJson.kt deleted file mode 100644 index 5ac72691d6d3..000000000000 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/SchemalessTypesToJson.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.cdk.load.data - -import io.airbyte.cdk.load.data.json.toJson -import io.airbyte.cdk.load.message.DestinationRecord -import io.airbyte.cdk.load.util.serializeToString - -class SchemalessTypesToJson : AirbyteSchemaIdentityMapper { - override fun mapObjectWithoutSchema(schema: ObjectTypeWithoutSchema): AirbyteType = StringType - override fun mapObjectWithEmptySchema(schema: ObjectTypeWithEmptySchema): AirbyteType = - StringType - override fun mapArrayWithoutSchema(schema: ArrayTypeWithoutSchema): AirbyteType = StringType -} - -class SchemalessValuesToJson(meta: DestinationRecord.Meta) : AirbyteValueIdentityMapper(meta) { - override fun mapObjectWithoutSchema( - value: ObjectValue, - schema: ObjectTypeWithoutSchema, - path: List - ): AirbyteValue = value.toJson().serializeToString().let(::StringValue) - override fun mapObjectWithEmptySchema( - value: ObjectValue, - schema: ObjectTypeWithEmptySchema, - path: List - ): AirbyteValue = value.toJson().serializeToString().let(::StringValue) - override fun mapArrayWithoutSchema( - value: ArrayValue, - schema: ArrayTypeWithoutSchema, - path: List - ): AirbyteValue = value.toJson().serializeToString().let(::StringValue) -} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/SchemalessTypesToJsonString.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/SchemalessTypesToJsonString.kt index 7946bdc22b9b..eb61fb562c5b 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/SchemalessTypesToJsonString.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/SchemalessTypesToJsonString.kt @@ -5,31 +5,57 @@ package io.airbyte.cdk.load.data import io.airbyte.cdk.load.data.json.toJson -import io.airbyte.cdk.load.message.DestinationRecord import io.airbyte.cdk.load.util.serializeToString -class SchemalessTypesToJsonString : AirbyteSchemaIdentityMapper { - override fun mapObjectWithoutSchema(schema: ObjectTypeWithoutSchema): AirbyteType = StringType - override fun mapObjectWithEmptySchema(schema: ObjectTypeWithEmptySchema): AirbyteType = - StringType - override fun mapArrayWithoutSchema(schema: ArrayTypeWithoutSchema): AirbyteType = StringType +/** + * Intended for Avro and Parquet Conversions and similar use cases. + * + * The contract is to serialize the values of schemaless and unknown types to a json string. + * + * Because there is no JsonBlob `AirbyteType`, we leave the types as-is and just serialize them. It + * is expected that the serializer will know to expect strings for each type. + * + * This means there's no need for a type mapper, unless you also want to support some subset of the + * Unknown types. + * + * For example, [FailOnAllUnknownTypesExceptNull] is used to add support for `{ "type": "null" }` + */ +class FailOnAllUnknownTypesExceptNull : AirbyteSchemaIdentityMapper { + override fun mapUnknown(schema: UnknownType) = + if ( + schema.schema.isObject && + ((schema.schema.get("type").isTextual && + schema.schema.get("type").textValue() == "null") || + (schema.schema.get("type").isArray && + schema.schema.get("type").elements().asSequence().all { + it.isTextual && it.textValue() == "null" + })) + ) { + schema + } else { + throw IllegalStateException("Unknown type: $schema") + } } -class SchemalessValuesToJsonString(meta: DestinationRecord.Meta) : - AirbyteValueIdentityMapper(meta) { +class SchemalessValuesToJsonString : AirbyteValueIdentityMapper() { override fun mapObjectWithoutSchema( - value: ObjectValue, + value: AirbyteValue, schema: ObjectTypeWithoutSchema, - path: List - ): AirbyteValue = value.toJson().serializeToString().let(::StringValue) + context: Context + ): Pair = + value.toJson().serializeToString().let(::StringValue) to context override fun mapObjectWithEmptySchema( - value: ObjectValue, + value: AirbyteValue, schema: ObjectTypeWithEmptySchema, - path: List - ): AirbyteValue = value.toJson().serializeToString().let(::StringValue) + context: Context + ): Pair = + value.toJson().serializeToString().let(::StringValue) to context override fun mapArrayWithoutSchema( - value: ArrayValue, + value: AirbyteValue, schema: ArrayTypeWithoutSchema, - path: List - ): AirbyteValue = value.toJson().serializeToString().let(::StringValue) + context: Context + ): Pair = + value.toJson().serializeToString().let(::StringValue) to context + override fun mapUnknown(value: AirbyteValue, context: Context): Pair = + value.toJson().serializeToString().let(::StringValue) to context } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/TimeStringToInteger.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/TimeStringToInteger.kt index 0bfe95911288..d2be041c8778 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/TimeStringToInteger.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/TimeStringToInteger.kt @@ -4,97 +4,67 @@ package io.airbyte.cdk.load.data -import io.airbyte.cdk.load.message.DestinationRecord -import java.time.LocalDate import java.time.LocalDateTime import java.time.LocalTime +import java.time.OffsetDateTime import java.time.OffsetTime import java.time.ZoneOffset -import java.time.ZonedDateTime -import java.time.format.DateTimeFormatter import java.time.temporal.ChronoUnit -class TimeStringTypeToIntegerType : AirbyteSchemaIdentityMapper { - override fun mapDate(schema: DateType): AirbyteType = IntegerType - override fun mapTimeTypeWithTimezone(schema: TimeTypeWithTimezone): AirbyteType = IntegerType - override fun mapTimeTypeWithoutTimezone(schema: TimeTypeWithoutTimezone): AirbyteType = - IntegerType - override fun mapTimestampTypeWithTimezone(schema: TimestampTypeWithTimezone): AirbyteType = - IntegerType - override fun mapTimestampTypeWithoutTimezone( - schema: TimestampTypeWithoutTimezone - ): AirbyteType = IntegerType -} - /** * NOTE: To keep parity with the old avro/parquet code, we will always first try to parse the value * as with timezone, then fall back to without. But in theory we should be more strict. */ -class TimeStringToInteger(meta: DestinationRecord.Meta) : AirbyteValueIdentityMapper(meta) { - companion object { - private val DATE_TIME_FORMATTER: DateTimeFormatter = - DateTimeFormatter.ofPattern( - "[yyyy][yy]['-']['/']['.'][' '][MMM][MM][M]['-']['/']['.'][' '][dd][d][[' '][G]][[' ']['T']HH:mm[':'ss[.][SSSSSS][SSSSS][SSSS][SSS][' '][z][zzz][Z][O][x][XXX][XX][X][[' '][G]]]]" - ) - private val TIME_FORMATTER: DateTimeFormatter = - DateTimeFormatter.ofPattern( - "HH:mm[':'ss[.][SSSSSS][SSSSS][SSSS][SSS][' '][z][zzz][Z][O][x][XXX][XX][X]]" - ) - } +class TimeStringToInteger : AirbyteValueIdentityMapper() { - override fun mapDate(value: DateValue, path: List): AirbyteValue { - val epochDay = LocalDate.parse(value.value, DATE_TIME_FORMATTER).toEpochDay() - return IntValue(epochDay.toInt()) + override fun mapDate(value: AirbyteValue, context: Context): Pair { + value as DateValue + val epochDay = value.value.toEpochDay() + return IntegerValue(epochDay) to context } - private fun toMicrosOfDayWithTimezone(timeString: String): Long { - val time = OffsetTime.parse(timeString, TIME_FORMATTER) + private fun toMicrosOfDayWithTimezone(time: OffsetTime): Long { return time.withOffsetSameInstant(ZoneOffset.UTC).toLocalTime().toNanoOfDay() / 1_000 } - private fun toMicrosOfDayWithoutTimezone(timeString: String): Long { - val time = LocalTime.parse(timeString, TIME_FORMATTER) + private fun toMicrosOfDayWithoutTimezone(time: LocalTime): Long { return time.toNanoOfDay() / 1_000 } - private fun toMicrosOfDay(timeString: String): Long { - return try { - toMicrosOfDayWithTimezone(timeString) - } catch (e: Exception) { - toMicrosOfDayWithoutTimezone(timeString) - } - } + override fun mapTimeWithTimezone( + value: AirbyteValue, + context: Context + ): Pair = + IntegerValue(toMicrosOfDayWithTimezone((value as TimeWithTimezoneValue).value)) to context - override fun mapTimeWithTimezone(value: TimeValue, path: List): AirbyteValue = - IntegerValue(toMicrosOfDay(value.value)) + override fun mapTimeWithoutTimezone( + value: AirbyteValue, + context: Context + ): Pair = + IntegerValue(toMicrosOfDayWithoutTimezone((value as TimeWithoutTimezoneValue).value)) to + context - override fun mapTimeWithoutTimezone(value: TimeValue, path: List): AirbyteValue = - IntegerValue(toMicrosOfDay(value.value)) - - private fun toEpochMicrosWithTimezone(timestampString: String): Long { - val zdt = ZonedDateTime.parse(timestampString, DATE_TIME_FORMATTER) - return zdt.toInstant().truncatedTo(ChronoUnit.MICROS).toEpochMilli() * 1_000 + - zdt.toInstant().nano / 1_000 % 1_000 + private fun toEpochMicrosWithTimezone(odt: OffsetDateTime): Long { + return odt.toInstant().truncatedTo(ChronoUnit.MICROS).toEpochMilli() * 1_000 + + odt.toInstant().nano / 1_000 % 1_000 } - private fun toEpochMicrosWithoutTimezone(timestampString: String): Long { - val dt = LocalDateTime.parse(timestampString, DATE_TIME_FORMATTER) + private fun toEpochMicrosWithoutTimezone(dt: LocalDateTime): Long { val instant = dt.toInstant(ZoneOffset.UTC) return instant.epochSecond * 1_000_000 + instant.nano / 1_000 } - private fun toEpochMicros(timestampString: String): Long { - return try { - toEpochMicrosWithTimezone(timestampString) - } catch (e: Exception) { - toEpochMicrosWithoutTimezone(timestampString) - } - } - - override fun mapTimestampWithTimezone(value: TimestampValue, path: List): AirbyteValue = - IntegerValue(toEpochMicros(value.value)) + override fun mapTimestampWithTimezone( + value: AirbyteValue, + context: Context + ): Pair = + IntegerValue(toEpochMicrosWithTimezone((value as TimestampWithTimezoneValue).value)) to + context override fun mapTimestampWithoutTimezone( - value: TimestampValue, - path: List - ): AirbyteValue = IntegerValue(toEpochMicros(value.value)) + value: AirbyteValue, + context: Context + ): Pair = + IntegerValue( + toEpochMicrosWithoutTimezone((value as TimestampWithoutTimezoneValue).value) + ) to context } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/Transformations.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/Transformations.kt new file mode 100644 index 000000000000..c5a82d6dc808 --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/Transformations.kt @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data + +import java.text.Normalizer +import java.util.regex.Pattern + +class Transformations { + companion object { + private const val S3_SAFE_CHARACTERS = "\\p{Alnum}/!_.*')(" + private const val S3_SPECIAL_CHARACTERS = "&$@=;:+,?-" + private val S3_CHARACTER_PATTERN = + "[^${S3_SAFE_CHARACTERS}${Pattern.quote(S3_SPECIAL_CHARACTERS)}]" + const val NON_ALPHANUMERIC_AND_UNDERSCORE_PATTERN: String = "[^\\p{Alnum}_]" + + fun toS3SafeCharacters(input: String): String { + return Normalizer.normalize(input, Normalizer.Form.NFKD) + .replace( + "\\p{M}".toRegex(), + "", + ) // P{M} matches a code point that is not a combining mark (unicode) + .replace(S3_CHARACTER_PATTERN.toRegex(), "_") + } + + fun toAlphanumericAndUnderscore(s: String): String { + return Normalizer.normalize(s, Normalizer.Form.NFKD) + .replace( + "\\p{M}".toRegex(), + "" + ) // P{M} matches a code point that is not a combining mark (unicode) + .replace("\\s+".toRegex(), "_") + .replace(NON_ALPHANUMERIC_AND_UNDERSCORE_PATTERN.toRegex(), "_") + } + + fun toAvroSafeNamespace(namespace: String): String { + val tokens = + namespace.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + return tokens + .map { name: String -> toAlphanumericAndUnderscore(name) } + .joinToString(separator = ".") + } + + fun toAvroSafeName(name: String): String { + val stripped = toAlphanumericAndUnderscore(name) + return if (stripped.substring(0, 1).matches("[A-Za-z_]".toRegex())) { + stripped + } else { + "_$stripped" + } + } + } +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/UnionTypeToDisjointRecord.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/UnionTypeToDisjointRecord.kt index 7217f8f32097..cbbbba37caa2 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/UnionTypeToDisjointRecord.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/UnionTypeToDisjointRecord.kt @@ -4,34 +4,28 @@ package io.airbyte.cdk.load.data -import io.airbyte.cdk.load.message.DestinationRecord - class UnionTypeToDisjointRecord : AirbyteSchemaIdentityMapper { override fun mapUnion(schema: UnionType): AirbyteType { - val (nullOptions, nonNullOptions) = schema.options.partition { it is NullType } - if (nonNullOptions.size < 2) { + if (schema.options.size < 2) { return schema } /* Create a schema of { "type": "string", "": , etc... } */ val properties = linkedMapOf("type" to FieldType(StringType, nullable = false)) - nonNullOptions.forEach { - val name = typeName(it) + schema.options.forEach { unmappedType -> + /* Necessary because the type might contain a nested union that needs mapping to a disjoint record. */ + val mappedType = map(unmappedType) + val name = typeName(mappedType) if (name in properties) { throw IllegalArgumentException("Union of types with same name: $name") } - properties[typeName(it)] = FieldType(it, nullable = true) - } - val obj = ObjectType(properties) - if (nullOptions.isEmpty()) { - return obj + properties[typeName(mappedType)] = FieldType(mappedType, nullable = true) } - return UnionType(nullOptions + obj) + return ObjectType(properties) } companion object { fun typeName(type: AirbyteType): String = when (type) { - is NullType -> "null" is StringType -> "string" is BooleanType -> "boolean" is IntegerType -> "integer" @@ -41,9 +35,9 @@ class UnionTypeToDisjointRecord : AirbyteSchemaIdentityMapper { is TimestampTypeWithoutTimezone -> "timestamp_without_timezone" is TimeTypeWithTimezone -> "time_with_timezone" is TimeTypeWithoutTimezone -> "time_without_timezone" - is ArrayType, - is ArrayTypeWithoutSchema -> "array" - is ObjectType, + is ArrayType -> "array" + is ObjectType -> "object" + is ArrayTypeWithoutSchema, is ObjectTypeWithoutSchema, is ObjectTypeWithEmptySchema -> "object" is UnionType -> "union" @@ -52,46 +46,41 @@ class UnionTypeToDisjointRecord : AirbyteSchemaIdentityMapper { } } -class UnionValueToDisjointRecord(meta: DestinationRecord.Meta) : AirbyteValueIdentityMapper(meta) { +class UnionValueToDisjointRecord : AirbyteValueIdentityMapper() { override fun mapUnion( value: AirbyteValue, schema: UnionType, - path: List - ): AirbyteValue { - val nNonNullOptions = schema.options.filter { it !is NullType }.size - if (nNonNullOptions < 2) { - return value - } - + context: Context + ): Pair { val type = schema.options.find { matches(it, value) } ?: throw IllegalArgumentException("No matching union option in $schema for $value") + val (valueMapped, contextMapped) = mapInner(value, type, context) return ObjectValue( values = linkedMapOf( "type" to StringValue(UnionTypeToDisjointRecord.typeName(type)), - UnionTypeToDisjointRecord.typeName(type) to map(value, type, path) + UnionTypeToDisjointRecord.typeName(type) to valueMapped ) - ) + ) to contextMapped } private fun matches(schema: AirbyteType, value: AirbyteValue): Boolean { return when (schema) { - is ArrayType, - is ArrayTypeWithoutSchema -> value is ArrayValue + is StringType -> value is StringValue is BooleanType -> value is BooleanValue - is DateType -> value is DateValue is IntegerType -> value is IntegerValue - is NullType -> value is NullValue is NumberType -> value is NumberValue - is ObjectType, + is ArrayType -> value is ArrayValue + is ObjectType -> value is ObjectValue + is ArrayTypeWithoutSchema, is ObjectTypeWithoutSchema, - is ObjectTypeWithEmptySchema -> value is ObjectValue - is StringType -> value is StringValue + is ObjectTypeWithEmptySchema -> value is StringValue + is DateType, is TimeTypeWithTimezone, is TimeTypeWithoutTimezone, is TimestampTypeWithTimezone, - is TimestampTypeWithoutTimezone -> value is TimeValue + is TimestampTypeWithoutTimezone -> value is IntegerValue is UnionType -> schema.options.any { matches(it, value) } is UnknownType -> false } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/json/AirbyteTypeToJsonSchema.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/json/AirbyteTypeToJsonSchema.kt index 101f9344ba41..a55eb19183b6 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/json/AirbyteTypeToJsonSchema.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/json/AirbyteTypeToJsonSchema.kt @@ -16,7 +16,6 @@ class AirbyteTypeToJsonSchema { fun convert(airbyteType: AirbyteType): JsonNode { return when (airbyteType) { - is NullType -> ofType("null") is StringType -> ofType("string") is BooleanType -> ofType("boolean") is IntegerType -> ofType("integer") @@ -25,13 +24,13 @@ class AirbyteTypeToJsonSchema { JsonNodeFactory.instance .objectNode() .put("type", "array") - .set("items", fromFieldType(airbyteType.items)) + .set("items", convert(airbyteType.items.type)) is ArrayTypeWithoutSchema -> ofType("array") is ObjectType -> { val objNode = ofType("object") val properties = objNode.putObject("properties") airbyteType.properties.forEach { (name, field) -> - properties.replace(name, fromFieldType(field)) + properties.replace(name, convert(field.type)) } objNode } @@ -64,17 +63,8 @@ class AirbyteTypeToJsonSchema { val timestampNode = ofType("string").put("format", "date-time") timestampNode.put("airbyte_type", "timestamp_without_timezone") } - is UnknownType -> throw IllegalArgumentException("Unknown type: $airbyteType") + // In case of unknown type, just return {} (i.e. the accept-all JsonSchema) + is UnknownType -> JsonNodeFactory.instance.objectNode() } } - - private fun fromFieldType(field: FieldType): JsonNode { - if (field.nullable) { - if (field.type is UnionType) { - return convert(UnionType(options = field.type.options + NullType)) - } - return convert(UnionType(options = listOf(field.type, NullType))) - } - return convert(field.type) - } } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/json/AirbyteValueToJson.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/json/AirbyteValueToJson.kt index ac68a0082bf5..88bc4050256f 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/json/AirbyteValueToJson.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/json/AirbyteValueToJson.kt @@ -14,9 +14,8 @@ class AirbyteValueToJson { is ArrayValue -> JsonNodeFactory.instance.arrayNode().addAll(value.values.map { convert(it) }) is BooleanValue -> JsonNodeFactory.instance.booleanNode(value.value) - is DateValue -> JsonNodeFactory.instance.textNode(value.value) + is DateValue -> JsonNodeFactory.instance.textNode(value.value.toString()) is IntegerValue -> JsonNodeFactory.instance.numberNode(value.value) - is IntValue -> JsonNodeFactory.instance.numberNode(value.value) is NullValue -> JsonNodeFactory.instance.nullNode() is NumberValue -> JsonNodeFactory.instance.numberNode(value.value) is ObjectValue -> { @@ -25,9 +24,13 @@ class AirbyteValueToJson { objNode } is StringValue -> JsonNodeFactory.instance.textNode(value.value) - is TimeValue -> JsonNodeFactory.instance.textNode(value.value) - is TimestampValue -> JsonNodeFactory.instance.textNode(value.value) - is UnknownValue -> throw IllegalArgumentException("Unknown value: $value") + is TimeWithTimezoneValue -> JsonNodeFactory.instance.textNode(value.value.toString()) + is TimeWithoutTimezoneValue -> JsonNodeFactory.instance.textNode(value.value.toString()) + is TimestampWithTimezoneValue -> + JsonNodeFactory.instance.textNode(value.value.toString()) + is TimestampWithoutTimezoneValue -> + JsonNodeFactory.instance.textNode(value.value.toString()) + is UnknownValue -> value.value } } } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/json/JsonSchemaToAirbyteType.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/json/JsonSchemaToAirbyteType.kt index 7653c70e467c..f3a0ba33ffbd 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/json/JsonSchemaToAirbyteType.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/json/JsonSchemaToAirbyteType.kt @@ -8,9 +8,14 @@ import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.node.JsonNodeFactory import com.fasterxml.jackson.databind.node.ObjectNode import io.airbyte.cdk.load.data.* +import io.github.oshai.kotlinlogging.KotlinLogging class JsonSchemaToAirbyteType { - fun convert(schema: JsonNode): AirbyteType { + private val log = KotlinLogging.logger {} + + fun convert(schema: JsonNode): AirbyteType = convertInner(schema)!! + + private fun convertInner(schema: JsonNode): AirbyteType? { // try { if (schema.isObject && schema.has("type")) { // Normal json object with {"type": ..., ...} @@ -20,44 +25,54 @@ class JsonSchemaToAirbyteType { when (schema.get("type").asText()) { "string" -> fromString(schema) "boolean" -> BooleanType + "int", "integer" -> IntegerType "number" -> fromNumber(schema) "array" -> fromArray(schema) "object" -> fromObject(schema) - "null" -> NullType - else -> - throw IllegalArgumentException( - "Unknown type: ${ - schema.get("type").asText() - }" - ) + "null" -> null + else -> UnknownType(schema) } } else if (schemaType.isArray) { // {"type": [...], ...} unionFromCombinedTypes(schemaType.toList(), schema) } else { - UnknownType("unspported type for 'type' field: $schemaType") + UnknownType(schema) + } + } else if (schema.isObject && schema.has("\$ref")) { + // TODO: Determine whether we even still need to support this + return when (schema.get("\$ref").asText()) { + "WellKnownTypes.json#/definitions/Integer" -> IntegerType + "WellKnownTypes.json#/definitions/Number" -> NumberType + "WellKnownTypes.json#/definitions/String" -> StringType + "WellKnownTypes.json#/definitions/Boolean" -> BooleanType + "WellKnownTypes.json#/definitions/Date" -> DateType + "WellKnownTypes.json#/definitions/TimestampWithTimezone" -> + TimestampTypeWithTimezone + "WellKnownTypes.json#/definitions/TimestampWithoutTimezone" -> + TimestampTypeWithoutTimezone + "WellKnownTypes.json#/definitions/BinaryData" -> StringType + "WellKnownTypes.json#/definitions/TimeWithTimezone" -> TimeTypeWithTimezone + "WellKnownTypes.json#/definitions/TimeWithoutTimezone" -> TimeTypeWithoutTimezone + else -> UnknownType(schema) } } else if (schema.isObject) { // {"oneOf": [...], ...} or {"anyOf": [...], ...} or {"allOf": [...], ...} val options = schema.get("oneOf") ?: schema.get("anyOf") ?: schema.get("allOf") return if (options != null) { - UnionType(options.map { convert(it as ObjectNode) }) + UnionType.of(options.mapNotNull { convertInner(it as ObjectNode) }) } else { // Default to object if no type and not a union type - convert((schema as ObjectNode).put("type", "object")) + convertInner((schema as ObjectNode).put("type", "object")) } } else if (schema.isTextual) { // "" val typeSchema = JsonNodeFactory.instance.objectNode().put("type", schema.asText()) - return convert(typeSchema) + return convertInner(typeSchema) } else { - return UnknownType("Unknown schema type: $schema") + return UnknownType(schema) } - } // catch (t: Throwable) { - // return UnknownType(t.message ?: "Unknown error") - // } - // } + } private fun fromString(schema: ObjectNode): AirbyteType = when (schema.get("format")?.asText()) { @@ -75,12 +90,10 @@ class JsonSchemaToAirbyteType { TimestampTypeWithTimezone } null -> StringType - else -> - throw IllegalArgumentException( - "Unknown string format: ${ - schema.get("format").asText() - }" - ) + else -> { + log.warn { "Ignoring unrecognized string format: ${schema.get("format").asText()}" } + StringType + } } private fun fromNumber(schema: ObjectNode): AirbyteType = @@ -96,8 +109,8 @@ class JsonSchemaToAirbyteType { if (items.isEmpty) { return ArrayTypeWithoutSchema } - val itemOptions = UnionType(items.map { convert(it) }) - return ArrayType(fieldFromUnion(itemOptions)) + val itemType = UnionType.of(items.mapNotNull { convertInner(it) }) + return ArrayType(FieldType(itemType, true)) } return ArrayType(fieldFromSchema(items as ObjectNode)) } @@ -107,60 +120,41 @@ class JsonSchemaToAirbyteType { if (properties.isEmpty) { return ObjectTypeWithEmptySchema } - val requiredFields = schema.get("required")?.map { it.asText() } ?: emptyList() - return objectFromProperties(properties as ObjectNode, requiredFields) + val propertiesMapped = + properties + .fields() + .asSequence() + .map { (name, node) -> name to fieldFromSchema(node as ObjectNode) } + .toMap(LinkedHashMap()) + return ObjectType(propertiesMapped) } private fun fieldFromSchema( fieldSchema: ObjectNode, - onRequiredList: Boolean = false ): FieldType { - val markedRequired = fieldSchema.get("required")?.asBoolean() ?: false - val nullable = !(onRequiredList || markedRequired) - val airbyteType = convert(fieldSchema) - if (airbyteType is UnionType) { - return fieldFromUnion(airbyteType, nullable) - } else { - return FieldType(airbyteType, nullable) - } - } - - private fun fieldFromUnion(unionType: UnionType, nullable: Boolean = false): FieldType { - if (unionType.options.contains(NullType)) { - val filtered = unionType.options.filter { it != NullType } - return FieldType(UnionType(filtered), nullable = true) - } - return FieldType(unionType, nullable = nullable) - } - - private fun objectFromProperties(schema: ObjectNode, requiredFields: List): ObjectType { - val properties = - schema - .fields() - .asSequence() - .map { (name, node) -> - name to fieldFromSchema(node as ObjectNode, requiredFields.contains(name)) - } - .toMap(LinkedHashMap()) - return ObjectType(properties) + val airbyteType = convertInner(fieldSchema) ?: UnknownType(fieldSchema) + return FieldType(airbyteType, nullable = true) } private fun unionFromCombinedTypes( options: List, parentSchema: ObjectNode - ): UnionType { + ): AirbyteType { // Denormalize the properties across each type (the converter only checks what matters // per type). val unionOptions = - options.map { + options.mapNotNull { if (it.isTextual) { val schema = parentSchema.deepCopy() schema.put("type", it.textValue()) - convert(schema) + convertInner(schema) } else { - convert(it) + convertInner(it) } } - return UnionType(unionOptions) + if (unionOptions.isEmpty()) { + return UnknownType(parentSchema) + } + return UnionType.of(unionOptions) } } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/json/JsonToAirbyteValue.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/json/JsonToAirbyteValue.kt index db84e70dd5e0..aa848f8444a2 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/json/JsonToAirbyteValue.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/data/json/JsonToAirbyteValue.kt @@ -5,202 +5,42 @@ package io.airbyte.cdk.load.data.json import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.JsonNodeType +import com.fasterxml.jackson.databind.node.ObjectNode import io.airbyte.cdk.load.data.* -import java.math.BigDecimal /** - * Converts from json to airbyte value, performing the minimum validation necessary to marshal to a - * native type. For example, we enforce that an integer is either integral or something that can be - * reasonably converted to an integer, but we do not parse dates or timestamps, which can be - * reasonably left as strings. - * - * TODO: In the future, should we be more or less aggressive here? Which keeps parity with existing - * behavior? Which existing behavior should be preserved? + * Naively convert a json node to the equivalent AirbyteValue. Note that this does not match against + * a declared schema; it simply does the most obvious conversion. */ class JsonToAirbyteValue { - fun convert(json: JsonNode, schema: AirbyteType): AirbyteValue { - if (json.isNull) { - return NullValue - } - try { - return when (schema) { - is ArrayType -> toArray(json, schema.items.type) - is ArrayTypeWithoutSchema -> toArrayWithoutSchema(json) - is BooleanType -> toBoolean(json) - is DateType -> DateValue(json.asText()) - is IntegerType -> toInteger(json) - is NullType -> toNull(json) - is NumberType -> toNumber(json) - is ObjectType -> toObject(json, schema) - is ObjectTypeWithoutSchema, - is ObjectTypeWithEmptySchema -> toObjectWithoutSchema(json) - is StringType -> StringValue(json.asText()) - is TimeTypeWithTimezone, - is TimeTypeWithoutTimezone -> TimeValue(json.asText()) - is TimestampTypeWithTimezone, - is TimestampTypeWithoutTimezone -> TimestampValue(json.asText()) - is UnionType -> toUnion(json, schema.options) - is UnknownType -> UnknownValue("From $schema: $json") + fun convert(json: JsonNode): AirbyteValue { + return when (json.nodeType!!) { + JsonNodeType.NULL, + JsonNodeType.MISSING -> NullValue + JsonNodeType.BOOLEAN -> BooleanValue(json.booleanValue()) + JsonNodeType.NUMBER -> { + if (json.isIntegralNumber) { + IntegerValue(json.bigIntegerValue()) + } else { + NumberValue(json.decimalValue()) + } } - } catch (t: Throwable) { - return UnknownValue(t.message ?: "Unknown error") - } - } - - private fun toArray(json: JsonNode, schema: AirbyteType): ArrayValue { - if (!json.isArray) { - throw IllegalArgumentException("Could not convert $json to Array") - } - - return ArrayValue(json.map { convert(it, schema) }) - } - - private fun toArrayWithoutSchema(json: JsonNode): ArrayValue { - if (!json.isArray) { - throw IllegalArgumentException("Could not convert $json to Array") - } - - return ArrayValue(json.map { fromJson(it) }) - } - - private fun toBoolean(json: JsonNode): BooleanValue { - val boolVal = - when { - json.isBoolean -> json.asBoolean() - json.isIntegralNumber -> json.asLong() != 0L - json.isFloatingPointNumber -> json.asDouble() != 0.0 - json.isTextual -> json.asText().toBooleanStrict() - else -> throw IllegalArgumentException("Could not convert $json to Boolean") - } - return BooleanValue(boolVal) - } - - private fun toInteger(json: JsonNode): IntegerValue { - val longVal = - when { - json.isBoolean -> if (json.asBoolean()) 1L else 0L - json.isIntegralNumber -> json.asLong() - json.isFloatingPointNumber -> json.asDouble().toLong() - json.isTextual -> json.asText().toLong() - else -> throw IllegalArgumentException("Could not convert $json to Integer") - } - return IntegerValue(longVal) - } - - private fun toNumber(json: JsonNode): NumberValue { - val numVal = - when { - json.isBoolean -> BigDecimal(if (json.asBoolean()) 1.0 else 0.0) - json.isIntegralNumber -> json.asLong().toBigDecimal() - json.isFloatingPointNumber -> json.asDouble().toBigDecimal() - json.isTextual -> json.asText().toBigDecimal() - else -> throw IllegalArgumentException("Could not convert $json to Number") - } - return NumberValue(numVal) - } - - private fun toObject(json: JsonNode, schema: ObjectType): ObjectValue { - if (!json.isObject) { - throw IllegalArgumentException("Could not convert $json to Object") - } - - return ObjectValue( - values = - schema.properties - // Note that this will create an ObjectValue where properties in the schema - // might not exist in the value. - // This matches JSON behavior (i.e. explicit null != property not set), - // but we maybe would prefer to set an explicit NullValue. - .filter { (name, _) -> json.has(name) } - .mapValues { (name, field) -> convert(json.get(name), field.type) } - .toMap(LinkedHashMap()) - ) - } - - private fun toObjectWithoutSchema(json: JsonNode): ObjectValue { - if (!json.isObject) { - throw IllegalArgumentException("Could not convert $json to Object") - } - - return ObjectValue( - values = - json - .fields() - .asSequence() - .map { (name, value) -> name to fromJson(value) } - .toMap(LinkedHashMap()) - ) - } - - private fun toNull(json: JsonNode): NullValue { - if (!json.isNull) { - throw IllegalArgumentException("Null types must be null (not $json)") - } - - return NullValue - } - - private fun toUnion(json: JsonNode, options: List): AirbyteValue { - val option = - options.find { matchesStrictly(it, json) } - ?: options.find { matchesPermissively(it, json) } - ?: throw IllegalArgumentException( - "No matching union option in $options for $json" - ) - return convert(json, option) - } - - private fun fromJson(json: JsonNode): AirbyteValue { - return when { - json.isBoolean -> toBoolean(json) - json.isIntegralNumber -> toInteger(json) - json.isFloatingPointNumber -> toNumber(json) - json.isTextual -> StringValue(json.asText()) - json.isArray -> ArrayValue(json.map { fromJson(it) }) - json.isObject -> + JsonNodeType.STRING -> StringValue(json.textValue()) + JsonNodeType.ARRAY -> ArrayValue(json.map { convert(it) }) + JsonNodeType.OBJECT -> ObjectValue( - json - .fields() - .asSequence() - .map { (name, value) -> name to fromJson(value) } - .toMap(LinkedHashMap()) + (json as ObjectNode).properties().associateTo(linkedMapOf()) { (k, v) -> + k to convert(v) + } ) - json.isNull -> NullValue - else -> UnknownValue("From unrecognized json: $json") - } - } - - private fun matchesStrictly(schema: AirbyteType, json: JsonNode): Boolean { - return when (schema) { - is ArrayType, - is ArrayTypeWithoutSchema -> json.isArray - is BooleanType -> json.isBoolean - is DateType -> json.isTextual - is IntegerType -> json.isIntegralNumber - is NullType -> json.isNull - is NumberType -> json.isNumber - is ObjectType, - is ObjectTypeWithoutSchema, - is ObjectTypeWithEmptySchema -> json.isObject - is StringType -> json.isTextual - is TimeTypeWithTimezone, - is TimeTypeWithoutTimezone, - is TimestampTypeWithTimezone, - is TimestampTypeWithoutTimezone -> json.isTextual - is UnionType -> schema.options.any { matchesStrictly(it, json) } - is UnknownType -> false - } - } - - private fun matchesPermissively(schema: AirbyteType, json: JsonNode): Boolean { - return try { - convert(json, schema) !is UnknownValue - } catch (t: Throwable) { - false + JsonNodeType.POJO, + JsonNodeType.BINARY -> + throw NotImplementedError("Unsupported JsonNode type: ${json.nodeType}") } } } -fun JsonNode.toAirbyteValue(schema: AirbyteType): AirbyteValue { - return JsonToAirbyteValue().convert(this, schema) +fun JsonNode.toAirbyteValue(): AirbyteValue { + return JsonToAirbyteValue().convert(this) } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/file/SpillFileProvider.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/file/SpillFileProvider.kt index aba15226d7ca..0d5607099f01 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/file/SpillFileProvider.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/file/SpillFileProvider.kt @@ -20,6 +20,6 @@ class DefaultSpillFileProvider(val config: DestinationConfiguration) : SpillFile override fun createTempFile(): Path { val directory = config.tmpFileDirectory Files.createDirectories(directory) - return Files.createTempFile(directory, "staged-raw-records", "jsonl") + return Files.createTempFile(directory, "staged-raw-records", ".jsonl") } } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/file/StreamProcessor.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/file/StreamProcessor.kt index 1edc10a2c366..5f8d49e5c7ab 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/file/StreamProcessor.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/file/StreamProcessor.kt @@ -4,10 +4,12 @@ package io.airbyte.cdk.load.file +import java.io.BufferedOutputStream import java.io.ByteArrayOutputStream +import java.io.OutputStream import java.util.zip.GZIPOutputStream -interface StreamProcessor { +interface StreamProcessor { val wrapper: (ByteArrayOutputStream) -> T val partFinisher: T.() -> Unit val extension: String? @@ -19,8 +21,10 @@ data object NoopProcessor : StreamProcessor { override val extension: String? = null } -data object GZIPProcessor : StreamProcessor { - override val wrapper: (ByteArrayOutputStream) -> GZIPOutputStream = { GZIPOutputStream(it) } - override val partFinisher: GZIPOutputStream.() -> Unit = { finish() } +data object GZIPProcessor : StreamProcessor { + override val wrapper: (ByteArrayOutputStream) -> BufferedOutputStream = { + BufferedOutputStream(GZIPOutputStream(it)) + } + override val partFinisher: BufferedOutputStream.() -> Unit = { close() } override val extension: String = "gz" } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/file/TimeProvider.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/file/TimeProvider.kt index 054bd6074b29..30ae80c0fa18 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/file/TimeProvider.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/file/TimeProvider.kt @@ -8,6 +8,7 @@ import io.micronaut.context.annotation.Secondary import jakarta.inject.Singleton interface TimeProvider { + fun syncTimeMillis(): Long fun currentTimeMillis(): Long suspend fun delay(ms: Long) } @@ -15,6 +16,10 @@ interface TimeProvider { @Singleton @Secondary class DefaultTimeProvider : TimeProvider { + private val creationTime = System.currentTimeMillis() + + override fun syncTimeMillis(): Long = creationTime + override fun currentTimeMillis(): Long { return System.currentTimeMillis() } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/Batch.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/Batch.kt index 9b4ac55bef1e..0c6fe3e17287 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/Batch.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/Batch.kt @@ -7,6 +7,7 @@ package io.airbyte.cdk.load.message import com.google.common.collect.Range import com.google.common.collect.RangeSet import com.google.common.collect.TreeRangeSet +import io.airbyte.cdk.load.command.DestinationStream /** * Represents an accumulated batch of records in some stage of processing. @@ -20,12 +21,17 @@ import com.google.common.collect.TreeRangeSet * the associated ranges have been persisted remotely, and that platform checkpoint messages can be * emitted. * - * [State.SPILLED] is used internally to indicate that records have been spooled to disk for + * [State.STAGED] is used internally to indicate that records have been spooled to disk for * processing and should not be used by implementors. * * When a stream has been read to End-of-stream, and all ranges between 0 and End-of-stream are * [State.COMPLETE], then all records are considered to have been processed. * + * A [Batch] may contain an optional `groupId`. If provided, the most advanced state provided for + * any batch will apply to all batches with the same `groupId`. This is useful for a case where each + * batch represents part of a larger work unit that is only completed when all parts are processed. + * (We used most advanced instead of latest to avoid race conditions.) + * * The intended usage for implementors is to implement the provided interfaces in case classes that * contain the necessary metadata for processing, using them in @ * [io.airbyte.cdk.write.StreamLoader.processBatch] to route to the appropriate handler(s). @@ -45,8 +51,11 @@ import com.google.common.collect.TreeRangeSet * ``` */ interface Batch { + val groupId: String? + enum class State { - LOCAL, + PROCESSED, + STAGED, PERSISTED, COMPLETE } @@ -59,10 +68,20 @@ interface Batch { } val state: State + + /** + * If a [Batch] is [State.COMPLETE], there's nothing further to do. If it is part of a group, + * then its state will be updated by the next batch in the group that advances. + */ + val requiresProcessing: Boolean + get() = state != State.COMPLETE && groupId == null } /** Simple batch: use if you need no other metadata for processing. */ -data class SimpleBatch(override val state: Batch.State) : Batch +data class SimpleBatch( + override val state: Batch.State, + override val groupId: String? = null, +) : Batch /** * Internally-used wrapper for tracking the association between a batch and the range of records it @@ -70,14 +89,20 @@ data class SimpleBatch(override val state: Batch.State) : Batch */ data class BatchEnvelope( val batch: B, - val ranges: RangeSet = TreeRangeSet.create() + val ranges: RangeSet = TreeRangeSet.create(), + val streamDescriptor: DestinationStream.Descriptor ) { constructor( batch: B, - range: Range - ) : this(batch = batch, ranges = TreeRangeSet.create(listOf(range))) + range: Range?, + streamDescriptor: DestinationStream.Descriptor + ) : this( + batch = batch, + ranges = range?.let { TreeRangeSet.create(listOf(range)) } ?: TreeRangeSet.create(), + streamDescriptor = streamDescriptor + ) fun withBatch(newBatch: C): BatchEnvelope { - return BatchEnvelope(newBatch, ranges) + return BatchEnvelope(newBatch, ranges, streamDescriptor) } } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/DestinationMessage.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/DestinationMessage.kt index a6a76520c519..55efadc0d422 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/DestinationMessage.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/DestinationMessage.kt @@ -4,16 +4,20 @@ package io.airbyte.cdk.load.message +import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.databind.JsonNode import io.airbyte.cdk.load.command.DestinationCatalog import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.data.AirbyteType import io.airbyte.cdk.load.data.AirbyteValue -import io.airbyte.cdk.load.data.ObjectTypeWithoutSchema -import io.airbyte.cdk.load.data.json.AirbyteValueToJson -import io.airbyte.cdk.load.data.json.JsonToAirbyteValue +import io.airbyte.cdk.load.data.AirbyteValueDeepCoercingMapper +import io.airbyte.cdk.load.data.IntegerValue +import io.airbyte.cdk.load.data.StringValue +import io.airbyte.cdk.load.data.TimestampWithTimezoneValue +import io.airbyte.cdk.load.data.json.toAirbyteValue import io.airbyte.cdk.load.message.CheckpointMessage.Checkpoint import io.airbyte.cdk.load.message.CheckpointMessage.Stats -import io.airbyte.protocol.models.Jsons +import io.airbyte.cdk.load.util.deserializeToNode import io.airbyte.protocol.models.v0.AirbyteGlobalState import io.airbyte.protocol.models.v0.AirbyteMessage import io.airbyte.protocol.models.v0.AirbyteRecordMessage @@ -25,7 +29,10 @@ import io.airbyte.protocol.models.v0.AirbyteStreamState import io.airbyte.protocol.models.v0.AirbyteStreamStatusTraceMessage import io.airbyte.protocol.models.v0.AirbyteStreamStatusTraceMessage.AirbyteStreamStatus import io.airbyte.protocol.models.v0.AirbyteTraceMessage +import io.micronaut.context.annotation.Value import jakarta.inject.Singleton +import java.math.BigInteger +import java.time.OffsetDateTime /** * Internal representation of destination messages. These are intended to be specialized for @@ -40,42 +47,68 @@ sealed interface DestinationStreamAffinedMessage : DestinationMessage { val stream: DestinationStream.Descriptor } -data class DestinationRecord( - override val stream: DestinationStream.Descriptor, - val data: AirbyteValue, - val emittedAtMs: Long, - val meta: Meta?, - val serialized: String, -) : DestinationStreamAffinedMessage { - /** Convenience constructor, primarily intended for use in tests. */ - constructor( - namespace: String?, - name: String, - data: String, - emittedAtMs: Long, - changes: MutableList = mutableListOf(), - ) : this( - stream = DestinationStream.Descriptor(namespace, name), - data = JsonToAirbyteValue().convert(Jsons.deserialize(data), ObjectTypeWithoutSchema), - emittedAtMs = emittedAtMs, - meta = Meta(changes), - serialized = "", - ) +sealed interface DestinationRecordDomainMessage : DestinationStreamAffinedMessage - data class Meta(val changes: MutableList = mutableListOf()) { - companion object { - const val COLUMN_NAME_AB_RAW_ID: String = "_airbyte_raw_id" - const val COLUMN_NAME_AB_EXTRACTED_AT: String = "_airbyte_extracted_at" - const val COLUMN_NAME_AB_META: String = "_airbyte_meta" - const val COLUMN_NAME_AB_GENERATION_ID: String = "_airbyte_generation_id" - const val COLUMN_NAME_DATA: String = "_airbyte_data" - } +sealed interface DestinationFileDomainMessage : DestinationStreamAffinedMessage - fun asProtocolObject(): AirbyteRecordMessageMeta = - AirbyteRecordMessageMeta() - .withChanges(changes.map { change -> change.asProtocolObject() }) +data class Meta( + val changes: List = mutableListOf(), +) { + companion object { + const val COLUMN_NAME_AB_RAW_ID: String = "_airbyte_raw_id" + const val COLUMN_NAME_AB_EXTRACTED_AT: String = "_airbyte_extracted_at" + const val COLUMN_NAME_AB_META: String = "_airbyte_meta" + const val COLUMN_NAME_AB_GENERATION_ID: String = "_airbyte_generation_id" + const val COLUMN_NAME_DATA: String = "_airbyte_data" + val COLUMN_NAMES = + setOf( + COLUMN_NAME_AB_RAW_ID, + COLUMN_NAME_AB_EXTRACTED_AT, + COLUMN_NAME_AB_META, + COLUMN_NAME_AB_GENERATION_ID, + ) + + fun getMetaValue(metaColumnName: String, value: String): AirbyteValue { + if (!COLUMN_NAMES.contains(metaColumnName)) { + throw IllegalArgumentException("Invalid meta column name: $metaColumnName") + } + fun toObjectValue(value: JsonNode): AirbyteValue { + if (value.isTextual) { + return toObjectValue(value.textValue().deserializeToNode()) + } + return value.toAirbyteValue() + } + return when (metaColumnName) { + COLUMN_NAME_AB_RAW_ID -> StringValue(value) + COLUMN_NAME_AB_EXTRACTED_AT -> { + // Some destinations represent extractedAt as a long epochMillis, + // and others represent it as a timestamp string. + // Handle both cases here. + try { + IntegerValue(BigInteger(value)) + } catch (e: Exception) { + TimestampWithTimezoneValue( + OffsetDateTime.parse( + value, + AirbyteValueDeepCoercingMapper.DATE_TIME_FORMATTER + ) + ) + } + } + COLUMN_NAME_AB_META -> toObjectValue(value.deserializeToNode()) + COLUMN_NAME_AB_GENERATION_ID -> IntegerValue(BigInteger(value)) + COLUMN_NAME_DATA -> toObjectValue(value.deserializeToNode()) + else -> + throw NotImplementedError( + "Column name $metaColumnName is not yet supported. This is probably a bug." + ) + } + } } + fun asProtocolObject(): AirbyteRecordMessageMeta = + AirbyteRecordMessageMeta().withChanges(changes.map { change -> change.asProtocolObject() }) + data class Change( val field: String, // Using the raw protocol enums here. @@ -86,22 +119,124 @@ data class DestinationRecord( fun asProtocolObject(): AirbyteRecordMessageMetaChange = AirbyteRecordMessageMetaChange().withField(field).withChange(change).withReason(reason) } +} - override fun asProtocolMessage(): AirbyteMessage = - AirbyteMessage() +data class DestinationRecord( + override val stream: DestinationStream.Descriptor, + val message: AirbyteMessage, + val serialized: String, + val schema: AirbyteType +) : DestinationRecordDomainMessage { + override fun asProtocolMessage(): AirbyteMessage = message + + fun asRecordSerialized(): DestinationRecordSerialized = + DestinationRecordSerialized(stream, serialized) + fun asRecordMarshaledToAirbyteValue(): DestinationRecordAirbyteValue { + return DestinationRecordAirbyteValue( + stream, + message.record.data.toAirbyteValue(), + message.record.emittedAt, + Meta( + message.record.meta?.changes?.map { Meta.Change(it.field, it.change, it.reason) } + ?: emptyList() + ) + ) + } +} + +/** + * Represents a record already in its serialized state. The intended use is for conveying records + * from stdin to the spill file, where reserialization is not necessary. + */ +data class DestinationRecordSerialized( + val stream: DestinationStream.Descriptor, + val serialized: String +) + +/** Represents a record both deserialized AND marshaled to airbyte value. The marshaling */ +data class DestinationRecordAirbyteValue( + val stream: DestinationStream.Descriptor, + val data: AirbyteValue, + val emittedAtMs: Long, + val meta: Meta?, +) + +data class DestinationFile( + override val stream: DestinationStream.Descriptor, + val emittedAtMs: Long, + val serialized: String, + val fileMessage: AirbyteRecordMessageFile +) : DestinationFileDomainMessage { + /** Convenience constructor, primarily intended for use in tests. */ + class AirbyteRecordMessageFile { + constructor( + fileUrl: String? = null, + bytes: Long? = null, + fileRelativePath: String? = null, + modified: Long? = null, + sourceFileUrl: String? = null + ) { + this.fileUrl = fileUrl + this.bytes = bytes + this.fileRelativePath = fileRelativePath + this.modified = modified + this.sourceFileUrl = sourceFileUrl + } + constructor() : + this( + fileUrl = null, + bytes = null, + fileRelativePath = null, + modified = null, + sourceFileUrl = null + ) + + @get:JsonProperty("file_url") + @set:JsonProperty("file_url") + @JsonProperty("file_url") + var fileUrl: String? = null + + @get:JsonProperty("bytes") + @set:JsonProperty("bytes") + @JsonProperty("bytes") + var bytes: Long? = null + + @get:JsonProperty("file_relative_path") + @set:JsonProperty("file_relative_path") + @JsonProperty("file_relative_path") + var fileRelativePath: String? = null + + @get:JsonProperty("modified") + @set:JsonProperty("modified") + @JsonProperty("modified") + var modified: Long? = null + + @get:JsonProperty("source_file_url") + @set:JsonProperty("source_file_url") + @JsonProperty("source_file_url") + var sourceFileUrl: String? = null + } + + override fun asProtocolMessage(): AirbyteMessage { + val file = + mapOf( + "file_url" to fileMessage.fileUrl, + "file_relative_path" to fileMessage.fileRelativePath, + "source_file_url" to fileMessage.sourceFileUrl, + "modified" to fileMessage.modified, + "bytes" to fileMessage.bytes, + ) + + return AirbyteMessage() .withType(AirbyteMessage.Type.RECORD) .withRecord( AirbyteRecordMessage() .withStream(stream.name) .withNamespace(stream.namespace) .withEmittedAt(emittedAtMs) - .withData(AirbyteValueToJson().convert(data)) - .also { - if (meta != null) { - it.meta = meta.asProtocolObject() - } - } + .withAdditionalProperty("file", file) ) + } } private fun statusToProtocolMessage( @@ -122,18 +257,34 @@ private fun statusToProtocolMessage( ) ) -data class DestinationStreamComplete( +data class DestinationRecordStreamComplete( + override val stream: DestinationStream.Descriptor, + val emittedAtMs: Long, +) : DestinationRecordDomainMessage { + override fun asProtocolMessage(): AirbyteMessage = + statusToProtocolMessage(stream, emittedAtMs, AirbyteStreamStatus.COMPLETE) +} + +data class DestinationRecordStreamIncomplete( override val stream: DestinationStream.Descriptor, val emittedAtMs: Long, -) : DestinationStreamAffinedMessage { +) : DestinationRecordDomainMessage { + override fun asProtocolMessage(): AirbyteMessage = + statusToProtocolMessage(stream, emittedAtMs, AirbyteStreamStatus.INCOMPLETE) +} + +data class DestinationFileStreamComplete( + override val stream: DestinationStream.Descriptor, + val emittedAtMs: Long, +) : DestinationFileDomainMessage { override fun asProtocolMessage(): AirbyteMessage = statusToProtocolMessage(stream, emittedAtMs, AirbyteStreamStatus.COMPLETE) } -data class DestinationStreamIncomplete( +data class DestinationFileStreamIncomplete( override val stream: DestinationStream.Descriptor, val emittedAtMs: Long, -) : DestinationStreamAffinedMessage { +) : DestinationFileDomainMessage { override fun asProtocolMessage(): AirbyteMessage = statusToProtocolMessage(stream, emittedAtMs, AirbyteStreamStatus.INCOMPLETE) } @@ -143,25 +294,40 @@ sealed interface CheckpointMessage : DestinationMessage { data class Stats(val recordCount: Long) data class Checkpoint( val stream: DestinationStream.Descriptor, - val state: JsonNode, + val state: JsonNode?, ) { fun asProtocolObject(): AirbyteStreamState = - AirbyteStreamState() - .withStreamDescriptor(stream.asProtocolObject()) - .withStreamState(state) + AirbyteStreamState().withStreamDescriptor(stream.asProtocolObject()).also { + if (state != null) { + it.streamState = state + } + } } val sourceStats: Stats? val destinationStats: Stats? + val additionalProperties: Map fun withDestinationStats(stats: Stats): CheckpointMessage + + fun decorateStateMessage(message: AirbyteStateMessage) { + if (sourceStats != null) { + message.sourceStats = + AirbyteStateStats().withRecordCount(sourceStats!!.recordCount.toDouble()) + } + if (destinationStats != null) { + message.destinationStats = + AirbyteStateStats().withRecordCount(destinationStats!!.recordCount.toDouble()) + } + additionalProperties.forEach { (key, value) -> message.withAdditionalProperty(key, value) } + } } data class StreamCheckpoint( val checkpoint: Checkpoint, override val sourceStats: Stats?, override val destinationStats: Stats? = null, - val additionalProperties: Map + override val additionalProperties: Map = emptyMap(), ) : CheckpointMessage { /** Convenience constructor, intended for use in tests. */ constructor( @@ -173,35 +339,21 @@ data class StreamCheckpoint( ) : this( Checkpoint( DestinationStream.Descriptor(streamNamespace, streamName), - state = Jsons.deserialize(blob) + state = blob.deserializeToNode() ), Stats(sourceRecordCount), destinationRecordCount?.let { Stats(it) }, - additionalProperties = mutableMapOf(), + emptyMap(), ) - override fun withDestinationStats(stats: Stats) = - StreamCheckpoint(checkpoint, sourceStats, stats, additionalProperties) + override fun withDestinationStats(stats: Stats) = copy(destinationStats = stats) override fun asProtocolMessage(): AirbyteMessage { val stateMessage = AirbyteStateMessage() .withType(AirbyteStateMessage.AirbyteStateType.STREAM) .withStream(checkpoint.asProtocolObject()) - .also { - if (sourceStats != null) { - it.sourceStats = - AirbyteStateStats().withRecordCount(sourceStats.recordCount.toDouble()) - } - if (destinationStats != null) { - it.destinationStats = - AirbyteStateStats() - .withRecordCount(destinationStats.recordCount.toDouble()) - } - additionalProperties.forEach { (key, value) -> - it.withAdditionalProperty(key, value) - } - } + decorateStateMessage(stateMessage) return AirbyteMessage().withType(AirbyteMessage.Type.STATE).withState(stateMessage) } } @@ -211,39 +363,31 @@ data class GlobalCheckpoint( override val sourceStats: Stats?, override val destinationStats: Stats? = null, val checkpoints: List = emptyList(), - val additionalProperties: MutableMap = mutableMapOf() + override val additionalProperties: Map, + val originalTypeField: AirbyteStateMessage.AirbyteStateType? = + AirbyteStateMessage.AirbyteStateType.GLOBAL, ) : CheckpointMessage { /** Convenience constructor, primarily intended for use in tests. */ constructor( blob: String, sourceRecordCount: Long, - ) : this(state = Jsons.deserialize(blob), Stats(sourceRecordCount)) - override fun withDestinationStats(stats: Stats) = - GlobalCheckpoint(state, sourceStats, stats, checkpoints, additionalProperties) + ) : this( + state = blob.deserializeToNode(), + Stats(sourceRecordCount), + additionalProperties = emptyMap(), + ) + override fun withDestinationStats(stats: Stats) = copy(destinationStats = stats) override fun asProtocolMessage(): AirbyteMessage { val stateMessage = AirbyteStateMessage() - .withType(AirbyteStateMessage.AirbyteStateType.GLOBAL) + .withType(originalTypeField) .withGlobal( AirbyteGlobalState() .withSharedState(state) .withStreamStates(checkpoints.map { it.asProtocolObject() }) ) - .also { - if (sourceStats != null) { - it.sourceStats = - AirbyteStateStats().withRecordCount(sourceStats.recordCount.toDouble()) - } - if (destinationStats != null) { - it.destinationStats = - AirbyteStateStats() - .withRecordCount(destinationStats.recordCount.toDouble()) - } - it.additionalProperties.forEach { (key, value) -> - it.withAdditionalProperty(key, value) - } - } + decorateStateMessage(stateMessage) return AirbyteMessage().withType(AirbyteMessage.Type.STATE).withState(stateMessage) } } @@ -260,8 +404,29 @@ data object Undefined : DestinationMessage { } @Singleton -class DestinationMessageFactory(private val catalog: DestinationCatalog) { - fun fromAirbyteMessage(message: AirbyteMessage, serialized: String): DestinationMessage { +class DestinationMessageFactory( + private val catalog: DestinationCatalog, + @Value("\${airbyte.file-transfer.enabled}") private val fileTransferEnabled: Boolean, +) { + fun fromAirbyteMessage( + message: AirbyteMessage, + serialized: String, + ): DestinationMessage { + fun toLong(value: Any?, name: String): Long? { + return value?.let { + when (it) { + // you can't cast java.lang.Integer -> java.lang.Long + // so instead we have to do this manual pattern match + is Int -> it.toLong() + is Long -> it + else -> + throw IllegalArgumentException( + "Unexpected value for $name: $it (${it::class.qualifiedName})" + ) + } + } + } + return when (message.type) { AirbyteMessage.Type.RECORD -> { val stream = @@ -269,27 +434,34 @@ class DestinationMessageFactory(private val catalog: DestinationCatalog) { namespace = message.record.namespace, name = message.record.stream, ) - DestinationRecord( - stream = stream.descriptor, - data = JsonToAirbyteValue().convert(message.record.data, stream.schema), - emittedAtMs = message.record.emittedAt, - meta = - DestinationRecord.Meta( - changes = - message.record.meta - ?.changes - ?.map { - DestinationRecord.Change( - field = it.field, - change = it.change, - reason = it.reason, - ) - } - ?.toMutableList() - ?: mutableListOf() - ), - serialized = serialized - ) + if (fileTransferEnabled) { + try { + @Suppress("UNCHECKED_CAST") + val fileMessage = + message.record.additionalProperties["file"] as Map + + DestinationFile( + stream = stream.descriptor, + emittedAtMs = message.record.emittedAt, + serialized = serialized, + fileMessage = + DestinationFile.AirbyteRecordMessageFile( + fileUrl = fileMessage["file_url"] as String?, + bytes = toLong(fileMessage["bytes"], "message.record.bytes"), + fileRelativePath = fileMessage["file_relative_path"] as String?, + modified = + toLong(fileMessage["modified"], "message.record.modified"), + sourceFileUrl = fileMessage["source_file_url"] as String? + ) + ) + } catch (e: Exception) { + throw IllegalArgumentException( + "Failed to construct file message: ${e.message}" + ) + } + } else { + DestinationRecord(stream.descriptor, message, serialized, stream.schema) + } } AirbyteMessage.Type.TRACE -> { val status = message.trace.streamStatus @@ -298,18 +470,35 @@ class DestinationMessageFactory(private val catalog: DestinationCatalog) { namespace = status.streamDescriptor.namespace, name = status.streamDescriptor.name, ) - if (message.trace.type == AirbyteTraceMessage.Type.STREAM_STATUS) { + if ( + message.trace.type == null || + message.trace.type == AirbyteTraceMessage.Type.STREAM_STATUS + ) { when (status.status) { AirbyteStreamStatus.COMPLETE -> - DestinationStreamComplete( - stream.descriptor, - message.trace.emittedAt.toLong() - ) + if (fileTransferEnabled) { + DestinationFileStreamComplete( + stream.descriptor, + message.trace.emittedAt?.toLong() ?: 0L + ) + } else { + DestinationRecordStreamComplete( + stream.descriptor, + message.trace.emittedAt?.toLong() ?: 0L + ) + } AirbyteStreamStatus.INCOMPLETE -> - DestinationStreamIncomplete( - stream.descriptor, - message.trace.emittedAt.toLong() - ) + if (fileTransferEnabled) { + DestinationFileStreamIncomplete( + stream.descriptor, + message.trace.emittedAt?.toLong() ?: 0L + ) + } else { + DestinationRecordStreamIncomplete( + stream.descriptor, + message.trace.emittedAt?.toLong() ?: 0L + ) + } else -> Undefined } } else { @@ -325,8 +514,9 @@ class DestinationMessageFactory(private val catalog: DestinationCatalog) { message.state.sourceStats?.recordCount?.let { Stats(recordCount = it.toLong()) }, - additionalProperties = message.state.additionalProperties + additionalProperties = message.state.additionalProperties, ) + null, AirbyteStateMessage.AirbyteStateType.GLOBAL -> GlobalCheckpoint( sourceStats = @@ -338,7 +528,8 @@ class DestinationMessageFactory(private val catalog: DestinationCatalog) { message.state.global.streamStates.map { fromAirbyteStreamState(it) }, - additionalProperties = message.state.additionalProperties + additionalProperties = message.state.additionalProperties, + originalTypeField = message.state.type, ) else -> // TODO: Do we still need to handle LEGACY? Undefined @@ -352,7 +543,7 @@ class DestinationMessageFactory(private val catalog: DestinationCatalog) { val descriptor = streamState.streamDescriptor return Checkpoint( stream = DestinationStream.Descriptor(descriptor.namespace, descriptor.name), - state = streamState.streamState + state = runCatching { streamState.streamState }.getOrNull() ) } } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/DestinationMessageDeserializer.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/DestinationMessageDeserializer.kt index 81a7f5a4fd81..65f42ece592f 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/DestinationMessageDeserializer.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/DestinationMessageDeserializer.kt @@ -4,28 +4,52 @@ package io.airbyte.cdk.load.message -import io.airbyte.cdk.util.Jsons +import io.airbyte.cdk.load.util.deserializeToClass import io.airbyte.protocol.models.v0.AirbyteMessage import jakarta.inject.Singleton -interface Deserializer { - fun deserialize(serialized: String): T -} - /** * Converts the internal @[AirbyteMessage] to the internal @[DestinationMessage] Ideally, this would * not use protocol messages at all, but rather a specialized deserializer for routing. */ @Singleton -class DefaultDestinationMessageDeserializer(private val messageFactory: DestinationMessageFactory) : - Deserializer { +class ProtocolMessageDeserializer( + private val destinationMessageFactory: DestinationMessageFactory, +) { + fun deserialize( + serialized: String, + ): DestinationMessage { + val airbyteMessage = + try { + serialized.deserializeToClass(AirbyteMessage::class.java) + } catch (t: Throwable) { + /** + * We don't want to expose client data, but we'd like to get as much info as we can + * about these malformed messages. + */ + val type = + if (serialized.contains("RECORD")) { + "record" + } else if (serialized.contains("STATE")) { + "state" + } else if (serialized.contains("TRACE")) { + if (serialized.contains("STATUS", ignoreCase = true)) { + "status" + } else { + "trace" + } + } else { + "unknown" + } + + throw RuntimeException( + "Failed to deserialize airbyte message (type=$type; length=${serialized.length}; reason=${t.javaClass})" + ) + } - override fun deserialize(serialized: String): DestinationMessage { - try { - val airbyteMessage = Jsons.readValue(serialized, AirbyteMessage::class.java) - return messageFactory.fromAirbyteMessage(airbyteMessage, serialized) - } catch (t: Throwable) { - throw RuntimeException("Failed to deserialize AirbyteMessage: $serialized") - } + return destinationMessageFactory.fromAirbyteMessage( + airbyteMessage, + serialized, + ) } } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/DestinationMessageQueues.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/DestinationMessageQueues.kt index aa9099044b24..7164e8982688 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/DestinationMessageQueues.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/DestinationMessageQueues.kt @@ -6,7 +6,7 @@ package io.airbyte.cdk.load.message import io.airbyte.cdk.load.command.DestinationCatalog import io.airbyte.cdk.load.command.DestinationStream -import io.airbyte.cdk.load.state.MemoryManager +import io.airbyte.cdk.load.state.ReservationManager import io.airbyte.cdk.load.state.Reserved import io.micronaut.context.annotation.Secondary import jakarta.inject.Singleton @@ -17,47 +17,62 @@ interface Sized { } /** - * Wrapper for record messages published to the message queue, containing metadata like index and - * size. + * Wrapper message for stream events published to the stream specific queues, containing metadata + * like index and size. * * In a future where we deserialize only the info necessary for routing, this could include a dumb * container for the serialized, and deserialization could be deferred until the spooled records * were recovered from disk. */ -sealed class DestinationRecordWrapped : Sized +sealed class DestinationStreamEvent : Sized -data class StreamRecordWrapped( +/** Contains a record to be aggregated and processed. */ +data class StreamRecordEvent( val index: Long, override val sizeBytes: Long, - val record: DestinationRecord -) : DestinationRecordWrapped() + val payload: DestinationRecordSerialized +) : DestinationStreamEvent() -data class StreamCompleteWrapped( +/** + * Indicates the stream is in a terminal (complete or incomplete) state as signalled by upstream. + */ +data class StreamEndEvent( val index: Long, -) : DestinationRecordWrapped() { +) : DestinationStreamEvent() { + override val sizeBytes: Long = 0L +} + +/** + * Emitted to trigger evaluation of the conditional flush logic of a stream. The consumer may or may + * not decide to flush. + */ +data class StreamFlushEvent( + val tickedAtMs: Long, +) : DestinationStreamEvent() { override val sizeBytes: Long = 0L } -class DestinationRecordQueue : ChannelMessageQueue>() +class DestinationStreamEventQueue : ChannelMessageQueue>() /** - * A supplier of message queues to which ([MemoryManager.reserveBlocking]'d) @ - * [DestinationRecordWrapped] messages can be published on a @ [DestinationStream] key. The queues - * themselves do not manage memory. + * A supplier of message queues to which ([ReservationManager.reserve]'d) @ [DestinationStreamEvent] + * messages can be published on a @ [DestinationStream] key. The queues themselves do not manage + * memory. */ @Singleton @Secondary -class DestinationRecordQueueSupplier(catalog: DestinationCatalog) : - MessageQueueSupplier> { - private val queues = ConcurrentHashMap() +class DestinationStreamQueueSupplier(catalog: DestinationCatalog) : + MessageQueueSupplier> { + private val queues = + ConcurrentHashMap() init { - catalog.streams.forEach { queues[it.descriptor] = DestinationRecordQueue() } + catalog.streams.forEach { queues[it.descriptor] = DestinationStreamEventQueue() } } - override fun get(key: DestinationStream.Descriptor): DestinationRecordQueue { + override fun get(key: DestinationStream.Descriptor): DestinationStreamEventQueue { return queues[key] - ?: throw IllegalArgumentException("Reading from non-existent record stream: $key") + ?: throw IllegalArgumentException("Reading from non-existent stream: $key") } } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/MessageQueue.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/MessageQueue.kt index 2fe9488d03a4..e9ae6c33e39f 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/MessageQueue.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/MessageQueue.kt @@ -5,6 +5,7 @@ package io.airbyte.cdk.load.message import io.airbyte.cdk.load.util.CloseableCoroutine +import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.receiveAsFlow @@ -16,12 +17,13 @@ interface QueueReader { interface QueueWriter : CloseableCoroutine { suspend fun publish(message: T) + fun isClosedForPublish(): Boolean } interface MessageQueue : QueueReader, QueueWriter abstract class ChannelMessageQueue : MessageQueue { - val channel = Channel(Channel.UNLIMITED) + open val channel = Channel(Channel.UNLIMITED) override suspend fun publish(message: T) = channel.send(message) override suspend fun consume(): Flow = channel.receiveAsFlow() @@ -29,6 +31,8 @@ abstract class ChannelMessageQueue : MessageQueue { override suspend fun close() { channel.close() } + @OptIn(DelicateCoroutinesApi::class) + override fun isClosedForPublish(): Boolean = channel.isClosedForSend } interface MessageQueueSupplier { diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/MessageSupplier.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/MessageSupplier.kt new file mode 100644 index 000000000000..d2ec5d05532f --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/MessageSupplier.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.message + +import io.airbyte.cdk.load.util.CloseableCoroutine +import kotlinx.coroutines.channels.Channel + +interface MessageReader { + suspend fun get(): T? +} + +interface MessageWriter : CloseableCoroutine { + suspend fun publish(message: T) +} + +interface Message : MessageReader, MessageWriter + +abstract class ChannelMessage : Message { + val channel = Channel(Channel.UNLIMITED) + + override suspend fun publish(message: T) = channel.send(message) + override suspend fun get(): T? = channel.tryReceive().getOrNull() + override suspend fun close() { + channel.close() + } +} + +interface MessageSupplier { + fun get(key: K): ChannelMessage +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/MultiProducerChannel.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/MultiProducerChannel.kt new file mode 100644 index 000000000000..c369e8b47b8c --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/message/MultiProducerChannel.kt @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.message + +import io.github.oshai.kotlinlogging.KotlinLogging +import java.util.concurrent.atomic.AtomicLong +import kotlinx.coroutines.channels.Channel + +/** + * A channel designed for use with a fixed amount of producers. Close will be called on the + * underlying channel, when there are no remaining registered producers. + */ +class MultiProducerChannel( + producerCount: Long, + override val channel: Channel, + private val name: String, +) : ChannelMessageQueue() { + private val log = KotlinLogging.logger {} + private val initializedProducerCount = producerCount + private val producerCount = AtomicLong(producerCount) + + override suspend fun close() { + val count = producerCount.decrementAndGet() + log.info { + "Closing producer $name (active count=$count, initialized count: $initializedProducerCount)" + } + if (count == 0L) { + log.info { "Closing underlying queue" } + channel.close() + } + } +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/CheckpointManager.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/CheckpointManager.kt index 3f155cd5de72..ee20f281d0b5 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/CheckpointManager.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/CheckpointManager.kt @@ -158,6 +158,9 @@ abstract class StreamsCheckpointManager : CheckpointManager : CheckpointManager { + suspend fun getState(stream: DestinationStream): T + suspend fun persistState(stream: DestinationStream) +} + +@SuppressFBWarnings( + "NP_NONNULL_PARAM_VIOLATION", + justification = "state is guaranteed to be non-null by Kotlin's type system" +) +@Singleton +@Secondary +class DefaultDestinationStateManager( + private val persister: DestinationStatePersister, +) : DestinationStateManager { + private val states: ConcurrentHashMap = ConcurrentHashMap() + + override suspend fun getState(stream: DestinationStream): T { + return states.getOrPut(stream.descriptor) { persister.load(stream) } + } + + override suspend fun persistState(stream: DestinationStream) { + val state = + states[stream.descriptor] + ?: throw IllegalStateException("State not found for stream $stream") + persister.persist(stream, state) + } +} + +interface DestinationStatePersister { + suspend fun load(stream: DestinationStream): T + suspend fun persist(stream: DestinationStream, state: T) +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/FlushStrategy.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/FlushStrategy.kt index a6177ae8d88f..74738e076578 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/FlushStrategy.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/FlushStrategy.kt @@ -16,7 +16,7 @@ import java.util.concurrent.ConcurrentHashMap interface FlushStrategy { suspend fun shouldFlush( - stream: DestinationStream, + stream: DestinationStream.Descriptor, rangeRead: Range, bytesProcessed: Long ): Boolean @@ -40,7 +40,7 @@ class DefaultFlushStrategy( private val forceFlushIndexes = ConcurrentHashMap() override suspend fun shouldFlush( - stream: DestinationStream, + stream: DestinationStream.Descriptor, rangeRead: Range, bytesProcessed: Long ): Boolean { @@ -49,12 +49,11 @@ class DefaultFlushStrategy( } // Listen to the event stream for a new force flush index - val nextFlushIndex = eventQueue.poll()?.indexes?.get(stream.descriptor) + val nextFlushIndex = eventQueue.poll()?.indexes?.get(stream) // Always update the index if the new one is not null return when ( - val testIndex = - forceFlushIndexes.compute(stream.descriptor) { _, v -> nextFlushIndex ?: v } + val testIndex = forceFlushIndexes.compute(stream) { _, v -> nextFlushIndex ?: v } ) { null -> false else -> rangeRead.contains(testIndex) diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/MemoryManager.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/MemoryManager.kt deleted file mode 100644 index 99ed41d73cef..000000000000 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/MemoryManager.kt +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.cdk.load.state - -import io.airbyte.cdk.load.util.CloseableCoroutine -import io.micronaut.context.annotation.Secondary -import jakarta.inject.Singleton -import java.util.concurrent.atomic.AtomicBoolean -import java.util.concurrent.atomic.AtomicLong -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock - -/** - * Releasable reservation of memory. For large blocks (ie, from [MemoryManager.reserveRatio], - * provides a submanager that can be used to manage allocating the reservation). - */ -class Reserved( - private val memoryManager: MemoryManager, - val bytesReserved: Long, - val value: T, -) : CloseableCoroutine { - private var released = AtomicBoolean(false) - - suspend fun release() { - if (!released.compareAndSet(false, true)) { - return - } - memoryManager.release(bytesReserved) - } - - fun getReservationManager(): MemoryManager = MemoryManager(bytesReserved) - - fun replace(value: U): Reserved = Reserved(memoryManager, bytesReserved, value) - - override suspend fun close() { - release() - } -} - -/** - * Manages memory usage for the destination. - * - * TODO: Better initialization of available runtime memory? - * - * TODO: Some degree of logging/monitoring around how accurate we're actually being? - */ -@Singleton -class MemoryManager(availableMemoryProvider: AvailableMemoryProvider) { - // This is slightly awkward, but Micronaut only injects the primary constructor - constructor( - availableMemory: Long - ) : this( - object : AvailableMemoryProvider { - override val availableMemoryBytes: Long = availableMemory - } - ) - - private val totalMemoryBytes = availableMemoryProvider.availableMemoryBytes - private var usedMemoryBytes = AtomicLong(0L) - private val mutex = Mutex() - private val syncChannel = Channel(Channel.UNLIMITED) - - val remainingMemoryBytes: Long - get() = totalMemoryBytes - usedMemoryBytes.get() - - /* Attempt to reserve memory. If enough memory is not available, waits until it is, then reserves. */ - suspend fun reserveBlocking(memoryBytes: Long, reservedFor: T): Reserved { - if (memoryBytes > totalMemoryBytes) { - throw IllegalArgumentException( - "Requested ${memoryBytes}b memory exceeds ${totalMemoryBytes}b total" - ) - } - - mutex.withLock { - while (usedMemoryBytes.get() + memoryBytes > totalMemoryBytes) { - syncChannel.receive() - } - usedMemoryBytes.addAndGet(memoryBytes) - - return Reserved(this, memoryBytes, reservedFor) - } - } - - suspend fun reserveRatio(ratio: Double, reservedFor: T): Reserved { - val estimatedSize = (totalMemoryBytes.toDouble() * ratio).toLong() - return reserveBlocking(estimatedSize, reservedFor) - } - - suspend fun release(memoryBytes: Long) { - usedMemoryBytes.addAndGet(-memoryBytes) - syncChannel.send(Unit) - } -} - -interface AvailableMemoryProvider { - val availableMemoryBytes: Long -} - -@Singleton -@Secondary -class JavaRuntimeAvailableMemoryProvider : AvailableMemoryProvider { - override val availableMemoryBytes: Long = Runtime.getRuntime().maxMemory() -} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/ReservationManager.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/ReservationManager.kt new file mode 100644 index 000000000000..354dfadd123d --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/ReservationManager.kt @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.state + +import io.airbyte.cdk.load.util.CloseableCoroutine +import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.atomic.AtomicLong +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock + +/** Releasable reservation of memory. */ +class Reserved( + private val parentManager: ReservationManager? = null, + val bytesReserved: Long = 0, + val value: T, +) : CloseableCoroutine { + private var released = AtomicBoolean(false) + + suspend fun release() { + if (!released.compareAndSet(false, true)) { + return + } + parentManager?.release(bytesReserved) + } + + fun replace(value: U): Reserved = Reserved(parentManager, bytesReserved, value) + + override suspend fun close() { + release() + } +} + +/** + * Manages memory usage for the destination. + * + * TODO: Better initialization of available runtime memory? + * + * TODO: Some degree of logging/monitoring around how accurate we're actually being? + */ +class ReservationManager(val totalCapacityBytes: Long) { + + private var usedBytes = AtomicLong(0L) + private var updateChannel = MutableStateFlow(0L) + private val reserveLock = Mutex() + + val remainingCapacityBytes: Long + get() = totalCapacityBytes - usedBytes.get() + val totalBytesReserved: Long + get() = usedBytes.get() + + /* Attempt to reserve memory. If enough memory is not available, waits until it is, then reserves. */ + suspend fun reserve(bytes: Long, reservedFor: T): Reserved { + reserve(bytes) + + return Reserved(this, bytes, reservedFor) + } + + /* Attempt to reserve memory. If enough memory is not available, waits until it is, then reserves. */ + suspend fun reserve(bytes: Long) { + if (bytes > totalCapacityBytes) { + throw IllegalArgumentException( + "Requested ${bytes}b exceeds ${totalCapacityBytes}b total" + ) + } + + reserveLock.withLock { + while (usedBytes.get() + bytes > totalCapacityBytes) { + updateChannel.first() + } + usedBytes.addAndGet(bytes) + } + } + + suspend fun release(bytes: Long) { + updateChannel.value = usedBytes.addAndGet(-bytes) + } +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/StreamManager.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/StreamManager.kt index 80769f1e8cb1..b8a71842a676 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/StreamManager.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/StreamManager.kt @@ -20,13 +20,9 @@ import kotlinx.coroutines.CompletableDeferred sealed interface StreamResult -sealed interface StreamIncompleteResult : StreamResult +data class StreamProcessingFailed(val streamException: Exception) : StreamResult -data class StreamFailed(val streamException: Exception) : StreamIncompleteResult - -data class StreamKilled(val syncException: Exception) : StreamIncompleteResult - -data object StreamSucceeded : StreamResult +data object StreamProcessingSucceeded : StreamResult /** Manages the state of a single stream. */ interface StreamManager { @@ -38,13 +34,17 @@ interface StreamManager { fun recordCount(): Long /** - * Mark the end-of-stream and return the record count. Expect this exactly once. Expect no - * further `countRecordIn`, and expect that [markSucceeded] or [markFailed] or [markKilled] will - * alway occur after this. + * Mark the end-of-stream, set the end of stream variant (complete or incomplete) and return the + * record count. Expect this exactly once. Expect no further `countRecordIn`, and expect that + * [markProcessingSucceeded] will always occur after this, while [markProcessingFailed] can + * occur before or after. */ - fun markEndOfStream(): Long + fun markEndOfStream(receivedStreamCompleteMessage: Boolean): Long fun endOfStreamRead(): Boolean + /** Whether we received a stream complete message for the managed stream. */ + fun isComplete(): Boolean + /** * Mark a checkpoint in the stream and return the current index and the number of records since * the last one. @@ -72,22 +72,23 @@ interface StreamManager { */ fun areRecordsPersistedUntil(index: Long): Boolean - /** Mark the stream as closed. This should only be called after all records have been read. */ - fun markSucceeded() - /** - * Mark that the stream was killed due to failure elsewhere. Returns false if task was already - * complete. + * Indicates destination processing of the stream succeeded, regardless of complete/incomplete + * status. This should only be called after all records and end of stream messages have been + * read. */ - fun markKilled(causedBy: Exception): Boolean + fun markProcessingSucceeded() - /** Mark that the stream itself failed. Return false if task was already complete */ - fun markFailed(causedBy: Exception): Boolean + /** + * Indicates destination processing of the stream failed. Returns false if task was already + * complete + */ + fun markProcessingFailed(causedBy: Exception): Boolean /** Suspend until the stream completes, returning the result. */ suspend fun awaitStreamResult(): StreamResult - /** True if the stream has not yet been marked successful, failed, or killed. */ + /** True if the stream processing has not yet been marked as successful or failed. */ fun isActive(): Boolean } @@ -96,12 +97,16 @@ class DefaultStreamManager( ) : StreamManager { private val streamResult = CompletableDeferred() + data class CachedRanges(val state: Batch.State, val ranges: RangeSet) + private val cachedRangesById = ConcurrentHashMap() + private val log = KotlinLogging.logger {} private val recordCount = AtomicLong(0) private val lastCheckpoint = AtomicLong(0L) private val markedEndOfStream = AtomicBoolean(false) + private val receivedComplete = AtomicBoolean(false) private val rangesState: ConcurrentHashMap> = ConcurrentHashMap() @@ -121,10 +126,11 @@ class DefaultStreamManager( return recordCount.get() } - override fun markEndOfStream(): Long { + override fun markEndOfStream(receivedStreamCompleteMessage: Boolean): Long { if (markedEndOfStream.getAndSet(true)) { throw IllegalStateException("Stream is closed for reading") } + receivedComplete.getAndSet(receivedStreamCompleteMessage) return recordCount.get() } @@ -133,6 +139,10 @@ class DefaultStreamManager( return markedEndOfStream.get() } + override fun isComplete(): Boolean { + return receivedComplete.get() + } + override fun markCheckpoint(): Pair { val index = recordCount.get() val lastCheckpoint = lastCheckpoint.getAndSet(index) @@ -140,9 +150,96 @@ class DefaultStreamManager( } override fun updateBatchState(batch: BatchEnvelope) { - val stateRanges = - rangesState[batch.batch.state] - ?: throw IllegalArgumentException("Invalid batch state: ${batch.batch.state}") + rangesState[batch.batch.state] + ?: throw IllegalArgumentException("Invalid batch state: ${batch.batch.state}") + + val stateRangesToAdd = mutableListOf(batch.batch.state to batch.ranges) + + // If the batch is part of a group, update all ranges associated with its groupId + // to the most advanced state. Otherwise, just use the ranges provided. + val fromCache = + batch.batch.groupId?.let { groupId -> + val cachedRangesMaybe = cachedRangesById[groupId] + val cachedSet = cachedRangesMaybe?.ranges?.asRanges() ?: emptySet() + val newRanges = TreeRangeSet.create(cachedSet + batch.ranges.asRanges()).merged() + val newCachedRanges = CachedRanges(state = batch.batch.state, ranges = newRanges) + cachedRangesById[groupId] = newCachedRanges + if (cachedRangesMaybe != null && cachedRangesMaybe.state != batch.batch.state) { + stateRangesToAdd.add(batch.batch.state to newRanges) + stateRangesToAdd.add(cachedRangesMaybe.state to batch.ranges) + } + cachedRangesMaybe + } + + stateRangesToAdd.forEach { (stateToSet, rangesToUpdate) -> + when (stateToSet) { + Batch.State.COMPLETE -> { + // A COMPLETED state implies PERSISTED, so also mark PERSISTED. + addAndMarge(Batch.State.PERSISTED, rangesToUpdate) + addAndMarge(Batch.State.COMPLETE, rangesToUpdate) + } + else -> { + // For all other states, just mark the state. + addAndMarge(stateToSet, rangesToUpdate) + } + } + } + + log.info { + "Added ${batch.batch.state}->${batch.ranges} (groupId=${batch.batch.groupId}) to ${stream.descriptor.namespace}.${stream.descriptor.name}=>${rangesState[batch.batch.state]}" + } + log.debug { + val groupLineMaybe = + if (fromCache != null) { + "\n From group cache: ${fromCache.state}->${fromCache.ranges}" + } else { + "" + } + val stateRangesJoined = + stateRangesToAdd.joinToString(",") { "${it.first}->${it.second}" } + val readRange = TreeRangeSet.create(listOf(Range.closed(0, recordCount.get()))) + """ Added $stateRangesJoined to ${stream.descriptor.namespace}.${stream.descriptor.name}$groupLineMaybe + READ: $readRange (complete=${markedEndOfStream.get()}) + PROCESSED: ${rangesState[Batch.State.PROCESSED]} + STAGED: ${rangesState[Batch.State.STAGED]} + PERSISTED: ${rangesState[Batch.State.PERSISTED]} + COMPLETE: ${rangesState[Batch.State.COMPLETE]} + """.trimIndent() + } + } + + private fun RangeSet.merged(): RangeSet { + val newRanges = this.asRanges().toMutableSet() + this.asRanges().forEach { oldRange -> + newRanges + .find { newRange -> + oldRange.upperEndpoint() + 1 == newRange.lowerEndpoint() || + newRange.upperEndpoint() + 1 == oldRange.lowerEndpoint() + } + ?.let { newRange -> + newRanges.remove(oldRange) + newRanges.remove(newRange) + val lower = minOf(oldRange.lowerEndpoint(), newRange.lowerEndpoint()) + val upper = maxOf(oldRange.upperEndpoint(), newRange.upperEndpoint()) + newRanges.add(Range.closed(lower, upper)) + } + } + return TreeRangeSet.create(newRanges) + } + + private fun addAndMarge(state: Batch.State, ranges: RangeSet) { + rangesState[state] = + (rangesState[state]?.let { + it.addAll(ranges) + it + } + ?: ranges) + .merged() + } + + /** True if all records in `[0, index)` have reached the given state. */ + private fun isProcessingCompleteForState(index: Long, state: Batch.State): Boolean { + val completeRanges = rangesState[state]!! // Force the ranges to overlap at their endpoints, in order to work around // the behavior of `.encloses`, which otherwise would not consider adjacent ranges as @@ -150,17 +247,14 @@ class DefaultStreamManager( // This ensures that a state message received at eg, index 10 (after messages 0..9 have // been received), will pass `{'[0..5]','[6..9]'}.encloses('[0..10)')`. val expanded = - batch.ranges.asRanges().map { it.span(Range.singleton(it.upperEndpoint() + 1)) } - - stateRanges.addAll(expanded) - log.info { "Updated ranges for ${stream.descriptor}[${batch.batch.state}]: $stateRanges" } - } + completeRanges.asRanges().map { it.span(Range.singleton(it.upperEndpoint() + 1)) } + val expandedSet = TreeRangeSet.create(expanded) - /** True if all records in `[0, index)` have reached the given state. */ - private fun isProcessingCompleteForState(index: Long, state: Batch.State): Boolean { - val completeRanges = rangesState[state]!! + if (index == 0L && recordCount.get() == 0L) { + return true + } - return completeRanges.encloses(Range.closedOpen(0L, index)) + return expandedSet.encloses(Range.closedOpen(0L, index)) } override fun isBatchProcessingComplete(): Boolean { @@ -169,28 +263,27 @@ class DefaultStreamManager( return false } + /* A closed empty stream is always complete. */ + if (recordCount.get() == 0L) { + return true + } + return isProcessingCompleteForState(recordCount.get(), Batch.State.COMPLETE) } - /** TODO: Handle conflating PERSISTED w/ COMPLETE upstream, to allow for overlap? */ override fun areRecordsPersistedUntil(index: Long): Boolean { - return isProcessingCompleteForState(index, Batch.State.PERSISTED) || - isProcessingCompleteForState(index, Batch.State.COMPLETE) // complete => persisted + return isProcessingCompleteForState(index, Batch.State.PERSISTED) } - override fun markSucceeded() { + override fun markProcessingSucceeded() { if (!markedEndOfStream.get()) { throw IllegalStateException("Stream is not closed for reading") } - streamResult.complete(StreamSucceeded) - } - - override fun markKilled(causedBy: Exception): Boolean { - return streamResult.complete(StreamKilled(causedBy)) + streamResult.complete(StreamProcessingSucceeded) } - override fun markFailed(causedBy: Exception): Boolean { - return streamResult.complete(StreamFailed(causedBy)) + override fun markProcessingFailed(causedBy: Exception): Boolean { + return streamResult.complete(StreamProcessingFailed(causedBy)) } override suspend fun awaitStreamResult(): StreamResult { diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/SyncManager.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/SyncManager.kt index 351c6697fa85..eeefe4d21aad 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/SyncManager.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/SyncManager.kt @@ -14,36 +14,47 @@ import jakarta.inject.Singleton import java.util.concurrent.ConcurrentHashMap import kotlinx.coroutines.CompletableDeferred -sealed interface SyncResult +sealed interface DestinationResult -data object SyncSuccess : SyncResult +data object DestinationSuccess : DestinationResult -data class SyncFailure( - val syncFailure: Exception, +data class DestinationFailure( + val cause: Exception, val streamResults: Map -) : SyncResult +) : DestinationResult /** Manages the state of all streams in the destination. */ interface SyncManager { /** Get the manager for the given stream. Throws an exception if the stream is not found. */ fun getStreamManager(stream: DestinationStream.Descriptor): StreamManager - fun registerStartedStreamLoader(streamLoader: StreamLoader) + fun registerStartedStreamLoader( + streamDescriptor: DestinationStream.Descriptor, + streamLoaderResult: Result + ) suspend fun getOrAwaitStreamLoader(stream: DestinationStream.Descriptor): StreamLoader suspend fun getStreamLoaderOrNull(stream: DestinationStream.Descriptor): StreamLoader? - /** Suspend until all streams are complete. Returns false if any stream was failed/killed. */ - suspend fun awaitAllStreamsCompletedSuccessfully(): Boolean + /** + * Suspend until all streams are processed successfully. Returns false if processing failed for + * any stream. + */ + suspend fun awaitAllStreamsProcessedSuccessfully(): Boolean suspend fun markInputConsumed() suspend fun markCheckpointsProcessed() - suspend fun markFailed(causedBy: Exception): SyncFailure - suspend fun markSucceeded() + suspend fun markDestinationFailed(causedBy: Exception): DestinationFailure + suspend fun markDestinationSucceeded() + + /** + * Whether we received stream complete messages for all streams in the catalog from upstream. + */ + suspend fun allStreamsComplete(): Boolean fun isActive(): Boolean - suspend fun awaitInputProcessingComplete(): Unit - suspend fun awaitSyncResult(): SyncResult + suspend fun awaitInputProcessingComplete() + suspend fun awaitDestinationResult(): DestinationResult } @SuppressFBWarnings( @@ -53,9 +64,9 @@ interface SyncManager { class DefaultSyncManager( private val streamManagers: ConcurrentHashMap ) : SyncManager { - private val syncResult = CompletableDeferred() + private val destinationResult = CompletableDeferred() private val streamLoaders = - ConcurrentHashMap>() + ConcurrentHashMap>>() private val inputConsumed = CompletableDeferred() private val checkpointsProcessed = CompletableDeferred() @@ -63,51 +74,59 @@ class DefaultSyncManager( return streamManagers[stream] ?: throw IllegalArgumentException("Stream not found: $stream") } - override fun registerStartedStreamLoader(streamLoader: StreamLoader) { + override fun registerStartedStreamLoader( + streamDescriptor: DestinationStream.Descriptor, + streamLoaderResult: Result + ) { streamLoaders - .getOrPut(streamLoader.stream.descriptor) { CompletableDeferred() } - .complete(streamLoader) + .getOrPut(streamDescriptor) { CompletableDeferred() } + .complete(streamLoaderResult) } override suspend fun getOrAwaitStreamLoader( stream: DestinationStream.Descriptor ): StreamLoader { - return streamLoaders.getOrPut(stream) { CompletableDeferred() }.await() + return streamLoaders.getOrPut(stream) { CompletableDeferred() }.await().getOrThrow() } override suspend fun getStreamLoaderOrNull( stream: DestinationStream.Descriptor ): StreamLoader? { - val completable = streamLoaders[stream] - return completable?.let { if (it.isCompleted) it.await() else null } + return streamLoaders[stream]?.await()?.getOrNull() } - override suspend fun awaitAllStreamsCompletedSuccessfully(): Boolean { - return streamManagers.all { (_, manager) -> manager.awaitStreamResult() is StreamSucceeded } + override suspend fun awaitAllStreamsProcessedSuccessfully(): Boolean { + return streamManagers.all { (_, manager) -> + manager.awaitStreamResult() is StreamProcessingSucceeded + } } - override suspend fun markFailed(causedBy: Exception): SyncFailure { + override suspend fun markDestinationFailed(causedBy: Exception): DestinationFailure { val result = - SyncFailure(causedBy, streamManagers.mapValues { it.value.awaitStreamResult() }) - syncResult.complete(result) + DestinationFailure(causedBy, streamManagers.mapValues { it.value.awaitStreamResult() }) + destinationResult.complete(result) return result } - override suspend fun markSucceeded() { + override suspend fun markDestinationSucceeded() { if (streamManagers.values.any { it.isActive() }) { throw IllegalStateException( "Cannot mark sync as succeeded until all streams are complete" ) } - syncResult.complete(SyncSuccess) + destinationResult.complete(DestinationSuccess) + } + + override suspend fun allStreamsComplete(): Boolean { + return streamManagers.all { it.value.isComplete() } } override fun isActive(): Boolean { - return syncResult.isActive + return destinationResult.isActive } - override suspend fun awaitSyncResult(): SyncResult { - return syncResult.await() + override suspend fun awaitDestinationResult(): DestinationResult { + return destinationResult.await() } override suspend fun awaitInputProcessingComplete() { diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/TimeWindowTrigger.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/TimeWindowTrigger.kt new file mode 100644 index 000000000000..4e3f86f78b6f --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/state/TimeWindowTrigger.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.state + +import java.time.Clock + +/* + * Simple time-windowing strategy for bucketing partial aggregates. + * + * Works off time relative to the injected @param clock. Generally this is the processing time domain. + */ +data class TimeWindowTrigger( + private val clock: Clock, + private val windowWidthMs: Long, +) { + var openedAtMs: Long? = null + private set + + /* + * Sets window open timestamp for computing completeness. Idempotent. Mutative. + */ + fun open(): Long { + if (openedAtMs == null) { + openedAtMs = clock.millis() + } + return openedAtMs!! + } + + /* + * Returns whether window is complete relative to configured @param windowWidthMs. Non-mutative. + */ + fun isComplete(): Boolean { + return openedAtMs?.let { ts -> (clock.millis() - ts) >= windowWidthMs } ?: false + } +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/DestinationTaskExceptionHandler.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/DestinationTaskExceptionHandler.kt deleted file mode 100644 index f2063ae47308..000000000000 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/DestinationTaskExceptionHandler.kt +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.cdk.load.task - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings -import io.airbyte.cdk.load.command.DestinationCatalog -import io.airbyte.cdk.load.command.DestinationStream -import io.airbyte.cdk.load.state.StreamSucceeded -import io.airbyte.cdk.load.state.SyncManager -import io.airbyte.cdk.load.state.SyncSuccess -import io.airbyte.cdk.load.task.implementor.FailStreamTaskFactory -import io.airbyte.cdk.load.task.implementor.FailSyncTaskFactory -import io.airbyte.cdk.load.util.setOnce -import io.github.oshai.kotlinlogging.KotlinLogging -import io.micronaut.context.annotation.Secondary -import jakarta.inject.Singleton -import java.util.concurrent.atomic.AtomicBoolean -import java.util.concurrent.atomic.AtomicReference -import kotlinx.coroutines.CancellationException - -/** - * The level at which a task operates: - * - SyncTask: global across all streams - * - StreamTask: affined to a single stream - */ -sealed interface LeveledTask : Task - -interface SyncLevel : LeveledTask - -interface StreamLevel : LeveledTask { - val stream: DestinationStream -} - -interface DestinationTaskExceptionHandler : TaskExceptionHandler { - suspend fun handleSyncFailure(e: Exception) - suspend fun handleStreamFailure(stream: DestinationStream, e: Exception) - suspend fun handleSyncFailed() -} - -interface WrappedTask : Task { - val innerTask: T -} - -/** - * The exception handler takes over the workflow in the event of an exception. Its contract is - * * provide a wrapper that directs exceptions to the correct handler (by task type) - * * close the task runner when the cleanup workflow is complete - * - * Handling works as follows: - * * a failure in a sync-level task (setup/teardown) triggers a fail sync task - * * a failure in a stream task triggers a fails stream task THEN a fail sync task - * * the wrappers will skip tasks if the sync/stream has already failed - */ -@SuppressFBWarnings("NP_NONNULL_PARAM_VIOLATION", justification = "Kotlin async continuation") -@Singleton -@Secondary -class DefaultDestinationTaskExceptionHandler( - private val taskScopeProvider: TaskScopeProvider>, - private val catalog: DestinationCatalog, - private val syncManager: SyncManager, - private val failStreamTaskFactory: FailStreamTaskFactory, - private val failSyncTaskFactory: FailSyncTaskFactory, -) : DestinationTaskExceptionHandler> where -T : LeveledTask, -T : ScopedTask { - val log = KotlinLogging.logger {} - - val onException = AtomicReference(suspend {}) - private val failSyncTaskEnqueued = AtomicBoolean(false) - - inner class SyncTaskWrapper( - private val syncManager: SyncManager, - override val innerTask: ScopedTask, - ) : WrappedTask { - override suspend fun execute() { - if (!syncManager.isActive()) { - val result = syncManager.awaitSyncResult() - if (result is SyncSuccess) { - throw IllegalStateException( - "Task $innerTask run after sync has succeeded. This should not happen." - ) - } - log.info { "Sync task $innerTask skipped because sync has already failed." } - return - } - - try { - innerTask.execute() - } catch (e: CancellationException) { - log.warn { "Sync task $innerTask was cancelled." } - throw e - } catch (e: Exception) { - log.error { "Caught exception in sync task $innerTask: $e" } - handleSyncFailure(e) - } - } - - override fun toString(): String { - return "SyncTaskWrapper(innerTask=$innerTask)" - } - } - - inner class StreamTaskWrapper( - private val stream: DestinationStream, - private val syncManager: SyncManager, - override val innerTask: ScopedTask, - ) : WrappedTask { - override suspend fun execute() { - // Stop dispatching tasks if the stream has been killed by a failure elsewhere. - // Specifically fail if the stream was marked succeeded: we should not be in this state. - val streamManager = syncManager.getStreamManager(stream.descriptor) - if (!streamManager.isActive()) { - val result = streamManager.awaitStreamResult() - if (result is StreamSucceeded) { - throw IllegalStateException( - "Task $innerTask run after its stream ${stream.descriptor} has succeeded. This should not happen." - ) - } - log.info { "Stream task $innerTask skipped because stream has already failed." } - return - } - - try { - innerTask.execute() - } catch (e: CancellationException) { - log.warn { "Stream task $innerTask was cancelled." } - throw e - } catch (e: Exception) { - log.error { "Caught exception in sync task $innerTask: $e" } - handleStreamFailure(stream, e) - } - } - - override fun toString(): String { - return "StreamTaskWrapper(innerTask=$innerTask)" - } - } - - inner class NoHandlingWrapper( - override val innerTask: ScopedTask, - ) : WrappedTask { - override suspend fun execute() { - innerTask.execute() - } - - override fun toString(): String { - return "NoHandlingWrapper(innerTask=$innerTask)" - } - } - - override suspend fun setCallback(callback: suspend () -> Unit) { - onException.set(callback) - } - - override suspend fun withExceptionHandling(task: T): WrappedTask { - return when (task) { - is SyncLevel -> SyncTaskWrapper(syncManager, task) - is StreamLevel -> StreamTaskWrapper(task.stream, syncManager, task) - else -> throw IllegalArgumentException("Task without level: $task") - } - } - - override suspend fun handleSyncFailure(e: Exception) { - log.error { "Sync failed: $e: killing remaining streams" } - catalog.streams.forEach { - val task = failStreamTaskFactory.make(this, e, it, kill = true) - taskScopeProvider.launch(NoHandlingWrapper(task)) - } - if (failSyncTaskEnqueued.setOnce()) { - val failSyncTask = failSyncTaskFactory.make(this, e) - taskScopeProvider.launch(NoHandlingWrapper(failSyncTask)) - } else { - log.info { "Sync fail task already launched, not triggering a second one" } - } - } - - override suspend fun handleStreamFailure(stream: DestinationStream, e: Exception) { - log.error { "Caught failure in stream task: $e for ${stream.descriptor}, failing stream" } - val failStreamTask = failStreamTaskFactory.make(this, e, stream, kill = false) - taskScopeProvider.launch(NoHandlingWrapper(failStreamTask)) - } - - override suspend fun handleSyncFailed() { - onException.get().invoke() - } -} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/DestinationTaskLauncher.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/DestinationTaskLauncher.kt index f82fc6368914..eba1ea311fb0 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/DestinationTaskLauncher.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/DestinationTaskLauncher.kt @@ -6,38 +6,54 @@ package io.airbyte.cdk.load.task import edu.umd.cs.findbugs.annotations.SuppressFBWarnings import io.airbyte.cdk.load.command.DestinationCatalog +import io.airbyte.cdk.load.command.DestinationConfiguration import io.airbyte.cdk.load.command.DestinationStream -import io.airbyte.cdk.load.message.Batch import io.airbyte.cdk.load.message.BatchEnvelope +import io.airbyte.cdk.load.message.CheckpointMessageWrapped +import io.airbyte.cdk.load.message.DestinationStreamEvent +import io.airbyte.cdk.load.message.MessageQueue +import io.airbyte.cdk.load.message.MessageQueueSupplier +import io.airbyte.cdk.load.message.QueueWriter +import io.airbyte.cdk.load.state.Reserved import io.airbyte.cdk.load.state.SyncManager import io.airbyte.cdk.load.task.implementor.CloseStreamTaskFactory +import io.airbyte.cdk.load.task.implementor.FailStreamTaskFactory +import io.airbyte.cdk.load.task.implementor.FailSyncTaskFactory +import io.airbyte.cdk.load.task.implementor.FileTransferQueueMessage import io.airbyte.cdk.load.task.implementor.OpenStreamTaskFactory import io.airbyte.cdk.load.task.implementor.ProcessBatchTaskFactory +import io.airbyte.cdk.load.task.implementor.ProcessFileTaskFactory import io.airbyte.cdk.load.task.implementor.ProcessRecordsTaskFactory import io.airbyte.cdk.load.task.implementor.SetupTaskFactory import io.airbyte.cdk.load.task.implementor.TeardownTaskFactory import io.airbyte.cdk.load.task.internal.FlushCheckpointsTaskFactory -import io.airbyte.cdk.load.task.internal.InputConsumerTask +import io.airbyte.cdk.load.task.internal.FlushTickTask +import io.airbyte.cdk.load.task.internal.InputConsumerTaskFactory +import io.airbyte.cdk.load.task.internal.ReservingDeserializingInputFlow import io.airbyte.cdk.load.task.internal.SpillToDiskTaskFactory -import io.airbyte.cdk.load.task.internal.SpilledRawMessagesLocalFile import io.airbyte.cdk.load.task.internal.TimedForcedCheckpointFlushTask import io.airbyte.cdk.load.task.internal.UpdateCheckpointsTask import io.airbyte.cdk.load.util.setOnce import io.github.oshai.kotlinlogging.KotlinLogging import io.micronaut.context.annotation.Secondary +import io.micronaut.context.annotation.Value +import jakarta.inject.Named import jakarta.inject.Singleton +import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicBoolean +import kotlinx.coroutines.CancellationException import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock interface DestinationTaskLauncher : TaskLauncher { suspend fun handleSetupComplete() - suspend fun handleStreamStarted(stream: DestinationStream) - suspend fun handleNewSpilledFile(stream: DestinationStream, file: SpilledRawMessagesLocalFile) - suspend fun handleNewBatch(stream: DestinationStream, wrapped: BatchEnvelope<*>) - suspend fun handleStreamClosed(stream: DestinationStream) - suspend fun handleTeardownComplete() + suspend fun handleStreamStarted(stream: DestinationStream.Descriptor) + suspend fun handleNewBatch(stream: DestinationStream.Descriptor, wrapped: BatchEnvelope<*>) + suspend fun handleStreamClosed(stream: DestinationStream.Descriptor) + suspend fun handleTeardownComplete(success: Boolean = true) + suspend fun handleException(e: Exception) + suspend fun handleFailStreamComplete(stream: DestinationStream.Descriptor, e: Exception) } /** @@ -79,27 +95,41 @@ interface DestinationTaskLauncher : TaskLauncher { class DefaultDestinationTaskLauncher( private val taskScopeProvider: TaskScopeProvider>, private val catalog: DestinationCatalog, + private val config: DestinationConfiguration, private val syncManager: SyncManager, // Internal Tasks - private val inputConsumerTask: InputConsumerTask, + private val inputConsumerTaskFactory: InputConsumerTaskFactory, private val spillToDiskTaskFactory: SpillToDiskTaskFactory, + private val flushTickTask: FlushTickTask, // Implementor Tasks private val setupTaskFactory: SetupTaskFactory, private val openStreamTaskFactory: OpenStreamTaskFactory, private val processRecordsTaskFactory: ProcessRecordsTaskFactory, + private val processFileTaskFactory: ProcessFileTaskFactory, private val processBatchTaskFactory: ProcessBatchTaskFactory, private val closeStreamTaskFactory: CloseStreamTaskFactory, private val teardownTaskFactory: TeardownTaskFactory, // Checkpoint Tasks private val flushCheckpointsTaskFactory: FlushCheckpointsTaskFactory, - private val timedFlushTask: TimedForcedCheckpointFlushTask, + private val timedCheckpointFlushTask: TimedForcedCheckpointFlushTask, private val updateCheckpointsTask: UpdateCheckpointsTask, // Exception handling - private val exceptionHandler: TaskExceptionHandler> + private val failStreamTaskFactory: FailStreamTaskFactory, + private val failSyncTaskFactory: FailSyncTaskFactory, + + // File transfer + @Value("\${airbyte.file-transfer.enabled}") private val fileTransferEnabled: Boolean, + + // Input Consumer requirements + private val inputFlow: ReservingDeserializingInputFlow, + private val recordQueueSupplier: + MessageQueueSupplier>, + private val checkpointQueue: QueueWriter>, + @Named("fileMessageQueue") private val fileTransferQueue: MessageQueue ) : DestinationTaskLauncher { private val log = KotlinLogging.logger {} @@ -107,16 +137,55 @@ class DefaultDestinationTaskLauncher( private val succeeded = Channel(Channel.UNLIMITED) private val teardownIsEnqueued = AtomicBoolean(false) + private val failSyncIsEnqueued = AtomicBoolean(false) - private suspend fun enqueue(task: LeveledTask) { - taskScopeProvider.launch(exceptionHandler.withExceptionHandling(task)) + private val closeStreamHasRun = ConcurrentHashMap() + + inner class TaskWrapper( + override val innerTask: ScopedTask, + ) : WrappedTask { + override suspend fun execute() { + try { + innerTask.execute() + } catch (e: CancellationException) { + log.info { "Task $innerTask was cancelled." } + throw e + } catch (e: Exception) { + log.error(e) { "Caught exception in task $innerTask" } + handleException(e) + } + } + + override fun toString(): String { + return "TaskWrapper($innerTask)" + } } - override suspend fun run() { - exceptionHandler.setCallback { succeeded.send(false) } + inner class NoopWrapper( + override val innerTask: ScopedTask, + ) : WrappedTask { + override suspend fun execute() { + innerTask.execute() + } + } + private suspend fun enqueue(task: ScopedTask, withExceptionHandling: Boolean = true) { + val wrapped = if (withExceptionHandling) TaskWrapper(task) else NoopWrapper(task) + taskScopeProvider.launch(wrapped) + } + + override suspend fun run() { // Start the input consumer ASAP log.info { "Starting input consumer task" } + val inputConsumerTask = + inputConsumerTaskFactory.make( + catalog = catalog, + inputFlow = inputFlow, + recordQueueSupplier = recordQueueSupplier, + checkpointQueue = checkpointQueue, + fileTransferQueue = fileTransferQueue, + destinationTaskLauncher = this, + ) enqueue(inputConsumerTask) // Launch the client interface setup task @@ -124,16 +193,46 @@ class DefaultDestinationTaskLauncher( val setupTask = setupTaskFactory.make(this) enqueue(setupTask) - // Start a spill-to-disk task for each record stream - catalog.streams.forEach { stream -> - log.info { "Starting spill-to-disk task for $stream" } - val spillTask = spillToDiskTaskFactory.make(this, stream) - enqueue(spillTask) + // TODO: pluggable file transfer + if (!fileTransferEnabled) { + // Start a spill-to-disk task for each record stream + catalog.streams.forEach { stream -> + log.info { "Starting spill-to-disk task for $stream" } + val spillTask = spillToDiskTaskFactory.make(this, stream.descriptor) + enqueue(spillTask) + } + + repeat(config.numProcessRecordsWorkers) { + log.info { "Launching process records task $it" } + val task = processRecordsTaskFactory.make(this) + enqueue(task) + } + + repeat(config.numProcessBatchWorkers) { + log.info { "Launching process batch task $it" } + val task = processBatchTaskFactory.make(this) + enqueue(task) + } + } else { + repeat(config.numProcessRecordsWorkers) { + log.info { "Launching process file task $it" } + enqueue(processFileTaskFactory.make(this)) + } + + repeat(config.numProcessBatchWorkersForFileTransfer) { + log.info { "Launching process batch task $it" } + val task = processBatchTaskFactory.make(this) + enqueue(task) + } } + // Start flush task + log.info { "Starting timed file aggregate flush task " } + enqueue(flushTickTask) + // Start the checkpoint management tasks - log.info { "Starting timed flush task" } - enqueue(timedFlushTask) + log.info { "Starting timed checkpoint flush task" } + enqueue(timedCheckpointFlushTask) log.info { "Starting checkpoint update task" } enqueue(updateCheckpointsTask) @@ -150,69 +249,52 @@ class DefaultDestinationTaskLauncher( override suspend fun handleSetupComplete() { catalog.streams.forEach { log.info { "Starting open stream task for $it" } - val openStreamTask = openStreamTaskFactory.make(this, it) - enqueue(openStreamTask) + val task = openStreamTaskFactory.make(this, it) + enqueue(task) } } /** Called when a stream is ready for loading. */ - override suspend fun handleStreamStarted(stream: DestinationStream) { + override suspend fun handleStreamStarted(stream: DestinationStream.Descriptor) { // Nothing to do because the SpillToDiskTask will trigger the next calls - log.info { "Stream ${stream.descriptor} successfully opened for writing." } - } - - /** Called for each new spilled file. */ - override suspend fun handleNewSpilledFile( - stream: DestinationStream, - file: SpilledRawMessagesLocalFile - ) { - log.info { "Starting process records task for ${stream.descriptor}, file $file" } - val task = processRecordsTaskFactory.make(this, stream, file) - enqueue(task) - if (!file.endOfStream) { - log.info { "End-of-stream not reached, restarting spill-to-disk task for $stream" } - val spillTask = spillToDiskTaskFactory.make(this, stream) - enqueue(spillTask) - } + log.info { "Stream $stream successfully opened for writing." } } /** * Called for each new batch. Enqueues processing for any incomplete batch, and enqueues closing * the stream if all batches are complete. */ - override suspend fun handleNewBatch(stream: DestinationStream, wrapped: BatchEnvelope<*>) { + override suspend fun handleNewBatch( + stream: DestinationStream.Descriptor, + wrapped: BatchEnvelope<*> + ) { batchUpdateLock.withLock { - val streamManager = syncManager.getStreamManager(stream.descriptor) + val streamManager = syncManager.getStreamManager(stream) streamManager.updateBatchState(wrapped) if (wrapped.batch.isPersisted()) { - enqueue(flushCheckpointsTaskFactory.make()) - } - - if (wrapped.batch.state != Batch.State.COMPLETE) { log.info { - "Batch not complete: Starting process batch task for ${stream.descriptor}, batch $wrapped" + "Batch $wrapped is persisted: Starting flush checkpoints task for $stream" } + enqueue(flushCheckpointsTaskFactory.make()) + } - val task = processBatchTaskFactory.make(this, stream, wrapped) - enqueue(task) - } else if (streamManager.isBatchProcessingComplete()) { - log.info { - "Batch $wrapped complete and batch processing complete: Starting close stream task for ${stream.descriptor}" + if (streamManager.isBatchProcessingComplete()) { + if (closeStreamHasRun.getOrPut(stream) { AtomicBoolean(false) }.setOnce()) { + log.info { "Batch processing complete: Starting close stream task for $stream" } + val task = closeStreamTaskFactory.make(this, stream) + enqueue(task) + } else { + log.info { "Close stream task has already run, skipping." } } - - val task = closeStreamTaskFactory.make(this, stream) - enqueue(task) } else { - log.info { - "Batch $wrapped complete, but batch processing not complete: nothing else to do." - } + log.info { "Batch processing not complete: nothing else to do." } } } } /** Called when a stream is closed. */ - override suspend fun handleStreamClosed(stream: DestinationStream) { + override suspend fun handleStreamClosed(stream: DestinationStream.Descriptor) { if (teardownIsEnqueued.setOnce()) { enqueue(teardownTaskFactory.make(this)) } else { @@ -220,8 +302,25 @@ class DefaultDestinationTaskLauncher( } } + override suspend fun handleException(e: Exception) { + catalog.streams + .map { failStreamTaskFactory.make(this, e, it.descriptor) } + .forEach { enqueue(it, withExceptionHandling = false) } + } + + override suspend fun handleFailStreamComplete( + stream: DestinationStream.Descriptor, + e: Exception + ) { + if (failSyncIsEnqueued.setOnce()) { + enqueue(failSyncTaskFactory.make(this, e)) + } else { + log.info { "Teardown task already enqueued, not enqueuing another one" } + } + } + /** Called exactly once when all streams are closed. */ - override suspend fun handleTeardownComplete() { - succeeded.send(true) + override suspend fun handleTeardownComplete(success: Boolean) { + succeeded.send(success) } } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/DestinationTaskScopeProvider.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/DestinationTaskScopeProvider.kt index 9c8965f1a29e..4478e39079ea 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/DestinationTaskScopeProvider.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/DestinationTaskScopeProvider.kt @@ -42,6 +42,16 @@ interface InternalScope : ScopedTask interface ImplementorScope : ScopedTask +/** + * Some tasks should be immediately cancelled upon any failure (for example, reading from stdin, the + * every-15-minutes flush). Those tasks should be placed into the fail-fast scope. + */ +interface KillableScope : ScopedTask + +interface WrappedTask : Task { + val innerTask: T +} + @Singleton @Secondary class DestinationTaskScopeProvider(config: DestinationConfiguration) : @@ -69,11 +79,14 @@ class DestinationTaskScopeProvider(config: DestinationConfiguration) : .asCoroutineDispatcher() ) + private val failFastScope = ControlScope("input", Job(), Dispatchers.IO) + override suspend fun launch(task: WrappedTask) { val scope = when (task.innerTask) { is InternalScope -> internalScope is ImplementorScope -> implementorScope + is KillableScope -> failFastScope } scope.scope.launch { var nJobs = scope.runningJobs.incrementAndGet() @@ -115,6 +128,8 @@ class DestinationTaskScopeProvider(config: DestinationConfiguration) : override suspend fun kill() { log.info { "Killing task scopes" } + // Terminate tasks which should be immediately terminated + failFastScope.job.cancel() // Give the implementor tasks a chance to fail gracefully withTimeoutOrNull(timeoutMs) { diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/CloseStreamTask.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/CloseStreamTask.kt index 8fcd18c16198..14a1688e7ad9 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/CloseStreamTask.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/CloseStreamTask.kt @@ -8,33 +8,36 @@ import io.airbyte.cdk.load.command.DestinationStream import io.airbyte.cdk.load.state.SyncManager import io.airbyte.cdk.load.task.DestinationTaskLauncher import io.airbyte.cdk.load.task.ImplementorScope -import io.airbyte.cdk.load.task.StreamLevel import io.airbyte.cdk.load.write.StreamLoader import io.micronaut.context.annotation.Secondary import jakarta.inject.Singleton -interface CloseStreamTask : StreamLevel, ImplementorScope +interface CloseStreamTask : ImplementorScope /** * Wraps @[StreamLoader.close] and marks the stream as closed in the stream manager. Also starts the - * teardown task. + * teardown task. Called after the end of stream message (complete OR incomplete) has been received + * and all record messages have been processed. */ class DefaultCloseStreamTask( private val syncManager: SyncManager, - override val stream: DestinationStream, + val streamDescriptor: DestinationStream.Descriptor, private val taskLauncher: DestinationTaskLauncher ) : CloseStreamTask { override suspend fun execute() { - val streamLoader = syncManager.getOrAwaitStreamLoader(stream.descriptor) + val streamLoader = syncManager.getOrAwaitStreamLoader(streamDescriptor) streamLoader.close() - syncManager.getStreamManager(stream.descriptor).markSucceeded() - taskLauncher.handleStreamClosed(streamLoader.stream) + syncManager.getStreamManager(streamDescriptor).markProcessingSucceeded() + taskLauncher.handleStreamClosed(streamLoader.stream.descriptor) } } interface CloseStreamTaskFactory { - fun make(taskLauncher: DestinationTaskLauncher, stream: DestinationStream): CloseStreamTask + fun make( + taskLauncher: DestinationTaskLauncher, + stream: DestinationStream.Descriptor + ): CloseStreamTask } @Singleton @@ -42,7 +45,7 @@ interface CloseStreamTaskFactory { class DefaultCloseStreamTaskFactory(private val syncManager: SyncManager) : CloseStreamTaskFactory { override fun make( taskLauncher: DestinationTaskLauncher, - stream: DestinationStream + stream: DestinationStream.Descriptor ): CloseStreamTask { return DefaultCloseStreamTask(syncManager, stream, taskLauncher) } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/FailStreamTask.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/FailStreamTask.kt index fdb84dded44a..9959a3286ab0 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/FailStreamTask.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/FailStreamTask.kt @@ -5,9 +5,10 @@ package io.airbyte.cdk.load.task.implementor import io.airbyte.cdk.load.command.DestinationStream -import io.airbyte.cdk.load.state.StreamIncompleteResult +import io.airbyte.cdk.load.state.StreamProcessingFailed +import io.airbyte.cdk.load.state.StreamProcessingSucceeded import io.airbyte.cdk.load.state.SyncManager -import io.airbyte.cdk.load.task.DestinationTaskExceptionHandler +import io.airbyte.cdk.load.task.DestinationTaskLauncher import io.airbyte.cdk.load.task.ImplementorScope import io.github.oshai.kotlinlogging.KotlinLogging import io.micronaut.context.annotation.Secondary @@ -16,58 +17,38 @@ import jakarta.inject.Singleton interface FailStreamTask : ImplementorScope /** - * FailStreamTask is a task that is executed when a stream fails. It is responsible for cleaning up - * resources and reporting the failure. + * FailStreamTask is a task that is executed when the processing of a stream fails in the + * destination. It is responsible for cleaning up resources and reporting the failure. */ class DefaultFailStreamTask( - private val exceptionHandler: DestinationTaskExceptionHandler<*, *>, + private val taskLauncher: DestinationTaskLauncher, private val exception: Exception, private val syncManager: SyncManager, - private val stream: DestinationStream, - private val kill: Boolean, + private val stream: DestinationStream.Descriptor, ) : FailStreamTask { val log = KotlinLogging.logger {} override suspend fun execute() { - val streamManager = syncManager.getStreamManager(stream.descriptor) - if (kill) { - if (!streamManager.markKilled(exception)) { - log.info { "Stream ${stream.descriptor} already complete, skipping kill." } - return + val streamManager = syncManager.getStreamManager(stream) + streamManager.markProcessingFailed(exception) + when (val streamResult = streamManager.awaitStreamResult()) { + is StreamProcessingSucceeded -> { + log.info { "Cannot fail stream $stream, which is already complete, doing nothing." } } - } else { - if (!streamManager.markFailed(exception)) { - throw IllegalStateException( - "Cannot fail stream ${stream.descriptor}, which is already complete." - ) + is StreamProcessingFailed -> { + syncManager.getStreamLoaderOrNull(stream)?.close(streamResult) + ?: log.warn { "StreamLoader not found for stream $stream, cannot call close." } } - // Stream failure implies sync failure - exceptionHandler.handleSyncFailure(exception) } - - val streamResult = streamManager.awaitStreamResult() - val incompleteResult = - if (streamResult is StreamIncompleteResult) { - streamResult - } else { - null - } - // TODO: Bit of smell here, suggests we should be fetching the StreamLoader - // lazily+unconditionally - // through the DestinationWriter (via an injected wrapper?) - syncManager.getStreamLoaderOrNull(stream.descriptor)?.close(incompleteResult) - ?: log.warn { - "StreamLoader not found for stream ${stream.descriptor}, cannot call close." - } + taskLauncher.handleFailStreamComplete(stream, exception) } } interface FailStreamTaskFactory { fun make( - exceptionHandler: DestinationTaskExceptionHandler<*, *>, + taskLauncher: DestinationTaskLauncher, exception: Exception, - stream: DestinationStream, - kill: Boolean, + stream: DestinationStream.Descriptor, ): FailStreamTask } @@ -75,11 +56,10 @@ interface FailStreamTaskFactory { @Secondary class DefaultFailStreamTaskFactory(private val syncManager: SyncManager) : FailStreamTaskFactory { override fun make( - exceptionHandler: DestinationTaskExceptionHandler<*, *>, + taskLauncher: DestinationTaskLauncher, exception: Exception, - stream: DestinationStream, - kill: Boolean, + stream: DestinationStream.Descriptor, ): FailStreamTask { - return DefaultFailStreamTask(exceptionHandler, exception, syncManager, stream, kill) + return DefaultFailStreamTask(taskLauncher, exception, syncManager, stream) } } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/FailSyncTask.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/FailSyncTask.kt index dd079f5f40f8..10f64ab9de0f 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/FailSyncTask.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/FailSyncTask.kt @@ -6,7 +6,7 @@ package io.airbyte.cdk.load.task.implementor import io.airbyte.cdk.load.state.CheckpointManager import io.airbyte.cdk.load.state.SyncManager -import io.airbyte.cdk.load.task.DestinationTaskExceptionHandler +import io.airbyte.cdk.load.task.DestinationTaskLauncher import io.airbyte.cdk.load.task.ImplementorScope import io.airbyte.cdk.load.write.DestinationWriter import io.github.oshai.kotlinlogging.KotlinLogging @@ -16,11 +16,12 @@ import jakarta.inject.Singleton interface FailSyncTask : ImplementorScope /** - * FailSyncTask is a task that is executed when a sync fails. It is responsible for cleaning up - * resources and reporting the failure. + * FailSyncTask is a task that is executed only when the destination itself fails during a sync. If + * the sync is failed by upstream (e.g. an incomplete stream message is received), we do not call + * this task. It is responsible for cleaning up resources and reporting the failure. */ class DefaultFailSyncTask( - private val exceptionHandler: DestinationTaskExceptionHandler<*, *>, + private val taskLauncher: DestinationTaskLauncher, private val destinationWriter: DestinationWriter, private val exception: Exception, private val syncManager: SyncManager, @@ -31,19 +32,15 @@ class DefaultFailSyncTask( override suspend fun execute() { // Ensure any remaining ready state gets captured: don't waste work! checkpointManager.flushReadyCheckpointMessages() - val result = syncManager.markFailed(exception) // awaits stream completion + val result = syncManager.markDestinationFailed(exception) // awaits stream completion log.info { "Calling teardown with failure result $result" } - exceptionHandler.handleSyncFailed() - // Do this cleanup last, after all the tasks have had a decent chance to finish. destinationWriter.teardown(result) + taskLauncher.handleTeardownComplete(success = false) } } interface FailSyncTaskFactory { - fun make( - exceptionHandler: DestinationTaskExceptionHandler<*, *>, - exception: Exception - ): FailSyncTask + fun make(taskLauncher: DestinationTaskLauncher, exception: Exception): FailSyncTask } @Singleton @@ -53,12 +50,9 @@ class DefaultFailSyncTaskFactory( private val checkpointManager: CheckpointManager<*, *>, private val destinationWriter: DestinationWriter ) : FailSyncTaskFactory { - override fun make( - exceptionHandler: DestinationTaskExceptionHandler<*, *>, - exception: Exception - ): FailSyncTask { + override fun make(taskLauncher: DestinationTaskLauncher, exception: Exception): FailSyncTask { return DefaultFailSyncTask( - exceptionHandler, + taskLauncher, destinationWriter, exception, syncManager, diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/OpenStreamTask.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/OpenStreamTask.kt index 4a65fefd19fc..80f8e99024c7 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/OpenStreamTask.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/OpenStreamTask.kt @@ -8,13 +8,12 @@ import io.airbyte.cdk.load.command.DestinationStream import io.airbyte.cdk.load.state.SyncManager import io.airbyte.cdk.load.task.DestinationTaskLauncher import io.airbyte.cdk.load.task.ImplementorScope -import io.airbyte.cdk.load.task.StreamLevel import io.airbyte.cdk.load.write.DestinationWriter import io.airbyte.cdk.load.write.StreamLoader import io.micronaut.context.annotation.Secondary import jakarta.inject.Singleton -interface OpenStreamTask : StreamLevel, ImplementorScope +interface OpenStreamTask : ImplementorScope /** * Wraps @[StreamLoader.start] and starts the spill-to-disk tasks. @@ -24,14 +23,19 @@ interface OpenStreamTask : StreamLevel, ImplementorScope class DefaultOpenStreamTask( private val destinationWriter: DestinationWriter, private val syncManager: SyncManager, - override val stream: DestinationStream, - private val taskLauncher: DestinationTaskLauncher + val streamDescriptor: DestinationStream.Descriptor, + private val taskLauncher: DestinationTaskLauncher, + private val stream: DestinationStream, ) : OpenStreamTask { override suspend fun execute() { val streamLoader = destinationWriter.createStreamLoader(stream) - streamLoader.start() - syncManager.registerStartedStreamLoader(streamLoader) - taskLauncher.handleStreamStarted(stream) + val result = runCatching { + streamLoader.start() + streamLoader + } + syncManager.registerStartedStreamLoader(stream.descriptor, result) + result.getOrThrow() // throw after registering the failure + taskLauncher.handleStreamStarted(streamDescriptor) } } @@ -49,6 +53,12 @@ class DefaultOpenStreamTaskFactory( taskLauncher: DestinationTaskLauncher, stream: DestinationStream ): OpenStreamTask { - return DefaultOpenStreamTask(destinationWriter, syncManager, stream, taskLauncher) + return DefaultOpenStreamTask( + destinationWriter, + syncManager, + stream.descriptor, + taskLauncher, + stream + ) } } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/ProcessBatchTask.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/ProcessBatchTask.kt index c884a1c3c72e..1d0e43d86242 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/ProcessBatchTask.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/ProcessBatchTask.kt @@ -4,50 +4,51 @@ package io.airbyte.cdk.load.task.implementor -import io.airbyte.cdk.load.command.DestinationStream import io.airbyte.cdk.load.message.BatchEnvelope +import io.airbyte.cdk.load.message.MultiProducerChannel import io.airbyte.cdk.load.state.SyncManager import io.airbyte.cdk.load.task.DestinationTaskLauncher -import io.airbyte.cdk.load.task.ImplementorScope -import io.airbyte.cdk.load.task.StreamLevel +import io.airbyte.cdk.load.task.KillableScope import io.airbyte.cdk.load.write.StreamLoader +import io.github.oshai.kotlinlogging.KotlinLogging import io.micronaut.context.annotation.Secondary +import jakarta.inject.Named import jakarta.inject.Singleton -interface ProcessBatchTask : StreamLevel, ImplementorScope +interface ProcessBatchTask : KillableScope /** Wraps @[StreamLoader.processBatch] and handles the resulting batch. */ class DefaultProcessBatchTask( private val syncManager: SyncManager, - private val batchEnvelope: BatchEnvelope<*>, - override val stream: DestinationStream, + private val batchQueue: MultiProducerChannel>, private val taskLauncher: DestinationTaskLauncher ) : ProcessBatchTask { + val log = KotlinLogging.logger {} override suspend fun execute() { - val streamLoader = syncManager.getOrAwaitStreamLoader(stream.descriptor) - val nextBatch = streamLoader.processBatch(batchEnvelope.batch) - val nextWrapped = batchEnvelope.withBatch(nextBatch) - taskLauncher.handleNewBatch(stream, nextWrapped) + batchQueue.consume().collect { batchEnvelope -> + val streamLoader = syncManager.getOrAwaitStreamLoader(batchEnvelope.streamDescriptor) + val nextBatch = streamLoader.processBatch(batchEnvelope.batch) + val nextWrapped = batchEnvelope.withBatch(nextBatch) + taskLauncher.handleNewBatch(nextWrapped.streamDescriptor, nextWrapped) + } } } interface ProcessBatchTaskFactory { fun make( taskLauncher: DestinationTaskLauncher, - stream: DestinationStream, - batchEnvelope: BatchEnvelope<*> ): ProcessBatchTask } @Singleton @Secondary -class DefaultProcessBatchTaskFactory(private val syncManager: SyncManager) : - ProcessBatchTaskFactory { +class DefaultProcessBatchTaskFactory( + private val syncManager: SyncManager, + @Named("batchQueue") private val batchQueue: MultiProducerChannel> +) : ProcessBatchTaskFactory { override fun make( taskLauncher: DestinationTaskLauncher, - stream: DestinationStream, - batchEnvelope: BatchEnvelope<*> ): ProcessBatchTask { - return DefaultProcessBatchTask(syncManager, batchEnvelope, stream, taskLauncher) + return DefaultProcessBatchTask(syncManager, batchQueue, taskLauncher) } } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/ProcessFileTask.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/ProcessFileTask.kt new file mode 100644 index 000000000000..0f2dcb0c3cf7 --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/ProcessFileTask.kt @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.task.implementor + +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.message.BatchEnvelope +import io.airbyte.cdk.load.message.DestinationFile +import io.airbyte.cdk.load.message.MessageQueue +import io.airbyte.cdk.load.message.MultiProducerChannel +import io.airbyte.cdk.load.state.SyncManager +import io.airbyte.cdk.load.task.DestinationTaskLauncher +import io.airbyte.cdk.load.task.ImplementorScope +import io.airbyte.cdk.load.util.use +import io.airbyte.cdk.load.write.FileBatchAccumulator +import io.github.oshai.kotlinlogging.KotlinLogging +import io.micronaut.context.annotation.Secondary +import jakarta.inject.Named +import jakarta.inject.Singleton +import java.util.concurrent.ConcurrentHashMap + +interface ProcessFileTask : ImplementorScope + +class DefaultProcessFileTask( + private val syncManager: SyncManager, + private val taskLauncher: DestinationTaskLauncher, + private val inputQueue: MessageQueue, + private val outputQueue: MultiProducerChannel>, +) : ProcessFileTask { + val log = KotlinLogging.logger {} + private val accumulators = + ConcurrentHashMap() + + override suspend fun execute() { + outputQueue.use { + inputQueue.consume().collect { (streamDescriptor, file, index) -> + val streamLoader = syncManager.getOrAwaitStreamLoader(streamDescriptor) + + val acc = + accumulators.getOrPut(streamDescriptor) { + streamLoader.createFileBatchAccumulator(outputQueue) + } + + acc.processFilePart(file, index) + } + } + } +} + +interface ProcessFileTaskFactory { + fun make( + taskLauncher: DestinationTaskLauncher, + ): ProcessFileTask +} + +@Singleton +@Secondary +class DefaultFileRecordsTaskFactory( + private val syncManager: SyncManager, + @Named("fileMessageQueue") + private val fileTransferQueue: MessageQueue, + @Named("batchQueue") private val outputQueue: MultiProducerChannel>, +) : ProcessFileTaskFactory { + override fun make( + taskLauncher: DestinationTaskLauncher, + ): ProcessFileTask { + return DefaultProcessFileTask(syncManager, taskLauncher, fileTransferQueue, outputQueue) + } +} + +data class FileTransferQueueMessage( + val streamDescriptor: DestinationStream.Descriptor, + val file: DestinationFile, + val index: Long, +) diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/ProcessRecordsTask.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/ProcessRecordsTask.kt index da911947cedd..7cc62d5c57a6 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/ProcessRecordsTask.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/ProcessRecordsTask.kt @@ -4,27 +4,37 @@ package io.airbyte.cdk.load.task.implementor +import com.google.common.collect.Range +import io.airbyte.cdk.load.command.DestinationConfiguration import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.message.Batch import io.airbyte.cdk.load.message.BatchEnvelope -import io.airbyte.cdk.load.message.Deserializer -import io.airbyte.cdk.load.message.DestinationMessage import io.airbyte.cdk.load.message.DestinationRecord +import io.airbyte.cdk.load.message.DestinationRecordAirbyteValue +import io.airbyte.cdk.load.message.DestinationRecordStreamComplete +import io.airbyte.cdk.load.message.DestinationRecordStreamIncomplete import io.airbyte.cdk.load.message.DestinationStreamAffinedMessage -import io.airbyte.cdk.load.message.DestinationStreamComplete -import io.airbyte.cdk.load.message.DestinationStreamIncomplete +import io.airbyte.cdk.load.message.MessageQueue +import io.airbyte.cdk.load.message.MultiProducerChannel +import io.airbyte.cdk.load.message.ProtocolMessageDeserializer +import io.airbyte.cdk.load.state.ReservationManager import io.airbyte.cdk.load.state.SyncManager import io.airbyte.cdk.load.task.DestinationTaskLauncher -import io.airbyte.cdk.load.task.ImplementorScope -import io.airbyte.cdk.load.task.StreamLevel +import io.airbyte.cdk.load.task.KillableScope import io.airbyte.cdk.load.task.internal.SpilledRawMessagesLocalFile import io.airbyte.cdk.load.util.lineSequence +import io.airbyte.cdk.load.util.use +import io.airbyte.cdk.load.write.BatchAccumulator import io.airbyte.cdk.load.write.StreamLoader import io.github.oshai.kotlinlogging.KotlinLogging import io.micronaut.context.annotation.Secondary +import jakarta.inject.Named import jakarta.inject.Singleton +import java.io.InputStream +import java.util.concurrent.ConcurrentHashMap import kotlin.io.path.inputStream -interface ProcessRecordsTask : StreamLevel, ImplementorScope +interface ProcessRecordsTask : KillableScope /** * Wraps @[StreamLoader.processRecords] and feeds it a lazy iterator over the last batch of spooled @@ -35,71 +45,130 @@ interface ProcessRecordsTask : StreamLevel, ImplementorScope * moved to the task launcher. */ class DefaultProcessRecordsTask( - override val stream: DestinationStream, + private val config: DestinationConfiguration, private val taskLauncher: DestinationTaskLauncher, - private val file: SpilledRawMessagesLocalFile, - private val deserializer: Deserializer, + private val deserializer: ProtocolMessageDeserializer, private val syncManager: SyncManager, + private val diskManager: ReservationManager, + private val inputQueue: MessageQueue, + private val outputQueue: MultiProducerChannel>, ) : ProcessRecordsTask { + private val log = KotlinLogging.logger {} + private val accumulators = ConcurrentHashMap() override suspend fun execute() { - val log = KotlinLogging.logger {} - - log.info { "Fetching stream loader for ${stream.descriptor}" } - val streamLoader = syncManager.getOrAwaitStreamLoader(stream.descriptor) - - log.info { "Processing records from $file" } - val batch = - try { - file.localFile.inputStream().use { inputStream -> - val records = - inputStream - .lineSequence() - .map { - when (val message = deserializer.deserialize(it)) { - is DestinationStreamAffinedMessage -> message - else -> - throw IllegalStateException( - "Expected record message, got ${message::class}" - ) + outputQueue.use { + inputQueue.consume().collect { (streamDescriptor, file) -> + log.info { "Fetching stream loader for $streamDescriptor" } + val streamLoader = syncManager.getOrAwaitStreamLoader(streamDescriptor) + val acc = + accumulators.getOrPut(streamDescriptor) { + streamLoader.createBatchAccumulator() + } + log.info { "Processing records from $file for stream $streamDescriptor" } + val batch = + try { + file.localFile.inputStream().use { + val records = + if (file.isEmpty) { + emptyList().listIterator() + } else { + it.toRecordIterator() } - } - .takeWhile { - it !is DestinationStreamComplete && - it !is DestinationStreamIncomplete - } - .map { it as DestinationRecord } - .iterator() - streamLoader.processRecords(records, file.totalSizeBytes) + val batch = + acc.processRecords(records, file.totalSizeBytes, file.endOfStream) + log.info { "Finished processing $file" } + batch + } + } finally { + log.info { "Processing completed, deleting $file" } + file.localFile.toFile().delete() + diskManager.release(file.totalSizeBytes) + } + handleBatch(streamDescriptor, batch, file.indexRange) + } + if (config.processEmptyFiles) { + // TODO: Get rid of the need to handle empty files please + log.info { "Forcing finalization of all accumulators." } + accumulators.forEach { (streamDescriptor, acc) -> + val finalBatch = + acc.processRecords( + emptyList().listIterator(), + 0, + true + ) + handleBatch(streamDescriptor, finalBatch, null) } - } finally { - log.info { "Processing completed, deleting $file" } - file.localFile.toFile().delete() } + } + } - val wrapped = BatchEnvelope(batch, file.indexRange) - taskLauncher.handleNewBatch(stream, wrapped) + private suspend fun handleBatch( + streamDescriptor: DestinationStream.Descriptor, + batch: Batch, + indexRange: Range? + ) { + val wrapped = BatchEnvelope(batch, indexRange, streamDescriptor) + taskLauncher.handleNewBatch(streamDescriptor, wrapped) + log.info { "Updating batch $wrapped for $streamDescriptor" } + if (batch.requiresProcessing) { + outputQueue.publish(wrapped) + } else { + log.info { "Batch $wrapped requires no further processing." } + } + } + + private fun InputStream.toRecordIterator(): Iterator { + return lineSequence() + .map { + when (val message = deserializer.deserialize(it)) { + is DestinationStreamAffinedMessage -> message + else -> + throw IllegalStateException( + "Expected record message, got ${message::class}" + ) + } + } + .takeWhile { + it !is DestinationRecordStreamComplete && it !is DestinationRecordStreamIncomplete + } + .map { (it as DestinationRecord).asRecordMarshaledToAirbyteValue() } + .iterator() } } interface ProcessRecordsTaskFactory { fun make( taskLauncher: DestinationTaskLauncher, - stream: DestinationStream, - file: SpilledRawMessagesLocalFile, ): ProcessRecordsTask } +data class FileAggregateMessage( + val streamDescriptor: DestinationStream.Descriptor, + val file: SpilledRawMessagesLocalFile +) + @Singleton @Secondary class DefaultProcessRecordsTaskFactory( - private val deserializer: Deserializer, + private val config: DestinationConfiguration, + private val deserializer: ProtocolMessageDeserializer, private val syncManager: SyncManager, + @Named("diskManager") private val diskManager: ReservationManager, + @Named("fileAggregateQueue") private val inputQueue: MessageQueue, + @Named("batchQueue") private val outputQueue: MultiProducerChannel>, ) : ProcessRecordsTaskFactory { + override fun make( taskLauncher: DestinationTaskLauncher, - stream: DestinationStream, - file: SpilledRawMessagesLocalFile, ): ProcessRecordsTask { - return DefaultProcessRecordsTask(stream, taskLauncher, file, deserializer, syncManager) + return DefaultProcessRecordsTask( + config, + taskLauncher, + deserializer, + syncManager, + diskManager, + inputQueue, + outputQueue, + ) } } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/SetupTask.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/SetupTask.kt index d55b4acb6c43..1bf807973d13 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/SetupTask.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/SetupTask.kt @@ -6,12 +6,11 @@ package io.airbyte.cdk.load.task.implementor import io.airbyte.cdk.load.task.DestinationTaskLauncher import io.airbyte.cdk.load.task.ImplementorScope -import io.airbyte.cdk.load.task.SyncLevel import io.airbyte.cdk.load.write.DestinationWriter import io.micronaut.context.annotation.Secondary import jakarta.inject.Singleton -interface SetupTask : SyncLevel, ImplementorScope +interface SetupTask : ImplementorScope /** * Wraps @[DestinationWriter.setup] and starts the open stream tasks. diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/TeardownTask.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/TeardownTask.kt index 04b9c5b2182d..64dada897c6b 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/TeardownTask.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/implementor/TeardownTask.kt @@ -8,13 +8,12 @@ import io.airbyte.cdk.load.state.CheckpointManager import io.airbyte.cdk.load.state.SyncManager import io.airbyte.cdk.load.task.DestinationTaskLauncher import io.airbyte.cdk.load.task.ImplementorScope -import io.airbyte.cdk.load.task.SyncLevel import io.airbyte.cdk.load.write.DestinationWriter import io.github.oshai.kotlinlogging.KotlinLogging import io.micronaut.context.annotation.Secondary import jakarta.inject.Singleton -interface TeardownTask : SyncLevel, ImplementorScope +interface TeardownTask : ImplementorScope /** * Wraps @[DestinationWriter.teardown] and stops the task launcher. @@ -31,18 +30,18 @@ class DefaultTeardownTask( override suspend fun execute() { syncManager.awaitInputProcessingComplete() - checkpointManager.awaitAllCheckpointsFlushed() - log.info { "Teardown task awaiting stream completion" } - if (!syncManager.awaitAllStreamsCompletedSuccessfully()) { - log.info { "Streams failed to complete successfully, doing nothing." } + log.info { "Teardown task awaiting stream processing completion" } + if (!syncManager.awaitAllStreamsProcessedSuccessfully()) { + log.info { "Streams failed to be processed successfully, doing nothing." } return } + checkpointManager.awaitAllCheckpointsFlushed() log.info { "Starting teardown task" } destination.teardown() log.info { "Teardown task complete, marking sync succeeded." } - syncManager.markSucceeded() + syncManager.markDestinationSucceeded() taskLauncher.handleTeardownComplete() } } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/FlushCheckpointsTask.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/FlushCheckpointsTask.kt index 251416da46e2..37901ecb9fe6 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/FlushCheckpointsTask.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/FlushCheckpointsTask.kt @@ -6,11 +6,10 @@ package io.airbyte.cdk.load.task.internal import io.airbyte.cdk.load.state.CheckpointManager import io.airbyte.cdk.load.task.InternalScope -import io.airbyte.cdk.load.task.SyncLevel import io.micronaut.context.annotation.Secondary import jakarta.inject.Singleton -interface FlushCheckpointsTask : SyncLevel, InternalScope +interface FlushCheckpointsTask : InternalScope class DefaultFlushCheckpointsTask( private val checkpointManager: CheckpointManager<*, *>, diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/FlushTickTask.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/FlushTickTask.kt new file mode 100644 index 000000000000..0e69940b4c17 --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/FlushTickTask.kt @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.task.internal + +import com.google.common.annotations.VisibleForTesting +import io.airbyte.cdk.load.command.DestinationCatalog +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.file.TimeProvider +import io.airbyte.cdk.load.message.DestinationStreamEvent +import io.airbyte.cdk.load.message.MessageQueueSupplier +import io.airbyte.cdk.load.message.StreamFlushEvent +import io.airbyte.cdk.load.state.Reserved +import io.airbyte.cdk.load.task.KillableScope +import io.github.oshai.kotlinlogging.KotlinLogging +import io.micronaut.context.annotation.Secondary +import io.micronaut.context.annotation.Value +import jakarta.inject.Singleton +import java.time.Clock +import kotlinx.coroutines.channels.ClosedSendChannelException + +@Singleton +@Secondary +class FlushTickTask( + @Value("\${airbyte.flush.rate-ms}") private val tickIntervalMs: Long, + private val clock: Clock, + private val coroutineTimeUtils: TimeProvider, + private val catalog: DestinationCatalog, + private val recordQueueSupplier: + MessageQueueSupplier>, +) : KillableScope { + private val log = KotlinLogging.logger {} + + override suspend fun execute() { + while (true) { + waitAndPublishFlushTick() + } + } + + @VisibleForTesting + suspend fun waitAndPublishFlushTick() { + coroutineTimeUtils.delay(tickIntervalMs) + + catalog.streams.forEach { + val queue = recordQueueSupplier.get(it.descriptor) + if (queue.isClosedForPublish()) { + return@forEach + } + try { + queue.publish(Reserved(value = StreamFlushEvent(clock.millis()))) + } catch (e: ClosedSendChannelException) { + log.info { "Attempted to flush closed queue for ${it.descriptor}. Ignoring..." } + } + } + } +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/InputConsumerTask.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/InputConsumerTask.kt index 268ae746e7a6..e084bcc4fe41 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/InputConsumerTask.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/InputConsumerTask.kt @@ -6,40 +6,42 @@ package io.airbyte.cdk.load.task.internal import edu.umd.cs.findbugs.annotations.SuppressFBWarnings import io.airbyte.cdk.load.command.DestinationCatalog -import io.airbyte.cdk.load.command.DestinationConfiguration import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.message.Batch +import io.airbyte.cdk.load.message.BatchEnvelope import io.airbyte.cdk.load.message.CheckpointMessage import io.airbyte.cdk.load.message.CheckpointMessageWrapped -import io.airbyte.cdk.load.message.Deserializer -import io.airbyte.cdk.load.message.DestinationMessage +import io.airbyte.cdk.load.message.DestinationFile +import io.airbyte.cdk.load.message.DestinationFileStreamComplete +import io.airbyte.cdk.load.message.DestinationFileStreamIncomplete import io.airbyte.cdk.load.message.DestinationRecord -import io.airbyte.cdk.load.message.DestinationRecordWrapped +import io.airbyte.cdk.load.message.DestinationRecordStreamComplete +import io.airbyte.cdk.load.message.DestinationRecordStreamIncomplete import io.airbyte.cdk.load.message.DestinationStreamAffinedMessage -import io.airbyte.cdk.load.message.DestinationStreamComplete -import io.airbyte.cdk.load.message.DestinationStreamIncomplete +import io.airbyte.cdk.load.message.DestinationStreamEvent import io.airbyte.cdk.load.message.GlobalCheckpoint import io.airbyte.cdk.load.message.GlobalCheckpointWrapped +import io.airbyte.cdk.load.message.MessageQueue import io.airbyte.cdk.load.message.MessageQueueSupplier import io.airbyte.cdk.load.message.QueueWriter +import io.airbyte.cdk.load.message.SimpleBatch import io.airbyte.cdk.load.message.StreamCheckpoint import io.airbyte.cdk.load.message.StreamCheckpointWrapped -import io.airbyte.cdk.load.message.StreamCompleteWrapped -import io.airbyte.cdk.load.message.StreamRecordWrapped +import io.airbyte.cdk.load.message.StreamEndEvent +import io.airbyte.cdk.load.message.StreamRecordEvent import io.airbyte.cdk.load.message.Undefined -import io.airbyte.cdk.load.state.MemoryManager import io.airbyte.cdk.load.state.Reserved import io.airbyte.cdk.load.state.SyncManager -import io.airbyte.cdk.load.task.InternalScope -import io.airbyte.cdk.load.task.SyncLevel +import io.airbyte.cdk.load.task.DestinationTaskLauncher +import io.airbyte.cdk.load.task.KillableScope +import io.airbyte.cdk.load.task.implementor.FileTransferQueueMessage import io.airbyte.cdk.load.util.use import io.github.oshai.kotlinlogging.KotlinLogging import io.micronaut.context.annotation.Secondary +import jakarta.inject.Named import jakarta.inject.Singleton -import java.io.InputStream -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.FlowCollector -interface InputConsumerTask : SyncLevel, InternalScope +interface InputConsumerTask : KillableScope /** * Routes @[DestinationStreamAffinedMessage]s by stream to the appropriate channel and @ @@ -55,11 +57,14 @@ interface InputConsumerTask : SyncLevel, InternalScope @Secondary class DefaultInputConsumerTask( private val catalog: DestinationCatalog, - private val inputFlow: SizedInputFlow>, + private val inputFlow: ReservingDeserializingInputFlow, private val recordQueueSupplier: - MessageQueueSupplier>, + MessageQueueSupplier>, private val checkpointQueue: QueueWriter>, private val syncManager: SyncManager, + private val destinationTaskLauncher: DestinationTaskLauncher, + @Named("fileMessageQueue") + private val fileTransferQueue: MessageQueue, ) : InputConsumerTask { private val log = KotlinLogging.logger {} @@ -69,25 +74,49 @@ class DefaultInputConsumerTask( ) { val stream = reserved.value.stream val manager = syncManager.getStreamManager(stream) - val queue = recordQueueSupplier.get(stream) + val recordQueue = recordQueueSupplier.get(stream) when (val message = reserved.value) { is DestinationRecord -> { val wrapped = - StreamRecordWrapped( + StreamRecordEvent( index = manager.countRecordIn(), sizeBytes = sizeBytes, - record = message + payload = message.asRecordSerialized() ) - queue.publish(reserved.replace(wrapped)) + recordQueue.publish(reserved.replace(wrapped)) } - is DestinationStreamComplete -> { + is DestinationRecordStreamComplete -> { reserved.release() // safe because multiple calls conflate - val wrapped = StreamCompleteWrapped(index = manager.markEndOfStream()) - queue.publish(reserved.replace(wrapped)) - queue.close() + val wrapped = StreamEndEvent(index = manager.markEndOfStream(true)) + log.info { "Read COMPLETE for stream $stream" } + recordQueue.publish(reserved.replace(wrapped)) + recordQueue.close() } - is DestinationStreamIncomplete -> - throw IllegalStateException("Stream $stream failed upstream, cannot continue.") + is DestinationRecordStreamIncomplete -> { + reserved.release() // safe because multiple calls conflate + val wrapped = StreamEndEvent(index = manager.markEndOfStream(false)) + log.info { "Read INCOMPLETE for stream $stream" } + recordQueue.publish(reserved.replace(wrapped)) + recordQueue.close() + } + is DestinationFile -> { + val index = manager.countRecordIn() + // destinationTaskLauncher.handleFile(stream, message, index) + fileTransferQueue.publish(FileTransferQueueMessage(stream, message, index)) + } + is DestinationFileStreamComplete -> { + reserved.release() // safe because multiple calls conflate + manager.markEndOfStream(true) + fileTransferQueue.close() + val envelope = + BatchEnvelope( + SimpleBatch(Batch.State.COMPLETE), + streamDescriptor = message.stream, + ) + destinationTaskLauncher.handleNewBatch(stream, envelope) + } + is DestinationFileStreamIncomplete -> + throw IllegalStateException("File stream $stream failed upstream, cannot continue.") } } @@ -167,48 +196,39 @@ class DefaultInputConsumerTask( } } -interface SizedInputFlow : Flow> - -abstract class ReservingDeserializingInputFlow : SizedInputFlow> { - val log = KotlinLogging.logger {} - - abstract val config: DestinationConfiguration - abstract val deserializer: Deserializer - abstract val memoryManager: MemoryManager - abstract val inputStream: InputStream - - override suspend fun collect(collector: FlowCollector>>) { - val reservation = memoryManager.reserveRatio(config.maxMessageQueueMemoryUsageRatio, this) - val reservationManager = reservation.getReservationManager() - - log.info { "Reserved ${reservation.bytesReserved/1024}mb memory for input processing" } - - reservation.use { _ -> - inputStream.bufferedReader().lineSequence().forEachIndexed { index, line -> - if (line.isEmpty()) { - return@forEachIndexed - } - - val lineSize = line.length.toLong() - val estimatedSize = lineSize * config.estimatedRecordMemoryOverheadRatio - val reserved = reservationManager.reserveBlocking(estimatedSize.toLong(), line) - val message = deserializer.deserialize(line) - collector.emit(Pair(lineSize, reserved.replace(message))) - - if (index % 10_000 == 0) { - log.info { "Processed $index lines" } - } - } - } - - log.info { "Finished processing input" } - } +interface InputConsumerTaskFactory { + fun make( + catalog: DestinationCatalog, + inputFlow: ReservingDeserializingInputFlow, + recordQueueSupplier: + MessageQueueSupplier>, + checkpointQueue: QueueWriter>, + destinationTaskLauncher: DestinationTaskLauncher, + fileTransferQueue: MessageQueue + ): InputConsumerTask } @Singleton -class DefaultInputFlow( - override val config: DestinationConfiguration, - override val deserializer: Deserializer, - override val memoryManager: MemoryManager, - override val inputStream: InputStream -) : ReservingDeserializingInputFlow() +@Secondary +class DefaultInputConsumerTaskFactory(private val syncManager: SyncManager) : + InputConsumerTaskFactory { + override fun make( + catalog: DestinationCatalog, + inputFlow: ReservingDeserializingInputFlow, + recordQueueSupplier: + MessageQueueSupplier>, + checkpointQueue: QueueWriter>, + destinationTaskLauncher: DestinationTaskLauncher, + fileTransferQueue: MessageQueue, + ): InputConsumerTask { + return DefaultInputConsumerTask( + catalog, + inputFlow, + recordQueueSupplier, + checkpointQueue, + syncManager, + destinationTaskLauncher, + fileTransferQueue, + ) + } +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/ReservingDeserializingInputFlow.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/ReservingDeserializingInputFlow.kt new file mode 100644 index 000000000000..c7dce658529a --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/ReservingDeserializingInputFlow.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.task.internal + +import io.airbyte.cdk.load.command.DestinationConfiguration +import io.airbyte.cdk.load.message.DestinationMessage +import io.airbyte.cdk.load.message.ProtocolMessageDeserializer +import io.airbyte.cdk.load.state.ReservationManager +import io.airbyte.cdk.load.state.Reserved +import io.github.oshai.kotlinlogging.KotlinLogging +import jakarta.inject.Named +import jakarta.inject.Singleton +import java.io.InputStream +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.FlowCollector + +@Singleton +class ReservingDeserializingInputFlow( + val config: DestinationConfiguration, + val deserializer: ProtocolMessageDeserializer, + @Named("memoryManager") val memoryManager: ReservationManager, + val inputStream: InputStream, +) : Flow>> { + val log = KotlinLogging.logger {} + + override suspend fun collect( + collector: FlowCollector>> + ) { + log.info { + "Reserved ${memoryManager.totalCapacityBytes/1024}mb memory for input processing" + } + + inputStream.bufferedReader().lineSequence().forEachIndexed { index, line -> + if (line.isEmpty()) { + return@forEachIndexed + } + + val lineSize = line.length.toLong() + val estimatedSize = lineSize * config.estimatedRecordMemoryOverheadRatio + val reserved = memoryManager.reserve(estimatedSize.toLong(), line) + val message = deserializer.deserialize(line) + collector.emit(Pair(lineSize, reserved.replace(message))) + + if (index % 10_000 == 0) { + log.info { "Processed $index lines" } + } + } + + log.info { "Finished processing input" } + } +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/SpillToDiskTask.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/SpillToDiskTask.kt index 12e6ea721b26..182bbe3d9fba 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/SpillToDiskTask.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/SpillToDiskTask.kt @@ -5,126 +5,268 @@ package io.airbyte.cdk.load.task.internal import com.google.common.collect.Range +import com.google.common.collect.TreeRangeSet +import io.airbyte.cdk.load.command.DestinationConfiguration import io.airbyte.cdk.load.command.DestinationStream import io.airbyte.cdk.load.file.SpillFileProvider -import io.airbyte.cdk.load.message.DestinationRecordWrapped +import io.airbyte.cdk.load.message.Batch +import io.airbyte.cdk.load.message.BatchEnvelope +import io.airbyte.cdk.load.message.DestinationStreamEvent import io.airbyte.cdk.load.message.MessageQueueSupplier +import io.airbyte.cdk.load.message.MultiProducerChannel import io.airbyte.cdk.load.message.QueueReader -import io.airbyte.cdk.load.message.StreamCompleteWrapped -import io.airbyte.cdk.load.message.StreamRecordWrapped +import io.airbyte.cdk.load.message.SimpleBatch +import io.airbyte.cdk.load.message.StreamEndEvent +import io.airbyte.cdk.load.message.StreamFlushEvent +import io.airbyte.cdk.load.message.StreamRecordEvent import io.airbyte.cdk.load.state.FlushStrategy +import io.airbyte.cdk.load.state.ReservationManager import io.airbyte.cdk.load.state.Reserved +import io.airbyte.cdk.load.state.TimeWindowTrigger import io.airbyte.cdk.load.task.DestinationTaskLauncher -import io.airbyte.cdk.load.task.InternalScope -import io.airbyte.cdk.load.task.StreamLevel -import io.airbyte.cdk.load.util.takeUntilInclusive +import io.airbyte.cdk.load.task.KillableScope +import io.airbyte.cdk.load.task.implementor.FileAggregateMessage import io.airbyte.cdk.load.util.use import io.airbyte.cdk.load.util.withNextAdjacentValue import io.airbyte.cdk.load.util.write import io.github.oshai.kotlinlogging.KotlinLogging +import io.micronaut.context.annotation.Value +import jakarta.inject.Named import jakarta.inject.Singleton +import java.io.OutputStream import java.nio.file.Path +import java.time.Clock +import kotlin.io.path.deleteExisting import kotlin.io.path.outputStream -import kotlinx.coroutines.flow.last -import kotlinx.coroutines.flow.runningFold +import kotlinx.coroutines.flow.fold -interface SpillToDiskTask : StreamLevel, InternalScope +interface SpillToDiskTask : KillableScope /** - * Reads records from the message queue and writes them to disk. This task is internal and is not - * exposed to the implementor. + * Reads records from the message queue and writes them to disk. Completes once the upstream + * inputQueue is closed. * * TODO: Allow for the record batch size to be supplied per-stream. (Needed?) */ class DefaultSpillToDiskTask( - private val spillFileProvider: SpillFileProvider, - private val queue: QueueReader>, + private val fileAccFactory: FileAccumulatorFactory, + private val inputQueue: QueueReader>, + private val outputQueue: MultiProducerChannel, private val flushStrategy: FlushStrategy, - override val stream: DestinationStream, - private val launcher: DestinationTaskLauncher, + val streamDescriptor: DestinationStream.Descriptor, + private val diskManager: ReservationManager, + private val taskLauncher: DestinationTaskLauncher, + private val processEmptyFiles: Boolean, ) : SpillToDiskTask { private val log = KotlinLogging.logger {} - data class ReadResult( - val range: Range? = null, - val sizeBytes: Long = 0, - val hasReadEndOfStream: Boolean = false, - val forceFlush: Boolean = false, - ) - override suspend fun execute() { - val tmpFile = spillFileProvider.createTempFile() - val result = - tmpFile.outputStream().use { outputStream -> - queue - .consume() - .runningFold(ReadResult()) { (range, sizeBytes, _), reserved -> - reserved.use { - when (val wrapped = it.value) { - is StreamRecordWrapped -> { - outputStream.write(wrapped.record.serialized) - outputStream.write("\n") - val nextRange = range.withNextAdjacentValue(wrapped.index) - val nextSize = sizeBytes + wrapped.sizeBytes - val forceFlush = - flushStrategy.shouldFlush(stream, nextRange, nextSize) - ReadResult(nextRange, nextSize, forceFlush = forceFlush) - } - is StreamCompleteWrapped -> { - val nextRange = range.withNextAdjacentValue(wrapped.index) - ReadResult(nextRange, sizeBytes, hasReadEndOfStream = true) - } - } - } + val initialAccumulator = fileAccFactory.make() + + outputQueue.use { + inputQueue.consume().fold(initialAccumulator) { acc, reserved -> + reserved.use { + when (val event = it.value) { + is StreamRecordEvent -> accRecordEvent(acc, event) + is StreamEndEvent -> accStreamEndEvent(acc, event) + is StreamFlushEvent -> accFlushEvent(acc) } - .takeUntilInclusive { it.hasReadEndOfStream || it.forceFlush } - .last() + } } + } + } - /** Handle the result */ - val (range, sizeBytes, endOfStream) = result + /** + * Handles accumulation of record events, triggering a publish downstream when the flush + * strategy returns true—generally when a size (MB) thresholds has been reached. + */ + private suspend fun accRecordEvent( + acc: FileAccumulator, + event: StreamRecordEvent, + ): FileAccumulator { + val (spillFile, outputStream, timeWindow, range, sizeBytes) = acc + // once we have received a record for the stream, consider the aggregate opened. + timeWindow.open() - log.info { "Finished writing $range records (${sizeBytes}b) to $tmpFile" } + // reserve enough room for the record + diskManager.reserve(event.sizeBytes) - // This could happen if the chunk only contained end-of-stream - if (range == null) { - // We read 0 records, do nothing - return + // write to disk + outputStream.write(event.payload.serialized) + outputStream.write("\n") + + // calculate whether we should flush + val rangeProcessed = range.withNextAdjacentValue(event.index) + val bytesProcessed = sizeBytes + event.sizeBytes + val shouldPublish = + flushStrategy.shouldFlush(streamDescriptor, rangeProcessed, bytesProcessed) + + if (!shouldPublish) { + return FileAccumulator( + spillFile, + outputStream, + timeWindow, + rangeProcessed, + bytesProcessed, + ) } - val file = SpilledRawMessagesLocalFile(tmpFile, sizeBytes, range, endOfStream) - launcher.handleNewSpilledFile(stream, file) + val file = SpilledRawMessagesLocalFile(spillFile, bytesProcessed, rangeProcessed) + publishFile(file) + outputStream.close() + return fileAccFactory.make() + } + + /** + * Handles accumulation of stream end events (complete or incomplete), triggering a final flush + * if the aggregate isn't empty. + */ + private suspend fun accStreamEndEvent( + acc: FileAccumulator, + event: StreamEndEvent, + ): FileAccumulator { + val (spillFile, outputStream, timeWindow, range, sizeBytes) = acc + if (sizeBytes == 0L && !processEmptyFiles) { + log.info { "Skipping empty file $spillFile" } + // Cleanup empty file + spillFile.deleteExisting() + // Directly send empty batch (skipping load step) to force bookkeeping; otherwise the + // sync will hang forever. (Usually this happens because the entire stream was empty.) + val empty = + BatchEnvelope( + SimpleBatch(Batch.State.COMPLETE), + TreeRangeSet.create(), + streamDescriptor + ) + taskLauncher.handleNewBatch(streamDescriptor, empty) + } else { + val nextRange = + if (sizeBytes == 0L) { + null + } else { + range.withNextAdjacentValue(event.index) + } + val file = + SpilledRawMessagesLocalFile( + spillFile, + sizeBytes, + nextRange, + endOfStream = true, + ) + + publishFile(file) + } + // this result should not be used as upstream will close the channel. + return FileAccumulator( + spillFile, + outputStream, + timeWindow, + range, + sizeBytes, + ) + } + + /** + * Handles accumulation of flush tick events, triggering publish when the window has been open + * for longer than the cutoff (default: 15 minutes) + */ + private suspend fun accFlushEvent( + acc: FileAccumulator, + ): FileAccumulator { + val (spillFile, outputStream, timeWindow, range, sizeBytes) = acc + val shouldPublish = timeWindow.isComplete() + if (!shouldPublish) { + return FileAccumulator(spillFile, outputStream, timeWindow, range, sizeBytes) + } + + log.info { + "Time window complete for $streamDescriptor@${timeWindow.openedAtMs} closing $spillFile of (${sizeBytes}b)" + } + + val file = + SpilledRawMessagesLocalFile( + spillFile, + sizeBytes, + range!!, + endOfStream = false, + ) + publishFile(file) + outputStream.close() + return fileAccFactory.make() + } + + private suspend fun publishFile(file: SpilledRawMessagesLocalFile) { + log.info { "Publishing file aggregate: $file for processing..." } + outputQueue.publish(FileAggregateMessage(streamDescriptor, file)) } } interface SpillToDiskTaskFactory { - fun make(taskLauncher: DestinationTaskLauncher, stream: DestinationStream): SpillToDiskTask + fun make( + taskLauncher: DestinationTaskLauncher, + stream: DestinationStream.Descriptor + ): SpillToDiskTask } @Singleton class DefaultSpillToDiskTaskFactory( - private val spillFileProvider: SpillFileProvider, + private val config: DestinationConfiguration, + private val fileAccFactory: FileAccumulatorFactory, private val queueSupplier: - MessageQueueSupplier>, + MessageQueueSupplier>, private val flushStrategy: FlushStrategy, + @Named("diskManager") private val diskManager: ReservationManager, + @Named("fileAggregateQueue") + private val fileAggregateQueue: MultiProducerChannel, ) : SpillToDiskTaskFactory { override fun make( taskLauncher: DestinationTaskLauncher, - stream: DestinationStream + stream: DestinationStream.Descriptor ): SpillToDiskTask { + return DefaultSpillToDiskTask( - spillFileProvider, - queueSupplier.get(stream.descriptor), + fileAccFactory, + queueSupplier.get(stream), + fileAggregateQueue, flushStrategy, stream, + diskManager, taskLauncher, + config.processEmptyFiles, + ) + } +} + +@Singleton +class FileAccumulatorFactory( + @Value("\${airbyte.flush.window-ms}") private val windowWidthMs: Long, + private val spillFileProvider: SpillFileProvider, + private val clock: Clock, +) { + fun make(): FileAccumulator { + val file = spillFileProvider.createTempFile() + return FileAccumulator( + file, + file.outputStream(), + TimeWindowTrigger(clock, windowWidthMs), ) } } +data class FileAccumulator( + val spillFile: Path, + val spillFileOutputStream: OutputStream, + val timeWindow: TimeWindowTrigger, + val range: Range? = null, + val sizeBytes: Long = 0, +) + data class SpilledRawMessagesLocalFile( val localFile: Path, val totalSizeBytes: Long, - val indexRange: Range, + val indexRange: Range?, val endOfStream: Boolean = false -) +) { + val isEmpty + get() = totalSizeBytes == 0L +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/TimedForcedCheckpointFlushTask.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/TimedForcedCheckpointFlushTask.kt index ff3053c80f4e..92aaf8b12beb 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/TimedForcedCheckpointFlushTask.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/TimedForcedCheckpointFlushTask.kt @@ -10,14 +10,13 @@ import io.airbyte.cdk.load.file.TimeProvider import io.airbyte.cdk.load.message.ChannelMessageQueue import io.airbyte.cdk.load.message.QueueWriter import io.airbyte.cdk.load.state.CheckpointManager -import io.airbyte.cdk.load.task.InternalScope -import io.airbyte.cdk.load.task.SyncLevel +import io.airbyte.cdk.load.task.KillableScope import io.airbyte.cdk.load.util.use import io.github.oshai.kotlinlogging.KotlinLogging import io.micronaut.context.annotation.Secondary import jakarta.inject.Singleton -interface TimedForcedCheckpointFlushTask : SyncLevel, InternalScope +interface TimedForcedCheckpointFlushTask : KillableScope @Singleton @Secondary diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/UpdateCheckpointsTask.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/UpdateCheckpointsTask.kt index 3b0bc8be50e7..c73a8ffd6376 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/UpdateCheckpointsTask.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/task/internal/UpdateCheckpointsTask.kt @@ -14,12 +14,11 @@ import io.airbyte.cdk.load.state.CheckpointManager import io.airbyte.cdk.load.state.Reserved import io.airbyte.cdk.load.state.SyncManager import io.airbyte.cdk.load.task.InternalScope -import io.airbyte.cdk.load.task.SyncLevel import io.github.oshai.kotlinlogging.KotlinLogging import io.micronaut.context.annotation.Secondary import jakarta.inject.Singleton -interface UpdateCheckpointsTask : SyncLevel, InternalScope +interface UpdateCheckpointsTask : InternalScope @Singleton @Secondary @@ -36,10 +35,12 @@ class DefaultUpdateCheckpointsTask( when (it.value) { is StreamCheckpointWrapped -> { val (_, stream, index, message) = it.value + log.info { "Updating checkpoint for stream $stream with index $index" } checkpointManager.addStreamCheckpoint(stream, index, it.replace(message)) } is GlobalCheckpointWrapped -> { val (_, streamIndexes, message) = it.value + log.info { "Updating global checkpoint for streams $streamIndexes" } checkpointManager.addGlobalCheckpoint(streamIndexes, it.replace(message)) } } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/util/JsonUtils.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/util/JsonUtils.kt index 682354cde481..7fea7a48bd7b 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/util/JsonUtils.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/util/JsonUtils.kt @@ -4,13 +4,55 @@ package io.airbyte.cdk.load.util +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.StreamReadConstraints +import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.JsonNode -import io.airbyte.cdk.util.Jsons +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule +import com.fasterxml.jackson.module.afterburner.AfterburnerModule +import com.fasterxml.jackson.module.kotlin.registerKotlinModule +import java.io.InputStream -fun JsonNode.serializeToString(): String { +object Jsons : ObjectMapper() { + // allow jackson to deserialize anything under 100 MiB + // (the default, at time of writing 2024-05-29, with jackson 2.15.2, is 20 MiB) + private const val JSON_MAX_LENGTH = 100 * 1024 * 1024 + + init { + registerKotlinModule() + registerModule(JavaTimeModule()) + registerModule(AfterburnerModule()) + setSerializationInclusion(JsonInclude.Include.NON_NULL) + configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true) + configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true) + factory.setStreamReadConstraints( + StreamReadConstraints.builder().maxStringLength(JSON_MAX_LENGTH).build() + ) + } +} + +fun T.serializeToString(): String { return Jsons.writeValueAsString(this) } +fun InputStream.readIntoClass(klass: Class): T = + Jsons.readTree(this).let { Jsons.treeToValue(it, klass) } + +fun T.deserializeToPrettyPrintedString(): String { + return Jsons.writerWithDefaultPrettyPrinter().writeValueAsString(this) +} + fun String.deserializeToNode(): JsonNode { return Jsons.readTree(this) } + +fun String.deserializeToClass(klass: Class): T { + return Jsons.readValue(this, klass) +} + +fun Any.serializeToJsonBytes(): ByteArray { + return Jsons.writeValueAsBytes(this) +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/util/TimeStringUtility.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/util/TimeStringUtility.kt new file mode 100644 index 000000000000..e0f87e5cbd55 --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/util/TimeStringUtility.kt @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.util + +import io.airbyte.cdk.load.data.AirbyteValueDeepCoercingMapper +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.LocalTime +import java.time.OffsetDateTime +import java.time.OffsetTime +import java.time.ZoneOffset +import java.time.ZonedDateTime + +/** Collection of time/date string to time/date object conversion utilities. */ +object TimeStringUtility { + + fun toLocalDate(dateString: String): LocalDate { + return LocalDate.parse(dateString, AirbyteValueDeepCoercingMapper.DATE_TIME_FORMATTER) + } + + fun toLocalDateTime(dateString: String): LocalDateTime { + return LocalDateTime.parse(dateString, AirbyteValueDeepCoercingMapper.DATE_TIME_FORMATTER) + } + + fun toOffset(timeString: String): LocalTime { + return try { + toMicrosOfDayWithTimezone(timeString) + } catch (e: Exception) { + toMicrosOfDayWithoutTimezone(timeString) + } + } + + private fun toMicrosOfDayWithTimezone(timeString: String): LocalTime { + return OffsetTime.parse(timeString, AirbyteValueDeepCoercingMapper.TIME_FORMATTER) + .toLocalTime() + } + + private fun toMicrosOfDayWithoutTimezone(timeString: String): LocalTime { + return LocalTime.parse(timeString, AirbyteValueDeepCoercingMapper.TIME_FORMATTER) + } + + fun toOffsetDateTime(timestampString: String): OffsetDateTime { + return try { + toOffsetDateTimeWithTimezone(timestampString) + } catch (e: Exception) { + toOffsetDateTimeWithoutTimezone(timestampString) + } + } + + private fun toOffsetDateTimeWithTimezone(timestampString: String): OffsetDateTime { + return ZonedDateTime.parse( + timestampString, + AirbyteValueDeepCoercingMapper.DATE_TIME_FORMATTER + ) + .toOffsetDateTime() + } + + private fun toOffsetDateTimeWithoutTimezone(timestampString: String): OffsetDateTime { + return LocalDateTime.parse( + timestampString, + AirbyteValueDeepCoercingMapper.DATE_TIME_FORMATTER + ) + .atOffset(ZoneOffset.UTC) + } +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/write/DestinationWriter.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/write/DestinationWriter.kt index 7ad369a3623d..665dd5abaae7 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/write/DestinationWriter.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/write/DestinationWriter.kt @@ -5,7 +5,7 @@ package io.airbyte.cdk.load.write import io.airbyte.cdk.load.command.DestinationStream -import io.airbyte.cdk.load.state.SyncFailure +import io.airbyte.cdk.load.state.DestinationFailure import io.micronaut.context.annotation.Secondary import jakarta.inject.Singleton @@ -22,7 +22,7 @@ interface DestinationWriter { // Called once at the end of the job, unconditionally. // NOTE: we don't pass Success here, because it depends on this completing successfully. - suspend fun teardown(syncFailure: SyncFailure? = null) {} + suspend fun teardown(destinationFailure: DestinationFailure? = null) {} } @Singleton diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/write/StreamLoader.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/write/StreamLoader.kt index d7b0581590df..f45d3b67c81d 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/write/StreamLoader.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/write/StreamLoader.kt @@ -6,36 +6,77 @@ package io.airbyte.cdk.load.write import io.airbyte.cdk.load.command.DestinationStream import io.airbyte.cdk.load.message.Batch -import io.airbyte.cdk.load.message.DestinationRecord +import io.airbyte.cdk.load.message.BatchEnvelope +import io.airbyte.cdk.load.message.DestinationFile +import io.airbyte.cdk.load.message.DestinationRecordAirbyteValue +import io.airbyte.cdk.load.message.MultiProducerChannel import io.airbyte.cdk.load.message.SimpleBatch -import io.airbyte.cdk.load.state.StreamIncompleteResult +import io.airbyte.cdk.load.state.StreamProcessingFailed /** - * Implementor interface. The framework calls open and close once per stream at the beginning and - * end of processing. The framework calls processRecords once per batch of records as batches of the - * configured size become available. (Specified in @ - * [io.airbyte.cdk.command.WriteConfiguration.recordBatchSizeBytes]) + * Implementor interface. * * [start] is called once before any records are processed. * - * [processRecords] is called whenever a batch of records is available for processing, and only - * after [start] has returned successfully. The return value is a client-defined implementation of @ - * [Batch] that the framework may pass to [processBatch] and/or [finalize]. (See @[Batch] for more - * details.) + * [processRecords] is called whenever a batch of records is available for processing (of the size + * configured in [io.airbyte.cdk.load.command.DestinationConfiguration.recordBatchSizeBytes]) and + * only after [start] has returned successfully. The return value is a client-defined implementation + * of @ [Batch] that the framework may pass to [processBatch]. (See @[Batch] for more details.) + * + * [processRecords] may be called concurrently by multiple workers, so it should be thread-safe if + * [io.airbyte.cdk.load.command.DestinationConfiguration.numProcessRecordsWorkers] > 1. For a + * non-thread-safe alternative, use [createBatchAccumulator]. + * + * [createBatchAccumulator] returns an optional new instance of a [BatchAccumulator] to use for + * record processing instead of this stream loader. By default, it returns a reference to the stream + * loader itself. Use this interface if you want each record processing worker to use a separate + * instance (with its own state, etc). * * [processBatch] is called once per incomplete batch returned by either [processRecords] or - * [processBatch] itself. + * [processBatch] itself. It must be thread-safe if + * [io.airbyte.cdk.load.command.DestinationConfiguration.numProcessBatchWorkers] > 1. If + * [processRecords] never returns a non-[Batch.State.COMPLETE] batch, [processBatch] will never be + * called. * - * [finalize] is called once after all records and batches have been processed successfully. + * NOTE: even if [processBatch] returns a not-[Batch.State.COMPLETE] batch, it will be called again. + * TODO: allow the client to specify subsequent processing stages instead. * - * [close] is called once after all records have been processed, regardless of success or failure. - * If there are failed batches, they are passed in as an argument. + * [close] is called once after all records have been processed, regardless of success or failure, + * but only if [start] returned successfully. If any exception was thrown during processing, it is + * passed as an argument to [close]. */ -interface StreamLoader { +interface StreamLoader : BatchAccumulator, FileBatchAccumulator { val stream: DestinationStream suspend fun start() {} - suspend fun processRecords(records: Iterator, totalSizeBytes: Long): Batch + suspend fun createBatchAccumulator(): BatchAccumulator = this + suspend fun createFileBatchAccumulator( + outputQueue: MultiProducerChannel>, + ): FileBatchAccumulator = this + suspend fun processBatch(batch: Batch): Batch = SimpleBatch(Batch.State.COMPLETE) - suspend fun close(streamFailure: StreamIncompleteResult? = null) {} + suspend fun close(streamFailure: StreamProcessingFailed? = null) {} +} + +interface BatchAccumulator { + suspend fun processRecords( + records: Iterator, + totalSizeBytes: Long, + endOfStream: Boolean = false + ): Batch = + throw NotImplementedError( + "processRecords must be implemented if createBatchAccumulator is overridden" + ) +} + +interface FileBatchAccumulator { + /** + * This is an unusal way to process a message (the DestinationFile). The batch are pushed to the + * queue immediately instead of being return by the method, the main reason is that we nned to + * keep a single instance of a PartFactory for the whole file. + */ + suspend fun processFilePart(file: DestinationFile, index: Long): Unit = + throw NotImplementedError( + "processRecords must be implemented if createBatchAccumulator is overridden" + ) } diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/write/StreamsIncompleteException.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/write/StreamsIncompleteException.kt new file mode 100644 index 000000000000..a4b52f166147 --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/write/StreamsIncompleteException.kt @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.write + +/** + * Thrown when the destination completes successfully, but some streams were indicated as incomplete + * by upstream. Without throwing an exception the sync will not be marked as succeed by the + * platform. + * + * TODO: Once the API with platform is updated to not require an exceptional exit code, remove this. + */ +class StreamsIncompleteException : Exception() { + override val message = "Some streams were indicated as incomplete by upstream." +} diff --git a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/write/WriteOperation.kt b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/write/WriteOperation.kt index 357d08b17e52..5d673a5b26f6 100644 --- a/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/write/WriteOperation.kt +++ b/airbyte-cdk/bulk/core/load/src/main/kotlin/io/airbyte/cdk/load/write/WriteOperation.kt @@ -5,9 +5,9 @@ package io.airbyte.cdk.load.write import io.airbyte.cdk.Operation -import io.airbyte.cdk.load.state.SyncFailure +import io.airbyte.cdk.load.state.DestinationFailure +import io.airbyte.cdk.load.state.DestinationSuccess import io.airbyte.cdk.load.state.SyncManager -import io.airbyte.cdk.load.state.SyncSuccess import io.airbyte.cdk.load.task.TaskLauncher import io.github.oshai.kotlinlogging.KotlinLogging import io.micronaut.context.annotation.Factory @@ -32,13 +32,19 @@ class WriteOperation( override fun execute() = runBlocking { taskLauncher.run() - when (val result = syncManager.awaitSyncResult()) { - is SyncSuccess -> { - log.info { "Sync completed successfully" } + when (val result = syncManager.awaitDestinationResult()) { + is DestinationSuccess -> { + if (!syncManager.allStreamsComplete()) { + log.info { + "Destination completed successfully but some streams were incomplete. Throwing to exit non-zero..." + } + throw StreamsIncompleteException() + } + log.info { "Destination completed successfully and all streams were complete." } } - is SyncFailure -> { - log.info { "Sync failed with stream results ${result.streamResults}" } - throw result.syncFailure + is DestinationFailure -> { + log.info { "Destination failed with stream results ${result.streamResults}" } + throw result.cause } } } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/command/DestinationCatalogTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/command/DestinationCatalogTest.kt index c21f0775ffe0..5f39b6296188 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/command/DestinationCatalogTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/command/DestinationCatalogTest.kt @@ -4,7 +4,7 @@ package io.airbyte.cdk.load.command -import io.airbyte.protocol.models.Jsons +import io.airbyte.cdk.load.util.deserializeToNode import io.airbyte.protocol.models.v0.AirbyteStream import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream @@ -26,7 +26,7 @@ class DestinationCatalogTest { .withDestinationSyncMode(DestinationSyncMode.APPEND) .withStream( AirbyteStream() - .withJsonSchema(Jsons.deserialize("""{"type": "object"}""")) + .withJsonSchema("""{"type": "object"}""".deserializeToNode()) .withNamespace("namespace1") .withName("name1") ), @@ -37,7 +37,7 @@ class DestinationCatalogTest { .withDestinationSyncMode(DestinationSyncMode.APPEND_DEDUP) .withStream( AirbyteStream() - .withJsonSchema(Jsons.deserialize("""{"type": "object"}""")) + .withJsonSchema("""{"type": "object"}""".deserializeToNode()) .withNamespace("namespace2") .withName("name2") ) @@ -50,7 +50,7 @@ class DestinationCatalogTest { .withDestinationSyncMode(DestinationSyncMode.OVERWRITE) .withStream( AirbyteStream() - .withJsonSchema(Jsons.deserialize("""{"type": "object"}""")) + .withJsonSchema("""{"type": "object"}""".deserializeToNode()) .withNamespace("namespace3") .withName("name3") ), diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/AirbyteSchemaIdentityMapperTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/AirbyteSchemaIdentityMapperTest.kt index f91d2f9680a6..9354266a9d4e 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/AirbyteSchemaIdentityMapperTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/AirbyteSchemaIdentityMapperTest.kt @@ -19,9 +19,8 @@ class AirbyteSchemaIdentityMapperTest { .with(IntegerType) .with(BooleanType) .with(NumberType) - .with(NullType) .with(ArrayType(FieldType(StringType, true))) - .with(UnionType(listOf(StringType, IntegerType, NullType))) + .with(UnionType.of(StringType, IntegerType)) .withRecord() .with(TimeTypeWithTimezone) .with(TimeTypeWithoutTimezone) @@ -33,7 +32,6 @@ class AirbyteSchemaIdentityMapperTest { .with(ArrayTypeWithoutSchema) .endRecord() .endRecord() - .with(NullType) .build() val mapper = object : AirbyteSchemaIdentityMapper {} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/AirbyteTypeToAirbyteTypeWithMetaTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/AirbyteTypeToAirbyteTypeWithMetaTest.kt new file mode 100644 index 000000000000..9c1bb4f908da --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/AirbyteTypeToAirbyteTypeWithMetaTest.kt @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data + +import io.airbyte.cdk.load.message.Meta +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +internal class AirbyteTypeToAirbyteTypeWithMetaTest { + private val expectedMeta = + linkedMapOf( + Meta.COLUMN_NAME_AB_RAW_ID to FieldType(StringType, nullable = false), + Meta.COLUMN_NAME_AB_EXTRACTED_AT to FieldType(IntegerType, nullable = false), + Meta.COLUMN_NAME_AB_META to + FieldType( + ObjectType( + linkedMapOf( + "sync_id" to FieldType(IntegerType, nullable = false), + "changes" to + FieldType( + ArrayType( + FieldType( + ObjectType( + linkedMapOf( + "field" to + FieldType(StringType, nullable = false), + "change" to + FieldType(StringType, nullable = false), + "reason" to + FieldType(StringType, nullable = false) + ) + ), + nullable = false + ) + ), + nullable = false + ) + ) + ), + nullable = false + ), + Meta.COLUMN_NAME_AB_GENERATION_ID to FieldType(IntegerType, nullable = false) + ) + + @Test + fun testWithoutFlattening() { + val schema = + ObjectType( + linkedMapOf( + "name" to FieldType(StringType, nullable = false), + "age" to FieldType(IntegerType, nullable = false), + "is_cool" to FieldType(BooleanType, nullable = false) + ) + ) + val withMeta = schema.withAirbyteMeta(flatten = false) + val expected = ObjectType(expectedMeta) + expected.properties[Meta.COLUMN_NAME_DATA] = FieldType(schema, nullable = false) + assertEquals(expected, withMeta) + } + + @Test + fun testWithFlattening() { + val schema = + ObjectType( + linkedMapOf( + "name" to FieldType(StringType, nullable = false), + "age" to FieldType(IntegerType, nullable = false), + "is_cool" to FieldType(BooleanType, nullable = false) + ) + ) + val withMeta = schema.withAirbyteMeta(flatten = true) + val expected = ObjectType(expectedMeta) + schema.properties.forEach { (name, field) -> expected.properties[name] = field } + assertEquals(expected, withMeta) + } +} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/AirbyteValueDeepCoercingMapperTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/AirbyteValueDeepCoercingMapperTest.kt new file mode 100644 index 000000000000..337992809718 --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/AirbyteValueDeepCoercingMapperTest.kt @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data + +import io.airbyte.cdk.load.data.AirbyteValueDeepCoercingMapper.Companion.DATE_TIME_FORMATTER +import io.airbyte.cdk.load.data.json.toAirbyteValue +import io.airbyte.cdk.load.message.Meta +import io.airbyte.cdk.load.util.Jsons +import java.math.BigDecimal +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.LocalTime +import java.time.OffsetDateTime +import java.time.OffsetTime +import java.time.ZoneOffset +import java.time.ZonedDateTime +import org.junit.jupiter.api.Assertions.assertAll +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +class AirbyteValueDeepCoercingMapperTest { + private val mapper = AirbyteValueDeepCoercingMapper() + + @Test + fun testBasicCoerce() { + val (mappedValue, changes) = + mapper.map( + Jsons.readTree( + """ + { + "undeclared": 42, + "null": null, + "string": "foo", + "boolean": true, + "integer": 42, + "number": 42.1, + "date": "2024-01-23", + "timestamptz": "2024-01-23T01:23:45Z", + "timestampntz": "2024-01-23T01:23:45", + "timetz": "01:23:45Z", + "timentz": "01:23:45", + "array": [1, 2, 3], + "array_schemaless": [1, true, "foo"], + "object": {"foo": 42}, + "object_schemaless": {"foo": 42}, + "object_empty": {"foo": 42} + } + """.trimIndent() + ) + .toAirbyteValue(), + ObjectType( + linkedMapOf( + "null" to f(IntegerType), + "string" to f(StringType), + "boolean" to f(BooleanType), + "integer" to f(IntegerType), + "number" to f(NumberType), + "date" to f(DateType), + "timestamptz" to f(TimestampTypeWithTimezone), + "timestampntz" to f(TimestampTypeWithoutTimezone), + "timetz" to f(TimeTypeWithTimezone), + "timentz" to f(TimeTypeWithoutTimezone), + "array" to f(ArrayType(f(IntegerType))), + "array_schemaless" to f(ArrayTypeWithoutSchema), + "object" to f(ObjectType(linkedMapOf("foo" to f(IntegerType)))), + "object_schemaless" to f(ObjectTypeWithoutSchema), + "object_empty" to f(ObjectTypeWithEmptySchema), + ) + ), + ) + assertAll( + { + assertEquals( + ObjectValue( + linkedMapOf( + // note that the undeclared field is now gone + "null" to NullValue, + "string" to StringValue("foo"), + "boolean" to BooleanValue(true), + "integer" to IntegerValue(42), + "number" to NumberValue(BigDecimal("42.1")), + "date" to DateValue(LocalDate.parse("2024-01-23")), + "timestamptz" to + TimestampWithTimezoneValue( + OffsetDateTime.parse("2024-01-23T01:23:45Z") + ), + "timestampntz" to + TimestampWithoutTimezoneValue( + LocalDateTime.parse("2024-01-23T01:23:45") + ), + "timetz" to TimeWithTimezoneValue(OffsetTime.parse("01:23:45Z")), + "timentz" to TimeWithoutTimezoneValue(LocalTime.parse("01:23:45")), + "array" to + ArrayValue( + listOf(IntegerValue(1), IntegerValue(2), IntegerValue(3)) + ), + "array_schemaless" to + ArrayValue( + listOf(IntegerValue(1), BooleanValue(true), StringValue("foo")) + ), + "object" to ObjectValue(linkedMapOf("foo" to IntegerValue(42))), + "object_schemaless" to + ObjectValue(linkedMapOf("foo" to IntegerValue(42))), + "object_empty" to ObjectValue(linkedMapOf("foo" to IntegerValue(42))), + ) + ), + mappedValue + ) + }, + { assertEquals(emptyList(), changes) }, + ) + } + + @Test + fun testCoerceDate() { + listOf( + "2021-1-1", + "2021-01-01", + "2021/01/02", + "2021.01.03", + "2021 Jan 04", + "2021-1-1 BC", + ) + .map { it to LocalDate.parse(it, DATE_TIME_FORMATTER) } + .forEach { (input, localDate) -> + val (value, changes) = mapper.map(StringValue(input), DateType) + assertAll( + "Failed for input $input", + { assertEquals(DateValue(localDate), value) }, + { assertEquals(emptyList(), changes) } + ) + } + } + + private val timestampPairs: List> = + listOf( + "2018-09-15 12:00:00" to + LocalDateTime.parse("2018-09-15 12:00:00", DATE_TIME_FORMATTER) + .atOffset(ZoneOffset.UTC), + "2018-09-15 12:00:00.006542" to + LocalDateTime.parse("2018-09-15 12:00:00.006542", DATE_TIME_FORMATTER) + .atOffset(ZoneOffset.UTC), + "2018/09/15 12:00:00" to + LocalDateTime.parse("2018/09/15 12:00:00", DATE_TIME_FORMATTER) + .atOffset(ZoneOffset.UTC), + "2018.09.15 12:00:00" to + LocalDateTime.parse("2018.09.15 12:00:00", DATE_TIME_FORMATTER) + .atOffset(ZoneOffset.UTC), + "2018 Jul 15 12:00:00" to + LocalDateTime.parse("2018 Jul 15 12:00:00", DATE_TIME_FORMATTER) + .atOffset(ZoneOffset.UTC), + "2021-1-1 01:01:01" to + LocalDateTime.parse("2021-1-1 01:01:01", DATE_TIME_FORMATTER) + .atOffset(ZoneOffset.UTC), + "2021.1.1 01:01:01" to + LocalDateTime.parse("2021.1.1 01:01:01", DATE_TIME_FORMATTER) + .atOffset(ZoneOffset.UTC), + "2021/1/1 01:01:01" to + LocalDateTime.parse("2021/1/1 01:01:01", DATE_TIME_FORMATTER) + .atOffset(ZoneOffset.UTC), + "2021-01-01 01:01:01" to + LocalDateTime.parse("2021-01-01 01:01:01", DATE_TIME_FORMATTER) + .atOffset(ZoneOffset.UTC), + "2021-1-1 01:01:01 +01" to + ZonedDateTime.parse("2021-1-1 01:01:01 +01", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + "2018 Jul 15 12:00:00 GMT+08:00" to + ZonedDateTime.parse("2018 Jul 15 12:00:00 GMT+08:00", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + "2018 Jul 15 12:00:00GMT+07" to + ZonedDateTime.parse("2018 Jul 15 12:00:00GMT+07", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + "2021-01-01T01:01:01+01:00" to + ZonedDateTime.parse("2021-01-01T01:01:01+01:00", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + "2021-01-01T01:01:01.546+01:00" to + ZonedDateTime.parse("2021-01-01T01:01:01.546+01:00", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + "2021-01-01 01:01:01 +0000" to + ZonedDateTime.parse("2021-01-01 01:01:01 +0000", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + "2021/01/01 01:01:01 +0000" to + ZonedDateTime.parse("2021/01/01 01:01:01 +0000", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + "2021-01-01T01:01:01Z" to + ZonedDateTime.parse("2021-01-01T01:01:01Z", DATE_TIME_FORMATTER).toOffsetDateTime(), + "2021-01-01T01:01:01-01:00" to + ZonedDateTime.parse("2021-01-01T01:01:01-01:00", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + "2021-01-01T01:01:01+01:00" to + ZonedDateTime.parse("2021-01-01T01:01:01+01:00", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + "2021-01-01 01:01:01 UTC" to + ZonedDateTime.parse("2021-01-01 01:01:01 UTC", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + "2021-01-01T01:01:01 PST" to + ZonedDateTime.parse("2021-01-01T01:01:01 PST", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + "2021-01-01T01:01:01 +0000" to + ZonedDateTime.parse("2021-01-01T01:01:01 +0000", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + "2021-01-01T01:01:01+0000" to + ZonedDateTime.parse("2021-01-01T01:01:01+0000", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + "2021-01-01T01:01:01UTC" to + ZonedDateTime.parse("2021-01-01T01:01:01UTC", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + "2021-01-01T01:01:01+01" to + ZonedDateTime.parse("2021-01-01T01:01:01+01", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + "2022-01-23T01:23:45.678-11:30 BC" to + ZonedDateTime.parse("2022-01-23T01:23:45.678-11:30 BC", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + "2022-01-23T01:23:45.678-11:30" to + ZonedDateTime.parse("2022-01-23T01:23:45.678-11:30", DATE_TIME_FORMATTER) + .toOffsetDateTime(), + ) + + @Test + fun testCoerceTimestampWithTimezone() { + timestampPairs.forEach { (input, offsetDateTime) -> + val (value, changes) = mapper.map(StringValue(input), TimestampTypeWithTimezone) + + assertAll( + "Failed for input $input", + { assertEquals(TimestampWithTimezoneValue(offsetDateTime), value) }, + { assertEquals(emptyList(), changes) } + ) + } + } + + @Test + fun testCoerceTimestampWithoutTimezone() { + timestampPairs.forEach { (input, offsetDateTime) -> + val (value, changes) = mapper.map(StringValue(input), TimestampTypeWithoutTimezone) + + assertAll( + "Failed for input $input", + { + assertEquals( + TimestampWithoutTimezoneValue(offsetDateTime.toLocalDateTime()), + value + ) + }, + { assertEquals(emptyList(), changes) } + ) + } + } + + private val timePairs: List> = + listOf( + "01:01:01" to LocalTime.parse("01:01:01").atOffset(ZoneOffset.UTC), + "01:01" to LocalTime.parse("01:01").atOffset(ZoneOffset.UTC), + "12:23:01.541" to LocalTime.parse("12:23:01.541").atOffset(ZoneOffset.UTC), + "12:23:01.541214" to LocalTime.parse("12:23:01.541214").atOffset(ZoneOffset.UTC), + "12:00:00.000000+01:00" to OffsetTime.parse("12:00:00.000000+01:00"), + "10:00:00.000000-01:00" to OffsetTime.parse("10:00:00.000000-01:00"), + "03:30:00.000000+04:00" to OffsetTime.parse("03:30:00.000000+04:00"), + ) + + @Test + fun testCoerceTimeWithTimezone() { + timePairs.forEach { (input, offsetTime) -> + val (value, changes) = mapper.map(StringValue(input), TimeTypeWithTimezone) + + assertAll( + "Failed for input $input", + { assertEquals(TimeWithTimezoneValue(offsetTime), value) }, + { assertEquals(emptyList(), changes) } + ) + } + } + + @Test + fun testCoerceTimeWithoutTimezone() { + timePairs.forEach { (input, offsetTime) -> + val (value, changes) = mapper.map(StringValue(input), TimeTypeWithoutTimezone) + + assertAll( + "Failed for input $input", + { assertEquals(TimeWithoutTimezoneValue(offsetTime.toLocalTime()), value) }, + { assertEquals(emptyList(), changes) } + ) + } + } + + private fun f(type: AirbyteType) = FieldType(type, nullable = true) +} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/AirbyteValueIdentityMapperTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/AirbyteValueIdentityMapperTest.kt index 6adcad2dadd4..17a7bc1994bf 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/AirbyteValueIdentityMapperTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/AirbyteValueIdentityMapperTest.kt @@ -4,13 +4,13 @@ package io.airbyte.cdk.load.data -import io.airbyte.cdk.load.message.DestinationRecord +import io.airbyte.cdk.load.message.Meta import io.airbyte.cdk.load.test.util.Root import io.airbyte.cdk.load.test.util.SchemaRecordBuilder import io.airbyte.cdk.load.test.util.ValueTestBuilder -import io.airbyte.protocol.models.v0.AirbyteRecordMessageMetaChange import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertAll class AirbyteValueIdentityMapperTest { @Test @@ -20,10 +20,13 @@ class AirbyteValueIdentityMapperTest { .with(StringValue("a"), StringType) .with(IntegerValue(1), IntegerType) .with(BooleanValue(true), BooleanType) - .with(TimestampValue("2021-01-01T12:00:00Z"), TimestampTypeWithTimezone) - .with(TimestampValue("2021-01-01T12:00:00"), TimestampTypeWithoutTimezone) - .with(TimeValue("12:00:00Z"), TimeTypeWithTimezone) - .with(TimeValue("12:00:00"), TimeTypeWithoutTimezone) + .with(TimestampWithTimezoneValue("2021-01-01T12:00:00Z"), TimestampTypeWithTimezone) + .with( + TimestampWithoutTimezoneValue("2021-01-01T12:00:00"), + TimestampTypeWithoutTimezone + ) + .with(TimeWithTimezoneValue("12:00:00Z"), TimeTypeWithTimezone) + .with(TimeWithoutTimezoneValue("12:00:00"), TimeTypeWithoutTimezone) .with(DateValue("2021-01-01"), DateType) .withRecord() .with( @@ -35,15 +38,14 @@ class AirbyteValueIdentityMapperTest { ArrayTypeWithoutSchema ) .withRecord() - .with(NullValue, NullType) .endRecord() .endRecord() .build() - val meta = DestinationRecord.Meta() - val values = AirbyteValueIdentityMapper(meta).map(inputValues, inputSchema) + val mapper = AirbyteValueIdentityMapper() + val (values, changes) = mapper.map(inputValues, inputSchema) Assertions.assertEquals(expectedValues, values) - Assertions.assertTrue(meta.changes.isEmpty()) + Assertions.assertTrue(changes.isEmpty()) } @Test @@ -51,23 +53,13 @@ class AirbyteValueIdentityMapperTest { val (inputValues, inputSchema, _) = ValueTestBuilder>() .with(StringValue("a"), StringType) - .with( - TimestampValue("2021-01-01T12:00:00Z"), - TimeTypeWithTimezone, - nameOverride = "bad" - ) + .with(IntegerValue(1000), BooleanType, nameOverride = "bad", nullable = true) .build() - val meta = DestinationRecord.Meta() - val values = AirbyteValueIdentityMapper(meta).map(inputValues, inputSchema) as ObjectValue - Assertions.assertTrue(meta.changes.isNotEmpty()) - Assertions.assertTrue(values.values["bad"] is NullValue) - Assertions.assertTrue(meta.changes[0].field == "bad") - Assertions.assertTrue( - meta.changes[0].change == AirbyteRecordMessageMetaChange.Change.NULLED - ) - Assertions.assertTrue( - meta.changes[0].reason == - AirbyteRecordMessageMetaChange.Reason.DESTINATION_SERIALIZATION_ERROR + val mapper = AirbyteValueIdentityMapper() + val (values, changes) = mapper.map(inputValues, inputSchema) + assertAll( + { Assertions.assertEquals(emptyList(), changes) }, + { Assertions.assertEquals(IntegerValue(1000), (values as ObjectValue).values["bad"]) }, ) } } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/DestinationRecordAirbyteValueToAirbyteValueWithMetaTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/DestinationRecordAirbyteValueToAirbyteValueWithMetaTest.kt new file mode 100644 index 000000000000..d7cfcfed5a2f --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/DestinationRecordAirbyteValueToAirbyteValueWithMetaTest.kt @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data + +import io.airbyte.cdk.load.command.MockDestinationCatalogFactory +import io.airbyte.cdk.load.message.DestinationRecordAirbyteValue +import io.airbyte.cdk.load.message.Meta +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class DestinationRecordAirbyteValueToAirbyteValueWithMetaTest { + val stream = MockDestinationCatalogFactory.stream1 + val emittedAtMs = 123456L + val syncId = stream.syncId + val generationId = stream.generationId + val expectedMeta = + linkedMapOf( + // Don't do raw_id, we'll evict it and validate that it's a uuid + Meta.COLUMN_NAME_AB_EXTRACTED_AT to IntegerValue(emittedAtMs), + Meta.COLUMN_NAME_AB_META to + ObjectValue( + linkedMapOf( + "sync_id" to IntegerValue(syncId), + "changes" to ArrayValue(emptyList()) + ) + ), + Meta.COLUMN_NAME_AB_GENERATION_ID to IntegerValue(generationId) + ) + + @Test + fun testWithoutFlattening() { + val data = + ObjectValue( + linkedMapOf( + "name" to StringValue("John"), + "age" to IntegerValue(30), + "is_cool" to BooleanValue(true) + ) + ) + val expected = LinkedHashMap(expectedMeta) + expected[Meta.COLUMN_NAME_DATA] = data + val mockRecord = DestinationRecordAirbyteValue(stream.descriptor, data, emittedAtMs, Meta()) + val withMeta = mockRecord.dataWithAirbyteMeta(stream, flatten = false) + val uuid = withMeta.values.remove(Meta.COLUMN_NAME_AB_RAW_ID) as StringValue + Assertions.assertTrue( + uuid.value.matches( + Regex("[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}") + ) + ) + Assertions.assertEquals(expected, withMeta.values) + } + + @Test + fun testWithFlattening() { + val data = + ObjectValue( + linkedMapOf( + "name" to StringValue("John"), + "age" to IntegerValue(30), + "is_cool" to BooleanValue(true) + ) + ) + val expected = LinkedHashMap(expectedMeta) + data.values.forEach { (name, value) -> expected[name] = value } + val mockRecord = DestinationRecordAirbyteValue(stream.descriptor, data, emittedAtMs, Meta()) + val withMeta = mockRecord.dataWithAirbyteMeta(stream, flatten = true) + withMeta.values.remove(Meta.COLUMN_NAME_AB_RAW_ID) + Assertions.assertEquals(expected, withMeta.values) + } +} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/FailOnAllUnknownTypesExceptNullTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/FailOnAllUnknownTypesExceptNullTest.kt new file mode 100644 index 000000000000..1f31db5e7aa7 --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/FailOnAllUnknownTypesExceptNullTest.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data + +import com.fasterxml.jackson.databind.node.JsonNodeFactory +import io.airbyte.cdk.load.test.util.Root +import io.airbyte.cdk.load.test.util.SchemaRecordBuilder +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class FailOnAllUnknownTypesExceptNullTest { + @Test + fun testBasicTypeBehavior() { + val nullType = JsonNodeFactory.instance.objectNode().put("type", "null") + val (inputSchema, expectedOutput) = + SchemaRecordBuilder() + .with(UnknownType(nullType)) + .with( + UnknownType( + JsonNodeFactory.instance + .objectNode() + .set( + "type", + JsonNodeFactory.instance.arrayNode().add("null").add("null") + ) + ) + ) + .build() + FailOnAllUnknownTypesExceptNull().map(inputSchema).let { + Assertions.assertEquals(expectedOutput, it) + } + } + + @Test + fun `test throws on non-null unknown types`() { + val (inputSchema, _) = + SchemaRecordBuilder() + .with(UnknownType(JsonNodeFactory.instance.objectNode().put("type", "whatever"))) + .build() + Assertions.assertThrows(IllegalStateException::class.java) { + FailOnAllUnknownTypesExceptNull().map(inputSchema) + } + } +} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/MapperPipelineTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/MapperPipelineTest.kt new file mode 100644 index 000000000000..3d38c3691815 --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/MapperPipelineTest.kt @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data + +import io.airbyte.cdk.load.test.util.Root +import io.airbyte.cdk.load.test.util.SchemaRecordBuilder +import io.airbyte.cdk.load.test.util.ValueTestBuilder +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class MapperPipelineTest { + class TurnSchemalessObjectTypesIntoIntegers : AirbyteSchemaIdentityMapper { + override fun mapObjectWithoutSchema(schema: ObjectTypeWithoutSchema): AirbyteType = + IntegerType + } + + class TurnSchemalessObjectsIntoIntegers : AirbyteValueIdentityMapper() { + override fun mapObjectWithoutSchema( + value: AirbyteValue, + schema: ObjectTypeWithoutSchema, + context: Context + ): Pair { + if ((value as ObjectValue).values.size == 1) { + throw IllegalStateException("Arbitrarily reject 1") + } + return IntegerValue(value.values.size.toLong()) to context + } + } + + class TurnIntegerTypesIntoStrings : AirbyteSchemaIdentityMapper { + override fun mapInteger(schema: IntegerType): AirbyteType = StringType + } + + class TurnIntegersIntoStrings : AirbyteValueIdentityMapper() { + override fun mapInteger( + value: AirbyteValue, + context: Context + ): Pair { + if ((value as IntegerValue).value.toLong() == 2L) { + throw IllegalStateException("Arbitrarily reject 2") + } + return StringValue(value.value.toString()) to context + } + } + + private fun makePipeline(schema: AirbyteType) = + MapperPipeline( + schema, + listOf( + TurnIntegerTypesIntoStrings() to TurnIntegersIntoStrings(), + TurnSchemalessObjectTypesIntoIntegers() to TurnSchemalessObjectsIntoIntegers(), + ) + ) + + @Test + fun testSuccessfulPipeline() { + val (inputSchema, expectedSchema) = + SchemaRecordBuilder() + .with(ObjectTypeWithoutSchema, IntegerType) + .with(IntegerType, StringType) + .withRecord() + .with(IntegerType, StringType) + .with(BooleanType, BooleanType) // expect unchanged + .endRecord() + .build() + + val pipeline = makePipeline(inputSchema) + Assertions.assertEquals( + expectedSchema, + pipeline.finalSchema, + "final schema matches expected transformed schema" + ) + } + + @Test + fun testRecordMapping() { + val (inputValue, inputSchema, expectedOutput) = + ValueTestBuilder() + .with( + ObjectValue(linkedMapOf("a" to IntegerValue(1), "b" to IntegerValue(2))), + ObjectTypeWithoutSchema, + IntegerValue(2) + ) + .with(IntegerValue(1), IntegerType, StringValue("1")) + .withRecord() + .with(IntegerValue(3), IntegerType, StringValue("3")) + .with(BooleanValue(true), BooleanType, BooleanValue(true)) // expect unchanged + .endRecord() + .build() + val pipeline = makePipeline(inputSchema) + val (result, changes) = pipeline.map(inputValue) + + Assertions.assertEquals(0, changes.size, "no changes were captured") + Assertions.assertEquals(expectedOutput, result, "data was transformed as expected") + } + + @Test + fun testFailedMapping() { + val (inputValue, inputSchema, _) = + ValueTestBuilder() + .with( + ObjectValue(linkedMapOf("a" to IntegerValue(1))), + ObjectTypeWithoutSchema, + NullValue, + nullable = true + ) // fail: reject size==1 + .with(IntegerValue(1), IntegerType, StringValue("1")) + .withRecord() + .with(IntegerValue(2), IntegerType, NullValue, nullable = true) // fail: reject 2 + .with(BooleanValue(true), BooleanType, BooleanValue(true)) // expect unchanged + .endRecord() + .build() + val pipeline = makePipeline(inputSchema) + val (_, changes) = pipeline.map(inputValue) + + Assertions.assertEquals(2, changes.size, "two failures were captured") + } + + @Test + fun testFailedMappingThrowsOnNonNullable() { + val (inputValue, inputSchema, _) = + ValueTestBuilder() + .with(IntegerValue(2), IntegerType, NullValue, nullable = false) // fail: reject 2 + .build() + + val pipeline = makePipeline(inputSchema) + + Assertions.assertThrows(IllegalStateException::class.java) { pipeline.map(inputValue) } + } +} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/MergeUnionsTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/MergeUnionsTest.kt index ea4aa91a3f44..9bba426dcd17 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/MergeUnionsTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/MergeUnionsTest.kt @@ -8,7 +8,6 @@ import io.airbyte.cdk.load.test.util.Root import io.airbyte.cdk.load.test.util.SchemaRecordBuilder import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertThrows class MergeUnionsTest { @Test @@ -41,10 +40,22 @@ class MergeUnionsTest { } @Test - fun testNameClashFails() { - val (inputSchema, _) = + fun testNameClash() { + val (inputSchema, expectedOutput) = SchemaRecordBuilder() - .withUnion() + .withUnion( + expectedInstead = + FieldType( + ObjectType( + properties = + linkedMapOf( + "foo" to + FieldType(UnionType.of(StringType, IntegerType), false) + ) + ), + false + ) + ) .withRecord() .with(StringType, nameOverride = "foo") .endRecord() @@ -53,7 +64,8 @@ class MergeUnionsTest { .endRecord() .endUnion() .build() - assertThrows { MergeUnions().map(inputSchema) } + val output = MergeUnions().map(inputSchema) + Assertions.assertEquals(expectedOutput, output) } @Test @@ -62,7 +74,7 @@ class MergeUnionsTest { SchemaRecordBuilder() .withUnion( expectedInstead = - FieldType(UnionType(listOf(StringType, IntegerType)), nullable = false) + FieldType(UnionType.of(StringType, IntegerType), nullable = false) ) .with(StringType) .with(IntegerType) @@ -79,10 +91,10 @@ class MergeUnionsTest { SchemaRecordBuilder() .withUnion( expectedInstead = - FieldType(UnionType(listOf(StringType, IntegerType)), nullable = false) + FieldType(UnionType.of(StringType, IntegerType), nullable = false) ) .with(StringType) - .with(UnionType(listOf(StringType, UnionType(listOf(IntegerType, StringType))))) + .with(UnionType.of(StringType, UnionType.of(IntegerType, StringType))) .with(IntegerType) .endUnion() .build() diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/NullOutOfRangeIntegersTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/NullOutOfRangeIntegersTest.kt new file mode 100644 index 000000000000..7c3645bde128 --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/NullOutOfRangeIntegersTest.kt @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data + +import io.airbyte.cdk.load.message.Meta +import io.airbyte.cdk.load.test.util.Root +import io.airbyte.cdk.load.test.util.ValueTestBuilder +import io.airbyte.protocol.models.v0.AirbyteRecordMessageMetaChange.Change +import io.airbyte.protocol.models.v0.AirbyteRecordMessageMetaChange.Reason +import java.math.BigInteger +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class NullOutOfRangeIntegersTest { + @Test + fun testDefaultBehavior() { + val (valueIn, schemaIn, expectedValue) = + ValueTestBuilder() + .with(IntegerValue(150), IntegerType, nullable = true) + .with( + IntegerValue(BigInteger("123456789012345678901234567890")), + IntegerType, + NullValue, + nameOverride = "big_integer", + nullable = true + ) + .build() + val (actualValue, changes) = NullOutOfRangeIntegers().map(valueIn, schemaIn) + Assertions.assertEquals(expectedValue, actualValue) + Assertions.assertEquals(1, changes.size) + Assertions.assertEquals( + Meta.Change( + "big_integer", + Change.NULLED, + Reason.DESTINATION_FIELD_SIZE_LIMITATION, + ), + changes[0] + ) + } + + @Test + fun testRestrictiveBehavior() { + val minValue = BigInteger("100") + val maxValue = BigInteger("200") + val (valueIn, schemaIn, expectedValue) = + ValueTestBuilder() + .with(IntegerValue(150), IntegerType, nullable = true) + .with( + IntegerValue(10), + IntegerType, + NullValue, + nameOverride = "too_small", + nullable = true + ) + .with( + IntegerValue(300), + IntegerType, + NullValue, + nameOverride = "too_big", + nullable = true + ) + .build() + val (actualValue, changes) = + NullOutOfRangeIntegers(minValue, maxValue).map(valueIn, schemaIn) + Assertions.assertEquals(expectedValue, actualValue) + Assertions.assertEquals( + setOf( + Meta.Change( + "too_small", + Change.NULLED, + Reason.DESTINATION_FIELD_SIZE_LIMITATION, + ), + Meta.Change( + "too_big", + Change.NULLED, + Reason.DESTINATION_FIELD_SIZE_LIMITATION, + ), + changes[1] + ), + changes.toSet() + ) + } +} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/NullableToUnionNullTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/NullableToUnionNullTest.kt deleted file mode 100644 index 7832c3628232..000000000000 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/NullableToUnionNullTest.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.cdk.load.data - -import io.airbyte.cdk.load.test.util.Root -import io.airbyte.cdk.load.test.util.SchemaRecordBuilder -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test - -class NullableToUnionNullTest { - @Test - fun testBasicBehavior() { - val (inputSchema, expectedOutput) = - SchemaRecordBuilder() - .with(FieldType(StringType, nullable = false)) - .with( - FieldType(IntegerType, nullable = true), - FieldType(UnionType(listOf(IntegerType, NullType)), nullable = false) - ) - .build() - Assertions.assertEquals(NullableToUnionNull().map(inputSchema), expectedOutput) - } - - @Test - fun testWackyBehavior() { - val (inputSchema, expectedOutput) = - SchemaRecordBuilder() - .with(FieldType(UnionType(listOf(StringType, IntegerType)), nullable = false)) - .with( - FieldType(UnionType(listOf(StringType, IntegerType)), nullable = true), - FieldType( - UnionType(listOf(UnionType(listOf(StringType, IntegerType)), NullType)), - nullable = false - ) - ) - .with(FieldType(UnionType(listOf(StringType, NullType)), nullable = false)) - .with( - FieldType(UnionType(listOf(StringType, NullType)), nullable = true), - FieldType( - UnionType(listOf(UnionType(listOf(StringType, NullType)), NullType)), - nullable = false - ) - ) - .build() - Assertions.assertEquals(NullableToUnionNull().map(inputSchema), expectedOutput) - } -} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/SchemalessTypesToJsonStringTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/SchemalessTypesToJsonStringTest.kt index 27d5d9cf9042..7d91ffc8db85 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/SchemalessTypesToJsonStringTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/SchemalessTypesToJsonStringTest.kt @@ -5,55 +5,13 @@ package io.airbyte.cdk.load.data import io.airbyte.cdk.load.data.json.toAirbyteValue -import io.airbyte.cdk.load.message.DestinationRecord import io.airbyte.cdk.load.test.util.Root -import io.airbyte.cdk.load.test.util.SchemaRecordBuilder import io.airbyte.cdk.load.test.util.ValueTestBuilder import io.airbyte.cdk.load.util.deserializeToNode import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test class SchemalessTypesToJsonStringTest { - @Test - fun testBasicTypeBehavior() { - val (inputSchema, expectedOutput) = - SchemaRecordBuilder() - .withRecord() - .with(StringType) - .with(IntegerType) - .endRecord() - .with(ObjectTypeWithoutSchema, StringType) - .with(ObjectTypeWithEmptySchema, StringType) - .with(ArrayTypeWithoutSchema, StringType) - .with(ArrayType(FieldType(StringType, nullable = false))) - .build() - val mapper = SchemalessTypesToJsonString() - val output = mapper.map(inputSchema) - Assertions.assertEquals(expectedOutput, output) - } - - @Test - fun testNestedTypes() { - val (inputSchema, expectedOutput) = - SchemaRecordBuilder() - .withRecord() - .with(StringType) - .with(ObjectTypeWithEmptySchema, StringType) - .withRecord() - .with(IntegerType) - .with(ObjectTypeWithoutSchema, StringType) - .endRecord() - .with( - ArrayType(FieldType(ArrayTypeWithoutSchema, nullable = false)), - ArrayType(FieldType(StringType, nullable = false)) - ) - .endRecord() - .build() - val mapper = SchemalessTypesToJsonString() - val output = mapper.map(inputSchema) - Assertions.assertEquals(expectedOutput, output) - } - private val addressJson = """{"address":{"street":"123 Main St","city":"San Francisco","state":"CA"}}""" @@ -71,7 +29,7 @@ class SchemalessTypesToJsonStringTest { StringValue("""{"foo":"bar"}""") ) .with( - addressJson.deserializeToNode().toAirbyteValue(ObjectTypeWithoutSchema), + addressJson.deserializeToNode().toAirbyteValue(), ObjectTypeWithEmptySchema, StringValue(addressJson) ) @@ -85,8 +43,8 @@ class SchemalessTypesToJsonStringTest { ArrayType(FieldType(StringType, nullable = false)) ) .build() - val mapper = SchemalessValuesToJsonString(DestinationRecord.Meta()) - val output = mapper.map(inputValues, inputSchema) + val mapper = SchemalessValuesToJsonString() + val output = mapper.map(inputValues, inputSchema).first Assertions.assertEquals(expectedOutput, output) } @@ -120,8 +78,8 @@ class SchemalessTypesToJsonStringTest { ArrayType(FieldType(StringType, nullable = false)) ) .build() - val mapper = SchemalessValuesToJsonString(DestinationRecord.Meta()) - val output = mapper.map(inputValues, inputSchema) + val mapper = SchemalessValuesToJsonString() + val output = mapper.map(inputValues, inputSchema).first Assertions.assertEquals(expectedOutput, output) } } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/SchemalessTypesToJsonTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/SchemalessTypesToJsonTest.kt deleted file mode 100644 index 7dab6e3d4b1a..000000000000 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/SchemalessTypesToJsonTest.kt +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.cdk.load.data - -import io.airbyte.cdk.load.data.json.toAirbyteValue -import io.airbyte.cdk.load.message.DestinationRecord -import io.airbyte.cdk.load.test.util.Root -import io.airbyte.cdk.load.test.util.SchemaRecordBuilder -import io.airbyte.cdk.load.test.util.ValueTestBuilder -import io.airbyte.cdk.load.util.deserializeToNode -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test - -class SchemalessTypesToJsonTest { - @Test - fun testBasicTypeBehavior() { - val (inputSchema, expectedOutput) = - SchemaRecordBuilder() - .withRecord() - .with(StringType) - .with(IntegerType) - .endRecord() - .with(ObjectTypeWithoutSchema, StringType) - .with(ObjectTypeWithEmptySchema, StringType) - .with(ArrayTypeWithoutSchema, StringType) - .with(ArrayType(FieldType(StringType, nullable = false))) - .build() - val mapper = SchemalessTypesToJson() - val output = mapper.map(inputSchema) - Assertions.assertEquals(expectedOutput, output) - } - - @Test - fun testNestedTypes() { - val (inputSchema, expectedOutput) = - SchemaRecordBuilder() - .withRecord() - .with(StringType) - .with(ObjectTypeWithEmptySchema, StringType) - .withRecord() - .with(IntegerType) - .with(ObjectTypeWithoutSchema, StringType) - .endRecord() - .with( - ArrayType(FieldType(ArrayTypeWithoutSchema, nullable = false)), - ArrayType(FieldType(StringType, nullable = false)) - ) - .endRecord() - .build() - val mapper = SchemalessTypesToJson() - val output = mapper.map(inputSchema) - Assertions.assertEquals(expectedOutput, output) - } - - private val addressJson = - """{"address":{"street":"123 Main St","city":"San Francisco","state":"CA"}}""" - - @Test - fun testBasicValueBehavior() { - val (inputValues, inputSchema, expectedOutput) = - ValueTestBuilder() - .withRecord() - .with(StringValue("hello"), StringType) - .with(IntegerValue(42), IntegerType) - .endRecord() - .with( - ObjectValue(linkedMapOf("foo" to StringValue("bar"))), - ObjectTypeWithoutSchema, - StringValue("""{"foo":"bar"}""") - ) - .with( - addressJson.deserializeToNode().toAirbyteValue(ObjectTypeWithoutSchema), - ObjectTypeWithEmptySchema, - StringValue(addressJson) - ) - .with( - ArrayValue(listOf(StringValue("hello"), StringValue("world"))), - ArrayTypeWithoutSchema, - StringValue("""["hello","world"]""") - ) - .with( - ArrayValue(listOf(StringValue("hello"), StringValue("world"))), - ArrayType(FieldType(StringType, nullable = false)) - ) - .build() - val mapper = SchemalessValuesToJson(DestinationRecord.Meta()) - val output = mapper.map(inputValues, inputSchema) - Assertions.assertEquals(expectedOutput, output) - } - - @Test - fun testNestedBehavior() { - val (inputValues, inputSchema, expectedOutput) = - ValueTestBuilder() - .withRecord() - .with(StringValue("hello"), StringType) - .with( - ObjectValue(linkedMapOf("foo" to StringValue("bar"))), - ObjectTypeWithEmptySchema, - StringValue("""{"foo":"bar"}""") - ) - .withRecord() - .with(IntegerValue(42), IntegerType) - .with( - ObjectValue(linkedMapOf("foo" to StringValue("bar"))), - ObjectTypeWithoutSchema, - StringValue("""{"foo":"bar"}""") - ) - .endRecord() - .with( - ArrayValue(listOf(StringValue("hello"), StringValue("world"))), - ArrayTypeWithoutSchema, - StringValue("""["hello","world"]""") - ) - .endRecord() - .with( - ArrayValue(listOf(StringValue("hello"), StringValue("world"))), - ArrayType(FieldType(StringType, nullable = false)) - ) - .build() - val mapper = SchemalessValuesToJson(DestinationRecord.Meta()) - val output = mapper.map(inputValues, inputSchema) - Assertions.assertEquals(expectedOutput, output) - } -} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/TimeStringToIntegerTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/TimeStringToIntegerTest.kt index 6cfc18a622fd..7c8fc1728aa0 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/TimeStringToIntegerTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/TimeStringToIntegerTest.kt @@ -4,9 +4,6 @@ package io.airbyte.cdk.load.data -import io.airbyte.cdk.load.message.DestinationRecord -import io.airbyte.cdk.load.test.util.Root -import io.airbyte.cdk.load.test.util.SchemaRecordBuilder import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test @@ -14,138 +11,66 @@ class TimeStringToIntegerTest { @Test fun testMapDate() { - val mapper = TimeStringToInteger(DestinationRecord.Meta()) - listOf( - "2021-1-1" to 18628, - "2021-01-01" to 18628, - "2021/01/02" to 18629, - "2021.01.03" to 18630, - "2021 Jan 04" to 18631, - "2021-1-1 BC" to -1457318 - ) - .forEach { - Assertions.assertEquals( - IntValue(it.second), - mapper.mapDate(DateValue(it.first), emptyList()), - "Failed for ${it.first} to ${it.second}" - ) - } - } - - private val timestampPairs = - listOf( - "2018-09-15 12:00:00" to 1537012800000000, - "2018-09-15 12:00:00.006542" to 1537012800006542, - "2018/09/15 12:00:00" to 1537012800000000, - "2018.09.15 12:00:00" to 1537012800000000, - "2018 Jul 15 12:00:00" to 1531656000000000, - "2018 Jul 15 12:00:00 GMT+08:00" to 1531627200000000, - "2018 Jul 15 12:00:00GMT+07" to 1531630800000000, - "2021-1-1 01:01:01" to 1609462861000000, - "2021.1.1 01:01:01" to 1609462861000000, - "2021/1/1 01:01:01" to 1609462861000000, - "2021-1-1 01:01:01 +01" to 1609459261000000, - "2021-01-01T01:01:01+01:00" to 1609459261000000, - "2021-01-01T01:01:01.546+01:00" to 1609459261546000, - "2021-01-01 01:01:01" to 1609462861000000, - "2021-01-01 01:01:01 +0000" to 1609462861000000, - "2021/01/01 01:01:01 +0000" to 1609462861000000, - "2021-01-01T01:01:01Z" to 1609462861000000, - "2021-01-01T01:01:01-01:00" to 1609466461000000, - "2021-01-01T01:01:01+01:00" to 1609459261000000, - "2021-01-01 01:01:01 UTC" to 1609462861000000, - "2021-01-01T01:01:01 PST" to 1609491661000000, - "2021-01-01T01:01:01 +0000" to 1609462861000000, - "2021-01-01T01:01:01+0000" to 1609462861000000, - "2021-01-01T01:01:01UTC" to 1609462861000000, - "2021-01-01T01:01:01+01" to 1609459261000000, - "2022-01-23T01:23:45.678-11:30 BC" to -125941863974322000, - "2022-01-23T01:23:45.678-11:30" to 1642942425678000 + val mapper = TimeStringToInteger() + Assertions.assertEquals( + IntegerValue(18628), + mapper.mapDate(DateValue("2021-01-01"), AirbyteValueIdentityMapper.Context()).first, ) + } @Test fun testMapTimestampWithTimezone() { - val mapper = TimeStringToInteger(DestinationRecord.Meta()) - timestampPairs.forEach { - Assertions.assertEquals( - IntegerValue(it.second), - mapper.mapTimestampWithTimezone(TimestampValue(it.first), emptyList()), - "Failed for ${it.first} to ${it.second}" - ) - } + val mapper = TimeStringToInteger() + Assertions.assertEquals( + IntegerValue(1609462861000000), + mapper + .mapTimestampWithTimezone( + TimestampWithTimezoneValue("2021-01-01T01:01:01Z"), + AirbyteValueIdentityMapper.Context() + ) + .first, + ) } @Test fun testMapTimestampWithoutTimezone() { - val mapper = TimeStringToInteger(DestinationRecord.Meta()) - timestampPairs.forEach { - Assertions.assertEquals( - IntegerValue(it.second), - mapper.mapTimestampWithoutTimezone(TimestampValue(it.first), emptyList()), - "Failed for ${it.first} to ${it.second}" - ) - } - } - - private val timePairs = - listOf( - "01:01:01" to 3661000000, - "01:01" to 3660000000, - "12:23:01.541" to 44581541000, - "12:23:01.541214" to 44581541214, - "12:00:00.000000+01:00" to 39600000000, - "10:00:00.000000-01:00" to 39600000000, - "03:30:00.000000+04:00" to 84600000000 + val mapper = TimeStringToInteger() + Assertions.assertEquals( + IntegerValue(1537012800000000), + mapper + .mapTimestampWithoutTimezone( + TimestampWithoutTimezoneValue("2018-09-15T12:00:00"), + AirbyteValueIdentityMapper.Context() + ) + .first, ) + } @Test fun testTimeWithTimezone() { - val mapper = TimeStringToInteger(DestinationRecord.Meta()) - timePairs.forEach { - Assertions.assertEquals( - IntegerValue(it.second), - mapper.mapTimeWithTimezone(TimeValue(it.first), emptyList()), - "Failed for ${it.first} to ${it.second}" - ) - } + val mapper = TimeStringToInteger() + Assertions.assertEquals( + IntegerValue(39600000000), + mapper + .mapTimeWithTimezone( + TimeWithTimezoneValue("12:00:00.000000+01:00"), + AirbyteValueIdentityMapper.Context() + ) + .first, + ) } @Test fun testTimeWithoutTimezone() { - val mapper = TimeStringToInteger(DestinationRecord.Meta()) - timePairs.forEach { - Assertions.assertEquals( - IntegerValue(it.second), - mapper.mapTimeWithoutTimezone(TimeValue(it.first), emptyList()), - "Failed for ${it.first} to ${it.second}" - ) - } - } - - @Test - fun testBasicSchemaBehavior() { - val (inputSchema, expectedOutput) = - SchemaRecordBuilder() - .with(DateType, IntegerType) - .withRecord() - .with(TimestampTypeWithTimezone, IntegerType) - .endRecord() - .with(TimestampTypeWithoutTimezone, IntegerType) - .withRecord() - .with(TimeTypeWithTimezone, IntegerType) - .withRecord() - .with(TimeTypeWithoutTimezone, IntegerType) - .endRecord() - .endRecord() - .withUnion( - expectedInstead = - FieldType(UnionType(listOf(IntegerType, IntegerType)), nullable = false) + val mapper = TimeStringToInteger() + Assertions.assertEquals( + IntegerValue(3661000000), + mapper + .mapTimeWithoutTimezone( + TimeWithoutTimezoneValue("01:01:01"), + AirbyteValueIdentityMapper.Context() ) - .with(DateType) - .with(TimeTypeWithTimezone) - .endUnion() - .build() - val output = TimeStringTypeToIntegerType().map(inputSchema) - Assertions.assertEquals(expectedOutput, output) + .first, + ) } } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/TransformationsTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/TransformationsTest.kt new file mode 100644 index 000000000000..2197f534e2bd --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/TransformationsTest.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data + +import org.junit.jupiter.api.Test + +class TransformationsTest { + @Test + fun `test avro illegal start character`() { + val unsafeName = "1d_view" + assert(Transformations.toAvroSafeName(unsafeName) == "_1d_view") + } + + @Test + fun `test avro special characters`() { + val unsafeName = "1d_view!@#$%^&*()" + assert(Transformations.toAvroSafeName(unsafeName) == "_1d_view__________") + } +} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/UnionTypeToDisjointRecordTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/UnionTypeToDisjointRecordTest.kt index dee9cc9e95a8..d11ea13c3bc8 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/UnionTypeToDisjointRecordTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/UnionTypeToDisjointRecordTest.kt @@ -12,7 +12,7 @@ import org.junit.jupiter.api.Test class UnionTypeToDisjointRecordTest { @Test fun testBasicSchemaBehavior() { - val disjoinRecord = + val disjointRecord = ObjectType( linkedMapOf( "type" to FieldType(StringType, nullable = false), @@ -22,16 +22,8 @@ class UnionTypeToDisjointRecordTest { ) val (inputSchema, expectedOutput) = SchemaRecordBuilder() - .with(UnionType(listOf(StringType))) // union of 1 => ignore - .with(UnionType(listOf(StringType, NullType))) // union of 1 w/ null => ignore - .with( - UnionType(listOf(StringType, IntegerType)), - expected = disjoinRecord - ) // union of 2 => disjoint - .with( - UnionType(listOf(StringType, IntegerType, NullType)), - expected = UnionType(listOf(NullType, disjoinRecord)) - ) // union of 2 w/ null => disjoint + .with(UnionType.of(StringType)) // union of 1 => ignore + .with(UnionType.of(StringType, IntegerType), expected = disjointRecord) .build() val output = UnionTypeToDisjointRecord().map(inputSchema) Assertions.assertEquals(expectedOutput, output) @@ -41,7 +33,8 @@ class UnionTypeToDisjointRecordTest { fun testUnionOfTypesWithSameNameThrows() { val (inputSchema, _) = SchemaRecordBuilder() - .with(UnionType(listOf(ObjectType(linkedMapOf()), ObjectTypeWithoutSchema))) + // Both are mapped to `string` + .with(UnionType.of(ObjectTypeWithEmptySchema, ObjectTypeWithoutSchema)) .build() Assertions.assertThrows(IllegalArgumentException::class.java) { UnionTypeToDisjointRecord().map(inputSchema) diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/json/AirbyteSchemaTypeToJsonSchemaTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/json/AirbyteSchemaTypeToJsonSchemaTest.kt index b4139df4af5e..be9b12d4d375 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/json/AirbyteSchemaTypeToJsonSchemaTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/json/AirbyteSchemaTypeToJsonSchemaTest.kt @@ -4,145 +4,164 @@ package io.airbyte.cdk.load.data.json -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.node.JsonNodeFactory -import com.fasterxml.jackson.databind.node.ObjectNode +import io.airbyte.cdk.load.data.ArrayType +import io.airbyte.cdk.load.data.BooleanType +import io.airbyte.cdk.load.data.DateType +import io.airbyte.cdk.load.data.FieldType +import io.airbyte.cdk.load.data.IntegerType +import io.airbyte.cdk.load.data.NumberType +import io.airbyte.cdk.load.data.ObjectType +import io.airbyte.cdk.load.data.StringType +import io.airbyte.cdk.load.data.TimeTypeWithTimezone +import io.airbyte.cdk.load.data.TimeTypeWithoutTimezone +import io.airbyte.cdk.load.data.TimestampTypeWithTimezone +import io.airbyte.cdk.load.data.TimestampTypeWithoutTimezone +import io.airbyte.cdk.load.data.UnionType +import io.airbyte.cdk.load.util.deserializeToNode +import io.airbyte.cdk.load.util.serializeToString import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test class AirbyteSchemaTypeToJsonSchemaTest { - @Test - fun testRoundTrip() { - val schema = JsonNodeFactory.instance.objectNode() - val props = schema.putObject("properties") - props.putObject("name").put("type", "string").put("required", true) - props.putObject("age").put("type", "integer") - props.putObject("is_cool").put("type", "boolean") - props.putObject("height").put("type", "number") - props.putObject("friends").put("type", "array").putObject("items").put("type", "string") - val subProps = props.putObject("address").put("type", "object").putObject("properties") - subProps.putObject("street").put("type", "string") - subProps.putObject("city").put("type", "string") - props.putObject("null_field").put("type", "null") - val union = props.putObject("nullable_union").putArray("oneOf") - union.add(JsonNodeFactory.instance.objectNode().put("type", "string")) - union.add(JsonNodeFactory.instance.objectNode().put("type", "integer")) - union.add(JsonNodeFactory.instance.objectNode().put("type", "null")) - - val union2 = props.putObject("nonnullable_union") - val union2opts = union2.putArray("oneOf") - union2opts.add(JsonNodeFactory.instance.objectNode().put("type", "string")) - union2opts.add(JsonNodeFactory.instance.objectNode().put("type", "integer")) - union2.put("required", true) - - props.putObject("combined_null").putArray("type").add("string").add("null") - - val combinedDenormalized = props.putObject("combined_denormalized") - combinedDenormalized.putArray("type").add("string").add("object") - combinedDenormalized.putObject("properties").putObject("name").put("type", "string") - - props - .putObject("union_array") - .put("type", "array") - .putArray("items") - .add("string") - .add("integer") - - props.putObject("date").put("type", "string").put("format", "date") - props.putObject("time").put("type", "string").put("format", "time") - props.putObject("timestamp").put("type", "string").put("format", "date-time") - props - .putObject("time_without_timezone") - .put("type", "string") - .put("format", "time") - .put("airbyte_type", "time_without_timezone") - props - .putObject("timestamp_without_timezone") - .put("type", "string") - .put("format", "date-time") - .put("airbyte_type", "timestamp_without_timezone") - - val converted = JsonSchemaToAirbyteType().convert(schema) - val unconverted = AirbyteTypeToJsonSchema().convert(converted) - - val propsOut = unconverted.get("properties") - Assertions.assertEquals(ofType("string", false), propsOut.get("name")) - Assertions.assertEquals(ofType("integer", true), propsOut.get("age")) - Assertions.assertEquals(ofType("boolean", true), propsOut.get("is_cool")) - Assertions.assertEquals(ofType("number", true), propsOut.get("height")) - - val friends = JsonNodeFactory.instance.objectNode() - friends.put("type", "array").replace("items", ofType("string", true)) - Assertions.assertEquals(ofNullable(friends), propsOut.get("friends")) - - val address = JsonNodeFactory.instance.objectNode() - val addressProps = address.put("type", "object").putObject("properties") - addressProps.replace("street", ofType("string", true)) - addressProps.replace("city", ofType("string", true)) - Assertions.assertEquals(ofNullable(address), propsOut.get("address")) - - Assertions.assertEquals(ofType("null", true), propsOut.get("null_field")) - - val nullableUnion = JsonNodeFactory.instance.objectNode() - nullableUnion - .putArray("oneOf") - .add(ofType("string", false)) - .add(ofType("integer", false)) - .add(ofType("null", false)) - Assertions.assertEquals(nullableUnion, propsOut.get("nullable_union")) - - val nonnullableUnion = JsonNodeFactory.instance.objectNode() - nonnullableUnion - .putArray("oneOf") - .add(ofType("string", false)) - .add(ofType("integer", false)) - Assertions.assertEquals(nonnullableUnion, propsOut.get("nonnullable_union")) - - Assertions.assertEquals(ofType("string", true), propsOut.get("combined_null")) - - val combinedDenormed = JsonNodeFactory.instance.objectNode() - val cdObj = ofType("object", false) - cdObj.putObject("properties").replace("name", ofType("string", true)) - combinedDenormed - .putArray("oneOf") - .add(ofType("string", false)) - .add(cdObj) - .add(ofType("null", false)) - Assertions.assertEquals(combinedDenormed, propsOut.get("combined_denormalized")) - - val unionArrayOut = JsonNodeFactory.instance.objectNode() - unionArrayOut - .put("type", "array") - .putObject("items") - .putArray("oneOf") - .add(ofType("string", false)) - .add(ofType("integer", false)) - Assertions.assertEquals(ofNullable(unionArrayOut), propsOut.get("union_array")) - - val timeTypeFieldNames = - listOf("time", "timestamp", "time_without_timezone", "timestamp_without_timezone") - timeTypeFieldNames.forEach { fieldName -> - val expected = props.get(fieldName) as ObjectNode - if (listOf("date-time", "time").contains(expected.get("format").asText())) { - val formatName = expected.get("format").asText().replace("date-time", "timestamp") - if (!expected.has("airbyte_type")) { - expected.put("airbyte_type", "${formatName}_with_timezone") + // A json of every supported type + private val airbyteType = + ObjectType( + mapOf( + "name" to StringType, + "age" to IntegerType, + "is_cool" to BooleanType, + "height" to NumberType, + "alt_integer" to IntegerType, + "friends" to ArrayType(FieldType(StringType, true)), + "mixed_array" to + ArrayType( + FieldType(UnionType.of(StringType, IntegerType), nullable = true) + ), + "address" to + ObjectType( + linkedMapOf( + "street" to FieldType(StringType, true), + "city" to FieldType(StringType, true) + ) + ), + "combined_denormalized" to + ObjectType(linkedMapOf("name" to FieldType(StringType, true))), + "union_array" to + ArrayType(FieldType(UnionType.of(StringType, IntegerType), true)), + "date" to DateType, + "time" to TimeTypeWithTimezone, + "time_without_timezone" to TimeTypeWithoutTimezone, + "timestamp" to TimestampTypeWithTimezone, + "timestamp_without_timezone" to TimestampTypeWithoutTimezone + ) + .map { it.key to FieldType(it.value, nullable = true) } + .let { linkedMapOf(*it.toTypedArray()) } + ) + + // the json equivalent + private val json = + """ + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "age": { + "type": "integer" + }, + "is_cool": { + "type": "boolean" + }, + "height": { + "type": "number" + }, + "alt_integer": { + "type": "integer" + }, + "friends": { + "type": "array", + "items": { + "type": "string" + } + }, + "mixed_array": { + "type": "array", + "items": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + } + }, + "address": { + "type": "object", + "properties": { + "street": { + "type": "string" + }, + "city": { + "type": "string" } + } + }, + "combined_denormalized": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + }, + "union_array": { + "type": "array", + "items": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + } + }, + "date": { + "type": "string", + "format": "date" + }, + "time": { + "type": "string", + "format": "time", + "airbyte_type": "time_with_timezone" + }, + "time_without_timezone": { + "type": "string", + "format": "time", + "airbyte_type": "time_without_timezone" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "timestamp_without_timezone": { + "type": "string", + "format": "date-time", + "airbyte_type": "timestamp_without_timezone" } - Assertions.assertEquals(ofNullable(expected), propsOut.get(fieldName)) + } } - } + """.trimIndent() - private fun ofType(type: String, nullable: Boolean = true): ObjectNode = - if (nullable) { - ofNullable(ofType(type, false)) - } else { - JsonNodeFactory.instance.objectNode().put("type", type) - } - - private fun ofNullable(typeNode: JsonNode): ObjectNode { - val schema = JsonNodeFactory.instance.objectNode() - schema.putArray("oneOf").add(typeNode).add(ofType("null", false)) - return schema + @Test + fun testToJsonSchema() { + val expected = json.deserializeToNode().serializeToString() + val actual = AirbyteTypeToJsonSchema().convert(airbyteType).serializeToString() + Assertions.assertEquals(expected, actual) } } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/json/AirbyteValueToJsonTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/json/AirbyteValueToJsonTest.kt index 4d2bede2c25a..17a7e7f43f34 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/json/AirbyteValueToJsonTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/json/AirbyteValueToJsonTest.kt @@ -4,30 +4,12 @@ package io.airbyte.cdk.load.data.json -import io.airbyte.cdk.load.data.ArrayType import io.airbyte.cdk.load.data.ArrayValue -import io.airbyte.cdk.load.data.BooleanType import io.airbyte.cdk.load.data.BooleanValue -import io.airbyte.cdk.load.data.DateType -import io.airbyte.cdk.load.data.DateValue -import io.airbyte.cdk.load.data.FieldType -import io.airbyte.cdk.load.data.IntegerType import io.airbyte.cdk.load.data.IntegerValue -import io.airbyte.cdk.load.data.NullType -import io.airbyte.cdk.load.data.NullValue -import io.airbyte.cdk.load.data.NumberType import io.airbyte.cdk.load.data.NumberValue -import io.airbyte.cdk.load.data.ObjectType import io.airbyte.cdk.load.data.ObjectValue -import io.airbyte.cdk.load.data.StringType import io.airbyte.cdk.load.data.StringValue -import io.airbyte.cdk.load.data.TimeTypeWithTimezone -import io.airbyte.cdk.load.data.TimeTypeWithoutTimezone -import io.airbyte.cdk.load.data.TimeValue -import io.airbyte.cdk.load.data.TimestampTypeWithTimezone -import io.airbyte.cdk.load.data.TimestampTypeWithoutTimezone -import io.airbyte.cdk.load.data.TimestampValue -import io.airbyte.cdk.load.data.UnionType import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test @@ -49,63 +31,10 @@ class AirbyteValueToJsonTest { "city" to StringValue("San Francisco") ) ), - "null_field" to NullValue, - "nullable_union" to IntegerValue(42), - "nonnullable_union" to StringValue("hello"), - "combined_null" to StringValue("hello"), - "combined_denormalized" to - ObjectValue(linkedMapOf("name" to StringValue("hello"))), - "union_array" to ArrayValue(listOf(StringValue("hello"), IntegerValue(42))), - "date" to DateValue("2021-01-01"), - "time" to TimeValue("12:00:00"), - "timestamp" to TimestampValue("2021-01-01T12:00:00Z"), - "time_without_timezone" to TimeValue("12:00:00"), - "timestamp_without_timezone" to TimestampValue("2021-01-01T12:00:00") - ) - ) - val schema = - ObjectType( - linkedMapOf( - "name" to FieldType(StringType, true), - "age" to FieldType(IntegerType, false), - "is_cool" to FieldType(BooleanType, false), - "height" to FieldType(NumberType, false), - "friends" to FieldType(ArrayType(FieldType(StringType, true)), false), - "address" to - FieldType( - ObjectType( - linkedMapOf( - "street" to FieldType(StringType, true), - "city" to FieldType(StringType, true) - ) - ), - false - ), - "null_field" to FieldType(NullType, false), - "nullable_union" to - FieldType(UnionType(listOf(StringType, IntegerType, NullType)), false), - "nonnullable_union" to - FieldType(UnionType(listOf(StringType, IntegerType)), true), - "combined_null" to FieldType(UnionType(listOf(StringType, NullType)), false), - "combined_denormalized" to - FieldType( - ObjectType(linkedMapOf("name" to FieldType(StringType, true))), - false - ), - "union_array" to - FieldType( - ArrayType(FieldType(UnionType(listOf(StringType, IntegerType)), true)), - true - ), - "date" to FieldType(DateType, false), - "time" to FieldType(TimeTypeWithoutTimezone, false), - "timestamp" to FieldType(TimestampTypeWithoutTimezone, false), - "time_without_timezone" to FieldType(TimeTypeWithTimezone, false), - "timestamp_without_timezone" to FieldType(TimestampTypeWithTimezone, false) ) ) val jsonValue = AirbyteValueToJson().convert(airbyteValue) - val roundTripValue = JsonToAirbyteValue().convert(jsonValue, schema) + val roundTripValue = JsonToAirbyteValue().convert(jsonValue) Assertions.assertEquals(airbyteValue, roundTripValue) } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/json/JsonSchemaToAirbyteSchemaTypeTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/json/JsonSchemaToAirbyteSchemaTypeTest.kt index 6264dea2dca4..2b6cc39f0fd0 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/json/JsonSchemaToAirbyteSchemaTypeTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/json/JsonSchemaToAirbyteSchemaTypeTest.kt @@ -12,7 +12,6 @@ import io.airbyte.cdk.load.data.BooleanType import io.airbyte.cdk.load.data.DateType import io.airbyte.cdk.load.data.FieldType import io.airbyte.cdk.load.data.IntegerType -import io.airbyte.cdk.load.data.NullType import io.airbyte.cdk.load.data.NumberType import io.airbyte.cdk.load.data.ObjectType import io.airbyte.cdk.load.data.ObjectTypeWithEmptySchema @@ -23,7 +22,7 @@ import io.airbyte.cdk.load.data.TimeTypeWithoutTimezone import io.airbyte.cdk.load.data.TimestampTypeWithTimezone import io.airbyte.cdk.load.data.TimestampTypeWithoutTimezone import io.airbyte.cdk.load.data.UnionType -import io.airbyte.cdk.util.Jsons +import io.airbyte.cdk.load.util.deserializeToNode import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test @@ -32,13 +31,6 @@ class JsonSchemaToAirbyteSchemaTypeTest { return JsonNodeFactory.instance.objectNode().put("type", type) } - @Test - fun testNull() { - val nullType = ofType("null") - val airbyteType = JsonSchemaToAirbyteType().convert(nullType) - Assertions.assertTrue(airbyteType is NullType) - } - @Test fun testString() { val stringType = ofType("string") @@ -60,6 +52,14 @@ class JsonSchemaToAirbyteSchemaTypeTest { Assertions.assertTrue(airbyteType is IntegerType) } + /** Note: this is nonstandard, but some sources apparently use it. */ + @Test + fun testInt() { + val integerType = ofType("int") + val airbyteType = JsonSchemaToAirbyteType().convert(integerType) + Assertions.assertTrue(airbyteType is IntegerType) + } + @Test fun testNumber() { val numberType = ofType("number") @@ -236,8 +236,7 @@ class JsonSchemaToAirbyteSchemaTypeTest { @Test fun testHandleNonstandardFields() { val inputSchema = - Jsons.readTree( - """ + """ { "type": [ "string", @@ -246,9 +245,17 @@ class JsonSchemaToAirbyteSchemaTypeTest { "description": "foo", "some_random_other_property": "lol, lmao, isn't jsonschema great" } - """.trimIndent() - ) as ObjectNode + """ + .trimIndent() + .deserializeToNode() as ObjectNode val airbyteType = JsonSchemaToAirbyteType().convert(inputSchema) - Assertions.assertEquals(UnionType(listOf(StringType, IntegerType)), airbyteType) + Assertions.assertEquals(UnionType.of(StringType, IntegerType), airbyteType) + } + + @Test + fun testUnrecognizedStringFormats() { + val schemaNode = ofType("string").put("format", "foo") + val airbyteType = JsonSchemaToAirbyteType().convert(schemaNode) + Assertions.assertTrue(airbyteType is StringType) } } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/json/JsonToAirbyteValueTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/json/JsonToAirbyteValueTest.kt index 515099026352..dfddd5e9854b 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/json/JsonToAirbyteValueTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/data/json/JsonToAirbyteValueTest.kt @@ -5,83 +5,52 @@ package io.airbyte.cdk.load.data.json import com.fasterxml.jackson.databind.node.JsonNodeFactory -import io.airbyte.cdk.load.data.ArrayType -import io.airbyte.cdk.load.data.ArrayTypeWithoutSchema import io.airbyte.cdk.load.data.ArrayValue -import io.airbyte.cdk.load.data.BooleanType import io.airbyte.cdk.load.data.BooleanValue -import io.airbyte.cdk.load.data.DateType -import io.airbyte.cdk.load.data.DateValue -import io.airbyte.cdk.load.data.FieldType -import io.airbyte.cdk.load.data.IntegerType import io.airbyte.cdk.load.data.IntegerValue -import io.airbyte.cdk.load.data.NullType -import io.airbyte.cdk.load.data.NullValue -import io.airbyte.cdk.load.data.NumberType import io.airbyte.cdk.load.data.NumberValue -import io.airbyte.cdk.load.data.ObjectType -import io.airbyte.cdk.load.data.ObjectTypeWithEmptySchema -import io.airbyte.cdk.load.data.ObjectTypeWithoutSchema import io.airbyte.cdk.load.data.ObjectValue -import io.airbyte.cdk.load.data.StringType import io.airbyte.cdk.load.data.StringValue -import io.airbyte.cdk.load.data.TimeTypeWithTimezone -import io.airbyte.cdk.load.data.TimeValue -import io.airbyte.cdk.load.data.TimestampTypeWithTimezone -import io.airbyte.cdk.load.data.TimestampValue -import io.airbyte.cdk.load.data.UnionType -import io.airbyte.cdk.util.Jsons import java.math.BigDecimal +import java.math.BigInteger import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test class JsonToAirbyteValueTest { - @Test - fun testNull() { - val value = JsonToAirbyteValue().convert(JsonNodeFactory.instance.nullNode(), NullType) - Assertions.assertTrue(value is NullValue) - } @Test fun testString() { - val value = - JsonToAirbyteValue().convert(JsonNodeFactory.instance.textNode("hello"), StringType) + val value = JsonToAirbyteValue().convert(JsonNodeFactory.instance.textNode("hello")) Assertions.assertTrue(value is StringValue) Assertions.assertEquals("hello", (value as StringValue).value) } @Test fun testBoolean() { - val value = - JsonToAirbyteValue().convert(JsonNodeFactory.instance.booleanNode(true), BooleanType) + val value = JsonToAirbyteValue().convert(JsonNodeFactory.instance.booleanNode(true)) Assertions.assertTrue(value is BooleanValue) Assertions.assertEquals(true, (value as BooleanValue).value) } @Test fun testInteger() { - val value = - JsonToAirbyteValue().convert(JsonNodeFactory.instance.numberNode(42), IntegerType) + val value = JsonToAirbyteValue().convert(JsonNodeFactory.instance.numberNode(42)) Assertions.assertTrue(value is IntegerValue) - Assertions.assertEquals(42, (value as IntegerValue).value) + Assertions.assertEquals(BigInteger.valueOf(42), (value as IntegerValue).value) } @Test fun testNumber() { - val value = - JsonToAirbyteValue().convert(JsonNodeFactory.instance.numberNode(42), NumberType) + val value = JsonToAirbyteValue().convert(JsonNodeFactory.instance.numberNode(42.1)) Assertions.assertTrue(value is NumberValue) - Assertions.assertEquals(BigDecimal(42), (value as NumberValue).value) + Assertions.assertEquals(BigDecimal("42.1"), (value as NumberValue).value) } @Test fun testArray() { val value = JsonToAirbyteValue() - .convert( - JsonNodeFactory.instance.arrayNode().add("hello").add("world"), - ArrayType(FieldType(StringType, true)) - ) + .convert(JsonNodeFactory.instance.arrayNode().add("hello").add("world")) Assertions.assertTrue(value is ArrayValue) val arrayValue = value as ArrayValue Assertions.assertEquals(2, arrayValue.values.size) @@ -91,119 +60,14 @@ class JsonToAirbyteValueTest { Assertions.assertEquals("world", (arrayValue.values[1] as StringValue).value) } - @Test - fun testArrayWithoutSchema() { - val value = - JsonToAirbyteValue() - .convert( - JsonNodeFactory.instance.arrayNode().add("hello").add("world"), - ArrayTypeWithoutSchema - ) - Assertions.assertTrue(value is ArrayValue, "Expected ArrayValue, got $value") - val arrayValue = value as ArrayValue - Assertions.assertEquals(2, arrayValue.values.size) - Assertions.assertTrue(arrayValue.values[0] is StringValue) - Assertions.assertEquals("hello", (arrayValue.values[0] as StringValue).value) - Assertions.assertTrue(arrayValue.values[1] is StringValue) - Assertions.assertEquals("world", (arrayValue.values[1] as StringValue).value) - } - @Test fun testObject() { val value = - JsonToAirbyteValue() - .convert( - JsonNodeFactory.instance.objectNode().put("name", "world"), - ObjectType(linkedMapOf("name" to FieldType(StringType, true))) - ) + JsonToAirbyteValue().convert(JsonNodeFactory.instance.objectNode().put("name", "world")) Assertions.assertTrue(value is ObjectValue) val objectValue = value as ObjectValue Assertions.assertEquals(1, objectValue.values.size) Assertions.assertTrue(objectValue.values["name"] is StringValue) Assertions.assertEquals("world", (objectValue.values["name"] as StringValue).value) } - - @Test - fun testObjectWithoutSchema() { - listOf(ObjectTypeWithoutSchema, ObjectTypeWithEmptySchema).forEach { - val value = - JsonToAirbyteValue() - .convert(JsonNodeFactory.instance.objectNode().put("name", "world"), it) - Assertions.assertTrue(value is ObjectValue) - val objectValue = value as ObjectValue - Assertions.assertEquals(1, objectValue.values.size) - Assertions.assertTrue(objectValue.values["name"] is StringValue) - Assertions.assertEquals("world", (objectValue.values["name"] as StringValue).value) - } - } - - @Test - fun testUnion() { - val stringValue = - JsonToAirbyteValue() - .convert( - JsonNodeFactory.instance.textNode("hello"), - UnionType(listOf(StringType, IntegerType)) - ) - Assertions.assertTrue(stringValue is StringValue) - Assertions.assertEquals("hello", (stringValue as StringValue).value) - - val intValue = - JsonToAirbyteValue() - .convert( - JsonNodeFactory.instance.numberNode(42), - UnionType(listOf(StringType, IntegerType)) - ) - Assertions.assertTrue(intValue is IntegerValue) - Assertions.assertEquals(42, (intValue as IntegerValue).value) - } - - @Test - fun testDate() { - val value = - JsonToAirbyteValue().convert(JsonNodeFactory.instance.textNode("2021-01-01"), DateType) - Assertions.assertTrue(value is DateValue) - Assertions.assertEquals("2021-01-01", (value as DateValue).value) - } - - @Test - fun testTimestamp() { - val value = - JsonToAirbyteValue() - .convert( - JsonNodeFactory.instance.textNode("2021-01-01T00:00:00Z"), - TimestampTypeWithTimezone - ) - Assertions.assertTrue(value is TimestampValue) - Assertions.assertEquals("2021-01-01T00:00:00Z", (value as TimestampValue).value) - } - - @Test - fun testTime() { - val value = - JsonToAirbyteValue() - .convert(JsonNodeFactory.instance.textNode("00:00:00"), TimeTypeWithTimezone) - Assertions.assertTrue(value is TimeValue) - Assertions.assertEquals("00:00:00", (value as TimeValue).value) - } - - @Test - fun testMissingObjectField() { - val value = - JsonToAirbyteValue() - .convert( - Jsons.readTree("""{"foo": 1}"""), - ObjectType( - properties = - linkedMapOf( - "foo" to FieldType(IntegerType, nullable = true), - "bar" to FieldType(IntegerType, nullable = true), - ) - ) - ) - Assertions.assertEquals( - ObjectValue(linkedMapOf("foo" to IntegerValue(1))), - value, - ) - } } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/message/DestinationMessageTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/message/DestinationMessageTest.kt index 10b0ea1d89f6..2fbc6af691dd 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/message/DestinationMessageTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/message/DestinationMessageTest.kt @@ -8,7 +8,9 @@ import io.airbyte.cdk.load.command.Append import io.airbyte.cdk.load.command.DestinationCatalog import io.airbyte.cdk.load.command.DestinationStream import io.airbyte.cdk.load.data.ObjectTypeWithEmptySchema -import io.airbyte.protocol.models.Jsons +import io.airbyte.cdk.load.util.deserializeToClass +import io.airbyte.cdk.load.util.deserializeToNode +import io.airbyte.cdk.load.util.serializeToString import io.airbyte.protocol.models.v0.AirbyteGlobalState import io.airbyte.protocol.models.v0.AirbyteMessage import io.airbyte.protocol.models.v0.AirbyteRecordMessage @@ -21,12 +23,13 @@ import io.airbyte.protocol.models.v0.AirbyteStreamStatusTraceMessage import io.airbyte.protocol.models.v0.AirbyteTraceMessage import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.Arguments import org.junit.jupiter.params.provider.MethodSource class DestinationMessageTest { - private val factory = + private fun factory(isFileTransferEnabled: Boolean) = DestinationMessageFactory( DestinationCatalog( listOf( @@ -39,14 +42,39 @@ class DestinationMessageTest { syncId = 42, ) ) - ) + ), + isFileTransferEnabled ) + private fun convert( + factory: DestinationMessageFactory, + message: AirbyteMessage, + ): DestinationMessage { + val serialized = message.serializeToString() + return factory.fromAirbyteMessage( + // We have to set some stuff in additionalProperties, so force the protocol model back + // to a serialized representation and back. + // This avoids issues with e.g. `additionalProperties.put("foo", 12L)`: + // working directly with that object, `additionalProperties["foo"]` returns `Long?`, + // whereas converting to JSON yields `{"foo": 12}`, which then deserializes back out + // as `Int?`. + // Fortunately, the protocol models are (by definition) round-trippable through JSON. + serialized.deserializeToClass(AirbyteMessage::class.java), + serialized, + ) + } + @ParameterizedTest @MethodSource("roundTrippableMessages") - fun testRoundTrip(message: AirbyteMessage) { - val roundTripped = - factory.fromAirbyteMessage(message, Jsons.serialize(message)).asProtocolMessage() + fun testRoundTripRecord(message: AirbyteMessage) { + val roundTripped = convert(factory(false), message).asProtocolMessage() + Assertions.assertEquals(message, roundTripped) + } + + @ParameterizedTest + @MethodSource("roundTrippableFileMessages") + fun testRoundTripFile(message: AirbyteMessage) { + val roundTripped = convert(factory(true), message).asProtocolMessage() Assertions.assertEquals(message, roundTripped) } @@ -67,17 +95,22 @@ class DestinationMessageTest { ) // Note: only source stats, no destination stats .withSourceStats(AirbyteStateStats().withRecordCount(2.0)) + .withAdditionalProperty("id", 1234) ) - val parsedMessage = - factory.fromAirbyteMessage(inputMessage, Jsons.serialize(inputMessage)) - as StreamCheckpoint + val parsedMessage = convert(factory(false), inputMessage) as StreamCheckpoint Assertions.assertEquals( - inputMessage.also { - it.state.destinationStats = AirbyteStateStats().withRecordCount(3.0) - }, - parsedMessage.withDestinationStats(CheckpointMessage.Stats(3)).asProtocolMessage(), + // we represent the state message ID as a long, but jackson sees that 1234 can be Int, + // and Int(1234) != Long(1234). (and additionalProperties is just a Map) + // So we just compare the serialized protocol messages. + inputMessage + .also { it.state.destinationStats = AirbyteStateStats().withRecordCount(3.0) } + .serializeToString(), + parsedMessage + .withDestinationStats(CheckpointMessage.Stats(3)) + .asProtocolMessage() + .serializeToString() ) } @@ -102,26 +135,26 @@ class DestinationMessageTest { ) // Note: only source stats, no destination stats .withSourceStats(AirbyteStateStats().withRecordCount(2.0)) + .withAdditionalProperty("id", 1234) ) - val parsedMessage = - factory.fromAirbyteMessage( - inputMessage, - Jsons.serialize(inputMessage), - ) as GlobalCheckpoint + val parsedMessage = convert(factory(false), inputMessage) as GlobalCheckpoint Assertions.assertEquals( - inputMessage.also { - it.state.destinationStats = AirbyteStateStats().withRecordCount(3.0) - }, - parsedMessage.withDestinationStats(CheckpointMessage.Stats(3)).asProtocolMessage(), + inputMessage + .also { it.state.destinationStats = AirbyteStateStats().withRecordCount(3.0) } + .serializeToString(), + parsedMessage + .withDestinationStats(CheckpointMessage.Stats(3)) + .asProtocolMessage() + .serializeToString() ) } companion object { private val descriptor = DestinationStream.Descriptor("namespace", "name") - private val blob1 = Jsons.deserialize("""{"foo": "bar"}""") - private val blob2 = Jsons.deserialize("""{"foo": "bar"}""") + private val blob1 = """{"foo": "bar"}""".deserializeToNode() + private val blob2 = """{"foo": "bar"}""".deserializeToNode() @JvmStatic fun roundTrippableMessages(): List = @@ -189,5 +222,83 @@ class DestinationMessageTest { ), ) .map { Arguments.of(it) } + + @JvmStatic + fun roundTrippableFileMessages(): List { + val file = + mapOf( + "file_url" to "file://foo/bar", + "file_relative_path" to "foo/bar", + "source_file_url" to "file://source/foo/bar", + "modified" to 123L, + "bytes" to 9001L, + ) + + return listOf( + AirbyteMessage() + .withType(AirbyteMessage.Type.RECORD) + .withRecord( + AirbyteRecordMessage() + .withStream("name") + .withNamespace("namespace") + .withEmittedAt(1234) + .withAdditionalProperty("file", file) + ), + AirbyteMessage() + .withType(AirbyteMessage.Type.TRACE) + .withTrace( + AirbyteTraceMessage() + .withType(AirbyteTraceMessage.Type.STREAM_STATUS) + .withEmittedAt(1234.0) + .withStreamStatus( + AirbyteStreamStatusTraceMessage() + // Intentionally no "reasons" here - destinations never + // inspect that + // field, so it's not round-trippable + .withStreamDescriptor(descriptor.asProtocolObject()) + .withStatus( + AirbyteStreamStatusTraceMessage.AirbyteStreamStatus + .COMPLETE + ) + ) + ), + AirbyteMessage() + .withType(AirbyteMessage.Type.TRACE) + .withTrace( + AirbyteTraceMessage() + .withType(AirbyteTraceMessage.Type.STREAM_STATUS) + .withEmittedAt(1234.0) + .withStreamStatus( + AirbyteStreamStatusTraceMessage() + // Intentionally no "reasons" here - destinations never + // inspect that + // field, so it's not round-trippable + .withStreamDescriptor(descriptor.asProtocolObject()) + .withStatus( + AirbyteStreamStatusTraceMessage.AirbyteStreamStatus + .INCOMPLETE + ) + ) + ), + ) + .map { Arguments.of(it) } + } + } + + @Test + fun testNullStreamState() { + val inputMessage = + AirbyteMessage() + .withType(AirbyteMessage.Type.STATE) + .withState( + AirbyteStateMessage() + .withType(AirbyteStateMessage.AirbyteStateType.STREAM) + .withStream( + AirbyteStreamState().withStreamDescriptor(descriptor.asProtocolObject()) + ) + .withSourceStats(AirbyteStateStats().withRecordCount(2.0)) + ) + + assertDoesNotThrow { convert(factory(false), inputMessage) as StreamCheckpoint } } } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/message/MultiProducerChannelTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/message/MultiProducerChannelTest.kt new file mode 100644 index 000000000000..4156c9a220f9 --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/message/MultiProducerChannelTest.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.message + +import io.mockk.coVerify +import io.mockk.impl.annotations.MockK +import io.mockk.junit5.MockKExtension +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(MockKExtension::class) +class MultiProducerChannelTest { + @MockK(relaxed = true) lateinit var wrapped: Channel + + private lateinit var channel: MultiProducerChannel + + val size = 3L + + @BeforeEach + fun setup() { + channel = MultiProducerChannel(size, wrapped, "test") + } + + @Test + fun `does not close until the expected number of producers have closed`() = runTest { + channel.close() + channel.close() + + coVerify(exactly = 0) { wrapped.close() } + } + + @Test + fun `closes underlying channel when no producers are registered`() = runTest { + channel.close() + channel.close() + channel.close() + coVerify(exactly = 1) { wrapped.close() } + } + + @Test + fun `subsequent calls to to close are idempotent`() = runTest { + channel.close() + channel.close() + channel.close() + channel.close() + coVerify(exactly = 1) { wrapped.close() } + } +} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/CheckpointManagerTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/CheckpointManagerTest.kt index 246f96a8120d..3a6aabdaa86f 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/CheckpointManagerTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/CheckpointManagerTest.kt @@ -446,7 +446,12 @@ class CheckpointManagerTest { it.persistedRanges.forEach { (stream, ranges) -> val mockBatch = SimpleBatch(state = Batch.State.PERSISTED) val rangeSet = TreeRangeSet.create(ranges) - val mockBatchEnvelope = BatchEnvelope(batch = mockBatch, ranges = rangeSet) + val mockBatchEnvelope = + BatchEnvelope( + batch = mockBatch, + ranges = rangeSet, + streamDescriptor = stream.descriptor + ) syncManager .getStreamManager(stream.descriptor) .updateBatchState(mockBatchEnvelope) diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/DefaultFlushStrategyTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/DefaultFlushStrategyTest.kt index cc277e5e3ce9..bee3ac1c4552 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/DefaultFlushStrategyTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/DefaultFlushStrategyTest.kt @@ -37,13 +37,25 @@ class DefaultFlushStrategyTest { fun testFlushByByteSize(flushStrategy: DefaultFlushStrategy, config: DestinationConfiguration) = runTest { Assertions.assertFalse( - flushStrategy.shouldFlush(stream1, Range.all(), config.recordBatchSizeBytes - 1L) + flushStrategy.shouldFlush( + stream1.descriptor, + Range.all(), + config.recordBatchSizeBytes - 1L + ) ) Assertions.assertTrue( - flushStrategy.shouldFlush(stream1, Range.all(), config.recordBatchSizeBytes) + flushStrategy.shouldFlush( + stream1.descriptor, + Range.all(), + config.recordBatchSizeBytes + ) ) Assertions.assertTrue( - flushStrategy.shouldFlush(stream1, Range.all(), config.recordBatchSizeBytes * 1000L) + flushStrategy.shouldFlush( + stream1.descriptor, + Range.all(), + config.recordBatchSizeBytes * 1000L + ) ) } @@ -57,46 +69,46 @@ class DefaultFlushStrategyTest { val insufficientSize = config.recordBatchSizeBytes - 1L Assertions.assertFalse( - flushStrategy.shouldFlush(stream1, Range.all(), insufficientSize), + flushStrategy.shouldFlush(stream1.descriptor, Range.all(), insufficientSize), "Should not flush even with whole range if no event" ) forceFlushEventProducer.publish(ForceFlushEvent(mapOf(stream1.descriptor to 42L))) Assertions.assertFalse( - flushStrategy.shouldFlush(stream1, Range.closed(0, 41), insufficientSize), + flushStrategy.shouldFlush(stream1.descriptor, Range.closed(0, 41), insufficientSize), "Should not flush if index is not in range" ) Assertions.assertTrue( - flushStrategy.shouldFlush(stream1, Range.closed(0, 42), insufficientSize), + flushStrategy.shouldFlush(stream1.descriptor, Range.closed(0, 42), insufficientSize), "Should flush if index is in range" ) Assertions.assertFalse( - flushStrategy.shouldFlush(stream2, Range.closed(0, 42), insufficientSize), + flushStrategy.shouldFlush(stream2.descriptor, Range.closed(0, 42), insufficientSize), "Should not flush other streams" ) forceFlushEventProducer.publish(ForceFlushEvent(mapOf(stream2.descriptor to 200L))) Assertions.assertTrue( - flushStrategy.shouldFlush(stream2, Range.closed(0, 200), insufficientSize), + flushStrategy.shouldFlush(stream2.descriptor, Range.closed(0, 200), insufficientSize), "(Unless they also have flush points)" ) Assertions.assertTrue( - flushStrategy.shouldFlush(stream1, Range.closed(42, 100), insufficientSize), + flushStrategy.shouldFlush(stream1.descriptor, Range.closed(42, 100), insufficientSize), "Should flush even if barely in range" ) Assertions.assertFalse( - flushStrategy.shouldFlush(stream1, Range.closed(43, 100), insufficientSize), + flushStrategy.shouldFlush(stream1.descriptor, Range.closed(43, 100), insufficientSize), "Should not flush if index has been passed" ) forceFlushEventProducer.publish(ForceFlushEvent(mapOf(stream1.descriptor to 100L))) Assertions.assertFalse( - flushStrategy.shouldFlush(stream1, Range.closed(0, 42), insufficientSize), + flushStrategy.shouldFlush(stream1.descriptor, Range.closed(0, 42), insufficientSize), "New events indexes should invalidate old ones" ) Assertions.assertTrue( - flushStrategy.shouldFlush(stream1, Range.closed(43, 100), insufficientSize), + flushStrategy.shouldFlush(stream1.descriptor, Range.closed(43, 100), insufficientSize), "New event indexes should be honored" ) } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/MemoryManagerTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/MemoryManagerTest.kt deleted file mode 100644 index b2c66db6eeaf..000000000000 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/MemoryManagerTest.kt +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.cdk.load.state - -import io.micronaut.context.annotation.Replaces -import io.micronaut.context.annotation.Requires -import io.micronaut.test.extensions.junit5.annotation.MicronautTest -import jakarta.inject.Singleton -import java.util.concurrent.atomic.AtomicBoolean -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.test.runTest -import kotlinx.coroutines.withContext -import kotlinx.coroutines.withTimeout -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test - -@MicronautTest(environments = ["MemoryManagerTest"]) -class MemoryManagerTest { - @Singleton - @Replaces(MemoryManager::class) - @Requires(env = ["MemoryManagerTest"]) - class MockAvailableMemoryProvider : AvailableMemoryProvider { - override val availableMemoryBytes: Long = 1000 - } - - @Test - fun testReserveBlocking() = runTest { - val memoryManager = MemoryManager(MockAvailableMemoryProvider()) - val reserved = AtomicBoolean(false) - - try { - withTimeout(5000) { memoryManager.reserveBlocking(900, this) } - } catch (e: Exception) { - Assertions.fail("Failed to reserve memory") - } - - Assertions.assertEquals(100, memoryManager.remainingMemoryBytes) - - val job = launch { - memoryManager.reserveBlocking(200, this) - reserved.set(true) - } - - memoryManager.reserveBlocking(0, this) - Assertions.assertFalse(reserved.get()) - - memoryManager.release(50) - memoryManager.reserveBlocking(0, this) - Assertions.assertEquals(150, memoryManager.remainingMemoryBytes) - Assertions.assertFalse(reserved.get()) - - memoryManager.release(25) - memoryManager.reserveBlocking(0, this) - Assertions.assertEquals(175, memoryManager.remainingMemoryBytes) - Assertions.assertFalse(reserved.get()) - - memoryManager.release(25) - try { - withTimeout(5000) { job.join() } - } catch (e: Exception) { - Assertions.fail("Failed to unblock reserving memory") - } - Assertions.assertEquals(0, memoryManager.remainingMemoryBytes) - Assertions.assertTrue(reserved.get()) - } - - @Test - fun testReserveBlockingMultithreaded() = runTest { - val memoryManager = MemoryManager(MockAvailableMemoryProvider()) - withContext(Dispatchers.IO) { - memoryManager.reserveBlocking(1000, this) - Assertions.assertEquals(0, memoryManager.remainingMemoryBytes) - val nIterations = 100000 - - val jobs = - (0 until nIterations).map { launch { memoryManager.reserveBlocking(10, this) } } - - repeat(nIterations) { - memoryManager.release(10) - Assertions.assertTrue( - memoryManager.remainingMemoryBytes >= 0, - "Remaining memory is negative: ${memoryManager.remainingMemoryBytes}" - ) - } - jobs.forEach { it.join() } - Assertions.assertEquals(0, memoryManager.remainingMemoryBytes) - } - } - - @Test - fun testRequestingMoreThanAvailableThrows() = runTest { - val memoryManager = MemoryManager(MockAvailableMemoryProvider()) - try { - memoryManager.reserveBlocking(1001, this) - } catch (e: IllegalArgumentException) { - return@runTest - } - Assertions.fail("Requesting more memory than available should throw an exception") - } - - @Test - fun testReservations() = runTest { - val memoryManager = MemoryManager(MockAvailableMemoryProvider()) - val reservation = memoryManager.reserveBlocking(100, this) - Assertions.assertEquals(900, memoryManager.remainingMemoryBytes) - reservation.release() - Assertions.assertEquals(1000, memoryManager.remainingMemoryBytes) - } -} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/ReservationManagerTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/ReservationManagerTest.kt new file mode 100644 index 000000000000..67ace29a60fb --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/ReservationManagerTest.kt @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.state + +import java.util.concurrent.atomic.AtomicBoolean +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.withContext +import kotlinx.coroutines.withTimeout +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class ReservationManagerTest { + @Test + fun testReserve() = runTest { + val manager = ReservationManager(1000) + val reserved = AtomicBoolean(false) + + try { + withTimeout(5000) { manager.reserve(900, this) } + } catch (e: Exception) { + Assertions.fail("Failed to reserve memory") + } + + Assertions.assertEquals(100, manager.remainingCapacityBytes) + + val job = launch { + manager.reserve(200, this) + reserved.set(true) + } + + manager.reserve(0, this) + Assertions.assertFalse(reserved.get()) + + manager.release(50) + manager.reserve(0, this) + Assertions.assertEquals(150, manager.remainingCapacityBytes) + Assertions.assertFalse(reserved.get()) + + manager.release(25) + manager.reserve(0, this) + Assertions.assertEquals(175, manager.remainingCapacityBytes) + Assertions.assertFalse(reserved.get()) + + manager.release(25) + try { + withTimeout(5000) { job.join() } + } catch (e: Exception) { + Assertions.fail("Failed to unblock reserving memory") + } + Assertions.assertEquals(0, manager.remainingCapacityBytes) + Assertions.assertTrue(reserved.get()) + } + + @Test + fun testReserveMultithreaded() = runTest { + val manager = ReservationManager(1000) + withContext(Dispatchers.IO) { + manager.reserve(1000, this) + Assertions.assertEquals(0, manager.remainingCapacityBytes) + val nIterations = 100000 + + val jobs = (0 until nIterations).map { launch { manager.reserve(10, this) } } + + repeat(nIterations) { + manager.release(10) + Assertions.assertTrue( + manager.remainingCapacityBytes >= 0, + "Remaining memory is negative: ${manager.remainingCapacityBytes}" + ) + } + jobs.forEach { it.join() } + Assertions.assertEquals(0, manager.remainingCapacityBytes) + } + } + + @Test + fun testRequestingMoreThanAvailableThrows() = runTest { + val manager = ReservationManager(1000) + try { + manager.reserve(1001, this) + } catch (e: IllegalArgumentException) { + return@runTest + } + Assertions.fail("Requesting more memory than available should throw an exception") + } + + @Test + fun testReservations() = runTest { + val manager = ReservationManager(1000) + val reservation = manager.reserve(100, this) + Assertions.assertEquals(900, manager.remainingCapacityBytes) + reservation.release() + Assertions.assertEquals(1000, manager.remainingCapacityBytes) + } +} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/StreamManagerTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/StreamManagerTest.kt index ceb8f009fb82..adb2b4052da1 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/StreamManagerTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/StreamManagerTest.kt @@ -62,17 +62,19 @@ class StreamManagerTest { val manager = DefaultStreamManager(stream1) val channel = Channel(Channel.UNLIMITED) - launch { channel.send(manager.awaitStreamResult() is StreamSucceeded) } + launch { channel.send(manager.awaitStreamResult() is StreamProcessingSucceeded) } delay(500) Assertions.assertTrue(channel.tryReceive().isFailure) - Assertions.assertThrows(IllegalStateException::class.java) { manager.markSucceeded() } - manager.markEndOfStream() + Assertions.assertThrows(IllegalStateException::class.java) { + manager.markProcessingSucceeded() + } + manager.markEndOfStream(true) - manager.markSucceeded() + manager.markProcessingSucceeded() Assertions.assertTrue(channel.receive()) - Assertions.assertEquals(StreamSucceeded, manager.awaitStreamResult()) + Assertions.assertEquals(StreamProcessingSucceeded, manager.awaitStreamResult()) } @Test @@ -80,29 +82,14 @@ class StreamManagerTest { val manager = DefaultStreamManager(stream1) val channel = Channel(Channel.UNLIMITED) - launch { channel.send(manager.awaitStreamResult() is StreamSucceeded) } - - delay(500) - Assertions.assertTrue(channel.tryReceive().isFailure) - manager.markFailed(Exception("test")) - Assertions.assertFalse(channel.receive()) - - Assertions.assertTrue(manager.awaitStreamResult() is StreamFailed) - } - - @Test - fun testMarkKilled() = runTest { - val manager = DefaultStreamManager(stream1) - val channel = Channel(Channel.UNLIMITED) - - launch { channel.send(manager.awaitStreamResult() is StreamSucceeded) } + launch { channel.send(manager.awaitStreamResult() is StreamProcessingSucceeded) } delay(500) Assertions.assertTrue(channel.tryReceive().isFailure) - manager.markKilled(Exception("test")) + manager.markProcessingFailed(Exception("test")) Assertions.assertFalse(channel.receive()) - Assertions.assertTrue(manager.awaitStreamResult() is StreamKilled) + Assertions.assertTrue(manager.awaitStreamResult() is StreamProcessingFailed) } class TestUpdateBatchStateProvider : ArgumentsProvider { @@ -154,6 +141,34 @@ class StreamManagerTest { Pair(stream1, ExpectComplete(true)), ) ), + TestCase( + "Single stream, multiple batches, complete also persists", + listOf( + Pair(stream1, SetRecordCount(10)), + Pair(stream1, AddComplete(0, 4)), + Pair(stream1, ExpectPersistedUntil(5, true)), + Pair(stream1, ExpectComplete(false)), + Pair(stream1, SetEndOfStream), + Pair(stream1, AddComplete(5, 9)), + Pair(stream1, ExpectComplete(true)), + ) + ), + TestCase( + "Single stream, multiple batches, persist/complete out of order", + listOf( + Pair(stream1, SetRecordCount(10)), + Pair( + stream1, + AddComplete(5, 9) + ), // complete a rangeset before the preceding rangeset is persisted + Pair(stream1, AddPersisted(0, 4)), + Pair(stream1, ExpectPersistedUntil(10, true)), + Pair(stream1, ExpectComplete(false)), + Pair(stream1, AddComplete(0, 4)), + Pair(stream1, SetEndOfStream), + Pair(stream1, ExpectComplete(true)), + ) + ), TestCase( "multiple streams", listOf( @@ -177,7 +192,43 @@ class StreamManagerTest { Pair(stream2, ExpectPersistedUntil(20, true)), Pair(stream2, ExpectComplete(true)), ) - ) + ), + TestCase( + "mingle streams, multiple batches, complete also persists", + listOf( + Pair(stream1, SetRecordCount(10)), + Pair(stream1, AddComplete(0, 4)), + Pair(stream1, ExpectPersistedUntil(5, true)), + Pair(stream2, AddComplete(0, 4)), + Pair(stream2, ExpectPersistedUntil(5, true)), + Pair(stream1, ExpectComplete(false)), + Pair(stream2, ExpectComplete(false)), + Pair(stream1, SetEndOfStream), + Pair(stream1, AddComplete(5, 9)), + Pair(stream2, AddComplete(5, 9)), + Pair(stream2, SetEndOfStream), + Pair(stream1, ExpectComplete(true)), + Pair(stream2, ExpectComplete(true)), + ) + ), + TestCase( + "mingle streams, multiple batches, persist/complete out of order", + listOf( + Pair(stream1, SetRecordCount(10)), + Pair(stream1, AddComplete(5, 9)), + Pair(stream1, ExpectPersistedUntil(10, false)), + Pair(stream2, AddComplete(5, 9)), + Pair(stream2, ExpectPersistedUntil(10, false)), + Pair(stream1, ExpectComplete(false)), + Pair(stream2, ExpectComplete(false)), + Pair(stream1, SetEndOfStream), + Pair(stream1, AddComplete(0, 4)), + Pair(stream2, AddComplete(0, 4)), + Pair(stream2, SetEndOfStream), + Pair(stream1, ExpectComplete(true)), + Pair(stream2, ExpectComplete(true)), + ) + ), ) .map { Arguments.of(it) } .stream() @@ -210,19 +261,21 @@ class StreamManagerTest { val manager = managers[stream.descriptor]!! when (event) { is SetRecordCount -> repeat(event.count.toInt()) { manager.countRecordIn() } - is SetEndOfStream -> manager.markEndOfStream() + is SetEndOfStream -> manager.markEndOfStream(true) is AddPersisted -> manager.updateBatchState( BatchEnvelope( SimpleBatch(Batch.State.PERSISTED), - Range.closed(event.firstIndex, event.lastIndex) + Range.closed(event.firstIndex, event.lastIndex), + stream.descriptor ) ) is AddComplete -> manager.updateBatchState( BatchEnvelope( SimpleBatch(Batch.State.COMPLETE), - Range.closed(event.firstIndex, event.lastIndex) + Range.closed(event.firstIndex, event.lastIndex), + stream.descriptor ) ) is ExpectPersistedUntil -> @@ -246,16 +299,162 @@ class StreamManagerTest { val manager = DefaultStreamManager(stream1) // Can't mark success before end-of-stream - Assertions.assertThrows(IllegalStateException::class.java) { manager.markSucceeded() } + Assertions.assertThrows(IllegalStateException::class.java) { + manager.markProcessingSucceeded() + } manager.countRecordIn() - manager.markEndOfStream() + manager.markEndOfStream(true) // Can't update after end-of-stream Assertions.assertThrows(IllegalStateException::class.java) { manager.countRecordIn() } - Assertions.assertThrows(IllegalStateException::class.java) { manager.markEndOfStream() } + Assertions.assertThrows(IllegalStateException::class.java) { manager.markEndOfStream(true) } // Can close now - Assertions.assertDoesNotThrow(manager::markSucceeded) + Assertions.assertDoesNotThrow(manager::markProcessingSucceeded) + } + + @Test + fun testEmptyCompletedStreamYieldsBatchProcessingComplete() { + val manager = DefaultStreamManager(stream1) + manager.markEndOfStream(true) + Assertions.assertTrue(manager.isBatchProcessingComplete()) + } + + @Test + fun `ranges with the same id conflate to latest state`() { + val manager = DefaultStreamManager(stream1) + val range1 = Range.closed(0L, 9L) + val batch1 = + BatchEnvelope( + SimpleBatch(Batch.State.STAGED, groupId = "foo"), + range1, + stream1.descriptor + ) + + val range2 = Range.closed(10, 19L) + val batch2 = + BatchEnvelope( + SimpleBatch(Batch.State.PERSISTED, groupId = "foo"), + range2, + stream1.descriptor + ) + + manager.updateBatchState(batch1) + Assertions.assertFalse(manager.areRecordsPersistedUntil(10L), "local < persisted") + manager.updateBatchState(batch2) + Assertions.assertTrue(manager.areRecordsPersistedUntil(10L), "later state propagates back") + } + + @Test + fun `ranges with a different id conflate to latest state`() { + val manager = DefaultStreamManager(stream1) + val range1 = Range.closed(0L, 9L) + val batch1 = + BatchEnvelope( + SimpleBatch(Batch.State.STAGED, groupId = "foo"), + range1, + stream1.descriptor + ) + + val range2 = Range.closed(10, 19L) + val batch2 = + BatchEnvelope( + SimpleBatch(Batch.State.PERSISTED, groupId = "bar"), + range2, + stream1.descriptor + ) + + manager.updateBatchState(batch1) + Assertions.assertFalse(manager.areRecordsPersistedUntil(10L), "local < persisted") + manager.updateBatchState(batch2) + Assertions.assertFalse( + manager.areRecordsPersistedUntil(10L), + "state does not propagate to other ids" + ) + } + + @Test + fun `state does not conflate between id and no id`() { + val manager = DefaultStreamManager(stream1) + val range1 = Range.closed(0L, 9L) + val batch1 = + BatchEnvelope( + SimpleBatch(Batch.State.STAGED, groupId = null), + range1, + stream1.descriptor + ) + + val range2 = Range.closed(10, 19L) + val batch2 = + BatchEnvelope( + SimpleBatch(Batch.State.PERSISTED, groupId = "bar"), + range2, + stream1.descriptor + ) + + manager.updateBatchState(batch1) + Assertions.assertFalse(manager.areRecordsPersistedUntil(10L), "local < persisted") + manager.updateBatchState(batch2) + Assertions.assertFalse( + manager.areRecordsPersistedUntil(10L), + "state does not propagate to null ids" + ) + } + + @Test + fun `max of newer and older state is always used`() { + val manager = DefaultStreamManager(stream1) + val range1 = Range.closed(0L, 9L) + val batch1 = + BatchEnvelope( + SimpleBatch(Batch.State.PERSISTED, groupId = "foo"), + range1, + stream1.descriptor + ) + + val range2 = Range.closed(10, 19L) + val batch2 = + BatchEnvelope( + SimpleBatch(Batch.State.STAGED, groupId = "foo"), + range2, + stream1.descriptor + ) + + manager.updateBatchState(batch1) + Assertions.assertFalse(manager.areRecordsPersistedUntil(20L), "local < persisted") + manager.updateBatchState(batch2) + Assertions.assertTrue( + manager.areRecordsPersistedUntil(20L), + "max of newer and older state is used" + ) + } + + @Test + fun `max of older and newer state is always used`() { + val manager = DefaultStreamManager(stream1) + val range1 = Range.closed(0L, 9L) + val batch1 = + BatchEnvelope( + SimpleBatch(Batch.State.COMPLETE, groupId = "foo"), + range1, + stream1.descriptor + ) + + val range2 = Range.closed(10, 19L) + val batch2 = + BatchEnvelope( + SimpleBatch(Batch.State.PERSISTED, groupId = "foo"), + range2, + stream1.descriptor + ) + manager.markEndOfStream(true) + + manager.updateBatchState(batch2) + manager.updateBatchState(batch1) + Assertions.assertTrue( + manager.isBatchProcessingComplete(), + "max of older and newer state is used" + ) } } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/SyncManagerTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/SyncManagerTest.kt index 6589794d1bec..29d1f0a8049d 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/SyncManagerTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/SyncManagerTest.kt @@ -41,43 +41,43 @@ class SyncManagerTest { // deferred; B) It should probably move into a writer wrapper. @Test - fun testAwaitAllStreamsCompletedSuccessfully() = runTest { + fun testAwaitAllStreamsProcessedSuccessfully() = runTest { val manager1 = syncManager.getStreamManager(stream1.descriptor) val manager2 = syncManager.getStreamManager(stream2.descriptor) val completionChannel = Channel(Channel.UNLIMITED) - manager1.markEndOfStream() - manager2.markEndOfStream() + manager1.markEndOfStream(true) + manager2.markEndOfStream(true) - launch { completionChannel.send(syncManager.awaitAllStreamsCompletedSuccessfully()) } + launch { completionChannel.send(syncManager.awaitAllStreamsProcessedSuccessfully()) } delay(500) Assertions.assertTrue(completionChannel.tryReceive().isFailure) - manager1.markSucceeded() + manager1.markProcessingSucceeded() delay(500) Assertions.assertTrue(completionChannel.tryReceive().isFailure) - manager2.markSucceeded() + manager2.markProcessingSucceeded() Assertions.assertTrue(completionChannel.receive()) } @Test - fun testAwaitAllStreamsCompletedSuccessfullyWithFailure() = runTest { + fun testAwaitAllStreamsProcessedSuccessfullyWithFailure() = runTest { val manager1 = syncManager.getStreamManager(stream1.descriptor) val manager2 = syncManager.getStreamManager(stream2.descriptor) val completionChannel = Channel(Channel.UNLIMITED) - launch { completionChannel.send(syncManager.awaitAllStreamsCompletedSuccessfully()) } + launch { completionChannel.send(syncManager.awaitAllStreamsProcessedSuccessfully()) } - manager1.markEndOfStream() - manager2.markEndOfStream() + manager1.markEndOfStream(true) + manager2.markEndOfStream(true) delay(500) Assertions.assertTrue(completionChannel.tryReceive().isFailure) - manager1.markSucceeded() + manager1.markProcessingSucceeded() delay(500) Assertions.assertTrue(completionChannel.tryReceive().isFailure) - manager2.markFailed(RuntimeException()) + manager2.markProcessingFailed(RuntimeException()) Assertions.assertFalse(completionChannel.receive()) } @@ -86,15 +86,15 @@ class SyncManagerTest { val manager1 = syncManager.getStreamManager(stream1.descriptor) val manager2 = syncManager.getStreamManager(stream2.descriptor) - manager1.markEndOfStream() - manager2.markEndOfStream() + manager1.markEndOfStream(true) + manager2.markEndOfStream(true) Assertions.assertTrue(syncManager.isActive()) - manager1.markSucceeded() + manager1.markProcessingSucceeded() Assertions.assertTrue(syncManager.isActive()) - manager2.markSucceeded() + manager2.markProcessingSucceeded() Assertions.assertTrue(syncManager.isActive()) - syncManager.markSucceeded() + syncManager.markDestinationSucceeded() Assertions.assertFalse(syncManager.isActive()) } @@ -103,35 +103,35 @@ class SyncManagerTest { val manager1 = syncManager.getStreamManager(stream1.descriptor) val manager2 = syncManager.getStreamManager(stream2.descriptor) - manager1.markEndOfStream() - manager2.markEndOfStream() + manager1.markEndOfStream(true) + manager2.markEndOfStream(true) - val completionChannel = Channel(Channel.UNLIMITED) + val completionChannel = Channel(Channel.UNLIMITED) - launch { completionChannel.send(syncManager.awaitSyncResult()) } + launch { completionChannel.send(syncManager.awaitDestinationResult()) } CoroutineTestUtils.assertThrows(IllegalStateException::class) { - syncManager.markSucceeded() + syncManager.markDestinationSucceeded() } Assertions.assertTrue(completionChannel.tryReceive().isFailure) - manager1.markSucceeded() + manager1.markProcessingSucceeded() CoroutineTestUtils.assertThrows(IllegalStateException::class) { - syncManager.markSucceeded() + syncManager.markDestinationSucceeded() } Assertions.assertTrue(completionChannel.tryReceive().isFailure) - manager2.markSucceeded() + manager2.markProcessingSucceeded() Assertions.assertTrue(completionChannel.tryReceive().isFailure) - syncManager.markSucceeded() - Assertions.assertEquals(SyncSuccess, completionChannel.receive()) + syncManager.markDestinationSucceeded() + Assertions.assertEquals(DestinationSuccess, completionChannel.receive()) } @Test fun testCrashOnNoEndOfStream() = runTest { val manager1 = syncManager.getStreamManager(stream1.descriptor) - manager1.markEndOfStream() + manager1.markEndOfStream(true) // This should fail, because stream2 was not marked with end of stream val e = assertThrows { syncManager.markInputConsumed() } assertEquals( diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/SyncManagerUtils.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/SyncManagerUtils.kt index 28a24a2b8362..283cbdbabefb 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/SyncManagerUtils.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/SyncManagerUtils.kt @@ -19,5 +19,7 @@ import io.airbyte.cdk.load.message.SimpleBatch */ fun SyncManager.markPersisted(stream: DestinationStream, range: Range) { this.getStreamManager(stream.descriptor) - .updateBatchState(BatchEnvelope(SimpleBatch(Batch.State.PERSISTED), range)) + .updateBatchState( + BatchEnvelope(SimpleBatch(Batch.State.PERSISTED), range, stream.descriptor) + ) } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/TimeWindowTriggerTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/TimeWindowTriggerTest.kt new file mode 100644 index 000000000000..86c07486b0bc --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/state/TimeWindowTriggerTest.kt @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.state + +import io.airbyte.cdk.load.state.TimeWindowTriggerTest.Fixtures.TIME_WINDOW_WIDTH_MS +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.junit5.MockKExtension +import java.time.Clock +import java.util.stream.Stream +import kotlin.test.assertEquals +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.Arguments +import org.junit.jupiter.params.provider.MethodSource + +@ExtendWith(MockKExtension::class) +class TimeWindowTriggerTest { + @MockK lateinit var clock: Clock + + private lateinit var timeWindow: TimeWindowTrigger + + @BeforeEach + fun setup() { + timeWindow = TimeWindowTrigger(clock, TIME_WINDOW_WIDTH_MS) + } + + @Test + fun `open is idempotent`() { + val initialOpenedAt = 1000L + + every { clock.millis() } returns initialOpenedAt + val openedAt1 = timeWindow.open() + + assertEquals(initialOpenedAt, openedAt1) + + every { clock.millis() } returns initialOpenedAt + 1 + val openedAt2 = timeWindow.open() + + assertEquals(initialOpenedAt, openedAt2) + } + + @Test + fun `isComplete returns false if window not opened`() { + every { clock.millis() } returns TIME_WINDOW_WIDTH_MS + assertEquals(false, timeWindow.isComplete()) + + every { clock.millis() } returns TIME_WINDOW_WIDTH_MS + 1 + assertEquals(false, timeWindow.isComplete()) + + every { clock.millis() } returns TIME_WINDOW_WIDTH_MS + 60000 + assertEquals(false, timeWindow.isComplete()) + } + + @ParameterizedTest + @MethodSource("windowWidthMatrix") + fun `isComplete calculates time window based on configured width`(windowWidthMs: Long) { + every { clock.millis() } returns 0 + + timeWindow = TimeWindowTrigger(clock, windowWidthMs) + + val openedAt = timeWindow.open() + assertEquals(0, openedAt) + + every { clock.millis() } returns windowWidthMs - 1 + assertEquals(false, timeWindow.isComplete()) + + every { clock.millis() } returns windowWidthMs - 124 + assertEquals(false, timeWindow.isComplete()) + + every { clock.millis() } returns windowWidthMs + assertEquals(true, timeWindow.isComplete()) + + every { clock.millis() } returns windowWidthMs + 1 + assertEquals(true, timeWindow.isComplete()) + + every { clock.millis() } returns windowWidthMs + 60000 + assertEquals(true, timeWindow.isComplete()) + } + + object Fixtures { + const val TIME_WINDOW_WIDTH_MS = 60000L + } + + companion object { + @JvmStatic + private fun windowWidthMatrix(): Stream { + return Stream.of( + Arguments.of(100L), + Arguments.of(10000L), + Arguments.of(900000L), + Arguments.of(900001L), + ) + } + } +} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/DestinationTaskExceptionHandlerTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/DestinationTaskExceptionHandlerTest.kt deleted file mode 100644 index 61b0733920f3..000000000000 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/DestinationTaskExceptionHandlerTest.kt +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.cdk.load.task - -import io.airbyte.cdk.load.command.DestinationCatalog -import io.airbyte.cdk.load.command.DestinationStream -import io.airbyte.cdk.load.command.MockDestinationCatalogFactory -import io.airbyte.cdk.load.state.SyncManager -import io.airbyte.cdk.load.task.implementor.FailStreamTask -import io.airbyte.cdk.load.task.implementor.FailStreamTaskFactory -import io.airbyte.cdk.load.task.implementor.FailSyncTask -import io.airbyte.cdk.load.task.implementor.FailSyncTaskFactory -import io.airbyte.cdk.load.test.util.CoroutineTestUtils -import io.micronaut.context.annotation.Primary -import io.micronaut.context.annotation.Requires -import io.micronaut.test.extensions.junit5.annotation.MicronautTest -import jakarta.inject.Inject -import jakarta.inject.Singleton -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.consumeAsFlow -import kotlinx.coroutines.flow.toList -import kotlinx.coroutines.launch -import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test - -@MicronautTest( - rebuildContext = true, - environments = - [ - "DestinationTaskLauncherExceptionHandlerTest", - "MockDestinationConfiguration", - "MockDestinationCatalog", - "MockScopeProvider" - ] -) -class DestinationTaskExceptionHandlerTest where T : LeveledTask, T : ScopedTask { - @Inject - lateinit var exceptionHandler: DestinationTaskExceptionHandler> - - @Singleton - @Primary - @Requires(env = ["DestinationTaskLauncherExceptionHandlerTest"]) - class MockFailStreamTaskFactory : FailStreamTaskFactory { - val didRunFor = Channel>(Channel.UNLIMITED) - - override fun make( - exceptionHandler: DestinationTaskExceptionHandler<*, *>, - exception: Exception, - stream: DestinationStream, - kill: Boolean - ): FailStreamTask { - return object : FailStreamTask { - override suspend fun execute() { - didRunFor.send(Triple(stream, exception, kill)) - } - } - } - } - - @Singleton - @Primary - @Requires(env = ["DestinationTaskLauncherExceptionHandlerTest"]) - class MockFailSyncTaskFactory : FailSyncTaskFactory { - val didRunWith = Channel(Channel.UNLIMITED) - - override fun make( - exceptionHandler: DestinationTaskExceptionHandler<*, *>, - exception: Exception - ): FailSyncTask { - return object : FailSyncTask { - override suspend fun execute() { - didRunWith.send(exception) - } - } - } - } - - /** - * Validate that the wrapper directs failures in - * - StreamTask(s) to handleStreamFailure (and to an injected Mock FailStreamTask) - * - SyncTask(s) to handleSyncFailure (and to an injected Mock FailSyncTask) - */ - @Suppress("UNCHECKED_CAST") - @Test - fun testHandleStreamTaskException( - mockFailStreamTaskFactory: MockFailStreamTaskFactory, - ) = runTest { - val mockTask = - object : StreamLevel, ImplementorScope { - override val stream = MockDestinationCatalogFactory.stream1 - override suspend fun execute() { - throw RuntimeException("StreamTask failure") - } - } - - val wrappedTask = exceptionHandler.withExceptionHandling(mockTask as T) - wrappedTask.execute() - val (stream, exception) = mockFailStreamTaskFactory.didRunFor.receive() - Assertions.assertEquals(MockDestinationCatalogFactory.stream1, stream) - Assertions.assertTrue(exception is RuntimeException) - } - - @Suppress("UNCHECKED_CAST") - @Test - fun testHandleSyncTaskException( - mockFailStreamTaskFactory: MockFailStreamTaskFactory, - catalog: DestinationCatalog - ) = runTest { - val mockTask = - object : SyncLevel, ImplementorScope { - override suspend fun execute() { - throw RuntimeException("SyncTask failure") - } - } - - val wrappedTask = exceptionHandler.withExceptionHandling(mockTask as T) - wrappedTask.execute() - mockFailStreamTaskFactory.didRunFor.close() - val streamResults = - mockFailStreamTaskFactory.didRunFor.consumeAsFlow().toList().associate { - (stream, exception, kill) -> - stream to Pair(exception, kill) - } - catalog.streams.forEach { stream -> - Assertions.assertTrue(streamResults[stream]!!.first is RuntimeException) - Assertions.assertTrue(streamResults[stream]!!.second) - } - } - - @Suppress("UNCHECKED_CAST") - @Test - fun testSyncFailureBlocksSyncTasks( - mockFailSyncTaskFactory: MockFailSyncTaskFactory, - syncManager: SyncManager, - catalog: DestinationCatalog - ) = runTest { - val innerTaskRan = Channel(Channel.UNLIMITED) - val mockTask = - object : SyncLevel, ImplementorScope { - override suspend fun execute() { - innerTaskRan.send(true) - } - } - - val wrappedTask = exceptionHandler.withExceptionHandling(mockTask as T) - catalog.streams.forEach { - syncManager.getStreamManager(it.descriptor).markFailed(RuntimeException("dummy")) - } - syncManager.markFailed(RuntimeException("dummy failure")) - wrappedTask.execute() - delay(1000) - Assertions.assertTrue(mockFailSyncTaskFactory.didRunWith.tryReceive().isFailure) - Assertions.assertTrue(innerTaskRan.tryReceive().isFailure) - } - - @Suppress("UNCHECKED_CAST") - @Test - fun testSyncFailureAfterSuccessThrows(syncManager: SyncManager, catalog: DestinationCatalog) = - runTest { - val mockTask = - object : SyncLevel, ImplementorScope { - override suspend fun execute() { - // do nothing - } - } - - val wrappedTask = exceptionHandler.withExceptionHandling(mockTask as T) - - for (stream in catalog.streams) { - val manager = syncManager.getStreamManager(stream.descriptor) - manager.markEndOfStream() - manager.markSucceeded() - } - syncManager.markSucceeded() - CoroutineTestUtils.assertThrows(IllegalStateException::class) { wrappedTask.execute() } - } - - @Suppress("UNCHECKED_CAST") - @Test - fun testStreamFailureBlocksStreamTasks( - mockFailStreamTaskFactory: MockFailStreamTaskFactory, - syncManager: SyncManager - ) = runTest { - val innerTaskRan = Channel(Channel.UNLIMITED) - val mockTask = - object : StreamLevel, ImplementorScope { - override val stream: DestinationStream = MockDestinationCatalogFactory.stream1 - - override suspend fun execute() { - innerTaskRan.send(true) - } - } - - val wrappedTask = exceptionHandler.withExceptionHandling(mockTask as T) - val manager = syncManager.getStreamManager(MockDestinationCatalogFactory.stream1.descriptor) - manager.markEndOfStream() - manager.markFailed(RuntimeException("dummy failure")) - launch { wrappedTask.execute() } - delay(1000) - Assertions.assertTrue(mockFailStreamTaskFactory.didRunFor.tryReceive().isFailure) - Assertions.assertTrue(innerTaskRan.tryReceive().isFailure) - } - - @Suppress("UNCHECKED_CAST") - @Test - fun testStreamFailureAfterSuccessThrows( - mockFailStreamTaskFactory: MockFailStreamTaskFactory, - syncManager: SyncManager, - ) = runTest { - val mockTask = - object : StreamLevel, ImplementorScope { - override val stream: DestinationStream = MockDestinationCatalogFactory.stream1 - - override suspend fun execute() { - // do nothing - } - } - - val wrappedTask = exceptionHandler.withExceptionHandling(mockTask as T) - - val manager = syncManager.getStreamManager(MockDestinationCatalogFactory.stream1.descriptor) - manager.markEndOfStream() - manager.markSucceeded() - - CoroutineTestUtils.assertThrows(IllegalStateException::class) { wrappedTask.execute() } - mockFailStreamTaskFactory.didRunFor.close() - } - - @Test - fun testHandleSyncFailed() = runTest { - val wasHandled = Channel(Channel.UNLIMITED) - exceptionHandler.setCallback { wasHandled.send(true) } - exceptionHandler.handleSyncFailed() - Assertions.assertTrue(wasHandled.receive()) - } -} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/DestinationTaskLauncherTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/DestinationTaskLauncherTest.kt index ce69c2d2c790..3c9671d5deaf 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/DestinationTaskLauncherTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/DestinationTaskLauncherTest.kt @@ -9,22 +9,30 @@ import com.google.common.collect.TreeRangeSet import io.airbyte.cdk.load.command.DestinationCatalog import io.airbyte.cdk.load.command.DestinationStream import io.airbyte.cdk.load.command.MockDestinationCatalogFactory +import io.airbyte.cdk.load.command.MockDestinationConfiguration import io.airbyte.cdk.load.message.Batch import io.airbyte.cdk.load.message.BatchEnvelope +import io.airbyte.cdk.load.message.CheckpointMessageWrapped +import io.airbyte.cdk.load.message.DestinationStreamEvent +import io.airbyte.cdk.load.message.MessageQueue +import io.airbyte.cdk.load.message.MessageQueueSupplier +import io.airbyte.cdk.load.message.QueueWriter +import io.airbyte.cdk.load.state.Reserved import io.airbyte.cdk.load.state.SyncManager import io.airbyte.cdk.load.task.implementor.CloseStreamTask import io.airbyte.cdk.load.task.implementor.CloseStreamTaskFactory import io.airbyte.cdk.load.task.implementor.DefaultCloseStreamTaskFactory import io.airbyte.cdk.load.task.implementor.DefaultOpenStreamTaskFactory -import io.airbyte.cdk.load.task.implementor.DefaultProcessBatchTaskFactory -import io.airbyte.cdk.load.task.implementor.DefaultProcessRecordsTaskFactory import io.airbyte.cdk.load.task.implementor.DefaultSetupTaskFactory import io.airbyte.cdk.load.task.implementor.DefaultTeardownTaskFactory +import io.airbyte.cdk.load.task.implementor.FailStreamTask +import io.airbyte.cdk.load.task.implementor.FailStreamTaskFactory +import io.airbyte.cdk.load.task.implementor.FailSyncTask +import io.airbyte.cdk.load.task.implementor.FailSyncTaskFactory +import io.airbyte.cdk.load.task.implementor.FileTransferQueueMessage import io.airbyte.cdk.load.task.implementor.OpenStreamTask import io.airbyte.cdk.load.task.implementor.OpenStreamTaskFactory -import io.airbyte.cdk.load.task.implementor.ProcessBatchTask import io.airbyte.cdk.load.task.implementor.ProcessBatchTaskFactory -import io.airbyte.cdk.load.task.implementor.ProcessRecordsTask import io.airbyte.cdk.load.task.implementor.ProcessRecordsTaskFactory import io.airbyte.cdk.load.task.implementor.SetupTask import io.airbyte.cdk.load.task.implementor.SetupTaskFactory @@ -33,24 +41,27 @@ import io.airbyte.cdk.load.task.implementor.TeardownTaskFactory import io.airbyte.cdk.load.task.internal.DefaultSpillToDiskTaskFactory import io.airbyte.cdk.load.task.internal.FlushCheckpointsTask import io.airbyte.cdk.load.task.internal.FlushCheckpointsTaskFactory +import io.airbyte.cdk.load.task.internal.FlushTickTask import io.airbyte.cdk.load.task.internal.InputConsumerTask +import io.airbyte.cdk.load.task.internal.InputConsumerTaskFactory +import io.airbyte.cdk.load.task.internal.ReservingDeserializingInputFlow import io.airbyte.cdk.load.task.internal.SpillToDiskTask import io.airbyte.cdk.load.task.internal.SpillToDiskTaskFactory -import io.airbyte.cdk.load.task.internal.SpilledRawMessagesLocalFile import io.airbyte.cdk.load.task.internal.TimedForcedCheckpointFlushTask import io.airbyte.cdk.load.task.internal.UpdateCheckpointsTask import io.micronaut.context.annotation.Primary import io.micronaut.context.annotation.Replaces import io.micronaut.context.annotation.Requires import io.micronaut.test.extensions.junit5.annotation.MicronautTest +import io.mockk.coVerify +import io.mockk.mockk import jakarta.inject.Inject import jakarta.inject.Singleton -import kotlin.io.path.Path +import java.util.concurrent.atomic.AtomicBoolean import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.toList import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test @@ -65,32 +76,92 @@ import org.junit.jupiter.api.Test "MockScopeProvider", ] ) -class DestinationTaskLauncherTest where T : LeveledTask, T : ScopedTask { +class DestinationTaskLauncherTest { @Inject lateinit var mockScopeProvider: MockScopeProvider @Inject lateinit var taskLauncher: DestinationTaskLauncher @Inject lateinit var syncManager: SyncManager - @Inject lateinit var mockExceptionHandler: MockExceptionHandler - @Inject lateinit var mockInputConsumerTask: MockInputConsumerTask + @Inject lateinit var mockInputConsumerTask: MockInputConsumerTaskFactory @Inject lateinit var mockSetupTaskFactory: MockSetupTaskFactory @Inject lateinit var mockSpillToDiskTaskFactory: MockSpillToDiskTaskFactory @Inject lateinit var mockOpenStreamTaskFactory: MockOpenStreamTaskFactory - @Inject lateinit var processRecordsTaskFactory: MockProcessRecordsTaskFactory - @Inject lateinit var processBatchTaskFactory: MockProcessBatchTaskFactory + @Inject lateinit var processRecordsTaskFactory: ProcessRecordsTaskFactory + @Inject lateinit var processBatchTaskFactory: ProcessBatchTaskFactory @Inject lateinit var closeStreamTaskFactory: MockCloseStreamTaskFactory @Inject lateinit var teardownTaskFactory: MockTeardownTaskFactory @Inject lateinit var flushCheckpointsTaskFactory: MockFlushCheckpointsTaskFactory @Inject lateinit var mockForceFlushTask: MockForceFlushTask @Inject lateinit var updateCheckpointsTask: MockUpdateCheckpointsTask + @Inject lateinit var inputFlow: ReservingDeserializingInputFlow + @Inject lateinit var queueWriter: MockQueueWriter + @Inject lateinit var messageQueueSupplier: MockMessageQueueSupplier + @Inject lateinit var flushTickTask: FlushTickTask + @Inject lateinit var mockFailStreamTaskFactory: MockFailStreamTaskFactory + @Inject lateinit var mockFailSyncTaskFactory: MockFailSyncTaskFactory + @Inject lateinit var config: MockDestinationConfiguration @Singleton @Primary @Requires(env = ["DestinationTaskLauncherTest"]) - class MockInputConsumerTask : InputConsumerTask { + fun inputFlow(): ReservingDeserializingInputFlow = mockk(relaxed = true) + + @Singleton + @Primary + @Requires(env = ["DestinationTaskLauncherTest"]) + fun flushTickTask(): FlushTickTask = mockk(relaxed = true) + + @Singleton + @Primary + @Requires(env = ["DestinationTaskLauncherTest"]) + fun processRecordsTaskFactory(): ProcessRecordsTaskFactory = mockk(relaxed = true) + + @Singleton + @Primary + @Requires(env = ["DestinationTaskLauncherTest"]) + fun processBatchTaskFactory(): ProcessBatchTaskFactory = mockk(relaxed = true) + + @Singleton + @Primary + @Requires(env = ["DestinationTaskLauncherTest"]) + class MockQueueWriter : QueueWriter> { + override suspend fun publish(message: Reserved) {} + override fun isClosedForPublish(): Boolean = false + override suspend fun close() {} + } + + @Singleton + @Primary + @Requires(env = ["DestinationTaskLauncherTest"]) + class MockMessageQueueSupplier : + MessageQueueSupplier> { + override fun get( + key: DestinationStream.Descriptor + ): MessageQueue> { + return mockk() + } + } + + @Singleton + @Primary + @Requires(env = ["DestinationTaskLauncherTest"]) + class MockInputConsumerTaskFactory : InputConsumerTaskFactory { val hasRun: Channel = Channel(Channel.UNLIMITED) - override suspend fun execute() { - hasRun.send(true) + override fun make( + catalog: DestinationCatalog, + inputFlow: ReservingDeserializingInputFlow, + recordQueueSupplier: + MessageQueueSupplier< + DestinationStream.Descriptor, Reserved>, + checkpointQueue: QueueWriter>, + destinationTaskLauncher: DestinationTaskLauncher, + fileTransferQueue: MessageQueue, + ): InputConsumerTask { + return object : InputConsumerTask { + override suspend fun execute() { + hasRun.send(true) + } + } } } @@ -116,6 +187,7 @@ class DestinationTaskLauncherTest where T : LeveledTask, T : ScopedTask { @Requires(env = ["DestinationTaskLauncherTest"]) class MockSpillToDiskTaskFactory(catalog: DestinationCatalog) : SpillToDiskTaskFactory { val streamHasRun = mutableMapOf>() + val forceFailure = AtomicBoolean(false) init { catalog.streams.forEach { streamHasRun[it.descriptor] = Channel(Channel.UNLIMITED) } @@ -123,12 +195,14 @@ class DestinationTaskLauncherTest where T : LeveledTask, T : ScopedTask { override fun make( taskLauncher: DestinationTaskLauncher, - stream: DestinationStream + stream: DestinationStream.Descriptor ): SpillToDiskTask { return object : SpillToDiskTask { - override val stream: DestinationStream = stream override suspend fun execute() { - streamHasRun[stream.descriptor]?.send(Unit) + if (forceFailure.get()) { + throw Exception("Forced failure") + } + streamHasRun[stream]?.send(Unit) } } } @@ -149,7 +223,6 @@ class DestinationTaskLauncherTest where T : LeveledTask, T : ScopedTask { stream: DestinationStream ): OpenStreamTask { return object : OpenStreamTask { - override val stream: DestinationStream = stream override suspend fun execute() { streamHasRun[stream]?.send(Unit) } @@ -157,46 +230,6 @@ class DestinationTaskLauncherTest where T : LeveledTask, T : ScopedTask { } } - @Singleton - @Replaces(DefaultProcessRecordsTaskFactory::class) - @Requires(env = ["DestinationTaskLauncherTest"]) - class MockProcessRecordsTaskFactory : ProcessRecordsTaskFactory { - val hasRun: Channel = Channel(Channel.UNLIMITED) - - override fun make( - taskLauncher: DestinationTaskLauncher, - stream: DestinationStream, - file: SpilledRawMessagesLocalFile - ): ProcessRecordsTask { - return object : ProcessRecordsTask { - override val stream: DestinationStream = stream - override suspend fun execute() { - hasRun.send(Unit) - } - } - } - } - - @Singleton - @Replaces(DefaultProcessBatchTaskFactory::class) - @Requires(env = ["DestinationTaskLauncherTest"]) - class MockProcessBatchTaskFactory : ProcessBatchTaskFactory { - val hasRun: Channel> = Channel(Channel.UNLIMITED) - - override fun make( - taskLauncher: DestinationTaskLauncher, - stream: DestinationStream, - batchEnvelope: BatchEnvelope<*> - ): ProcessBatchTask { - return object : ProcessBatchTask { - override val stream: DestinationStream = stream - override suspend fun execute() { - hasRun.send(batchEnvelope) - } - } - } - } - @Singleton @Replaces(DefaultCloseStreamTaskFactory::class) @Requires(env = ["DestinationTaskLauncherTest"]) @@ -205,10 +238,9 @@ class DestinationTaskLauncherTest where T : LeveledTask, T : ScopedTask { override fun make( taskLauncher: DestinationTaskLauncher, - stream: DestinationStream, + stream: DestinationStream.Descriptor, ): CloseStreamTask { return object : CloseStreamTask { - override val stream: DestinationStream = stream override suspend fun execute() { hasRun.send(Unit) } @@ -267,38 +299,43 @@ class DestinationTaskLauncherTest where T : LeveledTask, T : ScopedTask { } } - class MockBatch(override val state: Batch.State) : Batch - @Singleton + @Primary @Requires(env = ["DestinationTaskLauncherTest"]) - class MockExceptionHandler : TaskExceptionHandler> where - T : LeveledTask, - T : ScopedTask { - val wrappedTasks = Channel(Channel.UNLIMITED) - val callbacks = Channel Unit>(Channel.UNLIMITED) - - inner class IdentityWrapper(override val innerTask: ScopedTask) : WrappedTask { - override suspend fun execute() { - innerTask.execute() + class MockFailStreamTaskFactory : FailStreamTaskFactory { + val didRunFor = Channel(Channel.UNLIMITED) + override fun make( + taskLauncher: DestinationTaskLauncher, + exception: Exception, + stream: DestinationStream.Descriptor + ): FailStreamTask { + return object : FailStreamTask { + override suspend fun execute() { + didRunFor.send(stream) + } } } + } - override suspend fun withExceptionHandling(task: T): WrappedTask { - runBlocking { wrappedTasks.send(task) } - val innerTask = - object : InternalScope { - override suspend fun execute() { - task.execute() - } + @Singleton + @Primary + @Requires(env = ["DestinationTaskLauncherTest"]) + class MockFailSyncTaskFactory : FailSyncTaskFactory { + val didRun = Channel(Channel.UNLIMITED) + override fun make( + taskLauncher: DestinationTaskLauncher, + exception: Exception + ): FailSyncTask { + return object : FailSyncTask { + override suspend fun execute() { + didRun.send(true) } - return IdentityWrapper(innerTask) - } - - override suspend fun setCallback(callback: suspend () -> Unit) { - callbacks.send(callback) + } } } + class MockBatch(override val state: Batch.State, override val groupId: String? = null) : Batch + @Test fun testRun() = runTest { val job = launch { taskLauncher.run() } @@ -314,6 +351,12 @@ class DestinationTaskLauncherTest where T : LeveledTask, T : ScopedTask { // Verify that spill to disk ran for each stream mockSpillToDiskTaskFactory.streamHasRun.values.forEach { it.receive() } + coVerify(exactly = config.numProcessRecordsWorkers) { + processRecordsTaskFactory.make(any()) + } + + coVerify(exactly = config.numProcessBatchWorkers) { processBatchTaskFactory.make(any()) } + // Verify that we kicked off the timed force flush w/o a specific delay Assertions.assertTrue(mockForceFlushTask.didRun.receive()) @@ -322,15 +365,6 @@ class DestinationTaskLauncherTest where T : LeveledTask, T : ScopedTask { "update checkpoints task was started" ) - // Collect the tasks wrapped by the exception handler: expect one Setup and [nStreams] - // SpillToDisk - mockExceptionHandler.wrappedTasks.close() - val taskList = mockExceptionHandler.wrappedTasks.toList() - Assertions.assertEquals(1, taskList.filterIsInstance().size) - Assertions.assertEquals( - mockSpillToDiskTaskFactory.streamHasRun.size, - taskList.filterIsInstance().size - ) job.cancel() } @@ -339,91 +373,77 @@ class DestinationTaskLauncherTest where T : LeveledTask, T : ScopedTask { // Verify that open stream ran for each stream taskLauncher.handleSetupComplete() mockOpenStreamTaskFactory.streamHasRun.values.forEach { it.receive() } - - // Collect the tasks wrapped by the exception handler: expect [nStreams] OpenStream - mockExceptionHandler.wrappedTasks.close() - val taskList = mockExceptionHandler.wrappedTasks.toList() - Assertions.assertEquals( - mockOpenStreamTaskFactory.streamHasRun.size, - taskList.filterIsInstance().size - ) - } - - @Test - fun testHandleSpilledFileCompleteNotEndOfStream() = runTest { - taskLauncher.handleNewSpilledFile( - MockDestinationCatalogFactory.stream1, - SpilledRawMessagesLocalFile(Path("not/a/real/file"), 100L, Range.singleton(0)) - ) - - processRecordsTaskFactory.hasRun.receive() - mockSpillToDiskTaskFactory.streamHasRun[MockDestinationCatalogFactory.stream1.descriptor] - ?.receive() - ?: Assertions.fail("SpillToDiskTask not run") - } - - @Test - fun testHandleSpilledFileCompleteEndOfStream() = runTest { - launch { - taskLauncher.handleNewSpilledFile( - MockDestinationCatalogFactory.stream1, - SpilledRawMessagesLocalFile(Path("not/a/real/file"), 100L, Range.singleton(0), true) - ) - } - - processRecordsTaskFactory.hasRun.receive() - delay(500) - Assertions.assertTrue( - mockSpillToDiskTaskFactory.streamHasRun[ - MockDestinationCatalogFactory.stream1.descriptor] - ?.tryReceive() - ?.isFailure != false - ) } @Test fun testHandleNewBatch() = runTest { val range = TreeRangeSet.create(listOf(Range.closed(0L, 100L))) - val streamManager = - syncManager.getStreamManager(MockDestinationCatalogFactory.stream1.descriptor) + val stream1 = MockDestinationCatalogFactory.stream1 + val streamManager = syncManager.getStreamManager(stream1.descriptor) repeat(100) { streamManager.countRecordIn() } - streamManager.markEndOfStream() + streamManager.markEndOfStream(true) // Verify incomplete batch triggers process batch - val incompleteBatch = BatchEnvelope(MockBatch(Batch.State.LOCAL), range) - taskLauncher.handleNewBatch(MockDestinationCatalogFactory.stream1, incompleteBatch) + val incompleteBatch = + BatchEnvelope(MockBatch(Batch.State.STAGED), range, stream1.descriptor) + taskLauncher.handleNewBatch( + MockDestinationCatalogFactory.stream1.descriptor, + incompleteBatch + ) Assertions.assertFalse(streamManager.areRecordsPersistedUntil(100L)) - val batchReceived = processBatchTaskFactory.hasRun.receive() - Assertions.assertEquals(incompleteBatch, batchReceived) delay(500) Assertions.assertTrue(flushCheckpointsTaskFactory.hasRun.tryReceive().isFailure) - val persistedBatch = BatchEnvelope(MockBatch(Batch.State.PERSISTED), range) - taskLauncher.handleNewBatch(MockDestinationCatalogFactory.stream1, persistedBatch) + val persistedBatch = + BatchEnvelope(MockBatch(Batch.State.PERSISTED), range, stream1.descriptor) + taskLauncher.handleNewBatch( + MockDestinationCatalogFactory.stream1.descriptor, + persistedBatch + ) Assertions.assertTrue(streamManager.areRecordsPersistedUntil(100L)) Assertions.assertTrue(flushCheckpointsTaskFactory.hasRun.receive()) // Verify complete batch w/o batch processing complete does nothing val halfRange = TreeRangeSet.create(listOf(Range.closed(0L, 50L))) - val completeBatchHalf = BatchEnvelope(MockBatch(Batch.State.COMPLETE), halfRange) - taskLauncher.handleNewBatch(MockDestinationCatalogFactory.stream1, completeBatchHalf) + val completeBatchHalf = + BatchEnvelope(MockBatch(Batch.State.COMPLETE), halfRange, stream1.descriptor) + taskLauncher.handleNewBatch( + MockDestinationCatalogFactory.stream1.descriptor, + completeBatchHalf + ) delay(1000) Assertions.assertTrue(closeStreamTaskFactory.hasRun.tryReceive().isFailure) // Verify complete batch w/ batch processing complete triggers close stream val secondHalf = TreeRangeSet.create(listOf(Range.closed(51L, 100L))) - val completingBatch = BatchEnvelope(MockBatch(Batch.State.COMPLETE), secondHalf) - taskLauncher.handleNewBatch(MockDestinationCatalogFactory.stream1, completingBatch) + val completingBatch = + BatchEnvelope(MockBatch(Batch.State.COMPLETE), secondHalf, stream1.descriptor) + taskLauncher.handleNewBatch( + MockDestinationCatalogFactory.stream1.descriptor, + completingBatch + ) closeStreamTaskFactory.hasRun.receive() Assertions.assertTrue(true) } + @Test + fun handleEmptyBatch() = runTest { + val range = TreeRangeSet.create(listOf(Range.closed(0L, 0L))) + val stream1 = MockDestinationCatalogFactory.stream1 + val streamManager = syncManager.getStreamManager(stream1.descriptor) + streamManager.markEndOfStream(true) + + val emptyBatch = BatchEnvelope(MockBatch(Batch.State.COMPLETE), range, stream1.descriptor) + taskLauncher.handleNewBatch(MockDestinationCatalogFactory.stream1.descriptor, emptyBatch) + closeStreamTaskFactory.hasRun.receive() + } + @Test fun testHandleStreamClosed() = runTest { // This should run teardown unconditionally. - launch { taskLauncher.handleStreamClosed(MockDestinationCatalogFactory.stream1) } + launch { taskLauncher.handleStreamClosed(MockDestinationCatalogFactory.stream1.descriptor) } teardownTaskFactory.hasRun.receive() } @@ -443,6 +463,42 @@ class DestinationTaskLauncherTest where T : LeveledTask, T : ScopedTask { taskLauncher.run() Assertions.assertTrue(mockScopeProvider.didKill) } - mockExceptionHandler.callbacks.receive().invoke() + taskLauncher.handleTeardownComplete(success = false) + } + + @Test + fun `test exceptions in tasks throw`(catalog: DestinationCatalog) = runTest { + mockSpillToDiskTaskFactory.forceFailure.getAndSet(true) + + val job = launch { taskLauncher.run() } + taskLauncher.handleTeardownComplete() + job.join() + + mockFailStreamTaskFactory.didRunFor.close() + + Assertions.assertEquals( + catalog.streams.map { it.descriptor }.toSet(), + mockFailStreamTaskFactory.didRunFor.toList().toSet(), + "FailStreamTask was run for each stream" + ) + } + + @Test + fun `test sync failure after stream failure`() = runTest { + val job = launch { taskLauncher.run() } + taskLauncher.handleFailStreamComplete( + MockDestinationCatalogFactory.stream1.descriptor, + Exception() + ) + taskLauncher.handleFailStreamComplete( + MockDestinationCatalogFactory.stream2.descriptor, + Exception() + ) + taskLauncher.handleTeardownComplete() + job.join() + mockFailSyncTaskFactory.didRun.close() + val runs = mockFailSyncTaskFactory.didRun.toList() + Assertions.assertTrue(runs.all { it }, "FailSyncTask was run") + Assertions.assertTrue(runs.size == 1, "FailSyncTask was run exactly once") } } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/DestinationTaskLauncherUTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/DestinationTaskLauncherUTest.kt new file mode 100644 index 000000000000..f1ee31f867fd --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/DestinationTaskLauncherUTest.kt @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.task + +import io.airbyte.cdk.load.command.DestinationCatalog +import io.airbyte.cdk.load.command.DestinationConfiguration +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.message.Batch +import io.airbyte.cdk.load.message.BatchEnvelope +import io.airbyte.cdk.load.message.CheckpointMessageWrapped +import io.airbyte.cdk.load.message.DestinationStreamEvent +import io.airbyte.cdk.load.message.MessageQueue +import io.airbyte.cdk.load.message.MessageQueueSupplier +import io.airbyte.cdk.load.message.QueueWriter +import io.airbyte.cdk.load.message.SimpleBatch +import io.airbyte.cdk.load.state.Reserved +import io.airbyte.cdk.load.state.StreamManager +import io.airbyte.cdk.load.state.SyncManager +import io.airbyte.cdk.load.task.implementor.CloseStreamTaskFactory +import io.airbyte.cdk.load.task.implementor.FailStreamTask +import io.airbyte.cdk.load.task.implementor.FailStreamTaskFactory +import io.airbyte.cdk.load.task.implementor.FailSyncTaskFactory +import io.airbyte.cdk.load.task.implementor.FileTransferQueueMessage +import io.airbyte.cdk.load.task.implementor.OpenStreamTaskFactory +import io.airbyte.cdk.load.task.implementor.ProcessBatchTaskFactory +import io.airbyte.cdk.load.task.implementor.ProcessFileTaskFactory +import io.airbyte.cdk.load.task.implementor.ProcessRecordsTaskFactory +import io.airbyte.cdk.load.task.implementor.SetupTaskFactory +import io.airbyte.cdk.load.task.implementor.TeardownTaskFactory +import io.airbyte.cdk.load.task.internal.FlushCheckpointsTaskFactory +import io.airbyte.cdk.load.task.internal.FlushTickTask +import io.airbyte.cdk.load.task.internal.InputConsumerTaskFactory +import io.airbyte.cdk.load.task.internal.ReservingDeserializingInputFlow +import io.airbyte.cdk.load.task.internal.SpillToDiskTask +import io.airbyte.cdk.load.task.internal.SpillToDiskTaskFactory +import io.airbyte.cdk.load.task.internal.TimedForcedCheckpointFlushTask +import io.airbyte.cdk.load.task.internal.UpdateCheckpointsTask +import io.mockk.Called +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.every +import io.mockk.mockk +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class DestinationTaskLauncherUTest { + private val taskScopeProvider: TaskScopeProvider> = + mockk(relaxed = true) + private val catalog: DestinationCatalog = mockk(relaxed = true) + private val syncManager: SyncManager = mockk(relaxed = true) + + // Internal Tasks + private val inputConsumerTaskFactory: InputConsumerTaskFactory = mockk(relaxed = true) + private val spillToDiskTaskFactory: SpillToDiskTaskFactory = mockk(relaxed = true) + private val flushTickTask: FlushTickTask = mockk(relaxed = true) + + // Implementor Tasks + private val setupTaskFactory: SetupTaskFactory = mockk(relaxed = true) + private val openStreamTaskFactory: OpenStreamTaskFactory = mockk(relaxed = true) + private val processRecordsTaskFactory: ProcessRecordsTaskFactory = mockk(relaxed = true) + private val processFileTaskFactory: ProcessFileTaskFactory = mockk(relaxed = true) + private val processBatchTaskFactory: ProcessBatchTaskFactory = mockk(relaxed = true) + private val closeStreamTaskFactory: CloseStreamTaskFactory = mockk(relaxed = true) + private val teardownTaskFactory: TeardownTaskFactory = mockk(relaxed = true) + + // Checkpoint Tasks + private val flushCheckpointsTaskFactory: FlushCheckpointsTaskFactory = mockk(relaxed = true) + private val timedFlushTask: TimedForcedCheckpointFlushTask = mockk(relaxed = true) + private val updateCheckpointsTask: UpdateCheckpointsTask = mockk(relaxed = true) + private val config: DestinationConfiguration = mockk(relaxed = true) + + // Exception tasks + private val failStreamTaskFactory: FailStreamTaskFactory = mockk(relaxed = true) + private val failSyncTaskFactory: FailSyncTaskFactory = mockk(relaxed = true) + + // Input Comsumer requirements + private val inputFlow: ReservingDeserializingInputFlow = mockk(relaxed = true) + private val recordQueueSupplier: + MessageQueueSupplier> = + mockk(relaxed = true) + private val checkpointQueue: QueueWriter> = + mockk(relaxed = true) + private val fileTransferQueue: MessageQueue = mockk(relaxed = true) + private fun getDefaultDestinationTaskLauncher( + useFileTranfer: Boolean + ): DefaultDestinationTaskLauncher { + return DefaultDestinationTaskLauncher( + taskScopeProvider, + catalog, + config, + syncManager, + inputConsumerTaskFactory, + spillToDiskTaskFactory, + flushTickTask, + setupTaskFactory, + openStreamTaskFactory, + processRecordsTaskFactory, + processFileTaskFactory, + processBatchTaskFactory, + closeStreamTaskFactory, + teardownTaskFactory, + flushCheckpointsTaskFactory, + timedFlushTask, + updateCheckpointsTask, + failStreamTaskFactory, + failSyncTaskFactory, + useFileTranfer, + inputFlow, + recordQueueSupplier, + checkpointQueue, + fileTransferQueue, + ) + } + + @BeforeEach + fun init() { + coEvery { taskScopeProvider.launch(any()) } returns Unit + + val stream = mockk(relaxed = true) + val streamDescriptor = DestinationStream.Descriptor("namespace", "name") + every { stream.descriptor } returns streamDescriptor + coEvery { catalog.streams } returns listOf(stream) + } + + @Test + fun `test that we don't start the spill-to-disk task when file transfer is enabled`() = + runTest { + val destinationTaskLauncher = getDefaultDestinationTaskLauncher(true) + // This is needed to let the run method to complete + destinationTaskLauncher.handleTeardownComplete() + destinationTaskLauncher.run() + + coVerify { spillToDiskTaskFactory wasNot Called } + } + + @Test + fun `test that we start the spill-to-disk task when file transfer is disabled`() = runTest { + val spillToDiskTask = mockk(relaxed = true) + coEvery { spillToDiskTaskFactory.make(any(), any()) } returns spillToDiskTask + + val destinationTaskLauncher = getDefaultDestinationTaskLauncher(false) + // This is needed to let the run method to complete + destinationTaskLauncher.handleTeardownComplete() + destinationTaskLauncher.run() + + coVerify { spillToDiskTaskFactory.make(any(), any()) } + } + + @Test + fun `test handle exception`() = runTest { + val destinationTaskLauncher = getDefaultDestinationTaskLauncher(true) + launch { destinationTaskLauncher.run() } + val e = Exception("e") + destinationTaskLauncher.handleException(e) + destinationTaskLauncher.handleTeardownComplete() + + coVerify { failStreamTaskFactory.make(any(), e, any()) } + coVerify { taskScopeProvider.launch(match { it.innerTask is FailStreamTask }) } + } + + @Test + fun `test run close stream no more than once per stream`() = runTest { + val destinationTaskLauncher = getDefaultDestinationTaskLauncher(true) + val streamManager = mockk(relaxed = true) + coEvery { syncManager.getStreamManager(any()) } returns streamManager + coEvery { streamManager.isBatchProcessingComplete() } returns true + val descriptor = DestinationStream.Descriptor("namespace", "name") + destinationTaskLauncher.handleNewBatch( + descriptor, + BatchEnvelope(SimpleBatch(Batch.State.COMPLETE), null, descriptor) + ) + destinationTaskLauncher.handleNewBatch( + descriptor, + BatchEnvelope(SimpleBatch(Batch.State.COMPLETE), null, descriptor) + ) + coVerify(exactly = 1) { closeStreamTaskFactory.make(any(), any()) } + } +} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/MockTaskLauncher.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/MockTaskLauncher.kt index 7561e31d3dc6..da78d46d0e2a 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/MockTaskLauncher.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/MockTaskLauncher.kt @@ -6,7 +6,6 @@ package io.airbyte.cdk.load.task import io.airbyte.cdk.load.command.DestinationStream import io.airbyte.cdk.load.message.BatchEnvelope -import io.airbyte.cdk.load.task.internal.SpilledRawMessagesLocalFile import io.micronaut.context.annotation.Primary import io.micronaut.context.annotation.Requires import jakarta.inject.Singleton @@ -15,36 +14,42 @@ import jakarta.inject.Singleton @Primary @Requires(env = ["MockTaskLauncher"]) class MockTaskLauncher : DestinationTaskLauncher { - val spilledFiles = mutableListOf() val batchEnvelopes = mutableListOf>() override suspend fun handleSetupComplete() { throw NotImplementedError() } - override suspend fun handleStreamStarted(stream: DestinationStream) { + override suspend fun handleStreamStarted(stream: DestinationStream.Descriptor) { throw NotImplementedError() } - override suspend fun handleNewSpilledFile( - stream: DestinationStream, - file: SpilledRawMessagesLocalFile + override suspend fun handleNewBatch( + stream: DestinationStream.Descriptor, + wrapped: BatchEnvelope<*> ) { - spilledFiles.add(file) - } - - override suspend fun handleNewBatch(stream: DestinationStream, wrapped: BatchEnvelope<*>) { batchEnvelopes.add(wrapped) } - override suspend fun handleStreamClosed(stream: DestinationStream) { + override suspend fun handleStreamClosed(stream: DestinationStream.Descriptor) { throw NotImplementedError() } - override suspend fun handleTeardownComplete() { + override suspend fun handleTeardownComplete(success: Boolean) { throw NotImplementedError() } + override suspend fun handleException(e: Exception) { + TODO("Not yet implemented") + } + + override suspend fun handleFailStreamComplete( + stream: DestinationStream.Descriptor, + e: Exception + ) { + TODO("Not yet implemented") + } + override suspend fun run() { throw NotImplementedError() } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/ProcessBatchTaskTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/ProcessBatchTaskTest.kt new file mode 100644 index 000000000000..c808acc24b9b --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/ProcessBatchTaskTest.kt @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.task + +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.message.Batch +import io.airbyte.cdk.load.message.BatchEnvelope +import io.airbyte.cdk.load.message.MultiProducerChannel +import io.airbyte.cdk.load.message.SimpleBatch +import io.airbyte.cdk.load.state.SyncManager +import io.airbyte.cdk.load.task.implementor.DefaultProcessBatchTask +import io.airbyte.cdk.load.write.StreamLoader +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.mockk +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class ProcessBatchTaskTest { + private lateinit var syncManager: SyncManager + private lateinit var streamLoaders: Map + private lateinit var batchQueue: MultiProducerChannel> + private lateinit var taskLauncher: DestinationTaskLauncher + + @BeforeEach + fun setup() { + val streams = + (0 until 3).map { DestinationStream.Descriptor(namespace = "test", name = "stream$it") } + syncManager = mockk(relaxed = true) + streamLoaders = streams.associateWith { mockk(relaxed = true) } + streamLoaders.values.forEach { + coEvery { it.processBatch(any()) } returns SimpleBatch(Batch.State.COMPLETE) + } + coEvery { syncManager.getOrAwaitStreamLoader(any()) } answers + { + streamLoaders[firstArg()]!! + } + batchQueue = mockk(relaxed = true) + taskLauncher = mockk(relaxed = true) + } + + @Test + fun `test each enqueued batch passes through the associated processBatch`() = runTest { + val task = DefaultProcessBatchTask(syncManager, batchQueue, taskLauncher) + coEvery { batchQueue.consume() } returns + streamLoaders.keys + .map { + BatchEnvelope(streamDescriptor = it, batch = SimpleBatch(Batch.State.STAGED)) + } + .asFlow() + + task.execute() + + streamLoaders.forEach { (descriptor, loader) -> + coVerify { loader.processBatch(match { it.state == Batch.State.STAGED }) } + coVerify { + taskLauncher.handleNewBatch( + descriptor, + match { + it.streamDescriptor == descriptor && it.batch.state == Batch.State.COMPLETE + } + ) + } + } + } +} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/implementor/ProcessRecordsTaskTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/implementor/ProcessRecordsTaskTest.kt index 95d96473d56d..52146fc1472b 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/implementor/ProcessRecordsTaskTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/implementor/ProcessRecordsTaskTest.kt @@ -4,120 +4,191 @@ package io.airbyte.cdk.load.task.implementor +import com.fasterxml.jackson.databind.node.JsonNodeFactory import com.google.common.collect.Range -import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.command.DestinationConfiguration import io.airbyte.cdk.load.command.MockDestinationCatalogFactory import io.airbyte.cdk.load.data.IntegerValue import io.airbyte.cdk.load.message.Batch -import io.airbyte.cdk.load.message.Deserializer -import io.airbyte.cdk.load.message.DestinationMessage +import io.airbyte.cdk.load.message.BatchEnvelope import io.airbyte.cdk.load.message.DestinationRecord +import io.airbyte.cdk.load.message.DestinationRecordAirbyteValue +import io.airbyte.cdk.load.message.MessageQueue +import io.airbyte.cdk.load.message.MultiProducerChannel +import io.airbyte.cdk.load.message.ProtocolMessageDeserializer +import io.airbyte.cdk.load.state.ReservationManager import io.airbyte.cdk.load.state.SyncManager -import io.airbyte.cdk.load.task.MockTaskLauncher +import io.airbyte.cdk.load.task.DefaultDestinationTaskLauncher import io.airbyte.cdk.load.task.internal.SpilledRawMessagesLocalFile import io.airbyte.cdk.load.util.write +import io.airbyte.cdk.load.write.BatchAccumulator import io.airbyte.cdk.load.write.StreamLoader -import io.micronaut.context.annotation.Primary -import io.micronaut.context.annotation.Requires -import io.micronaut.test.extensions.junit5.annotation.MicronautTest -import jakarta.inject.Inject -import jakarta.inject.Singleton +import io.airbyte.protocol.models.v0.AirbyteMessage +import io.airbyte.protocol.models.v0.AirbyteRecordMessage +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.coVerifySequence +import io.mockk.mockk import java.nio.file.Files import kotlin.io.path.outputStream +import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test -@MicronautTest( - environments = - [ - "ProcessRecordsTaskTest", - "MockDestinationCatalog", - "MockTaskLauncher", - ] -) class ProcessRecordsTaskTest { - @Inject lateinit var processRecordsTaskFactory: DefaultProcessRecordsTaskFactory - @Inject lateinit var launcher: MockTaskLauncher - @Inject lateinit var syncManager: SyncManager + private lateinit var config: DestinationConfiguration + private lateinit var diskManager: ReservationManager + private lateinit var deserializer: ProtocolMessageDeserializer + private lateinit var streamLoader: StreamLoader + private lateinit var batchAccumulator: BatchAccumulator + private lateinit var inputQueue: MessageQueue + private lateinit var processRecordsTaskFactory: DefaultProcessRecordsTaskFactory + private lateinit var launcher: DefaultDestinationTaskLauncher + private lateinit var outputQueue: MultiProducerChannel> + private lateinit var syncManager: SyncManager + + @BeforeEach + fun setup() { + config = mockk(relaxed = true) + diskManager = mockk(relaxed = true) + inputQueue = mockk(relaxed = true) + outputQueue = mockk(relaxed = true) + syncManager = mockk(relaxed = true) + streamLoader = mockk(relaxed = true) + batchAccumulator = mockk(relaxed = true) + coEvery { config.processEmptyFiles } returns false + coEvery { syncManager.getOrAwaitStreamLoader(any()) } returns streamLoader + coEvery { streamLoader.createBatchAccumulator() } returns batchAccumulator + launcher = mockk(relaxed = true) + deserializer = mockk(relaxed = true) + coEvery { deserializer.deserialize(any()) } answers + { + DestinationRecord( + stream = MockDestinationCatalogFactory.stream1.descriptor, + message = + AirbyteMessage() + .withRecord( + AirbyteRecordMessage() + .withEmittedAt(0L) + .withData( + JsonNodeFactory.instance.numberNode( + firstArg().toLong() + ) + ) + ), + serialized = "ignored", + schema = io.airbyte.cdk.load.data.IntegerType + ) + } + processRecordsTaskFactory = + DefaultProcessRecordsTaskFactory( + config, + deserializer, + syncManager, + diskManager, + inputQueue, + outputQueue, + ) + } class MockBatch( + override val groupId: String?, override val state: Batch.State, - val reportedByteSize: Long, - val recordCount: Long, - val pmChecksum: Long, - ) : Batch - - class MockStreamLoader : StreamLoader { - override val stream: DestinationStream = MockDestinationCatalogFactory.stream1 - - data class SumAndCount(val sum: Long = 0, val count: Long = 0) - - override suspend fun processRecords( - records: Iterator, - totalSizeBytes: Long - ): Batch { - // Do a simple sum of the record values and count - // To demonstrate that the primed data was actually processed - val (sum, count) = - records.asSequence().fold(SumAndCount()) { acc, record -> - SumAndCount(acc.sum + (record.data as IntegerValue).value, acc.count + 1) - } - return MockBatch( - state = Batch.State.COMPLETE, - reportedByteSize = totalSizeBytes, - recordCount = count, - pmChecksum = sum - ) - } + recordIterator: Iterator + ) : Batch { + val records = recordIterator.asSequence().toList() } - @Singleton - @Primary - @Requires(env = ["ProcessRecordsTaskTest"]) - class MockDeserializer : Deserializer { - override fun deserialize(serialized: String): DestinationMessage { - return DestinationRecord( - stream = MockDestinationCatalogFactory.stream1.descriptor, - data = IntegerValue(serialized.toLong()), - emittedAtMs = 0L, - meta = null, - serialized = serialized, - ) + private val recordCount = 1024 + private val serializedRecords = (0 until 1024).map { "$it" } + private fun makeFile(index: Int): SpilledRawMessagesLocalFile { + val mockFile = Files.createTempFile("test_$index", ".jsonl") + mockFile.outputStream().use { outputStream -> + serializedRecords.map { "$it\n" }.forEach { outputStream.write(it) } } + return SpilledRawMessagesLocalFile( + localFile = mockFile, + totalSizeBytes = 999L, + indexRange = Range.closed(0, recordCount.toLong()) + ) } @Test - fun testProcessRecordsTask() = runTest { + fun `test standard workflow`() = runTest { val byteSize = 999L val recordCount = 1024L + val descriptor = MockDestinationCatalogFactory.stream1.descriptor - val mockFile = Files.createTempFile("test", ".jsonl") - val file = - SpilledRawMessagesLocalFile( - localFile = mockFile, - totalSizeBytes = byteSize, - indexRange = Range.closed(0, recordCount) - ) + // Put three files on the flow. + val files = (0 until 3).map { makeFile(it) } + coEvery { inputQueue.consume() } returns + files.map { FileAggregateMessage(descriptor, it) }.asFlow() + + // Process records returns batches in 3 states. + coEvery { batchAccumulator.processRecords(any(), any()) } answers + { + MockBatch( + groupId = null, + state = Batch.State.PERSISTED, + recordIterator = firstArg() + ) + } andThenAnswer + { + MockBatch(groupId = null, state = Batch.State.COMPLETE, recordIterator = firstArg()) + } andThenAnswer + { + MockBatch( + groupId = "foo", + state = Batch.State.PERSISTED, + recordIterator = firstArg() + ) + } + + // Run the task. val task = processRecordsTaskFactory.make( taskLauncher = launcher, - stream = MockDestinationCatalogFactory.stream1, - file = file ) - mockFile.outputStream().use { outputStream -> - (0 until recordCount).forEach { outputStream.write("$it\n") } - } - syncManager.registerStartedStreamLoader(MockStreamLoader()) task.execute() - Assertions.assertEquals(1, launcher.batchEnvelopes.size) - val batch = launcher.batchEnvelopes[0].batch as MockBatch - Assertions.assertEquals(Batch.State.COMPLETE, batch.state) - Assertions.assertEquals(999, batch.reportedByteSize) - Assertions.assertEquals(recordCount, batch.recordCount) - Assertions.assertEquals((0 until recordCount).sum(), batch.pmChecksum) - Assertions.assertFalse(Files.exists(mockFile), "ensure task deleted file") + fun batchMatcher(groupId: String?, state: Batch.State): (BatchEnvelope<*>) -> Boolean = { + it.ranges.encloses(Range.closed(0, recordCount)) && + it.streamDescriptor == descriptor && + it.batch.groupId == groupId && + it.batch.state == state && + it.batch is MockBatch && + (it.batch as MockBatch) + .records + .map { record -> (record.data as IntegerValue).value.toString() } + .toSet() == serializedRecords.toSet() + } + + // Verify the batch was *handled* 3 times but *published* ONLY when it is not complete AND + // group id is null. + coVerify(exactly = 1) { + outputQueue.publish(match { batchMatcher(null, Batch.State.PERSISTED)(it) }) + } + coVerifySequence { + launcher.handleNewBatch( + MockDestinationCatalogFactory.stream1.descriptor, + match { batchMatcher(null, Batch.State.PERSISTED)(it) } + ) + launcher.handleNewBatch( + MockDestinationCatalogFactory.stream1.descriptor, + match { batchMatcher(null, Batch.State.COMPLETE)(it) } + ) + launcher.handleNewBatch( + MockDestinationCatalogFactory.stream1.descriptor, + match { batchMatcher("foo", Batch.State.PERSISTED)(it) } + ) + } + + files.forEach { + Assertions.assertFalse(Files.exists(it.localFile), "ensure task deleted file $it") + } + coVerify(exactly = 3) { diskManager.release(byteSize) } } } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/internal/FlushTickTaskTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/internal/FlushTickTaskTest.kt new file mode 100644 index 000000000000..2ffeff5af451 --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/internal/FlushTickTaskTest.kt @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.task.internal + +import io.airbyte.cdk.load.command.Append +import io.airbyte.cdk.load.command.DestinationCatalog +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.data.FieldType +import io.airbyte.cdk.load.data.IntegerType +import io.airbyte.cdk.load.data.ObjectType +import io.airbyte.cdk.load.data.StringType +import io.airbyte.cdk.load.file.TimeProvider +import io.airbyte.cdk.load.message.DestinationStreamEvent +import io.airbyte.cdk.load.message.MessageQueue +import io.airbyte.cdk.load.message.MessageQueueSupplier +import io.airbyte.cdk.load.message.StreamFlushEvent +import io.airbyte.cdk.load.state.Reserved +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.junit5.MockKExtension +import io.mockk.mockk +import io.mockk.slot +import java.time.Clock +import java.util.stream.Stream +import kotlinx.coroutines.channels.ClosedSendChannelException +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.Arguments +import org.junit.jupiter.params.provider.MethodSource + +@ExtendWith(MockKExtension::class) +class FlushTickTaskTest { + @MockK(relaxed = true) lateinit var clock: Clock + @MockK(relaxed = true) lateinit var coroutineTimeUtils: TimeProvider + @MockK(relaxed = true) lateinit var catalog: DestinationCatalog + @MockK(relaxed = true) + lateinit var recordQueueSupplier: + MessageQueueSupplier> + + private val tickIntervalMs = 60000L // 1 min + + private lateinit var task: FlushTickTask + + @BeforeEach + fun setup() { + task = + FlushTickTask( + tickIntervalMs, + clock, + coroutineTimeUtils, + catalog, + recordQueueSupplier, + ) + } + + @Test + fun `waits for the configured amount of time`() = runTest { + task.waitAndPublishFlushTick() + + coVerify { coroutineTimeUtils.delay(tickIntervalMs) } + } + + @ParameterizedTest + @MethodSource("streamMatrix") + fun `publishes a flush message for each stream in the catalog`( + streams: List + ) = runTest { + every { catalog.streams } returns streams + val queues = + streams.associateWith { + mockk>>(relaxed = true) + } + + streams.forEach { + every { recordQueueSupplier.get(eq(it.descriptor)) } returns queues[it]!! + } + + task.waitAndPublishFlushTick() + + streams.forEach { + val msgSlot = slot>() + coVerify { queues[it]!!.publish(capture(msgSlot)) } + assert(msgSlot.captured.value is StreamFlushEvent) + } + } + + @Test + fun `does not attempt to send flush events for closed queues`() = runTest { + every { catalog.streams } returns + listOf(Fixtures.stream1, Fixtures.stream2, Fixtures.stream3) + val queue1 = mockk>>(relaxed = true) + val queue2 = + mockk>>(relaxed = true) { + every { isClosedForPublish() } returns true + } + val queue3 = mockk>>(relaxed = true) + + every { recordQueueSupplier.get(Fixtures.stream1.descriptor) } returns queue1 + every { recordQueueSupplier.get(Fixtures.stream2.descriptor) } returns queue2 + every { recordQueueSupplier.get(Fixtures.stream3.descriptor) } returns queue3 + + task.waitAndPublishFlushTick() + + val msgSlot1 = slot>() + coVerify(exactly = 1) { queue1.publish(capture(msgSlot1)) } + assert(msgSlot1.captured.value is StreamFlushEvent) + + // no event should be sent for 2 + coVerify(exactly = 0) { queue2.publish(any()) } + + val msgSlot3 = slot>() + coVerify(exactly = 1) { queue3.publish(capture(msgSlot3)) } + assert(msgSlot3.captured.value is StreamFlushEvent) + } + + @Test + fun `handles channel closed exceptions due to race`() = runTest { + every { catalog.streams } returns listOf(Fixtures.stream1, Fixtures.stream2) + val queue1 = + mockk>>(relaxed = true) { + coEvery { publish(any()) } throws ClosedSendChannelException("Closed.") + } + val queue2 = mockk>>(relaxed = true) + + every { recordQueueSupplier.get(Fixtures.stream1.descriptor) } returns queue1 + every { recordQueueSupplier.get(Fixtures.stream2.descriptor) } returns queue2 + + task.waitAndPublishFlushTick() + + val msgSlot1 = slot>() + coVerify(exactly = 1) { queue1.publish(capture(msgSlot1)) } + assert(msgSlot1.captured.value is StreamFlushEvent) + + val msgSlot2 = slot>() + coVerify(exactly = 1) { queue2.publish(capture(msgSlot2)) } + assert(msgSlot2.captured.value is StreamFlushEvent) + } + + companion object { + @JvmStatic + fun streamMatrix(): Stream { + return Stream.of( + Arguments.of(listOf(Fixtures.stream1)), + Arguments.of(listOf(Fixtures.stream1, Fixtures.stream2)), + Arguments.of(listOf(Fixtures.stream1, Fixtures.stream3)), + Arguments.of(listOf(Fixtures.stream2, Fixtures.stream3)), + Arguments.of(listOf(Fixtures.stream1, Fixtures.stream2, Fixtures.stream3)), + ) + } + } + + object Fixtures { + val stream1 = + DestinationStream( + DestinationStream.Descriptor("test", "stream1"), + importType = Append, + schema = + ObjectType( + properties = + linkedMapOf( + "id" to FieldType(type = IntegerType, nullable = true), + "name" to FieldType(type = StringType, nullable = true), + ), + ), + generationId = 1, + minimumGenerationId = 0, + syncId = 42, + ) + val stream2 = + DestinationStream( + DestinationStream.Descriptor("test", "stream2"), + importType = Append, + schema = + ObjectType( + properties = + linkedMapOf( + "id" to FieldType(type = IntegerType, nullable = true), + "name" to FieldType(type = StringType, nullable = true), + ), + ), + generationId = 3, + minimumGenerationId = 0, + syncId = 42, + ) + val stream3 = + DestinationStream( + DestinationStream.Descriptor(null, "stream3"), + importType = Append, + schema = + ObjectType( + properties = + linkedMapOf( + "id" to FieldType(type = IntegerType, nullable = true), + "name" to FieldType(type = StringType, nullable = true), + ), + ), + generationId = 9, + minimumGenerationId = 0, + syncId = 42, + ) + } +} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/internal/InputConsumerTaskTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/internal/InputConsumerTaskTest.kt index 4dae1e367d35..02a402904910 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/internal/InputConsumerTaskTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/internal/InputConsumerTaskTest.kt @@ -4,231 +4,170 @@ package io.airbyte.cdk.load.task.internal -import com.fasterxml.jackson.databind.node.JsonNodeFactory -import io.airbyte.cdk.load.command.DestinationConfiguration +import io.airbyte.cdk.load.command.DestinationCatalog import io.airbyte.cdk.load.command.DestinationStream import io.airbyte.cdk.load.command.MockDestinationCatalogFactory -import io.airbyte.cdk.load.data.NullValue -import io.airbyte.cdk.load.message.CheckpointMessage import io.airbyte.cdk.load.message.CheckpointMessageWrapped import io.airbyte.cdk.load.message.DestinationMessage -import io.airbyte.cdk.load.message.DestinationRecord -import io.airbyte.cdk.load.message.DestinationRecordWrapped -import io.airbyte.cdk.load.message.DestinationStreamComplete -import io.airbyte.cdk.load.message.DestinationStreamIncomplete -import io.airbyte.cdk.load.message.GlobalCheckpoint +import io.airbyte.cdk.load.message.DestinationStreamEvent import io.airbyte.cdk.load.message.GlobalCheckpointWrapped import io.airbyte.cdk.load.message.MessageQueue import io.airbyte.cdk.load.message.MessageQueueSupplier -import io.airbyte.cdk.load.message.StreamCheckpoint import io.airbyte.cdk.load.message.StreamCheckpointWrapped -import io.airbyte.cdk.load.message.StreamCompleteWrapped -import io.airbyte.cdk.load.message.StreamRecordWrapped -import io.airbyte.cdk.load.state.MemoryManager +import io.airbyte.cdk.load.message.StreamRecordEvent +import io.airbyte.cdk.load.state.DefaultStreamManager +import io.airbyte.cdk.load.state.ReservationManager import io.airbyte.cdk.load.state.Reserved import io.airbyte.cdk.load.state.SyncManager -import io.airbyte.cdk.load.test.util.CoroutineTestUtils -import io.airbyte.cdk.load.util.takeUntilInclusive -import io.micronaut.context.annotation.Primary -import io.micronaut.context.annotation.Requires -import io.micronaut.test.extensions.junit5.annotation.MicronautTest -import jakarta.inject.Inject -import jakarta.inject.Singleton -import kotlinx.coroutines.channels.Channel +import io.airbyte.cdk.load.test.util.CoroutineTestUtils.Companion.assertThrows +import io.airbyte.cdk.load.test.util.StubDestinationMessageFactory +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.coVerifySequence +import io.mockk.impl.annotations.MockK +import io.mockk.mockk +import java.util.concurrent.ConcurrentLinkedQueue import kotlinx.coroutines.flow.FlowCollector -import kotlinx.coroutines.flow.take -import kotlinx.coroutines.flow.toList -import kotlinx.coroutines.launch import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test -@MicronautTest( - rebuildContext = true, - environments = - [ - "InputConsumerTaskTest", - "MockDestinationConfiguration", - "MockDestinationCatalog", - ] -) class InputConsumerTaskTest { - @Inject lateinit var config: DestinationConfiguration - @Inject lateinit var task: InputConsumerTask - @Inject - lateinit var recordQueueSupplier: - MessageQueueSupplier> - @Inject lateinit var checkpointQueue: MessageQueue> - @Inject lateinit var syncManager: SyncManager - @Inject lateinit var mockInputFlow: MockInputFlow - - @Singleton - @Primary - @Requires(env = ["InputConsumerTaskTest"]) - class MockInputFlow(val memoryManager: MemoryManager) : - SizedInputFlow> { - private val messages = Channel>>(Channel.UNLIMITED) - val initialMemory = memoryManager.remainingMemoryBytes - - override suspend fun collect( - collector: FlowCollector>> - ) { - for (message in messages) { - collector.emit(message) - } - } - - suspend fun addMessage(message: DestinationMessage, size: Long = 0L) { - messages.send(Pair(size, memoryManager.reserveBlocking(1, message))) - } - - fun stop() { - messages.close() - } - } - - private fun makeRecord(stream: DestinationStream, record: String): DestinationRecord { - return DestinationRecord( - stream = stream.descriptor, - data = NullValue, - emittedAtMs = 0, - meta = null, - serialized = record - ) - } - - private fun makeStreamComplete(stream: DestinationStream): DestinationStreamComplete { - return DestinationStreamComplete(stream = stream.descriptor, emittedAtMs = 0) - } - - private fun makeStreamIncomplete(stream: DestinationStream): DestinationStreamIncomplete { - return DestinationStreamIncomplete(stream = stream.descriptor, emittedAtMs = 0) + companion object { + val STREAM1 = DestinationStream.Descriptor("test", "stream1") + val STREAM2 = DestinationStream.Descriptor("test", "stream2") } - private fun makeStreamState(stream: DestinationStream, recordCount: Long): CheckpointMessage { - return StreamCheckpoint( - checkpoint = - CheckpointMessage.Checkpoint( - stream.descriptor, - JsonNodeFactory.instance.objectNode() - ), - sourceStats = CheckpointMessage.Stats(recordCount), - additionalProperties = emptyMap() - ) + @MockK(relaxed = true) + lateinit var recordQueueSupplier: + MessageQueueSupplier> + @MockK(relaxed = true) + lateinit var checkpointQueue: MessageQueue> + @MockK(relaxed = true) lateinit var syncManager: SyncManager + @MockK(relaxed = true) lateinit var memoryManager: ReservationManager + @MockK(relaxed = true) lateinit var inputFlow: ReservingDeserializingInputFlow + @MockK(relaxed = true) lateinit var catalog: DestinationCatalog + @MockK(relaxed = true) lateinit var stream1: DestinationStream + @MockK(relaxed = true) lateinit var stream2: DestinationStream + @MockK(relaxed = true) lateinit var queue1: MessageQueue> + @MockK(relaxed = true) lateinit var queue2: MessageQueue> + + @BeforeEach + fun setup() { + coEvery { stream1.descriptor } returns STREAM1 + coEvery { stream2.descriptor } returns STREAM2 + + coEvery { catalog.streams } returns listOf(stream1, stream2) + + coEvery { recordQueueSupplier.get(STREAM1) } returns queue1 + coEvery { recordQueueSupplier.get(STREAM2) } returns queue2 + + coEvery { syncManager.getStreamManager(STREAM1) } returns DefaultStreamManager(stream1) + coEvery { syncManager.getStreamManager(STREAM2) } returns DefaultStreamManager(stream2) } - private fun makeGlobalState(recordCount: Long): CheckpointMessage { - return GlobalCheckpoint( - state = JsonNodeFactory.instance.objectNode(), - sourceStats = CheckpointMessage.Stats(recordCount), - checkpoints = emptyList() - ) - } + private fun DestinationMessage.wrap(bytesReserved: Long) = + bytesReserved to Reserved(memoryManager, bytesReserved, this) @Test fun testSendRecords() = runTest { - val queue1 = recordQueueSupplier.get(MockDestinationCatalogFactory.stream1.descriptor) - val queue2 = recordQueueSupplier.get(MockDestinationCatalogFactory.stream2.descriptor) + coEvery { inputFlow.collect(any()) } coAnswers + { + val collector = firstArg>>>() + collector.emit( + StubDestinationMessageFactory.makeRecord( + MockDestinationCatalogFactory.stream1, + ) + .wrap(1L) + ) + repeat(2) { + collector.emit( + StubDestinationMessageFactory.makeRecord( + MockDestinationCatalogFactory.stream2, + ) + .wrap(it + 2L) + ) + } + } - val manager1 = - syncManager.getStreamManager(MockDestinationCatalogFactory.stream1.descriptor) - val manager2 = - syncManager.getStreamManager(MockDestinationCatalogFactory.stream2.descriptor) + val task = + DefaultInputConsumerTaskFactory(syncManager) + .make( + catalog = catalog, + inputFlow = inputFlow, + recordQueueSupplier = recordQueueSupplier, + checkpointQueue = checkpointQueue, + destinationTaskLauncher = mockk(), + fileTransferQueue = mockk(relaxed = true), + ) + task.execute() - (0 until 10).forEach { - mockInputFlow.addMessage( - makeRecord(MockDestinationCatalogFactory.stream1, "test${it}"), - it * 2L + coVerify(exactly = 1) { + queue1.publish( + match { + it.value is StreamRecordEvent && + (it.value as StreamRecordEvent).payload.stream == STREAM1 + } ) } - mockInputFlow.addMessage(makeStreamComplete(MockDestinationCatalogFactory.stream1)) - mockInputFlow.addMessage(makeStreamComplete(MockDestinationCatalogFactory.stream2)) - launch { task.execute() } - - val messages1 = - queue1 - .consume() - .takeUntilInclusive { - (it.value as StreamRecordWrapped).record.serialized == "test9" + coVerify(exactly = 2) { + queue2.publish( + match { + it.value is StreamRecordEvent && + (it.value as StreamRecordEvent).payload.stream == STREAM2 } - .toList() - - Assertions.assertEquals(10, messages1.size) - val expectedRecords = - (0 until 10).map { - StreamRecordWrapped( - it.toLong(), - it * 2L, - makeRecord(MockDestinationCatalogFactory.stream1, "test${it}") - ) - } - val streamComplete1: Reserved = - queue1.consume().take(1).toList().first() - val streamComplete2: Reserved = - queue2.consume().take(1).toList().first() - - Assertions.assertEquals(expectedRecords, messages1.map { it.value }) - Assertions.assertEquals(expectedRecords.map { _ -> 1L }, messages1.map { it.bytesReserved }) - Assertions.assertEquals(StreamCompleteWrapped(10), streamComplete1.value) - Assertions.assertEquals(1, streamComplete1.bytesReserved) - Assertions.assertEquals(10L, manager1.recordCount()) - Assertions.assertEquals(emptyList(), queue1.consume().toList()) - - Assertions.assertEquals(StreamCompleteWrapped(0), streamComplete2.value) - Assertions.assertEquals(emptyList(), queue2.consume().toList()) - Assertions.assertEquals(0L, manager2.recordCount()) - mockInputFlow.stop() + ) + } + assert(syncManager.getStreamManager(stream1.descriptor).recordCount() == 1L) + assert(syncManager.getStreamManager(stream2.descriptor).recordCount() == 2L) } @Test fun testSendEndOfStream() = runTest { - val queue1 = recordQueueSupplier.get(MockDestinationCatalogFactory.stream1.descriptor) - val queue2 = recordQueueSupplier.get(MockDestinationCatalogFactory.stream2.descriptor) - - val manager1 = - syncManager.getStreamManager(MockDestinationCatalogFactory.stream1.descriptor) - val manager2 = - syncManager.getStreamManager(MockDestinationCatalogFactory.stream2.descriptor) + coEvery { inputFlow.collect(any()) } coAnswers + { + val collector = firstArg>>>() + collector.emit( + StubDestinationMessageFactory.makeRecord( + MockDestinationCatalogFactory.stream1, + ) + .wrap(1L) + ) + collector.emit( + StubDestinationMessageFactory.makeStreamComplete( + MockDestinationCatalogFactory.stream1, + ) + .wrap(2L) + ) + collector.emit( + StubDestinationMessageFactory.makeStreamComplete( + MockDestinationCatalogFactory.stream2, + ) + .wrap(3L) + ) + } - (0 until 10).forEach { _ -> - mockInputFlow.addMessage( - makeRecord(MockDestinationCatalogFactory.stream1, "whatever"), - 0L - ) + val task = + DefaultInputConsumerTaskFactory(syncManager) + .make( + catalog = catalog, + inputFlow = inputFlow, + recordQueueSupplier = recordQueueSupplier, + checkpointQueue = checkpointQueue, + destinationTaskLauncher = mockk(), + fileTransferQueue = mockk(relaxed = true), + ) + task.execute() + coVerifySequence { + memoryManager.release(2L) + memoryManager.release(3L) } - mockInputFlow.addMessage(makeRecord(MockDestinationCatalogFactory.stream2, "test"), 1L) - mockInputFlow.addMessage(makeStreamComplete(MockDestinationCatalogFactory.stream1), 0L) - mockInputFlow.addMessage(makeStreamComplete(MockDestinationCatalogFactory.stream2), 0L) - val job = launch { task.execute() } - mockInputFlow.stop() - job.join() - queue2.close() - Assertions.assertEquals( - listOf( - StreamRecordWrapped( - 0, - 1L, - makeRecord(MockDestinationCatalogFactory.stream2, "test") - ), - StreamCompleteWrapped(1) - ), - queue2.consume().toList().map { it.value } - ) - Assertions.assertEquals(1L, manager2.recordCount()) - - Assertions.assertEquals(manager2.endOfStreamRead(), true) - Assertions.assertEquals(manager1.endOfStreamRead(), true) - - queue1.close() - val messages1 = queue1.consume().toList() - Assertions.assertEquals(11, messages1.size) - Assertions.assertEquals(messages1[10].value, StreamCompleteWrapped(10)) - Assertions.assertEquals( - mockInputFlow.initialMemory - 11, - mockInputFlow.memoryManager.remainingMemoryBytes, - "1 byte per message should have been reserved, but the end-of-stream should have been released" - ) + assert(syncManager.getStreamManager(stream1.descriptor).recordCount() == 1L) + assert(syncManager.getStreamManager(stream1.descriptor).endOfStreamRead()) + assert(syncManager.getStreamManager(stream2.descriptor).recordCount() == 0L) + assert(syncManager.getStreamManager(stream2.descriptor).endOfStreamRead()) } @Test @@ -247,18 +186,38 @@ class InputConsumerTaskTest { TestEvent(MockDestinationCatalogFactory.stream1, 3, 18), ) - launch { task.execute() } - batches.forEach { (stream, count, expectedCount) -> - repeat(count) { mockInputFlow.addMessage(makeRecord(stream, "test"), 1L) } - mockInputFlow.addMessage(makeStreamState(stream, count.toLong()), 0L) - val state = - checkpointQueue.consume().take(1).toList().first().value as StreamCheckpointWrapped - Assertions.assertEquals(expectedCount, state.index) - Assertions.assertEquals(count.toLong(), state.checkpoint.destinationStats?.recordCount) + val task = + DefaultInputConsumerTaskFactory(syncManager) + .make( + catalog = catalog, + inputFlow = inputFlow, + recordQueueSupplier = recordQueueSupplier, + checkpointQueue = checkpointQueue, + destinationTaskLauncher = mockk(), + fileTransferQueue = mockk(relaxed = true), + ) + coEvery { inputFlow.collect(any()) } coAnswers + { + val collector = firstArg>>>() + batches.forEach { (stream, count, _) -> + repeat(count) { + collector.emit(StubDestinationMessageFactory.makeRecord(stream).wrap(1L)) + } + collector.emit( + StubDestinationMessageFactory.makeStreamState(stream, count.toLong()) + .wrap(0L) + ) + } + } + task.execute() + + val published = ConcurrentLinkedQueue>() + coEvery { checkpointQueue.publish(any()) } coAnswers { published.add(firstArg()) } + published.toList().zip(batches).forEach { (checkpoint, event) -> + val wrapped = checkpoint.value + Assertions.assertEquals(event.expectedStateIndex, wrapped.index) + Assertions.assertEquals(event.stream.descriptor, wrapped.stream) } - mockInputFlow.addMessage(makeStreamComplete(MockDestinationCatalogFactory.stream1)) - mockInputFlow.addMessage(makeStreamComplete(MockDestinationCatalogFactory.stream2)) - mockInputFlow.stop() } @Test @@ -283,46 +242,90 @@ class InputConsumerTaskTest { SendState(14, 8, 0), ) - launch { task.execute() } - batches.forEach { event -> - when (event) { - is AddRecords -> { - repeat(event.count) { - mockInputFlow.addMessage(makeRecord(event.stream, "test"), 1L) + val task = + DefaultInputConsumerTaskFactory(syncManager) + .make( + catalog = catalog, + inputFlow = inputFlow, + recordQueueSupplier = recordQueueSupplier, + checkpointQueue = checkpointQueue, + destinationTaskLauncher = mockk(), + fileTransferQueue = mockk(relaxed = true), + ) + + coEvery { inputFlow.collect(any()) } coAnswers + { + val collector = firstArg>>>() + batches.forEach { event -> + when (event) { + is AddRecords -> { + repeat(event.count) { + collector.emit( + StubDestinationMessageFactory.makeRecord(event.stream).wrap(1L) + ) + } + } + is SendState -> { + collector.emit( + StubDestinationMessageFactory.makeGlobalState( + event.expectedStream1Count + ) + .wrap(0L) + ) + } } } - is SendState -> { - mockInputFlow.addMessage(makeGlobalState(event.expectedStream1Count), 0L) - val state = - checkpointQueue.consume().take(1).toList().first().value - as GlobalCheckpointWrapped - val stream1State = - state.streamIndexes.find { - it.first == MockDestinationCatalogFactory.stream1.descriptor - }!! - val stream2State = - state.streamIndexes.find { - it.first == MockDestinationCatalogFactory.stream2.descriptor - }!! - Assertions.assertEquals(event.expectedStream1Count, stream1State.second) - Assertions.assertEquals(event.expectedStream2Count, stream2State.second) - Assertions.assertEquals( - event.expectedStats, - state.checkpoint.destinationStats?.recordCount - ) - } } + val checkpoints = ConcurrentLinkedQueue>() + coEvery { checkpointQueue.publish(any()) } coAnswers { checkpoints.add(firstArg()) } + + task.execute() + + checkpoints.toList().zip(batches.filterIsInstance()).forEach { + (checkpoint, event) -> + val wrapped = checkpoint.value + val stream1State = wrapped.streamIndexes.find { it.first == stream1.descriptor }!! + val stream2State = wrapped.streamIndexes.find { it.first == stream2.descriptor }!! + Assertions.assertEquals(event.expectedStream1Count, stream1State.second) + Assertions.assertEquals(event.expectedStream2Count, stream2State.second) + Assertions.assertEquals( + event.expectedStats, + wrapped.checkpoint.destinationStats?.recordCount + ) } - mockInputFlow.addMessage(makeStreamComplete(MockDestinationCatalogFactory.stream1)) - mockInputFlow.addMessage(makeStreamComplete(MockDestinationCatalogFactory.stream2)) - mockInputFlow.stop() } @Test - fun testStreamIncompleteThrows() = runTest { - mockInputFlow.addMessage(makeRecord(MockDestinationCatalogFactory.stream1, "test"), 1L) - mockInputFlow.addMessage(makeStreamIncomplete(MockDestinationCatalogFactory.stream1), 0L) - CoroutineTestUtils.assertThrows(IllegalStateException::class) { task.execute() } - mockInputFlow.stop() + fun testFileStreamIncompleteThrows() = runTest { + coEvery { inputFlow.collect(any()) } coAnswers + { + val collector = firstArg>>>() + collector.emit( + StubDestinationMessageFactory.makeFile( + MockDestinationCatalogFactory.stream1, + "test" + ) + .wrap(1L) + ) + collector.emit( + StubDestinationMessageFactory.makeFileStreamIncomplete( + MockDestinationCatalogFactory.stream1 + ) + .wrap(0L) + ) + } + + val task = + DefaultInputConsumerTaskFactory(syncManager) + .make( + catalog = catalog, + inputFlow = inputFlow, + recordQueueSupplier = recordQueueSupplier, + checkpointQueue = checkpointQueue, + destinationTaskLauncher = mockk(relaxed = true), + fileTransferQueue = mockk(relaxed = true), + ) + + assertThrows(IllegalStateException::class) { task.execute() } } } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/internal/ReservingDeserializingInputFlowTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/internal/ReservingDeserializingInputFlowTest.kt index 91c2faf8b6db..63cb5a036c76 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/internal/ReservingDeserializingInputFlowTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/internal/ReservingDeserializingInputFlowTest.kt @@ -5,107 +5,73 @@ package io.airbyte.cdk.load.task.internal import io.airbyte.cdk.load.command.DestinationConfiguration -import io.airbyte.cdk.load.message.Deserializer -import io.airbyte.cdk.load.state.MemoryManager -import io.micronaut.context.annotation.Primary -import io.micronaut.context.annotation.Requires -import io.micronaut.test.extensions.junit5.annotation.MicronautTest -import jakarta.inject.Inject -import jakarta.inject.Singleton -import java.io.InputStream -import java.util.stream.Stream +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.data.ObjectTypeWithoutSchema +import io.airbyte.cdk.load.message.DestinationRecord +import io.airbyte.cdk.load.message.DestinationRecordSerialized +import io.airbyte.cdk.load.message.ProtocolMessageDeserializer +import io.airbyte.cdk.load.state.ReservationManager +import io.airbyte.cdk.load.state.Reserved +import io.airbyte.protocol.models.v0.AirbyteMessage +import io.mockk.coEvery +import io.mockk.impl.annotations.MockK +import java.io.ByteArrayInputStream import kotlinx.coroutines.flow.toList import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.extension.ExtensionContext -import org.junit.jupiter.params.ParameterizedTest -import org.junit.jupiter.params.provider.Arguments -import org.junit.jupiter.params.provider.ArgumentsProvider -import org.junit.jupiter.params.provider.ArgumentsSource +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test -@MicronautTest( - rebuildContext = true, - environments = - [ - "ReservingDeserializingInputFlowTest", - "MockDestinationCatalog", - "MockDestinationConfiguration" - ], -) class ReservingDeserializingInputFlowTest { - @Inject lateinit var config: DestinationConfiguration - @Inject lateinit var inputFlow: ReservingDeserializingInputFlow - @Inject lateinit var inputStream: MockInputStream - - @Singleton - @Primary - @Requires(env = ["ReservingDeserializingInputFlowTest"]) - class MockInputFlow( - override val config: DestinationConfiguration, - override val inputStream: InputStream, - override val deserializer: Deserializer, - override val memoryManager: MemoryManager, - ) : ReservingDeserializingInputFlow() - - @Singleton - @Primary - @Requires(env = ["ReservingDeserializingInputFlowTest"]) - class MockDeserializer : Deserializer { - override fun deserialize(serialized: String): String { - return serialized.reversed() + "!" - } + companion object { + const val RATIO = 1.1 } - @Singleton - @Primary - @Requires(env = ["ReservingDeserializingInputFlowTest"]) - class MockInputStream : InputStream() { - val chars = mutableListOf() + @MockK(relaxed = true) lateinit var config: DestinationConfiguration + @MockK(relaxed = true) lateinit var deserializer: ProtocolMessageDeserializer + @MockK(relaxed = true) lateinit var memoryManager: ReservationManager + @MockK(relaxed = true) lateinit var stream: DestinationStream.Descriptor + lateinit var inputFlow: ReservingDeserializingInputFlow - fun load(lines: List) { - lines.forEach { line -> - chars.addAll(line.toList()) - chars.add('\n') + @BeforeEach + fun setup() { + coEvery { memoryManager.reserve(any(), any()) } answers + { + Reserved(memoryManager, firstArg(), secondArg()) } - } - - override fun read(): Int { - return if (chars.isEmpty()) { - -1 - } else { - chars.removeAt(0).code - } - } } - class InputConsumerTestArgumentsProvider : ArgumentsProvider { - override fun provideArguments(context: ExtensionContext): Stream { - return Stream.of( - Arguments.of(listOf("cat", "dog", "turtle")), - Arguments.of(listOf("", "109j321dcDASD", "2023", "1", "2", "3")) + @Test + fun testInputConsumer() = runTest { + val records = + listOf( + "foo", + "hello there", + "goodbye", ) - } - } + val bytes = records.joinToString("\n").toByteArray() + val inputStream = ByteArrayInputStream(bytes) - @ParameterizedTest - @ArgumentsSource(InputConsumerTestArgumentsProvider::class) - fun testInputConsumer(testInput: List) = runTest { - inputStream.load(testInput) - val inputs = inputFlow.toList() - Assertions.assertEquals( - testInput.filter { it != "" }.map { it.reversed() + "!" }, - inputs.map { it.second.value }.toList() - ) - Assertions.assertEquals( - testInput.filter { it != "" }.map { it.length.toLong() }, - inputs.map { it.first }.toList() - ) - Assertions.assertEquals( - testInput - .filter { it != "" } - .map { (it.length.toLong() * config.estimatedRecordMemoryOverheadRatio).toLong() } - .toList(), - inputs.map { it.second.bytesReserved }.toList() - ) + inputFlow = + ReservingDeserializingInputFlow(config, deserializer, memoryManager, inputStream) + + coEvery { config.estimatedRecordMemoryOverheadRatio } returns RATIO + coEvery { deserializer.deserialize(any()) } answers + { + DestinationRecord( + stream, + AirbyteMessage(), + firstArg().reversed() + "!", + ObjectTypeWithoutSchema + ) + } + val inputs = + inputFlow.toList().map { + it.first to (it.second.value as DestinationRecord).asRecordSerialized() + } + val expectedOutputs = + records.map { + it.length.toLong() to DestinationRecordSerialized(stream, it.reversed() + "!") + } + assert(inputs == expectedOutputs) } } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/internal/SpillToDiskTaskTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/internal/SpillToDiskTaskTest.kt index 1eaa0cb74a7a..23fca2007bd9 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/internal/SpillToDiskTaskTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/task/internal/SpillToDiskTaskTest.kt @@ -7,123 +7,275 @@ package io.airbyte.cdk.load.task.internal import com.google.common.collect.Range import io.airbyte.cdk.load.command.DestinationStream import io.airbyte.cdk.load.command.MockDestinationCatalogFactory -import io.airbyte.cdk.load.data.NullValue -import io.airbyte.cdk.load.message.DestinationRecord -import io.airbyte.cdk.load.message.DestinationRecordWrapped +import io.airbyte.cdk.load.command.MockDestinationConfiguration +import io.airbyte.cdk.load.file.DefaultSpillFileProvider +import io.airbyte.cdk.load.file.SpillFileProvider +import io.airbyte.cdk.load.message.DestinationRecordSerialized +import io.airbyte.cdk.load.message.DestinationStreamEvent +import io.airbyte.cdk.load.message.DestinationStreamEventQueue +import io.airbyte.cdk.load.message.DestinationStreamQueueSupplier import io.airbyte.cdk.load.message.MessageQueueSupplier -import io.airbyte.cdk.load.message.StreamCompleteWrapped -import io.airbyte.cdk.load.message.StreamRecordWrapped +import io.airbyte.cdk.load.message.MultiProducerChannel +import io.airbyte.cdk.load.message.StreamEndEvent +import io.airbyte.cdk.load.message.StreamFlushEvent +import io.airbyte.cdk.load.message.StreamRecordEvent import io.airbyte.cdk.load.state.FlushStrategy -import io.airbyte.cdk.load.state.MemoryManager +import io.airbyte.cdk.load.state.ReservationManager import io.airbyte.cdk.load.state.Reserved +import io.airbyte.cdk.load.state.TimeWindowTrigger +import io.airbyte.cdk.load.task.DestinationTaskLauncher import io.airbyte.cdk.load.task.MockTaskLauncher -import io.airbyte.cdk.load.util.lineSequence -import io.micronaut.context.annotation.Primary -import io.micronaut.context.annotation.Requires -import io.micronaut.test.extensions.junit5.annotation.MicronautTest -import jakarta.inject.Inject -import jakarta.inject.Singleton -import kotlin.io.path.inputStream +import io.airbyte.cdk.load.task.implementor.FileAggregateMessage +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.junit5.MockKExtension +import io.mockk.mockk +import java.time.Clock +import kotlinx.coroutines.launch import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith -@MicronautTest( - environments = - [ - "SpillToDiskTaskTest", - "MockDestinationConfiguration", - "MockDestinationCatalog", - "MockTempFileProvider", - "MockTaskLauncher", - ] -) class SpillToDiskTaskTest { - @Inject lateinit var memoryManager: MemoryManager - @Inject lateinit var spillToDiskTaskFactory: DefaultSpillToDiskTaskFactory - @Inject - lateinit var queueSupplier: - MessageQueueSupplier> - - @Singleton - @Primary - @Requires(env = ["SpillToDiskTaskTest"]) - class MockFlushStrategy : FlushStrategy { - override suspend fun shouldFlush( - stream: DestinationStream, - rangeRead: Range, - bytesProcessed: Long - ): Boolean { - return bytesProcessed >= 1024 + /** Validates task delegates to dependencies as expected. Does not test dependency behavior. */ + @Nested + @ExtendWith(MockKExtension::class) + inner class UnitTests { + @MockK(relaxed = true) lateinit var fileAccumulatorFactory: FileAccumulatorFactory + + @MockK(relaxed = true) lateinit var flushStrategy: FlushStrategy + + @MockK(relaxed = true) lateinit var taskLauncher: DestinationTaskLauncher + + @MockK(relaxed = true) lateinit var timeWindow: TimeWindowTrigger + + @MockK(relaxed = true) lateinit var diskManager: ReservationManager + + @MockK(relaxed = true) lateinit var outputQueue: MultiProducerChannel + + private lateinit var inputQueue: DestinationStreamEventQueue + + private lateinit var task: DefaultSpillToDiskTask + + @BeforeEach + fun setup() { + val acc = + FileAccumulator( + mockk(), + mockk(), + timeWindow, + ) + every { fileAccumulatorFactory.make() } returns acc + inputQueue = DestinationStreamEventQueue() + task = + DefaultSpillToDiskTask( + fileAccumulatorFactory, + inputQueue, + outputQueue, + flushStrategy, + MockDestinationCatalogFactory.stream1.descriptor, + diskManager, + taskLauncher, + false, + ) } - } - private suspend fun primeMessageQueue(): Long { - val queue = queueSupplier.get(MockDestinationCatalogFactory.stream1.descriptor) - val maxRecords = ((1024 * 1.5) / 8).toLong() - var recordsWritten = 0L - var bytesReserved = 0L - while (recordsWritten < maxRecords) { - val index = recordsWritten++ - bytesReserved++ - queue.publish( - memoryManager.reserveBlocking( - 1L, - StreamRecordWrapped( - index = index, - sizeBytes = 8, - record = - DestinationRecord( - stream = MockDestinationCatalogFactory.stream1.descriptor, - data = NullValue, - emittedAtMs = 0, - meta = null, - serialized = "test${index}" - ) + @Test + fun `publishes 'spilled file' aggregates according to flush strategy on stream record`() = + runTest { + val recordMsg = + StreamRecordEvent( + 3L, + 2L, + DestinationRecordSerialized( + MockDestinationCatalogFactory.stream1.descriptor, + "" + ) ) - ) - ) + // flush strategy returns true, so we flush + coEvery { flushStrategy.shouldFlush(any(), any(), any()) } returns true + inputQueue.publish(Reserved(value = recordMsg)) + + val job = launch { + task.execute() + coVerify(exactly = 1) { outputQueue.publish(any()) } + } + job.cancel() + } + + @Test + fun `publishes 'spilled file' aggregates on stream complete event`() = runTest { + val completeMsg = StreamEndEvent(0L) + inputQueue.publish(Reserved(value = completeMsg)) + + val job = launch { + task.execute() + coVerify(exactly = 1) { outputQueue.publish(any()) } + } + job.cancel() } - queue.publish(memoryManager.reserveBlocking(0L, StreamCompleteWrapped(index = maxRecords))) - return bytesReserved + + @Test + fun `publishes 'spilled file' aggregates according to time window on stream flush event`() = + runTest { + // flush strategy returns false, so it won't flush + coEvery { flushStrategy.shouldFlush(any(), any(), any()) } returns false + every { timeWindow.isComplete() } returns true + + val flushMsg = StreamFlushEvent(101L) + val recordMsg = + StreamRecordEvent( + 3L, + 2L, + DestinationRecordSerialized( + MockDestinationCatalogFactory.stream1.descriptor, + "" + ) + ) + + // must publish 1 record message so range isn't empty + inputQueue.publish(Reserved(value = recordMsg)) + inputQueue.publish(Reserved(value = flushMsg)) + + val job = launch { + task.execute() + coVerify(exactly = 1) { outputQueue.publish(any()) } + } + job.cancel() + } } - @Test - fun testSpillToDiskTask() = runTest { - val availableMemory = memoryManager.remainingMemoryBytes - val bytesReserved = primeMessageQueue() - Assertions.assertEquals(availableMemory - bytesReserved, memoryManager.remainingMemoryBytes) + /** + * Validates end to end behaviors including those of dependencies. Also exercises the factory. + */ + @Nested + inner class EndToEndTests { + private lateinit var memoryManager: ReservationManager + private lateinit var diskManager: ReservationManager + private lateinit var spillToDiskTaskFactory: DefaultSpillToDiskTaskFactory + private lateinit var taskLauncher: MockTaskLauncher + private lateinit var fileAccumulatorFactory: FileAccumulatorFactory + private val clock: Clock = mockk(relaxed = true) + private val flushWindowMs = 60000L - val mockTaskLauncher = MockTaskLauncher() - spillToDiskTaskFactory - .make(mockTaskLauncher, MockDestinationCatalogFactory.stream1) - .execute() - Assertions.assertEquals(1, mockTaskLauncher.spilledFiles.size) - spillToDiskTaskFactory - .make(mockTaskLauncher, MockDestinationCatalogFactory.stream1) - .execute() - Assertions.assertEquals(2, mockTaskLauncher.spilledFiles.size) + private lateinit var queueSupplier: + MessageQueueSupplier> + private lateinit var spillFileProvider: SpillFileProvider + private lateinit var outputQueue: MultiProducerChannel - Assertions.assertEquals(1024, mockTaskLauncher.spilledFiles[0].totalSizeBytes) - Assertions.assertEquals(512, mockTaskLauncher.spilledFiles[1].totalSizeBytes) + @BeforeEach + fun setup() { + outputQueue = mockk(relaxed = true) + spillFileProvider = DefaultSpillFileProvider(MockDestinationConfiguration()) + queueSupplier = + DestinationStreamQueueSupplier( + MockDestinationCatalogFactory().make(), + ) + fileAccumulatorFactory = FileAccumulatorFactory(flushWindowMs, spillFileProvider, clock) + taskLauncher = MockTaskLauncher() + memoryManager = ReservationManager(Fixtures.INITIAL_MEMORY_CAPACITY) + diskManager = ReservationManager(Fixtures.INITIAL_DISK_CAPACITY) + spillToDiskTaskFactory = + DefaultSpillToDiskTaskFactory( + MockDestinationConfiguration(), + fileAccumulatorFactory, + queueSupplier, + MockFlushStrategy(), + diskManager, + outputQueue, + ) + } - val spilled1 = mockTaskLauncher.spilledFiles[0] - val spilled2 = mockTaskLauncher.spilledFiles[1] - Assertions.assertEquals(1024, spilled1.totalSizeBytes) - Assertions.assertEquals(512, spilled2.totalSizeBytes) + @Test + fun `writes aggregates to files and manages disk and memory reservations`() = runTest { + val messageCount = primeMessageQueue() + val bytesReservedMemory = Fixtures.MEMORY_RESERVATION_SIZE_BYTES * messageCount + val bytesReservedDisk = Fixtures.SERIALIZED_SIZE_BYTES * messageCount - val file1 = spilled1.localFile - val file2 = spilled2.localFile + // memory manager has reserved bytes for messages + Assertions.assertEquals( + Fixtures.INITIAL_MEMORY_CAPACITY - bytesReservedMemory, + memoryManager.remainingCapacityBytes, + ) + // disk manager has not reserved any bytes + Assertions.assertEquals( + Fixtures.INITIAL_DISK_CAPACITY, + diskManager.remainingCapacityBytes, + ) - val expectedLinesFirst = (0 until 1024 / 8).flatMap { listOf("test$it") } - val expectedLinesSecond = (1024 / 8 until 1536 / 8).flatMap { listOf("test$it") } + val job = launch { + spillToDiskTaskFactory + .make(taskLauncher, MockDestinationCatalogFactory.stream1.descriptor) + .execute() + spillToDiskTaskFactory + .make(taskLauncher, MockDestinationCatalogFactory.stream1.descriptor) + .execute() - Assertions.assertEquals(expectedLinesFirst, file1.inputStream().lineSequence().toList()) - Assertions.assertEquals(expectedLinesSecond, file2.inputStream().lineSequence().toList()) + // we have released all memory reservations + Assertions.assertEquals( + Fixtures.INITIAL_MEMORY_CAPACITY, + memoryManager.remainingCapacityBytes, + ) + // we now have equivalent disk reservations + Assertions.assertEquals( + Fixtures.INITIAL_DISK_CAPACITY - bytesReservedDisk, + diskManager.remainingCapacityBytes, + ) + } + job.cancel() + } + + inner class MockFlushStrategy : FlushStrategy { + override suspend fun shouldFlush( + stream: DestinationStream.Descriptor, + rangeRead: Range, + bytesProcessed: Long + ): Boolean { + return bytesProcessed >= 1024 + } + } + + private suspend fun primeMessageQueue(): Long { + val queue = queueSupplier.get(MockDestinationCatalogFactory.stream1.descriptor) + val maxRecords = ((1024 * 1.5) / 8).toLong() + var recordsWritten = 0L + while (recordsWritten < maxRecords) { + val index = recordsWritten++ + queue.publish( + memoryManager.reserve( + Fixtures.MEMORY_RESERVATION_SIZE_BYTES, + StreamRecordEvent( + index = index, + sizeBytes = Fixtures.SERIALIZED_SIZE_BYTES, + payload = + DestinationRecordSerialized( + MockDestinationCatalogFactory.stream1.descriptor, + "", + ), + ), + ), + ) + } + queue.publish( + memoryManager.reserve( + 0L, + StreamEndEvent(index = maxRecords), + ), + ) + return recordsWritten + } + } - Assertions.assertEquals(availableMemory, memoryManager.remainingMemoryBytes) + object Fixtures { + const val INITIAL_DISK_CAPACITY = 100000L + const val INITIAL_MEMORY_CAPACITY = 200000L - file1.toFile().delete() - file2.toFile().delete() + const val SERIALIZED_SIZE_BYTES = 8L + const val MEMORY_RESERVATION_SIZE_BYTES = 10L } } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/test/util/RecordDifferTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/test/util/RecordDifferTest.kt index 56a7bb94737b..bfae3c54bfbe 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/test/util/RecordDifferTest.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/test/util/RecordDifferTest.kt @@ -5,6 +5,8 @@ package io.airbyte.cdk.load.test.util import java.time.OffsetDateTime +import kotlin.test.assertEquals +import kotlin.test.assertNull import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test @@ -106,16 +108,173 @@ class RecordDifferTest { Assertions.assertEquals( """ - Missing record (pk=[IntegerValue(value=1), IntegerValue(value=100)], cursor=TimestampValue(value=1970-01-01T00:00Z)): OutputRecord(rawId=null, extractedAt=1970-01-01T00:00:01.234Z, loadedAt=null, generationId=42, data=ObjectValue(values={id1=IntegerValue(value=1), id2=IntegerValue(value=100), updated_at=TimestampValue(value=1970-01-01T00:00Z), name=StringValue(value=alice), phone=StringValue(value=1234)}), airbyteMeta=null) - Incorrect record (pk=[IntegerValue(value=1), IntegerValue(value=100)], cursor=TimestampValue(value=1970-01-01T00:00:02Z)): + Missing record (pk=[IntegerValue(value=1), IntegerValue(value=100)], cursor=TimestampWithTimezoneValue(value=1970-01-01T00:00Z)): OutputRecord(rawId=null, extractedAt=1970-01-01T00:00:01.234Z, loadedAt=null, generationId=42, data=ObjectValue(values={id1=IntegerValue(value=1), id2=IntegerValue(value=100), updated_at=TimestampWithTimezoneValue(value=1970-01-01T00:00Z), name=StringValue(value=alice), phone=StringValue(value=1234)}), airbyteMeta=null) + Incorrect record (pk=[IntegerValue(value=1), IntegerValue(value=100)], cursor=TimestampWithTimezoneValue(value=1970-01-01T00:00:02Z)): generationId: Expected 42, got 41 airbyteMeta: Expected Meta(changes=[], syncId=42), got null phone: Expected StringValue(value=1234), but was StringValue(value=5678) email: Expected StringValue(value=charlie@example.com), but was address: Expected , but was StringValue(value=1234 charlie street) - Unexpected record (pk=[IntegerValue(value=1), IntegerValue(value=100)], cursor=TimestampValue(value=1970-01-01T00:00:03Z)): OutputRecord(rawId=null, extractedAt=1970-01-01T00:00:01.234Z, loadedAt=null, generationId=42, data=ObjectValue(values={id1=IntegerValue(value=1), id2=IntegerValue(value=100), updated_at=TimestampValue(value=1970-01-01T00:00:03Z), name=StringValue(value=dana)}), airbyteMeta=null) + Unexpected record (pk=[IntegerValue(value=1), IntegerValue(value=100)], cursor=TimestampWithTimezoneValue(value=1970-01-01T00:00:03Z)): OutputRecord(rawId=null, extractedAt=1970-01-01T00:00:01.234Z, loadedAt=null, generationId=42, data=ObjectValue(values={id1=IntegerValue(value=1), id2=IntegerValue(value=100), updated_at=TimestampWithTimezoneValue(value=1970-01-01T00:00:03Z), name=StringValue(value=dana)}), airbyteMeta=null) """.trimIndent(), diff ) } + + /** Verify that the differ can sort records which are identical other than the PK */ + @Test + fun testSortPk() { + val diff = + RecordDiffer(primaryKey = listOf(listOf("id")), cursor = null) + .diffRecords( + listOf( + OutputRecord( + extractedAt = 0, + generationId = 0, + data = mapOf("id" to 1, "name" to "foo"), + airbyteMeta = null, + ), + OutputRecord( + extractedAt = 0, + generationId = 0, + data = mapOf("id" to 2, "name" to "bar"), + airbyteMeta = null, + ), + ), + listOf( + OutputRecord( + extractedAt = 0, + generationId = 0, + data = mapOf("id" to 2, "name" to "bar"), + airbyteMeta = null, + ), + OutputRecord( + extractedAt = 0, + generationId = 0, + data = mapOf("id" to 1, "name" to "foo"), + airbyteMeta = null, + ), + ) + ) + assertNull(diff) + } + + /** Verify that the differ can sort records which are identical other than the cursor */ + @Test + fun testSortCursor() { + val diff = + RecordDiffer(primaryKey = listOf(listOf("id")), cursor = listOf("updated_at")) + .diffRecords( + listOf( + OutputRecord( + extractedAt = 0, + generationId = 0, + data = mapOf("id" to 1, "name" to "foo", "updated_at" to 1), + airbyteMeta = null, + ), + OutputRecord( + extractedAt = 0, + generationId = 0, + data = mapOf("id" to 1, "name" to "bar", "updated_at" to 2), + airbyteMeta = null, + ), + ), + listOf( + OutputRecord( + extractedAt = 0, + generationId = 0, + data = mapOf("id" to 1, "name" to "bar", "updated_at" to 2), + airbyteMeta = null, + ), + OutputRecord( + extractedAt = 0, + generationId = 0, + data = mapOf("id" to 1, "name" to "foo", "updated_at" to 1), + airbyteMeta = null, + ), + ), + ) + assertNull(diff) + } + + /** Verify that the differ can sort records which are identical other than extractedAt */ + @Test + fun testSortExtractedAt() { + val diff = + RecordDiffer(primaryKey = listOf(listOf("id")), cursor = null) + .diffRecords( + listOf( + OutputRecord( + extractedAt = 0, + generationId = 0, + data = mapOf("id" to 1, "name" to "foo"), + airbyteMeta = null, + ), + OutputRecord( + extractedAt = 1, + generationId = 0, + data = mapOf("id" to 1, "name" to "bar"), + airbyteMeta = null, + ), + ), + listOf( + OutputRecord( + extractedAt = 1, + generationId = 0, + data = mapOf("id" to 1, "name" to "bar"), + airbyteMeta = null, + ), + OutputRecord( + extractedAt = 0, + generationId = 0, + data = mapOf("id" to 1, "name" to "foo"), + airbyteMeta = null, + ), + ) + ) + assertNull(diff) + } + + @Test + fun testNullEqualsUnset() { + val diff = + RecordDiffer(primaryKey = listOf(listOf("id")), cursor = null, nullEqualsUnset = true) + .diffRecords( + listOf( + OutputRecord( + extractedAt = 1, + generationId = 0, + data = + mapOf( + "id" to 1, + "sub_object" to + mapOf( + "foo" to "bar", + "sub_list" to listOf(mapOf()), + ) + ), + airbyteMeta = null, + ), + ), + listOf( + OutputRecord( + extractedAt = 1, + generationId = 0, + data = + mapOf( + "id" to 1, + "name" to null, + "sub_object" to + mapOf( + "foo" to "bar", + "bar" to null, + "sub_list" to listOf(mapOf("foo" to null)), + ) + ), + airbyteMeta = null, + ), + ), + ) + assertNull(diff) + } } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/test/util/SchemaRecordBuilder.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/test/util/SchemaRecordBuilder.kt index b90cd930016e..789b45affa5c 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/test/util/SchemaRecordBuilder.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/test/util/SchemaRecordBuilder.kt @@ -34,14 +34,15 @@ class SchemaRecordBuilder( fun with( given: AirbyteType, expected: AirbyteType = given, - nameOverride: String? = null + nameOverride: String? = null, ): SchemaRecordBuilder { return with(FieldType(given, false), FieldType(expected, false), nameOverride) } fun withRecord( nullable: Boolean = false, - nameOverride: String? = null + nameOverride: String? = null, + expectedInstead: ObjectType? = null ): SchemaRecordBuilder> { val name = nameOverride ?: UUID.randomUUID().toString() val inputRecord = ObjectType(properties = LinkedHashMap()) @@ -50,7 +51,7 @@ class SchemaRecordBuilder( expectedSchema.properties[name] = FieldType(outputRecord, nullable = nullable) return SchemaRecordBuilder( inputSchema = inputRecord, - expectedSchema = outputRecord, + expectedSchema = expectedInstead ?: outputRecord, parent = this ) } @@ -61,10 +62,10 @@ class SchemaRecordBuilder( expectedInstead: FieldType? = null ): SchemaTestUnionBuilder { val name = nameOverride ?: UUID.randomUUID().toString() - val inputOptions = mutableListOf() + val inputOptions = mutableSetOf() val expectedOptions = if (expectedInstead == null) { - mutableListOf() + mutableSetOf() } else { null } @@ -91,8 +92,8 @@ class SchemaRecordBuilder( class SchemaTestUnionBuilder( private val parent: SchemaRecordBuilder, - private val options: MutableList, - private val expectedOptions: MutableList? + private val options: MutableSet, + private val expectedOptions: MutableSet? ) : SchemaRecordBuilderType { fun with(option: AirbyteType, expected: AirbyteType? = null): SchemaTestUnionBuilder { options.add(option) diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/test/util/StubDestinationMessageFactory.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/test/util/StubDestinationMessageFactory.kt new file mode 100644 index 000000000000..0a9583dfcbcc --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/test/util/StubDestinationMessageFactory.kt @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.test.util + +import com.fasterxml.jackson.databind.node.JsonNodeFactory +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.data.ObjectTypeWithoutSchema +import io.airbyte.cdk.load.message.CheckpointMessage +import io.airbyte.cdk.load.message.DestinationFile +import io.airbyte.cdk.load.message.DestinationFileStreamComplete +import io.airbyte.cdk.load.message.DestinationFileStreamIncomplete +import io.airbyte.cdk.load.message.DestinationRecord +import io.airbyte.cdk.load.message.DestinationRecordStreamComplete +import io.airbyte.cdk.load.message.DestinationRecordStreamIncomplete +import io.airbyte.cdk.load.message.GlobalCheckpoint +import io.airbyte.cdk.load.message.StreamCheckpoint +import io.airbyte.protocol.models.v0.AirbyteMessage +import io.airbyte.protocol.models.v0.AirbyteRecordMessage +import io.airbyte.protocol.models.v0.AirbyteStateMessage + +/* + * Shared factory methods for making stub destination messages for testing. + */ +object StubDestinationMessageFactory { + fun makeRecord(stream: DestinationStream): DestinationRecord { + return DestinationRecord( + stream = stream.descriptor, + message = + AirbyteMessage() + .withRecord( + AirbyteRecordMessage().withData(JsonNodeFactory.instance.nullNode()) + ), + serialized = "", + schema = ObjectTypeWithoutSchema + ) + } + + fun makeFile(stream: DestinationStream, record: String): DestinationFile { + return DestinationFile( + stream = stream.descriptor, + emittedAtMs = 0, + serialized = record, + fileMessage = nullFileMessage, + ) + } + + fun makeStreamComplete(stream: DestinationStream): DestinationRecordStreamComplete { + return DestinationRecordStreamComplete(stream = stream.descriptor, emittedAtMs = 0) + } + + fun makeFileStreamComplete(stream: DestinationStream): DestinationFileStreamComplete { + return DestinationFileStreamComplete(stream = stream.descriptor, emittedAtMs = 0) + } + + fun makeStreamIncomplete(stream: DestinationStream): DestinationRecordStreamIncomplete { + return DestinationRecordStreamIncomplete(stream = stream.descriptor, emittedAtMs = 0) + } + + fun makeFileStreamIncomplete(stream: DestinationStream): DestinationFileStreamIncomplete { + return DestinationFileStreamIncomplete(stream = stream.descriptor, emittedAtMs = 0) + } + + fun makeStreamState(stream: DestinationStream, recordCount: Long): CheckpointMessage { + return StreamCheckpoint( + checkpoint = + CheckpointMessage.Checkpoint( + stream.descriptor, + JsonNodeFactory.instance.objectNode() + ), + sourceStats = CheckpointMessage.Stats(recordCount), + ) + } + + fun makeGlobalState(recordCount: Long): CheckpointMessage { + return GlobalCheckpoint( + state = JsonNodeFactory.instance.objectNode(), + sourceStats = CheckpointMessage.Stats(recordCount), + checkpoints = emptyList(), + additionalProperties = emptyMap(), + originalTypeField = AirbyteStateMessage.AirbyteStateType.GLOBAL, + ) + } + + private val nullFileMessage = DestinationFile.AirbyteRecordMessageFile() +} diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/test/util/ValueTestBuilder.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/test/util/ValueTestBuilder.kt index 922cde30f918..3f8e0e10cd65 100644 --- a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/test/util/ValueTestBuilder.kt +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/test/util/ValueTestBuilder.kt @@ -6,6 +6,7 @@ package io.airbyte.cdk.load.test.util import io.airbyte.cdk.load.data.AirbyteType import io.airbyte.cdk.load.data.AirbyteValue +import io.airbyte.cdk.load.data.FieldType import io.airbyte.cdk.load.data.ObjectType import io.airbyte.cdk.load.data.ObjectValue import java.util.UUID @@ -21,12 +22,16 @@ data class ValueTestBuilder( inputValue: AirbyteValue, inputSchema: AirbyteType, expectedValue: AirbyteValue = inputValue, - nameOverride: String? = null + nameOverride: String? = null, + nullable: Boolean = false, ): ValueTestBuilder { val name = nameOverride ?: UUID.randomUUID().toString() inputValues.values[name] = inputValue expectedValues.values[name] = expectedValue - (schemaRecordBuilder as SchemaRecordBuilder<*>).with(inputSchema, nameOverride = name) + (schemaRecordBuilder as SchemaRecordBuilder<*>).with( + FieldType(inputSchema, nullable), + nameOverride = name + ) return this } diff --git a/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/util/TimeStringUtilityTest.kt b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/util/TimeStringUtilityTest.kt new file mode 100644 index 000000000000..676a66cc8d2a --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/test/kotlin/io/airbyte/cdk/load/util/TimeStringUtilityTest.kt @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.util + +import io.airbyte.cdk.load.data.AirbyteValueDeepCoercingMapper +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.LocalTime +import java.time.OffsetTime +import java.time.ZoneOffset +import java.time.ZonedDateTime +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertThrows +import org.junit.jupiter.api.Test + +internal class TimeStringUtilityTest { + + @Test + fun testToLocalDate() { + val localDateString = "2024-11-18" + val localDate = TimeStringUtility.toLocalDate(localDateString) + assertEquals( + LocalDate.parse(localDateString, AirbyteValueDeepCoercingMapper.DATE_TIME_FORMATTER), + localDate + ) + } + + @Test + fun testToLocalDateInvalidDateString() { + val invalidDateStr = "invalid-date" + assertThrows(java.time.format.DateTimeParseException::class.java) { + TimeStringUtility.toLocalDate(invalidDateStr) + } + } + + @Test + fun testToLocalDateTime() { + val localDateTimeString = "2024-11-18T12:34:56Z" + val localDateTime = TimeStringUtility.toLocalDateTime(localDateTimeString) + assertEquals( + LocalDateTime.parse( + localDateTimeString, + AirbyteValueDeepCoercingMapper.DATE_TIME_FORMATTER + ), + localDateTime + ) + } + + @Test + fun testToOffsetWithTimezone() { + val offsetWithTimezoneString = "12:34:56Z" + val offsetWithTimezone = TimeStringUtility.toOffset(offsetWithTimezoneString) + assertEquals( + OffsetTime.parse( + offsetWithTimezoneString, + AirbyteValueDeepCoercingMapper.TIME_FORMATTER + ) + .toLocalTime(), + offsetWithTimezone + ) + } + + @Test + fun testToOffsetWithoutTimezone() { + val offsetWithoutTimezoneString = "12:34:56" + val offsetWithoutTimezone = TimeStringUtility.toOffset(offsetWithoutTimezoneString) + assertEquals( + LocalTime.parse( + offsetWithoutTimezoneString, + AirbyteValueDeepCoercingMapper.TIME_FORMATTER + ), + offsetWithoutTimezone + ) + } + + @Test + fun testToOffsetDateTimeWithTimezone() { + val offsetWithTimezoneString = "2024-11-18T12:34:56Z" + val offsetWithTimezone = TimeStringUtility.toOffsetDateTime(offsetWithTimezoneString) + assertEquals( + ZonedDateTime.parse( + offsetWithTimezoneString, + AirbyteValueDeepCoercingMapper.DATE_TIME_FORMATTER + ) + .toOffsetDateTime(), + offsetWithTimezone + ) + } + + @Test + fun testToOffsetDateTimeWithoutTimezone() { + val offsetWithoutTimezoneString = "2024-11-18T12:34:56" + val offsetWithoutTimezone = TimeStringUtility.toOffsetDateTime(offsetWithoutTimezoneString) + assertEquals( + LocalDateTime.parse( + offsetWithoutTimezoneString, + AirbyteValueDeepCoercingMapper.DATE_TIME_FORMATTER + ) + .atOffset(ZoneOffset.UTC), + offsetWithoutTimezone + ) + } + + @Test + fun testToOffsetDateTimeInvalidFormat() { + val invalidDateTime = "invalid-datetime" + assertThrows(java.time.format.DateTimeParseException::class.java) { + TimeStringUtility.toOffsetDateTime(invalidDateTime) + } + } +} diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/check/CheckIntegrationTest.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/check/CheckIntegrationTest.kt index 5a880c207ed9..eb4e96872ec2 100644 --- a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/check/CheckIntegrationTest.kt +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/check/CheckIntegrationTest.kt @@ -6,6 +6,8 @@ package io.airbyte.cdk.load.check import io.airbyte.cdk.command.ConfigurationSpecification import io.airbyte.cdk.command.FeatureFlag +import io.airbyte.cdk.load.test.util.ConfigurationUpdater +import io.airbyte.cdk.load.test.util.FakeConfigurationUpdater import io.airbyte.cdk.load.test.util.FakeDataDumper import io.airbyte.cdk.load.test.util.IntegrationTest import io.airbyte.cdk.load.test.util.NoopDestinationCleaner @@ -25,19 +27,20 @@ import org.junit.jupiter.api.assertAll data class CheckTestConfig(val configPath: Path, val featureFlags: Set = emptySet()) open class CheckIntegrationTest( - val configurationClass: Class, val successConfigFilenames: List, val failConfigFilenamesAndFailureReasons: Map, + configUpdater: ConfigurationUpdater = FakeConfigurationUpdater, ) : IntegrationTest( - FakeDataDumper, - NoopDestinationCleaner, - NoopExpectedRecordMapper, + dataDumper = FakeDataDumper, + destinationCleaner = NoopDestinationCleaner, + recordMangler = NoopExpectedRecordMapper, + configUpdater = configUpdater, ) { @Test open fun testSuccessConfigs() { for ((path, featureFlags) in successConfigFilenames) { - val config = Files.readString(path, StandardCharsets.UTF_8) + val config = updateConfig(Files.readString(path, StandardCharsets.UTF_8)) val process = destinationProcessFactory.createDestinationProcess( "check", @@ -65,7 +68,7 @@ open class CheckIntegrationTest( open fun testFailConfigs() { for ((checkTestConfig, failurePattern) in failConfigFilenamesAndFailureReasons) { val (path, featureFlags) = checkTestConfig - val config = Files.readString(path) + val config = updateConfig(Files.readString(path)) val process = destinationProcessFactory.createDestinationProcess( "check", diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/file/MockTimeProvider.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/file/MockTimeProvider.kt index f51bdccb7478..771c2fd7c9eb 100644 --- a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/file/MockTimeProvider.kt +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/file/MockTimeProvider.kt @@ -13,17 +13,26 @@ import java.util.concurrent.atomic.AtomicLong @Primary @Requires(env = ["MockTimeProvider"]) open class MockTimeProvider : TimeProvider { + private var syncTime = AtomicLong(0) private var currentTime = AtomicLong(0) - override fun currentTimeMillis(): Long { - return currentTime.get() - } - fun setCurrentTime(currentTime: Long) { this.currentTime.set(currentTime) } + fun setSyncTime(currentTime: Long) { + this.syncTime.set(currentTime) + } + + override fun currentTimeMillis(): Long { + return currentTime.get() + } + override suspend fun delay(ms: Long) { currentTime.addAndGet(ms) } + + override fun syncTimeMillis(): Long { + return syncTime.get() + } } diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/message/InputMessage.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/message/InputMessage.kt new file mode 100644 index 000000000000..322e750056f6 --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/message/InputMessage.kt @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.message + +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.data.AirbyteValue +import io.airbyte.cdk.load.data.json.JsonToAirbyteValue +import io.airbyte.cdk.load.data.json.toJson +import io.airbyte.cdk.load.message.CheckpointMessage.Checkpoint +import io.airbyte.cdk.load.message.CheckpointMessage.Stats +import io.airbyte.cdk.load.util.deserializeToNode +import io.airbyte.protocol.models.v0.AirbyteMessage +import io.airbyte.protocol.models.v0.AirbyteRecordMessage + +sealed interface InputMessage { + fun asProtocolMessage(): AirbyteMessage +} + +data class InputRecord( + val stream: DestinationStream.Descriptor, + val data: AirbyteValue, + val emittedAtMs: Long, + val meta: Meta?, + val serialized: String, +) : InputMessage { + /** Convenience constructor, primarily intended for use in tests. */ + constructor( + namespace: String?, + name: String, + data: String, + emittedAtMs: Long, + changes: MutableList = mutableListOf(), + ) : this( + stream = DestinationStream.Descriptor(namespace, name), + data = JsonToAirbyteValue().convert(data.deserializeToNode()), + emittedAtMs = emittedAtMs, + meta = Meta(changes), + serialized = "", + ) + + override fun asProtocolMessage(): AirbyteMessage = + AirbyteMessage() + .withType(AirbyteMessage.Type.RECORD) + .withRecord( + AirbyteRecordMessage() + .withStream(stream.name) + .withNamespace(stream.namespace) + .withEmittedAt(emittedAtMs) + .withData(data.toJson()) + .also { + if (meta != null) { + it.withMeta(meta.asProtocolObject()) + } + } + ) +} + +data class InputFile( + val file: DestinationFile, +) : InputMessage { + constructor( + stream: DestinationStream.Descriptor, + emittedAtMs: Long, + fileMessage: DestinationFile.AirbyteRecordMessageFile, + serialized: String = "" + ) : this( + DestinationFile( + stream, + emittedAtMs, + serialized, + fileMessage, + ) + ) + override fun asProtocolMessage(): AirbyteMessage = file.asProtocolMessage() +} + +sealed interface InputCheckpoint : InputMessage + +data class InputStreamCheckpoint(val checkpoint: StreamCheckpoint) : InputCheckpoint { + constructor( + streamNamespace: String?, + streamName: String, + blob: String, + sourceRecordCount: Long, + destinationRecordCount: Long? = null, + ) : this( + StreamCheckpoint( + Checkpoint( + DestinationStream.Descriptor(streamNamespace, streamName), + state = blob.deserializeToNode() + ), + Stats(sourceRecordCount), + destinationRecordCount?.let { Stats(it) }, + emptyMap(), + ) + ) + override fun asProtocolMessage(): AirbyteMessage = checkpoint.asProtocolMessage() +} diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/spec/SpecTest.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/spec/SpecTest.kt index d2dd15ae9541..3b5eb90de778 100644 --- a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/spec/SpecTest.kt +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/spec/SpecTest.kt @@ -5,11 +5,10 @@ package io.airbyte.cdk.load.spec import com.deblock.jsondiff.DiffGenerator -import com.deblock.jsondiff.diff.JsonDiff import com.deblock.jsondiff.matcher.CompositeJsonMatcher import com.deblock.jsondiff.matcher.JsonMatcher -import com.deblock.jsondiff.matcher.LenientJsonObjectPartialMatcher import com.deblock.jsondiff.matcher.StrictJsonArrayPartialMatcher +import com.deblock.jsondiff.matcher.StrictJsonObjectPartialMatcher import com.deblock.jsondiff.matcher.StrictPrimitivePartialMatcher import com.deblock.jsondiff.viewer.OnlyErrorDiffViewer import io.airbyte.cdk.command.FeatureFlag @@ -17,7 +16,8 @@ import io.airbyte.cdk.load.test.util.FakeDataDumper import io.airbyte.cdk.load.test.util.IntegrationTest import io.airbyte.cdk.load.test.util.NoopDestinationCleaner import io.airbyte.cdk.load.test.util.NoopExpectedRecordMapper -import io.airbyte.cdk.util.Jsons +import io.airbyte.cdk.load.util.Jsons +import io.airbyte.cdk.load.util.deserializeToPrettyPrintedString import io.airbyte.protocol.models.v0.AirbyteMessage import java.nio.file.Files import java.nio.file.Path @@ -36,10 +36,12 @@ import org.junit.jupiter.api.assertAll */ abstract class SpecTest : IntegrationTest( - FakeDataDumper, - NoopDestinationCleaner, - NoopExpectedRecordMapper, + dataDumper = FakeDataDumper, + destinationCleaner = NoopDestinationCleaner, + recordMangler = NoopExpectedRecordMapper, ) { + private val testResourcesPath = Path.of("src/test-integration/resources") + @Test fun testSpecOss() { testSpec("expected-spec-oss.json") @@ -54,14 +56,18 @@ abstract class SpecTest : expectedSpecFilename: String, vararg featureFlags: FeatureFlag, ) { - val expectedSpecPath = Path.of("src/test-integration/resources", expectedSpecFilename) + val expectedSpecPath = testResourcesPath.resolve(expectedSpecFilename) if (!Files.exists(expectedSpecPath)) { + Files.createDirectories(testResourcesPath) Files.createFile(expectedSpecPath) } val expectedSpec = Files.readString(expectedSpecPath) val process = - destinationProcessFactory.createDestinationProcess("spec", featureFlags = featureFlags) + destinationProcessFactory.createDestinationProcess( + "spec", + featureFlags = featureFlags, + ) runBlocking { process.run() } val messages = process.readMessages() val specMessages = messages.filter { it.type == AirbyteMessage.Type.SPEC } @@ -73,22 +79,34 @@ abstract class SpecTest : ) val spec = specMessages.first().spec - val actualSpecPrettyPrint: String = - Jsons.writerWithDefaultPrettyPrinter().writeValueAsString(spec) + val actualSpecPrettyPrint: String = spec.deserializeToPrettyPrintedString() Files.write(expectedSpecPath, actualSpecPrettyPrint.toByteArray()) val jsonMatcher: JsonMatcher = CompositeJsonMatcher( StrictJsonArrayPartialMatcher(), - LenientJsonObjectPartialMatcher(), + StrictJsonObjectPartialMatcher(), StrictPrimitivePartialMatcher(), ) - val diff: JsonDiff = - DiffGenerator.diff(expectedSpec, Jsons.writeValueAsString(spec), jsonMatcher) + val diff = + OnlyErrorDiffViewer.from( + DiffGenerator.diff(expectedSpec, Jsons.writeValueAsString(spec), jsonMatcher) + ) + .toString() assertAll( "Spec snapshot test failed. Run this test locally and then `git diff <...>/$expectedSpecFilename` to see what changed, and commit the diff if that change was intentional.", - { Assertions.assertEquals("", OnlyErrorDiffViewer.from(diff).toString()) }, - { Assertions.assertEquals(expectedSpec, actualSpecPrettyPrint) } + { + Assertions.assertTrue( + diff.isEmpty(), + "Detected semantic diff in JSON:\n" + diff.prependIndent("\t\t") + ) + }, + { + Assertions.assertTrue( + expectedSpec == actualSpecPrettyPrint, + "File contents did not equal generated spec, see git diff for details" + ) + } ) } } diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/AirbyteValueWithMetaToOutputRecord.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/AirbyteValueWithMetaToOutputRecord.kt index 76daff1b4bdc..20c70534e0f9 100644 --- a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/AirbyteValueWithMetaToOutputRecord.kt +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/AirbyteValueWithMetaToOutputRecord.kt @@ -9,39 +9,40 @@ import io.airbyte.cdk.load.data.ArrayValue import io.airbyte.cdk.load.data.IntegerValue import io.airbyte.cdk.load.data.ObjectValue import io.airbyte.cdk.load.data.StringValue -import io.airbyte.cdk.load.message.DestinationRecord +import io.airbyte.cdk.load.data.TimestampWithTimezoneValue +import io.airbyte.cdk.load.message.Meta import io.airbyte.protocol.models.v0.AirbyteRecordMessageMetaChange import java.time.Instant -import java.util.* +import java.util.UUID class AirbyteValueWithMetaToOutputRecord { fun convert(value: ObjectValue): OutputRecord { - val meta = value.values[DestinationRecord.Meta.COLUMN_NAME_AB_META] as ObjectValue + val meta = value.values[Meta.COLUMN_NAME_AB_META] as ObjectValue return OutputRecord( rawId = - UUID.fromString( - (value.values[DestinationRecord.Meta.COLUMN_NAME_AB_RAW_ID] as StringValue) - .value - ), + UUID.fromString((value.values[Meta.COLUMN_NAME_AB_RAW_ID] as StringValue).value), extractedAt = Instant.ofEpochMilli( - (value.values[DestinationRecord.Meta.COLUMN_NAME_AB_EXTRACTED_AT] - as IntegerValue) - .value + value.values[Meta.COLUMN_NAME_AB_EXTRACTED_AT].let { v -> + when (v) { + is IntegerValue -> v.value.toLong() + is TimestampWithTimezoneValue -> v.value.toEpochSecond() + else -> throw IllegalArgumentException("Invalid extractedAt value: $v") + } + } ), loadedAt = null, - data = value.values[DestinationRecord.Meta.COLUMN_NAME_DATA] as ObjectValue, + data = value.values[Meta.COLUMN_NAME_DATA] as ObjectValue, generationId = - (value.values[DestinationRecord.Meta.COLUMN_NAME_AB_GENERATION_ID] as IntegerValue) - .value, + (value.values[Meta.COLUMN_NAME_AB_GENERATION_ID] as IntegerValue).value.toLong(), airbyteMeta = OutputRecord.Meta( - syncId = (meta.values["sync_id"] as IntegerValue).value, + syncId = (meta.values["sync_id"] as IntegerValue).value.toLong(), changes = (meta.values["changes"] as ArrayValue) .values .map { - DestinationRecord.Change( + Meta.Change( field = ((it as ObjectValue).values["field"] as StringValue).value, change = @@ -60,6 +61,18 @@ class AirbyteValueWithMetaToOutputRecord { } } +fun AirbyteValue.maybeUnflatten(wasFlattened: Boolean): ObjectValue { + this as ObjectValue + if (!wasFlattened) { + return this + } + val (meta, data) = this.values.toList().partition { Meta.COLUMN_NAMES.contains(it.first) } + val properties = LinkedHashMap(meta.toMap()) + val dataObject = ObjectValue(LinkedHashMap(data.toMap())) + properties[Meta.COLUMN_NAME_DATA] = dataObject + return ObjectValue(properties) +} + fun AirbyteValue.toOutputRecord(): OutputRecord { return AirbyteValueWithMetaToOutputRecord().convert(this as ObjectValue) } diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/ConfigurationUpdater.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/ConfigurationUpdater.kt new file mode 100644 index 000000000000..ed24d261a649 --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/ConfigurationUpdater.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.test.util + +/** Utility that may update/modify a connector configuration for test purposes. */ +interface ConfigurationUpdater { + + /** + * May modify one or more entry in the provided configuration. + * @param config The connector configuration. + * @return The potentially modified configuration. + */ + fun update(config: String): String +} + +/** + * Basic implementation of the [ConfigurationUpdater] interface that does not modify the + * configuration. + */ +object FakeConfigurationUpdater : ConfigurationUpdater { + override fun update(config: String): String = config +} diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/DestinationCleaner.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/DestinationCleaner.kt index 1ab6c2e20f10..84375e28ea31 100644 --- a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/DestinationCleaner.kt +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/DestinationCleaner.kt @@ -8,6 +8,10 @@ fun interface DestinationCleaner { /** * Search the test destination for old test data and delete it. This should leave recent data * (e.g. from the last week) untouched, to avoid causing failures in actively-running tests. + * + * Implementers should generally list all namespaces in the destination, filter for namespace + * which match [IntegrationTest.randomizedNamespaceRegex], and then use + * [IntegrationTest.isNamespaceOld] to filter down to namespaces which can be deleted. */ fun cleanup() } diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/DestinationDataDumper.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/DestinationDataDumper.kt index f02454d92b2d..59ec2dc9999b 100644 --- a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/DestinationDataDumper.kt +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/DestinationDataDumper.kt @@ -7,8 +7,9 @@ package io.airbyte.cdk.load.test.util import io.airbyte.cdk.command.ConfigurationSpecification import io.airbyte.cdk.load.command.DestinationStream -fun interface DestinationDataDumper { +interface DestinationDataDumper { fun dumpRecords(spec: ConfigurationSpecification, stream: DestinationStream): List + fun dumpFile(spec: ConfigurationSpecification, stream: DestinationStream): List } /** @@ -22,4 +23,11 @@ object FakeDataDumper : DestinationDataDumper { ): List { throw NotImplementedError() } + + override fun dumpFile( + spec: ConfigurationSpecification, + stream: DestinationStream + ): List { + throw NotImplementedError() + } } diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/ExpectedRecordMapper.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/ExpectedRecordMapper.kt index d500e8398b97..3320a78ad8c9 100644 --- a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/ExpectedRecordMapper.kt +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/ExpectedRecordMapper.kt @@ -4,10 +4,56 @@ package io.airbyte.cdk.load.test.util +import io.airbyte.cdk.load.data.AirbyteType +import io.airbyte.cdk.load.data.AirbyteValue +import io.airbyte.cdk.load.data.ArrayValue +import io.airbyte.cdk.load.data.DateValue +import io.airbyte.cdk.load.data.ObjectValue +import io.airbyte.cdk.load.data.StringValue +import io.airbyte.cdk.load.data.TimeWithTimezoneValue +import io.airbyte.cdk.load.data.TimeWithoutTimezoneValue +import io.airbyte.cdk.load.data.TimestampWithTimezoneValue +import io.airbyte.cdk.load.data.TimestampWithoutTimezoneValue +import java.time.format.DateTimeFormatter + fun interface ExpectedRecordMapper { - fun mapRecord(expectedRecord: OutputRecord): OutputRecord + fun mapRecord(expectedRecord: OutputRecord, schema: AirbyteType): OutputRecord } object NoopExpectedRecordMapper : ExpectedRecordMapper { - override fun mapRecord(expectedRecord: OutputRecord): OutputRecord = expectedRecord + override fun mapRecord(expectedRecord: OutputRecord, schema: AirbyteType): OutputRecord = + expectedRecord +} + +/** + * Some destinations (e.g. JSONL files) don't have temporal types, we just write everything as + * string. So we map expected records' temporal values back to string. + */ +object UncoercedExpectedRecordMapper : ExpectedRecordMapper { + override fun mapRecord(expectedRecord: OutputRecord, schema: AirbyteType): OutputRecord { + val mappedData = mapTemporalValuesToString(expectedRecord.data) + return expectedRecord.copy(data = mappedData as ObjectValue) + } + + private fun mapTemporalValuesToString(value: AirbyteValue): AirbyteValue = + when (value) { + is DateValue -> StringValue(value.value.toString()) + // Use specific formatters that match our integration test input. + is TimeWithTimezoneValue -> + StringValue(value.value.format(DateTimeFormatter.ISO_OFFSET_TIME)) + is TimeWithoutTimezoneValue -> + StringValue(value.value.format(DateTimeFormatter.ISO_LOCAL_TIME)) + is TimestampWithTimezoneValue -> + StringValue(value.value.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)) + is TimestampWithoutTimezoneValue -> + StringValue(value.value.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)) + is ArrayValue -> ArrayValue(value.values.map { mapTemporalValuesToString(it) }) + is ObjectValue -> + ObjectValue( + value.values.mapValuesTo(linkedMapOf()) { (_, v) -> + mapTemporalValuesToString(v) + } + ) + else -> value + } } diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/IntegrationTest.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/IntegrationTest.kt index 223c110e0209..e5482dee7874 100644 --- a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/IntegrationTest.kt +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/IntegrationTest.kt @@ -8,24 +8,33 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings import io.airbyte.cdk.command.ConfigurationSpecification import io.airbyte.cdk.load.command.DestinationCatalog import io.airbyte.cdk.load.command.DestinationStream -import io.airbyte.cdk.load.message.DestinationMessage -import io.airbyte.cdk.load.message.DestinationStreamComplete +import io.airbyte.cdk.load.message.DestinationRecordStreamComplete +import io.airbyte.cdk.load.message.InputMessage +import io.airbyte.cdk.load.message.InputRecord +import io.airbyte.cdk.load.message.StreamCheckpoint import io.airbyte.cdk.load.test.util.destination_process.DestinationProcessFactory +import io.airbyte.cdk.load.test.util.destination_process.DestinationUncleanExitException +import io.airbyte.cdk.load.test.util.destination_process.NonDockerizedDestination import io.airbyte.protocol.models.v0.AirbyteMessage +import io.airbyte.protocol.models.v0.AirbyteStateMessage import io.airbyte.protocol.models.v0.AirbyteStreamStatusTraceMessage.AirbyteStreamStatus import java.time.Instant +import java.time.LocalDate import java.time.LocalDateTime import java.time.ZoneOffset import java.time.format.DateTimeFormatter import java.util.concurrent.atomic.AtomicBoolean import kotlin.test.fail import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.apache.commons.lang3.RandomStringUtils import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.TestInfo +import org.junit.jupiter.api.assertThrows import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.parallel.Execution import org.junit.jupiter.api.parallel.ExecutionMode @@ -44,19 +53,10 @@ abstract class IntegrationTest( val destinationCleaner: DestinationCleaner, val recordMangler: ExpectedRecordMapper = NoopExpectedRecordMapper, val nameMapper: NameMapper = NoopNameMapper, + /** See [RecordDiffer.nullEqualsUnset]. */ + val nullEqualsUnset: Boolean = false, + val configUpdater: ConfigurationUpdater = FakeConfigurationUpdater, ) { - // Connectors are calling System.getenv rather than using micronaut-y properties, - // so we have to mock it out, instead of just setting more properties - // inside NonDockerizedDestination. - // This field has no effect on DockerizedDestination, which explicitly - // sets env vars when invoking `docker run`. - @SystemStub private lateinit var nonDockerMockEnvVars: EnvironmentVariables - - @BeforeEach - fun setEnvVars() { - nonDockerMockEnvVars.set("WORKER_JOB_ID", "0") - } - // Intentionally don't inject the actual destination process - we need a full factory // because some tests want to run multiple syncs, so we need to run the destination // multiple times. @@ -65,7 +65,7 @@ abstract class IntegrationTest( @Suppress("DEPRECATION") private val randomSuffix = RandomStringUtils.randomAlphabetic(4) private val timestampString = LocalDateTime.ofInstant(Instant.now(), ZoneOffset.UTC) - .format(DateTimeFormatter.ofPattern("YYYYMMDD")) + .format(randomizedNamespaceDateFormatter) // stream name doesn't need to be randomized, only the namespace. val randomizedNamespace = "test$timestampString$randomSuffix" @@ -99,20 +99,27 @@ abstract class IntegrationTest( stream: DestinationStream, primaryKey: List>, cursor: List?, + reason: String? = null, + allowUnexpectedRecord: Boolean = false, ) { val actualRecords: List = dataDumper.dumpRecords(config, stream) val expectedRecords: List = - canonicalExpectedRecords.map { recordMangler.mapRecord(it) } + canonicalExpectedRecords.map { recordMangler.mapRecord(it, stream.schema) } RecordDiffer( - primaryKey.map { nameMapper.mapFieldName(it) }, - cursor?.let { nameMapper.mapFieldName(it) }, + primaryKey = primaryKey.map { nameMapper.mapFieldName(it) }, + cursor = cursor?.let { nameMapper.mapFieldName(it) }, + nullEqualsUnset = nullEqualsUnset, + allowUnexpectedRecord = allowUnexpectedRecord, ) .diffRecords(expectedRecords, actualRecords) ?.let { - fail( + var message = "Incorrect records for ${stream.descriptor.namespace}.${stream.descriptor.name}:\n$it" - ) + if (reason != null) { + message = reason + "\n" + message + } + fail(message) } } @@ -120,10 +127,19 @@ abstract class IntegrationTest( fun runSync( configContents: String, stream: DestinationStream, - messages: List, + messages: List, streamStatus: AirbyteStreamStatus? = AirbyteStreamStatus.COMPLETE, + useFileTransfer: Boolean = false, + envVars: Map = emptyMap(), ): List = - runSync(configContents, DestinationCatalog(listOf(stream)), messages, streamStatus) + runSync( + configContents, + DestinationCatalog(listOf(stream)), + messages, + streamStatus, + useFileTransfer, + envVars + ) /** * Run a sync with the given config+stream+messages, sending a trace message at the end of the @@ -134,14 +150,38 @@ abstract class IntegrationTest( fun runSync( configContents: String, catalog: DestinationCatalog, - messages: List, + messages: List, + /** + * If you set this to anything other than `COMPLETE`, you may run into a race condition. + * It's recommended that you send an explicit state message in [messages], and run the sync + * in a loop until it acks the state message, e.g. + * ``` + * while (true) { + * val e = assertThrows { + * runSync( + * ..., + * listOf( + * ..., + * StreamCheckpoint(...), + * ), + * ... + * ) + * } + * if (e.stateMessages.isNotEmpty()) { break } + * } + * ``` + */ streamStatus: AirbyteStreamStatus? = AirbyteStreamStatus.COMPLETE, + useFileTransfer: Boolean = false, + envVars: Map = emptyMap(), ): List { val destination = destinationProcessFactory.createDestinationProcess( "write", configContents, catalog.asProtocolObject(), + useFileTransfer = useFileTransfer, + envVars = envVars, ) return runBlocking(Dispatchers.IO) { launch { destination.run() } @@ -149,17 +189,119 @@ abstract class IntegrationTest( if (streamStatus != null) { catalog.streams.forEach { destination.sendMessage( - DestinationStreamComplete(it.descriptor, System.currentTimeMillis()) + DestinationRecordStreamComplete(it.descriptor, System.currentTimeMillis()) .asProtocolMessage() ) } } destination.shutdown() + if (useFileTransfer) { + destination.verifyFileDeleted() + } destination.readMessages() } } + /** + * Run a sync until it acknowledges the given state message, then kill the sync. This method is + * useful for tests that want to verify recovery-from-failure cases, e.g. truncate refresh + * behaviors. + * + * A common pattern is to call [runSyncUntilStateAck], and then call `dumpAndDiffRecords(..., + * allowUnexpectedRecord = true)` to verify that [records] were written to the destination. + */ + fun runSyncUntilStateAck( + configContents: String, + stream: DestinationStream, + records: List, + inputStateMessage: StreamCheckpoint, + allowGracefulShutdown: Boolean, + useFileTransfer: Boolean = false, + envVars: Map = emptyMap(), + ): AirbyteStateMessage { + val destination = + destinationProcessFactory.createDestinationProcess( + "write", + configContents, + DestinationCatalog(listOf(stream)).asProtocolObject(), + useFileTransfer, + envVars + ) + return runBlocking(Dispatchers.IO) { + launch { + // expect an exception. we're sending a stream incomplete or killing the + // destination, so it's expected to crash + // TODO: This is a hack, not sure what's going on + if (destination is NonDockerizedDestination) { + assertThrows { destination.run() } + } else { + destination.run() + } + } + records.forEach { destination.sendMessage(it.asProtocolMessage()) } + destination.sendMessage(inputStateMessage.asProtocolMessage()) + + val deferred = async { + val outputStateMessage: AirbyteStateMessage + while (true) { + destination.sendMessage("") + val returnedMessages = destination.readMessages() + if (returnedMessages.any { it.type == AirbyteMessage.Type.STATE }) { + outputStateMessage = + returnedMessages + .filter { it.type == AirbyteMessage.Type.STATE } + .map { it.state } + .first() + break + } + } + outputStateMessage + } + val outputStateMessage = deferred.await() + if (allowGracefulShutdown) { + destination.sendMessage("{\"unparseable") + destination.shutdown() + } else { + destination.kill() + } + + outputStateMessage + } + } + + fun updateConfig(config: String): String = configUpdater.update(config) + companion object { + val randomizedNamespaceRegex = Regex("test(\\d{8})[A-Za-z]{4}") + val randomizedNamespaceDateFormatter: DateTimeFormatter = + DateTimeFormatter.ofPattern("yyyyMMdd") + + /** + * Given a randomizedNamespace (such as `test20241216abcd`), return whether the namespace + * was created more than [retentionDays] days ago, and therefore should be deleted by a + * [DestinationCleaner]. + */ + fun isNamespaceOld(namespace: String, retentionDays: Long = 30): Boolean { + val cleanupCutoffDate = LocalDate.now().minusDays(retentionDays) + val matchResult = randomizedNamespaceRegex.find(namespace) + val namespaceCreationDate = + LocalDate.parse(matchResult!!.groupValues[1], randomizedNamespaceDateFormatter) + return namespaceCreationDate.isBefore(cleanupCutoffDate) + } + private val hasRunCleaner = AtomicBoolean(false) + + // Connectors are calling System.getenv rather than using micronaut-y properties, + // so we have to mock it out, instead of just setting more properties + // inside NonDockerizedDestination. + // This field has no effect on DockerizedDestination, which explicitly + // sets env vars when invoking `docker run`. + @SystemStub lateinit var nonDockerMockEnvVars: EnvironmentVariables + + @JvmStatic + @BeforeAll + fun setEnvVars() { + nonDockerMockEnvVars.set("WORKER_JOB_ID", "0") + } } } diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/OutputRecord.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/OutputRecord.kt index af463be00f94..e2f94f5acda5 100644 --- a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/OutputRecord.kt +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/OutputRecord.kt @@ -5,7 +5,7 @@ package io.airbyte.cdk.load.test.util import io.airbyte.cdk.load.data.ObjectValue -import io.airbyte.cdk.load.message.DestinationRecord.Change +import io.airbyte.cdk.load.message.Meta.Change import java.time.Instant import java.util.UUID @@ -29,7 +29,7 @@ data class OutputRecord( * that we write to the destination. */ data class Meta( - val changes: MutableList = mutableListOf(), + val changes: List = listOf(), val syncId: Long? = null, ) diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/RecordDiffer.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/RecordDiffer.kt index b5e260c8268a..227de6114934 100644 --- a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/RecordDiffer.kt +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/RecordDiffer.kt @@ -5,17 +5,12 @@ package io.airbyte.cdk.load.test.util import io.airbyte.cdk.load.data.AirbyteValue -import io.airbyte.cdk.load.data.DateValue +import io.airbyte.cdk.load.data.ArrayValue import io.airbyte.cdk.load.data.IntegerValue import io.airbyte.cdk.load.data.NullValue import io.airbyte.cdk.load.data.ObjectValue -import io.airbyte.cdk.load.data.TimeValue -import io.airbyte.cdk.load.data.TimestampValue -import java.time.LocalDate -import java.time.LocalDateTime -import java.time.LocalTime -import java.time.OffsetDateTime -import java.time.OffsetTime +import io.airbyte.cdk.load.data.UnknownValue +import io.airbyte.cdk.load.data.json.JsonToAirbyteValue import kotlin.reflect.jvm.jvmName class RecordDiffer( @@ -30,7 +25,24 @@ class RecordDiffer( val primaryKey: List> = emptyList(), /** The path to the cursor from a record, or null if the stream has no cursor. */ val cursor: List? = null, + /** + * Many destinations (e.g. SQL destinations with a JSON column type) can distinguish between a + * value being explicitly null, vs being unset. E.g. postgres `"null" :: jsonb` vs `null :: + * jsonb`, or plain JSONL files `{"foo": null}` vs `{}`. + * + * Set this parameter to true for destinations which do not support this distinction (e.g. Avro + * files). + */ + val nullEqualsUnset: Boolean = false, + /** + * Most tests should require the destination to contain an exact list of records. However, some + * tests expect a record to be present, but may also expect other unspecified records to exist. + * Those tests should set this parameter to true. + */ + val allowUnexpectedRecord: Boolean = false, ) { + private val valueComparator = getValueComparator(nullEqualsUnset) + private fun extract(data: Map, path: List): AirbyteValue { return when (path.size) { 0 -> throw IllegalArgumentException("Empty path") @@ -70,7 +82,7 @@ class RecordDiffer( ) } - comparePks(pk1, pk2) + comparePks(pk1, pk2, nullEqualsUnset) } /** @@ -109,8 +121,8 @@ class RecordDiffer( expectedRecordIndex < expectedRecordsSorted.size && actualRecordIndex < actualRecordsSorted.size ) { - val expectedRecord = expectedRecords[expectedRecordIndex] - val actualRecord = actualRecords[actualRecordIndex] + val expectedRecord = expectedRecordsSorted[expectedRecordIndex] + val actualRecord = actualRecordsSorted[actualRecordIndex] val compare = everythingComparator.compare(expectedRecord, actualRecord) if (compare == 0) { // These records are the same underlying record @@ -122,8 +134,10 @@ class RecordDiffer( matches.add(MatchingRecords(expectedRecord, actualRecord = null)) expectedRecordIndex++ } else { - // There's an extra actual record - matches.add(MatchingRecords(expectedRecord = null, actualRecord)) + if (!allowUnexpectedRecord) { + // There's an extra actual record + matches.add(MatchingRecords(expectedRecord = null, actualRecord)) + } actualRecordIndex++ } } @@ -133,9 +147,13 @@ class RecordDiffer( matches.add(MatchingRecords(expectedRecords[expectedRecordIndex], actualRecord = null)) expectedRecordIndex++ } - while (actualRecordIndex < actualRecords.size) { - matches.add(MatchingRecords(expectedRecord = null, actualRecords[actualRecordIndex])) - actualRecordIndex++ + if (!allowUnexpectedRecord) { + while (actualRecordIndex < actualRecords.size) { + matches.add( + MatchingRecords(expectedRecord = null, actualRecords[actualRecordIndex]) + ) + actualRecordIndex++ + } } // We've paired up all the records, now find just the ones that are wrong. @@ -220,17 +238,22 @@ class RecordDiffer( val expectedPresent: Boolean = expectedRecord.data.values.containsKey(key) val actualPresent: Boolean = actualRecord.data.values.containsKey(key) if (expectedPresent && !actualPresent) { - // The expected record contained this key, but the actual record was missing - // this key. - diff.append( - "$key: Expected ${expectedRecord.data.values[key]}, but was \n" - ) + if (!nullEqualsUnset || expectedRecord.data.values[key] !is NullValue) { + // The expected record contained this key, but the actual record was missing + // this key. + diff.append( + "$key: Expected ${expectedRecord.data.values[key]}, but was \n" + ) + } } else if (!expectedPresent && actualPresent) { - // The expected record didn't contain this key, but the actual record contained - // this key. - diff.append( - "$key: Expected , but was ${actualRecord.data.values[key]}\n" - ) + if (!nullEqualsUnset || actualRecord.data.values[key] !is NullValue) { + // The expected record didn't contain this key, but the actual record + // contained + // this key. + diff.append( + "$key: Expected , but was ${actualRecord.data.values[key]}\n" + ) + } } else if (expectedPresent && actualPresent) { // The expected and actual records both contain this key. // Compare the values for equality. @@ -248,57 +271,85 @@ class RecordDiffer( } companion object { - val valueComparator: Comparator = - Comparator.nullsFirst { v1, v2 -> compare(v1!!, v2!!) } + fun getValueComparator(nullEqualsUnset: Boolean): Comparator = + Comparator.nullsFirst { v1, v2 -> compare(v1!!, v2!!, nullEqualsUnset) } /** * Compare each PK field in order, until we find a field that the two records differ in. If * all the fields are equal, then these two records have the same PK. */ - fun comparePks(pk1: List, pk2: List) = - (pk1.zip(pk2) - .map { (pk1Field, pk2Field) -> valueComparator.compare(pk1Field, pk2Field) } + fun comparePks( + pk1: List, + pk2: List, + nullEqualsUnset: Boolean, + ): Int { + return (pk1.zip(pk2) + .map { (pk1Field, pk2Field) -> + getValueComparator(nullEqualsUnset).compare(pk1Field, pk2Field) + } .firstOrNull { it != 0 } ?: 0) + } + + private fun compare(v1: AirbyteValue, v2: AirbyteValue, nullEqualsUnset: Boolean): Int { + if (v1 is UnknownValue) { + return compare( + JsonToAirbyteValue().convert(v1.value), + v2, + nullEqualsUnset, + ) + } + if (v2 is UnknownValue) { + return compare( + v1, + JsonToAirbyteValue().convert(v2.value), + nullEqualsUnset, + ) + } - private fun compare(v1: AirbyteValue, v2: AirbyteValue): Int { // when comparing values of different types, just sort by their class name. // in theory, we could check for numeric types and handle them smartly... // that's a lot of work though return if (v1::class != v2::class) { v1::class.jvmName.compareTo(v2::class.jvmName) } else { - // Handle temporal types specifically, because they require explicit parsing return when (v1) { - is DateValue -> - LocalDate.parse(v1.value) - .compareTo(LocalDate.parse((v2 as DateValue).value)) - is TimeValue -> { - try { - val time1 = LocalTime.parse(v1.value) - val time2 = LocalTime.parse((v2 as TimeValue).value) - time1.compareTo(time2) - } catch (e: Exception) { - val time1 = OffsetTime.parse(v1.value) - val time2 = OffsetTime.parse((v2 as TimeValue).value) - time1.compareTo(time2) + is ObjectValue -> { + fun objComp(a: ObjectValue, b: ObjectValue): Int { + // objects aren't really comparable, so just do an equality check + return if (a == b) 0 else 1 } - } - is TimestampValue -> { - try { - val ts1 = LocalDateTime.parse(v1.value) - val ts2 = LocalDateTime.parse((v2 as TimestampValue).value) - ts1.compareTo(ts2) - } catch (e: Exception) { - val ts1 = OffsetDateTime.parse(v1.value) - val ts2 = OffsetDateTime.parse((v2 as TimestampValue).value) - ts1.compareTo(ts2) + if (nullEqualsUnset) { + // Walk through the airbyte value, removing any NullValue entries + // from ObjectValues. + fun removeObjectNullValues(value: AirbyteValue): AirbyteValue = + when (value) { + is ObjectValue -> + ObjectValue( + value.values + .filterTo(linkedMapOf()) { (_, v) -> + v !is NullValue + } + .mapValuesTo(linkedMapOf()) { (_, v) -> + removeObjectNullValues(v) + } + ) + is ArrayValue -> + ArrayValue(value.values.map { removeObjectNullValues(it) }) + else -> value + } + val filteredV1 = removeObjectNullValues(v1) as ObjectValue + val filteredV2 = removeObjectNullValues(v2) as ObjectValue + objComp(filteredV1, filteredV2) + } else { + objComp(v1, v2 as ObjectValue) } } // otherwise, just be a terrible person. // we know these are the same type, so this is safe to do. - else -> + is Comparable<*> -> @Suppress("UNCHECKED_CAST") (v1 as Comparable).compareTo(v2) + else -> if (v1 == v2) 0 else 1 } } } diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/destination_process/DestinationProcess.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/destination_process/DestinationProcess.kt index 5b9f849960d5..c12714e9c62f 100644 --- a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/destination_process/DestinationProcess.kt +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/destination_process/DestinationProcess.kt @@ -29,6 +29,7 @@ interface DestinationProcess { */ suspend fun run() + fun sendMessage(string: String) fun sendMessage(message: AirbyteMessage) fun sendMessages(vararg messages: AirbyteMessage) { messages.forEach { sendMessage(it) } @@ -44,6 +45,8 @@ interface DestinationProcess { /** Terminate the destination as immediately as possible. */ fun kill() + + fun verifyFileDeleted() } @SuppressFBWarnings("NP_NONNULL_RETURN_VIOLATION", "good old lateinit") @@ -59,6 +62,8 @@ abstract class DestinationProcessFactory { command: String, configContents: String? = null, catalog: ConfiguredAirbyteCatalog? = null, + useFileTransfer: Boolean = false, + envVars: Map = emptyMap(), vararg featureFlags: FeatureFlag, ): DestinationProcess diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/destination_process/DestinationUncleanExitException.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/destination_process/DestinationUncleanExitException.kt index f07c7cba70b6..e388e4aa57d1 100644 --- a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/destination_process/DestinationUncleanExitException.kt +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/destination_process/DestinationUncleanExitException.kt @@ -5,15 +5,21 @@ package io.airbyte.cdk.load.test.util.destination_process import io.airbyte.protocol.models.v0.AirbyteErrorTraceMessage +import io.airbyte.protocol.models.v0.AirbyteStateMessage import io.airbyte.protocol.models.v0.AirbyteTraceMessage class DestinationUncleanExitException( exitCode: Int, - traceMessages: List + traceMessages: List, + /** + * If the destination emitted any state messages before crashing, they will be stored into this + * list. + */ + val stateMessages: List, ) : Exception( """ - Destination process exited uncleanly: $exitCode + Connector process exited uncleanly: $exitCode Trace messages: """.trimIndent() // explicit concat because otherwise trimIndent behaves badly @@ -24,10 +30,15 @@ class DestinationUncleanExitException( // this can't just be a second constructor, because both constructors // would have signature `traceMessages: List`. // so we have to pull this into a companion object function. - fun of(exitCode: Int, traceMessages: List) = + fun of( + exitCode: Int, + traceMessages: List, + stateMessages: List, + ) = DestinationUncleanExitException( exitCode, - traceMessages.filter { it.type == AirbyteTraceMessage.Type.ERROR }.map { it.error } + traceMessages.filter { it.type == AirbyteTraceMessage.Type.ERROR }.map { it.error }, + stateMessages, ) } } diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/destination_process/DockerizedDestination.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/destination_process/DockerizedDestination.kt index ac6f435269fd..a5d1e18e3fca 100644 --- a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/destination_process/DockerizedDestination.kt +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/destination_process/DockerizedDestination.kt @@ -5,19 +5,23 @@ package io.airbyte.cdk.load.test.util.destination_process import io.airbyte.cdk.command.FeatureFlag +import io.airbyte.cdk.load.util.deserializeToClass +import io.airbyte.cdk.load.util.serializeToJsonBytes +import io.airbyte.cdk.load.util.serializeToString import io.airbyte.cdk.output.BufferingOutputConsumer -import io.airbyte.cdk.util.Jsons import io.airbyte.protocol.models.v0.AirbyteLogMessage import io.airbyte.protocol.models.v0.AirbyteMessage import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog import io.github.oshai.kotlinlogging.KotlinLogging import java.io.BufferedWriter +import java.io.File import java.io.OutputStreamWriter import java.nio.file.Files import java.nio.file.Path import java.time.Clock import java.util.Locale import java.util.Scanner +import kotlin.io.path.writeText import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.coroutineScope @@ -25,6 +29,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.coroutines.yield import org.apache.commons.lang3.RandomStringUtils +import org.junit.jupiter.api.Assertions.assertFalse private val logger = KotlinLogging.logger {} @@ -35,6 +40,8 @@ class DockerizedDestination( configContents: String?, catalog: ConfiguredAirbyteCatalog?, private val testName: String, + useFileTransfer: Boolean, + envVars: Map, vararg featureFlags: FeatureFlag, ) : DestinationProcess { private val process: Process @@ -51,6 +58,7 @@ class DockerizedDestination( private val stdoutDrained = CompletableDeferred() private val stderrDrained = CompletableDeferred() + private val fileTransferMountSource = Files.createTempDirectory("tmp") init { // This is largely copied from the old cdk's DockerProcessFactory / @@ -71,6 +79,11 @@ class DockerizedDestination( // and is also mounted as a volume. val jobRoot = Files.createDirectories(workspaceRoot.resolve("job")) + // This directory is being used for the file transfer feature. + if (useFileTransfer) { + val file = Files.createFile(fileTransferMountSource.resolve("test_file")) + file.writeText("123") + } // Extract the string "destination-foo" from "gcr.io/airbyte/destination-foo:1.2.3". // The old code had a ton of extra logic here, along with a max string // length (docker container names must be <128 chars) - none of that @@ -81,7 +94,9 @@ class DockerizedDestination( val shortImageName = imageTag.substringAfterLast("/").substringBefore(":") val containerName = "$shortImageName-$command-$randomSuffix" logger.info { "Creating docker container $containerName" } - + logger.info { "File transfer ${if (useFileTransfer) "is " else "isn't"} enabled" } + val additionalEnvEntries = envVars.flatMap { (key, value) -> listOf("-e", "$key=$value") } + logger.info { "Env vars: $envVars loaded" } val cmd: MutableList = (listOf( "docker", @@ -101,10 +116,16 @@ class DockerizedDestination( String.format("%s:%s", workspaceRoot, "/data"), "-v", String.format("%s:%s", localRoot, "/local"), + "-v", + "$fileTransferMountSource:/tmp", + "-e", + "AIRBYTE_DESTINATION_RECORD_BATCH_SIZE_OVERRIDE=1", + "-e", + "USE_FILE_TRANSFER=$useFileTransfer", ) + + additionalEnvEntries + featureFlags.flatMap { listOf("-e", it.envVarBindingDeclaration) } + listOf( - // Yes, we hardcode the job ID to 0. // Also yes, this is available in the configured catalog // via the syncId property. @@ -125,7 +146,7 @@ class DockerizedDestination( cmd.add("destination_$paramName.json") } configContents?.let { addInput("config", it.toByteArray(Charsets.UTF_8)) } - catalog?.let { addInput("catalog", Jsons.writeValueAsBytes(catalog)) } + catalog?.let { addInput("catalog", catalog.serializeToJsonBytes()) } logger.info { "Executing command: ${cmd.joinToString(" ")}" } process = ProcessBuilder(cmd).start() @@ -143,7 +164,7 @@ class DockerizedDestination( val line = destinationStdout.nextLine() val message = try { - Jsons.readValue(line, AirbyteMessage::class.java) + line.deserializeToClass(AirbyteMessage::class.java) } catch (e: Exception) { // If a destination logs non-json output, just echo it getMdcScope().use { logger.info { line } } @@ -205,7 +226,12 @@ class DockerizedDestination( } override fun sendMessage(message: AirbyteMessage) { - destinationStdin.write(Jsons.writeValueAsString(message)) + destinationStdin.write(message.serializeToString()) + destinationStdin.newLine() + } + + override fun sendMessage(string: String) { + destinationStdin.write(string) destinationStdin.newLine() } @@ -225,7 +251,11 @@ class DockerizedDestination( process.waitFor() val exitCode = process.exitValue() if (exitCode != 0) { - throw DestinationUncleanExitException.of(exitCode, destinationOutput.traces()) + throw DestinationUncleanExitException.of( + exitCode, + destinationOutput.traces(), + destinationOutput.states(), + ) } } } @@ -233,6 +263,11 @@ class DockerizedDestination( override fun kill() { process.destroyForcibly() } + + override fun verifyFileDeleted() { + val file = File(fileTransferMountSource.resolve("test_file").toUri()) + assertFalse(file.exists()) + } } class DockerizedDestinationFactory( @@ -243,6 +278,8 @@ class DockerizedDestinationFactory( command: String, configContents: String?, catalog: ConfiguredAirbyteCatalog?, + useFileTransfer: Boolean, + envVars: Map, vararg featureFlags: FeatureFlag, ): DestinationProcess { return DockerizedDestination( @@ -251,6 +288,8 @@ class DockerizedDestinationFactory( configContents, catalog, testName, + useFileTransfer, + envVars, *featureFlags, ) } diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/destination_process/NonDockerizedDestination.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/destination_process/NonDockerizedDestination.kt index f1726b5702d3..7c2050855dfc 100644 --- a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/destination_process/NonDockerizedDestination.kt +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/test/util/destination_process/NonDockerizedDestination.kt @@ -8,9 +8,12 @@ import io.airbyte.cdk.ConnectorUncleanExitException import io.airbyte.cdk.command.CliRunnable import io.airbyte.cdk.command.CliRunner import io.airbyte.cdk.command.FeatureFlag -import io.airbyte.protocol.models.Jsons +import io.airbyte.cdk.load.test.util.IntegrationTest +import io.airbyte.cdk.load.util.serializeToString import io.airbyte.protocol.models.v0.AirbyteMessage import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog +import io.github.oshai.kotlinlogging.KotlinLogging +import java.io.File import java.io.PipedInputStream import java.io.PipedOutputStream import java.io.PrintWriter @@ -19,11 +22,16 @@ import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.junit.jupiter.api.Assertions.assertFalse + +private val logger = KotlinLogging.logger {} class NonDockerizedDestination( command: String, configContents: String?, catalog: ConfiguredAirbyteCatalog?, + useFileTransfer: Boolean, + envVars: Map, vararg featureFlags: FeatureFlag, ) : DestinationProcess { private val destinationStdinPipe: PrintWriter @@ -34,8 +42,19 @@ class NonDockerizedDestination( // So we start our own thread pool, which we can forcibly kill if needed. private val executor = Executors.newSingleThreadExecutor() private val coroutineDispatcher = executor.asCoroutineDispatcher() + private val file = File("/tmp/test_file") init { + envVars.forEach { (key, value) -> IntegrationTest.nonDockerMockEnvVars.set(key, value) } + logger.info { "Env vars: $envVars loaded" } + + if (useFileTransfer) { + IntegrationTest.nonDockerMockEnvVars.set("USE_FILE_TRANSFER", "true") + val fileContentStr = "123" + file.writeText(fileContentStr) + } else { + IntegrationTest.nonDockerMockEnvVars.set("USE_FILE_TRANSFER", "false") + } val destinationStdin = PipedInputStream() // This could probably be a channel, somehow. But given the current structure, // it's easier to just use the pipe stuff. @@ -63,7 +82,8 @@ class NonDockerizedDestination( } catch (e: ConnectorUncleanExitException) { throw DestinationUncleanExitException.of( e.exitCode, - destination.results.traces() + destination.results.traces(), + destination.results.states(), ) } destinationComplete.complete(Unit) @@ -73,7 +93,11 @@ class NonDockerizedDestination( } override fun sendMessage(message: AirbyteMessage) { - destinationStdinPipe.println(Jsons.serialize(message)) + destinationStdinPipe.println(message.serializeToString()) + } + + override fun sendMessage(string: String) { + destinationStdinPipe.println(string) } override fun readMessages(): List = destination.results.newMessages() @@ -89,6 +113,10 @@ class NonDockerizedDestination( // Coroutines interpret this as a cancellation. executor.shutdownNow() } + + override fun verifyFileDeleted() { + assertFalse(file.exists()) + } } class NonDockerizedDestinationFactory : DestinationProcessFactory() { @@ -96,9 +124,18 @@ class NonDockerizedDestinationFactory : DestinationProcessFactory() { command: String, configContents: String?, catalog: ConfiguredAirbyteCatalog?, + useFileTransfer: Boolean, + envVars: Map, vararg featureFlags: FeatureFlag, ): DestinationProcess { // TODO pass test name into the destination process - return NonDockerizedDestination(command, configContents, catalog, *featureFlags) + return NonDockerizedDestination( + command, + configContents, + catalog, + useFileTransfer, + envVars, + *featureFlags + ) } } diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/write/BasicFunctionalityIntegrationTest.kt b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/write/BasicFunctionalityIntegrationTest.kt index abcde861434b..1625286f47be 100644 --- a/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/write/BasicFunctionalityIntegrationTest.kt +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/kotlin/io/airbyte/cdk/load/write/BasicFunctionalityIntegrationTest.kt @@ -4,6 +4,7 @@ package io.airbyte.cdk.load.write +import com.fasterxml.jackson.databind.node.JsonNodeFactory import io.airbyte.cdk.command.ConfigurationSpecification import io.airbyte.cdk.command.ValidatedJsonUtils import io.airbyte.cdk.load.command.Append @@ -11,34 +12,56 @@ import io.airbyte.cdk.load.command.Dedupe import io.airbyte.cdk.load.command.DestinationCatalog import io.airbyte.cdk.load.command.DestinationStream import io.airbyte.cdk.load.data.AirbyteValue +import io.airbyte.cdk.load.data.ArrayType +import io.airbyte.cdk.load.data.ArrayTypeWithoutSchema +import io.airbyte.cdk.load.data.BooleanType +import io.airbyte.cdk.load.data.DateType import io.airbyte.cdk.load.data.FieldType import io.airbyte.cdk.load.data.IntegerType import io.airbyte.cdk.load.data.IntegerValue +import io.airbyte.cdk.load.data.NumberType import io.airbyte.cdk.load.data.ObjectType +import io.airbyte.cdk.load.data.ObjectTypeWithEmptySchema +import io.airbyte.cdk.load.data.ObjectTypeWithoutSchema import io.airbyte.cdk.load.data.ObjectValue import io.airbyte.cdk.load.data.StringType import io.airbyte.cdk.load.data.StringValue +import io.airbyte.cdk.load.data.TimeTypeWithTimezone +import io.airbyte.cdk.load.data.TimeTypeWithoutTimezone import io.airbyte.cdk.load.data.TimestampTypeWithTimezone -import io.airbyte.cdk.load.message.DestinationRecord +import io.airbyte.cdk.load.data.TimestampTypeWithoutTimezone +import io.airbyte.cdk.load.data.TimestampWithTimezoneValue +import io.airbyte.cdk.load.data.UnionType +import io.airbyte.cdk.load.data.UnknownType +import io.airbyte.cdk.load.message.DestinationFile +import io.airbyte.cdk.load.message.InputFile +import io.airbyte.cdk.load.message.InputRecord +import io.airbyte.cdk.load.message.InputStreamCheckpoint +import io.airbyte.cdk.load.message.Meta.Change import io.airbyte.cdk.load.message.StreamCheckpoint +import io.airbyte.cdk.load.test.util.ConfigurationUpdater import io.airbyte.cdk.load.test.util.DestinationCleaner import io.airbyte.cdk.load.test.util.DestinationDataDumper import io.airbyte.cdk.load.test.util.ExpectedRecordMapper +import io.airbyte.cdk.load.test.util.FakeConfigurationUpdater import io.airbyte.cdk.load.test.util.IntegrationTest import io.airbyte.cdk.load.test.util.NameMapper import io.airbyte.cdk.load.test.util.NoopExpectedRecordMapper import io.airbyte.cdk.load.test.util.NoopNameMapper import io.airbyte.cdk.load.test.util.OutputRecord -import io.airbyte.cdk.load.test.util.destination_process.DestinationUncleanExitException -import io.airbyte.cdk.util.Jsons +import io.airbyte.cdk.load.util.deserializeToNode import io.airbyte.protocol.models.v0.AirbyteMessage import io.airbyte.protocol.models.v0.AirbyteRecordMessageMetaChange -import io.airbyte.protocol.models.v0.AirbyteStateMessage +import java.math.BigDecimal +import java.math.BigInteger +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.LocalTime import java.time.OffsetDateTime +import java.time.OffsetTime import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import org.junit.jupiter.api.Assertions.assertDoesNotThrow import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Assumptions.assumeTrue @@ -46,6 +69,25 @@ import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertAll +sealed interface AllTypesBehavior + +data class StronglyTyped( + /** + * Whether the destination can cast any value to string. E.g. given a StringType column, if a + * record contains `{"the_column": {"foo": "bar"}}`, does the connector treat this as a type + * error, or does it persist a serialized JSON string? + */ + val convertAllValuesToString: Boolean = true, + /** Whether top-level fields are represented as float64, or as fixed-point values */ + val topLevelFloatLosesPrecision: Boolean = true, + /** Whether floats nested inside objects/arrays are represented as float64. */ + val nestedFloatLosesPrecision: Boolean = true, + /** Whether the destination supports integers larger than int64 */ + val integerCanBeLarge: Boolean = true, +) : AllTypesBehavior + +data object Untyped : AllTypesBehavior + abstract class BasicFunctionalityIntegrationTest( /** The config to pass into the connector, as a serialized JSON blob */ val configContents: String, @@ -69,8 +111,36 @@ abstract class BasicFunctionalityIntegrationTest( */ val isStreamSchemaRetroactive: Boolean, val supportsDedup: Boolean, -) : IntegrationTest(dataDumper, destinationCleaner, recordMangler, nameMapper) { - val parsedConfig = ValidatedJsonUtils.parseOne(configSpecClass, configContents) + val stringifySchemalessObjects: Boolean, + val promoteUnionToObject: Boolean, + val preserveUndeclaredFields: Boolean, + val supportFileTransfer: Boolean, + val envVars: Map, + /** + * Whether the destination commits new data when it receives a non-`COMPLETE` stream status. For + * example: + * * A destination which writes new data to a temporary directory, and moves those files to the + * "real" directory at the end of the sync if and only if it received a COMPLETE status, would + * set this parameter to `false`. + * * A destination which writes new data directly into the real directory throughout the sync, + * would set this parameter to `true`. + */ + val commitDataIncrementally: Boolean, + val allTypesBehavior: AllTypesBehavior, + val nullUnknownTypes: Boolean = false, + nullEqualsUnset: Boolean = false, + configUpdater: ConfigurationUpdater = FakeConfigurationUpdater, +) : + IntegrationTest( + dataDumper = dataDumper, + destinationCleaner = destinationCleaner, + recordMangler = recordMangler, + nameMapper = nameMapper, + nullEqualsUnset = nullEqualsUnset, + configUpdater = configUpdater + ) { + val parsedConfig = + ValidatedJsonUtils.parseOne(configSpecClass, configUpdater.update(configContents)) @Test open fun testBasicWrite() { @@ -88,16 +158,14 @@ abstract class BasicFunctionalityIntegrationTest( configContents, stream, listOf( - DestinationRecord( + InputRecord( namespace = randomizedNamespace, name = "test_stream", - // The `undeclared` field should be dropped by the destination, because it - // is not present in the stream schema. data = """{"id": 5678, "undeclared": "asdf"}""", emittedAtMs = 1234, changes = mutableListOf( - DestinationRecord.Change( + Change( field = "foo", change = AirbyteRecordMessageMetaChange.Change.NULLED, reason = @@ -106,13 +174,14 @@ abstract class BasicFunctionalityIntegrationTest( ) ) ), - StreamCheckpoint( + InputStreamCheckpoint( streamName = "test_stream", streamNamespace = randomizedNamespace, blob = """{"foo": "bar"}""", sourceRecordCount = 1, ) - ) + ), + envVars = envVars, ) val stateMessages = messages.filter { it.type == AirbyteMessage.Type.STATE } @@ -143,12 +212,17 @@ abstract class BasicFunctionalityIntegrationTest( OutputRecord( extractedAt = 1234, generationId = 0, - data = mapOf("id" to 5678), + data = + if (preserveUndeclaredFields) { + mapOf("id" to 5678, "undeclared" to "asdf") + } else { + mapOf("id" to 5678) + }, airbyteMeta = OutputRecord.Meta( changes = mutableListOf( - DestinationRecord.Change( + Change( field = "foo", change = AirbyteRecordMessageMetaChange.Change @@ -171,176 +245,151 @@ abstract class BasicFunctionalityIntegrationTest( ) } + @Test + open fun testBasicWriteFile() { + assumeTrue(supportFileTransfer) + val stream = + DestinationStream( + DestinationStream.Descriptor(randomizedNamespace, "test_stream_file"), + Append, + ObjectType(linkedMapOf("id" to intType)), + generationId = 0, + minimumGenerationId = 0, + syncId = 42, + ) + val fileMessage = + DestinationFile.AirbyteRecordMessageFile( + fileUrl = "/tmp/test_file", + bytes = 1234L, + fileRelativePath = "path/to/file", + modified = 4321L, + sourceFileUrl = "file://path/to/source", + ) + + val messages = + runSync( + configContents, + stream, + listOf( + InputFile( + stream = stream.descriptor, + emittedAtMs = 1234, + fileMessage = fileMessage, + ), + InputStreamCheckpoint( + streamName = stream.descriptor.name, + streamNamespace = stream.descriptor.namespace, + blob = """{"foo": "bar"}""", + sourceRecordCount = 1, + ) + ), + useFileTransfer = true, + ) + + val stateMessages = messages.filter { it.type == AirbyteMessage.Type.STATE } + assertAll({ + assertEquals( + 1, + stateMessages.size, + "Expected to receive exactly one state message, got ${stateMessages.size} ($stateMessages)" + ) + assertEquals( + StreamCheckpoint( + streamName = stream.descriptor.name, + streamNamespace = stream.descriptor.namespace, + blob = """{"foo": "bar"}""", + sourceRecordCount = 1, + destinationRecordCount = 1, + ) + .asProtocolMessage(), + stateMessages.first() + ) + }) + + val config = ValidatedJsonUtils.parseOne(configSpecClass, configContents) + val fileContent = dataDumper.dumpFile(config, stream) + + assertEquals(listOf("123"), fileContent) + } + @Disabled("https://github.com/airbytehq/airbyte-internal-issues/issues/10413") @Test open fun testMidSyncCheckpointingStreamState(): Unit = runBlocking(Dispatchers.IO) { - fun makeStream(name: String) = + val stream = DestinationStream( - DestinationStream.Descriptor(randomizedNamespace, name), + DestinationStream.Descriptor(randomizedNamespace, "test_stream"), Append, ObjectType(linkedMapOf("id" to intType)), generationId = 0, minimumGenerationId = 0, syncId = 42, ) - val destination = - destinationProcessFactory.createDestinationProcess( - "write", + val stateMessage = + runSyncUntilStateAck( configContents, - DestinationCatalog( - listOf( - makeStream("test_stream1"), - makeStream("test_stream2"), - ) + stream, + listOf( + InputRecord( + namespace = randomizedNamespace, + name = "test_stream", + data = """{"id": 12}""", + emittedAtMs = 1234, ) - .asProtocolObject(), - ) - launch { - try { - destination.run() - } catch (e: DestinationUncleanExitException) { - // swallow exception - we'll kill the destination, - // so it's expected to exit uncleanly - } - } - - // Send one record+state to each stream - destination.sendMessages( - DestinationRecord( - namespace = randomizedNamespace, - name = "test_stream1", - data = """{"id": 12}""", - emittedAtMs = 1234, - ) - .asProtocolMessage(), - StreamCheckpoint( + ), + StreamCheckpoint( streamNamespace = randomizedNamespace, - streamName = "test_stream1", + streamName = "test_stream", blob = """{"foo": "bar1"}""", sourceRecordCount = 1 + ), + allowGracefulShutdown = false, + ) + runSync(configContents, stream, emptyList()) + + val streamName = stateMessage.stream.streamDescriptor.name + val streamNamespace = stateMessage.stream.streamDescriptor.namespace + // basic state message checks - this is mostly just exercising the CDK itself, + // but is cheap and easy to do. + assertAll( + { assertEquals(randomizedNamespace, streamNamespace) }, + { + assertEquals( + streamName, + "test_stream", + "Expected stream name to be test_stream, got $streamName" ) - .asProtocolMessage(), - DestinationRecord( - namespace = randomizedNamespace, - name = "test_stream2", - data = """{"id": 34}""", - emittedAtMs = 1234, - ) - .asProtocolMessage(), - StreamCheckpoint( - streamNamespace = randomizedNamespace, - streamName = "test_stream2", - blob = """{"foo": "bar2"}""", - sourceRecordCount = 1 + }, + { + assertEquals( + 1.0, + stateMessage.destinationStats.recordCount, + "Expected destination stats to show 1 record" ) - .asProtocolMessage() - ) - // Send records to stream1 until we get a state message back. - // Generally, we expect that that state message will belong to stream1. - val stateMessages: List - var i = 0 - while (true) { - // limit ourselves to 2M messages, which should be enough to force a flush - if (i < 2_000_000) { - destination.sendMessage( - DestinationRecord( - namespace = randomizedNamespace, - name = "test_stream1", - data = """{"id": 56}""", - emittedAtMs = 1234, - ) - .asProtocolMessage() + }, + { + assertEquals( + """{"foo": "bar1"}""".deserializeToNode(), + stateMessage.stream.streamState ) - i++ - } else { - delay(1000) - } - val returnedMessages = destination.readMessages() - if (returnedMessages.any { it.type == AirbyteMessage.Type.STATE }) { - stateMessages = - returnedMessages - .filter { it.type == AirbyteMessage.Type.STATE } - .map { it.state } - break } - } - - try { - // for each state message, verify that it's a valid state, - // and that we actually wrote the data - stateMessages.forEach { stateMessage -> - val streamName = stateMessage.stream.streamDescriptor.name - val streamNamespace = stateMessage.stream.streamDescriptor.namespace - // basic state message checks - this is mostly just exercising the CDK itself, - // but is cheap and easy to do. - assertAll( - { assertEquals(randomizedNamespace, streamNamespace) }, - { - assertTrue( - streamName == "test_stream1" || streamName == "test_stream2", - "Expected stream name to be test_stream1 or test_stream2, got $streamName" - ) - }, - { - assertEquals( - 1.0, - stateMessage.destinationStats.recordCount, - "Expected destination stats to show 1 record" - ) - }, - { - when (streamName) { - "test_stream1" -> { - assertEquals( - Jsons.readTree("""{"foo": "bar1"}"""), - stateMessage.stream.streamState, - ) - } - "test_stream2" -> { - assertEquals( - Jsons.readTree("""{"foo": "bar2"}"""), - stateMessage.stream.streamState - ) - } - else -> - throw IllegalStateException( - "Unexpected stream name: $streamName" - ) - } - } - ) - if (verifyDataWriting) { - val records = dataDumper.dumpRecords(parsedConfig, makeStream(streamName)) - val expectedId = - when (streamName) { - "test_stream1" -> 12 - "test_stream2" -> 34 - else -> - throw IllegalStateException( - "Unexpected stream name: $streamName" - ) - } - val expectedRecord = - recordMangler.mapRecord( - OutputRecord( - extractedAt = 1234, - generationId = 0, - data = mapOf("id" to expectedId), - airbyteMeta = OutputRecord.Meta(syncId = 42) - ) - ) - - assertTrue( - records.any { actualRecord -> - expectedRecord.data == actualRecord.data - }, - "Expected the first record to be present in the dumped records.", + ) + if (verifyDataWriting) { + dumpAndDiffRecords( + parsedConfig, + listOf( + OutputRecord( + extractedAt = 1234, + generationId = 0, + data = mapOf("id" to 12), + airbyteMeta = OutputRecord.Meta(syncId = 42) ) - } - } - } finally { - destination.kill() + ), + stream, + primaryKey = listOf(listOf("id")), + cursor = null, + allowUnexpectedRecord = true, + ) } } @@ -367,13 +416,13 @@ abstract class BasicFunctionalityIntegrationTest( ) ), listOf( - DestinationRecord( + InputRecord( namespace = stream1.descriptor.namespace, name = stream1.descriptor.name, data = """{"id": 1234}""", emittedAtMs = 1234, ), - DestinationRecord( + InputRecord( namespace = stream2.descriptor.namespace, name = stream2.descriptor.name, data = """{"id": 5678}""", @@ -467,7 +516,7 @@ abstract class BasicFunctionalityIntegrationTest( // The id field is always 42, and the string fields are always "foo\nbar". val messages = catalog.streams.map { stream -> - DestinationRecord( + InputRecord( stream.descriptor, ObjectValue( (stream.schema as ObjectType) @@ -525,7 +574,7 @@ abstract class BasicFunctionalityIntegrationTest( configContents, makeStream(generationId = 12, minimumGenerationId = 0, syncId = 42), listOf( - DestinationRecord( + InputRecord( randomizedNamespace, "test_stream", """{"id": 42, "name": "first_value"}""", @@ -538,7 +587,7 @@ abstract class BasicFunctionalityIntegrationTest( configContents, finalStream, listOf( - DestinationRecord( + InputRecord( randomizedNamespace, "test_stream", """{"id": 42, "name": "second_value"}""", @@ -562,129 +611,616 @@ abstract class BasicFunctionalityIntegrationTest( ) } + /** + * Test behavior in a failed truncate refresh. Sync 1 just populates two records with ID 1 and + * 2. The test then runs two more syncs: + * 1. Sync 2 emits ID 1, and then fails the sync (i.e. no COMPLETE stream status). We expect the + * first sync's records to still exist in the destination. The new record may be visible to the + * data dumper, depending on the [commitDataIncrementally] parameter. + * 2. Sync 3 emits ID 2, and then ends the sync normally (i.e. COMPLETE stream status). After + * this sync, the data from the first sync should be deleted, and the data from both the second + * and third syncs should be visible to the data dumper. + */ @Test - open fun testAppend() { + open fun testInterruptedTruncateWithPriorData() { assumeTrue(verifyDataWriting) - fun makeStream(syncId: Long) = + fun makeInputRecord(id: Int, updatedAt: String, extractedAt: Long) = + InputRecord( + randomizedNamespace, + "test_stream", + """{"id": $id, "updated_at": "$updatedAt", "name": "foo_${id}_$extractedAt"}""", + emittedAtMs = extractedAt, + ) + fun makeOutputRecord( + id: Int, + updatedAt: String, + extractedAt: Long, + generationId: Long, + syncId: Long, + ) = + OutputRecord( + extractedAt = extractedAt, + generationId = generationId, + data = + mapOf( + "id" to id, + "updated_at" to TimestampWithTimezoneValue(updatedAt), + "name" to "foo_${id}_$extractedAt", + ), + airbyteMeta = OutputRecord.Meta(syncId = syncId), + ) + // Run a normal sync with nonempty data + val stream1 = DestinationStream( DestinationStream.Descriptor(randomizedNamespace, "test_stream"), Append, - ObjectType(linkedMapOf("id" to intType, "name" to stringType)), - generationId = 0, + ObjectType( + linkedMapOf( + "id" to intType, + "updated_at" to timestamptzType, + "name" to stringType, + ) + ), + generationId = 41, minimumGenerationId = 0, - syncId, + syncId = 41, ) runSync( configContents, - makeStream(syncId = 42), + stream1, listOf( - DestinationRecord( - randomizedNamespace, - "test_stream", - """{"id": 42, "name": "first_value"}""", - emittedAtMs = 1234L, - ) + makeInputRecord(1, "2024-01-23T01:00:00Z", 100), + makeInputRecord(2, "2024-01-23T01:00:00Z", 100), + ), + ) + dumpAndDiffRecords( + parsedConfig, + listOf( + makeOutputRecord( + id = 1, + updatedAt = "2024-01-23T01:00:00Z", + extractedAt = 100, + generationId = 41, + syncId = 41, + ), + makeOutputRecord( + id = 2, + updatedAt = "2024-01-23T01:00:00Z", + extractedAt = 100, + generationId = 41, + syncId = 41, + ), + ), + stream1, + primaryKey = listOf(listOf("id")), + cursor = null, + "Records were incorrect after initial sync - this indicates a bug in basic connector behavior", + ) + + val stream2 = + stream1.copy( + generationId = 42, + minimumGenerationId = 42, + syncId = 42, ) + // Run a sync, but emit a status incomplete. This should not delete any existing data. + runSyncUntilStateAck( + configContents, + stream2, + listOf(makeInputRecord(1, "2024-01-23T02:00:00Z", 200)), + StreamCheckpoint( + randomizedNamespace, + stream2.descriptor.name, + """{}""", + sourceRecordCount = 1, + ), + allowGracefulShutdown = false, ) - val finalStream = makeStream(syncId = 43) + dumpAndDiffRecords( + parsedConfig, + listOfNotNull( + makeOutputRecord( + id = 1, + updatedAt = "2024-01-23T01:00:00Z", + extractedAt = 100, + generationId = 41, + syncId = 41, + ), + makeOutputRecord( + id = 2, + updatedAt = "2024-01-23T01:00:00Z", + extractedAt = 100, + generationId = 41, + syncId = 41, + ), + if (commitDataIncrementally) { + makeOutputRecord( + id = 1, + updatedAt = "2024-01-23T02:00:00Z", + extractedAt = 200, + generationId = 42, + syncId = 42, + ) + } else { + null + } + ), + stream2, + primaryKey = listOf(listOf("id")), + cursor = null, + "Records were incorrect after a failed sync.", + ) + + // Run a third sync, this time with a successful status. + // This should delete the first sync's data, and retain the second+third syncs' data. runSync( configContents, - finalStream, - listOf( - DestinationRecord( - randomizedNamespace, - "test_stream", - """{"id": 42, "name": "second_value"}""", - emittedAtMs = 1234, - ) - ) + stream2, + listOf(makeInputRecord(2, "2024-01-23T03:00:00Z", 300)), ) dumpAndDiffRecords( parsedConfig, listOf( - OutputRecord( - extractedAt = 1234, - generationId = 0, - data = mapOf("id" to 42, "name" to "first_value"), - airbyteMeta = OutputRecord.Meta(syncId = 42), + makeOutputRecord( + id = 1, + updatedAt = "2024-01-23T02:00:00Z", + extractedAt = 200, + generationId = 42, + syncId = 42, + ), + makeOutputRecord( + id = 2, + updatedAt = "2024-01-23T03:00:00Z", + extractedAt = 300, + generationId = 42, + syncId = 42, ), - OutputRecord( - extractedAt = 1234, - generationId = 0, - data = mapOf("id" to 42, "name" to "second_value"), - airbyteMeta = OutputRecord.Meta(syncId = 43), - ) ), - finalStream, + stream2, primaryKey = listOf(listOf("id")), cursor = null, + "Records were incorrect after a successful sync following a failed sync. This may indicate that we are not retaining data from the failed sync.", + allowUnexpectedRecord = true, ) } /** - * Intended to test for basic schema evolution. Runs two append syncs, where the second sync has - * a few changes - * * drop the `to_drop` column - * * add a `to_add` column - * * change the `to_change` column from int to string + * Largely identical to [testInterruptedTruncateWithPriorData], but doesn't run the initial + * sync. This is mostly relevant to warehouse destinations, where running a truncate sync into + * an empty destination behaves differently from running a truncate sync when the destination + * already contains data. */ @Test - open fun testAppendSchemaEvolution() { + open fun testInterruptedTruncateWithoutPriorData() { assumeTrue(verifyDataWriting) - fun makeStream(syncId: Long, schema: LinkedHashMap) = + fun makeInputRecord(id: Int, updatedAt: String, extractedAt: Long) = + InputRecord( + randomizedNamespace, + "test_stream", + """{"id": $id, "updated_at": "$updatedAt", "name": "foo_${id}_$extractedAt"}""", + emittedAtMs = extractedAt, + ) + fun makeOutputRecord( + id: Int, + updatedAt: String, + extractedAt: Long, + generationId: Long, + syncId: Long, + ) = + OutputRecord( + extractedAt = extractedAt, + generationId = generationId, + data = + mapOf( + "id" to id, + "updated_at" to TimestampWithTimezoneValue(updatedAt), + "name" to "foo_${id}_$extractedAt", + ), + airbyteMeta = OutputRecord.Meta(syncId = syncId), + ) + val stream = DestinationStream( DestinationStream.Descriptor(randomizedNamespace, "test_stream"), Append, - ObjectType(schema), - generationId = 0, - minimumGenerationId = 0, - syncId, + ObjectType( + linkedMapOf( + "id" to intType, + "updated_at" to timestamptzType, + "name" to stringType, + ) + ), + generationId = 42, + minimumGenerationId = 42, + syncId = 42, ) - runSync( + // Run a sync, but emit a stream status incomplete. + runSyncUntilStateAck( configContents, - makeStream( - syncId = 42, - linkedMapOf("id" to intType, "to_drop" to stringType, "to_change" to intType) + stream, + listOf(makeInputRecord(1, "2024-01-23T02:00:00Z", 200)), + StreamCheckpoint( + randomizedNamespace, + stream.descriptor.name, + """{}""", + sourceRecordCount = 1, ), - listOf( - DestinationRecord( - randomizedNamespace, - "test_stream", - """{"id": 42, "to_drop": "val1", "to_change": 42}""", - emittedAtMs = 1234L, + allowGracefulShutdown = false, + ) + dumpAndDiffRecords( + parsedConfig, + if (commitDataIncrementally) { + listOf( + makeOutputRecord( + id = 1, + updatedAt = "2024-01-23T02:00:00Z", + extractedAt = 200, + generationId = 42, + syncId = 42, + ) ) - ) + } else { + listOf() + }, + stream, + primaryKey = listOf(listOf("id")), + cursor = null, + "Records were incorrect after a failed sync.", ) - val finalStream = - makeStream( - syncId = 43, - linkedMapOf("id" to intType, "to_change" to stringType, "to_add" to stringType) - ) + + // Run a second sync, this time with a successful status. + // This should retain the first syncs' data. runSync( configContents, - finalStream, - listOf( - DestinationRecord( - randomizedNamespace, - "test_stream", - """{"id": 42, "to_change": "val2", "to_add": "val3"}""", - emittedAtMs = 1234, - ) - ) + stream, + listOf(makeInputRecord(2, "2024-01-23T03:00:00Z", 300)), ) dumpAndDiffRecords( parsedConfig, listOf( - OutputRecord( - extractedAt = 1234, - generationId = 0, - data = - if (isStreamSchemaRetroactive) - // the first sync's record has to_change modified to a string, - // and to_drop is gone completely - mapOf("id" to 42, "to_change" to "42") - else mapOf("id" to 42, "to_drop" to "val1", "to_change" to 42), - airbyteMeta = OutputRecord.Meta(syncId = 42), + makeOutputRecord( + id = 1, + updatedAt = "2024-01-23T02:00:00Z", + extractedAt = 200, + generationId = 42, + syncId = 42, + ), + makeOutputRecord( + id = 2, + updatedAt = "2024-01-23T03:00:00Z", + extractedAt = 300, + generationId = 42, + syncId = 42, + ), + ), + stream, + primaryKey = listOf(listOf("id")), + cursor = null, + "Records were incorrect after a successful sync following a failed sync. This may indicate that we are not retaining data from the failed sync.", + allowUnexpectedRecord = true, + ) + } + + /** + * Emulates this sequence of events: + * 1. User runs a normal incremental sync + * 2. User initiates a truncate refresh, but it fails. + * 3. User cancels the truncate refresh, and initiates a normal incremental sync. + * + * In particular, we must retain all records from both the first and second syncs. + * + * This is, again, similar to [testInterruptedTruncateWithPriorData], except that the third sync + * has generation 43 + minGeneration 0 (instead of generation=minGeneration=42)(. + */ + @Test + open fun resumeAfterCancelledTruncate() { + assumeTrue(verifyDataWriting) + fun makeInputRecord(id: Int, updatedAt: String, extractedAt: Long) = + InputRecord( + randomizedNamespace, + "test_stream", + """{"id": $id, "updated_at": "$updatedAt", "name": "foo_${id}_$extractedAt"}""", + emittedAtMs = extractedAt, + ) + fun makeOutputRecord( + id: Int, + updatedAt: String, + extractedAt: Long, + generationId: Long, + syncId: Long, + ) = + OutputRecord( + extractedAt = extractedAt, + generationId = generationId, + data = + mapOf( + "id" to id, + "updated_at" to TimestampWithTimezoneValue(updatedAt), + "name" to "foo_${id}_$extractedAt", + ), + airbyteMeta = OutputRecord.Meta(syncId = syncId), + ) + // Run a normal sync with nonempty data + val stream1 = + DestinationStream( + DestinationStream.Descriptor(randomizedNamespace, "test_stream"), + Append, + ObjectType( + linkedMapOf( + "id" to intType, + "updated_at" to timestamptzType, + "name" to stringType, + ) + ), + generationId = 41, + minimumGenerationId = 0, + syncId = 41, + ) + runSync( + configContents, + stream1, + listOf( + makeInputRecord(1, "2024-01-23T01:00:00Z", 100), + makeInputRecord(2, "2024-01-23T01:00:00Z", 100), + ), + ) + dumpAndDiffRecords( + parsedConfig, + listOf( + makeOutputRecord( + id = 1, + updatedAt = "2024-01-23T01:00:00Z", + extractedAt = 100, + generationId = 41, + syncId = 41, + ), + makeOutputRecord( + id = 2, + updatedAt = "2024-01-23T01:00:00Z", + extractedAt = 100, + generationId = 41, + syncId = 41, + ), + ), + stream1, + primaryKey = listOf(listOf("id")), + cursor = null, + "Records were incorrect after initial sync - this indicates a bug in basic connector behavior", + ) + + val stream2 = + stream1.copy( + generationId = 42, + minimumGenerationId = 42, + syncId = 42, + ) + // Run a sync, but emit a stream status incomplete. This should not delete any existing + // data. + runSyncUntilStateAck( + configContents, + stream2, + listOf(makeInputRecord(1, "2024-01-23T02:00:00Z", 200)), + StreamCheckpoint( + randomizedNamespace, + stream2.descriptor.name, + """{}""", + sourceRecordCount = 1, + ), + allowGracefulShutdown = false, + ) + dumpAndDiffRecords( + parsedConfig, + listOfNotNull( + makeOutputRecord( + id = 1, + updatedAt = "2024-01-23T01:00:00Z", + extractedAt = 100, + generationId = 41, + syncId = 41, + ), + makeOutputRecord( + id = 2, + updatedAt = "2024-01-23T01:00:00Z", + extractedAt = 100, + generationId = 41, + syncId = 41, + ), + if (commitDataIncrementally) { + makeOutputRecord( + id = 1, + updatedAt = "2024-01-23T02:00:00Z", + extractedAt = 200, + generationId = 42, + syncId = 42, + ) + } else { + null + } + ), + stream2, + primaryKey = listOf(listOf("id")), + cursor = null, + "Records were incorrect after a failed sync.", + ) + + // Run a third sync, this time with a successful status. + // This should delete the first sync's data, and retain the second+third syncs' data. + val stream3 = + stream2.copy( + generationId = 43, + minimumGenerationId = 0, + syncId = 43, + ) + runSync( + configContents, + stream3, + listOf(makeInputRecord(2, "2024-01-23T03:00:00Z", 300)), + ) + dumpAndDiffRecords( + parsedConfig, + listOf( + // records from sync 1 + makeOutputRecord( + id = 1, + updatedAt = "2024-01-23T01:00:00Z", + extractedAt = 100, + generationId = 41, + syncId = 41, + ), + makeOutputRecord( + id = 2, + updatedAt = "2024-01-23T01:00:00Z", + extractedAt = 100, + generationId = 41, + syncId = 41, + ), + // sync 2 + makeOutputRecord( + id = 1, + updatedAt = "2024-01-23T02:00:00Z", + extractedAt = 200, + generationId = 42, + syncId = 42, + ), + // and sync 3 + makeOutputRecord( + id = 2, + updatedAt = "2024-01-23T03:00:00Z", + extractedAt = 300, + generationId = 43, + syncId = 43, + ), + ), + stream2, + primaryKey = listOf(listOf("id")), + cursor = null, + "Records were incorrect after a successful sync following a failed sync. This may indicate that we are not retaining data from the failed sync.", + allowUnexpectedRecord = true, + ) + } + + @Test + open fun testAppend() { + assumeTrue(verifyDataWriting) + fun makeStream(syncId: Long) = + DestinationStream( + DestinationStream.Descriptor(randomizedNamespace, "test_stream"), + Append, + ObjectType(linkedMapOf("id" to intType, "name" to stringType)), + generationId = 0, + minimumGenerationId = 0, + syncId, + ) + runSync( + configContents, + makeStream(syncId = 42), + listOf( + InputRecord( + randomizedNamespace, + "test_stream", + """{"id": 42, "name": "first_value"}""", + emittedAtMs = 1234L, + ) + ) + ) + val finalStream = makeStream(syncId = 43) + runSync( + configContents, + finalStream, + listOf( + InputRecord( + randomizedNamespace, + "test_stream", + """{"id": 42, "name": "second_value"}""", + emittedAtMs = 5678L, + ) + ) + ) + dumpAndDiffRecords( + parsedConfig, + listOf( + OutputRecord( + extractedAt = 1234, + generationId = 0, + data = mapOf("id" to 42, "name" to "first_value"), + airbyteMeta = OutputRecord.Meta(syncId = 42), + ), + OutputRecord( + extractedAt = 5678, + generationId = 0, + data = mapOf("id" to 42, "name" to "second_value"), + airbyteMeta = OutputRecord.Meta(syncId = 43), + ) + ), + finalStream, + primaryKey = listOf(listOf("id")), + cursor = null, + ) + } + + /** + * Intended to test for basic schema evolution. Runs two append syncs, where the second sync has + * a few changes + * * drop the `to_drop` column + * * add a `to_add` column + * * change the `to_change` column from int to string + */ + @Test + open fun testAppendSchemaEvolution() { + assumeTrue(verifyDataWriting) + fun makeStream(syncId: Long, schema: LinkedHashMap) = + DestinationStream( + DestinationStream.Descriptor(randomizedNamespace, "test_stream"), + Append, + ObjectType(schema), + generationId = 0, + minimumGenerationId = 0, + syncId, + ) + runSync( + configContents, + makeStream( + syncId = 42, + linkedMapOf("id" to intType, "to_drop" to stringType, "to_change" to intType) + ), + listOf( + InputRecord( + randomizedNamespace, + "test_stream", + """{"id": 42, "to_drop": "val1", "to_change": 42}""", + emittedAtMs = 1234L, + ) + ) + ) + val finalStream = + makeStream( + syncId = 43, + linkedMapOf("id" to intType, "to_change" to stringType, "to_add" to stringType) + ) + runSync( + configContents, + finalStream, + listOf( + InputRecord( + randomizedNamespace, + "test_stream", + """{"id": 42, "to_change": "val2", "to_add": "val3"}""", + emittedAtMs = 1234, + ) + ) + ) + dumpAndDiffRecords( + parsedConfig, + listOf( + OutputRecord( + extractedAt = 1234, + generationId = 0, + data = + if (isStreamSchemaRetroactive) + // the first sync's record has to_change modified to a string, + // and to_drop is gone completely + mapOf("id" to 42, "to_change" to "42") + else mapOf("id" to 42, "to_drop" to "val1", "to_change" to 42), + airbyteMeta = OutputRecord.Meta(syncId = 42), ), OutputRecord( extractedAt = 1234, @@ -726,7 +1262,7 @@ abstract class BasicFunctionalityIntegrationTest( syncId = syncId, ) fun makeRecord(data: String, extractedAt: Long) = - DestinationRecord( + InputRecord( randomizedNamespace, "test_stream", data, @@ -770,7 +1306,7 @@ abstract class BasicFunctionalityIntegrationTest( mapOf( "id1" to 1, "id2" to 200, - "updated_at" to OffsetDateTime.parse("2000-01-01T00:01:00Z"), + "updated_at" to TimestampWithTimezoneValue("2000-01-01T00:01:00Z"), "name" to "Alice2", "_ab_cdc_deleted_at" to null ), @@ -783,7 +1319,7 @@ abstract class BasicFunctionalityIntegrationTest( mapOf( "id1" to 1, "id2" to 201, - "updated_at" to OffsetDateTime.parse("2000-01-01T00:02:00Z"), + "updated_at" to TimestampWithTimezoneValue("2000-01-01T00:02:00Z"), "name" to "Bob1" ), airbyteMeta = OutputRecord.Meta(syncId = 42), @@ -828,7 +1364,7 @@ abstract class BasicFunctionalityIntegrationTest( mapOf( "id1" to 1, "id2" to 200, - "updated_at" to OffsetDateTime.parse("2000-01-02T00:00:00Z"), + "updated_at" to TimestampWithTimezoneValue("2000-01-02T00:00:00Z"), "name" to "Alice3", "_ab_cdc_deleted_at" to null ), @@ -841,8 +1377,963 @@ abstract class BasicFunctionalityIntegrationTest( ) } + /** + * Change the cursor column in the second sync to a column that doesn't exist in the first sync. + * Verify that we overwrite everything correctly. + * + * This essentially verifies that the destination connector correctly recognizes NULL cursors as + * older than non-NULL cursors. + */ + @Test + open fun testDedupChangeCursor() { + assumeTrue(verifyDataWriting && supportsDedup) + fun makeStream(cursor: String) = + DestinationStream( + DestinationStream.Descriptor(randomizedNamespace, "test_stream"), + Dedupe( + primaryKey = listOf(listOf("id")), + cursor = listOf(cursor), + ), + schema = + ObjectType( + linkedMapOf( + "id" to intType, + cursor to intType, + "name" to stringType, + ) + ), + generationId = 42, + minimumGenerationId = 0, + syncId = 42, + ) + fun makeRecord(cursorName: String) = + InputRecord( + randomizedNamespace, + "test_stream", + data = """{"id": 1, "$cursorName": 1, "name": "foo_$cursorName"}""", + // this is unrealistic (extractedAt should always increase between syncs), + // but it lets us force the dedupe behavior to rely solely on the cursor column, + // instead of being able to fallback onto extractedAt. + emittedAtMs = 100, + ) + runSync(configContents, makeStream("cursor1"), listOf(makeRecord("cursor1"))) + val stream2 = makeStream("cursor2") + runSync(configContents, stream2, listOf(makeRecord("cursor2"))) + dumpAndDiffRecords( + parsedConfig, + listOf( + OutputRecord( + extractedAt = 100, + generationId = 42, + data = + mapOf( + "id" to 1, + "cursor2" to 1, + "name" to "foo_cursor2", + ), + airbyteMeta = OutputRecord.Meta(syncId = 42), + ) + ), + stream2, + primaryKey = listOf(listOf("id")), + cursor = listOf("cursor2"), + ) + } + + open val manyStreamCount = 20 + + /** + * Some destinations can't handle large numbers of streams. This test runs a basic smoke test + * against a catalog with many streams. Subclasses many configure the number of streams using + * [manyStreamCount]. + */ + @Test + open fun testManyStreamsCompletion() { + assumeTrue(verifyDataWriting) + assertTrue( + manyStreamCount > 1, + "manyStreamCount should be greater than 1. If you want to disable this test, just override it and use @Disabled.", + ) + val streams = + (0..manyStreamCount).map { i -> + DestinationStream( + DestinationStream.Descriptor(randomizedNamespace, "test_stream_$i"), + Append, + ObjectType(linkedMapOf("id" to intType, "name" to stringType)), + generationId = 42, + minimumGenerationId = 42, + syncId = 42, + ) + } + val messages = + (0..manyStreamCount).map { i -> + InputRecord( + randomizedNamespace, + "test_stream_$i", + """{"id": 1, "name": "foo_$i"}""", + emittedAtMs = 100, + ) + } + // Just verify that we don't crash. + assertDoesNotThrow { runSync(configContents, DestinationCatalog(streams), messages) } + } + + /** + * A basic test that we handle all supported basic data types in a reasonable way. See also + * [testContainerTypes] for objects/arrays. + */ + // Depending on how future connector development goes - we might need to do something similar to + // BaseSqlGeneratorIntegrationTest, where we split out tests for connectors that do/don't + // support safe_cast. (or, we move fully to in-connector typing, and we stop worrying about + // per-destination safe_cast support). + @Test + open fun testBasicTypes() { + assumeTrue(verifyDataWriting) + val stream = + DestinationStream( + DestinationStream.Descriptor(randomizedNamespace, "test_stream"), + Append, + ObjectType( + linkedMapOf( + "id" to intType, + // Some destinations handle numbers differently in root and nested fields + "struct" to + FieldType( + ObjectType(linkedMapOf("foo" to numberType)), + nullable = true + ), + "string" to FieldType(StringType, nullable = true), + "number" to FieldType(NumberType, nullable = true), + "integer" to FieldType(IntegerType, nullable = true), + "boolean" to FieldType(BooleanType, nullable = true), + "timestamp_with_timezone" to + FieldType(TimestampTypeWithTimezone, nullable = true), + "timestamp_without_timezone" to + FieldType(TimestampTypeWithoutTimezone, nullable = true), + "time_with_timezone" to FieldType(TimeTypeWithTimezone, nullable = true), + "time_without_timezone" to + FieldType(TimeTypeWithoutTimezone, nullable = true), + "date" to FieldType(DateType, nullable = true), + ) + ), + generationId = 42, + minimumGenerationId = 0, + syncId = 42, + ) + fun makeRecord(data: String) = + InputRecord( + randomizedNamespace, + "test_stream", + data, + emittedAtMs = 100, + ) + runSync( + configContents, + stream, + listOf( + // A record with valid values for all fields + makeRecord( + """ + { + "id": 1, + "string": "foo", + "number": 42.1, + "integer": 42, + "boolean": true, + "timestamp_with_timezone": "2023-01-23T12:34:56Z", + "timestamp_without_timezone": "2023-01-23T12:34:56", + "time_with_timezone": "12:34:56Z", + "time_without_timezone": "12:34:56", + "date": "2023-01-23" + } + """.trimIndent() + ), + // A record with null for all fields + makeRecord( + """ + { + "id": 2, + "string": null, + "number": null, + "integer": null, + "boolean": null, + "timestamp_with_timezone": null, + "timestamp_without_timezone": null, + "time_with_timezone": null, + "time_without_timezone": null, + "date": null + } + """.trimIndent() + ), + // A record with all fields unset + makeRecord("""{"id": 3}"""), + // A record that verifies numeric behavior. + // 99999999999999999999999999999999 is out of range for int64. + // 50000.0000000000000001 can't be represented as a standard float64, + // and gets rounded off. + makeRecord( + """ + { + "id": 4, + "struct": {"foo": 50000.0000000000000001}, + "number": 50000.0000000000000001, + "integer": 99999999999999999999999999999999 + } + """.trimIndent(), + ), + // A record with invalid values for all fields + makeRecord( + """ + { + "id": 5, + "string": {}, + "number": "foo", + "integer": "foo", + "boolean": "foo", + "timestamp_with_timezone": "foo", + "timestamp_without_timezone": "foo", + "time_with_timezone": "foo", + "time_without_timezone": "foo", + "date": "foo" + } + """.trimIndent() + ), + ), + ) + + val nestedFloat: BigDecimal + val topLevelFloat: BigDecimal + val bigInt: BigInteger? + val bigIntChanges: List + val badValuesData: Map + val badValuesChanges: MutableList + when (allTypesBehavior) { + is StronglyTyped -> { + nestedFloat = + if (allTypesBehavior.nestedFloatLosesPrecision) { + BigDecimal("50000.0") + } else { + BigDecimal("50000.0000000000000001") + } + topLevelFloat = + if (allTypesBehavior.topLevelFloatLosesPrecision) { + BigDecimal("50000.0") + } else { + BigDecimal("50000.0000000000000001") + } + bigInt = + if (allTypesBehavior.integerCanBeLarge) { + BigInteger("99999999999999999999999999999999") + } else { + null + } + bigIntChanges = + if (allTypesBehavior.integerCanBeLarge) { + emptyList() + } else { + listOf( + Change( + "integer", + AirbyteRecordMessageMetaChange.Change.NULLED, + AirbyteRecordMessageMetaChange.Reason + .DESTINATION_FIELD_SIZE_LIMITATION, + ) + ) + } + badValuesData = + mapOf( + "id" to 5, + "string" to + if (allTypesBehavior.convertAllValuesToString) { + "{}" + } else { + null + }, + "number" to null, + "integer" to null, + "boolean" to null, + "timestamp_with_timezone" to null, + "timestamp_without_timezone" to null, + "time_with_timezone" to null, + "time_without_timezone" to null, + "date" to null, + ) + badValuesChanges = + (stream.schema as ObjectType) + .properties + .keys + // id and struct don't have a bad value case here + // (id would make the test unusable; struct is tested in testContainerTypes) + .filter { it != "id" && it != "struct" } + .map { key -> + Change( + key, + AirbyteRecordMessageMetaChange.Change.NULLED, + AirbyteRecordMessageMetaChange.Reason + .DESTINATION_SERIALIZATION_ERROR, + ) + } + .filter { + !allTypesBehavior.convertAllValuesToString || it.field != "string" + } + .toMutableList() + } + Untyped -> { + nestedFloat = BigDecimal("50000.0000000000000001") + topLevelFloat = BigDecimal("50000.0000000000000001") + bigInt = BigInteger("99999999999999999999999999999999") + bigIntChanges = emptyList() + badValuesData = + // note that the values have different types than what's declared in the schema + mapOf( + "id" to 5, + "string" to ObjectValue(linkedMapOf()), + "number" to "foo", + "integer" to "foo", + "boolean" to "foo", + "timestamp_with_timezone" to "foo", + "timestamp_without_timezone" to "foo", + "time_with_timezone" to "foo", + "time_without_timezone" to "foo", + "date" to "foo", + ) + badValuesChanges = mutableListOf() + } + } + dumpAndDiffRecords( + parsedConfig, + listOf( + OutputRecord( + extractedAt = 100, + generationId = 42, + data = + mapOf( + "id" to 1, + "string" to "foo", + "number" to 42.1, + "integer" to 42, + "boolean" to true, + "timestamp_with_timezone" to + OffsetDateTime.parse("2023-01-23T12:34:56Z"), + "timestamp_without_timezone" to + LocalDateTime.parse("2023-01-23T12:34:56"), + "time_with_timezone" to OffsetTime.parse("12:34:56Z"), + "time_without_timezone" to LocalTime.parse("12:34:56"), + "date" to LocalDate.parse("2023-01-23"), + ), + airbyteMeta = OutputRecord.Meta(syncId = 42), + ), + OutputRecord( + extractedAt = 100, + generationId = 42, + data = + mapOf( + "id" to 2, + "string" to null, + "number" to null, + "integer" to null, + "boolean" to null, + "timestamp_with_timezone" to null, + "timestamp_without_timezone" to null, + "time_with_timezone" to null, + "time_without_timezone" to null, + "date" to null, + ), + airbyteMeta = OutputRecord.Meta(syncId = 42), + ), + OutputRecord( + extractedAt = 100, + generationId = 42, + data = mapOf("id" to 3), + airbyteMeta = OutputRecord.Meta(syncId = 42), + ), + OutputRecord( + extractedAt = 100, + generationId = 42, + data = + mapOf( + "id" to 4, + "struct" to mapOf("foo" to nestedFloat), + "number" to topLevelFloat, + "integer" to bigInt, + ), + airbyteMeta = OutputRecord.Meta(syncId = 42, changes = bigIntChanges), + ), + OutputRecord( + extractedAt = 100, + generationId = 42, + data = badValuesData, + airbyteMeta = OutputRecord.Meta(syncId = 42, changes = badValuesChanges), + ), + ), + stream, + primaryKey = listOf(listOf("id")), + cursor = null, + ) + } + + /** + * Some types (object/array) are expected to contain other types. Verify that we handle them + * correctly. + * + * In particular, verify behavior when they don't specify a schema for the values inside them. + * (e.g. `{type: object}` (without an explicit `properties`) / `{type: array}` (without explicit + * `items`). Some destinations can write those types directly; other destinations need to + * serialize them to a JSON string first. + */ + @Test + open fun testContainerTypes() { + assumeTrue(verifyDataWriting) + val stream = + DestinationStream( + DestinationStream.Descriptor(randomizedNamespace, "problematic_types"), + Append, + ObjectType( + linkedMapOf( + "id" to FieldType(IntegerType, nullable = true), + "schematized_object" to + FieldType( + ObjectType( + linkedMapOf( + "id" to FieldType(IntegerType, nullable = true), + "name" to FieldType(StringType, nullable = true), + ) + ), + nullable = true, + ), + "empty_object" to FieldType(ObjectTypeWithEmptySchema, nullable = true), + "schemaless_object" to FieldType(ObjectTypeWithoutSchema, nullable = true), + "schematized_array" to FieldType(ArrayType(intType), nullable = true), + "schemaless_array" to FieldType(ArrayTypeWithoutSchema, nullable = true), + ), + ), + generationId = 42, + minimumGenerationId = 0, + syncId = 42, + ) + runSync( + configContents, + stream, + listOf( + InputRecord( + randomizedNamespace, + "problematic_types", + """ + { + "id": 1, + "schematized_object": { "id": 1, "name": "Joe" }, + "empty_object": {}, + "schemaless_object": { "uuid": "38F52396-736D-4B23-B5B4-F504D8894B97", "probability": 1.5 }, + "schematized_array": [10, null], + "schemaless_array": [ 10, "foo", null, { "bar": "qua" } ] + }""".trimIndent(), + emittedAtMs = 1602637589100, + ), + InputRecord( + randomizedNamespace, + "problematic_types", + """ + { + "id": 2, + "schematized_object": { "id": 2, "name": "Jane" }, + "empty_object": {"extra": "stuff"}, + "schemaless_object": { "address": { "street": "113 Hickey Rd", "zip": "37932" }, "flags": [ true, false, false ] }, + "schematized_array": [], + "schemaless_array": [] + }""".trimIndent(), + emittedAtMs = 1602637589200, + ), + InputRecord( + randomizedNamespace, + "problematic_types", + """ + { + "id": 3, + "schematized_object": null, + "empty_object": null, + "schemaless_object": null, + "schematized_array": null, + "schemaless_array": null + }""".trimIndent(), + emittedAtMs = 1602637589300, + ), + ) + ) + + val expectedRecords: List = + listOf( + OutputRecord( + extractedAt = 1602637589100, + generationId = 42, + data = + mapOf( + "id" to 1, + "schematized_object" to mapOf("id" to 1, "name" to "Joe"), + "empty_object" to + if (stringifySchemalessObjects) "{}" else emptyMap(), + "schemaless_object" to + if (stringifySchemalessObjects) { + """{"uuid":"38F52396-736D-4B23-B5B4-F504D8894B97","probability":1.5}""" + } else { + mapOf( + "uuid" to "38F52396-736D-4B23-B5B4-F504D8894B97", + "probability" to 1.5 + ) + }, + "schematized_array" to listOf(10, null), + "schemaless_array" to + if (stringifySchemalessObjects) { + """[10,"foo",null,{"bar":"qua"}]""" + } else { + listOf(10, "foo", null, mapOf("bar" to "qua")) + }, + ), + airbyteMeta = OutputRecord.Meta(syncId = 42), + ), + OutputRecord( + extractedAt = 1602637589200, + generationId = 42, + data = + mapOf( + "id" to 2, + "schematized_object" to mapOf("id" to 2, "name" to "Jane"), + "empty_object" to + if (stringifySchemalessObjects) { + """{"extra":"stuff"}""" + } else { + mapOf("extra" to "stuff") + }, + "schemaless_object" to + if (stringifySchemalessObjects) { + """{"address":{"street":"113 Hickey Rd","zip":"37932"},"flags":[true,false,false]}""" + } else { + mapOf( + "address" to + mapOf( + "street" to "113 Hickey Rd", + "zip" to "37932", + ), + "flags" to listOf(true, false, false) + ) + }, + "schematized_array" to emptyList(), + "schemaless_array" to + if (stringifySchemalessObjects) { + "[]" + } else { + emptyList() + }, + ), + airbyteMeta = OutputRecord.Meta(syncId = 42), + ), + OutputRecord( + extractedAt = 1602637589300, + generationId = 42, + data = + mapOf( + "id" to 3, + "schematized_object" to null, + "empty_object" to null, + "schemaless_object" to null, + "schematized_array" to null, + "schemaless_array" to null, + ), + airbyteMeta = OutputRecord.Meta(syncId = 42), + ), + ) + + dumpAndDiffRecords( + parsedConfig, + expectedRecords, + stream, + primaryKey = listOf(listOf("id")), + cursor = null, + ) + } + + @Test + open fun testUnknownTypes() { + assumeTrue(verifyDataWriting) + val stream = + DestinationStream( + DestinationStream.Descriptor(randomizedNamespace, "problematic_types"), + Append, + ObjectType( + linkedMapOf( + "id" to intType, + "name" to + FieldType( + UnknownType( + JsonNodeFactory.instance.objectNode().put("type", "whatever") + ), + nullable = true + ), + ), + ), + generationId = 42, + minimumGenerationId = 0, + syncId = 42, + ) + runSync( + configContents, + stream, + listOf( + InputRecord( + randomizedNamespace, + "problematic_types", + """ + { + "id": 1, + "name": "ex falso quodlibet" + }""".trimIndent(), + emittedAtMs = 1602637589100, + ) + ) + ) + + val expectedRecords: List = + listOf( + OutputRecord( + extractedAt = 1602637589100, + generationId = 42, + data = + mapOf( + "id" to 1, + "name" to + if (nullUnknownTypes) { + null + } else { + "ex falso quodlibet" + }, + ), + airbyteMeta = + OutputRecord.Meta( + syncId = 42, + changes = + if (nullUnknownTypes) { + listOf( + Change( + "name", + AirbyteRecordMessageMetaChange.Change.NULLED, + AirbyteRecordMessageMetaChange.Reason + .DESTINATION_SERIALIZATION_ERROR + ) + ) + } else { + emptyList() + } + ), + ), + ) + + dumpAndDiffRecords( + parsedConfig, + expectedRecords, + stream, + primaryKey = listOf(listOf("id")), + cursor = null, + ) + } + + /** + * This test verifies that destinations handle unions correctly. + * + * Some destinations have poor native support for union types, and instead promote unions into + * objects. For example, given a schema `Union(String, Integer)`, this field would be written + * into the destination as either `{"string": "foo"}` or `{"integer": 42}`. + */ + @Test + open fun testUnions() { + assumeTrue(verifyDataWriting) + val stream = + DestinationStream( + DestinationStream.Descriptor(randomizedNamespace, "problematic_types"), + Append, + ObjectType( + linkedMapOf( + "id" to FieldType(IntegerType, nullable = true), + // in jsonschema, there are two ways to achieve this: + // {type: [string, int]} + // {oneOf: [{type: string}, {type: int}]} + // Our AirbyteType treats them identically, so we don't need two test cases. + "combined_type" to + FieldType(UnionType.of(StringType, IntegerType), nullable = true), + // For destinations which promote unions to objects, + // and also stringify schemaless values, + // we should verify that the promoted schemaless value + // is still labelled as "object" rather than "string". + "union_of_string_and_schemaless_type" to + FieldType( + UnionType.of(ObjectTypeWithoutSchema, IntegerType), + nullable = true, + ), + "union_of_objects_with_properties_identical" to + FieldType( + UnionType.of( + ObjectType( + linkedMapOf( + "id" to FieldType(IntegerType, nullable = true), + "name" to FieldType(StringType, nullable = true), + ) + ), + ObjectType( + linkedMapOf( + "id" to FieldType(IntegerType, nullable = true), + "name" to FieldType(StringType, nullable = true), + ) + ) + ), + nullable = true, + ), + "union_of_objects_with_properties_overlapping" to + FieldType( + UnionType.of( + ObjectType( + linkedMapOf( + "id" to FieldType(IntegerType, nullable = true), + "name" to FieldType(StringType, nullable = true), + ) + ), + ObjectType( + linkedMapOf( + "name" to FieldType(StringType, nullable = true), + "flagged" to FieldType(BooleanType, nullable = true), + ) + ) + ), + nullable = true, + ), + "union_of_objects_with_properties_nonoverlapping" to + FieldType( + UnionType.of( + ObjectType( + linkedMapOf( + "id" to FieldType(IntegerType, nullable = true), + "name" to FieldType(StringType, nullable = true), + ) + ), + ObjectType( + linkedMapOf( + "flagged" to FieldType(BooleanType, nullable = true), + "description" to FieldType(StringType, nullable = true), + ) + ) + ), + nullable = true, + ), + "union_of_objects_with_properties_contradicting" to + FieldType( + UnionType.of( + ObjectType( + linkedMapOf( + "id" to FieldType(IntegerType, nullable = true), + "name" to FieldType(StringType, nullable = true), + ) + ), + ObjectType( + linkedMapOf( + "id" to FieldType(StringType, nullable = true), + "name" to FieldType(StringType, nullable = true), + ) + ) + ), + nullable = true, + ), + ), + ), + generationId = 42, + minimumGenerationId = 0, + syncId = 42, + ) + runSync( + configContents, + stream, + listOf( + InputRecord( + randomizedNamespace, + "problematic_types", + """ + { + "id": 1, + "combined_type": "string1", + "union_of_string_and_schemaless_type": {"foo": "bar"}, + "union_of_objects_with_properties_identical": { "id": 10, "name": "Joe" }, + "union_of_objects_with_properties_overlapping": { "id": 20, "name": "Jane", "flagged": true }, + "union_of_objects_with_properties_contradicting": { "id": 1, "name": "Jenny" }, + "union_of_objects_with_properties_nonoverlapping": { "id": 30, "name": "Phil", "flagged": false, "description":"Very Phil" } + }""".trimIndent(), + emittedAtMs = 1602637589100, + ), + InputRecord( + randomizedNamespace, + "problematic_types", + """ + { + "id": 2, + "combined_type": 20, + "union_of_objects_with_properties_identical": {}, + "union_of_objects_with_properties_overlapping": {}, + "union_of_objects_with_properties_nonoverlapping": {}, + "union_of_objects_with_properties_contradicting": { "id": "seal-one-hippity", "name": "James" } + }""".trimIndent(), + emittedAtMs = 1602637589200, + ), + InputRecord( + randomizedNamespace, + "problematic_types", + """ + { + "id": 3, + "combined_type": null, + "union_of_objects_with_properties_identical": null, + "union_of_objects_with_properties_overlapping": null, + "union_of_objects_with_properties_nonoverlapping": null, + "union_of_objects_with_properties_contradicting": null + }""".trimIndent(), + emittedAtMs = 1602637589300, + ), + ) + ) + + fun maybePromote(typeName: String, value: Any?) = + if (promoteUnionToObject) { + mapOf( + "type" to typeName, + typeName to value, + ) + } else { + value + } + val expectedRecords: List = + listOf( + OutputRecord( + extractedAt = 1602637589100, + generationId = 42, + data = + mapOf( + "id" to 1, + "combined_type" to maybePromote("string", "string1"), + "union_of_string_and_schemaless_type" to + maybePromote( + "object", + if (stringifySchemalessObjects) { + """{"foo":"bar"}""" + } else { + mapOf("foo" to "bar") + } + ), + "union_of_objects_with_properties_identical" to + mapOf("id" to 10, "name" to "Joe"), + "union_of_objects_with_properties_overlapping" to + mapOf("id" to 20, "name" to "Jane", "flagged" to true), + "union_of_objects_with_properties_contradicting" to + mapOf("id" to maybePromote("integer", 1), "name" to "Jenny"), + "union_of_objects_with_properties_nonoverlapping" to + mapOf( + "id" to 30, + "name" to "Phil", + "flagged" to false, + "description" to "Very Phil", + ) + ), + airbyteMeta = OutputRecord.Meta(syncId = 42), + ), + OutputRecord( + extractedAt = 1602637589200, + generationId = 42, + data = + mapOf( + "id" to 2, + "combined_type" to maybePromote("integer", 20), + "union_of_objects_with_properties_identical" to + emptyMap(), + "union_of_objects_with_properties_nonoverlapping" to + emptyMap(), + "union_of_objects_with_properties_overlapping" to + emptyMap(), + "union_of_objects_with_properties_contradicting" to + mapOf( + "id" to maybePromote("string", "seal-one-hippity"), + "name" to "James" + ) + ), + airbyteMeta = OutputRecord.Meta(syncId = 42), + ), + OutputRecord( + extractedAt = 1602637589300, + generationId = 42, + data = + mapOf( + "id" to 3, + "combined_type" to null, + "union_of_objects_with_properties_identical" to null, + "union_of_objects_with_properties_overlapping" to null, + "union_of_objects_with_properties_nonoverlapping" to null, + "union_of_objects_with_properties_contradicting" to null + ), + airbyteMeta = OutputRecord.Meta(syncId = 42), + ), + ) + + dumpAndDiffRecords( + parsedConfig, + expectedRecords, + stream, + primaryKey = listOf(listOf("id")), + cursor = null, + ) + } + + /** + * Verify that we can handle a stream with 0 columns. This is... not particularly useful, but + * happens sometimes. + */ + open fun testNoColumns() { + val stream = + DestinationStream( + DestinationStream.Descriptor(randomizedNamespace, "test_stream"), + Append, + ObjectType(linkedMapOf()), + generationId = 42, + minimumGenerationId = 0, + syncId = 42, + ) + runSync( + configContents, + stream, + listOf( + InputRecord( + randomizedNamespace, + "test_stream", + """{"foo": "bar"}""", + emittedAtMs = 1000L, + ) + ) + ) + dumpAndDiffRecords( + parsedConfig, + listOf( + OutputRecord( + extractedAt = 1000L, + generationId = 42, + data = + if (preserveUndeclaredFields) { + mapOf("foo" to "bar") + } else { + emptyMap() + }, + airbyteMeta = OutputRecord.Meta(syncId = 42), + ) + ), + stream, + primaryKey = listOf(), + cursor = null, + ) + } + companion object { private val intType = FieldType(IntegerType, nullable = true) + private val numberType = FieldType(NumberType, nullable = true) private val stringType = FieldType(StringType, nullable = true) private val timestamptzType = FieldType(TimestampTypeWithTimezone, nullable = true) } diff --git a/airbyte-cdk/bulk/core/load/src/testFixtures/resources/application.yaml b/airbyte-cdk/bulk/core/load/src/testFixtures/resources/application.yaml new file mode 100644 index 000000000000..eaf8e065262f --- /dev/null +++ b/airbyte-cdk/bulk/core/load/src/testFixtures/resources/application.yaml @@ -0,0 +1,12 @@ +airbyte: + file-transfer: + enabled: ${USE_FILE_TRANSFER:false} + staging-path: ${AIRBYTE_STAGING_DIRECTORY:/staging/files} + resources: + disk: + bytes: ${CONNECTOR_STORAGE_LIMIT_BYTES:5368709120} # 5GB + flush: + rate-ms: 900000 # 15 minutes + window-ms: 900000 # 15 minutes + destination: + record-batch-size-override: 1 # 1 byte for testing; 1 record => 1 upload diff --git a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/CdcGlobalLockResource.kt b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/CdcGlobalLockResource.kt deleted file mode 100644 index 4820064d7ed9..000000000000 --- a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/CdcGlobalLockResource.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.cdk.read.cdc - -import io.airbyte.cdk.command.SourceConfiguration -import io.airbyte.cdk.read.GlobalLockResource -import io.micronaut.context.annotation.Replaces -import jakarta.inject.Singleton -import java.util.concurrent.atomic.AtomicBoolean - -@Singleton -@Replaces(GlobalLockResource::class) -/** - * [GlobalLockResource] implementation for CDC with Debezium. - * - * Holds the lock while CDC is ongoing. - */ -class CdcGlobalLockResource(configuration: SourceConfiguration) : GlobalLockResource { - - private val isCdcComplete = AtomicBoolean(configuration.global.not()) - - /** Called when CDC is done to release the lock. */ - fun markCdcAsComplete() { - isCdcComplete.set(true) - } - - override fun tryAcquire(): GlobalLockResource.AcquiredGlobalLock? = - if (isCdcComplete.get()) { - GlobalLockResource.AcquiredGlobalLock {} - } else { - null - } -} diff --git a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionReader.kt b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionReader.kt index a2896a4bf7af..7c0c8661fbbc 100644 --- a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionReader.kt +++ b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionReader.kt @@ -9,20 +9,19 @@ import io.airbyte.cdk.read.ConcurrencyResource import io.airbyte.cdk.read.PartitionReadCheckpoint import io.airbyte.cdk.read.PartitionReader import io.airbyte.cdk.read.StreamRecordConsumer -import io.airbyte.cdk.util.Jsons -import io.debezium.embedded.EmbeddedEngineChangeEvent +import io.airbyte.cdk.read.UnlimitedTimePartitionReader +import io.airbyte.protocol.models.v0.StreamDescriptor import io.debezium.engine.ChangeEvent import io.debezium.engine.DebeziumEngine import io.debezium.engine.format.Json import io.github.oshai.kotlinlogging.KotlinLogging -import java.util.Properties +import java.util.* import java.util.concurrent.atomic.AtomicLong import java.util.concurrent.atomic.AtomicReference import java.util.function.Consumer import kotlin.coroutines.CoroutineContext import kotlin.coroutines.coroutineContext import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.isActive import kotlinx.coroutines.withContext import org.apache.kafka.connect.source.SourceRecord @@ -33,7 +32,7 @@ class CdcPartitionReader>( val readerOps: CdcPartitionReaderDebeziumOperations, val upperBound: T, val input: DebeziumInput, -) : PartitionReader { +) : UnlimitedTimePartitionReader { private val log = KotlinLogging.logger {} private val acquiredThread = AtomicReference() private lateinit var stateFilesAccessor: DebeziumStateFilesAccessor @@ -88,7 +87,14 @@ class CdcPartitionReader>( val thread = Thread(engine, "debezium-engine") thread.setUncaughtExceptionHandler { _, e: Throwable -> engineException.set(e) } thread.start() - withContext(Dispatchers.IO) { thread.join() } + try { + withContext(Dispatchers.IO) { thread.join() } + } catch (e: Throwable) { + // This catches any exceptions thrown by join() + // but also by the kotlin coroutine dispatcher, like TimeoutCancellationException. + engineException.compareAndSet(null, e) + } + // Print a nice log message and re-throw any exception. val exception: Throwable? = engineException.get() val summary: Map = mapOf( @@ -125,61 +131,107 @@ class CdcPartitionReader>( private val coroutineContext: CoroutineContext, ) : Consumer> { - override fun accept(event: ChangeEvent) { + override fun accept(changeEvent: ChangeEvent) { + val event = DebeziumEvent(changeEvent) + val eventType: EventType = emitRecord(event) + // Update counters. + updateCounters(event, eventType) + // Look for reasons to close down the engine. + val closeReason: CloseReason = findCloseReason(event, eventType) ?: return + // At this point, if we haven't returned already, we want to close down the engine. + if (!closeReasonReference.compareAndSet(null, closeReason)) { + // An earlier event has already triggered closing down the engine, do nothing. + return + } + // At this point, if we haven't returned already, we need to close down the engine. + log.info { "Shutting down Debezium engine: ${closeReason.message}." } + // TODO : send close analytics message + Thread({ engine.close() }, "debezium-close").start() + } + + private fun emitRecord(event: DebeziumEvent): EventType { + if (event.isTombstone) { + // Debezium outputs a tombstone event that has a value of null. This is an artifact + // of how it interacts with kafka. We want to ignore it. More on the tombstone: + // https://debezium.io/documentation/reference/stable/transformations/event-flattening.html + return EventType.TOMBSTONE + } + if (event.isHeartbeat) { + // Heartbeats are only used for their position. + return EventType.HEARTBEAT + } + if (event.key == null) { + // Sometimes, presumably due to bugs in Debezium, the key isn't valid JSON. + return EventType.KEY_JSON_INVALID + } + if (event.value == null) { + // Sometimes, presumably due to bugs in Debezium, the value isn't valid JSON. + return EventType.VALUE_JSON_INVALID + } + val streamRecordConsumer: StreamRecordConsumer = + findStreamRecordConsumer(event.key, event.value) + // Ignore events which can't be mapped to a stream. + ?: return EventType.RECORD_DISCARDED_BY_STREAM_ID + val deserializedRecord: DeserializedRecord = + readerOps.deserialize(event.key, event.value, streamRecordConsumer.stream) + // Ignore events which can't be deserialized into records. + ?: return EventType.RECORD_DISCARDED_BY_DESERIALIZE + // Emit the record at the end of the happy path. + streamRecordConsumer.accept(deserializedRecord.data, deserializedRecord.changes) + return EventType.RECORD_EMITTED + } + + private fun findStreamRecordConsumer( + key: DebeziumRecordKey, + value: DebeziumRecordValue + ): StreamRecordConsumer? { + val name: String = readerOps.findStreamName(key, value) ?: return null + val namespace: String? = readerOps.findStreamNamespace(key, value) + val desc: StreamDescriptor = StreamDescriptor().withNamespace(namespace).withName(name) + val streamID: StreamIdentifier = StreamIdentifier.from(desc) + return streamRecordConsumers[streamID] + } + + private fun updateCounters(event: DebeziumEvent, eventType: EventType) { numEvents.incrementAndGet() - // Get SourceRecord object if possible. - // This object is the preferred way to obtain the current position. - val sourceRecord: SourceRecord? = - (event as? EmbeddedEngineChangeEvent<*, *, *>)?.sourceRecord() - if (sourceRecord == null) numEventsWithoutSourceRecord.incrementAndGet() - // Debezium outputs a tombstone event that has a value of null. This is an artifact - // of how it interacts with kafka. We want to ignore it. More on the tombstone: - // https://debezium.io/documentation/reference/stable/transformations/event-flattening.html - val debeziumRecordValue: DebeziumRecordValue? = - event.value()?.let { DebeziumRecordValue(Jsons.readTree(it)) } - // Process records, ignoring heartbeats which are only used for completion checks. - val isRecord: Boolean - if (debeziumRecordValue == null) { - isRecord = false - numTombstones.incrementAndGet() - } else if (debeziumRecordValue.isHeartbeat) { - isRecord = false - numHeartbeats.incrementAndGet() - } else { - isRecord = true - val debeziumRecordKey = DebeziumRecordKey(Jsons.readTree(event.key())) - val deserializedRecord: DeserializedRecord = - readerOps.deserialize(debeziumRecordKey, debeziumRecordValue) - val streamRecordConsumer: StreamRecordConsumer? = - streamRecordConsumers[deserializedRecord.streamID] - if (streamRecordConsumer == null) { - numDiscardedRecords.incrementAndGet() - } else { - streamRecordConsumer.accept(deserializedRecord.data, deserializedRecord.changes) - numEmittedRecords.incrementAndGet() - } + if (event.sourceRecord == null) { + numEventsWithoutSourceRecord.incrementAndGet() } - // Look for reasons to close down the engine. - val closeReason: CloseReason? = run { - if (!coroutineContext.isActive) { - return@run CloseReason.TIMEOUT - } - val currentPosition: T? = position(sourceRecord) ?: position(debeziumRecordValue) - if (currentPosition == null || currentPosition < upperBound) { - return@run null - } - // Close because the current event is past the sync upper bound. - if (isRecord) { - CloseReason.RECORD_REACHED_TARGET_POSITION - } else { - CloseReason.HEARTBEAT_OR_TOMBSTONE_REACHED_TARGET_POSITION - } + when (eventType) { + EventType.TOMBSTONE -> numTombstones + EventType.HEARTBEAT -> numHeartbeats + EventType.KEY_JSON_INVALID, + EventType.VALUE_JSON_INVALID, + EventType.RECORD_DISCARDED_BY_DESERIALIZE, + EventType.RECORD_DISCARDED_BY_STREAM_ID -> numDiscardedRecords + EventType.RECORD_EMITTED -> numEmittedRecords + }.incrementAndGet() + } + + private fun findCloseReason(event: DebeziumEvent, eventType: EventType): CloseReason? { + if (input.isSynthetic && eventType != EventType.HEARTBEAT) { + // Special case where the engine started with a synthetic offset: + // don't even consider closing the engine unless handling a heartbeat event. + // For some databases, such as Oracle, Debezium actually needs to snapshot the + // schema in order to collect the database schema history and there's no point + // in interrupting it until the snapshot is done. + return null } - // Idempotent engine shutdown. - if (closeReason != null && closeReasonReference.compareAndSet(null, closeReason)) { - log.info { "Shutting down Debezium engine: ${closeReason.message}." } - // TODO : send close analytics message - Thread({ engine.close() }, "debezium-close").start() + + val currentPosition: T? = position(event.sourceRecord) ?: position(event.value) + if (currentPosition == null || currentPosition < upperBound) { + return null + } + // Close because the current event is past the sync upper bound. + return when (eventType) { + EventType.TOMBSTONE, + EventType.HEARTBEAT -> CloseReason.HEARTBEAT_OR_TOMBSTONE_REACHED_TARGET_POSITION + EventType.KEY_JSON_INVALID, + EventType.VALUE_JSON_INVALID, + EventType.RECORD_EMITTED, + EventType.RECORD_DISCARDED_BY_DESERIALIZE, + EventType.RECORD_DISCARDED_BY_STREAM_ID -> + CloseReason.RECORD_REACHED_TARGET_POSITION } } @@ -204,6 +256,16 @@ class CdcPartitionReader>( } } + private enum class EventType { + TOMBSTONE, + HEARTBEAT, + KEY_JSON_INVALID, + VALUE_JSON_INVALID, + RECORD_DISCARDED_BY_DESERIALIZE, + RECORD_DISCARDED_BY_STREAM_ID, + RECORD_EMITTED, + } + inner class CompletionCallback : DebeziumEngine.CompletionCallback { override fun handle(success: Boolean, message: String?, error: Throwable?) { if (success) { diff --git a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionsCreator.kt b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionsCreator.kt index 4ec20217d07b..6ae589cb6499 100644 --- a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionsCreator.kt +++ b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionsCreator.kt @@ -5,6 +5,7 @@ package io.airbyte.cdk.read.cdc import io.airbyte.cdk.ConfigErrorException +import io.airbyte.cdk.TransientErrorException import io.airbyte.cdk.read.ConcurrencyResource import io.airbyte.cdk.read.GlobalFeedBootstrap import io.airbyte.cdk.read.PartitionReader @@ -16,15 +17,17 @@ import java.util.concurrent.atomic.AtomicReference /** [PartitionsCreator] implementation for CDC with Debezium. */ class CdcPartitionsCreator>( val concurrencyResource: ConcurrencyResource, - val globalLockResource: CdcGlobalLockResource, val feedBootstrap: GlobalFeedBootstrap, val creatorOps: CdcPartitionsCreatorDebeziumOperations, val readerOps: CdcPartitionReaderDebeziumOperations, + val lowerBoundReference: AtomicReference, val upperBoundReference: AtomicReference, ) : PartitionsCreator { private val log = KotlinLogging.logger {} private val acquiredThread = AtomicReference() + class OffsetInvalidNeedsResyncIllegalStateException() : IllegalStateException() + override fun tryAcquireResources(): PartitionsCreator.TryAcquireResourcesStatus { val acquiredThread: ConcurrencyResource.AcquiredThread = concurrencyResource.tryAcquire() @@ -38,6 +41,11 @@ class CdcPartitionsCreator>( } override suspend fun run(): List { + if (CDCNeedsRestart) { + throw TransientErrorException( + "Saved offset no longer present on the server, Airbyte is going to trigger a sync from scratch." + ) + } val activeStreams: List by lazy { feedBootstrap.feed.streams.filter { feedBootstrap.stateQuerier.current(it) != null } } @@ -57,8 +65,14 @@ class CdcPartitionsCreator>( creatorOps.deserialize(incumbentOpaqueStateValue, activeStreams) } catch (ex: ConfigErrorException) { log.error(ex) { "Existing state is invalid." } - globalLockResource.markCdcAsComplete() throw ex + } catch (_: OffsetInvalidNeedsResyncIllegalStateException) { + // If deserialization concludes we need a re-sync we rollback stream states + // and put the creator in a Need Restart mode. + // The next round will throw a transient error to kickoff the resync + feedBootstrap.stateQuerier.resetFeedStates() + CDCNeedsRestart = true + syntheticInput } } } @@ -72,23 +86,35 @@ class CdcPartitionsCreator>( upperBound, input ) + val lowerBound: T = creatorOps.position(input.state.offset) + val lowerBoundInPreviousRound: T? = lowerBoundReference.getAndSet(lowerBound) if (input.isSynthetic) { // Handle synthetic offset edge-case, which always needs to run. // Debezium needs to run to generate the full state, which might include schema history. log.info { "Current offset is synthetic." } return listOf(partitionReader) } - val lowerBound: T = creatorOps.position(input.state.offset) if (upperBound <= lowerBound) { // Handle completion due to reaching the WAL position upper bound. log.info { "Current position '$lowerBound' equals or exceeds target position '$upperBound'." } - globalLockResource.markCdcAsComplete() - return listOf() + return emptyList() + } + if (lowerBoundInPreviousRound != null && lowerBound <= lowerBoundInPreviousRound) { + // Handle completion due to stalling. + log.info { + "Current position '$lowerBound' has not increased in the last round, " + + "prior to which is was '$lowerBoundInPreviousRound'." + } + return emptyList() } // Handle common case. log.info { "Current position '$lowerBound' does not exceed target position '$upperBound'." } return listOf(partitionReader) } + + companion object { + var CDCNeedsRestart: Boolean = false + } } diff --git a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionsCreatorFactory.kt b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionsCreatorFactory.kt index c7aa758be6bf..6a188c02575a 100644 --- a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionsCreatorFactory.kt +++ b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionsCreatorFactory.kt @@ -18,10 +18,16 @@ import java.util.concurrent.atomic.AtomicReference /** [PartitionsCreatorFactory] implementation for CDC with Debezium. */ class CdcPartitionsCreatorFactory>( val concurrencyResource: ConcurrencyResource, - val globalLockResource: CdcGlobalLockResource, val debeziumOps: DebeziumOperations, ) : PartitionsCreatorFactory { + /** + * [AtomicReference] to a WAL position lower bound value shared by all [CdcPartitionsCreator]s. + * This value is updated by the [CdcPartitionsCreator] based on the incumbent state and is used + * to detect stalls. + */ + private val lowerBoundReference = AtomicReference() + /** * [AtomicReference] to a WAL position upper bound value shared by all [CdcPartitionsCreator]s. * This value is set exactly once by the first [CdcPartitionsCreator]. @@ -35,10 +41,10 @@ class CdcPartitionsCreatorFactory>( } return CdcPartitionsCreator( concurrencyResource, - globalLockResource, feedBootstrap, debeziumOps, debeziumOps, + lowerBoundReference, upperBoundReference, ) } diff --git a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/Debezium.kt b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/Debezium.kt index e1693a0d0fc0..f73c7522e4ee 100644 --- a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/Debezium.kt +++ b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/Debezium.kt @@ -6,7 +6,43 @@ package io.airbyte.cdk.read.cdc import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.node.NullNode +import io.airbyte.cdk.util.Jsons +import io.debezium.embedded.EmbeddedEngineChangeEvent +import io.debezium.engine.ChangeEvent import io.debezium.relational.history.HistoryRecord +import org.apache.kafka.connect.source.SourceRecord + +/** Convenience wrapper around [ChangeEvent]. */ +class DebeziumEvent(event: ChangeEvent) { + + /** This [SourceRecord] object is the preferred way to obtain the current position. */ + val sourceRecord: SourceRecord? = (event as? EmbeddedEngineChangeEvent<*, *, *>)?.sourceRecord() + + val key: DebeziumRecordKey? = + event + .key() + ?.let { runCatching { Jsons.readTree(it) }.getOrNull() } + ?.let(::DebeziumRecordKey) + + val value: DebeziumRecordValue? = + event + .value() + ?.let { runCatching { Jsons.readTree(it) }.getOrNull() } + ?.let(::DebeziumRecordValue) + + /** + * Debezium can output a tombstone event that has a value of null. This is an artifact of how it + * interacts with kafka. We want to ignore it. More on the tombstone: + * https://debezium.io/documentation/reference/stable/transformations/event-flattening.html + */ + val isTombstone: Boolean = event.value() == null + + /** + * True if this is a Debezium heartbeat event, or the equivalent thereof. In any case, such + * events are only used for their position value and for triggering timeouts. + */ + val isHeartbeat: Boolean = value?.source?.isNull == true +} /** [DebeziumRecordKey] wraps a Debezium change data event key. */ @JvmInline @@ -25,10 +61,6 @@ value class DebeziumRecordKey(val wrapped: JsonNode) { @JvmInline value class DebeziumRecordValue(val wrapped: JsonNode) { - /** True if this is a Debezium heartbeat event. These aren't passed to [DebeziumConsumer]. */ - val isHeartbeat: Boolean - get() = source.isNull - /** The datum prior to this event; null for insertions. */ val before: JsonNode get() = element("before") diff --git a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/DebeziumOperations.kt b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/DebeziumOperations.kt index 990924bcfcdb..c425f5fd6d96 100644 --- a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/DebeziumOperations.kt +++ b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/DebeziumOperations.kt @@ -5,7 +5,6 @@ package io.airbyte.cdk.read.cdc import com.fasterxml.jackson.databind.node.ObjectNode -import io.airbyte.cdk.StreamIdentifier import io.airbyte.cdk.command.OpaqueStateValue import io.airbyte.cdk.discover.Field import io.airbyte.cdk.read.FieldValueChange @@ -30,8 +29,28 @@ interface CdcPartitionsCreatorDebeziumOperations> { interface CdcPartitionReaderDebeziumOperations> { - /** Transforms a [DebeziumRecordValue] into a [DeserializedRecord]. */ - fun deserialize(key: DebeziumRecordKey, value: DebeziumRecordValue): DeserializedRecord + /** + * Transforms a [DebeziumRecordKey] and a [DebeziumRecordValue] into a [DeserializedRecord]. + * + * Returning null means that the event should be treated like a heartbeat. + */ + fun deserialize( + key: DebeziumRecordKey, + value: DebeziumRecordValue, + stream: Stream, + ): DeserializedRecord? + + /** Identifies the namespace of the stream that this event belongs to, if applicable. */ + fun findStreamNamespace( + key: DebeziumRecordKey, + value: DebeziumRecordValue, + ): String? + + /** Identifies the null of the stream that this event belongs to, if applicable. */ + fun findStreamName( + key: DebeziumRecordKey, + value: DebeziumRecordValue, + ): String? /** Maps a [DebeziumState] to an [OpaqueStateValue]. */ fun serialize(debeziumState: DebeziumState): OpaqueStateValue @@ -45,7 +64,6 @@ interface CdcPartitionReaderDebeziumOperations> { /** [DeserializedRecord]s are used to generate Airbyte RECORD messages. */ data class DeserializedRecord( - val streamID: StreamIdentifier, val data: ObjectNode, val changes: Map, ) diff --git a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/DebeziumPropertiesBuilder.kt b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/DebeziumPropertiesBuilder.kt index 97a2aee945f8..d0b8dcc0803f 100644 --- a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/DebeziumPropertiesBuilder.kt +++ b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/DebeziumPropertiesBuilder.kt @@ -11,6 +11,7 @@ import java.nio.file.Path import java.time.Duration import java.util.Properties import java.util.regex.Pattern +import kotlin.reflect.KClass import org.apache.kafka.connect.connector.Connector import org.apache.kafka.connect.runtime.standalone.StandaloneConfig import org.apache.kafka.connect.storage.FileOffsetBackingStore @@ -56,7 +57,10 @@ class DebeziumPropertiesBuilder(private val props: Properties = Properties()) { // unless we set the following. with("value.converter.replace.null.with.default", "false") // Timeout for DebeziumEngine's close() method. - with("debezium.embedded.shutdown.pause.before.interrupt.ms", "10000") + // We find that in production, substantial time is in fact legitimately required here. + with("debezium.embedded.shutdown.pause.before.interrupt.ms", "60000") + // Unblock CDC syncs by skipping errors caused by unparseable DDLs + with("schema.history.internal.skip.unparseable.ddl", "true") } fun withOffset(): DebeziumPropertiesBuilder = apply { @@ -125,6 +129,25 @@ class DebeziumPropertiesBuilder(private val props: Properties = Properties()) { } } + fun withConverters( + vararg converters: KClass + ): DebeziumPropertiesBuilder = withConverters(*converters.map { it.java }.toTypedArray()) + + fun withConverters( + vararg converters: Class + ): DebeziumPropertiesBuilder { + val classByKey: Map> = + converters.associateBy { + it.getDeclaredConstructor().newInstance().debeziumPropertiesKey + } + return apply { + with("converters", classByKey.keys.joinToString(separator = ",")) + for ((key, converterClass) in classByKey) { + with("${key}.type", converterClass.canonicalName) + } + } + } + companion object { fun joinIncludeList(includes: List): String = diff --git a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/DebeziumStateFilesAccessor.kt b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/DebeziumStateFilesAccessor.kt index 536b55cd20ea..012cc461e0c3 100644 --- a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/DebeziumStateFilesAccessor.kt +++ b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/DebeziumStateFilesAccessor.kt @@ -53,22 +53,8 @@ class DebeziumStateFilesAccessor : AutoCloseable { fileOffsetBackingStore.configure(StandaloneConfig(fileOffsetConfig)) } - private val fileSchemaHistory = FileSchemaHistory() - - init { - fileSchemaHistory.configure( - Configuration.create() - .with(FileSchemaHistory.FILE_PATH, schemaFilePath.toString()) - .build(), - HistoryRecordComparator.INSTANCE, - SchemaHistoryListener.NOOP, - false - ) - } - override fun close() { fileOffsetBackingStore.stop() - fileSchemaHistory.stop() FileUtils.deleteDirectory(workingDir.toFile()) } @@ -90,21 +76,20 @@ class DebeziumStateFilesAccessor : AutoCloseable { } fun readSchema(): DebeziumSchemaHistory { - fileSchemaHistory.start() - val schema: List = buildList { - recoverRecords(fileSchemaHistory, Consumer(this::add)) + var schema: List = listOf() + doWithFileSchemaHistory(schemaFilePath) { fileSchemaHistory -> + schema = buildList { recoverRecords(fileSchemaHistory, Consumer(this::add)) } } - fileSchemaHistory.stop() + return DebeziumSchemaHistory(schema) } fun writeSchema(schema: DebeziumSchemaHistory) { - fileSchemaHistory.initializeStorage() - fileSchemaHistory.start() - for (r in schema.wrapped) { - storeRecord(fileSchemaHistory, r) + doWithFileSchemaHistory(schemaFilePath) { fileSchemaHistory -> + for (r in schema.wrapped) { + storeRecord(fileSchemaHistory, r) + } } - fileSchemaHistory.stop() } private fun toJson(byteBuffer: ByteBuffer): JsonNode { @@ -137,5 +122,23 @@ class DebeziumStateFilesAccessor : AutoCloseable { .java .getDeclaredMethod("recoverRecords", Consumer::class.java) .apply { isAccessible = true } + + private fun doWithFileSchemaHistory( + schemaFilePath: Path, + block: (FileSchemaHistory) -> Unit + ) { + val fileSchemaHistory = FileSchemaHistory() + fileSchemaHistory.configure( + Configuration.create() + .with(FileSchemaHistory.FILE_PATH, schemaFilePath.toString()) + .build(), + HistoryRecordComparator.INSTANCE, + SchemaHistoryListener.NOOP, + false + ) + fileSchemaHistory.start() + block(fileSchemaHistory) + fileSchemaHistory.stop() + } } } diff --git a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/PartialConverter.kt b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/PartialConverter.kt new file mode 100644 index 000000000000..f74ada36409f --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/PartialConverter.kt @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.read.cdc + +import io.debezium.spi.converter.ConvertedField +import io.debezium.spi.converter.CustomConverter +import io.debezium.spi.converter.RelationalColumn +import io.github.oshai.kotlinlogging.KotlinLogging +import java.util.concurrent.atomic.AtomicBoolean + +/** + * [PartialConverter] objects are used by [RelationalColumnCustomConverter.Handler] objects which to + * define a sequence of conversion functions which work on a best-effort basis to convert a given + * input value, provided by Debezium, into an output value which obeys the Airbyte Protocol. + * + * For example, a [PartialConverter] implementation for timestamps with time zones may attempt to + * cast an input value as an [java.time.OffsetDateTime]. If the cast is unsuccessful the + * [PartialConverter] will return [NoConversion], but if it's successful it will format it the way + * Airbyte expects (ISO8601 with microsecond precision etc.) and wrap the result in a [Converted]. + */ +fun interface PartialConverter { + /** Attempts to convert the [input] to a valid result. */ + fun maybeConvert(input: Any?): PartialConverterResult +} + +/** Output type of a [PartialConverter]. */ +sealed interface PartialConverterResult + +/** Returned by unsuccessful [PartialConverter] applications. */ +data object NoConversion : PartialConverterResult + +/** Returned by successful [PartialConverter] applications. */ +data class Converted(val output: Any?) : PartialConverterResult + +/** + * Utility [PartialConverter] for dealing with null values when these are valid. This cuts down on + * the boilerplate when defining subsequent [PartialConverter] implementations. + */ +object NullFallThrough : PartialConverter { + override fun maybeConvert(input: Any?): PartialConverterResult = + if (input == null) Converted(null) else NoConversion +} + +/** + * Utility [PartialConverter] for dealing with known default values. This cuts down on the + * boilerplate when defining subsequent [PartialConverter] implementations. + */ +internal data class DefaultFallThrough(val defaultValue: Any?) : PartialConverter { + override fun maybeConvert(input: Any?): PartialConverterResult = + if (input == null) Converted(defaultValue) else NoConversion +} + +/** + * Factory class for generating [CustomConverter.Converter] instances for debezium given a list of + * [PartialConverter]s. + */ +class ConverterFactory(val customConverterClass: Class>) { + private val log = KotlinLogging.logger {} + + /** Factory method for generating a [CustomConverter.Converter] for a [RelationalColumn]. */ + fun build( + column: RelationalColumn, + partialConverters: List + ): CustomConverter.Converter { + val noDefaultConverter = Converter(column, partialConverters, NoConversion) + if (column.isOptional || !column.hasDefaultValue()) { + log.info { + "Building custom converter for" + + " column '${column.dataCollection()}.${column.name()}'" + + " of type '${column.typeName()}'." + } + return noDefaultConverter + } + val unconvertedDefaultValue: Any? = column.defaultValue() + log.info { + "Computing converted default value for" + + " column '${column.dataCollection()}.${column.name()}'" + + " of type '${column.typeName()}'" + + " with unconverted default value '$unconvertedDefaultValue'." + } + val convertedDefaultValue: Any? = noDefaultConverter.convert(unconvertedDefaultValue) + log.info { + "Building custom converter for" + + " column '${column.dataCollection()}.${column.name()}'" + + " of type '${column.typeName()}'" + + " with default value '$convertedDefaultValue'." + } + return Converter(column, partialConverters, Converted(convertedDefaultValue)) + } + + /** Implementation of [CustomConverter.Converter] used by [ConverterFactory]. */ + internal inner class Converter( + private val convertedField: ConvertedField, + private val partialConverters: List, + private val defaultValue: PartialConverterResult, + ) : CustomConverter.Converter { + + private val loggingFlag = AtomicBoolean() + + override fun convert(input: Any?): Any? { + if (input == null && defaultValue is Converted) { + return defaultValue.output + } + var cause: Throwable? = null + for (converter in partialConverters) { + val result: PartialConverterResult + try { + result = converter.maybeConvert(input) + } catch (e: Throwable) { + cause = e + break + } + when (result) { + NoConversion -> Unit + is Converted -> return result.output + } + } + if (loggingFlag.compareAndSet(false, true)) { + log.warn(cause) { + "Converter $customConverterClass" + + " for field ${convertedField.dataCollection()}.${convertedField.name()}" + + " cannot handle value '$input' of type ${input?.javaClass}." + } + log.warn { "Future similar warnings from $customConverterClass will be silenced." } + } + return null + } + } +} diff --git a/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/RelationalColumnCustomConverter.kt b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/RelationalColumnCustomConverter.kt new file mode 100644 index 000000000000..ea2bec28a545 --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/extract-cdc/src/main/kotlin/io/airbyte/cdk/read/cdc/RelationalColumnCustomConverter.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.read.cdc + +import io.debezium.spi.converter.CustomConverter +import io.debezium.spi.converter.RelationalColumn +import java.util.Properties +import org.apache.kafka.connect.data.SchemaBuilder + +/** Used by Debezium to transform record values into their expected format. */ +interface RelationalColumnCustomConverter : CustomConverter { + + /** A nice name for use in Debezium properties. */ + val debeziumPropertiesKey: String + + /** Fall-through list of handlers to try to match and register for each column. */ + val handlers: List + + interface Handler { + /** Predicate to match the column by. */ + fun matches(column: RelationalColumn): Boolean + + /** Schema of the output values. */ + fun outputSchemaBuilder(): SchemaBuilder + + /** Partial conversion functions, applied in sequence until conversion occurs. */ + val partialConverters: List + } + + override fun configure(props: Properties?) {} + + override fun converterFor( + column: RelationalColumn?, + registration: CustomConverter.ConverterRegistration? + ) { + if (column == null || registration == null) { + return + } + val handler: Handler = handlers.find { it.matches(column) } ?: return + val converter: CustomConverter.Converter = + ConverterFactory(javaClass).build(column, handler.partialConverters) + registration.register(handler.outputSchemaBuilder(), converter) + } +} diff --git a/airbyte-cdk/bulk/toolkits/extract-cdc/src/test/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionReaderTest.kt b/airbyte-cdk/bulk/toolkits/extract-cdc/src/test/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionReaderTest.kt index 6f9d1da1b6e8..c9ded56997ba 100644 --- a/airbyte-cdk/bulk/toolkits/extract-cdc/src/test/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionReaderTest.kt +++ b/airbyte-cdk/bulk/toolkits/extract-cdc/src/test/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionReaderTest.kt @@ -25,6 +25,7 @@ import io.airbyte.cdk.discover.TestMetaFieldDecorator import io.airbyte.cdk.output.BufferingOutputConsumer import io.airbyte.cdk.read.ConcurrencyResource import io.airbyte.cdk.read.ConfiguredSyncMode +import io.airbyte.cdk.read.FieldValueChange import io.airbyte.cdk.read.Global import io.airbyte.cdk.read.PartitionReadCheckpoint import io.airbyte.cdk.read.PartitionReader @@ -169,13 +170,20 @@ sealed class CdcPartitionReaderTest, C : AutoCloseable>( val streamRecordConsumers: Map = mapOf( stream.id to - StreamRecordConsumer { recordData: ObjectNode, _ -> - outputConsumer.accept( - AirbyteRecordMessage() - .withStream(stream.name) - .withNamespace(stream.namespace) - .withData(recordData) - ) + object : StreamRecordConsumer { + override val stream: Stream = this@CdcPartitionReaderTest.stream + + override fun accept( + recordData: ObjectNode, + changes: Map? + ) { + outputConsumer.accept( + AirbyteRecordMessage() + .withStream(stream.name) + .withNamespace(stream.namespace) + .withData(recordData) + ) + } } ) val reader = @@ -245,6 +253,7 @@ sealed class CdcPartitionReaderTest, C : AutoCloseable>( override fun deserialize( key: DebeziumRecordKey, value: DebeziumRecordValue, + stream: Stream, ): DeserializedRecord { val id: Int = key.element("id").asInt() val after: Int? = value.after["v"]?.asInt() @@ -257,12 +266,17 @@ sealed class CdcPartitionReaderTest, C : AutoCloseable>( Update(id, after) } return DeserializedRecord( - streamID = stream.id, data = Jsons.valueToTree(record) as ObjectNode, changes = emptyMap(), ) } + override fun findStreamNamespace(key: DebeziumRecordKey, value: DebeziumRecordValue): String? = + stream.id.namespace + + override fun findStreamName(key: DebeziumRecordKey, value: DebeziumRecordValue): String? = + stream.id.name + override fun serialize(debeziumState: DebeziumState): OpaqueStateValue = Jsons.valueToTree( mapOf( @@ -666,7 +680,8 @@ class CdcPartitionReaderMongoTest : override fun deserialize( key: DebeziumRecordKey, - value: DebeziumRecordValue + value: DebeziumRecordValue, + stream: Stream, ): DeserializedRecord { val id: Int = key.element("id").asInt() val record: Record = @@ -691,7 +706,6 @@ class CdcPartitionReaderMongoTest : } } return DeserializedRecord( - streamID = stream.id, data = Jsons.valueToTree(record), changes = emptyMap(), ) diff --git a/airbyte-cdk/bulk/toolkits/extract-cdc/src/test/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionsCreatorTest.kt b/airbyte-cdk/bulk/toolkits/extract-cdc/src/test/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionsCreatorTest.kt index e339e92d84d7..d778aafc5a7d 100644 --- a/airbyte-cdk/bulk/toolkits/extract-cdc/src/test/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionsCreatorTest.kt +++ b/airbyte-cdk/bulk/toolkits/extract-cdc/src/test/kotlin/io/airbyte/cdk/read/cdc/CdcPartitionsCreatorTest.kt @@ -37,8 +37,6 @@ class CdcPartitionsCreatorTest { @MockK lateinit var concurrencyResource: ConcurrencyResource - @MockK(relaxUnitFun = true) lateinit var globalLockResource: CdcGlobalLockResource - @MockK lateinit var creatorOps: CdcPartitionsCreatorDebeziumOperations @MockK lateinit var readerOps: CdcPartitionReaderDebeziumOperations @@ -58,16 +56,17 @@ class CdcPartitionsCreatorTest { val global = Global(listOf(stream)) + val lowerBoundReference = AtomicReference(null) val upperBoundReference = AtomicReference(null) val creator: CdcPartitionsCreator get() = CdcPartitionsCreator( concurrencyResource, - globalLockResource, globalFeedBootstrap, creatorOps, readerOps, + lowerBoundReference, upperBoundReference, ) diff --git a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/discover/JdbcAirbyteStreamFactory.kt b/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/discover/JdbcAirbyteStreamFactory.kt index 6c52a13b2fe9..f702d3b506d9 100644 --- a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/discover/JdbcAirbyteStreamFactory.kt +++ b/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/discover/JdbcAirbyteStreamFactory.kt @@ -1,7 +1,6 @@ /* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ package io.airbyte.cdk.discover -import io.airbyte.cdk.jdbc.BinaryStreamFieldType import io.airbyte.cdk.jdbc.BooleanFieldType import io.airbyte.cdk.jdbc.CharacterStreamFieldType import io.airbyte.cdk.jdbc.ClobFieldType @@ -75,7 +74,6 @@ interface JdbcAirbyteStreamFactory : AirbyteStreamFactory, MetaFieldDecorator { fun isPossiblePrimaryKeyElement(field: Field): Boolean = when (field.type) { !is LosslessFieldType -> false - BinaryStreamFieldType, CharacterStreamFieldType, NCharacterStreamFieldType, ClobFieldType, diff --git a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/jdbc/converters/DataTypeUtils.kt b/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/jdbc/converters/DataTypeUtils.kt deleted file mode 100644 index 2bb7ab4c4f2c..000000000000 --- a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/jdbc/converters/DataTypeUtils.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ -package io.airbyte.cdk.jdbc.converters - -import java.time.* -import java.time.format.DateTimeFormatter - -/** - * TODO : Replace all the DateTime related logic of this class with - * [io.airbyte.cdk.db.jdbc.DateTimeConverter] - */ -object DataTypeUtils { - val TIME_FORMATTER: DateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSSSSS") - val TIMESTAMP_FORMATTER: DateTimeFormatter = - DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS") - val TIMETZ_FORMATTER: DateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSSSSSXXX") - val TIMESTAMPTZ_FORMATTER: DateTimeFormatter = - DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXX") - val DATE_FORMATTER: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") -} diff --git a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/jdbc/converters/DateTimeConverter.kt b/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/jdbc/converters/DateTimeConverter.kt deleted file mode 100644 index 04eed03be47e..000000000000 --- a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/jdbc/converters/DateTimeConverter.kt +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ -package io.airbyte.cdk.jdbc.converters - -import io.github.oshai.kotlinlogging.KotlinLogging -import java.sql.* -import java.time.* -import java.time.chrono.IsoEra -import java.time.format.DateTimeFormatter -import java.util.concurrent.* -import kotlin.math.abs -import kotlin.math.min - -private val LOGGER = KotlinLogging.logger {} - -object DateTimeConverter { - private val ONE_CE: Date = Date.valueOf("0001-01-01") - val TIME_WITH_TIMEZONE_FORMATTER: DateTimeFormatter = - DateTimeFormatter.ofPattern( - "HH:mm:ss[.][SSSSSSSSS][SSSSSSS][SSSSSS][SSSSS][SSSS][SSS][SS][S][''][XXX][XX][X]" - ) - private var loggedUnknownTimeWithTimeZoneClass = false - private var loggedUnknownTimeClass = false - private var loggedUnknownTimestampWithTimeZoneClass = false - private var loggedUnknownTimestampClass = false - private var loggedUnknownDateClass = false - - @JvmStatic - fun convertToTimeWithTimezone(time: Any): String { - if (time is OffsetTime) { - return if (hasZeroSecondsAndNanos(time.toLocalTime())) - time.format(DataTypeUtils.TIMETZ_FORMATTER) - else time.toString() - } else { - if (!loggedUnknownTimeWithTimeZoneClass) { - LOGGER.info { "Unknown class for Time with timezone data type ${time.javaClass}" } - loggedUnknownTimeWithTimeZoneClass = true - } - val timetz = OffsetTime.parse(time.toString(), TIME_WITH_TIMEZONE_FORMATTER) - return if (hasZeroSecondsAndNanos(timetz.toLocalTime())) - timetz.format(DataTypeUtils.TIMETZ_FORMATTER) - else timetz.toString() - } - } - - @JvmStatic - fun convertToTimestampWithTimezone(timestamp: Any): String { - if (timestamp is Timestamp) { - // In snapshot mode, debezium produces a java.sql.Timestamp object for the TIMESTAMPTZ - // type. - // Conceptually, a timestamp with timezone is an Instant. But t.toInstant() actually - // mangles the - // value for ancient dates, because leap years weren't applied consistently in ye olden - // days. - // Additionally, toInstant() (and toLocalDateTime()) actually lose the era indicator, so - // we can't - // rely on their getEra() methods. - // So we have special handling for this case, which sidesteps the toInstant conversion. - val timestamptz: ZonedDateTime = timestamp.toLocalDateTime().atZone(ZoneOffset.UTC) - val value = timestamptz.format(DataTypeUtils.TIMESTAMPTZ_FORMATTER) - return resolveEra(timestamp, value) - } else if (timestamp is OffsetDateTime) { - return resolveEra( - timestamp.toLocalDate(), - timestamp.format(DataTypeUtils.TIMESTAMPTZ_FORMATTER) - ) - } else if (timestamp is ZonedDateTime) { - return resolveEra( - timestamp.toLocalDate(), - timestamp.format(DataTypeUtils.TIMESTAMPTZ_FORMATTER) - ) - } else if (timestamp is Instant) { - val offsetDateTime = OffsetDateTime.ofInstant(timestamp, ZoneOffset.UTC) - val timestamptz = ZonedDateTime.from(offsetDateTime) - val localDate = timestamptz.toLocalDate() - val value = timestamptz.format(DataTypeUtils.TIMESTAMPTZ_FORMATTER) - return resolveEra(localDate, value) - } else { - if (!loggedUnknownTimestampWithTimeZoneClass) { - LOGGER.info { - "Unknown class for Timestamp with time zone data type ${timestamp.javaClass}" - } - loggedUnknownTimestampWithTimeZoneClass = true - } - val instant = Instant.parse(timestamp.toString()) - val offsetDateTime = OffsetDateTime.ofInstant(instant, ZoneOffset.UTC) - val timestamptz = ZonedDateTime.from(offsetDateTime) - val localDate = timestamptz.toLocalDate() - val value = timestamptz.format(DataTypeUtils.TIMESTAMPTZ_FORMATTER) - return resolveEra(localDate, value) - } - } - - /** See [.convertToTimestampWithTimezone] for explanation of the weird things happening here. */ - @JvmStatic - fun convertToTimestamp(timestamp: Any): String { - if (timestamp is Timestamp) { - // Snapshot mode - val localDateTime: LocalDateTime = timestamp.toLocalDateTime() - return resolveEra( - timestamp, - if (hasZeroSecondsAndNanos(localDateTime.toLocalTime())) - localDateTime.format(DataTypeUtils.TIMESTAMP_FORMATTER) - else localDateTime.toString() - ) - } else if (timestamp is Instant) { - // Incremental mode - return resolveEra( - timestamp.atZone(ZoneOffset.UTC).toLocalDate(), - timestamp - .atOffset(ZoneOffset.UTC) - .toLocalDateTime() - .format(DataTypeUtils.TIMESTAMP_FORMATTER) - ) - } else if (timestamp is LocalDateTime) { - val date: LocalDate = timestamp.toLocalDate() - return resolveEra( - date, - if (hasZeroSecondsAndNanos(timestamp.toLocalTime())) - timestamp.format(DataTypeUtils.TIMESTAMP_FORMATTER) - else timestamp.toString() - ) - } else { - if (!loggedUnknownTimestampClass) { - LOGGER.info { "Unknown class for Timestamp data type ${timestamp.javaClass}" } - loggedUnknownTimestampClass = true - } - val localDateTime = LocalDateTime.parse(timestamp.toString()) - val date = localDateTime.toLocalDate() - return resolveEra( - date, - if (hasZeroSecondsAndNanos(localDateTime.toLocalTime())) - localDateTime.format(DataTypeUtils.TIMESTAMP_FORMATTER) - else localDateTime.toString() - ) - } - } - - /** See [.convertToTimestampWithTimezone] for explanation of the weird things happening here. */ - @JvmStatic - fun convertToDate(date: Any): String { - if (date is Date) { - // Snapshot mode - val localDate = date.toLocalDate() - return resolveEra(date, localDate.format(DataTypeUtils.DATE_FORMATTER)) - } else if (date is LocalDate) { - // Incremental mode - return resolveEra(date, date.format(DataTypeUtils.DATE_FORMATTER)) - } else if (date is Int) { - // Incremental mode - return LocalDate.ofEpochDay(date.toLong()).format(DataTypeUtils.DATE_FORMATTER) - } else { - if (!loggedUnknownDateClass) { - LOGGER.info { "Unknown class for Date data type${date.javaClass}" } - loggedUnknownDateClass = true - } - val localDate = LocalDate.parse(date.toString()) - return resolveEra(localDate, localDate.format(DataTypeUtils.DATE_FORMATTER)) - } - } - - @JvmStatic - fun convertToTime(time: Any): String { - if (time is Time) { - return formatTime(time.toLocalTime()) - } else if (time is LocalTime) { - return formatTime(time) - } else if (time is Duration) { - val value = time.toNanos() - if (value >= 0 && value < TimeUnit.DAYS.toNanos(1)) { - return formatTime(LocalTime.ofNanoOfDay(value)) - } else { - val updatedValue = - min(abs(value.toDouble()), LocalTime.MAX.toNanoOfDay().toDouble()).toLong() - LOGGER.debug { - "Time values must use number of nanoseconds greater than 0 and less than 86400000000000 but its $value, converting to $updatedValue " - } - return formatTime(LocalTime.ofNanoOfDay(updatedValue)) - } - } else { - if (!loggedUnknownTimeClass) { - LOGGER.info { "Unknown class for Time data type ${time.javaClass}" } - loggedUnknownTimeClass = true - } - - val valueAsString = time.toString() - if (valueAsString.startsWith("24")) { - LOGGER.debug { - "Time value ${valueAsString} is above range, converting to 23:59:59" - } - return LocalTime.MAX.toString() - } - return formatTime(LocalTime.parse(valueAsString)) - } - } - - @JvmStatic - private fun formatTime(localTime: LocalTime): String { - return if (hasZeroSecondsAndNanos(localTime)) localTime.format(DataTypeUtils.TIME_FORMATTER) - else localTime.toString() - } - - @JvmStatic - fun hasZeroSecondsAndNanos(localTime: LocalTime): Boolean { - return (localTime.second == 0 && localTime.nano == 0) - } - - /** - * Modifies a string representation of a date/timestamp and normalizes its era indicator. - * Specifically, if this is a BCE value: - * - * * The leading negative sign will be removed if present - * * The "BC" suffix will be appended, if not already present - * - * You most likely would prefer to call one of the overloaded methods, which accept temporal - * types. - */ - fun resolveEra(isBce: Boolean, value: String): String { - var mangledValue = value - if (isBce) { - if (mangledValue.startsWith("-")) { - mangledValue = mangledValue.substring(1) - } - if (!mangledValue.endsWith(" BC")) { - mangledValue += " BC" - } - } - return mangledValue - } - - fun isBce(date: LocalDate): Boolean { - return date.era == IsoEra.BCE - } - - @JvmStatic - fun resolveEra(date: LocalDate, value: String): String { - return resolveEra(isBce(date), value) - } - - /** - * java.sql.Date objects don't properly represent their era (for example, using toLocalDate() - * always returns an object in CE). So to determine the era, we just check whether the date is - * before 1 AD. - * - * This is technically kind of sketchy due to ancient timestamps being weird (leap years, etc.), - * but my understanding is that [.ONE_CE] has the same weirdness, so it cancels out. - */ - @JvmStatic - fun resolveEra(date: Date, value: String): String { - return resolveEra(date.before(ONE_CE), value) - } - - /** See [.resolveEra] for explanation. */ - @JvmStatic - fun resolveEra(timestamp: Timestamp, value: String): String { - return resolveEra(timestamp.before(ONE_CE), value) - } -} diff --git a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/read/DefaultJdbcSharedState.kt b/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/read/DefaultJdbcSharedState.kt index e9db8dde1358..703d991ceb2f 100644 --- a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/read/DefaultJdbcSharedState.kt +++ b/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/read/DefaultJdbcSharedState.kt @@ -16,7 +16,6 @@ class DefaultJdbcSharedState( override val selectQuerier: SelectQuerier, val constants: DefaultJdbcConstants, internal val concurrencyResource: ConcurrencyResource, - private val globalLockResource: GlobalLockResource, ) : JdbcSharedState { // First hit to the readStartTime initializes the value. @@ -51,32 +50,14 @@ class DefaultJdbcSharedState( ) override fun tryAcquireResourcesForCreator(): JdbcPartitionsCreator.AcquiredResources? { - val acquiredLock: GlobalLockResource.AcquiredGlobalLock = - globalLockResource.tryAcquire() ?: return null val acquiredThread: ConcurrencyResource.AcquiredThread = - concurrencyResource.tryAcquire() - ?: run { - acquiredLock.close() - return null - } - return JdbcPartitionsCreator.AcquiredResources { - acquiredThread.close() - acquiredLock.close() - } + concurrencyResource.tryAcquire() ?: return null + return JdbcPartitionsCreator.AcquiredResources { acquiredThread.close() } } override fun tryAcquireResourcesForReader(): JdbcPartitionReader.AcquiredResources? { - val acquiredLock: GlobalLockResource.AcquiredGlobalLock = - globalLockResource.tryAcquire() ?: return null val acquiredThread: ConcurrencyResource.AcquiredThread = - concurrencyResource.tryAcquire() - ?: run { - acquiredLock.close() - return null - } - return JdbcPartitionReader.AcquiredResources { - acquiredThread.close() - acquiredLock.close() - } + concurrencyResource.tryAcquire() ?: return null + return JdbcPartitionReader.AcquiredResources { acquiredThread.close() } } } diff --git a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/read/JdbcPartitionReader.kt b/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/read/JdbcPartitionReader.kt index e5e05a1e2569..606f66f5e568 100644 --- a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/read/JdbcPartitionReader.kt +++ b/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/read/JdbcPartitionReader.kt @@ -36,8 +36,8 @@ sealed class JdbcPartitionReader

>( return PartitionReader.TryAcquireResourcesStatus.READY_TO_RUN } - fun out(record: ObjectNode) { - streamRecordConsumer.accept(record, changes = null) + fun out(row: SelectQuerier.ResultRow) { + streamRecordConsumer.accept(row.data, row.changes) } override fun releaseResources() { @@ -79,8 +79,8 @@ class JdbcNonResumablePartitionReader

>( ), ) .use { result: SelectQuerier.Result -> - for (record in result) { - out(record) + for (row in result) { + out(row) numRecords.incrementAndGet() } } @@ -126,9 +126,9 @@ class JdbcResumablePartitionReader

>( SelectQuerier.Parameters(reuseResultObject = true, fetchSize = fetchSize), ) .use { result: SelectQuerier.Result -> - for (record in result) { - out(record) - lastRecord.set(record) + for (row in result) { + out(row) + lastRecord.set(row.data) // Check activity periodically to handle timeout. if (numRecords.incrementAndGet() % fetchSize == 0L) { coroutineContext.ensureActive() diff --git a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/read/JdbcPartitionsCreator.kt b/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/read/JdbcPartitionsCreator.kt index 91d9a143d460..b95eaf015a95 100644 --- a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/read/JdbcPartitionsCreator.kt +++ b/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/read/JdbcPartitionsCreator.kt @@ -29,6 +29,20 @@ sealed class JdbcPartitionsCreator< private val acquiredResources = AtomicReference() + // A reader that only checkpoints the complete state of a partition + // used for empty tables + inner class CheckpointOnlyPartitionReader() : PartitionReader { + override fun tryAcquireResources(): PartitionReader.TryAcquireResourcesStatus = + PartitionReader.TryAcquireResourcesStatus.READY_TO_RUN + + override suspend fun run() {} + + override fun checkpoint(): PartitionReadCheckpoint = + PartitionReadCheckpoint(partition.completeState, 0) + + override fun releaseResources() {} + } + /** Calling [close] releases the resources acquired for the [JdbcPartitionsCreator]. */ fun interface AcquiredResources : AutoCloseable @@ -53,7 +67,7 @@ sealed class JdbcPartitionsCreator< log.info { "Querying maximum cursor column value." } val record: ObjectNode? = selectQuerier.executeQuery(cursorUpperBoundQuery).use { - if (it.hasNext()) it.next() else null + if (it.hasNext()) it.next().data else null } if (record == null) { streamState.cursorUpperBound = Jsons.nullNode() @@ -88,8 +102,8 @@ sealed class JdbcPartitionsCreator< values.clear() val samplingQuery: SelectQuery = partition.samplingQuery(sampleRateInvPow2) selectQuerier.executeQuery(samplingQuery).use { - for (record in it) { - values.add(recordMapper(record)) + for (row in it) { + values.add(recordMapper(row.data)) } } if (values.size < sharedState.maxSampleSize) { @@ -126,9 +140,11 @@ class JdbcSequentialPartitionsCreator< // Ensure that the cursor upper bound is known, if required. if (partition is JdbcCursorPartition<*>) { ensureCursorUpperBound() - if (streamState.cursorUpperBound?.isNull == true) { + if ( + streamState.cursorUpperBound == null || streamState.cursorUpperBound?.isNull == true + ) { log.info { "Maximum cursor column value query found that the table was empty." } - return listOf() + return listOf(CheckpointOnlyPartitionReader()) } } if (streamState.fetchSize == null) { @@ -140,7 +156,9 @@ class JdbcSequentialPartitionsCreator< log.info { "Table memory size estimated at ${expectedTableByteSize shr 20} MiB." } if (rowByteSizeSample.kind == Sample.Kind.EMPTY) { log.info { "Sampling query found that the table was empty." } - return listOf() + // An empty table will checkpoint once in order to emit its complete state + // Otherwise on each sync we would try to read this partition + return listOf(CheckpointOnlyPartitionReader()) } streamState.fetchSize = sharedState.jdbcFetchSizeEstimator().apply(rowByteSizeSample) @@ -176,9 +194,11 @@ class JdbcConcurrentPartitionsCreator< // Ensure that the cursor upper bound is known, if required. if (partition is JdbcCursorPartition<*>) { ensureCursorUpperBound() - if (streamState.cursorUpperBound?.isNull == true) { + if ( + streamState.cursorUpperBound == null || streamState.cursorUpperBound?.isNull == true + ) { log.info { "Maximum cursor column value query found that the table was empty." } - return listOf() + return listOf(CheckpointOnlyPartitionReader()) } } // Handle edge case where the table can't be sampled. @@ -198,7 +218,7 @@ class JdbcConcurrentPartitionsCreator< } if (sample.kind == Sample.Kind.EMPTY) { log.info { "Sampling query found that the table was empty." } - return listOf() + return listOf(CheckpointOnlyPartitionReader()) } val rowByteSizeSample: Sample = sample.map { (_, rowByteSize: Long) -> rowByteSize } streamState.fetchSize = sharedState.jdbcFetchSizeEstimator().apply(rowByteSizeSample) diff --git a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/read/SelectQuerier.kt b/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/read/SelectQuerier.kt index caa44bf22f47..c5bf58dda78d 100644 --- a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/read/SelectQuerier.kt +++ b/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/read/SelectQuerier.kt @@ -3,6 +3,7 @@ package io.airbyte.cdk.read import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.node.ObjectNode +import io.airbyte.cdk.discover.Field import io.airbyte.cdk.jdbc.JdbcConnectionFactory import io.airbyte.cdk.jdbc.JdbcFieldType import io.airbyte.cdk.util.Jsons @@ -22,12 +23,24 @@ interface SelectQuerier { data class Parameters( /** When set, the [ObjectNode] in the [Result] is reused; take care with this! */ - val reuseResultObject: Boolean = false, - /** JDBC fetchSize value. */ - val fetchSize: Int? = null, - ) + val reuseResultObject: Boolean, + /** JDBC [PreparedStatement] fetchSize value. */ + val statementFetchSize: Int?, + /** JDBC [ResultSet] fetchSize value. */ + val resultSetFetchSize: Int?, + ) { + constructor( + reuseResultObject: Boolean = false, + fetchSize: Int? = null + ) : this(reuseResultObject, fetchSize, fetchSize) + } + + interface Result : Iterator, AutoCloseable - interface Result : Iterator, AutoCloseable + interface ResultRow { + val data: ObjectNode + val changes: Map + } } /** Default implementation of [SelectQuerier]. */ @@ -38,35 +51,29 @@ class JdbcSelectQuerier( override fun executeQuery( q: SelectQuery, parameters: SelectQuerier.Parameters, - ): SelectQuerier.Result = Result(q, parameters) + ): SelectQuerier.Result = Result(jdbcConnectionFactory, q, parameters) + + data class ResultRow( + override var data: ObjectNode = Jsons.objectNode(), + override var changes: MutableMap = mutableMapOf(), + ) : SelectQuerier.ResultRow - private inner class Result( + class Result( + val jdbcConnectionFactory: JdbcConnectionFactory, val q: SelectQuery, - parameters: SelectQuerier.Parameters, + val parameters: SelectQuerier.Parameters, ) : SelectQuerier.Result { private val log = KotlinLogging.logger {} var conn: Connection? = null var stmt: PreparedStatement? = null var rs: ResultSet? = null - val reusable: ObjectNode? = Jsons.objectNode().takeIf { parameters.reuseResultObject } + val reusable: ResultRow? = ResultRow().takeIf { parameters.reuseResultObject } init { log.info { "Querying ${q.sql}" } try { - conn = jdbcConnectionFactory.get() - stmt = conn!!.prepareStatement(q.sql) - parameters.fetchSize?.let { fetchSize: Int -> - log.info { "Setting fetchSize to $fetchSize." } - stmt!!.fetchSize = fetchSize - } - var paramIdx = 1 - for (binding in q.bindings) { - log.info { "Setting parameter #$paramIdx to $binding." } - binding.type.set(stmt!!, paramIdx, binding.value) - paramIdx++ - } - rs = stmt!!.executeQuery() + initQueryExecution() } catch (e: Throwable) { close() throw e @@ -76,6 +83,28 @@ class JdbcSelectQuerier( var isReady = false var hasNext = false var hasLoggedResultsReceived = false + var hasLoggedException = false + + /** Initializes a connection and readies the resultset. */ + fun initQueryExecution() { + conn = jdbcConnectionFactory.get() + stmt = conn!!.prepareStatement(q.sql) + parameters.statementFetchSize?.let { fetchSize: Int -> + log.info { "Setting Statement fetchSize to $fetchSize." } + stmt!!.fetchSize = fetchSize + } + var paramIdx = 1 + for (binding in q.bindings) { + log.info { "Setting parameter #$paramIdx to $binding." } + binding.type.set(stmt!!, paramIdx, binding.value) + paramIdx++ + } + rs = stmt!!.executeQuery() + parameters.resultSetFetchSize?.let { fetchSize: Int -> + log.info { "Setting ResultSet fetchSize to $fetchSize." } + rs!!.fetchSize = fetchSize + } + } override fun hasNext(): Boolean { // hasNext() is idempotent @@ -93,22 +122,34 @@ class JdbcSelectQuerier( return hasNext } - override fun next(): ObjectNode { + override fun next(): SelectQuerier.ResultRow { // Ensure that the current row in the ResultSet hasn't been read yet; advance if // necessary. if (!hasNext()) throw NoSuchElementException() // Read the current row in the ResultSet - val record: ObjectNode = reusable ?: Jsons.objectNode() + val resultRow: ResultRow = reusable ?: ResultRow() + resultRow.changes.clear() var colIdx = 1 for (column in q.columns) { log.debug { "Getting value #$colIdx for $column." } val jdbcFieldType: JdbcFieldType<*> = column.type as JdbcFieldType<*> - record.set(column.id, jdbcFieldType.get(rs!!, colIdx)) + try { + resultRow.data.set(column.id, jdbcFieldType.get(rs!!, colIdx)) + } catch (e: Exception) { + resultRow.data.set(column.id, Jsons.nullNode()) + if (!hasLoggedException) { + log.warn(e) { "Error deserializing value in column $column." } + hasLoggedException = true + } else { + log.debug(e) { "Error deserializing value in column $column." } + } + resultRow.changes.set(column, FieldValueChange.RETRIEVAL_FAILURE_TOTAL) + } colIdx++ } // Flag that the current row has been read before returning. isReady = false - return record + return resultRow } override fun close() { diff --git a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/test/kotlin/io/airbyte/cdk/read/JdbcSelectQuerierTest.kt b/airbyte-cdk/bulk/toolkits/extract-jdbc/src/test/kotlin/io/airbyte/cdk/read/JdbcSelectQuerierTest.kt index dee03df81681..6ea0fb4a67b4 100644 --- a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/test/kotlin/io/airbyte/cdk/read/JdbcSelectQuerierTest.kt +++ b/airbyte-cdk/bulk/toolkits/extract-jdbc/src/test/kotlin/io/airbyte/cdk/read/JdbcSelectQuerierTest.kt @@ -89,18 +89,19 @@ class JdbcSelectQuerierTest { val querier: SelectQuerier = JdbcSelectQuerier(JdbcConnectionFactory(config)) // Vanilla query val expected: List = expectedJson.map(Jsons::readTree) - val actual: List = querier.executeQuery(q).use { it.asSequence().toList() } + val actual: List = + querier.executeQuery(q).use { it.asSequence().toList().map { it.data } } Assertions.assertIterableEquals(expected, actual) // Query with reuseResultObject = true querier.executeQuery(q, SelectQuerier.Parameters(reuseResultObject = true)).use { var i = 0 var previous: ObjectNode? = null - for (record in it) { + for (row in it) { if (i > 0) { - Assertions.assertTrue(previous === record) + Assertions.assertTrue(previous === row.data) } - Assertions.assertEquals(expected[i++], record) - previous = record + Assertions.assertEquals(expected[i++], row.data) + previous = row.data } } } diff --git a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/test/kotlin/io/airbyte/cdk/read/TestFixtures.kt b/airbyte-cdk/bulk/toolkits/extract-jdbc/src/test/kotlin/io/airbyte/cdk/read/TestFixtures.kt index cd29b4321743..6db035983750 100644 --- a/airbyte-cdk/bulk/toolkits/extract-jdbc/src/test/kotlin/io/airbyte/cdk/read/TestFixtures.kt +++ b/airbyte-cdk/bulk/toolkits/extract-jdbc/src/test/kotlin/io/airbyte/cdk/read/TestFixtures.kt @@ -93,7 +93,6 @@ object TestFixtures { MockSelectQuerier(ArrayDeque(mockedQueries.toList())), constants.copy(maxMemoryBytesForTesting = maxMemoryBytesForTesting), ConcurrencyResource(configuration), - NoOpGlobalLockResource() ) } @@ -160,7 +159,11 @@ object TestFixtures { return object : SelectQuerier.Result { val wrapped: Iterator = mockedQuery.results.iterator() override fun hasNext(): Boolean = wrapped.hasNext() - override fun next(): ObjectNode = wrapped.next() + override fun next(): SelectQuerier.ResultRow = + object : SelectQuerier.ResultRow { + override val data: ObjectNode = wrapped.next() + override val changes: Map = emptyMap() + } override fun close() {} } } @@ -190,6 +193,9 @@ object TestFixtures { object MockStateQuerier : StateQuerier { override val feeds: List = listOf() override fun current(feed: Feed): OpaqueStateValue? = null + override fun resetFeedStates() { + // no-op + } } object MockMetaFieldDecorator : MetaFieldDecorator { @@ -212,6 +218,9 @@ object TestFixtures { object : StateQuerier { override val feeds: List = listOf(this@bootstrap) override fun current(feed: Feed): OpaqueStateValue? = opaqueStateValue + override fun resetFeedStates() { + // no-op + } }, stream = this ) diff --git a/airbyte-cdk/bulk/toolkits/load-avro/src/main/kotlin/io/airbyte/cdk/load/data/avro/AirbyteTypeToAvroSchema.kt b/airbyte-cdk/bulk/toolkits/load-avro/src/main/kotlin/io/airbyte/cdk/load/data/avro/AirbyteTypeToAvroSchema.kt index a4c8797db572..a129d3c5cf66 100644 --- a/airbyte-cdk/bulk/toolkits/load-avro/src/main/kotlin/io/airbyte/cdk/load/data/avro/AirbyteTypeToAvroSchema.kt +++ b/airbyte-cdk/bulk/toolkits/load-avro/src/main/kotlin/io/airbyte/cdk/load/data/avro/AirbyteTypeToAvroSchema.kt @@ -10,8 +10,8 @@ import io.airbyte.cdk.load.data.ArrayType import io.airbyte.cdk.load.data.ArrayTypeWithoutSchema import io.airbyte.cdk.load.data.BooleanType import io.airbyte.cdk.load.data.DateType +import io.airbyte.cdk.load.data.FieldType import io.airbyte.cdk.load.data.IntegerType -import io.airbyte.cdk.load.data.NullType import io.airbyte.cdk.load.data.NumberType import io.airbyte.cdk.load.data.ObjectType import io.airbyte.cdk.load.data.ObjectTypeWithEmptySchema @@ -21,6 +21,7 @@ import io.airbyte.cdk.load.data.TimeTypeWithTimezone import io.airbyte.cdk.load.data.TimeTypeWithoutTimezone import io.airbyte.cdk.load.data.TimestampTypeWithTimezone import io.airbyte.cdk.load.data.TimestampTypeWithoutTimezone +import io.airbyte.cdk.load.data.Transformations import io.airbyte.cdk.load.data.UnionType import io.airbyte.cdk.load.data.UnknownType import org.apache.avro.LogicalTypes @@ -29,52 +30,82 @@ import org.apache.avro.SchemaBuilder class AirbyteTypeToAvroSchema { fun convert(airbyteSchema: AirbyteType, path: List): Schema { - return when (airbyteSchema) { - is ObjectType -> { - val name = path.last() - val namespace = path.take(path.size - 1).reversed().joinToString(".") - val builder = SchemaBuilder.record(name).namespace(namespace).fields() - airbyteSchema.properties.entries - .fold(builder) { acc, (name, field) -> - // NOTE: We will not support nullable at this stage. - // All nullables should have been converted to union[this, null] upstream - // TODO: Enforce this - acc.name(name).type(convert(field.type, path + name)).noDefault() - } - .endRecord() - } - is ArrayType -> { - SchemaBuilder.array().items(convert(airbyteSchema.items.type, path + "items")) - } - is ArrayTypeWithoutSchema -> - throw IllegalArgumentException("Array type without schema is not supported") - is BooleanType -> SchemaBuilder.builder().booleanType() - is DateType -> { - val schema = SchemaBuilder.builder().intType() - LogicalTypes.date().addToSchema(schema) - } - is IntegerType -> SchemaBuilder.builder().longType() - is NullType -> SchemaBuilder.builder().nullType() - is NumberType -> SchemaBuilder.builder().doubleType() - is ObjectTypeWithEmptySchema -> - throw IllegalArgumentException("Object type with empty schema is not supported") - is ObjectTypeWithoutSchema -> - throw IllegalArgumentException("Object type without schema is not supported") - is StringType -> SchemaBuilder.builder().stringType() - is TimeTypeWithTimezone, - is TimeTypeWithoutTimezone -> { - val schema = SchemaBuilder.builder().longType() - LogicalTypes.timeMicros().addToSchema(schema) - } - is TimestampTypeWithTimezone, - is TimestampTypeWithoutTimezone -> { - val schema = SchemaBuilder.builder().longType() - LogicalTypes.timestampMicros().addToSchema(schema) + return try { + when (airbyteSchema) { + is ObjectType -> { + val recordName = Transformations.toAvroSafeName(path.last()) + val recordNamespace = path.take(path.size - 1).reversed().joinToString(".") + val namespaceMangled = Transformations.toAvroSafeNamespace(recordNamespace) + val builder = + SchemaBuilder.record(recordName).namespace(namespaceMangled).fields() + airbyteSchema.properties.entries + .fold(builder) { acc, (name, field) -> + val converted = convert(field.type, path + name) + val propertySchema = maybeMakeNullable(field, converted) + val nameMangled = Transformations.toAvroSafeName(name) + acc.name(nameMangled).type(propertySchema).let { + if (field.nullable) { + it.withDefault(null) + } else { + it.noDefault() + } + } + } + .endRecord() + } + is ArrayType -> { + val converted = convert(airbyteSchema.items.type, path + "items") + val itemsSchema = maybeMakeNullable(airbyteSchema.items, converted) + SchemaBuilder.array().items(itemsSchema) + } + is BooleanType -> SchemaBuilder.builder().booleanType() + is IntegerType -> SchemaBuilder.builder().longType() + is NumberType -> SchemaBuilder.builder().doubleType() + is StringType -> SchemaBuilder.builder().stringType() + + // HACK: After upstream validation, UnknownType is sentinel for NullType + is UnknownType -> SchemaBuilder.builder().nullType() + is ObjectTypeWithEmptySchema, + is ObjectTypeWithoutSchema, + is ArrayTypeWithoutSchema -> SchemaBuilder.builder().stringType() + is DateType -> { + val schema = SchemaBuilder.builder().intType() + LogicalTypes.date().addToSchema(schema) + } + is TimeTypeWithTimezone, + is TimeTypeWithoutTimezone -> { + val schema = SchemaBuilder.builder().longType() + LogicalTypes.timeMicros().addToSchema(schema) + } + is TimestampTypeWithTimezone, + is TimestampTypeWithoutTimezone -> { + val schema = SchemaBuilder.builder().longType() + LogicalTypes.timestampMicros().addToSchema(schema) + } + is UnionType -> Schema.createUnion(airbyteSchema.options.map { convert(it, path) }) } - is UnionType -> Schema.createUnion(airbyteSchema.options.map { convert(it, path) }) - is UnknownType -> throw IllegalArgumentException("Unknown type: ${airbyteSchema.what}") + } catch (e: Exception) { + throw IllegalArgumentException("Failed to convert $airbyteSchema at $path", e) } } + + private fun maybeMakeNullable( + airbyteSchema: FieldType, + avroSchema: Schema, + ): Schema = + if (airbyteSchema.nullable && avroSchema.type != Schema.Type.UNION) { + if (avroSchema.type == Schema.Type.NULL) { + avroSchema + } else { + SchemaBuilder.unionOf().nullType().and().type(avroSchema).endUnion() + } + } else if (airbyteSchema.nullable && avroSchema.type == Schema.Type.UNION) { + avroSchema.types + .fold(SchemaBuilder.unionOf().nullType()) { acc, type -> acc.and().type(type) } + .endUnion() + } else { + avroSchema + } } fun ObjectType.toAvroSchema(stream: DestinationStream.Descriptor): Schema { diff --git a/airbyte-cdk/bulk/toolkits/load-avro/src/main/kotlin/io/airbyte/cdk/load/data/avro/AirbyteValueToAvroRecord.kt b/airbyte-cdk/bulk/toolkits/load-avro/src/main/kotlin/io/airbyte/cdk/load/data/avro/AirbyteValueToAvroRecord.kt index cb01f592f90a..a89697d93703 100644 --- a/airbyte-cdk/bulk/toolkits/load-avro/src/main/kotlin/io/airbyte/cdk/load/data/avro/AirbyteValueToAvroRecord.kt +++ b/airbyte-cdk/bulk/toolkits/load-avro/src/main/kotlin/io/airbyte/cdk/load/data/avro/AirbyteValueToAvroRecord.kt @@ -4,57 +4,143 @@ package io.airbyte.cdk.load.data.avro +import io.airbyte.cdk.load.data.AirbyteType import io.airbyte.cdk.load.data.AirbyteValue +import io.airbyte.cdk.load.data.ArrayType +import io.airbyte.cdk.load.data.ArrayTypeWithoutSchema import io.airbyte.cdk.load.data.ArrayValue +import io.airbyte.cdk.load.data.BooleanType import io.airbyte.cdk.load.data.BooleanValue -import io.airbyte.cdk.load.data.DateValue -import io.airbyte.cdk.load.data.IntValue +import io.airbyte.cdk.load.data.DateType +import io.airbyte.cdk.load.data.IntegerType import io.airbyte.cdk.load.data.IntegerValue import io.airbyte.cdk.load.data.NullValue +import io.airbyte.cdk.load.data.NumberType import io.airbyte.cdk.load.data.NumberValue +import io.airbyte.cdk.load.data.ObjectType +import io.airbyte.cdk.load.data.ObjectTypeWithEmptySchema +import io.airbyte.cdk.load.data.ObjectTypeWithoutSchema import io.airbyte.cdk.load.data.ObjectValue +import io.airbyte.cdk.load.data.StringType import io.airbyte.cdk.load.data.StringValue -import io.airbyte.cdk.load.data.TimeValue -import io.airbyte.cdk.load.data.TimestampValue -import io.airbyte.cdk.load.data.UnknownValue +import io.airbyte.cdk.load.data.TimeTypeWithTimezone +import io.airbyte.cdk.load.data.TimeTypeWithoutTimezone +import io.airbyte.cdk.load.data.TimestampTypeWithTimezone +import io.airbyte.cdk.load.data.TimestampTypeWithoutTimezone +import io.airbyte.cdk.load.data.Transformations +import io.airbyte.cdk.load.data.UnionType +import io.airbyte.cdk.load.data.UnknownType import org.apache.avro.Schema import org.apache.avro.generic.GenericData import org.apache.avro.generic.GenericRecord class AirbyteValueToAvroRecord { - fun convert(airbyteValue: AirbyteValue, schema: Schema): Any? { - when (airbyteValue) { - is ObjectValue -> { - val record = GenericData.Record(schema) - airbyteValue.values.forEach { (name, value) -> - record.put(name, convert(value, schema.getField(name).schema())) - } - return record + fun convert(airbyteValue: AirbyteValue, airbyteSchema: AirbyteType, schema: Schema): Any? { + try { + if (airbyteValue == NullValue) { + return null + } + + if ( + schema.isUnion && + schema.types.size == 2 && + schema.types.any { it.type == Schema.Type.NULL } + ) { + val nonNullSchema = schema.types.find { it.type != Schema.Type.NULL }!! + return convert(airbyteValue, airbyteSchema, nonNullSchema) } - is ArrayValue -> { - val array = GenericData.Array(airbyteValue.values.size, schema) - airbyteValue.values.forEach { value -> - array.add(convert(value, schema.elementType)) + + when (airbyteSchema) { + is ObjectType -> { + val record = GenericData.Record(schema) + airbyteSchema.properties.forEach { (name, airbyteField) -> + val nameMangled = Transformations.toAvroSafeName(name) + schema.getField(nameMangled)?.let { avroField -> + val value = (airbyteValue as ObjectValue).values[name] + record.put( + nameMangled, + convert(value ?: NullValue, airbyteField.type, avroField.schema()) + ) + } + } + return record + } + is ArrayType -> { + val array = + GenericData.Array((airbyteValue as ArrayValue).values.size, schema) + airbyteValue.values.forEach { value -> + array.add(convert(value, airbyteSchema.items.type, schema.elementType)) + } + return array + } + BooleanType -> return (airbyteValue as BooleanValue).value + DateType -> return (airbyteValue as IntegerValue).value.toInt() + IntegerType -> return (airbyteValue as IntegerValue).value.toLong() + NumberType -> return (airbyteValue as NumberValue).value.toDouble() + StringType -> return (airbyteValue as StringValue).value + + // Upstream all unknown types other than {"type": "null"} are converted to + // Schemaless + is UnknownType -> return null + + // Converted to strings upstream + ObjectTypeWithEmptySchema, + ObjectTypeWithoutSchema, + ArrayTypeWithoutSchema -> return (airbyteValue as StringValue).value + + // Converted to integrals upstream + TimeTypeWithTimezone, + TimeTypeWithoutTimezone, + TimestampTypeWithTimezone, + TimestampTypeWithoutTimezone -> return (airbyteValue as IntegerValue).value.toLong() + is UnionType -> { + for (optionType in airbyteSchema.options) { + try { + val optionSchema = matchingAvroType(optionType, schema) + return convert(airbyteValue, optionType, optionSchema) + } catch (e: Exception) { + continue + } + } + throw IllegalArgumentException( + "No matching Avro type found for $airbyteSchema in $schema (airbyte value: ${airbyteValue.javaClass.simpleName})" + ) } - return array } - is BooleanValue -> return airbyteValue.value - is DateValue -> - throw IllegalArgumentException("String-based date types are not supported") - is IntegerValue -> return airbyteValue.value - is IntValue -> return airbyteValue.value - is NullValue -> return null - is NumberValue -> return airbyteValue.value.toDouble() - is StringValue -> return airbyteValue.value - is TimeValue -> - throw IllegalArgumentException("String-based time types are not supported") - is TimestampValue -> - throw IllegalArgumentException("String-based timestamp types are not supported") - is UnknownValue -> throw IllegalArgumentException("Unknown type is not supported") + } catch (e: Exception) { + throw RuntimeException( + "Failed to convert $airbyteSchema(${airbyteValue.javaClass.simpleName}) to $schema", + e + ) + } + } + + private fun matchingAvroType(airbyteSchema: AirbyteType, avroUnionSchema: Schema): Schema { + return when (airbyteSchema) { + is ObjectType -> avroUnionSchema.types.find { it.type == Schema.Type.RECORD } + is ArrayType -> avroUnionSchema.types.find { it.type == Schema.Type.ARRAY } + BooleanType -> avroUnionSchema.types.find { it.type == Schema.Type.BOOLEAN } + DateType -> avroUnionSchema.types.find { it.type == Schema.Type.INT } + IntegerType -> avroUnionSchema.types.find { it.type == Schema.Type.LONG } + NumberType -> avroUnionSchema.types.find { it.type == Schema.Type.DOUBLE } + is UnknownType, + ArrayTypeWithoutSchema, + ObjectTypeWithEmptySchema, + ObjectTypeWithoutSchema, + StringType -> avroUnionSchema.types.find { it.type == Schema.Type.STRING } + TimeTypeWithTimezone, + TimeTypeWithoutTimezone, + TimestampTypeWithTimezone, + TimestampTypeWithoutTimezone -> + avroUnionSchema.types.find { it.type == Schema.Type.LONG } + is UnionType -> throw IllegalArgumentException("Nested unions are not supported") } + ?: throw IllegalArgumentException( + "No matching Avro type found for $airbyteSchema in $avroUnionSchema" + ) } } -fun ObjectValue.toAvroRecord(schema: Schema): GenericRecord { - return AirbyteValueToAvroRecord().convert(this, schema) as GenericRecord +fun ObjectValue.toAvroRecord(airbyteSchema: ObjectType, avroSchema: Schema): GenericRecord { + return AirbyteValueToAvroRecord().convert(this, airbyteSchema, avroSchema) as GenericRecord } diff --git a/airbyte-cdk/bulk/toolkits/load-avro/src/main/kotlin/io/airbyte/cdk/load/data/avro/AvroMapperPipelineFactory.kt b/airbyte-cdk/bulk/toolkits/load-avro/src/main/kotlin/io/airbyte/cdk/load/data/avro/AvroMapperPipelineFactory.kt new file mode 100644 index 000000000000..cae1f8a7759e --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-avro/src/main/kotlin/io/airbyte/cdk/load/data/avro/AvroMapperPipelineFactory.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data.avro + +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.data.AirbyteSchemaNoopMapper +import io.airbyte.cdk.load.data.AirbyteValueDeepCoercingMapper +import io.airbyte.cdk.load.data.AirbyteValueNoopMapper +import io.airbyte.cdk.load.data.FailOnAllUnknownTypesExceptNull +import io.airbyte.cdk.load.data.MapperPipeline +import io.airbyte.cdk.load.data.MapperPipelineFactory +import io.airbyte.cdk.load.data.MergeUnions +import io.airbyte.cdk.load.data.NullOutOfRangeIntegers +import io.airbyte.cdk.load.data.SchemalessValuesToJsonString +import io.airbyte.cdk.load.data.TimeStringToInteger + +class AvroMapperPipelineFactory : MapperPipelineFactory { + override fun create(stream: DestinationStream): MapperPipeline = + MapperPipeline( + stream.schema, + listOf( + FailOnAllUnknownTypesExceptNull() to AirbyteValueNoopMapper(), + MergeUnions() to AirbyteValueNoopMapper(), + AirbyteSchemaNoopMapper() to AirbyteValueDeepCoercingMapper(), + // We need to maintain the original ObjectWithNoProperties/etc type. + // For example, if a stream declares no columns, we will (correctly) recognize + // the root schema as ObjectTypeWithEmptySchema. + // If we then map that root schema to StringType, then + // AirbyteTypeToAirbyteTypeWithMeta will crash on it. + AirbyteSchemaNoopMapper() to SchemalessValuesToJsonString(), + AirbyteSchemaNoopMapper() to NullOutOfRangeIntegers(), + AirbyteSchemaNoopMapper() to TimeStringToInteger(), + ), + ) +} diff --git a/airbyte-cdk/bulk/toolkits/load-avro/src/test/kotlin/AirbyteTypeToAvroSchemaTest.kt b/airbyte-cdk/bulk/toolkits/load-avro/src/test/kotlin/AirbyteTypeToAvroSchemaTest.kt new file mode 100644 index 000000000000..703121d58dfd --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-avro/src/test/kotlin/AirbyteTypeToAvroSchemaTest.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.data.FieldType +import io.airbyte.cdk.load.data.ObjectType +import io.airbyte.cdk.load.data.StringType +import io.airbyte.cdk.load.data.avro.toAvroSchema +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertDoesNotThrow + +class AirbyteTypeToAvroSchemaTest { + @Test + fun `test name mangling`() { + val schema = + ObjectType( + properties = + linkedMapOf( + "1d_view" to FieldType(type = StringType, nullable = false), + ) + ) + val descriptor = DestinationStream.Descriptor("test", "stream") + assertDoesNotThrow { schema.toAvroSchema(descriptor) } + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-avro/src/testFixtures/kotlin/io/airbyte/cdk/load/data/avro/AvroExpectedRecordMapper.kt b/airbyte-cdk/bulk/toolkits/load-avro/src/testFixtures/kotlin/io/airbyte/cdk/load/data/avro/AvroExpectedRecordMapper.kt new file mode 100644 index 000000000000..bc771a739598 --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-avro/src/testFixtures/kotlin/io/airbyte/cdk/load/data/avro/AvroExpectedRecordMapper.kt @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data.avro + +import io.airbyte.cdk.load.data.AirbyteType +import io.airbyte.cdk.load.data.AirbyteValue +import io.airbyte.cdk.load.data.ArrayValue +import io.airbyte.cdk.load.data.DateValue +import io.airbyte.cdk.load.data.IntegerValue +import io.airbyte.cdk.load.data.ObjectValue +import io.airbyte.cdk.load.data.TimeWithTimezoneValue +import io.airbyte.cdk.load.data.TimeWithoutTimezoneValue +import io.airbyte.cdk.load.data.TimestampWithTimezoneValue +import io.airbyte.cdk.load.data.TimestampWithoutTimezoneValue +import io.airbyte.cdk.load.test.util.ExpectedRecordMapper +import io.airbyte.cdk.load.test.util.OutputRecord +import java.time.LocalDate +import java.time.ZoneOffset +import java.time.temporal.ChronoField +import java.time.temporal.TemporalAccessor + +object AvroExpectedRecordMapper : ExpectedRecordMapper { + override fun mapRecord(expectedRecord: OutputRecord, schema: AirbyteType): OutputRecord { + return expectedRecord.copy(data = timestampsToInteger(expectedRecord.data) as ObjectValue) + } + + /** + * Avro doesn't have true temporal types. Instead, we write dates as epoch days, and other + * temporal types as epochMicros. Therefore, in expected records, we should convert from real + * temporal types to IntegerValue. + */ + private fun timestampsToInteger(value: AirbyteValue): AirbyteValue = + when (value) { + is DateValue -> IntegerValue(value.value.toEpochDay()) + is TimestampWithTimezoneValue -> { + val micros = getMicros(value.value) + val epochSecond = value.value.toEpochSecond() + integerValue(epochSecond, micros) + } + is TimestampWithoutTimezoneValue -> { + val micros = getMicros(value.value) + val epochSecond = value.value.toEpochSecond(ZoneOffset.UTC) + integerValue(epochSecond, micros) + } + is TimeWithTimezoneValue -> { + val micros = getMicros(value.value) + val epochSecond = value.value.toEpochSecond(LocalDate.EPOCH) + integerValue(epochSecond, micros) + } + is TimeWithoutTimezoneValue -> { + val micros = getMicros(value.value) + val epochSecond = value.value.toEpochSecond(LocalDate.EPOCH, ZoneOffset.UTC) + integerValue(epochSecond, micros) + } + is ArrayValue -> ArrayValue(value.values.map { timestampsToInteger(it) }) + is ObjectValue -> + ObjectValue( + value.values.mapValuesTo(linkedMapOf()) { (_, v) -> timestampsToInteger(v) } + ) + else -> value + } + + private fun getMicros(value: TemporalAccessor) = value.getLong(ChronoField.MICRO_OF_SECOND) + + private fun integerValue(epochSecond: Long, micros: Long) = + IntegerValue(epochSecond * 1_000_000 + micros) +} diff --git a/airbyte-cdk/bulk/toolkits/load-avro/src/testFixtures/kotlin/io/airbyte/cdk/load/data/avro/AvroRecordToAirbyteValue.kt b/airbyte-cdk/bulk/toolkits/load-avro/src/testFixtures/kotlin/io/airbyte/cdk/load/data/avro/AvroRecordToAirbyteValue.kt index 0cd0ba1f680d..dc3b6f701cb4 100644 --- a/airbyte-cdk/bulk/toolkits/load-avro/src/testFixtures/kotlin/io/airbyte/cdk/load/data/avro/AvroRecordToAirbyteValue.kt +++ b/airbyte-cdk/bulk/toolkits/load-avro/src/testFixtures/kotlin/io/airbyte/cdk/load/data/avro/AvroRecordToAirbyteValue.kt @@ -4,96 +4,43 @@ package io.airbyte.cdk.load.data.avro -import io.airbyte.cdk.load.data.AirbyteType import io.airbyte.cdk.load.data.AirbyteValue -import io.airbyte.cdk.load.data.ArrayType -import io.airbyte.cdk.load.data.ArrayTypeWithoutSchema import io.airbyte.cdk.load.data.ArrayValue -import io.airbyte.cdk.load.data.BooleanType import io.airbyte.cdk.load.data.BooleanValue -import io.airbyte.cdk.load.data.DateType -import io.airbyte.cdk.load.data.IntegerType import io.airbyte.cdk.load.data.IntegerValue -import io.airbyte.cdk.load.data.NullType import io.airbyte.cdk.load.data.NullValue -import io.airbyte.cdk.load.data.NumberType import io.airbyte.cdk.load.data.NumberValue -import io.airbyte.cdk.load.data.ObjectType -import io.airbyte.cdk.load.data.ObjectTypeWithEmptySchema -import io.airbyte.cdk.load.data.ObjectTypeWithoutSchema import io.airbyte.cdk.load.data.ObjectValue -import io.airbyte.cdk.load.data.StringType import io.airbyte.cdk.load.data.StringValue -import io.airbyte.cdk.load.data.TimeTypeWithTimezone -import io.airbyte.cdk.load.data.TimeTypeWithoutTimezone -import io.airbyte.cdk.load.data.TimestampTypeWithTimezone -import io.airbyte.cdk.load.data.TimestampTypeWithoutTimezone -import io.airbyte.cdk.load.data.UnionType -import io.airbyte.cdk.load.data.UnknownType import org.apache.avro.generic.GenericArray import org.apache.avro.generic.GenericRecord import org.apache.avro.util.Utf8 -class AvroRecordToAirbyteValue { - fun convert(avroValue: Any?, schema: AirbyteType): AirbyteValue { - when (schema) { - is ObjectType -> { - val properties = LinkedHashMap() - schema.properties.forEach { (name, field) -> - val value = (avroValue as GenericRecord).get(name) - properties[name] = convert(value, field.type) - } - return ObjectValue(properties) - } - is ArrayType -> { - val items = schema.items - val values = (avroValue as GenericArray<*>).map { convert(it, items.type) } - return ArrayValue(values) - } - is ArrayTypeWithoutSchema -> - throw UnsupportedOperationException("ArrayTypeWithoutSchema is not supported") - is BooleanType -> return BooleanValue(avroValue as Boolean) - is DateType -> throw UnsupportedOperationException("DateType is not supported") - is IntegerType -> return IntegerValue(avroValue as Long) - is NullType -> return NullValue - is NumberType -> return NumberValue((avroValue as Double).toBigDecimal()) - is ObjectTypeWithEmptySchema -> - throw UnsupportedOperationException("ObjectTypeWithEmptySchema is not supported") - is ObjectTypeWithoutSchema -> - throw UnsupportedOperationException("ObjectTypeWithoutSchema is not supported") - is StringType -> - return StringValue( - when (avroValue) { - is Utf8 -> avroValue.toString() // Avro - is String -> avroValue // Avro via Parquet - else -> - throw IllegalArgumentException("Unsupported string type: $avroValue") +object AvroRecordToAirbyteValue { + fun convert(avroValue: Any?): AirbyteValue { + return when (avroValue) { + null -> NullValue + is GenericRecord -> + ObjectValue( + avroValue.schema.fields.associateTo(linkedMapOf()) { field -> + field.name() to convert(avroValue.get(field.name())) } ) - is TimeTypeWithoutTimezone, - is TimeTypeWithTimezone -> - throw UnsupportedOperationException("TimeType is not supported") - is TimestampTypeWithoutTimezone, - is TimestampTypeWithTimezone -> - throw UnsupportedOperationException("TimestampType is not supported") - is UnionType -> return tryConvertUnion(avroValue, schema) - is UnknownType -> throw UnsupportedOperationException("UnknownType is not supported") - else -> throw IllegalArgumentException("Unsupported schema type: $schema") - } - } - - private fun tryConvertUnion(avroValue: Any?, schema: UnionType): AirbyteValue { - for (type in schema.options) { - try { - return convert(avroValue, type) - } catch (e: Exception) { - continue - } + is GenericArray<*> -> ArrayValue(avroValue.map { convert(it) }) + is Boolean -> BooleanValue(avroValue) + is Int -> IntegerValue(avroValue.toLong()) + is Long -> IntegerValue(avroValue) + is Double -> NumberValue(avroValue.toBigDecimal()) + is Utf8 -> StringValue(avroValue.toString()) + is String -> StringValue(avroValue) + else -> + throw IllegalArgumentException( + "Unrecognized avro value type: ${avroValue::class.qualifiedName} with value: $avroValue" + ) } - throw IllegalArgumentException("Could not convert value to any of the union types") } } -fun GenericRecord.toAirbyteValue(schema: AirbyteType): AirbyteValue { - return AvroRecordToAirbyteValue().convert(this, schema) +fun GenericRecord.toAirbyteValue(): AirbyteValue { + return AvroRecordToAirbyteValue.convert(this) } diff --git a/airbyte-cdk/bulk/toolkits/load-avro/src/testFixtures/kotlin/io/airbyte/cdk/load/file/avro/AvroReader.kt b/airbyte-cdk/bulk/toolkits/load-avro/src/testFixtures/kotlin/io/airbyte/cdk/load/file/avro/AvroReader.kt index 22f335b0abb3..8af3e8868093 100644 --- a/airbyte-cdk/bulk/toolkits/load-avro/src/testFixtures/kotlin/io/airbyte/cdk/load/file/avro/AvroReader.kt +++ b/airbyte-cdk/bulk/toolkits/load-avro/src/testFixtures/kotlin/io/airbyte/cdk/load/file/avro/AvroReader.kt @@ -4,10 +4,10 @@ package io.airbyte.cdk.load.file.avro +import io.airbyte.cdk.load.command.DestinationStream import java.io.Closeable import java.io.InputStream import kotlin.io.path.outputStream -import org.apache.avro.Schema import org.apache.avro.file.DataFileReader import org.apache.avro.generic.GenericDatumReader import org.apache.avro.generic.GenericRecord @@ -34,12 +34,12 @@ class AvroReader( } } -fun InputStream.toAvroReader(avroSchema: Schema): AvroReader { - val reader = GenericDatumReader(avroSchema) +fun InputStream.toAvroReader(streamDescriptor: DestinationStream.Descriptor): AvroReader { + val reader = GenericDatumReader() val tmpFile = kotlin.io.path.createTempFile( - prefix = "${avroSchema.namespace}.${avroSchema.name}", - suffix = ".avro" + prefix = "${streamDescriptor.namespace}.${streamDescriptor.name}", + suffix = ".avro", ) tmpFile.outputStream().use { outputStream -> this.copyTo(outputStream) } val file = tmpFile.toFile() diff --git a/airbyte-cdk/bulk/toolkits/load-aws/src/main/kotlin/io/airbyte/cdk/load/command/aws/AWSAccessKeySpecification.kt b/airbyte-cdk/bulk/toolkits/load-aws/src/main/kotlin/io/airbyte/cdk/load/command/aws/AWSAccessKeySpecification.kt index 17779147ad18..f599a8806487 100644 --- a/airbyte-cdk/bulk/toolkits/load-aws/src/main/kotlin/io/airbyte/cdk/load/command/aws/AWSAccessKeySpecification.kt +++ b/airbyte-cdk/bulk/toolkits/load-aws/src/main/kotlin/io/airbyte/cdk/load/command/aws/AWSAccessKeySpecification.kt @@ -21,23 +21,29 @@ interface AWSAccessKeySpecification { "The access key ID to access the S3 bucket. Airbyte requires Read and Write permissions to the given bucket. Read more here." ) @get:JsonProperty("access_key_id") - @get:JsonSchemaInject(json = """{"examples":["A012345678910EXAMPLE"]}""") - val accessKeyId: String + @get:JsonSchemaInject( + json = + """{"examples":["A012345678910EXAMPLE"],"airbyte_secret": true,"always_show": true}""" + ) + val accessKeyId: String? @get:JsonSchemaTitle("S3 Access Key") @get:JsonPropertyDescription( "The corresponding secret to the access key ID. Read more here" ) @get:JsonProperty("secret_access_key") - @get:JsonSchemaInject(json = """{"examples":["a012345678910ABCDEFGH/AbCdEfGhEXAMPLEKEY"]}""") - val secretAccessKey: String + @get:JsonSchemaInject( + json = + """{"examples":["a012345678910ABCDEFGH/AbCdEfGhEXAMPLEKEY"],"airbyte_secret": true,"always_show": true}""" + ) + val secretAccessKey: String? fun toAWSAccessKeyConfiguration(): AWSAccessKeyConfiguration { return AWSAccessKeyConfiguration(accessKeyId, secretAccessKey) } } -data class AWSAccessKeyConfiguration(val accessKeyId: String, val secretAccessKey: String) +data class AWSAccessKeyConfiguration(val accessKeyId: String?, val secretAccessKey: String?) interface AWSAccessKeyConfigurationProvider { val awsAccessKeyConfiguration: AWSAccessKeyConfiguration diff --git a/airbyte-cdk/bulk/toolkits/load-aws/src/main/kotlin/io/airbyte/cdk/load/command/aws/AWSArnRoleSpecification.kt b/airbyte-cdk/bulk/toolkits/load-aws/src/main/kotlin/io/airbyte/cdk/load/command/aws/AWSArnRoleSpecification.kt new file mode 100644 index 000000000000..7c48b7997672 --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-aws/src/main/kotlin/io/airbyte/cdk/load/command/aws/AWSArnRoleSpecification.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.command.aws + +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonPropertyDescription +import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaTitle + +interface AWSArnRoleSpecification { + @get:JsonSchemaTitle("Role ARN") + @get:JsonPropertyDescription("The Role ARN.") + @get:JsonProperty("role_arn") + val roleArn: String? + + fun toAWSArnRoleConfiguration(): AWSArnRoleConfiguration { + return AWSArnRoleConfiguration(roleArn) + } +} + +data class AWSArnRoleConfiguration(val roleArn: String?) + +interface AWSArnRoleConfigurationProvider { + val awsArnRoleConfiguration: AWSArnRoleConfiguration +} diff --git a/airbyte-cdk/bulk/toolkits/load-csv/build.gradle b/airbyte-cdk/bulk/toolkits/load-csv/build.gradle index e9a2f683d569..5e4680267a9c 100644 --- a/airbyte-cdk/bulk/toolkits/load-csv/build.gradle +++ b/airbyte-cdk/bulk/toolkits/load-csv/build.gradle @@ -2,7 +2,7 @@ dependencies { implementation project(':airbyte-cdk:bulk:core:bulk-cdk-core-base') implementation project(':airbyte-cdk:bulk:core:bulk-cdk-core-load') - api("org.apache.commons:commons-csv:1.10.0") + api("org.apache.commons:commons-csv:1.11.0") testFixturesImplementation testFixtures(project(":airbyte-cdk:bulk:core:bulk-cdk-core-load")) } diff --git a/airbyte-cdk/bulk/toolkits/load-csv/src/main/kotlin/io/airbyte/cdk/load/data/csv/AirbyteValueToCsvRow.kt b/airbyte-cdk/bulk/toolkits/load-csv/src/main/kotlin/io/airbyte/cdk/load/data/csv/AirbyteValueToCsvRow.kt index 1f55dfa5ff21..f35cde846af1 100644 --- a/airbyte-cdk/bulk/toolkits/load-csv/src/main/kotlin/io/airbyte/cdk/load/data/csv/AirbyteValueToCsvRow.kt +++ b/airbyte-cdk/bulk/toolkits/load-csv/src/main/kotlin/io/airbyte/cdk/load/data/csv/AirbyteValueToCsvRow.kt @@ -4,32 +4,42 @@ package io.airbyte.cdk.load.data.csv -import io.airbyte.cdk.load.data.AirbyteValue import io.airbyte.cdk.load.data.ArrayValue +import io.airbyte.cdk.load.data.BooleanValue +import io.airbyte.cdk.load.data.DateValue import io.airbyte.cdk.load.data.IntegerValue +import io.airbyte.cdk.load.data.NullValue import io.airbyte.cdk.load.data.NumberValue +import io.airbyte.cdk.load.data.ObjectType import io.airbyte.cdk.load.data.ObjectValue import io.airbyte.cdk.load.data.StringValue +import io.airbyte.cdk.load.data.TimeWithTimezoneValue +import io.airbyte.cdk.load.data.TimeWithoutTimezoneValue +import io.airbyte.cdk.load.data.TimestampWithTimezoneValue +import io.airbyte.cdk.load.data.TimestampWithoutTimezoneValue +import io.airbyte.cdk.load.data.UnknownValue import io.airbyte.cdk.load.data.json.toJson import io.airbyte.cdk.load.util.serializeToString -class AirbyteValueToCsvRow { - fun convert(value: ObjectValue): Array { - return value.values.map { convertInner(it.value) }.toTypedArray() - } - - private fun convertInner(value: AirbyteValue): String { - return when (value) { - is ObjectValue -> value.toJson().serializeToString() - is ArrayValue -> value.toJson().serializeToString() - is StringValue -> value.value - is IntegerValue -> value.value.toString() - is NumberValue -> value.value.toString() - else -> value.toString() +fun ObjectValue.toCsvRecord(schema: ObjectType): List { + return schema.properties.map { (key, _) -> + values[key]?.let { + when (it) { + is ObjectValue -> it.toJson().serializeToString() + is ArrayValue -> it.toJson().serializeToString() + is StringValue -> it.value + is IntegerValue -> it.value + is NumberValue -> it.value + is NullValue -> "" + is TimestampWithTimezoneValue -> it.value + is TimestampWithoutTimezoneValue -> it.value + is BooleanValue -> it.value + is DateValue -> it.value + is TimeWithTimezoneValue -> it.value + is TimeWithoutTimezoneValue -> it.value + is UnknownValue -> "" + } } + ?: "" } } - -fun ObjectValue.toCsvRecord(): Array { - return AirbyteValueToCsvRow().convert(this) -} diff --git a/airbyte-cdk/bulk/toolkits/load-csv/src/main/kotlin/io/airbyte/cdk/load/file/csv/CSVWriter.kt b/airbyte-cdk/bulk/toolkits/load-csv/src/main/kotlin/io/airbyte/cdk/load/file/csv/CSVWriter.kt index 60d293470ad9..3a4b234a9cf4 100644 --- a/airbyte-cdk/bulk/toolkits/load-csv/src/main/kotlin/io/airbyte/cdk/load/file/csv/CSVWriter.kt +++ b/airbyte-cdk/bulk/toolkits/load-csv/src/main/kotlin/io/airbyte/cdk/load/file/csv/CSVWriter.kt @@ -7,12 +7,15 @@ package io.airbyte.cdk.load.file.csv import io.airbyte.cdk.load.data.ObjectType import io.airbyte.cdk.load.data.csv.toCsvHeader import java.io.OutputStream +import java.io.PrintWriter +import java.nio.charset.StandardCharsets import org.apache.commons.csv.CSVFormat import org.apache.commons.csv.CSVPrinter +import org.apache.commons.csv.QuoteMode -fun ObjectType.toCsvPrinterWithHeader(outputStream: OutputStream): CSVPrinter = - CSVFormat.Builder.create() - .setHeader(*toCsvHeader()) - .setAutoFlush(true) - .build() - .print(outputStream.writer(charset = Charsets.UTF_8)) +@Suppress("DEPRECATION") +fun ObjectType.toCsvPrinterWithHeader(outputStream: OutputStream): CSVPrinter { + val csvSettings = + CSVFormat.DEFAULT.withQuoteMode(QuoteMode.NON_NUMERIC).withHeader(*toCsvHeader()) + return CSVPrinter(PrintWriter(outputStream, true, StandardCharsets.UTF_8), csvSettings) +} diff --git a/airbyte-cdk/bulk/toolkits/load-csv/src/testFixtures/kotlin/io/airbyte/cdk/load/data/csv/CsvRowToAirbyteValue.kt b/airbyte-cdk/bulk/toolkits/load-csv/src/testFixtures/kotlin/io/airbyte/cdk/load/data/csv/CsvRowToAirbyteValue.kt index 50c5922a4888..f140cf9142e4 100644 --- a/airbyte-cdk/bulk/toolkits/load-csv/src/testFixtures/kotlin/io/airbyte/cdk/load/data/csv/CsvRowToAirbyteValue.kt +++ b/airbyte-cdk/bulk/toolkits/load-csv/src/testFixtures/kotlin/io/airbyte/cdk/load/data/csv/CsvRowToAirbyteValue.kt @@ -6,20 +6,11 @@ package io.airbyte.cdk.load.data.csv import io.airbyte.cdk.load.data.AirbyteType import io.airbyte.cdk.load.data.AirbyteValue -import io.airbyte.cdk.load.data.ArrayType -import io.airbyte.cdk.load.data.ArrayValue -import io.airbyte.cdk.load.data.BooleanType -import io.airbyte.cdk.load.data.BooleanValue -import io.airbyte.cdk.load.data.IntegerType -import io.airbyte.cdk.load.data.IntegerValue -import io.airbyte.cdk.load.data.NumberType -import io.airbyte.cdk.load.data.NumberValue import io.airbyte.cdk.load.data.ObjectType -import io.airbyte.cdk.load.data.ObjectTypeWithoutSchema import io.airbyte.cdk.load.data.ObjectValue -import io.airbyte.cdk.load.data.StringType import io.airbyte.cdk.load.data.StringValue import io.airbyte.cdk.load.data.json.toAirbyteValue +import io.airbyte.cdk.load.message.Meta import io.airbyte.cdk.load.util.deserializeToNode import org.apache.commons.csv.CSVRecord @@ -28,51 +19,25 @@ class CsvRowToAirbyteValue { if (schema !is ObjectType) { throw IllegalArgumentException("Only object types are supported") } - val asList = row.toList() - if (asList.size != schema.properties.size) { - throw IllegalArgumentException("Row size does not match schema size") - } - val properties = linkedMapOf() - schema.properties - .toList() - .zip(asList) - .map { (property, value) -> - property.first to convertInner(value, property.second.type) - } - .toMap(properties) - return ObjectValue(properties) - } - private fun convertInner(value: String, field: AirbyteType): AirbyteValue { - return when (field) { - is ArrayType -> - value - .deserializeToNode() - .elements() - .asSequence() - .map { it.toAirbyteValue(field.items.type) } - .toList() - .let(::ArrayValue) - is BooleanType -> BooleanValue(value.toBoolean()) - is IntegerType -> IntegerValue(value.toLong()) - is NumberType -> NumberValue(value.toBigDecimal()) - is ObjectType -> { - val properties = linkedMapOf() - value - .deserializeToNode() - .fields() - .asSequence() - .map { entry -> - entry.key to entry.value.toAirbyteValue(field.properties[entry.key]!!.type) + return ObjectValue( + row.parser.headerNames.zip(row.toList()).associateTo(linkedMapOf()) { (key, valueString) + -> + val airbyteValue = + if (Meta.COLUMN_NAMES.contains(key)) { + Meta.getMetaValue(key, valueString) + } else { + try { + valueString.deserializeToNode().toAirbyteValue() + } catch (e: Exception) { + // boolean/number/object/array can deserialize cleanly + // but strings don't work, so just handle them here + StringValue(valueString) + } } - .toMap(properties) - ObjectValue(properties) - } - is ObjectTypeWithoutSchema -> - value.deserializeToNode().toAirbyteValue(ObjectTypeWithoutSchema) - is StringType -> StringValue(value) - else -> throw IllegalArgumentException("Unsupported field type: $field") - } + key to airbyteValue + }, + ) } } diff --git a/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/build.gradle b/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/build.gradle new file mode 100644 index 000000000000..d395ecd3a6f0 --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/build.gradle @@ -0,0 +1,16 @@ +ext { + apacheIcebergVersion = '1.7.0' +} + +dependencies { + api project(':airbyte-cdk:bulk:toolkits:bulk-cdk-toolkit-load-s3') + + implementation project(':airbyte-cdk:bulk:core:bulk-cdk-core-base') + implementation project(':airbyte-cdk:bulk:core:bulk-cdk-core-load') + api "org.apache.iceberg:iceberg-core:${project.ext.apacheIcebergVersion}" + api "org.apache.iceberg:iceberg-api:${project.ext.apacheIcebergVersion}" + api "org.apache.iceberg:iceberg-parquet:${project.ext.apacheIcebergVersion}" + api "org.apache.iceberg:iceberg-nessie:${project.ext.apacheIcebergVersion}" + + testFixturesImplementation testFixtures(project(":airbyte-cdk:bulk:core:bulk-cdk-core-load")) +} diff --git a/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/main/kotlin/io/airbyte/cdk/load/command/iceberg/parquet/IcebergCatalogSpecifications.kt b/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/main/kotlin/io/airbyte/cdk/load/command/iceberg/parquet/IcebergCatalogSpecifications.kt new file mode 100644 index 000000000000..6c93e70d1e6e --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/main/kotlin/io/airbyte/cdk/load/command/iceberg/parquet/IcebergCatalogSpecifications.kt @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.command.iceberg.parquet + +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonPropertyDescription +import com.fasterxml.jackson.annotation.JsonSubTypes +import com.fasterxml.jackson.annotation.JsonTypeInfo +import com.fasterxml.jackson.annotation.JsonValue +import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaDescription +import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaInject +import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaTitle + +/** + * Interface defining the specifications for configuring an Iceberg catalog. + * + * This includes general warehouse information as well as details about the primary branch and the + * specific type of catalog (e.g., Nessie or Glue). Implementations of this interface should provide + * the necessary configuration to connect to and use an Iceberg catalog in different environments. + */ +@JsonSchemaTitle("Iceberg Catalog Specifications") +@JsonSchemaDescription( + "Defines the configurations required to connect to an Iceberg catalog, including warehouse location, main branch name, and catalog type specifics." +) +interface IcebergCatalogSpecifications { + + /** + * The warehouse location. + * + * Specifies the physical or logical location of the data warehouse that the Iceberg catalog + * uses. For example: `s3://my-bucket/warehouse/` + */ + @get:JsonSchemaTitle("Warehouse Location") + @get:JsonPropertyDescription( + "The root location of the data warehouse used by the Iceberg catalog." + ) + @get:JsonProperty("warehouse_location") + val warehouseLocation: String + + /** + * The name of the main branch in the Nessie repository (or the equivalent main branch in other + * catalog types). + * + * Specifies the default or primary branch name in the catalog repository. For example: `main` + */ + @get:JsonSchemaTitle("Main Branch Name") + @get:JsonPropertyDescription("The primary or default branch name in the catalog repository.") + @get:JsonProperty("main_branch_name") + val mainBranchName: String + + /** + * The catalog type. + * + * Indicates the type of catalog used (e.g., Nessie or Glue) and provides configuration details + * specific to that type. + */ + @get:JsonSchemaTitle("Catalog Type") + @get:JsonPropertyDescription( + "Specifies the type of Iceberg catalog (e.g., NESSIE or GLUE) and its associated configuration." + ) + @get:JsonProperty("catalog_type") + val catalogType: CatalogType + + /** + * Converts the current specifications into a common Iceberg catalog configuration object. + * + * @return A unified IcebergCatalogConfiguration containing all necessary configuration details. + */ + fun toIcebergCatalogConfiguration(): IcebergCatalogConfiguration { + val catalogConfiguration = + when (catalogType) { + is GlueCatalogSpecification -> + GlueCatalogConfiguration((catalogType as GlueCatalogSpecification).glueId) + is NessieCatalogSpecification -> + NessieCatalogConfiguration( + (catalogType as NessieCatalogSpecification).serverUri, + (catalogType as NessieCatalogSpecification).accessToken + ) + } + + return IcebergCatalogConfiguration(warehouseLocation, mainBranchName, catalogConfiguration) + } +} + +/** + * A sealed class representing different catalog types for Iceberg. + * + * The catalog type determines which underlying service or system (e.g., Nessie or Glue) is used to + * store and manage Iceberg table metadata. + */ +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.EXISTING_PROPERTY, + property = "catalog_type", +) +@JsonSubTypes( + JsonSubTypes.Type(value = NessieCatalogSpecification::class, name = "NESSIE"), + JsonSubTypes.Type(value = GlueCatalogSpecification::class, name = "GLUE"), +) +@JsonSchemaTitle("Iceberg Catalog Type") +@JsonSchemaDescription( + "Determines the specific implementation used by the Iceberg catalog, such as NESSIE or GLUE." +) +sealed class CatalogType(@JsonSchemaTitle("Catalog Type") open val catalogType: Type) { + /** Enumeration of possible catalog types. */ + enum class Type(@get:JsonValue val catalogTypeName: String) { + NESSIE("NESSIE"), + GLUE("GLUE"), + } +} + +/** + * Nessie catalog specifications. + * + * Provides configuration details required to connect to a Nessie server and manage Iceberg table + * metadata. + */ +@JsonSchemaTitle("Nessie Catalog") +@JsonSchemaDescription("Configuration details for connecting to a Nessie-based Iceberg catalog.") +class NessieCatalogSpecification( + @JsonSchemaTitle("Catalog Type") + @JsonProperty("catalog_type") + @JsonSchemaInject(json = """{"order":0}""") + override val catalogType: Type = Type.NESSIE, + + /** + * The URI of the Nessie server. + * + * This is required to establish a connection. For example: `https://nessie-server.example.com` + */ + @get:JsonSchemaTitle("Nessie Server URI") + @get:JsonPropertyDescription( + "The base URL of the Nessie server used to connect to the Nessie catalog." + ) + @get:JsonProperty("server_uri") + @JsonSchemaInject(json = """{"order":1}""") + val serverUri: String, + + /** + * Access token for authenticating with the Nessie server. + * + * This is optional and used for secure authentication. For example: + * `a012345678910ABCDEFGH/AbCdEfGhEXAMPLEKEY` + */ + @get:JsonSchemaTitle("Nessie Access Token") + @get:JsonPropertyDescription("Optional token for authentication with the Nessie server.") + @get:JsonProperty("access_token") + @get:JsonSchemaInject( + json = + """{ + "examples": ["a012345678910ABCDEFGH/AbCdEfGhEXAMPLEKEY"], + "airbyte_secret": true, + "order":2 + }""", + ) + val accessToken: String? +) : CatalogType(catalogType) + +/** + * Glue catalog specifications. + * + * Provides configuration details required to connect to the AWS Glue catalog service and manage + * Iceberg table metadata. + */ +@JsonSchemaTitle("Glue Catalog") +@JsonSchemaDescription("Configuration details for connecting to an AWS Glue-based Iceberg catalog.") +class GlueCatalogSpecification( + @JsonSchemaTitle("Catalog Type") + @JsonProperty("catalog_type") + @JsonSchemaInject(json = """{"order":0}""") + override val catalogType: Type = Type.GLUE, + + /** + * The AWS Account ID for the Glue service. + * + * Specifies the target AWS Account where the Glue catalog is hosted. + */ + @get:JsonSchemaTitle("AWS Account ID") + @get:JsonPropertyDescription( + "The AWS Account ID associated with the Glue service used by the Iceberg catalog." + ) + @JsonProperty("glue_id") + @JsonSchemaInject(json = """{"order":1}""") + val glueId: String, +) : CatalogType(catalogType) + +/** + * Represents a unified Iceberg catalog configuration. + * + * This class encapsulates the warehouse location, main branch, and a generic catalog configuration + * (e.g., Nessie or Glue), providing a standardized way to work with various catalog backends. + */ +@JsonSchemaTitle("Iceberg Catalog Configuration") +@JsonSchemaDescription( + "A unified configuration object for an Iceberg catalog, including warehouse location, main branch name, and backend-specific settings." +) +data class IcebergCatalogConfiguration( + @JsonSchemaTitle("Warehouse Location") + @JsonPropertyDescription("The root location of the data warehouse used by the Iceberg catalog.") + val warehouseLocation: String, + @JsonSchemaTitle("Main Branch Name") + @JsonPropertyDescription("The primary or default branch name in the catalog repository.") + val mainBranchName: String, + @JsonSchemaTitle("Catalog Configuration") + @JsonPropertyDescription( + "The specific configuration details of the chosen Iceberg catalog type." + ) + val catalogConfiguration: CatalogConfiguration +) + +/** + * A marker interface for catalog configuration details. + * + * Implementations of this interface contain the specific information needed to connect to a + * particular type of catalog backend. + */ +sealed interface CatalogConfiguration + +/** + * Glue catalog configuration details. + * + * Stores information required to connect to an AWS Glue catalog. + */ +@JsonSchemaTitle("Glue Catalog Configuration") +@JsonSchemaDescription("AWS Glue-specific configuration details for connecting an Iceberg catalog.") +data class GlueCatalogConfiguration( + @JsonSchemaTitle("AWS Account ID") + @JsonPropertyDescription("The AWS Account ID associated with the Glue service.") + val glueId: String +) : CatalogConfiguration + +/** + * Nessie catalog configuration details. + * + * Stores information required to connect to a Nessie server. + */ +@JsonSchemaTitle("Nessie Catalog Configuration") +@JsonSchemaDescription("Nessie-specific configuration details for connecting an Iceberg catalog.") +data class NessieCatalogConfiguration( + @JsonSchemaTitle("Nessie Server URI") + @JsonPropertyDescription("The base URL of the Nessie server.") + val serverUri: String, + @JsonSchemaTitle("Nessie Access Token") + @JsonPropertyDescription("An optional token for authentication with the Nessie server.") + val accessToken: String? +) : CatalogConfiguration + +/** + * Provides a way to retrieve the unified Iceberg catalog configuration. + * + * Classes implementing this interface should supply the IcebergCatalogConfiguration instance + * representing the fully resolved configuration for the Iceberg catalog. + */ +interface IcebergCatalogConfigurationProvider { + val icebergCatalogConfiguration: IcebergCatalogConfiguration +} diff --git a/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/main/kotlin/io/airbyte/cdk/load/data/iceberg/parquet/AirbyteTypeToIcebergSchema.kt b/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/main/kotlin/io/airbyte/cdk/load/data/iceberg/parquet/AirbyteTypeToIcebergSchema.kt new file mode 100644 index 000000000000..344fcf56e85c --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/main/kotlin/io/airbyte/cdk/load/data/iceberg/parquet/AirbyteTypeToIcebergSchema.kt @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data.iceberg.parquet + +import io.airbyte.cdk.load.data.AirbyteType +import io.airbyte.cdk.load.data.ArrayType +import io.airbyte.cdk.load.data.ArrayTypeWithoutSchema +import io.airbyte.cdk.load.data.BooleanType +import io.airbyte.cdk.load.data.DateType +import io.airbyte.cdk.load.data.IntegerType +import io.airbyte.cdk.load.data.NumberType +import io.airbyte.cdk.load.data.ObjectType +import io.airbyte.cdk.load.data.ObjectTypeWithEmptySchema +import io.airbyte.cdk.load.data.ObjectTypeWithoutSchema +import io.airbyte.cdk.load.data.StringType +import io.airbyte.cdk.load.data.TimeTypeWithTimezone +import io.airbyte.cdk.load.data.TimeTypeWithoutTimezone +import io.airbyte.cdk.load.data.TimestampTypeWithTimezone +import io.airbyte.cdk.load.data.TimestampTypeWithoutTimezone +import io.airbyte.cdk.load.data.UnionType +import io.airbyte.cdk.load.data.UnknownType +import java.util.UUID +import org.apache.iceberg.Schema +import org.apache.iceberg.types.Type +import org.apache.iceberg.types.Types +import org.apache.iceberg.types.Types.NestedField + +class AirbyteTypeToIcebergSchema { + + fun convert(airbyteSchema: AirbyteType): Type { + return when (airbyteSchema) { + is ObjectType -> { + Types.StructType.of( + *airbyteSchema.properties.entries + .map { (name, field) -> + if (field.nullable) { + NestedField.optional( + UUID.randomUUID().hashCode(), + name, + convert(field.type) + ) + } else { + NestedField.required( + UUID.randomUUID().hashCode(), + name, + convert(field.type) + ) + } + } + .toTypedArray() + ) + } + is ArrayType -> { + val convert = convert(airbyteSchema.items.type) + if (airbyteSchema.items.nullable) { + return Types.ListType.ofOptional(UUID.randomUUID().hashCode(), convert) + } + return Types.ListType.ofRequired(UUID.randomUUID().hashCode(), convert) + } + is BooleanType -> Types.BooleanType.get() + is DateType -> Types.DateType.get() + is IntegerType -> Types.LongType.get() + is NumberType -> Types.DoubleType.get() + // Schemaless types are converted to string + is ArrayTypeWithoutSchema, + is ObjectTypeWithEmptySchema, + is ObjectTypeWithoutSchema -> Types.StringType.get() + is StringType -> Types.StringType.get() + is TimeTypeWithTimezone, + is TimeTypeWithoutTimezone -> Types.TimeType.get() + is TimestampTypeWithTimezone -> Types.TimestampType.withZone() + is TimestampTypeWithoutTimezone -> Types.TimestampType.withoutZone() + is UnionType -> { + if (airbyteSchema.options.size == 1) { + return Types.ListType.ofOptional( + UUID.randomUUID().hashCode(), + convert(airbyteSchema.options.first()) + ) + } + // Iceberg doesnt support a UNION data type + return Types.ListType.ofOptional( + UUID.randomUUID().hashCode(), + Types.StringType.get() + ) + } + is UnknownType -> Types.StringType.get() + } + } +} + +fun ObjectType.toIcebergSchema(primaryKeys: List>): Schema { + val fields = mutableListOf() + val identifierFields = mutableSetOf() + val identifierFieldNames = primaryKeys.flatten().toSet() + val icebergTypeConverter = AirbyteTypeToIcebergSchema() + this.properties.entries.forEach { (name, field) -> + val id = generatedSchemaFieldId() + val isPrimaryKey = identifierFieldNames.contains(name) + val isOptional = !isPrimaryKey && field.nullable + fields.add( + NestedField.of( + id, + isOptional, + name, + icebergTypeConverter.convert(field.type), + ), + ) + if (isPrimaryKey) { + identifierFields.add(id) + } + } + return Schema(fields, identifierFields) +} + +private fun generatedSchemaFieldId() = UUID.randomUUID().hashCode() diff --git a/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/main/kotlin/io/airbyte/cdk/load/data/iceberg/parquet/AirbyteValueToIcebergRecord.kt b/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/main/kotlin/io/airbyte/cdk/load/data/iceberg/parquet/AirbyteValueToIcebergRecord.kt new file mode 100644 index 000000000000..e3f6dead93fb --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/main/kotlin/io/airbyte/cdk/load/data/iceberg/parquet/AirbyteValueToIcebergRecord.kt @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ +package io.airbyte.cdk.load.data.iceberg.parquet + +import io.airbyte.cdk.load.data.AirbyteValue +import io.airbyte.cdk.load.data.ArrayValue +import io.airbyte.cdk.load.data.BooleanValue +import io.airbyte.cdk.load.data.DateValue +import io.airbyte.cdk.load.data.IntegerValue +import io.airbyte.cdk.load.data.NullValue +import io.airbyte.cdk.load.data.NumberValue +import io.airbyte.cdk.load.data.ObjectValue +import io.airbyte.cdk.load.data.StringValue +import io.airbyte.cdk.load.data.TimeWithTimezoneValue +import io.airbyte.cdk.load.data.TimeWithoutTimezoneValue +import io.airbyte.cdk.load.data.TimestampWithTimezoneValue +import io.airbyte.cdk.load.data.TimestampWithoutTimezoneValue +import io.airbyte.cdk.load.data.UnknownValue +import java.time.ZoneOffset +import org.apache.iceberg.Schema +import org.apache.iceberg.data.GenericRecord +import org.apache.iceberg.types.Type +import org.apache.iceberg.types.Types.TimestampType + +class AirbyteValueToIcebergRecord { + fun convert(airbyteValue: AirbyteValue, type: Type): Any? { + when (airbyteValue) { + is ObjectValue -> { + val recordSchema = + if (type.isStructType) { + type.asStructType().asSchema() + } else { + throw IllegalArgumentException("ObjectValue should be mapped to StructType") + } + + val record = GenericRecord.create(recordSchema) + recordSchema + .columns() + .filter { column -> airbyteValue.values.containsKey(column.name()) } + .associate { column -> + column.name() to + convert( + airbyteValue.values.getOrDefault(column.name(), NullValue), + column.type(), + ) + } + .forEach { (name, value) -> record.setField(name, value) } + return record + } + is ArrayValue -> { + val elementType = + if (type.isListType) { + type.asListType().elementType() + } else { + throw IllegalArgumentException("ArrayValue should be mapped to ListType") + } + + val array: MutableList = mutableListOf() + + airbyteValue.values.forEach { value -> array.add(convert(value, elementType)) } + return array + } + is BooleanValue -> return airbyteValue.value + is DateValue -> return airbyteValue.value + is IntegerValue -> return airbyteValue.value.toLong() + is NullValue -> return null + is NumberValue -> return airbyteValue.value.toDouble() + is StringValue -> return airbyteValue.value + is TimeWithTimezoneValue -> + return when (type.typeId()) { + Type.TypeID.TIME -> airbyteValue.value.toLocalTime() + else -> + throw IllegalArgumentException( + "${type.typeId()} type is not allowed for TimeValue" + ) + } + is TimeWithoutTimezoneValue -> + return when (type.typeId()) { + Type.TypeID.TIME -> airbyteValue.value + else -> + throw IllegalArgumentException( + "${type.typeId()} type is not allowed for TimeValue" + ) + } + is TimestampWithTimezoneValue -> + return when (type.typeId()) { + Type.TypeID.TIMESTAMP -> { + val timestampType = type as TimestampType + val offsetDateTime = airbyteValue.value + + if (timestampType.shouldAdjustToUTC()) { + offsetDateTime + } else { + offsetDateTime.toLocalDateTime() + } + } + else -> + throw IllegalArgumentException( + "${type.typeId()} type is not allowed for TimestampValue" + ) + } + is TimestampWithoutTimezoneValue -> + return when (type.typeId()) { + Type.TypeID.TIMESTAMP -> { + val timestampType = type as TimestampType + val localDateTime = airbyteValue.value + + if (timestampType.shouldAdjustToUTC()) { + localDateTime.atOffset(ZoneOffset.UTC) + } else { + localDateTime + } + } + else -> + throw IllegalArgumentException( + "${type.typeId()} type is not allowed for TimestampValue" + ) + } + is UnknownValue -> throw IllegalArgumentException("Unknown type is not supported") + } + } +} + +fun ObjectValue.toIcebergRecord(schema: Schema): GenericRecord { + val record = GenericRecord.create(schema) + val airbyteValueToIcebergRecord = AirbyteValueToIcebergRecord() + schema.asStruct().fields().forEach { field -> + val value = this.values[field.name()] + if (value != null) { + record.setField(field.name(), airbyteValueToIcebergRecord.convert(value, field.type())) + } + } + return record +} diff --git a/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/main/kotlin/io/airbyte/cdk/load/data/iceberg/parquet/IcebergParquetPipelineFactory.kt b/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/main/kotlin/io/airbyte/cdk/load/data/iceberg/parquet/IcebergParquetPipelineFactory.kt new file mode 100644 index 000000000000..979662621260 --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/main/kotlin/io/airbyte/cdk/load/data/iceberg/parquet/IcebergParquetPipelineFactory.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data.iceberg.parquet + +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.data.AirbyteSchemaNoopMapper +import io.airbyte.cdk.load.data.AirbyteValueDeepCoercingMapper +import io.airbyte.cdk.load.data.AirbyteValueNoopMapper +import io.airbyte.cdk.load.data.MapperPipeline +import io.airbyte.cdk.load.data.MapperPipelineFactory +import io.airbyte.cdk.load.data.MergeUnions +import io.airbyte.cdk.load.data.NullOutOfRangeIntegers +import io.airbyte.cdk.load.data.SchemalessValuesToJsonString +import io.airbyte.cdk.load.data.UnionTypeToDisjointRecord +import io.airbyte.cdk.load.data.UnionValueToDisjointRecord + +class IcebergParquetPipelineFactory : MapperPipelineFactory { + override fun create(stream: DestinationStream): MapperPipeline = + MapperPipeline( + stream.schema, + listOf( + MergeUnions() to AirbyteValueNoopMapper(), + AirbyteSchemaNoopMapper() to AirbyteValueDeepCoercingMapper(), + // We need to maintain the original ObjectWithNoProperties/etc type. + // For example, if a stream declares no columns, we will (correctly) recognize + // the root schema as ObjectTypeWithEmptySchema. + // If we then map that root schema to StringType, then + // AirbyteTypeToAirbyteTypeWithMeta will crash on it. + // Furthermore, in UnionTypeToDisjointRecord, this enables us to write thes fields + // as "object" rather than as "string". + AirbyteSchemaNoopMapper() to SchemalessValuesToJsonString(), + AirbyteSchemaNoopMapper() to NullOutOfRangeIntegers(), + UnionTypeToDisjointRecord() to UnionValueToDisjointRecord(), + ), + ) +} diff --git a/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/testFixtures/kotlin/io/airbyte/cdk/load/data/icerberg/parquet/AirbyteTypeToIcebergSchemaTest.kt b/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/testFixtures/kotlin/io/airbyte/cdk/load/data/icerberg/parquet/AirbyteTypeToIcebergSchemaTest.kt new file mode 100644 index 000000000000..1b2f0182905b --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/testFixtures/kotlin/io/airbyte/cdk/load/data/icerberg/parquet/AirbyteTypeToIcebergSchemaTest.kt @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data.icerberg.parquet + +import io.airbyte.cdk.load.data.* +import io.airbyte.cdk.load.data.iceberg.parquet.AirbyteTypeToIcebergSchema +import io.airbyte.cdk.load.data.iceberg.parquet.toIcebergSchema +import io.airbyte.protocol.models.Jsons +import org.apache.iceberg.types.Types +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows + +class AirbyteTypeToIcebergSchemaTest { + + private val converter = AirbyteTypeToIcebergSchema() + + @Test + fun `convert handles ObjectType`() { + val objectType = + ObjectType( + linkedMapOf( + "id" to FieldType(IntegerType, false), + "name" to FieldType(StringType, true), + ), + ) + val result = converter.convert(objectType) as Types.StructType + + assertEquals(2, result.fields().size) + val idField = result.field("id") + val nameField = result.field("name") + + assertNotNull(idField) + assertFalse(idField.isOptional) + assertEquals(Types.LongType.get(), idField.type()) + + assertNotNull(nameField) + assertTrue(nameField.isOptional) + assertEquals(Types.StringType.get(), nameField.type()) + } + + @Test + fun `convert handles ArrayType`() { + val arrayType = ArrayType(FieldType(IntegerType, false)) + val result = converter.convert(arrayType) as Types.ListType + + assertEquals(Types.LongType.get(), result.elementType()) + assertFalse(result.isElementOptional) + } + + @Test + fun `convert handles ArrayType with nullable items`() { + val arrayType = ArrayType(FieldType(StringType, true)) + val result = converter.convert(arrayType) as Types.ListType + + assertEquals(Types.StringType.get(), result.elementType()) + assertTrue(result.isElementOptional) + } + + @Test + fun `convert throws exception for ArrayTypeWithoutSchema`() { + assertThrows { converter.convert(ArrayTypeWithoutSchema) } + } + + @Test + fun `convert handles BooleanType`() { + assertEquals(Types.BooleanType.get(), converter.convert(BooleanType)) + } + + @Test + fun `convert handles DateType`() { + assertEquals(Types.DateType.get(), converter.convert(DateType)) + } + + @Test + fun `convert handles IntegerType`() { + assertEquals(Types.LongType.get(), converter.convert(IntegerType)) + } + + @Test + fun `convert handles NumberType`() { + assertEquals(Types.DoubleType.get(), converter.convert(NumberType)) + } + + @Test + fun `convert throws exception for ObjectTypeWithEmptySchema`() { + assertThrows { converter.convert(ObjectTypeWithEmptySchema) } + } + + @Test + fun `convert throws exception for ObjectTypeWithoutSchema`() { + assertThrows { converter.convert(ObjectTypeWithoutSchema) } + } + + @Test + fun `convert handles StringType`() { + assertEquals(Types.StringType.get(), converter.convert(StringType)) + } + + @Test + fun `convert handles TimeTypeWithTimezone`() { + assertEquals(Types.TimeType.get(), converter.convert(TimeTypeWithTimezone)) + } + + @Test + fun `convert handles TimeTypeWithoutTimezone`() { + assertEquals(Types.TimeType.get(), converter.convert(TimeTypeWithoutTimezone)) + } + + @Test + fun `convert handles TimestampTypeWithTimezone`() { + assertEquals(Types.TimestampType.withZone(), converter.convert(TimestampTypeWithTimezone)) + } + + @Test + fun `convert handles TimestampTypeWithoutTimezone`() { + assertEquals( + Types.TimestampType.withoutZone(), + converter.convert(TimestampTypeWithoutTimezone) + ) + } + + @Test + fun `convert handles UnionType with single option`() { + val unionType = UnionType(setOf(IntegerType)) + val result = converter.convert(unionType) as Types.ListType + + assertEquals(Types.LongType.get(), result.elementType()) + assertTrue(result.isElementOptional) + } + + @Test + fun `convert handles UnionType with multiple options`() { + val unionType = UnionType(setOf(StringType, IntegerType)) + val result = converter.convert(unionType) as Types.ListType + + assertEquals(Types.StringType.get(), result.elementType()) + assertTrue(result.isElementOptional) + } + + @Test + fun `convert handles UnknownType`() { + assertEquals(Types.StringType.get(), converter.convert(UnknownType(Jsons.emptyObject()))) + } + + @Test + fun `toIcebergSchema handles ObjectType`() { + val objectType = + ObjectType( + linkedMapOf( + "age" to FieldType(IntegerType, false), + "email" to FieldType(StringType, true), + ), + ) + val schema = objectType.toIcebergSchema(mutableListOf(mutableListOf("age"))) + + assertEquals(2, schema.columns().size) + val ageColumn = schema.findField("age") + val emailColumn = schema.findField("email") + + assertNotNull(ageColumn) + assertFalse(ageColumn!!.isOptional) + assertEquals(Types.LongType.get(), ageColumn.type()) + + assertNotNull(emailColumn) + assertTrue(emailColumn!!.isOptional) + assertEquals(Types.StringType.get(), emailColumn.type()) + + val identifierFieldIds = schema.identifierFieldIds() + assertEquals(1, identifierFieldIds.size) + assertEquals(true, identifierFieldIds.contains(ageColumn.fieldId())) + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/testFixtures/kotlin/io/airbyte/cdk/load/data/icerberg/parquet/AirbyteValueToIcebergRecordTest.kt b/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/testFixtures/kotlin/io/airbyte/cdk/load/data/icerberg/parquet/AirbyteValueToIcebergRecordTest.kt new file mode 100644 index 000000000000..5bba3951666e --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-iceberg-parquet/src/testFixtures/kotlin/io/airbyte/cdk/load/data/icerberg/parquet/AirbyteValueToIcebergRecordTest.kt @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data.icerberg.parquet + +import io.airbyte.cdk.load.data.ArrayValue +import io.airbyte.cdk.load.data.BooleanValue +import io.airbyte.cdk.load.data.DateValue +import io.airbyte.cdk.load.data.IntegerValue +import io.airbyte.cdk.load.data.NullValue +import io.airbyte.cdk.load.data.NumberValue +import io.airbyte.cdk.load.data.ObjectValue +import io.airbyte.cdk.load.data.StringValue +import io.airbyte.cdk.load.data.TimeWithTimezoneValue +import io.airbyte.cdk.load.data.TimeWithoutTimezoneValue +import io.airbyte.cdk.load.data.TimestampWithTimezoneValue +import io.airbyte.cdk.load.data.TimestampWithoutTimezoneValue +import io.airbyte.cdk.load.data.UnknownValue +import io.airbyte.cdk.load.data.iceberg.parquet.AirbyteValueToIcebergRecord +import io.airbyte.cdk.load.data.iceberg.parquet.toIcebergRecord +import io.airbyte.protocol.models.Jsons +import java.math.BigDecimal +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.LocalTime +import java.time.OffsetDateTime +import java.time.OffsetTime +import org.apache.iceberg.Schema +import org.apache.iceberg.data.GenericRecord +import org.apache.iceberg.types.Types +import org.apache.iceberg.types.Types.NestedField +import org.apache.iceberg.types.Types.StructType +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows + +class AirbyteValueToIcebergRecordTest { + + private val converter = AirbyteValueToIcebergRecord() + + @Test + fun `convert handles ObjectValue`() { + val schema = + Schema( + NestedField.required(1, "id", Types.LongType.get()), + NestedField.optional(2, "name", Types.StringType.get()) + ) + val objectValue = + ObjectValue(linkedMapOf("id" to IntegerValue(42L), "name" to StringValue("John Doe"))) + + val result = converter.convert(objectValue, schema.asStruct()) as GenericRecord + assertEquals(42L, result.getField("id")) + assertEquals("John Doe", result.getField("name")) + } + + @Test + fun `convert throws exception for ObjectValue mapped to non-StructType`() { + val schemaType = Types.StringType.get() + val objectValue = ObjectValue(linkedMapOf("id" to IntegerValue(42L))) + + assertThrows { converter.convert(objectValue, schemaType) } + } + + @Test + fun `convert handles ArrayValue`() { + val arrayType = Types.ListType.ofRequired(1, Types.LongType.get()) + val arrayValue = ArrayValue(listOf(IntegerValue(1L), IntegerValue(2L), IntegerValue(3L))) + + val result = converter.convert(arrayValue, arrayType) as List<*> + assertEquals(listOf(1L, 2L, 3L), result) + } + + @Test + fun `convert throws exception for ArrayValue mapped to non-ListType`() { + val schemaType = Types.StringType.get() + val arrayValue = ArrayValue(listOf(IntegerValue(1L), IntegerValue(2L))) + + assertThrows { converter.convert(arrayValue, schemaType) } + } + + @Test + fun `convert handles BooleanValue`() { + val result = converter.convert(BooleanValue(true), Types.BooleanType.get()) + assertEquals(true, result) + } + + @Test + fun `convert throws exception for DateValue`() { + val result = + converter.convert(DateValue(LocalDate.parse("2024-11-18")), Types.DateType.get()) + assertEquals(LocalDate.parse("2024-11-18"), result) + } + + @Test + fun `convert handles IntegerValue`() { + val result = converter.convert(IntegerValue(123L), Types.LongType.get()) + assertEquals(123L, result) + } + + @Test + fun `convert handles NullValue`() { + val result = converter.convert(NullValue, Types.StringType.get()) + assertNull(result) + } + + @Test + fun `convert handles NumberValue`() { + val result = + converter.convert(NumberValue(BigDecimal.valueOf(123.45)), Types.DoubleType.get()) + assertEquals(123.45, result) + } + + @Test + fun `convert handles StringValue`() { + val result = converter.convert(StringValue("test string"), Types.StringType.get()) + assertEquals("test string", result) + } + + @Test + fun `convert handles TimeNtzValue`() { + val result = + converter.convert( + TimeWithoutTimezoneValue(LocalTime.parse("12:34:56")), + Types.TimeType.get() + ) + assertEquals(LocalTime.parse("12:34:56"), result) + } + + @Test + fun `convert handles TimeTzValue`() { + val result = + converter.convert( + TimeWithTimezoneValue(OffsetTime.parse("12:34:56Z")), + Types.TimeType.get() + ) + // Note LocalTime here. Iceberg+Parquet doesn't have a dedicated timetz type. + assertEquals(LocalTime.parse("12:34:56"), result) + } + + @Test + fun `convert handles TimestampNtzValue`() { + val result = + converter.convert( + TimestampWithoutTimezoneValue(LocalDateTime.parse("2024-11-18T12:34:56")), + Types.TimestampType.withoutZone() + ) + assertEquals(LocalDateTime.parse("2024-11-18T12:34:56"), result) + } + + @Test + fun `convert handles TimestampTzValue`() { + val result = + converter.convert( + TimestampWithTimezoneValue(OffsetDateTime.parse("2024-11-18T12:34:56Z")), + Types.TimestampType.withZone() + ) + assertEquals(OffsetDateTime.parse("2024-11-18T12:34:56Z"), result) + } + + @Test + fun `convert throws exception for UnknownValue`() { + assertThrows { + converter.convert(UnknownValue(Jsons.emptyObject()), Types.StringType.get()) + } + } + + @Test + fun `toIcebergRecord correctly converts ObjectValue to GenericRecord`() { + val schema = + Schema( + NestedField.required(1, "id", Types.LongType.get()), + NestedField.optional(2, "name", Types.StringType.get()), + NestedField.required( + 3, + "meta", + StructType.of( + NestedField.required(4, "sync_id", Types.IntegerType.get()), + NestedField.required( + 5, + "changes", + StructType.of( + NestedField.required(6, "change", Types.StringType.get()), + NestedField.required(7, "reason", Types.StringType.get()), + ) + ) + ) + ) + ) + val objectValue = + ObjectValue( + linkedMapOf( + "id" to IntegerValue(123L), + "name" to StringValue("John Doe"), + "meta" to + ObjectValue( + linkedMapOf( + "sync_id" to IntegerValue(123L), + "changes" to + ObjectValue( + linkedMapOf( + "change" to StringValue("insert"), + "reason" to StringValue("reason"), + ) + ) + ) + ) + ) + ) + + val result = objectValue.toIcebergRecord(schema) + assertEquals(123L, result.getField("id")) + assertEquals("John Doe", result.getField("name")) + assertEquals(123L, (result.getField("meta") as GenericRecord).getField("sync_id") as Long) + assertEquals( + "insert", + ((result.getField("meta") as GenericRecord).getField("changes") as GenericRecord) + .getField("change") + ) + assertEquals( + "reason", + ((result.getField("meta") as GenericRecord).getField("changes") as GenericRecord) + .getField("reason") + ) + } + + @Test + fun `toIcebergRecord ignores fields not in schema`() { + val schema = Schema(NestedField.required(1, "id", Types.LongType.get())) + val objectValue = + ObjectValue( + linkedMapOf( + "id" to IntegerValue(123L), + "name" to StringValue("Should be ignored"), + ) + ) + + val result = objectValue.toIcebergRecord(schema) + assertEquals(123L, result.getField("id")) + assertNull(result.getField("name")) // Not in schema + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/build.gradle b/airbyte-cdk/bulk/toolkits/load-object-storage/build.gradle index aa96859890c5..aee9515324f8 100644 --- a/airbyte-cdk/bulk/toolkits/load-object-storage/build.gradle +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/build.gradle @@ -9,8 +9,19 @@ dependencies { api project(':airbyte-cdk:bulk:toolkits:bulk-cdk-toolkit-load-csv') api project(':airbyte-cdk:bulk:toolkits:bulk-cdk-toolkit-load-parquet') + testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1") + testFixturesImplementation testFixtures(project(":airbyte-cdk:bulk:core:bulk-cdk-core-load")) testFixturesImplementation testFixtures(project(":airbyte-cdk:bulk:toolkits:bulk-cdk-toolkit-load-avro")) testFixturesImplementation testFixtures(project(":airbyte-cdk:bulk:toolkits:bulk-cdk-toolkit-load-csv")) testFixturesImplementation testFixtures(project(":airbyte-cdk:bulk:toolkits:bulk-cdk-toolkit-load-parquet")) } + +project.tasks.matching { + it.name == 'spotbugsIntegrationTestLegacy' || + it.name == 'spotbugsIntegrationTest' || + it.name == 'spotbugsTest' || + it.name == 'spotbugsMain' +}.configureEach { + enabled = false +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/command/object_storage/ObjectStorageCompressionSpecification.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/command/object_storage/ObjectStorageCompressionSpecification.kt index e1a5e6c64f52..7f5761174f4f 100644 --- a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/command/object_storage/ObjectStorageCompressionSpecification.kt +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/command/object_storage/ObjectStorageCompressionSpecification.kt @@ -32,10 +32,10 @@ interface ObjectStorageCompressionSpecificationProvider { "Whether the output files should be compressed. If compression is selected, the output filename will have an extra extension (GZIP: \".jsonl.gz\").", ) @get:JsonProperty("compression") - val compression: ObjectStorageCompressionSpecification + val compression: ObjectStorageCompressionSpecification? fun toCompressionConfiguration(): ObjectStorageCompressionConfiguration<*> { - return when (compression) { + return when (compression ?: NoCompressionSpecification()) { is NoCompressionSpecification -> ObjectStorageCompressionConfiguration(NoopProcessor) is GZIPCompressionSpecification -> ObjectStorageCompressionConfiguration(GZIPProcessor) } diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/command/object_storage/ObjectStorageFormatSpecification.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/command/object_storage/ObjectStorageFormatSpecification.kt index d5b3c35ed859..89ad07a4c289 100644 --- a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/command/object_storage/ObjectStorageFormatSpecification.kt +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/command/object_storage/ObjectStorageFormatSpecification.kt @@ -9,6 +9,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyDescription import com.fasterxml.jackson.annotation.JsonSubTypes import com.fasterxml.jackson.annotation.JsonTypeInfo import com.fasterxml.jackson.annotation.JsonValue +import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaInject import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaTitle import io.airbyte.cdk.load.command.avro.AvroCompressionConfiguration import io.airbyte.cdk.load.command.avro.AvroCompressionConfigurationProvider @@ -36,8 +37,18 @@ interface ObjectStorageFormatSpecificationProvider { fun toObjectStorageFormatConfiguration(): ObjectStorageFormatConfiguration { return when (format) { - is JsonFormatSpecification -> JsonFormatConfiguration() - is CSVFormatSpecification -> CSVFormatConfiguration() + is JsonFormatSpecification -> + JsonFormatConfiguration( + rootLevelFlattening = + (format as JsonFormatSpecification).flattening == + FlatteningSpecificationProvider.Flattening.ROOT_LEVEL_FLATTENING + ) + is CSVFormatSpecification -> + CSVFormatConfiguration( + rootLevelFlattening = + (format as CSVFormatSpecification).flattening == + FlatteningSpecificationProvider.Flattening.ROOT_LEVEL_FLATTENING + ) is AvroFormatSpecification -> AvroFormatConfiguration( avroCompressionConfiguration = @@ -79,8 +90,8 @@ interface ObjectStorageFormatSpecificationProvider { property = "format_type" ) @JsonSubTypes( - JsonSubTypes.Type(value = JsonFormatSpecification::class, name = "JSONL"), JsonSubTypes.Type(value = CSVFormatSpecification::class, name = "CSV"), + JsonSubTypes.Type(value = JsonFormatSpecification::class, name = "JSONL"), JsonSubTypes.Type(value = AvroFormatSpecification::class, name = "Avro"), JsonSubTypes.Type(value = ParquetFormatSpecification::class, name = "Parquet") ) @@ -88,21 +99,22 @@ sealed class ObjectStorageFormatSpecification( @JsonSchemaTitle("Format Type") open val formatType: Type ) { enum class Type(@get:JsonValue val typeName: String) { - JSONL("JSONL"), CSV("CSV"), + JSONL("JSONL"), AVRO("Avro"), PARQUET("Parquet") } } -/** JSONL */ -@JsonSchemaTitle("JSON Lines: Newline-delimited JSON") -class JsonFormatSpecification( - @JsonSchemaTitle("Format Type") - @JsonProperty("format_type") - override val formatType: Type = Type.JSONL -) : ObjectStorageFormatSpecification(formatType), ObjectStorageCompressionSpecificationProvider { - override val compression: ObjectStorageCompressionSpecification = NoCompressionSpecification() +interface FlatteningSpecificationProvider { + @get:JsonSchemaTitle("Flattening") + @get:JsonProperty("flattening", defaultValue = "No flattening") + val flattening: Flattening? + + enum class Flattening(@get:JsonValue val flatteningName: String) { + NO_FLATTENING("No flattening"), + ROOT_LEVEL_FLATTENING("Root level flattening") + } } /** CSV */ @@ -111,8 +123,30 @@ class CSVFormatSpecification( @JsonSchemaTitle("Format Type") @JsonProperty("format_type") override val formatType: Type = Type.CSV -) : ObjectStorageFormatSpecification(formatType), ObjectStorageCompressionSpecificationProvider { - override val compression: ObjectStorageCompressionSpecification = NoCompressionSpecification() +) : + ObjectStorageFormatSpecification(formatType), + FlatteningSpecificationProvider, + ObjectStorageCompressionSpecificationProvider { + override val flattening: FlatteningSpecificationProvider.Flattening = + FlatteningSpecificationProvider.Flattening.NO_FLATTENING + override val compression: ObjectStorageCompressionSpecification? = + GZIPCompressionSpecification() +} + +/** JSONL */ +@JsonSchemaTitle("JSON Lines: Newline-delimited JSON") +class JsonFormatSpecification( + @JsonSchemaTitle("Format Type") + @JsonProperty("format_type") + override val formatType: Type = Type.JSONL +) : + ObjectStorageFormatSpecification(formatType), + FlatteningSpecificationProvider, + ObjectStorageCompressionSpecificationProvider { + override val flattening: FlatteningSpecificationProvider.Flattening? = + FlatteningSpecificationProvider.Flattening.NO_FLATTENING + override val compression: ObjectStorageCompressionSpecification? = + GZIPCompressionSpecification() } /** AVRO */ @@ -120,6 +154,7 @@ class CSVFormatSpecification( class AvroFormatSpecification( @JsonSchemaTitle("Format Type") @JsonProperty("format_type") + @JsonSchemaInject(json = """{"order":0}""") override val formatType: Type = Type.AVRO ) : ObjectStorageFormatSpecification(formatType) { @@ -128,6 +163,7 @@ class AvroFormatSpecification( "The compression algorithm used to compress data. Default to no compression." ) @JsonProperty("compression_codec") + @JsonSchemaInject(json = """{"order":1}""") val compressionCodec: AvroFormatCompressionCodecSpecification = AvroFormatNoCompressionCodecSpecification() } @@ -151,7 +187,7 @@ class ParquetFormatSpecification( @JsonSchemaTitle("Compression Codec") @JsonPropertyDescription("The compression algorithm used to compress data pages.") - @JsonProperty("compression_codec") + @JsonProperty("compression_codec", defaultValue = "UNCOMPRESSED") val compressionCodec: ParquetFormatCompressionCodec? = ParquetFormatCompressionCodec.UNCOMPRESSED @@ -159,28 +195,28 @@ class ParquetFormatSpecification( @JsonPropertyDescription( "This is the size of a row group being buffered in memory. It limits the memory usage when writing. Larger values will improve the IO when reading, but consume more memory when writing. Default: 128 MB." ) - @JsonProperty("block_size_mb") + @JsonProperty("block_size_mb", defaultValue = "128") val blockSizeMb: Int? = 128 @JsonSchemaTitle("Max Padding Size (MB)") @JsonPropertyDescription( "Maximum size allowed as padding to align row groups. This is also the minimum size of a row group. Default: 8 MB." ) - @JsonProperty("max_padding_size_mb") + @JsonProperty("max_padding_size_mb", defaultValue = "8") val maxPaddingSizeMb: Int? = 8 @JsonSchemaTitle("Page Size (KB)") @JsonPropertyDescription( "The page size is for compression. A block is composed of pages. A page is the smallest unit that must be read fully to access a single record. If this value is too small, the compression will deteriorate. Default: 1024 KB." ) - @JsonProperty("page_size_kb") + @JsonProperty("page_size_kb", defaultValue = "1024") val pageSizeKb: Int? = 1024 @JsonSchemaTitle("Dictionary Page Size (KB)") @JsonPropertyDescription( "There is one dictionary page per column per row group when dictionary encoding is used. The dictionary page size works like the page size but for dictionary. Default: 1024 KB." ) - @JsonProperty("dictionary_page_size_kb") + @JsonProperty("dictionary_page_size_kb", defaultValue = "1024") val dictionaryPageSizeKb: Int? = 1024 @JsonSchemaTitle("Dictionary Encoding") @@ -196,23 +232,32 @@ interface OutputFormatConfigurationProvider { sealed interface ObjectStorageFormatConfiguration { val extension: String + val rootLevelFlattening: Boolean } -data class JsonFormatConfiguration(override val extension: String = "jsonl") : - ObjectStorageFormatConfiguration +data class JsonFormatConfiguration( + override val extension: String = "jsonl", + override val rootLevelFlattening: Boolean = false +) : ObjectStorageFormatConfiguration {} -data class CSVFormatConfiguration(override val extension: String = "csv") : - ObjectStorageFormatConfiguration +data class CSVFormatConfiguration( + override val extension: String = "csv", + override val rootLevelFlattening: Boolean = false +) : ObjectStorageFormatConfiguration {} data class AvroFormatConfiguration( override val extension: String = "avro", override val avroCompressionConfiguration: AvroCompressionConfiguration, -) : ObjectStorageFormatConfiguration, AvroCompressionConfigurationProvider +) : ObjectStorageFormatConfiguration, AvroCompressionConfigurationProvider { + override val rootLevelFlattening: Boolean = true // Always flatten avro +} data class ParquetFormatConfiguration( override val extension: String = "parquet", override val parquetWriterConfiguration: ParquetWriterConfiguration -) : ObjectStorageFormatConfiguration, ParquetWriterConfigurationProvider +) : ObjectStorageFormatConfiguration, ParquetWriterConfigurationProvider { + override val rootLevelFlattening: Boolean = true // Always flatten parquet +} interface ObjectStorageFormatConfigurationProvider { val objectStorageFormatConfiguration: ObjectStorageFormatConfiguration diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/command/object_storage/ObjectStoragePathConfiguration.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/command/object_storage/ObjectStoragePathConfiguration.kt index 16c5874e28b1..f9a9c6b915a7 100644 --- a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/command/object_storage/ObjectStoragePathConfiguration.kt +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/command/object_storage/ObjectStoragePathConfiguration.kt @@ -8,7 +8,8 @@ data class ObjectStoragePathConfiguration( val prefix: String, val stagingPrefix: String?, val pathSuffixPattern: String?, - val fileNamePattern: String? + val fileNamePattern: String?, + val usesStagingDirectory: Boolean ) interface ObjectStoragePathConfigurationProvider { diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/command/object_storage/ObjectStorageUploadConfiguration.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/command/object_storage/ObjectStorageUploadConfiguration.kt index d868ca1c9e9c..4d17e736239e 100644 --- a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/command/object_storage/ObjectStorageUploadConfiguration.kt +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/command/object_storage/ObjectStorageUploadConfiguration.kt @@ -4,7 +4,15 @@ package io.airbyte.cdk.load.command.object_storage -data class ObjectStorageUploadConfiguration(val streamingUploadPartSize: Long) +data class ObjectStorageUploadConfiguration( + val fileSizeBytes: Long = DEFAULT_FILE_SIZE_BYTES, + val uploadPartSizeBytes: Long = DEFAULT_PART_SIZE_BYTES, +) { + companion object { + const val DEFAULT_PART_SIZE_BYTES: Long = 10 * 1024 * 1024 // File xfer is still using it + const val DEFAULT_FILE_SIZE_BYTES: Long = 200 * 1024 * 1024 + } +} interface ObjectStorageUploadConfigurationProvider { val objectStorageUploadConfiguration: ObjectStorageUploadConfiguration diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStorageClient.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStorageClient.kt index 099d5979a261..633691bea678 100644 --- a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStorageClient.kt +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStorageClient.kt @@ -4,7 +4,6 @@ package io.airbyte.cdk.load.file.object_storage -import io.airbyte.cdk.load.file.NoopProcessor import io.airbyte.cdk.load.file.StreamProcessor import java.io.InputStream import java.io.OutputStream @@ -13,9 +12,12 @@ import kotlinx.coroutines.flow.Flow interface ObjectStorageClient> { suspend fun list(prefix: String): Flow suspend fun move(remoteObject: T, toKey: String): T + suspend fun move(key: String, toKey: String): T suspend fun get(key: String, block: (InputStream) -> U): U + suspend fun getMetadata(key: String): Map suspend fun put(key: String, bytes: ByteArray): T suspend fun delete(remoteObject: T) + suspend fun delete(key: String) /** * Streaming upload should provide an [OutputStream] managed within the lifecycle of [block]. @@ -24,11 +26,34 @@ interface ObjectStorageClient> { * files). Specifically, the method should guarantee that no operations will be performed on the * stream after [block] completes. */ - suspend fun streamingUpload(key: String, block: suspend (OutputStream) -> Unit): T = - streamingUpload(key, NoopProcessor, block) suspend fun streamingUpload( key: String, - streamProcessor: StreamProcessor, + metadata: Map = emptyMap(), + streamProcessor: StreamProcessor? = null, block: suspend (OutputStream) -> Unit ): T + + /** Experimental sane replacement interface */ + suspend fun startStreamingUpload( + key: String, + metadata: Map = emptyMap() + ): StreamingUpload +} + +interface StreamingUpload> { + /** + * Uploads a part of the object. Each part must have a unique index. The parts do not need to be + * uploaded in order. The index is 1-based. + */ + suspend fun uploadPart(part: ByteArray, index: Int) + + /** + * Completes a multipart upload. All parts must be uploaded before completing the upload, and + * there cannot be gaps in the indexes. Idempotent, Multiple calls will return the same object, + * but only the first call will have side effects. + * + * NOTE: If no parts were uploaded, it will skip the complete call but still return the object. + * This is a temporary hack to support empty files. + */ + suspend fun complete(): T } diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStorageFormattingWriter.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStorageFormattingWriter.kt index 99a97afa7e17..286e302fcbcc 100644 --- a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStorageFormattingWriter.kt +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStorageFormattingWriter.kt @@ -8,47 +8,61 @@ import io.airbyte.cdk.load.command.DestinationStream import io.airbyte.cdk.load.command.object_storage.AvroFormatConfiguration import io.airbyte.cdk.load.command.object_storage.CSVFormatConfiguration import io.airbyte.cdk.load.command.object_storage.JsonFormatConfiguration +import io.airbyte.cdk.load.command.object_storage.ObjectStorageCompressionConfigurationProvider import io.airbyte.cdk.load.command.object_storage.ObjectStorageFormatConfigurationProvider import io.airbyte.cdk.load.command.object_storage.ParquetFormatConfiguration -import io.airbyte.cdk.load.data.DestinationRecordToAirbyteValueWithMeta +import io.airbyte.cdk.load.data.ObjectType +import io.airbyte.cdk.load.data.avro.AvroMapperPipelineFactory import io.airbyte.cdk.load.data.avro.toAvroRecord import io.airbyte.cdk.load.data.avro.toAvroSchema import io.airbyte.cdk.load.data.csv.toCsvRecord +import io.airbyte.cdk.load.data.dataWithAirbyteMeta import io.airbyte.cdk.load.data.json.toJson +import io.airbyte.cdk.load.data.parquet.ParquetMapperPipelineFactory +import io.airbyte.cdk.load.data.withAirbyteMeta +import io.airbyte.cdk.load.file.StreamProcessor import io.airbyte.cdk.load.file.avro.toAvroWriter import io.airbyte.cdk.load.file.csv.toCsvPrinterWithHeader +import io.airbyte.cdk.load.file.parquet.ParquetWriter import io.airbyte.cdk.load.file.parquet.toParquetWriter -import io.airbyte.cdk.load.message.DestinationRecord +import io.airbyte.cdk.load.message.DestinationRecordAirbyteValue import io.airbyte.cdk.load.util.serializeToString import io.airbyte.cdk.load.util.write +import io.github.oshai.kotlinlogging.KotlinLogging import io.micronaut.context.annotation.Secondary import jakarta.inject.Singleton +import java.io.ByteArrayOutputStream import java.io.Closeable import java.io.OutputStream +import java.util.concurrent.atomic.AtomicLong +import org.apache.avro.Schema interface ObjectStorageFormattingWriter : Closeable { - fun accept(record: DestinationRecord) + fun accept(record: DestinationRecordAirbyteValue) + fun flush() } @Singleton @Secondary class ObjectStorageFormattingWriterFactory( - private val recordDecorator: DestinationRecordToAirbyteValueWithMeta, private val formatConfigProvider: ObjectStorageFormatConfigurationProvider, ) { fun create( stream: DestinationStream, outputStream: OutputStream ): ObjectStorageFormattingWriter { + val flatten = formatConfigProvider.objectStorageFormatConfiguration.rootLevelFlattening + // TODO: FileWriter + return when (formatConfigProvider.objectStorageFormatConfiguration) { - is JsonFormatConfiguration -> JsonFormattingWriter(outputStream, recordDecorator) + is JsonFormatConfiguration -> JsonFormattingWriter(stream, outputStream, flatten) is AvroFormatConfiguration -> AvroFormattingWriter( stream, outputStream, formatConfigProvider.objectStorageFormatConfiguration as AvroFormatConfiguration, - recordDecorator + flatten ) is ParquetFormatConfiguration -> ParquetFormattingWriter( @@ -56,19 +70,28 @@ class ObjectStorageFormattingWriterFactory( outputStream, formatConfigProvider.objectStorageFormatConfiguration as ParquetFormatConfiguration, - recordDecorator + flatten ) - is CSVFormatConfiguration -> CSVFormattingWriter(stream, outputStream, recordDecorator) + is CSVFormatConfiguration -> CSVFormattingWriter(stream, outputStream, flatten) } } } class JsonFormattingWriter( + private val stream: DestinationStream, private val outputStream: OutputStream, - private val recordDecorator: DestinationRecordToAirbyteValueWithMeta + private val rootLevelFlattening: Boolean, ) : ObjectStorageFormattingWriter { - override fun accept(record: DestinationRecord) { - outputStream.write(recordDecorator.decorate(record).toJson().serializeToString()) + + override fun accept(record: DestinationRecordAirbyteValue) { + val data = + record.dataWithAirbyteMeta(stream, rootLevelFlattening).toJson().serializeToString() + outputStream.write(data) + outputStream.write("\n") + } + + override fun flush() { + outputStream.flush() } override fun close() { @@ -77,30 +100,54 @@ class JsonFormattingWriter( } class CSVFormattingWriter( - stream: DestinationStream, + private val stream: DestinationStream, outputStream: OutputStream, - private val recordDecorator: DestinationRecordToAirbyteValueWithMeta + private val rootLevelFlattening: Boolean ) : ObjectStorageFormattingWriter { - private val printer = stream.schemaWithMeta.toCsvPrinterWithHeader(outputStream) - override fun accept(record: DestinationRecord) { - printer.printRecord(*recordDecorator.decorate(record).toCsvRecord()) + + private val finalSchema = stream.schema.withAirbyteMeta(rootLevelFlattening) + private val printer = finalSchema.toCsvPrinterWithHeader(outputStream) + override fun accept(record: DestinationRecordAirbyteValue) { + printer.printRecord( + record.dataWithAirbyteMeta(stream, rootLevelFlattening).toCsvRecord(finalSchema) + ) + } + + override fun flush() { + printer.flush() } + override fun close() { printer.close() } } class AvroFormattingWriter( - stream: DestinationStream, + private val stream: DestinationStream, outputStream: OutputStream, formatConfig: AvroFormatConfiguration, - private val recordDecorator: DestinationRecordToAirbyteValueWithMeta + private val rootLevelFlattening: Boolean, ) : ObjectStorageFormattingWriter { - private val avroSchema = stream.schemaWithMeta.toAvroSchema(stream.descriptor) + val log = KotlinLogging.logger {} + + private val pipeline = AvroMapperPipelineFactory().create(stream) + private val mappedSchema = pipeline.finalSchema.withAirbyteMeta(rootLevelFlattening) + private val avroSchema = mappedSchema.toAvroSchema(stream.descriptor) private val writer = outputStream.toAvroWriter(avroSchema, formatConfig.avroCompressionConfiguration) - override fun accept(record: DestinationRecord) { - writer.write(recordDecorator.decorate(record).toAvroRecord(avroSchema)) + + init { + log.info { "Generated avro schema: $avroSchema" } + } + + override fun accept(record: DestinationRecordAirbyteValue) { + val dataMapped = pipeline.map(record.data, record.meta?.changes) + val withMeta = dataMapped.withAirbyteMeta(stream, record.emittedAtMs, rootLevelFlattening) + writer.write(withMeta.toAvroRecord(mappedSchema, avroSchema)) + } + + override fun flush() { + writer.flush() } override fun close() { @@ -109,16 +156,101 @@ class AvroFormattingWriter( } class ParquetFormattingWriter( - stream: DestinationStream, + private val stream: DestinationStream, outputStream: OutputStream, formatConfig: ParquetFormatConfiguration, - private val recordDecorator: DestinationRecordToAirbyteValueWithMeta + private val rootLevelFlattening: Boolean, ) : ObjectStorageFormattingWriter { - private val avroSchema = stream.schemaWithMeta.toAvroSchema(stream.descriptor) - private val writer = + private val log = KotlinLogging.logger {} + + private val pipeline = ParquetMapperPipelineFactory().create(stream) + private val mappedSchema: ObjectType = pipeline.finalSchema.withAirbyteMeta(rootLevelFlattening) + private val avroSchema: Schema = mappedSchema.toAvroSchema(stream.descriptor) + private val writer: ParquetWriter = outputStream.toParquetWriter(avroSchema, formatConfig.parquetWriterConfiguration) - override fun accept(record: DestinationRecord) { - writer.write(recordDecorator.decorate(record).toAvroRecord(avroSchema)) + + init { + log.info { "Generated avro schema: $avroSchema" } + } + + override fun accept(record: DestinationRecordAirbyteValue) { + val dataMapped = pipeline.map(record.data, record.meta?.changes) + val withMeta = dataMapped.withAirbyteMeta(stream, record.emittedAtMs, rootLevelFlattening) + writer.write(withMeta.toAvroRecord(mappedSchema, avroSchema)) + } + + override fun flush() { + // Parquet writer does not support flushing + } + + override fun close() { + writer.close() + } +} + +@Singleton +@Secondary +class BufferedFormattingWriterFactory( + private val writerFactory: ObjectStorageFormattingWriterFactory, + private val compressionConfigurationProvider: ObjectStorageCompressionConfigurationProvider, +) { + fun create(stream: DestinationStream): BufferedFormattingWriter { + val outputStream = ByteArrayOutputStream() + val processor = + compressionConfigurationProvider.objectStorageCompressionConfiguration.compressor + val wrappingBuffer = processor.wrapper.invoke(outputStream) + val writer = writerFactory.create(stream, wrappingBuffer) + return BufferedFormattingWriter(writer, outputStream, processor, wrappingBuffer) + } +} + +class BufferedFormattingWriter( + private val writer: ObjectStorageFormattingWriter, + private val buffer: ByteArrayOutputStream, + private val streamProcessor: StreamProcessor, + private val wrappingBuffer: T +) : ObjectStorageFormattingWriter { + // An empty buffer is not a guarantee of a non-empty + // file, some writers (parquet) start with a + // header. Avoid writing empty files by requiring + // both 0 bytes AND 0 rows. + private val rowsAdded = AtomicLong(0) + val bufferSize: Int + get() = + if (rowsAdded.get() == 0L) { + 0 + } else buffer.size() + + override fun accept(record: DestinationRecordAirbyteValue) { + writer.accept(record) + rowsAdded.incrementAndGet() + } + + fun takeBytes(): ByteArray? { + wrappingBuffer.flush() + if (bufferSize == 0) { + return null + } + + val bytes = buffer.toByteArray() + buffer.reset() + return bytes + } + + fun finish(): ByteArray? { + writer.flush() + writer.close() + streamProcessor.partFinisher.invoke(wrappingBuffer) + return if (bufferSize > 0) { + buffer.toByteArray() + } else { + null + } + } + + override fun flush() { + writer.flush() + wrappingBuffer.flush() } override fun close() { diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStoragePathFactory.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStoragePathFactory.kt index c7f051dede0b..36b1d9778a26 100644 --- a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStoragePathFactory.kt +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStoragePathFactory.kt @@ -8,11 +8,11 @@ import io.airbyte.cdk.load.command.DestinationStream import io.airbyte.cdk.load.command.object_storage.ObjectStorageCompressionConfigurationProvider import io.airbyte.cdk.load.command.object_storage.ObjectStorageFormatConfigurationProvider import io.airbyte.cdk.load.command.object_storage.ObjectStoragePathConfigurationProvider +import io.airbyte.cdk.load.data.Transformations import io.airbyte.cdk.load.file.DefaultTimeProvider import io.airbyte.cdk.load.file.TimeProvider import io.micronaut.context.annotation.Secondary import jakarta.inject.Singleton -import java.nio.file.Path import java.nio.file.Paths import java.time.Instant import java.time.ZoneId @@ -20,16 +20,55 @@ import java.time.ZonedDateTime import java.time.format.DateTimeFormatter import java.util.* +interface PathFactory { + fun getLongestStreamConstantPrefix(stream: DestinationStream, isStaging: Boolean): String + fun getStagingDirectory( + stream: DestinationStream, + substituteStreamAndNamespaceOnly: Boolean = false + ): String + fun getFinalDirectory( + stream: DestinationStream, + substituteStreamAndNamespaceOnly: Boolean = false + ): String + fun getPathToFile( + stream: DestinationStream, + partNumber: Long?, + isStaging: Boolean = false, + extension: String? = null + ): String + fun getPathMatcher(stream: DestinationStream, suffixPattern: String? = null): PathMatcher + + val supportsStaging: Boolean + val prefix: String +} + +data class PathMatcher(val regex: Regex, val variableToIndex: Map) { + fun match(path: String): PathMatcherResult? { + val match = regex.matchEntire(path) ?: return null + return PathMatcherResult( + path, + variableToIndex["part_number"]?.let { match.groupValues[it].toLong() }, + variableToIndex["suffix"]?.let { match.groupValues[it].let { g -> g.ifBlank { null } } } + ) + } +} + +data class PathMatcherResult(val path: String, val partNumber: Long?, val customSuffix: String?) + @Singleton @Secondary class ObjectStoragePathFactory( pathConfigProvider: ObjectStoragePathConfigurationProvider, formatConfigProvider: ObjectStorageFormatConfigurationProvider? = null, compressionConfigProvider: ObjectStorageCompressionConfigurationProvider<*>? = null, - timeProvider: TimeProvider, -) { - private val loadedAt = timeProvider.let { Instant.ofEpochMilli(it.currentTimeMillis()) } + private val timeProvider: TimeProvider, +) : PathFactory { private val pathConfig = pathConfigProvider.objectStoragePathConfiguration + private val stagingPrefixResolved = + pathConfig.stagingPrefix + ?: Paths.get(pathConfig.prefix, DEFAULT_STAGING_PREFIX_SUFFIX).toString() + private val pathPatternResolved = pathConfig.pathSuffixPattern ?: DEFAULT_PATH_FORMAT + private val filePatternResolved = pathConfig.fileNamePattern ?: DEFAULT_FILE_FORMAT private val fileFormatExtension = formatConfigProvider?.objectStorageFormatConfiguration?.extension private val compressionExtension = @@ -41,15 +80,56 @@ class ObjectStoragePathFactory( fileFormatExtension ?: compressionExtension } + private val stagingPrefix: String + get() = + if (!pathConfig.usesStagingDirectory) { + throw UnsupportedOperationException( + "Staging is not supported by this configuration" + ) + } else { + stagingPrefixResolved + } + + override val supportsStaging: Boolean = pathConfig.usesStagingDirectory + override val prefix: String = + if (pathConfig.prefix.endsWith('/')) { + pathConfig.prefix.take(pathConfig.prefix.length - 1) + } else { + pathConfig.prefix + } + + /** + * Variable substitution is complex. + * + * 1. There are two types: path variables and file name variables. + * 2. Path variables use the ${NAME} syntax, while file name variables use the {name} syntax. (I + * have no idea why this is.) + * 3. A variable is defined by a [Variable.pattern] and a [Variable.provider] + * 4. [Variable.provider] is a function that takes a [VariableContext] and returns a string. + * It's used for substitution to get the actual path. + * 5. [Variable.pattern] is a regex pattern that can match any results of [Variable.provider]. + * 6. If [Variable.pattern] is null, [Variable.provider] is used to get the value. (Ie, we won't + * match against a pattern, but always against the realized value. In practice this is for + * stream name and namespace, because matching always performed at the stream level.) + * 7. Matching should be considered deprecated. It is only required for configurations that do + * not enable staging, which populate destination state by collecting metadata from object + * headers. It is extremely brittle and can break against malformed paths or paths that do not + * include enough variables to avoid clashes. If you run into a client issue which requires a + * path change anyway (a breaking change for some workflows), consider advising them to enable + * staging. + */ inner class VariableContext( val stream: DestinationStream, - val time: Instant = loadedAt, + val syncTime: Instant = Instant.ofEpochMilli(timeProvider.syncTimeMillis()), + val currentTimeProvider: TimeProvider = timeProvider, val extension: String? = null, val partNumber: Long? = null ) interface Variable { + val pattern: String? val provider: (VariableContext) -> String + fun toMacro(): String fun maybeApply(source: String, context: VariableContext): String { val macro = toMacro() @@ -62,14 +142,16 @@ class ObjectStoragePathFactory( data class PathVariable( val variable: String, - override val provider: (VariableContext) -> String + override val pattern: String? = null, + override val provider: (VariableContext) -> String, ) : Variable { override fun toMacro(): String = "\${$variable}" } data class FileVariable( val variable: String, - override val provider: (VariableContext) -> String + override val pattern: String? = null, + override val provider: (VariableContext) -> String, ) : Variable { override fun toMacro(): String = "{$variable}" } @@ -84,55 +166,78 @@ class ObjectStoragePathFactory( const val DEFAULT_FILE_FORMAT = "{part_number}{format_extension}" val PATH_VARIABLES = listOf( - PathVariable("NAMESPACE") { it.stream.descriptor.namespace ?: "" }, - PathVariable("STREAM_NAME") { it.stream.descriptor.name }, - PathVariable("YEAR") { - ZonedDateTime.ofInstant(it.time, ZoneId.of("UTC")).year.toString() + PathVariable("NAMESPACE") { + Transformations.toS3SafeCharacters(it.stream.descriptor.namespace ?: "") + }, + PathVariable("STREAM_NAME") { + Transformations.toS3SafeCharacters(it.stream.descriptor.name) }, - PathVariable("MONTH") { + PathVariable("YEAR", """\d{4}""") { + ZonedDateTime.ofInstant(it.syncTime, ZoneId.of("UTC")).year.toString() + }, + PathVariable("MONTH", """\d{2}""") { String.format( "%02d", - ZonedDateTime.ofInstant(it.time, ZoneId.of("UTC")).monthValue + ZonedDateTime.ofInstant(it.syncTime, ZoneId.of("UTC")).monthValue ) }, - PathVariable("DAY") { + PathVariable("DAY", """\d{2}""") { String.format( "%02d", - ZonedDateTime.ofInstant(it.time, ZoneId.of("UTC")).dayOfMonth + ZonedDateTime.ofInstant(it.syncTime, ZoneId.of("UTC")).dayOfMonth ) }, - PathVariable("HOUR") { - String.format("%02d", ZonedDateTime.ofInstant(it.time, ZoneId.of("UTC")).hour) + PathVariable("HOUR", """\d{2}""") { + String.format( + "%02d", + ZonedDateTime.ofInstant(it.syncTime, ZoneId.of("UTC")).hour + ) }, - PathVariable("MINUTE") { - String.format("%02d", ZonedDateTime.ofInstant(it.time, ZoneId.of("UTC")).minute) + PathVariable("MINUTE", """\d{2}""") { + String.format( + "%02d", + ZonedDateTime.ofInstant(it.syncTime, ZoneId.of("UTC")).minute + ) }, - PathVariable("SECOND") { - String.format("%02d", ZonedDateTime.ofInstant(it.time, ZoneId.of("UTC")).second) + PathVariable("SECOND", """\d{2}""") { + String.format( + "%02d", + ZonedDateTime.ofInstant(it.syncTime, ZoneId.of("UTC")).second + ) }, - PathVariable("MILLISECOND") { + PathVariable("MILLISECOND", """\d{4}""") { // Unclear why this is %04d, but that's what it was in the old code String.format( "%04d", - ZonedDateTime.ofInstant(it.time, ZoneId.of("UTC")) + ZonedDateTime.ofInstant(it.syncTime, ZoneId.of("UTC")) .toLocalTime() .toNanoOfDay() / 1_000_000 % 1_000 ) }, - PathVariable("EPOCH") { it.time.toEpochMilli().toString() }, - PathVariable("UUID") { UUID.randomUUID().toString() } + PathVariable("EPOCH", """\d+""") { it.syncTime.toEpochMilli().toString() }, + PathVariable("UUID", """[a-fA-F0-9\\-]{36}""") { UUID.randomUUID().toString() } ) + val PATH_VARIABLES_STREAM_CONSTANT = + PATH_VARIABLES.filter { it.variable == "NAMESPACE" || it.variable == "STREAM_NAME" } val FILENAME_VARIABLES = listOf( - FileVariable("date") { DATE_FORMATTER.format(it.time) }, - FileVariable("timestamp") { it.time.toEpochMilli().toString() }, - FileVariable("part_number") { + FileVariable("date", """\d{4}_\d{2}_\d{2}""") { + DATE_FORMATTER.format(it.syncTime) + }, + FileVariable("date:yyyy_MM", """\d{4}_\d{2}""") { + DATE_FORMATTER.format(it.syncTime).substring(0, 7) + }, + FileVariable("timestamp", """\d+""") { + // NOTE: We use a constant time for the path but wall time for the files + it.currentTimeProvider.currentTimeMillis().toString() + }, + FileVariable("part_number", """\d+""") { it.partNumber?.toString() ?: throw IllegalArgumentException( "part_number is required when {part_number} is present" ) }, - FileVariable("sync_id") { it.stream.syncId.toString() }, + FileVariable("sync_id", """\d+""") { it.stream.syncId.toString() }, FileVariable("format_extension") { it.extension?.let { ext -> ".$ext" } ?: "" } ) @@ -147,46 +252,158 @@ class ObjectStoragePathFactory( } } - fun getStagingDirectory(stream: DestinationStream): Path { - val prefix = - pathConfig.stagingPrefix - ?: Paths.get(pathConfig.prefix, DEFAULT_STAGING_PREFIX_SUFFIX).toString() - val path = getFormattedPath(stream) - return Paths.get(prefix, path) + private fun resolveRetainingTerminalSlash(prefix: String, path: String): String { + val asPath = Paths.get(prefix, path) + return if (path.endsWith('/')) { + asPath.toString() + "/" + } else { + asPath.toString() + } } - fun getFinalDirectory(stream: DestinationStream): Path { - val path = getFormattedPath(stream) - return Paths.get(pathConfig.prefix, path) + override fun getStagingDirectory( + stream: DestinationStream, + substituteStreamAndNamespaceOnly: Boolean + ): String { + val path = + getFormattedPath( + stream, + if (substituteStreamAndNamespaceOnly) PATH_VARIABLES_STREAM_CONSTANT + else PATH_VARIABLES + ) + return resolveRetainingTerminalSlash(stagingPrefix, path) } - fun getPathToFile( + override fun getFinalDirectory( stream: DestinationStream, - partNumber: Long?, - isStaging: Boolean = false, - extension: String? = defaultExtension - ): Path { + substituteStreamAndNamespaceOnly: Boolean + ): String { val path = - if (isStaging) { - getStagingDirectory(stream) + getFormattedPath( + stream, + if (substituteStreamAndNamespaceOnly) PATH_VARIABLES_STREAM_CONSTANT + else PATH_VARIABLES + ) + return resolveRetainingTerminalSlash(prefix, path) + } + + override fun getLongestStreamConstantPrefix( + stream: DestinationStream, + isStaging: Boolean + ): String { + return if (isStaging) { + getStagingDirectory(stream, substituteStreamAndNamespaceOnly = true) } else { - getFinalDirectory(stream) + getFinalDirectory(stream, substituteStreamAndNamespaceOnly = true) } - val context = VariableContext(stream, extension = extension, partNumber = partNumber) + .takeWhile { it != '$' } + } + + override fun getPathToFile( + stream: DestinationStream, + partNumber: Long?, + isStaging: Boolean, + extension: String? + ): String { + val extensionResolved = extension ?: defaultExtension + val path = + if (isStaging) { + getStagingDirectory(stream) + } else { + getFinalDirectory(stream) + } + .toString() + val context = + VariableContext(stream, extension = extensionResolved, partNumber = partNumber) val fileName = getFormattedFileName(context) - return path.resolve(fileName) + // NOTE: The old code does not actually resolve the path + filename, even tho the + // documentation says it does. + return "$path$fileName" } - private fun getFormattedPath(stream: DestinationStream): String { - val pattern = pathConfig.pathSuffixPattern ?: DEFAULT_PATH_FORMAT + private fun getFormattedPath( + stream: DestinationStream, + variables: List = PATH_VARIABLES + ): String { + val pattern = pathPatternResolved val context = VariableContext(stream) - return PATH_VARIABLES.fold(pattern) { acc, variable -> variable.maybeApply(acc, context) } + return variables.fold(pattern) { acc, variable -> variable.maybeApply(acc, context) } } private fun getFormattedFileName(context: VariableContext): String { - val pattern = pathConfig.fileNamePattern ?: DEFAULT_FILE_FORMAT + val pattern = filePatternResolved return FILENAME_VARIABLES.fold(pattern) { acc, variable -> variable.maybeApply(acc, context) } } + + private fun getPathVariableToPattern(stream: DestinationStream): Map { + return PATH_VARIABLES.associate { + it.variable to (it.pattern ?: it.provider(VariableContext(stream))) + } + + FILENAME_VARIABLES.associate { + it.variable to + (it.pattern + ?: it.provider(VariableContext(stream, extension = defaultExtension))) + } + } + + private fun buildPattern( + input: String, + macroPattern: String, + variableToPattern: Map, + variableToIndex: MutableMap + ): String { + return Regex.escapeReplacement(input).replace(macroPattern.toRegex()) { + val variable = it.groupValues[1] + val pattern = variableToPattern[variable] + if (pattern == null) { + variable + } else if (pattern.isBlank()) { + // This should only happen in the case of a blank namespace. + // This is to avoid inserting `()` and then trying to match + // `()/($streamName)` against `$streamName`. + "" + } else { + variableToIndex[variable] = variableToIndex.size + 1 + "($pattern)" + } + } + } + + override fun getPathMatcher(stream: DestinationStream, suffixPattern: String?): PathMatcher { + val pathVariableToPattern = getPathVariableToPattern(stream) + val variableToIndex = mutableMapOf() + + val replacedForPath = + buildPattern( + pathPatternResolved, + """\\\$\{(\w+)}""", + pathVariableToPattern, + variableToIndex + ) + val replacedForFile = + buildPattern( + filePatternResolved, + """\{([\w\:]+)}""", + pathVariableToPattern, + variableToIndex + ) + // NOTE the old code does not actually resolve the path + filename, + // even tho the documentation says it does. + val combined = + if (replacedForPath.startsWith('/')) { + "${prefix}$replacedForPath$replacedForFile" + } else { + "$prefix/$replacedForPath$replacedForFile" + } + val withSuffix = + if (suffixPattern != null) { + variableToIndex["suffix"] = variableToIndex.size + 1 + "$combined$suffixPattern" + } else { + combined + } + return PathMatcher(Regex(withSuffix), variableToIndex) + } } diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/file/object_storage/PartFactory.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/file/object_storage/PartFactory.kt new file mode 100644 index 000000000000..e8c09b56f0ab --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/file/object_storage/PartFactory.kt @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.file.object_storage + +import java.util.concurrent.atomic.AtomicReference +import org.apache.mina.util.ConcurrentHashSet + +/** + * Generates part w/ metadata for a multi-part upload for a given key and file no. parts are + * 1-indexed. For convenience, empty parts are tolerated but not counted by the assembler. + * + * Not thread-safe. It is expected that the parts are generated in order. + */ +class PartFactory( + val key: String, + val fileNumber: Long, +) { + var totalSize: Long = 0 + private var nextIndex: Int = 0 + private var finalProduced = false + + fun nextPart(bytes: ByteArray?, isFinal: Boolean = false): Part { + if (finalProduced) { + throw IllegalStateException("Final part already produced") + } + finalProduced = isFinal + + totalSize += bytes?.size?.toLong() ?: 0 + // Only advance the index if the part isn't empty. + // This way empty parts can be ignored, but empty final parts + // can still convey the final index. + if (bytes != null) { + nextIndex++ // pre-increment as parts are 1-indexed + } + return Part( + key = key, + fileNumber = fileNumber, + partIndex = nextIndex, + bytes = bytes, + isFinal = isFinal + ) + } +} + +/** + * Reassembles part metadata into a view of the upload state. + * + * Usage: add the parts created by the factory. + * + * [PartBookkeeper.isComplete] will be true when all the parts AND the final part have been seen, + * regardless of the order in which they were added. + * + * Thread-safe: parts can be added by multiple threads in any order. + */ +data class Part( + val key: String, + val fileNumber: Long, + val partIndex: Int, + val bytes: ByteArray?, + val isFinal: Boolean, +) { + val isEmpty: Boolean + get() = bytes == null +} + +class PartBookkeeper { + private val partIndexes = ConcurrentHashSet() + private var finalIndex = AtomicReference(null) + + val isEmpty: Boolean + get() = partIndexes.isEmpty() + + fun add(part: Part) { + // Only add non-empty parts + if (part.bytes != null) { + if (part.partIndex in partIndexes) { + throw IllegalStateException( + "Part index ${part.partIndex} already seen for ${part.key}" + ) + } + partIndexes.add(part.partIndex) + } + + // The final part conveys the last + // index even if it is empty. + if (part.isFinal) { + if (!finalIndex.compareAndSet(null, part.partIndex)) { + throw IllegalStateException("Final part already seen for ${part.key}") + } + } + } + + /** + * Complete + * 1. we have seen a final part + * 2. there are no gaps in the part indices + * 3. the last index is the final index + */ + val isComplete: Boolean + get() = finalIndex.get()?.let { it == partIndexes.size } ?: false +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/message/object_storage/ObjectStorageBatch.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/message/object_storage/ObjectStorageBatch.kt new file mode 100644 index 000000000000..6ae91e0f69d7 --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/message/object_storage/ObjectStorageBatch.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.message.object_storage + +import io.airbyte.cdk.load.file.object_storage.Part +import io.airbyte.cdk.load.file.object_storage.RemoteObject +import io.airbyte.cdk.load.message.Batch + +sealed interface ObjectStorageBatch : Batch + +// An indexed bytearray containing an uploadable chunk of a file. +// Returned by the batch accumulator after processing records. +data class LoadablePart(val part: Part) : ObjectStorageBatch { + override val groupId = null + override val state = Batch.State.PROCESSED + + // Hide the data from the logs + override fun toString(): String { + return "LoadablePart(partIndex=${part.partIndex}, key=${part.key}, fileNumber=${part.fileNumber}, empty=${part.isEmpty})" + } +} + +// An UploadablePart that has been uploaded to an incomplete object. +// Returned by processBatch +data class IncompletePartialUpload(val key: String) : ObjectStorageBatch { + override val state: Batch.State = Batch.State.STAGED + override val groupId: String = key +} + +// An UploadablePart that has triggered a completed upload. +data class LoadedObject>( + val remoteObject: T, + val fileNumber: Long, +) : ObjectStorageBatch { + override val state: Batch.State = Batch.State.COMPLETE + override val groupId = remoteObject.key +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/state/object_storage/ObjectStorageDestinationStateManager.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/state/object_storage/ObjectStorageDestinationStateManager.kt new file mode 100644 index 000000000000..da8b5df5f871 --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/state/object_storage/ObjectStorageDestinationStateManager.kt @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.state.object_storage + +import com.fasterxml.jackson.annotation.JsonProperty +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.file.object_storage.ObjectStorageClient +import io.airbyte.cdk.load.file.object_storage.PathFactory +import io.airbyte.cdk.load.file.object_storage.RemoteObject +import io.airbyte.cdk.load.state.DestinationState +import io.airbyte.cdk.load.state.DestinationStatePersister +import io.airbyte.cdk.load.state.object_storage.ObjectStorageDestinationState.Companion.OPTIONAL_ORDINAL_SUFFIX_PATTERN +import io.airbyte.cdk.load.util.readIntoClass +import io.airbyte.cdk.load.util.serializeToJsonBytes +import io.github.oshai.kotlinlogging.KotlinLogging +import io.micronaut.context.annotation.Factory +import io.micronaut.context.annotation.Secondary +import jakarta.inject.Singleton +import java.nio.file.Paths +import java.util.concurrent.ConcurrentHashMap +import kotlinx.coroutines.flow.mapNotNull +import kotlinx.coroutines.flow.toList + +@SuppressFBWarnings("NP_NONNULL_PARAM_VIOLATION", justification = "Kotlin async continuation") +class ObjectStorageDestinationState( + // (State -> (GenerationId -> (Key -> PartNumber))) + @JsonProperty("generations_by_state") + var generationMap: ConcurrentHashMap>> = + ConcurrentHashMap(), + @JsonProperty("count_by_key") var countByKey: MutableMap = mutableMapOf() +) : DestinationState { + enum class State { + STAGED, + FINALIZED + } + + companion object { + const val METADATA_GENERATION_ID_KEY = "ab-generation-id" + const val STREAM_NAMESPACE_KEY = "ab-stream-namespace" + const val STREAM_NAME_KEY = "ab-stream-name" + const val OPTIONAL_ORDINAL_SUFFIX_PATTERN = "(-[0-9]+)?" + + fun metadataFor(stream: DestinationStream): Map = + mapOf(METADATA_GENERATION_ID_KEY to stream.generationId.toString()) + } + + suspend fun addObject( + generationId: Long, + key: String, + partNumber: Long?, + isStaging: Boolean = false + ) { + val state = if (isStaging) State.STAGED else State.FINALIZED + generationMap + .getOrPut(state) { ConcurrentHashMap() } + .getOrPut(generationId) { ConcurrentHashMap() }[key] = partNumber ?: 0L + } + + suspend fun removeObject(generationId: Long, key: String, isStaging: Boolean = false) { + val state = if (isStaging) State.STAGED else State.FINALIZED + generationMap[state]?.get(generationId)?.remove(key) + } + + suspend fun dropGenerationsBefore(minimumGenerationId: Long) { + State.entries.forEach { state -> + (0 until minimumGenerationId).forEach { generationMap[state]?.remove(it) } + } + } + + data class Generation( + val isStaging: Boolean, + val generationId: Long, + val objects: List + ) + + data class ObjectAndPart( + val key: String, + val partNumber: Long, + ) + + suspend fun getGenerations(): Sequence = + generationMap.entries + .asSequence() + .map { (state, gens) -> + val isStaging = state == State.STAGED + gens.map { (generationId, objects) -> + Generation( + isStaging, + generationId, + objects.map { (key, partNumber) -> ObjectAndPart(key, partNumber) } + ) + } + } + .flatten() + + suspend fun getNextPartNumber(): Long = + getGenerations().flatMap { it.objects }.map { it.partNumber }.maxOrNull()?.plus(1) ?: 0L + + /** Returns generationId -> objectAndPart for all staged objects that should be kept. */ + suspend fun getStagedObjectsToFinalize( + minimumGenerationId: Long + ): Sequence> = + getGenerations() + .filter { it.isStaging && it.generationId >= minimumGenerationId } + .flatMap { it.objects.map { obj -> it.generationId to obj } } + + /** + * Returns generationId -> objectAndPart for all objects (staged and unstaged) that should be + * cleaned up. + */ + suspend fun getObjectsToDelete(minimumGenerationId: Long): Sequence> { + val (toKeep, toDrop) = getGenerations().partition { it.generationId >= minimumGenerationId } + val keepKeys = toKeep.flatMap { it.objects.map { obj -> obj.key } }.toSet() + return toDrop.asSequence().flatMap { + it.objects.filter { obj -> obj.key !in keepKeys }.map { obj -> it.generationId to obj } + } + } + + /** Used to guarantee the uniqueness of a key */ + suspend fun ensureUnique(key: String): String { + val ordinal = countByKey.merge(key, 0L) { old, new -> maxOf(old + 1, new) } ?: 0L + return if (ordinal > 0L) { + "$key-$ordinal" + } else { + key + } + } +} + +@SuppressFBWarnings("NP_NONNULL_PARAM_VIOLATION", justification = "Kotlin async continuation") +class ObjectStorageStagingPersister( + private val client: ObjectStorageClient<*>, + private val pathFactory: PathFactory +) : DestinationStatePersister { + private val log = KotlinLogging.logger {} + private val fallbackPersister = ObjectStorageFallbackPersister(client, pathFactory) + + companion object { + const val STATE_FILENAME = "__airbyte_state.json" + } + + private fun keyFor(stream: DestinationStream): String = + Paths.get(pathFactory.getStagingDirectory(stream), STATE_FILENAME).toString() + + override suspend fun load(stream: DestinationStream): ObjectStorageDestinationState { + val key = keyFor(stream) + try { + log.info { "Loading destination state from $key" } + return client.get(key) { inputStream -> + inputStream.readIntoClass(ObjectStorageDestinationState::class.java) + } + } catch (e: Exception) { + log.info { "No destination state found at $key: $e; falling back to metadata search" } + return fallbackPersister.load(stream) + } + } + + override suspend fun persist(stream: DestinationStream, state: ObjectStorageDestinationState) { + client.put(keyFor(stream), state.serializeToJsonBytes()) + } +} + +@SuppressFBWarnings("NP_NONNULL_PARAM_VIOLATION", justification = "Kotlin async continuation") +class ObjectStorageFallbackPersister( + private val client: ObjectStorageClient<*>, + private val pathFactory: PathFactory +) : DestinationStatePersister { + private val log = KotlinLogging.logger {} + override suspend fun load(stream: DestinationStream): ObjectStorageDestinationState { + // Add a suffix matching an OPTIONAL -[0-9]+ ordinal + val matcher = + pathFactory.getPathMatcher(stream, suffixPattern = OPTIONAL_ORDINAL_SUFFIX_PATTERN) + val longestUnambiguous = + pathFactory.getLongestStreamConstantPrefix(stream, isStaging = false) + log.info { + "Searching path $longestUnambiguous (matching ${matcher.regex}) for destination state metadata" + } + val matches = client.list(longestUnambiguous).mapNotNull { matcher.match(it.key) }.toList() + val countByKey = mutableMapOf() + matches.forEach { + val key = it.path.replace(Regex("-[0-9]+$"), "") + val ordinal = it.customSuffix?.substring(1)?.toLongOrNull() ?: 0 + countByKey.merge(key, ordinal) { a, b -> maxOf(a, b) } + } + matches + .groupBy { + client + .getMetadata(it.path)[ObjectStorageDestinationState.METADATA_GENERATION_ID_KEY] + ?.toLong() + ?: 0L + } + .mapValues { (_, matches) -> + matches.associate { it.path to (it.partNumber ?: 0L) }.toMutableMap() + } + .toMutableMap() + .let { + val generationSizes = it.map { gen -> gen.key to gen.value.size } + log.info { + "Inferred state for generations with size: $generationSizes (minimum=${stream.minimumGenerationId}; current=${stream.generationId})" + } + return ObjectStorageDestinationState( + ConcurrentHashMap( + mutableMapOf( + ObjectStorageDestinationState.State.FINALIZED to ConcurrentHashMap(it) + ) + ), + countByKey + ) + } + } + + override suspend fun persist(stream: DestinationStream, state: ObjectStorageDestinationState) { + // No-op; state is persisted when the generation id is set on the object metadata + } +} + +@Factory +class ObjectStorageDestinationStatePersisterFactory>( + private val client: ObjectStorageClient, + private val pathFactory: PathFactory +) { + @Singleton + @Secondary + fun create(): DestinationStatePersister = + if (pathFactory.supportsStaging) { + ObjectStorageStagingPersister(client, pathFactory) + } else { + ObjectStorageFallbackPersister(client, pathFactory) + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/write/object_storage/FilePartAccumulator.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/write/object_storage/FilePartAccumulator.kt new file mode 100644 index 000000000000..cbf0199082df --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/write/object_storage/FilePartAccumulator.kt @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.write.object_storage + +import com.google.common.collect.Range +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.command.object_storage.ObjectStorageUploadConfiguration +import io.airbyte.cdk.load.file.object_storage.ObjectStoragePathFactory +import io.airbyte.cdk.load.file.object_storage.PartFactory +import io.airbyte.cdk.load.message.Batch +import io.airbyte.cdk.load.message.BatchEnvelope +import io.airbyte.cdk.load.message.DestinationFile +import io.airbyte.cdk.load.message.MultiProducerChannel +import io.airbyte.cdk.load.message.object_storage.LoadablePart +import io.airbyte.cdk.load.write.FileBatchAccumulator +import java.io.File +import java.nio.file.Path + +@SuppressFBWarnings( + "NP_NONNULL_PARAM_VIOLATION", + justification = "state is guaranteed to be non-null by Kotlin's type system" +) +class FilePartAccumulator( + private val pathFactory: ObjectStoragePathFactory, + private val stream: DestinationStream, + private val outputQueue: MultiProducerChannel>, +) : FileBatchAccumulator { + override suspend fun processFilePart(file: DestinationFile, index: Long) { + val key = + Path.of(pathFactory.getFinalDirectory(stream), "${file.fileMessage.fileRelativePath}") + .toString() + + val part = + PartFactory( + key = key, + fileNumber = index, + ) + + val localFile = File(file.fileMessage.fileUrl) + val fileInputStream = localFile.inputStream() + + while (true) { + val bytePart = + ByteArray(ObjectStorageUploadConfiguration.DEFAULT_FILE_SIZE_BYTES.toInt()) + val read = fileInputStream.read(bytePart) + + if (read == -1) { + val filePart: ByteArray? = null + val batch = LoadablePart(part.nextPart(filePart, isFinal = true)) + handleFilePart(batch, stream.descriptor, index) + break + } else if (read < bytePart.size) { + val filePart: ByteArray = bytePart.copyOfRange(0, read) + val batch = LoadablePart(part.nextPart(filePart, isFinal = true)) + handleFilePart(batch, stream.descriptor, index) + break + } else { + val batch = LoadablePart(part.nextPart(bytePart, isFinal = false)) + handleFilePart(batch, stream.descriptor, index) + } + } + localFile.delete() + } + + private suspend fun handleFilePart( + batch: Batch, + streamDescriptor: DestinationStream.Descriptor, + index: Long, + ) { + val wrapped = BatchEnvelope(batch, Range.singleton(index), streamDescriptor) + outputQueue.publish(wrapped) + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/write/object_storage/ObjectStorageStreamLoaderFactory.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/write/object_storage/ObjectStorageStreamLoaderFactory.kt new file mode 100644 index 000000000000..10afada4bccc --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/write/object_storage/ObjectStorageStreamLoaderFactory.kt @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.write.object_storage + +import com.google.common.annotations.VisibleForTesting +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.command.object_storage.ObjectStorageCompressionConfigurationProvider +import io.airbyte.cdk.load.command.object_storage.ObjectStorageUploadConfigurationProvider +import io.airbyte.cdk.load.file.StreamProcessor +import io.airbyte.cdk.load.file.object_storage.BufferedFormattingWriterFactory +import io.airbyte.cdk.load.file.object_storage.ObjectStorageClient +import io.airbyte.cdk.load.file.object_storage.ObjectStoragePathFactory +import io.airbyte.cdk.load.file.object_storage.RemoteObject +import io.airbyte.cdk.load.message.Batch +import io.airbyte.cdk.load.message.BatchEnvelope +import io.airbyte.cdk.load.message.MultiProducerChannel +import io.airbyte.cdk.load.message.object_storage.* +import io.airbyte.cdk.load.message.object_storage.LoadedObject +import io.airbyte.cdk.load.message.object_storage.ObjectStorageBatch +import io.airbyte.cdk.load.state.DestinationStateManager +import io.airbyte.cdk.load.state.StreamProcessingFailed +import io.airbyte.cdk.load.state.object_storage.ObjectStorageDestinationState +import io.airbyte.cdk.load.write.BatchAccumulator +import io.airbyte.cdk.load.write.FileBatchAccumulator +import io.airbyte.cdk.load.write.StreamLoader +import io.github.oshai.kotlinlogging.KotlinLogging +import io.micronaut.context.annotation.Secondary +import jakarta.inject.Singleton +import java.io.File +import java.io.OutputStream +import java.util.concurrent.atomic.AtomicLong + +@Singleton +@Secondary +class ObjectStorageStreamLoaderFactory, U : OutputStream>( + private val client: ObjectStorageClient, + private val pathFactory: ObjectStoragePathFactory, + private val bufferedWriterFactory: BufferedFormattingWriterFactory, + private val compressionConfigurationProvider: + ObjectStorageCompressionConfigurationProvider? = + null, + private val uploadConfigurationProvider: ObjectStorageUploadConfigurationProvider, + private val destinationStateManager: DestinationStateManager, +) { + fun create(stream: DestinationStream): StreamLoader { + return ObjectStorageStreamLoader( + stream, + client, + compressionConfigurationProvider?.objectStorageCompressionConfiguration?.compressor, + pathFactory, + bufferedWriterFactory, + destinationStateManager, + uploadConfigurationProvider.objectStorageUploadConfiguration.uploadPartSizeBytes, + uploadConfigurationProvider.objectStorageUploadConfiguration.fileSizeBytes + ) + } +} + +@SuppressFBWarnings( + value = ["NP_NONNULL_PARAM_VIOLATION", "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE"], + justification = "Kotlin async continuation" +) +class ObjectStorageStreamLoader, U : OutputStream>( + override val stream: DestinationStream, + private val client: ObjectStorageClient, + private val compressor: StreamProcessor?, + private val pathFactory: ObjectStoragePathFactory, + private val bufferedWriterFactory: BufferedFormattingWriterFactory, + private val destinationStateManager: DestinationStateManager, + private val partSizeBytes: Long, + private val fileSizeBytes: Long, +) : StreamLoader { + private val log = KotlinLogging.logger {} + + // Used for naming files. Distinct from part index, which is used to track uploads. + private val fileNumber = AtomicLong(0L) + private val objectAccumulator = PartToObjectAccumulator(stream, client) + + override suspend fun start() { + val state = destinationStateManager.getState(stream) + // This is the number used to populate {part_number} on the object path. + // We'll call it file number here to avoid confusion with the part index used for uploads. + val fileNumber = state.getNextPartNumber() + log.info { "Got next file number from destination state: $fileNumber" } + this.fileNumber.set(fileNumber) + } + + override suspend fun createBatchAccumulator(): BatchAccumulator { + return RecordToPartAccumulator( + pathFactory, + bufferedWriterFactory, + partSizeBytes = partSizeBytes, + fileSizeBytes = fileSizeBytes, + stream, + fileNumber + ) { name -> destinationStateManager.getState(stream).ensureUnique(name) } + } + + override suspend fun createFileBatchAccumulator( + outputQueue: MultiProducerChannel>, + ): FileBatchAccumulator = FilePartAccumulator(pathFactory, stream, outputQueue) + + @VisibleForTesting fun createFile(url: String) = File(url) + + override suspend fun processBatch(batch: Batch): Batch { + val nextBatch = objectAccumulator.processBatch(batch) as ObjectStorageBatch + when (nextBatch) { + is LoadedObject<*> -> { + // Mark that we've completed the upload and persist the state before returning the + // persisted batch. + // Otherwise, we might lose track of the upload if the process crashes before + // persisting. + // TODO: Migrate all state bookkeeping to the CDK if possible + val state = destinationStateManager.getState(stream) + state.addObject( + stream.generationId, + nextBatch.remoteObject.key, + nextBatch.fileNumber, + isStaging = pathFactory.supportsStaging + ) + destinationStateManager.persistState(stream) + } + else -> {} // Do nothing + } + return nextBatch + } + + override suspend fun close(streamFailure: StreamProcessingFailed?) { + if (streamFailure != null) { + log.info { "Sync failed, persisting destination state for next run" } + destinationStateManager.persistState(stream) + } else { + val state = destinationStateManager.getState(stream) + log.info { "Sync succeeded, Removing old files" } + state.getObjectsToDelete(stream.minimumGenerationId).forEach { + (generationId, objectAndPart) -> + log.info { + "Deleting old object for generation $generationId: ${objectAndPart.key}" + } + client.delete(objectAndPart.key) + state.removeObject(generationId, objectAndPart.key) + } + + log.info { "Moving all current data out of staging" } + state.getStagedObjectsToFinalize(stream.minimumGenerationId).forEach { + (generationId, objectAndPart) -> + val newKey = + pathFactory.getPathToFile(stream, objectAndPart.partNumber, isStaging = false) + log.info { + "Moving staged object of generation $generationId: ${objectAndPart.key} to $newKey" + } + val newObject = client.move(objectAndPart.key, newKey) + state.removeObject(generationId, objectAndPart.key, isStaging = true) + state.addObject(generationId, newObject.key, objectAndPart.partNumber) + } + + log.info { "Persisting state" } + destinationStateManager.persistState(stream) + } + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/write/object_storage/PartToObjectAccumulator.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/write/object_storage/PartToObjectAccumulator.kt new file mode 100644 index 000000000000..1dba37ab3ee4 --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/write/object_storage/PartToObjectAccumulator.kt @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.write.object_storage + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.file.object_storage.ObjectStorageClient +import io.airbyte.cdk.load.file.object_storage.PartBookkeeper +import io.airbyte.cdk.load.file.object_storage.RemoteObject +import io.airbyte.cdk.load.file.object_storage.StreamingUpload +import io.airbyte.cdk.load.message.Batch +import io.airbyte.cdk.load.message.object_storage.IncompletePartialUpload +import io.airbyte.cdk.load.message.object_storage.LoadablePart +import io.airbyte.cdk.load.message.object_storage.LoadedObject +import io.airbyte.cdk.load.state.object_storage.ObjectStorageDestinationState +import io.airbyte.cdk.load.util.setOnce +import io.github.oshai.kotlinlogging.KotlinLogging +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicBoolean +import kotlinx.coroutines.CompletableDeferred + +@SuppressFBWarnings("NP_NONNULL_PARAM_VIOLATION", justification = "Kotlin async continuation") +class PartToObjectAccumulator>( + private val stream: DestinationStream, + private val client: ObjectStorageClient, +) { + private val log = KotlinLogging.logger {} + + data class UploadInProgress>( + val streamingUpload: CompletableDeferred> = CompletableDeferred(), + val partBookkeeper: PartBookkeeper = PartBookkeeper(), + val hasStarted: AtomicBoolean = AtomicBoolean(false), + ) + private val uploadsInProgress = ConcurrentHashMap>() + + suspend fun processBatch(batch: Batch): Batch { + batch as LoadablePart + val upload = uploadsInProgress.getOrPut(batch.part.key) { UploadInProgress() } + if (upload.hasStarted.setOnce()) { + // Start the upload if we haven't already. Note that the `complete` + // here refers to the completable deferred, not the streaming upload. + val metadata = ObjectStorageDestinationState.metadataFor(stream) + val streamingUpload = client.startStreamingUpload(batch.part.key, metadata) + upload.streamingUpload.complete(streamingUpload) + } + val streamingUpload = upload.streamingUpload.await() + + log.info { + "Processing loadable part ${batch.part.partIndex} of ${batch.part.key} (empty=${batch.part.isEmpty}; final=${batch.part.isFinal})" + } + + // Upload provided bytes and update indexes. + if (batch.part.bytes != null) { + streamingUpload.uploadPart(batch.part.bytes, batch.part.partIndex) + } + upload.partBookkeeper.add(batch.part) + if (upload.partBookkeeper.isComplete) { + val obj = streamingUpload.complete() + uploadsInProgress.remove(batch.part.key) + + log.info { "Completed upload of ${obj.key}" } + return LoadedObject(remoteObject = obj, fileNumber = batch.part.fileNumber) + } else { + return IncompletePartialUpload(batch.part.key) + } + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/write/object_storage/RecordToPartAccumulator.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/write/object_storage/RecordToPartAccumulator.kt new file mode 100644 index 000000000000..cedba80734af --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/main/kotlin/io/airbyte/cdk/load/write/object_storage/RecordToPartAccumulator.kt @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.write.object_storage + +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.file.object_storage.BufferedFormattingWriter +import io.airbyte.cdk.load.file.object_storage.BufferedFormattingWriterFactory +import io.airbyte.cdk.load.file.object_storage.ObjectStoragePathFactory +import io.airbyte.cdk.load.file.object_storage.PartFactory +import io.airbyte.cdk.load.message.Batch +import io.airbyte.cdk.load.message.DestinationRecordAirbyteValue +import io.airbyte.cdk.load.message.object_storage.* +import io.airbyte.cdk.load.write.BatchAccumulator +import io.github.oshai.kotlinlogging.KotlinLogging +import java.io.OutputStream +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicLong + +data class ObjectInProgress( + val partFactory: PartFactory, + val writer: BufferedFormattingWriter, +) + +class RecordToPartAccumulator( + private val pathFactory: ObjectStoragePathFactory, + private val bufferedWriterFactory: BufferedFormattingWriterFactory, + private val partSizeBytes: Long, + private val fileSizeBytes: Long, + private val stream: DestinationStream, + private val fileNumber: AtomicLong, + private val fileNameMapper: suspend (String) -> String +) : BatchAccumulator { + private val log = KotlinLogging.logger {} + + // Hack because AtomicReference doesn't support lazily evaluated blocks. + private val key = "key" + private val currentObject = ConcurrentHashMap>() + + override suspend fun processRecords( + records: Iterator, + totalSizeBytes: Long, + endOfStream: Boolean + ): Batch { + // Start a new object if there is not one in progress. + val partialUpload = + currentObject.getOrPut(key) { + val fileNo = fileNumber.getAndIncrement() + ObjectInProgress( + partFactory = + PartFactory( + key = + fileNameMapper( + pathFactory.getPathToFile( + stream, + fileNo, + isStaging = pathFactory.supportsStaging + ) + ), + fileNumber = fileNo + ), + writer = bufferedWriterFactory.create(stream), + ) + } + + // Add all the records to the formatting writer. + log.info { "Accumulating ${totalSizeBytes}b records for ${partialUpload.partFactory.key}" } + records.forEach { partialUpload.writer.accept(it) } + partialUpload.writer.flush() + + // Check if we have reached the target size. + val bufferSize = partialUpload.writer.bufferSize + val newSize = partialUpload.partFactory.totalSize + bufferSize + if (newSize >= fileSizeBytes || endOfStream) { + + // If we have reached target file size, clear the object and yield a final part. + val bytes = partialUpload.writer.finish() + partialUpload.writer.close() + val part = partialUpload.partFactory.nextPart(bytes, isFinal = true) + + log.info { + val reason = if (endOfStream) "end of stream" else "file size ${fileSizeBytes}b" + "${partialUpload.partFactory.key}: buffer ${bufferSize}b; total: ${newSize}b; $reason reached, yielding final part ${part.partIndex} (size=${bytes?.size}b)" + } + + currentObject.remove(key) + return LoadablePart(part) + } else if (bufferSize >= partSizeBytes) { + // If we have not reached file size, but have reached part size, yield a non-final part. + val bytes = partialUpload.writer.takeBytes() + val part = partialUpload.partFactory.nextPart(bytes) + log.info { + "${partialUpload.partFactory.key}: buffer ${bufferSize}b; total ${newSize}b; part size ${partSizeBytes}b reached, yielding part ${part.partIndex}" + } + + return LoadablePart(part) + } else { + // If we have not reached either the file or part size, yield a null part. + // TODO: Change this to a generator interface so we never have to do this. + val part = partialUpload.partFactory.nextPart(null) + log.info { + "${partialUpload.partFactory.key}: buffer ${bufferSize}b; total ${newSize}b; part size ${partSizeBytes}b not reached, yielding null part ${part.partIndex}" + } + + return LoadablePart(part) + } + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStoragePathFactoryTest.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStoragePathFactoryTest.kt index 9f3fa27fbac9..a7739bd3e06f 100644 --- a/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStoragePathFactoryTest.kt +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStoragePathFactoryTest.kt @@ -4,6 +4,8 @@ package io.airbyte.cdk.load.file.object_storage +import io.airbyte.cdk.load.command.Append +import io.airbyte.cdk.load.command.DestinationStream import io.airbyte.cdk.load.command.MockDestinationCatalogFactory import io.airbyte.cdk.load.command.object_storage.JsonFormatConfiguration import io.airbyte.cdk.load.command.object_storage.ObjectStorageCompressionConfiguration @@ -12,35 +14,28 @@ import io.airbyte.cdk.load.command.object_storage.ObjectStorageFormatConfigurati import io.airbyte.cdk.load.command.object_storage.ObjectStorageFormatConfigurationProvider import io.airbyte.cdk.load.command.object_storage.ObjectStoragePathConfiguration import io.airbyte.cdk.load.command.object_storage.ObjectStoragePathConfigurationProvider +import io.airbyte.cdk.load.data.StringType import io.airbyte.cdk.load.file.GZIPProcessor import io.airbyte.cdk.load.file.MockTimeProvider import io.airbyte.cdk.load.file.TimeProvider import io.micronaut.context.annotation.Primary +import io.micronaut.context.annotation.Property import io.micronaut.context.annotation.Requires import io.micronaut.test.extensions.junit5.annotation.MicronautTest -import jakarta.inject.Inject import jakarta.inject.Singleton +import java.io.BufferedOutputStream import java.time.LocalDateTime import java.time.ZoneId import java.time.format.DateTimeFormatter -import java.util.zip.GZIPOutputStream import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test -@MicronautTest( - environments = - [ - "ObjectStoragePathFactoryTest", - "MockDestinationCatalog", - ] -) class ObjectStoragePathFactoryTest { - @Inject lateinit var timeProvider: TimeProvider - @Singleton @Primary @Requires(env = ["ObjectStoragePathFactoryTest"]) - class PathTimeProvider : MockTimeProvider() { + class PathTimeProvider : MockTimeProvider(), TimeProvider { init { val dateTime = LocalDateTime.parse( @@ -49,13 +44,15 @@ class ObjectStoragePathFactoryTest { ) val epochMilli = dateTime.toInstant(ZoneId.of("UTC").rules.getOffset(dateTime)).toEpochMilli() - setCurrentTime(epochMilli) + setSyncTime(epochMilli) + setCurrentTime(epochMilli + 1) } } @Singleton @Primary @Requires(env = ["ObjectStoragePathFactoryTest"]) + @Requires(property = "object-storage-path-factory-test.use-staging", value = "true") class MockPathConfigProvider : ObjectStoragePathConfigurationProvider { override val objectStoragePathConfiguration: ObjectStoragePathConfiguration = ObjectStoragePathConfiguration( @@ -63,10 +60,37 @@ class ObjectStoragePathFactoryTest { stagingPrefix = "staging/prefix", pathSuffixPattern = "\${NAMESPACE}/\${STREAM_NAME}/\${YEAR}/\${MONTH}/\${DAY}/\${HOUR}/\${MINUTE}/\${SECOND}/\${MILLISECOND}/\${EPOCH}/", - fileNamePattern = "{date}-{timestamp}-{part_number}-{sync_id}{format_extension}" + fileNamePattern = + "{date}-{date:yyyy_MM}-{timestamp}-{part_number}-{sync_id}{format_extension}", + usesStagingDirectory = true ) } + @Singleton + @Primary + @Requires(env = ["ObjectStoragePathFactoryTest"]) + @Requires(property = "object-storage-path-factory-test.path-without-slash", value = "true") + class MockPathConfigProviderWithoutSlash : ObjectStoragePathConfigurationProvider { + override val objectStoragePathConfiguration: ObjectStoragePathConfiguration = + MockPathConfigProvider() + .objectStoragePathConfiguration + .copy( + pathSuffixPattern = + "\${NAMESPACE}/\${STREAM_NAME}/\${YEAR}/\${MONTH}/\${DAY}/\${HOUR}/\${MINUTE}/\${SECOND}/\${MILLISECOND}/\${EPOCH}_" + ) + } + + @Singleton + @Primary + @Requires(env = ["ObjectStoragePathFactoryTest"]) + @Requires(property = "object-storage-path-factory-test.use-staging", value = "false") + class MockPathConfigProviderWithoutStaging : ObjectStoragePathConfigurationProvider { + override val objectStoragePathConfiguration: ObjectStoragePathConfiguration = + MockPathConfigProvider() + .objectStoragePathConfiguration + .copy(usesStagingDirectory = false) + } + @Singleton @Primary @Requires(env = ["ObjectStoragePathFactoryTest"]) @@ -79,34 +103,183 @@ class ObjectStoragePathFactoryTest { @Primary @Requires(env = ["ObjectStoragePathFactoryTest"]) class MockCompressionConfigProvider : - ObjectStorageCompressionConfigurationProvider { + ObjectStorageCompressionConfigurationProvider { override val objectStorageCompressionConfiguration: - ObjectStorageCompressionConfiguration = + ObjectStorageCompressionConfiguration = ObjectStorageCompressionConfiguration(compressor = GZIPProcessor) } - @Test - fun testBasicBehavior(pathFactory: ObjectStoragePathFactory) { - val epochMilli = timeProvider.currentTimeMillis() - val stream1 = MockDestinationCatalogFactory.stream1 - val (namespace, name) = stream1.descriptor - val prefixOnly = "prefix/$namespace/$name/2020/01/02/03/04/05/0678/$epochMilli" - val fileName = "2020_01_02-1577934245678-173-42.jsonl.gz" - Assertions.assertEquals( - "staging/$prefixOnly", - pathFactory.getStagingDirectory(stream1).toString(), - ) - Assertions.assertEquals( - prefixOnly, - pathFactory.getFinalDirectory(stream1).toString(), - ) - Assertions.assertEquals( - "staging/$prefixOnly/$fileName", - pathFactory.getPathToFile(stream1, 173, true).toString(), - ) - Assertions.assertEquals( - "$prefixOnly/$fileName", - pathFactory.getPathToFile(stream1, 173, false).toString(), - ) + @Nested + @MicronautTest( + environments = + [ + "ObjectStoragePathFactoryTest", + "MockDestinationCatalog", + ], + ) + @Property(name = "object-storage-path-factory-test.use-staging", value = "true") + inner class ObjectStoragePathFactoryTestWithStaging { + @Test + fun testBasicBehavior(pathFactory: ObjectStoragePathFactory, timeProvider: TimeProvider) { + val syncTime = timeProvider.syncTimeMillis() + val wallTime = timeProvider.currentTimeMillis() + val stream1 = MockDestinationCatalogFactory.stream1 + val (namespace, name) = stream1.descriptor + val prefixOnly = "prefix/$namespace/$name/2020/01/02/03/04/05/0678/$syncTime/" + val fileName = "2020_01_02-2020_01-$wallTime-173-42.jsonl.gz" + Assertions.assertEquals( + "staging/$prefixOnly", + pathFactory.getStagingDirectory(stream1).toString(), + ) + Assertions.assertEquals( + prefixOnly, + pathFactory.getFinalDirectory(stream1).toString(), + ) + Assertions.assertEquals( + "staging/$prefixOnly$fileName", + pathFactory.getPathToFile(stream1, 173, true).toString(), + ) + Assertions.assertEquals( + "$prefixOnly$fileName", + pathFactory.getPathToFile(stream1, 173, false).toString(), + ) + } + + @Test + fun testPathMatchingPattern( + pathFactory: ObjectStoragePathFactory, + timeProvider: TimeProvider + ) { + val syncTime = timeProvider.syncTimeMillis() + val stream1 = MockDestinationCatalogFactory.stream1 + val (namespace, name) = stream1.descriptor + val expectedToMatch = + "prefix/$namespace/$name/2020/01/02/03/04/05/0678/$syncTime/2020_01_02-2020_01-1577934245678-173-42.jsonl.gz" + val match = pathFactory.getPathMatcher(stream1).match(expectedToMatch) + Assertions.assertTrue(match != null) + Assertions.assertTrue(match?.partNumber == 173L) + } + + @Test + fun testPathMatchingPatternWithEmptyStream( + pathFactory: ObjectStoragePathFactory, + timeProvider: TimeProvider + ) { + val epochMilli = timeProvider.currentTimeMillis() + val stream1 = MockDestinationCatalogFactory.stream1 + val (_, name) = stream1.descriptor + val emptyNamespaceStream = + stream1.copy(descriptor = stream1.descriptor.copy(namespace = null)) + val expectedToMatch = + "prefix/$name/2020/01/02/03/04/05/0678/$epochMilli/2020_01_02-2020_01-1577934245678-173-42.jsonl.gz" + val match = pathFactory.getPathMatcher(emptyNamespaceStream).match(expectedToMatch) + Assertions.assertTrue(match != null) + Assertions.assertTrue(match?.partNumber == 173L) + } + + @Test + fun testSpecialCharacterInStream( + pathFactory: ObjectStoragePathFactory, + timeProvider: TimeProvider + ) { + val epochMilli = timeProvider.syncTimeMillis() + val streamWithSpecial = + DestinationStream( + DestinationStream.Descriptor( + "namespace", + "stream_with:spécial:characters", + ), + generationId = 0, + minimumGenerationId = 0, + syncId = 0, + schema = StringType, + importType = Append + ) + val expectedPath = + "prefix/namespace/stream_with:special:characters/2020/01/02/03/04/05/0678/$epochMilli/" + Assertions.assertEquals( + expectedPath, + pathFactory.getFinalDirectory(streamWithSpecial), + ) + } + + @Test + fun testLongestConstantPrefix(pathFactory: ObjectStoragePathFactory) { + val stream1 = MockDestinationCatalogFactory.stream1 + val (namespace, name) = stream1.descriptor + val prefixOnly = "prefix/$namespace/$name/" + Assertions.assertEquals( + prefixOnly, + pathFactory.getLongestStreamConstantPrefix(stream1, false) + ) + } + } + + @Nested + @MicronautTest( + environments = + [ + "ObjectStoragePathFactoryTest", + "MockDestinationCatalog", + ], + ) + @Property(name = "object-storage-path-factory-test.use-staging", value = "false") + inner class ObjectStoragePathFactoryTestWithoutStaging { + @Test + fun testBasicBehavior(pathFactory: ObjectStoragePathFactory, timeProvider: TimeProvider) { + val syncTime = timeProvider.syncTimeMillis() + val wallTime = timeProvider.currentTimeMillis() + val stream1 = MockDestinationCatalogFactory.stream1 + val (namespace, name) = stream1.descriptor + val prefixOnly = "prefix/$namespace/$name/2020/01/02/03/04/05/0678/$syncTime/" + val fileName = "2020_01_02-2020_01-$wallTime-173-42.jsonl.gz" + Assertions.assertEquals( + prefixOnly, + pathFactory.getFinalDirectory(stream1), + ) + Assertions.assertEquals( + "$prefixOnly$fileName", + pathFactory.getPathToFile(stream1, 173, false), + ) + + Assertions.assertThrows(UnsupportedOperationException::class.java) { + pathFactory.getStagingDirectory(stream1) + } + Assertions.assertThrows(UnsupportedOperationException::class.java) { + pathFactory.getPathToFile(stream1, 173, true) + } + } + } + + @Nested + @MicronautTest( + environments = + [ + "ObjectStoragePathFactoryTest", + "MockDestinationCatalog", + ], + ) + @Property(name = "object-storage-path-factory-test.path-without-slash", value = "true") + inner class ObjectStoragePathFactoryTestNoTrailingPathSlash { + @Test + fun testPathDoesNotHaveTrailingSlash( + pathFactory: ObjectStoragePathFactory, + timeProvider: TimeProvider + ) { + val syncTime = timeProvider.syncTimeMillis() + val wallTime = timeProvider.currentTimeMillis() + val stream1 = MockDestinationCatalogFactory.stream1 + val (namespace, name) = stream1.descriptor + val prefixOnly = "prefix/$namespace/$name/2020/01/02/03/04/05/0678/${syncTime}_" + val fileName = "2020_01_02-2020_01-$wallTime-173-42.jsonl.gz" + Assertions.assertEquals( + prefixOnly, + pathFactory.getFinalDirectory(stream1), + ) + Assertions.assertEquals( + "$prefixOnly$fileName", + pathFactory.getPathToFile(stream1, 173, false), + ) + } } } diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStoragePathFactoryUTest.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStoragePathFactoryUTest.kt new file mode 100644 index 000000000000..9732954ddcd3 --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/file/object_storage/ObjectStoragePathFactoryUTest.kt @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.file.object_storage + +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.command.object_storage.ObjectStoragePathConfiguration +import io.airbyte.cdk.load.command.object_storage.ObjectStoragePathConfigurationProvider +import io.airbyte.cdk.load.file.TimeProvider +import io.mockk.every +import io.mockk.impl.annotations.MockK +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class ObjectStoragePathFactoryUTest { + @MockK lateinit var stream: DestinationStream + @MockK lateinit var pathConfigProvider: ObjectStoragePathConfigurationProvider + @MockK lateinit var timeProvider: TimeProvider + + @BeforeEach + fun setup() { + every { stream.descriptor } returns DestinationStream.Descriptor("test", "stream") + every { timeProvider.syncTimeMillis() } returns 0 + every { timeProvider.currentTimeMillis() } returns 1 + } + + @Test + fun `test matcher with suffix`() { + every { pathConfigProvider.objectStoragePathConfiguration } returns + ObjectStoragePathConfiguration( + "prefix", + null, + "path/", + "ambiguous_filename", + false, + ) + val factory = ObjectStoragePathFactory(pathConfigProvider, null, null, timeProvider) + + val matcher = factory.getPathMatcher(stream, "(-\\d+)?") + val match1 = matcher.match("prefix/path/ambiguous_filename") + assertNotNull(match1) + assertNull(match1?.customSuffix) + val match2 = matcher.match("prefix/path/ambiguous_filename-1") + assertNotNull(match2) + assertEquals(match2?.customSuffix, "-1") + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/file/object_storage/PartFactoryTest.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/file/object_storage/PartFactoryTest.kt new file mode 100644 index 000000000000..d54e3d1ce0c8 --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/file/object_storage/PartFactoryTest.kt @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.file.object_storage + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.withContext +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows + +class PartFactoryTest { + @Test + fun `parts are generated in order and empty parts are skipped (empty final)`() { + val factory = PartFactory("key", 1) + val part1 = factory.nextPart(byteArrayOf(1)) + val part2 = factory.nextPart(null) + val part3 = factory.nextPart(byteArrayOf(2)) + val part4 = factory.nextPart(null, isFinal = true) + + assert(part1.partIndex == 1) + assert(!part1.isFinal) + assert(!part1.isEmpty) + + assert(part2.partIndex == 1) + assert(!part2.isFinal) + assert(part2.isEmpty) + + assert(part3.partIndex == 2) + assert(!part3.isFinal) + assert(!part3.isEmpty) + + assert(part4.partIndex == 2) + assert(part4.isFinal) + assert(part4.isEmpty) + + // No more parts can be produced after the final part. + assertThrows { factory.nextPart(byteArrayOf(3)) } + } + + @Test + fun `parts are generated in order and empty parts are skipped (non-empty final)`() { + val factory = PartFactory("key", 1) + val part1 = factory.nextPart(byteArrayOf(1)) + val part2 = factory.nextPart(null) + val part3 = factory.nextPart(byteArrayOf(2)) + val part4 = factory.nextPart(byteArrayOf(3), isFinal = true) + + assert(part1.partIndex == 1) + assert(part2.partIndex == 1) + assert(part3.partIndex == 2) + + assert(part4.partIndex == 3) + assert(part4.isFinal) + assert(!part4.isEmpty) + } + + @Test + fun `total size is calculated correctly`() { + val factory = PartFactory("key", 1) + factory.nextPart(byteArrayOf(1)) + factory.nextPart(null) + factory.nextPart(byteArrayOf(2, 2)) + factory.nextPart(byteArrayOf(3, 3, 3), isFinal = true) + + assert(factory.totalSize == 6L) + } + + @Test + fun `test that assembler is not complete until all parts are seen`() { + val factory = PartFactory("key", 1) + val assembler = PartBookkeeper() + + repeat(10) { + val part = factory.nextPart(byteArrayOf(it.toByte()), it == 9) + assert(!assembler.isComplete) + assembler.add(part) + } + + assert(assembler.isComplete) + } + + @Test + fun `test assembler not complete until all are seen (out-of-order, gaps, and null final)`() { + val factory = PartFactory("key", 1) + val assembler = PartBookkeeper() + + val sortOrder = listOf(2, 1, 0, 9, 8, 7, 6, 4, 5, 3) + val parts = + (0 until 10).map { + // Make a gap every 3rd part + val bytes = + if (it % 3 == 0) { + null + } else { + byteArrayOf(it.toByte()) + } + + // Last in list must be final + factory.nextPart(bytes, it == 9) + } + + val partsSorted = parts.zip(sortOrder).sortedBy { it.second } + partsSorted.forEach { (part, sortIndex) -> + if (sortIndex == 9) { + // Because the last part was null, and the assembler already saw the final part + // it *should* think it is complete. + assert(assembler.isComplete) + } else { + assert(!assembler.isComplete) + } + assembler.add(part) + } + + assert(assembler.isComplete) + } + + @Test + fun `test adding parts asynchronously`() = runTest { + val factory = PartFactory("key", 1) + val parts = (0 until 100000).map { factory.nextPart(byteArrayOf(it.toByte()), it == 99999) } + val assembler = PartBookkeeper() + val jobs = mutableListOf() + withContext(Dispatchers.IO) { + parts.shuffled(random = java.util.Random(0)).forEach { + jobs.add( + launch { + assert(!assembler.isComplete) + assembler.add(it) + } + ) + } + jobs.forEach { it.join() } + } + assert(assembler.isComplete) + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/state/object_storage/ObjectStorageDestinationStateTest.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/state/object_storage/ObjectStorageDestinationStateTest.kt new file mode 100644 index 000000000000..de22e0674f3f --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/state/object_storage/ObjectStorageDestinationStateTest.kt @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.state.object_storage + +import io.airbyte.cdk.load.MockObjectStorageClient +import io.airbyte.cdk.load.MockPathFactory +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.command.MockDestinationCatalogFactory +import io.airbyte.cdk.load.file.NoopProcessor +import io.airbyte.cdk.load.state.DestinationStateManager +import io.micronaut.context.annotation.Primary +import io.micronaut.context.annotation.Property +import io.micronaut.context.annotation.Requires +import io.micronaut.test.extensions.junit5.annotation.MicronautTest +import jakarta.inject.Singleton +import java.nio.file.Paths +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Test + +class ObjectStorageDestinationStateTest { + @Singleton + @Requires(env = ["ObjectStorageDestinationStateTest"]) + data class Dependencies( + val stateManager: DestinationStateManager, + val mockClient: MockObjectStorageClient, + val pathFactory: MockPathFactory + ) + + companion object { + val stream1 = MockDestinationCatalogFactory.stream1 + const val PERSISTED = + """{"generations_by_state":{"FINALIZED":{"0":{"key1":0,"key2":1},"1":{"key3":0,"key4":1}}},"count_by_key":{}}""" + } + + @Singleton + @Primary + @Requires(property = "object-storage-destination-state-test.use-staging", value = "true") + class MockPathFactoryWithStaging : MockPathFactory() { + override var doSupportStaging = true + } + + @Singleton + @Primary + @Requires(property = "object-storage-destination-state-test.use-staging", value = "false") + class MockPathFactoryWithoutStaging : MockPathFactory() { + override var doSupportStaging = false + } + + @Nested + @MicronautTest( + rebuildContext = true, + environments = + [ + "ObjectStorageDestinationStateTest", + "MockObjectStorageClient", + "MockDestinationCatalog", + ], + ) + @Property(name = "object-storage-destination-state-test.use-staging", value = "true") + inner class ObjectStorageDestinationStateTestStaging { + @Test + fun testBasicLifecycle(d: Dependencies) = runTest { + val state = d.stateManager.getState(stream1) + Assertions.assertEquals( + emptyList(), + state.getGenerations().toList(), + "state should initially be empty" + ) + state.addObject(0, "key1", 0) + state.addObject(0, "key2", 1) + state.addObject(1, "key3", 0) + state.addObject(1, "key4", 1) + Assertions.assertEquals( + 4, + state.getGenerations().flatMap { it.objects }.toList().size, + "state should contain 4 objects" + ) + + d.stateManager.persistState(stream1) + val obj = d.mockClient.list("").toList().first() + val data = d.mockClient.get(obj.key) { it.readBytes() } + Assertions.assertEquals( + PERSISTED, + data.toString(Charsets.UTF_8), + "state should be persisted" + ) + + state.removeObject(0, "key1") + state.removeObject(0, "key2") + state.removeObject(1, "key3") + state.removeObject(1, "key4") + Assertions.assertEquals( + emptyList(), + state.getGenerations().flatMap { it.objects }.toList(), + "objects should be removed" + ) + + val fetchedState = d.stateManager.getState(stream1) + Assertions.assertEquals( + 0, + fetchedState.getGenerations().flatMap { it.objects }.toList().size, + "state should still contain 0 objects (managed state is in cache)" + ) + } + + @Test + fun testLoadingExistingState(d: Dependencies) = runTest { + val key = + Paths.get( + d.pathFactory.getStagingDirectory(stream1), + ObjectStorageStagingPersister.STATE_FILENAME + ) + .toString() + d.mockClient.put(key, PERSISTED.toByteArray()) + val state = d.stateManager.getState(stream1) + Assertions.assertEquals( + listOf( + ObjectStorageDestinationState.Generation( + false, + 0, + listOf( + ObjectStorageDestinationState.ObjectAndPart("key1", 0), + ObjectStorageDestinationState.ObjectAndPart("key2", 1) + ) + ), + ObjectStorageDestinationState.Generation( + false, + 1, + listOf( + ObjectStorageDestinationState.ObjectAndPart("key3", 0), + ObjectStorageDestinationState.ObjectAndPart("key4", 1) + ) + ) + ), + state.getGenerations().toList(), + "state should be loaded from storage" + ) + + Assertions.assertEquals(2L, state.getNextPartNumber()) + } + + @Test + fun testFallbackToMetadataState(d: Dependencies) = runTest { + val generations = + ObjectStorageDestinationStateTestWithoutStaging().loadMetadata(d, stream1) + val state = d.stateManager.getState(stream1) + ObjectStorageDestinationStateTestWithoutStaging().validateMetadata(state, generations) + Assertions.assertEquals(2L, state.getNextPartNumber()) + } + + @Test + fun testGetObjectsToMoveAndDelete(d: Dependencies) = runTest { + val state = d.stateManager.getState(stream1) + state.addObject(generationId = 0L, "old-finalized", partNumber = 0L, isStaging = false) + state.addObject(generationId = 1L, "new-finalized", partNumber = 1L, isStaging = false) + state.addObject( + generationId = 0L, + "leftover-old-staging", + partNumber = 2L, + isStaging = true + ) + state.addObject(generationId = 1L, "new-staging", partNumber = 3L, isStaging = true) + val toFinalize = + state + .getStagedObjectsToFinalize(minimumGenerationId = 1L) + .map { it.first to it.second } + .toSet() + + Assertions.assertEquals( + setOf(1L to ObjectStorageDestinationState.ObjectAndPart("new-staging", 3L)), + toFinalize, + "only new-staging should be finalized" + ) + + val toDelete = + state + .getObjectsToDelete(minimumGenerationId = 1L) + .map { it.first to it.second } + .toSet() + Assertions.assertEquals( + setOf( + 0L to ObjectStorageDestinationState.ObjectAndPart("old-finalized", 0L), + 0L to ObjectStorageDestinationState.ObjectAndPart("leftover-old-staging", 2L) + ), + toDelete, + "all old objects should be deleted" + ) + } + } + + @Nested + @MicronautTest( + environments = + [ + "ObjectStorageDestinationStateTest", + "MockObjectStorageClient", + "MockDestinationCatalog", + ], + ) + @Property(name = "object-storage-destination-state-test.use-staging", value = "false") + inner class ObjectStorageDestinationStateTestWithoutStaging { + suspend fun loadMetadata( + d: Dependencies, + stream: DestinationStream + ): List> { + val genIdKey = ObjectStorageDestinationState.METADATA_GENERATION_ID_KEY + val prefix = + "${d.pathFactory.prefix}/${stream.descriptor.namespace}/${stream.descriptor.name}" + val generations = + listOf( + Triple(0, "$prefix/key1-0", 0L), + Triple(0, "$prefix/key2-1", 1L), + Triple(1, "$prefix/key3-0", 0L), + Triple(1, "$prefix/key4-1", 1L) + ) + generations.forEach { (genId, key, _) -> + d.mockClient.streamingUpload( + key, + mapOf(genIdKey to genId.toString()), + NoopProcessor + ) { it.write(0) } + } + return generations + } + + fun validateMetadata( + state: ObjectStorageDestinationState, + generations: List> + ) = runTest { + Assertions.assertEquals( + generations + .groupBy { it.first } + .map { (generationId, triples) -> + ObjectStorageDestinationState.Generation( + false, + generationId.toLong(), + triples + .map { (_, key, partNumber) -> + ObjectStorageDestinationState.ObjectAndPart(key, partNumber) + } + .sortedByDescending { + // Brittle hack to get the order to line up + it.key.contains("key2") || it.key.contains("key4") + } + .toMutableList() + ) + }, + state.getGenerations().toList().sortedBy { it.generationId }, + "state should be recovered from metadata" + ) + } + + @Test + fun testRecoveringFromMetadata(d: Dependencies) = runTest { + val generations = loadMetadata(d, stream1) + val state = d.stateManager.getState(stream1) + validateMetadata(state, generations) + Assertions.assertEquals(2L, state.getNextPartNumber()) + } + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/state/object_storage/ObjectStorageDestinationStateUTest.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/state/object_storage/ObjectStorageDestinationStateUTest.kt new file mode 100644 index 000000000000..d545c550a24f --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/state/object_storage/ObjectStorageDestinationStateUTest.kt @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.state.object_storage + +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.file.object_storage.ObjectStorageClient +import io.airbyte.cdk.load.file.object_storage.ObjectStoragePathFactory +import io.airbyte.cdk.load.file.object_storage.PathMatcher +import io.airbyte.cdk.load.file.object_storage.RemoteObject +import io.mockk.coEvery +import io.mockk.every +import io.mockk.impl.annotations.MockK +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class ObjectStorageDestinationStateUTest { + data class MockObj(override val key: String, override val storageConfig: Unit = Unit) : + RemoteObject + + @MockK lateinit var stream: DestinationStream + @MockK lateinit var client: ObjectStorageClient<*> + @MockK lateinit var pathFactory: ObjectStoragePathFactory + + @BeforeEach + fun setup() { + every { stream.descriptor } returns DestinationStream.Descriptor("test", "stream") + every { pathFactory.getPathMatcher(any(), any()) } answers + { + val suffix = secondArg() + PathMatcher(Regex("([a-z]+)$suffix"), mapOf("suffix" to 2)) + } + every { pathFactory.getLongestStreamConstantPrefix(any(), any()) } returns "prefix/" + } + + @Test + fun `test that the fallback persister correctly infers the unique key to ordinal count`() = + runTest { + coEvery { client.list(any()) } returns + flowOf( + MockObj("dog"), + MockObj("dog-1"), + MockObj("dog-3"), + MockObj("cat"), + MockObj("turtle-100") + ) + coEvery { client.getMetadata(any()) } returns mapOf("ab-generation-id" to "1") + + val persister = ObjectStorageFallbackPersister(client, pathFactory) + val state = persister.load(stream) + assertEquals(state.countByKey["dog"], 3L) + assertEquals(state.countByKey["cat"], 0L) + assertEquals(state.countByKey["turtle"], 100L) + + assertEquals(state.ensureUnique("dog"), "dog-4") + assertEquals(state.ensureUnique("dog"), "dog-5") + assertEquals(state.ensureUnique("cat"), "cat-1") + assertEquals(state.ensureUnique("turtle"), "turtle-101") + assertEquals(state.ensureUnique("turtle"), "turtle-102") + assertEquals(state.ensureUnique("spider"), "spider") + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/write/object_storage/FilePartAccumulatorTest.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/write/object_storage/FilePartAccumulatorTest.kt new file mode 100644 index 000000000000..25d232bd3328 --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/write/object_storage/FilePartAccumulatorTest.kt @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.write.object_storage + +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.command.object_storage.ObjectStorageUploadConfiguration +import io.airbyte.cdk.load.file.object_storage.ObjectStoragePathFactory +import io.airbyte.cdk.load.message.BatchEnvelope +import io.airbyte.cdk.load.message.DestinationFile +import io.airbyte.cdk.load.message.MultiProducerChannel +import io.mockk.coVerify +import io.mockk.every +import io.mockk.mockk +import java.io.File +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class FilePartAccumulatorTest { + private val pathFactory: ObjectStoragePathFactory = mockk(relaxed = true) + private val stream: DestinationStream = mockk(relaxed = true) + private val outputQueue: MultiProducerChannel> = mockk(relaxed = true) + + private val filePartAccumulator = FilePartAccumulator(pathFactory, stream, outputQueue) + + private val fileRelativePath = "relativePath" + private val descriptor = DestinationStream.Descriptor("namespace", "name") + + @BeforeEach + fun init() { + every { stream.descriptor } returns descriptor + } + + @Test + fun testFilePartAccumulatorSmall() = runTest { + val finalDirectory = "finalDirectory" + every { pathFactory.getFinalDirectory(stream) } returns finalDirectory + val file = createFile(10) + val index = 21L + val fileMessage = createFileMessage(file) + + filePartAccumulator.processFilePart(fileMessage, index) + + coVerify(exactly = 1) { outputQueue.publish(any()) } + } + + @Test + fun testFilePartAccumulatorExactlyPartSize() = runTest { + val finalDirectory = "finalDirectory" + every { pathFactory.getFinalDirectory(stream) } returns finalDirectory + val file = createFile(ObjectStorageUploadConfiguration.DEFAULT_FILE_SIZE_BYTES.toInt()) + val index = 21L + val fileMessage = createFileMessage(file) + + filePartAccumulator.processFilePart(fileMessage, index) + + coVerify(exactly = 2) { outputQueue.publish(any()) } + } + + @Test + fun testFilePartAccumulatorBig() = runTest { + val finalDirectory = "finalDirectory" + every { pathFactory.getFinalDirectory(stream) } returns finalDirectory + val file = + createFile(ObjectStorageUploadConfiguration.DEFAULT_FILE_SIZE_BYTES.toInt() + 1000) + val index = 21L + val fileMessage = createFileMessage(file) + + filePartAccumulator.processFilePart(fileMessage, index) + + coVerify(exactly = 2) { outputQueue.publish(any()) } + } + + private fun createFile(sizeInBytes: Int): File { + val file = File.createTempFile("test", ".txt") + val text = CharArray(sizeInBytes) { 'a' }.concatToString() + file.writeText(text) + return file + } + + private fun createFileMessage(file: File): DestinationFile { + return DestinationFile( + descriptor, + 0, + "", + DestinationFile.AirbyteRecordMessageFile( + fileUrl = file.absolutePath, + fileRelativePath = fileRelativePath, + ) + ) + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/write/object_storage/ObjectStorageFormattingWriterTest.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/write/object_storage/ObjectStorageFormattingWriterTest.kt new file mode 100644 index 000000000000..4ef874f50f8e --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/write/object_storage/ObjectStorageFormattingWriterTest.kt @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.write.object_storage + +import io.airbyte.cdk.load.file.NoopProcessor +import io.airbyte.cdk.load.file.object_storage.BufferedFormattingWriter +import io.airbyte.cdk.load.file.object_storage.ObjectStorageFormattingWriter +import io.mockk.coEvery +import io.mockk.impl.annotations.MockK +import io.mockk.mockk +import java.io.ByteArrayOutputStream +import org.junit.jupiter.api.Test + +class ObjectStorageFormattingWriterTest { + @MockK(relaxed = true) lateinit var underlyingWriter: ObjectStorageFormattingWriter + + @Test + fun `buffered formatting writer never produces empty parts`() { + val outputStream = ByteArrayOutputStream() + outputStream.write("i am a header".toByteArray()) + val bufferedWriter = + BufferedFormattingWriter( + underlyingWriter, + outputStream, + NoopProcessor, + NoopProcessor.wrapper(outputStream), + ) + + assert(bufferedWriter.bufferSize == 0) { "buffer appears empty despite header" } + assert(bufferedWriter.takeBytes() == null) { "buffer yields no data despite header" } + assert(bufferedWriter.finish() == null) { "buffer yields no data despite header" } + } + + @Test + fun `buffered formatting writer yields entire buffer once any data has been added`() { + val outputStream = ByteArrayOutputStream() + outputStream.write("i am a header".toByteArray()) + val bufferedWriter = + BufferedFormattingWriter( + underlyingWriter, + outputStream, + NoopProcessor, + NoopProcessor.wrapper(outputStream), + ) + + assert(bufferedWriter.takeBytes() == null) + coEvery { bufferedWriter.accept(any()) } coAnswers { outputStream.write("!".toByteArray()) } + bufferedWriter.accept(mockk()) + val bytes = bufferedWriter.takeBytes() + assert(bytes != null) { "buffer yields data now that we've written to it" } + assert(bytes.contentEquals("i am a header!".toByteArray())) { + "buffer yields all data written to it" + } + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/write/object_storage/PartToObjectAccumulatorTest.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/write/object_storage/PartToObjectAccumulatorTest.kt new file mode 100644 index 000000000000..083da1bd193b --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/write/object_storage/PartToObjectAccumulatorTest.kt @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.write.object_storage + +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.file.object_storage.ObjectStorageClient +import io.airbyte.cdk.load.file.object_storage.Part +import io.airbyte.cdk.load.file.object_storage.StreamingUpload +import io.airbyte.cdk.load.message.object_storage.LoadablePart +import io.airbyte.cdk.load.state.object_storage.ObjectStorageDestinationState +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.mockk +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class PartToObjectAccumulatorTest { + private val streamDescriptor = DestinationStream.Descriptor("test", "stream") + + private lateinit var stream: DestinationStream + private lateinit var client: ObjectStorageClient<*> + private lateinit var streamingUpload: StreamingUpload<*> + private lateinit var metadata: Map + + @BeforeEach + fun setup() { + stream = mockk(relaxed = true) + client = mockk(relaxed = true) + streamingUpload = mockk(relaxed = true) + coEvery { stream.descriptor } returns streamDescriptor + metadata = ObjectStorageDestinationState.metadataFor(stream) + coEvery { client.startStreamingUpload(any(), any()) } returns streamingUpload + coEvery { streamingUpload.uploadPart(any(), any()) } returns Unit + coEvery { streamingUpload.complete() } returns mockk(relaxed = true) + } + + private fun makePart( + fileNumber: Int, + index: Int, + isFinal: Boolean = false, + empty: Boolean = false + ): LoadablePart = + LoadablePart( + Part( + "key$fileNumber", + fileNumber.toLong(), + index, + if (empty) { + null + } else { + ByteArray(0) + }, + isFinal + ) + ) + + @Test + fun `test part accumulation`() = runTest { + val acc = PartToObjectAccumulator(stream, client) + + // First part triggers starting the upload + val firstPartFile1 = makePart(1, 1) + acc.processBatch(firstPartFile1) + coVerify { client.startStreamingUpload(firstPartFile1.part.key, metadata) } + coVerify { + streamingUpload.uploadPart(firstPartFile1.part.bytes!!, firstPartFile1.part.partIndex) + } + + // All nonempty parts are added + (2 until 4).forEach { + val nonEmptyPart = makePart(1, it) + acc.processBatch(nonEmptyPart) + coVerify { + streamingUpload.uploadPart(nonEmptyPart.part.bytes!!, nonEmptyPart.part.partIndex) + } + } + + // New key starts new upload + val firstPartFile2 = makePart(2, 1) + acc.processBatch(firstPartFile2) + coVerify { client.startStreamingUpload(firstPartFile2.part.key, metadata) } + + // All empty parts are not added + repeat(2) { + val emptyPartFile1 = makePart(2, it + 2, empty = true) + acc.processBatch(emptyPartFile1) + // Ie, no more calls. + coVerify(exactly = 1) { + streamingUpload.uploadPart(any(), emptyPartFile1.part.partIndex) + } + } + + // The final part will trigger an upload + val finalPartFile1 = makePart(1, 4, isFinal = true) + acc.processBatch(finalPartFile1) + coVerify(exactly = 1) { streamingUpload.complete() } + + // The final part can be empty and/or added at any time and will still count for data + // sufficiency + val emptyFinalPartFile2 = makePart(2, 2, isFinal = true, empty = true) + acc.processBatch(emptyFinalPartFile2) + // empty part won't be uploaded + coVerify(exactly = 1) { + streamingUpload.uploadPart(any(), emptyFinalPartFile2.part.partIndex) + } + + // The missing part, even tho it isn't final, will trigger the completion + val nonEmptyPenultimatePartFile2 = makePart(2, 2) + acc.processBatch(nonEmptyPenultimatePartFile2) + coVerify { + streamingUpload.uploadPart( + nonEmptyPenultimatePartFile2.part.bytes!!, + nonEmptyPenultimatePartFile2.part.partIndex + ) + } + coVerify(exactly = 2) { streamingUpload.complete() } + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/write/object_storage/RecordToPartAccumulatorTest.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/write/object_storage/RecordToPartAccumulatorTest.kt new file mode 100644 index 000000000000..1712ff0c8e05 --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/test/kotlin/io/airbyte/cdk/load/write/object_storage/RecordToPartAccumulatorTest.kt @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.write.object_storage + +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.data.ObjectValue +import io.airbyte.cdk.load.file.object_storage.BufferedFormattingWriter +import io.airbyte.cdk.load.file.object_storage.BufferedFormattingWriterFactory +import io.airbyte.cdk.load.file.object_storage.ObjectStoragePathFactory +import io.airbyte.cdk.load.message.DestinationRecordAirbyteValue +import io.airbyte.cdk.load.message.object_storage.* +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.mockk +import java.io.OutputStream +import java.util.concurrent.atomic.AtomicLong +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class RecordToPartAccumulatorTest { + private val partSizeBytes: Long = 2L + private val fileSizeBytes: Long = 4L + + private lateinit var pathFactory: ObjectStoragePathFactory + private lateinit var bufferedWriterFactory: BufferedFormattingWriterFactory + private lateinit var bufferedWriter: BufferedFormattingWriter + private lateinit var stream: DestinationStream + + @BeforeEach + fun setup() { + pathFactory = mockk() + bufferedWriterFactory = mockk() + stream = mockk() + bufferedWriter = mockk() + coEvery { bufferedWriterFactory.create(any()) } returns bufferedWriter + coEvery { bufferedWriter.flush() } returns Unit + coEvery { bufferedWriter.close() } returns Unit + } + + private fun makeRecord(): DestinationRecordAirbyteValue = + DestinationRecordAirbyteValue( + DestinationStream.Descriptor("test", "stream"), + ObjectValue(linkedMapOf()), + 0L, + null, + ) + + private fun makeRecords(n: Int): Iterator = + (0 until n).map { makeRecord() }.listIterator() + + private fun makeBytes(n: Int): ByteArray? = + if (n == 0) { + null + } else (0 until n).map { it.toByte() }.toByteArray() + + @Test + fun `test parts are emitted correctly`() = runTest { + val fileNumber = AtomicLong(111L) + val acc = + RecordToPartAccumulator( + pathFactory = pathFactory, + bufferedWriterFactory = bufferedWriterFactory, + partSizeBytes = partSizeBytes, + fileSizeBytes = fileSizeBytes, + stream = stream, + fileNumber = fileNumber, + fileNameMapper = { "$it!" }, + ) + + val bufferSize = AtomicLong(0L) + coEvery { bufferedWriter.accept(any()) } answers + { + bufferSize.getAndIncrement() + Unit + } + coEvery { bufferedWriter.bufferSize } answers { bufferSize.get().toInt() } + coEvery { bufferedWriter.takeBytes() } answers + { + val bytes = makeBytes(bufferSize.get().toInt()) + bufferSize.set(0) + bytes + } + coEvery { bufferedWriter.finish() } answers + { + val bytes = makeBytes(bufferSize.get().toInt()) + bufferSize.set(0) + bytes + } + + coEvery { pathFactory.getPathToFile(any(), any()) } answers { "path.${secondArg()}" } + coEvery { pathFactory.supportsStaging } returns false + + // Object 1 + + // part 0->1/2b of 4b total => not data sufficient, should be first and empty + when (val batch = acc.processRecords(makeRecords(1), 0L, false) as ObjectStorageBatch) { + is LoadablePart -> { + assert(batch.part.isEmpty) + assert(batch.part.partIndex == 0) + assert(batch.part.fileNumber == 111L) + assert(!batch.isPersisted()) + assert(!batch.part.isFinal) + assert(batch.part.key == "path.111!") + } + else -> assert(false) + } + + // empty iterator, should be still first, empty, and nonfinal + when (val batch = acc.processRecords(makeRecords(0), 0L, false) as ObjectStorageBatch) { + is LoadablePart -> { + assert(batch.part.isEmpty) + assert(batch.part.partIndex == 0) + assert(batch.part.fileNumber == 111L) + assert(!batch.isPersisted()) + assert(!batch.part.isFinal) + assert(batch.part.key == "path.111!") + } + else -> assert(false) + } + + // part 1->3/2b of 4b total => data sufficient for part, should be first part and nonfinal + when (val batch = acc.processRecords(makeRecords(2), 0L, false) as ObjectStorageBatch) { + is LoadablePart -> { + assert(batch.part.bytes.contentEquals(makeBytes(3))) + assert(batch.part.partIndex == 1) + assert(batch.part.fileNumber == 111L) + assert(!batch.isPersisted()) + assert(!batch.part.isFinal) + assert(batch.part.key == "path.111!") + } + else -> assert(false) + } + + // part 3->4/2b of 4b total => data sufficient for file (but not part! this is expected!), + // should be second part and final (and not empty) + when (val batch = acc.processRecords(makeRecords(1), 0L, false) as ObjectStorageBatch) { + is LoadablePart -> { + assert(batch.part.bytes.contentEquals(makeBytes(1))) + assert(batch.part.partIndex == 2) + assert(batch.part.fileNumber == 111L) + assert(!batch.isPersisted()) + assert(batch.part.isFinal) + assert(batch.part.key == "path.111!") + } + else -> assert(false) + } + + // Object 2 + + // Next part 10/4b => data sufficient, should be first and final + when (val batch = acc.processRecords(makeRecords(10), 0L, false) as ObjectStorageBatch) { + is LoadablePart -> { + assert(batch.part.bytes.contentEquals(makeBytes(10))) + assert(batch.part.partIndex == 1) + assert(batch.part.fileNumber == 112L) + assert(!batch.isPersisted()) + assert(batch.part.isFinal) + assert(batch.part.key == "path.112!") + } + else -> assert(false) + } + + // Object 3: empty eos, should be final and empty + + when (val batch = acc.processRecords(makeRecords(0), 0L, true) as ObjectStorageBatch) { + is LoadablePart -> { + assert(batch.part.isEmpty) + assert(batch.part.partIndex == 0) + assert(batch.part.fileNumber == 113L) + assert(!batch.isPersisted()) + assert(batch.part.isFinal) + assert(batch.part.key == "path.113!") + } + else -> assert(false) + } + + // One flush per call, one create/close per finished object + coVerify(exactly = 3) { bufferedWriterFactory.create(any()) } + coVerify(exactly = 6) { bufferedWriter.flush() } + coVerify(exactly = 3) { bufferedWriter.close() } + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/testFixtures/kotlin/io/airbyte/cdk/load/MockObjectStorageClient.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/testFixtures/kotlin/io/airbyte/cdk/load/MockObjectStorageClient.kt new file mode 100644 index 000000000000..c261efcae958 --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/testFixtures/kotlin/io/airbyte/cdk/load/MockObjectStorageClient.kt @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings +import io.airbyte.cdk.load.file.StreamProcessor +import io.airbyte.cdk.load.file.object_storage.ObjectStorageClient +import io.airbyte.cdk.load.file.object_storage.RemoteObject +import io.airbyte.cdk.load.file.object_storage.StreamingUpload +import io.micronaut.context.annotation.Requires +import jakarta.inject.Singleton +import java.io.ByteArrayOutputStream +import java.io.InputStream +import java.io.OutputStream +import java.util.concurrent.ConcurrentHashMap +import kotlinx.coroutines.flow.flow + +class MockRemoteObject( + override val key: String, + override val storageConfig: Int, + val data: ByteArray, + val metadata: Map = emptyMap() +) : RemoteObject + +@SuppressFBWarnings("NP_NONNULL_PARAM_VIOLATION", justification = "Kotlin async continuation") +@Singleton +@Requires(env = ["MockObjectStorageClient"]) +class MockObjectStorageClient : ObjectStorageClient { + private val objects = ConcurrentHashMap() + + override suspend fun list(prefix: String) = flow { + objects.values.filter { it.key.startsWith(prefix) }.forEach { emit(it) } + } + + override suspend fun move(remoteObject: MockRemoteObject, toKey: String): MockRemoteObject { + val oldObject = + objects.remove(remoteObject.key) ?: throw IllegalArgumentException("Object not found") + val newObject = MockRemoteObject(toKey, oldObject.storageConfig, oldObject.data) + objects[toKey] = newObject + return newObject + } + + override suspend fun move(key: String, toKey: String): MockRemoteObject { + val remoteObject = objects[key] ?: throw IllegalArgumentException("Object not found") + return move(remoteObject, toKey) + } + + override suspend fun get(key: String, block: (InputStream) -> R): R { + val remoteObject = objects[key] ?: throw IllegalArgumentException("Object not found") + return block(remoteObject.data.inputStream()) + } + + override suspend fun getMetadata(key: String): Map { + return objects[key]?.metadata ?: emptyMap() + } + + override suspend fun put(key: String, bytes: ByteArray): MockRemoteObject { + val remoteObject = MockRemoteObject(key, 0, bytes) + objects[key] = remoteObject + return remoteObject + } + + override suspend fun delete(key: String) { + objects.remove(key) + } + + override suspend fun streamingUpload( + key: String, + metadata: Map, + streamProcessor: StreamProcessor?, + block: suspend (OutputStream) -> Unit + ): MockRemoteObject { + val outputStream = ByteArrayOutputStream() + block(outputStream) + val remoteObject = MockRemoteObject(key, 0, outputStream.toByteArray(), metadata) + objects[key] = remoteObject + return remoteObject + } + + override suspend fun delete(remoteObject: MockRemoteObject) { + objects.remove(remoteObject.key) + } + + override suspend fun startStreamingUpload( + key: String, + metadata: Map + ): StreamingUpload { + TODO("Not yet implemented") + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/testFixtures/kotlin/io/airbyte/cdk/load/MockPathFactory.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/testFixtures/kotlin/io/airbyte/cdk/load/MockPathFactory.kt new file mode 100644 index 000000000000..c76239ebcec1 --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/testFixtures/kotlin/io/airbyte/cdk/load/MockPathFactory.kt @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load + +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.file.object_storage.PathFactory +import io.airbyte.cdk.load.file.object_storage.PathMatcher +import io.micronaut.context.annotation.Requires +import jakarta.inject.Singleton + +@Singleton +@Requires(env = ["MockPathFactory"]) +open class MockPathFactory : PathFactory { + open var doSupportStaging = false + + override val supportsStaging: Boolean + get() = doSupportStaging + override val prefix: String + get() = "prefix" + + private fun fromStream(stream: DestinationStream): String { + return "${stream.descriptor.namespace}/${stream.descriptor.name}" + } + + override fun getStagingDirectory( + stream: DestinationStream, + substituteStreamAndNamespaceOnly: Boolean + ): String { + return "$prefix/staging/${fromStream(stream)}" + } + + override fun getFinalDirectory( + stream: DestinationStream, + substituteStreamAndNamespaceOnly: Boolean + ): String { + return "$prefix/${fromStream(stream)}" + } + + override fun getPathToFile( + stream: DestinationStream, + partNumber: Long?, + isStaging: Boolean, + extension: String? + ): String { + val prefix = if (isStaging) getStagingDirectory(stream) else getFinalDirectory(stream) + return "${prefix}file" + } + + override fun getLongestStreamConstantPrefix( + stream: DestinationStream, + isStaging: Boolean + ): String { + return if (isStaging) { + getStagingDirectory(stream) + } else { + getFinalDirectory(stream) + } + } + + override fun getPathMatcher( + stream: DestinationStream, + suffixPattern: String? // ignored + ): PathMatcher { + return PathMatcher( + regex = + Regex( + "$prefix/(${stream.descriptor.namespace})/(${stream.descriptor.name})/(.*)-(.*)$" + ), + variableToIndex = mapOf("part_number" to 4) + ) + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-object-storage/src/testFixtures/kotlin/io/airbyte/cdk/load/ObjectStorageDataDumper.kt b/airbyte-cdk/bulk/toolkits/load-object-storage/src/testFixtures/kotlin/io/airbyte/cdk/load/ObjectStorageDataDumper.kt index 00210b252097..fdbb0062d279 100644 --- a/airbyte-cdk/bulk/toolkits/load-object-storage/src/testFixtures/kotlin/io/airbyte/cdk/load/ObjectStorageDataDumper.kt +++ b/airbyte-cdk/bulk/toolkits/load-object-storage/src/testFixtures/kotlin/io/airbyte/cdk/load/ObjectStorageDataDumper.kt @@ -12,9 +12,9 @@ import io.airbyte.cdk.load.command.object_storage.ObjectStorageCompressionConfig import io.airbyte.cdk.load.command.object_storage.ObjectStorageFormatConfiguration import io.airbyte.cdk.load.command.object_storage.ParquetFormatConfiguration import io.airbyte.cdk.load.data.avro.toAirbyteValue -import io.airbyte.cdk.load.data.avro.toAvroSchema import io.airbyte.cdk.load.data.csv.toAirbyteValue import io.airbyte.cdk.load.data.json.toAirbyteValue +import io.airbyte.cdk.load.data.withAirbyteMeta import io.airbyte.cdk.load.file.GZIPProcessor import io.airbyte.cdk.load.file.NoopProcessor import io.airbyte.cdk.load.file.avro.toAvroReader @@ -22,12 +22,16 @@ import io.airbyte.cdk.load.file.object_storage.ObjectStorageClient import io.airbyte.cdk.load.file.object_storage.ObjectStoragePathFactory import io.airbyte.cdk.load.file.object_storage.RemoteObject import io.airbyte.cdk.load.file.parquet.toParquetReader +import io.airbyte.cdk.load.state.object_storage.ObjectStorageDestinationState.Companion.OPTIONAL_ORDINAL_SUFFIX_PATTERN import io.airbyte.cdk.load.test.util.OutputRecord +import io.airbyte.cdk.load.test.util.maybeUnflatten import io.airbyte.cdk.load.test.util.toOutputRecord import io.airbyte.cdk.load.util.deserializeToNode +import java.io.BufferedReader import java.io.InputStream import java.util.zip.GZIPInputStream import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.toList import kotlinx.coroutines.runBlocking @@ -43,11 +47,17 @@ class ObjectStorageDataDumper( private val compressionConfig: ObjectStorageCompressionConfiguration<*>? = null ) { fun dump(): List { - val prefix = pathFactory.getFinalDirectory(stream).toString() + // Note: this is implicitly a test of the `streamConstant` final directory + // and the path matcher, so a failure here might imply a bug in the metadata-based + // destination state loader, which lists by `prefix` and filters against the matcher. + val prefix = pathFactory.getLongestStreamConstantPrefix(stream, isStaging = false) + val matcher = + pathFactory.getPathMatcher(stream, suffixPattern = OPTIONAL_ORDINAL_SUFFIX_PATTERN) return runBlocking { withContext(Dispatchers.IO) { client .list(prefix) + .filter { matcher.match(it.key) != null } .map { listedObject: RemoteObject<*> -> client.get(listedObject.key) { objectData: InputStream -> val decompressed = @@ -66,9 +76,33 @@ class ObjectStorageDataDumper( } } + fun dumpFile(): List { + val prefix = pathFactory.getFinalDirectory(stream).toString() + return runBlocking { + withContext(Dispatchers.IO) { + client + .list(prefix) + .map { listedObject: RemoteObject<*> -> + client.get(listedObject.key) { objectData: InputStream -> + val decompressed = + when (compressionConfig?.compressor) { + is GZIPProcessor -> GZIPInputStream(objectData) + is NoopProcessor, + null -> objectData + else -> error("Unsupported compressor") + } + BufferedReader(decompressed.reader()).readText() + } + } + .toList() + } + } + } + @Suppress("DEPRECATION") - private fun readLines(inputStream: InputStream): List = - when (formatConfig) { + private fun readLines(inputStream: InputStream): List { + val wasFlattened = formatConfig.rootLevelFlattening + return when (formatConfig) { is JsonFormatConfiguration -> { inputStream .bufferedReader() @@ -76,7 +110,8 @@ class ObjectStorageDataDumper( .map { line -> line .deserializeToNode() - .toAirbyteValue(stream.schemaWithMeta) + .toAirbyteValue() + .maybeUnflatten(wasFlattened) .toOutputRecord() } .toList() @@ -84,29 +119,29 @@ class ObjectStorageDataDumper( is CSVFormatConfiguration -> { CSVParser(inputStream.bufferedReader(), CSVFormat.DEFAULT.withHeader()).use { it.records.map { record -> - record.toAirbyteValue(stream.schemaWithMeta).toOutputRecord() + record + .toAirbyteValue(stream.schema.withAirbyteMeta(wasFlattened)) + .maybeUnflatten(wasFlattened) + .toOutputRecord() } } } is AvroFormatConfiguration -> { - inputStream - .toAvroReader(stream.schemaWithMeta.toAvroSchema(stream.descriptor)) - .use { reader -> - reader - .recordSequence() - .map { it.toAirbyteValue(stream.schemaWithMeta).toOutputRecord() } - .toList() - } + inputStream.toAvroReader(stream.descriptor).use { reader -> + reader + .recordSequence() + .map { it.toAirbyteValue().maybeUnflatten(wasFlattened).toOutputRecord() } + .toList() + } } is ParquetFormatConfiguration -> { - inputStream - .toParquetReader(stream.schemaWithMeta.toAvroSchema(stream.descriptor)) - .use { reader -> - reader - .recordSequence() - .map { it.toAirbyteValue(stream.schemaWithMeta).toOutputRecord() } - .toList() - } + inputStream.toParquetReader(stream.descriptor).use { reader -> + reader + .recordSequence() + .map { it.toAirbyteValue().maybeUnflatten(wasFlattened).toOutputRecord() } + .toList() + } } } + } } diff --git a/airbyte-cdk/bulk/toolkits/load-parquet/src/main/kotlin/io/airbyte/cdk/load/data/parquet/ParquetMapperPipelineFactory.kt b/airbyte-cdk/bulk/toolkits/load-parquet/src/main/kotlin/io/airbyte/cdk/load/data/parquet/ParquetMapperPipelineFactory.kt new file mode 100644 index 000000000000..605eb097385d --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-parquet/src/main/kotlin/io/airbyte/cdk/load/data/parquet/ParquetMapperPipelineFactory.kt @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.load.data.parquet + +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.data.AirbyteSchemaNoopMapper +import io.airbyte.cdk.load.data.AirbyteValueDeepCoercingMapper +import io.airbyte.cdk.load.data.AirbyteValueNoopMapper +import io.airbyte.cdk.load.data.FailOnAllUnknownTypesExceptNull +import io.airbyte.cdk.load.data.MapperPipeline +import io.airbyte.cdk.load.data.MapperPipelineFactory +import io.airbyte.cdk.load.data.MergeUnions +import io.airbyte.cdk.load.data.NullOutOfRangeIntegers +import io.airbyte.cdk.load.data.SchemalessValuesToJsonString +import io.airbyte.cdk.load.data.TimeStringToInteger +import io.airbyte.cdk.load.data.UnionTypeToDisjointRecord +import io.airbyte.cdk.load.data.UnionValueToDisjointRecord + +class ParquetMapperPipelineFactory : MapperPipelineFactory { + override fun create(stream: DestinationStream): MapperPipeline = + MapperPipeline( + stream.schema, + listOf( + FailOnAllUnknownTypesExceptNull() to AirbyteValueNoopMapper(), + MergeUnions() to AirbyteValueNoopMapper(), + AirbyteSchemaNoopMapper() to AirbyteValueDeepCoercingMapper(), + // We need to maintain the original ObjectWithNoProperties/etc type. + // For example, if a stream declares no columns, we will (correctly) recognize + // the root schema as ObjectTypeWithEmptySchema. + // If we then map that root schema to StringType, then + // AirbyteTypeToAirbyteTypeWithMeta will crash on it. + // Furthermore, in UnionTypeToDisjointRecord, this enables us to write thes fields + // as "object" rather than as "string". + AirbyteSchemaNoopMapper() to SchemalessValuesToJsonString(), + AirbyteSchemaNoopMapper() to NullOutOfRangeIntegers(), + AirbyteSchemaNoopMapper() to TimeStringToInteger(), + UnionTypeToDisjointRecord() to UnionValueToDisjointRecord(), + ), + ) +} diff --git a/airbyte-cdk/bulk/toolkits/load-parquet/src/main/kotlin/io/airbyte/cdk/load/file/parquet/ParquetWriter.kt b/airbyte-cdk/bulk/toolkits/load-parquet/src/main/kotlin/io/airbyte/cdk/load/file/parquet/ParquetWriter.kt index a64fd51e137d..588d31a07803 100644 --- a/airbyte-cdk/bulk/toolkits/load-parquet/src/main/kotlin/io/airbyte/cdk/load/file/parquet/ParquetWriter.kt +++ b/airbyte-cdk/bulk/toolkits/load-parquet/src/main/kotlin/io/airbyte/cdk/load/file/parquet/ParquetWriter.kt @@ -10,6 +10,7 @@ import org.apache.avro.Schema import org.apache.avro.generic.GenericRecord import org.apache.hadoop.conf.Configuration import org.apache.parquet.avro.AvroParquetWriter +import org.apache.parquet.avro.AvroWriteSupport.WRITE_OLD_LIST_STRUCTURE import org.apache.parquet.hadoop.ParquetWriter as ApacheParquetWriter import org.apache.parquet.hadoop.metadata.CompressionCodecName import org.apache.parquet.io.OutputFile @@ -44,7 +45,7 @@ fun OutputStream.toParquetWriter( } override fun createOrOverwrite(blockSizeHint: Long) = create(blockSizeHint) - override fun supportsBlockSize() = false + override fun supportsBlockSize() = true override fun defaultBlockSize() = 0L } @@ -52,13 +53,15 @@ fun OutputStream.toParquetWriter( val writer = AvroParquetWriter.builder(outputFile) .withSchema(avroSchema) - .withConf(Configuration()) + // needed so that we can have arrays containing null elements + .withConf(Configuration().apply { setBoolean(WRITE_OLD_LIST_STRUCTURE, false) }) .withCompressionCodec(config.compressionCodec) .withRowGroupSize(config.blockSizeMb * 1024 * 1024L) .withPageSize(config.pageSizeKb * 1024) .withDictionaryPageSize(config.dictionaryPageSizeKb * 1024) .withDictionaryEncoding(config.dictionaryEncoding) .withMaxPaddingSize(config.maxPaddingSizeMb * 1024 * 1024) + .withRowGroupSize(5 * 1024L * 1024L) .build() return ParquetWriter(writer) diff --git a/airbyte-cdk/bulk/toolkits/load-parquet/src/test/kotlin/ParquetMapperPipelineTest.kt b/airbyte-cdk/bulk/toolkits/load-parquet/src/test/kotlin/ParquetMapperPipelineTest.kt new file mode 100644 index 000000000000..a390507429df --- /dev/null +++ b/airbyte-cdk/bulk/toolkits/load-parquet/src/test/kotlin/ParquetMapperPipelineTest.kt @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +import io.airbyte.cdk.load.command.DestinationStream +import io.airbyte.cdk.load.data.* +import io.airbyte.cdk.load.data.parquet.ParquetMapperPipelineFactory +import io.mockk.every +import io.mockk.mockk +import org.junit.jupiter.api.Test + +class ParquetMapperPipelineTest { + @Test + fun `test conversions nested in unions`() { + val stream = mockk() + val schema = + ObjectType( + linkedMapOf( + "id" to FieldType(StringType, true), + "plan" to + FieldType( + UnionType( + setOf( + ObjectType( + linkedMapOf( + "id" to FieldType(StringType, true), + "price" to FieldType(NumberType, true), + "tiers" to + FieldType( + UnionType( + setOf( + ObjectType( + linkedMapOf( + "up_to" to + FieldType( + IntegerType, + true + ), + "name" to + FieldType(StringType, true), + ) + ), + StringType + ) + ), + true + ), + "metadata" to FieldType(ObjectTypeWithEmptySchema, true) + ) + ), + StringType + ) + ), + true + ) + ) + ) + every { stream.schema } returns schema + every { stream.syncId } returns 101L + every { stream.generationId } returns 202L + + val record = + ObjectValue( + linkedMapOf( + "id" to StringValue("1"), + "plan" to + ObjectValue( + linkedMapOf( + "id" to StringValue("2"), + "price" to NumberValue(10.0.toBigDecimal()), + "tiers" to + ObjectValue( + linkedMapOf( + "up_to" to IntegerValue(10), + "name" to StringValue("tier1") + ) + ), + "metadata" to + ObjectValue(linkedMapOf("key" to StringValue("value"))) + ) + ), + ) + ) + val pipeline = ParquetMapperPipelineFactory().create(stream) + val schemaMapped = pipeline.finalSchema as ObjectType + val (recordMapped, _) = pipeline.map(record) + + val planSchema = schemaMapped.properties["plan"]?.type as ObjectType + val planObjectOption = planSchema.properties["object"]?.type as ObjectType + assert(planObjectOption.properties["tiers"]?.type is ObjectType) { + "Unions nested within converted unions should also be converted" + } + + val planValue = (recordMapped as ObjectValue).values["plan"] as ObjectValue + val planObjectValue = planValue.values["object"] as ObjectValue + assert(planObjectValue.values["metadata"] is StringValue) { + "Schemaless types values nested within converted unions should be converted" + } + } +} diff --git a/airbyte-cdk/bulk/toolkits/load-parquet/src/testFixtures/kotlin/io/airbyte/cdk/load/file/parquet/ParquetReader.kt b/airbyte-cdk/bulk/toolkits/load-parquet/src/testFixtures/kotlin/io/airbyte/cdk/load/file/parquet/ParquetReader.kt index 384a2753bad2..f2f410967406 100644 --- a/airbyte-cdk/bulk/toolkits/load-parquet/src/testFixtures/kotlin/io/airbyte/cdk/load/file/parquet/ParquetReader.kt +++ b/airbyte-cdk/bulk/toolkits/load-parquet/src/testFixtures/kotlin/io/airbyte/cdk/load/file/parquet/ParquetReader.kt @@ -4,11 +4,11 @@ package io.airbyte.cdk.load.file.parquet +import io.airbyte.cdk.load.command.DestinationStream import java.io.Closeable import java.io.File import java.io.InputStream import kotlin.io.path.outputStream -import org.apache.avro.Schema import org.apache.avro.generic.GenericRecord import org.apache.hadoop.fs.Path import org.apache.parquet.avro.AvroParquetReader @@ -31,11 +31,10 @@ class ParquetReader( } } -fun InputStream.toParquetReader(avroSchema: Schema): ParquetReader { - +fun InputStream.toParquetReader(descriptor: DestinationStream.Descriptor): ParquetReader { val tmpFile = kotlin.io.path.createTempFile( - prefix = "${avroSchema.namespace}.${avroSchema.name}", + prefix = "${descriptor.namespace}.${descriptor.name}", suffix = ".avro" ) tmpFile.outputStream().use { outputStream -> this.copyTo(outputStream) } diff --git a/airbyte-cdk/bulk/toolkits/load-s3/build.gradle b/airbyte-cdk/bulk/toolkits/load-s3/build.gradle index 00336f267d49..ec1667e9b2ca 100644 --- a/airbyte-cdk/bulk/toolkits/load-s3/build.gradle +++ b/airbyte-cdk/bulk/toolkits/load-s3/build.gradle @@ -5,5 +5,6 @@ dependencies { api project(':airbyte-cdk:bulk:toolkits:bulk-cdk-toolkit-load-object-storage') testFixturesApi(testFixtures(project(":airbyte-cdk:bulk:toolkits:bulk-cdk-toolkit-load-object-storage"))) - implementation("aws.sdk.kotlin:s3:1.0.0") + implementation("aws.sdk.kotlin:s3:1.3.98") + implementation("aws.smithy.kotlin:http-client-engine-okhttp:1.3.31") } diff --git a/airbyte-cdk/bulk/toolkits/load-s3/src/main/kotlin/io/airbyte/cdk/load/command/s3/S3BucketSpecification.kt b/airbyte-cdk/bulk/toolkits/load-s3/src/main/kotlin/io/airbyte/cdk/load/command/s3/S3BucketSpecification.kt index 8b537653175a..033bd92d8392 100644 --- a/airbyte-cdk/bulk/toolkits/load-s3/src/main/kotlin/io/airbyte/cdk/load/command/s3/S3BucketSpecification.kt +++ b/airbyte-cdk/bulk/toolkits/load-s3/src/main/kotlin/io/airbyte/cdk/load/command/s3/S3BucketSpecification.kt @@ -6,43 +6,46 @@ package io.airbyte.cdk.load.command.s3 import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonPropertyDescription +import com.fasterxml.jackson.annotation.JsonValue import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaInject import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaTitle -enum class S3BucketRegion { - `af-south-1`, - `ap-east-1`, - `ap-northeast-1`, - `ap-northeast-2`, - `ap-northeast-3`, - `ap-south-1`, - `ap-south-2`, - `ap-southeast-1`, - `ap-southeast-2`, - `ap-southeast-3`, - `ap-southeast-4`, - `ca-central-1`, - `ca-west-1`, - `cn-north-1`, - `cn-northwest-1`, - `eu-central-1`, - `eu-central-2`, - `eu-north-1`, - `eu-south-1`, - `eu-south-2`, - `eu-west-1`, - `eu-west-2`, - `eu-west-3`, - `il-central-1`, - `me-central-1`, - `me-south-1`, - `sa-east-1`, - `us-east-1`, - `us-east-2`, - `us-gov-east-1`, - `us-gov-west-1`, - `us-west-1`, - `us-west-2` +// First region is a kotlin-legal empty string +enum class S3BucketRegion(@get:JsonValue val region: String) { + NO_REGION(""), + `af-south-1`("af-south-1"), + `ap-east-1`("ap-east-1"), + `ap-northeast-1`("ap-northeast-1"), + `ap-northeast-2`("ap-northeast-2"), + `ap-northeast-3`("ap-northeast-3"), + `ap-south-1`("ap-south-1"), + `ap-south-2`("ap-south-2"), + `ap-southeast-1`("ap-southeast-1"), + `ap-southeast-2`("ap-southeast-2"), + `ap-southeast-3`("ap-southeast-3"), + `ap-southeast-4`("ap-southeast-4"), + `ca-central-1`("ca-central-1"), + `ca-west-1`("ca-west-1"), + `cn-north-1`("cn-north-1"), + `cn-northwest-1`("cn-northwest-1"), + `eu-central-1`("eu-central-1"), + `eu-central-2`("eu-central-2"), + `eu-north-1`("eu-north-1"), + `eu-south-1`("eu-south-1"), + `eu-south-2`("eu-south-2"), + `eu-west-1`("eu-west-1"), + `eu-west-2`("eu-west-2"), + `eu-west-3`("eu-west-3"), + `il-central-1`("il-central-1"), + `me-central-1`("me-central-1"), + `me-south-1`("me-south-1"), + `sa-east-1`("sa-east-1"), + `us-east-1`("us-east-1"), + `us-east-2`("us-east-2"), + `us-gov-east-1`("us-gov-east-1"), + `us-gov-west-1`("us-gov-west-1"), + `us-west-1`("us-west-1"), + `us-west-2`("us-west-2") } /** @@ -66,7 +69,7 @@ interface S3BucketSpecification { ) @get:JsonProperty("s3_bucket_region", defaultValue = "") @get:JsonSchemaInject(json = """{"examples":["us-east-1"]}""") - val s3BucketRegion: S3BucketRegion + val s3BucketRegion: S3BucketRegion? @get:JsonSchemaTitle("S3 Endpoint") @get:JsonPropertyDescription( @@ -77,7 +80,11 @@ interface S3BucketSpecification { val s3Endpoint: String? fun toS3BucketConfiguration(): S3BucketConfiguration { - return S3BucketConfiguration(s3BucketName, s3BucketRegion, s3Endpoint) + return S3BucketConfiguration( + s3BucketName, + s3BucketRegion ?: S3BucketRegion.NO_REGION, + s3Endpoint + ) } } diff --git a/airbyte-cdk/bulk/toolkits/load-s3/src/main/kotlin/io/airbyte/cdk/load/command/s3/S3PathSpecification.kt b/airbyte-cdk/bulk/toolkits/load-s3/src/main/kotlin/io/airbyte/cdk/load/command/s3/S3PathSpecification.kt index b7a76991a3d3..0bf40e601d40 100644 --- a/airbyte-cdk/bulk/toolkits/load-s3/src/main/kotlin/io/airbyte/cdk/load/command/s3/S3PathSpecification.kt +++ b/airbyte-cdk/bulk/toolkits/load-s3/src/main/kotlin/io/airbyte/cdk/load/command/s3/S3PathSpecification.kt @@ -50,19 +50,31 @@ interface S3PathSpecification { @get:JsonSchemaInject(json = """{"examples":["data_sync/test"]}""") val s3BucketPath: String - @get:JsonSchemaTitle("S3 Staging Prefix") - @get:JsonPropertyDescription( - "Path to use when staging data in the bucket directory. Documentation TBD." - ) - @get:JsonProperty("s3_staging_prefix", defaultValue = "{s3_bucket_path}/__airbyte_tmp") - @get:JsonSchemaInject(json = """{"examples":["__staging/data_sync/test"]}""") - val s3StagingPrefix: String? + // Uncomment to re-enable staging + + // @get:JsonSchemaTitle("Use a Staging Directory") + // @get:JsonPropertyDescription( + // "Whether to use a staging directory in the bucket based on the s3_staging_prefix. If + // this is not set, airbyte will maintain sync integrity by adding metadata to each object." + // ) + // @get:JsonProperty("use_staging_directory", defaultValue = "false") + // val useStagingDirectory: Boolean? + // + // @get:JsonSchemaTitle("S3 Staging Prefix") + // @get:JsonPropertyDescription( + // "Path to use when staging data in the bucket directory. Airbyte will stage data here + // during sync and/or write small manifest/recovery files." + // ) + // @get:JsonProperty("s3_staging_prefix") + // @get:JsonSchemaInject(json = """{"examples":["__staging/data_sync/test"]}""") + // val s3StagingPrefix: String? fun toObjectStoragePathConfiguration(): ObjectStoragePathConfiguration = ObjectStoragePathConfiguration( prefix = s3BucketPath, - stagingPrefix = s3StagingPrefix, + stagingPrefix = null, pathSuffixPattern = s3PathFormat, - fileNamePattern = fileNamePattern + fileNamePattern = fileNamePattern, + usesStagingDirectory = false ) } diff --git a/airbyte-cdk/bulk/toolkits/load-s3/src/main/kotlin/io/airbyte/cdk/load/file/s3/S3Client.kt b/airbyte-cdk/bulk/toolkits/load-s3/src/main/kotlin/io/airbyte/cdk/load/file/s3/S3Client.kt index 0d8275c31fa6..48558739a029 100644 --- a/airbyte-cdk/bulk/toolkits/load-s3/src/main/kotlin/io/airbyte/cdk/load/file/s3/S3Client.kt +++ b/airbyte-cdk/bulk/toolkits/load-s3/src/main/kotlin/io/airbyte/cdk/load/file/s3/S3Client.kt @@ -4,19 +4,25 @@ package io.airbyte.cdk.load.file.s3 +import aws.sdk.kotlin.runtime.auth.credentials.AssumeRoleParameters +import aws.sdk.kotlin.runtime.auth.credentials.DefaultChainCredentialsProvider import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider +import aws.sdk.kotlin.runtime.auth.credentials.StsAssumeRoleCredentialsProvider import aws.sdk.kotlin.services.s3.model.CopyObjectRequest import aws.sdk.kotlin.services.s3.model.CreateMultipartUploadRequest import aws.sdk.kotlin.services.s3.model.DeleteObjectRequest import aws.sdk.kotlin.services.s3.model.GetObjectRequest +import aws.sdk.kotlin.services.s3.model.HeadObjectRequest import aws.sdk.kotlin.services.s3.model.ListObjectsRequest import aws.sdk.kotlin.services.s3.model.PutObjectRequest +import aws.smithy.kotlin.runtime.auth.awscredentials.CredentialsProvider import aws.smithy.kotlin.runtime.content.ByteStream import aws.smithy.kotlin.runtime.content.toInputStream +import aws.smithy.kotlin.runtime.http.engine.okhttp.OkHttpEngine +import aws.smithy.kotlin.runtime.net.url.Url import edu.umd.cs.findbugs.annotations.SuppressFBWarnings import io.airbyte.cdk.load.command.aws.AWSAccessKeyConfigurationProvider -import io.airbyte.cdk.load.command.object_storage.ObjectStorageCompressionConfiguration -import io.airbyte.cdk.load.command.object_storage.ObjectStorageCompressionConfigurationProvider +import io.airbyte.cdk.load.command.aws.AWSArnRoleConfigurationProvider import io.airbyte.cdk.load.command.object_storage.ObjectStorageUploadConfiguration import io.airbyte.cdk.load.command.object_storage.ObjectStorageUploadConfigurationProvider import io.airbyte.cdk.load.command.s3.S3BucketConfiguration @@ -25,6 +31,7 @@ import io.airbyte.cdk.load.file.NoopProcessor import io.airbyte.cdk.load.file.StreamProcessor import io.airbyte.cdk.load.file.object_storage.ObjectStorageClient import io.airbyte.cdk.load.file.object_storage.RemoteObject +import io.airbyte.cdk.load.file.object_storage.StreamingUpload import io.github.oshai.kotlinlogging.KotlinLogging import io.micronaut.context.annotation.Factory import io.micronaut.context.annotation.Secondary @@ -32,6 +39,7 @@ import jakarta.inject.Singleton import java.io.ByteArrayOutputStream import java.io.InputStream import java.io.OutputStream +import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.flow.flow data class S3Object(override val key: String, override val storageConfig: S3BucketConfiguration) : @@ -45,7 +53,6 @@ class S3Client( private val client: aws.sdk.kotlin.services.s3.S3Client, val bucketConfig: S3BucketConfiguration, private val uploadConfig: ObjectStorageUploadConfiguration?, - private val compressionConfig: ObjectStorageCompressionConfiguration<*>? = null, ) : ObjectStorageClient { private val log = KotlinLogging.logger {} @@ -79,6 +86,10 @@ class S3Client( return S3Object(toKey, bucketConfig) } + override suspend fun move(key: String, toKey: String): S3Object { + return move(S3Object(key, bucketConfig), toKey) + } + override suspend fun get(key: String, block: (InputStream) -> R): R { val request = GetObjectRequest { bucket = bucketConfig.s3BucketName @@ -94,6 +105,14 @@ class S3Client( } } + override suspend fun getMetadata(key: String): Map { + val request = HeadObjectRequest { + bucket = bucketConfig.s3BucketName + this.key = key + } + return client.headObject(request).metadata ?: emptyMap() + } + override suspend fun put(key: String, bytes: ByteArray): S3Object { val request = PutObjectRequest { bucket = bucketConfig.s3BucketName @@ -112,21 +131,29 @@ class S3Client( client.deleteObject(request) } - override suspend fun streamingUpload( + override suspend fun delete(key: String) { + delete(S3Object(key, bucketConfig)) + } + + override suspend fun streamingUpload( key: String, + metadata: Map, + streamProcessor: StreamProcessor?, block: suspend (OutputStream) -> Unit ): S3Object { - return streamingUpload(key, compressionConfig?.compressor ?: NoopProcessor, block) + return streamingUploadInner(key, metadata, streamProcessor, block) } - override suspend fun streamingUpload( + private suspend fun streamingUploadInner( key: String, - streamProcessor: StreamProcessor, + metadata: Map, + streamProcessor: StreamProcessor?, block: suspend (OutputStream) -> Unit ): S3Object { val request = CreateMultipartUploadRequest { this.bucket = bucketConfig.s3BucketName this.key = key + this.metadata = metadata } val response = client.createMultipartUpload(request) val upload = @@ -134,48 +161,100 @@ class S3Client( client, response, ByteArrayOutputStream(), - streamProcessor, + streamProcessor ?: NoopProcessor, uploadConfig ) upload.runUsing(block) return S3Object(key, bucketConfig) } + + override suspend fun startStreamingUpload( + key: String, + metadata: Map + ): StreamingUpload { + val request = CreateMultipartUploadRequest { + this.bucket = bucketConfig.s3BucketName + this.key = key + this.metadata = metadata + } + val response = client.createMultipartUpload(request) + + log.info { "Starting multipart upload for $key (uploadId=${response.uploadId})" } + + return S3StreamingUpload(client, bucketConfig, response) + } } @Factory class S3ClientFactory( + private val arnRole: AWSArnRoleConfigurationProvider, private val keyConfig: AWSAccessKeyConfigurationProvider, private val bucketConfig: S3BucketConfigurationProvider, - private val uploadConifg: ObjectStorageUploadConfigurationProvider? = null, - private val compressionConfig: ObjectStorageCompressionConfigurationProvider<*>? = null, + private val uploadConfig: ObjectStorageUploadConfigurationProvider? = null, ) { companion object { fun make(config: T) where T : S3BucketConfigurationProvider, T : AWSAccessKeyConfigurationProvider, + T : AWSArnRoleConfigurationProvider, T : ObjectStorageUploadConfigurationProvider = - S3ClientFactory(config, config, config).make() + S3ClientFactory(config, config, config, config).make() } + private val AIRBYTE_STS_SESSION_NAME = "airbyte-sts-session" + private val EXTERNAL_ID = "AWS_ASSUME_ROLE_EXTERNAL_ID" + private val AWS_ACCESS_KEY_ID = "AWS_ACCESS_KEY_ID" + private val AWS_SECRET_ACCESS_KEY = "AWS_SECRET_ACCESS_KEY" + @Singleton @Secondary fun make(): S3Client { - val credentials = StaticCredentialsProvider { - accessKeyId = keyConfig.awsAccessKeyConfiguration.accessKeyId - secretAccessKey = keyConfig.awsAccessKeyConfiguration.secretAccessKey - } + val credsProvider: CredentialsProvider = + if (keyConfig.awsAccessKeyConfiguration.accessKeyId != null) { + StaticCredentialsProvider { + accessKeyId = keyConfig.awsAccessKeyConfiguration.accessKeyId + secretAccessKey = keyConfig.awsAccessKeyConfiguration.secretAccessKey + } + } else if (arnRole.awsArnRoleConfiguration.roleArn != null) { + // The Platform is expected to inject via credentials if ROLE_ARN is present. + val externalId = System.getenv(EXTERNAL_ID) // Consider injecting this dependency + val assumeRoleParams = + AssumeRoleParameters( + roleArn = arnRole.awsArnRoleConfiguration.roleArn!!, + roleSessionName = AIRBYTE_STS_SESSION_NAME, + externalId = externalId + ) + val creds = StaticCredentialsProvider { + accessKeyId = System.getenv(AWS_ACCESS_KEY_ID) + secretAccessKey = System.getenv(AWS_SECRET_ACCESS_KEY) + } + StsAssumeRoleCredentialsProvider( + bootstrapCredentialsProvider = creds, + assumeRoleParameters = assumeRoleParams + ) + } else { + DefaultChainCredentialsProvider() + } - val client = + val s3SdkClient = aws.sdk.kotlin.services.s3.S3Client { region = bucketConfig.s3BucketConfiguration.s3BucketRegion.name - credentialsProvider = credentials + credentialsProvider = credsProvider + endpointUrl = + bucketConfig.s3BucketConfiguration.s3Endpoint?.let { + if (it.isNotBlank()) { + Url.parse(it) + } else null + } + // Fix for connection reset issue: + // https://github.com/awslabs/aws-sdk-kotlin/issues/1214#issuecomment-2464831817 + httpClient(OkHttpEngine) { connectionIdlePollingInterval = 200.milliseconds } } return S3Client( - client, + s3SdkClient, bucketConfig.s3BucketConfiguration, - uploadConifg?.objectStorageUploadConfiguration, - compressionConfig?.objectStorageCompressionConfiguration, + uploadConfig?.objectStorageUploadConfiguration ) } } diff --git a/airbyte-cdk/bulk/toolkits/load-s3/src/main/kotlin/io/airbyte/cdk/load/file/s3/S3MultipartUpload.kt b/airbyte-cdk/bulk/toolkits/load-s3/src/main/kotlin/io/airbyte/cdk/load/file/s3/S3MultipartUpload.kt index 8a62b79fa869..b12dab4b4c52 100644 --- a/airbyte-cdk/bulk/toolkits/load-s3/src/main/kotlin/io/airbyte/cdk/load/file/s3/S3MultipartUpload.kt +++ b/airbyte-cdk/bulk/toolkits/load-s3/src/main/kotlin/io/airbyte/cdk/load/file/s3/S3MultipartUpload.kt @@ -10,8 +10,11 @@ import aws.sdk.kotlin.services.s3.model.CompletedPart import aws.sdk.kotlin.services.s3.model.CreateMultipartUploadResponse import aws.sdk.kotlin.services.s3.model.UploadPartRequest import aws.smithy.kotlin.runtime.content.ByteStream +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings import io.airbyte.cdk.load.command.object_storage.ObjectStorageUploadConfiguration +import io.airbyte.cdk.load.command.s3.S3BucketConfiguration import io.airbyte.cdk.load.file.StreamProcessor +import io.airbyte.cdk.load.file.object_storage.StreamingUpload import io.airbyte.cdk.load.util.setOnce import io.github.oshai.kotlinlogging.KotlinLogging import java.io.ByteArrayOutputStream @@ -21,6 +24,7 @@ import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import org.apache.mina.util.ConcurrentHashSet /** * An S3MultipartUpload that provides an [OutputStream] abstraction for writing data. This should @@ -41,24 +45,23 @@ class S3MultipartUpload( uploadConfig: ObjectStorageUploadConfiguration?, ) { private val log = KotlinLogging.logger {} - - private val uploadedParts = mutableListOf() private val partSize = - uploadConfig?.streamingUploadPartSize + uploadConfig?.uploadPartSizeBytes ?: throw IllegalStateException("Streaming upload part size is not configured") private val wrappingBuffer = streamProcessor.wrapper(underlyingBuffer) - private val workQueue = Channel Unit>(Channel.UNLIMITED) - private val closeOnce = AtomicBoolean(false) + private val partQueue = Channel(Channel.UNLIMITED) + private val isClosed = AtomicBoolean(false) /** * Run the upload using the provided block. This should only be used by the - * [S3Client.streamingUpload] method. Work items are processed asynchronously in the [launch] - * block. The for loop will suspend until [workQueue] is closed, after which the call to - * [complete] will finish the upload. + * [S3Client.streamingUpload] method. Completed partss are processed asynchronously in the + * [launch] block. The for loop will suspend until [partQueue] is closed, after which the call + * to [complete] will finish the upload. * * Moreover, [runUsing] will not return until the launch block exits. This ensures - * - work items are processed in order - * - minimal work is done in [runBlocking] (just enough to enqueue the work items) + * - parts are processed in order + * - minimal work is done in [runBlocking] (just enough to enqueue the parts, and only once per + * part) * - the upload will not complete until the [OutputStream.close] is called (either by the user * in [block] or when the [use] block terminates). * - the upload will not complete until all the work is done @@ -68,10 +71,17 @@ class S3MultipartUpload( "Starting multipart upload to ${response.bucket}/${response.key} (${response.uploadId}" } launch { - for (item in workQueue) { - item() + val uploadedParts = mutableListOf() + for (bytes in partQueue) { + val part = uploadPart(bytes, uploadedParts) + uploadedParts.add(part) + } + streamProcessor.partFinisher.invoke(wrappingBuffer) + if (underlyingBuffer.size() > 0) { + val part = uploadPart(underlyingBuffer.toByteArray(), uploadedParts) + uploadedParts.add(part) } - complete() + complete(uploadedParts) } UploadStream().use { block(it) } log.info { @@ -80,57 +90,56 @@ class S3MultipartUpload( } inner class UploadStream : OutputStream() { - override fun close() = runBlocking { - if (closeOnce.setOnce()) { - workQueue.send { workQueue.close() } + override fun close() { + if (isClosed.setOnce()) { + partQueue.close() } } - override fun flush() = runBlocking { workQueue.send { wrappingBuffer.flush() } } + override fun flush() = wrappingBuffer.flush() - override fun write(b: Int) = runBlocking { - workQueue.send { - wrappingBuffer.write(b) - if (underlyingBuffer.size() >= partSize) { - uploadPart() - } + override fun write(b: Int) { + wrappingBuffer.write(b) + if (underlyingBuffer.size() >= partSize) { + enqueuePart() } } - override fun write(b: ByteArray) = runBlocking { - workQueue.send { - wrappingBuffer.write(b) - if (underlyingBuffer.size() >= partSize) { - uploadPart() - } + override fun write(b: ByteArray) { + wrappingBuffer.write(b) + if (underlyingBuffer.size() >= partSize) { + enqueuePart() } } } - private suspend fun uploadPart() { - streamProcessor.partFinisher.invoke(wrappingBuffer) + private fun enqueuePart() { + wrappingBuffer.flush() + val bytes = underlyingBuffer.toByteArray() + underlyingBuffer.reset() + runBlocking { partQueue.send(bytes) } + } + + private suspend fun uploadPart( + bytes: ByteArray, + uploadedParts: List + ): CompletedPart { val partNumber = uploadedParts.size + 1 val request = UploadPartRequest { uploadId = response.uploadId bucket = response.bucket key = response.key - body = ByteStream.fromBytes(underlyingBuffer.toByteArray()) + body = ByteStream.fromBytes(bytes) this.partNumber = partNumber } val uploadResponse = client.uploadPart(request) - uploadedParts.add( - CompletedPart { - this.partNumber = partNumber - this.eTag = uploadResponse.eTag - } - ) - underlyingBuffer.reset() + return CompletedPart { + this.partNumber = partNumber + this.eTag = uploadResponse.eTag + } } - private suspend fun complete() { - if (underlyingBuffer.size() > 0) { - uploadPart() - } + private suspend fun complete(uploadedParts: List) { val request = CompleteMultipartUploadRequest { uploadId = response.uploadId bucket = response.bucket @@ -140,3 +149,77 @@ class S3MultipartUpload( client.completeMultipartUpload(request) } } + +@SuppressFBWarnings("NP_NONNULL_PARAM_VIOLATION", justification = "Kotlin async continuation") +class S3StreamingUpload( + private val client: aws.sdk.kotlin.services.s3.S3Client, + private val bucketConfig: S3BucketConfiguration, + private val response: CreateMultipartUploadResponse, +) : StreamingUpload { + private val log = KotlinLogging.logger {} + private val uploadedParts = ConcurrentHashSet() + private val isComplete = AtomicBoolean(false) + + override suspend fun uploadPart(part: ByteArray, index: Int) { + log.info { "Uploading part $index to ${response.key} (uploadId=${response.uploadId}" } + + try { + val request = UploadPartRequest { + uploadId = response.uploadId + bucket = response.bucket + key = response.key + body = ByteStream.fromBytes(part) + this.partNumber = index + } + val uploadResponse = client.uploadPart(request) + uploadedParts.add( + CompletedPart { + this.partNumber = index + this.eTag = uploadResponse.eTag + } + ) + } catch (e: Exception) { + log.error(e) { + "Failed to upload part $index to ${response.key} (uploadId=${response.uploadId}" + } + throw e + } + } + + override suspend fun complete(): S3Object { + try { + if (isComplete.setOnce()) { + log.info { + "Completing multipart upload to ${response.key} (uploadId=${response.uploadId}" + } + val partsSorted = uploadedParts.toList().sortedBy { it.partNumber } + if (partsSorted.isEmpty()) { + log.warn { + "Skipping empty upload to ${response.key} (uploadId=${response.uploadId}" + } + return S3Object(response.key!!, bucketConfig) + } + + val request = CompleteMultipartUploadRequest { + uploadId = response.uploadId + bucket = response.bucket + key = response.key + this.multipartUpload = CompletedMultipartUpload { parts = partsSorted } + } + // S3 will handle enforcing no gaps in the part numbers + client.completeMultipartUpload(request) + } else { + log.warn { + "Complete called multiple times for ${response.key} (uploadId=${response.uploadId}" + } + } + } catch (e: Exception) { + log.error(e) { + "Failed to complete upload to ${response.key} (uploadId=${response.uploadId}; parts=${uploadedParts.map {it.partNumber}.sortedBy { it }}" + } + throw e + } + + return S3Object(response.key!!, bucketConfig) + } +} diff --git a/airbyte-cdk/java/airbyte-cdk/README.md b/airbyte-cdk/java/airbyte-cdk/README.md index 48f390a35cc4..d100bd452d99 100644 --- a/airbyte-cdk/java/airbyte-cdk/README.md +++ b/airbyte-cdk/java/airbyte-cdk/README.md @@ -174,14 +174,18 @@ corresponds to that version. | Version | Date | Pull Request | Subject | |:-----------|:-----------|:------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 0.47.3 | 2024-10-23 | [\#46689](https://github.com/airbytehq/airbyte/pull/46689) | Split DestinationAcceptanceTest| -| 0.47.2 | 2024-10-21 | [\#47216](https://github.com/airbytehq/airbyte/pull/47216) | improve java compatibiilty| -| 0.47.1 | 2024-09-27 | [\#45397](https://github.com/airbytehq/airbyte/pull/45397) | Allow logical replication from Postgres 16 read-replicas| +| 0.48.4 | 2024-12-24 | [\#50410](https://github.com/airbytehq/airbyte/pull/50410) | Save SSL key to /tmp | +| 0.48.3 | 2024-12-23 | [\#49858](https://github.com/airbytehq/airbyte/pull/49858) | Relax various Destination CDK methods visibility. | +| 0.48.1 | 2024-11-13 | [\#48482](https://github.com/airbytehq/airbyte/pull/48482) | Adding support converting very large numbers via BigInteger | +| 0.48.0 | 2024-10-23 | [\#46302](https://github.com/airbytehq/airbyte/pull/46302) | Add support for file transfer | +| 0.47.3 | 2024-10-23 | [\#46689](https://github.com/airbytehq/airbyte/pull/46689) | Split DestinationAcceptanceTest | +| 0.47.2 | 2024-10-21 | [\#47216](https://github.com/airbytehq/airbyte/pull/47216) | improve java compatibiilty | +| 0.47.1 | 2024-09-27 | [\#45397](https://github.com/airbytehq/airbyte/pull/45397) | Allow logical replication from Postgres 16 read-replicas | | 0.47.0 | 2024-09-26 | [\#42030](https://github.com/airbytehq/airbyte/pull/42030) | minor refactor | -| 0.46.1 | 2024-09-20 | [\#45700](https://github.com/airbytehq/airbyte/pull/45700) | Destinations: Fix bug in parsing jsonschema | -| 0.46.0 | 2024-09-18 | [\#45432](https://github.com/airbytehq/airbyte/pull/45432) | upgrade all libraries to latest version | -| 0.45.1 | 2024-09-17 | [\#45638](https://github.com/airbytehq/airbyte/pull/45638) | upgrade apache mina sshd to 2.13.2 to handle openssh tcpkeepalive requests | -| 0.45.0 | 2024-09-16 | [\#45469](https://github.com/airbytehq/airbyte/pull/45469) | Fix some race conditions, improve thread filtering, improve test logging | +| 0.46.1 | 2024-09-20 | [\#45700](https://github.com/airbytehq/airbyte/pull/45700) | Destinations: Fix bug in parsing jsonschema | +| 0.46.0 | 2024-09-18 | [\#45432](https://github.com/airbytehq/airbyte/pull/45432) | upgrade all libraries to latest version | +| 0.45.1 | 2024-09-17 | [\#45638](https://github.com/airbytehq/airbyte/pull/45638) | upgrade apache mina sshd to 2.13.2 to handle openssh tcpkeepalive requests | +| 0.45.0 | 2024-09-16 | [\#45469](https://github.com/airbytehq/airbyte/pull/45469) | Fix some race conditions, improve thread filtering, improve test logging | | 0.44.22 | 2024-09-10 | [\#45368](https://github.com/airbytehq/airbyte/pull/45368) | Remove excessive debezium logging | | 0.44.21 | 2024-09-04 | [\#45143](https://github.com/airbytehq/airbyte/pull/45143) | S3-destination: don't overwrite existing files, skip those file indexes instead | | 0.44.20 | 2024-08-30 | [\#44933](https://github.com/airbytehq/airbyte/pull/44933) | Avro/Parquet destinations: handle `{}` schemas inside objects/arrays | diff --git a/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/db/jdbc/AbstractJdbcCompatibleSourceOperations.kt b/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/db/jdbc/AbstractJdbcCompatibleSourceOperations.kt index 5ee46b5cf3d4..625550ba6033 100644 --- a/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/db/jdbc/AbstractJdbcCompatibleSourceOperations.kt +++ b/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/db/jdbc/AbstractJdbcCompatibleSourceOperations.kt @@ -158,6 +158,19 @@ abstract class AbstractJdbcCompatibleSourceOperations : node.put(columnName, DataTypeUtils.returnNullIfInvalid { resultSet.getLong(index) }) } + @Throws(SQLException::class) + protected fun putBigInteger( + node: ObjectNode, + columnName: String?, + resultSet: ResultSet, + index: Int + ) { + node.put( + columnName, + DataTypeUtils.returnNullIfInvalid { resultSet.getBigDecimal(index).toBigInteger() } + ) + } + @Throws(SQLException::class) protected open fun putDouble( node: ObjectNode, diff --git a/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/db/util/SSLCertificateUtils.kt b/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/db/util/SSLCertificateUtils.kt index 0c8ef8aaa3c9..19852b2a8def 100644 --- a/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/db/util/SSLCertificateUtils.kt +++ b/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/db/util/SSLCertificateUtils.kt @@ -50,7 +50,7 @@ object SSLCertificateUtils { directory: String? ): URI { val fs = Objects.requireNonNullElse(filesystem, FileSystems.getDefault()) - val pathToStore = fs!!.getPath(Objects.toString(directory, "")) + val pathToStore = fs!!.getPath(Objects.toString(directory, "/tmp")) val pathToFile = pathToStore.resolve(KEYSTORE_FILE_NAME + RANDOM.nextInt() + KEYSTORE_FILE_TYPE) val os = Files.newOutputStream(pathToFile) diff --git a/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/AsyncStreamConsumer.kt b/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/AsyncStreamConsumer.kt index 9581d943473a..59188aef425c 100644 --- a/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/AsyncStreamConsumer.kt +++ b/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/AsyncStreamConsumer.kt @@ -54,6 +54,7 @@ constructor( workerPool: ExecutorService = Executors.newFixedThreadPool(5), private val airbyteMessageDeserializer: AirbyteMessageDeserializer = AirbyteMessageDeserializer(), + flushOnEveryMessage: Boolean = false, ) : SerializedAirbyteMessageConsumer { private val bufferEnqueue: BufferEnqueue = bufferManager.bufferEnqueue private val flushWorkers: FlushWorkers = @@ -64,6 +65,7 @@ constructor( flushFailure, bufferManager.stateManager, workerPool, + flushOnEveryMessage, ) private val streamNames: Set = StreamDescriptorUtils.fromConfiguredCatalog( diff --git a/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/DetectStreamToFlush.kt b/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/DetectStreamToFlush.kt index db61cdaebf45..f8531b9c134c 100644 --- a/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/DetectStreamToFlush.kt +++ b/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/DetectStreamToFlush.kt @@ -28,6 +28,7 @@ internal constructor( private val isClosing: AtomicBoolean, private val flusher: DestinationFlushFunction, private val nowProvider: Clock, + private val flushOnEveryMessage: Boolean = false, ) { private val latestFlushTimeMsPerStream: ConcurrentMap = ConcurrentHashMap() @@ -37,7 +38,15 @@ internal constructor( runningFlushWorkers: RunningFlushWorkers, isClosing: AtomicBoolean, flusher: DestinationFlushFunction, - ) : this(bufferDequeue, runningFlushWorkers, isClosing, flusher, Clock.systemUTC()) + flushOnEveryMessage: Boolean = false, + ) : this( + bufferDequeue, + runningFlushWorkers, + isClosing, + flusher, + Clock.systemUTC(), + flushOnEveryMessage + ) val nextStreamToFlush: Optional /** @@ -70,7 +79,8 @@ internal constructor( bufferDequeue.totalGlobalQueueSizeBytes.toDouble() / bufferDequeue.maxQueueSizeBytes // when we are closing or queues are very full, flush regardless of how few items are in the // queue. - return if (isClosing.get() || isBuffer90Full) 0 else flusher.queueFlushThresholdBytes + return if (flushOnEveryMessage || isClosing.get() || isBuffer90Full) 0 + else flusher.queueFlushThresholdBytes } // todo (cgardens) - improve prioritization by getting a better estimate of how much data @@ -105,7 +115,7 @@ internal constructor( "${isTimeTriggeredResult.second} , ${isSizeTriggeredResult.second}" logger.debug { "computed: $debugString" } - if (isSizeTriggeredResult.first || isTimeTriggeredResult.first) { + if (flushOnEveryMessage || isSizeTriggeredResult.first || isTimeTriggeredResult.first) { logger.info { "flushing: $debugString" } latestFlushTimeMsPerStream[stream] = nowProvider.millis() return Optional.of(stream) diff --git a/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/FlushWorkers.kt b/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/FlushWorkers.kt index 52377b504b9a..58c17827c561 100644 --- a/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/FlushWorkers.kt +++ b/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/FlushWorkers.kt @@ -51,6 +51,7 @@ constructor( private val flushFailure: FlushFailure, private val stateManager: GlobalAsyncStateManager, private val workerPool: ExecutorService = Executors.newFixedThreadPool(5), + flushOnEveryMessage: Boolean = false, ) : AutoCloseable { private val supervisorThread: ScheduledExecutorService = Executors.newScheduledThreadPool(1) private val debugLoop: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor() @@ -66,6 +67,7 @@ constructor( runningFlushWorkers, isClosing, flusher, + flushOnEveryMessage, ) } diff --git a/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/buffers/BufferDequeue.kt b/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/buffers/BufferDequeue.kt index 31f80de484d5..60ab054a2fb6 100644 --- a/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/buffers/BufferDequeue.kt +++ b/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/buffers/BufferDequeue.kt @@ -63,7 +63,7 @@ class BufferDequeue( // otherwise pull records until we hit the memory limit. val newSize: Long = (memoryItem.size) + bytesRead.get() - if (newSize <= optimalBytesToRead) { + if (newSize <= optimalBytesToRead || output.isEmpty()) { memoryItem.size.let { bytesRead.addAndGet(it) } queue.poll()?.item?.let { output.add(it) } } else { diff --git a/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/model/AirbyteRecordMessageFile.kt b/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/model/AirbyteRecordMessageFile.kt new file mode 100644 index 000000000000..54df03f239d0 --- /dev/null +++ b/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/model/AirbyteRecordMessageFile.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.integrations.destination.async.model + +import com.fasterxml.jackson.annotation.JsonProperty + +class AirbyteRecordMessageFile { + constructor( + fileUrl: String? = null, + bytes: Long? = null, + fileRelativePath: String? = null, + modified: Long? = null, + sourceFileUrl: String? = null + ) { + this.fileUrl = fileUrl + this.bytes = bytes + this.fileRelativePath = fileRelativePath + this.modified = modified + this.sourceFileUrl = sourceFileUrl + } + constructor() : + this( + fileUrl = null, + bytes = null, + fileRelativePath = null, + modified = null, + sourceFileUrl = null + ) + + @get:JsonProperty("file_url") + @set:JsonProperty("file_url") + @JsonProperty("file_url") + var fileUrl: String? = null + + @get:JsonProperty("bytes") + @set:JsonProperty("bytes") + @JsonProperty("bytes") + var bytes: Long? = null + + @get:JsonProperty("file_relative_path") + @set:JsonProperty("file_relative_path") + @JsonProperty("file_relative_path") + var fileRelativePath: String? = null + + @get:JsonProperty("modified") + @set:JsonProperty("modified") + @JsonProperty("modified") + var modified: Long? = null + + @get:JsonProperty("source_file_url") + @set:JsonProperty("source_file_url") + @JsonProperty("source_file_url") + var sourceFileUrl: String? = null +} diff --git a/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/model/PartialAirbyteRecordMessage.kt b/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/model/PartialAirbyteRecordMessage.kt index fd26f6ad5747..d01c70c15cf6 100644 --- a/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/model/PartialAirbyteRecordMessage.kt +++ b/airbyte-cdk/java/airbyte-cdk/core/src/main/kotlin/io/airbyte/cdk/integrations/destination/async/model/PartialAirbyteRecordMessage.kt @@ -5,7 +5,6 @@ package io.airbyte.cdk.integrations.destination.async.model import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.annotation.JsonPropertyDescription import com.fasterxml.jackson.databind.JsonNode import io.airbyte.protocol.models.v0.AirbyteRecordMessageMeta import io.airbyte.protocol.models.v0.StreamDescriptor @@ -33,7 +32,6 @@ class PartialAirbyteRecordMessage { @get:JsonProperty("emitted_at") @set:JsonProperty("emitted_at") @JsonProperty("emitted_at") - @JsonPropertyDescription("when the data was emitted from the source. epoch in millisecond.") var emittedAt: Long = 0 @get:JsonProperty("meta") @@ -41,6 +39,11 @@ class PartialAirbyteRecordMessage { @JsonProperty("meta") var meta: AirbyteRecordMessageMeta? = null + @get:JsonProperty("file") + @set:JsonProperty("file") + @JsonProperty("file") + var file: AirbyteRecordMessageFile? = null + fun withNamespace(namespace: String?): PartialAirbyteRecordMessage { this.namespace = namespace return this @@ -66,6 +69,11 @@ class PartialAirbyteRecordMessage { return this } + fun withFile(file: AirbyteRecordMessageFile): PartialAirbyteRecordMessage { + this.file = file + return this + } + override fun equals(other: Any?): Boolean { if (this === other) { return true @@ -77,7 +85,8 @@ class PartialAirbyteRecordMessage { return namespace == that.namespace && stream == that.stream && emittedAt == that.emittedAt && - meta == that.meta + meta == that.meta && + file == that.file } override fun hashCode(): Int { @@ -98,6 +107,9 @@ class PartialAirbyteRecordMessage { ", meta='" + meta + '\'' + + ", file='" + + file + + '\'' + '}' } diff --git a/airbyte-cdk/java/airbyte-cdk/core/src/main/resources/version.properties b/airbyte-cdk/java/airbyte-cdk/core/src/main/resources/version.properties index 5312981f0d4d..dda403542207 100644 --- a/airbyte-cdk/java/airbyte-cdk/core/src/main/resources/version.properties +++ b/airbyte-cdk/java/airbyte-cdk/core/src/main/resources/version.properties @@ -1 +1 @@ -version=0.47.3 +version=0.48.4 diff --git a/airbyte-cdk/java/airbyte-cdk/core/src/test/kotlin/io/airbyte/cdk/integrations/destination/async/AsyncStreamConsumerTest.kt b/airbyte-cdk/java/airbyte-cdk/core/src/test/kotlin/io/airbyte/cdk/integrations/destination/async/AsyncStreamConsumerTest.kt index e8634f5f8707..bd706681ed5a 100644 --- a/airbyte-cdk/java/airbyte-cdk/core/src/test/kotlin/io/airbyte/cdk/integrations/destination/async/AsyncStreamConsumerTest.kt +++ b/airbyte-cdk/java/airbyte-cdk/core/src/test/kotlin/io/airbyte/cdk/integrations/destination/async/AsyncStreamConsumerTest.kt @@ -765,6 +765,9 @@ class AsyncStreamConsumerTest { val throwable = assertThrows(RuntimeException::class.java) { consumer.accept(retyped, retyped.length) } // Ensure that the offending data has been scrubbed from the error message - assertFalse(throwable.message!!.contains(offender)) + assertFalse( + throwable.message!!.contains(offender), + "message should not contain the offender. Was ${throwable.message}" + ) } } diff --git a/airbyte-cdk/java/airbyte-cdk/core/src/test/kotlin/io/airbyte/cdk/integrations/destination/async/DetectStreamToFlushTest.kt b/airbyte-cdk/java/airbyte-cdk/core/src/test/kotlin/io/airbyte/cdk/integrations/destination/async/DetectStreamToFlushTest.kt index 190a62db5bab..8d7455433815 100644 --- a/airbyte-cdk/java/airbyte-cdk/core/src/test/kotlin/io/airbyte/cdk/integrations/destination/async/DetectStreamToFlushTest.kt +++ b/airbyte-cdk/java/airbyte-cdk/core/src/test/kotlin/io/airbyte/cdk/integrations/destination/async/DetectStreamToFlushTest.kt @@ -49,7 +49,13 @@ class DetectStreamToFlushTest { ) val detect = - DetectStreamToFlush(bufferDequeue, runningFlushWorkers, AtomicBoolean(false), flusher) + DetectStreamToFlush( + bufferDequeue, + runningFlushWorkers, + AtomicBoolean(false), + flusher, + flushOnEveryMessage = false + ) Assertions.assertEquals(Optional.empty(), detect.getNextStreamToFlush(0)) } @@ -66,7 +72,13 @@ class DetectStreamToFlushTest { RunningFlushWorkers::class.java, ) val detect = - DetectStreamToFlush(bufferDequeue, runningFlushWorkers, AtomicBoolean(false), flusher) + DetectStreamToFlush( + bufferDequeue, + runningFlushWorkers, + AtomicBoolean(false), + flusher, + flushOnEveryMessage = false + ) // if above threshold, triggers Assertions.assertEquals(Optional.of(DESC1), detect.getNextStreamToFlush(0)) // if below threshold, no trigger @@ -94,10 +106,41 @@ class DetectStreamToFlushTest { ), ) val detect = - DetectStreamToFlush(bufferDequeue, runningFlushWorkers, AtomicBoolean(false), flusher) + DetectStreamToFlush( + bufferDequeue, + runningFlushWorkers, + AtomicBoolean(false), + flusher, + flushOnEveryMessage = false + ) Assertions.assertEquals(Optional.empty(), detect.getNextStreamToFlush(0)) } + @Test + internal fun testFileTransfer() { + val bufferDequeue = + Mockito.mock( + BufferDequeue::class.java, + ) + Mockito.`when`(bufferDequeue.bufferedStreams).thenReturn(setOf(DESC1)) + Mockito.`when`(bufferDequeue.getQueueSizeBytes(DESC1)).thenReturn(Optional.of(0L)) + val runningFlushWorkers = + Mockito.mock( + RunningFlushWorkers::class.java, + ) + + val detect = + DetectStreamToFlush( + bufferDequeue, + runningFlushWorkers, + AtomicBoolean(false), + flusher, + flushOnEveryMessage = true + ) + Assertions.assertEquals(0, detect.computeQueueThreshold()) + Assertions.assertEquals(Optional.of(DESC1), detect.getNextStreamToFlush(0)) + } + @Test internal fun testGetNextPicksUpOnTimeTrigger() { val bufferDequeue = @@ -127,6 +170,7 @@ class DetectStreamToFlushTest { AtomicBoolean(false), flusher, mockedNowProvider, + flushOnEveryMessage = false ) // initialize flush time diff --git a/airbyte-cdk/java/airbyte-cdk/db-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/jdbc/typing_deduping/JdbcDestinationHandler.kt b/airbyte-cdk/java/airbyte-cdk/db-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/jdbc/typing_deduping/JdbcDestinationHandler.kt index 6e767e9cb6be..18154ded08c9 100644 --- a/airbyte-cdk/java/airbyte-cdk/db-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/jdbc/typing_deduping/JdbcDestinationHandler.kt +++ b/airbyte-cdk/java/airbyte-cdk/db-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/jdbc/typing_deduping/JdbcDestinationHandler.kt @@ -74,7 +74,7 @@ abstract class JdbcDestinationHandler( ): ResultSet = dbmetadata.getTables(catalogName, id.rawNamespace, id.rawName + suffix, null) @Throws(Exception::class) - private fun isFinalTableEmpty(id: StreamId): Boolean { + protected open fun isFinalTableEmpty(id: StreamId): Boolean { return !jdbcDatabase.queryBoolean( dslContext .select( @@ -211,7 +211,8 @@ abstract class JdbcDestinationHandler( } @Throws(SQLException::class) - protected fun getAllDestinationStates(): Map { + protected open fun getAllDestinationStates(): + Map { try { // Guarantee the table exists. jdbcDatabase.execute( diff --git a/airbyte-cdk/java/airbyte-cdk/db-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/jdbc/typing_deduping/JdbcSqlGenerator.kt b/airbyte-cdk/java/airbyte-cdk/db-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/jdbc/typing_deduping/JdbcSqlGenerator.kt index 310a0da43b40..b97127939123 100644 --- a/airbyte-cdk/java/airbyte-cdk/db-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/jdbc/typing_deduping/JdbcSqlGenerator.kt +++ b/airbyte-cdk/java/airbyte-cdk/db-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/jdbc/typing_deduping/JdbcSqlGenerator.kt @@ -403,7 +403,7 @@ constructor( .columns(buildFinalTableFields(columns, metaFields)) } - private fun insertAndDeleteTransaction( + protected open fun insertAndDeleteTransaction( streamConfig: StreamConfig, finalSuffix: String?, minRawTimestamp: Optional, @@ -507,7 +507,7 @@ constructor( return createSchemaSql.sql } - protected fun createTableSql( + protected open fun createTableSql( namespace: String, tableName: String, columns: LinkedHashMap diff --git a/airbyte-cdk/java/airbyte-cdk/db-destinations/src/testFixtures/kotlin/io/airbyte/cdk/integrations/standardtest/destination/BaseDestinationAcceptanceTest.kt b/airbyte-cdk/java/airbyte-cdk/db-destinations/src/testFixtures/kotlin/io/airbyte/cdk/integrations/standardtest/destination/BaseDestinationAcceptanceTest.kt index 6fdd1d4836bf..791cce057db3 100644 --- a/airbyte-cdk/java/airbyte-cdk/db-destinations/src/testFixtures/kotlin/io/airbyte/cdk/integrations/standardtest/destination/BaseDestinationAcceptanceTest.kt +++ b/airbyte-cdk/java/airbyte-cdk/db-destinations/src/testFixtures/kotlin/io/airbyte/cdk/integrations/standardtest/destination/BaseDestinationAcceptanceTest.kt @@ -14,6 +14,7 @@ import io.airbyte.configoss.WorkerDestinationConfig import io.airbyte.protocol.models.v0.AirbyteMessage import io.airbyte.protocol.models.v0.AirbyteStateStats import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog +import io.airbyte.workers.exception.TestHarnessException import io.airbyte.workers.helper.ConnectorConfigUpdater import io.airbyte.workers.internal.AirbyteDestination import io.airbyte.workers.internal.DefaultAirbyteDestination @@ -173,9 +174,10 @@ abstract class BaseDestinationAcceptanceTest( catalog: ConfiguredAirbyteCatalog, runNormalization: Boolean, imageName: String, + additionalEnvs: Map = mapOf() ): List { val destinationConfig = getDestinationConfig(config, catalog) - return runSync(messages, runNormalization, imageName, destinationConfig) + return runSync(messages, runNormalization, imageName, destinationConfig, additionalEnvs) } @Throws(Exception::class) @@ -184,13 +186,14 @@ abstract class BaseDestinationAcceptanceTest( runNormalization: Boolean, imageName: String, destinationConfig: WorkerDestinationConfig, + additionalEnvs: Map = mapOf() ): List { val destination = getDestination(imageName) destination.start( destinationConfig, jobRoot, - inDestinationNormalizationFlags(runNormalization) + additionalEnvs + inDestinationNormalizationFlags(runNormalization) ) messages.forEach( Consumer { message: AirbyteMessage -> @@ -215,7 +218,11 @@ abstract class BaseDestinationAcceptanceTest( } } - destination.close() + try { + destination.close() + } catch (e: TestHarnessException) { + throw TestHarnessException(e.message, e, destinationOutput) + } return destinationOutput } @@ -258,6 +265,7 @@ abstract class BaseDestinationAcceptanceTest( workspaceRoot, workspaceRoot.toString(), localRoot.toString(), + fileTransferMountSource, "host", getConnectorEnv() ) diff --git a/airbyte-cdk/java/airbyte-cdk/db-destinations/src/testFixtures/kotlin/io/airbyte/cdk/integrations/standardtest/destination/DestinationAcceptanceTest.kt b/airbyte-cdk/java/airbyte-cdk/db-destinations/src/testFixtures/kotlin/io/airbyte/cdk/integrations/standardtest/destination/DestinationAcceptanceTest.kt index 581da32655b8..c0994cfdf812 100644 --- a/airbyte-cdk/java/airbyte-cdk/db-destinations/src/testFixtures/kotlin/io/airbyte/cdk/integrations/standardtest/destination/DestinationAcceptanceTest.kt +++ b/airbyte-cdk/java/airbyte-cdk/db-destinations/src/testFixtures/kotlin/io/airbyte/cdk/integrations/standardtest/destination/DestinationAcceptanceTest.kt @@ -1944,10 +1944,11 @@ abstract class DestinationAcceptanceTest( catalog: ConfiguredAirbyteCatalog, runNormalization: Boolean, imageName: String, + additionalEnvs: Map, ): List { val destinationConfig = getDestinationConfig(config, catalog) val destinationOutput = - super.runSync(messages, runNormalization, imageName, destinationConfig) + super.runSync(messages, runNormalization, imageName, destinationConfig, additionalEnvs) if (!runNormalization || (supportsInDestinationNormalization())) { return destinationOutput diff --git a/airbyte-cdk/java/airbyte-cdk/db-destinations/src/testFixtures/resources/v0/problematic_types_disjoint_union_messages_out.txt b/airbyte-cdk/java/airbyte-cdk/db-destinations/src/testFixtures/resources/v0/problematic_types_disjoint_union_messages_out.txt index eb2f612d3748..fc9e73e5de9c 100644 --- a/airbyte-cdk/java/airbyte-cdk/db-destinations/src/testFixtures/resources/v0/problematic_types_disjoint_union_messages_out.txt +++ b/airbyte-cdk/java/airbyte-cdk/db-destinations/src/testFixtures/resources/v0/problematic_types_disjoint_union_messages_out.txt @@ -1,3 +1,3 @@ -{"schemaless_object":"{\"uuid\":\"38F52396-736D-4B23-B5B4-F504D8894B97\",\"probability\":1.5}","schematized_object":{"id":1,"name":"Joe"},"combined_type":{"type":"string","string":"string1","integer":null},"union_type":{"type":"integer","string":null,"integer":10},"schemaless_array":"[10,\"foo\",null,{\"bar\":\"qua\"}]","mixed_array_integer_and_schemaless_object":[15,null,"{\"hello\":\"world\"}"],"array_of_union_integer_and_schemaless_array":[{"type":"integer","integer":25,"string":null},null,{"type":"string","integer":null,"string":"[\"goodbye\",\"cruel world\"]"}],"union_of_objects_with_properties_identical":{"id":10,"name":"Joe"},"union_of_objects_with_properties_overlapping":{"id":20,"name":"Jane","flagged":true},"union_of_objects_with_properties_nonoverlapping":{"id":30,"name":"Phil","flagged":false,"description":"Very Phil"}, "union_of_objects_with_properties_contradicting": { "id": {"type":"integer","integer":1,"string":null}, "name": "Jenny" }, "empty_object": "{}","object_with_null_properties": "{}", "combined_with_null": "foobar", "union_with_null":"barfoo", "combined_nulls": null, "compact_union": {"type": "object", "object": { "id": 10, "name": "Tyler" }, "integer": null } } +{"schemaless_object":"{\"uuid\":\"38F52396-736D-4B23-B5B4-F504D8894B97\",\"probability\":1.5}","schematized_object":{"id":1,"name":"Joe"},"combined_type":{"type":"string","string":"string1","integer":null},"union_type":{"type":"integer","string":null,"integer":10},"schemaless_array":"[10,\"foo\",null,{\"bar\":\"qua\"}]","mixed_array_integer_and_schemaless_object":[{"type":"integer","integer":15,"object":null},null,{"type":"object","integer":null,"object":"{\"hello\":\"world\"}"}],"array_of_union_integer_and_schemaless_array":[{"type":"integer","integer":25,"object":null},null,{"type":"object","integer":null,"object":"[\"goodbye\",\"cruel world\"]"}],"union_of_objects_with_properties_identical":{"id":10,"name":"Joe"},"union_of_objects_with_properties_overlapping":{"id":20,"name":"Jane","flagged":true},"union_of_objects_with_properties_nonoverlapping":{"id":30,"name":"Phil","flagged":false,"description":"Very Phil"},"union_of_objects_with_properties_contradicting":{"id":{"type":"integer","integer":1,"string":null},"name":"Jenny"},"empty_object":"{}","object_with_null_properties":"{}","combined_with_null":"foobar","union_with_null":"barfoo","combined_nulls":null,"compact_union":{"type":"object","object":{"id":10,"name":"Tyler"},"integer":null}} {"schemaless_object":"{\"address\":{\"street\":\"113 Hickey Rd\",\"zip\":\"37932\"},\"flags\":[true,false,false]}","schematized_object":{"id":2,"name":"Jane"},"combined_type":{"type":"integer","string":null,"integer":20},"union_type":{"type":"string","string":"string2","integer":null},"schemaless_array":"[]","mixed_array_integer_and_schemaless_object":[],"array_of_union_integer_and_schemaless_array":[],"union_of_objects_with_properties_identical":{"id":null,"name":null},"union_of_objects_with_properties_overlapping":{"id":null,"name":null,"flagged":null},"union_of_objects_with_properties_nonoverlapping":{"id":null,"name":null,"flagged":null,"description":null}, "union_of_objects_with_properties_contradicting": { "id": {"type":"string","integer":null,"string":"seal-one-hippity"}, "name": "James" }, "empty_object": "{\"extra\":\"stuff\"}", "object_with_null_properties": "{\"more\":{\"extra\":\"stuff\"}}", "combined_with_null": "foobar2", "union_with_null": "barfoo2", "combined_nulls": null, "compact_union": {"type":"integer","integer":4444,"object":null} } { "schemaless_object": null, "schematized_object": null, "combined_type": null, "union_type": null, "schemaless_array": null, "mixed_array_integer_and_schemaless_object": null, "array_of_union_integer_and_schemaless_array": null, "union_of_objects_with_properties_identical": null, "union_of_objects_with_properties_overlapping": null, "union_of_objects_with_properties_nonoverlapping": null, "union_of_objects_with_properties_contradicting": null, "empty_object": null, "object_with_null_properties": null, "combined_with_null": null, "union_with_null": null, "combined_nulls": null, "compact_union": null } \ No newline at end of file diff --git a/airbyte-cdk/java/airbyte-cdk/db-sources/src/testFixtures/kotlin/io/airbyte/cdk/integrations/standardtest/source/AbstractSourceConnectorTest.kt b/airbyte-cdk/java/airbyte-cdk/db-sources/src/testFixtures/kotlin/io/airbyte/cdk/integrations/standardtest/source/AbstractSourceConnectorTest.kt index 4761398a496c..a71aca115d2e 100644 --- a/airbyte-cdk/java/airbyte-cdk/db-sources/src/testFixtures/kotlin/io/airbyte/cdk/integrations/standardtest/source/AbstractSourceConnectorTest.kt +++ b/airbyte-cdk/java/airbyte-cdk/db-sources/src/testFixtures/kotlin/io/airbyte/cdk/integrations/standardtest/source/AbstractSourceConnectorTest.kt @@ -117,6 +117,7 @@ abstract class AbstractSourceConnectorTest { workspaceRoot, workspaceRoot.toString(), localRoot.toString(), + fileTransferMountSource = null, "host", envMap ) diff --git a/airbyte-cdk/java/airbyte-cdk/dependencies/src/main/kotlin/io/airbyte/commons/features/EnvVariableFeatureFlags.kt b/airbyte-cdk/java/airbyte-cdk/dependencies/src/main/kotlin/io/airbyte/commons/features/EnvVariableFeatureFlags.kt index 5106ad19f598..ee70fe2c54d1 100644 --- a/airbyte-cdk/java/airbyte-cdk/dependencies/src/main/kotlin/io/airbyte/commons/features/EnvVariableFeatureFlags.kt +++ b/airbyte-cdk/java/airbyte-cdk/dependencies/src/main/kotlin/io/airbyte/commons/features/EnvVariableFeatureFlags.kt @@ -4,6 +4,7 @@ package io.airbyte.commons.features import io.github.oshai.kotlinlogging.KotlinLogging +import java.nio.file.Path import java.util.function.Function private val log = KotlinLogging.logger {} @@ -46,6 +47,16 @@ class EnvVariableFeatureFlags : FeatureFlags { return getEnvOrDefault(DEPLOYMENT_MODE, "") { arg: String -> arg } } + override fun airbyteStagingDirectory(): Path? { + return getEnvOrDefault(AIRBYTE_STAGING_DIRECTORY_PROPERTY_NAME, null) { arg: String -> + Path.of(arg) + } + } + + override fun useFileTransfer(): Boolean { + return getEnvOrDefault(USE_FILE_TRANSFER, false) { it.toBoolean() } + } + // TODO: refactor in order to use the same method than the ones in EnvConfigs.java fun getEnvOrDefault(key: String?, defaultValue: T, parser: Function): T { val value = System.getenv(key) @@ -73,5 +84,8 @@ class EnvVariableFeatureFlags : FeatureFlags { const val STRICT_COMPARISON_NORMALIZATION_TAG: String = "STRICT_COMPARISON_NORMALIZATION_TAG" const val DEPLOYMENT_MODE: String = "DEPLOYMENT_MODE" + val DEFAULT_AIRBYTE_STAGING_DIRECTORY: Path = Path.of("/staging/files") + const val AIRBYTE_STAGING_DIRECTORY_PROPERTY_NAME: String = "AIRBYTE_STAGING_DIRECTORY" + const val USE_FILE_TRANSFER = "USE_FILE_TRANSFER" } } diff --git a/airbyte-cdk/java/airbyte-cdk/dependencies/src/main/kotlin/io/airbyte/commons/features/FeatureFlags.kt b/airbyte-cdk/java/airbyte-cdk/dependencies/src/main/kotlin/io/airbyte/commons/features/FeatureFlags.kt index a8626b46ec64..e05e9608d8f4 100644 --- a/airbyte-cdk/java/airbyte-cdk/dependencies/src/main/kotlin/io/airbyte/commons/features/FeatureFlags.kt +++ b/airbyte-cdk/java/airbyte-cdk/dependencies/src/main/kotlin/io/airbyte/commons/features/FeatureFlags.kt @@ -3,6 +3,8 @@ */ package io.airbyte.commons.features +import java.nio.file.Path + /** * Interface that describe which features are activated in airbyte. Currently, the only * implementation relies on env. Ideally it should be on some DB. @@ -51,4 +53,8 @@ interface FeatureFlags { * @return empty string for the default deployment mode, "CLOUD" for cloud deployment mode. */ fun deploymentMode(): String? + + fun airbyteStagingDirectory(): Path? + + fun useFileTransfer(): Boolean } diff --git a/airbyte-cdk/java/airbyte-cdk/dependencies/src/main/kotlin/io/airbyte/commons/features/FeatureFlagsWrapper.kt b/airbyte-cdk/java/airbyte-cdk/dependencies/src/main/kotlin/io/airbyte/commons/features/FeatureFlagsWrapper.kt index 056c6730332c..abb16dbe463e 100644 --- a/airbyte-cdk/java/airbyte-cdk/dependencies/src/main/kotlin/io/airbyte/commons/features/FeatureFlagsWrapper.kt +++ b/airbyte-cdk/java/airbyte-cdk/dependencies/src/main/kotlin/io/airbyte/commons/features/FeatureFlagsWrapper.kt @@ -3,6 +3,8 @@ */ package io.airbyte.commons.features +import java.nio.file.Path + open class FeatureFlagsWrapper(private val wrapped: FeatureFlags) : FeatureFlags { override fun autoDetectSchema(): Boolean { return wrapped.autoDetectSchema() @@ -36,6 +38,14 @@ open class FeatureFlagsWrapper(private val wrapped: FeatureFlags) : FeatureFlags return wrapped.deploymentMode() } + override fun airbyteStagingDirectory(): Path? { + return wrapped.airbyteStagingDirectory() + } + + override fun useFileTransfer(): Boolean { + return wrapped.useFileTransfer() + } + companion object { /** Overrides the [FeatureFlags.deploymentMode] method in the feature flags. */ @JvmStatic diff --git a/airbyte-cdk/java/airbyte-cdk/dependencies/src/testFixtures/kotlin/io/airbyte/workers/exception/TestHarnessException.kt b/airbyte-cdk/java/airbyte-cdk/dependencies/src/testFixtures/kotlin/io/airbyte/workers/exception/TestHarnessException.kt index 15adcfdd2a06..b7f1edd1c0a6 100644 --- a/airbyte-cdk/java/airbyte-cdk/dependencies/src/testFixtures/kotlin/io/airbyte/workers/exception/TestHarnessException.kt +++ b/airbyte-cdk/java/airbyte-cdk/dependencies/src/testFixtures/kotlin/io/airbyte/workers/exception/TestHarnessException.kt @@ -3,8 +3,23 @@ */ package io.airbyte.workers.exception +import io.airbyte.protocol.models.v0.AirbyteMessage + class TestHarnessException : Exception { - constructor(message: String?) : super(message) + val outputMessages: List? + constructor(message: String?) : super(message) { + outputMessages = null + } + + constructor(message: String?, cause: Throwable?) : super(message, cause) { + outputMessages = null + } - constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor( + message: String?, + cause: Throwable?, + outputMessages: List + ) : super(message, cause) { + this.outputMessages = outputMessages + } } diff --git a/airbyte-cdk/java/airbyte-cdk/dependencies/src/testFixtures/kotlin/io/airbyte/workers/process/DockerProcessFactory.kt b/airbyte-cdk/java/airbyte-cdk/dependencies/src/testFixtures/kotlin/io/airbyte/workers/process/DockerProcessFactory.kt index e58319655d9d..03d7a9b8c138 100644 --- a/airbyte-cdk/java/airbyte-cdk/dependencies/src/testFixtures/kotlin/io/airbyte/workers/process/DockerProcessFactory.kt +++ b/airbyte-cdk/java/airbyte-cdk/dependencies/src/testFixtures/kotlin/io/airbyte/workers/process/DockerProcessFactory.kt @@ -7,6 +7,7 @@ import com.google.common.annotations.VisibleForTesting import com.google.common.base.Joiner import com.google.common.base.Strings import com.google.common.collect.Lists +import io.airbyte.commons.features.EnvVariableFeatureFlags import io.airbyte.commons.io.IOs import io.airbyte.commons.io.LineGobbler import io.airbyte.commons.map.MoreMaps @@ -30,6 +31,7 @@ class DockerProcessFactory( private val workspaceRoot: Path, private val workspaceMountSource: String?, private val localMountSource: String?, + private val fileTransferMountSource: Path?, private val networkName: String?, private val envMap: Map ) : ProcessFactory { @@ -125,6 +127,20 @@ class DockerProcessFactory( cmd.add(String.format("%s:%s", localMountSource, LOCAL_MOUNT_DESTINATION)) } + if (fileTransferMountSource != null) { + cmd.add("-v") + cmd.add( + "$fileTransferMountSource:${EnvVariableFeatureFlags.DEFAULT_AIRBYTE_STAGING_DIRECTORY}" + ) + cmd.add("-e") + cmd.add( + "${EnvVariableFeatureFlags.AIRBYTE_STAGING_DIRECTORY_PROPERTY_NAME}=${EnvVariableFeatureFlags.DEFAULT_AIRBYTE_STAGING_DIRECTORY}" + ) + + cmd.add("-e") + cmd.add("${EnvVariableFeatureFlags.USE_FILE_TRANSFER}=true") + } + val allEnvMap = MoreMaps.merge(jobMetadata, envMap, additionalEnvironmentVariables) for ((key, value) in allEnvMap) { cmd.add("-e") diff --git a/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/s3/BaseS3Destination.kt b/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/s3/BaseS3Destination.kt index 84496b9951ec..cf4bac36654d 100644 --- a/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/s3/BaseS3Destination.kt +++ b/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/s3/BaseS3Destination.kt @@ -79,7 +79,8 @@ protected constructor( s3Config, catalog, memoryRatio, - nThreads + nThreads, + featureFlags ) } diff --git a/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/s3/S3ConsumerFactory.kt b/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/s3/S3ConsumerFactory.kt index fdf25cf0c6f7..55e601e55673 100644 --- a/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/s3/S3ConsumerFactory.kt +++ b/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/s3/S3ConsumerFactory.kt @@ -10,6 +10,8 @@ import io.airbyte.cdk.integrations.base.SerializedAirbyteMessageConsumer import io.airbyte.cdk.integrations.destination.StreamSyncSummary import io.airbyte.cdk.integrations.destination.async.AsyncStreamConsumer import io.airbyte.cdk.integrations.destination.async.buffers.BufferManager +import io.airbyte.cdk.integrations.destination.async.function.DestinationFlushFunction +import io.airbyte.cdk.integrations.destination.async.model.PartialAirbyteMessage import io.airbyte.cdk.integrations.destination.buffered_stream_consumer.BufferedStreamConsumer import io.airbyte.cdk.integrations.destination.buffered_stream_consumer.OnCloseFunction import io.airbyte.cdk.integrations.destination.buffered_stream_consumer.OnStartFunction @@ -21,12 +23,17 @@ import io.airbyte.cdk.integrations.destination.record_buffer.SerializableBuffer import io.airbyte.cdk.integrations.destination.record_buffer.SerializedBufferingStrategy import io.airbyte.cdk.integrations.destination.s3.SerializedBufferFactory.Companion.getCreateFunction import io.airbyte.commons.exceptions.ConfigErrorException +import io.airbyte.commons.features.FeatureFlags import io.airbyte.commons.json.Jsons import io.airbyte.protocol.models.v0.* import io.github.oshai.kotlinlogging.KotlinLogging +import java.io.File +import java.text.DecimalFormat import java.util.concurrent.Executors import java.util.function.Consumer import java.util.function.Function +import java.util.stream.Stream +import org.apache.commons.io.FileUtils import org.joda.time.DateTime import org.joda.time.DateTimeZone @@ -188,7 +195,8 @@ class S3ConsumerFactory { s3Config: S3DestinationConfig, catalog: ConfiguredAirbyteCatalog, memoryRatio: Double, - nThreads: Int + nThreads: Int, + featureFlags: FeatureFlags ): SerializedAirbyteMessageConsumer { val writeConfigs = createWriteConfigs(storageOps, s3Config, catalog) // Buffer creation function: yields a file buffer that converts @@ -203,15 +211,6 @@ class S3ConsumerFactory { descriptor to Pair(stream.generationId, stream.syncId) } - val createFunction = - getCreateFunction( - s3Config, - Function { fileExtension: String -> - FileBuffer(fileExtension) - }, - useV2FieldNames = true - ) - // Parquet has significantly higher overhead. This small adjustment // results in a ~5x performance improvement. val adjustedMemoryRatio = @@ -221,25 +220,52 @@ class S3ConsumerFactory { memoryRatio } + // This needs to be called before the creation of the flush function because it updates + // writeConfigs! + val onStartFunction = onStartFunction(storageOps, writeConfigs) + + val streamDescriptorToWriteConfig = + writeConfigs.associateBy { + StreamDescriptor().withNamespace(it.namespace).withName(it.streamName) + } + val flushFunction = + if (featureFlags.useFileTransfer()) { + FileTransferDestinationFlushFunction( + streamDescriptorToWriteConfig, + storageOps, + featureFlags + ) + } else { + val createFunction = + getCreateFunction( + s3Config, + Function { fileExtension: String -> + FileBuffer(fileExtension) + }, + useV2FieldNames = true + ) + S3DestinationFlushFunction( + // Ensure the file buffer is always larger than the memory buffer, + // as the file buffer will be flushed at the end of the memory flush. + optimalBatchSizeBytes = + (FileBuffer.MAX_PER_STREAM_BUFFER_SIZE_BYTES * 0.9).toLong(), + { + // Yield a new BufferingStrategy every time we flush (for thread-safety). + SerializedBufferingStrategy( + createFunction, + catalog, + flushBufferFunction(storageOps, writeConfigs, catalog) + ) + }, + generationAndSyncIds + ) + } + return AsyncStreamConsumer( outputRecordCollector, - onStartFunction(storageOps, writeConfigs), + onStartFunction, onCloseFunction(storageOps, writeConfigs), - S3DestinationFlushFunction( - // Ensure the file buffer is always larger than the memory buffer, - // as the file buffer will be flushed at the end of the memory flush. - optimalBatchSizeBytes = - (FileBuffer.MAX_PER_STREAM_BUFFER_SIZE_BYTES * 0.9).toLong(), - { - // Yield a new BufferingStrategy every time we flush (for thread-safety). - SerializedBufferingStrategy( - createFunction, - catalog, - flushBufferFunction(storageOps, writeConfigs, catalog) - ) - }, - generationAndSyncIds - ), + flushFunction, catalog, // S3 has no concept of default namespace // In the "namespace from destination case", the namespace @@ -248,10 +274,57 @@ class S3ConsumerFactory { defaultNamespace = null, maxMemory = (Runtime.getRuntime().maxMemory() * adjustedMemoryRatio).toLong() ), - workerPool = Executors.newFixedThreadPool(nThreads) + workerPool = Executors.newFixedThreadPool(nThreads), + flushOnEveryMessage = featureFlags.useFileTransfer() ) } + private class FileTransferDestinationFlushFunction( + val streamDescriptorToWriteConfig: Map, + val storageOps: S3StorageOperations, + val featureFlags: FeatureFlags + ) : DestinationFlushFunction { + override fun flush( + streamDescriptor: StreamDescriptor, + stream: Stream + ) { + val records = stream.toList() + val writeConfig = streamDescriptorToWriteConfig.getValue(streamDescriptor) + if (records.isEmpty()) { + return + } + if (records.size > 1) { + throw RuntimeException( + "the destinationFlushFunction for RAW_FILES should be called with only 1 record" + ) + } + val file = records[0].record!!.file + if (file == null) { + throw RuntimeException(MISSING_FILE_FIELD_IN_FILE_TRANSFER_ERROR_MESSAGE) + } + val absolutePath = file.fileUrl!! + val relativePath = file.fileRelativePath!! + val fullObjectKey = writeConfig.fullOutputPath + relativePath + val dataFile = File(absolutePath) + val fileSize = dataFile.length() + val startTimeMs = System.currentTimeMillis() + storageOps.loadDataIntoBucket( + fullObjectKey = fullObjectKey, + fileName = dataFile.name, + fileContent = dataFile.inputStream(), + generationId = writeConfig.generationId + ) + val elapsedTimeSeconds = (System.currentTimeMillis() - startTimeMs) / 1_000.0 + val speedMBps = (fileSize / (1_024 * 1_024)) / elapsedTimeSeconds + LOGGER.info { + "wrote ${FileUtils.byteCountToDisplaySize(fileSize)} file in $elapsedTimeSeconds s, for a speed of ${decimalFormat.format(speedMBps)} MBps" + } + dataFile.delete() + } + + override val optimalBatchSizeBytes: Long = 1L + } + private fun isAppendSync(writeConfig: WriteConfig): Boolean { // This is an additional safety check, that this really is OVERWRITE // mode, this avoids bad things happening like deleting all objects @@ -323,8 +396,10 @@ class S3ConsumerFactory { } companion object { - + val decimalFormat = DecimalFormat("#.###") private val SYNC_DATETIME: DateTime = DateTime.now(DateTimeZone.UTC) + val MISSING_FILE_FIELD_IN_FILE_TRANSFER_ERROR_MESSAGE = + "the RECORD message doesn't have a file field in file transfer mode" private fun createWriteConfigs( storageOperations: BlobStorageOperations, diff --git a/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/s3/S3DestinationFlushFunction.kt b/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/s3/S3DestinationFlushFunction.kt index cb89081ddd0b..de15e206baac 100644 --- a/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/s3/S3DestinationFlushFunction.kt +++ b/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/s3/S3DestinationFlushFunction.kt @@ -27,13 +27,16 @@ class S3DestinationFlushFunction( strategyProvider().use { strategy -> for (partialMessage in stream) { val partialRecord = partialMessage.record!! - val data = + if (partialRecord.file != null) { + throw RuntimeException(FILE_RECORD_ERROR_MESSAGE) + } /** * This should always be null, but if something changes upstream to trigger a clone * of the record, then `null` becomes `JsonNull` and `data == null` goes from `true` * to `false` */ - if (partialRecord.data == null || partialRecord.data!!.isNull) { + val data = + if (partialRecord.data == null || partialRecord.data!!.isNull) { Jsons.deserialize(partialMessage.serialized) } else { partialRecord.data @@ -53,4 +56,9 @@ class S3DestinationFlushFunction( strategy.flushSingleStream(nameAndNamespace) } } + + companion object { + val FILE_RECORD_ERROR_MESSAGE = + "received a message of RECORD type with a populated `file` attribute. This should only happen in file transfer mode" + } } diff --git a/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/s3/S3StorageOperations.kt b/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/s3/S3StorageOperations.kt index 894e53789973..85a8d546a1f8 100644 --- a/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/s3/S3StorageOperations.kt +++ b/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/main/kotlin/io/airbyte/cdk/integrations/destination/s3/S3StorageOperations.kt @@ -22,8 +22,7 @@ import io.airbyte.cdk.integrations.destination.s3.util.StreamTransferManagerFact import io.airbyte.cdk.integrations.util.ConnectorExceptionUtil import io.airbyte.commons.exceptions.ConfigErrorException import io.github.oshai.kotlinlogging.KotlinLogging -import java.io.IOException -import java.io.OutputStream +import java.io.* import java.util.* import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentMap @@ -194,15 +193,32 @@ open class S3StorageOperations( } while (objectNameByPrefix.getValue(objectPath).contains(fullObjectKey)) return fullObjectKey } + @Throws(IOException::class) private fun loadDataIntoBucket( objectPath: String, recordsData: SerializableBuffer, generationId: Long + ): String { + val fullObjectKey: String = getFileName(objectPath, recordsData) + return loadDataIntoBucket( + fullObjectKey, + recordsData.filename, + recordsData.inputStream!!, + generationId + ) + } + + @Throws(IOException::class) + public fun loadDataIntoBucket( + fullObjectKey: String, + fileName: String, + fileContent: InputStream, + generationId: Long ): String { val partSize: Long = DEFAULT_PART_SIZE.toLong() val bucket: String? = s3Config.bucketName - val fullObjectKey: String = getFileName(objectPath, recordsData) + val metadata: MutableMap = HashMap() for (blobDecorator: BlobDecorator in blobDecorators) { blobDecorator.updateMetadata(metadata, getMetadataMapping()) @@ -232,13 +248,13 @@ open class S3StorageOperations( try { rawOutputStream.use { outputStream -> - recordsData.inputStream!!.use { dataStream -> + fileContent.use { dataStream -> dataStream.transferTo(outputStream) succeeded = true } } } catch (e: Exception) { - logger.error(e) { "Failed to load data into storage $objectPath" } + logger.error(e) { "Failed to load data into storage $fullObjectKey" } throw RuntimeException(e) } finally { if (!succeeded) { @@ -253,7 +269,7 @@ open class S3StorageOperations( } val newFilename: String = getFilename(fullObjectKey) logger.info { - "Uploaded buffer file to storage: ${recordsData.filename} -> $fullObjectKey (filename: $newFilename)" + "Uploaded buffer file to storage: $fileName -> $fullObjectKey (filename: $newFilename)" } return newFilename } @@ -611,7 +627,7 @@ open class S3StorageOperations( private const val FORMAT_VARIABLE_EPOCH: String = "\${EPOCH}" private const val FORMAT_VARIABLE_UUID: String = "\${UUID}" private const val GZ_FILE_EXTENSION: String = "gz" - private const val GENERATION_ID_USER_META_KEY = "ab-generation-id" + const val GENERATION_ID_USER_META_KEY = "ab-generation-id" @VisibleForTesting @JvmStatic fun getFilename(fullPath: String): String { diff --git a/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/testFixtures/kotlin/io/airbyte/cdk/integrations/destination/s3/S3BaseDestinationAcceptanceTest.kt b/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/testFixtures/kotlin/io/airbyte/cdk/integrations/destination/s3/S3BaseDestinationAcceptanceTest.kt new file mode 100644 index 000000000000..845b2bc9e637 --- /dev/null +++ b/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/testFixtures/kotlin/io/airbyte/cdk/integrations/destination/s3/S3BaseDestinationAcceptanceTest.kt @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.cdk.integrations.destination.s3 + +import com.amazonaws.services.s3.AmazonS3 +import com.amazonaws.services.s3.model.S3ObjectSummary +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.ObjectNode +import io.airbyte.cdk.integrations.destination.NamingConventionTransformer +import io.airbyte.cdk.integrations.destination.s3.util.S3NameTransformer +import io.airbyte.cdk.integrations.standardtest.destination.BaseDestinationAcceptanceTest +import io.airbyte.cdk.integrations.standardtest.destination.DestinationAcceptanceTest +import io.airbyte.commons.io.IOs +import io.airbyte.commons.json.Jsons +import io.github.oshai.kotlinlogging.KotlinLogging +import java.nio.file.Path +import java.util.Comparator +import java.util.HashSet +import org.apache.commons.lang3.RandomStringUtils +import org.joda.time.DateTime +import org.joda.time.DateTimeZone +import org.mockito.Mockito + +private val LOGGER = KotlinLogging.logger {} + +abstract class S3BaseDestinationAcceptanceTest() : + BaseDestinationAcceptanceTest( + verifyIndividualStateAndCounts = true, + ) { + protected val secretFilePath: String = "secrets/config.json" + override val imageName: String + get() = "airbyte/destination-s3:dev" + protected var configJson: JsonNode? = null + + override fun getConfig(): JsonNode = configJson!! + protected open val baseConfigJson: JsonNode + get() = Jsons.deserialize(IOs.readFile(Path.of(secretFilePath))) + protected abstract val formatConfig: JsonNode? + get + protected var s3DestinationConfig: S3DestinationConfig = Mockito.mock() + protected var s3Client: AmazonS3? = null + protected var s3nameTransformer: NamingConventionTransformer = Mockito.mock() + protected var s3StorageOperations: S3StorageOperations? = null + var testBucketPath: String? = null + + fun storageProvider(): StorageProvider { + return StorageProvider.AWS_S3 + } + + /** + * This method does the following: + * * Construct the S3 destination config. + * * Construct the S3 client. + */ + override fun setup( + testEnv: DestinationAcceptanceTest.TestDestinationEnv, + TEST_SCHEMAS: HashSet + ) { + val baseConfigJson = baseConfigJson + // Set a random s3 bucket path for each integration test + val configJson = Jsons.clone(baseConfigJson) + testBucketPath = + String.format( + "test_%s", + RandomStringUtils.insecure().nextAlphanumeric(5), + ) + (configJson as ObjectNode) + .put("s3_bucket_path", testBucketPath) + .set("format", formatConfig) + this.configJson = configJson + this.s3DestinationConfig = + S3DestinationConfig.getS3DestinationConfig( + configJson, + storageProvider(), + getConnectorEnv() + ) + LOGGER.info { + "${"Test full path: {}/{}"} ${s3DestinationConfig.bucketName} ${s3DestinationConfig.bucketPath}" + } + + this.s3Client = s3DestinationConfig.getS3Client() + this.s3nameTransformer = S3NameTransformer() + this.s3StorageOperations = + S3StorageOperations(s3nameTransformer, s3Client!!, s3DestinationConfig) + } + + fun getDefaultSchema(): String { + if (configJson!!.has("s3_bucket_path")) { + return configJson!!["s3_bucket_path"].asText() + } + throw RuntimeException() + } + + /** Helper method to retrieve all synced objects inside the configured bucket path. */ + protected fun getAllSyncedObjects( + streamName: String, + ): List { + val namespaceStr = s3nameTransformer.getNamespace(getDefaultSchema()) + val streamNameStr = s3nameTransformer.getIdentifier(streamName) + val outputPrefix = + s3StorageOperations!!.getBucketObjectPath( + namespaceStr, + streamNameStr, + DateTime.now(DateTimeZone.UTC), + s3DestinationConfig.pathFormat!!, + ) + // the child folder contains a non-deterministic epoch timestamp, so use the parent folder + val parentFolder = outputPrefix.substring(0, outputPrefix.lastIndexOf("/") + 1) + val objectSummaries = + s3Client!! + .listObjects(s3DestinationConfig.bucketName, parentFolder) + .objectSummaries + .filter { o: S3ObjectSummary -> o.key.contains("$streamNameStr/") } + .sortedWith(Comparator.comparingLong { o: S3ObjectSummary -> o.lastModified.time }) + + LOGGER.info { + "${"All objects: {}"} ${ + objectSummaries.map { o: S3ObjectSummary -> + String.format("%s/%s", o.bucketName, o.key) + } + }" + } + return objectSummaries + } +} diff --git a/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/testFixtures/kotlin/io/airbyte/cdk/integrations/destination/s3/S3DestinationAcceptanceTest.kt b/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/testFixtures/kotlin/io/airbyte/cdk/integrations/destination/s3/S3DestinationAcceptanceTest.kt index 8095464a4d62..04bec228cc53 100644 --- a/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/testFixtures/kotlin/io/airbyte/cdk/integrations/destination/s3/S3DestinationAcceptanceTest.kt +++ b/airbyte-cdk/java/airbyte-cdk/s3-destinations/src/testFixtures/kotlin/io/airbyte/cdk/integrations/destination/s3/S3DestinationAcceptanceTest.kt @@ -12,11 +12,13 @@ import com.fasterxml.jackson.databind.node.JsonNodeFactory import com.fasterxml.jackson.databind.node.ObjectNode import com.google.common.collect.ImmutableMap import io.airbyte.cdk.integrations.destination.NamingConventionTransformer +import io.airbyte.cdk.integrations.destination.async.model.AirbyteRecordMessageFile import io.airbyte.cdk.integrations.destination.s3.util.S3NameTransformer import io.airbyte.cdk.integrations.standardtest.destination.DestinationAcceptanceTest import io.airbyte.cdk.integrations.standardtest.destination.argproviders.DataArgumentsProvider import io.airbyte.cdk.integrations.standardtest.destination.comparator.AdvancedTestDataComparator import io.airbyte.cdk.integrations.standardtest.destination.comparator.TestDataComparator +import io.airbyte.commons.features.EnvVariableFeatureFlags import io.airbyte.commons.io.IOs import io.airbyte.commons.jackson.MoreMappers import io.airbyte.commons.json.Jsons @@ -27,9 +29,11 @@ import io.github.oshai.kotlinlogging.KotlinLogging import java.nio.file.Path import java.time.Instant import java.util.* +import kotlin.test.assertContains import org.apache.commons.lang3.RandomStringUtils import org.joda.time.DateTime import org.joda.time.DateTimeZone +import org.junit.Assert.fail import org.junit.jupiter.api.Assumptions.* import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows @@ -487,7 +491,7 @@ protected constructor( * both syncs are preserved. */ @Test - fun testOverwriteSyncFailedResumedGeneration() { + open fun testOverwriteSyncFailedResumedGeneration() { assumeTrue( implementsOverwrite(), "Destination's spec.json does not support overwrite sync mode." @@ -521,7 +525,7 @@ protected constructor( /** Test runs 2 failed syncs and verifies the previous sync objects are not cleaned up. */ @Test - fun testOverwriteSyncMultipleFailedGenerationsFilesPreserved() { + open fun testOverwriteSyncMultipleFailedGenerationsFilesPreserved() { assumeTrue( implementsOverwrite(), "Destination's spec.json does not support overwrite sync mode." @@ -734,6 +738,77 @@ protected constructor( ) } + @Test + open fun testFakeFileTransfer() { + val streamSchema = JsonNodeFactory.instance.objectNode() + streamSchema.set("properties", JsonNodeFactory.instance.objectNode()) + val streamName = "str" + RandomStringUtils.randomAlphanumeric(5) + val catalog = + ConfiguredAirbyteCatalog() + .withStreams( + java.util.List.of( + ConfiguredAirbyteStream() + .withSyncMode(SyncMode.INCREMENTAL) + .withDestinationSyncMode(DestinationSyncMode.APPEND_DEDUP) + .withGenerationId(0) + .withMinimumGenerationId(0) + .withSyncId(0) + .withStream( + AirbyteStream().withName(streamName).withJsonSchema(streamSchema) + ), + ), + ) + + val recordMessage = + AirbyteMessage() + .withType(AirbyteMessage.Type.RECORD) + .withRecord( + AirbyteRecordMessage() + .withStream(streamName) + .withEmittedAt(Instant.now().toEpochMilli()) + .withData(ObjectMapper().readTree("{}")) + .withAdditionalProperty( + "file", + AirbyteRecordMessageFile( + fileUrl = + "${EnvVariableFeatureFlags.DEFAULT_AIRBYTE_STAGING_DIRECTORY}/fakeFile", + bytes = 182776, + fileRelativePath = "fakeFile", + modified = 123456L, + sourceFileUrl = + "//sftp-testing-for-file-transfer/sftp-folder/simpsons_locations.csv", + ) + ) + ) + val streamCompleteMessage = + AirbyteMessage() + .withType(AirbyteMessage.Type.TRACE) + .withTrace( + AirbyteTraceMessage() + .withStreamStatus( + AirbyteStreamStatusTraceMessage() + .withStatus( + AirbyteStreamStatusTraceMessage.AirbyteStreamStatus.COMPLETE + ) + .withStreamDescriptor(StreamDescriptor().withName(streamName)) + ) + ) + try { + val destinationOutput = + runSync( + config = getConfig(), + messages = listOf(recordMessage, streamCompleteMessage), + catalog = catalog, + runNormalization = false, + imageName = imageName, + additionalEnvs = mapOf("USE_FILE_TRANSFER" to "true"), + ) + fail("sync should have failed. Instead got output $destinationOutput") + } catch (e: TestHarnessException) { + assertContains(e.outputMessages!![0].trace.error.internalMessage, "File does not exist") + } + } + companion object { @JvmStatic protected val MAPPER: ObjectMapper = MoreMappers.initMapper() diff --git a/airbyte-cdk/java/airbyte-cdk/typing-deduping/src/testFixtures/kotlin/io/airbyte/integrations/base/destination/typing_deduping/BaseTypingDedupingTest.kt b/airbyte-cdk/java/airbyte-cdk/typing-deduping/src/testFixtures/kotlin/io/airbyte/integrations/base/destination/typing_deduping/BaseTypingDedupingTest.kt index 1c7c08350d01..6aa2d476cc5a 100644 --- a/airbyte-cdk/java/airbyte-cdk/typing-deduping/src/testFixtures/kotlin/io/airbyte/integrations/base/destination/typing_deduping/BaseTypingDedupingTest.kt +++ b/airbyte-cdk/java/airbyte-cdk/typing-deduping/src/testFixtures/kotlin/io/airbyte/integrations/base/destination/typing_deduping/BaseTypingDedupingTest.kt @@ -1525,6 +1525,7 @@ abstract class BaseTypingDedupingTest { workspaceRoot, workspaceRoot.toString(), localRoot.toString(), + fileTransferMountSource = null, "host", emptyMap() ) @@ -1534,7 +1535,6 @@ abstract class BaseTypingDedupingTest { .withConnectionId(UUID.randomUUID()) .withCatalog(convertProtocolObject(catalog, ConfiguredAirbyteCatalog::class.java)) .withDestinationConnectionConfiguration(transformedConfig) - val destination: AirbyteDestination = DefaultAirbyteDestination( integrationLauncher = diff --git a/airbyte-cdk/python/.coveragerc b/airbyte-cdk/python/.coveragerc deleted file mode 100644 index e83ca1d70fa3..000000000000 --- a/airbyte-cdk/python/.coveragerc +++ /dev/null @@ -1,11 +0,0 @@ -[report] -# show lines missing coverage -show_missing = true - -[run] -omit = - # omit the models package as it's auto-generated - airbyte_cdk/models/* - - # omit as unimplemented - airbyte_cdk/base_python/cdk/streams/auth/jwt.py diff --git a/airbyte-cdk/python/.dockerignore b/airbyte-cdk/python/.dockerignore deleted file mode 100644 index 378eac25d311..000000000000 --- a/airbyte-cdk/python/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -build diff --git a/airbyte-cdk/python/.gitignore b/airbyte-cdk/python/.gitignore deleted file mode 100644 index 3d99a021c606..000000000000 --- a/airbyte-cdk/python/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -.coverage - -# TODO: these are tmp files generated by unit tests. They should go to the /tmp directory. -` - -## 0.56.1 - -no-op to verify pypi publish flow - -## 0.56.0 - -Allow for connectors to continue syncing when a stream fails - -## 0.55.5 - -File-based CDK: hide source-defined primary key; users can define primary keys in the connection's configuration - -## 0.55.4 - -Source Integration tests: decoupling entrypoint wrapper from pytest - -## 0.55.3 - -First iteration of integration tests tooling (http mocker and response builder) - -## 0.55.2 - -concurrent-cdk: factory method initializes concurrent source with default number of max tasks - -## 0.55.1 - -Vector DB CDK: Add omit_raw_text flag - -## 0.55.0 - -concurrent cdk: read multiple streams concurrently - -## 0.54.0 - -low-code: fix injection of page token if first request - -## 0.53.9 - -Fix of generate the error message using \_try_get_error based on list of errors - -## 0.53.8 - -Vector DB CDK: Remove CDC records, File CDK: Update unstructured parser - -## 0.53.7 - -low-code: fix debug logging when using --debug flag - -## 0.53.6 - -Increase maximum_attempts_to_acquire to avoid crashing in acquire_call - -## 0.53.5 - -File CDK: Improve stream config appearance - -## 0.53.4 - -Concurrent CDK: fix futures pruning - -## 0.53.3 - -Fix spec schema generation for File CDK and Vector DB CDK and allow skipping invalid files in document file parser - -## 0.53.2 - -Concurrent CDK: Increase connection pool size to allow for 20 max workers - -## 0.53.1 - -Concurrent CDK: Improve handling of future to avoid memory leak and improve performances - -## 0.53.0 - -Add call rate functionality - -## 0.52.10 - -Fix class SessionTokenAuthenticator for CLASS_TYPES_REGISTRY mapper - -## 0.52.9 - -File CDK: Improve file type detection in document file type parser - -## 0.52.8 - -Concurrent CDK: incremental (missing state conversion). Outside of concurrent specific work, this includes the following changes: - -- Checkpointing state was acting on the number of records per slice. This has been changed to consider the number of records per syncs -- `Source.read_state` and `Source._emit_legacy_state_format` are now classmethods to allow for developers to have access to the state before instantiating the source - -## 0.52.7 - -File CDK: Add pptx support - -## 0.52.6 - -make parameter as not required for default backoff handler - -## 0.52.5 - -use in-memory cache if no file path is provided - -## 0.52.4 - -File CDK: Add unstructured parser - -## 0.52.3 - -Update source-declarative-manifest base image to update Linux alpine and Python - -## 0.52.2 - -## 0.52.1 - -Add max time for backoff handler - -## 0.52.0 - -File CDK: Add CustomFileBasedException for custom errors - -## 0.51.44 - -low-code: Allow connector developers to specify the type of an added field - -## 0.51.43 - -concurrent cdk: fail fast if a partition raises an exception - -## 0.51.42 - -File CDK: Avoid listing all files for check command - -## 0.51.41 - -Vector DB CDK: Expose stream identifier logic, add field remapping to processing | File CDK: Emit analytics message for used streams - -## 0.51.40 - -Add filters for base64 encode and decode in Jinja Interpolation - -## 0.51.39 - -Few bug fixes for concurrent cdk - -## 0.51.38 - -Add ability to wrap HTTP errors with specific status codes occurred during access token refresh into AirbyteTracedException - -## 0.51.37 - -Enable debug logging when running availability check - -## 0.51.36 - -Enable debug logging when running availability check - -## 0.51.35 - -File CDK: Allow configuring number of tested files for schema inference and parsability check - -## 0.51.34 - -Vector DB CDK: Fix OpenAI compatible embedder when used without api key - -## 0.51.33 - -Vector DB CDK: Improve batching process - -## 0.51.32 - -Introduce experimental ThreadBasedConcurrentStream - -## 0.51.31 - -Fix initialize of token_expiry_is_time_of_expiration field - -## 0.51.30 - -Add new token_expiry_is_time_of_expiration property for AbstractOauth2Authenticator for indicate that token's expiry_in is a time of expiration - -## 0.51.29 - -Coerce read_records to iterable in http availabilty strategy - -## 0.51.28 - -Add functionality enabling Page Number/Offset to be set on the first request - -## 0.51.27 - -Fix parsing of UUID fields in avro files - -## 0.51.26 - -Vector DB CDK: Fix OpenAI embedder batch size - -## 0.51.25 - -Add configurable OpenAI embedder to cdk and add cloud environment helper - -## 0.51.24 - -Fix previous version of request_cache clearing - -## 0.51.23 - -Fix request_cache clearing and move it to tmp folder - -## 0.51.22 - -Vector DB CDK: Adjust batch size for Azure embedder to current limits - -## 0.51.21 - -Change Error message if Stream is not found - -## 0.51.20 - -Vector DB CDK: Add text splitting options to document processing - -## 0.51.19 - -Ensuring invalid user-provided urls does not generate sentry issues - -## 0.51.18 - -Vector DB CDK adjustments: Prevent failures with big records and OpenAI embedder - -## 0.51.17 - -[ISSUE #30353] File-Based CDK: remove file_type from stream config - -## 0.51.16 - -Connector Builder: fix datetime format inference for str parsable as int but not isdecimal - -## 0.51.15 - -Vector DB CDK: Add Azure OpenAI embedder - -## 0.51.14 - -File-based CDK: improve error message for CSV parsing error - -## 0.51.13 - -File-based CDK: migrated parsing error to config error to avoid sentry alerts - -## 0.51.12 - -Add from-field embedder to vector db CDK - -## 0.51.11 - -FIle-based CDK: Update spec and fix autogenerated headers with skip after - -## 0.51.10 - -Vector DB CDK adjustments: Fix id generation, improve config spec, add base test case - -## 0.51.9 - -[Issue #29660] Support empty keys with record selection - -## 0.51.8 - -Add vector db CDK helpers - -## 0.51.7 - -File-based CDK: allow user to provided column names for CSV files - -## 0.51.6 - -File-based CDK: allow for extension mismatch - -## 0.51.5 - -File-based CDK: Remove CSV noisy log - -## 0.51.4 - -Source-S3 V4: feature parity rollout - -## 0.51.3 - -File-based CDK: Do not stop processing files in slice on error - -## 0.51.2 - -Check config against spec in embedded sources and remove list endpoint from connector builder module - -## 0.51.1 - -low-code: allow formatting datetime as milliseconds since unix epoch - -## 0.51.0 - -File-based CDK: handle legacy options - -## 0.50.2 - -Fix title and description of datetime_format fields - -## 0.50.1 - -File-based CDK cursor and entrypoint updates - -## 0.50.0 - -Low code CDK: Decouple SimpleRetriever and HttpStream - -## 0.49.0 - -Add utils for embedding sources in other Python applications - -## 0.48.0 - -Relax pydantic version requirement and update to protocol models version 0.4.0 - -## 0.47.5 - -Support many format for cursor datetime - -## 0.47.4 - -File-based CDK updates - -## 0.47.3 - -Connector Builder: Ensure we return when there are no slices - -## 0.47.2 - -low-code: deduplicate query params if they are already encoded in the URL - -## 0.47.1 - -Fix RemoveFields transformation issue - -## 0.47.0 - -Breaking change: Rename existing SessionTokenAuthenticator to LegacySessionTokenAuthenticator and make SessionTokenAuthenticator more generic - -## 0.46.1 - -Connector builder: warn if the max number of records was reached - -## 0.46.0 - -Remove pyarrow from main dependency and add it to extras - -## 0.45.0 - -Fix pyyaml and cython incompatibility - -## 0.44.4 - -Connector builder: Show all request/responses as part of the testing panel - -## 0.44.3 - -[ISSUE #27494] allow for state to rely on transformed field - -## 0.44.2 - -Ensuring the state value format matches the cursor value from the record - -## 0.44.1 - -Fix issue with incremental sync following data feed release - -## 0.44.0 - -Support data feed like incremental syncs - -## 0.43.3 - -Fix return type of RecordFilter: changed from generator to list - -## 0.43.2 - -Connector builder module: serialize request body as string - -## 0.43.1 - -Fix availability check to handle HttpErrors which happen during slice extraction - -## 0.43.0 - -Refactoring declarative state management - -## 0.42.1 - -Error message on state per partition state discrepancy - -## 0.42.0 - -Supporting state per partition given incremental sync and partition router - -## 0.41.0 - -Use x-www-urlencoded for access token refresh requests - -## 0.40.5 - -Replace with when making oauth calls - -## 0.40.4 - -Emit messages using message repository - -## 0.40.3 - -Add utils for inferring datetime formats - -## 0.40.2 - -Add a metadata field to the declarative component schema - -## 0.40.1 - -make DatetimeBasedCursor.end_datetime optional - -## 0.40.0 - -Remove SingleUseRefreshTokenOAuthAuthenticator from low code CDK and add generic injection capabilities to ApiKeyAuthenticator - -## 0.39.4 - -Connector builder: add latest connector config control message to read calls - -## 0.39.3 - -Add refresh token update capabilities to OAuthAuthenticator - -## 0.39.2 - -Make step and cursor_granularity optional - -## 0.39.1 - -Improve connector builder error messages - -## 0.39.0 - -Align schema generation in SchemaInferrer with Airbyte platform capabilities - -## 0.38.0 - -Allow nested objects in request_body_json - -## 0.37.0 - -low-code: Make refresh token in oauth authenticator optional - -## 0.36.5 - -Unfreeze requests version and test new pipeline - -## 0.36.4 - -low-code: use jinja sandbox and restrict some methods - -## 0.36.3 - -pin the version of the requests library - -## 0.36.2 - -Support parsing non UTC dates and Connector Builder set slice descriptor - -## 0.36.1 - -low-code: fix add field transformation when running from the connector builder - -## 0.36.0 - -Emit stream status messages - -## 0.35.4 - -low-code: remove now_local() macro because it's too unpredictable - -## 0.35.3 - -low-code: alias stream_interval and stream_partition to stream_slice in jinja context - -## 0.35.2 - -Connector builder scrubs secrets from raw request and response - -## 0.35.1 - -low-code: Add title, description, and examples for all fields in the manifest schema - -## 0.35.0 - -low-code: simplify session token authenticator interface - -## 0.34.3 - -low-code: fix typo in ManifestDeclarativeSource - -## 0.34.2 - -Emit slice log messages when running the connector builder - -## 0.34.1 - -set slice and pages limit when reading from the connector builder module - -## 0.34.0 - -Low-Code CDK: Enable use of SingleUseRefreshTokenAuthenticator - -## 0.33.2 - -low-code: fix duplicate stream slicer update - -## 0.33.1 - -Low-Code CDK: make RecordFilter.filter_records as generator - -## 0.33.0 - -Enable oauth flow for low-code connectors - -## 0.32.0 - -Remove unexpected error swallowing on abstract source's check method - -## 0.31.1 - -connector builder: send stacktrace when error on read - -## 0.31.0 - -Add connector builder module for handling Connector Builder server requests - -## 0.30.4 - -CDK's read command handler supports Connector Builder list_streams requests - -## 0.30.3 - -Fix reset pagination issue on test reads - -## 0.30.2 - -- Low-code CDK: Override refresh_access_token logic DeclarativeOAuthAuthenticator - -## 0.30.1 - -Releasing using the new release flow. No change to the CDK per se - -## 0.30.0 - -OAuth: retry refresh access token requests - -## 0.29.3 - -Low-Code CDK: duration macro added - -## 0.29.2 - -support python3.8 - -## 0.29.1 - -Publishing Docker image for source-declarative-manifest - -## 0.29.0 - -**Breaking changes: We have promoted the low-code CDK to Beta. This release contains a number of breaking changes intended to improve the overall usability of the language by reorganizing certain concepts, renaming, reducing some field duplication, and removal of fields that are seldom used.** - -The changes are: - -- Deprecated the concept of Stream Slicers in favor of two individual concepts: Incremental Syncs, and Partition Routers: - - Stream will define an `incremental_sync` field which is responsible for defining how the connector should support incremental syncs using a cursor field. `DatetimeStreamSlicer` has been renamed to `DatetimeBasedCursor` and can be used for this field. - - `Retriever`s will now define a `partition_router` field. The remaining slicers are now called `SubstreamPartitionRouter` and `ListPartitionRouter`, both of which can be used here as they already have been. - - The `CartesianProductStreamSlicer` because `partition_router` can accept a list of values and will generate that same cartesian product by default. -- `$options` have been renamed to `$parameters` -- Changed the notation for component references to the JSON schema notation (`$ref: "#/definitions/requester"`) -- `DefaultPaginator` no longer has a `url_base` field. Moving forward, paginators will derive the `url_base` from the `HttpRequester`. There are some unique cases for connectors that implement a custom `Retriever`. -- `primary_key` and `name` no longer need to be defined on `Retriever`s or `Requester`s. They will be derived from the stream’s definition -- Streams no longer define a `stream_cursor_field` and will derive it from the `incremental_sync` component. `checkpoint_interval` has also been deprecated -- DpathExtractor `field_pointer` has been renamed to `field_path` -- `RequestOption` can no longer be used with with `inject_into` set to `path`. There is now a dedicated `RequestPath` component moving forward. - -## 0.28.1 - -Low-Code CDK: fix signature \_parse_records_and_emit_request_and_responses - -## 0.28.0 - -Low-Code: improve day_delta macro and MinMaxDatetime component - -## 0.27.0 - -Make HttpAvailabilityStrategy default for HttpStreams - -## 0.26.0 - -Low-Code CDK: make DatetimeStreamSlicer.step as InterpolatedString - -## 0.25.2 - -Low-Code: SubstreamSlicer.parent_key - dpath support added - -## 0.25.1 - -Fix issue when trying to log stream slices that are non-JSON-serializable - -## 0.25.0 - -Use dpath.util.values method to parse response with nested lists - -## 0.24.0 - -Use dpath.util.values method to parse response with nested lists - -## 0.23.0 - -Limiting the number of HTTP requests during a test read - -## 0.22.0 - -Surface the resolved manifest in the CDK - -## 0.21.0 - -Add AvailabilityStrategy concept and use check_availability within CheckStream - -## 0.20.2 - -Add missing package in previous patch release - -## 0.20.1 - -Handle edge cases for CheckStream - checking connection to empty stream, and checking connection to substream with no parent records - -## 0.20.0 - -Low-Code: Refactor low-code to use Pydantic model based manifest parsing and component creation - -## 0.19.1 - -Low-code: Make documentation_url in the Spec be optional - -## 0.19.0 - -Low-Code: Handle forward references in manifest - -## 0.18.1 - -Allow for CustomRequester to be defined within declarative manifests - -## 0.18.0 - -Adding `cursor_granularity` to the declarative API of DatetimeStreamSlicer - -## 0.17.0 - -Add utility class to infer schemas from real records - -## 0.16.3 - -Do not eagerly refresh access token in `SingleUseRefreshTokenOauth2Authenticator` [#20923](https://github.com/airbytehq/airbyte/pull/20923) - -## 0.16.2 - -Fix the naming of OAuthAuthenticator - -## 0.16.1 - -Include declarative_component_schema.yaml in the publish to PyPi - -## 0.16.0 - -Start validating low-code manifests using the declarative_component_schema.yaml file - -## 0.15.0 - -Reverts additions from versions 0.13.0 and 0.13.3. - -## 0.14.0 - -Low-code: Add token_expiry_date_format to OAuth Authenticator. Resolve ref schema - -## 0.13.3 - -Fixed `StopIteration` exception for empty streams while `check_availability` runs. - -## 0.13.2 - -Low-code: Enable low-code CDK users to specify schema inline in the manifest - -## 0.13.1 - -Low-code: Add `SessionTokenAuthenticator` - -## 0.13.0 - -Add `Stream.check_availability` and `Stream.AvailabilityStrategy`. Make `HttpAvailabilityStrategy` the default `HttpStream.AvailabilityStrategy`. - -## 0.12.4 - -Lookback window should applied when a state is supplied as well - -## 0.12.3 - -Low-code: Finally, make `OffsetIncrement.page_size` interpolated string or int - -## 0.12.2 - -Revert breaking change on `read_config` while keeping the improvement on the error message - -## 0.12.0 - -Improve error readability when reading JSON config files - -## 0.11.3 - -Low-code: Log response error message on failure - -## 0.11.2 - -Low-code: Include the HTTP method used by the request in logging output of the `airbyte-cdk` - -## 0.11.1 - -Low-code: Fix the component manifest schema to and validate check instead of checker - -## 0.11.0 - -Declare a new authenticator `SingleUseRefreshTokenOauth2Authenticator` that can perform connector configuration mutation and emit `AirbyteControlMessage.ConnectorConfig`. - -## 0.10.0 - -Low-code: Add `start_from_page` option to a PageIncrement class - -## 0.9.5 - -Low-code: Add jinja macro `format_datetime` - -## 0.9.4 - -Low-code: Fix reference resolution for connector builder - -## 0.9.3 - -Low-code: Avoid duplicate HTTP query in `simple_retriever` - -## 0.9.2 - -Low-code: Make `default_paginator.page_token_option` optional - -## 0.9.1 - -Low-code: Fix filtering vars in `InterpolatedRequestInputProvider.eval_request_inputs` - -## 0.9.0 - -Low-code: Allow `grant_type` to be specified for OAuthAuthenticator - -## 0.8.1 - -Low-code: Don't update cursor for non-record messages and fix default loader for connector builder manifests - -## 0.8.0 - -Low-code: Allow for request and response to be emitted as log messages - -## 0.7.1 - -Low-code: Decouple yaml manifest parsing from the declarative source implementation - -## 0.7.0 - -Low-code: Allow connector specifications to be defined in the manifest - -## 0.6.0 - -Low-code: Add support for monthly and yearly incremental updates for `DatetimeStreamSlicer` - -## 0.5.4 - -Low-code: Get response.json in a safe way - -## 0.5.3 - -Low-code: Replace EmptySchemaLoader with DefaultSchemaLoader to retain backwards compatibility -Low-code: Evaluate backoff strategies at runtime - -## 0.5.2 - -Low-code: Allow for read even when schemas are not defined for a connector yet - -## 0.4.2 - -Low-code: Fix off by one error with the stream slicers - -## 0.4.1 - -Low-code: Fix a few bugs with the stream slicers - -## 0.4.0 - -Low-code: Add support for custom error messages on error response filters - -## 0.3.0 - -Publish python typehints via `py.typed` file. - -## 0.2.3 - -- Propagate options to InterpolatedRequestInputProvider - -## 0.2.2 - -- Report config validation errors as failed connection status during `check`. -- Report config validation errors as `config_error` failure type. - -## 0.2.1 - -- Low-code: Always convert stream slices output to an iterator - -## 0.2.0 - -- Replace caching method: VCR.py -> requests-cache with SQLite backend - -## 0.1.104 - -- Protocol change: `supported_sync_modes` is now a required properties on AirbyteStream. [#15591](https://github.com/airbytehq/airbyte/pull/15591) - -## 0.1.103 - -- Low-code: added hash filter to jinja template - -## 0.1.102 - -- Low-code: Fix check for streams that do not define a stream slicer - -## 0.1.101 - -- Low-code: $options do not overwrite parameters that are already set - -## 0.1.100 - -- Low-code: Pass stream_slice to read_records when reading from CheckStream - -## 0.1.99 - -- Low-code: Fix default stream schema loader - -## 0.1.98 - -- Low-code: Expose WaitUntilTimeFromHeader strategy and WaitTimeFromHeader as component type - -## 0.1.97 - -- Revert 0.1.96 - -## 0.1.96 - -- Improve error for returning non-iterable from connectors parse_response - -## 0.1.95 - -- Low-code: Expose PageIncrement strategy as component type - -## 0.1.94 - -- Low-code: Stream schema loader has a default value and can be omitted - -## 0.1.93 - -- Low-code: Standardize slashes in url_base and path - -## 0.1.92 - -- Low-code: Properly propagate $options to array items -- Low-code: Log request and response when running check operation in debug mode - -## 0.1.91 - -- Low-code: Rename LimitPaginator to DefaultPaginator and move page_size field to PaginationStrategy - -## 0.1.90 - -- Fix error when TypeTransformer tries to warn about invalid transformations in arrays - -## 0.1.89 - -- Fix: properly emit state when a stream has empty slices, provided by an iterator - -## 0.1.88 - -- Bugfix: Evaluate `response.text` only in debug mode - -## 0.1.87 - -- During incremental syncs allow for streams to emit state messages in the per-stream format - -## 0.1.86 - -- TypeTransformer now converts simple types to array of simple types -- TypeTransformer make warning message more informative - -## 0.1.85 - -- Make TypeTransformer more robust to incorrect incoming records - -## 0.1.84 - -- Emit legacy format when state is unspecified for read override connectors - -## 0.1.83 - -- Fix per-stream to send legacy format for connectors that override read - -## 0.1.82 - -- Freeze dataclasses-jsonschema to 2.15.1 - -## 0.1.81 - -- Fix regression in `_checkpoint_state` arg - -## Unreleased - -- Update Airbyte Protocol model to support protocol_version - -## 0.1.80 - -- Add NoAuth to declarative registry and auth parse bug fix - -## 0.1.79 - -- Fix yaml schema parsing when running from docker container - -## 0.1.78 - -- Fix yaml config parsing when running from docker container - -## 0.1.77 - -- Add schema validation for declarative YAML connector configs - -## 0.1.76 - -- Bugfix: Correctly set parent slice stream for sub-resource streams - -## 0.1.75 - -- Improve `filter_secrets` skip empty secret - -## 0.1.74 - -- Replace JelloRecordExtractor with DpathRecordExtractor - -## 0.1.73 - -- Bugfix: Fix bug in DatetimeStreamSlicer's parsing method - -## 0.1.72 - -- Bugfix: Fix bug in DatetimeStreamSlicer's format method - -## 0.1.71 - -- Refactor declarative package to dataclasses -- Bugfix: Requester header always converted to string -- Bugfix: Reset paginator state between stream slices -- Bugfix: Record selector handles single records - -## 0.1.70 - -- Bugfix: DatetimeStreamSlicer cast interpolated result to string before converting to datetime -- Bugfix: Set stream slicer's request options in SimpleRetriever - -## 0.1.69 - -- AbstractSource emits a state message when reading incremental even if there were no stream slices to process. - -## 0.1.68 - -- Replace parse-time string interpolation with run-time interpolation in YAML-based sources - -## 0.1.67 - -- Add support declarative token authenticator. - -## 0.1.66 - -- Call init_uncaught_exception_handler from AirbyteEntrypoint.**init** and Destination.run_cmd -- Add the ability to remove & add records in YAML-based sources - -## 0.1.65 - -- Allow for detailed debug messages to be enabled using the --debug command. - -## 0.1.64 - -- Add support for configurable oauth request payload and declarative oauth authenticator. - -## 0.1.63 - -- Define `namespace` property on the `Stream` class inside `core.py`. - -## 0.1.62 - -Bugfix: Correctly obfuscate nested secrets and secrets specified inside oneOf blocks inside the connector's spec. - -## 0.1.61 - -- Remove legacy sentry code - -## 0.1.60 - -- Add `requests.exceptions.ChunkedEncodingError` to transient errors so it could be retried - -## 0.1.59 - -- Add `Stream.get_error_display_message()` to retrieve user-friendly messages from exceptions encountered while reading streams. -- Add default error error message retrieval logic for `HTTPStream`s following common API patterns. - -## 0.1.58 - -`TypeTransformer.default_convert` catch `TypeError` - -## 0.1.57 - -Update protocol models to support per-stream state: [#12829](https://github.com/airbytehq/airbyte/pull/12829). - -## 0.1.56 - -- Update protocol models to include `AirbyteTraceMessage` -- Emit an `AirbyteTraceMessage` on uncaught exceptions -- Add `AirbyteTracedException` - -## 0.1.55 - -Add support for reading the spec from a YAML file (`spec.yaml`) - -## 0.1.54 - -- Add ability to import `IncrementalMixin` from `airbyte_cdk.sources.streams`. -- Bumped minimum supported Python version to 3.9. - -## 0.1.53 - -Remove a false positive error logging during the send process. - -## 0.1.52 - -Fix BaseBackoffException constructor - -## 0.1.50 - -Improve logging for Error handling during send process. - -## 0.1.49 - -Add support for streams with explicit state attribute. - -## 0.1.48 - -Fix type annotations. - -## 0.1.47 - -Fix typing errors. - -## 0.1.45 - -Integrate Sentry for performance and errors tracking. - -## 0.1.44 - -Log http response status code and its content. - -## 0.1.43 - -Fix logging of unhandled exceptions: print stacktrace. - -## 0.1.42 - -Add base pydantic model for connector config and schemas. - -## 0.1.41 - -Fix build error - -## 0.1.40 - -Filter airbyte_secrets values at logger and other logging refactorings. - -## 0.1.39 - -Add `__init__.py` to mark the directory `airbyte_cdk/utils` as a package. - -## 0.1.38 - -Improve URL-creation in CDK. Changed to using `urllib.parse.urljoin()`. - -## 0.1.37 - -Fix `emitted_at` from `seconds * 1000` to correct milliseconds. - -## 0.1.36 - -Fix broken logger in streams: add logger inheritance for streams from `airbyte`. - -## 0.1.35 - -Fix false warnings on record transform. - -## 0.1.34 - -Fix logging inside source and streams - -## 0.1.33 - -Resolve $ref fields for discover json schema. - -## 0.1.32 - -- Added Sphinx docs `airbyte-cdk/python/reference_docs` module. -- Added module documents at `airbyte-cdk/python/sphinx-docs.md`. -- Added Read the Docs publishing configuration at `.readthedocs.yaml`. - -## 0.1.31 - -Transforming Python log levels to Airbyte protocol log levels - -## 0.1.30 - -Updated OAuth2Specification.rootObject type in airbyte_protocol to allow string or int - -## 0.1.29 - -Fix import logger error - -## 0.1.28 - -Added `check_config_against_spec` parameter to `Connector` abstract class -to allow skipping validating the input config against the spec for non-`check` calls - -## 0.1.27 - -Improving unit test for logger - -## 0.1.26 - -Use python standard logging instead of custom class - -## 0.1.25 - -Modified `OAuth2Specification` model, added new fields: `rootObject` and `oauthFlowOutputParameters` - -## 0.1.24 - -Added Transform class to use for mutating record value types so they adhere to jsonschema definition. - -## 0.1.23 - -Added the ability to use caching for efficient synchronization of nested streams. - -## 0.1.22 - -Allow passing custom headers to request in `OAuth2Authenticator.refresh_access_token()`: https://github.com/airbytehq/airbyte/pull/6219 - -## 0.1.21 - -Resolve nested schema references and move external references to single schema definitions. - -## 0.1.20 - -- Allow using `requests.auth.AuthBase` as authenticators instead of custom CDK authenticators. -- Implement Oauth2Authenticator, MultipleTokenAuthenticator and TokenAuthenticator authenticators. -- Add support for both legacy and requests native authenticator to HttpStream class. - -## 0.1.19 - -No longer prints full config files on validation error to prevent exposing secrets to log file: https://github.com/airbytehq/airbyte/pull/5879 - -## 0.1.18 - -Fix incremental stream not saved state when internal limit config set. - -## 0.1.17 - -Fix mismatching between number of records actually read and number of records in logs by 1: https://github.com/airbytehq/airbyte/pull/5767 - -## 0.1.16 - -Update generated AirbyteProtocol models to contain [Oauth changes](https://github.com/airbytehq/airbyte/pull/5776). - -## 0.1.15 - -Add \_limit and \_page_size as internal config parameters for SAT - -## 0.1.14 - -If the input config file does not comply with spec schema, raise an exception instead of `system.exit`. - -## 0.1.13 - -Fix defect with user defined backoff time retry attempts, number of retries logic fixed - -## 0.1.12 - -Add raise_on_http_errors, max_retries, retry_factor properties to be able to ignore http status errors and modify retry time in HTTP stream - -## 0.1.11 - -Add checking specified config againt spec for read, write, check and discover commands - -## 0.1.10 - -Add `MultipleTokenAuthenticator` class to allow cycling through a list of API tokens when making HTTP requests - -## 0.1.8 - -Allow to fetch primary key info from singer catalog - -## 0.1.7 - -Allow to use non-JSON payloads in request body for http source - -## 0.1.6 - -Add abstraction for creating destinations. - -Fix logging of the initial state. - -## 0.1.5 - -Allow specifying keyword arguments to be sent on a request made by an HTTP stream: https://github.com/airbytehq/airbyte/pull/4493 - -## 0.1.4 - -Allow to use Python 3.7.0: https://github.com/airbytehq/airbyte/pull/3566 - -## 0.1.2 - -Fix an issue that caused infinite pagination: https://github.com/airbytehq/airbyte/pull/3366 - -## 0.1.1 - -Initial Release diff --git a/airbyte-cdk/python/LICENSE.txt b/airbyte-cdk/python/LICENSE.txt deleted file mode 100644 index 06a0065fd011..000000000000 --- a/airbyte-cdk/python/LICENSE.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2020 Airbyte - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/airbyte-cdk/python/README.md b/airbyte-cdk/python/README.md index 4df178963b3c..b35713584f58 100644 --- a/airbyte-cdk/python/README.md +++ b/airbyte-cdk/python/README.md @@ -1,222 +1,3 @@ -# Airbyte Python CDK and Low-Code CDK +# The Airbyte Python CDK has Moved! -Airbyte Python CDK is a framework for building Airbyte API Source Connectors. It provides a set of -classes and helpers that make it easy to build a connector against an HTTP API (REST, GraphQL, etc), -or a generic Python source connector. - -## Usage - -If you're looking to build a connector, we highly recommend that you -[start with the Connector Builder](https://docs.airbyte.com/connector-development/connector-builder-ui/overview). -It should be enough for 90% connectors out there. For more flexible and complex connectors, use the -[low-code CDK and `SourceDeclarativeManifest`](https://docs.airbyte.com/connector-development/config-based/low-code-cdk-overview). - -If that doesn't work, then consider building on top of the -[lower-level Python CDK itself](https://docs.airbyte.com/connector-development/cdk-python/). - -### Quick Start - -To get started on a Python CDK based connector or a low-code connector, you can generate a connector -project from a template: - -```bash -# from the repo root -cd airbyte-integrations/connector-templates/generator -./generate.sh -``` - -### Example Connectors - -**HTTP Connectors**: - -- [Stripe](https://github.com/airbytehq/airbyte/blob/master/airbyte-integrations/connectors/source-stripe/) -- [Salesforce](https://github.com/airbytehq/airbyte/blob/master/airbyte-integrations/connectors/source-salesforce/) - -**Python connectors using the bare-bones `Source` abstraction**: - -- [Google Sheets](https://github.com/airbytehq/airbyte/blob/master/airbyte-integrations/connectors/source-google-sheets/google_sheets_source/google_sheets_source.py) - -This will generate a project with a type and a name of your choice and put it in -`airbyte-integrations/connectors`. Open the directory with your connector in an editor and follow -the `TODO` items. - -## Python CDK Overview - -Airbyte CDK code is within `airbyte_cdk` directory. Here's a high level overview of what's inside: - -- `connector_builder`. Internal wrapper that helps the Connector Builder platform run a declarative - manifest (low-code connector). You should not use this code directly. If you need to run a - `SourceDeclarativeManifest`, take a look at - [`source-declarative-manifest`](https://github.com/airbytehq/airbyte/tree/master/airbyte-integrations/connectors/source-declarative-manifest) - connector implementation instead. -- `destinations`. Basic Destination connector support! If you're building a Destination connector in - Python, try that. Some of our vector DB destinations like `destination-pinecone` are using that - code. -- `models` expose `airbyte_protocol.models` as a part of `airbyte_cdk` package. -- `sources/concurrent_source` is the Concurrent CDK implementation. It supports reading data from - streams concurrently per slice / partition, useful for connectors with high throughput and high - number of records. -- `sources/declarative` is the low-code CDK. It works on top of Airbyte Python CDK, but provides a - declarative manifest language to define streams, operations, etc. This makes it easier to build - connectors without writing Python code. -- `sources/file_based` is the CDK for file-based sources. Examples include S3, Azure, GCS, etc. - -## Contributing - -Thank you for being interested in contributing to Airbyte Python CDK! Here are some guidelines to -get you started: - -- We adhere to the [code of conduct](/CODE_OF_CONDUCT.md). -- You can contribute by reporting bugs, posting github discussions, opening issues, improving - [documentation](/docs/), and submitting pull requests with bugfixes and new features alike. -- If you're changing the code, please add unit tests for your change. -- When submitting issues or PRs, please add a small reproduction project. Using the changes in your - connector and providing that connector code as an example (or a satellite PR) helps! - -### First time setup - -Install the project dependencies and development tools: - -```bash -poetry install --all-extras -``` - -Installing all extras is required to run the full suite of unit tests. - -#### Running tests locally - -- Iterate on the CDK code locally -- Run tests via `poetry run poe unit-test-with-cov`, or `python -m pytest -s unit_tests` if you want - to pass pytest options. -- Run `poetry run poe check-local` to lint all code, type-check modified code, and run unit tests - with coverage in one command. - -To see all available scripts, run `poetry run poe`. - -##### Autogenerated files - -Low-code CDK models are generated from `sources/declarative/declarative_component_schema.yaml`. If -the iteration you are working on includes changes to the models or the connector generator, you -might want to regenerate them. In order to do that, you can run: - -```bash -poetry run poe build -``` - -This will generate the code generator docker image and the component manifest files based on the -schemas and templates. - -#### Testing - -All tests are located in the `unit_tests` directory. Run `poetry run poe unit-test-with-cov` to run -them. This also presents a test coverage report. For faster iteration with no coverage report and -more options, `python -m pytest -s unit_tests` is a good place to start. - -#### Building and testing a connector with your local CDK - -When developing a new feature in the CDK, you may find it helpful to run a connector that uses that -new feature. You can test this in one of two ways: - -- Running a connector locally -- Building and running a source via Docker - -##### Installing your local CDK into a local Python connector - -Open the connector's `pyproject.toml` file and replace the line with `airbyte_cdk` with the -following: - -```toml -airbyte_cdk = { path = "../../../airbyte-cdk/python/airbyte_cdk", develop = true } -``` - -Then, running `poetry update` should reinstall `airbyte_cdk` from your local working directory. - -##### Building a Python connector in Docker with your local CDK installed - -_Pre-requisite: Install the -[`airbyte-ci` CLI](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md)_ - -You can build your connector image with the local CDK using - -```bash -# from the airbytehq/airbyte base directory -airbyte-ci connectors --use-local-cdk --name= build -``` - -Note that the local CDK is injected at build time, so if you make changes, you will have to run the -build command again to see them reflected. - -##### Running Connector Acceptance Tests for a single connector in Docker with your local CDK installed - -_Pre-requisite: Install the -[`airbyte-ci` CLI](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md)_ - -To run acceptance tests for a single connectors using the local CDK, from the connector directory, -run - -```bash -airbyte-ci connectors --use-local-cdk --name= test -``` - -#### When you don't have access to the API - -There may be a time when you do not have access to the API (either because you don't have the -credentials, network access, etc...) You will probably still want to do end-to-end testing at least -once. In order to do so, you can emulate the server you would be reaching using a server stubbing -tool. - -For example, using [mockserver](https://www.mock-server.com/), you can set up an expectation file -like this: - -```json -{ - "httpRequest": { - "method": "GET", - "path": "/data" - }, - "httpResponse": { - "body": "{\"data\": [{\"record_key\": 1}, {\"record_key\": 2}]}" - } -} -``` - -Assuming this file has been created at `secrets/mock_server_config/expectations.json`, running the -following command will allow to match any requests on path `/data` to return the response defined in -the expectation file: - -```bash -docker run -d --rm -v $(pwd)/secrets/mock_server_config:/config -p 8113:8113 --env MOCKSERVER_LOG_LEVEL=TRACE --env MOCKSERVER_SERVER_PORT=8113 --env MOCKSERVER_WATCH_INITIALIZATION_JSON=true --env MOCKSERVER_PERSISTED_EXPECTATIONS_PATH=/config/expectations.json --env MOCKSERVER_INITIALIZATION_JSON_PATH=/config/expectations.json mockserver/mockserver:5.15.0 -``` - -HTTP requests to `localhost:8113/data` should now return the body defined in the expectations file. -To test this, the implementer either has to change the code which defines the base URL for Python -source or update the `url_base` from low-code. With the Connector Builder running in docker, you -will have to use domain `host.docker.internal` instead of `localhost` as the requests are executed -within docker. - -#### Publishing a new version to PyPi - -Python CDK has a -[GitHub workflow](https://github.com/airbytehq/airbyte/actions/workflows/publish-cdk-command-manually.yml) -that manages the CDK changelog, making a new release for `airbyte_cdk`, publishing it to PyPI, and -then making a commit to update (and subsequently auto-release) -[`source-declarative-m anifest`](https://github.com/airbytehq/airbyte/tree/master/airbyte-integrations/connectors/source-declarative-manifest) -and Connector Builder (in the platform repository). - -> [!Note]: The workflow will handle the `CHANGELOG.md` entry for you. You should not add changelog -> lines in your PRs to the CDK itself. - -> [!Warning]: The workflow bumps version on it's own, please don't change the CDK version in -> `pyproject.toml` manually. - -1. You only trigger the release workflow once all the PRs that you want to be included are already - merged into the `master` branch. -2. The - [`Publish CDK Manually`](https://github.com/airbytehq/airbyte/actions/workflows/publish-cdk-command-manually.yml) - workflow from master using `release-type=major|manor|patch` and setting the changelog message. -3. When the workflow runs, it will commit a new version directly to master branch. -4. The workflow will bump the version of `source-declarative-manifest` according to the - `release-type` of the CDK, then commit these changes back to master. The commit to master will - kick off a publish of the new version of `source-declarative-manifest`. -5. The workflow will also add a pull request to `airbyte-platform-internal` repo to bump the - dependency in Connector Builder. +The CDK's new home is at: https://github.com/airbytehq/airbyte-python-cdk diff --git a/airbyte-cdk/python/airbyte_cdk/__init__.py b/airbyte-cdk/python/airbyte_cdk/__init__.py deleted file mode 100644 index 312983853b1d..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/__init__.py +++ /dev/null @@ -1,254 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# - -from importlib import metadata - -from .destinations import Destination -from .models import AirbyteConnectionStatus, AirbyteMessage, ConfiguredAirbyteCatalog, Status, Type, FailureType, AirbyteStream, AdvancedAuth, DestinationSyncMode, ConnectorSpecification, OAuthConfigSpecification, OrchestratorType, ConfiguredAirbyteStream, SyncMode, AirbyteLogMessage, Level, AirbyteRecordMessage - -from .sources import Source -from .config_observation import create_connector_config_control_message, emit_configuration_as_airbyte_control_message -from .connector import BaseConnector, Connector - -from .entrypoint import launch, AirbyteEntrypoint - -from .logger import AirbyteLogFormatter, init_logger -from .sources import AbstractSource -from .sources.concurrent_source.concurrent_source import ConcurrentSource -from .sources.concurrent_source.concurrent_source_adapter import ConcurrentSourceAdapter -from .sources.config import BaseConfig -from .sources.types import Config, Record, StreamSlice -from .sources.connector_state_manager import ConnectorStateManager -from .sources.declarative.auth import DeclarativeOauth2Authenticator -from .sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator -from .sources.declarative.auth.declarative_authenticator import NoAuth -from .sources.declarative.auth.oauth import DeclarativeSingleUseRefreshTokenOauth2Authenticator -from .sources.declarative.auth.token import BasicHttpAuthenticator, BearerAuthenticator, ApiKeyAuthenticator -from .sources.declarative.datetime.min_max_datetime import MinMaxDatetime -from .sources.declarative.declarative_stream import DeclarativeStream -from .sources.declarative.decoders import Decoder, JsonDecoder -from .sources.declarative.exceptions import ReadException -from .sources.declarative.extractors import DpathExtractor, RecordSelector -from .sources.declarative.extractors.record_extractor import RecordExtractor -from .sources.declarative.extractors.record_filter import RecordFilter -from .sources.declarative.incremental import DatetimeBasedCursor -from .sources.declarative.interpolation import InterpolatedString, InterpolatedBoolean -from .sources.declarative.manifest_declarative_source import ManifestDeclarativeSource -from .sources.declarative.migrations.legacy_to_per_partition_state_migration import LegacyToPerPartitionStateMigration - -from .sources.declarative.partition_routers import CartesianProductStreamSlicer, SinglePartitionRouter, SubstreamPartitionRouter -from .sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig -from .sources.declarative.requesters import Requester, HttpRequester - -from .sources.declarative.requesters.error_handlers import BackoffStrategy -from .sources.declarative.requesters.paginators import DefaultPaginator, PaginationStrategy -from .sources.declarative.requesters.paginators.strategies import OffsetIncrement, CursorPaginationStrategy, PageIncrement, StopConditionPaginationStrategyDecorator - -from .sources.declarative.requesters.request_option import RequestOption, RequestOptionType - -from .sources.declarative.requesters.request_options.default_request_options_provider import DefaultRequestOptionsProvider -from .sources.declarative.requesters.request_options.interpolated_request_input_provider import InterpolatedRequestInputProvider -from .sources.declarative.requesters.requester import HttpMethod -from .sources.declarative.retrievers import SimpleRetriever -from .sources.declarative.schema import JsonFileSchemaLoader -from .sources.declarative.transformations.add_fields import AddFields, AddedFieldDefinition -from .sources.declarative.transformations.transformation import RecordTransformation -from .sources.declarative.types import FieldPointer -from .sources.declarative.yaml_declarative_source import YamlDeclarativeSource -from .sources.message import InMemoryMessageRepository, MessageRepository -from .sources.source import TState -from .sources.streams.availability_strategy import AvailabilityStrategy -from .sources.streams.call_rate import AbstractAPIBudget, HttpAPIBudget, HttpRequestMatcher, MovingWindowCallRatePolicy, Rate, CachedLimiterSession, LimiterSession -from .sources.streams.checkpoint import Cursor as LegacyCursor -from .sources.streams.checkpoint import ResumableFullRefreshCursor -from .sources.streams.concurrent.adapters import StreamFacade -from .sources.streams.concurrent.cursor import ConcurrentCursor, CursorField, FinalStateCursor -from .sources.streams.concurrent.cursor import Cursor -from .sources.streams.concurrent.state_converters.datetime_stream_state_converter import EpochValueConcurrentStreamStateConverter, IsoMillisConcurrentStreamStateConverter -from .sources.streams.core import Stream, IncrementalMixin, package_name_from_class -from .sources.streams.http import HttpStream, HttpSubStream -from .sources.streams.http.availability_strategy import HttpAvailabilityStrategy -from .sources.streams.http.exceptions import BaseBackoffException, DefaultBackoffException, UserDefinedBackoffException -from .sources.streams.http.rate_limiting import default_backoff_handler -from .sources.streams.http.requests_native_auth import Oauth2Authenticator, TokenAuthenticator, SingleUseRefreshTokenOauth2Authenticator -from .sources.streams.http.requests_native_auth.abstract_token import AbstractHeaderAuthenticator -from .sources.utils import casing -from .sources.utils.schema_helpers import InternalConfig, ResourceSchemaLoader, check_config_against_spec_or_exit, split_config, expand_refs -from .sources.utils.transform import TransformConfig, TypeTransformer -from .utils import AirbyteTracedException, is_cloud_environment -from .utils.constants import ENV_REQUEST_CACHE_PATH -from .utils.event_timing import create_timer -from .utils.oneof_option_config import OneOfOptionConfig -from .utils.spec_schema_transformations import resolve_refs -from .utils.stream_status_utils import as_airbyte_message - - -__all__ = [ - # Availability strategy - "AvailabilityStrategy", - "HttpAvailabilityStrategy", - - # Checkpoint - "LegacyCursor", - "ResumableFullRefreshCursor", - - # Concurrent - "ConcurrentCursor", - "ConcurrentSource", - "ConcurrentSourceAdapter", - "Cursor", - "CursorField", - "DEFAULT_CONCURRENCY", - "EpochValueConcurrentStreamStateConverter", - "FinalStateCursor", - "IsoMillisConcurrentStreamStateConverter", - "StreamFacade", - - # Config observation - "create_connector_config_control_message", - "emit_configuration_as_airbyte_control_message", - - # Connector - "AbstractSource", - "BaseConfig", - "BaseConnector", - "Connector", - "Destination", - "Source", - "TState", - - # Declarative - "AddFields", - "AddedFieldDefinition", - "ApiKeyAuthenticator", - "BackoffStrategy", - "BasicHttpAuthenticator", - "BearerAuthenticator", - "CartesianProductStreamSlicer", - "CursorPaginationStrategy", - "DatetimeBasedCursor", - "DeclarativeAuthenticator", - "DeclarativeOauth2Authenticator", - "DeclarativeSingleUseRefreshTokenOauth2Authenticator", - "DeclarativeStream", - "Decoder", - "DefaultPaginator", - "DefaultRequestOptionsProvider", - "DpathExtractor", - "FieldPointer", - "HttpMethod", - "HttpRequester", - "InterpolatedBoolean", - "InterpolatedRequestInputProvider", - "InterpolatedString", - "JsonDecoder", - "JsonFileSchemaLoader", - "LegacyToPerPartitionStateMigration", - "ManifestDeclarativeSource", - "MinMaxDatetime", - "NoAuth", - "OffsetIncrement", - "PageIncrement", - "PaginationStrategy", - "ParentStreamConfig", - "ReadException", - "RecordExtractor", - "RecordFilter", - "RecordSelector", - "RecordTransformation", - "RequestOption", - "RequestOptionType", - "Requester", - "ResponseStatus", - "SimpleRetriever", - "SinglePartitionRouter", - "StopConditionPaginationStrategyDecorator", - "StreamSlice", - "SubstreamPartitionRouter", - "YamlDeclarativeSource", - - # Entrypoint - "launch", - "AirbyteEntrypoint", - - # HTTP - "AbstractAPIBudget", - "AbstractHeaderAuthenticator", - "BaseBackoffException", - "CachedLimiterSession", - "DefaultBackoffException", - "default_backoff_handler", - "HttpAPIBudget", - "HttpAuthenticator", - "HttpRequestMatcher", - "HttpStream", - "HttpSubStream", - "LimiterSession", - "MovingWindowCallRatePolicy", - "MultipleTokenAuthenticator", - "Oauth2Authenticator", - "Rate", - "SingleUseRefreshTokenOauth2Authenticator", - "TokenAuthenticator", - "UserDefinedBackoffException", - - # Logger - "AirbyteLogFormatter", - "init_logger", - - # Protocol classes - "AirbyteStream", - "AirbyteConnectionStatus", - "AirbyteMessage", - "ConfiguredAirbyteCatalog", - "Status", - "Type", - "OrchestratorType", - "ConfiguredAirbyteStream", - "DestinationSyncMode", - "SyncMode", - "FailureType", - "AdvancedAuth", - "AirbyteLogMessage", - "OAuthConfigSpecification", - "ConnectorSpecification", - "Level", - "AirbyteRecordMessage", - - # Repository - "InMemoryMessageRepository", - "MessageRepository", - - # State management - "ConnectorStateManager", - - # Stream - "IncrementalMixin", - "Stream", - "StreamData", - "package_name_from_class", - - # Utils - "AirbyteTracedException", - "is_cloud_environment", - "casing", - "InternalConfig", - "ResourceSchemaLoader", - "check_config_against_spec_or_exit", - "split_config", - "TransformConfig", - "TypeTransformer", - "ENV_REQUEST_CACHE_PATH", - "create_timer", - "OneOfOptionConfig", - "resolve_refs", - "as_airbyte_message", - - # Types - "Config", - "Record", - "Source", - "StreamSlice", -] -__version__ = metadata.version("airbyte_cdk") diff --git a/airbyte-cdk/python/airbyte_cdk/config_observation.py b/airbyte-cdk/python/airbyte_cdk/config_observation.py deleted file mode 100644 index 94a3d64a511b..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/config_observation.py +++ /dev/null @@ -1,96 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from __future__ import ( # Used to evaluate type hints at runtime, a NameError: name 'ConfigObserver' is not defined is thrown otherwise - annotations, -) - -import time -from copy import copy -from typing import Any, List, MutableMapping - -from airbyte_cdk.models import ( - AirbyteControlConnectorConfigMessage, - AirbyteControlMessage, - AirbyteMessage, - AirbyteMessageSerializer, - OrchestratorType, - Type, -) -from orjson import orjson - - -class ObservedDict(dict): # type: ignore # disallow_any_generics is set to True, and dict is equivalent to dict[Any] - def __init__( - self, non_observed_mapping: MutableMapping[Any, Any], observer: ConfigObserver, update_on_unchanged_value: bool = True - ) -> None: - non_observed_mapping = copy(non_observed_mapping) - self.observer = observer - self.update_on_unchanged_value = update_on_unchanged_value - for item, value in non_observed_mapping.items(): - # Observe nested dicts - if isinstance(value, MutableMapping): - non_observed_mapping[item] = ObservedDict(value, observer) - - # Observe nested list of dicts - if isinstance(value, List): - for i, sub_value in enumerate(value): - if isinstance(sub_value, MutableMapping): - value[i] = ObservedDict(sub_value, observer) - super().__init__(non_observed_mapping) - - def __setitem__(self, item: Any, value: Any) -> None: - """Override dict.__setitem__ by: - 1. Observing the new value if it is a dict - 2. Call observer update if the new value is different from the previous one - """ - previous_value = self.get(item) - if isinstance(value, MutableMapping): - value = ObservedDict(value, self.observer) - if isinstance(value, List): - for i, sub_value in enumerate(value): - if isinstance(sub_value, MutableMapping): - value[i] = ObservedDict(sub_value, self.observer) - super(ObservedDict, self).__setitem__(item, value) - if self.update_on_unchanged_value or value != previous_value: - self.observer.update() - - -class ConfigObserver: - """This class is made to track mutations on ObservedDict config. - When update is called a CONNECTOR_CONFIG control message is emitted on stdout. - """ - - def set_config(self, config: ObservedDict) -> None: - self.config = config - - def update(self) -> None: - emit_configuration_as_airbyte_control_message(self.config) - - -def observe_connector_config(non_observed_connector_config: MutableMapping[str, Any]) -> ObservedDict: - if isinstance(non_observed_connector_config, ObservedDict): - raise ValueError("This connector configuration is already observed") - connector_config_observer = ConfigObserver() - observed_connector_config = ObservedDict(non_observed_connector_config, connector_config_observer) - connector_config_observer.set_config(observed_connector_config) - return observed_connector_config - - -def emit_configuration_as_airbyte_control_message(config: MutableMapping[str, Any]) -> None: - """ - WARNING: deprecated - emit_configuration_as_airbyte_control_message is being deprecated in favor of the MessageRepository mechanism. - See the airbyte_cdk.sources.message package - """ - airbyte_message = create_connector_config_control_message(config) - print(orjson.dumps(AirbyteMessageSerializer.dump(airbyte_message)).decode()) - - -def create_connector_config_control_message(config: MutableMapping[str, Any]) -> AirbyteMessage: - control_message = AirbyteControlMessage( - type=OrchestratorType.CONNECTOR_CONFIG, - emitted_at=time.time() * 1000, - connectorConfig=AirbyteControlConnectorConfigMessage(config=config), - ) - return AirbyteMessage(type=Type.CONTROL, control=control_message) diff --git a/airbyte-cdk/python/airbyte_cdk/connector.py b/airbyte-cdk/python/airbyte_cdk/connector.py deleted file mode 100644 index 658a0b167077..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/connector.py +++ /dev/null @@ -1,112 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import json -import logging -import os -import pkgutil -from abc import ABC, abstractmethod -from typing import Any, Generic, Mapping, Optional, Protocol, TypeVar - -import yaml -from airbyte_cdk.models import AirbyteConnectionStatus, ConnectorSpecification, ConnectorSpecificationSerializer - - -def load_optional_package_file(package: str, filename: str) -> Optional[bytes]: - """Gets a resource from a package, returning None if it does not exist""" - try: - return pkgutil.get_data(package, filename) - except FileNotFoundError: - return None - - -TConfig = TypeVar("TConfig", bound=Mapping[str, Any]) - - -class BaseConnector(ABC, Generic[TConfig]): - # configure whether the `check_config_against_spec_or_exit()` needs to be called - check_config_against_spec: bool = True - - @abstractmethod - def configure(self, config: Mapping[str, Any], temp_dir: str) -> TConfig: - """ - Persist config in temporary directory to run the Source job - """ - - @staticmethod - def read_config(config_path: str) -> Mapping[str, Any]: - config = BaseConnector._read_json_file(config_path) - if isinstance(config, Mapping): - return config - else: - raise ValueError( - f"The content of {config_path} is not an object and therefore is not a valid config. Please ensure the file represent a config." - ) - - @staticmethod - def _read_json_file(file_path: str) -> Any: - with open(file_path, "r") as file: - contents = file.read() - - try: - return json.loads(contents) - except json.JSONDecodeError as error: - raise ValueError(f"Could not read json file {file_path}: {error}. Please ensure that it is a valid JSON.") - - @staticmethod - def write_config(config: TConfig, config_path: str) -> None: - with open(config_path, "w") as fh: - fh.write(json.dumps(config)) - - def spec(self, logger: logging.Logger) -> ConnectorSpecification: - """ - Returns the spec for this integration. The spec is a JSON-Schema object describing the required configurations (e.g: username and password) - required to run this integration. By default, this will be loaded from a "spec.yaml" or a "spec.json" in the package root. - """ - - package = self.__class__.__module__.split(".")[0] - - yaml_spec = load_optional_package_file(package, "spec.yaml") - json_spec = load_optional_package_file(package, "spec.json") - - if yaml_spec and json_spec: - raise RuntimeError("Found multiple spec files in the package. Only one of spec.yaml or spec.json should be provided.") - - if yaml_spec: - spec_obj = yaml.load(yaml_spec, Loader=yaml.SafeLoader) - elif json_spec: - try: - spec_obj = json.loads(json_spec) - except json.JSONDecodeError as error: - raise ValueError(f"Could not read json spec file: {error}. Please ensure that it is a valid JSON.") - else: - raise FileNotFoundError("Unable to find spec.yaml or spec.json in the package.") - - return ConnectorSpecificationSerializer.load(spec_obj) - - @abstractmethod - def check(self, logger: logging.Logger, config: TConfig) -> AirbyteConnectionStatus: - """ - Tests if the input configuration can be used to successfully connect to the integration e.g: if a provided Stripe API token can be used to connect - to the Stripe API. - """ - - -class _WriteConfigProtocol(Protocol): - @staticmethod - def write_config(config: Mapping[str, Any], config_path: str) -> None: - ... - - -class DefaultConnectorMixin: - # can be overridden to change an input config - def configure(self: _WriteConfigProtocol, config: Mapping[str, Any], temp_dir: str) -> Mapping[str, Any]: - config_path = os.path.join(temp_dir, "config.json") - self.write_config(config, config_path) - return config - - -class Connector(DefaultConnectorMixin, BaseConnector[Mapping[str, Any]], ABC): - ... diff --git a/airbyte-cdk/python/airbyte_cdk/connector_builder/README.md b/airbyte-cdk/python/airbyte_cdk/connector_builder/README.md deleted file mode 100644 index cc2cf7064e29..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/connector_builder/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# Connector Builder Backend - -This is the backend for requests from the -[Connector Builder](https://docs.airbyte.com/connector-development/connector-builder-ui/overview/). - -## Local development - -### Locally running the Connector Builder backend - -```bash -python main.py read --config path/to/config --catalog path/to/catalog -``` - -Note: - -- Requires the keys `__injected_declarative_manifest` and `__command` in its config, where - `__injected_declarative_manifest` is a JSON manifest and `__command` is one of the commands - handled by the ConnectorBuilderHandler (`stream_read` or `resolve_manifest`), i.e. - -```json -{ - "config": , - "__injected_declarative_manifest": {...}, - "__command": <"resolve_manifest" | "test_read"> -} -``` - -\*See -[ConnectionSpecification](https://docs.airbyte.com/understanding-airbyte/airbyte-protocol/#actor-specification) -for details on the `"config"` key if needed. - -- When the `__command` is `resolve_manifest`, the argument to `catalog` should be an empty string. -- The config can optionally contain an object under the `__test_read_config` key which can define - custom test read limits with `max_records`, `max_slices`, and `max_pages_per_slice` properties. - All custom limits are optional; a default will be used for any limit that is not provided. - -### Locally running the docker image - -#### Build - -First, make sure you build the latest Docker image: - -```bash -docker build -t airbyte/source-declarative-manifest:dev . -``` - -#### Run - -Then run any of the connector commands as follows: - -```bash -docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-declarative-manifest:dev read --config /secrets/config.json -``` diff --git a/airbyte-cdk/python/airbyte_cdk/connector_builder/connector_builder_handler.py b/airbyte-cdk/python/airbyte_cdk/connector_builder/connector_builder_handler.py deleted file mode 100644 index b3cfd9a0503b..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/connector_builder/connector_builder_handler.py +++ /dev/null @@ -1,96 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import dataclasses -from datetime import datetime -from typing import Any, List, Mapping - -from airbyte_cdk.connector_builder.message_grouper import MessageGrouper -from airbyte_cdk.models import AirbyteMessage, AirbyteRecordMessage, AirbyteStateMessage, ConfiguredAirbyteCatalog -from airbyte_cdk.models import Type -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.declarative.declarative_source import DeclarativeSource -from airbyte_cdk.sources.declarative.manifest_declarative_source import ManifestDeclarativeSource -from airbyte_cdk.sources.declarative.parsers.model_to_component_factory import ModelToComponentFactory -from airbyte_cdk.utils.airbyte_secrets_utils import filter_secrets -from airbyte_cdk.utils.traced_exception import AirbyteTracedException - -DEFAULT_MAXIMUM_NUMBER_OF_PAGES_PER_SLICE = 5 -DEFAULT_MAXIMUM_NUMBER_OF_SLICES = 5 -DEFAULT_MAXIMUM_RECORDS = 100 - -MAX_PAGES_PER_SLICE_KEY = "max_pages_per_slice" -MAX_SLICES_KEY = "max_slices" -MAX_RECORDS_KEY = "max_records" - - -@dataclasses.dataclass -class TestReadLimits: - max_records: int = dataclasses.field(default=DEFAULT_MAXIMUM_RECORDS) - max_pages_per_slice: int = dataclasses.field(default=DEFAULT_MAXIMUM_NUMBER_OF_PAGES_PER_SLICE) - max_slices: int = dataclasses.field(default=DEFAULT_MAXIMUM_NUMBER_OF_SLICES) - - -def get_limits(config: Mapping[str, Any]) -> TestReadLimits: - command_config = config.get("__test_read_config", {}) - max_pages_per_slice = command_config.get(MAX_PAGES_PER_SLICE_KEY) or DEFAULT_MAXIMUM_NUMBER_OF_PAGES_PER_SLICE - max_slices = command_config.get(MAX_SLICES_KEY) or DEFAULT_MAXIMUM_NUMBER_OF_SLICES - max_records = command_config.get(MAX_RECORDS_KEY) or DEFAULT_MAXIMUM_RECORDS - return TestReadLimits(max_records, max_pages_per_slice, max_slices) - - -def create_source(config: Mapping[str, Any], limits: TestReadLimits) -> ManifestDeclarativeSource: - manifest = config["__injected_declarative_manifest"] - return ManifestDeclarativeSource( - emit_connector_builder_messages=True, - source_config=manifest, - component_factory=ModelToComponentFactory( - emit_connector_builder_messages=True, - limit_pages_fetched_per_slice=limits.max_pages_per_slice, - limit_slices_fetched=limits.max_slices, - disable_retries=True, - disable_cache=True, - ), - ) - - -def read_stream( - source: DeclarativeSource, - config: Mapping[str, Any], - configured_catalog: ConfiguredAirbyteCatalog, - state: List[AirbyteStateMessage], - limits: TestReadLimits, -) -> AirbyteMessage: - try: - handler = MessageGrouper(limits.max_pages_per_slice, limits.max_slices, limits.max_records) - stream_name = configured_catalog.streams[0].stream.name # The connector builder only supports a single stream - stream_read = handler.get_message_groups(source, config, configured_catalog, state, limits.max_records) - return AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage(data=dataclasses.asdict(stream_read), stream=stream_name, emitted_at=_emitted_at()), - ) - except Exception as exc: - error = AirbyteTracedException.from_exception( - exc, message=filter_secrets(f"Error reading stream with config={config} and catalog={configured_catalog}: {str(exc)}") - ) - return error.as_airbyte_message() - - -def resolve_manifest(source: ManifestDeclarativeSource) -> AirbyteMessage: - try: - return AirbyteMessage( - type=Type.RECORD, - record=AirbyteRecordMessage( - data={"manifest": source.resolved_manifest}, - emitted_at=_emitted_at(), - stream="resolve_manifest", - ), - ) - except Exception as exc: - error = AirbyteTracedException.from_exception(exc, message=f"Error resolving manifest: {str(exc)}") - return error.as_airbyte_message() - - -def _emitted_at() -> int: - return int(datetime.now().timestamp()) * 1000 diff --git a/airbyte-cdk/python/airbyte_cdk/connector_builder/main.py b/airbyte-cdk/python/airbyte_cdk/connector_builder/main.py deleted file mode 100644 index 54e0b1e0be41..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/connector_builder/main.py +++ /dev/null @@ -1,86 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import sys -from typing import Any, List, Mapping, Optional, Tuple - -from airbyte_cdk.connector import BaseConnector -from airbyte_cdk.connector_builder.connector_builder_handler import TestReadLimits, create_source, get_limits, read_stream, resolve_manifest -from airbyte_cdk.entrypoint import AirbyteEntrypoint -from airbyte_cdk.models import ( - AirbyteMessage, - AirbyteMessageSerializer, - AirbyteStateMessage, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteCatalogSerializer, -) -from airbyte_cdk.sources.declarative.manifest_declarative_source import ManifestDeclarativeSource -from airbyte_cdk.sources.source import Source -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from orjson import orjson - - -def get_config_and_catalog_from_args(args: List[str]) -> Tuple[str, Mapping[str, Any], Optional[ConfiguredAirbyteCatalog], Any]: - # TODO: Add functionality for the `debug` logger. - # Currently, no one `debug` level log will be displayed during `read` a stream for a connector created through `connector-builder`. - parsed_args = AirbyteEntrypoint.parse_args(args) - config_path, catalog_path, state_path = parsed_args.config, parsed_args.catalog, parsed_args.state - if parsed_args.command != "read": - raise ValueError("Only read commands are allowed for Connector Builder requests.") - - config = BaseConnector.read_config(config_path) - - if "__command" not in config: - raise ValueError( - f"Invalid config: `__command` should be provided at the root of the config but config only has keys {list(config.keys())}" - ) - - command = config["__command"] - if command == "test_read": - catalog = ConfiguredAirbyteCatalogSerializer.load(BaseConnector.read_config(catalog_path)) - state = Source.read_state(state_path) - else: - catalog = None - state = [] - - if "__injected_declarative_manifest" not in config: - raise ValueError( - f"Invalid config: `__injected_declarative_manifest` should be provided at the root of the config but config only has keys {list(config.keys())}" - ) - - return command, config, catalog, state - - -def handle_connector_builder_request( - source: ManifestDeclarativeSource, - command: str, - config: Mapping[str, Any], - catalog: Optional[ConfiguredAirbyteCatalog], - state: List[AirbyteStateMessage], - limits: TestReadLimits, -) -> AirbyteMessage: - if command == "resolve_manifest": - return resolve_manifest(source) - elif command == "test_read": - assert catalog is not None, "`test_read` requires a valid `ConfiguredAirbyteCatalog`, got None." - return read_stream(source, config, catalog, state, limits) - else: - raise ValueError(f"Unrecognized command {command}.") - - -def handle_request(args: List[str]) -> str: - command, config, catalog, state = get_config_and_catalog_from_args(args) - limits = get_limits(config) - source = create_source(config, limits) - return orjson.dumps(AirbyteMessageSerializer.dump(handle_connector_builder_request(source, command, config, catalog, state, limits))).decode() # type: ignore[no-any-return] # Serializer.dump() always returns AirbyteMessage - - -if __name__ == "__main__": - try: - print(handle_request(sys.argv[1:])) - except Exception as exc: - error = AirbyteTracedException.from_exception(exc, message=f"Error handling request: {str(exc)}") - m = error.as_airbyte_message() - print(orjson.dumps(AirbyteMessageSerializer.dump(m)).decode()) diff --git a/airbyte-cdk/python/airbyte_cdk/connector_builder/message_grouper.py b/airbyte-cdk/python/airbyte_cdk/connector_builder/message_grouper.py deleted file mode 100644 index e21ffd61abd8..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/connector_builder/message_grouper.py +++ /dev/null @@ -1,378 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import logging -from copy import deepcopy -from json import JSONDecodeError -from typing import Any, Dict, Iterable, Iterator, List, Mapping, Optional, Union - -from airbyte_cdk.connector_builder.models import ( - AuxiliaryRequest, - HttpRequest, - HttpResponse, - LogMessage, - StreamRead, - StreamReadPages, - StreamReadSlices, -) -from airbyte_cdk.entrypoint import AirbyteEntrypoint -from airbyte_cdk.models import ( - AirbyteControlMessage, - AirbyteLogMessage, - AirbyteMessage, - AirbyteStateMessage, - AirbyteTraceMessage, - ConfiguredAirbyteCatalog, - OrchestratorType, - TraceType, -) -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.declarative.declarative_source import DeclarativeSource -from airbyte_cdk.sources.utils.slice_logger import SliceLogger -from airbyte_cdk.sources.utils.types import JsonType -from airbyte_cdk.utils import AirbyteTracedException -from airbyte_cdk.utils.datetime_format_inferrer import DatetimeFormatInferrer -from airbyte_cdk.utils.schema_inferrer import SchemaInferrer, SchemaValidationException - - -class MessageGrouper: - logger = logging.getLogger("airbyte.connector-builder") - - def __init__(self, max_pages_per_slice: int, max_slices: int, max_record_limit: int = 1000): - self._max_pages_per_slice = max_pages_per_slice - self._max_slices = max_slices - self._max_record_limit = max_record_limit - - def _pk_to_nested_and_composite_field(self, field: Optional[Union[str, List[str], List[List[str]]]]) -> List[List[str]]: - if not field: - return [[]] - - if isinstance(field, str): - return [[field]] - - is_composite_key = isinstance(field[0], str) - if is_composite_key: - return [[i] for i in field] # type: ignore # the type of field is expected to be List[str] here - - return field # type: ignore # the type of field is expected to be List[List[str]] here - - def _cursor_field_to_nested_and_composite_field(self, field: Union[str, List[str]]) -> List[List[str]]: - if not field: - return [[]] - - if isinstance(field, str): - return [[field]] - - is_nested_key = isinstance(field[0], str) - if is_nested_key: - return [field] # type: ignore # the type of field is expected to be List[str] here - - raise ValueError(f"Unknown type for cursor field `{field}") - - def get_message_groups( - self, - source: DeclarativeSource, - config: Mapping[str, Any], - configured_catalog: ConfiguredAirbyteCatalog, - state: List[AirbyteStateMessage], - record_limit: Optional[int] = None, - ) -> StreamRead: - if record_limit is not None and not (1 <= record_limit <= self._max_record_limit): - raise ValueError(f"Record limit must be between 1 and {self._max_record_limit}. Got {record_limit}") - stream = source.streams(config)[0] # The connector builder currently only supports reading from a single stream at a time - schema_inferrer = SchemaInferrer( - self._pk_to_nested_and_composite_field(stream.primary_key), - self._cursor_field_to_nested_and_composite_field(stream.cursor_field), - ) - datetime_format_inferrer = DatetimeFormatInferrer() - - if record_limit is None: - record_limit = self._max_record_limit - else: - record_limit = min(record_limit, self._max_record_limit) - - slices = [] - log_messages = [] - latest_config_update: AirbyteControlMessage = None - auxiliary_requests = [] - for message_group in self._get_message_groups( - self._read_stream(source, config, configured_catalog, state), - schema_inferrer, - datetime_format_inferrer, - record_limit, - ): - if isinstance(message_group, AirbyteLogMessage): - log_messages.append(LogMessage(**{"message": message_group.message, "level": message_group.level.value})) - elif isinstance(message_group, AirbyteTraceMessage): - if message_group.type == TraceType.ERROR: - log_messages.append( - LogMessage( - **{ - "message": message_group.error.message, - "level": "ERROR", - "internal_message": message_group.error.internal_message, - "stacktrace": message_group.error.stack_trace, - } - ) - ) - elif isinstance(message_group, AirbyteControlMessage): - if not latest_config_update or latest_config_update.emitted_at <= message_group.emitted_at: - latest_config_update = message_group - elif isinstance(message_group, AuxiliaryRequest): - auxiliary_requests.append(message_group) - elif isinstance(message_group, StreamReadSlices): - slices.append(message_group) - else: - raise ValueError(f"Unknown message group type: {type(message_group)}") - - try: - # The connector builder currently only supports reading from a single stream at a time - configured_stream = configured_catalog.streams[0] - schema = schema_inferrer.get_stream_schema(configured_stream.stream.name) - except SchemaValidationException as exception: - for validation_error in exception.validation_errors: - log_messages.append(LogMessage(validation_error, "ERROR")) - schema = exception.schema - - return StreamRead( - logs=log_messages, - slices=slices, - test_read_limit_reached=self._has_reached_limit(slices), - auxiliary_requests=auxiliary_requests, - inferred_schema=schema, - latest_config_update=self._clean_config(latest_config_update.connectorConfig.config) if latest_config_update else None, - inferred_datetime_formats=datetime_format_inferrer.get_inferred_datetime_formats(), - ) - - def _get_message_groups( - self, - messages: Iterator[AirbyteMessage], - schema_inferrer: SchemaInferrer, - datetime_format_inferrer: DatetimeFormatInferrer, - limit: int, - ) -> Iterable[Union[StreamReadPages, AirbyteControlMessage, AirbyteLogMessage, AirbyteTraceMessage, AuxiliaryRequest]]: - """ - Message groups are partitioned according to when request log messages are received. Subsequent response log messages - and record messages belong to the prior request log message and when we encounter another request, append the latest - message group, until records have been read. - - Messages received from the CDK read operation will always arrive in the following order: - {type: LOG, log: {message: "request: ..."}} - {type: LOG, log: {message: "response: ..."}} - ... 0 or more record messages - {type: RECORD, record: {data: ...}} - {type: RECORD, record: {data: ...}} - Repeats for each request/response made - - Note: The exception is that normal log messages can be received at any time which are not incorporated into grouping - """ - records_count = 0 - at_least_one_page_in_group = False - current_page_records: List[Mapping[str, Any]] = [] - current_slice_descriptor: Optional[Dict[str, Any]] = None - current_slice_pages: List[StreamReadPages] = [] - current_page_request: Optional[HttpRequest] = None - current_page_response: Optional[HttpResponse] = None - latest_state_message: Optional[Dict[str, Any]] = None - - while records_count < limit and (message := next(messages, None)): - json_object = self._parse_json(message.log) if message.type == MessageType.LOG else None - if json_object is not None and not isinstance(json_object, dict): - raise ValueError(f"Expected log message to be a dict, got {json_object} of type {type(json_object)}") - json_message: Optional[Dict[str, JsonType]] = json_object - if self._need_to_close_page(at_least_one_page_in_group, message, json_message): - self._close_page(current_page_request, current_page_response, current_slice_pages, current_page_records) - current_page_request = None - current_page_response = None - - if ( - at_least_one_page_in_group - and message.type == MessageType.LOG - and message.log.message.startswith(SliceLogger.SLICE_LOG_PREFIX) # type: ignore[union-attr] # AirbyteMessage with MessageType.LOG has log.message - ): - yield StreamReadSlices( - pages=current_slice_pages, - slice_descriptor=current_slice_descriptor, - state=[latest_state_message] if latest_state_message else [], - ) - current_slice_descriptor = self._parse_slice_description(message.log.message) # type: ignore[union-attr] # AirbyteMessage with MessageType.LOG has log.message - current_slice_pages = [] - at_least_one_page_in_group = False - elif message.type == MessageType.LOG and message.log.message.startswith(SliceLogger.SLICE_LOG_PREFIX): # type: ignore[union-attr] # AirbyteMessage with MessageType.LOG has log.message - # parsing the first slice - current_slice_descriptor = self._parse_slice_description(message.log.message) # type: ignore[union-attr] # AirbyteMessage with MessageType.LOG has log.message - elif message.type == MessageType.LOG: - if json_message is not None and self._is_http_log(json_message): - if self._is_auxiliary_http_request(json_message): - airbyte_cdk = json_message.get("airbyte_cdk", {}) - if not isinstance(airbyte_cdk, dict): - raise ValueError(f"Expected airbyte_cdk to be a dict, got {airbyte_cdk} of type {type(airbyte_cdk)}") - stream = airbyte_cdk.get("stream", {}) - if not isinstance(stream, dict): - raise ValueError(f"Expected stream to be a dict, got {stream} of type {type(stream)}") - title_prefix = "Parent stream: " if stream.get("is_substream", False) else "" - http = json_message.get("http", {}) - if not isinstance(http, dict): - raise ValueError(f"Expected http to be a dict, got {http} of type {type(http)}") - yield AuxiliaryRequest( - title=title_prefix + str(http.get("title", None)), - description=str(http.get("description", None)), - request=self._create_request_from_log_message(json_message), - response=self._create_response_from_log_message(json_message), - ) - else: - at_least_one_page_in_group = True - current_page_request = self._create_request_from_log_message(json_message) - current_page_response = self._create_response_from_log_message(json_message) - else: - yield message.log - elif message.type == MessageType.TRACE: - if message.trace.type == TraceType.ERROR: # type: ignore[union-attr] # AirbyteMessage with MessageType.TRACE has trace.type - yield message.trace - elif message.type == MessageType.RECORD: - current_page_records.append(message.record.data) # type: ignore[union-attr] # AirbyteMessage with MessageType.RECORD has record.data - records_count += 1 - schema_inferrer.accumulate(message.record) - datetime_format_inferrer.accumulate(message.record) - elif message.type == MessageType.CONTROL and message.control.type == OrchestratorType.CONNECTOR_CONFIG: # type: ignore[union-attr] # AirbyteMessage with MessageType.CONTROL has control.type - yield message.control - elif message.type == MessageType.STATE: - latest_state_message = message.state # type: ignore[assignment] - else: - if current_page_request or current_page_response or current_page_records: - self._close_page(current_page_request, current_page_response, current_slice_pages, current_page_records) - yield StreamReadSlices( - pages=current_slice_pages, - slice_descriptor=current_slice_descriptor, - state=[latest_state_message] if latest_state_message else [], - ) - - @staticmethod - def _need_to_close_page(at_least_one_page_in_group: bool, message: AirbyteMessage, json_message: Optional[Dict[str, Any]]) -> bool: - return ( - at_least_one_page_in_group - and message.type == MessageType.LOG - and (MessageGrouper._is_page_http_request(json_message) or message.log.message.startswith("slice:")) # type: ignore[union-attr] # AirbyteMessage with MessageType.LOG has log.message - ) - - @staticmethod - def _is_page_http_request(json_message: Optional[Dict[str, Any]]) -> bool: - if not json_message: - return False - else: - return MessageGrouper._is_http_log(json_message) and not MessageGrouper._is_auxiliary_http_request(json_message) - - @staticmethod - def _is_http_log(message: Dict[str, JsonType]) -> bool: - return bool(message.get("http", False)) - - @staticmethod - def _is_auxiliary_http_request(message: Optional[Dict[str, Any]]) -> bool: - """ - A auxiliary request is a request that is performed and will not directly lead to record for the specific stream it is being queried. - A couple of examples are: - * OAuth authentication - * Substream slice generation - """ - if not message: - return False - - is_http = MessageGrouper._is_http_log(message) - return is_http and message.get("http", {}).get("is_auxiliary", False) - - @staticmethod - def _close_page( - current_page_request: Optional[HttpRequest], - current_page_response: Optional[HttpResponse], - current_slice_pages: List[StreamReadPages], - current_page_records: List[Mapping[str, Any]], - ) -> None: - """ - Close a page when parsing message groups - """ - current_slice_pages.append( - StreamReadPages(request=current_page_request, response=current_page_response, records=deepcopy(current_page_records)) # type: ignore - ) - current_page_records.clear() - - def _read_stream( - self, - source: DeclarativeSource, - config: Mapping[str, Any], - configured_catalog: ConfiguredAirbyteCatalog, - state: List[AirbyteStateMessage], - ) -> Iterator[AirbyteMessage]: - # the generator can raise an exception - # iterate over the generated messages. if next raise an exception, catch it and yield it as an AirbyteLogMessage - try: - yield from AirbyteEntrypoint(source).read(source.spec(self.logger), config, configured_catalog, state) - except AirbyteTracedException as traced_exception: - # Look for this message which indicates that it is the "final exception" raised by AbstractSource. - # If it matches, don't yield this as we don't need to show this in the Builder. - # This is somewhat brittle as it relies on the message string, but if they drift then the worst case - # is that this message will be shown in the Builder. - if ( - traced_exception.message is not None - and "During the sync, the following streams did not sync successfully" in traced_exception.message - ): - return - yield traced_exception.as_airbyte_message() - except Exception as e: - error_message = f"{e.args[0] if len(e.args) > 0 else str(e)}" - yield AirbyteTracedException.from_exception(e, message=error_message).as_airbyte_message() - - @staticmethod - def _parse_json(log_message: AirbyteLogMessage) -> JsonType: - # TODO: As a temporary stopgap, the CDK emits request/response data as a log message string. Ideally this should come in the - # form of a custom message object defined in the Airbyte protocol, but this unblocks us in the immediate while the - # protocol change is worked on. - try: - json_object: JsonType = json.loads(log_message.message) - return json_object - except JSONDecodeError: - return None - - @staticmethod - def _create_request_from_log_message(json_http_message: Dict[str, Any]) -> HttpRequest: - url = json_http_message.get("url", {}).get("full", "") - request = json_http_message.get("http", {}).get("request", {}) - return HttpRequest( - url=url, - http_method=request.get("method", ""), - headers=request.get("headers"), - body=request.get("body", {}).get("content", ""), - ) - - @staticmethod - def _create_response_from_log_message(json_http_message: Dict[str, Any]) -> HttpResponse: - response = json_http_message.get("http", {}).get("response", {}) - body = response.get("body", {}).get("content", "") - return HttpResponse(status=response.get("status_code"), body=body, headers=response.get("headers")) - - def _has_reached_limit(self, slices: List[StreamReadSlices]) -> bool: - if len(slices) >= self._max_slices: - return True - - record_count = 0 - - for _slice in slices: - if len(_slice.pages) >= self._max_pages_per_slice: - return True - for page in _slice.pages: - record_count += len(page.records) - if record_count >= self._max_record_limit: - return True - return False - - def _parse_slice_description(self, log_message: str) -> Dict[str, Any]: - return json.loads(log_message.replace(SliceLogger.SLICE_LOG_PREFIX, "", 1)) # type: ignore - - @staticmethod - def _clean_config(config: Dict[str, Any]) -> Dict[str, Any]: - cleaned_config = deepcopy(config) - for key in config.keys(): - if key.startswith("__"): - del cleaned_config[key] - return cleaned_config diff --git a/airbyte-cdk/python/airbyte_cdk/connector_builder/models.py b/airbyte-cdk/python/airbyte_cdk/connector_builder/models.py deleted file mode 100644 index 50eb8eb95530..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/connector_builder/models.py +++ /dev/null @@ -1,71 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import dataclass -from typing import Any, Dict, List, Optional - - -@dataclass -class HttpResponse: - status: int - body: Optional[str] = None - headers: Optional[Dict[str, Any]] = None - - -@dataclass -class HttpRequest: - url: str - headers: Optional[Dict[str, Any]] - http_method: str - body: Optional[str] = None - - -@dataclass -class StreamReadPages: - records: List[object] - request: Optional[HttpRequest] = None - response: Optional[HttpResponse] = None - - -@dataclass -class StreamReadSlices: - pages: List[StreamReadPages] - slice_descriptor: Optional[Dict[str, Any]] - state: Optional[List[Dict[str, Any]]] = None - - -@dataclass -class LogMessage: - message: str - level: str - internal_message: Optional[str] = None - stacktrace: Optional[str] = None - - -@dataclass -class AuxiliaryRequest: - title: str - description: str - request: HttpRequest - response: HttpResponse - - -@dataclass -class StreamRead(object): - logs: List[LogMessage] - slices: List[StreamReadSlices] - test_read_limit_reached: bool - auxiliary_requests: List[AuxiliaryRequest] - inferred_schema: Optional[Dict[str, Any]] - inferred_datetime_formats: Optional[Dict[str, str]] - latest_config_update: Optional[Dict[str, Any]] - - -@dataclass -class StreamReadRequestBody: - manifest: Dict[str, Any] - stream: str - config: Dict[str, Any] - state: Optional[Dict[str, Any]] - record_limit: Optional[int] diff --git a/airbyte-cdk/python/airbyte_cdk/destinations/__init__.py b/airbyte-cdk/python/airbyte_cdk/destinations/__init__.py deleted file mode 100644 index 5366d7cde0cc..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/destinations/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# - -from .destination import Destination - -__all__ = ["Destination"] diff --git a/airbyte-cdk/python/airbyte_cdk/destinations/destination.py b/airbyte-cdk/python/airbyte_cdk/destinations/destination.py deleted file mode 100644 index 336a54a94e8f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/destinations/destination.py +++ /dev/null @@ -1,120 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import argparse -import io -import logging -import sys -from abc import ABC, abstractmethod -from typing import Any, Iterable, List, Mapping - -from airbyte_cdk.connector import Connector -from airbyte_cdk.exception_handler import init_uncaught_exception_handler -from airbyte_cdk.models import AirbyteMessage, AirbyteMessageSerializer, ConfiguredAirbyteCatalog, ConfiguredAirbyteCatalogSerializer, Type -from airbyte_cdk.sources.utils.schema_helpers import check_config_against_spec_or_exit -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from orjson import orjson - -logger = logging.getLogger("airbyte") - - -class Destination(Connector, ABC): - VALID_CMDS = {"spec", "check", "write"} - - @abstractmethod - def write( - self, config: Mapping[str, Any], configured_catalog: ConfiguredAirbyteCatalog, input_messages: Iterable[AirbyteMessage] - ) -> Iterable[AirbyteMessage]: - """Implement to define how the connector writes data to the destination""" - - def _run_check(self, config: Mapping[str, Any]) -> AirbyteMessage: - check_result = self.check(logger, config) - return AirbyteMessage(type=Type.CONNECTION_STATUS, connectionStatus=check_result) - - def _parse_input_stream(self, input_stream: io.TextIOWrapper) -> Iterable[AirbyteMessage]: - """Reads from stdin, converting to Airbyte messages""" - for line in input_stream: - try: - yield AirbyteMessageSerializer.load(orjson.loads(line)) - except orjson.JSONDecodeError: - logger.info(f"ignoring input which can't be deserialized as Airbyte Message: {line}") - - def _run_write( - self, config: Mapping[str, Any], configured_catalog_path: str, input_stream: io.TextIOWrapper - ) -> Iterable[AirbyteMessage]: - catalog = ConfiguredAirbyteCatalogSerializer.load(orjson.loads(open(configured_catalog_path).read())) - input_messages = self._parse_input_stream(input_stream) - logger.info("Begin writing to the destination...") - yield from self.write(config=config, configured_catalog=catalog, input_messages=input_messages) - logger.info("Writing complete.") - - def parse_args(self, args: List[str]) -> argparse.Namespace: - """ - :param args: commandline arguments - :return: - """ - - parent_parser = argparse.ArgumentParser(add_help=False) - main_parser = argparse.ArgumentParser() - subparsers = main_parser.add_subparsers(title="commands", dest="command") - - # spec - subparsers.add_parser("spec", help="outputs the json configuration specification", parents=[parent_parser]) - - # check - check_parser = subparsers.add_parser("check", help="checks the config can be used to connect", parents=[parent_parser]) - required_check_parser = check_parser.add_argument_group("required named arguments") - required_check_parser.add_argument("--config", type=str, required=True, help="path to the json configuration file") - - # write - write_parser = subparsers.add_parser("write", help="Writes data to the destination", parents=[parent_parser]) - write_required = write_parser.add_argument_group("required named arguments") - write_required.add_argument("--config", type=str, required=True, help="path to the JSON configuration file") - write_required.add_argument("--catalog", type=str, required=True, help="path to the configured catalog JSON file") - - parsed_args = main_parser.parse_args(args) - cmd = parsed_args.command - if not cmd: - raise Exception("No command entered. ") - elif cmd not in ["spec", "check", "write"]: - # This is technically dead code since parse_args() would fail if this was the case - # But it's non-obvious enough to warrant placing it here anyways - raise Exception(f"Unknown command entered: {cmd}") - - return parsed_args - - def run_cmd(self, parsed_args: argparse.Namespace) -> Iterable[AirbyteMessage]: - - cmd = parsed_args.command - if cmd not in self.VALID_CMDS: - raise Exception(f"Unrecognized command: {cmd}") - - spec = self.spec(logger) - if cmd == "spec": - yield AirbyteMessage(type=Type.SPEC, spec=spec) - return - config = self.read_config(config_path=parsed_args.config) - if self.check_config_against_spec or cmd == "check": - try: - check_config_against_spec_or_exit(config, spec) - except AirbyteTracedException as traced_exc: - connection_status = traced_exc.as_connection_status_message() - if connection_status and cmd == "check": - yield connection_status - return - raise traced_exc - - if cmd == "check": - yield self._run_check(config=config) - elif cmd == "write": - # Wrap in UTF-8 to override any other input encodings - wrapped_stdin = io.TextIOWrapper(sys.stdin.buffer, encoding="utf-8") - yield from self._run_write(config=config, configured_catalog_path=parsed_args.catalog, input_stream=wrapped_stdin) - - def run(self, args: List[str]) -> None: - init_uncaught_exception_handler(logger) - parsed_args = self.parse_args(args) - output_messages = self.run_cmd(parsed_args) - for message in output_messages: - print(orjson.dumps(AirbyteMessageSerializer.dump(message)).decode()) diff --git a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/README.md b/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/README.md deleted file mode 100644 index 09668b61e963..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Vector DB based destinations - -## Note: All helpers in this directory are experimental and subject to change - -This directory contains several helpers that can be used to create a destination that processes and chunks records, embeds their text part and loads them into a vector database. -The specific loading behavior is defined by the destination connector itself, but chunking and embedding behavior is handled by the helpers. - -To use these helpers, install the CDK with the `vector-db-based` extra: - -```bash -pip install airbyte-cdk[vector-db-based] -``` - -The helpers can be used in the following way: - -- Add the config models to the spec of the connector -- Implement the `Indexer` interface for your specific database -- In the check implementation of the destination, initialize the indexer and the embedder and call `check` on them -- In the write implementation of the destination, initialize the indexer, the embedder and pass them to a new instance of the writer. Then call the writers `write` method with the iterable for incoming messages - -If there are no connector-specific embedders, the `airbyte_cdk.destinations.vector_db_based.embedder.create_from_config` function can be used to get an embedder instance from the config. - -This is how the components interact: - -```text -┌─────────────┐ -│MyDestination│ -└┬────────────┘ -┌▽───────────────────────────────┐ -│Writer │ -└┬─────────┬──────────┬──────────┘ -┌▽───────┐┌▽────────┐┌▽────────────────┐ -│Embedder││MyIndexer││DocumentProcessor│ -└────────┘└─────────┘└─────────────────┘ -``` - -Normally, only the `MyDestination` class and the `MyIndexer` class has to be implemented specifically for the destination. The other classes are provided as is by the helpers. diff --git a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/__init__.py b/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/__init__.py deleted file mode 100644 index 86ae207f69d8..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/__init__.py +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# - -from .config import ( - AzureOpenAIEmbeddingConfigModel, - CohereEmbeddingConfigModel, - FakeEmbeddingConfigModel, - FromFieldEmbeddingConfigModel, - OpenAICompatibleEmbeddingConfigModel, - OpenAIEmbeddingConfigModel, - ProcessingConfigModel, -) -from .document_processor import Chunk, DocumentProcessor -from .embedder import CohereEmbedder, Embedder, FakeEmbedder, OpenAIEmbedder -from .indexer import Indexer -from .writer import Writer - -__all__ = [ - "AzureOpenAIEmbedder", - "AzureOpenAIEmbeddingConfigModel", - "Chunk", - "CohereEmbedder", - "CohereEmbeddingConfigModel", - "DocumentProcessor", - "Embedder", - "FakeEmbedder", - "FakeEmbeddingConfigModel", - "FromFieldEmbedder", - "FromFieldEmbeddingConfigModel", - "Indexer", - "OpenAICompatibleEmbedder", - "OpenAICompatibleEmbeddingConfigModel", - "OpenAIEmbedder", - "OpenAIEmbeddingConfigModel", - "ProcessingConfigModel", - "Writer", -] diff --git a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/config.py b/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/config.py deleted file mode 100644 index 90de6b777e97..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/config.py +++ /dev/null @@ -1,275 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Dict, List, Literal, Optional, Union - -import dpath -from airbyte_cdk.utils.oneof_option_config import OneOfOptionConfig -from airbyte_cdk.utils.spec_schema_transformations import resolve_refs -from pydantic.v1 import BaseModel, Field - - -class SeparatorSplitterConfigModel(BaseModel): - mode: Literal["separator"] = Field("separator", const=True) - separators: List[str] = Field( - default=['"\\n\\n"', '"\\n"', '" "', '""'], - title="Separators", - description='List of separator strings to split text fields by. The separator itself needs to be wrapped in double quotes, e.g. to split by the dot character, use ".". To split by a newline, use "\\n".', - ) - keep_separator: bool = Field(default=False, title="Keep separator", description="Whether to keep the separator in the resulting chunks") - - class Config(OneOfOptionConfig): - title = "By Separator" - description = "Split the text by the list of separators until the chunk size is reached, using the earlier mentioned separators where possible. This is useful for splitting text fields by paragraphs, sentences, words, etc." - discriminator = "mode" - - -class MarkdownHeaderSplitterConfigModel(BaseModel): - mode: Literal["markdown"] = Field("markdown", const=True) - split_level: int = Field( - default=1, - title="Split level", - description="Level of markdown headers to split text fields by. Headings down to the specified level will be used as split points", - le=6, - ge=1, - ) - - class Config(OneOfOptionConfig): - title = "By Markdown header" - description = "Split the text by Markdown headers down to the specified header level. If the chunk size fits multiple sections, they will be combined into a single chunk." - discriminator = "mode" - - -class CodeSplitterConfigModel(BaseModel): - mode: Literal["code"] = Field("code", const=True) - language: str = Field( - title="Language", - description="Split code in suitable places based on the programming language", - enum=[ - "cpp", - "go", - "java", - "js", - "php", - "proto", - "python", - "rst", - "ruby", - "rust", - "scala", - "swift", - "markdown", - "latex", - "html", - "sol", - ], - ) - - class Config(OneOfOptionConfig): - title = "By Programming Language" - description = ( - "Split the text by suitable delimiters based on the programming language. This is useful for splitting code into chunks." - ) - discriminator = "mode" - - -TextSplitterConfigModel = Union[SeparatorSplitterConfigModel, MarkdownHeaderSplitterConfigModel, CodeSplitterConfigModel] - - -class FieldNameMappingConfigModel(BaseModel): - from_field: str = Field(title="From field name", description="The field name in the source") - to_field: str = Field(title="To field name", description="The field name to use in the destination") - - -class ProcessingConfigModel(BaseModel): - chunk_size: int = Field( - ..., - title="Chunk size", - maximum=8191, - minimum=1, - description="Size of chunks in tokens to store in vector store (make sure it is not too big for the context if your LLM)", - ) - chunk_overlap: int = Field( - title="Chunk overlap", - description="Size of overlap between chunks in tokens to store in vector store to better capture relevant context", - default=0, - ) - text_fields: Optional[List[str]] = Field( - default=[], - title="Text fields to embed", - description="List of fields in the record that should be used to calculate the embedding. The field list is applied to all streams in the same way and non-existing fields are ignored. If none are defined, all fields are considered text fields. When specifying text fields, you can access nested fields in the record by using dot notation, e.g. `user.name` will access the `name` field in the `user` object. It's also possible to use wildcards to access all fields in an object, e.g. `users.*.name` will access all `names` fields in all entries of the `users` array.", - always_show=True, - examples=["text", "user.name", "users.*.name"], - ) - metadata_fields: Optional[List[str]] = Field( - default=[], - title="Fields to store as metadata", - description="List of fields in the record that should be stored as metadata. The field list is applied to all streams in the same way and non-existing fields are ignored. If none are defined, all fields are considered metadata fields. When specifying text fields, you can access nested fields in the record by using dot notation, e.g. `user.name` will access the `name` field in the `user` object. It's also possible to use wildcards to access all fields in an object, e.g. `users.*.name` will access all `names` fields in all entries of the `users` array. When specifying nested paths, all matching values are flattened into an array set to a field named by the path.", - always_show=True, - examples=["age", "user", "user.name"], - ) - text_splitter: TextSplitterConfigModel = Field( - default=None, - title="Text splitter", - discriminator="mode", - type="object", - description="Split text fields into chunks based on the specified method.", - ) - field_name_mappings: Optional[List[FieldNameMappingConfigModel]] = Field( - default=[], - title="Field name mappings", - description="List of fields to rename. Not applicable for nested fields, but can be used to rename fields already flattened via dot notation.", - ) - - class Config: - schema_extra = {"group": "processing"} - - -class OpenAIEmbeddingConfigModel(BaseModel): - mode: Literal["openai"] = Field("openai", const=True) - openai_key: str = Field(..., title="OpenAI API key", airbyte_secret=True) - - class Config(OneOfOptionConfig): - title = "OpenAI" - description = ( - "Use the OpenAI API to embed text. This option is using the text-embedding-ada-002 model with 1536 embedding dimensions." - ) - discriminator = "mode" - - -class OpenAICompatibleEmbeddingConfigModel(BaseModel): - mode: Literal["openai_compatible"] = Field("openai_compatible", const=True) - api_key: str = Field(title="API key", default="", airbyte_secret=True) - base_url: str = Field( - ..., title="Base URL", description="The base URL for your OpenAI-compatible service", examples=["https://your-service-name.com"] - ) - model_name: str = Field( - title="Model name", - description="The name of the model to use for embedding", - default="text-embedding-ada-002", - examples=["text-embedding-ada-002"], - ) - dimensions: int = Field( - title="Embedding dimensions", description="The number of dimensions the embedding model is generating", examples=[1536, 384] - ) - - class Config(OneOfOptionConfig): - title = "OpenAI-compatible" - description = "Use a service that's compatible with the OpenAI API to embed text." - discriminator = "mode" - - -class AzureOpenAIEmbeddingConfigModel(BaseModel): - mode: Literal["azure_openai"] = Field("azure_openai", const=True) - openai_key: str = Field( - ..., - title="Azure OpenAI API key", - airbyte_secret=True, - description="The API key for your Azure OpenAI resource. You can find this in the Azure portal under your Azure OpenAI resource", - ) - api_base: str = Field( - ..., - title="Resource base URL", - description="The base URL for your Azure OpenAI resource. You can find this in the Azure portal under your Azure OpenAI resource", - examples=["https://your-resource-name.openai.azure.com"], - ) - deployment: str = Field( - ..., - title="Deployment", - description="The deployment for your Azure OpenAI resource. You can find this in the Azure portal under your Azure OpenAI resource", - examples=["your-resource-name"], - ) - - class Config(OneOfOptionConfig): - title = "Azure OpenAI" - description = "Use the Azure-hosted OpenAI API to embed text. This option is using the text-embedding-ada-002 model with 1536 embedding dimensions." - discriminator = "mode" - - -class FakeEmbeddingConfigModel(BaseModel): - mode: Literal["fake"] = Field("fake", const=True) - - class Config(OneOfOptionConfig): - title = "Fake" - description = "Use a fake embedding made out of random vectors with 1536 embedding dimensions. This is useful for testing the data pipeline without incurring any costs." - discriminator = "mode" - - -class FromFieldEmbeddingConfigModel(BaseModel): - mode: Literal["from_field"] = Field("from_field", const=True) - field_name: str = Field( - ..., title="Field name", description="Name of the field in the record that contains the embedding", examples=["embedding", "vector"] - ) - dimensions: int = Field( - ..., title="Embedding dimensions", description="The number of dimensions the embedding model is generating", examples=[1536, 384] - ) - - class Config(OneOfOptionConfig): - title = "From Field" - description = "Use a field in the record as the embedding. This is useful if you already have an embedding for your data and want to store it in the vector store." - discriminator = "mode" - - -class CohereEmbeddingConfigModel(BaseModel): - mode: Literal["cohere"] = Field("cohere", const=True) - cohere_key: str = Field(..., title="Cohere API key", airbyte_secret=True) - - class Config(OneOfOptionConfig): - title = "Cohere" - description = "Use the Cohere API to embed text." - discriminator = "mode" - - -class VectorDBConfigModel(BaseModel): - """ - The configuration model for the Vector DB based destinations. This model is used to generate the UI for the destination configuration, - as well as to provide type safety for the configuration passed to the destination. - - The configuration model is composed of four parts: - * Processing configuration - * Embedding configuration - * Indexing configuration - * Advanced configuration - - Processing, embedding and advanced configuration are provided by this base class, while the indexing configuration is provided by the destination connector in the sub class. - """ - - embedding: Union[ - OpenAIEmbeddingConfigModel, - CohereEmbeddingConfigModel, - FakeEmbeddingConfigModel, - AzureOpenAIEmbeddingConfigModel, - OpenAICompatibleEmbeddingConfigModel, - ] = Field(..., title="Embedding", description="Embedding configuration", discriminator="mode", group="embedding", type="object") - processing: ProcessingConfigModel - omit_raw_text: bool = Field( - default=False, - title="Do not store raw text", - group="advanced", - description="Do not store the text that gets embedded along with the vector and the metadata in the destination. If set to true, only the vector and the metadata will be stored - in this case raw text for LLM use cases needs to be retrieved from another source.", - ) - - class Config: - title = "Destination Config" - schema_extra = { - "groups": [ - {"id": "processing", "title": "Processing"}, - {"id": "embedding", "title": "Embedding"}, - {"id": "indexing", "title": "Indexing"}, - {"id": "advanced", "title": "Advanced"}, - ] - } - - @staticmethod - def remove_discriminator(schema: Dict[str, Any]) -> None: - """pydantic adds "discriminator" to the schema for oneOfs, which is not treated right by the platform as we inline all references""" - dpath.delete(schema, "properties/**/discriminator") - - @classmethod - def schema(cls, by_alias: bool = True, ref_template: str = "") -> Dict[str, Any]: - """we're overriding the schema classmethod to enable some post-processing""" - schema: Dict[str, Any] = super().schema() - schema = resolve_refs(schema) - cls.remove_discriminator(schema) - return schema diff --git a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/document_processor.py b/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/document_processor.py deleted file mode 100644 index 45b6e4d7bc52..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/document_processor.py +++ /dev/null @@ -1,184 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import logging -from dataclasses import dataclass -from typing import Any, Dict, List, Mapping, Optional, Tuple - -import dpath -from airbyte_cdk.destinations.vector_db_based.config import ProcessingConfigModel, SeparatorSplitterConfigModel, TextSplitterConfigModel -from airbyte_cdk.destinations.vector_db_based.utils import create_stream_identifier -from airbyte_cdk.models import AirbyteRecordMessage, ConfiguredAirbyteCatalog, ConfiguredAirbyteStream, DestinationSyncMode -from airbyte_cdk.utils.traced_exception import AirbyteTracedException, FailureType -from langchain.text_splitter import Language, RecursiveCharacterTextSplitter -from langchain.utils import stringify_dict -from langchain_core.documents.base import Document - -METADATA_STREAM_FIELD = "_ab_stream" -METADATA_RECORD_ID_FIELD = "_ab_record_id" - -CDC_DELETED_FIELD = "_ab_cdc_deleted_at" - - -@dataclass -class Chunk: - page_content: Optional[str] - metadata: Dict[str, Any] - record: AirbyteRecordMessage - embedding: Optional[List[float]] = None - - -headers_to_split_on = ["(?:^|\n)# ", "(?:^|\n)## ", "(?:^|\n)### ", "(?:^|\n)#### ", "(?:^|\n)##### ", "(?:^|\n)###### "] - - -class DocumentProcessor: - """ - DocumentProcessor is a helper class that generates documents from Airbyte records. - - It is used to generate documents from records before writing them to the destination: - * The text fields are extracted from the record and concatenated to a single string. - * The metadata fields are extracted from the record and added to the document metadata. - * The document is split into chunks of a given size using a langchain text splitter. - - The Writer class uses the DocumentProcessor class to internally generate documents from records - in most cases you don't need to use it directly, - except if you want to implement a custom writer. - - The config parameters specified by the ProcessingConfigModel has to be made part of the connector spec to allow the user to configure the document processor. - Calling DocumentProcessor.check_config(config) will validate the config and return an error message if the config is invalid. - """ - - streams: Mapping[str, ConfiguredAirbyteStream] - - @staticmethod - def check_config(config: ProcessingConfigModel) -> Optional[str]: - if config.text_splitter is not None and config.text_splitter.mode == "separator": - for s in config.text_splitter.separators: - try: - separator = json.loads(s) - if not isinstance(separator, str): - return f"Invalid separator: {s}. Separator needs to be a valid JSON string using double quotes." - except json.decoder.JSONDecodeError: - return f"Invalid separator: {s}. Separator needs to be a valid JSON string using double quotes." - return None - - def _get_text_splitter( - self, chunk_size: int, chunk_overlap: int, splitter_config: Optional[TextSplitterConfigModel] - ) -> RecursiveCharacterTextSplitter: - if splitter_config is None: - splitter_config = SeparatorSplitterConfigModel(mode="separator") - if splitter_config.mode == "separator": - return RecursiveCharacterTextSplitter.from_tiktoken_encoder( - chunk_size=chunk_size, - chunk_overlap=chunk_overlap, - separators=[json.loads(s) for s in splitter_config.separators], - keep_separator=splitter_config.keep_separator, - disallowed_special=(), - ) - if splitter_config.mode == "markdown": - return RecursiveCharacterTextSplitter.from_tiktoken_encoder( - chunk_size=chunk_size, - chunk_overlap=chunk_overlap, - separators=headers_to_split_on[: splitter_config.split_level], - is_separator_regex=True, - keep_separator=True, - disallowed_special=(), - ) - if splitter_config.mode == "code": - return RecursiveCharacterTextSplitter.from_tiktoken_encoder( - chunk_size=chunk_size, - chunk_overlap=chunk_overlap, - separators=RecursiveCharacterTextSplitter.get_separators_for_language(Language(splitter_config.language)), - disallowed_special=(), - ) - - def __init__(self, config: ProcessingConfigModel, catalog: ConfiguredAirbyteCatalog): - self.streams = {create_stream_identifier(stream.stream): stream for stream in catalog.streams} - - self.splitter = self._get_text_splitter(config.chunk_size, config.chunk_overlap, config.text_splitter) - self.text_fields = config.text_fields - self.metadata_fields = config.metadata_fields - self.field_name_mappings = config.field_name_mappings - self.logger = logging.getLogger("airbyte.document_processor") - - def process(self, record: AirbyteRecordMessage) -> Tuple[List[Chunk], Optional[str]]: - """ - Generate documents from records. - :param records: List of AirbyteRecordMessages - :return: Tuple of (List of document chunks, record id to delete if a stream is in dedup mode to avoid stale documents in the vector store) - """ - if CDC_DELETED_FIELD in record.data and record.data[CDC_DELETED_FIELD]: - return [], self._extract_primary_key(record) - doc = self._generate_document(record) - if doc is None: - text_fields = ", ".join(self.text_fields) if self.text_fields else "all fields" - raise AirbyteTracedException( - internal_message="No text fields found in record", - message=f"Record {str(record.data)[:250]}... does not contain any of the configured text fields: {text_fields}. Please check your processing configuration, there has to be at least one text field set in each record.", - failure_type=FailureType.config_error, - ) - chunks = [ - Chunk(page_content=chunk_document.page_content, metadata=chunk_document.metadata, record=record) - for chunk_document in self._split_document(doc) - ] - id_to_delete = doc.metadata[METADATA_RECORD_ID_FIELD] if METADATA_RECORD_ID_FIELD in doc.metadata else None - return chunks, id_to_delete - - def _generate_document(self, record: AirbyteRecordMessage) -> Optional[Document]: - relevant_fields = self._extract_relevant_fields(record, self.text_fields) - if len(relevant_fields) == 0: - return None - text = stringify_dict(relevant_fields) - metadata = self._extract_metadata(record) - return Document(page_content=text, metadata=metadata) - - def _extract_relevant_fields(self, record: AirbyteRecordMessage, fields: Optional[List[str]]) -> Dict[str, Any]: - relevant_fields = {} - if fields and len(fields) > 0: - for field in fields: - values = dpath.values(record.data, field, separator=".") - if values and len(values) > 0: - relevant_fields[field] = values if len(values) > 1 else values[0] - else: - relevant_fields = record.data - return self._remap_field_names(relevant_fields) - - def _extract_metadata(self, record: AirbyteRecordMessage) -> Dict[str, Any]: - metadata = self._extract_relevant_fields(record, self.metadata_fields) - metadata[METADATA_STREAM_FIELD] = create_stream_identifier(record) - primary_key = self._extract_primary_key(record) - if primary_key: - metadata[METADATA_RECORD_ID_FIELD] = primary_key - return metadata - - def _extract_primary_key(self, record: AirbyteRecordMessage) -> Optional[str]: - stream_identifier = create_stream_identifier(record) - current_stream: ConfiguredAirbyteStream = self.streams[stream_identifier] - # if the sync mode is deduping, use the primary key to upsert existing records instead of appending new ones - if not current_stream.primary_key or current_stream.destination_sync_mode != DestinationSyncMode.append_dedup: - return None - - primary_key = [] - for key in current_stream.primary_key: - try: - primary_key.append(str(dpath.get(record.data, key))) - except KeyError: - primary_key.append("__not_found__") - stringified_primary_key = "_".join(primary_key) - return f"{stream_identifier}_{stringified_primary_key}" - - def _split_document(self, doc: Document) -> List[Document]: - chunks: List[Document] = self.splitter.split_documents([doc]) - return chunks - - def _remap_field_names(self, fields: Dict[str, Any]) -> Dict[str, Any]: - if not self.field_name_mappings: - return fields - - new_fields = fields.copy() - for mapping in self.field_name_mappings: - if mapping.from_field in new_fields: - new_fields[mapping.to_field] = new_fields.pop(mapping.from_field) - - return new_fields diff --git a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/embedder.py b/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/embedder.py deleted file mode 100644 index 7fb880fadaae..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/embedder.py +++ /dev/null @@ -1,261 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import os -from abc import ABC, abstractmethod -from dataclasses import dataclass -from typing import List, Optional, Union, cast - -from airbyte_cdk.destinations.vector_db_based.config import ( - AzureOpenAIEmbeddingConfigModel, - CohereEmbeddingConfigModel, - FakeEmbeddingConfigModel, - FromFieldEmbeddingConfigModel, - OpenAICompatibleEmbeddingConfigModel, - OpenAIEmbeddingConfigModel, - ProcessingConfigModel, -) -from airbyte_cdk.destinations.vector_db_based.utils import create_chunks, format_exception -from airbyte_cdk.models import AirbyteRecordMessage -from airbyte_cdk.utils.traced_exception import AirbyteTracedException, FailureType -from langchain.embeddings.cohere import CohereEmbeddings -from langchain.embeddings.fake import FakeEmbeddings -from langchain.embeddings.localai import LocalAIEmbeddings -from langchain.embeddings.openai import OpenAIEmbeddings - - -@dataclass -class Document: - page_content: str - record: AirbyteRecordMessage - - -class Embedder(ABC): - """ - Embedder is an abstract class that defines the interface for embedding text. - - The Indexer class uses the Embedder class to internally embed text - each indexer is responsible to pass the text of all documents to the embedder and store the resulting embeddings in the destination. - The destination connector is responsible to create an embedder instance and pass it to the writer. - The CDK defines basic embedders that should be supported in each destination. It is possible to implement custom embedders for special destinations if needed. - """ - - def __init__(self) -> None: - pass - - @abstractmethod - def check(self) -> Optional[str]: - pass - - @abstractmethod - def embed_documents(self, documents: List[Document]) -> List[Optional[List[float]]]: - """ - Embed the text of each chunk and return the resulting embedding vectors. - If a chunk cannot be embedded or is configured to not be embedded, return None for that chunk. - """ - pass - - @property - @abstractmethod - def embedding_dimensions(self) -> int: - pass - - -OPEN_AI_VECTOR_SIZE = 1536 - -OPEN_AI_TOKEN_LIMIT = 150_000 # limit of tokens per minute - - -class BaseOpenAIEmbedder(Embedder): - def __init__(self, embeddings: OpenAIEmbeddings, chunk_size: int): - super().__init__() - self.embeddings = embeddings - self.chunk_size = chunk_size - - def check(self) -> Optional[str]: - try: - self.embeddings.embed_query("test") - except Exception as e: - return format_exception(e) - return None - - def embed_documents(self, documents: List[Document]) -> List[Optional[List[float]]]: - """ - Embed the text of each chunk and return the resulting embedding vectors. - - As the OpenAI API will fail if more than the per-minute limit worth of tokens is sent at once, we split the request into batches and embed each batch separately. - It's still possible to run into the rate limit between each embed call because the available token budget hasn't recovered between the calls, - but the built-in retry mechanism of the OpenAI client handles that. - """ - # Each chunk can hold at most self.chunk_size tokens, so tokens-per-minute by maximum tokens per chunk is the number of documents that can be embedded at once without exhausting the limit in a single request - embedding_batch_size = OPEN_AI_TOKEN_LIMIT // self.chunk_size - batches = create_chunks(documents, batch_size=embedding_batch_size) - embeddings: List[Optional[List[float]]] = [] - for batch in batches: - embeddings.extend(self.embeddings.embed_documents([chunk.page_content for chunk in batch])) - return embeddings - - @property - def embedding_dimensions(self) -> int: - # vector size produced by text-embedding-ada-002 model - return OPEN_AI_VECTOR_SIZE - - -class OpenAIEmbedder(BaseOpenAIEmbedder): - def __init__(self, config: OpenAIEmbeddingConfigModel, chunk_size: int): - super().__init__(OpenAIEmbeddings(openai_api_key=config.openai_key, max_retries=15, disallowed_special=()), chunk_size) # type: ignore - - -class AzureOpenAIEmbedder(BaseOpenAIEmbedder): - def __init__(self, config: AzureOpenAIEmbeddingConfigModel, chunk_size: int): - # Azure OpenAI API has — as of 20230927 — a limit of 16 documents per request - super().__init__(OpenAIEmbeddings(openai_api_key=config.openai_key, chunk_size=16, max_retries=15, openai_api_type="azure", openai_api_version="2023-05-15", openai_api_base=config.api_base, deployment=config.deployment, disallowed_special=()), chunk_size) # type: ignore - - -COHERE_VECTOR_SIZE = 1024 - - -class CohereEmbedder(Embedder): - def __init__(self, config: CohereEmbeddingConfigModel): - super().__init__() - # Client is set internally - self.embeddings = CohereEmbeddings(cohere_api_key=config.cohere_key, model="embed-english-light-v2.0") # type: ignore - - def check(self) -> Optional[str]: - try: - self.embeddings.embed_query("test") - except Exception as e: - return format_exception(e) - return None - - def embed_documents(self, documents: List[Document]) -> List[Optional[List[float]]]: - return cast(List[Optional[List[float]]], self.embeddings.embed_documents([document.page_content for document in documents])) - - @property - def embedding_dimensions(self) -> int: - # vector size produced by text-embedding-ada-002 model - return COHERE_VECTOR_SIZE - - -class FakeEmbedder(Embedder): - def __init__(self, config: FakeEmbeddingConfigModel): - super().__init__() - self.embeddings = FakeEmbeddings(size=OPEN_AI_VECTOR_SIZE) - - def check(self) -> Optional[str]: - try: - self.embeddings.embed_query("test") - except Exception as e: - return format_exception(e) - return None - - def embed_documents(self, documents: List[Document]) -> List[Optional[List[float]]]: - return cast(List[Optional[List[float]]], self.embeddings.embed_documents([document.page_content for document in documents])) - - @property - def embedding_dimensions(self) -> int: - # use same vector size as for OpenAI embeddings to keep it realistic - return OPEN_AI_VECTOR_SIZE - - -CLOUD_DEPLOYMENT_MODE = "cloud" - - -class OpenAICompatibleEmbedder(Embedder): - def __init__(self, config: OpenAICompatibleEmbeddingConfigModel): - super().__init__() - self.config = config - # Client is set internally - # Always set an API key even if there is none defined in the config because the validator will fail otherwise. Embedding APIs that don't require an API key don't fail if one is provided, so this is not breaking usage. - self.embeddings = LocalAIEmbeddings(model=config.model_name, openai_api_key=config.api_key or "dummy-api-key", openai_api_base=config.base_url, max_retries=15, disallowed_special=()) # type: ignore - - def check(self) -> Optional[str]: - deployment_mode = os.environ.get("DEPLOYMENT_MODE", "") - if deployment_mode.casefold() == CLOUD_DEPLOYMENT_MODE and not self.config.base_url.startswith("https://"): - return "Base URL must start with https://" - - try: - self.embeddings.embed_query("test") - except Exception as e: - return format_exception(e) - return None - - def embed_documents(self, documents: List[Document]) -> List[Optional[List[float]]]: - return cast(List[Optional[List[float]]], self.embeddings.embed_documents([document.page_content for document in documents])) - - @property - def embedding_dimensions(self) -> int: - # vector size produced by the model - return self.config.dimensions - - -class FromFieldEmbedder(Embedder): - def __init__(self, config: FromFieldEmbeddingConfigModel): - super().__init__() - self.config = config - - def check(self) -> Optional[str]: - return None - - def embed_documents(self, documents: List[Document]) -> List[Optional[List[float]]]: - """ - From each chunk, pull the embedding from the field specified in the config. - Check that the field exists, is a list of numbers and is the correct size. If not, raise an AirbyteTracedException explaining the problem. - """ - embeddings: List[Optional[List[float]]] = [] - for document in documents: - data = document.record.data - if self.config.field_name not in data: - raise AirbyteTracedException( - internal_message="Embedding vector field not found", - failure_type=FailureType.config_error, - message=f"Record {str(data)[:250]}... in stream {document.record.stream} does not contain embedding vector field {self.config.field_name}. Please check your embedding configuration, the embedding vector field has to be set correctly on every record.", - ) - field = data[self.config.field_name] - if not isinstance(field, list) or not all(isinstance(x, (int, float)) for x in field): - raise AirbyteTracedException( - internal_message="Embedding vector field not a list of numbers", - failure_type=FailureType.config_error, - message=f"Record {str(data)[:250]}... in stream {document.record.stream} does contain embedding vector field {self.config.field_name}, but it is not a list of numbers. Please check your embedding configuration, the embedding vector field has to be a list of numbers of length {self.config.dimensions} on every record.", - ) - if len(field) != self.config.dimensions: - raise AirbyteTracedException( - internal_message="Embedding vector field has wrong length", - failure_type=FailureType.config_error, - message=f"Record {str(data)[:250]}... in stream {document.record.stream} does contain embedding vector field {self.config.field_name}, but it has length {len(field)} instead of the configured {self.config.dimensions}. Please check your embedding configuration, the embedding vector field has to be a list of numbers of length {self.config.dimensions} on every record.", - ) - embeddings.append(field) - - return embeddings - - @property - def embedding_dimensions(self) -> int: - return self.config.dimensions - - -embedder_map = { - "openai": OpenAIEmbedder, - "cohere": CohereEmbedder, - "fake": FakeEmbedder, - "azure_openai": AzureOpenAIEmbedder, - "from_field": FromFieldEmbedder, - "openai_compatible": OpenAICompatibleEmbedder, -} - - -def create_from_config( - embedding_config: Union[ - AzureOpenAIEmbeddingConfigModel, - CohereEmbeddingConfigModel, - FakeEmbeddingConfigModel, - FromFieldEmbeddingConfigModel, - OpenAIEmbeddingConfigModel, - OpenAICompatibleEmbeddingConfigModel, - ], - processing_config: ProcessingConfigModel, -) -> Embedder: - - if embedding_config.mode == "azure_openai" or embedding_config.mode == "openai": - return cast(Embedder, embedder_map[embedding_config.mode](embedding_config, processing_config.chunk_size)) - else: - return cast(Embedder, embedder_map[embedding_config.mode](embedding_config)) diff --git a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/indexer.py b/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/indexer.py deleted file mode 100644 index c49f576a6709..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/indexer.py +++ /dev/null @@ -1,78 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import itertools -from abc import ABC, abstractmethod -from typing import Any, Generator, Iterable, List, Optional, Tuple, TypeVar - -from airbyte_cdk.destinations.vector_db_based.document_processor import Chunk -from airbyte_cdk.models import AirbyteMessage, ConfiguredAirbyteCatalog - - -class Indexer(ABC): - """ - Indexer is an abstract class that defines the interface for indexing documents. - - The Writer class uses the Indexer class to internally index documents generated by the document processor. - In a destination connector, implement a custom indexer by extending this class and implementing the abstract methods. - """ - - def __init__(self, config: Any): - self.config = config - pass - - def pre_sync(self, catalog: ConfiguredAirbyteCatalog) -> None: - """ - Run before the sync starts. This method should be used to make sure all records in the destination that belong to streams with a destination mode of overwrite are deleted. - - Each record has a metadata field with the name airbyte_cdk.destinations.vector_db_based.document_processor.METADATA_STREAM_FIELD which can be used to filter documents for deletion. - Use the airbyte_cdk.destinations.vector_db_based.utils.create_stream_identifier method to create the stream identifier based on the stream definition to use for filtering. - """ - pass - - def post_sync(self) -> List[AirbyteMessage]: - """ - Run after the sync finishes. This method should be used to perform any cleanup operations and can return a list of AirbyteMessages to be logged. - """ - return [] - - @abstractmethod - def index(self, document_chunks: List[Chunk], namespace: str, stream: str) -> None: - """ - Index a list of document chunks. - - This method should be used to index the documents in the destination. If page_content is None, the document should be indexed without the raw text. - All chunks belong to the stream and namespace specified in the parameters. - """ - pass - - @abstractmethod - def delete(self, delete_ids: List[str], namespace: str, stream: str) -> None: - """ - Delete document chunks belonging to certain record ids. - - This method should be used to delete documents from the destination. - The delete_ids parameter contains a list of record ids - all chunks with a record id in this list should be deleted from the destination. - All ids belong to the stream and namespace specified in the parameters. - """ - pass - - @abstractmethod - def check(self) -> Optional[str]: - """ - Check if the indexer is configured correctly. This method should be used to check if the indexer is configured correctly and return an error message if it is not. - """ - pass - - -T = TypeVar("T") - - -def chunks(iterable: Iterable[T], batch_size: int) -> Generator[Tuple[T, ...], None, None]: - """A helper function to break an iterable into chunks of size batch_size.""" - it = iter(iterable) - chunk = tuple(itertools.islice(it, batch_size)) - while chunk: - yield chunk - chunk = tuple(itertools.islice(it, batch_size)) diff --git a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/test_utils.py b/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/test_utils.py deleted file mode 100644 index 7f8cfe5fbd8a..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/test_utils.py +++ /dev/null @@ -1,53 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import unittest -from typing import Any, Dict - -from airbyte_cdk.models import ( - AirbyteMessage, - AirbyteRecordMessage, - AirbyteStateMessage, - AirbyteStream, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteStream, - DestinationSyncMode, - SyncMode, - Type, -) - - -class BaseIntegrationTest(unittest.TestCase): - """ - BaseIntegrationTest is a base class for integration tests for vector db destinations. - - It provides helper methods to create Airbyte catalogs, records and state messages. - """ - - def _get_configured_catalog(self, destination_mode: DestinationSyncMode) -> ConfiguredAirbyteCatalog: - stream_schema = {"type": "object", "properties": {"str_col": {"type": "str"}, "int_col": {"type": "integer"}}} - - overwrite_stream = ConfiguredAirbyteStream( - stream=AirbyteStream( - name="mystream", json_schema=stream_schema, supported_sync_modes=[SyncMode.incremental, SyncMode.full_refresh] - ), - primary_key=[["int_col"]], - sync_mode=SyncMode.incremental, - destination_sync_mode=destination_mode, - ) - - return ConfiguredAirbyteCatalog(streams=[overwrite_stream]) - - def _state(self, data: Dict[str, Any]) -> AirbyteMessage: - return AirbyteMessage(type=Type.STATE, state=AirbyteStateMessage(data=data)) - - def _record(self, stream: str, str_value: str, int_value: int) -> AirbyteMessage: - return AirbyteMessage( - type=Type.RECORD, record=AirbyteRecordMessage(stream=stream, data={"str_col": str_value, "int_col": int_value}, emitted_at=0) - ) - - def setUp(self) -> None: - with open("secrets/config.json", "r") as f: - self.config = json.loads(f.read()) diff --git a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/utils.py b/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/utils.py deleted file mode 100644 index b0d4edebf890..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/utils.py +++ /dev/null @@ -1,29 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import itertools -import traceback -from typing import Any, Iterable, Iterator, Tuple, Union - -from airbyte_cdk.models import AirbyteRecordMessage, AirbyteStream - - -def format_exception(exception: Exception) -> str: - return str(exception) + "\n" + "".join(traceback.TracebackException.from_exception(exception).format()) - - -def create_chunks(iterable: Iterable[Any], batch_size: int) -> Iterator[Tuple[Any, ...]]: - """A helper function to break an iterable into chunks of size batch_size.""" - it = iter(iterable) - chunk = tuple(itertools.islice(it, batch_size)) - while chunk: - yield chunk - chunk = tuple(itertools.islice(it, batch_size)) - - -def create_stream_identifier(stream: Union[AirbyteStream, AirbyteRecordMessage]) -> str: - if isinstance(stream, AirbyteStream): - return str(stream.name if stream.namespace is None else f"{stream.namespace}_{stream.name}") - else: - return str(stream.stream if stream.namespace is None else f"{stream.namespace}_{stream.stream}") diff --git a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/writer.py b/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/writer.py deleted file mode 100644 index 0f764c366b54..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/destinations/vector_db_based/writer.py +++ /dev/null @@ -1,85 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from collections import defaultdict -from typing import Dict, Iterable, List, Tuple - -from airbyte_cdk.destinations.vector_db_based.config import ProcessingConfigModel -from airbyte_cdk.destinations.vector_db_based.document_processor import Chunk, DocumentProcessor -from airbyte_cdk.destinations.vector_db_based.embedder import Document, Embedder -from airbyte_cdk.destinations.vector_db_based.indexer import Indexer -from airbyte_cdk.models import AirbyteMessage, ConfiguredAirbyteCatalog, Type - - -class Writer: - """ - The Writer class is orchestrating the document processor, the embedder and the indexer: - * Incoming records are passed through the document processor to generate chunks - * One the configured batch size is reached, the chunks are passed to the embedder to generate embeddings - * The embedder embeds the chunks - * The indexer deletes old chunks by the associated record id before indexing the new ones - - The destination connector is responsible to create a writer instance and pass the input messages iterable to the write method. - The batch size can be configured by the destination connector to give the freedom of either letting the user configure it or hardcoding it to a sensible value depending on the destination. - The omit_raw_text parameter can be used to omit the raw text from the chunks. This can be useful if the raw text is very large and not needed for the destination. - """ - - def __init__( - self, processing_config: ProcessingConfigModel, indexer: Indexer, embedder: Embedder, batch_size: int, omit_raw_text: bool - ) -> None: - self.processing_config = processing_config - self.indexer = indexer - self.embedder = embedder - self.batch_size = batch_size - self.omit_raw_text = omit_raw_text - self._init_batch() - - def _init_batch(self) -> None: - self.chunks: Dict[Tuple[str, str], List[Chunk]] = defaultdict(list) - self.ids_to_delete: Dict[Tuple[str, str], List[str]] = defaultdict(list) - self.number_of_chunks = 0 - - def _convert_to_document(self, chunk: Chunk) -> Document: - """ - Convert a chunk to a document for the embedder. - """ - if chunk.page_content is None: - raise ValueError("Cannot embed a chunk without page content") - return Document(page_content=chunk.page_content, record=chunk.record) - - def _process_batch(self) -> None: - for (namespace, stream), ids in self.ids_to_delete.items(): - self.indexer.delete(ids, namespace, stream) - - for (namespace, stream), chunks in self.chunks.items(): - embeddings = self.embedder.embed_documents([self._convert_to_document(chunk) for chunk in chunks]) - for i, document in enumerate(chunks): - document.embedding = embeddings[i] - if self.omit_raw_text: - document.page_content = None - self.indexer.index(chunks, namespace, stream) - - self._init_batch() - - def write(self, configured_catalog: ConfiguredAirbyteCatalog, input_messages: Iterable[AirbyteMessage]) -> Iterable[AirbyteMessage]: - self.processor = DocumentProcessor(self.processing_config, configured_catalog) - self.indexer.pre_sync(configured_catalog) - for message in input_messages: - if message.type == Type.STATE: - # Emitting a state message indicates that all records which came before it have been written to the destination. So we flush - # the queue to ensure writes happen, then output the state message to indicate it's safe to checkpoint state - self._process_batch() - yield message - elif message.type == Type.RECORD: - record_chunks, record_id_to_delete = self.processor.process(message.record) - self.chunks[(message.record.namespace, message.record.stream)].extend(record_chunks) - if record_id_to_delete is not None: - self.ids_to_delete[(message.record.namespace, message.record.stream)].append(record_id_to_delete) - self.number_of_chunks += len(record_chunks) - if self.number_of_chunks >= self.batch_size: - self._process_batch() - - self._process_batch() - yield from self.indexer.post_sync() diff --git a/airbyte-cdk/python/airbyte_cdk/entrypoint.py b/airbyte-cdk/python/airbyte_cdk/entrypoint.py deleted file mode 100644 index 945d28405336..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/entrypoint.py +++ /dev/null @@ -1,334 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import argparse -import importlib -import ipaddress -import logging -import os.path -import socket -import sys -import tempfile -from collections import defaultdict -from functools import wraps -from typing import Any, DefaultDict, Iterable, List, Mapping, Optional -from urllib.parse import urlparse - -import requests -from airbyte_cdk.connector import TConfig -from airbyte_cdk.exception_handler import init_uncaught_exception_handler -from airbyte_cdk.logger import init_logger -from airbyte_cdk.models import ( # type: ignore [attr-defined] - AirbyteConnectionStatus, - AirbyteMessage, - AirbyteMessageSerializer, - AirbyteStateStats, - ConnectorSpecification, - FailureType, - Status, - Type, -) -from airbyte_cdk.sources import Source -from airbyte_cdk.sources.connector_state_manager import HashableStreamDescriptor -from airbyte_cdk.sources.utils.schema_helpers import check_config_against_spec_or_exit, split_config - -# from airbyte_cdk.utils import PrintBuffer, is_cloud_environment, message_utils # add PrintBuffer back once fixed -from airbyte_cdk.utils import is_cloud_environment, message_utils -from airbyte_cdk.utils.airbyte_secrets_utils import get_secrets, update_secrets -from airbyte_cdk.utils.constants import ENV_REQUEST_CACHE_PATH -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from orjson import orjson -from requests import PreparedRequest, Response, Session - -logger = init_logger("airbyte") - -VALID_URL_SCHEMES = ["https"] -CLOUD_DEPLOYMENT_MODE = "cloud" - - -class AirbyteEntrypoint(object): - def __init__(self, source: Source): - init_uncaught_exception_handler(logger) - - # Deployment mode is read when instantiating the entrypoint because it is the common path shared by syncs and connector builder test requests - if is_cloud_environment(): - _init_internal_request_filter() - - self.source = source - self.logger = logging.getLogger(f"airbyte.{getattr(source, 'name', '')}") - - @staticmethod - def parse_args(args: List[str]) -> argparse.Namespace: - # set up parent parsers - parent_parser = argparse.ArgumentParser(add_help=False) - parent_parser.add_argument("--debug", action="store_true", help="enables detailed debug logs related to the sync") - main_parser = argparse.ArgumentParser() - subparsers = main_parser.add_subparsers(title="commands", dest="command") - - # spec - subparsers.add_parser("spec", help="outputs the json configuration specification", parents=[parent_parser]) - - # check - check_parser = subparsers.add_parser("check", help="checks the config can be used to connect", parents=[parent_parser]) - required_check_parser = check_parser.add_argument_group("required named arguments") - required_check_parser.add_argument("--config", type=str, required=True, help="path to the json configuration file") - - # discover - discover_parser = subparsers.add_parser( - "discover", help="outputs a catalog describing the source's schema", parents=[parent_parser] - ) - required_discover_parser = discover_parser.add_argument_group("required named arguments") - required_discover_parser.add_argument("--config", type=str, required=True, help="path to the json configuration file") - - # read - read_parser = subparsers.add_parser("read", help="reads the source and outputs messages to STDOUT", parents=[parent_parser]) - - read_parser.add_argument("--state", type=str, required=False, help="path to the json-encoded state file") - required_read_parser = read_parser.add_argument_group("required named arguments") - required_read_parser.add_argument("--config", type=str, required=True, help="path to the json configuration file") - required_read_parser.add_argument( - "--catalog", type=str, required=True, help="path to the catalog used to determine which data to read" - ) - - return main_parser.parse_args(args) - - def run(self, parsed_args: argparse.Namespace) -> Iterable[str]: - cmd = parsed_args.command - if not cmd: - raise Exception("No command passed") - - if hasattr(parsed_args, "debug") and parsed_args.debug: - self.logger.setLevel(logging.DEBUG) - logger.setLevel(logging.DEBUG) - self.logger.debug("Debug logs enabled") - else: - self.logger.setLevel(logging.INFO) - - source_spec: ConnectorSpecification = self.source.spec(self.logger) - try: - with tempfile.TemporaryDirectory() as temp_dir: - os.environ[ENV_REQUEST_CACHE_PATH] = temp_dir # set this as default directory for request_cache to store *.sqlite files - if cmd == "spec": - message = AirbyteMessage(type=Type.SPEC, spec=source_spec) - yield from [ - self.airbyte_message_to_string(queued_message) for queued_message in self._emit_queued_messages(self.source) - ] - yield self.airbyte_message_to_string(message) - else: - raw_config = self.source.read_config(parsed_args.config) - config = self.source.configure(raw_config, temp_dir) - - yield from [ - self.airbyte_message_to_string(queued_message) for queued_message in self._emit_queued_messages(self.source) - ] - if cmd == "check": - yield from map(AirbyteEntrypoint.airbyte_message_to_string, self.check(source_spec, config)) - elif cmd == "discover": - yield from map(AirbyteEntrypoint.airbyte_message_to_string, self.discover(source_spec, config)) - elif cmd == "read": - config_catalog = self.source.read_catalog(parsed_args.catalog) - state = self.source.read_state(parsed_args.state) - - yield from map(AirbyteEntrypoint.airbyte_message_to_string, self.read(source_spec, config, config_catalog, state)) - else: - raise Exception("Unexpected command " + cmd) - finally: - yield from [self.airbyte_message_to_string(queued_message) for queued_message in self._emit_queued_messages(self.source)] - - def check(self, source_spec: ConnectorSpecification, config: TConfig) -> Iterable[AirbyteMessage]: - self.set_up_secret_filter(config, source_spec.connectionSpecification) - try: - self.validate_connection(source_spec, config) - except AirbyteTracedException as traced_exc: - connection_status = traced_exc.as_connection_status_message() - # The platform uses the exit code to surface unexpected failures so we raise the exception if the failure type not a config error - # If the failure is not exceptional, we'll emit a failed connection status message and return - if traced_exc.failure_type != FailureType.config_error: - raise traced_exc - if connection_status: - yield from self._emit_queued_messages(self.source) - yield connection_status - return - - try: - check_result = self.source.check(self.logger, config) - except AirbyteTracedException as traced_exc: - yield traced_exc.as_airbyte_message() - # The platform uses the exit code to surface unexpected failures so we raise the exception if the failure type not a config error - # If the failure is not exceptional, we'll emit a failed connection status message and return - if traced_exc.failure_type != FailureType.config_error: - raise traced_exc - else: - yield AirbyteMessage( - type=Type.CONNECTION_STATUS, connectionStatus=AirbyteConnectionStatus(status=Status.FAILED, message=traced_exc.message) - ) - return - if check_result.status == Status.SUCCEEDED: - self.logger.info("Check succeeded") - else: - self.logger.error("Check failed") - - yield from self._emit_queued_messages(self.source) - yield AirbyteMessage(type=Type.CONNECTION_STATUS, connectionStatus=check_result) - - def discover(self, source_spec: ConnectorSpecification, config: TConfig) -> Iterable[AirbyteMessage]: - self.set_up_secret_filter(config, source_spec.connectionSpecification) - if self.source.check_config_against_spec: - self.validate_connection(source_spec, config) - catalog = self.source.discover(self.logger, config) - - yield from self._emit_queued_messages(self.source) - yield AirbyteMessage(type=Type.CATALOG, catalog=catalog) - - def read(self, source_spec: ConnectorSpecification, config: TConfig, catalog: Any, state: list[Any]) -> Iterable[AirbyteMessage]: - self.set_up_secret_filter(config, source_spec.connectionSpecification) - if self.source.check_config_against_spec: - self.validate_connection(source_spec, config) - - # The Airbyte protocol dictates that counts be expressed as float/double to better protect against integer overflows - stream_message_counter: DefaultDict[HashableStreamDescriptor, float] = defaultdict(float) - for message in self.source.read(self.logger, config, catalog, state): - yield self.handle_record_counts(message, stream_message_counter) - for message in self._emit_queued_messages(self.source): - yield self.handle_record_counts(message, stream_message_counter) - - @staticmethod - def handle_record_counts(message: AirbyteMessage, stream_message_count: DefaultDict[HashableStreamDescriptor, float]) -> AirbyteMessage: - match message.type: - case Type.RECORD: - stream_message_count[HashableStreamDescriptor(name=message.record.stream, namespace=message.record.namespace)] += 1.0 # type: ignore[union-attr] # record has `stream` and `namespace` - case Type.STATE: - stream_descriptor = message_utils.get_stream_descriptor(message) - - # Set record count from the counter onto the state message - message.state.sourceStats = message.state.sourceStats or AirbyteStateStats() # type: ignore[union-attr] # state has `sourceStats` - message.state.sourceStats.recordCount = stream_message_count.get(stream_descriptor, 0.0) # type: ignore[union-attr] # state has `sourceStats` - - # Reset the counter - stream_message_count[stream_descriptor] = 0.0 - return message - - @staticmethod - def validate_connection(source_spec: ConnectorSpecification, config: TConfig) -> None: - # Remove internal flags from config before validating so - # jsonschema's additionalProperties flag won't fail the validation - connector_config, _ = split_config(config) - check_config_against_spec_or_exit(connector_config, source_spec) - - @staticmethod - def set_up_secret_filter(config: TConfig, connection_specification: Mapping[str, Any]) -> None: - # Now that we have the config, we can use it to get a list of ai airbyte_secrets - # that we should filter in logging to avoid leaking secrets - config_secrets = get_secrets(connection_specification, config) - update_secrets(config_secrets) - - @staticmethod - def airbyte_message_to_string(airbyte_message: AirbyteMessage) -> str: - return orjson.dumps(AirbyteMessageSerializer.dump(airbyte_message)).decode() # type: ignore[no-any-return] # orjson.dumps(message).decode() always returns string - - @classmethod - def extract_state(cls, args: List[str]) -> Optional[Any]: - parsed_args = cls.parse_args(args) - if hasattr(parsed_args, "state"): - return parsed_args.state - return None - - @classmethod - def extract_catalog(cls, args: List[str]) -> Optional[Any]: - parsed_args = cls.parse_args(args) - if hasattr(parsed_args, "catalog"): - return parsed_args.catalog - return None - - @classmethod - def extract_config(cls, args: List[str]) -> Optional[Any]: - parsed_args = cls.parse_args(args) - if hasattr(parsed_args, "config"): - return parsed_args.config - return None - - def _emit_queued_messages(self, source: Source) -> Iterable[AirbyteMessage]: - if hasattr(source, "message_repository") and source.message_repository: - yield from source.message_repository.consume_queue() - return - - -def launch(source: Source, args: List[str]) -> None: - source_entrypoint = AirbyteEntrypoint(source) - parsed_args = source_entrypoint.parse_args(args) - # temporarily removes the PrintBuffer because we're seeing weird print behavior for concurrent syncs - # Refer to: https://github.com/airbytehq/oncall/issues/6235 - # with PrintBuffer(): - for message in source_entrypoint.run(parsed_args): - # simply printing is creating issues for concurrent CDK as Python uses different two instructions to print: one for the message and - # the other for the break line. Adding `\n` to the message ensure that both are printed at the same time - print(f"{message}\n", end="", flush=True) - - -def _init_internal_request_filter() -> None: - """ - Wraps the Python requests library to prevent sending requests to internal URL endpoints. - """ - wrapped_fn = Session.send - - @wraps(wrapped_fn) - def filtered_send(self: Any, request: PreparedRequest, **kwargs: Any) -> Response: - parsed_url = urlparse(request.url) - - if parsed_url.scheme not in VALID_URL_SCHEMES: - raise requests.exceptions.InvalidSchema( - "Invalid Protocol Scheme: The endpoint that data is being requested from is using an invalid or insecure " - + f"protocol {parsed_url.scheme!r}. Valid protocol schemes: {','.join(VALID_URL_SCHEMES)}" - ) - - if not parsed_url.hostname: - raise requests.exceptions.InvalidURL("Invalid URL specified: The endpoint that data is being requested from is not a valid URL") - - try: - is_private = _is_private_url(parsed_url.hostname, parsed_url.port) # type: ignore [arg-type] - if is_private: - raise AirbyteTracedException( - internal_message=f"Invalid URL endpoint: `{parsed_url.hostname!r}` belongs to a private network", - failure_type=FailureType.config_error, - message="Invalid URL endpoint: The endpoint that data is being requested from belongs to a private network. Source connectors only support requesting data from public API endpoints.", - ) - except socket.gaierror as exception: - # This is a special case where the developer specifies an IP address string that is not formatted correctly like trailing - # whitespace which will fail the socket IP lookup. This only happens when using IP addresses and not text hostnames. - # Knowing that this is a request using the requests library, we will mock the exception without calling the lib - raise requests.exceptions.InvalidURL(f"Invalid URL {parsed_url}: {exception}") - - return wrapped_fn(self, request, **kwargs) - - Session.send = filtered_send # type: ignore [method-assign] - - -def _is_private_url(hostname: str, port: int) -> bool: - """ - Helper method that checks if any of the IP addresses associated with a hostname belong to a private network. - """ - address_info_entries = socket.getaddrinfo(hostname, port) - for entry in address_info_entries: - # getaddrinfo() returns entries in the form of a 5-tuple where the IP is stored as the sockaddr. For IPv4 this - # is a 2-tuple and for IPv6 it is a 4-tuple, but the address is always the first value of the tuple at 0. - # See https://docs.python.org/3/library/socket.html#socket.getaddrinfo for more details. - ip_address = entry[4][0] - if ipaddress.ip_address(ip_address).is_private: - return True - return False - - -def main() -> None: - impl_module = os.environ.get("AIRBYTE_IMPL_MODULE", Source.__module__) - impl_class = os.environ.get("AIRBYTE_IMPL_PATH", Source.__name__) - module = importlib.import_module(impl_module) - impl = getattr(module, impl_class) - - # set up and run entrypoint - source = impl() - - if not isinstance(source, Source): - raise Exception("Source implementation provided does not implement Source class!") - - launch(source, sys.argv[1:]) diff --git a/airbyte-cdk/python/airbyte_cdk/exception_handler.py b/airbyte-cdk/python/airbyte_cdk/exception_handler.py deleted file mode 100644 index 77fa88989378..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/exception_handler.py +++ /dev/null @@ -1,46 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -import sys -from types import TracebackType -from typing import Any, List, Mapping, Optional - -from airbyte_cdk.utils.airbyte_secrets_utils import filter_secrets -from airbyte_cdk.utils.traced_exception import AirbyteTracedException - - -def assemble_uncaught_exception(exception_type: type[BaseException], exception_value: BaseException) -> AirbyteTracedException: - if issubclass(exception_type, AirbyteTracedException): - return exception_value # type: ignore # validated as part of the previous line - return AirbyteTracedException.from_exception(exception_value) - - -def init_uncaught_exception_handler(logger: logging.Logger) -> None: - """ - Handles uncaught exceptions by emitting an AirbyteTraceMessage and making sure they are not - printed to the console without having secrets removed. - """ - - def hook_fn(exception_type: type[BaseException], exception_value: BaseException, traceback_: Optional[TracebackType]) -> Any: - # For developer ergonomics, we want to see the stack trace in the logs when we do a ctrl-c - if issubclass(exception_type, KeyboardInterrupt): - sys.__excepthook__(exception_type, exception_value, traceback_) - return - - logger.fatal(exception_value, exc_info=exception_value) - - # emit an AirbyteTraceMessage for any exception that gets to this spot - traced_exc = assemble_uncaught_exception(exception_type, exception_value) - - traced_exc.emit_message() - - sys.excepthook = hook_fn - - -def generate_failed_streams_error_message(stream_failures: Mapping[str, List[Exception]]) -> str: - failures = "\n".join( - [f"{stream}: {filter_secrets(exception.__repr__())}" for stream, exceptions in stream_failures.items() for exception in exceptions] - ) - return f"During the sync, the following streams did not sync successfully: {failures}" diff --git a/airbyte-cdk/python/airbyte_cdk/logger.py b/airbyte-cdk/python/airbyte_cdk/logger.py deleted file mode 100644 index 59d4d7dd68d3..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/logger.py +++ /dev/null @@ -1,97 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import logging -import logging.config -from typing import Any, Callable, Mapping, Optional, Tuple - -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, AirbyteMessageSerializer, Level, Type -from airbyte_cdk.utils.airbyte_secrets_utils import filter_secrets -from orjson import orjson - -LOGGING_CONFIG = { - "version": 1, - "disable_existing_loggers": False, - "formatters": { - "airbyte": {"()": "airbyte_cdk.logger.AirbyteLogFormatter", "format": "%(message)s"}, - }, - "handlers": { - "console": { - "class": "logging.StreamHandler", - "stream": "ext://sys.stdout", - "formatter": "airbyte", - }, - }, - "root": { - "handlers": ["console"], - }, -} - - -def init_logger(name: Optional[str] = None) -> logging.Logger: - """Initial set up of logger""" - logger = logging.getLogger(name) - logger.setLevel(logging.INFO) - logging.config.dictConfig(LOGGING_CONFIG) - return logger - - -def lazy_log(logger: logging.Logger, level: int, lazy_log_provider: Callable[[], str]) -> None: - """ - This method ensure that the processing of the log message is only done if the logger is enabled for the log level. - """ - if logger.isEnabledFor(level): - logger.log(level, lazy_log_provider()) - - -class AirbyteLogFormatter(logging.Formatter): - """Output log records using AirbyteMessage""" - - # Transforming Python log levels to Airbyte protocol log levels - level_mapping = { - logging.FATAL: Level.FATAL, - logging.ERROR: Level.ERROR, - logging.WARNING: Level.WARN, - logging.INFO: Level.INFO, - logging.DEBUG: Level.DEBUG, - } - - def format(self, record: logging.LogRecord) -> str: - """Return a JSON representation of the log message""" - airbyte_level = self.level_mapping.get(record.levelno, "INFO") - if airbyte_level == Level.DEBUG: - extras = self.extract_extra_args_from_record(record) - debug_dict = {"type": "DEBUG", "message": record.getMessage(), "data": extras} - return filter_secrets(json.dumps(debug_dict)) - else: - message = super().format(record) - message = filter_secrets(message) - log_message = AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=airbyte_level, message=message)) - return orjson.dumps(AirbyteMessageSerializer.dump(log_message)).decode() # type: ignore[no-any-return] # orjson.dumps(message).decode() always returns string - - @staticmethod - def extract_extra_args_from_record(record: logging.LogRecord) -> Mapping[str, Any]: - """ - The python logger conflates default args with extra args. We use an empty log record and set operations - to isolate fields passed to the log record via extra by the developer. - """ - default_attrs = logging.LogRecord("", 0, "", 0, None, None, None).__dict__.keys() - extra_keys = set(record.__dict__.keys()) - default_attrs - return {k: str(getattr(record, k)) for k in extra_keys if hasattr(record, k)} - - -def log_by_prefix(msg: str, default_level: str) -> Tuple[int, str]: - """Custom method, which takes log level from first word of message""" - valid_log_types = ["FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"] - split_line = msg.split() - first_word = next(iter(split_line), None) - if first_word in valid_log_types: - log_level = logging.getLevelName(first_word) - rendered_message = " ".join(split_line[1:]) - else: - log_level = logging.getLevelName(default_level) - rendered_message = msg - - return log_level, rendered_message diff --git a/airbyte-cdk/python/airbyte_cdk/models/__init__.py b/airbyte-cdk/python/airbyte_cdk/models/__init__.py deleted file mode 100644 index c56df9adc43a..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/models/__init__.py +++ /dev/null @@ -1,70 +0,0 @@ -# The earlier versions of airbyte-cdk (0.28.0<=) had the airbyte_protocol python classes -# declared inline in the airbyte-cdk code. However, somewhere around Feb 2023 the -# Airbyte Protocol moved to its own repo/PyPi package, called airbyte-protocol-models. -# This directory including the airbyte_protocol.py and well_known_types.py files -# are just wrappers on top of that stand-alone package which do some namespacing magic -# to make the airbyte_protocol python classes available to the airbyte-cdk consumer as part -# of airbyte-cdk rather than a standalone package. -from .airbyte_protocol import ( - AdvancedAuth, - AirbyteStateStats, - AirbyteAnalyticsTraceMessage, - AirbyteCatalog, - AirbyteConnectionStatus, - AirbyteControlConnectorConfigMessage, - AirbyteControlMessage, - AirbyteErrorTraceMessage, - AirbyteEstimateTraceMessage, - AirbyteGlobalState, - AirbyteLogMessage, - AirbyteMessage, - AirbyteProtocol, - AirbyteRecordMessage, - AirbyteStateBlob, - AirbyteStateMessage, - AirbyteStateType, - AirbyteStream, - AirbyteStreamState, - AirbyteStreamStatus, - AirbyteStreamStatusTraceMessage, - AirbyteStreamStatusReason, - AirbyteStreamStatusReasonType, - AirbyteTraceMessage, - AuthFlowType, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteStream, - ConnectorSpecification, - DestinationSyncMode, - EstimateType, - FailureType, - Level, - OAuthConfigSpecification, - OrchestratorType, - Status, - StreamDescriptor, - SyncMode, - TraceType, - Type, -) -from .well_known_types import ( - BinaryData, - Boolean, - Date, - Integer, - Model, - Number, - String, - TimestampWithoutTimezone, - TimestampWithTimezone, - TimeWithoutTimezone, - TimeWithTimezone, -) - -from .airbyte_protocol_serializers import ( -AirbyteStreamStateSerializer, -AirbyteStateMessageSerializer, -AirbyteMessageSerializer, -ConfiguredAirbyteCatalogSerializer, -ConfiguredAirbyteStreamSerializer, -ConnectorSpecificationSerializer, -) \ No newline at end of file diff --git a/airbyte-cdk/python/airbyte_cdk/models/airbyte_protocol.py b/airbyte-cdk/python/airbyte_cdk/models/airbyte_protocol.py deleted file mode 100644 index 477cfb8a66fd..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/models/airbyte_protocol.py +++ /dev/null @@ -1,82 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Annotated, Any, Dict, List, Mapping, Optional - -from airbyte_protocol_dataclasses.models import * -from serpyco_rs.metadata import Alias - - -@dataclass -class AirbyteStateBlob: - """ - A dataclass that dynamically sets attributes based on provided keyword arguments and positional arguments. - Used to "mimic" pydantic Basemodel with ConfigDict(extra='allow') option. - - The `AirbyteStateBlob` class allows for flexible instantiation by accepting any number of keyword arguments - and positional arguments. These are used to dynamically update the instance's attributes. This class is useful - in scenarios where the attributes of an object are not known until runtime and need to be set dynamically. - - Attributes: - kwargs (InitVar[Mapping[str, Any]]): A dictionary of keyword arguments used to set attributes dynamically. - - Methods: - __init__(*args: Any, **kwargs: Any) -> None: - Initializes the `AirbyteStateBlob` by setting attributes from the provided arguments. - - __eq__(other: object) -> bool: - Checks equality between two `AirbyteStateBlob` instances based on their internal dictionaries. - Returns `False` if the other object is not an instance of `AirbyteStateBlob`. - """ - - kwargs: InitVar[Mapping[str, Any]] - - def __init__(self, *args: Any, **kwargs: Any) -> None: - # Set any attribute passed in through kwargs - for arg in args: - self.__dict__.update(arg) - for key, value in kwargs.items(): - setattr(self, key, value) - - def __eq__(self, other: object) -> bool: - return False if not isinstance(other, AirbyteStateBlob) else bool(self.__dict__ == other.__dict__) - - -# The following dataclasses have been redeclared to include the new version of AirbyteStateBlob -@dataclass -class AirbyteStreamState: - stream_descriptor: StreamDescriptor # type: ignore [name-defined] - stream_state: Optional[AirbyteStateBlob] = None - - -@dataclass -class AirbyteGlobalState: - stream_states: List[AirbyteStreamState] - shared_state: Optional[AirbyteStateBlob] = None - - -@dataclass -class AirbyteStateMessage: - type: Optional[AirbyteStateType] = None # type: ignore [name-defined] - stream: Optional[AirbyteStreamState] = None - global_: Annotated[ - AirbyteGlobalState | None, Alias("global") - ] = None # "global" is a reserved keyword in python ⇒ Alias is used for (de-)serialization - data: Optional[Dict[str, Any]] = None - sourceStats: Optional[AirbyteStateStats] = None # type: ignore [name-defined] - destinationStats: Optional[AirbyteStateStats] = None # type: ignore [name-defined] - - -@dataclass -class AirbyteMessage: - type: Type # type: ignore [name-defined] - log: Optional[AirbyteLogMessage] = None # type: ignore [name-defined] - spec: Optional[ConnectorSpecification] = None # type: ignore [name-defined] - connectionStatus: Optional[AirbyteConnectionStatus] = None # type: ignore [name-defined] - catalog: Optional[AirbyteCatalog] = None # type: ignore [name-defined] - record: Optional[AirbyteRecordMessage] = None # type: ignore [name-defined] - state: Optional[AirbyteStateMessage] = None - trace: Optional[AirbyteTraceMessage] = None # type: ignore [name-defined] - control: Optional[AirbyteControlMessage] = None # type: ignore [name-defined] diff --git a/airbyte-cdk/python/airbyte_cdk/models/airbyte_protocol_serializers.py b/airbyte-cdk/python/airbyte_cdk/models/airbyte_protocol_serializers.py deleted file mode 100644 index aeac43f794ce..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/models/airbyte_protocol_serializers.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -from typing import Any, Dict - -from serpyco_rs import CustomType, Serializer - -from .airbyte_protocol import ( # type: ignore[attr-defined] # all classes are imported to airbyte_protocol via * - AirbyteMessage, - AirbyteStateBlob, - AirbyteStateMessage, - AirbyteStreamState, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteStream, - ConnectorSpecification, -) - - -class AirbyteStateBlobType(CustomType[AirbyteStateBlob, Dict[str, Any]]): - def serialize(self, value: AirbyteStateBlob) -> Dict[str, Any]: - # cant use orjson.dumps() directly because private attributes are excluded, e.g. "__ab_full_refresh_sync_complete" - return {k: v for k, v in value.__dict__.items()} - - def deserialize(self, value: Dict[str, Any]) -> AirbyteStateBlob: - return AirbyteStateBlob(value) - - def get_json_schema(self) -> Dict[str, Any]: - return {"type": "object"} - - -def custom_type_resolver(t: type) -> CustomType[AirbyteStateBlob, Dict[str, Any]] | None: - return AirbyteStateBlobType() if t is AirbyteStateBlob else None - - -AirbyteStreamStateSerializer = Serializer(AirbyteStreamState, omit_none=True, custom_type_resolver=custom_type_resolver) -AirbyteStateMessageSerializer = Serializer(AirbyteStateMessage, omit_none=True, custom_type_resolver=custom_type_resolver) -AirbyteMessageSerializer = Serializer(AirbyteMessage, omit_none=True, custom_type_resolver=custom_type_resolver) -ConfiguredAirbyteCatalogSerializer = Serializer(ConfiguredAirbyteCatalog, omit_none=True) -ConfiguredAirbyteStreamSerializer = Serializer(ConfiguredAirbyteStream, omit_none=True) -ConnectorSpecificationSerializer = Serializer(ConnectorSpecification, omit_none=True) diff --git a/airbyte-cdk/python/airbyte_cdk/models/well_known_types.py b/airbyte-cdk/python/airbyte_cdk/models/well_known_types.py deleted file mode 100644 index a063ad7db03a..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/models/well_known_types.py +++ /dev/null @@ -1,5 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_protocol_dataclasses.models.well_known_types import * diff --git a/airbyte-cdk/python/airbyte_cdk/py.typed b/airbyte-cdk/python/airbyte_cdk/py.typed deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/airbyte_cdk/sources/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/__init__.py deleted file mode 100644 index 396513539fcd..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# - -import dpath.options - -from .abstract_source import AbstractSource -from .config import BaseConfig -from .source import Source - -# As part of the CDK sources, we do not control what the APIs return and it is possible that a key is empty. -# Reasons why we are doing this at the airbyte_cdk level: -# * As of today, all the use cases should allow for empty keys -# * Cases as of 2023-08-31: oauth/session token provider responses, extractor, transformation and substream) -# * The behavior is explicit at the package level and not hidden in every package that needs dpath.options.ALLOW_EMPTY_STRING_KEYS = True -# There is a downside in enforcing this option preemptively in the module __init__.py: the runtime code will import dpath even though the it -# might not need dpath leading to longer initialization time. -# There is a downside in using dpath as a library since the options are global: if we have two pieces of code that want different options, -# this will not be thread-safe. -dpath.options.ALLOW_EMPTY_STRING_KEYS = True - -__all__ = ["AbstractSource", "BaseConfig", "Source"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/abstract_source.py b/airbyte-cdk/python/airbyte_cdk/sources/abstract_source.py deleted file mode 100644 index 3656a88c3157..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/abstract_source.py +++ /dev/null @@ -1,280 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from abc import ABC, abstractmethod -from typing import Any, Dict, Iterable, Iterator, List, Mapping, MutableMapping, Optional, Tuple, Union - -from airbyte_cdk.exception_handler import generate_failed_streams_error_message -from airbyte_cdk.models import ( - AirbyteCatalog, - AirbyteConnectionStatus, - AirbyteMessage, - AirbyteStateMessage, - AirbyteStreamStatus, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteStream, - FailureType, - Status, - StreamDescriptor, -) -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager -from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository -from airbyte_cdk.sources.source import Source -from airbyte_cdk.sources.streams import Stream -from airbyte_cdk.sources.streams.core import StreamData -from airbyte_cdk.sources.streams.http.http import HttpStream -from airbyte_cdk.sources.utils.record_helper import stream_data_to_airbyte_message -from airbyte_cdk.sources.utils.schema_helpers import InternalConfig, split_config -from airbyte_cdk.sources.utils.slice_logger import DebugSliceLogger, SliceLogger -from airbyte_cdk.utils.event_timing import create_timer -from airbyte_cdk.utils.stream_status_utils import as_airbyte_message as stream_status_as_airbyte_message -from airbyte_cdk.utils.traced_exception import AirbyteTracedException - -_default_message_repository = InMemoryMessageRepository() - - -class AbstractSource(Source, ABC): - """ - Abstract base class for an Airbyte Source. Consumers should implement any abstract methods - in this class to create an Airbyte Specification compliant Source. - """ - - @abstractmethod - def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Optional[Any]]: - """ - :param logger: source logger - :param config: The user-provided configuration as specified by the source's spec. - This usually contains information required to check connection e.g. tokens, secrets and keys etc. - :return: A tuple of (boolean, error). If boolean is true, then the connection check is successful - and we can connect to the underlying data source using the provided configuration. - Otherwise, the input config cannot be used to connect to the underlying data source, - and the "error" object should describe what went wrong. - The error object will be cast to string to display the problem to the user. - """ - - @abstractmethod - def streams(self, config: Mapping[str, Any]) -> List[Stream]: - """ - :param config: The user-provided configuration as specified by the source's spec. - Any stream construction related operation should happen here. - :return: A list of the streams in this source connector. - """ - - # Stream name to instance map for applying output object transformation - _stream_to_instance_map: Dict[str, Stream] = {} - _slice_logger: SliceLogger = DebugSliceLogger() - - def discover(self, logger: logging.Logger, config: Mapping[str, Any]) -> AirbyteCatalog: - """Implements the Discover operation from the Airbyte Specification. - See https://docs.airbyte.com/understanding-airbyte/airbyte-protocol/#discover. - """ - streams = [stream.as_airbyte_stream() for stream in self.streams(config=config)] - return AirbyteCatalog(streams=streams) - - def check(self, logger: logging.Logger, config: Mapping[str, Any]) -> AirbyteConnectionStatus: - """Implements the Check Connection operation from the Airbyte Specification. - See https://docs.airbyte.com/understanding-airbyte/airbyte-protocol/#check. - """ - check_succeeded, error = self.check_connection(logger, config) - if not check_succeeded: - return AirbyteConnectionStatus(status=Status.FAILED, message=repr(error)) - return AirbyteConnectionStatus(status=Status.SUCCEEDED) - - def read( - self, - logger: logging.Logger, - config: Mapping[str, Any], - catalog: ConfiguredAirbyteCatalog, - state: Optional[List[AirbyteStateMessage]] = None, - ) -> Iterator[AirbyteMessage]: - """Implements the Read operation from the Airbyte Specification. See https://docs.airbyte.com/understanding-airbyte/airbyte-protocol/.""" - logger.info(f"Starting syncing {self.name}") - config, internal_config = split_config(config) - # TODO assert all streams exist in the connector - # get the streams once in case the connector needs to make any queries to generate them - stream_instances = {s.name: s for s in self.streams(config)} - state_manager = ConnectorStateManager(state=state) - self._stream_to_instance_map = stream_instances - - stream_name_to_exception: MutableMapping[str, AirbyteTracedException] = {} - - with create_timer(self.name) as timer: - for configured_stream in catalog.streams: - stream_instance = stream_instances.get(configured_stream.stream.name) - is_stream_exist = bool(stream_instance) - try: - # Used direct reference to `stream_instance` instead of `is_stream_exist` to avoid mypy type checking errors - if not stream_instance: - if not self.raise_exception_on_missing_stream: - yield stream_status_as_airbyte_message(configured_stream.stream, AirbyteStreamStatus.INCOMPLETE) - continue - - error_message = ( - f"The stream '{configured_stream.stream.name}' in your connection configuration was not found in the source. " - f"Refresh the schema in your replication settings and remove this stream from future sync attempts." - ) - - # Use configured_stream as stream_instance to support references in error handling. - stream_instance = configured_stream.stream - - raise AirbyteTracedException( - message="A stream listed in your configuration was not found in the source. Please check the logs for more " - "details.", - internal_message=error_message, - failure_type=FailureType.config_error, - ) - - timer.start_event(f"Syncing stream {configured_stream.stream.name}") - logger.info(f"Marking stream {configured_stream.stream.name} as STARTED") - yield stream_status_as_airbyte_message(configured_stream.stream, AirbyteStreamStatus.STARTED) - yield from self._read_stream( - logger=logger, - stream_instance=stream_instance, - configured_stream=configured_stream, - state_manager=state_manager, - internal_config=internal_config, - ) - logger.info(f"Marking stream {configured_stream.stream.name} as STOPPED") - yield stream_status_as_airbyte_message(configured_stream.stream, AirbyteStreamStatus.COMPLETE) - - except Exception as e: - yield from self._emit_queued_messages() - logger.exception(f"Encountered an exception while reading stream {configured_stream.stream.name}") - logger.info(f"Marking stream {configured_stream.stream.name} as STOPPED") - yield stream_status_as_airbyte_message(configured_stream.stream, AirbyteStreamStatus.INCOMPLETE) - - stream_descriptor = StreamDescriptor(name=configured_stream.stream.name) - - if isinstance(e, AirbyteTracedException): - traced_exception = e - info_message = f"Stopping sync on error from stream {configured_stream.stream.name} because {self.name} does not support continuing syncs on error." - else: - traced_exception = self._serialize_exception(stream_descriptor, e, stream_instance=stream_instance) - info_message = f"{self.name} does not support continuing syncs on error from stream {configured_stream.stream.name}" - - yield traced_exception.as_sanitized_airbyte_message(stream_descriptor=stream_descriptor) - stream_name_to_exception[stream_instance.name] = traced_exception # type: ignore # use configured_stream if stream_instance is None - if self.stop_sync_on_stream_failure: - logger.info(info_message) - break - finally: - # Finish read event only if the stream instance exists; - # otherwise, there's no need as it never started - if is_stream_exist: - timer.finish_event() - logger.info(f"Finished syncing {configured_stream.stream.name}") - logger.info(timer.report()) - - if len(stream_name_to_exception) > 0: - error_message = generate_failed_streams_error_message({key: [value] for key, value in stream_name_to_exception.items()}) # type: ignore # for some reason, mypy can't figure out the types for key and value - logger.info(error_message) - # We still raise at least one exception when a stream raises an exception because the platform currently relies - # on a non-zero exit code to determine if a sync attempt has failed. We also raise the exception as a config_error - # type because this combined error isn't actionable, but rather the previously emitted individual errors. - raise AirbyteTracedException(message=error_message, failure_type=FailureType.config_error) - logger.info(f"Finished syncing {self.name}") - - @staticmethod - def _serialize_exception( - stream_descriptor: StreamDescriptor, e: Exception, stream_instance: Optional[Stream] = None - ) -> AirbyteTracedException: - display_message = stream_instance.get_error_display_message(e) if stream_instance else None - if display_message: - return AirbyteTracedException.from_exception(e, message=display_message, stream_descriptor=stream_descriptor) - return AirbyteTracedException.from_exception(e, stream_descriptor=stream_descriptor) - - @property - def raise_exception_on_missing_stream(self) -> bool: - return False - - def _read_stream( - self, - logger: logging.Logger, - stream_instance: Stream, - configured_stream: ConfiguredAirbyteStream, - state_manager: ConnectorStateManager, - internal_config: InternalConfig, - ) -> Iterator[AirbyteMessage]: - if internal_config.page_size and isinstance(stream_instance, HttpStream): - logger.info(f"Setting page size for {stream_instance.name} to {internal_config.page_size}") - stream_instance.page_size = internal_config.page_size - logger.debug( - f"Syncing configured stream: {configured_stream.stream.name}", - extra={ - "sync_mode": configured_stream.sync_mode, - "primary_key": configured_stream.primary_key, - "cursor_field": configured_stream.cursor_field, - }, - ) - stream_instance.log_stream_sync_configuration() - - stream_name = configured_stream.stream.name - stream_state = state_manager.get_stream_state(stream_name, stream_instance.namespace) - - # This is a hack. Existing full refresh streams that are converted into resumable full refresh need to discard - # the state because the terminal state for a full refresh sync is not compatible with substream resumable full - # refresh state. This is only required when running live traffic regression testing since the platform normally - # handles whether to pass state - if stream_state == {"__ab_no_cursor_state_message": True}: - stream_state = {} - - if "state" in dir(stream_instance): - stream_instance.state = stream_state # type: ignore # we check that state in the dir(stream_instance) - logger.info(f"Setting state of {self.name} stream to {stream_state}") - - record_iterator = stream_instance.read( - configured_stream, - logger, - self._slice_logger, - stream_state, - state_manager, - internal_config, - ) - - record_counter = 0 - logger.info(f"Syncing stream: {stream_name} ") - for record_data_or_message in record_iterator: - record = self._get_message(record_data_or_message, stream_instance) - if record.type == MessageType.RECORD: - record_counter += 1 - if record_counter == 1: - logger.info(f"Marking stream {stream_name} as RUNNING") - # If we just read the first record of the stream, emit the transition to the RUNNING state - yield stream_status_as_airbyte_message(configured_stream.stream, AirbyteStreamStatus.RUNNING) - yield from self._emit_queued_messages() - yield record - - logger.info(f"Read {record_counter} records from {stream_name} stream") - - def _emit_queued_messages(self) -> Iterable[AirbyteMessage]: - if self.message_repository: - yield from self.message_repository.consume_queue() - return - - def _get_message(self, record_data_or_message: Union[StreamData, AirbyteMessage], stream: Stream) -> AirbyteMessage: - """ - Converts the input to an AirbyteMessage if it is a StreamData. Returns the input as is if it is already an AirbyteMessage - """ - match record_data_or_message: - case AirbyteMessage(): - return record_data_or_message - case _: - return stream_data_to_airbyte_message(stream.name, record_data_or_message, stream.transformer, stream.get_json_schema()) - - @property - def message_repository(self) -> Union[None, MessageRepository]: - return _default_message_repository - - @property - def stop_sync_on_stream_failure(self) -> bool: - """ - WARNING: This function is in-development which means it is subject to change. Use at your own risk. - - By default, when a source encounters an exception while syncing a stream, it will emit an error trace message and then - continue syncing the next stream. This can be overwritten on a per-source basis so that the source will stop the sync - on the first error seen and emit a single error trace message for that stream. - """ - return False diff --git a/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/concurrent_read_processor.py b/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/concurrent_read_processor.py deleted file mode 100644 index bd186c6dfa2b..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/concurrent_read_processor.py +++ /dev/null @@ -1,217 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import logging -from typing import Dict, Iterable, List, Optional, Set - -from airbyte_cdk.exception_handler import generate_failed_streams_error_message -from airbyte_cdk.models import AirbyteMessage, AirbyteStreamStatus, FailureType, StreamDescriptor -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.concurrent_source.partition_generation_completed_sentinel import PartitionGenerationCompletedSentinel -from airbyte_cdk.sources.concurrent_source.stream_thread_exception import StreamThreadException -from airbyte_cdk.sources.concurrent_source.thread_pool_manager import ThreadPoolManager -from airbyte_cdk.sources.message import MessageRepository -from airbyte_cdk.sources.streams.concurrent.abstract_stream import AbstractStream -from airbyte_cdk.sources.streams.concurrent.partition_enqueuer import PartitionEnqueuer -from airbyte_cdk.sources.streams.concurrent.partition_reader import PartitionReader -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record -from airbyte_cdk.sources.streams.concurrent.partitions.types import PartitionCompleteSentinel -from airbyte_cdk.sources.utils.record_helper import stream_data_to_airbyte_message -from airbyte_cdk.sources.utils.slice_logger import SliceLogger -from airbyte_cdk.utils import AirbyteTracedException -from airbyte_cdk.utils.stream_status_utils import as_airbyte_message as stream_status_as_airbyte_message - - -class ConcurrentReadProcessor: - def __init__( - self, - stream_instances_to_read_from: List[AbstractStream], - partition_enqueuer: PartitionEnqueuer, - thread_pool_manager: ThreadPoolManager, - logger: logging.Logger, - slice_logger: SliceLogger, - message_repository: MessageRepository, - partition_reader: PartitionReader, - ): - """ - This class is responsible for handling items from a concurrent stream read process. - :param stream_instances_to_read_from: List of streams to read from - :param partition_enqueuer: PartitionEnqueuer instance - :param thread_pool_manager: ThreadPoolManager instance - :param logger: Logger instance - :param slice_logger: SliceLogger instance - :param message_repository: MessageRepository instance - :param partition_reader: PartitionReader instance - """ - self._stream_name_to_instance = {s.name: s for s in stream_instances_to_read_from} - self._record_counter = {} - self._streams_to_running_partitions: Dict[str, Set[Partition]] = {} - for stream in stream_instances_to_read_from: - self._streams_to_running_partitions[stream.name] = set() - self._record_counter[stream.name] = 0 - self._thread_pool_manager = thread_pool_manager - self._partition_enqueuer = partition_enqueuer - self._stream_instances_to_start_partition_generation = stream_instances_to_read_from - self._streams_currently_generating_partitions: List[str] = [] - self._logger = logger - self._slice_logger = slice_logger - self._message_repository = message_repository - self._partition_reader = partition_reader - self._streams_done: Set[str] = set() - self._exceptions_per_stream_name: dict[str, List[Exception]] = {} - - def on_partition_generation_completed(self, sentinel: PartitionGenerationCompletedSentinel) -> Iterable[AirbyteMessage]: - """ - This method is called when a partition generation is completed. - 1. Remove the stream from the list of streams currently generating partitions - 2. If the stream is done, mark it as such and return a stream status message - 3. If there are more streams to read from, start the next partition generator - """ - stream_name = sentinel.stream.name - self._streams_currently_generating_partitions.remove(sentinel.stream.name) - # It is possible for the stream to already be done if no partitions were generated - # If the partition generation process was completed and there are no partitions left to process, the stream is done - if self._is_stream_done(stream_name) or len(self._streams_to_running_partitions[stream_name]) == 0: - yield from self._on_stream_is_done(stream_name) - if self._stream_instances_to_start_partition_generation: - yield self.start_next_partition_generator() # type:ignore # None may be yielded - - def on_partition(self, partition: Partition) -> None: - """ - This method is called when a partition is generated. - 1. Add the partition to the set of partitions for the stream - 2. Log the slice if necessary - 3. Submit the partition to the thread pool manager - """ - stream_name = partition.stream_name() - self._streams_to_running_partitions[stream_name].add(partition) - if self._slice_logger.should_log_slice_message(self._logger): - self._message_repository.emit_message(self._slice_logger.create_slice_log_message(partition.to_slice())) - self._thread_pool_manager.submit(self._partition_reader.process_partition, partition) - - def on_partition_complete_sentinel(self, sentinel: PartitionCompleteSentinel) -> Iterable[AirbyteMessage]: - """ - This method is called when a partition is completed. - 1. Close the partition - 2. If the stream is done, mark it as such and return a stream status message - 3. Emit messages that were added to the message repository - """ - partition = sentinel.partition - - try: - if sentinel.is_successful: - partition.close() - except Exception as exception: - self._flag_exception(partition.stream_name(), exception) - yield AirbyteTracedException.from_exception( - exception, stream_descriptor=StreamDescriptor(name=partition.stream_name()) - ).as_sanitized_airbyte_message() - finally: - partitions_running = self._streams_to_running_partitions[partition.stream_name()] - if partition in partitions_running: - partitions_running.remove(partition) - # If all partitions were generated and this was the last one, the stream is done - if partition.stream_name() not in self._streams_currently_generating_partitions and len(partitions_running) == 0: - yield from self._on_stream_is_done(partition.stream_name()) - yield from self._message_repository.consume_queue() - - def on_record(self, record: Record) -> Iterable[AirbyteMessage]: - """ - This method is called when a record is read from a partition. - 1. Convert the record to an AirbyteMessage - 2. If this is the first record for the stream, mark the stream as RUNNING - 3. Increment the record counter for the stream - 4. Ensures the cursor knows the record has been successfully emitted - 5. Emit the message - 6. Emit messages that were added to the message repository - """ - # Do not pass a transformer or a schema - # AbstractStreams are expected to return data as they are expected. - # Any transformation on the data should be done before reaching this point - message = stream_data_to_airbyte_message(record.partition.stream_name(), record.data) - stream = self._stream_name_to_instance[record.partition.stream_name()] - - if message.type == MessageType.RECORD: - if self._record_counter[stream.name] == 0: - self._logger.info(f"Marking stream {stream.name} as RUNNING") - yield stream_status_as_airbyte_message(stream.as_airbyte_stream(), AirbyteStreamStatus.RUNNING) - self._record_counter[stream.name] += 1 - stream.cursor.observe(record) - yield message - yield from self._message_repository.consume_queue() - - def on_exception(self, exception: StreamThreadException) -> Iterable[AirbyteMessage]: - """ - This method is called when an exception is raised. - 1. Stop all running streams - 2. Raise the exception - """ - self._flag_exception(exception.stream_name, exception.exception) - self._logger.exception(f"Exception while syncing stream {exception.stream_name}", exc_info=exception.exception) - - stream_descriptor = StreamDescriptor(name=exception.stream_name) - if isinstance(exception.exception, AirbyteTracedException): - yield exception.exception.as_airbyte_message(stream_descriptor=stream_descriptor) - else: - yield AirbyteTracedException.from_exception(exception, stream_descriptor=stream_descriptor).as_airbyte_message() - - def _flag_exception(self, stream_name: str, exception: Exception) -> None: - self._exceptions_per_stream_name.setdefault(stream_name, []).append(exception) - - def start_next_partition_generator(self) -> Optional[AirbyteMessage]: - """ - Start the next partition generator. - 1. Pop the next stream to read from - 2. Submit the partition generator to the thread pool manager - 3. Add the stream to the list of streams currently generating partitions - 4. Return a stream status message - """ - if self._stream_instances_to_start_partition_generation: - stream = self._stream_instances_to_start_partition_generation.pop(0) - self._thread_pool_manager.submit(self._partition_enqueuer.generate_partitions, stream) - self._streams_currently_generating_partitions.append(stream.name) - self._logger.info(f"Marking stream {stream.name} as STARTED") - self._logger.info(f"Syncing stream: {stream.name} ") - return stream_status_as_airbyte_message( - stream.as_airbyte_stream(), - AirbyteStreamStatus.STARTED, - ) - else: - return None - - def is_done(self) -> bool: - """ - This method is called to check if the sync is done. - The sync is done when: - 1. There are no more streams generating partitions - 2. There are no more streams to read from - 3. All partitions for all streams are closed - """ - is_done = all([self._is_stream_done(stream_name) for stream_name in self._stream_name_to_instance.keys()]) - if is_done and self._exceptions_per_stream_name: - error_message = generate_failed_streams_error_message(self._exceptions_per_stream_name) - self._logger.info(error_message) - # We still raise at least one exception when a stream raises an exception because the platform currently relies - # on a non-zero exit code to determine if a sync attempt has failed. We also raise the exception as a config_error - # type because this combined error isn't actionable, but rather the previously emitted individual errors. - raise AirbyteTracedException( - message=error_message, internal_message="Concurrent read failure", failure_type=FailureType.config_error - ) - return is_done - - def _is_stream_done(self, stream_name: str) -> bool: - return stream_name in self._streams_done - - def _on_stream_is_done(self, stream_name: str) -> Iterable[AirbyteMessage]: - self._logger.info(f"Read {self._record_counter[stream_name]} records from {stream_name} stream") - self._logger.info(f"Marking stream {stream_name} as STOPPED") - stream = self._stream_name_to_instance[stream_name] - stream.cursor.ensure_at_least_one_state_emitted() - yield from self._message_repository.consume_queue() - self._logger.info(f"Finished syncing {stream.name}") - self._streams_done.add(stream_name) - stream_status = ( - AirbyteStreamStatus.INCOMPLETE if self._exceptions_per_stream_name.get(stream_name, []) else AirbyteStreamStatus.COMPLETE - ) - yield stream_status_as_airbyte_message(stream.as_airbyte_stream(), stream_status) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/concurrent_source.py b/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/concurrent_source.py deleted file mode 100644 index 8e49f66a19c8..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/concurrent_source.py +++ /dev/null @@ -1,147 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import concurrent -import logging -from queue import Queue -from typing import Iterable, Iterator, List - -from airbyte_cdk.models import AirbyteMessage -from airbyte_cdk.sources.concurrent_source.concurrent_read_processor import ConcurrentReadProcessor -from airbyte_cdk.sources.concurrent_source.partition_generation_completed_sentinel import PartitionGenerationCompletedSentinel -from airbyte_cdk.sources.concurrent_source.stream_thread_exception import StreamThreadException -from airbyte_cdk.sources.concurrent_source.thread_pool_manager import ThreadPoolManager -from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository -from airbyte_cdk.sources.streams.concurrent.abstract_stream import AbstractStream -from airbyte_cdk.sources.streams.concurrent.partition_enqueuer import PartitionEnqueuer -from airbyte_cdk.sources.streams.concurrent.partition_reader import PartitionReader -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record -from airbyte_cdk.sources.streams.concurrent.partitions.types import PartitionCompleteSentinel, QueueItem -from airbyte_cdk.sources.utils.slice_logger import DebugSliceLogger, SliceLogger - - -class ConcurrentSource: - """ - A Source that reads data from multiple AbstractStreams concurrently. - It does so by submitting partition generation, and partition read tasks to a thread pool. - The tasks asynchronously add their output to a shared queue. - The read is done when all partitions for all streams w ere generated and read. - """ - - DEFAULT_TIMEOUT_SECONDS = 900 - - @staticmethod - def create( - num_workers: int, - initial_number_of_partitions_to_generate: int, - logger: logging.Logger, - slice_logger: SliceLogger, - message_repository: MessageRepository, - timeout_seconds: int = DEFAULT_TIMEOUT_SECONDS, - ) -> "ConcurrentSource": - is_single_threaded = initial_number_of_partitions_to_generate == 1 and num_workers == 1 - too_many_generator = not is_single_threaded and initial_number_of_partitions_to_generate >= num_workers - assert not too_many_generator, "It is required to have more workers than threads generating partitions" - threadpool = ThreadPoolManager( - concurrent.futures.ThreadPoolExecutor(max_workers=num_workers, thread_name_prefix="workerpool"), - logger, - ) - return ConcurrentSource( - threadpool, logger, slice_logger, message_repository, initial_number_of_partitions_to_generate, timeout_seconds - ) - - def __init__( - self, - threadpool: ThreadPoolManager, - logger: logging.Logger, - slice_logger: SliceLogger = DebugSliceLogger(), - message_repository: MessageRepository = InMemoryMessageRepository(), - initial_number_partitions_to_generate: int = 1, - timeout_seconds: int = DEFAULT_TIMEOUT_SECONDS, - ) -> None: - """ - :param threadpool: The threadpool to submit tasks to - :param logger: The logger to log to - :param slice_logger: The slice logger used to create messages on new slices - :param message_repository: The repository to emit messages to - :param initial_number_partitions_to_generate: The initial number of concurrent partition generation tasks. Limiting this number ensures will limit the latency of the first records emitted. While the latency is not critical, emitting the records early allows the platform and the destination to process them as early as possible. - :param timeout_seconds: The maximum number of seconds to wait for a record to be read from the queue. If no record is read within this time, the source will stop reading and return. - """ - self._threadpool = threadpool - self._logger = logger - self._slice_logger = slice_logger - self._message_repository = message_repository - self._initial_number_partitions_to_generate = initial_number_partitions_to_generate - self._timeout_seconds = timeout_seconds - - def read( - self, - streams: List[AbstractStream], - ) -> Iterator[AirbyteMessage]: - self._logger.info("Starting syncing") - - # We set a maxsize to for the main thread to process record items when the queue size grows. This assumes that there are less - # threads generating partitions that than are max number of workers. If it weren't the case, we could have threads only generating - # partitions which would fill the queue. This number is arbitrarily set to 10_000 but will probably need to be changed given more - # information and might even need to be configurable depending on the source - queue: Queue[QueueItem] = Queue(maxsize=10_000) - concurrent_stream_processor = ConcurrentReadProcessor( - streams, - PartitionEnqueuer(queue, self._threadpool), - self._threadpool, - self._logger, - self._slice_logger, - self._message_repository, - PartitionReader(queue), - ) - - # Enqueue initial partition generation tasks - yield from self._submit_initial_partition_generators(concurrent_stream_processor) - - # Read from the queue until all partitions were generated and read - yield from self._consume_from_queue( - queue, - concurrent_stream_processor, - ) - self._threadpool.check_for_errors_and_shutdown() - self._logger.info("Finished syncing") - - def _submit_initial_partition_generators(self, concurrent_stream_processor: ConcurrentReadProcessor) -> Iterable[AirbyteMessage]: - for _ in range(self._initial_number_partitions_to_generate): - status_message = concurrent_stream_processor.start_next_partition_generator() - if status_message: - yield status_message - - def _consume_from_queue( - self, - queue: Queue[QueueItem], - concurrent_stream_processor: ConcurrentReadProcessor, - ) -> Iterable[AirbyteMessage]: - while airbyte_message_or_record_or_exception := queue.get(): - yield from self._handle_item( - airbyte_message_or_record_or_exception, - concurrent_stream_processor, - ) - if concurrent_stream_processor.is_done() and queue.empty(): - # all partitions were generated and processed. we're done here - break - - def _handle_item( - self, - queue_item: QueueItem, - concurrent_stream_processor: ConcurrentReadProcessor, - ) -> Iterable[AirbyteMessage]: - # handle queue item and call the appropriate handler depending on the type of the queue item - if isinstance(queue_item, StreamThreadException): - yield from concurrent_stream_processor.on_exception(queue_item) - elif isinstance(queue_item, PartitionGenerationCompletedSentinel): - yield from concurrent_stream_processor.on_partition_generation_completed(queue_item) - elif isinstance(queue_item, Partition): - concurrent_stream_processor.on_partition(queue_item) - elif isinstance(queue_item, PartitionCompleteSentinel): - yield from concurrent_stream_processor.on_partition_complete_sentinel(queue_item) - elif isinstance(queue_item, Record): - yield from concurrent_stream_processor.on_record(queue_item) - else: - raise ValueError(f"Unknown queue item type: {type(queue_item)}") diff --git a/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/concurrent_source_adapter.py b/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/concurrent_source_adapter.py deleted file mode 100644 index bbffe8f88f71..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/concurrent_source_adapter.py +++ /dev/null @@ -1,126 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from abc import ABC -from datetime import timedelta -from typing import Any, Callable, Iterator, List, Mapping, MutableMapping, Optional, Tuple - -from airbyte_cdk.models import AirbyteMessage, AirbyteStateMessage, ConfiguredAirbyteCatalog -from airbyte_cdk.sources import AbstractSource -from airbyte_cdk.sources.concurrent_source.concurrent_source import ConcurrentSource -from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager -from airbyte_cdk.sources.streams import Stream -from airbyte_cdk.sources.streams.concurrent.abstract_stream import AbstractStream -from airbyte_cdk.sources.streams.concurrent.abstract_stream_facade import AbstractStreamFacade -from airbyte_cdk.sources.streams.concurrent.adapters import StreamFacade -from airbyte_cdk.sources.streams.concurrent.cursor import ConcurrentCursor, Cursor, CursorField, CursorValueType, FinalStateCursor, GapType -from airbyte_cdk.sources.streams.concurrent.state_converters.abstract_stream_state_converter import AbstractStreamStateConverter - -DEFAULT_LOOKBACK_SECONDS = 0 - - -class ConcurrentSourceAdapter(AbstractSource, ABC): - def __init__(self, concurrent_source: ConcurrentSource, **kwargs: Any) -> None: - """ - ConcurrentSourceAdapter is a Source that wraps a concurrent source and exposes it as a regular source. - - The source's streams are still defined through the streams() method. - Streams wrapped in a StreamFacade will be processed concurrently. - Other streams will be processed sequentially as a later step. - """ - self._concurrent_source = concurrent_source - super().__init__(**kwargs) - - def read( - self, - logger: logging.Logger, - config: Mapping[str, Any], - catalog: ConfiguredAirbyteCatalog, - state: Optional[List[AirbyteStateMessage]] = None, - ) -> Iterator[AirbyteMessage]: - abstract_streams = self._select_abstract_streams(config, catalog) - concurrent_stream_names = {stream.name for stream in abstract_streams} - configured_catalog_for_regular_streams = ConfiguredAirbyteCatalog( - streams=[stream for stream in catalog.streams if stream.stream.name not in concurrent_stream_names] - ) - if abstract_streams: - yield from self._concurrent_source.read(abstract_streams) - if configured_catalog_for_regular_streams.streams: - yield from super().read(logger, config, configured_catalog_for_regular_streams, state) - - def _select_abstract_streams(self, config: Mapping[str, Any], configured_catalog: ConfiguredAirbyteCatalog) -> List[AbstractStream]: - """ - Selects streams that can be processed concurrently and returns their abstract representations. - """ - all_streams = self.streams(config) - stream_name_to_instance: Mapping[str, Stream] = {s.name: s for s in all_streams} - abstract_streams: List[AbstractStream] = [] - for configured_stream in configured_catalog.streams: - stream_instance = stream_name_to_instance.get(configured_stream.stream.name) - if not stream_instance: - continue - - if isinstance(stream_instance, AbstractStreamFacade): - abstract_streams.append(stream_instance.get_underlying_stream()) - return abstract_streams - - def convert_to_concurrent_stream( - self, logger: logging.Logger, stream: Stream, state_manager: ConnectorStateManager, cursor: Optional[Cursor] = None - ) -> Stream: - """ - Prepares a stream for concurrent processing by initializing or assigning a cursor, - managing the stream's state, and returning an updated Stream instance. - """ - state: MutableMapping[str, Any] = {} - - if cursor: - state = state_manager.get_stream_state(stream.name, stream.namespace) - - stream.cursor = cursor # type: ignore[assignment] # cursor is of type ConcurrentCursor, which inherits from Cursor - if hasattr(stream, "parent"): - stream.parent.cursor = cursor - else: - cursor = FinalStateCursor( - stream_name=stream.name, - stream_namespace=stream.namespace, - message_repository=self.message_repository, # type: ignore[arg-type] # _default_message_repository will be returned in the worst case - ) - return StreamFacade.create_from_stream(stream, self, logger, state, cursor) - - def initialize_cursor( - self, - stream: Stream, - state_manager: ConnectorStateManager, - converter: AbstractStreamStateConverter, - slice_boundary_fields: Optional[Tuple[str, str]], - start: Optional[CursorValueType], - end_provider: Callable[[], CursorValueType], - lookback_window: Optional[GapType] = None, - slice_range: Optional[GapType] = None, - ) -> Optional[ConcurrentCursor]: - lookback_window = lookback_window or timedelta(seconds=DEFAULT_LOOKBACK_SECONDS) - - cursor_field_name = stream.cursor_field - - if cursor_field_name: - if not isinstance(cursor_field_name, str): - raise ValueError(f"Cursor field type must be a string, but received {type(cursor_field_name).__name__}.") - - return ConcurrentCursor( - stream.name, - stream.namespace, - state_manager.get_stream_state(stream.name, stream.namespace), - self.message_repository, # type: ignore[arg-type] # _default_message_repository will be returned in the worst case - state_manager, - converter, - CursorField(cursor_field_name), - slice_boundary_fields, - start, - end_provider, - lookback_window, - slice_range, - ) - - return None diff --git a/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/partition_generation_completed_sentinel.py b/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/partition_generation_completed_sentinel.py deleted file mode 100644 index b6643042b24c..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/partition_generation_completed_sentinel.py +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -from typing import Any - -from airbyte_cdk.sources.streams.concurrent.abstract_stream import AbstractStream - - -class PartitionGenerationCompletedSentinel: - """ - A sentinel object indicating all partitions for a stream were produced. - Includes a pointer to the stream that was processed. - """ - - def __init__(self, stream: AbstractStream): - """ - :param stream: The stream that was processed - """ - self.stream = stream - - def __eq__(self, other: Any) -> bool: - if isinstance(other, PartitionGenerationCompletedSentinel): - return self.stream == other.stream - return False diff --git a/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/stream_thread_exception.py b/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/stream_thread_exception.py deleted file mode 100644 index c865bef59732..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/stream_thread_exception.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from typing import Any - - -class StreamThreadException(Exception): - def __init__(self, exception: Exception, stream_name: str): - self._exception = exception - self._stream_name = stream_name - - @property - def stream_name(self) -> str: - return self._stream_name - - @property - def exception(self) -> Exception: - return self._exception - - def __str__(self) -> str: - return f"Exception while syncing stream {self._stream_name}: {self._exception}" - - def __eq__(self, other: Any) -> bool: - if isinstance(other, StreamThreadException): - return self._exception == other._exception and self._stream_name == other._stream_name - return False diff --git a/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/thread_pool_manager.py b/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/thread_pool_manager.py deleted file mode 100644 index b6933e6bc3d2..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/concurrent_source/thread_pool_manager.py +++ /dev/null @@ -1,109 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import logging -import threading -from concurrent.futures import Future, ThreadPoolExecutor -from typing import Any, Callable, List, Optional - - -class ThreadPoolManager: - """ - Wrapper to abstract away the threadpool and the logic to wait for pending tasks to be completed. - """ - - DEFAULT_MAX_QUEUE_SIZE = 10_000 - - def __init__( - self, - threadpool: ThreadPoolExecutor, - logger: logging.Logger, - max_concurrent_tasks: int = DEFAULT_MAX_QUEUE_SIZE, - ): - """ - :param threadpool: The threadpool to use - :param logger: The logger to use - :param max_concurrent_tasks: The maximum number of tasks that can be pending at the same time - """ - self._threadpool = threadpool - self._logger = logger - self._max_concurrent_tasks = max_concurrent_tasks - self._futures: List[Future[Any]] = [] - self._lock = threading.Lock() - self._most_recently_seen_exception: Optional[Exception] = None - - self._logging_threshold = max_concurrent_tasks * 2 - - def prune_to_validate_has_reached_futures_limit(self) -> bool: - self._prune_futures(self._futures) - if len(self._futures) > self._logging_threshold: - self._logger.warning(f"ThreadPoolManager: The list of futures is getting bigger than expected ({len(self._futures)})") - return len(self._futures) >= self._max_concurrent_tasks - - def submit(self, function: Callable[..., Any], *args: Any) -> None: - self._futures.append(self._threadpool.submit(function, *args)) - - def _prune_futures(self, futures: List[Future[Any]]) -> None: - """ - Take a list in input and remove the futures that are completed. If a future has an exception, it'll raise and kill the stream - operation. - - We are using a lock here as without it, the algorithm would not be thread safe - """ - with self._lock: - if len(futures) < self._max_concurrent_tasks: - return - - for index in reversed(range(len(futures))): - future = futures[index] - - if future.done(): - # Only call future.exception() if the future is known to be done because it will block until the future is done. - # See https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Future.exception - optional_exception = future.exception() - if optional_exception: - # Exception handling should be done in the main thread. Hence, we only store the exception and expect the main - # thread to call raise_if_exception - # We do not expect this error to happen. The futures created during concurrent syncs should catch the exception and - # push it to the queue. If this exception occurs, please review the futures and how they handle exceptions. - self._most_recently_seen_exception = RuntimeError( - f"Failed processing a future: {optional_exception}. Please contact the Airbyte team." - ) - futures.pop(index) - - def _shutdown(self) -> None: - # Without a way to stop the threads that have already started, this will not stop the Python application. We are fine today with - # this imperfect approach because we only do this in case of `self._most_recently_seen_exception` which we don't expect to happen - self._threadpool.shutdown(wait=False, cancel_futures=True) - - def is_done(self) -> bool: - return all([f.done() for f in self._futures]) - - def check_for_errors_and_shutdown(self) -> None: - """ - Check if any of the futures have an exception, and raise it if so. If all futures are done, shutdown the threadpool. - If the futures are not done, raise an exception. - :return: - """ - if self._most_recently_seen_exception: - self._logger.exception( - "An unknown exception has occurred while reading concurrently", - exc_info=self._most_recently_seen_exception, - ) - self._stop_and_raise_exception(self._most_recently_seen_exception) - - exceptions_from_futures = [f for f in [future.exception() for future in self._futures] if f is not None] - if exceptions_from_futures: - exception = RuntimeError(f"Failed reading with errors: {exceptions_from_futures}") - self._stop_and_raise_exception(exception) - else: - futures_not_done = [f for f in self._futures if not f.done()] - if futures_not_done: - exception = RuntimeError(f"Failed reading with futures not done: {futures_not_done}") - self._stop_and_raise_exception(exception) - else: - self._shutdown() - - def _stop_and_raise_exception(self, exception: BaseException) -> None: - self._shutdown() - raise exception diff --git a/airbyte-cdk/python/airbyte_cdk/sources/config.py b/airbyte-cdk/python/airbyte_cdk/sources/config.py deleted file mode 100644 index 8ea2b6400db4..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/config.py +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Dict - -from airbyte_cdk.sources.utils.schema_helpers import expand_refs, rename_key -from pydantic.v1 import BaseModel - - -class BaseConfig(BaseModel): - """Base class for connector spec, adds the following behaviour: - - - resolve $ref and replace it with definition - - replace all occurrences of anyOf with oneOf - - drop description - """ - - @classmethod - def schema(cls, *args: Any, **kwargs: Any) -> Dict[str, Any]: - """We're overriding the schema classmethod to enable some post-processing""" - schema = super().schema(*args, **kwargs) - rename_key(schema, old_key="anyOf", new_key="oneOf") # UI supports only oneOf - expand_refs(schema) - schema.pop("description", None) # description added from the docstring - return schema # type: ignore[no-any-return] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/connector_state_manager.py b/airbyte-cdk/python/airbyte_cdk/sources/connector_state_manager.py deleted file mode 100644 index 547f4bb23dca..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/connector_state_manager.py +++ /dev/null @@ -1,134 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import copy -from dataclasses import dataclass -from typing import Any, List, Mapping, MutableMapping, Optional, Tuple, Union - -from airbyte_cdk.models import AirbyteMessage, AirbyteStateBlob, AirbyteStateMessage, AirbyteStateType, AirbyteStreamState, StreamDescriptor -from airbyte_cdk.models import Type as MessageType - - -@dataclass(frozen=True) -class HashableStreamDescriptor: - """ - Helper class that overrides the existing StreamDescriptor class that is auto generated from the Airbyte Protocol and - freezes its fields so that it be used as a hash key. This is only marked public because we use it outside for unit tests. - """ - - name: str - namespace: Optional[str] = None - - -class ConnectorStateManager: - """ - ConnectorStateManager consolidates the various forms of a stream's incoming state message (STREAM / GLOBAL) under a common - interface. It also provides methods to extract and update state - """ - - def __init__(self, state: Optional[List[AirbyteStateMessage]] = None): - shared_state, per_stream_states = self._extract_from_state_message(state) - - # We explicitly throw an error if we receive a GLOBAL state message that contains a shared_state because API sources are - # designed to checkpoint state independently of one another. API sources should never be emitting a state message where - # shared_state is populated. Rather than define how to handle shared_state without a clear use case, we're opting to throw an - # error instead and if/when we find one, we will then implement processing of the shared_state value. - if shared_state: - raise ValueError( - "Received a GLOBAL AirbyteStateMessage that contains a shared_state. This library only ever generates per-STREAM " - "STATE messages so this was not generated by this connector. This must be an orchestrator or platform error. GLOBAL " - "state messages with shared_state will not be processed correctly. " - ) - self.per_stream_states = per_stream_states - - def get_stream_state(self, stream_name: str, namespace: Optional[str]) -> MutableMapping[str, Any]: - """ - Retrieves the state of a given stream based on its descriptor (name + namespace). - :param stream_name: Name of the stream being fetched - :param namespace: Namespace of the stream being fetched - :return: The per-stream state for a stream - """ - stream_state: AirbyteStateBlob | None = self.per_stream_states.get(HashableStreamDescriptor(name=stream_name, namespace=namespace)) - if stream_state: - return copy.deepcopy({k: v for k, v in stream_state.__dict__.items()}) - return {} - - def update_state_for_stream(self, stream_name: str, namespace: Optional[str], value: Mapping[str, Any]) -> None: - """ - Overwrites the state blob of a specific stream based on the provided stream name and optional namespace - :param stream_name: The name of the stream whose state is being updated - :param namespace: The namespace of the stream if it exists - :param value: A stream state mapping that is being updated for a stream - """ - stream_descriptor = HashableStreamDescriptor(name=stream_name, namespace=namespace) - self.per_stream_states[stream_descriptor] = AirbyteStateBlob(value) - - def create_state_message(self, stream_name: str, namespace: Optional[str]) -> AirbyteMessage: - """ - Generates an AirbyteMessage using the current per-stream state of a specified stream - :param stream_name: The name of the stream for the message that is being created - :param namespace: The namespace of the stream for the message that is being created - :return: The Airbyte state message to be emitted by the connector during a sync - """ - hashable_descriptor = HashableStreamDescriptor(name=stream_name, namespace=namespace) - stream_state = self.per_stream_states.get(hashable_descriptor) or AirbyteStateBlob() - - return AirbyteMessage( - type=MessageType.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name=stream_name, namespace=namespace), stream_state=stream_state - ), - ), - ) - - @classmethod - def _extract_from_state_message( - cls, - state: Optional[List[AirbyteStateMessage]], - ) -> Tuple[Optional[AirbyteStateBlob], MutableMapping[HashableStreamDescriptor, Optional[AirbyteStateBlob]]]: - """ - Takes an incoming list of state messages or a global state message and extracts state attributes according to - type which can then be assigned to the new state manager being instantiated - :param state: The incoming state input - :return: A tuple of shared state and per stream state assembled from the incoming state list - """ - if state is None: - return None, {} - - is_global = cls._is_global_state(state) - - if is_global: - global_state = state[0].global_ # type: ignore # We verified state is a list in _is_global_state - shared_state = copy.deepcopy(global_state.shared_state, {}) # type: ignore[union-attr] # global_state has shared_state - streams = { - HashableStreamDescriptor( - name=per_stream_state.stream_descriptor.name, namespace=per_stream_state.stream_descriptor.namespace - ): per_stream_state.stream_state - for per_stream_state in global_state.stream_states # type: ignore[union-attr] # global_state has shared_state - } - return shared_state, streams - else: - streams = { - HashableStreamDescriptor( - name=per_stream_state.stream.stream_descriptor.name, namespace=per_stream_state.stream.stream_descriptor.namespace # type: ignore[union-attr] # stream has stream_descriptor - ): per_stream_state.stream.stream_state # type: ignore[union-attr] # stream has stream_state - for per_stream_state in state - if per_stream_state.type == AirbyteStateType.STREAM and hasattr(per_stream_state, "stream") # type: ignore # state is always a list of AirbyteStateMessage if is_per_stream is True - } - return None, streams - - @staticmethod - def _is_global_state(state: Union[List[AirbyteStateMessage], MutableMapping[str, Any]]) -> bool: - return ( - isinstance(state, List) - and len(state) == 1 - and isinstance(state[0], AirbyteStateMessage) - and state[0].type == AirbyteStateType.GLOBAL - ) - - @staticmethod - def _is_per_stream_state(state: Union[List[AirbyteStateMessage], MutableMapping[str, Any]]) -> bool: - return isinstance(state, List) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/__init__.py deleted file mode 100644 index 46b7376756ec..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/job.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/job.py deleted file mode 100644 index 5b4f1c7ab0ce..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/job.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - - -from datetime import timedelta -from typing import Optional - -from airbyte_cdk.sources.declarative.async_job.timer import Timer -from airbyte_cdk.sources.types import StreamSlice - -from .status import AsyncJobStatus - - -class AsyncJob: - """ - Description of an API job. - - Note that the timer will only stop once `update_status` is called so the job might be completed on the API side but until we query for - it and call `ApiJob.update_status`, `ApiJob.status` will not reflect the actual API side status. - """ - - def __init__(self, api_job_id: str, job_parameters: StreamSlice, timeout: Optional[timedelta] = None) -> None: - self._api_job_id = api_job_id - self._job_parameters = job_parameters - self._status = AsyncJobStatus.RUNNING - - timeout = timeout if timeout else timedelta(minutes=60) - self._timer = Timer(timeout) - self._timer.start() - - def api_job_id(self) -> str: - return self._api_job_id - - def status(self) -> AsyncJobStatus: - if self._timer.has_timed_out(): - return AsyncJobStatus.TIMED_OUT - return self._status - - def job_parameters(self) -> StreamSlice: - return self._job_parameters - - def update_status(self, status: AsyncJobStatus) -> None: - if self._status != AsyncJobStatus.RUNNING and status == AsyncJobStatus.RUNNING: - self._timer.start() - elif status.is_terminal(): - self._timer.stop() - - self._status = status - - def __repr__(self) -> str: - return f"AsyncJob(api_job_id={self.api_job_id()}, job_parameters={self.job_parameters()}, status={self.status()})" diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/job_orchestrator.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/job_orchestrator.py deleted file mode 100644 index ddd7b8b3a7c9..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/job_orchestrator.py +++ /dev/null @@ -1,443 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -import logging -import threading -import time -import traceback -import uuid -from datetime import timedelta -from typing import Any, Generator, Generic, Iterable, List, Mapping, Optional, Set, Tuple, Type, TypeVar - -from airbyte_cdk import StreamSlice -from airbyte_cdk.logger import lazy_log -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.declarative.async_job.job import AsyncJob -from airbyte_cdk.sources.declarative.async_job.job_tracker import ConcurrentJobLimitReached, JobTracker -from airbyte_cdk.sources.declarative.async_job.repository import AsyncJobRepository -from airbyte_cdk.sources.declarative.async_job.status import AsyncJobStatus -from airbyte_cdk.sources.message import MessageRepository -from airbyte_cdk.utils.airbyte_secrets_utils import filter_secrets -from airbyte_cdk.utils.traced_exception import AirbyteTracedException - -LOGGER = logging.getLogger("airbyte") -_NO_TIMEOUT = timedelta.max -_API_SIDE_RUNNING_STATUS = {AsyncJobStatus.RUNNING, AsyncJobStatus.TIMED_OUT} - - -class AsyncPartition: - """ - This bucket of api_jobs is a bit useless for this iteration but should become interesting when we will be able to split jobs - """ - - _MAX_NUMBER_OF_ATTEMPTS = 3 - - def __init__(self, jobs: List[AsyncJob], stream_slice: StreamSlice) -> None: - self._attempts_per_job = {job: 1 for job in jobs} - self._stream_slice = stream_slice - - def has_reached_max_attempt(self) -> bool: - return any(map(lambda attempt_count: attempt_count >= self._MAX_NUMBER_OF_ATTEMPTS, self._attempts_per_job.values())) - - def replace_job(self, job_to_replace: AsyncJob, new_jobs: List[AsyncJob]) -> None: - current_attempt_count = self._attempts_per_job.pop(job_to_replace, None) - if current_attempt_count is None: - raise ValueError("Could not find job to replace") - elif current_attempt_count >= self._MAX_NUMBER_OF_ATTEMPTS: - raise ValueError(f"Max attempt reached for job in partition {self._stream_slice}") - - new_attempt_count = current_attempt_count + 1 - for job in new_jobs: - self._attempts_per_job[job] = new_attempt_count - - def should_split(self, job: AsyncJob) -> bool: - """ - Not used right now but once we support job split, we should split based on the number of attempts - """ - return False - - @property - def jobs(self) -> Iterable[AsyncJob]: - return self._attempts_per_job.keys() - - @property - def stream_slice(self) -> StreamSlice: - return self._stream_slice - - @property - def status(self) -> AsyncJobStatus: - """ - Given different job statuses, the priority is: FAILED, TIMED_OUT, RUNNING. Else, it means everything is completed. - """ - statuses = set(map(lambda job: job.status(), self.jobs)) - if statuses == {AsyncJobStatus.COMPLETED}: - return AsyncJobStatus.COMPLETED - elif AsyncJobStatus.FAILED in statuses: - return AsyncJobStatus.FAILED - elif AsyncJobStatus.TIMED_OUT in statuses: - return AsyncJobStatus.TIMED_OUT - else: - return AsyncJobStatus.RUNNING - - def __repr__(self) -> str: - return f"AsyncPartition(stream_slice={self._stream_slice}, attempt_per_job={self._attempts_per_job})" - - def __json_serializable__(self) -> Any: - return self._stream_slice - - -T = TypeVar("T") - - -class LookaheadIterator(Generic[T]): - def __init__(self, iterable: Iterable[T]) -> None: - self._iterator = iter(iterable) - self._buffer: List[T] = [] - - def __iter__(self) -> "LookaheadIterator[T]": - return self - - def __next__(self) -> T: - if self._buffer: - return self._buffer.pop() - else: - return next(self._iterator) - - def has_next(self) -> bool: - if self._buffer: - return True - - try: - self._buffer = [next(self._iterator)] - except StopIteration: - return False - else: - return True - - def add_at_the_beginning(self, item: T) -> None: - self._buffer = [item] + self._buffer - - -class AsyncJobOrchestrator: - _WAIT_TIME_BETWEEN_STATUS_UPDATE_IN_SECONDS = 5 - _KNOWN_JOB_STATUSES = {AsyncJobStatus.COMPLETED, AsyncJobStatus.FAILED, AsyncJobStatus.RUNNING, AsyncJobStatus.TIMED_OUT} - _RUNNING_ON_API_SIDE_STATUS = {AsyncJobStatus.RUNNING, AsyncJobStatus.TIMED_OUT} - - def __init__( - self, - job_repository: AsyncJobRepository, - slices: Iterable[StreamSlice], - job_tracker: JobTracker, - message_repository: MessageRepository, - exceptions_to_break_on: Iterable[Type[Exception]] = tuple(), - has_bulk_parent: bool = False, - ) -> None: - """ - If the stream slices provided as a parameters relies on a async job streams that relies on the same JobTracker, `has_bulk_parent` - needs to be set to True as jobs creation needs to be prioritized on the parent level. Doing otherwise could lead to a situation - where the child has taken up all the job budget without room to the parent to create more which would lead to an infinite loop of - "trying to start a parent job" and "ConcurrentJobLimitReached". - """ - if {*AsyncJobStatus} != self._KNOWN_JOB_STATUSES: - # this is to prevent developers updating the possible statuses without updating the logic of this class - raise ValueError( - "An AsyncJobStatus has been either removed or added which means the logic of this class needs to be reviewed. Once the logic has been updated, please update _KNOWN_JOB_STATUSES" - ) - - self._job_repository: AsyncJobRepository = job_repository - self._slice_iterator = LookaheadIterator(slices) - self._running_partitions: List[AsyncPartition] = [] - self._job_tracker = job_tracker - self._message_repository = message_repository - self._exceptions_to_break_on: Tuple[Type[Exception], ...] = tuple(exceptions_to_break_on) - self._has_bulk_parent = has_bulk_parent - - self._non_breaking_exceptions: List[Exception] = [] - - def _replace_failed_jobs(self, partition: AsyncPartition) -> None: - failed_status_jobs = (AsyncJobStatus.FAILED, AsyncJobStatus.TIMED_OUT) - jobs_to_replace = [job for job in partition.jobs if job.status() in failed_status_jobs] - for job in jobs_to_replace: - new_job = self._start_job(job.job_parameters(), job.api_job_id()) - partition.replace_job(job, [new_job]) - - def _start_jobs(self) -> None: - """ - Retry failed jobs and start jobs for each slice in the slice iterator. - This method iterates over the running jobs and slice iterator and starts a job for each slice. - The started jobs are added to the running partitions. - Returns: - None - - However, the first iteration is for sendgrid which only has one job. - """ - at_least_one_slice_consumed_from_slice_iterator_during_current_iteration = False - _slice = None - try: - for partition in self._running_partitions: - self._replace_failed_jobs(partition) - - if self._has_bulk_parent and self._running_partitions and self._slice_iterator.has_next(): - LOGGER.debug( - "This AsyncJobOrchestrator is operating as a child of a bulk stream hence we limit the number of concurrent jobs on the child until there are no more parent slices to avoid the child taking all the API job budget" - ) - return - - for _slice in self._slice_iterator: - at_least_one_slice_consumed_from_slice_iterator_during_current_iteration = True - job = self._start_job(_slice) - self._running_partitions.append(AsyncPartition([job], _slice)) - if self._has_bulk_parent and self._slice_iterator.has_next(): - break - except ConcurrentJobLimitReached: - if at_least_one_slice_consumed_from_slice_iterator_during_current_iteration: - # this means a slice has been consumed but the job couldn't be create therefore we need to put it back at the beginning of the _slice_iterator - self._slice_iterator.add_at_the_beginning(_slice) # type: ignore # we know it's not None here because `ConcurrentJobLimitReached` happens during the for loop - LOGGER.debug("Waiting before creating more jobs as the limit of concurrent jobs has been reached. Will try again later...") - - def _start_job(self, _slice: StreamSlice, previous_job_id: Optional[str] = None) -> AsyncJob: - if previous_job_id: - id_to_replace = previous_job_id - lazy_log(LOGGER, logging.DEBUG, lambda: f"Attempting to replace job {id_to_replace}...") - else: - id_to_replace = self._job_tracker.try_to_get_intent() - - try: - job = self._job_repository.start(_slice) - self._job_tracker.add_job(id_to_replace, job.api_job_id()) - return job - except Exception as exception: - LOGGER.warning(f"Exception has occurred during job creation: {exception}") - if self._is_breaking_exception(exception): - self._job_tracker.remove_job(id_to_replace) - raise exception - return self._keep_api_budget_with_failed_job(_slice, exception, id_to_replace) - - def _keep_api_budget_with_failed_job(self, _slice: StreamSlice, exception: Exception, intent: str) -> AsyncJob: - """ - We have a mechanism to retry job. It is used when a job status is FAILED or TIMED_OUT. The easiest way to retry is to have this job - as created in a failed state and leverage the retry for failed/timed out jobs. This way, we don't have to have another process for - retrying jobs that couldn't be started. - """ - LOGGER.warning( - f"Could not start job for slice {_slice}. Job will be flagged as failed and retried if max number of attempts not reached: {exception}" - ) - traced_exception = exception if isinstance(exception, AirbyteTracedException) else AirbyteTracedException.from_exception(exception) - # Even though we're not sure this will break the stream, we will emit here for simplicity's sake. If we wanted to be more accurate, - # we would keep the exceptions in-memory until we know that we have reached the max attempt. - self._message_repository.emit_message(traced_exception.as_airbyte_message()) - job = self._create_failed_job(_slice) - self._job_tracker.add_job(intent, job.api_job_id()) - return job - - def _create_failed_job(self, stream_slice: StreamSlice) -> AsyncJob: - job = AsyncJob(f"{uuid.uuid4()} - Job that could not start", stream_slice, _NO_TIMEOUT) - job.update_status(AsyncJobStatus.FAILED) - return job - - def _get_running_jobs(self) -> Set[AsyncJob]: - """ - Returns a set of running AsyncJob objects. - - Returns: - Set[AsyncJob]: A set of AsyncJob objects that are currently running. - """ - return {job for partition in self._running_partitions for job in partition.jobs if job.status() == AsyncJobStatus.RUNNING} - - def _update_jobs_status(self) -> None: - """ - Update the status of all running jobs in the repository. - """ - running_jobs = self._get_running_jobs() - if running_jobs: - # update the status only if there are RUNNING jobs - self._job_repository.update_jobs_status(running_jobs) - - def _wait_on_status_update(self) -> None: - """ - Waits for a specified amount of time between status updates. - - - This method is used to introduce a delay between status updates in order to avoid excessive polling. - The duration of the delay is determined by the value of `_WAIT_TIME_BETWEEN_STATUS_UPDATE_IN_SECONDS`. - - Returns: - None - """ - lazy_log( - LOGGER, - logging.DEBUG, - lambda: f"Polling status in progress. There are currently {len(self._running_partitions)} running partitions.", - ) - - lazy_log( - LOGGER, - logging.DEBUG, - lambda: f"Waiting for {self._WAIT_TIME_BETWEEN_STATUS_UPDATE_IN_SECONDS} seconds before next poll...", - ) - time.sleep(self._WAIT_TIME_BETWEEN_STATUS_UPDATE_IN_SECONDS) - - def _process_completed_partition(self, partition: AsyncPartition) -> None: - """ - Process a completed partition. - Args: - partition (AsyncPartition): The completed partition to process. - """ - job_ids = list(map(lambda job: job.api_job_id(), {job for job in partition.jobs})) - LOGGER.info(f"The following jobs for stream slice {partition.stream_slice} have been completed: {job_ids}.") - - # It is important to remove the jobs from the job tracker before yielding the partition as the caller might try to schedule jobs - # but won't be able to as all jobs slots are taken even though job is done. - for job in partition.jobs: - self._job_tracker.remove_job(job.api_job_id()) - - def _process_running_partitions_and_yield_completed_ones(self) -> Generator[AsyncPartition, Any, None]: - """ - Process the running partitions. - - Yields: - AsyncPartition: The processed partition. - - Raises: - Any: Any exception raised during processing. - """ - current_running_partitions: List[AsyncPartition] = [] - for partition in self._running_partitions: - match partition.status: - case AsyncJobStatus.COMPLETED: - self._process_completed_partition(partition) - yield partition - case AsyncJobStatus.RUNNING: - current_running_partitions.append(partition) - case _ if partition.has_reached_max_attempt(): - self._stop_partition(partition) - self._process_partitions_with_errors(partition) - case _: - self._stop_timed_out_jobs(partition) - - # job will be restarted in `_start_job` - current_running_partitions.insert(0, partition) - - for job in partition.jobs: - # We only remove completed jobs as we want failed/timed out jobs to be re-allocated in priority - if job.status() == AsyncJobStatus.COMPLETED: - self._job_tracker.remove_job(job.api_job_id()) - - # update the referenced list with running partitions - self._running_partitions = current_running_partitions - - def _stop_partition(self, partition: AsyncPartition) -> None: - for job in partition.jobs: - if job.status() in _API_SIDE_RUNNING_STATUS: - self._abort_job(job, free_job_allocation=True) - else: - self._job_tracker.remove_job(job.api_job_id()) - - def _stop_timed_out_jobs(self, partition: AsyncPartition) -> None: - for job in partition.jobs: - if job.status() == AsyncJobStatus.TIMED_OUT: - # we don't free allocation here because it is expected to retry the job - self._abort_job(job, free_job_allocation=False) - - def _abort_job(self, job: AsyncJob, free_job_allocation: bool = True) -> None: - try: - self._job_repository.abort(job) - if free_job_allocation: - self._job_tracker.remove_job(job.api_job_id()) - except Exception as exception: - LOGGER.warning(f"Could not free budget for job {job.api_job_id()}: {exception}") - - def _process_partitions_with_errors(self, partition: AsyncPartition) -> None: - """ - Process a partition with status errors (FAILED and TIMEOUT). - - Args: - partition (AsyncPartition): The partition to process. - Returns: - AirbyteTracedException: An exception indicating that at least one job could not be completed. - Raises: - AirbyteTracedException: If at least one job could not be completed. - """ - status_by_job_id = {job.api_job_id(): job.status() for job in partition.jobs} - self._non_breaking_exceptions.append( - AirbyteTracedException( - internal_message=f"At least one job could not be completed for slice {partition.stream_slice}. Job statuses were: {status_by_job_id}. See warning logs for more information.", - failure_type=FailureType.config_error, - ) - ) - - def create_and_get_completed_partitions(self) -> Iterable[AsyncPartition]: - """ - Creates and retrieves completed partitions. - This method continuously starts jobs, updates job status, processes running partitions, - logs polling partitions, and waits for status updates. It yields completed partitions - as they become available. - - Returns: - An iterable of completed partitions, represented as AsyncPartition objects. - Each partition is wrapped in an Optional, allowing for None values. - """ - while True: - try: - lazy_log( - LOGGER, - logging.DEBUG, - lambda: f"JobOrchestrator loop - (Thread {threading.get_native_id()}, AsyncJobOrchestrator {self}) is starting the async job loop", - ) - self._start_jobs() - if not self._slice_iterator.has_next() and not self._running_partitions: - break - - self._update_jobs_status() - yield from self._process_running_partitions_and_yield_completed_ones() - self._wait_on_status_update() - except Exception as exception: - if self._is_breaking_exception(exception): - LOGGER.warning(f"Caught exception that stops the processing of the jobs: {exception}") - self._abort_all_running_jobs() - raise exception - - self._non_breaking_exceptions.append(exception) - - LOGGER.info( - f"JobOrchestrator loop - Thread (Thread {threading.get_native_id()}, AsyncJobOrchestrator {self}) completed! Errors during creation were {self._non_breaking_exceptions}" - ) - if self._non_breaking_exceptions: - # We emitted traced message but we didn't break on non_breaking_exception. We still need to raise an exception so that the - # call of `create_and_get_completed_partitions` knows that there was an issue with some partitions and the sync is incomplete. - raise AirbyteTracedException( - message="", - internal_message="\n".join([filter_secrets(exception.__repr__()) for exception in self._non_breaking_exceptions]), - failure_type=FailureType.config_error, - ) - - def _handle_non_breaking_error(self, exception: Exception) -> None: - LOGGER.error(f"Failed to start the Job: {exception}, traceback: {traceback.format_exc()}") - self._non_breaking_exceptions.append(exception) - - def _abort_all_running_jobs(self) -> None: - for partition in self._running_partitions: - for job in partition.jobs: - if job.status() in self._RUNNING_ON_API_SIDE_STATUS: - self._abort_job(job, free_job_allocation=True) - self._job_tracker.remove_job(job.api_job_id()) - - self._running_partitions = [] - - def _is_breaking_exception(self, exception: Exception) -> bool: - return isinstance(exception, self._exceptions_to_break_on) or ( - isinstance(exception, AirbyteTracedException) and exception.failure_type == FailureType.config_error - ) - - def fetch_records(self, partition: AsyncPartition) -> Iterable[Mapping[str, Any]]: - """ - Fetches records from the given partition's jobs. - - Args: - partition (AsyncPartition): The partition containing the jobs. - - Yields: - Iterable[Mapping[str, Any]]: The fetched records from the jobs. - """ - for job in partition.jobs: - yield from self._job_repository.fetch_records(job) - self._job_repository.delete(job) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/job_tracker.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/job_tracker.py deleted file mode 100644 index 54fbd26d5924..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/job_tracker.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -import logging -import threading -import uuid -from typing import Set - -from airbyte_cdk.logger import lazy_log - -LOGGER = logging.getLogger("airbyte") - - -class ConcurrentJobLimitReached(Exception): - pass - - -class JobTracker: - def __init__(self, limit: int): - self._jobs: Set[str] = set() - self._limit = limit - self._lock = threading.Lock() - - def try_to_get_intent(self) -> str: - lazy_log(LOGGER, logging.DEBUG, lambda: f"JobTracker - Trying to acquire lock by thread {threading.get_native_id()}...") - with self._lock: - if self._has_reached_limit(): - raise ConcurrentJobLimitReached("Can't allocate more jobs right now: limit already reached") - intent = f"intent_{str(uuid.uuid4())}" - lazy_log(LOGGER, logging.DEBUG, lambda: f"JobTracker - Thread {threading.get_native_id()} has acquired {intent}!") - self._jobs.add(intent) - return intent - - def add_job(self, intent_or_job_id: str, job_id: str) -> None: - if intent_or_job_id not in self._jobs: - raise ValueError(f"Can't add job: Unknown intent or job id, known values are {self._jobs}") - - if intent_or_job_id == job_id: - # Nothing to do here as the ID to replace is the same - return - - lazy_log( - LOGGER, logging.DEBUG, lambda: f"JobTracker - Thread {threading.get_native_id()} replacing job {intent_or_job_id} by {job_id}!" - ) - with self._lock: - self._jobs.add(job_id) - self._jobs.remove(intent_or_job_id) - - def remove_job(self, job_id: str) -> None: - """ - If the job is not allocated as a running job, this method does nothing and it won't raise. - """ - lazy_log(LOGGER, logging.DEBUG, lambda: f"JobTracker - Thread {threading.get_native_id()} removing job {job_id}") - with self._lock: - self._jobs.discard(job_id) - - def _has_reached_limit(self) -> bool: - return len(self._jobs) >= self._limit diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/repository.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/repository.py deleted file mode 100644 index b2de8659a393..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/repository.py +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from abc import abstractmethod -from typing import Any, Iterable, Mapping, Set - -from airbyte_cdk.sources.declarative.async_job.job import AsyncJob -from airbyte_cdk.sources.types import StreamSlice - - -class AsyncJobRepository: - @abstractmethod - def start(self, stream_slice: StreamSlice) -> AsyncJob: - pass - - @abstractmethod - def update_jobs_status(self, jobs: Set[AsyncJob]) -> None: - pass - - @abstractmethod - def fetch_records(self, job: AsyncJob) -> Iterable[Mapping[str, Any]]: - pass - - @abstractmethod - def abort(self, job: AsyncJob) -> None: - """ - Called when we need to stop on the API side. This method can raise NotImplementedError as not all the APIs will support aborting - jobs. - """ - raise NotImplementedError("Either the API or the AsyncJobRepository implementation do not support aborting jobs") - - @abstractmethod - def delete(self, job: AsyncJob) -> None: - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/status.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/status.py deleted file mode 100644 index 586e79889ca1..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/status.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - - -from enum import Enum - -_TERMINAL = True - - -class AsyncJobStatus(Enum): - RUNNING = ("RUNNING", not _TERMINAL) - COMPLETED = ("COMPLETED", _TERMINAL) - FAILED = ("FAILED", _TERMINAL) - TIMED_OUT = ("TIMED_OUT", _TERMINAL) - - def __init__(self, value: str, is_terminal: bool) -> None: - self._value = value - self._is_terminal = is_terminal - - def is_terminal(self) -> bool: - """ - A status is terminal when a job status can't be updated anymore. For example if a job is completed, it will stay completed but a - running job might because completed, failed or timed out. - """ - return self._is_terminal diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/timer.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/timer.py deleted file mode 100644 index c4e5a9a1d85a..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/timer.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -from datetime import datetime, timedelta, timezone -from typing import Optional - - -class Timer: - def __init__(self, timeout: timedelta) -> None: - self._start_datetime: Optional[datetime] = None - self._end_datetime: Optional[datetime] = None - self._timeout = timeout - - def start(self) -> None: - self._start_datetime = self._now() - self._end_datetime = None - - def stop(self) -> None: - if self._end_datetime is None: - self._end_datetime = self._now() - - def is_started(self) -> bool: - return self._start_datetime is not None - - @property - def elapsed_time(self) -> Optional[timedelta]: - if not self._start_datetime: - return None - - end_time = self._end_datetime or self._now() - elapsed_period = end_time - self._start_datetime - return elapsed_period - - def has_timed_out(self) -> bool: - if not self.is_started(): - return False - return self.elapsed_time > self._timeout # type: ignore # given the job timer is started, we assume there is an elapsed_period - - @staticmethod - def _now() -> datetime: - return datetime.now(tz=timezone.utc) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/__init__.py deleted file mode 100644 index a02f6f140ba6..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.auth.oauth import DeclarativeOauth2Authenticator -from airbyte_cdk.sources.declarative.auth.jwt import JwtAuthenticator - -__all__ = [ - "DeclarativeOauth2Authenticator", - "JwtAuthenticator" -] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/declarative_authenticator.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/declarative_authenticator.py deleted file mode 100644 index 5517f546209a..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/declarative_authenticator.py +++ /dev/null @@ -1,40 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Mapping, Union - -from airbyte_cdk.sources.streams.http.requests_native_auth.abstract_token import AbstractHeaderAuthenticator - - -@dataclass -class DeclarativeAuthenticator(AbstractHeaderAuthenticator): - """ - Interface used to associate which authenticators can be used as part of the declarative framework - """ - - def get_request_params(self) -> Mapping[str, Any]: - """HTTP request parameter to add to the requests""" - return {} - - def get_request_body_data(self) -> Union[Mapping[str, Any], str]: - """Form-encoded body data to set on the requests""" - return {} - - def get_request_body_json(self) -> Mapping[str, Any]: - """JSON-encoded body data to set on the requests""" - return {} - - -@dataclass -class NoAuth(DeclarativeAuthenticator): - parameters: InitVar[Mapping[str, Any]] - - @property - def auth_header(self) -> str: - return "" - - @property - def token(self) -> str: - return "" diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/jwt.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/jwt.py deleted file mode 100644 index e24ee793715a..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/jwt.py +++ /dev/null @@ -1,170 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import base64 -from dataclasses import InitVar, dataclass -from datetime import datetime -from typing import Any, Mapping, Optional, Union - -import jwt -from airbyte_cdk.sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator -from airbyte_cdk.sources.declarative.interpolation.interpolated_boolean import InterpolatedBoolean -from airbyte_cdk.sources.declarative.interpolation.interpolated_mapping import InterpolatedMapping -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString - - -class JwtAlgorithm(str): - """ - Enum for supported JWT algorithms - """ - - HS256 = "HS256" - HS384 = "HS384" - HS512 = "HS512" - ES256 = "ES256" - ES256K = "ES256K" - ES384 = "ES384" - ES512 = "ES512" - RS256 = "RS256" - RS384 = "RS384" - RS512 = "RS512" - PS256 = "PS256" - PS384 = "PS384" - PS512 = "PS512" - EdDSA = "EdDSA" - - -@dataclass -class JwtAuthenticator(DeclarativeAuthenticator): - """ - Generates a JSON Web Token (JWT) based on a declarative connector configuration file. The generated token is attached to each request via the Authorization header. - - Attributes: - config (Mapping[str, Any]): The user-provided configuration as specified by the source's spec - secret_key (Union[InterpolatedString, str]): The secret key used to sign the JWT - algorithm (Union[str, JwtAlgorithm]): The algorithm used to sign the JWT - token_duration (Optional[int]): The duration in seconds for which the token is valid - base64_encode_secret_key (Optional[Union[InterpolatedBoolean, str, bool]]): Whether to base64 encode the secret key - header_prefix (Optional[Union[InterpolatedString, str]]): The prefix to add to the Authorization header - kid (Optional[Union[InterpolatedString, str]]): The key identifier to be included in the JWT header - typ (Optional[Union[InterpolatedString, str]]): The type of the JWT. - cty (Optional[Union[InterpolatedString, str]]): The content type of the JWT. - iss (Optional[Union[InterpolatedString, str]]): The issuer of the JWT. - sub (Optional[Union[InterpolatedString, str]]): The subject of the JWT. - aud (Optional[Union[InterpolatedString, str]]): The audience of the JWT. - additional_jwt_headers (Optional[Mapping[str, Any]]): Additional headers to include in the JWT. - additional_jwt_payload (Optional[Mapping[str, Any]]): Additional payload to include in the JWT. - """ - - config: Mapping[str, Any] - parameters: InitVar[Mapping[str, Any]] - secret_key: Union[InterpolatedString, str] - algorithm: Union[str, JwtAlgorithm] - token_duration: Optional[int] - base64_encode_secret_key: Optional[Union[InterpolatedBoolean, str, bool]] = False - header_prefix: Optional[Union[InterpolatedString, str]] = None - kid: Optional[Union[InterpolatedString, str]] = None - typ: Optional[Union[InterpolatedString, str]] = None - cty: Optional[Union[InterpolatedString, str]] = None - iss: Optional[Union[InterpolatedString, str]] = None - sub: Optional[Union[InterpolatedString, str]] = None - aud: Optional[Union[InterpolatedString, str]] = None - additional_jwt_headers: Optional[Mapping[str, Any]] = None - additional_jwt_payload: Optional[Mapping[str, Any]] = None - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._secret_key = InterpolatedString.create(self.secret_key, parameters=parameters) - self._algorithm = JwtAlgorithm(self.algorithm) if isinstance(self.algorithm, str) else self.algorithm - self._base64_encode_secret_key = ( - InterpolatedBoolean(self.base64_encode_secret_key, parameters=parameters) - if isinstance(self.base64_encode_secret_key, str) - else self.base64_encode_secret_key - ) - self._token_duration = self.token_duration - self._header_prefix = InterpolatedString.create(self.header_prefix, parameters=parameters) if self.header_prefix else None - self._kid = InterpolatedString.create(self.kid, parameters=parameters) if self.kid else None - self._typ = InterpolatedString.create(self.typ, parameters=parameters) if self.typ else None - self._cty = InterpolatedString.create(self.cty, parameters=parameters) if self.cty else None - self._iss = InterpolatedString.create(self.iss, parameters=parameters) if self.iss else None - self._sub = InterpolatedString.create(self.sub, parameters=parameters) if self.sub else None - self._aud = InterpolatedString.create(self.aud, parameters=parameters) if self.aud else None - self._additional_jwt_headers = InterpolatedMapping(self.additional_jwt_headers or {}, parameters=parameters) - self._additional_jwt_payload = InterpolatedMapping(self.additional_jwt_payload or {}, parameters=parameters) - - def _get_jwt_headers(self) -> dict[str, Any]: - """ " - Builds and returns the headers used when signing the JWT. - """ - headers = self._additional_jwt_headers.eval(self.config) - if any(prop in headers for prop in ["kid", "alg", "typ", "cty"]): - raise ValueError("'kid', 'alg', 'typ', 'cty' are reserved headers and should not be set as part of 'additional_jwt_headers'") - - if self._kid: - headers["kid"] = self._kid.eval(self.config) - if self._typ: - headers["typ"] = self._typ.eval(self.config) - if self._cty: - headers["cty"] = self._cty.eval(self.config) - headers["alg"] = self._algorithm - return headers - - def _get_jwt_payload(self) -> dict[str, Any]: - """ - Builds and returns the payload used when signing the JWT. - """ - now = int(datetime.now().timestamp()) - exp = now + self._token_duration if isinstance(self._token_duration, int) else now - nbf = now - - payload = self._additional_jwt_payload.eval(self.config) - if any(prop in payload for prop in ["iss", "sub", "aud", "iat", "exp", "nbf"]): - raise ValueError( - "'iss', 'sub', 'aud', 'iat', 'exp', 'nbf' are reserved properties and should not be set as part of 'additional_jwt_payload'" - ) - - if self._iss: - payload["iss"] = self._iss.eval(self.config) - if self._sub: - payload["sub"] = self._sub.eval(self.config) - if self._aud: - payload["aud"] = self._aud.eval(self.config) - payload["iat"] = now - payload["exp"] = exp - payload["nbf"] = nbf - return payload - - def _get_secret_key(self) -> str: - """ - Returns the secret key used to sign the JWT. - """ - secret_key: str = self._secret_key.eval(self.config) - return base64.b64encode(secret_key.encode()).decode() if self._base64_encode_secret_key else secret_key - - def _get_signed_token(self) -> Union[str, Any]: - """ - Signed the JWT using the provided secret key and algorithm and the generated headers and payload. For additional information on PyJWT see: https://pyjwt.readthedocs.io/en/stable/ - """ - try: - return jwt.encode( - payload=self._get_jwt_payload(), - key=self._get_secret_key(), - algorithm=self._algorithm, - headers=self._get_jwt_headers(), - ) - except Exception as e: - raise ValueError(f"Failed to sign token: {e}") - - def _get_header_prefix(self) -> Union[str, None]: - """ - Returns the header prefix to be used when attaching the token to the request. - """ - return self._header_prefix.eval(self.config) if self._header_prefix else None - - @property - def auth_header(self) -> str: - return "Authorization" - - @property - def token(self) -> str: - return f"{self._get_header_prefix()} {self._get_signed_token()}" if self._get_header_prefix() else self._get_signed_token() diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/oauth.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/oauth.py deleted file mode 100644 index b68dbcf1583b..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/oauth.py +++ /dev/null @@ -1,148 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass, field -from typing import Any, List, Mapping, Optional, Union - -import pendulum -from airbyte_cdk.sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator -from airbyte_cdk.sources.declarative.interpolation.interpolated_mapping import InterpolatedMapping -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.message import MessageRepository, NoopMessageRepository -from airbyte_cdk.sources.streams.http.requests_native_auth.abstract_oauth import AbstractOauth2Authenticator -from airbyte_cdk.sources.streams.http.requests_native_auth.oauth import SingleUseRefreshTokenOauth2Authenticator - - -@dataclass -class DeclarativeOauth2Authenticator(AbstractOauth2Authenticator, DeclarativeAuthenticator): - """ - Generates OAuth2.0 access tokens from an OAuth2.0 refresh token and client credentials based on - a declarative connector configuration file. Credentials can be defined explicitly or via interpolation - at runtime. The generated access token is attached to each request via the Authorization header. - - Attributes: - token_refresh_endpoint (Union[InterpolatedString, str]): The endpoint to refresh the access token - client_id (Union[InterpolatedString, str]): The client id - client_secret (Union[InterpolatedString, str]): Client secret - refresh_token (Union[InterpolatedString, str]): The token used to refresh the access token - access_token_name (Union[InterpolatedString, str]): THe field to extract access token from in the response - expires_in_name (Union[InterpolatedString, str]): The field to extract expires_in from in the response - config (Mapping[str, Any]): The user-provided configuration as specified by the source's spec - scopes (Optional[List[str]]): The scopes to request - token_expiry_date (Optional[Union[InterpolatedString, str]]): The access token expiration date - token_expiry_date_format str: format of the datetime; provide it if expires_in is returned in datetime instead of seconds - token_expiry_is_time_of_expiration bool: set True it if expires_in is returned as time of expiration instead of the number seconds until expiration - refresh_request_body (Optional[Mapping[str, Any]]): The request body to send in the refresh request - grant_type: The grant_type to request for access_token. If set to refresh_token, the refresh_token parameter has to be provided - message_repository (MessageRepository): the message repository used to emit logs on HTTP requests - """ - - token_refresh_endpoint: Union[InterpolatedString, str] - client_id: Union[InterpolatedString, str] - client_secret: Union[InterpolatedString, str] - config: Mapping[str, Any] - parameters: InitVar[Mapping[str, Any]] - refresh_token: Optional[Union[InterpolatedString, str]] = None - scopes: Optional[List[str]] = None - token_expiry_date: Optional[Union[InterpolatedString, str]] = None - _token_expiry_date: Optional[pendulum.DateTime] = field(init=False, repr=False, default=None) - token_expiry_date_format: Optional[str] = None - token_expiry_is_time_of_expiration: bool = False - access_token_name: Union[InterpolatedString, str] = "access_token" - expires_in_name: Union[InterpolatedString, str] = "expires_in" - refresh_request_body: Optional[Mapping[str, Any]] = None - grant_type: Union[InterpolatedString, str] = "refresh_token" - message_repository: MessageRepository = NoopMessageRepository() - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - super().__init__() - self._token_refresh_endpoint = InterpolatedString.create(self.token_refresh_endpoint, parameters=parameters) - self._client_id = InterpolatedString.create(self.client_id, parameters=parameters) - self._client_secret = InterpolatedString.create(self.client_secret, parameters=parameters) - if self.refresh_token is not None: - self._refresh_token: Optional[InterpolatedString] = InterpolatedString.create(self.refresh_token, parameters=parameters) - else: - self._refresh_token = None - self.access_token_name = InterpolatedString.create(self.access_token_name, parameters=parameters) - self.expires_in_name = InterpolatedString.create(self.expires_in_name, parameters=parameters) - self.grant_type = InterpolatedString.create(self.grant_type, parameters=parameters) - self._refresh_request_body = InterpolatedMapping(self.refresh_request_body or {}, parameters=parameters) - self._token_expiry_date: pendulum.DateTime = ( - pendulum.parse(InterpolatedString.create(self.token_expiry_date, parameters=parameters).eval(self.config)) # type: ignore # pendulum.parse returns a datetime in this context - if self.token_expiry_date - else pendulum.now().subtract(days=1) # type: ignore # substract does not have type hints - ) - self._access_token: Optional[str] = None # access_token is initialized by a setter - - if self.get_grant_type() == "refresh_token" and self._refresh_token is None: - raise ValueError("OAuthAuthenticator needs a refresh_token parameter if grant_type is set to `refresh_token`") - - def get_token_refresh_endpoint(self) -> str: - refresh_token: str = self._token_refresh_endpoint.eval(self.config) - if not refresh_token: - raise ValueError("OAuthAuthenticator was unable to evaluate token_refresh_endpoint parameter") - return refresh_token - - def get_client_id(self) -> str: - client_id: str = self._client_id.eval(self.config) - if not client_id: - raise ValueError("OAuthAuthenticator was unable to evaluate client_id parameter") - return client_id - - def get_client_secret(self) -> str: - client_secret: str = self._client_secret.eval(self.config) - if not client_secret: - raise ValueError("OAuthAuthenticator was unable to evaluate client_secret parameter") - return client_secret - - def get_refresh_token(self) -> Optional[str]: - return None if self._refresh_token is None else str(self._refresh_token.eval(self.config)) - - def get_scopes(self) -> List[str]: - return self.scopes or [] - - def get_access_token_name(self) -> str: - return self.access_token_name.eval(self.config) # type: ignore # eval returns a string in this context - - def get_expires_in_name(self) -> str: - return self.expires_in_name.eval(self.config) # type: ignore # eval returns a string in this context - - def get_grant_type(self) -> str: - return self.grant_type.eval(self.config) # type: ignore # eval returns a string in this context - - def get_refresh_request_body(self) -> Mapping[str, Any]: - return self._refresh_request_body.eval(self.config) # type: ignore # eval should return a Mapping in this context - - def get_token_expiry_date(self) -> pendulum.DateTime: - return self._token_expiry_date # type: ignore # _token_expiry_date is a pendulum.DateTime. It is never None despite what mypy thinks - - def set_token_expiry_date(self, value: Union[str, int]) -> None: - self._token_expiry_date = self._parse_token_expiration_date(value) - - @property - def access_token(self) -> str: - if self._access_token is None: - raise ValueError("access_token is not set") - return self._access_token - - @access_token.setter - def access_token(self, value: str) -> None: - self._access_token = value - - @property - def _message_repository(self) -> MessageRepository: - """ - Overriding AbstractOauth2Authenticator._message_repository to allow for HTTP request logs - """ - return self.message_repository - - -@dataclass -class DeclarativeSingleUseRefreshTokenOauth2Authenticator(SingleUseRefreshTokenOauth2Authenticator, DeclarativeAuthenticator): - """ - Declarative version of SingleUseRefreshTokenOauth2Authenticator which can be used in declarative connectors. - """ - - def __init__(self, *args: Any, **kwargs: Any) -> None: - super().__init__(*args, **kwargs) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/selective_authenticator.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/selective_authenticator.py deleted file mode 100644 index e3f39a0a8ec1..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/selective_authenticator.py +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import dataclass -from typing import Any, List, Mapping - -import dpath -from airbyte_cdk.sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator - - -@dataclass -class SelectiveAuthenticator(DeclarativeAuthenticator): - """Authenticator that selects concrete implementation based on specific config value.""" - - config: Mapping[str, Any] - authenticators: Mapping[str, DeclarativeAuthenticator] - authenticator_selection_path: List[str] - - # returns "DeclarativeAuthenticator", but must return a subtype of "SelectiveAuthenticator" - def __new__( # type: ignore[misc] - cls, - config: Mapping[str, Any], - authenticators: Mapping[str, DeclarativeAuthenticator], - authenticator_selection_path: List[str], - *arg: Any, - **kwargs: Any, - ) -> DeclarativeAuthenticator: - try: - selected_key = str(dpath.get(config, authenticator_selection_path)) - except KeyError as err: - raise ValueError("The path from `authenticator_selection_path` is not found in the config.") from err - - try: - return authenticators[selected_key] - except KeyError as err: - raise ValueError(f"The authenticator `{selected_key}` is not found.") from err diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/token.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/token.py deleted file mode 100644 index a2b64fce04c0..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/token.py +++ /dev/null @@ -1,254 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import base64 -import logging -from dataclasses import InitVar, dataclass -from typing import Any, Mapping, Union - -import requests -from airbyte_cdk.sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator -from airbyte_cdk.sources.declarative.auth.token_provider import TokenProvider -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType -from airbyte_cdk.sources.types import Config -from cachetools import TTLCache, cached - - -@dataclass -class ApiKeyAuthenticator(DeclarativeAuthenticator): - """ - ApiKeyAuth sets a request header on the HTTP requests sent. - - The header is of the form: - `"

": ""` - - For example, - `ApiKeyAuthenticator("Authorization", "Bearer hello")` - will result in the following header set on the HTTP request - `"Authorization": "Bearer hello"` - - Attributes: - request_option (RequestOption): request option how to inject the token into the request - token_provider (TokenProvider): Provider of the token - config (Config): The user-provided configuration as specified by the source's spec - parameters (Mapping[str, Any]): Additional runtime parameters to be used for string interpolation - """ - - request_option: RequestOption - token_provider: TokenProvider - config: Config - parameters: InitVar[Mapping[str, Any]] - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._field_name = InterpolatedString.create(self.request_option.field_name, parameters=parameters) - - @property - def auth_header(self) -> str: - options = self._get_request_options(RequestOptionType.header) - return next(iter(options.keys()), "") - - @property - def token(self) -> str: - return self.token_provider.get_token() - - def _get_request_options(self, option_type: RequestOptionType) -> Mapping[str, Any]: - options = {} - if self.request_option.inject_into == option_type: - options[self._field_name.eval(self.config)] = self.token - return options - - def get_request_params(self) -> Mapping[str, Any]: - return self._get_request_options(RequestOptionType.request_parameter) - - def get_request_body_data(self) -> Union[Mapping[str, Any], str]: - return self._get_request_options(RequestOptionType.body_data) - - def get_request_body_json(self) -> Mapping[str, Any]: - return self._get_request_options(RequestOptionType.body_json) - - -@dataclass -class BearerAuthenticator(DeclarativeAuthenticator): - """ - Authenticator that sets the Authorization header on the HTTP requests sent. - - The header is of the form: - `"Authorization": "Bearer "` - - Attributes: - token_provider (TokenProvider): Provider of the token - config (Config): The user-provided configuration as specified by the source's spec - parameters (Mapping[str, Any]): Additional runtime parameters to be used for string interpolation - """ - - token_provider: TokenProvider - config: Config - parameters: InitVar[Mapping[str, Any]] - - @property - def auth_header(self) -> str: - return "Authorization" - - @property - def token(self) -> str: - return f"Bearer {self.token_provider.get_token()}" - - -@dataclass -class BasicHttpAuthenticator(DeclarativeAuthenticator): - """ - Builds auth based off the basic authentication scheme as defined by RFC 7617, which transmits credentials as USER ID/password pairs, encoded using base64 - https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#basic_authentication_scheme - - The header is of the form - `"Authorization": "Basic "` - - Attributes: - username (Union[InterpolatedString, str]): The username - config (Config): The user-provided configuration as specified by the source's spec - password (Union[InterpolatedString, str]): The password - parameters (Mapping[str, Any]): Additional runtime parameters to be used for string interpolation - """ - - username: Union[InterpolatedString, str] - config: Config - parameters: InitVar[Mapping[str, Any]] - password: Union[InterpolatedString, str] = "" - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._username = InterpolatedString.create(self.username, parameters=parameters) - self._password = InterpolatedString.create(self.password, parameters=parameters) - - @property - def auth_header(self) -> str: - return "Authorization" - - @property - def token(self) -> str: - auth_string = f"{self._username.eval(self.config)}:{self._password.eval(self.config)}".encode("utf8") - b64_encoded = base64.b64encode(auth_string).decode("utf8") - return f"Basic {b64_encoded}" - - -""" - maxsize - The maximum size of the cache - ttl - time-to-live value in seconds - docs https://cachetools.readthedocs.io/en/latest/ - maxsize=1000 - when the cache is full, in this case more than 1000, - i.e. by adding another item the cache would exceed its maximum size, the cache must choose which item(s) to discard - ttl=86400 means that cached token will live for 86400 seconds (one day) -""" -cacheSessionTokenAuthenticator: TTLCache[str, str] = TTLCache(maxsize=1000, ttl=86400) - - -@cached(cacheSessionTokenAuthenticator) -def get_new_session_token(api_url: str, username: str, password: str, response_key: str) -> str: - """ - This method retrieves session token from api by username and password for SessionTokenAuthenticator. - It's cashed to avoid a multiple calling by sync and updating session token every stream sync. - Args: - api_url: api url for getting new session token - username: username for auth - password: password for auth - response_key: field name in response to retrieve a session token - - Returns: - session token - """ - response = requests.post( - f"{api_url}", - headers={"Content-Type": "application/json"}, - json={"username": username, "password": password}, - ) - response.raise_for_status() - if not response.ok: - raise ConnectionError(f"Failed to retrieve new session token, response code {response.status_code} because {response.reason}") - return str(response.json()[response_key]) - - -@dataclass -class LegacySessionTokenAuthenticator(DeclarativeAuthenticator): - """ - Builds auth based on session tokens. - A session token is a random value generated by a server to identify - a specific user for the duration of one interaction session. - - The header is of the form - `"Specific Header": "Session Token Value"` - - Attributes: - api_url (Union[InterpolatedString, str]): Base api url of source - username (Union[InterpolatedString, str]): The username - config (Config): The user-provided configuration as specified by the source's spec - password (Union[InterpolatedString, str]): The password - header (Union[InterpolatedString, str]): Specific header of source for providing session token - parameters (Mapping[str, Any]): Additional runtime parameters to be used for string interpolation - session_token (Union[InterpolatedString, str]): Session token generated by user - session_token_response_key (Union[InterpolatedString, str]): Key for retrieving session token from api response - login_url (Union[InterpolatedString, str]): Url fot getting a specific session token - validate_session_url (Union[InterpolatedString, str]): Url to validate passed session token - """ - - api_url: Union[InterpolatedString, str] - header: Union[InterpolatedString, str] - session_token: Union[InterpolatedString, str] - session_token_response_key: Union[InterpolatedString, str] - username: Union[InterpolatedString, str] - config: Config - parameters: InitVar[Mapping[str, Any]] - login_url: Union[InterpolatedString, str] - validate_session_url: Union[InterpolatedString, str] - password: Union[InterpolatedString, str] = "" - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._username = InterpolatedString.create(self.username, parameters=parameters) - self._password = InterpolatedString.create(self.password, parameters=parameters) - self._api_url = InterpolatedString.create(self.api_url, parameters=parameters) - self._header = InterpolatedString.create(self.header, parameters=parameters) - self._session_token = InterpolatedString.create(self.session_token, parameters=parameters) - self._session_token_response_key = InterpolatedString.create(self.session_token_response_key, parameters=parameters) - self._login_url = InterpolatedString.create(self.login_url, parameters=parameters) - self._validate_session_url = InterpolatedString.create(self.validate_session_url, parameters=parameters) - - self.logger = logging.getLogger("airbyte") - - @property - def auth_header(self) -> str: - return str(self._header.eval(self.config)) - - @property - def token(self) -> str: - if self._session_token.eval(self.config): - if self.is_valid_session_token(): - return str(self._session_token.eval(self.config)) - if self._password.eval(self.config) and self._username.eval(self.config): - username = self._username.eval(self.config) - password = self._password.eval(self.config) - session_token_response_key = self._session_token_response_key.eval(self.config) - api_url = f"{self._api_url.eval(self.config)}{self._login_url.eval(self.config)}" - - self.logger.info("Using generated session token by username and password") - return get_new_session_token(api_url, username, password, session_token_response_key) - - raise ConnectionError("Invalid credentials: session token is not valid or provide username and password") - - def is_valid_session_token(self) -> bool: - try: - response = requests.get( - f"{self._api_url.eval(self.config)}{self._validate_session_url.eval(self.config)}", - headers={self.auth_header: self._session_token.eval(self.config)}, - ) - response.raise_for_status() - except requests.exceptions.HTTPError as e: - if e.response.status_code == requests.codes["unauthorized"]: - self.logger.info(f"Unable to connect by session token from config due to {str(e)}") - return False - else: - raise ConnectionError(f"Error while validating session token: {e}") - if response.ok: - self.logger.info("Connection check for source is successful.") - return True - else: - raise ConnectionError(f"Failed to retrieve new session token, response code {response.status_code} because {response.reason}") diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/token_provider.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/token_provider.py deleted file mode 100644 index c3c2a41f555e..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/token_provider.py +++ /dev/null @@ -1,81 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import datetime -from abc import abstractmethod -from dataclasses import InitVar, dataclass, field -from typing import Any, List, Mapping, Optional, Union - -import dpath -import pendulum -from airbyte_cdk.sources.declarative.decoders.decoder import Decoder -from airbyte_cdk.sources.declarative.decoders.json_decoder import JsonDecoder -from airbyte_cdk.sources.declarative.exceptions import ReadException -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.requesters.requester import Requester -from airbyte_cdk.sources.http_logger import format_http_message -from airbyte_cdk.sources.message import MessageRepository, NoopMessageRepository -from airbyte_cdk.sources.types import Config -from isodate import Duration -from pendulum import DateTime - - -class TokenProvider: - @abstractmethod - def get_token(self) -> str: - pass - - -@dataclass -class SessionTokenProvider(TokenProvider): - login_requester: Requester - session_token_path: List[str] - expiration_duration: Optional[Union[datetime.timedelta, Duration]] - parameters: InitVar[Mapping[str, Any]] - message_repository: MessageRepository = NoopMessageRepository() - decoder: Decoder = field(default_factory=lambda: JsonDecoder(parameters={})) - - _next_expiration_time: Optional[DateTime] = None - _token: Optional[str] = None - - def get_token(self) -> str: - self._refresh_if_necessary() - if self._token is None: - raise ReadException("Failed to get session token, token is None") - return self._token - - def _refresh_if_necessary(self) -> None: - if self._next_expiration_time is None or self._next_expiration_time < pendulum.now(): - self._refresh() - - def _refresh(self) -> None: - response = self.login_requester.send_request( - log_formatter=lambda response: format_http_message( - response, - "Login request", - "Obtains session token", - None, - is_auxiliary=True, - ), - ) - if response is None: - raise ReadException("Failed to get session token, response got ignored by requester") - session_token = dpath.get(next(self.decoder.decode(response)), self.session_token_path) - if self.expiration_duration is not None: - self._next_expiration_time = pendulum.now() + self.expiration_duration - self._token = session_token # type: ignore # Returned decoded response will be Mapping and therefore session_token will be str or None - - -@dataclass -class InterpolatedStringTokenProvider(TokenProvider): - config: Config - api_token: Union[InterpolatedString, str] - parameters: Mapping[str, Any] - - def __post_init__(self) -> None: - self._token = InterpolatedString.create(self.api_token, parameters=self.parameters) - - def get_token(self) -> str: - return str(self._token.eval(self.config)) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/checks/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/checks/__init__.py deleted file mode 100644 index 16244cd1f6f3..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/checks/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.checks.check_stream import CheckStream -from airbyte_cdk.sources.declarative.checks.connection_checker import ConnectionChecker - -__all__ = ["CheckStream", "ConnectionChecker"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/checks/check_stream.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/checks/check_stream.py deleted file mode 100644 index f2e6ad5461c5..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/checks/check_stream.py +++ /dev/null @@ -1,48 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -import traceback -from dataclasses import InitVar, dataclass -from typing import Any, List, Mapping, Tuple - -from airbyte_cdk.sources.declarative.checks.connection_checker import ConnectionChecker -from airbyte_cdk.sources.source import Source -from airbyte_cdk.sources.streams.http.availability_strategy import HttpAvailabilityStrategy - - -@dataclass -class CheckStream(ConnectionChecker): - """ - Checks the connections by checking availability of one or many streams selected by the developer - - Attributes: - stream_name (List[str]): names of streams to check - """ - - stream_names: List[str] - parameters: InitVar[Mapping[str, Any]] - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._parameters = parameters - - def check_connection(self, source: Source, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Any]: - streams = source.streams(config) # type: ignore # source is always a DeclarativeSource, but this parameter type adheres to the outer interface - stream_name_to_stream = {s.name: s for s in streams} - if len(streams) == 0: - return False, f"No streams to connect to from source {source}" - for stream_name in self.stream_names: - if stream_name not in stream_name_to_stream.keys(): - raise ValueError(f"{stream_name} is not part of the catalog. Expected one of {stream_name_to_stream.keys()}.") - - stream = stream_name_to_stream[stream_name] - availability_strategy = HttpAvailabilityStrategy() - try: - stream_is_available, reason = availability_strategy.check_availability(stream, logger) - if not stream_is_available: - return False, reason - except Exception as error: - logger.error(f"Encountered an error trying to connect to stream {stream_name}. Error: \n {traceback.format_exc()}") - return False, f"Unable to connect to stream {stream_name} - {error}" - return True, None diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/checks/connection_checker.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/checks/connection_checker.py deleted file mode 100644 index ede15537f38b..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/checks/connection_checker.py +++ /dev/null @@ -1,33 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from abc import ABC, abstractmethod -from typing import Any, Mapping, Tuple - -from airbyte_cdk.sources.source import Source - - -class ConnectionChecker(ABC): - """ - Abstract base class for checking a connection - """ - - @abstractmethod - def check_connection(self, source: Source, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Any]: - """ - Tests if the input configuration can be used to successfully connect to the integration e.g: if a provided Stripe API token can be used to connect - to the Stripe API. - - :param source: source - :param logger: source logger - :param config: The user-provided configuration as specified by the source's spec. - This usually contains information required to check connection e.g. tokens, secrets and keys etc. - :return: A tuple of (boolean, error). If boolean is true, then the connection check is successful - and we can connect to the underlying data source using the provided configuration. - Otherwise, the input config cannot be used to connect to the underlying data source, - and the "error" object should describe what went wrong. - The error object will be cast to string to display the problem to the user. - """ - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/concurrency_level/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/concurrency_level/__init__.py deleted file mode 100644 index 6c55c15c9d5e..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/concurrency_level/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.concurrency_level.concurrency_level import ConcurrencyLevel - -__all__ = ["ConcurrencyLevel"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/concurrency_level/concurrency_level.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/concurrency_level/concurrency_level.py deleted file mode 100644 index a86c4f8ff8c0..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/concurrency_level/concurrency_level.py +++ /dev/null @@ -1,42 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Mapping, Optional, Union - -from airbyte_cdk.sources.declarative.interpolation import InterpolatedString -from airbyte_cdk.sources.types import Config - - -@dataclass -class ConcurrencyLevel: - """ - Returns the number of worker threads that should be used when syncing concurrent streams in parallel - - Attributes: - default_concurrency (Union[int, str]): The hardcoded integer or interpolation of how many worker threads to use during a sync - max_concurrency (Optional[int]): The maximum number of worker threads to use when the default_concurrency is exceeded - """ - - default_concurrency: Union[int, str] - max_concurrency: Optional[int] - config: Config - parameters: InitVar[Mapping[str, Any]] - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - if isinstance(self.default_concurrency, int): - self._default_concurrency: Union[int, InterpolatedString] = self.default_concurrency - elif "config" in self.default_concurrency and not self.max_concurrency: - raise ValueError("ConcurrencyLevel requires that max_concurrency be defined if the default_concurrency can be used-specified") - else: - self._default_concurrency = InterpolatedString.create(self.default_concurrency, parameters=parameters) - - def get_concurrency_level(self) -> int: - if isinstance(self._default_concurrency, InterpolatedString): - evaluated_default_concurrency = self._default_concurrency.eval(config=self.config) - if not isinstance(evaluated_default_concurrency, int): - raise ValueError("default_concurrency did not evaluate to an integer") - return min(evaluated_default_concurrency, self.max_concurrency) if self.max_concurrency else evaluated_default_concurrency - else: - return self._default_concurrency diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/__init__.py deleted file mode 100644 index bf1f13e1edb2..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.datetime.min_max_datetime import MinMaxDatetime - -__all__ = ["MinMaxDatetime"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/datetime_parser.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/datetime_parser.py deleted file mode 100644 index 93122e29c591..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/datetime_parser.py +++ /dev/null @@ -1,55 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import datetime -from typing import Union - - -class DatetimeParser: - """ - Parses and formats datetime objects according to a specified format. - - This class mainly acts as a wrapper to properly handling timestamp formatting through the "%s" directive. - - %s is part of the list of format codes required by the 1989 C standard, but it is unreliable because it always return a datetime in the system's timezone. - Instead of using the directive directly, we can use datetime.fromtimestamp and dt.timestamp() - """ - - _UNIX_EPOCH = datetime.datetime(1970, 1, 1, tzinfo=datetime.timezone.utc) - - def parse(self, date: Union[str, int], format: str) -> datetime.datetime: - # "%s" is a valid (but unreliable) directive for formatting, but not for parsing - # It is defined as - # The number of seconds since the Epoch, 1970-01-01 00:00:00+0000 (UTC). https://man7.org/linux/man-pages/man3/strptime.3.html - # - # The recommended way to parse a date from its timestamp representation is to use datetime.fromtimestamp - # See https://stackoverflow.com/a/4974930 - if format == "%s": - return datetime.datetime.fromtimestamp(int(date), tz=datetime.timezone.utc) - elif format == "%s_as_float": - return datetime.datetime.fromtimestamp(float(date), tz=datetime.timezone.utc) - elif format == "%ms": - return self._UNIX_EPOCH + datetime.timedelta(milliseconds=int(date)) - - parsed_datetime = datetime.datetime.strptime(str(date), format) - if self._is_naive(parsed_datetime): - return parsed_datetime.replace(tzinfo=datetime.timezone.utc) - return parsed_datetime - - def format(self, dt: datetime.datetime, format: str) -> str: - # strftime("%s") is unreliable because it ignores the time zone information and assumes the time zone of the system it's running on - # It's safer to use the timestamp() method than the %s directive - # See https://stackoverflow.com/a/4974930 - if format == "%s": - return str(int(dt.timestamp())) - if format == "%s_as_float": - return str(float(dt.timestamp())) - if format == "%ms": - # timstamp() returns a float representing the number of seconds since the unix epoch - return str(int(dt.timestamp() * 1000)) - else: - return dt.strftime(format) - - def _is_naive(self, dt: datetime.datetime) -> bool: - return dt.tzinfo is None or dt.tzinfo.utcoffset(dt) is None diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/min_max_datetime.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/min_max_datetime.py deleted file mode 100644 index 2694da2762ca..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/datetime/min_max_datetime.py +++ /dev/null @@ -1,98 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import datetime as dt -from dataclasses import InitVar, dataclass, field -from typing import Any, Mapping, Optional, Union - -from airbyte_cdk.sources.declarative.datetime.datetime_parser import DatetimeParser -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString - - -@dataclass -class MinMaxDatetime: - """ - Compares the provided date against optional minimum or maximum times. If date is earlier than - min_date, then min_date is returned. If date is greater than max_date, then max_date is returned. - If neither, the input date is returned. - - The timestamp format accepts the same format codes as datetime.strfptime, which are - all the format codes required by the 1989 C standard. - Full list of accepted format codes: https://man7.org/linux/man-pages/man3/strftime.3.html - - Attributes: - datetime (Union[InterpolatedString, str]): InterpolatedString or string representing the datetime in the format specified by `datetime_format` - datetime_format (str): Format of the datetime passed as argument - min_datetime (Union[InterpolatedString, str]): Represents the minimum allowed datetime value. - max_datetime (Union[InterpolatedString, str]): Represents the maximum allowed datetime value. - """ - - datetime: Union[InterpolatedString, str] - parameters: InitVar[Mapping[str, Any]] - # datetime_format is a unique case where we inherit it from the parent if it is not specified before using the default value - # which is why we need dedicated getter/setter methods and private dataclass field - datetime_format: str = "" - _datetime_format: str = field(init=False, repr=False, default="") - min_datetime: Union[InterpolatedString, str] = "" - max_datetime: Union[InterpolatedString, str] = "" - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self.datetime = InterpolatedString.create(self.datetime, parameters=parameters or {}) - self._parser = DatetimeParser() - self.min_datetime = InterpolatedString.create(self.min_datetime, parameters=parameters) if self.min_datetime else None # type: ignore - self.max_datetime = InterpolatedString.create(self.max_datetime, parameters=parameters) if self.max_datetime else None # type: ignore - - def get_datetime(self, config: Mapping[str, Any], **additional_parameters: Mapping[str, Any]) -> dt.datetime: - """ - Evaluates and returns the datetime - :param config: The user-provided configuration as specified by the source's spec - :param additional_parameters: Additional arguments to be passed to the strings for interpolation - :return: The evaluated datetime - """ - # We apply a default datetime format here instead of at instantiation, so it can be set by the parent first - datetime_format = self._datetime_format - if not datetime_format: - datetime_format = "%Y-%m-%dT%H:%M:%S.%f%z" - - time = self._parser.parse(str(self.datetime.eval(config, **additional_parameters)), datetime_format) # type: ignore # datetime is always cast to an interpolated string - - if self.min_datetime: - min_time = str(self.min_datetime.eval(config, **additional_parameters)) # type: ignore # min_datetime is always cast to an interpolated string - if min_time: - min_datetime = self._parser.parse(min_time, datetime_format) # type: ignore # min_datetime is always cast to an interpolated string - time = max(time, min_datetime) - if self.max_datetime: - max_time = str(self.max_datetime.eval(config, **additional_parameters)) # type: ignore # max_datetime is always cast to an interpolated string - if max_time: - max_datetime = self._parser.parse(max_time, datetime_format) - time = min(time, max_datetime) - return time - - @property # type: ignore # properties don't play well with dataclasses... - def datetime_format(self) -> str: - """The format of the string representing the datetime""" - return self._datetime_format - - @datetime_format.setter - def datetime_format(self, value: str) -> None: - """Setter for the datetime format""" - # Covers the case where datetime_format is not provided in the constructor, which causes the property object - # to be set which we need to avoid doing - if not isinstance(value, property): - self._datetime_format = value - - @classmethod - def create( - cls, - interpolated_string_or_min_max_datetime: Union[InterpolatedString, str, "MinMaxDatetime"], - parameters: Optional[Mapping[str, Any]] = None, - ) -> "MinMaxDatetime": - if parameters is None: - parameters = {} - if isinstance(interpolated_string_or_min_max_datetime, InterpolatedString) or isinstance( - interpolated_string_or_min_max_datetime, str - ): - return MinMaxDatetime(datetime=interpolated_string_or_min_max_datetime, parameters=parameters) - else: - return interpolated_string_or_min_max_datetime diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_component_schema.yaml b/airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_component_schema.yaml index 3fcbbf34672d..58a88af9ed4b 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_component_schema.yaml +++ b/airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_component_schema.yaml @@ -1,6 +1,9 @@ "$schema": http://json-schema.org/draft-07/schema# "$id": https://github.com/airbytehq/airbyte/blob/master/airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_component_schema.yaml title: DeclarativeSource +# Manually mirrored copy of the DeclarativeSource schema file from the Airbyte CDK: +# https://github.com/airbytehq/airbyte-python-cdk/blob/main/airbyte_cdk/sources/declarative/declarative_component_schema.yaml#L9 +# TODO: Find a way to make this DRY to prevent drift. type: object description: An API source that extracts data according to its declarative components. version: 1.0.0 @@ -1750,6 +1753,45 @@ definitions: type: type: string enum: [XmlDecoder] + CustomDecoder: + title: Custom Decoder + description: Use this to implement custom decoder logic. + type: object + additionalProperties: true + required: + - type + - class_name + properties: + type: + type: string + enum: [CustomDecoder] + class_name: + title: Class Name + description: Fully-qualified name of the class that will be implementing the custom decoding. Has to be a sub class of Decoder. The format is `source_..`. + type: string + additionalProperties: true + examples: + - "source_amazon_ads.components.GzipJsonlDecoder" + $parameters: + type: object + additionalProperties: true + GzipJsonDecoder: + title: GzipJson Decoder + description: Use this if the response is Gzip compressed Json. + type: object + additionalProperties: true + required: + - type + properties: + type: + type: string + enum: [GzipJsonDecoder] + encoding: + type: string + default: utf-8 + $parameters: + type: object + additionalProperties: true ListPartitionRouter: title: List Partition Router description: A Partition router that specifies a list of attributes where each attribute describes a portion of the complete data set for a stream. During a sync, each value is iterated over and can be used as input to outbound API requests. @@ -2404,10 +2446,12 @@ definitions: title: Decoder description: Component decoding the response so records can be extracted. anyOf: + - "$ref": "#/definitions/CustomDecoder" - "$ref": "#/definitions/JsonDecoder" - "$ref": "#/definitions/JsonlDecoder" - "$ref": "#/definitions/IterableDecoder" - "$ref": "#/definitions/XmlDecoder" + - "$ref": "#/definitions/GzipJsonDecoder" $parameters: type: object additionalProperties: true @@ -2520,10 +2564,12 @@ definitions: title: Decoder description: Component decoding the response so records can be extracted. anyOf: + - "$ref": "#/definitions/CustomDecoder" - "$ref": "#/definitions/JsonDecoder" - "$ref": "#/definitions/JsonlDecoder" - "$ref": "#/definitions/IterableDecoder" - "$ref": "#/definitions/XmlDecoder" + - "$ref": "#/definitions/GzipJsonDecoder" $parameters: type: object additionalProperties: true diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_source.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_source.py deleted file mode 100644 index 9135f2a99b5f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_source.py +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from abc import abstractmethod -from typing import Any, Mapping, Tuple - -from airbyte_cdk.sources.abstract_source import AbstractSource -from airbyte_cdk.sources.declarative.checks.connection_checker import ConnectionChecker - - -class DeclarativeSource(AbstractSource): - """ - Base class for declarative Source. Concrete sources need to define the connection_checker to use - """ - - @property - @abstractmethod - def connection_checker(self) -> ConnectionChecker: - """Returns the ConnectionChecker to use for the `check` operation""" - - def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Any]: - """ - :param logger: The source logger - :param config: The user-provided configuration as specified by the source's spec. - This usually contains information required to check connection e.g. tokens, secrets and keys etc. - :return: A tuple of (boolean, error). If boolean is true, then the connection check is successful - and we can connect to the underlying data source using the provided configuration. - Otherwise, the input config cannot be used to connect to the underlying data source, - and the "error" object should describe what went wrong. - The error object will be cast to string to display the problem to the user. - """ - return self.connection_checker.check_connection(self, logger, config) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_stream.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_stream.py deleted file mode 100644 index 09ce080c8ae4..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_stream.py +++ /dev/null @@ -1,211 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import logging -from dataclasses import InitVar, dataclass, field -from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Union - -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.declarative.incremental import GlobalSubstreamCursor, PerPartitionCursor, PerPartitionWithGlobalCursor -from airbyte_cdk.sources.declarative.interpolation import InterpolatedString -from airbyte_cdk.sources.declarative.migrations.state_migration import StateMigration -from airbyte_cdk.sources.declarative.retrievers import SimpleRetriever -from airbyte_cdk.sources.declarative.retrievers.retriever import Retriever -from airbyte_cdk.sources.declarative.schema import DefaultSchemaLoader -from airbyte_cdk.sources.declarative.schema.schema_loader import SchemaLoader -from airbyte_cdk.sources.streams.checkpoint import CheckpointMode, CheckpointReader, Cursor, CursorBasedCheckpointReader -from airbyte_cdk.sources.streams.core import Stream -from airbyte_cdk.sources.types import Config, StreamSlice - - -@dataclass -class DeclarativeStream(Stream): - """ - DeclarativeStream is a Stream that delegates most of its logic to its schema_load and retriever - - Attributes: - name (str): stream name - primary_key (Optional[Union[str, List[str], List[List[str]]]]): the primary key of the stream - schema_loader (SchemaLoader): The schema loader - retriever (Retriever): The retriever - config (Config): The user-provided configuration as specified by the source's spec - stream_cursor_field (Optional[Union[InterpolatedString, str]]): The cursor field - stream. Transformations are applied in the order in which they are defined. - """ - - retriever: Retriever - config: Config - parameters: InitVar[Mapping[str, Any]] - name: str - primary_key: Optional[Union[str, List[str], List[List[str]]]] - state_migrations: List[StateMigration] = field(repr=True, default_factory=list) - schema_loader: Optional[SchemaLoader] = None - _name: str = field(init=False, repr=False, default="") - _primary_key: str = field(init=False, repr=False, default="") - stream_cursor_field: Optional[Union[InterpolatedString, str]] = None - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._stream_cursor_field = ( - InterpolatedString.create(self.stream_cursor_field, parameters=parameters) - if isinstance(self.stream_cursor_field, str) - else self.stream_cursor_field - ) - self._schema_loader = self.schema_loader if self.schema_loader else DefaultSchemaLoader(config=self.config, parameters=parameters) - - @property # type: ignore - def primary_key(self) -> Optional[Union[str, List[str], List[List[str]]]]: - return self._primary_key - - @primary_key.setter - def primary_key(self, value: str) -> None: - if not isinstance(value, property): - self._primary_key = value - - @property - def exit_on_rate_limit(self) -> bool: - return self.retriever.requester.exit_on_rate_limit # type: ignore # abstract Retriever class has not requester attribute - - @exit_on_rate_limit.setter - def exit_on_rate_limit(self, value: bool) -> None: - self.retriever.requester.exit_on_rate_limit = value # type: ignore[attr-defined] - - @property # type: ignore - def name(self) -> str: - """ - :return: Stream name. By default this is the implementing class name, but it can be overridden as needed. - """ - return self._name - - @name.setter - def name(self, value: str) -> None: - if not isinstance(value, property): - self._name = value - - @property - def state(self) -> MutableMapping[str, Any]: - return self.retriever.state # type: ignore - - @state.setter - def state(self, value: MutableMapping[str, Any]) -> None: - """State setter, accept state serialized by state getter.""" - state: Mapping[str, Any] = value - if self.state_migrations: - for migration in self.state_migrations: - if migration.should_migrate(state): - state = migration.migrate(state) - self.retriever.state = state - - def get_updated_state( - self, current_stream_state: MutableMapping[str, Any], latest_record: Mapping[str, Any] - ) -> MutableMapping[str, Any]: - return self.state - - @property - def cursor_field(self) -> Union[str, List[str]]: - """ - Override to return the default cursor field used by this stream e.g: an API entity might always use created_at as the cursor field. - :return: The name of the field used as a cursor. If the cursor is nested, return an array consisting of the path to the cursor. - """ - cursor = self._stream_cursor_field.eval(self.config) # type: ignore # _stream_cursor_field is always cast to interpolated string - return cursor if cursor else [] - - @property - def is_resumable(self) -> bool: - # Declarative sources always implement state getter/setter, but whether it supports checkpointing is based on - # if the retriever has a cursor defined. - return self.retriever.cursor is not None if hasattr(self.retriever, "cursor") else False - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: Optional[List[str]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[Mapping[str, Any]]: - """ - :param: stream_state We knowingly avoid using stream_state as we want cursors to manage their own state. - """ - if stream_slice is None or stream_slice == {}: - # As the parameter is Optional, many would just call `read_records(sync_mode)` during testing without specifying the field - # As part of the declarative model without custom components, this should never happen as the CDK would wire up a - # SinglePartitionRouter that would create this StreamSlice properly - # As part of the declarative model with custom components, a user that would return a `None` slice would now have the default - # empty slice which seems to make sense. - stream_slice = StreamSlice(partition={}, cursor_slice={}) - if not isinstance(stream_slice, StreamSlice): - raise ValueError(f"DeclarativeStream does not support stream_slices that are not StreamSlice. Got {stream_slice}") - yield from self.retriever.read_records(self.get_json_schema(), stream_slice) # type: ignore # records are of the correct type - - def get_json_schema(self) -> Mapping[str, Any]: # type: ignore - """ - :return: A dict of the JSON schema representing this stream. - - The default implementation of this method looks for a JSONSchema file with the same name as this stream's "name" property. - Override as needed. - """ - return self._schema_loader.get_json_schema() - - def stream_slices( - self, *, sync_mode: SyncMode, cursor_field: Optional[List[str]] = None, stream_state: Optional[Mapping[str, Any]] = None - ) -> Iterable[Optional[StreamSlice]]: - """ - Override to define the slices for this stream. See the stream slicing section of the docs for more information. - - :param sync_mode: - :param cursor_field: - :param stream_state: we knowingly avoid using stream_state as we want cursors to manage their own state - :return: - """ - return self.retriever.stream_slices() - - @property - def state_checkpoint_interval(self) -> Optional[int]: - """ - We explicitly disable checkpointing here. There are a couple reasons for that and not all are documented here but: - * In the case where records are not ordered, the granularity of what is ordered is the slice. Therefore, we will only update the - cursor value once at the end of every slice. - * Updating the state once every record would generate issues for data feed stop conditions or semi-incremental syncs where the - important state is the one at the beginning of the slice - """ - return None - - def get_cursor(self) -> Optional[Cursor]: - if self.retriever and isinstance(self.retriever, SimpleRetriever): - return self.retriever.cursor - return None - - def _get_checkpoint_reader( - self, - logger: logging.Logger, - cursor_field: Optional[List[str]], - sync_mode: SyncMode, - stream_state: MutableMapping[str, Any], - ) -> CheckpointReader: - """ - This method is overridden to prevent issues with stream slice classification for incremental streams that have parent streams. - - The classification logic, when used with `itertools.tee`, creates a copy of the stream slices. When `stream_slices` is called - the second time, the parent records generated during the classification phase are lost. This occurs because `itertools.tee` - only buffers the results, meaning the logic in `simple_retriever` that observes and updates the cursor isn't executed again. - - By overriding this method, we ensure that the stream slices are processed correctly and parent records are not lost, - allowing the cursor to function as expected. - """ - mappings_or_slices = self.stream_slices( - cursor_field=cursor_field, - sync_mode=sync_mode, # todo: change this interface to no longer rely on sync_mode for behavior - stream_state=stream_state, - ) - - cursor = self.get_cursor() - checkpoint_mode = self._checkpoint_mode - - if isinstance(cursor, (GlobalSubstreamCursor, PerPartitionCursor, PerPartitionWithGlobalCursor)): - self.has_multiple_slices = True - return CursorBasedCheckpointReader( - stream_slices=mappings_or_slices, - cursor=cursor, - read_state_from_cursor=checkpoint_mode == CheckpointMode.RESUMABLE_FULL_REFRESH, - ) - - return super()._get_checkpoint_reader(logger, cursor_field, sync_mode, stream_state) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/__init__.py deleted file mode 100644 index b67561e989ce..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.decoders.decoder import Decoder -from airbyte_cdk.sources.declarative.decoders.json_decoder import JsonDecoder, JsonlDecoder, IterableDecoder -from airbyte_cdk.sources.declarative.decoders.noop_decoder import NoopDecoder -from airbyte_cdk.sources.declarative.decoders.pagination_decoder_decorator import PaginationDecoderDecorator -from airbyte_cdk.sources.declarative.decoders.xml_decoder import XmlDecoder - -__all__ = ["Decoder", "JsonDecoder", "JsonlDecoder", "IterableDecoder", "NoopDecoder", "PaginationDecoderDecorator", "XmlDecoder"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/decoder.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/decoder.py deleted file mode 100644 index 4e8fdd64444f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/decoder.py +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import abstractmethod -from dataclasses import dataclass -from typing import Any, Generator, MutableMapping - -import requests - - -@dataclass -class Decoder: - """ - Decoder strategy to transform a requests.Response into a Mapping[str, Any] - """ - - @abstractmethod - def is_stream_response(self) -> bool: - """ - Set to True if you'd like to use stream=True option in http requester - """ - - @abstractmethod - def decode(self, response: requests.Response) -> Generator[MutableMapping[str, Any], None, None]: - """ - Decodes a requests.Response into a Mapping[str, Any] or an array - :param response: the response to decode - :return: Generator of Mapping describing the response - """ diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/json_decoder.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/json_decoder.py deleted file mode 100644 index b2c25c3370fe..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/json_decoder.py +++ /dev/null @@ -1,75 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from dataclasses import InitVar, dataclass -from typing import Any, Generator, Mapping - -import requests -from airbyte_cdk.sources.declarative.decoders.decoder import Decoder -from orjson import orjson - -logger = logging.getLogger("airbyte") - - -@dataclass -class JsonDecoder(Decoder): - """ - Decoder strategy that returns the json-encoded content of a response, if any. - """ - - parameters: InitVar[Mapping[str, Any]] - - def is_stream_response(self) -> bool: - return False - - def decode(self, response: requests.Response) -> Generator[Mapping[str, Any], None, None]: - """ - Given the response is an empty string or an emtpy list, the function will return a generator with an empty mapping. - """ - try: - body_json = response.json() - if not isinstance(body_json, list): - body_json = [body_json] - if len(body_json) == 0: - yield {} - else: - yield from body_json - except requests.exceptions.JSONDecodeError: - logger.warning(f"Response cannot be parsed into json: {response.status_code=}, {response.text=}") - yield {} - - -@dataclass -class IterableDecoder(Decoder): - """ - Decoder strategy that returns the string content of the response, if any. - """ - - parameters: InitVar[Mapping[str, Any]] - - def is_stream_response(self) -> bool: - return True - - def decode(self, response: requests.Response) -> Generator[Mapping[str, Any], None, None]: - for line in response.iter_lines(): - yield {"record": line.decode()} - - -@dataclass -class JsonlDecoder(Decoder): - """ - Decoder strategy that returns the json-encoded content of the response, if any. - """ - - parameters: InitVar[Mapping[str, Any]] - - def is_stream_response(self) -> bool: - return True - - def decode(self, response: requests.Response) -> Generator[Mapping[str, Any], None, None]: - # TODO???: set delimiter? usually it is `\n` but maybe it would be useful to set optional? - # https://github.com/airbytehq/airbyte-internal-issues/issues/8436 - for record in response.iter_lines(): - yield orjson.loads(record) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/noop_decoder.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/noop_decoder.py deleted file mode 100644 index eb977712a1ea..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/noop_decoder.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -import logging -from typing import Any, Generator, Mapping - -import requests -from airbyte_cdk.sources.declarative.decoders.decoder import Decoder - -logger = logging.getLogger("airbyte") - - -class NoopDecoder(Decoder): - def is_stream_response(self) -> bool: - return False - - def decode(self, response: requests.Response) -> Generator[Mapping[str, Any], None, None]: - yield from [{}] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/pagination_decoder_decorator.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/pagination_decoder_decorator.py deleted file mode 100644 index dadb717a1723..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/pagination_decoder_decorator.py +++ /dev/null @@ -1,36 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from dataclasses import dataclass -from typing import Any, Generator, MutableMapping - -import requests -from airbyte_cdk.sources.declarative.decoders import Decoder - -logger = logging.getLogger("airbyte") - - -@dataclass -class PaginationDecoderDecorator(Decoder): - """ - Decoder to wrap other decoders when instantiating a DefaultPaginator in order to bypass decoding if the response is streamed. - """ - - def __init__(self, decoder: Decoder): - self._decoder = decoder - - @property - def decoder(self) -> Decoder: - return self._decoder - - def is_stream_response(self) -> bool: - return self._decoder.is_stream_response() - - def decode(self, response: requests.Response) -> Generator[MutableMapping[str, Any], None, None]: - if self._decoder.is_stream_response(): - logger.warning("Response is streamed and therefore will not be decoded for pagination.") - yield {} - else: - yield from self._decoder.decode(response) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/xml_decoder.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/xml_decoder.py deleted file mode 100644 index 7b598ba851f9..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/decoders/xml_decoder.py +++ /dev/null @@ -1,93 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -import logging -from dataclasses import InitVar, dataclass -from typing import Any, Generator, Mapping, MutableMapping -from xml.parsers.expat import ExpatError - -import requests -import xmltodict -from airbyte_cdk.sources.declarative.decoders.decoder import Decoder - -logger = logging.getLogger("airbyte") - - -@dataclass -class XmlDecoder(Decoder): - """ - XmlDecoder is a decoder strategy that parses the XML content of the resopnse, and converts it to a dict. - - This class handles XML attributes by prefixing them with an '@' symbol and represents XML text content by using the '#text' key if the element has attributes or the element name/tag. It does not currently support XML namespace declarations. - - Example XML Input: - - - San Francisco - - - Book Title 1 - 10.99 - - - Gadget - 299.99 - A useful gadget - - - - Converted Output: - { - "root": { - "location: { - "@id": "123, - "#text": "San Francisco" - }, - "item": [ - { - "@id": "1", - "@category": "books", - "name": "Book Title 1", - "price": "10.99" - }, - { - "@id": "2", - "@category": "electronics", - "name": "Gadget", - "price": "299.99", - "description": "A useful gadget" - } - ] - } - } - - Notes: - - Attributes of an XML element are prefixed with an '@' symbol in the dictionary output. - - Text content of an XML element is handled in two different ways, depending on whether - the element has attributes. - - If the element has attributes, the text content will be - represented by the "#text" key. - - If the element does not have any attributes, the text content will be - represented by element name. - - Namespace declarations are not supported in the current implementation. - """ - - parameters: InitVar[Mapping[str, Any]] - - def is_stream_response(self) -> bool: - return False - - def decode(self, response: requests.Response) -> Generator[MutableMapping[str, Any], None, None]: - body_xml = response.text - try: - body_json = xmltodict.parse(body_xml) - if not isinstance(body_json, list): - body_json = [body_json] - if len(body_json) == 0: - yield {} - else: - yield from body_json - except ExpatError as exc: - logger.warning(f"Response cannot be parsed from XML: {response.status_code=}, {response.text=}, {exc=}") - yield {} diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/exceptions.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/exceptions.py deleted file mode 100644 index ca67c6a55a34..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/exceptions.py +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -class ReadException(Exception): - """ - Raise when there is an error reading data from an API Source - """ diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/__init__.py deleted file mode 100644 index 76304b467f43..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.extractors.dpath_extractor import DpathExtractor -from airbyte_cdk.sources.declarative.extractors.http_selector import HttpSelector -from airbyte_cdk.sources.declarative.extractors.record_filter import RecordFilter -from airbyte_cdk.sources.declarative.extractors.record_selector import RecordSelector -from airbyte_cdk.sources.declarative.extractors.response_to_file_extractor import ResponseToFileExtractor - -__all__ = ["HttpSelector", "DpathExtractor", "RecordFilter", "RecordSelector", "ResponseToFileExtractor"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/dpath_extractor.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/dpath_extractor.py deleted file mode 100644 index 512d6919d07f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/dpath_extractor.py +++ /dev/null @@ -1,81 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass, field -from typing import Any, Iterable, List, Mapping, MutableMapping, Union - -import dpath -import requests -from airbyte_cdk.sources.declarative.decoders import Decoder, JsonDecoder -from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.types import Config - - -@dataclass -class DpathExtractor(RecordExtractor): - """ - Record extractor that searches a decoded response over a path defined as an array of fields. - - If the field path points to an array, that array is returned. - If the field path points to an object, that object is returned wrapped as an array. - If the field path points to an empty object, an empty array is returned. - If the field path points to a non-existing path, an empty array is returned. - - Examples of instantiating this transform: - ``` - extractor: - type: DpathExtractor - field_path: - - "root" - - "data" - ``` - - ``` - extractor: - type: DpathExtractor - field_path: - - "root" - - "{{ parameters['field'] }}" - ``` - - ``` - extractor: - type: DpathExtractor - field_path: [] - ``` - - Attributes: - field_path (Union[InterpolatedString, str]): Path to the field that should be extracted - config (Config): The user-provided configuration as specified by the source's spec - decoder (Decoder): The decoder responsible to transfom the response in a Mapping - """ - - field_path: List[Union[InterpolatedString, str]] - config: Config - parameters: InitVar[Mapping[str, Any]] - decoder: Decoder = field(default_factory=lambda: JsonDecoder(parameters={})) - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._field_path = [InterpolatedString.create(path, parameters=parameters) for path in self.field_path] - for path_index in range(len(self.field_path)): - if isinstance(self.field_path[path_index], str): - self._field_path[path_index] = InterpolatedString.create(self.field_path[path_index], parameters=parameters) - - def extract_records(self, response: requests.Response) -> Iterable[MutableMapping[Any, Any]]: - for body in self.decoder.decode(response): - if len(self._field_path) == 0: - extracted = body - else: - path = [path.eval(self.config) for path in self._field_path] - if "*" in path: - extracted = dpath.values(body, path) - else: - extracted = dpath.get(body, path, default=[]) # type: ignore # extracted will be a MutableMapping, given input data structure - if isinstance(extracted, list): - yield from extracted - elif extracted: - yield extracted - else: - yield from [] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/http_selector.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/http_selector.py deleted file mode 100644 index 905477a6c6d9..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/http_selector.py +++ /dev/null @@ -1,36 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import abstractmethod -from typing import Any, Iterable, Mapping, Optional - -import requests -from airbyte_cdk.sources.types import Record, StreamSlice, StreamState - - -class HttpSelector: - """ - Responsible for translating an HTTP response into a list of records by extracting records from the response and optionally filtering - records based on a heuristic. - """ - - @abstractmethod - def select_records( - self, - response: requests.Response, - stream_state: StreamState, - records_schema: Mapping[str, Any], - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Iterable[Record]: - """ - Selects records from the response - :param response: The response to select the records from - :param stream_state: The stream state - :param records_schema: json schema of records to return - :param stream_slice: The stream slice - :param next_page_token: The paginator token - :return: List of Records selected from the response - """ - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/record_extractor.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/record_extractor.py deleted file mode 100644 index 5de6a84a7db7..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/record_extractor.py +++ /dev/null @@ -1,27 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -from abc import abstractmethod -from dataclasses import dataclass -from typing import Any, Iterable, Mapping - -import requests - - -@dataclass -class RecordExtractor: - """ - Responsible for translating an HTTP response into a list of records by extracting records from the response. - """ - - @abstractmethod - def extract_records( - self, - response: requests.Response, - ) -> Iterable[Mapping[str, Any]]: - """ - Selects records from the response - :param response: The response to extract the records from - :return: List of Records extracted from the response - """ - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/record_filter.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/record_filter.py deleted file mode 100644 index f396224c12e8..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/record_filter.py +++ /dev/null @@ -1,118 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import datetime -from dataclasses import InitVar, dataclass -from typing import Any, Iterable, Mapping, Optional, Union - -from airbyte_cdk.sources.declarative.incremental import DatetimeBasedCursor, GlobalSubstreamCursor, PerPartitionWithGlobalCursor -from airbyte_cdk.sources.declarative.interpolation.interpolated_boolean import InterpolatedBoolean -from airbyte_cdk.sources.types import Config, StreamSlice, StreamState - - -@dataclass -class RecordFilter: - """ - Filter applied on a list of Records - - config (Config): The user-provided configuration as specified by the source's spec - condition (str): The string representing the predicate to filter a record. Records will be removed if evaluated to False - """ - - parameters: InitVar[Mapping[str, Any]] - config: Config - condition: str = "" - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._filter_interpolator = InterpolatedBoolean(condition=self.condition, parameters=parameters) - - def filter_records( - self, - records: Iterable[Mapping[str, Any]], - stream_state: StreamState, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Iterable[Mapping[str, Any]]: - kwargs = { - "stream_state": stream_state, - "stream_slice": stream_slice, - "next_page_token": next_page_token, - "stream_slice.extra_fields": stream_slice.extra_fields if stream_slice else {}, - } - for record in records: - if self._filter_interpolator.eval(self.config, record=record, **kwargs): - yield record - - -class ClientSideIncrementalRecordFilterDecorator(RecordFilter): - """ - Applies a filter to a list of records to exclude those that are older than the stream_state/start_date. - - :param DatetimeBasedCursor date_time_based_cursor: Cursor used to extract datetime values - :param PerPartitionCursor per_partition_cursor: Optional Cursor used for mapping cursor value in nested stream_state - """ - - def __init__( - self, - date_time_based_cursor: DatetimeBasedCursor, - substream_cursor: Optional[Union[PerPartitionWithGlobalCursor, GlobalSubstreamCursor]], - **kwargs: Any, - ): - super().__init__(**kwargs) - self._date_time_based_cursor = date_time_based_cursor - self._substream_cursor = substream_cursor - - @property - def _cursor_field(self) -> str: - return self._date_time_based_cursor.cursor_field.eval(self._date_time_based_cursor.config) # type: ignore # eval returns a string in this context - - @property - def _start_date_from_config(self) -> datetime.datetime: - return self._date_time_based_cursor._start_datetime.get_datetime(self._date_time_based_cursor.config) - - @property - def _end_datetime(self) -> datetime.datetime: - return self._date_time_based_cursor.select_best_end_datetime() - - def filter_records( - self, - records: Iterable[Mapping[str, Any]], - stream_state: StreamState, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Iterable[Mapping[str, Any]]: - state_value = self._get_state_value(stream_state, stream_slice or StreamSlice(partition={}, cursor_slice={})) - filter_date: datetime.datetime = self._get_filter_date(state_value) - records = ( - record - for record in records - if self._end_datetime >= self._date_time_based_cursor.parse_date(record[self._cursor_field]) >= filter_date - ) - if self.condition: - records = super().filter_records( - records=records, stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token - ) - yield from records - - def _get_state_value(self, stream_state: StreamState, stream_slice: StreamSlice) -> Optional[str]: - """ - Return cursor_value or None in case it was not found. - Cursor_value may be empty if: - 1. It is an initial sync => no stream_state exist at all. - 2. In Parent-child stream, and we already make initial sync, so stream_state is present. - During the second read, we receive one extra record from parent and therefore no stream_state for this record will be found. - - :param StreamState stream_state: State - :param StreamSlice stream_slice: Current Stream slice - :return Optional[str]: cursor_value in case it was found, otherwise None. - """ - state = (self._substream_cursor or self._date_time_based_cursor).select_state(stream_slice) - - return state.get(self._cursor_field) if state else None - - def _get_filter_date(self, state_value: Optional[str]) -> datetime.datetime: - start_date_parsed = self._start_date_from_config - if state_value: - return max(start_date_parsed, self._date_time_based_cursor.parse_date(state_value)) - else: - return start_date_parsed diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/record_selector.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/record_selector.py deleted file mode 100644 index eed33d858228..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/record_selector.py +++ /dev/null @@ -1,123 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass, field -from typing import Any, Iterable, List, Mapping, Optional - -import requests -from airbyte_cdk.sources.declarative.extractors.http_selector import HttpSelector -from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor -from airbyte_cdk.sources.declarative.extractors.record_filter import RecordFilter -from airbyte_cdk.sources.declarative.models import SchemaNormalization -from airbyte_cdk.sources.declarative.transformations import RecordTransformation -from airbyte_cdk.sources.types import Config, Record, StreamSlice, StreamState -from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer - -SCHEMA_TRANSFORMER_TYPE_MAPPING = { - SchemaNormalization.None_: TransformConfig.NoTransform, - SchemaNormalization.Default: TransformConfig.DefaultSchemaNormalization, -} - - -@dataclass -class RecordSelector(HttpSelector): - """ - Responsible for translating an HTTP response into a list of records by extracting records from the response and optionally filtering - records based on a heuristic. - - Attributes: - extractor (RecordExtractor): The record extractor responsible for extracting records from a response - schema_normalization (TypeTransformer): The record normalizer responsible for casting record values to stream schema types - record_filter (RecordFilter): The record filter responsible for filtering extracted records - transformations (List[RecordTransformation]): The transformations to be done on the records - """ - - extractor: RecordExtractor - config: Config - parameters: InitVar[Mapping[str, Any]] - schema_normalization: TypeTransformer - record_filter: Optional[RecordFilter] = None - transformations: List[RecordTransformation] = field(default_factory=lambda: []) - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._parameters = parameters - - def select_records( - self, - response: requests.Response, - stream_state: StreamState, - records_schema: Mapping[str, Any], - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Iterable[Record]: - """ - Selects records from the response - :param response: The response to select the records from - :param stream_state: The stream state - :param records_schema: json schema of records to return - :param stream_slice: The stream slice - :param next_page_token: The paginator token - :return: List of Records selected from the response - """ - all_data: Iterable[Mapping[str, Any]] = self.extractor.extract_records(response) - yield from self.filter_and_transform(all_data, stream_state, records_schema, stream_slice, next_page_token) - - def filter_and_transform( - self, - all_data: Iterable[Mapping[str, Any]], - stream_state: StreamState, - records_schema: Mapping[str, Any], - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Iterable[Record]: - """ - There is an issue with the selector as of 2024-08-30: it does technology-agnostic processing like filtering, transformation and - normalization with an API that is technology-specific (as requests.Response is only for HTTP communication using the requests - library). - - Until we decide to move this logic away from the selector, we made this method public so that users like AsyncJobRetriever could - share the logic of doing transformations on a set of records. - """ - filtered_data = self._filter(all_data, stream_state, stream_slice, next_page_token) - transformed_data = self._transform(filtered_data, stream_state, stream_slice) - normalized_data = self._normalize_by_schema(transformed_data, schema=records_schema) - for data in normalized_data: - yield Record(data, stream_slice) - - def _normalize_by_schema( - self, records: Iterable[Mapping[str, Any]], schema: Optional[Mapping[str, Any]] - ) -> Iterable[Mapping[str, Any]]: - if schema: - # record has type Mapping[str, Any], but dict[str, Any] expected - for record in records: - normalized_record = dict(record) - self.schema_normalization.transform(normalized_record, schema) - yield normalized_record - else: - yield from records - - def _filter( - self, - records: Iterable[Mapping[str, Any]], - stream_state: StreamState, - stream_slice: Optional[StreamSlice], - next_page_token: Optional[Mapping[str, Any]], - ) -> Iterable[Mapping[str, Any]]: - if self.record_filter: - yield from self.record_filter.filter_records( - records, stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token - ) - else: - yield from records - - def _transform( - self, - records: Iterable[Mapping[str, Any]], - stream_state: StreamState, - stream_slice: Optional[StreamSlice] = None, - ) -> Iterable[Mapping[str, Any]]: - for record in records: - for transformation in self.transformations: - transformation.transform(record, config=self.config, stream_state=stream_state, stream_slice=stream_slice) # type: ignore # record has type Mapping[str, Any], but Dict[str, Any] expected - yield record diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/response_to_file_extractor.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/response_to_file_extractor.py deleted file mode 100644 index 48ef69e12a02..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/extractors/response_to_file_extractor.py +++ /dev/null @@ -1,162 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import logging -import os -import uuid -import zlib -from contextlib import closing -from typing import Any, Dict, Iterable, Mapping, Optional, Tuple - -import pandas as pd -import requests -from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor -from numpy import nan - -EMPTY_STR: str = "" -DEFAULT_ENCODING: str = "utf-8" -DOWNLOAD_CHUNK_SIZE: int = 1024 * 10 - - -class ResponseToFileExtractor(RecordExtractor): - """ - This class is used when having very big HTTP responses (usually streamed) which would require too much memory so we use disk space as - a tradeoff. - - Eventually, we want to support multiple file type by re-using the file based CDK parsers if possible. However, the lift is too high for - a first iteration so we will only support CSV parsing using pandas as salesforce and sendgrid were doing. - """ - - def __init__(self) -> None: - self.logger = logging.getLogger("airbyte") - - def _get_response_encoding(self, headers: Dict[str, Any]) -> str: - """ - Get the encoding of the response based on the provided headers. This method is heavily inspired by the requests library - implementation. - - Args: - headers (Dict[str, Any]): The headers of the response. - Returns: - str: The encoding of the response. - """ - - content_type = headers.get("content-type") - - if not content_type: - return DEFAULT_ENCODING - - content_type, params = requests.utils.parse_header_links(content_type) - - if "charset" in params: - return params["charset"].strip("'\"") # type: ignore # we assume headers are returned as str - - return DEFAULT_ENCODING - - def _filter_null_bytes(self, b: bytes) -> bytes: - """ - Filter out null bytes from a bytes object. - - Args: - b (bytes): The input bytes object. - Returns: - bytes: The filtered bytes object with null bytes removed. - - Referenced Issue: - https://github.com/airbytehq/airbyte/issues/8300 - """ - - res = b.replace(b"\x00", b"") - if len(res) < len(b): - self.logger.warning("Filter 'null' bytes from string, size reduced %d -> %d chars", len(b), len(res)) - return res - - def _save_to_file(self, response: requests.Response) -> Tuple[str, str]: - """ - Saves the binary data from the given response to a temporary file and returns the filepath and response encoding. - - Args: - response (Optional[requests.Response]): The response object containing the binary data. Defaults to None. - - Returns: - Tuple[str, str]: A tuple containing the filepath of the temporary file and the response encoding. - - Raises: - ValueError: If the temporary file does not exist after saving the binary data. - """ - # set filepath for binary data from response - decompressor = zlib.decompressobj(zlib.MAX_WBITS | 32) - needs_decompression = True # we will assume at first that the response is compressed and change the flag if not - - tmp_file = str(uuid.uuid4()) - with closing(response) as response, open(tmp_file, "wb") as data_file: - response_encoding = self._get_response_encoding(dict(response.headers or {})) - for chunk in response.iter_content(chunk_size=DOWNLOAD_CHUNK_SIZE): - try: - if needs_decompression: - data_file.write(decompressor.decompress(chunk)) - needs_decompression = True - else: - data_file.write(self._filter_null_bytes(chunk)) - except zlib.error: - data_file.write(self._filter_null_bytes(chunk)) - needs_decompression = False - - # check the file exists - if os.path.isfile(tmp_file): - return tmp_file, response_encoding - else: - raise ValueError(f"The IO/Error occured while verifying binary data. Tmp file {tmp_file} doesn't exist.") - - def _read_with_chunks(self, path: str, file_encoding: str, chunk_size: int = 100) -> Iterable[Mapping[str, Any]]: - """ - Reads data from a file in chunks and yields each row as a dictionary. - - Args: - path (str): The path to the file to be read. - file_encoding (str): The encoding of the file. - chunk_size (int, optional): The size of each chunk to be read. Defaults to 100. - - Yields: - Mapping[str, Any]: A dictionary representing each row of data. - - Raises: - ValueError: If an IO/Error occurs while reading the temporary data. - """ - - try: - with open(path, "r", encoding=file_encoding) as data: - chunks = pd.read_csv(data, chunksize=chunk_size, iterator=True, dialect="unix", dtype=object) - for chunk in chunks: - chunk = chunk.replace({nan: None}).to_dict(orient="records") - for row in chunk: - yield row - except pd.errors.EmptyDataError as e: - self.logger.info(f"Empty data received. {e}") - yield from [] - except IOError as ioe: - raise ValueError(f"The IO/Error occured while reading tmp data. Called: {path}", ioe) - finally: - # remove binary tmp file, after data is read - os.remove(path) - - def extract_records(self, response: Optional[requests.Response] = None) -> Iterable[Mapping[str, Any]]: - """ - Extracts records from the given response by: - 1) Saving the result to a tmp file - 2) Reading from saved file by chunks to avoid OOM - - Args: - response (Optional[requests.Response]): The response object containing the data. Defaults to None. - - Yields: - Iterable[Mapping[str, Any]]: An iterable of mappings representing the extracted records. - - Returns: - None - """ - if response: - file_path, encoding = self._save_to_file(response) - yield from self._read_with_chunks(file_path, encoding) - else: - yield from [] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/__init__.py deleted file mode 100644 index 11c1cba9913f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (c) 2022 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.incremental.datetime_based_cursor import DatetimeBasedCursor -from airbyte_cdk.sources.declarative.incremental.declarative_cursor import DeclarativeCursor -from airbyte_cdk.sources.declarative.incremental.global_substream_cursor import GlobalSubstreamCursor -from airbyte_cdk.sources.declarative.incremental.per_partition_cursor import CursorFactory, PerPartitionCursor -from airbyte_cdk.sources.declarative.incremental.per_partition_with_global import PerPartitionWithGlobalCursor -from airbyte_cdk.sources.declarative.incremental.resumable_full_refresh_cursor import ( - ChildPartitionResumableFullRefreshCursor, - ResumableFullRefreshCursor, -) - -__all__ = [ - "CursorFactory", - "DatetimeBasedCursor", - "DeclarativeCursor", - "GlobalSubstreamCursor", - "PerPartitionCursor", - "PerPartitionWithGlobalCursor", - "ResumableFullRefreshCursor", - "ChildPartitionResumableFullRefreshCursor", -] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/datetime_based_cursor.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/datetime_based_cursor.py deleted file mode 100644 index fafdabae03b1..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/datetime_based_cursor.py +++ /dev/null @@ -1,380 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import datetime -from dataclasses import InitVar, dataclass, field -from datetime import timedelta -from typing import Any, Callable, Iterable, List, Mapping, MutableMapping, Optional, Union - -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, Level, Type -from airbyte_cdk.sources.declarative.datetime.datetime_parser import DatetimeParser -from airbyte_cdk.sources.declarative.datetime.min_max_datetime import MinMaxDatetime -from airbyte_cdk.sources.declarative.incremental.declarative_cursor import DeclarativeCursor -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.interpolation.jinja import JinjaInterpolation -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType -from airbyte_cdk.sources.message import MessageRepository -from airbyte_cdk.sources.types import Config, Record, StreamSlice, StreamState -from isodate import Duration, duration_isoformat, parse_duration - - -@dataclass -class DatetimeBasedCursor(DeclarativeCursor): - """ - Slices the stream over a datetime range and create a state with format {: } - - Given a start time, end time, a step function, and an optional lookback window, - the stream slicer will partition the date range from start time - lookback window to end time. - - The step function is defined as a string of the form ISO8601 duration - - The timestamp format accepts the same format codes as datetime.strfptime, which are - all the format codes required by the 1989 C standard. - Full list of accepted format codes: https://man7.org/linux/man-pages/man3/strftime.3.html - - Attributes: - start_datetime (Union[MinMaxDatetime, str]): the datetime that determines the earliest record that should be synced - end_datetime (Optional[Union[MinMaxDatetime, str]]): the datetime that determines the last record that should be synced - cursor_field (Union[InterpolatedString, str]): record's cursor field - datetime_format (str): format of the datetime - step (Optional[str]): size of the timewindow (ISO8601 duration) - cursor_granularity (Optional[str]): smallest increment the datetime_format has (ISO 8601 duration) that will be used to ensure that the start of a slice does not overlap with the end of the previous one - config (Config): connection config - start_time_option (Optional[RequestOption]): request option for start time - end_time_option (Optional[RequestOption]): request option for end time - partition_field_start (Optional[str]): partition start time field - partition_field_end (Optional[str]): stream slice end time field - lookback_window (Optional[InterpolatedString]): how many days before start_datetime to read data for (ISO8601 duration) - """ - - start_datetime: Union[MinMaxDatetime, str] - cursor_field: Union[InterpolatedString, str] - datetime_format: str - config: Config - parameters: InitVar[Mapping[str, Any]] - _highest_observed_cursor_field_value: Optional[str] = field( - repr=False, default=None - ) # tracks the latest observed datetime, which may not be safe to emit in the case of out-of-order records - _cursor: Optional[str] = field( - repr=False, default=None - ) # tracks the latest observed datetime that is appropriate to emit as stream state - end_datetime: Optional[Union[MinMaxDatetime, str]] = None - step: Optional[Union[InterpolatedString, str]] = None - cursor_granularity: Optional[str] = None - start_time_option: Optional[RequestOption] = None - end_time_option: Optional[RequestOption] = None - partition_field_start: Optional[str] = None - partition_field_end: Optional[str] = None - lookback_window: Optional[Union[InterpolatedString, str]] = None - message_repository: Optional[MessageRepository] = None - is_compare_strictly: Optional[bool] = False - cursor_datetime_formats: List[str] = field(default_factory=lambda: []) - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - if (self.step and not self.cursor_granularity) or (not self.step and self.cursor_granularity): - raise ValueError( - f"If step is defined, cursor_granularity should be as well and vice-versa. " - f"Right now, step is `{self.step}` and cursor_granularity is `{self.cursor_granularity}`" - ) - self._start_datetime = MinMaxDatetime.create(self.start_datetime, parameters) - self._end_datetime = None if not self.end_datetime else MinMaxDatetime.create(self.end_datetime, parameters) - - self._timezone = datetime.timezone.utc - self._interpolation = JinjaInterpolation() - - self._step = ( - self._parse_timedelta(InterpolatedString.create(self.step, parameters=parameters).eval(self.config)) - if self.step - else datetime.timedelta.max - ) - self._cursor_granularity = self._parse_timedelta(self.cursor_granularity) - self.cursor_field = InterpolatedString.create(self.cursor_field, parameters=parameters) - self._lookback_window = InterpolatedString.create(self.lookback_window, parameters=parameters) if self.lookback_window else None - self._partition_field_start = InterpolatedString.create(self.partition_field_start or "start_time", parameters=parameters) - self._partition_field_end = InterpolatedString.create(self.partition_field_end or "end_time", parameters=parameters) - self._parser = DatetimeParser() - - # If datetime format is not specified then start/end datetime should inherit it from the stream slicer - if not self._start_datetime.datetime_format: - self._start_datetime.datetime_format = self.datetime_format - if self._end_datetime and not self._end_datetime.datetime_format: - self._end_datetime.datetime_format = self.datetime_format - - if not self.cursor_datetime_formats: - self.cursor_datetime_formats = [self.datetime_format] - - def get_stream_state(self) -> StreamState: - return {self.cursor_field.eval(self.config): self._cursor} if self._cursor else {} # type: ignore # cursor_field is converted to an InterpolatedString in __post_init__ - - def set_initial_state(self, stream_state: StreamState) -> None: - """ - Cursors are not initialized with their state. As state is needed in order to function properly, this method should be called - before calling anything else - - :param stream_state: The state of the stream as returned by get_stream_state - """ - self._cursor = stream_state.get(self.cursor_field.eval(self.config)) if stream_state else None # type: ignore # cursor_field is converted to an InterpolatedString in __post_init__ - - def observe(self, stream_slice: StreamSlice, record: Record) -> None: - """ - Register a record with the cursor; the cursor instance can then use it to manage the state of the in-progress stream read. - - :param stream_slice: The current slice, which may or may not contain the most recently observed record - :param record: the most recently-read record, which the cursor can use to update the stream state. Outwardly-visible changes to the - stream state may need to be deferred depending on whether the source reliably orders records by the cursor field. - """ - record_cursor_value = record.get(self.cursor_field.eval(self.config)) # type: ignore # cursor_field is converted to an InterpolatedString in __post_init__ - # if the current record has no cursor value, we cannot meaningfully update the state based on it, so there is nothing more to do - if not record_cursor_value: - return - - start_field = self._partition_field_start.eval(self.config) - end_field = self._partition_field_end.eval(self.config) - is_highest_observed_cursor_value = not self._highest_observed_cursor_field_value or self.parse_date( - record_cursor_value - ) > self.parse_date(self._highest_observed_cursor_field_value) - if ( - self._is_within_daterange_boundaries(record, stream_slice.get(start_field), stream_slice.get(end_field)) # type: ignore # we know that stream_slices for these cursors will use a string representing an unparsed date - and is_highest_observed_cursor_value - ): - self._highest_observed_cursor_field_value = record_cursor_value - - def close_slice(self, stream_slice: StreamSlice, *args: Any) -> None: - if stream_slice.partition: - raise ValueError(f"Stream slice {stream_slice} should not have a partition. Got {stream_slice.partition}.") - cursor_value_str_by_cursor_value_datetime = dict( - map( - # we need to ensure the cursor value is preserved as is in the state else the CATs might complain of something like - # 2023-01-04T17:30:19.000Z' <= '2023-01-04T17:30:19.000000Z' - lambda datetime_str: (self.parse_date(datetime_str), datetime_str), # type: ignore # because of the filter on the next line, this will only be called with a str - filter(lambda item: item, [self._cursor, self._highest_observed_cursor_field_value]), - ) - ) - self._cursor = ( - cursor_value_str_by_cursor_value_datetime[max(cursor_value_str_by_cursor_value_datetime.keys())] - if cursor_value_str_by_cursor_value_datetime - else None - ) - - def stream_slices(self) -> Iterable[StreamSlice]: - """ - Partition the daterange into slices of size = step. - - The start of the window is the minimum datetime between start_datetime - lookback_window and the stream_state's datetime - The end of the window is the minimum datetime between the start of the window and end_datetime. - - :return: - """ - end_datetime = self.select_best_end_datetime() - start_datetime = self._calculate_earliest_possible_value(self.select_best_end_datetime()) - return self._partition_daterange(start_datetime, end_datetime, self._step) - - def select_state(self, stream_slice: Optional[StreamSlice] = None) -> Optional[StreamState]: - # Datetime based cursors operate over slices made up of datetime ranges. Stream state is based on the progress - # through each slice and does not belong to a specific slice. We just return stream state as it is. - return self.get_stream_state() - - def _calculate_earliest_possible_value(self, end_datetime: datetime.datetime) -> datetime.datetime: - lookback_delta = self._parse_timedelta(self._lookback_window.eval(self.config) if self._lookback_window else "P0D") - earliest_possible_start_datetime = min(self._start_datetime.get_datetime(self.config), end_datetime) - cursor_datetime = self._calculate_cursor_datetime_from_state(self.get_stream_state()) - return max(earliest_possible_start_datetime, cursor_datetime) - lookback_delta - - def select_best_end_datetime(self) -> datetime.datetime: - """ - Returns the optimal end datetime. - This method compares the current datetime with a pre-configured end datetime - and returns the earlier of the two. If no pre-configured end datetime is set, - the current datetime is returned. - - :return datetime.datetime: The best end datetime, which is either the current datetime or the pre-configured end datetime, whichever is earlier. - """ - now = datetime.datetime.now(tz=self._timezone) - if not self._end_datetime: - return now - return min(self._end_datetime.get_datetime(self.config), now) - - def _calculate_cursor_datetime_from_state(self, stream_state: Mapping[str, Any]) -> datetime.datetime: - if self.cursor_field.eval(self.config, stream_state=stream_state) in stream_state: # type: ignore # cursor_field is converted to an InterpolatedString in __post_init__ - return self.parse_date(stream_state[self.cursor_field.eval(self.config)]) # type: ignore # cursor_field is converted to an InterpolatedString in __post_init__ - return datetime.datetime.min.replace(tzinfo=datetime.timezone.utc) - - def _format_datetime(self, dt: datetime.datetime) -> str: - return self._parser.format(dt, self.datetime_format) - - def _partition_daterange( - self, start: datetime.datetime, end: datetime.datetime, step: Union[datetime.timedelta, Duration] - ) -> List[StreamSlice]: - start_field = self._partition_field_start.eval(self.config) - end_field = self._partition_field_end.eval(self.config) - dates = [] - - while self._is_within_date_range(start, end): - next_start = self._evaluate_next_start_date_safely(start, step) - end_date = self._get_date(next_start - self._cursor_granularity, end, min) - dates.append( - StreamSlice( - partition={}, cursor_slice={start_field: self._format_datetime(start), end_field: self._format_datetime(end_date)} - ) - ) - start = next_start - return dates - - def _is_within_date_range(self, start: datetime.datetime, end: datetime.datetime) -> bool: - if self.is_compare_strictly: - return start < end - return start <= end - - def _evaluate_next_start_date_safely(self, start: datetime.datetime, step: datetime.timedelta) -> datetime.datetime: - """ - Given that we set the default step at datetime.timedelta.max, we will generate an OverflowError when evaluating the next start_date - This method assumes that users would never enter a step that would generate an overflow. Given that would be the case, the code - would have broken anyway. - """ - try: - return start + step - except OverflowError: - return datetime.datetime.max.replace(tzinfo=datetime.timezone.utc) - - def _get_date( - self, - cursor_value: datetime.datetime, - default_date: datetime.datetime, - comparator: Callable[[datetime.datetime, datetime.datetime], datetime.datetime], - ) -> datetime.datetime: - cursor_date = cursor_value or default_date - return comparator(cursor_date, default_date) - - def parse_date(self, date: str) -> datetime.datetime: - for datetime_format in self.cursor_datetime_formats + [self.datetime_format]: - try: - return self._parser.parse(date, datetime_format) - except ValueError: - pass - raise ValueError(f"No format in {self.cursor_datetime_formats} matching {date}") - - @classmethod - def _parse_timedelta(cls, time_str: Optional[str]) -> Union[datetime.timedelta, Duration]: - """ - :return Parses an ISO 8601 durations into datetime.timedelta or Duration objects. - """ - if not time_str: - return datetime.timedelta(0) - return parse_duration(time_str) - - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._get_request_options(RequestOptionType.request_parameter, stream_slice) - - def get_request_headers( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._get_request_options(RequestOptionType.header, stream_slice) - - def get_request_body_data( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._get_request_options(RequestOptionType.body_data, stream_slice) - - def get_request_body_json( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._get_request_options(RequestOptionType.body_json, stream_slice) - - def request_kwargs(self) -> Mapping[str, Any]: - # Never update kwargs - return {} - - def _get_request_options(self, option_type: RequestOptionType, stream_slice: Optional[StreamSlice]) -> Mapping[str, Any]: - options: MutableMapping[str, Any] = {} - if not stream_slice: - return options - if self.start_time_option and self.start_time_option.inject_into == option_type: - options[self.start_time_option.field_name.eval(config=self.config)] = stream_slice.get( # type: ignore # field_name is always casted to an interpolated string - self._partition_field_start.eval(self.config) - ) - if self.end_time_option and self.end_time_option.inject_into == option_type: - options[self.end_time_option.field_name.eval(config=self.config)] = stream_slice.get(self._partition_field_end.eval(self.config)) # type: ignore # field_name is always casted to an interpolated string - return options - - def should_be_synced(self, record: Record) -> bool: - cursor_field = self.cursor_field.eval(self.config) # type: ignore # cursor_field is converted to an InterpolatedString in __post_init__ - record_cursor_value = record.get(cursor_field) - if not record_cursor_value: - self._send_log( - Level.WARN, - f"Could not find cursor field `{cursor_field}` in record. The incremental sync will assume it needs to be synced", - ) - return True - latest_possible_cursor_value = self.select_best_end_datetime() - earliest_possible_cursor_value = self._calculate_earliest_possible_value(latest_possible_cursor_value) - return self._is_within_daterange_boundaries(record, earliest_possible_cursor_value, latest_possible_cursor_value) - - def _is_within_daterange_boundaries( - self, record: Record, start_datetime_boundary: Union[datetime.datetime, str], end_datetime_boundary: Union[datetime.datetime, str] - ) -> bool: - cursor_field = self.cursor_field.eval(self.config) # type: ignore # cursor_field is converted to an InterpolatedString in __post_init__ - record_cursor_value = record.get(cursor_field) - if not record_cursor_value: - self._send_log( - Level.WARN, - f"Could not find cursor field `{cursor_field}` in record. The record will not be considered when emitting sync state", - ) - return False - if isinstance(start_datetime_boundary, str): - start_datetime_boundary = self.parse_date(start_datetime_boundary) - if isinstance(end_datetime_boundary, str): - end_datetime_boundary = self.parse_date(end_datetime_boundary) - return start_datetime_boundary <= self.parse_date(record_cursor_value) <= end_datetime_boundary - - def _send_log(self, level: Level, message: str) -> None: - if self.message_repository: - self.message_repository.emit_message( - AirbyteMessage( - type=Type.LOG, - log=AirbyteLogMessage(level=level, message=message), - ) - ) - - def is_greater_than_or_equal(self, first: Record, second: Record) -> bool: - cursor_field = self.cursor_field.eval(self.config) # type: ignore # cursor_field is converted to an InterpolatedString in __post_init__ - first_cursor_value = first.get(cursor_field) - second_cursor_value = second.get(cursor_field) - if first_cursor_value and second_cursor_value: - return self.parse_date(first_cursor_value) >= self.parse_date(second_cursor_value) - elif first_cursor_value: - return True - else: - return False - - def set_runtime_lookback_window(self, lookback_window_in_seconds: int) -> None: - """ - Updates the lookback window based on a given number of seconds if the new duration - is greater than the currently configured lookback window. - - :param lookback_window_in_seconds: The lookback duration in seconds to potentially update to. - """ - runtime_lookback_window = duration_isoformat(timedelta(seconds=lookback_window_in_seconds)) - config_lookback = parse_duration(self._lookback_window.eval(self.config) if self._lookback_window else "P0D") - - # Check if the new runtime lookback window is greater than the current config lookback - if parse_duration(runtime_lookback_window) > config_lookback: - self._lookback_window = InterpolatedString.create(runtime_lookback_window, parameters={}) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/declarative_cursor.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/declarative_cursor.py deleted file mode 100644 index adb64d119039..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/declarative_cursor.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from abc import ABC - -from airbyte_cdk.sources.declarative.stream_slicers.stream_slicer import StreamSlicer -from airbyte_cdk.sources.streams.checkpoint.cursor import Cursor - - -class DeclarativeCursor(Cursor, StreamSlicer, ABC): - """ - DeclarativeCursors are components that allow for checkpointing syncs. In addition to managing the fetching and updating of - state, declarative cursors also manage stream slicing and injecting slice values into outbound requests. - """ diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/global_substream_cursor.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/global_substream_cursor.py deleted file mode 100644 index f7454ef083a5..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/global_substream_cursor.py +++ /dev/null @@ -1,333 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import threading -import time -from typing import Any, Callable, Iterable, Mapping, Optional, TypeVar, Union - -from airbyte_cdk.sources.declarative.incremental.datetime_based_cursor import DatetimeBasedCursor -from airbyte_cdk.sources.declarative.incremental.declarative_cursor import DeclarativeCursor -from airbyte_cdk.sources.declarative.partition_routers.partition_router import PartitionRouter -from airbyte_cdk.sources.types import Record, StreamSlice, StreamState - -T = TypeVar("T") - - -def iterate_with_last_flag_and_state( - generator: Iterable[T], get_stream_state_func: Callable[[], Optional[Mapping[str, StreamState]]] -) -> Iterable[tuple[T, bool, Any]]: - """ - Iterates over the given generator, yielding tuples containing the element, a flag - indicating whether it's the last element in the generator, and the result of - `get_stream_state_func` applied to the element. - - Args: - generator: The iterable to iterate over. - get_stream_state_func: A function that takes an element from the generator and - returns its state. - - Returns: - An iterator that yields tuples of the form (element, is_last, state). - """ - - iterator = iter(generator) - - try: - current = next(iterator) - state = get_stream_state_func() - except StopIteration: - return # Return an empty iterator - - for next_item in iterator: - yield current, False, state - current = next_item - state = get_stream_state_func() - - yield current, True, state - - -class Timer: - """ - A simple timer class that measures elapsed time in seconds using a high-resolution performance counter. - """ - - def __init__(self) -> None: - self._start: Optional[int] = None - - def start(self) -> None: - self._start = time.perf_counter_ns() - - def finish(self) -> int: - if self._start: - return ((time.perf_counter_ns() - self._start) / 1e9).__ceil__() - else: - raise RuntimeError("Global substream cursor timer not started") - - -class GlobalSubstreamCursor(DeclarativeCursor): - """ - The GlobalSubstreamCursor is designed to track the state of substreams using a single global cursor. - This class is beneficial for streams with many partitions, as it allows the state to be managed globally - instead of per partition, simplifying state management and reducing the size of state messages. - - This cursor is activated by setting the `global_substream_cursor` parameter for incremental sync. - - Warnings: - - This class enforces a minimal lookback window for substream based on the duration of the previous sync to avoid losing records. This lookback ensures that any records added or updated during the sync are captured in subsequent syncs. - - The global cursor is updated only at the end of the sync. If the sync ends prematurely (e.g., due to an exception), the state will not be updated. - - When using the `incremental_dependency` option, the sync will progress through parent records, preventing the sync from getting infinitely stuck. However, it is crucial to understand the requirements for both the `global_substream_cursor` and `incremental_dependency` options to avoid data loss. - """ - - def __init__(self, stream_cursor: DatetimeBasedCursor, partition_router: PartitionRouter): - self._stream_cursor = stream_cursor - self._partition_router = partition_router - self._timer = Timer() - self._lock = threading.Lock() - self._slice_semaphore = threading.Semaphore(0) # Start with 0, indicating no slices being tracked - self._all_slices_yielded = False - self._lookback_window: Optional[int] = None - self._current_partition: Optional[Mapping[str, Any]] = None - self._last_slice: bool = False - self._parent_state: Optional[Mapping[str, Any]] = None - - def start_slices_generation(self) -> None: - self._timer.start() - - def stream_slices(self) -> Iterable[StreamSlice]: - """ - Generates stream slices, ensuring the last slice is properly flagged and processed. - - This method creates a sequence of stream slices by iterating over partitions and cursor slices. - It holds onto one slice in memory to set `_all_slices_yielded` to `True` before yielding the - final slice. A semaphore is used to track the processing of slices, ensuring that `close_slice` - is called only after all slices have been processed. - - We expect the following events: - * Yields all the slices except the last one. At this point, `close_slice` won't actually close the global slice as `self._all_slices_yielded == False` - * Release the semaphore one last time before setting `self._all_slices_yielded = True`. This will cause `close_slice` to know about all the slices before we indicate that all slices have been yielded so the left side of `if self._all_slices_yielded and self._slice_semaphore._value == 0` will be false if not everything is closed - * Setting `self._all_slices_yielded = True`. We do that before actually yielding the last slice as the caller of `stream_slices` might stop iterating at any point and hence the code after `yield` might not be executed - * Yield the last slice. At that point, once there are as many slices yielded as closes, the global slice will be closed too - """ - slice_generator = ( - StreamSlice(partition=partition, cursor_slice=cursor_slice) - for partition in self._partition_router.stream_slices() - for cursor_slice in self._stream_cursor.stream_slices() - ) - - self.start_slices_generation() - for slice, last, state in iterate_with_last_flag_and_state(slice_generator, self._partition_router.get_stream_state): - self._parent_state = state - self.register_slice(last) - yield slice - self._parent_state = self._partition_router.get_stream_state() - - def generate_slices_from_partition(self, partition: StreamSlice) -> Iterable[StreamSlice]: - slice_generator = ( - StreamSlice(partition=partition, cursor_slice=cursor_slice) for cursor_slice in self._stream_cursor.stream_slices() - ) - - yield from slice_generator - - def register_slice(self, last: bool) -> None: - """ - Tracks the processing of a stream slice. - - Releases the semaphore for each slice. If it's the last slice (`last=True`), - sets `_all_slices_yielded` to `True` to indicate no more slices will be processed. - - Args: - last (bool): True if the current slice is the last in the sequence. - """ - self._slice_semaphore.release() - if last: - self._all_slices_yielded = True - - def set_initial_state(self, stream_state: StreamState) -> None: - """ - Set the initial state for the cursors. - - This method initializes the state for the global cursor using the provided stream state. - - Additionally, it sets the parent state for partition routers that are based on parent streams. If a partition router - does not have parent streams, this step will be skipped due to the default PartitionRouter implementation. - - Args: - stream_state (StreamState): The state of the streams to be set. The format of the stream state should be: - { - "state": { - "last_updated": "2023-05-27T00:00:00Z" - }, - "parent_state": { - "parent_stream_name": { - "last_updated": "2023-05-27T00:00:00Z" - } - }, - "lookback_window": 132 - } - """ - if not stream_state: - return - - if "lookback_window" in stream_state: - self._lookback_window = stream_state["lookback_window"] - self._inject_lookback_into_stream_cursor(stream_state["lookback_window"]) - - if "state" in stream_state: - self._stream_cursor.set_initial_state(stream_state["state"]) - elif "states" not in stream_state: - # We assume that `stream_state` is in the old global format - # Example: {"global_state_format_key": "global_state_format_value"} - self._stream_cursor.set_initial_state(stream_state) - - # Set parent state for partition routers based on parent streams - self._partition_router.set_initial_state(stream_state) - - def _inject_lookback_into_stream_cursor(self, lookback_window: int) -> None: - """ - Modifies the stream cursor's lookback window based on the duration of the previous sync. - This adjustment ensures the cursor is set to the minimal lookback window necessary for - avoiding missing data. - - Parameters: - lookback_window (int): The lookback duration in seconds to be set, derived from - the previous sync. - - Raises: - ValueError: If the cursor does not support dynamic lookback window adjustments. - """ - if hasattr(self._stream_cursor, "set_runtime_lookback_window"): - self._stream_cursor.set_runtime_lookback_window(lookback_window) - else: - raise ValueError("The cursor class for Global Substream Cursor does not have a set_runtime_lookback_window method") - - def observe(self, stream_slice: StreamSlice, record: Record) -> None: - self._stream_cursor.observe(StreamSlice(partition={}, cursor_slice=stream_slice.cursor_slice), record) - - def close_slice(self, stream_slice: StreamSlice, *args: Any) -> None: - """ - Close the current stream slice. - - This method is called when a stream slice is completed. For the global parent cursor, we close the child cursor - only after reading all slices. This ensures that we do not miss any child records from a later parent record - if the child cursor is earlier than a record from the first parent record. - - Args: - stream_slice (StreamSlice): The stream slice to be closed. - *args (Any): Additional arguments. - """ - with self._lock: - self._slice_semaphore.acquire() - if self._all_slices_yielded and self._slice_semaphore._value == 0: - self._lookback_window = self._timer.finish() - self._stream_cursor.close_slice(StreamSlice(partition={}, cursor_slice=stream_slice.cursor_slice), *args) - - def get_stream_state(self) -> StreamState: - state: dict[str, Any] = {"state": self._stream_cursor.get_stream_state()} - - if self._parent_state: - state["parent_state"] = self._parent_state - - if self._lookback_window is not None: - state["lookback_window"] = self._lookback_window - - return state - - def select_state(self, stream_slice: Optional[StreamSlice] = None) -> Optional[StreamState]: - # stream_slice is ignored as cursor is global - return self._stream_cursor.get_stream_state() - - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - if stream_slice: - return self._partition_router.get_request_params( # type: ignore # this always returns a mapping - stream_state=stream_state, - stream_slice=StreamSlice(partition=stream_slice.partition, cursor_slice={}), - next_page_token=next_page_token, - ) | self._stream_cursor.get_request_params( - stream_state=stream_state, - stream_slice=StreamSlice(partition={}, cursor_slice=stream_slice.cursor_slice), - next_page_token=next_page_token, - ) - else: - raise ValueError("A partition needs to be provided in order to get request params") - - def get_request_headers( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - if stream_slice: - return self._partition_router.get_request_headers( # type: ignore # this always returns a mapping - stream_state=stream_state, - stream_slice=StreamSlice(partition=stream_slice.partition, cursor_slice={}), - next_page_token=next_page_token, - ) | self._stream_cursor.get_request_headers( - stream_state=stream_state, - stream_slice=StreamSlice(partition={}, cursor_slice=stream_slice.cursor_slice), - next_page_token=next_page_token, - ) - else: - raise ValueError("A partition needs to be provided in order to get request headers") - - def get_request_body_data( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Union[Mapping[str, Any], str]: - if stream_slice: - return self._partition_router.get_request_body_data( # type: ignore # this always returns a mapping - stream_state=stream_state, - stream_slice=StreamSlice(partition=stream_slice.partition, cursor_slice={}), - next_page_token=next_page_token, - ) | self._stream_cursor.get_request_body_data( - stream_state=stream_state, - stream_slice=StreamSlice(partition={}, cursor_slice=stream_slice.cursor_slice), - next_page_token=next_page_token, - ) - else: - raise ValueError("A partition needs to be provided in order to get request body data") - - def get_request_body_json( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - if stream_slice: - return self._partition_router.get_request_body_json( # type: ignore # this always returns a mapping - stream_state=stream_state, - stream_slice=StreamSlice(partition=stream_slice.partition, cursor_slice={}), - next_page_token=next_page_token, - ) | self._stream_cursor.get_request_body_json( - stream_state=stream_state, - stream_slice=StreamSlice(partition={}, cursor_slice=stream_slice.cursor_slice), - next_page_token=next_page_token, - ) - else: - raise ValueError("A partition needs to be provided in order to get request body json") - - def should_be_synced(self, record: Record) -> bool: - return self._stream_cursor.should_be_synced(self._convert_record_to_cursor_record(record)) - - def is_greater_than_or_equal(self, first: Record, second: Record) -> bool: - return self._stream_cursor.is_greater_than_or_equal( - self._convert_record_to_cursor_record(first), self._convert_record_to_cursor_record(second) - ) - - @staticmethod - def _convert_record_to_cursor_record(record: Record) -> Record: - return Record( - record.data, - StreamSlice(partition={}, cursor_slice=record.associated_slice.cursor_slice) if record.associated_slice else None, - ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/per_partition_cursor.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/per_partition_cursor.py deleted file mode 100644 index 86236ec92230..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/per_partition_cursor.py +++ /dev/null @@ -1,314 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from collections import OrderedDict -from typing import Any, Callable, Iterable, Mapping, Optional, Union - -from airbyte_cdk.sources.declarative.incremental.declarative_cursor import DeclarativeCursor -from airbyte_cdk.sources.declarative.partition_routers.partition_router import PartitionRouter -from airbyte_cdk.sources.streams.checkpoint.per_partition_key_serializer import PerPartitionKeySerializer -from airbyte_cdk.sources.types import Record, StreamSlice, StreamState - -logger = logging.getLogger("airbyte") - - -class CursorFactory: - def __init__(self, create_function: Callable[[], DeclarativeCursor]): - self._create_function = create_function - - def create(self) -> DeclarativeCursor: - return self._create_function() - - -class PerPartitionCursor(DeclarativeCursor): - """ - Manages state per partition when a stream has many partitions, to prevent data loss or duplication. - - **Partition Limitation and Limit Reached Logic** - - - **DEFAULT_MAX_PARTITIONS_NUMBER**: The maximum number of partitions to keep in memory (default is 10,000). - - **_cursor_per_partition**: An ordered dictionary that stores cursors for each partition. - - **_over_limit**: A counter that increments each time an oldest partition is removed when the limit is exceeded. - - The class ensures that the number of partitions tracked does not exceed the `DEFAULT_MAX_PARTITIONS_NUMBER` to prevent excessive memory usage. - - - When the number of partitions exceeds the limit, the oldest partitions are removed from `_cursor_per_partition`, and `_over_limit` is incremented accordingly. - - The `limit_reached` method returns `True` when `_over_limit` exceeds `DEFAULT_MAX_PARTITIONS_NUMBER`, indicating that the global cursor should be used instead of per-partition cursors. - - This approach avoids unnecessary switching to a global cursor due to temporary spikes in partition counts, ensuring that switching is only done when a sustained high number of partitions is observed. - """ - - DEFAULT_MAX_PARTITIONS_NUMBER = 10000 - _NO_STATE: Mapping[str, Any] = {} - _NO_CURSOR_STATE: Mapping[str, Any] = {} - _KEY = 0 - _VALUE = 1 - _state_to_migrate_from: Mapping[str, Any] = {} - - def __init__(self, cursor_factory: CursorFactory, partition_router: PartitionRouter): - self._cursor_factory = cursor_factory - self._partition_router = partition_router - # The dict is ordered to ensure that once the maximum number of partitions is reached, - # the oldest partitions can be efficiently removed, maintaining the most recent partitions. - self._cursor_per_partition: OrderedDict[str, DeclarativeCursor] = OrderedDict() - self._over_limit = 0 - self._partition_serializer = PerPartitionKeySerializer() - - def stream_slices(self) -> Iterable[StreamSlice]: - slices = self._partition_router.stream_slices() - for partition in slices: - yield from self.generate_slices_from_partition(partition) - - def generate_slices_from_partition(self, partition: StreamSlice) -> Iterable[StreamSlice]: - # Ensure the maximum number of partitions is not exceeded - self._ensure_partition_limit() - - cursor = self._cursor_per_partition.get(self._to_partition_key(partition.partition)) - if not cursor: - partition_state = self._state_to_migrate_from if self._state_to_migrate_from else self._NO_CURSOR_STATE - cursor = self._create_cursor(partition_state) - self._cursor_per_partition[self._to_partition_key(partition.partition)] = cursor - - for cursor_slice in cursor.stream_slices(): - yield StreamSlice(partition=partition, cursor_slice=cursor_slice, extra_fields=partition.extra_fields) - - def _ensure_partition_limit(self) -> None: - """ - Ensure the maximum number of partitions is not exceeded. If so, the oldest added partition will be dropped. - """ - while len(self._cursor_per_partition) > self.DEFAULT_MAX_PARTITIONS_NUMBER - 1: - self._over_limit += 1 - oldest_partition = self._cursor_per_partition.popitem(last=False)[0] # Remove the oldest partition - logger.warning( - f"The maximum number of partitions has been reached. Dropping the oldest partition: {oldest_partition}. Over limit: {self._over_limit}." - ) - - def limit_reached(self) -> bool: - return self._over_limit > self.DEFAULT_MAX_PARTITIONS_NUMBER - - def set_initial_state(self, stream_state: StreamState) -> None: - """ - Set the initial state for the cursors. - - This method initializes the state for each partition cursor using the provided stream state. - If a partition state is provided in the stream state, it will update the corresponding partition cursor with this state. - - Additionally, it sets the parent state for partition routers that are based on parent streams. If a partition router - does not have parent streams, this step will be skipped due to the default PartitionRouter implementation. - - Args: - stream_state (StreamState): The state of the streams to be set. The format of the stream state should be: - { - "states": [ - { - "partition": { - "partition_key": "value" - }, - "cursor": { - "last_updated": "2023-05-27T00:00:00Z" - } - } - ], - "parent_state": { - "parent_stream_name": { - "last_updated": "2023-05-27T00:00:00Z" - } - } - } - """ - if not stream_state: - return - - if "states" not in stream_state: - # We assume that `stream_state` is in a global format that can be applied to all partitions. - # Example: {"global_state_format_key": "global_state_format_value"} - self._state_to_migrate_from = stream_state - - else: - for state in stream_state["states"]: - self._cursor_per_partition[self._to_partition_key(state["partition"])] = self._create_cursor(state["cursor"]) - - # set default state for missing partitions if it is per partition with fallback to global - if "state" in stream_state: - self._state_to_migrate_from = stream_state["state"] - - # Set parent state for partition routers based on parent streams - self._partition_router.set_initial_state(stream_state) - - def observe(self, stream_slice: StreamSlice, record: Record) -> None: - self._cursor_per_partition[self._to_partition_key(stream_slice.partition)].observe( - StreamSlice(partition={}, cursor_slice=stream_slice.cursor_slice), record - ) - - def close_slice(self, stream_slice: StreamSlice, *args: Any) -> None: - try: - self._cursor_per_partition[self._to_partition_key(stream_slice.partition)].close_slice( - StreamSlice(partition={}, cursor_slice=stream_slice.cursor_slice), *args - ) - except KeyError as exception: - raise ValueError( - f"Partition {str(exception)} could not be found in current state based on the record. This is unexpected because " - f"we should only update state for partitions that were emitted during `stream_slices`" - ) - - def get_stream_state(self) -> StreamState: - states = [] - for partition_tuple, cursor in self._cursor_per_partition.items(): - cursor_state = cursor.get_stream_state() - if cursor_state: - states.append( - { - "partition": self._to_dict(partition_tuple), - "cursor": cursor_state, - } - ) - state: dict[str, Any] = {"states": states} - - parent_state = self._partition_router.get_stream_state() - if parent_state: - state["parent_state"] = parent_state - return state - - def _get_state_for_partition(self, partition: Mapping[str, Any]) -> Optional[StreamState]: - cursor = self._cursor_per_partition.get(self._to_partition_key(partition)) - if cursor: - return cursor.get_stream_state() - - return None - - @staticmethod - def _is_new_state(stream_state: Mapping[str, Any]) -> bool: - return not bool(stream_state) - - def _to_partition_key(self, partition: Mapping[str, Any]) -> str: - return self._partition_serializer.to_partition_key(partition) - - def _to_dict(self, partition_key: str) -> Mapping[str, Any]: - return self._partition_serializer.to_partition(partition_key) - - def select_state(self, stream_slice: Optional[StreamSlice] = None) -> Optional[StreamState]: - if not stream_slice: - raise ValueError("A partition needs to be provided in order to extract a state") - - if not stream_slice: - return None - - return self._get_state_for_partition(stream_slice.partition) - - def _create_cursor(self, cursor_state: Any) -> DeclarativeCursor: - cursor = self._cursor_factory.create() - cursor.set_initial_state(cursor_state) - return cursor - - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - if stream_slice: - return self._partition_router.get_request_params( # type: ignore # this always returns a mapping - stream_state=stream_state, - stream_slice=StreamSlice(partition=stream_slice.partition, cursor_slice={}), - next_page_token=next_page_token, - ) | self._cursor_per_partition[self._to_partition_key(stream_slice.partition)].get_request_params( - stream_state=stream_state, - stream_slice=StreamSlice(partition={}, cursor_slice=stream_slice.cursor_slice), - next_page_token=next_page_token, - ) - else: - raise ValueError("A partition needs to be provided in order to get request params") - - def get_request_headers( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - if stream_slice: - return self._partition_router.get_request_headers( # type: ignore # this always returns a mapping - stream_state=stream_state, - stream_slice=StreamSlice(partition=stream_slice.partition, cursor_slice={}), - next_page_token=next_page_token, - ) | self._cursor_per_partition[self._to_partition_key(stream_slice.partition)].get_request_headers( - stream_state=stream_state, - stream_slice=StreamSlice(partition={}, cursor_slice=stream_slice.cursor_slice), - next_page_token=next_page_token, - ) - else: - raise ValueError("A partition needs to be provided in order to get request headers") - - def get_request_body_data( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Union[Mapping[str, Any], str]: - if stream_slice: - return self._partition_router.get_request_body_data( # type: ignore # this always returns a mapping - stream_state=stream_state, - stream_slice=StreamSlice(partition=stream_slice.partition, cursor_slice={}), - next_page_token=next_page_token, - ) | self._cursor_per_partition[self._to_partition_key(stream_slice.partition)].get_request_body_data( - stream_state=stream_state, - stream_slice=StreamSlice(partition={}, cursor_slice=stream_slice.cursor_slice), - next_page_token=next_page_token, - ) - else: - raise ValueError("A partition needs to be provided in order to get request body data") - - def get_request_body_json( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - if stream_slice: - return self._partition_router.get_request_body_json( # type: ignore # this always returns a mapping - stream_state=stream_state, - stream_slice=StreamSlice(partition=stream_slice.partition, cursor_slice={}), - next_page_token=next_page_token, - ) | self._cursor_per_partition[self._to_partition_key(stream_slice.partition)].get_request_body_json( - stream_state=stream_state, - stream_slice=StreamSlice(partition={}, cursor_slice=stream_slice.cursor_slice), - next_page_token=next_page_token, - ) - else: - raise ValueError("A partition needs to be provided in order to get request body json") - - def should_be_synced(self, record: Record) -> bool: - return self._get_cursor(record).should_be_synced(self._convert_record_to_cursor_record(record)) - - def is_greater_than_or_equal(self, first: Record, second: Record) -> bool: - if not first.associated_slice or not second.associated_slice: - raise ValueError(f"Both records should have an associated slice but got {first.associated_slice} and {second.associated_slice}") - if first.associated_slice.partition != second.associated_slice.partition: - raise ValueError( - f"To compare records, partition should be the same but got {first.associated_slice.partition} and {second.associated_slice.partition}" - ) - - return self._get_cursor(first).is_greater_than_or_equal( - self._convert_record_to_cursor_record(first), self._convert_record_to_cursor_record(second) - ) - - @staticmethod - def _convert_record_to_cursor_record(record: Record) -> Record: - return Record( - record.data, - StreamSlice(partition={}, cursor_slice=record.associated_slice.cursor_slice) if record.associated_slice else None, - ) - - def _get_cursor(self, record: Record) -> DeclarativeCursor: - if not record.associated_slice: - raise ValueError("Invalid state as stream slices that are emitted should refer to an existing cursor") - partition_key = self._to_partition_key(record.associated_slice.partition) - if partition_key not in self._cursor_per_partition: - raise ValueError("Invalid state as stream slices that are emitted should refer to an existing cursor") - cursor = self._cursor_per_partition[partition_key] - return cursor diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/per_partition_with_global.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/per_partition_with_global.py deleted file mode 100644 index d5ad6b40d1b8..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/per_partition_with_global.py +++ /dev/null @@ -1,188 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -from typing import Any, Iterable, Mapping, MutableMapping, Optional, Union - -from airbyte_cdk.sources.declarative.incremental.datetime_based_cursor import DatetimeBasedCursor -from airbyte_cdk.sources.declarative.incremental.declarative_cursor import DeclarativeCursor -from airbyte_cdk.sources.declarative.incremental.global_substream_cursor import GlobalSubstreamCursor, iterate_with_last_flag_and_state -from airbyte_cdk.sources.declarative.incremental.per_partition_cursor import CursorFactory, PerPartitionCursor -from airbyte_cdk.sources.declarative.partition_routers.partition_router import PartitionRouter -from airbyte_cdk.sources.types import Record, StreamSlice, StreamState - - -class PerPartitionWithGlobalCursor(DeclarativeCursor): - """ - Manages state for streams with multiple partitions, with an optional fallback to a global cursor when specific conditions are met. - - This cursor handles partitioned streams by maintaining individual state per partition using `PerPartitionCursor`. If the number of partitions exceeds a defined limit, it switches to a global cursor (`GlobalSubstreamCursor`) to manage state more efficiently. - - **Overview** - - - **Partition-Based State**: Initially manages state per partition to ensure accurate processing of each partition's data. - - **Global Fallback**: Switches to a global cursor when the partition limit is exceeded to handle state management more effectively. - - **Switching Logic** - - - Monitors the number of partitions. - - If `PerPartitionCursor.limit_reached()` returns `True`, sets `_use_global_cursor` to `True`, activating the global cursor. - - **Active Cursor Selection** - - - Uses the `_get_active_cursor()` helper method to select the active cursor based on the `_use_global_cursor` flag. - - This simplifies the logic and ensures consistent cursor usage across methods. - - **State Structure Example** - - ```json - { - "states": [ - { - "partition": {"partition_key": "partition_1"}, - "cursor": {"cursor_field": "2021-01-15"} - }, - { - "partition": {"partition_key": "partition_2"}, - "cursor": {"cursor_field": "2021-02-14"} - } - ], - "state": { - "cursor_field": "2021-02-15" - }, - "use_global_cursor": false - } - ``` - - In this example, the cursor is using partition-based state management (`"use_global_cursor": false`), maintaining separate cursor states for each partition. - - **Usage Scenario** - - Suitable for streams where the number of partitions may vary significantly, requiring dynamic switching between per-partition and global state management to ensure data consistency and efficient synchronization. - """ - - def __init__(self, cursor_factory: CursorFactory, partition_router: PartitionRouter, stream_cursor: DatetimeBasedCursor): - self._partition_router = partition_router - self._per_partition_cursor = PerPartitionCursor(cursor_factory, partition_router) - self._global_cursor = GlobalSubstreamCursor(stream_cursor, partition_router) - self._use_global_cursor = False - self._current_partition: Optional[Mapping[str, Any]] = None - self._last_slice: bool = False - self._parent_state: Optional[Mapping[str, Any]] = None - - def _get_active_cursor(self) -> Union[PerPartitionCursor, GlobalSubstreamCursor]: - return self._global_cursor if self._use_global_cursor else self._per_partition_cursor - - def stream_slices(self) -> Iterable[StreamSlice]: - self._global_cursor.start_slices_generation() - - # Iterate through partitions and process slices - for partition, is_last_partition, parent_state in iterate_with_last_flag_and_state( - self._partition_router.stream_slices(), self._partition_router.get_stream_state - ): - # Generate slices for the current cursor and handle the last slice using the flag - self._parent_state = parent_state - for slice, is_last_slice, _ in iterate_with_last_flag_and_state( - self._get_active_cursor().generate_slices_from_partition(partition=partition), lambda: None - ): - self._global_cursor.register_slice(is_last_slice and is_last_partition) - yield slice - self._parent_state = self._partition_router.get_stream_state() - - def set_initial_state(self, stream_state: StreamState) -> None: - """ - Set the initial state for the cursors. - """ - self._use_global_cursor = stream_state.get("use_global_cursor", False) - - self._parent_state = stream_state.get("parent_state", {}) - - self._global_cursor.set_initial_state(stream_state) - if not self._use_global_cursor: - self._per_partition_cursor.set_initial_state(stream_state) - - def observe(self, stream_slice: StreamSlice, record: Record) -> None: - if not self._use_global_cursor and self._per_partition_cursor.limit_reached(): - self._use_global_cursor = True - - if not self._use_global_cursor: - self._per_partition_cursor.observe(stream_slice, record) - self._global_cursor.observe(stream_slice, record) - - def close_slice(self, stream_slice: StreamSlice, *args: Any) -> None: - if not self._use_global_cursor: - self._per_partition_cursor.close_slice(stream_slice, *args) - self._global_cursor.close_slice(stream_slice, *args) - - def get_stream_state(self) -> StreamState: - final_state: MutableMapping[str, Any] = {"use_global_cursor": self._use_global_cursor} - - final_state.update(self._global_cursor.get_stream_state()) - if not self._use_global_cursor: - final_state.update(self._per_partition_cursor.get_stream_state()) - - final_state["parent_state"] = self._parent_state - if not final_state.get("parent_state"): - del final_state["parent_state"] - - return final_state - - def select_state(self, stream_slice: Optional[StreamSlice] = None) -> Optional[StreamState]: - return self._get_active_cursor().select_state(stream_slice) - - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._get_active_cursor().get_request_params( - stream_state=stream_state, - stream_slice=stream_slice, - next_page_token=next_page_token, - ) - - def get_request_headers( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._get_active_cursor().get_request_headers( - stream_state=stream_state, - stream_slice=stream_slice, - next_page_token=next_page_token, - ) - - def get_request_body_data( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Union[Mapping[str, Any], str]: - return self._get_active_cursor().get_request_body_data( - stream_state=stream_state, - stream_slice=stream_slice, - next_page_token=next_page_token, - ) - - def get_request_body_json( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._get_active_cursor().get_request_body_json( - stream_state=stream_state, - stream_slice=stream_slice, - next_page_token=next_page_token, - ) - - def should_be_synced(self, record: Record) -> bool: - return self._global_cursor.should_be_synced(record) or self._per_partition_cursor.should_be_synced(record) - - def is_greater_than_or_equal(self, first: Record, second: Record) -> bool: - return self._global_cursor.is_greater_than_or_equal(first, second) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/resumable_full_refresh_cursor.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/resumable_full_refresh_cursor.py deleted file mode 100644 index 499220a4c4fd..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/incremental/resumable_full_refresh_cursor.py +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from dataclasses import InitVar, dataclass -from typing import Any, Iterable, Mapping, Optional - -from airbyte_cdk.sources.declarative.incremental import DeclarativeCursor -from airbyte_cdk.sources.declarative.types import Record, StreamSlice, StreamState -from airbyte_cdk.sources.streams.checkpoint.checkpoint_reader import FULL_REFRESH_COMPLETE_STATE - - -@dataclass -class ResumableFullRefreshCursor(DeclarativeCursor): - parameters: InitVar[Mapping[str, Any]] - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._cursor: StreamState = {} - - def get_stream_state(self) -> StreamState: - return self._cursor - - def set_initial_state(self, stream_state: StreamState) -> None: - self._cursor = stream_state - - def observe(self, stream_slice: StreamSlice, record: Record) -> None: - """ - Resumable full refresh manages state using a page number so it does not need to update state by observing incoming records. - """ - pass - - def close_slice(self, stream_slice: StreamSlice, *args: Any) -> None: - # The ResumableFullRefreshCursor doesn't support nested streams yet so receiving a partition is unexpected - if stream_slice.partition: - raise ValueError(f"Stream slice {stream_slice} should not have a partition. Got {stream_slice.partition}.") - self._cursor = stream_slice.cursor_slice - - def should_be_synced(self, record: Record) -> bool: - """ - Unlike date-based cursors which filter out records outside slice boundaries, resumable full refresh records exist within pages - that don't have filterable bounds. We should always return them. - """ - return True - - def is_greater_than_or_equal(self, first: Record, second: Record) -> bool: - """ - RFR record don't have ordering to be compared between one another. - """ - return False - - def select_state(self, stream_slice: Optional[StreamSlice] = None) -> Optional[StreamState]: - # A top-level RFR cursor only manages the state of a single partition - return self._cursor - - def stream_slices(self) -> Iterable[StreamSlice]: - """ - Resumable full refresh cursors only return a single slice and can't perform partitioning because iteration is done per-page - along an unbounded set. - """ - yield from [StreamSlice(cursor_slice=self._cursor, partition={})] - - # This is an interesting pattern that might not seem obvious at first glance. This cursor itself has no functional need to - # inject any request values into the outbound response because the up-to-date pagination state is already loaded and - # maintained by the paginator component - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return {} - - def get_request_headers( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return {} - - def get_request_body_data( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return {} - - def get_request_body_json( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return {} - - -@dataclass -class ChildPartitionResumableFullRefreshCursor(ResumableFullRefreshCursor): - """ - The Sub-stream Resumable Cursor for Full-Refresh substreams. - Follows the parent type `ResumableFullRefreshCursor` with a small override, - to provide the ability to close the substream's slice once it has finished processing. - - Check the `close_slice` method overide for more info about the actual behaviour of this cursor. - """ - - def close_slice(self, stream_slice: StreamSlice, *args: Any) -> None: - """ - Once the current slice has finished syncing: - - paginator returns None - - no more slices to process - - we assume that the records are processed and emitted already, - thus we have to set the cursor to ` __ab_full_refresh_sync_complete: true `, - otherwise there is a risk of Inf. Loop processing the same slice. - """ - self._cursor = FULL_REFRESH_COMPLETE_STATE diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/__init__.py deleted file mode 100644 index d721b99f1e29..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.interpolation.interpolated_boolean import InterpolatedBoolean -from airbyte_cdk.sources.declarative.interpolation.interpolated_mapping import InterpolatedMapping -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString - -__all__ = ["InterpolatedBoolean", "InterpolatedMapping", "InterpolatedString"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/filters.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/filters.py deleted file mode 100644 index 52d76cab6423..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/filters.py +++ /dev/null @@ -1,120 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import base64 -import hashlib -import json -import re -from typing import Any, Optional - - -def hash(value: Any, hash_type: str = "md5", salt: Optional[str] = None) -> str: - """ - Implementation of a custom Jinja2 hash filter - Hash type defaults to 'md5' if one is not specified. - - If you are using this has function for GDPR compliance, then - you should probably also pass in a salt as discussed in: - https://security.stackexchange.com/questions/202022/hashing-email-addresses-for-gdpr-compliance - - This can be used in a low code connector definition under the AddFields transformation. - For example: - - rates_stream: - $ref: "#/definitions/base_stream" - $parameters: - name: "rates" - primary_key: "date" - path: "/exchangerates_data/latest" - transformations: - - type: AddFields - fields: - - path: ["some_new_path"] - value: "{{ record['rates']['CAD'] | hash('md5', 'mysalt') }}" - - - - :param value: value to be hashed - :param hash_type: valid hash type - :param salt: a salt that will be combined with the value to ensure that the hash created for a given value on this system - is different from the hash created for that value on other systems. - :return: computed hash as a hexadecimal string - """ - hash_func = getattr(hashlib, hash_type, None) - - if hash_func: - hash_obj = hash_func() - hash_obj.update(str(value).encode("utf-8")) - if salt: - hash_obj.update(str(salt).encode("utf-8")) - computed_hash: str = hash_obj.hexdigest() - else: - raise AttributeError("No hashing function named {hname}".format(hname=hash_type)) - - return computed_hash - - -def base64encode(value: str) -> str: - """ - Implementation of a custom Jinja2 base64encode filter - - For example: - - OAuthAuthenticator: - $ref: "#/definitions/OAuthAuthenticator" - $parameters: - name: "client_id" - value: "{{ config['client_id'] | base64encode }}" - - :param value: value to be encoded in base64 - :return: base64 encoded string - """ - - return base64.b64encode(value.encode("utf-8")).decode() - - -def base64decode(value: str) -> str: - """ - Implementation of a custom Jinja2 base64decode filter - - For example: - - OAuthAuthenticator: - $ref: "#/definitions/OAuthAuthenticator" - $parameters: - name: "client_id" - value: "{{ config['client_id'] | base64decode }}" - - :param value: value to be decoded from base64 - :return: base64 decoded string - """ - - return base64.b64decode(value.encode("utf-8")).decode() - - -def string(value: Any) -> str: - """ - Converts the input value to a string. - If the value is already a string, it is returned as is. - Otherwise, the value is interpreted as a json object and wrapped in triple-quotes so it's evalued as a string by the JinjaInterpolation - :param value: the value to convert to a string - :return: string representation of the input value - """ - if isinstance(value, str): - return value - ret = f'"""{json.dumps(value)}"""' - return ret - - -def regex_search(value: str, regex: str) -> str: - """ - Match a regular expression against a string and return the first match group if it exists. - """ - match = re.search(regex, value) - if match and len(match.groups()) > 0: - return match.group(1) - return "" - - -_filters_list = [hash, base64encode, base64decode, string, regex_search] -filters = {f.__name__: f for f in _filters_list} diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/interpolated_boolean.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/interpolated_boolean.py deleted file mode 100644 index e3c3d6a68290..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/interpolated_boolean.py +++ /dev/null @@ -1,48 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Final, List, Mapping - -from airbyte_cdk.sources.declarative.interpolation.jinja import JinjaInterpolation -from airbyte_cdk.sources.types import Config - -FALSE_VALUES: Final[List[Any]] = ["False", "false", "{}", "[]", "()", "", "0", "0.0", {}, False, [], (), set()] - - -@dataclass -class InterpolatedBoolean: - f""" - Wrapper around a string to be evaluated to a boolean value. - The string will be evaluated as False if it interpolates to a value in {FALSE_VALUES} - - Attributes: - condition (str): The string representing the condition to evaluate to a boolean - """ - condition: str - parameters: InitVar[Mapping[str, Any]] - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._default = "False" - self._interpolation = JinjaInterpolation() - self._parameters = parameters - - def eval(self, config: Config, **additional_parameters: Any) -> bool: - """ - Interpolates the predicate condition string using the config and other optional arguments passed as parameter. - - :param config: The user-provided configuration as specified by the source's spec - :param additional_parameters: Optional parameters used for interpolation - :return: The interpolated string - """ - if isinstance(self.condition, bool): - return self.condition - else: - evaluated = self._interpolation.eval( - self.condition, config, self._default, parameters=self._parameters, **additional_parameters - ) - if evaluated in FALSE_VALUES: - return False - # The presence of a value is generally regarded as truthy, so we treat it as such - return True diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/interpolated_mapping.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/interpolated_mapping.py deleted file mode 100644 index b0f26e0d9b77..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/interpolated_mapping.py +++ /dev/null @@ -1,52 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from dataclasses import InitVar, dataclass -from typing import Any, Dict, Mapping, Optional - -from airbyte_cdk.sources.declarative.interpolation.jinja import JinjaInterpolation -from airbyte_cdk.sources.types import Config - - -@dataclass -class InterpolatedMapping: - """ - Wrapper around a Mapping[str, str] where both the keys and values are to be interpolated. - - Attributes: - mapping (Mapping[str, str]): to be evaluated - """ - - mapping: Mapping[str, str] - parameters: InitVar[Mapping[str, Any]] - - def __post_init__(self, parameters: Optional[Mapping[str, Any]]) -> None: - self._interpolation = JinjaInterpolation() - self._parameters = parameters - - def eval(self, config: Config, **additional_parameters: Any) -> Dict[str, Any]: - """ - Wrapper around a Mapping[str, str] that allows for both keys and values to be interpolated. - - :param config: The user-provided configuration as specified by the source's spec - :param additional_parameters: Optional parameters used for interpolation - :return: The interpolated mapping - """ - valid_key_types = additional_parameters.pop("valid_key_types", (str,)) - valid_value_types = additional_parameters.pop("valid_value_types", None) - return { - self._interpolation.eval( - name, config, valid_types=valid_key_types, parameters=self._parameters, **additional_parameters - ): self._eval(value, config, valid_types=valid_value_types, **additional_parameters) - for name, value in self.mapping.items() - } - - def _eval(self, value: str, config: Config, **kwargs: Any) -> Any: - # The values in self._mapping can be of Any type - # We only want to interpolate them if they are strings - if isinstance(value, str): - return self._interpolation.eval(value, config, parameters=self._parameters, **kwargs) - else: - return value diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/interpolated_nested_mapping.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/interpolated_nested_mapping.py deleted file mode 100644 index 6c0afde2e44b..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/interpolated_nested_mapping.py +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from dataclasses import InitVar, dataclass -from typing import Any, Mapping, Optional, Union - -from airbyte_cdk.sources.declarative.interpolation.jinja import JinjaInterpolation -from airbyte_cdk.sources.types import Config - -NestedMappingEntry = Union[dict[str, "NestedMapping"], list["NestedMapping"], str, int, float, bool, None] -NestedMapping = Union[dict[str, NestedMappingEntry], str] - - -@dataclass -class InterpolatedNestedMapping: - """ - Wrapper around a nested dict which can contain lists and primitive values where both the keys and values are interpolated recursively. - - Attributes: - mapping (NestedMapping): to be evaluated - """ - - mapping: NestedMapping - parameters: InitVar[Mapping[str, Any]] - - def __post_init__(self, parameters: Optional[Mapping[str, Any]]) -> None: - self._interpolation = JinjaInterpolation() - self._parameters = parameters - - def eval(self, config: Config, **additional_parameters: Any) -> Any: - return self._eval(self.mapping, config, **additional_parameters) - - def _eval(self, value: Union[NestedMapping, NestedMappingEntry], config: Config, **kwargs: Any) -> Any: - # Recursively interpolate dictionaries and lists - if isinstance(value, str): - return self._interpolation.eval(value, config, parameters=self._parameters, **kwargs) - elif isinstance(value, dict): - interpolated_dict = {self._eval(k, config, **kwargs): self._eval(v, config, **kwargs) for k, v in value.items()} - return {k: v for k, v in interpolated_dict.items() if v is not None} - elif isinstance(value, list): - return [self._eval(v, config, **kwargs) for v in value] - else: - return value diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/interpolated_string.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/interpolated_string.py deleted file mode 100644 index 52b3401559fb..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/interpolated_string.py +++ /dev/null @@ -1,75 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Mapping, Optional, Union - -from airbyte_cdk.sources.declarative.interpolation.jinja import JinjaInterpolation -from airbyte_cdk.sources.types import Config - - -@dataclass -class InterpolatedString: - """ - Wrapper around a raw string to be interpolated with the Jinja2 templating engine - - Attributes: - string (str): The string to evalute - default (Optional[str]): The default value to return if the evaluation returns an empty string - parameters (Mapping[str, Any]): Additional runtime parameters to be used for string interpolation - """ - - string: str - parameters: InitVar[Mapping[str, Any]] - default: Optional[str] = None - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self.default = self.default or self.string - self._interpolation = JinjaInterpolation() - self._parameters = parameters - # indicates whether passed string is just a plain string, not Jinja template - # This allows for optimization, but we do not know it yet at this stage - self._is_plain_string = None - - def eval(self, config: Config, **kwargs: Any) -> Any: - """ - Interpolates the input string using the config and other optional arguments passed as parameter. - - :param config: The user-provided configuration as specified by the source's spec - :param kwargs: Optional parameters used for interpolation - :return: The interpolated string - """ - if self._is_plain_string: - return self.string - if self._is_plain_string is None: - # Let's check whether output from evaluation is the same as input. - # This indicates occurence of a plain string, not a template and we can skip Jinja in subsequent runs. - evaluated = self._interpolation.eval(self.string, config, self.default, parameters=self._parameters, **kwargs) - self._is_plain_string = self.string == evaluated - return evaluated - return self._interpolation.eval(self.string, config, self.default, parameters=self._parameters, **kwargs) - - def __eq__(self, other: Any) -> bool: - if not isinstance(other, InterpolatedString): - return False - return self.string == other.string and self.default == other.default - - @classmethod - def create( - cls, - string_or_interpolated: Union["InterpolatedString", str], - *, - parameters: Mapping[str, Any], - ) -> "InterpolatedString": - """ - Helper function to obtain an InterpolatedString from either a raw string or an InterpolatedString. - - :param string_or_interpolated: either a raw string or an InterpolatedString. - :param parameters: parameters propagated from parent component - :return: InterpolatedString representing the input string. - """ - if isinstance(string_or_interpolated, str): - return InterpolatedString(string=string_or_interpolated, parameters=parameters) - else: - return string_or_interpolated diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/interpolation.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/interpolation.py deleted file mode 100644 index 8a8f05a5ba71..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/interpolation.py +++ /dev/null @@ -1,27 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import ABC, abstractmethod -from typing import Any, Optional - -from airbyte_cdk.sources.types import Config - - -class Interpolation(ABC): - """ - Strategy for evaluating the interpolated value of a string at runtime using Jinja. - """ - - @abstractmethod - def eval(self, input_str: str, config: Config, default: Optional[str] = None, **additional_options: Any) -> Any: - """ - Interpolates the input string using the config, and additional options passed as parameter. - - :param input_str: The string to interpolate - :param config: The user-provided configuration as specified by the source's spec - :param default: Default value to return if the evaluation returns an empty string - :param additional_options: Optional parameters used for interpolation - :return: The interpolated string - """ - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/jinja.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/jinja.py deleted file mode 100644 index 45a93e58252f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/jinja.py +++ /dev/null @@ -1,142 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import ast -from functools import cache -from typing import Any, Mapping, Optional, Tuple, Type - -from airbyte_cdk.sources.declarative.interpolation.filters import filters -from airbyte_cdk.sources.declarative.interpolation.interpolation import Interpolation -from airbyte_cdk.sources.declarative.interpolation.macros import macros -from airbyte_cdk.sources.types import Config -from jinja2 import meta -from jinja2.environment import Template -from jinja2.exceptions import UndefinedError -from jinja2.sandbox import SandboxedEnvironment - - -class StreamPartitionAccessEnvironment(SandboxedEnvironment): - """ - Currently, source-jira is setting an attribute to StreamSlice specific to its use case which because of the PerPartitionCursor is set to - StreamSlice._partition but not exposed through StreamSlice.partition. This is a patch to still allow source-jira to have access to this - parameter - """ - - def is_safe_attribute(self, obj: Any, attr: str, value: Any) -> bool: - if attr in ["_partition"]: - return True - return super().is_safe_attribute(obj, attr, value) # type: ignore # for some reason, mypy says 'Returning Any from function declared to return "bool"' - - -class JinjaInterpolation(Interpolation): - """ - Interpolation strategy using the Jinja2 template engine. - - If the input string is a raw string, the interpolated string will be the same. - `eval("hello world") -> "hello world"` - - The engine will evaluate the content passed within {{}}, interpolating the keys from the config and context-specific arguments. - `eval("hello {{ name }}", name="airbyte") -> "hello airbyte")` - `eval("hello {{ config.name }}", config={"name": "airbyte"}) -> "hello airbyte")` - - In additional to passing additional values through the kwargs argument, macros can be called from within the string interpolation. - For example, - "{{ max(2, 3) }}" will return 3 - - Additional information on jinja templating can be found at https://jinja.palletsprojects.com/en/3.1.x/templates/# - """ - - # These aliases are used to deprecate existing keywords without breaking all existing connectors. - ALIASES = { - "stream_interval": "stream_slice", # Use stream_interval to access incremental_sync values - "stream_partition": "stream_slice", # Use stream_partition to access partition router's values - } - - # These extensions are not installed so they're not currently a problem, - # but we're still explicitely removing them from the jinja context. - # At worst, this is documentation that we do NOT want to include these extensions because of the potential security risks - RESTRICTED_EXTENSIONS = ["jinja2.ext.loopcontrols"] # Adds support for break continue in loops - - # By default, these Python builtin functions are available in the Jinja context. - # We explicitely remove them because of the potential security risk. - # Please add a unit test to test_jinja.py when adding a restriction. - RESTRICTED_BUILTIN_FUNCTIONS = ["range"] # The range function can cause very expensive computations - - def __init__(self) -> None: - self._environment = StreamPartitionAccessEnvironment() - self._environment.filters.update(**filters) - self._environment.globals.update(**macros) - - for extension in self.RESTRICTED_EXTENSIONS: - self._environment.extensions.pop(extension, None) - for builtin in self.RESTRICTED_BUILTIN_FUNCTIONS: - self._environment.globals.pop(builtin, None) - - def eval( - self, - input_str: str, - config: Config, - default: Optional[str] = None, - valid_types: Optional[Tuple[Type[Any]]] = None, - **additional_parameters: Any, - ) -> Any: - context = {"config": config, **additional_parameters} - - for alias, equivalent in self.ALIASES.items(): - if alias in context: - # This is unexpected. We could ignore or log a warning, but failing loudly should result in fewer surprises - raise ValueError( - f"Found reserved keyword {alias} in interpolation context. This is unexpected and indicative of a bug in the CDK." - ) - elif equivalent in context: - context[alias] = context[equivalent] - - try: - if isinstance(input_str, str): - result = self._eval(input_str, context) - if result: - return self._literal_eval(result, valid_types) - else: - # If input is not a string, return it as is - raise Exception(f"Expected a string, got {input_str}") - except UndefinedError: - pass - # If result is empty or resulted in an undefined error, evaluate and return the default string - return self._literal_eval(self._eval(default, context), valid_types) - - def _literal_eval(self, result: Optional[str], valid_types: Optional[Tuple[Type[Any]]]) -> Any: - try: - evaluated = ast.literal_eval(result) # type: ignore # literal_eval is able to handle None - except (ValueError, SyntaxError): - return result - if not valid_types or (valid_types and isinstance(evaluated, valid_types)): - return evaluated - return result - - def _eval(self, s: Optional[str], context: Mapping[str, Any]) -> Optional[str]: - try: - undeclared = self._find_undeclared_variables(s) - undeclared_not_in_context = {var for var in undeclared if var not in context} - if undeclared_not_in_context: - raise ValueError(f"Jinja macro has undeclared variables: {undeclared_not_in_context}. Context: {context}") - return self._compile(s).render(context) # type: ignore # from_string is able to handle None - except TypeError: - # The string is a static value, not a jinja template - # It can be returned as is - return s - - @cache - def _find_undeclared_variables(self, s: Optional[str]) -> Template: - """ - Find undeclared variables and cache them - """ - ast = self._environment.parse(s) # type: ignore # parse is able to handle None - return meta.find_undeclared_variables(ast) - - @cache - def _compile(self, s: Optional[str]) -> Template: - """ - We must cache the Jinja Template ourselves because we're using `from_string` instead of a template loader - """ - return self._environment.from_string(s) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/macros.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/macros.py deleted file mode 100644 index b90d82e79d71..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/interpolation/macros.py +++ /dev/null @@ -1,130 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import builtins -import datetime -import typing -from typing import Optional, Union - -import isodate -import pytz -from dateutil import parser -from isodate import parse_duration - -""" -This file contains macros that can be evaluated by a `JinjaInterpolation` object -""" - - -def now_utc() -> datetime.datetime: - """ - Current local date and time in UTC timezone - - Usage: - `"{{ now_utc() }}"` - """ - return datetime.datetime.now(datetime.timezone.utc) - - -def today_utc() -> datetime.date: - """ - Current date in UTC timezone - - Usage: - `"{{ today_utc() }}"` - """ - return datetime.datetime.now(datetime.timezone.utc).date() - - -def timestamp(dt: Union[float, str]) -> Union[int, float]: - """ - Converts a number or a string to a timestamp - - If dt is a number, then convert to an int - If dt is a string, then parse it using dateutil.parser - - Usage: - `"{{ timestamp(1658505815.223235) }}" - - :param dt: datetime to convert to timestamp - :return: unix timestamp - """ - if isinstance(dt, (int, float)): - return int(dt) - else: - return _str_to_datetime(dt).astimezone(pytz.utc).timestamp() - - -def _str_to_datetime(s: str) -> datetime.datetime: - parsed_date = parser.isoparse(s) - if not parsed_date.tzinfo: - # Assume UTC if the input does not contain a timezone - parsed_date = parsed_date.replace(tzinfo=pytz.utc) - return parsed_date.astimezone(pytz.utc) - - -def max(*args: typing.Any) -> typing.Any: - """ - Returns biggest object of an iterable, or two or more arguments. - - max(iterable, *[, default=obj, key=func]) -> value - max(arg1, arg2, *args, *[, key=func]) -> value - - Usage: - `"{{ max(2,3) }}" - - With a single iterable argument, return its biggest item. The - default keyword-only argument specifies an object to return if - the provided iterable is empty. - With two or more arguments, return the largest argument. - :param args: args to compare - :return: largest argument - """ - return builtins.max(*args) - - -def day_delta(num_days: int, format: str = "%Y-%m-%dT%H:%M:%S.%f%z") -> str: - """ - Returns datetime of now() + num_days - - Usage: - `"{{ day_delta(25) }}"` - - :param num_days: number of days to add to current date time - :return: datetime formatted as RFC3339 - """ - return (datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=num_days)).strftime(format) - - -def duration(datestring: str) -> Union[datetime.timedelta, isodate.Duration]: - """ - Converts ISO8601 duration to datetime.timedelta - - Usage: - `"{{ now_utc() - duration('P1D') }}"` - """ - return parse_duration(datestring) # type: ignore # mypy thinks this returns Any for some reason - - -def format_datetime(dt: Union[str, datetime.datetime], format: str, input_format: Optional[str] = None) -> str: - """ - Converts datetime to another format - - Usage: - `"{{ format_datetime(config.start_date, '%Y-%m-%d') }}"` - - CPython Datetime package has known bug with `stfrtime` method: '%s' formatting uses locale timezone - https://github.com/python/cpython/issues/77169 - https://github.com/python/cpython/issues/56959 - """ - if isinstance(dt, datetime.datetime): - return dt.strftime(format) - dt_datetime = datetime.datetime.strptime(dt, input_format) if input_format else _str_to_datetime(dt) - if format == "%s": - return str(int(dt_datetime.timestamp())) - return dt_datetime.strftime(format) - - -_macros_list = [now_utc, today_utc, timestamp, max, day_delta, duration, format_datetime] -macros = {f.__name__: f for f in _macros_list} diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/manifest_declarative_source.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/manifest_declarative_source.py deleted file mode 100644 index 7fe268f600a8..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/manifest_declarative_source.py +++ /dev/null @@ -1,236 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import logging -import pkgutil -import re -from copy import deepcopy -from importlib import metadata -from typing import Any, Dict, Iterator, List, Mapping, MutableMapping, Optional, Tuple, Union - -import yaml -from airbyte_cdk.models import ( - AirbyteConnectionStatus, - AirbyteMessage, - AirbyteStateMessage, - ConfiguredAirbyteCatalog, - ConnectorSpecification, -) -from airbyte_cdk.sources.declarative.checks.connection_checker import ConnectionChecker -from airbyte_cdk.sources.declarative.declarative_source import DeclarativeSource -from airbyte_cdk.sources.declarative.models.declarative_component_schema import CheckStream as CheckStreamModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import DeclarativeStream as DeclarativeStreamModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import Spec as SpecModel -from airbyte_cdk.sources.declarative.parsers.manifest_component_transformer import ManifestComponentTransformer -from airbyte_cdk.sources.declarative.parsers.manifest_reference_resolver import ManifestReferenceResolver -from airbyte_cdk.sources.declarative.parsers.model_to_component_factory import ModelToComponentFactory -from airbyte_cdk.sources.message import MessageRepository -from airbyte_cdk.sources.streams.core import Stream -from airbyte_cdk.sources.types import ConnectionDefinition -from airbyte_cdk.sources.utils.slice_logger import AlwaysLogSliceLogger, DebugSliceLogger, SliceLogger -from jsonschema.exceptions import ValidationError -from jsonschema.validators import validate - - -class ManifestDeclarativeSource(DeclarativeSource): - """Declarative source defined by a manifest of low-code components that define source connector behavior""" - - def __init__( - self, - source_config: ConnectionDefinition, - debug: bool = False, - emit_connector_builder_messages: bool = False, - component_factory: Optional[ModelToComponentFactory] = None, - ): - """ - :param source_config(Mapping[str, Any]): The manifest of low-code components that describe the source connector - :param debug(bool): True if debug mode is enabled - :param component_factory(ModelToComponentFactory): optional factory if ModelToComponentFactory's default behaviour needs to be tweaked - """ - self.logger = logging.getLogger(f"airbyte.{self.name}") - - # For ease of use we don't require the type to be specified at the top level manifest, but it should be included during processing - manifest = dict(source_config) - if "type" not in manifest: - manifest["type"] = "DeclarativeSource" - - resolved_source_config = ManifestReferenceResolver().preprocess_manifest(manifest) - propagated_source_config = ManifestComponentTransformer().propagate_types_and_parameters("", resolved_source_config, {}) - self._source_config = propagated_source_config - self._debug = debug - self._emit_connector_builder_messages = emit_connector_builder_messages - self._constructor = component_factory if component_factory else ModelToComponentFactory(emit_connector_builder_messages) - self._message_repository = self._constructor.get_message_repository() - self._slice_logger: SliceLogger = AlwaysLogSliceLogger() if emit_connector_builder_messages else DebugSliceLogger() - - self._validate_source() - - @property - def resolved_manifest(self) -> Mapping[str, Any]: - return self._source_config - - @property - def message_repository(self) -> Union[None, MessageRepository]: - return self._message_repository - - @property - def connection_checker(self) -> ConnectionChecker: - check = self._source_config["check"] - if "type" not in check: - check["type"] = "CheckStream" - check_stream = self._constructor.create_component( - CheckStreamModel, check, dict(), emit_connector_builder_messages=self._emit_connector_builder_messages - ) - if isinstance(check_stream, ConnectionChecker): - return check_stream - else: - raise ValueError(f"Expected to generate a ConnectionChecker component, but received {check_stream.__class__}") - - def streams(self, config: Mapping[str, Any]) -> List[Stream]: - self._emit_manifest_debug_message(extra_args={"source_name": self.name, "parsed_config": json.dumps(self._source_config)}) - stream_configs = self._stream_configs(self._source_config) - - source_streams = [ - self._constructor.create_component( - DeclarativeStreamModel, stream_config, config, emit_connector_builder_messages=self._emit_connector_builder_messages - ) - for stream_config in self._initialize_cache_for_parent_streams(deepcopy(stream_configs)) - ] - - return source_streams - - @staticmethod - def _initialize_cache_for_parent_streams(stream_configs: List[Dict[str, Any]]) -> List[Dict[str, Any]]: - parent_streams = set() - - def update_with_cache_parent_configs(parent_configs: list[dict[str, Any]]) -> None: - for parent_config in parent_configs: - parent_streams.add(parent_config["stream"]["name"]) - parent_config["stream"]["retriever"]["requester"]["use_cache"] = True - - for stream_config in stream_configs: - if stream_config.get("incremental_sync", {}).get("parent_stream"): - parent_streams.add(stream_config["incremental_sync"]["parent_stream"]["name"]) - stream_config["incremental_sync"]["parent_stream"]["retriever"]["requester"]["use_cache"] = True - - elif stream_config.get("retriever", {}).get("partition_router", {}): - partition_router = stream_config["retriever"]["partition_router"] - - if isinstance(partition_router, dict) and partition_router.get("parent_stream_configs"): - update_with_cache_parent_configs(partition_router["parent_stream_configs"]) - elif isinstance(partition_router, list): - for router in partition_router: - if router.get("parent_stream_configs"): - update_with_cache_parent_configs(router["parent_stream_configs"]) - - for stream_config in stream_configs: - if stream_config["name"] in parent_streams: - stream_config["retriever"]["requester"]["use_cache"] = True - - return stream_configs - - def spec(self, logger: logging.Logger) -> ConnectorSpecification: - """ - Returns the connector specification (spec) as defined in the Airbyte Protocol. The spec is an object describing the possible - configurations (e.g: username and password) which can be configured when running this connector. For low-code connectors, this - will first attempt to load the spec from the manifest's spec block, otherwise it will load it from "spec.yaml" or "spec.json" - in the project root. - """ - self._configure_logger_level(logger) - self._emit_manifest_debug_message(extra_args={"source_name": self.name, "parsed_config": json.dumps(self._source_config)}) - - spec = self._source_config.get("spec") - if spec: - if "type" not in spec: - spec["type"] = "Spec" - spec_component = self._constructor.create_component(SpecModel, spec, dict()) - return spec_component.generate_spec() - else: - return super().spec(logger) - - def check(self, logger: logging.Logger, config: Mapping[str, Any]) -> AirbyteConnectionStatus: - self._configure_logger_level(logger) - return super().check(logger, config) - - def read( - self, - logger: logging.Logger, - config: Mapping[str, Any], - catalog: ConfiguredAirbyteCatalog, - state: Optional[Union[List[AirbyteStateMessage], MutableMapping[str, Any]]] = None, - ) -> Iterator[AirbyteMessage]: - self._configure_logger_level(logger) - yield from super().read(logger, config, catalog, state) - - def _configure_logger_level(self, logger: logging.Logger) -> None: - """ - Set the log level to logging.DEBUG if debug mode is enabled - """ - if self._debug: - logger.setLevel(logging.DEBUG) - - def _validate_source(self) -> None: - """ - Validates the connector manifest against the declarative component schema - """ - try: - raw_component_schema = pkgutil.get_data("airbyte_cdk", "sources/declarative/declarative_component_schema.yaml") - if raw_component_schema is not None: - declarative_component_schema = yaml.load(raw_component_schema, Loader=yaml.SafeLoader) - else: - raise RuntimeError("Failed to read manifest component json schema required for validation") - except FileNotFoundError as e: - raise FileNotFoundError(f"Failed to read manifest component json schema required for validation: {e}") - - streams = self._source_config.get("streams") - if not streams: - raise ValidationError(f"A valid manifest should have at least one stream defined. Got {streams}") - - try: - validate(self._source_config, declarative_component_schema) - except ValidationError as e: - raise ValidationError("Validation against json schema defined in declarative_component_schema.yaml schema failed") from e - - cdk_version = metadata.version("airbyte_cdk") - cdk_major, cdk_minor, cdk_patch = self._get_version_parts(cdk_version, "airbyte-cdk") - manifest_version = self._source_config.get("version") - if manifest_version is None: - raise RuntimeError( - "Manifest version is not defined in the manifest. This is unexpected since it should be a required field. Please contact support." - ) - manifest_major, manifest_minor, manifest_patch = self._get_version_parts(manifest_version, "manifest") - - if cdk_major < manifest_major or (cdk_major == manifest_major and cdk_minor < manifest_minor): - raise ValidationError( - f"The manifest version {manifest_version} is greater than the airbyte-cdk package version ({cdk_version}). Your " - f"manifest may contain features that are not in the current CDK version." - ) - elif manifest_major == 0 and manifest_minor < 29: - raise ValidationError( - f"The low-code framework was promoted to Beta in airbyte-cdk version 0.29.0 and contains many breaking changes to the " - f"language. The manifest version {manifest_version} is incompatible with the airbyte-cdk package version " - f"{cdk_version} which contains these breaking changes." - ) - - @staticmethod - def _get_version_parts(version: str, version_type: str) -> Tuple[int, int, int]: - """ - Takes a semantic version represented as a string and splits it into a tuple of its major, minor, and patch versions. - """ - version_parts = re.split(r"\.", version) - if len(version_parts) != 3 or not all([part.isdigit() for part in version_parts]): - raise ValidationError(f"The {version_type} version {version} specified is not a valid version format (ex. 1.2.3)") - return tuple(int(part) for part in version_parts) # type: ignore # We already verified there were 3 parts and they are all digits - - def _stream_configs(self, manifest: Mapping[str, Any]) -> List[Dict[str, Any]]: - # This has a warning flag for static, but after we finish part 4 we'll replace manifest with self._source_config - stream_configs: List[Dict[str, Any]] = manifest.get("streams", []) - for s in stream_configs: - if "type" not in s: - s["type"] = "DeclarativeStream" - return stream_configs - - def _emit_manifest_debug_message(self, extra_args: dict[str, Any]) -> None: - self.logger.debug("declarative source created from manifest", extra=extra_args) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/migrations/legacy_to_per_partition_state_migration.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/migrations/legacy_to_per_partition_state_migration.py deleted file mode 100644 index 361f81bf8b21..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/migrations/legacy_to_per_partition_state_migration.py +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from typing import Any, Mapping - -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.migrations.state_migration import StateMigration -from airbyte_cdk.sources.declarative.models import DatetimeBasedCursor, SubstreamPartitionRouter -from airbyte_cdk.sources.declarative.models.declarative_component_schema import ParentStreamConfig - - -def _is_already_migrated(stream_state: Mapping[str, Any]) -> bool: - return "states" in stream_state - - -class LegacyToPerPartitionStateMigration(StateMigration): - """ - Transforms the input state for per-partitioned streams from the legacy format to the low-code format. - The cursor field and partition ID fields are automatically extracted from the stream's DatetimebasedCursor and SubstreamPartitionRouter. - - Example input state: - { - "13506132": { - "last_changed": "2022-12-27T08:34:39+00:00" - } - Example output state: - { - "partition": {"id": "13506132"}, - "cursor": {"last_changed": "2022-12-27T08:34:39+00:00"} - } - """ - - def __init__( - self, - partition_router: SubstreamPartitionRouter, - cursor: DatetimeBasedCursor, - config: Mapping[str, Any], - parameters: Mapping[str, Any], - ): - self._partition_router = partition_router - self._cursor = cursor - self._config = config - self._parameters = parameters - self._partition_key_field = InterpolatedString.create( - self._get_partition_field(self._partition_router), parameters=self._parameters - ).eval(self._config) - self._cursor_field = InterpolatedString.create(self._cursor.cursor_field, parameters=self._parameters).eval(self._config) - - def _get_partition_field(self, partition_router: SubstreamPartitionRouter) -> str: - parent_stream_config = partition_router.parent_stream_configs[0] - - # Retrieve the partition field with a condition, as properties are returned as a dictionary for custom components. - partition_field = ( - parent_stream_config.partition_field - if isinstance(parent_stream_config, ParentStreamConfig) - else parent_stream_config.get("partition_field") # type: ignore # See above comment on why parent_stream_config might be a dict - ) - - return partition_field - - def should_migrate(self, stream_state: Mapping[str, Any]) -> bool: - if _is_already_migrated(stream_state): - return False - - # There is exactly one parent stream - number_of_parent_streams = len(self._partition_router.parent_stream_configs) - if number_of_parent_streams != 1: - # There should be exactly one parent stream - return False - """ - The expected state format is - "" : { - "" : "" - } - """ - if stream_state: - for key, value in stream_state.items(): - if isinstance(value, dict): - keys = list(value.keys()) - if len(keys) != 1: - # The input partitioned state should only have one key - return False - if keys[0] != self._cursor_field: - # Unexpected key. Found {keys[0]}. Expected {self._cursor.cursor_field} - return False - return True - - def migrate(self, stream_state: Mapping[str, Any]) -> Mapping[str, Any]: - states = [{"partition": {self._partition_key_field: key}, "cursor": value} for key, value in stream_state.items()] - return {"states": states} diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/migrations/state_migration.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/migrations/state_migration.py deleted file mode 100644 index 9cf7f3cfe08c..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/migrations/state_migration.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from abc import abstractmethod -from typing import Any, Mapping - - -class StateMigration: - @abstractmethod - def should_migrate(self, stream_state: Mapping[str, Any]) -> bool: - """ - Check if the stream_state should be migrated - - :param stream_state: The stream_state to potentially migrate - :return: true if the state is of the expected format and should be migrated. False otherwise. - """ - - @abstractmethod - def migrate(self, stream_state: Mapping[str, Any]) -> Mapping[str, Any]: - """ - Migrate the stream_state. Assumes should_migrate(stream_state) returned True. - - :param stream_state: The stream_state to migrate - :return: The migrated stream_state - """ diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/models/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/models/__init__.py deleted file mode 100644 index 81f2e2f3351e..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/models/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# generated by bin/generate_component_manifest_files.py -from .declarative_component_schema import * diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/models/declarative_component_schema.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/models/declarative_component_schema.py deleted file mode 100644 index eeb773b2522f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/models/declarative_component_schema.py +++ /dev/null @@ -1,1729 +0,0 @@ -# generated by datamodel-codegen: -# filename: declarative_component_schema.yaml - -from __future__ import annotations - -from enum import Enum -from typing import Any, Dict, List, Optional, Union - -from pydantic.v1 import BaseModel, Extra, Field -from typing_extensions import Literal - - -class AuthFlowType(Enum): - oauth2_0 = 'oauth2.0' - oauth1_0 = 'oauth1.0' - - -class BasicHttpAuthenticator(BaseModel): - type: Literal['BasicHttpAuthenticator'] - username: str = Field( - ..., - description='The username that will be combined with the password, base64 encoded and used to make requests. Fill it in the user inputs.', - examples=["{{ config['username'] }}", "{{ config['api_key'] }}"], - title='Username', - ) - password: Optional[str] = Field( - '', - description='The password that will be combined with the username, base64 encoded and used to make requests. Fill it in the user inputs.', - examples=["{{ config['password'] }}", ''], - title='Password', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class BearerAuthenticator(BaseModel): - type: Literal['BearerAuthenticator'] - api_token: str = Field( - ..., - description='Token to inject as request header for authenticating with the API.', - examples=["{{ config['api_key'] }}", "{{ config['token'] }}"], - title='Bearer Token', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class CheckStream(BaseModel): - type: Literal['CheckStream'] - stream_names: List[str] = Field( - ..., - description='Names of the streams to try reading from when running a check operation.', - examples=[['users'], ['users', 'contacts']], - title='Stream Names', - ) - - -class ConcurrencyLevel(BaseModel): - type: Optional[Literal['ConcurrencyLevel']] = None - default_concurrency: Union[int, str] = Field( - ..., - description='The amount of concurrency that will applied during a sync. This value can be hardcoded or user-defined in the config if different users have varying volume thresholds in the target API.', - examples=[10, "{{ config['num_workers'] or 10 }}"], - title='Default Concurrency', - ) - max_concurrency: Optional[int] = Field( - None, - description='The maximum level of concurrency that will be used during a sync. This becomes a required field when the default_concurrency derives from the config, because it serves as a safeguard against a user-defined threshold that is too high.', - examples=[20, 100], - title='Max Concurrency', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class ConstantBackoffStrategy(BaseModel): - type: Literal['ConstantBackoffStrategy'] - backoff_time_in_seconds: Union[float, str] = Field( - ..., - description='Backoff time in seconds.', - examples=[30, 30.5, "{{ config['backoff_time'] }}"], - title='Backoff Time', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class CursorPagination(BaseModel): - type: Literal['CursorPagination'] - cursor_value: str = Field( - ..., - description='Value of the cursor defining the next page to fetch.', - examples=[ - '{{ headers.link.next.cursor }}', - "{{ last_record['key'] }}", - "{{ response['nextPage'] }}", - ], - title='Cursor Value', - ) - page_size: Optional[int] = Field( - None, - description='The number of records to include in each pages.', - examples=[100], - title='Page Size', - ) - stop_condition: Optional[str] = Field( - None, - description='Template string evaluating when to stop paginating.', - examples=[ - '{{ response.data.has_more is false }}', - "{{ 'next' not in headers['link'] }}", - ], - title='Stop Condition', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class CustomAuthenticator(BaseModel): - class Config: - extra = Extra.allow - - type: Literal['CustomAuthenticator'] - class_name: str = Field( - ..., - description='Fully-qualified name of the class that will be implementing the custom authentication strategy. Has to be a sub class of DeclarativeAuthenticator. The format is `source_..`.', - examples=['source_railz.components.ShortLivedTokenAuthenticator'], - title='Class Name', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class CustomBackoffStrategy(BaseModel): - class Config: - extra = Extra.allow - - type: Literal['CustomBackoffStrategy'] - class_name: str = Field( - ..., - description='Fully-qualified name of the class that will be implementing the custom backoff strategy. The format is `source_..`.', - examples=['source_railz.components.MyCustomBackoffStrategy'], - title='Class Name', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class CustomErrorHandler(BaseModel): - class Config: - extra = Extra.allow - - type: Literal['CustomErrorHandler'] - class_name: str = Field( - ..., - description='Fully-qualified name of the class that will be implementing the custom error handler. The format is `source_..`.', - examples=['source_railz.components.MyCustomErrorHandler'], - title='Class Name', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class CustomIncrementalSync(BaseModel): - class Config: - extra = Extra.allow - - type: Literal['CustomIncrementalSync'] - class_name: str = Field( - ..., - description='Fully-qualified name of the class that will be implementing the custom incremental sync. The format is `source_..`.', - examples=['source_railz.components.MyCustomIncrementalSync'], - title='Class Name', - ) - cursor_field: str = Field( - ..., - description='The location of the value on a record that will be used as a bookmark during sync.', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class CustomPaginationStrategy(BaseModel): - class Config: - extra = Extra.allow - - type: Literal['CustomPaginationStrategy'] - class_name: str = Field( - ..., - description='Fully-qualified name of the class that will be implementing the custom pagination strategy. The format is `source_..`.', - examples=['source_railz.components.MyCustomPaginationStrategy'], - title='Class Name', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class CustomRecordExtractor(BaseModel): - class Config: - extra = Extra.allow - - type: Literal['CustomRecordExtractor'] - class_name: str = Field( - ..., - description='Fully-qualified name of the class that will be implementing the custom record extraction strategy. The format is `source_..`.', - examples=['source_railz.components.MyCustomRecordExtractor'], - title='Class Name', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class CustomRecordFilter(BaseModel): - class Config: - extra = Extra.allow - - type: Literal['CustomRecordFilter'] - class_name: str = Field( - ..., - description='Fully-qualified name of the class that will be implementing the custom record filter strategy. The format is `source_..`.', - examples=['source_railz.components.MyCustomCustomRecordFilter'], - title='Class Name', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class CustomRequester(BaseModel): - class Config: - extra = Extra.allow - - type: Literal['CustomRequester'] - class_name: str = Field( - ..., - description='Fully-qualified name of the class that will be implementing the custom requester strategy. The format is `source_..`.', - examples=['source_railz.components.MyCustomRecordExtractor'], - title='Class Name', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class CustomRetriever(BaseModel): - class Config: - extra = Extra.allow - - type: Literal['CustomRetriever'] - class_name: str = Field( - ..., - description='Fully-qualified name of the class that will be implementing the custom retriever strategy. The format is `source_..`.', - examples=['source_railz.components.MyCustomRetriever'], - title='Class Name', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class CustomPartitionRouter(BaseModel): - class Config: - extra = Extra.allow - - type: Literal['CustomPartitionRouter'] - class_name: str = Field( - ..., - description='Fully-qualified name of the class that will be implementing the custom partition router. The format is `source_..`.', - examples=['source_railz.components.MyCustomPartitionRouter'], - title='Class Name', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class CustomSchemaLoader(BaseModel): - class Config: - extra = Extra.allow - - type: Literal['CustomSchemaLoader'] - class_name: str = Field( - ..., - description='Fully-qualified name of the class that will be implementing the custom schema loader. The format is `source_..`.', - examples=['source_railz.components.MyCustomSchemaLoader'], - title='Class Name', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class CustomStateMigration(BaseModel): - class Config: - extra = Extra.allow - - type: Literal['CustomStateMigration'] - class_name: str = Field( - ..., - description='Fully-qualified name of the class that will be implementing the custom state migration. The format is `source_..`.', - examples=['source_railz.components.MyCustomStateMigration'], - title='Class Name', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class CustomTransformation(BaseModel): - class Config: - extra = Extra.allow - - type: Literal['CustomTransformation'] - class_name: str = Field( - ..., - description='Fully-qualified name of the class that will be implementing the custom transformation. The format is `source_..`.', - examples=['source_railz.components.MyCustomTransformation'], - title='Class Name', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class LegacyToPerPartitionStateMigration(BaseModel): - class Config: - extra = Extra.allow - - type: Optional[Literal['LegacyToPerPartitionStateMigration']] = None - - -class Algorithm(Enum): - HS256 = 'HS256' - HS384 = 'HS384' - HS512 = 'HS512' - ES256 = 'ES256' - ES256K = 'ES256K' - ES384 = 'ES384' - ES512 = 'ES512' - RS256 = 'RS256' - RS384 = 'RS384' - RS512 = 'RS512' - PS256 = 'PS256' - PS384 = 'PS384' - PS512 = 'PS512' - EdDSA = 'EdDSA' - - -class JwtHeaders(BaseModel): - class Config: - extra = Extra.forbid - - kid: Optional[str] = Field( - None, - description='Private key ID for user account.', - examples=["{{ config['kid'] }}"], - title='Key Identifier', - ) - typ: Optional[str] = Field( - 'JWT', - description='The media type of the complete JWT.', - examples=['JWT'], - title='Type', - ) - cty: Optional[str] = Field( - None, - description='Content type of JWT header.', - examples=['JWT'], - title='Content Type', - ) - - -class JwtPayload(BaseModel): - class Config: - extra = Extra.forbid - - iss: Optional[str] = Field( - None, - description='The user/principal that issued the JWT. Commonly a value unique to the user.', - examples=["{{ config['iss'] }}"], - title='Issuer', - ) - sub: Optional[str] = Field( - None, - description='The subject of the JWT. Commonly defined by the API.', - title='Subject', - ) - aud: Optional[str] = Field( - None, - description='The recipient that the JWT is intended for. Commonly defined by the API.', - examples=['appstoreconnect-v1'], - title='Audience', - ) - - -class JwtAuthenticator(BaseModel): - type: Literal['JwtAuthenticator'] - secret_key: str = Field( - ..., - description='Secret used to sign the JSON web token.', - examples=["{{ config['secret_key'] }}"], - ) - base64_encode_secret_key: Optional[bool] = Field( - False, - description='When set to true, the secret key will be base64 encoded prior to being encoded as part of the JWT. Only set to "true" when required by the API.', - ) - algorithm: Algorithm = Field( - ..., - description='Algorithm used to sign the JSON web token.', - examples=['ES256', 'HS256', 'RS256', "{{ config['algorithm'] }}"], - ) - token_duration: Optional[int] = Field( - 1200, - description='The amount of time in seconds a JWT token can be valid after being issued.', - examples=[1200, 3600], - title='Token Duration', - ) - header_prefix: Optional[str] = Field( - None, - description='The prefix to be used within the Authentication header.', - examples=['Bearer', 'Basic'], - title='Header Prefix', - ) - jwt_headers: Optional[JwtHeaders] = Field( - None, - description='JWT headers used when signing JSON web token.', - title='JWT Headers', - ) - additional_jwt_headers: Optional[Dict[str, Any]] = Field( - None, - description='Additional headers to be included with the JWT headers object.', - title='Additional JWT Headers', - ) - jwt_payload: Optional[JwtPayload] = Field( - None, - description='JWT Payload used when signing JSON web token.', - title='JWT Payload', - ) - additional_jwt_payload: Optional[Dict[str, Any]] = Field( - None, - description='Additional properties to be added to the JWT payload.', - title='Additional JWT Payload Properties', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class RefreshTokenUpdater(BaseModel): - refresh_token_name: Optional[str] = Field( - 'refresh_token', - description='The name of the property which contains the updated refresh token in the response from the token refresh endpoint.', - examples=['refresh_token'], - title='Refresh Token Property Name', - ) - access_token_config_path: Optional[List[str]] = Field( - ['credentials', 'access_token'], - description='Config path to the access token. Make sure the field actually exists in the config.', - examples=[['credentials', 'access_token'], ['access_token']], - title='Config Path To Access Token', - ) - refresh_token_config_path: Optional[List[str]] = Field( - ['credentials', 'refresh_token'], - description='Config path to the access token. Make sure the field actually exists in the config.', - examples=[['credentials', 'refresh_token'], ['refresh_token']], - title='Config Path To Refresh Token', - ) - token_expiry_date_config_path: Optional[List[str]] = Field( - ['credentials', 'token_expiry_date'], - description='Config path to the expiry date. Make sure actually exists in the config.', - examples=[['credentials', 'token_expiry_date']], - title='Config Path To Expiry Date', - ) - refresh_token_error_status_codes: Optional[List[int]] = Field( - [], - description='Status Codes to Identify refresh token error in response (Refresh Token Error Key and Refresh Token Error Values should be also specified). Responses with one of the error status code and containing an error value will be flagged as a config error', - examples=[[400, 500]], - title='Refresh Token Error Status Codes', - ) - refresh_token_error_key: Optional[str] = Field( - '', - description='Key to Identify refresh token error in response (Refresh Token Error Status Codes and Refresh Token Error Values should be also specified).', - examples=['error'], - title='Refresh Token Error Key', - ) - refresh_token_error_values: Optional[List[str]] = Field( - [], - description='List of values to check for exception during token refresh process. Used to check if the error found in the response matches the key from the Refresh Token Error Key field (e.g. response={"error": "invalid_grant"}). Only responses with one of the error status code and containing an error value will be flagged as a config error', - examples=[['invalid_grant', 'invalid_permissions']], - title='Refresh Token Error Values', - ) - - -class OAuthAuthenticator(BaseModel): - type: Literal['OAuthAuthenticator'] - client_id: str = Field( - ..., - description='The OAuth client ID. Fill it in the user inputs.', - examples=["{{ config['client_id }}", "{{ config['credentials']['client_id }}"], - title='Client ID', - ) - client_secret: str = Field( - ..., - description='The OAuth client secret. Fill it in the user inputs.', - examples=[ - "{{ config['client_secret }}", - "{{ config['credentials']['client_secret }}", - ], - title='Client Secret', - ) - refresh_token: Optional[str] = Field( - None, - description='Credential artifact used to get a new access token.', - examples=[ - "{{ config['refresh_token'] }}", - "{{ config['credentials]['refresh_token'] }}", - ], - title='Refresh Token', - ) - token_refresh_endpoint: str = Field( - ..., - description='The full URL to call to obtain a new access token.', - examples=['https://connect.squareup.com/oauth2/token'], - title='Token Refresh Endpoint', - ) - access_token_name: Optional[str] = Field( - 'access_token', - description='The name of the property which contains the access token in the response from the token refresh endpoint.', - examples=['access_token'], - title='Access Token Property Name', - ) - expires_in_name: Optional[str] = Field( - 'expires_in', - description='The name of the property which contains the expiry date in the response from the token refresh endpoint.', - examples=['expires_in'], - title='Token Expiry Property Name', - ) - grant_type: Optional[str] = Field( - 'refresh_token', - description='Specifies the OAuth2 grant type. If set to refresh_token, the refresh_token needs to be provided as well. For client_credentials, only client id and secret are required. Other grant types are not officially supported.', - examples=['refresh_token', 'client_credentials'], - title='Grant Type', - ) - refresh_request_body: Optional[Dict[str, Any]] = Field( - None, - description='Body of the request sent to get a new access token.', - examples=[ - { - 'applicationId': "{{ config['application_id'] }}", - 'applicationSecret': "{{ config['application_secret'] }}", - 'token': "{{ config['token'] }}", - } - ], - title='Refresh Request Body', - ) - scopes: Optional[List[str]] = Field( - None, - description='List of scopes that should be granted to the access token.', - examples=[ - ['crm.list.read', 'crm.objects.contacts.read', 'crm.schema.contacts.read'] - ], - title='Scopes', - ) - token_expiry_date: Optional[str] = Field( - None, - description='The access token expiry date.', - examples=['2023-04-06T07:12:10.421833+00:00', 1680842386], - title='Token Expiry Date', - ) - token_expiry_date_format: Optional[str] = Field( - None, - description='The format of the time to expiration datetime. Provide it if the time is returned as a date-time string instead of seconds.', - examples=['%Y-%m-%d %H:%M:%S.%f+00:00'], - title='Token Expiry Date Format', - ) - refresh_token_updater: Optional[RefreshTokenUpdater] = Field( - None, - description='When the token updater is defined, new refresh tokens, access tokens and the access token expiry date are written back from the authentication response to the config object. This is important if the refresh token can only used once.', - title='Token Updater', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class DpathExtractor(BaseModel): - type: Literal['DpathExtractor'] - field_path: List[str] = Field( - ..., - description='List of potentially nested fields describing the full path of the field to extract. Use "*" to extract all values from an array. See more info in the [docs](https://docs.airbyte.com/connector-development/config-based/understanding-the-yaml-file/record-selector).', - examples=[ - ['data'], - ['data', 'records'], - ['data', '{{ parameters.name }}'], - ['data', '*', 'record'], - ], - title='Field Path', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class ExponentialBackoffStrategy(BaseModel): - type: Literal['ExponentialBackoffStrategy'] - factor: Optional[Union[float, str]] = Field( - 5, - description='Multiplicative constant applied on each retry.', - examples=[5, 5.5, '10'], - title='Factor', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class SessionTokenRequestBearerAuthenticator(BaseModel): - type: Literal['Bearer'] - - -class HttpMethod(Enum): - GET = 'GET' - POST = 'POST' - - -class Action(Enum): - SUCCESS = 'SUCCESS' - FAIL = 'FAIL' - RETRY = 'RETRY' - IGNORE = 'IGNORE' - RATE_LIMITED = 'RATE_LIMITED' - - -class FailureType(Enum): - system_error = 'system_error' - config_error = 'config_error' - transient_error = 'transient_error' - - -class HttpResponseFilter(BaseModel): - type: Literal['HttpResponseFilter'] - action: Optional[Action] = Field( - None, - description='Action to execute if a response matches the filter.', - examples=['SUCCESS', 'FAIL', 'RETRY', 'IGNORE', 'RATE_LIMITED'], - title='Action', - ) - failure_type: Optional[FailureType] = Field( - None, - description='Failure type of traced exception if a response matches the filter.', - examples=['system_error', 'config_error', 'transient_error'], - title='Failure Type', - ) - error_message: Optional[str] = Field( - None, - description='Error Message to display if the response matches the filter.', - title='Error Message', - ) - error_message_contains: Optional[str] = Field( - None, - description='Match the response if its error message contains the substring.', - example=['This API operation is not enabled for this site'], - title='Error Message Substring', - ) - http_codes: Optional[List[int]] = Field( - None, - description='Match the response if its HTTP code is included in this list.', - examples=[[420, 429], [500]], - title='HTTP Codes', - ) - predicate: Optional[str] = Field( - None, - description='Match the response if the predicate evaluates to true.', - examples=[ - "{{ 'Too much requests' in response }}", - "{{ 'error_code' in response and response['error_code'] == 'ComplexityException' }}", - ], - title='Predicate', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class InlineSchemaLoader(BaseModel): - type: Literal['InlineSchemaLoader'] - schema_: Optional[Dict[str, Any]] = Field( - None, - alias='schema', - description='Describes a streams\' schema. Refer to the Data Types documentation for more details on which types are valid.', - title='Schema', - ) - - -class JsonFileSchemaLoader(BaseModel): - type: Literal['JsonFileSchemaLoader'] - file_path: Optional[str] = Field( - None, - description="Path to the JSON file defining the schema. The path is relative to the connector module's root.", - example=['./schemas/users.json'], - title='File Path', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class JsonDecoder(BaseModel): - type: Literal['JsonDecoder'] - - -class JsonlDecoder(BaseModel): - type: Literal['JsonlDecoder'] - - -class KeysToLower(BaseModel): - type: Literal['KeysToLower'] - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class IterableDecoder(BaseModel): - type: Literal['IterableDecoder'] - - -class XmlDecoder(BaseModel): - type: Literal['XmlDecoder'] - - -class MinMaxDatetime(BaseModel): - type: Literal['MinMaxDatetime'] - datetime: str = Field( - ..., - description='Datetime value.', - examples=['2021-01-01', '2021-01-01T00:00:00Z', "{{ config['start_time'] }}"], - title='Datetime', - ) - datetime_format: Optional[str] = Field( - '', - description='Format of the datetime value. Defaults to "%Y-%m-%dT%H:%M:%S.%f%z" if left empty. Use placeholders starting with "%" to describe the format the API is using. The following placeholders are available:\n * **%s**: Epoch unix timestamp - `1686218963`\n * **%s_as_float**: Epoch unix timestamp in seconds as float with microsecond precision - `1686218963.123456`\n * **%ms**: Epoch unix timestamp - `1686218963123`\n * **%a**: Weekday (abbreviated) - `Sun`\n * **%A**: Weekday (full) - `Sunday`\n * **%w**: Weekday (decimal) - `0` (Sunday), `6` (Saturday)\n * **%d**: Day of the month (zero-padded) - `01`, `02`, ..., `31`\n * **%b**: Month (abbreviated) - `Jan`\n * **%B**: Month (full) - `January`\n * **%m**: Month (zero-padded) - `01`, `02`, ..., `12`\n * **%y**: Year (without century, zero-padded) - `00`, `01`, ..., `99`\n * **%Y**: Year (with century) - `0001`, `0002`, ..., `9999`\n * **%H**: Hour (24-hour, zero-padded) - `00`, `01`, ..., `23`\n * **%I**: Hour (12-hour, zero-padded) - `01`, `02`, ..., `12`\n * **%p**: AM/PM indicator\n * **%M**: Minute (zero-padded) - `00`, `01`, ..., `59`\n * **%S**: Second (zero-padded) - `00`, `01`, ..., `59`\n * **%f**: Microsecond (zero-padded to 6 digits) - `000000`, `000001`, ..., `999999`\n * **%z**: UTC offset - `(empty)`, `+0000`, `-04:00`\n * **%Z**: Time zone name - `(empty)`, `UTC`, `GMT`\n * **%j**: Day of the year (zero-padded) - `001`, `002`, ..., `366`\n * **%U**: Week number of the year (Sunday as first day) - `00`, `01`, ..., `53`\n * **%W**: Week number of the year (Monday as first day) - `00`, `01`, ..., `53`\n * **%c**: Date and time representation - `Tue Aug 16 21:30:00 1988`\n * **%x**: Date representation - `08/16/1988`\n * **%X**: Time representation - `21:30:00`\n * **%%**: Literal \'%\' character\n\n Some placeholders depend on the locale of the underlying system - in most cases this locale is configured as en/US. For more information see the [Python documentation](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes).\n', - examples=['%Y-%m-%dT%H:%M:%S.%f%z', '%Y-%m-%d', '%s'], - title='Datetime Format', - ) - max_datetime: Optional[str] = Field( - None, - description='Ceiling applied on the datetime value. Must be formatted with the datetime_format field.', - examples=['2021-01-01T00:00:00Z', '2021-01-01'], - title='Max Datetime', - ) - min_datetime: Optional[str] = Field( - None, - description='Floor applied on the datetime value. Must be formatted with the datetime_format field.', - examples=['2010-01-01T00:00:00Z', '2010-01-01'], - title='Min Datetime', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class NoAuth(BaseModel): - type: Literal['NoAuth'] - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class NoPagination(BaseModel): - type: Literal['NoPagination'] - - -class OAuthConfigSpecification(BaseModel): - class Config: - extra = Extra.allow - - oauth_user_input_from_connector_config_specification: Optional[Dict[str, Any]] = ( - Field( - None, - description="OAuth specific blob. This is a Json Schema used to validate Json configurations used as input to OAuth.\nMust be a valid non-nested JSON that refers to properties from ConnectorSpecification.connectionSpecification\nusing special annotation 'path_in_connector_config'.\nThese are input values the user is entering through the UI to authenticate to the connector, that might also shared\nas inputs for syncing data via the connector.\nExamples:\nif no connector values is shared during oauth flow, oauth_user_input_from_connector_config_specification=[]\nif connector values such as 'app_id' inside the top level are used to generate the API url for the oauth flow,\n oauth_user_input_from_connector_config_specification={\n app_id: {\n type: string\n path_in_connector_config: ['app_id']\n }\n }\nif connector values such as 'info.app_id' nested inside another object are used to generate the API url for the oauth flow,\n oauth_user_input_from_connector_config_specification={\n app_id: {\n type: string\n path_in_connector_config: ['info', 'app_id']\n }\n }", - examples=[ - {'app_id': {'type': 'string', 'path_in_connector_config': ['app_id']}}, - { - 'app_id': { - 'type': 'string', - 'path_in_connector_config': ['info', 'app_id'], - } - }, - ], - title='OAuth user input', - ) - ) - complete_oauth_output_specification: Optional[Dict[str, Any]] = Field( - None, - description="OAuth specific blob. This is a Json Schema used to validate Json configurations produced by the OAuth flows as they are\nreturned by the distant OAuth APIs.\nMust be a valid JSON describing the fields to merge back to `ConnectorSpecification.connectionSpecification`.\nFor each field, a special annotation `path_in_connector_config` can be specified to determine where to merge it,\nExamples:\n complete_oauth_output_specification={\n refresh_token: {\n type: string,\n path_in_connector_config: ['credentials', 'refresh_token']\n }\n }", - examples=[ - { - 'refresh_token': { - 'type': 'string,', - 'path_in_connector_config': ['credentials', 'refresh_token'], - } - } - ], - title='OAuth output specification', - ) - complete_oauth_server_input_specification: Optional[Dict[str, Any]] = Field( - None, - description='OAuth specific blob. This is a Json Schema used to validate Json configurations persisted as Airbyte Server configurations.\nMust be a valid non-nested JSON describing additional fields configured by the Airbyte Instance or Workspace Admins to be used by the\nserver when completing an OAuth flow (typically exchanging an auth code for refresh token).\nExamples:\n complete_oauth_server_input_specification={\n client_id: {\n type: string\n },\n client_secret: {\n type: string\n }\n }', - examples=[ - {'client_id': {'type': 'string'}, 'client_secret': {'type': 'string'}} - ], - title='OAuth input specification', - ) - complete_oauth_server_output_specification: Optional[Dict[str, Any]] = Field( - None, - description="OAuth specific blob. This is a Json Schema used to validate Json configurations persisted as Airbyte Server configurations that\nalso need to be merged back into the connector configuration at runtime.\nThis is a subset configuration of `complete_oauth_server_input_specification` that filters fields out to retain only the ones that\nare necessary for the connector to function with OAuth. (some fields could be used during oauth flows but not needed afterwards, therefore\nthey would be listed in the `complete_oauth_server_input_specification` but not `complete_oauth_server_output_specification`)\nMust be a valid non-nested JSON describing additional fields configured by the Airbyte Instance or Workspace Admins to be used by the\nconnector when using OAuth flow APIs.\nThese fields are to be merged back to `ConnectorSpecification.connectionSpecification`.\nFor each field, a special annotation `path_in_connector_config` can be specified to determine where to merge it,\nExamples:\n complete_oauth_server_output_specification={\n client_id: {\n type: string,\n path_in_connector_config: ['credentials', 'client_id']\n },\n client_secret: {\n type: string,\n path_in_connector_config: ['credentials', 'client_secret']\n }\n }", - examples=[ - { - 'client_id': { - 'type': 'string,', - 'path_in_connector_config': ['credentials', 'client_id'], - }, - 'client_secret': { - 'type': 'string,', - 'path_in_connector_config': ['credentials', 'client_secret'], - }, - } - ], - title='OAuth server output specification', - ) - - -class OffsetIncrement(BaseModel): - type: Literal['OffsetIncrement'] - page_size: Optional[Union[int, str]] = Field( - None, - description='The number of records to include in each pages.', - examples=[100, "{{ config['page_size'] }}"], - title='Limit', - ) - inject_on_first_request: Optional[bool] = Field( - False, - description='Using the `offset` with value `0` during the first request', - title='Inject Offset', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class PageIncrement(BaseModel): - type: Literal['PageIncrement'] - page_size: Optional[Union[int, str]] = Field( - None, - description='The number of records to include in each pages.', - examples=[100, '100', "{{ config['page_size'] }}"], - title='Page Size', - ) - start_from_page: Optional[int] = Field( - 0, - description='Index of the first page to request.', - examples=[0, 1], - title='Start From Page', - ) - inject_on_first_request: Optional[bool] = Field( - False, - description='Using the `page number` with value defined by `start_from_page` during the first request', - title='Inject Page Number', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class PrimaryKey(BaseModel): - __root__: Union[str, List[str], List[List[str]]] = Field( - ..., - description='The stream field to be used to distinguish unique records. Can either be a single field, an array of fields representing a composite key, or an array of arrays representing a composite key where the fields are nested fields.', - examples=['id', ['code', 'type']], - title='Primary Key', - ) - - -class RecordFilter(BaseModel): - type: Literal['RecordFilter'] - condition: Optional[str] = Field( - '', - description='The predicate to filter a record. Records will be removed if evaluated to False.', - examples=[ - "{{ record['created_at'] >= stream_interval['start_time'] }}", - "{{ record.status in ['active', 'expired'] }}", - ], - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class SchemaNormalization(Enum): - None_ = 'None' - Default = 'Default' - - -class RemoveFields(BaseModel): - type: Literal['RemoveFields'] - condition: Optional[str] = Field( - '', - description='The predicate to filter a property by a property value. Property will be removed if it is empty OR expression is evaluated to True.,', - examples=[ - "{{ property|string == '' }}", - '{{ property is integer }}', - '{{ property|length > 5 }}', - "{{ property == 'some_string_to_match' }}", - ], - ) - field_pointers: List[List[str]] = Field( - ..., - description='Array of paths defining the field to remove. Each item is an array whose field describe the path of a field to remove.', - examples=[['tags'], [['content', 'html'], ['content', 'plain_text']]], - title='Field Paths', - ) - - -class RequestPath(BaseModel): - type: Literal['RequestPath'] - - -class InjectInto(Enum): - request_parameter = 'request_parameter' - header = 'header' - body_data = 'body_data' - body_json = 'body_json' - - -class RequestOption(BaseModel): - type: Literal['RequestOption'] - field_name: str = Field( - ..., - description='Configures which key should be used in the location that the descriptor is being injected into', - examples=['segment_id'], - title='Request Option', - ) - inject_into: InjectInto = Field( - ..., - description='Configures where the descriptor should be set on the HTTP requests. Note that request parameters that are already encoded in the URL path will not be duplicated.', - examples=['request_parameter', 'header', 'body_data', 'body_json'], - title='Inject Into', - ) - - -class Schemas(BaseModel): - pass - - class Config: - extra = Extra.allow - - -class LegacySessionTokenAuthenticator(BaseModel): - type: Literal['LegacySessionTokenAuthenticator'] - header: str = Field( - ..., - description='The name of the session token header that will be injected in the request', - examples=['X-Session'], - title='Session Request Header', - ) - login_url: str = Field( - ..., - description='Path of the login URL (do not include the base URL)', - examples=['session'], - title='Login Path', - ) - session_token: Optional[str] = Field( - None, - description='Session token to use if using a pre-defined token. Not needed if authenticating with username + password pair', - example=["{{ config['session_token'] }}"], - title='Session Token', - ) - session_token_response_key: str = Field( - ..., - description='Name of the key of the session token to be extracted from the response', - examples=['id'], - title='Response Token Response Key', - ) - username: Optional[str] = Field( - None, - description='Username used to authenticate and obtain a session token', - examples=[" {{ config['username'] }}"], - title='Username', - ) - password: Optional[str] = Field( - '', - description='Password used to authenticate and obtain a session token', - examples=["{{ config['password'] }}", ''], - title='Password', - ) - validate_session_url: str = Field( - ..., - description='Path of the URL to use to validate that the session token is valid (do not include the base URL)', - examples=['user/current'], - title='Validate Session Path', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class AsyncJobStatusMap(BaseModel): - type: Optional[Literal['AsyncJobStatusMap']] = None - running: List[str] - completed: List[str] - failed: List[str] - timeout: List[str] - - -class ValueType(Enum): - string = 'string' - number = 'number' - integer = 'integer' - boolean = 'boolean' - - -class WaitTimeFromHeader(BaseModel): - type: Literal['WaitTimeFromHeader'] - header: str = Field( - ..., - description='The name of the response header defining how long to wait before retrying.', - examples=['Retry-After'], - title='Response Header Name', - ) - regex: Optional[str] = Field( - None, - description='Optional regex to apply on the header to extract its value. The regex should define a capture group defining the wait time.', - examples=['([-+]?\\d+)'], - title='Extraction Regex', - ) - max_waiting_time_in_seconds: Optional[float] = Field( - None, - description='Given the value extracted from the header is greater than this value, stop the stream.', - examples=[3600], - title='Max Waiting Time in Seconds', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class WaitUntilTimeFromHeader(BaseModel): - type: Literal['WaitUntilTimeFromHeader'] - header: str = Field( - ..., - description='The name of the response header defining how long to wait before retrying.', - examples=['wait_time'], - title='Response Header', - ) - min_wait: Optional[Union[float, str]] = Field( - None, - description='Minimum time to wait before retrying.', - examples=[10, '60'], - title='Minimum Wait Time', - ) - regex: Optional[str] = Field( - None, - description='Optional regex to apply on the header to extract its value. The regex should define a capture group defining the wait time.', - examples=['([-+]?\\d+)'], - title='Extraction Regex', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class AddedFieldDefinition(BaseModel): - type: Literal['AddedFieldDefinition'] - path: List[str] = Field( - ..., - description='List of strings defining the path where to add the value on the record.', - examples=[['segment_id'], ['metadata', 'segment_id']], - title='Path', - ) - value: str = Field( - ..., - description="Value of the new field. Use {{ record['existing_field'] }} syntax to refer to other fields in the record.", - examples=[ - "{{ record['updates'] }}", - "{{ record['MetaData']['LastUpdatedTime'] }}", - "{{ stream_partition['segment_id'] }}", - ], - title='Value', - ) - value_type: Optional[ValueType] = Field( - None, - description='Type of the value. If not specified, the type will be inferred from the value.', - title='Value Type', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class AddFields(BaseModel): - type: Literal['AddFields'] - fields: List[AddedFieldDefinition] = Field( - ..., - description='List of transformations (path and corresponding value) that will be added to the record.', - title='Fields', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class ApiKeyAuthenticator(BaseModel): - type: Literal['ApiKeyAuthenticator'] - api_token: Optional[str] = Field( - None, - description='The API key to inject in the request. Fill it in the user inputs.', - examples=["{{ config['api_key'] }}", "Token token={{ config['api_key'] }}"], - title='API Key', - ) - header: Optional[str] = Field( - None, - description='The name of the HTTP header that will be set to the API key. This setting is deprecated, use inject_into instead. Header and inject_into can not be defined at the same time.', - examples=['Authorization', 'Api-Token', 'X-Auth-Token'], - title='Header Name', - ) - inject_into: Optional[RequestOption] = Field( - None, - description='Configure how the API Key will be sent in requests to the source API. Either inject_into or header has to be defined.', - examples=[ - {'inject_into': 'header', 'field_name': 'Authorization'}, - {'inject_into': 'request_parameter', 'field_name': 'authKey'}, - ], - title='Inject API Key Into Outgoing HTTP Request', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class AuthFlow(BaseModel): - auth_flow_type: Optional[AuthFlowType] = Field( - None, description='The type of auth to use', title='Auth flow type' - ) - predicate_key: Optional[List[str]] = Field( - None, - description='JSON path to a field in the connectorSpecification that should exist for the advanced auth to be applicable.', - examples=[['credentials', 'auth_type']], - title='Predicate key', - ) - predicate_value: Optional[str] = Field( - None, - description='Value of the predicate_key fields for the advanced auth to be applicable.', - examples=['Oauth'], - title='Predicate value', - ) - oauth_config_specification: Optional[OAuthConfigSpecification] = None - - -class DatetimeBasedCursor(BaseModel): - type: Literal['DatetimeBasedCursor'] - cursor_field: str = Field( - ..., - description='The location of the value on a record that will be used as a bookmark during sync. To ensure no data loss, the API must return records in ascending order based on the cursor field. Nested fields are not supported, so the field must be at the top level of the record. You can use a combination of Add Field and Remove Field transformations to move the nested field to the top.', - examples=['created_at', "{{ config['record_cursor'] }}"], - title='Cursor Field', - ) - datetime_format: str = Field( - ..., - description='The datetime format used to format the datetime values that are sent in outgoing requests to the API. Use placeholders starting with "%" to describe the format the API is using. The following placeholders are available:\n * **%s**: Epoch unix timestamp - `1686218963`\n * **%s_as_float**: Epoch unix timestamp in seconds as float with microsecond precision - `1686218963.123456`\n * **%ms**: Epoch unix timestamp (milliseconds) - `1686218963123`\n * **%a**: Weekday (abbreviated) - `Sun`\n * **%A**: Weekday (full) - `Sunday`\n * **%w**: Weekday (decimal) - `0` (Sunday), `6` (Saturday)\n * **%d**: Day of the month (zero-padded) - `01`, `02`, ..., `31`\n * **%b**: Month (abbreviated) - `Jan`\n * **%B**: Month (full) - `January`\n * **%m**: Month (zero-padded) - `01`, `02`, ..., `12`\n * **%y**: Year (without century, zero-padded) - `00`, `01`, ..., `99`\n * **%Y**: Year (with century) - `0001`, `0002`, ..., `9999`\n * **%H**: Hour (24-hour, zero-padded) - `00`, `01`, ..., `23`\n * **%I**: Hour (12-hour, zero-padded) - `01`, `02`, ..., `12`\n * **%p**: AM/PM indicator\n * **%M**: Minute (zero-padded) - `00`, `01`, ..., `59`\n * **%S**: Second (zero-padded) - `00`, `01`, ..., `59`\n * **%f**: Microsecond (zero-padded to 6 digits) - `000000`\n * **%z**: UTC offset - `(empty)`, `+0000`, `-04:00`\n * **%Z**: Time zone name - `(empty)`, `UTC`, `GMT`\n * **%j**: Day of the year (zero-padded) - `001`, `002`, ..., `366`\n * **%U**: Week number of the year (starting Sunday) - `00`, ..., `53`\n * **%W**: Week number of the year (starting Monday) - `00`, ..., `53`\n * **%c**: Date and time - `Tue Aug 16 21:30:00 1988`\n * **%x**: Date standard format - `08/16/1988`\n * **%X**: Time standard format - `21:30:00`\n * **%%**: Literal \'%\' character\n\n Some placeholders depend on the locale of the underlying system - in most cases this locale is configured as en/US. For more information see the [Python documentation](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes).\n', - examples=['%Y-%m-%dT%H:%M:%S.%f%z', '%Y-%m-%d', '%s', '%ms', '%s_as_float'], - title='Outgoing Datetime Format', - ) - start_datetime: Union[str, MinMaxDatetime] = Field( - ..., - description='The datetime that determines the earliest record that should be synced.', - examples=['2020-01-1T00:00:00Z', "{{ config['start_time'] }}"], - title='Start Datetime', - ) - cursor_datetime_formats: Optional[List[str]] = Field( - None, - description='The possible formats for the cursor field, in order of preference. The first format that matches the cursor field value will be used to parse it. If not provided, the `datetime_format` will be used.', - title='Cursor Datetime Formats', - ) - cursor_granularity: Optional[str] = Field( - None, - description='Smallest increment the datetime_format has (ISO 8601 duration) that is used to ensure the start of a slice does not overlap with the end of the previous one, e.g. for %Y-%m-%d the granularity should be P1D, for %Y-%m-%dT%H:%M:%SZ the granularity should be PT1S. Given this field is provided, `step` needs to be provided as well.', - examples=['PT1S'], - title='Cursor Granularity', - ) - end_datetime: Optional[Union[str, MinMaxDatetime]] = Field( - None, - description='The datetime that determines the last record that should be synced. If not provided, `{{ now_utc() }}` will be used.', - examples=['2021-01-1T00:00:00Z', '{{ now_utc() }}', '{{ day_delta(-1) }}'], - title='End Datetime', - ) - end_time_option: Optional[RequestOption] = Field( - None, - description='Optionally configures how the end datetime will be sent in requests to the source API.', - title='Inject End Time Into Outgoing HTTP Request', - ) - is_data_feed: Optional[bool] = Field( - None, - description='A data feed API is an API that does not allow filtering and paginates the content from the most recent to the least recent. Given this, the CDK needs to know when to stop paginating and this field will generate a stop condition for pagination.', - title='Whether the target API is formatted as a data feed', - ) - is_client_side_incremental: Optional[bool] = Field( - None, - description='If the target API endpoint does not take cursor values to filter records and returns all records anyway, the connector with this cursor will filter out records locally, and only emit new records from the last sync, hence incremental. This means that all records would be read from the API, but only new records will be emitted to the destination.', - title='Whether the target API does not support filtering and returns all data (the cursor filters records in the client instead of the API side)', - ) - is_compare_strictly: Optional[bool] = Field( - False, - description='Set to True if the target API does not accept queries where the start time equal the end time.', - title='Whether to skip requests if the start time equals the end time', - ) - global_substream_cursor: Optional[bool] = Field( - False, - description='This setting optimizes performance when the parent stream has thousands of partitions by storing the cursor as a single value rather than per partition. Notably, the substream state is updated only at the end of the sync, which helps prevent data loss in case of a sync failure. See more info in the [docs](https://docs.airbyte.com/connector-development/config-based/understanding-the-yaml-file/incremental-syncs).', - title='Whether to store cursor as one value instead of per partition', - ) - lookback_window: Optional[str] = Field( - None, - description='Time interval before the start_datetime to read data for, e.g. P1M for looking back one month.', - examples=['P1D', "P{{ config['lookback_days'] }}D"], - title='Lookback Window', - ) - partition_field_end: Optional[str] = Field( - None, - description='Name of the partition start time field.', - examples=['ending_time'], - title='Partition Field End', - ) - partition_field_start: Optional[str] = Field( - None, - description='Name of the partition end time field.', - examples=['starting_time'], - title='Partition Field Start', - ) - start_time_option: Optional[RequestOption] = Field( - None, - description='Optionally configures how the start datetime will be sent in requests to the source API.', - title='Inject Start Time Into Outgoing HTTP Request', - ) - step: Optional[str] = Field( - None, - description='The size of the time window (ISO8601 duration). Given this field is provided, `cursor_granularity` needs to be provided as well.', - examples=['P1W', "{{ config['step_increment'] }}"], - title='Step', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class DefaultErrorHandler(BaseModel): - type: Literal['DefaultErrorHandler'] - backoff_strategies: Optional[ - List[ - Union[ - ConstantBackoffStrategy, - CustomBackoffStrategy, - ExponentialBackoffStrategy, - WaitTimeFromHeader, - WaitUntilTimeFromHeader, - ] - ] - ] = Field( - None, - description='List of backoff strategies to use to determine how long to wait before retrying a retryable request.', - title='Backoff Strategies', - ) - max_retries: Optional[int] = Field( - 5, - description='The maximum number of time to retry a retryable request before giving up and failing.', - examples=[5, 0, 10], - title='Max Retry Count', - ) - response_filters: Optional[List[HttpResponseFilter]] = Field( - None, - description="List of response filters to iterate on when deciding how to handle an error. When using an array of multiple filters, the filters will be applied sequentially and the response will be selected if it matches any of the filter's predicate.", - title='Response Filters', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class DefaultPaginator(BaseModel): - type: Literal['DefaultPaginator'] - pagination_strategy: Union[ - CursorPagination, CustomPaginationStrategy, OffsetIncrement, PageIncrement - ] = Field( - ..., - description='Strategy defining how records are paginated.', - title='Pagination Strategy', - ) - page_size_option: Optional[RequestOption] = None - page_token_option: Optional[Union[RequestOption, RequestPath]] = None - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class SessionTokenRequestApiKeyAuthenticator(BaseModel): - type: Literal['ApiKey'] - inject_into: RequestOption = Field( - ..., - description='Configure how the API Key will be sent in requests to the source API.', - examples=[ - {'inject_into': 'header', 'field_name': 'Authorization'}, - {'inject_into': 'request_parameter', 'field_name': 'authKey'}, - ], - title='Inject API Key Into Outgoing HTTP Request', - ) - - -class ListPartitionRouter(BaseModel): - type: Literal['ListPartitionRouter'] - cursor_field: str = Field( - ..., - description='While iterating over list values, the name of field used to reference a list value. The partition value can be accessed with string interpolation. e.g. "{{ stream_partition[\'my_key\'] }}" where "my_key" is the value of the cursor_field.', - examples=['section', "{{ config['section_key'] }}"], - title='Current Partition Value Identifier', - ) - values: Union[str, List[str]] = Field( - ..., - description='The list of attributes being iterated over and used as input for the requests made to the source API.', - examples=[['section_a', 'section_b', 'section_c'], "{{ config['sections'] }}"], - title='Partition Values', - ) - request_option: Optional[RequestOption] = Field( - None, - description='A request option describing where the list value should be injected into and under what field name if applicable.', - title='Inject Partition Value Into Outgoing HTTP Request', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class RecordSelector(BaseModel): - type: Literal['RecordSelector'] - extractor: Union[CustomRecordExtractor, DpathExtractor] - record_filter: Optional[Union[CustomRecordFilter, RecordFilter]] = Field( - None, - description='Responsible for filtering records to be emitted by the Source.', - title='Record Filter', - ) - schema_normalization: Optional[SchemaNormalization] = SchemaNormalization.None_ - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class Spec(BaseModel): - type: Literal['Spec'] - connection_specification: Dict[str, Any] = Field( - ..., - description='A connection specification describing how a the connector can be configured.', - title='Connection Specification', - ) - documentation_url: Optional[str] = Field( - None, - description="URL of the connector's documentation page.", - examples=['https://docs.airbyte.com/integrations/sources/dremio'], - title='Documentation URL', - ) - advanced_auth: Optional[AuthFlow] = Field( - None, - description='Advanced specification for configuring the authentication flow.', - title='Advanced Auth', - ) - - -class CompositeErrorHandler(BaseModel): - type: Literal['CompositeErrorHandler'] - error_handlers: List[Union[CompositeErrorHandler, DefaultErrorHandler]] = Field( - ..., - description='List of error handlers to iterate on to determine how to handle a failed response.', - title='Error Handlers', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class DeclarativeSource(BaseModel): - class Config: - extra = Extra.forbid - - type: Literal['DeclarativeSource'] - check: CheckStream - streams: List[DeclarativeStream] - version: str = Field( - ..., - description='The version of the Airbyte CDK used to build and test the source.', - ) - schemas: Optional[Schemas] = None - definitions: Optional[Dict[str, Any]] = None - spec: Optional[Spec] = None - concurrency_level: Optional[ConcurrencyLevel] = None - metadata: Optional[Dict[str, Any]] = Field( - None, - description='For internal Airbyte use only - DO NOT modify manually. Used by consumers of declarative manifests for storing related metadata.', - ) - description: Optional[str] = Field( - None, - description='A description of the connector. It will be presented on the Source documentation page.', - ) - - -class SelectiveAuthenticator(BaseModel): - class Config: - extra = Extra.allow - - type: Literal['SelectiveAuthenticator'] - authenticator_selection_path: List[str] = Field( - ..., - description='Path of the field in config with selected authenticator name', - examples=[['auth'], ['auth', 'type']], - title='Authenticator Selection Path', - ) - authenticators: Dict[ - str, - Union[ - ApiKeyAuthenticator, - BasicHttpAuthenticator, - BearerAuthenticator, - CustomAuthenticator, - OAuthAuthenticator, - JwtAuthenticator, - NoAuth, - SessionTokenAuthenticator, - LegacySessionTokenAuthenticator, - ], - ] = Field( - ..., - description='Authenticators to select from.', - examples=[ - { - 'authenticators': { - 'token': '#/definitions/ApiKeyAuthenticator', - 'oauth': '#/definitions/OAuthAuthenticator', - 'jwt': '#/definitions/JwtAuthenticator', - } - } - ], - title='Authenticators', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class DeclarativeStream(BaseModel): - class Config: - extra = Extra.allow - - type: Literal['DeclarativeStream'] - retriever: Union[AsyncRetriever, CustomRetriever, SimpleRetriever] = Field( - ..., - description='Component used to coordinate how records are extracted across stream slices and request pages.', - title='Retriever', - ) - incremental_sync: Optional[Union[CustomIncrementalSync, DatetimeBasedCursor]] = ( - Field( - None, - description='Component used to fetch data incrementally based on a time field in the data.', - title='Incremental Sync', - ) - ) - name: Optional[str] = Field( - '', description='The stream name.', example=['Users'], title='Name' - ) - primary_key: Optional[PrimaryKey] = Field( - '', description='The primary key of the stream.', title='Primary Key' - ) - schema_loader: Optional[ - Union[InlineSchemaLoader, JsonFileSchemaLoader, CustomSchemaLoader] - ] = Field( - None, - description='Component used to retrieve the schema for the current stream.', - title='Schema Loader', - ) - transformations: Optional[ - List[Union[AddFields, CustomTransformation, RemoveFields, KeysToLower]] - ] = Field( - None, - description='A list of transformations to be applied to each output record.', - title='Transformations', - ) - state_migrations: Optional[ - List[Union[LegacyToPerPartitionStateMigration, CustomStateMigration]] - ] = Field( - [], - description='Array of state migrations to be applied on the input state', - title='State Migrations', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class SessionTokenAuthenticator(BaseModel): - type: Literal['SessionTokenAuthenticator'] - login_requester: HttpRequester = Field( - ..., - description='Description of the request to perform to obtain a session token to perform data requests. The response body is expected to be a JSON object with a session token property.', - examples=[ - { - 'type': 'HttpRequester', - 'url_base': 'https://my_api.com', - 'path': '/login', - 'authenticator': { - 'type': 'BasicHttpAuthenticator', - 'username': '{{ config.username }}', - 'password': '{{ config.password }}', - }, - } - ], - title='Login Requester', - ) - session_token_path: List[str] = Field( - ..., - description='The path in the response body returned from the login requester to the session token.', - examples=[['access_token'], ['result', 'token']], - title='Session Token Path', - ) - expiration_duration: Optional[str] = Field( - None, - description='The duration in ISO 8601 duration notation after which the session token expires, starting from the time it was obtained. Omitting it will result in the session token being refreshed for every request.', - examples=['PT1H', 'P1D'], - title='Expiration Duration', - ) - request_authentication: Union[ - SessionTokenRequestApiKeyAuthenticator, SessionTokenRequestBearerAuthenticator - ] = Field( - ..., - description='Authentication method to use for requests sent to the API, specifying how to inject the session token.', - title='Data Request Authentication', - ) - decoder: Optional[Union[JsonDecoder, XmlDecoder]] = Field( - None, description='Component used to decode the response.', title='Decoder' - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class HttpRequester(BaseModel): - type: Literal['HttpRequester'] - url_base: str = Field( - ..., - description='Base URL of the API source. Do not put sensitive information (e.g. API tokens) into this field - Use the Authentication component for this.', - examples=[ - 'https://connect.squareup.com/v2', - "{{ config['base_url'] or 'https://app.posthog.com'}}/api/", - ], - title='API Base URL', - ) - path: str = Field( - ..., - description='Path the specific API endpoint that this stream represents. Do not put sensitive information (e.g. API tokens) into this field - Use the Authentication component for this.', - examples=[ - '/products', - "/quotes/{{ stream_partition['id'] }}/quote_line_groups", - "/trades/{{ config['symbol_id'] }}/history", - ], - title='URL Path', - ) - authenticator: Optional[ - Union[ - ApiKeyAuthenticator, - BasicHttpAuthenticator, - BearerAuthenticator, - CustomAuthenticator, - OAuthAuthenticator, - JwtAuthenticator, - NoAuth, - SessionTokenAuthenticator, - LegacySessionTokenAuthenticator, - SelectiveAuthenticator, - ] - ] = Field( - None, - description='Authentication method to use for requests sent to the API.', - title='Authenticator', - ) - error_handler: Optional[ - Union[DefaultErrorHandler, CustomErrorHandler, CompositeErrorHandler] - ] = Field( - None, - description='Error handler component that defines how to handle errors.', - title='Error Handler', - ) - http_method: Optional[HttpMethod] = Field( - HttpMethod.GET, - description='The HTTP method used to fetch data from the source (can be GET or POST).', - examples=['GET', 'POST'], - title='HTTP Method', - ) - request_body_data: Optional[Union[str, Dict[str, str]]] = Field( - None, - description='Specifies how to populate the body of the request with a non-JSON payload. Plain text will be sent as is, whereas objects will be converted to a urlencoded form.', - examples=[ - '[{"clause": {"type": "timestamp", "operator": 10, "parameters":\n [{"value": {{ stream_interval[\'start_time\'] | int * 1000 }} }]\n }, "orderBy": 1, "columnName": "Timestamp"}]/\n' - ], - title='Request Body Payload (Non-JSON)', - ) - request_body_json: Optional[Union[str, Dict[str, Any]]] = Field( - None, - description='Specifies how to populate the body of the request with a JSON payload. Can contain nested objects.', - examples=[ - {'sort_order': 'ASC', 'sort_field': 'CREATED_AT'}, - {'key': "{{ config['value'] }}"}, - {'sort': {'field': 'updated_at', 'order': 'ascending'}}, - ], - title='Request Body JSON Payload', - ) - request_headers: Optional[Union[str, Dict[str, str]]] = Field( - None, - description='Return any non-auth headers. Authentication headers will overwrite any overlapping headers returned from this method.', - examples=[{'Output-Format': 'JSON'}, {'Version': "{{ config['version'] }}"}], - title='Request Headers', - ) - request_parameters: Optional[Union[str, Dict[str, str]]] = Field( - None, - description='Specifies the query parameters that should be set on an outgoing HTTP request given the inputs.', - examples=[ - {'unit': 'day'}, - { - 'query': 'last_event_time BETWEEN TIMESTAMP "{{ stream_interval.start_time }}" AND TIMESTAMP "{{ stream_interval.end_time }}"' - }, - {'searchIn': "{{ ','.join(config.get('search_in', [])) }}"}, - {'sort_by[asc]': 'updated_at'}, - ], - title='Query Parameters', - ) - use_cache: Optional[bool] = Field( - False, - description='Enables stream requests caching. This field is automatically set by the CDK.', - title='Use Cache', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class ParentStreamConfig(BaseModel): - type: Literal['ParentStreamConfig'] - parent_key: str = Field( - ..., - description='The primary key of records from the parent stream that will be used during the retrieval of records for the current substream. This parent identifier field is typically a characteristic of the child records being extracted from the source API.', - examples=['id', "{{ config['parent_record_id'] }}"], - title='Parent Key', - ) - stream: DeclarativeStream = Field( - ..., description='Reference to the parent stream.', title='Parent Stream' - ) - partition_field: str = Field( - ..., - description='While iterating over parent records during a sync, the parent_key value can be referenced by using this field.', - examples=['parent_id', "{{ config['parent_partition_field'] }}"], - title='Current Parent Key Value Identifier', - ) - request_option: Optional[RequestOption] = Field( - None, - description='A request option describing where the parent key value should be injected into and under what field name if applicable.', - title='Request Option', - ) - incremental_dependency: Optional[bool] = Field( - False, - description='Indicates whether the parent stream should be read incrementally based on updates in the child stream.', - title='Incremental Dependency', - ) - extra_fields: Optional[List[List[str]]] = Field( - None, - description='Array of field paths to include as additional fields in the stream slice. Each path is an array of strings representing keys to access fields in the respective parent record. Accessible via `stream_slice.extra_fields`. Missing fields are set to `None`.', - title='Extra Fields', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class SimpleRetriever(BaseModel): - type: Literal['SimpleRetriever'] - record_selector: RecordSelector = Field( - ..., - description='Component that describes how to extract records from a HTTP response.', - ) - requester: Union[CustomRequester, HttpRequester] = Field( - ..., - description='Requester component that describes how to prepare HTTP requests to send to the source API.', - ) - paginator: Optional[Union[DefaultPaginator, NoPagination]] = Field( - None, - description="Paginator component that describes how to navigate through the API's pages.", - ) - ignore_stream_slicer_parameters_on_paginated_requests: Optional[bool] = Field( - False, - description='If true, the partition router and incremental request options will be ignored when paginating requests. Request options set directly on the requester will not be ignored.', - ) - partition_router: Optional[ - Union[ - CustomPartitionRouter, - ListPartitionRouter, - SubstreamPartitionRouter, - List[ - Union[ - CustomPartitionRouter, ListPartitionRouter, SubstreamPartitionRouter - ] - ], - ] - ] = Field( - [], - description='PartitionRouter component that describes how to partition the stream, enabling incremental syncs and checkpointing.', - title='Partition Router', - ) - decoder: Optional[Union[JsonDecoder, JsonlDecoder, IterableDecoder, XmlDecoder]] = ( - Field( - None, - description='Component decoding the response so records can be extracted.', - title='Decoder', - ) - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class AsyncRetriever(BaseModel): - type: Literal['AsyncRetriever'] - record_selector: RecordSelector = Field( - ..., - description='Component that describes how to extract records from a HTTP response.', - ) - status_mapping: AsyncJobStatusMap = Field( - ..., description='Async Job Status to Airbyte CDK Async Job Status mapping.' - ) - status_extractor: Union[CustomRecordExtractor, DpathExtractor] = Field( - ..., description='Responsible for fetching the actual status of the async job.' - ) - urls_extractor: Union[CustomRecordExtractor, DpathExtractor] = Field( - ..., - description='Responsible for fetching the final result `urls` provided by the completed / finished / ready async job.', - ) - creation_requester: Union[CustomRequester, HttpRequester] = Field( - ..., - description='Requester component that describes how to prepare HTTP requests to send to the source API to create the async server-side job.', - ) - polling_requester: Union[CustomRequester, HttpRequester] = Field( - ..., - description='Requester component that describes how to prepare HTTP requests to send to the source API to fetch the status of the running async job.', - ) - download_requester: Union[CustomRequester, HttpRequester] = Field( - ..., - description='Requester component that describes how to prepare HTTP requests to send to the source API to download the data provided by the completed async job.', - ) - download_paginator: Optional[Union[DefaultPaginator, NoPagination]] = Field( - None, - description="Paginator component that describes how to navigate through the API's pages during download.", - ) - abort_requester: Optional[Union[CustomRequester, HttpRequester]] = Field( - None, - description="Requester component that describes how to prepare HTTP requests to send to the source API to abort a job once it is timed out from the source's perspective.", - ) - delete_requester: Optional[Union[CustomRequester, HttpRequester]] = Field( - None, - description='Requester component that describes how to prepare HTTP requests to send to the source API to delete a job once the records are extracted.', - ) - partition_router: Optional[ - Union[ - CustomPartitionRouter, - ListPartitionRouter, - SubstreamPartitionRouter, - List[ - Union[ - CustomPartitionRouter, ListPartitionRouter, SubstreamPartitionRouter - ] - ], - ] - ] = Field( - [], - description='PartitionRouter component that describes how to partition the stream, enabling incremental syncs and checkpointing.', - title='Partition Router', - ) - decoder: Optional[Union[JsonDecoder, JsonlDecoder, IterableDecoder, XmlDecoder]] = ( - Field( - None, - description='Component decoding the response so records can be extracted.', - title='Decoder', - ) - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -class SubstreamPartitionRouter(BaseModel): - type: Literal['SubstreamPartitionRouter'] - parent_stream_configs: List[ParentStreamConfig] = Field( - ..., - description='Specifies which parent streams are being iterated over and how parent records should be used to partition the child stream data set.', - title='Parent Stream Configs', - ) - parameters: Optional[Dict[str, Any]] = Field(None, alias='$parameters') - - -CompositeErrorHandler.update_forward_refs() -DeclarativeSource.update_forward_refs() -SelectiveAuthenticator.update_forward_refs() -DeclarativeStream.update_forward_refs() -SessionTokenAuthenticator.update_forward_refs() -SimpleRetriever.update_forward_refs() -AsyncRetriever.update_forward_refs() diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/__init__.py deleted file mode 100644 index 46b7376756ec..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/custom_exceptions.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/custom_exceptions.py deleted file mode 100644 index d6fdee69562f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/custom_exceptions.py +++ /dev/null @@ -1,21 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -class CircularReferenceException(Exception): - """ - Raised when a circular reference is detected in a manifest. - """ - - def __init__(self, reference: str) -> None: - super().__init__(f"Circular reference found: {reference}") - - -class UndefinedReferenceException(Exception): - """ - Raised when refering to an undefined reference. - """ - - def __init__(self, path: str, reference: str) -> None: - super().__init__(f"Undefined reference {reference} from {path}") diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py deleted file mode 100644 index 7b8b221c68df..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py +++ /dev/null @@ -1,150 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import copy -import typing -from typing import Any, Mapping - -PARAMETERS_STR = "$parameters" - - -DEFAULT_MODEL_TYPES: Mapping[str, str] = { - # CompositeErrorHandler - "CompositeErrorHandler.error_handlers": "DefaultErrorHandler", - # CursorPagination - "CursorPagination.decoder": "JsonDecoder", - # DatetimeBasedCursor - "DatetimeBasedCursor.end_datetime": "MinMaxDatetime", - "DatetimeBasedCursor.end_time_option": "RequestOption", - "DatetimeBasedCursor.start_datetime": "MinMaxDatetime", - "DatetimeBasedCursor.start_time_option": "RequestOption", - # CustomIncrementalSync - "CustomIncrementalSync.end_datetime": "MinMaxDatetime", - "CustomIncrementalSync.end_time_option": "RequestOption", - "CustomIncrementalSync.start_datetime": "MinMaxDatetime", - "CustomIncrementalSync.start_time_option": "RequestOption", - # DeclarativeSource - "DeclarativeSource.check": "CheckStream", - "DeclarativeSource.spec": "Spec", - "DeclarativeSource.streams": "DeclarativeStream", - # DeclarativeStream - "DeclarativeStream.retriever": "SimpleRetriever", - "DeclarativeStream.schema_loader": "JsonFileSchemaLoader", - # DefaultErrorHandler - "DefaultErrorHandler.response_filters": "HttpResponseFilter", - # DefaultPaginator - "DefaultPaginator.decoder": "JsonDecoder", - "DefaultPaginator.page_size_option": "RequestOption", - # DpathExtractor - "DpathExtractor.decoder": "JsonDecoder", - # HttpRequester - "HttpRequester.error_handler": "DefaultErrorHandler", - # ListPartitionRouter - "ListPartitionRouter.request_option": "RequestOption", - # ParentStreamConfig - "ParentStreamConfig.request_option": "RequestOption", - "ParentStreamConfig.stream": "DeclarativeStream", - # RecordSelector - "RecordSelector.extractor": "DpathExtractor", - "RecordSelector.record_filter": "RecordFilter", - # SimpleRetriever - "SimpleRetriever.paginator": "NoPagination", - "SimpleRetriever.record_selector": "RecordSelector", - "SimpleRetriever.requester": "HttpRequester", - # SubstreamPartitionRouter - "SubstreamPartitionRouter.parent_stream_configs": "ParentStreamConfig", - # AddFields - "AddFields.fields": "AddedFieldDefinition", - # CustomPartitionRouter - "CustomPartitionRouter.parent_stream_configs": "ParentStreamConfig", -} - -# We retain a separate registry for custom components to automatically insert the type if it is missing. This is intended to -# be a short term fix because once we have migrated, then type and class_name should be requirements for all custom components. -CUSTOM_COMPONENTS_MAPPING: Mapping[str, str] = { - "CompositeErrorHandler.backoff_strategies": "CustomBackoffStrategy", - "DeclarativeStream.retriever": "CustomRetriever", - "DeclarativeStream.transformations": "CustomTransformation", - "DefaultErrorHandler.backoff_strategies": "CustomBackoffStrategy", - "DefaultPaginator.pagination_strategy": "CustomPaginationStrategy", - "HttpRequester.authenticator": "CustomAuthenticator", - "HttpRequester.error_handler": "CustomErrorHandler", - "RecordSelector.extractor": "CustomRecordExtractor", - "SimpleRetriever.partition_router": "CustomPartitionRouter", -} - - -class ManifestComponentTransformer: - def propagate_types_and_parameters( - self, parent_field_identifier: str, declarative_component: Mapping[str, Any], parent_parameters: Mapping[str, Any] - ) -> Mapping[str, Any]: - """ - Recursively transforms the specified declarative component and subcomponents to propagate parameters and insert the - default component type if it was not already present. The resulting transformed components are a deep copy of the input - components, not an in-place transformation. - - :param declarative_component: The current component that is having type and parameters added - :param parent_field_identifier: The name of the field of the current component coming from the parent component - :param parent_parameters: The parameters set on parent components defined before the current component - :return: A deep copy of the transformed component with types and parameters persisted to it - """ - propagated_component = dict(copy.deepcopy(declarative_component)) - if "type" not in propagated_component: - # If the component has class_name we assume that this is a reference to a custom component. This is a slight change to - # existing behavior because we originally allowed for either class or type to be specified. After the pydantic migration, - # class_name will only be a valid field on custom components and this change reflects that. I checked, and we currently - # have no low-code connectors that use class_name except for custom components. - if "class_name" in propagated_component: - found_type = CUSTOM_COMPONENTS_MAPPING.get(parent_field_identifier) - else: - found_type = DEFAULT_MODEL_TYPES.get(parent_field_identifier) - if found_type: - propagated_component["type"] = found_type - - # When there is no resolved type, we're not processing a component (likely a regular object) and don't need to propagate parameters - # When the type refers to a json schema, we're not processing a component as well. This check is currently imperfect as there could - # be json_schema are not objects but we believe this is not likely in our case because: - # * records are Mapping so objects hence SchemaLoader root should be an object - # * connection_specification is a Mapping - if "type" not in propagated_component or self._is_json_schema_object(propagated_component): - return propagated_component - - # Combines parameters defined at the current level with parameters from parent components. Parameters at the current - # level take precedence - current_parameters = dict(copy.deepcopy(parent_parameters)) - component_parameters = propagated_component.pop(PARAMETERS_STR, {}) - current_parameters = {**current_parameters, **component_parameters} - - # Parameters should be applied to the current component fields with the existing field taking precedence over parameters if - # both exist - for parameter_key, parameter_value in current_parameters.items(): - propagated_component[parameter_key] = propagated_component.get(parameter_key) or parameter_value - - for field_name, field_value in propagated_component.items(): - if isinstance(field_value, dict): - # We exclude propagating a parameter that matches the current field name because that would result in an infinite cycle - excluded_parameter = current_parameters.pop(field_name, None) - parent_type_field_identifier = f"{propagated_component.get('type')}.{field_name}" - propagated_component[field_name] = self.propagate_types_and_parameters( - parent_type_field_identifier, field_value, current_parameters - ) - if excluded_parameter: - current_parameters[field_name] = excluded_parameter - elif isinstance(field_value, typing.List): - # We exclude propagating a parameter that matches the current field name because that would result in an infinite cycle - excluded_parameter = current_parameters.pop(field_name, None) - for i, element in enumerate(field_value): - if isinstance(element, dict): - parent_type_field_identifier = f"{propagated_component.get('type')}.{field_name}" - field_value[i] = self.propagate_types_and_parameters(parent_type_field_identifier, element, current_parameters) - if excluded_parameter: - current_parameters[field_name] = excluded_parameter - - if current_parameters: - propagated_component[PARAMETERS_STR] = current_parameters - return propagated_component - - @staticmethod - def _is_json_schema_object(propagated_component: Mapping[str, Any]) -> bool: - return propagated_component.get("type") == "object" diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/manifest_reference_resolver.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/manifest_reference_resolver.py deleted file mode 100644 index 66bf3d5ef856..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/manifest_reference_resolver.py +++ /dev/null @@ -1,206 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import re -from typing import Any, Mapping, Set, Tuple, Union - -from airbyte_cdk.sources.declarative.parsers.custom_exceptions import CircularReferenceException, UndefinedReferenceException - -REF_TAG = "$ref" - - -class ManifestReferenceResolver: - """ - An incoming manifest can contain references to values previously defined. - This parser will dereference these values to produce a complete ConnectionDefinition. - - References can be defined using a #/ string. - ``` - key: 1234 - reference: "#/key" - ``` - will produce the following definition: - ``` - key: 1234 - reference: 1234 - ``` - This also works with objects: - ``` - key_value_pairs: - k1: v1 - k2: v2 - same_key_value_pairs: "#/key_value_pairs" - ``` - will produce the following definition: - ``` - key_value_pairs: - k1: v1 - k2: v2 - same_key_value_pairs: - k1: v1 - k2: v2 - ``` - - The $ref keyword can be used to refer to an object and enhance it with addition key-value pairs - ``` - key_value_pairs: - k1: v1 - k2: v2 - same_key_value_pairs: - $ref: "#/key_value_pairs" - k3: v3 - ``` - will produce the following definition: - ``` - key_value_pairs: - k1: v1 - k2: v2 - same_key_value_pairs: - k1: v1 - k2: v2 - k3: v3 - ``` - - References can also point to nested values. - Nested references are ambiguous because one could define a key containing with `.` - in this example, we want to refer to the limit key in the dict object: - ``` - dict: - limit: 50 - limit_ref: "#/dict/limit" - ``` - will produce the following definition: - ``` - dict - limit: 50 - limit-ref: 50 - ``` - - whereas here we want to access the `nested/path` value. - ``` - nested: - path: "first one" - nested/path: "uh oh" - value: "#/nested/path - ``` - will produce the following definition: - ``` - nested: - path: "first one" - nested/path: "uh oh" - value: "uh oh" - ``` - - to resolve the ambiguity, we try looking for the reference key at the top level, and then traverse the structs downward - until we find a key with the given path, or until there is nothing to traverse. - """ - - def preprocess_manifest(self, manifest: Mapping[str, Any]) -> Mapping[str, Any]: - """ - :param manifest: incoming manifest that could have references to previously defined components - :return: - """ - return self._evaluate_node(manifest, manifest, set()) # type: ignore[no-any-return] - - def _evaluate_node(self, node: Any, manifest: Mapping[str, Any], visited: Set[Any]) -> Any: - if isinstance(node, dict): - evaluated_dict = {k: self._evaluate_node(v, manifest, visited) for k, v in node.items() if not self._is_ref_key(k)} - if REF_TAG in node: - # The node includes a $ref key, so we splat the referenced value(s) into the evaluated dict - evaluated_ref = self._evaluate_node(node[REF_TAG], manifest, visited) - if not isinstance(evaluated_ref, dict): - return evaluated_ref - else: - # The values defined on the component take precedence over the reference values - return evaluated_ref | evaluated_dict - else: - return evaluated_dict - elif isinstance(node, list): - return [self._evaluate_node(v, manifest, visited) for v in node] - elif self._is_ref(node): - if node in visited: - raise CircularReferenceException(node) - visited.add(node) - ret = self._evaluate_node(self._lookup_ref_value(node, manifest), manifest, visited) - visited.remove(node) - return ret - else: - return node - - def _lookup_ref_value(self, ref: str, manifest: Mapping[str, Any]) -> Any: - ref_match = re.match(r"#/(.*)", ref) - if not ref_match: - raise ValueError(f"Invalid reference format {ref}") - try: - path = ref_match.groups()[0] - return self._read_ref_value(path, manifest) - except (AttributeError, KeyError, IndexError): - raise UndefinedReferenceException(path, ref) - - @staticmethod - def _is_ref(node: Any) -> bool: - return isinstance(node, str) and node.startswith("#/") - - @staticmethod - def _is_ref_key(key: str) -> bool: - return bool(key == REF_TAG) - - @staticmethod - def _read_ref_value(ref: str, manifest_node: Mapping[str, Any]) -> Any: - """ - Read the value at the referenced location of the manifest. - - References are ambiguous because one could define a key containing `/` - In this example, we want to refer to the `limit` key in the `dict` object: - dict: - limit: 50 - limit_ref: "#/dict/limit" - - Whereas here we want to access the `nested/path` value. - nested: - path: "first one" - nested/path: "uh oh" - value: "#/nested/path" - - To resolve the ambiguity, we try looking for the reference key at the top level, and then traverse the structs downward - until we find a key with the given path, or until there is nothing to traverse. - - Consider the path foo/bar/baz. To resolve the ambiguity, we first try 'foo/bar/baz' in its entirety as a top-level key. If this - fails, we try 'foo' as the top-level key, and if this succeeds, pass 'bar/baz' on as the key to be tried at the next level. - """ - while ref: - try: - return manifest_node[ref] - except (KeyError, TypeError): - head, ref = _parse_path(ref) - manifest_node = manifest_node[head] # type: ignore # Couldn't figure out how to fix this since manifest_node can get reassigned into other types like lists - return manifest_node - - -def _parse_path(ref: str) -> Tuple[Union[str, int], str]: - """ - Return the next path component, together with the rest of the path. - - A path component may be a string key, or an int index. - - >>> _parse_path("foo/bar") - "foo", "bar" - >>> _parse_path("foo/7/8/bar") - "foo", "7/8/bar" - >>> _parse_path("7/8/bar") - 7, "8/bar" - >>> _parse_path("8/bar") - 8, "bar" - >>> _parse_path("8foo/bar") - "8foo", "bar" - """ - match = re.match(r"([^/]*)/?(.*)", ref) - if match: - first, rest = match.groups() - try: - return int(first), rest - except ValueError: - return first, rest - else: - raise ValueError(f"Invalid path {ref} specified") diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py deleted file mode 100644 index 8d1b2a6d200f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +++ /dev/null @@ -1,1471 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from __future__ import annotations - -import importlib -import inspect -import re -from functools import partial -from typing import Any, Callable, Dict, List, Mapping, Optional, Type, Union, get_args, get_origin, get_type_hints - -from airbyte_cdk.models import FailureType, Level -from airbyte_cdk.sources.declarative.async_job.job_orchestrator import AsyncJobOrchestrator -from airbyte_cdk.sources.declarative.async_job.job_tracker import JobTracker -from airbyte_cdk.sources.declarative.async_job.repository import AsyncJobRepository -from airbyte_cdk.sources.declarative.async_job.status import AsyncJobStatus -from airbyte_cdk.sources.declarative.auth import DeclarativeOauth2Authenticator, JwtAuthenticator -from airbyte_cdk.sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator, NoAuth -from airbyte_cdk.sources.declarative.auth.jwt import JwtAlgorithm -from airbyte_cdk.sources.declarative.auth.oauth import DeclarativeSingleUseRefreshTokenOauth2Authenticator -from airbyte_cdk.sources.declarative.auth.selective_authenticator import SelectiveAuthenticator -from airbyte_cdk.sources.declarative.auth.token import ( - ApiKeyAuthenticator, - BasicHttpAuthenticator, - BearerAuthenticator, - LegacySessionTokenAuthenticator, -) -from airbyte_cdk.sources.declarative.auth.token_provider import InterpolatedStringTokenProvider, SessionTokenProvider, TokenProvider -from airbyte_cdk.sources.declarative.checks import CheckStream -from airbyte_cdk.sources.declarative.concurrency_level import ConcurrencyLevel -from airbyte_cdk.sources.declarative.datetime import MinMaxDatetime -from airbyte_cdk.sources.declarative.declarative_stream import DeclarativeStream -from airbyte_cdk.sources.declarative.decoders import ( - Decoder, - IterableDecoder, - JsonDecoder, - JsonlDecoder, - PaginationDecoderDecorator, - XmlDecoder, -) -from airbyte_cdk.sources.declarative.extractors import DpathExtractor, RecordFilter, RecordSelector, ResponseToFileExtractor -from airbyte_cdk.sources.declarative.extractors.record_filter import ClientSideIncrementalRecordFilterDecorator -from airbyte_cdk.sources.declarative.extractors.record_selector import SCHEMA_TRANSFORMER_TYPE_MAPPING -from airbyte_cdk.sources.declarative.incremental import ( - ChildPartitionResumableFullRefreshCursor, - CursorFactory, - DatetimeBasedCursor, - DeclarativeCursor, - GlobalSubstreamCursor, - PerPartitionCursor, - PerPartitionWithGlobalCursor, - ResumableFullRefreshCursor, -) -from airbyte_cdk.sources.declarative.interpolation import InterpolatedString -from airbyte_cdk.sources.declarative.interpolation.interpolated_mapping import InterpolatedMapping -from airbyte_cdk.sources.declarative.migrations.legacy_to_per_partition_state_migration import LegacyToPerPartitionStateMigration -from airbyte_cdk.sources.declarative.models import CustomStateMigration -from airbyte_cdk.sources.declarative.models.declarative_component_schema import AddedFieldDefinition as AddedFieldDefinitionModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import AddFields as AddFieldsModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import ApiKeyAuthenticator as ApiKeyAuthenticatorModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import AsyncJobStatusMap as AsyncJobStatusMapModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import AsyncRetriever as AsyncRetrieverModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import BasicHttpAuthenticator as BasicHttpAuthenticatorModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import BearerAuthenticator as BearerAuthenticatorModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import CheckStream as CheckStreamModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import CompositeErrorHandler as CompositeErrorHandlerModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import ConcurrencyLevel as ConcurrencyLevelModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import ConstantBackoffStrategy as ConstantBackoffStrategyModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import CursorPagination as CursorPaginationModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import CustomAuthenticator as CustomAuthenticatorModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import CustomBackoffStrategy as CustomBackoffStrategyModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import CustomErrorHandler as CustomErrorHandlerModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import CustomIncrementalSync as CustomIncrementalSyncModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import CustomPaginationStrategy as CustomPaginationStrategyModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import CustomPartitionRouter as CustomPartitionRouterModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import CustomRecordExtractor as CustomRecordExtractorModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import CustomRecordFilter as CustomRecordFilterModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import CustomRequester as CustomRequesterModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import CustomRetriever as CustomRetrieverModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import CustomSchemaLoader as CustomSchemaLoader -from airbyte_cdk.sources.declarative.models.declarative_component_schema import CustomTransformation as CustomTransformationModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import DatetimeBasedCursor as DatetimeBasedCursorModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import DeclarativeStream as DeclarativeStreamModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import DefaultErrorHandler as DefaultErrorHandlerModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import DefaultPaginator as DefaultPaginatorModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import DpathExtractor as DpathExtractorModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import ( - ExponentialBackoffStrategy as ExponentialBackoffStrategyModel, -) -from airbyte_cdk.sources.declarative.models.declarative_component_schema import HttpRequester as HttpRequesterModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import HttpResponseFilter as HttpResponseFilterModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import InlineSchemaLoader as InlineSchemaLoaderModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import IterableDecoder as IterableDecoderModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import JsonDecoder as JsonDecoderModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import JsonFileSchemaLoader as JsonFileSchemaLoaderModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import JsonlDecoder as JsonlDecoderModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import JwtAuthenticator as JwtAuthenticatorModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import JwtHeaders as JwtHeadersModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import JwtPayload as JwtPayloadModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import KeysToLower as KeysToLowerModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import ( - LegacySessionTokenAuthenticator as LegacySessionTokenAuthenticatorModel, -) -from airbyte_cdk.sources.declarative.models.declarative_component_schema import ( - LegacyToPerPartitionStateMigration as LegacyToPerPartitionStateMigrationModel, -) -from airbyte_cdk.sources.declarative.models.declarative_component_schema import ListPartitionRouter as ListPartitionRouterModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import MinMaxDatetime as MinMaxDatetimeModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import NoAuth as NoAuthModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import NoPagination as NoPaginationModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import OAuthAuthenticator as OAuthAuthenticatorModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import OffsetIncrement as OffsetIncrementModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import PageIncrement as PageIncrementModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import ParentStreamConfig as ParentStreamConfigModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import RecordFilter as RecordFilterModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import RecordSelector as RecordSelectorModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import RemoveFields as RemoveFieldsModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import RequestOption as RequestOptionModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import RequestPath as RequestPathModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import SelectiveAuthenticator as SelectiveAuthenticatorModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import SessionTokenAuthenticator as SessionTokenAuthenticatorModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import SimpleRetriever as SimpleRetrieverModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import Spec as SpecModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import SubstreamPartitionRouter as SubstreamPartitionRouterModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import ValueType -from airbyte_cdk.sources.declarative.models.declarative_component_schema import WaitTimeFromHeader as WaitTimeFromHeaderModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import WaitUntilTimeFromHeader as WaitUntilTimeFromHeaderModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import XmlDecoder as XmlDecoderModel -from airbyte_cdk.sources.declarative.partition_routers import ( - CartesianProductStreamSlicer, - ListPartitionRouter, - SinglePartitionRouter, - SubstreamPartitionRouter, -) -from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig -from airbyte_cdk.sources.declarative.requesters import HttpRequester, RequestOption -from airbyte_cdk.sources.declarative.requesters.error_handlers import CompositeErrorHandler, DefaultErrorHandler, HttpResponseFilter -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies import ( - ConstantBackoffStrategy, - ExponentialBackoffStrategy, - WaitTimeFromHeaderBackoffStrategy, - WaitUntilTimeFromHeaderBackoffStrategy, -) -from airbyte_cdk.sources.declarative.requesters.http_job_repository import AsyncHttpJobRepository -from airbyte_cdk.sources.declarative.requesters.paginators import DefaultPaginator, NoPagination, PaginatorTestReadDecorator -from airbyte_cdk.sources.declarative.requesters.paginators.strategies import ( - CursorPaginationStrategy, - CursorStopCondition, - OffsetIncrement, - PageIncrement, - StopConditionPaginationStrategyDecorator, -) -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOptionType -from airbyte_cdk.sources.declarative.requesters.request_options import ( - DatetimeBasedRequestOptionsProvider, - DefaultRequestOptionsProvider, - InterpolatedRequestOptionsProvider, - RequestOptionsProvider, -) -from airbyte_cdk.sources.declarative.requesters.request_path import RequestPath -from airbyte_cdk.sources.declarative.requesters.requester import HttpMethod -from airbyte_cdk.sources.declarative.retrievers import AsyncRetriever, SimpleRetriever, SimpleRetrieverTestReadDecorator -from airbyte_cdk.sources.declarative.schema import DefaultSchemaLoader, InlineSchemaLoader, JsonFileSchemaLoader -from airbyte_cdk.sources.declarative.spec import Spec -from airbyte_cdk.sources.declarative.stream_slicers import StreamSlicer -from airbyte_cdk.sources.declarative.transformations import AddFields, RecordTransformation, RemoveFields -from airbyte_cdk.sources.declarative.transformations.add_fields import AddedFieldDefinition -from airbyte_cdk.sources.declarative.transformations.keys_to_lower_transformation import KeysToLowerTransformation -from airbyte_cdk.sources.message import InMemoryMessageRepository, LogAppenderMessageRepositoryDecorator, MessageRepository -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ResponseAction -from airbyte_cdk.sources.types import Config -from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer -from isodate import parse_duration -from pydantic.v1 import BaseModel - -ComponentDefinition = Mapping[str, Any] - - -class ModelToComponentFactory: - def __init__( - self, - limit_pages_fetched_per_slice: Optional[int] = None, - limit_slices_fetched: Optional[int] = None, - emit_connector_builder_messages: bool = False, - disable_retries: bool = False, - disable_cache: bool = False, - message_repository: Optional[MessageRepository] = None, - ): - self._init_mappings() - self._limit_pages_fetched_per_slice = limit_pages_fetched_per_slice - self._limit_slices_fetched = limit_slices_fetched - self._emit_connector_builder_messages = emit_connector_builder_messages - self._disable_retries = disable_retries - self._disable_cache = disable_cache - self._message_repository = message_repository or InMemoryMessageRepository( # type: ignore - self._evaluate_log_level(emit_connector_builder_messages) - ) - - def _init_mappings(self) -> None: - self.PYDANTIC_MODEL_TO_CONSTRUCTOR: Mapping[Type[BaseModel], Callable[..., Any]] = { - AddedFieldDefinitionModel: self.create_added_field_definition, - AddFieldsModel: self.create_add_fields, - ApiKeyAuthenticatorModel: self.create_api_key_authenticator, - BasicHttpAuthenticatorModel: self.create_basic_http_authenticator, - BearerAuthenticatorModel: self.create_bearer_authenticator, - CheckStreamModel: self.create_check_stream, - CompositeErrorHandlerModel: self.create_composite_error_handler, - ConcurrencyLevelModel: self.create_concurrency_level, - ConstantBackoffStrategyModel: self.create_constant_backoff_strategy, - CursorPaginationModel: self.create_cursor_pagination, - CustomAuthenticatorModel: self.create_custom_component, - CustomBackoffStrategyModel: self.create_custom_component, - CustomErrorHandlerModel: self.create_custom_component, - CustomIncrementalSyncModel: self.create_custom_component, - CustomRecordExtractorModel: self.create_custom_component, - CustomRecordFilterModel: self.create_custom_component, - CustomRequesterModel: self.create_custom_component, - CustomRetrieverModel: self.create_custom_component, - CustomSchemaLoader: self.create_custom_component, - CustomStateMigration: self.create_custom_component, - CustomPaginationStrategyModel: self.create_custom_component, - CustomPartitionRouterModel: self.create_custom_component, - CustomTransformationModel: self.create_custom_component, - DatetimeBasedCursorModel: self.create_datetime_based_cursor, - DeclarativeStreamModel: self.create_declarative_stream, - DefaultErrorHandlerModel: self.create_default_error_handler, - DefaultPaginatorModel: self.create_default_paginator, - DpathExtractorModel: self.create_dpath_extractor, - ExponentialBackoffStrategyModel: self.create_exponential_backoff_strategy, - SessionTokenAuthenticatorModel: self.create_session_token_authenticator, - HttpRequesterModel: self.create_http_requester, - HttpResponseFilterModel: self.create_http_response_filter, - InlineSchemaLoaderModel: self.create_inline_schema_loader, - JsonDecoderModel: self.create_json_decoder, - JsonlDecoderModel: self.create_jsonl_decoder, - KeysToLowerModel: self.create_keys_to_lower_transformation, - IterableDecoderModel: self.create_iterable_decoder, - XmlDecoderModel: self.create_xml_decoder, - JsonFileSchemaLoaderModel: self.create_json_file_schema_loader, - JwtAuthenticatorModel: self.create_jwt_authenticator, - LegacyToPerPartitionStateMigrationModel: self.create_legacy_to_per_partition_state_migration, - ListPartitionRouterModel: self.create_list_partition_router, - MinMaxDatetimeModel: self.create_min_max_datetime, - NoAuthModel: self.create_no_auth, - NoPaginationModel: self.create_no_pagination, - OAuthAuthenticatorModel: self.create_oauth_authenticator, - OffsetIncrementModel: self.create_offset_increment, - PageIncrementModel: self.create_page_increment, - ParentStreamConfigModel: self.create_parent_stream_config, - RecordFilterModel: self.create_record_filter, - RecordSelectorModel: self.create_record_selector, - RemoveFieldsModel: self.create_remove_fields, - RequestPathModel: self.create_request_path, - RequestOptionModel: self.create_request_option, - LegacySessionTokenAuthenticatorModel: self.create_legacy_session_token_authenticator, - SelectiveAuthenticatorModel: self.create_selective_authenticator, - SimpleRetrieverModel: self.create_simple_retriever, - SpecModel: self.create_spec, - SubstreamPartitionRouterModel: self.create_substream_partition_router, - WaitTimeFromHeaderModel: self.create_wait_time_from_header, - WaitUntilTimeFromHeaderModel: self.create_wait_until_time_from_header, - AsyncRetrieverModel: self.create_async_retriever, - } - - # Needed for the case where we need to perform a second parse on the fields of a custom component - self.TYPE_NAME_TO_MODEL = {cls.__name__: cls for cls in self.PYDANTIC_MODEL_TO_CONSTRUCTOR} - - def create_component( - self, model_type: Type[BaseModel], component_definition: ComponentDefinition, config: Config, **kwargs: Any - ) -> Any: - """ - Takes a given Pydantic model type and Mapping representing a component definition and creates a declarative component and - subcomponents which will be used at runtime. This is done by first parsing the mapping into a Pydantic model and then creating - creating declarative components from that model. - - :param model_type: The type of declarative component that is being initialized - :param component_definition: The mapping that represents a declarative component - :param config: The connector config that is provided by the customer - :return: The declarative component to be used at runtime - """ - - component_type = component_definition.get("type") - if component_definition.get("type") != model_type.__name__: - raise ValueError(f"Expected manifest component of type {model_type.__name__}, but received {component_type} instead") - - declarative_component_model = model_type.parse_obj(component_definition) - - if not isinstance(declarative_component_model, model_type): - raise ValueError(f"Expected {model_type.__name__} component, but received {declarative_component_model.__class__.__name__}") - - return self._create_component_from_model(model=declarative_component_model, config=config, **kwargs) - - def _create_component_from_model(self, model: BaseModel, config: Config, **kwargs: Any) -> Any: - if model.__class__ not in self.PYDANTIC_MODEL_TO_CONSTRUCTOR: - raise ValueError(f"{model.__class__} with attributes {model} is not a valid component type") - component_constructor = self.PYDANTIC_MODEL_TO_CONSTRUCTOR.get(model.__class__) - if not component_constructor: - raise ValueError(f"Could not find constructor for {model.__class__}") - return component_constructor(model=model, config=config, **kwargs) - - @staticmethod - def create_added_field_definition(model: AddedFieldDefinitionModel, config: Config, **kwargs: Any) -> AddedFieldDefinition: - interpolated_value = InterpolatedString.create(model.value, parameters=model.parameters or {}) - return AddedFieldDefinition( - path=model.path, - value=interpolated_value, - value_type=ModelToComponentFactory._json_schema_type_name_to_type(model.value_type), - parameters=model.parameters or {}, - ) - - def create_add_fields(self, model: AddFieldsModel, config: Config, **kwargs: Any) -> AddFields: - added_field_definitions = [ - self._create_component_from_model( - model=added_field_definition_model, - value_type=ModelToComponentFactory._json_schema_type_name_to_type(added_field_definition_model.value_type), - config=config, - ) - for added_field_definition_model in model.fields - ] - return AddFields(fields=added_field_definitions, parameters=model.parameters or {}) - - def create_keys_to_lower_transformation(self, model: KeysToLowerModel, config: Config, **kwargs: Any) -> KeysToLowerTransformation: - return KeysToLowerTransformation() - - @staticmethod - def _json_schema_type_name_to_type(value_type: Optional[ValueType]) -> Optional[Type[Any]]: - if not value_type: - return None - names_to_types = { - ValueType.string: str, - ValueType.number: float, - ValueType.integer: int, - ValueType.boolean: bool, - } - return names_to_types[value_type] - - @staticmethod - def create_api_key_authenticator( - model: ApiKeyAuthenticatorModel, config: Config, token_provider: Optional[TokenProvider] = None, **kwargs: Any - ) -> ApiKeyAuthenticator: - if model.inject_into is None and model.header is None: - raise ValueError("Expected either inject_into or header to be set for ApiKeyAuthenticator") - - if model.inject_into is not None and model.header is not None: - raise ValueError("inject_into and header cannot be set both for ApiKeyAuthenticator - remove the deprecated header option") - - if token_provider is not None and model.api_token != "": - raise ValueError("If token_provider is set, api_token is ignored and has to be set to empty string.") - - request_option = ( - RequestOption( - inject_into=RequestOptionType(model.inject_into.inject_into.value), - field_name=model.inject_into.field_name, - parameters=model.parameters or {}, - ) - if model.inject_into - else RequestOption( - inject_into=RequestOptionType.header, - field_name=model.header or "", - parameters=model.parameters or {}, - ) - ) - return ApiKeyAuthenticator( - token_provider=( - token_provider - if token_provider is not None - else InterpolatedStringTokenProvider(api_token=model.api_token or "", config=config, parameters=model.parameters or {}) - ), - request_option=request_option, - config=config, - parameters=model.parameters or {}, - ) - - def create_legacy_to_per_partition_state_migration( - self, - model: LegacyToPerPartitionStateMigrationModel, - config: Mapping[str, Any], - declarative_stream: DeclarativeStreamModel, - ) -> LegacyToPerPartitionStateMigration: - retriever = declarative_stream.retriever - if not isinstance(retriever, SimpleRetrieverModel): - raise ValueError( - f"LegacyToPerPartitionStateMigrations can only be applied on a DeclarativeStream with a SimpleRetriever. Got {type(retriever)}" - ) - partition_router = retriever.partition_router - if not isinstance(partition_router, (SubstreamPartitionRouterModel, CustomPartitionRouterModel)): - raise ValueError( - f"LegacyToPerPartitionStateMigrations can only be applied on a SimpleRetriever with a Substream partition router. Got {type(partition_router)}" - ) - if not hasattr(partition_router, "parent_stream_configs"): - raise ValueError("LegacyToPerPartitionStateMigrations can only be applied with a parent stream configuration.") - - return LegacyToPerPartitionStateMigration(declarative_stream.retriever.partition_router, declarative_stream.incremental_sync, config, declarative_stream.parameters) # type: ignore # The retriever type was already checked - - def create_session_token_authenticator( - self, model: SessionTokenAuthenticatorModel, config: Config, name: str, **kwargs: Any - ) -> Union[ApiKeyAuthenticator, BearerAuthenticator]: - decoder = self._create_component_from_model(model=model.decoder, config=config) if model.decoder else JsonDecoder(parameters={}) - login_requester = self._create_component_from_model( - model=model.login_requester, config=config, name=f"{name}_login_requester", decoder=decoder - ) - token_provider = SessionTokenProvider( - login_requester=login_requester, - session_token_path=model.session_token_path, - expiration_duration=parse_duration(model.expiration_duration) if model.expiration_duration else None, - parameters=model.parameters or {}, - message_repository=self._message_repository, - decoder=decoder, - ) - if model.request_authentication.type == "Bearer": - return ModelToComponentFactory.create_bearer_authenticator( - BearerAuthenticatorModel(type="BearerAuthenticator", api_token=""), # type: ignore # $parameters has a default value - config, - token_provider=token_provider, # type: ignore # $parameters defaults to None - ) - else: - return ModelToComponentFactory.create_api_key_authenticator( - ApiKeyAuthenticatorModel(type="ApiKeyAuthenticator", api_token="", inject_into=model.request_authentication.inject_into), # type: ignore # $parameters and headers default to None - config=config, - token_provider=token_provider, - ) - - @staticmethod - def create_basic_http_authenticator(model: BasicHttpAuthenticatorModel, config: Config, **kwargs: Any) -> BasicHttpAuthenticator: - return BasicHttpAuthenticator( - password=model.password or "", username=model.username, config=config, parameters=model.parameters or {} - ) - - @staticmethod - def create_bearer_authenticator( - model: BearerAuthenticatorModel, config: Config, token_provider: Optional[TokenProvider] = None, **kwargs: Any - ) -> BearerAuthenticator: - if token_provider is not None and model.api_token != "": - raise ValueError("If token_provider is set, api_token is ignored and has to be set to empty string.") - return BearerAuthenticator( - token_provider=( - token_provider - if token_provider is not None - else InterpolatedStringTokenProvider(api_token=model.api_token or "", config=config, parameters=model.parameters or {}) - ), - config=config, - parameters=model.parameters or {}, - ) - - @staticmethod - def create_check_stream(model: CheckStreamModel, config: Config, **kwargs: Any) -> CheckStream: - return CheckStream(stream_names=model.stream_names, parameters={}) - - def create_composite_error_handler(self, model: CompositeErrorHandlerModel, config: Config, **kwargs: Any) -> CompositeErrorHandler: - error_handlers = [ - self._create_component_from_model(model=error_handler_model, config=config) for error_handler_model in model.error_handlers - ] - return CompositeErrorHandler(error_handlers=error_handlers, parameters=model.parameters or {}) - - @staticmethod - def create_concurrency_level(model: ConcurrencyLevelModel, config: Config, **kwargs: Any) -> ConcurrencyLevel: - return ConcurrencyLevel( - default_concurrency=model.default_concurrency, - max_concurrency=model.max_concurrency, - config=config, - parameters={}, - ) - - @staticmethod - def create_constant_backoff_strategy(model: ConstantBackoffStrategyModel, config: Config, **kwargs: Any) -> ConstantBackoffStrategy: - return ConstantBackoffStrategy( - backoff_time_in_seconds=model.backoff_time_in_seconds, - config=config, - parameters=model.parameters or {}, - ) - - def create_cursor_pagination( - self, model: CursorPaginationModel, config: Config, decoder: Decoder, **kwargs: Any - ) -> CursorPaginationStrategy: - if isinstance(decoder, PaginationDecoderDecorator): - if not isinstance(decoder.decoder, (JsonDecoder, XmlDecoder)): - raise ValueError( - f"Provided decoder of {type(decoder.decoder)=} is not supported. Please set JsonDecoder or XmlDecoder instead." - ) - decoder_to_use = decoder - else: - if not isinstance(decoder, (JsonDecoder, XmlDecoder)): - raise ValueError(f"Provided decoder of {type(decoder)=} is not supported. Please set JsonDecoder or XmlDecoder instead.") - decoder_to_use = PaginationDecoderDecorator(decoder=decoder) - - return CursorPaginationStrategy( - cursor_value=model.cursor_value, - decoder=decoder_to_use, - page_size=model.page_size, - stop_condition=model.stop_condition, - config=config, - parameters=model.parameters or {}, - ) - - def create_custom_component(self, model: Any, config: Config, **kwargs: Any) -> Any: - """ - Generically creates a custom component based on the model type and a class_name reference to the custom Python class being - instantiated. Only the model's additional properties that match the custom class definition are passed to the constructor - :param model: The Pydantic model of the custom component being created - :param config: The custom defined connector config - :return: The declarative component built from the Pydantic model to be used at runtime - """ - - custom_component_class = self._get_class_from_fully_qualified_class_name(model.class_name) - component_fields = get_type_hints(custom_component_class) - model_args = model.dict() - model_args["config"] = config - - # There are cases where a parent component will pass arguments to a child component via kwargs. When there are field collisions - # we defer to these arguments over the component's definition - for key, arg in kwargs.items(): - model_args[key] = arg - - # Pydantic is unable to parse a custom component's fields that are subcomponents into models because their fields and types are not - # defined in the schema. The fields and types are defined within the Python class implementation. Pydantic can only parse down to - # the custom component and this code performs a second parse to convert the sub-fields first into models, then declarative components - for model_field, model_value in model_args.items(): - # If a custom component field doesn't have a type set, we try to use the type hints to infer the type - if isinstance(model_value, dict) and "type" not in model_value and model_field in component_fields: - derived_type = self._derive_component_type_from_type_hints(component_fields.get(model_field)) - if derived_type: - model_value["type"] = derived_type - - if self._is_component(model_value): - model_args[model_field] = self._create_nested_component(model, model_field, model_value, config) - elif isinstance(model_value, list): - vals = [] - for v in model_value: - if isinstance(v, dict) and "type" not in v and model_field in component_fields: - derived_type = self._derive_component_type_from_type_hints(component_fields.get(model_field)) - if derived_type: - v["type"] = derived_type - if self._is_component(v): - vals.append(self._create_nested_component(model, model_field, v, config)) - else: - vals.append(v) - model_args[model_field] = vals - - kwargs = {class_field: model_args[class_field] for class_field in component_fields.keys() if class_field in model_args} - return custom_component_class(**kwargs) - - @staticmethod - def _get_class_from_fully_qualified_class_name(full_qualified_class_name: str) -> Any: - split = full_qualified_class_name.split(".") - module = ".".join(split[:-1]) - class_name = split[-1] - try: - return getattr(importlib.import_module(module), class_name) - except AttributeError: - raise ValueError(f"Could not load class {full_qualified_class_name}.") - - @staticmethod - def _derive_component_type_from_type_hints(field_type: Any) -> Optional[str]: - interface = field_type - while True: - origin = get_origin(interface) - if origin: - # Unnest types until we reach the raw type - # List[T] -> T - # Optional[List[T]] -> T - args = get_args(interface) - interface = args[0] - else: - break - if isinstance(interface, type) and not ModelToComponentFactory.is_builtin_type(interface): - return interface.__name__ - return None - - @staticmethod - def is_builtin_type(cls: Optional[Type[Any]]) -> bool: - if not cls: - return False - return cls.__module__ == "builtins" - - @staticmethod - def _extract_missing_parameters(error: TypeError) -> List[str]: - parameter_search = re.search(r"keyword-only.*:\s(.*)", str(error)) - if parameter_search: - return re.findall(r"\'(.+?)\'", parameter_search.group(1)) - else: - return [] - - def _create_nested_component(self, model: Any, model_field: str, model_value: Any, config: Config) -> Any: - type_name = model_value.get("type", None) - if not type_name: - # If no type is specified, we can assume this is a dictionary object which can be returned instead of a subcomponent - return model_value - - model_type = self.TYPE_NAME_TO_MODEL.get(type_name, None) - if model_type: - parsed_model = model_type.parse_obj(model_value) - try: - # To improve usability of the language, certain fields are shared between components. This can come in the form of - # a parent component passing some of its fields to a child component or the parent extracting fields from other child - # components and passing it to others. One example is the DefaultPaginator referencing the HttpRequester url_base - # while constructing a SimpleRetriever. However, custom components don't support this behavior because they are created - # generically in create_custom_component(). This block allows developers to specify extra arguments in $parameters that - # are needed by a component and could not be shared. - model_constructor = self.PYDANTIC_MODEL_TO_CONSTRUCTOR.get(parsed_model.__class__) - constructor_kwargs = inspect.getfullargspec(model_constructor).kwonlyargs - model_parameters = model_value.get("$parameters", {}) - matching_parameters = {kwarg: model_parameters[kwarg] for kwarg in constructor_kwargs if kwarg in model_parameters} - return self._create_component_from_model(model=parsed_model, config=config, **matching_parameters) - except TypeError as error: - missing_parameters = self._extract_missing_parameters(error) - if missing_parameters: - raise ValueError( - f"Error creating component '{type_name}' with parent custom component {model.class_name}: Please provide " - + ", ".join((f"{type_name}.$parameters.{parameter}" for parameter in missing_parameters)) - ) - raise TypeError(f"Error creating component '{type_name}' with parent custom component {model.class_name}: {error}") - else: - raise ValueError( - f"Error creating custom component {model.class_name}. Subcomponent creation has not been implemented for '{type_name}'" - ) - - @staticmethod - def _is_component(model_value: Any) -> bool: - return isinstance(model_value, dict) and model_value.get("type") is not None - - def create_datetime_based_cursor(self, model: DatetimeBasedCursorModel, config: Config, **kwargs: Any) -> DatetimeBasedCursor: - start_datetime: Union[str, MinMaxDatetime] = ( - model.start_datetime if isinstance(model.start_datetime, str) else self.create_min_max_datetime(model.start_datetime, config) - ) - end_datetime: Union[str, MinMaxDatetime, None] = None - if model.is_data_feed and model.end_datetime: - raise ValueError("Data feed does not support end_datetime") - if model.is_data_feed and model.is_client_side_incremental: - raise ValueError("`Client side incremental` cannot be applied with `data feed`. Choose only 1 from them.") - if model.end_datetime: - end_datetime = ( - model.end_datetime if isinstance(model.end_datetime, str) else self.create_min_max_datetime(model.end_datetime, config) - ) - - end_time_option = ( - RequestOption( - inject_into=RequestOptionType(model.end_time_option.inject_into.value), - field_name=model.end_time_option.field_name, - parameters=model.parameters or {}, - ) - if model.end_time_option - else None - ) - start_time_option = ( - RequestOption( - inject_into=RequestOptionType(model.start_time_option.inject_into.value), - field_name=model.start_time_option.field_name, - parameters=model.parameters or {}, - ) - if model.start_time_option - else None - ) - - return DatetimeBasedCursor( - cursor_field=model.cursor_field, - cursor_datetime_formats=model.cursor_datetime_formats if model.cursor_datetime_formats else [], - cursor_granularity=model.cursor_granularity, - datetime_format=model.datetime_format, - end_datetime=end_datetime, - start_datetime=start_datetime, - step=model.step, - end_time_option=end_time_option, - lookback_window=model.lookback_window, - start_time_option=start_time_option, - partition_field_end=model.partition_field_end, - partition_field_start=model.partition_field_start, - message_repository=self._message_repository, - is_compare_strictly=model.is_compare_strictly, - config=config, - parameters=model.parameters or {}, - ) - - def create_declarative_stream(self, model: DeclarativeStreamModel, config: Config, **kwargs: Any) -> DeclarativeStream: - # When constructing a declarative stream, we assemble the incremental_sync component and retriever's partition_router field - # components if they exist into a single CartesianProductStreamSlicer. This is then passed back as an argument when constructing the - # Retriever. This is done in the declarative stream not the retriever to support custom retrievers. The custom create methods in - # the factory only support passing arguments to the component constructors, whereas this performs a merge of all slicers into one. - combined_slicers = self._merge_stream_slicers(model=model, config=config) - - primary_key = model.primary_key.__root__ if model.primary_key else None - stop_condition_on_cursor = ( - model.incremental_sync and hasattr(model.incremental_sync, "is_data_feed") and model.incremental_sync.is_data_feed - ) - client_side_incremental_sync = None - if ( - model.incremental_sync - and hasattr(model.incremental_sync, "is_client_side_incremental") - and model.incremental_sync.is_client_side_incremental - ): - supported_slicers = (DatetimeBasedCursor, GlobalSubstreamCursor, PerPartitionWithGlobalCursor) - if combined_slicers and not isinstance(combined_slicers, supported_slicers): - raise ValueError("Unsupported Slicer is used. PerPartitionWithGlobalCursor should be used here instead") - client_side_incremental_sync = { - "date_time_based_cursor": self._create_component_from_model(model=model.incremental_sync, config=config), - "substream_cursor": ( - combined_slicers if isinstance(combined_slicers, (PerPartitionWithGlobalCursor, GlobalSubstreamCursor)) else None - ), - } - - if model.incremental_sync and isinstance(model.incremental_sync, DatetimeBasedCursorModel): - cursor_model = model.incremental_sync - - end_time_option = ( - RequestOption( - inject_into=RequestOptionType(cursor_model.end_time_option.inject_into.value), - field_name=cursor_model.end_time_option.field_name, - parameters=cursor_model.parameters or {}, - ) - if cursor_model.end_time_option - else None - ) - start_time_option = ( - RequestOption( - inject_into=RequestOptionType(cursor_model.start_time_option.inject_into.value), - field_name=cursor_model.start_time_option.field_name, - parameters=cursor_model.parameters or {}, - ) - if cursor_model.start_time_option - else None - ) - - request_options_provider = DatetimeBasedRequestOptionsProvider( - start_time_option=start_time_option, - end_time_option=end_time_option, - partition_field_start=cursor_model.partition_field_end, - partition_field_end=cursor_model.partition_field_end, - config=config, - parameters=model.parameters or {}, - ) - else: - request_options_provider = None - - transformations = [] - if model.transformations: - for transformation_model in model.transformations: - transformations.append(self._create_component_from_model(model=transformation_model, config=config)) - retriever = self._create_component_from_model( - model=model.retriever, - config=config, - name=model.name, - primary_key=primary_key, - stream_slicer=combined_slicers, - request_options_provider=request_options_provider, - stop_condition_on_cursor=stop_condition_on_cursor, - client_side_incremental_sync=client_side_incremental_sync, - transformations=transformations, - ) - cursor_field = model.incremental_sync.cursor_field if model.incremental_sync else None - - if model.state_migrations: - state_transformations = [ - self._create_component_from_model(state_migration, config, declarative_stream=model) - for state_migration in model.state_migrations - ] - else: - state_transformations = [] - - if model.schema_loader: - schema_loader = self._create_component_from_model(model=model.schema_loader, config=config) - else: - options = model.parameters or {} - if "name" not in options: - options["name"] = model.name - schema_loader = DefaultSchemaLoader(config=config, parameters=options) - - return DeclarativeStream( - name=model.name or "", - primary_key=primary_key, - retriever=retriever, - schema_loader=schema_loader, - stream_cursor_field=cursor_field or "", - state_migrations=state_transformations, - config=config, - parameters=model.parameters or {}, - ) - - def _merge_stream_slicers(self, model: DeclarativeStreamModel, config: Config) -> Optional[StreamSlicer]: - stream_slicer = None - if ( - hasattr(model.retriever, "partition_router") - and isinstance(model.retriever, SimpleRetrieverModel) - and model.retriever.partition_router - ): - stream_slicer_model = model.retriever.partition_router - - if isinstance(stream_slicer_model, list): - stream_slicer = CartesianProductStreamSlicer( - [self._create_component_from_model(model=slicer, config=config) for slicer in stream_slicer_model], parameters={} - ) - else: - stream_slicer = self._create_component_from_model(model=stream_slicer_model, config=config) - - if model.incremental_sync and stream_slicer: - incremental_sync_model = model.incremental_sync - if hasattr(incremental_sync_model, "global_substream_cursor") and incremental_sync_model.global_substream_cursor: - cursor_component = self._create_component_from_model(model=incremental_sync_model, config=config) - return GlobalSubstreamCursor(stream_cursor=cursor_component, partition_router=stream_slicer) - else: - cursor_component = self._create_component_from_model(model=incremental_sync_model, config=config) - return PerPartitionWithGlobalCursor( - cursor_factory=CursorFactory( - lambda: self._create_component_from_model(model=incremental_sync_model, config=config), - ), - partition_router=stream_slicer, - stream_cursor=cursor_component, - ) - elif model.incremental_sync: - return self._create_component_from_model(model=model.incremental_sync, config=config) if model.incremental_sync else None - elif stream_slicer: - # For the Full-Refresh sub-streams, we use the nested `ChildPartitionResumableFullRefreshCursor` - return PerPartitionCursor( - cursor_factory=CursorFactory(create_function=partial(ChildPartitionResumableFullRefreshCursor, {})), - partition_router=stream_slicer, - ) - elif hasattr(model.retriever, "paginator") and model.retriever.paginator and not stream_slicer: - # For the regular Full-Refresh streams, we use the high level `ResumableFullRefreshCursor` - return ResumableFullRefreshCursor(parameters={}) - else: - return None - - def create_default_error_handler(self, model: DefaultErrorHandlerModel, config: Config, **kwargs: Any) -> DefaultErrorHandler: - backoff_strategies = [] - if model.backoff_strategies: - for backoff_strategy_model in model.backoff_strategies: - backoff_strategies.append(self._create_component_from_model(model=backoff_strategy_model, config=config)) - - response_filters = [] - if model.response_filters: - for response_filter_model in model.response_filters: - response_filters.append(self._create_component_from_model(model=response_filter_model, config=config)) - response_filters.append(HttpResponseFilter(config=config, parameters=model.parameters or {})) - - return DefaultErrorHandler( - backoff_strategies=backoff_strategies, - max_retries=model.max_retries, - response_filters=response_filters, - config=config, - parameters=model.parameters or {}, - ) - - def create_default_paginator( - self, - model: DefaultPaginatorModel, - config: Config, - *, - url_base: str, - decoder: Optional[Decoder] = None, - cursor_used_for_stop_condition: Optional[DeclarativeCursor] = None, - ) -> Union[DefaultPaginator, PaginatorTestReadDecorator]: - if decoder: - if not isinstance(decoder, (JsonDecoder, XmlDecoder)): - raise ValueError(f"Provided decoder of {type(decoder)=} is not supported. Please set JsonDecoder or XmlDecoder instead.") - decoder_to_use = PaginationDecoderDecorator(decoder=decoder) - else: - decoder_to_use = PaginationDecoderDecorator(decoder=JsonDecoder(parameters={})) - page_size_option = ( - self._create_component_from_model(model=model.page_size_option, config=config) if model.page_size_option else None - ) - page_token_option = ( - self._create_component_from_model(model=model.page_token_option, config=config) if model.page_token_option else None - ) - pagination_strategy = self._create_component_from_model(model=model.pagination_strategy, config=config, decoder=decoder_to_use) - if cursor_used_for_stop_condition: - pagination_strategy = StopConditionPaginationStrategyDecorator( - pagination_strategy, CursorStopCondition(cursor_used_for_stop_condition) - ) - paginator = DefaultPaginator( - decoder=decoder_to_use, - page_size_option=page_size_option, - page_token_option=page_token_option, - pagination_strategy=pagination_strategy, - url_base=url_base, - config=config, - parameters=model.parameters or {}, - ) - if self._limit_pages_fetched_per_slice: - return PaginatorTestReadDecorator(paginator, self._limit_pages_fetched_per_slice) - return paginator - - def create_dpath_extractor( - self, model: DpathExtractorModel, config: Config, decoder: Optional[Decoder] = None, **kwargs: Any - ) -> DpathExtractor: - if decoder: - decoder_to_use = decoder - else: - decoder_to_use = JsonDecoder(parameters={}) - model_field_path: List[Union[InterpolatedString, str]] = [x for x in model.field_path] - return DpathExtractor(decoder=decoder_to_use, field_path=model_field_path, config=config, parameters=model.parameters or {}) - - @staticmethod - def create_exponential_backoff_strategy(model: ExponentialBackoffStrategyModel, config: Config) -> ExponentialBackoffStrategy: - return ExponentialBackoffStrategy(factor=model.factor or 5, parameters=model.parameters or {}, config=config) - - def create_http_requester(self, model: HttpRequesterModel, decoder: Decoder, config: Config, *, name: str) -> HttpRequester: - authenticator = ( - self._create_component_from_model(model=model.authenticator, config=config, url_base=model.url_base, name=name, decoder=decoder) - if model.authenticator - else None - ) - error_handler = ( - self._create_component_from_model(model=model.error_handler, config=config) - if model.error_handler - else DefaultErrorHandler(backoff_strategies=[], response_filters=[], config=config, parameters=model.parameters or {}) - ) - - request_options_provider = InterpolatedRequestOptionsProvider( - request_body_data=model.request_body_data, - request_body_json=model.request_body_json, - request_headers=model.request_headers, - request_parameters=model.request_parameters, - config=config, - parameters=model.parameters or {}, - ) - - assert model.use_cache is not None # for mypy - assert model.http_method is not None # for mypy - - use_cache = model.use_cache and not self._disable_cache - - return HttpRequester( - name=name, - url_base=model.url_base, - path=model.path, - authenticator=authenticator, - error_handler=error_handler, - http_method=HttpMethod[model.http_method.value], - request_options_provider=request_options_provider, - config=config, - disable_retries=self._disable_retries, - parameters=model.parameters or {}, - message_repository=self._message_repository, - use_cache=use_cache, - decoder=decoder, - stream_response=decoder.is_stream_response() if decoder else False, - ) - - @staticmethod - def create_http_response_filter(model: HttpResponseFilterModel, config: Config, **kwargs: Any) -> HttpResponseFilter: - if model.action: - action = ResponseAction(model.action.value) - else: - action = None - - failure_type = FailureType(model.failure_type.value) if model.failure_type else None - - http_codes = ( - set(model.http_codes) if model.http_codes else set() - ) # JSON schema notation has no set data type. The schema enforces an array of unique elements - - return HttpResponseFilter( - action=action, - failure_type=failure_type, - error_message=model.error_message or "", - error_message_contains=model.error_message_contains or "", - http_codes=http_codes, - predicate=model.predicate or "", - config=config, - parameters=model.parameters or {}, - ) - - @staticmethod - def create_inline_schema_loader(model: InlineSchemaLoaderModel, config: Config, **kwargs: Any) -> InlineSchemaLoader: - return InlineSchemaLoader(schema=model.schema_ or {}, parameters={}) - - @staticmethod - def create_json_decoder(model: JsonDecoderModel, config: Config, **kwargs: Any) -> JsonDecoder: - return JsonDecoder(parameters={}) - - @staticmethod - def create_jsonl_decoder(model: JsonlDecoderModel, config: Config, **kwargs: Any) -> JsonlDecoder: - return JsonlDecoder(parameters={}) - - @staticmethod - def create_iterable_decoder(model: IterableDecoderModel, config: Config, **kwargs: Any) -> IterableDecoder: - return IterableDecoder(parameters={}) - - @staticmethod - def create_xml_decoder(model: XmlDecoderModel, config: Config, **kwargs: Any) -> XmlDecoder: - return XmlDecoder(parameters={}) - - @staticmethod - def create_json_file_schema_loader(model: JsonFileSchemaLoaderModel, config: Config, **kwargs: Any) -> JsonFileSchemaLoader: - return JsonFileSchemaLoader(file_path=model.file_path or "", config=config, parameters=model.parameters or {}) - - @staticmethod - def create_jwt_authenticator(model: JwtAuthenticatorModel, config: Config, **kwargs: Any) -> JwtAuthenticator: - jwt_headers = model.jwt_headers or JwtHeadersModel(kid=None, typ="JWT", cty=None) - jwt_payload = model.jwt_payload or JwtPayloadModel(iss=None, sub=None, aud=None) - return JwtAuthenticator( - config=config, - parameters=model.parameters or {}, - algorithm=JwtAlgorithm(model.algorithm.value), - secret_key=model.secret_key, - base64_encode_secret_key=model.base64_encode_secret_key, - token_duration=model.token_duration, - header_prefix=model.header_prefix, - kid=jwt_headers.kid, - typ=jwt_headers.typ, - cty=jwt_headers.cty, - iss=jwt_payload.iss, - sub=jwt_payload.sub, - aud=jwt_payload.aud, - additional_jwt_headers=model.additional_jwt_headers, - additional_jwt_payload=model.additional_jwt_payload, - ) - - @staticmethod - def create_list_partition_router(model: ListPartitionRouterModel, config: Config, **kwargs: Any) -> ListPartitionRouter: - request_option = ( - RequestOption( - inject_into=RequestOptionType(model.request_option.inject_into.value), - field_name=model.request_option.field_name, - parameters=model.parameters or {}, - ) - if model.request_option - else None - ) - return ListPartitionRouter( - cursor_field=model.cursor_field, - request_option=request_option, - values=model.values, - config=config, - parameters=model.parameters or {}, - ) - - @staticmethod - def create_min_max_datetime(model: MinMaxDatetimeModel, config: Config, **kwargs: Any) -> MinMaxDatetime: - return MinMaxDatetime( - datetime=model.datetime, - datetime_format=model.datetime_format or "", - max_datetime=model.max_datetime or "", - min_datetime=model.min_datetime or "", - parameters=model.parameters or {}, - ) - - @staticmethod - def create_no_auth(model: NoAuthModel, config: Config, **kwargs: Any) -> NoAuth: - return NoAuth(parameters=model.parameters or {}) - - @staticmethod - def create_no_pagination(model: NoPaginationModel, config: Config, **kwargs: Any) -> NoPagination: - return NoPagination(parameters={}) - - def create_oauth_authenticator(self, model: OAuthAuthenticatorModel, config: Config, **kwargs: Any) -> DeclarativeOauth2Authenticator: - if model.refresh_token_updater: - # ignore type error because fixing it would have a lot of dependencies, revisit later - return DeclarativeSingleUseRefreshTokenOauth2Authenticator( # type: ignore - config, - InterpolatedString.create(model.token_refresh_endpoint, parameters=model.parameters or {}).eval(config), - access_token_name=InterpolatedString.create( - model.access_token_name or "access_token", parameters=model.parameters or {} - ).eval(config), - refresh_token_name=model.refresh_token_updater.refresh_token_name, - expires_in_name=InterpolatedString.create(model.expires_in_name or "expires_in", parameters=model.parameters or {}).eval( - config - ), - client_id=InterpolatedString.create(model.client_id, parameters=model.parameters or {}).eval(config), - client_secret=InterpolatedString.create(model.client_secret, parameters=model.parameters or {}).eval(config), - access_token_config_path=model.refresh_token_updater.access_token_config_path, - refresh_token_config_path=model.refresh_token_updater.refresh_token_config_path, - token_expiry_date_config_path=model.refresh_token_updater.token_expiry_date_config_path, - grant_type=InterpolatedString.create(model.grant_type or "refresh_token", parameters=model.parameters or {}).eval(config), - refresh_request_body=InterpolatedMapping(model.refresh_request_body or {}, parameters=model.parameters or {}).eval(config), - scopes=model.scopes, - token_expiry_date_format=model.token_expiry_date_format, - message_repository=self._message_repository, - refresh_token_error_status_codes=model.refresh_token_updater.refresh_token_error_status_codes, - refresh_token_error_key=model.refresh_token_updater.refresh_token_error_key, - refresh_token_error_values=model.refresh_token_updater.refresh_token_error_values, - ) - # ignore type error because fixing it would have a lot of dependencies, revisit later - return DeclarativeOauth2Authenticator( # type: ignore - access_token_name=model.access_token_name or "access_token", - client_id=model.client_id, - client_secret=model.client_secret, - expires_in_name=model.expires_in_name or "expires_in", - grant_type=model.grant_type or "refresh_token", - refresh_request_body=model.refresh_request_body, - refresh_token=model.refresh_token, - scopes=model.scopes, - token_expiry_date=model.token_expiry_date, - token_expiry_date_format=model.token_expiry_date_format, # type: ignore - token_expiry_is_time_of_expiration=bool(model.token_expiry_date_format), - token_refresh_endpoint=model.token_refresh_endpoint, - config=config, - parameters=model.parameters or {}, - message_repository=self._message_repository, - ) - - @staticmethod - def create_offset_increment(model: OffsetIncrementModel, config: Config, decoder: Decoder, **kwargs: Any) -> OffsetIncrement: - if isinstance(decoder, PaginationDecoderDecorator): - if not isinstance(decoder.decoder, (JsonDecoder, XmlDecoder)): - raise ValueError( - f"Provided decoder of {type(decoder.decoder)=} is not supported. Please set JsonDecoder or XmlDecoder instead." - ) - decoder_to_use = decoder - else: - if not isinstance(decoder, (JsonDecoder, XmlDecoder)): - raise ValueError(f"Provided decoder of {type(decoder)=} is not supported. Please set JsonDecoder or XmlDecoder instead.") - decoder_to_use = PaginationDecoderDecorator(decoder=decoder) - return OffsetIncrement( - page_size=model.page_size, - config=config, - decoder=decoder_to_use, - inject_on_first_request=model.inject_on_first_request or False, - parameters=model.parameters or {}, - ) - - @staticmethod - def create_page_increment(model: PageIncrementModel, config: Config, **kwargs: Any) -> PageIncrement: - return PageIncrement( - page_size=model.page_size, - config=config, - start_from_page=model.start_from_page or 0, - inject_on_first_request=model.inject_on_first_request or False, - parameters=model.parameters or {}, - ) - - def create_parent_stream_config(self, model: ParentStreamConfigModel, config: Config, **kwargs: Any) -> ParentStreamConfig: - declarative_stream = self._create_component_from_model(model.stream, config=config) - request_option = self._create_component_from_model(model.request_option, config=config) if model.request_option else None - return ParentStreamConfig( - parent_key=model.parent_key, - request_option=request_option, - stream=declarative_stream, - partition_field=model.partition_field, - config=config, - incremental_dependency=model.incremental_dependency or False, - parameters=model.parameters or {}, - extra_fields=model.extra_fields, - ) - - @staticmethod - def create_record_filter(model: RecordFilterModel, config: Config, **kwargs: Any) -> RecordFilter: - return RecordFilter(condition=model.condition or "", config=config, parameters=model.parameters or {}) - - @staticmethod - def create_request_path(model: RequestPathModel, config: Config, **kwargs: Any) -> RequestPath: - return RequestPath(parameters={}) - - @staticmethod - def create_request_option(model: RequestOptionModel, config: Config, **kwargs: Any) -> RequestOption: - inject_into = RequestOptionType(model.inject_into.value) - return RequestOption(field_name=model.field_name, inject_into=inject_into, parameters={}) - - def create_record_selector( - self, - model: RecordSelectorModel, - config: Config, - *, - transformations: List[RecordTransformation], - decoder: Optional[Decoder] = None, - client_side_incremental_sync: Optional[Dict[str, Any]] = None, - **kwargs: Any, - ) -> RecordSelector: - assert model.schema_normalization is not None # for mypy - extractor = self._create_component_from_model(model=model.extractor, decoder=decoder, config=config) - record_filter = self._create_component_from_model(model.record_filter, config=config) if model.record_filter else None - if client_side_incremental_sync: - record_filter = ClientSideIncrementalRecordFilterDecorator( - config=config, - parameters=model.parameters, - condition=model.record_filter.condition if (model.record_filter and hasattr(model.record_filter, "condition")) else None, - **client_side_incremental_sync, - ) - schema_normalization = TypeTransformer(SCHEMA_TRANSFORMER_TYPE_MAPPING[model.schema_normalization]) - - return RecordSelector( - extractor=extractor, - config=config, - record_filter=record_filter, - transformations=transformations, - schema_normalization=schema_normalization, - parameters=model.parameters or {}, - ) - - @staticmethod - def create_remove_fields(model: RemoveFieldsModel, config: Config, **kwargs: Any) -> RemoveFields: - return RemoveFields(field_pointers=model.field_pointers, condition=model.condition or "", parameters={}) - - def create_selective_authenticator(self, model: SelectiveAuthenticatorModel, config: Config, **kwargs: Any) -> DeclarativeAuthenticator: - authenticators = {name: self._create_component_from_model(model=auth, config=config) for name, auth in model.authenticators.items()} - # SelectiveAuthenticator will return instance of DeclarativeAuthenticator or raise ValueError error - return SelectiveAuthenticator( # type: ignore[abstract] - config=config, - authenticators=authenticators, - authenticator_selection_path=model.authenticator_selection_path, - **kwargs, - ) - - @staticmethod - def create_legacy_session_token_authenticator( - model: LegacySessionTokenAuthenticatorModel, config: Config, *, url_base: str, **kwargs: Any - ) -> LegacySessionTokenAuthenticator: - return LegacySessionTokenAuthenticator( - api_url=url_base, - header=model.header, - login_url=model.login_url, - password=model.password or "", - session_token=model.session_token or "", - session_token_response_key=model.session_token_response_key or "", - username=model.username or "", - validate_session_url=model.validate_session_url, - config=config, - parameters=model.parameters or {}, - ) - - def create_simple_retriever( - self, - model: SimpleRetrieverModel, - config: Config, - *, - name: str, - primary_key: Optional[Union[str, List[str], List[List[str]]]], - stream_slicer: Optional[StreamSlicer], - request_options_provider: Optional[RequestOptionsProvider] = None, - stop_condition_on_cursor: bool = False, - client_side_incremental_sync: Optional[Dict[str, Any]] = None, - transformations: List[RecordTransformation], - ) -> SimpleRetriever: - decoder = self._create_component_from_model(model=model.decoder, config=config) if model.decoder else JsonDecoder(parameters={}) - requester = self._create_component_from_model(model=model.requester, decoder=decoder, config=config, name=name) - record_selector = self._create_component_from_model( - model=model.record_selector, - config=config, - decoder=decoder, - transformations=transformations, - client_side_incremental_sync=client_side_incremental_sync, - ) - url_base = model.requester.url_base if hasattr(model.requester, "url_base") else requester.get_url_base() - - # Define cursor only if per partition or common incremental support is needed - cursor = stream_slicer if isinstance(stream_slicer, DeclarativeCursor) else None - - if not isinstance(stream_slicer, DatetimeBasedCursor) or type(stream_slicer) is not DatetimeBasedCursor: - # Many of the custom component implementations of DatetimeBasedCursor override get_request_params() (or other methods). - # Because we're decoupling RequestOptionsProvider from the Cursor, custom components will eventually need to reimplement - # their own RequestOptionsProvider. However, right now the existing StreamSlicer/Cursor still can act as the SimpleRetriever's - # request_options_provider - request_options_provider = stream_slicer or DefaultRequestOptionsProvider(parameters={}) - elif not request_options_provider: - request_options_provider = DefaultRequestOptionsProvider(parameters={}) - - stream_slicer = stream_slicer or SinglePartitionRouter(parameters={}) - - cursor_used_for_stop_condition = cursor if stop_condition_on_cursor else None - paginator = ( - self._create_component_from_model( - model=model.paginator, - config=config, - url_base=url_base, - decoder=decoder, - cursor_used_for_stop_condition=cursor_used_for_stop_condition, - ) - if model.paginator - else NoPagination(parameters={}) - ) - - ignore_stream_slicer_parameters_on_paginated_requests = model.ignore_stream_slicer_parameters_on_paginated_requests or False - - if self._limit_slices_fetched or self._emit_connector_builder_messages: - return SimpleRetrieverTestReadDecorator( - name=name, - paginator=paginator, - primary_key=primary_key, - requester=requester, - record_selector=record_selector, - stream_slicer=stream_slicer, - request_option_provider=request_options_provider, - cursor=cursor, - config=config, - maximum_number_of_slices=self._limit_slices_fetched or 5, - ignore_stream_slicer_parameters_on_paginated_requests=ignore_stream_slicer_parameters_on_paginated_requests, - parameters=model.parameters or {}, - ) - return SimpleRetriever( - name=name, - paginator=paginator, - primary_key=primary_key, - requester=requester, - record_selector=record_selector, - stream_slicer=stream_slicer, - request_option_provider=request_options_provider, - cursor=cursor, - config=config, - ignore_stream_slicer_parameters_on_paginated_requests=ignore_stream_slicer_parameters_on_paginated_requests, - parameters=model.parameters or {}, - ) - - def _create_async_job_status_mapping( - self, model: AsyncJobStatusMapModel, config: Config, **kwargs: Any - ) -> Mapping[str, AsyncJobStatus]: - api_status_to_cdk_status = {} - for cdk_status, api_statuses in model.dict().items(): - if cdk_status == "type": - # This is an element of the dict because of the typing of the CDK but it is not a CDK status - continue - - for status in api_statuses: - if status in api_status_to_cdk_status: - raise ValueError( - f"API status {status} is already set for CDK status {cdk_status}. Please ensure API statuses are only provided once" - ) - api_status_to_cdk_status[status] = self._get_async_job_status(cdk_status) - return api_status_to_cdk_status - - def _get_async_job_status(self, status: str) -> AsyncJobStatus: - match status: - case "running": - return AsyncJobStatus.RUNNING - case "completed": - return AsyncJobStatus.COMPLETED - case "failed": - return AsyncJobStatus.FAILED - case "timeout": - return AsyncJobStatus.TIMED_OUT - case _: - raise ValueError(f"Unsupported CDK status {status}") - - def create_async_retriever( - self, - model: AsyncRetrieverModel, - config: Config, - *, - name: str, - primary_key: Optional[Union[str, List[str], List[List[str]]]], # this seems to be needed to match create_simple_retriever - stream_slicer: Optional[StreamSlicer], - client_side_incremental_sync: Optional[Dict[str, Any]] = None, - transformations: List[RecordTransformation], - **kwargs: Any, - ) -> AsyncRetriever: - - decoder = self._create_component_from_model(model=model.decoder, config=config) if model.decoder else JsonDecoder(parameters={}) - record_selector = self._create_component_from_model( - model=model.record_selector, - config=config, - decoder=decoder, - transformations=transformations, - client_side_incremental_sync=client_side_incremental_sync, - ) - stream_slicer = stream_slicer or SinglePartitionRouter(parameters={}) - creation_requester = self._create_component_from_model( - model=model.creation_requester, decoder=decoder, config=config, name=f"job creation - {name}" - ) - polling_requester = self._create_component_from_model( - model=model.polling_requester, decoder=decoder, config=config, name=f"job polling - {name}" - ) - job_download_components_name = f"job download - {name}" - download_requester = self._create_component_from_model( - model=model.download_requester, decoder=decoder, config=config, name=job_download_components_name - ) - download_retriever = SimpleRetriever( - requester=download_requester, - record_selector=RecordSelector( - extractor=ResponseToFileExtractor(), - record_filter=None, - transformations=[], - schema_normalization=TypeTransformer(TransformConfig.NoTransform), - config=config, - parameters={}, - ), - primary_key=None, - name=job_download_components_name, - paginator=( - self._create_component_from_model(model=model.download_paginator, decoder=decoder, config=config, url_base="") - if model.download_paginator - else NoPagination(parameters={}) - ), - config=config, - parameters={}, - ) - abort_requester = ( - self._create_component_from_model(model=model.abort_requester, decoder=decoder, config=config, name=f"job abort - {name}") - if model.abort_requester - else None - ) - delete_requester = ( - self._create_component_from_model(model=model.delete_requester, decoder=decoder, config=config, name=f"job delete - {name}") - if model.delete_requester - else None - ) - status_extractor = self._create_component_from_model(model=model.status_extractor, decoder=decoder, config=config, name=name) - urls_extractor = self._create_component_from_model(model=model.urls_extractor, decoder=decoder, config=config, name=name) - job_repository: AsyncJobRepository = AsyncHttpJobRepository( - creation_requester=creation_requester, - polling_requester=polling_requester, - download_retriever=download_retriever, - abort_requester=abort_requester, - delete_requester=delete_requester, - status_extractor=status_extractor, - status_mapping=self._create_async_job_status_mapping(model.status_mapping, config), - urls_extractor=urls_extractor, - ) - - return AsyncRetriever( - job_orchestrator_factory=lambda stream_slices: AsyncJobOrchestrator( - job_repository, - stream_slices, - JobTracker(1), # FIXME eventually make the number of concurrent jobs in the API configurable. Until then, we limit to 1 - self._message_repository, - has_bulk_parent=False, # FIXME work would need to be done here in order to detect if a stream as a parent stream that is bulk - ), - record_selector=record_selector, - stream_slicer=stream_slicer, - config=config, - parameters=model.parameters or {}, - ) - - @staticmethod - def create_spec(model: SpecModel, config: Config, **kwargs: Any) -> Spec: - return Spec( - connection_specification=model.connection_specification, - documentation_url=model.documentation_url, - advanced_auth=model.advanced_auth, - parameters={}, - ) - - def create_substream_partition_router( - self, model: SubstreamPartitionRouterModel, config: Config, **kwargs: Any - ) -> SubstreamPartitionRouter: - parent_stream_configs = [] - if model.parent_stream_configs: - parent_stream_configs.extend( - [ - self._create_message_repository_substream_wrapper(model=parent_stream_config, config=config) - for parent_stream_config in model.parent_stream_configs - ] - ) - - return SubstreamPartitionRouter(parent_stream_configs=parent_stream_configs, parameters=model.parameters or {}, config=config) - - def _create_message_repository_substream_wrapper(self, model: ParentStreamConfigModel, config: Config) -> Any: - substream_factory = ModelToComponentFactory( - limit_pages_fetched_per_slice=self._limit_pages_fetched_per_slice, - limit_slices_fetched=self._limit_slices_fetched, - emit_connector_builder_messages=self._emit_connector_builder_messages, - disable_retries=self._disable_retries, - disable_cache=self._disable_cache, - message_repository=LogAppenderMessageRepositoryDecorator( - {"airbyte_cdk": {"stream": {"is_substream": True}}, "http": {"is_auxiliary": True}}, - self._message_repository, - self._evaluate_log_level(self._emit_connector_builder_messages), - ), - ) - return substream_factory._create_component_from_model(model=model, config=config) - - @staticmethod - def create_wait_time_from_header(model: WaitTimeFromHeaderModel, config: Config, **kwargs: Any) -> WaitTimeFromHeaderBackoffStrategy: - return WaitTimeFromHeaderBackoffStrategy( - header=model.header, - parameters=model.parameters or {}, - config=config, - regex=model.regex, - max_waiting_time_in_seconds=model.max_waiting_time_in_seconds if model.max_waiting_time_in_seconds is not None else None, - ) - - @staticmethod - def create_wait_until_time_from_header( - model: WaitUntilTimeFromHeaderModel, config: Config, **kwargs: Any - ) -> WaitUntilTimeFromHeaderBackoffStrategy: - return WaitUntilTimeFromHeaderBackoffStrategy( - header=model.header, parameters=model.parameters or {}, config=config, min_wait=model.min_wait, regex=model.regex - ) - - def get_message_repository(self) -> MessageRepository: - return self._message_repository - - def _evaluate_log_level(self, emit_connector_builder_messages: bool) -> Level: - return Level.DEBUG if emit_connector_builder_messages else Level.INFO diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/__init__.py deleted file mode 100644 index 86e472a42c52..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (c) 2022 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.partition_routers.cartesian_product_stream_slicer import CartesianProductStreamSlicer -from airbyte_cdk.sources.declarative.partition_routers.list_partition_router import ListPartitionRouter -from airbyte_cdk.sources.declarative.partition_routers.single_partition_router import SinglePartitionRouter -from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import SubstreamPartitionRouter - -__all__ = ["CartesianProductStreamSlicer", "ListPartitionRouter", "SinglePartitionRouter", "SubstreamPartitionRouter"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/cartesian_product_stream_slicer.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/cartesian_product_stream_slicer.py deleted file mode 100644 index 14898428ede3..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/cartesian_product_stream_slicer.py +++ /dev/null @@ -1,154 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import itertools -import logging -from collections import ChainMap -from collections.abc import Callable -from dataclasses import InitVar, dataclass -from typing import Any, Iterable, List, Mapping, Optional - -from airbyte_cdk.sources.declarative.partition_routers.partition_router import PartitionRouter -from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import SubstreamPartitionRouter -from airbyte_cdk.sources.types import StreamSlice, StreamState - - -def check_for_substream_in_slicers(slicers: Iterable[PartitionRouter], log_warning: Callable[[str], None]) -> None: - """ - Recursively checks for the presence of SubstreamPartitionRouter within slicers. - Logs a warning if a SubstreamPartitionRouter is found within a CartesianProductStreamSlicer. - - Args: - slicers (Iterable[PartitionRouter]): The list of slicers to check. - log_warning (Callable): Logging function to record warnings. - """ - for slicer in slicers: - if isinstance(slicer, SubstreamPartitionRouter): - log_warning("Parent state handling is not supported for CartesianProductStreamSlicer.") - return - elif isinstance(slicer, CartesianProductStreamSlicer): - # Recursively check sub-slicers within CartesianProductStreamSlicer - check_for_substream_in_slicers(slicer.stream_slicers, log_warning) - - -@dataclass -class CartesianProductStreamSlicer(PartitionRouter): - """ - Stream slicers that iterates over the cartesian product of input stream slicers - Given 2 stream slicers with the following slices: - A: [{"i": 0}, {"i": 1}, {"i": 2}] - B: [{"s": "hello"}, {"s": "world"}] - the resulting stream slices are - [ - {"i": 0, "s": "hello"}, - {"i": 0, "s": "world"}, - {"i": 1, "s": "hello"}, - {"i": 1, "s": "world"}, - {"i": 2, "s": "hello"}, - {"i": 2, "s": "world"}, - ] - - Attributes: - stream_slicers (List[PartitionRouter]): Underlying stream slicers. The RequestOptions (e.g: Request headers, parameters, etc..) returned by this slicer are the combination of the RequestOptions of its input slicers. If there are conflicts e.g: two slicers define the same header or request param, the conflict is resolved by taking the value from the first slicer, where ordering is determined by the order in which slicers were input to this composite slicer. - """ - - stream_slicers: List[PartitionRouter] - parameters: InitVar[Mapping[str, Any]] - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - check_for_substream_in_slicers(self.stream_slicers, self.logger.warning) - - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return dict( - ChainMap( - *[ # type: ignore # ChainMap expects a MutableMapping[Never, Never] for reasons - s.get_request_params(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token) - for s in self.stream_slicers - ] - ) - ) - - def get_request_headers( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return dict( - ChainMap( - *[ # type: ignore # ChainMap expects a MutableMapping[Never, Never] for reasons - s.get_request_headers(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token) - for s in self.stream_slicers - ] - ) - ) - - def get_request_body_data( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return dict( - ChainMap( - *[ # type: ignore # ChainMap expects a MutableMapping[Never, Never] for reasons - s.get_request_body_data(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token) - for s in self.stream_slicers - ] - ) - ) - - def get_request_body_json( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return dict( - ChainMap( - *[ # type: ignore # ChainMap expects a MutableMapping[Never, Never] for reasons - s.get_request_body_json(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token) - for s in self.stream_slicers - ] - ) - ) - - def stream_slices(self) -> Iterable[StreamSlice]: - sub_slices = (s.stream_slices() for s in self.stream_slicers) - product = itertools.product(*sub_slices) - for stream_slice_tuple in product: - partition = dict(ChainMap(*[s.partition for s in stream_slice_tuple])) # type: ignore # ChainMap expects a MutableMapping[Never, Never] for reasons - cursor_slices = [s.cursor_slice for s in stream_slice_tuple if s.cursor_slice] - if len(cursor_slices) > 1: - raise ValueError(f"There should only be a single cursor slice. Found {cursor_slices}") - if cursor_slices: - cursor_slice = cursor_slices[0] - else: - cursor_slice = {} - yield StreamSlice(partition=partition, cursor_slice=cursor_slice) - - def set_initial_state(self, stream_state: StreamState) -> None: - """ - Parent stream states are not supported for cartesian product stream slicer - """ - pass - - def get_stream_state(self) -> Optional[Mapping[str, StreamState]]: - """ - Parent stream states are not supported for cartesian product stream slicer - """ - pass - - @property - def logger(self) -> logging.Logger: - return logging.getLogger("airbyte.CartesianProductStreamSlicer") diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/list_partition_router.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/list_partition_router.py deleted file mode 100644 index 564a3119e25b..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/list_partition_router.py +++ /dev/null @@ -1,101 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Iterable, List, Mapping, Optional, Union - -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.partition_routers.partition_router import PartitionRouter -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType -from airbyte_cdk.sources.types import Config, StreamSlice, StreamState - - -@dataclass -class ListPartitionRouter(PartitionRouter): - """ - Partition router that iterates over the values of a list - If values is a string, then evaluate it as literal and assert the resulting literal is a list - - Attributes: - values (Union[str, List[str]]): The values to iterate over - cursor_field (Union[InterpolatedString, str]): The name of the cursor field - config (Config): The user-provided configuration as specified by the source's spec - request_option (Optional[RequestOption]): The request option to configure the HTTP request - """ - - values: Union[str, List[str]] - cursor_field: Union[InterpolatedString, str] - config: Config - parameters: InitVar[Mapping[str, Any]] - request_option: Optional[RequestOption] = None - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - if isinstance(self.values, str): - self.values = InterpolatedString.create(self.values, parameters=parameters).eval(self.config) - self._cursor_field = ( - InterpolatedString(string=self.cursor_field, parameters=parameters) if isinstance(self.cursor_field, str) else self.cursor_field - ) - - self._cursor = None - - def get_request_params( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - # Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response - return self._get_request_option(RequestOptionType.request_parameter, stream_slice) - - def get_request_headers( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - # Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response - return self._get_request_option(RequestOptionType.header, stream_slice) - - def get_request_body_data( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - # Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response - return self._get_request_option(RequestOptionType.body_data, stream_slice) - - def get_request_body_json( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - # Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response - return self._get_request_option(RequestOptionType.body_json, stream_slice) - - def stream_slices(self) -> Iterable[StreamSlice]: - return [StreamSlice(partition={self._cursor_field.eval(self.config): slice_value}, cursor_slice={}) for slice_value in self.values] - - def _get_request_option(self, request_option_type: RequestOptionType, stream_slice: Optional[StreamSlice]) -> Mapping[str, Any]: - if self.request_option and self.request_option.inject_into == request_option_type and stream_slice: - slice_value = stream_slice.get(self._cursor_field.eval(self.config)) - if slice_value: - return {self.request_option.field_name.eval(self.config): slice_value} # type: ignore # field_name is always casted to InterpolatedString - else: - return {} - else: - return {} - - def set_initial_state(self, stream_state: StreamState) -> None: - """ - ListPartitionRouter doesn't have parent streams - """ - pass - - def get_stream_state(self) -> Optional[Mapping[str, StreamState]]: - """ - ListPartitionRouter doesn't have parent streams - """ - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/partition_router.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/partition_router.py deleted file mode 100644 index 3a9bc3abfbf2..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/partition_router.py +++ /dev/null @@ -1,62 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from abc import abstractmethod -from dataclasses import dataclass -from typing import Mapping, Optional - -from airbyte_cdk.sources.declarative.stream_slicers.stream_slicer import StreamSlicer -from airbyte_cdk.sources.types import StreamState - - -@dataclass -class PartitionRouter(StreamSlicer): - """ - Base class for partition routers. - Methods: - set_parent_state(stream_state): Set the state of the parent streams. - get_parent_state(): Get the state of the parent streams. - """ - - @abstractmethod - def set_initial_state(self, stream_state: StreamState) -> None: - """ - Set the state of the parent streams. - - This method should only be implemented if the slicer is based on some parent stream and needs to read this stream - incrementally using the state. - - Args: - stream_state (StreamState): The state of the streams to be set. The expected format is a dictionary that includes - 'parent_state' which is a dictionary of parent state names to their corresponding state. - Example: - { - "parent_state": { - "parent_stream_name_1": { ... }, - "parent_stream_name_2": { ... }, - ... - } - } - """ - - @abstractmethod - def get_stream_state(self) -> Optional[Mapping[str, StreamState]]: - """ - Get the state of the parent streams. - - This method should only be implemented if the slicer is based on some parent stream and needs to read this stream - incrementally using the state. - - Returns: - Optional[Mapping[str, StreamState]]: The current state of the parent streams in a dictionary format. - The returned format will be: - { - "parent_stream_name1": { - "last_updated": "2023-05-27T00:00:00Z" - }, - "parent_stream_name2": { - "last_updated": "2023-05-27T00:00:00Z" - } - } - """ diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/single_partition_router.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/single_partition_router.py deleted file mode 100644 index 32e6a353dedf..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/single_partition_router.py +++ /dev/null @@ -1,63 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Iterable, Mapping, Optional - -from airbyte_cdk.sources.declarative.partition_routers.partition_router import PartitionRouter -from airbyte_cdk.sources.types import StreamSlice, StreamState - - -@dataclass -class SinglePartitionRouter(PartitionRouter): - """Partition router returning only a stream slice""" - - parameters: InitVar[Mapping[str, Any]] - - def get_request_params( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return {} - - def get_request_headers( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return {} - - def get_request_body_data( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return {} - - def get_request_body_json( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return {} - - def stream_slices(self) -> Iterable[StreamSlice]: - yield StreamSlice(partition={}, cursor_slice={}) - - def set_initial_state(self, stream_state: StreamState) -> None: - """ - SinglePartitionRouter doesn't have parent streams - """ - pass - - def get_stream_state(self) -> Optional[Mapping[str, StreamState]]: - """ - SinglePartitionRouter doesn't have parent streams - """ - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/substream_partition_router.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/substream_partition_router.py deleted file mode 100644 index b9ca80f25463..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/partition_routers/substream_partition_router.py +++ /dev/null @@ -1,261 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import copy -import logging -from dataclasses import InitVar, dataclass -from typing import TYPE_CHECKING, Any, Iterable, List, Mapping, Optional, Union - -import dpath -from airbyte_cdk.models import AirbyteMessage -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.partition_routers.partition_router import PartitionRouter -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType -from airbyte_cdk.sources.types import Config, Record, StreamSlice, StreamState -from airbyte_cdk.utils import AirbyteTracedException - -if TYPE_CHECKING: - from airbyte_cdk.sources.declarative.declarative_stream import DeclarativeStream - - -@dataclass -class ParentStreamConfig: - """ - Describes how to create a stream slice from a parent stream - - stream: The stream to read records from - parent_key: The key of the parent stream's records that will be the stream slice key - partition_field: The partition key - extra_fields: Additional field paths to include in the stream slice - request_option: How to inject the slice value on an outgoing HTTP request - incremental_dependency (bool): Indicates if the parent stream should be read incrementally. - """ - - stream: "DeclarativeStream" # Parent streams must be DeclarativeStream because we can't know which part of the stream slice is a partition for regular Stream - parent_key: Union[InterpolatedString, str] - partition_field: Union[InterpolatedString, str] - config: Config - parameters: InitVar[Mapping[str, Any]] - extra_fields: Optional[Union[List[List[str]], List[List[InterpolatedString]]]] = None # List of field paths (arrays of strings) - request_option: Optional[RequestOption] = None - incremental_dependency: bool = False - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self.parent_key = InterpolatedString.create(self.parent_key, parameters=parameters) - self.partition_field = InterpolatedString.create(self.partition_field, parameters=parameters) - if self.extra_fields: - # Create InterpolatedString for each field path in extra_keys - self.extra_fields = [ - [InterpolatedString.create(path, parameters=parameters) for path in key_path] for key_path in self.extra_fields - ] - - -@dataclass -class SubstreamPartitionRouter(PartitionRouter): - """ - Partition router that iterates over the parent's stream records and emits slices - Will populate the state with `partition_field` and `parent_slice` so they can be accessed by other components - - Attributes: - parent_stream_configs (List[ParentStreamConfig]): parent streams to iterate over and their config - """ - - parent_stream_configs: List[ParentStreamConfig] - config: Config - parameters: InitVar[Mapping[str, Any]] - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - if not self.parent_stream_configs: - raise ValueError("SubstreamPartitionRouter needs at least 1 parent stream") - self._parameters = parameters - - def get_request_params( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - # Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response - return self._get_request_option(RequestOptionType.request_parameter, stream_slice) - - def get_request_headers( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - # Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response - return self._get_request_option(RequestOptionType.header, stream_slice) - - def get_request_body_data( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - # Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response - return self._get_request_option(RequestOptionType.body_data, stream_slice) - - def get_request_body_json( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - # Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response - return self._get_request_option(RequestOptionType.body_json, stream_slice) - - def _get_request_option(self, option_type: RequestOptionType, stream_slice: Optional[StreamSlice]) -> Mapping[str, Any]: - params = {} - if stream_slice: - for parent_config in self.parent_stream_configs: - if parent_config.request_option and parent_config.request_option.inject_into == option_type: - key = parent_config.partition_field.eval(self.config) # type: ignore # partition_field is always casted to an interpolated string - value = stream_slice.get(key) - if value: - params.update({parent_config.request_option.field_name.eval(config=self.config): value}) # type: ignore # field_name is always casted to an interpolated string - return params - - def stream_slices(self) -> Iterable[StreamSlice]: - """ - Iterate over each parent stream's record and create a StreamSlice for each record. - - For each stream, iterate over its stream_slices. - For each stream slice, iterate over each record. - yield a stream slice for each such records. - - If a parent slice contains no record, emit a slice with parent_record=None. - - The template string can interpolate the following values: - - parent_stream_slice: mapping representing the parent's stream slice - - parent_record: mapping representing the parent record - - parent_stream_name: string representing the parent stream name - """ - if not self.parent_stream_configs: - yield from [] - else: - for parent_stream_config in self.parent_stream_configs: - parent_stream = parent_stream_config.stream - parent_field = parent_stream_config.parent_key.eval(self.config) # type: ignore # parent_key is always casted to an interpolated string - partition_field = parent_stream_config.partition_field.eval(self.config) # type: ignore # partition_field is always casted to an interpolated string - extra_fields = None - if parent_stream_config.extra_fields: - extra_fields = [[field_path_part.eval(self.config) for field_path_part in field_path] for field_path in parent_stream_config.extra_fields] # type: ignore # extra_fields is always casted to an interpolated string - - # read_stateless() assumes the parent is not concurrent. This is currently okay since the concurrent CDK does - # not support either substreams or RFR, but something that needs to be considered once we do - for parent_record in parent_stream.read_only_records(): - parent_partition = None - # Skip non-records (eg AirbyteLogMessage) - if isinstance(parent_record, AirbyteMessage): - self.logger.warning( - f"Parent stream {parent_stream.name} returns records of type AirbyteMessage. This SubstreamPartitionRouter is not able to checkpoint incremental parent state." - ) - if parent_record.type == MessageType.RECORD: - parent_record = parent_record.record.data # type: ignore[union-attr] # record is always a Record - else: - continue - elif isinstance(parent_record, Record): - parent_partition = parent_record.associated_slice.partition if parent_record.associated_slice else {} - parent_record = parent_record.data - elif not isinstance(parent_record, Mapping): - # The parent_record should only take the form of a Record, AirbyteMessage, or Mapping. Anything else is invalid - raise AirbyteTracedException(message=f"Parent stream returned records as invalid type {type(parent_record)}") - try: - partition_value = dpath.get(parent_record, parent_field) - except KeyError: - continue - - # Add extra fields - extracted_extra_fields = self._extract_extra_fields(parent_record, extra_fields) - - yield StreamSlice( - partition={partition_field: partition_value, "parent_slice": parent_partition or {}}, - cursor_slice={}, - extra_fields=extracted_extra_fields, - ) - - def _extract_extra_fields( - self, parent_record: Mapping[str, Any] | AirbyteMessage, extra_fields: Optional[List[List[str]]] = None - ) -> Mapping[str, Any]: - """ - Extracts additional fields specified by their paths from the parent record. - - Args: - parent_record (Mapping[str, Any]): The record from the parent stream to extract fields from. - extra_fields (Optional[List[List[str]]]): A list of field paths (as lists of strings) to extract from the parent record. - - Returns: - Mapping[str, Any]: A dictionary containing the extracted fields. - The keys are the joined field paths, and the values are the corresponding extracted values. - """ - extracted_extra_fields = {} - if extra_fields: - for extra_field_path in extra_fields: - try: - extra_field_value = dpath.get(parent_record, extra_field_path) - self.logger.debug(f"Extracted extra_field_path: {extra_field_path} with value: {extra_field_value}") - except KeyError: - self.logger.debug(f"Failed to extract extra_field_path: {extra_field_path}") - extra_field_value = None - extracted_extra_fields[".".join(extra_field_path)] = extra_field_value - return extracted_extra_fields - - def set_initial_state(self, stream_state: StreamState) -> None: - """ - Set the state of the parent streams. - - Args: - stream_state (StreamState): The state of the streams to be set. If `parent_state` exists in the - stream_state, it will update the state of each parent stream with the corresponding state from the stream_state. - - Example of state format: - { - "parent_state": { - "parent_stream_name1": { - "last_updated": "2023-05-27T00:00:00Z" - }, - "parent_stream_name2": { - "last_updated": "2023-05-27T00:00:00Z" - } - } - } - """ - if not stream_state: - return - - parent_state = stream_state.get("parent_state") - if not parent_state: - return - - for parent_config in self.parent_stream_configs: - if parent_config.incremental_dependency: - parent_config.stream.state = parent_state.get(parent_config.stream.name, {}) - - def get_stream_state(self) -> Optional[Mapping[str, StreamState]]: - """ - Get the state of the parent streams. - - Returns: - StreamState: The current state of the parent streams. - - Example of state format: - { - "parent_stream_name1": { - "last_updated": "2023-05-27T00:00:00Z" - }, - "parent_stream_name2": { - "last_updated": "2023-05-27T00:00:00Z" - } - } - """ - parent_state = {} - for parent_config in self.parent_stream_configs: - if parent_config.incremental_dependency: - parent_state[parent_config.stream.name] = copy.deepcopy(parent_config.stream.state) - return parent_state - - @property - def logger(self) -> logging.Logger: - return logging.getLogger("airbyte.SubstreamPartitionRouter") diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/__init__.py deleted file mode 100644 index e5266ea7cfd4..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.requesters.http_requester import HttpRequester -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption -from airbyte_cdk.sources.declarative.requesters.requester import Requester - -__all__ = ["HttpRequester", "RequestOption", "Requester"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/__init__.py deleted file mode 100644 index 490169b6b6ee..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategy import BackoffStrategy -from airbyte_cdk.sources.declarative.requesters.error_handlers.composite_error_handler import CompositeErrorHandler -from airbyte_cdk.sources.declarative.requesters.error_handlers.default_error_handler import DefaultErrorHandler -from airbyte_cdk.sources.declarative.requesters.error_handlers.error_handler import ErrorHandler -from airbyte_cdk.sources.declarative.requesters.error_handlers.http_response_filter import HttpResponseFilter - -__all__ = ["BackoffStrategy", "CompositeErrorHandler", "DefaultErrorHandler", "ErrorHandler", "HttpResponseFilter"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py deleted file mode 100644 index 29647ae2959e..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.constant_backoff_strategy import ConstantBackoffStrategy -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.exponential_backoff_strategy import ( - ExponentialBackoffStrategy, -) -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.wait_time_from_header_backoff_strategy import ( - WaitTimeFromHeaderBackoffStrategy, -) -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.wait_until_time_from_header_backoff_strategy import ( - WaitUntilTimeFromHeaderBackoffStrategy, -) - -__all__ = [ - "ConstantBackoffStrategy", - "ExponentialBackoffStrategy", - "WaitTimeFromHeaderBackoffStrategy", - "WaitUntilTimeFromHeaderBackoffStrategy", -] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/constant_backoff_strategy.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/constant_backoff_strategy.py deleted file mode 100644 index 96c50ef0bf6d..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/constant_backoff_strategy.py +++ /dev/null @@ -1,40 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Mapping, Optional, Union - -import requests -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.streams.http.error_handlers import BackoffStrategy -from airbyte_cdk.sources.types import Config - - -@dataclass -class ConstantBackoffStrategy(BackoffStrategy): - """ - Backoff strategy with a constant backoff interval - - Attributes: - backoff_time_in_seconds (float): time to backoff before retrying a retryable request. - """ - - backoff_time_in_seconds: Union[float, InterpolatedString, str] - parameters: InitVar[Mapping[str, Any]] - config: Config - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - if not isinstance(self.backoff_time_in_seconds, InterpolatedString): - self.backoff_time_in_seconds = str(self.backoff_time_in_seconds) - if isinstance(self.backoff_time_in_seconds, float): - self.backoff_time_in_seconds = InterpolatedString.create(str(self.backoff_time_in_seconds), parameters=parameters) - else: - self.backoff_time_in_seconds = InterpolatedString.create(self.backoff_time_in_seconds, parameters=parameters) - - def backoff_time( - self, - response_or_exception: Optional[Union[requests.Response, requests.RequestException]], - attempt_count: int, - ) -> Optional[float]: - return self.backoff_time_in_seconds.eval(self.config) # type: ignore # backoff_time_in_seconds is always cast to an interpolated string diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/exponential_backoff_strategy.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/exponential_backoff_strategy.py deleted file mode 100644 index b3a57675b727..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/exponential_backoff_strategy.py +++ /dev/null @@ -1,44 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Mapping, Optional, Union - -import requests -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.streams.http.error_handlers import BackoffStrategy -from airbyte_cdk.sources.types import Config - - -@dataclass -class ExponentialBackoffStrategy(BackoffStrategy): - """ - Backoff strategy with an exponential backoff interval - - Attributes: - factor (float): multiplicative factor - """ - - parameters: InitVar[Mapping[str, Any]] - config: Config - factor: Union[float, InterpolatedString, str] = 5 - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - if not isinstance(self.factor, InterpolatedString): - self.factor = str(self.factor) - if isinstance(self.factor, float): - self._factor = InterpolatedString.create(str(self.factor), parameters=parameters) - else: - self._factor = InterpolatedString.create(self.factor, parameters=parameters) - - @property - def _retry_factor(self) -> float: - return self._factor.eval(self.config) # type: ignore # factor is always cast to an interpolated string - - def backoff_time( - self, - response_or_exception: Optional[Union[requests.Response, requests.RequestException]], - attempt_count: int, - ) -> Optional[float]: - return self._retry_factor * 2**attempt_count # type: ignore # factor is always cast to an interpolated string diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/header_helper.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/header_helper.py deleted file mode 100644 index e7f5e1f88a64..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/header_helper.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import numbers -from re import Pattern -from typing import Optional - -import requests - - -def get_numeric_value_from_header(response: requests.Response, header: str, regex: Optional[Pattern[str]]) -> Optional[float]: - """ - Extract a header value from the response as a float - :param response: response the extract header value from - :param header: Header to extract - :param regex: optional regex to apply on the header to obtain the value - :return: header value as float if it's a number. None otherwise - """ - header_value = response.headers.get(header, None) - if not header_value: - return None - if isinstance(header_value, str): - if regex: - match = regex.match(header_value) - if match: - header_value = match.group() - return _as_float(header_value) - elif isinstance(header_value, numbers.Number): - return float(header_value) # type: ignore[arg-type] - else: - return None - - -def _as_float(s: str) -> Optional[float]: - try: - return float(s) - except ValueError: - return None diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_time_from_header_backoff_strategy.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_time_from_header_backoff_strategy.py deleted file mode 100644 index 79eb8a7fe23d..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_time_from_header_backoff_strategy.py +++ /dev/null @@ -1,57 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import re -from dataclasses import InitVar, dataclass -from typing import Any, Mapping, Optional, Union - -import requests -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.header_helper import get_numeric_value_from_header -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategy import BackoffStrategy -from airbyte_cdk.sources.types import Config -from airbyte_cdk.utils import AirbyteTracedException - - -@dataclass -class WaitTimeFromHeaderBackoffStrategy(BackoffStrategy): - """ - Extract wait time from http header - - Attributes: - header (str): header to read wait time from - regex (Optional[str]): optional regex to apply on the header to extract its value - max_waiting_time_in_seconds: (Optional[float]): given the value extracted from the header is greater than this value, stop the stream - """ - - header: Union[InterpolatedString, str] - parameters: InitVar[Mapping[str, Any]] - config: Config - regex: Optional[Union[InterpolatedString, str]] = None - max_waiting_time_in_seconds: Optional[float] = None - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self.regex = InterpolatedString.create(self.regex, parameters=parameters) if self.regex else None - self.header = InterpolatedString.create(self.header, parameters=parameters) - - def backoff_time( - self, response_or_exception: Optional[Union[requests.Response, requests.RequestException]], attempt_count: int - ) -> Optional[float]: - header = self.header.eval(config=self.config) # type: ignore # header is always cast to an interpolated stream - if self.regex: - evaled_regex = self.regex.eval(self.config) # type: ignore # header is always cast to an interpolated string - regex = re.compile(evaled_regex) - else: - regex = None - header_value = None - if isinstance(response_or_exception, requests.Response): - header_value = get_numeric_value_from_header(response_or_exception, header, regex) - if self.max_waiting_time_in_seconds and header_value and header_value >= self.max_waiting_time_in_seconds: - raise AirbyteTracedException( - internal_message=f"Rate limit wait time {header_value} is greater than max waiting time of {self.max_waiting_time_in_seconds} seconds. Stopping the stream...", - message="The rate limit is greater than max waiting time has been reached.", - failure_type=FailureType.transient_error, - ) - return header_value diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_until_time_from_header_backoff_strategy.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_until_time_from_header_backoff_strategy.py deleted file mode 100644 index 861f8ba83193..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_until_time_from_header_backoff_strategy.py +++ /dev/null @@ -1,66 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import numbers -import re -import time -from dataclasses import InitVar, dataclass -from typing import Any, Mapping, Optional, Union - -import requests -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.header_helper import get_numeric_value_from_header -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategy import BackoffStrategy -from airbyte_cdk.sources.types import Config - - -@dataclass -class WaitUntilTimeFromHeaderBackoffStrategy(BackoffStrategy): - """ - Extract time at which we can retry the request from response header - and wait for the difference between now and that time - - Attributes: - header (str): header to read wait time from - min_wait (Optional[float]): minimum time to wait for safety - regex (Optional[str]): optional regex to apply on the header to extract its value - """ - - header: Union[InterpolatedString, str] - parameters: InitVar[Mapping[str, Any]] - config: Config - min_wait: Optional[Union[float, InterpolatedString, str]] = None - regex: Optional[Union[InterpolatedString, str]] = None - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self.header = InterpolatedString.create(self.header, parameters=parameters) - self.regex = InterpolatedString.create(self.regex, parameters=parameters) if self.regex else None - if not isinstance(self.min_wait, InterpolatedString): - self.min_wait = InterpolatedString.create(str(self.min_wait), parameters=parameters) - - def backoff_time( - self, response_or_exception: Optional[Union[requests.Response, requests.RequestException]], attempt_count: int - ) -> Optional[float]: - now = time.time() - header = self.header.eval(self.config) # type: ignore # header is always cast to an interpolated string - if self.regex: - evaled_regex = self.regex.eval(self.config) # type: ignore # header is always cast to an interpolated string - regex = re.compile(evaled_regex) - else: - regex = None - wait_until = None - if isinstance(response_or_exception, requests.Response): - wait_until = get_numeric_value_from_header(response_or_exception, header, regex) - min_wait = self.min_wait.eval(self.config) # type: ignore # header is always cast to an interpolated string - if wait_until is None or not wait_until: - return float(min_wait) if min_wait else None - if (isinstance(wait_until, str) and wait_until.isnumeric()) or isinstance(wait_until, numbers.Number): - wait_time = float(wait_until) - now - else: - return float(min_wait) - if min_wait: - return float(max(wait_time, min_wait)) - elif wait_time < 0: - return None - return wait_time diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategy.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategy.py deleted file mode 100644 index 7a44f7b94895..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategy.py +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import ABC -from dataclasses import dataclass - -from airbyte_cdk.sources.streams.http.error_handlers import BackoffStrategy - - -@dataclass -class DecalarativeBackoffStrategy(BackoffStrategy, ABC): - """ - This interface exists to retain backwards compatability with connectors that reference the declarative BackoffStrategy. As part of the effort to promote common interfaces to the Python CDK, this now extends the Python CDK backoff strategy interface. - - Backoff strategy defining how long to wait before retrying a request that resulted in an error. - """ diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/composite_error_handler.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/composite_error_handler.py deleted file mode 100644 index bc151feca3dc..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/composite_error_handler.py +++ /dev/null @@ -1,76 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, List, Mapping, Optional, Union - -import requests -from airbyte_cdk.sources.streams.http.error_handlers import ErrorHandler -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ( - ErrorResolution, - ResponseAction, - create_fallback_error_resolution, -) - - -@dataclass -class CompositeErrorHandler(ErrorHandler): - """ - Error handler that sequentially iterates over a list of `ErrorHandler`s - - Sample config chaining 2 different retriers: - error_handler: - type: "CompositeErrorHandler" - error_handlers: - - response_filters: - - predicate: "{{ 'codase' in response }}" - action: RETRY - backoff_strategies: - - type: "ConstantBackoff" - backoff_time_in_seconds: 5 - - response_filters: - - http_codes: [ 403 ] - action: RETRY - backoff_strategies: - - type: "ConstantBackoff" - backoff_time_in_seconds: 10 - Attributes: - error_handlers (List[ErrorHandler]): list of error handlers - """ - - error_handlers: List[ErrorHandler] - parameters: InitVar[Mapping[str, Any]] - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - if not self.error_handlers: - raise ValueError("CompositeErrorHandler expects at least 1 underlying error handler") - - @property - def max_retries(self) -> Optional[int]: - return self.error_handlers[0].max_retries - - @property - def max_time(self) -> Optional[int]: - return max([error_handler.max_time or 0 for error_handler in self.error_handlers]) - - def interpret_response(self, response_or_exception: Optional[Union[requests.Response, Exception]]) -> ErrorResolution: - matched_error_resolution = None - for error_handler in self.error_handlers: - matched_error_resolution = error_handler.interpret_response(response_or_exception) - - if not isinstance(matched_error_resolution, ErrorResolution): - continue - - if matched_error_resolution.response_action == ResponseAction.SUCCESS: - return matched_error_resolution - - if ( - matched_error_resolution.response_action == ResponseAction.RETRY - or matched_error_resolution.response_action == ResponseAction.IGNORE - ): - return matched_error_resolution - if matched_error_resolution: - return matched_error_resolution - - return create_fallback_error_resolution(response_or_exception) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/default_error_handler.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/default_error_handler.py deleted file mode 100644 index 68ff5ecf99cd..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/default_error_handler.py +++ /dev/null @@ -1,136 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass, field -from typing import Any, List, Mapping, MutableMapping, Optional, Union - -import requests -from airbyte_cdk.sources.declarative.requesters.error_handlers.default_http_response_filter import DefaultHttpResponseFilter -from airbyte_cdk.sources.declarative.requesters.error_handlers.http_response_filter import HttpResponseFilter -from airbyte_cdk.sources.streams.http.error_handlers import BackoffStrategy, ErrorHandler -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ( - SUCCESS_RESOLUTION, - ErrorResolution, - create_fallback_error_resolution, -) -from airbyte_cdk.sources.types import Config - - -@dataclass -class DefaultErrorHandler(ErrorHandler): - """ - Default error handler. - - By default, the handler will only use the `DEFAULT_ERROR_MAPPING` that is part of the Python CDK's `HttpStatusErrorHandler`. - - If the response is successful, then a SUCCESS_RESOLUTION is returned. - Otherwise, iterate over the response_filters. - If any of the filter match the response, then return the appropriate status. - When `DefaultErrorHandler.backoff_time()` is invoked, iterate sequentially over the backoff_strategies and return the first non-None backoff time, else return None. - - Sample configs: - - 1. retry 10 times - ` - error_handler: - max_retries: 10 - ` - 2. backoff for 5 seconds - ` - error_handler: - backoff_strategies: - - type: "ConstantBackoff" - backoff_time_in_seconds: 5 - ` - 3. retry on HTTP 404 - ` - error_handler: - response_filters: - - http_codes: [ 404 ] - action: RETRY - ` - 4. ignore HTTP 404 - ` - error_handler: - response_filters: - - http_codes: [ 404 ] - action: IGNORE - ` - 5. retry if error message contains `retrythisrequest!` substring - ` - error_handler: - response_filters: - - error_message_contain: "retrythisrequest!" - action: IGNORE - ` - 6. retry if 'code' is a field present in the response body - ` - error_handler: - response_filters: - - predicate: "{{ 'code' in response }}" - action: IGNORE - ` - - 7. ignore 429 and retry on 404 - ` - error_handler: - - http_codes: [ 429 ] - action: IGNORE - - http_codes: [ 404 ] - action: RETRY - ` - - Attributes: - response_filters (Optional[List[HttpResponseFilter]]): response filters to iterate on - max_retries (Optional[int]): maximum retry attempts - backoff_strategies (Optional[List[BackoffStrategy]]): list of backoff strategies to use to determine how long - to wait before retrying - """ - - parameters: InitVar[Mapping[str, Any]] - config: Config - response_filters: Optional[List[HttpResponseFilter]] = None - max_retries: Optional[int] = 5 - max_time: int = 60 * 10 - _max_retries: int = field(init=False, repr=False, default=5) - _max_time: int = field(init=False, repr=False, default=60 * 10) - backoff_strategies: Optional[List[BackoffStrategy]] = None - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - - if not self.response_filters: - self.response_filters = [HttpResponseFilter(config=self.config, parameters={})] - - self._last_request_to_attempt_count: MutableMapping[requests.PreparedRequest, int] = {} - - def interpret_response(self, response_or_exception: Optional[Union[requests.Response, Exception]]) -> ErrorResolution: - - if self.response_filters: - for response_filter in self.response_filters: - matched_error_resolution = response_filter.matches(response_or_exception=response_or_exception) - if matched_error_resolution: - return matched_error_resolution - if isinstance(response_or_exception, requests.Response): - if response_or_exception.ok: - return SUCCESS_RESOLUTION - - default_reponse_filter = DefaultHttpResponseFilter(parameters={}, config=self.config) - default_response_filter_resolution = default_reponse_filter.matches(response_or_exception) - - return ( - default_response_filter_resolution - if default_response_filter_resolution - else create_fallback_error_resolution(response_or_exception) - ) - - def backoff_time( - self, response_or_exception: Optional[Union[requests.Response, requests.RequestException]], attempt_count: int = 0 - ) -> Optional[float]: - backoff = None - if self.backoff_strategies: - for backoff_strategy in self.backoff_strategies: - backoff = backoff_strategy.backoff_time(response_or_exception=response_or_exception, attempt_count=attempt_count) # type: ignore # attempt_count maintained for compatibility with low code CDK - if backoff: - return backoff - return backoff diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/default_http_response_filter.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/default_http_response_filter.py deleted file mode 100644 index 4e3f54169825..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/default_http_response_filter.py +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from typing import Optional, Union - -import requests -from airbyte_cdk.sources.declarative.requesters.error_handlers.http_response_filter import HttpResponseFilter -from airbyte_cdk.sources.streams.http.error_handlers.default_error_mapping import DEFAULT_ERROR_MAPPING -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, create_fallback_error_resolution - - -class DefaultHttpResponseFilter(HttpResponseFilter): - def matches(self, response_or_exception: Optional[Union[requests.Response, Exception]]) -> Optional[ErrorResolution]: - - default_mapped_error_resolution = None - - if isinstance(response_or_exception, (requests.Response, Exception)): - - mapped_key: Union[int, type] = ( - response_or_exception.status_code - if isinstance(response_or_exception, requests.Response) - else response_or_exception.__class__ - ) - - default_mapped_error_resolution = DEFAULT_ERROR_MAPPING.get(mapped_key) - - return ( - default_mapped_error_resolution if default_mapped_error_resolution else create_fallback_error_resolution(response_or_exception) - ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/error_handler.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/error_handler.py deleted file mode 100644 index a84747f91996..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/error_handler.py +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import ABC -from dataclasses import dataclass - -from airbyte_cdk.sources.streams.http.error_handlers import ErrorHandler - - -@dataclass -class DeclarativeErrorHandler(ErrorHandler, ABC): - """ - This interface exists to retain backwards compatability with connectors that reference the declarative ErrorHandler. As part of the effort to promote common interfaces to the Python CDK, this now extends the Python CDK ErrorHandler interface. - - `ErrorHandler` defines how to handle errors that occur during the request process, returning an ErrorResolution object that defines how to proceed. - """ diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/http_response_filter.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/http_response_filter.py deleted file mode 100644 index c452dcac5cdd..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/error_handlers/http_response_filter.py +++ /dev/null @@ -1,139 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Mapping, Optional, Set, Union - -import requests -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.declarative.interpolation import InterpolatedString -from airbyte_cdk.sources.declarative.interpolation.interpolated_boolean import InterpolatedBoolean -from airbyte_cdk.sources.streams.http.error_handlers import JsonErrorMessageParser -from airbyte_cdk.sources.streams.http.error_handlers.default_error_mapping import DEFAULT_ERROR_MAPPING -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, ResponseAction -from airbyte_cdk.sources.types import Config - - -@dataclass -class HttpResponseFilter: - """ - Filter to select a response based on its HTTP status code, error message or a predicate. - If a response matches the filter, the response action, failure_type, and error message are returned as an ErrorResolution object. - For http_codes declared in the filter, the failure_type will default to `system_error`. - To override default failure_type use configured failure_type with ResponseAction.FAIL. - - Attributes: - action (Union[ResponseAction, str]): action to execute if a request matches - failure_type (Union[ResponseAction, str]): failure type of traced exception if a response matches the filter - http_codes (Set[int]): http code of matching requests - error_message_contains (str): error substring of matching requests - predicate (str): predicate to apply to determine if a request is matching - error_message (Union[InterpolatedString, str): error message to display if the response matches the filter - """ - - config: Config - parameters: InitVar[Mapping[str, Any]] - action: Optional[Union[ResponseAction, str]] = None - failure_type: Optional[Union[FailureType, str]] = None - http_codes: Optional[Set[int]] = None - error_message_contains: Optional[str] = None - predicate: Union[InterpolatedBoolean, str] = "" - error_message: Union[InterpolatedString, str] = "" - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - - if self.action is not None: - if self.http_codes is None and self.predicate is None and self.error_message_contains is None: - raise ValueError("HttpResponseFilter requires a filter condition if an action is specified") - elif isinstance(self.action, str): - self.action = ResponseAction[self.action] - self.http_codes = self.http_codes or set() - if isinstance(self.predicate, str): - self.predicate = InterpolatedBoolean(condition=self.predicate, parameters=parameters) - self.error_message = InterpolatedString.create(string_or_interpolated=self.error_message, parameters=parameters) - self._error_message_parser = JsonErrorMessageParser() - if self.failure_type and isinstance(self.failure_type, str): - self.failure_type = FailureType[self.failure_type] - - def matches(self, response_or_exception: Optional[Union[requests.Response, Exception]]) -> Optional[ErrorResolution]: - filter_action = self._matches_filter(response_or_exception) - mapped_key = ( - response_or_exception.status_code if isinstance(response_or_exception, requests.Response) else response_or_exception.__class__ - ) - - if isinstance(mapped_key, (int, Exception)): - default_mapped_error_resolution = self._match_default_error_mapping(mapped_key) - else: - default_mapped_error_resolution = None - - if filter_action is not None: - default_error_message = default_mapped_error_resolution.error_message if default_mapped_error_resolution else "" - error_message = None - if isinstance(response_or_exception, requests.Response): - error_message = self._create_error_message(response_or_exception) - error_message = error_message or default_error_message - - if self.failure_type and filter_action == ResponseAction.FAIL: - failure_type = self.failure_type - elif default_mapped_error_resolution: - failure_type = default_mapped_error_resolution.failure_type - else: - failure_type = FailureType.system_error - - return ErrorResolution( - response_action=filter_action, - failure_type=failure_type, - error_message=error_message, - ) - - if ( - (isinstance(self.http_codes, list) and len(self.http_codes)) is None - and self.predicate is None - and self.error_message_contains is None - ) and default_mapped_error_resolution: - return default_mapped_error_resolution - - return None - - def _match_default_error_mapping(self, mapped_key: Union[int, type[Exception]]) -> Optional[ErrorResolution]: - return DEFAULT_ERROR_MAPPING.get(mapped_key) - - def _matches_filter(self, response_or_exception: Optional[Union[requests.Response, Exception]]) -> Optional[ResponseAction]: - """ - Apply the HTTP filter on the response and return the action to execute if it matches - :param response: The HTTP response to evaluate - :return: The action to execute. None if the response does not match the filter - """ - if isinstance(response_or_exception, requests.Response) and ( - response_or_exception.status_code in self.http_codes # type: ignore # http_codes set is always initialized to a value in __post_init__ - or self._response_matches_predicate(response_or_exception) - or self._response_contains_error_message(response_or_exception) - ): - return self.action # type: ignore # action is always cast to a ResponseAction not a str - return None - - @staticmethod - def _safe_response_json(response: requests.Response) -> dict[str, Any]: - try: - return response.json() # type: ignore # Response.json() returns a dictionary even if the signature does not - except requests.exceptions.JSONDecodeError: - return {} - - def _create_error_message(self, response: requests.Response) -> Optional[str]: - """ - Construct an error message based on the specified message template of the filter. - :param response: The HTTP response which can be used during interpolation - :return: The evaluated error message string to be emitted - """ - return self.error_message.eval(self.config, response=self._safe_response_json(response), headers=response.headers) # type: ignore # error_message is always cast to an interpolated string - - def _response_matches_predicate(self, response: requests.Response) -> bool: - return bool(self.predicate.condition and self.predicate.eval(None, response=self._safe_response_json(response), headers=response.headers)) if self.predicate else False # type: ignore # predicate is always cast to an interpolated string - - def _response_contains_error_message(self, response: requests.Response) -> bool: - if not self.error_message_contains: - return False - else: - error_message = self._error_message_parser.parse_response_error_message(response=response) - return bool(error_message and self.error_message_contains in error_message) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/http_job_repository.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/http_job_repository.py deleted file mode 100644 index 2c425bf84dd5..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/http_job_repository.py +++ /dev/null @@ -1,206 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -import logging -import uuid -from dataclasses import dataclass, field -from datetime import timedelta -from typing import Any, Dict, Iterable, Mapping, Optional - -import requests -from airbyte_cdk import AirbyteMessage -from airbyte_cdk.logger import lazy_log -from airbyte_cdk.models import FailureType, Type -from airbyte_cdk.sources.declarative.async_job.job import AsyncJob -from airbyte_cdk.sources.declarative.async_job.repository import AsyncJobRepository -from airbyte_cdk.sources.declarative.async_job.status import AsyncJobStatus -from airbyte_cdk.sources.declarative.extractors.dpath_extractor import DpathExtractor, RecordExtractor -from airbyte_cdk.sources.declarative.extractors.response_to_file_extractor import ResponseToFileExtractor -from airbyte_cdk.sources.declarative.requesters.requester import Requester -from airbyte_cdk.sources.declarative.retrievers.simple_retriever import SimpleRetriever -from airbyte_cdk.sources.types import Record, StreamSlice -from airbyte_cdk.utils import AirbyteTracedException -from requests import Response - -LOGGER = logging.getLogger("airbyte") - - -@dataclass -class AsyncHttpJobRepository(AsyncJobRepository): - creation_requester: Requester - polling_requester: Requester - download_retriever: SimpleRetriever - abort_requester: Optional[Requester] - delete_requester: Optional[Requester] - status_extractor: DpathExtractor - status_mapping: Mapping[str, AsyncJobStatus] - urls_extractor: DpathExtractor - - job_timeout: Optional[timedelta] = None - record_extractor: RecordExtractor = field(init=False, repr=False, default_factory=lambda: ResponseToFileExtractor()) - - def __post_init__(self) -> None: - self._create_job_response_by_id: Dict[str, Response] = {} - self._polling_job_response_by_id: Dict[str, Response] = {} - - def _get_validated_polling_response(self, stream_slice: StreamSlice) -> requests.Response: - """ - Validates and retrieves the pooling response for a given stream slice. - - Args: - stream_slice (StreamSlice): The stream slice to send the pooling request for. - - Returns: - requests.Response: The validated pooling response. - - Raises: - AirbyteTracedException: If the polling request returns an empty response. - """ - - polling_response: Optional[requests.Response] = self.polling_requester.send_request(stream_slice=stream_slice) - if polling_response is None: - raise AirbyteTracedException( - internal_message="Polling Requester received an empty Response.", - failure_type=FailureType.system_error, - ) - return polling_response - - def _get_validated_job_status(self, response: requests.Response) -> AsyncJobStatus: - """ - Validates the job status extracted from the API response. - - Args: - response (requests.Response): The API response. - - Returns: - AsyncJobStatus: The validated job status. - - Raises: - ValueError: If the API status is unknown. - """ - - api_status = next(iter(self.status_extractor.extract_records(response)), None) - job_status = self.status_mapping.get(str(api_status), None) - if job_status is None: - raise ValueError( - f"API status `{api_status}` is unknown. Contact the connector developer to make sure this status is supported." - ) - - return job_status - - def _start_job_and_validate_response(self, stream_slice: StreamSlice) -> requests.Response: - """ - Starts a job and validates the response. - - Args: - stream_slice (StreamSlice): The stream slice to be used for the job. - - Returns: - requests.Response: The response from the job creation requester. - - Raises: - AirbyteTracedException: If no response is received from the creation requester. - """ - - response: Optional[requests.Response] = self.creation_requester.send_request(stream_slice=stream_slice) - if not response: - raise AirbyteTracedException( - internal_message="Always expect a response or an exception from creation_requester", - failure_type=FailureType.system_error, - ) - - return response - - def start(self, stream_slice: StreamSlice) -> AsyncJob: - """ - Starts a job for the given stream slice. - - Args: - stream_slice (StreamSlice): The stream slice to start the job for. - - Returns: - AsyncJob: The asynchronous job object representing the started job. - """ - - response: requests.Response = self._start_job_and_validate_response(stream_slice) - job_id: str = str(uuid.uuid4()) - self._create_job_response_by_id[job_id] = response - - return AsyncJob(api_job_id=job_id, job_parameters=stream_slice, timeout=self.job_timeout) - - def update_jobs_status(self, jobs: Iterable[AsyncJob]) -> None: - """ - Updates the status of multiple jobs. - - Because we don't have interpolation on random fields, we have this hack which consist on using the stream_slice to allow for - interpolation. We are looking at enabling interpolation on more field which would require a change to those three layers: - HttpRequester, RequestOptionProvider, RequestInputProvider. - - Args: - jobs (Iterable[AsyncJob]): An iterable of AsyncJob objects representing the jobs to update. - - Returns: - None - """ - for job in jobs: - stream_slice = self._get_create_job_stream_slice(job) - polling_response: requests.Response = self._get_validated_polling_response(stream_slice) - job_status: AsyncJobStatus = self._get_validated_job_status(polling_response) - - if job_status != job.status(): - lazy_log(LOGGER, logging.DEBUG, lambda: f"Status of job {job.api_job_id()} changed from {job.status()} to {job_status}") - else: - lazy_log(LOGGER, logging.DEBUG, lambda: f"Status of job {job.api_job_id()} is still {job.status()}") - - job.update_status(job_status) - if job_status == AsyncJobStatus.COMPLETED: - self._polling_job_response_by_id[job.api_job_id()] = polling_response - - def fetch_records(self, job: AsyncJob) -> Iterable[Mapping[str, Any]]: - """ - Fetches records from the given job. - - Args: - job (AsyncJob): The job to fetch records from. - - Yields: - Iterable[Mapping[str, Any]]: A generator that yields records as dictionaries. - - """ - - for url in self.urls_extractor.extract_records(self._polling_job_response_by_id[job.api_job_id()]): - stream_slice: StreamSlice = StreamSlice(partition={"url": url}, cursor_slice={}) - for message in self.download_retriever.read_records({}, stream_slice): - if isinstance(message, Record): - yield message.data - elif isinstance(message, AirbyteMessage): - if message.type == Type.RECORD: - yield message.record.data # type: ignore # message.record won't be None here as the message is a record - elif isinstance(message, (dict, Mapping)): - yield message - else: - raise TypeError(f"Unknown type `{type(message)}` for message") - - yield from [] - - def abort(self, job: AsyncJob) -> None: - if not self.abort_requester: - return - - self.abort_requester.send_request(stream_slice=self._get_create_job_stream_slice(job)) - - def delete(self, job: AsyncJob) -> None: - if not self.delete_requester: - return - - self.delete_requester.send_request(stream_slice=self._get_create_job_stream_slice(job)) - self._clean_up_job(job.api_job_id()) - - def _clean_up_job(self, job_id: str) -> None: - del self._create_job_response_by_id[job_id] - del self._polling_job_response_by_id[job_id] - - def _get_create_job_stream_slice(self, job: AsyncJob) -> StreamSlice: - stream_slice = StreamSlice( - partition={"create_job_response": self._create_job_response_by_id[job.api_job_id()]}, - cursor_slice={}, - ) - return stream_slice diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/http_requester.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/http_requester.py deleted file mode 100644 index 05d8bfa1b957..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/http_requester.py +++ /dev/null @@ -1,321 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -import os -from dataclasses import InitVar, dataclass, field -from typing import Any, Callable, Mapping, MutableMapping, Optional, Union -from urllib.parse import urljoin - -import requests -from airbyte_cdk.sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator, NoAuth -from airbyte_cdk.sources.declarative.decoders import Decoder -from airbyte_cdk.sources.declarative.decoders.json_decoder import JsonDecoder -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.requesters.request_options.interpolated_request_options_provider import ( - InterpolatedRequestOptionsProvider, -) -from airbyte_cdk.sources.declarative.requesters.requester import HttpMethod, Requester -from airbyte_cdk.sources.message import MessageRepository, NoopMessageRepository -from airbyte_cdk.sources.streams.http import HttpClient -from airbyte_cdk.sources.streams.http.error_handlers import ErrorHandler -from airbyte_cdk.sources.types import Config, StreamSlice, StreamState -from airbyte_cdk.utils.mapping_helpers import combine_mappings - - -@dataclass -class HttpRequester(Requester): - """ - Default implementation of a Requester - - Attributes: - name (str): Name of the stream. Only used for request/response caching - url_base (Union[InterpolatedString, str]): Base url to send requests to - path (Union[InterpolatedString, str]): Path to send requests to - http_method (Union[str, HttpMethod]): HTTP method to use when sending requests - request_options_provider (Optional[InterpolatedRequestOptionsProvider]): request option provider defining the options to set on outgoing requests - authenticator (DeclarativeAuthenticator): Authenticator defining how to authenticate to the source - error_handler (Optional[ErrorHandler]): Error handler defining how to detect and handle errors - backoff_strategies (Optional[List[BackoffStrategy]]): List of backoff strategies to use when retrying requests - config (Config): The user-provided configuration as specified by the source's spec - use_cache (bool): Indicates that data should be cached for this stream - """ - - name: str - url_base: Union[InterpolatedString, str] - path: Union[InterpolatedString, str] - config: Config - parameters: InitVar[Mapping[str, Any]] - authenticator: Optional[DeclarativeAuthenticator] = None - http_method: Union[str, HttpMethod] = HttpMethod.GET - request_options_provider: Optional[InterpolatedRequestOptionsProvider] = None - error_handler: Optional[ErrorHandler] = None - disable_retries: bool = False - message_repository: MessageRepository = NoopMessageRepository() - use_cache: bool = False - _exit_on_rate_limit: bool = False - stream_response: bool = False - decoder: Decoder = field(default_factory=lambda: JsonDecoder(parameters={})) - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._url_base = InterpolatedString.create(self.url_base, parameters=parameters) - self._path = InterpolatedString.create(self.path, parameters=parameters) - if self.request_options_provider is None: - self._request_options_provider = InterpolatedRequestOptionsProvider(config=self.config, parameters=parameters) - elif isinstance(self.request_options_provider, dict): - self._request_options_provider = InterpolatedRequestOptionsProvider(config=self.config, **self.request_options_provider) - else: - self._request_options_provider = self.request_options_provider - self._authenticator = self.authenticator or NoAuth(parameters=parameters) - self._http_method = HttpMethod[self.http_method] if isinstance(self.http_method, str) else self.http_method - self.error_handler = self.error_handler - self._parameters = parameters - - if self.error_handler is not None and hasattr(self.error_handler, "backoff_strategies"): - backoff_strategies = self.error_handler.backoff_strategies - else: - backoff_strategies = None - - self._http_client = HttpClient( - name=self.name, - logger=self.logger, - error_handler=self.error_handler, - authenticator=self._authenticator, - use_cache=self.use_cache, - backoff_strategy=backoff_strategies, - disable_retries=self.disable_retries, - message_repository=self.message_repository, - ) - - @property - def exit_on_rate_limit(self) -> bool: - return self._exit_on_rate_limit - - @exit_on_rate_limit.setter - def exit_on_rate_limit(self, value: bool) -> None: - self._exit_on_rate_limit = value - - def get_authenticator(self) -> DeclarativeAuthenticator: - return self._authenticator - - def get_url_base(self) -> str: - return os.path.join(self._url_base.eval(self.config), "") - - def get_path( - self, *, stream_state: Optional[StreamState], stream_slice: Optional[StreamSlice], next_page_token: Optional[Mapping[str, Any]] - ) -> str: - kwargs = {"stream_state": stream_state, "stream_slice": stream_slice, "next_page_token": next_page_token} - path = str(self._path.eval(self.config, **kwargs)) - return path.lstrip("/") - - def get_method(self) -> HttpMethod: - return self._http_method - - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> MutableMapping[str, Any]: - return self._request_options_provider.get_request_params( - stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token - ) - - def get_request_headers( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._request_options_provider.get_request_headers( - stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token - ) - - # fixing request options provider types has a lot of dependencies - def get_request_body_data( # type: ignore - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Union[Mapping[str, Any], str]: - return ( - self._request_options_provider.get_request_body_data( - stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token - ) - or {} - ) - - # fixing request options provider types has a lot of dependencies - def get_request_body_json( # type: ignore - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Optional[Mapping[str, Any]]: - return self._request_options_provider.get_request_body_json( - stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token - ) - - @property - def logger(self) -> logging.Logger: - return logging.getLogger(f"airbyte.HttpRequester.{self.name}") - - def _get_request_options( - self, - stream_state: Optional[StreamState], - stream_slice: Optional[StreamSlice], - next_page_token: Optional[Mapping[str, Any]], - requester_method: Callable[..., Optional[Union[Mapping[str, Any], str]]], - auth_options_method: Callable[..., Optional[Union[Mapping[str, Any], str]]], - extra_options: Optional[Union[Mapping[str, Any], str]] = None, - ) -> Union[Mapping[str, Any], str]: - """ - Get the request_option from the requester, the authenticator and extra_options passed in. - Raise a ValueError if there's a key collision - Returned merged mapping otherwise - """ - return combine_mappings( - [ - requester_method(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - auth_options_method(), - extra_options, - ] - ) - - def _request_headers( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - extra_headers: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - """ - Specifies request headers. - Authentication headers will overwrite any overlapping headers returned from this method. - """ - headers = self._get_request_options( - stream_state, - stream_slice, - next_page_token, - self.get_request_headers, - self.get_authenticator().get_auth_header, - extra_headers, - ) - if isinstance(headers, str): - raise ValueError("Request headers cannot be a string") - return {str(k): str(v) for k, v in headers.items()} - - def _request_params( - self, - stream_state: Optional[StreamState], - stream_slice: Optional[StreamSlice], - next_page_token: Optional[Mapping[str, Any]], - extra_params: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - """ - Specifies the query parameters that should be set on an outgoing HTTP request given the inputs. - - E.g: you might want to define query parameters for paging if next_page_token is not None. - """ - options = self._get_request_options( - stream_state, stream_slice, next_page_token, self.get_request_params, self.get_authenticator().get_request_params, extra_params - ) - if isinstance(options, str): - raise ValueError("Request params cannot be a string") - - for k, v in options.items(): - if isinstance(v, (dict,)): - raise ValueError(f"Invalid value for `{k}` parameter. The values of request params cannot be an object.") - - return options - - def _request_body_data( - self, - stream_state: Optional[StreamState], - stream_slice: Optional[StreamSlice], - next_page_token: Optional[Mapping[str, Any]], - extra_body_data: Optional[Union[Mapping[str, Any], str]] = None, - ) -> Optional[Union[Mapping[str, Any], str]]: - """ - Specifies how to populate the body of the request with a non-JSON payload. - - If returns a ready text that it will be sent as is. - If returns a dict that it will be converted to a urlencoded form. - E.g. {"key1": "value1", "key2": "value2"} => "key1=value1&key2=value2" - - At the same time only one of the 'request_body_data' and 'request_body_json' functions can be overridden. - """ - # Warning: use self.state instead of the stream_state passed as argument! - return self._get_request_options( - stream_state, - stream_slice, - next_page_token, - self.get_request_body_data, - self.get_authenticator().get_request_body_data, - extra_body_data, - ) - - def _request_body_json( - self, - stream_state: Optional[StreamState], - stream_slice: Optional[StreamSlice], - next_page_token: Optional[Mapping[str, Any]], - extra_body_json: Optional[Mapping[str, Any]] = None, - ) -> Optional[Mapping[str, Any]]: - """ - Specifies how to populate the body of the request with a JSON payload. - - At the same time only one of the 'request_body_data' and 'request_body_json' functions can be overridden. - """ - # Warning: use self.state instead of the stream_state passed as argument! - options = self._get_request_options( - stream_state, - stream_slice, - next_page_token, - self.get_request_body_json, - self.get_authenticator().get_request_body_json, - extra_body_json, - ) - if isinstance(options, str): - raise ValueError("Request body json cannot be a string") - return options - - @classmethod - def _join_url(cls, url_base: str, path: str) -> str: - return urljoin(url_base, path) - - def send_request( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - path: Optional[str] = None, - request_headers: Optional[Mapping[str, Any]] = None, - request_params: Optional[Mapping[str, Any]] = None, - request_body_data: Optional[Union[Mapping[str, Any], str]] = None, - request_body_json: Optional[Mapping[str, Any]] = None, - log_formatter: Optional[Callable[[requests.Response], Any]] = None, - ) -> Optional[requests.Response]: - - request, response = self._http_client.send_request( - http_method=self.get_method().value, - url=self._join_url( - self.get_url_base(), - path or self.get_path(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - ), - request_kwargs={"stream": self.stream_response}, - headers=self._request_headers(stream_state, stream_slice, next_page_token, request_headers), - params=self._request_params(stream_state, stream_slice, next_page_token, request_params), - json=self._request_body_json(stream_state, stream_slice, next_page_token, request_body_json), - data=self._request_body_data(stream_state, stream_slice, next_page_token, request_body_data), - dedupe_query_params=True, - log_formatter=log_formatter, - exit_on_rate_limit=self._exit_on_rate_limit, - ) - - return response diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/__init__.py deleted file mode 100644 index cb2cfddb275c..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.requesters.paginators.default_paginator import DefaultPaginator, PaginatorTestReadDecorator -from airbyte_cdk.sources.declarative.requesters.paginators.no_pagination import NoPagination -from airbyte_cdk.sources.declarative.requesters.paginators.paginator import Paginator -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import PaginationStrategy - -__all__ = ["DefaultPaginator", "NoPagination", "PaginationStrategy", "Paginator", "PaginatorTestReadDecorator"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/default_paginator.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/default_paginator.py deleted file mode 100644 index c92e99770070..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/default_paginator.py +++ /dev/null @@ -1,242 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass, field -from typing import Any, Mapping, MutableMapping, Optional, Union - -import requests -from airbyte_cdk.sources.declarative.decoders import Decoder, JsonDecoder, PaginationDecoderDecorator -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.requesters.paginators.paginator import Paginator -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import PaginationStrategy -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType -from airbyte_cdk.sources.declarative.requesters.request_path import RequestPath -from airbyte_cdk.sources.types import Config, Record, StreamSlice, StreamState - - -@dataclass -class DefaultPaginator(Paginator): - """ - Default paginator to request pages of results with a fixed size until the pagination strategy no longer returns a next_page_token - - Examples: - 1. - * fetches up to 10 records at a time by setting the "limit" request param to 10 - * updates the request path with "{{ response._metadata.next }}" - ``` - paginator: - type: "DefaultPaginator" - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - page_token_option: - type: RequestPath - path: "location" - pagination_strategy: - type: "CursorPagination" - cursor_value: "{{ response._metadata.next }}" - page_size: 10 - ``` - - 2. - * fetches up to 5 records at a time by setting the "page_size" header to 5 - * increments a record counter and set the request parameter "offset" to the value of the counter - ``` - paginator: - type: "DefaultPaginator" - page_size_option: - type: RequestOption - inject_into: header - field_name: page_size - pagination_strategy: - type: "OffsetIncrement" - page_size: 5 - page_token_option: - option_type: "request_parameter" - field_name: "offset" - ``` - - 3. - * fetches up to 5 records at a time by setting the "page_size" request param to 5 - * increments a page counter and set the request parameter "page" to the value of the counter - ``` - paginator: - type: "DefaultPaginator" - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: page_size - pagination_strategy: - type: "PageIncrement" - page_size: 5 - page_token_option: - type: RequestOption - option_type: "request_parameter" - field_name: "page" - ``` - Attributes: - page_size_option (Optional[RequestOption]): the request option to set the page size. Cannot be injected in the path. - page_token_option (Optional[RequestPath, RequestOption]): the request option to set the page token - pagination_strategy (PaginationStrategy): Strategy defining how to get the next page token - config (Config): connection config - url_base (Union[InterpolatedString, str]): endpoint's base url - decoder (Decoder): decoder to decode the response - """ - - pagination_strategy: PaginationStrategy - config: Config - url_base: Union[InterpolatedString, str] - parameters: InitVar[Mapping[str, Any]] - decoder: Decoder = field(default_factory=lambda: PaginationDecoderDecorator(decoder=JsonDecoder(parameters={}))) - page_size_option: Optional[RequestOption] = None - page_token_option: Optional[Union[RequestPath, RequestOption]] = None - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - if self.page_size_option and not self.pagination_strategy.get_page_size(): - raise ValueError("page_size_option cannot be set if the pagination strategy does not have a page_size") - if isinstance(self.url_base, str): - self.url_base = InterpolatedString(string=self.url_base, parameters=parameters) - self._token: Optional[Any] = self.pagination_strategy.initial_token - - def next_page_token( - self, response: requests.Response, last_page_size: int, last_record: Optional[Record] - ) -> Optional[Mapping[str, Any]]: - self._token = self.pagination_strategy.next_page_token(response, last_page_size, last_record) - if self._token: - return {"next_page_token": self._token} - else: - return None - - def path(self) -> Optional[str]: - if self._token and self.page_token_option and isinstance(self.page_token_option, RequestPath): - # Replace url base to only return the path - return str(self._token).replace(self.url_base.eval(self.config), "") # type: ignore # url_base is casted to a InterpolatedString in __post_init__ - else: - return None - - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> MutableMapping[str, Any]: - return self._get_request_options(RequestOptionType.request_parameter) - - def get_request_headers( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, str]: - return self._get_request_options(RequestOptionType.header) - - def get_request_body_data( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._get_request_options(RequestOptionType.body_data) - - def get_request_body_json( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._get_request_options(RequestOptionType.body_json) - - def reset(self, reset_value: Optional[Any] = None) -> None: - if reset_value: - self.pagination_strategy.reset(reset_value=reset_value) - else: - self.pagination_strategy.reset() - self._token = self.pagination_strategy.initial_token - - def _get_request_options(self, option_type: RequestOptionType) -> MutableMapping[str, Any]: - options = {} - - if ( - self.page_token_option - and self._token is not None - and isinstance(self.page_token_option, RequestOption) - and self.page_token_option.inject_into == option_type - ): - options[self.page_token_option.field_name.eval(config=self.config)] = self._token # type: ignore # field_name is always cast to an interpolated string - if self.page_size_option and self.pagination_strategy.get_page_size() and self.page_size_option.inject_into == option_type: - options[self.page_size_option.field_name.eval(config=self.config)] = self.pagination_strategy.get_page_size() # type: ignore # field_name is always cast to an interpolated string - return options - - -class PaginatorTestReadDecorator(Paginator): - """ - In some cases, we want to limit the number of requests that are made to the backend source. This class allows for limiting the number of - pages that are queried throughout a read command. - """ - - _PAGE_COUNT_BEFORE_FIRST_NEXT_CALL = 1 - - def __init__(self, decorated: Paginator, maximum_number_of_pages: int = 5) -> None: - if maximum_number_of_pages and maximum_number_of_pages < 1: - raise ValueError(f"The maximum number of pages on a test read needs to be strictly positive. Got {maximum_number_of_pages}") - self._maximum_number_of_pages = maximum_number_of_pages - self._decorated = decorated - self._page_count = self._PAGE_COUNT_BEFORE_FIRST_NEXT_CALL - - def next_page_token( - self, response: requests.Response, last_page_size: int, last_record: Optional[Record] - ) -> Optional[Mapping[str, Any]]: - if self._page_count >= self._maximum_number_of_pages: - return None - - self._page_count += 1 - return self._decorated.next_page_token(response, last_page_size, last_record) - - def path(self) -> Optional[str]: - return self._decorated.path() - - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._decorated.get_request_params(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token) - - def get_request_headers( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, str]: - return self._decorated.get_request_headers(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token) - - def get_request_body_data( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Union[Mapping[str, Any], str]: - return self._decorated.get_request_body_data(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token) - - def get_request_body_json( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._decorated.get_request_body_json(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token) - - def reset(self, reset_value: Optional[Any] = None) -> None: - self._decorated.reset() - self._page_count = self._PAGE_COUNT_BEFORE_FIRST_NEXT_CALL diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/no_pagination.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/no_pagination.py deleted file mode 100644 index 4065902ffd09..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/no_pagination.py +++ /dev/null @@ -1,65 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Mapping, MutableMapping, Optional, Union - -import requests -from airbyte_cdk.sources.declarative.requesters.paginators.paginator import Paginator -from airbyte_cdk.sources.types import Record, StreamSlice, StreamState - - -@dataclass -class NoPagination(Paginator): - """ - Pagination implementation that never returns a next page. - """ - - parameters: InitVar[Mapping[str, Any]] - - def path(self) -> Optional[str]: - return None - - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> MutableMapping[str, Any]: - return {} - - def get_request_headers( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, str]: - return {} - - def get_request_body_data( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Union[Mapping[str, Any], str]: - return {} - - def get_request_body_json( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return {} - - def next_page_token(self, response: requests.Response, last_page_size: int, last_record: Optional[Record]) -> Mapping[str, Any]: - return {} - - def reset(self, reset_value: Optional[Any] = None) -> None: - # No state to reset - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/paginator.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/paginator.py deleted file mode 100644 index aebc8241a2d0..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/paginator.py +++ /dev/null @@ -1,52 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import ABC, abstractmethod -from dataclasses import dataclass -from typing import Any, Mapping, Optional - -import requests -from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import RequestOptionsProvider -from airbyte_cdk.sources.types import Record - - -@dataclass -class Paginator(ABC, RequestOptionsProvider): - """ - Defines the token to use to fetch the next page of records from the API. - - If needed, the Paginator will set request options to be set on the HTTP request to fetch the next page of records. - If the next_page_token is the path to the next page of records, then it should be accessed through the `path` method - """ - - @abstractmethod - def reset(self, reset_value: Optional[Any] = None) -> None: - """ - Reset the pagination's inner state - """ - - @abstractmethod - def next_page_token( - self, response: requests.Response, last_page_size: int, last_record: Optional[Record] - ) -> Optional[Mapping[str, Any]]: - """ - Returns the next_page_token to use to fetch the next page of records. - - :param response: the response to process - :param last_page_size: the number of records read from the response - :param last_record: the last record extracted from the response - :return: A mapping {"next_page_token": } for the next page from the input response object. Returning None means there are no more pages to read in this response. - """ - pass - - @abstractmethod - def path(self) -> Optional[str]: - """ - Returns the URL path to hit to fetch the next page of records - - e.g: if you wanted to hit https://myapi.com/v1/some_entity then this will return "some_entity" - - :return: path to hit to fetch the next request. Returning None means the path is not defined by the next_page_token - """ - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/__init__.py deleted file mode 100644 index 03e5ecae532e..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.cursor_pagination_strategy import CursorPaginationStrategy -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.offset_increment import OffsetIncrement -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.page_increment import PageIncrement -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.stop_condition import ( - CursorStopCondition, - StopConditionPaginationStrategyDecorator, -) - -__all__ = [ - "CursorPaginationStrategy", - "CursorStopCondition", - "OffsetIncrement", - "PageIncrement", - "StopConditionPaginationStrategyDecorator", -] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/cursor_pagination_strategy.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/cursor_pagination_strategy.py deleted file mode 100644 index 7ba3c1d096ac..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/cursor_pagination_strategy.py +++ /dev/null @@ -1,81 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass, field -from typing import Any, Dict, Mapping, Optional, Union - -import requests -from airbyte_cdk.sources.declarative.decoders import Decoder, JsonDecoder, PaginationDecoderDecorator -from airbyte_cdk.sources.declarative.interpolation.interpolated_boolean import InterpolatedBoolean -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import PaginationStrategy -from airbyte_cdk.sources.types import Config, Record - - -@dataclass -class CursorPaginationStrategy(PaginationStrategy): - """ - Pagination strategy that evaluates an interpolated string to define the next page token - - Attributes: - page_size (Optional[int]): the number of records to request - cursor_value (Union[InterpolatedString, str]): template string evaluating to the cursor value - config (Config): connection config - stop_condition (Optional[InterpolatedBoolean]): template string evaluating when to stop paginating - decoder (Decoder): decoder to decode the response - """ - - cursor_value: Union[InterpolatedString, str] - config: Config - parameters: InitVar[Mapping[str, Any]] - page_size: Optional[int] = None - stop_condition: Optional[Union[InterpolatedBoolean, str]] = None - decoder: Decoder = field(default_factory=lambda: PaginationDecoderDecorator(decoder=JsonDecoder(parameters={}))) - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._initial_cursor = None - if isinstance(self.cursor_value, str): - self._cursor_value = InterpolatedString.create(self.cursor_value, parameters=parameters) - else: - self._cursor_value = self.cursor_value - if isinstance(self.stop_condition, str): - self._stop_condition: Optional[InterpolatedBoolean] = InterpolatedBoolean(condition=self.stop_condition, parameters=parameters) - else: - self._stop_condition = self.stop_condition - - @property - def initial_token(self) -> Optional[Any]: - return self._initial_cursor - - def next_page_token(self, response: requests.Response, last_page_size: int, last_record: Optional[Record]) -> Optional[Any]: - decoded_response = next(self.decoder.decode(response)) - - # The default way that link is presented in requests.Response is a string of various links (last, next, etc). This - # is not indexable or useful for parsing the cursor, so we replace it with the link dictionary from response.links - headers: Dict[str, Any] = dict(response.headers) - headers["link"] = response.links - if self._stop_condition: - should_stop = self._stop_condition.eval( - self.config, - response=decoded_response, - headers=headers, - last_record=last_record, - last_page_size=last_page_size, - ) - if should_stop: - return None - token = self._cursor_value.eval( - config=self.config, - response=decoded_response, - headers=headers, - last_record=last_record, - last_page_size=last_page_size, - ) - return token if token else None - - def reset(self, reset_value: Optional[Any] = None) -> None: - self._initial_cursor = reset_value - - def get_page_size(self) -> Optional[int]: - return self.page_size diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/offset_increment.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/offset_increment.py deleted file mode 100644 index 295b09082b56..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/offset_increment.py +++ /dev/null @@ -1,82 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass, field -from typing import Any, Mapping, Optional, Union - -import requests -from airbyte_cdk.sources.declarative.decoders import Decoder, JsonDecoder, PaginationDecoderDecorator -from airbyte_cdk.sources.declarative.interpolation import InterpolatedString -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import PaginationStrategy -from airbyte_cdk.sources.types import Config, Record - - -@dataclass -class OffsetIncrement(PaginationStrategy): - """ - Pagination strategy that returns the number of records reads so far and returns it as the next page token - Examples: - # page_size to be a constant integer value - pagination_strategy: - type: OffsetIncrement - page_size: 2 - - # page_size to be a constant string value - pagination_strategy: - type: OffsetIncrement - page_size: "2" - - # page_size to be an interpolated string value - pagination_strategy: - type: OffsetIncrement - page_size: "{{ parameters['items_per_page'] }}" - - Attributes: - page_size (InterpolatedString): the number of records to request - """ - - config: Config - page_size: Optional[Union[str, int]] - parameters: InitVar[Mapping[str, Any]] - decoder: Decoder = field(default_factory=lambda: PaginationDecoderDecorator(decoder=JsonDecoder(parameters={}))) - inject_on_first_request: bool = False - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._offset = 0 - page_size = str(self.page_size) if isinstance(self.page_size, int) else self.page_size - if page_size: - self._page_size: Optional[InterpolatedString] = InterpolatedString(page_size, parameters=parameters) - else: - self._page_size = None - - @property - def initial_token(self) -> Optional[Any]: - if self.inject_on_first_request: - return self._offset - return None - - def next_page_token(self, response: requests.Response, last_page_size: int, last_record: Optional[Record]) -> Optional[Any]: - decoded_response = next(self.decoder.decode(response)) - - # Stop paginating when there are fewer records than the page size or the current page has no records - if (self._page_size and last_page_size < self._page_size.eval(self.config, response=decoded_response)) or last_page_size == 0: - return None - else: - self._offset += last_page_size - return self._offset - - def reset(self, reset_value: Optional[Any] = 0) -> None: - if not isinstance(reset_value, int): - raise ValueError(f"Reset value {reset_value} for OffsetIncrement pagination strategy was not an integer") - else: - self._offset = reset_value - - def get_page_size(self) -> Optional[int]: - if self._page_size: - page_size = self._page_size.eval(self.config) - if not isinstance(page_size, int): - raise Exception(f"{page_size} is of type {type(page_size)}. Expected {int}") - return page_size - else: - return None diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/page_increment.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/page_increment.py deleted file mode 100644 index 978ac1abaafd..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/page_increment.py +++ /dev/null @@ -1,63 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Mapping, Optional, Union - -import requests -from airbyte_cdk.sources.declarative.interpolation import InterpolatedString -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import PaginationStrategy -from airbyte_cdk.sources.types import Config, Record - - -@dataclass -class PageIncrement(PaginationStrategy): - """ - Pagination strategy that returns the number of pages reads so far and returns it as the next page token - - Attributes: - page_size (int): the number of records to request - start_from_page (int): number of the initial page - """ - - config: Config - page_size: Optional[Union[str, int]] - parameters: InitVar[Mapping[str, Any]] - start_from_page: int = 0 - inject_on_first_request: bool = False - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._page = self.start_from_page - if isinstance(self.page_size, int) or (self.page_size is None): - self._page_size = self.page_size - else: - page_size = InterpolatedString(self.page_size, parameters=parameters).eval(self.config) - if not isinstance(page_size, int): - raise Exception(f"{page_size} is of type {type(page_size)}. Expected {int}") - self._page_size = page_size - - @property - def initial_token(self) -> Optional[Any]: - if self.inject_on_first_request: - return self._page - return None - - def next_page_token(self, response: requests.Response, last_page_size: int, last_record: Optional[Record]) -> Optional[Any]: - # Stop paginating when there are fewer records than the page size or the current page has no records - if (self._page_size and last_page_size < self._page_size) or last_page_size == 0: - return None - else: - self._page += 1 - return self._page - - def reset(self, reset_value: Optional[Any] = None) -> None: - if reset_value is None: - self._page = self.start_from_page - elif not isinstance(reset_value, int): - raise ValueError(f"Reset value {reset_value} for PageIncrement pagination strategy was not an integer") - else: - self._page = reset_value - - def get_page_size(self) -> Optional[int]: - return self._page_size diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/pagination_strategy.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/pagination_strategy.py deleted file mode 100644 index 135eb4812c6f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/pagination_strategy.py +++ /dev/null @@ -1,46 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import abstractmethod -from dataclasses import dataclass -from typing import Any, Optional - -import requests -from airbyte_cdk.sources.types import Record - - -@dataclass -class PaginationStrategy: - """ - Defines how to get the next page token - """ - - @property - @abstractmethod - def initial_token(self) -> Optional[Any]: - """ - Return the initial value of the token - """ - - @abstractmethod - def next_page_token(self, response: requests.Response, last_page_size: int, last_record: Optional[Record]) -> Optional[Any]: - """ - :param response: response to process - :param last_page_size: the number of records read from the response - :param last_record: the last record extracted from the response - :return: next page token. Returns None if there are no more pages to fetch - """ - pass - - @abstractmethod - def reset(self, reset_value: Optional[Any] = None) -> None: - """ - Reset the pagination's inner state - """ - - @abstractmethod - def get_page_size(self) -> Optional[int]: - """ - :return: page size: The number of records to fetch in a page. Returns None if unspecified - """ diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/stop_condition.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/stop_condition.py deleted file mode 100644 index ca79bfd39ac7..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/paginators/strategies/stop_condition.py +++ /dev/null @@ -1,53 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import ABC, abstractmethod -from typing import Any, Optional - -import requests -from airbyte_cdk.sources.declarative.incremental.declarative_cursor import DeclarativeCursor -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import PaginationStrategy -from airbyte_cdk.sources.types import Record - - -class PaginationStopCondition(ABC): - @abstractmethod - def is_met(self, record: Record) -> bool: - """ - Given a condition is met, the pagination will stop - - :param record: a record used to evaluate the condition - """ - raise NotImplementedError() - - -class CursorStopCondition(PaginationStopCondition): - def __init__(self, cursor: DeclarativeCursor): - self._cursor = cursor - - def is_met(self, record: Record) -> bool: - return not self._cursor.should_be_synced(record) - - -class StopConditionPaginationStrategyDecorator(PaginationStrategy): - def __init__(self, _delegate: PaginationStrategy, stop_condition: PaginationStopCondition): - self._delegate = _delegate - self._stop_condition = stop_condition - - def next_page_token(self, response: requests.Response, last_page_size: int, last_record: Optional[Record]) -> Optional[Any]: - # We evaluate in reverse order because the assumption is that most of the APIs using data feed structure will return records in - # descending order. In terms of performance/memory, we return the records lazily - if last_record and self._stop_condition.is_met(last_record): - return None - return self._delegate.next_page_token(response, last_page_size, last_record) - - def reset(self) -> None: - self._delegate.reset() - - def get_page_size(self) -> Optional[int]: - return self._delegate.get_page_size() - - @property - def initial_token(self) -> Optional[Any]: - return self._delegate.initial_token diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_option.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_option.py deleted file mode 100644 index d13d2056681d..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_option.py +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from enum import Enum -from typing import Any, Mapping, Union - -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString - - -class RequestOptionType(Enum): - """ - Describes where to set a value on a request - """ - - request_parameter = "request_parameter" - header = "header" - body_data = "body_data" - body_json = "body_json" - - -@dataclass -class RequestOption: - """ - Describes an option to set on a request - - Attributes: - field_name (str): Describes the name of the parameter to inject - inject_into (RequestOptionType): Describes where in the HTTP request to inject the parameter - """ - - field_name: Union[InterpolatedString, str] - inject_into: RequestOptionType - parameters: InitVar[Mapping[str, Any]] - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self.field_name = InterpolatedString.create(self.field_name, parameters=parameters) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/__init__.py deleted file mode 100644 index c6540e939ed6..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.requesters.request_options.datetime_based_request_options_provider import ( - DatetimeBasedRequestOptionsProvider, -) -from airbyte_cdk.sources.declarative.requesters.request_options.default_request_options_provider import DefaultRequestOptionsProvider -from airbyte_cdk.sources.declarative.requesters.request_options.interpolated_request_options_provider import ( - InterpolatedRequestOptionsProvider, -) -from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import RequestOptionsProvider - -__all__ = ["DatetimeBasedRequestOptionsProvider", "DefaultRequestOptionsProvider", "InterpolatedRequestOptionsProvider", "RequestOptionsProvider"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/datetime_based_request_options_provider.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/datetime_based_request_options_provider.py deleted file mode 100644 index d9e86afcffb5..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/datetime_based_request_options_provider.py +++ /dev/null @@ -1,78 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Mapping, MutableMapping, Optional, Union - -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType -from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import RequestOptionsProvider -from airbyte_cdk.sources.types import Config, StreamSlice, StreamState - - -@dataclass -class DatetimeBasedRequestOptionsProvider(RequestOptionsProvider): - """ - Request options provider that extracts fields from the stream_slice and injects them into the respective location in the - outbound request being made - """ - - config: Config - parameters: InitVar[Mapping[str, Any]] - start_time_option: Optional[RequestOption] = None - end_time_option: Optional[RequestOption] = None - partition_field_start: Optional[str] = None - partition_field_end: Optional[str] = None - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._partition_field_start = InterpolatedString.create(self.partition_field_start or "start_time", parameters=parameters) - self._partition_field_end = InterpolatedString.create(self.partition_field_end or "end_time", parameters=parameters) - - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._get_request_options(RequestOptionType.request_parameter, stream_slice) - - def get_request_headers( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._get_request_options(RequestOptionType.header, stream_slice) - - def get_request_body_data( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Union[Mapping[str, Any], str]: - return self._get_request_options(RequestOptionType.body_data, stream_slice) - - def get_request_body_json( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._get_request_options(RequestOptionType.body_json, stream_slice) - - def _get_request_options(self, option_type: RequestOptionType, stream_slice: Optional[StreamSlice]) -> Mapping[str, Any]: - options: MutableMapping[str, Any] = {} - if not stream_slice: - return options - if self.start_time_option and self.start_time_option.inject_into == option_type: - options[self.start_time_option.field_name.eval(config=self.config)] = stream_slice.get( # type: ignore # field_name is always casted to an interpolated string - self._partition_field_start.eval(self.config) - ) - if self.end_time_option and self.end_time_option.inject_into == option_type: - options[self.end_time_option.field_name.eval(config=self.config)] = stream_slice.get(self._partition_field_end.eval(self.config)) # type: ignore # field_name is always casted to an interpolated string - return options diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/default_request_options_provider.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/default_request_options_provider.py deleted file mode 100644 index 42d8ee70a4b4..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/default_request_options_provider.py +++ /dev/null @@ -1,58 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Mapping, Optional, Union - -from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import RequestOptionsProvider -from airbyte_cdk.sources.types import StreamSlice, StreamState - - -@dataclass -class DefaultRequestOptionsProvider(RequestOptionsProvider): - """ - Request options provider that extracts fields from the stream_slice and injects them into the respective location in the - outbound request being made - """ - - parameters: InitVar[Mapping[str, Any]] - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - pass - - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return {} - - def get_request_headers( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return {} - - def get_request_body_data( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Union[Mapping[str, Any], str]: - return {} - - def get_request_body_json( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return {} diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_nested_request_input_provider.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_nested_request_input_provider.py deleted file mode 100644 index 4a6c7a860e17..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_nested_request_input_provider.py +++ /dev/null @@ -1,48 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass, field -from typing import Any, Mapping, Optional, Union - -from airbyte_cdk.sources.declarative.interpolation.interpolated_nested_mapping import InterpolatedNestedMapping, NestedMapping -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.types import Config, StreamSlice, StreamState - - -@dataclass -class InterpolatedNestedRequestInputProvider: - """ - Helper class that generically performs string interpolation on a provided deeply nested dictionary or string input - """ - - parameters: InitVar[Mapping[str, Any]] - request_inputs: Optional[Union[str, NestedMapping]] = field(default=None) - config: Config = field(default_factory=dict) - _interpolator: Optional[Union[InterpolatedString, InterpolatedNestedMapping]] = field(init=False, repr=False, default=None) - _request_inputs: Optional[Union[str, NestedMapping]] = field(init=False, repr=False, default=None) - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - - self._request_inputs = self.request_inputs or {} - if isinstance(self._request_inputs, str): - self._interpolator = InterpolatedString(self._request_inputs, default="", parameters=parameters) - else: - self._interpolator = InterpolatedNestedMapping(self._request_inputs, parameters=parameters) - - def eval_request_inputs( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - """ - Returns the request inputs to set on an outgoing HTTP request - - :param stream_state: The stream state - :param stream_slice: The stream slice - :param next_page_token: The pagination token - :return: The request inputs to set on an outgoing HTTP request - """ - kwargs = {"stream_state": stream_state, "stream_slice": stream_slice, "next_page_token": next_page_token} - return self._interpolator.eval(self.config, **kwargs) # type: ignore # self._interpolator is always initialized with a value and will not be None diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_input_provider.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_input_provider.py deleted file mode 100644 index 868cd84208ef..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_input_provider.py +++ /dev/null @@ -1,59 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass, field -from typing import Any, Mapping, Optional, Tuple, Type, Union - -from airbyte_cdk.sources.declarative.interpolation.interpolated_mapping import InterpolatedMapping -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.types import Config, StreamSlice, StreamState - - -@dataclass -class InterpolatedRequestInputProvider: - """ - Helper class that generically performs string interpolation on the provided dictionary or string input - """ - - parameters: InitVar[Mapping[str, Any]] - request_inputs: Optional[Union[str, Mapping[str, str]]] = field(default=None) - config: Config = field(default_factory=dict) - _interpolator: Optional[Union[InterpolatedString, InterpolatedMapping]] = field(init=False, repr=False, default=None) - _request_inputs: Optional[Union[str, Mapping[str, str]]] = field(init=False, repr=False, default=None) - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - - self._request_inputs = self.request_inputs or {} - if isinstance(self._request_inputs, str): - self._interpolator = InterpolatedString(self._request_inputs, default="", parameters=parameters) - else: - self._interpolator = InterpolatedMapping(self._request_inputs, parameters=parameters) - - def eval_request_inputs( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - valid_key_types: Optional[Tuple[Type[Any]]] = None, - valid_value_types: Optional[Tuple[Type[Any], ...]] = None, - ) -> Mapping[str, Any]: - """ - Returns the request inputs to set on an outgoing HTTP request - - :param stream_state: The stream state - :param stream_slice: The stream slice - :param next_page_token: The pagination token - :param valid_key_types: A tuple of types that the interpolator should allow - :param valid_value_types: A tuple of types that the interpolator should allow - :return: The request inputs to set on an outgoing HTTP request - """ - kwargs = {"stream_state": stream_state, "stream_slice": stream_slice, "next_page_token": next_page_token} - interpolated_value = self._interpolator.eval( # type: ignore # self._interpolator is always initialized with a value and will not be None - self.config, valid_key_types=valid_key_types, valid_value_types=valid_value_types, **kwargs - ) - - if isinstance(interpolated_value, dict): - non_null_tokens = {k: v for k, v in interpolated_value.items() if v is not None} - return non_null_tokens - return interpolated_value # type: ignore[no-any-return] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_options_provider.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_options_provider.py deleted file mode 100644 index 6fe995bc7677..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_options_provider.py +++ /dev/null @@ -1,111 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass, field -from typing import Any, Mapping, MutableMapping, Optional, Union - -from airbyte_cdk.sources.declarative.interpolation.interpolated_nested_mapping import NestedMapping -from airbyte_cdk.sources.declarative.requesters.request_options.interpolated_nested_request_input_provider import ( - InterpolatedNestedRequestInputProvider, -) -from airbyte_cdk.sources.declarative.requesters.request_options.interpolated_request_input_provider import InterpolatedRequestInputProvider -from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import RequestOptionsProvider -from airbyte_cdk.sources.types import Config, StreamSlice, StreamState - -RequestInput = Union[str, Mapping[str, str]] -ValidRequestTypes = (str, list) - - -@dataclass -class InterpolatedRequestOptionsProvider(RequestOptionsProvider): - """ - Defines the request options to set on an outgoing HTTP request by evaluating `InterpolatedMapping`s - - Attributes: - config (Config): The user-provided configuration as specified by the source's spec - request_parameters (Union[str, Mapping[str, str]]): The request parameters to set on an outgoing HTTP request - request_headers (Union[str, Mapping[str, str]]): The request headers to set on an outgoing HTTP request - request_body_data (Union[str, Mapping[str, str]]): The body data to set on an outgoing HTTP request - request_body_json (Union[str, Mapping[str, str]]): The json content to set on an outgoing HTTP request - """ - - parameters: InitVar[Mapping[str, Any]] - config: Config = field(default_factory=dict) - request_parameters: Optional[RequestInput] = None - request_headers: Optional[RequestInput] = None - request_body_data: Optional[RequestInput] = None - request_body_json: Optional[NestedMapping] = None - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - if self.request_parameters is None: - self.request_parameters = {} - if self.request_headers is None: - self.request_headers = {} - if self.request_body_data is None: - self.request_body_data = {} - if self.request_body_json is None: - self.request_body_json = {} - - if self.request_body_json and self.request_body_data: - raise ValueError("RequestOptionsProvider should only contain either 'request_body_data' or 'request_body_json' not both") - - self._parameter_interpolator = InterpolatedRequestInputProvider( - config=self.config, request_inputs=self.request_parameters, parameters=parameters - ) - self._headers_interpolator = InterpolatedRequestInputProvider( - config=self.config, request_inputs=self.request_headers, parameters=parameters - ) - self._body_data_interpolator = InterpolatedRequestInputProvider( - config=self.config, request_inputs=self.request_body_data, parameters=parameters - ) - self._body_json_interpolator = InterpolatedNestedRequestInputProvider( - config=self.config, request_inputs=self.request_body_json, parameters=parameters - ) - - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> MutableMapping[str, Any]: - interpolated_value = self._parameter_interpolator.eval_request_inputs( - stream_state, stream_slice, next_page_token, valid_key_types=(str,), valid_value_types=ValidRequestTypes - ) - if isinstance(interpolated_value, dict): - return interpolated_value - return {} - - def get_request_headers( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._headers_interpolator.eval_request_inputs(stream_state, stream_slice, next_page_token) - - def get_request_body_data( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Union[Mapping[str, Any], str]: - return self._body_data_interpolator.eval_request_inputs( - stream_state, - stream_slice, - next_page_token, - valid_key_types=(str,), - valid_value_types=ValidRequestTypes, - ) - - def get_request_body_json( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - return self._body_json_interpolator.eval_request_inputs(stream_state, stream_slice, next_page_token) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/request_options_provider.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/request_options_provider.py deleted file mode 100644 index f0a94ecb91ab..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_options/request_options_provider.py +++ /dev/null @@ -1,79 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import abstractmethod -from dataclasses import dataclass -from typing import Any, Mapping, Optional, Union - -from airbyte_cdk.sources.types import StreamSlice, StreamState - - -@dataclass -class RequestOptionsProvider: - """ - Defines the request options to set on an outgoing HTTP request - - Options can be passed by - - request parameter - - request headers - - body data - - json content - """ - - @abstractmethod - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - """ - Specifies the query parameters that should be set on an outgoing HTTP request given the inputs. - - E.g: you might want to define query parameters for paging if next_page_token is not None. - """ - pass - - @abstractmethod - def get_request_headers( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - """Return any non-auth headers. Authentication headers will overwrite any overlapping headers returned from this method.""" - - @abstractmethod - def get_request_body_data( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Union[Mapping[str, Any], str]: - """ - Specifies how to populate the body of the request with a non-JSON payload. - - If returns a ready text that it will be sent as is. - If returns a dict that it will be converted to a urlencoded form. - E.g. {"key1": "value1", "key2": "value2"} => "key1=value1&key2=value2" - - At the same time only one of the 'request_body_data' and 'request_body_json' functions can be overridden. - """ - - @abstractmethod - def get_request_body_json( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - """ - Specifies how to populate the body of the request with a JSON payload. - - At the same time only one of the 'request_body_data' and 'request_body_json' functions can be overridden. - """ diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_path.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_path.py deleted file mode 100644 index 378ea6220c4f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/request_path.py +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Mapping - - -@dataclass -class RequestPath: - """ - Describes that a component value should be inserted into the path - """ - - parameters: InitVar[Mapping[str, Any]] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/requester.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/requester.py deleted file mode 100644 index ef702216bb31..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/requester.py +++ /dev/null @@ -1,135 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import abstractmethod -from enum import Enum -from typing import Any, Callable, Mapping, MutableMapping, Optional, Union - -import requests -from airbyte_cdk.sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator -from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import RequestOptionsProvider -from airbyte_cdk.sources.types import StreamSlice, StreamState - - -class HttpMethod(Enum): - """ - Http Method to use when submitting an outgoing HTTP request - """ - - DELETE = "DELETE" - GET = "GET" - PATCH = "PATCH" - POST = "POST" - - -class Requester(RequestOptionsProvider): - @abstractmethod - def get_authenticator(self) -> DeclarativeAuthenticator: - """ - Specifies the authenticator to use when submitting requests - """ - pass - - @abstractmethod - def get_url_base(self) -> str: - """ - :return: URL base for the API endpoint e.g: if you wanted to hit https://myapi.com/v1/some_entity then this should return "https://myapi.com/v1/" - """ - - @abstractmethod - def get_path( - self, - *, - stream_state: Optional[StreamState], - stream_slice: Optional[StreamSlice], - next_page_token: Optional[Mapping[str, Any]], - ) -> str: - """ - Returns the URL path for the API endpoint e.g: if you wanted to hit https://myapi.com/v1/some_entity then this should return "some_entity" - """ - - @abstractmethod - def get_method(self) -> HttpMethod: - """ - Specifies the HTTP method to use - """ - - @abstractmethod - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> MutableMapping[str, Any]: - """ - Specifies the query parameters that should be set on an outgoing HTTP request given the inputs. - - E.g: you might want to define query parameters for paging if next_page_token is not None. - """ - - @abstractmethod - def get_request_headers( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - """ - Return any non-auth headers. Authentication headers will overwrite any overlapping headers returned from this method. - """ - - @abstractmethod - def get_request_body_data( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Union[Mapping[str, Any], str]: - """ - Specifies how to populate the body of the request with a non-JSON payload. - - If returns a ready text that it will be sent as is. - If returns a dict that it will be converted to a urlencoded form. - E.g. {"key1": "value1", "key2": "value2"} => "key1=value1&key2=value2" - - At the same time only one of the 'request_body_data' and 'request_body_json' functions can be overridden. - """ - - @abstractmethod - def get_request_body_json( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - """ - Specifies how to populate the body of the request with a JSON payload. - - At the same time only one of the 'request_body_data' and 'request_body_json' functions can be overridden. - """ - - @abstractmethod - def send_request( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - path: Optional[str] = None, - request_headers: Optional[Mapping[str, Any]] = None, - request_params: Optional[Mapping[str, Any]] = None, - request_body_data: Optional[Union[Mapping[str, Any], str]] = None, - request_body_json: Optional[Mapping[str, Any]] = None, - log_formatter: Optional[Callable[[requests.Response], Any]] = None, - ) -> Optional[requests.Response]: - """ - Sends a request and returns the response. Might return no response if the error handler chooses to ignore the response or throw an exception in case of an error. - If path is set, the path configured on the requester itself is ignored. - If header, params and body are set, they are merged with the ones configured on the requester itself. - - If a log formatter is provided, it's used to log the performed request and response. If it's not provided, no logging is performed. - """ diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/retrievers/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/retrievers/__init__.py deleted file mode 100644 index 9ec5017fb38c..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/retrievers/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.retrievers.retriever import Retriever -from airbyte_cdk.sources.declarative.retrievers.simple_retriever import SimpleRetriever, SimpleRetrieverTestReadDecorator -from airbyte_cdk.sources.declarative.retrievers.async_retriever import AsyncRetriever - -__all__ = ["Retriever", "SimpleRetriever", "SimpleRetrieverTestReadDecorator", "AsyncRetriever"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/retrievers/async_retriever.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/retrievers/async_retriever.py deleted file mode 100644 index a9f9686e7691..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/retrievers/async_retriever.py +++ /dev/null @@ -1,115 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - - -from dataclasses import InitVar, dataclass, field -from typing import Any, Callable, Iterable, Mapping, Optional - -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.declarative.async_job.job_orchestrator import AsyncJobOrchestrator, AsyncPartition -from airbyte_cdk.sources.declarative.extractors.record_selector import RecordSelector -from airbyte_cdk.sources.declarative.partition_routers import SinglePartitionRouter -from airbyte_cdk.sources.declarative.retrievers import Retriever -from airbyte_cdk.sources.declarative.stream_slicers import StreamSlicer -from airbyte_cdk.sources.source import ExperimentalClassWarning -from airbyte_cdk.sources.streams.core import StreamData -from airbyte_cdk.sources.types import Config, StreamSlice, StreamState -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from deprecated.classic import deprecated - - -@deprecated("This class is experimental. Use at your own risk.", category=ExperimentalClassWarning) -@dataclass -class AsyncRetriever(Retriever): - config: Config - parameters: InitVar[Mapping[str, Any]] - job_orchestrator_factory: Callable[[Iterable[StreamSlice]], AsyncJobOrchestrator] - record_selector: RecordSelector - stream_slicer: StreamSlicer = field(default_factory=lambda: SinglePartitionRouter(parameters={})) - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._job_orchestrator_factory = self.job_orchestrator_factory - self.__job_orchestrator: Optional[AsyncJobOrchestrator] = None - self._parameters = parameters - - @property - def state(self) -> StreamState: - """ - As a first iteration for sendgrid, there is no state to be managed - """ - return {} - - @state.setter - def state(self, value: StreamState) -> None: - """ - As a first iteration for sendgrid, there is no state to be managed - """ - pass - - @property - def _job_orchestrator(self) -> AsyncJobOrchestrator: - if not self.__job_orchestrator: - raise AirbyteTracedException( - message="Invalid state within AsyncJobRetriever. Please contact Airbyte Support", - internal_message="AsyncPartitionRepository is expected to be accessed only after `stream_slices`", - failure_type=FailureType.system_error, - ) - - return self.__job_orchestrator - - def _get_stream_state(self) -> StreamState: - """ - Gets the current state of the stream. - - Returns: - StreamState: Mapping[str, Any] - """ - - return self.state - - def _validate_and_get_stream_slice_partition(self, stream_slice: Optional[StreamSlice] = None) -> AsyncPartition: - """ - Validates the stream_slice argument and returns the partition from it. - - Args: - stream_slice (Optional[StreamSlice]): The stream slice to validate and extract the partition from. - - Returns: - AsyncPartition: The partition extracted from the stream_slice. - - Raises: - AirbyteTracedException: If the stream_slice is not an instance of StreamSlice or if the partition is not present in the stream_slice. - - """ - if not isinstance(stream_slice, StreamSlice) or "partition" not in stream_slice.partition: - raise AirbyteTracedException( - message="Invalid arguments to AsyncJobRetriever.read_records: stream_slice is no optional. Please contact Airbyte Support", - failure_type=FailureType.system_error, - ) - return stream_slice["partition"] # type: ignore # stream_slice["partition"] has been added as an AsyncPartition as part of stream_slices - - def stream_slices(self) -> Iterable[Optional[StreamSlice]]: - slices = self.stream_slicer.stream_slices() - self.__job_orchestrator = self._job_orchestrator_factory(slices) - - for completed_partition in self._job_orchestrator.create_and_get_completed_partitions(): - yield StreamSlice( - partition=dict(completed_partition.stream_slice.partition) | {"partition": completed_partition}, - cursor_slice=completed_partition.stream_slice.cursor_slice, - ) - - def read_records( - self, - records_schema: Mapping[str, Any], - stream_slice: Optional[StreamSlice] = None, - ) -> Iterable[StreamData]: - - stream_state: StreamState = self._get_stream_state() - partition: AsyncPartition = self._validate_and_get_stream_slice_partition(stream_slice) - records: Iterable[Mapping[str, Any]] = self._job_orchestrator.fetch_records(partition) - - yield from self.record_selector.filter_and_transform( - all_data=records, - stream_state=stream_state, - records_schema=records_schema, - stream_slice=stream_slice, - ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/retrievers/retriever.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/retrievers/retriever.py deleted file mode 100644 index 155de5782aa0..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/retrievers/retriever.py +++ /dev/null @@ -1,54 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import abstractmethod -from typing import Any, Iterable, Mapping, Optional - -from airbyte_cdk.sources.declarative.incremental.per_partition_cursor import StreamSlice -from airbyte_cdk.sources.streams.core import StreamData -from airbyte_cdk.sources.types import StreamState - - -class Retriever: - """ - Responsible for fetching a stream's records from an HTTP API source. - """ - - @abstractmethod - def read_records( - self, - records_schema: Mapping[str, Any], - stream_slice: Optional[StreamSlice] = None, - ) -> Iterable[StreamData]: - """ - Fetch a stream's records from an HTTP API source - - :param records_schema: json schema to describe record - :param stream_slice: The stream slice to read data for - :return: The records read from the API source - """ - - @abstractmethod - def stream_slices(self) -> Iterable[Optional[StreamSlice]]: - """Returns the stream slices""" - - @property - @abstractmethod - def state(self) -> StreamState: - """State getter, should return state in form that can serialized to a string and send to the output - as a STATE AirbyteMessage. - - A good example of a state is a cursor_value: - { - self.cursor_field: "cursor_value" - } - - State should try to be as small as possible but at the same time descriptive enough to restore - syncing process from the point where it stopped. - """ - - @state.setter - @abstractmethod - def state(self, value: StreamState) -> None: - """State setter, accept state serialized by state getter.""" diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/retrievers/simple_retriever.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/retrievers/simple_retriever.py deleted file mode 100644 index 99639d8467ee..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/retrievers/simple_retriever.py +++ /dev/null @@ -1,506 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -from dataclasses import InitVar, dataclass, field -from functools import partial -from itertools import islice -from typing import Any, Callable, Iterable, List, Mapping, MutableMapping, Optional, Set, Tuple, Union - -import requests -from airbyte_cdk.models import AirbyteMessage -from airbyte_cdk.sources.declarative.extractors.http_selector import HttpSelector -from airbyte_cdk.sources.declarative.incremental import ResumableFullRefreshCursor -from airbyte_cdk.sources.declarative.incremental.declarative_cursor import DeclarativeCursor -from airbyte_cdk.sources.declarative.interpolation import InterpolatedString -from airbyte_cdk.sources.declarative.partition_routers.single_partition_router import SinglePartitionRouter -from airbyte_cdk.sources.declarative.requesters.paginators.no_pagination import NoPagination -from airbyte_cdk.sources.declarative.requesters.paginators.paginator import Paginator -from airbyte_cdk.sources.declarative.requesters.request_options import DefaultRequestOptionsProvider, RequestOptionsProvider -from airbyte_cdk.sources.declarative.requesters.requester import Requester -from airbyte_cdk.sources.declarative.retrievers.retriever import Retriever -from airbyte_cdk.sources.declarative.stream_slicers.stream_slicer import StreamSlicer -from airbyte_cdk.sources.http_logger import format_http_message -from airbyte_cdk.sources.streams.core import StreamData -from airbyte_cdk.sources.types import Config, Record, StreamSlice, StreamState -from airbyte_cdk.utils.mapping_helpers import combine_mappings - -FULL_REFRESH_SYNC_COMPLETE_KEY = "__ab_full_refresh_sync_complete" - - -@dataclass -class SimpleRetriever(Retriever): - """ - Retrieves records by synchronously sending requests to fetch records. - - The retriever acts as an orchestrator between the requester, the record selector, the paginator, and the stream slicer. - - For each stream slice, submit requests until there are no more pages of records to fetch. - - This retriever currently inherits from HttpStream to reuse the request submission and pagination machinery. - As a result, some of the parameters passed to some methods are unused. - The two will be decoupled in a future release. - - Attributes: - stream_name (str): The stream's name - stream_primary_key (Optional[Union[str, List[str], List[List[str]]]]): The stream's primary key - requester (Requester): The HTTP requester - record_selector (HttpSelector): The record selector - paginator (Optional[Paginator]): The paginator - stream_slicer (Optional[StreamSlicer]): The stream slicer - cursor (Optional[cursor]): The cursor - parameters (Mapping[str, Any]): Additional runtime parameters to be used for string interpolation - """ - - requester: Requester - record_selector: HttpSelector - config: Config - parameters: InitVar[Mapping[str, Any]] - name: str - _name: Union[InterpolatedString, str] = field(init=False, repr=False, default="") - primary_key: Optional[Union[str, List[str], List[List[str]]]] - _primary_key: str = field(init=False, repr=False, default="") - paginator: Optional[Paginator] = None - stream_slicer: StreamSlicer = field(default_factory=lambda: SinglePartitionRouter(parameters={})) - request_option_provider: RequestOptionsProvider = field(default_factory=lambda: DefaultRequestOptionsProvider(parameters={})) - cursor: Optional[DeclarativeCursor] = None - ignore_stream_slicer_parameters_on_paginated_requests: bool = False - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._paginator = self.paginator or NoPagination(parameters=parameters) - self._last_response: Optional[requests.Response] = None - self._last_page_size: int = 0 - self._last_record: Optional[Record] = None - self._parameters = parameters - self._name = InterpolatedString(self._name, parameters=parameters) if isinstance(self._name, str) else self._name - - # This mapping is used during a resumable full refresh syncs to indicate whether a partition has started syncing - # records. Partitions serve as the key and map to True if they already began processing records - self._partition_started: MutableMapping[Any, bool] = dict() - - @property # type: ignore - def name(self) -> str: - """ - :return: Stream name - """ - return str(self._name.eval(self.config)) if isinstance(self._name, InterpolatedString) else self._name - - @name.setter - def name(self, value: str) -> None: - if not isinstance(value, property): - self._name = value - - def _get_mapping( - self, method: Callable[..., Optional[Union[Mapping[str, Any], str]]], **kwargs: Any - ) -> Tuple[Union[Mapping[str, Any], str], Set[str]]: - """ - Get mapping from the provided method, and get the keys of the mapping. - If the method returns a string, it will return the string and an empty set. - If the method returns a dict, it will return the dict and its keys. - """ - mapping = method(**kwargs) or {} - keys = set(mapping.keys()) if not isinstance(mapping, str) else set() - return mapping, keys - - def _get_request_options( - self, - stream_state: Optional[StreamData], - stream_slice: Optional[StreamSlice], - next_page_token: Optional[Mapping[str, Any]], - paginator_method: Callable[..., Optional[Union[Mapping[str, Any], str]]], - stream_slicer_method: Callable[..., Optional[Union[Mapping[str, Any], str]]], - ) -> Union[Mapping[str, Any], str]: - """ - Get the request_option from the paginator and the stream slicer. - Raise a ValueError if there's a key collision - Returned merged mapping otherwise - """ - # FIXME we should eventually remove the usage of stream_state as part of the interpolation - mappings = [ - paginator_method(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - ] - if not next_page_token or not self.ignore_stream_slicer_parameters_on_paginated_requests: - mappings.append(stream_slicer_method(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token)) - return combine_mappings(mappings) - - def _request_headers( - self, - stream_state: Optional[StreamData] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - """ - Specifies request headers. - Authentication headers will overwrite any overlapping headers returned from this method. - """ - headers = self._get_request_options( - stream_state, - stream_slice, - next_page_token, - self._paginator.get_request_headers, - self.stream_slicer.get_request_headers, - ) - if isinstance(headers, str): - raise ValueError("Request headers cannot be a string") - return {str(k): str(v) for k, v in headers.items()} - - def _request_params( - self, - stream_state: Optional[StreamData] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - """ - Specifies the query parameters that should be set on an outgoing HTTP request given the inputs. - - E.g: you might want to define query parameters for paging if next_page_token is not None. - """ - params = self._get_request_options( - stream_state, - stream_slice, - next_page_token, - self._paginator.get_request_params, - self.request_option_provider.get_request_params, - ) - if isinstance(params, str): - raise ValueError("Request params cannot be a string") - return params - - def _request_body_data( - self, - stream_state: Optional[StreamData] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Union[Mapping[str, Any], str]: - """ - Specifies how to populate the body of the request with a non-JSON payload. - - If returns a ready text that it will be sent as is. - If returns a dict that it will be converted to a urlencoded form. - E.g. {"key1": "value1", "key2": "value2"} => "key1=value1&key2=value2" - - At the same time only one of the 'request_body_data' and 'request_body_json' functions can be overridden. - """ - return self._get_request_options( - stream_state, - stream_slice, - next_page_token, - self._paginator.get_request_body_data, - self.request_option_provider.get_request_body_data, - ) - - def _request_body_json( - self, - stream_state: Optional[StreamData] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Optional[Mapping[str, Any]]: - """ - Specifies how to populate the body of the request with a JSON payload. - - At the same time only one of the 'request_body_data' and 'request_body_json' functions can be overridden. - """ - body_json = self._get_request_options( - stream_state, - stream_slice, - next_page_token, - self._paginator.get_request_body_json, - self.request_option_provider.get_request_body_json, - ) - if isinstance(body_json, str): - raise ValueError("Request body json cannot be a string") - return body_json - - def _paginator_path( - self, - ) -> Optional[str]: - """ - If the paginator points to a path, follow it, else return nothing so the requester is used. - :param stream_state: - :param stream_slice: - :param next_page_token: - :return: - """ - return self._paginator.path() - - def _parse_response( - self, - response: Optional[requests.Response], - stream_state: StreamState, - records_schema: Mapping[str, Any], - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Iterable[Record]: - if not response: - self._last_response = None - yield from [] - else: - self._last_response = response - record_generator = self.record_selector.select_records( - response=response, - stream_state=stream_state, - records_schema=records_schema, - stream_slice=stream_slice, - next_page_token=next_page_token, - ) - self._last_page_size = 0 - for record in record_generator: - self._last_page_size += 1 - self._last_record = record - yield record - - @property # type: ignore - def primary_key(self) -> Optional[Union[str, List[str], List[List[str]]]]: - """The stream's primary key""" - return self._primary_key - - @primary_key.setter - def primary_key(self, value: str) -> None: - if not isinstance(value, property): - self._primary_key = value - - def _next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - """ - Specifies a pagination strategy. - - The value returned from this method is passed to most other methods in this class. Use it to form a request e.g: set headers or query params. - - :return: The token for the next page from the input response object. Returning None means there are no more pages to read in this response. - """ - return self._paginator.next_page_token(response, self._last_page_size, self._last_record) - - def _fetch_next_page( - self, stream_state: Mapping[str, Any], stream_slice: StreamSlice, next_page_token: Optional[Mapping[str, Any]] = None - ) -> Optional[requests.Response]: - return self.requester.send_request( - path=self._paginator_path(), - stream_state=stream_state, - stream_slice=stream_slice, - next_page_token=next_page_token, - request_headers=self._request_headers(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - request_params=self._request_params(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - request_body_data=self._request_body_data( - stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token - ), - request_body_json=self._request_body_json( - stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token - ), - ) - - # This logic is similar to _read_pages in the HttpStream class. When making changes here, consider making changes there as well. - def _read_pages( - self, - records_generator_fn: Callable[[Optional[requests.Response]], Iterable[StreamData]], - stream_state: Mapping[str, Any], - stream_slice: StreamSlice, - ) -> Iterable[StreamData]: - pagination_complete = False - next_page_token = None - while not pagination_complete: - response = self._fetch_next_page(stream_state, stream_slice, next_page_token) - yield from records_generator_fn(response) - - if not response: - pagination_complete = True - else: - next_page_token = self._next_page_token(response) - if not next_page_token: - pagination_complete = True - - # Always return an empty generator just in case no records were ever yielded - yield from [] - - def _read_single_page( - self, - records_generator_fn: Callable[[Optional[requests.Response]], Iterable[StreamData]], - stream_state: Mapping[str, Any], - stream_slice: StreamSlice, - ) -> Iterable[StreamData]: - response = self._fetch_next_page(stream_state, stream_slice) - yield from records_generator_fn(response) - - if not response: - next_page_token: Mapping[str, Any] = {FULL_REFRESH_SYNC_COMPLETE_KEY: True} - else: - next_page_token = self._next_page_token(response) or {FULL_REFRESH_SYNC_COMPLETE_KEY: True} - - if self.cursor: - self.cursor.close_slice(StreamSlice(cursor_slice=next_page_token, partition=stream_slice.partition)) - - # Always return an empty generator just in case no records were ever yielded - yield from [] - - def read_records( - self, - records_schema: Mapping[str, Any], - stream_slice: Optional[StreamSlice] = None, - ) -> Iterable[StreamData]: - """ - Fetch a stream's records from an HTTP API source - - :param records_schema: json schema to describe record - :param stream_slice: The stream slice to read data for - :return: The records read from the API source - """ - _slice = stream_slice or StreamSlice(partition={}, cursor_slice={}) # None-check - - most_recent_record_from_slice = None - record_generator = partial( - self._parse_records, - stream_state=self.state or {}, - stream_slice=_slice, - records_schema=records_schema, - ) - - if self.cursor and isinstance(self.cursor, ResumableFullRefreshCursor): - stream_state = self.state - - # Before syncing the RFR stream, we check if the job's prior attempt was successful and don't need to fetch more records - # The platform deletes stream state for full refresh streams before starting a new job, so we don't need to worry about - # this value existing for the initial attempt - if stream_state.get(FULL_REFRESH_SYNC_COMPLETE_KEY): - return - cursor_value = stream_state.get("next_page_token") - - # The first attempt to read a page for the current partition should reset the paginator to the current - # cursor state which is initially assigned to the incoming state from the platform - partition_key = self._to_partition_key(_slice.partition) - if partition_key not in self._partition_started: - self._partition_started[partition_key] = True - self._paginator.reset(reset_value=cursor_value) - - yield from self._read_single_page(record_generator, stream_state, _slice) - else: - # Fixing paginator types has a long tail of dependencies - self._paginator.reset() - - for stream_data in self._read_pages(record_generator, self.state, _slice): - current_record = self._extract_record(stream_data, _slice) - if self.cursor and current_record: - self.cursor.observe(_slice, current_record) - - # Latest record read, not necessarily within slice boundaries. - # TODO Remove once all custom components implement `observe` method. - # https://github.com/airbytehq/airbyte-internal-issues/issues/6955 - most_recent_record_from_slice = self._get_most_recent_record(most_recent_record_from_slice, current_record, _slice) - yield stream_data - - if self.cursor: - self.cursor.close_slice(_slice, most_recent_record_from_slice) - return - - def _get_most_recent_record( - self, current_most_recent: Optional[Record], current_record: Optional[Record], stream_slice: StreamSlice - ) -> Optional[Record]: - if self.cursor and current_record: - if not current_most_recent: - return current_record - else: - return current_most_recent if self.cursor.is_greater_than_or_equal(current_most_recent, current_record) else current_record - else: - return None - - @staticmethod - def _extract_record(stream_data: StreamData, stream_slice: StreamSlice) -> Optional[Record]: - """ - As we allow the output of _read_pages to be StreamData, it can be multiple things. Therefore, we need to filter out and normalize - to data to streamline the rest of the process. - """ - if isinstance(stream_data, Record): - # Record is not part of `StreamData` but is the most common implementation of `Mapping[str, Any]` which is part of `StreamData` - return stream_data - elif isinstance(stream_data, (dict, Mapping)): - return Record(dict(stream_data), stream_slice) - elif isinstance(stream_data, AirbyteMessage) and stream_data.record: - return Record(stream_data.record.data, stream_slice) - return None - - # stream_slices is defined with arguments on http stream and fixing this has a long tail of dependencies. Will be resolved by the decoupling of http stream and simple retriever - def stream_slices(self) -> Iterable[Optional[StreamSlice]]: # type: ignore - """ - Specifies the slices for this stream. See the stream slicing section of the docs for more information. - - :param sync_mode: - :param cursor_field: - :param stream_state: - :return: - """ - return self.stream_slicer.stream_slices() - - @property - def state(self) -> Mapping[str, Any]: - return self.cursor.get_stream_state() if self.cursor else {} - - @state.setter - def state(self, value: StreamState) -> None: - """State setter, accept state serialized by state getter.""" - if self.cursor: - self.cursor.set_initial_state(value) - - def _parse_records( - self, - response: Optional[requests.Response], - stream_state: Mapping[str, Any], - records_schema: Mapping[str, Any], - stream_slice: Optional[StreamSlice], - ) -> Iterable[StreamData]: - yield from self._parse_response( - response, - stream_slice=stream_slice, - stream_state=stream_state, - records_schema=records_schema, - ) - - def must_deduplicate_query_params(self) -> bool: - return True - - @staticmethod - def _to_partition_key(to_serialize: Any) -> str: - # separators have changed in Python 3.4. To avoid being impacted by further change, we explicitly specify our own value - return json.dumps(to_serialize, indent=None, separators=(",", ":"), sort_keys=True) - - -@dataclass -class SimpleRetrieverTestReadDecorator(SimpleRetriever): - """ - In some cases, we want to limit the number of requests that are made to the backend source. This class allows for limiting the number of - slices that are queried throughout a read command. - """ - - maximum_number_of_slices: int = 5 - - def __post_init__(self, options: Mapping[str, Any]) -> None: - super().__post_init__(options) - if self.maximum_number_of_slices and self.maximum_number_of_slices < 1: - raise ValueError( - f"The maximum number of slices on a test read needs to be strictly positive. Got {self.maximum_number_of_slices}" - ) - - # stream_slices is defined with arguments on http stream and fixing this has a long tail of dependencies. Will be resolved by the decoupling of http stream and simple retriever - def stream_slices(self) -> Iterable[Optional[StreamSlice]]: # type: ignore - return islice(super().stream_slices(), self.maximum_number_of_slices) - - def _fetch_next_page( - self, stream_state: Mapping[str, Any], stream_slice: StreamSlice, next_page_token: Optional[Mapping[str, Any]] = None - ) -> Optional[requests.Response]: - return self.requester.send_request( - path=self._paginator_path(), - stream_state=stream_state, - stream_slice=stream_slice, - next_page_token=next_page_token, - request_headers=self._request_headers(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - request_params=self._request_params(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - request_body_data=self._request_body_data( - stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token - ), - request_body_json=self._request_body_json( - stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token - ), - log_formatter=lambda response: format_http_message( - response, - f"Stream '{self.name}' request", - f"Request performed in order to extract records for stream '{self.name}'", - self.name, - ), - ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/schema/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/schema/__init__.py deleted file mode 100644 index fee72f44fe18..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/schema/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.schema.default_schema_loader import DefaultSchemaLoader -from airbyte_cdk.sources.declarative.schema.inline_schema_loader import InlineSchemaLoader -from airbyte_cdk.sources.declarative.schema.json_file_schema_loader import JsonFileSchemaLoader -from airbyte_cdk.sources.declarative.schema.schema_loader import SchemaLoader - -__all__ = ["JsonFileSchemaLoader", "DefaultSchemaLoader", "SchemaLoader", "InlineSchemaLoader"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/schema/default_schema_loader.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/schema/default_schema_loader.py deleted file mode 100644 index 1aa70be18fb2..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/schema/default_schema_loader.py +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from dataclasses import InitVar, dataclass -from typing import Any, Mapping - -from airbyte_cdk.sources.declarative.schema.json_file_schema_loader import JsonFileSchemaLoader -from airbyte_cdk.sources.declarative.schema.schema_loader import SchemaLoader -from airbyte_cdk.sources.types import Config - - -@dataclass -class DefaultSchemaLoader(SchemaLoader): - """ - Loads a schema from the default location or returns an empty schema for streams that have not defined their schema file yet. - - Attributes: - config (Config): The user-provided configuration as specified by the source's spec - parameters (Mapping[str, Any]): Additional arguments to pass to the string interpolation if needed - """ - - config: Config - parameters: InitVar[Mapping[str, Any]] - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._parameters = parameters - self.default_loader = JsonFileSchemaLoader(parameters=parameters, config=self.config) - - def get_json_schema(self) -> Mapping[str, Any]: - """ - Attempts to retrieve a schema from the default filepath location or returns the empty schema if a schema cannot be found. - - :return: The empty schema - """ - - try: - return self.default_loader.get_json_schema() - except OSError: - # A slight hack since we don't directly have the stream name. However, when building the default filepath we assume the - # runtime options stores stream name 'name' so we'll do the same here - stream_name = self._parameters.get("name", "") - logging.info(f"Could not find schema for stream {stream_name}, defaulting to the empty schema") - return {} diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/schema/inline_schema_loader.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/schema/inline_schema_loader.py deleted file mode 100644 index 72a46b7e595c..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/schema/inline_schema_loader.py +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Dict, Mapping - -from airbyte_cdk.sources.declarative.schema.schema_loader import SchemaLoader - - -@dataclass -class InlineSchemaLoader(SchemaLoader): - """Describes a stream's schema""" - - schema: Dict[str, Any] - parameters: InitVar[Mapping[str, Any]] - - def get_json_schema(self) -> Mapping[str, Any]: - return self.schema diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/schema/json_file_schema_loader.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/schema/json_file_schema_loader.py deleted file mode 100644 index af51fe5db01e..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/schema/json_file_schema_loader.py +++ /dev/null @@ -1,92 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import pkgutil -import sys -from dataclasses import InitVar, dataclass, field -from typing import Any, Mapping, Tuple, Union - -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.schema.schema_loader import SchemaLoader -from airbyte_cdk.sources.types import Config -from airbyte_cdk.sources.utils.schema_helpers import ResourceSchemaLoader - - -def _default_file_path() -> str: - # Schema files are always in "source_/schemas/.json - # The connector's module name can be inferred by looking at the modules loaded and look for the one starting with source_ - source_modules = [ - k for k, v in sys.modules.items() if "source_" in k and "airbyte_cdk" not in k - ] # example: ['source_exchange_rates', 'source_exchange_rates.source'] - if source_modules: - module = source_modules[0].split(".")[0] - return f"./{module}/schemas/{{{{parameters['name']}}}}.json" - - # If we are not in a source_ module, the most likely scenario is we're processing a manifest from the connector builder - # server which does not require a json schema to be defined. - return "./{{parameters['name']}}.json" - - -@dataclass -class JsonFileSchemaLoader(ResourceSchemaLoader, SchemaLoader): - """ - Loads the schema from a json file - - Attributes: - file_path (Union[InterpolatedString, str]): The path to the json file describing the schema - name (str): The stream's name - config (Config): The user-provided configuration as specified by the source's spec - parameters (Mapping[str, Any]): Additional arguments to pass to the string interpolation if needed - """ - - config: Config - parameters: InitVar[Mapping[str, Any]] - file_path: Union[InterpolatedString, str] = field(default="") - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - if not self.file_path: - self.file_path = _default_file_path() - self.file_path = InterpolatedString.create(self.file_path, parameters=parameters) - - def get_json_schema(self) -> Mapping[str, Any]: - # todo: It is worth revisiting if we can replace file_path with just file_name if every schema is in the /schemas directory - # this would require that we find a creative solution to store or retrieve source_name in here since the files are mounted there - json_schema_path = self._get_json_filepath() - resource, schema_path = self.extract_resource_and_schema_path(json_schema_path) - raw_json_file = pkgutil.get_data(resource, schema_path) - - if not raw_json_file: - raise IOError(f"Cannot find file {json_schema_path}") - try: - raw_schema = json.loads(raw_json_file) - except ValueError as err: - raise RuntimeError(f"Invalid JSON file format for file {json_schema_path}") from err - self.package_name = resource - return self._resolve_schema_references(raw_schema) - - def _get_json_filepath(self) -> Any: - return self.file_path.eval(self.config) # type: ignore # file_path is always cast to an interpolated string - - @staticmethod - def extract_resource_and_schema_path(json_schema_path: str) -> Tuple[str, str]: - """ - When the connector is running on a docker container, package_data is accessible from the resource (source_), so we extract - the resource from the first part of the schema path and the remaining path is used to find the schema file. This is a slight - hack to identify the source name while we are in the airbyte_cdk module. - :param json_schema_path: The path to the schema JSON file - :return: Tuple of the resource name and the path to the schema file - """ - split_path = json_schema_path.split("/") - - if split_path[0] == "" or split_path[0] == ".": - split_path = split_path[1:] - - if len(split_path) == 0: - return "", "" - - if len(split_path) == 1: - return "", split_path[0] - - return split_path[0], "/".join(split_path[1:]) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/schema/schema_loader.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/schema/schema_loader.py deleted file mode 100644 index a6beb70ae50b..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/schema/schema_loader.py +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import abstractmethod -from dataclasses import dataclass -from typing import Any, Mapping - - -@dataclass -class SchemaLoader: - """Describes a stream's schema""" - - @abstractmethod - def get_json_schema(self) -> Mapping[str, Any]: - """Returns a mapping describing the stream's schema""" - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/spec/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/spec/__init__.py deleted file mode 100644 index 1c13ed67cb66..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/spec/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.spec.spec import Spec - -__all__ = ["Spec"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/spec/spec.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/spec/spec.py deleted file mode 100644 index 87c8911d6aa6..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/spec/spec.py +++ /dev/null @@ -1,42 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Mapping, Optional - -from airbyte_cdk.models import AdvancedAuth, ConnectorSpecification, ConnectorSpecificationSerializer # type: ignore [attr-defined] -from airbyte_cdk.sources.declarative.models.declarative_component_schema import AuthFlow - - -@dataclass -class Spec: - """ - Returns a connection specification made up of information about the connector and how it can be configured - - Attributes: - connection_specification (Mapping[str, Any]): information related to how a connector can be configured - documentation_url (Optional[str]): The link the Airbyte documentation about this connector - """ - - connection_specification: Mapping[str, Any] - parameters: InitVar[Mapping[str, Any]] - documentation_url: Optional[str] = None - advanced_auth: Optional[AuthFlow] = None - - def generate_spec(self) -> ConnectorSpecification: - """ - Returns the connector specification according the spec block defined in the low code connector manifest. - """ - - obj: dict[str, Mapping[str, Any] | str | AdvancedAuth] = {"connectionSpecification": self.connection_specification} - - if self.documentation_url: - obj["documentationUrl"] = self.documentation_url - if self.advanced_auth: - self.advanced_auth.auth_flow_type = self.advanced_auth.auth_flow_type.value # type: ignore # We know this is always assigned to an AuthFlow which has the auth_flow_type field - # Map CDK AuthFlow model to protocol AdvancedAuth model - obj["advanced_auth"] = self.advanced_auth.dict() - - # We remap these keys to camel case because that's the existing format expected by the rest of the platform - return ConnectorSpecificationSerializer.load(obj) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/__init__.py deleted file mode 100644 index 7bacc3ca80fc..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.stream_slicers.stream_slicer import StreamSlicer - -__all__ = ["StreamSlicer"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/stream_slicer.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/stream_slicer.py deleted file mode 100644 index a1ecf68ae5a3..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/stream_slicers/stream_slicer.py +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import abstractmethod -from dataclasses import dataclass -from typing import Iterable - -from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import RequestOptionsProvider -from airbyte_cdk.sources.types import StreamSlice - - -@dataclass -class StreamSlicer(RequestOptionsProvider): - """ - Slices the stream into a subset of records. - Slices enable state checkpointing and data retrieval parallelization. - - The stream slicer keeps track of the cursor state as a dict of cursor_field -> cursor_value - - See the stream slicing section of the docs for more information. - """ - - @abstractmethod - def stream_slices(self) -> Iterable[StreamSlice]: - """ - Defines stream slices - - :return: List of stream slices - """ diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/transformations/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/transformations/__init__.py deleted file mode 100644 index e18712a01273..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/transformations/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -# RecordTransformation is depended upon by every class in this module (since it's the abc everything implements). For this reason, -# the order of imports matters i.e: this file must fully import RecordTransformation before importing anything which depends on RecordTransformation -# Otherwise there will be a circular dependency (load order will be init.py --> RemoveFields (which tries to import RecordTransformation) --> -# init.py --> circular dep error, since loading this file causes it to try to import itself down the line. -# so we add the split directive below to tell isort to sort imports while keeping RecordTransformation as the first import -from .transformation import RecordTransformation - -# isort: split -from .add_fields import AddFields -from .remove_fields import RemoveFields - -__all__ = ["AddFields", "RecordTransformation", "RemoveFields"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/transformations/add_fields.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/transformations/add_fields.py deleted file mode 100644 index 2a69b78218fd..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/transformations/add_fields.py +++ /dev/null @@ -1,128 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass, field -from typing import Any, Dict, List, Mapping, Optional, Type, Union - -import dpath -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.transformations import RecordTransformation -from airbyte_cdk.sources.types import Config, FieldPointer, StreamSlice, StreamState - - -@dataclass(frozen=True) -class AddedFieldDefinition: - """Defines the field to add on a record""" - - path: FieldPointer - value: Union[InterpolatedString, str] - value_type: Optional[Type[Any]] - parameters: InitVar[Mapping[str, Any]] - - -@dataclass(frozen=True) -class ParsedAddFieldDefinition: - """Defines the field to add on a record""" - - path: FieldPointer - value: InterpolatedString - value_type: Optional[Type[Any]] - parameters: InitVar[Mapping[str, Any]] - - -@dataclass -class AddFields(RecordTransformation): - """ - Transformation which adds field to an output record. The path of the added field can be nested. Adding nested fields will create all - necessary parent objects (like mkdir -p). Adding fields to an array will extend the array to that index (filling intermediate - indices with null values). So if you add a field at index 5 to the array ["value"], it will become ["value", null, null, null, null, - "new_value"]. - - - This transformation has access to the following contextual values: - record: the record about to be output by the connector - config: the input configuration provided to a connector - stream_state: the current state of the stream - stream_slice: the current stream slice being read - - - - Examples of instantiating this transformation via YAML: - - type: AddFields - fields: - # hardcoded constant - - path: ["path"] - value: "static_value" - - # nested path - - path: ["path", "to", "field"] - value: "static" - - # from config - - path: ["shop_id"] - value: "{{ config.shop_id }}" - - # from state - - path: ["current_state"] - value: "{{ stream_state.cursor_field }}" # Or {{ stream_state['cursor_field'] }} - - # from record - - path: ["unnested_value"] - value: {{ record.nested.field }} - - # from stream_slice - - path: ["start_date"] - value: {{ stream_slice.start_date }} - - # by supplying any valid Jinja template directive or expression https://jinja.palletsprojects.com/en/3.1.x/templates/# - - path: ["two_times_two"] - value: {{ 2 * 2 }} - - Attributes: - fields (List[AddedFieldDefinition]): A list of transformations (path and corresponding value) that will be added to the record - """ - - fields: List[AddedFieldDefinition] - parameters: InitVar[Mapping[str, Any]] - _parsed_fields: List[ParsedAddFieldDefinition] = field(init=False, repr=False, default_factory=list) - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - for add_field in self.fields: - if len(add_field.path) < 1: - raise ValueError(f"Expected a non-zero-length path for the AddFields transformation {add_field}") - - if not isinstance(add_field.value, InterpolatedString): - if not isinstance(add_field.value, str): - raise f"Expected a string value for the AddFields transformation: {add_field}" - else: - self._parsed_fields.append( - ParsedAddFieldDefinition( - add_field.path, - InterpolatedString.create(add_field.value, parameters=parameters), - value_type=add_field.value_type, - parameters=parameters, - ) - ) - else: - self._parsed_fields.append( - ParsedAddFieldDefinition(add_field.path, add_field.value, value_type=add_field.value_type, parameters={}) - ) - - def transform( - self, - record: Dict[str, Any], - config: Optional[Config] = None, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - ) -> None: - if config is None: - config = {} - kwargs = {"record": record, "stream_state": stream_state, "stream_slice": stream_slice} - for parsed_field in self._parsed_fields: - valid_types = (parsed_field.value_type,) if parsed_field.value_type else None - value = parsed_field.value.eval(config, valid_types=valid_types, **kwargs) - dpath.new(record, parsed_field.path, value) - - def __eq__(self, other: Any) -> bool: - return bool(self.__dict__ == other.__dict__) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/transformations/keys_to_lower_transformation.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/transformations/keys_to_lower_transformation.py deleted file mode 100644 index 53db3d49abd4..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/transformations/keys_to_lower_transformation.py +++ /dev/null @@ -1,22 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import dataclass -from typing import Any, Dict, Optional - -from airbyte_cdk.sources.declarative.transformations import RecordTransformation -from airbyte_cdk.sources.types import Config, StreamSlice, StreamState - - -@dataclass -class KeysToLowerTransformation(RecordTransformation): - def transform( - self, - record: Dict[str, Any], - config: Optional[Config] = None, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - ) -> None: - for key in set(record.keys()): - record[key.lower()] = record.pop(key) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/transformations/remove_fields.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/transformations/remove_fields.py deleted file mode 100644 index 658d5dd2ccdb..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/transformations/remove_fields.py +++ /dev/null @@ -1,70 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass -from typing import Any, Dict, List, Mapping, Optional - -import dpath -import dpath.exceptions -from airbyte_cdk.sources.declarative.interpolation.interpolated_boolean import InterpolatedBoolean -from airbyte_cdk.sources.declarative.transformations import RecordTransformation -from airbyte_cdk.sources.types import Config, FieldPointer, StreamSlice, StreamState - - -@dataclass -class RemoveFields(RecordTransformation): - """ - A transformation which removes fields from a record. The fields removed are designated using FieldPointers. - During transformation, if a field or any of its parents does not exist in the record, no error is thrown. - - If an input field pointer references an item in a list (e.g: ["k", 0] in the object {"k": ["a", "b", "c"]}) then - the object at that index is set to None rather than being not entirely removed from the list. TODO change this behavior. - - It's possible to remove objects nested in lists e.g: removing [".", 0, "k"] from {".": [{"k": "V"}]} results in {".": [{}]} - - Usage syntax: - - ```yaml - my_stream: - - transformations: - - type: RemoveFields - field_pointers: - - ["path", "to", "field1"] - - ["path2"] - ``` - - Attributes: - field_pointers (List[FieldPointer]): pointers to the fields that should be removed - """ - - field_pointers: List[FieldPointer] - parameters: InitVar[Mapping[str, Any]] - condition: str = "" - - def __post_init__(self, parameters: Mapping[str, Any]) -> None: - self._filter_interpolator = InterpolatedBoolean(condition=self.condition, parameters=parameters) - - def transform( - self, - record: Dict[str, Any], - config: Optional[Config] = None, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - ) -> None: - """ - :param record: The record to be transformed - :return: the input record with the requested fields removed - """ - for pointer in self.field_pointers: - # the dpath library by default doesn't delete fields from arrays - try: - dpath.delete( - record, - pointer, - afilter=(lambda x: self._filter_interpolator.eval(config or {}, property=x)) if self.condition else None, - ) - except dpath.exceptions.PathNotFound: - # if the (potentially nested) property does not exist, silently skip - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/transformations/transformation.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/transformations/transformation.py deleted file mode 100644 index f5b22642964b..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/transformations/transformation.py +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import abstractmethod -from dataclasses import dataclass -from typing import Any, Dict, Optional - -from airbyte_cdk.sources.types import Config, StreamSlice, StreamState - - -@dataclass -class RecordTransformation: - """ - Implementations of this class define transformations that can be applied to records of a stream. - """ - - @abstractmethod - def transform( - self, - record: Dict[str, Any], - config: Optional[Config] = None, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - ) -> None: - """ - Transform a record by adding, deleting, or mutating fields directly from the record reference passed in argument. - - :param record: The input record to be transformed - :param config: The user-provided configuration as specified by the source's spec - :param stream_state: The stream state - :param stream_slice: The stream slice - :return: The transformed record - """ - - def __eq__(self, other: object) -> bool: - return other.__dict__ == self.__dict__ diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/types.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/types.py deleted file mode 100644 index 91900d1885de..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/types.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from __future__ import annotations - -from airbyte_cdk.sources.types import Config, ConnectionDefinition, FieldPointer, Record, StreamSlice, StreamState - -# Note: This package originally contained class definitions for low-code CDK types, but we promoted them into the Python CDK. -# We've migrated connectors in the repository to reference the new location, but these assignments are used to retain backwards -# compatibility for sources created by OSS customers or on forks. This can be removed when we start bumping major versions. - -FieldPointer = FieldPointer -Config = Config -ConnectionDefinition = ConnectionDefinition -StreamState = StreamState -Record = Record -StreamSlice = StreamSlice diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/yaml_declarative_source.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/yaml_declarative_source.py deleted file mode 100644 index 9632df6cf7ed..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/yaml_declarative_source.py +++ /dev/null @@ -1,46 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pkgutil -from typing import Any - -import yaml -from airbyte_cdk.sources.declarative.manifest_declarative_source import ManifestDeclarativeSource -from airbyte_cdk.sources.types import ConnectionDefinition - - -class YamlDeclarativeSource(ManifestDeclarativeSource): - """Declarative source defined by a yaml file""" - - def __init__(self, path_to_yaml: str, debug: bool = False) -> None: - """ - :param path_to_yaml: Path to the yaml file describing the source - """ - self._path_to_yaml = path_to_yaml - source_config = self._read_and_parse_yaml_file(path_to_yaml) - super().__init__(source_config, debug) - - def _read_and_parse_yaml_file(self, path_to_yaml_file: str) -> ConnectionDefinition: - package = self.__class__.__module__.split(".")[0] - - yaml_config = pkgutil.get_data(package, path_to_yaml_file) - if yaml_config: - decoded_yaml = yaml_config.decode() - return self._parse(decoded_yaml) - else: - return {} - - def _emit_manifest_debug_message(self, extra_args: dict[str, Any]) -> None: - extra_args["path_to_yaml"] = self._path_to_yaml - self.logger.debug("declarative source created from parsed YAML manifest", extra=extra_args) - - @staticmethod - def _parse(connection_definition_str: str) -> ConnectionDefinition: - """ - Parses a yaml file into a manifest. Component references still exist in the manifest which will be - resolved during the creating of the DeclarativeSource. - :param connection_definition_str: yaml string to parse - :return: The ConnectionDefinition parsed from connection_definition_str - """ - return yaml.safe_load(connection_definition_str) # type: ignore # yaml.safe_load doesn't return a type but know it is a Mapping diff --git a/airbyte-cdk/python/airbyte_cdk/sources/embedded/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/embedded/__init__.py deleted file mode 100644 index 46b7376756ec..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/embedded/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/airbyte_cdk/sources/embedded/base_integration.py b/airbyte-cdk/python/airbyte_cdk/sources/embedded/base_integration.py deleted file mode 100644 index 79c9bd850a3a..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/embedded/base_integration.py +++ /dev/null @@ -1,50 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import ABC, abstractmethod -from typing import Generic, Iterable, Optional, TypeVar - -from airbyte_cdk.connector import TConfig -from airbyte_cdk.models import AirbyteRecordMessage, AirbyteStateMessage, SyncMode, Type -from airbyte_cdk.sources.embedded.catalog import create_configured_catalog, get_stream, get_stream_names -from airbyte_cdk.sources.embedded.runner import SourceRunner -from airbyte_cdk.sources.embedded.tools import get_defined_id -from airbyte_cdk.sources.utils.schema_helpers import check_config_against_spec_or_exit - -TOutput = TypeVar("TOutput") - - -class BaseEmbeddedIntegration(ABC, Generic[TConfig, TOutput]): - def __init__(self, runner: SourceRunner[TConfig], config: TConfig): - check_config_against_spec_or_exit(config, runner.spec()) - - self.source = runner - self.config = config - - self.last_state: Optional[AirbyteStateMessage] = None - - @abstractmethod - def _handle_record(self, record: AirbyteRecordMessage, id: Optional[str]) -> Optional[TOutput]: - """ - Turn an Airbyte record into the appropriate output type for the integration. - """ - pass - - def _load_data(self, stream_name: str, state: Optional[AirbyteStateMessage] = None) -> Iterable[TOutput]: - catalog = self.source.discover(self.config) - stream = get_stream(catalog, stream_name) - if not stream: - raise ValueError(f"Stream {stream_name} not found, the following streams are available: {', '.join(get_stream_names(catalog))}") - if SyncMode.incremental not in stream.supported_sync_modes: - configured_catalog = create_configured_catalog(stream, sync_mode=SyncMode.full_refresh) - else: - configured_catalog = create_configured_catalog(stream, sync_mode=SyncMode.incremental) - - for message in self.source.read(self.config, configured_catalog, state): - if message.type == Type.RECORD: - output = self._handle_record(message.record, get_defined_id(stream, message.record.data)) # type: ignore[union-attr] # record has `data` - if output: - yield output - elif message.type is Type.STATE and message.state: - self.last_state = message.state diff --git a/airbyte-cdk/python/airbyte_cdk/sources/embedded/catalog.py b/airbyte-cdk/python/airbyte_cdk/sources/embedded/catalog.py deleted file mode 100644 index 765e9b260233..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/embedded/catalog.py +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import List, Optional - -from airbyte_cdk.models import ( - AirbyteCatalog, - AirbyteStream, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteStream, - DestinationSyncMode, - SyncMode, -) -from airbyte_cdk.sources.embedded.tools import get_first - - -def get_stream(catalog: AirbyteCatalog, stream_name: str) -> Optional[AirbyteStream]: - return get_first(catalog.streams, lambda s: s.name == stream_name) - - -def get_stream_names(catalog: AirbyteCatalog) -> List[str]: - return [stream.name for stream in catalog.streams] - - -def to_configured_stream( - stream: AirbyteStream, - sync_mode: SyncMode = SyncMode.full_refresh, - destination_sync_mode: DestinationSyncMode = DestinationSyncMode.append, - cursor_field: Optional[List[str]] = None, - primary_key: Optional[List[List[str]]] = None, -) -> ConfiguredAirbyteStream: - return ConfiguredAirbyteStream( - stream=stream, sync_mode=sync_mode, destination_sync_mode=destination_sync_mode, cursor_field=cursor_field, primary_key=primary_key - ) - - -def to_configured_catalog(configured_streams: List[ConfiguredAirbyteStream]) -> ConfiguredAirbyteCatalog: - return ConfiguredAirbyteCatalog(streams=configured_streams) - - -def create_configured_catalog(stream: AirbyteStream, sync_mode: SyncMode = SyncMode.full_refresh) -> ConfiguredAirbyteCatalog: - configured_streams = [to_configured_stream(stream, sync_mode=sync_mode, primary_key=stream.source_defined_primary_key)] - - return to_configured_catalog(configured_streams) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/embedded/runner.py b/airbyte-cdk/python/airbyte_cdk/sources/embedded/runner.py deleted file mode 100644 index c64e66ed581e..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/embedded/runner.py +++ /dev/null @@ -1,41 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import logging -from abc import ABC, abstractmethod -from typing import Generic, Iterable, Optional - -from airbyte_cdk.connector import TConfig -from airbyte_cdk.models import AirbyteCatalog, AirbyteMessage, AirbyteStateMessage, ConfiguredAirbyteCatalog, ConnectorSpecification -from airbyte_cdk.sources.source import Source - - -class SourceRunner(ABC, Generic[TConfig]): - @abstractmethod - def spec(self) -> ConnectorSpecification: - pass - - @abstractmethod - def discover(self, config: TConfig) -> AirbyteCatalog: - pass - - @abstractmethod - def read(self, config: TConfig, catalog: ConfiguredAirbyteCatalog, state: Optional[AirbyteStateMessage]) -> Iterable[AirbyteMessage]: - pass - - -class CDKRunner(SourceRunner[TConfig]): - def __init__(self, source: Source, name: str): - self._source = source - self._logger = logging.getLogger(name) - - def spec(self) -> ConnectorSpecification: - return self._source.spec(self._logger) - - def discover(self, config: TConfig) -> AirbyteCatalog: - return self._source.discover(self._logger, config) - - def read(self, config: TConfig, catalog: ConfiguredAirbyteCatalog, state: Optional[AirbyteStateMessage]) -> Iterable[AirbyteMessage]: - return self._source.read(self._logger, config, catalog, state=[state] if state else []) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/embedded/tools.py b/airbyte-cdk/python/airbyte_cdk/sources/embedded/tools.py deleted file mode 100644 index 39d70c118cd0..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/embedded/tools.py +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Callable, Dict, Iterable, Optional - -import dpath -from airbyte_cdk.models import AirbyteStream - - -def get_first(iterable: Iterable[Any], predicate: Callable[[Any], bool] = lambda m: True) -> Optional[Any]: - return next(filter(predicate, iterable), None) - - -def get_defined_id(stream: AirbyteStream, data: Dict[str, Any]) -> Optional[str]: - if not stream.source_defined_primary_key: - return None - primary_key = [] - for key in stream.source_defined_primary_key: - try: - primary_key.append(str(dpath.get(data, key))) - except KeyError: - primary_key.append("__not_found__") - return "_".join(primary_key) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/README.md b/airbyte-cdk/python/airbyte_cdk/sources/file_based/README.md deleted file mode 100644 index ea3c20d4ce99..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/README.md +++ /dev/null @@ -1,152 +0,0 @@ -## Behavior - -The Airbyte protocol defines the actions `spec`, `discover`, `check` and `read` for a source to be compliant. Here is the high-level description of the flow for a file-based source: - -- spec: calls AbstractFileBasedSpec.documentation_url and AbstractFileBasedSpec.schema to return a ConnectorSpecification. -- discover: calls Source.streams, and subsequently Stream.get_json_schema; this uses Source.open_file to open files during schema discovery. -- check: Source.check_connection is called from the entrypoint code (in the main CDK). -- read: Stream.read_records calls Stream.list_files which calls Source.list_matching_files, and then also uses Source.open_file to parse records from the file handle. - -## How to Implement Your Own - -To create a file-based source a user must extend three classes – AbstractFileBasedSource, AbstractFileBasedSpec, and AbstractStreamReader – to create an implementation for the connector’s specific storage system. They then initialize a FileBasedSource with the instance of AbstractStreamReader specific to their storage system. - -The abstract classes house the vast majority of the logic required by file-based sources. For example, when extending AbstractStreamReader, users only have to implement three methods: - -- list_matching_files: lists files matching the glob pattern(s) provided in the config. -- open_file: returns a file handle for reading. -- config property setter: concrete implementations of AbstractFileBasedStreamReader's config setter should assert that `value` is of the correct config type for that type of StreamReader. - -The result is that an implementation of a source might look like this: - -``` -class CustomStreamReader(AbstractStreamReader): - def open_file(self, remote_file: RemoteFile) -> FileHandler: - <...> - - def get_matching_files( - self, - globs: List[str], - logger: logging.Logger, - ) -> Iterable[RemoteFile]: - <...> - - @config.setter - def config(self, value: Config): - assert isinstance(value, CustomConfig) - self._config = value - - -class CustomConfig(AbstractFileBasedSpec): - @classmethod - def documentation_url(cls) -> AnyUrl: - return AnyUrl("https://docs.airbyte.com/integrations/sources/s3", scheme="https") - - a_spec_field: str = Field(title="A Spec Field", description="This is where you describe the fields of the spec", order=0) - <...> -``` - -For more information, feel free to check the docstrings of each classes or check specific implementations (like source-s3). - -## Supported File Types - -### Avro - -Avro is a serialization format developed by [Apache](https://avro.apache.org/docs/). Avro configuration options for the file-based CDK: - -- `double_as_string`: Whether to convert double fields to strings. This is recommended if you have decimal numbers with a high degree of precision because there can be a loss precision when handling floating point numbers. - -### CSV - -CSV is a format loosely described by [RFC 4180](https://www.rfc-editor.org/rfc/rfc4180). The format is quite flexible which leads to a ton of options to consider: - -- `delimiter`: The character delimiting individual cells in the CSV data. By name, CSV is comma separated so the default value is `,` -- `quote_char`: When quoted fields are used, it is possible for a field to span multiple lines, even when line breaks appear within such field. The default quote character is `"`. -- `escape_char`: The character used for escaping special characters. -- `encoding`: The character encoding of the file. By default, `UTF-8` -- `double_quote`: Whether two quotes in a quoted CSV value denote a single quote in the data. -- `quoting_behavior`: The quoting behavior determines when a value in a row should have quote marks added around it. -- `skip_rows_before_header`: The number of rows to skip before the header row. For example, if the header row is on the 3rd row, enter 2 in this field. -- `skip_rows_after_header`: The number of rows to skip after the header row. -- `autogenerate_column_names`: If your CSV does not have a header row, the file-based CDK will need this enable to generate column names. -- `null_values`: As CSV does not explicitly define a value for null values, the user can specify a set of case-sensitive strings that should be interpreted as null values. -- `true_values`: As CSV does not explicitly define a value for positive boolean, the user can specify a set of case-sensitive strings that should be interpreted as true values. -- `false_values`: As CSV does not explicitly define a value for negative boolean, the user can specify a set of case-sensitive strings that should be interpreted as false values. - -### JSONL - -[JSONL](https://jsonlines.org/) (or JSON Lines) is a format where each row is a JSON object. There are no configuration option for this format. For backward compatibility reasons, the JSONL parser currently supports multiline objects even though this is not part of the JSONL standard. Following some data gathering, we reserve the right to remove the support for this. Given that files have multiline JSON objects, performances will be slow. - -### Parquet - -Parquet is a file format defined by [Apache](https://parquet.apache.org/). Configuration options are: - -- `decimal_as_float`: Whether to convert decimal fields to floats. There is a loss of precision when converting decimals to floats, so this is not recommended. - -### Document file types (PDF, DOCX, Markdown) - -For file share source connectors, the `unstructured` parser can be used to parse document file types. The textual content of the whole file will be parsed as a single record with a `content` field containing the text encoded as markdown. - -To use the unstructured parser, the libraries `poppler` and `tesseract` need to be installed on the system running the connector. For example, on Ubuntu, you can install them with the following command: - -``` -apt-get install -y tesseract-ocr poppler-utils -``` - -on Mac, you can install these via brew: - -``` -brew install poppler -brew install tesseract -``` - -## Schema - -Having a schema allows for the file-based CDK to take action when there is a discrepancy between a record and what are the expected types of the record fields. - -Schema can be either inferred or user provided. - -- If the user defines it a format using JSON types, inference will not apply. Input schemas are a key/value pair of strings describing column name and data type. Supported types are `["string", "number", "integer", "object", "array", "boolean", "null"]`. For example, `{"col1": "string", "col2": "boolean"}`. -- If the user enables schemaless sync, schema will `{"data": "object"}` and therefore emitted records will look like `{"data": {"col1": val1, …}}`. This is recommended if the contents between files in the stream vary significantly, and/or if data is very nested. -- Else, the file-based CDK will infer the schema depending on the file type. Some file formats defined the schema as part of their metadata (like Parquet), some do on the record-level (like Avro) and some don't have any explicit typing (like JSON or CSV). Note that all CSV values are inferred as strings except where we are supporting legacy configurations. Any file format that does not define their schema on a metadata level will require the file-based CDK to iterate to a number of records. There is a limit of bytes that will be consumed in order to infer the schema. - -### Validation Policies - -Users will be required to select one of 3 different options, in the event that records are encountered that don’t conform to the schema. - -- Skip nonconforming records: check each record to see if it conforms to the user-input or inferred schema; skip the record if it doesn't conform. We keep a count of the number of records in each file that do and do not conform and emit a log message with these counts once we’re done reading the file. -- Emit all records: emit all records, even if they do not conform to the user-provided or inferred schema. Columns that don't exist in the configured catalog probably won't be available in the destination's table since that's the current behavior. - Only error if there are conflicting field types or malformed rows. -- Stop the sync and wait for schema re-discovery: if a record is encountered that does not conform to the configured catalog’s schema, we log a message and stop the whole sync. Note: this option is not recommended if the files have very different columns or datatypes, because the inferred schema may vary significantly at discover time. - -When the `schemaless` is enabled, validation will be skipped. - -## Breaking Changes (compared to previous S3 implementation) - -- [CSV] Mapping of type `array` and `object`: before, they were mapped as `large_string` and hence casted as strings. Given the new changes, if `array` or `object` is specified, the value will be casted as `array` and `object` respectively. -- [CSV] Before, a string value would not be considered as `null_values` if the column type was a string. We will now start to cast string columns with values matching `null_values` to null. -- [CSV] `decimal_point` option is deprecated: It is not possible anymore to use another character than `.` to separate the integer part from non-integer part. Given that the float is format with another character than this, it will be considered as a string. -- [Parquet] `columns` option is deprecated: You can use Airbyte column selection in order to have the same behavior. We don't expect it, but this could have impact on the performance as payload could be bigger. - -## Incremental syncs - -The file-based connectors supports the following [sync modes](https://docs.airbyte.com/cloud/core-concepts#connection-sync-modes): - -| Feature | Supported? | -| :--------------------------------------------- | :--------- | -| Full Refresh Sync | Yes | -| Incremental Sync | Yes | -| Replicate Incremental Deletes | No | -| Replicate Multiple Files \(pattern matching\) | Yes | -| Replicate Multiple Streams \(distinct tables\) | Yes | -| Namespaces | No | - -We recommend you do not manually modify files that are already synced. The connector has file-level granularity, which means adding or modifying a row in a CSV file will trigger a re-sync of the content of that file. - -### Incremental sync - -After the initial sync, the connector only pulls files that were modified since the last sync. - -The connector checkpoints the connection states when it is done syncing all files for a given timestamp. The connection's state only keeps track of the last 10 000 files synced. If more than 10 000 files are synced, the connector won't be able to rely on the connection state to deduplicate files. In this case, the connector will initialize its cursor to the minimum between the earliest file in the history, or 3 days ago. - -Both the maximum number of files, and the time buffer can be configured by connector developers. diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/__init__.py deleted file mode 100644 index 6ea0ca31eaf1..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -from .config.abstract_file_based_spec import AbstractFileBasedSpec -from .config.csv_format import CsvFormat -from .config.file_based_stream_config import FileBasedStreamConfig -from .config.jsonl_format import JsonlFormat -from .exceptions import CustomFileBasedException, ErrorListingFiles, FileBasedSourceError -from .file_based_source import DEFAULT_CONCURRENCY, FileBasedSource -from .file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode -from .remote_file import RemoteFile -from .stream.cursor import DefaultFileBasedCursor - -__all__ = [ - "AbstractFileBasedSpec", - "AbstractFileBasedStreamReader", - "CsvFormat", - "CustomFileBasedException", - "DefaultFileBasedCursor", - "ErrorListingFiles", - "FileBasedSource", - "FileBasedSourceError", - "FileBasedStreamConfig", - "FileReadMode", - "JsonlFormat", - "RemoteFile", -] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/availability_strategy/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/availability_strategy/__init__.py deleted file mode 100644 index a05e5421000a..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/availability_strategy/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .abstract_file_based_availability_strategy import AbstractFileBasedAvailabilityStrategy, AbstractFileBasedAvailabilityStrategyWrapper -from .default_file_based_availability_strategy import DefaultFileBasedAvailabilityStrategy - -__all__ = ["AbstractFileBasedAvailabilityStrategy", "AbstractFileBasedAvailabilityStrategyWrapper", "DefaultFileBasedAvailabilityStrategy"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/availability_strategy/abstract_file_based_availability_strategy.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/availability_strategy/abstract_file_based_availability_strategy.py deleted file mode 100644 index ba26745ea57c..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/availability_strategy/abstract_file_based_availability_strategy.py +++ /dev/null @@ -1,57 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from abc import abstractmethod -from typing import TYPE_CHECKING, Optional, Tuple - -from airbyte_cdk.sources import Source -from airbyte_cdk.sources.streams.availability_strategy import AvailabilityStrategy -from airbyte_cdk.sources.streams.concurrent.availability_strategy import ( - AbstractAvailabilityStrategy, - StreamAvailability, - StreamAvailable, - StreamUnavailable, -) -from airbyte_cdk.sources.streams.core import Stream - -if TYPE_CHECKING: - from airbyte_cdk.sources.file_based.stream import AbstractFileBasedStream - - -class AbstractFileBasedAvailabilityStrategy(AvailabilityStrategy): - @abstractmethod - def check_availability(self, stream: Stream, logger: logging.Logger, _: Optional[Source]) -> Tuple[bool, Optional[str]]: - """ - Perform a connection check for the stream. - - Returns (True, None) if successful, otherwise (False, ). - """ - ... - - @abstractmethod - def check_availability_and_parsability( - self, stream: "AbstractFileBasedStream", logger: logging.Logger, _: Optional[Source] - ) -> Tuple[bool, Optional[str]]: - """ - Performs a connection check for the stream, as well as additional checks that - verify that the connection is working as expected. - - Returns (True, None) if successful, otherwise (False, ). - """ - ... - - -class AbstractFileBasedAvailabilityStrategyWrapper(AbstractAvailabilityStrategy): - def __init__(self, stream: "AbstractFileBasedStream"): - self.stream = stream - - def check_availability(self, logger: logging.Logger) -> StreamAvailability: - is_available, reason = self.stream.availability_strategy.check_availability(self.stream, logger, None) - if is_available: - return StreamAvailable() - return StreamUnavailable(reason or "") - - def check_availability_and_parsability(self, logger: logging.Logger) -> Tuple[bool, Optional[str]]: - return self.stream.availability_strategy.check_availability_and_parsability(self.stream, logger, None) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/availability_strategy/default_file_based_availability_strategy.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/availability_strategy/default_file_based_availability_strategy.py deleted file mode 100644 index 079b1e2a11c7..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/availability_strategy/default_file_based_availability_strategy.py +++ /dev/null @@ -1,118 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -import traceback -from typing import TYPE_CHECKING, Optional, Tuple - -from airbyte_cdk import AirbyteTracedException -from airbyte_cdk.sources import Source -from airbyte_cdk.sources.file_based.availability_strategy import AbstractFileBasedAvailabilityStrategy -from airbyte_cdk.sources.file_based.exceptions import CheckAvailabilityError, CustomFileBasedException, FileBasedSourceError -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.schema_helpers import conforms_to_schema - -if TYPE_CHECKING: - from airbyte_cdk.sources.file_based.stream import AbstractFileBasedStream - - -class DefaultFileBasedAvailabilityStrategy(AbstractFileBasedAvailabilityStrategy): - def __init__(self, stream_reader: AbstractFileBasedStreamReader): - self.stream_reader = stream_reader - - def check_availability(self, stream: "AbstractFileBasedStream", logger: logging.Logger, _: Optional[Source]) -> Tuple[bool, Optional[str]]: # type: ignore[override] - """ - Perform a connection check for the stream (verify that we can list files from the stream). - - Returns (True, None) if successful, otherwise (False, ). - """ - try: - self._check_list_files(stream) - except CheckAvailabilityError: - return False, "".join(traceback.format_exc()) - - return True, None - - def check_availability_and_parsability( - self, stream: "AbstractFileBasedStream", logger: logging.Logger, _: Optional[Source] - ) -> Tuple[bool, Optional[str]]: - """ - Perform a connection check for the stream. - - Returns (True, None) if successful, otherwise (False, ). - - For the stream: - - Verify the parser config is valid per check_config method of the parser. - - Verify that we can list files from the stream using the configured globs. - - Verify that we can read one file from the stream as long as the stream parser is not setting parser_max_n_files_for_parsability to 0. - - This method will also check that the files and their contents are consistent - with the configured options, as follows: - - If the files have extensions, verify that they don't disagree with the - configured file type. - - If the user provided a schema in the config, check that a subset of records in - one file conform to the schema via a call to stream.conforms_to_schema(schema). - """ - parser = stream.get_parser() - config_check_result, config_check_error_message = parser.check_config(stream.config) - if config_check_result is False: - return False, config_check_error_message - try: - file = self._check_list_files(stream) - if not parser.parser_max_n_files_for_parsability == 0: - self._check_parse_record(stream, file, logger) - else: - # If the parser is set to not check parsability, we still want to check that we can open the file. - handle = stream.stream_reader.open_file(file, parser.file_read_mode, None, logger) - handle.close() - except AirbyteTracedException as ate: - raise ate - except CheckAvailabilityError: - return False, "".join(traceback.format_exc()) - - return True, None - - def _check_list_files(self, stream: "AbstractFileBasedStream") -> RemoteFile: - """ - Check that we can list files from the stream. - - Returns the first file if successful, otherwise raises a CheckAvailabilityError. - """ - try: - file = next(iter(stream.get_files())) - except StopIteration: - raise CheckAvailabilityError(FileBasedSourceError.EMPTY_STREAM, stream=stream.name) - except CustomFileBasedException as exc: - raise CheckAvailabilityError(str(exc), stream=stream.name) from exc - except Exception as exc: - raise CheckAvailabilityError(FileBasedSourceError.ERROR_LISTING_FILES, stream=stream.name) from exc - - return file - - def _check_parse_record(self, stream: "AbstractFileBasedStream", file: RemoteFile, logger: logging.Logger) -> None: - parser = stream.get_parser() - - try: - record = next(iter(parser.parse_records(stream.config, file, self.stream_reader, logger, discovered_schema=None))) - except StopIteration: - # The file is empty. We've verified that we can open it, so will - # consider the connection check successful even though it means - # we skip the schema validation check. - return - except AirbyteTracedException as ate: - raise ate - except Exception as exc: - raise CheckAvailabilityError(FileBasedSourceError.ERROR_READING_FILE, stream=stream.name, file=file.uri) from exc - - schema = stream.catalog_schema or stream.config.input_schema - if schema and stream.validation_policy.validate_schema_before_sync: - if not conforms_to_schema(record, schema): # type: ignore - raise CheckAvailabilityError( - FileBasedSourceError.ERROR_VALIDATING_RECORD, - stream=stream.name, - file=file.uri, - ) - - return None diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py deleted file mode 100644 index 862c987000bc..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py +++ /dev/null @@ -1,104 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import copy -from abc import abstractmethod -from typing import Any, Dict, List, Optional - -import dpath -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig -from airbyte_cdk.sources.utils import schema_helpers -from pydantic.v1 import AnyUrl, BaseModel, Field - - -class AbstractFileBasedSpec(BaseModel): - """ - Used during spec; allows the developer to configure the cloud provider specific options - that are needed when users configure a file-based source. - """ - - start_date: Optional[str] = Field( - title="Start Date", - description="UTC date and time in the format 2017-01-25T00:00:00.000000Z. Any file modified before this date will not be replicated.", - examples=["2021-01-01T00:00:00.000000Z"], - format="date-time", - pattern="^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{6}Z$", - pattern_descriptor="YYYY-MM-DDTHH:mm:ss.SSSSSSZ", - order=1, - ) - - streams: List[FileBasedStreamConfig] = Field( - title="The list of streams to sync", - description='Each instance of this configuration defines a stream. Use this to define which files belong in the stream, their format, and how they should be parsed and validated. When sending data to warehouse destination such as Snowflake or BigQuery, each stream is a separate table.', - order=10, - ) - - @classmethod - @abstractmethod - def documentation_url(cls) -> AnyUrl: - """ - :return: link to docs page for this source e.g. "https://docs.airbyte.com/integrations/sources/s3" - """ - - @classmethod - def schema(cls, *args: Any, **kwargs: Any) -> Dict[str, Any]: - """ - Generates the mapping comprised of the config fields - """ - schema = super().schema(*args, **kwargs) - transformed_schema: Dict[str, Any] = copy.deepcopy(schema) - schema_helpers.expand_refs(transformed_schema) - cls.replace_enum_allOf_and_anyOf(transformed_schema) - cls.remove_discriminator(transformed_schema) - - return transformed_schema - - @staticmethod - def remove_discriminator(schema: Dict[str, Any]) -> None: - """pydantic adds "discriminator" to the schema for oneOfs, which is not treated right by the platform as we inline all references""" - dpath.delete(schema, "properties/**/discriminator") - - @staticmethod - def replace_enum_allOf_and_anyOf(schema: Dict[str, Any]) -> Dict[str, Any]: - """ - allOfs are not supported by the UI, but pydantic is automatically writing them for enums. - Unpacks the enums under allOf and moves them up a level under the enum key - anyOfs are also not supported by the UI, so we replace them with the similar oneOf, with the - additional validation that an incoming config only matches exactly one of a field's types. - """ - objects_to_check = schema["properties"]["streams"]["items"]["properties"]["format"] - objects_to_check["type"] = "object" - objects_to_check["oneOf"] = objects_to_check.pop("anyOf", []) - for format in objects_to_check["oneOf"]: - for key in format["properties"]: - object_property = format["properties"][key] - AbstractFileBasedSpec.move_enum_to_root(object_property) - - properties_to_change = ["validation_policy"] - for property_to_change in properties_to_change: - property_object = schema["properties"]["streams"]["items"]["properties"][property_to_change] - if "anyOf" in property_object: - schema["properties"]["streams"]["items"]["properties"][property_to_change]["type"] = "object" - schema["properties"]["streams"]["items"]["properties"][property_to_change]["oneOf"] = property_object.pop("anyOf") - AbstractFileBasedSpec.move_enum_to_root(property_object) - - csv_format_schemas = list( - filter( - lambda format: format["properties"]["filetype"]["default"] == "csv", - schema["properties"]["streams"]["items"]["properties"]["format"]["oneOf"], - ) - ) - if len(csv_format_schemas) != 1: - raise ValueError(f"Expecting only one CSV format but got {csv_format_schemas}") - csv_format_schemas[0]["properties"]["header_definition"]["oneOf"] = csv_format_schemas[0]["properties"]["header_definition"].pop( - "anyOf", [] - ) - csv_format_schemas[0]["properties"]["header_definition"]["type"] = "object" - return schema - - @staticmethod - def move_enum_to_root(object_property: Dict[str, Any]) -> None: - if "allOf" in object_property and "enum" in object_property["allOf"][0]: - object_property["enum"] = object_property["allOf"][0]["enum"] - object_property.pop("allOf") diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/avro_format.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/avro_format.py deleted file mode 100644 index ac8fafef577e..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/avro_format.py +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from airbyte_cdk.utils.oneof_option_config import OneOfOptionConfig -from pydantic.v1 import BaseModel, Field - - -class AvroFormat(BaseModel): - class Config(OneOfOptionConfig): - title = "Avro Format" - discriminator = "filetype" - - filetype: str = Field( - "avro", - const=True, - ) - - double_as_string: bool = Field( - title="Convert Double Fields to Strings", - description="Whether to convert double fields to strings. This is recommended if you have decimal numbers with a high degree of precision because there can be a loss precision when handling floating point numbers.", - default=False, - ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/csv_format.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/csv_format.py deleted file mode 100644 index 317a01722078..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/csv_format.py +++ /dev/null @@ -1,197 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import codecs -from enum import Enum -from typing import Any, Dict, List, Optional, Set, Union - -from airbyte_cdk.utils.oneof_option_config import OneOfOptionConfig -from pydantic.v1 import BaseModel, Field, root_validator, validator -from pydantic.v1.error_wrappers import ValidationError - - -class InferenceType(Enum): - NONE = "None" - PRIMITIVE_TYPES_ONLY = "Primitive Types Only" - - -class CsvHeaderDefinitionType(Enum): - FROM_CSV = "From CSV" - AUTOGENERATED = "Autogenerated" - USER_PROVIDED = "User Provided" - - -class CsvHeaderFromCsv(BaseModel): - class Config(OneOfOptionConfig): - title = "From CSV" - discriminator = "header_definition_type" - - header_definition_type: str = Field( - CsvHeaderDefinitionType.FROM_CSV.value, - const=True, - ) - - def has_header_row(self) -> bool: - return True - - -class CsvHeaderAutogenerated(BaseModel): - class Config(OneOfOptionConfig): - title = "Autogenerated" - discriminator = "header_definition_type" - - header_definition_type: str = Field( - CsvHeaderDefinitionType.AUTOGENERATED.value, - const=True, - ) - - def has_header_row(self) -> bool: - return False - - -class CsvHeaderUserProvided(BaseModel): - class Config(OneOfOptionConfig): - title = "User Provided" - discriminator = "header_definition_type" - - header_definition_type: str = Field( - CsvHeaderDefinitionType.USER_PROVIDED.value, - const=True, - ) - column_names: List[str] = Field( - title="Column Names", - description="The column names that will be used while emitting the CSV records", - ) - - def has_header_row(self) -> bool: - return False - - @validator("column_names") - def validate_column_names(cls, v: List[str]) -> List[str]: - if not v: - raise ValueError("At least one column name needs to be provided when using user provided headers") - return v - - -DEFAULT_TRUE_VALUES = ["y", "yes", "t", "true", "on", "1"] -DEFAULT_FALSE_VALUES = ["n", "no", "f", "false", "off", "0"] - - -class CsvFormat(BaseModel): - class Config(OneOfOptionConfig): - title = "CSV Format" - discriminator = "filetype" - - filetype: str = Field( - "csv", - const=True, - ) - delimiter: str = Field( - title="Delimiter", - description="The character delimiting individual cells in the CSV data. This may only be a 1-character string. For tab-delimited data enter '\\t'.", - default=",", - ) - quote_char: str = Field( - title="Quote Character", - default='"', - description="The character used for quoting CSV values. To disallow quoting, make this field blank.", - ) - escape_char: Optional[str] = Field( - title="Escape Character", - default=None, - description="The character used for escaping special characters. To disallow escaping, leave this field blank.", - ) - encoding: Optional[str] = Field( - default="utf8", - description='The character encoding of the CSV data. Leave blank to default to UTF8. See list of python encodings for allowable options.', - ) - double_quote: bool = Field( - title="Double Quote", default=True, description="Whether two quotes in a quoted CSV value denote a single quote in the data." - ) - null_values: Set[str] = Field( - title="Null Values", - default=[], - description="A set of case-sensitive strings that should be interpreted as null values. For example, if the value 'NA' should be interpreted as null, enter 'NA' in this field.", - ) - strings_can_be_null: bool = Field( - title="Strings Can Be Null", - default=True, - description="Whether strings can be interpreted as null values. If true, strings that match the null_values set will be interpreted as null. If false, strings that match the null_values set will be interpreted as the string itself.", - ) - skip_rows_before_header: int = Field( - title="Skip Rows Before Header", - default=0, - description="The number of rows to skip before the header row. For example, if the header row is on the 3rd row, enter 2 in this field.", - ) - skip_rows_after_header: int = Field( - title="Skip Rows After Header", default=0, description="The number of rows to skip after the header row." - ) - header_definition: Union[CsvHeaderFromCsv, CsvHeaderAutogenerated, CsvHeaderUserProvided] = Field( - title="CSV Header Definition", - default=CsvHeaderFromCsv(header_definition_type=CsvHeaderDefinitionType.FROM_CSV.value), - description="How headers will be defined. `User Provided` assumes the CSV does not have a header row and uses the headers provided and `Autogenerated` assumes the CSV does not have a header row and the CDK will generate headers using for `f{i}` where `i` is the index starting from 0. Else, the default behavior is to use the header from the CSV file. If a user wants to autogenerate or provide column names for a CSV having headers, they can skip rows.", - ) - true_values: Set[str] = Field( - title="True Values", - default=DEFAULT_TRUE_VALUES, - description="A set of case-sensitive strings that should be interpreted as true values.", - ) - false_values: Set[str] = Field( - title="False Values", - default=DEFAULT_FALSE_VALUES, - description="A set of case-sensitive strings that should be interpreted as false values.", - ) - inference_type: InferenceType = Field( - title="Inference Type", - default=InferenceType.NONE, - description="How to infer the types of the columns. If none, inference default to strings.", - airbyte_hidden=True, - ) - ignore_errors_on_fields_mismatch: bool = Field( - title="Ignore errors on field mismatch", - default=False, - description="Whether to ignore errors that occur when the number of fields in the CSV does not match the number of columns in the schema.", - ) - - @validator("delimiter") - def validate_delimiter(cls, v: str) -> str: - if v == r"\t": - v = "\t" - if len(v) != 1: - raise ValueError("delimiter should only be one character") - if v in {"\r", "\n"}: - raise ValueError(f"delimiter cannot be {v}") - return v - - @validator("quote_char") - def validate_quote_char(cls, v: str) -> str: - if len(v) != 1: - raise ValueError("quote_char should only be one character") - return v - - @validator("escape_char") - def validate_escape_char(cls, v: str) -> str: - if v is not None and len(v) != 1: - raise ValueError("escape_char should only be one character") - return v - - @validator("encoding") - def validate_encoding(cls, v: str) -> str: - try: - codecs.lookup(v) - except LookupError: - raise ValueError(f"invalid encoding format: {v}") - return v - - @root_validator - def validate_optional_args(cls, values: Dict[str, Any]) -> Dict[str, Any]: - definition_type = values.get("header_definition_type") - column_names = values.get("user_provided_column_names") - if definition_type == CsvHeaderDefinitionType.USER_PROVIDED and not column_names: - raise ValidationError("`user_provided_column_names` should be defined if the definition 'User Provided'.", model=CsvFormat) - if definition_type != CsvHeaderDefinitionType.USER_PROVIDED and column_names: - raise ValidationError( - "`user_provided_column_names` should not be defined if the definition is not 'User Provided'.", model=CsvFormat - ) - return values diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/excel_format.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/excel_format.py deleted file mode 100644 index 02a4f52d2a76..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/excel_format.py +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.utils.oneof_option_config import OneOfOptionConfig -from pydantic.v1 import BaseModel, Field - - -class ExcelFormat(BaseModel): - class Config(OneOfOptionConfig): - title = "Excel Format" - discriminator = "filetype" - - filetype: str = Field( - "excel", - const=True, - ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py deleted file mode 100644 index 5419f4a679dd..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py +++ /dev/null @@ -1,94 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from enum import Enum -from typing import Any, List, Mapping, Optional, Union - -from airbyte_cdk.sources.file_based.config.avro_format import AvroFormat -from airbyte_cdk.sources.file_based.config.csv_format import CsvFormat -from airbyte_cdk.sources.file_based.config.excel_format import ExcelFormat -from airbyte_cdk.sources.file_based.config.jsonl_format import JsonlFormat -from airbyte_cdk.sources.file_based.config.parquet_format import ParquetFormat -from airbyte_cdk.sources.file_based.config.unstructured_format import UnstructuredFormat -from airbyte_cdk.sources.file_based.exceptions import ConfigValidationError, FileBasedSourceError -from airbyte_cdk.sources.file_based.schema_helpers import type_mapping_to_jsonschema -from pydantic.v1 import BaseModel, Field, validator - -PrimaryKeyType = Optional[Union[str, List[str]]] - - -class ValidationPolicy(Enum): - emit_record = "Emit Record" - skip_record = "Skip Record" - wait_for_discover = "Wait for Discover" - - -class FileBasedStreamConfig(BaseModel): - name: str = Field(title="Name", description="The name of the stream.") - globs: Optional[List[str]] = Field( - default=["**"], - title="Globs", - description='The pattern used to specify which files should be selected from the file system. For more information on glob pattern matching look here.', - order=1, - ) - legacy_prefix: Optional[str] = Field( - title="Legacy Prefix", - description="The path prefix configured in v3 versions of the S3 connector. This option is deprecated in favor of a single glob.", - airbyte_hidden=True, - ) - validation_policy: ValidationPolicy = Field( - title="Validation Policy", - description="The name of the validation policy that dictates sync behavior when a record does not adhere to the stream schema.", - default=ValidationPolicy.emit_record, - ) - input_schema: Optional[str] = Field( - title="Input Schema", - description="The schema that will be used to validate records extracted from the file. This will override the stream schema that is auto-detected from incoming files.", - ) - primary_key: Optional[str] = Field( - title="Primary Key", - description="The column or columns (for a composite key) that serves as the unique identifier of a record. If empty, the primary key will default to the parser's default primary key.", - airbyte_hidden=True, # Users can create/modify primary keys in the connection configuration so we shouldn't duplicate it here. - ) - days_to_sync_if_history_is_full: int = Field( - title="Days To Sync If History Is Full", - description="When the state history of the file store is full, syncs will only read files that were last modified in the provided day range.", - default=3, - ) - format: Union[AvroFormat, CsvFormat, JsonlFormat, ParquetFormat, UnstructuredFormat, ExcelFormat] = Field( - title="Format", - description="The configuration options that are used to alter how to read incoming files that deviate from the standard formatting.", - ) - schemaless: bool = Field( - title="Schemaless", - description="When enabled, syncs will not validate or structure records against the stream's schema.", - default=False, - ) - recent_n_files_to_read_for_schema_discovery: Optional[int] = Field( - title="Files To Read For Schema Discover", - description="The number of resent files which will be used to discover the schema for this stream.", - default=None, - gt=0, - ) - - @validator("input_schema", pre=True) - def validate_input_schema(cls, v: Optional[str]) -> Optional[str]: - if v: - if type_mapping_to_jsonschema(v): - return v - else: - raise ConfigValidationError(FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA) - return None - - def get_input_schema(self) -> Optional[Mapping[str, Any]]: - """ - User defined input_schema is defined as a string in the config. This method takes the string representation - and converts it into a Mapping[str, Any] which is used by file-based CDK components. - """ - if self.input_schema: - schema = type_mapping_to_jsonschema(self.input_schema) - if not schema: - raise ValueError(f"Unable to create JSON schema from input schema {self.input_schema}") - return schema - return None diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/jsonl_format.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/jsonl_format.py deleted file mode 100644 index 1d9ed54fe083..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/jsonl_format.py +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.utils.oneof_option_config import OneOfOptionConfig -from pydantic.v1 import BaseModel, Field - - -class JsonlFormat(BaseModel): - class Config(OneOfOptionConfig): - title = "Jsonl Format" - discriminator = "filetype" - - filetype: str = Field( - "jsonl", - const=True, - ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/parquet_format.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/parquet_format.py deleted file mode 100644 index 7c40f8e3d431..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/parquet_format.py +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from airbyte_cdk.utils.oneof_option_config import OneOfOptionConfig -from pydantic.v1 import BaseModel, Field - - -class ParquetFormat(BaseModel): - class Config(OneOfOptionConfig): - title = "Parquet Format" - discriminator = "filetype" - - filetype: str = Field( - "parquet", - const=True, - ) - # This option is not recommended, but necessary for backwards compatibility - decimal_as_float: bool = Field( - title="Convert Decimal Fields to Floats", - description="Whether to convert decimal fields to floats. There is a loss of precision when converting decimals to floats, so this is not recommended.", - default=False, - ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/unstructured_format.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/unstructured_format.py deleted file mode 100644 index 7858ae61d327..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/unstructured_format.py +++ /dev/null @@ -1,94 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import List, Literal, Optional, Union - -from airbyte_cdk.utils.oneof_option_config import OneOfOptionConfig -from pydantic.v1 import BaseModel, Field - - -class LocalProcessingConfigModel(BaseModel): - mode: Literal["local"] = Field("local", const=True) - - class Config(OneOfOptionConfig): - title = "Local" - description = "Process files locally, supporting `fast` and `ocr` modes. This is the default option." - discriminator = "mode" - - -class APIParameterConfigModel(BaseModel): - name: str = Field( - title="Parameter name", - description="The name of the unstructured API parameter to use", - examples=["combine_under_n_chars", "languages"], - ) - value: str = Field(title="Value", description="The value of the parameter", examples=["true", "hi_res"]) - - -class APIProcessingConfigModel(BaseModel): - mode: Literal["api"] = Field("api", const=True) - - api_key: str = Field( - default="", - always_show=True, - title="API Key", - airbyte_secret=True, - description="The API key to use matching the environment", - ) - - api_url: str = Field( - default="https://api.unstructured.io", - title="API URL", - always_show=True, - description="The URL of the unstructured API to use", - examples=["https://api.unstructured.com"], - ) - - parameters: Optional[List[APIParameterConfigModel]] = Field( - default=[], - always_show=True, - title="Additional URL Parameters", - description="List of parameters send to the API", - ) - - class Config(OneOfOptionConfig): - title = "via API" - description = "Process files via an API, using the `hi_res` mode. This option is useful for increased performance and accuracy, but requires an API key and a hosted instance of unstructured." - discriminator = "mode" - - -class UnstructuredFormat(BaseModel): - class Config(OneOfOptionConfig): - title = "Unstructured Document Format" - description = "Extract text from document formats (.pdf, .docx, .md, .pptx) and emit as one record per file." - discriminator = "filetype" - - filetype: str = Field( - "unstructured", - const=True, - ) - - skip_unprocessable_files: bool = Field( - default=True, - title="Skip Unprocessable Files", - description="If true, skip files that cannot be parsed and pass the error message along as the _ab_source_file_parse_error field. If false, fail the sync.", - always_show=True, - ) - - strategy: str = Field( - always_show=True, - order=0, - default="auto", - title="Parsing Strategy", - enum=["auto", "fast", "ocr_only", "hi_res"], - description="The strategy used to parse documents. `fast` extracts text directly from the document which doesn't work for all files. `ocr_only` is more reliable, but slower. `hi_res` is the most reliable, but requires an API key and a hosted instance of unstructured and can't be used with local mode. See the unstructured.io documentation for more details: https://unstructured-io.github.io/unstructured/core/partition.html#partition-pdf", - ) - - processing: Union[LocalProcessingConfigModel, APIProcessingConfigModel,] = Field( - default=LocalProcessingConfigModel(mode="local"), - title="Processing", - description="Processing configuration", - discriminator="mode", - type="object", - ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/discovery_policy/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/discovery_policy/__init__.py deleted file mode 100644 index c50aa1a4e70f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/discovery_policy/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from airbyte_cdk.sources.file_based.discovery_policy.abstract_discovery_policy import AbstractDiscoveryPolicy -from airbyte_cdk.sources.file_based.discovery_policy.default_discovery_policy import DefaultDiscoveryPolicy - -__all__ = ["AbstractDiscoveryPolicy", "DefaultDiscoveryPolicy"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/discovery_policy/abstract_discovery_policy.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/discovery_policy/abstract_discovery_policy.py deleted file mode 100644 index ca2645787dc7..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/discovery_policy/abstract_discovery_policy.py +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import ABC, abstractmethod - -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser - - -class AbstractDiscoveryPolicy(ABC): - """ - Used during discovery; allows the developer to configure the number of concurrent - requests to send to the source, and the number of files to use for schema discovery. - """ - - @property - @abstractmethod - def n_concurrent_requests(self) -> int: - ... - - @abstractmethod - def get_max_n_files_for_schema_inference(self, parser: FileTypeParser) -> int: - ... diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/discovery_policy/default_discovery_policy.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/discovery_policy/default_discovery_policy.py deleted file mode 100644 index 3ce098899fc0..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/discovery_policy/default_discovery_policy.py +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.file_based.discovery_policy.abstract_discovery_policy import AbstractDiscoveryPolicy -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser - -DEFAULT_N_CONCURRENT_REQUESTS = 10 -DEFAULT_MAX_N_FILES_FOR_STREAM_SCHEMA_INFERENCE = 10 - - -class DefaultDiscoveryPolicy(AbstractDiscoveryPolicy): - """ - Default number of concurrent requests to send to the source on discover, and number - of files to use for schema inference. - """ - - @property - def n_concurrent_requests(self) -> int: - return DEFAULT_N_CONCURRENT_REQUESTS - - def get_max_n_files_for_schema_inference(self, parser: FileTypeParser) -> int: - return min( - filter( - None, - (DEFAULT_MAX_N_FILES_FOR_STREAM_SCHEMA_INFERENCE, parser.parser_max_n_files_for_schema_inference), - ) - ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/exceptions.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/exceptions.py deleted file mode 100644 index 5bb43e43fbd3..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/exceptions.py +++ /dev/null @@ -1,123 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from enum import Enum -from typing import Any, List, Union - -from airbyte_cdk.models import AirbyteMessage, FailureType -from airbyte_cdk.utils import AirbyteTracedException - - -class FileBasedSourceError(Enum): - EMPTY_STREAM = "No files were identified in the stream. This may be because there are no files in the specified container, or because your glob patterns did not match any files. Please verify that your source contains files last modified after the start_date and that your glob patterns are not overly strict." - GLOB_PARSE_ERROR = ( - "Error parsing glob pattern. Please refer to the glob pattern rules at https://facelessuser.github.io/wcmatch/glob/#split." - ) - ENCODING_ERROR = "File encoding error. The configured encoding must match file encoding." - ERROR_CASTING_VALUE = "Could not cast the value to the expected type." - ERROR_CASTING_VALUE_UNRECOGNIZED_TYPE = "Could not cast the value to the expected type because the type is not recognized. Valid types are null, array, boolean, integer, number, object, and string." - ERROR_DECODING_VALUE = "Expected a JSON-decodeable value but could not decode record." - ERROR_LISTING_FILES = ( - "Error listing files. Please check the credentials provided in the config and verify that they provide permission to list files." - ) - ERROR_READING_FILE = ( - "Error opening file. Please check the credentials provided in the config and verify that they provide permission to read files." - ) - ERROR_PARSING_RECORD = "Error parsing record. This could be due to a mismatch between the config's file type and the actual file type, or because the file or record is not parseable." - ERROR_PARSING_USER_PROVIDED_SCHEMA = "The provided schema could not be transformed into valid JSON Schema." - ERROR_VALIDATING_RECORD = "One or more records do not pass the schema validation policy. Please modify your input schema, or select a more lenient validation policy." - ERROR_PARSING_RECORD_MISMATCHED_COLUMNS = "A header field has resolved to `None`. This indicates that the CSV has more rows than the number of header fields. If you input your schema or headers, please verify that the number of columns corresponds to the number of columns in your CSV's rows." - ERROR_PARSING_RECORD_MISMATCHED_ROWS = "A row's value has resolved to `None`. This indicates that the CSV has more columns in the header field than the number of columns in the row(s). If you input your schema or headers, please verify that the number of columns corresponds to the number of columns in your CSV's rows." - STOP_SYNC_PER_SCHEMA_VALIDATION_POLICY = ( - "Stopping sync in accordance with the configured validation policy. Records in file did not conform to the schema." - ) - NULL_VALUE_IN_SCHEMA = "Error during schema inference: no type was detected for key." - UNRECOGNIZED_TYPE = "Error during schema inference: unrecognized type." - SCHEMA_INFERENCE_ERROR = "Error inferring schema from files. Are the files valid?" - INVALID_SCHEMA_ERROR = "No fields were identified for this schema. This may happen if the stream is empty. Please check your configuration to verify that there are files that match the stream's glob patterns." - CONFIG_VALIDATION_ERROR = "Error creating stream config object." - MISSING_SCHEMA = "Expected `json_schema` in the configured catalog but it is missing." - UNDEFINED_PARSER = "No parser is defined for this file type." - UNDEFINED_VALIDATION_POLICY = "The validation policy defined in the config does not exist for the source." - - -class FileBasedErrorsCollector: - """ - The placeholder for all errors collected. - """ - - errors: List[AirbyteMessage] = [] - - def yield_and_raise_collected(self) -> Any: - if self.errors: - # emit collected logged messages - yield from self.errors - # clean the collector - self.errors.clear() - # raising the single exception - raise AirbyteTracedException( - internal_message="Please check the logged errors for more information.", - message="Some errors occured while reading from the source.", - failure_type=FailureType.config_error, - ) - - def collect(self, logged_error: AirbyteMessage) -> None: - self.errors.append(logged_error) - - -class BaseFileBasedSourceError(Exception): - def __init__(self, error: Union[FileBasedSourceError, str], **kwargs): # type: ignore # noqa - if isinstance(error, FileBasedSourceError): - error = FileBasedSourceError(error).value - super().__init__(f"{error} Contact Support if you need assistance.\n{' '.join([f'{k}={v}' for k, v in kwargs.items()])}") - - -class ConfigValidationError(BaseFileBasedSourceError): - pass - - -class InvalidSchemaError(BaseFileBasedSourceError): - pass - - -class MissingSchemaError(BaseFileBasedSourceError): - pass - - -class NoFilesMatchingError(BaseFileBasedSourceError): - pass - - -class RecordParseError(BaseFileBasedSourceError): - pass - - -class SchemaInferenceError(BaseFileBasedSourceError): - pass - - -class CheckAvailabilityError(BaseFileBasedSourceError): - pass - - -class UndefinedParserError(BaseFileBasedSourceError): - pass - - -class StopSyncPerValidationPolicy(BaseFileBasedSourceError): - pass - - -class ErrorListingFiles(BaseFileBasedSourceError): - pass - - -class CustomFileBasedException(AirbyteTracedException): - """ - A specialized exception for file-based connectors. - - This exception is designed to bypass the default error handling in the file-based CDK, allowing the use of custom error messages. - """ - - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py deleted file mode 100644 index b023287598bb..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py +++ /dev/null @@ -1,300 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -import traceback -from abc import ABC -from collections import Counter -from typing import Any, Iterator, List, Mapping, MutableMapping, Optional, Tuple, Type, Union - -from airbyte_cdk.logger import AirbyteLogFormatter, init_logger -from airbyte_cdk.models import ( - AirbyteMessage, - AirbyteStateMessage, - AirbyteStream, - ConfiguredAirbyteCatalog, - ConnectorSpecification, - FailureType, - Level, - SyncMode, -) -from airbyte_cdk.sources.concurrent_source.concurrent_source import ConcurrentSource -from airbyte_cdk.sources.concurrent_source.concurrent_source_adapter import ConcurrentSourceAdapter -from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager -from airbyte_cdk.sources.file_based.availability_strategy import AbstractFileBasedAvailabilityStrategy, DefaultFileBasedAvailabilityStrategy -from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig, ValidationPolicy -from airbyte_cdk.sources.file_based.discovery_policy import AbstractDiscoveryPolicy, DefaultDiscoveryPolicy -from airbyte_cdk.sources.file_based.exceptions import ConfigValidationError, FileBasedErrorsCollector, FileBasedSourceError -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader -from airbyte_cdk.sources.file_based.file_types import default_parsers -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser -from airbyte_cdk.sources.file_based.schema_validation_policies import DEFAULT_SCHEMA_VALIDATION_POLICIES, AbstractSchemaValidationPolicy -from airbyte_cdk.sources.file_based.stream import AbstractFileBasedStream, DefaultFileBasedStream -from airbyte_cdk.sources.file_based.stream.concurrent.adapters import FileBasedStreamFacade -from airbyte_cdk.sources.file_based.stream.concurrent.cursor import ( - AbstractConcurrentFileBasedCursor, - FileBasedConcurrentCursor, - FileBasedFinalStateCursor, -) -from airbyte_cdk.sources.file_based.stream.cursor import AbstractFileBasedCursor -from airbyte_cdk.sources.message.repository import InMemoryMessageRepository, MessageRepository -from airbyte_cdk.sources.streams import Stream -from airbyte_cdk.sources.streams.concurrent.cursor import CursorField -from airbyte_cdk.utils.analytics_message import create_analytics_message -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from pydantic.v1.error_wrappers import ValidationError - -DEFAULT_CONCURRENCY = 100 -MAX_CONCURRENCY = 100 -INITIAL_N_PARTITIONS = MAX_CONCURRENCY // 2 - - -class FileBasedSource(ConcurrentSourceAdapter, ABC): - # We make each source override the concurrency level to give control over when they are upgraded. - _concurrency_level = None - - def __init__( - self, - stream_reader: AbstractFileBasedStreamReader, - spec_class: Type[AbstractFileBasedSpec], - catalog: Optional[ConfiguredAirbyteCatalog], - config: Optional[Mapping[str, Any]], - state: Optional[List[AirbyteStateMessage]], - availability_strategy: Optional[AbstractFileBasedAvailabilityStrategy] = None, - discovery_policy: AbstractDiscoveryPolicy = DefaultDiscoveryPolicy(), - parsers: Mapping[Type[Any], FileTypeParser] = default_parsers, - validation_policies: Mapping[ValidationPolicy, AbstractSchemaValidationPolicy] = DEFAULT_SCHEMA_VALIDATION_POLICIES, - cursor_cls: Type[Union[AbstractConcurrentFileBasedCursor, AbstractFileBasedCursor]] = FileBasedConcurrentCursor, - ): - self.stream_reader = stream_reader - self.spec_class = spec_class - self.config = config - self.catalog = catalog - self.state = state - self.availability_strategy = availability_strategy or DefaultFileBasedAvailabilityStrategy(stream_reader) - self.discovery_policy = discovery_policy - self.parsers = parsers - self.validation_policies = validation_policies - self.stream_schemas = {s.stream.name: s.stream.json_schema for s in catalog.streams} if catalog else {} - self.cursor_cls = cursor_cls - self.logger = init_logger(f"airbyte.{self.name}") - self.errors_collector: FileBasedErrorsCollector = FileBasedErrorsCollector() - self._message_repository: Optional[MessageRepository] = None - concurrent_source = ConcurrentSource.create( - MAX_CONCURRENCY, INITIAL_N_PARTITIONS, self.logger, self._slice_logger, self.message_repository - ) - self._state = None - super().__init__(concurrent_source) - - @property - def message_repository(self) -> MessageRepository: - if self._message_repository is None: - self._message_repository = InMemoryMessageRepository(Level(AirbyteLogFormatter.level_mapping[self.logger.level])) - return self._message_repository - - def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Optional[Any]]: - """ - Check that the source can be accessed using the user-provided configuration. - - For each stream, verify that we can list and read files. - - Returns (True, None) if the connection check is successful. - - Otherwise, the "error" object should describe what went wrong. - """ - try: - streams = self.streams(config) - except Exception as config_exception: - raise AirbyteTracedException( - internal_message="Please check the logged errors for more information.", - message=FileBasedSourceError.CONFIG_VALIDATION_ERROR.value, - exception=AirbyteTracedException(exception=config_exception), - failure_type=FailureType.config_error, - ) - if len(streams) == 0: - return ( - False, - f"No streams are available for source {self.name}. This is probably an issue with the connector. Please verify that your " - f"configuration provides permissions to list and read files from the source. Contact support if you are unable to " - f"resolve this issue.", - ) - - errors = [] - tracebacks = [] - for stream in streams: - if not isinstance(stream, AbstractFileBasedStream): - raise ValueError(f"Stream {stream} is not a file-based stream.") - try: - ( - stream_is_available, - reason, - ) = stream.availability_strategy.check_availability_and_parsability(stream, logger, self) - except AirbyteTracedException as ate: - errors.append(f"Unable to connect to stream {stream.name} - {ate.message}") - tracebacks.append(traceback.format_exc()) - except Exception: - errors.append(f"Unable to connect to stream {stream.name}") - tracebacks.append(traceback.format_exc()) - else: - if not stream_is_available and reason: - errors.append(reason) - - if len(errors) == 1 and len(tracebacks) == 1: - raise AirbyteTracedException( - internal_message=tracebacks[0], - message=f"{errors[0]}", - failure_type=FailureType.config_error, - ) - if len(errors) == 1 and len(tracebacks) == 0: - raise AirbyteTracedException( - message=f"{errors[0]}", - failure_type=FailureType.config_error, - ) - elif len(errors) > 1: - raise AirbyteTracedException( - internal_message="\n".join(tracebacks), - message=f"{len(errors)} streams with errors: {', '.join(error for error in errors)}", - failure_type=FailureType.config_error, - ) - - return not bool(errors), (errors or None) - - def streams(self, config: Mapping[str, Any]) -> List[Stream]: - """ - Return a list of this source's streams. - """ - - if self.catalog: - state_manager = ConnectorStateManager(state=self.state) - else: - # During `check` operations we don't have a catalog so cannot create a state manager. - # Since the state manager is only required for incremental syncs, this is fine. - state_manager = None - - try: - parsed_config = self._get_parsed_config(config) - self.stream_reader.config = parsed_config - streams: List[Stream] = [] - for stream_config in parsed_config.streams: - # Like state_manager, `catalog_stream` may be None during `check` - catalog_stream = self._get_stream_from_catalog(stream_config) - stream_state = ( - state_manager.get_stream_state(catalog_stream.name, catalog_stream.namespace) - if (state_manager and catalog_stream) - else None - ) - self._validate_input_schema(stream_config) - - sync_mode = self._get_sync_mode_from_catalog(stream_config.name) - - if sync_mode == SyncMode.full_refresh and hasattr(self, "_concurrency_level") and self._concurrency_level is not None: - cursor = FileBasedFinalStateCursor( - stream_config=stream_config, stream_namespace=None, message_repository=self.message_repository - ) - stream = FileBasedStreamFacade.create_from_stream( - self._make_default_stream(stream_config, cursor), self, self.logger, stream_state, cursor - ) - - elif ( - sync_mode == SyncMode.incremental - and issubclass(self.cursor_cls, AbstractConcurrentFileBasedCursor) - and hasattr(self, "_concurrency_level") - and self._concurrency_level is not None - ): - assert ( - state_manager is not None - ), "No ConnectorStateManager was created, but it is required for incremental syncs. This is unexpected. Please contact Support." - - cursor = self.cursor_cls( - stream_config, - stream_config.name, - None, - stream_state, - self.message_repository, - state_manager, - CursorField(DefaultFileBasedStream.ab_last_mod_col), - ) - stream = FileBasedStreamFacade.create_from_stream( - self._make_default_stream(stream_config, cursor), self, self.logger, stream_state, cursor - ) - else: - cursor = self.cursor_cls(stream_config) - stream = self._make_default_stream(stream_config, cursor) - - streams.append(stream) - return streams - - except ValidationError as exc: - raise ConfigValidationError(FileBasedSourceError.CONFIG_VALIDATION_ERROR) from exc - - def _make_default_stream( - self, stream_config: FileBasedStreamConfig, cursor: Optional[AbstractFileBasedCursor] - ) -> AbstractFileBasedStream: - return DefaultFileBasedStream( - config=stream_config, - catalog_schema=self.stream_schemas.get(stream_config.name), - stream_reader=self.stream_reader, - availability_strategy=self.availability_strategy, - discovery_policy=self.discovery_policy, - parsers=self.parsers, - validation_policy=self._validate_and_get_validation_policy(stream_config), - errors_collector=self.errors_collector, - cursor=cursor, - ) - - def _get_stream_from_catalog(self, stream_config: FileBasedStreamConfig) -> Optional[AirbyteStream]: - if self.catalog: - for stream in self.catalog.streams or []: - if stream.stream.name == stream_config.name: - return stream.stream - return None - - def _get_sync_mode_from_catalog(self, stream_name: str) -> Optional[SyncMode]: - if self.catalog: - for catalog_stream in self.catalog.streams: - if stream_name == catalog_stream.stream.name: - return catalog_stream.sync_mode - self.logger.warning(f"No sync mode was found for {stream_name}.") - return None - - def read( - self, - logger: logging.Logger, - config: Mapping[str, Any], - catalog: ConfiguredAirbyteCatalog, - state: Optional[Union[List[AirbyteStateMessage], MutableMapping[str, Any]]] = None, - ) -> Iterator[AirbyteMessage]: - yield from super().read(logger, config, catalog, state) - # emit all the errors collected - yield from self.errors_collector.yield_and_raise_collected() - # count streams using a certain parser - parsed_config = self._get_parsed_config(config) - for parser, count in Counter(stream.format.filetype for stream in parsed_config.streams).items(): - yield create_analytics_message(f"file-cdk-{parser}-stream-count", count) - - def spec(self, *args: Any, **kwargs: Any) -> ConnectorSpecification: - """ - Returns the specification describing what fields can be configured by a user when setting up a file-based source. - """ - - return ConnectorSpecification( - documentationUrl=self.spec_class.documentation_url(), - connectionSpecification=self.spec_class.schema(), - ) - - def _get_parsed_config(self, config: Mapping[str, Any]) -> AbstractFileBasedSpec: - return self.spec_class(**config) - - def _validate_and_get_validation_policy(self, stream_config: FileBasedStreamConfig) -> AbstractSchemaValidationPolicy: - if stream_config.validation_policy not in self.validation_policies: - # This should never happen because we validate the config against the schema's validation_policy enum - raise ValidationError( - f"`validation_policy` must be one of {list(self.validation_policies.keys())}", model=FileBasedStreamConfig - ) - return self.validation_policies[stream_config.validation_policy] - - def _validate_input_schema(self, stream_config: FileBasedStreamConfig) -> None: - if stream_config.schemaless and stream_config.input_schema: - raise ValidationError("`input_schema` and `schemaless` options cannot both be set", model=FileBasedStreamConfig) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_stream_reader.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_stream_reader.py deleted file mode 100644 index 4a7de3bb6992..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_stream_reader.py +++ /dev/null @@ -1,107 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from abc import ABC, abstractmethod -from datetime import datetime -from enum import Enum -from io import IOBase -from typing import Iterable, List, Optional, Set - -from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from wcmatch.glob import GLOBSTAR, globmatch - - -class FileReadMode(Enum): - READ = "r" - READ_BINARY = "rb" - - -class AbstractFileBasedStreamReader(ABC): - DATE_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ" - - def __init__(self) -> None: - self._config = None - - @property - def config(self) -> Optional[AbstractFileBasedSpec]: - return self._config - - @config.setter - @abstractmethod - def config(self, value: AbstractFileBasedSpec) -> None: - """ - FileBasedSource reads the config from disk and parses it, and once parsed, the source sets the config on its StreamReader. - - Note: FileBasedSource only requires the keys defined in the abstract config, whereas concrete implementations of StreamReader - will require keys that (for example) allow it to authenticate with the 3rd party. - - Therefore, concrete implementations of AbstractFileBasedStreamReader's config setter should assert that `value` is of the correct - config type for that type of StreamReader. - """ - ... - - @abstractmethod - def open_file(self, file: RemoteFile, mode: FileReadMode, encoding: Optional[str], logger: logging.Logger) -> IOBase: - """ - Return a file handle for reading. - - Many sources will be able to use smart_open to implement this method, - for example: - - client = boto3.Session(...) - return smart_open.open(remote_file.uri, transport_params={"client": client}) - """ - ... - - @abstractmethod - def get_matching_files( - self, - globs: List[str], - prefix: Optional[str], - logger: logging.Logger, - ) -> Iterable[RemoteFile]: - """ - Return all files that match any of the globs. - - Example: - - The source has files "a.json", "foo/a.json", "foo/bar/a.json" - - If globs = ["*.json"] then this method returns ["a.json"]. - - If globs = ["foo/*.json"] then this method returns ["foo/a.json"]. - - Utility method `self.filter_files_by_globs` and `self.get_prefixes_from_globs` - are available, which may be helpful when implementing this method. - """ - ... - - def filter_files_by_globs_and_start_date(self, files: List[RemoteFile], globs: List[str]) -> Iterable[RemoteFile]: - """ - Utility method for filtering files based on globs. - """ - start_date = datetime.strptime(self.config.start_date, self.DATE_TIME_FORMAT) if self.config and self.config.start_date else None - seen = set() - - for file in files: - if self.file_matches_globs(file, globs): - if file.uri not in seen and (not start_date or file.last_modified >= start_date): - seen.add(file.uri) - yield file - - @staticmethod - def file_matches_globs(file: RemoteFile, globs: List[str]) -> bool: - # Use the GLOBSTAR flag to enable recursive ** matching - # (https://facelessuser.github.io/wcmatch/wcmatch/#globstar) - return any(globmatch(file.uri, g, flags=GLOBSTAR) for g in globs) - - @staticmethod - def get_prefixes_from_globs(globs: List[str]) -> Set[str]: - """ - Utility method for extracting prefixes from the globs. - """ - prefixes = {glob.split("*")[0] for glob in globs} - return set(filter(lambda x: bool(x), prefixes)) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/__init__.py deleted file mode 100644 index 0faabf0e97f9..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import Any, Mapping, Type - -from airbyte_cdk.sources.file_based.config.avro_format import AvroFormat -from airbyte_cdk.sources.file_based.config.excel_format import ExcelFormat -from airbyte_cdk.sources.file_based.config.csv_format import CsvFormat -from airbyte_cdk.sources.file_based.config.jsonl_format import JsonlFormat -from airbyte_cdk.sources.file_based.config.parquet_format import ParquetFormat -from airbyte_cdk.sources.file_based.config.unstructured_format import UnstructuredFormat - -from .avro_parser import AvroParser -from .csv_parser import CsvParser -from .excel_parser import ExcelParser -from .file_type_parser import FileTypeParser -from .jsonl_parser import JsonlParser -from .parquet_parser import ParquetParser -from .unstructured_parser import UnstructuredParser - -default_parsers: Mapping[Type[Any], FileTypeParser] = { - AvroFormat: AvroParser(), - CsvFormat: CsvParser(), - ExcelFormat: ExcelParser(), - JsonlFormat: JsonlParser(), - ParquetFormat: ParquetParser(), - UnstructuredFormat: UnstructuredParser(), -} - -__all__ = ["AvroParser", "CsvParser", "ExcelParser", "JsonlParser", "ParquetParser", "UnstructuredParser", "default_parsers"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/avro_parser.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/avro_parser.py deleted file mode 100644 index b033afa57fb3..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/avro_parser.py +++ /dev/null @@ -1,188 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from typing import Any, Dict, Iterable, Mapping, Optional, Tuple - -import fastavro -from airbyte_cdk.sources.file_based.config.avro_format import AvroFormat -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig -from airbyte_cdk.sources.file_based.exceptions import FileBasedSourceError, RecordParseError -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.schema_helpers import SchemaType - -AVRO_TYPE_TO_JSON_TYPE = { - "null": "null", - "boolean": "boolean", - "int": "integer", - "long": "integer", - "float": "number", - "double": "string", # double -> number conversions can lose precision - "bytes": "string", - "string": "string", -} - -AVRO_LOGICAL_TYPE_TO_JSON = { - "decimal": {"type": "string"}, - "uuid": {"type": "string"}, - "date": {"type": "string", "format": "date"}, - "time-millis": {"type": "integer"}, - "time-micros": {"type": "integer"}, - "timestamp-millis": {"type": "string", "format": "date-time"}, - "timestamp-micros": {"type": "string"}, - "local-timestamp-millis": {"type": "string", "format": "date-time"}, - "local-timestamp-micros": {"type": "string"}, - # fastavro does not support duration https://fastavro.readthedocs.io/en/latest/logical_types.html -} - - -class AvroParser(FileTypeParser): - ENCODING = None - - def check_config(self, config: FileBasedStreamConfig) -> Tuple[bool, Optional[str]]: - """ - AvroParser does not require config checks, implicit pydantic validation is enough. - """ - return True, None - - async def infer_schema( - self, - config: FileBasedStreamConfig, - file: RemoteFile, - stream_reader: AbstractFileBasedStreamReader, - logger: logging.Logger, - ) -> SchemaType: - avro_format = config.format - if not isinstance(avro_format, AvroFormat): - raise ValueError(f"Expected ParquetFormat, got {avro_format}") - - with stream_reader.open_file(file, self.file_read_mode, self.ENCODING, logger) as fp: - avro_reader = fastavro.reader(fp) - avro_schema = avro_reader.writer_schema - if not avro_schema["type"] == "record": - unsupported_type = avro_schema["type"] - raise ValueError(f"Only record based avro files are supported. Found {unsupported_type}") - json_schema = { - field["name"]: AvroParser._convert_avro_type_to_json(avro_format, field["name"], field["type"]) - for field in avro_schema["fields"] - } - return json_schema - - @classmethod - def _convert_avro_type_to_json(cls, avro_format: AvroFormat, field_name: str, avro_field: str) -> Mapping[str, Any]: - if isinstance(avro_field, str) and avro_field in AVRO_TYPE_TO_JSON_TYPE: - # Legacy behavior to retain backwards compatibility. Long term we should always represent doubles as strings - if avro_field == "double" and not avro_format.double_as_string: - return {"type": "number"} - return {"type": AVRO_TYPE_TO_JSON_TYPE[avro_field]} - if isinstance(avro_field, Mapping): - if avro_field["type"] == "record": - return { - "type": "object", - "properties": { - object_field["name"]: AvroParser._convert_avro_type_to_json(avro_format, object_field["name"], object_field["type"]) - for object_field in avro_field["fields"] - }, - } - elif avro_field["type"] == "array": - if "items" not in avro_field: - raise ValueError(f"{field_name} array type does not have a required field items") - return {"type": "array", "items": AvroParser._convert_avro_type_to_json(avro_format, "", avro_field["items"])} - elif avro_field["type"] == "enum": - if "symbols" not in avro_field: - raise ValueError(f"{field_name} enum type does not have a required field symbols") - if "name" not in avro_field: - raise ValueError(f"{field_name} enum type does not have a required field name") - return {"type": "string", "enum": avro_field["symbols"]} - elif avro_field["type"] == "map": - if "values" not in avro_field: - raise ValueError(f"{field_name} map type does not have a required field values") - return { - "type": "object", - "additionalProperties": AvroParser._convert_avro_type_to_json(avro_format, "", avro_field["values"]), - } - elif avro_field["type"] == "fixed" and avro_field.get("logicalType") != "duration": - if "size" not in avro_field: - raise ValueError(f"{field_name} fixed type does not have a required field size") - if not isinstance(avro_field["size"], int): - raise ValueError(f"{field_name} fixed type size value is not an integer") - return { - "type": "string", - "pattern": f"^[0-9A-Fa-f]{{{avro_field['size'] * 2}}}$", - } - elif avro_field.get("logicalType") == "decimal": - if "precision" not in avro_field: - raise ValueError(f"{field_name} decimal type does not have a required field precision") - if "scale" not in avro_field: - raise ValueError(f"{field_name} decimal type does not have a required field scale") - max_whole_number_range = avro_field["precision"] - avro_field["scale"] - decimal_range = avro_field["scale"] - - # This regex looks like a mess, but it is validation for at least one whole number and optional fractional numbers - # For example: ^-?\d{1,5}(?:\.\d{1,3})?$ would accept 12345.123 and 123456.12345 would be rejected - return {"type": "string", "pattern": f"^-?\\d{{{1,max_whole_number_range}}}(?:\\.\\d{1,decimal_range})?$"} - elif "logicalType" in avro_field: - if avro_field["logicalType"] not in AVRO_LOGICAL_TYPE_TO_JSON: - raise ValueError(f"{avro_field['logicalType']} is not a valid Avro logical type") - return AVRO_LOGICAL_TYPE_TO_JSON[avro_field["logicalType"]] - else: - raise ValueError(f"Unsupported avro type: {avro_field}") - else: - raise ValueError(f"Unsupported avro type: {avro_field}") - - def parse_records( - self, - config: FileBasedStreamConfig, - file: RemoteFile, - stream_reader: AbstractFileBasedStreamReader, - logger: logging.Logger, - discovered_schema: Optional[Mapping[str, SchemaType]], - ) -> Iterable[Dict[str, Any]]: - avro_format = config.format or AvroFormat(filetype="avro") - if not isinstance(avro_format, AvroFormat): - raise ValueError(f"Expected ParquetFormat, got {avro_format}") - - line_no = 0 - try: - with stream_reader.open_file(file, self.file_read_mode, self.ENCODING, logger) as fp: - avro_reader = fastavro.reader(fp) - schema = avro_reader.writer_schema - schema_field_name_to_type = {field["name"]: field["type"] for field in schema["fields"]} - for record in avro_reader: - line_no += 1 - yield { - record_field: self._to_output_value(avro_format, schema_field_name_to_type[record_field], record[record_field]) - for record_field, record_value in schema_field_name_to_type.items() - } - except Exception as exc: - raise RecordParseError(FileBasedSourceError.ERROR_PARSING_RECORD, filename=file.uri, lineno=line_no) from exc - - @property - def file_read_mode(self) -> FileReadMode: - return FileReadMode.READ_BINARY - - @staticmethod - def _to_output_value(avro_format: AvroFormat, record_type: Mapping[str, Any], record_value: Any) -> Any: - if isinstance(record_value, bytes): - return record_value.decode() - elif not isinstance(record_type, Mapping): - if record_type == "double" and avro_format.double_as_string: - return str(record_value) - return record_value - if record_type.get("logicalType") in ("decimal", "uuid"): - return str(record_value) - elif record_type.get("logicalType") == "date": - return record_value.isoformat() - elif record_type.get("logicalType") == "timestamp-millis": - return record_value.isoformat(sep="T", timespec="milliseconds") - elif record_type.get("logicalType") == "timestamp-micros": - return record_value.isoformat(sep="T", timespec="microseconds") - elif record_type.get("logicalType") == "local-timestamp-millis": - return record_value.isoformat(sep="T", timespec="milliseconds") - elif record_type.get("logicalType") == "local-timestamp-micros": - return record_value.isoformat(sep="T", timespec="microseconds") - else: - return record_value diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/csv_parser.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/csv_parser.py deleted file mode 100644 index 961fc8f14cad..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/csv_parser.py +++ /dev/null @@ -1,463 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import csv -import json -import logging -from abc import ABC, abstractmethod -from collections import defaultdict -from functools import partial -from io import IOBase -from typing import Any, Callable, Dict, Generator, Iterable, List, Mapping, Optional, Set, Tuple -from uuid import uuid4 - -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.file_based.config.csv_format import CsvFormat, CsvHeaderAutogenerated, CsvHeaderUserProvided, InferenceType -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig -from airbyte_cdk.sources.file_based.exceptions import FileBasedSourceError, RecordParseError -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.schema_helpers import TYPE_PYTHON_MAPPING, SchemaType -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from orjson import orjson - -DIALECT_NAME = "_config_dialect" - - -class _CsvReader: - def read_data( - self, - config: FileBasedStreamConfig, - file: RemoteFile, - stream_reader: AbstractFileBasedStreamReader, - logger: logging.Logger, - file_read_mode: FileReadMode, - ) -> Generator[Dict[str, Any], None, None]: - config_format = _extract_format(config) - lineno = 0 - - # Formats are configured individually per-stream so a unique dialect should be registered for each stream. - # We don't unregister the dialect because we are lazily parsing each csv file to generate records - # Give each stream's dialect a unique name; otherwise, when we are doing a concurrent sync we can end up - # with a race condition where a thread attempts to use a dialect before a separate thread has finished - # registering it. - dialect_name = f"{config.name}_{str(uuid4())}_{DIALECT_NAME}" - csv.register_dialect( - dialect_name, - delimiter=config_format.delimiter, - quotechar=config_format.quote_char, - escapechar=config_format.escape_char, - doublequote=config_format.double_quote, - quoting=csv.QUOTE_MINIMAL, - ) - with stream_reader.open_file(file, file_read_mode, config_format.encoding, logger) as fp: - try: - headers = self._get_headers(fp, config_format, dialect_name) - except UnicodeError: - raise AirbyteTracedException( - message=f"{FileBasedSourceError.ENCODING_ERROR.value} Expected encoding: {config_format.encoding}", - ) - - rows_to_skip = ( - config_format.skip_rows_before_header - + (1 if config_format.header_definition.has_header_row() else 0) - + config_format.skip_rows_after_header - ) - self._skip_rows(fp, rows_to_skip) - lineno += rows_to_skip - - reader = csv.DictReader(fp, dialect=dialect_name, fieldnames=headers) # type: ignore - try: - for row in reader: - lineno += 1 - - # The row was not properly parsed if any of the values are None. This will most likely occur if there are more columns - # than headers or more headers dans columns - if None in row: - if config_format.ignore_errors_on_fields_mismatch: - logger.error(f"Skipping record in line {lineno} of file {file.uri}; invalid CSV row with missing column.") - else: - raise RecordParseError( - FileBasedSourceError.ERROR_PARSING_RECORD_MISMATCHED_COLUMNS, - filename=file.uri, - lineno=lineno, - ) - if None in row.values(): - if config_format.ignore_errors_on_fields_mismatch: - logger.error(f"Skipping record in line {lineno} of file {file.uri}; invalid CSV row with extra column.") - else: - raise RecordParseError( - FileBasedSourceError.ERROR_PARSING_RECORD_MISMATCHED_ROWS, filename=file.uri, lineno=lineno - ) - yield row - finally: - # due to RecordParseError or GeneratorExit - csv.unregister_dialect(dialect_name) - - def _get_headers(self, fp: IOBase, config_format: CsvFormat, dialect_name: str) -> List[str]: - """ - Assumes the fp is pointing to the beginning of the files and will reset it as such - """ - # Note that this method assumes the dialect has already been registered if we're parsing the headers - if isinstance(config_format.header_definition, CsvHeaderUserProvided): - return config_format.header_definition.column_names # type: ignore # should be CsvHeaderUserProvided given the type - - if isinstance(config_format.header_definition, CsvHeaderAutogenerated): - self._skip_rows(fp, config_format.skip_rows_before_header + config_format.skip_rows_after_header) - headers = self._auto_generate_headers(fp, dialect_name) - else: - # Then read the header - self._skip_rows(fp, config_format.skip_rows_before_header) - reader = csv.reader(fp, dialect=dialect_name) # type: ignore - headers = list(next(reader)) - - fp.seek(0) - return headers - - def _auto_generate_headers(self, fp: IOBase, dialect_name: str) -> List[str]: - """ - Generates field names as [f0, f1, ...] in the same way as pyarrow's csv reader with autogenerate_column_names=True. - See https://arrow.apache.org/docs/python/generated/pyarrow.csv.ReadOptions.html - """ - reader = csv.reader(fp, dialect=dialect_name) # type: ignore - number_of_columns = len(next(reader)) # type: ignore - return [f"f{i}" for i in range(number_of_columns)] - - @staticmethod - def _skip_rows(fp: IOBase, rows_to_skip: int) -> None: - """ - Skip rows before the header. This has to be done on the file object itself, not the reader - """ - for _ in range(rows_to_skip): - fp.readline() - - -class CsvParser(FileTypeParser): - _MAX_BYTES_PER_FILE_FOR_SCHEMA_INFERENCE = 1_000_000 - - def __init__(self, csv_reader: Optional[_CsvReader] = None, csv_field_max_bytes: int = 2**31): - # Increase the maximum length of data that can be parsed in a single CSV field. The default is 128k, which is typically sufficient - # but given the use of Airbyte in loading a large variety of data it is best to allow for a larger maximum field size to avoid - # skipping data on load. https://stackoverflow.com/questions/15063936/csv-error-field-larger-than-field-limit-131072 - csv.field_size_limit(csv_field_max_bytes) - self._csv_reader = csv_reader if csv_reader else _CsvReader() - - def check_config(self, config: FileBasedStreamConfig) -> Tuple[bool, Optional[str]]: - """ - CsvParser does not require config checks, implicit pydantic validation is enough. - """ - return True, None - - async def infer_schema( - self, - config: FileBasedStreamConfig, - file: RemoteFile, - stream_reader: AbstractFileBasedStreamReader, - logger: logging.Logger, - ) -> SchemaType: - input_schema = config.get_input_schema() - if input_schema: - return input_schema - - # todo: the existing InMemoryFilesSource.open_file() test source doesn't currently require an encoding, but actual - # sources will likely require one. Rather than modify the interface now we can wait until the real use case - config_format = _extract_format(config) - type_inferrer_by_field: Dict[str, _TypeInferrer] = defaultdict( - lambda: _JsonTypeInferrer(config_format.true_values, config_format.false_values, config_format.null_values) - if config_format.inference_type != InferenceType.NONE - else _DisabledTypeInferrer() - ) - data_generator = self._csv_reader.read_data(config, file, stream_reader, logger, self.file_read_mode) - read_bytes = 0 - for row in data_generator: - for header, value in row.items(): - type_inferrer_by_field[header].add_value(value) - # This is not accurate as a representation of how many bytes were read because csv does some processing on the actual value - # before returning. Given we would like to be more accurate, we could wrap the IO file using a decorator - read_bytes += len(value) - read_bytes += len(row) - 1 # for separators - if read_bytes >= self._MAX_BYTES_PER_FILE_FOR_SCHEMA_INFERENCE: - break - - if not type_inferrer_by_field: - raise AirbyteTracedException( - message=f"Could not infer schema as there are no rows in {file.uri}. If having an empty CSV file is expected, ignore this. " - f"Else, please contact Airbyte.", - failure_type=FailureType.config_error, - ) - schema = {header.strip(): {"type": type_inferred.infer()} for header, type_inferred in type_inferrer_by_field.items()} - data_generator.close() - return schema - - def parse_records( - self, - config: FileBasedStreamConfig, - file: RemoteFile, - stream_reader: AbstractFileBasedStreamReader, - logger: logging.Logger, - discovered_schema: Optional[Mapping[str, SchemaType]], - ) -> Iterable[Dict[str, Any]]: - line_no = 0 - try: - config_format = _extract_format(config) - if discovered_schema: - property_types = {col: prop["type"] for col, prop in discovered_schema["properties"].items()} # type: ignore # discovered_schema["properties"] is known to be a mapping - deduped_property_types = CsvParser._pre_propcess_property_types(property_types) - else: - deduped_property_types = {} - cast_fn = CsvParser._get_cast_function(deduped_property_types, config_format, logger, config.schemaless) - data_generator = self._csv_reader.read_data(config, file, stream_reader, logger, self.file_read_mode) - for row in data_generator: - line_no += 1 - yield CsvParser._to_nullable( - cast_fn(row), deduped_property_types, config_format.null_values, config_format.strings_can_be_null - ) - except RecordParseError as parse_err: - raise RecordParseError(FileBasedSourceError.ERROR_PARSING_RECORD, filename=file.uri, lineno=line_no) from parse_err - finally: - data_generator.close() - - @property - def file_read_mode(self) -> FileReadMode: - return FileReadMode.READ - - @staticmethod - def _get_cast_function( - deduped_property_types: Mapping[str, str], config_format: CsvFormat, logger: logging.Logger, schemaless: bool - ) -> Callable[[Mapping[str, str]], Mapping[str, str]]: - # Only cast values if the schema is provided - if deduped_property_types and not schemaless: - return partial(CsvParser._cast_types, deduped_property_types=deduped_property_types, config_format=config_format, logger=logger) - else: - # If no schema is provided, yield the rows as they are - return _no_cast - - @staticmethod - def _to_nullable( - row: Mapping[str, str], deduped_property_types: Mapping[str, str], null_values: Set[str], strings_can_be_null: bool - ) -> Dict[str, Optional[str]]: - nullable = { - k: None if CsvParser._value_is_none(v, deduped_property_types.get(k), null_values, strings_can_be_null) else v - for k, v in row.items() - } - return nullable - - @staticmethod - def _value_is_none(value: Any, deduped_property_type: Optional[str], null_values: Set[str], strings_can_be_null: bool) -> bool: - return value in null_values and (strings_can_be_null or deduped_property_type != "string") - - @staticmethod - def _pre_propcess_property_types(property_types: Dict[str, Any]) -> Mapping[str, str]: - """ - Transform the property types to be non-nullable and remove duplicate types if any. - Sample input: - { - "col1": ["string", "null"], - "col2": ["string", "string", "null"], - "col3": "integer" - } - - Sample output: - { - "col1": "string", - "col2": "string", - "col3": "integer", - } - """ - output = {} - for prop, prop_type in property_types.items(): - if isinstance(prop_type, list): - prop_type_distinct = set(prop_type) - prop_type_distinct.remove("null") - if len(prop_type_distinct) != 1: - raise ValueError(f"Could not get non nullable type from {prop_type}") - output[prop] = next(iter(prop_type_distinct)) - else: - output[prop] = prop_type - return output - - @staticmethod - def _cast_types( - row: Dict[str, str], deduped_property_types: Mapping[str, str], config_format: CsvFormat, logger: logging.Logger - ) -> Dict[str, Any]: - """ - Casts the values in the input 'row' dictionary according to the types defined in the JSON schema. - - Array and object types are only handled if they can be deserialized as JSON. - - If any errors are encountered, the value will be emitted as a string. - """ - warnings = [] - result = {} - - for key, value in row.items(): - prop_type = deduped_property_types.get(key) - cast_value: Any = value - - if prop_type in TYPE_PYTHON_MAPPING and prop_type is not None: - _, python_type = TYPE_PYTHON_MAPPING[prop_type] - - if python_type is None: - if value == "": - cast_value = None - else: - warnings.append(_format_warning(key, value, prop_type)) - - elif python_type == bool: - try: - cast_value = _value_to_bool(value, config_format.true_values, config_format.false_values) - except ValueError: - warnings.append(_format_warning(key, value, prop_type)) - - elif python_type == dict: - try: - # we don't re-use _value_to_object here because we type the column as object as long as there is only one object - cast_value = orjson.loads(value) - except orjson.JSONDecodeError: - warnings.append(_format_warning(key, value, prop_type)) - - elif python_type == list: - try: - cast_value = _value_to_list(value) - except (ValueError, json.JSONDecodeError): - warnings.append(_format_warning(key, value, prop_type)) - - elif python_type: - try: - cast_value = _value_to_python_type(value, python_type) - except ValueError: - warnings.append(_format_warning(key, value, prop_type)) - - result[key] = cast_value - - if warnings: - logger.warning( - f"{FileBasedSourceError.ERROR_CASTING_VALUE.value}: {','.join([w for w in warnings])}", - ) - return result - - -class _TypeInferrer(ABC): - @abstractmethod - def add_value(self, value: Any) -> None: - pass - - @abstractmethod - def infer(self) -> str: - pass - - -class _DisabledTypeInferrer(_TypeInferrer): - def add_value(self, value: Any) -> None: - pass - - def infer(self) -> str: - return "string" - - -class _JsonTypeInferrer(_TypeInferrer): - _NULL_TYPE = "null" - _BOOLEAN_TYPE = "boolean" - _INTEGER_TYPE = "integer" - _NUMBER_TYPE = "number" - _STRING_TYPE = "string" - - def __init__(self, boolean_trues: Set[str], boolean_falses: Set[str], null_values: Set[str]) -> None: - self._boolean_trues = boolean_trues - self._boolean_falses = boolean_falses - self._null_values = null_values - self._values: Set[str] = set() - - def add_value(self, value: Any) -> None: - self._values.add(value) - - def infer(self) -> str: - types_by_value = {value: self._infer_type(value) for value in self._values} - types_excluding_null_values = [types for types in types_by_value.values() if self._NULL_TYPE not in types] - if not types_excluding_null_values: - # this is highly unusual but we will consider the column as a string - return self._STRING_TYPE - - types = set.intersection(*types_excluding_null_values) - if self._BOOLEAN_TYPE in types: - return self._BOOLEAN_TYPE - elif self._INTEGER_TYPE in types: - return self._INTEGER_TYPE - elif self._NUMBER_TYPE in types: - return self._NUMBER_TYPE - return self._STRING_TYPE - - def _infer_type(self, value: str) -> Set[str]: - inferred_types = set() - - if value in self._null_values: - inferred_types.add(self._NULL_TYPE) - if self._is_boolean(value): - inferred_types.add(self._BOOLEAN_TYPE) - if self._is_integer(value): - inferred_types.add(self._INTEGER_TYPE) - inferred_types.add(self._NUMBER_TYPE) - elif self._is_number(value): - inferred_types.add(self._NUMBER_TYPE) - - inferred_types.add(self._STRING_TYPE) - return inferred_types - - def _is_boolean(self, value: str) -> bool: - try: - _value_to_bool(value, self._boolean_trues, self._boolean_falses) - return True - except ValueError: - return False - - @staticmethod - def _is_integer(value: str) -> bool: - try: - _value_to_python_type(value, int) - return True - except ValueError: - return False - - @staticmethod - def _is_number(value: str) -> bool: - try: - _value_to_python_type(value, float) - return True - except ValueError: - return False - - -def _value_to_bool(value: str, true_values: Set[str], false_values: Set[str]) -> bool: - if value in true_values: - return True - if value in false_values: - return False - raise ValueError(f"Value {value} is not a valid boolean value") - - -def _value_to_list(value: str) -> List[Any]: - parsed_value = json.loads(value) - if isinstance(parsed_value, list): - return parsed_value - raise ValueError(f"Value {parsed_value} is not a valid list value") - - -def _value_to_python_type(value: str, python_type: type) -> Any: - return python_type(value) - - -def _format_warning(key: str, value: str, expected_type: Optional[Any]) -> str: - return f"{key}: value={value},expected_type={expected_type}" - - -def _no_cast(row: Mapping[str, str]) -> Mapping[str, str]: - return row - - -def _extract_format(config: FileBasedStreamConfig) -> CsvFormat: - config_format = config.format - if not isinstance(config_format, CsvFormat): - raise ValueError(f"Invalid format config: {config_format}") - return config_format diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/excel_parser.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/excel_parser.py deleted file mode 100644 index 93add4108dea..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/excel_parser.py +++ /dev/null @@ -1,172 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -import logging -from io import IOBase -from pathlib import Path -from typing import Any, Dict, Iterable, Mapping, Optional, Tuple, Union - -import pandas as pd -from airbyte_cdk.sources.file_based.config.file_based_stream_config import ExcelFormat, FileBasedStreamConfig -from airbyte_cdk.sources.file_based.exceptions import ConfigValidationError, FileBasedSourceError, RecordParseError -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.schema_helpers import SchemaType -from numpy import datetime64 -from numpy import dtype as dtype_ -from numpy import issubdtype -from orjson import orjson -from pydantic.v1 import BaseModel - - -class ExcelParser(FileTypeParser): - ENCODING = None - - def check_config(self, config: FileBasedStreamConfig) -> Tuple[bool, Optional[str]]: - """ - ExcelParser does not require config checks, implicit pydantic validation is enough. - """ - return True, None - - async def infer_schema( - self, - config: FileBasedStreamConfig, - file: RemoteFile, - stream_reader: AbstractFileBasedStreamReader, - logger: logging.Logger, - ) -> SchemaType: - """ - Infers the schema of the Excel file by examining its contents. - - Args: - config (FileBasedStreamConfig): Configuration for the file-based stream. - file (RemoteFile): The remote file to be read. - stream_reader (AbstractFileBasedStreamReader): Reader to read the file. - logger (logging.Logger): Logger for logging information and errors. - - Returns: - SchemaType: Inferred schema of the Excel file. - """ - - # Validate the format of the config - self.validate_format(config.format, logger) - - fields: Dict[str, str] = {} - - with stream_reader.open_file(file, self.file_read_mode, self.ENCODING, logger) as fp: - df = self.open_and_parse_file(fp) - for column, df_type in df.dtypes.items(): - # Choose the broadest data type if the column's data type differs in dataframes - prev_frame_column_type = fields.get(column) - fields[column] = self.dtype_to_json_type(prev_frame_column_type, df_type) - - schema = { - field: ({"type": "string", "format": "date-time"} if fields[field] == "date-time" else {"type": fields[field]}) - for field in fields - } - return schema - - def parse_records( - self, - config: FileBasedStreamConfig, - file: RemoteFile, - stream_reader: AbstractFileBasedStreamReader, - logger: logging.Logger, - discovered_schema: Optional[Mapping[str, SchemaType]] = None, - ) -> Iterable[Dict[str, Any]]: - """ - Parses records from an Excel file based on the provided configuration. - - Args: - config (FileBasedStreamConfig): Configuration for the file-based stream. - file (RemoteFile): The remote file to be read. - stream_reader (AbstractFileBasedStreamReader): Reader to read the file. - logger (logging.Logger): Logger for logging information and errors. - discovered_schema (Optional[Mapping[str, SchemaType]]): Discovered schema for validation. - - Yields: - Iterable[Dict[str, Any]]: Parsed records from the Excel file. - """ - - # Validate the format of the config - self.validate_format(config.format, logger) - - try: - # Open and parse the file using the stream reader - with stream_reader.open_file(file, self.file_read_mode, self.ENCODING, logger) as fp: - df = self.open_and_parse_file(fp) - # Yield records as dictionaries - # DataFrame.to_dict() method returns datetime values in pandas.Timestamp values, which are not serializable by orjson - # DataFrame.to_json() returns string with datetime values serialized to iso8601 with microseconds to align with pydantic behavior - # see PR description: https://github.com/airbytehq/airbyte/pull/44444/ - yield from orjson.loads(df.to_json(orient="records", date_format="iso", date_unit="us")) - - except Exception as exc: - # Raise a RecordParseError if any exception occurs during parsing - raise RecordParseError(FileBasedSourceError.ERROR_PARSING_RECORD, filename=file.uri) from exc - - @property - def file_read_mode(self) -> FileReadMode: - """ - Returns the file read mode for the Excel file. - - Returns: - FileReadMode: The file read mode (binary). - """ - return FileReadMode.READ_BINARY - - @staticmethod - def dtype_to_json_type(current_type: Optional[str], dtype: dtype_) -> str: - """ - Convert Pandas DataFrame types to Airbyte Types. - - Args: - current_type (Optional[str]): One of the previous types based on earlier dataframes. - dtype: Pandas DataFrame type. - - Returns: - str: Corresponding Airbyte Type. - """ - number_types = ("int64", "float64") - if current_type == "string": - # Previous column values were of the string type, no need to look further. - return current_type - if dtype == object: - return "string" - if dtype in number_types and (not current_type or current_type == "number"): - return "number" - if dtype == "bool" and (not current_type or current_type == "boolean"): - return "boolean" - if issubdtype(dtype, datetime64): - return "date-time" - return "string" - - @staticmethod - def validate_format(excel_format: BaseModel, logger: logging.Logger) -> None: - """ - Validates if the given format is of type ExcelFormat. - - Args: - excel_format (Any): The format to be validated. - - Raises: - ConfigValidationError: If the format is not ExcelFormat. - """ - if not isinstance(excel_format, ExcelFormat): - logger.info(f"Expected ExcelFormat, got {excel_format}") - raise ConfigValidationError(FileBasedSourceError.CONFIG_VALIDATION_ERROR) - - @staticmethod - def open_and_parse_file(fp: Union[IOBase, str, Path]) -> pd.DataFrame: - """ - Opens and parses the Excel file. - - Args: - fp: File pointer to the Excel file. - - Returns: - pd.DataFrame: Parsed data from the Excel file. - """ - return pd.ExcelFile(fp, engine="calamine").parse() diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/file_type_parser.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/file_type_parser.py deleted file mode 100644 index d334621ada66..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/file_type_parser.py +++ /dev/null @@ -1,83 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from abc import ABC, abstractmethod -from typing import Any, Dict, Iterable, Mapping, Optional, Tuple - -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.schema_helpers import SchemaType - -Record = Dict[str, Any] - - -class FileTypeParser(ABC): - """ - An abstract class containing methods that must be implemented for each - supported file type. - """ - - @property - def parser_max_n_files_for_schema_inference(self) -> Optional[int]: - """ - The discovery policy decides how many files are loaded for schema inference. This method can provide a parser-specific override. If it's defined, the smaller of the two values will be used. - """ - return None - - @property - def parser_max_n_files_for_parsability(self) -> Optional[int]: - """ - The availability policy decides how many files are loaded for checking whether parsing works correctly. This method can provide a parser-specific override. If it's defined, the smaller of the two values will be used. - """ - return None - - def get_parser_defined_primary_key(self, config: FileBasedStreamConfig) -> Optional[str]: - """ - The parser can define a primary key. If no user-defined primary key is provided, this will be used. - """ - return None - - @abstractmethod - def check_config(self, config: FileBasedStreamConfig) -> Tuple[bool, Optional[str]]: - """ - Check whether the config is valid for this file type. If it is, return True and None. If it's not, return False and an error message explaining why it's invalid. - """ - return True, None - - @abstractmethod - async def infer_schema( - self, - config: FileBasedStreamConfig, - file: RemoteFile, - stream_reader: AbstractFileBasedStreamReader, - logger: logging.Logger, - ) -> SchemaType: - """ - Infer the JSON Schema for this file. - """ - ... - - @abstractmethod - def parse_records( - self, - config: FileBasedStreamConfig, - file: RemoteFile, - stream_reader: AbstractFileBasedStreamReader, - logger: logging.Logger, - discovered_schema: Optional[Mapping[str, SchemaType]], - ) -> Iterable[Record]: - """ - Parse and emit each record. - """ - ... - - @property - @abstractmethod - def file_read_mode(self) -> FileReadMode: - """ - The mode in which the file should be opened for reading. - """ - ... diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/jsonl_parser.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/jsonl_parser.py deleted file mode 100644 index f0603f4ecd2f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/jsonl_parser.py +++ /dev/null @@ -1,130 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import logging -from typing import Any, Dict, Iterable, Mapping, Optional, Tuple, Union - -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig -from airbyte_cdk.sources.file_based.exceptions import FileBasedSourceError, RecordParseError -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.schema_helpers import PYTHON_TYPE_MAPPING, SchemaType, merge_schemas -from orjson import orjson - - -class JsonlParser(FileTypeParser): - - MAX_BYTES_PER_FILE_FOR_SCHEMA_INFERENCE = 1_000_000 - ENCODING = "utf8" - - def check_config(self, config: FileBasedStreamConfig) -> Tuple[bool, Optional[str]]: - """ - JsonlParser does not require config checks, implicit pydantic validation is enough. - """ - return True, None - - async def infer_schema( - self, - config: FileBasedStreamConfig, - file: RemoteFile, - stream_reader: AbstractFileBasedStreamReader, - logger: logging.Logger, - ) -> SchemaType: - """ - Infers the schema for the file by inferring the schema for each line, and merging - it with the previously-inferred schema. - """ - inferred_schema: Mapping[str, Any] = {} - - for entry in self._parse_jsonl_entries(file, stream_reader, logger, read_limit=True): - line_schema = self._infer_schema_for_record(entry) - inferred_schema = merge_schemas(inferred_schema, line_schema) - - return inferred_schema - - def parse_records( - self, - config: FileBasedStreamConfig, - file: RemoteFile, - stream_reader: AbstractFileBasedStreamReader, - logger: logging.Logger, - discovered_schema: Optional[Mapping[str, SchemaType]], - ) -> Iterable[Dict[str, Any]]: - """ - This code supports parsing json objects over multiple lines even though this does not align with the JSONL format. This is for - backward compatibility reasons i.e. the previous source-s3 parser did support this. The drawback is: - * performance as the way we support json over multiple lines is very brute forced - * given that we don't have `newlines_in_values` config to scope the possible inputs, we might parse the whole file before knowing if - the input is improperly formatted or if the json is over multiple lines - - The goal is to run the V4 of source-s3 in production, track the warning log emitted when there are multiline json objects and - deprecate this feature if it's not a valid use case. - """ - yield from self._parse_jsonl_entries(file, stream_reader, logger) - - @classmethod - def _infer_schema_for_record(cls, record: Dict[str, Any]) -> Dict[str, Any]: - record_schema = {} - for key, value in record.items(): - if value is None: - record_schema[key] = {"type": "null"} - else: - record_schema[key] = {"type": PYTHON_TYPE_MAPPING[type(value)]} - - return record_schema - - @property - def file_read_mode(self) -> FileReadMode: - return FileReadMode.READ - - def _parse_jsonl_entries( - self, - file: RemoteFile, - stream_reader: AbstractFileBasedStreamReader, - logger: logging.Logger, - read_limit: bool = False, - ) -> Iterable[Dict[str, Any]]: - with stream_reader.open_file(file, self.file_read_mode, self.ENCODING, logger) as fp: - read_bytes = 0 - - had_json_parsing_error = False - has_warned_for_multiline_json_object = False - yielded_at_least_once = False - - accumulator = None - for line in fp: - if not accumulator: - accumulator = self._instantiate_accumulator(line) - read_bytes += len(line) - accumulator += line # type: ignore [operator] # In reality, it's either bytes or string and we add the same type - try: - record = orjson.loads(accumulator) - if had_json_parsing_error and not has_warned_for_multiline_json_object: - logger.warning(f"File at {file.uri} is using multiline JSON. Performance could be greatly reduced") - has_warned_for_multiline_json_object = True - - yield record - yielded_at_least_once = True - accumulator = self._instantiate_accumulator(line) - except orjson.JSONDecodeError: - had_json_parsing_error = True - - if read_limit and yielded_at_least_once and read_bytes >= self.MAX_BYTES_PER_FILE_FOR_SCHEMA_INFERENCE: - logger.warning( - f"Exceeded the maximum number of bytes per file for schema inference ({self.MAX_BYTES_PER_FILE_FOR_SCHEMA_INFERENCE}). " - f"Inferring schema from an incomplete set of records." - ) - break - - if had_json_parsing_error and not yielded_at_least_once: - raise RecordParseError(FileBasedSourceError.ERROR_PARSING_RECORD, filename=file.uri, lineno=line) - - @staticmethod - def _instantiate_accumulator(line: Union[bytes, str]) -> Union[bytes, str]: - if isinstance(line, bytes): - return bytes("", json.detect_encoding(line)) - elif isinstance(line, str): - return "" diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/parquet_parser.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/parquet_parser.py deleted file mode 100644 index 7e3d3013c4e0..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/parquet_parser.py +++ /dev/null @@ -1,233 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import logging -import os -from typing import Any, Dict, Iterable, List, Mapping, Optional, Tuple, Union -from urllib.parse import unquote - -import pyarrow as pa -import pyarrow.parquet as pq -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig, ParquetFormat -from airbyte_cdk.sources.file_based.exceptions import ConfigValidationError, FileBasedSourceError, RecordParseError -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.schema_helpers import SchemaType -from pyarrow import DictionaryArray, Scalar - - -class ParquetParser(FileTypeParser): - - ENCODING = None - - def check_config(self, config: FileBasedStreamConfig) -> Tuple[bool, Optional[str]]: - """ - ParquetParser does not require config checks, implicit pydantic validation is enough. - """ - return True, None - - async def infer_schema( - self, - config: FileBasedStreamConfig, - file: RemoteFile, - stream_reader: AbstractFileBasedStreamReader, - logger: logging.Logger, - ) -> SchemaType: - parquet_format = config.format - if not isinstance(parquet_format, ParquetFormat): - raise ValueError(f"Expected ParquetFormat, got {parquet_format}") - - with stream_reader.open_file(file, self.file_read_mode, self.ENCODING, logger) as fp: - parquet_file = pq.ParquetFile(fp) - parquet_schema = parquet_file.schema_arrow - - # Inferred non-partition schema - schema = {field.name: ParquetParser.parquet_type_to_schema_type(field.type, parquet_format) for field in parquet_schema} - # Inferred partition schema - partition_columns = {partition.split("=")[0]: {"type": "string"} for partition in self._extract_partitions(file.uri)} - - schema.update(partition_columns) - return schema - - def parse_records( - self, - config: FileBasedStreamConfig, - file: RemoteFile, - stream_reader: AbstractFileBasedStreamReader, - logger: logging.Logger, - discovered_schema: Optional[Mapping[str, SchemaType]], - ) -> Iterable[Dict[str, Any]]: - parquet_format = config.format - if not isinstance(parquet_format, ParquetFormat): - logger.info(f"Expected ParquetFormat, got {parquet_format}") - raise ConfigValidationError(FileBasedSourceError.CONFIG_VALIDATION_ERROR) - - line_no = 0 - try: - with stream_reader.open_file(file, self.file_read_mode, self.ENCODING, logger) as fp: - reader = pq.ParquetFile(fp) - partition_columns = {x.split("=")[0]: x.split("=")[1] for x in self._extract_partitions(file.uri)} - for row_group in range(reader.num_row_groups): - batch = reader.read_row_group(row_group) - for row in range(batch.num_rows): - line_no += 1 - yield { - **{ - column: ParquetParser._to_output_value(batch.column(column)[row], parquet_format) - for column in batch.column_names - }, - **partition_columns, - } - except Exception as exc: - raise RecordParseError( - FileBasedSourceError.ERROR_PARSING_RECORD, filename=file.uri, lineno=f"{row_group=}, {line_no=}" - ) from exc - - @staticmethod - def _extract_partitions(filepath: str) -> List[str]: - return [unquote(partition) for partition in filepath.split(os.sep) if "=" in partition] - - @property - def file_read_mode(self) -> FileReadMode: - return FileReadMode.READ_BINARY - - @staticmethod - def _to_output_value(parquet_value: Union[Scalar, DictionaryArray], parquet_format: ParquetFormat) -> Any: - """ - Convert an entry in a pyarrow table to a value that can be output by the source. - """ - if isinstance(parquet_value, DictionaryArray): - return ParquetParser._dictionary_array_to_python_value(parquet_value) - else: - return ParquetParser._scalar_to_python_value(parquet_value, parquet_format) - - @staticmethod - def _scalar_to_python_value(parquet_value: Scalar, parquet_format: ParquetFormat) -> Any: - """ - Convert a pyarrow scalar to a value that can be output by the source. - """ - if parquet_value.as_py() is None: - return None - - # Convert date and datetime objects to isoformat strings - if pa.types.is_time(parquet_value.type) or pa.types.is_timestamp(parquet_value.type) or pa.types.is_date(parquet_value.type): - return parquet_value.as_py().isoformat() - - # Convert month_day_nano_interval to array - if parquet_value.type == pa.month_day_nano_interval(): - return json.loads(json.dumps(parquet_value.as_py())) - - # Decode binary strings to utf-8 - if ParquetParser._is_binary(parquet_value.type): - return parquet_value.as_py().decode("utf-8") - - if pa.types.is_decimal(parquet_value.type): - if parquet_format.decimal_as_float: - return float(parquet_value.as_py()) - else: - return str(parquet_value.as_py()) - - if pa.types.is_map(parquet_value.type): - return {k: v for k, v in parquet_value.as_py()} - - if pa.types.is_null(parquet_value.type): - return None - - # Convert duration to seconds, then convert to the appropriate unit - if pa.types.is_duration(parquet_value.type): - duration = parquet_value.as_py() - duration_seconds = duration.total_seconds() - if parquet_value.type.unit == "s": - return duration_seconds - elif parquet_value.type.unit == "ms": - return duration_seconds * 1000 - elif parquet_value.type.unit == "us": - return duration_seconds * 1_000_000 - elif parquet_value.type.unit == "ns": - return duration_seconds * 1_000_000_000 + duration.nanoseconds - else: - raise ValueError(f"Unknown duration unit: {parquet_value.type.unit}") - else: - return parquet_value.as_py() - - @staticmethod - def _dictionary_array_to_python_value(parquet_value: DictionaryArray) -> Dict[str, Any]: - """ - Convert a pyarrow dictionary array to a value that can be output by the source. - - Dictionaries are stored as two columns: indices and values - The indices column is an array of integers that maps to the values column - """ - - return { - "indices": parquet_value.indices.tolist(), - "values": parquet_value.dictionary.tolist(), - } - - @staticmethod - def parquet_type_to_schema_type(parquet_type: pa.DataType, parquet_format: ParquetFormat) -> Mapping[str, str]: - """ - Convert a pyarrow data type to an Airbyte schema type. - Parquet data types are defined at https://arrow.apache.org/docs/python/api/datatypes.html - """ - - if pa.types.is_timestamp(parquet_type): - return {"type": "string", "format": "date-time"} - elif pa.types.is_date(parquet_type): - return {"type": "string", "format": "date"} - elif ParquetParser._is_string(parquet_type, parquet_format): - return {"type": "string"} - elif pa.types.is_boolean(parquet_type): - return {"type": "boolean"} - elif ParquetParser._is_integer(parquet_type): - return {"type": "integer"} - elif ParquetParser._is_float(parquet_type, parquet_format): - return {"type": "number"} - elif ParquetParser._is_object(parquet_type): - return {"type": "object"} - elif ParquetParser._is_list(parquet_type): - return {"type": "array"} - elif pa.types.is_null(parquet_type): - return {"type": "null"} - else: - raise ValueError(f"Unsupported parquet type: {parquet_type}") - - @staticmethod - def _is_binary(parquet_type: pa.DataType) -> bool: - return bool( - pa.types.is_binary(parquet_type) or pa.types.is_large_binary(parquet_type) or pa.types.is_fixed_size_binary(parquet_type) - ) - - @staticmethod - def _is_integer(parquet_type: pa.DataType) -> bool: - return bool(pa.types.is_integer(parquet_type) or pa.types.is_duration(parquet_type)) - - @staticmethod - def _is_float(parquet_type: pa.DataType, parquet_format: ParquetFormat) -> bool: - if pa.types.is_decimal(parquet_type): - return parquet_format.decimal_as_float - else: - return bool(pa.types.is_floating(parquet_type)) - - @staticmethod - def _is_string(parquet_type: pa.DataType, parquet_format: ParquetFormat) -> bool: - if pa.types.is_decimal(parquet_type): - return not parquet_format.decimal_as_float - else: - return bool( - pa.types.is_time(parquet_type) - or pa.types.is_string(parquet_type) - or pa.types.is_large_string(parquet_type) - or ParquetParser._is_binary(parquet_type) # Best we can do is return as a string since we do not support binary - ) - - @staticmethod - def _is_object(parquet_type: pa.DataType) -> bool: - return bool(pa.types.is_dictionary(parquet_type) or pa.types.is_struct(parquet_type) or pa.types.is_map(parquet_type)) - - @staticmethod - def _is_list(parquet_type: pa.DataType) -> bool: - return bool(pa.types.is_list(parquet_type) or pa.types.is_large_list(parquet_type) or parquet_type == pa.month_day_nano_interval()) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/unstructured_parser.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/unstructured_parser.py deleted file mode 100644 index 659fbd2c4734..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/unstructured_parser.py +++ /dev/null @@ -1,357 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import logging -import traceback -from datetime import datetime -from io import BytesIO, IOBase -from typing import Any, Dict, Iterable, List, Mapping, Optional, Tuple, Union - -import backoff -import dpath -import requests -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig -from airbyte_cdk.sources.file_based.config.unstructured_format import ( - APIParameterConfigModel, - APIProcessingConfigModel, - LocalProcessingConfigModel, - UnstructuredFormat, -) -from airbyte_cdk.sources.file_based.exceptions import FileBasedSourceError, RecordParseError -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.schema_helpers import SchemaType -from airbyte_cdk.utils import is_cloud_environment -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from unstructured.file_utils.filetype import FILETYPE_TO_MIMETYPE, STR_TO_FILETYPE, FileType, detect_filetype - -unstructured_partition_pdf = None -unstructured_partition_docx = None -unstructured_partition_pptx = None - - -def optional_decode(contents: Union[str, bytes]) -> str: - if isinstance(contents, bytes): - return contents.decode("utf-8") - return contents - - -def _import_unstructured() -> None: - """Dynamically imported as needed, due to slow import speed.""" - global unstructured_partition_pdf - global unstructured_partition_docx - global unstructured_partition_pptx - from unstructured.partition.docx import partition_docx - from unstructured.partition.pdf import partition_pdf - from unstructured.partition.pptx import partition_pptx - - # separate global variables to properly propagate typing - unstructured_partition_pdf = partition_pdf - unstructured_partition_docx = partition_docx - unstructured_partition_pptx = partition_pptx - - -def user_error(e: Exception) -> bool: - """ - Return True if this exception is caused by user error, False otherwise. - """ - if not isinstance(e, RecordParseError): - return False - if not isinstance(e, requests.exceptions.RequestException): - return False - return bool(e.response and 400 <= e.response.status_code < 500) - - -CLOUD_DEPLOYMENT_MODE = "cloud" - - -class UnstructuredParser(FileTypeParser): - @property - def parser_max_n_files_for_schema_inference(self) -> Optional[int]: - """ - Just check one file as the schema is static - """ - return 1 - - @property - def parser_max_n_files_for_parsability(self) -> Optional[int]: - """ - Do not check any files for parsability because it might be an expensive operation and doesn't give much confidence whether the sync will succeed. - """ - return 0 - - def get_parser_defined_primary_key(self, config: FileBasedStreamConfig) -> Optional[str]: - """ - Return the document_key field as the primary key. - - his will pre-select the document key column as the primary key when setting up a connection, making it easier for the user to configure normalization in the destination. - """ - return "document_key" - - async def infer_schema( - self, - config: FileBasedStreamConfig, - file: RemoteFile, - stream_reader: AbstractFileBasedStreamReader, - logger: logging.Logger, - ) -> SchemaType: - format = _extract_format(config) - with stream_reader.open_file(file, self.file_read_mode, None, logger) as file_handle: - filetype = self._get_filetype(file_handle, file) - - if filetype not in self._supported_file_types() and not format.skip_unprocessable_files: - raise self._create_parse_error(file, self._get_file_type_error_message(filetype)) - - return { - "content": { - "type": "string", - "description": "Content of the file as markdown. Might be null if the file could not be parsed", - }, - "document_key": {"type": "string", "description": "Unique identifier of the document, e.g. the file path"}, - "_ab_source_file_parse_error": { - "type": "string", - "description": "Error message if the file could not be parsed even though the file is supported", - }, - } - - def parse_records( - self, - config: FileBasedStreamConfig, - file: RemoteFile, - stream_reader: AbstractFileBasedStreamReader, - logger: logging.Logger, - discovered_schema: Optional[Mapping[str, SchemaType]], - ) -> Iterable[Dict[str, Any]]: - format = _extract_format(config) - with stream_reader.open_file(file, self.file_read_mode, None, logger) as file_handle: - try: - markdown = self._read_file(file_handle, file, format, logger) - yield { - "content": markdown, - "document_key": file.uri, - "_ab_source_file_parse_error": None, - } - except RecordParseError as e: - # RecordParseError is raised when the file can't be parsed because of a problem with the file content (either the file is not supported or the file is corrupted) - # if the skip_unprocessable_files flag is set, we log a warning and pass the error as part of the document - # otherwise, we raise the error to fail the sync - if format.skip_unprocessable_files: - exception_str = str(e) - logger.warn(f"File {file.uri} caused an error during parsing: {exception_str}.") - yield { - "content": None, - "document_key": file.uri, - "_ab_source_file_parse_error": exception_str, - } - logger.warn(f"File {file.uri} cannot be parsed. Skipping it.") - else: - raise e - - def _read_file(self, file_handle: IOBase, remote_file: RemoteFile, format: UnstructuredFormat, logger: logging.Logger) -> str: - _import_unstructured() - if (not unstructured_partition_pdf) or (not unstructured_partition_docx) or (not unstructured_partition_pptx): - # check whether unstructured library is actually available for better error message and to ensure proper typing (can't be None after this point) - raise Exception("unstructured library is not available") - - filetype = self._get_filetype(file_handle, remote_file) - - if filetype == FileType.MD or filetype == FileType.TXT: - file_content: bytes = file_handle.read() - decoded_content: str = optional_decode(file_content) - return decoded_content - if filetype not in self._supported_file_types(): - raise self._create_parse_error(remote_file, self._get_file_type_error_message(filetype)) - if format.processing.mode == "local": - return self._read_file_locally(file_handle, filetype, format.strategy, remote_file) - elif format.processing.mode == "api": - try: - result: str = self._read_file_remotely_with_retries(file_handle, format.processing, filetype, format.strategy, remote_file) - except Exception as e: - # If a parser error happens during remotely processing the file, this means the file is corrupted. This case is handled by the parse_records method, so just rethrow. - # - # For other exceptions, re-throw as config error so the sync is stopped as problems with the external API need to be resolved by the user and are not considered part of the SLA. - # Once this parser leaves experimental stage, we should consider making this a system error instead for issues that might be transient. - if isinstance(e, RecordParseError): - raise e - raise AirbyteTracedException.from_exception(e, failure_type=FailureType.config_error) - - return result - - def _params_to_dict(self, params: Optional[List[APIParameterConfigModel]], strategy: str) -> Dict[str, Union[str, List[str]]]: - result_dict: Dict[str, Union[str, List[str]]] = {"strategy": strategy} - if params is None: - return result_dict - for item in params: - key = item.name - value = item.value - if key in result_dict: - existing_value = result_dict[key] - # If the key already exists, append the new value to its list - if isinstance(existing_value, list): - existing_value.append(value) - else: - result_dict[key] = [existing_value, value] - else: - # If the key doesn't exist, add it to the dictionary - result_dict[key] = value - - return result_dict - - def check_config(self, config: FileBasedStreamConfig) -> Tuple[bool, Optional[str]]: - """ - Perform a connection check for the parser config: - - Verify that encryption is enabled if the API is hosted on a cloud instance. - - Verify that the API can extract text from a file. - - For local processing, we don't need to perform any additional checks, implicit pydantic validation is enough. - """ - format_config = _extract_format(config) - if isinstance(format_config.processing, LocalProcessingConfigModel): - if format_config.strategy == "hi_res": - return False, "Hi-res strategy is not supported for local processing" - return True, None - - if is_cloud_environment() and not format_config.processing.api_url.startswith("https://"): - return False, "Base URL must start with https://" - - try: - self._read_file_remotely( - BytesIO(b"# Airbyte source connection test"), - format_config.processing, - FileType.MD, - "auto", - RemoteFile(uri="test", last_modified=datetime.now()), - ) - except Exception: - return False, "".join(traceback.format_exc()) - - return True, None - - @backoff.on_exception(backoff.expo, requests.exceptions.RequestException, max_tries=5, giveup=user_error) - def _read_file_remotely_with_retries( - self, file_handle: IOBase, format: APIProcessingConfigModel, filetype: FileType, strategy: str, remote_file: RemoteFile - ) -> str: - """ - Read a file remotely, retrying up to 5 times if the error is not caused by user error. This is useful for transient network errors or the API server being overloaded temporarily. - """ - return self._read_file_remotely(file_handle, format, filetype, strategy, remote_file) - - def _read_file_remotely( - self, file_handle: IOBase, format: APIProcessingConfigModel, filetype: FileType, strategy: str, remote_file: RemoteFile - ) -> str: - headers = {"accept": "application/json", "unstructured-api-key": format.api_key} - - data = self._params_to_dict(format.parameters, strategy) - - file_data = {"files": ("filename", file_handle, FILETYPE_TO_MIMETYPE[filetype])} - - response = requests.post(f"{format.api_url}/general/v0/general", headers=headers, data=data, files=file_data) - - if response.status_code == 422: - # 422 means the file couldn't be processed, but the API is working. Treat this as a parsing error (passing an error record to the destination). - raise self._create_parse_error(remote_file, response.json()) - else: - # Other error statuses are raised as requests exceptions (retry everything except user errors) - response.raise_for_status() - - json_response = response.json() - - return self._render_markdown(json_response) - - def _read_file_locally(self, file_handle: IOBase, filetype: FileType, strategy: str, remote_file: RemoteFile) -> str: - _import_unstructured() - if (not unstructured_partition_pdf) or (not unstructured_partition_docx) or (not unstructured_partition_pptx): - # check whether unstructured library is actually available for better error message and to ensure proper typing (can't be None after this point) - raise Exception("unstructured library is not available") - - file: Any = file_handle - - # before the parsing logic is entered, the file is read completely to make sure it is in local memory - file_handle.seek(0) - file_handle.read() - file_handle.seek(0) - - try: - if filetype == FileType.PDF: - # for PDF, read the file into a BytesIO object because some code paths in pdf parsing are doing an instance check on the file object and don't work with file-like objects - file_handle.seek(0) - with BytesIO(file_handle.read()) as file: - file_handle.seek(0) - elements = unstructured_partition_pdf(file=file, strategy=strategy) - elif filetype == FileType.DOCX: - elements = unstructured_partition_docx(file=file) - elif filetype == FileType.PPTX: - elements = unstructured_partition_pptx(file=file) - except Exception as e: - raise self._create_parse_error(remote_file, str(e)) - - return self._render_markdown([element.to_dict() for element in elements]) - - def _create_parse_error(self, remote_file: RemoteFile, message: str) -> RecordParseError: - return RecordParseError(FileBasedSourceError.ERROR_PARSING_RECORD, filename=remote_file.uri, message=message) - - def _get_filetype(self, file: IOBase, remote_file: RemoteFile) -> Optional[FileType]: - """ - Detect the file type based on the file name and the file content. - - There are three strategies to determine the file type: - 1. Use the mime type if available (only some sources support it) - 2. Use the file name if available - 3. Use the file content - """ - if remote_file.mime_type and remote_file.mime_type in STR_TO_FILETYPE: - return STR_TO_FILETYPE[remote_file.mime_type] - - # set name to none, otherwise unstructured will try to get the modified date from the local file system - if hasattr(file, "name"): - file.name = None - - # detect_filetype is either using the file name or file content - # if possible, try to leverage the file name to detect the file type - # if the file name is not available, use the file content - file_type = detect_filetype( - filename=remote_file.uri, - ) - if file_type is not None and not file_type == FileType.UNK: - return file_type - - type_based_on_content = detect_filetype(file=file) - - # detect_filetype is reading to read the file content - file.seek(0) - - return type_based_on_content - - def _supported_file_types(self) -> List[Any]: - return [FileType.MD, FileType.PDF, FileType.DOCX, FileType.PPTX, FileType.TXT] - - def _get_file_type_error_message(self, file_type: FileType) -> str: - supported_file_types = ", ".join([str(type) for type in self._supported_file_types()]) - return f"File type {file_type} is not supported. Supported file types are {supported_file_types}" - - def _render_markdown(self, elements: List[Any]) -> str: - return "\n\n".join((self._convert_to_markdown(el) for el in elements)) - - def _convert_to_markdown(self, el: Dict[str, Any]) -> str: - if dpath.get(el, "type") == "Title": - heading_str = "#" * (dpath.get(el, "metadata/category_depth", default=1) or 1) - return f"{heading_str} {dpath.get(el, 'text')}" - elif dpath.get(el, "type") == "ListItem": - return f"- {dpath.get(el, 'text')}" - elif dpath.get(el, "type") == "Formula": - return f"```\n{dpath.get(el, 'text')}\n```" - else: - return str(dpath.get(el, "text", default="")) - - @property - def file_read_mode(self) -> FileReadMode: - return FileReadMode.READ_BINARY - - -def _extract_format(config: FileBasedStreamConfig) -> UnstructuredFormat: - config_format = config.format - if not isinstance(config_format, UnstructuredFormat): - raise ValueError(f"Invalid format config: {config_format}") - return config_format diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/remote_file.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/remote_file.py deleted file mode 100644 index 0197a35fdbb1..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/remote_file.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from datetime import datetime -from typing import Optional - -from pydantic.v1 import BaseModel - - -class RemoteFile(BaseModel): - """ - A file in a file-based stream. - """ - - uri: str - last_modified: datetime - mime_type: Optional[str] = None diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_helpers.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_helpers.py deleted file mode 100644 index c7c7bfa32288..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_helpers.py +++ /dev/null @@ -1,249 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -from copy import deepcopy -from enum import Enum -from functools import total_ordering -from typing import Any, Dict, List, Literal, Mapping, Optional, Tuple, Type, Union - -from airbyte_cdk.sources.file_based.exceptions import ConfigValidationError, FileBasedSourceError, SchemaInferenceError - -JsonSchemaSupportedType = Union[List[str], Literal["string"], str] -SchemaType = Mapping[str, Mapping[str, JsonSchemaSupportedType]] - -schemaless_schema = {"type": "object", "properties": {"data": {"type": "object"}}} - - -@total_ordering -class ComparableType(Enum): - NULL = 0 - BOOLEAN = 1 - INTEGER = 2 - NUMBER = 3 - STRING = 4 - OBJECT = 5 - - def __lt__(self, other: Any) -> bool: - if self.__class__ is other.__class__: - return self.value < other.value # type: ignore - else: - return NotImplemented - - -TYPE_PYTHON_MAPPING: Mapping[str, Tuple[str, Optional[Type[Any]]]] = { - "null": ("null", None), - "array": ("array", list), - "boolean": ("boolean", bool), - "float": ("number", float), - "integer": ("integer", int), - "number": ("number", float), - "object": ("object", dict), - "string": ("string", str), -} -PYTHON_TYPE_MAPPING = {t: k for k, (_, t) in TYPE_PYTHON_MAPPING.items()} - - -def get_comparable_type(value: Any) -> Optional[ComparableType]: - if value == "null": - return ComparableType.NULL - if value == "boolean": - return ComparableType.BOOLEAN - if value == "integer": - return ComparableType.INTEGER - if value == "number": - return ComparableType.NUMBER - if value == "string": - return ComparableType.STRING - if value == "object": - return ComparableType.OBJECT - else: - return None - - -def get_inferred_type(value: Any) -> Optional[ComparableType]: - if value is None: - return ComparableType.NULL - if isinstance(value, bool): - return ComparableType.BOOLEAN - if isinstance(value, int): - return ComparableType.INTEGER - if isinstance(value, float): - return ComparableType.NUMBER - if isinstance(value, str): - return ComparableType.STRING - if isinstance(value, dict): - return ComparableType.OBJECT - else: - return None - - -def merge_schemas(schema1: SchemaType, schema2: SchemaType) -> SchemaType: - """ - Returns a new dictionary that contains schema1 and schema2. - - Schemas are merged as follows - - If a key is in one schema but not the other, add it to the base schema with its existing type. - - If a key is in both schemas but with different types, use the wider type. - - If the type is a list in one schema but a different type of element in the other schema, raise an exception. - - If the type is an object in both schemas but the objects are different raise an exception. - - If the type is an object in one schema but not in the other schema, raise an exception. - - In other words, we support merging - - any atomic type with any other atomic type (choose the wider of the two) - - list with list (union) - and nothing else. - """ - for k, t in list(schema1.items()) + list(schema2.items()): - if not isinstance(t, dict) or "type" not in t or not _is_valid_type(t["type"]): - raise SchemaInferenceError(FileBasedSourceError.UNRECOGNIZED_TYPE, key=k, type=t) - - merged_schema: Dict[str, Any] = deepcopy(schema1) # type: ignore # as of 2023-08-08, deepcopy can copy Mapping - for k2, t2 in schema2.items(): - t1 = merged_schema.get(k2) - if t1 is None: - merged_schema[k2] = t2 - elif t1 == t2: - continue - else: - merged_schema[k2] = _choose_wider_type(k2, t1, t2) - - return merged_schema - - -def _is_valid_type(t: JsonSchemaSupportedType) -> bool: - return t == "array" or get_comparable_type(t) is not None - - -def _choose_wider_type(key: str, t1: Mapping[str, Any], t2: Mapping[str, Any]) -> Mapping[str, Any]: - t1_type = t1["type"] - t2_type = t2["type"] - - if (t1_type == "array" or t2_type == "array") and t1 != t2: - raise SchemaInferenceError( - FileBasedSourceError.SCHEMA_INFERENCE_ERROR, - details="Cannot merge schema for unequal array types.", - key=key, - detected_types=f"{t1},{t2}", - ) - # Schemas can still be merged if a key contains a null value in either t1 or t2, but it is still an object - elif (t1_type == "object" or t2_type == "object") and t1_type != "null" and t2_type != "null" and t1 != t2: - raise SchemaInferenceError( - FileBasedSourceError.SCHEMA_INFERENCE_ERROR, - details="Cannot merge schema for unequal object types.", - key=key, - detected_types=f"{t1},{t2}", - ) - else: - comparable_t1 = get_comparable_type(TYPE_PYTHON_MAPPING[t1_type][0]) # accessing the type_mapping value - comparable_t2 = get_comparable_type(TYPE_PYTHON_MAPPING[t2_type][0]) # accessing the type_mapping value - if not comparable_t1 and comparable_t2: - raise SchemaInferenceError(FileBasedSourceError.UNRECOGNIZED_TYPE, key=key, detected_types=f"{t1},{t2}") - return max( - [t1, t2], key=lambda x: ComparableType(get_comparable_type(TYPE_PYTHON_MAPPING[x["type"]][0])) - ) # accessing the type_mapping value - - -def is_equal_or_narrower_type(value: Any, expected_type: str) -> bool: - if isinstance(value, list): - # We do not compare lists directly; the individual items are compared. - # If we hit this condition, it means that the expected type is not - # compatible with the inferred type. - return False - - inferred_type = ComparableType(get_inferred_type(value)) - - if inferred_type is None: - return False - - return ComparableType(inferred_type) <= ComparableType(get_comparable_type(expected_type)) - - -def conforms_to_schema(record: Mapping[str, Any], schema: Mapping[str, Any]) -> bool: - """ - Return true iff the record conforms to the supplied schema. - - The record conforms to the supplied schema iff: - - All columns in the record are in the schema. - - For every column in the record, that column's type is equal to or narrower than the same column's - type in the schema. - """ - schema_columns = set(schema.get("properties", {}).keys()) - record_columns = set(record.keys()) - - if not record_columns.issubset(schema_columns): - return False - - for column, definition in schema.get("properties", {}).items(): - expected_type = definition.get("type") - value = record.get(column) - - if value is not None: - if isinstance(expected_type, list): - return any(is_equal_or_narrower_type(value, e) for e in expected_type) - elif expected_type == "object": - return isinstance(value, dict) - elif expected_type == "array": - if not isinstance(value, list): - return False - array_type = definition.get("items", {}).get("type") - if not all(is_equal_or_narrower_type(v, array_type) for v in value): - return False - elif not is_equal_or_narrower_type(value, expected_type): - return False - - return True - - -def _parse_json_input(input_schema: Union[str, Mapping[str, str]]) -> Optional[Mapping[str, str]]: - try: - if isinstance(input_schema, str): - schema: Mapping[str, str] = json.loads(input_schema) - else: - schema = input_schema - if not all(isinstance(s, str) for s in schema.values()): - raise ConfigValidationError( - FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA, details="Invalid input schema; nested schemas are not supported." - ) - - except json.decoder.JSONDecodeError: - return None - - return schema - - -def type_mapping_to_jsonschema(input_schema: Optional[Union[str, Mapping[str, str]]]) -> Optional[Mapping[str, Any]]: - """ - Return the user input schema (type mapping), transformed to JSON Schema format. - - Verify that the input schema: - - is a key:value map - - all values in the map correspond to a JsonSchema datatype - """ - if not input_schema: - return None - - result_schema = {} - - json_mapping = _parse_json_input(input_schema) or {} - - for col_name, type_name in json_mapping.items(): - col_name, type_name = col_name.strip(), type_name.strip() - if not (col_name and type_name): - raise ConfigValidationError( - FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA, - details=f"Invalid input schema; expected mapping in the format column_name: type, got {input_schema}.", - ) - - _json_schema_type = TYPE_PYTHON_MAPPING.get(type_name.casefold()) - - if not _json_schema_type: - raise ConfigValidationError( - FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA, details=f"Invalid type '{type_name}' for property '{col_name}'." - ) - - json_schema_type = _json_schema_type[0] - result_schema[col_name] = {"type": json_schema_type} - - return {"type": "object", "properties": result_schema} diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/__init__.py deleted file mode 100644 index d2cc0e63b214..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -from airbyte_cdk.sources.file_based.schema_validation_policies.abstract_schema_validation_policy import AbstractSchemaValidationPolicy -from airbyte_cdk.sources.file_based.schema_validation_policies.default_schema_validation_policies import ( - DEFAULT_SCHEMA_VALIDATION_POLICIES, - EmitRecordPolicy, - SkipRecordPolicy, - WaitForDiscoverPolicy, -) - -__all__ = [ - "DEFAULT_SCHEMA_VALIDATION_POLICIES", - "AbstractSchemaValidationPolicy", - "EmitRecordPolicy", - "SkipRecordPolicy", - "WaitForDiscoverPolicy", -] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/abstract_schema_validation_policy.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/abstract_schema_validation_policy.py deleted file mode 100644 index 004139b78b10..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/abstract_schema_validation_policy.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import ABC, abstractmethod -from typing import Any, Mapping, Optional - - -class AbstractSchemaValidationPolicy(ABC): - name: str - validate_schema_before_sync = False # Whether to verify that records conform to the schema during the stream's availabilty check - - @abstractmethod - def record_passes_validation_policy(self, record: Mapping[str, Any], schema: Optional[Mapping[str, Any]]) -> bool: - """ - Return True if the record passes the user's validation policy. - """ - raise NotImplementedError() diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/default_schema_validation_policies.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/default_schema_validation_policies.py deleted file mode 100644 index 02134d1b839f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/default_schema_validation_policies.py +++ /dev/null @@ -1,41 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Mapping, Optional - -from airbyte_cdk.sources.file_based.config.file_based_stream_config import ValidationPolicy -from airbyte_cdk.sources.file_based.exceptions import FileBasedSourceError, StopSyncPerValidationPolicy -from airbyte_cdk.sources.file_based.schema_helpers import conforms_to_schema -from airbyte_cdk.sources.file_based.schema_validation_policies import AbstractSchemaValidationPolicy - - -class EmitRecordPolicy(AbstractSchemaValidationPolicy): - name = "emit_record" - - def record_passes_validation_policy(self, record: Mapping[str, Any], schema: Optional[Mapping[str, Any]]) -> bool: - return True - - -class SkipRecordPolicy(AbstractSchemaValidationPolicy): - name = "skip_record" - - def record_passes_validation_policy(self, record: Mapping[str, Any], schema: Optional[Mapping[str, Any]]) -> bool: - return schema is not None and conforms_to_schema(record, schema) - - -class WaitForDiscoverPolicy(AbstractSchemaValidationPolicy): - name = "wait_for_discover" - validate_schema_before_sync = True - - def record_passes_validation_policy(self, record: Mapping[str, Any], schema: Optional[Mapping[str, Any]]) -> bool: - if schema is None or not conforms_to_schema(record, schema): - raise StopSyncPerValidationPolicy(FileBasedSourceError.STOP_SYNC_PER_SCHEMA_VALIDATION_POLICY) - return True - - -DEFAULT_SCHEMA_VALIDATION_POLICIES = { - ValidationPolicy.emit_record: EmitRecordPolicy(), - ValidationPolicy.skip_record: SkipRecordPolicy(), - ValidationPolicy.wait_for_discover: WaitForDiscoverPolicy(), -} diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/__init__.py deleted file mode 100644 index 4b5c4bc2edd5..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from airbyte_cdk.sources.file_based.stream.abstract_file_based_stream import AbstractFileBasedStream -from airbyte_cdk.sources.file_based.stream.default_file_based_stream import DefaultFileBasedStream - -__all__ = ["AbstractFileBasedStream", "DefaultFileBasedStream"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py deleted file mode 100644 index 850c4c936d6c..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py +++ /dev/null @@ -1,173 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import abstractmethod -from functools import cache, cached_property, lru_cache -from typing import Any, Dict, Iterable, List, Mapping, Optional, Type - -from airbyte_cdk import AirbyteMessage -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.file_based.availability_strategy import AbstractFileBasedAvailabilityStrategy -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig, PrimaryKeyType -from airbyte_cdk.sources.file_based.discovery_policy import AbstractDiscoveryPolicy -from airbyte_cdk.sources.file_based.exceptions import FileBasedErrorsCollector, FileBasedSourceError, RecordParseError, UndefinedParserError -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.schema_validation_policies import AbstractSchemaValidationPolicy -from airbyte_cdk.sources.file_based.stream.cursor import AbstractFileBasedCursor -from airbyte_cdk.sources.file_based.types import StreamSlice -from airbyte_cdk.sources.streams import Stream -from airbyte_cdk.sources.streams.checkpoint import Cursor -from deprecated import deprecated - - -class AbstractFileBasedStream(Stream): - """ - A file-based stream in an Airbyte source. - - In addition to the base Stream attributes, a file-based stream has - - A config object (derived from the corresponding stream section in source config). - This contains the globs defining the stream's files. - - A StreamReader, which knows how to list and open files in the stream. - - A FileBasedAvailabilityStrategy, which knows how to verify that we can list and open - files in the stream. - - A DiscoveryPolicy that controls the number of concurrent requests sent to the source - during discover, and the number of files used for schema discovery. - - A dictionary of FileType:Parser that holds all the file types that can be handled - by the stream. - """ - - def __init__( - self, - config: FileBasedStreamConfig, - catalog_schema: Optional[Mapping[str, Any]], - stream_reader: AbstractFileBasedStreamReader, - availability_strategy: AbstractFileBasedAvailabilityStrategy, - discovery_policy: AbstractDiscoveryPolicy, - parsers: Dict[Type[Any], FileTypeParser], - validation_policy: AbstractSchemaValidationPolicy, - errors_collector: FileBasedErrorsCollector, - cursor: AbstractFileBasedCursor, - ): - super().__init__() - self.config = config - self.catalog_schema = catalog_schema - self.validation_policy = validation_policy - self.stream_reader = stream_reader - self._discovery_policy = discovery_policy - self._availability_strategy = availability_strategy - self._parsers = parsers - self.errors_collector = errors_collector - self._cursor = cursor - - @property - @abstractmethod - def primary_key(self) -> PrimaryKeyType: - ... - - @cache - def list_files(self) -> List[RemoteFile]: - """ - List all files that belong to the stream. - - The output of this method is cached so we don't need to list the files more than once. - This means we won't pick up changes to the files during a sync. This method uses the - get_files method which is implemented by the concrete stream class. - """ - return list(self.get_files()) - - @abstractmethod - def get_files(self) -> Iterable[RemoteFile]: - """ - List all files that belong to the stream as defined by the stream's globs. - """ - ... - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: Optional[List[str]] = None, - stream_slice: Optional[StreamSlice] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[Mapping[str, Any] | AirbyteMessage]: - """ - Yield all records from all remote files in `list_files_for_this_sync`. - This method acts as an adapter between the generic Stream interface and the file-based's - stream since file-based streams manage their own states. - """ - if stream_slice is None: - raise ValueError("stream_slice must be set") - return self.read_records_from_slice(stream_slice) - - @abstractmethod - def read_records_from_slice(self, stream_slice: StreamSlice) -> Iterable[Mapping[str, Any] | AirbyteMessage]: - """ - Yield all records from all remote files in `list_files_for_this_sync`. - """ - ... - - def stream_slices( - self, *, sync_mode: SyncMode, cursor_field: Optional[List[str]] = None, stream_state: Optional[Mapping[str, Any]] = None - ) -> Iterable[Optional[Mapping[str, Any]]]: - """ - This method acts as an adapter between the generic Stream interface and the file-based's - stream since file-based streams manage their own states. - """ - return self.compute_slices() - - @abstractmethod - def compute_slices(self) -> Iterable[Optional[StreamSlice]]: - """ - Return a list of slices that will be used to read files in the current sync. - :return: The slices to use for the current sync. - """ - ... - - @abstractmethod - @lru_cache(maxsize=None) - def get_json_schema(self) -> Mapping[str, Any]: - """ - Return the JSON Schema for a stream. - """ - ... - - @abstractmethod - def infer_schema(self, files: List[RemoteFile]) -> Mapping[str, Any]: - """ - Infer the schema for files in the stream. - """ - ... - - def get_parser(self) -> FileTypeParser: - try: - return self._parsers[type(self.config.format)] - except KeyError: - raise UndefinedParserError(FileBasedSourceError.UNDEFINED_PARSER, stream=self.name, format=type(self.config.format)) - - def record_passes_validation_policy(self, record: Mapping[str, Any]) -> bool: - if self.validation_policy: - return self.validation_policy.record_passes_validation_policy(record=record, schema=self.catalog_schema) - else: - raise RecordParseError( - FileBasedSourceError.UNDEFINED_VALIDATION_POLICY, stream=self.name, validation_policy=self.config.validation_policy - ) - - @cached_property - @deprecated(version="3.7.0") - def availability_strategy(self) -> AbstractFileBasedAvailabilityStrategy: - return self._availability_strategy - - @property - def name(self) -> str: - return self.config.name - - def get_cursor(self) -> Optional[Cursor]: - """ - This is a temporary hack. Because file-based, declarative, and concurrent have _slightly_ different cursor implementations - the file-based cursor isn't compatible with the cursor-based iteration flow in core.py top-level CDK. By setting this to - None, we defer to the regular incremental checkpoint flow. Once all cursors are consolidated under a common interface - then this override can be removed. - """ - return None diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/adapters.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/adapters.py deleted file mode 100644 index cb20dd9aab3e..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/adapters.py +++ /dev/null @@ -1,314 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -import copy -import logging -from functools import lru_cache -from typing import TYPE_CHECKING, Any, Iterable, List, Mapping, MutableMapping, Optional, Union - -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, ConfiguredAirbyteStream, Level, SyncMode, Type -from airbyte_cdk.sources import AbstractSource -from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager -from airbyte_cdk.sources.file_based.availability_strategy import ( - AbstractFileBasedAvailabilityStrategy, - AbstractFileBasedAvailabilityStrategyWrapper, -) -from airbyte_cdk.sources.file_based.config.file_based_stream_config import PrimaryKeyType -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.stream import AbstractFileBasedStream -from airbyte_cdk.sources.file_based.stream.concurrent.cursor import FileBasedFinalStateCursor -from airbyte_cdk.sources.file_based.stream.cursor import AbstractFileBasedCursor -from airbyte_cdk.sources.file_based.types import StreamSlice -from airbyte_cdk.sources.message import MessageRepository -from airbyte_cdk.sources.source import ExperimentalClassWarning -from airbyte_cdk.sources.streams.concurrent.abstract_stream_facade import AbstractStreamFacade -from airbyte_cdk.sources.streams.concurrent.default_stream import DefaultStream -from airbyte_cdk.sources.streams.concurrent.exceptions import ExceptionWithDisplayMessage -from airbyte_cdk.sources.streams.concurrent.helpers import get_cursor_field_from_stream, get_primary_key_from_stream -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.partition_generator import PartitionGenerator -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record -from airbyte_cdk.sources.streams.core import StreamData -from airbyte_cdk.sources.utils.schema_helpers import InternalConfig -from airbyte_cdk.sources.utils.slice_logger import SliceLogger -from deprecated.classic import deprecated - -if TYPE_CHECKING: - from airbyte_cdk.sources.file_based.stream.concurrent.cursor import AbstractConcurrentFileBasedCursor - -""" -This module contains adapters to help enabling concurrency on File-based Stream objects without needing to migrate to AbstractStream -""" - - -@deprecated("This class is experimental. Use at your own risk.", category=ExperimentalClassWarning) -class FileBasedStreamFacade(AbstractStreamFacade[DefaultStream], AbstractFileBasedStream): - @classmethod - def create_from_stream( - cls, - stream: AbstractFileBasedStream, - source: AbstractSource, - logger: logging.Logger, - state: Optional[MutableMapping[str, Any]], - cursor: "AbstractConcurrentFileBasedCursor", - ) -> "FileBasedStreamFacade": - """ - Create a ConcurrentStream from a FileBasedStream object. - """ - pk = get_primary_key_from_stream(stream.primary_key) - cursor_field = get_cursor_field_from_stream(stream) - stream._cursor = cursor - - if not source.message_repository: - raise ValueError( - "A message repository is required to emit non-record messages. Please set the message repository on the source." - ) - - message_repository = source.message_repository - return FileBasedStreamFacade( - DefaultStream( - partition_generator=FileBasedStreamPartitionGenerator( - stream, - message_repository, - SyncMode.full_refresh if isinstance(cursor, FileBasedFinalStateCursor) else SyncMode.incremental, - [cursor_field] if cursor_field is not None else None, - state, - cursor, - ), - name=stream.name, - json_schema=stream.get_json_schema(), - availability_strategy=AbstractFileBasedAvailabilityStrategyWrapper(stream), - primary_key=pk, - cursor_field=cursor_field, - logger=logger, - namespace=stream.namespace, - cursor=cursor, - ), - stream, - cursor, - logger=logger, - slice_logger=source._slice_logger, - ) - - def __init__( - self, - stream: DefaultStream, - legacy_stream: AbstractFileBasedStream, - cursor: AbstractFileBasedCursor, - slice_logger: SliceLogger, - logger: logging.Logger, - ): - """ - :param stream: The underlying AbstractStream - """ - self._abstract_stream = stream - self._legacy_stream = legacy_stream - self._cursor = cursor - self._slice_logger = slice_logger - self._logger = logger - self.catalog_schema = legacy_stream.catalog_schema - self.config = legacy_stream.config - self.validation_policy = legacy_stream.validation_policy - - @property - def cursor_field(self) -> Union[str, List[str]]: - if self._abstract_stream.cursor_field is None: - return [] - else: - return self._abstract_stream.cursor_field - - @property - def name(self) -> str: - return self._abstract_stream.name - - @property - def supports_incremental(self) -> bool: - return self._legacy_stream.supports_incremental - - @property - @deprecated(version="3.7.0") - def availability_strategy(self) -> AbstractFileBasedAvailabilityStrategy: - return self._legacy_stream.availability_strategy - - @lru_cache(maxsize=None) - def get_json_schema(self) -> Mapping[str, Any]: - return self._abstract_stream.get_json_schema() - - @property - def primary_key(self) -> PrimaryKeyType: - return self._legacy_stream.config.primary_key or self.get_parser().get_parser_defined_primary_key(self._legacy_stream.config) - - def get_parser(self) -> FileTypeParser: - return self._legacy_stream.get_parser() - - def get_files(self) -> Iterable[RemoteFile]: - return self._legacy_stream.get_files() - - def read_records_from_slice(self, stream_slice: StreamSlice) -> Iterable[Mapping[str, Any]]: - yield from self._legacy_stream.read_records_from_slice(stream_slice) # type: ignore[misc] # Only Mapping[str, Any] is expected for legacy streams, not AirbyteMessage - - def compute_slices(self) -> Iterable[Optional[StreamSlice]]: - return self._legacy_stream.compute_slices() - - def infer_schema(self, files: List[RemoteFile]) -> Mapping[str, Any]: - return self._legacy_stream.infer_schema(files) - - def get_underlying_stream(self) -> DefaultStream: - return self._abstract_stream - - def read( - self, - configured_stream: ConfiguredAirbyteStream, - logger: logging.Logger, - slice_logger: SliceLogger, - stream_state: MutableMapping[str, Any], - state_manager: ConnectorStateManager, - internal_config: InternalConfig, - ) -> Iterable[StreamData]: - yield from self._read_records() - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: Optional[List[str]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - try: - yield from self._read_records() - except Exception as exc: - if hasattr(self._cursor, "state"): - state = str(self._cursor.state) - else: - # This shouldn't happen if the ConcurrentCursor was used - state = "unknown; no state attribute was available on the cursor" - yield AirbyteMessage( - type=Type.LOG, log=AirbyteLogMessage(level=Level.ERROR, message=f"Cursor State at time of exception: {state}") - ) - raise exc - - def _read_records(self) -> Iterable[StreamData]: - for partition in self._abstract_stream.generate_partitions(): - if self._slice_logger.should_log_slice_message(self._logger): - yield self._slice_logger.create_slice_log_message(partition.to_slice()) - for record in partition.read(): - yield record.data - - -class FileBasedStreamPartition(Partition): - def __init__( - self, - stream: AbstractFileBasedStream, - _slice: Optional[Mapping[str, Any]], - message_repository: MessageRepository, - sync_mode: SyncMode, - cursor_field: Optional[List[str]], - state: Optional[MutableMapping[str, Any]], - cursor: "AbstractConcurrentFileBasedCursor", - ): - self._stream = stream - self._slice = _slice - self._message_repository = message_repository - self._sync_mode = sync_mode - self._cursor_field = cursor_field - self._state = state - self._cursor = cursor - self._is_closed = False - - def read(self) -> Iterable[Record]: - try: - for record_data in self._stream.read_records( - cursor_field=self._cursor_field, - sync_mode=SyncMode.full_refresh, - stream_slice=copy.deepcopy(self._slice), - stream_state=self._state, - ): - if isinstance(record_data, Mapping): - data_to_return = dict(record_data) - self._stream.transformer.transform(data_to_return, self._stream.get_json_schema()) - yield Record(data_to_return, self) - elif isinstance(record_data, AirbyteMessage) and record_data.type == Type.RECORD and record_data.record is not None: - # `AirbyteMessage`s of type `Record` should also be yielded so they are enqueued - yield Record(record_data.record.data, self) - else: - self._message_repository.emit_message(record_data) - except Exception as e: - display_message = self._stream.get_error_display_message(e) - if display_message: - raise ExceptionWithDisplayMessage(display_message) from e - else: - raise e - - def to_slice(self) -> Optional[Mapping[str, Any]]: - if self._slice is None: - return None - assert ( - len(self._slice["files"]) == 1 - ), f"Expected 1 file per partition but got {len(self._slice['files'])} for stream {self.stream_name()}" - file = self._slice["files"][0] - return {"files": [file]} - - def close(self) -> None: - self._cursor.close_partition(self) - self._is_closed = True - - def is_closed(self) -> bool: - return self._is_closed - - def __hash__(self) -> int: - if self._slice: - # Convert the slice to a string so that it can be hashed - if len(self._slice["files"]) != 1: - raise ValueError( - f"Slices for file-based streams should be of length 1, but got {len(self._slice['files'])}. This is unexpected. Please contact Support." - ) - else: - s = f"{self._slice['files'][0].last_modified.strftime('%Y-%m-%dT%H:%M:%S.%fZ')}_{self._slice['files'][0].uri}" - return hash((self._stream.name, s)) - else: - return hash(self._stream.name) - - def stream_name(self) -> str: - return self._stream.name - - def __repr__(self) -> str: - return f"FileBasedStreamPartition({self._stream.name}, {self._slice})" - - -class FileBasedStreamPartitionGenerator(PartitionGenerator): - def __init__( - self, - stream: AbstractFileBasedStream, - message_repository: MessageRepository, - sync_mode: SyncMode, - cursor_field: Optional[List[str]], - state: Optional[MutableMapping[str, Any]], - cursor: "AbstractConcurrentFileBasedCursor", - ): - self._stream = stream - self._message_repository = message_repository - self._sync_mode = sync_mode - self._cursor_field = cursor_field - self._state = state - self._cursor = cursor - - def generate(self) -> Iterable[FileBasedStreamPartition]: - pending_partitions = [] - for _slice in self._stream.stream_slices(sync_mode=self._sync_mode, cursor_field=self._cursor_field, stream_state=self._state): - if _slice is not None: - for file in _slice.get("files", []): - pending_partitions.append( - FileBasedStreamPartition( - self._stream, - {"files": [copy.deepcopy(file)]}, - self._message_repository, - self._sync_mode, - self._cursor_field, - self._state, - self._cursor, - ) - ) - self._cursor.set_pending_partitions(pending_partitions) - yield from pending_partitions diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/cursor/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/cursor/__init__.py deleted file mode 100644 index 590f37bb6d63..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/cursor/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from .abstract_concurrent_file_based_cursor import AbstractConcurrentFileBasedCursor -from .file_based_concurrent_cursor import FileBasedConcurrentCursor -from .file_based_final_state_cursor import FileBasedFinalStateCursor - -__all__ = ["AbstractConcurrentFileBasedCursor", "FileBasedConcurrentCursor", "FileBasedFinalStateCursor"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/cursor/abstract_concurrent_file_based_cursor.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/cursor/abstract_concurrent_file_based_cursor.py deleted file mode 100644 index d21a6a01e70e..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/cursor/abstract_concurrent_file_based_cursor.py +++ /dev/null @@ -1,68 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from abc import ABC, abstractmethod -from datetime import datetime -from typing import TYPE_CHECKING, Any, Iterable, List, MutableMapping - -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.stream.cursor import AbstractFileBasedCursor -from airbyte_cdk.sources.file_based.types import StreamState -from airbyte_cdk.sources.streams.concurrent.cursor import Cursor -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record - -if TYPE_CHECKING: - from airbyte_cdk.sources.file_based.stream.concurrent.adapters import FileBasedStreamPartition - - -class AbstractConcurrentFileBasedCursor(Cursor, AbstractFileBasedCursor, ABC): - def __init__(self, *args: Any, **kwargs: Any) -> None: - pass - - @property - @abstractmethod - def state(self) -> MutableMapping[str, Any]: - ... - - @abstractmethod - def observe(self, record: Record) -> None: - ... - - @abstractmethod - def close_partition(self, partition: Partition) -> None: - ... - - @abstractmethod - def set_pending_partitions(self, partitions: List["FileBasedStreamPartition"]) -> None: - ... - - @abstractmethod - def add_file(self, file: RemoteFile) -> None: - ... - - @abstractmethod - def get_files_to_sync(self, all_files: Iterable[RemoteFile], logger: logging.Logger) -> Iterable[RemoteFile]: - ... - - @abstractmethod - def get_state(self) -> MutableMapping[str, Any]: - ... - - @abstractmethod - def set_initial_state(self, value: StreamState) -> None: - ... - - @abstractmethod - def get_start_time(self) -> datetime: - ... - - @abstractmethod - def emit_state_message(self) -> None: - ... - - @abstractmethod - def ensure_at_least_one_state_emitted(self) -> None: - ... diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_concurrent_cursor.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_concurrent_cursor.py deleted file mode 100644 index 0e3acaf85366..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_concurrent_cursor.py +++ /dev/null @@ -1,277 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from datetime import datetime, timedelta -from threading import RLock -from typing import TYPE_CHECKING, Any, Dict, Iterable, List, MutableMapping, Optional, Tuple - -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, Level, Type -from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.stream.concurrent.cursor.abstract_concurrent_file_based_cursor import AbstractConcurrentFileBasedCursor -from airbyte_cdk.sources.file_based.stream.cursor import DefaultFileBasedCursor -from airbyte_cdk.sources.file_based.types import StreamState -from airbyte_cdk.sources.message.repository import MessageRepository -from airbyte_cdk.sources.streams.concurrent.cursor import CursorField -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record - -if TYPE_CHECKING: - from airbyte_cdk.sources.file_based.stream.concurrent.adapters import FileBasedStreamPartition - -_NULL_FILE = "" - - -class FileBasedConcurrentCursor(AbstractConcurrentFileBasedCursor): - CURSOR_FIELD = "_ab_source_file_last_modified" - DEFAULT_DAYS_TO_SYNC_IF_HISTORY_IS_FULL = DefaultFileBasedCursor.DEFAULT_DAYS_TO_SYNC_IF_HISTORY_IS_FULL - DEFAULT_MAX_HISTORY_SIZE = 10_000 - DATE_TIME_FORMAT = DefaultFileBasedCursor.DATE_TIME_FORMAT - zero_value = datetime.min - zero_cursor_value = f"0001-01-01T00:00:00.000000Z_{_NULL_FILE}" - - def __init__( - self, - stream_config: FileBasedStreamConfig, - stream_name: str, - stream_namespace: Optional[str], - stream_state: MutableMapping[str, Any], - message_repository: MessageRepository, - connector_state_manager: ConnectorStateManager, - cursor_field: CursorField, - ) -> None: - super().__init__() - self._stream_name = stream_name - self._stream_namespace = stream_namespace - self._state = stream_state - self._message_repository = message_repository - self._connector_state_manager = connector_state_manager - self._cursor_field = cursor_field - self._time_window_if_history_is_full = timedelta( - days=stream_config.days_to_sync_if_history_is_full or self.DEFAULT_DAYS_TO_SYNC_IF_HISTORY_IS_FULL - ) - self._state_lock = RLock() - self._pending_files_lock = RLock() - self._pending_files: Optional[Dict[str, RemoteFile]] = None - self._file_to_datetime_history = stream_state.get("history", {}) if stream_state else {} - self._prev_cursor_value = self._compute_prev_sync_cursor(stream_state) - self._sync_start = self._compute_start_time() - - @property - def state(self) -> MutableMapping[str, Any]: - return self._state - - def observe(self, record: Record) -> None: - pass - - def close_partition(self, partition: Partition) -> None: - with self._pending_files_lock: - if self._pending_files is None: - raise RuntimeError("Expected pending partitions to be set but it was not. This is unexpected. Please contact Support.") - - def set_pending_partitions(self, partitions: List["FileBasedStreamPartition"]) -> None: - with self._pending_files_lock: - self._pending_files = {} - for partition in partitions: - _slice = partition.to_slice() - if _slice is None: - continue - for file in _slice["files"]: - if file.uri in self._pending_files.keys(): - raise RuntimeError(f"Already found file {_slice} in pending files. This is unexpected. Please contact Support.") - self._pending_files.update({file.uri: file}) - - def _compute_prev_sync_cursor(self, value: Optional[StreamState]) -> Tuple[datetime, str]: - if not value: - return self.zero_value, "" - prev_cursor_str = value.get(self._cursor_field.cursor_field_key) or self.zero_cursor_value - # So if we see a cursor greater than the earliest file, it means that we have likely synced all files. - # However, we take the earliest file as the cursor value for the purpose of checking which files to - # sync, in case new files have been uploaded in the meantime. - # This should be very rare, as it would indicate a race condition where a file with an earlier - # last_modified time was uploaded after a file with a later last_modified time. Since last_modified - # represents the start time that the file was uploaded, we can usually expect that all previous - # files have already been uploaded. If that's the case, they'll be in history and we'll skip - # re-uploading them. - earliest_file_cursor_value = self._get_cursor_key_from_file(self._compute_earliest_file_in_history()) - cursor_str = min(prev_cursor_str, earliest_file_cursor_value) - cursor_dt, cursor_uri = cursor_str.split("_", 1) - return datetime.strptime(cursor_dt, self.DATE_TIME_FORMAT), cursor_uri - - def _get_cursor_key_from_file(self, file: Optional[RemoteFile]) -> str: - if file: - return f"{datetime.strftime(file.last_modified, self.DATE_TIME_FORMAT)}_{file.uri}" - return self.zero_cursor_value - - def _compute_earliest_file_in_history(self) -> Optional[RemoteFile]: - with self._state_lock: - if self._file_to_datetime_history: - filename, last_modified = min(self._file_to_datetime_history.items(), key=lambda f: (f[1], f[0])) - return RemoteFile(uri=filename, last_modified=datetime.strptime(last_modified, self.DATE_TIME_FORMAT)) - else: - return None - - def add_file(self, file: RemoteFile) -> None: - """ - Add a file to the cursor. This method is called when a file is processed by the stream. - :param file: The file to add - """ - if self._pending_files is None: - raise RuntimeError("Expected pending partitions to be set but it was not. This is unexpected. Please contact Support.") - with self._pending_files_lock: - with self._state_lock: - if file.uri not in self._pending_files: - self._message_repository.emit_message( - AirbyteMessage( - type=Type.LOG, - log=AirbyteLogMessage( - level=Level.WARN, - message=f"The file {file.uri} was not found in the list of pending files. This is unexpected. Please contact Support", - ), - ) - ) - else: - self._pending_files.pop(file.uri) - self._file_to_datetime_history[file.uri] = file.last_modified.strftime(self.DATE_TIME_FORMAT) - if len(self._file_to_datetime_history) > self.DEFAULT_MAX_HISTORY_SIZE: - # Get the earliest file based on its last modified date and its uri - oldest_file = self._compute_earliest_file_in_history() - if oldest_file: - del self._file_to_datetime_history[oldest_file.uri] - else: - raise Exception( - "The history is full but there is no files in the history. This should never happen and might be indicative of a bug in the CDK." - ) - self.emit_state_message() - - def emit_state_message(self) -> None: - with self._state_lock: - new_state = self.get_state() - self._connector_state_manager.update_state_for_stream( - self._stream_name, - self._stream_namespace, - new_state, - ) - state_message = self._connector_state_manager.create_state_message(self._stream_name, self._stream_namespace) - self._message_repository.emit_message(state_message) - - def _get_new_cursor_value(self) -> str: - with self._pending_files_lock: - with self._state_lock: - if self._pending_files: - # If there are partitions that haven't been synced, we don't know whether the files that have been synced - # represent a contiguous region. - # To avoid missing files, we only increment the cursor up to the oldest pending file, because we know - # that all older files have been synced. - return self._get_cursor_key_from_file(self._compute_earliest_pending_file()) - elif self._file_to_datetime_history: - # If all partitions have been synced, we know that the sync is up-to-date and so can advance - # the cursor to the newest file in history. - return self._get_cursor_key_from_file(self._compute_latest_file_in_history()) - else: - return f"{self.zero_value.strftime(self.DATE_TIME_FORMAT)}_" - - def _compute_earliest_pending_file(self) -> Optional[RemoteFile]: - if self._pending_files: - return min(self._pending_files.values(), key=lambda x: x.last_modified) - else: - return None - - def _compute_latest_file_in_history(self) -> Optional[RemoteFile]: - with self._state_lock: - if self._file_to_datetime_history: - filename, last_modified = max(self._file_to_datetime_history.items(), key=lambda f: (f[1], f[0])) - return RemoteFile(uri=filename, last_modified=datetime.strptime(last_modified, self.DATE_TIME_FORMAT)) - else: - return None - - def get_files_to_sync(self, all_files: Iterable[RemoteFile], logger: logging.Logger) -> Iterable[RemoteFile]: - """ - Given the list of files in the source, return the files that should be synced. - :param all_files: All files in the source - :param logger: - :return: The files that should be synced - """ - with self._state_lock: - if self._is_history_full(): - logger.warning( - f"The state history is full. " - f"This sync and future syncs won't be able to use the history to filter out duplicate files. " - f"It will instead use the time window of {self._time_window_if_history_is_full} to filter out files." - ) - for f in all_files: - if self._should_sync_file(f, logger): - yield f - - def _should_sync_file(self, file: RemoteFile, logger: logging.Logger) -> bool: - with self._state_lock: - if file.uri in self._file_to_datetime_history: - # If the file's uri is in the history, we should sync the file if it has been modified since it was synced - updated_at_from_history = datetime.strptime(self._file_to_datetime_history[file.uri], self.DATE_TIME_FORMAT) - if file.last_modified < updated_at_from_history: - self._message_repository.emit_message( - AirbyteMessage( - type=Type.LOG, - log=AirbyteLogMessage( - level=Level.WARN, - message=f"The file {file.uri}'s last modified date is older than the last time it was synced. This is unexpected. Skipping the file.", - ), - ) - ) - return False - else: - return file.last_modified > updated_at_from_history - - prev_cursor_timestamp, prev_cursor_uri = self._prev_cursor_value - if self._is_history_full(): - if file.last_modified > prev_cursor_timestamp: - # If the history is partial and the file's datetime is strictly greater than the cursor, we should sync it - return True - elif file.last_modified == prev_cursor_timestamp: - # If the history is partial and the file's datetime is equal to the earliest file in the history, - # we should sync it if its uri is greater than or equal to the cursor value. - return file.uri > prev_cursor_uri - else: - return file.last_modified >= self._sync_start - else: - # The file is not in the history and the history is complete. We know we need to sync the file - return True - - def _is_history_full(self) -> bool: - """ - Returns true if the state's history is full, meaning new entries will start to replace old entries. - """ - with self._state_lock: - if self._file_to_datetime_history is None: - raise RuntimeError("The history object has not been set. This is unexpected. Please contact Support.") - return len(self._file_to_datetime_history) >= self.DEFAULT_MAX_HISTORY_SIZE - - def _compute_start_time(self) -> datetime: - if not self._file_to_datetime_history: - return datetime.min - else: - earliest = min(self._file_to_datetime_history.values()) - earliest_dt = datetime.strptime(earliest, self.DATE_TIME_FORMAT) - if self._is_history_full(): - time_window = datetime.now() - self._time_window_if_history_is_full - earliest_dt = min(earliest_dt, time_window) - return earliest_dt - - def get_start_time(self) -> datetime: - return self._sync_start - - def get_state(self) -> MutableMapping[str, Any]: - """ - Get the state of the cursor. - """ - with self._state_lock: - return {"history": self._file_to_datetime_history, self._cursor_field.cursor_field_key: self._get_new_cursor_value()} - - def set_initial_state(self, value: StreamState) -> None: - pass - - def ensure_at_least_one_state_emitted(self) -> None: - self.emit_state_message() diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_final_state_cursor.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_final_state_cursor.py deleted file mode 100644 index 7181ecd15d7f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_final_state_cursor.py +++ /dev/null @@ -1,71 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from datetime import datetime -from typing import TYPE_CHECKING, Any, Iterable, List, MutableMapping, Optional - -from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.stream.concurrent.cursor.abstract_concurrent_file_based_cursor import AbstractConcurrentFileBasedCursor -from airbyte_cdk.sources.file_based.types import StreamState -from airbyte_cdk.sources.message import MessageRepository -from airbyte_cdk.sources.streams import NO_CURSOR_STATE_KEY -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record - -if TYPE_CHECKING: - from airbyte_cdk.sources.file_based.stream.concurrent.adapters import FileBasedStreamPartition - - -class FileBasedFinalStateCursor(AbstractConcurrentFileBasedCursor): - """Cursor that is used to guarantee at least one state message is emitted for a concurrent file-based stream.""" - - def __init__( - self, stream_config: FileBasedStreamConfig, message_repository: MessageRepository, stream_namespace: Optional[str], **kwargs: Any - ): - self._stream_name = stream_config.name - self._stream_namespace = stream_namespace - self._message_repository = message_repository - # Normally the connector state manager operates at the source-level. However, we only need it to write the sentinel - # state message rather than manage overall source state. This is also only temporary as we move to the resumable - # full refresh world where every stream uses a FileBasedConcurrentCursor with incremental state. - self._connector_state_manager = ConnectorStateManager() - - @property - def state(self) -> MutableMapping[str, Any]: - return {NO_CURSOR_STATE_KEY: True} - - def observe(self, record: Record) -> None: - pass - - def close_partition(self, partition: Partition) -> None: - pass - - def set_pending_partitions(self, partitions: List["FileBasedStreamPartition"]) -> None: - pass - - def add_file(self, file: RemoteFile) -> None: - pass - - def get_files_to_sync(self, all_files: Iterable[RemoteFile], logger: logging.Logger) -> Iterable[RemoteFile]: - return all_files - - def get_state(self) -> MutableMapping[str, Any]: - return {} - - def set_initial_state(self, value: StreamState) -> None: - return None - - def get_start_time(self) -> datetime: - return datetime.min - - def emit_state_message(self) -> None: - pass - - def ensure_at_least_one_state_emitted(self) -> None: - self._connector_state_manager.update_state_for_stream(self._stream_name, self._stream_namespace, self.state) - state_message = self._connector_state_manager.create_state_message(self._stream_name, self._stream_namespace) - self._message_repository.emit_message(state_message) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/cursor/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/cursor/__init__.py deleted file mode 100644 index c1bf15a5d01f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/cursor/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .abstract_file_based_cursor import AbstractFileBasedCursor -from .default_file_based_cursor import DefaultFileBasedCursor - -__all__ = ["AbstractFileBasedCursor", "DefaultFileBasedCursor"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/cursor/abstract_file_based_cursor.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/cursor/abstract_file_based_cursor.py deleted file mode 100644 index f38a5364135c..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/cursor/abstract_file_based_cursor.py +++ /dev/null @@ -1,64 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from abc import ABC, abstractmethod -from datetime import datetime -from typing import Any, Iterable, MutableMapping - -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.types import StreamState - - -class AbstractFileBasedCursor(ABC): - """ - Abstract base class for cursors used by file-based streams. - """ - - @abstractmethod - def __init__(self, stream_config: FileBasedStreamConfig, **kwargs: Any): - """ - Common interface for all cursors. - """ - ... - - @abstractmethod - def add_file(self, file: RemoteFile) -> None: - """ - Add a file to the cursor. This method is called when a file is processed by the stream. - :param file: The file to add - """ - ... - - @abstractmethod - def set_initial_state(self, value: StreamState) -> None: - """ - Set the initial state of the cursor. The cursor cannot be initialized at construction time because the stream doesn't know its state yet. - :param value: The stream state - """ - - @abstractmethod - def get_state(self) -> MutableMapping[str, Any]: - """ - Get the state of the cursor. - """ - ... - - @abstractmethod - def get_start_time(self) -> datetime: - """ - Returns the start time of the current sync. - """ - ... - - @abstractmethod - def get_files_to_sync(self, all_files: Iterable[RemoteFile], logger: logging.Logger) -> Iterable[RemoteFile]: - """ - Given the list of files in the source, return the files that should be synced. - :param all_files: All files in the source - :param logger: - :return: The files that should be synced - """ - ... diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/cursor/default_file_based_cursor.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/cursor/default_file_based_cursor.py deleted file mode 100644 index 58d64acbf63d..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/cursor/default_file_based_cursor.py +++ /dev/null @@ -1,132 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from datetime import datetime, timedelta -from typing import Any, Iterable, MutableMapping, Optional - -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.stream.cursor.abstract_file_based_cursor import AbstractFileBasedCursor -from airbyte_cdk.sources.file_based.types import StreamState - - -class DefaultFileBasedCursor(AbstractFileBasedCursor): - DEFAULT_DAYS_TO_SYNC_IF_HISTORY_IS_FULL = 3 - DEFAULT_MAX_HISTORY_SIZE = 10_000 - DATE_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ" - CURSOR_FIELD = "_ab_source_file_last_modified" - - def __init__(self, stream_config: FileBasedStreamConfig, **_: Any): - super().__init__(stream_config) - self._file_to_datetime_history: MutableMapping[str, str] = {} - self._time_window_if_history_is_full = timedelta( - days=stream_config.days_to_sync_if_history_is_full or self.DEFAULT_DAYS_TO_SYNC_IF_HISTORY_IS_FULL - ) - - if self._time_window_if_history_is_full <= timedelta(): - raise ValueError(f"days_to_sync_if_history_is_full must be a positive timedelta, got {self._time_window_if_history_is_full}") - - self._start_time = self._compute_start_time() - self._initial_earliest_file_in_history: Optional[RemoteFile] = None - - def set_initial_state(self, value: StreamState) -> None: - self._file_to_datetime_history = value.get("history", {}) - self._start_time = self._compute_start_time() - self._initial_earliest_file_in_history = self._compute_earliest_file_in_history() - - def add_file(self, file: RemoteFile) -> None: - self._file_to_datetime_history[file.uri] = file.last_modified.strftime(self.DATE_TIME_FORMAT) - if len(self._file_to_datetime_history) > self.DEFAULT_MAX_HISTORY_SIZE: - # Get the earliest file based on its last modified date and its uri - oldest_file = self._compute_earliest_file_in_history() - if oldest_file: - del self._file_to_datetime_history[oldest_file.uri] - else: - raise Exception( - "The history is full but there is no files in the history. This should never happen and might be indicative of a bug in the CDK." - ) - - def get_state(self) -> StreamState: - state = {"history": self._file_to_datetime_history, self.CURSOR_FIELD: self._get_cursor()} - return state - - def _get_cursor(self) -> Optional[str]: - """ - Returns the cursor value. - - Files are synced in order of last-modified with secondary sort on filename, so the cursor value is - a string joining the last-modified timestamp of the last synced file and the name of the file. - """ - if self._file_to_datetime_history.items(): - filename, timestamp = max(self._file_to_datetime_history.items(), key=lambda x: (x[1], x[0])) - return f"{timestamp}_{filename}" - return None - - def _is_history_full(self) -> bool: - """ - Returns true if the state's history is full, meaning new entries will start to replace old entries. - """ - return len(self._file_to_datetime_history) >= self.DEFAULT_MAX_HISTORY_SIZE - - def _should_sync_file(self, file: RemoteFile, logger: logging.Logger) -> bool: - if file.uri in self._file_to_datetime_history: - # If the file's uri is in the history, we should sync the file if it has been modified since it was synced - updated_at_from_history = datetime.strptime(self._file_to_datetime_history[file.uri], self.DATE_TIME_FORMAT) - if file.last_modified < updated_at_from_history: - logger.warning( - f"The file {file.uri}'s last modified date is older than the last time it was synced. This is unexpected. Skipping the file." - ) - else: - return file.last_modified > updated_at_from_history - return file.last_modified > updated_at_from_history - if self._is_history_full(): - if self._initial_earliest_file_in_history is None: - return True - if file.last_modified > self._initial_earliest_file_in_history.last_modified: - # If the history is partial and the file's datetime is strictly greater than the earliest file in the history, - # we should sync it - return True - elif file.last_modified == self._initial_earliest_file_in_history.last_modified: - # If the history is partial and the file's datetime is equal to the earliest file in the history, - # we should sync it if its uri is strictly greater than the earliest file in the history - return file.uri > self._initial_earliest_file_in_history.uri - else: - # Otherwise, only sync the file if it has been modified since the start of the time window - return file.last_modified >= self.get_start_time() - else: - # The file is not in the history and the history is complete. We know we need to sync the file - return True - - def get_files_to_sync(self, all_files: Iterable[RemoteFile], logger: logging.Logger) -> Iterable[RemoteFile]: - if self._is_history_full(): - logger.warning( - f"The state history is full. " - f"This sync and future syncs won't be able to use the history to filter out duplicate files. " - f"It will instead use the time window of {self._time_window_if_history_is_full} to filter out files." - ) - for f in all_files: - if self._should_sync_file(f, logger): - yield f - - def get_start_time(self) -> datetime: - return self._start_time - - def _compute_earliest_file_in_history(self) -> Optional[RemoteFile]: - if self._file_to_datetime_history: - filename, last_modified = min(self._file_to_datetime_history.items(), key=lambda f: (f[1], f[0])) - return RemoteFile(uri=filename, last_modified=datetime.strptime(last_modified, self.DATE_TIME_FORMAT)) - else: - return None - - def _compute_start_time(self) -> datetime: - if not self._file_to_datetime_history: - return datetime.min - else: - earliest = min(self._file_to_datetime_history.values()) - earliest_dt = datetime.strptime(earliest, self.DATE_TIME_FORMAT) - if self._is_history_full(): - time_window = datetime.now() - self._time_window_if_history_is_full - earliest_dt = min(earliest_dt, time_window) - return earliest_dt diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/default_file_based_stream.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/default_file_based_stream.py deleted file mode 100644 index 77747c3cbb58..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/default_file_based_stream.py +++ /dev/null @@ -1,306 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import asyncio -import itertools -import traceback -from copy import deepcopy -from functools import cache -from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Set, Union - -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, FailureType, Level -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.file_based.config.file_based_stream_config import PrimaryKeyType -from airbyte_cdk.sources.file_based.exceptions import ( - FileBasedSourceError, - InvalidSchemaError, - MissingSchemaError, - RecordParseError, - SchemaInferenceError, - StopSyncPerValidationPolicy, -) -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.schema_helpers import SchemaType, merge_schemas, schemaless_schema -from airbyte_cdk.sources.file_based.stream import AbstractFileBasedStream -from airbyte_cdk.sources.file_based.stream.cursor import AbstractFileBasedCursor -from airbyte_cdk.sources.file_based.types import StreamSlice -from airbyte_cdk.sources.streams import IncrementalMixin -from airbyte_cdk.sources.streams.core import JsonSchema -from airbyte_cdk.sources.utils.record_helper import stream_data_to_airbyte_message -from airbyte_cdk.utils.traced_exception import AirbyteTracedException - - -class DefaultFileBasedStream(AbstractFileBasedStream, IncrementalMixin): - - """ - The default file-based stream. - """ - - DATE_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ" - ab_last_mod_col = "_ab_source_file_last_modified" - ab_file_name_col = "_ab_source_file_url" - airbyte_columns = [ab_last_mod_col, ab_file_name_col] - - def __init__(self, **kwargs: Any): - super().__init__(**kwargs) - - @property - def state(self) -> MutableMapping[str, Any]: - return self._cursor.get_state() - - @state.setter - def state(self, value: MutableMapping[str, Any]) -> None: - """State setter, accept state serialized by state getter.""" - self._cursor.set_initial_state(value) - - @property # type: ignore # mypy complains wrong type, but AbstractFileBasedCursor is parent of file-based cursors - def cursor(self) -> Optional[AbstractFileBasedCursor]: - return self._cursor - - @cursor.setter - def cursor(self, value: AbstractFileBasedCursor) -> None: - if self._cursor is not None: - raise RuntimeError(f"Cursor for stream {self.name} is already set. This is unexpected. Please contact Support.") - self._cursor = value - - @property - def primary_key(self) -> PrimaryKeyType: - return self.config.primary_key or self.get_parser().get_parser_defined_primary_key(self.config) - - def compute_slices(self) -> Iterable[Optional[Mapping[str, Any]]]: - # Sort files by last_modified, uri and return them grouped by last_modified - all_files = self.list_files() - files_to_read = self._cursor.get_files_to_sync(all_files, self.logger) - sorted_files_to_read = sorted(files_to_read, key=lambda f: (f.last_modified, f.uri)) - slices = [{"files": list(group[1])} for group in itertools.groupby(sorted_files_to_read, lambda f: f.last_modified)] - return slices - - def transform_record(self, record: dict[str, Any], file: RemoteFile, last_updated: str) -> dict[str, Any]: - # adds _ab_source_file_last_modified and _ab_source_file_url to the record - record[self.ab_last_mod_col] = last_updated - record[self.ab_file_name_col] = file.uri - return record - - def read_records_from_slice(self, stream_slice: StreamSlice) -> Iterable[AirbyteMessage]: - """ - Yield all records from all remote files in `list_files_for_this_sync`. - - If an error is encountered reading records from a file, log a message and do not attempt - to sync the rest of the file. - """ - schema = self.catalog_schema - if schema is None: - # On read requests we should always have the catalog available - raise MissingSchemaError(FileBasedSourceError.MISSING_SCHEMA, stream=self.name) - # The stream only supports a single file type, so we can use the same parser for all files - parser = self.get_parser() - for file in stream_slice["files"]: - # only serialize the datetime once - file_datetime_string = file.last_modified.strftime(self.DATE_TIME_FORMAT) - n_skipped = line_no = 0 - - try: - for record in parser.parse_records(self.config, file, self.stream_reader, self.logger, schema): - line_no += 1 - if self.config.schemaless: - record = {"data": record} - elif not self.record_passes_validation_policy(record): - n_skipped += 1 - continue - record = self.transform_record(record, file, file_datetime_string) - yield stream_data_to_airbyte_message(self.name, record) - self._cursor.add_file(file) - - except StopSyncPerValidationPolicy: - yield AirbyteMessage( - type=MessageType.LOG, - log=AirbyteLogMessage( - level=Level.WARN, - message=f"Stopping sync in accordance with the configured validation policy. Records in file did not conform to the schema. stream={self.name} file={file.uri} validation_policy={self.config.validation_policy.value} n_skipped={n_skipped}", - ), - ) - break - - except RecordParseError: - # Increment line_no because the exception was raised before we could increment it - line_no += 1 - self.errors_collector.collect( - AirbyteMessage( - type=MessageType.LOG, - log=AirbyteLogMessage( - level=Level.ERROR, - message=f"{FileBasedSourceError.ERROR_PARSING_RECORD.value} stream={self.name} file={file.uri} line_no={line_no} n_skipped={n_skipped}", - stack_trace=traceback.format_exc(), - ), - ), - ) - - except AirbyteTracedException as exc: - # Re-raise the exception to stop the whole sync immediately as this is a fatal error - raise exc - - except Exception: - yield AirbyteMessage( - type=MessageType.LOG, - log=AirbyteLogMessage( - level=Level.ERROR, - message=f"{FileBasedSourceError.ERROR_PARSING_RECORD.value} stream={self.name} file={file.uri} line_no={line_no} n_skipped={n_skipped}", - stack_trace=traceback.format_exc(), - ), - ) - - finally: - if n_skipped: - yield AirbyteMessage( - type=MessageType.LOG, - log=AirbyteLogMessage( - level=Level.WARN, - message=f"Records in file did not pass validation policy. stream={self.name} file={file.uri} n_skipped={n_skipped} validation_policy={self.validation_policy.name}", - ), - ) - - @property - def cursor_field(self) -> Union[str, List[str]]: - """ - Override to return the default cursor field used by this stream e.g: an API entity might always use created_at as the cursor field. - :return: The name of the field used as a cursor. If the cursor is nested, return an array consisting of the path to the cursor. - """ - return self.ab_last_mod_col - - @cache - def get_json_schema(self) -> JsonSchema: - extra_fields = { - self.ab_last_mod_col: {"type": "string"}, - self.ab_file_name_col: {"type": "string"}, - } - try: - schema = self._get_raw_json_schema() - except InvalidSchemaError as config_exception: - raise AirbyteTracedException( - internal_message="Please check the logged errors for more information.", - message=FileBasedSourceError.SCHEMA_INFERENCE_ERROR.value, - exception=AirbyteTracedException(exception=config_exception), - failure_type=FailureType.config_error, - ) - except AirbyteTracedException as ate: - raise ate - except Exception as exc: - raise SchemaInferenceError(FileBasedSourceError.SCHEMA_INFERENCE_ERROR, stream=self.name) from exc - else: - return {"type": "object", "properties": {**extra_fields, **schema["properties"]}} - - def _get_raw_json_schema(self) -> JsonSchema: - if self.config.input_schema: - return self.config.get_input_schema() # type: ignore - elif self.config.schemaless: - return schemaless_schema - else: - files = self.list_files() - first_n_files = len(files) - - if self.config.recent_n_files_to_read_for_schema_discovery: - self.logger.info( - msg=( - f"Only first {self.config.recent_n_files_to_read_for_schema_discovery} files will be used to infer schema " - f"for stream {self.name} due to limitation in config." - ) - ) - first_n_files = self.config.recent_n_files_to_read_for_schema_discovery - - if first_n_files == 0: - self.logger.warning(msg=f"No files were identified in the stream {self.name}. Setting default schema for the stream.") - return schemaless_schema - - max_n_files_for_schema_inference = self._discovery_policy.get_max_n_files_for_schema_inference(self.get_parser()) - - if first_n_files > max_n_files_for_schema_inference: - # Use the most recent files for schema inference, so we pick up schema changes during discovery. - self.logger.warning(msg=f"Refusing to infer schema for {first_n_files} files; using {max_n_files_for_schema_inference} files.") - first_n_files = max_n_files_for_schema_inference - - files = sorted(files, key=lambda x: x.last_modified, reverse=True)[:first_n_files] - - inferred_schema = self.infer_schema(files) - - if not inferred_schema: - raise InvalidSchemaError( - FileBasedSourceError.INVALID_SCHEMA_ERROR, - details=f"Empty schema. Please check that the files are valid for format {self.config.format}", - stream=self.name, - ) - - schema = {"type": "object", "properties": inferred_schema} - - return schema - - def get_files(self) -> Iterable[RemoteFile]: - """ - Return all files that belong to the stream as defined by the stream's globs. - """ - return self.stream_reader.get_matching_files(self.config.globs or [], self.config.legacy_prefix, self.logger) - - def infer_schema(self, files: List[RemoteFile]) -> Mapping[str, Any]: - loop = asyncio.get_event_loop() - schema = loop.run_until_complete(self._infer_schema(files)) - # as infer schema returns a Mapping that is assumed to be immutable, we need to create a deepcopy to avoid modifying the reference - return self._fill_nulls(deepcopy(schema)) - - @staticmethod - def _fill_nulls(schema: Mapping[str, Any]) -> Mapping[str, Any]: - if isinstance(schema, dict): - for k, v in schema.items(): - if k == "type": - if isinstance(v, list): - if "null" not in v: - schema[k] = ["null"] + v - elif v != "null": - schema[k] = ["null", v] - else: - DefaultFileBasedStream._fill_nulls(v) - elif isinstance(schema, list): - for item in schema: - DefaultFileBasedStream._fill_nulls(item) - return schema - - async def _infer_schema(self, files: List[RemoteFile]) -> Mapping[str, Any]: - """ - Infer the schema for a stream. - - Each file type has a corresponding `infer_schema` handler. - Dispatch on file type. - """ - base_schema: SchemaType = {} - pending_tasks: Set[asyncio.tasks.Task[SchemaType]] = set() - - n_started, n_files = 0, len(files) - files_iterator = iter(files) - while pending_tasks or n_started < n_files: - while len(pending_tasks) <= self._discovery_policy.n_concurrent_requests and (file := next(files_iterator, None)): - pending_tasks.add(asyncio.create_task(self._infer_file_schema(file))) - n_started += 1 - # Return when the first task is completed so that we can enqueue a new task as soon as the - # number of concurrent tasks drops below the number allowed. - done, pending_tasks = await asyncio.wait(pending_tasks, return_when=asyncio.FIRST_COMPLETED) - for task in done: - try: - base_schema = merge_schemas(base_schema, task.result()) - except AirbyteTracedException as ate: - raise ate - except Exception as exc: - self.logger.error(f"An error occurred inferring the schema. \n {traceback.format_exc()}", exc_info=exc) - - return base_schema - - async def _infer_file_schema(self, file: RemoteFile) -> SchemaType: - try: - return await self.get_parser().infer_schema(self.config, file, self.stream_reader, self.logger) - except AirbyteTracedException as ate: - raise ate - except Exception as exc: - raise SchemaInferenceError( - FileBasedSourceError.SCHEMA_INFERENCE_ERROR, - file=file.uri, - format=str(self.config.format), - stream=self.name, - ) from exc diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/types.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/types.py deleted file mode 100644 index b83bf37a37a7..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/types.py +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from __future__ import annotations - -from typing import Any, Mapping, MutableMapping - -StreamSlice = Mapping[str, Any] -StreamState = MutableMapping[str, Any] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/http_config.py b/airbyte-cdk/python/airbyte_cdk/sources/http_config.py deleted file mode 100644 index 289ed9a923fb..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/http_config.py +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -# The goal of this variable is to make an implicit dependency explicit. As part of of the Concurrent CDK work, we are facing a situation -# where the connection pool size is too small to serve all the threads (see https://github.com/airbytehq/airbyte/issues/32072). In -# order to fix that, we will increase the requests library pool_maxsize. As there are many pieces of code that sets a requests.Session, we -# are creating this variable here so that a change in one affects the other. This can be removed once we merge how we do HTTP requests in -# one piece of code or once we make connection pool size configurable for each piece of code -MAX_CONNECTION_POOL_SIZE = 20 diff --git a/airbyte-cdk/python/airbyte_cdk/sources/http_logger.py b/airbyte-cdk/python/airbyte_cdk/sources/http_logger.py deleted file mode 100644 index 7158c8003e5b..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/http_logger.py +++ /dev/null @@ -1,47 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Optional, Union - -import requests -from airbyte_cdk.sources.message import LogMessage - - -def format_http_message( - response: requests.Response, title: str, description: str, stream_name: Optional[str], is_auxiliary: bool = None -) -> LogMessage: - request = response.request - log_message = { - "http": { - "title": title, - "description": description, - "request": { - "method": request.method, - "body": { - "content": _normalize_body_string(request.body), - }, - "headers": dict(request.headers), - }, - "response": { - "body": { - "content": response.text, - }, - "headers": dict(response.headers), - "status_code": response.status_code, - }, - }, - "log": { - "level": "debug", - }, - "url": {"full": request.url}, - } - if is_auxiliary is not None: - log_message["http"]["is_auxiliary"] = is_auxiliary - if stream_name: - log_message["airbyte_cdk"] = {"stream": {"name": stream_name}} - return log_message - - -def _normalize_body_string(body_str: Optional[Union[str, bytes]]) -> Optional[str]: - return body_str.decode() if isinstance(body_str, (bytes, bytearray)) else body_str diff --git a/airbyte-cdk/python/airbyte_cdk/sources/message/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/message/__init__.py deleted file mode 100644 index c545c0d736ab..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/message/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# - -from .repository import ( - InMemoryMessageRepository, - LogAppenderMessageRepositoryDecorator, - LogMessage, - MessageRepository, - NoopMessageRepository, -) - -__all__ = ["InMemoryMessageRepository", "LogAppenderMessageRepositoryDecorator", "LogMessage", "MessageRepository", "NoopMessageRepository"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/message/repository.py b/airbyte-cdk/python/airbyte_cdk/sources/message/repository.py deleted file mode 100644 index bf90830900ae..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/message/repository.py +++ /dev/null @@ -1,123 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import logging -from abc import ABC, abstractmethod -from collections import deque -from typing import Callable, Deque, Iterable, List, Optional - -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, Level, Type -from airbyte_cdk.sources.utils.types import JsonType -from airbyte_cdk.utils.airbyte_secrets_utils import filter_secrets - -_LOGGER = logging.getLogger("MessageRepository") -_SUPPORTED_MESSAGE_TYPES = {Type.CONTROL, Type.LOG} -LogMessage = dict[str, JsonType] - -_SEVERITY_BY_LOG_LEVEL = { - Level.FATAL: 1, - Level.ERROR: 2, - Level.WARN: 3, - Level.INFO: 4, - Level.DEBUG: 5, - Level.TRACE: 5, -} - - -def _is_severe_enough(threshold: Level, level: Level) -> bool: - if threshold not in _SEVERITY_BY_LOG_LEVEL: - _LOGGER.warning(f"Log level {threshold} for threshold is not supported. This is probably a CDK bug. Please contact Airbyte.") - return True - - if level not in _SEVERITY_BY_LOG_LEVEL: - _LOGGER.warning( - f"Log level {level} is not supported. This is probably a source bug. Please contact the owner of the source or Airbyte." - ) - return True - - return _SEVERITY_BY_LOG_LEVEL[threshold] >= _SEVERITY_BY_LOG_LEVEL[level] - - -class MessageRepository(ABC): - @abstractmethod - def emit_message(self, message: AirbyteMessage) -> None: - raise NotImplementedError() - - @abstractmethod - def log_message(self, level: Level, message_provider: Callable[[], LogMessage]) -> None: - """ - Computing messages can be resource consuming. This method is specialized for logging because we want to allow for lazy evaluation if - the log level is less severe than what is configured - """ - raise NotImplementedError() - - @abstractmethod - def consume_queue(self) -> Iterable[AirbyteMessage]: - raise NotImplementedError() - - -class NoopMessageRepository(MessageRepository): - def emit_message(self, message: AirbyteMessage) -> None: - pass - - def log_message(self, level: Level, message_provider: Callable[[], LogMessage]) -> None: - pass - - def consume_queue(self) -> Iterable[AirbyteMessage]: - return [] - - -class InMemoryMessageRepository(MessageRepository): - def __init__(self, log_level: Level = Level.INFO) -> None: - self._message_queue: Deque[AirbyteMessage] = deque() - self._log_level = log_level - - def emit_message(self, message: AirbyteMessage) -> None: - self._message_queue.append(message) - - def log_message(self, level: Level, message_provider: Callable[[], LogMessage]) -> None: - if _is_severe_enough(self._log_level, level): - self.emit_message( - AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=level, message=filter_secrets(json.dumps(message_provider())))) - ) - - def consume_queue(self) -> Iterable[AirbyteMessage]: - while self._message_queue: - yield self._message_queue.popleft() - - -class LogAppenderMessageRepositoryDecorator(MessageRepository): - def __init__(self, dict_to_append: LogMessage, decorated: MessageRepository, log_level: Level = Level.INFO): - self._dict_to_append = dict_to_append - self._decorated = decorated - self._log_level = log_level - - def emit_message(self, message: AirbyteMessage) -> None: - self._decorated.emit_message(message) - - def log_message(self, level: Level, message_provider: Callable[[], LogMessage]) -> None: - if _is_severe_enough(self._log_level, level): - message = message_provider() - self._append_second_to_first(message, self._dict_to_append) - self._decorated.log_message(level, lambda: message) - - def consume_queue(self) -> Iterable[AirbyteMessage]: - return self._decorated.consume_queue() - - def _append_second_to_first(self, first: LogMessage, second: LogMessage, path: Optional[List[str]] = None) -> LogMessage: - if path is None: - path = [] - - for key in second: - if key in first: - if isinstance(first[key], dict) and isinstance(second[key], dict): - self._append_second_to_first(first[key], second[key], path + [str(key)]) # type: ignore # type is verified above - else: - if first[key] != second[key]: - _LOGGER.warning("Conflict at %s" % ".".join(path + [str(key)])) - first[key] = second[key] - else: - first[key] = second[key] - return first diff --git a/airbyte-cdk/python/airbyte_cdk/sources/source.py b/airbyte-cdk/python/airbyte_cdk/sources/source.py deleted file mode 100644 index 975770c88949..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/source.py +++ /dev/null @@ -1,85 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import logging -from abc import ABC, abstractmethod -from typing import Any, Generic, Iterable, List, Mapping, Optional, TypeVar - -from airbyte_cdk.connector import BaseConnector, DefaultConnectorMixin, TConfig -from airbyte_cdk.models import ( - AirbyteCatalog, - AirbyteMessage, - AirbyteStateMessage, - AirbyteStateMessageSerializer, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteCatalogSerializer, -) - -TState = TypeVar("TState") -TCatalog = TypeVar("TCatalog") - - -class ExperimentalClassWarning(DeprecationWarning): - pass - - -class BaseSource(BaseConnector[TConfig], ABC, Generic[TConfig, TState, TCatalog]): - @abstractmethod - def read_state(self, state_path: str) -> TState: - ... - - @abstractmethod - def read_catalog(self, catalog_path: str) -> TCatalog: - ... - - @abstractmethod - def read(self, logger: logging.Logger, config: TConfig, catalog: TCatalog, state: Optional[TState] = None) -> Iterable[AirbyteMessage]: - """ - Returns a generator of the AirbyteMessages generated by reading the source with the given configuration, catalog, and state. - """ - - @abstractmethod - def discover(self, logger: logging.Logger, config: TConfig) -> AirbyteCatalog: - """ - Returns an AirbyteCatalog representing the available streams and fields in this integration. For example, given valid credentials to a - Postgres database, returns an Airbyte catalog where each postgres table is a stream, and each table column is a field. - """ - - -class Source( - DefaultConnectorMixin, - BaseSource[Mapping[str, Any], List[AirbyteStateMessage], ConfiguredAirbyteCatalog], - ABC, -): - # can be overridden to change an input state. - @classmethod - def read_state(cls, state_path: str) -> List[AirbyteStateMessage]: - """ - Retrieves the input state of a sync by reading from the specified JSON file. Incoming state can be deserialized into either - a JSON object for legacy state input or as a list of AirbyteStateMessages for the per-stream state format. Regardless of the - incoming input type, it will always be transformed and output as a list of AirbyteStateMessage(s). - :param state_path: The filepath to where the stream states are located - :return: The complete stream state based on the connector's previous sync - """ - parsed_state_messages = [] - if state_path: - state_obj = BaseConnector._read_json_file(state_path) - if state_obj: - for state in state_obj: # type: ignore # `isinstance(state_obj, List)` ensures that this is a list - parsed_message = AirbyteStateMessageSerializer.load(state) - if not parsed_message.stream and not parsed_message.data and not parsed_message.global_: - raise ValueError("AirbyteStateMessage should contain either a stream, global, or state field") - parsed_state_messages.append(parsed_message) - return parsed_state_messages - - # can be overridden to change an input catalog - @classmethod - def read_catalog(cls, catalog_path: str) -> ConfiguredAirbyteCatalog: - return ConfiguredAirbyteCatalogSerializer.load(cls._read_json_file(catalog_path)) - - @property - def name(self) -> str: - """Source name""" - return self.__class__.__name__ diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/__init__.py deleted file mode 100644 index 030502822f94..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -# Initialize Streams Package -from .core import NO_CURSOR_STATE_KEY, IncrementalMixin, CheckpointMixin, Stream - -__all__ = ["NO_CURSOR_STATE_KEY", "IncrementalMixin", "CheckpointMixin", "Stream"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/availability_strategy.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/availability_strategy.py deleted file mode 100644 index f2042bc1cb92..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/availability_strategy.py +++ /dev/null @@ -1,78 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -import typing -from abc import ABC, abstractmethod -from typing import Any, Mapping, Optional, Tuple - -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.streams.core import Stream, StreamData - -if typing.TYPE_CHECKING: - from airbyte_cdk.sources import Source - - -class AvailabilityStrategy(ABC): - """ - Abstract base class for checking stream availability. - """ - - @abstractmethod - def check_availability(self, stream: Stream, logger: logging.Logger, source: Optional["Source"] = None) -> Tuple[bool, Optional[str]]: - """ - Checks stream availability. - - :param stream: stream - :param logger: source logger - :param source: (optional) source - :return: A tuple of (boolean, str). If boolean is true, then the stream - is available, and no str is required. Otherwise, the stream is unavailable - for some reason and the str should describe what went wrong and how to - resolve the unavailability, if possible. - """ - - @staticmethod - def get_first_stream_slice(stream: Stream) -> Optional[Mapping[str, Any]]: - """ - Gets the first stream_slice from a given stream's stream_slices. - :param stream: stream - :raises StopIteration: if there is no first slice to return (the stream_slices generator is empty) - :return: first stream slice from 'stream_slices' generator (`None` is a valid stream slice) - """ - # We wrap the return output of stream_slices() because some implementations return types that are iterable, - # but not iterators such as lists or tuples - slices = iter( - stream.stream_slices( - cursor_field=stream.cursor_field, # type: ignore[arg-type] - sync_mode=SyncMode.full_refresh, - ) - ) - return next(slices) - - @staticmethod - def get_first_record_for_slice(stream: Stream, stream_slice: Optional[Mapping[str, Any]]) -> StreamData: - """ - Gets the first record for a stream_slice of a stream. - - :param stream: stream instance from which to read records - :param stream_slice: stream_slice parameters for slicing the stream - :raises StopIteration: if there is no first record to return (the read_records generator is empty) - :return: StreamData containing the first record in the slice - """ - # Store the original value of exit_on_rate_limit - original_exit_on_rate_limit = stream.exit_on_rate_limit - - try: - # Ensure exit_on_rate_limit is safely set to True if possible - stream.exit_on_rate_limit = True - - # We wrap the return output of read_records() because some implementations return types that are iterable, - # but not iterators such as lists or tuples - records_for_slice = iter(stream.read_records(sync_mode=SyncMode.full_refresh, stream_slice=stream_slice)) - - return next(records_for_slice) - finally: - # Restore the original exit_on_rate_limit value - stream.exit_on_rate_limit = original_exit_on_rate_limit diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/call_rate.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/call_rate.py deleted file mode 100644 index eb33754504ee..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/call_rate.py +++ /dev/null @@ -1,523 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import abc -import dataclasses -import datetime -import logging -import time -from datetime import timedelta -from threading import RLock -from typing import TYPE_CHECKING, Any, Mapping, Optional -from urllib import parse - -import requests -import requests_cache -from pyrate_limiter import InMemoryBucket, Limiter -from pyrate_limiter import Rate as PyRateRate -from pyrate_limiter import RateItem, TimeClock -from pyrate_limiter.exceptions import BucketFullException - -# prevents mypy from complaining about missing session attributes in LimiterMixin -if TYPE_CHECKING: - MIXIN_BASE = requests.Session -else: - MIXIN_BASE = object - -logger = logging.getLogger("airbyte") - - -@dataclasses.dataclass -class Rate: - """Call rate limit""" - - limit: int - interval: timedelta - - -class CallRateLimitHit(Exception): - def __init__(self, error: str, item: Any, weight: int, rate: str, time_to_wait: timedelta): - """Constructor - - :param error: error message - :param item: object passed into acquire_call - :param weight: how many credits were requested - :param rate: string representation of the rate violated - :param time_to_wait: how long should wait util more call will be available - """ - self.item = item - self.weight = weight - self.rate = rate - self.time_to_wait = time_to_wait - super().__init__(error) - - -class AbstractCallRatePolicy(abc.ABC): - """Call rate policy interface. - Should be configurable with different rules, like N per M for endpoint X. Endpoint X is matched with APIBudget. - """ - - @abc.abstractmethod - def matches(self, request: Any) -> bool: - """Tells if this policy matches specific request and should apply to it - - :param request: - :return: True if policy should apply to this request, False - otherwise - """ - - @abc.abstractmethod - def try_acquire(self, request: Any, weight: int) -> None: - """Try to acquire request - - :param request: a request object representing a single call to API - :param weight: number of requests to deduct from credit - :return: - """ - - @abc.abstractmethod - def update(self, available_calls: Optional[int], call_reset_ts: Optional[datetime.datetime]) -> None: - """Update call rate counting with current values - - :param available_calls: - :param call_reset_ts: - """ - - -class RequestMatcher(abc.ABC): - """Callable that help to match a request object with call rate policies.""" - - @abc.abstractmethod - def __call__(self, request: Any) -> bool: - """ - - :param request: - :return: True if matches the provided request object, False - otherwise - """ - - -class HttpRequestMatcher(RequestMatcher): - """Simple implementation of RequestMatcher for http requests case""" - - def __init__( - self, - method: Optional[str] = None, - url: Optional[str] = None, - params: Optional[Mapping[str, Any]] = None, - headers: Optional[Mapping[str, Any]] = None, - ): - """Constructor - - :param method: - :param url: - :param params: - :param headers: - """ - self._method = method - self._url = url - self._params = {str(k): str(v) for k, v in (params or {}).items()} - self._headers = {str(k): str(v) for k, v in (headers or {}).items()} - - @staticmethod - def _match_dict(obj: Mapping[str, Any], pattern: Mapping[str, Any]) -> bool: - """Check that all elements from pattern dict present and have the same values in obj dict - - :param obj: - :param pattern: - :return: - """ - return pattern.items() <= obj.items() - - def __call__(self, request: Any) -> bool: - """ - - :param request: - :return: True if matches the provided request object, False - otherwise - """ - if isinstance(request, requests.Request): - prepared_request = request.prepare() - elif isinstance(request, requests.PreparedRequest): - prepared_request = request - else: - return False - - if self._method is not None: - if prepared_request.method != self._method: - return False - if self._url is not None and prepared_request.url is not None: - url_without_params = prepared_request.url.split("?")[0] - if url_without_params != self._url: - return False - if self._params is not None: - parsed_url = parse.urlsplit(prepared_request.url) - params = dict(parse.parse_qsl(str(parsed_url.query))) - if not self._match_dict(params, self._params): - return False - if self._headers is not None: - if not self._match_dict(prepared_request.headers, self._headers): - return False - return True - - -class BaseCallRatePolicy(AbstractCallRatePolicy, abc.ABC): - def __init__(self, matchers: list[RequestMatcher]): - self._matchers = matchers - - def matches(self, request: Any) -> bool: - """Tell if this policy matches specific request and should apply to it - - :param request: - :return: True if policy should apply to this request, False - otherwise - """ - - if not self._matchers: - return True - return any(matcher(request) for matcher in self._matchers) - - -class UnlimitedCallRatePolicy(BaseCallRatePolicy): - """ - This policy is for explicit unlimited call rates. - It can be used when we want to match a specific group of requests and don't apply any limits. - - Example: - - APICallBudget( - [ - UnlimitedCallRatePolicy( - matchers=[HttpRequestMatcher(url="/some/method", headers={"sandbox": true})], - ), - FixedWindowCallRatePolicy( - matchers=[HttpRequestMatcher(url="/some/method")], - next_reset_ts=datetime.now(), - period=timedelta(hours=1) - call_limit=1000, - ), - ] - ) - - The code above will limit all calls to /some/method except calls that have header sandbox=True - """ - - def try_acquire(self, request: Any, weight: int) -> None: - """Do nothing""" - - def update(self, available_calls: Optional[int], call_reset_ts: Optional[datetime.datetime]) -> None: - """Do nothing""" - - -class FixedWindowCallRatePolicy(BaseCallRatePolicy): - def __init__(self, next_reset_ts: datetime.datetime, period: timedelta, call_limit: int, matchers: list[RequestMatcher]): - """A policy that allows {call_limit} calls within a {period} time interval - - :param next_reset_ts: next call rate reset time point - :param period: call rate reset period - :param call_limit: - :param matchers: - """ - - self._next_reset_ts = next_reset_ts - self._offset = period - self._call_limit = call_limit - self._calls_num = 0 - self._lock = RLock() - super().__init__(matchers=matchers) - - def try_acquire(self, request: Any, weight: int) -> None: - if weight > self._call_limit: - raise ValueError("Weight can not exceed the call limit") - if not self.matches(request): - raise ValueError("Request does not match the policy") - - with self._lock: - self._update_current_window() - - if self._calls_num + weight > self._call_limit: - reset_in = self._next_reset_ts - datetime.datetime.now() - error_message = ( - f"reached maximum number of allowed calls {self._call_limit} " f"per {self._offset} interval, next reset in {reset_in}." - ) - raise CallRateLimitHit( - error=error_message, - item=request, - weight=weight, - rate=f"{self._call_limit} per {self._offset}", - time_to_wait=reset_in, - ) - - self._calls_num += weight - - def update(self, available_calls: Optional[int], call_reset_ts: Optional[datetime.datetime]) -> None: - """Update call rate counters, by default, only reacts to decreasing updates of available_calls and changes to call_reset_ts. - We ignore updates with available_calls > current_available_calls to support call rate limits that are lower than API limits. - - :param available_calls: - :param call_reset_ts: - """ - with self._lock: - self._update_current_window() - current_available_calls = self._call_limit - self._calls_num - - if available_calls is not None and current_available_calls > available_calls: - logger.debug( - "got rate limit update from api, adjusting available calls from %s to %s", current_available_calls, available_calls - ) - self._calls_num = self._call_limit - available_calls - - if call_reset_ts is not None and call_reset_ts != self._next_reset_ts: - logger.debug("got rate limit update from api, adjusting reset time from %s to %s", self._next_reset_ts, call_reset_ts) - self._next_reset_ts = call_reset_ts - - def _update_current_window(self) -> None: - now = datetime.datetime.now() - if now > self._next_reset_ts: - logger.debug("started new window, %s calls available now", self._call_limit) - self._next_reset_ts = self._next_reset_ts + self._offset - self._calls_num = 0 - - -class MovingWindowCallRatePolicy(BaseCallRatePolicy): - """ - Policy to control requests rate implemented on top of PyRateLimiter lib. - The main difference between this policy and FixedWindowCallRatePolicy is that the rate-limiting window - is moving along requests that we made, and there is no moment when we reset an available number of calls. - This strategy requires saving of timestamps of all requests within a window. - """ - - def __init__(self, rates: list[Rate], matchers: list[RequestMatcher]): - """Constructor - - :param rates: list of rates, the order is important and must be ascending - :param matchers: - """ - if not rates: - raise ValueError("The list of rates can not be empty") - pyrate_rates = [PyRateRate(limit=rate.limit, interval=int(rate.interval.total_seconds() * 1000)) for rate in rates] - self._bucket = InMemoryBucket(pyrate_rates) - # Limiter will create the background task that clears old requests in the bucket - self._limiter = Limiter(self._bucket) - super().__init__(matchers=matchers) - - def try_acquire(self, request: Any, weight: int) -> None: - if not self.matches(request): - raise ValueError("Request does not match the policy") - - try: - self._limiter.try_acquire(request, weight=weight) - except BucketFullException as exc: - item = self._limiter.bucket_factory.wrap_item(request, weight) - assert isinstance(item, RateItem) - - with self._limiter.lock: - time_to_wait = self._bucket.waiting(item) - assert isinstance(time_to_wait, int) - - raise CallRateLimitHit( - error=str(exc.meta_info["error"]), - item=request, - weight=int(exc.meta_info["weight"]), - rate=str(exc.meta_info["rate"]), - time_to_wait=timedelta(milliseconds=time_to_wait), - ) - - def update(self, available_calls: Optional[int], call_reset_ts: Optional[datetime.datetime]) -> None: - """Adjust call bucket to reflect the state of the API server - - :param available_calls: - :param call_reset_ts: - :return: - """ - if available_calls is not None and call_reset_ts is None: # we do our best to sync buckets with API - if available_calls == 0: - with self._limiter.lock: - items_to_add = self._bucket.count() < self._bucket.rates[0].limit - if items_to_add > 0: - now: int = TimeClock().now() # type: ignore[no-untyped-call] - self._bucket.put(RateItem(name="dummy", timestamp=now, weight=items_to_add)) - # TODO: add support if needed, it might be that it is not possible to make a good solution for this case - # if available_calls is not None and call_reset_ts is not None: - # ts = call_reset_ts.timestamp() - - -class AbstractAPIBudget(abc.ABC): - """Interface to some API where a client allowed to have N calls per T interval. - - Important: APIBudget is not doing any API calls, the end user code is responsible to call this interface - to respect call rate limitation of the API. - - It supports multiple policies applied to different group of requests. To distinct these groups we use RequestMatchers. - Individual policy represented by MovingWindowCallRatePolicy and currently supports only moving window strategy. - """ - - @abc.abstractmethod - def acquire_call(self, request: Any, block: bool = True, timeout: Optional[float] = None) -> None: - """Try to get a call from budget, will block by default - - :param request: - :param block: when true (default) will block the current thread until call credit is available - :param timeout: if set will limit maximum time in block, otherwise will wait until credit is available - :raises: CallRateLimitHit - when no credits left and if timeout was set the waiting time exceed the timeout - """ - - @abc.abstractmethod - def get_matching_policy(self, request: Any) -> Optional[AbstractCallRatePolicy]: - """Find matching call rate policy for specific request""" - - @abc.abstractmethod - def update_from_response(self, request: Any, response: Any) -> None: - """Update budget information based on response from API - - :param request: the initial request that triggered this response - :param response: response from the API - """ - - -class APIBudget(AbstractAPIBudget): - """Default APIBudget implementation""" - - def __init__(self, policies: list[AbstractCallRatePolicy], maximum_attempts_to_acquire: int = 100000) -> None: - """Constructor - - :param policies: list of policies in this budget - :param maximum_attempts_to_acquire: number of attempts before throwing hit ratelimit exception, we put some big number here - to avoid situations when many threads compete with each other for a few lots over a significant amount of time - """ - - self._policies = policies - self._maximum_attempts_to_acquire = maximum_attempts_to_acquire - - def get_matching_policy(self, request: Any) -> Optional[AbstractCallRatePolicy]: - for policy in self._policies: - if policy.matches(request): - return policy - return None - - def acquire_call(self, request: Any, block: bool = True, timeout: Optional[float] = None) -> None: - """Try to get a call from budget, will block by default. - Matchers will be called sequentially in the same order they were added. - The first matcher that returns True will - - :param request: - :param block: when true (default) will block the current thread until call credit is available - :param timeout: if provided will limit maximum time in block, otherwise will wait until credit is available - :raises: CallRateLimitHit - when no calls left and if timeout was set the waiting time exceed the timeout - """ - - policy = self.get_matching_policy(request) - if policy: - self._do_acquire(request=request, policy=policy, block=block, timeout=timeout) - elif self._policies: - logger.info("no policies matched with requests, allow call by default") - - def update_from_response(self, request: Any, response: Any) -> None: - """Update budget information based on response from API - - :param request: the initial request that triggered this response - :param response: response from the API - """ - pass - - def _do_acquire(self, request: Any, policy: AbstractCallRatePolicy, block: bool, timeout: Optional[float]) -> None: - """Internal method to try to acquire a call credit - - :param request: - :param policy: - :param block: - :param timeout: - """ - last_exception = None - # sometimes we spend all budget before a second attempt, so we have few more here - for attempt in range(1, self._maximum_attempts_to_acquire): - try: - policy.try_acquire(request, weight=1) - return - except CallRateLimitHit as exc: - last_exception = exc - if block: - if timeout is not None: - time_to_wait = min(timedelta(seconds=timeout), exc.time_to_wait) - else: - time_to_wait = exc.time_to_wait - - time_to_wait = max(timedelta(0), time_to_wait) # sometimes we get negative duration - logger.info("reached call limit %s. going to sleep for %s", exc.rate, time_to_wait) - time.sleep(time_to_wait.total_seconds()) - else: - raise - - if last_exception: - logger.info("we used all %s attempts to acquire and failed", self._maximum_attempts_to_acquire) - raise last_exception - - -class HttpAPIBudget(APIBudget): - """Implementation of AbstractAPIBudget for HTTP""" - - def __init__( - self, - ratelimit_reset_header: str = "ratelimit-reset", - ratelimit_remaining_header: str = "ratelimit-remaining", - status_codes_for_ratelimit_hit: tuple[int] = (429,), - **kwargs: Any, - ): - """Constructor - - :param ratelimit_reset_header: name of the header that has a timestamp of the next reset of call budget - :param ratelimit_remaining_header: name of the header that has the number of calls left - :param status_codes_for_ratelimit_hit: list of HTTP status codes that signal about rate limit being hit - """ - self._ratelimit_reset_header = ratelimit_reset_header - self._ratelimit_remaining_header = ratelimit_remaining_header - self._status_codes_for_ratelimit_hit = status_codes_for_ratelimit_hit - super().__init__(**kwargs) - - def update_from_response(self, request: Any, response: Any) -> None: - policy = self.get_matching_policy(request) - if not policy: - return - - if isinstance(response, requests.Response): - available_calls = self.get_calls_left_from_response(response) - reset_ts = self.get_reset_ts_from_response(response) - policy.update(available_calls=available_calls, call_reset_ts=reset_ts) - - def get_reset_ts_from_response(self, response: requests.Response) -> Optional[datetime.datetime]: - if response.headers.get(self._ratelimit_reset_header): - return datetime.datetime.fromtimestamp(int(response.headers[self._ratelimit_reset_header])) - return None - - def get_calls_left_from_response(self, response: requests.Response) -> Optional[int]: - if response.headers.get(self._ratelimit_remaining_header): - return int(response.headers[self._ratelimit_remaining_header]) - - if response.status_code in self._status_codes_for_ratelimit_hit: - return 0 - - return None - - -class LimiterMixin(MIXIN_BASE): - """Mixin class that adds rate-limiting behavior to requests.""" - - def __init__( - self, - api_budget: AbstractAPIBudget, - **kwargs: Any, - ): - self._api_budget = api_budget - super().__init__(**kwargs) # type: ignore # Base Session doesn't take any kwargs - - def send(self, request: requests.PreparedRequest, **kwargs: Any) -> requests.Response: - """Send a request with rate-limiting.""" - self._api_budget.acquire_call(request) - response = super().send(request, **kwargs) - self._api_budget.update_from_response(request, response) - return response - - -class LimiterSession(LimiterMixin, requests.Session): - """Session that adds rate-limiting behavior to requests.""" - - -class CachedLimiterSession(requests_cache.CacheMixin, LimiterMixin, requests.Session): - """Session class with caching and rate-limiting behavior.""" diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/__init__.py deleted file mode 100644 index 0b122acbab6f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - - -from .checkpoint_reader import ( - CheckpointMode, - CheckpointReader, - CursorBasedCheckpointReader, - FullRefreshCheckpointReader, - IncrementalCheckpointReader, - LegacyCursorBasedCheckpointReader, - ResumableFullRefreshCheckpointReader -) -from .cursor import Cursor -from .resumable_full_refresh_cursor import ResumableFullRefreshCursor - - -__all__ = [ - "CheckpointMode", - "CheckpointReader", - "Cursor", - "CursorBasedCheckpointReader", - "FullRefreshCheckpointReader", - "IncrementalCheckpointReader", - "LegacyCursorBasedCheckpointReader", - "ResumableFullRefreshCheckpointReader", - "ResumableFullRefreshCursor" -] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/checkpoint_reader.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/checkpoint_reader.py deleted file mode 100644 index 1b6d63247206..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/checkpoint_reader.py +++ /dev/null @@ -1,311 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from abc import ABC, abstractmethod -from enum import Enum -from typing import Any, Iterable, Mapping, Optional - -from airbyte_cdk.sources.types import StreamSlice - -from .cursor import Cursor - - -class CheckpointMode(Enum): - INCREMENTAL = "incremental" - RESUMABLE_FULL_REFRESH = "resumable_full_refresh" - FULL_REFRESH = "full_refresh" - - -FULL_REFRESH_COMPLETE_STATE: Mapping[str, Any] = {"__ab_full_refresh_sync_complete": True} - - -class CheckpointReader(ABC): - """ - CheckpointReader manages how to iterate over a stream's partitions and serves as the bridge for interpreting the current state - of the stream that should be emitted back to the platform. - """ - - @abstractmethod - def next(self) -> Optional[Mapping[str, Any]]: - """ - Returns the next slice that will be used to fetch the next group of records. Returning None indicates that the reader - has finished iterating over all slices. - """ - - @abstractmethod - def observe(self, new_state: Mapping[str, Any]) -> None: - """ - Updates the internal state of the checkpoint reader based on the incoming stream state from a connector. - - WARNING: This is used to retain backwards compatibility with streams using the legacy get_stream_state() method. - In order to uptake Resumable Full Refresh, connectors must migrate streams to use the state setter/getter methods. - """ - - @abstractmethod - def get_checkpoint(self) -> Optional[Mapping[str, Any]]: - """ - Retrieves the current state value of the stream. The connector does not emit state messages if the checkpoint value is None. - """ - - -class IncrementalCheckpointReader(CheckpointReader): - """ - IncrementalCheckpointReader handles iterating through a stream based on partitioned windows of data that are determined - before syncing data. - """ - - def __init__(self, stream_state: Mapping[str, Any], stream_slices: Iterable[Optional[Mapping[str, Any]]]): - self._state: Optional[Mapping[str, Any]] = stream_state - self._stream_slices = iter(stream_slices) - self._has_slices = False - - def next(self) -> Optional[Mapping[str, Any]]: - try: - next_slice = next(self._stream_slices) - self._has_slices = True - return next_slice - except StopIteration: - # This is used to avoid sending a duplicate state message at the end of a sync since the stream has already - # emitted state at the end of each slice. If we want to avoid this extra complexity, we can also just accept - # that every sync emits a final duplicate state - if self._has_slices: - self._state = None - return None - - def observe(self, new_state: Mapping[str, Any]) -> None: - self._state = new_state - - def get_checkpoint(self) -> Optional[Mapping[str, Any]]: - return self._state - - -class CursorBasedCheckpointReader(CheckpointReader): - """ - CursorBasedCheckpointReader is used by streams that implement a Cursor in order to manage state. This allows the checkpoint - reader to delegate the complexity of fetching state to the cursor and focus on the iteration over a stream's partitions. - - This reader supports the Cursor interface used by Python and low-code sources. Not to be confused with Cursor interface - that belongs to the Concurrent CDK. - """ - - def __init__(self, cursor: Cursor, stream_slices: Iterable[Optional[Mapping[str, Any]]], read_state_from_cursor: bool = False): - self._cursor = cursor - self._stream_slices = iter(stream_slices) - # read_state_from_cursor is used to delineate that partitions should determine when to stop syncing dynamically according - # to the value of the state at runtime. This currently only applies to streams that use resumable full refresh. - self._read_state_from_cursor = read_state_from_cursor - self._current_slice: Optional[StreamSlice] = None - self._finished_sync = False - self._previous_state: Optional[Mapping[str, Any]] = None - - def next(self) -> Optional[Mapping[str, Any]]: - try: - self.current_slice = self._find_next_slice() - return self.current_slice - except StopIteration: - self._finished_sync = True - return None - - def observe(self, new_state: Mapping[str, Any]) -> None: - # Cursor based checkpoint readers don't need to observe the new state because it has already been updated by the cursor - # while processing records - pass - - def get_checkpoint(self) -> Optional[Mapping[str, Any]]: - # This is used to avoid sending a duplicate state messages - new_state = self._cursor.get_stream_state() - if new_state != self._previous_state: - self._previous_state = new_state - return new_state - else: - return None - - def _find_next_slice(self) -> StreamSlice: - """ - _find_next_slice() returns the next slice of data should be synced for the current stream according to its cursor. - This function supports iterating over a stream's slices across two dimensions. The first dimension is the stream's - partitions like parent records for a substream. The inner dimension iterates over the cursor value like a date - range for incremental streams or a pagination checkpoint for resumable full refresh. - - The basic algorithm for iterating through a stream's slices is: - 1. The first time next() is invoked we get the first partition - 2. If the current partition is already complete as a result of a previous sync attempt, continue iterating until - we find an un-synced partition. - 2. For streams whose cursor value is determined dynamically using stream state - 1. Get the state for the current partition - 2. If the current partition's state is complete, continue iterating over partitions - 3. If the current partition's state is still in progress, emit the next cursor value - 4. If the current partition is complete as delineated by the sentinel value, get the next incomplete partition - 3. When stream has processed all partitions, the iterator will raise a StopIteration exception signaling there are no more - slices left for extracting more records. - """ - - if self._read_state_from_cursor: - if self.current_slice is None: - # current_slice is None represents the first time we are iterating over a stream's slices. The first slice to - # sync not been assigned yet and must first be read from the iterator - next_slice = self.read_and_convert_slice() - state_for_slice = self._cursor.select_state(next_slice) - if state_for_slice == FULL_REFRESH_COMPLETE_STATE: - # Skip every slice that already has the terminal complete value indicating that a previous attempt - # successfully synced the slice - has_more = True - while has_more: - next_slice = self.read_and_convert_slice() - state_for_slice = self._cursor.select_state(next_slice) - has_more = state_for_slice == FULL_REFRESH_COMPLETE_STATE - return StreamSlice(cursor_slice=state_for_slice or {}, partition=next_slice.partition, extra_fields=next_slice.extra_fields) - else: - state_for_slice = self._cursor.select_state(self.current_slice) - if state_for_slice == FULL_REFRESH_COMPLETE_STATE: - # If the current slice is is complete, move to the next slice and skip the next slices that already - # have the terminal complete value indicating that a previous attempt was successfully read. - # Dummy initialization for mypy since we'll iterate at least once to get the next slice - next_candidate_slice = StreamSlice(cursor_slice={}, partition={}) - has_more = True - while has_more: - next_candidate_slice = self.read_and_convert_slice() - state_for_slice = self._cursor.select_state(next_candidate_slice) - has_more = state_for_slice == FULL_REFRESH_COMPLETE_STATE - return StreamSlice( - cursor_slice=state_for_slice or {}, - partition=next_candidate_slice.partition, - extra_fields=next_candidate_slice.extra_fields, - ) - # The reader continues to process the current partition if it's state is still in progress - return StreamSlice( - cursor_slice=state_for_slice or {}, partition=self.current_slice.partition, extra_fields=self.current_slice.extra_fields - ) - else: - # Unlike RFR cursors that iterate dynamically according to how stream state is updated, most cursors operate - # on a fixed set of slices determined before reading records. They just iterate to the next slice - return self.read_and_convert_slice() - - @property - def current_slice(self) -> Optional[StreamSlice]: - return self._current_slice - - @current_slice.setter - def current_slice(self, value: StreamSlice) -> None: - self._current_slice = value - - def read_and_convert_slice(self) -> StreamSlice: - next_slice = next(self._stream_slices) - if not isinstance(next_slice, StreamSlice): - raise ValueError( - f"{self.current_slice} should be of type StreamSlice. This is likely a bug in the CDK, please contact Airbyte support" - ) - return next_slice - - -class LegacyCursorBasedCheckpointReader(CursorBasedCheckpointReader): - """ - This (unfortunate) class operates like an adapter to retain backwards compatibility with legacy sources that take in stream_slice - in the form of a Mapping instead of the StreamSlice object. Internally, the reader still operates over StreamSlices, but it - is instantiated with and emits stream slices in the form of a Mapping[str, Any]. The logic of how partitions and cursors - are iterated over is synonymous with CursorBasedCheckpointReader. - - We also retain the existing top level fields defined by the connector so the fields are present on dependent methods. For example, - the resulting mapping structure passed back to the stream's read_records() method looks like: - { - "cursor_slice": { - "next_page_token": 10 - }, - "partition": { - "repository": "airbytehq/airbyte" - }, - "next_page_token": 10, - "repository": "airbytehq/airbyte" - } - """ - - def __init__(self, cursor: Cursor, stream_slices: Iterable[Optional[Mapping[str, Any]]], read_state_from_cursor: bool = False): - super().__init__(cursor=cursor, stream_slices=stream_slices, read_state_from_cursor=read_state_from_cursor) - - def next(self) -> Optional[Mapping[str, Any]]: - try: - self.current_slice = self._find_next_slice() - - if "partition" in dict(self.current_slice): - raise ValueError("Stream is configured to use invalid stream slice key 'partition'") - elif "cursor_slice" in dict(self.current_slice): - raise ValueError("Stream is configured to use invalid stream slice key 'cursor_slice'") - - # We convert StreamSlice to a regular mapping because legacy connectors operate on the basic Mapping object. We - # also duplicate all fields at the top level for backwards compatibility for existing Python sources - return { - "partition": self.current_slice.partition, - "cursor_slice": self.current_slice.cursor_slice, - **dict(self.current_slice), - } - except StopIteration: - self._finished_sync = True - return None - - def read_and_convert_slice(self) -> StreamSlice: - next_mapping_slice = next(self._stream_slices) - if not isinstance(next_mapping_slice, Mapping): - raise ValueError( - f"{self.current_slice} should be of type Mapping. This is likely a bug in the CDK, please contact Airbyte support" - ) - - # The legacy reader is instantiated with an iterable of stream slice mappings. We convert each into a StreamSlice - # to sanely process them during the sync and to reuse the existing Python defined cursors - return StreamSlice( - partition=next_mapping_slice, - cursor_slice={}, - ) - - -class ResumableFullRefreshCheckpointReader(CheckpointReader): - """ - ResumableFullRefreshCheckpointReader allows for iteration over an unbounded set of records based on the pagination strategy - of the stream. Because the number of pages is unknown, the stream's current state is used to determine whether to continue - fetching more pages or stopping the sync. - """ - - def __init__(self, stream_state: Mapping[str, Any]): - # The first attempt of an RFR stream has an empty {} incoming state, but should still make a first attempt to read records - # from the first page in next(). - self._first_page = bool(stream_state == {}) - self._state: Mapping[str, Any] = stream_state - - def next(self) -> Optional[Mapping[str, Any]]: - if self._first_page: - self._first_page = False - return self._state - elif self._state == FULL_REFRESH_COMPLETE_STATE: - return None - else: - return self._state - - def observe(self, new_state: Mapping[str, Any]) -> None: - self._state = new_state - - def get_checkpoint(self) -> Optional[Mapping[str, Any]]: - return self._state or {} - - -class FullRefreshCheckpointReader(CheckpointReader): - """ - FullRefreshCheckpointReader iterates over data that cannot be checkpointed incrementally during the sync because the stream - is not capable of managing state. At the end of a sync, a final state message is emitted to signal completion. - """ - - def __init__(self, stream_slices: Iterable[Optional[Mapping[str, Any]]]): - self._stream_slices = iter(stream_slices) - self._final_checkpoint = False - - def next(self) -> Optional[Mapping[str, Any]]: - try: - return next(self._stream_slices) - except StopIteration: - self._final_checkpoint = True - return None - - def observe(self, new_state: Mapping[str, Any]) -> None: - pass - - def get_checkpoint(self) -> Optional[Mapping[str, Any]]: - if self._final_checkpoint: - return {"__ab_no_cursor_state_message": True} - return None diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/cursor.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/cursor.py deleted file mode 100644 index 6d758bf4edb8..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/cursor.py +++ /dev/null @@ -1,77 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import ABC, abstractmethod -from typing import Any, Optional - -from airbyte_cdk.sources.types import Record, StreamSlice, StreamState - - -class Cursor(ABC): - """ - Cursors are components that allow for checkpointing the current state of a sync. They keep track of what data has been consumed - and allows for syncs to be resumed from a specific point based on that information. - """ - - @abstractmethod - def set_initial_state(self, stream_state: StreamState) -> None: - """ - Cursors are not initialized with their state. As state is needed in order to function properly, this method should be called - before calling anything else - - :param stream_state: The state of the stream as returned by get_stream_state - """ - - def observe(self, stream_slice: StreamSlice, record: Record) -> None: - """ - Register a record with the cursor; the cursor instance can then use it to manage the state of the in-progress stream read. - - :param stream_slice: The current slice, which may or may not contain the most recently observed record - :param record: the most recently-read record, which the cursor can use to update the stream state. Outwardly-visible changes to the - stream state may need to be deferred depending on whether the source reliably orders records by the cursor field. - """ - pass - - @abstractmethod - def close_slice(self, stream_slice: StreamSlice, *args: Any) -> None: - """ - Update state based on the stream slice. Note that `stream_slice.cursor_slice` and `most_recent_record.associated_slice` are expected - to be the same but we make it explicit here that `stream_slice` should be leveraged to update the state. We do not pass in the - latest record, since cursor instances should maintain the relevant internal state on their own. - - :param stream_slice: slice to close - """ - - @abstractmethod - def get_stream_state(self) -> StreamState: - """ - Returns the current stream state. We would like to restrict it's usage since it does expose internal of state. As of 2023-06-14, it - is used for two things: - * Interpolation of the requests - * Transformation of records - * Saving the state - - For the first case, we are probably stuck with exposing the stream state. For the second, we can probably expose a method that - allows for emitting the state to the platform. - """ - - @abstractmethod - def should_be_synced(self, record: Record) -> bool: - """ - Evaluating if a record should be synced allows for filtering and stop condition on pagination - """ - - @abstractmethod - def is_greater_than_or_equal(self, first: Record, second: Record) -> bool: - """ - Evaluating which record is greater in terms of cursor. This is used to avoid having to capture all the records to close a slice - """ - - @abstractmethod - def select_state(self, stream_slice: Optional[StreamSlice] = None) -> Optional[StreamState]: - """ - Get the state value of a specific stream_slice. For incremental or resumable full refresh cursors which only manage state in - a single dimension this is the entire state object. For per-partition cursors used by substreams, this returns the state of - a specific parent delineated by the incoming slice's partition object. - """ diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/per_partition_key_serializer.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/per_partition_key_serializer.py deleted file mode 100644 index e0dee4a92b89..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/per_partition_key_serializer.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -import json -from typing import Any, Mapping - - -class PerPartitionKeySerializer: - """ - We are concerned of the performance of looping through the `states` list and evaluating equality on the partition. To reduce this - concern, we wanted to use dictionaries to map `partition -> cursor`. However, partitions are dict and dict can't be used as dict keys - since they are not hashable. By creating json string using the dict, we can have a use the dict as a key to the dict since strings are - hashable. - """ - - @staticmethod - def to_partition_key(to_serialize: Any) -> str: - # separators have changed in Python 3.4. To avoid being impacted by further change, we explicitly specify our own value - return json.dumps(to_serialize, indent=None, separators=(",", ":"), sort_keys=True) - - @staticmethod - def to_partition(to_deserialize: Any) -> Mapping[str, Any]: - return json.loads(to_deserialize) # type: ignore # The partition is known to be a dict, but the type hint is Any diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/resumable_full_refresh_cursor.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/resumable_full_refresh_cursor.py deleted file mode 100644 index 86abd253f137..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/resumable_full_refresh_cursor.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from dataclasses import dataclass -from typing import Any, Optional - -from airbyte_cdk.sources.streams.checkpoint import Cursor -from airbyte_cdk.sources.types import Record, StreamSlice, StreamState - - -@dataclass -class ResumableFullRefreshCursor(Cursor): - """ - Cursor that allows for the checkpointing of sync progress according to a synthetic cursor based on the pagination state - of the stream. Resumable full refresh syncs are only intended to retain state in between sync attempts of the same job - with the platform responsible for removing said state. - """ - - def __init__(self) -> None: - self._cursor: StreamState = {} - - def get_stream_state(self) -> StreamState: - return self._cursor - - def set_initial_state(self, stream_state: StreamState) -> None: - self._cursor = stream_state - - def observe(self, stream_slice: StreamSlice, record: Record) -> None: - """ - Resumable full refresh manages state using a page number so it does not need to update state by observing incoming records. - """ - pass - - def close_slice(self, stream_slice: StreamSlice, *args: Any) -> None: - self._cursor = stream_slice.cursor_slice - - def should_be_synced(self, record: Record) -> bool: - """ - Unlike date-based cursors which filter out records outside slice boundaries, resumable full refresh records exist within pages - that don't have filterable bounds. We should always return them. - """ - return True - - def is_greater_than_or_equal(self, first: Record, second: Record) -> bool: - """ - RFR record don't have ordering to be compared between one another. - """ - return False - - def select_state(self, stream_slice: Optional[StreamSlice] = None) -> Optional[StreamState]: - # A top-level RFR cursor only manages the state of a single partition - return self._cursor diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/substream_resumable_full_refresh_cursor.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/substream_resumable_full_refresh_cursor.py deleted file mode 100644 index 8ebadcafbd19..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/checkpoint/substream_resumable_full_refresh_cursor.py +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from dataclasses import dataclass -from typing import Any, Mapping, MutableMapping, Optional - -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.streams.checkpoint import Cursor -from airbyte_cdk.sources.streams.checkpoint.per_partition_key_serializer import PerPartitionKeySerializer -from airbyte_cdk.sources.types import Record, StreamSlice, StreamState -from airbyte_cdk.utils import AirbyteTracedException - -FULL_REFRESH_COMPLETE_STATE: Mapping[str, Any] = {"__ab_full_refresh_sync_complete": True} - - -@dataclass -class SubstreamResumableFullRefreshCursor(Cursor): - def __init__(self) -> None: - self._per_partition_state: MutableMapping[str, StreamState] = {} - self._partition_serializer = PerPartitionKeySerializer() - - def get_stream_state(self) -> StreamState: - return {"states": list(self._per_partition_state.values())} - - def set_initial_state(self, stream_state: StreamState) -> None: - """ - Set the initial state for the cursors. - - This method initializes the state for each partition cursor using the provided stream state. - If a partition state is provided in the stream state, it will update the corresponding partition cursor with this state. - - To simplify processing and state management, we do not maintain the checkpointed state of the parent partitions. - Instead, we are tracking whether a parent has already successfully synced on a prior attempt and skipping over it - allowing the sync to continue making progress. And this works for RFR because the platform will dispose of this - state on the next sync job. - - Args: - stream_state (StreamState): The state of the streams to be set. The format of the stream state should be: - { - "states": [ - { - "partition": { - "partition_key": "value_0" - }, - "cursor": { - "__ab_full_refresh_sync_complete": True - } - }, - { - "partition": { - "partition_key": "value_1" - }, - "cursor": {}, - }, - ] - } - """ - if not stream_state: - return - - if "states" not in stream_state: - raise AirbyteTracedException( - internal_message=f"Could not sync parse the following state: {stream_state}", - message="The state for is format invalid. Validate that the migration steps included a reset and that it was performed " - "properly. Otherwise, please contact Airbyte support.", - failure_type=FailureType.config_error, - ) - - for state in stream_state["states"]: - self._per_partition_state[self._to_partition_key(state["partition"])] = state - - def observe(self, stream_slice: StreamSlice, record: Record) -> None: - """ - Substream resumable full refresh manages state by closing the slice after syncing a parent so observe is not used. - """ - pass - - def close_slice(self, stream_slice: StreamSlice, *args: Any) -> None: - self._per_partition_state[self._to_partition_key(stream_slice.partition)] = { - "partition": stream_slice.partition, - "cursor": FULL_REFRESH_COMPLETE_STATE, - } - - def should_be_synced(self, record: Record) -> bool: - """ - Unlike date-based cursors which filter out records outside slice boundaries, resumable full refresh records exist within pages - that don't have filterable bounds. We should always return them. - """ - return True - - def is_greater_than_or_equal(self, first: Record, second: Record) -> bool: - """ - RFR record don't have ordering to be compared between one another. - """ - return False - - def select_state(self, stream_slice: Optional[StreamSlice] = None) -> Optional[StreamState]: - if not stream_slice: - raise ValueError("A partition needs to be provided in order to extract a state") - - return self._per_partition_state.get(self._to_partition_key(stream_slice.partition), {}).get("cursor") - - def _to_partition_key(self, partition: Mapping[str, Any]) -> str: - return self._partition_serializer.to_partition_key(partition) - - def _to_dict(self, partition_key: str) -> Mapping[str, Any]: - return self._partition_serializer.to_partition(partition_key) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/README.md b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/README.md deleted file mode 100644 index 6970c3acd05f..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/README.md +++ /dev/null @@ -1,7 +0,0 @@ -## Breaking Changes & Limitations - -- [bigger scope than Concurrent CDK] checkpointing state was acting on the number of records per slice. This has been changed to consider the number of records per syncs -- `Source.read_state` and `Source._emit_legacy_state_format` are now classmethods to allow for developers to have access to the state before instantiating the source -- send_per_stream_state is always True for Concurrent CDK -- Using stream_state during read_records: The concern is that today, stream_instance.get_updated_state is called on every record and read_records on every slice. The implication is that the argument stream_state passed to read_records will have the value after the last stream_instance.get_updated_state of the previous slice. For Concurrent CDK, this is not possible as slices are processed in an unordered way. -- Cursor fields can only be data-time formatted as epoch. Eventually, we want to move to ISO 8601 as it provides more flexibility but for the first iteration on Stripe, it was easier to use the same format that was already used diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/abstract_stream.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/abstract_stream.py deleted file mode 100644 index da99ae10bd83..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/abstract_stream.py +++ /dev/null @@ -1,92 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import ABC, abstractmethod -from typing import Any, Iterable, Mapping, Optional - -from airbyte_cdk.models import AirbyteStream -from airbyte_cdk.sources.source import ExperimentalClassWarning -from airbyte_cdk.sources.streams.concurrent.availability_strategy import StreamAvailability -from airbyte_cdk.sources.streams.concurrent.cursor import Cursor -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from deprecated.classic import deprecated - - -@deprecated("This class is experimental. Use at your own risk.", category=ExperimentalClassWarning) -class AbstractStream(ABC): - """ - AbstractStream is an experimental interface for streams developed as part of the Concurrent CDK. - This interface is not yet stable and may change in the future. Use at your own risk. - - Why create a new interface instead of adding concurrency capabilities the existing Stream? - We learnt a lot since the initial design of the Stream interface, and we wanted to take the opportunity to improve. - - High level, the changes we are targeting are: - - Removing superfluous or leaky parameters from the methods' interfaces - - Using composition instead of inheritance to add new capabilities - - To allow us to iterate fast while ensuring backwards compatibility, we are creating a new interface with a facade object that will bridge the old and the new interfaces. - Source connectors that wish to leverage concurrency need to implement this new interface. An example will be available shortly - - Current restrictions on sources that implement this interface. Not all of these restrictions will be lifted in the future, but most will as we iterate on the design. - - Only full refresh is supported. This will be addressed in the future. - - The read method does not accept a cursor_field. Streams must be internally aware of the cursor field to use. User-defined cursor fields can be implemented by modifying the connector's main method to instantiate the streams with the configured cursor field. - - Streams cannot return user-friendly messages by overriding Stream.get_error_display_message. This will be addressed in the future. - - The Stream's behavior cannot depend on a namespace - - TypeTransformer is not supported. This will be addressed in the future. - - Nested cursor and primary keys are not supported - """ - - @abstractmethod - def generate_partitions(self) -> Iterable[Partition]: - """ - Generates the partitions that will be read by this stream. - :return: An iterable of partitions. - """ - - @property - @abstractmethod - def name(self) -> str: - """ - :return: The stream name - """ - - @property - @abstractmethod - def cursor_field(self) -> Optional[str]: - """ - Override to return the default cursor field used by this stream e.g: an API entity might always use created_at as the cursor field. - :return: The name of the field used as a cursor. Nested cursor fields are not supported. - """ - - @abstractmethod - def check_availability(self) -> StreamAvailability: - """ - :return: The stream's availability - """ - - @abstractmethod - def get_json_schema(self) -> Mapping[str, Any]: - """ - :return: A dict of the JSON schema representing this stream. - """ - - @abstractmethod - def as_airbyte_stream(self) -> AirbyteStream: - """ - :return: A dict of the JSON schema representing this stream. - """ - - @abstractmethod - def log_stream_sync_configuration(self) -> None: - """ - Logs the stream's configuration for debugging purposes. - """ - - @property - @abstractmethod - def cursor(self) -> Cursor: - """ - :return: The cursor associated with this stream. - """ diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/abstract_stream_facade.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/abstract_stream_facade.py deleted file mode 100644 index 18cacbc500d5..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/abstract_stream_facade.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -from abc import ABC, abstractmethod -from typing import Generic, Optional, TypeVar - -from airbyte_cdk.sources.streams.concurrent.exceptions import ExceptionWithDisplayMessage - -StreamType = TypeVar("StreamType") - - -class AbstractStreamFacade(Generic[StreamType], ABC): - @abstractmethod - def get_underlying_stream(self) -> StreamType: - """ - Return the underlying stream facade object. - """ - ... - - @property - def source_defined_cursor(self) -> bool: - # Streams must be aware of their cursor at instantiation time - return True - - def get_error_display_message(self, exception: BaseException) -> Optional[str]: - """ - Retrieves the user-friendly display message that corresponds to an exception. - This will be called when encountering an exception while reading records from the stream, and used to build the AirbyteTraceMessage. - - A display message will be returned if the exception is an instance of ExceptionWithDisplayMessage. - - :param exception: The exception that was raised - :return: A user-friendly message that indicates the cause of the error - """ - if isinstance(exception, ExceptionWithDisplayMessage): - return exception.display_message - else: - return None diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/adapters.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/adapters.py deleted file mode 100644 index df1ec1b62aff..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/adapters.py +++ /dev/null @@ -1,406 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import copy -import json -import logging -from functools import lru_cache -from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Tuple, Union - -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, AirbyteStream, ConfiguredAirbyteStream, Level, SyncMode, Type -from airbyte_cdk.sources import AbstractSource, Source -from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager -from airbyte_cdk.sources.message import MessageRepository -from airbyte_cdk.sources.source import ExperimentalClassWarning -from airbyte_cdk.sources.streams import Stream -from airbyte_cdk.sources.streams.availability_strategy import AvailabilityStrategy -from airbyte_cdk.sources.streams.concurrent.abstract_stream_facade import AbstractStreamFacade -from airbyte_cdk.sources.streams.concurrent.availability_strategy import AbstractAvailabilityStrategy, AlwaysAvailableAvailabilityStrategy -from airbyte_cdk.sources.streams.concurrent.cursor import Cursor, FinalStateCursor -from airbyte_cdk.sources.streams.concurrent.default_stream import DefaultStream -from airbyte_cdk.sources.streams.concurrent.exceptions import ExceptionWithDisplayMessage -from airbyte_cdk.sources.streams.concurrent.helpers import get_cursor_field_from_stream, get_primary_key_from_stream -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.partition_generator import PartitionGenerator -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record -from airbyte_cdk.sources.streams.core import StreamData -from airbyte_cdk.sources.types import StreamSlice -from airbyte_cdk.sources.utils.schema_helpers import InternalConfig -from airbyte_cdk.sources.utils.slice_logger import SliceLogger -from deprecated.classic import deprecated - -""" -This module contains adapters to help enabling concurrency on Stream objects without needing to migrate to AbstractStream -""" - - -@deprecated("This class is experimental. Use at your own risk.", category=ExperimentalClassWarning) -class StreamFacade(AbstractStreamFacade[DefaultStream], Stream): - """ - The StreamFacade is a Stream that wraps an AbstractStream and exposes it as a Stream. - - All methods either delegate to the wrapped AbstractStream or provide a default implementation. - The default implementations define restrictions imposed on Streams migrated to the new interface. For instance, only source-defined cursors are supported. - """ - - @classmethod - def create_from_stream( - cls, - stream: Stream, - source: AbstractSource, - logger: logging.Logger, - state: Optional[MutableMapping[str, Any]], - cursor: Cursor, - ) -> Stream: - """ - Create a ConcurrentStream from a Stream object. - :param source: The source - :param stream: The stream - :param max_workers: The maximum number of worker thread to use - :return: - """ - pk = get_primary_key_from_stream(stream.primary_key) - cursor_field = get_cursor_field_from_stream(stream) - - if not source.message_repository: - raise ValueError( - "A message repository is required to emit non-record messages. Please set the message repository on the source." - ) - - message_repository = source.message_repository - return StreamFacade( - DefaultStream( - partition_generator=StreamPartitionGenerator( - stream, - message_repository, - SyncMode.full_refresh if isinstance(cursor, FinalStateCursor) else SyncMode.incremental, - [cursor_field] if cursor_field is not None else None, - state, - cursor, - ), - name=stream.name, - namespace=stream.namespace, - json_schema=stream.get_json_schema(), - availability_strategy=AlwaysAvailableAvailabilityStrategy(), - primary_key=pk, - cursor_field=cursor_field, - logger=logger, - cursor=cursor, - ), - stream, - cursor, - slice_logger=source._slice_logger, - logger=logger, - ) - - @property - def state(self) -> MutableMapping[str, Any]: - raise NotImplementedError("This should not be called as part of the Concurrent CDK code. Please report the problem to Airbyte") - - @state.setter - def state(self, value: Mapping[str, Any]) -> None: - if "state" in dir(self._legacy_stream): - self._legacy_stream.state = value # type: ignore # validating `state` is attribute of stream using `if` above - - def __init__(self, stream: DefaultStream, legacy_stream: Stream, cursor: Cursor, slice_logger: SliceLogger, logger: logging.Logger): - """ - :param stream: The underlying AbstractStream - """ - self._abstract_stream = stream - self._legacy_stream = legacy_stream - self._cursor = cursor - self._slice_logger = slice_logger - self._logger = logger - - def read( - self, - configured_stream: ConfiguredAirbyteStream, - logger: logging.Logger, - slice_logger: SliceLogger, - stream_state: MutableMapping[str, Any], - state_manager: ConnectorStateManager, - internal_config: InternalConfig, - ) -> Iterable[StreamData]: - yield from self._read_records() - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: Optional[List[str]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - try: - yield from self._read_records() - except Exception as exc: - if hasattr(self._cursor, "state"): - state = str(self._cursor.state) - else: - # This shouldn't happen if the ConcurrentCursor was used - state = "unknown; no state attribute was available on the cursor" - yield AirbyteMessage( - type=Type.LOG, log=AirbyteLogMessage(level=Level.ERROR, message=f"Cursor State at time of exception: {state}") - ) - raise exc - - def _read_records(self) -> Iterable[StreamData]: - for partition in self._abstract_stream.generate_partitions(): - if self._slice_logger.should_log_slice_message(self._logger): - yield self._slice_logger.create_slice_log_message(partition.to_slice()) - for record in partition.read(): - yield record.data - - @property - def name(self) -> str: - return self._abstract_stream.name - - @property - def primary_key(self) -> Optional[Union[str, List[str], List[List[str]]]]: - # This method is not expected to be called directly. It is only implemented for backward compatibility with the old interface - return self.as_airbyte_stream().source_defined_primary_key # type: ignore # source_defined_primary_key is known to be an Optional[List[List[str]]] - - @property - def cursor_field(self) -> Union[str, List[str]]: - if self._abstract_stream.cursor_field is None: - return [] - else: - return self._abstract_stream.cursor_field - - @property - def cursor(self) -> Optional[Cursor]: # type: ignore[override] # StreamFaced expects to use only airbyte_cdk.sources.streams.concurrent.cursor.Cursor - return self._cursor - - @lru_cache(maxsize=None) - def get_json_schema(self) -> Mapping[str, Any]: - return self._abstract_stream.get_json_schema() - - @property - def supports_incremental(self) -> bool: - return self._legacy_stream.supports_incremental - - def check_availability(self, logger: logging.Logger, source: Optional["Source"] = None) -> Tuple[bool, Optional[str]]: - """ - Verifies the stream is available. Delegates to the underlying AbstractStream and ignores the parameters - :param logger: (ignored) - :param source: (ignored) - :return: - """ - availability = self._abstract_stream.check_availability() - return availability.is_available(), availability.message() - - def as_airbyte_stream(self) -> AirbyteStream: - return self._abstract_stream.as_airbyte_stream() - - def log_stream_sync_configuration(self) -> None: - self._abstract_stream.log_stream_sync_configuration() - - def get_underlying_stream(self) -> DefaultStream: - return self._abstract_stream - - -class SliceEncoder(json.JSONEncoder): - def default(self, obj: Any) -> Any: - if hasattr(obj, "__json_serializable__"): - return obj.__json_serializable__() - # Let the base class default method raise the TypeError - return super().default(obj) - - -class StreamPartition(Partition): - """ - This class acts as an adapter between the new Partition interface and the Stream's stream_slice interface - - StreamPartitions are instantiated from a Stream and a stream_slice. - - This class can be used to help enable concurrency on existing connectors without having to rewrite everything as AbstractStream. - In the long-run, it would be preferable to update the connectors, but we don't have the tooling or need to justify the effort at this time. - """ - - def __init__( - self, - stream: Stream, - _slice: Optional[Mapping[str, Any]], - message_repository: MessageRepository, - sync_mode: SyncMode, - cursor_field: Optional[List[str]], - state: Optional[MutableMapping[str, Any]], - cursor: Cursor, - ): - """ - :param stream: The stream to delegate to - :param _slice: The partition's stream_slice - :param message_repository: The message repository to use to emit non-record messages - """ - self._stream = stream - self._slice = _slice - self._message_repository = message_repository - self._sync_mode = sync_mode - self._cursor_field = cursor_field - self._state = state - self._cursor = cursor - self._is_closed = False - - def read(self) -> Iterable[Record]: - """ - Read messages from the stream. - If the StreamData is a Mapping, it will be converted to a Record. - Otherwise, the message will be emitted on the message repository. - """ - try: - # using `stream_state=self._state` have a very different behavior than the current one as today the state is updated slice - # by slice incrementally. We don't have this guarantee with Concurrent CDK. For HttpStream, `stream_state` is passed to: - # * fetch_next_page - # * parse_response - # Both are not used for Stripe so we should be good for the first iteration of Concurrent CDK. However, Stripe still do - # `if not stream_state` to know if it calls the Event stream or not - for record_data in self._stream.read_records( - cursor_field=self._cursor_field, - sync_mode=SyncMode.full_refresh, - stream_slice=copy.deepcopy(self._slice), - stream_state=self._state, - ): - if isinstance(record_data, Mapping): - data_to_return = dict(record_data) - self._stream.transformer.transform(data_to_return, self._stream.get_json_schema()) - yield Record(data_to_return, self) - else: - self._message_repository.emit_message(record_data) - except Exception as e: - display_message = self._stream.get_error_display_message(e) - if display_message: - raise ExceptionWithDisplayMessage(display_message) from e - else: - raise e - - def to_slice(self) -> Optional[Mapping[str, Any]]: - return self._slice - - def __hash__(self) -> int: - if self._slice: - # Convert the slice to a string so that it can be hashed - s = json.dumps(self._slice, sort_keys=True, cls=SliceEncoder) - return hash((self._stream.name, s)) - else: - return hash(self._stream.name) - - def stream_name(self) -> str: - return self._stream.name - - def close(self) -> None: - self._cursor.close_partition(self) - self._is_closed = True - - def is_closed(self) -> bool: - return self._is_closed - - def __repr__(self) -> str: - return f"StreamPartition({self._stream.name}, {self._slice})" - - -class StreamPartitionGenerator(PartitionGenerator): - """ - This class acts as an adapter between the new PartitionGenerator and Stream.stream_slices - - This class can be used to help enable concurrency on existing connectors without having to rewrite everything as AbstractStream. - In the long-run, it would be preferable to update the connectors, but we don't have the tooling or need to justify the effort at this time. - """ - - def __init__( - self, - stream: Stream, - message_repository: MessageRepository, - sync_mode: SyncMode, - cursor_field: Optional[List[str]], - state: Optional[MutableMapping[str, Any]], - cursor: Cursor, - ): - """ - :param stream: The stream to delegate to - :param message_repository: The message repository to use to emit non-record messages - """ - self.message_repository = message_repository - self._stream = stream - self._sync_mode = sync_mode - self._cursor_field = cursor_field - self._state = state - self._cursor = cursor - - def generate(self) -> Iterable[Partition]: - for s in self._stream.stream_slices(sync_mode=self._sync_mode, cursor_field=self._cursor_field, stream_state=self._state): - yield StreamPartition( - self._stream, copy.deepcopy(s), self.message_repository, self._sync_mode, self._cursor_field, self._state, self._cursor - ) - - -class CursorPartitionGenerator(PartitionGenerator): - """ - This class generates partitions using the concurrent cursor and iterates through state slices to generate partitions. - - It is used when synchronizing a stream in incremental or full-refresh mode where state information is maintained - across partitions. Each partition represents a subset of the stream's data and is determined by the cursor's state. - """ - - def __init__( - self, - stream: Stream, - message_repository: MessageRepository, - cursor: Cursor, - cursor_field: Optional[List[str]], - ): - """ - Initialize the CursorPartitionGenerator with a stream, sync mode, and cursor. - - :param stream: The stream to delegate to for partition generation. - :param message_repository: The message repository to use to emit non-record messages. - :param sync_mode: The synchronization mode. - :param cursor: A Cursor object that maintains the state and the cursor field. - """ - self._stream = stream - self.message_repository = message_repository - self._sync_mode = SyncMode.full_refresh - self._cursor = cursor - self._cursor_field = cursor_field - self._state = self._cursor.state - - def generate(self) -> Iterable[Partition]: - """ - Generate partitions based on the slices in the cursor's state. - - This method iterates through the list of slices found in the cursor's state, and for each slice, it generates - a `StreamPartition` object. - - :return: An iterable of StreamPartition objects. - """ - for slice_start, slice_end in self._cursor.generate_slices(): - stream_slice = StreamSlice(partition={}, cursor_slice={"start": slice_start, "end": slice_end}) - - yield StreamPartition( - self._stream, - copy.deepcopy(stream_slice), - self.message_repository, - self._sync_mode, - self._cursor_field, - self._state, - self._cursor, - ) - - -@deprecated("This class is experimental. Use at your own risk.", category=ExperimentalClassWarning) -class AvailabilityStrategyFacade(AvailabilityStrategy): - def __init__(self, abstract_availability_strategy: AbstractAvailabilityStrategy): - self._abstract_availability_strategy = abstract_availability_strategy - - def check_availability(self, stream: Stream, logger: logging.Logger, source: Optional["Source"] = None) -> Tuple[bool, Optional[str]]: - """ - Checks stream availability. - - Important to note that the stream and source parameters are not used by the underlying AbstractAvailabilityStrategy. - - :param stream: (unused) - :param logger: logger object to use - :param source: (unused) - :return: A tuple of (boolean, str). If boolean is true, then the stream - """ - stream_availability = self._abstract_availability_strategy.check_availability(logger) - return stream_availability.is_available(), stream_availability.message() diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/availability_strategy.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/availability_strategy.py deleted file mode 100644 index a97b70009001..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/availability_strategy.py +++ /dev/null @@ -1,86 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from abc import ABC, abstractmethod -from typing import Optional - -from airbyte_cdk.sources.source import ExperimentalClassWarning -from deprecated.classic import deprecated - - -class StreamAvailability(ABC): - @abstractmethod - def is_available(self) -> bool: - """ - :return: True if the stream is available. False if the stream is not - """ - - @abstractmethod - def message(self) -> Optional[str]: - """ - :return: A message describing why the stream is not available. If the stream is available, this should return None. - """ - - -class StreamAvailable(StreamAvailability): - def is_available(self) -> bool: - return True - - def message(self) -> Optional[str]: - return None - - -class StreamUnavailable(StreamAvailability): - def __init__(self, message: str): - self._message = message - - def is_available(self) -> bool: - return False - - def message(self) -> Optional[str]: - return self._message - - -# Singleton instances of StreamAvailability to avoid the overhead of creating new dummy objects -STREAM_AVAILABLE = StreamAvailable() - - -@deprecated("This class is experimental. Use at your own risk.", category=ExperimentalClassWarning) -class AbstractAvailabilityStrategy(ABC): - """ - AbstractAvailabilityStrategy is an experimental interface developed as part of the Concurrent CDK. - This interface is not yet stable and may change in the future. Use at your own risk. - - Why create a new interface instead of using the existing AvailabilityStrategy? - The existing AvailabilityStrategy is tightly coupled with Stream and Source, which yields to circular dependencies and makes it difficult to move away from the Stream interface to AbstractStream. - """ - - @abstractmethod - def check_availability(self, logger: logging.Logger) -> StreamAvailability: - """ - Checks stream availability. - - :param logger: logger object to use - :return: A StreamAvailability object describing the stream's availability - """ - - -class AlwaysAvailableAvailabilityStrategy(AbstractAvailabilityStrategy): - """ - An availability strategy that always indicates a stream is available. - - This strategy is used to avoid breaking changes and serves as a soft - deprecation of the availability strategy, allowing a smoother transition - without disrupting existing functionality. - """ - - def check_availability(self, logger: logging.Logger) -> StreamAvailability: - """ - Checks stream availability. - - :param logger: logger object to use - :return: A StreamAvailability object describing the stream's availability - """ - return StreamAvailable() diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/cursor.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/cursor.py deleted file mode 100644 index 523e8af7deaa..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/cursor.py +++ /dev/null @@ -1,336 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import functools -from abc import ABC, abstractmethod -from typing import Any, Callable, Iterable, List, Mapping, MutableMapping, Optional, Protocol, Tuple - -from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager -from airbyte_cdk.sources.message import MessageRepository -from airbyte_cdk.sources.streams import NO_CURSOR_STATE_KEY -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record -from airbyte_cdk.sources.streams.concurrent.state_converters.abstract_stream_state_converter import AbstractStreamStateConverter - - -def _extract_value(mapping: Mapping[str, Any], path: List[str]) -> Any: - return functools.reduce(lambda a, b: a[b], path, mapping) - - -class GapType(Protocol): - """ - This is the representation of gaps between two cursor values. Examples: - * if cursor values are datetimes, GapType is timedelta - * if cursor values are integer, GapType will also be integer - """ - - pass - - -class CursorValueType(Protocol): - """Protocol for annotating comparable types.""" - - @abstractmethod - def __lt__(self: "CursorValueType", other: "CursorValueType") -> bool: - pass - - @abstractmethod - def __ge__(self: "CursorValueType", other: "CursorValueType") -> bool: - pass - - @abstractmethod - def __add__(self: "CursorValueType", other: GapType) -> "CursorValueType": - pass - - @abstractmethod - def __sub__(self: "CursorValueType", other: GapType) -> "CursorValueType": - pass - - -class CursorField: - def __init__(self, cursor_field_key: str) -> None: - self.cursor_field_key = cursor_field_key - - def extract_value(self, record: Record) -> CursorValueType: - cursor_value = record.data.get(self.cursor_field_key) - if cursor_value is None: - raise ValueError(f"Could not find cursor field {self.cursor_field_key} in record") - return cursor_value # type: ignore # we assume that the value the path points at is a comparable - - -class Cursor(ABC): - @property - @abstractmethod - def state(self) -> MutableMapping[str, Any]: - ... - - @abstractmethod - def observe(self, record: Record) -> None: - """ - Indicate to the cursor that the record has been emitted - """ - raise NotImplementedError() - - @abstractmethod - def close_partition(self, partition: Partition) -> None: - """ - Indicate to the cursor that the partition has been successfully processed - """ - raise NotImplementedError() - - @abstractmethod - def ensure_at_least_one_state_emitted(self) -> None: - """ - State messages are emitted when a partition is closed. However, the platform expects at least one state to be emitted per sync per - stream. Hence, if no partitions are generated, this method needs to be called. - """ - raise NotImplementedError() - - def generate_slices(self) -> Iterable[Tuple[Any, Any]]: - """ - Default placeholder implementation of generate_slices. - Subclasses can override this method to provide actual behavior. - """ - yield from () - - -class FinalStateCursor(Cursor): - """Cursor that is used to guarantee at least one state message is emitted for a concurrent stream.""" - - def __init__( - self, - stream_name: str, - stream_namespace: Optional[str], - message_repository: MessageRepository, - ) -> None: - self._stream_name = stream_name - self._stream_namespace = stream_namespace - self._message_repository = message_repository - # Normally the connector state manager operates at the source-level. However, we only need it to write the sentinel - # state message rather than manage overall source state. This is also only temporary as we move to the resumable - # full refresh world where every stream uses a FileBasedConcurrentCursor with incremental state. - self._connector_state_manager = ConnectorStateManager() - self._has_closed_at_least_one_slice = False - - @property - def state(self) -> MutableMapping[str, Any]: - return {NO_CURSOR_STATE_KEY: True} - - def observe(self, record: Record) -> None: - pass - - def close_partition(self, partition: Partition) -> None: - pass - - def ensure_at_least_one_state_emitted(self) -> None: - """ - Used primarily for full refresh syncs that do not have a valid cursor value to emit at the end of a sync - """ - - self._connector_state_manager.update_state_for_stream(self._stream_name, self._stream_namespace, self.state) - state_message = self._connector_state_manager.create_state_message(self._stream_name, self._stream_namespace) - self._message_repository.emit_message(state_message) - - -class ConcurrentCursor(Cursor): - _START_BOUNDARY = 0 - _END_BOUNDARY = 1 - - def __init__( - self, - stream_name: str, - stream_namespace: Optional[str], - stream_state: Any, - message_repository: MessageRepository, - connector_state_manager: ConnectorStateManager, - connector_state_converter: AbstractStreamStateConverter, - cursor_field: CursorField, - slice_boundary_fields: Optional[Tuple[str, str]], - start: Optional[CursorValueType], - end_provider: Callable[[], CursorValueType], - lookback_window: Optional[GapType] = None, - slice_range: Optional[GapType] = None, - cursor_granularity: Optional[GapType] = None, - ) -> None: - self._stream_name = stream_name - self._stream_namespace = stream_namespace - self._message_repository = message_repository - self._connector_state_converter = connector_state_converter - self._connector_state_manager = connector_state_manager - self._cursor_field = cursor_field - # To see some example where the slice boundaries might not be defined, check https://github.com/airbytehq/airbyte/blob/1ce84d6396e446e1ac2377362446e3fb94509461/airbyte-integrations/connectors/source-stripe/source_stripe/streams.py#L363-L379 - self._slice_boundary_fields = slice_boundary_fields if slice_boundary_fields else tuple() - self._start = start - self._end_provider = end_provider - self.start, self._concurrent_state = self._get_concurrent_state(stream_state) - self._lookback_window = lookback_window - self._slice_range = slice_range - self._most_recent_cursor_value_per_partition: MutableMapping[Partition, Any] = {} - self._has_closed_at_least_one_slice = False - self._cursor_granularity = cursor_granularity - - @property - def state(self) -> MutableMapping[str, Any]: - return self._concurrent_state - - def _get_concurrent_state(self, state: MutableMapping[str, Any]) -> Tuple[CursorValueType, MutableMapping[str, Any]]: - if self._connector_state_converter.is_state_message_compatible(state): - return self._start or self._connector_state_converter.zero_value, self._connector_state_converter.deserialize(state) - return self._connector_state_converter.convert_from_sequential_state(self._cursor_field, state, self._start) - - def observe(self, record: Record) -> None: - most_recent_cursor_value = self._most_recent_cursor_value_per_partition.get(record.partition) - cursor_value = self._extract_cursor_value(record) - - if most_recent_cursor_value is None or most_recent_cursor_value < cursor_value: - self._most_recent_cursor_value_per_partition[record.partition] = cursor_value - - def _extract_cursor_value(self, record: Record) -> Any: - return self._connector_state_converter.parse_value(self._cursor_field.extract_value(record)) - - def close_partition(self, partition: Partition) -> None: - slice_count_before = len(self.state.get("slices", [])) - self._add_slice_to_state(partition) - if slice_count_before < len(self.state["slices"]): # only emit if at least one slice has been processed - self._merge_partitions() - self._emit_state_message() - self._has_closed_at_least_one_slice = True - - def _add_slice_to_state(self, partition: Partition) -> None: - most_recent_cursor_value = self._most_recent_cursor_value_per_partition.get(partition) - - if self._slice_boundary_fields: - if "slices" not in self.state: - raise RuntimeError( - f"The state for stream {self._stream_name} should have at least one slice to delineate the sync start time, but no slices are present. This is unexpected. Please contact Support." - ) - self.state["slices"].append( - { - self._connector_state_converter.START_KEY: self._extract_from_slice( - partition, self._slice_boundary_fields[self._START_BOUNDARY] - ), - self._connector_state_converter.END_KEY: self._extract_from_slice( - partition, self._slice_boundary_fields[self._END_BOUNDARY] - ), - "most_recent_cursor_value": most_recent_cursor_value, - } - ) - elif most_recent_cursor_value: - if self._has_closed_at_least_one_slice: - # If we track state value using records cursor field, we can only do that if there is one partition. This is because we save - # the state every time we close a partition. We assume that if there are multiple slices, they need to be providing - # boundaries. There are cases where partitions could not have boundaries: - # * The cursor should be per-partition - # * The stream state is actually the parent stream state - # There might be other cases not listed above. Those are not supported today hence the stream should not use this cursor for - # state management. For the specific user that was affected with this issue, we need to: - # * Fix state tracking (which is currently broken) - # * Make the new version available - # * (Probably) ask the user to reset the stream to avoid data loss - raise ValueError( - "Given that slice_boundary_fields is not defined and that per-partition state is not supported, only one slice is " - "expected. Please contact the Airbyte team." - ) - - self.state["slices"].append( - { - self._connector_state_converter.START_KEY: self.start, - self._connector_state_converter.END_KEY: most_recent_cursor_value, - "most_recent_cursor_value": most_recent_cursor_value, - } - ) - - def _emit_state_message(self) -> None: - self._connector_state_manager.update_state_for_stream( - self._stream_name, - self._stream_namespace, - self._connector_state_converter.convert_to_state_message(self._cursor_field, self.state), - ) - state_message = self._connector_state_manager.create_state_message(self._stream_name, self._stream_namespace) - self._message_repository.emit_message(state_message) - - def _merge_partitions(self) -> None: - self.state["slices"] = self._connector_state_converter.merge_intervals(self.state["slices"]) - - def _extract_from_slice(self, partition: Partition, key: str) -> CursorValueType: - try: - _slice = partition.to_slice() - if not _slice: - raise KeyError(f"Could not find key `{key}` in empty slice") - return self._connector_state_converter.parse_value(_slice[key]) # type: ignore # we expect the devs to specify a key that would return a CursorValueType - except KeyError as exception: - raise KeyError(f"Partition is expected to have key `{key}` but could not be found") from exception - - def ensure_at_least_one_state_emitted(self) -> None: - """ - The platform expect to have at least one state message on successful syncs. Hence, whatever happens, we expect this method to be - called. - """ - self._emit_state_message() - - def generate_slices(self) -> Iterable[Tuple[CursorValueType, CursorValueType]]: - """ - Generating slices based on a few parameters: - * lookback_window: Buffer to remove from END_KEY of the highest slice - * slice_range: Max difference between two slices. If the difference between two slices is greater, multiple slices will be created - * start: `_split_per_slice_range` will clip any value to `self._start which means that: - * if upper is less than self._start, no slices will be generated - * if lower is less than self._start, self._start will be used as the lower boundary (lookback_window will not be considered in that case) - - Note that the slices will overlap at their boundaries. We therefore expect to have at least the lower or the upper boundary to be - inclusive in the API that is queried. - """ - self._merge_partitions() - - if self._start is not None and self._is_start_before_first_slice(): - yield from self._split_per_slice_range(self._start, self.state["slices"][0][self._connector_state_converter.START_KEY]) - - if len(self.state["slices"]) == 1: - yield from self._split_per_slice_range( - self._calculate_lower_boundary_of_last_slice(self.state["slices"][0][self._connector_state_converter.END_KEY]), - self._end_provider(), - ) - elif len(self.state["slices"]) > 1: - for i in range(len(self.state["slices"]) - 1): - yield from self._split_per_slice_range( - self.state["slices"][i][self._connector_state_converter.END_KEY], - self.state["slices"][i + 1][self._connector_state_converter.START_KEY], - ) - yield from self._split_per_slice_range( - self._calculate_lower_boundary_of_last_slice(self.state["slices"][-1][self._connector_state_converter.END_KEY]), - self._end_provider(), - ) - else: - raise ValueError("Expected at least one slice") - - def _is_start_before_first_slice(self) -> bool: - return self._start is not None and self._start < self.state["slices"][0][self._connector_state_converter.START_KEY] - - def _calculate_lower_boundary_of_last_slice(self, lower_boundary: CursorValueType) -> CursorValueType: - if self._lookback_window: - return lower_boundary - self._lookback_window - return lower_boundary - - def _split_per_slice_range(self, lower: CursorValueType, upper: CursorValueType) -> Iterable[Tuple[CursorValueType, CursorValueType]]: - if lower >= upper: - return - - if self._start and upper < self._start: - return - - lower = max(lower, self._start) if self._start else lower - if not self._slice_range or lower + self._slice_range >= upper: - yield lower, upper - else: - stop_processing = False - current_lower_boundary = lower - while not stop_processing: - current_upper_boundary = min(current_lower_boundary + self._slice_range, upper) - if self._cursor_granularity: - yield current_lower_boundary, current_upper_boundary - self._cursor_granularity - else: - yield current_lower_boundary, current_upper_boundary - current_lower_boundary = current_upper_boundary - if current_upper_boundary >= upper: - stop_processing = True diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/default_stream.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/default_stream.py deleted file mode 100644 index 6cf4a694118e..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/default_stream.py +++ /dev/null @@ -1,90 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from functools import lru_cache -from logging import Logger -from typing import Any, Iterable, List, Mapping, Optional - -from airbyte_cdk.models import AirbyteStream, SyncMode -from airbyte_cdk.sources.streams.concurrent.abstract_stream import AbstractStream -from airbyte_cdk.sources.streams.concurrent.availability_strategy import AbstractAvailabilityStrategy, StreamAvailability -from airbyte_cdk.sources.streams.concurrent.cursor import Cursor -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.partition_generator import PartitionGenerator - - -class DefaultStream(AbstractStream): - def __init__( - self, - partition_generator: PartitionGenerator, - name: str, - json_schema: Mapping[str, Any], - availability_strategy: AbstractAvailabilityStrategy, - primary_key: List[str], - cursor_field: Optional[str], - logger: Logger, - cursor: Cursor, - namespace: Optional[str] = None, - ) -> None: - self._stream_partition_generator = partition_generator - self._name = name - self._json_schema = json_schema - self._availability_strategy = availability_strategy - self._primary_key = primary_key - self._cursor_field = cursor_field - self._logger = logger - self._cursor = cursor - self._namespace = namespace - - def generate_partitions(self) -> Iterable[Partition]: - yield from self._stream_partition_generator.generate() - - @property - def name(self) -> str: - return self._name - - @property - def namespace(self) -> Optional[str]: - return self._namespace - - def check_availability(self) -> StreamAvailability: - return self._availability_strategy.check_availability(self._logger) - - @property - def cursor_field(self) -> Optional[str]: - return self._cursor_field - - @lru_cache(maxsize=None) - def get_json_schema(self) -> Mapping[str, Any]: - return self._json_schema - - def as_airbyte_stream(self) -> AirbyteStream: - stream = AirbyteStream(name=self.name, json_schema=dict(self._json_schema), supported_sync_modes=[SyncMode.full_refresh]) - - if self._namespace: - stream.namespace = self._namespace - - if self._cursor_field: - stream.source_defined_cursor = True - stream.supported_sync_modes.append(SyncMode.incremental) - stream.default_cursor_field = [self._cursor_field] - - keys = self._primary_key - if keys and len(keys) > 0: - stream.source_defined_primary_key = [keys] - - return stream - - def log_stream_sync_configuration(self) -> None: - self._logger.debug( - f"Syncing stream instance: {self.name}", - extra={ - "primary_key": self._primary_key, - "cursor_field": self.cursor_field, - }, - ) - - @property - def cursor(self) -> Cursor: - return self._cursor diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/exceptions.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/exceptions.py deleted file mode 100644 index a0cf699a46d0..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/exceptions.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any - - -class ExceptionWithDisplayMessage(Exception): - """ - Exception that can be used to display a custom message to the user. - """ - - def __init__(self, display_message: str, **kwargs: Any): - super().__init__(**kwargs) - self.display_message = display_message - - def __str__(self) -> str: - return f'ExceptionWithDisplayMessage: "{self.display_message}"' diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/helpers.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/helpers.py deleted file mode 100644 index ad7722726498..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/helpers.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -from typing import List, Optional, Union - -from airbyte_cdk.sources.streams import Stream - - -def get_primary_key_from_stream(stream_primary_key: Optional[Union[str, List[str], List[List[str]]]]) -> List[str]: - if stream_primary_key is None: - return [] - elif isinstance(stream_primary_key, str): - return [stream_primary_key] - elif isinstance(stream_primary_key, list): - if len(stream_primary_key) > 0 and all(isinstance(k, str) for k in stream_primary_key): - return stream_primary_key # type: ignore # We verified all items in the list are strings - else: - raise ValueError(f"Nested primary keys are not supported. Found {stream_primary_key}") - else: - raise ValueError(f"Invalid type for primary key: {stream_primary_key}") - - -def get_cursor_field_from_stream(stream: Stream) -> Optional[str]: - if isinstance(stream.cursor_field, list): - if len(stream.cursor_field) > 1: - raise ValueError(f"Nested cursor fields are not supported. Got {stream.cursor_field} for {stream.name}") - elif len(stream.cursor_field) == 0: - return None - else: - return stream.cursor_field[0] - else: - return stream.cursor_field diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partition_enqueuer.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partition_enqueuer.py deleted file mode 100644 index 8e63c16a4b2c..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partition_enqueuer.py +++ /dev/null @@ -1,57 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import time -from queue import Queue - -from airbyte_cdk.sources.concurrent_source.partition_generation_completed_sentinel import PartitionGenerationCompletedSentinel -from airbyte_cdk.sources.concurrent_source.stream_thread_exception import StreamThreadException -from airbyte_cdk.sources.concurrent_source.thread_pool_manager import ThreadPoolManager -from airbyte_cdk.sources.streams.concurrent.abstract_stream import AbstractStream -from airbyte_cdk.sources.streams.concurrent.partitions.types import QueueItem - - -class PartitionEnqueuer: - """ - Generates partitions from a partition generator and puts them in a queue. - """ - - def __init__(self, queue: Queue[QueueItem], thread_pool_manager: ThreadPoolManager, sleep_time_in_seconds: float = 0.1) -> None: - """ - :param queue: The queue to put the partitions in. - :param throttler: The throttler to use to throttle the partition generation. - """ - self._queue = queue - self._thread_pool_manager = thread_pool_manager - self._sleep_time_in_seconds = sleep_time_in_seconds - - def generate_partitions(self, stream: AbstractStream) -> None: - """ - Generate partitions from a partition generator and put them in a queue. - When all the partitions are added to the queue, a sentinel is added to the queue to indicate that all the partitions have been generated. - - If an exception is encountered, the exception will be caught and put in the queue. This is very important because if we don't, the - main thread will have no way to know that something when wrong and will wait until the timeout is reached - - This method is meant to be called in a separate thread. - """ - try: - for partition in stream.generate_partitions(): - # Adding partitions to the queue generates futures. To avoid having too many futures, we throttle here. We understand that - # we might add more futures than the limit by throttling in the threads while it is the main thread that actual adds the - # future but we expect the delta between the max futures length and the actual to be small enough that it would not be an - # issue. We do this in the threads because we want the main thread to always be processing QueueItems as if it does not, the - # queue size could grow and generating OOM issues. - # - # Also note that we do not expect this to create deadlocks where all worker threads wait because we have less - # PartitionEnqueuer threads than worker threads. - # - # Also note that prune_to_validate_has_reached_futures_limit has a lock while pruning which might create a bottleneck in - # terms of performance. - while self._thread_pool_manager.prune_to_validate_has_reached_futures_limit(): - time.sleep(self._sleep_time_in_seconds) - self._queue.put(partition) - self._queue.put(PartitionGenerationCompletedSentinel(stream)) - except Exception as e: - self._queue.put(StreamThreadException(e, stream.name)) - self._queue.put(PartitionGenerationCompletedSentinel(stream)) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partition_reader.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partition_reader.py deleted file mode 100644 index eec69d569d8a..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partition_reader.py +++ /dev/null @@ -1,42 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -from queue import Queue - -from airbyte_cdk.sources.concurrent_source.stream_thread_exception import StreamThreadException -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.types import PartitionCompleteSentinel, QueueItem - - -class PartitionReader: - """ - Generates records from a partition and puts them in a queue. - """ - - _IS_SUCCESSFUL = True - - def __init__(self, queue: Queue[QueueItem]) -> None: - """ - :param queue: The queue to put the records in. - """ - self._queue = queue - - def process_partition(self, partition: Partition) -> None: - """ - Process a partition and put the records in the output queue. - When all the partitions are added to the queue, a sentinel is added to the queue to indicate that all the partitions have been generated. - - If an exception is encountered, the exception will be caught and put in the queue. This is very important because if we don't, the - main thread will have no way to know that something when wrong and will wait until the timeout is reached - - This method is meant to be called from a thread. - :param partition: The partition to read data from - :return: None - """ - try: - for record in partition.read(): - self._queue.put(record) - self._queue.put(PartitionCompleteSentinel(partition, self._IS_SUCCESSFUL)) - except Exception as e: - self._queue.put(StreamThreadException(e, partition.stream_name())) - self._queue.put(PartitionCompleteSentinel(partition, not self._IS_SUCCESSFUL)) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partitions/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partitions/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partitions/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partitions/partition.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partitions/partition.py deleted file mode 100644 index 09f83d8f85f2..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partitions/partition.py +++ /dev/null @@ -1,63 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import ABC, abstractmethod -from typing import Any, Iterable, Mapping, Optional - -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record - - -class Partition(ABC): - """ - A partition is responsible for reading a specific set of data from a source. - """ - - @abstractmethod - def read(self) -> Iterable[Record]: - """ - Reads the data from the partition. - :return: An iterable of records. - """ - pass - - @abstractmethod - def to_slice(self) -> Optional[Mapping[str, Any]]: - """ - Converts the partition to a slice that can be serialized and deserialized. - - Note: it would have been interesting to have a type of `Mapping[str, Comparable]` to simplify typing but some slices can have nested - values ([example](https://github.com/airbytehq/airbyte/blob/1ce84d6396e446e1ac2377362446e3fb94509461/airbyte-integrations/connectors/source-stripe/source_stripe/streams.py#L584-L596)) - :return: A mapping representing a slice - """ - pass - - @abstractmethod - def stream_name(self) -> str: - """ - Returns the name of the stream that this partition is reading from. - :return: The name of the stream. - """ - pass - - @abstractmethod - def close(self) -> None: - """ - Closes the partition. - """ - pass - - @abstractmethod - def is_closed(self) -> bool: - """ - Returns whether the partition is closed. - :return: - """ - pass - - @abstractmethod - def __hash__(self) -> int: - """ - Returns a hash of the partition. - Partitions must be hashable so that they can be used as keys in a dictionary. - """ diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partitions/partition_generator.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partitions/partition_generator.py deleted file mode 100644 index eff978564772..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partitions/partition_generator.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import ABC, abstractmethod -from typing import Iterable - -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition - - -class PartitionGenerator(ABC): - @abstractmethod - def generate(self) -> Iterable[Partition]: - """ - Generates partitions for a given sync mode. - :return: An iterable of partitions - """ - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partitions/record.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partitions/record.py deleted file mode 100644 index 05cd70c3b378..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partitions/record.py +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import TYPE_CHECKING, Any, Mapping - -if TYPE_CHECKING: - from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition - - -class Record: - """ - Represents a record read from a stream. - """ - - def __init__(self, data: Mapping[str, Any], partition: "Partition"): - self.data = data - self.partition = partition - - def __eq__(self, other: Any) -> bool: - if not isinstance(other, Record): - return False - return self.data == other.data and self.partition.stream_name() == other.partition.stream_name() - - def __repr__(self) -> str: - return f"Record(data={self.data}, stream_name={self.partition.stream_name()})" diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partitions/types.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partitions/types.py deleted file mode 100644 index c36d9d944cce..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/partitions/types.py +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Union - -from airbyte_cdk.sources.concurrent_source.partition_generation_completed_sentinel import PartitionGenerationCompletedSentinel -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record - - -class PartitionCompleteSentinel: - """ - A sentinel object indicating all records for a partition were produced. - Includes a pointer to the partition that was processed. - """ - - def __init__(self, partition: Partition, is_successful: bool = True): - """ - :param partition: The partition that was processed - """ - self.partition = partition - self.is_successful = is_successful - - def __eq__(self, other: Any) -> bool: - if isinstance(other, PartitionCompleteSentinel): - return self.partition == other.partition - return False - - -""" -Typedef representing the items that can be added to the ThreadBasedConcurrentStream -""" -QueueItem = Union[Record, Partition, PartitionCompleteSentinel, PartitionGenerationCompletedSentinel, Exception] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/state_converters/abstract_stream_state_converter.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/state_converters/abstract_stream_state_converter.py deleted file mode 100644 index 6211f886c7cf..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/state_converters/abstract_stream_state_converter.py +++ /dev/null @@ -1,157 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import ABC, abstractmethod -from enum import Enum -from typing import TYPE_CHECKING, Any, List, MutableMapping, Optional, Tuple - -if TYPE_CHECKING: - from airbyte_cdk.sources.streams.concurrent.cursor import CursorField - - -class ConcurrencyCompatibleStateType(Enum): - date_range = "date-range" - - -class AbstractStreamStateConverter(ABC): - START_KEY = "start" - END_KEY = "end" - - @abstractmethod - def _from_state_message(self, value: Any) -> Any: - pass - - @abstractmethod - def _to_state_message(self, value: Any) -> Any: - pass - - def __init__(self, is_sequential_state: bool = True): - self._is_sequential_state = is_sequential_state - - def convert_to_state_message(self, cursor_field: "CursorField", stream_state: MutableMapping[str, Any]) -> MutableMapping[str, Any]: - """ - Convert the state message from the concurrency-compatible format to the stream's original format. - - e.g. - { "created": "2021-01-18T21:18:20.000Z" } - """ - if self.is_state_message_compatible(stream_state) and self._is_sequential_state: - legacy_state = stream_state.get("legacy", {}) - latest_complete_time = self._get_latest_complete_time(stream_state.get("slices", [])) - if latest_complete_time is not None: - legacy_state.update({cursor_field.cursor_field_key: self._to_state_message(latest_complete_time)}) - return legacy_state or {} - else: - return self.serialize(stream_state, ConcurrencyCompatibleStateType.date_range) - - def _get_latest_complete_time(self, slices: List[MutableMapping[str, Any]]) -> Any: - """ - Get the latest time before which all records have been processed. - """ - if not slices: - raise RuntimeError("Expected at least one slice but there were none. This is unexpected; please contact Support.") - merged_intervals = self.merge_intervals(slices) - first_interval = merged_intervals[0] - - return first_interval.get("most_recent_cursor_value") or first_interval[self.START_KEY] - - def deserialize(self, state: MutableMapping[str, Any]) -> MutableMapping[str, Any]: - """ - Perform any transformations needed for compatibility with the converter. - """ - for stream_slice in state.get("slices", []): - stream_slice[self.START_KEY] = self._from_state_message(stream_slice[self.START_KEY]) - stream_slice[self.END_KEY] = self._from_state_message(stream_slice[self.END_KEY]) - return state - - def serialize(self, state: MutableMapping[str, Any], state_type: ConcurrencyCompatibleStateType) -> MutableMapping[str, Any]: - """ - Perform any transformations needed for compatibility with the converter. - """ - serialized_slices = [] - for stream_slice in state.get("slices", []): - serialized_slices.append( - { - self.START_KEY: self._to_state_message(stream_slice[self.START_KEY]), - self.END_KEY: self._to_state_message(stream_slice[self.END_KEY]), - } - ) - return {"slices": serialized_slices, "state_type": state_type.value} - - @staticmethod - def is_state_message_compatible(state: MutableMapping[str, Any]) -> bool: - return bool(state) and state.get("state_type") in [t.value for t in ConcurrencyCompatibleStateType] - - @abstractmethod - def convert_from_sequential_state( - self, - cursor_field: "CursorField", # to deprecate as it is only needed for sequential state - stream_state: MutableMapping[str, Any], - start: Optional[Any], - ) -> Tuple[Any, MutableMapping[str, Any]]: - """ - Convert the state message to the format required by the ConcurrentCursor. - - e.g. - { - "state_type": ConcurrencyCompatibleStateType.date_range.value, - "metadata": { … }, - "slices": [ - {starts: 0, end: 1617030403, finished_processing: true}] - } - """ - ... - - @abstractmethod - def increment(self, value: Any) -> Any: - """ - Increment a timestamp by a single unit. - """ - ... - - def merge_intervals(self, intervals: List[MutableMapping[str, Any]]) -> List[MutableMapping[str, Any]]: - """ - Compute and return a list of merged intervals. - - Intervals may be merged if the start time of the second interval is 1 unit or less (as defined by the - `increment` method) than the end time of the first interval. - """ - if not intervals: - return [] - - sorted_intervals = sorted(intervals, key=lambda interval: (interval[self.START_KEY], interval[self.END_KEY])) - merged_intervals = [sorted_intervals[0]] - - for current_interval in sorted_intervals[1:]: - last_interval = merged_intervals[-1] - last_interval_end = last_interval[self.END_KEY] - current_interval_start = current_interval[self.START_KEY] - - if self.increment(last_interval_end) >= current_interval_start: - last_interval[self.END_KEY] = max(last_interval_end, current_interval[self.END_KEY]) - last_interval_cursor_value = last_interval.get("most_recent_cursor_value") - current_interval_cursor_value = current_interval.get("most_recent_cursor_value") - - last_interval["most_recent_cursor_value"] = ( - max(current_interval_cursor_value, last_interval_cursor_value) - if current_interval_cursor_value and last_interval_cursor_value - else current_interval_cursor_value or last_interval_cursor_value - ) - else: - # Add a new interval if no overlap - merged_intervals.append(current_interval) - - return merged_intervals - - @abstractmethod - def parse_value(self, value: Any) -> Any: - """ - Parse the value of the cursor field into a comparable value. - """ - ... - - @property - @abstractmethod - def zero_value(self) -> Any: - ... diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/state_converters/datetime_stream_state_converter.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/state_converters/datetime_stream_state_converter.py deleted file mode 100644 index 6e50d6b2bcf7..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/state_converters/datetime_stream_state_converter.py +++ /dev/null @@ -1,159 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import abstractmethod -from datetime import datetime, timedelta, timezone -from typing import Any, Callable, MutableMapping, Optional, Tuple - -import pendulum -from airbyte_cdk.sources.streams.concurrent.cursor import CursorField -from airbyte_cdk.sources.streams.concurrent.state_converters.abstract_stream_state_converter import ( - AbstractStreamStateConverter, - ConcurrencyCompatibleStateType, -) -from pendulum.datetime import DateTime - - -class DateTimeStreamStateConverter(AbstractStreamStateConverter): - def _from_state_message(self, value: Any) -> Any: - return self.parse_timestamp(value) - - def _to_state_message(self, value: Any) -> Any: - return self.output_format(value) - - @property - @abstractmethod - def _zero_value(self) -> Any: - ... - - @property - def zero_value(self) -> datetime: - return self.parse_timestamp(self._zero_value) - - @classmethod - def get_end_provider(cls) -> Callable[[], datetime]: - return lambda: datetime.now(timezone.utc) - - @abstractmethod - def increment(self, timestamp: datetime) -> datetime: - ... - - @abstractmethod - def parse_timestamp(self, timestamp: Any) -> datetime: - ... - - @abstractmethod - def output_format(self, timestamp: datetime) -> Any: - ... - - def parse_value(self, value: Any) -> Any: - """ - Parse the value of the cursor field into a comparable value. - """ - return self.parse_timestamp(value) - - def _compare_intervals(self, end_time: Any, start_time: Any) -> bool: - return bool(self.increment(end_time) >= start_time) - - def convert_from_sequential_state( - self, cursor_field: CursorField, stream_state: MutableMapping[str, Any], start: Optional[datetime] - ) -> Tuple[datetime, MutableMapping[str, Any]]: - """ - Convert the state message to the format required by the ConcurrentCursor. - - e.g. - { - "state_type": ConcurrencyCompatibleStateType.date_range.value, - "metadata": { … }, - "slices": [ - {"start": "2021-01-18T21:18:20.000+00:00", "end": "2021-01-18T21:18:20.000+00:00"}, - ] - } - """ - sync_start = self._get_sync_start(cursor_field, stream_state, start) - if self.is_state_message_compatible(stream_state): - return sync_start, stream_state - - # Create a slice to represent the records synced during prior syncs. - # The start and end are the same to avoid confusion as to whether the records for this slice - # were actually synced - slices = [{self.START_KEY: start if start is not None else sync_start, self.END_KEY: sync_start}] - - return sync_start, { - "state_type": ConcurrencyCompatibleStateType.date_range.value, - "slices": slices, - "legacy": stream_state, - } - - def _get_sync_start(self, cursor_field: CursorField, stream_state: MutableMapping[str, Any], start: Optional[datetime]) -> datetime: - sync_start = start if start is not None else self.zero_value - prev_sync_low_water_mark = ( - self.parse_timestamp(stream_state[cursor_field.cursor_field_key]) if cursor_field.cursor_field_key in stream_state else None - ) - if prev_sync_low_water_mark and prev_sync_low_water_mark >= sync_start: - return prev_sync_low_water_mark - else: - return sync_start - - -class EpochValueConcurrentStreamStateConverter(DateTimeStreamStateConverter): - """ - e.g. - { "created": 1617030403 } - => - { - "state_type": "date-range", - "metadata": { … }, - "slices": [ - {starts: 0, end: 1617030403, finished_processing: true} - ] - } - """ - - _zero_value = 0 - - def increment(self, timestamp: datetime) -> datetime: - return timestamp + timedelta(seconds=1) - - def output_format(self, timestamp: datetime) -> int: - return int(timestamp.timestamp()) - - def parse_timestamp(self, timestamp: int) -> datetime: - dt_object = pendulum.from_timestamp(timestamp) - if not isinstance(dt_object, DateTime): - raise ValueError(f"DateTime object was expected but got {type(dt_object)} from pendulum.parse({timestamp})") - return dt_object # type: ignore # we are manually type checking because pendulum.parse may return different types - - -class IsoMillisConcurrentStreamStateConverter(DateTimeStreamStateConverter): - """ - e.g. - { "created": "2021-01-18T21:18:20.000Z" } - => - { - "state_type": "date-range", - "metadata": { … }, - "slices": [ - {starts: "2020-01-18T21:18:20.000Z", end: "2021-01-18T21:18:20.000Z", finished_processing: true} - ] - } - """ - - _zero_value = "0001-01-01T00:00:00.000Z" - - def __init__(self, is_sequential_state: bool = True, cursor_granularity: Optional[timedelta] = None): - super().__init__(is_sequential_state=is_sequential_state) - self._cursor_granularity = cursor_granularity or timedelta(milliseconds=1) - - def increment(self, timestamp: datetime) -> datetime: - return timestamp + self._cursor_granularity - - def output_format(self, timestamp: datetime) -> Any: - return timestamp.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z" - - def parse_timestamp(self, timestamp: str) -> datetime: - dt_object = pendulum.parse(timestamp) - if not isinstance(dt_object, DateTime): - raise ValueError(f"DateTime object was expected but got {type(dt_object)} from pendulum.parse({timestamp})") - return dt_object # type: ignore # we are manually type checking because pendulum.parse may return different types diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/core.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/core.py deleted file mode 100644 index c7a0cf02ec5a..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/core.py +++ /dev/null @@ -1,644 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import copy -import inspect -import itertools -import logging -from abc import ABC, abstractmethod -from dataclasses import dataclass -from functools import cached_property, lru_cache -from typing import Any, Dict, Iterable, Iterator, List, Mapping, MutableMapping, Optional, Union - -import airbyte_cdk.sources.utils.casing as casing -from airbyte_cdk.models import AirbyteMessage, AirbyteStream, ConfiguredAirbyteStream, DestinationSyncMode, SyncMode -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.streams.checkpoint import ( - CheckpointMode, - CheckpointReader, - Cursor, - CursorBasedCheckpointReader, - FullRefreshCheckpointReader, - IncrementalCheckpointReader, - LegacyCursorBasedCheckpointReader, - ResumableFullRefreshCheckpointReader, -) -from airbyte_cdk.sources.types import StreamSlice - -# list of all possible HTTP methods which can be used for sending of request bodies -from airbyte_cdk.sources.utils.schema_helpers import InternalConfig, ResourceSchemaLoader -from airbyte_cdk.sources.utils.slice_logger import DebugSliceLogger, SliceLogger -from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer -from deprecated import deprecated - -# A stream's read method can return one of the following types: -# Mapping[str, Any]: The content of an AirbyteRecordMessage -# AirbyteMessage: An AirbyteMessage. Could be of any type -StreamData = Union[Mapping[str, Any], AirbyteMessage] - -JsonSchema = Mapping[str, Any] - -NO_CURSOR_STATE_KEY = "__ab_no_cursor_state_message" - - -def package_name_from_class(cls: object) -> str: - """Find the package name given a class name""" - module = inspect.getmodule(cls) - if module is not None: - return module.__name__.split(".")[0] - else: - raise ValueError(f"Could not find package name for class {cls}") - - -class CheckpointMixin(ABC): - """Mixin for a stream that implements reading and writing the internal state used to checkpoint sync progress to the platform - - class CheckpointedStream(Stream, CheckpointMixin): - @property - def state(self): - return self._state - - @state.setter - def state(self, value): - self._state[self.cursor_field] = value[self.cursor_field] - """ - - @property - @abstractmethod - def state(self) -> MutableMapping[str, Any]: - """State getter, should return state in form that can serialized to a string and send to the output - as a STATE AirbyteMessage. - - A good example of a state is a cursor_value: - { - self.cursor_field: "cursor_value" - } - - State should try to be as small as possible but at the same time descriptive enough to restore - syncing process from the point where it stopped. - """ - - @state.setter - @abstractmethod - def state(self, value: MutableMapping[str, Any]) -> None: - """State setter, accept state serialized by state getter.""" - - -@deprecated(version="0.87.0", reason="Deprecated in favor of the CheckpointMixin which offers similar functionality") -class IncrementalMixin(CheckpointMixin, ABC): - """Mixin to make stream incremental. - - class IncrementalStream(Stream, IncrementalMixin): - @property - def state(self): - return self._state - - @state.setter - def state(self, value): - self._state[self.cursor_field] = value[self.cursor_field] - """ - - -@dataclass -class StreamClassification: - is_legacy_format: bool - has_multiple_slices: bool - - -# Moved to class declaration since get_updated_state is called on every record for incremental syncs, and thus the @deprecated decorator as well. -@deprecated( - version="0.1.49", - reason="Deprecated method get_updated_state, You should use explicit state property instead, see IncrementalMixin docs.", - action="ignore", -) -class Stream(ABC): - """ - Base abstract class for an Airbyte Stream. Makes no assumption of the Stream's underlying transport protocol. - """ - - _configured_json_schema: Optional[Dict[str, Any]] = None - _exit_on_rate_limit: bool = False - - # Use self.logger in subclasses to log any messages - @property - def logger(self) -> logging.Logger: - return logging.getLogger(f"airbyte.streams.{self.name}") - - # TypeTransformer object to perform output data transformation - transformer: TypeTransformer = TypeTransformer(TransformConfig.NoTransform) - - cursor: Optional[Cursor] = None - - has_multiple_slices = False - - @cached_property - def name(self) -> str: - """ - :return: Stream name. By default this is the implementing class name, but it can be overridden as needed. - """ - return casing.camel_to_snake(self.__class__.__name__) - - def get_error_display_message(self, exception: BaseException) -> Optional[str]: - """ - Retrieves the user-friendly display message that corresponds to an exception. - This will be called when encountering an exception while reading records from the stream, and used to build the AirbyteTraceMessage. - - The default implementation of this method does not return user-friendly messages for any exception type, but it should be overriden as needed. - - :param exception: The exception that was raised - :return: A user-friendly message that indicates the cause of the error - """ - return None - - def read( # type: ignore # ignoring typing for ConnectorStateManager because of circular dependencies - self, - configured_stream: ConfiguredAirbyteStream, - logger: logging.Logger, - slice_logger: SliceLogger, - stream_state: MutableMapping[str, Any], - state_manager, - internal_config: InternalConfig, - ) -> Iterable[StreamData]: - sync_mode = configured_stream.sync_mode - cursor_field = configured_stream.cursor_field - self.configured_json_schema = configured_stream.stream.json_schema - - # WARNING: When performing a read() that uses incoming stream state, we MUST use the self.state that is defined as - # opposed to the incoming stream_state value. Because some connectors like ones using the file-based CDK modify - # state before setting the value on the Stream attribute, the most up-to-date state is derived from Stream.state - # instead of the stream_state parameter. This does not apply to legacy connectors using get_updated_state(). - try: - stream_state = self.state # type: ignore # we know the field might not exist... - except AttributeError: - pass - - should_checkpoint = bool(state_manager) - checkpoint_reader = self._get_checkpoint_reader( - logger=logger, cursor_field=cursor_field, sync_mode=sync_mode, stream_state=stream_state - ) - - next_slice = checkpoint_reader.next() - record_counter = 0 - stream_state_tracker = copy.deepcopy(stream_state) - while next_slice is not None: - if slice_logger.should_log_slice_message(logger): - yield slice_logger.create_slice_log_message(next_slice) - records = self.read_records( - sync_mode=sync_mode, # todo: change this interface to no longer rely on sync_mode for behavior - stream_slice=next_slice, - stream_state=stream_state, - cursor_field=cursor_field or None, - ) - for record_data_or_message in records: - yield record_data_or_message - if isinstance(record_data_or_message, Mapping) or ( - hasattr(record_data_or_message, "type") and record_data_or_message.type == MessageType.RECORD - ): - record_data = record_data_or_message if isinstance(record_data_or_message, Mapping) else record_data_or_message.record - - # Thanks I hate it. RFR fundamentally doesn't fit with the concept of the legacy Stream.get_updated_state() - # method because RFR streams rely on pagination as a cursor. Stream.get_updated_state() was designed to make - # the CDK manage state using specifically the last seen record. don't @ brian.lai - # - # Also, because the legacy incremental state case decouples observing incoming records from emitting state, it - # requires that we separate CheckpointReader.observe() and CheckpointReader.get_checkpoint() which could - # otherwise be combined. - if self.cursor_field: - # Some connectors have streams that implement get_updated_state(), but do not define a cursor_field. This - # should be fixed on the stream implementation, but we should also protect against this in the CDK as well - stream_state_tracker = self.get_updated_state(stream_state_tracker, record_data) - self._observe_state(checkpoint_reader, stream_state_tracker) - record_counter += 1 - - checkpoint_interval = self.state_checkpoint_interval - checkpoint = checkpoint_reader.get_checkpoint() - if should_checkpoint and checkpoint_interval and record_counter % checkpoint_interval == 0 and checkpoint is not None: - airbyte_state_message = self._checkpoint_state(checkpoint, state_manager=state_manager) - yield airbyte_state_message - - if internal_config.is_limit_reached(record_counter): - break - self._observe_state(checkpoint_reader) - checkpoint_state = checkpoint_reader.get_checkpoint() - if should_checkpoint and checkpoint_state is not None: - airbyte_state_message = self._checkpoint_state(checkpoint_state, state_manager=state_manager) - yield airbyte_state_message - - next_slice = checkpoint_reader.next() - - checkpoint = checkpoint_reader.get_checkpoint() - if should_checkpoint and checkpoint is not None: - airbyte_state_message = self._checkpoint_state(checkpoint, state_manager=state_manager) - yield airbyte_state_message - - def read_only_records(self, state: Optional[Mapping[str, Any]] = None) -> Iterable[StreamData]: - """ - Helper method that performs a read on a stream with an optional state and emits records. If the parent stream supports - incremental, this operation does not update the stream's internal state (if it uses the modern state setter/getter) - or emit state messages. - """ - - configured_stream = ConfiguredAirbyteStream( - stream=AirbyteStream( - name=self.name, - json_schema={}, - supported_sync_modes=[SyncMode.full_refresh, SyncMode.incremental], - ), - sync_mode=SyncMode.incremental if state else SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.append, - ) - - yield from self.read( - configured_stream=configured_stream, - logger=self.logger, - slice_logger=DebugSliceLogger(), - stream_state=dict(state) if state else {}, # read() expects MutableMapping instead of Mapping which is used more often - state_manager=None, - internal_config=InternalConfig(), - ) - - @abstractmethod - def read_records( - self, - sync_mode: SyncMode, - cursor_field: Optional[List[str]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - """ - This method should be overridden by subclasses to read records based on the inputs - """ - - @lru_cache(maxsize=None) - def get_json_schema(self) -> Mapping[str, Any]: - """ - :return: A dict of the JSON schema representing this stream. - - The default implementation of this method looks for a JSONSchema file with the same name as this stream's "name" property. - Override as needed. - """ - # TODO show an example of using pydantic to define the JSON schema, or reading an OpenAPI spec - return ResourceSchemaLoader(package_name_from_class(self.__class__)).get_schema(self.name) - - def as_airbyte_stream(self) -> AirbyteStream: - stream = AirbyteStream( - name=self.name, - json_schema=dict(self.get_json_schema()), - supported_sync_modes=[SyncMode.full_refresh], - is_resumable=self.is_resumable, - ) - - if self.namespace: - stream.namespace = self.namespace - - # If we can offer incremental we always should. RFR is always less reliable than incremental which uses a real cursor value - if self.supports_incremental: - stream.source_defined_cursor = self.source_defined_cursor - stream.supported_sync_modes.append(SyncMode.incremental) # type: ignore - stream.default_cursor_field = self._wrapped_cursor_field() - - keys = Stream._wrapped_primary_key(self.primary_key) - if keys and len(keys) > 0: - stream.source_defined_primary_key = keys - - return stream - - @property - def supports_incremental(self) -> bool: - """ - :return: True if this stream supports incrementally reading data - """ - return len(self._wrapped_cursor_field()) > 0 - - @property - def is_resumable(self) -> bool: - """ - :return: True if this stream allows the checkpointing of sync progress and can resume from it on subsequent attempts. - This differs from supports_incremental because certain kinds of streams like those supporting resumable full refresh - can checkpoint progress in between attempts for improved fault tolerance. However, they will start from the beginning - on the next sync job. - """ - if self.supports_incremental: - return True - if self.has_multiple_slices: - # We temporarily gate substream to not support RFR because puts a pretty high burden on connector developers - # to structure stream state in a very specific way. We also can't check for issubclass(HttpSubStream) because - # not all substreams implement the interface and it would be a circular dependency so we use parent as a surrogate - return False - elif hasattr(type(self), "state") and getattr(type(self), "state").fset is not None: - # Modern case where a stream manages state using getter/setter - return True - else: - # Legacy case where the CDK manages state via the get_updated_state() method. This is determined by checking if - # the stream's get_updated_state() differs from the Stream class and therefore has been overridden - return type(self).get_updated_state != Stream.get_updated_state - - def _wrapped_cursor_field(self) -> List[str]: - return [self.cursor_field] if isinstance(self.cursor_field, str) else self.cursor_field - - @property - def cursor_field(self) -> Union[str, List[str]]: - """ - Override to return the default cursor field used by this stream e.g: an API entity might always use created_at as the cursor field. - :return: The name of the field used as a cursor. If the cursor is nested, return an array consisting of the path to the cursor. - """ - return [] - - @property - def namespace(self) -> Optional[str]: - """ - Override to return the namespace of this stream, e.g. the Postgres schema which this stream will emit records for. - :return: A string containing the name of the namespace. - """ - return None - - @property - def source_defined_cursor(self) -> bool: - """ - Return False if the cursor can be configured by the user. - """ - return True - - @property - def exit_on_rate_limit(self) -> bool: - """Exit on rate limit getter, should return bool value. False if the stream will retry endlessly when rate limited.""" - return self._exit_on_rate_limit - - @exit_on_rate_limit.setter - def exit_on_rate_limit(self, value: bool) -> None: - """Exit on rate limit setter, accept bool value.""" - self._exit_on_rate_limit = value - - @property - @abstractmethod - def primary_key(self) -> Optional[Union[str, List[str], List[List[str]]]]: - """ - :return: string if single primary key, list of strings if composite primary key, list of list of strings if composite primary key consisting of nested fields. - If the stream has no primary keys, return None. - """ - - def stream_slices( - self, *, sync_mode: SyncMode, cursor_field: Optional[List[str]] = None, stream_state: Optional[Mapping[str, Any]] = None - ) -> Iterable[Optional[Mapping[str, Any]]]: - """ - Override to define the slices for this stream. See the stream slicing section of the docs for more information. - - :param sync_mode: - :param cursor_field: - :param stream_state: - :return: - """ - yield StreamSlice(partition={}, cursor_slice={}) - - @property - def state_checkpoint_interval(self) -> Optional[int]: - """ - Decides how often to checkpoint state (i.e: emit a STATE message). E.g: if this returns a value of 100, then state is persisted after reading - 100 records, then 200, 300, etc.. A good default value is 1000 although your mileage may vary depending on the underlying data source. - - Checkpointing a stream avoids re-reading records in the case a sync is failed or cancelled. - - return None if state should not be checkpointed e.g: because records returned from the underlying data source are not returned in - ascending order with respect to the cursor field. This can happen if the source does not support reading records in ascending order of - created_at date (or whatever the cursor is). In those cases, state must only be saved once the full stream has been read. - """ - return None - - def get_updated_state( - self, current_stream_state: MutableMapping[str, Any], latest_record: Mapping[str, Any] - ) -> MutableMapping[str, Any]: - """Override to extract state from the latest record. Needed to implement incremental sync. - - Inspects the latest record extracted from the data source and the current state object and return an updated state object. - - For example: if the state object is based on created_at timestamp, and the current state is {'created_at': 10}, and the latest_record is - {'name': 'octavia', 'created_at': 20 } then this method would return {'created_at': 20} to indicate state should be updated to this object. - - :param current_stream_state: The stream's current state object - :param latest_record: The latest record extracted from the stream - :return: An updated state object - """ - return {} - - def get_cursor(self) -> Optional[Cursor]: - """ - A Cursor is an interface that a stream can implement to manage how its internal state is read and updated while - reading records. Historically, Python connectors had no concept of a cursor to manage state. Python streams need - to define a cursor implementation and override this method to manage state through a Cursor. - """ - return self.cursor - - def _get_checkpoint_reader( - self, - logger: logging.Logger, - cursor_field: Optional[List[str]], - sync_mode: SyncMode, - stream_state: MutableMapping[str, Any], - ) -> CheckpointReader: - mappings_or_slices = self.stream_slices( - cursor_field=cursor_field, - sync_mode=sync_mode, # todo: change this interface to no longer rely on sync_mode for behavior - stream_state=stream_state, - ) - - # Because of poor foresight, we wrote the default Stream.stream_slices() method to return [None] which is confusing and - # has now normalized this behavior for connector developers. Now some connectors return [None]. This is objectively - # misleading and a more ideal interface is [{}] to indicate we still want to iterate over one slice, but with no - # specific slice values. None is bad, and now I feel bad that I have to write this hack. - if mappings_or_slices == [None]: - mappings_or_slices = [{}] - - slices_iterable_copy, iterable_for_detecting_format = itertools.tee(mappings_or_slices, 2) - stream_classification = self._classify_stream(mappings_or_slices=iterable_for_detecting_format) - - # Streams that override has_multiple_slices are explicitly indicating that they will iterate over - # multiple partitions. Inspecting slices to automatically apply the correct cursor is only needed as - # a backup. So if this value was already assigned to True by the stream, we don't need to reassign it - self.has_multiple_slices = self.has_multiple_slices or stream_classification.has_multiple_slices - - cursor = self.get_cursor() - if cursor: - cursor.set_initial_state(stream_state=stream_state) - - checkpoint_mode = self._checkpoint_mode - - if cursor and stream_classification.is_legacy_format: - return LegacyCursorBasedCheckpointReader(stream_slices=slices_iterable_copy, cursor=cursor, read_state_from_cursor=True) - elif cursor: - return CursorBasedCheckpointReader( - stream_slices=slices_iterable_copy, - cursor=cursor, - read_state_from_cursor=checkpoint_mode == CheckpointMode.RESUMABLE_FULL_REFRESH, - ) - elif checkpoint_mode == CheckpointMode.RESUMABLE_FULL_REFRESH: - # Resumable full refresh readers rely on the stream state dynamically being updated during pagination and does - # not iterate over a static set of slices. - return ResumableFullRefreshCheckpointReader(stream_state=stream_state) - elif checkpoint_mode == CheckpointMode.INCREMENTAL: - return IncrementalCheckpointReader(stream_slices=slices_iterable_copy, stream_state=stream_state) - else: - return FullRefreshCheckpointReader(stream_slices=slices_iterable_copy) - - @property - def _checkpoint_mode(self) -> CheckpointMode: - if self.is_resumable and len(self._wrapped_cursor_field()) > 0: - return CheckpointMode.INCREMENTAL - elif self.is_resumable: - return CheckpointMode.RESUMABLE_FULL_REFRESH - else: - return CheckpointMode.FULL_REFRESH - - @staticmethod - def _classify_stream(mappings_or_slices: Iterator[Optional[Union[Mapping[str, Any], StreamSlice]]]) -> StreamClassification: - """ - This is a bit of a crazy solution, but also the only way we can detect certain attributes about the stream since Python - streams do not follow consistent implementation patterns. We care about the following two attributes: - - is_substream: Helps to incrementally release changes since substreams w/ parents are much more complicated. Also - helps de-risk the release of changes that might impact all connectors - - uses_legacy_slice_format: Since the checkpoint reader must manage a complex state object, we opted to have it always - use the structured StreamSlice object. However, this requires backwards compatibility with Python sources that only - support the legacy mapping object - - Both attributes can eventually be deprecated once stream's define this method deleted once substreams have been implemented and - legacy connectors all adhere to the StreamSlice object. - """ - if not mappings_or_slices: - raise ValueError("A stream should always have at least one slice") - try: - next_slice = next(mappings_or_slices) - if isinstance(next_slice, StreamSlice) and next_slice == StreamSlice(partition={}, cursor_slice={}): - is_legacy_format = False - slice_has_value = False - elif next_slice == {}: - is_legacy_format = True - slice_has_value = False - elif isinstance(next_slice, StreamSlice): - is_legacy_format = False - slice_has_value = True - else: - is_legacy_format = True - slice_has_value = True - except StopIteration: - # If the stream has no slices, the format ultimately does not matter since no data will get synced. This is technically - # a valid case because it is up to the stream to define its slicing behavior - return StreamClassification(is_legacy_format=False, has_multiple_slices=False) - - if slice_has_value: - # If the first slice contained a partition value from the result of stream_slices(), this is a substream that might - # have multiple parent records to iterate over - return StreamClassification(is_legacy_format=is_legacy_format, has_multiple_slices=slice_has_value) - - try: - # If stream_slices() returns multiple slices, this is also a substream that can potentially generate empty slices - next(mappings_or_slices) - return StreamClassification(is_legacy_format=is_legacy_format, has_multiple_slices=True) - except StopIteration: - # If the result of stream_slices() only returns a single empty stream slice, then we know this is a regular stream - return StreamClassification(is_legacy_format=is_legacy_format, has_multiple_slices=False) - - def log_stream_sync_configuration(self) -> None: - """ - Logs the configuration of this stream. - """ - self.logger.debug( - f"Syncing stream instance: {self.name}", - extra={ - "primary_key": self.primary_key, - "cursor_field": self.cursor_field, - }, - ) - - @staticmethod - def _wrapped_primary_key(keys: Optional[Union[str, List[str], List[List[str]]]]) -> Optional[List[List[str]]]: - """ - :return: wrap the primary_key property in a list of list of strings required by the Airbyte Stream object. - """ - if not keys: - return None - - if isinstance(keys, str): - return [[keys]] - elif isinstance(keys, list): - wrapped_keys = [] - for component in keys: - if isinstance(component, str): - wrapped_keys.append([component]) - elif isinstance(component, list): - wrapped_keys.append(component) - else: - raise ValueError(f"Element must be either list or str. Got: {type(component)}") - return wrapped_keys - else: - raise ValueError(f"Element must be either list or str. Got: {type(keys)}") - - def _observe_state(self, checkpoint_reader: CheckpointReader, stream_state: Optional[Mapping[str, Any]] = None) -> None: - """ - Convenience method that attempts to read the Stream's state using the recommended way of connector's managing their - own state via state setter/getter. But if we get back an AttributeError, then the legacy Stream.get_updated_state() - method is used as a fallback method. - """ - - # This is an inversion of the original logic that used to try state getter/setters first. As part of the work to - # automatically apply resumable full refresh to all streams, all HttpStream classes implement default state - # getter/setter methods, we should default to only using the incoming stream_state parameter value is {} which - # indicates the stream does not override the default get_updated_state() implementation. When the default method - # is not overridden, then the stream defers to self.state getter - if stream_state: - checkpoint_reader.observe(stream_state) - elif type(self).get_updated_state == Stream.get_updated_state: - # We only default to the state getter/setter if the stream does not use the legacy get_updated_state() method - try: - new_state = self.state # type: ignore # This will always exist on HttpStreams, but may not for Stream - if new_state: - checkpoint_reader.observe(new_state) - except AttributeError: - pass - - def _checkpoint_state( # type: ignore # ignoring typing for ConnectorStateManager because of circular dependencies - self, - stream_state: Mapping[str, Any], - state_manager, - ) -> AirbyteMessage: - # todo: This can be consolidated into one ConnectorStateManager.update_and_create_state_message() method, but I want - # to reduce changes right now and this would span concurrent as well - state_manager.update_state_for_stream(self.name, self.namespace, stream_state) - return state_manager.create_state_message(self.name, self.namespace) - - @property - def configured_json_schema(self) -> Optional[Dict[str, Any]]: - """ - This property is set from the read method. - - :return Optional[Dict]: JSON schema from configured catalog if provided, otherwise None. - """ - return self._configured_json_schema - - @configured_json_schema.setter - def configured_json_schema(self, json_schema: Dict[str, Any]) -> None: - self._configured_json_schema = self._filter_schema_invalid_properties(json_schema) - - def _filter_schema_invalid_properties(self, configured_catalog_json_schema: Dict[str, Any]) -> Dict[str, Any]: - """ - Filters the properties in json_schema that are not present in the stream schema. - Configured Schemas can have very old fields, so we need to housekeeping ourselves. - """ - configured_schema: Any = configured_catalog_json_schema.get("properties", {}) - stream_schema_properties: Any = self.get_json_schema().get("properties", {}) - - configured_keys = configured_schema.keys() - stream_keys = stream_schema_properties.keys() - invalid_properties = configured_keys - stream_keys - if not invalid_properties: - return configured_catalog_json_schema - - self.logger.warning( - f"Stream {self.name}: the following fields are deprecated and cannot be synced. {invalid_properties}. Refresh the connection's source schema to resolve this warning." - ) - - valid_configured_schema_properties_keys = stream_keys & configured_keys - valid_configured_schema_properties = {} - - for configured_schema_property in valid_configured_schema_properties_keys: - valid_configured_schema_properties[configured_schema_property] = stream_schema_properties[configured_schema_property] - - return {**configured_catalog_json_schema, "properties": valid_configured_schema_properties} diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/__init__.py deleted file mode 100644 index a876406b48b4..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -# Initialize Streams Package -from .http_client import HttpClient -from .http import HttpStream, HttpSubStream -from .exceptions import UserDefinedBackoffException - -__all__ = ["HttpClient", "HttpStream", "HttpSubStream", "UserDefinedBackoffException"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/availability_strategy.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/availability_strategy.py deleted file mode 100644 index 4b3dba106c6e..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/availability_strategy.py +++ /dev/null @@ -1,52 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -import typing -from typing import Optional, Tuple - -from airbyte_cdk.sources.streams import Stream -from airbyte_cdk.sources.streams.availability_strategy import AvailabilityStrategy -from airbyte_cdk.utils.traced_exception import AirbyteTracedException - -if typing.TYPE_CHECKING: - from airbyte_cdk.sources import Source - - -class HttpAvailabilityStrategy(AvailabilityStrategy): - def check_availability(self, stream: Stream, logger: logging.Logger, source: Optional["Source"] = None) -> Tuple[bool, Optional[str]]: - """ - Check stream availability by attempting to read the first record of the - stream. - - :param stream: stream - :param logger: source logger - :param source: (optional) source - :return: A tuple of (boolean, str). If boolean is true, then the stream - is available, and no str is required. Otherwise, the stream is unavailable - for some reason and the str should describe what went wrong and how to - resolve the unavailability, if possible. - """ - reason: Optional[str] - try: - # Some streams need a stream slice to read records (e.g. if they have a SubstreamPartitionRouter) - # Streams that don't need a stream slice will return `None` as their first stream slice. - stream_slice = self.get_first_stream_slice(stream) - except StopIteration: - # If stream_slices has no `next()` item (Note - this is different from stream_slices returning [None]!) - # This can happen when a substream's `stream_slices` method does a `for record in parent_records: yield ` - # without accounting for the case in which the parent stream is empty. - reason = f"Cannot attempt to connect to stream {stream.name} - no stream slices were found, likely because the parent stream is empty." - return False, reason - except AirbyteTracedException as error: - return False, error.message - - try: - self.get_first_record_for_slice(stream, stream_slice) - return True, None - except StopIteration: - logger.info(f"Successfully connected to stream {stream.name}, but got 0 records.") - return True, None - except AirbyteTracedException as error: - return False, error.message diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/__init__.py deleted file mode 100644 index 40abd4f944a4..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from .backoff_strategy import BackoffStrategy -from .default_backoff_strategy import DefaultBackoffStrategy -from .error_handler import ErrorHandler -from .error_message_parser import ErrorMessageParser -from .http_status_error_handler import HttpStatusErrorHandler -from .json_error_message_parser import JsonErrorMessageParser -from .response_models import ResponseAction, ErrorResolution - -__all__ = [ - "BackoffStrategy", - "DefaultBackoffStrategy", - "ErrorHandler", - "ErrorMessageParser", - "HttpStatusErrorHandler", - "JsonErrorMessageParser", - "ResponseAction", - "ErrorResolution" -] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/backoff_strategy.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/backoff_strategy.py deleted file mode 100644 index 6ed821791ca4..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/backoff_strategy.py +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import ABC, abstractmethod -from typing import Optional, Union - -import requests - - -class BackoffStrategy(ABC): - @abstractmethod - def backoff_time( - self, - response_or_exception: Optional[Union[requests.Response, requests.RequestException]], - attempt_count: int, - ) -> Optional[float]: - """ - Override this method to dynamically determine backoff time e.g: by reading the X-Retry-After header. - - This method is called only if should_backoff() returns True for the input request. - - :param response_or_exception: The response or exception that caused the backoff. - :param attempt_count: The number of attempts already performed for this request. - :return how long to backoff in seconds. The return value may be a floating point number for subsecond precision. Returning None defers backoff - to the default backoff behavior (e.g using an exponential algorithm). - """ - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/default_backoff_strategy.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/default_backoff_strategy.py deleted file mode 100644 index 2c3e10ad7a1a..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/default_backoff_strategy.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - - -from typing import Optional, Union - -import requests - -from .backoff_strategy import BackoffStrategy - - -class DefaultBackoffStrategy(BackoffStrategy): - def backoff_time( - self, - response_or_exception: Optional[Union[requests.Response, requests.RequestException]], - attempt_count: int, - ) -> Optional[float]: - return None diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/default_error_mapping.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/default_error_mapping.py deleted file mode 100644 index 546a910f57c5..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/default_error_mapping.py +++ /dev/null @@ -1,82 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from typing import Mapping, Type, Union - -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, ResponseAction -from requests.exceptions import InvalidSchema, InvalidURL, RequestException - -DEFAULT_ERROR_MAPPING: Mapping[Union[int, str, Type[Exception]], ErrorResolution] = { - InvalidSchema: ErrorResolution( - response_action=ResponseAction.FAIL, - failure_type=FailureType.config_error, - error_message="Invalid Protocol Schema: The endpoint that data is being requested from is using an invalid or insecure. Exception: requests.exceptions.InvalidSchema", - ), - InvalidURL: ErrorResolution( - response_action=ResponseAction.FAIL, - failure_type=FailureType.config_error, - error_message="Invalid URL specified: The endpoint that data is being requested from is not a valid URL. Exception: requests.exceptions.InvalidURL", - ), - RequestException: ErrorResolution( - response_action=ResponseAction.RETRY, - failure_type=FailureType.transient_error, - error_message="An exception occurred when making the request. Exception: requests.exceptions.RequestException", - ), - 400: ErrorResolution( - response_action=ResponseAction.FAIL, - failure_type=FailureType.system_error, - error_message="Bad request. Please check your request parameters.", - ), - 401: ErrorResolution( - response_action=ResponseAction.FAIL, - failure_type=FailureType.config_error, - error_message="Unauthorized. Please ensure you are authenticated correctly.", - ), - 403: ErrorResolution( - response_action=ResponseAction.FAIL, - failure_type=FailureType.config_error, - error_message="Forbidden. You don't have permission to access this resource.", - ), - 404: ErrorResolution( - response_action=ResponseAction.FAIL, - failure_type=FailureType.system_error, - error_message="Not found. The requested resource was not found on the server.", - ), - 405: ErrorResolution( - response_action=ResponseAction.FAIL, - failure_type=FailureType.system_error, - error_message="Method not allowed. Please check your request method.", - ), - 408: ErrorResolution( - response_action=ResponseAction.RETRY, - failure_type=FailureType.transient_error, - error_message="Request timeout.", - ), - 429: ErrorResolution( - response_action=ResponseAction.RATE_LIMITED, - failure_type=FailureType.transient_error, - error_message="Too many requests.", - ), - 500: ErrorResolution( - response_action=ResponseAction.RETRY, - failure_type=FailureType.transient_error, - error_message="Internal server error.", - ), - 502: ErrorResolution( - response_action=ResponseAction.RETRY, - failure_type=FailureType.transient_error, - error_message="Bad gateway.", - ), - 503: ErrorResolution( - response_action=ResponseAction.RETRY, - failure_type=FailureType.transient_error, - error_message="Service unavailable.", - ), - 504: ErrorResolution( - response_action=ResponseAction.RETRY, - failure_type=FailureType.transient_error, - error_message="Gateway timeout.", - ), -} diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/error_handler.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/error_handler.py deleted file mode 100644 index f1789cc6fb45..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/error_handler.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from abc import ABC, abstractmethod -from typing import Optional, Union - -import requests - -from .response_models import ErrorResolution - - -class ErrorHandler(ABC): - """ - Abstract base class to determine how to handle a failed HTTP request. - """ - - @property - @abstractmethod - def max_retries(self) -> Optional[int]: - """ - The maximum number of retries to attempt before giving up. - """ - pass - - @property - @abstractmethod - def max_time(self) -> Optional[int]: - """ - The maximum amount of time in seconds to retry before giving up. - """ - pass - - @abstractmethod - def interpret_response(self, response: Optional[Union[requests.Response, Exception]]) -> ErrorResolution: - """ - Interpret the response or exception and return the corresponding response action, failure type, and error message. - - :param response: The HTTP response object or exception raised during the request. - :return: A tuple containing the response action, failure type, and error message. - """ - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/error_message_parser.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/error_message_parser.py deleted file mode 100644 index 966fe93a12bd..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/error_message_parser.py +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import ABC, abstractmethod -from typing import Optional - -import requests - - -class ErrorMessageParser(ABC): - @abstractmethod - def parse_response_error_message(self, response: requests.Response) -> Optional[str]: - """ - Parse error message from response. - :param response: response received for the request - :return: error message - """ - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/http_status_error_handler.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/http_status_error_handler.py deleted file mode 100644 index 69adab30d1f6..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/http_status_error_handler.py +++ /dev/null @@ -1,98 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -import logging -from datetime import timedelta -from typing import Mapping, Optional, Union - -import requests -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.streams.http.error_handlers.default_error_mapping import DEFAULT_ERROR_MAPPING -from airbyte_cdk.sources.streams.http.error_handlers.error_handler import ErrorHandler -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, ResponseAction - - -class HttpStatusErrorHandler(ErrorHandler): - def __init__( - self, - logger: logging.Logger, - error_mapping: Optional[Mapping[Union[int, str, type[Exception]], ErrorResolution]] = None, - max_retries: int = 5, - max_time: timedelta = timedelta(seconds=600), - ) -> None: - """ - Initialize the HttpStatusErrorHandler. - - :param error_mapping: Custom error mappings to extend or override the default mappings. - """ - self._logger = logger - self._error_mapping = error_mapping or DEFAULT_ERROR_MAPPING - self._max_retries = max_retries - self._max_time = int(max_time.total_seconds()) - - @property - def max_retries(self) -> Optional[int]: - return self._max_retries - - @property - def max_time(self) -> Optional[int]: - return self._max_time - - def interpret_response(self, response_or_exception: Optional[Union[requests.Response, Exception]] = None) -> ErrorResolution: - """ - Interpret the response and return the corresponding response action, failure type, and error message. - - :param response: The HTTP response object. - :return: A tuple containing the response action, failure type, and error message. - """ - - if isinstance(response_or_exception, Exception): - mapped_error: Optional[ErrorResolution] = self._error_mapping.get(response_or_exception.__class__) - - if mapped_error is not None: - return mapped_error - else: - self._logger.error(f"Unexpected exception in error handler: {response_or_exception}") - return ErrorResolution( - response_action=ResponseAction.RETRY, - failure_type=FailureType.system_error, - error_message=f"Unexpected exception in error handler: {response_or_exception}", - ) - - elif isinstance(response_or_exception, requests.Response): - if response_or_exception.status_code is None: - self._logger.error("Response does not include an HTTP status code.") - return ErrorResolution( - response_action=ResponseAction.RETRY, - failure_type=FailureType.transient_error, - error_message="Response does not include an HTTP status code.", - ) - - if response_or_exception.ok: - return ErrorResolution( - response_action=ResponseAction.SUCCESS, - failure_type=None, - error_message=None, - ) - - error_key = response_or_exception.status_code - - mapped_error = self._error_mapping.get(error_key) - - if mapped_error is not None: - return mapped_error - else: - self._logger.warning(f"Unexpected HTTP Status Code in error handler: '{error_key}'") - return ErrorResolution( - response_action=ResponseAction.RETRY, - failure_type=FailureType.system_error, - error_message=f"Unexpected HTTP Status Code in error handler: {error_key}", - ) - else: - self._logger.error(f"Received unexpected response type: {type(response_or_exception)}") - return ErrorResolution( - response_action=ResponseAction.FAIL, - failure_type=FailureType.system_error, - error_message=f"Received unexpected response type: {type(response_or_exception)}", - ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/json_error_message_parser.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/json_error_message_parser.py deleted file mode 100644 index 3ca31ec57131..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/json_error_message_parser.py +++ /dev/null @@ -1,51 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Optional - -import requests -from airbyte_cdk.sources.streams.http.error_handlers import ErrorMessageParser -from airbyte_cdk.sources.utils.types import JsonType - - -class JsonErrorMessageParser(ErrorMessageParser): - def _try_get_error(self, value: Optional[JsonType]) -> Optional[str]: - if isinstance(value, str): - return value - elif isinstance(value, list): - errors_in_value = [self._try_get_error(v) for v in value] - return ", ".join(v for v in errors_in_value if v is not None) - elif isinstance(value, dict): - new_value = ( - value.get("message") - or value.get("messages") - or value.get("error") - or value.get("errors") - or value.get("failures") - or value.get("failure") - or value.get("detail") - or value.get("err") - or value.get("error_message") - or value.get("msg") - or value.get("reason") - or value.get("status_message") - ) - return self._try_get_error(new_value) - return None - - def parse_response_error_message(self, response: requests.Response) -> Optional[str]: - """ - Parses the raw response object from a failed request into a user-friendly error message. - - :param response: - :return: A user-friendly message that indicates the cause of the error - """ - try: - body = response.json() - return self._try_get_error(body) - except requests.exceptions.JSONDecodeError: - try: - return response.content.decode("utf-8") - except Exception: - return None diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/response_models.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/response_models.py deleted file mode 100644 index 21e20049a6c1..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/response_models.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from dataclasses import dataclass -from enum import Enum -from typing import Optional, Union - -import requests -from airbyte_cdk.models import FailureType -from airbyte_cdk.utils.airbyte_secrets_utils import filter_secrets -from requests import HTTPError - - -class ResponseAction(Enum): - SUCCESS = "SUCCESS" - RETRY = "RETRY" - FAIL = "FAIL" - IGNORE = "IGNORE" - RATE_LIMITED = "RATE_LIMITED" - - -@dataclass -class ErrorResolution: - response_action: Optional[ResponseAction] = None - failure_type: Optional[FailureType] = None - error_message: Optional[str] = None - - -def _format_exception_error_message(exception: Exception) -> str: - return f"{type(exception).__name__}: {str(exception)}" - - -def _format_response_error_message(response: requests.Response) -> str: - try: - response.raise_for_status() - except HTTPError as exception: - return filter_secrets(f"Response was not ok: `{str(exception)}`. Response content is: {response.text}") - # We purposefully do not add the response.content because the response is "ok" so there might be sensitive information in the payload. - # Feel free the - return f"Unexpected response with HTTP status {response.status_code}" - - -def create_fallback_error_resolution(response_or_exception: Optional[Union[requests.Response, Exception]]) -> ErrorResolution: - if response_or_exception is None: - # We do not expect this case to happen but if it does, it would be good to understand the cause and improve the error message - error_message = "Error handler did not receive a valid response or exception. This is unexpected please contact Airbyte Support" - elif isinstance(response_or_exception, Exception): - error_message = _format_exception_error_message(response_or_exception) - else: - error_message = _format_response_error_message(response_or_exception) - - return ErrorResolution( - response_action=ResponseAction.RETRY, - failure_type=FailureType.system_error, - error_message=error_message, - ) - - -SUCCESS_RESOLUTION = ErrorResolution(response_action=ResponseAction.SUCCESS, failure_type=None, error_message=None) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/exceptions.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/exceptions.py deleted file mode 100644 index efa44165f8c2..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/exceptions.py +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from typing import Optional, Union - -import requests - - -class BaseBackoffException(requests.exceptions.HTTPError): - def __init__( - self, - request: requests.PreparedRequest, - response: Optional[Union[requests.Response, Exception]], - error_message: str = "", - ): - - if isinstance(response, requests.Response): - error_message = ( - error_message or f"Request URL: {request.url}, Response Code: {response.status_code}, Response Text: {response.text}" - ) - super().__init__(error_message, request=request, response=response) - else: - error_message = error_message or f"Request URL: {request.url}, Exception: {response}" - super().__init__(error_message, request=request, response=None) - - -class RequestBodyException(Exception): - """ - Raised when there are issues in configuring a request body - """ - - -class UserDefinedBackoffException(BaseBackoffException): - """ - An exception that exposes how long it attempted to backoff - """ - - def __init__( - self, - backoff: Union[int, float], - request: requests.PreparedRequest, - response: Optional[Union[requests.Response, Exception]], - error_message: str = "", - ): - """ - :param backoff: how long to backoff in seconds - :param request: the request that triggered this backoff exception - :param response: the response that triggered the backoff exception - """ - self.backoff = backoff - super().__init__(request=request, response=response, error_message=error_message) - - -class DefaultBackoffException(BaseBackoffException): - pass - - -class RateLimitBackoffException(BaseBackoffException): - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/http.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/http.py deleted file mode 100644 index 6c552ddab5e6..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/http.py +++ /dev/null @@ -1,573 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from abc import ABC, abstractmethod -from datetime import timedelta -from typing import Any, Callable, Iterable, List, Mapping, MutableMapping, Optional, Tuple, Union -from urllib.parse import urljoin - -import requests -from airbyte_cdk.models import AirbyteMessage, FailureType, SyncMode -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.message.repository import InMemoryMessageRepository -from airbyte_cdk.sources.streams.call_rate import APIBudget -from airbyte_cdk.sources.streams.checkpoint.cursor import Cursor -from airbyte_cdk.sources.streams.checkpoint.resumable_full_refresh_cursor import ResumableFullRefreshCursor -from airbyte_cdk.sources.streams.checkpoint.substream_resumable_full_refresh_cursor import SubstreamResumableFullRefreshCursor -from airbyte_cdk.sources.streams.core import CheckpointMixin, Stream, StreamData -from airbyte_cdk.sources.streams.http.error_handlers import BackoffStrategy, ErrorHandler, HttpStatusErrorHandler -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, ResponseAction -from airbyte_cdk.sources.streams.http.http_client import HttpClient -from airbyte_cdk.sources.types import Record, StreamSlice -from airbyte_cdk.sources.utils.types import JsonType -from deprecated import deprecated -from requests.auth import AuthBase - -# list of all possible HTTP methods which can be used for sending of request bodies -BODY_REQUEST_METHODS = ("GET", "POST", "PUT", "PATCH") - - -class HttpStream(Stream, CheckpointMixin, ABC): - """ - Base abstract class for an Airbyte Stream using the HTTP protocol. Basic building block for users building an Airbyte source for a HTTP API. - """ - - source_defined_cursor = True # Most HTTP streams use a source defined cursor (i.e: the user can't configure it like on a SQL table) - page_size: Optional[int] = None # Use this variable to define page size for API http requests with pagination support - - def __init__(self, authenticator: Optional[AuthBase] = None, api_budget: Optional[APIBudget] = None): - self._exit_on_rate_limit: bool = False - self._http_client = HttpClient( - name=self.name, - logger=self.logger, - error_handler=self.get_error_handler(), - api_budget=api_budget or APIBudget(policies=[]), - authenticator=authenticator, - use_cache=self.use_cache, - backoff_strategy=self.get_backoff_strategy(), - message_repository=InMemoryMessageRepository(), - ) - - # There are three conditions that dictate if RFR should automatically be applied to a stream - # 1. Streams that explicitly initialize their own cursor should defer to it and not automatically apply RFR - # 2. Streams with at least one cursor_field are incremental and thus a superior sync to RFR. - # 3. Streams overriding read_records() do not guarantee that they will call the parent implementation which can perform - # per-page checkpointing so RFR is only supported if a stream use the default `HttpStream.read_records()` method - if not self.cursor and len(self.cursor_field) == 0 and type(self).read_records is HttpStream.read_records: - self.cursor = ResumableFullRefreshCursor() - - @property - def exit_on_rate_limit(self) -> bool: - """ - :return: False if the stream will retry endlessly when rate limited - """ - return self._exit_on_rate_limit - - @exit_on_rate_limit.setter - def exit_on_rate_limit(self, value: bool) -> None: - self._exit_on_rate_limit = value - - @property - def cache_filename(self) -> str: - """ - Override if needed. Return the name of cache file - Note that if the environment variable REQUEST_CACHE_PATH is not set, the cache will be in-memory only. - """ - return f"{self.name}.sqlite" - - @property - def use_cache(self) -> bool: - """ - Override if needed. If True, all records will be cached. - Note that if the environment variable REQUEST_CACHE_PATH is not set, the cache will be in-memory only. - """ - return False - - @property - @abstractmethod - def url_base(self) -> str: - """ - :return: URL base for the API endpoint e.g: if you wanted to hit https://myapi.com/v1/some_entity then this should return "https://myapi.com/v1/" - """ - - @property - def http_method(self) -> str: - """ - Override if needed. See get_request_data/get_request_json if using POST/PUT/PATCH. - """ - return "GET" - - @property - @deprecated(version="3.0.0", reason="You should set error_handler explicitly in HttpStream.get_error_handler() instead.") - def raise_on_http_errors(self) -> bool: - """ - Override if needed. If set to False, allows opting-out of raising HTTP code exception. - """ - return True - - @property - @deprecated(version="3.0.0", reason="You should set backoff_strategies explicitly in HttpStream.get_backoff_strategy() instead.") - def max_retries(self) -> Union[int, None]: - """ - Override if needed. Specifies maximum amount of retries for backoff policy. Return None for no limit. - """ - return 5 - - @property - @deprecated(version="3.0.0", reason="You should set backoff_strategies explicitly in HttpStream.get_backoff_strategy() instead.") - def max_time(self) -> Union[int, None]: - """ - Override if needed. Specifies maximum total waiting time (in seconds) for backoff policy. Return None for no limit. - """ - return 60 * 10 - - @property - @deprecated(version="3.0.0", reason="You should set backoff_strategies explicitly in HttpStream.get_backoff_strategy() instead.") - def retry_factor(self) -> float: - """ - Override if needed. Specifies factor for backoff policy. - """ - return 5 - - @abstractmethod - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - """ - Override this method to define a pagination strategy. - - The value returned from this method is passed to most other methods in this class. Use it to form a request e.g: set headers or query params. - - :return: The token for the next page from the input response object. Returning None means there are no more pages to read in this response. - """ - - @abstractmethod - def path( - self, - *, - stream_state: Optional[Mapping[str, Any]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> str: - """ - Returns the URL path for the API endpoint e.g: if you wanted to hit https://myapi.com/v1/some_entity then this should return "some_entity" - """ - - def request_params( - self, - stream_state: Optional[Mapping[str, Any]], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> MutableMapping[str, Any]: - """ - Override this method to define the query parameters that should be set on an outgoing HTTP request given the inputs. - - E.g: you might want to define query parameters for paging if next_page_token is not None. - """ - return {} - - def request_headers( - self, - stream_state: Optional[Mapping[str, Any]], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - """ - Override to return any non-auth headers. Authentication headers will overwrite any overlapping headers returned from this method. - """ - return {} - - def request_body_data( - self, - stream_state: Optional[Mapping[str, Any]], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Optional[Union[Mapping[str, Any], str]]: - """ - Override when creating POST/PUT/PATCH requests to populate the body of the request with a non-JSON payload. - - If returns a ready text that it will be sent as is. - If returns a dict that it will be converted to a urlencoded form. - E.g. {"key1": "value1", "key2": "value2"} => "key1=value1&key2=value2" - - At the same time only one of the 'request_body_data' and 'request_body_json' functions can be overridden. - """ - return None - - def request_body_json( - self, - stream_state: Optional[Mapping[str, Any]], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Optional[Mapping[str, Any]]: - """ - Override when creating POST/PUT/PATCH requests to populate the body of the request with a JSON payload. - - At the same time only one of the 'request_body_data' and 'request_body_json' functions can be overridden. - """ - return None - - def request_kwargs( - self, - stream_state: Optional[Mapping[str, Any]], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - """ - Override to return a mapping of keyword arguments to be used when creating the HTTP request. - Any option listed in https://docs.python-requests.org/en/latest/api/#requests.adapters.BaseAdapter.send for can be returned from - this method. Note that these options do not conflict with request-level options such as headers, request params, etc.. - """ - return {} - - @abstractmethod - def parse_response( - self, - response: requests.Response, - *, - stream_state: Mapping[str, Any], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Iterable[Mapping[str, Any]]: - """ - Parses the raw response object into a list of records. - By default, this returns an iterable containing the input. Override to parse differently. - :param response: - :param stream_state: - :param stream_slice: - :param next_page_token: - :return: An iterable containing the parsed response - """ - - def get_backoff_strategy(self) -> Optional[Union[BackoffStrategy, List[BackoffStrategy]]]: - """ - Used to initialize Adapter to avoid breaking changes. - If Stream has a `backoff_time` method implementation, we know this stream uses old (pre-HTTPClient) backoff handlers and thus an adapter is needed. - - Override to provide custom BackoffStrategy - :return Optional[BackoffStrategy]: - """ - if hasattr(self, "backoff_time"): - return HttpStreamAdapterBackoffStrategy(self) - else: - return None - - def get_error_handler(self) -> Optional[ErrorHandler]: - """ - Used to initialize Adapter to avoid breaking changes. - If Stream has a `should_retry` method implementation, we know this stream uses old (pre-HTTPClient) error handlers and thus an adapter is needed. - - Override to provide custom ErrorHandler - :return Optional[ErrorHandler]: - """ - if hasattr(self, "should_retry"): - error_handler = HttpStreamAdapterHttpStatusErrorHandler( - stream=self, logger=logging.getLogger(), max_retries=self.max_retries, max_time=timedelta(seconds=self.max_time or 0) - ) - return error_handler - else: - return None - - @classmethod - def _join_url(cls, url_base: str, path: str) -> str: - return urljoin(url_base, path) - - @classmethod - def parse_response_error_message(cls, response: requests.Response) -> Optional[str]: - """ - Parses the raw response object from a failed request into a user-friendly error message. - By default, this method tries to grab the error message from JSON responses by following common API patterns. Override to parse differently. - - :param response: - :return: A user-friendly message that indicates the cause of the error - """ - - # default logic to grab error from common fields - def _try_get_error(value: Optional[JsonType]) -> Optional[str]: - if isinstance(value, str): - return value - elif isinstance(value, list): - errors_in_value = [_try_get_error(v) for v in value] - return ", ".join(v for v in errors_in_value if v is not None) - elif isinstance(value, dict): - new_value = ( - value.get("message") - or value.get("messages") - or value.get("error") - or value.get("errors") - or value.get("failures") - or value.get("failure") - or value.get("detail") - ) - return _try_get_error(new_value) - return None - - try: - body = response.json() - return _try_get_error(body) - except requests.exceptions.JSONDecodeError: - return None - - def get_error_display_message(self, exception: BaseException) -> Optional[str]: - """ - Retrieves the user-friendly display message that corresponds to an exception. - This will be called when encountering an exception while reading records from the stream, and used to build the AirbyteTraceMessage. - - The default implementation of this method only handles HTTPErrors by passing the response to self.parse_response_error_message(). - The method should be overriden as needed to handle any additional exception types. - - :param exception: The exception that was raised - :return: A user-friendly message that indicates the cause of the error - """ - if isinstance(exception, requests.HTTPError) and exception.response is not None: - return self.parse_response_error_message(exception.response) - return None - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: Optional[List[str]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - # A cursor_field indicates this is an incremental stream which offers better checkpointing than RFR enabled via the cursor - if self.cursor_field or not isinstance(self.get_cursor(), ResumableFullRefreshCursor): - yield from self._read_pages( - lambda req, res, state, _slice: self.parse_response(res, stream_slice=_slice, stream_state=state), - stream_slice, - stream_state, - ) - else: - yield from self._read_single_page( - lambda req, res, state, _slice: self.parse_response(res, stream_slice=_slice, stream_state=state), - stream_slice, - stream_state, - ) - - @property - def state(self) -> MutableMapping[str, Any]: - cursor = self.get_cursor() - if cursor: - return cursor.get_stream_state() # type: ignore - return self._state - - @state.setter - def state(self, value: MutableMapping[str, Any]) -> None: - cursor = self.get_cursor() - if cursor: - cursor.set_initial_state(value) - self._state = value - - def get_cursor(self) -> Optional[Cursor]: - # I don't love that this is semi-stateful but not sure what else to do. We don't know exactly what type of cursor to - # instantiate when creating the class. We can make a few assumptions like if there is a cursor_field which implies - # incremental, but we don't know until runtime if this is a substream. Ideally, a stream should explicitly define - # its cursor, but because we're trying to automatically apply RFR we're stuck with this logic where we replace the - # cursor at runtime once we detect this is a substream based on self.has_multiple_slices being reassigned - if self.has_multiple_slices and isinstance(self.cursor, ResumableFullRefreshCursor): - self.cursor = SubstreamResumableFullRefreshCursor() - return self.cursor - else: - return self.cursor - - def _read_pages( - self, - records_generator_fn: Callable[ - [requests.PreparedRequest, requests.Response, Mapping[str, Any], Optional[Mapping[str, Any]]], Iterable[StreamData] - ], - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - partition, _, _ = self._extract_slice_fields(stream_slice=stream_slice) - - stream_state = stream_state or {} - pagination_complete = False - next_page_token = None - while not pagination_complete: - request, response = self._fetch_next_page(stream_slice, stream_state, next_page_token) - yield from records_generator_fn(request, response, stream_state, stream_slice) - - next_page_token = self.next_page_token(response) - if not next_page_token: - pagination_complete = True - - cursor = self.get_cursor() - if cursor and isinstance(cursor, SubstreamResumableFullRefreshCursor): - # Substreams checkpoint state by marking an entire parent partition as completed so that on the subsequent attempt - # after a failure, completed parents are skipped and the sync can make progress - cursor.close_slice(StreamSlice(cursor_slice={}, partition=partition)) - - # Always return an empty generator just in case no records were ever yielded - yield from [] - - def _read_single_page( - self, - records_generator_fn: Callable[ - [requests.PreparedRequest, requests.Response, Mapping[str, Any], Optional[Mapping[str, Any]]], Iterable[StreamData] - ], - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - partition, cursor_slice, remaining_slice = self._extract_slice_fields(stream_slice=stream_slice) - stream_state = stream_state or {} - next_page_token = cursor_slice or None - - request, response = self._fetch_next_page(remaining_slice, stream_state, next_page_token) - yield from records_generator_fn(request, response, stream_state, remaining_slice) - - next_page_token = self.next_page_token(response) or {"__ab_full_refresh_sync_complete": True} - - cursor = self.get_cursor() - if cursor: - cursor.close_slice(StreamSlice(cursor_slice=next_page_token, partition=partition)) - - # Always return an empty generator just in case no records were ever yielded - yield from [] - - @staticmethod - def _extract_slice_fields(stream_slice: Optional[Mapping[str, Any]]) -> tuple[Mapping[str, Any], Mapping[str, Any], Mapping[str, Any]]: - if not stream_slice: - return {}, {}, {} - - if isinstance(stream_slice, StreamSlice): - partition = stream_slice.partition - cursor_slice = stream_slice.cursor_slice - remaining = {k: v for k, v in stream_slice.items()} - else: - # RFR streams that implement stream_slices() to generate stream slices in the legacy mapping format are converted into a - # structured stream slice mapping by the LegacyCursorBasedCheckpointReader. The structured mapping object has separate - # fields for the partition and cursor_slice value - partition = stream_slice.get("partition", {}) - cursor_slice = stream_slice.get("cursor_slice", {}) - remaining = {key: val for key, val in stream_slice.items() if key != "partition" and key != "cursor_slice"} - return partition, cursor_slice, remaining - - def _fetch_next_page( - self, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Tuple[requests.PreparedRequest, requests.Response]: - - request, response = self._http_client.send_request( - http_method=self.http_method, - url=self._join_url( - self.url_base, - self.path(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - ), - request_kwargs=self.request_kwargs(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - headers=self.request_headers(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - params=self.request_params(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - json=self.request_body_json(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - data=self.request_body_data(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - dedupe_query_params=True, - log_formatter=self.get_log_formatter(), - exit_on_rate_limit=self.exit_on_rate_limit, - ) - - return request, response - - def get_log_formatter(self) -> Optional[Callable[[requests.Response], Any]]: - """ - - :return Optional[Callable[[requests.Response], Any]]: Function that will be used in logging inside HttpClient - """ - return None - - -class HttpSubStream(HttpStream, ABC): - def __init__(self, parent: HttpStream, **kwargs: Any): - """ - :param parent: should be the instance of HttpStream class - """ - super().__init__(**kwargs) - self.parent = parent - self.has_multiple_slices = True # Substreams are based on parent records which implies there are multiple slices - - # There are three conditions that dictate if RFR should automatically be applied to a stream - # 1. Streams that explicitly initialize their own cursor should defer to it and not automatically apply RFR - # 2. Streams with at least one cursor_field are incremental and thus a superior sync to RFR. - # 3. Streams overriding read_records() do not guarantee that they will call the parent implementation which can perform - # per-page checkpointing so RFR is only supported if a stream use the default `HttpStream.read_records()` method - if not self.cursor and len(self.cursor_field) == 0 and type(self).read_records is HttpStream.read_records: - self.cursor = SubstreamResumableFullRefreshCursor() - - def stream_slices( - self, sync_mode: SyncMode, cursor_field: Optional[List[str]] = None, stream_state: Optional[Mapping[str, Any]] = None - ) -> Iterable[Optional[Mapping[str, Any]]]: - # read_stateless() assumes the parent is not concurrent. This is currently okay since the concurrent CDK does - # not support either substreams or RFR, but something that needs to be considered once we do - for parent_record in self.parent.read_only_records(stream_state): - # Skip non-records (eg AirbyteLogMessage) - if isinstance(parent_record, AirbyteMessage): - if parent_record.type == MessageType.RECORD: - parent_record = parent_record.record.data - else: - continue - elif isinstance(parent_record, Record): - parent_record = parent_record.data - yield {"parent": parent_record} - - -@deprecated(version="3.0.0", reason="You should set backoff_strategies explicitly in HttpStream.get_backoff_strategy() instead.") -class HttpStreamAdapterBackoffStrategy(BackoffStrategy): - def __init__(self, stream: HttpStream): - self.stream = stream - - def backoff_time( - self, - response_or_exception: Optional[Union[requests.Response, requests.RequestException]], - attempt_count: int, - ) -> Optional[float]: - return self.stream.backoff_time(response_or_exception) # type: ignore # noqa # HttpStream.backoff_time has been deprecated - - -@deprecated(version="3.0.0", reason="You should set error_handler explicitly in HttpStream.get_error_handler() instead.") -class HttpStreamAdapterHttpStatusErrorHandler(HttpStatusErrorHandler): - def __init__(self, stream: HttpStream, **kwargs): # type: ignore # noqa - self.stream = stream - super().__init__(**kwargs) - - def interpret_response(self, response_or_exception: Optional[Union[requests.Response, Exception]] = None) -> ErrorResolution: - if isinstance(response_or_exception, Exception): - return super().interpret_response(response_or_exception) - elif isinstance(response_or_exception, requests.Response): - should_retry = self.stream.should_retry(response_or_exception) # type: ignore # noqa - if should_retry: - if response_or_exception.status_code == 429: - return ErrorResolution( - response_action=ResponseAction.RATE_LIMITED, - failure_type=FailureType.transient_error, - error_message=f"Response status code: {response_or_exception.status_code}. Retrying...", # type: ignore[union-attr] - ) - return ErrorResolution( - response_action=ResponseAction.RETRY, - failure_type=FailureType.transient_error, - error_message=f"Response status code: {response_or_exception.status_code}. Retrying...", # type: ignore[union-attr] - ) - else: - if response_or_exception.ok: # type: ignore # noqa - return ErrorResolution( - response_action=ResponseAction.SUCCESS, - failure_type=None, - error_message=None, - ) - if self.stream.raise_on_http_errors: - return ErrorResolution( - response_action=ResponseAction.FAIL, - failure_type=FailureType.transient_error, - error_message=f"Response status code: {response_or_exception.status_code}. Unexpected error. Failed.", # type: ignore[union-attr] - ) - else: - return ErrorResolution( - response_action=ResponseAction.IGNORE, - failure_type=FailureType.transient_error, - error_message=f"Response status code: {response_or_exception.status_code}. Ignoring...", # type: ignore[union-attr] - ) - else: - self._logger.error(f"Received unexpected response type: {type(response_or_exception)}") - return ErrorResolution( - response_action=ResponseAction.FAIL, - failure_type=FailureType.system_error, - error_message=f"Received unexpected response type: {type(response_or_exception)}", - ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/http_client.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/http_client.py deleted file mode 100644 index cccbc4b8c01c..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/http_client.py +++ /dev/null @@ -1,410 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -import os -import urllib -from pathlib import Path -from typing import Any, Callable, Dict, List, Mapping, Optional, Tuple, Union - -import orjson -import requests -import requests_cache -from airbyte_cdk.models import ( - AirbyteMessageSerializer, - AirbyteStreamStatus, - AirbyteStreamStatusReason, - AirbyteStreamStatusReasonType, - Level, - StreamDescriptor, -) -from airbyte_cdk.sources.http_config import MAX_CONNECTION_POOL_SIZE -from airbyte_cdk.sources.message import MessageRepository -from airbyte_cdk.sources.streams.call_rate import APIBudget, CachedLimiterSession, LimiterSession -from airbyte_cdk.sources.streams.http.error_handlers import ( - BackoffStrategy, - DefaultBackoffStrategy, - ErrorHandler, - ErrorMessageParser, - ErrorResolution, - HttpStatusErrorHandler, - JsonErrorMessageParser, - ResponseAction, -) -from airbyte_cdk.sources.streams.http.exceptions import ( - DefaultBackoffException, - RateLimitBackoffException, - RequestBodyException, - UserDefinedBackoffException, -) -from airbyte_cdk.sources.streams.http.rate_limiting import ( - http_client_default_backoff_handler, - rate_limit_default_backoff_handler, - user_defined_backoff_handler, -) -from airbyte_cdk.utils.constants import ENV_REQUEST_CACHE_PATH -from airbyte_cdk.utils.stream_status_utils import as_airbyte_message as stream_status_as_airbyte_message -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from requests.auth import AuthBase - -BODY_REQUEST_METHODS = ("GET", "POST", "PUT", "PATCH") - - -class MessageRepresentationAirbyteTracedErrors(AirbyteTracedException): - """ - Before the migration to the HttpClient in low-code, the exception raised was - [ReadException](https://github.com/airbytehq/airbyte/blob/8fdd9818ec16e653ba3dd2b167a74b7c07459861/airbyte-cdk/python/airbyte_cdk/sources/declarative/requesters/http_requester.py#L566). - This has been moved to a AirbyteTracedException. The printing on this is questionable (AirbyteTracedException string representation - shows the internal_message and not the message). We have already discussed moving the AirbyteTracedException string representation to - `message` but the impact is unclear and hard to quantify so we will do it here only for now. - """ - - def __str__(self) -> str: - if self.message: - return self.message - elif self.internal_message: - return self.internal_message - return "" - - -class HttpClient: - - _DEFAULT_MAX_RETRY: int = 5 - _DEFAULT_MAX_TIME: int = 60 * 10 - - def __init__( - self, - name: str, - logger: logging.Logger, - error_handler: Optional[ErrorHandler] = None, - api_budget: Optional[APIBudget] = None, - session: Optional[Union[requests.Session, requests_cache.CachedSession]] = None, - authenticator: Optional[AuthBase] = None, - use_cache: bool = False, - backoff_strategy: Optional[Union[BackoffStrategy, List[BackoffStrategy]]] = None, - error_message_parser: Optional[ErrorMessageParser] = None, - disable_retries: bool = False, - message_repository: Optional[MessageRepository] = None, - ): - self._name = name - self._api_budget: APIBudget = api_budget or APIBudget(policies=[]) - if session: - self._session = session - else: - self._use_cache = use_cache - self._session = self._request_session() - self._session.mount( - "https://", requests.adapters.HTTPAdapter(pool_connections=MAX_CONNECTION_POOL_SIZE, pool_maxsize=MAX_CONNECTION_POOL_SIZE) - ) - if isinstance(authenticator, AuthBase): - self._session.auth = authenticator - self._logger = logger - self._error_handler = error_handler or HttpStatusErrorHandler(self._logger) - if backoff_strategy is not None: - if isinstance(backoff_strategy, list): - self._backoff_strategies = backoff_strategy - else: - self._backoff_strategies = [backoff_strategy] - else: - self._backoff_strategies = [DefaultBackoffStrategy()] - self._error_message_parser = error_message_parser or JsonErrorMessageParser() - self._request_attempt_count: Dict[requests.PreparedRequest, int] = {} - self._disable_retries = disable_retries - self._message_repository = message_repository - - @property - def cache_filename(self) -> str: - """ - Override if needed. Return the name of cache file - Note that if the environment variable REQUEST_CACHE_PATH is not set, the cache will be in-memory only. - """ - return f"{self._name}.sqlite" - - def _request_session(self) -> requests.Session: - """ - Session factory based on use_cache property and call rate limits (api_budget parameter) - :return: instance of request-based session - """ - if self._use_cache: - cache_dir = os.getenv(ENV_REQUEST_CACHE_PATH) - # Use in-memory cache if cache_dir is not set - # This is a non-obvious interface, but it ensures we don't write sql files when running unit tests - if cache_dir: - sqlite_path = str(Path(cache_dir) / self.cache_filename) - else: - sqlite_path = "file::memory:?cache=shared" - return CachedLimiterSession(sqlite_path, backend="sqlite", api_budget=self._api_budget, match_headers=True) # type: ignore # there are no typeshed stubs for requests_cache - else: - return LimiterSession(api_budget=self._api_budget) - - def clear_cache(self) -> None: - """ - Clear cached requests for current session, can be called any time - """ - if isinstance(self._session, requests_cache.CachedSession): - self._session.cache.clear() # type: ignore # cache.clear is not typed - - def _dedupe_query_params(self, url: str, params: Optional[Mapping[str, str]]) -> Mapping[str, str]: - """ - Remove query parameters from params mapping if they are already encoded in the URL. - :param url: URL with - :param params: - :return: - """ - if params is None: - params = {} - query_string = urllib.parse.urlparse(url).query - query_dict = {k: v[0] for k, v in urllib.parse.parse_qs(query_string).items()} - - duplicate_keys_with_same_value = {k for k in query_dict.keys() if str(params.get(k)) == str(query_dict[k])} - return {k: v for k, v in params.items() if k not in duplicate_keys_with_same_value} - - def _create_prepared_request( - self, - http_method: str, - url: str, - dedupe_query_params: bool = False, - headers: Optional[Mapping[str, str]] = None, - params: Optional[Mapping[str, str]] = None, - json: Optional[Mapping[str, Any]] = None, - data: Optional[Union[str, Mapping[str, Any]]] = None, - ) -> requests.PreparedRequest: - if dedupe_query_params: - query_params = self._dedupe_query_params(url, params) - else: - query_params = params or {} - args = {"method": http_method, "url": url, "headers": headers, "params": query_params} - if http_method.upper() in BODY_REQUEST_METHODS: - if json and data: - raise RequestBodyException( - "At the same time only one of the 'request_body_data' and 'request_body_json' functions can return data" - ) - elif json: - args["json"] = json - elif data: - args["data"] = data - prepared_request: requests.PreparedRequest = self._session.prepare_request(requests.Request(**args)) - - return prepared_request - - @property - def _max_retries(self) -> int: - """ - Determines the max retries based on the provided error handler. - """ - max_retries = None - if self._disable_retries: - max_retries = 0 - else: - max_retries = self._error_handler.max_retries - return max_retries if max_retries is not None else self._DEFAULT_MAX_RETRY - - @property - def _max_time(self) -> int: - """ - Determines the max time based on the provided error handler. - """ - return self._error_handler.max_time if self._error_handler.max_time is not None else self._DEFAULT_MAX_TIME - - def _send_with_retry( - self, - request: requests.PreparedRequest, - request_kwargs: Mapping[str, Any], - log_formatter: Optional[Callable[[requests.Response], Any]] = None, - exit_on_rate_limit: Optional[bool] = False, - ) -> requests.Response: - """ - Sends a request with retry logic. - - Args: - request (requests.PreparedRequest): The prepared HTTP request to send. - request_kwargs (Mapping[str, Any]): Additional keyword arguments for the request. - - Returns: - requests.Response: The HTTP response received from the server after retries. - """ - - max_retries = self._max_retries - max_tries = max(0, max_retries) + 1 - max_time = self._max_time - - user_backoff_handler = user_defined_backoff_handler(max_tries=max_tries, max_time=max_time)(self._send) - rate_limit_backoff_handler = rate_limit_default_backoff_handler() - backoff_handler = http_client_default_backoff_handler(max_tries=max_tries, max_time=max_time) - # backoff handlers wrap _send, so it will always return a response - response = backoff_handler(rate_limit_backoff_handler(user_backoff_handler))(request, request_kwargs, log_formatter=log_formatter, exit_on_rate_limit=exit_on_rate_limit) # type: ignore # mypy can't infer that backoff_handler wraps _send - - return response - - def _send( - self, - request: requests.PreparedRequest, - request_kwargs: Mapping[str, Any], - log_formatter: Optional[Callable[[requests.Response], Any]] = None, - exit_on_rate_limit: Optional[bool] = False, - ) -> requests.Response: - - if request not in self._request_attempt_count: - self._request_attempt_count[request] = 1 - else: - self._request_attempt_count[request] += 1 - if hasattr(self._session, "auth") and isinstance(self._session.auth, AuthBase): - self._session.auth(request) - - self._logger.debug( - "Making outbound API request", extra={"headers": request.headers, "url": request.url, "request_body": request.body} - ) - - response: Optional[requests.Response] = None - exc: Optional[requests.RequestException] = None - - try: - response = self._session.send(request, **request_kwargs) - except requests.RequestException as e: - exc = e - - error_resolution: ErrorResolution = self._error_handler.interpret_response(response if response is not None else exc) - - # Evaluation of response.text can be heavy, for example, if streaming a large response - # Do it only in debug mode - if self._logger.isEnabledFor(logging.DEBUG) and response is not None: - if request_kwargs.get("stream"): - self._logger.debug( - "Receiving response, but not logging it as the response is streamed", - extra={"headers": response.headers, "status": response.status_code}, - ) - else: - self._logger.debug( - "Receiving response", extra={"headers": response.headers, "status": response.status_code, "body": response.text} - ) - - # Request/response logging for declarative cdk - if log_formatter is not None and response is not None and self._message_repository is not None: - formatter = log_formatter - self._message_repository.log_message( - Level.DEBUG, - lambda: formatter(response), # type: ignore # log_formatter is always cast to a callable - ) - - self._handle_error_resolution( - response=response, exc=exc, request=request, error_resolution=error_resolution, exit_on_rate_limit=exit_on_rate_limit - ) - - return response # type: ignore # will either return a valid response of type requests.Response or raise an exception - - def _handle_error_resolution( - self, - response: Optional[requests.Response], - exc: Optional[requests.RequestException], - request: requests.PreparedRequest, - error_resolution: ErrorResolution, - exit_on_rate_limit: Optional[bool] = False, - ) -> None: - # Emit stream status RUNNING with the reason RATE_LIMITED to log that the rate limit has been reached - if error_resolution.response_action == ResponseAction.RATE_LIMITED: - # TODO: Update to handle with message repository when concurrent message repository is ready - reasons = [AirbyteStreamStatusReason(type=AirbyteStreamStatusReasonType.RATE_LIMITED)] - message = orjson.dumps( - AirbyteMessageSerializer.dump( - stream_status_as_airbyte_message(StreamDescriptor(name=self._name), AirbyteStreamStatus.RUNNING, reasons) - ) - ).decode() - - # Simply printing the stream status is a temporary solution and can cause future issues. Currently, the _send method is - # wrapped with backoff decorators, and we can only emit messages by iterating record_iterator in the abstract source at the - # end of the retry decorator behavior. This approach does not allow us to emit messages in the queue before exiting the - # backoff retry loop. Adding `\n` to the message and ignore 'end' ensure that few messages are printed at the same time. - print(f"{message}\n", end="", flush=True) - - if error_resolution.response_action == ResponseAction.FAIL: - if response is not None: - error_message = f"'{request.method}' request to '{request.url}' failed with status code '{response.status_code}' and error message '{self._error_message_parser.parse_response_error_message(response)}'" - else: - error_message = f"'{request.method}' request to '{request.url}' failed with exception: '{exc}'" - - raise MessageRepresentationAirbyteTracedErrors( - internal_message=error_message, - message=error_resolution.error_message or error_message, - failure_type=error_resolution.failure_type, - ) - - elif error_resolution.response_action == ResponseAction.IGNORE: - if response is not None: - log_message = ( - f"Ignoring response for '{request.method}' request to '{request.url}' with response code '{response.status_code}'" - ) - else: - log_message = f"Ignoring response for '{request.method}' request to '{request.url}' with error '{exc}'" - - self._logger.info(error_resolution.error_message or log_message) - - # TODO: Consider dynamic retry count depending on subsequent error codes - elif error_resolution.response_action == ResponseAction.RETRY or error_resolution.response_action == ResponseAction.RATE_LIMITED: - user_defined_backoff_time = None - for backoff_strategy in self._backoff_strategies: - backoff_time = backoff_strategy.backoff_time( - response_or_exception=response if response is not None else exc, attempt_count=self._request_attempt_count[request] - ) - if backoff_time: - user_defined_backoff_time = backoff_time - break - error_message = ( - error_resolution.error_message - or f"Request to {request.url} failed with failure type {error_resolution.failure_type}, response action {error_resolution.response_action}." - ) - - retry_endlessly = error_resolution.response_action == ResponseAction.RATE_LIMITED and not exit_on_rate_limit - - if user_defined_backoff_time: - raise UserDefinedBackoffException( - backoff=user_defined_backoff_time, - request=request, - response=(response if response is not None else exc), - error_message=error_message, - ) - - elif retry_endlessly: - raise RateLimitBackoffException(request=request, response=response or exc, error_message=error_message) - - raise DefaultBackoffException( - request=request, response=(response if response is not None else exc), error_message=error_message - ) - - elif response: - try: - response.raise_for_status() - except requests.HTTPError as e: - self._logger.error(response.text) - raise e - - @property - def name(self) -> str: - return self._name - - def send_request( - self, - http_method: str, - url: str, - request_kwargs: Mapping[str, Any], - headers: Optional[Mapping[str, str]] = None, - params: Optional[Mapping[str, str]] = None, - json: Optional[Mapping[str, Any]] = None, - data: Optional[Union[str, Mapping[str, Any]]] = None, - dedupe_query_params: bool = False, - log_formatter: Optional[Callable[[requests.Response], Any]] = None, - exit_on_rate_limit: Optional[bool] = False, - ) -> Tuple[requests.PreparedRequest, requests.Response]: - """ - Prepares and sends request and return request and response objects. - """ - - request: requests.PreparedRequest = self._create_prepared_request( - http_method=http_method, url=url, dedupe_query_params=dedupe_query_params, headers=headers, params=params, json=json, data=data - ) - - response: requests.Response = self._send_with_retry( - request=request, request_kwargs=request_kwargs, log_formatter=log_formatter, exit_on_rate_limit=exit_on_rate_limit - ) - - return request, response diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/rate_limiting.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/rate_limiting.py deleted file mode 100644 index cae3907dbb39..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/rate_limiting.py +++ /dev/null @@ -1,142 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -import sys -import time -from typing import Any, Callable, Mapping, Optional - -import backoff -from requests import PreparedRequest, RequestException, Response, codes, exceptions - -from .exceptions import DefaultBackoffException, RateLimitBackoffException, UserDefinedBackoffException - -TRANSIENT_EXCEPTIONS = ( - DefaultBackoffException, - exceptions.ConnectTimeout, - exceptions.ReadTimeout, - exceptions.ConnectionError, - exceptions.ChunkedEncodingError, -) - -logger = logging.getLogger("airbyte") - - -SendRequestCallableType = Callable[[PreparedRequest, Mapping[str, Any]], Response] - - -def default_backoff_handler( - max_tries: Optional[int], factor: float, max_time: Optional[int] = None, **kwargs: Any -) -> Callable[[SendRequestCallableType], SendRequestCallableType]: - def log_retry_attempt(details: Mapping[str, Any]) -> None: - _, exc, _ = sys.exc_info() - if isinstance(exc, RequestException) and exc.response: - logger.info(f"Status code: {exc.response.status_code!r}, Response Content: {exc.response.content!r}") - logger.info( - f"Caught retryable error '{str(exc)}' after {details['tries']} tries. Waiting {details['wait']} seconds then retrying..." - ) - - def should_give_up(exc: Exception) -> bool: - # If a non-rate-limiting related 4XX error makes it this far, it means it was unexpected and probably consistent, so we shouldn't back off - if isinstance(exc, RequestException): - if exc.response is not None: - give_up: bool = ( - exc.response is not None - and exc.response.status_code != codes.too_many_requests - and 400 <= exc.response.status_code < 500 - ) - if give_up: - logger.info(f"Giving up for returned HTTP status: {exc.response.status_code!r}") - return give_up - # Only RequestExceptions are retryable, so if we get here, it's not retryable - return False - - return backoff.on_exception( # type: ignore # Decorator function returns a function with a different signature than the input function, so mypy can't infer the type of the returned function - backoff.expo, - TRANSIENT_EXCEPTIONS, - jitter=None, - on_backoff=log_retry_attempt, - giveup=should_give_up, - max_tries=max_tries, - max_time=max_time, - factor=factor, - **kwargs, - ) - - -def http_client_default_backoff_handler( - max_tries: Optional[int], max_time: Optional[int] = None, **kwargs: Any -) -> Callable[[SendRequestCallableType], SendRequestCallableType]: - def log_retry_attempt(details: Mapping[str, Any]) -> None: - _, exc, _ = sys.exc_info() - if isinstance(exc, RequestException) and exc.response: - logger.info(f"Status code: {exc.response.status_code!r}, Response Content: {exc.response.content!r}") - logger.info( - f"Caught retryable error '{str(exc)}' after {details['tries']} tries. Waiting {details['wait']} seconds then retrying..." - ) - - def should_give_up(exc: Exception) -> bool: - # If made it here, the ResponseAction was RETRY and therefore should not give up - return False - - return backoff.on_exception( # type: ignore # Decorator function returns a function with a different signature than the input function, so mypy can't infer the type of the returned function - backoff.expo, - TRANSIENT_EXCEPTIONS, - jitter=None, - on_backoff=log_retry_attempt, - giveup=should_give_up, - max_tries=max_tries, - max_time=max_time, - **kwargs, - ) - - -def user_defined_backoff_handler( - max_tries: Optional[int], max_time: Optional[int] = None, **kwargs: Any -) -> Callable[[SendRequestCallableType], SendRequestCallableType]: - def sleep_on_ratelimit(details: Mapping[str, Any]) -> None: - _, exc, _ = sys.exc_info() - if isinstance(exc, UserDefinedBackoffException): - if exc.response: - logger.info(f"Status code: {exc.response.status_code!r}, Response Content: {exc.response.content!r}") - retry_after = exc.backoff - logger.info(f"Retrying. Sleeping for {retry_after} seconds") - time.sleep(retry_after + 1) # extra second to cover any fractions of second - - def log_give_up(details: Mapping[str, Any]) -> None: - _, exc, _ = sys.exc_info() - if isinstance(exc, RequestException): - logger.error(f"Max retry limit reached in {details['elapsed']}s. Request: {exc.request}, Response: {exc.response}") - else: - logger.error("Max retry limit reached for unknown request and response") - - return backoff.on_exception( # type: ignore # Decorator function returns a function with a different signature than the input function, so mypy can't infer the type of the returned function - backoff.constant, - UserDefinedBackoffException, - interval=0, # skip waiting, we'll wait in on_backoff handler - on_backoff=sleep_on_ratelimit, - on_giveup=log_give_up, - jitter=None, - max_tries=max_tries, - max_time=max_time, - **kwargs, - ) - - -def rate_limit_default_backoff_handler(**kwargs: Any) -> Callable[[SendRequestCallableType], SendRequestCallableType]: - def log_retry_attempt(details: Mapping[str, Any]) -> None: - _, exc, _ = sys.exc_info() - if isinstance(exc, RequestException) and exc.response: - logger.info(f"Status code: {exc.response.status_code!r}, Response Content: {exc.response.content!r}") - logger.info( - f"Caught retryable error '{str(exc)}' after {details['tries']} tries. Waiting {details['wait']} seconds then retrying..." - ) - - return backoff.on_exception( # type: ignore # Decorator function returns a function with a different signature than the input function, so mypy can't infer the type of the returned function - backoff.expo, - RateLimitBackoffException, - jitter=None, - on_backoff=log_retry_attempt, - **kwargs, - ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/__init__.py deleted file mode 100644 index 307f91f40ced..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from .oauth import Oauth2Authenticator, SingleUseRefreshTokenOauth2Authenticator -from .token import BasicHttpAuthenticator, MultipleTokenAuthenticator, TokenAuthenticator - -__all__ = [ - "Oauth2Authenticator", - "SingleUseRefreshTokenOauth2Authenticator", - "TokenAuthenticator", - "MultipleTokenAuthenticator", - "BasicHttpAuthenticator", -] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py deleted file mode 100644 index 63915f71d651..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py +++ /dev/null @@ -1,258 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from abc import abstractmethod -from json import JSONDecodeError -from typing import Any, List, Mapping, MutableMapping, Optional, Tuple, Union - -import backoff -import pendulum -import requests -from airbyte_cdk.models import FailureType, Level -from airbyte_cdk.sources.http_logger import format_http_message -from airbyte_cdk.sources.message import MessageRepository, NoopMessageRepository -from airbyte_cdk.utils import AirbyteTracedException -from airbyte_cdk.utils.airbyte_secrets_utils import add_to_secrets -from requests.auth import AuthBase - -from ..exceptions import DefaultBackoffException - -logger = logging.getLogger("airbyte") -_NOOP_MESSAGE_REPOSITORY = NoopMessageRepository() - - -class AbstractOauth2Authenticator(AuthBase): - """ - Abstract class for an OAuth authenticators that implements the OAuth token refresh flow. The authenticator - is designed to generically perform the refresh flow without regard to how config fields are get/set by - delegating that behavior to the classes implementing the interface. - """ - - _NO_STREAM_NAME = None - - def __init__( - self, - refresh_token_error_status_codes: Tuple[int, ...] = (), - refresh_token_error_key: str = "", - refresh_token_error_values: Tuple[str, ...] = (), - ) -> None: - """ - If all of refresh_token_error_status_codes, refresh_token_error_key, and refresh_token_error_values are set, - then http errors with such params will be wrapped in AirbyteTracedException. - """ - self._refresh_token_error_status_codes = refresh_token_error_status_codes - self._refresh_token_error_key = refresh_token_error_key - self._refresh_token_error_values = refresh_token_error_values - - def __call__(self, request: requests.PreparedRequest) -> requests.PreparedRequest: - """Attach the HTTP headers required to authenticate on the HTTP request""" - request.headers.update(self.get_auth_header()) - return request - - def get_auth_header(self) -> Mapping[str, Any]: - """HTTP header to set on the requests""" - return {"Authorization": f"Bearer {self.get_access_token()}"} - - def get_access_token(self) -> str: - """Returns the access token""" - if self.token_has_expired(): - token, expires_in = self.refresh_access_token() - self.access_token = token - self.set_token_expiry_date(expires_in) - - return self.access_token - - def token_has_expired(self) -> bool: - """Returns True if the token is expired""" - return pendulum.now() > self.get_token_expiry_date() # type: ignore # this is always a bool despite what mypy thinks - - def build_refresh_request_body(self) -> Mapping[str, Any]: - """ - Returns the request body to set on the refresh request - - Override to define additional parameters - """ - payload: MutableMapping[str, Any] = { - "grant_type": self.get_grant_type(), - "client_id": self.get_client_id(), - "client_secret": self.get_client_secret(), - "refresh_token": self.get_refresh_token(), - } - - if self.get_scopes(): - payload["scopes"] = self.get_scopes() - - if self.get_refresh_request_body(): - for key, val in self.get_refresh_request_body().items(): - # We defer to existing oauth constructs over custom configured fields - if key not in payload: - payload[key] = val - - return payload - - def _wrap_refresh_token_exception(self, exception: requests.exceptions.RequestException) -> bool: - try: - if exception.response is not None: - exception_content = exception.response.json() - else: - return False - except JSONDecodeError: - return False - return ( - exception.response.status_code in self._refresh_token_error_status_codes - and exception_content.get(self._refresh_token_error_key) in self._refresh_token_error_values - ) - - @backoff.on_exception( - backoff.expo, - DefaultBackoffException, - on_backoff=lambda details: logger.info( - f"Caught retryable error after {details['tries']} tries. Waiting {details['wait']} seconds then retrying..." - ), - max_time=300, - ) - def _get_refresh_access_token_response(self) -> Any: - try: - response = requests.request(method="POST", url=self.get_token_refresh_endpoint(), data=self.build_refresh_request_body()) - if response.ok: - response_json = response.json() - # Add the access token to the list of secrets so it is replaced before logging the response - # An argument could be made to remove the prevous access key from the list of secrets, but unmasking values seems like a security incident waiting to happen... - access_key = response_json.get(self.get_access_token_name()) - if not access_key: - raise Exception("Token refresh API response was missing access token {self.get_access_token_name()}") - add_to_secrets(access_key) - self._log_response(response) - return response_json - else: - # log the response even if the request failed for troubleshooting purposes - self._log_response(response) - response.raise_for_status() - except requests.exceptions.RequestException as e: - if e.response is not None: - if e.response.status_code == 429 or e.response.status_code >= 500: - raise DefaultBackoffException(request=e.response.request, response=e.response) - if self._wrap_refresh_token_exception(e): - message = "Refresh token is invalid or expired. Please re-authenticate from Sources//Settings." - raise AirbyteTracedException(internal_message=message, message=message, failure_type=FailureType.config_error) - raise - except Exception as e: - raise Exception(f"Error while refreshing access token: {e}") from e - - def refresh_access_token(self) -> Tuple[str, Union[str, int]]: - """ - Returns the refresh token and its expiration datetime - - :return: a tuple of (access_token, token_lifespan) - """ - response_json = self._get_refresh_access_token_response() - - return response_json[self.get_access_token_name()], response_json[self.get_expires_in_name()] - - def _parse_token_expiration_date(self, value: Union[str, int]) -> pendulum.DateTime: - """ - Return the expiration datetime of the refresh token - - :return: expiration datetime - """ - - if self.token_expiry_is_time_of_expiration: - if not self.token_expiry_date_format: - raise ValueError( - f"Invalid token expiry date format {self.token_expiry_date_format}; a string representing the format is required." - ) - return pendulum.from_format(str(value), self.token_expiry_date_format) - else: - return pendulum.now().add(seconds=int(float(value))) - - @property - def token_expiry_is_time_of_expiration(self) -> bool: - """ - Indicates that the Token Expiry returns the date until which the token will be valid, not the amount of time it will be valid. - """ - - return False - - @property - def token_expiry_date_format(self) -> Optional[str]: - """ - Format of the datetime; exists it if expires_in is returned as the expiration datetime instead of seconds until it expires - """ - - return None - - @abstractmethod - def get_token_refresh_endpoint(self) -> str: - """Returns the endpoint to refresh the access token""" - - @abstractmethod - def get_client_id(self) -> str: - """The client id to authenticate""" - - @abstractmethod - def get_client_secret(self) -> str: - """The client secret to authenticate""" - - @abstractmethod - def get_refresh_token(self) -> Optional[str]: - """The token used to refresh the access token when it expires""" - - @abstractmethod - def get_scopes(self) -> List[str]: - """List of requested scopes""" - - @abstractmethod - def get_token_expiry_date(self) -> pendulum.DateTime: - """Expiration date of the access token""" - - @abstractmethod - def set_token_expiry_date(self, value: Union[str, int]) -> None: - """Setter for access token expiration date""" - - @abstractmethod - def get_access_token_name(self) -> str: - """Field to extract access token from in the response""" - - @abstractmethod - def get_expires_in_name(self) -> str: - """Returns the expires_in field name""" - - @abstractmethod - def get_refresh_request_body(self) -> Mapping[str, Any]: - """Returns the request body to set on the refresh request""" - - @abstractmethod - def get_grant_type(self) -> str: - """Returns grant_type specified for requesting access_token""" - - @property - @abstractmethod - def access_token(self) -> str: - """Returns the access token""" - - @access_token.setter - @abstractmethod - def access_token(self, value: str) -> str: - """Setter for the access token""" - - @property - def _message_repository(self) -> Optional[MessageRepository]: - """ - The implementation can define a message_repository if it wants debugging logs for HTTP requests - """ - return _NOOP_MESSAGE_REPOSITORY - - def _log_response(self, response: requests.Response) -> None: - if self._message_repository: - self._message_repository.log_message( - Level.DEBUG, - lambda: format_http_message( - response, - "Refresh token", - "Obtains access token", - self._NO_STREAM_NAME, - is_auxiliary=True, - ), - ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_token.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_token.py deleted file mode 100644 index db59600db8f0..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_token.py +++ /dev/null @@ -1,33 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from abc import abstractmethod -from typing import Any, Mapping - -from requests.auth import AuthBase - - -class AbstractHeaderAuthenticator(AuthBase): - """Abstract class for an header-based authenticators that add a header to outgoing HTTP requests.""" - - def __call__(self, request): - """Attach the HTTP headers required to authenticate on the HTTP request""" - request.headers.update(self.get_auth_header()) - return request - - def get_auth_header(self) -> Mapping[str, Any]: - """The header to set on outgoing HTTP requests""" - if self.auth_header: - return {self.auth_header: self.token} - return {} - - @property - @abstractmethod - def auth_header(self) -> str: - """HTTP header to set on the requests""" - - @property - @abstractmethod - def token(self) -> str: - """The header value to set on outgoing HTTP requests""" diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py deleted file mode 100644 index 1728f4099797..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py +++ /dev/null @@ -1,258 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, List, Mapping, Optional, Sequence, Tuple, Union - -import dpath -import pendulum -from airbyte_cdk.config_observation import create_connector_config_control_message, emit_configuration_as_airbyte_control_message -from airbyte_cdk.sources.message import MessageRepository, NoopMessageRepository -from airbyte_cdk.sources.streams.http.requests_native_auth.abstract_oauth import AbstractOauth2Authenticator - - -class Oauth2Authenticator(AbstractOauth2Authenticator): - """ - Generates OAuth2.0 access tokens from an OAuth2.0 refresh token and client credentials. - The generated access token is attached to each request via the Authorization header. - If a connector_config is provided any mutation of it's value in the scope of this class will emit AirbyteControlConnectorConfigMessage. - """ - - def __init__( - self, - token_refresh_endpoint: str, - client_id: str, - client_secret: str, - refresh_token: str, - scopes: List[str] = None, - token_expiry_date: pendulum.DateTime = None, - token_expiry_date_format: str = None, - access_token_name: str = "access_token", - expires_in_name: str = "expires_in", - refresh_request_body: Mapping[str, Any] = None, - grant_type: str = "refresh_token", - token_expiry_is_time_of_expiration: bool = False, - refresh_token_error_status_codes: Tuple[int, ...] = (), - refresh_token_error_key: str = "", - refresh_token_error_values: Tuple[str, ...] = (), - ): - self._token_refresh_endpoint = token_refresh_endpoint - self._client_secret = client_secret - self._client_id = client_id - self._refresh_token = refresh_token - self._scopes = scopes - self._access_token_name = access_token_name - self._expires_in_name = expires_in_name - self._refresh_request_body = refresh_request_body - self._grant_type = grant_type - - self._token_expiry_date = token_expiry_date or pendulum.now().subtract(days=1) - self._token_expiry_date_format = token_expiry_date_format - self._token_expiry_is_time_of_expiration = token_expiry_is_time_of_expiration - self._access_token = None - super().__init__(refresh_token_error_status_codes, refresh_token_error_key, refresh_token_error_values) - - def get_token_refresh_endpoint(self) -> str: - return self._token_refresh_endpoint - - def get_client_id(self) -> str: - return self._client_id - - def get_client_secret(self) -> str: - return self._client_secret - - def get_refresh_token(self) -> str: - return self._refresh_token - - def get_access_token_name(self) -> str: - return self._access_token_name - - def get_scopes(self) -> [str]: - return self._scopes - - def get_expires_in_name(self) -> str: - return self._expires_in_name - - def get_refresh_request_body(self) -> Mapping[str, Any]: - return self._refresh_request_body - - def get_grant_type(self) -> str: - return self._grant_type - - def get_token_expiry_date(self) -> pendulum.DateTime: - return self._token_expiry_date - - def set_token_expiry_date(self, value: Union[str, int]): - self._token_expiry_date = self._parse_token_expiration_date(value) - - @property - def token_expiry_is_time_of_expiration(self) -> bool: - return self._token_expiry_is_time_of_expiration - - @property - def token_expiry_date_format(self) -> Optional[str]: - return self._token_expiry_date_format - - @property - def access_token(self) -> str: - return self._access_token - - @access_token.setter - def access_token(self, value: str): - self._access_token = value - - -class SingleUseRefreshTokenOauth2Authenticator(Oauth2Authenticator): - """ - Authenticator that should be used for API implementing single use refresh tokens: - when refreshing access token some API returns a new refresh token that needs to used in the next refresh flow. - This authenticator updates the configuration with new refresh token by emitting Airbyte control message from an observed mutation. - By default, this authenticator expects a connector config with a "credentials" field with the following nested fields: client_id, - client_secret, refresh_token. This behavior can be changed by defining custom config path (using dpath paths) in client_id_config_path, - client_secret_config_path, refresh_token_config_path constructor arguments. - """ - - def __init__( - self, - connector_config: Mapping[str, Any], - token_refresh_endpoint: str, - scopes: List[str] = None, - access_token_name: str = "access_token", - expires_in_name: str = "expires_in", - refresh_token_name: str = "refresh_token", - refresh_request_body: Mapping[str, Any] = None, - grant_type: str = "refresh_token", - client_id: Optional[str] = None, - client_secret: Optional[str] = None, - access_token_config_path: Sequence[str] = ("credentials", "access_token"), - refresh_token_config_path: Sequence[str] = ("credentials", "refresh_token"), - token_expiry_date_config_path: Sequence[str] = ("credentials", "token_expiry_date"), - token_expiry_date_format: Optional[str] = None, - message_repository: MessageRepository = NoopMessageRepository(), - token_expiry_is_time_of_expiration: bool = False, - refresh_token_error_status_codes: Tuple[int, ...] = (), - refresh_token_error_key: str = "", - refresh_token_error_values: Tuple[str, ...] = (), - ): - """ - Args: - connector_config (Mapping[str, Any]): The full connector configuration - token_refresh_endpoint (str): Full URL to the token refresh endpoint - scopes (List[str], optional): List of OAuth scopes to pass in the refresh token request body. Defaults to None. - access_token_name (str, optional): Name of the access token field, used to parse the refresh token response. Defaults to "access_token". - expires_in_name (str, optional): Name of the name of the field that characterizes when the current access token will expire, used to parse the refresh token response. Defaults to "expires_in". - refresh_token_name (str, optional): Name of the name of the refresh token field, used to parse the refresh token response. Defaults to "refresh_token". - refresh_request_body (Mapping[str, Any], optional): Custom key value pair that will be added to the refresh token request body. Defaults to None. - grant_type (str, optional): OAuth grant type. Defaults to "refresh_token". - client_id (Optional[str]): The client id to authenticate. If not specified, defaults to credentials.client_id in the config object. - client_secret (Optional[str]): The client secret to authenticate. If not specified, defaults to credentials.client_secret in the config object. - access_token_config_path (Sequence[str]): Dpath to the access_token field in the connector configuration. Defaults to ("credentials", "access_token"). - refresh_token_config_path (Sequence[str]): Dpath to the refresh_token field in the connector configuration. Defaults to ("credentials", "refresh_token"). - token_expiry_date_config_path (Sequence[str]): Dpath to the token_expiry_date field in the connector configuration. Defaults to ("credentials", "token_expiry_date"). - token_expiry_date_format (Optional[str]): Date format of the token expiry date field (set by expires_in_name). If not specified the token expiry date is interpreted as number of seconds until expiration. - token_expiry_is_time_of_expiration bool: set True it if expires_in is returned as time of expiration instead of the number seconds until expiration - message_repository (MessageRepository): the message repository used to emit logs on HTTP requests and control message on config update - """ - self._client_id = client_id if client_id is not None else dpath.get(connector_config, ("credentials", "client_id")) - self._client_secret = client_secret if client_secret is not None else dpath.get(connector_config, ("credentials", "client_secret")) - self._access_token_config_path = access_token_config_path - self._refresh_token_config_path = refresh_token_config_path - self._token_expiry_date_config_path = token_expiry_date_config_path - self._token_expiry_date_format = token_expiry_date_format - self._refresh_token_name = refresh_token_name - self._connector_config = connector_config - self.__message_repository = message_repository - super().__init__( - token_refresh_endpoint, - self.get_client_id(), - self.get_client_secret(), - self.get_refresh_token(), - scopes=scopes, - token_expiry_date=self.get_token_expiry_date(), - access_token_name=access_token_name, - expires_in_name=expires_in_name, - refresh_request_body=refresh_request_body, - grant_type=grant_type, - token_expiry_date_format=token_expiry_date_format, - token_expiry_is_time_of_expiration=token_expiry_is_time_of_expiration, - refresh_token_error_status_codes=refresh_token_error_status_codes, - refresh_token_error_key=refresh_token_error_key, - refresh_token_error_values=refresh_token_error_values, - ) - - def get_refresh_token_name(self) -> str: - return self._refresh_token_name - - def get_client_id(self) -> str: - return self._client_id - - def get_client_secret(self) -> str: - return self._client_secret - - @property - def access_token(self) -> str: - return dpath.get(self._connector_config, self._access_token_config_path, default="") - - @access_token.setter - def access_token(self, new_access_token: str): - dpath.new(self._connector_config, self._access_token_config_path, new_access_token) - - def get_refresh_token(self) -> str: - return dpath.get(self._connector_config, self._refresh_token_config_path, default="") - - def set_refresh_token(self, new_refresh_token: str): - dpath.new(self._connector_config, self._refresh_token_config_path, new_refresh_token) - - def get_token_expiry_date(self) -> pendulum.DateTime: - expiry_date = dpath.get(self._connector_config, self._token_expiry_date_config_path, default="") - return pendulum.now().subtract(days=1) if expiry_date == "" else pendulum.parse(expiry_date) - - def set_token_expiry_date(self, new_token_expiry_date): - dpath.new(self._connector_config, self._token_expiry_date_config_path, str(new_token_expiry_date)) - - def token_has_expired(self) -> bool: - """Returns True if the token is expired""" - return pendulum.now("UTC") > self.get_token_expiry_date() - - @staticmethod - def get_new_token_expiry_date(access_token_expires_in: str, token_expiry_date_format: str = None) -> pendulum.DateTime: - if token_expiry_date_format: - return pendulum.from_format(access_token_expires_in, token_expiry_date_format) - else: - return pendulum.now("UTC").add(seconds=int(access_token_expires_in)) - - def get_access_token(self) -> str: - """Retrieve new access and refresh token if the access token has expired. - The new refresh token is persisted with the set_refresh_token function - Returns: - str: The current access_token, updated if it was previously expired. - """ - if self.token_has_expired(): - new_access_token, access_token_expires_in, new_refresh_token = self.refresh_access_token() - new_token_expiry_date = self.get_new_token_expiry_date(access_token_expires_in, self._token_expiry_date_format) - self.access_token = new_access_token - self.set_refresh_token(new_refresh_token) - self.set_token_expiry_date(new_token_expiry_date) - # FIXME emit_configuration_as_airbyte_control_message as been deprecated in favor of package airbyte_cdk.sources.message - # Usually, a class shouldn't care about the implementation details but to keep backward compatibility where we print the - # message directly in the console, this is needed - if not isinstance(self._message_repository, NoopMessageRepository): - self._message_repository.emit_message(create_connector_config_control_message(self._connector_config)) - else: - emit_configuration_as_airbyte_control_message(self._connector_config) - return self.access_token - - def refresh_access_token(self) -> Tuple[str, str, str]: - response_json = self._get_refresh_access_token_response() - return ( - response_json[self.get_access_token_name()], - response_json[self.get_expires_in_name()], - response_json[self.get_refresh_token_name()], - ) - - @property - def _message_repository(self) -> MessageRepository: - """ - Overriding AbstractOauth2Authenticator._message_repository to allow for HTTP request logs - """ - return self.__message_repository diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/token.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/token.py deleted file mode 100644 index becfe8108f24..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/token.py +++ /dev/null @@ -1,73 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import base64 -from itertools import cycle -from typing import List - -from airbyte_cdk.sources.streams.http.requests_native_auth.abstract_token import AbstractHeaderAuthenticator - - -class MultipleTokenAuthenticator(AbstractHeaderAuthenticator): - """ - Builds auth header, based on the list of tokens provided. - Auth header is changed per each `get_auth_header` call, using each token in cycle. - The token is attached to each request via the `auth_header` header. - """ - - @property - def auth_header(self) -> str: - return self._auth_header - - @property - def token(self) -> str: - return f"{self._auth_method} {next(self._tokens_iter)}" - - def __init__(self, tokens: List[str], auth_method: str = "Bearer", auth_header: str = "Authorization"): - self._auth_method = auth_method - self._auth_header = auth_header - self._tokens = tokens - self._tokens_iter = cycle(self._tokens) - - -class TokenAuthenticator(AbstractHeaderAuthenticator): - """ - Builds auth header, based on the token provided. - The token is attached to each request via the `auth_header` header. - """ - - @property - def auth_header(self) -> str: - return self._auth_header - - @property - def token(self) -> str: - return f"{self._auth_method} {self._token}" - - def __init__(self, token: str, auth_method: str = "Bearer", auth_header: str = "Authorization"): - self._auth_header = auth_header - self._auth_method = auth_method - self._token = token - - -class BasicHttpAuthenticator(AbstractHeaderAuthenticator): - """ - Builds auth based off the basic authentication scheme as defined by RFC 7617, which transmits credentials as USER ID/password pairs, encoded using bas64 - https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#basic_authentication_scheme - """ - - @property - def auth_header(self) -> str: - return self._auth_header - - @property - def token(self) -> str: - return f"{self._auth_method} {self._token}" - - def __init__(self, username: str, password: str = "", auth_method: str = "Basic", auth_header: str = "Authorization"): - auth_string = f"{username}:{password}".encode("utf8") - b64_encoded = base64.b64encode(auth_string).decode("utf8") - self._auth_header = auth_header - self._auth_method = auth_method - self._token = b64_encoded diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/utils/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/utils/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/utils/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/airbyte_cdk/sources/types.py b/airbyte-cdk/python/airbyte_cdk/sources/types.py deleted file mode 100644 index 6659c8dd767c..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/types.py +++ /dev/null @@ -1,137 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from __future__ import annotations - -from typing import Any, ItemsView, Iterator, KeysView, List, Mapping, Optional, ValuesView - -# A FieldPointer designates a path to a field inside a mapping. For example, retrieving ["k1", "k1.2"] in the object {"k1" :{"k1.2": -# "hello"}] returns "hello" -FieldPointer = List[str] -Config = Mapping[str, Any] -ConnectionDefinition = Mapping[str, Any] -StreamState = Mapping[str, Any] - - -class Record(Mapping[str, Any]): - def __init__(self, data: Mapping[str, Any], associated_slice: Optional[StreamSlice]): - self._data = data - self._associated_slice = associated_slice - - @property - def data(self) -> Mapping[str, Any]: - return self._data - - @property - def associated_slice(self) -> Optional[StreamSlice]: - return self._associated_slice - - def __repr__(self) -> str: - return repr(self._data) - - def __getitem__(self, key: str) -> Any: - return self._data[key] - - def __len__(self) -> int: - return len(self._data) - - def __iter__(self) -> Any: - return iter(self._data) - - def __contains__(self, item: object) -> bool: - return item in self._data - - def __eq__(self, other: object) -> bool: - if isinstance(other, Record): - # noinspection PyProtectedMember - return self._data == other._data - return False - - def __ne__(self, other: object) -> bool: - return not self.__eq__(other) - - -class StreamSlice(Mapping[str, Any]): - def __init__( - self, *, partition: Mapping[str, Any], cursor_slice: Mapping[str, Any], extra_fields: Optional[Mapping[str, Any]] = None - ) -> None: - """ - :param partition: The partition keys representing a unique partition in the stream. - :param cursor_slice: The incremental cursor slice keys, such as dates or pagination tokens. - :param extra_fields: Additional fields that should not be part of the partition but passed along, such as metadata from the parent stream. - """ - self._partition = partition - self._cursor_slice = cursor_slice - self._extra_fields = extra_fields or {} - - # Ensure that partition keys do not overlap with cursor slice keys - if partition.keys() & cursor_slice.keys(): - raise ValueError("Keys for partition and incremental sync cursor should not overlap") - - self._stream_slice = dict(partition) | dict(cursor_slice) - - @property - def partition(self) -> Mapping[str, Any]: - """Returns the partition portion of the stream slice.""" - p = self._partition - while isinstance(p, StreamSlice): - p = p.partition - return p - - @property - def cursor_slice(self) -> Mapping[str, Any]: - """Returns the cursor slice portion of the stream slice.""" - c = self._cursor_slice - while isinstance(c, StreamSlice): - c = c.cursor_slice - return c - - @property - def extra_fields(self) -> Mapping[str, Any]: - """Returns the extra fields that are not part of the partition.""" - return self._extra_fields - - def __repr__(self) -> str: - return repr(self._stream_slice) - - def __setitem__(self, key: str, value: Any) -> None: - raise ValueError("StreamSlice is immutable") - - def __getitem__(self, key: str) -> Any: - return self._stream_slice[key] - - def __len__(self) -> int: - return len(self._stream_slice) - - def __iter__(self) -> Iterator[str]: - return iter(self._stream_slice) - - def __contains__(self, item: Any) -> bool: - return item in self._stream_slice - - def keys(self) -> KeysView[str]: - return self._stream_slice.keys() - - def items(self) -> ItemsView[str, Any]: - return self._stream_slice.items() - - def values(self) -> ValuesView[Any]: - return self._stream_slice.values() - - def get(self, key: str, default: Any = None) -> Optional[Any]: - return self._stream_slice.get(key, default) - - def __eq__(self, other: Any) -> bool: - if isinstance(other, dict): - return self._stream_slice == other - if isinstance(other, StreamSlice): - # noinspection PyProtectedMember - return self._partition == other._partition and self._cursor_slice == other._cursor_slice - return False - - def __ne__(self, other: Any) -> bool: - return not self.__eq__(other) - - def __json_serializable__(self) -> Any: - return self._stream_slice diff --git a/airbyte-cdk/python/airbyte_cdk/sources/utils/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/utils/__init__.py deleted file mode 100644 index b609a6c7a540..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/utils/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -# Initialize Utils Package - -__all__ = ["record_helper"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/utils/casing.py b/airbyte-cdk/python/airbyte_cdk/sources/utils/casing.py deleted file mode 100644 index 806e077ae00c..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/utils/casing.py +++ /dev/null @@ -1,12 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import re - - -# https://stackoverflow.com/a/1176023 -def camel_to_snake(s: str) -> str: - s = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", s) - return re.sub("([a-z0-9])([A-Z])", r"\1_\2", s).lower() diff --git a/airbyte-cdk/python/airbyte_cdk/sources/utils/record_helper.py b/airbyte-cdk/python/airbyte_cdk/sources/utils/record_helper.py deleted file mode 100644 index ec92ac2f9645..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/utils/record_helper.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import time -from collections.abc import Mapping as ABCMapping -from typing import Any, Mapping, Optional - -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, AirbyteRecordMessage, AirbyteTraceMessage -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.streams.core import StreamData -from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer - - -def stream_data_to_airbyte_message( - stream_name: str, - data_or_message: StreamData, - transformer: TypeTransformer = TypeTransformer(TransformConfig.NoTransform), - schema: Optional[Mapping[str, Any]] = None, -) -> AirbyteMessage: - if schema is None: - schema = {} - - match data_or_message: - case ABCMapping(): - data = dict(data_or_message) - now_millis = time.time_ns() // 1_000_000 - # Transform object fields according to config. Most likely you will - # need it to normalize values against json schema. By default no action - # taken unless configured. See - # docs/connector-development/cdk-python/schemas.md for details. - transformer.transform(data, schema) # type: ignore - message = AirbyteRecordMessage(stream=stream_name, data=data, emitted_at=now_millis) - return AirbyteMessage(type=MessageType.RECORD, record=message) - case AirbyteTraceMessage(): - return AirbyteMessage(type=MessageType.TRACE, trace=data_or_message) - case AirbyteLogMessage(): - return AirbyteMessage(type=MessageType.LOG, log=data_or_message) - case _: - raise ValueError(f"Unexpected type for data_or_message: {type(data_or_message)}: {data_or_message}") diff --git a/airbyte-cdk/python/airbyte_cdk/sources/utils/schema_helpers.py b/airbyte-cdk/python/airbyte_cdk/sources/utils/schema_helpers.py deleted file mode 100644 index 7eef091aa02b..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/utils/schema_helpers.py +++ /dev/null @@ -1,223 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import importlib -import json -import os -import pkgutil -from typing import Any, ClassVar, Dict, List, Mapping, MutableMapping, Optional, Tuple - -import jsonref -from airbyte_cdk.models import ConnectorSpecification, FailureType -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from jsonschema import RefResolver, validate -from jsonschema.exceptions import ValidationError -from pydantic.v1 import BaseModel, Field - - -class JsonFileLoader: - """ - Custom json file loader to resolve references to resources located in "shared" directory. - We need this for compatability with existing schemas cause all of them have references - pointing to shared_schema.json file instead of shared/shared_schema.json - """ - - def __init__(self, uri_base: str, shared: str): - self.shared = shared - self.uri_base = uri_base - - def __call__(self, uri: str) -> Dict[str, Any]: - uri = uri.replace(self.uri_base, f"{self.uri_base}/{self.shared}/") - with open(uri) as f: - data = json.load(f) - if isinstance(data, dict): - return data - else: - raise ValueError(f"Expected to read a dictionary from {uri}. Got: {data}") - - -def resolve_ref_links(obj: Any) -> Any: - """ - Scan resolved schema and convert jsonref.JsonRef object to JSON serializable dict. - - :param obj - jsonschema object with ref field resolved. - :return JSON serializable object with references without external dependencies. - """ - if isinstance(obj, jsonref.JsonRef): - obj = resolve_ref_links(obj.__subject__) - # Omit existing definitions for external resource since - # we dont need it anymore. - if isinstance(obj, dict): - obj.pop("definitions", None) - return obj - else: - raise ValueError(f"Expected obj to be a dict. Got {obj}") - elif isinstance(obj, dict): - return {k: resolve_ref_links(v) for k, v in obj.items()} - elif isinstance(obj, list): - return [resolve_ref_links(item) for item in obj] - else: - return obj - - -def _expand_refs(schema: Any, ref_resolver: Optional[RefResolver] = None) -> None: - """Internal function to iterate over schema and replace all occurrences of $ref with their definitions. Recursive. - - :param schema: schema that will be patched - :param ref_resolver: resolver to get definition from $ref, if None pass it will be instantiated - """ - ref_resolver = ref_resolver or RefResolver.from_schema(schema) - - if isinstance(schema, MutableMapping): - if "$ref" in schema: - ref_url = schema.pop("$ref") - _, definition = ref_resolver.resolve(ref_url) - _expand_refs(definition, ref_resolver=ref_resolver) # expand refs in definitions as well - schema.update(definition) - else: - for key, value in schema.items(): - _expand_refs(value, ref_resolver=ref_resolver) - elif isinstance(schema, List): - for value in schema: - _expand_refs(value, ref_resolver=ref_resolver) - - -def expand_refs(schema: Any) -> None: - """Iterate over schema and replace all occurrences of $ref with their definitions. - - :param schema: schema that will be patched - """ - _expand_refs(schema) - schema.pop("definitions", None) # remove definitions created by $ref - - -def rename_key(schema: Any, old_key: str, new_key: str) -> None: - """Iterate over nested dictionary and replace one key with another. Used to replace anyOf with oneOf. Recursive." - - :param schema: schema that will be patched - :param old_key: name of the key to replace - :param new_key: new name of the key - """ - if not isinstance(schema, MutableMapping): - return - - for key, value in schema.items(): - rename_key(value, old_key, new_key) - if old_key in schema: - schema[new_key] = schema.pop(old_key) - - -class ResourceSchemaLoader: - """JSONSchema loader from package resources""" - - def __init__(self, package_name: str): - self.package_name = package_name - - def get_schema(self, name: str) -> dict[str, Any]: - """ - This method retrieves a JSON schema from the schemas/ folder. - - - The expected file structure is to have all top-level schemas (corresponding to streams) in the "schemas/" folder, with any shared $refs - living inside the "schemas/shared/" folder. For example: - - schemas/shared/.json - schemas/.json # contains a $ref to shared_definition - schemas/.json # contains a $ref to shared_definition - """ - - schema_filename = f"schemas/{name}.json" - raw_file = pkgutil.get_data(self.package_name, schema_filename) - if not raw_file: - raise IOError(f"Cannot find file {schema_filename}") - try: - raw_schema = json.loads(raw_file) - except ValueError as err: - raise RuntimeError(f"Invalid JSON file format for file {schema_filename}") from err - - return self._resolve_schema_references(raw_schema) - - def _resolve_schema_references(self, raw_schema: dict[str, Any]) -> dict[str, Any]: - """ - Resolve links to external references and move it to local "definitions" map. - - :param raw_schema jsonschema to lookup for external links. - :return JSON serializable object with references without external dependencies. - """ - - package = importlib.import_module(self.package_name) - if package.__file__: - base = os.path.dirname(package.__file__) + "/" - else: - raise ValueError(f"Package {package} does not have a valid __file__ field") - resolved = jsonref.JsonRef.replace_refs(raw_schema, loader=JsonFileLoader(base, "schemas/shared"), base_uri=base) - resolved = resolve_ref_links(resolved) - if isinstance(resolved, dict): - return resolved - else: - raise ValueError(f"Expected resolved to be a dict. Got {resolved}") - - -def check_config_against_spec_or_exit(config: Mapping[str, Any], spec: ConnectorSpecification) -> None: - """ - Check config object against spec. In case of spec is invalid, throws - an exception with validation error description. - - :param config - config loaded from file specified over command line - :param spec - spec object generated by connector - """ - spec_schema = spec.connectionSpecification - try: - validate(instance=config, schema=spec_schema) - except ValidationError as validation_error: - raise AirbyteTracedException( - message="Config validation error: " + validation_error.message, - internal_message=validation_error.message, - failure_type=FailureType.config_error, - ) from None # required to prevent logging config secrets from the ValidationError's stacktrace - - -class InternalConfig(BaseModel): - KEYWORDS: ClassVar[set[str]] = {"_limit", "_page_size"} - limit: int = Field(None, alias="_limit") - page_size: int = Field(None, alias="_page_size") - - def dict(self, *args: Any, **kwargs: Any) -> dict[str, Any]: - kwargs["by_alias"] = True - kwargs["exclude_unset"] = True - return super().dict(*args, **kwargs) # type: ignore[no-any-return] - - def is_limit_reached(self, records_counter: int) -> bool: - """ - Check if record count reached limit set by internal config. - :param records_counter - number of records already red - :return True if limit reached, False otherwise - """ - if self.limit: - if records_counter >= self.limit: - return True - return False - - -def split_config(config: Mapping[str, Any]) -> Tuple[dict[str, Any], InternalConfig]: - """ - Break config map object into 2 instances: first is a dict with user defined - configuration and second is internal config that contains private keys for - acceptance test configuration. - - :param - config - Dict object that has been loaded from config file. - - :return tuple of user defined config dict with filtered out internal - parameters and connector acceptance test internal config object. - """ - main_config = {} - internal_config = {} - for k, v in config.items(): - if k in InternalConfig.KEYWORDS: - internal_config[k] = v - else: - main_config[k] = v - return main_config, InternalConfig.parse_obj(internal_config) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/utils/slice_logger.py b/airbyte-cdk/python/airbyte_cdk/sources/utils/slice_logger.py deleted file mode 100644 index 6981cdde88fa..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/utils/slice_logger.py +++ /dev/null @@ -1,54 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import logging -from abc import ABC, abstractmethod -from typing import Any, Mapping, Optional - -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, Level -from airbyte_cdk.models import Type as MessageType - - -class SliceLogger(ABC): - """ - SliceLogger is an interface that allows us to log slices of data in a uniform way. - It is responsible for determining whether or not a slice should be logged and for creating the log message. - """ - - SLICE_LOG_PREFIX = "slice:" - - def create_slice_log_message(self, _slice: Optional[Mapping[str, Any]]) -> AirbyteMessage: - """ - Mapping is an interface that can be implemented in various ways. However, json.dumps will just do a `str()` if - the slice is a class implementing Mapping. Therefore, we want to cast this as a dict before passing this to json.dump - """ - printable_slice = dict(_slice) if _slice else _slice - return AirbyteMessage( - type=MessageType.LOG, - log=AirbyteLogMessage(level=Level.INFO, message=f"{SliceLogger.SLICE_LOG_PREFIX}{json.dumps(printable_slice, default=str)}"), - ) - - @abstractmethod - def should_log_slice_message(self, logger: logging.Logger) -> bool: - """ - - :param logger: - :return: - """ - - -class DebugSliceLogger(SliceLogger): - def should_log_slice_message(self, logger: logging.Logger) -> bool: - """ - - :param logger: - :return: - """ - return logger.isEnabledFor(logging.DEBUG) - - -class AlwaysLogSliceLogger(SliceLogger): - def should_log_slice_message(self, logger: logging.Logger) -> bool: - return True diff --git a/airbyte-cdk/python/airbyte_cdk/sources/utils/transform.py b/airbyte-cdk/python/airbyte_cdk/sources/utils/transform.py deleted file mode 100644 index b15ff11db84a..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/utils/transform.py +++ /dev/null @@ -1,196 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from distutils.util import strtobool -from enum import Flag, auto -from typing import Any, Callable, Dict, Mapping, Optional - -from jsonschema import Draft7Validator, ValidationError, validators - -json_to_python_simple = {"string": str, "number": float, "integer": int, "boolean": bool, "null": type(None)} -json_to_python = {**json_to_python_simple, **{"object": dict, "array": list}} -python_to_json = {v: k for k, v in json_to_python.items()} - -logger = logging.getLogger("airbyte") - - -class TransformConfig(Flag): - """ - TypeTransformer class config. Configs can be combined using bitwise or operator e.g. - ``` - TransformConfig.DefaultSchemaNormalization | TransformConfig.CustomSchemaNormalization - ``` - """ - - # No action taken, default behaviour. Cannot be combined with any other options. - NoTransform = auto() - # Applies default type casting with default_convert method which converts - # values by applying simple type casting to specified jsonschema type. - DefaultSchemaNormalization = auto() - # Allow registering custom type transformation callback. Can be combined - # with DefaultSchemaNormalization. In this case default type casting would - # be applied before custom one. - CustomSchemaNormalization = auto() - - -class TypeTransformer: - """ - Class for transforming object before output. - """ - - _custom_normalizer: Optional[Callable[[Any, Dict[str, Any]], Any]] = None - - def __init__(self, config: TransformConfig): - """ - Initialize TypeTransformer instance. - :param config Transform config that would be applied to object - """ - if TransformConfig.NoTransform in config and config != TransformConfig.NoTransform: - raise Exception("NoTransform option cannot be combined with other flags.") - self._config = config - all_validators = { - key: self.__get_normalizer(key, orig_validator) - for key, orig_validator in Draft7Validator.VALIDATORS.items() - # Do not validate field we do not transform for maximum performance. - if key in ["type", "array", "$ref", "properties", "items"] - } - self._normalizer = validators.create(meta_schema=Draft7Validator.META_SCHEMA, validators=all_validators) - - def registerCustomTransform(self, normalization_callback: Callable[[Any, Dict[str, Any]], Any]) -> Callable: - """ - Register custom normalization callback. - :param normalization_callback function to be used for value - normalization. Takes original value and part type schema. Should return - normalized value. See docs/connector-development/cdk-python/schemas.md - for details. - :return Same callbeck, this is usefull for using registerCustomTransform function as decorator. - """ - if TransformConfig.CustomSchemaNormalization not in self._config: - raise Exception("Please set TransformConfig.CustomSchemaNormalization config before registering custom normalizer") - self._custom_normalizer = normalization_callback - return normalization_callback - - def __normalize(self, original_item: Any, subschema: Dict[str, Any]) -> Any: - """ - Applies different transform function to object's field according to config. - :param original_item original value of field. - :param subschema part of the jsonschema containing field type/format data. - :return Final field value. - """ - if TransformConfig.DefaultSchemaNormalization in self._config: - original_item = self.default_convert(original_item, subschema) - - if self._custom_normalizer: - original_item = self._custom_normalizer(original_item, subschema) - return original_item - - @staticmethod - def default_convert(original_item: Any, subschema: Dict[str, Any]) -> Any: - """ - Default transform function that is used when TransformConfig.DefaultSchemaNormalization flag set. - :param original_item original value of field. - :param subschema part of the jsonschema containing field type/format data. - :return transformed field value. - """ - target_type = subschema.get("type", []) - if original_item is None and "null" in target_type: - return None - if isinstance(target_type, list): - # jsonschema type could either be a single string or array of type - # strings. In case if there is some disambigous and more than one - # type (except null) do not do any conversion and return original - # value. If type array has one type and null i.e. {"type": - # ["integer", "null"]}, convert value to specified type. - target_type = [t for t in target_type if t != "null"] - if len(target_type) != 1: - return original_item - target_type = target_type[0] - try: - if target_type == "string": - return str(original_item) - elif target_type == "number": - return float(original_item) - elif target_type == "integer": - return int(original_item) - elif target_type == "boolean": - if isinstance(original_item, str): - return strtobool(original_item) == 1 - return bool(original_item) - elif target_type == "array": - item_types = set(subschema.get("items", {}).get("type", set())) - if item_types.issubset(json_to_python_simple) and type(original_item) in json_to_python_simple.values(): - return [original_item] - except (ValueError, TypeError): - return original_item - return original_item - - def __get_normalizer(self, schema_key: str, original_validator: Callable): - """ - Traverse through object fields using native jsonschema validator and apply normalization function. - :param schema_key related json schema key that currently being validated/normalized. - :original_validator: native jsonschema validator callback. - """ - - def normalizator(validator_instance: Callable, property_value: Any, instance: Any, schema: Dict[str, Any]): - """ - Jsonschema validator callable it uses for validating instance. We - override default Draft7Validator to perform value transformation - before validation take place. We do not take any action except - logging warn if object does not conform to json schema, just using - jsonschema algorithm to traverse through object fields. - Look - https://python-jsonschema.readthedocs.io/en/stable/creating/?highlight=validators.create#jsonschema.validators.create - validators parameter for detailed description. - : - """ - - def resolve(subschema): - if "$ref" in subschema: - _, resolved = validator_instance.resolver.resolve(subschema["$ref"]) - return resolved - return subschema - - # Transform object and array values before running json schema type checking for each element. - # Recursively normalize every value of the "instance" sub-object, - # if "instance" is an incorrect type - skip recursive normalization of "instance" - if schema_key == "properties" and isinstance(instance, dict): - for k, subschema in property_value.items(): - if k in instance: - subschema = resolve(subschema) - instance[k] = self.__normalize(instance[k], subschema) - # Recursively normalize every item of the "instance" sub-array, - # if "instance" is an incorrect type - skip recursive normalization of "instance" - elif schema_key == "items" and isinstance(instance, list): - subschema = resolve(property_value) - for index, item in enumerate(instance): - instance[index] = self.__normalize(item, subschema) - - # Running native jsonschema traverse algorithm after field normalization is done. - yield from original_validator(validator_instance, property_value, instance, schema) - - return normalizator - - def transform(self, record: Dict[str, Any], schema: Mapping[str, Any]): - """ - Normalize and validate according to config. - :param record: record instance for normalization/transformation. All modification are done by modifying existent object. - :param schema: object's jsonschema for normalization. - """ - if TransformConfig.NoTransform in self._config: - return - normalizer = self._normalizer(schema) - for e in normalizer.iter_errors(record): - """ - just calling normalizer.validate() would throw an exception on - first validation occurences and stop processing rest of schema. - """ - logger.warning(self.get_error_message(e)) - - def get_error_message(self, e: ValidationError) -> str: - instance_json_type = python_to_json[type(e.instance)] - key_path = "." + ".".join(map(str, e.path)) - return ( - f"Failed to transform value {repr(e.instance)} of type '{instance_json_type}' to '{e.validator_value}', key path: '{key_path}'" - ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/utils/types.py b/airbyte-cdk/python/airbyte_cdk/sources/utils/types.py deleted file mode 100644 index 9dc5e253bf29..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sources/utils/types.py +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Union - -JsonType = Union[dict[str, "JsonType"], list["JsonType"], str, int, float, bool, None] diff --git a/airbyte-cdk/python/airbyte_cdk/sql/__init__.py b/airbyte-cdk/python/airbyte_cdk/sql/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/airbyte_cdk/sql/_processors/__init__.py b/airbyte-cdk/python/airbyte_cdk/sql/_processors/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/airbyte_cdk/sql/_processors/duckdb.py b/airbyte-cdk/python/airbyte_cdk/sql/_processors/duckdb.py deleted file mode 100644 index 3f3f1a5ed319..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sql/_processors/duckdb.py +++ /dev/null @@ -1,296 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -"""A DuckDB implementation of the cache.""" - -from __future__ import annotations - -import logging -import warnings -from pathlib import Path -from typing import TYPE_CHECKING, Any, Dict, List, Literal - -import pyarrow as pa -from airbyte_cdk import DestinationSyncMode -from airbyte_cdk.sql import exceptions as exc -from airbyte_cdk.sql.constants import AB_EXTRACTED_AT_COLUMN -from airbyte_cdk.sql.secrets import SecretString -from airbyte_cdk.sql.shared.sql_processor import SqlConfig, SqlProcessorBase, SQLRuntimeError -from duckdb_engine import DuckDBEngineWarning -from overrides import overrides -from pydantic import Field -from sqlalchemy import Executable, TextClause, text -from sqlalchemy.exc import ProgrammingError, SQLAlchemyError - -if TYPE_CHECKING: - from sqlalchemy.engine import Connection, Engine - -logger = logging.getLogger(__name__) - - -# @dataclass -class DuckDBConfig(SqlConfig): - """Configuration for DuckDB.""" - - db_path: Path | str = Field() - """Normally db_path is a Path object. - - The database name will be inferred from the file name. For example, given a `db_path` of - `/path/to/my/duckdb-file`, the database name is `my_db`. - """ - - schema_name: str = Field(default="main") - """The name of the schema to write to. Defaults to "main".""" - - @overrides - def get_sql_alchemy_url(self) -> SecretString: - """Return the SQLAlchemy URL to use.""" - # Suppress warnings from DuckDB about reflection on indices. - # https://github.com/Mause/duckdb_engine/issues/905 - warnings.filterwarnings( - "ignore", - message="duckdb-engine doesn't yet support reflection on indices", - category=DuckDBEngineWarning, - ) - return SecretString(f"duckdb:///{self.db_path!s}") - - @overrides - def get_database_name(self) -> str: - """Return the name of the database.""" - if self.db_path == ":memory:": - return "memory" - - # Split the path on the appropriate separator ("/" or "\") - split_on: Literal["/", "\\"] = "\\" if "\\" in str(self.db_path) else "/" - - # Return the file name without the extension - return str(self.db_path).split(sep=split_on)[-1].split(".")[0] - - def _is_file_based_db(self) -> bool: - """Return whether the database is file-based.""" - if isinstance(self.db_path, Path): - return True - - db_path_str = str(self.db_path) - return ( - ("/" in db_path_str or "\\" in db_path_str) - and db_path_str != ":memory:" - and "md:" not in db_path_str - and "motherduck:" not in db_path_str - ) - - @overrides - def get_sql_engine(self) -> Engine: - """Return the SQL Alchemy engine. - - This method is overridden to ensure that the database parent directory is created if it - doesn't exist. - """ - if self._is_file_based_db(): - Path(self.db_path).parent.mkdir(parents=True, exist_ok=True) - - return super().get_sql_engine() - - -class DuckDBSqlProcessor(SqlProcessorBase): - """A DuckDB implementation of the cache. - - Jsonl is used for local file storage before bulk loading. - Unlike the Snowflake implementation, we can't use the COPY command to load data - so we insert as values instead. - """ - - supports_merge_insert = False - sql_config: DuckDBConfig - - @overrides - def _setup(self) -> None: - """Create the database parent folder if it doesn't yet exist.""" - if self.sql_config.db_path == ":memory:": - return - - Path(self.sql_config.db_path).parent.mkdir(parents=True, exist_ok=True) - - def _create_table_if_not_exists( - self, - table_name: str, - column_definition_str: str, - primary_keys: list[str] | None = None, - ) -> None: - if primary_keys: - pk_str = ", ".join(primary_keys) - column_definition_str += f",\n PRIMARY KEY ({pk_str})" - - cmd = f""" - CREATE TABLE IF NOT EXISTS {self._fully_qualified(table_name)} ( - {column_definition_str} - ) - """ - _ = self._execute_sql(cmd) - - def _do_checkpoint( - self, - connection: Connection | None = None, - ) -> None: - """Checkpoint the given connection. - - We override this method to ensure that the DuckDB WAL is checkpointed explicitly. - Otherwise DuckDB will lazily flush the WAL to disk, which can cause issues for users - who want to manipulate the DB files after writing them. - - For more info: - - https://duckdb.org/docs/sql/statements/checkpoint.html - """ - if connection is not None: - connection.execute(text("CHECKPOINT")) - return - - with self.get_sql_connection() as new_conn: - new_conn.execute(text("CHECKPOINT")) - - def _executemany(self, sql: str | TextClause | Executable, params: list[list[Any]]) -> None: - """Execute the given SQL statement.""" - if isinstance(sql, str): - sql = text(sql) - - with self.get_sql_connection() as conn: - try: - entries = list(params) - conn.engine.pool.connect().executemany(str(sql), entries) # type: ignore - except ( - ProgrammingError, - SQLAlchemyError, - ) as ex: - msg = f"Error when executing SQL:\n{sql}\n{type(ex).__name__}{ex!s}" - raise SQLRuntimeError(msg) from None # from ex - - def _write_with_executemany(self, buffer: Dict[str, Dict[str, List[Any]]], stream_name: str, table_name: str) -> None: - column_names_list = list(buffer[stream_name].keys()) - column_names = ", ".join(column_names_list) - params = ", ".join(["?"] * len(column_names_list)) - sql = f""" - -- Write with executemany - INSERT INTO {self._fully_qualified(table_name)} - ({column_names}) - VALUES ({params}) - """ - entries_to_write = buffer[stream_name] - num_entries = len(entries_to_write[column_names_list[0]]) - parameters = [[entries_to_write[column_name][n] for column_name in column_names_list] for n in range(num_entries)] - self._executemany(sql, parameters) - - def _write_from_pa_table(self, table_name: str, stream_name: str, pa_table: pa.Table) -> None: - full_table_name = self._fully_qualified(table_name) - columns = list(self._get_sql_column_definitions(stream_name).keys()) - if len(columns) != len(pa_table.column_names): - warnings.warn(f"Schema has colums: {columns}, buffer has columns: {pa_table.column_names}") - column_names = ", ".join(pa_table.column_names) - sql = f""" - -- Write from PyArrow table - INSERT INTO {full_table_name} ({column_names}) SELECT {column_names} FROM pa_table - """ - self._execute_sql(sql) - - def _write_temp_table_to_target_table( - self, - stream_name: str, - temp_table_name: str, - final_table_name: str, - sync_mode: DestinationSyncMode, - ) -> None: - """Write the temp table into the final table using the provided write strategy.""" - if sync_mode == DestinationSyncMode.overwrite: - # Note: No need to check for schema compatibility - # here, because we are fully replacing the table. - self._swap_temp_table_with_final_table( - stream_name=stream_name, - temp_table_name=temp_table_name, - final_table_name=final_table_name, - ) - return - - if sync_mode == DestinationSyncMode.append: - self._ensure_compatible_table_schema( - stream_name=stream_name, - table_name=final_table_name, - ) - self._append_temp_table_to_final_table( - stream_name=stream_name, - temp_table_name=temp_table_name, - final_table_name=final_table_name, - ) - return - - if sync_mode == DestinationSyncMode.append_dedup: - self._ensure_compatible_table_schema( - stream_name=stream_name, - table_name=final_table_name, - ) - if not self.supports_merge_insert: - # Fallback to emulated merge if the database does not support merge natively. - self._emulated_merge_temp_table_to_final_table( - stream_name=stream_name, - temp_table_name=temp_table_name, - final_table_name=final_table_name, - ) - return - - self._merge_temp_table_to_final_table( - stream_name=stream_name, - temp_table_name=temp_table_name, - final_table_name=final_table_name, - ) - return - - raise exc.AirbyteInternalError( - message="Sync mode is not supported.", - context={ - "sync_mode": sync_mode, - }, - ) - - def _drop_duplicates(self, table_name: str, stream_name: str) -> str: - primary_keys = self.catalog_provider.get_primary_keys(stream_name) - new_table_name = f"{table_name}_deduped" - if primary_keys: - pks = ", ".join(primary_keys) - sql = f""" - -- Drop duplicates from temp table - CREATE TABLE {self._fully_qualified(new_table_name)} AS ( - SELECT * FROM {self._fully_qualified(table_name)} - QUALIFY row_number() OVER (PARTITION BY ({pks}) ORDER BY {AB_EXTRACTED_AT_COLUMN} DESC) = 1 - ) - """ - self._execute_sql(sql) - return new_table_name - return table_name - - def write_stream_data_from_buffer( - self, - buffer: Dict[str, Dict[str, List[Any]]], - stream_name: str, - sync_mode: DestinationSyncMode, - ) -> None: - temp_table_name = self._create_table_for_loading(stream_name, batch_id=None) - try: - pa_table = pa.Table.from_pydict(buffer[stream_name]) - except Exception: - logger.exception( - "Writing with PyArrow table failed, falling back to writing with executemany. Expect some performance degradation." - ) - self._write_with_executemany(buffer, stream_name, temp_table_name) - else: - # DuckDB will automatically find and SELECT from the `pa_table` - # local variable defined above. - self._write_from_pa_table(temp_table_name, stream_name, pa_table) - - temp_table_name_dedup = self._drop_duplicates(temp_table_name, stream_name) - - try: - self._write_temp_table_to_target_table( - stream_name=stream_name, - temp_table_name=temp_table_name_dedup, - final_table_name=stream_name, - sync_mode=sync_mode, - ) - finally: - self._drop_temp_table(temp_table_name_dedup, if_exists=True) - self._drop_temp_table(temp_table_name, if_exists=True) diff --git a/airbyte-cdk/python/airbyte_cdk/sql/_processors/motherduck.py b/airbyte-cdk/python/airbyte_cdk/sql/_processors/motherduck.py deleted file mode 100644 index 1e3bf0019780..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sql/_processors/motherduck.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -"""A MotherDuck implementation of the cache, built on DuckDB. - -## Usage Example - -```python -from airbyte as ab -from airbyte.caches import MotherDuckCache - -cache = MotherDuckCache( - database="mydatabase", - schema_name="myschema", - api_key=ab.get_secret("MOTHERDUCK_API_KEY"), -) -""" - -from __future__ import annotations - -import warnings - -from airbyte_cdk.sql._processors.duckdb import DuckDBConfig, DuckDBSqlProcessor -from airbyte_cdk.sql.secrets import SecretString -from duckdb_engine import DuckDBEngineWarning -from overrides import overrides -from pydantic import Field - -# Suppress warnings from DuckDB about reflection on indices. -# https://github.com/Mause/duckdb_engine/issues/905 -warnings.filterwarnings( - "ignore", - message="duckdb-engine doesn't yet support reflection on indices", - category=DuckDBEngineWarning, -) - - -class MotherDuckConfig(DuckDBConfig): - """Configuration for the MotherDuck cache.""" - - database: str = Field() - api_key: SecretString = Field() - db_path: str = Field(default="md:") - custom_user_agent: str = Field(default="airbyte") - - @overrides - def get_sql_alchemy_url(self) -> SecretString: - """Return the SQLAlchemy URL to use.""" - # Suppress warnings from DuckDB about reflection on indices. - # https://github.com/Mause/duckdb_engine/issues/905 - warnings.filterwarnings( - "ignore", - message="duckdb-engine doesn't yet support reflection on indices", - category=DuckDBEngineWarning, - ) - - return SecretString( - f"duckdb:///md:{self.database}?motherduck_token={self.api_key}" - f"&custom_user_agent={self.custom_user_agent}" - # Not sure why this doesn't work. We have to override later in the flow. - # f"&schema={self.schema_name}" - ) - - @overrides - def get_database_name(self) -> str: - """Return the name of the database.""" - return self.database - - -class MotherDuckSqlProcessor(DuckDBSqlProcessor): - """A cache implementation for MotherDuck.""" - - supports_merge_insert = False - - @overrides - def _setup(self) -> None: - """Do any necessary setup, if applicable. - - Note: The DuckDB parent class requires pre-creation of local directory structure. We - don't need to do that here so we override the method be a no-op. - """ - # No setup to do and no need to pre-create local file storage. - pass diff --git a/airbyte-cdk/python/airbyte_cdk/sql/_util/__init__.py b/airbyte-cdk/python/airbyte_cdk/sql/_util/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/airbyte_cdk/sql/_util/hashing.py b/airbyte-cdk/python/airbyte_cdk/sql/_util/hashing.py deleted file mode 100644 index 781305c48a14..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sql/_util/hashing.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -"""Hashing utils for Airbyte.""" - -from __future__ import annotations - -import hashlib -from collections.abc import Mapping - -HASH_SEED = "Airbyte:" -"""Additional seed for randomizing one-way hashed strings.""" - - -def one_way_hash( - obj: Mapping[str, str] | list[str] | object, - /, -) -> str: - """Return a one-way hash of the given string. - - To ensure a unique domain of hashes, we prepend a seed to the string before hashing. - """ - string_to_hash: str - if isinstance(obj, Mapping): - # Recursively sort and convert nested dictionaries to tuples of key-value pairs - string_to_hash = str(sorted((k, one_way_hash(v)) for k, v in obj.items())) - - elif isinstance(obj, list): - # Recursively hash elements of the list - string_to_hash = str([one_way_hash(item) for item in obj]) - - else: - # Convert the object to a string - string_to_hash = str(obj) - - return hashlib.sha256((HASH_SEED + str(string_to_hash)).encode()).hexdigest() diff --git a/airbyte-cdk/python/airbyte_cdk/sql/_util/name_normalizers.py b/airbyte-cdk/python/airbyte_cdk/sql/_util/name_normalizers.py deleted file mode 100644 index 9311432d7387..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sql/_util/name_normalizers.py +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -"""Name normalizer classes.""" - -from __future__ import annotations - -import abc -import functools -import re -from typing import TYPE_CHECKING - -from airbyte_cdk.sql import exceptions as exc - -if TYPE_CHECKING: - from collections.abc import Iterable - - -class NameNormalizerBase(abc.ABC): - """Abstract base class for name normalizers.""" - - @staticmethod - @abc.abstractmethod - def normalize(name: str) -> str: - """Return the normalized name.""" - ... - - @classmethod - def normalize_set(cls, str_iter: Iterable[str]) -> set[str]: - """Converts string iterable to a set of lower case strings.""" - return {cls.normalize(s) for s in str_iter} - - @classmethod - def normalize_list(cls, str_iter: Iterable[str]) -> list[str]: - """Converts string iterable to a list of lower case strings.""" - return [cls.normalize(s) for s in str_iter] - - @classmethod - def check_matched(cls, name1: str, name2: str) -> bool: - """Return True if the two names match after each is normalized.""" - return cls.normalize(name1) == cls.normalize(name2) - - @classmethod - def check_normalized(cls, name: str) -> bool: - """Return True if the name is already normalized.""" - return cls.normalize(name) == name - - -class LowerCaseNormalizer(NameNormalizerBase): - """A name normalizer that converts names to lower case.""" - - @staticmethod - @functools.cache - def normalize(name: str) -> str: - """Return the normalized name. - - - All non-alphanumeric characters are replaced with underscores. - - Any names that start with a numeric ("1", "2", "123", "1b" etc.) are prefixed - with and underscore ("_1", "_2", "_123", "_1b" etc.) - - Examples: - - "Hello World!" -> "hello_world" - - "Hello, World!" -> "hello__world" - - "Hello - World" -> "hello___world" - - "___Hello, World___" -> "___hello__world___" - - "Average Sales (%)" -> "average_sales____" - - "Average Sales (#)" -> "average_sales____" - - "+1" -> "_1" - - "-1" -> "_1" - """ - result = name - - # Replace all non-alphanumeric characters with underscores. - result = re.sub("[^A-Za-z0-9]", "_", result.lower()) - - # Check if name starts with a number and prepend "_" if it does. - if result and result[0].isdigit(): - # Most databases do not allow identifiers to start with a number. - result = f"_{result}" - - if not result.replace("_", ""): - raise exc.AirbyteNameNormalizationError( - message="Name cannot be empty after normalization.", - raw_name=name, - normalization_result=result, - ) - - return result - - -__all__ = [ - "NameNormalizerBase", - "LowerCaseNormalizer", -] diff --git a/airbyte-cdk/python/airbyte_cdk/sql/constants.py b/airbyte-cdk/python/airbyte_cdk/sql/constants.py deleted file mode 100644 index 2f7de7817ac6..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sql/constants.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -"""Constants shared across the Airbyte codebase.""" - -from __future__ import annotations - -DEBUG_MODE = False # Set to True to enable additional debug logging. - -AB_EXTRACTED_AT_COLUMN = "_airbyte_extracted_at" -"""A column that stores the timestamp when the record was extracted.""" - -AB_META_COLUMN = "_airbyte_meta" -"""A column that stores metadata about the record.""" - -AB_RAW_ID_COLUMN = "_airbyte_raw_id" -"""A column that stores a unique identifier for each row in the source data. - -Note: The interpretation of this column is slightly different from in Airbyte Dv2 destinations. -In Airbyte Dv2 destinations, this column points to a row in a separate 'raw' table. In Airbyte, -this column is simply used as a unique identifier for each record as it is received. - -Airbyte uses ULIDs for this column, which are identifiers that can be sorted by time -received. This allows us to determine the debug the order of records as they are received, even if -the source provides records that are tied or received out of order from the perspective of their -`emitted_at` (`_airbyte_extracted_at`) timestamps. -""" - -AB_INTERNAL_COLUMNS = { - AB_RAW_ID_COLUMN, - AB_EXTRACTED_AT_COLUMN, - AB_META_COLUMN, -} -"""A set of internal columns that are reserved for Airbyte's internal use.""" diff --git a/airbyte-cdk/python/airbyte_cdk/sql/exceptions.py b/airbyte-cdk/python/airbyte_cdk/sql/exceptions.py deleted file mode 100644 index 0192d829ac50..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sql/exceptions.py +++ /dev/null @@ -1,222 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -"""All exceptions used in Airbyte. - -This design is modeled after structlog's exceptions, in that we bias towards auto-generated -property prints rather than sentence-like string concatenation. - -E.g. Instead of this: - -> `Subprocess failed with exit code '1'` - -We do this: - -> `Subprocess failed. (exit_code=1)` - -The benefit of this approach is that we can easily support structured logging, and we can -easily add new properties to exceptions without having to update all the places where they -are raised. We can also support any arbitrary number of properties in exceptions, without spending -time on building sentence-like string constructions with optional inputs. - - -In addition, the following principles are applied for exception class design: - -- All exceptions inherit from a common base class. -- All exceptions have a message attribute. -- The first line of the docstring is used as the default message. -- The default message can be overridden by explicitly setting the message attribute. -- Exceptions may optionally have a guidance attribute. -- Exceptions may optionally have a help_url attribute. -- Rendering is automatically handled by the base class. -- Any helpful context not defined by the exception class can be passed in the `context` dict arg. -- Within reason, avoid sending PII to the exception constructor. -- Exceptions are dataclasses, so they can be instantiated with keyword arguments. -- Use the 'from' syntax to chain exceptions when it is helpful to do so. - E.g. `raise AirbyteConnectorNotFoundError(...) from FileNotFoundError(connector_path)` -- Any exception that adds a new property should also be decorated as `@dataclass`. -""" - -from __future__ import annotations - -import logging -from dataclasses import dataclass -from pathlib import Path -from textwrap import indent -from typing import Any - -NEW_ISSUE_URL = "https://github.com/airbytehq/airbyte/issues/new/choose" -DOCS_URL_BASE = "https://https://docs.airbyte.com/" -DOCS_URL = f"{DOCS_URL_BASE}/airbyte.html" - -VERTICAL_SEPARATOR = "\n" + "-" * 60 - - -# Base error class - - -@dataclass -class AirbyteError(Exception): - """Base class for exceptions in Airbyte.""" - - guidance: str | None = None - help_url: str | None = None - log_text: str | list[str] | None = None - log_file: Path | None = None - context: dict[str, Any] | None = None - message: str | None = None - original_exception: Exception | None = None - - def get_message(self) -> str: - """Return the best description for the exception. - - We resolve the following in order: - 1. The message sent to the exception constructor (if provided). - 2. The first line of the class's docstring. - """ - if self.message: - return self.message - - return self.__doc__.split("\n")[0] if self.__doc__ else "" - - def __str__(self) -> str: - """Return a string representation of the exception.""" - special_properties = [ - "message", - "guidance", - "help_url", - "log_text", - "context", - "log_file", - "original_exception", - ] - display_properties = { - k: v for k, v in self.__dict__.items() if k not in special_properties and not k.startswith("_") and v is not None - } - display_properties.update(self.context or {}) - context_str = "\n ".join(f"{str(k).replace('_', ' ').title()}: {v!r}" for k, v in display_properties.items()) - exception_str = ( - f"{self.get_message()} ({self.__class__.__name__})" + VERTICAL_SEPARATOR + f"\n{self.__class__.__name__}: {self.get_message()}" - ) - - if self.guidance: - exception_str += f"\n {self.guidance}" - - if self.help_url: - exception_str += f"\n More info: {self.help_url}" - - if context_str: - exception_str += "\n " + context_str - - if self.log_file: - exception_str += f"\n Log file: {self.log_file.absolute()!s}" - - if self.log_text: - if isinstance(self.log_text, list): - self.log_text = "\n".join(self.log_text) - - exception_str += f"\n Log output: \n {indent(self.log_text, ' ')}" - - if self.original_exception: - exception_str += VERTICAL_SEPARATOR + f"\nCaused by: {self.original_exception!s}" - - return exception_str - - def __repr__(self) -> str: - """Return a string representation of the exception.""" - class_name = self.__class__.__name__ - properties_str = ", ".join(f"{k}={v!r}" for k, v in self.__dict__.items() if not k.startswith("_")) - return f"{class_name}({properties_str})" - - def safe_logging_dict(self) -> dict[str, Any]: - """Return a dictionary of the exception's properties which is safe for logging. - - We avoid any properties which could potentially contain PII. - """ - result = { - # The class name is safe to log: - "class": self.__class__.__name__, - # We discourage interpolated strings in 'message' so that this should never contain PII: - "message": self.get_message(), - } - safe_attrs = ["connector_name", "stream_name", "violation", "exit_code"] - for attr in safe_attrs: - if hasattr(self, attr): - result[attr] = getattr(self, attr) - - return result - - -# Airbyte Internal Errors (these are probably bugs) - - -@dataclass -class AirbyteInternalError(AirbyteError): - """An internal error occurred in Airbyte.""" - - guidance = "Please consider reporting this error to the Airbyte team." - help_url = NEW_ISSUE_URL - - -# Airbyte Input Errors (replaces ValueError for user input) - - -@dataclass -class AirbyteInputError(AirbyteError, ValueError): - """The input provided to Airbyte did not match expected validation rules. - - This inherits from ValueError so that it can be used as a drop-in replacement for - ValueError in the Airbyte API. - """ - - guidance = "Please check the provided value and try again." - help_url = DOCS_URL - input_value: str | None = None - - -# Normalization Errors - - -@dataclass -class AirbyteNameNormalizationError(AirbyteError, ValueError): - """Error occurred while normalizing a table or column name.""" - - guidance = "Please consider renaming the source object if possible, or " "raise an issue in GitHub if not." - help_url = NEW_ISSUE_URL - - raw_name: str | None = None - normalization_result: str | None = None - - -@dataclass -class AirbyteConnectorError(AirbyteError): - """Error when running the connector.""" - - connector_name: str | None = None - - def __post_init__(self) -> None: - """Set the log file path for the connector.""" - self.log_file = self._get_log_file() - if not self.guidance and self.log_file: - self.guidance = "Please review the log file for more information." - - def _get_log_file(self) -> Path | None: - """Return the log file path for the connector.""" - if self.connector_name: - logger = logging.getLogger(f"airbyte.{self.connector_name}") - - log_paths: list[Path] = [ - Path(handler.baseFilename).absolute() for handler in logger.handlers if isinstance(handler, logging.FileHandler) - ] - - if log_paths: - return log_paths[0] - - return None - - -@dataclass -class AirbyteStreamNotFoundError(AirbyteConnectorError): - """Connector stream not found.""" - - stream_name: str | None = None - available_streams: list[str] | None = None diff --git a/airbyte-cdk/python/airbyte_cdk/sql/secrets.py b/airbyte-cdk/python/airbyte_cdk/sql/secrets.py deleted file mode 100644 index aaf7641aa934..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sql/secrets.py +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -"""Base classes and methods for working with secrets in Airbyte.""" - -from __future__ import annotations - -import json -from typing import TYPE_CHECKING, Any - -from airbyte_cdk.sql import exceptions as exc -from pydantic_core import CoreSchema, core_schema - -if TYPE_CHECKING: - from pydantic import GetCoreSchemaHandler, GetJsonSchemaHandler, ValidationInfo - from pydantic.json_schema import JsonSchemaValue - - -class SecretString(str): - """A string that represents a secret. - - This class is used to mark a string as a secret. When a secret is printed, it - will be masked to prevent accidental exposure of sensitive information when debugging - or when printing containing objects like dictionaries. - - To create a secret string, simply instantiate the class with any string value: - - ```python - secret = SecretString("my_secret_password") - ``` - - """ - - __slots__ = () - - def __repr__(self) -> str: - """Override the representation of the secret string to return a masked value. - - The secret string is always masked with `****` to prevent accidental exposure, unless - explicitly converted to a string. For instance, printing a config dictionary that contains - a secret will automatically mask the secret value instead of printing it in plain text. - - However, if you explicitly convert the cast the secret as a string, such as when used - in an f-string, the secret will be exposed. This is the desired behavior to allow - secrets to be used in a controlled manner. - """ - return "" - - def is_empty(self) -> bool: - """Check if the secret is an empty string.""" - return len(self) == 0 - - def is_json(self) -> bool: - """Check if the secret string is a valid JSON string.""" - try: - json.loads(self) - except (json.JSONDecodeError, Exception): - return False - - return True - - def __bool__(self) -> bool: - """Override the boolean value of the secret string. - - Always returns `True` without inspecting contents. - """ - return True - - def parse_json(self) -> Any: - """Parse the secret string as JSON.""" - try: - return json.loads(self) - except json.JSONDecodeError as ex: - raise exc.AirbyteInputError( - message="Failed to parse secret as JSON.", - context={ - "Message": ex.msg, - "Position": ex.pos, - "SecretString_Length": len(self), # Debug secret blank or an unexpected format. - }, - ) from None - - # Pydantic compatibility - - @classmethod - def validate( - cls, - v: Any, # noqa: ANN401 # Must allow `Any` to match Pydantic signature - info: ValidationInfo, - ) -> SecretString: - """Validate the input value is valid as a secret string.""" - _ = info # Unused - if not isinstance(v, str): - raise exc.AirbyteInputError( - message="A valid `str` or `SecretString` object is required.", - ) - return cls(v) - - @classmethod - def __get_pydantic_core_schema__( # noqa: PLW3201 # Pydantic dunder - cls, - source_type: Any, # noqa: ANN401 # Must allow `Any` to match Pydantic signature - handler: GetCoreSchemaHandler, - ) -> CoreSchema: - """Return a modified core schema for the secret string.""" - return core_schema.with_info_after_validator_function(function=cls.validate, schema=handler(str), field_name=handler.field_name) - - @classmethod - def __get_pydantic_json_schema__( # noqa: PLW3201 # Pydantic dunder method - cls, _core_schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler - ) -> JsonSchemaValue: - """Return a modified JSON schema for the secret string. - - - `writeOnly=True` is the official way to prevent secrets from being exposed inadvertently. - - `Format=password` is a popular and readable convention to indicate the field is sensitive. - """ - _ = _core_schema, handler # Unused - return { - "type": "string", - "format": "password", - "writeOnly": True, - } diff --git a/airbyte-cdk/python/airbyte_cdk/sql/shared/__init__.py b/airbyte-cdk/python/airbyte_cdk/sql/shared/__init__.py deleted file mode 100644 index d9156b9d0d76..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sql/shared/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -"""Module for future CDK components. - -Components here are planned to move to the CDK. - -TODO!: Add GitHub link here before merging. -""" - -from __future__ import annotations - -from airbyte_cdk.sql.shared.sql_processor import SqlProcessorBase - -__all__ = [ - "SqlProcessorBase", -] diff --git a/airbyte-cdk/python/airbyte_cdk/sql/shared/catalog_providers.py b/airbyte-cdk/python/airbyte_cdk/sql/shared/catalog_providers.py deleted file mode 100644 index 8d139c9c9cd2..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sql/shared/catalog_providers.py +++ /dev/null @@ -1,136 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -"""Catalog provider implementation. - -A catalog provider wraps a configured catalog and configured streams. This class is responsible for -providing information about the catalog and streams. A catalog provider can also be updated with new -streams as they are discovered, providing a thin layer of abstraction over the configured catalog. -""" - -from __future__ import annotations - -from typing import TYPE_CHECKING, Any, cast, final - -from airbyte_cdk.models import ConfiguredAirbyteCatalog -from airbyte_cdk.sql import exceptions as exc -from airbyte_cdk.sql._util.name_normalizers import LowerCaseNormalizer - -if TYPE_CHECKING: - from airbyte_cdk.models import ConfiguredAirbyteStream - - -class CatalogProvider: - """A catalog provider wraps a configured catalog and configured streams. - - This class is responsible for providing information about the catalog and streams. - - Note: - - The catalog provider is not responsible for managing the catalog or streams but it may - be updated with new streams as they are discovered. - """ - - def __init__( - self, - configured_catalog: ConfiguredAirbyteCatalog, - ) -> None: - """Initialize the catalog manager with a catalog object reference. - - Since the catalog is passed by reference, the catalog manager may be updated with new - streams as they are discovered. - """ - self._catalog: ConfiguredAirbyteCatalog = self.validate_catalog(configured_catalog) - - @staticmethod - def validate_catalog(catalog: ConfiguredAirbyteCatalog) -> Any: - """Validate the catalog to ensure it is valid. - - This requires ensuring that `generationId` and `minGenerationId` are both set. If - not, both values will be set to `1`. - """ - for stream in catalog.streams: - if stream.generation_id is None: - stream.generation_id = 1 - if stream.minimum_generation_id is None: - stream.minimum_generation_id = 1 - if stream.sync_id is None: - stream.sync_id = 1 # This should ideally increment monotonically with each sync. - - return catalog - - @property - def configured_catalog(self) -> ConfiguredAirbyteCatalog: - """Return the configured catalog.""" - return self._catalog - - @property - def stream_names(self) -> list[str]: - """Return the names of the streams in the catalog.""" - return list({stream.stream.name for stream in self.configured_catalog.streams}) - - def get_configured_stream_info( - self, - stream_name: str, - ) -> ConfiguredAirbyteStream: - """Return the column definitions for the given stream.""" - if not self.configured_catalog: - raise exc.AirbyteInternalError( - message="Cannot get stream JSON schema without a catalog.", - ) - - matching_streams: list[ConfiguredAirbyteStream] = [ - stream for stream in self.configured_catalog.streams if stream.stream.name == stream_name - ] - if not matching_streams: - raise exc.AirbyteStreamNotFoundError( - stream_name=stream_name, - context={ - "available_streams": [stream.stream.name for stream in self.configured_catalog.streams], - }, - ) - - if len(matching_streams) > 1: - raise exc.AirbyteInternalError( - message="Multiple streams found with same name.", - context={ - "stream_name": stream_name, - }, - ) - - return matching_streams[0] - - @final - def get_stream_json_schema( - self, - stream_name: str, - ) -> dict[str, Any]: - """Return the column definitions for the given stream.""" - return cast(dict[str, Any], self.get_configured_stream_info(stream_name).stream.json_schema) - - def get_stream_properties( - self, - stream_name: str, - ) -> dict[str, dict[str, Any]]: - """Return the names of the top-level properties for the given stream.""" - return cast(dict[str, Any], self.get_stream_json_schema(stream_name)["properties"]) - - def get_primary_keys( - self, - stream_name: str, - ) -> list[str]: - """Return the primary keys for the given stream.""" - pks = self.get_configured_stream_info(stream_name).primary_key - if not pks: - return [] - - normalized_pks: list[list[str]] = [[LowerCaseNormalizer.normalize(c) for c in pk] for pk in pks] - - for pk_nodes in normalized_pks: - if len(pk_nodes) != 1: - raise exc.AirbyteError( - message=("Nested primary keys are not supported. " "Each PK column should have exactly one node. "), - context={ - "stream_name": stream_name, - "primary_key_nodes": pk_nodes, - }, - ) - - return [pk_nodes[0] for pk_nodes in normalized_pks] diff --git a/airbyte-cdk/python/airbyte_cdk/sql/shared/sql_processor.py b/airbyte-cdk/python/airbyte_cdk/sql/shared/sql_processor.py deleted file mode 100644 index 52a8e52dee3a..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sql/shared/sql_processor.py +++ /dev/null @@ -1,754 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -"""The base SQL Cache implementation.""" - -from __future__ import annotations - -import abc -from collections import defaultdict -from contextlib import contextmanager -from functools import cached_property -from pathlib import Path -from typing import TYPE_CHECKING, Any, final - -import pandas as pd -import sqlalchemy -import ulid -from airbyte_cdk.sql import exceptions as exc -from airbyte_cdk.sql._util.hashing import one_way_hash -from airbyte_cdk.sql._util.name_normalizers import LowerCaseNormalizer -from airbyte_cdk.sql.constants import AB_EXTRACTED_AT_COLUMN, AB_META_COLUMN, AB_RAW_ID_COLUMN, DEBUG_MODE -from airbyte_cdk.sql.secrets import SecretString -from airbyte_cdk.sql.types import SQLTypeConverter -from airbyte_protocol_dataclasses.models import AirbyteStateMessage -from pandas import Index -from pydantic import BaseModel, Field -from sqlalchemy import Column, Table, and_, create_engine, insert, null, select, text, update -from sqlalchemy.exc import ProgrammingError, SQLAlchemyError - -if TYPE_CHECKING: - from collections.abc import Generator - - from airbyte_cdk.sql.shared.catalog_providers import CatalogProvider - from sqlalchemy.engine import Connection, Engine - from sqlalchemy.engine.cursor import CursorResult - from sqlalchemy.engine.reflection import Inspector - from sqlalchemy.sql.base import Executable - from sqlalchemy.sql.elements import TextClause - from sqlalchemy.sql.type_api import TypeEngine - - -class SQLRuntimeError(Exception): - """Raised when an SQL operation fails.""" - - -class SqlConfig(BaseModel, abc.ABC): - """Common configuration for SQL connections.""" - - schema_name: str = Field(default="airbyte_raw") - """The name of the schema to write to.""" - - table_prefix: str | None = "" - """A prefix to add to created table names.""" - - @abc.abstractmethod - def get_sql_alchemy_url(self) -> SecretString: - """Returns a SQL Alchemy URL.""" - ... - - @abc.abstractmethod - def get_database_name(self) -> str: - """Return the name of the database.""" - ... - - @property - def config_hash(self) -> str | None: - """Return a unique one-way hash of the configuration. - - The generic implementation uses the SQL Alchemy URL, schema name, and table prefix. Some - inputs may be redundant with the SQL Alchemy URL, but this does not hurt the hash - uniqueness. - - In most cases, subclasses do not need to override this method. - """ - return one_way_hash( - SecretString( - ":".join( - [ - str(self.get_sql_alchemy_url()), - self.schema_name or "", - self.table_prefix or "", - ] - ) - ) - ) - - def get_sql_engine(self) -> Engine: - """Return a new SQL engine to use.""" - return create_engine( - url=self.get_sql_alchemy_url(), - echo=DEBUG_MODE, - execution_options={ - "schema_translate_map": {None: self.schema_name}, - }, - future=True, - ) - - def get_vendor_client(self) -> object: - """Return the vendor-specific client object. - - This is used for vendor-specific operations. - - Raises `NotImplementedError` if a custom vendor client is not defined. - """ - raise NotImplementedError(f"The type '{type(self).__name__}' does not define a custom client.") - - -class SqlProcessorBase(abc.ABC): - """A base class to be used for SQL Caches.""" - - type_converter_class: type[SQLTypeConverter] = SQLTypeConverter - """The type converter class to use for converting JSON schema types to SQL types.""" - - normalizer = LowerCaseNormalizer - """The name normalizer to user for table and column name normalization.""" - - supports_merge_insert = False - """True if the database supports the MERGE INTO syntax.""" - - def __init__( - self, - *, - sql_config: SqlConfig, - catalog_provider: CatalogProvider, - ) -> None: - """Create a new SQL processor.""" - self._sql_config: SqlConfig = sql_config - self._catalog_provider: CatalogProvider | None = catalog_provider - - self._pending_state_messages: dict[str, list[AirbyteStateMessage]] = defaultdict(list, {}) - self._finalized_state_messages: dict[ - str, - list[AirbyteStateMessage], - ] = defaultdict(list, {}) - - self._setup() - self.type_converter = self.type_converter_class() - self._cached_table_definitions: dict[str, sqlalchemy.Table] = {} - - self._known_schemas_list: list[str] = [] - self._ensure_schema_exists() - - @property - def catalog_provider( - self, - ) -> CatalogProvider: - """Return the catalog manager. - - Subclasses should set this property to a valid catalog manager instance if one - is not explicitly passed to the constructor. - - Raises: - AirbyteInternalError: If the catalog manager is not set. - """ - if not self._catalog_provider: - raise exc.AirbyteInternalError( - message="Catalog manager should exist but does not.", - ) - - return self._catalog_provider - - def _setup(self) -> None: # noqa: B027 # Intentionally empty, not abstract - """Create the database. - - By default this is a no-op but subclasses can override this method to prepare - any necessary resources. - """ - pass - - def _do_checkpoint( # noqa: B027 # Intentionally empty, not abstract - self, - connection: Connection | None = None, - ) -> None: - """Checkpoint the given connection. - - If the WAL log needs to be, it will be flushed. - - For most SQL databases, this is a no-op. However, it exists so that - subclasses can override this method to perform a checkpoint operation. - """ - pass - - # Public interface: - - @property - def sql_config(self) -> SqlConfig: - """Return the SQL configuration.""" - return self._sql_config - - def get_sql_alchemy_url(self) -> SecretString: - """Return the SQLAlchemy URL to use.""" - return self.sql_config.get_sql_alchemy_url() - - @final - @cached_property - def database_name(self) -> str: - """Return the name of the database.""" - return self.sql_config.get_database_name() - - @final - def get_sql_engine(self) -> Engine: - """Return a new SQL engine to use.""" - return self.sql_config.get_sql_engine() - - @contextmanager - def get_sql_connection(self) -> Generator[sqlalchemy.engine.Connection, None, None]: - """A context manager which returns a new SQL connection for running queries. - - If the connection needs to close, it will be closed automatically. - """ - with self.get_sql_engine().begin() as connection: - self._init_connection_settings(connection) - yield connection - - connection.close() - del connection - - def get_sql_table_name( - self, - stream_name: str, - ) -> str: - """Return the name of the SQL table for the given stream.""" - table_prefix = self.sql_config.table_prefix - return self.normalizer.normalize( - f"{table_prefix}{stream_name}", - ) - - @final - def get_sql_table( - self, - stream_name: str, - ) -> sqlalchemy.Table: - """Return the main table object for the stream.""" - return self._get_table_by_name( - self.get_sql_table_name(stream_name), - ) - - # Protected members (non-public interface): - - def _init_connection_settings(self, connection: Connection) -> None: # noqa: B027 # Intentionally empty, not abstract - """This is called automatically whenever a new connection is created. - - By default this is a no-op. Subclasses can use this to set connection settings, such as - timezone, case-sensitivity settings, and other session-level variables. - """ - pass - - def _invalidate_table_cache( - self, - table_name: str, - ) -> None: - """Invalidate the the named table cache. - - This should be called whenever the table schema is known to have changed. - """ - if table_name in self._cached_table_definitions: - del self._cached_table_definitions[table_name] - - def _get_table_by_name( - self, - table_name: str, - *, - force_refresh: bool = False, - shallow_okay: bool = False, - ) -> sqlalchemy.Table: - """Return a table object from a table name. - - If 'shallow_okay' is True, the table will be returned without requiring properties to - be read from the database. - - To prevent unnecessary round-trips to the database, the table is cached after the first - query. To ignore the cache and force a refresh, set 'force_refresh' to True. - """ - if force_refresh and shallow_okay: - raise exc.AirbyteInternalError(message="Cannot force refresh and use shallow query at the same time.") - - if force_refresh and table_name in self._cached_table_definitions: - self._invalidate_table_cache(table_name) - - if table_name not in self._cached_table_definitions: - if shallow_okay: - # Return a shallow instance, without column declarations. Do not cache - # the table definition in this case. - return sqlalchemy.Table( - table_name, - sqlalchemy.MetaData(schema=self.sql_config.schema_name), - ) - - self._cached_table_definitions[table_name] = sqlalchemy.Table( - table_name, - sqlalchemy.MetaData(schema=self.sql_config.schema_name), - autoload_with=self.get_sql_engine(), - ) - - return self._cached_table_definitions[table_name] - - def _ensure_schema_exists( - self, - ) -> None: - schema_name = self.normalizer.normalize(self.sql_config.schema_name) - known_schemas_list = self.normalizer.normalize_list(self._known_schemas_list) - if known_schemas_list and schema_name in known_schemas_list: - return # Already exists - - schemas_list = self.normalizer.normalize_list(self._get_schemas_list()) - if schema_name in schemas_list: - return - - sql = f"CREATE SCHEMA IF NOT EXISTS {schema_name}" - - try: - self._execute_sql(sql) - except Exception as ex: - # Ignore schema exists errors. - if "already exists" not in str(ex): - raise - - if DEBUG_MODE: - found_schemas = schemas_list - assert schema_name in found_schemas, f"Schema {schema_name} was not created. Found: {found_schemas}" - - def _quote_identifier(self, identifier: str) -> str: - """Return the given identifier, quoted.""" - return f'"{identifier}"' - - @final - def _get_temp_table_name( - self, - stream_name: str, - batch_id: str | None = None, # ULID of the batch - ) -> str: - """Return a new (unique) temporary table name.""" - if not batch_id: - batch_id = str(ulid.ULID()) - - # Use the first 6 and last 3 characters of the ULID. This gives great uniqueness while - # limiting the table name suffix to 10 characters, including the underscore. - suffix = f"{batch_id[:6]}{batch_id[-3:]}" if len(batch_id) > 9 else batch_id # noqa: PLR2004 # Allow magic int value - - # Note: The normalizer may truncate the table name if the database has a name length limit. - # For instance, the Postgres normalizer will enforce a 63-character limit on table names. - return self.normalizer.normalize(f"{stream_name}_{suffix}") - - def _fully_qualified( - self, - table_name: str, - ) -> str: - """Return the fully qualified name of the given table.""" - return f"{self.sql_config.schema_name}.{self._quote_identifier(table_name)}" - - @final - def _create_table_for_loading( - self, - /, - stream_name: str, - batch_id: str | None, - ) -> str: - """Create a new table for loading data.""" - temp_table_name = self._get_temp_table_name(stream_name, batch_id) - column_definition_str = ",\n ".join( - f"{self._quote_identifier(column_name)} {sql_type}" - for column_name, sql_type in self._get_sql_column_definitions(stream_name).items() - ) - self._create_table(temp_table_name, column_definition_str) - - return temp_table_name - - def _get_tables_list( - self, - ) -> list[str]: - """Return a list of all tables in the database.""" - with self.get_sql_connection() as conn: - inspector: Inspector = sqlalchemy.inspect(conn) - return inspector.get_table_names(schema=self.sql_config.schema_name) # type: ignore - - def _get_schemas_list( - self, - database_name: str | None = None, - *, - force_refresh: bool = False, - ) -> list[str]: - """Return a list of all tables in the database.""" - if not force_refresh and self._known_schemas_list: - return self._known_schemas_list - - inspector: Inspector = sqlalchemy.inspect(self.get_sql_engine()) - database_name = database_name or self.database_name - found_schemas = inspector.get_schema_names() - self._known_schemas_list = [ - found_schema.split(".")[-1].strip('"') - for found_schema in found_schemas - if "." not in found_schema or (found_schema.split(".")[0].lower().strip('"') == database_name.lower()) - ] - return self._known_schemas_list - - def _ensure_final_table_exists( - self, - stream_name: str, - *, - create_if_missing: bool = True, - ) -> str: - """Create the final table if it doesn't already exist. - - Return the table name. - """ - table_name = self.get_sql_table_name(stream_name) - did_exist = self._table_exists(table_name) - if not did_exist and create_if_missing: - column_definition_str = ",\n ".join( - f"{self._quote_identifier(column_name)} {sql_type}" - for column_name, sql_type in self._get_sql_column_definitions( - stream_name, - ).items() - ) - self._create_table(table_name, column_definition_str) - - return table_name - - def _ensure_compatible_table_schema( - self, - stream_name: str, - table_name: str, - ) -> None: - """Return true if the given table is compatible with the stream's schema. - - Raises an exception if the table schema is not compatible with the schema of the - input stream. - """ - # TODO: Expand this to check for column types and sizes. - # https://github.com/airbytehq/Airbyte/issues/321 - self._add_missing_columns_to_table( - stream_name=stream_name, - table_name=table_name, - ) - - @final - def _create_table( - self, - table_name: str, - column_definition_str: str, - primary_keys: list[str] | None = None, - ) -> None: - if primary_keys: - pk_str = ", ".join(primary_keys) - column_definition_str += f",\n PRIMARY KEY ({pk_str})" - - cmd = f""" - CREATE TABLE {self._fully_qualified(table_name)} ( - {column_definition_str} - ) - """ - _ = self._execute_sql(cmd) - - @final - def _get_sql_column_definitions( - self, - stream_name: str, - ) -> dict[str, sqlalchemy.types.TypeEngine[Any]]: - """Return the column definitions for the given stream.""" - columns: dict[str, sqlalchemy.types.TypeEngine[Any]] = {} - properties = self.catalog_provider.get_stream_properties(stream_name) - for property_name, json_schema_property_def in properties.items(): - clean_prop_name = self.normalizer.normalize(property_name) - columns[clean_prop_name] = self.type_converter.to_sql_type( - json_schema_property_def, - ) - - columns[AB_RAW_ID_COLUMN] = self.type_converter_class.get_string_type() - columns[AB_EXTRACTED_AT_COLUMN] = sqlalchemy.TIMESTAMP() - columns[AB_META_COLUMN] = self.type_converter_class.get_json_type() - - return columns - - def _execute_sql(self, sql: str | TextClause | Executable) -> CursorResult[Any]: - """Execute the given SQL statement.""" - if isinstance(sql, str): - sql = text(sql) - - with self.get_sql_connection() as conn: - try: - result = conn.execute(sql) - except ( - ProgrammingError, - SQLAlchemyError, - ) as ex: - msg = f"Error when executing SQL:\n{sql}\n{type(ex).__name__}{ex!s}" - raise SQLRuntimeError(msg) from None # from ex - - return result - - def _drop_temp_table( - self, - table_name: str, - *, - if_exists: bool = True, - ) -> None: - """Drop the given table.""" - exists_str = "IF EXISTS" if if_exists else "" - self._execute_sql(f"DROP TABLE {exists_str} {self._fully_qualified(table_name)}") - - def _write_files_to_new_table( - self, - files: list[Path], - stream_name: str, - batch_id: str, - ) -> str: - """Write a file(s) to a new table. - - This is a generic implementation, which can be overridden by subclasses - to improve performance. - """ - temp_table_name = self._create_table_for_loading(stream_name, batch_id) - for file_path in files: - dataframe = pd.read_json(file_path, lines=True) - - sql_column_definitions: dict[str, TypeEngine[Any]] = self._get_sql_column_definitions(stream_name) - - # Remove fields that are not in the schema - for col_name in dataframe.columns: - if col_name not in sql_column_definitions: - dataframe = dataframe.drop(columns=col_name) - - # Pandas will auto-create the table if it doesn't exist, which we don't want. - if not self._table_exists(temp_table_name): - raise exc.AirbyteInternalError( - message="Table does not exist after creation.", - context={ - "temp_table_name": temp_table_name, - }, - ) - - # Normalize all column names to lower case. - dataframe.columns = Index([self.normalizer.normalize(col) for col in dataframe.columns]) - - # Write the data to the table. - dataframe.to_sql( - temp_table_name, - self.get_sql_alchemy_url(), - schema=self.sql_config.schema_name, - if_exists="append", - index=False, - dtype=sql_column_definitions, # type: ignore[arg-type] - ) - return temp_table_name - - def _add_column_to_table( - self, - table: Table, - column_name: str, - column_type: sqlalchemy.types.TypeEngine[Any], - ) -> None: - """Add a column to the given table.""" - self._execute_sql( - text(f"ALTER TABLE {self._fully_qualified(table.name)} " f"ADD COLUMN {column_name} {column_type}"), - ) - - def _add_missing_columns_to_table( - self, - stream_name: str, - table_name: str, - ) -> None: - """Add missing columns to the table. - - This is a no-op if all columns are already present. - """ - columns = self._get_sql_column_definitions(stream_name) - # First check without forcing a refresh of the cache (faster). If nothing is missing, - # then we're done. - table = self._get_table_by_name( - table_name, - force_refresh=False, - ) - missing_columns: bool = any(column_name not in table.columns for column_name in columns) - - if missing_columns: - # If we found missing columns, refresh the cache and then take action on anything - # that's still confirmed missing. - columns_added = False - table = self._get_table_by_name( - table_name, - force_refresh=True, - ) - for column_name, column_type in columns.items(): - if column_name not in table.columns: - self._add_column_to_table(table, column_name, column_type) - columns_added = True - - if columns_added: - # We've added columns, so invalidate the cache. - self._invalidate_table_cache(table_name) - - def _append_temp_table_to_final_table( - self, - temp_table_name: str, - final_table_name: str, - stream_name: str, - ) -> None: - nl = "\n" - columns = [self._quote_identifier(c) for c in self._get_sql_column_definitions(stream_name)] - self._execute_sql( - f""" - INSERT INTO {self._fully_qualified(final_table_name)} ( - {f',{nl} '.join(columns)} - ) - SELECT - {f',{nl} '.join(columns)} - FROM {self._fully_qualified(temp_table_name)} - """, - ) - - def _swap_temp_table_with_final_table( - self, - stream_name: str, - temp_table_name: str, - final_table_name: str, - ) -> None: - """Merge the temp table into the main one. - - This implementation requires MERGE support in the SQL DB. - Databases that do not support this syntax can override this method. - """ - if final_table_name is None: - raise exc.AirbyteInternalError(message="Arg 'final_table_name' cannot be None.") - if temp_table_name is None: - raise exc.AirbyteInternalError(message="Arg 'temp_table_name' cannot be None.") - - _ = stream_name - deletion_name = f"{final_table_name}_deleteme" - commands = "\n".join( - [ - f"ALTER TABLE {self._fully_qualified(final_table_name)} RENAME " f"TO {deletion_name};", - f"ALTER TABLE {self._fully_qualified(temp_table_name)} RENAME " f"TO {final_table_name};", - f"DROP TABLE {self._fully_qualified(deletion_name)};", - ] - ) - self._execute_sql(commands) - - def _merge_temp_table_to_final_table( - self, - stream_name: str, - temp_table_name: str, - final_table_name: str, - ) -> None: - """Merge the temp table into the main one. - - This implementation requires MERGE support in the SQL DB. - Databases that do not support this syntax can override this method. - """ - nl = "\n" - columns = {self._quote_identifier(c) for c in self._get_sql_column_definitions(stream_name)} - pk_columns = {self._quote_identifier(c) for c in self.catalog_provider.get_primary_keys(stream_name)} - non_pk_columns = columns - pk_columns - join_clause = f"{nl} AND ".join(f"tmp.{pk_col} = final.{pk_col}" for pk_col in pk_columns) - set_clause = f"{nl} , ".join(f"{col} = tmp.{col}" for col in non_pk_columns) - self._execute_sql( - f""" - MERGE INTO {self._fully_qualified(final_table_name)} final - USING ( - SELECT * - FROM {self._fully_qualified(temp_table_name)} - ) AS tmp - ON {join_clause} - WHEN MATCHED THEN UPDATE - SET - {set_clause} - WHEN NOT MATCHED THEN INSERT - ( - {f',{nl} '.join(columns)} - ) - VALUES ( - tmp.{f',{nl} tmp.'.join(columns)} - ); - """, - ) - - def _get_column_by_name(self, table: str | Table, column_name: str) -> Column[Any]: - """Return the column object for the given column name. - - This method is case-insensitive. - """ - if isinstance(table, str): - table = self._get_table_by_name(table) - try: - # Try to get the column in a case-insensitive manner - return next(col for col in table.c if col.name.lower() == column_name.lower()) - except StopIteration: - raise exc.AirbyteInternalError( - message="Could not find matching column.", - context={ - "table": table, - "column_name": column_name, - }, - ) from None - - def _emulated_merge_temp_table_to_final_table( - self, - stream_name: str, - temp_table_name: str, - final_table_name: str, - ) -> None: - """Emulate the merge operation using a series of SQL commands. - - This is a fallback implementation for databases that do not support MERGE. - """ - final_table = self._get_table_by_name(final_table_name) - temp_table = self._get_table_by_name(temp_table_name) - pk_columns = self.catalog_provider.get_primary_keys(stream_name) - - columns_to_update: set[str] = self._get_sql_column_definitions(stream_name=stream_name).keys() - set(pk_columns) - - # Create a dictionary mapping columns in users_final to users_stage for updating - update_values = { - self._get_column_by_name(final_table, column): (self._get_column_by_name(temp_table, column)) for column in columns_to_update - } - - # Craft the WHERE clause for composite primary keys - join_conditions = [ - self._get_column_by_name(final_table, pk_column) == self._get_column_by_name(temp_table, pk_column) for pk_column in pk_columns - ] - join_clause = and_(*join_conditions) - - # Craft the UPDATE statement - update_stmt = update(final_table).values(update_values).where(join_clause) - - # Define a join between temp_table and final_table - joined_table = temp_table.outerjoin(final_table, join_clause) - - # Define a condition that checks for records in temp_table that do not have a corresponding - # record in final_table - where_not_exists_clause = self._get_column_by_name(final_table, pk_columns[0]) == null() - - # Select records from temp_table that are not in final_table - select_new_records_stmt = select(temp_table).select_from(joined_table).where(where_not_exists_clause) - - # Craft the INSERT statement using the select statement - insert_new_records_stmt = insert(final_table).from_select( - names=[column.name for column in temp_table.columns], select=select_new_records_stmt - ) - - if DEBUG_MODE: - print(str(update_stmt)) - print(str(insert_new_records_stmt)) - - with self.get_sql_connection() as conn: - conn.execute(update_stmt) - conn.execute(insert_new_records_stmt) - - def _table_exists( - self, - table_name: str, - ) -> bool: - """Return true if the given table exists. - - Subclasses may override this method to provide a more efficient implementation. - """ - return table_name in self._get_tables_list() diff --git a/airbyte-cdk/python/airbyte_cdk/sql/types.py b/airbyte-cdk/python/airbyte_cdk/sql/types.py deleted file mode 100644 index bb6fa1cb76df..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/sql/types.py +++ /dev/null @@ -1,160 +0,0 @@ -# noqa: A005 # Allow shadowing the built-in 'types' module -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -"""Type conversion methods for SQL Caches.""" - -from __future__ import annotations - -from typing import Any, cast - -import sqlalchemy - -# Compare to documentation here: https://docs.airbyte.com/understanding-airbyte/supported-data-types -CONVERSION_MAP = { - "string": sqlalchemy.types.VARCHAR, - "integer": sqlalchemy.types.BIGINT, - "number": sqlalchemy.types.DECIMAL(38, 9), - "boolean": sqlalchemy.types.BOOLEAN, - "date": sqlalchemy.types.DATE, - "timestamp_with_timezone": sqlalchemy.types.TIMESTAMP, - "timestamp_without_timezone": sqlalchemy.types.TIMESTAMP, - "time_with_timezone": sqlalchemy.types.TIME, - "time_without_timezone": sqlalchemy.types.TIME, - # Technically 'object' and 'array' as JSON Schema types, not airbyte types. - # We include them here for completeness. - "object": sqlalchemy.types.JSON, - "array": sqlalchemy.types.JSON, - "vector_array": sqlalchemy.types.ARRAY, -} - - -class SQLTypeConversionError(Exception): - """An exception to be raised when a type conversion fails.""" - - -def _get_airbyte_type( # noqa: PLR0911 # Too many return statements - json_schema_property_def: dict[str, str | dict[str, Any] | list[Any]], -) -> tuple[str, str | None]: - """Get the airbyte type and subtype from a JSON schema property definition. - - Subtype is only used for array types. Otherwise, subtype will return None. - """ - airbyte_type = cast(str, json_schema_property_def.get("airbyte_type", None)) - if airbyte_type: - return airbyte_type, None - - json_schema_type = json_schema_property_def.get("type", None) - json_schema_format = json_schema_property_def.get("format", None) - - # if json_schema_type is an array of two strings with one of them being null, pick the other one - # this strategy is often used by connectors to indicate a field might not be set all the time - if isinstance(json_schema_type, list): - non_null_types = [t for t in json_schema_type if t != "null"] - if len(non_null_types) == 1: - json_schema_type = non_null_types[0] - - if json_schema_type == "string": - if json_schema_format == "date": - return "date", None - - if json_schema_format == "date-time": - return "timestamp_with_timezone", None - - if json_schema_format == "time": - return "time_without_timezone", None - - if isinstance(json_schema_type, str) and json_schema_type in { - "string", - "number", - "boolean", - "integer", - }: - return json_schema_type, None - - if json_schema_type == "object": - return "object", None - - if json_schema_type == "array": - items_def = json_schema_property_def.get("items", None) - if isinstance(items_def, dict): - try: - subtype, _ = _get_airbyte_type(items_def) - except SQLTypeConversionError: - # We have enough information, so we can ignore parsing errors on subtype. - subtype = None - - return "array", subtype - - return "array", None - - if json_schema_type == "vector_array": - return "vector_array", "Float" - - err_msg = f"Could not determine airbyte type from JSON schema type: {json_schema_property_def}" - raise SQLTypeConversionError(err_msg) - - -class SQLTypeConverter: - """A base class to perform type conversions.""" - - def __init__( - self, - conversion_map: dict[str, Any] | None = None, - ) -> None: - """Initialize the type converter.""" - self.conversion_map = conversion_map or CONVERSION_MAP - - @classmethod - def get_string_type(cls) -> sqlalchemy.types.TypeEngine[str]: - """Get the type to use for string data.""" - return sqlalchemy.types.VARCHAR() - - @classmethod - def get_failover_type(cls) -> sqlalchemy.types.TypeEngine[str]: - """Get the 'last resort' type to use if no other type is found.""" - return cls.get_string_type() - - @classmethod - def get_json_type(cls) -> sqlalchemy.types.TypeEngine[Any]: - """Get the type to use for nested JSON data.""" - return sqlalchemy.types.JSON() - - def to_sql_type( # noqa: PLR0911 # Too many return statements - self, - json_schema_property_def: dict[str, str | dict[str, Any] | list[Any]], - ) -> Any: - """Convert a value to a SQL type.""" - try: - airbyte_type, _ = _get_airbyte_type(json_schema_property_def) - # to-do - is there a better way to check the following - if airbyte_type == "vector_array": - return sqlalchemy.types.ARRAY(sqlalchemy.types.Float()) - sql_type = self.conversion_map[airbyte_type] - except SQLTypeConversionError: - print(f"Could not determine airbyte type from JSON schema: {json_schema_property_def}") - except KeyError: - print(f"Could not find SQL type for airbyte type: {airbyte_type}") - else: - # No exceptions were raised, so we can return the SQL type. - if isinstance(sql_type, type): - # This is a class. Call its constructor. - sql_type = sql_type() - - return sql_type - - json_schema_type = json_schema_property_def.get("type", None) - json_schema_format = json_schema_property_def.get("format", None) - - if json_schema_type == "string" and json_schema_format == "date": - return sqlalchemy.types.DATE() - - if json_schema_type == "string" and json_schema_format == "date-time": - return sqlalchemy.types.TIMESTAMP() - - if json_schema_type == "array": - return sqlalchemy.types.JSON() - - if json_schema_type == "object": - return sqlalchemy.types.JSON() - - return self.get_failover_type() diff --git a/airbyte-cdk/python/airbyte_cdk/test/__init__.py b/airbyte-cdk/python/airbyte_cdk/test/__init__.py deleted file mode 100644 index 6d3fabb5a354..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/test/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -""" -This package is provided as tooling to help sources test their implementation. It is not expected to be used as production code. -""" diff --git a/airbyte-cdk/python/airbyte_cdk/test/catalog_builder.py b/airbyte-cdk/python/airbyte_cdk/test/catalog_builder.py deleted file mode 100644 index 235be7c579b6..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/test/catalog_builder.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -from typing import Any, Dict, List, Union, overload - -from airbyte_cdk.models import ConfiguredAirbyteCatalog, ConfiguredAirbyteStream, ConfiguredAirbyteStreamSerializer, SyncMode - - -class ConfiguredAirbyteStreamBuilder: - def __init__(self) -> None: - self._stream: Dict[str, Any] = { - "stream": { - "name": "any name", - "json_schema": {}, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_primary_key": [["id"]], - }, - "primary_key": [["id"]], - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite", - } - - def with_name(self, name: str) -> "ConfiguredAirbyteStreamBuilder": - self._stream["stream"]["name"] = name # type: ignore # we assume that self._stream["stream"] is a Dict[str, Any] - return self - - def with_sync_mode(self, sync_mode: SyncMode) -> "ConfiguredAirbyteStreamBuilder": - self._stream["sync_mode"] = sync_mode.name - return self - - def with_primary_key(self, pk: List[List[str]]) -> "ConfiguredAirbyteStreamBuilder": - self._stream["primary_key"] = pk - self._stream["stream"]["source_defined_primary_key"] = pk # type: ignore # we assume that self._stream["stream"] is a Dict[str, Any] - return self - - def with_json_schema(self, json_schema: Dict[str, Any]) -> "ConfiguredAirbyteStreamBuilder": - self._stream["stream"]["json_schema"] = json_schema - return self - - def build(self) -> ConfiguredAirbyteStream: - return ConfiguredAirbyteStreamSerializer.load(self._stream) - - -class CatalogBuilder: - def __init__(self) -> None: - self._streams: List[ConfiguredAirbyteStreamBuilder] = [] - - @overload - def with_stream(self, name: ConfiguredAirbyteStreamBuilder) -> "CatalogBuilder": - ... - - @overload - def with_stream(self, name: str, sync_mode: SyncMode) -> "CatalogBuilder": - ... - - def with_stream(self, name: Union[str, ConfiguredAirbyteStreamBuilder], sync_mode: Union[SyncMode, None] = None) -> "CatalogBuilder": - # As we are introducing a fully fledge ConfiguredAirbyteStreamBuilder, we would like to deprecate the previous interface - # with_stream(str, SyncMode) - - # to avoid a breaking change, `name` needs to stay in the API but this can be either a name or a builder - name_or_builder = name - builder = ( - name_or_builder - if isinstance(name_or_builder, ConfiguredAirbyteStreamBuilder) - else ConfiguredAirbyteStreamBuilder().with_name(name_or_builder).with_sync_mode(sync_mode) - ) - self._streams.append(builder) - return self - - def build(self) -> ConfiguredAirbyteCatalog: - return ConfiguredAirbyteCatalog(streams=list(map(lambda builder: builder.build(), self._streams))) diff --git a/airbyte-cdk/python/airbyte_cdk/test/entrypoint_wrapper.py b/airbyte-cdk/python/airbyte_cdk/test/entrypoint_wrapper.py deleted file mode 100644 index 9cc74ec2669b..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/test/entrypoint_wrapper.py +++ /dev/null @@ -1,225 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -""" -The AirbyteEntrypoint is important because it is a service layer that orchestrate how we execute commands from the -[common interface](https://docs.airbyte.com/understanding-airbyte/airbyte-protocol#common-interface) through the source Python -implementation. There is some logic about which message we send to the platform and when which is relevant for integration testing. Other -than that, there are integrations point that are annoying to integrate with using Python code: -* Sources communicate with the platform using stdout. The implication is that the source could just print every message instead of - returning things to source. or to using the message repository. WARNING: As part of integration testing, we will not support - messages that are simply printed. The reason is that capturing stdout relies on overriding sys.stdout (see - https://docs.python.org/3/library/contextlib.html#contextlib.redirect_stdout) which clashes with how pytest captures logs and brings - considerations for multithreaded applications. If code you work with uses `print` statements, please migrate to - source.message_repository to emit those messages -* The entrypoint interface relies on file being written on the file system -""" - -import json -import logging -import re -import tempfile -import traceback -from io import StringIO -from pathlib import Path -from typing import Any, List, Mapping, Optional, Union - -from airbyte_cdk.entrypoint import AirbyteEntrypoint -from airbyte_cdk.exception_handler import assemble_uncaught_exception -from airbyte_cdk.logger import AirbyteLogFormatter -from airbyte_cdk.models import ( - AirbyteLogMessage, - AirbyteMessage, - AirbyteMessageSerializer, - AirbyteStateMessage, - AirbyteStateMessageSerializer, - AirbyteStreamStatus, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteCatalogSerializer, - Level, - TraceType, - Type, -) -from airbyte_cdk.sources import Source -from orjson import orjson -from pydantic import ValidationError as V2ValidationError -from serpyco_rs import SchemaValidationError - - -class EntrypointOutput: - def __init__(self, messages: List[str], uncaught_exception: Optional[BaseException] = None): - try: - self._messages = [self._parse_message(message) for message in messages] - except V2ValidationError as exception: - raise ValueError("All messages are expected to be AirbyteMessage") from exception - - if uncaught_exception: - self._messages.append(assemble_uncaught_exception(type(uncaught_exception), uncaught_exception).as_airbyte_message()) - - @staticmethod - def _parse_message(message: str) -> AirbyteMessage: - try: - return AirbyteMessageSerializer.load(orjson.loads(message)) # type: ignore[no-any-return] # Serializer.load() always returns AirbyteMessage - except (orjson.JSONDecodeError, SchemaValidationError): - # The platform assumes that logs that are not of AirbyteMessage format are log messages - return AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=Level.INFO, message=message)) - - @property - def records_and_state_messages(self) -> List[AirbyteMessage]: - return self._get_message_by_types([Type.RECORD, Type.STATE]) - - @property - def records(self) -> List[AirbyteMessage]: - return self._get_message_by_types([Type.RECORD]) - - @property - def state_messages(self) -> List[AirbyteMessage]: - return self._get_message_by_types([Type.STATE]) - - @property - def most_recent_state(self) -> Any: - state_messages = self._get_message_by_types([Type.STATE]) - if not state_messages: - raise ValueError("Can't provide most recent state as there are no state messages") - return state_messages[-1].state.stream # type: ignore[union-attr] # state has `stream` - - @property - def logs(self) -> List[AirbyteMessage]: - return self._get_message_by_types([Type.LOG]) - - @property - def trace_messages(self) -> List[AirbyteMessage]: - return self._get_message_by_types([Type.TRACE]) - - @property - def analytics_messages(self) -> List[AirbyteMessage]: - return self._get_trace_message_by_trace_type(TraceType.ANALYTICS) - - @property - def errors(self) -> List[AirbyteMessage]: - return self._get_trace_message_by_trace_type(TraceType.ERROR) - - @property - def catalog(self) -> AirbyteMessage: - catalog = self._get_message_by_types([Type.CATALOG]) - if len(catalog) != 1: - raise ValueError(f"Expected exactly one catalog but got {len(catalog)}") - return catalog[0] - - def get_stream_statuses(self, stream_name: str) -> List[AirbyteStreamStatus]: - status_messages = map( - lambda message: message.trace.stream_status.status, # type: ignore - filter( - lambda message: message.trace.stream_status.stream_descriptor.name == stream_name, # type: ignore # callable; trace has `stream_status` - self._get_trace_message_by_trace_type(TraceType.STREAM_STATUS), - ), - ) - return list(status_messages) - - def _get_message_by_types(self, message_types: List[Type]) -> List[AirbyteMessage]: - return [message for message in self._messages if message.type in message_types] - - def _get_trace_message_by_trace_type(self, trace_type: TraceType) -> List[AirbyteMessage]: - return [message for message in self._get_message_by_types([Type.TRACE]) if message.trace.type == trace_type] # type: ignore[union-attr] # trace has `type` - - def is_in_logs(self, pattern: str) -> bool: - """Check if any log message case-insensitive matches the pattern.""" - return any(re.search(pattern, entry.log.message, flags=re.IGNORECASE) for entry in self.logs) # type: ignore[union-attr] # log has `message` - - def is_not_in_logs(self, pattern: str) -> bool: - """Check if no log message matches the case-insensitive pattern.""" - return not self.is_in_logs(pattern) - - -def _run_command(source: Source, args: List[str], expecting_exception: bool = False) -> EntrypointOutput: - log_capture_buffer = StringIO() - stream_handler = logging.StreamHandler(log_capture_buffer) - stream_handler.setLevel(logging.INFO) - stream_handler.setFormatter(AirbyteLogFormatter()) - parent_logger = logging.getLogger("") - parent_logger.addHandler(stream_handler) - - parsed_args = AirbyteEntrypoint.parse_args(args) - - source_entrypoint = AirbyteEntrypoint(source) - messages = [] - uncaught_exception = None - try: - for message in source_entrypoint.run(parsed_args): - messages.append(message) - except Exception as exception: - if not expecting_exception: - print("Printing unexpected error from entrypoint_wrapper") - print("".join(traceback.format_exception(None, exception, exception.__traceback__))) - uncaught_exception = exception - - captured_logs = log_capture_buffer.getvalue().split("\n")[:-1] - - parent_logger.removeHandler(stream_handler) - - return EntrypointOutput(messages + captured_logs, uncaught_exception) - - -def discover( - source: Source, - config: Mapping[str, Any], - expecting_exception: bool = False, -) -> EntrypointOutput: - """ - config must be json serializable - :param expecting_exception: By default if there is an uncaught exception, the exception will be printed out. If this is expected, please - provide expecting_exception=True so that the test output logs are cleaner - """ - - with tempfile.TemporaryDirectory() as tmp_directory: - tmp_directory_path = Path(tmp_directory) - config_file = make_file(tmp_directory_path / "config.json", config) - - return _run_command(source, ["discover", "--config", config_file, "--debug"], expecting_exception) - - -def read( - source: Source, - config: Mapping[str, Any], - catalog: ConfiguredAirbyteCatalog, - state: Optional[List[AirbyteStateMessage]] = None, - expecting_exception: bool = False, -) -> EntrypointOutput: - """ - config and state must be json serializable - - :param expecting_exception: By default if there is an uncaught exception, the exception will be printed out. If this is expected, please - provide expecting_exception=True so that the test output logs are cleaner - """ - with tempfile.TemporaryDirectory() as tmp_directory: - tmp_directory_path = Path(tmp_directory) - config_file = make_file(tmp_directory_path / "config.json", config) - catalog_file = make_file( - tmp_directory_path / "catalog.json", orjson.dumps(ConfiguredAirbyteCatalogSerializer.dump(catalog)).decode() - ) - args = [ - "read", - "--config", - config_file, - "--catalog", - catalog_file, - ] - if state is not None: - args.extend( - [ - "--state", - make_file( - tmp_directory_path / "state.json", - f"[{','.join([orjson.dumps(AirbyteStateMessageSerializer.dump(stream_state)).decode() for stream_state in state])}]", - ), - ] - ) - - return _run_command(source, args, expecting_exception) - - -def make_file(path: Path, file_contents: Optional[Union[str, Mapping[str, Any], List[Mapping[str, Any]]]]) -> str: - if isinstance(file_contents, str): - path.write_text(file_contents) - else: - path.write_text(json.dumps(file_contents)) - return str(path) diff --git a/airbyte-cdk/python/airbyte_cdk/test/mock_http/__init__.py b/airbyte-cdk/python/airbyte_cdk/test/mock_http/__init__.py deleted file mode 100644 index 88b28b0225e8..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/test/mock_http/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from airbyte_cdk.test.mock_http.matcher import HttpRequestMatcher -from airbyte_cdk.test.mock_http.request import HttpRequest -from airbyte_cdk.test.mock_http.response import HttpResponse -from airbyte_cdk.test.mock_http.mocker import HttpMocker - -__all__ = ["HttpMocker", "HttpRequest", "HttpRequestMatcher", "HttpResponse"] diff --git a/airbyte-cdk/python/airbyte_cdk/test/mock_http/matcher.py b/airbyte-cdk/python/airbyte_cdk/test/mock_http/matcher.py deleted file mode 100644 index 441a765b7321..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/test/mock_http/matcher.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -from airbyte_cdk.test.mock_http.request import HttpRequest - - -class HttpRequestMatcher: - def __init__(self, request: HttpRequest, minimum_number_of_expected_match: int): - self._request_to_match = request - self._minimum_number_of_expected_match = minimum_number_of_expected_match - self._actual_number_of_matches = 0 - - def matches(self, request: HttpRequest) -> bool: - hit = request.matches(self._request_to_match) - if hit: - self._actual_number_of_matches += 1 - return hit - - def has_expected_match_count(self) -> bool: - return self._actual_number_of_matches >= self._minimum_number_of_expected_match - - @property - def actual_number_of_matches(self) -> int: - return self._actual_number_of_matches - - @property - def request(self) -> HttpRequest: - return self._request_to_match - - def __str__(self) -> str: - return ( - f"HttpRequestMatcher(" - f"request_to_match={self._request_to_match}, " - f"minimum_number_of_expected_match={self._minimum_number_of_expected_match}, " - f"actual_number_of_matches={self._actual_number_of_matches})" - ) diff --git a/airbyte-cdk/python/airbyte_cdk/test/mock_http/mocker.py b/airbyte-cdk/python/airbyte_cdk/test/mock_http/mocker.py deleted file mode 100644 index 90d4745372b3..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/test/mock_http/mocker.py +++ /dev/null @@ -1,133 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -import contextlib -import functools -from enum import Enum -from types import TracebackType -from typing import Callable, List, Optional, Union - -import requests_mock -from airbyte_cdk.test.mock_http import HttpRequest, HttpRequestMatcher, HttpResponse - - -class SupportedHttpMethods(str, Enum): - GET = "get" - PATCH = "patch" - POST = "post" - DELETE = "delete" - - -class HttpMocker(contextlib.ContextDecorator): - """ - WARNING 1: This implementation only works if the lib used to perform HTTP requests is `requests`. - - WARNING 2: Given multiple requests that are not mutually exclusive, the request will match the first one. This can happen in scenarios - where the same request is added twice (in which case there will always be an exception because we will never match the second - request) or in a case like this: - ``` - http_mocker.get(HttpRequest(_A_URL, headers={"less_granular": "1", "more_granular": "2"}), <...>) - http_mocker.get(HttpRequest(_A_URL, headers={"less_granular": "1"}), <...>) - requests.get(_A_URL, headers={"less_granular": "1", "more_granular": "2"}) - ``` - In the example above, the matcher would match the second mock as requests_mock iterate over the matcher in reverse order (see - https://github.com/jamielennox/requests-mock/blob/c06f124a33f56e9f03840518e19669ba41b93202/requests_mock/adapter.py#L246) even - though the request sent is a better match for the first `http_mocker.get`. - """ - - def __init__(self) -> None: - self._mocker = requests_mock.Mocker() - self._matchers: List[HttpRequestMatcher] = [] - - def __enter__(self) -> "HttpMocker": - self._mocker.__enter__() - return self - - def __exit__(self, exc_type: Optional[BaseException], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType]) -> None: - self._mocker.__exit__(exc_type, exc_val, exc_tb) - - def _validate_all_matchers_called(self) -> None: - for matcher in self._matchers: - if not matcher.has_expected_match_count(): - raise ValueError(f"Invalid number of matches for `{matcher}`") - - def _mock_request_method( - self, method: SupportedHttpMethods, request: HttpRequest, responses: Union[HttpResponse, List[HttpResponse]] - ) -> None: - if isinstance(responses, HttpResponse): - responses = [responses] - - matcher = HttpRequestMatcher(request, len(responses)) - self._matchers.append(matcher) - - getattr(self._mocker, method)( - requests_mock.ANY, - additional_matcher=self._matches_wrapper(matcher), - response_list=[ - {"text": response.body, "status_code": response.status_code, "headers": response.headers} for response in responses - ], - ) - - def get(self, request: HttpRequest, responses: Union[HttpResponse, List[HttpResponse]]) -> None: - self._mock_request_method(SupportedHttpMethods.GET, request, responses) - - def patch(self, request: HttpRequest, responses: Union[HttpResponse, List[HttpResponse]]) -> None: - self._mock_request_method(SupportedHttpMethods.PATCH, request, responses) - - def post(self, request: HttpRequest, responses: Union[HttpResponse, List[HttpResponse]]) -> None: - self._mock_request_method(SupportedHttpMethods.POST, request, responses) - - def delete(self, request: HttpRequest, responses: Union[HttpResponse, List[HttpResponse]]) -> None: - self._mock_request_method(SupportedHttpMethods.DELETE, request, responses) - - @staticmethod - def _matches_wrapper(matcher: HttpRequestMatcher) -> Callable[[requests_mock.request._RequestObjectProxy], bool]: - def matches(requests_mock_request: requests_mock.request._RequestObjectProxy) -> bool: - # query_params are provided as part of `requests_mock_request.url` - http_request = HttpRequest( - requests_mock_request.url, query_params={}, headers=requests_mock_request.headers, body=requests_mock_request.body - ) - return matcher.matches(http_request) - - return matches - - def assert_number_of_calls(self, request: HttpRequest, number_of_calls: int) -> None: - corresponding_matchers = list(filter(lambda matcher: matcher.request == request, self._matchers)) - if len(corresponding_matchers) != 1: - raise ValueError(f"Was expecting only one matcher to match the request but got `{corresponding_matchers}`") - - assert corresponding_matchers[0].actual_number_of_matches == number_of_calls - - # trying to type that using callables provides the error `incompatible with return type "_F" in supertype "ContextDecorator"` - def __call__(self, f): # type: ignore - @functools.wraps(f) - def wrapper(*args, **kwargs): # type: ignore # this is a very generic wrapper that does not need to be typed - with self: - assertion_error = None - - kwargs["http_mocker"] = self - try: - result = f(*args, **kwargs) - except requests_mock.NoMockAddress as no_mock_exception: - matchers_as_string = "\n\t".join(map(lambda matcher: str(matcher.request), self._matchers)) - raise ValueError( - f"No matcher matches {no_mock_exception.args[0]} with headers `{no_mock_exception.request.headers}` " - f"and body `{no_mock_exception.request.body}`. " - f"Matchers currently configured are:\n\t{matchers_as_string}." - ) from no_mock_exception - except AssertionError as test_assertion: - assertion_error = test_assertion - - # We validate the matchers before raising the assertion error because we want to show the tester if an HTTP request wasn't - # mocked correctly - try: - self._validate_all_matchers_called() - except ValueError as http_mocker_exception: - # This seems useless as it catches ValueError and raises ValueError but without this, the prevailing error message in - # the output is the function call that failed the assertion, whereas raising `ValueError(http_mocker_exception)` - # like we do here provides additional context for the exception. - raise ValueError(http_mocker_exception) from None - if assertion_error: - raise assertion_error - return result - - return wrapper diff --git a/airbyte-cdk/python/airbyte_cdk/test/mock_http/request.py b/airbyte-cdk/python/airbyte_cdk/test/mock_http/request.py deleted file mode 100644 index a2b6bdb9430a..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/test/mock_http/request.py +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -import json -from typing import Any, List, Mapping, Optional, Union -from urllib.parse import parse_qs, urlencode, urlparse - -ANY_QUERY_PARAMS = "any query_parameters" - - -def _is_subdict(small: Mapping[str, str], big: Mapping[str, str]) -> bool: - return dict(big, **small) == big - - -class HttpRequest: - def __init__( - self, - url: str, - query_params: Optional[Union[str, Mapping[str, Union[str, List[str]]]]] = None, - headers: Optional[Mapping[str, str]] = None, - body: Optional[Union[str, bytes, Mapping[str, Any]]] = None, - ) -> None: - self._parsed_url = urlparse(url) - self._query_params = query_params - if not self._parsed_url.query and query_params: - self._parsed_url = urlparse(f"{url}?{self._encode_qs(query_params)}") - elif self._parsed_url.query and query_params: - raise ValueError("If query params are provided as part of the url, `query_params` should be empty") - - self._headers = headers or {} - self._body = body - - @staticmethod - def _encode_qs(query_params: Union[str, Mapping[str, Union[str, List[str]]]]) -> str: - if isinstance(query_params, str): - return query_params - return urlencode(query_params, doseq=True) - - def matches(self, other: Any) -> bool: - """ - If the body of any request is a Mapping, we compare as Mappings which means that the order is not important. - If the body is a string, encoding ISO-8859-1 will be assumed - Headers only need to be a subset of `other` in order to match - """ - if isinstance(other, HttpRequest): - # if `other` is a mapping, we match as an object and formatting is not considers - if isinstance(self._body, Mapping) or isinstance(other._body, Mapping): - body_match = self._to_mapping(self._body) == self._to_mapping(other._body) - else: - body_match = self._to_bytes(self._body) == self._to_bytes(other._body) - - return ( - self._parsed_url.scheme == other._parsed_url.scheme - and self._parsed_url.hostname == other._parsed_url.hostname - and self._parsed_url.path == other._parsed_url.path - and ( - ANY_QUERY_PARAMS in (self._query_params, other._query_params) - or parse_qs(self._parsed_url.query) == parse_qs(other._parsed_url.query) - ) - and _is_subdict(other._headers, self._headers) - and body_match - ) - return False - - @staticmethod - def _to_mapping(body: Optional[Union[str, bytes, Mapping[str, Any]]]) -> Optional[Mapping[str, Any]]: - if isinstance(body, Mapping): - return body - elif isinstance(body, bytes): - return json.loads(body.decode()) # type: ignore # assumes return type of Mapping[str, Any] - elif isinstance(body, str): - return json.loads(body) # type: ignore # assumes return type of Mapping[str, Any] - return None - - @staticmethod - def _to_bytes(body: Optional[Union[str, bytes]]) -> bytes: - if isinstance(body, bytes): - return body - elif isinstance(body, str): - # `ISO-8859-1` is the default encoding used by requests - return body.encode("ISO-8859-1") - return b"" - - def __str__(self) -> str: - return f"{self._parsed_url} with headers {self._headers} and body {self._body!r})" - - def __repr__(self) -> str: - return f"HttpRequest(request={self._parsed_url}, headers={self._headers}, body={self._body!r})" diff --git a/airbyte-cdk/python/airbyte_cdk/test/mock_http/response.py b/airbyte-cdk/python/airbyte_cdk/test/mock_http/response.py deleted file mode 100644 index 8d5dc4c308da..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/test/mock_http/response.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -from types import MappingProxyType -from typing import Mapping - - -class HttpResponse: - def __init__(self, body: str, status_code: int = 200, headers: Mapping[str, str] = MappingProxyType({})): - self._body = body - self._status_code = status_code - self._headers = headers - - @property - def body(self) -> str: - return self._body - - @property - def status_code(self) -> int: - return self._status_code - - @property - def headers(self) -> Mapping[str, str]: - return self._headers diff --git a/airbyte-cdk/python/airbyte_cdk/test/mock_http/response_builder.py b/airbyte-cdk/python/airbyte_cdk/test/mock_http/response_builder.py deleted file mode 100644 index 27bb5125d396..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/test/mock_http/response_builder.py +++ /dev/null @@ -1,207 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -import functools -import json -from abc import ABC, abstractmethod -from pathlib import Path as FilePath -from typing import Any, Dict, List, Optional, Union - -from airbyte_cdk.test.mock_http import HttpResponse -from airbyte_cdk.test.utils.data import get_unit_test_folder - - -def _extract(path: List[str], response_template: Dict[str, Any]) -> Any: - return functools.reduce(lambda a, b: a[b], path, response_template) - - -def _replace_value(dictionary: Dict[str, Any], path: List[str], value: Any) -> None: - current = dictionary - for key in path[:-1]: - current = current[key] - current[path[-1]] = value - - -def _write(dictionary: Dict[str, Any], path: List[str], value: Any) -> None: - current = dictionary - for key in path[:-1]: - current = current.setdefault(key, {}) - current[path[-1]] = value - - -class Path(ABC): - @abstractmethod - def write(self, template: Dict[str, Any], value: Any) -> None: - pass - - @abstractmethod - def update(self, template: Dict[str, Any], value: Any) -> None: - pass - - def extract(self, template: Dict[str, Any]) -> Any: - pass - - -class FieldPath(Path): - def __init__(self, field: str): - self._path = [field] - - def write(self, template: Dict[str, Any], value: Any) -> None: - _write(template, self._path, value) - - def update(self, template: Dict[str, Any], value: Any) -> None: - _replace_value(template, self._path, value) - - def extract(self, template: Dict[str, Any]) -> Any: - return _extract(self._path, template) - - def __str__(self) -> str: - return f"FieldPath(field={self._path[0]})" - - -class NestedPath(Path): - def __init__(self, path: List[str]): - self._path = path - - def write(self, template: Dict[str, Any], value: Any) -> None: - _write(template, self._path, value) - - def update(self, template: Dict[str, Any], value: Any) -> None: - _replace_value(template, self._path, value) - - def extract(self, template: Dict[str, Any]) -> Any: - return _extract(self._path, template) - - def __str__(self) -> str: - return f"NestedPath(path={self._path})" - - -class PaginationStrategy(ABC): - @abstractmethod - def update(self, response: Dict[str, Any]) -> None: - pass - - -class FieldUpdatePaginationStrategy(PaginationStrategy): - def __init__(self, path: Path, value: Any): - self._path = path - self._value = value - - def update(self, response: Dict[str, Any]) -> None: - self._path.update(response, self._value) - - -class RecordBuilder: - def __init__(self, template: Dict[str, Any], id_path: Optional[Path], cursor_path: Optional[Union[FieldPath, NestedPath]]): - self._record = template - self._id_path = id_path - self._cursor_path = cursor_path - - self._validate_template() - - def _validate_template(self) -> None: - paths_to_validate = [ - ("_id_path", self._id_path), - ("_cursor_path", self._cursor_path), - ] - for field_name, field_path in paths_to_validate: - self._validate_field(field_name, field_path) - - def _validate_field(self, field_name: str, path: Optional[Path]) -> None: - try: - if path and not path.extract(self._record): - raise ValueError(f"{field_name} `{path}` was provided but it is not part of the template `{self._record}`") - except (IndexError, KeyError) as exception: - raise ValueError(f"{field_name} `{path}` was provided but it is not part of the template `{self._record}`") from exception - - def with_id(self, identifier: Any) -> "RecordBuilder": - self._set_field("id", self._id_path, identifier) - return self - - def with_cursor(self, cursor_value: Any) -> "RecordBuilder": - self._set_field("cursor", self._cursor_path, cursor_value) - return self - - def with_field(self, path: Path, value: Any) -> "RecordBuilder": - path.write(self._record, value) - return self - - def _set_field(self, field_name: str, path: Optional[Path], value: Any) -> None: - if not path: - raise ValueError( - f"{field_name}_path was not provided and hence, the record {field_name} can't be modified. Please provide `id_field` while " - f"instantiating RecordBuilder to leverage this capability" - ) - path.update(self._record, value) - - def build(self) -> Dict[str, Any]: - return self._record - - -class HttpResponseBuilder: - def __init__( - self, template: Dict[str, Any], records_path: Union[FieldPath, NestedPath], pagination_strategy: Optional[PaginationStrategy] - ): - self._response = template - self._records: List[RecordBuilder] = [] - self._records_path = records_path - self._pagination_strategy = pagination_strategy - self._status_code = 200 - - def with_record(self, record: RecordBuilder) -> "HttpResponseBuilder": - self._records.append(record) - return self - - def with_pagination(self) -> "HttpResponseBuilder": - if not self._pagination_strategy: - raise ValueError( - "`pagination_strategy` was not provided and hence, fields related to the pagination can't be modified. Please provide " - "`pagination_strategy` while instantiating ResponseBuilder to leverage this capability" - ) - self._pagination_strategy.update(self._response) - return self - - def with_status_code(self, status_code: int) -> "HttpResponseBuilder": - self._status_code = status_code - return self - - def build(self) -> HttpResponse: - self._records_path.update(self._response, [record.build() for record in self._records]) - return HttpResponse(json.dumps(self._response), self._status_code) - - -def _get_unit_test_folder(execution_folder: str) -> FilePath: - # FIXME: This function should be removed after the next CDK release to avoid breaking amazon-seller-partner test code. - return get_unit_test_folder(execution_folder) # type: ignore # get_unit_test_folder is known to return a FilePath - - -def find_template(resource: str, execution_folder: str) -> Dict[str, Any]: - response_template_filepath = str(get_unit_test_folder(execution_folder) / "resource" / "http" / "response" / f"{resource}.json") - with open(response_template_filepath, "r") as template_file: - return json.load(template_file) # type: ignore # we assume the dev correctly set up the resource file - - -def create_record_builder( - response_template: Dict[str, Any], - records_path: Union[FieldPath, NestedPath], - record_id_path: Optional[Path] = None, - record_cursor_path: Optional[Union[FieldPath, NestedPath]] = None, -) -> RecordBuilder: - """ - This will use the first record define at `records_path` as a template for the records. If more records are defined, they will be ignored - """ - try: - record_template = records_path.extract(response_template)[0] - if not record_template: - raise ValueError( - f"Could not extract any record from template at path `{records_path}`. " - f"Please fix the template to provide a record sample or fix `records_path`." - ) - return RecordBuilder(record_template, record_id_path, record_cursor_path) - except (IndexError, KeyError): - raise ValueError(f"Error while extracting records at path `{records_path}` from response template `{response_template}`") - - -def create_response_builder( - response_template: Dict[str, Any], records_path: Union[FieldPath, NestedPath], pagination_strategy: Optional[PaginationStrategy] = None -) -> HttpResponseBuilder: - return HttpResponseBuilder(response_template, records_path, pagination_strategy) diff --git a/airbyte-cdk/python/airbyte_cdk/test/state_builder.py b/airbyte-cdk/python/airbyte_cdk/test/state_builder.py deleted file mode 100644 index 50b5dbe5f793..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/test/state_builder.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -from typing import Any, List - -from airbyte_cdk.models import AirbyteStateBlob, AirbyteStateMessage, AirbyteStateType, AirbyteStreamState, StreamDescriptor - - -class StateBuilder: - def __init__(self) -> None: - self._state: List[AirbyteStateMessage] = [] - - def with_stream_state(self, stream_name: str, state: Any) -> "StateBuilder": - self._state.append( - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_state=state if isinstance(state, AirbyteStateBlob) else AirbyteStateBlob(state), - stream_descriptor=StreamDescriptor(**{"name": stream_name}), - ), - ) - ) - return self - - def build(self) -> List[AirbyteStateMessage]: - return self._state diff --git a/airbyte-cdk/python/airbyte_cdk/test/utils/__init__.py b/airbyte-cdk/python/airbyte_cdk/test/utils/__init__.py deleted file mode 100644 index 7f66676b8716..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/test/utils/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. diff --git a/airbyte-cdk/python/airbyte_cdk/test/utils/data.py b/airbyte-cdk/python/airbyte_cdk/test/utils/data.py deleted file mode 100644 index a4d4fef6d2a5..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/test/utils/data.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from pydantic import FilePath - - -def get_unit_test_folder(execution_folder: str) -> FilePath: - path = FilePath(execution_folder) - while path.name != "unit_tests": - if path.name == path.root or path.name == path.drive: - raise ValueError(f"Could not find `unit_tests` folder as a parent of {execution_folder}") - path = path.parent - return path - - -def read_resource_file_contents(resource: str, test_location: str) -> str: - """Read the contents of a test data file from the test resource folder.""" - file_path = str(get_unit_test_folder(test_location) / "resource" / "http" / "response" / f"{resource}") - with open(file_path) as f: - response = f.read() - return response diff --git a/airbyte-cdk/python/airbyte_cdk/test/utils/http_mocking.py b/airbyte-cdk/python/airbyte_cdk/test/utils/http_mocking.py deleted file mode 100644 index 0cdd8f4cef1b..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/test/utils/http_mocking.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -import re -from typing import Any, Mapping - -from requests_mock import Mocker - - -def register_mock_responses(mocker: Mocker, http_calls: list[Mapping[str, Mapping[str, Any]]]) -> None: - """Register a list of HTTP request-response pairs.""" - for call in http_calls: - request, response = call["request"], call["response"] - matcher = re.compile(request["url"]) if request["is_regex"] else request["url"] - mocker.register_uri(request["method"], matcher, **response) diff --git a/airbyte-cdk/python/airbyte_cdk/test/utils/reading.py b/airbyte-cdk/python/airbyte_cdk/test/utils/reading.py deleted file mode 100644 index 2d89cb870984..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/test/utils/reading.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from typing import Any, List, Mapping, Optional - -from airbyte_cdk import AbstractSource -from airbyte_cdk.models import AirbyteStateMessage, ConfiguredAirbyteCatalog, SyncMode -from airbyte_cdk.test.catalog_builder import CatalogBuilder -from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read - - -def catalog(stream_name: str, sync_mode: SyncMode) -> ConfiguredAirbyteCatalog: - """Create a catalog with a single stream.""" - return CatalogBuilder().with_stream(stream_name, sync_mode).build() - - -def read_records( - source: AbstractSource, - config: Mapping[str, Any], - stream_name: str, - sync_mode: SyncMode, - state: Optional[List[AirbyteStateMessage]] = None, - expecting_exception: bool = False, -) -> EntrypointOutput: - """Read records from a stream.""" - _catalog = catalog(stream_name, sync_mode) - return read(source, config, _catalog, state, expecting_exception) diff --git a/airbyte-cdk/python/airbyte_cdk/utils/__init__.py b/airbyte-cdk/python/airbyte_cdk/utils/__init__.py deleted file mode 100644 index 70b1375b0e83..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/utils/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from .is_cloud_environment import is_cloud_environment -from .schema_inferrer import SchemaInferrer -from .traced_exception import AirbyteTracedException -from .print_buffer import PrintBuffer - -__all__ = ["AirbyteTracedException", "SchemaInferrer", "is_cloud_environment", "PrintBuffer"] diff --git a/airbyte-cdk/python/airbyte_cdk/utils/airbyte_secrets_utils.py b/airbyte-cdk/python/airbyte_cdk/utils/airbyte_secrets_utils.py deleted file mode 100644 index 5afd305f38ed..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/utils/airbyte_secrets_utils.py +++ /dev/null @@ -1,78 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, List, Mapping - -import dpath - - -def get_secret_paths(spec: Mapping[str, Any]) -> List[List[str]]: - paths = [] - - def traverse_schema(schema_item: Any, path: List[str]) -> None: - """ - schema_item can be any property or value in the originally input jsonschema, depending on how far down the recursion stack we go - path is the path to that schema item in the original input - for example if we have the input {'password': {'type': 'string', 'airbyte_secret': True}} then the arguments will evolve - as follows: - schema_item=, path=[] - schema_item={'type': 'string', 'airbyte_secret': True}, path=['password'] - schema_item='string', path=['password', 'type'] - schema_item=True, path=['password', 'airbyte_secret'] - """ - if isinstance(schema_item, dict): - for k, v in schema_item.items(): - traverse_schema(v, [*path, k]) - elif isinstance(schema_item, list): - for i in schema_item: - traverse_schema(i, path) - else: - if path[-1] == "airbyte_secret" and schema_item is True: - filtered_path = [p for p in path[:-1] if p not in ["properties", "oneOf"]] - paths.append(filtered_path) - - traverse_schema(spec, []) - return paths - - -def get_secrets(connection_specification: Mapping[str, Any], config: Mapping[str, Any]) -> List[Any]: - """ - Get a list of secret values from the source config based on the source specification - :type connection_specification: the connection_specification field of an AirbyteSpecification i.e the JSONSchema definition - """ - secret_paths = get_secret_paths(connection_specification.get("properties", {})) - result = [] - for path in secret_paths: - try: - result.append(dpath.get(config, path)) - except KeyError: - # Since we try to get paths to all known secrets in the spec, in the case of oneOfs, some secret fields may not be present - # In that case, a KeyError is thrown. This is expected behavior. - pass - return result - - -__SECRETS_FROM_CONFIG: List[str] = [] - - -def update_secrets(secrets: List[str]) -> None: - """Update the list of secrets to be replaced""" - global __SECRETS_FROM_CONFIG - __SECRETS_FROM_CONFIG = secrets - - -def add_to_secrets(secret: str) -> None: - """Add to the list of secrets to be replaced""" - global __SECRETS_FROM_CONFIG - __SECRETS_FROM_CONFIG.append(secret) - - -def filter_secrets(string: str) -> str: - """Filter secrets from a string by replacing them with ****""" - # TODO this should perform a maximal match for each secret. if "x" and "xk" are both secret values, and this method is called twice on - # the input "xk", then depending on call order it might only obfuscate "*k". This is a bug. - for secret in __SECRETS_FROM_CONFIG: - if secret: - string = string.replace(str(secret), "****") - return string diff --git a/airbyte-cdk/python/airbyte_cdk/utils/analytics_message.py b/airbyte-cdk/python/airbyte_cdk/utils/analytics_message.py deleted file mode 100644 index 54c3e984f93c..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/utils/analytics_message.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -import time -from typing import Any, Optional - -from airbyte_cdk.models import AirbyteAnalyticsTraceMessage, AirbyteMessage, AirbyteTraceMessage, TraceType, Type - - -def create_analytics_message(type: str, value: Optional[Any]) -> AirbyteMessage: - return AirbyteMessage( - type=Type.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.ANALYTICS, - emitted_at=time.time() * 1000, - analytics=AirbyteAnalyticsTraceMessage(type=type, value=str(value) if value is not None else None), - ), - ) diff --git a/airbyte-cdk/python/airbyte_cdk/utils/constants.py b/airbyte-cdk/python/airbyte_cdk/utils/constants.py deleted file mode 100644 index 1d6345cbd8f4..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/utils/constants.py +++ /dev/null @@ -1,5 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -ENV_REQUEST_CACHE_PATH = "REQUEST_CACHE_PATH" diff --git a/airbyte-cdk/python/airbyte_cdk/utils/datetime_format_inferrer.py b/airbyte-cdk/python/airbyte_cdk/utils/datetime_format_inferrer.py deleted file mode 100644 index cd423db9c201..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/utils/datetime_format_inferrer.py +++ /dev/null @@ -1,91 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Dict, Optional - -from airbyte_cdk.models import AirbyteRecordMessage -from airbyte_cdk.sources.declarative.datetime.datetime_parser import DatetimeParser - - -class DatetimeFormatInferrer: - """ - This class is used to detect toplevel fields in records that might be datetime values, along with the used format. - """ - - def __init__(self) -> None: - self._parser = DatetimeParser() - self._datetime_candidates: Optional[Dict[str, str]] = None - self._formats = [ - "%Y-%m-%d", - "%Y-%m-%d %H:%M:%S", - "%Y-%m-%dT%H:%M:%SZ", - "%Y-%m-%dT%H:%M:%S.%fZ", - "%Y-%m-%d %H:%M:%S.%f%z", - "%Y-%m-%dT%H:%M:%S.%f%z", - "%s", - "%ms", - "%d/%m/%Y %H:%M", - "%Y-%m", - "%d-%m-%Y", - ] - self._timestamp_heuristic_ranges = [range(1_000_000_000, 2_000_000_000), range(1_000_000_000_000, 2_000_000_000_000)] - - def _can_be_datetime(self, value: Any) -> bool: - """Checks if the value can be a datetime. - This is the case if the value is a string or an integer between 1_000_000_000 and 2_000_000_000 for seconds - or between 1_000_000_000_000 and 2_000_000_000_000 for milliseconds. - This is separate from the format check for performance reasons""" - if isinstance(value, (str, int)): - try: - value_as_int = int(value) - for timestamp_range in self._timestamp_heuristic_ranges: - if value_as_int in timestamp_range: - return True - except ValueError: - # given that it's not parsable as an int, it can represent a datetime with one of the self._formats - return True - return False - - def _matches_format(self, value: Any, format: str) -> bool: - """Checks if the value matches the format""" - try: - self._parser.parse(value, format) - return True - except ValueError: - return False - - def _initialize(self, record: AirbyteRecordMessage) -> None: - """Initializes the internal state of the class""" - self._datetime_candidates = {} - for field_name, field_value in record.data.items(): - if not self._can_be_datetime(field_value): - continue - for format in self._formats: - if self._matches_format(field_value, format): - self._datetime_candidates[field_name] = format - break - - def _validate(self, record: AirbyteRecordMessage) -> None: - """Validates that the record is consistent with the inferred datetime formats""" - if self._datetime_candidates: - for candidate_field_name in list(self._datetime_candidates.keys()): - candidate_field_format = self._datetime_candidates[candidate_field_name] - current_value = record.data.get(candidate_field_name, None) - if ( - current_value is None - or not self._can_be_datetime(current_value) - or not self._matches_format(current_value, candidate_field_format) - ): - self._datetime_candidates.pop(candidate_field_name) - - def accumulate(self, record: AirbyteRecordMessage) -> None: - """Analyzes the record and updates the internal state of candidate datetime fields""" - self._initialize(record) if self._datetime_candidates is None else self._validate(record) - - def get_inferred_datetime_formats(self) -> Dict[str, str]: - """ - Returns the list of candidate datetime fields - the keys are the field names and the values are the inferred datetime formats. - For these fields the format was consistent across all visited records. - """ - return self._datetime_candidates or {} diff --git a/airbyte-cdk/python/airbyte_cdk/utils/event_timing.py b/airbyte-cdk/python/airbyte_cdk/utils/event_timing.py deleted file mode 100644 index 447543ec0b23..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/utils/event_timing.py +++ /dev/null @@ -1,85 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import datetime -import logging -import time -from contextlib import contextmanager -from dataclasses import dataclass, field -from typing import Optional - -logger = logging.getLogger("airbyte") - - -class EventTimer: - """Simple nanosecond resolution event timer for debugging, initially intended to be used to record streams execution - time for a source. - Event nesting follows a LIFO pattern, so finish will apply to the last started event. - """ - - def __init__(self, name): - self.name = name - self.events = {} - self.count = 0 - self.stack = [] - - def start_event(self, name): - """ - Start a new event and push it to the stack. - """ - self.events[name] = Event(name=name) - self.count += 1 - self.stack.insert(0, self.events[name]) - - def finish_event(self): - """ - Finish the current event and pop it from the stack. - """ - - if self.stack: - event = self.stack.pop(0) - event.finish() - else: - logger.warning(f"{self.name} finish_event called without start_event") - - def report(self, order_by="name"): - """ - :param order_by: 'name' or 'duration' - """ - if order_by == "name": - events = sorted(self.events.values(), key=lambda event: event.name) - elif order_by == "duration": - events = sorted(self.events.values(), key=lambda event: event.duration) - text = f"{self.name} runtimes:\n" - text += "\n".join(str(event) for event in events) - return text - - -@dataclass -class Event: - name: str - start: float = field(default_factory=time.perf_counter_ns) - end: Optional[float] = field(default=None) - - @property - def duration(self) -> float: - """Returns the elapsed time in seconds or positive infinity if event was never finished""" - if self.end: - return (self.end - self.start) / 1e9 - return float("+inf") - - def __str__(self): - return f"{self.name} {datetime.timedelta(seconds=self.duration)}" - - def finish(self): - self.end = time.perf_counter_ns() - - -@contextmanager -def create_timer(name): - """ - Creates a new EventTimer as a context manager to improve code readability. - """ - a_timer = EventTimer(name) - yield a_timer diff --git a/airbyte-cdk/python/airbyte_cdk/utils/is_cloud_environment.py b/airbyte-cdk/python/airbyte_cdk/utils/is_cloud_environment.py deleted file mode 100644 index 25b1eee87fad..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/utils/is_cloud_environment.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import os - -CLOUD_DEPLOYMENT_MODE = "cloud" - - -def is_cloud_environment() -> bool: - """ - Returns True if the connector is running in a cloud environment, False otherwise. - - The function checks the value of the DEPLOYMENT_MODE environment variable which is set by the platform. - This function can be used to determine whether stricter security measures should be applied. - """ - deployment_mode = os.environ.get("DEPLOYMENT_MODE", "") - return deployment_mode.casefold() == CLOUD_DEPLOYMENT_MODE diff --git a/airbyte-cdk/python/airbyte_cdk/utils/mapping_helpers.py b/airbyte-cdk/python/airbyte_cdk/utils/mapping_helpers.py deleted file mode 100644 index ae5e898f667d..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/utils/mapping_helpers.py +++ /dev/null @@ -1,43 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from typing import Any, List, Mapping, Optional, Set, Union - - -def combine_mappings(mappings: List[Optional[Union[Mapping[str, Any], str]]]) -> Union[Mapping[str, Any], str]: - """ - Combine multiple mappings into a single mapping. If any of the mappings are a string, return - that string. Raise errors in the following cases: - * If there are duplicate keys across mappings - * If there are multiple string mappings - * If there are multiple mappings containing keys and one of them is a string - """ - all_keys: List[Set[str]] = [] - for part in mappings: - if part is None: - continue - keys = set(part.keys()) if not isinstance(part, str) else set() - all_keys.append(keys) - - string_options = sum(isinstance(mapping, str) for mapping in mappings) - # If more than one mapping is a string, raise a ValueError - if string_options > 1: - raise ValueError("Cannot combine multiple string options") - - if string_options == 1 and sum(len(keys) for keys in all_keys) > 0: - raise ValueError("Cannot combine multiple options if one is a string") - - # If any mapping is a string, return it - for mapping in mappings: - if isinstance(mapping, str): - return mapping - - # If there are duplicate keys across mappings, raise a ValueError - intersection = set().union(*all_keys) - if len(intersection) < sum(len(keys) for keys in all_keys): - raise ValueError(f"Duplicate keys found: {intersection}") - - # Return the combined mappings - return {key: value for mapping in mappings if mapping for key, value in mapping.items()} # type: ignore # mapping can't be string here diff --git a/airbyte-cdk/python/airbyte_cdk/utils/message_utils.py b/airbyte-cdk/python/airbyte_cdk/utils/message_utils.py deleted file mode 100644 index a862d4696495..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/utils/message_utils.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from airbyte_cdk.models import AirbyteMessage, Type -from airbyte_cdk.sources.connector_state_manager import HashableStreamDescriptor - - -def get_stream_descriptor(message: AirbyteMessage) -> HashableStreamDescriptor: - match message.type: - case Type.RECORD: - return HashableStreamDescriptor(name=message.record.stream, namespace=message.record.namespace) # type: ignore[union-attr] # record has `stream` and `namespace` - case Type.STATE: - if not message.state.stream or not message.state.stream.stream_descriptor: # type: ignore[union-attr] # state has `stream` - raise ValueError("State message was not in per-stream state format, which is required for record counts.") - return HashableStreamDescriptor( - name=message.state.stream.stream_descriptor.name, namespace=message.state.stream.stream_descriptor.namespace # type: ignore[union-attr] # state has `stream` - ) - case _: - raise NotImplementedError(f"get_stream_descriptor is not implemented for message type '{message.type}'.") diff --git a/airbyte-cdk/python/airbyte_cdk/utils/oneof_option_config.py b/airbyte-cdk/python/airbyte_cdk/utils/oneof_option_config.py deleted file mode 100644 index 17ebf0511beb..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/utils/oneof_option_config.py +++ /dev/null @@ -1,33 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Dict - - -class OneOfOptionConfig: - """ - Base class to configure a Pydantic model that's used as a oneOf option in a parent model in a way that's compatible with all Airbyte consumers. - - Inherit from this class in the nested Config class in a model and set title and description (these show up in the UI) and discriminator (this is making sure it's marked as required in the schema). - - Usage: - - ```python - class OptionModel(BaseModel): - mode: Literal["option_a"] = Field("option_a", const=True) - option_a_field: str = Field(...) - - class Config(OneOfOptionConfig): - title = "Option A" - description = "Option A description" - discriminator = "mode" - ``` - """ - - @staticmethod - def schema_extra(schema: Dict[str, Any], model: Any) -> None: - if hasattr(model.Config, "description"): - schema["description"] = model.Config.description - if hasattr(model.Config, "discriminator"): - schema.setdefault("required", []).append(model.Config.discriminator) diff --git a/airbyte-cdk/python/airbyte_cdk/utils/print_buffer.py b/airbyte-cdk/python/airbyte_cdk/utils/print_buffer.py deleted file mode 100644 index 51ca2a84b0fe..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/utils/print_buffer.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -import sys -import time -from io import StringIO -from threading import RLock -from types import TracebackType -from typing import Optional - - -class PrintBuffer: - """ - A class to buffer print statements and flush them at a specified interval. - - The PrintBuffer class is designed to capture and buffer output that would - normally be printed to the standard output (stdout). This can be useful for - scenarios where you want to minimize the number of I/O operations by grouping - multiple print statements together and flushing them as a single operation. - - Attributes: - buffer (StringIO): A buffer to store the messages before flushing. - flush_interval (float): The time interval (in seconds) after which the buffer is flushed. - last_flush_time (float): The last time the buffer was flushed. - lock (RLock): A reentrant lock to ensure thread-safe operations. - - Methods: - write(message: str) -> None: - Writes a message to the buffer and flushes if the interval has passed. - - flush() -> None: - Flushes the buffer content to the standard output. - - __enter__() -> "PrintBuffer": - Enters the runtime context related to this object, redirecting stdout and stderr. - - __exit__(exc_type, exc_val, exc_tb) -> None: - Exits the runtime context and restores the original stdout and stderr. - """ - - def __init__(self, flush_interval: float = 0.1): - self.buffer = StringIO() - self.flush_interval = flush_interval - self.last_flush_time = time.monotonic() - self.lock = RLock() - - def write(self, message: str) -> None: - with self.lock: - self.buffer.write(message) - current_time = time.monotonic() - if (current_time - self.last_flush_time) >= self.flush_interval: - self.flush() - self.last_flush_time = current_time - - def flush(self) -> None: - with self.lock: - combined_message = self.buffer.getvalue() - sys.__stdout__.write(combined_message) # type: ignore[union-attr] - self.buffer = StringIO() - - def __enter__(self) -> "PrintBuffer": - self.old_stdout, self.old_stderr = sys.stdout, sys.stderr - # Used to disable buffering during the pytest session, because it is not compatible with capsys - if "pytest" not in str(type(sys.stdout)).lower(): - sys.stdout = self - sys.stderr = self - return self - - def __exit__(self, exc_type: Optional[BaseException], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType]) -> None: - self.flush() - sys.stdout, sys.stderr = self.old_stdout, self.old_stderr diff --git a/airbyte-cdk/python/airbyte_cdk/utils/schema_inferrer.py b/airbyte-cdk/python/airbyte_cdk/utils/schema_inferrer.py deleted file mode 100644 index fd749850900b..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/utils/schema_inferrer.py +++ /dev/null @@ -1,248 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from collections import defaultdict -from typing import Any, Dict, List, Mapping, Optional - -from airbyte_cdk.models import AirbyteRecordMessage -from genson import SchemaBuilder, SchemaNode -from genson.schema.strategies.object import Object -from genson.schema.strategies.scalar import Number - -# schema keywords -_TYPE = "type" -_NULL_TYPE = "null" -_OBJECT_TYPE = "object" -_ANY_OF = "anyOf" -_ITEMS = "items" -_PROPERTIES = "properties" -_REQUIRED = "required" - - -class NoRequiredObj(Object): - """ - This class has Object behaviour, but it does not generate "required[]" fields - every time it parses object. So we don't add unnecessary extra field. - - The logic is that even reading all the data from a source, it does not mean that there can be another record added with those fields as - optional. Hence, we make everything nullable. - """ - - def to_schema(self) -> Mapping[str, Any]: - schema: Dict[str, Any] = super(NoRequiredObj, self).to_schema() - schema.pop("required", None) - return schema - - -class IntegerToNumber(Number): - """ - This class has the regular Number behaviour, but it will never emit an integer type. - """ - - def __init__(self, node_class: SchemaNode): - super().__init__(node_class) - self._type = "number" - - -class NoRequiredSchemaBuilder(SchemaBuilder): - EXTRA_STRATEGIES = (NoRequiredObj, IntegerToNumber) - - -# This type is inferred from the genson lib, but there is no alias provided for it - creating it here for type safety -InferredSchema = Dict[str, Any] - - -class SchemaValidationException(Exception): - @classmethod - def merge_exceptions(cls, exceptions: List["SchemaValidationException"]) -> "SchemaValidationException": - # We assume the schema is the same for all SchemaValidationException - return SchemaValidationException(exceptions[0].schema, [x for exception in exceptions for x in exception._validation_errors]) - - def __init__(self, schema: InferredSchema, validation_errors: List[Exception]): - self._schema = schema - self._validation_errors = validation_errors - - @property - def schema(self) -> InferredSchema: - return self._schema - - @property - def validation_errors(self) -> List[str]: - return list(map(lambda error: str(error), self._validation_errors)) - - -class SchemaInferrer: - """ - This class is used to infer a JSON schema which fits all the records passed into it - throughout its lifecycle via the accumulate method. - - Instances of this class are stateful, meaning they build their inferred schemas - from every record passed into the accumulate method. - - """ - - stream_to_builder: Dict[str, SchemaBuilder] - - def __init__(self, pk: Optional[List[List[str]]] = None, cursor_field: Optional[List[List[str]]] = None) -> None: - self.stream_to_builder = defaultdict(NoRequiredSchemaBuilder) - self._pk = [] if pk is None else pk - self._cursor_field = [] if cursor_field is None else cursor_field - - def accumulate(self, record: AirbyteRecordMessage) -> None: - """Uses the input record to add to the inferred schemas maintained by this object""" - self.stream_to_builder[record.stream].add_object(record.data) - - def _null_type_in_any_of(self, node: InferredSchema) -> bool: - if _ANY_OF in node: - return {_TYPE: _NULL_TYPE} in node[_ANY_OF] - else: - return False - - def _remove_type_from_any_of(self, node: InferredSchema) -> None: - if _ANY_OF in node: - node.pop(_TYPE, None) - - def _clean_any_of(self, node: InferredSchema) -> None: - if len(node[_ANY_OF]) == 2 and self._null_type_in_any_of(node): - real_type = node[_ANY_OF][1] if node[_ANY_OF][0][_TYPE] == _NULL_TYPE else node[_ANY_OF][0] - node.update(real_type) - node[_TYPE] = [node[_TYPE], _NULL_TYPE] - node.pop(_ANY_OF) - # populate `type` for `anyOf` if it's not present to pass all other checks - elif len(node[_ANY_OF]) == 2 and not self._null_type_in_any_of(node): - node[_TYPE] = [_NULL_TYPE] - - def _clean_properties(self, node: InferredSchema) -> None: - for key, value in list(node[_PROPERTIES].items()): - if isinstance(value, dict) and value.get(_TYPE, None) == _NULL_TYPE: - node[_PROPERTIES].pop(key) - else: - self._clean(value) - - def _ensure_null_type_on_top(self, node: InferredSchema) -> None: - if isinstance(node[_TYPE], list): - if _NULL_TYPE in node[_TYPE]: - # we want to make sure null is always at the end as it makes schemas more readable - node[_TYPE].remove(_NULL_TYPE) - node[_TYPE].append(_NULL_TYPE) - else: - node[_TYPE] = [node[_TYPE], _NULL_TYPE] - - def _clean(self, node: InferredSchema) -> InferredSchema: - """ - Recursively cleans up a produced schema: - - remove anyOf if one of them is just a null value - - remove properties of type "null" - """ - - if isinstance(node, dict): - if _ANY_OF in node: - self._clean_any_of(node) - - if _PROPERTIES in node and isinstance(node[_PROPERTIES], dict): - self._clean_properties(node) - - if _ITEMS in node: - self._clean(node[_ITEMS]) - - # this check needs to follow the "anyOf" cleaning as it might populate `type` - self._ensure_null_type_on_top(node) - - # remove added `type: ["null"]` for `anyOf` nested node - self._remove_type_from_any_of(node) - - return node - - def _add_required_properties(self, node: InferredSchema) -> InferredSchema: - """ - This method takes properties that should be marked as required (self._pk and self._cursor_field) and travel the schema to mark every - node as required. - """ - # Removing nullable for the root as when we call `_clean`, we make everything nullable - node[_TYPE] = _OBJECT_TYPE - - exceptions = [] - for field in [x for x in [self._pk, self._cursor_field] if x]: - try: - self._add_fields_as_required(node, field) - except SchemaValidationException as exception: - exceptions.append(exception) - - if exceptions: - raise SchemaValidationException.merge_exceptions(exceptions) - - return node - - def _add_fields_as_required(self, node: InferredSchema, composite_key: List[List[str]]) -> None: - """ - Take a list of nested keys (this list represents a composite key) and travel the schema to mark every node as required. - """ - errors: List[Exception] = [] - - for path in composite_key: - try: - self._add_field_as_required(node, path) - except ValueError as exception: - errors.append(exception) - - if errors: - raise SchemaValidationException(node, errors) - - def _add_field_as_required(self, node: InferredSchema, path: List[str], traveled_path: Optional[List[str]] = None) -> None: - """ - Take a nested key and travel the schema to mark every node as required. - """ - self._remove_null_from_type(node) - if self._is_leaf(path): - return - - if not traveled_path: - traveled_path = [] - - if _PROPERTIES not in node: - # This validation is only relevant when `traveled_path` is empty - raise ValueError( - f"Path {traveled_path} does not refer to an object but is `{node}` and hence {path} can't be marked as required." - ) - - next_node = path[0] - if next_node not in node[_PROPERTIES]: - raise ValueError(f"Path {traveled_path} does not have field `{next_node}` in the schema and hence can't be marked as required.") - - if _TYPE not in node: - # We do not expect this case to happen but we added a specific error message just in case - raise ValueError( - f"Unknown schema error: {traveled_path} is expected to have a type but did not. Schema inferrence is probably broken" - ) - - if node[_TYPE] not in [_OBJECT_TYPE, [_NULL_TYPE, _OBJECT_TYPE], [_OBJECT_TYPE, _NULL_TYPE]]: - raise ValueError(f"Path {traveled_path} is expected to be an object but was of type `{node['properties'][next_node]['type']}`") - - if _REQUIRED not in node or not node[_REQUIRED]: - node[_REQUIRED] = [next_node] - elif next_node not in node[_REQUIRED]: - node[_REQUIRED].append(next_node) - - traveled_path.append(next_node) - self._add_field_as_required(node[_PROPERTIES][next_node], path[1:], traveled_path) - - def _is_leaf(self, path: List[str]) -> bool: - return len(path) == 0 - - def _remove_null_from_type(self, node: InferredSchema) -> None: - if isinstance(node[_TYPE], list): - if _NULL_TYPE in node[_TYPE]: - node[_TYPE].remove(_NULL_TYPE) - if len(node[_TYPE]) == 1: - node[_TYPE] = node[_TYPE][0] - - def get_stream_schema(self, stream_name: str) -> Optional[InferredSchema]: - """ - Returns the inferred JSON schema for the specified stream. Might be `None` if there were no records for the given stream name. - """ - return ( - self._add_required_properties(self._clean(self.stream_to_builder[stream_name].to_schema())) - if stream_name in self.stream_to_builder - else None - ) diff --git a/airbyte-cdk/python/airbyte_cdk/utils/spec_schema_transformations.py b/airbyte-cdk/python/airbyte_cdk/utils/spec_schema_transformations.py deleted file mode 100644 index 2a772d50b6c3..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/utils/spec_schema_transformations.py +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import re - -from jsonschema import RefResolver - - -def resolve_refs(schema: dict) -> dict: - """ - For spec schemas generated using Pydantic models, the resulting JSON schema can contain refs between object - relationships. - """ - json_schema_ref_resolver = RefResolver.from_schema(schema) - str_schema = json.dumps(schema) - for ref_block in re.findall(r'{"\$ref": "#\/definitions\/.+?(?="})"}', str_schema): - ref = json.loads(ref_block)["$ref"] - str_schema = str_schema.replace(ref_block, json.dumps(json_schema_ref_resolver.resolve(ref)[1])) - pyschema: dict = json.loads(str_schema) - del pyschema["definitions"] - return pyschema diff --git a/airbyte-cdk/python/airbyte_cdk/utils/stream_status_utils.py b/airbyte-cdk/python/airbyte_cdk/utils/stream_status_utils.py deleted file mode 100644 index 49c07f49cd97..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/utils/stream_status_utils.py +++ /dev/null @@ -1,43 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from datetime import datetime -from typing import List, Optional, Union - -from airbyte_cdk.models import ( - AirbyteMessage, - AirbyteStream, - AirbyteStreamStatus, - AirbyteStreamStatusReason, - AirbyteStreamStatusTraceMessage, - AirbyteTraceMessage, - StreamDescriptor, - TraceType, -) -from airbyte_cdk.models import Type as MessageType - - -def as_airbyte_message( - stream: Union[AirbyteStream, StreamDescriptor], - current_status: AirbyteStreamStatus, - reasons: Optional[List[AirbyteStreamStatusReason]] = None, -) -> AirbyteMessage: - """ - Builds an AirbyteStreamStatusTraceMessage for the provided stream - """ - - now_millis = datetime.now().timestamp() * 1000.0 - - trace_message = AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - emitted_at=now_millis, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name=stream.name, namespace=stream.namespace), - status=current_status, - reasons=reasons, - ), - ) - - return AirbyteMessage(type=MessageType.TRACE, trace=trace_message) diff --git a/airbyte-cdk/python/airbyte_cdk/utils/traced_exception.py b/airbyte-cdk/python/airbyte_cdk/utils/traced_exception.py deleted file mode 100644 index bd96ea398146..000000000000 --- a/airbyte-cdk/python/airbyte_cdk/utils/traced_exception.py +++ /dev/null @@ -1,116 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import time -import traceback -from typing import Optional - -from airbyte_cdk.models import ( - AirbyteConnectionStatus, - AirbyteErrorTraceMessage, - AirbyteMessage, - AirbyteMessageSerializer, - AirbyteTraceMessage, - FailureType, - Status, - StreamDescriptor, - TraceType, -) -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.utils.airbyte_secrets_utils import filter_secrets -from orjson import orjson - - -class AirbyteTracedException(Exception): - """ - An exception that should be emitted as an AirbyteTraceMessage - """ - - def __init__( - self, - internal_message: Optional[str] = None, - message: Optional[str] = None, - failure_type: FailureType = FailureType.system_error, - exception: Optional[BaseException] = None, - stream_descriptor: Optional[StreamDescriptor] = None, - ): - """ - :param internal_message: the internal error that caused the failure - :param message: a user-friendly message that indicates the cause of the error - :param failure_type: the type of error - :param exception: the exception that caused the error, from which the stack trace should be retrieved - :param stream_descriptor: describe the stream from which the exception comes from - """ - self.internal_message = internal_message - self.message = message - self.failure_type = failure_type - self._exception = exception - self._stream_descriptor = stream_descriptor - super().__init__(internal_message) - - def as_airbyte_message(self, stream_descriptor: Optional[StreamDescriptor] = None) -> AirbyteMessage: - """ - Builds an AirbyteTraceMessage from the exception - - :param stream_descriptor is deprecated, please use the stream_description in `__init__ or `from_exception`. If many - stream_descriptors are defined, the one from `as_airbyte_message` will be discarded. - """ - now_millis = time.time_ns() // 1_000_000 - - trace_exc = self._exception or self - stack_trace_str = "".join(traceback.TracebackException.from_exception(trace_exc).format()) - - trace_message = AirbyteTraceMessage( - type=TraceType.ERROR, - emitted_at=now_millis, - error=AirbyteErrorTraceMessage( - message=self.message or "Something went wrong in the connector. See the logs for more details.", - internal_message=self.internal_message, - failure_type=self.failure_type, - stack_trace=stack_trace_str, - stream_descriptor=self._stream_descriptor if self._stream_descriptor is not None else stream_descriptor, - ), - ) - - return AirbyteMessage(type=MessageType.TRACE, trace=trace_message) - - def as_connection_status_message(self) -> Optional[AirbyteMessage]: - if self.failure_type == FailureType.config_error: - return AirbyteMessage( - type=MessageType.CONNECTION_STATUS, connectionStatus=AirbyteConnectionStatus(status=Status.FAILED, message=self.message) - ) - return None - - def emit_message(self) -> None: - """ - Prints the exception as an AirbyteTraceMessage. - Note that this will be called automatically on uncaught exceptions when using the airbyte_cdk entrypoint. - """ - message = orjson.dumps(AirbyteMessageSerializer.dump(self.as_airbyte_message())).decode() - filtered_message = filter_secrets(message) - print(filtered_message) - - @classmethod - def from_exception(cls, exc: BaseException, stream_descriptor: Optional[StreamDescriptor] = None, *args, **kwargs) -> "AirbyteTracedException": # type: ignore # ignoring because of args and kwargs - """ - Helper to create an AirbyteTracedException from an existing exception - :param exc: the exception that caused the error - :param stream_descriptor: describe the stream from which the exception comes from - """ - return cls(internal_message=str(exc), exception=exc, stream_descriptor=stream_descriptor, *args, **kwargs) # type: ignore # ignoring because of args and kwargs - - def as_sanitized_airbyte_message(self, stream_descriptor: Optional[StreamDescriptor] = None) -> AirbyteMessage: - """ - Builds an AirbyteTraceMessage from the exception and sanitizes any secrets from the message body - - :param stream_descriptor is deprecated, please use the stream_description in `__init__ or `from_exception`. If many - stream_descriptors are defined, the one from `as_sanitized_airbyte_message` will be discarded. - """ - error_message = self.as_airbyte_message(stream_descriptor=stream_descriptor) - if error_message.trace.error.message: # type: ignore[union-attr] # AirbyteMessage with MessageType.TRACE has AirbyteTraceMessage - error_message.trace.error.message = filter_secrets(error_message.trace.error.message) # type: ignore[union-attr] # AirbyteMessage with MessageType.TRACE has AirbyteTraceMessage - if error_message.trace.error.internal_message: # type: ignore[union-attr] # AirbyteMessage with MessageType.TRACE has AirbyteTraceMessage - error_message.trace.error.internal_message = filter_secrets(error_message.trace.error.internal_message) # type: ignore[union-attr] # AirbyteMessage with MessageType.TRACE has AirbyteTraceMessage - if error_message.trace.error.stack_trace: # type: ignore[union-attr] # AirbyteMessage with MessageType.TRACE has AirbyteTraceMessage - error_message.trace.error.stack_trace = filter_secrets(error_message.trace.error.stack_trace) # type: ignore[union-attr] # AirbyteMessage with MessageType.TRACE has AirbyteTraceMessage - return error_message diff --git a/airbyte-cdk/python/bin/generate-component-manifest-dagger.sh b/airbyte-cdk/python/bin/generate-component-manifest-dagger.sh deleted file mode 100755 index f920ff727e49..000000000000 --- a/airbyte-cdk/python/bin/generate-component-manifest-dagger.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -# We need to run this script in a docker container because we need to use a -# specific version of datamodel-codegen that generates pydantic v1 models (correctly). -# The newer datamodel-codegen's "pydantic v1" models are different than those v1 models -# generated by the older version of datamodel-codegen. - -set -e - -pip install dagger-io==0.13.3 -python bin/generate_component_manifest_files.py diff --git a/airbyte-cdk/python/bin/generate_component_manifest_files.py b/airbyte-cdk/python/bin/generate_component_manifest_files.py deleted file mode 100755 index 152486f9fb6b..000000000000 --- a/airbyte-cdk/python/bin/generate_component_manifest_files.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -import sys -from glob import glob -from pathlib import Path - -import anyio -import dagger - -PYTHON_IMAGE = "python:3.10" -LOCAL_YAML_DIR_PATH = "airbyte_cdk/sources/declarative" -LOCAL_OUTPUT_DIR_PATH = "airbyte_cdk/sources/declarative/models" - - -PIP_DEPENDENCIES = [ - "datamodel_code_generator==0.11.19", -] - - -def get_all_yaml_files_without_ext() -> list[str]: - return [Path(f).stem for f in glob(f"{LOCAL_YAML_DIR_PATH}/*.yaml")] - - -def generate_init_module_content() -> str: - header = "# generated by bin/generate_component_manifest_files.py\n" - for module_name in get_all_yaml_files_without_ext(): - header += f"from .{module_name} import *\n" - return header - - -async def post_process_codegen(codegen_container: dagger.Container): - codegen_container = codegen_container.with_exec(["mkdir", "/generated_post_processed"], use_entrypoint=True) - for generated_file in await codegen_container.directory("/generated").entries(): - if generated_file.endswith(".py"): - original_content = await codegen_container.file(f"/generated/{generated_file}").contents() - # the space before _parameters is intentional to avoid replacing things like `request_parameters:` with `requestparameters:` - post_processed_content = original_content.replace(" _parameters:", " parameters:").replace("from pydantic", "from pydantic.v1") - codegen_container = codegen_container.with_new_file( - f"/generated_post_processed/{generated_file}", contents=post_processed_content - ) - return codegen_container - - -async def main(): - init_module_content = generate_init_module_content() - - async with dagger.Connection(dagger.Config(log_output=sys.stderr)) as dagger_client: - - codegen_container = ( - dagger_client.container() - .from_(PYTHON_IMAGE) - .with_exec(["mkdir", "/generated"], use_entrypoint=True) - .with_exec(["pip", "install", " ".join(PIP_DEPENDENCIES)], use_entrypoint=True) - .with_mounted_directory("/yaml", dagger_client.host().directory(LOCAL_YAML_DIR_PATH, include=["*.yaml"])) - .with_new_file("/generated/__init__.py", contents=init_module_content) - ) - for yaml_file in get_all_yaml_files_without_ext(): - codegen_container = codegen_container.with_exec( - [ - "datamodel-codegen", - "--input", - f"/yaml/{yaml_file}.yaml", - "--output", - f"/generated/{yaml_file}.py", - "--disable-timestamp", - "--enum-field-as-literal", - "one", - "--set-default-enum-member", - ], - use_entrypoint=True, - ) - - await ((await post_process_codegen(codegen_container)).directory("/generated_post_processed").export(LOCAL_OUTPUT_DIR_PATH)) - - -anyio.run(main) diff --git a/airbyte-cdk/python/bin/run-mypy-on-modified-files.sh b/airbyte-cdk/python/bin/run-mypy-on-modified-files.sh deleted file mode 100755 index 96f757be1b7d..000000000000 --- a/airbyte-cdk/python/bin/run-mypy-on-modified-files.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env sh - -set -e - -# Ensure script always runs from the project directory. -cd "$(dirname "${0}")/.." || exit 1 - -# TODO change this to include unit_tests as well once it's in a good state -{ - git diff --name-only --diff-filter=d --relative ':(exclude)unit_tests' - git diff --name-only --diff-filter=d --staged --relative ':(exclude)unit_tests' - git diff --name-only --diff-filter=d master... --relative ':(exclude)unit_tests' -} | grep -E '\.py$' | sort | uniq | xargs mypy --config-file mypy.ini --install-types --non-interactive diff --git a/airbyte-cdk/python/cdk-migrations.md b/airbyte-cdk/python/cdk-migrations.md deleted file mode 100644 index 62685f78093a..000000000000 --- a/airbyte-cdk/python/cdk-migrations.md +++ /dev/null @@ -1,191 +0,0 @@ -# CDK Migration Guide - -## Upgrading to 5.0.0 - -Version 5.0.0 of the CDK updates the `airbyte_cdk.models` dependency to replace Pydantic v2 models with Python `dataclasses`. It also -updates the `airbyte-protocol-models` dependency to a version that uses dataclasses models. - -The changes to Airbyte CDK itself are backwards-compatible, but some changes are required if the connector: -- uses the `airbyte_protocol` models directly, or `airbyte_cdk.models`, which points to `airbyte_protocol` models -- uses third-party libraries, such as `pandas`, to read data from sources, which output non-native Python objects that cannot be serialized by the [orjson](https://github.com/ijl/orjson) library. - -> [!NOTE] -> All Serializers have omit_none=True parameter that is applied recursively. Thus, all None values are excluded from output. -> This is expected behaviour and does not break anything in protocol. - -### Updating direct usage of Pydantic based Airbyte Protocol Models - -- If the connector uses Pydantic based Airbyte Protocol Models, the code will need to be updated to reflect the changes `pydantic`. -- It is recommended to import protocol classes not directly by `import airbyte_protocol` statement, but from `airbyte_cdk.models` package. -- It is also recommended to use *-`Serializer` from `airbyte_cdk.models` to manipulate the data or convert to/from JSON. - These are based on the [serpyco-rs](https://pypi.org/project/serpyco-rs/) library. -- These classes have a `dump` method that converts the model to a dictionary and a `load` method that converts a dictionary to a model. -- The recommended serialization strategy is to pass the dictionary to the `orjson` library when serializing as a JSON string. - -E.g. - -```python3 -import orjson - -from airbyte_cdk.models import AirbyteMessage, AirbyteMessageSerializer - -# Before (pydantic model message serialization) -AirbyteMessage().model_dump_json() - -# After (dataclass model serialization) -orjson.dumps(AirbyteMessageSerializer.dump(AirbyteMessage())).decode() -``` - -### Updating third-party libraries - -For example, if `pandas` outputs data from the source, which has date-time `pandas.Timestamp` object in -it, [Orjson supported Types](https://github.com/ijl/orjson?tab=readme-ov-file#types), these fields should be transformed to native JSON -objects. - -```python3 -# Before -yield from df.to_dict(orient="records") - -# After - Option 1 -yield orjson.loads(df.to_json(orient="records", date_format="iso", date_unit="us")) - -``` - - -## Upgrading to 4.5.0 - -In this release, we are no longer supporting the legacy state format in favor of the current per-stream state -format which has been running in production for over 2 years. The impacts to connectors should be minimal, but for -the small number of connectors that instantiate their own `ConnectorStateManager`, the fix to upgrade to the latest -version of the CDK is to stop passing the `stream_instance_map` parameter to the `ConnectorStateManager` constructor. - -## Upgrading to 4.1.0 -We are unifying the `BackoffStrategy` interface as it currently differs from the Python CDK package to the declarative one. The different is that the interface will require the attempt_count to be passed. - -Main impact: This change is mostly internal but we spotted a couple of tests that expect `backoff_time` to not have the `attempt_count` parameter so these tests would fail ([example](https://github.com/airbytehq/airbyte/blob/c9f45a0b85735f58102fcd78385f6f673e731aa6/airbyte-integrations/connectors/source-github/unit_tests/test_stream.py#L99)). - -This change should not impact the following classes even though they have a different interface as they accept `kwargs` and `attempt_count` is currently passed as a keyword argument within the CDK. However, once there is a CDK change where `backoff_time` is called not as a keyword argument, they will fail: -* Zendesk Support: ZendeskSupportBackoffStrategy (this one will be updated shortly after as it is used for CI to validate CDK changes) -* Klaviyo: KlaviyoBackoffStrategy (the logic has been generified so we will remove this custom component shortly after this update) -* GitHub: GithubStreamABCBackoffStrategy and ContributorActivityBackoffStrategy -* Airtable: AirtableBackoffStrategy -* Slack: SlackBackoffStrategy - -This change should not impact `WaitUntilMidnightBackoffStrategy` from source-gnews as well but it is interesting to note that its interface is also wrong as it considers the first parameter as a `requests.Response` instead of a `Optional[Union[requests.Response, requests.RequestException]]`. - -## Upgrading to 4.0.0 - -Updated the codebase to utilize new Python syntax features. As a result, support for Python 3.9 has been dropped. The minimum required Python version is now 3.10. - -## Upgrading to 3.0.0 -Version 3.0.0 of the CDK updates the `HTTPStream` class by reusing the `HTTPClient` under the hood. - -- `backoff_time` and `should_retry` methods are removed from HttpStream -- `HttpStreamAdapterHttpStatusErrorHandler` and `HttpStreamAdapterBackoffStrategy` adapters are marked as `deprecated` -- `raise_on_http_errors`, `max_retries`, `max_time`, `retry_factor` are marked as `deprecated` - -Exceptions from the `requests` library should no longer be raised when calling `read_records`. -Therefore, catching exceptions should be updated, and error messages might change. -See [Migration of Source Zendesk Support](https://github.com/airbytehq/airbyte/pull/41032/commits/4d3a247f36b9826dcea4b98d30fc19802b03d014) as an example. - -### Migration of `should_retry` method -In case the connector uses custom logic for backoff based on the response from the server, a new method `get_error_handler` should be implemented. -This method should return instance of [`ErrorHandler`](https://github.com/airbytehq/airbyte/blob/master/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/error_handler.py). - -### Migration of `backoff_time` method -In case the connector uses custom logic for backoff time calculation, a new method `get_backoff_strategy` should be implemented. -This method should return instance(s) of [`BackoffStrategy`](https://github.com/airbytehq/airbyte/blob/master/airbyte-cdk/python/airbyte_cdk/sources/streams/http/error_handlers/backoff_strategy.py). - -## Upgrading to 2.0.0 -Version 2.0.0 of the CDK updates the `pydantic` dependency to from Pydantic v1 to Pydantic v2. It also -updates the `airbyte-protocol-models` dependency to a version that uses Pydantic V2 models. - -The changes to Airbyte CDK itself are backwards-compatible, but some changes are required if the connector: -- uses Pydantic directly, e.g. for its own custom models, or -- uses the `airbyte_protocol` models directly, or `airbyte_cdk.models`, which points to `airbyte_protocol` models, or -- customizes HashableStreamDescriptor, which inherits from a protocol model and has therefore been updated to use Pydantic V2 models. - -Some test assertions may also need updating due to changes to default serialization of the protocol models. - -### Updating direct usage of Pydantic - -If the connector uses pydantic, the code will need to be updated to reflect the change `pydantic` dependency version. -The Pydantic [migration guide](https://docs.pydantic.dev/latest/migration/) is a great resource for any questions that -might arise around upgrade behavior. - -#### Using Pydantic V1 models with Pydantic V2 -The easiest way to update the code to be compatible without major changes is to update the import statements from -`from pydantic` to `from pydantic.v1`, as Pydantic has kept the v1 module for backwards compatibility. - -Some potential gotchas: - - `ValidationError` must be imported from `pydantic.v1.error_wrappers` instead of `pydantic.v1` - - `ModelMetaclass` must be imported from `pydantic.v1.main` instead of `pydantic.v1` - - `resolve_annotations` must be imported from `pydantic.v1.typing` instead of `pydantic.v1` - -#### Upgrading to Pydantic V2 -To upgrade all the way to V2 proper, Pydantic also offers a [migration tool](https://docs.pydantic.dev/latest/migration/#code-transformation-tool) -to automatically update the code to be compatible with Pydantic V2. - -#### Updating assertions -It's possible that a connector might make assertions against protocol models without actually -importing them - for example when testing methods which return `AirbyteStateBlob` or `AnyUrl`. - -To resolve this, either compare directly to a model, or `dict()` or `str()` your model accordingly, depending -on if you care most about the serialized output or the model (for a method which returns a model, option 1 is -preferred). For example: - -```python -# Before -assert stream_read.slices[1].state[0].stream.stream_state == {"a_timestamp": 123} - -# After - Option 1 -from airbyte_cdk.models import AirbyteStateBlob -assert stream_read.slices[1].state[0].stream.stream_state == AirbyteStateBlob(a_timestamp=123) - -# After - Option 2 -assert stream_read.slices[1].state[0].stream.stream_state.dict() == {"a_timestamp": 123} -``` - - -## Upgrading to 1.0.0 -Starting from 1.0.0, CDK classes and functions should be imported directly from `airbyte_cdk` (example: `from airbyte_cdk import HttpStream`). Lower-level `__init__` files are not considered stable, and will be modified without introducing a major release. - -Introducing breaking changes to a class or function exported from the top level `__init__.py` will require a major version bump and a migration note to help developer upgrade. - -Note that the following packages are not part of the top level init because they require extras dependencies, but are still considered stable: -- `destination.vector_db_based` -- `source.file_based` - -The `test` package is not included in the top level init either. The `test` package is still evolving and isn't considered stable. - - -A few classes were deleted from the Airbyte CDK in version 1.0.0: -- AirbyteLogger -- AirbyteSpec -- Authenticators in the `sources.streams.http.auth` module - - - -### Migrating off AirbyteLogger -No connectors should still be using `AirbyteLogger` directly, but the class is still used in some interfaces. The only required change is to update the type annotation from `AirbyteLogger` to `logging.Logger`. For example: - -``` -def check_connection(self, logger: AirbyteLogger, config: Mapping[str, Any]) -> Tuple[bool, any]: -``` - -to - -``` -def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, any]: -``` -Don't forget to also update the imports. You can delete `from airbyte_cdk import AirbyteLogger` and replace it with `import logging`. - -### Migrating off AirbyteSpec -AirbyteSpec isn't used by any connectors in the repository, and I don't expect any custom connectors to use the class either. This should be a no-op. - -### Migrating off Authenticators -Replace usage of authenticators in the `airbyte_cdk.sources.streams.http.auth` module with their sister classes in the `airbyte_cdk.sources.streams.http.requests_native_auth` module. - -If any of your streams reference `self.authenticator`, you'll also need to update these references to `self._session.auth` as the authenticator is embedded in the session object. - -Here is a [pull request that can serve as an example](https://github.com/airbytehq/airbyte/pull/38065/files). diff --git a/airbyte-cdk/python/mypy.ini b/airbyte-cdk/python/mypy.ini deleted file mode 100644 index f51c0846fb8f..000000000000 --- a/airbyte-cdk/python/mypy.ini +++ /dev/null @@ -1,26 +0,0 @@ -# Global options: - -[mypy] -warn_unused_configs = True -warn_redundant_casts = True -ignore_missing_imports = True -strict_equality = True -check_untyped_defs = True -disallow_untyped_decorators = False -disallow_any_generics = True -disallow_untyped_calls = True -disallow_incomplete_defs = True -disallow_untyped_defs = True -warn_return_any = True - -# Only alert on the files we want to check -follow_imports = silent - -# Allow re-exporting types for airbyte-protocol -no_implicit_reexport = False - -[tool.mypy] -plugins = ["pydantic.mypy", "pendulum", "pytest-mypy-plugins"] - -[mypy-airbyte_cdk.models] -ignore_errors = True diff --git a/airbyte-cdk/python/poetry.lock b/airbyte-cdk/python/poetry.lock deleted file mode 100644 index 1019d433060f..000000000000 --- a/airbyte-cdk/python/poetry.lock +++ /dev/null @@ -1,5147 +0,0 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. - -[[package]] -name = "aiohappyeyeballs" -version = "2.4.3" -description = "Happy Eyeballs for asyncio" -optional = true -python-versions = ">=3.8" -files = [ - {file = "aiohappyeyeballs-2.4.3-py3-none-any.whl", hash = "sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572"}, - {file = "aiohappyeyeballs-2.4.3.tar.gz", hash = "sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586"}, -] - -[[package]] -name = "aiohttp" -version = "3.10.10" -description = "Async http client/server framework (asyncio)" -optional = true -python-versions = ">=3.8" -files = [ - {file = "aiohttp-3.10.10-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:be7443669ae9c016b71f402e43208e13ddf00912f47f623ee5994e12fc7d4b3f"}, - {file = "aiohttp-3.10.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7b06b7843929e41a94ea09eb1ce3927865387e3e23ebe108e0d0d09b08d25be9"}, - {file = "aiohttp-3.10.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:333cf6cf8e65f6a1e06e9eb3e643a0c515bb850d470902274239fea02033e9a8"}, - {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:274cfa632350225ce3fdeb318c23b4a10ec25c0e2c880eff951a3842cf358ac1"}, - {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9e5e4a85bdb56d224f412d9c98ae4cbd032cc4f3161818f692cd81766eee65a"}, - {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b606353da03edcc71130b52388d25f9a30a126e04caef1fd637e31683033abd"}, - {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab5a5a0c7a7991d90446a198689c0535be89bbd6b410a1f9a66688f0880ec026"}, - {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:578a4b875af3e0daaf1ac6fa983d93e0bbfec3ead753b6d6f33d467100cdc67b"}, - {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8105fd8a890df77b76dd3054cddf01a879fc13e8af576805d667e0fa0224c35d"}, - {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3bcd391d083f636c06a68715e69467963d1f9600f85ef556ea82e9ef25f043f7"}, - {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fbc6264158392bad9df19537e872d476f7c57adf718944cc1e4495cbabf38e2a"}, - {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e48d5021a84d341bcaf95c8460b152cfbad770d28e5fe14a768988c461b821bc"}, - {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2609e9ab08474702cc67b7702dbb8a80e392c54613ebe80db7e8dbdb79837c68"}, - {file = "aiohttp-3.10.10-cp310-cp310-win32.whl", hash = "sha256:84afcdea18eda514c25bc68b9af2a2b1adea7c08899175a51fe7c4fb6d551257"}, - {file = "aiohttp-3.10.10-cp310-cp310-win_amd64.whl", hash = "sha256:9c72109213eb9d3874f7ac8c0c5fa90e072d678e117d9061c06e30c85b4cf0e6"}, - {file = "aiohttp-3.10.10-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c30a0eafc89d28e7f959281b58198a9fa5e99405f716c0289b7892ca345fe45f"}, - {file = "aiohttp-3.10.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:258c5dd01afc10015866114e210fb7365f0d02d9d059c3c3415382ab633fcbcb"}, - {file = "aiohttp-3.10.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:15ecd889a709b0080f02721255b3f80bb261c2293d3c748151274dfea93ac871"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3935f82f6f4a3820270842e90456ebad3af15810cf65932bd24da4463bc0a4c"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:413251f6fcf552a33c981c4709a6bba37b12710982fec8e558ae944bfb2abd38"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1720b4f14c78a3089562b8875b53e36b51c97c51adc53325a69b79b4b48ebcb"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:679abe5d3858b33c2cf74faec299fda60ea9de62916e8b67e625d65bf069a3b7"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79019094f87c9fb44f8d769e41dbb664d6e8fcfd62f665ccce36762deaa0e911"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe2fb38c2ed905a2582948e2de560675e9dfbee94c6d5ccdb1301c6d0a5bf092"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a3f00003de6eba42d6e94fabb4125600d6e484846dbf90ea8e48a800430cc142"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1bbb122c557a16fafc10354b9d99ebf2f2808a660d78202f10ba9d50786384b9"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:30ca7c3b94708a9d7ae76ff281b2f47d8eaf2579cd05971b5dc681db8caac6e1"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:df9270660711670e68803107d55c2b5949c2e0f2e4896da176e1ecfc068b974a"}, - {file = "aiohttp-3.10.10-cp311-cp311-win32.whl", hash = "sha256:aafc8ee9b742ce75044ae9a4d3e60e3d918d15a4c2e08a6c3c3e38fa59b92d94"}, - {file = "aiohttp-3.10.10-cp311-cp311-win_amd64.whl", hash = "sha256:362f641f9071e5f3ee6f8e7d37d5ed0d95aae656adf4ef578313ee585b585959"}, - {file = "aiohttp-3.10.10-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9294bbb581f92770e6ed5c19559e1e99255e4ca604a22c5c6397b2f9dd3ee42c"}, - {file = "aiohttp-3.10.10-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a8fa23fe62c436ccf23ff930149c047f060c7126eae3ccea005f0483f27b2e28"}, - {file = "aiohttp-3.10.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5c6a5b8c7926ba5d8545c7dd22961a107526562da31a7a32fa2456baf040939f"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:007ec22fbc573e5eb2fb7dec4198ef8f6bf2fe4ce20020798b2eb5d0abda6138"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9627cc1a10c8c409b5822a92d57a77f383b554463d1884008e051c32ab1b3742"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:50edbcad60d8f0e3eccc68da67f37268b5144ecc34d59f27a02f9611c1d4eec7"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a45d85cf20b5e0d0aa5a8dca27cce8eddef3292bc29d72dcad1641f4ed50aa16"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b00807e2605f16e1e198f33a53ce3c4523114059b0c09c337209ae55e3823a8"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f2d4324a98062be0525d16f768a03e0bbb3b9fe301ceee99611dc9a7953124e6"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:438cd072f75bb6612f2aca29f8bd7cdf6e35e8f160bc312e49fbecab77c99e3a"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:baa42524a82f75303f714108fea528ccacf0386af429b69fff141ffef1c534f9"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a7d8d14fe962153fc681f6366bdec33d4356f98a3e3567782aac1b6e0e40109a"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c1277cd707c465cd09572a774559a3cc7c7a28802eb3a2a9472588f062097205"}, - {file = "aiohttp-3.10.10-cp312-cp312-win32.whl", hash = "sha256:59bb3c54aa420521dc4ce3cc2c3fe2ad82adf7b09403fa1f48ae45c0cbde6628"}, - {file = "aiohttp-3.10.10-cp312-cp312-win_amd64.whl", hash = "sha256:0e1b370d8007c4ae31ee6db7f9a2fe801a42b146cec80a86766e7ad5c4a259cf"}, - {file = "aiohttp-3.10.10-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ad7593bb24b2ab09e65e8a1d385606f0f47c65b5a2ae6c551db67d6653e78c28"}, - {file = "aiohttp-3.10.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1eb89d3d29adaf533588f209768a9c02e44e4baf832b08118749c5fad191781d"}, - {file = "aiohttp-3.10.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3fe407bf93533a6fa82dece0e74dbcaaf5d684e5a51862887f9eaebe6372cd79"}, - {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50aed5155f819873d23520919e16703fc8925e509abbb1a1491b0087d1cd969e"}, - {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f05e9727ce409358baa615dbeb9b969db94324a79b5a5cea45d39bdb01d82e6"}, - {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dffb610a30d643983aeb185ce134f97f290f8935f0abccdd32c77bed9388b42"}, - {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa6658732517ddabe22c9036479eabce6036655ba87a0224c612e1ae6af2087e"}, - {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:741a46d58677d8c733175d7e5aa618d277cd9d880301a380fd296975a9cdd7bc"}, - {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e00e3505cd80440f6c98c6d69269dcc2a119f86ad0a9fd70bccc59504bebd68a"}, - {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ffe595f10566f8276b76dc3a11ae4bb7eba1aac8ddd75811736a15b0d5311414"}, - {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdfcf6443637c148c4e1a20c48c566aa694fa5e288d34b20fcdc58507882fed3"}, - {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d183cf9c797a5291e8301790ed6d053480ed94070637bfaad914dd38b0981f67"}, - {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:77abf6665ae54000b98b3c742bc6ea1d1fb31c394bcabf8b5d2c1ac3ebfe7f3b"}, - {file = "aiohttp-3.10.10-cp313-cp313-win32.whl", hash = "sha256:4470c73c12cd9109db8277287d11f9dd98f77fc54155fc71a7738a83ffcc8ea8"}, - {file = "aiohttp-3.10.10-cp313-cp313-win_amd64.whl", hash = "sha256:486f7aabfa292719a2753c016cc3a8f8172965cabb3ea2e7f7436c7f5a22a151"}, - {file = "aiohttp-3.10.10-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:1b66ccafef7336a1e1f0e389901f60c1d920102315a56df85e49552308fc0486"}, - {file = "aiohttp-3.10.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:acd48d5b80ee80f9432a165c0ac8cbf9253eaddb6113269a5e18699b33958dbb"}, - {file = "aiohttp-3.10.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3455522392fb15ff549d92fbf4b73b559d5e43dc522588f7eb3e54c3f38beee7"}, - {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45c3b868724137f713a38376fef8120c166d1eadd50da1855c112fe97954aed8"}, - {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:da1dee8948d2137bb51fbb8a53cce6b1bcc86003c6b42565f008438b806cccd8"}, - {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5ce2ce7c997e1971b7184ee37deb6ea9922ef5163c6ee5aa3c274b05f9e12fa"}, - {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28529e08fde6f12eba8677f5a8608500ed33c086f974de68cc65ab218713a59d"}, - {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f7db54c7914cc99d901d93a34704833568d86c20925b2762f9fa779f9cd2e70f"}, - {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:03a42ac7895406220124c88911ebee31ba8b2d24c98507f4a8bf826b2937c7f2"}, - {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:7e338c0523d024fad378b376a79faff37fafb3c001872a618cde1d322400a572"}, - {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:038f514fe39e235e9fef6717fbf944057bfa24f9b3db9ee551a7ecf584b5b480"}, - {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:64f6c17757251e2b8d885d728b6433d9d970573586a78b78ba8929b0f41d045a"}, - {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:93429602396f3383a797a2a70e5f1de5df8e35535d7806c9f91df06f297e109b"}, - {file = "aiohttp-3.10.10-cp38-cp38-win32.whl", hash = "sha256:c823bc3971c44ab93e611ab1a46b1eafeae474c0c844aff4b7474287b75fe49c"}, - {file = "aiohttp-3.10.10-cp38-cp38-win_amd64.whl", hash = "sha256:54ca74df1be3c7ca1cf7f4c971c79c2daf48d9aa65dea1a662ae18926f5bc8ce"}, - {file = "aiohttp-3.10.10-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:01948b1d570f83ee7bbf5a60ea2375a89dfb09fd419170e7f5af029510033d24"}, - {file = "aiohttp-3.10.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9fc1500fd2a952c5c8e3b29aaf7e3cc6e27e9cfc0a8819b3bce48cc1b849e4cc"}, - {file = "aiohttp-3.10.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f614ab0c76397661b90b6851a030004dac502e48260ea10f2441abd2207fbcc7"}, - {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00819de9e45d42584bed046314c40ea7e9aea95411b38971082cad449392b08c"}, - {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05646ebe6b94cc93407b3bf34b9eb26c20722384d068eb7339de802154d61bc5"}, - {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:998f3bd3cfc95e9424a6acd7840cbdd39e45bc09ef87533c006f94ac47296090"}, - {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9010c31cd6fa59438da4e58a7f19e4753f7f264300cd152e7f90d4602449762"}, - {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ea7ffc6d6d6f8a11e6f40091a1040995cdff02cfc9ba4c2f30a516cb2633554"}, - {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ef9c33cc5cbca35808f6c74be11eb7f5f6b14d2311be84a15b594bd3e58b5527"}, - {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ce0cdc074d540265bfeb31336e678b4e37316849d13b308607efa527e981f5c2"}, - {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:597a079284b7ee65ee102bc3a6ea226a37d2b96d0418cc9047490f231dc09fe8"}, - {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:7789050d9e5d0c309c706953e5e8876e38662d57d45f936902e176d19f1c58ab"}, - {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e7f8b04d83483577fd9200461b057c9f14ced334dcb053090cea1da9c8321a91"}, - {file = "aiohttp-3.10.10-cp39-cp39-win32.whl", hash = "sha256:c02a30b904282777d872266b87b20ed8cc0d1501855e27f831320f471d54d983"}, - {file = "aiohttp-3.10.10-cp39-cp39-win_amd64.whl", hash = "sha256:edfe3341033a6b53a5c522c802deb2079eee5cbfbb0af032a55064bd65c73a23"}, - {file = "aiohttp-3.10.10.tar.gz", hash = "sha256:0631dd7c9f0822cc61c88586ca76d5b5ada26538097d0f1df510b082bad3411a"}, -] - -[package.dependencies] -aiohappyeyeballs = ">=2.3.0" -aiosignal = ">=1.1.2" -async-timeout = {version = ">=4.0,<5.0", markers = "python_version < \"3.11\""} -attrs = ">=17.3.0" -frozenlist = ">=1.1.1" -multidict = ">=4.5,<7.0" -yarl = ">=1.12.0,<2.0" - -[package.extras] -speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] - -[[package]] -name = "aiosignal" -version = "1.3.1" -description = "aiosignal: a list of registered asynchronous callbacks" -optional = true -python-versions = ">=3.7" -files = [ - {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, - {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, -] - -[package.dependencies] -frozenlist = ">=1.1.0" - -[[package]] -name = "airbyte-protocol-models-dataclasses" -version = "0.13.0" -description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" -optional = false -python-versions = ">=3.8" -files = [ - {file = "airbyte_protocol_models_dataclasses-0.13.0-py3-none-any.whl", hash = "sha256:0aedb99ffc4f9aab0ce91bba2c292fa17cd8fd4b42eeba196d6a16c20bbbd7a5"}, - {file = "airbyte_protocol_models_dataclasses-0.13.0.tar.gz", hash = "sha256:72e67850d661e2808406aec5839b3158ebb94d3553b798dbdae1b4a278548d2f"}, -] - -[[package]] -name = "alabaster" -version = "0.7.16" -description = "A light, configurable Sphinx theme" -optional = true -python-versions = ">=3.9" -files = [ - {file = "alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92"}, - {file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"}, -] - -[[package]] -name = "annotated-types" -version = "0.7.0" -description = "Reusable constraint types to use with typing.Annotated" -optional = false -python-versions = ">=3.8" -files = [ - {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, - {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, -] - -[[package]] -name = "anyio" -version = "4.6.2.post1" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = true -python-versions = ">=3.9" -files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, -] - -[package.dependencies] -exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} - -[package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] -trio = ["trio (>=0.26.1)"] - -[[package]] -name = "async-timeout" -version = "4.0.3" -description = "Timeout context manager for asyncio programs" -optional = true -python-versions = ">=3.7" -files = [ - {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, - {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, -] - -[[package]] -name = "asyncio" -version = "3.4.3" -description = "reference implementation of PEP 3156" -optional = false -python-versions = "*" -files = [ - {file = "asyncio-3.4.3-cp33-none-win32.whl", hash = "sha256:b62c9157d36187eca799c378e572c969f0da87cd5fc42ca372d92cdb06e7e1de"}, - {file = "asyncio-3.4.3-cp33-none-win_amd64.whl", hash = "sha256:c46a87b48213d7464f22d9a497b9eef8c1928b68320a2fa94240f969f6fec08c"}, - {file = "asyncio-3.4.3-py3-none-any.whl", hash = "sha256:c4d18b22701821de07bd6aea8b53d21449ec0ec5680645e5317062ea21817d2d"}, - {file = "asyncio-3.4.3.tar.gz", hash = "sha256:83360ff8bc97980e4ff25c964c7bd3923d333d177aa4f7fb736b019f26c7cb41"}, -] - -[[package]] -name = "attributes-doc" -version = "0.4.0" -description = "PEP 224 implementation" -optional = false -python-versions = ">=3.8" -files = [ - {file = "attributes-doc-0.4.0.tar.gz", hash = "sha256:b1576c94a714e9fc2c65c47cf10d0c8e1a5f7c4f5ae7f69006be108d95cbfbfb"}, - {file = "attributes_doc-0.4.0-py2.py3-none-any.whl", hash = "sha256:4c3007d9e58f3a6cb4b9c614c4d4ce2d92161581f28e594ddd8241cc3a113bdd"}, -] - -[[package]] -name = "attrs" -version = "24.2.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" -files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, -] - -[package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] - -[[package]] -name = "avro" -version = "1.11.3" -description = "Avro is a serialization and RPC framework." -optional = true -python-versions = ">=3.6" -files = [ - {file = "avro-1.11.3.tar.gz", hash = "sha256:3393bb5139f9cf0791d205756ce1e39a5b58586af5b153d6a3b5a199610e9d17"}, -] - -[package.extras] -snappy = ["python-snappy"] -zstandard = ["zstandard"] - -[[package]] -name = "babel" -version = "2.16.0" -description = "Internationalization utilities" -optional = true -python-versions = ">=3.8" -files = [ - {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, - {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, -] - -[package.extras] -dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] - -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "beautifulsoup4" -version = "4.12.3" -description = "Screen-scraping library" -optional = true -python-versions = ">=3.6.0" -files = [ - {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, - {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, -] - -[package.dependencies] -soupsieve = ">1.2" - -[package.extras] -cchardet = ["cchardet"] -chardet = ["chardet"] -charset-normalizer = ["charset-normalizer"] -html5lib = ["html5lib"] -lxml = ["lxml"] - -[[package]] -name = "bracex" -version = "2.5.post1" -description = "Bash style brace expander." -optional = false -python-versions = ">=3.8" -files = [ - {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, - {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, -] - -[[package]] -name = "cachetools" -version = "5.5.0" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, - {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, -] - -[[package]] -name = "cattrs" -version = "24.1.2" -description = "Composable complex class support for attrs and dataclasses." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, - {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, -] - -[package.dependencies] -attrs = ">=23.1.0" -exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} - -[package.extras] -bson = ["pymongo (>=4.4.0)"] -cbor2 = ["cbor2 (>=5.4.6)"] -msgpack = ["msgpack (>=1.0.5)"] -msgspec = ["msgspec (>=0.18.5)"] -orjson = ["orjson (>=3.9.2)"] -pyyaml = ["pyyaml (>=6.0)"] -tomlkit = ["tomlkit (>=0.11.8)"] -ujson = ["ujson (>=5.7.0)"] - -[[package]] -name = "certifi" -version = "2024.8.30" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, -] - -[[package]] -name = "cffi" -version = "1.17.1" -description = "Foreign Function Interface for Python calling C code." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, - {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, - {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, - {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, - {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, - {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, - {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, - {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, - {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, - {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, - {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, - {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, - {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, - {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, - {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, - {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, -] - -[package.dependencies] -pycparser = "*" - -[[package]] -name = "chardet" -version = "5.2.0" -description = "Universal encoding detector for Python 3" -optional = true -python-versions = ">=3.7" -files = [ - {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, - {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.0" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, -] - -[[package]] -name = "click" -version = "8.1.7" -description = "Composable command line interface toolkit" -optional = true -python-versions = ">=3.7" -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "cohere" -version = "4.21" -description = "" -optional = true -python-versions = ">=3.7,<4.0" -files = [ - {file = "cohere-4.21-py3-none-any.whl", hash = "sha256:5eb81db62e78b3156e734421cc3e657054f9d9f1d68b9f38cf48fe3a8ae40dbc"}, - {file = "cohere-4.21.tar.gz", hash = "sha256:f611438f409dfc5d5a0a153a585349f5a80b169c7102b5994d9999ecf8440866"}, -] - -[package.dependencies] -aiohttp = ">=3.0,<4.0" -backoff = ">=2.0,<3.0" -fastavro = {version = "1.8.2", markers = "python_version >= \"3.8\""} -importlib_metadata = ">=6.0,<7.0" -requests = ">=2.25.0,<3.0.0" -urllib3 = ">=1.26,<3" - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -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 = "contourpy" -version = "1.3.0" -description = "Python library for calculating contours of 2D quadrilateral grids" -optional = true -python-versions = ">=3.9" -files = [ - {file = "contourpy-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:880ea32e5c774634f9fcd46504bf9f080a41ad855f4fef54f5380f5133d343c7"}, - {file = "contourpy-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:76c905ef940a4474a6289c71d53122a4f77766eef23c03cd57016ce19d0f7b42"}, - {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92f8557cbb07415a4d6fa191f20fd9d2d9eb9c0b61d1b2f52a8926e43c6e9af7"}, - {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36f965570cff02b874773c49bfe85562b47030805d7d8360748f3eca570f4cab"}, - {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cacd81e2d4b6f89c9f8a5b69b86490152ff39afc58a95af002a398273e5ce589"}, - {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69375194457ad0fad3a839b9e29aa0b0ed53bb54db1bfb6c3ae43d111c31ce41"}, - {file = "contourpy-1.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a52040312b1a858b5e31ef28c2e865376a386c60c0e248370bbea2d3f3b760d"}, - {file = "contourpy-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3faeb2998e4fcb256542e8a926d08da08977f7f5e62cf733f3c211c2a5586223"}, - {file = "contourpy-1.3.0-cp310-cp310-win32.whl", hash = "sha256:36e0cff201bcb17a0a8ecc7f454fe078437fa6bda730e695a92f2d9932bd507f"}, - {file = "contourpy-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:87ddffef1dbe5e669b5c2440b643d3fdd8622a348fe1983fad7a0f0ccb1cd67b"}, - {file = "contourpy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fa4c02abe6c446ba70d96ece336e621efa4aecae43eaa9b030ae5fb92b309ad"}, - {file = "contourpy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:834e0cfe17ba12f79963861e0f908556b2cedd52e1f75e6578801febcc6a9f49"}, - {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbc4c3217eee163fa3984fd1567632b48d6dfd29216da3ded3d7b844a8014a66"}, - {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4865cd1d419e0c7a7bf6de1777b185eebdc51470800a9f42b9e9decf17762081"}, - {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:303c252947ab4b14c08afeb52375b26781ccd6a5ccd81abcdfc1fafd14cf93c1"}, - {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637f674226be46f6ba372fd29d9523dd977a291f66ab2a74fbeb5530bb3f445d"}, - {file = "contourpy-1.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:76a896b2f195b57db25d6b44e7e03f221d32fe318d03ede41f8b4d9ba1bff53c"}, - {file = "contourpy-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e1fd23e9d01591bab45546c089ae89d926917a66dceb3abcf01f6105d927e2cb"}, - {file = "contourpy-1.3.0-cp311-cp311-win32.whl", hash = "sha256:d402880b84df3bec6eab53cd0cf802cae6a2ef9537e70cf75e91618a3801c20c"}, - {file = "contourpy-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:6cb6cc968059db9c62cb35fbf70248f40994dfcd7aa10444bbf8b3faeb7c2d67"}, - {file = "contourpy-1.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:570ef7cf892f0afbe5b2ee410c507ce12e15a5fa91017a0009f79f7d93a1268f"}, - {file = "contourpy-1.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:da84c537cb8b97d153e9fb208c221c45605f73147bd4cadd23bdae915042aad6"}, - {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0be4d8425bfa755e0fd76ee1e019636ccc7c29f77a7c86b4328a9eb6a26d0639"}, - {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c0da700bf58f6e0b65312d0a5e695179a71d0163957fa381bb3c1f72972537c"}, - {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb8b141bb00fa977d9122636b16aa67d37fd40a3d8b52dd837e536d64b9a4d06"}, - {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3634b5385c6716c258d0419c46d05c8aa7dc8cb70326c9a4fb66b69ad2b52e09"}, - {file = "contourpy-1.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0dce35502151b6bd35027ac39ba6e5a44be13a68f55735c3612c568cac3805fd"}, - {file = "contourpy-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aea348f053c645100612b333adc5983d87be69acdc6d77d3169c090d3b01dc35"}, - {file = "contourpy-1.3.0-cp312-cp312-win32.whl", hash = "sha256:90f73a5116ad1ba7174341ef3ea5c3150ddf20b024b98fb0c3b29034752c8aeb"}, - {file = "contourpy-1.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:b11b39aea6be6764f84360fce6c82211a9db32a7c7de8fa6dd5397cf1d079c3b"}, - {file = "contourpy-1.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3e1c7fa44aaae40a2247e2e8e0627f4bea3dd257014764aa644f319a5f8600e3"}, - {file = "contourpy-1.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:364174c2a76057feef647c802652f00953b575723062560498dc7930fc9b1cb7"}, - {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32b238b3b3b649e09ce9aaf51f0c261d38644bdfa35cbaf7b263457850957a84"}, - {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d51fca85f9f7ad0b65b4b9fe800406d0d77017d7270d31ec3fb1cc07358fdea0"}, - {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:732896af21716b29ab3e988d4ce14bc5133733b85956316fb0c56355f398099b"}, - {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d73f659398a0904e125280836ae6f88ba9b178b2fed6884f3b1f95b989d2c8da"}, - {file = "contourpy-1.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c6c7c2408b7048082932cf4e641fa3b8ca848259212f51c8c59c45aa7ac18f14"}, - {file = "contourpy-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f317576606de89da6b7e0861cf6061f6146ead3528acabff9236458a6ba467f8"}, - {file = "contourpy-1.3.0-cp313-cp313-win32.whl", hash = "sha256:31cd3a85dbdf1fc002280c65caa7e2b5f65e4a973fcdf70dd2fdcb9868069294"}, - {file = "contourpy-1.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:4553c421929ec95fb07b3aaca0fae668b2eb5a5203d1217ca7c34c063c53d087"}, - {file = "contourpy-1.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:345af746d7766821d05d72cb8f3845dfd08dd137101a2cb9b24de277d716def8"}, - {file = "contourpy-1.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3bb3808858a9dc68f6f03d319acd5f1b8a337e6cdda197f02f4b8ff67ad2057b"}, - {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:420d39daa61aab1221567b42eecb01112908b2cab7f1b4106a52caaec8d36973"}, - {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d63ee447261e963af02642ffcb864e5a2ee4cbfd78080657a9880b8b1868e18"}, - {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:167d6c890815e1dac9536dca00828b445d5d0df4d6a8c6adb4a7ec3166812fa8"}, - {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:710a26b3dc80c0e4febf04555de66f5fd17e9cf7170a7b08000601a10570bda6"}, - {file = "contourpy-1.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:75ee7cb1a14c617f34a51d11fa7524173e56551646828353c4af859c56b766e2"}, - {file = "contourpy-1.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:33c92cdae89ec5135d036e7218e69b0bb2851206077251f04a6c4e0e21f03927"}, - {file = "contourpy-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a11077e395f67ffc2c44ec2418cfebed032cd6da3022a94fc227b6faf8e2acb8"}, - {file = "contourpy-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e8134301d7e204c88ed7ab50028ba06c683000040ede1d617298611f9dc6240c"}, - {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e12968fdfd5bb45ffdf6192a590bd8ddd3ba9e58360b29683c6bb71a7b41edca"}, - {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fd2a0fc506eccaaa7595b7e1418951f213cf8255be2600f1ea1b61e46a60c55f"}, - {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4cfb5c62ce023dfc410d6059c936dcf96442ba40814aefbfa575425a3a7f19dc"}, - {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68a32389b06b82c2fdd68276148d7b9275b5f5cf13e5417e4252f6d1a34f72a2"}, - {file = "contourpy-1.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:94e848a6b83da10898cbf1311a815f770acc9b6a3f2d646f330d57eb4e87592e"}, - {file = "contourpy-1.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d78ab28a03c854a873787a0a42254a0ccb3cb133c672f645c9f9c8f3ae9d0800"}, - {file = "contourpy-1.3.0-cp39-cp39-win32.whl", hash = "sha256:81cb5ed4952aae6014bc9d0421dec7c5835c9c8c31cdf51910b708f548cf58e5"}, - {file = "contourpy-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:14e262f67bd7e6eb6880bc564dcda30b15e351a594657e55b7eec94b6ef72843"}, - {file = "contourpy-1.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fe41b41505a5a33aeaed2a613dccaeaa74e0e3ead6dd6fd3a118fb471644fd6c"}, - {file = "contourpy-1.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eca7e17a65f72a5133bdbec9ecf22401c62bcf4821361ef7811faee695799779"}, - {file = "contourpy-1.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1ec4dc6bf570f5b22ed0d7efba0dfa9c5b9e0431aeea7581aa217542d9e809a4"}, - {file = "contourpy-1.3.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:00ccd0dbaad6d804ab259820fa7cb0b8036bda0686ef844d24125d8287178ce0"}, - {file = "contourpy-1.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ca947601224119117f7c19c9cdf6b3ab54c5726ef1d906aa4a69dfb6dd58102"}, - {file = "contourpy-1.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c6ec93afeb848a0845a18989da3beca3eec2c0f852322efe21af1931147d12cb"}, - {file = "contourpy-1.3.0.tar.gz", hash = "sha256:7ffa0db17717a8ffb127efd0c95a4362d996b892c2904db72428d5b52e1938a4"}, -] - -[package.dependencies] -numpy = ">=1.23" - -[package.extras] -bokeh = ["bokeh", "selenium"] -docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] -mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.11.1)", "types-Pillow"] -test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] -test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] - -[[package]] -name = "coverage" -version = "7.6.4" -description = "Code coverage measurement for Python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "coverage-7.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07"}, - {file = "coverage-7.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0"}, - {file = "coverage-7.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72"}, - {file = "coverage-7.6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51"}, - {file = "coverage-7.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491"}, - {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b"}, - {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea"}, - {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a"}, - {file = "coverage-7.6.4-cp310-cp310-win32.whl", hash = "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa"}, - {file = "coverage-7.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172"}, - {file = "coverage-7.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b"}, - {file = "coverage-7.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25"}, - {file = "coverage-7.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546"}, - {file = "coverage-7.6.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b"}, - {file = "coverage-7.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e"}, - {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718"}, - {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db"}, - {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522"}, - {file = "coverage-7.6.4-cp311-cp311-win32.whl", hash = "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf"}, - {file = "coverage-7.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19"}, - {file = "coverage-7.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2"}, - {file = "coverage-7.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117"}, - {file = "coverage-7.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613"}, - {file = "coverage-7.6.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27"}, - {file = "coverage-7.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52"}, - {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2"}, - {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1"}, - {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5"}, - {file = "coverage-7.6.4-cp312-cp312-win32.whl", hash = "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17"}, - {file = "coverage-7.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08"}, - {file = "coverage-7.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9"}, - {file = "coverage-7.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba"}, - {file = "coverage-7.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c"}, - {file = "coverage-7.6.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06"}, - {file = "coverage-7.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f"}, - {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b"}, - {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21"}, - {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a"}, - {file = "coverage-7.6.4-cp313-cp313-win32.whl", hash = "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e"}, - {file = "coverage-7.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963"}, - {file = "coverage-7.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f"}, - {file = "coverage-7.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806"}, - {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11"}, - {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3"}, - {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a"}, - {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc"}, - {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70"}, - {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef"}, - {file = "coverage-7.6.4-cp313-cp313t-win32.whl", hash = "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e"}, - {file = "coverage-7.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1"}, - {file = "coverage-7.6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9cb7fa111d21a6b55cbf633039f7bc2749e74932e3aa7cb7333f675a58a58bf3"}, - {file = "coverage-7.6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11a223a14e91a4693d2d0755c7a043db43d96a7450b4f356d506c2562c48642c"}, - {file = "coverage-7.6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a413a096c4cbac202433c850ee43fa326d2e871b24554da8327b01632673a076"}, - {file = "coverage-7.6.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00a1d69c112ff5149cabe60d2e2ee948752c975d95f1e1096742e6077affd376"}, - {file = "coverage-7.6.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f76846299ba5c54d12c91d776d9605ae33f8ae2b9d1d3c3703cf2db1a67f2c0"}, - {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fe439416eb6380de434886b00c859304338f8b19f6f54811984f3420a2e03858"}, - {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0294ca37f1ba500667b1aef631e48d875ced93ad5e06fa665a3295bdd1d95111"}, - {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6f01ba56b1c0e9d149f9ac85a2f999724895229eb36bd997b61e62999e9b0901"}, - {file = "coverage-7.6.4-cp39-cp39-win32.whl", hash = "sha256:bc66f0bf1d7730a17430a50163bb264ba9ded56739112368ba985ddaa9c3bd09"}, - {file = "coverage-7.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:c481b47f6b5845064c65a7bc78bc0860e635a9b055af0df46fdf1c58cebf8e8f"}, - {file = "coverage-7.6.4-pp39.pp310-none-any.whl", hash = "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e"}, - {file = "coverage-7.6.4.tar.gz", hash = "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73"}, -] - -[package.dependencies] -tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} - -[package.extras] -toml = ["tomli"] - -[[package]] -name = "cramjam" -version = "2.9.0" -description = "Thin Python bindings to de/compression algorithms in Rust" -optional = true -python-versions = ">=3.8" -files = [ - {file = "cramjam-2.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:eb16d995e454b0155b166f6e6da7df4ac812d44e0f3b6dc0f344a934609fd5bc"}, - {file = "cramjam-2.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cb1e86bfea656b51f2e75f2cedb17fc08b552d105b814d19b595294ecbe94d8d"}, - {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4bd76b654275736fd4f55521981b73751c34dacf70a1dbce96e454a39d43201f"}, - {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21569f19d5848606b85ac0dde0dc3639319d26fed8522c7103515df875bcb300"}, - {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b8f8b1117b4e697d39950ecab01700ce0aef66541e4478eb4d7b3ade8703347b"}, - {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3464d0042a03e8ef38a2b774ef23163cf3c0cdc41b8dfbf7c4aadf93e40b459"}, - {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0711c776750e243ae347d6609c975f0ff4be9ae65b2764d29e4bbdad8e574c3a"}, - {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00d96f798bc980b29f8e1c3ed7d554050e05d4cde23d1633ffed4cd63110024a"}, - {file = "cramjam-2.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fc49b6575e3cb15da3180c5a3926ec81db33b109e48530708da76614b306904b"}, - {file = "cramjam-2.9.0-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:c4fa6c23e56d48df18f534af921ec936c812743a8972ecdd5e5ff47b464fea00"}, - {file = "cramjam-2.9.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b4b8d8160685c11ffb4e8e6daaab79cb351a1c54ceec41cc18a0a62c89309fe0"}, - {file = "cramjam-2.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0ed6362cb6c964f8d0c6e7f790e8961b9242cd3acd87c56169ca14d642653707"}, - {file = "cramjam-2.9.0-cp310-none-win32.whl", hash = "sha256:fe9af350dfbdc7ed4c93a8016a8ad7b5492fc116e7197cad7cbce99b434d3fe1"}, - {file = "cramjam-2.9.0-cp310-none-win_amd64.whl", hash = "sha256:37054c73704a3183b60869e7fec1614648752c31d89f44de1ffe1f01ad4d20d5"}, - {file = "cramjam-2.9.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:170a50407f9400073621cc1d5f3200ca3ad9de3000831e3e86f5561ca8048a08"}, - {file = "cramjam-2.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:912c94781c8ff318a4d3f3306f8d94d41ae5aa7b9760c4bb0476b01142084845"}, - {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:df089639983a03070be6eabc60317aa1ffbf2c5409023b57a5fc2e4975163bc4"}, - {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ca28a8f6ab5fca35f163fd7d7a970880ce4fc1a0bead1249ecdaa96ec9ac1f4"}, - {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:abd8bf9a94e3866215ac181a7dbcfa1ddbedca4f8048494a79934febe88537df"}, - {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7de19a382bcab93cd4d028d51f6f581920a3b79659a384775188135b7fc64f15"}, - {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a4156fcefa1dfaa65d35ff82c252d1e32be12820f26d04748be6cd3b461cf85f"}, - {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4a3104022129d7463100dfaf12efd398ebfa4b7e4e50832ccc596754f7c26df"}, - {file = "cramjam-2.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6ebee5f5d7e2b9277895ea4fd94646b72075fe9cfc0e8f4770b65c9e72b1fec1"}, - {file = "cramjam-2.9.0-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:8e33ebe4d709b21bc15e7ddf485ac6b30d7fdc7ed7c3c65130654c007f50c183"}, - {file = "cramjam-2.9.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4d5a39118008bb9f2fba36a0ceea6c41fbd0b55d2647b043ba51a868e5f6de92"}, - {file = "cramjam-2.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7f6ef35eba883927af2678b561cc4407e0b3b0d58a251c863bec4b3d8258cc2f"}, - {file = "cramjam-2.9.0-cp311-none-win32.whl", hash = "sha256:b21e55b5cfdaff96eae1f323ae9a0d36e86852cdf62fe23b60a2481d2fed5571"}, - {file = "cramjam-2.9.0-cp311-none-win_amd64.whl", hash = "sha256:9f685fe4e49b2f3e233548e3397b3f9189d71a265718ec631d13eca3d5718ddb"}, - {file = "cramjam-2.9.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:34578e4c1518b10dad5e0ba40c721e529ef13e7742a528843b40e1f20dd6078c"}, - {file = "cramjam-2.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1d5b5512dc61ea78f32e021e88a5fd5b46a821409479e6657d33614fc9e45677"}, - {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0b4f1b5e33915ed591c0c19b8c3bbdd7aa0f6a9bfe2b7246b475d497bda15f18"}, - {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad301801afa0eecdacabf353a2802df5e6770f9bfb0a559d6c069813d83cfd42"}, - {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:399baf80fea574e3870f233e12e6a12f02c53b054e13d792348b272b0614370a"}, - {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3121e2fbec58907fa70636adaeaf30c27614c867e08a7a5bd2887b33786ff790"}, - {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd04205b2a87087ffc2257c3ad33f11daabc053956f64ac1ec7bae299cac3f2f"}, - {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddb9c4db36188a8f08c2303100a83100f26a8572803ae35eadff359bebd3d204"}, - {file = "cramjam-2.9.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ef553d4080368006817c1a935ed619c71987cf10417a32386acc00c5418a2934"}, - {file = "cramjam-2.9.0-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:9862ca8ead80857ecfb9b07f02f577733261e981346f31585fe118975eabb738"}, - {file = "cramjam-2.9.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4714e1ea0c3329368b83fe5ad6e831d5ca11fb794ca7cf491622eb6b2d420d2f"}, - {file = "cramjam-2.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1b4ca30c9f27e3b88bc082d4637e7648f93da5cb69a2dbe0c0300bc51353c820"}, - {file = "cramjam-2.9.0-cp312-none-win32.whl", hash = "sha256:0ed2fef010d1caca9ea63814e9cb5b1d47d907b80302b8cc0b3a1e116ea241e2"}, - {file = "cramjam-2.9.0-cp312-none-win_amd64.whl", hash = "sha256:bd26d71939de5dcf169d479fbc7fcfed21e6675bab33e7f7e9f8405f19711c71"}, - {file = "cramjam-2.9.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:dd70ea5d7b2c5e479e04ac3a00d8bc3deca146d2b5dbfbe3d7b42ed136e19de4"}, - {file = "cramjam-2.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b1410e68c464666473a89cade17483b94bb4639d9161c440ee54ee1e0eca583"}, - {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b0078727fe8c28ef1695e5d04aae5c41ac697eb087cba387c6a02b825f9071c0"}, - {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a63c4e63319bf7dfc3ab46c06afb76d3d9cc1c94369b609dde480e5cc78e4de"}, - {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47d7253b5a10c201cc65aecfb517dfa1c0b5831b2524ac32dd2964fceafc0dc4"}, - {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05970fb640f236767003e62c256a085754536169bac863f4a3502ecb59cbf197"}, - {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0b062d261fa3fac00146cf801896c8cfafe1e41332eb047aa0a36558299daa6"}, - {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:017b7066f18b7b676068f51b1dbdecc02d76d9af10092252b22dcbd03a78ed33"}, - {file = "cramjam-2.9.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:9de33ef3bc006c11fbad1dc8b15341dcc78430df2c5ce1e790dfb729b11ab593"}, - {file = "cramjam-2.9.0-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:b99efaf81be8e381de1cde6574e2c89030ed53994e73b0e75b62d6e232f491c5"}, - {file = "cramjam-2.9.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:36426e3f1920f6aa4c644d007bf9cfad06dd9f1a30cd0a921d72b010492d8447"}, - {file = "cramjam-2.9.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ea9bcaff298f5d35ef67346d474fca388c5cf6d4edab1d06b84868800f88bd36"}, - {file = "cramjam-2.9.0-cp313-none-win32.whl", hash = "sha256:c48da60a5eb481b412e5e462b81ad307fb2203178a2840a743f0a7c5fc1718c9"}, - {file = "cramjam-2.9.0-cp313-none-win_amd64.whl", hash = "sha256:97a6311bd32f301ff1b922bc9de62ace3d9fd845e20efc0f71b4d0239a45b8d2"}, - {file = "cramjam-2.9.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:78e7349f945a83bc48855fb042873092a69b155a088b8c11942eb76418b32705"}, - {file = "cramjam-2.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:65a097ea765dd4ef2fb868b5b0959d7c93a64c250b2c52f462898c823ae4b950"}, - {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:35cad507eb02c775e6c5444312f98b28dd8bf122425677ae199484996e838673"}, - {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8982925d179b940efa860513a31b839bb06343501077cca3e67f7a2f7360d355"}, - {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ba7e2d33e1d092dffd0a3ff4bd1b86177594aa3c2901fd478e78e1fb2aee8ed3"}, - {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:904be92e3bc25e78343ee52aa0fd5fba3a31d11d474e8af4623a9d00baa84bc2"}, - {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9221297c547d702e1431e96705fce26c6a87df34a681a6b97fe63b536d09c1d8"}, - {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e98a18c22a85f321091cc8db6694af1d713a369c2d60ec611c10ccfe24ab103a"}, - {file = "cramjam-2.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e248510f8e2dbc71fa99f86238c9023365dbe1a4520eb40e33d73416527349f2"}, - {file = "cramjam-2.9.0-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:dc07376aa33b6004ea372ac9b0ba0ed3455aa2fc4e18727414142ecb46b176b8"}, - {file = "cramjam-2.9.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e94021c541eb2a199b5a2ffae0ea84fb8b99863dab99a5b154b00bc7a44b5c48"}, - {file = "cramjam-2.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4adbf4366f8dc29b7c5c731c800cf633be76c9911e928daeb606827d6ae7c599"}, - {file = "cramjam-2.9.0-cp38-none-win32.whl", hash = "sha256:ca880f555c8db40942acc8a50722c33e229b6be90e598acc1a201f36487b917d"}, - {file = "cramjam-2.9.0-cp38-none-win_amd64.whl", hash = "sha256:ab17a429a92db90bf40115efb97d10e71b94b0dcacf30cf724552df2794a58fb"}, - {file = "cramjam-2.9.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ed7fd7bc2b86ec3161fe0cc49f5f392e6efa55c91a95397d5047820c38117660"}, - {file = "cramjam-2.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a0f654c739a6bc4a69a2aaf31463328a208757ed780ff886234532f78e06a864"}, - {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cd4d4ab9deb5846af0ac6cf1fa139cfa40291ad14d073efa8b8e20c8d1aa90bd"}, - {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bafc32f01d4ab64f83fdbc29bc5bd25a920b59c751c12e06e6f4b1e379be7600"}, - {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0fb5ea631dbf998f667766a9e485e757817d66ed559916ba553a0ec2f902d788"}, - {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c902e56e60c48f5f15e55257aaa1c2678323df5f18a1b839e8d05cac1107576c"}, - {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:441d3875cdffe5df9294b93ef570058837732dd727cd9d18efa0f089f1c2687a"}, - {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed486e57a79ccc7aebaa2ec12517d891fdc5d2fde16915e3db705b8a47570981"}, - {file = "cramjam-2.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:013cb872205641c6e5269f530ed40aaaa5640d84e0d8f33b89f5a1bf7f655527"}, - {file = "cramjam-2.9.0-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:a41b4b10a381be1d42a1a7dd07b8c3faccd3d12c7e98e973a6ec558fd040a607"}, - {file = "cramjam-2.9.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:598eac1713ddbe69c3b30dcc890d69b206ce08903fc3aed58149aae87c61973a"}, - {file = "cramjam-2.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:72e9ebc27c557706a3c9964c1d1b4522857760dbd60c105a4f5421f3b66e31a2"}, - {file = "cramjam-2.9.0-cp39-none-win32.whl", hash = "sha256:dbbd6fba677e1cbc9d6bd4ebbe3e8b3667d0295f1731489db2a971c95f0ceca0"}, - {file = "cramjam-2.9.0-cp39-none-win_amd64.whl", hash = "sha256:7f33a83969fa94ee8e0c1f0aef8eb303ead3e9142338dc543abeb7e1a28734ab"}, - {file = "cramjam-2.9.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:132db7d3346ea21ba44e7ee23ec73bd6fa9eb1e77133ca6dfe1f7449a69999af"}, - {file = "cramjam-2.9.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2addf801c88bead21256ccd87dc97cffead03758c4a4947fad8e454f4abfda0a"}, - {file = "cramjam-2.9.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24afad3ba62774abbb150dc25aab21b047ab999c4143c7a8d96577848baf7af6"}, - {file = "cramjam-2.9.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:604c16052cf29d0c796927ed7e107f65429d2036c82c9a8009bd453c94e5e4f0"}, - {file = "cramjam-2.9.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:65bded20fd2cef17b22246c336ddd67fac842341ee311042b4a70e65dc745aa7"}, - {file = "cramjam-2.9.0.tar.gz", hash = "sha256:f103e648aa3ebe9b8e2c1a3a92719288d8f3f41007c319ad298cdce2d0c28641"}, -] - -[package.extras] -dev = ["black (==22.3.0)", "hypothesis", "numpy", "pytest (>=5.30)", "pytest-benchmark", "pytest-xdist"] - -[[package]] -name = "cryptography" -version = "42.0.8" -description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -optional = false -python-versions = ">=3.7" -files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, -] - -[package.dependencies] -cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} - -[package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] -docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] -nox = ["nox"] -pep8test = ["check-sdist", "click", "mypy", "ruff"] -sdist = ["build"] -ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] -test-randomorder = ["pytest-randomly"] - -[[package]] -name = "cycler" -version = "0.12.1" -description = "Composable style cycles" -optional = true -python-versions = ">=3.8" -files = [ - {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, - {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, -] - -[package.extras] -docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] -tests = ["pytest", "pytest-cov", "pytest-xdist"] - -[[package]] -name = "dataclasses-json" -version = "0.6.7" -description = "Easily serialize dataclasses to and from JSON." -optional = true -python-versions = "<4.0,>=3.7" -files = [ - {file = "dataclasses_json-0.6.7-py3-none-any.whl", hash = "sha256:0dbf33f26c8d5305befd61b39d2b3414e8a407bedc2834dea9b8d642666fb40a"}, - {file = "dataclasses_json-0.6.7.tar.gz", hash = "sha256:b6b3e528266ea45b9535223bc53ca645f5208833c29229e847b3f26a1cc55fc0"}, -] - -[package.dependencies] -marshmallow = ">=3.18.0,<4.0.0" -typing-inspect = ">=0.4.0,<1" - -[[package]] -name = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - -[[package]] -name = "docutils" -version = "0.17.1" -description = "Docutils -- Python Documentation Utilities" -optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, - {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, -] - -[[package]] -name = "dpath" -version = "2.2.0" -description = "Filesystem-like pathing and searching for dictionaries" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dpath-2.2.0-py3-none-any.whl", hash = "sha256:b330a375ded0a0d2ed404440f6c6a715deae5313af40bbb01c8a41d891900576"}, - {file = "dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e"}, -] - -[[package]] -name = "emoji" -version = "2.14.0" -description = "Emoji for Python" -optional = true -python-versions = ">=3.7" -files = [ - {file = "emoji-2.14.0-py3-none-any.whl", hash = "sha256:fcc936bf374b1aec67dda5303ae99710ba88cc9cdce2d1a71c5f2204e6d78799"}, - {file = "emoji-2.14.0.tar.gz", hash = "sha256:f68ac28915a2221667cddb3e6c589303c3c6954c6c5af6fefaec7f9bdf72fdca"}, -] - -[package.extras] -dev = ["coverage", "pytest (>=7.4.4)"] - -[[package]] -name = "et-xmlfile" -version = "1.1.0" -description = "An implementation of lxml.xmlfile for the standard library" -optional = true -python-versions = ">=3.6" -files = [ - {file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"}, - {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "fastavro" -version = "1.8.2" -description = "Fast read/write of AVRO files" -optional = true -python-versions = ">=3.8" -files = [ - {file = "fastavro-1.8.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:0e08964b2e9a455d831f2557402a683d4c4d45206f2ab9ade7c69d3dc14e0e58"}, - {file = "fastavro-1.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:401a70b1e5c7161420c6019e0c8afa88f7c8a373468591f5ec37639a903c2509"}, - {file = "fastavro-1.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef1ed3eaa4240c05698d02d8d0c010b9a03780eda37b492da6cd4c9d37e04ec"}, - {file = "fastavro-1.8.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:543185a672ff6306beb329b57a7b8a3a2dd1eb21a5ccc530150623d58d48bb98"}, - {file = "fastavro-1.8.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ffbf8bae1edb50fe7beeffc3afa8e684686550c2e5d31bf01c25cfa213f581e1"}, - {file = "fastavro-1.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:bb545eb9d876bc7b785e27e98e7720ada7eee7d7a1729798d2ed51517f13500a"}, - {file = "fastavro-1.8.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b837d3038c651046252bc92c1b9899bf21c7927a148a1ff89599c36c2a331ca"}, - {file = "fastavro-1.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3510e96c0a47e4e914bd1a29c954eb662bfa24849ad92e597cb97cc79f21af7"}, - {file = "fastavro-1.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ccc0e74f2c2ab357f39bb73d67fcdb6dc10e23fdbbd399326139f72ec0fb99a3"}, - {file = "fastavro-1.8.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:add51c70d0ab1175601c75cd687bbe9d16ae312cd8899b907aafe0d79ee2bc1d"}, - {file = "fastavro-1.8.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d9e2662f57e6453e9a2c9fb4f54b2a9e62e3e46f5a412ac00558112336d23883"}, - {file = "fastavro-1.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:fea75cf53a93c56dd56e68abce8d314ef877b27451c870cd7ede7582d34c08a7"}, - {file = "fastavro-1.8.2-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:f489020bb8664c2737c03457ad5dbd490579ddab6f0a7b5c17fecfe982715a89"}, - {file = "fastavro-1.8.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a547625c138efd5e61300119241041906ee8cb426fc7aa789900f87af7ed330d"}, - {file = "fastavro-1.8.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53beb458f30c9ad4aa7bff4a42243ff990ffb713b6ce0cd9b360cbc3d648fe52"}, - {file = "fastavro-1.8.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7b1b2cbd2dd851452306beed0ab9bdaeeab1cc8ad46f84b47cd81eeaff6dd6b8"}, - {file = "fastavro-1.8.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d29e9baee0b2f37ecd09bde3b487cf900431fd548c85be3e4fe1b9a0b2a917f1"}, - {file = "fastavro-1.8.2-cp38-cp38-win_amd64.whl", hash = "sha256:66e132c710663230292bc63e2cb79cf95b16ccb94a5fc99bb63694b24e312fc5"}, - {file = "fastavro-1.8.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:38aca63ce604039bcdf2edd14912d00287bdbf8b76f9aa42b28e6ca0bf950092"}, - {file = "fastavro-1.8.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9787835f6449ee94713e7993a700432fce3763024791ffa8a58dc91ef9d1f950"}, - {file = "fastavro-1.8.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:536cb448bc83811056be02749fd9df37a69621678f02597d272970a769e9b40c"}, - {file = "fastavro-1.8.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e9d5027cf7d9968f8f819958b41bfedb933323ea6d6a0485eefacaa1afd91f54"}, - {file = "fastavro-1.8.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:792adfc0c80c7f1109e0ab4b0decef20691fdf0a45091d397a0563872eb56d42"}, - {file = "fastavro-1.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:650b22766259f7dd7519dfa4e4658f0e233c319efa130b9cf0c36a500e09cc57"}, - {file = "fastavro-1.8.2.tar.gz", hash = "sha256:ab9d9226d4b66b6b3d0661a57cd45259b0868fed1c0cd4fac95249b9e0973320"}, -] - -[package.extras] -codecs = ["lz4", "python-snappy", "zstandard"] -lz4 = ["lz4"] -snappy = ["python-snappy"] -zstandard = ["zstandard"] - -[[package]] -name = "filetype" -version = "1.2.0" -description = "Infer file type and MIME type of any file/buffer. No external dependencies." -optional = true -python-versions = "*" -files = [ - {file = "filetype-1.2.0-py2.py3-none-any.whl", hash = "sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25"}, - {file = "filetype-1.2.0.tar.gz", hash = "sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb"}, -] - -[[package]] -name = "flake8" -version = "6.1.0" -description = "the modular source code checker: pep8 pyflakes and co" -optional = false -python-versions = ">=3.8.1" -files = [ - {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"}, - {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"}, -] - -[package.dependencies] -mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.11.0,<2.12.0" -pyflakes = ">=3.1.0,<3.2.0" - -[[package]] -name = "fonttools" -version = "4.54.1" -description = "Tools to manipulate font files" -optional = true -python-versions = ">=3.8" -files = [ - {file = "fonttools-4.54.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7ed7ee041ff7b34cc62f07545e55e1468808691dddfd315d51dd82a6b37ddef2"}, - {file = "fonttools-4.54.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41bb0b250c8132b2fcac148e2e9198e62ff06f3cc472065dff839327945c5882"}, - {file = "fonttools-4.54.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7965af9b67dd546e52afcf2e38641b5be956d68c425bef2158e95af11d229f10"}, - {file = "fonttools-4.54.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:278913a168f90d53378c20c23b80f4e599dca62fbffae4cc620c8eed476b723e"}, - {file = "fonttools-4.54.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0e88e3018ac809b9662615072dcd6b84dca4c2d991c6d66e1970a112503bba7e"}, - {file = "fonttools-4.54.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4aa4817f0031206e637d1e685251ac61be64d1adef111060df84fdcbc6ab6c44"}, - {file = "fonttools-4.54.1-cp310-cp310-win32.whl", hash = "sha256:7e3b7d44e18c085fd8c16dcc6f1ad6c61b71ff463636fcb13df7b1b818bd0c02"}, - {file = "fonttools-4.54.1-cp310-cp310-win_amd64.whl", hash = "sha256:dd9cc95b8d6e27d01e1e1f1fae8559ef3c02c76317da650a19047f249acd519d"}, - {file = "fonttools-4.54.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5419771b64248484299fa77689d4f3aeed643ea6630b2ea750eeab219588ba20"}, - {file = "fonttools-4.54.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:301540e89cf4ce89d462eb23a89464fef50915255ece765d10eee8b2bf9d75b2"}, - {file = "fonttools-4.54.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ae5091547e74e7efecc3cbf8e75200bc92daaeb88e5433c5e3e95ea8ce5aa7"}, - {file = "fonttools-4.54.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82834962b3d7c5ca98cb56001c33cf20eb110ecf442725dc5fdf36d16ed1ab07"}, - {file = "fonttools-4.54.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d26732ae002cc3d2ecab04897bb02ae3f11f06dd7575d1df46acd2f7c012a8d8"}, - {file = "fonttools-4.54.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:58974b4987b2a71ee08ade1e7f47f410c367cdfc5a94fabd599c88165f56213a"}, - {file = "fonttools-4.54.1-cp311-cp311-win32.whl", hash = "sha256:ab774fa225238986218a463f3fe151e04d8c25d7de09df7f0f5fce27b1243dbc"}, - {file = "fonttools-4.54.1-cp311-cp311-win_amd64.whl", hash = "sha256:07e005dc454eee1cc60105d6a29593459a06321c21897f769a281ff2d08939f6"}, - {file = "fonttools-4.54.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:54471032f7cb5fca694b5f1a0aaeba4af6e10ae989df408e0216f7fd6cdc405d"}, - {file = "fonttools-4.54.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fa92cb248e573daab8d032919623cc309c005086d743afb014c836636166f08"}, - {file = "fonttools-4.54.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a911591200114969befa7f2cb74ac148bce5a91df5645443371aba6d222e263"}, - {file = "fonttools-4.54.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93d458c8a6a354dc8b48fc78d66d2a8a90b941f7fec30e94c7ad9982b1fa6bab"}, - {file = "fonttools-4.54.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5eb2474a7c5be8a5331146758debb2669bf5635c021aee00fd7c353558fc659d"}, - {file = "fonttools-4.54.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c9c563351ddc230725c4bdf7d9e1e92cbe6ae8553942bd1fb2b2ff0884e8b714"}, - {file = "fonttools-4.54.1-cp312-cp312-win32.whl", hash = "sha256:fdb062893fd6d47b527d39346e0c5578b7957dcea6d6a3b6794569370013d9ac"}, - {file = "fonttools-4.54.1-cp312-cp312-win_amd64.whl", hash = "sha256:e4564cf40cebcb53f3dc825e85910bf54835e8a8b6880d59e5159f0f325e637e"}, - {file = "fonttools-4.54.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6e37561751b017cf5c40fce0d90fd9e8274716de327ec4ffb0df957160be3bff"}, - {file = "fonttools-4.54.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:357cacb988a18aace66e5e55fe1247f2ee706e01debc4b1a20d77400354cddeb"}, - {file = "fonttools-4.54.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e953cc0bddc2beaf3a3c3b5dd9ab7554677da72dfaf46951e193c9653e515a"}, - {file = "fonttools-4.54.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:58d29b9a294573d8319f16f2f79e42428ba9b6480442fa1836e4eb89c4d9d61c"}, - {file = "fonttools-4.54.1-cp313-cp313-win32.whl", hash = "sha256:9ef1b167e22709b46bf8168368b7b5d3efeaaa746c6d39661c1b4405b6352e58"}, - {file = "fonttools-4.54.1-cp313-cp313-win_amd64.whl", hash = "sha256:262705b1663f18c04250bd1242b0515d3bbae177bee7752be67c979b7d47f43d"}, - {file = "fonttools-4.54.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ed2f80ca07025551636c555dec2b755dd005e2ea8fbeb99fc5cdff319b70b23b"}, - {file = "fonttools-4.54.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9dc080e5a1c3b2656caff2ac2633d009b3a9ff7b5e93d0452f40cd76d3da3b3c"}, - {file = "fonttools-4.54.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d152d1be65652fc65e695e5619e0aa0982295a95a9b29b52b85775243c06556"}, - {file = "fonttools-4.54.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8583e563df41fdecef31b793b4dd3af8a9caa03397be648945ad32717a92885b"}, - {file = "fonttools-4.54.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:0d1d353ef198c422515a3e974a1e8d5b304cd54a4c2eebcae708e37cd9eeffb1"}, - {file = "fonttools-4.54.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:fda582236fee135d4daeca056c8c88ec5f6f6d88a004a79b84a02547c8f57386"}, - {file = "fonttools-4.54.1-cp38-cp38-win32.whl", hash = "sha256:e7d82b9e56716ed32574ee106cabca80992e6bbdcf25a88d97d21f73a0aae664"}, - {file = "fonttools-4.54.1-cp38-cp38-win_amd64.whl", hash = "sha256:ada215fd079e23e060157aab12eba0d66704316547f334eee9ff26f8c0d7b8ab"}, - {file = "fonttools-4.54.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f5b8a096e649768c2f4233f947cf9737f8dbf8728b90e2771e2497c6e3d21d13"}, - {file = "fonttools-4.54.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4e10d2e0a12e18f4e2dd031e1bf7c3d7017be5c8dbe524d07706179f355c5dac"}, - {file = "fonttools-4.54.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31c32d7d4b0958600eac75eaf524b7b7cb68d3a8c196635252b7a2c30d80e986"}, - {file = "fonttools-4.54.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c39287f5c8f4a0c5a55daf9eaf9ccd223ea59eed3f6d467133cc727d7b943a55"}, - {file = "fonttools-4.54.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a7a310c6e0471602fe3bf8efaf193d396ea561486aeaa7adc1f132e02d30c4b9"}, - {file = "fonttools-4.54.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d3b659d1029946f4ff9b6183984578041b520ce0f8fb7078bb37ec7445806b33"}, - {file = "fonttools-4.54.1-cp39-cp39-win32.whl", hash = "sha256:e96bc94c8cda58f577277d4a71f51c8e2129b8b36fd05adece6320dd3d57de8a"}, - {file = "fonttools-4.54.1-cp39-cp39-win_amd64.whl", hash = "sha256:e8a4b261c1ef91e7188a30571be6ad98d1c6d9fa2427244c545e2fa0a2494dd7"}, - {file = "fonttools-4.54.1-py3-none-any.whl", hash = "sha256:37cddd62d83dc4f72f7c3f3c2bcf2697e89a30efb152079896544a93907733bd"}, - {file = "fonttools-4.54.1.tar.gz", hash = "sha256:957f669d4922f92c171ba01bef7f29410668db09f6c02111e22b2bce446f3285"}, -] - -[package.extras] -all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] -graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["munkres", "pycairo", "scipy"] -lxml = ["lxml (>=4.0)"] -pathops = ["skia-pathops (>=0.5.0)"] -plot = ["matplotlib"] -repacker = ["uharfbuzz (>=0.23.0)"] -symfont = ["sympy"] -type1 = ["xattr"] -ufo = ["fs (>=2.2.0,<3)"] -unicode = ["unicodedata2 (>=15.1.0)"] -woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] - -[[package]] -name = "freezegun" -version = "1.5.1" -description = "Let your Python tests travel through time" -optional = false -python-versions = ">=3.7" -files = [ - {file = "freezegun-1.5.1-py3-none-any.whl", hash = "sha256:bf111d7138a8abe55ab48a71755673dbaa4ab87f4cff5634a4442dfec34c15f1"}, - {file = "freezegun-1.5.1.tar.gz", hash = "sha256:b29dedfcda6d5e8e083ce71b2b542753ad48cfec44037b3fc79702e2980a89e9"}, -] - -[package.dependencies] -python-dateutil = ">=2.7" - -[[package]] -name = "frozenlist" -version = "1.4.1" -description = "A list-like structure which implements collections.abc.MutableSequence" -optional = true -python-versions = ">=3.8" -files = [ - {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac"}, - {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868"}, - {file = "frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776"}, - {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a"}, - {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad"}, - {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c"}, - {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe"}, - {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a"}, - {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98"}, - {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75"}, - {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5"}, - {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950"}, - {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc"}, - {file = "frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1"}, - {file = "frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439"}, - {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0"}, - {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49"}, - {file = "frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2"}, - {file = "frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17"}, - {file = "frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825"}, - {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae"}, - {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb"}, - {file = "frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b"}, - {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86"}, - {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480"}, - {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09"}, - {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a"}, - {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd"}, - {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6"}, - {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1"}, - {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b"}, - {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e"}, - {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8"}, - {file = "frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89"}, - {file = "frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5"}, - {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d"}, - {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826"}, - {file = "frozenlist-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb"}, - {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6"}, - {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d"}, - {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887"}, - {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a"}, - {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b"}, - {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701"}, - {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0"}, - {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11"}, - {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09"}, - {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7"}, - {file = "frozenlist-1.4.1-cp38-cp38-win32.whl", hash = "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497"}, - {file = "frozenlist-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09"}, - {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e"}, - {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d"}, - {file = "frozenlist-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8"}, - {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0"}, - {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b"}, - {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0"}, - {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897"}, - {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7"}, - {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742"}, - {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea"}, - {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5"}, - {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9"}, - {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6"}, - {file = "frozenlist-1.4.1-cp39-cp39-win32.whl", hash = "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932"}, - {file = "frozenlist-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0"}, - {file = "frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7"}, - {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, -] - -[[package]] -name = "genson" -version = "1.2.2" -description = "GenSON is a powerful, user-friendly JSON Schema generator." -optional = false -python-versions = "*" -files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, -] - -[[package]] -name = "greenlet" -version = "3.1.1" -description = "Lightweight in-process concurrent programming" -optional = true -python-versions = ">=3.7" -files = [ - {file = "greenlet-3.1.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:0bbae94a29c9e5c7e4a2b7f0aae5c17e8e90acbfd3bf6270eeba60c39fce3563"}, - {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fde093fb93f35ca72a556cf72c92ea3ebfda3d79fc35bb19fbe685853869a83"}, - {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36b89d13c49216cadb828db8dfa6ce86bbbc476a82d3a6c397f0efae0525bdd0"}, - {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94b6150a85e1b33b40b1464a3f9988dcc5251d6ed06842abff82e42632fac120"}, - {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93147c513fac16385d1036b7e5b102c7fbbdb163d556b791f0f11eada7ba65dc"}, - {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da7a9bff22ce038e19bf62c4dd1ec8391062878710ded0a845bcf47cc0200617"}, - {file = "greenlet-3.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b2795058c23988728eec1f36a4e5e4ebad22f8320c85f3587b539b9ac84128d7"}, - {file = "greenlet-3.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ed10eac5830befbdd0c32f83e8aa6288361597550ba669b04c48f0f9a2c843c6"}, - {file = "greenlet-3.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:77c386de38a60d1dfb8e55b8c1101d68c79dfdd25c7095d51fec2dd800892b80"}, - {file = "greenlet-3.1.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e4d333e558953648ca09d64f13e6d8f0523fa705f51cae3f03b5983489958c70"}, - {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09fc016b73c94e98e29af67ab7b9a879c307c6731a2c9da0db5a7d9b7edd1159"}, - {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d5e975ca70269d66d17dd995dafc06f1b06e8cb1ec1e9ed54c1d1e4a7c4cf26e"}, - {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2813dc3de8c1ee3f924e4d4227999285fd335d1bcc0d2be6dc3f1f6a318ec1"}, - {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e347b3bfcf985a05e8c0b7d462ba6f15b1ee1c909e2dcad795e49e91b152c383"}, - {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e8f8c9cb53cdac7ba9793c276acd90168f416b9ce36799b9b885790f8ad6c0a"}, - {file = "greenlet-3.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:62ee94988d6b4722ce0028644418d93a52429e977d742ca2ccbe1c4f4a792511"}, - {file = "greenlet-3.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1776fd7f989fc6b8d8c8cb8da1f6b82c5814957264d1f6cf818d475ec2bf6395"}, - {file = "greenlet-3.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:48ca08c771c268a768087b408658e216133aecd835c0ded47ce955381105ba39"}, - {file = "greenlet-3.1.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:4afe7ea89de619adc868e087b4d2359282058479d7cfb94970adf4b55284574d"}, - {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f406b22b7c9a9b4f8aa9d2ab13d6ae0ac3e85c9a809bd590ad53fed2bf70dc79"}, - {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3a701fe5a9695b238503ce5bbe8218e03c3bcccf7e204e455e7462d770268aa"}, - {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2846930c65b47d70b9d178e89c7e1a69c95c1f68ea5aa0a58646b7a96df12441"}, - {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99cfaa2110534e2cf3ba31a7abcac9d328d1d9f1b95beede58294a60348fba36"}, - {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1443279c19fca463fc33e65ef2a935a5b09bb90f978beab37729e1c3c6c25fe9"}, - {file = "greenlet-3.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b7cede291382a78f7bb5f04a529cb18e068dd29e0fb27376074b6d0317bf4dd0"}, - {file = "greenlet-3.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:23f20bb60ae298d7d8656c6ec6db134bca379ecefadb0b19ce6f19d1f232a942"}, - {file = "greenlet-3.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:7124e16b4c55d417577c2077be379514321916d5790fa287c9ed6f23bd2ffd01"}, - {file = "greenlet-3.1.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:05175c27cb459dcfc05d026c4232f9de8913ed006d42713cb8a5137bd49375f1"}, - {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935e943ec47c4afab8965954bf49bfa639c05d4ccf9ef6e924188f762145c0ff"}, - {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:667a9706c970cb552ede35aee17339a18e8f2a87a51fba2ed39ceeeb1004798a"}, - {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8a678974d1f3aa55f6cc34dc480169d58f2e6d8958895d68845fa4ab566509e"}, - {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efc0f674aa41b92da8c49e0346318c6075d734994c3c4e4430b1c3f853e498e4"}, - {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0153404a4bb921f0ff1abeb5ce8a5131da56b953eda6e14b88dc6bbc04d2049e"}, - {file = "greenlet-3.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:275f72decf9932639c1c6dd1013a1bc266438eb32710016a1c742df5da6e60a1"}, - {file = "greenlet-3.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c4aab7f6381f38a4b42f269057aee279ab0fc7bf2e929e3d4abfae97b682a12c"}, - {file = "greenlet-3.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42703b1cf69f2aa1df7d1030b9d77d3e584a70755674d60e710f0af570f3761"}, - {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1695e76146579f8c06c1509c7ce4dfe0706f49c6831a817ac04eebb2fd02011"}, - {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7876452af029456b3f3549b696bb36a06db7c90747740c5302f74a9e9fa14b13"}, - {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ead44c85f8ab905852d3de8d86f6f8baf77109f9da589cb4fa142bd3b57b475"}, - {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8320f64b777d00dd7ccdade271eaf0cad6636343293a25074cc5566160e4de7b"}, - {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6510bf84a6b643dabba74d3049ead221257603a253d0a9873f55f6a59a65f822"}, - {file = "greenlet-3.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:04b013dc07c96f83134b1e99888e7a79979f1a247e2a9f59697fa14b5862ed01"}, - {file = "greenlet-3.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:411f015496fec93c1c8cd4e5238da364e1da7a124bcb293f085bf2860c32c6f6"}, - {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47da355d8687fd65240c364c90a31569a133b7b60de111c255ef5b606f2ae291"}, - {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98884ecf2ffb7d7fe6bd517e8eb99d31ff7855a840fa6d0d63cd07c037f6a981"}, - {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1d4aeb8891338e60d1ab6127af1fe45def5259def8094b9c7e34690c8858803"}, - {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db32b5348615a04b82240cc67983cb315309e88d444a288934ee6ceaebcad6cc"}, - {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dcc62f31eae24de7f8dce72134c8651c58000d3b1868e01392baea7c32c247de"}, - {file = "greenlet-3.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1d3755bcb2e02de341c55b4fca7a745a24a9e7212ac953f6b3a48d117d7257aa"}, - {file = "greenlet-3.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b8da394b34370874b4572676f36acabac172602abf054cbc4ac910219f3340af"}, - {file = "greenlet-3.1.1-cp37-cp37m-win32.whl", hash = "sha256:a0dfc6c143b519113354e780a50381508139b07d2177cb6ad6a08278ec655798"}, - {file = "greenlet-3.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:54558ea205654b50c438029505def3834e80f0869a70fb15b871c29b4575ddef"}, - {file = "greenlet-3.1.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:346bed03fe47414091be4ad44786d1bd8bef0c3fcad6ed3dee074a032ab408a9"}, - {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfc59d69fc48664bc693842bd57acfdd490acafda1ab52c7836e3fc75c90a111"}, - {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21e10da6ec19b457b82636209cbe2331ff4306b54d06fa04b7c138ba18c8a81"}, - {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37b9de5a96111fc15418819ab4c4432e4f3c2ede61e660b1e33971eba26ef9ba"}, - {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ef9ea3f137e5711f0dbe5f9263e8c009b7069d8a1acea822bd5e9dae0ae49c8"}, - {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85f3ff71e2e60bd4b4932a043fbbe0f499e263c628390b285cb599154a3b03b1"}, - {file = "greenlet-3.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:95ffcf719966dd7c453f908e208e14cde192e09fde6c7186c8f1896ef778d8cd"}, - {file = "greenlet-3.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:03a088b9de532cbfe2ba2034b2b85e82df37874681e8c470d6fb2f8c04d7e4b7"}, - {file = "greenlet-3.1.1-cp38-cp38-win32.whl", hash = "sha256:8b8b36671f10ba80e159378df9c4f15c14098c4fd73a36b9ad715f057272fbef"}, - {file = "greenlet-3.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:7017b2be767b9d43cc31416aba48aab0d2309ee31b4dbf10a1d38fb7972bdf9d"}, - {file = "greenlet-3.1.1-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:396979749bd95f018296af156201d6211240e7a23090f50a8d5d18c370084dc3"}, - {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca9d0ff5ad43e785350894d97e13633a66e2b50000e8a183a50a88d834752d42"}, - {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f6ff3b14f2df4c41660a7dec01045a045653998784bf8cfcb5a525bdffffbc8f"}, - {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94ebba31df2aa506d7b14866fed00ac141a867e63143fe5bca82a8e503b36437"}, - {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73aaad12ac0ff500f62cebed98d8789198ea0e6f233421059fa68a5aa7220145"}, - {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:63e4844797b975b9af3a3fb8f7866ff08775f5426925e1e0bbcfe7932059a12c"}, - {file = "greenlet-3.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7939aa3ca7d2a1593596e7ac6d59391ff30281ef280d8632fa03d81f7c5f955e"}, - {file = "greenlet-3.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d0028e725ee18175c6e422797c407874da24381ce0690d6b9396c204c7f7276e"}, - {file = "greenlet-3.1.1-cp39-cp39-win32.whl", hash = "sha256:5e06afd14cbaf9e00899fae69b24a32f2196c19de08fcb9f4779dd4f004e5e7c"}, - {file = "greenlet-3.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:3319aa75e0e0639bc15ff54ca327e8dc7a6fe404003496e3c6925cd3142e0e22"}, - {file = "greenlet-3.1.1.tar.gz", hash = "sha256:4ce3ac6cdb6adf7946475d7ef31777c26d94bccc377e070a7986bd2d5c515467"}, -] - -[package.extras] -docs = ["Sphinx", "furo"] -test = ["objgraph", "psutil"] - -[[package]] -name = "h11" -version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = true -python-versions = ">=3.7" -files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, -] - -[[package]] -name = "httpcore" -version = "1.0.6" -description = "A minimal low-level HTTP client." -optional = true -python-versions = ">=3.8" -files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.13,<0.15" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<1.0)"] - -[[package]] -name = "httpx" -version = "0.27.2" -description = "The next generation HTTP client." -optional = true -python-versions = ">=3.8" -files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "imagesize" -version = "1.4.1" -description = "Getting image size from png/jpeg/jpeg2000/gif file" -optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, - {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, -] - -[[package]] -name = "importlib-metadata" -version = "6.11.0" -description = "Read metadata from Python packages" -optional = true -python-versions = ">=3.8" -files = [ - {file = "importlib_metadata-6.11.0-py3-none-any.whl", hash = "sha256:f0afba6205ad8f8947c7d338b5342d5db2afbfd82f9cbef7879a9539cc12eb9b"}, - {file = "importlib_metadata-6.11.0.tar.gz", hash = "sha256:1231cf92d825c9e03cfc4da076a16de6422c863558229ea0b22b675657463443"}, -] - -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isodate" -version = "0.6.1" -description = "An ISO 8601 date/time/duration parser and formatter" -optional = false -python-versions = "*" -files = [ - {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, - {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "jinja2" -version = "3.1.4" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "joblib" -version = "1.4.2" -description = "Lightweight pipelining with Python functions" -optional = true -python-versions = ">=3.8" -files = [ - {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, - {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, -] - -[[package]] -name = "jsonpatch" -version = "1.33" -description = "Apply JSON-Patches (RFC 6902)" -optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" -files = [ - {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, - {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, -] - -[package.dependencies] -jsonpointer = ">=1.9" - -[[package]] -name = "jsonpointer" -version = "3.0.0" -description = "Identify specific nodes in a JSON document (RFC 6901)" -optional = true -python-versions = ">=3.7" -files = [ - {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, - {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, -] - -[[package]] -name = "jsonref" -version = "0.2" -description = "An implementation of JSON Reference for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonref-0.2-py3-none-any.whl", hash = "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f"}, - {file = "jsonref-0.2.tar.gz", hash = "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697"}, -] - -[[package]] -name = "jsonschema" -version = "3.2.0" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, -] - -[package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" - -[package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] - -[[package]] -name = "kiwisolver" -version = "1.4.7" -description = "A fast implementation of the Cassowary constraint solver" -optional = true -python-versions = ">=3.8" -files = [ - {file = "kiwisolver-1.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8a9c83f75223d5e48b0bc9cb1bf2776cf01563e00ade8775ffe13b0b6e1af3a6"}, - {file = "kiwisolver-1.4.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:58370b1ffbd35407444d57057b57da5d6549d2d854fa30249771775c63b5fe17"}, - {file = "kiwisolver-1.4.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aa0abdf853e09aff551db11fce173e2177d00786c688203f52c87ad7fcd91ef9"}, - {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8d53103597a252fb3ab8b5845af04c7a26d5e7ea8122303dd7a021176a87e8b9"}, - {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:88f17c5ffa8e9462fb79f62746428dd57b46eb931698e42e990ad63103f35e6c"}, - {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a9ca9c710d598fd75ee5de59d5bda2684d9db36a9f50b6125eaea3969c2599"}, - {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f4d742cb7af1c28303a51b7a27aaee540e71bb8e24f68c736f6f2ffc82f2bf05"}, - {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e28c7fea2196bf4c2f8d46a0415c77a1c480cc0724722f23d7410ffe9842c407"}, - {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e968b84db54f9d42046cf154e02911e39c0435c9801681e3fc9ce8a3c4130278"}, - {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0c18ec74c0472de033e1bebb2911c3c310eef5649133dd0bedf2a169a1b269e5"}, - {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8f0ea6da6d393d8b2e187e6a5e3fb81f5862010a40c3945e2c6d12ae45cfb2ad"}, - {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f106407dda69ae456dd1227966bf445b157ccc80ba0dff3802bb63f30b74e895"}, - {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84ec80df401cfee1457063732d90022f93951944b5b58975d34ab56bb150dfb3"}, - {file = "kiwisolver-1.4.7-cp310-cp310-win32.whl", hash = "sha256:71bb308552200fb2c195e35ef05de12f0c878c07fc91c270eb3d6e41698c3bcc"}, - {file = "kiwisolver-1.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:44756f9fd339de0fb6ee4f8c1696cfd19b2422e0d70b4cefc1cc7f1f64045a8c"}, - {file = "kiwisolver-1.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:78a42513018c41c2ffd262eb676442315cbfe3c44eed82385c2ed043bc63210a"}, - {file = "kiwisolver-1.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d2b0e12a42fb4e72d509fc994713d099cbb15ebf1103545e8a45f14da2dfca54"}, - {file = "kiwisolver-1.4.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2a8781ac3edc42ea4b90bc23e7d37b665d89423818e26eb6df90698aa2287c95"}, - {file = "kiwisolver-1.4.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:46707a10836894b559e04b0fd143e343945c97fd170d69a2d26d640b4e297935"}, - {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef97b8df011141c9b0f6caf23b29379f87dd13183c978a30a3c546d2c47314cb"}, - {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab58c12a2cd0fc769089e6d38466c46d7f76aced0a1f54c77652446733d2d02"}, - {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:803b8e1459341c1bb56d1c5c010406d5edec8a0713a0945851290a7930679b51"}, - {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9a9e8a507420fe35992ee9ecb302dab68550dedc0da9e2880dd88071c5fb052"}, - {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18077b53dc3bb490e330669a99920c5e6a496889ae8c63b58fbc57c3d7f33a18"}, - {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6af936f79086a89b3680a280c47ea90b4df7047b5bdf3aa5c524bbedddb9e545"}, - {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3abc5b19d24af4b77d1598a585b8a719beb8569a71568b66f4ebe1fb0449460b"}, - {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:933d4de052939d90afbe6e9d5273ae05fb836cc86c15b686edd4b3560cc0ee36"}, - {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:65e720d2ab2b53f1f72fb5da5fb477455905ce2c88aaa671ff0a447c2c80e8e3"}, - {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3bf1ed55088f214ba6427484c59553123fdd9b218a42bbc8c6496d6754b1e523"}, - {file = "kiwisolver-1.4.7-cp311-cp311-win32.whl", hash = "sha256:4c00336b9dd5ad96d0a558fd18a8b6f711b7449acce4c157e7343ba92dd0cf3d"}, - {file = "kiwisolver-1.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:929e294c1ac1e9f615c62a4e4313ca1823ba37326c164ec720a803287c4c499b"}, - {file = "kiwisolver-1.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:e33e8fbd440c917106b237ef1a2f1449dfbb9b6f6e1ce17c94cd6a1e0d438376"}, - {file = "kiwisolver-1.4.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:5360cc32706dab3931f738d3079652d20982511f7c0ac5711483e6eab08efff2"}, - {file = "kiwisolver-1.4.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:942216596dc64ddb25adb215c3c783215b23626f8d84e8eff8d6d45c3f29f75a"}, - {file = "kiwisolver-1.4.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:48b571ecd8bae15702e4f22d3ff6a0f13e54d3d00cd25216d5e7f658242065ee"}, - {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad42ba922c67c5f219097b28fae965e10045ddf145d2928bfac2eb2e17673640"}, - {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:612a10bdae23404a72941a0fc8fa2660c6ea1217c4ce0dbcab8a8f6543ea9e7f"}, - {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e838bba3a3bac0fe06d849d29772eb1afb9745a59710762e4ba3f4cb8424483"}, - {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22f499f6157236c19f4bbbd472fa55b063db77a16cd74d49afe28992dff8c258"}, - {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693902d433cf585133699972b6d7c42a8b9f8f826ebcaf0132ff55200afc599e"}, - {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4e77f2126c3e0b0d055f44513ed349038ac180371ed9b52fe96a32aa071a5107"}, - {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:657a05857bda581c3656bfc3b20e353c232e9193eb167766ad2dc58b56504948"}, - {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4bfa75a048c056a411f9705856abfc872558e33c055d80af6a380e3658766038"}, - {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:34ea1de54beef1c104422d210c47c7d2a4999bdecf42c7b5718fbe59a4cac383"}, - {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:90da3b5f694b85231cf93586dad5e90e2d71b9428f9aad96952c99055582f520"}, - {file = "kiwisolver-1.4.7-cp312-cp312-win32.whl", hash = "sha256:18e0cca3e008e17fe9b164b55735a325140a5a35faad8de92dd80265cd5eb80b"}, - {file = "kiwisolver-1.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:58cb20602b18f86f83a5c87d3ee1c766a79c0d452f8def86d925e6c60fbf7bfb"}, - {file = "kiwisolver-1.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:f5a8b53bdc0b3961f8b6125e198617c40aeed638b387913bf1ce78afb1b0be2a"}, - {file = "kiwisolver-1.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2e6039dcbe79a8e0f044f1c39db1986a1b8071051efba3ee4d74f5b365f5226e"}, - {file = "kiwisolver-1.4.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a1ecf0ac1c518487d9d23b1cd7139a6a65bc460cd101ab01f1be82ecf09794b6"}, - {file = "kiwisolver-1.4.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7ab9ccab2b5bd5702ab0803676a580fffa2aa178c2badc5557a84cc943fcf750"}, - {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f816dd2277f8d63d79f9c8473a79fe54047bc0467754962840782c575522224d"}, - {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf8bcc23ceb5a1b624572a1623b9f79d2c3b337c8c455405ef231933a10da379"}, - {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dea0bf229319828467d7fca8c7c189780aa9ff679c94539eed7532ebe33ed37c"}, - {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c06a4c7cf15ec739ce0e5971b26c93638730090add60e183530d70848ebdd34"}, - {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:913983ad2deb14e66d83c28b632fd35ba2b825031f2fa4ca29675e665dfecbe1"}, - {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5337ec7809bcd0f424c6b705ecf97941c46279cf5ed92311782c7c9c2026f07f"}, - {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c26ed10c4f6fa6ddb329a5120ba3b6db349ca192ae211e882970bfc9d91420b"}, - {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c619b101e6de2222c1fcb0531e1b17bbffbe54294bfba43ea0d411d428618c27"}, - {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:073a36c8273647592ea332e816e75ef8da5c303236ec0167196793eb1e34657a"}, - {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3ce6b2b0231bda412463e152fc18335ba32faf4e8c23a754ad50ffa70e4091ee"}, - {file = "kiwisolver-1.4.7-cp313-cp313-win32.whl", hash = "sha256:f4c9aee212bc89d4e13f58be11a56cc8036cabad119259d12ace14b34476fd07"}, - {file = "kiwisolver-1.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:8a3ec5aa8e38fc4c8af308917ce12c536f1c88452ce554027e55b22cbbfbff76"}, - {file = "kiwisolver-1.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:76c8094ac20ec259471ac53e774623eb62e6e1f56cd8690c67ce6ce4fcb05650"}, - {file = "kiwisolver-1.4.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5d5abf8f8ec1f4e22882273c423e16cae834c36856cac348cfbfa68e01c40f3a"}, - {file = "kiwisolver-1.4.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:aeb3531b196ef6f11776c21674dba836aeea9d5bd1cf630f869e3d90b16cfade"}, - {file = "kiwisolver-1.4.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7d755065e4e866a8086c9bdada157133ff466476a2ad7861828e17b6026e22c"}, - {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08471d4d86cbaec61f86b217dd938a83d85e03785f51121e791a6e6689a3be95"}, - {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bbfcb7165ce3d54a3dfbe731e470f65739c4c1f85bb1018ee912bae139e263b"}, - {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d34eb8494bea691a1a450141ebb5385e4b69d38bb8403b5146ad279f4b30fa3"}, - {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9242795d174daa40105c1d86aba618e8eab7bf96ba8c3ee614da8302a9f95503"}, - {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a0f64a48bb81af7450e641e3fe0b0394d7381e342805479178b3d335d60ca7cf"}, - {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8e045731a5416357638d1700927529e2b8ab304811671f665b225f8bf8d8f933"}, - {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4322872d5772cae7369f8351da1edf255a604ea7087fe295411397d0cfd9655e"}, - {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:e1631290ee9271dffe3062d2634c3ecac02c83890ada077d225e081aca8aab89"}, - {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:edcfc407e4eb17e037bca59be0e85a2031a2ac87e4fed26d3e9df88b4165f92d"}, - {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:4d05d81ecb47d11e7f8932bd8b61b720bf0b41199358f3f5e36d38e28f0532c5"}, - {file = "kiwisolver-1.4.7-cp38-cp38-win32.whl", hash = "sha256:b38ac83d5f04b15e515fd86f312479d950d05ce2368d5413d46c088dda7de90a"}, - {file = "kiwisolver-1.4.7-cp38-cp38-win_amd64.whl", hash = "sha256:d83db7cde68459fc803052a55ace60bea2bae361fc3b7a6d5da07e11954e4b09"}, - {file = "kiwisolver-1.4.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3f9362ecfca44c863569d3d3c033dbe8ba452ff8eed6f6b5806382741a1334bd"}, - {file = "kiwisolver-1.4.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e8df2eb9b2bac43ef8b082e06f750350fbbaf2887534a5be97f6cf07b19d9583"}, - {file = "kiwisolver-1.4.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f32d6edbc638cde7652bd690c3e728b25332acbadd7cad670cc4a02558d9c417"}, - {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e2e6c39bd7b9372b0be21456caab138e8e69cc0fc1190a9dfa92bd45a1e6e904"}, - {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dda56c24d869b1193fcc763f1284b9126550eaf84b88bbc7256e15028f19188a"}, - {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79849239c39b5e1fd906556c474d9b0439ea6792b637511f3fe3a41158d89ca8"}, - {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5e3bc157fed2a4c02ec468de4ecd12a6e22818d4f09cde2c31ee3226ffbefab2"}, - {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3da53da805b71e41053dc670f9a820d1157aae77b6b944e08024d17bcd51ef88"}, - {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8705f17dfeb43139a692298cb6637ee2e59c0194538153e83e9ee0c75c2eddde"}, - {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:82a5c2f4b87c26bb1a0ef3d16b5c4753434633b83d365cc0ddf2770c93829e3c"}, - {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce8be0466f4c0d585cdb6c1e2ed07232221df101a4c6f28821d2aa754ca2d9e2"}, - {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:409afdfe1e2e90e6ee7fc896f3df9a7fec8e793e58bfa0d052c8a82f99c37abb"}, - {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5b9c3f4ee0b9a439d2415012bd1b1cc2df59e4d6a9939f4d669241d30b414327"}, - {file = "kiwisolver-1.4.7-cp39-cp39-win32.whl", hash = "sha256:a79ae34384df2b615eefca647a2873842ac3b596418032bef9a7283675962644"}, - {file = "kiwisolver-1.4.7-cp39-cp39-win_amd64.whl", hash = "sha256:cf0438b42121a66a3a667de17e779330fc0f20b0d97d59d2f2121e182b0505e4"}, - {file = "kiwisolver-1.4.7-cp39-cp39-win_arm64.whl", hash = "sha256:764202cc7e70f767dab49e8df52c7455e8de0df5d858fa801a11aa0d882ccf3f"}, - {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:94252291e3fe68001b1dd747b4c0b3be12582839b95ad4d1b641924d68fd4643"}, - {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5b7dfa3b546da08a9f622bb6becdb14b3e24aaa30adba66749d38f3cc7ea9706"}, - {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd3de6481f4ed8b734da5df134cd5a6a64fe32124fe83dde1e5b5f29fe30b1e6"}, - {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a91b5f9f1205845d488c928e8570dcb62b893372f63b8b6e98b863ebd2368ff2"}, - {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40fa14dbd66b8b8f470d5fc79c089a66185619d31645f9b0773b88b19f7223c4"}, - {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:eb542fe7933aa09d8d8f9d9097ef37532a7df6497819d16efe4359890a2f417a"}, - {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bfa1acfa0c54932d5607e19a2c24646fb4c1ae2694437789129cf099789a3b00"}, - {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:eee3ea935c3d227d49b4eb85660ff631556841f6e567f0f7bda972df6c2c9935"}, - {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f3160309af4396e0ed04db259c3ccbfdc3621b5559b5453075e5de555e1f3a1b"}, - {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a17f6a29cf8935e587cc8a4dbfc8368c55edc645283db0ce9801016f83526c2d"}, - {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10849fb2c1ecbfae45a693c070e0320a91b35dd4bcf58172c023b994283a124d"}, - {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:ac542bf38a8a4be2dc6b15248d36315ccc65f0743f7b1a76688ffb6b5129a5c2"}, - {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8b01aac285f91ca889c800042c35ad3b239e704b150cfd3382adfc9dcc780e39"}, - {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:48be928f59a1f5c8207154f935334d374e79f2b5d212826307d072595ad76a2e"}, - {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f37cfe618a117e50d8c240555331160d73d0411422b59b5ee217843d7b693608"}, - {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:599b5c873c63a1f6ed7eead644a8a380cfbdf5db91dcb6f85707aaab213b1674"}, - {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:801fa7802e5cfabe3ab0c81a34c323a319b097dfb5004be950482d882f3d7225"}, - {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0c6c43471bc764fad4bc99c5c2d6d16a676b1abf844ca7c8702bdae92df01ee0"}, - {file = "kiwisolver-1.4.7.tar.gz", hash = "sha256:9893ff81bd7107f7b685d3017cc6583daadb4fc26e4a888350df530e41980a60"}, -] - -[[package]] -name = "langchain" -version = "0.1.16" -description = "Building applications with LLMs through composability" -optional = true -python-versions = "<4.0,>=3.8.1" -files = [ - {file = "langchain-0.1.16-py3-none-any.whl", hash = "sha256:bc074cc5e51fad79b9ead1572fc3161918d0f614a6c8f0460543d505ad249ac7"}, - {file = "langchain-0.1.16.tar.gz", hash = "sha256:b6bce78f8c071baa898884accfff15c3d81da2f0dd86c20e2f4c80b41463f49f"}, -] - -[package.dependencies] -aiohttp = ">=3.8.3,<4.0.0" -async-timeout = {version = ">=4.0.0,<5.0.0", markers = "python_version < \"3.11\""} -dataclasses-json = ">=0.5.7,<0.7" -jsonpatch = ">=1.33,<2.0" -langchain-community = ">=0.0.32,<0.1" -langchain-core = ">=0.1.42,<0.2.0" -langchain-text-splitters = ">=0.0.1,<0.1" -langsmith = ">=0.1.17,<0.2.0" -numpy = ">=1,<2" -pydantic = ">=1,<3" -PyYAML = ">=5.3" -requests = ">=2,<3" -SQLAlchemy = ">=1.4,<3" -tenacity = ">=8.1.0,<9.0.0" - -[package.extras] -azure = ["azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-textanalytics (>=5.3.0,<6.0.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-core (>=1.26.4,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "azure-search-documents (==11.4.0b8)", "openai (<2)"] -clarifai = ["clarifai (>=9.1.0)"] -cli = ["typer (>=0.9.0,<0.10.0)"] -cohere = ["cohere (>=4,<6)"] -docarray = ["docarray[hnswlib] (>=0.32.0,<0.33.0)"] -embeddings = ["sentence-transformers (>=2,<3)"] -extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "cohere (>=4,<6)", "couchbase (>=4.1.9,<5.0.0)", "dashvector (>=1.0.1,<2.0.0)", "databricks-vectorsearch (>=0.21,<0.22)", "datasets (>=2.15.0,<3.0.0)", "dgml-utils (>=0.3.0,<0.4.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.9.0,<0.10.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "hologres-vector (>=0.0.6,<0.0.7)", "html2text (>=2020.1.16,<2021.0.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "langchain-openai (>=0.0.2,<0.1)", "lxml (>=4.9.3,<6.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "msal (>=1.25.0,<2.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "praw (>=7.7.1,<8.0.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "rdflib (==7.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)"] -javascript = ["esprima (>=4.0.1,<5.0.0)"] -llms = ["clarifai (>=9.1.0)", "cohere (>=4,<6)", "huggingface_hub (>=0,<1)", "manifest-ml (>=0.0.1,<0.0.2)", "nlpcloud (>=1,<2)", "openai (<2)", "openlm (>=0.0.5,<0.0.6)", "torch (>=1,<3)", "transformers (>=4,<5)"] -openai = ["openai (<2)", "tiktoken (>=0.3.2,<0.6.0)"] -qdrant = ["qdrant-client (>=1.3.1,<2.0.0)"] -text-helpers = ["chardet (>=5.1.0,<6.0.0)"] - -[[package]] -name = "langchain-community" -version = "0.0.32" -description = "Community contributed LangChain integrations." -optional = true -python-versions = "<4.0,>=3.8.1" -files = [ - {file = "langchain_community-0.0.32-py3-none-any.whl", hash = "sha256:406977009999952d0705de3806de2b4867e9bb8eda8ca154a59c7a8ed58da38d"}, - {file = "langchain_community-0.0.32.tar.gz", hash = "sha256:1510217d646c8380f54e9850351f6d2a0b0dd73c501b666c6f4b40baa8160b29"}, -] - -[package.dependencies] -aiohttp = ">=3.8.3,<4.0.0" -dataclasses-json = ">=0.5.7,<0.7" -langchain-core = ">=0.1.41,<0.2.0" -langsmith = ">=0.1.0,<0.2.0" -numpy = ">=1,<2" -PyYAML = ">=5.3" -requests = ">=2,<3" -SQLAlchemy = ">=1.4,<3" -tenacity = ">=8.1.0,<9.0.0" - -[package.extras] -cli = ["typer (>=0.9.0,<0.10.0)"] -extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "azure-ai-documentintelligence (>=1.0.0b1,<2.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "cloudpickle (>=2.0.0)", "cohere (>=4,<5)", "databricks-vectorsearch (>=0.21,<0.22)", "datasets (>=2.15.0,<3.0.0)", "dgml-utils (>=0.3.0,<0.4.0)", "elasticsearch (>=8.12.0,<9.0.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.9.0,<0.10.0)", "friendli-client (>=1.2.4,<2.0.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "gradientai (>=1.4.0,<2.0.0)", "hdbcli (>=2.19.21,<3.0.0)", "hologres-vector (>=0.0.6,<0.0.7)", "html2text (>=2020.1.16,<2021.0.0)", "httpx (>=0.24.1,<0.25.0)", "httpx-sse (>=0.4.0,<0.5.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "lxml (>=4.9.3,<6.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "msal (>=1.25.0,<2.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "nvidia-riva-client (>=2.14.0,<3.0.0)", "oci (>=2.119.1,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "oracle-ads (>=2.9.1,<3.0.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "praw (>=7.7.1,<8.0.0)", "premai (>=0.3.25,<0.4.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pyjwt (>=2.8.0,<3.0.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "rdflib (==7.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "tidb-vector (>=0.0.3,<1.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "tree-sitter (>=0.20.2,<0.21.0)", "tree-sitter-languages (>=1.8.0,<2.0.0)", "upstash-redis (>=0.15.0,<0.16.0)", "vdms (>=0.0.20,<0.0.21)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)"] - -[[package]] -name = "langchain-core" -version = "0.1.42" -description = "Building applications with LLMs through composability" -optional = true -python-versions = "<4.0,>=3.8.1" -files = [ - {file = "langchain_core-0.1.42-py3-none-any.whl", hash = "sha256:c5653ffa08a44f740295c157a24c0def4a753333f6a2c41f76bf431cd00be8b5"}, - {file = "langchain_core-0.1.42.tar.gz", hash = "sha256:40751bf60ea5d8e2b2efe65290db434717ee3834870c002e40e2811f09d814e6"}, -] - -[package.dependencies] -jsonpatch = ">=1.33,<2.0" -langsmith = ">=0.1.0,<0.2.0" -packaging = ">=23.2,<24.0" -pydantic = ">=1,<3" -PyYAML = ">=5.3" -tenacity = ">=8.1.0,<9.0.0" - -[package.extras] -extended-testing = ["jinja2 (>=3,<4)"] - -[[package]] -name = "langchain-text-splitters" -version = "0.0.2" -description = "LangChain text splitting utilities" -optional = true -python-versions = "<4.0,>=3.8.1" -files = [ - {file = "langchain_text_splitters-0.0.2-py3-none-any.whl", hash = "sha256:13887f32705862c1e1454213cb7834a63aae57c26fcd80346703a1d09c46168d"}, - {file = "langchain_text_splitters-0.0.2.tar.gz", hash = "sha256:ac8927dc0ba08eba702f6961c9ed7df7cead8de19a9f7101ab2b5ea34201b3c1"}, -] - -[package.dependencies] -langchain-core = ">=0.1.28,<0.3" - -[package.extras] -extended-testing = ["beautifulsoup4 (>=4.12.3,<5.0.0)", "lxml (>=4.9.3,<6.0)"] - -[[package]] -name = "langdetect" -version = "1.0.9" -description = "Language detection library ported from Google's language-detection." -optional = true -python-versions = "*" -files = [ - {file = "langdetect-1.0.9-py2-none-any.whl", hash = "sha256:7cbc0746252f19e76f77c0b1690aadf01963be835ef0cd4b56dddf2a8f1dfc2a"}, - {file = "langdetect-1.0.9.tar.gz", hash = "sha256:cbc1fef89f8d062739774bd51eda3da3274006b3661d199c2655f6b3f6d605a0"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "langsmith" -version = "0.1.136" -description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." -optional = true -python-versions = "<4.0,>=3.8.1" -files = [ - {file = "langsmith-0.1.136-py3-none-any.whl", hash = "sha256:cad2215eb7a754ee259878e19c558f4f8d3795aa1b699f087d4500e640f80d0a"}, - {file = "langsmith-0.1.136.tar.gz", hash = "sha256:5c0de01a313db70dd9a85845c0f416a69b5b653b3e98ba413d7d41e8851315b1"}, -] - -[package.dependencies] -httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" -pydantic = [ - {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""}, - {version = ">=2.7.4,<3.0.0", markers = "python_full_version >= \"3.12.4\""}, -] -requests = ">=2,<3" -requests-toolbelt = ">=1.0.0,<2.0.0" - -[[package]] -name = "linkify-it-py" -version = "2.0.3" -description = "Links recognition library with FULL unicode support." -optional = false -python-versions = ">=3.7" -files = [ - {file = "linkify-it-py-2.0.3.tar.gz", hash = "sha256:68cda27e162e9215c17d786649d1da0021a451bdc436ef9e0fa0ba5234b9b048"}, - {file = "linkify_it_py-2.0.3-py3-none-any.whl", hash = "sha256:6bcbc417b0ac14323382aef5c5192c0075bf8a9d6b41820a2b66371eac6b6d79"}, -] - -[package.dependencies] -uc-micro-py = "*" - -[package.extras] -benchmark = ["pytest", "pytest-benchmark"] -dev = ["black", "flake8", "isort", "pre-commit", "pyproject-flake8"] -doc = ["myst-parser", "sphinx", "sphinx-book-theme"] -test = ["coverage", "pytest", "pytest-cov"] - -[[package]] -name = "lxml" -version = "5.3.0" -description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." -optional = true -python-versions = ">=3.6" -files = [ - {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dd36439be765e2dde7660212b5275641edbc813e7b24668831a5c8ac91180656"}, - {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ae5fe5c4b525aa82b8076c1a59d642c17b6e8739ecf852522c6321852178119d"}, - {file = "lxml-5.3.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:501d0d7e26b4d261fca8132854d845e4988097611ba2531408ec91cf3fd9d20a"}, - {file = "lxml-5.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb66442c2546446944437df74379e9cf9e9db353e61301d1a0e26482f43f0dd8"}, - {file = "lxml-5.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e41506fec7a7f9405b14aa2d5c8abbb4dbbd09d88f9496958b6d00cb4d45330"}, - {file = "lxml-5.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f7d4a670107d75dfe5ad080bed6c341d18c4442f9378c9f58e5851e86eb79965"}, - {file = "lxml-5.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41ce1f1e2c7755abfc7e759dc34d7d05fd221723ff822947132dc934d122fe22"}, - {file = "lxml-5.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:44264ecae91b30e5633013fb66f6ddd05c006d3e0e884f75ce0b4755b3e3847b"}, - {file = "lxml-5.3.0-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:3c174dc350d3ec52deb77f2faf05c439331d6ed5e702fc247ccb4e6b62d884b7"}, - {file = "lxml-5.3.0-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:2dfab5fa6a28a0b60a20638dc48e6343c02ea9933e3279ccb132f555a62323d8"}, - {file = "lxml-5.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b1c8c20847b9f34e98080da785bb2336ea982e7f913eed5809e5a3c872900f32"}, - {file = "lxml-5.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2c86bf781b12ba417f64f3422cfc302523ac9cd1d8ae8c0f92a1c66e56ef2e86"}, - {file = "lxml-5.3.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:c162b216070f280fa7da844531169be0baf9ccb17263cf5a8bf876fcd3117fa5"}, - {file = "lxml-5.3.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:36aef61a1678cb778097b4a6eeae96a69875d51d1e8f4d4b491ab3cfb54b5a03"}, - {file = "lxml-5.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f65e5120863c2b266dbcc927b306c5b78e502c71edf3295dfcb9501ec96e5fc7"}, - {file = "lxml-5.3.0-cp310-cp310-win32.whl", hash = "sha256:ef0c1fe22171dd7c7c27147f2e9c3e86f8bdf473fed75f16b0c2e84a5030ce80"}, - {file = "lxml-5.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:052d99051e77a4f3e8482c65014cf6372e61b0a6f4fe9edb98503bb5364cfee3"}, - {file = "lxml-5.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:74bcb423462233bc5d6066e4e98b0264e7c1bed7541fff2f4e34fe6b21563c8b"}, - {file = "lxml-5.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a3d819eb6f9b8677f57f9664265d0a10dd6551d227afb4af2b9cd7bdc2ccbf18"}, - {file = "lxml-5.3.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b8f5db71b28b8c404956ddf79575ea77aa8b1538e8b2ef9ec877945b3f46442"}, - {file = "lxml-5.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3406b63232fc7e9b8783ab0b765d7c59e7c59ff96759d8ef9632fca27c7ee4"}, - {file = "lxml-5.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ecdd78ab768f844c7a1d4a03595038c166b609f6395e25af9b0f3f26ae1230f"}, - {file = "lxml-5.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:168f2dfcfdedf611eb285efac1516c8454c8c99caf271dccda8943576b67552e"}, - {file = "lxml-5.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa617107a410245b8660028a7483b68e7914304a6d4882b5ff3d2d3eb5948d8c"}, - {file = "lxml-5.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:69959bd3167b993e6e710b99051265654133a98f20cec1d9b493b931942e9c16"}, - {file = "lxml-5.3.0-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:bd96517ef76c8654446fc3db9242d019a1bb5fe8b751ba414765d59f99210b79"}, - {file = "lxml-5.3.0-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:ab6dd83b970dc97c2d10bc71aa925b84788c7c05de30241b9e96f9b6d9ea3080"}, - {file = "lxml-5.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:eec1bb8cdbba2925bedc887bc0609a80e599c75b12d87ae42ac23fd199445654"}, - {file = "lxml-5.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a7095eeec6f89111d03dabfe5883a1fd54da319c94e0fb104ee8f23616b572d"}, - {file = "lxml-5.3.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6f651ebd0b21ec65dfca93aa629610a0dbc13dbc13554f19b0113da2e61a4763"}, - {file = "lxml-5.3.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f422a209d2455c56849442ae42f25dbaaba1c6c3f501d58761c619c7836642ec"}, - {file = "lxml-5.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:62f7fdb0d1ed2065451f086519865b4c90aa19aed51081979ecd05a21eb4d1be"}, - {file = "lxml-5.3.0-cp311-cp311-win32.whl", hash = "sha256:c6379f35350b655fd817cd0d6cbeef7f265f3ae5fedb1caae2eb442bbeae9ab9"}, - {file = "lxml-5.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:9c52100e2c2dbb0649b90467935c4b0de5528833c76a35ea1a2691ec9f1ee7a1"}, - {file = "lxml-5.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e99f5507401436fdcc85036a2e7dc2e28d962550afe1cbfc07c40e454256a859"}, - {file = "lxml-5.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:384aacddf2e5813a36495233b64cb96b1949da72bef933918ba5c84e06af8f0e"}, - {file = "lxml-5.3.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:874a216bf6afaf97c263b56371434e47e2c652d215788396f60477540298218f"}, - {file = "lxml-5.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65ab5685d56914b9a2a34d67dd5488b83213d680b0c5d10b47f81da5a16b0b0e"}, - {file = "lxml-5.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aac0bbd3e8dd2d9c45ceb82249e8bdd3ac99131a32b4d35c8af3cc9db1657179"}, - {file = "lxml-5.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b369d3db3c22ed14c75ccd5af429086f166a19627e84a8fdade3f8f31426e52a"}, - {file = "lxml-5.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c24037349665434f375645fa9d1f5304800cec574d0310f618490c871fd902b3"}, - {file = "lxml-5.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:62d172f358f33a26d6b41b28c170c63886742f5b6772a42b59b4f0fa10526cb1"}, - {file = "lxml-5.3.0-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:c1f794c02903c2824fccce5b20c339a1a14b114e83b306ff11b597c5f71a1c8d"}, - {file = "lxml-5.3.0-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:5d6a6972b93c426ace71e0be9a6f4b2cfae9b1baed2eed2006076a746692288c"}, - {file = "lxml-5.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:3879cc6ce938ff4eb4900d901ed63555c778731a96365e53fadb36437a131a99"}, - {file = "lxml-5.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:74068c601baff6ff021c70f0935b0c7bc528baa8ea210c202e03757c68c5a4ff"}, - {file = "lxml-5.3.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ecd4ad8453ac17bc7ba3868371bffb46f628161ad0eefbd0a855d2c8c32dd81a"}, - {file = "lxml-5.3.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7e2f58095acc211eb9d8b5771bf04df9ff37d6b87618d1cbf85f92399c98dae8"}, - {file = "lxml-5.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e63601ad5cd8f860aa99d109889b5ac34de571c7ee902d6812d5d9ddcc77fa7d"}, - {file = "lxml-5.3.0-cp312-cp312-win32.whl", hash = "sha256:17e8d968d04a37c50ad9c456a286b525d78c4a1c15dd53aa46c1d8e06bf6fa30"}, - {file = "lxml-5.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:c1a69e58a6bb2de65902051d57fde951febad631a20a64572677a1052690482f"}, - {file = "lxml-5.3.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c72e9563347c7395910de6a3100a4840a75a6f60e05af5e58566868d5eb2d6a"}, - {file = "lxml-5.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e92ce66cd919d18d14b3856906a61d3f6b6a8500e0794142338da644260595cd"}, - {file = "lxml-5.3.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d04f064bebdfef9240478f7a779e8c5dc32b8b7b0b2fc6a62e39b928d428e51"}, - {file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c2fb570d7823c2bbaf8b419ba6e5662137f8166e364a8b2b91051a1fb40ab8b"}, - {file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c120f43553ec759f8de1fee2f4794452b0946773299d44c36bfe18e83caf002"}, - {file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:562e7494778a69086f0312ec9689f6b6ac1c6b65670ed7d0267e49f57ffa08c4"}, - {file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:423b121f7e6fa514ba0c7918e56955a1d4470ed35faa03e3d9f0e3baa4c7e492"}, - {file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c00f323cc00576df6165cc9d21a4c21285fa6b9989c5c39830c3903dc4303ef3"}, - {file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:1fdc9fae8dd4c763e8a31e7630afef517eab9f5d5d31a278df087f307bf601f4"}, - {file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:658f2aa69d31e09699705949b5fc4719cbecbd4a97f9656a232e7d6c7be1a367"}, - {file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1473427aff3d66a3fa2199004c3e601e6c4500ab86696edffdbc84954c72d832"}, - {file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a87de7dd873bf9a792bf1e58b1c3887b9264036629a5bf2d2e6579fe8e73edff"}, - {file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0d7b36afa46c97875303a94e8f3ad932bf78bace9e18e603f2085b652422edcd"}, - {file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:cf120cce539453ae086eacc0130a324e7026113510efa83ab42ef3fcfccac7fb"}, - {file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:df5c7333167b9674aa8ae1d4008fa4bc17a313cc490b2cca27838bbdcc6bb15b"}, - {file = "lxml-5.3.0-cp313-cp313-win32.whl", hash = "sha256:c802e1c2ed9f0c06a65bc4ed0189d000ada8049312cfeab6ca635e39c9608957"}, - {file = "lxml-5.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:406246b96d552e0503e17a1006fd27edac678b3fcc9f1be71a2f94b4ff61528d"}, - {file = "lxml-5.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8f0de2d390af441fe8b2c12626d103540b5d850d585b18fcada58d972b74a74e"}, - {file = "lxml-5.3.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1afe0a8c353746e610bd9031a630a95bcfb1a720684c3f2b36c4710a0a96528f"}, - {file = "lxml-5.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56b9861a71575f5795bde89256e7467ece3d339c9b43141dbdd54544566b3b94"}, - {file = "lxml-5.3.0-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:9fb81d2824dff4f2e297a276297e9031f46d2682cafc484f49de182aa5e5df99"}, - {file = "lxml-5.3.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2c226a06ecb8cdef28845ae976da407917542c5e6e75dcac7cc33eb04aaeb237"}, - {file = "lxml-5.3.0-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:7d3d1ca42870cdb6d0d29939630dbe48fa511c203724820fc0fd507b2fb46577"}, - {file = "lxml-5.3.0-cp36-cp36m-win32.whl", hash = "sha256:094cb601ba9f55296774c2d57ad68730daa0b13dc260e1f941b4d13678239e70"}, - {file = "lxml-5.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:eafa2c8658f4e560b098fe9fc54539f86528651f61849b22111a9b107d18910c"}, - {file = "lxml-5.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cb83f8a875b3d9b458cada4f880fa498646874ba4011dc974e071a0a84a1b033"}, - {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25f1b69d41656b05885aa185f5fdf822cb01a586d1b32739633679699f220391"}, - {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23e0553b8055600b3bf4a00b255ec5c92e1e4aebf8c2c09334f8368e8bd174d6"}, - {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ada35dd21dc6c039259596b358caab6b13f4db4d4a7f8665764d616daf9cc1d"}, - {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:81b4e48da4c69313192d8c8d4311e5d818b8be1afe68ee20f6385d0e96fc9512"}, - {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:2bc9fd5ca4729af796f9f59cd8ff160fe06a474da40aca03fcc79655ddee1a8b"}, - {file = "lxml-5.3.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:07da23d7ee08577760f0a71d67a861019103e4812c87e2fab26b039054594cc5"}, - {file = "lxml-5.3.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:ea2e2f6f801696ad7de8aec061044d6c8c0dd4037608c7cab38a9a4d316bfb11"}, - {file = "lxml-5.3.0-cp37-cp37m-win32.whl", hash = "sha256:5c54afdcbb0182d06836cc3d1be921e540be3ebdf8b8a51ee3ef987537455f84"}, - {file = "lxml-5.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:f2901429da1e645ce548bf9171784c0f74f0718c3f6150ce166be39e4dd66c3e"}, - {file = "lxml-5.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c56a1d43b2f9ee4786e4658c7903f05da35b923fb53c11025712562d5cc02753"}, - {file = "lxml-5.3.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ee8c39582d2652dcd516d1b879451500f8db3fe3607ce45d7c5957ab2596040"}, - {file = "lxml-5.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdf3a3059611f7585a78ee10399a15566356116a4288380921a4b598d807a22"}, - {file = "lxml-5.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:146173654d79eb1fc97498b4280c1d3e1e5d58c398fa530905c9ea50ea849b22"}, - {file = "lxml-5.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:0a7056921edbdd7560746f4221dca89bb7a3fe457d3d74267995253f46343f15"}, - {file = "lxml-5.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:9e4b47ac0f5e749cfc618efdf4726269441014ae1d5583e047b452a32e221920"}, - {file = "lxml-5.3.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f914c03e6a31deb632e2daa881fe198461f4d06e57ac3d0e05bbcab8eae01945"}, - {file = "lxml-5.3.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:213261f168c5e1d9b7535a67e68b1f59f92398dd17a56d934550837143f79c42"}, - {file = "lxml-5.3.0-cp38-cp38-win32.whl", hash = "sha256:218c1b2e17a710e363855594230f44060e2025b05c80d1f0661258142b2add2e"}, - {file = "lxml-5.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:315f9542011b2c4e1d280e4a20ddcca1761993dda3afc7a73b01235f8641e903"}, - {file = "lxml-5.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1ffc23010330c2ab67fac02781df60998ca8fe759e8efde6f8b756a20599c5de"}, - {file = "lxml-5.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2b3778cb38212f52fac9fe913017deea2fdf4eb1a4f8e4cfc6b009a13a6d3fcc"}, - {file = "lxml-5.3.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b0c7a688944891086ba192e21c5229dea54382f4836a209ff8d0a660fac06be"}, - {file = "lxml-5.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:747a3d3e98e24597981ca0be0fd922aebd471fa99d0043a3842d00cdcad7ad6a"}, - {file = "lxml-5.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86a6b24b19eaebc448dc56b87c4865527855145d851f9fc3891673ff97950540"}, - {file = "lxml-5.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b11a5d918a6216e521c715b02749240fb07ae5a1fefd4b7bf12f833bc8b4fe70"}, - {file = "lxml-5.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68b87753c784d6acb8a25b05cb526c3406913c9d988d51f80adecc2b0775d6aa"}, - {file = "lxml-5.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:109fa6fede314cc50eed29e6e56c540075e63d922455346f11e4d7a036d2b8cf"}, - {file = "lxml-5.3.0-cp39-cp39-manylinux_2_28_ppc64le.whl", hash = "sha256:02ced472497b8362c8e902ade23e3300479f4f43e45f4105c85ef43b8db85229"}, - {file = "lxml-5.3.0-cp39-cp39-manylinux_2_28_s390x.whl", hash = "sha256:6b038cc86b285e4f9fea2ba5ee76e89f21ed1ea898e287dc277a25884f3a7dfe"}, - {file = "lxml-5.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:7437237c6a66b7ca341e868cda48be24b8701862757426852c9b3186de1da8a2"}, - {file = "lxml-5.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7f41026c1d64043a36fda21d64c5026762d53a77043e73e94b71f0521939cc71"}, - {file = "lxml-5.3.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:482c2f67761868f0108b1743098640fbb2a28a8e15bf3f47ada9fa59d9fe08c3"}, - {file = "lxml-5.3.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:1483fd3358963cc5c1c9b122c80606a3a79ee0875bcac0204149fa09d6ff2727"}, - {file = "lxml-5.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dec2d1130a9cda5b904696cec33b2cfb451304ba9081eeda7f90f724097300a"}, - {file = "lxml-5.3.0-cp39-cp39-win32.whl", hash = "sha256:a0eabd0a81625049c5df745209dc7fcef6e2aea7793e5f003ba363610aa0a3ff"}, - {file = "lxml-5.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:89e043f1d9d341c52bf2af6d02e6adde62e0a46e6755d5eb60dc6e4f0b8aeca2"}, - {file = "lxml-5.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7b1cd427cb0d5f7393c31b7496419da594fe600e6fdc4b105a54f82405e6626c"}, - {file = "lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51806cfe0279e06ed8500ce19479d757db42a30fd509940b1701be9c86a5ff9a"}, - {file = "lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee70d08fd60c9565ba8190f41a46a54096afa0eeb8f76bd66f2c25d3b1b83005"}, - {file = "lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:8dc2c0395bea8254d8daebc76dcf8eb3a95ec2a46fa6fae5eaccee366bfe02ce"}, - {file = "lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6ba0d3dcac281aad8a0e5b14c7ed6f9fa89c8612b47939fc94f80b16e2e9bc83"}, - {file = "lxml-5.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:6e91cf736959057f7aac7adfc83481e03615a8e8dd5758aa1d95ea69e8931dba"}, - {file = "lxml-5.3.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:94d6c3782907b5e40e21cadf94b13b0842ac421192f26b84c45f13f3c9d5dc27"}, - {file = "lxml-5.3.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c300306673aa0f3ed5ed9372b21867690a17dba38c68c44b287437c362ce486b"}, - {file = "lxml-5.3.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d9b952e07aed35fe2e1a7ad26e929595412db48535921c5013edc8aa4a35ce"}, - {file = "lxml-5.3.0-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:01220dca0d066d1349bd6a1726856a78f7929f3878f7e2ee83c296c69495309e"}, - {file = "lxml-5.3.0-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:2d9b8d9177afaef80c53c0a9e30fa252ff3036fb1c6494d427c066a4ce6a282f"}, - {file = "lxml-5.3.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:20094fc3f21ea0a8669dc4c61ed7fa8263bd37d97d93b90f28fc613371e7a875"}, - {file = "lxml-5.3.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ace2c2326a319a0bb8a8b0e5b570c764962e95818de9f259ce814ee666603f19"}, - {file = "lxml-5.3.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92e67a0be1639c251d21e35fe74df6bcc40cba445c2cda7c4a967656733249e2"}, - {file = "lxml-5.3.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd5350b55f9fecddc51385463a4f67a5da829bc741e38cf689f38ec9023f54ab"}, - {file = "lxml-5.3.0-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c1fefd7e3d00921c44dc9ca80a775af49698bbfd92ea84498e56acffd4c5469"}, - {file = "lxml-5.3.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:71a8dd38fbd2f2319136d4ae855a7078c69c9a38ae06e0c17c73fd70fc6caad8"}, - {file = "lxml-5.3.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:97acf1e1fd66ab53dacd2c35b319d7e548380c2e9e8c54525c6e76d21b1ae3b1"}, - {file = "lxml-5.3.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:68934b242c51eb02907c5b81d138cb977b2129a0a75a8f8b60b01cb8586c7b21"}, - {file = "lxml-5.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b710bc2b8292966b23a6a0121f7a6c51d45d2347edcc75f016ac123b8054d3f2"}, - {file = "lxml-5.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18feb4b93302091b1541221196a2155aa296c363fd233814fa11e181adebc52f"}, - {file = "lxml-5.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:3eb44520c4724c2e1a57c0af33a379eee41792595023f367ba3952a2d96c2aab"}, - {file = "lxml-5.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:609251a0ca4770e5a8768ff902aa02bf636339c5a93f9349b48eb1f606f7f3e9"}, - {file = "lxml-5.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:516f491c834eb320d6c843156440fe7fc0d50b33e44387fcec5b02f0bc118a4c"}, - {file = "lxml-5.3.0.tar.gz", hash = "sha256:4e109ca30d1edec1ac60cdbe341905dc3b8f55b16855e03a54aaf59e51ec8c6f"}, -] - -[package.extras] -cssselect = ["cssselect (>=0.7)"] -html-clean = ["lxml-html-clean"] -html5 = ["html5lib"] -htmlsoup = ["BeautifulSoup4"] -source = ["Cython (>=3.0.11)"] - -[[package]] -name = "markdown" -version = "3.7" -description = "Python implementation of John Gruber's Markdown." -optional = true -python-versions = ">=3.8" -files = [ - {file = "Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803"}, - {file = "markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2"}, -] - -[package.extras] -docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] -testing = ["coverage", "pyyaml"] - -[[package]] -name = "markdown-it-py" -version = "3.0.0" -description = "Python port of markdown-it. Markdown parsing, done right!" -optional = false -python-versions = ">=3.8" -files = [ - {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, - {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, -] - -[package.dependencies] -linkify-it-py = {version = ">=1,<3", optional = true, markers = "extra == \"linkify\""} -mdit-py-plugins = {version = "*", optional = true, markers = "extra == \"plugins\""} -mdurl = ">=0.1,<1.0" - -[package.extras] -benchmarking = ["psutil", "pytest", "pytest-benchmark"] -code-style = ["pre-commit (>=3.0,<4.0)"] -compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] -linkify = ["linkify-it-py (>=1,<3)"] -plugins = ["mdit-py-plugins"] -profiling = ["gprof2dot"] -rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - -[[package]] -name = "markupsafe" -version = "3.0.2" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -files = [ - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, - {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, -] - -[[package]] -name = "marshmallow" -version = "3.23.0" -description = "A lightweight library for converting complex datatypes to and from native Python datatypes." -optional = true -python-versions = ">=3.9" -files = [ - {file = "marshmallow-3.23.0-py3-none-any.whl", hash = "sha256:82f20a2397834fe6d9611b241f2f7e7b680ed89c49f84728a1ad937be6b4bdf4"}, - {file = "marshmallow-3.23.0.tar.gz", hash = "sha256:98d8827a9f10c03d44ead298d2e99c6aea8197df18ccfad360dae7f89a50da2e"}, -] - -[package.dependencies] -packaging = ">=17.0" - -[package.extras] -dev = ["marshmallow[tests]", "pre-commit (>=3.5,<5.0)", "tox"] -docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.13)", "sphinx (==8.1.3)", "sphinx-issues (==5.0.0)", "sphinx-version-warning (==1.1.2)"] -tests = ["pytest", "simplejson"] - -[[package]] -name = "matplotlib" -version = "3.9.2" -description = "Python plotting package" -optional = true -python-versions = ">=3.9" -files = [ - {file = "matplotlib-3.9.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9d78bbc0cbc891ad55b4f39a48c22182e9bdaea7fc0e5dbd364f49f729ca1bbb"}, - {file = "matplotlib-3.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c375cc72229614632c87355366bdf2570c2dac01ac66b8ad048d2dabadf2d0d4"}, - {file = "matplotlib-3.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d94ff717eb2bd0b58fe66380bd8b14ac35f48a98e7c6765117fe67fb7684e64"}, - {file = "matplotlib-3.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab68d50c06938ef28681073327795c5db99bb4666214d2d5f880ed11aeaded66"}, - {file = "matplotlib-3.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:65aacf95b62272d568044531e41de26285d54aec8cb859031f511f84bd8b495a"}, - {file = "matplotlib-3.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:3fd595f34aa8a55b7fc8bf9ebea8aa665a84c82d275190a61118d33fbc82ccae"}, - {file = "matplotlib-3.9.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d8dd059447824eec055e829258ab092b56bb0579fc3164fa09c64f3acd478772"}, - {file = "matplotlib-3.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c797dac8bb9c7a3fd3382b16fe8f215b4cf0f22adccea36f1545a6d7be310b41"}, - {file = "matplotlib-3.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d719465db13267bcef19ea8954a971db03b9f48b4647e3860e4bc8e6ed86610f"}, - {file = "matplotlib-3.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8912ef7c2362f7193b5819d17dae8629b34a95c58603d781329712ada83f9447"}, - {file = "matplotlib-3.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7741f26a58a240f43bee74965c4882b6c93df3e7eb3de160126d8c8f53a6ae6e"}, - {file = "matplotlib-3.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:ae82a14dab96fbfad7965403c643cafe6515e386de723e498cf3eeb1e0b70cc7"}, - {file = "matplotlib-3.9.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ac43031375a65c3196bee99f6001e7fa5bdfb00ddf43379d3c0609bdca042df9"}, - {file = "matplotlib-3.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be0fc24a5e4531ae4d8e858a1a548c1fe33b176bb13eff7f9d0d38ce5112a27d"}, - {file = "matplotlib-3.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf81de2926c2db243c9b2cbc3917619a0fc85796c6ba4e58f541df814bbf83c7"}, - {file = "matplotlib-3.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ee45bc4245533111ced13f1f2cace1e7f89d1c793390392a80c139d6cf0e6c"}, - {file = "matplotlib-3.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:306c8dfc73239f0e72ac50e5a9cf19cc4e8e331dd0c54f5e69ca8758550f1e1e"}, - {file = "matplotlib-3.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:5413401594cfaff0052f9d8b1aafc6d305b4bd7c4331dccd18f561ff7e1d3bd3"}, - {file = "matplotlib-3.9.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:18128cc08f0d3cfff10b76baa2f296fc28c4607368a8402de61bb3f2eb33c7d9"}, - {file = "matplotlib-3.9.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4876d7d40219e8ae8bb70f9263bcbe5714415acfdf781086601211335e24f8aa"}, - {file = "matplotlib-3.9.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d9f07a80deab4bb0b82858a9e9ad53d1382fd122be8cde11080f4e7dfedb38b"}, - {file = "matplotlib-3.9.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7c0410f181a531ec4e93bbc27692f2c71a15c2da16766f5ba9761e7ae518413"}, - {file = "matplotlib-3.9.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:909645cce2dc28b735674ce0931a4ac94e12f5b13f6bb0b5a5e65e7cea2c192b"}, - {file = "matplotlib-3.9.2-cp313-cp313-win_amd64.whl", hash = "sha256:f32c7410c7f246838a77d6d1eff0c0f87f3cb0e7c4247aebea71a6d5a68cab49"}, - {file = "matplotlib-3.9.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:37e51dd1c2db16ede9cfd7b5cabdfc818b2c6397c83f8b10e0e797501c963a03"}, - {file = "matplotlib-3.9.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b82c5045cebcecd8496a4d694d43f9cc84aeeb49fe2133e036b207abe73f4d30"}, - {file = "matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f053c40f94bc51bc03832a41b4f153d83f2062d88c72b5e79997072594e97e51"}, - {file = "matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbe196377a8248972f5cede786d4c5508ed5f5ca4a1e09b44bda889958b33f8c"}, - {file = "matplotlib-3.9.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5816b1e1fe8c192cbc013f8f3e3368ac56fbecf02fb41b8f8559303f24c5015e"}, - {file = "matplotlib-3.9.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:cef2a73d06601437be399908cf13aee74e86932a5ccc6ccdf173408ebc5f6bb2"}, - {file = "matplotlib-3.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e0830e188029c14e891fadd99702fd90d317df294c3298aad682739c5533721a"}, - {file = "matplotlib-3.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ba9c1299c920964e8d3857ba27173b4dbb51ca4bab47ffc2c2ba0eb5e2cbc5"}, - {file = "matplotlib-3.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1cd93b91ab47a3616b4d3c42b52f8363b88ca021e340804c6ab2536344fad9ca"}, - {file = "matplotlib-3.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6d1ce5ed2aefcdce11904fc5bbea7d9c21fff3d5f543841edf3dea84451a09ea"}, - {file = "matplotlib-3.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:b2696efdc08648536efd4e1601b5fd491fd47f4db97a5fbfd175549a7365c1b2"}, - {file = "matplotlib-3.9.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d52a3b618cb1cbb769ce2ee1dcdb333c3ab6e823944e9a2d36e37253815f9556"}, - {file = "matplotlib-3.9.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:039082812cacd6c6bec8e17a9c1e6baca230d4116d522e81e1f63a74d01d2e21"}, - {file = "matplotlib-3.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6758baae2ed64f2331d4fd19be38b7b4eae3ecec210049a26b6a4f3ae1c85dcc"}, - {file = "matplotlib-3.9.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:050598c2b29e0b9832cde72bcf97627bf00262adbc4a54e2b856426bb2ef0697"}, - {file = "matplotlib-3.9.2.tar.gz", hash = "sha256:96ab43906269ca64a6366934106fa01534454a69e471b7bf3d79083981aaab92"}, -] - -[package.dependencies] -contourpy = ">=1.0.1" -cycler = ">=0.10" -fonttools = ">=4.22.0" -kiwisolver = ">=1.3.1" -numpy = ">=1.23" -packaging = ">=20.0" -pillow = ">=8" -pyparsing = ">=2.3.1" -python-dateutil = ">=2.7" - -[package.extras] -dev = ["meson-python (>=0.13.1)", "numpy (>=1.25)", "pybind11 (>=2.6)", "setuptools (>=64)", "setuptools_scm (>=7)"] - -[[package]] -name = "mccabe" -version = "0.7.0" -description = "McCabe checker, plugin for flake8" -optional = false -python-versions = ">=3.6" -files = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, -] - -[[package]] -name = "mdit-py-plugins" -version = "0.4.2" -description = "Collection of plugins for markdown-it-py" -optional = false -python-versions = ">=3.8" -files = [ - {file = "mdit_py_plugins-0.4.2-py3-none-any.whl", hash = "sha256:0c673c3f889399a33b95e88d2f0d111b4447bdfea7f237dab2d488f459835636"}, - {file = "mdit_py_plugins-0.4.2.tar.gz", hash = "sha256:5f2cd1fdb606ddf152d37ec30e46101a60512bc0e5fa1a7002c36647b09e26b5"}, -] - -[package.dependencies] -markdown-it-py = ">=1.0.0,<4.0.0" - -[package.extras] -code-style = ["pre-commit"] -rtd = ["myst-parser", "sphinx-book-theme"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - -[[package]] -name = "mdurl" -version = "0.1.2" -description = "Markdown URL utilities" -optional = false -python-versions = ">=3.7" -files = [ - {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, - {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, -] - -[[package]] -name = "memray" -version = "1.14.0" -description = "A memory profiler for Python applications" -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "memray-1.14.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:745d9014cb662065501441a7b534c29914fe2b68398b37385aba9f4a1c51c723"}, - {file = "memray-1.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f62a402ca1a7126f749544c3d6493672d6330ffd37d59ba230bc73e5143b3bc2"}, - {file = "memray-1.14.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:36840f39277b1871ecb5a9592dd1aa517a17b9f855f4e3ff08aa328a9d305e69"}, - {file = "memray-1.14.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3c7933ca70c0d59d0ce9b1064a6eda86231248759b46ed6dabedf489039d1aa1"}, - {file = "memray-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75a5907345ff845652e709ddce3171a9ba2d65c62e8bd49a99131066e2a7ce3b"}, - {file = "memray-1.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:88c89c3797834eec177a89ad528699c75b94e2ed08c00754141eae69c520b894"}, - {file = "memray-1.14.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:d6087f291fd68acdf0a833efb57bc0f192c98ae89b4377c690c28313e78d029c"}, - {file = "memray-1.14.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e6ba7bff9dfa37bf3b80a5b83b50eadf20afb1f0e8de4a0139019154086d6bed"}, - {file = "memray-1.14.0-cp311-cp311-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9bb0cfe1b755a860435cd52047b2e3f4f7b0c3887e0c1bf98da7127948284a91"}, - {file = "memray-1.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:638ba74e1735a40b6595fee7f37b426b9a95d244091a1f5df3dc5d98df1cbd4b"}, - {file = "memray-1.14.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7227ebf024cb0688a68ed91ed3e05c61a13751a9e875807195076b827bfde464"}, - {file = "memray-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:248dea8cfb5a615345e28b7e25c94377a8d198da3b6957ee443afa6f4ff1b733"}, - {file = "memray-1.14.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7d03f6be66aa259df7fa50082876fbe6461108d77d46c1f720c46067d60685d4"}, - {file = "memray-1.14.0-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:9af9d30b1e484fd8591c9a7f322fd50b9192a2bce660be92385a01555af9968b"}, - {file = "memray-1.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c4088b391c04796c888ac751b5d387f6e8212b3515d4c53ba540c65a6efe4bda"}, - {file = "memray-1.14.0-cp312-cp312-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:af8aee7e8e5cac1e4130f1184b3e03b6bb08264e4ba1696551791ed3f8fb824e"}, - {file = "memray-1.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4352f9e85957f2cbe45a9e1c87dfc19d2df77e93dcd8a558794a683eeee57b7b"}, - {file = "memray-1.14.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5953f0d2aa31b23d4cce20236a03d90b7c71903709a57b456d6494bfe6f470b7"}, - {file = "memray-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e4ccaca04365efcda51036fe2add980030e33cfc4f3a194a01f530a5c923c65"}, - {file = "memray-1.14.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f85a27eb8a65c810161bb992116a66d328546f78a4a4c7c1868949651b917c08"}, - {file = "memray-1.14.0-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:958d57f7149b8fa4831785394f2a7ace93dbc2be6c49a1c07987a8972986474a"}, - {file = "memray-1.14.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287a01953bc44dd0a32549a23bdacb5f9734e345ca289fa3923867c637715056"}, - {file = "memray-1.14.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfc17cba35d98e3d2ca20ab995f17eec3edba7138b062cbc1aa36d53d9d2d955"}, - {file = "memray-1.14.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c82342cead930ca50235f59740ca238808f9c33ef31d994712972966beb6226e"}, - {file = "memray-1.14.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a22a826b4047e839310514f4889c24e45a66ea222fca19ac0ae7b2f89bbb0281"}, - {file = "memray-1.14.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:344f3c73b97ffc8f1666b404deafbc31a19e6b2881341b706aa7ec20afb0e8b1"}, - {file = "memray-1.14.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a43455233d534e9c0e8dabe827d451124874a6455b2afcbcd60b823241ea5843"}, - {file = "memray-1.14.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e05a3b6bc82ef01821beaee98e86bd8de2ada06cb8781add9c40a3ae4a040383"}, - {file = "memray-1.14.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3bc27e5483c70236c9379b99277b4ea8fa4b3f73a99e37af81190649bd877881"}, - {file = "memray-1.14.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a7e5604448b2a78e329addfb099384515d3f973a03711c4e2a7b6c9f7f34f53"}, - {file = "memray-1.14.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:443885a96ab9f67d46288240e2593b5c3ecb2c507ddb4e3b10695e104403d001"}, - {file = "memray-1.14.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:52a45d96ed717d8efb645e99646a92dd21a2ca38bdb823fe22e38c429cba9513"}, - {file = "memray-1.14.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:72febec7b287667e8ea9ee3e879a4da19a4318bc47e211da815be74acd961994"}, - {file = "memray-1.14.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e07bdc3a4979b335c2b6b93a81b807d5aacd8dbbea56c41c6899a8bc0d2beb3"}, - {file = "memray-1.14.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b5e729d03caf426dc45a258270537a603794ecc067ccfd92f9c67ba9332e788"}, - {file = "memray-1.14.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:1d0a1397b5387b75dc9d9759beb022cb360948584840e850474d7d39ad267f85"}, - {file = "memray-1.14.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:c119b600e7c665e0713f09e25f9ee09733a98035688ecc1ec8fd168fa37a77f6"}, - {file = "memray-1.14.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:29a2e7d84d1652ef4664bcceb155630979b4797180b70da35525d963a4ca707f"}, - {file = "memray-1.14.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b3b8d46b6447cdecba3ba100d47c62e78cdad58b00b2d6ba004d6bad318c8668"}, - {file = "memray-1.14.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:57f9bf3f1c648f1ea877a84c21c449fdafd8cc105763ada6023e36bae9b45eb8"}, - {file = "memray-1.14.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b7a59346d242fc39041d87a71cb6cf45baf492ffbb69da9690de49346be64a8"}, - {file = "memray-1.14.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:11fb00105572b70f2aca8b787ce9748b0c94672fbb6334f1604f7f813ca3dca6"}, - {file = "memray-1.14.0.tar.gz", hash = "sha256:b5d8874b7b215551f0ae9fa8aef3f2f52321a6460dc0141aaf9374709e6b0eb7"}, -] - -[package.dependencies] -jinja2 = ">=2.9" -rich = ">=11.2.0" -textual = ">=0.41.0" - -[package.extras] -benchmark = ["asv"] -dev = ["Cython", "asv", "black", "bump2version", "check-manifest", "flake8", "furo", "greenlet", "ipython", "isort", "mypy", "packaging", "pytest", "pytest-cov", "pytest-textual-snapshot", "setuptools", "sphinx", "sphinx-argparse", "textual (>=0.43,!=0.65.2,!=0.66)", "towncrier"] -docs = ["IPython", "bump2version", "furo", "sphinx", "sphinx-argparse", "towncrier"] -lint = ["black", "check-manifest", "flake8", "isort", "mypy"] -test = ["Cython", "greenlet", "ipython", "packaging", "pytest", "pytest-cov", "pytest-textual-snapshot", "setuptools", "textual (>=0.43,!=0.65.2,!=0.66)"] - -[[package]] -name = "multidict" -version = "6.1.0" -description = "multidict implementation" -optional = true -python-versions = ">=3.8" -files = [ - {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3380252550e372e8511d49481bd836264c009adb826b23fefcc5dd3c69692f60"}, - {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99f826cbf970077383d7de805c0681799491cb939c25450b9b5b3ced03ca99f1"}, - {file = "multidict-6.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a114d03b938376557927ab23f1e950827c3b893ccb94b62fd95d430fd0e5cf53"}, - {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1c416351ee6271b2f49b56ad7f308072f6f44b37118d69c2cad94f3fa8a40d5"}, - {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b5d83030255983181005e6cfbac1617ce9746b219bc2aad52201ad121226581"}, - {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3e97b5e938051226dc025ec80980c285b053ffb1e25a3db2a3aa3bc046bf7f56"}, - {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d618649d4e70ac6efcbba75be98b26ef5078faad23592f9b51ca492953012429"}, - {file = "multidict-6.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10524ebd769727ac77ef2278390fb0068d83f3acb7773792a5080f2b0abf7748"}, - {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ff3827aef427c89a25cc96ded1759271a93603aba9fb977a6d264648ebf989db"}, - {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:06809f4f0f7ab7ea2cabf9caca7d79c22c0758b58a71f9d32943ae13c7ace056"}, - {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f179dee3b863ab1c59580ff60f9d99f632f34ccb38bf67a33ec6b3ecadd0fd76"}, - {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:aaed8b0562be4a0876ee3b6946f6869b7bcdb571a5d1496683505944e268b160"}, - {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3c8b88a2ccf5493b6c8da9076fb151ba106960a2df90c2633f342f120751a9e7"}, - {file = "multidict-6.1.0-cp310-cp310-win32.whl", hash = "sha256:4a9cb68166a34117d6646c0023c7b759bf197bee5ad4272f420a0141d7eb03a0"}, - {file = "multidict-6.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:20b9b5fbe0b88d0bdef2012ef7dee867f874b72528cf1d08f1d59b0e3850129d"}, - {file = "multidict-6.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3efe2c2cb5763f2f1b275ad2bf7a287d3f7ebbef35648a9726e3b69284a4f3d6"}, - {file = "multidict-6.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7053d3b0353a8b9de430a4f4b4268ac9a4fb3481af37dfe49825bf45ca24156"}, - {file = "multidict-6.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27e5fc84ccef8dfaabb09d82b7d179c7cf1a3fbc8a966f8274fcb4ab2eb4cadb"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2b90b43e696f25c62656389d32236e049568b39320e2735d51f08fd362761b"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d83a047959d38a7ff552ff94be767b7fd79b831ad1cd9920662db05fec24fe72"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1a9dd711d0877a1ece3d2e4fea11a8e75741ca21954c919406b44e7cf971304"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec2abea24d98246b94913b76a125e855eb5c434f7c46546046372fe60f666351"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4867cafcbc6585e4b678876c489b9273b13e9fff9f6d6d66add5e15d11d926cb"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5b48204e8d955c47c55b72779802b219a39acc3ee3d0116d5080c388970b76e3"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d8fff389528cad1618fb4b26b95550327495462cd745d879a8c7c2115248e399"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a7a9541cd308eed5e30318430a9c74d2132e9a8cb46b901326272d780bf2d423"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:da1758c76f50c39a2efd5e9859ce7d776317eb1dd34317c8152ac9251fc574a3"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c943a53e9186688b45b323602298ab727d8865d8c9ee0b17f8d62d14b56f0753"}, - {file = "multidict-6.1.0-cp311-cp311-win32.whl", hash = "sha256:90f8717cb649eea3504091e640a1b8568faad18bd4b9fcd692853a04475a4b80"}, - {file = "multidict-6.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:82176036e65644a6cc5bd619f65f6f19781e8ec2e5330f51aa9ada7504cc1926"}, - {file = "multidict-6.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b04772ed465fa3cc947db808fa306d79b43e896beb677a56fb2347ca1a49c1fa"}, - {file = "multidict-6.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6180c0ae073bddeb5a97a38c03f30c233e0a4d39cd86166251617d1bbd0af436"}, - {file = "multidict-6.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:071120490b47aa997cca00666923a83f02c7fbb44f71cf7f136df753f7fa8761"}, - {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50b3a2710631848991d0bf7de077502e8994c804bb805aeb2925a981de58ec2e"}, - {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b58c621844d55e71c1b7f7c498ce5aa6985d743a1a59034c57a905b3f153c1ef"}, - {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55b6d90641869892caa9ca42ff913f7ff1c5ece06474fbd32fb2cf6834726c95"}, - {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b820514bfc0b98a30e3d85462084779900347e4d49267f747ff54060cc33925"}, - {file = "multidict-6.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10a9b09aba0c5b48c53761b7c720aaaf7cf236d5fe394cd399c7ba662d5f9966"}, - {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e16bf3e5fc9f44632affb159d30a437bfe286ce9e02754759be5536b169b305"}, - {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76f364861c3bfc98cbbcbd402d83454ed9e01a5224bb3a28bf70002a230f73e2"}, - {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:820c661588bd01a0aa62a1283f20d2be4281b086f80dad9e955e690c75fb54a2"}, - {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0e5f362e895bc5b9e67fe6e4ded2492d8124bdf817827f33c5b46c2fe3ffaca6"}, - {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ec660d19bbc671e3a6443325f07263be452c453ac9e512f5eb935e7d4ac28b3"}, - {file = "multidict-6.1.0-cp312-cp312-win32.whl", hash = "sha256:58130ecf8f7b8112cdb841486404f1282b9c86ccb30d3519faf301b2e5659133"}, - {file = "multidict-6.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:188215fc0aafb8e03341995e7c4797860181562380f81ed0a87ff455b70bf1f1"}, - {file = "multidict-6.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d569388c381b24671589335a3be6e1d45546c2988c2ebe30fdcada8457a31008"}, - {file = "multidict-6.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:052e10d2d37810b99cc170b785945421141bf7bb7d2f8799d431e7db229c385f"}, - {file = "multidict-6.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f90c822a402cb865e396a504f9fc8173ef34212a342d92e362ca498cad308e28"}, - {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b225d95519a5bf73860323e633a664b0d85ad3d5bede6d30d95b35d4dfe8805b"}, - {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:23bfd518810af7de1116313ebd9092cb9aa629beb12f6ed631ad53356ed6b86c"}, - {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c09fcfdccdd0b57867577b719c69e347a436b86cd83747f179dbf0cc0d4c1f3"}, - {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf6bea52ec97e95560af5ae576bdac3aa3aae0b6758c6efa115236d9e07dae44"}, - {file = "multidict-6.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57feec87371dbb3520da6192213c7d6fc892d5589a93db548331954de8248fd2"}, - {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0c3f390dc53279cbc8ba976e5f8035eab997829066756d811616b652b00a23a3"}, - {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:59bfeae4b25ec05b34f1956eaa1cb38032282cd4dfabc5056d0a1ec4d696d3aa"}, - {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b2f59caeaf7632cc633b5cf6fc449372b83bbdf0da4ae04d5be36118e46cc0aa"}, - {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:37bb93b2178e02b7b618893990941900fd25b6b9ac0fa49931a40aecdf083fe4"}, - {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4e9f48f58c2c523d5a06faea47866cd35b32655c46b443f163d08c6d0ddb17d6"}, - {file = "multidict-6.1.0-cp313-cp313-win32.whl", hash = "sha256:3a37ffb35399029b45c6cc33640a92bef403c9fd388acce75cdc88f58bd19a81"}, - {file = "multidict-6.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:e9aa71e15d9d9beaad2c6b9319edcdc0a49a43ef5c0a4c8265ca9ee7d6c67774"}, - {file = "multidict-6.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:db7457bac39421addd0c8449933ac32d8042aae84a14911a757ae6ca3eef1392"}, - {file = "multidict-6.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d094ddec350a2fb899fec68d8353c78233debde9b7d8b4beeafa70825f1c281a"}, - {file = "multidict-6.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5845c1fd4866bb5dd3125d89b90e57ed3138241540897de748cdf19de8a2fca2"}, - {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9079dfc6a70abe341f521f78405b8949f96db48da98aeb43f9907f342f627cdc"}, - {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3914f5aaa0f36d5d60e8ece6a308ee1c9784cd75ec8151062614657a114c4478"}, - {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c08be4f460903e5a9d0f76818db3250f12e9c344e79314d1d570fc69d7f4eae4"}, - {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d093be959277cb7dee84b801eb1af388b6ad3ca6a6b6bf1ed7585895789d027d"}, - {file = "multidict-6.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3702ea6872c5a2a4eeefa6ffd36b042e9773f05b1f37ae3ef7264b1163c2dcf6"}, - {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2090f6a85cafc5b2db085124d752757c9d251548cedabe9bd31afe6363e0aff2"}, - {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:f67f217af4b1ff66c68a87318012de788dd95fcfeb24cc889011f4e1c7454dfd"}, - {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:189f652a87e876098bbc67b4da1049afb5f5dfbaa310dd67c594b01c10388db6"}, - {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:6bb5992037f7a9eff7991ebe4273ea7f51f1c1c511e6a2ce511d0e7bdb754492"}, - {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f4c2b9e770c4e393876e35a7046879d195cd123b4f116d299d442b335bcd"}, - {file = "multidict-6.1.0-cp38-cp38-win32.whl", hash = "sha256:e27bbb6d14416713a8bd7aaa1313c0fc8d44ee48d74497a0ff4c3a1b6ccb5167"}, - {file = "multidict-6.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:22f3105d4fb15c8f57ff3959a58fcab6ce36814486500cd7485651230ad4d4ef"}, - {file = "multidict-6.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4e18b656c5e844539d506a0a06432274d7bd52a7487e6828c63a63d69185626c"}, - {file = "multidict-6.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a185f876e69897a6f3325c3f19f26a297fa058c5e456bfcff8015e9a27e83ae1"}, - {file = "multidict-6.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab7c4ceb38d91570a650dba194e1ca87c2b543488fe9309b4212694174fd539c"}, - {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e617fb6b0b6953fffd762669610c1c4ffd05632c138d61ac7e14ad187870669c"}, - {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16e5f4bf4e603eb1fdd5d8180f1a25f30056f22e55ce51fb3d6ad4ab29f7d96f"}, - {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c035da3f544b1882bac24115f3e2e8760f10a0107614fc9839fd232200b875"}, - {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:957cf8e4b6e123a9eea554fa7ebc85674674b713551de587eb318a2df3e00255"}, - {file = "multidict-6.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:483a6aea59cb89904e1ceabd2b47368b5600fb7de78a6e4a2c2987b2d256cf30"}, - {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:87701f25a2352e5bf7454caa64757642734da9f6b11384c1f9d1a8e699758057"}, - {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:682b987361e5fd7a139ed565e30d81fd81e9629acc7d925a205366877d8c8657"}, - {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce2186a7df133a9c895dea3331ddc5ddad42cdd0d1ea2f0a51e5d161e4762f28"}, - {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9f636b730f7e8cb19feb87094949ba54ee5357440b9658b2a32a5ce4bce53972"}, - {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:73eae06aa53af2ea5270cc066dcaf02cc60d2994bbb2c4ef5764949257d10f43"}, - {file = "multidict-6.1.0-cp39-cp39-win32.whl", hash = "sha256:1ca0083e80e791cffc6efce7660ad24af66c8d4079d2a750b29001b53ff59ada"}, - {file = "multidict-6.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:aa466da5b15ccea564bdab9c89175c762bc12825f4659c11227f515cee76fa4a"}, - {file = "multidict-6.1.0-py3-none-any.whl", hash = "sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506"}, - {file = "multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a"}, -] - -[package.dependencies] -typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""} - -[[package]] -name = "mypy" -version = "1.13.0" -description = "Optional static typing for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a"}, - {file = "mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80"}, - {file = "mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7"}, - {file = "mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f"}, - {file = "mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372"}, - {file = "mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d"}, - {file = "mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d"}, - {file = "mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b"}, - {file = "mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73"}, - {file = "mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca"}, - {file = "mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5"}, - {file = "mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e"}, - {file = "mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2"}, - {file = "mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0"}, - {file = "mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2"}, - {file = "mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7"}, - {file = "mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62"}, - {file = "mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8"}, - {file = "mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7"}, - {file = "mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc"}, - {file = "mypy-1.13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:100fac22ce82925f676a734af0db922ecfea991e1d7ec0ceb1e115ebe501301a"}, - {file = "mypy-1.13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7bcb0bb7f42a978bb323a7c88f1081d1b5dee77ca86f4100735a6f541299d8fb"}, - {file = "mypy-1.13.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bde31fc887c213e223bbfc34328070996061b0833b0a4cfec53745ed61f3519b"}, - {file = "mypy-1.13.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:07de989f89786f62b937851295ed62e51774722e5444a27cecca993fc3f9cd74"}, - {file = "mypy-1.13.0-cp38-cp38-win_amd64.whl", hash = "sha256:4bde84334fbe19bad704b3f5b78c4abd35ff1026f8ba72b29de70dda0916beb6"}, - {file = "mypy-1.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0246bcb1b5de7f08f2826451abd947bf656945209b140d16ed317f65a17dc7dc"}, - {file = "mypy-1.13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7f5b7deae912cf8b77e990b9280f170381fdfbddf61b4ef80927edd813163732"}, - {file = "mypy-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7029881ec6ffb8bc233a4fa364736789582c738217b133f1b55967115288a2bc"}, - {file = "mypy-1.13.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3e38b980e5681f28f033f3be86b099a247b13c491f14bb8b1e1e134d23bb599d"}, - {file = "mypy-1.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:a6789be98a2017c912ae6ccb77ea553bbaf13d27605d2ca20a76dfbced631b24"}, - {file = "mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a"}, - {file = "mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e"}, -] - -[package.dependencies] -mypy-extensions = ">=1.0.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=4.6.0" - -[package.extras] -dmypy = ["psutil (>=4.0)"] -faster-cache = ["orjson"] -install-types = ["pip"] -mypyc = ["setuptools (>=50)"] -reports = ["lxml"] - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.5" -files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - -[[package]] -name = "nltk" -version = "3.8.1" -description = "Natural Language Toolkit" -optional = true -python-versions = ">=3.7" -files = [ - {file = "nltk-3.8.1-py3-none-any.whl", hash = "sha256:fd5c9109f976fa86bcadba8f91e47f5e9293bd034474752e92a520f81c93dda5"}, - {file = "nltk-3.8.1.zip", hash = "sha256:1834da3d0682cba4f2cede2f9aad6b0fafb6461ba451db0efb6f9c39798d64d3"}, -] - -[package.dependencies] -click = "*" -joblib = "*" -regex = ">=2021.8.3" -tqdm = "*" - -[package.extras] -all = ["matplotlib", "numpy", "pyparsing", "python-crfsuite", "requests", "scikit-learn", "scipy", "twython"] -corenlp = ["requests"] -machine-learning = ["numpy", "python-crfsuite", "scikit-learn", "scipy"] -plot = ["matplotlib"] -tgrep = ["pyparsing"] -twitter = ["twython"] - -[[package]] -name = "numpy" -version = "1.26.4" -description = "Fundamental package for array computing in Python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, - {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, - {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, - {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, - {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, - {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, - {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, - {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, - {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, - {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, - {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, - {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, - {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, - {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, - {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, - {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, - {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, - {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, - {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, - {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, - {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, - {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, - {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, - {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, - {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, - {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, - {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, - {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, - {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, - {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, - {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, - {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, - {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, - {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, - {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, - {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, -] - -[[package]] -name = "openai" -version = "0.27.9" -description = "Python client library for the OpenAI API" -optional = true -python-versions = ">=3.7.1" -files = [ - {file = "openai-0.27.9-py3-none-any.whl", hash = "sha256:6a3cf8e276d1a6262b50562fbc0cba7967cfebb78ed827d375986b48fdad6475"}, - {file = "openai-0.27.9.tar.gz", hash = "sha256:b687761c82f5ebb6f61efc791b2083d2d068277b94802d4d1369efe39851813d"}, -] - -[package.dependencies] -aiohttp = "*" -matplotlib = {version = "*", optional = true, markers = "extra == \"embeddings\""} -numpy = {version = "*", optional = true, markers = "extra == \"embeddings\""} -openpyxl = {version = ">=3.0.7", optional = true, markers = "extra == \"embeddings\""} -pandas = {version = ">=1.2.3", optional = true, markers = "extra == \"embeddings\""} -pandas-stubs = {version = ">=1.1.0.11", optional = true, markers = "extra == \"embeddings\""} -plotly = {version = "*", optional = true, markers = "extra == \"embeddings\""} -requests = ">=2.20" -scikit-learn = {version = ">=1.0.2", optional = true, markers = "extra == \"embeddings\""} -scipy = {version = "*", optional = true, markers = "extra == \"embeddings\""} -tenacity = {version = ">=8.0.1", optional = true, markers = "extra == \"embeddings\""} -tqdm = "*" - -[package.extras] -datalib = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] -dev = ["black (>=21.6b0,<22.0)", "pytest (==6.*)", "pytest-asyncio", "pytest-mock"] -embeddings = ["matplotlib", "numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)", "plotly", "scikit-learn (>=1.0.2)", "scipy", "tenacity (>=8.0.1)"] -wandb = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)", "wandb"] - -[[package]] -name = "openpyxl" -version = "3.1.5" -description = "A Python library to read/write Excel 2010 xlsx/xlsm files" -optional = true -python-versions = ">=3.8" -files = [ - {file = "openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2"}, - {file = "openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050"}, -] - -[package.dependencies] -et-xmlfile = "*" - -[[package]] -name = "orjson" -version = "3.10.10" -description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" -optional = false -python-versions = ">=3.8" -files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, -] - -[[package]] -name = "packaging" -version = "23.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, -] - -[[package]] -name = "pandas" -version = "2.2.2" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, - {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, - {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, - {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, - {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, - {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, - {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, - {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, - {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, - {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, - {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, - {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, - {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, - {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, - {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, - {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, - {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, - {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, - {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, - {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, - {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, - {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, - {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, - {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, - {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, - {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, - {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, - {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, - {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, -] - -[package.dependencies] -numpy = [ - {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.23.2", markers = "python_version == \"3.11\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, -] -python-dateutil = ">=2.8.2" -pytz = ">=2020.1" -tzdata = ">=2022.7" - -[package.extras] -all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] -aws = ["s3fs (>=2022.11.0)"] -clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] -compression = ["zstandard (>=0.19.0)"] -computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] -consortium-standard = ["dataframe-api-compat (>=0.1.7)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] -feather = ["pyarrow (>=10.0.1)"] -fss = ["fsspec (>=2022.11.0)"] -gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] -hdf5 = ["tables (>=3.8.0)"] -html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] -mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] -parquet = ["pyarrow (>=10.0.1)"] -performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] -plot = ["matplotlib (>=3.6.3)"] -postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] -pyarrow = ["pyarrow (>=10.0.1)"] -spss = ["pyreadstat (>=1.2.0)"] -sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] -test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.9.2)"] - -[[package]] -name = "pandas-stubs" -version = "2.2.3.241009" -description = "Type annotations for pandas" -optional = true -python-versions = ">=3.10" -files = [ - {file = "pandas_stubs-2.2.3.241009-py3-none-any.whl", hash = "sha256:3a6f8f142105a42550be677ba741ba532621f4e0acad2155c0e7b2450f114cfa"}, - {file = "pandas_stubs-2.2.3.241009.tar.gz", hash = "sha256:d4ab618253f0acf78a5d0d2bfd6dffdd92d91a56a69bdc8144e5a5c6d25be3b5"}, -] - -[package.dependencies] -numpy = ">=1.23.5" -types-pytz = ">=2022.1.1" - -[[package]] -name = "pastel" -version = "0.2.1" -description = "Bring colors to your terminal." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364"}, - {file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"}, -] - -[[package]] -name = "pdf2image" -version = "1.16.3" -description = "A wrapper around the pdftoppm and pdftocairo command line tools to convert PDF to a PIL Image list." -optional = true -python-versions = "*" -files = [ - {file = "pdf2image-1.16.3-py3-none-any.whl", hash = "sha256:b6154164af3677211c22cbb38b2bd778b43aca02758e962fe1e231f6d3b0e380"}, - {file = "pdf2image-1.16.3.tar.gz", hash = "sha256:74208810c2cef4d9e347769b8e62a52303982ddb4f2dfd744c7ab4b940ae287e"}, -] - -[package.dependencies] -pillow = "*" - -[[package]] -name = "pdfminer-six" -version = "20221105" -description = "PDF parser and analyzer" -optional = true -python-versions = ">=3.6" -files = [ - {file = "pdfminer.six-20221105-py3-none-any.whl", hash = "sha256:1eaddd712d5b2732f8ac8486824533514f8ba12a0787b3d5fe1e686cd826532d"}, - {file = "pdfminer.six-20221105.tar.gz", hash = "sha256:8448ab7b939d18b64820478ecac5394f482d7a79f5f7eaa7703c6c959c175e1d"}, -] - -[package.dependencies] -charset-normalizer = ">=2.0.0" -cryptography = ">=36.0.0" - -[package.extras] -dev = ["black", "mypy (==0.931)", "nox", "pytest"] -docs = ["sphinx", "sphinx-argparse"] -image = ["Pillow"] - -[[package]] -name = "pendulum" -version = "2.1.2" -description = "Python datetimes made easy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, - {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, - {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, - {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, - {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, - {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, - {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, - {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, - {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, - {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, - {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, -] - -[package.dependencies] -python-dateutil = ">=2.6,<3.0" -pytzdata = ">=2020.1" - -[[package]] -name = "pillow" -version = "11.0.0" -description = "Python Imaging Library (Fork)" -optional = true -python-versions = ">=3.9" -files = [ - {file = "pillow-11.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947"}, - {file = "pillow-11.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba"}, - {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086"}, - {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9"}, - {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488"}, - {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f"}, - {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb"}, - {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97"}, - {file = "pillow-11.0.0-cp310-cp310-win32.whl", hash = "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50"}, - {file = "pillow-11.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c"}, - {file = "pillow-11.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1"}, - {file = "pillow-11.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc"}, - {file = "pillow-11.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a"}, - {file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3"}, - {file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5"}, - {file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b"}, - {file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa"}, - {file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306"}, - {file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9"}, - {file = "pillow-11.0.0-cp311-cp311-win32.whl", hash = "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5"}, - {file = "pillow-11.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291"}, - {file = "pillow-11.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9"}, - {file = "pillow-11.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923"}, - {file = "pillow-11.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903"}, - {file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4"}, - {file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f"}, - {file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9"}, - {file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7"}, - {file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6"}, - {file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc"}, - {file = "pillow-11.0.0-cp312-cp312-win32.whl", hash = "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6"}, - {file = "pillow-11.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47"}, - {file = "pillow-11.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25"}, - {file = "pillow-11.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcd1fb5bb7b07f64c15618c89efcc2cfa3e95f0e3bcdbaf4642509de1942a699"}, - {file = "pillow-11.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e038b0745997c7dcaae350d35859c9715c71e92ffb7e0f4a8e8a16732150f38"}, - {file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ae08bd8ffc41aebf578c2af2f9d8749d91f448b3bfd41d7d9ff573d74f2a6b2"}, - {file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d69bfd8ec3219ae71bcde1f942b728903cad25fafe3100ba2258b973bd2bc1b2"}, - {file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:61b887f9ddba63ddf62fd02a3ba7add935d053b6dd7d58998c630e6dbade8527"}, - {file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:c6a660307ca9d4867caa8d9ca2c2658ab685de83792d1876274991adec7b93fa"}, - {file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:73e3a0200cdda995c7e43dd47436c1548f87a30bb27fb871f352a22ab8dcf45f"}, - {file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fba162b8872d30fea8c52b258a542c5dfd7b235fb5cb352240c8d63b414013eb"}, - {file = "pillow-11.0.0-cp313-cp313-win32.whl", hash = "sha256:f1b82c27e89fffc6da125d5eb0ca6e68017faf5efc078128cfaa42cf5cb38798"}, - {file = "pillow-11.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ba470552b48e5835f1d23ecb936bb7f71d206f9dfeee64245f30c3270b994de"}, - {file = "pillow-11.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:846e193e103b41e984ac921b335df59195356ce3f71dcfd155aa79c603873b84"}, - {file = "pillow-11.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4ad70c4214f67d7466bea6a08061eba35c01b1b89eaa098040a35272a8efb22b"}, - {file = "pillow-11.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6ec0d5af64f2e3d64a165f490d96368bb5dea8b8f9ad04487f9ab60dc4bb6003"}, - {file = "pillow-11.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c809a70e43c7977c4a42aefd62f0131823ebf7dd73556fa5d5950f5b354087e2"}, - {file = "pillow-11.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:4b60c9520f7207aaf2e1d94de026682fc227806c6e1f55bba7606d1c94dd623a"}, - {file = "pillow-11.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1e2688958a840c822279fda0086fec1fdab2f95bf2b717b66871c4ad9859d7e8"}, - {file = "pillow-11.0.0-cp313-cp313t-win32.whl", hash = "sha256:607bbe123c74e272e381a8d1957083a9463401f7bd01287f50521ecb05a313f8"}, - {file = "pillow-11.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c39ed17edea3bc69c743a8dd3e9853b7509625c2462532e62baa0732163a904"}, - {file = "pillow-11.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3"}, - {file = "pillow-11.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2e46773dc9f35a1dd28bd6981332fd7f27bec001a918a72a79b4133cf5291dba"}, - {file = "pillow-11.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2679d2258b7f1192b378e2893a8a0a0ca472234d4c2c0e6bdd3380e8dfa21b6a"}, - {file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eda2616eb2313cbb3eebbe51f19362eb434b18e3bb599466a1ffa76a033fb916"}, - {file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ec184af98a121fb2da42642dea8a29ec80fc3efbaefb86d8fdd2606619045d"}, - {file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:8594f42df584e5b4bb9281799698403f7af489fba84c34d53d1c4bfb71b7c4e7"}, - {file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:c12b5ae868897c7338519c03049a806af85b9b8c237b7d675b8c5e089e4a618e"}, - {file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:70fbbdacd1d271b77b7721fe3cdd2d537bbbd75d29e6300c672ec6bb38d9672f"}, - {file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5178952973e588b3f1360868847334e9e3bf49d19e169bbbdfaf8398002419ae"}, - {file = "pillow-11.0.0-cp39-cp39-win32.whl", hash = "sha256:8c676b587da5673d3c75bd67dd2a8cdfeb282ca38a30f37950511766b26858c4"}, - {file = "pillow-11.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:94f3e1780abb45062287b4614a5bc0874519c86a777d4a7ad34978e86428b8dd"}, - {file = "pillow-11.0.0-cp39-cp39-win_arm64.whl", hash = "sha256:290f2cc809f9da7d6d622550bbf4c1e57518212da51b6a30fe8e0a270a5b78bd"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316"}, - {file = "pillow-11.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5bd2d3bdb846d757055910f0a59792d33b555800813c3b39ada1829c372ccb06"}, - {file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:375b8dd15a1f5d2feafff536d47e22f69625c1aa92f12b339ec0b2ca40263273"}, - {file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:daffdf51ee5db69a82dd127eabecce20729e21f7a3680cf7cbb23f0829189790"}, - {file = "pillow-11.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7326a1787e3c7b0429659e0a944725e1b03eeaa10edd945a86dead1913383944"}, - {file = "pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=8.1)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] -fpx = ["olefile"] -mic = ["olefile"] -tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] -typing = ["typing-extensions"] -xmp = ["defusedxml"] - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "plotly" -version = "5.24.1" -description = "An open-source, interactive data visualization library for Python" -optional = true -python-versions = ">=3.8" -files = [ - {file = "plotly-5.24.1-py3-none-any.whl", hash = "sha256:f67073a1e637eb0dc3e46324d9d51e2fe76e9727c892dde64ddf1e1b51f29089"}, - {file = "plotly-5.24.1.tar.gz", hash = "sha256:dbc8ac8339d248a4bcc36e08a5659bacfe1b079390b8953533f4eb22169b4bae"}, -] - -[package.dependencies] -packaging = "*" -tenacity = ">=6.2.0" - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "poethepoet" -version = "0.24.4" -description = "A task runner that works well with poetry." -optional = false -python-versions = ">=3.8" -files = [ - {file = "poethepoet-0.24.4-py3-none-any.whl", hash = "sha256:fb4ea35d7f40fe2081ea917d2e4102e2310fda2cde78974050ca83896e229075"}, - {file = "poethepoet-0.24.4.tar.gz", hash = "sha256:ff4220843a87c888cbcb5312c8905214701d0af60ac7271795baa8369b428fef"}, -] - -[package.dependencies] -pastel = ">=0.2.1,<0.3.0" -tomli = ">=1.2.2" - -[package.extras] -poetry-plugin = ["poetry (>=1.0,<2.0)"] - -[[package]] -name = "propcache" -version = "0.2.0" -description = "Accelerated property cache" -optional = true -python-versions = ">=3.8" -files = [ - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"}, - {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"}, - {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"}, - {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"}, - {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, - {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, - {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544"}, - {file = "propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032"}, - {file = "propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed"}, - {file = "propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d"}, - {file = "propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798"}, - {file = "propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9"}, - {file = "propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df"}, - {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, - {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, -] - -[[package]] -name = "pyarrow" -version = "15.0.2" -description = "Python library for Apache Arrow" -optional = true -python-versions = ">=3.8" -files = [ - {file = "pyarrow-15.0.2-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:88b340f0a1d05b5ccc3d2d986279045655b1fe8e41aba6ca44ea28da0d1455d8"}, - {file = "pyarrow-15.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eaa8f96cecf32da508e6c7f69bb8401f03745c050c1dd42ec2596f2e98deecac"}, - {file = "pyarrow-15.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23c6753ed4f6adb8461e7c383e418391b8d8453c5d67e17f416c3a5d5709afbd"}, - {file = "pyarrow-15.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f639c059035011db8c0497e541a8a45d98a58dbe34dc8fadd0ef128f2cee46e5"}, - {file = "pyarrow-15.0.2-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:290e36a59a0993e9a5224ed2fb3e53375770f07379a0ea03ee2fce2e6d30b423"}, - {file = "pyarrow-15.0.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:06c2bb2a98bc792f040bef31ad3e9be6a63d0cb39189227c08a7d955db96816e"}, - {file = "pyarrow-15.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:f7a197f3670606a960ddc12adbe8075cea5f707ad7bf0dffa09637fdbb89f76c"}, - {file = "pyarrow-15.0.2-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:5f8bc839ea36b1f99984c78e06e7a06054693dc2af8920f6fb416b5bca9944e4"}, - {file = "pyarrow-15.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f5e81dfb4e519baa6b4c80410421528c214427e77ca0ea9461eb4097c328fa33"}, - {file = "pyarrow-15.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a4f240852b302a7af4646c8bfe9950c4691a419847001178662a98915fd7ee7"}, - {file = "pyarrow-15.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e7d9cfb5a1e648e172428c7a42b744610956f3b70f524aa3a6c02a448ba853e"}, - {file = "pyarrow-15.0.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:2d4f905209de70c0eb5b2de6763104d5a9a37430f137678edfb9a675bac9cd98"}, - {file = "pyarrow-15.0.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:90adb99e8ce5f36fbecbbc422e7dcbcbed07d985eed6062e459e23f9e71fd197"}, - {file = "pyarrow-15.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:b116e7fd7889294cbd24eb90cd9bdd3850be3738d61297855a71ac3b8124ee38"}, - {file = "pyarrow-15.0.2-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:25335e6f1f07fdaa026a61c758ee7d19ce824a866b27bba744348fa73bb5a440"}, - {file = "pyarrow-15.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:90f19e976d9c3d8e73c80be84ddbe2f830b6304e4c576349d9360e335cd627fc"}, - {file = "pyarrow-15.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a22366249bf5fd40ddacc4f03cd3160f2d7c247692945afb1899bab8a140ddfb"}, - {file = "pyarrow-15.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2a335198f886b07e4b5ea16d08ee06557e07db54a8400cc0d03c7f6a22f785f"}, - {file = "pyarrow-15.0.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:3e6d459c0c22f0b9c810a3917a1de3ee704b021a5fb8b3bacf968eece6df098f"}, - {file = "pyarrow-15.0.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:033b7cad32198754d93465dcfb71d0ba7cb7cd5c9afd7052cab7214676eec38b"}, - {file = "pyarrow-15.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:29850d050379d6e8b5a693098f4de7fd6a2bea4365bfd073d7c57c57b95041ee"}, - {file = "pyarrow-15.0.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:7167107d7fb6dcadb375b4b691b7e316f4368f39f6f45405a05535d7ad5e5058"}, - {file = "pyarrow-15.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e85241b44cc3d365ef950432a1b3bd44ac54626f37b2e3a0cc89c20e45dfd8bf"}, - {file = "pyarrow-15.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:248723e4ed3255fcd73edcecc209744d58a9ca852e4cf3d2577811b6d4b59818"}, - {file = "pyarrow-15.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ff3bdfe6f1b81ca5b73b70a8d482d37a766433823e0c21e22d1d7dde76ca33f"}, - {file = "pyarrow-15.0.2-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:f3d77463dee7e9f284ef42d341689b459a63ff2e75cee2b9302058d0d98fe142"}, - {file = "pyarrow-15.0.2-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:8c1faf2482fb89766e79745670cbca04e7018497d85be9242d5350cba21357e1"}, - {file = "pyarrow-15.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:28f3016958a8e45a1069303a4a4f6a7d4910643fc08adb1e2e4a7ff056272ad3"}, - {file = "pyarrow-15.0.2-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:89722cb64286ab3d4daf168386f6968c126057b8c7ec3ef96302e81d8cdb8ae4"}, - {file = "pyarrow-15.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cd0ba387705044b3ac77b1b317165c0498299b08261d8122c96051024f953cd5"}, - {file = "pyarrow-15.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad2459bf1f22b6a5cdcc27ebfd99307d5526b62d217b984b9f5c974651398832"}, - {file = "pyarrow-15.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58922e4bfece8b02abf7159f1f53a8f4d9f8e08f2d988109126c17c3bb261f22"}, - {file = "pyarrow-15.0.2-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:adccc81d3dc0478ea0b498807b39a8d41628fa9210729b2f718b78cb997c7c91"}, - {file = "pyarrow-15.0.2-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:8bd2baa5fe531571847983f36a30ddbf65261ef23e496862ece83bdceb70420d"}, - {file = "pyarrow-15.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6669799a1d4ca9da9c7e06ef48368320f5856f36f9a4dd31a11839dda3f6cc8c"}, - {file = "pyarrow-15.0.2.tar.gz", hash = "sha256:9c9bc803cb3b7bfacc1e96ffbfd923601065d9d3f911179d81e72d99fd74a3d9"}, -] - -[package.dependencies] -numpy = ">=1.16.6,<2" - -[[package]] -name = "pycodestyle" -version = "2.11.1" -description = "Python style guide checker" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"}, - {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"}, -] - -[[package]] -name = "pycparser" -version = "2.22" -description = "C parser in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, - {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, -] - -[[package]] -name = "pydantic" -version = "2.9.2" -description = "Data validation using Python type hints" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, -] - -[package.dependencies] -annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = [ - {version = ">=4.6.1", markers = "python_version < \"3.13\""}, - {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, -] - -[package.extras] -email = ["email-validator (>=2.0.0)"] -timezone = ["tzdata"] - -[[package]] -name = "pydantic-core" -version = "2.23.4" -description = "Core functionality for Pydantic validation and serialization" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, -] - -[package.dependencies] -typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" - -[[package]] -name = "pyflakes" -version = "3.1.0" -description = "passive checker of Python programs" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"}, - {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, -] - -[[package]] -name = "pygments" -version = "2.18.0" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, - {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, -] - -[package.extras] -windows-terminal = ["colorama (>=0.4.6)"] - -[[package]] -name = "pyjwt" -version = "2.9.0" -description = "JSON Web Token implementation in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, -] - -[package.extras] -crypto = ["cryptography (>=3.4.0)"] -dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] -docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] -tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] - -[[package]] -name = "pyparsing" -version = "3.2.0" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" -optional = true -python-versions = ">=3.9" -files = [ - {file = "pyparsing-3.2.0-py3-none-any.whl", hash = "sha256:93d9577b88da0bbea8cc8334ee8b918ed014968fd2ec383e868fb8afb1ccef84"}, - {file = "pyparsing-3.2.0.tar.gz", hash = "sha256:cbf74e27246d595d9a74b186b810f6fbb86726dbf3b9532efb343f6d7294fe9c"}, -] - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - -[[package]] -name = "pyproject-flake8" -version = "6.1.0" -description = "pyproject-flake8 (`pflake8`), a monkey patching wrapper to connect flake8 with pyproject.toml configuration" -optional = false -python-versions = ">=3.8.1" -files = [ - {file = "pyproject_flake8-6.1.0-py3-none-any.whl", hash = "sha256:86ea5559263c098e1aa4f866776aa2cf45362fd91a576b9fd8fbbbb55db12c4e"}, - {file = "pyproject_flake8-6.1.0.tar.gz", hash = "sha256:6da8e5a264395e0148bc11844c6fb50546f1fac83ac9210f7328664135f9e70f"}, -] - -[package.dependencies] -flake8 = "6.1.0" -tomli = {version = "*", markers = "python_version < \"3.11\""} - -[[package]] -name = "pyrate-limiter" -version = "3.1.1" -description = "Python Rate-Limiter using Leaky-Bucket Algorithm" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, - {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, -] - -[package.extras] -all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] -docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] - -[[package]] -name = "pyrsistent" -version = "0.20.0" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7"}, - {file = "pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee"}, - {file = "pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d"}, - {file = "pyrsistent-0.20.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win32.whl", hash = "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d"}, - {file = "pyrsistent-0.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win32.whl", hash = "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf"}, - {file = "pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b"}, - {file = "pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4"}, -] - -[[package]] -name = "pytesseract" -version = "0.3.10" -description = "Python-tesseract is a python wrapper for Google's Tesseract-OCR" -optional = true -python-versions = ">=3.7" -files = [ - {file = "pytesseract-0.3.10-py3-none-any.whl", hash = "sha256:8f22cc98f765bf13517ead0c70effedb46c153540d25783e04014f28b55a5fc6"}, - {file = "pytesseract-0.3.10.tar.gz", hash = "sha256:f1c3a8b0f07fd01a1085d451f5b8315be6eec1d5577a6796d46dc7a62bd4120f"}, -] - -[package.dependencies] -packaging = ">=21.3" -Pillow = ">=8.0.0" - -[[package]] -name = "pytest" -version = "7.4.4" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, - {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} - -[package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-cov" -version = "5.0.0" -description = "Pytest plugin for measuring coverage." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, - {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, -] - -[package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} -pytest = ">=4.6" - -[package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] - -[[package]] -name = "pytest-httpserver" -version = "1.1.0" -description = "pytest-httpserver is a httpserver for pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest_httpserver-1.1.0-py3-none-any.whl", hash = "sha256:7ef88be8ed3354b6784daa3daa75a422370327c634053cefb124903fa8d73a41"}, - {file = "pytest_httpserver-1.1.0.tar.gz", hash = "sha256:6b1cb0199e2ed551b1b94d43f096863bbf6ae5bcd7c75c2c06845e5ce2dc8701"}, -] - -[package.dependencies] -Werkzeug = ">=2.0.0" - -[[package]] -name = "pytest-memray" -version = "1.7.0" -description = "A simple plugin to use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest_memray-1.7.0-py3-none-any.whl", hash = "sha256:b896718c1adf6d0cd339dfaaaa5620f035c9919e1199a79b3453804a1254306f"}, - {file = "pytest_memray-1.7.0.tar.gz", hash = "sha256:c18fa907d2210b42f4096c093e2d3416dfc002dcaa450ef3f9ba819bc3dd8f5f"}, -] - -[package.dependencies] -memray = ">=1.12" -pytest = ">=7.2" - -[package.extras] -docs = ["furo (>=2022.12.7)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinx-inline-tabs (>=2022.1.2b11)", "sphinxcontrib-programoutput (>=0.17)", "towncrier (>=22.12)"] -lint = ["black (==22.12)", "isort (==5.11.4)", "mypy (==0.991)", "ruff (==0.0.272)"] -test = ["anyio (>=4.4.0)", "covdefaults (>=2.2.2)", "coverage (>=7.0.5)", "flaky (>=3.7)", "pytest (>=7.2)", "pytest-xdist (>=3.1)"] - -[[package]] -name = "pytest-mock" -version = "3.14.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, -] - -[package.dependencies] -pytest = ">=6.2.5" - -[package.extras] -dev = ["pre-commit", "pytest-asyncio", "tox"] - -[[package]] -name = "python-calamine" -version = "0.2.3" -description = "Python binding for Rust's library for reading excel and odf file - calamine" -optional = true -python-versions = ">=3.8" -files = [ - {file = "python_calamine-0.2.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:f292a03591b1cab1537424851b74baa33b0a55affc315248a7592ba3de1c3e83"}, - {file = "python_calamine-0.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6cfbd23d1147f53fd70fddfb38af2a98896ecad069c9a4120e77358a6fc43b39"}, - {file = "python_calamine-0.2.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:847373d0152bafd92b739c911de8c2d23e32ea93d9358bf32b58ed4ace382ae7"}, - {file = "python_calamine-0.2.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1e0dcdc796eb4b4907618392c4b71146812774ca30bf6162a711b63e54214912"}, - {file = "python_calamine-0.2.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2ee8250638ad174aa22a3776ebd41500cf88af62346f1c857505158d2685852"}, - {file = "python_calamine-0.2.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9ac718eb8e9753b986f329aec5dea964005a79115c622a2671fccd0c563d345a"}, - {file = "python_calamine-0.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1baf404027779cb298d15939a5268eb3d477c86a7a8f4cad0734ea513876c2"}, - {file = "python_calamine-0.2.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dc36a85f1a182e49fc318b3e91f06f390d3889ce8c843721cb03a68ca4c7e4ce"}, - {file = "python_calamine-0.2.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:11e2a74da47adc502c776e399972864802a20d358001a1cfaefb13c36a5116c0"}, - {file = "python_calamine-0.2.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f19c8eb9f2182cca54c274145b6c8409776b7c08ee5be8a61d44f0448dc55192"}, - {file = "python_calamine-0.2.3-cp310-none-win32.whl", hash = "sha256:37367f85282d87c0d9453cb3caec5a74f2720252bfbc1365d627e9fe12251e56"}, - {file = "python_calamine-0.2.3-cp310-none-win_amd64.whl", hash = "sha256:6d73ef3131b3a7c3894a533857b02fc50198fb65528cbf869742555d1497ee52"}, - {file = "python_calamine-0.2.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:e5a36cca8b447295e9edddbe055857bdfdec56cb78554455a03bacd78e3c45a0"}, - {file = "python_calamine-0.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7b5b0803c70269d93b67c42f03e5711a7ba02166fd473a6cb89ef71632167154"}, - {file = "python_calamine-0.2.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73766349215f69854afb092ef891cb1ff253f4b6611342566c469b46516c6ada"}, - {file = "python_calamine-0.2.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3bf4cf41518541016b9442082360a83f3579955a872cfca5cec50acc3101cce5"}, - {file = "python_calamine-0.2.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f1f6dab7b44deed8cf7b45a6d6d2743b622ba5e21a8b73f52ef1064cc5e3638"}, - {file = "python_calamine-0.2.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1991261d40be3d577ce48c0884c6403aefd1cbef5dcc451e039746aa1d185931"}, - {file = "python_calamine-0.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f675e7f45d9e3f1430f3114701133432c279aba06442e743220f6b648023b5ee"}, - {file = "python_calamine-0.2.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bb7444454cff2c1ad44e7f1a1be776845cbad8f1210d868c7058d2183b3da74"}, - {file = "python_calamine-0.2.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7a604306cd5ceca720f0426deb49192f2ede5eedd1597b7ff4fa9659a36dc462"}, - {file = "python_calamine-0.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b95afd1a1cd3871d472aa117537b8731c1609756347874b251300cff152176a5"}, - {file = "python_calamine-0.2.3-cp311-none-win32.whl", hash = "sha256:a0ae5a740c9d97b2842d948a91f926a0fab278d247d816fe786219b94507c5a2"}, - {file = "python_calamine-0.2.3-cp311-none-win_amd64.whl", hash = "sha256:a32c64e74673fb0203ad877c6ba4832de7976fd31c79c637552b567d295ff6b5"}, - {file = "python_calamine-0.2.3-cp311-none-win_arm64.whl", hash = "sha256:f8c4c9e7ade09b4122c59e3e0da7e5fba872a0e47d3076702185a4ffdf99dec4"}, - {file = "python_calamine-0.2.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:40e5f75c4a7bb2105e3bd65e7b4656e085c6d86e46af1c56468a2f87c2ed639a"}, - {file = "python_calamine-0.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3557bdd36060db4929f42bf4c2c728a76af60ccc95d5c98f2110331d993a7299"}, - {file = "python_calamine-0.2.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baa75b28686f9dc727d26a97b41c6a2a6ca1d2c679139b6199edbae2782e7c77"}, - {file = "python_calamine-0.2.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d2c8577b00e13f5f43b1c03a2eca01848c3b24467ebaf597729d1e483613c110"}, - {file = "python_calamine-0.2.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4639255202380251833a9ab75c077e687ebbef2120f54030b2dc46eb6ce43105"}, - {file = "python_calamine-0.2.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:583656c6a6e8efac8951cd72459e2d84eea5f2617214ebc7e1c96217b44a0fa1"}, - {file = "python_calamine-0.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68fc61b34a1d82d3eee2109d323268dd455107dfb639b027aa5c388e2781273c"}, - {file = "python_calamine-0.2.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64bb1f212275ed0288f578ee817e5cad4a063cfe5c38bf4c4dc6968957cb95b0"}, - {file = "python_calamine-0.2.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a7da299c1676dc34cd5f0adf93e92139afbfb832722d5d50a696ac180885aabb"}, - {file = "python_calamine-0.2.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:599752629ab0c5231159c5bea4f94795dd9b11a36c02dd5bd0613cf257ecd710"}, - {file = "python_calamine-0.2.3-cp312-none-win32.whl", hash = "sha256:fc73da2863c3251862583d64c0d07fe907f489a86a205e2b6ac94a39a1df1b42"}, - {file = "python_calamine-0.2.3-cp312-none-win_amd64.whl", hash = "sha256:a8d1662b4767f863c17ea4c1afc3c3fe3174d7b007ae77349d481e6792d142fe"}, - {file = "python_calamine-0.2.3-cp312-none-win_arm64.whl", hash = "sha256:87af11076364ade6f3da9e33993b6f55ec8dfd5f017129de688fd6d94d7bc24a"}, - {file = "python_calamine-0.2.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1ae98e1db1d3e74df08291f66d872bf7a4c47d96d39f8f589bff5dab873fbd13"}, - {file = "python_calamine-0.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bc270e8827191e7125600c97b61b3c78ec17d394820c2607c801f93c3475a0aa"}, - {file = "python_calamine-0.2.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c25b18eca7976aac0748fc122fa5109be66801d94b77a7676125fb825a8b67b9"}, - {file = "python_calamine-0.2.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:484330c0a917879afc615dc15e5ad925953a726f1a839ce3c35504a5befdae0c"}, - {file = "python_calamine-0.2.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c15ccb20f49eb6f824664ca8ec741edf09679977c2d41d13a02f0532f71a318b"}, - {file = "python_calamine-0.2.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19421a1b8a808333c39b03e007b74c85220700ceed1229449a21d51803d0671b"}, - {file = "python_calamine-0.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0cd8e3069c57a26eea5e6d3addb3dab812cc39b70f0cd11246d6f6592b7f293"}, - {file = "python_calamine-0.2.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d13822a6669a00da497394719a1fa63033ab79858fd653d330a6a7a681a5f6ce"}, - {file = "python_calamine-0.2.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:767db722eeb9c4d3847a87e4c3c4c9cc3e48938efaed4c507a5dd538a6bc5910"}, - {file = "python_calamine-0.2.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:4cac4095c25c64ef091fd994f62c5169f3ab0eec39c5bdbd0f319cac633b8183"}, - {file = "python_calamine-0.2.3-cp313-none-win32.whl", hash = "sha256:79aab3dc2c54525896b24002756e12fe09ec573efc2787285c244520bc17c39f"}, - {file = "python_calamine-0.2.3-cp313-none-win_amd64.whl", hash = "sha256:bd6606c893493eb555db5e63aef85b87fd806e6a0aa59bad0dbb591b88db2a0d"}, - {file = "python_calamine-0.2.3-cp313-none-win_arm64.whl", hash = "sha256:9f7b93851c941efba8387bb3c004437541230e8253230868204a079f1dacc21a"}, - {file = "python_calamine-0.2.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:5fa0395816ecff641b5df7ee3a2a953fb0f449a88f780e1c8b762b94578fdb9c"}, - {file = "python_calamine-0.2.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7397213b734e71434be06c3391ba9c23660215dc5e1c5601b8141f9f623fef84"}, - {file = "python_calamine-0.2.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be628b380f190b4140801731786f14d59d5a25c54398a724543181e6f46e71d3"}, - {file = "python_calamine-0.2.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d7fc182ebd15dd629d5c355207b125fd2301f109bc6cd2d91b1e67626fdbec1f"}, - {file = "python_calamine-0.2.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ae983b57379225f44102e0ff2f3724428174d0156ac42b1b69ed7f63ce105b1"}, - {file = "python_calamine-0.2.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98592f79f46cd2d74cd7f4e69ef2031a51138159a5852efe56fa5bc289c106b4"}, - {file = "python_calamine-0.2.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660347ae698f63f4a495b60411e913cfa448b149e7f51434934782559df6158f"}, - {file = "python_calamine-0.2.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fef87aa0b533c15e22ddb1bd6c257b3de9616c7a4ed3ca00c3c19e4cd8825d08"}, - {file = "python_calamine-0.2.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:06ab4232827eed11f6a40ddca5dd9015fe73a10c1cf71a4ab2aa26e63f3d1ffb"}, - {file = "python_calamine-0.2.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a6f64365bfc2cf6acefc3a618c7f25f64c317be3187d50dba3a2ccdbf405f911"}, - {file = "python_calamine-0.2.3-cp38-none-win32.whl", hash = "sha256:08b4b35d5943574ab44e87e4ccc2250f14ce7e8b34ad437ff95c1ae845823d0e"}, - {file = "python_calamine-0.2.3-cp38-none-win_amd64.whl", hash = "sha256:cd9b57326453be8ab52807cde90f3a61a008ed22a69489b41e9edbf66fb86a68"}, - {file = "python_calamine-0.2.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b439270ac6283a2e00abaae167ed35dececaa73f394bf5be8bf8631f3c9757fc"}, - {file = "python_calamine-0.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:38b6d1c315feaacfa95336f7d8d82bdc9fc75854ceae3dd003f075a4cf943582"}, - {file = "python_calamine-0.2.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:411812b0ffcf042be71408ae82b6fcc8dd70e2ee9ba8e8024a70242f7bce305e"}, - {file = "python_calamine-0.2.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4086c857d2cd1bf388bab6f18ca6ae453fb6618b8f3547e76447dc759b9a3a2a"}, - {file = "python_calamine-0.2.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6b43b8d0b556cb6e9fa9280cc6a61945fcef0005622590c45fa1471705476b5"}, - {file = "python_calamine-0.2.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ce29ebf7b8bd978ef7aaf7755489f67f056327a53ef112a9b24c7a90970f9467"}, - {file = "python_calamine-0.2.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:042385ce2ba386ef72bd678ed44ee6d4a5de20c9561c3cd1ecd2a57bfdc874cc"}, - {file = "python_calamine-0.2.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9e55fd471afd1c50ad88b442ef20c57d7efd38c7c300992708aa2cff943a29b9"}, - {file = "python_calamine-0.2.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4972a653bd54a4513e9419c26576429b391cdb4b417e7afa46469089ee7c10ee"}, - {file = "python_calamine-0.2.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:206524d140eb7d2999791afd4dfd62ceed531af3cfa487ff2b8b8fdc4b7c2b50"}, - {file = "python_calamine-0.2.3-cp39-none-win32.whl", hash = "sha256:e5a2c540d631343ba9f16be2afbb7b9fa187b3ced1b292ecc4cfcd51b8859bef"}, - {file = "python_calamine-0.2.3-cp39-none-win_amd64.whl", hash = "sha256:af65a13551d6575468d7cfcc61028df5d4218796dc4886419049e136148694e6"}, - {file = "python_calamine-0.2.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:10f28b56fb84bd622e23f32881fd17b07ab039e7f2cacdfb6101dce702e77970"}, - {file = "python_calamine-0.2.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d00cef2e12e4b6660b5fab13f936194263e7e11f707f7951b1867995278051df"}, - {file = "python_calamine-0.2.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7aebcbd105e49516dd1831f05a0ffca7c9b85f855bf3a9c68f9bc509a212e381"}, - {file = "python_calamine-0.2.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d5a9182590f5ad12e08a0ba9b72dfe0e6b1780ff95153926e2f4564a6018a14"}, - {file = "python_calamine-0.2.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2af3805806088acc7b4d766b58b03d08947a7100e1ef26e55509161adbb36201"}, - {file = "python_calamine-0.2.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:5283e049cc36a0e2442f72d0c2c156dc1e7dc7ca48cba02d52c5cb223525b5c3"}, - {file = "python_calamine-0.2.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:9b7d0ef322f073099ea69e4a3db8c31ff4c4f7cdf4cd333f0577ab0c9320eaf5"}, - {file = "python_calamine-0.2.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0bcd07be6953efb08340ccb19b9ae0732b104a9e672edf1ffd2d6b3cc226d815"}, - {file = "python_calamine-0.2.3-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7a8b12de6e2329643dd6b0a56570b853b94149ca7b1b323db3f69a06f61ec1e2"}, - {file = "python_calamine-0.2.3-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:cad27b0e491060dc72653ccd9288301120b23261e3e374f2401cc133547615d4"}, - {file = "python_calamine-0.2.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:303e2f2a1bdfaf428db7aca50d954667078c0cdf1b585ff090dfca2fac9107d7"}, - {file = "python_calamine-0.2.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a21187b6ebcdabdfe2113df11c2a522b9adc02bcf54bd3ba424ca8c6762cd9b"}, - {file = "python_calamine-0.2.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2773094cc62602f6bcc2acd8e905b3e2292daf6a6c24ddbc85f41065604fd9d4"}, - {file = "python_calamine-0.2.3-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:6de5646a9ec3d24b5089ed174f4dcee13620e65e20dc463097c00e803c81f86f"}, - {file = "python_calamine-0.2.3-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e976c948ab18e9fee589994b68878381e1e393d870362babf9634258deb4f13b"}, - {file = "python_calamine-0.2.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:00fdfd24d13d8b04619dd933be4888bc6a70427e217fb179f3a1f71f2e377219"}, - {file = "python_calamine-0.2.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ab7d60482520508ebf00476cde1b97011084a2e73ac49b2ca32003547e7444c9"}, - {file = "python_calamine-0.2.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00c915fc67b0b4e1ddd000d374bd808d947f2ecb0f6051a4669a77abada4b7b8"}, - {file = "python_calamine-0.2.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c869fe1b568a2a970b13dd59a58a13a81a667aff2f365a95a577555585ff14bc"}, - {file = "python_calamine-0.2.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:602ebad70b176a41f22547d6bb99a6d32a531a11dbf74720f3984e6bf98c94ab"}, - {file = "python_calamine-0.2.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f6a7c4eb79803ee7cdfd00a0b8267c60c33f25da8bb9275f6168a4dd1a54db76"}, - {file = "python_calamine-0.2.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:68275fed9dcbe90a9185c9919980933e4feea925db178461f0cdb336a2587021"}, - {file = "python_calamine-0.2.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:5efc667fd002db9482a7b9f2c70b41fa69c86e18206132be1a0adcad3c998c17"}, - {file = "python_calamine-0.2.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d2d845cbcd767c7b85c616849f0c6cd619662adb98d86af2a3fd8630d6acc48d"}, - {file = "python_calamine-0.2.3.tar.gz", hash = "sha256:d6b3858c3756629d9b4a166de0facfa6c8033fa0b73dcddd3d82144f3170c0dc"}, -] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "python-docx" -version = "1.1.2" -description = "Create, read, and update Microsoft Word .docx files." -optional = true -python-versions = ">=3.7" -files = [ - {file = "python_docx-1.1.2-py3-none-any.whl", hash = "sha256:08c20d6058916fb19853fcf080f7f42b6270d89eac9fa5f8c15f691c0017fabe"}, - {file = "python_docx-1.1.2.tar.gz", hash = "sha256:0cf1f22e95b9002addca7948e16f2cd7acdfd498047f1941ca5d293db7762efd"}, -] - -[package.dependencies] -lxml = ">=3.1.0" -typing-extensions = ">=4.9.0" - -[[package]] -name = "python-iso639" -version = "2024.10.22" -description = "ISO 639 language codes, names, and other associated information" -optional = true -python-versions = ">=3.8" -files = [ - {file = "python_iso639-2024.10.22-py3-none-any.whl", hash = "sha256:02d3ce2e01c6896b30b9cbbd3e1c8ee0d7221250b5d63ea9803e0d2a81fd1047"}, - {file = "python_iso639-2024.10.22.tar.gz", hash = "sha256:750f21b6a0bc6baa24253a3d8aae92b582bf93aa40988361cd96852c2c6d9a52"}, -] - -[package.extras] -dev = ["black (==24.10.0)", "build (==1.2.1)", "flake8 (==7.1.1)", "pytest (==8.3.3)", "requests (==2.32.3)", "twine (==5.1.1)"] - -[[package]] -name = "python-magic" -version = "0.4.27" -description = "File type identification using libmagic" -optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "python-magic-0.4.27.tar.gz", hash = "sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b"}, - {file = "python_magic-0.4.27-py2.py3-none-any.whl", hash = "sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3"}, -] - -[[package]] -name = "python-pptx" -version = "0.6.21" -description = "Generate and manipulate Open XML PowerPoint (.pptx) files" -optional = true -python-versions = "*" -files = [ - {file = "python-pptx-0.6.21.tar.gz", hash = "sha256:7798a2aaf89563565b3c7120c0acfe9aff775db0db3580544e3bf4840c2e378f"}, -] - -[package.dependencies] -lxml = ">=3.1.0" -Pillow = ">=3.3.2" -XlsxWriter = ">=0.5.7" - -[[package]] -name = "python-snappy" -version = "0.7.3" -description = "Python library for the snappy compression library from Google" -optional = true -python-versions = "*" -files = [ - {file = "python_snappy-0.7.3-py3-none-any.whl", hash = "sha256:074c0636cfcd97e7251330f428064050ac81a52c62ed884fc2ddebbb60ed7f50"}, - {file = "python_snappy-0.7.3.tar.gz", hash = "sha256:40216c1badfb2d38ac781ecb162a1d0ec40f8ee9747e610bcfefdfa79486cee3"}, -] - -[package.dependencies] -cramjam = "*" - -[[package]] -name = "pytz" -version = "2024.1" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, -] - -[[package]] -name = "pytzdata" -version = "2020.1" -description = "The Olson timezone database for Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, - {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "rapidfuzz" -version = "3.10.0" -description = "rapid fuzzy string matching" -optional = true -python-versions = ">=3.9" -files = [ - {file = "rapidfuzz-3.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:884453860de029380dded8f3c1918af2d8eb5adf8010261645c7e5c88c2b5428"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718c9bd369288aca5fa929df6dbf66fdbe9768d90940a940c0b5cdc96ade4309"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a68e3724b7dab761c01816aaa64b0903734d999d5589daf97c14ef5cc0629a8e"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1af60988d47534246d9525f77288fdd9de652608a4842815d9018570b959acc6"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3084161fc3e963056232ef8d937449a2943852e07101f5a136c8f3cfa4119217"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6cd67d3d017296d98ff505529104299f78433e4b8af31b55003d901a62bbebe9"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b11a127ac590fc991e8a02c2d7e1ac86e8141c92f78546f18b5c904064a0552c"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aadce42147fc09dcef1afa892485311e824c050352e1aa6e47f56b9b27af4cf0"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b54853c2371bf0e38d67da379519deb6fbe70055efb32f6607081641af3dc752"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ce19887268e90ee81a3957eef5e46a70ecc000713796639f83828b950343f49e"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f39a2a5ded23b9b9194ec45740dce57177b80f86c6d8eba953d3ff1a25c97766"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0ec338d5f4ad8d9339a88a08db5c23e7f7a52c2b2a10510c48a0cef1fb3f0ddc"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-win32.whl", hash = "sha256:56fd15ea8f4c948864fa5ebd9261c67cf7b89a1c517a0caef4df75446a7af18c"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:43dfc5e733808962a822ff6d9c29f3039a3cfb3620706f5953e17cfe4496724c"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-win_arm64.whl", hash = "sha256:ae7966f205b5a7fde93b44ca8fed37c1c8539328d7f179b1197de34eceaceb5f"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bb0013795b40db5cf361e6f21ee7cda09627cf294977149b50e217d7fe9a2f03"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:69ef5b363afff7150a1fbe788007e307b9802a2eb6ad92ed51ab94e6ad2674c6"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c582c46b1bb0b19f1a5f4c1312f1b640c21d78c371a6615c34025b16ee56369b"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:288f6f6e7410cacb115fb851f3f18bf0e4231eb3f6cb5bd1cec0e7b25c4d039d"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9e29a13d2fd9be3e7d8c26c7ef4ba60b5bc7efbc9dbdf24454c7e9ebba31768"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea2da0459b951ee461bd4e02b8904890bd1c4263999d291c5cd01e6620177ad4"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:457827ba82261aa2ae6ac06a46d0043ab12ba7216b82d87ae1434ec0f29736d6"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5d350864269d56f51ab81ab750c9259ae5cad3152c0680baef143dcec92206a1"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a9b8f51e08c3f983d857c3889930af9ddecc768453822076683664772d87e374"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7f3a6aa6e70fc27e4ff5c479f13cc9fc26a56347610f5f8b50396a0d344c5f55"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:803f255f10d63420979b1909ef976e7d30dec42025c9b067fc1d2040cc365a7e"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2026651761bf83a0f31495cc0f70840d5c0d54388f41316e3f9cb51bd85e49a5"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-win32.whl", hash = "sha256:4df75b3ebbb8cfdb9bf8b213b168620b88fd92d0c16a8bc9f9234630b282db59"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:f9f0bbfb6787b97c51516f3ccf97737d504db5d239ad44527673b81f598b84ab"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-win_arm64.whl", hash = "sha256:10fdad800441b9c97d471a937ba7d42625f1b530db05e572f1cb7d401d95c893"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7dc87073ba3a40dd65591a2100aa71602107443bf10770579ff9c8a3242edb94"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a425a0a868cf8e9c6e93e1cda4b758cdfd314bb9a4fc916c5742c934e3613480"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a86d5d1d75e61df060c1e56596b6b0a4422a929dff19cc3dbfd5eee762c86b61"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34f213d59219a9c3ca14e94a825f585811a68ac56b4118b4dc388b5b14afc108"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96ad46f5f56f70fab2be9e5f3165a21be58d633b90bf6e67fc52a856695e4bcf"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9178277f72d144a6c7704d7ae7fa15b7b86f0f0796f0e1049c7b4ef748a662ef"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76a35e9e19a7c883c422ffa378e9a04bc98cb3b29648c5831596401298ee51e6"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a6405d34c394c65e4f73a1d300c001f304f08e529d2ed6413b46ee3037956eb"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bd393683129f446a75d8634306aed7e377627098a1286ff3af2a4f1736742820"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b0445fa9880ead81f5a7d0efc0b9c977a947d8052c43519aceeaf56eabaf6843"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:c50bc308fa29767ed8f53a8d33b7633a9e14718ced038ed89d41b886e301da32"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e89605afebbd2d4b045bccfdc12a14b16fe8ccbae05f64b4b4c64a97dad1c891"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-win32.whl", hash = "sha256:2db9187f3acf3cd33424ecdbaad75414c298ecd1513470df7bda885dcb68cc15"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:50e3d0c72ea15391ba9531ead7f2068a67c5b18a6a365fef3127583aaadd1725"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-win_arm64.whl", hash = "sha256:9eac95b4278bd53115903d89118a2c908398ee8bdfd977ae844f1bd2b02b917c"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fe5231e8afd069c742ac5b4f96344a0fe4aff52df8e53ef87faebf77f827822c"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:886882367dbc985f5736356105798f2ae6e794e671fc605476cbe2e73838a9bb"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b33e13e537e3afd1627d421a142a12bbbe601543558a391a6fae593356842f6e"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:094c26116d55bf9c53abd840d08422f20da78ec4c4723e5024322321caedca48"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:545fc04f2d592e4350f59deb0818886c1b444ffba3bec535b4fbb97191aaf769"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:916a6abf3632e592b937c3d04c00a6efadd8fd30539cdcd4e6e4d92be7ca5d90"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb6ec40cef63b1922083d33bfef2f91fc0b0bc07b5b09bfee0b0f1717d558292"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c77a7330dd15c7eb5fd3631dc646fc96327f98db8181138766bd14d3e905f0ba"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:949b5e9eeaa4ecb4c7e9c2a4689dddce60929dd1ff9c76a889cdbabe8bbf2171"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b5363932a5aab67010ae1a6205c567d1ef256fb333bc23c27582481606be480c"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5dd6eec15b13329abe66cc241b484002ecb0e17d694491c944a22410a6a9e5e2"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79e7f98525b60b3c14524e0a4e1fedf7654657b6e02eb25f1be897ab097706f3"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-win32.whl", hash = "sha256:d29d1b9857c65f8cb3a29270732e1591b9bacf89de9d13fa764f79f07d8f1fd2"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:fa9720e56663cc3649d62b4b5f3145e94b8f5611e8a8e1b46507777249d46aad"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-win_arm64.whl", hash = "sha256:eda4c661e68dddd56c8fbfe1ca35e40dd2afd973f7ebb1605f4d151edc63dff8"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cffbc50e0767396ed483900900dd58ce4351bc0d40e64bced8694bd41864cc71"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c038b9939da3035afb6cb2f465f18163e8f070aba0482923ecff9443def67178"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca366c2e2a54e2f663f4529b189fdeb6e14d419b1c78b754ec1744f3c01070d4"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c4c82b1689b23b1b5e6a603164ed2be41b6f6de292a698b98ba2381e889eb9d"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98f6ebe28831a482981ecfeedc8237047878424ad0c1add2c7f366ba44a20452"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4bd1a7676ee2a4c8e2f7f2550bece994f9f89e58afb96088964145a83af7408b"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec9139baa3f85b65adc700eafa03ed04995ca8533dd56c924f0e458ffec044ab"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:26de93e6495078b6af4c4d93a42ca067b16cc0e95699526c82ab7d1025b4d3bf"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f3a0bda83c18195c361b5500377d0767749f128564ca95b42c8849fd475bb327"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:63e4c175cbce8c3adc22dca5e6154588ae673f6c55374d156f3dac732c88d7de"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4dd3d8443970eaa02ab5ae45ce584b061f2799cd9f7e875190e2617440c1f9d4"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e5ddb2388610799fc46abe389600625058f2a73867e63e20107c5ad5ffa57c47"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-win32.whl", hash = "sha256:2e9be5d05cd960914024412b5406fb75a82f8562f45912ff86255acbfdbfb78e"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:47aca565a39c9a6067927871973ca827023e8b65ba6c5747f4c228c8d7ddc04f"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-win_arm64.whl", hash = "sha256:b0732343cdc4273b5921268026dd7266f75466eb21873cb7635a200d9d9c3fac"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f744b5eb1469bf92dd143d36570d2bdbbdc88fe5cb0b5405e53dd34f479cbd8a"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b67cc21a14327a0eb0f47bc3d7e59ec08031c7c55220ece672f9476e7a8068d3"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fe5783676f0afba4a522c80b15e99dbf4e393c149ab610308a8ef1f04c6bcc8"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4688862f957c8629d557d084f20b2d803f8738b6c4066802a0b1cc472e088d9"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20bd153aacc244e4c907d772c703fea82754c4db14f8aa64d75ff81b7b8ab92d"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:50484d563f8bfa723c74c944b0bb15b9e054db9c889348c8c307abcbee75ab92"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5897242d455461f2c5b82d7397b29341fd11e85bf3608a522177071044784ee8"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:116c71a81e046ba56551d8ab68067ca7034d94b617545316d460a452c5c3c289"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0a547e4350d1fa32624d3eab51eff8cf329f4cae110b4ea0402486b1da8be40"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:399b9b79ccfcf50ca3bad7692bc098bb8eade88d7d5e15773b7f866c91156d0c"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7947a425d1be3e744707ee58c6cb318b93a56e08f080722dcc0347e0b7a1bb9a"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:94c48b4a2a4b1d22246f48e2b11cae01ec7d23f0c9123f8bb822839ad79d0a88"}, - {file = "rapidfuzz-3.10.0.tar.gz", hash = "sha256:6b62af27e65bb39276a66533655a2fa3c60a487b03935721c45b7809527979be"}, -] - -[package.extras] -all = ["numpy"] - -[[package]] -name = "regex" -version = "2024.9.11" -description = "Alternative regular expression module, to replace re." -optional = true -python-versions = ">=3.8" -files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-cache" -version = "1.2.1" -description = "A persistent cache for python requests" -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, - {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, -] - -[package.dependencies] -attrs = ">=21.2" -cattrs = ">=22.2" -platformdirs = ">=2.5" -requests = ">=2.22" -url-normalize = ">=1.4" -urllib3 = ">=1.25.5" - -[package.extras] -all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] -bson = ["bson (>=0.5)"] -docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] -dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] -json = ["ujson (>=5.4)"] -mongodb = ["pymongo (>=3)"] -redis = ["redis (>=3)"] -security = ["itsdangerous (>=2.0)"] -yaml = ["pyyaml (>=6.0.1)"] - -[[package]] -name = "requests-mock" -version = "1.12.1" -description = "Mock out responses from the requests package" -optional = false -python-versions = ">=3.5" -files = [ - {file = "requests-mock-1.12.1.tar.gz", hash = "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401"}, - {file = "requests_mock-1.12.1-py2.py3-none-any.whl", hash = "sha256:b1e37054004cdd5e56c84454cc7df12b25f90f382159087f4b6915aaeef39563"}, -] - -[package.dependencies] -requests = ">=2.22,<3" - -[package.extras] -fixture = ["fixtures"] - -[[package]] -name = "requests-toolbelt" -version = "1.0.0" -description = "A utility belt for advanced users of python-requests" -optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, - {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, -] - -[package.dependencies] -requests = ">=2.0.1,<3.0.0" - -[[package]] -name = "rich" -version = "13.9.3" -description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "rich-13.9.3-py3-none-any.whl", hash = "sha256:9836f5096eb2172c9e77df411c1b009bace4193d6a481d534fea75ebba758283"}, - {file = "rich-13.9.3.tar.gz", hash = "sha256:bc1e01b899537598cf02579d2b9f4a415104d3fc439313a7a2c165d76557a08e"}, -] - -[package.dependencies] -markdown-it-py = ">=2.2.0" -pygments = ">=2.13.0,<3.0.0" -typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.11\""} - -[package.extras] -jupyter = ["ipywidgets (>=7.5.1,<9)"] - -[[package]] -name = "scikit-learn" -version = "1.5.2" -description = "A set of python modules for machine learning and data mining" -optional = true -python-versions = ">=3.9" -files = [ - {file = "scikit_learn-1.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:299406827fb9a4f862626d0fe6c122f5f87f8910b86fe5daa4c32dcd742139b6"}, - {file = "scikit_learn-1.5.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:2d4cad1119c77930b235579ad0dc25e65c917e756fe80cab96aa3b9428bd3fb0"}, - {file = "scikit_learn-1.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c412ccc2ad9bf3755915e3908e677b367ebc8d010acbb3f182814524f2e5540"}, - {file = "scikit_learn-1.5.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a686885a4b3818d9e62904d91b57fa757fc2bed3e465c8b177be652f4dd37c8"}, - {file = "scikit_learn-1.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:c15b1ca23d7c5f33cc2cb0a0d6aaacf893792271cddff0edbd6a40e8319bc113"}, - {file = "scikit_learn-1.5.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:03b6158efa3faaf1feea3faa884c840ebd61b6484167c711548fce208ea09445"}, - {file = "scikit_learn-1.5.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:1ff45e26928d3b4eb767a8f14a9a6efbf1cbff7c05d1fb0f95f211a89fd4f5de"}, - {file = "scikit_learn-1.5.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f763897fe92d0e903aa4847b0aec0e68cadfff77e8a0687cabd946c89d17e675"}, - {file = "scikit_learn-1.5.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8b0ccd4a902836493e026c03256e8b206656f91fbcc4fde28c57a5b752561f1"}, - {file = "scikit_learn-1.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:6c16d84a0d45e4894832b3c4d0bf73050939e21b99b01b6fd59cbb0cf39163b6"}, - {file = "scikit_learn-1.5.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f932a02c3f4956dfb981391ab24bda1dbd90fe3d628e4b42caef3e041c67707a"}, - {file = "scikit_learn-1.5.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:3b923d119d65b7bd555c73be5423bf06c0105678ce7e1f558cb4b40b0a5502b1"}, - {file = "scikit_learn-1.5.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f60021ec1574e56632be2a36b946f8143bf4e5e6af4a06d85281adc22938e0dd"}, - {file = "scikit_learn-1.5.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:394397841449853c2290a32050382edaec3da89e35b3e03d6cc966aebc6a8ae6"}, - {file = "scikit_learn-1.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:57cc1786cfd6bd118220a92ede80270132aa353647684efa385a74244a41e3b1"}, - {file = "scikit_learn-1.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:757c7d514ddb00ae249832fe87100d9c73c6ea91423802872d9e74970a0e40b9"}, - {file = "scikit_learn-1.5.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:52788f48b5d8bca5c0736c175fa6bdaab2ef00a8f536cda698db61bd89c551c1"}, - {file = "scikit_learn-1.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:643964678f4b5fbdc95cbf8aec638acc7aa70f5f79ee2cdad1eec3df4ba6ead8"}, - {file = "scikit_learn-1.5.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca64b3089a6d9b9363cd3546f8978229dcbb737aceb2c12144ee3f70f95684b7"}, - {file = "scikit_learn-1.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:3bed4909ba187aca80580fe2ef370d9180dcf18e621a27c4cf2ef10d279a7efe"}, - {file = "scikit_learn-1.5.2.tar.gz", hash = "sha256:b4237ed7b3fdd0a4882792e68ef2545d5baa50aca3bb45aa7df468138ad8f94d"}, -] - -[package.dependencies] -joblib = ">=1.2.0" -numpy = ">=1.19.5" -scipy = ">=1.6.0" -threadpoolctl = ">=3.1.0" - -[package.extras] -benchmark = ["matplotlib (>=3.3.4)", "memory_profiler (>=0.57.0)", "pandas (>=1.1.5)"] -build = ["cython (>=3.0.10)", "meson-python (>=0.16.0)", "numpy (>=1.19.5)", "scipy (>=1.6.0)"] -docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.3.4)", "memory_profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "polars (>=0.20.30)", "pooch (>=1.6.0)", "pydata-sphinx-theme (>=0.15.3)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)", "sphinx (>=7.3.7)", "sphinx-copybutton (>=0.5.2)", "sphinx-design (>=0.5.0)", "sphinx-design (>=0.6.0)", "sphinx-gallery (>=0.16.0)", "sphinx-prompt (>=1.4.0)", "sphinx-remove-toctrees (>=1.0.0.post1)", "sphinxcontrib-sass (>=0.3.4)", "sphinxext-opengraph (>=0.9.1)"] -examples = ["matplotlib (>=3.3.4)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)"] -install = ["joblib (>=1.2.0)", "numpy (>=1.19.5)", "scipy (>=1.6.0)", "threadpoolctl (>=3.1.0)"] -maintenance = ["conda-lock (==2.5.6)"] -tests = ["black (>=24.3.0)", "matplotlib (>=3.3.4)", "mypy (>=1.9)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "polars (>=0.20.30)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pyarrow (>=12.0.0)", "pytest (>=7.1.2)", "pytest-cov (>=2.9.0)", "ruff (>=0.2.1)", "scikit-image (>=0.17.2)"] - -[[package]] -name = "scipy" -version = "1.14.1" -description = "Fundamental algorithms for scientific computing in Python" -optional = true -python-versions = ">=3.10" -files = [ - {file = "scipy-1.14.1-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:b28d2ca4add7ac16ae8bb6632a3c86e4b9e4d52d3e34267f6e1b0c1f8d87e389"}, - {file = "scipy-1.14.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d0d2821003174de06b69e58cef2316a6622b60ee613121199cb2852a873f8cf3"}, - {file = "scipy-1.14.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8bddf15838ba768bb5f5083c1ea012d64c9a444e16192762bd858f1e126196d0"}, - {file = "scipy-1.14.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:97c5dddd5932bd2a1a31c927ba5e1463a53b87ca96b5c9bdf5dfd6096e27efc3"}, - {file = "scipy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ff0a7e01e422c15739ecd64432743cf7aae2b03f3084288f399affcefe5222d"}, - {file = "scipy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e32dced201274bf96899e6491d9ba3e9a5f6b336708656466ad0522d8528f69"}, - {file = "scipy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8426251ad1e4ad903a4514712d2fa8fdd5382c978010d1c6f5f37ef286a713ad"}, - {file = "scipy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:a49f6ed96f83966f576b33a44257d869756df6cf1ef4934f59dd58b25e0327e5"}, - {file = "scipy-1.14.1-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:2da0469a4ef0ecd3693761acbdc20f2fdeafb69e6819cc081308cc978153c675"}, - {file = "scipy-1.14.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:c0ee987efa6737242745f347835da2cc5bb9f1b42996a4d97d5c7ff7928cb6f2"}, - {file = "scipy-1.14.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3a1b111fac6baec1c1d92f27e76511c9e7218f1695d61b59e05e0fe04dc59617"}, - {file = "scipy-1.14.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8475230e55549ab3f207bff11ebfc91c805dc3463ef62eda3ccf593254524ce8"}, - {file = "scipy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:278266012eb69f4a720827bdd2dc54b2271c97d84255b2faaa8f161a158c3b37"}, - {file = "scipy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fef8c87f8abfb884dac04e97824b61299880c43f4ce675dd2cbeadd3c9b466d2"}, - {file = "scipy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b05d43735bb2f07d689f56f7b474788a13ed8adc484a85aa65c0fd931cf9ccd2"}, - {file = "scipy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:716e389b694c4bb564b4fc0c51bc84d381735e0d39d3f26ec1af2556ec6aad94"}, - {file = "scipy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:631f07b3734d34aced009aaf6fedfd0eb3498a97e581c3b1e5f14a04164a456d"}, - {file = "scipy-1.14.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:af29a935803cc707ab2ed7791c44288a682f9c8107bc00f0eccc4f92c08d6e07"}, - {file = "scipy-1.14.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2843f2d527d9eebec9a43e6b406fb7266f3af25a751aa91d62ff416f54170bc5"}, - {file = "scipy-1.14.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:eb58ca0abd96911932f688528977858681a59d61a7ce908ffd355957f7025cfc"}, - {file = "scipy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30ac8812c1d2aab7131a79ba62933a2a76f582d5dbbc695192453dae67ad6310"}, - {file = "scipy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f9ea80f2e65bdaa0b7627fb00cbeb2daf163caa015e59b7516395fe3bd1e066"}, - {file = "scipy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:edaf02b82cd7639db00dbff629995ef185c8df4c3ffa71a5562a595765a06ce1"}, - {file = "scipy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:2ff38e22128e6c03ff73b6bb0f85f897d2362f8c052e3b8ad00532198fbdae3f"}, - {file = "scipy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1729560c906963fc8389f6aac023739ff3983e727b1a4d87696b7bf108316a79"}, - {file = "scipy-1.14.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:4079b90df244709e675cdc8b93bfd8a395d59af40b72e339c2287c91860deb8e"}, - {file = "scipy-1.14.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e0cf28db0f24a38b2a0ca33a85a54852586e43cf6fd876365c86e0657cfe7d73"}, - {file = "scipy-1.14.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:0c2f95de3b04e26f5f3ad5bb05e74ba7f68b837133a4492414b3afd79dfe540e"}, - {file = "scipy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b99722ea48b7ea25e8e015e8341ae74624f72e5f21fc2abd45f3a93266de4c5d"}, - {file = "scipy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5149e3fd2d686e42144a093b206aef01932a0059c2a33ddfa67f5f035bdfe13e"}, - {file = "scipy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4f5a7c49323533f9103d4dacf4e4f07078f360743dec7f7596949149efeec06"}, - {file = "scipy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:baff393942b550823bfce952bb62270ee17504d02a1801d7fd0719534dfb9c84"}, - {file = "scipy-1.14.1.tar.gz", hash = "sha256:5a275584e726026a5699459aa72f828a610821006228e841b94275c4a7c08417"}, -] - -[package.dependencies] -numpy = ">=1.23.5,<2.3" - -[package.extras] -dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodestyle", "pydevtool", "rich-click", "ruff (>=0.0.292)", "types-psutil", "typing_extensions"] -doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.13.1)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0,<=7.3.7)", "sphinx-design (>=0.4.0)"] -test = ["Cython", "array-api-strict (>=2.0)", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] - -[[package]] -name = "serpyco-rs" -version = "1.11.0" -description = "" -optional = false -python-versions = ">=3.9" -files = [ - {file = "serpyco_rs-1.11.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4b2bd933539bd8c84315e2fb5ae52ef7a58ace5a6dfe3f8b73f74dc71216779e"}, - {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:627f957889ff73c4d2269fc7b6bba93212381befe03633e7cb5495de66ba9a33"}, - {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b0933620abc01434023e0e3e22255b7e4ab9b427b5a9a5ee00834656d792377a"}, - {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9ce46683d92e34abb20304817fc5ac6cb141a06fc7468dedb1d8865a8a9682f6"}, - {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bda437d86e8859bf91c189c1f4650899822f6d6d7b02b48f5729da904eb7bb7d"}, - {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a72bfbd282af17ebe76d122639013e802c09902543fdbbd828fb2159ec9755e"}, - {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d4808df5384e3e8581e31a90ba7a1fa501c0837b1f174284bb8a4555b6864ea"}, - {file = "serpyco_rs-1.11.0-cp310-none-win_amd64.whl", hash = "sha256:c7b60aef4c16d68efb0d6241f05d0a434d873d98449cbb4366b0d385f0a7172b"}, - {file = "serpyco_rs-1.11.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d47ee577cf4d69b53917615cb031ad8708eb2f59fe78194b1968c13130fc2f7"}, - {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6090d9a1487237cdd4e9362a823eede23249602019b917e7bd57846179286e79"}, - {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7192eb3df576386fefd595ea31ae25c62522841ffec7e7aeb37a80b55bdc3213"}, - {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b52ef8affb7e71b9b98a7d5216d6a7ad03b04e990acb147cd9211c8b931c5487"}, - {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3480e09e473560c60e74aaa789e6b4d079637371aae0a98235440111464bbba7"}, - {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c92e36b0ab6fe866601c2331f7e99c809a126d21963c03d8a5c29331526deed"}, - {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84f497361952d4566bc1f77e9e15a84a2614f593cc671fbf0a0fa80046f9c3d7"}, - {file = "serpyco_rs-1.11.0-cp311-none-win_amd64.whl", hash = "sha256:37fc1cf192bef9784fbf1f4e03cec21750b9e704bef55cc0442f71a715eee920"}, - {file = "serpyco_rs-1.11.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3ea93d485f03dc8b0cfb0d477f0ad2e86e78f0461b53010656ab5b4db1b41fb0"}, - {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7772410d15694b03f9c5500a2c47d62eed76e191bea4087ad042250346b1a38e"}, - {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42118463c1679846cffd2f06f47744c9b9eb33c5d0448afd88ea19e1a81a8ddd"}, - {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:79481a455b76cc56021dc55bb6d5bdda1b2b32bcb6a1ee711b597140d112e9b1"}, - {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8fd79051f9af9591fc03cf7d3033ff180416301f6a4fd3d1e3d92ebd2d68697"}, - {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d29c8f9aeed734a3b51f7349d04ec9063516ffa4e10b632d75e9b1309e4930e4"}, - {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15609158b0d9591ffa118302cd9d0039970cb3faf91dce32975f7d276e7411d5"}, - {file = "serpyco_rs-1.11.0-cp312-none-win_amd64.whl", hash = "sha256:00081eae77fbf4c5d88371c5586317ab02ccb293a330b460869a283edf2b7b69"}, - {file = "serpyco_rs-1.11.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3028893366a1985adcedb13fa8f6f98c087c185efc427f94c2ccdafa40f45832"}, - {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c18bf511316f3abf648a68ee62ef88617bec57d3fcde69466b4361102715ae5"}, - {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7dde9ef09cdfaf7c62378186b9e29f54ec76114be4c347be6a06dd559c5681e"}, - {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:18500ebc5e75285841e35585a238629a990b709e14f68933233640d15ca17d5f"}, - {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47c23132d4e03982703a7630aa09877b41e499722142f76b6153f6619b612f3"}, - {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5f8e6ba499f6a0825bee0d8f8764569d367af871b563fc6512c171474e8e5383"}, - {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15438a076047c34cff6601a977df54948e8d39d1a86f89d05c48bc60f4c12a61"}, - {file = "serpyco_rs-1.11.0-cp313-none-win_amd64.whl", hash = "sha256:84ee2c109415bd81904fc9abb9aec86a5dd13166808c21142cf23ec639f683bd"}, - {file = "serpyco_rs-1.11.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5c97c16c865261577fac4effeccc7ef5e0a1e8e35e7a3ee6c90c77c3a4cd7ff9"}, - {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47825e70f86fd6ef7c4a835dea3d6e8eef4fee354ed7b39ced99f31aba74a86e"}, - {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24d220220365110edba2f778f41ab3cf396883da0f26e1361a3ada9bd0227f73"}, - {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3a46f334af5a9d77acc6e1e58f355ae497900a2798929371f0545e274f6e6166"}, - {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d72b748acce4b4e3c7c9724e1eb33d033a1c26b08a698b393e0288060e0901"}, - {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2b8b6f205e8cc038d4d30dd0e70eece7bbecc816eb2f3787c330dc2218e232d"}, - {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:038d748bfff31f150f0c3edab2766b8843edb952cb1bd3bf547886beb0912dae"}, - {file = "serpyco_rs-1.11.0-cp39-none-win_amd64.whl", hash = "sha256:0fee1c89ec2cb013dc232e4ebef88e2844357ce8631063b56639dbfb83762f20"}, - {file = "serpyco_rs-1.11.0.tar.gz", hash = "sha256:70a844615ffb229e6e89c204b3ab7404aacaf2838911814c7d847969b8da2e3a"}, -] - -[package.dependencies] -attributes-doc = "*" -typing-extensions = "*" - -[[package]] -name = "setuptools" -version = "75.2.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = true -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - -[[package]] -name = "snowballstemmer" -version = "2.2.0" -description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -optional = true -python-versions = "*" -files = [ - {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, - {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, -] - -[[package]] -name = "soupsieve" -version = "2.6" -description = "A modern CSS selector implementation for Beautiful Soup." -optional = true -python-versions = ">=3.8" -files = [ - {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, - {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, -] - -[[package]] -name = "sphinx" -version = "4.2.0" -description = "Python documentation generator" -optional = true -python-versions = ">=3.6" -files = [ - {file = "Sphinx-4.2.0-py3-none-any.whl", hash = "sha256:98a535c62a4fcfcc362528592f69b26f7caec587d32cd55688db580be0287ae0"}, - {file = "Sphinx-4.2.0.tar.gz", hash = "sha256:94078db9184491e15bce0a56d9186e0aec95f16ac20b12d00e06d4e36f1058a6"}, -] - -[package.dependencies] -alabaster = ">=0.7,<0.8" -babel = ">=1.3" -colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.14,<0.18" -imagesize = "*" -Jinja2 = ">=2.3" -packaging = "*" -Pygments = ">=2.0" -requests = ">=2.5.0" -setuptools = "*" -snowballstemmer = ">=1.1" -sphinxcontrib-applehelp = "*" -sphinxcontrib-devhelp = "*" -sphinxcontrib-htmlhelp = ">=2.0.0" -sphinxcontrib-jsmath = "*" -sphinxcontrib-qthelp = "*" -sphinxcontrib-serializinghtml = ">=1.1.5" - -[package.extras] -docs = ["sphinxcontrib-websupport"] -lint = ["docutils-stubs", "flake8 (>=3.5.0)", "isort", "mypy (>=0.900)", "types-pkg-resources", "types-requests", "types-typed-ast"] -test = ["cython", "html5lib", "pytest", "pytest-cov", "typed-ast"] - -[[package]] -name = "sphinx-rtd-theme" -version = "1.0.0" -description = "Read the Docs theme for Sphinx" -optional = true -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" -files = [ - {file = "sphinx_rtd_theme-1.0.0-py2.py3-none-any.whl", hash = "sha256:4d35a56f4508cfee4c4fb604373ede6feae2a306731d533f409ef5c3496fdbd8"}, - {file = "sphinx_rtd_theme-1.0.0.tar.gz", hash = "sha256:eec6d497e4c2195fa0e8b2016b337532b8a699a68bcb22a512870e16925c6a5c"}, -] - -[package.dependencies] -docutils = "<0.18" -sphinx = ">=1.6" - -[package.extras] -dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client"] - -[[package]] -name = "sphinxcontrib-applehelp" -version = "2.0.0" -description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" -optional = true -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, - {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-devhelp" -version = "2.0.0" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" -optional = true -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, - {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-htmlhelp" -version = "2.1.0" -description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -optional = true -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, - {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["html5lib", "pytest"] - -[[package]] -name = "sphinxcontrib-jsmath" -version = "1.0.1" -description = "A sphinx extension which renders display math in HTML via JavaScript" -optional = true -python-versions = ">=3.5" -files = [ - {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, - {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, -] - -[package.extras] -test = ["flake8", "mypy", "pytest"] - -[[package]] -name = "sphinxcontrib-qthelp" -version = "2.0.0" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" -optional = true -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, - {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["defusedxml (>=0.7.1)", "pytest"] - -[[package]] -name = "sphinxcontrib-serializinghtml" -version = "2.0.0" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" -optional = true -python-versions = ">=3.9" -files = [ - {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, - {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["pytest"] - -[[package]] -name = "sqlalchemy" -version = "2.0.35" -description = "Database Abstraction Library" -optional = true -python-versions = ">=3.7" -files = [ - {file = "SQLAlchemy-2.0.35-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:67219632be22f14750f0d1c70e62f204ba69d28f62fd6432ba05ab295853de9b"}, - {file = "SQLAlchemy-2.0.35-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4668bd8faf7e5b71c0319407b608f278f279668f358857dbfd10ef1954ac9f90"}, - {file = "SQLAlchemy-2.0.35-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb8bea573863762bbf45d1e13f87c2d2fd32cee2dbd50d050f83f87429c9e1ea"}, - {file = "SQLAlchemy-2.0.35-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f552023710d4b93d8fb29a91fadf97de89c5926c6bd758897875435f2a939f33"}, - {file = "SQLAlchemy-2.0.35-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:016b2e665f778f13d3c438651dd4de244214b527a275e0acf1d44c05bc6026a9"}, - {file = "SQLAlchemy-2.0.35-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7befc148de64b6060937231cbff8d01ccf0bfd75aa26383ffdf8d82b12ec04ff"}, - {file = "SQLAlchemy-2.0.35-cp310-cp310-win32.whl", hash = "sha256:22b83aed390e3099584b839b93f80a0f4a95ee7f48270c97c90acd40ee646f0b"}, - {file = "SQLAlchemy-2.0.35-cp310-cp310-win_amd64.whl", hash = "sha256:a29762cd3d116585278ffb2e5b8cc311fb095ea278b96feef28d0b423154858e"}, - {file = "SQLAlchemy-2.0.35-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e21f66748ab725ade40fa7af8ec8b5019c68ab00b929f6643e1b1af461eddb60"}, - {file = "SQLAlchemy-2.0.35-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8a6219108a15fc6d24de499d0d515c7235c617b2540d97116b663dade1a54d62"}, - {file = "SQLAlchemy-2.0.35-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:042622a5306c23b972192283f4e22372da3b8ddf5f7aac1cc5d9c9b222ab3ff6"}, - {file = "SQLAlchemy-2.0.35-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:627dee0c280eea91aed87b20a1f849e9ae2fe719d52cbf847c0e0ea34464b3f7"}, - {file = "SQLAlchemy-2.0.35-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4fdcd72a789c1c31ed242fd8c1bcd9ea186a98ee8e5408a50e610edfef980d71"}, - {file = "SQLAlchemy-2.0.35-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:89b64cd8898a3a6f642db4eb7b26d1b28a497d4022eccd7717ca066823e9fb01"}, - {file = "SQLAlchemy-2.0.35-cp311-cp311-win32.whl", hash = "sha256:6a93c5a0dfe8d34951e8a6f499a9479ffb9258123551fa007fc708ae2ac2bc5e"}, - {file = "SQLAlchemy-2.0.35-cp311-cp311-win_amd64.whl", hash = "sha256:c68fe3fcde03920c46697585620135b4ecfdfc1ed23e75cc2c2ae9f8502c10b8"}, - {file = "SQLAlchemy-2.0.35-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:eb60b026d8ad0c97917cb81d3662d0b39b8ff1335e3fabb24984c6acd0c900a2"}, - {file = "SQLAlchemy-2.0.35-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6921ee01caf375363be5e9ae70d08ce7ca9d7e0e8983183080211a062d299468"}, - {file = "SQLAlchemy-2.0.35-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8cdf1a0dbe5ced887a9b127da4ffd7354e9c1a3b9bb330dce84df6b70ccb3a8d"}, - {file = "SQLAlchemy-2.0.35-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93a71c8601e823236ac0e5d087e4f397874a421017b3318fd92c0b14acf2b6db"}, - {file = "SQLAlchemy-2.0.35-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e04b622bb8a88f10e439084486f2f6349bf4d50605ac3e445869c7ea5cf0fa8c"}, - {file = "SQLAlchemy-2.0.35-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1b56961e2d31389aaadf4906d453859f35302b4eb818d34a26fab72596076bb8"}, - {file = "SQLAlchemy-2.0.35-cp312-cp312-win32.whl", hash = "sha256:0f9f3f9a3763b9c4deb8c5d09c4cc52ffe49f9876af41cc1b2ad0138878453cf"}, - {file = "SQLAlchemy-2.0.35-cp312-cp312-win_amd64.whl", hash = "sha256:25b0f63e7fcc2a6290cb5f7f5b4fc4047843504983a28856ce9b35d8f7de03cc"}, - {file = "SQLAlchemy-2.0.35-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f021d334f2ca692523aaf7bbf7592ceff70c8594fad853416a81d66b35e3abf9"}, - {file = "SQLAlchemy-2.0.35-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05c3f58cf91683102f2f0265c0db3bd3892e9eedabe059720492dbaa4f922da1"}, - {file = "SQLAlchemy-2.0.35-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:032d979ce77a6c2432653322ba4cbeabf5a6837f704d16fa38b5a05d8e21fa00"}, - {file = "SQLAlchemy-2.0.35-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:2e795c2f7d7249b75bb5f479b432a51b59041580d20599d4e112b5f2046437a3"}, - {file = "SQLAlchemy-2.0.35-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:cc32b2990fc34380ec2f6195f33a76b6cdaa9eecf09f0c9404b74fc120aef36f"}, - {file = "SQLAlchemy-2.0.35-cp37-cp37m-win32.whl", hash = "sha256:9509c4123491d0e63fb5e16199e09f8e262066e58903e84615c301dde8fa2e87"}, - {file = "SQLAlchemy-2.0.35-cp37-cp37m-win_amd64.whl", hash = "sha256:3655af10ebcc0f1e4e06c5900bb33e080d6a1fa4228f502121f28a3b1753cde5"}, - {file = "SQLAlchemy-2.0.35-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4c31943b61ed8fdd63dfd12ccc919f2bf95eefca133767db6fbbd15da62078ec"}, - {file = "SQLAlchemy-2.0.35-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a62dd5d7cc8626a3634208df458c5fe4f21200d96a74d122c83bc2015b333bc1"}, - {file = "SQLAlchemy-2.0.35-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0630774b0977804fba4b6bbea6852ab56c14965a2b0c7fc7282c5f7d90a1ae72"}, - {file = "SQLAlchemy-2.0.35-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d625eddf7efeba2abfd9c014a22c0f6b3796e0ffb48f5d5ab106568ef01ff5a"}, - {file = "SQLAlchemy-2.0.35-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ada603db10bb865bbe591939de854faf2c60f43c9b763e90f653224138f910d9"}, - {file = "SQLAlchemy-2.0.35-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c41411e192f8d3ea39ea70e0fae48762cd11a2244e03751a98bd3c0ca9a4e936"}, - {file = "SQLAlchemy-2.0.35-cp38-cp38-win32.whl", hash = "sha256:d299797d75cd747e7797b1b41817111406b8b10a4f88b6e8fe5b5e59598b43b0"}, - {file = "SQLAlchemy-2.0.35-cp38-cp38-win_amd64.whl", hash = "sha256:0375a141e1c0878103eb3d719eb6d5aa444b490c96f3fedab8471c7f6ffe70ee"}, - {file = "SQLAlchemy-2.0.35-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ccae5de2a0140d8be6838c331604f91d6fafd0735dbdcee1ac78fc8fbaba76b4"}, - {file = "SQLAlchemy-2.0.35-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2a275a806f73e849e1c309ac11108ea1a14cd7058577aba962cd7190e27c9e3c"}, - {file = "SQLAlchemy-2.0.35-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:732e026240cdd1c1b2e3ac515c7a23820430ed94292ce33806a95869c46bd139"}, - {file = "SQLAlchemy-2.0.35-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:890da8cd1941fa3dab28c5bac3b9da8502e7e366f895b3b8e500896f12f94d11"}, - {file = "SQLAlchemy-2.0.35-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c0d8326269dbf944b9201911b0d9f3dc524d64779a07518199a58384c3d37a44"}, - {file = "SQLAlchemy-2.0.35-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b76d63495b0508ab9fc23f8152bac63205d2a704cd009a2b0722f4c8e0cba8e0"}, - {file = "SQLAlchemy-2.0.35-cp39-cp39-win32.whl", hash = "sha256:69683e02e8a9de37f17985905a5eca18ad651bf592314b4d3d799029797d0eb3"}, - {file = "SQLAlchemy-2.0.35-cp39-cp39-win_amd64.whl", hash = "sha256:aee110e4ef3c528f3abbc3c2018c121e708938adeeff9006428dd7c8555e9b3f"}, - {file = "SQLAlchemy-2.0.35-py3-none-any.whl", hash = "sha256:2ab3f0336c0387662ce6221ad30ab3a5e6499aab01b9790879b6578fd9b8faa1"}, - {file = "sqlalchemy-2.0.35.tar.gz", hash = "sha256:e11d7ea4d24f0a262bccf9a7cd6284c976c5369dac21db237cff59586045ab9f"}, -] - -[package.dependencies] -greenlet = {version = "!=0.4.17", markers = "python_version < \"3.13\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} -typing-extensions = ">=4.6.0" - -[package.extras] -aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] -aioodbc = ["aioodbc", "greenlet (!=0.4.17)"] -aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] -asyncio = ["greenlet (!=0.4.17)"] -asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"] -mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"] -mssql = ["pyodbc"] -mssql-pymssql = ["pymssql"] -mssql-pyodbc = ["pyodbc"] -mypy = ["mypy (>=0.910)"] -mysql = ["mysqlclient (>=1.4.0)"] -mysql-connector = ["mysql-connector-python"] -oracle = ["cx_oracle (>=8)"] -oracle-oracledb = ["oracledb (>=1.0.1)"] -postgresql = ["psycopg2 (>=2.7)"] -postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] -postgresql-pg8000 = ["pg8000 (>=1.29.1)"] -postgresql-psycopg = ["psycopg (>=3.0.7)"] -postgresql-psycopg2binary = ["psycopg2-binary"] -postgresql-psycopg2cffi = ["psycopg2cffi"] -postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] -pymysql = ["pymysql"] -sqlcipher = ["sqlcipher3_binary"] - -[[package]] -name = "tabulate" -version = "0.9.0" -description = "Pretty-print tabular data" -optional = true -python-versions = ">=3.7" -files = [ - {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, - {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, -] - -[package.extras] -widechars = ["wcwidth"] - -[[package]] -name = "tenacity" -version = "8.5.0" -description = "Retry code until it succeeds" -optional = true -python-versions = ">=3.8" -files = [ - {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, - {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, -] - -[package.extras] -doc = ["reno", "sphinx"] -test = ["pytest", "tornado (>=4.5)", "typeguard"] - -[[package]] -name = "textual" -version = "0.84.0" -description = "Modern Text User Interface framework" -optional = false -python-versions = "<4.0.0,>=3.8.1" -files = [ - {file = "textual-0.84.0-py3-none-any.whl", hash = "sha256:1457d2cb66ba4ea46812355f31adbb4b693424a94e69d052e4affe1dc410ec96"}, - {file = "textual-0.84.0.tar.gz", hash = "sha256:fb89717960fea7a539823fa264252f7be1c84844e4b8d27360e6d4edb36846a8"}, -] - -[package.dependencies] -markdown-it-py = {version = ">=2.1.0", extras = ["linkify", "plugins"]} -platformdirs = ">=3.6.0,<5" -rich = ">=13.3.3" -typing-extensions = ">=4.4.0,<5.0.0" - -[package.extras] -syntax = ["tree-sitter (>=0.20.1,<0.21.0)", "tree-sitter-languages (==1.10.2)"] - -[[package]] -name = "threadpoolctl" -version = "3.5.0" -description = "threadpoolctl" -optional = true -python-versions = ">=3.8" -files = [ - {file = "threadpoolctl-3.5.0-py3-none-any.whl", hash = "sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467"}, - {file = "threadpoolctl-3.5.0.tar.gz", hash = "sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107"}, -] - -[[package]] -name = "tiktoken" -version = "0.4.0" -description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" -optional = true -python-versions = ">=3.8" -files = [ - {file = "tiktoken-0.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:176cad7f053d2cc82ce7e2a7c883ccc6971840a4b5276740d0b732a2b2011f8a"}, - {file = "tiktoken-0.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:450d504892b3ac80207700266ee87c932df8efea54e05cefe8613edc963c1285"}, - {file = "tiktoken-0.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d662de1e7986d129139faf15e6a6ee7665ee103440769b8dedf3e7ba6ac37f"}, - {file = "tiktoken-0.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5727d852ead18b7927b8adf558a6f913a15c7766725b23dbe21d22e243041b28"}, - {file = "tiktoken-0.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c06cd92b09eb0404cedce3702fa866bf0d00e399439dad3f10288ddc31045422"}, - {file = "tiktoken-0.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9ec161e40ed44e4210d3b31e2ff426b4a55e8254f1023e5d2595cb60044f8ea6"}, - {file = "tiktoken-0.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:1e8fa13cf9889d2c928b9e258e9dbbbf88ab02016e4236aae76e3b4f82dd8288"}, - {file = "tiktoken-0.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bb2341836b725c60d0ab3c84970b9b5f68d4b733a7bcb80fb25967e5addb9920"}, - {file = "tiktoken-0.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ca30367ad750ee7d42fe80079d3092bd35bb266be7882b79c3bd159b39a17b0"}, - {file = "tiktoken-0.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3dc3df19ddec79435bb2a94ee46f4b9560d0299c23520803d851008445671197"}, - {file = "tiktoken-0.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d980fa066e962ef0f4dad0222e63a484c0c993c7a47c7dafda844ca5aded1f3"}, - {file = "tiktoken-0.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:329f548a821a2f339adc9fbcfd9fc12602e4b3f8598df5593cfc09839e9ae5e4"}, - {file = "tiktoken-0.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b1a038cee487931a5caaef0a2e8520e645508cde21717eacc9af3fbda097d8bb"}, - {file = "tiktoken-0.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:08efa59468dbe23ed038c28893e2a7158d8c211c3dd07f2bbc9a30e012512f1d"}, - {file = "tiktoken-0.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f3020350685e009053829c1168703c346fb32c70c57d828ca3742558e94827a9"}, - {file = "tiktoken-0.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba16698c42aad8190e746cd82f6a06769ac7edd415d62ba027ea1d99d958ed93"}, - {file = "tiktoken-0.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c15d9955cc18d0d7ffcc9c03dc51167aedae98542238b54a2e659bd25fe77ed"}, - {file = "tiktoken-0.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64e1091c7103100d5e2c6ea706f0ec9cd6dc313e6fe7775ef777f40d8c20811e"}, - {file = "tiktoken-0.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e87751b54eb7bca580126353a9cf17a8a8eaadd44edaac0e01123e1513a33281"}, - {file = "tiktoken-0.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e063b988b8ba8b66d6cc2026d937557437e79258095f52eaecfafb18a0a10c03"}, - {file = "tiktoken-0.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:9c6dd439e878172dc163fced3bc7b19b9ab549c271b257599f55afc3a6a5edef"}, - {file = "tiktoken-0.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8d1d97f83697ff44466c6bef5d35b6bcdb51e0125829a9c0ed1e6e39fb9a08fb"}, - {file = "tiktoken-0.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1b6bce7c68aa765f666474c7c11a7aebda3816b58ecafb209afa59c799b0dd2d"}, - {file = "tiktoken-0.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a73286c35899ca51d8d764bc0b4d60838627ce193acb60cc88aea60bddec4fd"}, - {file = "tiktoken-0.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0394967d2236a60fd0aacef26646b53636423cc9c70c32f7c5124ebe86f3093"}, - {file = "tiktoken-0.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:dae2af6f03ecba5f679449fa66ed96585b2fa6accb7fd57d9649e9e398a94f44"}, - {file = "tiktoken-0.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:55e251b1da3c293432179cf7c452cfa35562da286786be5a8b1ee3405c2b0dd2"}, - {file = "tiktoken-0.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:c835d0ee1f84a5aa04921717754eadbc0f0a56cf613f78dfc1cf9ad35f6c3fea"}, - {file = "tiktoken-0.4.0.tar.gz", hash = "sha256:59b20a819969735b48161ced9b92f05dc4519c17be4015cfb73b65270a243620"}, -] - -[package.dependencies] -regex = ">=2022.1.18" -requests = ">=2.26.0" - -[package.extras] -blobfile = ["blobfile (>=2)"] - -[[package]] -name = "tomli" -version = "2.0.2" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, -] - -[[package]] -name = "tqdm" -version = "4.66.5" -description = "Fast, Extensible Progress Meter" -optional = true -python-versions = ">=3.7" -files = [ - {file = "tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd"}, - {file = "tqdm-4.66.5.tar.gz", hash = "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] -notebook = ["ipywidgets (>=6)"] -slack = ["slack-sdk"] -telegram = ["requests"] - -[[package]] -name = "types-pytz" -version = "2024.2.0.20241003" -description = "Typing stubs for pytz" -optional = true -python-versions = ">=3.8" -files = [ - {file = "types-pytz-2024.2.0.20241003.tar.gz", hash = "sha256:575dc38f385a922a212bac00a7d6d2e16e141132a3c955078f4a4fd13ed6cb44"}, - {file = "types_pytz-2024.2.0.20241003-py3-none-any.whl", hash = "sha256:3e22df1336c0c6ad1d29163c8fda82736909eb977281cb823c57f8bae07118b7"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "typing-inspect" -version = "0.9.0" -description = "Runtime inspection utilities for typing module." -optional = true -python-versions = "*" -files = [ - {file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"}, - {file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"}, -] - -[package.dependencies] -mypy-extensions = ">=0.3.0" -typing-extensions = ">=3.7.4" - -[[package]] -name = "tzdata" -version = "2024.2" -description = "Provider of IANA time zone data" -optional = false -python-versions = ">=2" -files = [ - {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, - {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, -] - -[[package]] -name = "uc-micro-py" -version = "1.0.3" -description = "Micro subset of unicode data files for linkify-it-py projects." -optional = false -python-versions = ">=3.7" -files = [ - {file = "uc-micro-py-1.0.3.tar.gz", hash = "sha256:d321b92cff673ec58027c04015fcaa8bb1e005478643ff4a500882eaab88c48a"}, - {file = "uc_micro_py-1.0.3-py3-none-any.whl", hash = "sha256:db1dffff340817673d7b466ec86114a9dc0e9d4d9b5ba229d9d60e5c12600cd5"}, -] - -[package.extras] -test = ["coverage", "pytest", "pytest-cov"] - -[[package]] -name = "unstructured" -version = "0.10.27" -description = "A library that prepares raw documents for downstream ML tasks." -optional = true -python-versions = ">=3.7.0" -files = [ - {file = "unstructured-0.10.27-py3-none-any.whl", hash = "sha256:3a8a8e44302388ddc39c184059e8b4458f1cdc58032540b9af7d85f6c3eca3be"}, - {file = "unstructured-0.10.27.tar.gz", hash = "sha256:f567b5c4385993a9ab48db5563dd7b413aac4f2002bb22e6250496ea8f440f5e"}, -] - -[package.dependencies] -backoff = "*" -beautifulsoup4 = "*" -chardet = "*" -dataclasses-json = "*" -emoji = "*" -filetype = "*" -langdetect = "*" -lxml = "*" -nltk = "*" -numpy = "*" -python-docx = {version = ">=1.0.1", optional = true, markers = "extra == \"docx\""} -python-iso639 = "*" -python-magic = "*" -python-pptx = {version = "<=0.6.21", optional = true, markers = "extra == \"pptx\""} -rapidfuzz = "*" -requests = "*" -tabulate = "*" -typing-extensions = "*" - -[package.extras] -airtable = ["pyairtable"] -all-docs = ["markdown", "msg-parser", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pypandoc", "python-docx (>=1.0.1)", "python-pptx (<=0.6.21)", "unstructured-inference (==0.7.10)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] -azure = ["adlfs", "fsspec (==2023.9.1)"] -azure-cognitive-search = ["azure-search-documents"] -bedrock = ["boto3", "langchain"] -biomed = ["bs4"] -box = ["boxfs", "fsspec (==2023.9.1)"] -confluence = ["atlassian-python-api"] -csv = ["pandas"] -delta-table = ["deltalake", "fsspec (==2023.9.1)"] -discord = ["discord-py"] -doc = ["python-docx (>=1.0.1)"] -docx = ["python-docx (>=1.0.1)"] -dropbox = ["dropboxdrivefs", "fsspec (==2023.9.1)"] -elasticsearch = ["elasticsearch", "jq"] -embed-huggingface = ["huggingface", "langchain", "sentence-transformers"] -epub = ["pypandoc"] -gcs = ["bs4", "fsspec (==2023.9.1)", "gcsfs"] -github = ["pygithub (>1.58.0)"] -gitlab = ["python-gitlab"] -google-drive = ["google-api-python-client"] -huggingface = ["langdetect", "sacremoses", "sentencepiece", "torch", "transformers"] -image = ["onnx", "pdf2image", "pdfminer.six", "unstructured-inference (==0.7.10)", "unstructured.pytesseract (>=0.3.12)"] -jira = ["atlassian-python-api"] -local-inference = ["markdown", "msg-parser", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pypandoc", "python-docx (>=1.0.1)", "python-pptx (<=0.6.21)", "unstructured-inference (==0.7.10)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] -md = ["markdown"] -msg = ["msg-parser"] -notion = ["htmlBuilder", "notion-client"] -odt = ["pypandoc", "python-docx (>=1.0.1)"] -onedrive = ["Office365-REST-Python-Client (<2.4.3)", "bs4", "msal"] -openai = ["langchain", "openai", "tiktoken"] -org = ["pypandoc"] -outlook = ["Office365-REST-Python-Client (<2.4.3)", "msal"] -paddleocr = ["unstructured.paddleocr (==2.6.1.3)"] -pdf = ["onnx", "pdf2image", "pdfminer.six", "unstructured-inference (==0.7.10)", "unstructured.pytesseract (>=0.3.12)"] -ppt = ["python-pptx (<=0.6.21)"] -pptx = ["python-pptx (<=0.6.21)"] -reddit = ["praw"] -rst = ["pypandoc"] -rtf = ["pypandoc"] -s3 = ["fsspec (==2023.9.1)", "s3fs"] -salesforce = ["simple-salesforce"] -sharepoint = ["Office365-REST-Python-Client (<2.4.3)", "msal"] -slack = ["slack-sdk"] -tsv = ["pandas"] -wikipedia = ["wikipedia"] -xlsx = ["networkx", "openpyxl", "pandas", "xlrd"] - -[[package]] -name = "unstructured-pytesseract" -version = "0.3.13" -description = "Python-tesseract is a python wrapper for Google's Tesseract-OCR" -optional = true -python-versions = ">=3.8" -files = [ - {file = "unstructured.pytesseract-0.3.13-py3-none-any.whl", hash = "sha256:8001bc860470d56185176eb3ceb4623e888eba058ca3b30af79003784bc40e19"}, - {file = "unstructured.pytesseract-0.3.13.tar.gz", hash = "sha256:ff2e6391496e457dbf4b4e327f4a4577cce18921ea6570dc74bd64381b10e963"}, -] - -[package.dependencies] -packaging = ">=21.3" -Pillow = ">=8.0.0" - -[[package]] -name = "url-normalize" -version = "1.4.3" -description = "URL normalization for Python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, - {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "urllib3" -version = "2.2.3" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "wcmatch" -version = "8.4" -description = "Wildcard/glob file name matcher." -optional = false -python-versions = ">=3.7" -files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, -] - -[package.dependencies] -bracex = ">=2.1.1" - -[[package]] -name = "werkzeug" -version = "3.0.4" -description = "The comprehensive WSGI web application library." -optional = false -python-versions = ">=3.8" -files = [ - {file = "werkzeug-3.0.4-py3-none-any.whl", hash = "sha256:02c9eb92b7d6c06f31a782811505d2157837cea66aaede3e217c7c27c039476c"}, - {file = "werkzeug-3.0.4.tar.gz", hash = "sha256:34f2371506b250df4d4f84bfe7b0921e4762525762bbd936614909fe25cd7306"}, -] - -[package.dependencies] -MarkupSafe = ">=2.1.1" - -[package.extras] -watchdog = ["watchdog (>=2.3)"] - -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - -[[package]] -name = "xlsxwriter" -version = "3.2.0" -description = "A Python module for creating Excel XLSX files." -optional = true -python-versions = ">=3.6" -files = [ - {file = "XlsxWriter-3.2.0-py3-none-any.whl", hash = "sha256:ecfd5405b3e0e228219bcaf24c2ca0915e012ca9464a14048021d21a995d490e"}, - {file = "XlsxWriter-3.2.0.tar.gz", hash = "sha256:9977d0c661a72866a61f9f7a809e25ebbb0fb7036baa3b9fe74afcfca6b3cb8c"}, -] - -[[package]] -name = "xmltodict" -version = "0.13.0" -description = "Makes working with XML feel like you are working with JSON" -optional = false -python-versions = ">=3.4" -files = [ - {file = "xmltodict-0.13.0-py2.py3-none-any.whl", hash = "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"}, - {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"}, -] - -[[package]] -name = "yarl" -version = "1.16.0" -description = "Yet another URL library" -optional = true -python-versions = ">=3.9" -files = [ - {file = "yarl-1.16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:32468f41242d72b87ab793a86d92f885355bcf35b3355aa650bfa846a5c60058"}, - {file = "yarl-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:234f3a3032b505b90e65b5bc6652c2329ea7ea8855d8de61e1642b74b4ee65d2"}, - {file = "yarl-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a0296040e5cddf074c7f5af4a60f3fc42c0237440df7bcf5183be5f6c802ed5"}, - {file = "yarl-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de6c14dd7c7c0badba48157474ea1f03ebee991530ba742d381b28d4f314d6f3"}, - {file = "yarl-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b140e532fe0266003c936d017c1ac301e72ee4a3fd51784574c05f53718a55d8"}, - {file = "yarl-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:019f5d58093402aa8f6661e60fd82a28746ad6d156f6c5336a70a39bd7b162b9"}, - {file = "yarl-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c42998fd1cbeb53cd985bff0e4bc25fbe55fd6eb3a545a724c1012d69d5ec84"}, - {file = "yarl-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c7c30fb38c300fe8140df30a046a01769105e4cf4282567a29b5cdb635b66c4"}, - {file = "yarl-1.16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e49e0fd86c295e743fd5be69b8b0712f70a686bc79a16e5268386c2defacaade"}, - {file = "yarl-1.16.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:b9ca7b9147eb1365c8bab03c003baa1300599575effad765e0b07dd3501ea9af"}, - {file = "yarl-1.16.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:27e11db3f1e6a51081a981509f75617b09810529de508a181319193d320bc5c7"}, - {file = "yarl-1.16.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8994c42f4ca25df5380ddf59f315c518c81df6a68fed5bb0c159c6cb6b92f120"}, - {file = "yarl-1.16.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:542fa8e09a581bcdcbb30607c7224beff3fdfb598c798ccd28a8184ffc18b7eb"}, - {file = "yarl-1.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2bd6a51010c7284d191b79d3b56e51a87d8e1c03b0902362945f15c3d50ed46b"}, - {file = "yarl-1.16.0-cp310-cp310-win32.whl", hash = "sha256:178ccb856e265174a79f59721031060f885aca428983e75c06f78aa24b91d929"}, - {file = "yarl-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe8bba2545427418efc1929c5c42852bdb4143eb8d0a46b09de88d1fe99258e7"}, - {file = "yarl-1.16.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d8643975a0080f361639787415a038bfc32d29208a4bf6b783ab3075a20b1ef3"}, - {file = "yarl-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:676d96bafc8c2d0039cea0cd3fd44cee7aa88b8185551a2bb93354668e8315c2"}, - {file = "yarl-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d9525f03269e64310416dbe6c68d3b23e5d34aaa8f47193a1c45ac568cecbc49"}, - {file = "yarl-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b37d5ec034e668b22cf0ce1074d6c21fd2a08b90d11b1b73139b750a8b0dd97"}, - {file = "yarl-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f32c4cb7386b41936894685f6e093c8dfaf0960124d91fe0ec29fe439e201d0"}, - {file = "yarl-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b8e265a0545637492a7e12fd7038370d66c9375a61d88c5567d0e044ded9202"}, - {file = "yarl-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:789a3423f28a5fff46fbd04e339863c169ece97c827b44de16e1a7a42bc915d2"}, - {file = "yarl-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1d1f45e3e8d37c804dca99ab3cf4ab3ed2e7a62cd82542924b14c0a4f46d243"}, - {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:621280719c4c5dad4c1391160a9b88925bb8b0ff6a7d5af3224643024871675f"}, - {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ed097b26f18a1f5ff05f661dc36528c5f6735ba4ce8c9645e83b064665131349"}, - {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2f1fe2b2e3ee418862f5ebc0c0083c97f6f6625781382f828f6d4e9b614eba9b"}, - {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:87dd10bc0618991c66cee0cc65fa74a45f4ecb13bceec3c62d78ad2e42b27a16"}, - {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:4199db024b58a8abb2cfcedac7b1292c3ad421684571aeb622a02f242280e8d6"}, - {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:99a9dcd4b71dd5f5f949737ab3f356cfc058c709b4f49833aeffedc2652dac56"}, - {file = "yarl-1.16.0-cp311-cp311-win32.whl", hash = "sha256:a9394c65ae0ed95679717d391c862dece9afacd8fa311683fc8b4362ce8a410c"}, - {file = "yarl-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:5b9101f528ae0f8f65ac9d64dda2bb0627de8a50344b2f582779f32fda747c1d"}, - {file = "yarl-1.16.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4ffb7c129707dd76ced0a4a4128ff452cecf0b0e929f2668ea05a371d9e5c104"}, - {file = "yarl-1.16.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1a5e9d8ce1185723419c487758d81ac2bde693711947032cce600ca7c9cda7d6"}, - {file = "yarl-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d743e3118b2640cef7768ea955378c3536482d95550222f908f392167fe62059"}, - {file = "yarl-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26768342f256e6e3c37533bf9433f5f15f3e59e3c14b2409098291b3efaceacb"}, - {file = "yarl-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1b0796168b953bca6600c5f97f5ed407479889a36ad7d17183366260f29a6b9"}, - {file = "yarl-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:858728086914f3a407aa7979cab743bbda1fe2bdf39ffcd991469a370dd7414d"}, - {file = "yarl-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5570e6d47bcb03215baf4c9ad7bf7c013e56285d9d35013541f9ac2b372593e7"}, - {file = "yarl-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66ea8311422a7ba1fc79b4c42c2baa10566469fe5a78500d4e7754d6e6db8724"}, - {file = "yarl-1.16.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:649bddcedee692ee8a9b7b6e38582cb4062dc4253de9711568e5620d8707c2a3"}, - {file = "yarl-1.16.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:3a91654adb7643cb21b46f04244c5a315a440dcad63213033826549fa2435f71"}, - {file = "yarl-1.16.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b439cae82034ade094526a8f692b9a2b5ee936452de5e4c5f0f6c48df23f8604"}, - {file = "yarl-1.16.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:571f781ae8ac463ce30bacebfaef2c6581543776d5970b2372fbe31d7bf31a07"}, - {file = "yarl-1.16.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:aa7943f04f36d6cafc0cf53ea89824ac2c37acbdb4b316a654176ab8ffd0f968"}, - {file = "yarl-1.16.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1a5cf32539373ff39d97723e39a9283a7277cbf1224f7aef0c56c9598b6486c3"}, - {file = "yarl-1.16.0-cp312-cp312-win32.whl", hash = "sha256:a5b6c09b9b4253d6a208b0f4a2f9206e511ec68dce9198e0fbec4f160137aa67"}, - {file = "yarl-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:1208ca14eed2fda324042adf8d6c0adf4a31522fa95e0929027cd487875f0240"}, - {file = "yarl-1.16.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a5ace0177520bd4caa99295a9b6fb831d0e9a57d8e0501a22ffaa61b4c024283"}, - {file = "yarl-1.16.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7118bdb5e3ed81acaa2095cba7ec02a0fe74b52a16ab9f9ac8e28e53ee299732"}, - {file = "yarl-1.16.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38fec8a2a94c58bd47c9a50a45d321ab2285ad133adefbbadf3012c054b7e656"}, - {file = "yarl-1.16.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8791d66d81ee45866a7bb15a517b01a2bcf583a18ebf5d72a84e6064c417e64b"}, - {file = "yarl-1.16.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cf936ba67bc6c734f3aa1c01391da74ab7fc046a9f8bbfa230b8393b90cf472"}, - {file = "yarl-1.16.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1aab176dd55b59f77a63b27cffaca67d29987d91a5b615cbead41331e6b7428"}, - {file = "yarl-1.16.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:995d0759004c08abd5d1b81300a91d18c8577c6389300bed1c7c11675105a44d"}, - {file = "yarl-1.16.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1bc22e00edeb068f71967ab99081e9406cd56dbed864fc3a8259442999d71552"}, - {file = "yarl-1.16.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:35b4f7842154176523e0a63c9b871168c69b98065d05a4f637fce342a6a2693a"}, - {file = "yarl-1.16.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:7ace71c4b7a0c41f317ae24be62bb61e9d80838d38acb20e70697c625e71f120"}, - {file = "yarl-1.16.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8f639e3f5795a6568aa4f7d2ac6057c757dcd187593679f035adbf12b892bb00"}, - {file = "yarl-1.16.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e8be3aff14f0120ad049121322b107f8a759be76a6a62138322d4c8a337a9e2c"}, - {file = "yarl-1.16.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:122d8e7986043d0549e9eb23c7fd23be078be4b70c9eb42a20052b3d3149c6f2"}, - {file = "yarl-1.16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0fd9c227990f609c165f56b46107d0bc34553fe0387818c42c02f77974402c36"}, - {file = "yarl-1.16.0-cp313-cp313-win32.whl", hash = "sha256:595ca5e943baed31d56b33b34736461a371c6ea0038d3baec399949dd628560b"}, - {file = "yarl-1.16.0-cp313-cp313-win_amd64.whl", hash = "sha256:921b81b8d78f0e60242fb3db615ea3f368827a76af095d5a69f1c3366db3f596"}, - {file = "yarl-1.16.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab2b2ac232110a1fdb0d3ffcd087783edd3d4a6ced432a1bf75caf7b7be70916"}, - {file = "yarl-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7f8713717a09acbfee7c47bfc5777e685539fefdd34fa72faf504c8be2f3df4e"}, - {file = "yarl-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cdcffe1dbcb4477d2b4202f63cd972d5baa155ff5a3d9e35801c46a415b7f71a"}, - {file = "yarl-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a91217208306d82357c67daeef5162a41a28c8352dab7e16daa82e3718852a7"}, - {file = "yarl-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ab3ed42c78275477ea8e917491365e9a9b69bb615cb46169020bd0aa5e2d6d3"}, - {file = "yarl-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:707ae579ccb3262dfaef093e202b4c3fb23c3810e8df544b1111bd2401fd7b09"}, - {file = "yarl-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad7a852d1cd0b8d8b37fc9d7f8581152add917a98cfe2ea6e241878795f917ae"}, - {file = "yarl-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3f1cc3d3d4dc574bebc9b387f6875e228ace5748a7c24f49d8f01ac1bc6c31b"}, - {file = "yarl-1.16.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5ff96da263740779b0893d02b718293cc03400c3a208fc8d8cd79d9b0993e532"}, - {file = "yarl-1.16.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:3d375a19ba2bfe320b6d873f3fb165313b002cef8b7cc0a368ad8b8a57453837"}, - {file = "yarl-1.16.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:62c7da0ad93a07da048b500514ca47b759459ec41924143e2ddb5d7e20fd3db5"}, - {file = "yarl-1.16.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:147b0fcd0ee33b4b5f6edfea80452d80e419e51b9a3f7a96ce98eaee145c1581"}, - {file = "yarl-1.16.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:504e1fe1cc4f170195320eb033d2b0ccf5c6114ce5bf2f617535c01699479bca"}, - {file = "yarl-1.16.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:bdcf667a5dec12a48f669e485d70c54189f0639c2157b538a4cffd24a853624f"}, - {file = "yarl-1.16.0-cp39-cp39-win32.whl", hash = "sha256:e9951afe6557c75a71045148890052cb942689ee4c9ec29f5436240e1fcc73b7"}, - {file = "yarl-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:7d7aaa8ff95d0840e289423e7dc35696c2b058d635f945bf05b5cd633146b027"}, - {file = "yarl-1.16.0-py3-none-any.whl", hash = "sha256:e6980a558d8461230c457218bd6c92dfc1d10205548215c2c21d79dc8d0a96f3"}, - {file = "yarl-1.16.0.tar.gz", hash = "sha256:b6f687ced5510a9a2474bbae96a4352e5ace5fa34dc44a217b0537fec1db00b4"}, -] - -[package.dependencies] -idna = ">=2.0" -multidict = ">=4.0" -propcache = ">=0.2.0" - -[[package]] -name = "zipp" -version = "3.20.2" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = true -python-versions = ">=3.8" -files = [ - {file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"}, - {file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] -type = ["pytest-mypy"] - -[extras] -file-based = ["avro", "fastavro", "markdown", "pdf2image", "pdfminer.six", "pyarrow", "pytesseract", "python-calamine", "python-snappy", "unstructured", "unstructured.pytesseract"] -sphinx-docs = ["Sphinx", "sphinx-rtd-theme"] -sql = ["sqlalchemy"] -vector-db-based = ["cohere", "langchain", "openai", "tiktoken"] - -[metadata] -lock-version = "2.0" -python-versions = "^3.10" -content-hash = "dd9fc46d1b293c88a5424d1ac79244003726701dce8673cfbcdcd2424a9b3476" diff --git a/airbyte-cdk/python/pyproject.toml b/airbyte-cdk/python/pyproject.toml deleted file mode 100644 index 7bec56cb0f13..000000000000 --- a/airbyte-cdk/python/pyproject.toml +++ /dev/null @@ -1,123 +0,0 @@ -[build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -name = "airbyte-cdk" -version = "5.17.0" -description = "A framework for writing Airbyte Connectors." -authors = ["Airbyte "] -license = "MIT" -readme = "README.md" -homepage = "https://github.com/airbytehq/airbyte" -repository = "https://github.com/airbytehq/airbyte" -documentation = "https://docs.airbyte.io/" -classifiers = [ - "Development Status :: 3 - Alpha", - "Intended Audience :: Developers", - "Topic :: Scientific/Engineering", - "Topic :: Software Development :: Libraries :: Python Modules", - "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3.10", -] -keywords = ["airbyte", "connector-development-kit", "cdk"] - - -[tool.poetry.dependencies] -python = "^3.10" -airbyte-protocol-models-dataclasses = "^0.13" -backoff = "*" -cachetools = "*" -Deprecated = "~1.2" -dpath = "^2.1.6" -genson = "1.2.2" -isodate = "~0.6.1" -Jinja2 = "~3.1.2" -jsonref = "~0.2" -jsonschema = "~3.2.0" -pandas = "2.2.2" -pendulum = "<3.0.0" -pydantic = "^2.7" -pyrate-limiter = "~3.1.0" -python-dateutil = "*" -PyYAML = "^6.0.1" -requests = "*" -requests_cache = "*" -wcmatch = "8.4" -# Extras depedencies -avro = { version = "~1.11.2", optional = true } -cohere = { version = "4.21", optional = true } -fastavro = { version = "~1.8.0", optional = true } -langchain = { version = "0.1.16", optional = true } -langchain_core = { version = "0.1.42", optional = true } -markdown = { version = "*", optional = true } -openai = { version = "0.27.9", extras = ["embeddings"], optional = true } -pdf2image = { version = "1.16.3", optional = true } -"pdfminer.six" = { version = "20221105", optional = true } -pyarrow = { version = "~15.0.0", optional = true } -pytesseract = { version = "0.3.10", optional = true } -python-calamine = { version = "0.2.3", optional = true } -python-snappy = { version = "0.7.3", optional = true } -Sphinx = { version = "~4.2", optional = true } -sphinx-rtd-theme = { version = "~1.0", optional = true } -tiktoken = { version = "0.4.0", optional = true } -nltk = { version = "3.8.1", optional = true } -unstructured = { version = "0.10.27", extras = ["docx", "pptx"], optional = true } -"unstructured.pytesseract" = { version = ">=0.3.12", optional = true } -pyjwt = "^2.8.0" -cryptography = "^42.0.5" -pytz = "2024.1" -orjson = "^3.10.7" -serpyco-rs = "^1.10.2" -sqlalchemy = {version = "^2.0,!=2.0.36", optional = true } -xmltodict = "^0.13.0" - -[tool.poetry.group.dev.dependencies] -freezegun = "*" -mypy = "*" -asyncio = "3.4.3" -poethepoet = "^0.24.2" -pyproject-flake8 = "^6.1.0" -pytest = "^7" -pytest-memray = "^1.6.0" -pytest-cov = "*" -pytest-httpserver = "*" -pytest-mock = "*" -requests-mock = "*" - -[tool.poetry.extras] -file-based = ["avro", "fastavro", "pyarrow", "unstructured", "pdf2image", "pdfminer.six", "unstructured.pytesseract", "pytesseract", "markdown", "python-calamine", "python-snappy"] -sphinx-docs = ["Sphinx", "sphinx-rtd-theme"] -vector-db-based = ["langchain", "openai", "cohere", "tiktoken"] -sql = ["sqlalchemy"] - -[tool.ruff] -# Setting python version to at least 3.10 avoids `from __future__ import annotations`. -target-version = "py310" -# This is consistent with airbytehq/airbyte root pyproject.toml Black rule defined. -line-length = 140 - -[tool.poe.tasks] -# Build tasks -assemble = {cmd = "bin/generate-component-manifest-dagger.sh", help = "Generate component manifest files."} -build-package = {cmd = "poetry build", help = "Build the python package: source and wheels archives."} -build = {sequence = ["assemble", "build-package"], help = "Run all tasks to build the package."} - -# Check tasks -lint = {cmd = "pflake8 --config ../../pyproject.toml ./", help = "Lint with flake8."} -type-check = {cmd = "bin/run-mypy-on-modified-files.sh", help = "Type check modified files with mypy."} -unit-test-with-cov = {cmd = "pytest -s unit_tests -c pytest.ini --cov=airbyte_cdk --cov-report=term --cov-config ../../pyproject.toml", help = "Run unit tests and create a coverage report."} -# TODO: find a version of the modified mypy check that works both locally and in CI. -check-lockfile = {cmd = "poetry check", help = "Check the poetry lock file."} -check-local = {sequence = ["lint", "type-check", "check-lockfile", "unit-test-with-cov"], help = "Lint all code, type-check modified files, and run unit tests."} -check-ci = {sequence = ["check-lockfile", "build", "lint", "unit-test-with-cov"], help = "Build the package, lint and run unit tests. Does not include type-checking."} - -# Build and check -pre-push = {sequence = ["build", "check-local"], help = "Run all build and check tasks."} - -[tool.airbyte_ci] -python_versions = ["3.10", "3.11"] -optional_poetry_groups = ["dev"] -poetry_extras = ["file-based", "sphinx-docs", "vector-db-based"] -poe_tasks = ["check-ci"] -mount_docker_socket = true diff --git a/airbyte-cdk/python/pytest.ini b/airbyte-cdk/python/pytest.ini deleted file mode 100644 index 6a5cafc1f6ec..000000000000 --- a/airbyte-cdk/python/pytest.ini +++ /dev/null @@ -1,7 +0,0 @@ -[pytest] -log_cli = 1 -log_cli_level = INFO -log_cli_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s) -log_cli_date_format=%Y-%m-%d %H:%M:%S -filterwarnings = - ignore::airbyte_cdk.sources.source.ExperimentalClassWarning diff --git a/airbyte-cdk/python/reference_docs/Makefile b/airbyte-cdk/python/reference_docs/Makefile deleted file mode 100644 index c7f9263975e8..000000000000 --- a/airbyte-cdk/python/reference_docs/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = _source -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -rst: - sphinx-apidoc -f -F -o $(SOURCEDIR)/api ../airbyte_cdk diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.destinations.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.destinations.rst deleted file mode 100644 index e554319db2fb..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.destinations.rst +++ /dev/null @@ -1,19 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.destinations.destination module --------------------------------------------- - -.. automodule:: airbyte_cdk.destinations.destination - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.destinations - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.models.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.models.rst deleted file mode 100644 index 14d3065dd76c..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.models.rst +++ /dev/null @@ -1,19 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.models.airbyte\_protocol module --------------------------------------------- - -.. automodule:: airbyte_cdk.models.airbyte_protocol - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.models - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.rst deleted file mode 100644 index 4d270b65e6ee..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.rst +++ /dev/null @@ -1,54 +0,0 @@ - -Subpackages ------------ - -.. toctree:: - :maxdepth: 4 - - airbyte_cdk.destinations - airbyte_cdk.models - airbyte_cdk.sources - airbyte_cdk.utils - -Submodules ----------- - -airbyte\_cdk.connector module ------------------------------ - -.. automodule:: airbyte_cdk.connector - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.entrypoint module ------------------------------- - -.. automodule:: airbyte_cdk.entrypoint - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.exception\_handler module --------------------------------------- - -.. automodule:: airbyte_cdk.exception_handler - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.logger module --------------------------- - -.. automodule:: airbyte_cdk.logger - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.auth.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.auth.rst deleted file mode 100644 index 43c8a518e5d7..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.auth.rst +++ /dev/null @@ -1,27 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.auth.oauth module --------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.auth.oauth - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.auth.token module --------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.auth.token - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.auth - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.checks.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.checks.rst deleted file mode 100644 index d4d275419f54..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.checks.rst +++ /dev/null @@ -1,27 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.checks.check\_stream module ------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.checks.check_stream - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.checks.connection\_checker module ------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.checks.connection_checker - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.checks - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.datetime.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.datetime.rst deleted file mode 100644 index f523d1b1736a..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.datetime.rst +++ /dev/null @@ -1,27 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.datetime.datetime\_parser module ------------------------------------------------------------------ - -.. automodule:: airbyte_cdk.sources.declarative.datetime.datetime_parser - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.datetime.min\_max\_datetime module -------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.datetime.min_max_datetime - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.datetime - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.decoders.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.decoders.rst deleted file mode 100644 index 3d4a362b1064..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.decoders.rst +++ /dev/null @@ -1,27 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.decoders.decoder module --------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.decoders.decoder - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.decoders.json\_decoder module --------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.decoders.json_decoder - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.decoders - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.extractors.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.extractors.rst deleted file mode 100644 index 3b901d5c9f1e..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.extractors.rst +++ /dev/null @@ -1,51 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.extractors.dpath\_extractor module -------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.extractors.dpath_extractor - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.extractors.http\_selector module ------------------------------------------------------------------ - -.. automodule:: airbyte_cdk.sources.declarative.extractors.http_selector - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.extractors.record\_extractor module --------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.extractors.record_extractor - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.extractors.record\_filter module ------------------------------------------------------------------ - -.. automodule:: airbyte_cdk.sources.declarative.extractors.record_filter - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.extractors.record\_selector module -------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.extractors.record_selector - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.extractors - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.interpolation.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.interpolation.rst deleted file mode 100644 index 22ab8838517b..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.interpolation.rst +++ /dev/null @@ -1,59 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.interpolation.interpolated\_boolean module ---------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.interpolation.interpolated_boolean - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.interpolation.interpolated\_mapping module ---------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.interpolation.interpolated_mapping - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.interpolation.interpolated\_string module --------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.interpolation.interpolated_string - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.interpolation.interpolation module -------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.interpolation.interpolation - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.interpolation.jinja module ------------------------------------------------------------ - -.. automodule:: airbyte_cdk.sources.declarative.interpolation.jinja - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.interpolation.macros module ------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.interpolation.macros - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.interpolation - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.parsers.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.parsers.rst deleted file mode 100644 index c5f9fdb8b8ec..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.parsers.rst +++ /dev/null @@ -1,59 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.parsers.class\_types\_registry module ----------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.parsers.class_types_registry - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.parsers.config\_parser module --------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.parsers.config_parser - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.parsers.default\_implementation\_registry module ---------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.parsers.default_implementation_registry - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.parsers.factory module -------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.parsers.factory - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.parsers.undefined\_reference\_exception module -------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.parsers.undefined_reference_exception - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.parsers.yaml\_parser module ------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.parsers.yaml_parser - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.parsers - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.rst deleted file mode 100644 index 0fa4a8c4070d..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.rst +++ /dev/null @@ -1,51 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.requesters.error\_handlers.backoff\_strategies.constant\_backoff\_strategy module ------------------------------------------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.constant_backoff_strategy - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.error\_handlers.backoff\_strategies.exponential\_backoff\_strategy module ---------------------------------------------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.exponential_backoff_strategy - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.error\_handlers.backoff\_strategies.header\_helper module ------------------------------------------------------------------------------------------------------ - -.. automodule:: airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.header_helper - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.error\_handlers.backoff\_strategies.wait\_time\_from\_header\_backoff\_strategy module ----------------------------------------------------------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.wait_time_from_header_backoff_strategy - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.error\_handlers.backoff\_strategies.wait\_until\_time\_from\_header\_backoff\_strategy module ------------------------------------------------------------------------------------------------------------------------------------------ - -.. automodule:: airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.wait_until_time_from_header_backoff_strategy - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.error_handlers.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.error_handlers.rst deleted file mode 100644 index 5b69c8b19ce7..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.error_handlers.rst +++ /dev/null @@ -1,75 +0,0 @@ - -Subpackages ------------ - -.. toctree:: - :maxdepth: 4 - - airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies - -Submodules ----------- - -airbyte\_cdk.sources.declarative.requesters.error\_handlers.backoff\_strategy module ------------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategy - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.error\_handlers.composite\_error\_handler module --------------------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.error_handlers.composite_error_handler - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.error\_handlers.default\_error\_handler module ------------------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.error_handlers.default_error_handler - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.error\_handlers.error\_handler module ---------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.error_handlers.error_handler - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.error\_handlers.http\_response\_filter module ------------------------------------------------------------------------------------------ - -.. automodule:: airbyte_cdk.sources.declarative.requesters.error_handlers.http_response_filter - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.error\_handlers.response\_action module ------------------------------------------------------------------------------------ - -.. automodule:: airbyte_cdk.sources.declarative.requesters.error_handlers.response_action - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.error\_handlers.response\_status module ------------------------------------------------------------------------------------ - -.. automodule:: airbyte_cdk.sources.declarative.requesters.error_handlers.response_status - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.error_handlers - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.paginators.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.paginators.rst deleted file mode 100644 index fd91f3f08af4..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.paginators.rst +++ /dev/null @@ -1,43 +0,0 @@ - -Subpackages ------------ - -.. toctree:: - :maxdepth: 4 - - airbyte_cdk.sources.declarative.requesters.paginators.strategies - -Submodules ----------- - -airbyte\_cdk.sources.declarative.requesters.paginators.limit\_paginator module ------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.paginators.default_paginator - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.paginators.no\_pagination module ----------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.paginators.no_pagination - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.paginators.paginator module ------------------------------------------------------------------------ - -.. automodule:: airbyte_cdk.sources.declarative.requesters.paginators.paginator - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.paginators - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.paginators.strategies.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.paginators.strategies.rst deleted file mode 100644 index 86f929120e33..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.paginators.strategies.rst +++ /dev/null @@ -1,43 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.requesters.paginators.strategies.cursor\_pagination\_strategy module ------------------------------------------------------------------------------------------------------ - -.. automodule:: airbyte_cdk.sources.declarative.requesters.paginators.strategies.cursor_pagination_strategy - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.paginators.strategies.offset\_increment module ------------------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.paginators.strategies.offset_increment - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.paginators.strategies.page\_increment module ----------------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.paginators.strategies.page_increment - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.paginators.strategies.pagination\_strategy module ---------------------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.paginators.strategies - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.request_headers.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.request_headers.rst deleted file mode 100644 index ebb492b2a50b..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.request_headers.rst +++ /dev/null @@ -1,27 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.requesters.request\_headers.interpolated\_request\_header\_provider module ------------------------------------------------------------------------------------------------------------ - -.. automodule:: airbyte_cdk.sources.declarative.requesters.request_headers.interpolated_request_header_provider - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.request\_headers.request\_header\_provider module ---------------------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.request_headers.request_header_provider - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.request_headers - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.request_options.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.request_options.rst deleted file mode 100644 index ff8eb074f6d1..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.request_options.rst +++ /dev/null @@ -1,35 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.requesters.request\_options.interpolated\_request\_input\_provider module ----------------------------------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.request_options.interpolated_request_input_provider - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.request\_options.interpolated\_request\_options\_provider module ------------------------------------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.request_options.interpolated_request_options_provider - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.request\_options.request\_options\_provider module ----------------------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.request_options - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.retriers.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.retriers.rst deleted file mode 100644 index 65e58aec2e73..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.retriers.rst +++ /dev/null @@ -1,27 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.requesters.retriers.default\_retrier module ----------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.retriers.default_retrier - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.retriers.retrier module -------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.retriers.retrier - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.retriers - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.rst deleted file mode 100644 index 63a9dc689e6e..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.requesters.rst +++ /dev/null @@ -1,45 +0,0 @@ - -Subpackages ------------ - -.. toctree:: - :maxdepth: 4 - - airbyte_cdk.sources.declarative.requesters.error_handlers - airbyte_cdk.sources.declarative.requesters.paginators - airbyte_cdk.sources.declarative.requesters.request_options - -Submodules ----------- - -airbyte\_cdk.sources.declarative.requesters.http\_requester module ------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.http_requester - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.request\_option module ------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.request_option - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.requesters.requester module ------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters.requester - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.requesters - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.retrievers.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.retrievers.rst deleted file mode 100644 index 763c663648a9..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.retrievers.rst +++ /dev/null @@ -1,27 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.retrievers.retriever module ------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.retrievers.retriever - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.retrievers.simple\_retriever module --------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.retrievers.simple_retriever - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.retrievers - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.rst deleted file mode 100644 index 0ffe29a4ae01..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.rst +++ /dev/null @@ -1,78 +0,0 @@ - -Subpackages ------------ - -.. toctree:: - :maxdepth: 4 - - airbyte_cdk.sources.declarative.auth - airbyte_cdk.sources.declarative.checks - airbyte_cdk.sources.declarative.datetime - airbyte_cdk.sources.declarative.decoders - airbyte_cdk.sources.declarative.extractors - airbyte_cdk.sources.declarative.interpolation - airbyte_cdk.sources.declarative.parsers - airbyte_cdk.sources.declarative.requesters - airbyte_cdk.sources.declarative.retrievers - airbyte_cdk.sources.declarative.schema - airbyte_cdk.sources.declarative.stream_slicers - airbyte_cdk.sources.declarative.transformations - -Submodules ----------- - -airbyte\_cdk.sources.declarative.create\_partial module -------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.create_partial - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.declarative\_source module ------------------------------------------------------------ - -.. automodule:: airbyte_cdk.sources.declarative.declarative_source - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.declarative\_stream module ------------------------------------------------------------ - -.. automodule:: airbyte_cdk.sources.declarative.declarative_stream - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.exceptions module --------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.exceptions - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.types module ---------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.types - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.yaml\_declarative\_source module ------------------------------------------------------------------ - -.. automodule:: airbyte_cdk.sources.declarative.yaml_declarative_source - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.schema.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.schema.rst deleted file mode 100644 index d0da7b6a7127..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.schema.rst +++ /dev/null @@ -1,27 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.schema.json\_schema module ------------------------------------------------------------ - -.. automodule:: airbyte_cdk.sources.declarative.schema.json_schema - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.schema.schema\_loader module -------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.schema.schema_loader - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.schema - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.states.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.states.rst deleted file mode 100644 index f4d331f8d3da..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.states.rst +++ /dev/null @@ -1,27 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.states.dict\_state module ----------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.states.dict_state - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.states.state module ----------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.states.state - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.states - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.stream_slicers.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.stream_slicers.rst deleted file mode 100644 index ed5f6c179977..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.stream_slicers.rst +++ /dev/null @@ -1,59 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.stream\_slicers.cartesian\_product\_stream\_slicer module ------------------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.stream_slicers.cartesian_product_stream_slicer - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.stream\_slicers.datetime\_stream\_slicer module --------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.stream_slicers.datetime_stream_slicer - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.stream\_slicers.list\_stream\_slicer module ----------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.stream_slicers.list_stream_slicer - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.stream\_slicers.single\_slice module ---------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.stream_slicers.single_slice - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.stream\_slicers.stream\_slicer module ----------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.stream_slicers.stream_slicer - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.stream\_slicers.substream\_slicer module -------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.stream_slicers.substream_slicer - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.stream_slicers - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.transformations.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.transformations.rst deleted file mode 100644 index 031b1af23d2c..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.declarative.transformations.rst +++ /dev/null @@ -1,35 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.declarative.transformations.add\_fields module -------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.transformations.add_fields - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.transformations.remove\_fields module ----------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.transformations.remove_fields - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.declarative.transformations.transformation module ----------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.declarative.transformations.transformation - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.declarative.transformations - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.deprecated.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.deprecated.rst deleted file mode 100644 index 3d19a99f04f0..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.deprecated.rst +++ /dev/null @@ -1,27 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.deprecated.base\_source module ---------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.deprecated.base_source - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.deprecated.client module ---------------------------------------------- - -.. automodule:: airbyte_cdk.sources.deprecated.client - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.deprecated - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.rst deleted file mode 100644 index 0a25c34ae005..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.rst +++ /dev/null @@ -1,47 +0,0 @@ - -Subpackages ------------ - -.. toctree:: - :maxdepth: 4 - - airbyte_cdk.sources.declarative - airbyte_cdk.sources.deprecated - airbyte_cdk.sources.singer - airbyte_cdk.sources.streams - airbyte_cdk.sources.utils - -Submodules ----------- - -airbyte\_cdk.sources.abstract\_source module --------------------------------------------- - -.. automodule:: airbyte_cdk.sources.abstract_source - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.config module ----------------------------------- - -.. automodule:: airbyte_cdk.sources.config - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.source module ----------------------------------- - -.. automodule:: airbyte_cdk.sources.source - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.singer.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.singer.rst deleted file mode 100644 index 37af436cbc75..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.singer.rst +++ /dev/null @@ -1,27 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.singer.singer\_helpers module --------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.singer.singer_helpers - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.singer.source module ------------------------------------------ - -.. automodule:: airbyte_cdk.sources.singer.source - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.singer - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.streams.http.auth.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.streams.http.auth.rst deleted file mode 100644 index 049da2b74e72..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.streams.http.auth.rst +++ /dev/null @@ -1,35 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.streams.http.auth.core module --------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.streams.http.auth.core - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.streams.http.auth.oauth module ---------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.streams.http.auth.oauth - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.streams.http.auth.token module ---------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.streams.http.auth.token - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.streams.http.auth - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.streams.http.requests_native_auth.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.streams.http.requests_native_auth.rst deleted file mode 100644 index b2a7bc7d8ec5..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.streams.http.requests_native_auth.rst +++ /dev/null @@ -1,43 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.streams.http.requests\_native\_auth.abstract\_oauth module -------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.streams.http.requests_native_auth.abstract_oauth - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.streams.http.requests\_native\_auth.abstract\_token module -------------------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.streams.http.requests_native_auth.abstract_token - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.streams.http.requests\_native\_auth.oauth module ---------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.streams.http.requests_native_auth.oauth - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.streams.http.requests\_native\_auth.token module ---------------------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.streams.http.requests_native_auth.token - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.streams.http.requests_native_auth - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.streams.http.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.streams.http.rst deleted file mode 100644 index 920db700aa92..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.streams.http.rst +++ /dev/null @@ -1,44 +0,0 @@ - -Subpackages ------------ - -.. toctree:: - :maxdepth: 4 - - airbyte_cdk.sources.streams.http.auth - airbyte_cdk.sources.streams.http.requests_native_auth - -Submodules ----------- - -airbyte\_cdk.sources.streams.http.exceptions module ---------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.streams.http.exceptions - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.streams.http.http module ---------------------------------------------- - -.. automodule:: airbyte_cdk.sources.streams.http.http - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.streams.http.rate\_limiting module -------------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.streams.http.rate_limiting - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.streams.http - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.streams.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.streams.rst deleted file mode 100644 index e00b5d0f36f0..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.streams.rst +++ /dev/null @@ -1,27 +0,0 @@ - -Subpackages ------------ - -.. toctree:: - :maxdepth: 4 - - airbyte_cdk.sources.streams.http - -Submodules ----------- - -airbyte\_cdk.sources.streams.core module ----------------------------------------- - -.. automodule:: airbyte_cdk.sources.streams.core - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.streams - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.utils.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.utils.rst deleted file mode 100644 index 8b53a23a7199..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.sources.utils.rst +++ /dev/null @@ -1,51 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.sources.utils.casing module ----------------------------------------- - -.. automodule:: airbyte_cdk.sources.utils.casing - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.utils.catalog\_helpers module --------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.utils.catalog_helpers - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.utils.schema\_helpers module -------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.utils.schema_helpers - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.utils.schema\_models module ------------------------------------------------- - -.. automodule:: airbyte_cdk.sources.utils.schema_models - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.sources.utils.transform module -------------------------------------------- - -.. automodule:: airbyte_cdk.sources.utils.transform - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.sources.utils - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.utils.rst b/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.utils.rst deleted file mode 100644 index d65a8f8ec055..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/airbyte_cdk.utils.rst +++ /dev/null @@ -1,35 +0,0 @@ - -Submodules ----------- - -airbyte\_cdk.utils.airbyte\_secrets\_utils module -------------------------------------------------- - -.. automodule:: airbyte_cdk.utils.airbyte_secrets_utils - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.utils.event\_timing module ---------------------------------------- - -.. automodule:: airbyte_cdk.utils.event_timing - :members: - :undoc-members: - :show-inheritance: - -airbyte\_cdk.utils.traced\_exception module -------------------------------------------- - -.. automodule:: airbyte_cdk.utils.traced_exception - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: airbyte_cdk.utils - :members: - :undoc-members: - :show-inheritance: diff --git a/airbyte-cdk/python/reference_docs/_source/api/modules.rst b/airbyte-cdk/python/reference_docs/_source/api/modules.rst deleted file mode 100644 index 453898da5f38..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/api/modules.rst +++ /dev/null @@ -1,7 +0,0 @@ -airbyte_cdk -=========== - -.. toctree:: - :maxdepth: 4 - - airbyte_cdk diff --git a/airbyte-cdk/python/reference_docs/_source/conf.py b/airbyte-cdk/python/reference_docs/_source/conf.py deleted file mode 100644 index c661adb42534..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/conf.py +++ /dev/null @@ -1,66 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os -import sys - -sys.path.insert(0, os.path.abspath("../..")) - - -# -- Project information ----------------------------------------------------- - -project = "Airbyte Connector Development Kit" -copyright = "2021, Airbyte" -author = "Airbyte" - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - "sphinx.ext.autodoc", - "sphinx.ext.napoleon", # Support for NumPy and Google style docstrings -] # API docs - -source_suffix = {".rst": "restructuredtext", ".md": "markdown"} - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = "sphinx_rtd_theme" - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -# html_static_path = ['_static'] -html_logo = "../_static/img/airbyte_new_logo.svg" -html_theme_options = { - "logo_only": True, - "display_version": False, -} diff --git a/airbyte-cdk/python/reference_docs/_source/index.rst b/airbyte-cdk/python/reference_docs/_source/index.rst deleted file mode 100644 index cc6beef3ede9..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/index.rst +++ /dev/null @@ -1,36 +0,0 @@ -Welcome to Airbyte Connector Development Kit's documentation! -============================================================= -This documentation is autogenerated from source code comments. More extensive overviews and conceptual explanations will be coming soon. -======================================================================================================================================== - -.. toctree:: - :maxdepth: 4 - :caption: Destinations - - api/airbyte_cdk.destinations - -.. toctree:: - :maxdepth: 4 - :caption: Models - - api/airbyte_cdk.models - -.. toctree:: - :maxdepth: 4 - :caption: Sources - - api/airbyte_cdk.sources - -.. toctree:: - :maxdepth: 4 - :caption: Utils - - api/airbyte_cdk.utils - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/airbyte-cdk/python/reference_docs/_source/templates/master_doc.rst_t b/airbyte-cdk/python/reference_docs/_source/templates/master_doc.rst_t deleted file mode 100644 index 082c0ce4ed8c..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/templates/master_doc.rst_t +++ /dev/null @@ -1,19 +0,0 @@ -Welcome to Airbyte Connector Development Kit's documentation! -============================================================= -This documentation is autogenerated from source code comments. More extensive overviews and conceptual explanations will be coming soon. -======================================================================================================================================== -{% for module in top_modules %} -.. toctree:: - :maxdepth: {{ maxdepth }} - :caption: {{ module.caption }} - - {{module.path}} -{% endfor %} - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/airbyte-cdk/python/reference_docs/_source/templates/package.rst_t b/airbyte-cdk/python/reference_docs/_source/templates/package.rst_t deleted file mode 100644 index 8c7700310618..000000000000 --- a/airbyte-cdk/python/reference_docs/_source/templates/package.rst_t +++ /dev/null @@ -1,51 +0,0 @@ -{%- macro automodule(modname, options) -%} -.. automodule:: {{ modname }} -{%- for option in options %} - :{{ option }}: -{%- endfor %} -{%- endmacro %} - -{%- macro toctree(docnames) -%} -.. toctree:: - :maxdepth: {{ maxdepth }} -{% for docname in docnames %} - {{ docname }} -{%- endfor %} -{%- endmacro %} - -{%- if is_namespace %} -.. py:module:: {{ pkgname }} -{% endif %} - -{%- if modulefirst and not is_namespace %} -{{ automodule(pkgname, automodule_options) }} -{% endif %} - -{%- if subpackages %} -Subpackages ------------ - -{{ toctree(subpackages) }} -{% endif %} - -{%- if submodules %} -Submodules ----------- -{% if separatemodules %} -{{ toctree(submodules) }} -{% else %} -{%- for submodule in submodules %} -{% if show_headings %} -{{- [submodule, "module"] | join(" ") | e | heading(2) }} -{% endif %} -{{ automodule(submodule, automodule_options) }} -{% endfor %} -{%- endif %} -{%- endif %} - -{%- if not modulefirst and not is_namespace %} -Module contents ---------------- - -{{ automodule(pkgname, automodule_options) }} -{% endif %} diff --git a/airbyte-cdk/python/reference_docs/_static/img/airbyte_new_logo.svg b/airbyte-cdk/python/reference_docs/_static/img/airbyte_new_logo.svg deleted file mode 100644 index 463f23913c1a..000000000000 --- a/airbyte-cdk/python/reference_docs/_static/img/airbyte_new_logo.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/airbyte-cdk/python/reference_docs/generate_rst_schema.py b/airbyte-cdk/python/reference_docs/generate_rst_schema.py deleted file mode 100755 index b401d2e4d7b3..000000000000 --- a/airbyte-cdk/python/reference_docs/generate_rst_schema.py +++ /dev/null @@ -1,46 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import sys -from os import path -from typing import Any, Dict - -from sphinx.cmd.quickstart import QuickstartRenderer -from sphinx.ext.apidoc import get_parser, main, recurse_tree, write_file -from sphinx.locale import __ -from sphinx.util import ensuredir - - -def write_master_file(templatedir: str, master_name: str, values: Dict, opts: Any): - template = QuickstartRenderer(templatedir=templatedir) - opts.destdir = opts.destdir[: opts.destdir.rfind("/")] - write_file(master_name, template.render(f"{templatedir}/master_doc.rst_t", values), opts) - - -if __name__ == "__main__": - parser = get_parser() - parser.add_argument("--master", metavar="MASTER", default="index", help=__("master document name")) - args = parser.parse_args(sys.argv[1:]) - - rootpath = path.abspath(args.module_path) - - # normalize opts - if args.header is None: - args.header = rootpath.split(path.sep)[-1] - if args.suffix.startswith("."): - args.suffix = args.suffix[1:] - if not path.isdir(rootpath): - print(__(f"{rootpath} is not a directory."), file=sys.stderr) - sys.exit(1) - if not args.dryrun: - ensuredir(args.destdir) - excludes = [path.abspath(exclude) for exclude in args.exclude_pattern] - modules = recurse_tree(rootpath, excludes, args, args.templatedir) - - template_values = { - "top_modules": [{"path": f"api/{module}", "caption": module.split(".")[1].title()} for module in modules if module.count(".") == 1], - "maxdepth": args.maxdepth, - } - write_master_file(templatedir=args.templatedir, master_name=args.master, values=template_values, opts=args) - main() diff --git a/airbyte-cdk/python/sphinx-docs.md b/airbyte-cdk/python/sphinx-docs.md deleted file mode 100644 index 055055cf61ab..000000000000 --- a/airbyte-cdk/python/sphinx-docs.md +++ /dev/null @@ -1,96 +0,0 @@ -# Sphinx Docs - -We're using the [Sphinx](https://www.sphinx-doc.org/) library in order -to automatically generate the docs for the [airbyte-cdk](https://pypi.org/project/airbyte-cdk/). - -## Updating the docs structure (manually) - -Documentation structure is set in `airbyte-cdk/python/reference_docs/_source`, using the `.rst` files. - -See [reStructuredText docs](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html) -for the key concepts. - -Note that `index.rst` is the main index file, where we do define the layout of the main -docs page and relation to other sections. - -Each time a new module added to `airbyte-cdk/python/airbyte_cdk` module you'll need to update the Sphinx rst schema. - -Let's dive into using an example: - -- Assuming we're going to add a new package `airbyte_cdk/new_package`; -- Let this file contain a few modules: `airbyte_cdk/new_package/module1.py` and `airbyte_cdk/new_package/module2.py`; -- The above structure should be in `rst` config as: - - Add this block directly into `index.rst`: - - ``` - .. toctree:: - :maxdepth: 2 - :caption: New Package - - api/airbyte_cdk.new_package - ``` - - - Add a new file `api/airbyte_cdk.new_package.rst` with the following content: - - ``` - Submodules - ---------- - - airbyte\_cdk.new\_package.module1 module - -------------------------------------------- - - .. automodule:: airbyte_cdk.new_package.module1 - :members: - :undoc-members: - :show-inheritance: - - .. automodule:: airbyte_cdk.new_package.module2 - :members: - :undoc-members: - :show-inheritance: - - Module contents - --------------- - - .. automodule:: airbyte_cdk.models - :members: - :undoc-members: - :show-inheritance: - ``` - -For more examples see `airbyte-cdk/python/reference_docs/_source` -and read the [docs](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html). - -## Updating the docs structure (automatically) - -It's also possible to generate `.rst` files automatically using `generate_rst_schema.py` script. - -You should also update this script in order to change the docs appearance or structure. - -To generate the docs, -run `python generate_rst_schema.py -o _source/api ../../python/airbyte_cdk -f -t _source/templates` -from the `airbyte-cdk/python/reference_docs` root. - -## Building the docs locally - -After the `rst` files created to correctly represent current project structure you may build the docs locally. -This build could be useful on each `airbyte-cdk` update, especially if the package structure was changed. - -- Install Sphinx deps with `pip install ".[sphinx-docs]"`; -- Run `make html` from the `airbyte-cdk/python/reference_docs` root; -- Check out the `airbyte-cdk/python/reference_docs/_build` for the new documentation built. - -## Publishing to Read the Docs - -Our current sphinx docs setup is meant to be published to [readthedocs](https://readthedocs.org/). -So it may be useful to check our docs published at https://airbyte-cdk.readthedocs.io/en/latest/ -for the last build in case if the airbyte-cdk package was updated. - -Publishing process is automatic and implemented via the GitHub incoming webhook. -See https://docs.readthedocs.io/en/stable/webhooks.html. - -To check build logs and state, check the https://readthedocs.org/projects/airbyte-cdk/builds/. -You may also run build manually here if needed. - -Publishing configuration is placed to `.readthedocs.yaml`. -See https://docs.readthedocs.io/en/stable/config-file/v2.html for the config description. diff --git a/airbyte-cdk/python/unit_tests/__init__.py b/airbyte-cdk/python/unit_tests/__init__.py deleted file mode 100644 index 51e56f3ad0e1..000000000000 --- a/airbyte-cdk/python/unit_tests/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# THIS STOPS SOME MODELS TESTS FROM FALLING OVER. IT'S A HACK, WE SHOULD PIN DOWN WHAT'S ACTUALLY GOING ON HERE - -# Import the thing that needs to be imported to stop the tests from falling over -from airbyte_cdk.sources.declarative.manifest_declarative_source import ManifestDeclarativeSource - -# "Use" the thing so that the linter doesn't complain -placeholder = ManifestDeclarativeSource diff --git a/airbyte-cdk/python/unit_tests/conftest.py b/airbyte-cdk/python/unit_tests/conftest.py deleted file mode 100644 index ab0c9bb847a4..000000000000 --- a/airbyte-cdk/python/unit_tests/conftest.py +++ /dev/null @@ -1,33 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import datetime - -import freezegun -import pytest - - -@pytest.fixture() -def mock_sleep(monkeypatch): - with freezegun.freeze_time(datetime.datetime.now(), ignore=["_pytest.runner", "_pytest.terminal"]) as frozen_datetime: - monkeypatch.setattr("time.sleep", lambda x: frozen_datetime.tick(x)) - yield - - -def pytest_addoption(parser): - parser.addoption( - "--skipslow", action="store_true", default=False, help="skip slow tests" - ) - - -def pytest_configure(config): - config.addinivalue_line("markers", "slow: mark test as slow to run") - - -def pytest_collection_modifyitems(config, items): - if config.getoption("--skipslow"): - skip_slow = pytest.mark.skip(reason="--skipslow option has been provided and this test is marked as slow") - for item in items: - if "slow" in item.keywords: - item.add_marker(skip_slow) diff --git a/airbyte-cdk/python/unit_tests/connector_builder/__init__.py b/airbyte-cdk/python/unit_tests/connector_builder/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-cdk/python/unit_tests/connector_builder/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/connector_builder/test_connector_builder_handler.py b/airbyte-cdk/python/unit_tests/connector_builder/test_connector_builder_handler.py deleted file mode 100644 index 7189c8027d85..000000000000 --- a/airbyte-cdk/python/unit_tests/connector_builder/test_connector_builder_handler.py +++ /dev/null @@ -1,994 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import copy -import dataclasses -import json -import logging -import os -from unittest import mock -from unittest.mock import MagicMock, patch - -import pytest -import requests -from airbyte_cdk import connector_builder -from airbyte_cdk.connector_builder.connector_builder_handler import ( - DEFAULT_MAXIMUM_NUMBER_OF_PAGES_PER_SLICE, - DEFAULT_MAXIMUM_NUMBER_OF_SLICES, - DEFAULT_MAXIMUM_RECORDS, - TestReadLimits, - create_source, - get_limits, - resolve_manifest, -) -from airbyte_cdk.connector_builder.main import handle_connector_builder_request, handle_request, read_stream -from airbyte_cdk.connector_builder.models import LogMessage, StreamRead, StreamReadPages, StreamReadSlices -from airbyte_cdk.models import ( - AirbyteLogMessage, - AirbyteMessage, - AirbyteMessageSerializer, - AirbyteRecordMessage, - AirbyteStateMessage, - AirbyteStream, - AirbyteStreamState, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteCatalogSerializer, - ConfiguredAirbyteStream, - ConnectorSpecification, - DestinationSyncMode, - Level, - StreamDescriptor, - SyncMode, -) -from airbyte_cdk.models import Type -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.declarative.declarative_stream import DeclarativeStream -from airbyte_cdk.sources.declarative.manifest_declarative_source import ManifestDeclarativeSource -from airbyte_cdk.sources.declarative.retrievers import SimpleRetrieverTestReadDecorator -from airbyte_cdk.sources.declarative.retrievers.simple_retriever import SimpleRetriever -from airbyte_cdk.utils.airbyte_secrets_utils import filter_secrets, update_secrets -from orjson import orjson -from unit_tests.connector_builder.utils import create_configured_catalog - -_stream_name = "stream_with_custom_requester" -_stream_primary_key = "id" -_stream_url_base = "https://api.sendgrid.com" -_stream_options = {"name": _stream_name, "primary_key": _stream_primary_key, "url_base": _stream_url_base} -_page_size = 2 - -_A_STATE = [ - AirbyteStateMessage( - type="STREAM", stream=AirbyteStreamState(stream_descriptor=StreamDescriptor(name=_stream_name), stream_state={"key": "value"}) - ) -] - -_A_PER_PARTITION_STATE = [ - AirbyteStateMessage( - type="STREAM", - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name=_stream_name), - stream_state={ - "states": [ - { - "partition": {"key": "value"}, - "cursor": {"item_id": 0}, - }, - ], - "parent_state": {}, - }, - ), - ) -] - -MANIFEST = { - "version": "0.30.3", - "definitions": { - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": _page_size, - "page_size_option": {"inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"inject_into": "path", "type": "RequestPath"}, - "pagination_strategy": { - "type": "CursorPagination", - "cursor_value": "{{ response._metadata.next }}", - "page_size": _page_size, - }, - }, - "partition_router": { - "type": "ListPartitionRouter", - "values": ["0", "1", "2", "3", "4", "5", "6", "7"], - "cursor_field": "item_id", - }, - "" - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"a_param": "10"}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - "streams": [ - { - "type": "DeclarativeStream", - "$parameters": _stream_options, - "retriever": "#/definitions/retriever", - }, - ], - "check": {"type": "CheckStream", "stream_names": ["lists"]}, - "spec": { - "connection_specification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": [], - "properties": {}, - "additionalProperties": True, - }, - "type": "Spec", - }, -} - -OAUTH_MANIFEST = { - "version": "0.30.3", - "definitions": { - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": _page_size, - "page_size_option": {"inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"inject_into": "path", "type": "RequestPath"}, - "pagination_strategy": { - "type": "CursorPagination", - "cursor_value": "{{ response.next }}", - "page_size": _page_size, - }, - }, - "partition_router": { - "type": "ListPartitionRouter", - "values": ["0", "1", "2", "3", "4", "5", "6", "7"], - "cursor_field": "item_id", - }, - "" - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "OAuthAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"a_param": "10"}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - "streams": [ - { - "type": "DeclarativeStream", - "$parameters": _stream_options, - "retriever": "#/definitions/retriever", - }, - ], - "check": {"type": "CheckStream", "stream_names": ["lists"]}, - "spec": { - "connection_specification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": [], - "properties": {}, - "additionalProperties": True, - }, - "type": "Spec", - }, -} - -RESOLVE_MANIFEST_CONFIG = { - "__injected_declarative_manifest": MANIFEST, - "__command": "resolve_manifest", -} - -TEST_READ_CONFIG = { - "__injected_declarative_manifest": MANIFEST, - "__command": "test_read", - "__test_read_config": {"max_pages_per_slice": 2, "max_slices": 5, "max_records": 10}, -} - -DUMMY_CATALOG = { - "streams": [ - { - "stream": { - "name": "dummy_stream", - "json_schema": {"$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": {}}, - "supported_sync_modes": ["full_refresh"], - "source_defined_cursor": False, - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite", - } - ] -} - -CONFIGURED_CATALOG = { - "streams": [ - { - "stream": { - "name": _stream_name, - "json_schema": {"$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": {}}, - "supported_sync_modes": ["full_refresh"], - "source_defined_cursor": False, - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite", - } - ] -} - -MOCK_RESPONSE = { - "result": [ - {"id": 1, "name": "Nora Moon", "position": "director"}, - {"id": 2, "name": "Hae Sung Jung", "position": "cinematographer"}, - {"id": 3, "name": "Arthur Zenneranski", "position": "composer"}, - ] -} - - -@pytest.fixture -def valid_resolve_manifest_config_file(tmp_path): - config_file = tmp_path / "config.json" - config_file.write_text(json.dumps(RESOLVE_MANIFEST_CONFIG)) - return config_file - - -@pytest.fixture -def valid_read_config_file(tmp_path): - config_file = tmp_path / "config.json" - config_file.write_text(json.dumps(TEST_READ_CONFIG)) - return config_file - - -@pytest.fixture -def dummy_catalog(tmp_path): - config_file = tmp_path / "catalog.json" - config_file.write_text(json.dumps(DUMMY_CATALOG)) - return config_file - - -@pytest.fixture -def configured_catalog(tmp_path): - config_file = tmp_path / "catalog.json" - config_file.write_text(json.dumps(CONFIGURED_CATALOG)) - return config_file - - -@pytest.fixture -def invalid_config_file(tmp_path): - invalid_config = copy.deepcopy(RESOLVE_MANIFEST_CONFIG) - invalid_config["__command"] = "bad_command" - config_file = tmp_path / "config.json" - config_file.write_text(json.dumps(invalid_config)) - return config_file - - -def _mocked_send(self, request, **kwargs) -> requests.Response: - """ - Mocks the outbound send operation to provide faster and more reliable responses compared to actual API requests - """ - response = requests.Response() - response.request = request - response.status_code = 200 - response.headers = {"header": "value"} - response_body = MOCK_RESPONSE - response._content = json.dumps(response_body).encode("utf-8") - return response - - -def test_handle_resolve_manifest(valid_resolve_manifest_config_file, dummy_catalog): - with mock.patch.object(connector_builder.main, "handle_connector_builder_request", return_value=AirbyteMessage(type=MessageType.RECORD)) as patched_handle: - handle_request(["read", "--config", str(valid_resolve_manifest_config_file), "--catalog", str(dummy_catalog)]) - assert patched_handle.call_count == 1 - - -def test_handle_test_read(valid_read_config_file, configured_catalog): - with mock.patch.object(connector_builder.main, "handle_connector_builder_request", return_value=AirbyteMessage(type=MessageType.RECORD)) as patch: - handle_request(["read", "--config", str(valid_read_config_file), "--catalog", str(configured_catalog)]) - assert patch.call_count == 1 - - -def test_resolve_manifest(valid_resolve_manifest_config_file): - config = copy.deepcopy(RESOLVE_MANIFEST_CONFIG) - command = "resolve_manifest" - config["__command"] = command - source = ManifestDeclarativeSource(MANIFEST) - limits = TestReadLimits() - resolved_manifest = handle_connector_builder_request( - source, command, config, create_configured_catalog("dummy_stream"), _A_STATE, limits - ) - - expected_resolved_manifest = { - "type": "DeclarativeSource", - "version": "0.30.3", - "definitions": { - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": _page_size, - "page_size_option": {"inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"inject_into": "path", "type": "RequestPath"}, - "pagination_strategy": { - "type": "CursorPagination", - "cursor_value": "{{ response._metadata.next }}", - "page_size": _page_size, - }, - }, - "partition_router": { - "type": "ListPartitionRouter", - "values": ["0", "1", "2", "3", "4", "5", "6", "7"], - "cursor_field": "item_id", - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"a_param": "10"}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - "streams": [ - { - "type": "DeclarativeStream", - "retriever": { - "type": "SimpleRetriever", - "paginator": { - "type": "DefaultPaginator", - "page_size": _page_size, - "page_size_option": { - "type": "RequestOption", - "inject_into": "request_parameter", - "field_name": "page_size", - "name": _stream_name, - "primary_key": _stream_primary_key, - "url_base": _stream_url_base, - "$parameters": _stream_options, - }, - "page_token_option": { - "type": "RequestPath", - "inject_into": "path", - "name": _stream_name, - "primary_key": _stream_primary_key, - "url_base": _stream_url_base, - "$parameters": _stream_options, - }, - "pagination_strategy": { - "type": "CursorPagination", - "cursor_value": "{{ response._metadata.next }}", - "name": _stream_name, - "primary_key": _stream_primary_key, - "url_base": _stream_url_base, - "$parameters": _stream_options, - "page_size": _page_size, - }, - "name": _stream_name, - "primary_key": _stream_primary_key, - "url_base": _stream_url_base, - "$parameters": _stream_options, - }, - "requester": { - "type": "HttpRequester", - "path": "/v3/marketing/lists", - "authenticator": { - "type": "BearerAuthenticator", - "api_token": "{{ config.apikey }}", - "name": _stream_name, - "primary_key": _stream_primary_key, - "url_base": _stream_url_base, - "$parameters": _stream_options, - }, - "request_parameters": {"a_param": "10"}, - "name": _stream_name, - "primary_key": _stream_primary_key, - "url_base": _stream_url_base, - "$parameters": _stream_options, - }, - "partition_router": { - "type": "ListPartitionRouter", - "values": ["0", "1", "2", "3", "4", "5", "6", "7"], - "cursor_field": "item_id", - "name": _stream_name, - "primary_key": _stream_primary_key, - "url_base": _stream_url_base, - "$parameters": _stream_options, - }, - "record_selector": { - "type": "RecordSelector", - "extractor": { - "type": "DpathExtractor", - "field_path": ["result"], - "name": _stream_name, - "primary_key": _stream_primary_key, - "url_base": _stream_url_base, - "$parameters": _stream_options, - }, - "name": _stream_name, - "primary_key": _stream_primary_key, - "url_base": _stream_url_base, - "$parameters": _stream_options, - }, - "name": _stream_name, - "primary_key": _stream_primary_key, - "url_base": _stream_url_base, - "$parameters": _stream_options, - }, - "name": _stream_name, - "primary_key": _stream_primary_key, - "url_base": _stream_url_base, - "$parameters": _stream_options, - }, - ], - "check": {"type": "CheckStream", "stream_names": ["lists"]}, - "spec": { - "connection_specification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": [], - "properties": {}, - "additionalProperties": True, - }, - "type": "Spec", - }, - } - assert resolved_manifest.record.data["manifest"] == expected_resolved_manifest - assert resolved_manifest.record.stream == "resolve_manifest" - - -def test_resolve_manifest_error_returns_error_response(): - class MockManifestDeclarativeSource: - @property - def resolved_manifest(self): - raise ValueError - - source = MockManifestDeclarativeSource() - response = resolve_manifest(source) - assert "Error resolving manifest" in response.trace.error.message - - -def test_read(): - config = TEST_READ_CONFIG - source = ManifestDeclarativeSource(MANIFEST) - - real_record = AirbyteRecordMessage(data={"id": "1234", "key": "value"}, emitted_at=1, stream=_stream_name) - stream_read = StreamRead( - logs=[{"message": "here be a log message"}], - slices=[ - StreamReadSlices( - pages=[StreamReadPages(records=[real_record], request=None, response=None)], - slice_descriptor=None, - state=None, - ) - ], - auxiliary_requests=[], - test_read_limit_reached=False, - inferred_schema=None, - inferred_datetime_formats=None, - latest_config_update={}, - ) - - expected_airbyte_message = AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage( - stream=_stream_name, - data={ - "logs": [{"message": "here be a log message"}], - "slices": [ - {"pages": [{"records": [real_record], "request": None, "response": None}], "slice_descriptor": None, "state": None} - ], - "test_read_limit_reached": False, - "auxiliary_requests": [], - "inferred_schema": None, - "inferred_datetime_formats": None, - "latest_config_update": {}, - }, - emitted_at=1, - ), - ) - limits = TestReadLimits() - with patch("airbyte_cdk.connector_builder.message_grouper.MessageGrouper.get_message_groups", return_value=stream_read) as mock: - output_record = handle_connector_builder_request( - source, "test_read", config, ConfiguredAirbyteCatalogSerializer.load(CONFIGURED_CATALOG), _A_STATE, limits - ) - mock.assert_called_with(source, config, ConfiguredAirbyteCatalogSerializer.load(CONFIGURED_CATALOG), _A_STATE, limits.max_records) - output_record.record.emitted_at = 1 - assert ( - orjson.dumps(AirbyteMessageSerializer.dump(output_record)).decode() - == orjson.dumps(AirbyteMessageSerializer.dump(expected_airbyte_message)).decode() - ) - - -def test_config_update(): - manifest = copy.deepcopy(MANIFEST) - manifest["definitions"]["retriever"]["requester"]["authenticator"] = { - "type": "OAuthAuthenticator", - "token_refresh_endpoint": "https://oauth.endpoint.com/tokens/bearer", - "client_id": "{{ config['credentials']['client_id'] }}", - "client_secret": "{{ config['credentials']['client_secret'] }}", - "refresh_token": "{{ config['credentials']['refresh_token'] }}", - "refresh_token_updater": {}, - } - config = copy.deepcopy(TEST_READ_CONFIG) - config["__injected_declarative_manifest"] = manifest - config["credentials"] = { - "client_id": "a client id", - "client_secret": "a client secret", - "refresh_token": "a refresh token", - } - source = ManifestDeclarativeSource(manifest) - - refresh_request_response = { - "access_token": "an updated access token", - "refresh_token": "an updated refresh token", - "expires_in": 3600, - } - with patch( - "airbyte_cdk.sources.streams.http.requests_native_auth.SingleUseRefreshTokenOauth2Authenticator._get_refresh_access_token_response", - return_value=refresh_request_response, - ): - output = handle_connector_builder_request( - source, - "test_read", - config, - ConfiguredAirbyteCatalogSerializer.load(CONFIGURED_CATALOG), - _A_PER_PARTITION_STATE, - TestReadLimits(), - ) - assert output.record.data["latest_config_update"] - - -@patch("traceback.TracebackException.from_exception") -def test_read_returns_error_response(mock_from_exception): - class MockDeclarativeStream: - @property - def primary_key(self): - return [[]] - - @property - def cursor_field(self): - return [] - - class MockManifestDeclarativeSource: - def streams(self, config): - return [MockDeclarativeStream()] - - def read(self, logger, config, catalog, state): - raise ValueError("error_message") - - def spec(self, logger: logging.Logger) -> ConnectorSpecification: - connector_specification = mock.Mock() - connector_specification.connectionSpecification = {} - return connector_specification - - @property - def check_config_against_spec(self): - return False - - stack_trace = "a stack trace" - mock_from_exception.return_value = stack_trace - - source = MockManifestDeclarativeSource() - limits = TestReadLimits() - response = read_stream(source, TEST_READ_CONFIG, ConfiguredAirbyteCatalogSerializer.load(CONFIGURED_CATALOG), _A_STATE, limits) - - expected_stream_read = StreamRead( - logs=[LogMessage("error_message", "ERROR", "error_message", "a stack trace")], - slices=[], - test_read_limit_reached=False, - auxiliary_requests=[], - inferred_schema=None, - inferred_datetime_formats={}, - latest_config_update=None, - ) - - expected_message = AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage(stream=_stream_name, data=dataclasses.asdict(expected_stream_read), emitted_at=1), - ) - response.record.emitted_at = 1 - assert response == expected_message - - -def test_handle_429_response(): - response = _create_429_page_response({"result": [{"error": "too many requests"}], "_metadata": {"next": "next"}}) - - # Add backoff strategy to avoid default endless backoff loop - TEST_READ_CONFIG["__injected_declarative_manifest"]["definitions"]["retriever"]["requester"]["error_handler"] = { - "backoff_strategies": [{"type": "ConstantBackoffStrategy", "backoff_time_in_seconds": 5}] - } - - config = TEST_READ_CONFIG - limits = TestReadLimits() - source = create_source(config, limits) - - with patch("requests.Session.send", return_value=response) as mock_send: - response = handle_connector_builder_request( - source, "test_read", config, ConfiguredAirbyteCatalogSerializer.load(CONFIGURED_CATALOG), _A_PER_PARTITION_STATE, limits - ) - - mock_send.assert_called_once() - - -@pytest.mark.parametrize( - "command", - [ - pytest.param("check", id="test_check_command_error"), - pytest.param("spec", id="test_spec_command_error"), - pytest.param("discover", id="test_discover_command_error"), - pytest.param(None, id="test_command_is_none_error"), - pytest.param("", id="test_command_is_empty_error"), - ], -) -def test_invalid_protocol_command(command, valid_resolve_manifest_config_file): - config = copy.deepcopy(RESOLVE_MANIFEST_CONFIG) - config["__command"] = "resolve_manifest" - with pytest.raises(SystemExit): - handle_request([command, "--config", str(valid_resolve_manifest_config_file), "--catalog", ""]) - - -def test_missing_command(valid_resolve_manifest_config_file): - with pytest.raises(SystemExit): - handle_request(["--config", str(valid_resolve_manifest_config_file), "--catalog", ""]) - - -def test_missing_catalog(valid_resolve_manifest_config_file): - with pytest.raises(SystemExit): - handle_request(["read", "--config", str(valid_resolve_manifest_config_file)]) - - -def test_missing_config(valid_resolve_manifest_config_file): - with pytest.raises(SystemExit): - handle_request(["read", "--catalog", str(valid_resolve_manifest_config_file)]) - - -def test_invalid_config_command(invalid_config_file, dummy_catalog): - with pytest.raises(ValueError): - handle_request(["read", "--config", str(invalid_config_file), "--catalog", str(dummy_catalog)]) - - -@pytest.fixture -def manifest_declarative_source(): - return mock.Mock(spec=ManifestDeclarativeSource, autospec=True) - - -def create_mock_retriever(name, url_base, path): - http_stream = mock.Mock(spec=SimpleRetriever, autospec=True) - http_stream.name = name - http_stream.requester = MagicMock() - http_stream.requester.get_url_base.return_value = url_base - http_stream.requester.get_path.return_value = path - http_stream._paginator_path.return_value = None - return http_stream - - -def create_mock_declarative_stream(http_stream): - declarative_stream = mock.Mock(spec=DeclarativeStream, autospec=True) - declarative_stream.retriever = http_stream - return declarative_stream - - -@pytest.mark.parametrize( - "test_name, config, expected_max_records, expected_max_slices, expected_max_pages_per_slice", - [ - ( - "test_no_test_read_config", - {}, - DEFAULT_MAXIMUM_RECORDS, - DEFAULT_MAXIMUM_NUMBER_OF_SLICES, - DEFAULT_MAXIMUM_NUMBER_OF_PAGES_PER_SLICE, - ), - ( - "test_no_values_set", - {"__test_read_config": {}}, - DEFAULT_MAXIMUM_RECORDS, - DEFAULT_MAXIMUM_NUMBER_OF_SLICES, - DEFAULT_MAXIMUM_NUMBER_OF_PAGES_PER_SLICE, - ), - ("test_values_are_set", {"__test_read_config": {"max_slices": 1, "max_pages_per_slice": 2, "max_records": 3}}, 3, 1, 2), - ], -) -def test_get_limits(test_name, config, expected_max_records, expected_max_slices, expected_max_pages_per_slice): - limits = get_limits(config) - assert limits.max_records == expected_max_records - assert limits.max_pages_per_slice == expected_max_pages_per_slice - assert limits.max_slices == expected_max_slices - - -def test_create_source(): - max_records = 3 - max_pages_per_slice = 2 - max_slices = 1 - limits = TestReadLimits(max_records, max_pages_per_slice, max_slices) - - config = {"__injected_declarative_manifest": MANIFEST} - - source = create_source(config, limits) - - assert isinstance(source, ManifestDeclarativeSource) - assert source._constructor._limit_pages_fetched_per_slice == limits.max_pages_per_slice - assert source._constructor._limit_slices_fetched == limits.max_slices - assert source._constructor._disable_cache - - -def request_log_message(request: dict) -> AirbyteMessage: - return AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=Level.INFO, message=f"request:{json.dumps(request)}")) - - -def response_log_message(response: dict) -> AirbyteMessage: - return AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=Level.INFO, message=f"response:{json.dumps(response)}")) - - -def _create_request(): - url = "https://example.com/api" - headers = {"Content-Type": "application/json"} - return requests.Request("POST", url, headers=headers, json={"key": "value"}).prepare() - - -def _create_response(body, request): - response = requests.Response() - response.status_code = 200 - response._content = bytes(json.dumps(body), "utf-8") - response.headers["Content-Type"] = "application/json" - response.request = request - return response - - -def _create_429_response(body, request): - response = requests.Response() - response.status_code = 429 - response._content = bytes(json.dumps(body), "utf-8") - response.headers["Content-Type"] = "application/json" - response.request = request - return response - - -def _create_page_response(response_body): - request = _create_request() - return _create_response(response_body, request) - - -def _create_429_page_response(response_body): - request = _create_request() - return _create_429_response(response_body, request) - - -@patch.object( - requests.Session, - "send", - side_effect=( - _create_page_response({"result": [{"id": 0}, {"id": 1}], "_metadata": {"next": "next"}}), - _create_page_response({"result": [{"id": 2}], "_metadata": {"next": "next"}}), - ) - * 10, -) -def test_read_source(mock_http_stream): - """ - This test sort of acts as an integration test for the connector builder. - - Each slice has two pages - The first page has two records - The second page one record - - The response._metadata.next field in the first page tells the paginator to fetch the next page. - """ - max_records = 100 - max_pages_per_slice = 2 - max_slices = 3 - limits = TestReadLimits(max_records, max_pages_per_slice, max_slices) - - catalog = ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=AirbyteStream(name=_stream_name, json_schema={}, supported_sync_modes=[SyncMode.full_refresh]), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.append, - ) - ] - ) - - config = {"__injected_declarative_manifest": MANIFEST} - - source = create_source(config, limits) - - output_data = read_stream(source, config, catalog, _A_PER_PARTITION_STATE, limits).record.data - slices = output_data["slices"] - - assert len(slices) == max_slices - for s in slices: - pages = s["pages"] - assert len(pages) == max_pages_per_slice - - first_page, second_page = pages[0], pages[1] - assert len(first_page["records"]) == _page_size - assert len(second_page["records"]) == 1 - - streams = source.streams(config) - for s in streams: - assert isinstance(s.retriever, SimpleRetrieverTestReadDecorator) - - -@patch.object( - requests.Session, - "send", - side_effect=( - _create_page_response({"result": [{"id": 0}, {"id": 1}], "_metadata": {"next": "next"}}), - _create_page_response({"result": [{"id": 2}], "_metadata": {"next": "next"}}), - ), -) -def test_read_source_single_page_single_slice(mock_http_stream): - max_records = 100 - max_pages_per_slice = 1 - max_slices = 1 - limits = TestReadLimits(max_records, max_pages_per_slice, max_slices) - - catalog = ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=AirbyteStream(name=_stream_name, json_schema={}, supported_sync_modes=[SyncMode.full_refresh]), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.append, - ) - ] - ) - - config = {"__injected_declarative_manifest": MANIFEST} - - source = create_source(config, limits) - - output_data = read_stream(source, config, catalog, _A_PER_PARTITION_STATE, limits).record.data - slices = output_data["slices"] - - assert len(slices) == max_slices - for s in slices: - pages = s["pages"] - assert len(pages) == max_pages_per_slice - - first_page = pages[0] - assert len(first_page["records"]) == _page_size - - streams = source.streams(config) - for s in streams: - assert isinstance(s.retriever, SimpleRetrieverTestReadDecorator) - - -@pytest.mark.parametrize( - "deployment_mode, url_base, expected_error", - [ - pytest.param("CLOUD", "https://airbyte.com/api/v1/characters", None, id="test_cloud_read_with_public_endpoint"), - pytest.param("CLOUD", "https://10.0.27.27", "AirbyteTracedException", id="test_cloud_read_with_private_endpoint"), - pytest.param("CLOUD", "https://localhost:80/api/v1/cast", "AirbyteTracedException", id="test_cloud_read_with_localhost"), - pytest.param("CLOUD", "http://unsecured.protocol/api/v1", "InvalidSchema", id="test_cloud_read_with_unsecured_endpoint"), - pytest.param("CLOUD", "https://domainwithoutextension", "Invalid URL", id="test_cloud_read_with_invalid_url_endpoint"), - pytest.param("OSS", "https://airbyte.com/api/v1/", None, id="test_oss_read_with_public_endpoint"), - pytest.param("OSS", "https://10.0.27.27/api/v1/", None, id="test_oss_read_with_private_endpoint"), - ], -) -@patch.object(requests.Session, "send", _mocked_send) -def test_handle_read_external_requests(deployment_mode, url_base, expected_error): - """ - This test acts like an integration test for the connector builder when it receives Test Read requests. - - The scenario being tested is whether requests should be denied if they are done on an unsecure channel or are made to internal - endpoints when running on Cloud or OSS deployments - """ - - limits = TestReadLimits(max_records=100, max_pages_per_slice=1, max_slices=1) - - catalog = ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=AirbyteStream(name=_stream_name, json_schema={}, supported_sync_modes=[SyncMode.full_refresh]), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.append, - ) - ] - ) - - test_manifest = MANIFEST - test_manifest["streams"][0]["$parameters"]["url_base"] = url_base - config = {"__injected_declarative_manifest": test_manifest} - - source = create_source(config, limits) - - with mock.patch.dict(os.environ, {"DEPLOYMENT_MODE": deployment_mode}, clear=False): - output_data = read_stream(source, config, catalog, _A_PER_PARTITION_STATE, limits).record.data - if expected_error: - assert len(output_data["logs"]) > 0, "Expected at least one log message with the expected error" - error_message = output_data["logs"][0] - assert error_message["level"] == "ERROR" - assert expected_error in error_message["stacktrace"] - else: - page_records = output_data["slices"][0]["pages"][0] - assert len(page_records) == len(MOCK_RESPONSE["result"]) - - -@pytest.mark.parametrize( - "deployment_mode, token_url, expected_error", - [ - pytest.param("CLOUD", "https://airbyte.com/tokens/bearer", None, id="test_cloud_read_with_public_endpoint"), - pytest.param("CLOUD", "https://10.0.27.27/tokens/bearer", "AirbyteTracedException", id="test_cloud_read_with_private_endpoint"), - pytest.param("CLOUD", "http://unsecured.protocol/tokens/bearer", "InvalidSchema", id="test_cloud_read_with_unsecured_endpoint"), - pytest.param("CLOUD", "https://domainwithoutextension", "Invalid URL", id="test_cloud_read_with_invalid_url_endpoint"), - pytest.param("OSS", "https://airbyte.com/tokens/bearer", None, id="test_oss_read_with_public_endpoint"), - pytest.param("OSS", "https://10.0.27.27/tokens/bearer", None, id="test_oss_read_with_private_endpoint"), - ], -) -@patch.object(requests.Session, "send", _mocked_send) -def test_handle_read_external_oauth_request(deployment_mode, token_url, expected_error): - """ - This test acts like an integration test for the connector builder when it receives Test Read requests. - - The scenario being tested is whether requests should be denied if they are done on an unsecure channel or are made to internal - endpoints when running on Cloud or OSS deployments - """ - - limits = TestReadLimits(max_records=100, max_pages_per_slice=1, max_slices=1) - - catalog = ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=AirbyteStream(name=_stream_name, json_schema={}, supported_sync_modes=[SyncMode.full_refresh]), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.append, - ) - ] - ) - - oauth_authenticator_config: dict[str, str] = { - "type": "OAuthAuthenticator", - "token_refresh_endpoint": token_url, - "client_id": "greta", - "client_secret": "teo", - "refresh_token": "john", - } - - test_manifest = MANIFEST - test_manifest["definitions"]["retriever"]["requester"]["authenticator"] = oauth_authenticator_config - config = {"__injected_declarative_manifest": test_manifest} - - source = create_source(config, limits) - - with mock.patch.dict(os.environ, {"DEPLOYMENT_MODE": deployment_mode}, clear=False): - output_data = read_stream(source, config, catalog, _A_PER_PARTITION_STATE, limits).record.data - if expected_error: - assert len(output_data["logs"]) > 0, "Expected at least one log message with the expected error" - error_message = output_data["logs"][0] - assert error_message["level"] == "ERROR" - assert expected_error in error_message["stacktrace"] - - -def test_read_stream_exception_with_secrets(): - # Define the test parameters - config = {"__injected_declarative_manifest": "test_manifest", "api_key": "super_secret_key"} - catalog = ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=AirbyteStream(name=_stream_name, json_schema={}, supported_sync_modes=[SyncMode.full_refresh]), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.append, - ) - ] - ) - state = [] - limits = TestReadLimits() - - # Add the secret to be filtered - update_secrets([config["api_key"]]) - - # Mock the source - mock_source = MagicMock() - - # Patch the handler to raise an exception - with patch("airbyte_cdk.connector_builder.message_grouper.MessageGrouper.get_message_groups") as mock_handler: - mock_handler.side_effect = Exception("Test exception with secret key: super_secret_key") - - # Call the read_stream function and check for the correct error message - response = read_stream(mock_source, config, catalog, state, limits) - - # Check if the error message contains the filtered secret - filtered_message = filter_secrets("Test exception with secret key: super_secret_key") - assert response.type == Type.TRACE - assert filtered_message in response.trace.error.message - assert "super_secret_key" not in response.trace.error.message diff --git a/airbyte-cdk/python/unit_tests/connector_builder/test_message_grouper.py b/airbyte-cdk/python/unit_tests/connector_builder/test_message_grouper.py deleted file mode 100644 index 6a4c7a99e4a8..000000000000 --- a/airbyte-cdk/python/unit_tests/connector_builder/test_message_grouper.py +++ /dev/null @@ -1,830 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -from typing import Any, Iterator, List, Mapping -from unittest.mock import MagicMock, Mock, patch - -import pytest -from airbyte_cdk.connector_builder.message_grouper import MessageGrouper -from airbyte_cdk.connector_builder.models import HttpRequest, HttpResponse, LogMessage, StreamRead, StreamReadPages -from airbyte_cdk.models import ( - AirbyteControlConnectorConfigMessage, - AirbyteControlMessage, - AirbyteLogMessage, - AirbyteMessage, - AirbyteRecordMessage, - AirbyteStateBlob, - AirbyteStateMessage, - AirbyteStreamState, - Level, - OrchestratorType, - StreamDescriptor, -) -from airbyte_cdk.models import Type as MessageType -from orjson import orjson -from unit_tests.connector_builder.utils import create_configured_catalog - -_NO_PK = [[]] -_NO_CURSOR_FIELD = [] - -MAX_PAGES_PER_SLICE = 4 -MAX_SLICES = 3 - -_NO_STATE = [] - -MANIFEST = { - "version": "0.30.0", - "type": "DeclarativeSource", - "definitions": { - "selector": {"extractor": {"field_path": ["items"], "type": "DpathExtractor"}, "type": "RecordSelector"}, - "requester": {"url_base": "https://demonslayers.com/api/v1/", "http_method": "GET", "type": "DeclarativeSource"}, - "retriever": { - "type": "DeclarativeSource", - "record_selector": {"extractor": {"field_path": ["items"], "type": "DpathExtractor"}, "type": "RecordSelector"}, - "paginator": {"type": "NoPagination"}, - "requester": {"url_base": "https://demonslayers.com/api/v1/", "http_method": "GET", "type": "HttpRequester"}, - }, - "hashiras_stream": { - "retriever": { - "type": "DeclarativeSource", - "record_selector": {"extractor": {"field_path": ["items"], "type": "DpathExtractor"}, "type": "RecordSelector"}, - "paginator": {"type": "NoPagination"}, - "requester": {"url_base": "https://demonslayers.com/api/v1/", "http_method": "GET", "type": "HttpRequester"}, - }, - "$parameters": {"name": "hashiras", "path": "/hashiras"}, - }, - "breathing_techniques_stream": { - "retriever": { - "type": "DeclarativeSource", - "record_selector": {"extractor": {"field_path": ["items"], "type": "DpathExtractor"}, "type": "RecordSelector"}, - "paginator": {"type": "NoPagination"}, - "requester": {"url_base": "https://demonslayers.com/api/v1/", "http_method": "GET", "type": "HttpRequester"}, - }, - "$parameters": {"name": "breathing-techniques", "path": "/breathing_techniques"}, - }, - }, - "streams": [ - { - "type": "DeclarativeStream", - "retriever": { - "type": "SimpleRetriever", - "record_selector": {"extractor": {"field_path": ["items"], "type": "DpathExtractor"}, "type": "RecordSelector"}, - "paginator": {"type": "NoPagination"}, - "requester": {"url_base": "https://demonslayers.com/api/v1/", "http_method": "GET", "type": "HttpRequester"}, - }, - "$parameters": {"name": "hashiras", "path": "/hashiras"}, - }, - { - "type": "DeclarativeStream", - "retriever": { - "type": "SimpleRetriever", - "record_selector": {"extractor": {"field_path": ["items"], "type": "DpathExtractor"}, "type": "RecordSelector"}, - "paginator": {"type": "NoPagination"}, - "requester": {"url_base": "https://demonslayers.com/api/v1/", "http_method": "GET", "type": "HttpRequester"}, - }, - "$parameters": {"name": "breathing-techniques", "path": "/breathing_techniques"}, - }, - ], - "check": {"stream_names": ["hashiras"], "type": "CheckStream"}, -} - -CONFIG = {"rank": "upper-six"} - -A_SOURCE = MagicMock() - - -@patch("airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read") -def test_get_grouped_messages(mock_entrypoint_read: Mock) -> None: - url = "https://demonslayers.com/api/v1/hashiras?era=taisho" - request = { - "headers": {"Content-Type": "application/json"}, - "method": "GET", - "body": {"content": '{"custom": "field"}'}, - } - response = {"status_code": 200, "headers": {"field": "value"}, "body": {"content": '{"name": "field"}'}} - expected_schema = { - "$schema": "http://json-schema.org/schema#", - "properties": {"name": {"type": ["string", "null"]}, "date": {"type": ["string", "null"]}}, - "type": "object", - } - expected_datetime_fields = {"date": "%Y-%m-%d"} - expected_pages = [ - StreamReadPages( - request=HttpRequest( - url="https://demonslayers.com/api/v1/hashiras?era=taisho", - headers={"Content-Type": "application/json"}, - body='{"custom": "field"}', - http_method="GET", - ), - response=HttpResponse(status=200, headers={"field": "value"}, body='{"name": "field"}'), - records=[{"name": "Shinobu Kocho", "date": "2023-03-03"}, {"name": "Muichiro Tokito", "date": "2023-03-04"}], - ), - StreamReadPages( - request=HttpRequest( - url="https://demonslayers.com/api/v1/hashiras?era=taisho", - headers={"Content-Type": "application/json"}, - body='{"custom": "field"}', - http_method="GET", - ), - response=HttpResponse(status=200, headers={"field": "value"}, body='{"name": "field"}'), - records=[{"name": "Mitsuri Kanroji", "date": "2023-03-05"}], - ), - ] - - mock_source = make_mock_source( - mock_entrypoint_read, - iter( - [ - request_response_log_message(request, response, url), - record_message("hashiras", {"name": "Shinobu Kocho", "date": "2023-03-03"}), - record_message("hashiras", {"name": "Muichiro Tokito", "date": "2023-03-04"}), - request_response_log_message(request, response, url), - record_message("hashiras", {"name": "Mitsuri Kanroji", "date": "2023-03-05"}), - ] - ), - ) - - connector_builder_handler = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - actual_response: StreamRead = connector_builder_handler.get_message_groups( - source=mock_source, - config=CONFIG, - configured_catalog=create_configured_catalog("hashiras"), - state=_NO_STATE, - ) - - assert actual_response.inferred_schema == expected_schema - assert actual_response.inferred_datetime_formats == expected_datetime_fields - - single_slice = actual_response.slices[0] - for i, actual_page in enumerate(single_slice.pages): - assert actual_page == expected_pages[i] - - -@patch("airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read") -def test_get_grouped_messages_with_logs(mock_entrypoint_read: Mock) -> None: - url = "https://demonslayers.com/api/v1/hashiras?era=taisho" - request = { - "headers": {"Content-Type": "application/json"}, - "method": "GET", - "body": {"content": '{"custom": "field"}'}, - } - response = {"status_code": 200, "headers": {"field": "value"}, "body": {"content": '{"name": "field"}'}} - expected_pages = [ - StreamReadPages( - request=HttpRequest( - url="https://demonslayers.com/api/v1/hashiras?era=taisho", - headers={"Content-Type": "application/json"}, - body='{"custom": "field"}', - http_method="GET", - ), - response=HttpResponse(status=200, headers={"field": "value"}, body='{"name": "field"}'), - records=[{"name": "Shinobu Kocho"}, {"name": "Muichiro Tokito"}], - ), - StreamReadPages( - request=HttpRequest( - url="https://demonslayers.com/api/v1/hashiras?era=taisho", - headers={"Content-Type": "application/json"}, - body='{"custom": "field"}', - http_method="GET", - ), - response=HttpResponse(status=200, headers={"field": "value"}, body='{"name": "field"}'), - records=[{"name": "Mitsuri Kanroji"}], - ), - ] - expected_logs = [ - LogMessage(**{"message": "log message before the request", "level": "INFO"}), - LogMessage(**{"message": "log message during the page", "level": "INFO"}), - LogMessage(**{"message": "log message after the response", "level": "INFO"}), - ] - - mock_source = make_mock_source( - mock_entrypoint_read, - iter( - [ - AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=Level.INFO, message="log message before the request")), - request_response_log_message(request, response, url), - record_message("hashiras", {"name": "Shinobu Kocho"}), - AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=Level.INFO, message="log message during the page")), - record_message("hashiras", {"name": "Muichiro Tokito"}), - AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=Level.INFO, message="log message after the response")), - ] - ), - ) - - connector_builder_handler = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - - actual_response: StreamRead = connector_builder_handler.get_message_groups( - source=mock_source, - config=CONFIG, - configured_catalog=create_configured_catalog("hashiras"), - state=_NO_STATE, - ) - single_slice = actual_response.slices[0] - for i, actual_page in enumerate(single_slice.pages): - assert actual_page == expected_pages[i] - - for i, actual_log in enumerate(actual_response.logs): - assert actual_log == expected_logs[i] - - -@pytest.mark.parametrize( - "request_record_limit, max_record_limit, should_fail", - [ - pytest.param(1, 3, False, id="test_create_request_with_record_limit"), - pytest.param(3, 1, True, id="test_create_request_record_limit_exceeds_max"), - ], -) -@patch("airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read") -def test_get_grouped_messages_record_limit( - mock_entrypoint_read: Mock, request_record_limit: int, max_record_limit: int, should_fail: bool -) -> None: - url = "https://demonslayers.com/api/v1/hashiras?era=taisho" - request = { - "headers": {"Content-Type": "application/json"}, - "method": "GET", - "body": {"content": '{"custom": "field"}'}, - } - response = {"status_code": 200, "headers": {"field": "value"}, "body": {"content": '{"name": "field"}'}} - mock_source = make_mock_source( - mock_entrypoint_read, - iter( - [ - request_response_log_message(request, response, url), - record_message("hashiras", {"name": "Shinobu Kocho"}), - record_message("hashiras", {"name": "Muichiro Tokito"}), - request_response_log_message(request, response, url), - record_message("hashiras", {"name": "Mitsuri Kanroji"}), - ] - ), - ) - n_records = 2 - record_limit = min(request_record_limit, max_record_limit) - - api = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES, max_record_limit=max_record_limit) - # this is the call we expect to raise an exception - if should_fail: - with pytest.raises(ValueError): - api.get_message_groups( - mock_source, - config=CONFIG, - configured_catalog=create_configured_catalog("hashiras"), - state=_NO_STATE, - record_limit=request_record_limit, - ) - else: - actual_response: StreamRead = api.get_message_groups( - mock_source, - config=CONFIG, - configured_catalog=create_configured_catalog("hashiras"), - state=_NO_STATE, - record_limit=request_record_limit, - ) - single_slice = actual_response.slices[0] - total_records = 0 - for i, actual_page in enumerate(single_slice.pages): - total_records += len(actual_page.records) - assert total_records == min([record_limit, n_records]) - - assert (total_records >= max_record_limit) == actual_response.test_read_limit_reached - - -@pytest.mark.parametrize( - "max_record_limit", - [ - pytest.param(2, id="test_create_request_no_record_limit"), - pytest.param(1, id="test_create_request_no_record_limit_n_records_exceed_max"), - ], -) -@patch("airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read") -def test_get_grouped_messages_default_record_limit(mock_entrypoint_read: Mock, max_record_limit: int) -> None: - url = "https://demonslayers.com/api/v1/hashiras?era=taisho" - request = { - "headers": {"Content-Type": "application/json"}, - "method": "GET", - "body": {"content": '{"custom": "field"}'}, - } - response = {"status_code": 200, "headers": {"field": "value"}, "body": {"content": '{"name": "field"}'}} - mock_source = make_mock_source( - mock_entrypoint_read, - iter( - [ - request_response_log_message(request, response, url), - record_message("hashiras", {"name": "Shinobu Kocho"}), - record_message("hashiras", {"name": "Muichiro Tokito"}), - request_response_log_message(request, response, url), - record_message("hashiras", {"name": "Mitsuri Kanroji"}), - ] - ), - ) - n_records = 2 - - api = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES, max_record_limit=max_record_limit) - actual_response: StreamRead = api.get_message_groups( - source=mock_source, config=CONFIG, configured_catalog=create_configured_catalog("hashiras"), state=_NO_STATE - ) - single_slice = actual_response.slices[0] - total_records = 0 - for i, actual_page in enumerate(single_slice.pages): - total_records += len(actual_page.records) - assert total_records == min([max_record_limit, n_records]) - - -@patch("airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read") -def test_get_grouped_messages_limit_0(mock_entrypoint_read: Mock) -> None: - url = "https://demonslayers.com/api/v1/hashiras?era=taisho" - request = { - "headers": {"Content-Type": "application/json"}, - "method": "GET", - "body": {"content": '{"custom": "field"}'}, - } - response = {"status_code": 200, "headers": {"field": "value"}, "body": {"content": '{"name": "field"}'}} - mock_source = make_mock_source( - mock_entrypoint_read, - iter( - [ - request_response_log_message(request, response, url), - record_message("hashiras", {"name": "Shinobu Kocho"}), - record_message("hashiras", {"name": "Muichiro Tokito"}), - request_response_log_message(request, response, url), - record_message("hashiras", {"name": "Mitsuri Kanroji"}), - ] - ), - ) - api = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - - with pytest.raises(ValueError): - api.get_message_groups( - source=mock_source, config=CONFIG, configured_catalog=create_configured_catalog("hashiras"), state=_NO_STATE, record_limit=0 - ) - - -@patch("airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read") -def test_get_grouped_messages_no_records(mock_entrypoint_read: Mock) -> None: - url = "https://demonslayers.com/api/v1/hashiras?era=taisho" - request = { - "headers": {"Content-Type": "application/json"}, - "method": "GET", - "body": {"content": '{"custom": "field"}'}, - } - response = {"status_code": 200, "headers": {"field": "value"}, "body": {"content": '{"name": "field"}'}} - expected_pages = [ - StreamReadPages( - request=HttpRequest( - url="https://demonslayers.com/api/v1/hashiras?era=taisho", - headers={"Content-Type": "application/json"}, - body='{"custom": "field"}', - http_method="GET", - ), - response=HttpResponse(status=200, headers={"field": "value"}, body='{"name": "field"}'), - records=[], - ), - StreamReadPages( - request=HttpRequest( - url="https://demonslayers.com/api/v1/hashiras?era=taisho", - headers={"Content-Type": "application/json"}, - body='{"custom": "field"}', - http_method="GET", - ), - response=HttpResponse(status=200, headers={"field": "value"}, body='{"name": "field"}'), - records=[], - ), - ] - - mock_source = make_mock_source( - mock_entrypoint_read, - iter( - [ - request_response_log_message(request, response, url), - request_response_log_message(request, response, url), - ] - ), - ) - - message_grouper = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - - actual_response: StreamRead = message_grouper.get_message_groups( - source=mock_source, - config=CONFIG, - configured_catalog=create_configured_catalog("hashiras"), - state=_NO_STATE, - ) - - single_slice = actual_response.slices[0] - for i, actual_page in enumerate(single_slice.pages): - assert actual_page == expected_pages[i] - - -@pytest.mark.parametrize( - "log_message, expected_response", - [ - pytest.param( - { - "http": { - "response": { - "status_code": 200, - "headers": {"field": "name"}, - "body": {"content": '{"id": "fire", "owner": "kyojuro_rengoku"}'}, - } - } - }, - HttpResponse(status=200, headers={"field": "name"}, body='{"id": "fire", "owner": "kyojuro_rengoku"}'), - id="test_create_response_with_all_fields", - ), - pytest.param( - {"http": {"response": {"status_code": 200, "headers": {"field": "name"}}}}, - HttpResponse(status=200, headers={"field": "name"}, body=""), - id="test_create_response_with_no_body", - ), - pytest.param( - {"http": {"response": {"status_code": 200, "body": {"content": '{"id": "fire", "owner": "kyojuro_rengoku"}'}}}}, - HttpResponse(status=200, body='{"id": "fire", "owner": "kyojuro_rengoku"}'), - id="test_create_response_with_no_headers", - ), - pytest.param( - { - "http": { - "response": { - "status_code": 200, - "headers": {"field": "name"}, - "body": {"content": '[{"id": "fire", "owner": "kyojuro_rengoku"}, {"id": "mist", "owner": "muichiro_tokito"}]'}, - } - } - }, - HttpResponse( - status=200, - headers={"field": "name"}, - body='[{"id": "fire", "owner": "kyojuro_rengoku"}, {"id": "mist", "owner": "muichiro_tokito"}]', - ), - id="test_create_response_with_array", - ), - pytest.param( - {"http": {"response": {"status_code": 200, "body": {"content": "tomioka"}}}}, - HttpResponse(status=200, body="tomioka"), - id="test_create_response_with_string", - ), - ], -) -def test_create_response_from_log_message(log_message: str, expected_response: HttpResponse) -> None: - if isinstance(log_message, str): - response_message = json.loads(log_message) - else: - response_message = log_message - - connector_builder_handler = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - actual_response = connector_builder_handler._create_response_from_log_message(response_message) - - assert actual_response == expected_response - - -@patch("airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read") -def test_get_grouped_messages_with_many_slices(mock_entrypoint_read: Mock) -> None: - url = "http://a-url.com" - request: Mapping[str, Any] = {} - response = {"status_code": 200} - - mock_source = make_mock_source( - mock_entrypoint_read, - iter( - [ - slice_message('{"descriptor": "first_slice"}'), - request_response_log_message(request, response, url), - record_message("hashiras", {"name": "Muichiro Tokito"}), - slice_message('{"descriptor": "second_slice"}'), - request_response_log_message(request, response, url), - record_message("hashiras", {"name": "Shinobu Kocho"}), - record_message("hashiras", {"name": "Mitsuri Kanroji"}), - request_response_log_message(request, response, url), - record_message("hashiras", {"name": "Obanai Iguro"}), - request_response_log_message(request, response, url), - state_message("hashiras", {"a_timestamp": 123}), - ] - ), - ) - - connector_builder_handler = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - - stream_read: StreamRead = connector_builder_handler.get_message_groups( - source=mock_source, - config=CONFIG, - configured_catalog=create_configured_catalog("hashiras"), - state=_NO_STATE, - ) - - assert not stream_read.test_read_limit_reached - assert len(stream_read.slices) == 2 - - assert stream_read.slices[0].slice_descriptor == {"descriptor": "first_slice"} - assert len(stream_read.slices[0].pages) == 1 - assert len(stream_read.slices[0].pages[0].records) == 1 - assert stream_read.slices[0].state == [] - - assert stream_read.slices[1].slice_descriptor == {"descriptor": "second_slice"} - assert len(stream_read.slices[1].pages) == 3 - assert len(stream_read.slices[1].pages[0].records) == 2 - assert len(stream_read.slices[1].pages[1].records) == 1 - assert len(stream_read.slices[1].pages[2].records) == 0 - - assert ( - orjson.dumps(stream_read.slices[1].state[0].stream.stream_state).decode() - == orjson.dumps(AirbyteStateBlob(a_timestamp=123)).decode() - ) - - -@patch("airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read") -def test_get_grouped_messages_given_maximum_number_of_slices_then_test_read_limit_reached(mock_entrypoint_read: Mock) -> None: - maximum_number_of_slices = 5 - request: Mapping[str, Any] = {} - response = {"status_code": 200} - mock_source = make_mock_source( - mock_entrypoint_read, iter([slice_message(), request_response_log_message(request, response, "a_url")] * maximum_number_of_slices) - ) - - api = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - - stream_read: StreamRead = api.get_message_groups( - source=mock_source, - config=CONFIG, - configured_catalog=create_configured_catalog("hashiras"), - state=_NO_STATE, - ) - - assert stream_read.test_read_limit_reached - - -@patch("airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read") -def test_get_grouped_messages_given_maximum_number_of_pages_then_test_read_limit_reached(mock_entrypoint_read: Mock) -> None: - maximum_number_of_pages_per_slice = 5 - request: Mapping[str, Any] = {} - response = {"status_code": 200} - mock_source = make_mock_source( - mock_entrypoint_read, - iter([slice_message()] + [request_response_log_message(request, response, "a_url")] * maximum_number_of_pages_per_slice), - ) - - api = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - - stream_read: StreamRead = api.get_message_groups( - source=mock_source, - config=CONFIG, - configured_catalog=create_configured_catalog("hashiras"), - state=_NO_STATE, - ) - - assert stream_read.test_read_limit_reached - - -def test_read_stream_returns_error_if_stream_does_not_exist() -> None: - mock_source = MagicMock() - mock_source.read.side_effect = ValueError("error") - mock_source.streams.return_value = [make_mock_stream()] - - full_config: Mapping[str, Any] = {**CONFIG, **{"__injected_declarative_manifest": MANIFEST}} - - message_grouper = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - actual_response = message_grouper.get_message_groups( - source=mock_source, - config=full_config, - configured_catalog=create_configured_catalog("not_in_manifest"), - state=_NO_STATE, - ) - - assert len(actual_response.logs) == 1 - assert "Traceback" in actual_response.logs[0].stacktrace - assert "ERROR" in actual_response.logs[0].level - - -@patch("airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read") -def test_given_control_message_then_stream_read_has_config_update(mock_entrypoint_read: Mock) -> None: - updated_config = {"x": 1} - mock_source = make_mock_source( - mock_entrypoint_read, iter(any_request_and_response_with_a_record() + [connector_configuration_control_message(1, updated_config)]) - ) - connector_builder_handler = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - stream_read: StreamRead = connector_builder_handler.get_message_groups( - source=mock_source, - config=CONFIG, - configured_catalog=create_configured_catalog("hashiras"), - state=_NO_STATE, - ) - - assert stream_read.latest_config_update == updated_config - - -@patch("airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read") -def test_given_multiple_control_messages_then_stream_read_has_latest_based_on_emitted_at(mock_entrypoint_read: Mock) -> None: - earliest = 0 - earliest_config = {"earliest": 0} - latest = 1 - latest_config = {"latest": 1} - mock_source = make_mock_source( - mock_entrypoint_read, - iter( - any_request_and_response_with_a_record() - + [ - # here, we test that even if messages are emitted in a different order, we still rely on `emitted_at` - connector_configuration_control_message(latest, latest_config), - connector_configuration_control_message(earliest, earliest_config), - ] - ), - ) - connector_builder_handler = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - stream_read: StreamRead = connector_builder_handler.get_message_groups( - source=mock_source, - config=CONFIG, - configured_catalog=create_configured_catalog("hashiras"), - state=_NO_STATE, - ) - - assert stream_read.latest_config_update == latest_config - - -@patch("airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read") -def test_given_multiple_control_messages_with_same_timestamp_then_stream_read_has_latest_based_on_message_order( - mock_entrypoint_read: Mock, -) -> None: - emitted_at = 0 - earliest_config = {"earliest": 0} - latest_config = {"latest": 1} - mock_source = make_mock_source( - mock_entrypoint_read, - iter( - any_request_and_response_with_a_record() - + [ - connector_configuration_control_message(emitted_at, earliest_config), - connector_configuration_control_message(emitted_at, latest_config), - ] - ), - ) - connector_builder_handler = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - stream_read: StreamRead = connector_builder_handler.get_message_groups( - source=mock_source, - config=CONFIG, - configured_catalog=create_configured_catalog("hashiras"), - state=_NO_STATE, - ) - - assert stream_read.latest_config_update == latest_config - - -@patch("airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read") -def test_given_auxiliary_requests_then_return_auxiliary_request(mock_entrypoint_read: Mock) -> None: - mock_source = make_mock_source(mock_entrypoint_read, iter(any_request_and_response_with_a_record() + [auxiliary_request_log_message()])) - connector_builder_handler = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - stream_read: StreamRead = connector_builder_handler.get_message_groups( - source=mock_source, config=CONFIG, configured_catalog=create_configured_catalog("hashiras"), state=_NO_STATE - ) - - assert len(stream_read.auxiliary_requests) == 1 - - -@patch("airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read") -def test_given_no_slices_then_return_empty_slices(mock_entrypoint_read: Mock) -> None: - mock_source = make_mock_source(mock_entrypoint_read, iter([auxiliary_request_log_message()])) - connector_builder_handler = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - stream_read: StreamRead = connector_builder_handler.get_message_groups( - source=mock_source, config=CONFIG, configured_catalog=create_configured_catalog("hashiras"), state=_NO_STATE - ) - - assert len(stream_read.slices) == 0 - - -@patch("airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read") -def test_given_pk_then_ensure_pk_is_pass_to_schema_inferrence(mock_entrypoint_read: Mock) -> None: - mock_source = make_mock_source( - mock_entrypoint_read, - iter( - [ - request_response_log_message({"request": 1}, {"response": 2}, "http://any_url.com"), - record_message("hashiras", {"id": "Shinobu Kocho", "date": "2023-03-03"}), - record_message("hashiras", {"id": "Muichiro Tokito", "date": "2023-03-04"}), - ] - ), - ) - mock_source.streams.return_value = [Mock()] - mock_source.streams.return_value[0].primary_key = [["id"]] - mock_source.streams.return_value[0].cursor_field = _NO_CURSOR_FIELD - connector_builder_handler = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - - stream_read: StreamRead = connector_builder_handler.get_message_groups( - source=mock_source, config=CONFIG, configured_catalog=create_configured_catalog("hashiras"), state=_NO_STATE - ) - - assert stream_read.inferred_schema["required"] == ["id"] - - -@patch("airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read") -def test_given_cursor_field_then_ensure_cursor_field_is_pass_to_schema_inferrence(mock_entrypoint_read: Mock) -> None: - mock_source = make_mock_source( - mock_entrypoint_read, - iter( - [ - request_response_log_message({"request": 1}, {"response": 2}, "http://any_url.com"), - record_message("hashiras", {"id": "Shinobu Kocho", "date": "2023-03-03"}), - record_message("hashiras", {"id": "Muichiro Tokito", "date": "2023-03-04"}), - ] - ), - ) - mock_source.streams.return_value = [Mock()] - mock_source.streams.return_value[0].primary_key = _NO_PK - mock_source.streams.return_value[0].cursor_field = ["date"] - connector_builder_handler = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - - stream_read: StreamRead = connector_builder_handler.get_message_groups( - source=mock_source, config=CONFIG, configured_catalog=create_configured_catalog("hashiras"), state=_NO_STATE - ) - - assert stream_read.inferred_schema["required"] == ["date"] - - -def make_mock_source(mock_entrypoint_read: Mock, return_value: Iterator[AirbyteMessage]) -> MagicMock: - mock_source = MagicMock() - mock_entrypoint_read.return_value = return_value - mock_source.streams.return_value = [make_mock_stream()] - return mock_source - - -def make_mock_stream(): - mock_stream = MagicMock() - mock_stream.primary_key = [] - mock_stream.cursor_field = [] - return mock_stream - - -def request_log_message(request: Mapping[str, Any]) -> AirbyteMessage: - return AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=Level.INFO, message=f"request:{json.dumps(request)}")) - - -def response_log_message(response: Mapping[str, Any]) -> AirbyteMessage: - return AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=Level.INFO, message=f"response:{json.dumps(response)}")) - - -def record_message(stream: str, data: Mapping[str, Any]) -> AirbyteMessage: - return AirbyteMessage(type=MessageType.RECORD, record=AirbyteRecordMessage(stream=stream, data=data, emitted_at=1234)) - - -def state_message(stream: str, data: Mapping[str, Any]) -> AirbyteMessage: - return AirbyteMessage( - type=MessageType.STATE, - state=AirbyteStateMessage(stream=AirbyteStreamState(stream_descriptor=StreamDescriptor(name=stream), stream_state=data)), - ) - - -def slice_message(slice_descriptor: str = '{"key": "value"}') -> AirbyteMessage: - return AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=Level.INFO, message="slice:" + slice_descriptor)) - - -def connector_configuration_control_message(emitted_at: float, config: Mapping[str, Any]) -> AirbyteMessage: - return AirbyteMessage( - type=MessageType.CONTROL, - control=AirbyteControlMessage( - type=OrchestratorType.CONNECTOR_CONFIG, - emitted_at=emitted_at, - connectorConfig=AirbyteControlConnectorConfigMessage(config=config), - ), - ) - - -def auxiliary_request_log_message() -> AirbyteMessage: - return AirbyteMessage( - type=MessageType.LOG, - log=AirbyteLogMessage( - level=Level.INFO, - message=json.dumps( - { - "http": { - "is_auxiliary": True, - "title": "a title", - "description": "a description", - "request": {}, - "response": {}, - }, - "url": {"full": "https://a-url.com"}, - } - ), - ), - ) - - -def request_response_log_message(request: Mapping[str, Any], response: Mapping[str, Any], url: str) -> AirbyteMessage: - return AirbyteMessage( - type=MessageType.LOG, - log=AirbyteLogMessage( - level=Level.INFO, - message=json.dumps( - { - "airbyte_cdk": {"stream": {"name": "a stream name"}}, - "http": {"title": "a title", "description": "a description", "request": request, "response": response}, - "url": {"full": url}, - } - ), - ), - ) - - -def any_request_and_response_with_a_record() -> List[AirbyteMessage]: - return [ - request_response_log_message({"request": 1}, {"response": 2}, "http://any_url.com"), - record_message("hashiras", {"name": "Shinobu Kocho"}), - ] diff --git a/airbyte-cdk/python/unit_tests/connector_builder/utils.py b/airbyte-cdk/python/unit_tests/connector_builder/utils.py deleted file mode 100644 index a94a0416437c..000000000000 --- a/airbyte-cdk/python/unit_tests/connector_builder/utils.py +++ /dev/null @@ -1,27 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Mapping - -from airbyte_cdk.models import ConfiguredAirbyteCatalog, ConfiguredAirbyteCatalogSerializer - - -def create_configured_catalog_dict(stream_name: str) -> Mapping[str, Any]: - return { - "streams": [ - { - "stream": { - "name": stream_name, - "json_schema": {}, - "supported_sync_modes": ["full_refresh", "incremental"], - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite", - } - ] - } - - -def create_configured_catalog(stream_name: str) -> ConfiguredAirbyteCatalog: - return ConfiguredAirbyteCatalogSerializer.load(create_configured_catalog_dict(stream_name)) diff --git a/airbyte-cdk/python/unit_tests/destinations/__init__.py b/airbyte-cdk/python/unit_tests/destinations/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/destinations/test_destination.py b/airbyte-cdk/python/unit_tests/destinations/test_destination.py deleted file mode 100644 index a03d7ffcc6b0..000000000000 --- a/airbyte-cdk/python/unit_tests/destinations/test_destination.py +++ /dev/null @@ -1,277 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import argparse -import io -import json -from os import PathLike -from typing import Any, Dict, Iterable, List, Mapping, Union -from unittest.mock import ANY - -import pytest -from airbyte_cdk.destinations import Destination -from airbyte_cdk.destinations import destination as destination_module -from airbyte_cdk.models import ( - AirbyteCatalog, - AirbyteConnectionStatus, - AirbyteMessage, - AirbyteMessageSerializer, - AirbyteRecordMessage, - AirbyteStateMessage, - AirbyteStream, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteCatalogSerializer, - ConfiguredAirbyteStream, - ConnectorSpecification, - DestinationSyncMode, - Status, - SyncMode, - Type, -) -from orjson import orjson - - -@pytest.fixture(name="destination") -def destination_fixture(mocker) -> Destination: - # Wipe the internal list of abstract methods to allow instantiating the abstract class without implementing its abstract methods - mocker.patch("airbyte_cdk.destinations.Destination.__abstractmethods__", set()) - # Mypy yells at us because we're init'ing an abstract class - return Destination() # type: ignore - - -class TestArgParsing: - @pytest.mark.parametrize( - ("arg_list", "expected_output"), - [ - (["spec"], {"command": "spec"}), - (["check", "--config", "bogus_path/"], {"command": "check", "config": "bogus_path/"}), - ( - ["write", "--config", "config_path1", "--catalog", "catalog_path1"], - {"command": "write", "config": "config_path1", "catalog": "catalog_path1"}, - ), - ], - ) - def test_successful_parse(self, arg_list: List[str], expected_output: Mapping[str, Any], destination: Destination): - parsed_args = vars(destination.parse_args(arg_list)) - assert ( - parsed_args == expected_output - ), f"Expected parsing {arg_list} to return parsed args {expected_output} but instead found {parsed_args}" - - @pytest.mark.parametrize( - ("arg_list"), - [ - # Invalid commands - ([]), - (["not-a-real-command"]), - ([""]), - # Incorrect parameters - (["spec", "--config", "path"]), - (["check"]), - (["check", "--catalog", "path"]), - (["check", "path"]), - ], - ) - def test_failed_parse(self, arg_list: List[str], destination: Destination): - # We use BaseException because it encompasses SystemExit (raised by failed parsing) and other exceptions (raised by additional semantic - # checks) - with pytest.raises(BaseException): - destination.parse_args(arg_list) - - -def _state(state: Dict[str, Any]) -> AirbyteStateMessage: - return AirbyteStateMessage(data=state) - - -def _record(stream: str, data: Dict[str, Any]) -> AirbyteRecordMessage: - return AirbyteRecordMessage(stream=stream, data=data, emitted_at=0) - - -def _spec(schema: Dict[str, Any]) -> ConnectorSpecification: - return ConnectorSpecification(connectionSpecification=schema) - - -def write_file(path: PathLike, content: Union[str, Mapping]): - content = json.dumps(content) if isinstance(content, Mapping) else content - with open(path, "w") as f: - f.write(content) - - -def _wrapped( - msg: Union[AirbyteRecordMessage, AirbyteStateMessage, AirbyteCatalog, ConnectorSpecification, AirbyteConnectionStatus] -) -> AirbyteMessage: - if isinstance(msg, AirbyteRecordMessage): - return AirbyteMessage(type=Type.RECORD, record=msg) - elif isinstance(msg, AirbyteStateMessage): - return AirbyteMessage(type=Type.STATE, state=msg) - elif isinstance(msg, AirbyteCatalog): - return AirbyteMessage(type=Type.CATALOG, catalog=msg) - elif isinstance(msg, AirbyteConnectionStatus): - return AirbyteMessage(type=Type.CONNECTION_STATUS, connectionStatus=msg) - elif isinstance(msg, ConnectorSpecification): - return AirbyteMessage(type=Type.SPEC, spec=msg) - else: - raise Exception(f"Invalid Airbyte Message: {msg}") - - -class OrderedIterableMatcher(Iterable): - """ - A class whose purpose is to verify equality of one iterable object against another - in an ordered fashion - """ - - def attempt_consume(self, iterator): - try: - return next(iterator) - except StopIteration: - return None - - def __iter__(self): - return iter(self.iterable) - - def __init__(self, iterable: Iterable): - self.iterable = iterable - - def __eq__(self, other): - if not isinstance(other, Iterable): - return False - - return list(self) == list(other) - - -class TestRun: - def test_run_initializes_exception_handler(self, mocker, destination: Destination): - mocker.patch.object(destination_module, "init_uncaught_exception_handler") - mocker.patch.object(destination, "parse_args") - mocker.patch.object(destination, "run_cmd") - destination.run(["dummy"]) - destination_module.init_uncaught_exception_handler.assert_called_once_with(destination_module.logger) - - def test_run_spec(self, mocker, destination: Destination): - args = {"command": "spec"} - parsed_args = argparse.Namespace(**args) - - expected_spec = ConnectorSpecification(connectionSpecification={"json_schema": {"prop": "value"}}) - mocker.patch.object(destination, "spec", return_value=expected_spec, autospec=True) - - spec_message = next(iter(destination.run_cmd(parsed_args))) - - # Mypy doesn't understand magicmock so it thinks spec doesn't have assert_called_once attr - destination.spec.assert_called_once() # type: ignore - - # verify the output of spec was returned - assert spec_message == _wrapped(expected_spec) - - def test_run_check(self, mocker, destination: Destination, tmp_path): - file_path = tmp_path / "config.json" - dummy_config = {"user": "sherif"} - write_file(file_path, dummy_config) - args = {"command": "check", "config": file_path} - - parsed_args = argparse.Namespace(**args) - destination.run_cmd(parsed_args) - spec_msg = ConnectorSpecification(connectionSpecification={}) - mocker.patch.object(destination, "spec", return_value=spec_msg) - validate_mock = mocker.patch("airbyte_cdk.destinations.destination.check_config_against_spec_or_exit") - expected_check_result = AirbyteConnectionStatus(status=Status.SUCCEEDED) - mocker.patch.object(destination, "check", return_value=expected_check_result, autospec=True) - - returned_check_result = next(iter(destination.run_cmd(parsed_args))) - # verify method call with the correct params - # Affirm to Mypy that this is indeed a method on this mock - destination.check.assert_called_once() # type: ignore - # Affirm to Mypy that this is indeed a method on this mock - destination.check.assert_called_with(logger=ANY, config=dummy_config) # type: ignore - # Check if config validation has been called - validate_mock.assert_called_with(dummy_config, spec_msg) - - # verify output was correct - assert returned_check_result == _wrapped(expected_check_result) - - def test_run_check_with_invalid_config(self, mocker, destination: Destination, tmp_path): - file_path = tmp_path / "config.json" - invalid_config = {"not": "valid"} - write_file(file_path, invalid_config) - args = {"command": "check", "config": file_path} - - parsed_args = argparse.Namespace(**args) - destination.run_cmd(parsed_args) - - spec = {"type": "integer"} - spec_msg = ConnectorSpecification(connectionSpecification=spec) - - mocker.patch.object(destination, "spec", return_value=spec_msg) - - # validation against spec happens first, so this should not be reached - mocker.patch.object(destination, "check") - - returned_check_result = next(iter(destination.run_cmd(parsed_args))) - - destination.spec.assert_called_once() # type: ignore - - # config validation against spec happens first, so this should not be reached - destination.check.assert_not_called() # type: ignore - - # verify output was correct - assert isinstance(returned_check_result, AirbyteMessage) - assert returned_check_result.type == Type.CONNECTION_STATUS - assert returned_check_result.connectionStatus.status == Status.FAILED - # the specific phrasing is not relevant, so only check for the keywords - assert "validation error" in returned_check_result.connectionStatus.message - - def test_run_write(self, mocker, destination: Destination, tmp_path, monkeypatch): - config_path, dummy_config = tmp_path / "config.json", {"user": "sherif"} - write_file(config_path, dummy_config) - - dummy_catalog = ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=AirbyteStream(name="mystream", json_schema={"type": "object"}, supported_sync_modes=[SyncMode.full_refresh]), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.overwrite, - ) - ] - ) - catalog_path = tmp_path / "catalog.json" - write_file(catalog_path, ConfiguredAirbyteCatalogSerializer.dump(dummy_catalog)) - - args = {"command": "write", "config": config_path, "catalog": catalog_path} - parsed_args = argparse.Namespace(**args) - - expected_write_result = [_wrapped(_state({"k1": "v1"})), _wrapped(_state({"k2": "v2"}))] - mocker.patch.object( - destination, "write", return_value=iter(expected_write_result), autospec=True # convert to iterator to mimic real usage - ) - spec_msg = ConnectorSpecification(connectionSpecification={}) - mocker.patch.object(destination, "spec", return_value=spec_msg) - validate_mock = mocker.patch("airbyte_cdk.destinations.destination.check_config_against_spec_or_exit") - # mock input is a record followed by some state messages - mocked_input: List[AirbyteMessage] = [_wrapped(_record("s1", {"k1": "v1"})), *expected_write_result] - mocked_stdin_string = "\n".join([orjson.dumps(AirbyteMessageSerializer.dump(record)).decode() for record in mocked_input]) - mocked_stdin_string += "\n add this non-serializable string to verify the destination does not break on malformed input" - mocked_stdin = io.TextIOWrapper(io.BytesIO(bytes(mocked_stdin_string, "utf-8"))) - - monkeypatch.setattr("sys.stdin", mocked_stdin) - - returned_write_result = list(destination.run_cmd(parsed_args)) - # verify method call with the correct params - # Affirm to Mypy that call_count is indeed a method on this mock - destination.write.assert_called_once() # type: ignore - # Affirm to Mypy that call_count is indeed a method on this mock - destination.write.assert_called_with( # type: ignore - config=dummy_config, - configured_catalog=dummy_catalog, - # Stdin is internally consumed as a generator so we use a custom matcher - # that iterates over two iterables to check equality - input_messages=OrderedIterableMatcher(mocked_input), - ) - # Check if config validation has been called - validate_mock.assert_called_with(dummy_config, spec_msg) - - # verify output was correct - assert returned_write_result == expected_write_result - - @pytest.mark.parametrize("args", [{}, {"command": "fake"}]) - def test_run_cmd_with_incorrect_args_fails(self, args, destination: Destination): - with pytest.raises(Exception): - list(destination.run_cmd(parsed_args=argparse.Namespace(**args))) diff --git a/airbyte-cdk/python/unit_tests/destinations/vector_db_based/config_test.py b/airbyte-cdk/python/unit_tests/destinations/vector_db_based/config_test.py deleted file mode 100644 index 0eeae37b7f3e..000000000000 --- a/airbyte-cdk/python/unit_tests/destinations/vector_db_based/config_test.py +++ /dev/null @@ -1,385 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Union - -import dpath -from airbyte_cdk.destinations.vector_db_based.config import ( - AzureOpenAIEmbeddingConfigModel, - CohereEmbeddingConfigModel, - FakeEmbeddingConfigModel, - OpenAICompatibleEmbeddingConfigModel, - OpenAIEmbeddingConfigModel, - ProcessingConfigModel, -) -from airbyte_cdk.utils.spec_schema_transformations import resolve_refs -from pydantic.v1 import BaseModel, Field - - -class IndexingModel(BaseModel): - foo: str = Field( - ..., - title="Foo", - description="Foo", - ) - - -class ConfigModel(BaseModel): - indexing: IndexingModel - - embedding: Union[ - OpenAIEmbeddingConfigModel, - CohereEmbeddingConfigModel, - FakeEmbeddingConfigModel, - AzureOpenAIEmbeddingConfigModel, - OpenAICompatibleEmbeddingConfigModel, - ] = Field( - ..., - title="Embedding", - description="Embedding configuration", - discriminator="mode", - group="embedding", - type="object", - ) - processing: ProcessingConfigModel - - class Config: - title = "My Destination Config" - schema_extra = { - "groups": [ - {"id": "processing", "title": "Processing"}, - {"id": "embedding", "title": "Embedding"}, - {"id": "indexing", "title": "Indexing"}, - ] - } - - @staticmethod - def remove_discriminator(schema: dict) -> None: - """pydantic adds "discriminator" to the schema for oneOfs, which is not treated right by the platform as we inline all references""" - dpath.delete(schema, "properties/**/discriminator") - - @classmethod - def schema(cls): - """we're overriding the schema classmethod to enable some post-processing""" - schema = super().schema() - schema = resolve_refs(schema) - cls.remove_discriminator(schema) - return schema - - -def test_json_schema_generation(): - # This is the expected output of the schema generation - expected = { - "title": "My Destination Config", - "type": "object", - "properties": { - "indexing": { - "title": "IndexingModel", - "type": "object", - "properties": {"foo": {"title": "Foo", "description": "Foo", "type": "string"}}, - "required": ["foo"], - }, - "embedding": { - "title": "Embedding", - "description": "Embedding configuration", - "group": "embedding", - "type": "object", - "oneOf": [ - { - "title": "OpenAI", - "type": "object", - "properties": { - "mode": { - "title": "Mode", - "default": "openai", - "const": "openai", - "enum": ["openai"], - "type": "string", - }, - "openai_key": { - "title": "OpenAI API key", - "airbyte_secret": True, - "type": "string", - }, - }, - "required": ["openai_key", "mode"], - "description": "Use the OpenAI API to embed text. This option is using the text-embedding-ada-002 model with 1536 embedding dimensions.", - }, - { - "title": "Cohere", - "type": "object", - "properties": { - "mode": { - "title": "Mode", - "default": "cohere", - "const": "cohere", - "enum": ["cohere"], - "type": "string", - }, - "cohere_key": { - "title": "Cohere API key", - "airbyte_secret": True, - "type": "string", - }, - }, - "required": ["cohere_key", "mode"], - "description": "Use the Cohere API to embed text.", - }, - { - "title": "Fake", - "type": "object", - "properties": { - "mode": { - "title": "Mode", - "default": "fake", - "const": "fake", - "enum": ["fake"], - "type": "string", - } - }, - "description": "Use a fake embedding made out of random vectors with 1536 embedding dimensions. This is useful for testing the data pipeline without incurring any costs.", - "required": ["mode"], - }, - { - "title": "Azure OpenAI", - "type": "object", - "properties": { - "mode": { - "title": "Mode", - "default": "azure_openai", - "const": "azure_openai", - "enum": ["azure_openai"], - "type": "string", - }, - "openai_key": { - "title": "Azure OpenAI API key", - "description": "The API key for your Azure OpenAI resource. You can find this in the Azure portal under your Azure OpenAI resource", - "airbyte_secret": True, - "type": "string", - }, - "api_base": { - "title": "Resource base URL", - "description": "The base URL for your Azure OpenAI resource. You can find this in the Azure portal under your Azure OpenAI resource", - "examples": ["https://your-resource-name.openai.azure.com"], - "type": "string", - }, - "deployment": { - "title": "Deployment", - "description": "The deployment for your Azure OpenAI resource. You can find this in the Azure portal under your Azure OpenAI resource", - "examples": ["your-resource-name"], - "type": "string", - }, - }, - "required": ["openai_key", "api_base", "deployment", "mode"], - "description": "Use the Azure-hosted OpenAI API to embed text. This option is using the text-embedding-ada-002 model with 1536 embedding dimensions.", - }, - { - "title": "OpenAI-compatible", - "type": "object", - "properties": { - "mode": { - "title": "Mode", - "default": "openai_compatible", - "const": "openai_compatible", - "enum": ["openai_compatible"], - "type": "string", - }, - "api_key": { - "title": "API key", - "default": "", - "airbyte_secret": True, - "type": "string", - }, - "base_url": { - "title": "Base URL", - "description": "The base URL for your OpenAI-compatible service", - "examples": ["https://your-service-name.com"], - "type": "string", - }, - "model_name": { - "title": "Model name", - "description": "The name of the model to use for embedding", - "default": "text-embedding-ada-002", - "examples": ["text-embedding-ada-002"], - "type": "string", - }, - "dimensions": { - "title": "Embedding dimensions", - "description": "The number of dimensions the embedding model is generating", - "examples": [1536, 384], - "type": "integer", - }, - }, - "required": ["base_url", "dimensions", "mode"], - "description": "Use a service that's compatible with the OpenAI API to embed text.", - }, - ], - }, - "processing": { - "title": "ProcessingConfigModel", - "type": "object", - "properties": { - "chunk_size": { - "title": "Chunk size", - "description": "Size of chunks in tokens to store in vector store (make sure it is not too big for the context if your LLM)", - "maximum": 8191, - "minimum": 1, - "type": "integer", - }, - "chunk_overlap": { - "title": "Chunk overlap", - "description": "Size of overlap between chunks in tokens to store in vector store to better capture relevant context", - "default": 0, - "type": "integer", - }, - "text_fields": { - "title": "Text fields to embed", - "description": "List of fields in the record that should be used to calculate the embedding. The field list is applied to all streams in the same way and non-existing fields are ignored. If none are defined, all fields are considered text fields. When specifying text fields, you can access nested fields in the record by using dot notation, e.g. `user.name` will access the `name` field in the `user` object. It's also possible to use wildcards to access all fields in an object, e.g. `users.*.name` will access all `names` fields in all entries of the `users` array.", - "default": [], - "always_show": True, - "examples": ["text", "user.name", "users.*.name"], - "type": "array", - "items": {"type": "string"}, - }, - "metadata_fields": { - "title": "Fields to store as metadata", - "description": "List of fields in the record that should be stored as metadata. The field list is applied to all streams in the same way and non-existing fields are ignored. If none are defined, all fields are considered metadata fields. When specifying text fields, you can access nested fields in the record by using dot notation, e.g. `user.name` will access the `name` field in the `user` object. It's also possible to use wildcards to access all fields in an object, e.g. `users.*.name` will access all `names` fields in all entries of the `users` array. When specifying nested paths, all matching values are flattened into an array set to a field named by the path.", - "default": [], - "always_show": True, - "examples": ["age", "user", "user.name"], - "type": "array", - "items": {"type": "string"}, - }, - "text_splitter": { - "title": "Text splitter", - "description": "Split text fields into chunks based on the specified method.", - "type": "object", - "oneOf": [ - { - "title": "By Separator", - "type": "object", - "properties": { - "mode": { - "title": "Mode", - "default": "separator", - "const": "separator", - "enum": ["separator"], - "type": "string", - }, - "separators": { - "title": "Separators", - "description": 'List of separator strings to split text fields by. The separator itself needs to be wrapped in double quotes, e.g. to split by the dot character, use ".". To split by a newline, use "\\n".', - "default": ['"\\n\\n"', '"\\n"', '" "', '""'], - "type": "array", - "items": {"type": "string"}, - }, - "keep_separator": { - "title": "Keep separator", - "description": "Whether to keep the separator in the resulting chunks", - "default": False, - "type": "boolean", - }, - }, - "description": "Split the text by the list of separators until the chunk size is reached, using the earlier mentioned separators where possible. This is useful for splitting text fields by paragraphs, sentences, words, etc.", - "required": ["mode"], - }, - { - "title": "By Markdown header", - "type": "object", - "properties": { - "mode": { - "title": "Mode", - "default": "markdown", - "const": "markdown", - "enum": ["markdown"], - "type": "string", - }, - "split_level": { - "title": "Split level", - "description": "Level of markdown headers to split text fields by. Headings down to the specified level will be used as split points", - "default": 1, - "minimum": 1, - "maximum": 6, - "type": "integer", - }, - }, - "description": "Split the text by Markdown headers down to the specified header level. If the chunk size fits multiple sections, they will be combined into a single chunk.", - "required": ["mode"], - }, - { - "title": "By Programming Language", - "type": "object", - "properties": { - "mode": { - "title": "Mode", - "default": "code", - "const": "code", - "enum": ["code"], - "type": "string", - }, - "language": { - "title": "Language", - "description": "Split code in suitable places based on the programming language", - "enum": [ - "cpp", - "go", - "java", - "js", - "php", - "proto", - "python", - "rst", - "ruby", - "rust", - "scala", - "swift", - "markdown", - "latex", - "html", - "sol", - ], - "type": "string", - }, - }, - "required": ["language", "mode"], - "description": "Split the text by suitable delimiters based on the programming language. This is useful for splitting code into chunks.", - }, - ], - }, - "field_name_mappings": { - "title": "Field name mappings", - "description": "List of fields to rename. Not applicable for nested fields, but can be used to rename fields already flattened via dot notation.", - "default": [], - "type": "array", - "items": { - "title": "FieldNameMappingConfigModel", - "type": "object", - "properties": { - "from_field": { - "title": "From field name", - "description": "The field name in the source", - "type": "string", - }, - "to_field": { - "title": "To field name", - "description": "The field name to use in the destination", - "type": "string", - }, - }, - "required": ["from_field", "to_field"], - }, - }, - }, - "required": ["chunk_size"], - "group": "processing", - }, - }, - "required": ["indexing", "embedding", "processing"], - "groups": [ - {"id": "processing", "title": "Processing"}, - {"id": "embedding", "title": "Embedding"}, - {"id": "indexing", "title": "Indexing"}, - ], - } - assert ConfigModel.schema() == expected diff --git a/airbyte-cdk/python/unit_tests/destinations/vector_db_based/document_processor_test.py b/airbyte-cdk/python/unit_tests/destinations/vector_db_based/document_processor_test.py deleted file mode 100644 index db3ce730c89e..000000000000 --- a/airbyte-cdk/python/unit_tests/destinations/vector_db_based/document_processor_test.py +++ /dev/null @@ -1,664 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, List, Mapping, Optional -from unittest.mock import MagicMock - -import pytest -from airbyte_cdk.destinations.vector_db_based.config import ( - CodeSplitterConfigModel, - FieldNameMappingConfigModel, - MarkdownHeaderSplitterConfigModel, - ProcessingConfigModel, - SeparatorSplitterConfigModel, -) -from airbyte_cdk.destinations.vector_db_based.document_processor import DocumentProcessor -from airbyte_cdk.models import ( - AirbyteRecordMessage, - AirbyteStream, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteStream, - DestinationSyncMode, - SyncMode, -) -from airbyte_cdk.utils.traced_exception import AirbyteTracedException - - -def initialize_processor(config=ProcessingConfigModel(chunk_size=48, chunk_overlap=0, text_fields=None, metadata_fields=None)): - catalog = ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=AirbyteStream( - name="stream1", - json_schema={}, - namespace="namespace1", - supported_sync_modes=[SyncMode.full_refresh], - ), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.overwrite, - primary_key=[["id"]], - ), - ConfiguredAirbyteStream( - stream=AirbyteStream( - name="stream2", - json_schema={}, - supported_sync_modes=[SyncMode.full_refresh], - ), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.overwrite, - ), - ] - ) - return DocumentProcessor(config=config, catalog=catalog) - - -@pytest.mark.parametrize( - "metadata_fields, expected_metadata", - [ - ( - None, - { - "_ab_stream": "namespace1_stream1", - "id": 1, - "text": "This is the text", - "complex": {"test": "abc"}, - "arr": [{"test": "abc"}, {"test": "def"}], - }, - ), - (["id"], {"_ab_stream": "namespace1_stream1", "id": 1}), - (["id", "non_existing"], {"_ab_stream": "namespace1_stream1", "id": 1}), - ( - ["id", "complex.test"], - {"_ab_stream": "namespace1_stream1", "id": 1, "complex.test": "abc"}, - ), - ( - ["id", "arr.*.test"], - {"_ab_stream": "namespace1_stream1", "id": 1, "arr.*.test": ["abc", "def"]}, - ), - ], -) -def test_process_single_chunk_with_metadata(metadata_fields, expected_metadata): - processor = initialize_processor() - processor.metadata_fields = metadata_fields - - record = AirbyteRecordMessage( - stream="stream1", - namespace="namespace1", - data={ - "id": 1, - "text": "This is the text", - "complex": {"test": "abc"}, - "arr": [{"test": "abc"}, {"test": "def"}], - }, - emitted_at=1234, - ) - - chunks, id_to_delete = processor.process(record) - - assert len(chunks) == 1 - # natural id is only set for dedup mode - assert "_ab_record_id" not in chunks[0].metadata - assert chunks[0].metadata == expected_metadata - assert id_to_delete is None - - -def test_process_single_chunk_limited_metadata(): - processor = initialize_processor() - - record = AirbyteRecordMessage( - stream="stream1", - namespace="namespace1", - data={ - "id": 1, - "text": "This is the text", - }, - emitted_at=1234, - ) - - chunks, id_to_delete = processor.process(record) - - assert len(chunks) == 1 - # natural id is only set for dedup mode - assert "_ab_record_id" not in chunks[0].metadata - assert chunks[0].metadata["_ab_stream"] == "namespace1_stream1" - assert chunks[0].metadata["id"] == 1 - assert chunks[0].metadata["text"] == "This is the text" - assert chunks[0].page_content == "id: 1\ntext: This is the text" - assert id_to_delete is None - - -def test_process_single_chunk_without_namespace(): - config = ProcessingConfigModel(chunk_size=48, chunk_overlap=0, text_fields=None, metadata_fields=None) - catalog = ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=AirbyteStream( - name="stream1", - json_schema={}, - supported_sync_modes=[SyncMode.full_refresh], - ), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.overwrite, - ), - ] - ) - processor = DocumentProcessor(config=config, catalog=catalog) - - record = AirbyteRecordMessage( - stream="stream1", - data={ - "id": 1, - "text": "This is the text", - }, - emitted_at=1234, - ) - - chunks, _ = processor.process(record) - assert chunks[0].metadata["_ab_stream"] == "stream1" - - -def test_complex_text_fields(): - processor = initialize_processor() - - record = AirbyteRecordMessage( - stream="stream1", - namespace="namespace1", - data={ - "id": 1, - "nested": { - "texts": [ - {"text": "This is the text"}, - {"text": "And another"}, - ] - }, - "non_text": "a", - "non_text_2": 1, - "text": "This is the regular text", - "other_nested": {"non_text": {"a": "xyz", "b": "abc"}}, - }, - emitted_at=1234, - ) - - processor.text_fields = [ - "nested.texts.*.text", - "text", - "other_nested.non_text", - "non.*.existing", - ] - processor.metadata_fields = ["non_text", "non_text_2", "id"] - - chunks, _ = processor.process(record) - - assert len(chunks) == 1 - assert ( - chunks[0].page_content - == """nested.texts.*.text: This is the text -And another -text: This is the regular text -other_nested.non_text: \na: xyz -b: abc""" - ) - assert chunks[0].metadata == { - "id": 1, - "non_text": "a", - "non_text_2": 1, - "_ab_stream": "namespace1_stream1", - } - - -def test_no_text_fields(): - processor = initialize_processor() - - record = AirbyteRecordMessage( - stream="stream1", - namespace="namespace1", - data={ - "id": 1, - "text": "This is the regular text", - }, - emitted_at=1234, - ) - - processor.text_fields = ["another_field"] - processor.logger = MagicMock() - - # assert process is throwing with no text fields found - with pytest.raises(AirbyteTracedException): - processor.process(record) - - -def test_process_multiple_chunks_with_relevant_fields(): - processor = initialize_processor() - - record = AirbyteRecordMessage( - stream="stream1", - namespace="namespace1", - data={ - "id": 1, - "name": "John Doe", - "text": "This is the text and it is long enough to be split into multiple chunks. This is the text and it is long enough to be split into multiple chunks. This is the text and it is long enough to be split into multiple chunks", - "age": 25, - }, - emitted_at=1234, - ) - - processor.text_fields = ["text"] - - chunks, id_to_delete = processor.process(record) - - assert len(chunks) == 2 - - for chunk in chunks: - assert chunk.metadata["age"] == 25 - assert id_to_delete is None - - -@pytest.mark.parametrize( - "label, text, chunk_size, chunk_overlap, splitter_config, expected_chunks", - [ - ( - "Default splitting", - "By default, splits are done \non multi newlines,\n\n then single newlines, then spaces", - 10, - 0, - None, - [ - "text: By default, splits are done", - "on multi newlines,", - "then single newlines, then spaces", - ], - ), - ( - "Overlap splitting", - "One two three four five six seven eight nine ten eleven twelve thirteen", - 15, - 5, - None, - [ - "text: One two three four five six", - "four five six seven eight nine ten", - "eight nine ten eleven twelve thirteen", - ], - ), - ( - "Special tokens", - "Special tokens like <|endoftext|> are treated like regular text", - 15, - 0, - None, - [ - "text: Special tokens like", - "<|endoftext|> are treated like regular", - "text", - ], - ), - ( - "Custom separator", - "Custom \nseparatorxxxDoes not split on \n\nnewlines", - 10, - 0, - SeparatorSplitterConfigModel(mode="separator", separators=['"xxx"']), - [ - "text: Custom \nseparator", - "Does not split on \n\nnewlines\n", - ], - ), - ( - "Only splits if chunks dont fit", - "Does yyynot usexxxseparators yyyif not needed", - 10, - 0, - SeparatorSplitterConfigModel(mode="separator", separators=['"xxx"', '"yyy"']), - [ - "text: Does yyynot use", - "separators yyyif not needed", - ], - ), - ( - "Use first separator first", - "Does alwaysyyy usexxxmain separators yyyfirst", - 10, - 0, - SeparatorSplitterConfigModel(mode="separator", separators=['"yyy"', '"xxx"']), - [ - "text: Does always", - "usexxxmain separators yyyfirst", - ], - ), - ( - "Basic markdown splitting", - "# Heading 1\nText 1\n\n# Heading 2\nText 2\n\n# Heading 3\nText 3", - 10, - 0, - MarkdownHeaderSplitterConfigModel(mode="markdown", split_level=1), - [ - "text: # Heading 1\nText 1\n", - "# Heading 2\nText 2", - "# Heading 3\nText 3", - ], - ), - ( - "Split multiple levels", - "# Heading 1\nText 1\n\n## Sub-Heading 1\nText 2\n\n# Heading 2\nText 3", - 10, - 0, - MarkdownHeaderSplitterConfigModel(mode="markdown", split_level=2), - [ - "text: # Heading 1\nText 1\n", - "\n## Sub-Heading 1\nText 2\n", - "# Heading 2\nText 3", - ], - ), - ( - "Do not split if split level does not allow", - "## Heading 1\nText 1\n\n## Heading 2\nText 2\n\n## Heading 3\nText 3", - 10, - 0, - MarkdownHeaderSplitterConfigModel(mode="markdown", split_level=1), - [ - "text: ## Heading 1\nText 1\n\n## Heading 2\nText 2\n\n## Heading 3\nText 3\n", - ], - ), - ( - "Do not split if everything fits", - "## Does not split if everything fits. Heading 1\nText 1\n\n## Heading 2\nText 2\n\n## Heading 3\nText 3", - 1000, - 0, - MarkdownHeaderSplitterConfigModel(mode="markdown", split_level=5), - [ - "text: ## Does not split if everything fits. Heading 1\nText 1\n\n## Heading 2\nText 2\n\n## Heading 3\nText 3", - ], - ), - ( - "Split Java code, respecting class boundaries", - "class A { /* \n\nthis is the first class */ }\nclass B {}", - 20, - 0, - CodeSplitterConfigModel(mode="code", language="java"), - [ - "text: class A { /* \n\nthis is the first class */ }", - "class B {}", - ], - ), - ( - "Split Java code as proto, not respecting class boundaries", - "class A { /* \n\nthis is the first class */ }\nclass B {}", - 20, - 0, - CodeSplitterConfigModel(mode="code", language="proto"), - [ - "text: class A { /*", - "this is the first class */ }\nclass B {}", - ], - ), - ], -) -def test_text_splitters(label, text, chunk_size, chunk_overlap, splitter_config, expected_chunks): - processor = initialize_processor( - ProcessingConfigModel( - chunk_size=chunk_size, - chunk_overlap=chunk_overlap, - text_fields=["text"], - metadata_fields=None, - text_splitter=splitter_config, - ) - ) - - record = AirbyteRecordMessage( - stream="stream1", - namespace="namespace1", - data={ - "id": 1, - "name": "John Doe", - "text": text, - "age": 25, - }, - emitted_at=1234, - ) - - processor.text_fields = ["text"] - - chunks, id_to_delete = processor.process(record) - - assert len(chunks) == len(expected_chunks) - - # check that the page_content in each chunk equals the expected chunk - for i, chunk in enumerate(chunks): - print(chunk.page_content) - assert chunk.page_content == expected_chunks[i] - assert id_to_delete is None - - -@pytest.mark.parametrize( - "label, split_config, has_error_message", - [ - ( - "Invalid separator", - SeparatorSplitterConfigModel(mode="separator", separators=['"xxx']), - True, - ), - ( - "Missing quotes", - SeparatorSplitterConfigModel(mode="separator", separators=["xxx"]), - True, - ), - ( - "Non-string separator", - SeparatorSplitterConfigModel(mode="separator", separators=["123"]), - True, - ), - ( - "Object separator", - SeparatorSplitterConfigModel(mode="separator", separators=["{}"]), - True, - ), - ( - "Proper separator", - SeparatorSplitterConfigModel(mode="separator", separators=['"xxx"', '"\\n\\n"']), - False, - ), - ], -) -def test_text_splitter_check(label, split_config, has_error_message): - error = DocumentProcessor.check_config( - ProcessingConfigModel( - chunk_size=48, - chunk_overlap=0, - text_fields=None, - metadata_fields=None, - text_splitter=split_config, - ) - ) - if has_error_message: - assert error is not None - else: - assert error is None - - -@pytest.mark.parametrize( - "mappings, fields, expected_chunk_metadata", - [ - (None, {"abc": "def", "xyz": 123}, {"abc": "def", "xyz": 123}), - ([], {"abc": "def", "xyz": 123}, {"abc": "def", "xyz": 123}), - ( - [FieldNameMappingConfigModel(from_field="abc", to_field="AAA")], - {"abc": "def", "xyz": 123}, - {"AAA": "def", "xyz": 123}, - ), - ( - [FieldNameMappingConfigModel(from_field="non_existing", to_field="AAA")], - {"abc": "def", "xyz": 123}, - {"abc": "def", "xyz": 123}, - ), - ], -) -def test_rename_metadata_fields( - mappings: Optional[List[FieldNameMappingConfigModel]], - fields: Mapping[str, Any], - expected_chunk_metadata: Mapping[str, Any], -): - processor = initialize_processor() - - record = AirbyteRecordMessage( - stream="stream1", - namespace="namespace1", - data={**fields, "text": "abc"}, - emitted_at=1234, - ) - - processor.field_name_mappings = mappings - processor.text_fields = ["text"] - - chunks, id_to_delete = processor.process(record) - - assert len(chunks) == 1 - assert chunks[0].metadata == { - **expected_chunk_metadata, - "_ab_stream": "namespace1_stream1", - "text": "abc", - } - - -@pytest.mark.parametrize( - "primary_key_value, stringified_primary_key, primary_key", - [ - ({"id": 99}, "namespace1_stream1_99", [["id"]]), - ( - {"id": 99, "name": "John Doe"}, - "namespace1_stream1_99_John Doe", - [["id"], ["name"]], - ), - ( - {"id": 99, "name": "John Doe", "age": 25}, - "namespace1_stream1_99_John Doe_25", - [["id"], ["name"], ["age"]], - ), - ( - {"nested": {"id": "abc"}, "name": "John Doe"}, - "namespace1_stream1_abc_John Doe", - [["nested", "id"], ["name"]], - ), - ( - {"nested": {"id": "abc"}}, - "namespace1_stream1_abc___not_found__", - [["nested", "id"], ["name"]], - ), - ], -) -def test_process_multiple_chunks_with_dedupe_mode( - primary_key_value: Mapping[str, Any], - stringified_primary_key: str, - primary_key: List[List[str]], -): - processor = initialize_processor() - - record = AirbyteRecordMessage( - stream="stream1", - namespace="namespace1", - data={ - "text": "This is the text and it is long enough to be split into multiple chunks. This is the text and it is long enough to be split into multiple chunks. This is the text and it is long enough to be split into multiple chunks", - "age": 25, - **primary_key_value, - }, - emitted_at=1234, - ) - - processor.text_fields = ["text"] - - processor.streams["namespace1_stream1"].destination_sync_mode = DestinationSyncMode.append_dedup - processor.streams["namespace1_stream1"].primary_key = primary_key - - chunks, id_to_delete = processor.process(record) - - assert len(chunks) > 1 - for chunk in chunks: - assert chunk.metadata["_ab_record_id"] == stringified_primary_key - assert id_to_delete == stringified_primary_key - - -@pytest.mark.parametrize( - "record, sync_mode, has_chunks, raises, expected_id_to_delete", - [ - pytest.param( - AirbyteRecordMessage( - stream="stream1", - namespace="namespace1", - data={"text": "This is the text", "id": "1"}, - emitted_at=1234, - ), - DestinationSyncMode.append_dedup, - True, - False, - "namespace1_stream1_1", - id="update", - ), - pytest.param( - AirbyteRecordMessage( - stream="stream1", - namespace="namespace1", - data={"text": "This is the text", "id": "1"}, - emitted_at=1234, - ), - DestinationSyncMode.append, - True, - False, - None, - id="append", - ), - pytest.param( - AirbyteRecordMessage( - stream="stream1", - namespace="namespace1", - data={"text": "This is the text", "id": "1", "_ab_cdc_deleted_at": 1234}, - emitted_at=1234, - ), - DestinationSyncMode.append_dedup, - False, - False, - "namespace1_stream1_1", - id="cdc_delete", - ), - pytest.param( - AirbyteRecordMessage( - stream="stream1", - namespace="namespace1", - data={"id": "1", "_ab_cdc_deleted_at": 1234}, - emitted_at=1234, - ), - DestinationSyncMode.append_dedup, - False, - False, - "namespace1_stream1_1", - id="cdc_delete_without_text", - ), - pytest.param( - AirbyteRecordMessage( - stream="stream1", - namespace="namespace1", - data={"id": "1"}, - emitted_at=1234, - ), - DestinationSyncMode.append_dedup, - False, - True, - "namespace1_stream1_1", - id="update_without_text", - ), - ], -) -def test_process_cdc_records(record, sync_mode, has_chunks, raises, expected_id_to_delete): - processor = initialize_processor() - - processor.text_fields = ["text"] - - processor.streams["namespace1_stream1"].destination_sync_mode = sync_mode - - if raises: - with pytest.raises(AirbyteTracedException): - processor.process(record) - else: - chunks, id_to_delete = processor.process(record) - if has_chunks: - assert len(chunks) > 0 - assert id_to_delete == expected_id_to_delete diff --git a/airbyte-cdk/python/unit_tests/destinations/vector_db_based/embedder_test.py b/airbyte-cdk/python/unit_tests/destinations/vector_db_based/embedder_test.py deleted file mode 100644 index 600a4c0890d3..000000000000 --- a/airbyte-cdk/python/unit_tests/destinations/vector_db_based/embedder_test.py +++ /dev/null @@ -1,123 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from unittest.mock import MagicMock, call - -import pytest -from airbyte_cdk.destinations.vector_db_based.config import ( - AzureOpenAIEmbeddingConfigModel, - CohereEmbeddingConfigModel, - FakeEmbeddingConfigModel, - FromFieldEmbeddingConfigModel, - OpenAICompatibleEmbeddingConfigModel, - OpenAIEmbeddingConfigModel, -) -from airbyte_cdk.destinations.vector_db_based.embedder import ( - COHERE_VECTOR_SIZE, - OPEN_AI_VECTOR_SIZE, - AzureOpenAIEmbedder, - CohereEmbedder, - Document, - FakeEmbedder, - FromFieldEmbedder, - OpenAICompatibleEmbedder, - OpenAIEmbedder, -) -from airbyte_cdk.models import AirbyteRecordMessage -from airbyte_cdk.utils.traced_exception import AirbyteTracedException - - -@pytest.mark.parametrize( - "embedder_class, args, dimensions", - ( - (OpenAIEmbedder, [OpenAIEmbeddingConfigModel(**{"mode": "openai", "openai_key": "abc"}), 1000], OPEN_AI_VECTOR_SIZE), - (CohereEmbedder, [CohereEmbeddingConfigModel(**{"mode": "cohere", "cohere_key": "abc"})], COHERE_VECTOR_SIZE), - (FakeEmbedder, [FakeEmbeddingConfigModel(**{"mode": "fake"})], OPEN_AI_VECTOR_SIZE), - ( - AzureOpenAIEmbedder, - [ - AzureOpenAIEmbeddingConfigModel( - **{ - "mode": "azure_openai", - "openai_key": "abc", - "api_base": "https://my-resource.openai.azure.com", - "deployment": "my-deployment", - } - ), - 1000, - ], - OPEN_AI_VECTOR_SIZE, - ), - ( - OpenAICompatibleEmbedder, - [ - OpenAICompatibleEmbeddingConfigModel( - **{ - "mode": "openai_compatible", - "api_key": "abc", - "base_url": "https://my-service.com", - "model_name": "text-embedding-ada-002", - "dimensions": 50, - } - ) - ], - 50, - ), - ), -) -def test_embedder(embedder_class, args, dimensions): - embedder = embedder_class(*args) - mock_embedding_instance = MagicMock() - embedder.embeddings = mock_embedding_instance - - mock_embedding_instance.embed_query.side_effect = Exception("Some error") - assert embedder.check().startswith("Some error") - - mock_embedding_instance.embed_query.side_effect = None - assert embedder.check() is None - - assert embedder.embedding_dimensions == dimensions - - mock_embedding_instance.embed_documents.return_value = [[0] * dimensions] * 2 - - chunks = [ - Document(page_content="a", record=AirbyteRecordMessage(stream="mystream", data={}, emitted_at=0)), - Document(page_content="b", record=AirbyteRecordMessage(stream="mystream", data={}, emitted_at=0)), - ] - assert embedder.embed_documents(chunks) == mock_embedding_instance.embed_documents.return_value - mock_embedding_instance.embed_documents.assert_called_with(["a", "b"]) - - -@pytest.mark.parametrize( - "field_name, dimensions, metadata, expected_embedding, expected_error", - ( - ("a", 2, {"a": [1, 2]}, [1, 2], False), - ("a", 2, {"b": "b"}, None, True), - ("a", 2, {}, None, True), - ("a", 2, {"a": []}, None, True), - ("a", 2, {"a": [1, 2, 3]}, None, True), - ("a", 2, {"a": [1, "2", 3]}, None, True), - ), -) -def test_from_field_embedder(field_name, dimensions, metadata, expected_embedding, expected_error): - embedder = FromFieldEmbedder(FromFieldEmbeddingConfigModel(mode="from_field", dimensions=dimensions, field_name=field_name)) - chunks = [Document(page_content="a", record=AirbyteRecordMessage(stream="mystream", data=metadata, emitted_at=0))] - if expected_error: - with pytest.raises(AirbyteTracedException): - embedder.embed_documents(chunks) - else: - assert embedder.embed_documents(chunks) == [expected_embedding] - - -def test_openai_chunking(): - config = OpenAIEmbeddingConfigModel(**{"mode": "openai", "openai_key": "abc"}) - embedder = OpenAIEmbedder(config, 150) - mock_embedding_instance = MagicMock() - embedder.embeddings = mock_embedding_instance - - mock_embedding_instance.embed_documents.side_effect = lambda texts: [[0] * OPEN_AI_VECTOR_SIZE] * len(texts) - - chunks = [Document(page_content="a", record=AirbyteRecordMessage(stream="mystream", data={}, emitted_at=0)) for _ in range(1005)] - assert embedder.embed_documents(chunks) == [[0] * OPEN_AI_VECTOR_SIZE] * 1005 - mock_embedding_instance.embed_documents.assert_has_calls([call(["a"] * 1000), call(["a"] * 5)]) diff --git a/airbyte-cdk/python/unit_tests/destinations/vector_db_based/writer_test.py b/airbyte-cdk/python/unit_tests/destinations/vector_db_based/writer_test.py deleted file mode 100644 index ac831694c726..000000000000 --- a/airbyte-cdk/python/unit_tests/destinations/vector_db_based/writer_test.py +++ /dev/null @@ -1,173 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Optional -from unittest.mock import ANY, MagicMock, call - -import pytest -from airbyte_cdk.destinations.vector_db_based import ProcessingConfigModel, Writer -from airbyte_cdk.models import ( - AirbyteLogMessage, - AirbyteMessage, - AirbyteRecordMessage, - AirbyteStateMessage, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteCatalogSerializer, - Level, - Type, -) - - -def _generate_record_message(index: int, stream: str = "example_stream", namespace: Optional[str] = None): - return AirbyteMessage( - type=Type.RECORD, - record=AirbyteRecordMessage( - stream=stream, namespace=namespace, emitted_at=1234, data={"column_name": f"value {index}", "id": index} - ), - ) - - -BATCH_SIZE = 32 - - -def generate_stream(name: str = "example_stream", namespace: Optional[str] = None): - return { - "stream": { - "name": name, - "namespace": namespace, - "json_schema": {"$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": {}}, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": False, - "default_cursor_field": ["column_name"], - }, - "primary_key": [["id"]], - "sync_mode": "incremental", - "destination_sync_mode": "append_dedup", - } - - -def generate_mock_embedder(): - mock_embedder = MagicMock() - mock_embedder.embed_documents.return_value = [[0] * 1536] * (BATCH_SIZE + 5 + 5) - mock_embedder.embed_documents.side_effect = lambda chunks: [[0] * 1536] * len(chunks) - - return mock_embedder - - -@pytest.mark.parametrize("omit_raw_text", [True, False]) -def test_write(omit_raw_text: bool): - """ - Basic test for the write method, batcher and document processor. - """ - config_model = ProcessingConfigModel(chunk_overlap=0, chunk_size=1000, metadata_fields=None, text_fields=["column_name"]) - - configured_catalog: ConfiguredAirbyteCatalog = ConfiguredAirbyteCatalogSerializer.load({"streams": [generate_stream()]}) - # messages are flushed after 32 records or after a state message, so this will trigger two batches to be processed - input_messages = [_generate_record_message(i) for i in range(BATCH_SIZE + 5)] - state_message = AirbyteMessage(type=Type.STATE, state=AirbyteStateMessage()) - input_messages.append(state_message) - # messages are also flushed once the input messages are exhausted, so this will trigger another batch - input_messages.extend([_generate_record_message(i) for i in range(5)]) - - mock_embedder = generate_mock_embedder() - - mock_indexer = MagicMock() - post_sync_log_message = AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=Level.INFO, message="post sync")) - mock_indexer.post_sync.return_value = [post_sync_log_message] - - # Create the DestinationLangchain instance - writer = Writer(config_model, mock_indexer, mock_embedder, BATCH_SIZE, omit_raw_text) - - output_messages = writer.write(configured_catalog, input_messages) - output_message = next(output_messages) - # assert state message is - assert output_message == state_message - - mock_indexer.pre_sync.assert_called_with(configured_catalog) - - # 1 batches due to max batch size reached and 1 batch due to state message - assert mock_indexer.index.call_count == 2 - assert mock_indexer.delete.call_count == 2 - assert mock_embedder.embed_documents.call_count == 2 - - if omit_raw_text: - for call_args in mock_indexer.index.call_args_list: - for chunk in call_args[0][0]: - if omit_raw_text: - assert chunk.page_content is None - else: - assert chunk.page_content is not None - - output_message = next(output_messages) - assert output_message == post_sync_log_message - - try: - next(output_messages) - assert False, "Expected end of message stream" - except StopIteration: - pass - - # 1 batch due to end of message stream - assert mock_indexer.index.call_count == 3 - assert mock_indexer.delete.call_count == 3 - assert mock_embedder.embed_documents.call_count == 3 - - mock_indexer.post_sync.assert_called() - - -def test_write_stream_namespace_split(): - """ - Test separate handling of streams and namespaces in the writer - - generate BATCH_SIZE - 10 records for example_stream, 5 records for example_stream with namespace abc and 10 records for example_stream2 - messages are flushed after 32 records or after a state message, so this will trigger 4 calls to the indexer: - * out of the first batch of 32, example_stream, example stream with namespace abd and the first 5 records for example_stream2 - * in the second batch, the remaining 5 records for example_stream2 - """ - config_model = ProcessingConfigModel(chunk_overlap=0, chunk_size=1000, metadata_fields=None, text_fields=["column_name"]) - - configured_catalog: ConfiguredAirbyteCatalog = ConfiguredAirbyteCatalogSerializer.load( - { - "streams": [ - generate_stream(), - generate_stream(namespace="abc"), - generate_stream("example_stream2"), - ] - } - ) - - input_messages = [_generate_record_message(i, "example_stream", None) for i in range(BATCH_SIZE - 10)] - input_messages.extend([_generate_record_message(i, "example_stream", "abc") for i in range(5)]) - input_messages.extend([_generate_record_message(i, "example_stream2", None) for i in range(10)]) - state_message = AirbyteMessage(type=Type.STATE, state=AirbyteStateMessage()) - input_messages.append(state_message) - - mock_embedder = generate_mock_embedder() - - mock_indexer = MagicMock() - mock_indexer.post_sync.return_value = [] - - # Create the DestinationLangchain instance - writer = Writer(config_model, mock_indexer, mock_embedder, BATCH_SIZE, False) - - output_messages = writer.write(configured_catalog, input_messages) - next(output_messages) - - mock_indexer.index.assert_has_calls( - [ - call(ANY, None, "example_stream"), - call(ANY, "abc", "example_stream"), - call(ANY, None, "example_stream2"), - call(ANY, None, "example_stream2"), - ] - ) - mock_indexer.index.assert_has_calls( - [ - call(ANY, None, "example_stream"), - call(ANY, "abc", "example_stream"), - call(ANY, None, "example_stream2"), - call(ANY, None, "example_stream2"), - ] - ) - assert mock_embedder.embed_documents.call_count == 4 diff --git a/airbyte-cdk/python/unit_tests/resource/http/response/test-resource.json b/airbyte-cdk/python/unit_tests/resource/http/response/test-resource.json deleted file mode 100644 index 667ec0669008..000000000000 --- a/airbyte-cdk/python/unit_tests/resource/http/response/test-resource.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "test-source template": "this is a template for test-resource" -} diff --git a/airbyte-cdk/python/unit_tests/sources/__init__.py b/airbyte-cdk/python/unit_tests/sources/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/concurrent_source/__init__.py b/airbyte-cdk/python/unit_tests/sources/concurrent_source/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/concurrent_source/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/concurrent_source/test_concurrent_source_adapter.py b/airbyte-cdk/python/unit_tests/sources/concurrent_source/test_concurrent_source_adapter.py deleted file mode 100644 index 22c5d34a6a9c..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/concurrent_source/test_concurrent_source_adapter.py +++ /dev/null @@ -1,169 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from typing import Any, List, Mapping, Optional, Tuple -from unittest.mock import Mock - -import freezegun -import pytest -from airbyte_cdk.models import ( - AirbyteMessage, - AirbyteRecordMessage, - AirbyteStream, - AirbyteStreamStatus, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteStream, - DestinationSyncMode, - FailureType, - SyncMode, - TraceType, -) -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.concurrent_source.concurrent_source_adapter import ConcurrentSourceAdapter -from airbyte_cdk.sources.message import InMemoryMessageRepository -from airbyte_cdk.sources.streams import Stream -from airbyte_cdk.utils.traced_exception import AirbyteTracedException - - -class _MockSource(ConcurrentSourceAdapter): - def __init__(self, concurrent_source, _streams_to_is_concurrent, logger, raise_exception_on_missing_stream=True): - super().__init__(concurrent_source) - self._streams_to_is_concurrent = _streams_to_is_concurrent - self._logger = logger - self._raise_exception_on_missing_stream = raise_exception_on_missing_stream - - message_repository = InMemoryMessageRepository() - - def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Optional[Any]]: - raise NotImplementedError - - def streams(self, config: Mapping[str, Any]) -> List[Stream]: - return [ - self.convert_to_concurrent_stream(self._logger, s, Mock()) - if is_concurrent - else s - for s, is_concurrent in self._streams_to_is_concurrent.items() - ] - - @property - def raise_exception_on_missing_stream(self): - """The getter method.""" - return self._raise_exception_on_missing_stream - - @raise_exception_on_missing_stream.setter - def raise_exception_on_missing_stream(self, value): - self._raise_exception_on_missing_stream = value - - -@freezegun.freeze_time("2020-01-01T00:00:00") -def test_concurrent_source_adapter(as_stream_status, remove_stack_trace): - concurrent_source = Mock() - message_from_concurrent_stream = AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage( - stream="s2", - data={"data": 2}, - emitted_at=1577836800000, - ), - ) - concurrent_source.read.return_value = iter([message_from_concurrent_stream]) - regular_stream = _mock_stream("s1", [{"data": 1}]) - concurrent_stream = _mock_stream("s2", []) - unavailable_stream = _mock_stream("s3", [{"data": 3}], False) - concurrent_stream.name = "s2" - logger = Mock() - adapter = _MockSource(concurrent_source, {regular_stream: False, concurrent_stream: True}, logger) - with pytest.raises(AirbyteTracedException): - messages = [] - for message in adapter.read(logger, {}, _configured_catalog([regular_stream, concurrent_stream, unavailable_stream])): - messages.append(message) - - records = [m for m in messages if m.type == MessageType.RECORD] - - expected_records = [ - message_from_concurrent_stream, - AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage( - stream="s1", - data={"data": 1}, - emitted_at=1577836800000, - ), - ), - ] - - assert records == expected_records - - unavailable_stream_trace_messages = [ - m - for m in messages - if m.type == MessageType.TRACE - and m.trace.type == TraceType.STREAM_STATUS - and m.trace.stream_status.status == AirbyteStreamStatus.INCOMPLETE - ] - expected_status = [as_stream_status("s3", AirbyteStreamStatus.INCOMPLETE)] - - assert len(unavailable_stream_trace_messages) == 1 - assert unavailable_stream_trace_messages[0].trace.stream_status == expected_status[0].trace.stream_status - - -def _mock_stream(name: str, data=[], available: bool = True): - s = Mock() - s.name = name - s.namespace = None - s.as_airbyte_stream.return_value = AirbyteStream( - name=name, - json_schema={}, - supported_sync_modes=[SyncMode.full_refresh], - ) - s.check_availability.return_value = (True, None) if available else (False, "not available") - s.get_json_schema.return_value = {} - s.read.return_value = iter(data) - s.primary_key = None - return s - - -def _configured_catalog(streams: List[Stream]): - return ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=stream.as_airbyte_stream(), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.overwrite, - ) - for stream in streams - ] - ) - - -@pytest.mark.parametrize("raise_exception_on_missing_stream", [True, False]) -def test_read_nonexistent_concurrent_stream_emit_incomplete_stream_status( - mocker, remove_stack_trace, as_stream_status, raise_exception_on_missing_stream -): - """ - Tests that attempting to sync a stream which the source does not return from the `streams` method emits incomplete stream status. - """ - logger = Mock() - - s1 = _mock_stream("s1", []) - s2 = _mock_stream("this_stream_doesnt_exist_in_the_source", []) - - concurrent_source = Mock() - concurrent_source.read.return_value = [] - - adapter = _MockSource(concurrent_source, {s1: True}, logger) - expected_status = [as_stream_status("this_stream_doesnt_exist_in_the_source", AirbyteStreamStatus.INCOMPLETE)] - - adapter.raise_exception_on_missing_stream = raise_exception_on_missing_stream - - if not raise_exception_on_missing_stream: - messages = [remove_stack_trace(message) for message in adapter.read(logger, {}, _configured_catalog([s2]))] - assert messages[0].trace.stream_status == expected_status[0].trace.stream_status - else: - with pytest.raises(AirbyteTracedException) as exc_info: - messages = [remove_stack_trace(message) for message in adapter.read(logger, {}, _configured_catalog([s2]))] - assert messages == expected_status - assert exc_info.value.failure_type == FailureType.config_error - assert "not found in the source" in exc_info.value.message diff --git a/airbyte-cdk/python/unit_tests/sources/conftest.py b/airbyte-cdk/python/unit_tests/sources/conftest.py deleted file mode 100644 index d20d763bb17b..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/conftest.py +++ /dev/null @@ -1,46 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import datetime - -import pytest -from airbyte_cdk.models import ( - AirbyteMessage, - AirbyteStreamStatus, - AirbyteStreamStatusTraceMessage, - AirbyteTraceMessage, - StreamDescriptor, - TraceType, -) -from airbyte_cdk.models import Type as MessageType - - -@pytest.fixture -def remove_stack_trace(): - def _remove_stack_trace(message: AirbyteMessage) -> AirbyteMessage: - """ - Helper method that removes the stack trace from Airbyte trace messages to make asserting against expected records easier - """ - if message.trace and message.trace.error and message.trace.error.stack_trace: - message.trace.error.stack_trace = None - return message - - return _remove_stack_trace - - -@pytest.fixture -def as_stream_status(): - def _as_stream_status(stream: str, status: AirbyteStreamStatus) -> AirbyteMessage: - trace_message = AirbyteTraceMessage( - emitted_at=datetime.datetime.now().timestamp() * 1000.0, - type=TraceType.STREAM_STATUS, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name=stream), - status=status, - ), - ) - - return AirbyteMessage(type=MessageType.TRACE, trace=trace_message) - - return _as_stream_status diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/__init__.py deleted file mode 100644 index 46b7376756ec..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/async_job/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/async_job/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/async_job/test_integration.py b/airbyte-cdk/python/unit_tests/sources/declarative/async_job/test_integration.py deleted file mode 100644 index 7fbd04b92926..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/async_job/test_integration.py +++ /dev/null @@ -1,121 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - - -import logging -from typing import Any, Iterable, List, Mapping, Optional, Set, Tuple -from unittest import TestCase, mock - -from airbyte_cdk import AbstractSource, DeclarativeStream, SinglePartitionRouter, Stream, StreamSlice -from airbyte_cdk.models import ConnectorSpecification -from airbyte_cdk.sources.declarative.async_job.job import AsyncJob -from airbyte_cdk.sources.declarative.async_job.job_orchestrator import AsyncJobOrchestrator -from airbyte_cdk.sources.declarative.async_job.job_tracker import JobTracker -from airbyte_cdk.sources.declarative.async_job.repository import AsyncJobRepository -from airbyte_cdk.sources.declarative.async_job.status import AsyncJobStatus -from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor -from airbyte_cdk.sources.declarative.extractors.record_selector import RecordSelector -from airbyte_cdk.sources.declarative.retrievers.async_retriever import AsyncRetriever -from airbyte_cdk.sources.declarative.schema import InlineSchemaLoader -from airbyte_cdk.sources.declarative.stream_slicers import StreamSlicer -from airbyte_cdk.sources.message import NoopMessageRepository -from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer -from airbyte_cdk.test.catalog_builder import CatalogBuilder, ConfiguredAirbyteStreamBuilder -from airbyte_cdk.test.entrypoint_wrapper import read - -_A_STREAM_NAME = "a_stream_name" -_EXTRACTOR_NOT_USED: RecordExtractor = None # type: ignore # the extractor should not be used. If it is the case, there is an issue that needs fixing -_NO_LIMIT = 10000 - - -class MockAsyncJobRepository(AsyncJobRepository): - - def start(self, stream_slice: StreamSlice) -> AsyncJob: - return AsyncJob("a_job_id", StreamSlice(partition={}, cursor_slice={})) - - def update_jobs_status(self, jobs: Set[AsyncJob]) -> None: - for job in jobs: - job.update_status(AsyncJobStatus.COMPLETED) - - def fetch_records(self, job: AsyncJob) -> Iterable[Mapping[str, Any]]: - yield from [{"record_field": 10}] - - def abort(self, job: AsyncJob) -> None: - pass - - def delete(self, job: AsyncJob) -> None: - pass - - -class MockSource(AbstractSource): - - def __init__(self, stream_slicer: Optional[StreamSlicer] = None) -> None: - self._stream_slicer = SinglePartitionRouter({}) if stream_slicer is None else stream_slicer - self._message_repository = NoopMessageRepository() - - def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Optional[Any]]: - return True, None - - def spec(self, logger: logging.Logger) -> ConnectorSpecification: - return ConnectorSpecification(connectionSpecification={}) - - def streams(self, config: Mapping[str, Any]) -> List[Stream]: - noop_record_selector = RecordSelector( - extractor=_EXTRACTOR_NOT_USED, - config={}, - parameters={}, - schema_normalization=TypeTransformer(TransformConfig.NoTransform), - record_filter=None, - transformations=[] - ) - return [ - DeclarativeStream( - retriever=AsyncRetriever( - config={}, - parameters={}, - record_selector=noop_record_selector, - stream_slicer=self._stream_slicer, - job_orchestrator_factory=lambda stream_slices: AsyncJobOrchestrator( - MockAsyncJobRepository(), stream_slices, JobTracker(_NO_LIMIT), self._message_repository, - ), - ), - config={}, - parameters={}, - name=_A_STREAM_NAME, - primary_key=["id"], - schema_loader=InlineSchemaLoader({}, {}), - # the interface mentions that this is Optional, - # but I get `'NoneType' object has no attribute 'eval'` by passing None - stream_cursor_field="", - ) - ] - - -class JobDeclarativeStreamTest(TestCase): - _CONFIG: Mapping[str, Any] = {} - - def setUp(self) -> None: - self._stream_slicer = mock.Mock(wraps=SinglePartitionRouter({})) - self._source = MockSource(self._stream_slicer) - self._source.streams({}) - - def test_when_read_then_return_records_from_repository(self) -> None: - output = read( - self._source, - self._CONFIG, - CatalogBuilder().with_stream(ConfiguredAirbyteStreamBuilder().with_name(_A_STREAM_NAME)).build() - ) - - assert len(output.records) == 1 - - def test_when_read_then_call_stream_slices_only_once(self) -> None: - """ - As generating stream slices is very expensive, we want to ensure that during a read, it is only called once. - """ - output = read( - self._source, - self._CONFIG, - CatalogBuilder().with_stream(ConfiguredAirbyteStreamBuilder().with_name(_A_STREAM_NAME)).build() - ) - - assert not output.errors - assert self._stream_slicer.stream_slices.call_count == 1 diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/async_job/test_job.py b/airbyte-cdk/python/unit_tests/sources/declarative/async_job/test_job.py deleted file mode 100644 index 6399433e4413..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/async_job/test_job.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -import time -from datetime import timedelta -from unittest import TestCase - -from airbyte_cdk.sources.declarative.async_job.job import AsyncJob -from airbyte_cdk.sources.declarative.async_job.status import AsyncJobStatus -from airbyte_cdk.sources.declarative.types import StreamSlice - -_AN_API_JOB_ID = "an api job id" -_ANY_STREAM_SLICE = StreamSlice(partition={}, cursor_slice={}) -_A_VERY_BIG_TIMEOUT = timedelta(days=999999999) -_IMMEDIATELY_TIMED_OUT = timedelta(microseconds=1) - - -class AsyncJobTest(TestCase): - def test_given_timer_is_not_out_when_status_then_return_actual_status(self) -> None: - job = AsyncJob(_AN_API_JOB_ID, _ANY_STREAM_SLICE, _A_VERY_BIG_TIMEOUT) - assert job.status() == AsyncJobStatus.RUNNING - - def test_given_timer_is_out_when_status_then_return_timed_out(self) -> None: - job = AsyncJob(_AN_API_JOB_ID, _ANY_STREAM_SLICE, _IMMEDIATELY_TIMED_OUT) - time.sleep(0.001) - assert job.status() == AsyncJobStatus.TIMED_OUT - - def test_given_status_is_terminal_when_update_status_then_stop_timer(self) -> None: - """ - This test will become important once we will print stats associated with jobs. As for now, we stop the timer but do not return any - metrics regarding the timer so it is not useful. - """ - pass diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/async_job/test_job_orchestrator.py b/airbyte-cdk/python/unit_tests/sources/declarative/async_job/test_job_orchestrator.py deleted file mode 100644 index 7f10bb3ac28a..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/async_job/test_job_orchestrator.py +++ /dev/null @@ -1,303 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -import logging -import sys -import threading -import time -from typing import Callable, List, Mapping, Optional, Set, Tuple -from unittest import TestCase, mock -from unittest.mock import MagicMock, Mock, call - -import pytest -from airbyte_cdk import AirbyteTracedException, StreamSlice -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.declarative.async_job.job import AsyncJob, AsyncJobStatus -from airbyte_cdk.sources.declarative.async_job.job_orchestrator import AsyncJobOrchestrator, AsyncPartition -from airbyte_cdk.sources.declarative.async_job.job_tracker import JobTracker -from airbyte_cdk.sources.declarative.async_job.repository import AsyncJobRepository -from airbyte_cdk.sources.message import MessageRepository -from airbyte_cdk.sources.streams.http.http_client import MessageRepresentationAirbyteTracedErrors - -_ANY_STREAM_SLICE = Mock() -_A_STREAM_SLICE = Mock() -_ANOTHER_STREAM_SLICE = Mock() -_ANY_RECORD = {"a record field": "a record value"} -_NO_JOB_LIMIT = sys.maxsize -_BUFFER = 10000 # this buffer allows us to be unconcerned with the number of times the update status is called - - -def _create_job(status: AsyncJobStatus = AsyncJobStatus.FAILED) -> AsyncJob: - job = Mock(spec=AsyncJob) - job.status.return_value = status - return job - - -class AsyncPartitionTest(TestCase): - def test_given_one_failed_job_when_status_then_return_failed(self) -> None: - partition = AsyncPartition([_create_job(status) for status in AsyncJobStatus], _ANY_STREAM_SLICE) - assert partition.status == AsyncJobStatus.FAILED - - def test_given_all_status_except_failed_when_status_then_return_timed_out(self) -> None: - statuses = [status for status in AsyncJobStatus if status != AsyncJobStatus.FAILED] - partition = AsyncPartition([_create_job(status) for status in statuses], _ANY_STREAM_SLICE) - assert partition.status == AsyncJobStatus.TIMED_OUT - - def test_given_running_and_completed_jobs_when_status_then_return_running(self) -> None: - partition = AsyncPartition([_create_job(AsyncJobStatus.RUNNING), _create_job(AsyncJobStatus.COMPLETED)], _ANY_STREAM_SLICE) - assert partition.status == AsyncJobStatus.RUNNING - - def test_given_only_completed_jobs_when_status_then_return_running(self) -> None: - partition = AsyncPartition([_create_job(AsyncJobStatus.COMPLETED) for _ in range(10)], _ANY_STREAM_SLICE) - assert partition.status == AsyncJobStatus.COMPLETED - - -def _status_update_per_jobs(status_update_per_jobs: Mapping[AsyncJob, List[AsyncJobStatus]]) -> Callable[[set[AsyncJob]], None]: - status_index_by_job = {job: 0 for job in status_update_per_jobs.keys()} - - def _update_status(jobs: Set[AsyncJob]) -> None: - for job in jobs: - status_index = status_index_by_job[job] - job.update_status(status_update_per_jobs[job][status_index]) - status_index_by_job[job] += 1 - - return _update_status - - -sleep_mock_target = "airbyte_cdk.sources.declarative.async_job.job_orchestrator.time.sleep" -_MAX_NUMBER_OF_ATTEMPTS = 3 - - -class AsyncJobOrchestratorTest(TestCase): - def setUp(self) -> None: - self._job_repository = Mock(spec=AsyncJobRepository) - self._message_repository = Mock(spec=MessageRepository) - self._logger = Mock(spec=logging.Logger) - - self._job_for_a_slice = self._an_async_job("an api job id", _A_STREAM_SLICE) - self._job_for_another_slice = self._an_async_job("another api job id", _ANOTHER_STREAM_SLICE) - - @mock.patch(sleep_mock_target) - def test_when_create_and_get_completed_partitions_then_create_job_and_update_status_until_completed(self, mock_sleep: MagicMock) -> None: - self._job_repository.start.return_value = self._job_for_a_slice - status_updates = [AsyncJobStatus.RUNNING, AsyncJobStatus.RUNNING, AsyncJobStatus.COMPLETED] - self._job_repository.update_jobs_status.side_effect = _status_update_per_jobs( - { - self._job_for_a_slice: status_updates - } - ) - orchestrator = self._orchestrator([_A_STREAM_SLICE]) - - partitions = list(orchestrator.create_and_get_completed_partitions()) - - assert len(partitions) == 1 - assert partitions[0].status == AsyncJobStatus.COMPLETED - assert self._job_for_a_slice.update_status.mock_calls == [call(status) for status in status_updates] - - @mock.patch(sleep_mock_target) - def test_given_one_job_still_running_when_create_and_get_completed_partitions_then_only_update_running_job_status(self, mock_sleep: MagicMock) -> None: - self._job_repository.start.side_effect = [self._job_for_a_slice, self._job_for_another_slice] - self._job_repository.update_jobs_status.side_effect = _status_update_per_jobs( - { - self._job_for_a_slice: [AsyncJobStatus.COMPLETED], - self._job_for_another_slice: [AsyncJobStatus.RUNNING, AsyncJobStatus.COMPLETED], - } - ) - orchestrator = self._orchestrator([_A_STREAM_SLICE, _ANOTHER_STREAM_SLICE]) - - list(orchestrator.create_and_get_completed_partitions()) - - assert self._job_repository.update_jobs_status.mock_calls == [ - call({self._job_for_a_slice, self._job_for_another_slice}), - call({self._job_for_another_slice}), - ] - - @mock.patch(sleep_mock_target) - def test_given_timeout_when_create_and_get_completed_partitions_then_free_budget_and_raise_exception(self, mock_sleep: MagicMock) -> None: - job_tracker = JobTracker(1) - self._job_repository.start.return_value = self._job_for_a_slice - self._job_repository.update_jobs_status.side_effect = _status_update_per_jobs( - { - self._job_for_a_slice: [AsyncJobStatus.TIMED_OUT] - } - ) - orchestrator = self._orchestrator([_A_STREAM_SLICE], job_tracker) - - with pytest.raises(AirbyteTracedException): - list(orchestrator.create_and_get_completed_partitions()) - assert job_tracker.try_to_get_intent() - assert self._job_repository.start.call_args_list == [call(_A_STREAM_SLICE)] * _MAX_NUMBER_OF_ATTEMPTS - - @mock.patch(sleep_mock_target) - def test_given_failure_when_create_and_get_completed_partitions_then_raise_exception(self, mock_sleep: MagicMock) -> None: - self._job_repository.start.return_value = self._job_for_a_slice - self._job_repository.update_jobs_status.side_effect = _status_update_per_jobs( - { - self._job_for_a_slice: [AsyncJobStatus.FAILED] - } - ) - orchestrator = self._orchestrator([_A_STREAM_SLICE]) - - with pytest.raises(AirbyteTracedException): - list(orchestrator.create_and_get_completed_partitions()) - assert self._job_repository.start.call_args_list == [call(_A_STREAM_SLICE)] * _MAX_NUMBER_OF_ATTEMPTS - - def test_when_fetch_records_then_yield_records_from_each_job(self) -> None: - self._job_repository.fetch_records.return_value = [_ANY_RECORD] - orchestrator = self._orchestrator([_A_STREAM_SLICE]) - first_job = _create_job() - second_job = _create_job() - partition = AsyncPartition([first_job, second_job], _A_STREAM_SLICE) - - records = list(orchestrator.fetch_records(partition)) - - assert len(records) == 2 - assert self._job_repository.fetch_records.mock_calls == [call(first_job), call(second_job)] - assert self._job_repository.delete.mock_calls == [call(first_job), call(second_job)] - - def _orchestrator(self, slices: List[StreamSlice], job_tracker: Optional[JobTracker] = None) -> AsyncJobOrchestrator: - job_tracker = job_tracker if job_tracker else JobTracker(_NO_JOB_LIMIT) - return AsyncJobOrchestrator(self._job_repository, slices, job_tracker, self._message_repository) - - def test_given_more_jobs_than_limit_when_create_and_get_completed_partitions_then_still_return_all_slices_and_free_job_budget(self) -> None: - job_tracker = JobTracker(1) - self._job_repository.start.side_effect = [self._job_for_a_slice, self._job_for_another_slice] - self._job_repository.update_jobs_status.side_effect = _status_update_per_jobs( - { - self._job_for_a_slice: [AsyncJobStatus.COMPLETED], - self._job_for_another_slice: [AsyncJobStatus.COMPLETED], - } - ) - orchestrator = self._orchestrator([self._job_for_a_slice.job_parameters(), self._job_for_another_slice.job_parameters()], job_tracker) - - partitions = list(orchestrator.create_and_get_completed_partitions()) - - assert len(partitions) == 2 - assert job_tracker.try_to_get_intent() - - @mock.patch(sleep_mock_target) - def test_given_exception_to_break_when_start_job_and_raise_this_exception_and_abort_jobs(self, mock_sleep: MagicMock) -> None: - orchestrator = AsyncJobOrchestrator( - self._job_repository, - [_A_STREAM_SLICE, _ANOTHER_STREAM_SLICE], - JobTracker(_NO_JOB_LIMIT), - self._message_repository, - exceptions_to_break_on=[ValueError], - ) - self._job_repository.start.side_effect = [self._job_for_a_slice, ValueError("Something went wrong")] - - with pytest.raises(ValueError): - # assert that orchestrator exits on expected error - list(orchestrator.create_and_get_completed_partitions()) - assert len(orchestrator._job_tracker._jobs) == 0 - self._job_repository.abort.assert_called_once_with(self._job_for_a_slice) - - def test_given_traced_config_error_when_start_job_and_raise_this_exception_and_abort_jobs(self) -> None: - """ - Since this is a config error, we assume the other jobs will fail for the same reasons. - """ - job_tracker = JobTracker(1) - self._job_repository.start.side_effect = MessageRepresentationAirbyteTracedErrors("Can't create job", failure_type=FailureType.config_error) - - orchestrator = AsyncJobOrchestrator(self._job_repository, [_A_STREAM_SLICE], job_tracker, self._message_repository, [ValueError]) - - with pytest.raises(AirbyteTracedException): - list(orchestrator.create_and_get_completed_partitions()) - - assert job_tracker.try_to_get_intent() - - @mock.patch(sleep_mock_target) - def test_given_exception_on_single_job_when_create_and_get_completed_partitions_then_return(self, mock_sleep: MagicMock) -> None: - """ - We added this test because the initial logic of breaking the main loop we implemented (when `self._has_started_a_job and self._running_partitions`) was not enough in the case where there was only one slice and it would fail to start. - """ - orchestrator = self._orchestrator([_A_STREAM_SLICE]) - self._job_repository.start.side_effect = ValueError - - with pytest.raises(AirbyteTracedException): - # assert that orchestrator exits on expected error - list(orchestrator.create_and_get_completed_partitions()) - - @mock.patch(sleep_mock_target) - def test_given_exception_when_start_job_and_skip_this_exception(self, mock_sleep: MagicMock) -> None: - self._job_repository.start.side_effect = [ - AirbyteTracedException("Something went wrong. Expected error #1"), - self._job_for_another_slice, - AirbyteTracedException("Something went wrong. Expected error #2"), - AirbyteTracedException("Something went wrong. Expected error #3"), - ] - self._job_repository.update_jobs_status.side_effect = _status_update_per_jobs( - { - self._job_for_a_slice: [AsyncJobStatus.COMPLETED], - self._job_for_another_slice: [AsyncJobStatus.RUNNING, AsyncJobStatus.COMPLETED], - } - ) - orchestrator = self._orchestrator([_A_STREAM_SLICE, _ANOTHER_STREAM_SLICE]) - - partitions, exception = self._accumulate_create_and_get_completed_partitions(orchestrator) - - assert len(partitions) == 1 # only _job_for_another_slice has succeeded - assert self._message_repository.emit_message.call_count == 3 # one for each traced message - assert exception.failure_type == FailureType.config_error # type: ignore # exception should be of type AirbyteTracedException - - @mock.patch(sleep_mock_target) - def test_given_jobs_failed_more_than_max_attempts_when_create_and_get_completed_partitions_then_free_job_budget(self, mock_sleep: MagicMock) -> None: - job_tracker = JobTracker(1) - jobs = [self._an_async_job(str(i), _A_STREAM_SLICE) for i in range(_MAX_NUMBER_OF_ATTEMPTS)] - self._job_repository.start.side_effect = jobs - self._job_repository.update_jobs_status.side_effect = _status_update_per_jobs({job: [AsyncJobStatus.FAILED] for job in jobs}) - - orchestrator = self._orchestrator([_A_STREAM_SLICE], job_tracker) - - with pytest.raises(AirbyteTracedException): - list(orchestrator.create_and_get_completed_partitions()) - - assert job_tracker.try_to_get_intent() - - def given_budget_already_taken_before_start_when_create_and_get_completed_partitions_then_wait_for_budget_to_be_freed(self) -> None: - job_tracker = JobTracker(1) - intent_to_free = job_tracker.try_to_get_intent() - - def wait_and_free_intent(_job_tracker: JobTracker, _intent_to_free: str) -> None: - print("Waiting before freeing budget...") - time.sleep(1) - print("Waiting done, freeing budget!") - _job_tracker.remove_job(_intent_to_free) - self._job_repository.start.return_value = self._job_for_a_slice - self._job_repository.update_jobs_status.side_effect = _status_update_per_jobs( - { - self._job_for_a_slice: [AsyncJobStatus.COMPLETED] * _BUFFER - } - ) - orchestrator = self._orchestrator([_A_STREAM_SLICE], job_tracker) - - threading.Thread(target=wait_and_free_intent, args=[job_tracker, intent_to_free]).start() - partitions = list(orchestrator.create_and_get_completed_partitions()) - - assert len(partitions) == 1 - - def test_given_start_job_raise_when_create_and_get_completed_partitions_then_free_budget(self) -> None: - job_tracker = JobTracker(1) - self._job_repository.start.side_effect = ValueError("Can't create job") - - orchestrator = AsyncJobOrchestrator(self._job_repository, [_A_STREAM_SLICE], job_tracker, self._message_repository, [ValueError]) - - with pytest.raises(Exception): - list(orchestrator.create_and_get_completed_partitions()) - - assert job_tracker.try_to_get_intent() - - def _mock_repository(self) -> None: - self._job_repository = Mock(spec=AsyncJobRepository) - - def _an_async_job(self, job_id: str, stream_slice: StreamSlice) -> AsyncJob: - return mock.Mock(wraps=AsyncJob(job_id, stream_slice)) - - def _accumulate_create_and_get_completed_partitions(self, orchestrator: AsyncJobOrchestrator) -> Tuple[List[AsyncPartition], Optional[Exception]]: - result = [] - try: - for i in orchestrator.create_and_get_completed_partitions(): - result.append(i) - except Exception as exception: - return result, exception - - return result, None diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/async_job/test_job_tracker.py b/airbyte-cdk/python/unit_tests/sources/declarative/async_job/test_job_tracker.py deleted file mode 100644 index f3c2744d1fbe..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/async_job/test_job_tracker.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from typing import List -from unittest import TestCase - -import pytest -from airbyte_cdk.sources.declarative.async_job.job_tracker import ConcurrentJobLimitReached, JobTracker - -_LIMIT = 3 - - -class JobTrackerTest(TestCase): - def setUp(self) -> None: - self._tracker = JobTracker(_LIMIT) - - def test_given_limit_reached_when_remove_job_then_can_get_intent_again(self) -> None: - intents = self._reach_limit() - with pytest.raises(ConcurrentJobLimitReached): - self._tracker.try_to_get_intent() - - self._tracker.remove_job(intents[0]) - assert self._tracker.try_to_get_intent() - - def test_given_job_does_not_exist_when_remove_job_then_do_not_raise(self) -> None: - self._tracker.remove_job("non existing job id") - - def test_given_limit_reached_when_add_job_then_limit_is_still_reached(self) -> None: - intents = [self._tracker.try_to_get_intent() for i in range(_LIMIT)] - with pytest.raises(ConcurrentJobLimitReached): - self._tracker.try_to_get_intent() - - self._tracker.add_job(intents[0], "a created job") - with pytest.raises(ConcurrentJobLimitReached): - self._tracker.try_to_get_intent() - - def _reach_limit(self) -> List[str]: - return [self._tracker.try_to_get_intent() for i in range(_LIMIT)] diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/auth/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/auth/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/auth/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_jwt.py b/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_jwt.py deleted file mode 100644 index 51bef48230c9..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_jwt.py +++ /dev/null @@ -1,166 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import base64 -import logging -from datetime import datetime - -import freezegun -import jwt -import pytest -from airbyte_cdk.sources.declarative.auth.jwt import JwtAuthenticator - -LOGGER = logging.getLogger(__name__) - - -class TestJwtAuthenticator: - """ - Test class for JWT Authenticator. - """ - - @pytest.mark.parametrize( - "algorithm, kid, typ, cty, additional_jwt_headers, expected", - [ - ( - "ALGORITHM", - "test_kid", - "test_typ", - "test_cty", - {"test": "test"}, - {"kid": "test_kid", "typ": "test_typ", "cty": "test_cty", "test": "test", "alg": "ALGORITHM"}, - ), - ("ALGORITHM", None, None, None, None, {"alg": "ALGORITHM"}), - ], - ) - def test_get_jwt_headers(self, algorithm, kid, typ, cty, additional_jwt_headers, expected): - authenticator = JwtAuthenticator( - config={}, - parameters={}, - algorithm=algorithm, - secret_key="test_key", - token_duration=1200, - kid=kid, - typ=typ, - cty=cty, - additional_jwt_headers=additional_jwt_headers, - ) - assert authenticator._get_jwt_headers() == expected - - def test_given_overriden_reserverd_properties_get_jwt_headers_throws_error(self): - authenticator = JwtAuthenticator( - config={}, - parameters={}, - algorithm="ALGORITHM", - secret_key="test_key", - token_duration=1200, - additional_jwt_headers={"kid": "test_kid"}, - ) - with pytest.raises(ValueError): - authenticator._get_jwt_headers() - - @pytest.mark.parametrize( - "iss, sub, aud, additional_jwt_payload, expected", - [ - ( - "test_iss", - "test_sub", - "test_aud", - {"test": "test"}, - {"iss": "test_iss", "sub": "test_sub", "aud": "test_aud", "test": "test"}, - ), - (None, None, None, None, {}), - ], - ) - def test_get_jwt_payload(self, iss, sub, aud, additional_jwt_payload, expected): - authenticator = JwtAuthenticator( - config={}, - parameters={}, - algorithm="ALGORITHM", - secret_key="test_key", - token_duration=1000, - iss=iss, - sub=sub, - aud=aud, - additional_jwt_payload=additional_jwt_payload, - ) - with freezegun.freeze_time("2022-01-01 00:00:00"): - expected["iat"] = int(datetime.now().timestamp()) - expected["exp"] = expected["iat"] + 1000 - expected["nbf"] = expected["iat"] - assert authenticator._get_jwt_payload() == expected - - def test_given_overriden_reserverd_properties_get_jwt_payload_throws_error(self): - authenticator = JwtAuthenticator( - config={}, - parameters={}, - algorithm="ALGORITHM", - secret_key="test_key", - token_duration=0, - additional_jwt_payload={"exp": 1234}, - ) - with pytest.raises(ValueError): - authenticator._get_jwt_payload() - - @pytest.mark.parametrize( - "base64_encode_secret_key, secret_key, expected", - [ - (True, "test", base64.b64encode("test".encode()).decode()), - (False, "test", "test"), - ], - ) - def test_get_secret_key(self, base64_encode_secret_key, secret_key, expected): - authenticator = JwtAuthenticator( - config={}, - parameters={}, - secret_key=secret_key, - algorithm="test_algo", - token_duration=1200, - base64_encode_secret_key=base64_encode_secret_key, - ) - assert authenticator._get_secret_key() == expected - - def test_get_signed_token(self): - authenticator = JwtAuthenticator( - config={}, - parameters={}, - secret_key="test", - algorithm="HS256", - token_duration=1000, - typ="JWT", - iss="iss", - ) - assert authenticator._get_signed_token() == jwt.encode( - payload=authenticator._get_jwt_payload(), - key=authenticator._get_secret_key(), - algorithm=authenticator._algorithm, - headers=authenticator._get_jwt_headers(), - ) - - def test_given_invalid_algorithm_get_signed_token_throws_error(self): - authenticator = JwtAuthenticator( - config={}, - parameters={}, - secret_key="test", - algorithm="invalid algorithm type", - token_duration=1000, - base64_encode_secret_key=False, - header_prefix="Bearer", - typ="JWT", - iss="iss", - additional_jwt_headers={}, - additional_jwt_payload={}, - ) - with pytest.raises(ValueError): - authenticator._get_signed_token() - - @pytest.mark.parametrize("header_prefix, expected", [("test", "test"), (None, None)]) - def test_get_header_prefix(self, header_prefix, expected): - authenticator = JwtAuthenticator( - config={}, - parameters={}, - secret_key="key", - algorithm="test_algo", - token_duration=1200, - header_prefix=header_prefix, - ) - assert authenticator._get_header_prefix() == expected diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_oauth.py b/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_oauth.py deleted file mode 100644 index 78dd0b591ec3..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_oauth.py +++ /dev/null @@ -1,331 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import base64 -import logging -from unittest.mock import Mock - -import freezegun -import pendulum -import pytest -import requests -from airbyte_cdk.sources.declarative.auth import DeclarativeOauth2Authenticator -from airbyte_cdk.utils.airbyte_secrets_utils import filter_secrets -from requests import Response - -LOGGER = logging.getLogger(__name__) - -resp = Response() - -config = { - "refresh_endpoint": "refresh_end", - "client_id": "some_client_id", - "client_secret": "some_client_secret", - "token_expiry_date": pendulum.now().subtract(days=2).to_rfc3339_string(), - "custom_field": "in_outbound_request", - "another_field": "exists_in_body", - "grant_type": "some_grant_type", -} -parameters = {"refresh_token": "some_refresh_token"} - - -class TestOauth2Authenticator: - """ - Test class for OAuth2Authenticator. - """ - - def test_refresh_request_body(self): - """ - Request body should match given configuration. - """ - scopes = ["scope1", "scope2"] - oauth = DeclarativeOauth2Authenticator( - token_refresh_endpoint="{{ config['refresh_endpoint'] }}", - client_id="{{ config['client_id'] }}", - client_secret="{{ config['client_secret'] }}", - refresh_token="{{ parameters['refresh_token'] }}", - config=config, - scopes=["scope1", "scope2"], - token_expiry_date="{{ config['token_expiry_date'] }}", - refresh_request_body={ - "custom_field": "{{ config['custom_field'] }}", - "another_field": "{{ config['another_field'] }}", - "scopes": ["no_override"], - }, - parameters=parameters, - grant_type="{{ config['grant_type'] }}", - ) - body = oauth.build_refresh_request_body() - expected = { - "grant_type": "some_grant_type", - "client_id": "some_client_id", - "client_secret": "some_client_secret", - "refresh_token": "some_refresh_token", - "scopes": scopes, - "custom_field": "in_outbound_request", - "another_field": "exists_in_body", - } - assert body == expected - - def test_refresh_with_encode_config_params(self): - oauth = DeclarativeOauth2Authenticator( - token_refresh_endpoint="{{ config['refresh_endpoint'] }}", - client_id="{{ config['client_id'] | base64encode }}", - client_secret="{{ config['client_secret'] | base64encode }}", - config=config, - parameters={}, - grant_type="client_credentials", - ) - body = oauth.build_refresh_request_body() - expected = { - "grant_type": "client_credentials", - "client_id": base64.b64encode(config["client_id"].encode("utf-8")).decode(), - "client_secret": base64.b64encode(config["client_secret"].encode("utf-8")).decode(), - "refresh_token": None, - } - assert body == expected - - def test_refresh_with_decode_config_params(self): - updated_config_fields = { - "client_id": base64.b64encode(config["client_id"].encode("utf-8")).decode(), - "client_secret": base64.b64encode(config["client_secret"].encode("utf-8")).decode(), - } - oauth = DeclarativeOauth2Authenticator( - token_refresh_endpoint="{{ config['refresh_endpoint'] }}", - client_id="{{ config['client_id'] | base64decode }}", - client_secret="{{ config['client_secret'] | base64decode }}", - config=config | updated_config_fields, - parameters={}, - grant_type="client_credentials", - ) - body = oauth.build_refresh_request_body() - expected = { - "grant_type": "client_credentials", - "client_id": "some_client_id", - "client_secret": "some_client_secret", - "refresh_token": None, - } - assert body == expected - - def test_refresh_without_refresh_token(self): - """ - Should work fine for grant_type client_credentials. - """ - oauth = DeclarativeOauth2Authenticator( - token_refresh_endpoint="{{ config['refresh_endpoint'] }}", - client_id="{{ config['client_id'] }}", - client_secret="{{ config['client_secret'] }}", - config=config, - parameters={}, - grant_type="client_credentials", - ) - body = oauth.build_refresh_request_body() - expected = { - "grant_type": "client_credentials", - "client_id": "some_client_id", - "client_secret": "some_client_secret", - "refresh_token": None, - } - assert body == expected - - def test_error_on_refresh_token_grant_without_refresh_token(self): - """ - Should throw an error if grant_type refresh_token is configured without refresh_token. - """ - with pytest.raises(ValueError): - DeclarativeOauth2Authenticator( - token_refresh_endpoint="{{ config['refresh_endpoint'] }}", - client_id="{{ config['client_id'] }}", - client_secret="{{ config['client_secret'] }}", - config=config, - parameters={}, - grant_type="refresh_token", - ) - - def test_refresh_access_token(self, mocker): - oauth = DeclarativeOauth2Authenticator( - token_refresh_endpoint="{{ config['refresh_endpoint'] }}", - client_id="{{ config['client_id'] }}", - client_secret="{{ config['client_secret'] }}", - refresh_token="{{ config['refresh_token'] }}", - config=config, - scopes=["scope1", "scope2"], - token_expiry_date="{{ config['token_expiry_date'] }}", - refresh_request_body={ - "custom_field": "{{ config['custom_field'] }}", - "another_field": "{{ config['another_field'] }}", - "scopes": ["no_override"], - }, - parameters={}, - ) - - resp.status_code = 200 - mocker.patch.object(resp, "json", return_value={"access_token": "access_token", "expires_in": 1000}) - mocker.patch.object(requests, "request", side_effect=mock_request, autospec=True) - token = oauth.refresh_access_token() - - assert ("access_token", 1000) == token - - filtered = filter_secrets("access_token") - assert filtered == "****" - - def test_refresh_access_token_missing_access_token(self, mocker): - oauth = DeclarativeOauth2Authenticator( - token_refresh_endpoint="{{ config['refresh_endpoint'] }}", - client_id="{{ config['client_id'] }}", - client_secret="{{ config['client_secret'] }}", - refresh_token="{{ config['refresh_token'] }}", - config=config, - scopes=["scope1", "scope2"], - token_expiry_date="{{ config['token_expiry_date'] }}", - refresh_request_body={ - "custom_field": "{{ config['custom_field'] }}", - "another_field": "{{ config['another_field'] }}", - "scopes": ["no_override"], - }, - parameters={}, - ) - - resp.status_code = 200 - mocker.patch.object(resp, "json", return_value={"expires_in": 1000}) - mocker.patch.object(requests, "request", side_effect=mock_request, autospec=True) - with pytest.raises(Exception): - oauth.refresh_access_token() - - @pytest.mark.parametrize( - "timestamp, expected_date", - [ - (1640995200, "2022-01-01T00:00:00Z"), - ("1650758400", "2022-04-24T00:00:00Z"), - ], - ids=["timestamp_as_integer", "timestamp_as_integer_inside_string"], - ) - def test_initialize_declarative_oauth_with_token_expiry_date_as_timestamp(self, timestamp, expected_date): - # TODO: should be fixed inside DeclarativeOauth2Authenticator, remove next line after fixing - with pytest.raises(TypeError): - oauth = DeclarativeOauth2Authenticator( - token_refresh_endpoint="{{ config['refresh_endpoint'] }}", - client_id="{{ config['client_id'] }}", - client_secret="{{ config['client_secret'] }}", - refresh_token="{{ parameters['refresh_token'] }}", - config=config | {"token_expiry_date": timestamp}, - scopes=["scope1", "scope2"], - token_expiry_date="{{ config['token_expiry_date'] }}", - refresh_request_body={ - "custom_field": "{{ config['custom_field'] }}", - "another_field": "{{ config['another_field'] }}", - "scopes": ["no_override"], - }, - parameters={}, - ) - - assert oauth.get_token_expiry_date() == pendulum.parse(expected_date) - - @pytest.mark.parametrize( - "expires_in_response, token_expiry_date_format", - [ - ("2020-01-02T00:00:00Z", "YYYY-MM-DDTHH:mm:ss[Z]"), - ("2020-01-02T00:00:00.000000+00:00", "YYYY-MM-DDTHH:mm:ss.SSSSSSZ"), - ("2020-01-02", "YYYY-MM-DD"), - ], - ids=["rfc3339", "iso8601", "simple_date"], - ) - @freezegun.freeze_time("2020-01-01") - def test_refresh_access_token_expire_format(self, mocker, expires_in_response, token_expiry_date_format): - next_day = "2020-01-02T00:00:00Z" - config.update({"token_expiry_date": pendulum.parse(next_day).subtract(days=2).to_rfc3339_string()}) - message_repository = Mock() - oauth = DeclarativeOauth2Authenticator( - token_refresh_endpoint="{{ config['refresh_endpoint'] }}", - client_id="{{ config['client_id'] }}", - client_secret="{{ config['client_secret'] }}", - refresh_token="{{ config['refresh_token'] }}", - config=config, - scopes=["scope1", "scope2"], - token_expiry_date="{{ config['token_expiry_date'] }}", - token_expiry_date_format=token_expiry_date_format, - token_expiry_is_time_of_expiration=True, - refresh_request_body={ - "custom_field": "{{ config['custom_field'] }}", - "another_field": "{{ config['another_field'] }}", - "scopes": ["no_override"], - }, - message_repository=message_repository, - parameters={}, - ) - - resp.status_code = 200 - mocker.patch.object(resp, "json", return_value={"access_token": "access_token", "expires_in": expires_in_response}) - mocker.patch.object(requests, "request", side_effect=mock_request, autospec=True) - token = oauth.get_access_token() - assert "access_token" == token - assert oauth.get_token_expiry_date() == pendulum.parse(next_day) - assert message_repository.log_message.call_count == 1 - - @pytest.mark.parametrize( - "expires_in_response, next_day, raises", - [ - (86400, "2020-01-02T00:00:00Z", False), - (86400.1, "2020-01-02T00:00:00Z", False), - ("86400", "2020-01-02T00:00:00Z", False), - ("86400.1", "2020-01-02T00:00:00Z", False), - ("2020-01-02T00:00:00Z", "2020-01-02T00:00:00Z", True), - ], - ids=["time_in_seconds", "time_in_seconds_float", "time_in_seconds_str", "time_in_seconds_str_float", "invalid"], - ) - @freezegun.freeze_time("2020-01-01") - def test_set_token_expiry_date_no_format(self, mocker, expires_in_response, next_day, raises): - config.update({"token_expiry_date": pendulum.parse(next_day).subtract(days=2).to_rfc3339_string()}) - oauth = DeclarativeOauth2Authenticator( - token_refresh_endpoint="{{ config['refresh_endpoint'] }}", - client_id="{{ config['client_id'] }}", - client_secret="{{ config['client_secret'] }}", - refresh_token="{{ config['refresh_token'] }}", - config=config, - scopes=["scope1", "scope2"], - refresh_request_body={ - "custom_field": "{{ config['custom_field'] }}", - "another_field": "{{ config['another_field'] }}", - "scopes": ["no_override"], - }, - parameters={}, - ) - - resp.status_code = 200 - mocker.patch.object(resp, "json", return_value={"access_token": "access_token", "expires_in": expires_in_response}) - mocker.patch.object(requests, "request", side_effect=mock_request, autospec=True) - if raises: - with pytest.raises(ValueError): - oauth.get_access_token() - else: - token = oauth.get_access_token() - assert "access_token" == token - assert oauth.get_token_expiry_date() == pendulum.parse(next_day) - - def test_error_handling(self, mocker): - oauth = DeclarativeOauth2Authenticator( - token_refresh_endpoint="{{ config['refresh_endpoint'] }}", - client_id="{{ config['client_id'] }}", - client_secret="{{ config['client_secret'] }}", - refresh_token="{{ config['refresh_token'] }}", - config=config, - scopes=["scope1", "scope2"], - refresh_request_body={ - "custom_field": "{{ config['custom_field'] }}", - "another_field": "{{ config['another_field'] }}", - "scopes": ["no_override"], - }, - parameters={}, - ) - resp.status_code = 400 - mocker.patch.object(resp, "json", return_value={"access_token": "access_token", "expires_in": 123}) - mocker.patch.object(requests, "request", side_effect=mock_request, autospec=True) - with pytest.raises(requests.exceptions.HTTPError) as e: - oauth.refresh_access_token() - assert e.value.errno == 400 - - -def mock_request(method, url, data): - if url == "refresh_end": - return resp - raise Exception(f"Error while refreshing access token with request: {method}, {url}, {data}") diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_selective_authenticator.py b/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_selective_authenticator.py deleted file mode 100644 index 346b284c3786..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_selective_authenticator.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -from airbyte_cdk.sources.declarative.auth.selective_authenticator import SelectiveAuthenticator - - -def test_authenticator_selected(mocker): - authenticators = {"one": mocker.Mock(), "two": mocker.Mock()} - auth = SelectiveAuthenticator( - config={"auth": {"type": "one"}}, - authenticators=authenticators, - authenticator_selection_path=["auth", "type"], - ) - - assert auth is authenticators["one"] - - -def test_selection_path_not_found(mocker): - authenticators = {"one": mocker.Mock(), "two": mocker.Mock()} - - with pytest.raises(ValueError, match="The path from `authenticator_selection_path` is not found in the config"): - _ = SelectiveAuthenticator( - config={"auth": {"type": "one"}}, - authenticators=authenticators, - authenticator_selection_path=["auth_type"], - ) - - -def test_selected_auth_not_found(mocker): - authenticators = {"one": mocker.Mock(), "two": mocker.Mock()} - - with pytest.raises(ValueError, match="The authenticator `unknown` is not found"): - _ = SelectiveAuthenticator( - config={"auth": {"type": "unknown"}}, - authenticators=authenticators, - authenticator_selection_path=["auth", "type"], - ) diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_session_token_auth.py b/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_session_token_auth.py deleted file mode 100644 index 5f99fabf00b3..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_session_token_auth.py +++ /dev/null @@ -1,182 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -from airbyte_cdk.sources.declarative.auth.token import LegacySessionTokenAuthenticator, get_new_session_token -from requests.exceptions import HTTPError - -parameters = {"hello": "world"} -instance_api_url = "https://airbyte.metabaseapp.com/api/" -username = "username" -password = "password" -session_token = "session_token" -header = "X-App-Session" -session_token_response_key = "id" -login_url = "session" -validate_session_url = "user/current" - -input_instance_api_url = "{{ config['instance_api_url'] }}" -input_username = "{{ config['username'] }}" -input_password = "{{ config['password'] }}" -input_session_token = "{{ config['session_token'] }}" - -config = { - "instance_api_url": instance_api_url, - "username": username, - "password": password, - "session_token": session_token, - "header": header, - "session_token_response_key": session_token_response_key, - "login_url": login_url, - "validate_session_url": validate_session_url, -} - -config_session_token = { - "instance_api_url": instance_api_url, - "username": "", - "password": "", - "session_token": session_token, - "header": header, - "session_token_response_key": session_token_response_key, - "login_url": login_url, - "validate_session_url": validate_session_url, -} - -config_username_password = { - "instance_api_url": instance_api_url, - "username": username, - "password": password, - "session_token": "", - "header": header, - "session_token_response_key": session_token_response_key, - "login_url": login_url, - "validate_session_url": validate_session_url, -} - - -def test_auth_header(): - auth_header = LegacySessionTokenAuthenticator( - config=config, - parameters=parameters, - api_url=input_instance_api_url, - username=input_username, - password=input_password, - session_token=input_session_token, - header=header, - session_token_response_key=session_token_response_key, - login_url=login_url, - validate_session_url=validate_session_url, - ).auth_header - assert auth_header == "X-App-Session" - - -def test_get_token_valid_session(requests_mock): - requests_mock.get( - f"{config_session_token['instance_api_url']}user/current", json={"common_name": "common_name", "last_login": "last_login"} - ) - - token = LegacySessionTokenAuthenticator( - config=config_session_token, - parameters=parameters, - api_url=input_instance_api_url, - username=input_username, - password=input_password, - session_token=input_session_token, - header=header, - session_token_response_key=session_token_response_key, - login_url=login_url, - validate_session_url=validate_session_url, - ).token - assert token == "session_token" - - -def test_get_token_invalid_session_unauthorized(): - with pytest.raises(ConnectionError): - _ = LegacySessionTokenAuthenticator( - config=config_session_token, - parameters=parameters, - api_url=input_instance_api_url, - username=input_username, - password=input_password, - session_token=input_session_token, - header=header, - session_token_response_key=session_token_response_key, - login_url=login_url, - validate_session_url=validate_session_url, - ).token - - -def test_get_token_invalid_username_password_unauthorized(): - with pytest.raises(HTTPError): - _ = LegacySessionTokenAuthenticator( - config=config_username_password, - parameters=parameters, - api_url=input_instance_api_url, - username=input_username, - password=input_password, - session_token=input_session_token, - header=header, - session_token_response_key=session_token_response_key, - validate_session_url=validate_session_url, - login_url=login_url, - ).token - - -def test_get_token_username_password(requests_mock): - requests_mock.post(f"{config['instance_api_url']}session", json={"id": "some session id"}) - - token = LegacySessionTokenAuthenticator( - config=config_username_password, - parameters=parameters, - api_url=input_instance_api_url, - username=input_username, - password=input_password, - session_token=input_session_token, - header=header, - session_token_response_key=session_token_response_key, - login_url=login_url, - validate_session_url=validate_session_url, - ).token - assert token == "some session id" - - -def test_check_is_valid_session_token(requests_mock): - requests_mock.get(f"{config['instance_api_url']}user/current", json={"common_name": "common_name", "last_login": "last_login"}) - - assert LegacySessionTokenAuthenticator( - config=config, - parameters=parameters, - api_url=input_instance_api_url, - username=input_username, - password=input_password, - session_token=input_session_token, - header=header, - session_token_response_key=session_token_response_key, - validate_session_url=validate_session_url, - login_url=login_url, - ).is_valid_session_token() - - -def test_check_is_valid_session_token_unauthorized(): - assert not LegacySessionTokenAuthenticator( - config=config, - parameters=parameters, - api_url=input_instance_api_url, - username=input_username, - password=input_password, - session_token=input_session_token, - header=header, - session_token_response_key=session_token_response_key, - login_url=login_url, - validate_session_url=validate_session_url, - ).is_valid_session_token() - - -def test_get_new_session_token(requests_mock): - requests_mock.post(f"{config['instance_api_url']}session", headers={"Content-Type": "application/json"}, json={"id": "some session id"}) - - session_token = get_new_session_token( - f'{config["instance_api_url"]}session', config["username"], config["password"], config["session_token_response_key"] - ) - assert session_token == "some session id" diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_token_auth.py b/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_token_auth.py deleted file mode 100644 index 599667c42f9b..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_token_auth.py +++ /dev/null @@ -1,200 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging - -import pytest -import requests -from airbyte_cdk.sources.declarative.auth.token import ApiKeyAuthenticator, BasicHttpAuthenticator, BearerAuthenticator -from airbyte_cdk.sources.declarative.auth.token_provider import InterpolatedStringTokenProvider -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType -from requests import Response - -LOGGER = logging.getLogger(__name__) - -resp = Response() -config = {"username": "user", "password": "password", "header": "header"} -parameters = {"username": "user", "password": "password", "header": "header"} - - -@pytest.mark.parametrize( - "test_name, token, expected_header_value", - [ - ("test_static_token", "test-token", "Bearer test-token"), - ("test_token_from_config", "{{ config.username }}", "Bearer user"), - ("test_token_from_parameters", "{{ parameters.username }}", "Bearer user"), - ], -) -def test_bearer_token_authenticator(test_name, token, expected_header_value): - """ - Should match passed in token, no matter how many times token is retrieved. - """ - token_provider = InterpolatedStringTokenProvider(config=config, api_token=token, parameters=parameters) - token_auth = BearerAuthenticator(token_provider, config, parameters=parameters) - header1 = token_auth.get_auth_header() - header2 = token_auth.get_auth_header() - - prepared_request = requests.PreparedRequest() - prepared_request.headers = {} - token_auth(prepared_request) - - assert {"Authorization": expected_header_value} == prepared_request.headers - assert {"Authorization": expected_header_value} == header1 - assert {"Authorization": expected_header_value} == header2 - - -@pytest.mark.parametrize( - "test_name, username, password, expected_header_value", - [ - ("test_static_creds", "user", "password", "Basic dXNlcjpwYXNzd29yZA=="), - ("test_creds_from_config", "{{ config.username }}", "{{ config.password }}", "Basic dXNlcjpwYXNzd29yZA=="), - ("test_creds_from_parameters", "{{ parameters.username }}", "{{ parameters.password }}", "Basic dXNlcjpwYXNzd29yZA=="), - ], -) -def test_basic_authenticator(test_name, username, password, expected_header_value): - """ - Should match passed in token, no matter how many times token is retrieved. - """ - token_auth = BasicHttpAuthenticator(username=username, password=password, config=config, parameters=parameters) - header1 = token_auth.get_auth_header() - header2 = token_auth.get_auth_header() - - prepared_request = requests.PreparedRequest() - prepared_request.headers = {} - token_auth(prepared_request) - - assert {"Authorization": expected_header_value} == prepared_request.headers - assert {"Authorization": expected_header_value} == header1 - assert {"Authorization": expected_header_value} == header2 - - -@pytest.mark.parametrize( - "test_name, header, token, expected_header, expected_header_value", - [ - ("test_static_token", "Authorization", "test-token", "Authorization", "test-token"), - ("test_token_from_config", "{{ config.header }}", "{{ config.username }}", "header", "user"), - ("test_token_from_parameters", "{{ parameters.header }}", "{{ parameters.username }}", "header", "user"), - ], -) -def test_api_key_authenticator(test_name, header, token, expected_header, expected_header_value): - """ - Should match passed in token, no matter how many times token is retrieved. - """ - token_provider = InterpolatedStringTokenProvider(config=config, api_token=token, parameters=parameters) - token_auth = ApiKeyAuthenticator( - request_option=RequestOption(inject_into=RequestOptionType.header, field_name=header, parameters=parameters), - token_provider=token_provider, - config=config, - parameters=parameters, - ) - header1 = token_auth.get_auth_header() - header2 = token_auth.get_auth_header() - - prepared_request = requests.PreparedRequest() - prepared_request.headers = {} - token_auth(prepared_request) - - assert {expected_header: expected_header_value} == prepared_request.headers - assert {expected_header: expected_header_value} == header1 - assert {expected_header: expected_header_value} == header2 - - -@pytest.mark.parametrize( - "test_name, field_name, token, expected_field_name, expected_field_value, inject_type, validation_fn", - [ - ( - "test_static_token", - "Authorization", - "test-token", - "Authorization", - "test-token", - RequestOptionType.request_parameter, - "get_request_params", - ), - ( - "test_token_from_config", - "{{ config.header }}", - "{{ config.username }}", - "header", - "user", - RequestOptionType.request_parameter, - "get_request_params", - ), - ( - "test_token_from_parameters", - "{{ parameters.header }}", - "{{ parameters.username }}", - "header", - "user", - RequestOptionType.request_parameter, - "get_request_params", - ), - ( - "test_static_token", - "Authorization", - "test-token", - "Authorization", - "test-token", - RequestOptionType.body_data, - "get_request_body_data", - ), - ( - "test_token_from_config", - "{{ config.header }}", - "{{ config.username }}", - "header", - "user", - RequestOptionType.body_data, - "get_request_body_data", - ), - ( - "test_token_from_parameters", - "{{ parameters.header }}", - "{{ parameters.username }}", - "header", - "user", - RequestOptionType.body_data, - "get_request_body_data", - ), - ( - "test_static_token", - "Authorization", - "test-token", - "Authorization", - "test-token", - RequestOptionType.body_json, - "get_request_body_json", - ), - ( - "test_token_from_config", - "{{ config.header }}", - "{{ config.username }}", - "header", - "user", - RequestOptionType.body_json, - "get_request_body_json", - ), - ( - "test_token_from_parameters", - "{{ parameters.header }}", - "{{ parameters.username }}", - "header", - "user", - RequestOptionType.body_json, - "get_request_body_json", - ), - ], -) -def test_api_key_authenticator_inject(test_name, field_name, token, expected_field_name, expected_field_value, inject_type, validation_fn): - """ - Should match passed in token, no matter how many times token is retrieved. - """ - token_provider = InterpolatedStringTokenProvider(config=config, api_token=token, parameters=parameters) - token_auth = ApiKeyAuthenticator( - request_option=RequestOption(inject_into=inject_type, field_name=field_name, parameters=parameters), - token_provider=token_provider, - config=config, - parameters=parameters, - ) - assert {expected_field_name: expected_field_value} == getattr(token_auth, validation_fn)() diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_token_provider.py b/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_token_provider.py deleted file mode 100644 index e73e5eef0838..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_token_provider.py +++ /dev/null @@ -1,73 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from unittest.mock import MagicMock - -import pendulum -import pytest -from airbyte_cdk.sources.declarative.auth.token_provider import InterpolatedStringTokenProvider, SessionTokenProvider -from airbyte_cdk.sources.declarative.exceptions import ReadException -from isodate import parse_duration - - -def create_session_token_provider(): - login_requester = MagicMock() - login_response = MagicMock() - login_response.json.return_value = {"nested": {"token": "my_token"}} - login_requester.send_request.return_value = login_response - - return SessionTokenProvider( - login_requester=login_requester, - session_token_path=["nested", "token"], - expiration_duration=parse_duration("PT1H"), - parameters={"test": "test"}, - ) - - -def test_interpolated_string_token_provider(): - provider = InterpolatedStringTokenProvider( - config={"config_key": "val"}, api_token="{{ config.config_key }}-{{ parameters.test }}", parameters={"test": "test"} - ) - assert provider.get_token() == "val-test" - - -def test_session_token_provider(): - provider = create_session_token_provider() - assert provider.get_token() == "my_token" - - -def test_session_token_provider_cache(): - provider = create_session_token_provider() - provider.get_token() - assert provider.get_token() == "my_token" - assert provider.login_requester.send_request.call_count == 1 - - -def test_session_token_provider_cache_expiration(): - with pendulum.test(pendulum.datetime(2001, 5, 21, 12)): - provider = create_session_token_provider() - provider.get_token() - - provider.login_requester.send_request.return_value.json.return_value = {"nested": {"token": "updated_token"}} - - with pendulum.test(pendulum.datetime(2001, 5, 21, 14)): - assert provider.get_token() == "updated_token" - - assert provider.login_requester.send_request.call_count == 2 - - -def test_session_token_provider_no_cache(): - provider = create_session_token_provider() - provider.expiration_duration = None - provider.get_token() - assert provider.login_requester.send_request.call_count == 1 - provider.get_token() - assert provider.login_requester.send_request.call_count == 2 - - -def test_session_token_provider_ignored_response(): - provider = create_session_token_provider() - provider.login_requester.send_request.return_value = None - with pytest.raises(ReadException): - provider.get_token() diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/checks/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/checks/__init__.py deleted file mode 100644 index 46b7376756ec..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/checks/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/checks/test_check_stream.py b/airbyte-cdk/python/unit_tests/sources/declarative/checks/test_check_stream.py deleted file mode 100644 index 4ebe449dcd69..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/checks/test_check_stream.py +++ /dev/null @@ -1,139 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from typing import Any, Iterable, Mapping, Optional -from unittest.mock import MagicMock - -import pytest -import requests -from airbyte_cdk.sources.declarative.checks.check_stream import CheckStream -from airbyte_cdk.sources.streams.http import HttpStream - -logger = logging.getLogger("test") -config = dict() - -stream_names = ["s1"] -record = MagicMock() - - -@pytest.mark.parametrize( - "test_name, record, streams_to_check, stream_slice, expectation", - [ - ("test_success_check", record, stream_names, {}, (True, None)), - ("test_success_check_stream_slice", record, stream_names, {"slice": "slice_value"}, (True, None)), - ("test_fail_check", None, stream_names, {}, (True, None)), - ("test_try_to_check_invalid stream", record, ["invalid_stream_name"], {}, None), - ], -) -@pytest.mark.parametrize("slices_as_list", [True, False]) -def test_check_stream_with_slices_as_list(test_name, record, streams_to_check, stream_slice, expectation, slices_as_list): - stream = MagicMock() - stream.name = "s1" - stream.availability_strategy = None - if slices_as_list: - stream.stream_slices.return_value = [stream_slice] - else: - stream.stream_slices.return_value = iter([stream_slice]) - - stream.read_records.side_effect = mock_read_records({frozenset(stream_slice): iter([record])}) - - source = MagicMock() - source.streams.return_value = [stream] - - check_stream = CheckStream(streams_to_check, parameters={}) - - if expectation: - actual = check_stream.check_connection(source, logger, config) - assert actual == expectation - else: - with pytest.raises(ValueError): - check_stream.check_connection(source, logger, config) - - -def mock_read_records(responses, default_response=None, **kwargs): - return lambda stream_slice, sync_mode: responses[frozenset(stream_slice)] if frozenset(stream_slice) in responses else default_response - - -def test_check_empty_stream(): - stream = MagicMock() - stream.name = "s1" - stream.read_records.return_value = iter([]) - stream.stream_slices.return_value = iter([None]) - - source = MagicMock() - source.streams.return_value = [stream] - - check_stream = CheckStream(["s1"], parameters={}) - stream_is_available, reason = check_stream.check_connection(source, logger, config) - assert stream_is_available - - -def test_check_stream_with_no_stream_slices_aborts(): - stream = MagicMock() - stream.name = "s1" - stream.stream_slices.return_value = iter([]) - - source = MagicMock() - source.streams.return_value = [stream] - - check_stream = CheckStream(["s1"], parameters={}) - stream_is_available, reason = check_stream.check_connection(source, logger, config) - assert not stream_is_available - assert "no stream slices were found, likely because the parent stream is empty" in reason - - -@pytest.mark.parametrize( - "test_name, response_code, available_expectation, expected_messages", - [ - ("test_stream_unavailable_unhandled_error", 404, False, ["Not found. The requested resource was not found on the server."]), - ( - "test_stream_unavailable_handled_error", - 403, - False, - ["Forbidden. You don't have permission to access this resource."], - ), - ("test_stream_available", 200, True, []), - ], -) -def test_check_http_stream_via_availability_strategy(mocker, test_name, response_code, available_expectation, expected_messages): - class MockHttpStream(HttpStream): - url_base = "https://test_base_url.com" - primary_key = "" - - def __init__(self, **kwargs): - super().__init__(**kwargs) - self.resp_counter = 1 - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - return None - - def path(self, **kwargs) -> str: - return "" - - def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapping]: - stub_resp = {"data": self.resp_counter} - self.resp_counter += 1 - yield stub_resp - - pass - - http_stream = MockHttpStream() - assert isinstance(http_stream, HttpStream) - - source = MagicMock() - source.streams.return_value = [http_stream] - - check_stream = CheckStream(stream_names=["mock_http_stream"], parameters={}) - - req = requests.Response() - req.status_code = response_code - mocker.patch.object(requests.Session, "send", return_value=req) - - logger = logging.getLogger(f"airbyte.{getattr(source, 'name', '')}") - stream_is_available, reason = check_stream.check_connection(source, logger, config) - - assert stream_is_available == available_expectation - for message in expected_messages: - assert message in reason diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/concurrency_level/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/concurrency_level/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/concurrency_level/test_concurrency_level.py b/airbyte-cdk/python/unit_tests/sources/declarative/concurrency_level/test_concurrency_level.py deleted file mode 100644 index 0195a71c1968..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/concurrency_level/test_concurrency_level.py +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from typing import Any, Mapping, Optional, Type, Union - -import pytest -from airbyte_cdk.sources.declarative.concurrency_level import ConcurrencyLevel - - -@pytest.mark.parametrize( - "default_concurrency, max_concurrency, expected_concurrency", - [ - pytest.param(20, 75, 20, id="test_default_concurrency_as_int"), - pytest.param(20, 75, 20, id="test_default_concurrency_as_int_ignores_max_concurrency"), - pytest.param("{{ config['num_workers'] or 40 }}", 75, 50, id="test_default_concurrency_using_interpolation"), - pytest.param("{{ config['missing'] or 40 }}", 75, 40, id="test_default_concurrency_using_interpolation_no_value"), - pytest.param("{{ config['num_workers'] or 40 }}", 10, 10, id="test_use_max_concurrency_if_default_is_too_high"), - ], -) -def test_stream_slices(default_concurrency: Union[int, str], max_concurrency: int, expected_concurrency: int) -> None: - config = {"num_workers": 50} - concurrency_level = ConcurrencyLevel( - default_concurrency=default_concurrency, - max_concurrency=max_concurrency, - config=config, - parameters={} - ) - - actual_concurrency = concurrency_level.get_concurrency_level() - - assert actual_concurrency == expected_concurrency - - -@pytest.mark.parametrize( - "config, expected_concurrency, expected_error", - [ - pytest.param({"num_workers": "fifty five"}, None, ValueError, id="test_invalid_default_concurrency_as_string"), - pytest.param({"num_workers": "55"}, 55, None, id="test_default_concurrency_as_string_int"), - pytest.param({"num_workers": 60}, 60, None, id="test_default_concurrency_as_int"), - ], -) -def test_default_concurrency_input_types_and_errors( - config: Mapping[str, Any], - expected_concurrency: Optional[int], - expected_error: Optional[Type[Exception]], -) -> None: - concurrency_level = ConcurrencyLevel( - default_concurrency="{{ config['num_workers'] or 30 }}", - max_concurrency=65, - config=config, - parameters={} - ) - - if expected_error: - with pytest.raises(expected_error): - concurrency_level.get_concurrency_level() - else: - actual_concurrency = concurrency_level.get_concurrency_level() - - assert actual_concurrency == expected_concurrency - - -def test_max_concurrency_is_required_for_default_concurrency_using_config() -> None: - config = {"num_workers": "50"} - - with pytest.raises(ValueError): - ConcurrencyLevel( - default_concurrency="{{ config['num_workers'] or 40 }}", - max_concurrency=None, - config=config, - parameters={} - ) diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/datetime/test_datetime_parser.py b/airbyte-cdk/python/unit_tests/sources/declarative/datetime/test_datetime_parser.py deleted file mode 100644 index 1a7d45f7a78f..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/datetime/test_datetime_parser.py +++ /dev/null @@ -1,71 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import datetime - -import pytest -from airbyte_cdk.sources.declarative.datetime.datetime_parser import DatetimeParser - - -@pytest.mark.parametrize( - "test_name, input_date, date_format, expected_output_date", - [ - ( - "test_parse_date_iso", - "2021-01-01T00:00:00.000000+0000", - "%Y-%m-%dT%H:%M:%S.%f%z", - datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - ), - ( - "test_parse_date_iso_with_timezone_not_utc", - "2021-01-01T00:00:00.000000+0400", - "%Y-%m-%dT%H:%M:%S.%f%z", - datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=14400))), - ), - ( - "test_parse_timestamp", - "1609459200", - "%s", - datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - ), - ( - "test_parse_timestamp_as_float", - "1675092508.873709", - "%s_as_float", - datetime.datetime(2023, 1, 30, 15, 28, 28, 873709, tzinfo=datetime.timezone.utc), - ), - ( - "test_parse_ms_timestamp", - "1609459200001", - "%ms", - datetime.datetime(2021, 1, 1, 0, 0, 0, 1000, tzinfo=datetime.timezone.utc), - ), - ("test_parse_date_ms", "20210101", "%Y%m%d", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)), - ], -) -def test_parse_date(test_name, input_date, date_format, expected_output_date): - parser = DatetimeParser() - output_date = parser.parse(input_date, date_format) - assert output_date == expected_output_date - - -@pytest.mark.parametrize( - "test_name, input_dt, datetimeformat, expected_output", - [ - ("test_format_timestamp", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%s", "1609459200"), - ("test_format_timestamp_ms", datetime.datetime(2021, 1, 1, 0, 0, 0, 1000, tzinfo=datetime.timezone.utc), "%ms", "1609459200001"), - ( - "test_format_timestamp_as_float", - datetime.datetime(2023, 1, 30, 15, 28, 28, 873709, tzinfo=datetime.timezone.utc), - "%s_as_float", - "1675092508.873709", - ), - ("test_format_string", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%Y-%m-%d", "2021-01-01"), - ("test_format_to_number", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%Y%m%d", "20210101"), - ], -) -def test_format_datetime(test_name, input_dt, datetimeformat, expected_output): - parser = DatetimeParser() - output_date = parser.format(input_dt, datetimeformat) - assert output_date == expected_output diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/datetime/test_min_max_datetime.py b/airbyte-cdk/python/unit_tests/sources/declarative/datetime/test_min_max_datetime.py deleted file mode 100644 index ff9aedf0752a..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/datetime/test_min_max_datetime.py +++ /dev/null @@ -1,128 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import datetime - -import pytest -from airbyte_cdk.sources.declarative.datetime.min_max_datetime import MinMaxDatetime -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString - -date_format = "%Y-%m-%dT%H:%M:%S.%f%z" - -old_date = "2021-01-01T20:12:19.597854Z" -middle_date = "2022-01-01T20:12:19.597854Z" -new_date = "2022-06-24T20:12:19.597854Z" - - -@pytest.mark.parametrize( - "test_name, date, min_date, max_date, expected_date", - [ - ("test_time_is_greater_than_min", "{{ config['older'] }}", "{{ stream_state['newer'] }}", "", new_date), - ("test_time_is_less_than_min", "{{ stream_state['newer'] }}", "{{ config['older'] }}", "", new_date), - ("test_time_is_equal_to_min", "{{ config['older'] }}", "{{ config['older'] }}", "", old_date), - ("test_time_is_greater_than_max", "{{ stream_state['newer'] }}", "", "{{ config['older'] }}", old_date), - ("test_time_is_less_than_max", "{{ config['older'] }}", "", "{{ stream_state['newer'] }}", old_date), - ("test_time_is_equal_to_min", "{{ stream_state['newer'] }}", "{{ stream_state['newer'] }}", "", new_date), - ( - "test_time_is_between_min_and_max", - "{{ config['middle'] }}", - "{{ config['older'] }}", - "{{ stream_state['newer'] }}", - middle_date, - ), - ("test_min_newer_time_from_parameters", "{{ config['older'] }}", "{{ parameters['newer'] }}", "", new_date), - ("test_max_newer_time_from_parameters", "{{ stream_state['newer'] }}", "", "{{ parameters['older'] }}", old_date), - ], -) -def test_min_max_datetime(test_name, date, min_date, max_date, expected_date): - config = {"older": old_date, "middle": middle_date} - stream_state = {"newer": new_date} - parameters = {"newer": new_date, "older": old_date} - - min_max_date = MinMaxDatetime(datetime=date, min_datetime=min_date, max_datetime=max_date, parameters=parameters) - actual_date = min_max_date.get_datetime(config, **{"stream_state": stream_state}) - - assert actual_date == datetime.datetime.strptime(expected_date, date_format) - - -def test_custom_datetime_format(): - config = {"older": "2021-01-01T20:12:19", "middle": "2022-01-01T20:12:19"} - stream_state = {"newer": "2022-06-24T20:12:19"} - - min_max_date = MinMaxDatetime( - datetime="{{ config['middle'] }}", - datetime_format="%Y-%m-%dT%H:%M:%S", - min_datetime="{{ config['older'] }}", - max_datetime="{{ stream_state['newer'] }}", - parameters={}, - ) - actual_date = min_max_date.get_datetime(config, **{"stream_state": stream_state}) - - assert actual_date == datetime.datetime.strptime("2022-01-01T20:12:19", "%Y-%m-%dT%H:%M:%S").replace(tzinfo=datetime.timezone.utc) - - -def test_format_is_a_number(): - config = {"older": "20210101", "middle": "20220101"} - stream_state = {"newer": "20220624"} - - min_max_date = MinMaxDatetime( - datetime="{{ config['middle'] }}", - datetime_format="%Y%m%d", - min_datetime="{{ config['older'] }}", - max_datetime="{{ stream_state['newer'] }}", - parameters={}, - ) - actual_date = min_max_date.get_datetime(config, **{"stream_state": stream_state}) - - assert actual_date == datetime.datetime.strptime("20220101", "%Y%m%d").replace(tzinfo=datetime.timezone.utc) - - -def test_set_datetime_format(): - min_max_date = MinMaxDatetime(datetime="{{ config['middle'] }}", min_datetime="{{ config['older'] }}", parameters={}) - - # Retrieve datetime using the default datetime formatting - default_fmt_config = {"older": "2021-01-01T20:12:19.597854Z", "middle": "2022-01-01T20:12:19.597854Z"} - actual_date = min_max_date.get_datetime(default_fmt_config) - - assert actual_date == datetime.datetime.strptime("2022-01-01T20:12:19.597854Z", "%Y-%m-%dT%H:%M:%S.%f%z") - - # Set a different datetime format and attempt to retrieve datetime using an updated format - min_max_date.datetime_format = "%Y-%m-%dT%H:%M:%S" - - custom_fmt_config = {"older": "2021-01-01T20:12:19", "middle": "2022-01-01T20:12:19"} - actual_date = min_max_date.get_datetime(custom_fmt_config) - - assert actual_date == datetime.datetime.strptime("2022-01-01T20:12:19", "%Y-%m-%dT%H:%M:%S").replace(tzinfo=datetime.timezone.utc) - - -def test_min_max_datetime_lazy_eval(): - kwargs = { - "datetime": "2022-01-10T00:00:00", - "datetime_format": "%Y-%m-%dT%H:%M:%S", - "min_datetime": "{{ parameters.min_datetime }}", - "max_datetime": "{{ parameters.max_datetime }}", - } - - assert datetime.datetime(2022, 1, 10, 0, 0, tzinfo=datetime.timezone.utc) == MinMaxDatetime(**kwargs, parameters={}).get_datetime({}) - assert datetime.datetime(2022, 1, 20, 0, 0, tzinfo=datetime.timezone.utc) == MinMaxDatetime( - **kwargs, parameters={"min_datetime": "2022-01-20T00:00:00"} - ).get_datetime({}) - assert datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc) == MinMaxDatetime( - **kwargs, parameters={"max_datetime": "2021-01-01T00:00:00"} - ).get_datetime({}) - - -@pytest.mark.parametrize( - "input_datetime", - [ - pytest.param("2022-01-01T00:00:00", id="test_create_min_max_datetime_from_string"), - pytest.param(InterpolatedString.create("2022-01-01T00:00:00", parameters={}), id="test_create_min_max_datetime_from_string"), - pytest.param(MinMaxDatetime("2022-01-01T00:00:00", parameters={}), id="test_create_min_max_datetime_from_minmaxdatetime"), - ], -) -def test_create_min_max_datetime(input_datetime): - minMaxDatetime = MinMaxDatetime.create(input_datetime, parameters={}) - expected_value = "2022-01-01T00:00:00" - - assert minMaxDatetime.datetime.eval(config={}) == expected_value diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/decoders/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/decoders/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/decoders/test_json_decoder.py b/airbyte-cdk/python/unit_tests/sources/declarative/decoders/test_json_decoder.py deleted file mode 100644 index 1b9a552d6ed5..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/decoders/test_json_decoder.py +++ /dev/null @@ -1,111 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import json -import os - -import pytest -import requests -from airbyte_cdk import YamlDeclarativeSource -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.declarative.decoders.json_decoder import JsonDecoder, JsonlDecoder -from airbyte_cdk.sources.declarative.models import DeclarativeStream as DeclarativeStreamModel -from airbyte_cdk.sources.declarative.parsers.model_to_component_factory import ModelToComponentFactory - - -@pytest.mark.parametrize( - "response_body, first_element", - [("", {}), ("[]", {}), ('{"healthcheck": {"status": "ok"}}', {"healthcheck": {"status": "ok"}})], -) -def test_json_decoder(requests_mock, response_body, first_element): - requests_mock.register_uri("GET", "https://airbyte.io/", text=response_body) - response = requests.get("https://airbyte.io/") - assert next(JsonDecoder(parameters={}).decode(response)) == first_element - - -@pytest.mark.parametrize( - "response_body, expected_json", - [ - ("", []), - ('{"id": 1, "name": "test1"}', [{"id": 1, "name": "test1"}]), - ('{"id": 1, "name": "test1"}\n{"id": 2, "name": "test2"}', [{"id": 1, "name": "test1"}, {"id": 2, "name": "test2"}]), - ], - ids=["empty_response", "one_line_json", "multi_line_json"], -) -def test_jsonl_decoder(requests_mock, response_body, expected_json): - requests_mock.register_uri("GET", "https://airbyte.io/", text=response_body) - response = requests.get("https://airbyte.io/") - assert list(JsonlDecoder(parameters={}).decode(response)) == expected_json - - -@pytest.fixture(name="large_events_response") -def large_event_response_fixture(): - data = {"email": "email1@example.com"} - jsonl_string = f"{json.dumps(data)}\n" - lines_in_response = 2_000_000 # ≈ 58 MB of response - dir_path = os.path.dirname(os.path.realpath(__file__)) - file_path = f"{dir_path}/test_response.txt" - with open(file_path, "w") as file: - for _ in range(lines_in_response): - file.write(jsonl_string) - yield (lines_in_response, file_path) - os.remove(file_path) - - -@pytest.mark.slow -@pytest.mark.limit_memory("20 MB") -def test_jsonl_decoder_memory_usage(requests_mock, large_events_response): - lines_in_response, file_path = large_events_response - content = """ - name: users - type: DeclarativeStream - retriever: - type: SimpleRetriever - decoder: - type: JsonlDecoder - paginator: - type: "NoPagination" - requester: - path: "users/{{ stream_slice.slice }}" - type: HttpRequester - url_base: "https://for-all-mankind.nasa.com/api/v1" - http_method: GET - authenticator: - type: NoAuth - request_headers: {} - request_body_json: {} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: [] - partition_router: - type: ListPartitionRouter - cursor_field: "slice" - values: - - users1 - - users2 - - users3 - - users4 - primary_key: [] - """ - - factory = ModelToComponentFactory() - stream_manifest = YamlDeclarativeSource._parse(content) - stream = factory.create_component(model_type=DeclarativeStreamModel, component_definition=stream_manifest, config={}) - - def get_body(): - return open(file_path, "rb", buffering=30) - - counter = 0 - requests_mock.get("https://for-all-mankind.nasa.com/api/v1/users/users1", body=get_body()) - requests_mock.get("https://for-all-mankind.nasa.com/api/v1/users/users2", body=get_body()) - requests_mock.get("https://for-all-mankind.nasa.com/api/v1/users/users3", body=get_body()) - requests_mock.get("https://for-all-mankind.nasa.com/api/v1/users/users4", body=get_body()) - - stream_slices = list(stream.stream_slices(sync_mode=SyncMode.full_refresh)) - for stream_slice in stream_slices: - for _ in stream.retriever.read_records(records_schema={}, stream_slice=stream_slice): - counter += 1 - - assert counter == lines_in_response * len(stream_slices) diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/decoders/test_pagination_decoder_decorator.py b/airbyte-cdk/python/unit_tests/sources/declarative/decoders/test_pagination_decoder_decorator.py deleted file mode 100644 index f440a2b12c9f..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/decoders/test_pagination_decoder_decorator.py +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# -import pytest -import requests -from airbyte_cdk.sources.declarative.decoders import JsonDecoder, PaginationDecoderDecorator - - -class StreamingJsonDecoder(JsonDecoder): - def is_stream_response(self) -> bool: - return True - - -@pytest.mark.parametrize( - "decoder_class, expected", - [ - (StreamingJsonDecoder, {}), - (JsonDecoder, {"data": [{"id": 1}, {"id": 2}]}) - ] -) -def test_pagination_decoder_decorator(requests_mock, decoder_class, expected): - decoder = PaginationDecoderDecorator(decoder=decoder_class(parameters={})) - response_body = "{\"data\": [{\"id\": 1}, {\"id\": 2}]}" - requests_mock.register_uri("GET", "https://airbyte.io/", text=response_body) - response = requests.get("https://airbyte.io/") - assert next(decoder.decode(response)) == expected diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/decoders/test_xml_decoder.py b/airbyte-cdk/python/unit_tests/sources/declarative/decoders/test_xml_decoder.py deleted file mode 100644 index 87c78dae4fda..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/decoders/test_xml_decoder.py +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# -import pytest -import requests -from airbyte_cdk.sources.declarative.decoders import XmlDecoder - - -@pytest.mark.parametrize( - "response_body, expected", - [ - ( - "", - {"item": {"@name": "item_1"}} - ), - ( - "Item 1Item 2", - {"data": {"item": [{"@name": "item_1", "#text": "Item 1"}, {"@name": "item_2", "#text": "Item 2"}]}} - ), - ( - None, - {} - ), - ( - "", - {} - ), - ( - "1Item 1", - {'item': {'@xmlns:ns': 'https://airbyte.io', 'ns:id': '1', 'ns:name': 'Item 1'}} - ) - ], - ids=["one_element_response", "multi_element_response", "empty_response", "malformed_xml_response", "xml_with_namespace_response"] -) -def test_xml_decoder(requests_mock, response_body, expected): - requests_mock.register_uri("GET", "https://airbyte.io/", text=response_body) - response = requests.get("https://airbyte.io/") - assert next(XmlDecoder(parameters={}).decode(response)) == expected diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/external_component.py b/airbyte-cdk/python/unit_tests/sources/declarative/external_component.py deleted file mode 100644 index d9f0ca8cae10..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/external_component.py +++ /dev/null @@ -1,13 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.requesters import HttpRequester - - -class SampleCustomComponent(HttpRequester): - """ - A test class used to validate manifests that rely on custom defined Python components - """ - - pass diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/extractors/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/extractors/__init__.py deleted file mode 100644 index 46b7376756ec..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/extractors/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/extractors/compressed_response b/airbyte-cdk/python/unit_tests/sources/declarative/extractors/compressed_response deleted file mode 100644 index da79e347f053..000000000000 Binary files a/airbyte-cdk/python/unit_tests/sources/declarative/extractors/compressed_response and /dev/null differ diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/extractors/decompressed_response.csv b/airbyte-cdk/python/unit_tests/sources/declarative/extractors/decompressed_response.csv deleted file mode 100644 index ebef74b8ec70..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/extractors/decompressed_response.csv +++ /dev/null @@ -1,25 +0,0 @@ -"EMAIL","FIRST_NAME","LAST_NAME","ADDRESS_LINE_1","ADDRESS_LINE_2","CITY","STATE_PROVINCE_REGION","POSTAL_CODE","COUNTRY","ALTERNATE_EMAILS","PHONE_NUMBER","WHATSAPP","LINE","FACEBOOK","UNIQUE_NAME","CREATED_AT","UPDATED_AT","CONTACT_ID" -"fake_email_10@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:22Z","2021-02-01T12:35:51Z","eae8c5c8-f97e-40a8-8945-72acca457f5a" -"fake_email_1@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:08Z","2021-02-01T12:35:38Z","198f959f-f441-4d15-a280-9e8f65a90ba5" -"fake_email_12@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:24Z","2021-02-01T12:35:53Z","6975b74c-bb1e-4d54-a251-b934c4193ed4" -"fake_email_8@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:19Z","2021-02-01T12:35:49Z","36ef1a2d-3cc4-4515-9c00-1615c5f860d0" -"fake_email_18@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:30Z","2021-02-01T12:36:00Z","19163421-bb29-495d-950f-edede6218081" -"fake_email_3@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:14Z","2021-02-01T12:35:43Z","d1211b88-e116-4a0b-a823-0361bf059a06" -"fake_email_9@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:21Z","2021-02-01T12:35:50Z","ef4225b0-dff9-4756-af87-c4228d836d53" -"fake_email_4@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:15Z","2021-02-01T12:35:44Z","9adef36c-fe51-421a-9653-6bd010962e98" -"fake_email_2@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:13Z","2021-02-01T12:35:42Z","210d8004-d12a-4f01-815a-f90cfa9e4360" -"fake_email_6@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:17Z","2021-02-01T12:35:46Z","76330f89-5645-4432-b3bb-9e33a9195273" -"fake_email_14@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:26Z","2021-02-01T12:35:55Z","77200269-0b69-462c-bed1-9e6f912d4b83" -"fake_email_13@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:25Z","2021-02-01T12:35:54Z","c91c993b-1dfa-4686-bcf0-31e4aeb2a1a9" -"joepogbm@ggma.co",,,,,,,,,,,,,,,"2021-02-03T19:26:52Z","2021-02-03T19:27:21Z","a2a1f3f4-0170-4fbd-9152-ffe8cbcdb93d" -"fake_email_17@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:29Z","2021-02-01T12:35:59Z","e45af829-de4e-44d6-9c89-bb0c7ce47925" -"fake_email_15@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:27Z","2021-02-01T12:35:56Z","50b36a31-daf8-45c4-bc48-13e150f6746e" -"fake_email_7@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:18Z","2021-02-01T12:35:47Z","353113b9-b41e-480a-bf98-72213350194c" -"y.kurochkin@zazmic.com",,,,,,,,,,,,,,,"2021-02-03T19:34:41Z","2021-02-03T19:35:47Z","0b62947e-de93-419e-8c96-83572bf15ed1" -"fake_email_19@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:31Z","2021-02-01T12:36:01Z","9932d677-1128-47e4-9d97-667c6155bfee" -"joepogbum@ggma.co",,,,,,,,,,,,,,,"2021-02-03T19:22:41Z","2021-02-03T19:23:10Z","ba3c48d5-b63b-48e6-8687-c5034ed0a8dd" -"fake_email_0@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:34:49Z","2021-02-01T12:35:19Z","44ec451f-d401-40d2-831d-3e3ce8a94f66" -"avida.d3@gmail.com","dima","dima",,,,,,,,,,,,,"2021-09-08T09:02:22Z","2021-09-08T09:04:58Z","2f7b13f2-60d2-462a-bfb0-d30bb8eabed8" -"fake_email_16@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:28Z","2021-02-01T12:35:57Z","c6cfd936-e327-48da-aa76-824076461d80" -"fake_email_11@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:23Z","2021-02-01T12:35:52Z","4101feb2-2b07-4aef-8eb5-62878b612fcd" -"fake_email_5@lmail.c","Fake contact","Lastname",,,,,"22341",,,,,,,,"2021-02-01T12:35:16Z","2021-02-01T12:35:45Z","32deb20d-9f8f-44b4-aed2-dc15d5bf45ba" diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/extractors/test_dpath_extractor.py b/airbyte-cdk/python/unit_tests/sources/declarative/extractors/test_dpath_extractor.py deleted file mode 100644 index 92b4ffbb4804..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/extractors/test_dpath_extractor.py +++ /dev/null @@ -1,96 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import io -import json -from typing import Dict, List, Union - -import pytest -import requests -from airbyte_cdk import Decoder -from airbyte_cdk.sources.declarative.decoders.json_decoder import IterableDecoder, JsonDecoder, JsonlDecoder -from airbyte_cdk.sources.declarative.extractors.dpath_extractor import DpathExtractor - -config = {"field": "record_array"} -parameters = {"parameters_field": "record_array"} - -decoder_json = JsonDecoder(parameters={}) -decoder_jsonl = JsonlDecoder(parameters={}) -decoder_iterable = IterableDecoder(parameters={}) - - -def create_response(body: Union[Dict, bytes]): - response = requests.Response() - response.raw = io.BytesIO(body if isinstance(body, bytes) else json.dumps(body).encode("utf-8")) - return response - - -@pytest.mark.parametrize( - "field_path, decoder, body, expected_records", - [ - (["data"], decoder_json, {"data": [{"id": 1}, {"id": 2}]}, [{"id": 1}, {"id": 2}]), - (["data"], decoder_json, {"data": {"id": 1}}, [{"id": 1}]), - ([], decoder_json, {"id": 1}, [{"id": 1}]), - ([], decoder_json, [{"id": 1}, {"id": 2}], [{"id": 1}, {"id": 2}]), - (["data", "records"], decoder_json, {"data": {"records": [{"id": 1}, {"id": 2}]}}, [{"id": 1}, {"id": 2}]), - (["{{ config['field'] }}"], decoder_json, {"record_array": [{"id": 1}, {"id": 2}]}, [{"id": 1}, {"id": 2}]), - (["{{ parameters['parameters_field'] }}"], decoder_json, {"record_array": [{"id": 1}, {"id": 2}]}, [{"id": 1}, {"id": 2}]), - (["record"], decoder_json, {"id": 1}, []), - (["list", "*", "item"], decoder_json, {"list": [{"item": {"id": "1"}}]}, [{"id": "1"}]), - ( - ["data", "*", "list", "data2", "*"], - decoder_json, - {"data": [{"list": {"data2": [{"id": 1}, {"id": 2}]}}, {"list": {"data2": [{"id": 3}, {"id": 4}]}}]}, - [{"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}], - ), - ([], decoder_jsonl, {"id": 1}, [{"id": 1}]), - ([], decoder_jsonl, [{"id": 1}, {"id": 2}], [{"id": 1}, {"id": 2}]), - (["data"], decoder_jsonl, b'{"data": [{"id": 1}, {"id": 2}]}', [{"id": 1}, {"id": 2}]), - ( - ["data"], - decoder_jsonl, - b'{"data": [{"id": 1}, {"id": 2}]}\n{"data": [{"id": 3}, {"id": 4}]}', - [{"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}], - ), - ( - ["data"], - decoder_jsonl, - b'{"data": [{"id": 1, "text_field": "This is a text\\n. New paragraph start here."}]}\n{"data": [{"id": 2, "text_field": "This is another text\\n. New paragraph start here."}]}', - [ - {"id": 1, "text_field": "This is a text\n. New paragraph start here."}, - {"id": 2, "text_field": "This is another text\n. New paragraph start here."}, - ], - ), - ( - [], - decoder_iterable, - b"user1@example.com\nuser2@example.com", - [{"record": "user1@example.com"}, {"record": "user2@example.com"}], - ), - ], - ids=[ - "test_extract_from_array", - "test_extract_single_record", - "test_extract_single_record_from_root", - "test_extract_from_root_array", - "test_nested_field", - "test_field_in_config", - "test_field_in_parameters", - "test_field_does_not_exist", - "test_nested_list", - "test_complex_nested_list", - "test_extract_single_record_from_root_jsonl", - "test_extract_from_root_jsonl", - "test_extract_from_array_jsonl", - "test_extract_from_array_multiline_jsonl", - "test_extract_from_array_multiline_with_escape_character_jsonl", - "test_extract_from_string_per_line_iterable", - ], -) -def test_dpath_extractor(field_path: List, decoder: Decoder, body, expected_records: List): - extractor = DpathExtractor(field_path=field_path, config=config, decoder=decoder, parameters=parameters) - - response = create_response(body) - actual_records = list(extractor.extract_records(response)) - - assert actual_records == expected_records diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/extractors/test_record_filter.py b/airbyte-cdk/python/unit_tests/sources/declarative/extractors/test_record_filter.py deleted file mode 100644 index 498f61b714bd..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/extractors/test_record_filter.py +++ /dev/null @@ -1,373 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -from typing import List, Mapping, Optional - -import pytest -from airbyte_cdk.sources.declarative.datetime import MinMaxDatetime -from airbyte_cdk.sources.declarative.extractors.record_filter import ClientSideIncrementalRecordFilterDecorator, RecordFilter -from airbyte_cdk.sources.declarative.incremental import ( - CursorFactory, - DatetimeBasedCursor, - GlobalSubstreamCursor, - PerPartitionWithGlobalCursor, -) -from airbyte_cdk.sources.declarative.interpolation import InterpolatedString -from airbyte_cdk.sources.declarative.models import CustomRetriever, DeclarativeStream, ParentStreamConfig -from airbyte_cdk.sources.declarative.partition_routers import SubstreamPartitionRouter -from airbyte_cdk.sources.declarative.types import StreamSlice - -DATE_FORMAT = "%Y-%m-%d" -RECORDS_TO_FILTER_DATE_FORMAT = [ - {"id": 1, "created_at": "2020-01-03"}, - {"id": 2, "created_at": "2021-01-03"}, - {"id": 3, "created_at": "2021-01-04"}, - {"id": 4, "created_at": "2021-02-01"}, - {"id": 5, "created_at": "2021-01-02"}, -] - -DATE_TIME_WITH_TZ_FORMAT = "%Y-%m-%dT%H:%M:%S%z" -RECORDS_TO_FILTER_DATE_TIME_WITH_TZ_FORMAT = [ - {"id": 1, "created_at": "2020-01-03T00:00:00+00:00"}, - {"id": 2, "created_at": "2021-01-03T00:00:00+00:00"}, - {"id": 3, "created_at": "2021-01-04T00:00:00+00:00"}, - {"id": 4, "created_at": "2021-02-01T00:00:00+00:00"}, -] - -DATE_TIME_WITHOUT_TZ_FORMAT = "%Y-%m-%dT%H:%M:%S" -RECORDS_TO_FILTER_DATE_TIME_WITHOUT_TZ_FORMAT = [ - {"id": 1, "created_at": "2020-01-03T00:00:00"}, - {"id": 2, "created_at": "2021-01-03T00:00:00"}, - {"id": 3, "created_at": "2021-01-04T00:00:00"}, - {"id": 4, "created_at": "2021-02-01T00:00:00"}, -] - - -@pytest.mark.parametrize( - "filter_template, records, expected_records", - [ - ( - "{{ record['created_at'] > stream_state['created_at'] }}", - [{"id": 1, "created_at": "06-06-21"}, {"id": 2, "created_at": "06-07-21"}, {"id": 3, "created_at": "06-08-21"}], - [{"id": 2, "created_at": "06-07-21"}, {"id": 3, "created_at": "06-08-21"}], - ), - ( - "{{ record['last_seen'] >= stream_slice['last_seen'] }}", - [{"id": 1, "last_seen": "06-06-21"}, {"id": 2, "last_seen": "06-07-21"}, {"id": 3, "last_seen": "06-10-21"}], - [{"id": 3, "last_seen": "06-10-21"}], - ), - ( - "{{ record['id'] >= next_page_token['last_seen_id'] }}", - [{"id": 11}, {"id": 12}, {"id": 13}, {"id": 14}, {"id": 15}], - [{"id": 14}, {"id": 15}], - ), - ( - "{{ record['id'] >= next_page_token['path_to_nowhere'] }}", - [{"id": 11}, {"id": 12}, {"id": 13}, {"id": 14}, {"id": 15}], - [], - ), - ( - "{{ record['created_at'] > parameters['created_at'] }}", - [{"id": 1, "created_at": "06-06-21"}, {"id": 2, "created_at": "06-07-21"}, {"id": 3, "created_at": "06-08-21"}], - [{"id": 3, "created_at": "06-08-21"}], - ), - ( - "{{ record['created_at'] > stream_slice.extra_fields['created_at'] }}", - [{"id": 1, "created_at": "06-06-21"}, {"id": 2, "created_at": "06-07-21"}, {"id": 3, "created_at": "06-08-21"}], - [{"id": 3, "created_at": "06-08-21"}], - ), - ], - ids=[ - "test_using_state_filter", - "test_with_slice_filter", - "test_with_next_page_token_filter", - "test_missing_filter_fields_return_no_results", - "test_using_parameters_filter", - "test_using_extra_fields_filter", - ], -) -def test_record_filter(filter_template: str, records: List[Mapping], expected_records: List[Mapping]): - config = {"response_override": "stop_if_you_see_me"} - parameters = {"created_at": "06-07-21"} - stream_state = {"created_at": "06-06-21"} - stream_slice = StreamSlice(partition={}, cursor_slice={"last_seen": "06-10-21"}, extra_fields={"created_at": "06-07-21"}) - next_page_token = {"last_seen_id": 14} - record_filter = RecordFilter(config=config, condition=filter_template, parameters=parameters) - - actual_records = list( - record_filter.filter_records(records, stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token) - ) - assert actual_records == expected_records - - -@pytest.mark.parametrize( - "datetime_format, stream_state, record_filter_expression, end_datetime, records_to_filter, expected_record_ids", - [ - (DATE_FORMAT, {}, None, "2021-01-05", RECORDS_TO_FILTER_DATE_FORMAT, [2, 3, 5]), - (DATE_FORMAT, {}, None, None, RECORDS_TO_FILTER_DATE_FORMAT, [2, 3, 4, 5]), - (DATE_FORMAT, {"created_at": "2021-01-04"}, None, "2021-01-05", RECORDS_TO_FILTER_DATE_FORMAT, [3]), - (DATE_FORMAT, {"created_at": "2021-01-04"}, None, None, RECORDS_TO_FILTER_DATE_FORMAT, [3, 4]), - (DATE_FORMAT, {}, "{{ record['id'] % 2 == 1 }}", "2021-01-05", RECORDS_TO_FILTER_DATE_FORMAT, [3, 5]), - (DATE_TIME_WITH_TZ_FORMAT, {}, None, "2021-01-05T00:00:00+00:00", RECORDS_TO_FILTER_DATE_TIME_WITH_TZ_FORMAT, [2, 3]), - (DATE_TIME_WITH_TZ_FORMAT, {}, None, None, RECORDS_TO_FILTER_DATE_TIME_WITH_TZ_FORMAT, [2, 3, 4]), - ( - DATE_TIME_WITH_TZ_FORMAT, - {"created_at": "2021-01-04T00:00:00+00:00"}, - None, - "2021-01-05T00:00:00+00:00", - RECORDS_TO_FILTER_DATE_TIME_WITH_TZ_FORMAT, - [3], - ), - ( - DATE_TIME_WITH_TZ_FORMAT, - {"created_at": "2021-01-04T00:00:00+00:00"}, - None, - None, - RECORDS_TO_FILTER_DATE_TIME_WITH_TZ_FORMAT, - [3, 4], - ), - ( - DATE_TIME_WITH_TZ_FORMAT, - {}, - "{{ record['id'] % 2 == 1 }}", - "2021-01-05T00:00:00+00:00", - RECORDS_TO_FILTER_DATE_TIME_WITH_TZ_FORMAT, - [3], - ), - (DATE_TIME_WITHOUT_TZ_FORMAT, {}, None, "2021-01-05T00:00:00", RECORDS_TO_FILTER_DATE_TIME_WITHOUT_TZ_FORMAT, [2, 3]), - (DATE_TIME_WITHOUT_TZ_FORMAT, {}, None, None, RECORDS_TO_FILTER_DATE_TIME_WITHOUT_TZ_FORMAT, [2, 3, 4]), - ( - DATE_TIME_WITHOUT_TZ_FORMAT, - {"created_at": "2021-01-04T00:00:00"}, - None, - "2021-01-05T00:00:00", - RECORDS_TO_FILTER_DATE_TIME_WITHOUT_TZ_FORMAT, - [3], - ), - ( - DATE_TIME_WITHOUT_TZ_FORMAT, - {"created_at": "2021-01-04T00:00:00"}, - None, - None, - RECORDS_TO_FILTER_DATE_TIME_WITHOUT_TZ_FORMAT, - [3, 4], - ), - ( - DATE_TIME_WITHOUT_TZ_FORMAT, - {}, - "{{ record['id'] % 2 == 1 }}", - "2021-01-05T00:00:00", - RECORDS_TO_FILTER_DATE_TIME_WITHOUT_TZ_FORMAT, - [3], - ), - ], - ids=[ - "date_format_no_stream_state_no_record_filter", - "date_format_no_stream_state_no_end_date_no_record_filter", - "date_format_with_stream_state_no_record_filter", - "date_format_with_stream_state_no_end_date_no_record_filter", - "date_format_no_stream_state_with_record_filter", - "date_time_with_tz_format_no_stream_state_no_record_filter", - "date_time_with_tz_format_no_stream_state_no_end_date_no_record_filter", - "date_time_with_tz_format_with_stream_state_no_record_filter", - "date_time_with_tz_format_with_stream_state_no_end_date_no_record_filter", - "date_time_with_tz_format_no_stream_state_with_record_filter", - "date_time_without_tz_format_no_stream_state_no_record_filter", - "date_time_without_tz_format_no_stream_state_no_end_date_no_record_filter", - "date_time_without_tz_format_with_stream_state_no_record_filter", - "date_time_without_tz_format_with_stream_state_no_end_date_no_record_filter", - "date_time_without_tz_format_no_stream_state_with_record_filter", - ], -) -def test_client_side_record_filter_decorator_no_parent_stream( - datetime_format: str, - stream_state: Optional[Mapping], - record_filter_expression: str, - end_datetime: Optional[str], - records_to_filter: List[Mapping], - expected_record_ids: List[int], -): - date_time_based_cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="2021-01-01", datetime_format=DATE_FORMAT, parameters={}), - end_datetime=MinMaxDatetime(datetime=end_datetime, parameters={}) if end_datetime else None, - step="P10Y", - cursor_field=InterpolatedString.create("created_at", parameters={}), - datetime_format=datetime_format, - cursor_granularity="P1D", - config={}, - parameters={}, - ) - date_time_based_cursor.set_initial_state(stream_state) - - record_filter_decorator = ClientSideIncrementalRecordFilterDecorator( - config={}, - condition=record_filter_expression, - parameters={}, - date_time_based_cursor=date_time_based_cursor, - substream_cursor=None, - ) - - filtered_records = list( - record_filter_decorator.filter_records(records=records_to_filter, stream_state=stream_state, stream_slice={}, next_page_token=None) - ) - - assert [x.get("id") for x in filtered_records] == expected_record_ids - - -@pytest.mark.parametrize( - "stream_state, cursor_type, expected_record_ids", - [ - # Use only DatetimeBasedCursor - ({}, 'datetime', [2, 3, 5]), - # Use GlobalSubstreamCursor with no state - ({}, 'global_substream', [2, 3, 5]), - # Use GlobalSubstreamCursor with global state - ( - { - 'state': {'created_at': '2021-01-03'} - }, - 'global_substream', - [2, 3] - ), - # Use PerPartitionWithGlobalCursor with partition state - ( - { - 'use_global_cursor': False, - 'state': {'created_at': '2021-01-10'}, - 'states': [ - { - 'partition': {'id': 'some_parent_id', 'parent_slice': {}}, - 'cursor': {'created_at': '2021-01-03'} - } - ] - }, - 'per_partition_with_global', - [2, 3] - ), - # Use PerPartitionWithGlobalCursor with global state - ( - { - 'use_global_cursor': True, - 'state': {'created_at': '2021-01-03'}, - 'states': [ - { - 'partition': {'id': 'some_parent_id', 'parent_slice': {}}, - 'cursor': {'created_at': '2021-01-13'} - } - ] - }, - 'per_partition_with_global', - [2, 3] - ), - # Use PerPartitionWithGlobalCursor with partition state missing, global cursor used - ( - { - 'use_global_cursor': True, - 'state': {'created_at': '2021-01-03'} - }, - 'per_partition_with_global', - [2, 3] - ), - # Use PerPartitionWithGlobalCursor with partition state missing, global cursor not used - ( - { - 'use_global_cursor': False, - 'state': {'created_at': '2021-01-03'} - }, - 'per_partition_with_global', - [2, 3, 5] # Global cursor not used, start date used - ), - ], - ids=[ - 'datetime_cursor_only', - 'global_substream_no_state', - 'global_substream_with_state', - 'per_partition_with_partition_state', - 'per_partition_with_global_state', - 'per_partition_partition_missing_global_cursor_used', - 'per_partition_partition_missing_global_cursor_not_used', - ] -) -def test_client_side_record_filter_decorator_with_cursor_types( - stream_state: Optional[Mapping], - cursor_type: str, - expected_record_ids: List[int] -): - def date_time_based_cursor_factory() -> DatetimeBasedCursor: - return DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="2021-01-01", datetime_format=DATE_FORMAT, parameters={}), - end_datetime=MinMaxDatetime(datetime="2021-01-05", datetime_format=DATE_FORMAT, parameters={}), - step="P10Y", - cursor_field=InterpolatedString.create("created_at", parameters={}), - datetime_format=DATE_FORMAT, - cursor_granularity="P1D", - config={}, - parameters={}, - ) - - date_time_based_cursor = date_time_based_cursor_factory() - - substream_cursor = None - partition_router = SubstreamPartitionRouter( - config={}, - parameters={}, - parent_stream_configs=[ - ParentStreamConfig( - type="ParentStreamConfig", - parent_key="id", - partition_field="id", - stream=DeclarativeStream( - type="DeclarativeStream", - retriever=CustomRetriever(type="CustomRetriever", class_name="a_class_name") - ), - ) - ], - ) - - if cursor_type == 'datetime': - # Use only DatetimeBasedCursor - pass # No additional cursor needed - elif cursor_type == 'global_substream': - # Create GlobalSubstreamCursor instance - substream_cursor = GlobalSubstreamCursor( - stream_cursor=date_time_based_cursor, - partition_router=partition_router, - ) - if stream_state: - substream_cursor.set_initial_state(stream_state) - elif cursor_type == 'per_partition_with_global': - # Create PerPartitionWithGlobalCursor instance - substream_cursor = PerPartitionWithGlobalCursor( - cursor_factory=CursorFactory(date_time_based_cursor_factory), - partition_router=partition_router, - stream_cursor=date_time_based_cursor, - ) - else: - raise ValueError(f"Unsupported cursor type: {cursor_type}") - - if substream_cursor and stream_state: - substream_cursor.set_initial_state(stream_state) - elif stream_state: - date_time_based_cursor.set_initial_state(stream_state) - - # Create the record_filter_decorator with appropriate cursor - record_filter_decorator = ClientSideIncrementalRecordFilterDecorator( - config={}, - parameters={}, - date_time_based_cursor=date_time_based_cursor, - substream_cursor=substream_cursor, - ) - - # The partition we're testing - stream_slice = StreamSlice(partition={"id": "some_parent_id", "parent_slice": {}}, cursor_slice={}) - - filtered_records = list( - record_filter_decorator.filter_records( - records=RECORDS_TO_FILTER_DATE_FORMAT, - stream_state=stream_state, - stream_slice=stream_slice, - next_page_token=None, - ) - ) - - assert [x.get("id") for x in filtered_records] == expected_record_ids diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/extractors/test_record_selector.py b/airbyte-cdk/python/unit_tests/sources/declarative/extractors/test_record_selector.py deleted file mode 100644 index fc2bcd6dd51e..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/extractors/test_record_selector.py +++ /dev/null @@ -1,183 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -from unittest.mock import Mock, call - -import pytest -import requests -from airbyte_cdk.sources.declarative.decoders.json_decoder import JsonDecoder -from airbyte_cdk.sources.declarative.extractors.dpath_extractor import DpathExtractor -from airbyte_cdk.sources.declarative.extractors.record_filter import RecordFilter -from airbyte_cdk.sources.declarative.extractors.record_selector import RecordSelector -from airbyte_cdk.sources.declarative.transformations import RecordTransformation -from airbyte_cdk.sources.types import Record, StreamSlice -from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer - - -@pytest.mark.parametrize( - "test_name, field_path, filter_template, body, expected_data", - [ - ( - "test_with_extractor_and_filter", - ["data"], - "{{ record['created_at'] > stream_state['created_at'] }}", - {"data": [{"id": 1, "created_at": "06-06-21"}, {"id": 2, "created_at": "06-07-21"}, {"id": 3, "created_at": "06-08-21"}]}, - [{"id": 2, "created_at": "06-07-21"}, {"id": 3, "created_at": "06-08-21"}], - ), - ( - "test_no_record_filter_returns_all_records", - ["data"], - None, - {"data": [{"id": 1, "created_at": "06-06-21"}, {"id": 2, "created_at": "06-07-21"}]}, - [{"id": 1, "created_at": "06-06-21"}, {"id": 2, "created_at": "06-07-21"}], - ), - ( - "test_with_extractor_and_filter_with_parameters", - ["{{ parameters['parameters_field'] }}"], - "{{ record['created_at'] > parameters['created_at'] }}", - {"data": [{"id": 1, "created_at": "06-06-21"}, {"id": 2, "created_at": "06-07-21"}, {"id": 3, "created_at": "06-08-21"}]}, - [{"id": 3, "created_at": "06-08-21"}], - ), - ( - "test_read_single_record", - ["data"], - None, - {"data": {"id": 1, "created_at": "06-06-21"}}, - [{"id": 1, "created_at": "06-06-21"}], - ), - ( - "test_no_record", - ["data"], - None, - {"data": []}, - [], - ), - ( - "test_no_record_from_root", - [], - None, - [], - [], - ), - ], -) -def test_record_filter(test_name, field_path, filter_template, body, expected_data): - config = {"response_override": "stop_if_you_see_me"} - parameters = {"parameters_field": "data", "created_at": "06-07-21"} - stream_state = {"created_at": "06-06-21"} - stream_slice = StreamSlice(partition={}, cursor_slice={"last_seen": "06-10-21"}) - next_page_token = {"last_seen_id": 14} - schema = create_schema() - first_transformation = Mock(spec=RecordTransformation) - second_transformation = Mock(spec=RecordTransformation) - transformations = [first_transformation, second_transformation] - - response = create_response(body) - decoder = JsonDecoder(parameters={}) - extractor = DpathExtractor(field_path=field_path, decoder=decoder, config=config, parameters=parameters) - if filter_template is None: - record_filter = None - else: - record_filter = RecordFilter(config=config, condition=filter_template, parameters=parameters) - record_selector = RecordSelector( - extractor=extractor, - record_filter=record_filter, - transformations=transformations, - config=config, - parameters=parameters, - schema_normalization=TypeTransformer(TransformConfig.NoTransform), - ) - - actual_records = list( - record_selector.select_records( - response=response, records_schema=schema, stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token - ) - ) - assert actual_records == [Record(data, stream_slice) for data in expected_data] - - calls = [] - for record in expected_data: - calls.append(call(record, config=config, stream_state=stream_state, stream_slice=stream_slice)) - for transformation in transformations: - assert transformation.transform.call_count == len(expected_data) - transformation.transform.assert_has_calls(calls) - - -@pytest.mark.parametrize( - "test_name, schema, schema_transformation, body, expected_data", - [ - ( - "test_with_empty_schema", - {}, - TransformConfig.NoTransform, - {"data": [{"id": 1, "created_at": "06-06-21", "field_int": "100", "field_float": "123.3"}]}, - [{"id": 1, "created_at": "06-06-21", "field_int": "100", "field_float": "123.3"}], - ), - ( - "test_with_schema_none_normalizer", - {}, - TransformConfig.NoTransform, - {"data": [{"id": 1, "created_at": "06-06-21", "field_int": "100", "field_float": "123.3"}]}, - [{"id": 1, "created_at": "06-06-21", "field_int": "100", "field_float": "123.3"}], - ), - ( - "test_with_schema_and_default_normalizer", - {}, - TransformConfig.DefaultSchemaNormalization, - {"data": [{"id": 1, "created_at": "06-06-21", "field_int": "100", "field_float": "123.3"}]}, - [{"id": "1", "created_at": "06-06-21", "field_int": 100, "field_float": 123.3}], - ), - ], -) -def test_schema_normalization(test_name, schema, schema_transformation, body, expected_data): - config = {"response_override": "stop_if_you_see_me"} - parameters = {"parameters_field": "data", "created_at": "06-07-21"} - stream_state = {"created_at": "06-06-21"} - stream_slice = {"last_seen": "06-10-21"} - next_page_token = {"last_seen_id": 14} - - response = create_response(body) - schema = create_schema() - decoder = JsonDecoder(parameters={}) - extractor = DpathExtractor(field_path=["data"], decoder=decoder, config=config, parameters=parameters) - record_selector = RecordSelector( - extractor=extractor, - record_filter=None, - transformations=[], - config=config, - parameters=parameters, - schema_normalization=TypeTransformer(schema_transformation), - ) - - actual_records = list( - record_selector.select_records( - response=response, - stream_state=stream_state, - stream_slice=stream_slice, - next_page_token=next_page_token, - records_schema=schema, - ) - ) - - assert actual_records == [Record(data, stream_slice) for data in expected_data] - - -def create_response(body): - response = requests.Response() - response._content = json.dumps(body).encode("utf-8") - return response - - -def create_schema(): - return { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "id": {"type": "string"}, - "created_at": {"type": "string"}, - "field_int": {"type": "integer"}, - "field_float": {"type": "number"}, - }, - } diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/extractors/test_response_to_file_extractor.py b/airbyte-cdk/python/unit_tests/sources/declarative/extractors/test_response_to_file_extractor.py deleted file mode 100644 index 8771a70290d7..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/extractors/test_response_to_file_extractor.py +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -import csv -import os -from io import BytesIO -from pathlib import Path -from unittest import TestCase - -import pytest -import requests -import requests_mock -from airbyte_cdk.sources.declarative.extractors import ResponseToFileExtractor - - -class ResponseToFileExtractorTest(TestCase): - def setUp(self) -> None: - self._extractor = ResponseToFileExtractor() - self._http_mocker = requests_mock.Mocker() - self._http_mocker.__enter__() - - def tearDown(self) -> None: - self._http_mocker.__exit__(None, None, None) - - def test_compressed_response(self) -> None: - response = self._mock_streamed_response_from_file(self._compressed_response_path()) - extracted_records = list(self._extractor.extract_records(response)) - assert len(extracted_records) == 24 - - def test_text_response(self) -> None: - response = self._mock_streamed_response_from_file(self._decompressed_response_path()) - extracted_records = list(self._extractor.extract_records(response)) - assert len(extracted_records) == 24 - - def test_text_response_with_null_bytes(self) -> None: - csv_with_null_bytes = '"FIRST_\x00NAME","LAST_NAME"\n"a first n\x00ame","a last na\x00me"\n' - response = self._mock_streamed_response(BytesIO(csv_with_null_bytes.encode("utf-8"))) - - extracted_records = list(self._extractor.extract_records(response)) - - assert extracted_records == [{"FIRST_NAME": "a first name", "LAST_NAME": "a last name"}] - - def _test_folder_path(self) -> Path: - return Path(__file__).parent.resolve() - - def _compressed_response_path(self) -> Path: - return self._test_folder_path() / "compressed_response" - - def _decompressed_response_path(self) -> Path: - return self._test_folder_path() / "decompressed_response.csv" - - def _mock_streamed_response_from_file(self, path: Path) -> requests.Response: - with path.open("rb") as f: - return self._mock_streamed_response(f) # type: ignore # Could not find the right typing for file io - - def _mock_streamed_response(self, io: BytesIO) -> requests.Response: - any_url = "https://anyurl.com" - self._http_mocker.register_uri("GET", any_url, [{"body": io, "status_code": 200}]) - return requests.get(any_url) - - -@pytest.fixture(name="large_events_response") -def large_event_response_fixture(): - lines_in_response = 2_000_000 # ≈ 62 MB of response - dir_path = os.path.dirname(os.path.realpath(__file__)) - file_path = f"{dir_path}/test_response.csv" - with open(file_path, "w") as csvfile: - csv_writer = csv.writer(csvfile) - csv_writer.writerow(["username", "email"]) # headers - for _ in range(lines_in_response): - csv_writer.writerow(["a_username","email1@example.com"]) - yield (lines_in_response, file_path) - os.remove(file_path) - - -@pytest.mark.slow -@pytest.mark.limit_memory("20 MB") -def test_response_to_file_extractor_memory_usage(requests_mock, large_events_response): - lines_in_response, file_path = large_events_response - extractor = ResponseToFileExtractor() - - url = "https://for-all-mankind.nasa.com/api/v1/users/users1" - requests_mock.get(url, body=open(file_path, "rb")) - - counter = 0 - for _ in extractor.extract_records(requests.get(url, stream=True)): - counter += 1 - - assert counter == lines_in_response diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/incremental/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/incremental/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/incremental/test_datetime_based_cursor.py b/airbyte-cdk/python/unit_tests/sources/declarative/incremental/test_datetime_based_cursor.py deleted file mode 100644 index 33bd6786c152..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/incremental/test_datetime_based_cursor.py +++ /dev/null @@ -1,892 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import datetime -import unittest - -import pytest -from airbyte_cdk.sources.declarative.datetime.min_max_datetime import MinMaxDatetime -from airbyte_cdk.sources.declarative.incremental import DatetimeBasedCursor -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType -from airbyte_cdk.sources.types import Record, StreamSlice - -datetime_format = "%Y-%m-%dT%H:%M:%S.%f%z" -cursor_granularity = "PT0.000001S" -FAKE_NOW = datetime.datetime(2022, 1, 1, tzinfo=datetime.timezone.utc) - -config = {"start_date": "2021-01-01T00:00:00.000000+0000", "start_date_ymd": "2021-01-01"} -end_date_now = InterpolatedString(string="{{ today_utc() }}", parameters={}) -cursor_field = "created" -timezone = datetime.timezone.utc -NO_STATE = {} -ANY_SLICE = {} - - -class MockedNowDatetime(datetime.datetime): - @classmethod - def now(cls, tz=None): - return FAKE_NOW - - -@pytest.fixture() -def mock_datetime_now(monkeypatch): - monkeypatch.setattr(datetime, "datetime", MockedNowDatetime) - - -@pytest.mark.parametrize( - "test_name, stream_state, start, end, step, cursor_field, lookback_window, datetime_format, cursor_granularity, is_compare_strictly, expected_slices", - [ - ( - "test_1_day", - NO_STATE, - MinMaxDatetime(datetime="{{ config['start_date'] }}", parameters={}), - MinMaxDatetime(datetime="2021-01-10T00:00:00.000000+0000", parameters={}), - "P1D", - cursor_field, - None, - datetime_format, - cursor_granularity, - None, - [ - {"start_time": "2021-01-01T00:00:00.000000+0000", "end_time": "2021-01-01T23:59:59.999999+0000"}, - {"start_time": "2021-01-02T00:00:00.000000+0000", "end_time": "2021-01-02T23:59:59.999999+0000"}, - {"start_time": "2021-01-03T00:00:00.000000+0000", "end_time": "2021-01-03T23:59:59.999999+0000"}, - {"start_time": "2021-01-04T00:00:00.000000+0000", "end_time": "2021-01-04T23:59:59.999999+0000"}, - {"start_time": "2021-01-05T00:00:00.000000+0000", "end_time": "2021-01-05T23:59:59.999999+0000"}, - {"start_time": "2021-01-06T00:00:00.000000+0000", "end_time": "2021-01-06T23:59:59.999999+0000"}, - {"start_time": "2021-01-07T00:00:00.000000+0000", "end_time": "2021-01-07T23:59:59.999999+0000"}, - {"start_time": "2021-01-08T00:00:00.000000+0000", "end_time": "2021-01-08T23:59:59.999999+0000"}, - {"start_time": "2021-01-09T00:00:00.000000+0000", "end_time": "2021-01-09T23:59:59.999999+0000"}, - {"start_time": "2021-01-10T00:00:00.000000+0000", "end_time": "2021-01-10T00:00:00.000000+0000"}, - ], - ), - ( - "test_2_day", - NO_STATE, - MinMaxDatetime(datetime="{{ config['start_date'] }}", parameters={}), - MinMaxDatetime(datetime="2021-01-10T00:00:00.000000+0000", parameters={}), - "P2D", - cursor_field, - None, - datetime_format, - cursor_granularity, - None, - [ - {"start_time": "2021-01-01T00:00:00.000000+0000", "end_time": "2021-01-02T23:59:59.999999+0000"}, - {"start_time": "2021-01-03T00:00:00.000000+0000", "end_time": "2021-01-04T23:59:59.999999+0000"}, - {"start_time": "2021-01-05T00:00:00.000000+0000", "end_time": "2021-01-06T23:59:59.999999+0000"}, - {"start_time": "2021-01-07T00:00:00.000000+0000", "end_time": "2021-01-08T23:59:59.999999+0000"}, - {"start_time": "2021-01-09T00:00:00.000000+0000", "end_time": "2021-01-10T00:00:00.000000+0000"}, - ], - ), - ( - "test_1_week", - NO_STATE, - MinMaxDatetime(datetime="{{ config['start_date'] }}", parameters={}), - MinMaxDatetime(datetime="2021-02-10T00:00:00.000000+0000", parameters={}), - "P1W", - cursor_field, - None, - datetime_format, - cursor_granularity, - None, - [ - {"start_time": "2021-01-01T00:00:00.000000+0000", "end_time": "2021-01-07T23:59:59.999999+0000"}, - {"start_time": "2021-01-08T00:00:00.000000+0000", "end_time": "2021-01-14T23:59:59.999999+0000"}, - {"start_time": "2021-01-15T00:00:00.000000+0000", "end_time": "2021-01-21T23:59:59.999999+0000"}, - {"start_time": "2021-01-22T00:00:00.000000+0000", "end_time": "2021-01-28T23:59:59.999999+0000"}, - {"start_time": "2021-01-29T00:00:00.000000+0000", "end_time": "2021-02-04T23:59:59.999999+0000"}, - {"start_time": "2021-02-05T00:00:00.000000+0000", "end_time": "2021-02-10T00:00:00.000000+0000"}, - ], - ), - ( - "test_1_month", - NO_STATE, - MinMaxDatetime(datetime="{{ config['start_date'] }}", parameters={}), - MinMaxDatetime(datetime="2021-06-10T00:00:00.000000+0000", parameters={}), - "P1M", - cursor_field, - None, - datetime_format, - cursor_granularity, - None, - [ - {"start_time": "2021-01-01T00:00:00.000000+0000", "end_time": "2021-01-31T23:59:59.999999+0000"}, - {"start_time": "2021-02-01T00:00:00.000000+0000", "end_time": "2021-02-28T23:59:59.999999+0000"}, - {"start_time": "2021-03-01T00:00:00.000000+0000", "end_time": "2021-03-31T23:59:59.999999+0000"}, - {"start_time": "2021-04-01T00:00:00.000000+0000", "end_time": "2021-04-30T23:59:59.999999+0000"}, - {"start_time": "2021-05-01T00:00:00.000000+0000", "end_time": "2021-05-31T23:59:59.999999+0000"}, - {"start_time": "2021-06-01T00:00:00.000000+0000", "end_time": "2021-06-10T00:00:00.000000+0000"}, - ], - ), - ( - "test_1_year", - NO_STATE, - MinMaxDatetime(datetime="{{ config['start_date'] }}", parameters={}), - MinMaxDatetime(datetime="2022-06-10T00:00:00.000000+0000", parameters={}), - "P1Y", - cursor_field, - None, - datetime_format, - cursor_granularity, - None, - [ - {"start_time": "2021-01-01T00:00:00.000000+0000", "end_time": "2021-12-31T23:59:59.999999+0000"}, - {"start_time": "2022-01-01T00:00:00.000000+0000", "end_time": "2022-01-01T00:00:00.000000+0000"}, - ], - ), - ( - "test_from_stream_state", - {cursor_field: "2021-01-05T00:00:00.000000+0000"}, - MinMaxDatetime(datetime="2020-01-05T00:00:00.000000+0000", parameters={}), - MinMaxDatetime(datetime="2021-01-10T00:00:00.000000+0000", parameters={}), - "P1D", - cursor_field, - None, - datetime_format, - cursor_granularity, - None, - [ - {"start_time": "2021-01-05T00:00:00.000000+0000", "end_time": "2021-01-05T23:59:59.999999+0000"}, - {"start_time": "2021-01-06T00:00:00.000000+0000", "end_time": "2021-01-06T23:59:59.999999+0000"}, - {"start_time": "2021-01-07T00:00:00.000000+0000", "end_time": "2021-01-07T23:59:59.999999+0000"}, - {"start_time": "2021-01-08T00:00:00.000000+0000", "end_time": "2021-01-08T23:59:59.999999+0000"}, - {"start_time": "2021-01-09T00:00:00.000000+0000", "end_time": "2021-01-09T23:59:59.999999+0000"}, - {"start_time": "2021-01-10T00:00:00.000000+0000", "end_time": "2021-01-10T00:00:00.000000+0000"}, - ], - ), - ( - "test_12_day", - NO_STATE, - MinMaxDatetime(datetime="{{ config['start_date'] }}", parameters={}), - MinMaxDatetime(datetime="2021-01-10T00:00:00.000000+0000", parameters={}), - "P12D", - cursor_field, - None, - datetime_format, - cursor_granularity, - None, - [ - {"start_time": "2021-01-01T00:00:00.000000+0000", "end_time": "2021-01-10T00:00:00.000000+0000"}, - ], - ), - ( - "test_end_time_greater_than_now", - NO_STATE, - MinMaxDatetime(datetime="2021-12-28T00:00:00.000000+0000", parameters={}), - MinMaxDatetime(datetime=f"{(FAKE_NOW + datetime.timedelta(days=1)).strftime(datetime_format)}", parameters={}), - "P1D", - cursor_field, - None, - datetime_format, - cursor_granularity, - None, - [ - {"start_time": "2021-12-28T00:00:00.000000+0000", "end_time": "2021-12-28T23:59:59.999999+0000"}, - {"start_time": "2021-12-29T00:00:00.000000+0000", "end_time": "2021-12-29T23:59:59.999999+0000"}, - {"start_time": "2021-12-30T00:00:00.000000+0000", "end_time": "2021-12-30T23:59:59.999999+0000"}, - {"start_time": "2021-12-31T00:00:00.000000+0000", "end_time": "2021-12-31T23:59:59.999999+0000"}, - {"start_time": "2022-01-01T00:00:00.000000+0000", "end_time": "2022-01-01T00:00:00.000000+0000"}, - ], - ), - ( - "test_start_date_greater_than_end_time", - NO_STATE, - MinMaxDatetime(datetime="2021-01-10T00:00:00.000000+0000", parameters={}), - MinMaxDatetime(datetime="2021-01-05T00:00:00.000000+0000", parameters={}), - "P1D", - cursor_field, - None, - datetime_format, - cursor_granularity, - None, - [ - {"start_time": "2021-01-05T00:00:00.000000+0000", "end_time": "2021-01-05T00:00:00.000000+0000"}, - ], - ), - ( - "test_cursor_date_greater_than_start_date", - {cursor_field: "2021-01-05T00:00:00.000000+0000"}, - MinMaxDatetime(datetime="2021-01-01T00:00:00.000000+0000", parameters={}), - MinMaxDatetime(datetime="2021-01-10T00:00:00.000000+0000", parameters={}), - "P1D", - cursor_field, - None, - datetime_format, - cursor_granularity, - None, - [ - {"start_time": "2021-01-05T00:00:00.000000+0000", "end_time": "2021-01-05T23:59:59.999999+0000"}, - {"start_time": "2021-01-06T00:00:00.000000+0000", "end_time": "2021-01-06T23:59:59.999999+0000"}, - {"start_time": "2021-01-07T00:00:00.000000+0000", "end_time": "2021-01-07T23:59:59.999999+0000"}, - {"start_time": "2021-01-08T00:00:00.000000+0000", "end_time": "2021-01-08T23:59:59.999999+0000"}, - {"start_time": "2021-01-09T00:00:00.000000+0000", "end_time": "2021-01-09T23:59:59.999999+0000"}, - {"start_time": "2021-01-10T00:00:00.000000+0000", "end_time": "2021-01-10T00:00:00.000000+0000"}, - ], - ), - ( - "test_cursor_date_greater_than_start_date_multiday_step", - {cursor_field: "2021-01-05T00:00:00.000000+0000"}, - MinMaxDatetime(datetime="2021-01-03T00:00:00.000000+0000", parameters={}), - MinMaxDatetime(datetime="2021-01-10T00:00:00.000000+0000", parameters={}), - "P2D", - cursor_field, - None, - datetime_format, - cursor_granularity, - None, - [ - {"start_time": "2021-01-05T00:00:00.000000+0000", "end_time": "2021-01-06T23:59:59.999999+0000"}, - {"start_time": "2021-01-07T00:00:00.000000+0000", "end_time": "2021-01-08T23:59:59.999999+0000"}, - {"start_time": "2021-01-09T00:00:00.000000+0000", "end_time": "2021-01-10T00:00:00.000000+0000"}, - ], - ), - ( - "test_with_lookback_window_from_start_date", - NO_STATE, - MinMaxDatetime(datetime="2021-01-05", datetime_format="%Y-%m-%d", parameters={}), - MinMaxDatetime(datetime="2021-01-05", datetime_format="%Y-%m-%d", parameters={}), - "P1D", - cursor_field, - "P3D", - datetime_format, - cursor_granularity, - None, - [ - {"start_time": "2021-01-02T00:00:00.000000+0000", "end_time": "2021-01-02T23:59:59.999999+0000"}, - {"start_time": "2021-01-03T00:00:00.000000+0000", "end_time": "2021-01-03T23:59:59.999999+0000"}, - {"start_time": "2021-01-04T00:00:00.000000+0000", "end_time": "2021-01-04T23:59:59.999999+0000"}, - {"start_time": "2021-01-05T00:00:00.000000+0000", "end_time": "2021-01-05T00:00:00.000000+0000"}, - ], - ), - ( - "test_with_lookback_window_from_cursor", - {cursor_field: "2021-01-05T00:00:00.000000+0000"}, - MinMaxDatetime(datetime="2021-01-01T00:00:00.000000+0000", parameters={}), - MinMaxDatetime(datetime="2021-01-06T00:00:00.000000+0000", parameters={}), - "P1D", - cursor_field, - "P3D", - datetime_format, - cursor_granularity, - None, - [ - {"start_time": "2021-01-02T00:00:00.000000+0000", "end_time": "2021-01-02T23:59:59.999999+0000"}, - {"start_time": "2021-01-03T00:00:00.000000+0000", "end_time": "2021-01-03T23:59:59.999999+0000"}, - {"start_time": "2021-01-04T00:00:00.000000+0000", "end_time": "2021-01-04T23:59:59.999999+0000"}, - {"start_time": "2021-01-05T00:00:00.000000+0000", "end_time": "2021-01-05T23:59:59.999999+0000"}, - {"start_time": "2021-01-06T00:00:00.000000+0000", "end_time": "2021-01-06T00:00:00.000000+0000"}, - ], - ), - ( - "test_with_lookback_window_defaults_to_0d", - {}, - MinMaxDatetime(datetime="2021-01-01", datetime_format="%Y-%m-%d", parameters={}), - MinMaxDatetime(datetime="2021-01-05", datetime_format="%Y-%m-%d", parameters={}), - "P1D", - cursor_field, - "{{ config['does_not_exist'] }}", - datetime_format, - cursor_granularity, - None, - [ - {"start_time": "2021-01-01T00:00:00.000000+0000", "end_time": "2021-01-01T23:59:59.999999+0000"}, - {"start_time": "2021-01-02T00:00:00.000000+0000", "end_time": "2021-01-02T23:59:59.999999+0000"}, - {"start_time": "2021-01-03T00:00:00.000000+0000", "end_time": "2021-01-03T23:59:59.999999+0000"}, - {"start_time": "2021-01-04T00:00:00.000000+0000", "end_time": "2021-01-04T23:59:59.999999+0000"}, - {"start_time": "2021-01-05T00:00:00.000000+0000", "end_time": "2021-01-05T00:00:00.000000+0000"}, - ], - ), - ( - "test_start_is_after_stream_state", - {cursor_field: "2021-01-05T00:00:00.000000+0000"}, - MinMaxDatetime(datetime="2021-01-01T00:00:00.000000+0000", parameters={}), - MinMaxDatetime(datetime="2021-01-10T00:00:00.000000+0000", parameters={}), - "P1D", - cursor_field, - None, - datetime_format, - cursor_granularity, - None, - [ - {"start_time": "2021-01-05T00:00:00.000000+0000", "end_time": "2021-01-05T23:59:59.999999+0000"}, - {"start_time": "2021-01-06T00:00:00.000000+0000", "end_time": "2021-01-06T23:59:59.999999+0000"}, - {"start_time": "2021-01-07T00:00:00.000000+0000", "end_time": "2021-01-07T23:59:59.999999+0000"}, - {"start_time": "2021-01-08T00:00:00.000000+0000", "end_time": "2021-01-08T23:59:59.999999+0000"}, - {"start_time": "2021-01-09T00:00:00.000000+0000", "end_time": "2021-01-09T23:59:59.999999+0000"}, - {"start_time": "2021-01-10T00:00:00.000000+0000", "end_time": "2021-01-10T00:00:00.000000+0000"}, - ], - ), - ( - "test_slices_without_intersections", - NO_STATE, - MinMaxDatetime(datetime="{{ config['start_date'] }}", parameters={}), - MinMaxDatetime(datetime="2021-02-01T00:00:00.000000+0000", parameters={}), - "P1M", - cursor_field, - None, - datetime_format, - cursor_granularity, - True, - [ - {"start_time": "2021-01-01T00:00:00.000000+0000", "end_time": "2021-01-31T23:59:59.999999+0000"}, - ], - ), - ], -) -def test_stream_slices( - mock_datetime_now, - test_name, - stream_state, - start, - end, - step, - cursor_field, - lookback_window, - datetime_format, - cursor_granularity, - is_compare_strictly, - expected_slices, -): - lookback_window = InterpolatedString(string=lookback_window, parameters={}) if lookback_window else None - cursor = DatetimeBasedCursor( - start_datetime=start, - end_datetime=end, - step=step, - cursor_field=cursor_field, - datetime_format=datetime_format, - cursor_granularity=cursor_granularity, - lookback_window=lookback_window, - is_compare_strictly=is_compare_strictly, - config=config, - parameters={}, - ) - cursor.set_initial_state(stream_state) - stream_slices = cursor.stream_slices() - - assert stream_slices == expected_slices - - -@pytest.mark.parametrize( - "test_name, previous_cursor, stream_slice, observed_records, expected_state", - [ - ( - "test_close_slice_previous_cursor_is_highest", - "2023-01-01", - StreamSlice(partition={}, cursor_slice={"start_time": "2021-01-01", "end_time": "2022-01-01"}), - [{cursor_field: "2021-01-01"}], - {cursor_field: "2023-01-01"}, - ), - ( - "test_close_slice_stream_slice_partition_end_is_highest", - "2020-01-01", - StreamSlice(partition={}, cursor_slice={"start_time": "2021-01-01", "end_time": "2023-01-01"}), - [{cursor_field: "2021-01-01"}], - {cursor_field: "2021-01-01"}, - ), - ( - "test_close_slice_latest_record_cursor_value_is_higher_than_slice_end", - "2021-01-01", - StreamSlice(partition={}, cursor_slice={"start_time": "2021-01-01", "end_time": "2022-01-01"}), - [{cursor_field: "2023-01-01"}], - {cursor_field: "2021-01-01"}, - ), - ( - "test_close_slice_with_no_records_observed", - "2021-01-01", - StreamSlice(partition={}, cursor_slice={"start_time": "2021-01-01", "end_time": "2022-01-01"}), - [], - {cursor_field: "2021-01-01"}, - ), - ( - "test_close_slice_with_no_records_observed_and_no_previous_state", - None, - StreamSlice(partition={}, cursor_slice={"start_time": "2021-01-01", "end_time": "2022-01-01"}), - [], - {}, - ), - ( - "test_close_slice_without_previous_cursor", - None, - StreamSlice(partition={}, cursor_slice={"start_time": "2021-01-01", "end_time": "2023-01-01"}), - [{cursor_field: "2022-01-01"}], - {cursor_field: "2022-01-01"}, - ), - ( - "test_close_slice_with_out_of_order_records", - "2021-01-01", - StreamSlice(partition={}, cursor_slice={"start_time": "2021-01-01", "end_time": "2022-01-01"}), - [{cursor_field: "2021-04-01"}, {cursor_field: "2021-02-01"}, {cursor_field: "2021-03-01"}], - {cursor_field: "2021-04-01"}, - ), - ( - "test_close_slice_with_some_records_out_of_slice_boundaries", - "2021-01-01", - StreamSlice(partition={}, cursor_slice={"start_time": "2021-01-01", "end_time": "2022-01-01"}), - [{cursor_field: "2021-02-01"}, {cursor_field: "2021-03-01"}, {cursor_field: "2023-01-01"}], - {cursor_field: "2021-03-01"}, - ), - ( - "test_close_slice_with_all_records_out_of_slice_boundaries", - "2021-01-01", - StreamSlice(partition={}, cursor_slice={"start_time": "2021-01-01", "end_time": "2022-01-01"}), - [{cursor_field: "2023-01-01"}], - {cursor_field: "2021-01-01"}, - ), - ( - "test_close_slice_with_all_records_out_of_slice_and_no_previous_cursor", - None, - StreamSlice(partition={}, cursor_slice={"start_time": "2021-01-01", "end_time": "2022-01-01"}), - [{cursor_field: "2023-01-01"}], - {}, - ), - ], -) -def test_close_slice(test_name, previous_cursor, stream_slice, observed_records, expected_state): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="2021-01-01T00:00:00.000000+0000", parameters={}), - cursor_field=InterpolatedString(string=cursor_field, parameters={}), - datetime_format="%Y-%m-%d", - config=config, - parameters={}, - partition_field_start="start_time", - partition_field_end="end_time", - ) - cursor.set_initial_state({cursor_field: previous_cursor}) - for record_data in observed_records: - record = Record(record_data, stream_slice) - cursor.observe(stream_slice, record) - cursor.close_slice(stream_slice) - updated_state = cursor.get_stream_state() - assert updated_state == expected_state - - -def test_close_slice_fails_if_slice_has_a_partition(): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="2021-01-01T00:00:00.000000+0000", parameters={}), - cursor_field=InterpolatedString(string=cursor_field, parameters={}), - datetime_format="%Y-%m-%d", - config=config, - parameters={}, - ) - stream_slice = StreamSlice(partition={"key": "value"}, cursor_slice={"end_time": "2022-01-01"}) - with pytest.raises(ValueError): - cursor.close_slice(stream_slice) - - -def test_compares_cursor_values_by_chronological_order(): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="2021-01-01T00:00:00.000000+0000", parameters={}), - cursor_field=cursor_field, - datetime_format="%d-%m-%Y", - config=config, - parameters={}, - ) - - _slice = StreamSlice(partition={}, cursor_slice={"start_time": "01-01-2023", "end_time": "01-04-2023"}) - first_record = Record({cursor_field: "21-02-2023"}, _slice) - cursor.observe(_slice, first_record) - second_record = Record({cursor_field: "01-03-2023"}, _slice) - cursor.observe(_slice, second_record) - cursor.close_slice(_slice) - - assert cursor.get_stream_state()[cursor_field] == "01-03-2023" - - -def test_given_different_format_and_slice_is_highest_when_close_slice_then_state_uses_record_format(): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="2021-01-01T00:00:00.000000+0000", parameters={}), - cursor_field=cursor_field, - datetime_format="%Y-%m-%dT%H:%M:%S.%fZ", - cursor_datetime_formats=["%Y-%m-%d"], - config=config, - parameters={}, - ) - - _slice = StreamSlice(partition={}, cursor_slice={"start_time": "2023-01-01T17:30:19.000Z", "end_time": "2023-01-04T17:30:19.000Z"}) - record_cursor_value = "2023-01-03" - record = Record({cursor_field: record_cursor_value}, _slice) - cursor.observe(_slice, record) - cursor.close_slice(_slice) - - assert cursor.get_stream_state()[cursor_field] == "2023-01-03" - - -@pytest.mark.parametrize( - "test_name, inject_into, field_name, expected_req_params, expected_headers, expected_body_json, expected_body_data", - [ - ("test_start_time_inject_into_none", None, None, {}, {}, {}, {}), - ( - "test_start_time_passed_by_req_param", - RequestOptionType.request_parameter, - "start_time", - {"start_time": "2021-01-01T00:00:00.000000+0000", "endtime": "2021-01-04T00:00:00.000000+0000"}, - {}, - {}, - {}, - ), - ( - "test_start_time_inject_into_header", - RequestOptionType.header, - "start_time", - {}, - {"start_time": "2021-01-01T00:00:00.000000+0000", "endtime": "2021-01-04T00:00:00.000000+0000"}, - {}, - {}, - ), - ( - "test_start_time_inject_intoy_body_json", - RequestOptionType.body_json, - "start_time", - {}, - {}, - {"start_time": "2021-01-01T00:00:00.000000+0000", "endtime": "2021-01-04T00:00:00.000000+0000"}, - {}, - ), - ( - "test_start_time_inject_into_body_data", - RequestOptionType.body_data, - "start_time", - {}, - {}, - {}, - {"start_time": "2021-01-01T00:00:00.000000+0000", "endtime": "2021-01-04T00:00:00.000000+0000"}, - ), - ], -) -def test_request_option(test_name, inject_into, field_name, expected_req_params, expected_headers, expected_body_json, expected_body_data): - start_request_option = RequestOption(inject_into=inject_into, parameters={}, field_name=field_name) if inject_into else None - end_request_option = RequestOption(inject_into=inject_into, parameters={}, field_name="endtime") if inject_into else None - slicer = DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="2021-01-01T00:00:00.000000+0000", parameters={}), - end_datetime=MinMaxDatetime(datetime="2021-01-10T00:00:00.000000+0000", parameters={}), - step="P1D", - cursor_field=InterpolatedString(string=cursor_field, parameters={}), - datetime_format=datetime_format, - cursor_granularity=cursor_granularity, - lookback_window=InterpolatedString(string="P0D", parameters={}), - start_time_option=start_request_option, - end_time_option=end_request_option, - config=config, - parameters={}, - ) - stream_slice = {"start_time": "2021-01-01T00:00:00.000000+0000", "end_time": "2021-01-04T00:00:00.000000+0000"} - assert slicer.get_request_params(stream_slice=stream_slice) == expected_req_params - assert slicer.get_request_headers(stream_slice=stream_slice) == expected_headers - assert slicer.get_request_body_json(stream_slice=stream_slice) == expected_body_json - assert slicer.get_request_body_data(stream_slice=stream_slice) == expected_body_data - - -@pytest.mark.parametrize( - "stream_slice", - [ - pytest.param(None, id="test_none_stream_slice"), - pytest.param({}, id="test_none_stream_slice"), - ], -) -def test_request_option_with_empty_stream_slice(stream_slice): - start_request_option = RequestOption(inject_into=RequestOptionType.request_parameter, parameters={}, field_name="starttime") - end_request_option = RequestOption(inject_into=RequestOptionType.request_parameter, parameters={}, field_name="endtime") - slicer = DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="2021-01-01T00:00:00.000000+0000", parameters={}), - end_datetime=MinMaxDatetime(datetime="2021-01-10T00:00:00.000000+0000", parameters={}), - step="P1D", - cursor_field=InterpolatedString(string=cursor_field, parameters={}), - datetime_format=datetime_format, - cursor_granularity=cursor_granularity, - lookback_window=InterpolatedString(string="P0D", parameters={}), - start_time_option=start_request_option, - end_time_option=end_request_option, - config=config, - parameters={}, - ) - assert {} == slicer.get_request_params(stream_slice=stream_slice) - - -@pytest.mark.parametrize( - "test_name, input_date, date_format, date_format_granularity, expected_output_date", - [ - ( - "test_parse_date_iso", - "2021-01-01T00:00:00.000000+0000", - "%Y-%m-%dT%H:%M:%S.%f%z", - "PT0.000001S", - datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - ), - ( - "test_parse_timestamp", - "1609459200", - "%s", - "PT1S", - datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - ), - ("test_parse_date_number", "20210101", "%Y%m%d", "P1D", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)), - ], -) -def test_parse_date_legacy_merge_datetime_format_in_cursor_datetime_format( - test_name, input_date, date_format, date_format_granularity, expected_output_date -): - slicer = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("2021-01-01T00:00:00.000000+0000", parameters={}), - end_datetime=MinMaxDatetime("2021-01-10T00:00:00.000000+0000", parameters={}), - step="P1D", - cursor_field=InterpolatedString(cursor_field, parameters={}), - datetime_format=date_format, - cursor_granularity=date_format_granularity, - lookback_window=InterpolatedString("P0D", parameters={}), - config=config, - parameters={}, - ) - output_date = slicer.parse_date(input_date) - assert output_date == expected_output_date - - -@pytest.mark.parametrize( - "test_name, input_date, date_formats, expected_output_date", - [ - ( - "test_match_first_format", - "2021-01-01T00:00:00.000000+0000", - ["%Y-%m-%dT%H:%M:%S.%f%z", "%s"], - datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - ), - ( - "test_match_second_format", - "1609459200", - ["%Y-%m-%dT%H:%M:%S.%f%z", "%s"], - datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - ), - ], -) -def test_parse_date(test_name, input_date, date_formats, expected_output_date): - slicer = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("2021-01-01T00:00:00.000000+0000", parameters={}), - cursor_field=InterpolatedString(cursor_field, parameters={}), - datetime_format="%Y-%m-%d", - cursor_datetime_formats=date_formats, - config=config, - parameters={}, - ) - assert slicer.parse_date(input_date) == expected_output_date - - -def test_given_unknown_format_when_parse_date_then_raise_error(): - slicer = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("2021-01-01T00:00:00.000000+0000", parameters={}), - cursor_field=InterpolatedString(cursor_field, parameters={}), - datetime_format="%Y-%m-%d", - cursor_datetime_formats=["%Y-%m-%d", "%s"], - config=config, - parameters={}, - ) - with pytest.raises(ValueError): - slicer.parse_date("2021-01-01T00:00:00.000000+0000") - - -@pytest.mark.parametrize( - "test_name, input_dt, datetimeformat, datetimeformat_granularity, expected_output", - [ - ("test_format_timestamp", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%s", "PT1S", "1609459200"), - ("test_format_string", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%Y-%m-%d", "P1D", "2021-01-01"), - ("test_format_to_number", datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), "%Y%m%d", "P1D", "20210101"), - ], -) -def test_format_datetime(test_name, input_dt, datetimeformat, datetimeformat_granularity, expected_output): - slicer = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("2021-01-01T00:00:00.000000+0000", parameters={}), - end_datetime=MinMaxDatetime("2021-01-10T00:00:00.000000+0000", parameters={}), - step="P1D", - cursor_field=InterpolatedString(cursor_field, parameters={}), - datetime_format=datetimeformat, - cursor_granularity=datetimeformat_granularity, - lookback_window=InterpolatedString("P0D", parameters={}), - config=config, - parameters={}, - ) - - output_date = slicer._format_datetime(input_dt) - assert output_date == expected_output - - -def test_step_but_no_cursor_granularity(): - with pytest.raises(ValueError): - DatetimeBasedCursor( - start_datetime=MinMaxDatetime("2021-01-01T00:00:00.000000+0000", parameters={}), - end_datetime=MinMaxDatetime("2021-01-10T00:00:00.000000+0000", parameters={}), - step="P1D", - cursor_field=InterpolatedString(cursor_field, parameters={}), - datetime_format="%Y-%m-%d", - config=config, - parameters={}, - ) - - -def test_cursor_granularity_but_no_step(): - with pytest.raises(ValueError): - DatetimeBasedCursor( - start_datetime=MinMaxDatetime("2021-01-01T00:00:00.000000+0000", parameters={}), - end_datetime=MinMaxDatetime("2021-01-10T00:00:00.000000+0000", parameters={}), - cursor_granularity="P1D", - cursor_field=InterpolatedString(cursor_field, parameters={}), - datetime_format="%Y-%m-%d", - config=config, - parameters={}, - ) - - -def test_given_multiple_cursor_datetime_format_then_slice_using_first_format(): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("2021-01-01", parameters={}), - end_datetime=MinMaxDatetime("2023-01-10", parameters={}), - cursor_field=InterpolatedString(cursor_field, parameters={}), - datetime_format="%Y-%m-%d", - cursor_datetime_formats=["%Y-%m-%dT%H:%M:%S", "%Y-%m-%d"], - config=config, - parameters={}, - ) - stream_slices = cursor.stream_slices() - assert stream_slices == [{"start_time": "2021-01-01", "end_time": "2023-01-10"}] - - -def test_no_cursor_granularity_and_no_step_then_only_return_one_slice(): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("2021-01-01", parameters={}), - end_datetime=MinMaxDatetime("2023-01-01", parameters={}), - cursor_field=InterpolatedString(cursor_field, parameters={}), - datetime_format="%Y-%m-%d", - config=config, - parameters={}, - ) - stream_slices = cursor.stream_slices() - assert stream_slices == [{"start_time": "2021-01-01", "end_time": "2023-01-01"}] - - -def test_no_end_datetime(mock_datetime_now): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("2021-01-01", parameters={}), - cursor_field=InterpolatedString(cursor_field, parameters={}), - datetime_format="%Y-%m-%d", - config=config, - parameters={}, - ) - stream_slices = cursor.stream_slices() - assert stream_slices == [{"start_time": "2021-01-01", "end_time": FAKE_NOW.strftime("%Y-%m-%d")}] - - -def test_given_no_state_and_start_before_cursor_value_when_should_be_synced_then_return_true(): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("2021-01-01", parameters={}), - cursor_field=InterpolatedString(cursor_field, parameters={}), - datetime_format="%Y-%m-%d", - config=config, - parameters={}, - ) - assert cursor.should_be_synced(Record({cursor_field: "2022-01-01"}, ANY_SLICE)) - - -def test_given_no_state_and_start_after_cursor_value_when_should_be_synced_then_return_false(): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("2022-01-01", parameters={}), - cursor_field=InterpolatedString(cursor_field, parameters={}), - datetime_format="%Y-%m-%d", - config=config, - parameters={}, - ) - assert not cursor.should_be_synced(Record({cursor_field: "2021-01-01"}, ANY_SLICE)) - - -def test_given_state_earliest_to_start_datetime_when_should_be_synced_then_use_state_as_earliest_boundary(): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("2021-01-01", parameters={}), - cursor_field=InterpolatedString(cursor_field, parameters={}), - datetime_format="%Y-%m-%d", - config=config, - parameters={}, - ) - cursor.set_initial_state({cursor_field: "2023-01-01"}) - assert not cursor.should_be_synced(Record({cursor_field: "2022-01-01"}, ANY_SLICE)) - - -def test_given_start_datetime_earliest_to_state_when_should_be_synced_then_use_start_datetime_as_earliest_boundary(): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("2023-01-01", parameters={}), - cursor_field=InterpolatedString(cursor_field, parameters={}), - datetime_format="%Y-%m-%d", - config=config, - parameters={}, - ) - cursor.set_initial_state({cursor_field: "2021-01-01"}) - assert not cursor.should_be_synced(Record({cursor_field: "2022-01-01"}, ANY_SLICE)) - - -def test_given_end_datetime_before_cursor_value_when_should_be_synced_then_return_false(): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("2023-01-01", parameters={}), - end_datetime=MinMaxDatetime("2025-01-01", parameters={}), - cursor_field=InterpolatedString(cursor_field, parameters={}), - datetime_format="%Y-%m-%d", - config=config, - parameters={}, - ) - assert not cursor.should_be_synced(Record({cursor_field: "2030-01-01"}, ANY_SLICE)) - - -def test_given_record_without_cursor_value_when_should_be_synced_then_return_true(): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("3000-01-01", parameters={}), - cursor_field=InterpolatedString(cursor_field, parameters={}), - datetime_format="%Y-%m-%d", - config=config, - parameters={}, - ) - assert cursor.should_be_synced(Record({"record without cursor value": "any"}, ANY_SLICE)) - - -def test_given_first_greater_than_second_then_return_true(): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("3000-01-01", parameters={}), - cursor_field="cursor_field", - datetime_format="%Y-%m-%d", - config=config, - parameters={}, - ) - assert cursor.is_greater_than_or_equal(Record({"cursor_field": "2023-01-01"}, {}), Record({"cursor_field": "2021-01-01"}, {})) - - -def test_given_first_lesser_than_second_then_return_false(): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("3000-01-01", parameters={}), - cursor_field="cursor_field", - datetime_format="%Y-%m-%d", - config=config, - parameters={}, - ) - assert not cursor.is_greater_than_or_equal(Record({"cursor_field": "2021-01-01"}, {}), Record({"cursor_field": "2023-01-01"}, {})) - - -def test_given_no_cursor_value_for_second_than_second_then_return_true(): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("3000-01-01", parameters={}), - cursor_field="cursor_field", - datetime_format="%Y-%m-%d", - config=config, - parameters={}, - ) - assert cursor.is_greater_than_or_equal(Record({"cursor_field": "2021-01-01"}, {}), Record({}, {})) - - -def test_given_no_cursor_value_for_first_than_second_then_return_false(): - cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime("3000-01-01", parameters={}), - cursor_field="cursor_field", - datetime_format="%Y-%m-%d", - config=config, - parameters={}, - ) - assert not cursor.is_greater_than_or_equal(Record({}, {}), Record({"cursor_field": "2021-01-01"}, {})) - - -if __name__ == "__main__": - unittest.main() diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/incremental/test_per_partition_cursor.py b/airbyte-cdk/python/unit_tests/sources/declarative/incremental/test_per_partition_cursor.py deleted file mode 100644 index 823405cb5152..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/incremental/test_per_partition_cursor.py +++ /dev/null @@ -1,553 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from collections import OrderedDict -from unittest.mock import Mock - -import pytest -from airbyte_cdk.sources.declarative.incremental.declarative_cursor import DeclarativeCursor -from airbyte_cdk.sources.declarative.incremental.per_partition_cursor import PerPartitionCursor, PerPartitionKeySerializer, StreamSlice -from airbyte_cdk.sources.declarative.partition_routers.partition_router import PartitionRouter -from airbyte_cdk.sources.types import Record - -PARTITION = { - "partition_key string": "partition value", - "partition_key int": 1, - "partition_key list str": ["list item 1", "list item 2"], - "partition_key list dict": [ - {"dict within list key 1-1": "dict within list value 1-1", "dict within list key 1-2": "dict within list value 1-2"}, - {"dict within list key 2": "dict within list value 2"}, - ], - "partition_key nested dict": { - "nested_partition_key 1": "a nested value", - "nested_partition_key 2": "another nested value", - }, -} - -CURSOR_SLICE_FIELD = "cursor slice field" -CURSOR_STATE_KEY = "cursor state" -CURSOR_STATE = {CURSOR_STATE_KEY: "a state value"} -NOT_CONSIDERED_BECAUSE_MOCKED_CURSOR_HAS_NO_STATE = "any" -STATE = { - "states": [ - { - "partition": { - "partition_router_field_1": "X1", - "partition_router_field_2": "Y1", - }, - "cursor": {"cursor state field": 1}, - }, - { - "partition": { - "partition_router_field_1": "X2", - "partition_router_field_2": "Y2", - }, - "cursor": {"cursor state field": 2}, - }, - ] -} - - -def test_partition_serialization(): - serializer = PerPartitionKeySerializer() - assert serializer.to_partition(serializer.to_partition_key(PARTITION)) == PARTITION - - -def test_partition_with_different_key_orders(): - ordered_dict = OrderedDict({"1": 1, "2": 2}) - same_dict_with_different_order = OrderedDict({"2": 2, "1": 1}) - serializer = PerPartitionKeySerializer() - - assert serializer.to_partition_key(ordered_dict) == serializer.to_partition_key(same_dict_with_different_order) - - -def test_given_tuples_in_json_then_deserialization_convert_to_list(): - """ - This is a known issue with the current implementation. However, the assumption is that this wouldn't be a problem as we only use the - immutability and we expect stream slices to be immutable anyway - """ - serializer = PerPartitionKeySerializer() - partition_with_tuple = {"key": (1, 2, 3)} - - assert partition_with_tuple != serializer.to_partition(serializer.to_partition_key(partition_with_tuple)) - - -def test_stream_slice_merge_dictionaries(): - stream_slice = StreamSlice(partition={"partition key": "partition value"}, cursor_slice={"cursor key": "cursor value"}) - assert stream_slice == {"partition key": "partition value", "cursor key": "cursor value"} - - -def test_overlapping_slice_keys_raise_error(): - with pytest.raises(ValueError): - StreamSlice(partition={"overlapping key": "partition value"}, cursor_slice={"overlapping key": "cursor value"}) - - -class MockedCursorBuilder: - def __init__(self): - self._stream_slices = [] - self._stream_state = {} - - def with_stream_slices(self, stream_slices): - self._stream_slices = stream_slices - return self - - def with_stream_state(self, stream_state): - self._stream_state = stream_state - return self - - def build(self): - cursor = Mock(spec=DeclarativeCursor) - cursor.get_stream_state.return_value = self._stream_state - cursor.stream_slices.return_value = self._stream_slices - return cursor - - -@pytest.fixture() -def mocked_partition_router(): - return Mock(spec=PartitionRouter) - - -@pytest.fixture() -def mocked_cursor_factory(): - cursor_factory = Mock() - cursor_factory.create.return_value = MockedCursorBuilder().build() - return cursor_factory - - -def test_given_no_partition_when_stream_slices_then_no_slices(mocked_cursor_factory, mocked_partition_router): - mocked_partition_router.stream_slices.return_value = [] - cursor = PerPartitionCursor(mocked_cursor_factory, mocked_partition_router) - - slices = cursor.stream_slices() - - assert not next(slices, None) - - -def test_given_partition_router_without_state_has_one_partition_then_return_one_slice_per_cursor_slice( - mocked_cursor_factory, mocked_partition_router -): - partition = StreamSlice(partition={"partition_field_1": "a value", "partition_field_2": "another value"}, cursor_slice={}) - mocked_partition_router.stream_slices.return_value = [partition] - cursor_slices = [{"start_datetime": 1}, {"start_datetime": 2}] - mocked_cursor_factory.create.return_value = MockedCursorBuilder().with_stream_slices(cursor_slices).build() - cursor = PerPartitionCursor(mocked_cursor_factory, mocked_partition_router) - - slices = cursor.stream_slices() - - assert list(slices) == [StreamSlice(partition=partition, cursor_slice=cursor_slice) for cursor_slice in cursor_slices] - - -def test_given_partition_associated_with_state_when_stream_slices_then_do_not_recreate_cursor( - mocked_cursor_factory, mocked_partition_router -): - partition = StreamSlice(partition={"partition_field_1": "a value", "partition_field_2": "another value"}, cursor_slice={}) - mocked_partition_router.stream_slices.return_value = [partition] - cursor_slices = [{"start_datetime": 1}] - mocked_cursor_factory.create.return_value = MockedCursorBuilder().with_stream_slices(cursor_slices).build() - cursor = PerPartitionCursor(mocked_cursor_factory, mocked_partition_router) - - cursor.set_initial_state({"states": [{"partition": partition.partition, "cursor": CURSOR_STATE}]}) - mocked_cursor_factory.create.assert_called_once() - slices = list(cursor.stream_slices()) - - mocked_cursor_factory.create.assert_called_once() - assert len(slices) == 1 - - -def test_given_multiple_partitions_then_each_have_their_state(mocked_cursor_factory, mocked_partition_router): - first_partition = {"first_partition_key": "first_partition_value"} - mocked_partition_router.stream_slices.return_value = [ - StreamSlice(partition=first_partition, cursor_slice={}), - StreamSlice(partition={"second_partition_key": "second_partition_value"}, cursor_slice={}), - ] - first_cursor = MockedCursorBuilder().with_stream_slices([{CURSOR_SLICE_FIELD: "first slice cursor value"}]).build() - second_cursor = MockedCursorBuilder().with_stream_slices([{CURSOR_SLICE_FIELD: "second slice cursor value"}]).build() - mocked_cursor_factory.create.side_effect = [first_cursor, second_cursor] - cursor = PerPartitionCursor(mocked_cursor_factory, mocked_partition_router) - - cursor.set_initial_state({"states": [{"partition": first_partition, "cursor": CURSOR_STATE}]}) - slices = list(cursor.stream_slices()) - - first_cursor.stream_slices.assert_called_once() - second_cursor.stream_slices.assert_called_once() - assert slices == [ - StreamSlice( - partition={"first_partition_key": "first_partition_value"}, cursor_slice={CURSOR_SLICE_FIELD: "first slice cursor value"} - ), - StreamSlice( - partition={"second_partition_key": "second_partition_value"}, cursor_slice={CURSOR_SLICE_FIELD: "second slice cursor value"} - ), - ] - - -def test_given_stream_slices_when_get_stream_state_then_return_updated_state(mocked_cursor_factory, mocked_partition_router): - mocked_cursor_factory.create.side_effect = [ - MockedCursorBuilder().with_stream_state({CURSOR_STATE_KEY: "first slice cursor value"}).build(), - MockedCursorBuilder().with_stream_state({CURSOR_STATE_KEY: "second slice cursor value"}).build(), - ] - mocked_partition_router.stream_slices.return_value = [ - StreamSlice(partition={"partition key": "first partition"}, cursor_slice={}), - StreamSlice(partition={"partition key": "second partition"}, cursor_slice={}), - ] - - # Mock the get_parent_state method to return the parent state - mocked_partition_router.get_stream_state.return_value = {} - - cursor = PerPartitionCursor(mocked_cursor_factory, mocked_partition_router) - list(cursor.stream_slices()) - assert cursor.get_stream_state() == { - "states": [ - {"partition": {"partition key": "first partition"}, "cursor": {CURSOR_STATE_KEY: "first slice cursor value"}}, - {"partition": {"partition key": "second partition"}, "cursor": {CURSOR_STATE_KEY: "second slice cursor value"}}, - ] - } - - -def test_when_get_stream_state_then_delegate_to_underlying_cursor(mocked_cursor_factory, mocked_partition_router): - underlying_cursor = MockedCursorBuilder().with_stream_slices([{CURSOR_SLICE_FIELD: "first slice cursor value"}]).build() - mocked_cursor_factory.create.side_effect = [underlying_cursor] - mocked_partition_router.stream_slices.return_value = [StreamSlice(partition={"partition key": "first partition"}, cursor_slice={})] - cursor = PerPartitionCursor(mocked_cursor_factory, mocked_partition_router) - first_slice = list(cursor.stream_slices())[0] - - cursor.should_be_synced(Record({}, first_slice)) - - underlying_cursor.should_be_synced.assert_called_once_with(Record({}, first_slice.cursor_slice)) - - -def test_close_slice(mocked_cursor_factory, mocked_partition_router): - underlying_cursor = MockedCursorBuilder().with_stream_slices([{CURSOR_SLICE_FIELD: "first slice cursor value"}]).build() - mocked_cursor_factory.create.side_effect = [underlying_cursor] - stream_slice = StreamSlice(partition={"partition key": "first partition"}, cursor_slice={}) - mocked_partition_router.stream_slices.return_value = [stream_slice] - cursor = PerPartitionCursor(mocked_cursor_factory, mocked_partition_router) - list(cursor.stream_slices()) # generate internal state - - cursor.close_slice(stream_slice) - - underlying_cursor.close_slice.assert_called_once_with(stream_slice.cursor_slice) - - -def test_given_no_last_record_when_close_slice_then_do_not_raise_error(mocked_cursor_factory, mocked_partition_router): - underlying_cursor = MockedCursorBuilder().with_stream_slices([{CURSOR_SLICE_FIELD: "first slice cursor value"}]).build() - mocked_cursor_factory.create.side_effect = [underlying_cursor] - stream_slice = StreamSlice(partition={"partition key": "first partition"}, cursor_slice={}) - mocked_partition_router.stream_slices.return_value = [stream_slice] - cursor = PerPartitionCursor(mocked_cursor_factory, mocked_partition_router) - list(cursor.stream_slices()) # generate internal state - - cursor.close_slice(stream_slice) - - underlying_cursor.close_slice.assert_called_once_with(stream_slice.cursor_slice) - - -def test_given_unknown_partition_when_close_slice_then_raise_error(): - any_cursor_factory = Mock() - any_partition_router = Mock() - cursor = PerPartitionCursor(any_cursor_factory, any_partition_router) - stream_slice = StreamSlice(partition={"unknown_partition": "unknown"}, cursor_slice={}) - with pytest.raises(ValueError): - cursor.close_slice(stream_slice) - - -def test_given_unknown_partition_when_should_be_synced_then_raise_error(): - any_cursor_factory = Mock() - any_partition_router = Mock() - cursor = PerPartitionCursor(any_cursor_factory, any_partition_router) - with pytest.raises(ValueError): - cursor.should_be_synced(Record({}, StreamSlice(partition={"unknown_partition": "unknown"}, cursor_slice={}))) - - -def test_given_records_with_different_slice_when_is_greater_than_or_equal_then_raise_error(): - any_cursor_factory = Mock() - any_partition_router = Mock() - cursor = PerPartitionCursor(any_cursor_factory, any_partition_router) - with pytest.raises(ValueError): - cursor.is_greater_than_or_equal( - Record({}, StreamSlice(partition={"a slice": "value"}, cursor_slice={})), - Record({}, StreamSlice(partition={"another slice": "value"}, cursor_slice={})), - ) - - -@pytest.mark.parametrize( - "first_record_slice, second_record_slice", - [ - pytest.param(StreamSlice(partition={"a slice": "value"}, cursor_slice={}), None, id="second record does not have a slice"), - pytest.param(None, StreamSlice(partition={"a slice": "value"}, cursor_slice={}), id="first record does not have a slice"), - ], -) -def test_given_records_without_a_slice_when_is_greater_than_or_equal_then_raise_error(first_record_slice, second_record_slice): - any_cursor_factory = Mock() - any_partition_router = Mock() - cursor = PerPartitionCursor(any_cursor_factory, any_partition_router) - with pytest.raises(ValueError): - cursor.is_greater_than_or_equal(Record({}, first_record_slice), Record({}, second_record_slice)) - - -def test_given_slice_is_unknown_when_is_greater_than_or_equal_then_raise_error(): - any_cursor_factory = Mock() - any_partition_router = Mock() - cursor = PerPartitionCursor(any_cursor_factory, any_partition_router) - with pytest.raises(ValueError): - cursor.is_greater_than_or_equal( - Record({}, StreamSlice(partition={"a slice": "value"}, cursor_slice={})), - Record({}, StreamSlice(partition={"a slice": "value"}, cursor_slice={})), - ) - - -def test_when_is_greater_than_or_equal_then_return_underlying_cursor_response(mocked_cursor_factory, mocked_partition_router): - underlying_cursor = MockedCursorBuilder().with_stream_slices([{CURSOR_SLICE_FIELD: "first slice cursor value"}]).build() - mocked_cursor_factory.create.side_effect = [underlying_cursor] - stream_slice = StreamSlice(partition={"partition key": "first partition"}, cursor_slice={}) - mocked_partition_router.stream_slices.return_value = [stream_slice] - cursor = PerPartitionCursor(mocked_cursor_factory, mocked_partition_router) - first_record = Record({"first": "value"}, stream_slice) - second_record = Record({"second": "value"}, stream_slice) - list(cursor.stream_slices()) # generate internal state - - result = cursor.is_greater_than_or_equal(first_record, second_record) - - assert result == underlying_cursor.is_greater_than_or_equal.return_value - underlying_cursor.is_greater_than_or_equal.assert_called_once_with(first_record, second_record) - - -@pytest.mark.parametrize( - "stream_slice, expected_output", - [ - pytest.param( - StreamSlice(partition={"partition key": "first partition"}, cursor_slice={}), - {"cursor": "params", "router": "params"}, - id="first partition", - ), - pytest.param(None, None, id="first partition"), - ], -) -def test_get_request_params(mocked_cursor_factory, mocked_partition_router, stream_slice, expected_output): - underlying_cursor = MockedCursorBuilder().with_stream_slices([{CURSOR_SLICE_FIELD: "first slice cursor value"}]).build() - underlying_cursor.get_request_params.return_value = {"cursor": "params"} - mocked_cursor_factory.create.side_effect = [underlying_cursor] - mocked_partition_router.stream_slices.return_value = [stream_slice] - mocked_partition_router.get_request_params.return_value = {"router": "params"} - cursor = PerPartitionCursor(mocked_cursor_factory, mocked_partition_router) - if stream_slice: - cursor.set_initial_state({"states": [{"partition": stream_slice.partition, "cursor": CURSOR_STATE}]}) - params = cursor.get_request_params(stream_slice=stream_slice) - assert params == expected_output - mocked_partition_router.get_request_params.assert_called_once_with( - stream_state=None, stream_slice=stream_slice, next_page_token=None - ) - underlying_cursor.get_request_params.assert_called_once_with(stream_state=None, stream_slice={}, next_page_token=None) - else: - with pytest.raises(ValueError): - cursor.get_request_params(stream_slice=stream_slice) - - -@pytest.mark.parametrize( - "stream_slice, expected_output", - [ - pytest.param( - StreamSlice(partition={"partition key": "first partition"}, cursor_slice={}), - {"cursor": "params", "router": "params"}, - id="first partition", - ), - pytest.param(None, None, id="first partition"), - ], -) -def test_get_request_headers(mocked_cursor_factory, mocked_partition_router, stream_slice, expected_output): - underlying_cursor = MockedCursorBuilder().with_stream_slices([{CURSOR_SLICE_FIELD: "first slice cursor value"}]).build() - underlying_cursor.get_request_headers.return_value = {"cursor": "params"} - mocked_cursor_factory.create.side_effect = [underlying_cursor] - mocked_partition_router.stream_slices.return_value = [stream_slice] - mocked_partition_router.get_request_headers.return_value = {"router": "params"} - cursor = PerPartitionCursor(mocked_cursor_factory, mocked_partition_router) - if stream_slice: - cursor.set_initial_state({"states": [{"partition": stream_slice.partition, "cursor": CURSOR_STATE}]}) - params = cursor.get_request_headers(stream_slice=stream_slice) - assert params == expected_output - mocked_partition_router.get_request_headers.assert_called_once_with( - stream_state=None, stream_slice=stream_slice, next_page_token=None - ) - underlying_cursor.get_request_headers.assert_called_once_with(stream_state=None, stream_slice={}, next_page_token=None) - else: - with pytest.raises(ValueError): - cursor.get_request_headers(stream_slice=stream_slice) - - -@pytest.mark.parametrize( - "stream_slice, expected_output", - [ - pytest.param( - StreamSlice(partition={"partition key": "first partition"}, cursor_slice={}), - {"cursor": "params", "router": "params"}, - id="first partition", - ), - pytest.param(None, None, id="first partition"), - ], -) -def test_get_request_body_data(mocked_cursor_factory, mocked_partition_router, stream_slice, expected_output): - underlying_cursor = MockedCursorBuilder().with_stream_slices([{CURSOR_SLICE_FIELD: "first slice cursor value"}]).build() - underlying_cursor.get_request_body_data.return_value = {"cursor": "params"} - mocked_cursor_factory.create.side_effect = [underlying_cursor] - mocked_partition_router.stream_slices.return_value = [stream_slice] - mocked_partition_router.get_request_body_data.return_value = {"router": "params"} - cursor = PerPartitionCursor(mocked_cursor_factory, mocked_partition_router) - if stream_slice: - cursor.set_initial_state({"states": [{"partition": stream_slice.partition, "cursor": CURSOR_STATE}]}) - params = cursor.get_request_body_data(stream_slice=stream_slice) - assert params == expected_output - mocked_partition_router.get_request_body_data.assert_called_once_with( - stream_state=None, stream_slice=stream_slice, next_page_token=None - ) - underlying_cursor.get_request_body_data.assert_called_once_with(stream_state=None, stream_slice={}, next_page_token=None) - else: - with pytest.raises(ValueError): - cursor.get_request_body_data(stream_slice=stream_slice) - - -@pytest.mark.parametrize( - "stream_slice, expected_output", - [ - pytest.param( - StreamSlice(partition={"partition key": "first partition"}, cursor_slice={}), - {"cursor": "params", "router": "params"}, - id="first partition", - ), - pytest.param(None, None, id="first partition"), - ], -) -def test_get_request_body_json(mocked_cursor_factory, mocked_partition_router, stream_slice, expected_output): - underlying_cursor = MockedCursorBuilder().with_stream_slices([{CURSOR_SLICE_FIELD: "first slice cursor value"}]).build() - underlying_cursor.get_request_body_json.return_value = {"cursor": "params"} - mocked_cursor_factory.create.side_effect = [underlying_cursor] - mocked_partition_router.stream_slices.return_value = [stream_slice] - mocked_partition_router.get_request_body_json.return_value = {"router": "params"} - cursor = PerPartitionCursor(mocked_cursor_factory, mocked_partition_router) - if stream_slice: - cursor.set_initial_state({"states": [{"partition": stream_slice.partition, "cursor": CURSOR_STATE}]}) - params = cursor.get_request_body_json(stream_slice=stream_slice) - assert params == expected_output - mocked_partition_router.get_request_body_json.assert_called_once_with( - stream_state=None, stream_slice=stream_slice, next_page_token=None - ) - underlying_cursor.get_request_body_json.assert_called_once_with(stream_state=None, stream_slice={}, next_page_token=None) - else: - with pytest.raises(ValueError): - cursor.get_request_body_json(stream_slice=stream_slice) - - -def test_parent_state_is_set_for_per_partition_cursor(mocked_cursor_factory, mocked_partition_router): - # Define the parent state to be used in the test - parent_state = {"parent_cursor": "parent_state_value"} - - # Mock the partition router to return a stream slice - partition = StreamSlice(partition={"partition_field_1": "a value", "partition_field_2": "another value"}, cursor_slice={}) - mocked_partition_router.stream_slices.return_value = [partition] - - # Mock the cursor factory to create cursors with specific states - mocked_cursor_factory.create.side_effect = [ - MockedCursorBuilder() - .with_stream_slices([{CURSOR_SLICE_FIELD: "first slice cursor value"}]) - .with_stream_state(CURSOR_STATE) - .build(), - ] - - # Mock the get_parent_state method to return the parent state - mocked_partition_router.get_stream_state.return_value = parent_state - - # Initialize the PerPartitionCursor with the mocked cursor factory and partition router - cursor = PerPartitionCursor(mocked_cursor_factory, mocked_partition_router) - - # Set the initial state, including the parent state - initial_state = { - "states": [{"partition": partition.partition, "cursor": CURSOR_STATE}], - "parent_state": parent_state, - } - cursor.set_initial_state(initial_state) - - # Verify that the parent state has been set correctly - assert cursor.get_stream_state()["parent_state"] == parent_state - - # Verify that set_parent_state was called on the partition router with the initial state - mocked_partition_router.set_initial_state.assert_called_once_with(initial_state) - - -def test_get_stream_state_includes_parent_state(mocked_cursor_factory, mocked_partition_router): - # Define the parent state to be used in the test - parent_state = {"parent_cursor": "parent_state_value"} - - # Define the expected cursor states - cursor_state_1 = {CURSOR_STATE_KEY: "first slice cursor value"} - cursor_state_2 = {CURSOR_STATE_KEY: "second slice cursor value"} - - # Mock the partition router to return stream slices - partition_1 = {"partition_field_1": "a value", "partition_field_2": "another value"} - partition_2 = {"partition_field_1": "another value", "partition_field_2": "yet another value"} - mocked_partition_router.stream_slices.return_value = [ - StreamSlice(partition=partition_1, cursor_slice={}), - StreamSlice(partition=partition_2, cursor_slice={}), - ] - - # Mock the cursor factory to create cursors with specific states - mocked_cursor_factory.create.side_effect = [ - MockedCursorBuilder().with_stream_state(cursor_state_1).build(), - MockedCursorBuilder().with_stream_state(cursor_state_2).build(), - ] - - # Mock the get_parent_state method to return the parent state - mocked_partition_router.get_stream_state.return_value = parent_state - - # Initialize the PerPartitionCursor with the mocked cursor factory and partition router - cursor = PerPartitionCursor(mocked_cursor_factory, mocked_partition_router) - - # Simulate reading the records to initialize the internal state - list(cursor.stream_slices()) - - # Get the combined stream state - stream_state = cursor.get_stream_state() - - # Verify that the combined state includes both partition states and the parent state - expected_state = { - "states": [ - {"partition": partition_1, "cursor": cursor_state_1}, - {"partition": partition_2, "cursor": cursor_state_2}, - ], - "parent_state": parent_state, - } - assert stream_state == expected_state - - -def test_per_partition_state_when_set_initial_global_state(mocked_cursor_factory, mocked_partition_router) -> None: - first_partition = {"first_partition_key": "first_partition_value"} - second_partition = {"second_partition_key": "second_partition_value"} - global_state = {"global_state_format_key": "global_state_format_value"} - - mocked_partition_router.stream_slices.return_value = [ - StreamSlice(partition=first_partition, cursor_slice={}), - StreamSlice(partition=second_partition, cursor_slice={}), - ] - mocked_cursor_factory.create.side_effect = [ - MockedCursorBuilder().with_stream_state(global_state).build(), - MockedCursorBuilder().with_stream_state(global_state).build(), - ] - cursor = PerPartitionCursor(mocked_cursor_factory, mocked_partition_router) - global_state = {"global_state_format_key": "global_state_format_value"} - cursor.set_initial_state(global_state) - assert cursor._state_to_migrate_from == global_state - list(cursor.stream_slices()) - assert cursor._cursor_per_partition['{"first_partition_key":"first_partition_value"}'].set_initial_state.call_count == 1 - assert cursor._cursor_per_partition['{"first_partition_key":"first_partition_value"}'].set_initial_state.call_args[0] == ( - {"global_state_format_key": "global_state_format_value"}, - ) - assert cursor._cursor_per_partition['{"second_partition_key":"second_partition_value"}'].set_initial_state.call_count == 1 - assert cursor._cursor_per_partition['{"second_partition_key":"second_partition_value"}'].set_initial_state.call_args[0] == ( - {"global_state_format_key": "global_state_format_value"}, - ) - expected_state = [ - {"cursor": {"global_state_format_key": "global_state_format_value"}, "partition": {"first_partition_key": "first_partition_value"}}, - { - "cursor": {"global_state_format_key": "global_state_format_value"}, - "partition": {"second_partition_key": "second_partition_value"}, - }, - ] - assert cursor.get_stream_state()["states"] == expected_state diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/incremental/test_per_partition_cursor_integration.py b/airbyte-cdk/python/unit_tests/sources/declarative/incremental/test_per_partition_cursor_integration.py deleted file mode 100644 index 4fff298b99aa..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/incremental/test_per_partition_cursor_integration.py +++ /dev/null @@ -1,571 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from unittest.mock import MagicMock, patch - -from airbyte_cdk.models import ( - AirbyteStateBlob, - AirbyteStateMessage, - AirbyteStateType, - AirbyteStream, - AirbyteStreamState, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteStream, - DestinationSyncMode, - StreamDescriptor, - SyncMode, -) -from airbyte_cdk.sources.declarative.incremental.per_partition_cursor import PerPartitionCursor, StreamSlice -from airbyte_cdk.sources.declarative.manifest_declarative_source import ManifestDeclarativeSource -from airbyte_cdk.sources.declarative.retrievers.simple_retriever import SimpleRetriever -from airbyte_cdk.sources.types import Record -from orjson import orjson - -CURSOR_FIELD = "cursor_field" -SYNC_MODE = SyncMode.incremental - - -class ManifestBuilder: - def __init__(self): - self._incremental_sync = {} - self._partition_router = {} - self._substream_partition_router = {} - - def with_list_partition_router(self, stream_name, cursor_field, partitions): - self._partition_router[stream_name] = { - "type": "ListPartitionRouter", - "cursor_field": cursor_field, - "values": partitions, - } - return self - - def with_substream_partition_router(self, stream_name): - self._substream_partition_router[stream_name] = { - "type": "SubstreamPartitionRouter", - "parent_stream_configs": [ - { - "type": "ParentStreamConfig", - "stream": "#/definitions/Rates", - "parent_key": "id", - "partition_field": "parent_id", - } - ], - } - return self - - def with_incremental_sync(self, stream_name, start_datetime, end_datetime, datetime_format, cursor_field, step, cursor_granularity): - self._incremental_sync[stream_name] = { - "type": "DatetimeBasedCursor", - "start_datetime": start_datetime, - "end_datetime": end_datetime, - "datetime_format": datetime_format, - "cursor_field": cursor_field, - "step": step, - "cursor_granularity": cursor_granularity, - } - return self - - def build(self): - manifest = { - "version": "0.34.2", - "type": "DeclarativeSource", - "check": {"type": "CheckStream", "stream_names": ["Rates"]}, - "definitions": { - "AnotherStream": { - "type": "DeclarativeStream", - "name": "AnotherStream", - "primary_key": [], - "schema_loader": { - "type": "InlineSchemaLoader", - "schema": {"$schema": "http://json-schema.org/schema#", "properties": {"id": {"type": "string"}}, "type": "object"}, - }, - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "url_base": "https://api.apilayer.com", - "path": "/exchangerates_data/latest", - "http_method": "GET", - }, - "record_selector": {"type": "RecordSelector", "extractor": {"type": "DpathExtractor", "field_path": []}}, - }, - }, - "Rates": { - "type": "DeclarativeStream", - "name": "Rates", - "primary_key": [], - "schema_loader": { - "type": "InlineSchemaLoader", - "schema": {"$schema": "http://json-schema.org/schema#", "properties": {}, "type": "object"}, - }, - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "url_base": "https://api.apilayer.com", - "path": "/exchangerates_data/latest", - "http_method": "GET", - }, - "record_selector": {"type": "RecordSelector", "extractor": {"type": "DpathExtractor", "field_path": []}}, - }, - }, - }, - "streams": [{"$ref": "#/definitions/Rates"}, {"$ref": "#/definitions/AnotherStream"}], - "spec": { - "connection_specification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": [], - "properties": {}, - "additionalProperties": True, - }, - "documentation_url": "https://example.org", - "type": "Spec", - }, - } - for stream_name, incremental_sync_definition in self._incremental_sync.items(): - manifest["definitions"][stream_name]["incremental_sync"] = incremental_sync_definition - for stream_name, partition_router_definition in self._partition_router.items(): - manifest["definitions"][stream_name]["retriever"]["partition_router"] = partition_router_definition - for stream_name, partition_router_definition in self._substream_partition_router.items(): - manifest["definitions"][stream_name]["retriever"]["partition_router"] = partition_router_definition - return manifest - - -def test_given_state_for_only_some_partition_when_stream_slices_then_create_slices_using_state_or_start_from_start_datetime(): - source = ManifestDeclarativeSource( - source_config=ManifestBuilder() - .with_list_partition_router("Rates", "partition_field", ["1", "2"]) - .with_incremental_sync( - "Rates", - start_datetime="2022-01-01", - end_datetime="2022-02-28", - datetime_format="%Y-%m-%d", - cursor_field=CURSOR_FIELD, - step="P1M", - cursor_granularity="P1D", - ) - .build() - ) - stream_instance = source.streams({})[0] - stream_instance.state = { - "states": [ - { - "partition": {"partition_field": "1"}, - "cursor": {CURSOR_FIELD: "2022-02-01"}, - } - ] - } - - slices = stream_instance.stream_slices( - sync_mode=SYNC_MODE, - stream_state={}, - ) - - assert list(slices) == [ - {"partition_field": "1", "start_time": "2022-02-01", "end_time": "2022-02-28"}, - {"partition_field": "2", "start_time": "2022-01-01", "end_time": "2022-01-31"}, - {"partition_field": "2", "start_time": "2022-02-01", "end_time": "2022-02-28"}, - ] - - -def test_given_record_for_partition_when_read_then_update_state(): - source = ManifestDeclarativeSource( - source_config=ManifestBuilder() - .with_list_partition_router("Rates", "partition_field", ["1", "2"]) - .with_incremental_sync( - "Rates", - start_datetime="2022-01-01", - end_datetime="2022-02-28", - datetime_format="%Y-%m-%d", - cursor_field=CURSOR_FIELD, - step="P1M", - cursor_granularity="P1D", - ) - .build() - ) - stream_instance = source.streams({})[0] - list(stream_instance.stream_slices(sync_mode=SYNC_MODE)) - - stream_slice = StreamSlice(partition={"partition_field": "1"}, cursor_slice={"start_time": "2022-01-01", "end_time": "2022-01-31"}) - with patch.object( - SimpleRetriever, "_read_pages", side_effect=[[Record({"a record key": "a record value", CURSOR_FIELD: "2022-01-15"}, stream_slice)]] - ): - list( - stream_instance.read_records( - sync_mode=SYNC_MODE, - stream_slice=stream_slice, - stream_state={"states": []}, - cursor_field=CURSOR_FIELD, - ) - ) - - assert stream_instance.state == { - "state": {}, - "use_global_cursor": False, - "states": [ - { - "partition": {"partition_field": "1"}, - "cursor": {CURSOR_FIELD: "2022-01-15"}, - } - ], - } - - -def test_substream_without_input_state(): - test_source = ManifestDeclarativeSource( - source_config=ManifestBuilder() - .with_substream_partition_router("AnotherStream") - .with_incremental_sync( - "Rates", - start_datetime="2022-01-01", - end_datetime="2022-02-28", - datetime_format="%Y-%m-%d", - cursor_field=CURSOR_FIELD, - step="P1M", - cursor_granularity="P1D", - ) - .with_incremental_sync( - "AnotherStream", - start_datetime="2022-01-01", - end_datetime="2022-02-28", - datetime_format="%Y-%m-%d", - cursor_field=CURSOR_FIELD, - step="P1M", - cursor_granularity="P1D", - ) - .build() - ) - - stream_instance = test_source.streams({})[1] - - parent_stream_slice = StreamSlice(partition={}, cursor_slice={"start_time": "2022-01-01", "end_time": "2022-01-31"}) - - # This mocks the resulting records of the Rates stream which acts as the parent stream of the SubstreamPartitionRouter being tested - with patch.object( - SimpleRetriever, - "_read_pages", - side_effect=[ - [Record({"id": "1", CURSOR_FIELD: "2022-01-15"}, parent_stream_slice)], - [Record({"id": "2", CURSOR_FIELD: "2022-01-15"}, parent_stream_slice)], - ], - ): - slices = list(stream_instance.stream_slices(sync_mode=SYNC_MODE)) - assert list(slices) == [ - StreamSlice( - partition={ - "parent_id": "1", - "parent_slice": {}, - }, - cursor_slice={"start_time": "2022-01-01", "end_time": "2022-01-31"}, - ), - StreamSlice( - partition={ - "parent_id": "1", - "parent_slice": {}, - }, - cursor_slice={"start_time": "2022-02-01", "end_time": "2022-02-28"}, - ), - StreamSlice( - partition={ - "parent_id": "2", - "parent_slice": {}, - }, - cursor_slice={"start_time": "2022-01-01", "end_time": "2022-01-31"}, - ), - StreamSlice( - partition={ - "parent_id": "2", - "parent_slice": {}, - }, - cursor_slice={"start_time": "2022-02-01", "end_time": "2022-02-28"}, - ), - ] - - -def test_partition_limitation(caplog): - """ - Test that when the number of partitions exceeds the maximum allowed limit in PerPartitionCursor, - the oldest partitions are dropped, and the state is updated accordingly. - - In this test, we set the maximum number of partitions to 2 and provide 3 partitions. - We verify that the state only retains information for the two most recent partitions. - """ - source = ManifestDeclarativeSource( - source_config=ManifestBuilder() - .with_list_partition_router("Rates", "partition_field", ["1", "2", "3"]) - .with_incremental_sync( - "Rates", - start_datetime="2022-01-01", - end_datetime="2022-02-28", - datetime_format="%Y-%m-%d", - cursor_field=CURSOR_FIELD, - step="P1M", - cursor_granularity="P1D", - ) - .build() - ) - - partition_slices = [ - StreamSlice(partition={"partition_field": "1"}, cursor_slice={}), - StreamSlice(partition={"partition_field": "2"}, cursor_slice={}), - StreamSlice(partition={"partition_field": "3"}, cursor_slice={}), - ] - - records_list = [ - [ - Record({"a record key": "a record value", CURSOR_FIELD: "2022-01-15"}, partition_slices[0]), - Record({"a record key": "a record value", CURSOR_FIELD: "2022-01-16"}, partition_slices[0]), - ], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-02-15"}, partition_slices[0])], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-01-16"}, partition_slices[1])], - [], - [], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-02-17"}, partition_slices[2])], - ] - - configured_stream = ConfiguredAirbyteStream( - stream=AirbyteStream(name="Rates", json_schema={}, supported_sync_modes=[SyncMode.full_refresh, SyncMode.incremental]), - sync_mode=SyncMode.incremental, - destination_sync_mode=DestinationSyncMode.append, - ) - catalog = ConfiguredAirbyteCatalog(streams=[configured_stream]) - - initial_state = [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="post_comment_votes", namespace=None), - stream_state=AirbyteStateBlob( - { - "states": [ - { - "partition": {"partition_field": "1"}, - "cursor": {CURSOR_FIELD: "2022-01-01"}, - }, - { - "partition": {"partition_field": "2"}, - "cursor": {CURSOR_FIELD: "2022-01-02"}, - }, - { - "partition": {"partition_field": "3"}, - "cursor": {CURSOR_FIELD: "2022-01-03"}, - }, - ] - } - ), - ), - ) - ] - logger = MagicMock() - - # Use caplog to capture logs - with caplog.at_level(logging.WARNING, logger="airbyte"): - with patch.object(SimpleRetriever, "_read_pages", side_effect=records_list): - with patch.object(PerPartitionCursor, "DEFAULT_MAX_PARTITIONS_NUMBER", 2): - output = list(source.read(logger, {}, catalog, initial_state)) - - # Check if the warning was logged - logged_messages = [record.message for record in caplog.records if record.levelname == "WARNING"] - warning_message = ( - 'The maximum number of partitions has been reached. Dropping the oldest partition: {"partition_field":"1"}. Over limit: 1.' - ) - assert warning_message in logged_messages - - final_state = [orjson.loads(orjson.dumps(message.state.stream.stream_state)) for message in output if message.state] - assert final_state[-1] == { - "lookback_window": 1, - "state": {"cursor_field": "2022-02-17"}, - "use_global_cursor": False, - "states": [ - { - "partition": {"partition_field": "2"}, - "cursor": {CURSOR_FIELD: "2022-01-16"}, - }, - { - "partition": {"partition_field": "3"}, - "cursor": {CURSOR_FIELD: "2022-02-17"}, - }, - ], - } - - -def test_perpartition_with_fallback(caplog): - """ - Test that when the number of partitions exceeds the limit in PerPartitionCursor, - the cursor falls back to using the global cursor for state management. - - This test also checks that the appropriate warning logs are emitted when the partition limit is exceeded. - """ - source = ManifestDeclarativeSource( - source_config=ManifestBuilder() - .with_list_partition_router("Rates", "partition_field", ["1", "2", "3", "4", "5", "6"]) - .with_incremental_sync( - "Rates", - start_datetime="2022-01-01", - end_datetime="2022-02-28", - datetime_format="%Y-%m-%d", - cursor_field=CURSOR_FIELD, - step="P1M", - cursor_granularity="P1D", - ) - .build() - ) - - partition_slices = [StreamSlice(partition={"partition_field": str(i)}, cursor_slice={}) for i in range(1, 7)] - - records_list = [ - [ - Record({"a record key": "a record value", CURSOR_FIELD: "2022-01-15"}, partition_slices[0]), - Record({"a record key": "a record value", CURSOR_FIELD: "2022-01-16"}, partition_slices[0]), - ], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-02-15"}, partition_slices[0])], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-01-16"}, partition_slices[1])], - [], - [], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-02-17"}, partition_slices[2])], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-01-17"}, partition_slices[3])], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-02-19"}, partition_slices[3])], - [], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-02-18"}, partition_slices[4])], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-01-13"}, partition_slices[3])], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-02-18"}, partition_slices[3])], - ] - - configured_stream = ConfiguredAirbyteStream( - stream=AirbyteStream(name="Rates", json_schema={}, supported_sync_modes=[SyncMode.full_refresh, SyncMode.incremental]), - sync_mode=SyncMode.incremental, - destination_sync_mode=DestinationSyncMode.append, - ) - catalog = ConfiguredAirbyteCatalog(streams=[configured_stream]) - - initial_state = [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="Rates", namespace=None), - stream_state=AirbyteStateBlob( - { - "states": [ - { - "partition": {"partition_field": "1"}, - "cursor": {CURSOR_FIELD: "2022-01-01"}, - }, - { - "partition": {"partition_field": "2"}, - "cursor": {CURSOR_FIELD: "2022-01-02"}, - }, - { - "partition": {"partition_field": "3"}, - "cursor": {CURSOR_FIELD: "2022-01-03"}, - }, - ] - } - ), - ), - ) - ] - logger = MagicMock() - - # Use caplog to capture logs - with caplog.at_level(logging.WARNING, logger="airbyte"): - with patch.object(SimpleRetriever, "_read_pages", side_effect=records_list): - with patch.object(PerPartitionCursor, "DEFAULT_MAX_PARTITIONS_NUMBER", 2): - output = list(source.read(logger, {}, catalog, initial_state)) - - # Check if the warnings were logged - expected_warning_messages = [ - 'The maximum number of partitions has been reached. Dropping the oldest partition: {"partition_field":"1"}. Over limit: 1.', - 'The maximum number of partitions has been reached. Dropping the oldest partition: {"partition_field":"2"}. Over limit: 2.', - 'The maximum number of partitions has been reached. Dropping the oldest partition: {"partition_field":"3"}. Over limit: 3.', - ] - - logged_messages = [record.message for record in caplog.records if record.levelname == "WARNING"] - - for expected_message in expected_warning_messages: - assert expected_message in logged_messages - - # Proceed with existing assertions - final_state = [orjson.loads(orjson.dumps(message.state.stream.stream_state)) for message in output if message.state] - assert final_state[-1] == {"use_global_cursor": True, "state": {"cursor_field": "2022-02-19"}, "lookback_window": 1} - - -def test_per_partition_cursor_within_limit(caplog): - """ - Test that the PerPartitionCursor correctly updates the state for each partition - when the number of partitions is within the allowed limit. - - This test also checks that no warning logs are emitted when the partition limit is not exceeded. - """ - source = ManifestDeclarativeSource( - source_config=ManifestBuilder() - .with_list_partition_router("Rates", "partition_field", ["1", "2", "3"]) - .with_incremental_sync( - "Rates", - start_datetime="2022-01-01", - end_datetime="2022-03-31", - datetime_format="%Y-%m-%d", - cursor_field=CURSOR_FIELD, - step="P1M", - cursor_granularity="P1D", - ) - .build() - ) - - partition_slices = [StreamSlice(partition={"partition_field": str(i)}, cursor_slice={}) for i in range(1, 4)] - - records_list = [ - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-01-15"}, partition_slices[0])], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-02-20"}, partition_slices[0])], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-03-25"}, partition_slices[0])], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-01-16"}, partition_slices[1])], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-02-18"}, partition_slices[1])], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-03-28"}, partition_slices[1])], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-01-17"}, partition_slices[2])], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-02-19"}, partition_slices[2])], - [Record({"a record key": "a record value", CURSOR_FIELD: "2022-03-29"}, partition_slices[2])], - ] - - configured_stream = ConfiguredAirbyteStream( - stream=AirbyteStream(name="Rates", json_schema={}, supported_sync_modes=[SyncMode.full_refresh, SyncMode.incremental]), - sync_mode=SyncMode.incremental, - destination_sync_mode=DestinationSyncMode.append, - ) - catalog = ConfiguredAirbyteCatalog(streams=[configured_stream]) - - initial_state = {} - logger = MagicMock() - - # Use caplog to capture logs - with caplog.at_level(logging.WARNING, logger="airbyte"): - with patch.object(SimpleRetriever, "_read_pages", side_effect=records_list): - with patch.object(PerPartitionCursor, "DEFAULT_MAX_PARTITIONS_NUMBER", 5): - output = list(source.read(logger, {}, catalog, initial_state)) - - # Since the partition limit is not exceeded, we expect no warnings - logged_warnings = [record.message for record in caplog.records if record.levelname == "WARNING"] - assert len(logged_warnings) == 0 - - # Proceed with existing assertions - final_state = [orjson.loads(orjson.dumps(message.state.stream.stream_state)) for message in output if message.state] - assert final_state[-1] == { - "lookback_window": 1, - "state": {"cursor_field": "2022-03-29"}, - "use_global_cursor": False, - "states": [ - { - "partition": {"partition_field": "1"}, - "cursor": {CURSOR_FIELD: "2022-03-25"}, - }, - { - "partition": {"partition_field": "2"}, - "cursor": {CURSOR_FIELD: "2022-03-28"}, - }, - { - "partition": {"partition_field": "3"}, - "cursor": {CURSOR_FIELD: "2022-03-29"}, - }, - ], - } diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/incremental/test_resumable_full_refresh_cursor.py b/airbyte-cdk/python/unit_tests/sources/declarative/incremental/test_resumable_full_refresh_cursor.py deleted file mode 100644 index b45973283aad..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/incremental/test_resumable_full_refresh_cursor.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -import pytest -from airbyte_cdk.sources.declarative.incremental import ChildPartitionResumableFullRefreshCursor, ResumableFullRefreshCursor -from airbyte_cdk.sources.types import StreamSlice - - -@pytest.mark.parametrize( - "stream_state, cursor, expected_slice", - [ - pytest.param( - {"updated_at": "2024-04-30"}, - ResumableFullRefreshCursor, - StreamSlice(cursor_slice={"updated_at": "2024-04-30"}, partition={}), - id="test_set_resumable_full_refresh_incoming_stream_state", - ), - pytest.param( - {"updated_at": "2024-05-32"}, - ChildPartitionResumableFullRefreshCursor, - StreamSlice(cursor_slice={"updated_at": "2024-05-32"}, partition={}), - id="test_set_substream_resumable_full_refresh_incoming_stream_state", - ), - pytest.param( - {}, - ResumableFullRefreshCursor, - StreamSlice(cursor_slice={}, partition={}), - id="test_empty_resumable_full_refresh_stream_state", - ), - pytest.param( - {}, - ChildPartitionResumableFullRefreshCursor, - StreamSlice(cursor_slice={}, partition={}), - id="test_empty_substream_resumable_full_refresh_stream_state", - ), - ], -) -def test_stream_slices(stream_state, cursor, expected_slice): - cursor = cursor(parameters={}) - cursor.set_initial_state(stream_state=stream_state) - actual_slices = [stream_slice for stream_slice in cursor.stream_slices()] - assert actual_slices == [expected_slice] diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/__init__.py deleted file mode 100644 index 46b7376756ec..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_filters.py b/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_filters.py deleted file mode 100644 index 912abf3d2d0c..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_filters.py +++ /dev/null @@ -1,104 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import base64 -import hashlib - -import pytest -from airbyte_cdk.sources.declarative.interpolation.jinja import JinjaInterpolation - -interpolation = JinjaInterpolation() - - -def test_hash_md5_no_salt() -> None: - input_string = "abcd" - s = "{{ '%s' | hash('md5') }}" % input_string - filter_hash = interpolation.eval(s, config={}) - - # compute expected hash calling hashlib directly - hash_obj = hashlib.md5() - hash_obj.update(str(input_string).encode("utf-8")) - hashlib_computed_hash = hash_obj.hexdigest() - - assert filter_hash == hashlib_computed_hash - - -def test_hash_md5_on_numeric_value() -> None: - input_value = 123.456 - s = "{{ %f | hash('md5') }}" % input_value - filter_hash = interpolation.eval(s, config={}) - - # compute expected hash calling hashlib directly - hash_obj = hashlib.md5() - hash_obj.update(str(input_value).encode("utf-8")) - hashlib_computed_hash = hash_obj.hexdigest() - - assert filter_hash == hashlib_computed_hash - - -def test_hash_md5_with_salt() -> None: - input_string = "test_input_string" - input_salt = "test_input_salt" - - s = "{{ '%s' | hash('md5', '%s' ) }}" % (input_string, input_salt) - filter_hash = interpolation.eval(s, config={}) - - # compute expected value calling hashlib directly - hash_obj = hashlib.md5() - hash_obj.update(str(input_string + input_salt).encode("utf-8")) - hashlib_computed_hash = hash_obj.hexdigest() - - assert filter_hash == hashlib_computed_hash - - -@pytest.mark.parametrize( - "input_string", - ["test_input_client_id", "some_client_secret_1", "12345", "775.78"], -) -def test_base64encode(input_string: str) -> None: - s = "{{ '%s' | base64encode }}" % input_string - filter_base64encode = interpolation.eval(s, config={}) - - # compute expected base64encode calling base64 library directly - base64_obj = base64.b64encode(input_string.encode("utf-8")).decode() - - assert filter_base64encode == base64_obj - - -@pytest.mark.parametrize( - "input_string, expected_string", - [ - ("aW5wdXRfc3RyaW5n", "input_string"), - ("YWlyYnl0ZQ==", "airbyte"), - ("cGFzc3dvcmQ=", "password"), - ], -) -def test_base64decode(input_string: str, expected_string: str) -> None: - s = "{{ '%s' | base64decode }}" % input_string - filter_base64decode = interpolation.eval(s, config={}) - - assert filter_base64decode == expected_string - - -def test_regex_search_valid() -> None: - expression_with_regex = "{{ '; rel=\"next\"' | regex_search('<(.*)>; rel=.*') }}" - - val = interpolation.eval(expression_with_regex, {}) - assert val == "https://this-is-test-link.com/?page=2" - - -def test_regex_search_no_match_group() -> None: - # If no group is set in the regular expression, the result will be an empty string - expression_with_regex = "{{ '; rel=\"next\"' | regex_search('<.*>; rel=.*') }}" - - val = interpolation.eval(expression_with_regex, {}) - assert val is None - - -def test_regex_search_no_match() -> None: - # If no group is set in the regular expression, the result will be an empty string - expression_with_regex = "{{ '; rel=\"next\"' | regex_search('WATWATWAT') }}" - - val = interpolation.eval(expression_with_regex, {}) - - assert val is None diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_interpolated_boolean.py b/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_interpolated_boolean.py deleted file mode 100644 index 6b4ba5349247..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_interpolated_boolean.py +++ /dev/null @@ -1,40 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -from airbyte_cdk.sources.declarative.interpolation.interpolated_boolean import InterpolatedBoolean - -config = { - "parent": {"key_with_true": True}, - "string_key": "compare_me", - "zero_value": 0, - "empty_array": [], - "non_empty_array": [1], - "empty_dict": {}, - "empty_tuple": (), -} - - -@pytest.mark.parametrize( - "test_name, template, expected_result", - [ - ("test_interpolated_true_value", "{{ config['parent']['key_with_true'] }}", True), - ("test_interpolated_true_comparison", "{{ config['string_key'] == \"compare_me\" }}", True), - ("test_interpolated_false_condition", "{{ config['string_key'] == \"witness_me\" }}", False), - ("test_path_has_value_returns_true", "{{ config['string_key'] }}", True), - ("test_zero_is_false", "{{ config['zero_value'] }}", False), - ("test_empty_array_is_false", "{{ config['empty_array'] }}", False), - ("test_empty_dict_is_false", "{{ config['empty_dict'] }}", False), - ("test_empty_tuple_is_false", "{{ config['empty_tuple'] }}", False), - ("test_lowercase_false", '{{ "false" }}', False), - ("test_False", "{{ False }}", False), - ("test_True", "{{ True }}", True), - ("test_value_in_array", "{{ 1 in config['non_empty_array'] }}", True), - ("test_value_not_in_array", "{{ 2 in config['non_empty_array'] }}", False), - ("test_interpolation_using_parameters", "{{ parameters['from_parameters'] == \"come_find_me\" }}", True), - ], -) -def test_interpolated_boolean(test_name, template, expected_result): - interpolated_bool = InterpolatedBoolean(condition=template, parameters={"from_parameters": "come_find_me"}) - assert interpolated_bool.eval(config) == expected_result diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_interpolated_mapping.py b/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_interpolated_mapping.py deleted file mode 100644 index f4c77c3cec4d..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_interpolated_mapping.py +++ /dev/null @@ -1,35 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -from airbyte_cdk.sources.declarative.interpolation.interpolated_mapping import InterpolatedMapping - - -@pytest.mark.parametrize( - "test_name, key, expected_value", - [ - ("test_field_value", "field", "value"), - ("test_number", "number", 100), - ("test_field_to_interpolate_from_config", "field_to_interpolate_from_config", "VALUE_FROM_CONFIG"), - ("test_field_to_interpolate_from_kwargs", "field_to_interpolate_from_kwargs", "VALUE_FROM_KWARGS"), - ("test_field_to_interpolate_from_parameters", "field_to_interpolate_from_parameters", "VALUE_FROM_PARAMETERS"), - ("test_key_is_interpolated", "key", "VALUE"), - ], -) -def test(test_name, key, expected_value): - d = { - "field": "value", - "number": 100, - "field_to_interpolate_from_config": "{{ config['c'] }}", - "field_to_interpolate_from_kwargs": "{{ kwargs['a'] }}", - "field_to_interpolate_from_parameters": "{{ parameters['b'] }}", - "{{ parameters.k }}": "VALUE", - } - config = {"c": "VALUE_FROM_CONFIG"} - kwargs = {"a": "VALUE_FROM_KWARGS"} - mapping = InterpolatedMapping(mapping=d, parameters={"b": "VALUE_FROM_PARAMETERS", "k": "key"}) - - interpolated = mapping.eval(config, **{"kwargs": kwargs}) - - assert interpolated[key] == expected_value diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_interpolated_nested_mapping.py b/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_interpolated_nested_mapping.py deleted file mode 100644 index c1dea1d62fb2..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_interpolated_nested_mapping.py +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import dpath -import pytest -from airbyte_cdk.sources.declarative.interpolation.interpolated_nested_mapping import InterpolatedNestedMapping - - -@pytest.mark.parametrize( - "test_name, path, expected_value", - [ - ("test_field_value", "nested/field", "value"), - ("test_number", "nested/number", 100), - ("test_interpolated_number", "nested/nested_array/1/value", 5), - ("test_interpolated_boolean", "nested/nested_array/2/value", True), - ("test_field_to_interpolate_from_config", "nested/config_value", "VALUE_FROM_CONFIG"), - ("test_field_to_interpolate_from_kwargs", "nested/kwargs_value", "VALUE_FROM_KWARGS"), - ("test_field_to_interpolate_from_parameters", "nested/parameters_value", "VALUE_FROM_PARAMETERS"), - ("test_key_is_interpolated", "nested/nested_array/0/key", "VALUE"), - ], -) -def test(test_name, path, expected_value): - d = { - "nested": { - "field": "value", - "number": 100, - "nested_array": [ - {"{{ parameters.k }}": "VALUE"}, - {"value": "{{ config['num_value'] | int + 2 }}"}, - {"value": "{{ True }}"}, - ], - "config_value": "{{ config['c'] }}", - "parameters_value": "{{ parameters['b'] }}", - "kwargs_value": "{{ kwargs['a'] }}", - } - } - - config = {"c": "VALUE_FROM_CONFIG", "num_value": 3} - kwargs = {"a": "VALUE_FROM_KWARGS"} - mapping = InterpolatedNestedMapping(mapping=d, parameters={"b": "VALUE_FROM_PARAMETERS", "k": "key"}) - - interpolated = mapping.eval(config, **{"kwargs": kwargs}) - - assert dpath.get(interpolated, path) == expected_value diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_interpolated_string.py b/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_interpolated_string.py deleted file mode 100644 index f0f1a9952506..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_interpolated_string.py +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString - -config = {"field": "value"} -parameters = {"hello": "world"} -kwargs = {"c": "airbyte"} - - -@pytest.mark.parametrize( - "test_name, input_string, expected_value", - [ - ("test_static_value", "HELLO WORLD", "HELLO WORLD"), - ("test_eval_from_parameters", "{{ parameters['hello'] }}", "world"), - ("test_eval_from_config", "{{ config['field'] }}", "value"), - ("test_eval_from_kwargs", "{{ kwargs['c'] }}", "airbyte"), - ("test_eval_from_kwargs", "{{ kwargs['c'] }}", "airbyte"), - ], -) -def test_interpolated_string(test_name, input_string, expected_value): - s = InterpolatedString.create(input_string, parameters=parameters) - assert s.eval(config, **{"kwargs": kwargs}) == expected_value diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_jinja.py b/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_jinja.py deleted file mode 100644 index fd791345b699..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_jinja.py +++ /dev/null @@ -1,291 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import datetime - -import pytest -from airbyte_cdk import StreamSlice -from airbyte_cdk.sources.declarative.interpolation.jinja import JinjaInterpolation -from freezegun import freeze_time -from jinja2.exceptions import TemplateSyntaxError - -interpolation = JinjaInterpolation() - - -def test_get_value_from_config(): - s = "{{ config['date'] }}" - config = {"date": "2022-01-01"} - val = interpolation.eval(s, config) - assert val == "2022-01-01" - - -def test_get_missing_value_from_config(): - s = "{{ config['date'] }}" - config = {} - val = interpolation.eval(s, config) - assert val is None - - -@pytest.mark.parametrize( - "valid_types, expected_value", - [ - pytest.param((str,), "1234J", id="test_value_is_a_string_if_valid_types_is_str"), - pytest.param(None, 1234j, id="test_value_is_interpreted_as_complex_number_by_default"), - ], -) -def test_get_value_with_complex_number(valid_types, expected_value): - s = "{{ config['value'] }}" - config = {"value": "1234J"} - val = interpolation.eval(s, config, valid_types=valid_types) - assert val == expected_value - - -def test_get_value_from_stream_slice(): - s = "{{ stream_slice['date'] }}" - config = {"date": "2022-01-01"} - stream_slice = {"date": "2020-09-09"} - val = interpolation.eval(s, config, **{"stream_slice": stream_slice}) - assert val == "2020-09-09" - - -def test_get_missing_value_from_stream_slice(): - s = "{{ stream_slice['date'] }}" - config = {"date": "2022-01-01"} - stream_slice = {} - val = interpolation.eval(s, config, **{"stream_slice": stream_slice}) - assert val is None - - -def test_get_value_from_a_list_of_mappings(): - s = "{{ records[0]['date'] }}" - config = {"date": "2022-01-01"} - records = [{"date": "2020-09-09"}] - val = interpolation.eval(s, config, **{"records": records}) - assert val == "2020-09-09" - - -@pytest.mark.parametrize( - "s, value", - [ - pytest.param("{{1}}", 1, id="test_number"), - pytest.param("{{1}}", 1, id="test_number"), - pytest.param("{{[1,2]}}", [1, 2], id="test_list"), - pytest.param("{{ {1:2} }}", {1: 2}, id="test_dict"), - pytest.param("{{ 1+2 }}", 3, id="test_addition"), - ], -) -def test_literals(s, value): - val = interpolation.eval(s, None) - assert val == value - - -@pytest.mark.parametrize( - "context, input_string, expected_value", - [ - pytest.param( - {"stream_slice": {"stream_slice_key": "hello"}}, - "{{ stream_slice['stream_slice_key'] }}", - "hello", - id="test_get_value_from_stream_slice", - ), - pytest.param( - {"stream_slice": {"stream_slice_key": "hello"}}, - "{{ stream_partition['stream_slice_key'] }}", - "hello", - id="test_get_value_from_stream_slicer", - ), - pytest.param( - {"stream_slice": {"stream_slice_key": "hello"}}, - "{{ stream_interval['stream_slice_key'] }}", - "hello", - id="test_get_value_from_stream_interval", - ), - ], -) -def test_stream_slice_alias(context, input_string, expected_value): - config = {} - val = interpolation.eval(input_string, config, **context) - assert val == expected_value - - -@pytest.mark.parametrize( - "alias", - [ - pytest.param("stream_interval", id="test_error_is_raised_if_stream_interval_in_context"), - pytest.param("stream_partition", id="test_error_is_raised_if_stream_partition_in_context"), - ], -) -def test_error_is_raised_if_alias_is_already_in_context(alias): - config = {} - context = {alias: "a_value"} - with pytest.raises(ValueError): - interpolation.eval("a_key", config, **context) - - -def test_positive_day_delta(): - delta_template = "{{ day_delta(25) }}" - interpolation = JinjaInterpolation() - val = interpolation.eval(delta_template, {}) - - # We need to assert against an earlier delta since the interpolation function runs datetime.now() a few milliseconds earlier - assert val > (datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=24, hours=23)).strftime("%Y-%m-%dT%H:%M:%S.%f%z") - - -def test_positive_day_delta_with_format(): - delta_template = "{{ day_delta(25,format='%Y-%m-%d') }}" - - with freeze_time("2021-01-01 03:04:05"): - val = interpolation.eval(delta_template, {}) - assert val == "2021-01-26" - - -def test_negative_day_delta(): - delta_template = "{{ day_delta(-25) }}" - val = interpolation.eval(delta_template, {}) - - assert val <= (datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=25)).strftime("%Y-%m-%dT%H:%M:%S.%f%z") - - -@pytest.mark.parametrize( - "test_name, input_value, expected_output", - [ - ("test_string_to_string", "hello world", "hello world"), - ("test_int_to_string", 1, "1"), - ("test_number_to_string", 1.52, "1.52"), - ("test_true_to_string", True, "true"), - ("test_false_to_string", False, "false"), - ("test_array_to_string", ["hello", "world"], '["hello", "world"]'), - ("test_object_to_array", {"hello": "world"}, '{"hello": "world"}'), - ], -) -def test_to_string(test_name, input_value, expected_output): - interpolation = JinjaInterpolation() - config = {"key": input_value} - template = "{{ config['key'] | string }}" - actual_output = interpolation.eval(template, config, {}) - assert isinstance(actual_output, str) - assert actual_output == expected_output - - -@pytest.mark.parametrize( - "s, expected_value", - [ - pytest.param("{{ timestamp(1621439283) }}", 1621439283, id="test_timestamp_from_timestamp"), - pytest.param("{{ timestamp('2021-05-19') }}", 1621382400, id="test_timestamp_from_string"), - pytest.param("{{ timestamp('2017-01-01T00:00:00.0Z') }}", 1483228800, id="test_timestamp_from_rfc3339"), - pytest.param("{{ max(1,2) }}", 2, id="test_max"), - ], -) -def test_macros(s, expected_value): - config = {} - val = interpolation.eval(s, config) - assert val == expected_value - - -@pytest.mark.parametrize( - "template_string", - [ - pytest.param("{{ import os) }}", id="test_jinja_with_import"), - pytest.param("{{ [a for a in range(1000000000)] }}", id="test_jinja_with_list_comprehension"), - ], -) -def test_invalid_jinja_statements(template_string): - config = {"key": "value"} - with pytest.raises(TemplateSyntaxError): - interpolation.eval(template_string, config=config) - - -@pytest.mark.parametrize( - "template_string", - [ - # This test stalls if range is removed from JinjaInterpolation.RESTRICTED_BUILTIN_FUNCTIONS - pytest.param( - """ - {% set a = 1 %} - {% set b = 1 %} - {% for i in range(1000000000) %} - {% endfor %} - {{ a }}""", - id="test_jinja_with_very_long_running_compute", - ), - pytest.param("{{ eval ('2+2') }}", id="test_jinja_with_eval"), - pytest.param("{{ getattr(config, 'key') }}", id="test_getattr"), - pytest.param("{{ setattr(config, 'password', 'hunter2') }}", id="test_setattr"), - pytest.param("{{ globals() }}", id="test_jinja_with_globals"), - pytest.param("{{ locals() }}", id="test_jinja_with_globals"), - pytest.param("{{ eval ('2+2') }}", id="test_jinja_with_eval"), - pytest.param("{{ eval }}", id="test_jinja_with_eval"), - ], -) -def test_restricted_builtin_functions_are_not_executed(template_string): - config = {"key": JinjaInterpolation} - with pytest.raises(ValueError): - interpolation.eval(template_string, config=config) - - -@pytest.mark.parametrize( - "template_string, expected_value, expected_error", - [ - pytest.param("{{ to_be }}", "that_is_the_question", None, id="valid_template_variable"), - pytest.param("{{ missingno }}", None, ValueError, id="undeclared_template_variable"), - pytest.param("{{ to_be and or_not_to_be }}", None, ValueError, id="one_undeclared_template_variable"), - ], -) -def test_undeclared_variables(template_string, expected_error, expected_value): - config = {"key": JinjaInterpolation} - - if expected_error: - with pytest.raises(expected_error): - interpolation.eval(template_string, config=config, **{"to_be": "that_is_the_question"}) - else: - actual_value = interpolation.eval(template_string, config=config, **{"to_be": "that_is_the_question"}) - assert actual_value == expected_value - - -@freeze_time("2021-09-01") -@pytest.mark.parametrize( - "template_string, expected_value", - [ - pytest.param("{{ now_utc() }}", "2021-09-01 00:00:00+00:00", id="test_now_utc"), - pytest.param("{{ now_utc().strftime('%Y-%m-%d') }}", "2021-09-01", id="test_now_utc_strftime"), - pytest.param("{{ today_utc() }}", "2021-09-01", id="test_today_utc"), - pytest.param("{{ today_utc().strftime('%Y/%m/%d') }}", "2021/09/01", id="test_todat_utc_stftime"), - pytest.param("{{ timestamp(1646006400) }}", 1646006400, id="test_timestamp_from_timestamp"), - pytest.param("{{ timestamp('2022-02-28') }}", 1646006400, id="test_timestamp_from_timestamp"), - pytest.param("{{ timestamp('2022-02-28T00:00:00Z') }}", 1646006400, id="test_timestamp_from_timestamp"), - pytest.param("{{ timestamp('2022-02-28 00:00:00Z') }}", 1646006400, id="test_timestamp_from_timestamp"), - pytest.param("{{ timestamp('2022-02-28T00:00:00-08:00') }}", 1646035200, id="test_timestamp_from_date_with_tz"), - pytest.param("{{ max(2, 3) }}", 3, id="test_max_with_arguments"), - pytest.param("{{ max([2, 3]) }}", 3, id="test_max_with_list"), - pytest.param("{{ day_delta(1) }}", "2021-09-02T00:00:00.000000+0000", id="test_day_delta"), - pytest.param("{{ day_delta(-1) }}", "2021-08-31T00:00:00.000000+0000", id="test_day_delta_negative"), - pytest.param("{{ day_delta(1, format='%Y-%m-%d') }}", "2021-09-02", id="test_day_delta_with_format"), - pytest.param("{{ duration('P1D') }}", "1 day, 0:00:00", id="test_duration_one_day"), - pytest.param("{{ duration('P6DT23H') }}", "6 days, 23:00:00", id="test_duration_six_days_and_23_hours"), - pytest.param( - "{{ (now_utc() - duration('P1D')).strftime('%Y-%m-%dT%H:%M:%SZ') }}", - "2021-08-31T00:00:00Z", - id="test_now_utc_with_duration_and_format", - ), - pytest.param("{{ 1 | string }}", "1", id="test_int_to_string"), - pytest.param('{{ ["hello", "world"] | string }}', '["hello", "world"]', id="test_array_to_string"), - ], -) -def test_macros_examples(template_string, expected_value): - # The outputs of this test are referenced in declarative_component_schema.yaml - # If you change the expected output, you must also change the expected output in declarative_component_schema.yaml - now_utc = interpolation.eval(template_string, {}) - assert now_utc == expected_value - - -def test_interpolation_private_partition_attribute(): - inner_partition = StreamSlice(partition={}, cursor_slice={}) - expected_output = "value" - setattr(inner_partition, "parent_stream_fields", expected_output) - stream_slice = StreamSlice(partition=inner_partition, cursor_slice={}) - template = "{{ stream_slice._partition.parent_stream_fields }}" - - actual_output = JinjaInterpolation().eval(template, {}, **{"stream_slice": stream_slice}) - - assert actual_output == expected_output diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_macros.py b/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_macros.py deleted file mode 100644 index d2a2a291ec1a..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/interpolation/test_macros.py +++ /dev/null @@ -1,81 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import datetime - -import pytest -from airbyte_cdk.sources.declarative.interpolation.macros import macros - - -@pytest.mark.parametrize( - "test_name, fn_name, found_in_macros", - [ - ("test_now_utc", "now_utc", True), - ("test_today_utc", "today_utc", True), - ("test_max", "max", True), - ("test_day_delta", "day_delta", True), - ("test_format_datetime", "format_datetime", True), - ("test_duration", "duration", True), - ("test_not_a_macro", "thisisnotavalidmacro", False), - ], -) -def test_macros_export(test_name, fn_name, found_in_macros): - if found_in_macros: - assert fn_name in macros - else: - assert fn_name not in macros - - -@pytest.mark.parametrize( - "test_name, input_value, format, input_format, expected_output", - [ - ("test_datetime_string_to_date", "2022-01-01T01:01:01Z", "%Y-%m-%d", None, "2022-01-01"), - ("test_date_string_to_date", "2022-01-01", "%Y-%m-%d", None, "2022-01-01"), - ("test_datetime_string_to_date", "2022-01-01T00:00:00Z", "%Y-%m-%d", None, "2022-01-01"), - ("test_datetime_with_tz_string_to_date", "2022-01-01T00:00:00Z", "%Y-%m-%d", None, "2022-01-01"), - ("test_datetime_string_to_datetime", "2022-01-01T01:01:01Z", "%Y-%m-%dT%H:%M:%SZ", None, "2022-01-01T01:01:01Z"), - ("test_datetime_string_with_tz_to_datetime", "2022-01-01T01:01:01-0800", "%Y-%m-%dT%H:%M:%SZ", None, "2022-01-01T09:01:01Z"), - ("test_datetime_object_tz_to_date", datetime.datetime(2022, 1, 1, 1, 1, 1), "%Y-%m-%d", None, "2022-01-01"), - ("test_datetime_object_tz_to_datetime", datetime.datetime(2022, 1, 1, 1, 1, 1), "%Y-%m-%dT%H:%M:%SZ", None, "2022-01-01T01:01:01Z"), - ("test_datetime_string_to_rfc2822_date", "Sat, 01 Jan 2022 01:01:01 +0000", "%Y-%m-%d", "%a, %d %b %Y %H:%M:%S %z", "2022-01-01"), - ], -) -def test_format_datetime(test_name, input_value, format, input_format, expected_output): - format_datetime = macros["format_datetime"] - assert format_datetime(input_value, format, input_format) == expected_output - - -@pytest.mark.parametrize( - "test_name, input_value, expected_output", - [("test_one_day", "P1D", datetime.timedelta(days=1)), ("test_6_days_23_hours", "P6DT23H", datetime.timedelta(days=6, hours=23))], -) -def test_duration(test_name, input_value, expected_output): - duration_fn = macros["duration"] - assert duration_fn(input_value) == expected_output - - -@pytest.mark.parametrize( - "test_name, input_value, expected_output", - [ - ("test_int_input", 1646006400, 1646006400), - ("test_float_input", 100.0, 100), - ("test_float_input_is_floored", 100.9, 100), - ("test_string_date_iso8601", "2022-02-28", 1646006400), - ("test_string_datetime_midnight_iso8601", "2022-02-28T00:00:00Z", 1646006400), - ("test_string_datetime_midnight_iso8601_with_tz", "2022-02-28T00:00:00-08:00", 1646035200), - ("test_string_datetime_midnight_iso8601_no_t", "2022-02-28 00:00:00Z", 1646006400), - ("test_string_datetime_iso8601", "2022-02-28T10:11:12", 1646043072), - ], -) -def test_timestamp(test_name, input_value, expected_output): - timestamp_function = macros["timestamp"] - actual_output = timestamp_function(input_value) - assert actual_output == expected_output - - -def test_utc_datetime_to_local_timestamp_conversion(): - """ - This test ensures correct timezone handling independent of the timezone of the system on which the sync is running. - """ - assert macros["format_datetime"](dt="2020-10-01T00:00:00Z", format="%s") == "1601510400" diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/migrations/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/migrations/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/migrations/test_legacy_to_per_partition_migration.py b/airbyte-cdk/python/unit_tests/sources/declarative/migrations/test_legacy_to_per_partition_migration.py deleted file mode 100644 index 97e5efd69f97..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/migrations/test_legacy_to_per_partition_migration.py +++ /dev/null @@ -1,277 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from unittest.mock import MagicMock - -import pytest -from airbyte_cdk.sources.declarative.migrations.legacy_to_per_partition_state_migration import LegacyToPerPartitionStateMigration -from airbyte_cdk.sources.declarative.models import CustomPartitionRouter, CustomRetriever, DatetimeBasedCursor, DeclarativeStream -from airbyte_cdk.sources.declarative.models import LegacyToPerPartitionStateMigration as LegacyToPerPartitionStateMigrationModel -from airbyte_cdk.sources.declarative.models import ParentStreamConfig, SimpleRetriever, SubstreamPartitionRouter -from airbyte_cdk.sources.declarative.parsers.manifest_component_transformer import ManifestComponentTransformer -from airbyte_cdk.sources.declarative.parsers.manifest_reference_resolver import ManifestReferenceResolver -from airbyte_cdk.sources.declarative.parsers.model_to_component_factory import ModelToComponentFactory -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource - -factory = ModelToComponentFactory() - -resolver = ManifestReferenceResolver() - -transformer = ManifestComponentTransformer() - - -def test_migrate_a_valid_legacy_state_to_per_partition(): - input_state = { - "13506132": {"last_changed": "2022-12-27T08:34:39+00:00"}, - "14351124": {"last_changed": "2022-12-27T08:35:39+00:00"}, - } - - migrator = _migrator() - - assert migrator.should_migrate(input_state) - - expected_state = { - "states": [ - {"partition": {"parent_id": "13506132"}, "cursor": {"last_changed": "2022-12-27T08:34:39+00:00"}}, - {"partition": {"parent_id": "14351124"}, "cursor": {"last_changed": "2022-12-27T08:35:39+00:00"}}, - ] - } - - assert migrator.migrate(input_state) == expected_state - - -@pytest.mark.parametrize( - "input_state", - [ - pytest.param( - { - "states": [ - {"partition": {"id": "13506132"}, "cursor": {"last_changed": "2022-12-27T08:34:39+00:00"}}, - {"partition": {"id": "14351124"}, "cursor": {"last_changed": "2022-12-27T08:35:39+00:00"}}, - ] - }, - id="test_should_not_migrate_a_per_partition_state", - ), - pytest.param( - { - "states": [ - {"partition": {"id": "13506132"}, "cursor": {"last_changed": "2022-12-27T08:34:39+00:00"}}, - { - "partition": {"id": "14351124"}, - }, - ] - }, - id="test_should_not_migrate_state_without_a_cursor_component", - ), - pytest.param( - { - "states": [ - {"partition": {"id": "13506132"}, "cursor": {"updated_at": "2022-12-27T08:34:39+00:00"}}, - {"partition": {"id": "14351124"}, "cursor": {"updated_at": "2022-12-27T08:35:39+00:00"}}, - ] - }, - id="test_should_not_migrate_a_per_partition_state_with_wrong_cursor_field", - ), - pytest.param( - { - "states": [ - {"partition": {"id": "13506132"}, "cursor": {"last_changed": "2022-12-27T08:34:39+00:00"}}, - {"partition": {"id": "14351124"}, "cursor": {"last_changed": "2022-12-27T08:35:39+00:00", "updated_at": "2021-01-01"}}, - ] - }, - id="test_should_not_migrate_a_per_partition_state_with_multiple_cursor_fields", - ), - pytest.param( - { - "states": [ - {"partition": {"id": "13506132"}, "cursor": {"last_changed": "2022-12-27T08:34:39+00:00"}}, - {"cursor": {"last_changed": "2022-12-27T08:34:39+00:00"}}, - ] - }, - id="test_should_not_migrate_state_without_a_partition_component", - ), - pytest.param( - { - "states": [ - {"partition": {"id": "13506132", "another_id": "A"}, "cursor": {"last_changed": "2022-12-27T08:34:39+00:00"}}, - {"partition": {"id": "13506134"}, "cursor": {"last_changed": "2022-12-27T08:34:39+00:00"}}, - ] - }, - id="test_should_not_migrate_state_if_multiple_partition_keys", - ), - pytest.param( - { - "states": [ - {"partition": {"identifier": "13506132"}, "cursor": {"last_changed": "2022-12-27T08:34:39+00:00"}}, - {"partition": {"id": "13506134"}, "cursor": {"last_changed": "2022-12-27T08:34:39+00:00"}}, - ] - }, - id="test_should_not_migrate_state_if_invalid_partition_key", - ), - pytest.param( - { - "13506132": {"last_changed": "2022-12-27T08:34:39+00:00"}, - "14351124": {"last_changed": "2022-12-27T08:35:39+00:00", "another_key": "2022-12-27T08:35:39+00:00"}, - }, - id="test_should_not_migrate_if_the_partitioned_state_has_more_than_one_key", - ), - pytest.param( - { - "13506132": {"last_changed": "2022-12-27T08:34:39+00:00"}, - "14351124": {"another_key": "2022-12-27T08:35:39+00:00"}, - }, - id="test_should_not_migrate_if_the_partitioned_state_key_is_not_the_cursor_field", - ), - ], -) -def test_should_not_migrate(input_state): - migrator = _migrator() - assert not migrator.should_migrate(input_state) - - -def test_should_not_migrate_stream_with_multiple_parent_streams(): - input_state = { - "13506132": {"last_changed": "2022-12-27T08:34:39+00:00"}, - "14351124": {"last_changed": "2022-12-27T08:35:39+00:00"}, - } - - migrator = _migrator_with_multiple_parent_streams() - - assert not migrator.should_migrate(input_state) - - -def _migrator(): - partition_router = SubstreamPartitionRouter( - type="SubstreamPartitionRouter", - parent_stream_configs=[ - ParentStreamConfig( - type="ParentStreamConfig", - parent_key="{{ parameters['parent_key_id'] }}", - partition_field="parent_id", - stream=DeclarativeStream( - type="DeclarativeStream", retriever=CustomRetriever(type="CustomRetriever", class_name="a_class_name") - ), - ) - ], - ) - cursor = DatetimeBasedCursor( - type="DatetimeBasedCursor", - cursor_field="{{ parameters['cursor_field'] }}", - datetime_format="%Y-%m-%dT%H:%M:%S.%fZ", - start_datetime="1970-01-01T00:00:00.0Z", - ) - config = {} - parameters = {"cursor_field": "last_changed", "parent_key_id": "id"} - return LegacyToPerPartitionStateMigration(partition_router, cursor, config, parameters) - - -def _migrator_with_multiple_parent_streams(): - partition_router = SubstreamPartitionRouter( - type="SubstreamPartitionRouter", - parent_stream_configs=[ - ParentStreamConfig( - type="ParentStreamConfig", - parent_key="id", - partition_field="parent_id", - stream=DeclarativeStream( - type="DeclarativeStream", retriever=CustomRetriever(type="CustomRetriever", class_name="a_class_name") - ), - ), - ParentStreamConfig( - type="ParentStreamConfig", - parent_key="id", - partition_field="parent_id", - stream=DeclarativeStream( - type="DeclarativeStream", retriever=CustomRetriever(type="CustomRetriever", class_name="a_class_name") - ), - ), - ], - ) - cursor = DatetimeBasedCursor( - type="DatetimeBasedCursor", - cursor_field="{{ parameters['cursor_field'] }}", - datetime_format="%Y-%m-%dT%H:%M:%S.%fZ", - start_datetime="1970-01-01T00:00:00.0Z", - ) - config = {} - parameters = {} - return LegacyToPerPartitionStateMigration(partition_router, cursor, config, parameters) - - -@pytest.mark.parametrize( - "retriever_type, partition_router_class, is_parent_stream_config, expected_exception, expected_error_message", - [ - (SimpleRetriever, CustomPartitionRouter, True, None, None), - ( - None, - CustomPartitionRouter, - True, - ValueError, - "LegacyToPerPartitionStateMigrations can only be applied on a DeclarativeStream with a SimpleRetriever. Got ", - ), - ( - SimpleRetriever, - None, - False, - ValueError, - "LegacyToPerPartitionStateMigrations can only be applied on a SimpleRetriever with a Substream partition router. Got ", - ), - ( - SimpleRetriever, - CustomPartitionRouter, - False, - ValueError, - "LegacyToPerPartitionStateMigrations can only be applied with a parent stream configuration.", - ), - ], -) -def test_create_legacy_to_per_partition_state_migration( - retriever_type, - partition_router_class, - is_parent_stream_config, - expected_exception, - expected_error_message, -): - partition_router = partition_router_class(type="CustomPartitionRouter", class_name="a_class_namer") if partition_router_class else None - - stream = MagicMock() - stream.retriever = MagicMock(spec=retriever_type) - stream.retriever.partition_router = partition_router - - content = """ - state_migrations: - - type: LegacyToPerPartitionStateMigration - """ - - resolved_manifest = resolver.preprocess_manifest(YamlDeclarativeSource._parse(content)) - state_migrations_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["state_migrations"][0], {}) - - if is_parent_stream_config: - parent_stream_config = ParentStreamConfig( - type="ParentStreamConfig", - parent_key="id", - partition_field="parent_id", - stream=DeclarativeStream( - type="DeclarativeStream", retriever=CustomRetriever(type="CustomRetriever", class_name="a_class_name") - ), - ) - partition_router.parent_stream_configs = [parent_stream_config] - - if expected_exception: - with pytest.raises(expected_exception) as excinfo: - factory.create_component( - model_type=LegacyToPerPartitionStateMigrationModel, - component_definition=state_migrations_manifest, - config={}, - declarative_stream=stream, - ) - assert str(excinfo.value) == expected_error_message - else: - migration_instance = factory.create_component( - model_type=LegacyToPerPartitionStateMigrationModel, - component_definition=state_migrations_manifest, - config={}, - declarative_stream=stream, - ) - assert migration_instance is not None diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/parsers/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/parsers/__init__.py deleted file mode 100644 index 46b7376756ec..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/parsers/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/parsers/test_manifest_component_transformer.py b/airbyte-cdk/python/unit_tests/sources/declarative/parsers/test_manifest_component_transformer.py deleted file mode 100644 index 63efac6688d5..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/parsers/test_manifest_component_transformer.py +++ /dev/null @@ -1,406 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -from airbyte_cdk.sources.declarative.parsers.manifest_component_transformer import ManifestComponentTransformer - - -@pytest.mark.parametrize( - "component, expected_component", - [ - pytest.param( - {"type": "DeclarativeSource", "streams": [{"type": "DeclarativeStream", "retriever": {}, "schema_loader": {}}]}, - { - "type": "DeclarativeSource", - "streams": [ - { - "type": "DeclarativeStream", - "retriever": {"type": "SimpleRetriever"}, - "schema_loader": {"type": "JsonFileSchemaLoader"}, - } - ], - }, - id="test_declarative_stream", - ), - pytest.param( - { - "type": "DeclarativeStream", - "retriever": {"type": "SimpleRetriever", "paginator": {}, "record_selector": {}, "requester": {}}, - }, - { - "type": "DeclarativeStream", - "retriever": { - "type": "SimpleRetriever", - "paginator": {"type": "NoPagination"}, - "record_selector": {"type": "RecordSelector"}, - "requester": {"type": "HttpRequester"}, - }, - }, - id="test_simple_retriever", - ), - pytest.param( - {"type": "DeclarativeStream", "requester": {"type": "HttpRequester", "error_handler": {}}}, - { - "type": "DeclarativeStream", - "requester": { - "type": "HttpRequester", - "error_handler": {"type": "DefaultErrorHandler"}, - }, - }, - id="test_http_requester", - ), - pytest.param( - {"type": "SimpleRetriever", "paginator": {"type": "DefaultPaginator", "page_size_option": {}, "page_token_option": {}}}, - { - "type": "SimpleRetriever", - "paginator": { - "type": "DefaultPaginator", - "page_size_option": {"type": "RequestOption"}, - "page_token_option": {}, - }, - }, - id="test_default_paginator", - ), - pytest.param( - {"type": "SimpleRetriever", "partition_router": {"type": "SubstreamPartitionRouter", "parent_stream_configs": [{}, {}, {}]}}, - { - "type": "SimpleRetriever", - "partition_router": { - "type": "SubstreamPartitionRouter", - "parent_stream_configs": [ - {"type": "ParentStreamConfig"}, - {"type": "ParentStreamConfig"}, - {"type": "ParentStreamConfig"}, - ], - }, - }, - id="test_substream_slicer", - ), - ], -) -def test_find_default_types(component, expected_component): - transformer = ManifestComponentTransformer() - actual_component = transformer.propagate_types_and_parameters("", component, {}) - - assert actual_component == expected_component - - -@pytest.mark.parametrize( - "component, expected_component", - [ - pytest.param( - { - "type": "SimpleRetriever", - "requester": {"type": "HttpRequester", "authenticator": {"class_name": "source_greenhouse.components.NewAuthenticator"}}, - }, - { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "authenticator": {"type": "CustomAuthenticator", "class_name": "source_greenhouse.components.NewAuthenticator"}, - }, - }, - id="test_custom_authenticator", - ), - pytest.param( - { - "type": "SimpleRetriever", - "record_selector": { - "type": "RecordSelector", - "extractor": {"class_name": "source_greenhouse.components.NewRecordExtractor"}, - }, - }, - { - "type": "SimpleRetriever", - "record_selector": { - "type": "RecordSelector", - "extractor": {"type": "CustomRecordExtractor", "class_name": "source_greenhouse.components.NewRecordExtractor"}, - }, - }, - id="test_custom_extractor", - ), - ], -) -def test_transform_custom_components(component, expected_component): - transformer = ManifestComponentTransformer() - actual_component = transformer.propagate_types_and_parameters("", component, {}) - - assert actual_component == expected_component - - -def test_propagate_parameters_to_all_components(): - component = { - "type": "DeclarativeSource", - "streams": [ - { - "type": "DeclarativeStream", - "$parameters": {"name": "roasters", "primary_key": "id"}, - "retriever": { - "type": "SimpleRetriever", - "record_selector": {"type": "RecordSelector", "extractor": {"type": "DpathExtractor", "field_path": []}}, - "requester": { - "type": "HttpRequester", - "name": '{{ parameters["name"] }}', - "url_base": "https://coffee.example.io/v1/", - "http_method": "GET", - }, - }, - } - ], - } - - expected_component = { - "type": "DeclarativeSource", - "streams": [ - { - "type": "DeclarativeStream", - "retriever": { - "type": "SimpleRetriever", - "name": "roasters", - "primary_key": "id", - "record_selector": { - "type": "RecordSelector", - "extractor": { - "type": "DpathExtractor", - "field_path": [], - "name": "roasters", - "primary_key": "id", - "$parameters": {"name": "roasters", "primary_key": "id"}, - }, - "name": "roasters", - "primary_key": "id", - "$parameters": {"name": "roasters", "primary_key": "id"}, - }, - "requester": { - "type": "HttpRequester", - "name": '{{ parameters["name"] }}', - "url_base": "https://coffee.example.io/v1/", - "http_method": "GET", - "primary_key": "id", - "$parameters": {"name": "roasters", "primary_key": "id"}, - }, - "$parameters": {"name": "roasters", "primary_key": "id"}, - }, - "name": "roasters", - "primary_key": "id", - "$parameters": {"name": "roasters", "primary_key": "id"}, - } - ], - } - - transformer = ManifestComponentTransformer() - actual_component = transformer.propagate_types_and_parameters("", component, {}) - - assert actual_component == expected_component - - -def test_component_parameters_take_precedence_over_parent_parameters(): - component = { - "type": "DeclarativeStream", - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "name": "high_priority", - "url_base": "https://coffee.example.io/v1/", - "http_method": "GET", - "primary_key": "id", - "$parameters": { - "name": "high_priority", - }, - }, - "$parameters": { - "name": "low_priority", - }, - }, - } - - expected_component = { - "type": "DeclarativeStream", - "retriever": { - "type": "SimpleRetriever", - "name": "low_priority", - "requester": { - "type": "HttpRequester", - "name": "high_priority", - "url_base": "https://coffee.example.io/v1/", - "http_method": "GET", - "primary_key": "id", - "$parameters": { - "name": "high_priority", - }, - }, - "$parameters": { - "name": "low_priority", - }, - }, - } - - transformer = ManifestComponentTransformer() - actual_component = transformer.propagate_types_and_parameters("", component, {}) - - assert actual_component == expected_component - - -def test_do_not_propagate_parameters_that_have_the_same_field_name(): - component = { - "type": "DeclarativeStream", - "streams": [ - { - "type": "DeclarativeStream", - "$parameters": { - "name": "roasters", - "primary_key": "id", - "schema_loader": {"type": "JsonFileSchemaLoader", "file_path": './source_coffee/schemas/{{ parameters["name"] }}.json'}, - }, - } - ], - } - - expected_component = { - "type": "DeclarativeStream", - "streams": [ - { - "type": "DeclarativeStream", - "name": "roasters", - "primary_key": "id", - "schema_loader": { - "type": "JsonFileSchemaLoader", - "file_path": './source_coffee/schemas/{{ parameters["name"] }}.json', - "name": "roasters", - "primary_key": "id", - "$parameters": { - "name": "roasters", - "primary_key": "id", - }, - }, - "$parameters": { - "name": "roasters", - "primary_key": "id", - "schema_loader": {"type": "JsonFileSchemaLoader", "file_path": './source_coffee/schemas/{{ parameters["name"] }}.json'}, - }, - } - ], - } - - transformer = ManifestComponentTransformer() - actual_component = transformer.propagate_types_and_parameters("", component, {}) - - assert actual_component == expected_component - - -def test_ignore_empty_parameters(): - component = { - "type": "DeclarativeStream", - "retriever": { - "type": "SimpleRetriever", - "record_selector": {"type": "RecordSelector", "extractor": {"type": "DpathExtractor", "field_path": []}}, - }, - } - - transformer = ManifestComponentTransformer() - actual_component = transformer.propagate_types_and_parameters("", component, {}) - - assert actual_component == component - - -def test_only_propagate_parameters_to_components(): - component = { - "type": "ParentComponent", - "component_with_object_properties": { - "type": "TestComponent", - "subcomponent": { - "type": "TestSubComponent", - "some_field": "high_priority", - "$parameters": { - "some_option": "already", - }, - }, - "dictionary_field": {"details": "should_not_contain_parameters", "other": "no_parameters_as_fields"}, - "$parameters": { - "included": "not!", - }, - }, - } - - expected_component = { - "type": "ParentComponent", - "component_with_object_properties": { - "type": "TestComponent", - "subcomponent": { - "type": "TestSubComponent", - "some_field": "high_priority", - "some_option": "already", - "included": "not!", - "$parameters": {"some_option": "already", "included": "not!"}, - }, - "dictionary_field": {"details": "should_not_contain_parameters", "other": "no_parameters_as_fields"}, - "included": "not!", - "$parameters": { - "included": "not!", - }, - }, - } - - transformer = ManifestComponentTransformer() - actual_component = transformer.propagate_types_and_parameters("", component, {}) - - assert actual_component == expected_component - - -def test_do_not_propagate_parameters_on_json_schema_object(): - component = { - "type": "DeclarativeStream", - "streams": [ - { - "type": "DeclarativeStream", - "schema_loader": { - "type": "InlineSchemaLoader", - "schema": { - "type": "object", - "$schema": "http://json-schema.org/schema#", - "properties": {"id": {"type": "string"}}, - }, - }, - "$parameters": { - "name": "roasters", - "primary_key": "id", - }, - } - ], - } - - expected_component = { - "type": "DeclarativeStream", - "streams": [ - { - "type": "DeclarativeStream", - "name": "roasters", - "primary_key": "id", - "schema_loader": { - "type": "InlineSchemaLoader", - "name": "roasters", - "primary_key": "id", - "schema": { - "type": "object", - "$schema": "http://json-schema.org/schema#", - "properties": {"id": {"type": "string"}}, - }, - "$parameters": { - "name": "roasters", - "primary_key": "id", - }, - }, - "$parameters": { - "name": "roasters", - "primary_key": "id", - }, - } - ], - } - - transformer = ManifestComponentTransformer() - actual_component = transformer.propagate_types_and_parameters("", component, {}) - - assert actual_component == expected_component diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/parsers/test_manifest_reference_resolver.py b/airbyte-cdk/python/unit_tests/sources/declarative/parsers/test_manifest_reference_resolver.py deleted file mode 100644 index 75ee51c8c4d2..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/parsers/test_manifest_reference_resolver.py +++ /dev/null @@ -1,139 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -from airbyte_cdk.sources.declarative.parsers.custom_exceptions import CircularReferenceException, UndefinedReferenceException -from airbyte_cdk.sources.declarative.parsers.manifest_reference_resolver import ManifestReferenceResolver, _parse_path - -resolver = ManifestReferenceResolver() - - -# @ -def test_refer(): - content = {"limit": 50, "limit_ref": "#/limit"} - config = resolver.preprocess_manifest(content) - assert config["limit_ref"] == 50 - - -def test_refer_to_inner(): - content = {"dict": {"limit": 50}, "limit_ref": "#/dict/limit"} - config = resolver.preprocess_manifest(content) - assert config["limit_ref"] == 50 - - -def test_refer_to_non_existant_struct(): - content = {"dict": {"limit": 50}, "limit_ref": "#/not_dict"} - with pytest.raises(UndefinedReferenceException): - resolver.preprocess_manifest(content) - - -def test_refer_in_dict(): - content = {"limit": 50, "offset_request_parameters": {"offset": "{{ next_page_token['offset'] }}", "limit": "#/limit"}} - config = resolver.preprocess_manifest(content) - assert config["offset_request_parameters"]["offset"] == "{{ next_page_token['offset'] }}" - assert config["offset_request_parameters"]["limit"] == 50 - - -def test_refer_to_dict(): - content = { - "limit": 50, - "offset_request_parameters": {"offset": "{{ next_page_token['offset'] }}", "limit": "#/limit"}, - "offset_pagination_request_parameters": { - "class": "InterpolatedRequestParameterProvider", - "request_parameters": "#/offset_request_parameters", - }, - } - config = resolver.preprocess_manifest(content) - assert config["limit"] == 50 - assert config["offset_request_parameters"]["limit"] == 50 - assert len(config["offset_pagination_request_parameters"]) == 2 - assert config["offset_pagination_request_parameters"]["request_parameters"]["limit"] == 50 - assert config["offset_pagination_request_parameters"]["request_parameters"]["offset"] == "{{ next_page_token['offset'] }}" - - -def test_refer_and_overwrite(): - content = { - "limit": 50, - "custom_limit": 25, - "offset_request_parameters": {"offset": "{{ next_page_token['offset'] }}", "limit": "#/limit"}, - "custom_request_parameters": {"$ref": "#/offset_request_parameters", "limit": "#/custom_limit"}, - } - config = resolver.preprocess_manifest(content) - assert config["offset_request_parameters"]["limit"] == 50 - assert config["custom_request_parameters"]["limit"] == 25 - - assert config["offset_request_parameters"]["offset"] == "{{ next_page_token['offset'] }}" - assert config["custom_request_parameters"]["offset"] == "{{ next_page_token['offset'] }}" - - -def test_collision(): - content = { - "example": { - "nested": {"path": "first one", "more_nested": {"value": "found it!"}}, - "nested/path": "uh oh", - }, - "reference_to_nested_path": {"$ref": "#/example/nested/path"}, - "reference_to_nested_nested_value": {"$ref": "#/example/nested/more_nested/value"}, - } - config = resolver.preprocess_manifest(content) - assert config["example"]["nested"]["path"] == "first one" - assert config["example"]["nested/path"] == "uh oh" - assert config["reference_to_nested_path"] == "uh oh" - assert config["example"]["nested"]["more_nested"]["value"] == "found it!" - assert config["reference_to_nested_nested_value"] == "found it!" - - -def test_internal_collision(): - content = { - "example": { - "nested": {"path": {"internal": "uh oh"}, "path/internal": "found it!"}, - }, - "reference": {"$ref": "#/example/nested/path/internal"}, - } - config = resolver.preprocess_manifest(content) - assert config["example"]["nested"]["path"]["internal"] == "uh oh" - assert config["example"]["nested"]["path/internal"] == "found it!" - assert config["reference"] == "found it!" - - -def test_parse_path(): - assert _parse_path("foo/bar") == ("foo", "bar") - assert _parse_path("foo/7/8/bar") == ("foo", "7/8/bar") - assert _parse_path("7/8/bar") == (7, "8/bar") - assert _parse_path("8/bar") == (8, "bar") - assert _parse_path("8foo/bar") == ("8foo", "bar") - - -def test_list(): - content = {"list": ["A", "B"], "elem_ref": "#/list/0"} - config = resolver.preprocess_manifest(content) - elem_ref = config["elem_ref"] - assert elem_ref == "A" - - -def test_nested_list(): - content = {"list": [["A"], ["B"]], "elem_ref": "#/list/1/0"} - config = resolver.preprocess_manifest(content) - elem_ref = config["elem_ref"] - assert elem_ref == "B" - - -def test_list_of_dicts(): - content = {"list": [{"A": "a"}, {"B": "b"}], "elem_ref": "#/list/1/B"} - config = resolver.preprocess_manifest(content) - elem_ref = config["elem_ref"] - assert elem_ref == "b" - - -def test_multiple_levels_of_indexing(): - content = {"list": [{"A": ["a1", "a2"]}, {"B": ["b1", "b2"]}], "elem_ref": "#/list/1/B/0"} - config = resolver.preprocess_manifest(content) - elem_ref = config["elem_ref"] - assert elem_ref == "b1" - - -def test_circular_reference(): - content = {"elem_ref1": "#/elem_ref2", "elem_ref2": "#/elem_ref1"} - with pytest.raises(CircularReferenceException): - resolver.preprocess_manifest(content) diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/parsers/test_model_to_component_factory.py b/airbyte-cdk/python/unit_tests/sources/declarative/parsers/test_model_to_component_factory.py deleted file mode 100644 index 9b3789050287..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/parsers/test_model_to_component_factory.py +++ /dev/null @@ -1,2551 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -# mypy: ignore-errors -import datetime -from typing import Any, Mapping - -import freezegun -import pytest -from airbyte_cdk import AirbyteTracedException -from airbyte_cdk.models import FailureType, Level -from airbyte_cdk.sources.declarative.auth import DeclarativeOauth2Authenticator, JwtAuthenticator -from airbyte_cdk.sources.declarative.auth.token import ( - ApiKeyAuthenticator, - BasicHttpAuthenticator, - BearerAuthenticator, - LegacySessionTokenAuthenticator, -) -from airbyte_cdk.sources.declarative.auth.token_provider import SessionTokenProvider -from airbyte_cdk.sources.declarative.checks import CheckStream -from airbyte_cdk.sources.declarative.concurrency_level import ConcurrencyLevel -from airbyte_cdk.sources.declarative.datetime import MinMaxDatetime -from airbyte_cdk.sources.declarative.declarative_stream import DeclarativeStream -from airbyte_cdk.sources.declarative.decoders import JsonDecoder, PaginationDecoderDecorator -from airbyte_cdk.sources.declarative.extractors import DpathExtractor, RecordFilter, RecordSelector -from airbyte_cdk.sources.declarative.extractors.record_filter import ClientSideIncrementalRecordFilterDecorator -from airbyte_cdk.sources.declarative.incremental import ( - CursorFactory, - DatetimeBasedCursor, - PerPartitionCursor, - PerPartitionWithGlobalCursor, - ResumableFullRefreshCursor, -) -from airbyte_cdk.sources.declarative.interpolation import InterpolatedString -from airbyte_cdk.sources.declarative.models import CheckStream as CheckStreamModel -from airbyte_cdk.sources.declarative.models import CompositeErrorHandler as CompositeErrorHandlerModel -from airbyte_cdk.sources.declarative.models import ConcurrencyLevel as ConcurrencyLevelModel -from airbyte_cdk.sources.declarative.models import CustomErrorHandler as CustomErrorHandlerModel -from airbyte_cdk.sources.declarative.models import CustomPartitionRouter as CustomPartitionRouterModel -from airbyte_cdk.sources.declarative.models import CustomSchemaLoader as CustomSchemaLoaderModel -from airbyte_cdk.sources.declarative.models import DatetimeBasedCursor as DatetimeBasedCursorModel -from airbyte_cdk.sources.declarative.models import DeclarativeStream as DeclarativeStreamModel -from airbyte_cdk.sources.declarative.models import DefaultPaginator as DefaultPaginatorModel -from airbyte_cdk.sources.declarative.models import HttpRequester as HttpRequesterModel -from airbyte_cdk.sources.declarative.models import JwtAuthenticator as JwtAuthenticatorModel -from airbyte_cdk.sources.declarative.models import ListPartitionRouter as ListPartitionRouterModel -from airbyte_cdk.sources.declarative.models import OAuthAuthenticator as OAuthAuthenticatorModel -from airbyte_cdk.sources.declarative.models import RecordSelector as RecordSelectorModel -from airbyte_cdk.sources.declarative.models import SimpleRetriever as SimpleRetrieverModel -from airbyte_cdk.sources.declarative.models import Spec as SpecModel -from airbyte_cdk.sources.declarative.models import SubstreamPartitionRouter as SubstreamPartitionRouterModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import OffsetIncrement as OffsetIncrementModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import PageIncrement as PageIncrementModel -from airbyte_cdk.sources.declarative.models.declarative_component_schema import SelectiveAuthenticator -from airbyte_cdk.sources.declarative.parsers.manifest_component_transformer import ManifestComponentTransformer -from airbyte_cdk.sources.declarative.parsers.manifest_reference_resolver import ManifestReferenceResolver -from airbyte_cdk.sources.declarative.parsers.model_to_component_factory import ModelToComponentFactory -from airbyte_cdk.sources.declarative.partition_routers import ( - CartesianProductStreamSlicer, - ListPartitionRouter, - SinglePartitionRouter, - SubstreamPartitionRouter, -) -from airbyte_cdk.sources.declarative.requesters import HttpRequester -from airbyte_cdk.sources.declarative.requesters.error_handlers import CompositeErrorHandler, DefaultErrorHandler, HttpResponseFilter -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies import ( - ConstantBackoffStrategy, - ExponentialBackoffStrategy, - WaitTimeFromHeaderBackoffStrategy, - WaitUntilTimeFromHeaderBackoffStrategy, -) -from airbyte_cdk.sources.declarative.requesters.paginators import DefaultPaginator -from airbyte_cdk.sources.declarative.requesters.paginators.strategies import ( - CursorPaginationStrategy, - OffsetIncrement, - PageIncrement, - StopConditionPaginationStrategyDecorator, -) -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType -from airbyte_cdk.sources.declarative.requesters.request_options import ( - DatetimeBasedRequestOptionsProvider, - DefaultRequestOptionsProvider, - InterpolatedRequestOptionsProvider, -) -from airbyte_cdk.sources.declarative.requesters.request_path import RequestPath -from airbyte_cdk.sources.declarative.requesters.requester import HttpMethod -from airbyte_cdk.sources.declarative.retrievers import SimpleRetriever, SimpleRetrieverTestReadDecorator -from airbyte_cdk.sources.declarative.schema import JsonFileSchemaLoader -from airbyte_cdk.sources.declarative.schema.schema_loader import SchemaLoader -from airbyte_cdk.sources.declarative.spec import Spec -from airbyte_cdk.sources.declarative.transformations import AddFields, RemoveFields -from airbyte_cdk.sources.declarative.transformations.add_fields import AddedFieldDefinition -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ResponseAction -from airbyte_cdk.sources.streams.http.requests_native_auth.oauth import SingleUseRefreshTokenOauth2Authenticator -from unit_tests.sources.declarative.parsers.testing_components import TestingCustomSubstreamPartitionRouter, TestingSomeComponent - -factory = ModelToComponentFactory() - -resolver = ManifestReferenceResolver() - -transformer = ManifestComponentTransformer() - -input_config = {"apikey": "verysecrettoken", "repos": ["airbyte", "airbyte-cloud"]} - - -def test_create_check_stream(): - manifest = {"check": {"type": "CheckStream", "stream_names": ["list_stream"]}} - - check = factory.create_component(CheckStreamModel, manifest["check"], {}) - - assert isinstance(check, CheckStream) - assert check.stream_names == ["list_stream"] - - -def test_create_component_type_mismatch(): - manifest = {"check": {"type": "MismatchType", "stream_names": ["list_stream"]}} - - with pytest.raises(ValueError): - factory.create_component(CheckStreamModel, manifest["check"], {}) - - -def test_full_config_stream(): - content = """ -decoder: - type: JsonDecoder -extractor: - type: DpathExtractor -selector: - type: RecordSelector - record_filter: - type: RecordFilter - condition: "{{ record['id'] > stream_state['id'] }}" -metadata_paginator: - type: DefaultPaginator - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: page_size - page_token_option: - type: RequestPath - pagination_strategy: - type: "CursorPagination" - cursor_value: "{{ response._metadata.next }}" - page_size: 10 -requester: - type: HttpRequester - url_base: "https://api.sendgrid.com/v3/" - http_method: "GET" - authenticator: - type: BearerAuthenticator - api_token: "{{ config['apikey'] }}" - request_parameters: - unit: "day" -retriever: - paginator: - type: NoPagination - decoder: - $ref: "#/decoder" -partial_stream: - type: DeclarativeStream - schema_loader: - type: JsonFileSchemaLoader - file_path: "./source_sendgrid/schemas/{{ parameters.name }}.json" -list_stream: - $ref: "#/partial_stream" - $parameters: - name: "lists" - extractor: - $ref: "#/extractor" - field_path: ["{{ parameters['name'] }}"] - name: "lists" - primary_key: "id" - retriever: - $ref: "#/retriever" - requester: - $ref: "#/requester" - path: "{{ next_page_token['next_page_url'] }}" - paginator: - $ref: "#/metadata_paginator" - record_selector: - $ref: "#/selector" - transformations: - - type: AddFields - fields: - - path: ["extra"] - value: "{{ response.to_add }}" - incremental_sync: - type: DatetimeBasedCursor - start_datetime: "{{ config['start_time'] }}" - end_datetime: "{{ config['end_time'] }}" - step: "P10D" - cursor_field: "created" - cursor_granularity: "PT0.000001S" - start_time_option: - type: RequestOption - inject_into: request_parameter - field_name: after - end_time_option: - type: RequestOption - inject_into: request_parameter - field_name: before - $parameters: - datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" -check: - type: CheckStream - stream_names: ["list_stream"] -concurrency_level: - type: ConcurrencyLevel - default_concurrency: "{{ config['num_workers'] or 10 }}" - max_concurrency: 25 -spec: - type: Spec - documentation_url: https://airbyte.com/#yaml-from-manifest - connection_specification: - title: Test Spec - type: object - required: - - api_key - additionalProperties: false - properties: - api_key: - type: string - airbyte_secret: true - title: API Key - description: Test API Key - order: 0 - advanced_auth: - auth_flow_type: "oauth2.0" - """ - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - resolved_manifest["type"] = "DeclarativeSource" - manifest = transformer.propagate_types_and_parameters("", resolved_manifest, {}) - - stream_manifest = manifest["list_stream"] - assert stream_manifest["type"] == "DeclarativeStream" - stream = factory.create_component(model_type=DeclarativeStreamModel, component_definition=stream_manifest, config=input_config) - - assert isinstance(stream, DeclarativeStream) - assert stream.primary_key == "id" - assert stream.name == "lists" - assert stream._stream_cursor_field.string == "created" - - assert isinstance(stream.schema_loader, JsonFileSchemaLoader) - assert stream.schema_loader._get_json_filepath() == "./source_sendgrid/schemas/lists.json" - - assert len(stream.retriever.record_selector.transformations) == 1 - add_fields = stream.retriever.record_selector.transformations[0] - assert isinstance(add_fields, AddFields) - assert add_fields.fields[0].path == ["extra"] - assert add_fields.fields[0].value.string == "{{ response.to_add }}" - - assert isinstance(stream.retriever, SimpleRetriever) - assert stream.retriever.primary_key == stream.primary_key - assert stream.retriever.name == stream.name - - assert isinstance(stream.retriever.record_selector, RecordSelector) - - assert isinstance(stream.retriever.record_selector.extractor, DpathExtractor) - assert isinstance(stream.retriever.record_selector.extractor.decoder, JsonDecoder) - assert [fp.eval(input_config) for fp in stream.retriever.record_selector.extractor._field_path] == ["lists"] - - assert isinstance(stream.retriever.record_selector.record_filter, RecordFilter) - assert stream.retriever.record_selector.record_filter._filter_interpolator.condition == "{{ record['id'] > stream_state['id'] }}" - - assert isinstance(stream.retriever.paginator, DefaultPaginator) - assert isinstance(stream.retriever.paginator.decoder, PaginationDecoderDecorator) - assert stream.retriever.paginator.page_size_option.field_name.eval(input_config) == "page_size" - assert stream.retriever.paginator.page_size_option.inject_into == RequestOptionType.request_parameter - assert isinstance(stream.retriever.paginator.page_token_option, RequestPath) - assert stream.retriever.paginator.url_base.string == "https://api.sendgrid.com/v3/" - assert stream.retriever.paginator.url_base.default == "https://api.sendgrid.com/v3/" - - assert isinstance(stream.retriever.paginator.pagination_strategy, CursorPaginationStrategy) - assert isinstance(stream.retriever.paginator.pagination_strategy.decoder, PaginationDecoderDecorator) - assert stream.retriever.paginator.pagination_strategy._cursor_value.string == "{{ response._metadata.next }}" - assert stream.retriever.paginator.pagination_strategy._cursor_value.default == "{{ response._metadata.next }}" - assert stream.retriever.paginator.pagination_strategy.page_size == 10 - - assert isinstance(stream.retriever.requester, HttpRequester) - assert stream.retriever.requester.http_method == HttpMethod.GET - assert stream.retriever.requester.name == stream.name - assert stream.retriever.requester._path.string == "{{ next_page_token['next_page_url'] }}" - assert stream.retriever.requester._path.default == "{{ next_page_token['next_page_url'] }}" - - assert isinstance(stream.retriever.request_option_provider, DatetimeBasedRequestOptionsProvider) - assert stream.retriever.request_option_provider.start_time_option.inject_into == RequestOptionType.request_parameter - assert stream.retriever.request_option_provider.start_time_option.field_name.eval(config=input_config) == "after" - assert stream.retriever.request_option_provider.end_time_option.inject_into == RequestOptionType.request_parameter - assert stream.retriever.request_option_provider.end_time_option.field_name.eval(config=input_config) == "before" - assert stream.retriever.request_option_provider._partition_field_start.string == "start_time" - assert stream.retriever.request_option_provider._partition_field_end.string == "end_time" - - assert isinstance(stream.retriever.requester.authenticator, BearerAuthenticator) - assert stream.retriever.requester.authenticator.token_provider.get_token() == "verysecrettoken" - - assert isinstance(stream.retriever.requester.request_options_provider, InterpolatedRequestOptionsProvider) - assert stream.retriever.requester.request_options_provider.request_parameters.get("unit") == "day" - - checker = factory.create_component(model_type=CheckStreamModel, component_definition=manifest["check"], config=input_config) - - assert isinstance(checker, CheckStream) - streams_to_check = checker.stream_names - assert len(streams_to_check) == 1 - assert list(streams_to_check)[0] == "list_stream" - - spec = factory.create_component(model_type=SpecModel, component_definition=manifest["spec"], config=input_config) - - assert isinstance(spec, Spec) - documentation_url = spec.documentation_url - connection_specification = spec.connection_specification - assert documentation_url == "https://airbyte.com/#yaml-from-manifest" - assert connection_specification["title"] == "Test Spec" - assert connection_specification["required"] == ["api_key"] - assert connection_specification["properties"]["api_key"] == { - "type": "string", - "airbyte_secret": True, - "title": "API Key", - "description": "Test API Key", - "order": 0, - } - advanced_auth = spec.advanced_auth - assert advanced_auth.auth_flow_type.value == "oauth2.0" - - concurrency_level = factory.create_component( - model_type=ConcurrencyLevelModel, component_definition=manifest["concurrency_level"], config=input_config - ) - assert isinstance(concurrency_level, ConcurrencyLevel) - assert isinstance(concurrency_level._default_concurrency, InterpolatedString) - assert concurrency_level._default_concurrency.string == "{{ config['num_workers'] or 10 }}" - assert concurrency_level.max_concurrency == 25 - - -def test_interpolate_config(): - content = """ - authenticator: - type: OAuthAuthenticator - client_id: "some_client_id" - client_secret: "some_client_secret" - token_refresh_endpoint: "https://api.sendgrid.com/v3/auth" - refresh_token: "{{ config['apikey'] }}" - refresh_request_body: - body_field: "yoyoyo" - interpolated_body_field: "{{ config['apikey'] }}" - """ - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - authenticator_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["authenticator"], {}) - - authenticator = factory.create_component( - model_type=OAuthAuthenticatorModel, component_definition=authenticator_manifest, config=input_config - ) - - assert isinstance(authenticator, DeclarativeOauth2Authenticator) - assert authenticator._client_id.eval(input_config) == "some_client_id" - assert authenticator._client_secret.string == "some_client_secret" - assert authenticator._token_refresh_endpoint.eval(input_config) == "https://api.sendgrid.com/v3/auth" - assert authenticator._refresh_token.eval(input_config) == "verysecrettoken" - assert authenticator._refresh_request_body.mapping == {"body_field": "yoyoyo", "interpolated_body_field": "{{ config['apikey'] }}"} - assert authenticator.get_refresh_request_body() == {"body_field": "yoyoyo", "interpolated_body_field": "verysecrettoken"} - - -def test_interpolate_config_with_token_expiry_date_format(): - content = """ - authenticator: - type: OAuthAuthenticator - client_id: "some_client_id" - client_secret: "some_client_secret" - token_refresh_endpoint: "https://api.sendgrid.com/v3/auth" - refresh_token: "{{ config['apikey'] }}" - token_expiry_date_format: "%Y-%m-%d %H:%M:%S.%f+00:00" - """ - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - authenticator_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["authenticator"], {}) - - authenticator = factory.create_component( - model_type=OAuthAuthenticatorModel, component_definition=authenticator_manifest, config=input_config - ) - - assert isinstance(authenticator, DeclarativeOauth2Authenticator) - assert authenticator.token_expiry_date_format == "%Y-%m-%d %H:%M:%S.%f+00:00" - assert authenticator.token_expiry_is_time_of_expiration - assert authenticator._client_id.eval(input_config) == "some_client_id" - assert authenticator._client_secret.string == "some_client_secret" - assert authenticator._token_refresh_endpoint.eval(input_config) == "https://api.sendgrid.com/v3/auth" - - -def test_single_use_oauth_branch(): - single_use_input_config = { - "apikey": "verysecrettoken", - "repos": ["airbyte", "airbyte-cloud"], - "credentials": {"access_token": "access_token", "token_expiry_date": "1970-01-01"}, - } - - content = """ - authenticator: - type: OAuthAuthenticator - client_id: "some_client_id" - client_secret: "some_client_secret" - token_refresh_endpoint: "https://api.sendgrid.com/v3/auth" - refresh_token: "{{ config['apikey'] }}" - refresh_request_body: - body_field: "yoyoyo" - interpolated_body_field: "{{ config['apikey'] }}" - refresh_token_updater: - refresh_token_name: "the_refresh_token" - refresh_token_error_status_codes: [400] - refresh_token_error_key: "error" - refresh_token_error_values: ["invalid_grant"] - refresh_token_config_path: - - apikey - """ - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - authenticator_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["authenticator"], {}) - - authenticator: SingleUseRefreshTokenOauth2Authenticator = factory.create_component( - model_type=OAuthAuthenticatorModel, component_definition=authenticator_manifest, config=single_use_input_config - ) - - assert isinstance(authenticator, SingleUseRefreshTokenOauth2Authenticator) - assert authenticator._client_id == "some_client_id" - assert authenticator._client_secret == "some_client_secret" - assert authenticator._token_refresh_endpoint == "https://api.sendgrid.com/v3/auth" - assert authenticator._refresh_token == "verysecrettoken" - assert authenticator._refresh_request_body == {"body_field": "yoyoyo", "interpolated_body_field": "verysecrettoken"} - assert authenticator._refresh_token_name == "the_refresh_token" - assert authenticator._refresh_token_config_path == ["apikey"] - # default values - assert authenticator._access_token_config_path == ["credentials", "access_token"] - assert authenticator._token_expiry_date_config_path == ["credentials", "token_expiry_date"] - assert authenticator._refresh_token_error_status_codes == [400] - assert authenticator._refresh_token_error_key == "error" - assert authenticator._refresh_token_error_values == ["invalid_grant"] - - -def test_list_based_stream_slicer_with_values_refd(): - content = """ - repositories: ["airbyte", "airbyte-cloud"] - partition_router: - type: ListPartitionRouter - values: "#/repositories" - cursor_field: repository - """ - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - partition_router_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["partition_router"], {}) - - partition_router = factory.create_component( - model_type=ListPartitionRouterModel, component_definition=partition_router_manifest, config=input_config - ) - - assert isinstance(partition_router, ListPartitionRouter) - assert partition_router.values == ["airbyte", "airbyte-cloud"] - - -def test_list_based_stream_slicer_with_values_defined_in_config(): - content = """ - partition_router: - type: ListPartitionRouter - values: "{{config['repos']}}" - cursor_field: repository - request_option: - type: RequestOption - inject_into: header - field_name: repository - """ - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - partition_router_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["partition_router"], {}) - - partition_router = factory.create_component( - model_type=ListPartitionRouterModel, component_definition=partition_router_manifest, config=input_config - ) - - assert isinstance(partition_router, ListPartitionRouter) - assert partition_router.values == ["airbyte", "airbyte-cloud"] - assert partition_router.request_option.inject_into == RequestOptionType.header - assert partition_router.request_option.field_name.eval(config=input_config) == "repository" - - -def test_create_substream_partition_router(): - content = """ - schema_loader: - file_path: "./source_sendgrid/schemas/{{ parameters['name'] }}.yaml" - name: "{{ parameters['stream_name'] }}" - retriever: - requester: - type: "HttpRequester" - path: "kek" - record_selector: - extractor: - field_path: [] - stream_A: - type: DeclarativeStream - name: "A" - primary_key: "id" - $parameters: - retriever: "#/retriever" - url_base: "https://airbyte.io" - schema_loader: "#/schema_loader" - stream_B: - type: DeclarativeStream - name: "B" - primary_key: "id" - $parameters: - retriever: "#/retriever" - url_base: "https://airbyte.io" - schema_loader: "#/schema_loader" - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/stream_A" - parent_key: id - partition_field: repository_id - request_option: - type: RequestOption - inject_into: request_parameter - field_name: repository_id - - stream: "#/stream_B" - parent_key: someid - partition_field: word_id - """ - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - partition_router_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["partition_router"], {}) - - partition_router = factory.create_component( - model_type=SubstreamPartitionRouterModel, component_definition=partition_router_manifest, config=input_config - ) - - assert isinstance(partition_router, SubstreamPartitionRouter) - parent_stream_configs = partition_router.parent_stream_configs - assert len(parent_stream_configs) == 2 - assert isinstance(parent_stream_configs[0].stream, DeclarativeStream) - assert isinstance(parent_stream_configs[1].stream, DeclarativeStream) - - assert partition_router.parent_stream_configs[0].parent_key.eval({}) == "id" - assert partition_router.parent_stream_configs[0].partition_field.eval({}) == "repository_id" - assert partition_router.parent_stream_configs[0].request_option.inject_into == RequestOptionType.request_parameter - assert partition_router.parent_stream_configs[0].request_option.field_name.eval(config=input_config) == "repository_id" - - assert partition_router.parent_stream_configs[1].parent_key.eval({}) == "someid" - assert partition_router.parent_stream_configs[1].partition_field.eval({}) == "word_id" - assert partition_router.parent_stream_configs[1].request_option is None - - -def test_datetime_based_cursor(): - content = """ - incremental: - type: DatetimeBasedCursor - $parameters: - datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_time'] }}" - min_datetime: "{{ config['start_time'] + day_delta(2) }}" - end_datetime: "{{ config['end_time'] }}" - step: "P10D" - cursor_field: "created" - cursor_granularity: "PT0.000001S" - lookback_window: "P5D" - start_time_option: - type: RequestOption - inject_into: request_parameter - field_name: "since_{{ config['cursor_field'] }}" - end_time_option: - type: RequestOption - inject_into: body_json - field_name: "before_{{ parameters['cursor_field'] }}" - partition_field_start: star - partition_field_end: en - """ - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - slicer_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["incremental"], {"cursor_field": "created_at"}) - - stream_slicer = factory.create_component(model_type=DatetimeBasedCursorModel, component_definition=slicer_manifest, config=input_config) - - assert isinstance(stream_slicer, DatetimeBasedCursor) - assert stream_slicer._step == datetime.timedelta(days=10) - assert stream_slicer.cursor_field.string == "created" - assert stream_slicer.cursor_granularity == "PT0.000001S" - assert stream_slicer._lookback_window.string == "P5D" - assert stream_slicer.start_time_option.inject_into == RequestOptionType.request_parameter - assert stream_slicer.start_time_option.field_name.eval(config=input_config | {"cursor_field": "updated_at"}) == "since_updated_at" - assert stream_slicer.end_time_option.inject_into == RequestOptionType.body_json - assert stream_slicer.end_time_option.field_name.eval({}) == "before_created_at" - assert stream_slicer._partition_field_start.eval({}) == "star" - assert stream_slicer._partition_field_end.eval({}) == "en" - - assert isinstance(stream_slicer._start_datetime, MinMaxDatetime) - assert stream_slicer.start_datetime._datetime_format == "%Y-%m-%dT%H:%M:%S.%f%z" - assert stream_slicer.start_datetime.datetime.string == "{{ config['start_time'] }}" - assert stream_slicer.start_datetime.min_datetime.string == "{{ config['start_time'] + day_delta(2) }}" - - assert isinstance(stream_slicer._end_datetime, MinMaxDatetime) - assert stream_slicer._end_datetime.datetime.string == "{{ config['end_time'] }}" - - -def test_stream_with_incremental_and_retriever_with_partition_router(): - content = """ -decoder: - type: JsonDecoder -extractor: - type: DpathExtractor -selector: - type: RecordSelector - record_filter: - type: RecordFilter - condition: "{{ record['id'] > stream_state['id'] }}" -requester: - type: HttpRequester - name: "{{ parameters['name'] }}" - url_base: "https://api.sendgrid.com/v3/" - http_method: "GET" - authenticator: - type: SessionTokenAuthenticator - decoder: - type: JsonDecoder - expiration_duration: P10D - login_requester: - path: /session - type: HttpRequester - url_base: 'https://api.sendgrid.com' - http_method: POST - request_body_json: - password: '{{ config.apikey }}' - username: '{{ parameters.name }}' - session_token_path: - - id - request_authentication: - type: ApiKey - inject_into: - type: RequestOption - field_name: X-Metabase-Session - inject_into: header - request_parameters: - unit: "day" -list_stream: - type: DeclarativeStream - schema_loader: - type: JsonFileSchemaLoader - file_path: "./source_sendgrid/schemas/{{ parameters.name }}.json" - incremental_sync: - type: DatetimeBasedCursor - $parameters: - datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" - start_datetime: "{{ config['start_time'] }}" - end_datetime: "{{ config['end_time'] }}" - step: "P10D" - cursor_field: "created" - cursor_granularity: "PT0.000001S" - lookback_window: "P5D" - start_time_option: - inject_into: request_parameter - field_name: created[gte] - end_time_option: - inject_into: body_json - field_name: end_time - partition_field_start: star - partition_field_end: en - retriever: - type: SimpleRetriever - name: "{{ parameters['name'] }}" - decoder: - $ref: "#/decoder" - partition_router: - type: ListPartitionRouter - values: "{{config['repos']}}" - cursor_field: a_key - request_option: - inject_into: header - field_name: a_key - paginator: - type: DefaultPaginator - page_size_option: - inject_into: request_parameter - field_name: page_size - page_token_option: - inject_into: path - type: RequestPath - pagination_strategy: - type: "CursorPagination" - cursor_value: "{{ response._metadata.next }}" - page_size: 10 - requester: - $ref: "#/requester" - path: "{{ next_page_token['next_page_url'] }}" - record_selector: - $ref: "#/selector" - $parameters: - name: "lists" - primary_key: "id" - extractor: - $ref: "#/extractor" - field_path: ["{{ parameters['name'] }}"] - """ - - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - stream_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["list_stream"], {}) - - stream = factory.create_component(model_type=DeclarativeStreamModel, component_definition=stream_manifest, config=input_config) - - assert isinstance(stream, DeclarativeStream) - assert isinstance(stream.retriever, SimpleRetriever) - assert isinstance(stream.retriever.stream_slicer, PerPartitionWithGlobalCursor) - - datetime_stream_slicer = stream.retriever.stream_slicer._per_partition_cursor._cursor_factory.create() - assert isinstance(datetime_stream_slicer, DatetimeBasedCursor) - assert isinstance(datetime_stream_slicer._start_datetime, MinMaxDatetime) - assert datetime_stream_slicer._start_datetime.datetime.string == "{{ config['start_time'] }}" - assert isinstance(datetime_stream_slicer._end_datetime, MinMaxDatetime) - assert datetime_stream_slicer._end_datetime.datetime.string == "{{ config['end_time'] }}" - assert datetime_stream_slicer.step == "P10D" - assert datetime_stream_slicer.cursor_field.string == "created" - - list_stream_slicer = stream.retriever.stream_slicer._partition_router - assert isinstance(list_stream_slicer, ListPartitionRouter) - assert list_stream_slicer.values == ["airbyte", "airbyte-cloud"] - assert list_stream_slicer._cursor_field.string == "a_key" - - -def test_resumable_full_refresh_stream(): - content = """ -decoder: - type: JsonDecoder -extractor: - type: DpathExtractor -selector: - type: RecordSelector - record_filter: - type: RecordFilter - condition: "{{ record['id'] > stream_state['id'] }}" -metadata_paginator: - type: DefaultPaginator - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: page_size - page_token_option: - type: RequestPath - pagination_strategy: - type: "CursorPagination" - cursor_value: "{{ response._metadata.next }}" - page_size: 10 -requester: - type: HttpRequester - url_base: "https://api.sendgrid.com/v3/" - http_method: "GET" - authenticator: - type: BearerAuthenticator - api_token: "{{ config['apikey'] }}" - request_parameters: - unit: "day" -retriever: - paginator: - type: NoPagination - decoder: - $ref: "#/decoder" -partial_stream: - type: DeclarativeStream - schema_loader: - type: JsonFileSchemaLoader - file_path: "./source_sendgrid/schemas/{{ parameters.name }}.json" -list_stream: - $ref: "#/partial_stream" - $parameters: - name: "lists" - extractor: - $ref: "#/extractor" - field_path: ["{{ parameters['name'] }}"] - name: "lists" - primary_key: "id" - retriever: - $ref: "#/retriever" - requester: - $ref: "#/requester" - path: "{{ next_page_token['next_page_url'] }}" - paginator: - $ref: "#/metadata_paginator" - record_selector: - $ref: "#/selector" - transformations: - - type: AddFields - fields: - - path: ["extra"] - value: "{{ response.to_add }}" -check: - type: CheckStream - stream_names: ["list_stream"] -spec: - type: Spec - documentation_url: https://airbyte.com/#yaml-from-manifest - connection_specification: - title: Test Spec - type: object - required: - - api_key - additionalProperties: false - properties: - api_key: - type: string - airbyte_secret: true - title: API Key - description: Test API Key - order: 0 - advanced_auth: - auth_flow_type: "oauth2.0" - """ - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - resolved_manifest["type"] = "DeclarativeSource" - manifest = transformer.propagate_types_and_parameters("", resolved_manifest, {}) - - stream_manifest = manifest["list_stream"] - assert stream_manifest["type"] == "DeclarativeStream" - stream = factory.create_component(model_type=DeclarativeStreamModel, component_definition=stream_manifest, config=input_config) - - assert isinstance(stream, DeclarativeStream) - assert stream.primary_key == "id" - assert stream.name == "lists" - assert stream._stream_cursor_field.string == "" - - assert isinstance(stream.retriever, SimpleRetriever) - assert stream.retriever.primary_key == stream.primary_key - assert stream.retriever.name == stream.name - - assert isinstance(stream.retriever.record_selector, RecordSelector) - - assert isinstance(stream.retriever.stream_slicer, ResumableFullRefreshCursor) - assert isinstance(stream.retriever.cursor, ResumableFullRefreshCursor) - - assert isinstance(stream.retriever.paginator, DefaultPaginator) - assert isinstance(stream.retriever.paginator.decoder, PaginationDecoderDecorator) - assert stream.retriever.paginator.page_size_option.field_name.eval(input_config) == "page_size" - assert stream.retriever.paginator.page_size_option.inject_into == RequestOptionType.request_parameter - assert isinstance(stream.retriever.paginator.page_token_option, RequestPath) - assert stream.retriever.paginator.url_base.string == "https://api.sendgrid.com/v3/" - assert stream.retriever.paginator.url_base.default == "https://api.sendgrid.com/v3/" - - assert isinstance(stream.retriever.paginator.pagination_strategy, CursorPaginationStrategy) - assert isinstance(stream.retriever.paginator.pagination_strategy.decoder, PaginationDecoderDecorator) - assert stream.retriever.paginator.pagination_strategy._cursor_value.string == "{{ response._metadata.next }}" - assert stream.retriever.paginator.pagination_strategy._cursor_value.default == "{{ response._metadata.next }}" - assert stream.retriever.paginator.pagination_strategy.page_size == 10 - - checker = factory.create_component(model_type=CheckStreamModel, component_definition=manifest["check"], config=input_config) - - assert isinstance(checker, CheckStream) - streams_to_check = checker.stream_names - assert len(streams_to_check) == 1 - assert list(streams_to_check)[0] == "list_stream" - - -def test_incremental_data_feed(): - content = """ -selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: ["extractor_path"] - record_filter: - type: RecordFilter - condition: "{{ record['id'] > stream_state['id'] }}" -requester: - type: HttpRequester - name: "{{ parameters['name'] }}" - url_base: "https://api.sendgrid.com/v3/" - http_method: "GET" -list_stream: - type: DeclarativeStream - incremental_sync: - type: DatetimeBasedCursor - $parameters: - datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" - start_datetime: "{{ config['start_time'] }}" - cursor_field: "created" - is_data_feed: true - retriever: - type: SimpleRetriever - name: "{{ parameters['name'] }}" - paginator: - type: DefaultPaginator - pagination_strategy: - type: "CursorPagination" - cursor_value: "{{ response._metadata.next }}" - page_size: 10 - requester: - $ref: "#/requester" - path: "/" - record_selector: - $ref: "#/selector" - $parameters: - name: "lists" - """ - - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - stream_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["list_stream"], {}) - - stream = factory.create_component(model_type=DeclarativeStreamModel, component_definition=stream_manifest, config=input_config) - - assert isinstance(stream.retriever.paginator.pagination_strategy, StopConditionPaginationStrategyDecorator) - - -def test_given_data_feed_and_incremental_then_raise_error(): - content = """ -incremental_sync: - type: DatetimeBasedCursor - $parameters: - datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" - start_datetime: "{{ config['start_time'] }}" - end_datetime: "2023-01-01" - cursor_field: "created" - is_data_feed: true""" - - parsed_incremental_sync = YamlDeclarativeSource._parse(content) - resolved_incremental_sync = resolver.preprocess_manifest(parsed_incremental_sync) - datetime_based_cursor_definition = transformer.propagate_types_and_parameters("", resolved_incremental_sync["incremental_sync"], {}) - - with pytest.raises(ValueError): - factory.create_component( - model_type=DatetimeBasedCursorModel, component_definition=datetime_based_cursor_definition, config=input_config - ) - - -def test_client_side_incremental(): - content = """ -selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: ["extractor_path"] -requester: - type: HttpRequester - name: "{{ parameters['name'] }}" - url_base: "https://api.sendgrid.com/v3/" - http_method: "GET" -list_stream: - type: DeclarativeStream - incremental_sync: - type: DatetimeBasedCursor - $parameters: - datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config.get('start_date', '1970-01-01T00:00:00.0Z') }}" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - cursor_field: "created" - is_client_side_incremental: true - retriever: - type: SimpleRetriever - name: "{{ parameters['name'] }}" - paginator: - type: DefaultPaginator - pagination_strategy: - type: "CursorPagination" - cursor_value: "{{ response._metadata.next }}" - page_size: 10 - requester: - $ref: "#/requester" - path: "/" - record_selector: - $ref: "#/selector" - $parameters: - name: "lists" - """ - - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - stream_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["list_stream"], {}) - - stream = factory.create_component(model_type=DeclarativeStreamModel, component_definition=stream_manifest, config=input_config) - - assert isinstance(stream.retriever.record_selector.record_filter, ClientSideIncrementalRecordFilterDecorator) - - -def test_client_side_incremental_with_partition_router(): - content = """ -selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: ["extractor_path"] -requester: - type: HttpRequester - name: "{{ parameters['name'] }}" - url_base: "https://api.sendgrid.com/v3/" - http_method: "GET" -schema_loader: - file_path: "./source_sendgrid/schemas/{{ parameters['name'] }}.yaml" - name: "{{ parameters['stream_name'] }}" -retriever: - requester: - type: "HttpRequester" - path: "kek" - record_selector: - extractor: - field_path: [] -stream_A: - type: DeclarativeStream - name: "A" - primary_key: "id" - $parameters: - retriever: "#/retriever" - url_base: "https://airbyte.io" - schema_loader: "#/schema_loader" -list_stream: - type: DeclarativeStream - incremental_sync: - type: DatetimeBasedCursor - $parameters: - datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config.get('start_date', '1970-01-01T00:00:00.0Z') }}" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - cursor_field: "created" - is_client_side_incremental: true - retriever: - type: SimpleRetriever - name: "{{ parameters['name'] }}" - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/stream_A" - parent_key: id - partition_field: id - paginator: - type: DefaultPaginator - pagination_strategy: - type: "CursorPagination" - cursor_value: "{{ response._metadata.next }}" - page_size: 10 - requester: - $ref: "#/requester" - path: "/" - record_selector: - $ref: "#/selector" - $parameters: - name: "lists" - """ - - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - stream_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["list_stream"], {}) - - stream = factory.create_component(model_type=DeclarativeStreamModel, component_definition=stream_manifest, config=input_config) - - assert isinstance(stream.retriever.record_selector.record_filter, ClientSideIncrementalRecordFilterDecorator) - assert isinstance(stream.retriever.record_selector.record_filter._substream_cursor, PerPartitionWithGlobalCursor) - - -def test_given_data_feed_and_client_side_incremental_then_raise_error(): - content = """ -incremental_sync: - type: DatetimeBasedCursor - $parameters: - datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" - start_datetime: "{{ config['start_time'] }}" - cursor_field: "created" - is_data_feed: true - is_client_side_incremental: true - """ - - parsed_incremental_sync = YamlDeclarativeSource._parse(content) - resolved_incremental_sync = resolver.preprocess_manifest(parsed_incremental_sync) - datetime_based_cursor_definition = transformer.propagate_types_and_parameters("", resolved_incremental_sync["incremental_sync"], {}) - - with pytest.raises(ValueError) as e: - factory.create_component( - model_type=DatetimeBasedCursorModel, component_definition=datetime_based_cursor_definition, config=input_config - ) - assert e.value.args[0] == "`Client side incremental` cannot be applied with `data feed`. Choose only 1 from them." - - -@pytest.mark.parametrize( - "test_name, record_selector, expected_runtime_selector", - [("test_static_record_selector", "result", "result"), ("test_options_record_selector", "{{ parameters['name'] }}", "lists")], -) -def test_create_record_selector(test_name, record_selector, expected_runtime_selector): - content = f""" - extractor: - type: DpathExtractor - selector: - $parameters: - name: "lists" - type: RecordSelector - record_filter: - type: RecordFilter - condition: "{{{{ record['id'] > stream_state['id'] }}}}" - extractor: - $ref: "#/extractor" - field_path: ["{record_selector}"] - """ - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - selector_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["selector"], {}) - - selector = factory.create_component( - model_type=RecordSelectorModel, component_definition=selector_manifest, decoder=None, transformations=[], config=input_config - ) - - assert isinstance(selector, RecordSelector) - assert isinstance(selector.extractor, DpathExtractor) - assert [fp.eval(input_config) for fp in selector.extractor._field_path] == [expected_runtime_selector] - assert isinstance(selector.record_filter, RecordFilter) - assert selector.record_filter.condition == "{{ record['id'] > stream_state['id'] }}" - - -@pytest.mark.parametrize( - "test_name, error_handler, expected_backoff_strategy_type", - [ - ( - "test_create_requester_constant_error_handler", - """ - error_handler: - backoff_strategies: - - type: "ConstantBackoffStrategy" - backoff_time_in_seconds: 5 - """, - ConstantBackoffStrategy, - ), - ( - "test_create_requester_exponential_error_handler", - """ - error_handler: - backoff_strategies: - - type: "ExponentialBackoffStrategy" - factor: 5 - """, - ExponentialBackoffStrategy, - ), - ( - "test_create_requester_wait_time_from_header_error_handler", - """ - error_handler: - backoff_strategies: - - type: "WaitTimeFromHeader" - header: "a_header" - """, - WaitTimeFromHeaderBackoffStrategy, - ), - ( - "test_create_requester_wait_time_until_from_header_error_handler", - """ - error_handler: - backoff_strategies: - - type: "WaitUntilTimeFromHeader" - header: "a_header" - """, - WaitUntilTimeFromHeaderBackoffStrategy, - ), - ("test_create_requester_no_error_handler", """""", None), - ], -) -def test_create_requester(test_name, error_handler, expected_backoff_strategy_type): - content = f""" -requester: - type: HttpRequester - path: "/v3/marketing/lists" - $parameters: - name: 'lists' - url_base: "https://api.sendgrid.com" - authenticator: - type: "BasicHttpAuthenticator" - username: "{{{{ parameters.name}}}}" - password: "{{{{ config.apikey }}}}" - request_parameters: - a_parameter: "something_here" - request_headers: - header: header_value - {error_handler} - """ - name = "name" - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - requester_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["requester"], {}) - - selector = factory.create_component( - model_type=HttpRequesterModel, - component_definition=requester_manifest, - config=input_config, - name=name, - decoder=None, - ) - - assert isinstance(selector, HttpRequester) - assert selector.http_method == HttpMethod.GET - assert selector.name == "name" - assert selector._path.string == "/v3/marketing/lists" - assert selector._url_base.string == "https://api.sendgrid.com" - - assert isinstance(selector.error_handler, DefaultErrorHandler) - if expected_backoff_strategy_type: - assert len(selector.error_handler.backoff_strategies) == 1 - assert isinstance(selector.error_handler.backoff_strategies[0], expected_backoff_strategy_type) - - assert isinstance(selector.authenticator, BasicHttpAuthenticator) - assert selector.authenticator._username.eval(input_config) == "lists" - assert selector.authenticator._password.eval(input_config) == "verysecrettoken" - - assert isinstance(selector._request_options_provider, InterpolatedRequestOptionsProvider) - assert selector._request_options_provider._parameter_interpolator._interpolator.mapping["a_parameter"] == "something_here" - assert selector._request_options_provider._headers_interpolator._interpolator.mapping["header"] == "header_value" - - -def test_create_request_with_legacy_session_authenticator(): - content = """ -requester: - type: HttpRequester - path: "/v3/marketing/lists" - $parameters: - name: 'lists' - url_base: "https://api.sendgrid.com" - authenticator: - type: "LegacySessionTokenAuthenticator" - username: "{{ parameters.name}}" - password: "{{ config.apikey }}" - login_url: "login" - header: "token" - session_token_response_key: "session" - validate_session_url: validate - request_parameters: - a_parameter: "something_here" - request_headers: - header: header_value - """ - name = "name" - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - requester_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["requester"], {}) - - selector = factory.create_component( - model_type=HttpRequesterModel, component_definition=requester_manifest, config=input_config, name=name, decoder=None - ) - - assert isinstance(selector, HttpRequester) - assert isinstance(selector.authenticator, LegacySessionTokenAuthenticator) - assert selector.authenticator._username.eval(input_config) == "lists" - assert selector.authenticator._password.eval(input_config) == "verysecrettoken" - assert selector.authenticator._api_url.eval(input_config) == "https://api.sendgrid.com" - - -def test_create_request_with_session_authenticator(): - content = """ -requester: - type: HttpRequester - path: "/v3/marketing/lists" - $parameters: - name: 'lists' - url_base: "https://api.sendgrid.com" - authenticator: - type: SessionTokenAuthenticator - decoder: - type: JsonDecoder - expiration_duration: P10D - login_requester: - path: /session - type: HttpRequester - url_base: 'https://api.sendgrid.com' - http_method: POST - request_body_json: - password: '{{ config.apikey }}' - username: '{{ parameters.name }}' - session_token_path: - - id - request_authentication: - type: ApiKey - inject_into: - type: RequestOption - field_name: X-Metabase-Session - inject_into: header - request_parameters: - a_parameter: "something_here" - request_headers: - header: header_value - """ - name = "name" - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - requester_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["requester"], {}) - - selector = factory.create_component( - model_type=HttpRequesterModel, component_definition=requester_manifest, config=input_config, name=name, decoder=None - ) - - assert isinstance(selector.authenticator, ApiKeyAuthenticator) - assert isinstance(selector.authenticator.token_provider, SessionTokenProvider) - assert selector.authenticator.token_provider.session_token_path == ["id"] - assert isinstance(selector.authenticator.token_provider.login_requester, HttpRequester) - assert selector.authenticator.token_provider.session_token_path == ["id"] - assert selector.authenticator.token_provider.login_requester._url_base.eval(input_config) == "https://api.sendgrid.com" - assert selector.authenticator.token_provider.login_requester.get_request_body_json() == { - "username": "lists", - "password": "verysecrettoken", - } - - -def test_given_composite_error_handler_does_not_match_response_then_fallback_on_default_error_handler(requests_mock): - content = """ -requester: - type: HttpRequester - path: "/v3/marketing/lists" - $parameters: - name: 'lists' - url_base: "https://api.sendgrid.com" - error_handler: - type: CompositeErrorHandler - error_handlers: - - type: DefaultErrorHandler - response_filters: - - type: HttpResponseFilter - action: FAIL - http_codes: - - 500 - """ - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - requester_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["requester"], {}) - http_requester = factory.create_component( - model_type=HttpRequesterModel, - component_definition=requester_manifest, - config=input_config, - name="any name", - decoder=JsonDecoder(parameters={}), - ) - requests_mock.get("https://api.sendgrid.com/v3/marketing/lists", status_code=401) - - with pytest.raises(AirbyteTracedException) as exception: - http_requester.send_request() - - # The default behavior when we don't know about an error is to return a system_error. - # Here, we can confirm that we return a config_error which means we picked up the default error mapper - assert exception.value.failure_type == FailureType.config_error - - -@pytest.mark.parametrize( - "input_config, expected_authenticator_class", - [ - pytest.param( - {"auth": {"type": "token"}, "credentials": {"api_key": "some_key"}}, - ApiKeyAuthenticator, - id="test_create_requester_with_selective_authenticator_and_token_selected", - ), - pytest.param( - {"auth": {"type": "oauth"}, "credentials": {"client_id": "ABC"}}, - DeclarativeOauth2Authenticator, - id="test_create_requester_with_selective_authenticator_and_oauth_selected", - ), - ], -) -def test_create_requester_with_selective_authenticator(input_config, expected_authenticator_class): - content = """ -authenticator: - type: SelectiveAuthenticator - authenticator_selection_path: - - auth - - type - authenticators: - token: - type: ApiKeyAuthenticator - header: "Authorization" - api_token: "api_key={{ config['credentials']['api_key'] }}" - oauth: - type: OAuthAuthenticator - token_refresh_endpoint: https://api.url.com - client_id: "{{ config['credentials']['client_id'] }}" - client_secret: some_secret - refresh_token: some_token - """ - name = "name" - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - authenticator_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["authenticator"], {}) - - authenticator = factory.create_component( - model_type=SelectiveAuthenticator, component_definition=authenticator_manifest, config=input_config, name=name - ) - - assert isinstance(authenticator, expected_authenticator_class) - - -def test_create_composite_error_handler(): - content = """ - error_handler: - type: "CompositeErrorHandler" - error_handlers: - - response_filters: - - predicate: "{{ 'code' in response }}" - action: RETRY - - response_filters: - - http_codes: [ 403 ] - action: RETRY - """ - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - error_handler_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["error_handler"], {}) - - error_handler = factory.create_component( - model_type=CompositeErrorHandlerModel, component_definition=error_handler_manifest, config=input_config - ) - - assert isinstance(error_handler, CompositeErrorHandler) - assert len(error_handler.error_handlers) == 2 - - error_handler_0 = error_handler.error_handlers[0] - assert isinstance(error_handler_0, DefaultErrorHandler) - assert isinstance(error_handler_0.response_filters[0], HttpResponseFilter) - assert error_handler_0.response_filters[0].predicate.condition == "{{ 'code' in response }}" - assert error_handler_0.response_filters[0].action == ResponseAction.RETRY - - error_handler_1 = error_handler.error_handlers[1] - assert isinstance(error_handler_1, DefaultErrorHandler) - assert isinstance(error_handler_1.response_filters[0], HttpResponseFilter) - assert error_handler_1.response_filters[0].http_codes == {403} - assert error_handler_1.response_filters[0].action == ResponseAction.RETRY - - -# This might be a better test for the manifest transformer but also worth testing end-to-end here as well -def test_config_with_defaults(): - content = """ - lists_stream: - type: "DeclarativeStream" - name: "lists" - primary_key: id - $parameters: - name: "lists" - url_base: "https://api.sendgrid.com" - schema_loader: - name: "{{ parameters.stream_name }}" - file_path: "./source_sendgrid/schemas/{{ parameters.name }}.yaml" - retriever: - paginator: - type: "DefaultPaginator" - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: page_size - page_token_option: - type: RequestPath - pagination_strategy: - type: "CursorPagination" - cursor_value: "{{ response._metadata.next }}" - page_size: 10 - requester: - path: "/v3/marketing/lists" - authenticator: - type: "BearerAuthenticator" - api_token: "{{ config.apikey }}" - request_parameters: - page_size: 10 - record_selector: - extractor: - field_path: ["result"] - streams: - - "#/lists_stream" - """ - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - resolved_manifest["type"] = "DeclarativeSource" - stream_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["lists_stream"], {}) - - stream = factory.create_component(model_type=DeclarativeStreamModel, component_definition=stream_manifest, config=input_config) - - assert isinstance(stream, DeclarativeStream) - assert stream.primary_key == "id" - assert stream.name == "lists" - assert isinstance(stream.retriever, SimpleRetriever) - assert stream.retriever.name == stream.name - assert stream.retriever.primary_key == stream.primary_key - - assert isinstance(stream.schema_loader, JsonFileSchemaLoader) - assert stream.schema_loader.file_path.string == "./source_sendgrid/schemas/{{ parameters.name }}.yaml" - assert stream.schema_loader.file_path.default == "./source_sendgrid/schemas/{{ parameters.name }}.yaml" - - assert isinstance(stream.retriever.requester, HttpRequester) - assert stream.retriever.requester.http_method == HttpMethod.GET - - assert isinstance(stream.retriever.requester.authenticator, BearerAuthenticator) - assert stream.retriever.requester.authenticator.token_provider.get_token() == "verysecrettoken" - - assert isinstance(stream.retriever.record_selector, RecordSelector) - assert isinstance(stream.retriever.record_selector.extractor, DpathExtractor) - assert [fp.eval(input_config) for fp in stream.retriever.record_selector.extractor._field_path] == ["result"] - - assert isinstance(stream.retriever.paginator, DefaultPaginator) - assert stream.retriever.paginator.url_base.string == "https://api.sendgrid.com" - assert stream.retriever.paginator.pagination_strategy.get_page_size() == 10 - - -def test_create_default_paginator(): - content = """ - paginator: - type: "DefaultPaginator" - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: page_size - page_token_option: - type: RequestPath - pagination_strategy: - type: "CursorPagination" - page_size: 50 - cursor_value: "{{ response._metadata.next }}" - """ - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - paginator_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["paginator"], {}) - - paginator = factory.create_component( - model_type=DefaultPaginatorModel, - component_definition=paginator_manifest, - config=input_config, - url_base="https://airbyte.io", - decoder=JsonDecoder(parameters={}), - ) - - assert isinstance(paginator, DefaultPaginator) - assert paginator.url_base.string == "https://airbyte.io" - - assert isinstance(paginator.pagination_strategy, CursorPaginationStrategy) - assert paginator.pagination_strategy.page_size == 50 - assert paginator.pagination_strategy._cursor_value.string == "{{ response._metadata.next }}" - - assert isinstance(paginator.page_size_option, RequestOption) - assert paginator.page_size_option.inject_into == RequestOptionType.request_parameter - assert paginator.page_size_option.field_name.eval(config=input_config) == "page_size" - - assert isinstance(paginator.page_token_option, RequestPath) - - -@pytest.mark.parametrize( - "manifest, field_name, expected_value, expected_error", - [ - pytest.param( - { - "type": "CustomErrorHandler", - "class_name": "unit_tests.sources.declarative.parsers.testing_components.TestingSomeComponent", - "subcomponent_field_with_hint": {"type": "DpathExtractor", "field_path": [], "decoder": {"type": "JsonDecoder"}}, - }, - "subcomponent_field_with_hint", - DpathExtractor( - field_path=[], - config={"apikey": "verysecrettoken", "repos": ["airbyte", "airbyte-cloud"]}, - decoder=JsonDecoder(parameters={}), - parameters={}, - ), - None, - id="test_create_custom_component_with_subcomponent_that_must_be_parsed", - ), - pytest.param( - { - "type": "CustomErrorHandler", - "class_name": "unit_tests.sources.declarative.parsers.testing_components.TestingSomeComponent", - "subcomponent_field_with_hint": {"field_path": []}, - }, - "subcomponent_field_with_hint", - DpathExtractor(field_path=[], config={"apikey": "verysecrettoken", "repos": ["airbyte", "airbyte-cloud"]}, parameters={}), - None, - id="test_create_custom_component_with_subcomponent_that_must_infer_type_from_explicit_hints", - ), - pytest.param( - { - "type": "CustomErrorHandler", - "class_name": "unit_tests.sources.declarative.parsers.testing_components.TestingSomeComponent", - "basic_field": "expected", - }, - "basic_field", - "expected", - None, - id="test_create_custom_component_with_built_in_type", - ), - pytest.param( - { - "type": "CustomErrorHandler", - "class_name": "unit_tests.sources.declarative.parsers.testing_components.TestingSomeComponent", - "optional_subcomponent_field": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "destination"}, - }, - "optional_subcomponent_field", - RequestOption(inject_into=RequestOptionType.request_parameter, field_name="destination", parameters={}), - None, - id="test_create_custom_component_with_subcomponent_wrapped_in_optional", - ), - pytest.param( - { - "type": "CustomErrorHandler", - "class_name": "unit_tests.sources.declarative.parsers.testing_components.TestingSomeComponent", - "list_of_subcomponents": [ - {"inject_into": "header", "field_name": "store_me"}, - {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "destination"}, - ], - }, - "list_of_subcomponents", - [ - RequestOption(inject_into=RequestOptionType.header, field_name="store_me", parameters={}), - RequestOption(inject_into=RequestOptionType.request_parameter, field_name="destination", parameters={}), - ], - None, - id="test_create_custom_component_with_subcomponent_wrapped_in_list", - ), - pytest.param( - { - "type": "CustomErrorHandler", - "class_name": "unit_tests.sources.declarative.parsers.testing_components.TestingSomeComponent", - "without_hint": {"inject_into": "request_parameter", "field_name": "missing_hint"}, - }, - "without_hint", - None, - None, - id="test_create_custom_component_with_subcomponent_without_type_hints", - ), - pytest.param( - { - "type": "CustomErrorHandler", - "class_name": "unit_tests.sources.declarative.parsers.testing_components.TestingSomeComponent", - "paginator": { - "type": "DefaultPaginator", - "pagination_strategy": {"type": "OffsetIncrement", "page_size": 10}, - "$parameters": {"url_base": "https://physical_100.com"}, - }, - }, - "paginator", - DefaultPaginator( - pagination_strategy=OffsetIncrement( - page_size=10, config={"apikey": "verysecrettoken", "repos": ["airbyte", "airbyte-cloud"]}, parameters={} - ), - url_base="https://physical_100.com", - config={"apikey": "verysecrettoken", "repos": ["airbyte", "airbyte-cloud"]}, - parameters={"decoder": {"type": "JsonDecoder"}}, - ), - None, - id="test_create_custom_component_with_subcomponent_that_uses_parameters", - ), - pytest.param( - { - "type": "CustomErrorHandler", - "class_name": "unit_tests.sources.declarative.parsers.testing_components.TestingSomeComponent", - "paginator": { - "type": "DefaultPaginator", - "pagination_strategy": {"type": "OffsetIncrement", "page_size": 10}, - }, - }, - "paginator", - None, - ValueError, - id="test_create_custom_component_missing_required_field_emits_error", - ), - pytest.param( - { - "type": "CustomErrorHandler", - "class_name": "unit_tests.sources.declarative.parsers.testing_components.NonExistingClass", - "paginator": { - "type": "DefaultPaginator", - "pagination_strategy": {"type": "OffsetIncrement", "page_size": 10}, - }, - }, - "paginator", - None, - ValueError, - id="test_create_custom_component_non_existing_class_raises_value_error", - ), - ], -) -def test_create_custom_components(manifest, field_name, expected_value, expected_error): - if expected_error: - with pytest.raises(expected_error): - factory.create_component(CustomErrorHandlerModel, manifest, input_config) - else: - custom_component = factory.create_component(CustomErrorHandlerModel, manifest, input_config) - assert isinstance(custom_component, TestingSomeComponent) - - assert isinstance(getattr(custom_component, field_name), type(expected_value)) - assert getattr(custom_component, field_name) == expected_value - - -def test_custom_components_do_not_contain_extra_fields(): - custom_substream_partition_router_manifest = { - "type": "CustomPartitionRouter", - "class_name": "unit_tests.sources.declarative.parsers.testing_components.TestingCustomSubstreamPartitionRouter", - "custom_field": "here", - "extra_field_to_exclude": "should_not_pass_as_parameter", - "custom_pagination_strategy": {"type": "PageIncrement", "page_size": 100}, - "parent_stream_configs": [ - { - "type": "ParentStreamConfig", - "stream": { - "type": "DeclarativeStream", - "name": "a_parent", - "primary_key": "id", - "retriever": { - "type": "SimpleRetriever", - "record_selector": { - "type": "RecordSelector", - "extractor": {"type": "DpathExtractor", "field_path": []}, - }, - "requester": {"type": "HttpRequester", "url_base": "https://airbyte.io", "path": "some"}, - }, - "schema_loader": { - "type": "JsonFileSchemaLoader", - "file_path": "./source_sendgrid/schemas/{{ parameters['name'] }}.yaml", - }, - }, - "parent_key": "id", - "partition_field": "repository_id", - "request_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "repository_id"}, - } - ], - } - - custom_substream_partition_router = factory.create_component( - CustomPartitionRouterModel, custom_substream_partition_router_manifest, input_config - ) - assert isinstance(custom_substream_partition_router, TestingCustomSubstreamPartitionRouter) - - assert len(custom_substream_partition_router.parent_stream_configs) == 1 - assert custom_substream_partition_router.parent_stream_configs[0].parent_key.eval({}) == "id" - assert custom_substream_partition_router.parent_stream_configs[0].partition_field.eval({}) == "repository_id" - assert custom_substream_partition_router.parent_stream_configs[0].request_option.inject_into == RequestOptionType.request_parameter - assert custom_substream_partition_router.parent_stream_configs[0].request_option.field_name.eval(config=input_config) == "repository_id" - - assert isinstance(custom_substream_partition_router.custom_pagination_strategy, PageIncrement) - assert custom_substream_partition_router.custom_pagination_strategy.page_size == 100 - - -def test_parse_custom_component_fields_if_subcomponent(): - custom_substream_partition_router_manifest = { - "type": "CustomPartitionRouter", - "class_name": "unit_tests.sources.declarative.parsers.testing_components.TestingCustomSubstreamPartitionRouter", - "custom_field": "here", - "custom_pagination_strategy": {"type": "PageIncrement", "page_size": 100}, - "parent_stream_configs": [ - { - "type": "ParentStreamConfig", - "stream": { - "type": "DeclarativeStream", - "name": "a_parent", - "primary_key": "id", - "retriever": { - "type": "SimpleRetriever", - "record_selector": { - "type": "RecordSelector", - "extractor": {"type": "DpathExtractor", "field_path": []}, - }, - "requester": {"type": "HttpRequester", "url_base": "https://airbyte.io", "path": "some"}, - }, - "schema_loader": { - "type": "JsonFileSchemaLoader", - "file_path": "./source_sendgrid/schemas/{{ parameters['name'] }}.yaml", - }, - }, - "parent_key": "id", - "partition_field": "repository_id", - "request_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "repository_id"}, - } - ], - } - - custom_substream_partition_router = factory.create_component( - CustomPartitionRouterModel, custom_substream_partition_router_manifest, input_config - ) - assert isinstance(custom_substream_partition_router, TestingCustomSubstreamPartitionRouter) - assert custom_substream_partition_router.custom_field == "here" - - assert len(custom_substream_partition_router.parent_stream_configs) == 1 - assert custom_substream_partition_router.parent_stream_configs[0].parent_key.eval({}) == "id" - assert custom_substream_partition_router.parent_stream_configs[0].partition_field.eval({}) == "repository_id" - assert custom_substream_partition_router.parent_stream_configs[0].request_option.inject_into == RequestOptionType.request_parameter - assert custom_substream_partition_router.parent_stream_configs[0].request_option.field_name.eval(config=input_config) == "repository_id" - - assert isinstance(custom_substream_partition_router.custom_pagination_strategy, PageIncrement) - assert custom_substream_partition_router.custom_pagination_strategy.page_size == 100 - - -class TestCreateTransformations: - # the tabbing matters - base_parameters = """ - name: "lists" - primary_key: id - url_base: "https://api.sendgrid.com" - schema_loader: - name: "{{ parameters.name }}" - file_path: "./source_sendgrid/schemas/{{ parameters.name }}.yaml" - retriever: - requester: - name: "{{ parameters.name }}" - path: "/v3/marketing/lists" - request_parameters: - page_size: 10 - record_selector: - extractor: - field_path: ["result"] - """ - - def test_no_transformations(self): - content = f""" - the_stream: - type: DeclarativeStream - $parameters: - {self.base_parameters} - """ - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - resolved_manifest["type"] = "DeclarativeSource" - stream_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["the_stream"], {}) - - stream = factory.create_component(model_type=DeclarativeStreamModel, component_definition=stream_manifest, config=input_config) - - assert isinstance(stream, DeclarativeStream) - assert [] == stream.retriever.record_selector.transformations - - def test_remove_fields(self): - content = f""" - the_stream: - type: DeclarativeStream - $parameters: - {self.base_parameters} - transformations: - - type: RemoveFields - field_pointers: - - ["path", "to", "field1"] - - ["path2"] - """ - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - resolved_manifest["type"] = "DeclarativeSource" - stream_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["the_stream"], {}) - - stream = factory.create_component(model_type=DeclarativeStreamModel, component_definition=stream_manifest, config=input_config) - - assert isinstance(stream, DeclarativeStream) - expected = [RemoveFields(field_pointers=[["path", "to", "field1"], ["path2"]], parameters={})] - assert stream.retriever.record_selector.transformations == expected - - def test_add_fields_no_value_type(self): - content = f""" - the_stream: - type: DeclarativeStream - $parameters: - {self.base_parameters} - transformations: - - type: AddFields - fields: - - path: ["field1"] - value: "static_value" - """ - expected = [ - AddFields( - fields=[ - AddedFieldDefinition( - path=["field1"], - value=InterpolatedString(string="static_value", default="static_value", parameters={}), - value_type=None, - parameters={}, - ) - ], - parameters={}, - ) - ] - self._test_add_fields(content, expected) - - def test_add_fields_value_type_is_string(self): - content = f""" - the_stream: - type: DeclarativeStream - $parameters: - {self.base_parameters} - transformations: - - type: AddFields - fields: - - path: ["field1"] - value: "static_value" - value_type: string - """ - expected = [ - AddFields( - fields=[ - AddedFieldDefinition( - path=["field1"], - value=InterpolatedString(string="static_value", default="static_value", parameters={}), - value_type=str, - parameters={}, - ) - ], - parameters={}, - ) - ] - self._test_add_fields(content, expected) - - def test_add_fields_value_type_is_number(self): - content = f""" - the_stream: - type: DeclarativeStream - $parameters: - {self.base_parameters} - transformations: - - type: AddFields - fields: - - path: ["field1"] - value: "1" - value_type: number - """ - expected = [ - AddFields( - fields=[ - AddedFieldDefinition( - path=["field1"], - value=InterpolatedString(string="1", default="1", parameters={}), - value_type=float, - parameters={}, - ) - ], - parameters={}, - ) - ] - self._test_add_fields(content, expected) - - def test_add_fields_value_type_is_integer(self): - content = f""" - the_stream: - type: DeclarativeStream - $parameters: - {self.base_parameters} - transformations: - - type: AddFields - fields: - - path: ["field1"] - value: "1" - value_type: integer - """ - expected = [ - AddFields( - fields=[ - AddedFieldDefinition( - path=["field1"], - value=InterpolatedString(string="1", default="1", parameters={}), - value_type=int, - parameters={}, - ) - ], - parameters={}, - ) - ] - self._test_add_fields(content, expected) - - def test_add_fields_value_type_is_boolean(self): - content = f""" - the_stream: - type: DeclarativeStream - $parameters: - {self.base_parameters} - transformations: - - type: AddFields - fields: - - path: ["field1"] - value: False - value_type: boolean - """ - expected = [ - AddFields( - fields=[ - AddedFieldDefinition( - path=["field1"], - value=InterpolatedString(string="False", default="False", parameters={}), - value_type=bool, - parameters={}, - ) - ], - parameters={}, - ) - ] - self._test_add_fields(content, expected) - - def _test_add_fields(self, content, expected): - parsed_manifest = YamlDeclarativeSource._parse(content) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - resolved_manifest["type"] = "DeclarativeSource" - stream_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["the_stream"], {}) - - stream = factory.create_component(model_type=DeclarativeStreamModel, component_definition=stream_manifest, config=input_config) - - assert isinstance(stream, DeclarativeStream) - assert stream.retriever.record_selector.transformations == expected - - def test_default_schema_loader(self): - component_definition = { - "type": "DeclarativeStream", - "name": "test", - "primary_key": [], - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "url_base": "http://localhost:6767/", - "path": "items/", - "request_options_provider": { - "request_parameters": {}, - "request_headers": {}, - "request_body_json": {}, - "type": "InterpolatedRequestOptionsProvider", - }, - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config['api_key'] }}"}, - }, - "record_selector": {"type": "RecordSelector", "extractor": {"type": "DpathExtractor", "field_path": ["items"]}}, - "paginator": {"type": "NoPagination"}, - }, - } - resolved_manifest = resolver.preprocess_manifest(component_definition) - ws = ManifestComponentTransformer() - propagated_source_config = ws.propagate_types_and_parameters("", resolved_manifest, {}) - stream = factory.create_component( - model_type=DeclarativeStreamModel, component_definition=propagated_source_config, config=input_config - ) - schema_loader = stream.schema_loader - assert schema_loader.default_loader._get_json_filepath().split("/")[-1] == f"{stream.name}.json" - - -@pytest.mark.parametrize( - "incremental, partition_router, expected_type", - [ - pytest.param( - { - "type": "DatetimeBasedCursor", - "datetime_format": "%Y-%m-%dT%H:%M:%S.%f%z", - "start_datetime": "{{ config['start_time'] }}", - "end_datetime": "{{ config['end_time'] }}", - "step": "P10D", - "cursor_field": "created", - "cursor_granularity": "PT0.000001S", - }, - None, - DatetimeBasedCursor, - id="test_create_simple_retriever_with_incremental", - ), - pytest.param( - None, - { - "type": "ListPartitionRouter", - "values": "{{config['repos']}}", - "cursor_field": "a_key", - }, - PerPartitionCursor, - id="test_create_simple_retriever_with_partition_router", - ), - pytest.param( - { - "type": "DatetimeBasedCursor", - "datetime_format": "%Y-%m-%dT%H:%M:%S.%f%z", - "start_datetime": "{{ config['start_time'] }}", - "end_datetime": "{{ config['end_time'] }}", - "step": "P10D", - "cursor_field": "created", - "cursor_granularity": "PT0.000001S", - }, - { - "type": "ListPartitionRouter", - "values": "{{config['repos']}}", - "cursor_field": "a_key", - }, - PerPartitionWithGlobalCursor, - id="test_create_simple_retriever_with_incremental_and_partition_router", - ), - pytest.param( - { - "type": "DatetimeBasedCursor", - "datetime_format": "%Y-%m-%dT%H:%M:%S.%f%z", - "start_datetime": "{{ config['start_time'] }}", - "end_datetime": "{{ config['end_time'] }}", - "step": "P10D", - "cursor_field": "created", - "cursor_granularity": "PT0.000001S", - }, - [ - { - "type": "ListPartitionRouter", - "values": "{{config['repos']}}", - "cursor_field": "a_key", - }, - { - "type": "ListPartitionRouter", - "values": "{{config['repos']}}", - "cursor_field": "b_key", - }, - ], - PerPartitionWithGlobalCursor, - id="test_create_simple_retriever_with_partition_routers_multiple_components", - ), - pytest.param(None, None, SinglePartitionRouter, id="test_create_simple_retriever_with_no_incremental_or_partition_router"), - ], -) -def test_merge_incremental_and_partition_router(incremental, partition_router, expected_type): - stream_model = { - "type": "DeclarativeStream", - "retriever": { - "type": "SimpleRetriever", - "record_selector": { - "type": "RecordSelector", - "extractor": { - "type": "DpathExtractor", - "field_path": [], - }, - }, - "requester": { - "type": "HttpRequester", - "name": "list", - "url_base": "orange.com", - "path": "/v1/api", - }, - }, - } - - if incremental: - stream_model["incremental_sync"] = incremental - - if partition_router: - stream_model["retriever"]["partition_router"] = partition_router - - stream = factory.create_component(model_type=DeclarativeStreamModel, component_definition=stream_model, config=input_config) - - assert isinstance(stream, DeclarativeStream) - assert isinstance(stream.retriever, SimpleRetriever) - print(stream.retriever.stream_slicer) - assert isinstance(stream.retriever.stream_slicer, expected_type) - - if incremental and partition_router: - assert isinstance(stream.retriever.stream_slicer, PerPartitionWithGlobalCursor) - if isinstance(partition_router, list) and len(partition_router) > 1: - assert isinstance(stream.retriever.stream_slicer._partition_router, CartesianProductStreamSlicer) - assert len(stream.retriever.stream_slicer._partition_router.stream_slicers) == len(partition_router) - elif partition_router and isinstance(partition_router, list) and len(partition_router) > 1: - assert isinstance(stream.retriever.stream_slicer, PerPartitionWithGlobalCursor) - assert len(stream.retriever.stream_slicer.stream_slicerS) == len(partition_router) - - -def test_simple_retriever_emit_log_messages(): - simple_retriever_model = { - "type": "SimpleRetriever", - "record_selector": { - "type": "RecordSelector", - "extractor": { - "type": "DpathExtractor", - "field_path": [], - }, - }, - "requester": {"type": "HttpRequester", "name": "list", "url_base": "orange.com", "path": "/v1/api"}, - } - - connector_builder_factory = ModelToComponentFactory(emit_connector_builder_messages=True) - retriever = connector_builder_factory.create_component( - model_type=SimpleRetrieverModel, - component_definition=simple_retriever_model, - config={}, - name="Test", - primary_key="id", - stream_slicer=None, - transformations=[], - ) - - assert isinstance(retriever, SimpleRetrieverTestReadDecorator) - assert connector_builder_factory._message_repository._log_level == Level.DEBUG - - -def test_create_page_increment(): - model = PageIncrementModel( - type="PageIncrement", - page_size=10, - start_from_page=1, - inject_on_first_request=True, - ) - expected_strategy = PageIncrement(page_size=10, start_from_page=1, inject_on_first_request=True, parameters={}, config=input_config) - - strategy = factory.create_page_increment(model, input_config) - - assert strategy.page_size == expected_strategy.page_size - assert strategy.start_from_page == expected_strategy.start_from_page - assert strategy.inject_on_first_request == expected_strategy.inject_on_first_request - - -def test_create_page_increment_with_interpolated_page_size(): - model = PageIncrementModel( - type="PageIncrement", - page_size="{{ config['page_size'] }}", - start_from_page=1, - inject_on_first_request=True, - ) - config = {**input_config, "page_size": 5} - expected_strategy = PageIncrement(page_size=5, start_from_page=1, inject_on_first_request=True, parameters={}, config=config) - - strategy = factory.create_page_increment(model, config) - - assert strategy.get_page_size() == expected_strategy.get_page_size() - assert strategy.start_from_page == expected_strategy.start_from_page - assert strategy.inject_on_first_request == expected_strategy.inject_on_first_request - - -def test_create_offset_increment(): - model = OffsetIncrementModel( - type="OffsetIncrement", - page_size=10, - inject_on_first_request=True, - ) - expected_strategy = OffsetIncrement(page_size=10, inject_on_first_request=True, parameters={}, config=input_config) - - strategy = factory.create_offset_increment(model, input_config, decoder=JsonDecoder(parameters={})) - - assert strategy.page_size == expected_strategy.page_size - assert strategy.inject_on_first_request == expected_strategy.inject_on_first_request - assert strategy.config == input_config - - -class MyCustomSchemaLoader(SchemaLoader): - def get_json_schema(self) -> Mapping[str, Any]: - """Returns a mapping describing the stream's schema""" - return {} - - -def test_create_custom_schema_loader(): - - definition = { - "type": "CustomSchemaLoader", - "class_name": "unit_tests.sources.declarative.parsers.test_model_to_component_factory.MyCustomSchemaLoader", - } - component = factory.create_component(CustomSchemaLoaderModel, definition, {}) - assert isinstance(component, MyCustomSchemaLoader) - - -@freezegun.freeze_time("2021-01-01 00:00:00") -@pytest.mark.parametrize( - "config, manifest, expected", - [ - ( - { - "secret_key": "secret_key", - }, - """ - authenticator: - type: JwtAuthenticator - secret_key: "{{ config['secret_key'] }}" - algorithm: HS256 - """, - { - "secret_key": "secret_key", - "algorithm": "HS256", - "base64_encode_secret_key": False, - "token_duration": 1200, - "jwt_headers": {"typ": "JWT", "alg": "HS256"}, - "jwt_payload": {}, - }, - ), - ( - { - "secret_key": "secret_key", - "kid": "test kid", - "iss": "test iss", - "test": "test custom header", - }, - """ - authenticator: - type: JwtAuthenticator - secret_key: "{{ config['secret_key'] }}" - base64_encode_secret_key: True - algorithm: RS256 - token_duration: 3600 - header_prefix: Bearer - jwt_headers: - kid: "{{ config['kid'] }}" - cty: "JWT" - typ: "Alt" - additional_jwt_headers: - test: "{{ config['test']}}" - jwt_payload: - iss: "{{ config['iss'] }}" - sub: "test sub" - aud: "test aud" - additional_jwt_payload: - test: "test custom payload" - """, - { - "secret_key": "secret_key", - "algorithm": "RS256", - "base64_encode_secret_key": True, - "token_duration": 3600, - "header_prefix": "Bearer", - "jwt_headers": { - "kid": "test kid", - "typ": "Alt", - "alg": "RS256", - "cty": "JWT", - "test": "test custom header", - }, - "jwt_payload": { - "iss": "test iss", - "sub": "test sub", - "aud": "test aud", - "test": "test custom payload", - }, - }, - ), - ( - { - "secret_key": "secret_key", - }, - """ - authenticator: - type: JwtAuthenticator - secret_key: "{{ config['secret_key'] }}" - algorithm: HS256 - additional_jwt_headers: - custom_header: "custom header value" - additional_jwt_payload: - custom_payload: "custom payload value" - """, - { - "secret_key": "secret_key", - "algorithm": "HS256", - "base64_encode_secret_key": False, - "token_duration": 1200, - "jwt_headers": { - "typ": "JWT", - "alg": "HS256", - "custom_header": "custom header value", - }, - "jwt_payload": { - "custom_payload": "custom payload value", - }, - }, - ), - ( - { - "secret_key": "secret_key", - }, - """ - authenticator: - type: JwtAuthenticator - secret_key: "{{ config['secret_key'] }}" - algorithm: invalid_algorithm - """, - { - "expect_error": True, - }, - ), - ], -) -def test_create_jwt_authenticator(config, manifest, expected): - parsed_manifest = YamlDeclarativeSource._parse(manifest) - resolved_manifest = resolver.preprocess_manifest(parsed_manifest) - - authenticator_manifest = transformer.propagate_types_and_parameters("", resolved_manifest["authenticator"], {}) - - if expected.get("expect_error"): - with pytest.raises(ValueError): - authenticator = factory.create_component( - model_type=JwtAuthenticatorModel, component_definition=authenticator_manifest, config=config - ) - return - - authenticator = factory.create_component(model_type=JwtAuthenticatorModel, component_definition=authenticator_manifest, config=config) - - assert isinstance(authenticator, JwtAuthenticator) - assert authenticator._secret_key.eval(config) == expected["secret_key"] - assert authenticator._algorithm == expected["algorithm"] - assert authenticator._base64_encode_secret_key == expected["base64_encode_secret_key"] - assert authenticator._token_duration == expected["token_duration"] - if "header_prefix" in expected: - assert authenticator._header_prefix.eval(config) == expected["header_prefix"] - assert authenticator._get_jwt_headers() == expected["jwt_headers"] - jwt_payload = expected["jwt_payload"] - jwt_payload.update( - { - "iat": int(datetime.datetime.now().timestamp()), - "nbf": int(datetime.datetime.now().timestamp()), - "exp": int(datetime.datetime.now().timestamp()) + expected["token_duration"], - } - ) - assert authenticator._get_jwt_payload() == jwt_payload - - -def test_use_request_options_provider_for_datetime_based_cursor(): - config = { - "start_time": "2024-01-01T00:00:00.000000+0000", - } - - simple_retriever_model = { - "type": "SimpleRetriever", - "record_selector": { - "type": "RecordSelector", - "extractor": { - "type": "DpathExtractor", - "field_path": [], - }, - }, - "requester": {"type": "HttpRequester", "name": "list", "url_base": "orange.com", "path": "/v1/api"}, - } - - datetime_based_cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="{{ config.start_time }}", parameters={}), - step="P5D", - cursor_field="updated_at", - datetime_format="%Y-%m-%dT%H:%M:%S.%f%z", - cursor_granularity="PT1S", - is_compare_strictly=True, - config=config, - parameters={}, - ) - - datetime_based_request_options_provider = DatetimeBasedRequestOptionsProvider( - start_time_option=RequestOption( - inject_into=RequestOptionType.request_parameter, - field_name="after", - parameters={}, - ), - end_time_option=RequestOption( - inject_into=RequestOptionType.request_parameter, - field_name="before", - parameters={}, - ), - config=config, - parameters={}, - ) - - connector_builder_factory = ModelToComponentFactory(emit_connector_builder_messages=True) - retriever = connector_builder_factory.create_component( - model_type=SimpleRetrieverModel, - component_definition=simple_retriever_model, - config={}, - name="Test", - primary_key="id", - stream_slicer=datetime_based_cursor, - request_options_provider=datetime_based_request_options_provider, - transformations=[], - ) - - assert isinstance(retriever, SimpleRetriever) - assert retriever.primary_key == "id" - assert retriever.name == "Test" - - assert isinstance(retriever.cursor, DatetimeBasedCursor) - assert isinstance(retriever.stream_slicer, DatetimeBasedCursor) - - assert isinstance(retriever.request_option_provider, DatetimeBasedRequestOptionsProvider) - assert retriever.request_option_provider.start_time_option.inject_into == RequestOptionType.request_parameter - assert retriever.request_option_provider.start_time_option.field_name.eval(config=input_config) == "after" - assert retriever.request_option_provider.end_time_option.inject_into == RequestOptionType.request_parameter - assert retriever.request_option_provider.end_time_option.field_name.eval(config=input_config) == "before" - assert retriever.request_option_provider._partition_field_start.string == "start_time" - assert retriever.request_option_provider._partition_field_end.string == "end_time" - - -def test_do_not_separate_request_options_provider_for_non_datetime_based_cursor(): - # This test validates that we're only using the dedicated RequestOptionsProvider for DatetimeBasedCursor and using the - # existing StreamSlicer for other types of cursors and partition routing. Once everything is migrated this test can be deleted - - config = { - "start_time": "2024-01-01T00:00:00.000000+0000", - } - - simple_retriever_model = { - "type": "SimpleRetriever", - "record_selector": { - "type": "RecordSelector", - "extractor": { - "type": "DpathExtractor", - "field_path": [], - }, - }, - "requester": {"type": "HttpRequester", "name": "list", "url_base": "orange.com", "path": "/v1/api"}, - } - - datetime_based_cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="{{ config.start_time }}", parameters={}), - step="P5D", - cursor_field="updated_at", - datetime_format="%Y-%m-%dT%H:%M:%S.%f%z", - cursor_granularity="PT1S", - is_compare_strictly=True, - config=config, - parameters={}, - ) - - list_partition_router = ListPartitionRouter( - cursor_field="id", - values=["four", "oh", "eight"], - config=config, - parameters={}, - ) - - per_partition_cursor = PerPartitionCursor( - cursor_factory=CursorFactory(lambda: datetime_based_cursor), - partition_router=list_partition_router, - ) - - connector_builder_factory = ModelToComponentFactory(emit_connector_builder_messages=True) - retriever = connector_builder_factory.create_component( - model_type=SimpleRetrieverModel, - component_definition=simple_retriever_model, - config={}, - name="Test", - primary_key="id", - stream_slicer=per_partition_cursor, - request_options_provider=None, - transformations=[], - ) - - assert isinstance(retriever, SimpleRetriever) - assert retriever.primary_key == "id" - assert retriever.name == "Test" - - assert isinstance(retriever.cursor, PerPartitionCursor) - assert isinstance(retriever.stream_slicer, PerPartitionCursor) - - assert isinstance(retriever.request_option_provider, PerPartitionCursor) - assert isinstance(retriever.request_option_provider._cursor_factory, CursorFactory) - assert retriever.request_option_provider._partition_router == list_partition_router - - -def test_use_default_request_options_provider(): - simple_retriever_model = { - "type": "SimpleRetriever", - "record_selector": { - "type": "RecordSelector", - "extractor": { - "type": "DpathExtractor", - "field_path": [], - }, - }, - "requester": {"type": "HttpRequester", "name": "list", "url_base": "orange.com", "path": "/v1/api"}, - } - - connector_builder_factory = ModelToComponentFactory(emit_connector_builder_messages=True) - retriever = connector_builder_factory.create_component( - model_type=SimpleRetrieverModel, - component_definition=simple_retriever_model, - config={}, - name="Test", - primary_key="id", - stream_slicer=None, - request_options_provider=None, - transformations=[], - ) - - assert isinstance(retriever, SimpleRetriever) - assert retriever.primary_key == "id" - assert retriever.name == "Test" - - assert isinstance(retriever.stream_slicer, SinglePartitionRouter) - assert isinstance(retriever.request_option_provider, DefaultRequestOptionsProvider) diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/parsers/testing_components.py b/airbyte-cdk/python/unit_tests/sources/declarative/parsers/testing_components.py deleted file mode 100644 index db85283b7c0f..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/parsers/testing_components.py +++ /dev/null @@ -1,36 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import dataclass, field -from typing import List, Optional - -from airbyte_cdk.sources.declarative.extractors import DpathExtractor -from airbyte_cdk.sources.declarative.partition_routers import SubstreamPartitionRouter -from airbyte_cdk.sources.declarative.requesters import RequestOption -from airbyte_cdk.sources.declarative.requesters.error_handlers import DefaultErrorHandler -from airbyte_cdk.sources.declarative.requesters.paginators import DefaultPaginator, PaginationStrategy - - -@dataclass -class TestingSomeComponent(DefaultErrorHandler): - """ - A basic test class with various field permutations used to test manifests with custom components - """ - - subcomponent_field_with_hint: DpathExtractor = field(default_factory=lambda: DpathExtractor(field_path=[], config={}, parameters={})) - basic_field: str = "" - optional_subcomponent_field: Optional[RequestOption] = None - list_of_subcomponents: List[RequestOption] = None - without_hint = None - paginator: DefaultPaginator = None - - -@dataclass -class TestingCustomSubstreamPartitionRouter(SubstreamPartitionRouter): - """ - A test class based on a SubstreamPartitionRouter used for testing manifests that use custom components. - """ - - custom_field: str - custom_pagination_strategy: PaginationStrategy diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/__init__.py deleted file mode 100644 index 1100c1c58cf5..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2022 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/test_cartesian_product_partition_router.py b/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/test_cartesian_product_partition_router.py deleted file mode 100644 index 2b9313b3ebd7..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/test_cartesian_product_partition_router.py +++ /dev/null @@ -1,232 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest as pytest -from airbyte_cdk.sources.declarative.datetime.min_max_datetime import MinMaxDatetime -from airbyte_cdk.sources.declarative.incremental.datetime_based_cursor import DatetimeBasedCursor -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.partition_routers import CartesianProductStreamSlicer, ListPartitionRouter -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType -from airbyte_cdk.sources.types import StreamSlice - - -@pytest.mark.parametrize( - "test_name, stream_slicers, expected_slices", - [ - ( - "test_single_stream_slicer", - [ListPartitionRouter(values=["customer", "store", "subscription"], cursor_field="owner_resource", config={}, parameters={})], - [ - StreamSlice(partition={"owner_resource": "customer"}, cursor_slice={}), - StreamSlice(partition={"owner_resource": "store"}, cursor_slice={}), - StreamSlice(partition={"owner_resource": "subscription"}, cursor_slice={}), - ], - ), - ( - "test_two_stream_slicers", - [ - ListPartitionRouter(values=["customer", "store", "subscription"], cursor_field="owner_resource", config={}, parameters={}), - ListPartitionRouter(values=["A", "B"], cursor_field="letter", config={}, parameters={}), - ], - [ - StreamSlice(partition={"owner_resource": "customer", "letter": "A"}, cursor_slice={}), - StreamSlice(partition={"owner_resource": "customer", "letter": "B"}, cursor_slice={}), - StreamSlice(partition={"owner_resource": "store", "letter": "A"}, cursor_slice={}), - StreamSlice(partition={"owner_resource": "store", "letter": "B"}, cursor_slice={}), - StreamSlice(partition={"owner_resource": "subscription", "letter": "A"}, cursor_slice={}), - StreamSlice(partition={"owner_resource": "subscription", "letter": "B"}, cursor_slice={}), - ], - ), - ( - "test_singledatetime", - [ - DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="2021-01-01", datetime_format="%Y-%m-%d", parameters={}), - end_datetime=MinMaxDatetime(datetime="2021-01-03", datetime_format="%Y-%m-%d", parameters={}), - step="P1D", - cursor_field=InterpolatedString.create("", parameters={}), - datetime_format="%Y-%m-%d", - cursor_granularity="P1D", - config={}, - parameters={}, - ), - ], - [ - StreamSlice(partition={}, cursor_slice={"start_time": "2021-01-01", "end_time": "2021-01-01"}), - StreamSlice(partition={}, cursor_slice={"start_time": "2021-01-02", "end_time": "2021-01-02"}), - StreamSlice(partition={}, cursor_slice={"start_time": "2021-01-03", "end_time": "2021-01-03"}), - ], - ), - ( - "test_list_and_datetime", - [ - ListPartitionRouter(values=["customer", "store", "subscription"], cursor_field="owner_resource", config={}, parameters={}), - DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="2021-01-01", datetime_format="%Y-%m-%d", parameters={}), - end_datetime=MinMaxDatetime(datetime="2021-01-03", datetime_format="%Y-%m-%d", parameters={}), - step="P1D", - cursor_field=InterpolatedString.create("", parameters={}), - datetime_format="%Y-%m-%d", - cursor_granularity="P1D", - config={}, - parameters={}, - ), - ], - [ - StreamSlice(partition={"owner_resource": "customer"}, cursor_slice={"start_time": "2021-01-01", "end_time": "2021-01-01"}), - StreamSlice(partition={"owner_resource": "customer"}, cursor_slice={"start_time": "2021-01-02", "end_time": "2021-01-02"}), - StreamSlice(partition={"owner_resource": "customer"}, cursor_slice={"start_time": "2021-01-03", "end_time": "2021-01-03"}), - StreamSlice(partition={"owner_resource": "store"}, cursor_slice={"start_time": "2021-01-01", "end_time": "2021-01-01"}), - StreamSlice(partition={"owner_resource": "store"}, cursor_slice={"start_time": "2021-01-02", "end_time": "2021-01-02"}), - StreamSlice(partition={"owner_resource": "store"}, cursor_slice={"start_time": "2021-01-03", "end_time": "2021-01-03"}), - StreamSlice( - partition={"owner_resource": "subscription"}, cursor_slice={"start_time": "2021-01-01", "end_time": "2021-01-01"} - ), - StreamSlice( - partition={"owner_resource": "subscription"}, cursor_slice={"start_time": "2021-01-02", "end_time": "2021-01-02"} - ), - StreamSlice( - partition={"owner_resource": "subscription"}, cursor_slice={"start_time": "2021-01-03", "end_time": "2021-01-03"} - ), - ], - ), - ], -) -def test_substream_slicer(test_name, stream_slicers, expected_slices): - slicer = CartesianProductStreamSlicer(stream_slicers=stream_slicers, parameters={}) - slices = [s for s in slicer.stream_slices()] - assert slices == expected_slices - - -def test_stream_slices_raises_exception_if_multiple_cursor_slice_components(): - stream_slicers = [ - DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="2021-01-01", datetime_format="%Y-%m-%d", parameters={}), - end_datetime=MinMaxDatetime(datetime="2021-01-03", datetime_format="%Y-%m-%d", parameters={}), - step="P1D", - cursor_field=InterpolatedString.create("", parameters={}), - datetime_format="%Y-%m-%d", - cursor_granularity="P1D", - config={}, - parameters={}, - ), - DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="2021-01-01", datetime_format="%Y-%m-%d", parameters={}), - end_datetime=MinMaxDatetime(datetime="2021-01-03", datetime_format="%Y-%m-%d", parameters={}), - step="P1D", - cursor_field=InterpolatedString.create("", parameters={}), - datetime_format="%Y-%m-%d", - cursor_granularity="P1D", - config={}, - parameters={}, - ), - ] - slicer = CartesianProductStreamSlicer(stream_slicers=stream_slicers, parameters={}) - with pytest.raises(ValueError): - list(slicer.stream_slices()) - - -@pytest.mark.parametrize( - "test_name, stream_1_request_option, stream_2_request_option, expected_req_params, expected_headers,expected_body_json, expected_body_data", - [ - ( - "test_param_header", - RequestOption(inject_into=RequestOptionType.request_parameter, parameters={}, field_name="owner"), - RequestOption(inject_into=RequestOptionType.header, parameters={}, field_name="repo"), - {"owner": "customer"}, - {"repo": "airbyte"}, - {}, - {}, - ), - ( - "test_header_header", - RequestOption(inject_into=RequestOptionType.header, parameters={}, field_name="owner"), - RequestOption(inject_into=RequestOptionType.header, parameters={}, field_name="repo"), - {}, - {"owner": "customer", "repo": "airbyte"}, - {}, - {}, - ), - ( - "test_body_data", - RequestOption(inject_into=RequestOptionType.body_data, parameters={}, field_name="owner"), - RequestOption(inject_into=RequestOptionType.body_data, parameters={}, field_name="repo"), - {}, - {}, - {}, - {"owner": "customer", "repo": "airbyte"}, - ), - ( - "test_body_json", - RequestOption(inject_into=RequestOptionType.body_json, parameters={}, field_name="owner"), - RequestOption(inject_into=RequestOptionType.body_json, parameters={}, field_name="repo"), - {}, - {}, - {"owner": "customer", "repo": "airbyte"}, - {}, - ), - ], -) -def test_request_option( - test_name, - stream_1_request_option, - stream_2_request_option, - expected_req_params, - expected_headers, - expected_body_json, - expected_body_data, -): - slicer = CartesianProductStreamSlicer( - stream_slicers=[ - ListPartitionRouter( - values=["customer", "store", "subscription"], - cursor_field="owner_resource", - config={}, - request_option=stream_1_request_option, - parameters={}, - ), - ListPartitionRouter( - values=["airbyte", "airbyte-cloud"], - cursor_field="repository", - config={}, - request_option=stream_2_request_option, - parameters={}, - ), - ], - parameters={}, - ) - stream_slice = {"owner_resource": "customer", "repository": "airbyte"} - - assert slicer.get_request_params(stream_slice=stream_slice) == expected_req_params - assert slicer.get_request_headers(stream_slice=stream_slice) == expected_headers - assert slicer.get_request_body_json(stream_slice=stream_slice) == expected_body_json - assert slicer.get_request_body_data(stream_slice=stream_slice) == expected_body_data - - -def test_request_option_before_updating_cursor(): - stream_1_request_option = RequestOption(inject_into=RequestOptionType.request_parameter, parameters={}, field_name="owner") - stream_2_request_option = RequestOption(inject_into=RequestOptionType.header, parameters={}, field_name="repo") - slicer = CartesianProductStreamSlicer( - stream_slicers=[ - ListPartitionRouter( - values=["customer", "store", "subscription"], - cursor_field="owner_resource", - config={}, - request_option=stream_1_request_option, - parameters={}, - ), - ListPartitionRouter( - values=["airbyte", "airbyte-cloud"], - cursor_field="repository", - config={}, - request_option=stream_2_request_option, - parameters={}, - ), - ], - parameters={}, - ) - assert {} == slicer.get_request_params() - assert {} == slicer.get_request_headers() - assert {} == slicer.get_request_body_json() - assert {} == slicer.get_request_body_data() diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/test_list_partition_router.py b/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/test_list_partition_router.py deleted file mode 100644 index 87aa18f5a0b4..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/test_list_partition_router.py +++ /dev/null @@ -1,161 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest as pytest -from airbyte_cdk.sources.declarative.partition_routers.list_partition_router import ListPartitionRouter -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType -from airbyte_cdk.sources.types import StreamSlice - -partition_values = ["customer", "store", "subscription"] -cursor_field = "owner_resource" -parameters = {"cursor_field": "owner_resource"} - - -@pytest.mark.parametrize( - "partition_values, cursor_field, expected_slices", - [ - ( - ["customer", "store", "subscription"], - "owner_resource", - [ - StreamSlice(partition={"owner_resource": "customer"}, cursor_slice={}), - StreamSlice(partition={"owner_resource": "store"}, cursor_slice={}), - StreamSlice(partition={"owner_resource": "subscription"}, cursor_slice={}), - ], - ), - ( - '["customer", "store", "subscription"]', - "owner_resource", - [ - StreamSlice(partition={"owner_resource": "customer"}, cursor_slice={}), - StreamSlice(partition={"owner_resource": "store"}, cursor_slice={}), - StreamSlice(partition={"owner_resource": "subscription"}, cursor_slice={}), - ], - ), - ( - '["customer", "store", "subscription"]', - "{{ parameters['cursor_field'] }}", - [ - StreamSlice(partition={"owner_resource": "customer"}, cursor_slice={}), - StreamSlice(partition={"owner_resource": "store"}, cursor_slice={}), - StreamSlice(partition={"owner_resource": "subscription"}, cursor_slice={}), - ], - ), - ], - ids=[ - "test_single_element", - "test_input_list_is_string", - "test_using_cursor_from_parameters", - ], -) -def test_list_partition_router(partition_values, cursor_field, expected_slices): - slicer = ListPartitionRouter(values=partition_values, cursor_field=cursor_field, config={}, parameters=parameters) - slices = [s for s in slicer.stream_slices()] - assert slices == expected_slices - assert all(isinstance(s, StreamSlice) for s in slices) - - -@pytest.mark.parametrize( - "request_option, expected_req_params, expected_headers, expected_body_json, expected_body_data", - [ - ( - RequestOption(inject_into=RequestOptionType.request_parameter, parameters={}, field_name="owner_resource"), - {"owner_resource": "customer"}, - {}, - {}, - {}, - ), - ( - RequestOption(inject_into=RequestOptionType.header, parameters={}, field_name="owner_resource"), - {}, - {"owner_resource": "customer"}, - {}, - {}, - ), - ( - RequestOption(inject_into=RequestOptionType.body_json, parameters={}, field_name="owner_resource"), - {}, - {}, - {"owner_resource": "customer"}, - {}, - ), - ( - RequestOption(inject_into=RequestOptionType.body_data, parameters={}, field_name="owner_resource"), - {}, - {}, - {}, - {"owner_resource": "customer"}, - ), - ], - ids=[ - "test_inject_into_req_param", - "test_pass_by_header", - "test_inject_into_body_json", - "test_inject_into_body_data", - ], -) -def test_request_option(request_option, expected_req_params, expected_headers, expected_body_json, expected_body_data): - partition_router = ListPartitionRouter( - values=partition_values, cursor_field=cursor_field, config={}, request_option=request_option, parameters={} - ) - stream_slice = {cursor_field: "customer"} - - assert partition_router.get_request_params(stream_slice=stream_slice) == expected_req_params - assert partition_router.get_request_headers(stream_slice=stream_slice) == expected_headers - assert partition_router.get_request_body_json(stream_slice=stream_slice) == expected_body_json - assert partition_router.get_request_body_data(stream_slice=stream_slice) == expected_body_data - - -@pytest.mark.parametrize( - "stream_slice", - [ - pytest.param({}, id="test_request_option_is_empty_if_empty_stream_slice"), - pytest.param({"not the cursor": "value"}, id="test_request_option_is_empty_if_the_stream_slice_does_not_have_cursor_field"), - pytest.param(None, id="test_request_option_is_empty_if_no_stream_slice"), - ], -) -def test_request_option_is_empty_if_no_stream_slice(stream_slice): - request_option = RequestOption(inject_into=RequestOptionType.body_data, parameters={}, field_name="owner_resource") - partition_router = ListPartitionRouter( - values=partition_values, cursor_field=cursor_field, config={}, request_option=request_option, parameters={} - ) - assert {} == partition_router.get_request_body_data(stream_slice=stream_slice) - - -@pytest.mark.parametrize( - "field_name_interpolation, expected_request_params", - [ - ("{{parameters['partition_name']}}", {"parameters_partition": "customer"}), - ("{{config['partition_name']}}", {"config_partition": "customer"}), - ], - ids=[ - "parameters_interpolation", - "config_interpolation", - ], -) -def test_request_options_interpolation(field_name_interpolation: str, expected_request_params: dict): - config = {"partition_name": "config_partition"} - parameters = {"partition_name": "parameters_partition"} - request_option = RequestOption( - inject_into=RequestOptionType.request_parameter, parameters=parameters, field_name=field_name_interpolation - ) - partition_router = ListPartitionRouter( - values=partition_values, cursor_field=cursor_field, config=config, request_option=request_option, parameters=parameters - ) - stream_slice = {cursor_field: "customer"} - - assert partition_router.get_request_params(stream_slice=stream_slice) == expected_request_params - - -def test_request_option_before_updating_cursor(): - request_option = RequestOption(inject_into=RequestOptionType.request_parameter, parameters={}, field_name="owner_resource") - partition_router = ListPartitionRouter( - values=partition_values, cursor_field=cursor_field, config={}, request_option=request_option, parameters={} - ) - stream_slice = {cursor_field: "customer"} - - assert {} == partition_router.get_request_params(stream_slice) - assert {} == partition_router.get_request_headers() - assert {} == partition_router.get_request_body_json() - assert {} == partition_router.get_request_body_data() diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/test_parent_state_stream.py b/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/test_parent_state_stream.py deleted file mode 100644 index 8b820e490101..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/test_parent_state_stream.py +++ /dev/null @@ -1,1597 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -import copy -from typing import Any, List, Mapping, MutableMapping, Optional, Union -from unittest.mock import MagicMock - -import pytest -import requests_mock -from airbyte_cdk.models import ( - AirbyteMessage, - AirbyteStateBlob, - AirbyteStateMessage, - AirbyteStateType, - AirbyteStream, - AirbyteStreamState, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteStream, - DestinationSyncMode, - StreamDescriptor, - SyncMode, -) -from airbyte_cdk.sources.declarative.manifest_declarative_source import ManifestDeclarativeSource -from orjson import orjson - -SUBSTREAM_MANIFEST: MutableMapping[str, Any] = { - "version": "0.51.42", - "type": "DeclarativeSource", - "check": {"type": "CheckStream", "stream_names": ["post_comment_votes"]}, - "definitions": { - "basic_authenticator": { - "type": "BasicHttpAuthenticator", - "username": "{{ config['credentials']['email'] + '/token' }}", - "password": "{{ config['credentials']['api_token'] }}", - }, - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "url_base": "https://api.example.com", - "http_method": "GET", - "authenticator": "#/definitions/basic_authenticator", - }, - "record_selector": { - "type": "RecordSelector", - "extractor": { - "type": "DpathExtractor", - "field_path": ["{{ parameters.get('data_path') or parameters['name'] }}"], - }, - "schema_normalization": "Default", - }, - "paginator": { - "type": "DefaultPaginator", - "page_size_option": {"type": "RequestOption", "field_name": "per_page", "inject_into": "request_parameter"}, - "pagination_strategy": { - "type": "CursorPagination", - "page_size": 100, - "cursor_value": "{{ response.get('next_page', {}) }}", - "stop_condition": "{{ not response.get('next_page', {}) }}", - }, - "page_token_option": {"type": "RequestPath"}, - }, - }, - "cursor_incremental_sync": { - "type": "DatetimeBasedCursor", - "cursor_datetime_formats": ["%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%S%z"], - "datetime_format": "%Y-%m-%dT%H:%M:%SZ", - "cursor_field": "{{ parameters.get('cursor_field', 'updated_at') }}", - "start_datetime": {"datetime": "{{ config.get('start_date')}}"}, - "start_time_option": {"inject_into": "request_parameter", "field_name": "start_time", "type": "RequestOption"}, - }, - "posts_stream": { - "type": "DeclarativeStream", - "name": "posts", - "primary_key": ["id"], - "schema_loader": { - "type": "InlineSchemaLoader", - "schema": { - "$schema": "http://json-schema.org/schema#", - "properties": { - "id": {"type": "integer"}, - "updated_at": {"type": "string", "format": "date-time"}, - "title": {"type": "string"}, - "content": {"type": "string"}, - }, - "type": "object", - }, - }, - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "url_base": "https://api.example.com", - "path": "/community/posts", - "http_method": "GET", - "authenticator": "#/definitions/basic_authenticator", - }, - "record_selector": "#/definitions/retriever/record_selector", - "paginator": "#/definitions/retriever/paginator", - }, - "incremental_sync": "#/definitions/cursor_incremental_sync", - "$parameters": { - "name": "posts", - "path": "community/posts", - "data_path": "posts", - "cursor_field": "updated_at", - "primary_key": "id", - }, - }, - "post_comments_stream": { - "type": "DeclarativeStream", - "name": "post_comments", - "primary_key": ["id"], - "schema_loader": { - "type": "InlineSchemaLoader", - "schema": { - "$schema": "http://json-schema.org/schema#", - "properties": { - "id": {"type": "integer"}, - "updated_at": {"type": "string", "format": "date-time"}, - "post_id": {"type": "integer"}, - "comment": {"type": "string"}, - }, - "type": "object", - }, - }, - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "url_base": "https://api.example.com", - "path": "/community/posts/{{ stream_slice.id }}/comments", - "http_method": "GET", - "authenticator": "#/definitions/basic_authenticator", - }, - "record_selector": { - "type": "RecordSelector", - "extractor": {"type": "DpathExtractor", "field_path": ["comments"]}, - "record_filter": { - "condition": "{{ record['updated_at'] >= stream_state.get('updated_at', config.get('start_date')) }}" - }, - }, - "paginator": "#/definitions/retriever/paginator", - "partition_router": { - "type": "SubstreamPartitionRouter", - "parent_stream_configs": [ - { - "stream": "#/definitions/posts_stream", - "parent_key": "id", - "partition_field": "id", - "incremental_dependency": True, - } - ], - }, - }, - "incremental_sync": { - "type": "DatetimeBasedCursor", - "cursor_datetime_formats": ["%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%S%z"], - "datetime_format": "%Y-%m-%dT%H:%M:%SZ", - "cursor_field": "{{ parameters.get('cursor_field', 'updated_at') }}", - "start_datetime": {"datetime": "{{ config.get('start_date') }}"}, - }, - "$parameters": { - "name": "post_comments", - "path": "community/posts/{{ stream_slice.id }}/comments", - "data_path": "comments", - "cursor_field": "updated_at", - "primary_key": "id", - }, - }, - "post_comment_votes_stream": { - "type": "DeclarativeStream", - "name": "post_comment_votes", - "primary_key": ["id"], - "schema_loader": { - "type": "InlineSchemaLoader", - "schema": { - "$schema": "http://json-schema.org/schema#", - "properties": { - "id": {"type": "integer"}, - "created_at": {"type": "string", "format": "date-time"}, - "comment_id": {"type": "integer"}, - "vote": {"type": "number"}, - }, - "type": "object", - }, - }, - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "url_base": "https://api.example.com", - "path": "/community/posts/{{ stream_slice.parent_slice.id }}/comments/{{ stream_slice.id }}/votes", - "http_method": "GET", - "authenticator": "#/definitions/basic_authenticator", - }, - "record_selector": "#/definitions/retriever/record_selector", - "paginator": "#/definitions/retriever/paginator", - "partition_router": { - "type": "SubstreamPartitionRouter", - "parent_stream_configs": [ - { - "stream": "#/definitions/post_comments_stream", - "parent_key": "id", - "partition_field": "id", - "incremental_dependency": True, - } - ], - }, - }, - "incremental_sync": "#/definitions/cursor_incremental_sync", - "$parameters": { - "name": "post_comment_votes", - "path": "community/posts/{{ stream_slice.parent_slice.id }}/comments/{{ stream_slice.id }}/votes", - "data_path": "votes", - "cursor_field": "created_at", - "primary_key": "id", - }, - }, - }, - "streams": [ - {"$ref": "#/definitions/posts_stream"}, - {"$ref": "#/definitions/post_comments_stream"}, - {"$ref": "#/definitions/post_comment_votes_stream"}, - ], -} - - -def _run_read( - manifest: Mapping[str, Any], - config: Mapping[str, Any], - stream_name: str, - state: Optional[Union[List[AirbyteStateMessage], MutableMapping[str, Any]]] = None, -) -> List[AirbyteMessage]: - source = ManifestDeclarativeSource(source_config=manifest) - catalog = ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=AirbyteStream(name=stream_name, json_schema={}, supported_sync_modes=[SyncMode.full_refresh, SyncMode.incremental]), - sync_mode=SyncMode.incremental, - destination_sync_mode=DestinationSyncMode.append, - ) - ] - ) - logger = MagicMock() - return list(source.read(logger, config, catalog, state)) - - -def run_incremental_parent_state_test(manifest, mock_requests, expected_records, initial_state, expected_states): - """ - Run an incremental parent state test for the specified stream. - - This function performs the following steps: - 1. Mocks the API requests as defined in mock_requests. - 2. Executes the read operation using the provided manifest and config. - 3. Asserts that the output records match the expected records. - 4. Collects intermediate states and records, performing additional reads as necessary. - 5. Compares the cumulative records from each state against the expected records. - 6. Asserts that the final state matches one of the expected states for each run. - - Args: - manifest (dict): The manifest configuration for the stream. - mock_requests (list): A list of tuples containing URL and response data for mocking API requests. - expected_records (list): The expected records to compare against the output. - initial_state (list): The initial state to start the read operation. - expected_states (list): A list of expected final states after the read operation. - """ - _stream_name = "post_comment_votes" - config = {"start_date": "2024-01-01T00:00:01Z", "credentials": {"email": "email", "api_token": "api_token"}} - - with requests_mock.Mocker() as m: - for url, response in mock_requests: - m.get(url, json=response) - - # Run the initial read - output = _run_read(manifest, config, _stream_name, initial_state) - output_data = [message.record.data for message in output if message.record] - - # Assert that output_data equals expected_records - assert output_data == expected_records - - # Collect the intermediate states and records produced before each state - cumulative_records = [] - intermediate_states = [] - final_states = [] # To store the final state after each read - - # Store the final state after the initial read - final_state_initial = [orjson.loads(orjson.dumps(message.state.stream.stream_state)) for message in output if message.state] - final_states.append(final_state_initial[-1]) - - for message in output: - if message.type.value == "RECORD": - record_data = message.record.data - cumulative_records.append(record_data) - elif message.type.value == "STATE": - # Record the state and the records produced before this state - state = message.state - records_before_state = cumulative_records.copy() - intermediate_states.append((state, records_before_state)) - - # For each intermediate state, perform another read starting from that state - for state, records_before_state in intermediate_states[:-1]: - output_intermediate = _run_read(manifest, config, _stream_name, [state]) - records_from_state = [message.record.data for message in output_intermediate if message.record] - - # Combine records produced before the state with records from the new read - cumulative_records_state = records_before_state + records_from_state - - # Duplicates may occur because the state matches the cursor of the last record, causing it to be re-emitted in the next sync. - cumulative_records_state_deduped = list({orjson.dumps(record): record for record in cumulative_records_state}.values()) - - # Compare the cumulative records with the expected records - expected_records_set = list({orjson.dumps(record): record for record in expected_records}.values()) - assert sorted(cumulative_records_state_deduped, key=lambda x: orjson.dumps(x)) == sorted( - expected_records_set, key=lambda x: orjson.dumps(x) - ), f"Records mismatch with intermediate state {state}. Expected {expected_records}, got {cumulative_records_state_deduped}" - - # Store the final state after each intermediate read - final_state_intermediate = [ - orjson.loads(orjson.dumps(message.state.stream.stream_state)) for message in output_intermediate if message.state - ] - final_states.append(final_state_intermediate[-1]) - - # Assert that the final state matches the expected state for all runs - for i, final_state in enumerate(final_states): - assert final_state in expected_states, f"Final state mismatch at run {i + 1}. Expected {expected_states}, got {final_state}" - - -@pytest.mark.parametrize( - "test_name, manifest, mock_requests, expected_records, initial_state, expected_state", - [ - ( - "test_incremental_parent_state", - SUBSTREAM_MANIFEST, - [ - # Fetch the first page of posts - ( - "https://api.example.com/community/posts?per_page=100&start_time=2024-01-05T00:00:00Z", - { - "posts": [{"id": 1, "updated_at": "2024-01-30T00:00:00Z"}, {"id": 2, "updated_at": "2024-01-29T00:00:00Z"}], - "next_page": "https://api.example.com/community/posts?per_page=100&start_time=2024-01-05T00:00:00Z&page=2", - }, - ), - # Fetch the second page of posts - ( - "https://api.example.com/community/posts?per_page=100&start_time=2024-01-05T00:00:00Z&page=2", - {"posts": [{"id": 3, "updated_at": "2024-01-28T00:00:00Z"}]}, - ), - # Fetch the first page of comments for post 1 - ( - "https://api.example.com/community/posts/1/comments?per_page=100", - { - "comments": [ - {"id": 9, "post_id": 1, "updated_at": "2023-01-01T00:00:00Z"}, - {"id": 10, "post_id": 1, "updated_at": "2024-01-25T00:00:00Z"}, - {"id": 11, "post_id": 1, "updated_at": "2024-01-24T00:00:00Z"}, - ], - "next_page": "https://api.example.com/community/posts/1/comments?per_page=100&page=2", - }, - ), - # Fetch the second page of comments for post 1 - ( - "https://api.example.com/community/posts/1/comments?per_page=100&page=2", - {"comments": [{"id": 12, "post_id": 1, "updated_at": "2024-01-23T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 10 of post 1 - ( - "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&start_time=2024-01-02T00:00:00Z", - { - "votes": [{"id": 100, "comment_id": 10, "created_at": "2024-01-15T00:00:00Z"}], - "next_page": "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&page=2&start_time=2024-01-01T00:00:01Z", - }, - ), - # Fetch the second page of votes for comment 10 of post 1 - ( - "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&page=2&start_time=2024-01-01T00:00:01Z", - {"votes": [{"id": 101, "comment_id": 10, "created_at": "2024-01-14T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 11 of post 1 - ( - "https://api.example.com/community/posts/1/comments/11/votes?per_page=100&start_time=2024-01-03T00:00:00Z", - {"votes": [{"id": 102, "comment_id": 11, "created_at": "2024-01-13T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 12 of post 1 - ("https://api.example.com/community/posts/1/comments/12/votes?per_page=100&start_time=2024-01-01T00:00:01Z", {"votes": []}), - # Fetch the first page of comments for post 2 - ( - "https://api.example.com/community/posts/2/comments?per_page=100", - { - "comments": [{"id": 20, "post_id": 2, "updated_at": "2024-01-22T00:00:00Z"}], - "next_page": "https://api.example.com/community/posts/2/comments?per_page=100&page=2", - }, - ), - # Fetch the second page of comments for post 2 - ( - "https://api.example.com/community/posts/2/comments?per_page=100&page=2", - {"comments": [{"id": 21, "post_id": 2, "updated_at": "2024-01-21T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 20 of post 2 - ( - "https://api.example.com/community/posts/2/comments/20/votes?per_page=100&start_time=2024-01-01T00:00:01Z", - {"votes": [{"id": 200, "comment_id": 20, "created_at": "2024-01-12T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 21 of post 2 - ( - "https://api.example.com/community/posts/2/comments/21/votes?per_page=100&start_time=2024-01-01T00:00:01Z", - {"votes": [{"id": 201, "comment_id": 21, "created_at": "2024-01-12T00:00:15Z"}]}, - ), - # Fetch the first page of comments for post 3 - ( - "https://api.example.com/community/posts/3/comments?per_page=100", - {"comments": [{"id": 30, "post_id": 3, "updated_at": "2024-01-09T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 30 of post 3 - ( - "https://api.example.com/community/posts/3/comments/30/votes?per_page=100", - {"votes": [{"id": 300, "comment_id": 30, "created_at": "2024-01-10T00:00:00Z"}]}, - ), - # Requests with intermediate states - # Fetch votes for comment 10 of post 1 - ( - "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&start_time=2024-01-15T00:00:00Z", - { - "votes": [{"id": 100, "comment_id": 10, "created_at": "2024-01-15T00:00:00Z"}], - }, - ), - # Fetch votes for comment 11 of post 1 - ( - "https://api.example.com/community/posts/1/comments/11/votes?per_page=100&start_time=2024-01-13T00:00:00Z", - { - "votes": [{"id": 102, "comment_id": 11, "created_at": "2024-01-13T00:00:00Z"}], - }, - ), - # Fetch votes for comment 12 of post 1 - ( - "https://api.example.com/community/posts/1/comments/12/votes?per_page=100&start_time=2024-01-15T00:00:00Z", - { - "votes": [], - }, - ), - # Fetch votes for comment 20 of post 2 - ( - "https://api.example.com/community/posts/2/comments/20/votes?per_page=100&start_time=2024-01-12T00:00:00Z", - {"votes": [{"id": 200, "comment_id": 20, "created_at": "2024-01-12T00:00:00Z"}]}, - ), - # Fetch votes for comment 21 of post 2 - ( - "https://api.example.com/community/posts/2/comments/21/votes?per_page=100&start_time=2024-01-12T00:00:15Z", - {"votes": [{"id": 201, "comment_id": 21, "created_at": "2024-01-12T00:00:15Z"}]}, - ), - ], - # Expected records - [ - {"id": 100, "comment_id": 10, "created_at": "2024-01-15T00:00:00Z"}, - {"id": 101, "comment_id": 10, "created_at": "2024-01-14T00:00:00Z"}, - {"id": 102, "comment_id": 11, "created_at": "2024-01-13T00:00:00Z"}, - {"id": 200, "comment_id": 20, "created_at": "2024-01-12T00:00:00Z"}, - {"id": 201, "comment_id": 21, "created_at": "2024-01-12T00:00:15Z"}, - {"id": 300, "comment_id": 30, "created_at": "2024-01-10T00:00:00Z"}, - ], - # Initial state - [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="post_comment_votes", namespace=None), - stream_state=AirbyteStateBlob( - { - "parent_state": { - "post_comments": { - "states": [ - {"partition": {"id": 1, "parent_slice": {}}, "cursor": {"updated_at": "2023-01-04T00:00:00Z"}} - ], - "parent_state": {"posts": {"updated_at": "2024-01-05T00:00:00Z"}}, - } - }, - "states": [ - { - "partition": {"id": 10, "parent_slice": {"id": 1, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-02T00:00:00Z"}, - }, - { - "partition": {"id": 11, "parent_slice": {"id": 1, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-03T00:00:00Z"}, - }, - ], - } - ), - ), - ) - ], - # Expected state - { - "use_global_cursor": False, - "state": {"created_at": "2024-01-15T00:00:00Z"}, - "parent_state": { - "post_comments": { - "use_global_cursor": False, - "state": {"updated_at": "2024-01-25T00:00:00Z"}, - "parent_state": {"posts": {"updated_at": "2024-01-30T00:00:00Z"}}, - "lookback_window": 1, - "states": [ - {"partition": {"id": 1, "parent_slice": {}}, "cursor": {"updated_at": "2024-01-25T00:00:00Z"}}, - {"partition": {"id": 2, "parent_slice": {}}, "cursor": {"updated_at": "2024-01-22T00:00:00Z"}}, - {"partition": {"id": 3, "parent_slice": {}}, "cursor": {"updated_at": "2024-01-09T00:00:00Z"}}, - ], - } - }, - "lookback_window": 1, - "states": [ - { - "partition": {"id": 10, "parent_slice": {"id": 1, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-15T00:00:00Z"}, - }, - { - "partition": {"id": 11, "parent_slice": {"id": 1, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-13T00:00:00Z"}, - }, - { - "partition": {"id": 20, "parent_slice": {"id": 2, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-12T00:00:00Z"}, - }, - { - "partition": {"id": 21, "parent_slice": {"id": 2, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-12T00:00:15Z"}, - }, - { - "partition": {"id": 30, "parent_slice": {"id": 3, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-10T00:00:00Z"}, - }, - ], - }, - ), - ], -) -def test_incremental_parent_state(test_name, manifest, mock_requests, expected_records, initial_state, expected_state): - additional_expected_state = copy.deepcopy(expected_state) - # State for empty partition (comment 12), when the global cursor is used for intermediate states - empty_state = {"cursor": {"created_at": "2024-01-15T00:00:00Z"}, "partition": {"id": 12, "parent_slice": {"id": 1, "parent_slice": {}}}} - additional_expected_state["states"].append(empty_state) - run_incremental_parent_state_test(manifest, mock_requests, expected_records, initial_state, [expected_state, additional_expected_state]) - - -@pytest.mark.parametrize( - "test_name, manifest, mock_requests, expected_records, initial_state, expected_state", - [ - ( - "test_incremental_parent_state", - SUBSTREAM_MANIFEST, - [ - # Fetch the first page of posts - ( - "https://api.example.com/community/posts?per_page=100&start_time=2024-01-05T00:00:00Z", - { - "posts": [], - "next_page": "https://api.example.com/community/posts?per_page=100&start_time=2024-01-05T00:00:00Z&page=2", - }, - ), - # Fetch the second page of posts - ( - "https://api.example.com/community/posts?per_page=100&start_time=2024-01-05T00:00:00Z&page=2", - {"posts": []}, - ), - # Fetch the first page of comments for post 1 - ( - "https://api.example.com/community/posts/1/comments?per_page=100", - { - "comments": [], - "next_page": "https://api.example.com/community/posts/1/comments?per_page=100&page=2", - }, - ), - # Fetch the second page of comments for post 1 - ( - "https://api.example.com/community/posts/1/comments?per_page=100&page=2", - {"comments": []}, - ), - # Fetch the first page of votes for comment 10 of post 1 - ( - "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&start_time=2024-01-02T00:00:00Z", - { - "votes": [], - "next_page": "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&page=2&start_time=2024-01-01T00:00:01Z", - }, - ), - # Fetch the second page of votes for comment 10 of post 1 - ( - "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&page=2&start_time=2024-01-01T00:00:01Z", - {"votes": []}, - ), - # Fetch the first page of votes for comment 11 of post 1 - ( - "https://api.example.com/community/posts/1/comments/11/votes?per_page=100&start_time=2024-01-03T00:00:00Z", - {"votes": []}, - ), - # Fetch the first page of votes for comment 12 of post 1 - ("https://api.example.com/community/posts/1/comments/12/votes?per_page=100&start_time=2024-01-01T00:00:01Z", {"votes": []}), - # Fetch the first page of comments for post 2 - ( - "https://api.example.com/community/posts/2/comments?per_page=100", - { - "comments": [], - "next_page": "https://api.example.com/community/posts/2/comments?per_page=100&page=2", - }, - ), - # Fetch the second page of comments for post 2 - ( - "https://api.example.com/community/posts/2/comments?per_page=100&page=2", - {"comments": []}, - ), - # Fetch the first page of votes for comment 20 of post 2 - ( - "https://api.example.com/community/posts/2/comments/20/votes?per_page=100&start_time=2024-01-01T00:00:01Z", - {"votes": []}, - ), - # Fetch the first page of votes for comment 21 of post 2 - ( - "https://api.example.com/community/posts/2/comments/21/votes?per_page=100&start_time=2024-01-01T00:00:01Z", - {"votes": []}, - ), - # Fetch the first page of comments for post 3 - ( - "https://api.example.com/community/posts/3/comments?per_page=100", - {"comments": []}, - ), - # Fetch the first page of votes for comment 30 of post 3 - ( - "https://api.example.com/community/posts/3/comments/30/votes?per_page=100", - {"votes": []}, - ), - ], - # Expected records - [], - # Initial state - [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="post_comment_votes", namespace=None), - stream_state=AirbyteStateBlob( - { - "parent_state": { - "post_comments": { - "states": [ - {"partition": {"id": 1, "parent_slice": {}}, "cursor": {"updated_at": "2023-01-04T00:00:00Z"}} - ], - "parent_state": {"posts": {"updated_at": "2024-01-05T00:00:00Z"}}, - } - }, - "states": [ - { - "partition": {"id": 10, "parent_slice": {"id": 1, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-02T00:00:00Z"}, - }, - { - "partition": {"id": 11, "parent_slice": {"id": 1, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-03T00:00:00Z"}, - }, - ], - "state": {"created_at": "2024-01-03T00:00:00Z"}, - "lookback_window": 1, - } - ), - ), - ) - ], - # Expected state - { - "lookback_window": 1, - "use_global_cursor": False, - "state": {"created_at": "2024-01-03T00:00:00Z"}, - "parent_state": { - "post_comments": { - "use_global_cursor": False, - "state": {}, - "parent_state": {"posts": {"updated_at": "2024-01-05T00:00:00Z"}}, - "states": [{"partition": {"id": 1, "parent_slice": {}}, "cursor": {"updated_at": "2023-01-04T00:00:00Z"}}], - } - }, - "states": [ - { - "partition": {"id": 10, "parent_slice": {"id": 1, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-02T00:00:00Z"}, - }, - { - "partition": {"id": 11, "parent_slice": {"id": 1, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-03T00:00:00Z"}, - }, - ], - }, - ), - ], -) -def test_incremental_parent_state_no_slices(test_name, manifest, mock_requests, expected_records, initial_state, expected_state): - """ - Test incremental partition router with no parent records - """ - _stream_name = "post_comment_votes" - config = {"start_date": "2024-01-01T00:00:01Z", "credentials": {"email": "email", "api_token": "api_token"}} - - with requests_mock.Mocker() as m: - for url, response in mock_requests: - m.get(url, json=response) - - output = _run_read(manifest, config, _stream_name, initial_state) - output_data = [message.record.data for message in output if message.record] - - assert output_data == expected_records - final_state = [orjson.loads(orjson.dumps(message.state.stream.stream_state)) for message in output if message.state] - assert final_state[-1] == expected_state - - -@pytest.mark.parametrize( - "test_name, manifest, mock_requests, expected_records, initial_state, expected_state", - [ - ( - "test_incremental_parent_state", - SUBSTREAM_MANIFEST, - [ - # Fetch the first page of posts - ( - "https://api.example.com/community/posts?per_page=100&start_time=2024-01-05T00:00:00Z", - { - "posts": [{"id": 1, "updated_at": "2024-01-30T00:00:00Z"}, {"id": 2, "updated_at": "2024-01-29T00:00:00Z"}], - "next_page": "https://api.example.com/community/posts?per_page=100&start_time=2024-01-05T00:00:00Z&page=2", - }, - ), - # Fetch the second page of posts - ( - "https://api.example.com/community/posts?per_page=100&start_time=2024-01-05T00:00:00Z&page=2", - {"posts": [{"id": 3, "updated_at": "2024-01-28T00:00:00Z"}]}, - ), - # Fetch the first page of comments for post 1 - ( - "https://api.example.com/community/posts/1/comments?per_page=100", - { - "comments": [ - {"id": 9, "post_id": 1, "updated_at": "2023-01-01T00:00:00Z"}, - {"id": 10, "post_id": 1, "updated_at": "2024-01-25T00:00:00Z"}, - {"id": 11, "post_id": 1, "updated_at": "2024-01-24T00:00:00Z"}, - ], - "next_page": "https://api.example.com/community/posts/1/comments?per_page=100&page=2", - }, - ), - # Fetch the second page of comments for post 1 - ( - "https://api.example.com/community/posts/1/comments?per_page=100&page=2", - {"comments": [{"id": 12, "post_id": 1, "updated_at": "2024-01-23T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 10 of post 1 - ( - "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&start_time=2024-01-03T00:00:00Z", - { - "votes": [], - "next_page": "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&page=2&start_time=2024-01-01T00:00:01Z", - }, - ), - # Fetch the second page of votes for comment 10 of post 1 - ( - "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&page=2&start_time=2024-01-01T00:00:01Z", - {"votes": []}, - ), - # Fetch the first page of votes for comment 11 of post 1 - ( - "https://api.example.com/community/posts/1/comments/11/votes?per_page=100&start_time=2024-01-03T00:00:00Z", - {"votes": []}, - ), - # Fetch the first page of votes for comment 12 of post 1 - ("https://api.example.com/community/posts/1/comments/12/votes?per_page=100&start_time=2024-01-03T00:00:00Z", {"votes": []}), - # Fetch the first page of comments for post 2 - ( - "https://api.example.com/community/posts/2/comments?per_page=100", - { - "comments": [{"id": 20, "post_id": 2, "updated_at": "2024-01-22T00:00:00Z"}], - "next_page": "https://api.example.com/community/posts/2/comments?per_page=100&page=2", - }, - ), - # Fetch the second page of comments for post 2 - ( - "https://api.example.com/community/posts/2/comments?per_page=100&page=2", - {"comments": [{"id": 21, "post_id": 2, "updated_at": "2024-01-21T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 20 of post 2 - ( - "https://api.example.com/community/posts/2/comments/20/votes?per_page=100&start_time=2024-01-03T00:00:00Z", - {"votes": []}, - ), - # Fetch the first page of votes for comment 21 of post 2 - ( - "https://api.example.com/community/posts/2/comments/21/votes?per_page=100&start_time=2024-01-03T00:00:00Z", - {"votes": []}, - ), - # Fetch the first page of comments for post 3 - ( - "https://api.example.com/community/posts/3/comments?per_page=100", - {"comments": [{"id": 30, "post_id": 3, "updated_at": "2024-01-09T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 30 of post 3 - ( - "https://api.example.com/community/posts/3/comments/30/votes?per_page=100", - {"votes": []}, - ), - ], - # Expected records - [], - # Initial state - [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="post_comment_votes", namespace=None), - stream_state=AirbyteStateBlob( - { - "parent_state": { - "post_comments": { - "states": [ - {"partition": {"id": 1, "parent_slice": {}}, "cursor": {"updated_at": "2023-01-04T00:00:00Z"}} - ], - "parent_state": {"posts": {"updated_at": "2024-01-05T00:00:00Z"}}, - } - }, - "states": [ - { - "partition": {"id": 10, "parent_slice": {"id": 1, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-02T00:00:00Z"}, - }, - { - "partition": {"id": 11, "parent_slice": {"id": 1, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-03T00:00:00Z"}, - }, - ], - "use_global_cursor": True, - "state": {"created_at": "2024-01-03T00:00:00Z"}, - "lookback_window": 0, - } - ), - ), - ) - ], - # Expected state - { - "lookback_window": 1, - "use_global_cursor": True, - "state": {"created_at": "2024-01-03T00:00:00Z"}, - "parent_state": { - "post_comments": { - "use_global_cursor": False, - "state": {"updated_at": "2024-01-25T00:00:00Z"}, - "parent_state": {"posts": {"updated_at": "2024-01-30T00:00:00Z"}}, - "lookback_window": 1, - "states": [ - {"partition": {"id": 1, "parent_slice": {}}, "cursor": {"updated_at": "2024-01-25T00:00:00Z"}}, - {"partition": {"id": 2, "parent_slice": {}}, "cursor": {"updated_at": "2024-01-22T00:00:00Z"}}, - {"partition": {"id": 3, "parent_slice": {}}, "cursor": {"updated_at": "2024-01-09T00:00:00Z"}}, - ], - } - }, - }, - ), - ], -) -def test_incremental_parent_state_no_records(test_name, manifest, mock_requests, expected_records, initial_state, expected_state): - """ - Test incremental partition router with no child records - """ - _stream_name = "post_comment_votes" - config = {"start_date": "2024-01-01T00:00:01Z", "credentials": {"email": "email", "api_token": "api_token"}} - - with requests_mock.Mocker() as m: - for url, response in mock_requests: - m.get(url, json=response) - - output = _run_read(manifest, config, _stream_name, initial_state) - output_data = [message.record.data for message in output if message.record] - - assert output_data == expected_records - final_state = [orjson.loads(orjson.dumps(message.state.stream.stream_state)) for message in output if message.state] - assert final_state[-1] == expected_state - - -@pytest.mark.parametrize( - "test_name, manifest, mock_requests, expected_records, initial_state, expected_state", - [ - ( - "test_incremental_parent_state", - SUBSTREAM_MANIFEST, - [ - # Fetch the first page of posts - ( - "https://api.example.com/community/posts?per_page=100&start_time=2024-01-01T00:00:01Z", - { - "posts": [{"id": 1, "updated_at": "2024-01-30T00:00:00Z"}, {"id": 2, "updated_at": "2024-01-29T00:00:00Z"}], - "next_page": "https://api.example.com/community/posts?per_page=100&start_time=2024-01-05T00:00:00Z&page=2", - }, - ), - # Fetch the second page of posts - ( - "https://api.example.com/community/posts?per_page=100&start_time=2024-01-01T00:00:01Z&page=2", - {"posts": [{"id": 3, "updated_at": "2024-01-28T00:00:00Z"}]}, - ), - # Fetch the first page of comments for post 1 - ( - "https://api.example.com/community/posts/1/comments?per_page=100", - { - "comments": [ - {"id": 9, "post_id": 1, "updated_at": "2023-01-01T00:00:00Z"}, - {"id": 10, "post_id": 1, "updated_at": "2024-01-25T00:00:00Z"}, - {"id": 11, "post_id": 1, "updated_at": "2024-01-24T00:00:00Z"}, - ], - "next_page": "https://api.example.com/community/posts/1/comments?per_page=100&page=2", - }, - ), - # Fetch the second page of comments for post 1 - ( - "https://api.example.com/community/posts/1/comments?per_page=100&page=2", - {"comments": [{"id": 12, "post_id": 1, "updated_at": "2024-01-23T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 10 of post 1 - ( - "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&start_time=2024-01-02T00:00:00Z", - { - "votes": [{"id": 100, "comment_id": 10, "created_at": "2024-01-15T00:00:00Z"}], - "next_page": "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&page=2&start_time=2024-01-01T00:00:01Z", - }, - ), - # Fetch the second page of votes for comment 10 of post 1 - ( - "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&page=2&start_time=2024-01-01T00:00:01Z", - {"votes": [{"id": 101, "comment_id": 10, "created_at": "2024-01-14T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 11 of post 1 - ( - "https://api.example.com/community/posts/1/comments/11/votes?per_page=100&start_time=2024-01-03T00:00:00Z", - {"votes": [{"id": 102, "comment_id": 11, "created_at": "2024-01-13T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 12 of post 1 - ("https://api.example.com/community/posts/1/comments/12/votes?per_page=100&start_time=2024-01-01T00:00:01Z", {"votes": []}), - # Fetch the first page of comments for post 2 - ( - "https://api.example.com/community/posts/2/comments?per_page=100", - { - "comments": [{"id": 20, "post_id": 2, "updated_at": "2024-01-22T00:00:00Z"}], - "next_page": "https://api.example.com/community/posts/2/comments?per_page=100&page=2", - }, - ), - # Fetch the second page of comments for post 2 - ( - "https://api.example.com/community/posts/2/comments?per_page=100&page=2", - {"comments": [{"id": 21, "post_id": 2, "updated_at": "2024-01-21T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 20 of post 2 - ( - "https://api.example.com/community/posts/2/comments/20/votes?per_page=100&start_time=2024-01-01T00:00:01Z", - {"votes": [{"id": 200, "comment_id": 20, "created_at": "2024-01-12T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 21 of post 2 - ( - "https://api.example.com/community/posts/2/comments/21/votes?per_page=100&start_time=2024-01-01T00:00:01Z", - {"votes": [{"id": 201, "comment_id": 21, "created_at": "2024-01-12T00:00:15Z"}]}, - ), - # Fetch the first page of comments for post 3 - ( - "https://api.example.com/community/posts/3/comments?per_page=100", - {"comments": [{"id": 30, "post_id": 3, "updated_at": "2024-01-09T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 30 of post 3 - ( - "https://api.example.com/community/posts/3/comments/30/votes?per_page=100", - {"votes": [{"id": 300, "comment_id": 30, "created_at": "2024-01-10T00:00:00Z"}]}, - ), - ], - # Expected records - [ - {"id": 100, "comment_id": 10, "created_at": "2024-01-15T00:00:00Z"}, - {"id": 101, "comment_id": 10, "created_at": "2024-01-14T00:00:00Z"}, - {"id": 102, "comment_id": 11, "created_at": "2024-01-13T00:00:00Z"}, - {"id": 200, "comment_id": 20, "created_at": "2024-01-12T00:00:00Z"}, - {"id": 201, "comment_id": 21, "created_at": "2024-01-12T00:00:15Z"}, - {"id": 300, "comment_id": 30, "created_at": "2024-01-10T00:00:00Z"}, - ], - # Initial state - [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="post_comment_votes", namespace=None), - stream_state=AirbyteStateBlob( - { - # This should not happen since parent state is disabled, but I've added this to validate that and - # incoming parent_state is ignored when the parent stream's incremental_dependency is disabled - "parent_state": { - "post_comments": { - "states": [ - {"partition": {"id": 1, "parent_slice": {}}, "cursor": {"updated_at": "2023-01-04T00:00:00Z"}} - ], - "parent_state": {"posts": {"updated_at": "2024-01-05T00:00:00Z"}}, - } - }, - "states": [ - { - "partition": {"id": 10, "parent_slice": {"id": 1, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-02T00:00:00Z"}, - }, - { - "partition": {"id": 11, "parent_slice": {"id": 1, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-03T00:00:00Z"}, - }, - ], - } - ), - ), - ) - ], - # Expected state - { - "use_global_cursor": False, - "state": {"created_at": "2024-01-15T00:00:00Z"}, - "lookback_window": 1, - "states": [ - { - "partition": {"id": 10, "parent_slice": {"id": 1, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-15T00:00:00Z"}, - }, - { - "partition": {"id": 11, "parent_slice": {"id": 1, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-13T00:00:00Z"}, - }, - { - "partition": {"id": 20, "parent_slice": {"id": 2, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-12T00:00:00Z"}, - }, - { - "partition": {"id": 21, "parent_slice": {"id": 2, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-12T00:00:15Z"}, - }, - { - "partition": {"id": 30, "parent_slice": {"id": 3, "parent_slice": {}}}, - "cursor": {"created_at": "2024-01-10T00:00:00Z"}, - }, - ], - }, - ), - ], -) -def test_incremental_parent_state_no_incremental_dependency( - test_name, manifest, mock_requests, expected_records, initial_state, expected_state -): - """ - This is a pretty complicated test that syncs a low-code connector stream with three levels of substreams - - posts: (ids: 1, 2, 3) - - post comments: (parent post 1 with ids: 9, 10, 11, 12; parent post 2 with ids: 20, 21; parent post 3 with id: 30) - - post comment votes: (parent comment 10 with ids: 100, 101; parent comment 11 with id: 102; - parent comment 20 with id: 200; parent comment 21 with id: 201, parent comment 30 with id: 300) - - By setting incremental_dependency to false, parent streams will not use the incoming state and will not update state. - The post_comment_votes substream is incremental and will emit state messages We verify this by ensuring that mocked - parent stream requests use the incoming config as query parameters and the substream state messages does not - contain parent stream state. - """ - - _stream_name = "post_comment_votes" - config = {"start_date": "2024-01-01T00:00:01Z", "credentials": {"email": "email", "api_token": "api_token"}} - - # Disable incremental_dependency - manifest["definitions"]["post_comments_stream"]["retriever"]["partition_router"]["parent_stream_configs"][0][ - "incremental_dependency" - ] = False - manifest["definitions"]["post_comment_votes_stream"]["retriever"]["partition_router"]["parent_stream_configs"][0][ - "incremental_dependency" - ] = False - - with requests_mock.Mocker() as m: - for url, response in mock_requests: - m.get(url, json=response) - - output = _run_read(manifest, config, _stream_name, initial_state) - output_data = [message.record.data for message in output if message.record] - - assert output_data == expected_records - final_state = [orjson.loads(orjson.dumps(message.state.stream.stream_state)) for message in output if message.state] - assert final_state[-1] == expected_state - - -SUBSTREAM_MANIFEST_GLOBAL_PARENT_CURSOR: MutableMapping[str, Any] = { - "version": "0.51.42", - "type": "DeclarativeSource", - "check": {"type": "CheckStream", "stream_names": ["post_comment_votes"]}, - "definitions": { - "basic_authenticator": { - "type": "BasicHttpAuthenticator", - "username": "{{ config['credentials']['email'] + '/token' }}", - "password": "{{ config['credentials']['api_token'] }}", - }, - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "url_base": "https://api.example.com", - "http_method": "GET", - "authenticator": "#/definitions/basic_authenticator", - }, - "record_selector": { - "type": "RecordSelector", - "extractor": { - "type": "DpathExtractor", - "field_path": ["{{ parameters.get('data_path') or parameters['name'] }}"], - }, - "schema_normalization": "Default", - }, - "paginator": { - "type": "DefaultPaginator", - "page_size_option": {"type": "RequestOption", "field_name": "per_page", "inject_into": "request_parameter"}, - "pagination_strategy": { - "type": "CursorPagination", - "page_size": 100, - "cursor_value": "{{ response.get('next_page', {}) }}", - "stop_condition": "{{ not response.get('next_page', {}) }}", - }, - "page_token_option": {"type": "RequestPath"}, - }, - }, - "cursor_incremental_sync": { - "type": "DatetimeBasedCursor", - "cursor_datetime_formats": ["%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%S%z"], - "datetime_format": "%Y-%m-%dT%H:%M:%SZ", - "cursor_field": "{{ parameters.get('cursor_field', 'updated_at') }}", - "start_datetime": {"datetime": "{{ config.get('start_date')}}"}, - "start_time_option": {"inject_into": "request_parameter", "field_name": "start_time", "type": "RequestOption"}, - }, - "posts_stream": { - "type": "DeclarativeStream", - "name": "posts", - "primary_key": ["id"], - "schema_loader": { - "type": "InlineSchemaLoader", - "schema": { - "$schema": "http://json-schema.org/schema#", - "properties": { - "id": {"type": "integer"}, - "updated_at": {"type": "string", "format": "date-time"}, - "title": {"type": "string"}, - "content": {"type": "string"}, - }, - "type": "object", - }, - }, - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "url_base": "https://api.example.com", - "path": "/community/posts", - "http_method": "GET", - "authenticator": "#/definitions/basic_authenticator", - }, - "record_selector": "#/definitions/retriever/record_selector", - "paginator": "#/definitions/retriever/paginator", - }, - "incremental_sync": "#/definitions/cursor_incremental_sync", - "$parameters": { - "name": "posts", - "path": "community/posts", - "data_path": "posts", - "cursor_field": "updated_at", - "primary_key": "id", - }, - }, - "post_comments_stream": { - "type": "DeclarativeStream", - "name": "post_comments", - "primary_key": ["id"], - "schema_loader": { - "type": "InlineSchemaLoader", - "schema": { - "$schema": "http://json-schema.org/schema#", - "properties": { - "id": {"type": "integer"}, - "updated_at": {"type": "string", "format": "date-time"}, - "post_id": {"type": "integer"}, - "comment": {"type": "string"}, - }, - "type": "object", - }, - }, - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "url_base": "https://api.example.com", - "path": "/community/posts/{{ stream_slice.id }}/comments", - "http_method": "GET", - "authenticator": "#/definitions/basic_authenticator", - }, - "record_selector": { - "type": "RecordSelector", - "extractor": {"type": "DpathExtractor", "field_path": ["comments"]}, - "record_filter": { - "condition": "{{ record['updated_at'] >= stream_state.get('updated_at', config.get('start_date')) }}" - }, - }, - "paginator": "#/definitions/retriever/paginator", - "partition_router": { - "type": "SubstreamPartitionRouter", - "parent_stream_configs": [ - { - "stream": "#/definitions/posts_stream", - "parent_key": "id", - "partition_field": "id", - "incremental_dependency": True, - } - ], - }, - }, - "incremental_sync": { - "type": "DatetimeBasedCursor", - "cursor_datetime_formats": ["%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%S%z"], - "datetime_format": "%Y-%m-%dT%H:%M:%SZ", - "cursor_field": "{{ parameters.get('cursor_field', 'updated_at') }}", - "start_datetime": {"datetime": "{{ config.get('start_date') }}"}, - }, - "$parameters": { - "name": "post_comments", - "path": "community/posts/{{ stream_slice.id }}/comments", - "data_path": "comments", - "cursor_field": "updated_at", - "primary_key": "id", - }, - }, - "post_comment_votes_stream": { - "type": "DeclarativeStream", - "name": "post_comment_votes", - "primary_key": ["id"], - "schema_loader": { - "type": "InlineSchemaLoader", - "schema": { - "$schema": "http://json-schema.org/schema#", - "properties": { - "id": {"type": "integer"}, - "created_at": {"type": "string", "format": "date-time"}, - "comment_id": {"type": "integer"}, - "vote": {"type": "number"}, - }, - "type": "object", - }, - }, - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "url_base": "https://api.example.com", - "path": "/community/posts/{{ stream_slice.parent_slice.id }}/comments/{{ stream_slice.id }}/votes", - "http_method": "GET", - "authenticator": "#/definitions/basic_authenticator", - }, - "record_selector": "#/definitions/retriever/record_selector", - "paginator": "#/definitions/retriever/paginator", - "partition_router": { - "type": "SubstreamPartitionRouter", - "parent_stream_configs": [ - { - "stream": "#/definitions/post_comments_stream", - "parent_key": "id", - "partition_field": "id", - "incremental_dependency": True, - } - ], - }, - }, - "incremental_sync": { - "type": "DatetimeBasedCursor", - "cursor_datetime_formats": ["%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%S%z"], - "datetime_format": "%Y-%m-%dT%H:%M:%SZ", - "cursor_field": "{{ parameters.get('cursor_field', 'updated_at') }}", - "start_datetime": {"datetime": "{{ config.get('start_date')}}"}, - "start_time_option": {"inject_into": "request_parameter", "field_name": "start_time", "type": "RequestOption"}, - "global_substream_cursor": True, - }, - "$parameters": { - "name": "post_comment_votes", - "path": "community/posts/{{ stream_slice.parent_slice.id }}/comments/{{ stream_slice.id }}/votes", - "data_path": "votes", - "cursor_field": "created_at", - "primary_key": "id", - }, - }, - }, - "streams": [ - {"$ref": "#/definitions/posts_stream"}, - {"$ref": "#/definitions/post_comments_stream"}, - {"$ref": "#/definitions/post_comment_votes_stream"}, - ], -} -SUBSTREAM_MANIFEST_GLOBAL_PARENT_CURSOR_NO_DEPENDENCY = copy.deepcopy(SUBSTREAM_MANIFEST_GLOBAL_PARENT_CURSOR) -SUBSTREAM_MANIFEST_GLOBAL_PARENT_CURSOR_NO_DEPENDENCY["definitions"]["post_comment_votes_stream"]["retriever"]["partition_router"][ - "parent_stream_configs" -][0]["incremental_dependency"] = False - - -@pytest.mark.parametrize( - "test_name, manifest, mock_requests, expected_records, initial_state, expected_state", - [ - ( - "test_global_substream_cursor", - SUBSTREAM_MANIFEST_GLOBAL_PARENT_CURSOR, - [ - # Fetch the first page of posts - ( - "https://api.example.com/community/posts?per_page=100&start_time=2024-01-05T00:00:00Z", - { - "posts": [{"id": 1, "updated_at": "2024-01-30T00:00:00Z"}, {"id": 2, "updated_at": "2024-01-29T00:00:00Z"}], - "next_page": "https://api.example.com/community/posts?per_page=100&start_time=2024-01-05T00:00:00Z&page=2", - }, - ), - # Fetch the second page of posts - ( - "https://api.example.com/community/posts?per_page=100&start_time=2024-01-05T00:00:00Z&page=2", - {"posts": [{"id": 3, "updated_at": "2024-01-28T00:00:00Z"}]}, - ), - # Fetch the first page of comments for post 1 - ( - "https://api.example.com/community/posts/1/comments?per_page=100", - { - "comments": [ - {"id": 9, "post_id": 1, "updated_at": "2023-01-01T00:00:00Z"}, - {"id": 10, "post_id": 1, "updated_at": "2024-01-25T00:00:00Z"}, - {"id": 11, "post_id": 1, "updated_at": "2024-01-24T00:00:00Z"}, - ], - "next_page": "https://api.example.com/community/posts/1/comments?per_page=100&page=2", - }, - ), - # Fetch the second page of comments for post 1 - ( - "https://api.example.com/community/posts/1/comments?per_page=100&page=2", - {"comments": [{"id": 12, "post_id": 1, "updated_at": "2024-01-23T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 10 of post 1 - ( - "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&start_time=2024-01-03T00:00:00Z", - { - "votes": [{"id": 100, "comment_id": 10, "created_at": "2024-01-15T00:00:00Z"}], - "next_page": "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&page=2&start_time=2024-01-03T00:00:01Z", - }, - ), - # Fetch the second page of votes for comment 10 of post 1 - ( - "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&page=2&start_time=2024-01-03T00:00:01Z", - {"votes": [{"id": 101, "comment_id": 10, "created_at": "2024-01-14T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 11 of post 1 - ( - "https://api.example.com/community/posts/1/comments/11/votes?per_page=100&start_time=2024-01-03T00:00:00Z", - {"votes": [{"id": 102, "comment_id": 11, "created_at": "2024-01-13T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 12 of post 1 - ("https://api.example.com/community/posts/1/comments/12/votes?per_page=100&start_time=2024-01-03T00:00:00Z", {"votes": []}), - # Fetch the first page of comments for post 2 - ( - "https://api.example.com/community/posts/2/comments?per_page=100", - { - "comments": [{"id": 20, "post_id": 2, "updated_at": "2024-01-22T00:00:00Z"}], - "next_page": "https://api.example.com/community/posts/2/comments?per_page=100&page=2", - }, - ), - # Fetch the second page of comments for post 2 - ( - "https://api.example.com/community/posts/2/comments?per_page=100&page=2", - {"comments": [{"id": 21, "post_id": 2, "updated_at": "2024-01-21T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 20 of post 2 - ( - "https://api.example.com/community/posts/2/comments/20/votes?per_page=100&start_time=2024-01-03T00:00:00Z", - {"votes": [{"id": 200, "comment_id": 20, "created_at": "2024-01-12T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 21 of post 2 - ( - "https://api.example.com/community/posts/2/comments/21/votes?per_page=100&start_time=2024-01-03T00:00:00Z", - {"votes": [{"id": 201, "comment_id": 21, "created_at": "2024-01-12T00:00:15Z"}]}, - ), - # Fetch the first page of comments for post 3 - ( - "https://api.example.com/community/posts/3/comments?per_page=100", - {"comments": [{"id": 30, "post_id": 3, "updated_at": "2024-01-09T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 30 of post 3 - ( - "https://api.example.com/community/posts/3/comments/30/votes?per_page=100", - {"votes": [{"id": 300, "comment_id": 30, "created_at": "2024-01-10T00:00:00Z"}]}, - ), - # Requests with intermediate states - # Fetch votes for comment 10 of post 1 - ( - "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&start_time=2024-01-14T23:59:59Z", - { - "votes": [{"id": 100, "comment_id": 10, "created_at": "2024-01-15T00:00:00Z"}], - }, - ), - # Fetch votes for comment 11 of post 1 - ( - "https://api.example.com/community/posts/1/comments/11/votes?per_page=100&start_time=2024-01-14T23:59:59Z", - { - "votes": [{"id": 102, "comment_id": 11, "created_at": "2024-01-13T00:00:00Z"}], - }, - ), - # Fetch votes for comment 12 of post 1 - ( - "https://api.example.com/community/posts/1/comments/12/votes?per_page=100&start_time=2024-01-14T23:59:59Z", - { - "votes": [], - }, - ), - # Fetch votes for comment 20 of post 2 - ( - "https://api.example.com/community/posts/2/comments/20/votes?per_page=100&start_time=2024-01-14T23:59:59Z", - {"votes": [{"id": 200, "comment_id": 20, "created_at": "2024-01-12T00:00:00Z"}]}, - ), - # Fetch votes for comment 21 of post 2 - ( - "https://api.example.com/community/posts/2/comments/21/votes?per_page=100&start_time=2024-01-14T23:59:59Z", - {"votes": [{"id": 201, "comment_id": 21, "created_at": "2024-01-12T00:00:15Z"}]}, - ), - ], - # Expected records - [ - {"id": 100, "comment_id": 10, "created_at": "2024-01-15T00:00:00Z"}, - {"id": 101, "comment_id": 10, "created_at": "2024-01-14T00:00:00Z"}, - {"id": 102, "comment_id": 11, "created_at": "2024-01-13T00:00:00Z"}, - {"id": 200, "comment_id": 20, "created_at": "2024-01-12T00:00:00Z"}, - {"id": 201, "comment_id": 21, "created_at": "2024-01-12T00:00:15Z"}, - {"id": 300, "comment_id": 30, "created_at": "2024-01-10T00:00:00Z"}, - ], - # Initial state - [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="post_comment_votes", namespace=None), - stream_state=AirbyteStateBlob( - { - "parent_state": { - "post_comments": { - "states": [ - {"partition": {"id": 1, "parent_slice": {}}, "cursor": {"updated_at": "2023-01-04T00:00:00Z"}} - ], - "parent_state": {"posts": {"updated_at": "2024-01-05T00:00:00Z"}}, - } - }, - "state": {"created_at": "2024-01-04T02:03:04Z"}, - "lookback_window": 93784, - } - ), - ), - ) - ], - # Expected state - { - "state": {"created_at": "2024-01-15T00:00:00Z"}, - "lookback_window": 1, - "parent_state": { - "post_comments": { - "use_global_cursor": False, - "state": {"updated_at": "2024-01-25T00:00:00Z"}, - "parent_state": {"posts": {"updated_at": "2024-01-30T00:00:00Z"}}, - "lookback_window": 1, - "states": [ - {"partition": {"id": 1, "parent_slice": {}}, "cursor": {"updated_at": "2024-01-25T00:00:00Z"}}, - {"partition": {"id": 2, "parent_slice": {}}, "cursor": {"updated_at": "2024-01-22T00:00:00Z"}}, - {"partition": {"id": 3, "parent_slice": {}}, "cursor": {"updated_at": "2024-01-09T00:00:00Z"}}, - ], - } - }, - }, - ), - ( - "test_global_substream_cursor_no_dependency", - SUBSTREAM_MANIFEST_GLOBAL_PARENT_CURSOR_NO_DEPENDENCY, - [ - # Fetch the first page of posts - ( - "https://api.example.com/community/posts?per_page=100&start_time=2024-01-01T00:00:01Z", - { - "posts": [{"id": 1, "updated_at": "2024-01-30T00:00:00Z"}, {"id": 2, "updated_at": "2024-01-29T00:00:00Z"}], - "next_page": "https://api.example.com/community/posts?per_page=100&start_time=2024-01-01T00:00:01Z&page=2", - }, - ), - # Fetch the second page of posts - ( - "https://api.example.com/community/posts?per_page=100&start_time=2024-01-01T00:00:01Z&page=2", - {"posts": [{"id": 3, "updated_at": "2024-01-28T00:00:00Z"}]}, - ), - # Fetch the first page of comments for post 1 - ( - "https://api.example.com/community/posts/1/comments?per_page=100", - { - "comments": [ - {"id": 9, "post_id": 1, "updated_at": "2023-01-01T00:00:00Z"}, - {"id": 10, "post_id": 1, "updated_at": "2024-01-25T00:00:00Z"}, - {"id": 11, "post_id": 1, "updated_at": "2024-01-24T00:00:00Z"}, - ], - "next_page": "https://api.example.com/community/posts/1/comments?per_page=100&page=2", - }, - ), - # Fetch the second page of comments for post 1 - ( - "https://api.example.com/community/posts/1/comments?per_page=100&page=2", - {"comments": [{"id": 12, "post_id": 1, "updated_at": "2024-01-23T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 10 of post 1 - ( - "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&start_time=2024-01-03T00:00:00Z", - { - "votes": [{"id": 100, "comment_id": 10, "created_at": "2024-01-15T00:00:00Z"}], - "next_page": "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&page=2&start_time=2024-01-03T00:00:00Z", - }, - ), - # Fetch the second page of votes for comment 10 of post 1 - ( - "https://api.example.com/community/posts/1/comments/10/votes?per_page=100&page=2&start_time=2024-01-03T00:00:00Z", - {"votes": [{"id": 101, "comment_id": 10, "created_at": "2024-01-14T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 11 of post 1 - ( - "https://api.example.com/community/posts/1/comments/11/votes?per_page=100&start_time=2024-01-03T00:00:00Z", - {"votes": [{"id": 102, "comment_id": 11, "created_at": "2024-01-13T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 12 of post 1 - ("https://api.example.com/community/posts/1/comments/12/votes?per_page=100&start_time=2024-01-03T00:00:00Z", {"votes": []}), - # Fetch the first page of comments for post 2 - ( - "https://api.example.com/community/posts/2/comments?per_page=100", - { - "comments": [{"id": 20, "post_id": 2, "updated_at": "2024-01-22T00:00:00Z"}], - "next_page": "https://api.example.com/community/posts/2/comments?per_page=100&page=2", - }, - ), - # Fetch the second page of comments for post 2 - ( - "https://api.example.com/community/posts/2/comments?per_page=100&page=2", - {"comments": [{"id": 21, "post_id": 2, "updated_at": "2024-01-21T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 20 of post 2 - ( - "https://api.example.com/community/posts/2/comments/20/votes?per_page=100&start_time=2024-01-03T00:00:00Z", - {"votes": [{"id": 200, "comment_id": 20, "created_at": "2024-01-12T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 21 of post 2 - ( - "https://api.example.com/community/posts/2/comments/21/votes?per_page=100&start_time=2024-01-03T00:00:00Z", - {"votes": [{"id": 201, "comment_id": 21, "created_at": "2024-01-12T00:00:15Z"}]}, - ), - # Fetch the first page of comments for post 3 - ( - "https://api.example.com/community/posts/3/comments?per_page=100", - {"comments": [{"id": 30, "post_id": 3, "updated_at": "2024-01-09T00:00:00Z"}]}, - ), - # Fetch the first page of votes for comment 30 of post 3 - ( - "https://api.example.com/community/posts/3/comments/30/votes?per_page=100", - {"votes": [{"id": 300, "comment_id": 30, "created_at": "2024-01-10T00:00:00Z"}]}, - ), - ], - # Expected records - [ - {"id": 100, "comment_id": 10, "created_at": "2024-01-15T00:00:00Z"}, - {"id": 101, "comment_id": 10, "created_at": "2024-01-14T00:00:00Z"}, - {"id": 102, "comment_id": 11, "created_at": "2024-01-13T00:00:00Z"}, - {"id": 200, "comment_id": 20, "created_at": "2024-01-12T00:00:00Z"}, - {"id": 201, "comment_id": 21, "created_at": "2024-01-12T00:00:15Z"}, - {"id": 300, "comment_id": 30, "created_at": "2024-01-10T00:00:00Z"}, - ], - # Initial state - [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="post_comment_votes", namespace=None), - stream_state=AirbyteStateBlob( - { - "parent_state": { - "post_comments": { - "states": [ - {"partition": {"id": 1, "parent_slice": {}}, "cursor": {"updated_at": "2023-01-04T00:00:00Z"}} - ], - "parent_state": {"posts": {"updated_at": "2024-01-05T00:00:00Z"}}, - } - }, - "state": {"created_at": "2024-01-04T02:03:04Z"}, - "lookback_window": 93784, - } - ), - ), - ) - ], - # Expected state - {"state": {"created_at": "2024-01-15T00:00:00Z"}, "lookback_window": 1}, - ), - ], -) -def test_incremental_global_parent_state(test_name, manifest, mock_requests, expected_records, initial_state, expected_state): - run_incremental_parent_state_test(manifest, mock_requests, expected_records, initial_state, [expected_state]) diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/test_single_partition_router.py b/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/test_single_partition_router.py deleted file mode 100644 index b1512dc54f12..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/test_single_partition_router.py +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.partition_routers.single_partition_router import SinglePartitionRouter -from airbyte_cdk.sources.types import StreamSlice - - -def test(): - iterator = SinglePartitionRouter(parameters={}) - - stream_slices = iterator.stream_slices() - next_slice = next(stream_slices) - assert next_slice == StreamSlice(partition={}, cursor_slice={}) diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/test_substream_partition_router.py b/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/test_substream_partition_router.py deleted file mode 100644 index f29917abdccf..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/partition_routers/test_substream_partition_router.py +++ /dev/null @@ -1,970 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from functools import partial -from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Union - -import pytest as pytest -from airbyte_cdk.models import AirbyteMessage, AirbyteRecordMessage, SyncMode, Type -from airbyte_cdk.sources.declarative.declarative_stream import DeclarativeStream -from airbyte_cdk.sources.declarative.incremental import ChildPartitionResumableFullRefreshCursor, ResumableFullRefreshCursor -from airbyte_cdk.sources.declarative.incremental.per_partition_cursor import CursorFactory, PerPartitionCursor, StreamSlice -from airbyte_cdk.sources.declarative.interpolation import InterpolatedString -from airbyte_cdk.sources.declarative.partition_routers import CartesianProductStreamSlicer, ListPartitionRouter -from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig, SubstreamPartitionRouter -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType -from airbyte_cdk.sources.streams.checkpoint import Cursor -from airbyte_cdk.sources.types import Record -from airbyte_cdk.utils import AirbyteTracedException - -parent_records = [{"id": 1, "data": "data1"}, {"id": 2, "data": "data2"}] -more_records = [{"id": 10, "data": "data10", "slice": "second_parent"}, {"id": 20, "data": "data20", "slice": "second_parent"}] - -data_first_parent_slice = [{"id": 0, "slice": "first", "data": "A"}, {"id": 1, "slice": "first", "data": "B"}] -data_second_parent_slice = [{"id": 2, "slice": "second", "data": "C"}] -data_third_parent_slice = [] -all_parent_data = data_first_parent_slice + data_second_parent_slice + data_third_parent_slice -parent_slices = [{"slice": "first"}, {"slice": "second"}, {"slice": "third"}] -second_parent_stream_slice = [StreamSlice(partition={"slice": "second_parent"}, cursor_slice={})] - -data_first_parent_slice_with_cursor = [ - {"id": 0, "slice": "first", "data": "A", "cursor": "first_cursor_0"}, - {"id": 1, "slice": "first", "data": "B", "cursor": "first_cursor_1"}, -] -data_second_parent_slice_with_cursor = [{"id": 2, "slice": "second", "data": "C", "cursor": "second_cursor_2"}] -all_parent_data_with_cursor = data_first_parent_slice_with_cursor + data_second_parent_slice_with_cursor - - -class MockStream(DeclarativeStream): - def __init__(self, slices, records, name, cursor_field="", cursor=None): - self.config = {} - self._slices = slices - self._records = records - self._stream_cursor_field = ( - InterpolatedString.create(cursor_field, parameters={}) if isinstance(cursor_field, str) else cursor_field - ) - self._name = name - self._state = {"states": []} - self._cursor = cursor - - @property - def name(self) -> str: - return self._name - - @property - def primary_key(self) -> Optional[Union[str, List[str], List[List[str]]]]: - return "id" - - @property - def state(self) -> Mapping[str, Any]: - return self._state - - @state.setter - def state(self, value: Mapping[str, Any]) -> None: - self._state = value - - @property - def is_resumable(self) -> bool: - return bool(self._cursor) - - def get_cursor(self) -> Optional[Cursor]: - return self._cursor - - def stream_slices( - self, *, sync_mode: SyncMode, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None - ) -> Iterable[Optional[StreamSlice]]: - for s in self._slices: - if isinstance(s, StreamSlice): - yield s - else: - yield StreamSlice(partition=s, cursor_slice={}) - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: List[str] = None, - stream_slice: Mapping[str, Any] = None, - stream_state: Mapping[str, Any] = None, - ) -> Iterable[Mapping[str, Any]]: - # The parent stream's records should always be read as full refresh - assert sync_mode == SyncMode.full_refresh - - if not stream_slice: - result = self._records - else: - result = [Record(data=r, associated_slice=stream_slice) for r in self._records if r["slice"] == stream_slice["slice"]] - - yield from result - - # Update the state only after reading the full slice - cursor_field = self._stream_cursor_field.eval(config=self.config) - if stream_slice and cursor_field and result: - self._state["states"].append({cursor_field: result[-1][cursor_field], "partition": stream_slice["slice"]}) - - def get_json_schema(self) -> Mapping[str, Any]: - return {} - - -class MockIncrementalStream(MockStream): - def __init__(self, slices, records, name, cursor_field="", cursor=None, date_ranges=None): - super().__init__(slices, records, name, cursor_field, cursor) - if date_ranges is None: - date_ranges = [] - self._date_ranges = date_ranges - self._state = {} - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: List[str] = None, - stream_slice: Mapping[str, Any] = None, - stream_state: Mapping[str, Any] = None, - ) -> Iterable[Mapping[str, Any]]: - results = [record for record in self._records if stream_slice["start_time"] <= record["updated_at"] <= stream_slice["end_time"]] - print(f"about to emit {results}") - yield from results - print(f"setting state to {stream_slice}") - self._state = stream_slice - - -class MockResumableFullRefreshStream(MockStream): - def __init__(self, slices, name, cursor_field="", cursor=None, record_pages: Optional[List[List[Mapping[str, Any]]]] = None): - super().__init__(slices, [], name, cursor_field, cursor) - if record_pages: - self._record_pages = record_pages - else: - self._record_pages = [] - self._state: MutableMapping[str, Any] = {} - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: List[str] = None, - stream_slice: Mapping[str, Any] = None, - stream_state: Mapping[str, Any] = None, - ) -> Iterable[Mapping[str, Any]]: - page_number = self.state.get("next_page_token") or 1 - yield from self._record_pages[page_number - 1] - - cursor = self.get_cursor() - if page_number < len(self._record_pages): - cursor.close_slice(StreamSlice(cursor_slice={"next_page_token": page_number + 1}, partition={})) - else: - cursor.close_slice(StreamSlice(cursor_slice={"__ab_full_refresh_sync_complete": True}, partition={})) - - @property - def state(self) -> Mapping[str, Any]: - cursor = self.get_cursor() - return cursor.get_stream_state() if cursor else {} - - @state.setter - def state(self, value: Mapping[str, Any]) -> None: - self._state = value - - -@pytest.mark.parametrize( - "parent_stream_configs, expected_slices", - [ - ([], None), - ( - [ - ParentStreamConfig( - stream=MockStream([{}], [], "first_stream"), - parent_key="id", - partition_field="first_stream_id", - parameters={}, - config={}, - ) - ], - [], - ), - ( - [ - ParentStreamConfig( - stream=MockStream([{}], parent_records, "first_stream"), - parent_key="id", - partition_field="first_stream_id", - parameters={}, - config={}, - ) - ], - [{"first_stream_id": 1, "parent_slice": {}}, {"first_stream_id": 2, "parent_slice": {}}], - ), - ( - [ - ParentStreamConfig( - stream=MockStream(parent_slices, all_parent_data, "first_stream"), - parent_key="id", - partition_field="first_stream_id", - parameters={}, - config={}, - ) - ], - [ - {"parent_slice": {"slice": "first"}, "first_stream_id": 0}, - {"parent_slice": {"slice": "first"}, "first_stream_id": 1}, - {"parent_slice": {"slice": "second"}, "first_stream_id": 2}, - ], - ), - ( - [ - ParentStreamConfig( - stream=MockStream( - [StreamSlice(partition=p, cursor_slice={"start": 0, "end": 1}) for p in parent_slices], - all_parent_data, - "first_stream", - ), - parent_key="id", - partition_field="first_stream_id", - parameters={}, - config={}, - ) - ], - [ - {"parent_slice": {"slice": "first"}, "first_stream_id": 0}, - {"parent_slice": {"slice": "first"}, "first_stream_id": 1}, - {"parent_slice": {"slice": "second"}, "first_stream_id": 2}, - ], - ), - ( - [ - ParentStreamConfig( - stream=MockStream(parent_slices, data_first_parent_slice + data_second_parent_slice, "first_stream"), - parent_key="id", - partition_field="first_stream_id", - parameters={}, - config={}, - ), - ParentStreamConfig( - stream=MockStream(second_parent_stream_slice, more_records, "second_stream"), - parent_key="id", - partition_field="second_stream_id", - parameters={}, - config={}, - ), - ], - [ - {"parent_slice": {"slice": "first"}, "first_stream_id": 0}, - {"parent_slice": {"slice": "first"}, "first_stream_id": 1}, - {"parent_slice": {"slice": "second"}, "first_stream_id": 2}, - {"parent_slice": {"slice": "second_parent"}, "second_stream_id": 10}, - {"parent_slice": {"slice": "second_parent"}, "second_stream_id": 20}, - ], - ), - ( - [ - ParentStreamConfig( - stream=MockStream([{}], [{"id": 0}, {"id": 1}, {"_id": 2}, {"id": 3}], "first_stream"), - parent_key="id", - partition_field="first_stream_id", - parameters={}, - config={}, - ) - ], - [ - {"first_stream_id": 0, "parent_slice": {}}, - {"first_stream_id": 1, "parent_slice": {}}, - {"first_stream_id": 3, "parent_slice": {}}, - ], - ), - ( - [ - ParentStreamConfig( - stream=MockStream([{}], [{"a": {"b": 0}}, {"a": {"b": 1}}, {"a": {"c": 2}}, {"a": {"b": 3}}], "first_stream"), - parent_key="a/b", - partition_field="first_stream_id", - parameters={}, - config={}, - ) - ], - [ - {"first_stream_id": 0, "parent_slice": {}}, - {"first_stream_id": 1, "parent_slice": {}}, - {"first_stream_id": 3, "parent_slice": {}}, - ], - ), - ], - ids=[ - "test_no_parents", - "test_single_parent_slices_no_records", - "test_single_parent_slices_with_records", - "test_with_parent_slices_and_records", - "test_multiple_parent_streams", - "test_cursor_values_are_removed_from_parent_slices", - "test_missed_parent_key", - "test_dpath_extraction", - ], -) -def test_substream_partition_router(parent_stream_configs, expected_slices): - if expected_slices is None: - try: - SubstreamPartitionRouter(parent_stream_configs=parent_stream_configs, parameters={}, config={}) - assert False - except ValueError: - return - partition_router = SubstreamPartitionRouter(parent_stream_configs=parent_stream_configs, parameters={}, config={}) - slices = [s for s in partition_router.stream_slices()] - assert slices == expected_slices - - -def test_substream_partition_router_invalid_parent_record_type(): - partition_router = SubstreamPartitionRouter( - parent_stream_configs=[ - ParentStreamConfig( - stream=MockStream([{}], [list()], "first_stream"), - parent_key="id", - partition_field="first_stream_id", - parameters={}, - config={}, - ) - ], - parameters={}, - config={}, - ) - - with pytest.raises(AirbyteTracedException): - _ = [s for s in partition_router.stream_slices()] - - -@pytest.mark.parametrize( - "parent_stream_request_parameters, expected_req_params, expected_headers, expected_body_json, expected_body_data", - [ - ( - [ - RequestOption(inject_into=RequestOptionType.request_parameter, parameters={}, field_name="first_stream"), - RequestOption(inject_into=RequestOptionType.request_parameter, parameters={}, field_name="second_stream"), - ], - {"first_stream": "1234", "second_stream": "4567"}, - {}, - {}, - {}, - ), - ( - [ - RequestOption(inject_into=RequestOptionType.header, parameters={}, field_name="first_stream"), - RequestOption(inject_into=RequestOptionType.header, parameters={}, field_name="second_stream"), - ], - {}, - {"first_stream": "1234", "second_stream": "4567"}, - {}, - {}, - ), - ( - [ - RequestOption(inject_into=RequestOptionType.request_parameter, parameters={}, field_name="first_stream"), - RequestOption(inject_into=RequestOptionType.header, parameters={}, field_name="second_stream"), - ], - {"first_stream": "1234"}, - {"second_stream": "4567"}, - {}, - {}, - ), - ( - [ - RequestOption(inject_into=RequestOptionType.body_json, parameters={}, field_name="first_stream"), - RequestOption(inject_into=RequestOptionType.body_json, parameters={}, field_name="second_stream"), - ], - {}, - {}, - {"first_stream": "1234", "second_stream": "4567"}, - {}, - ), - ( - [ - RequestOption(inject_into=RequestOptionType.body_data, parameters={}, field_name="first_stream"), - RequestOption(inject_into=RequestOptionType.body_data, parameters={}, field_name="second_stream"), - ], - {}, - {}, - {}, - {"first_stream": "1234", "second_stream": "4567"}, - ), - ], - ids=[ - "test_request_option_in_request_param", - "test_request_option_in_header", - "test_request_option_in_param_and_header", - "test_request_option_in_body_json", - "test_request_option_in_body_data", - ], -) -def test_request_option( - parent_stream_request_parameters, - expected_req_params, - expected_headers, - expected_body_json, - expected_body_data, -): - partition_router = SubstreamPartitionRouter( - parent_stream_configs=[ - ParentStreamConfig( - stream=MockStream(parent_slices, data_first_parent_slice + data_second_parent_slice, "first_stream"), - parent_key="id", - partition_field="first_stream_id", - parameters={}, - config={}, - request_option=parent_stream_request_parameters[0], - ), - ParentStreamConfig( - stream=MockStream(second_parent_stream_slice, more_records, "second_stream"), - parent_key="id", - partition_field="second_stream_id", - parameters={}, - config={}, - request_option=parent_stream_request_parameters[1], - ), - ], - parameters={}, - config={}, - ) - stream_slice = {"first_stream_id": "1234", "second_stream_id": "4567"} - - assert partition_router.get_request_params(stream_slice=stream_slice) == expected_req_params - assert partition_router.get_request_headers(stream_slice=stream_slice) == expected_headers - assert partition_router.get_request_body_json(stream_slice=stream_slice) == expected_body_json - assert partition_router.get_request_body_data(stream_slice=stream_slice) == expected_body_data - - -@pytest.mark.parametrize( - "parent_stream_config, expected_state", - [ - ( - ParentStreamConfig( - stream=MockStream(parent_slices, all_parent_data_with_cursor, "first_stream", cursor_field="cursor"), - parent_key="id", - partition_field="first_stream_id", - parameters={}, - config={}, - incremental_dependency=True, - ), - { - "first_stream": { - "states": [{"cursor": "first_cursor_1", "partition": "first"}, {"cursor": "second_cursor_2", "partition": "second"}] - } - }, - ), - ], - ids=[ - "test_incremental_dependency_state_update_with_cursor", - ], -) -def test_substream_slicer_parent_state_update_with_cursor(parent_stream_config, expected_state): - partition_router = SubstreamPartitionRouter(parent_stream_configs=[parent_stream_config], parameters={}, config={}) - - # Simulate reading the records and updating the state - for _ in partition_router.stream_slices(): - pass # This will process the slices and should update the parent state - - # Check if the parent state has been updated correctly - parent_state = partition_router.get_stream_state() - assert parent_state == expected_state - - -@pytest.mark.parametrize( - "field_name_first_stream, field_name_second_stream, expected_request_params", - [ - ( - "{{parameters['field_name_first_stream']}}", - "{{parameters['field_name_second_stream']}}", - {"parameter_first_stream_id": "1234", "parameter_second_stream_id": "4567"}, - ), - ( - "{{config['field_name_first_stream']}}", - "{{config['field_name_second_stream']}}", - {"config_first_stream_id": "1234", "config_second_stream_id": "4567"}, - ), - ], - ids=[ - "parameters_interpolation", - "config_interpolation", - ], -) -def test_request_params_interpolation_for_parent_stream( - field_name_first_stream: str, field_name_second_stream: str, expected_request_params: dict -): - config = {"field_name_first_stream": "config_first_stream_id", "field_name_second_stream": "config_second_stream_id"} - parameters = {"field_name_first_stream": "parameter_first_stream_id", "field_name_second_stream": "parameter_second_stream_id"} - partition_router = SubstreamPartitionRouter( - parent_stream_configs=[ - ParentStreamConfig( - stream=MockStream(parent_slices, data_first_parent_slice + data_second_parent_slice, "first_stream"), - parent_key="id", - partition_field="first_stream_id", - parameters=parameters, - config=config, - request_option=RequestOption( - inject_into=RequestOptionType.request_parameter, parameters=parameters, field_name=field_name_first_stream - ), - ), - ParentStreamConfig( - stream=MockStream(second_parent_stream_slice, more_records, "second_stream"), - parent_key="id", - partition_field="second_stream_id", - parameters=parameters, - config=config, - request_option=RequestOption( - inject_into=RequestOptionType.request_parameter, parameters=parameters, field_name=field_name_second_stream - ), - ), - ], - parameters=parameters, - config=config, - ) - stream_slice = {"first_stream_id": "1234", "second_stream_id": "4567"} - - assert partition_router.get_request_params(stream_slice=stream_slice) == expected_request_params - - -def test_given_record_is_airbyte_message_when_stream_slices_then_use_record_data(): - parent_slice = {} - partition_router = SubstreamPartitionRouter( - parent_stream_configs=[ - ParentStreamConfig( - stream=MockStream( - [parent_slice], - [ - AirbyteMessage( - type=Type.RECORD, record=AirbyteRecordMessage(data={"id": "record value"}, emitted_at=0, stream="stream") - ) - ], - "first_stream", - ), - parent_key="id", - partition_field="partition_field", - parameters={}, - config={}, - ) - ], - parameters={}, - config={}, - ) - - slices = list(partition_router.stream_slices()) - assert slices == [{"partition_field": "record value", "parent_slice": parent_slice}] - - -def test_given_record_is_record_object_when_stream_slices_then_use_record_data(): - parent_slice = {} - partition_router = SubstreamPartitionRouter( - parent_stream_configs=[ - ParentStreamConfig( - stream=MockStream([parent_slice], [Record({"id": "record value"}, {})], "first_stream"), - parent_key="id", - partition_field="partition_field", - parameters={}, - config={}, - ) - ], - parameters={}, - config={}, - ) - - slices = list(partition_router.stream_slices()) - assert slices == [{"partition_field": "record value", "parent_slice": parent_slice}] - - -def test_substream_using_incremental_parent_stream(): - mock_slices = [ - StreamSlice(cursor_slice={"start_time": "2024-04-27", "end_time": "2024-05-27"}, partition={}), - StreamSlice(cursor_slice={"start_time": "2024-05-27", "end_time": "2024-06-27"}, partition={}), - ] - - expected_slices = [ - {"partition_field": "may_record_0", "parent_slice": {}}, - {"partition_field": "may_record_1", "parent_slice": {}}, - {"partition_field": "jun_record_0", "parent_slice": {}}, - {"partition_field": "jun_record_1", "parent_slice": {}}, - ] - - partition_router = SubstreamPartitionRouter( - parent_stream_configs=[ - ParentStreamConfig( - stream=MockIncrementalStream( - slices=mock_slices, - records=[ - Record({"id": "may_record_0", "updated_at": "2024-05-15"}, mock_slices[0]), - Record({"id": "may_record_1", "updated_at": "2024-05-16"}, mock_slices[0]), - Record({"id": "jun_record_0", "updated_at": "2024-06-15"}, mock_slices[1]), - Record({"id": "jun_record_1", "updated_at": "2024-06-16"}, mock_slices[1]), - ], - name="first_stream", - ), - parent_key="id", - partition_field="partition_field", - parameters={}, - config={}, - ) - ], - parameters={}, - config={}, - ) - - actual_slices = list(partition_router.stream_slices()) - assert actual_slices == expected_slices - - -def test_substream_checkpoints_after_each_parent_partition(): - """ - This test validates the specific behavior that when getting all parent records for a substream, - we are still updating state so that the parent stream's state is updated after we finish getting all - parent records for the parent slice (not just the substream) - """ - mock_slices = [ - StreamSlice(cursor_slice={"start_time": "2024-04-27", "end_time": "2024-05-27"}, partition={}), - StreamSlice(cursor_slice={"start_time": "2024-05-27", "end_time": "2024-06-27"}, partition={}), - ] - - expected_slices = [ - {"partition_field": "may_record_0", "parent_slice": {}}, - {"partition_field": "may_record_1", "parent_slice": {}}, - {"partition_field": "jun_record_0", "parent_slice": {}}, - {"partition_field": "jun_record_1", "parent_slice": {}}, - ] - - expected_parent_state = [ - {"first_stream": {}}, - {"first_stream": {}}, - {"first_stream": {"start_time": "2024-04-27", "end_time": "2024-05-27"}}, - {"first_stream": {"start_time": "2024-04-27", "end_time": "2024-05-27"}}, - {"first_stream": {"start_time": "2024-05-27", "end_time": "2024-06-27"}}, - ] - - partition_router = SubstreamPartitionRouter( - parent_stream_configs=[ - ParentStreamConfig( - stream=MockIncrementalStream( - slices=mock_slices, - records=[ - Record({"id": "may_record_0", "updated_at": "2024-05-15"}, mock_slices[0]), - Record({"id": "may_record_1", "updated_at": "2024-05-16"}, mock_slices[0]), - Record({"id": "jun_record_0", "updated_at": "2024-06-15"}, mock_slices[1]), - Record({"id": "jun_record_1", "updated_at": "2024-06-16"}, mock_slices[1]), - ], - name="first_stream", - ), - incremental_dependency=True, - parent_key="id", - partition_field="partition_field", - parameters={}, - config={}, - ) - ], - parameters={}, - config={}, - ) - - expected_counter = 0 - for actual_slice in partition_router.stream_slices(): - assert actual_slice == expected_slices[expected_counter] - assert partition_router.get_stream_state() == expected_parent_state[expected_counter] - expected_counter += 1 - assert partition_router.get_stream_state() == expected_parent_state[expected_counter] - - -@pytest.mark.parametrize( - "use_incremental_dependency", - [ - pytest.param(False, id="test_resumable_full_refresh_stream_without_parent_checkpoint"), - pytest.param(True, id="test_resumable_full_refresh_stream_with_use_incremental_dependency_for_parent_checkpoint"), - ], -) -def test_substream_using_resumable_full_refresh_parent_stream(use_incremental_dependency): - mock_slices = [ - StreamSlice(cursor_slice={}, partition={}), - StreamSlice(cursor_slice={"next_page_token": 2}, partition={}), - StreamSlice(cursor_slice={"next_page_token": 3}, partition={}), - ] - - expected_slices = [ - {"partition_field": "makoto_yuki", "parent_slice": {}}, - {"partition_field": "yukari_takeba", "parent_slice": {}}, - {"partition_field": "mitsuru_kirijo", "parent_slice": {}}, - {"partition_field": "akihiko_sanada", "parent_slice": {}}, - {"partition_field": "junpei_iori", "parent_slice": {}}, - {"partition_field": "fuuka_yamagishi", "parent_slice": {}}, - ] - - expected_parent_state = [ - {"persona_3_characters": {}}, - {"persona_3_characters": {}}, - {"persona_3_characters": {"next_page_token": 2}}, - {"persona_3_characters": {"next_page_token": 2}}, - {"persona_3_characters": {"next_page_token": 3}}, - {"persona_3_characters": {"next_page_token": 3}}, - {"persona_3_characters": {"__ab_full_refresh_sync_complete": True}}, - ] - - partition_router = SubstreamPartitionRouter( - parent_stream_configs=[ - ParentStreamConfig( - stream=MockResumableFullRefreshStream( - slices=[StreamSlice(partition={}, cursor_slice={})], - cursor=ResumableFullRefreshCursor(parameters={}), - record_pages=[ - [ - Record(data={"id": "makoto_yuki"}, associated_slice=mock_slices[0]), - Record(data={"id": "yukari_takeba"}, associated_slice=mock_slices[0]), - ], - [ - Record(data={"id": "mitsuru_kirijo"}, associated_slice=mock_slices[1]), - Record(data={"id": "akihiko_sanada"}, associated_slice=mock_slices[1]), - ], - [ - Record(data={"id": "junpei_iori"}, associated_slice=mock_slices[2]), - Record(data={"id": "fuuka_yamagishi"}, associated_slice=mock_slices[2]), - ], - ], - name="persona_3_characters", - ), - incremental_dependency=use_incremental_dependency, - parent_key="id", - partition_field="partition_field", - parameters={}, - config={}, - ) - ], - parameters={}, - config={}, - ) - - expected_counter = 0 - for actual_slice in partition_router.stream_slices(): - assert actual_slice == expected_slices[expected_counter] - if use_incremental_dependency: - assert partition_router.get_stream_state() == expected_parent_state[expected_counter] - expected_counter += 1 - if use_incremental_dependency: - assert partition_router.get_stream_state() == expected_parent_state[expected_counter] - - -@pytest.mark.parametrize( - "use_incremental_dependency", - [ - pytest.param(False, id="test_substream_resumable_full_refresh_stream_without_parent_checkpoint"), - pytest.param(True, id="test_substream_resumable_full_refresh_stream_with_use_incremental_dependency_for_parent_checkpoint"), - ], -) -def test_substream_using_resumable_full_refresh_parent_stream_slices(use_incremental_dependency): - mock_parent_slices = [ - StreamSlice(cursor_slice={}, partition={}), - StreamSlice(cursor_slice={"next_page_token": 2}, partition={}), - StreamSlice(cursor_slice={"next_page_token": 3}, partition={}), - ] - - expected_parent_slices = [ - {"partition_field": "makoto_yuki", "parent_slice": {}}, - {"partition_field": "yukari_takeba", "parent_slice": {}}, - {"partition_field": "mitsuru_kirijo", "parent_slice": {}}, - {"partition_field": "akihiko_sanada", "parent_slice": {}}, - {"partition_field": "junpei_iori", "parent_slice": {}}, - {"partition_field": "fuuka_yamagishi", "parent_slice": {}}, - ] - - expected_parent_state = [ - {"persona_3_characters": {}}, - {"persona_3_characters": {}}, - {"persona_3_characters": {"next_page_token": 2}}, - {"persona_3_characters": {"next_page_token": 2}}, - {"persona_3_characters": {"next_page_token": 3}}, - {"persona_3_characters": {"next_page_token": 3}}, - {"persona_3_characters": {"__ab_full_refresh_sync_complete": True}}, - ] - - expected_substream_state = { - "states": [ - {"partition": {"parent_slice": {}, "partition_field": "makoto_yuki"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - {"partition": {"parent_slice": {}, "partition_field": "yukari_takeba"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - {"partition": {"parent_slice": {}, "partition_field": "mitsuru_kirijo"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - {"partition": {"parent_slice": {}, "partition_field": "akihiko_sanada"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - {"partition": {"parent_slice": {}, "partition_field": "junpei_iori"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - {"partition": {"parent_slice": {}, "partition_field": "fuuka_yamagishi"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - ], - "parent_state": {"persona_3_characters": {"__ab_full_refresh_sync_complete": True}}, - } - - partition_router = SubstreamPartitionRouter( - parent_stream_configs=[ - ParentStreamConfig( - stream=MockResumableFullRefreshStream( - slices=[StreamSlice(partition={}, cursor_slice={})], - cursor=ResumableFullRefreshCursor(parameters={}), - record_pages=[ - [ - Record(data={"id": "makoto_yuki"}, associated_slice=mock_parent_slices[0]), - Record(data={"id": "yukari_takeba"}, associated_slice=mock_parent_slices[0]), - ], - [ - Record(data={"id": "mitsuru_kirijo"}, associated_slice=mock_parent_slices[1]), - Record(data={"id": "akihiko_sanada"}, associated_slice=mock_parent_slices[1]), - ], - [ - Record(data={"id": "junpei_iori"}, associated_slice=mock_parent_slices[2]), - Record(data={"id": "fuuka_yamagishi"}, associated_slice=mock_parent_slices[2]), - ], - ], - name="persona_3_characters", - ), - incremental_dependency=use_incremental_dependency, - parent_key="id", - partition_field="partition_field", - parameters={}, - config={}, - ) - ], - parameters={}, - config={}, - ) - - substream_cursor_slicer = PerPartitionCursor( - cursor_factory=CursorFactory(create_function=partial(ChildPartitionResumableFullRefreshCursor, {})), - partition_router=partition_router, - ) - - expected_counter = 0 - for actual_slice in substream_cursor_slicer.stream_slices(): - # close the substream slice - substream_cursor_slicer.close_slice(actual_slice) - # check the slice has been processed - assert actual_slice == expected_parent_slices[expected_counter] - # check for parent state - if use_incremental_dependency: - assert substream_cursor_slicer._partition_router.get_stream_state() == expected_parent_state[expected_counter] - expected_counter += 1 - if use_incremental_dependency: - assert substream_cursor_slicer._partition_router.get_stream_state() == expected_parent_state[expected_counter] - - # validate final state for closed substream slices - final_state = substream_cursor_slicer.get_stream_state() - if not use_incremental_dependency: - assert final_state["states"] == expected_substream_state["states"], "State for substreams is not valid!" - else: - assert final_state == expected_substream_state, "State for substreams with incremental dependency is not valid!" - - -@pytest.mark.parametrize( - "parent_stream_configs, expected_slices", - [ - ( - [ - ParentStreamConfig( - stream=MockStream( - [{}], - [ - {"id": 1, "field_1": "value_1", "field_2": {"nested_field": "nested_value_1"}}, - {"id": 2, "field_1": "value_2", "field_2": {"nested_field": "nested_value_2"}}, - ], - "first_stream", - ), - parent_key="id", - partition_field="first_stream_id", - extra_fields=[["field_1"], ["field_2", "nested_field"]], - parameters={}, - config={}, - ) - ], - [ - {"field_1": "value_1", "field_2.nested_field": "nested_value_1"}, - {"field_1": "value_2", "field_2.nested_field": "nested_value_2"}, - ], - ), - ( - [ - ParentStreamConfig( - stream=MockStream([{}], [{"id": 1, "field_1": "value_1"}, {"id": 2, "field_1": "value_2"}], "first_stream"), - parent_key="id", - partition_field="first_stream_id", - extra_fields=[["field_1"]], - parameters={}, - config={}, - ) - ], - [{"field_1": "value_1"}, {"field_1": "value_2"}], - ), - ], - ids=[ - "test_with_nested_extra_keys", - "test_with_single_extra_key", - ], -) -def test_substream_partition_router_with_extra_keys(parent_stream_configs, expected_slices): - partition_router = SubstreamPartitionRouter(parent_stream_configs=parent_stream_configs, parameters={}, config={}) - slices = [s.extra_fields for s in partition_router.stream_slices()] - assert slices == expected_slices - - -@pytest.mark.parametrize( - "stream_slicers, expect_warning", - [ - # Case with two ListPartitionRouters, no warning expected - ( - [ - ListPartitionRouter(values=["1", "2", "3"], cursor_field="partition_field", config={}, parameters={}), - ListPartitionRouter(values=["1", "2", "3"], cursor_field="partition_field", config={}, parameters={}), - ], - False, - ), - # Case with a SubstreamPartitionRouter, warning expected - ( - [ - ListPartitionRouter(values=["1", "2", "3"], cursor_field="partition_field", config={}, parameters={}), - SubstreamPartitionRouter( - parent_stream_configs=[ - ParentStreamConfig( - stream=MockStream([{}], [{"a": {"b": 0}}, {"a": {"b": 1}}, {"a": {"c": 2}}, {"a": {"b": 3}}], "first_stream"), - parent_key="a/b", - partition_field="first_stream_id", - parameters={}, - config={}, - ) - ], - parameters={}, - config={}, - ), - ], - True, - ), - # Case with nested CartesianProductStreamSlicer containing a SubstreamPartitionRouter, warning expected - ( - [ - ListPartitionRouter(values=["1", "2", "3"], cursor_field="partition_field", config={}, parameters={}), - CartesianProductStreamSlicer( - stream_slicers=[ - ListPartitionRouter(values=["1", "2", "3"], cursor_field="partition_field", config={}, parameters={}), - SubstreamPartitionRouter( - parent_stream_configs=[ - ParentStreamConfig( - stream=MockStream( - [{}], [{"a": {"b": 0}}, {"a": {"b": 1}}, {"a": {"c": 2}}, {"a": {"b": 3}}], "first_stream" - ), - parent_key="a/b", - partition_field="first_stream_id", - parameters={}, - config={}, - ) - ], - parameters={}, - config={}, - ), - ], - parameters={}, - ), - ], - True, - ), - ], -) -def test_cartesian_product_stream_slicer_warning_log_message(caplog, stream_slicers, expect_warning): - """Test that a warning is logged when SubstreamPartitionRouter is used within a CartesianProductStreamSlicer.""" - warning_message = "Parent state handling is not supported for CartesianProductStreamSlicer." - - with caplog.at_level(logging.WARNING, logger="airbyte"): - CartesianProductStreamSlicer(stream_slicers=stream_slicers, parameters={}) - - logged_warnings = [record.message for record in caplog.records if record.levelname == "WARNING"] - - if expect_warning: - assert warning_message in logged_warnings - else: - assert warning_message not in logged_warnings diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/__init__.py deleted file mode 100644 index 46b7376756ec..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_constant_backoff.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_constant_backoff.py deleted file mode 100644 index 3a931a0d2863..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_constant_backoff.py +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from unittest.mock import MagicMock - -import pytest -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.constant_backoff_strategy import ConstantBackoffStrategy - -BACKOFF_TIME = 10 -PARAMETERS_BACKOFF_TIME = 20 -CONFIG_BACKOFF_TIME = 30 - - -@pytest.mark.parametrize( - "test_name, attempt_count, backofftime, expected_backoff_time", - [ - ("test_constant_backoff_first_attempt", 1, BACKOFF_TIME, BACKOFF_TIME), - ("test_constant_backoff_first_attempt_float", 1, 6.7, 6.7), - ("test_constant_backoff_attempt_round_float", 1.0, 6.7, 6.7), - ("test_constant_backoff_attempt_round_float", 1.5, 6.7, 6.7), - ("test_constant_backoff_first_attempt_round_float", 1, 10.0, BACKOFF_TIME), - ("test_constant_backoff_second_attempt_round_float", 2, 10.0, BACKOFF_TIME), - ("test_constant_backoff_from_parameters", 1, "{{ parameters['backoff'] }}", PARAMETERS_BACKOFF_TIME), - ("test_constant_backoff_from_config", 1, "{{ config['backoff'] }}", CONFIG_BACKOFF_TIME), - ], -) -def test_constant_backoff(test_name, attempt_count, backofftime, expected_backoff_time): - response_mock = MagicMock() - backoff_strategy = ConstantBackoffStrategy( - parameters={"backoff": PARAMETERS_BACKOFF_TIME}, backoff_time_in_seconds=backofftime, config={"backoff": CONFIG_BACKOFF_TIME} - ) - backoff = backoff_strategy.backoff_time(response_mock, attempt_count=attempt_count) - assert backoff == expected_backoff_time diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_exponential_backoff.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_exponential_backoff.py deleted file mode 100644 index a99050a7ba4e..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_exponential_backoff.py +++ /dev/null @@ -1,36 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from unittest.mock import MagicMock - -import pytest -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.exponential_backoff_strategy import ( - ExponentialBackoffStrategy, -) - -parameters = {"backoff": 5} -config = {"backoff": 5} - - -@pytest.mark.parametrize( - "test_name, attempt_count, factor, expected_backoff_time", - [ - ("test_exponential_backoff_first_attempt", 1, 5, 10), - ("test_exponential_backoff_second_attempt", 2, 5, 20), - ("test_exponential_backoff_from_parameters", 2, "{{parameters['backoff']}}", 20), - ("test_exponential_backoff_from_config", 2, "{{config['backoff']}}", 20), - ], -) -def test_exponential_backoff(test_name, attempt_count, factor, expected_backoff_time): - response_mock = MagicMock() - backoff_strategy = ExponentialBackoffStrategy(factor=factor, parameters=parameters, config=config) - backoff = backoff_strategy.backoff_time(response_mock, attempt_count=attempt_count) - assert backoff == expected_backoff_time - - -def test_exponential_backoff_default(): - response_mock = MagicMock() - backoff_strategy = ExponentialBackoffStrategy(parameters=parameters, config=config) - backoff = backoff_strategy.backoff_time(response_mock, attempt_count=3) - assert backoff == 40 diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_header_helper.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_header_helper.py deleted file mode 100644 index 81c2d34e3f76..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_header_helper.py +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import re -from unittest.mock import MagicMock - -import pytest -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.header_helper import get_numeric_value_from_header - - -@pytest.mark.parametrize( - "test_name, headers, requested_header, regex, expected_value", - [ - ("test_get_numeric_value_from_header", {"header": 1}, "header", None, 1), - ("test_get_numeric_value_float_from_header", {"header": 1.2}, "header", None, 1.2), - ("test_get_numeric_value_from_string_value", {"header": "10.9"}, "header", None, 10.9), - ("test_get_numeric_value_from_non_numeric", {"header": "60,120"}, "header", None, None), - ("test_get_numeric_value_from_missing_header", {"header": 1}, "notheader", None, None), - ("test_get_numeric_value_with_regex", {"header": "61,60"}, "header", re.compile("([-+]?\d+)"), 61), # noqa - ("test_get_numeric_value_with_regex_no_header", {"header": "61,60"}, "notheader", re.compile("([-+]?\d+)"), None), # noqa - ("test_get_numeric_value_with_regex_not_matching", {"header": "abc61,60"}, "header", re.compile("([-+]?\d+)"), None), # noqa - ], -) -def test_get_numeric_value_from_header(test_name, headers, requested_header, regex, expected_value): - response_mock = create_response(headers=headers) - numeric_value = get_numeric_value_from_header(response_mock, requested_header, regex) - assert numeric_value == expected_value - - -def create_response(headers=None, json_body=None): - url = "https://airbyte.io" - - response_mock = MagicMock() - response_mock.url = url - response_mock.headers = headers or {} - response_mock.json.return_value = json_body or {} - return response_mock diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_wait_time_from_header.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_wait_time_from_header.py deleted file mode 100644 index 59dbb6b419a7..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_wait_time_from_header.py +++ /dev/null @@ -1,63 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from unittest.mock import MagicMock - -import pytest -from airbyte_cdk import AirbyteTracedException -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.wait_time_from_header_backoff_strategy import ( - WaitTimeFromHeaderBackoffStrategy, -) -from requests import Response - -SOME_BACKOFF_TIME = 60 -_A_RETRY_HEADER = "retry-header" -_A_MAX_TIME = 100 - - -@pytest.mark.parametrize( - "test_name, header, header_value, regex, expected_backoff_time", - [ - ("test_wait_time_from_header", "wait_time", SOME_BACKOFF_TIME, None, SOME_BACKOFF_TIME), - ("test_wait_time_from_header_string", "wait_time", "60", None, SOME_BACKOFF_TIME), - ("test_wait_time_from_header_parameters", "{{ parameters['wait_time'] }}", "60", None, SOME_BACKOFF_TIME), - ("test_wait_time_from_header_config", "{{ config['wait_time'] }}", "60", None, SOME_BACKOFF_TIME), - ("test_wait_time_from_header_not_a_number", "wait_time", "61,60", None, None), - ("test_wait_time_from_header_with_regex", "wait_time", "61,60", "([-+]?\d+)", 61), # noqa - ("test_wait_time_fœrom_header_with_regex_no_match", "wait_time", "...", "[-+]?\d+", None), # noqa - ("test_wait_time_from_header", "absent_header", None, None, None), - ], -) -def test_wait_time_from_header(test_name, header, header_value, regex, expected_backoff_time): - response_mock = MagicMock(spec=Response) - response_mock.headers = {"wait_time": header_value} - backoff_strategy = WaitTimeFromHeaderBackoffStrategy( - header=header, regex=regex, parameters={"wait_time": "wait_time"}, config={"wait_time": "wait_time"} - ) - backoff = backoff_strategy.backoff_time(response_mock, 1) - assert backoff == expected_backoff_time - - -def test_given_retry_after_smaller_than_max_time_then_raise_transient_error(): - response_mock = MagicMock(spec=Response) - retry_after = _A_MAX_TIME - 1 - response_mock.headers = {_A_RETRY_HEADER: str(retry_after)} - backoff_strategy = WaitTimeFromHeaderBackoffStrategy( - header=_A_RETRY_HEADER, max_waiting_time_in_seconds=_A_MAX_TIME, parameters={}, config={} - ) - - assert backoff_strategy.backoff_time(response_mock, 1) == retry_after - - -def test_given_retry_after_greater_than_max_time_then_raise_transient_error(): - response_mock = MagicMock(spec=Response) - response_mock.headers = {_A_RETRY_HEADER: str(_A_MAX_TIME + 1)} - backoff_strategy = WaitTimeFromHeaderBackoffStrategy( - header=_A_RETRY_HEADER, max_waiting_time_in_seconds=_A_MAX_TIME, parameters={}, config={} - ) - - with pytest.raises(AirbyteTracedException) as exception: - backoff_strategy.backoff_time(response_mock, 1) - assert exception.value.failure_type == FailureType.transient_error diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_wait_until_time_from_header.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_wait_until_time_from_header.py deleted file mode 100644 index 5f2bc02f95cd..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_wait_until_time_from_header.py +++ /dev/null @@ -1,65 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from unittest.mock import MagicMock, patch - -import pytest -import requests -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.wait_until_time_from_header_backoff_strategy import ( - WaitUntilTimeFromHeaderBackoffStrategy, -) - -SOME_BACKOFF_TIME = 60 -REGEX = "[-+]?\\d+" - - -@pytest.mark.parametrize( - "test_name, header, wait_until, min_wait, regex, expected_backoff_time", - [ - ("test_wait_until_time_from_header", "wait_until", 1600000060.0, None, None, 60), - ("test_wait_until_time_from_header_parameters", "{{parameters['wait_until']}}", 1600000060.0, None, None, 60), - ("test_wait_until_time_from_header_config", "{{config['wait_until']}}", 1600000060.0, None, None, 60), - ("test_wait_until_negative_time", "wait_until", 1500000000.0, None, None, None), - ("test_wait_until_time_less_than_min", "wait_until", 1600000060.0, 120, None, 120), - ("test_wait_until_no_header", "absent_header", 1600000000.0, None, None, None), - ("test_wait_until_time_from_header_not_numeric", "wait_until", "1600000000,1600000000", None, None, None), - ("test_wait_until_time_from_header_is_numeric", "wait_until", "1600000060", None, None, 60), - ("test_wait_until_time_from_header_with_regex", "wait_until", "1600000060,60", None, "[-+]?\d+", 60), # noqa - ("test_wait_until_time_from_header_with_regex_from_parameters", "wait_until", "1600000060,60", None, "{{parameters['regex']}}", 60), - # noqa - ("test_wait_until_time_from_header_with_regex_from_config", "wait_until", "1600000060,60", None, "{{config['regex']}}", 60), # noqa - ("test_wait_until_time_from_header_with_regex_no_match", "wait_time", "...", None, "[-+]?\d+", None), # noqa - ("test_wait_until_no_header_with_min", "absent_header", "1600000000.0", SOME_BACKOFF_TIME, None, SOME_BACKOFF_TIME), - ( - "test_wait_until_no_header_with_min_from_parameters", - "absent_header", - "1600000000.0", - "{{parameters['min_wait']}}", - None, - SOME_BACKOFF_TIME, - ), - ( - "test_wait_until_no_header_with_min_from_config", - "absent_header", - "1600000000.0", - "{{config['min_wait']}}", - None, - SOME_BACKOFF_TIME, - ), - ], -) -@patch("time.time", return_value=1600000000.0) -def test_wait_untiltime_from_header(time_mock, test_name, header, wait_until, min_wait, regex, expected_backoff_time): - response_mock = MagicMock(spec=requests.Response) - response_mock.headers = {"wait_until": wait_until} - backoff_strategy = WaitUntilTimeFromHeaderBackoffStrategy( - header=header, - min_wait=min_wait, - regex=regex, - parameters={"wait_until": "wait_until", "regex": REGEX, "min_wait": SOME_BACKOFF_TIME}, - config={"wait_until": "wait_until", "regex": REGEX, "min_wait": SOME_BACKOFF_TIME}, - ) - backoff = backoff_strategy.backoff_time(response_mock, 1) - assert backoff == expected_backoff_time diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/test_composite_error_handler.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/test_composite_error_handler.py deleted file mode 100644 index 574f3eec0e75..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/test_composite_error_handler.py +++ /dev/null @@ -1,226 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from unittest.mock import MagicMock - -import pytest -import requests -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.declarative.requesters.error_handlers import HttpResponseFilter -from airbyte_cdk.sources.declarative.requesters.error_handlers.composite_error_handler import CompositeErrorHandler -from airbyte_cdk.sources.declarative.requesters.error_handlers.default_error_handler import DefaultErrorHandler -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, ResponseAction - -SOME_BACKOFF_TIME = 60 - - -@pytest.mark.parametrize( - "test_name, first_handler_behavior, second_handler_behavior, expected_behavior", - [ - ( - "test_chain_retrier_ok_ok", - ErrorResolution( - response_action=ResponseAction.SUCCESS, - failure_type=None, - error_message=None, - ), - ErrorResolution( - response_action=ResponseAction.SUCCESS, - failure_type=None, - error_message=None, - ), - ErrorResolution( - response_action=ResponseAction.SUCCESS, - failure_type=None, - error_message=None, - ), - ), - ( - "test_chain_retrier_ignore_fail", - ErrorResolution( - response_action=ResponseAction.IGNORE, - ), - ErrorResolution( - response_action=ResponseAction.FAIL, - ), - ErrorResolution( - response_action=ResponseAction.IGNORE, - ), - ), - ( - "test_chain_retrier_fail_ignore", - ErrorResolution( - response_action=ResponseAction.FAIL, - ), - ErrorResolution( - response_action=ResponseAction.IGNORE, - ), - ErrorResolution( - response_action=ResponseAction.IGNORE, - ), - ), - ( - "test_chain_retrier_ignore_retry", - ErrorResolution( - response_action=ResponseAction.IGNORE, - ), - ErrorResolution( - response_action=ResponseAction.RETRY, - ), - ErrorResolution( - response_action=ResponseAction.IGNORE, - ), - ), - ( - "test_chain_retrier_ignore_success", - ErrorResolution( - response_action=ResponseAction.IGNORE, - ), - ErrorResolution( - response_action=ResponseAction.SUCCESS, - ), - ErrorResolution( - response_action=ResponseAction.IGNORE, - ), - ), - ], -) -def test_composite_error_handler(test_name, first_handler_behavior, second_handler_behavior, expected_behavior): - first_error_handler = MagicMock() - first_error_handler.interpret_response.return_value = first_handler_behavior - second_error_handler = MagicMock() - second_error_handler.interpret_response.return_value = second_handler_behavior - retriers = [first_error_handler, second_error_handler] - retrier = CompositeErrorHandler(error_handlers=retriers, parameters={}) - response_mock = MagicMock() - response_mock.ok = first_handler_behavior.response_action == ResponseAction.SUCCESS or second_handler_behavior == ResponseAction.SUCCESS - assert retrier.interpret_response(response_mock) == expected_behavior - - -def test_given_unmatched_response_or_exception_then_return_default_error_resolution(): - composite_error_handler = CompositeErrorHandler( - error_handlers=[ - DefaultErrorHandler( - response_filters=[], - parameters={}, - config={}, - ) - ], - parameters={}, - ) - - error_resolution = composite_error_handler.interpret_response(ValueError("Any error")) - - assert error_resolution.response_action == ResponseAction.RETRY - assert error_resolution.failure_type == FailureType.system_error - - -def test_composite_error_handler_no_handlers(): - try: - CompositeErrorHandler(error_handlers=[], parameters={}) - assert False - except ValueError: - pass - - -def test_error_handler_compatibility_simple(): - status_code = 403 - expected_action = ResponseAction.IGNORE - response_mock = create_response(status_code) - default_error_handler = DefaultErrorHandler( - config={}, - parameters={}, - response_filters=[HttpResponseFilter(action=ResponseAction.IGNORE, http_codes={403}, config={}, parameters={})], - ) - composite_error_handler = CompositeErrorHandler( - error_handlers=[ - DefaultErrorHandler( - response_filters=[HttpResponseFilter(action=ResponseAction.IGNORE, http_codes={403}, parameters={}, config={})], - parameters={}, - config={}, - ) - ], - parameters={}, - ) - assert default_error_handler.interpret_response(response_mock).response_action == expected_action - assert composite_error_handler.interpret_response(response_mock).response_action == expected_action - - -@pytest.mark.parametrize( - "test_name, status_code, expected_action", - [("test_first_filter", 403, ResponseAction.IGNORE), ("test_second_filter", 404, ResponseAction.FAIL)], -) -def test_error_handler_compatibility_multiple_filters(test_name, status_code, expected_action): - response_mock = create_response(status_code) - error_handler_with_multiple_filters = CompositeErrorHandler( - error_handlers=[ - DefaultErrorHandler( - response_filters=[ - HttpResponseFilter(action=ResponseAction.IGNORE, http_codes={403}, parameters={}, config={}), - HttpResponseFilter(action=ResponseAction.FAIL, http_codes={404}, parameters={}, config={}), - ], - parameters={}, - config={}, - ), - ], - parameters={}, - ) - composite_error_handler_with_single_filters = CompositeErrorHandler( - error_handlers=[ - DefaultErrorHandler( - response_filters=[HttpResponseFilter(action=ResponseAction.IGNORE, http_codes={403}, parameters={}, config={})], - parameters={}, - config={}, - ), - DefaultErrorHandler( - response_filters=[HttpResponseFilter(action=ResponseAction.FAIL, http_codes={404}, parameters={}, config={})], - parameters={}, - config={}, - ), - ], - parameters={}, - ) - actual_action_multiple_filters = error_handler_with_multiple_filters.interpret_response(response_mock).response_action - assert actual_action_multiple_filters == expected_action - - actual_action_single_filters = composite_error_handler_with_single_filters.interpret_response(response_mock).response_action - assert actual_action_single_filters == expected_action - - -def create_response(status_code: int, headers=None, json_body=None): - url = "https://airbyte.io" - - response_mock = MagicMock(spec=requests.Response) - response_mock.request = MagicMock(spec=requests.PreparedRequest) - response_mock.status_code = status_code - response_mock.ok = status_code < 400 or status_code >= 600 - response_mock.url = url - response_mock.headers = headers or {} - response_mock.json.return_value = json_body or {} - return response_mock - - -@pytest.mark.parametrize( - "test_name, max_times, expected_max_time", - [ - ("test_single_handler", [10], 10), - ("test_multiple_handlers", [10, 15], 15), - ], -) -def test_max_time_is_max_of_underlying_handlers(test_name, max_times, expected_max_time): - composite_error_handler = CompositeErrorHandler( - error_handlers=[ - DefaultErrorHandler( - response_filters=[HttpResponseFilter(action=ResponseAction.IGNORE, http_codes={403}, parameters={}, config={})], - max_time=max_time, - parameters={}, - config={}, - ) - for max_time in max_times - ], - parameters={}, - ) - - max_time = composite_error_handler.max_time - assert max_time == expected_max_time diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/test_default_error_handler.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/test_default_error_handler.py deleted file mode 100644 index 6fc99159afed..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/test_default_error_handler.py +++ /dev/null @@ -1,277 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from unittest.mock import MagicMock - -import pytest -import requests -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.constant_backoff_strategy import ConstantBackoffStrategy -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.exponential_backoff_strategy import ( - ExponentialBackoffStrategy, -) -from airbyte_cdk.sources.declarative.requesters.error_handlers.default_error_handler import DefaultErrorHandler, HttpResponseFilter -from airbyte_cdk.sources.streams.http.error_handlers.default_error_mapping import DEFAULT_ERROR_MAPPING -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, FailureType, ResponseAction - -SOME_BACKOFF_TIME = 60 - - -@pytest.mark.parametrize( - "test_name, http_status_code, expected_error_resolution", - [ - ( - "_with_http_response_status_200", - 200, - ErrorResolution( - response_action=ResponseAction.SUCCESS, - failure_type=None, - error_message=None, - ), - ), - ( - "_with_http_response_status_400", - 400, - DEFAULT_ERROR_MAPPING[400], - ), - ( - "_with_http_response_status_404", - 404, - DEFAULT_ERROR_MAPPING[404], - ), - ( - "_with_http_response_status_408", - 408, - DEFAULT_ERROR_MAPPING[408], - ), - ( - "_with_unmapped_http_status_418", - 418, - ErrorResolution( - response_action=ResponseAction.RETRY, - failure_type=FailureType.system_error, - error_message="Unexpected response with HTTP status 418", - ), - ), - ], -) -def test_default_error_handler_with_default_response_filter(test_name, http_status_code: int, expected_error_resolution: ErrorResolution): - response_mock = create_response(http_status_code) - error_handler = DefaultErrorHandler(config={}, parameters={}) - actual_error_resolution = error_handler.interpret_response(response_mock) - assert actual_error_resolution.response_action == expected_error_resolution.response_action - assert actual_error_resolution.failure_type == expected_error_resolution.failure_type - assert actual_error_resolution.error_message == expected_error_resolution.error_message - - -@pytest.mark.parametrize( - "test_name, http_status_code, test_response_filter, response_action, failure_type, error_message", - [ - ( - "_with_http_response_status_400_fail_with_default_failure_type", - 400, - HttpResponseFilter( - http_codes=[400], - action=ResponseAction.RETRY, - config={}, - parameters={}, - ), - ResponseAction.RETRY, - FailureType.system_error, - "Bad request. Please check your request parameters.", - ), - ( - "_with_http_response_status_402_fail_with_default_failure_type", - 402, - HttpResponseFilter( - http_codes=[402], - action=ResponseAction.FAIL, - config={}, - parameters={}, - ), - ResponseAction.FAIL, - FailureType.system_error, - "", - ), - ( - "_with_http_response_status_403_fail_with_default_failure_type", - 403, - HttpResponseFilter( - http_codes=[403], - action="FAIL", - config={}, - parameters={}, - ), - ResponseAction.FAIL, - FailureType.config_error, - "Forbidden. You don't have permission to access this resource.", - ), - ( - "_with_http_response_status_200_fail_with_contained_error_message", - 418, - HttpResponseFilter( - action=ResponseAction.FAIL, - error_message_contains="test", - config={}, - parameters={}, - ), - ResponseAction.FAIL, - FailureType.system_error, - "", - ), - ( - "_fail_with_predicate", - 418, - HttpResponseFilter( - action=ResponseAction.FAIL, - predicate="{{ 'error' in response }}", - config={}, - parameters={}, - ), - ResponseAction.FAIL, - FailureType.system_error, - "", - ), - ], -) -def test_default_error_handler_with_custom_response_filter( - test_name, http_status_code, test_response_filter, response_action, failure_type, error_message -): - response_mock = create_response(http_status_code) - if http_status_code == 418: - response_mock.json.return_value = {"error": "test"} - - response_filter = test_response_filter - error_handler = DefaultErrorHandler(config={}, parameters={}, response_filters=[response_filter]) - actual_error_resolution = error_handler.interpret_response(response_mock) - assert actual_error_resolution.response_action == response_action - assert actual_error_resolution.failure_type == failure_type - assert actual_error_resolution.error_message == error_message - - -@pytest.mark.parametrize( - "http_status_code, expected_response_action", - [ - (400, ResponseAction.RETRY), - (402, ResponseAction.FAIL), - ], -) -def test_default_error_handler_with_multiple_response_filters(http_status_code, expected_response_action): - response_filter_one = HttpResponseFilter( - http_codes=[400], - action=ResponseAction.RETRY, - config={}, - parameters={}, - ) - response_filter_two = HttpResponseFilter( - http_codes=[402], - action=ResponseAction.FAIL, - config={}, - parameters={}, - ) - - response_mock = create_response(http_status_code) - error_handler = DefaultErrorHandler(config={}, parameters={}, response_filters=[response_filter_one, response_filter_two]) - actual_error_resolution = error_handler.interpret_response(response_mock) - assert actual_error_resolution.response_action == expected_response_action - - -@pytest.mark.parametrize( - "first_response_filter_action, second_response_filter_action, expected_response_action", - [ - (ResponseAction.RETRY, ResponseAction.FAIL, ResponseAction.RETRY), - (ResponseAction.FAIL, ResponseAction.RETRY, ResponseAction.FAIL), - (ResponseAction.IGNORE, ResponseAction.IGNORE, ResponseAction.IGNORE), - (ResponseAction.SUCCESS, ResponseAction.IGNORE, ResponseAction.SUCCESS), - ], -) -def test_default_error_handler_with_conflicting_response_filters( - first_response_filter_action, second_response_filter_action, expected_response_action -): - response_filter_one = HttpResponseFilter( - http_codes=[400], - action=first_response_filter_action, - config={}, - parameters={}, - ) - response_filter_two = HttpResponseFilter( - http_codes=[400], - action=second_response_filter_action, - config={}, - parameters={}, - ) - - response_mock = create_response(400) - error_handler = DefaultErrorHandler(config={}, parameters={}, response_filters=[response_filter_one, response_filter_two]) - actual_error_resolution = error_handler.interpret_response(response_mock) - assert actual_error_resolution.response_action == expected_response_action - - -def test_default_error_handler_with_constant_backoff_strategy(): - response_mock = create_response(429) - error_handler = DefaultErrorHandler( - config={}, parameters={}, backoff_strategies=[ConstantBackoffStrategy(SOME_BACKOFF_TIME, config={}, parameters={})] - ) - assert error_handler.backoff_time(response_or_exception=response_mock, attempt_count=0) == SOME_BACKOFF_TIME - - -@pytest.mark.parametrize( - "attempt_count", - [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - ], -) -def test_default_error_handler_with_exponential_backoff_strategy(attempt_count): - response_mock = create_response(429) - error_handler = DefaultErrorHandler( - config={}, parameters={}, backoff_strategies=[ExponentialBackoffStrategy(factor=1, config={}, parameters={})] - ) - assert error_handler.backoff_time(response_or_exception=response_mock, attempt_count=attempt_count) == (1 * 2**attempt_count) - - -def create_response(status_code: int, headers=None, json_body=None): - url = "https://airbyte.io" - - response_mock = MagicMock(spec=requests.Response) - response_mock.status_code = status_code - response_mock.ok = status_code < 400 or status_code >= 600 - response_mock.url = url - response_mock.headers = headers or {} - response_mock.json.return_value = json_body or {} - response_mock.request = MagicMock(spec=requests.PreparedRequest) - return response_mock - - -def test_default_error_handler_with_unmapped_http_code(): - error_handler = DefaultErrorHandler(config={}, parameters={}) - response_mock = MagicMock(spec=requests.Response) - response_mock.status_code = 418 - response_mock.ok = False - response_mock.headers = {} - actual_error_resolution = error_handler.interpret_response(response_mock) - assert actual_error_resolution - assert actual_error_resolution.failure_type == FailureType.system_error - assert actual_error_resolution.response_action == ResponseAction.RETRY - - -def test_predicate_takes_precedent_over_default_mapped_error(): - response_mock = create_response(404, json_body={"error": "test"}) - - response_filter = HttpResponseFilter( - action=ResponseAction.FAIL, - predicate="{{ 'error' in response }}", - config={}, - parameters={}, - ) - - error_handler = DefaultErrorHandler(config={}, parameters={}, response_filters=[response_filter]) - actual_error_resolution = error_handler.interpret_response(response_mock) - assert actual_error_resolution.response_action == ResponseAction.FAIL - assert actual_error_resolution.failure_type == FailureType.system_error - assert actual_error_resolution.error_message == DEFAULT_ERROR_MAPPING.get(404).error_message diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/test_default_http_response_filter.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/test_default_http_response_filter.py deleted file mode 100644 index b3e4c517da26..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/test_default_http_response_filter.py +++ /dev/null @@ -1,63 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from unittest.mock import MagicMock - -import pytest -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.declarative.requesters.error_handlers.default_http_response_filter import DefaultHttpResponseFilter -from airbyte_cdk.sources.streams.http.error_handlers.default_error_mapping import DEFAULT_ERROR_MAPPING -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ResponseAction -from requests import RequestException, Response - - -@pytest.mark.parametrize( - "http_code, expected_error_resolution", - [ - pytest.param(403, DEFAULT_ERROR_MAPPING[403], id="403 mapping"), - pytest.param(404, DEFAULT_ERROR_MAPPING[404], id="404 mapping"), - pytest.param(408, DEFAULT_ERROR_MAPPING[408], id="408 mapping"), - ], -) -def test_matches_mapped_http_status_code(http_code, expected_error_resolution): - - response = MagicMock(spec=Response) - response.status_code = http_code - - response_filter = DefaultHttpResponseFilter( - config={}, - parameters={}, - ) - - actual_error_resolution = response_filter.matches(response) - assert actual_error_resolution == expected_error_resolution - - -def test_matches_mapped_exception(): - - exc = MagicMock(spec=RequestException) - - response_filter = DefaultHttpResponseFilter( - config={}, - parameters={}, - ) - - actual_error_resolution = response_filter.matches(exc) - assert actual_error_resolution == DEFAULT_ERROR_MAPPING[RequestException] - - -def test_unmapped_http_status_code_returns_default_error_resolution(): - - response = MagicMock(spec=Response) - response.status_code = 508 - - response_filter = DefaultHttpResponseFilter( - config={}, - parameters={}, - ) - - actual_error_resolution = response_filter.matches(response) - assert actual_error_resolution - assert actual_error_resolution.failure_type == FailureType.system_error - assert actual_error_resolution.response_action == ResponseAction.RETRY diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/test_http_response_filter.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/test_http_response_filter.py deleted file mode 100644 index 9c6817c268c4..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/error_handlers/test_http_response_filter.py +++ /dev/null @@ -1,197 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json - -import pytest -import requests -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.declarative.requesters.error_handlers import HttpResponseFilter -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, ResponseAction - - -@pytest.mark.parametrize( - "action, failure_type, http_codes, predicate, error_contains, error_message, response, expected_error_resolution", - [ - pytest.param( - ResponseAction.FAIL, - None, - {501, 503}, - "", - "", - "custom error message", - {"status_code": 503}, - ErrorResolution( - response_action=ResponseAction.FAIL, failure_type=FailureType.transient_error, error_message="custom error message" - ), - id="test_http_code_matches", - ), - pytest.param( - ResponseAction.IGNORE, - None, - {403}, - "", - "", - "", - {"status_code": 403}, - ErrorResolution( - response_action=ResponseAction.IGNORE, - failure_type=FailureType.config_error, - error_message="Forbidden. You don't have permission to access this resource.", - ), - id="test_http_code_matches_ignore_action", - ), - pytest.param( - ResponseAction.RETRY, - None, - {429}, - "", - "", - "", - {"status_code": 429}, - ErrorResolution( - response_action=ResponseAction.RETRY, failure_type=FailureType.transient_error, error_message="Too many requests." - ), - id="test_http_code_matches_retry_action", - ), - pytest.param( - ResponseAction.FAIL, - None, - {}, - '{{ response.the_body == "do_i_match" }}', - "", - "error message was: {{ response.failure }}", - {"status_code": 404, "json": {"the_body": "do_i_match", "failure": "i failed you"}}, - ErrorResolution( - response_action=ResponseAction.FAIL, failure_type=FailureType.system_error, error_message="error message was: i failed you" - ), - id="test_predicate_matches_json", - ), - pytest.param( - ResponseAction.FAIL, - None, - {}, - '{{ headers.the_key == "header_match" }}', - "", - "error from header: {{ headers.warning }}", - {"status_code": 404, "headers": {"the_key": "header_match", "warning": "this failed"}}, - ErrorResolution( - response_action=ResponseAction.FAIL, failure_type=FailureType.system_error, error_message="error from header: this failed" - ), - id="test_predicate_matches_headers", - ), - pytest.param( - ResponseAction.FAIL, - None, - {}, - None, - "DENIED", - "", - {"status_code": 403, "json": {"error": "REQUEST_DENIED"}}, - ErrorResolution( - response_action=ResponseAction.FAIL, - failure_type=FailureType.config_error, - error_message="Forbidden. You don't have permission to access this resource.", - ), - id="test_predicate_matches_headers", - ), - pytest.param( - ResponseAction.FAIL, - None, - {400, 404}, - '{{ headers.error == "invalid_input" or response.reason == "bad request"}}', - "", - "", - {"status_code": 403, "headers": {"error": "authentication_error"}, "json": {"reason": "permission denied"}}, - None, - id="test_response_does_not_match_filter", - ), - pytest.param( - ResponseAction.FAIL, - FailureType.config_error, - {403, 404}, - "", - "", - "check permissions", - {"status_code": 403}, - ErrorResolution(response_action=ResponseAction.FAIL, failure_type=FailureType.config_error, error_message="check permissions"), - id="test_http_code_matches_failure_type_config_error", - ), - pytest.param( - ResponseAction.FAIL, - FailureType.system_error, - {403, 404}, - "", - "", - "check permissions", - {"status_code": 403}, - ErrorResolution(response_action=ResponseAction.FAIL, failure_type=FailureType.system_error, error_message="check permissions"), - id="test_http_code_matches_failure_type_system_error", - ), - pytest.param( - ResponseAction.FAIL, - FailureType.transient_error, - {500}, - "", - "", - "rate limits", - {"status_code": 500}, - ErrorResolution(response_action=ResponseAction.FAIL, failure_type=FailureType.transient_error, error_message="rate limits"), - id="test_http_code_matches_failure_type_transient_error", - ), - pytest.param( - ResponseAction.RETRY, - FailureType.config_error, - {500}, - "", - "", - "rate limits", - {"status_code": 500}, - ErrorResolution(response_action=ResponseAction.RETRY, failure_type=FailureType.transient_error, error_message="rate limits"), - id="test_http_code_matches_failure_type_config_error_action_retry_uses_default_failure_type", - ), - pytest.param( - ResponseAction.RATE_LIMITED, - None, - {500}, - "", - "", - "rate limits", - {"status_code": 500}, - ErrorResolution( - response_action=ResponseAction.RATE_LIMITED, failure_type=FailureType.transient_error, error_message="rate limits" - ), - id="test_http_code_matches_response_action_rate_limited", - ), - ], -) -def test_matches( - requests_mock, action, failure_type, http_codes, predicate, error_contains, error_message, response, expected_error_resolution -): - requests_mock.register_uri( - "GET", - "https://airbyte.io/", - text=response.get("json") and json.dumps(response.get("json")), - headers=response.get("headers") or {}, - status_code=response.get("status_code"), - ) - response = requests.get("https://airbyte.io/") - response_filter = HttpResponseFilter( - action=action, - failure_type=failure_type, - config={}, - parameters={}, - http_codes=http_codes, - predicate=predicate, - error_message_contains=error_contains, - error_message=error_message, - ) - - actual_response_status = response_filter.matches(response) - if expected_error_resolution: - assert actual_response_status.response_action == expected_error_resolution.response_action - assert actual_response_status.failure_type == expected_error_resolution.failure_type - assert actual_response_status.error_message == expected_error_resolution.error_message - else: - assert actual_response_status is None diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/__init__.py deleted file mode 100644 index 46b7376756ec..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_cursor_pagination_strategy.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_cursor_pagination_strategy.py deleted file mode 100644 index 31d9ae5e05f5..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_cursor_pagination_strategy.py +++ /dev/null @@ -1,119 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json - -import pytest -import requests -from airbyte_cdk.sources.declarative.decoders.json_decoder import JsonDecoder -from airbyte_cdk.sources.declarative.interpolation.interpolated_boolean import InterpolatedBoolean -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.cursor_pagination_strategy import CursorPaginationStrategy - - -@pytest.mark.parametrize( - "template_string, stop_condition, expected_token, page_size", - [ - ("token", None, "token", None), - ("token", None, "token", 5), - ("{{ config.config_key }}", None, "config_value", None), - ("{{ last_record.id }}", None, 1, None), - ("{{ response._metadata.content }}", None, "content_value", None), - ("{{ parameters.key }}", None, "value", None), - ("{{ response.invalid_key }}", None, None, None), - ("token", InterpolatedBoolean("{{False}}", parameters={}), "token", None), - ("token", InterpolatedBoolean("{{True}}", parameters={}), None, None), - ("token", "{{True}}", None, None), - ( - "{{ headers.next }}", - InterpolatedBoolean("{{ not headers.has_more }}", parameters={}), - "ready_to_go", - None, - ), - ( - "{{ headers.link.next.url }}", - InterpolatedBoolean("{{ not headers.link.next.url }}", parameters={}), - "https://adventure.io/api/v1/records?page=2&per_page=100", - None, - ), - ], - ids=[ - "test_static_token", - "test_static_token_with_page_size", - "test_token_from_config", - "test_token_from_last_record", - "test_token_from_response", - "test_token_from_parameters", - "test_token_not_found", - "test_static_token_with_stop_condition_false", - "test_static_token_with_stop_condition_true", - "test_static_token_with_string_stop_condition", - "test_token_from_header", - "test_token_from_response_header_links", - ], -) -def test_cursor_pagination_strategy(template_string, stop_condition, expected_token, page_size): - decoder = JsonDecoder(parameters={}) - config = {"config_key": "config_value"} - parameters = {"key": "value"} - strategy = CursorPaginationStrategy( - page_size=page_size, - cursor_value=template_string, - config=config, - stop_condition=stop_condition, - decoder=decoder, - parameters=parameters, - ) - - response = requests.Response() - link_str = '; rel="next"' - response.headers = {"has_more": True, "next": "ready_to_go", "link": link_str} - response_body = {"_metadata": {"content": "content_value"}, "accounts": [], "end": 99, "total": 200, "characters": {}} - response._content = json.dumps(response_body).encode("utf-8") - last_record = {"id": 1, "more_records": True} - - token = strategy.next_page_token(response, 1, last_record) - assert expected_token == token - assert page_size == strategy.get_page_size() - - -def test_last_record_points_to_the_last_item_in_last_records_array(): - last_records = [{"id": 0, "more_records": True}, {"id": 1, "more_records": True}] - strategy = CursorPaginationStrategy( - page_size=1, - cursor_value="{{ last_record.id }}", - config={}, - parameters={}, - ) - - response = requests.Response() - next_page_token = strategy.next_page_token(response, 2, last_records[-1]) - assert next_page_token == 1 - - -def test_last_record_is_node_if_no_records(): - strategy = CursorPaginationStrategy( - page_size=1, - cursor_value="{{ last_record.id }}", - config={}, - parameters={}, - ) - - response = requests.Response() - next_page_token = strategy.next_page_token(response, 0, None) - assert next_page_token is None - - -def test_reset_with_initial_token(): - strategy = CursorPaginationStrategy( - page_size=10, - cursor_value="{{ response.next_page }}", - config={}, - parameters={}, - ) - - assert strategy.initial_token is None - - strategy.reset("https://for-all-mankind.nasa.com/api/v1/astronauts") - - assert strategy.initial_token == "https://for-all-mankind.nasa.com/api/v1/astronauts" diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_default_paginator.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_default_paginator.py deleted file mode 100644 index 41d973a9a8ce..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_default_paginator.py +++ /dev/null @@ -1,362 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -from unittest.mock import MagicMock - -import pytest -import requests -from airbyte_cdk.sources.declarative.decoders import JsonDecoder, XmlDecoder -from airbyte_cdk.sources.declarative.interpolation.interpolated_boolean import InterpolatedBoolean -from airbyte_cdk.sources.declarative.requesters.paginators.default_paginator import ( - DefaultPaginator, - PaginatorTestReadDecorator, - RequestOption, - RequestOptionType, -) -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.cursor_pagination_strategy import CursorPaginationStrategy -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.offset_increment import OffsetIncrement -from airbyte_cdk.sources.declarative.requesters.request_path import RequestPath - - -@pytest.mark.parametrize( - "page_token_request_option, stop_condition, expected_updated_path, expected_request_params, expected_headers, expected_body_data, expected_body_json, last_record, expected_next_page_token, limit, decoder, response_body", - [ - ( - RequestPath(parameters={}), - None, - "/next_url", - {"limit": 2}, - {}, - {}, - {}, - {"id": 1}, - {"next_page_token": "https://airbyte.io/next_url"}, - 2, - JsonDecoder, - {"next": "https://airbyte.io/next_url"}, - ), - ( - RequestOption(inject_into=RequestOptionType.request_parameter, field_name="from", parameters={}), - None, - None, - {"limit": 2, "from": "https://airbyte.io/next_url"}, - {}, - {}, - {}, - {"id": 1}, - {"next_page_token": "https://airbyte.io/next_url"}, - 2, - JsonDecoder, - {"next": "https://airbyte.io/next_url"}, - ), - ( - RequestOption(inject_into=RequestOptionType.request_parameter, field_name="from", parameters={}), - InterpolatedBoolean(condition="{{True}}", parameters={}), - None, - {"limit": 2}, - {}, - {}, - {}, - {"id": 1}, - None, - 2, - JsonDecoder, - {"next": "https://airbyte.io/next_url"}, - ), - ( - RequestOption(inject_into=RequestOptionType.header, field_name="from", parameters={}), - None, - None, - {"limit": 2}, - {"from": "https://airbyte.io/next_url"}, - {}, - {}, - {"id": 1}, - {"next_page_token": "https://airbyte.io/next_url"}, - 2, - JsonDecoder, - {"next": "https://airbyte.io/next_url"}, - ), - ( - RequestOption(inject_into=RequestOptionType.body_data, field_name="from", parameters={}), - None, - None, - {"limit": 2}, - {}, - {"from": "https://airbyte.io/next_url"}, - {}, - {"id": 1}, - {"next_page_token": "https://airbyte.io/next_url"}, - 2, - JsonDecoder, - {"next": "https://airbyte.io/next_url"}, - ), - ( - RequestOption(inject_into=RequestOptionType.body_json, field_name="from", parameters={}), - None, - None, - {"limit": 2}, - {}, - {}, - {"from": "https://airbyte.io/next_url"}, - {"id": 1}, - {"next_page_token": "https://airbyte.io/next_url"}, - 2, - JsonDecoder, - {"next": "https://airbyte.io/next_url"}, - ), - ( - RequestPath(parameters={}), - None, - "/next_url", - {"limit": 2}, - {}, - {}, - {}, - {"id": 1}, - {"next_page_token": "https://airbyte.io/next_url"}, - 2, - XmlDecoder, - b"https://airbyte.io/next_url", - ), - ( - RequestOption(inject_into=RequestOptionType.request_parameter, field_name="from", parameters={}), - None, - None, - {"limit": 2, "from": "https://airbyte.io/next_url"}, - {}, - {}, - {}, - {"id": 1}, - {"next_page_token": "https://airbyte.io/next_url"}, - 2, - XmlDecoder, - b"https://airbyte.io/next_url", - ), - ], - ids=[ - "test_default_paginator_path", - "test_default_paginator_request_param", - "test_default_paginator_no_token", - "test_default_paginator_cursor_header", - "test_default_paginator_cursor_body_data", - "test_default_paginator_cursor_body_json", - "test_default_paginator_path_with_xml_decoder", - "test_default_paginator_request_param_xml_decoder", - ], -) -def test_default_paginator_with_cursor( - page_token_request_option, - stop_condition, - expected_updated_path, - expected_request_params, - expected_headers, - expected_body_data, - expected_body_json, - last_record, - expected_next_page_token, - limit, - decoder, - response_body -): - page_size_request_option = RequestOption( - inject_into=RequestOptionType.request_parameter, field_name="{{parameters['page_limit']}}", parameters={"page_limit": "limit"} - ) - cursor_value = "{{ response.next }}" - url_base = "https://airbyte.io" - config = {} - parameters = {} - strategy = CursorPaginationStrategy( - page_size=limit, - cursor_value=cursor_value, - stop_condition=stop_condition, - decoder=decoder(parameters={}), - config=config, - parameters=parameters, - ) - paginator = DefaultPaginator( - page_size_option=page_size_request_option, - page_token_option=page_token_request_option, - pagination_strategy=strategy, - config=config, - url_base=url_base, - parameters={}, - ) - - response = requests.Response() - response.headers = {"A_HEADER": "HEADER_VALUE"} - response._content = json.dumps(response_body).encode("utf-8") if decoder == JsonDecoder else response_body - - actual_next_page_token = paginator.next_page_token(response, 2, last_record) - actual_next_path = paginator.path() - actual_request_params = paginator.get_request_params() - actual_headers = paginator.get_request_headers() - actual_body_data = paginator.get_request_body_data() - actual_body_json = paginator.get_request_body_json() - assert actual_next_page_token == expected_next_page_token - assert actual_next_path == expected_updated_path - assert actual_request_params == expected_request_params - assert actual_headers == expected_headers - assert actual_body_data == expected_body_data - assert actual_body_json == expected_body_json - - -@pytest.mark.parametrize( - "field_name_page_size_interpolation, field_name_page_token_interpolation, expected_request_params", - [ - ( - "{{parameters['page_limit']}}", - "{{parameters['page_token']}}", - {"parameters_limit": 50, "parameters_token": "https://airbyte.io/next_url"}, - ), - ("{{config['page_limit']}}", "{{config['page_token']}}", {"config_limit": 50, "config_token": "https://airbyte.io/next_url"}), - ], - ids=[ - "parameters_interpolation", - "config_interpolation", - ], -) -def test_paginator_request_param_interpolation( - field_name_page_size_interpolation: str, field_name_page_token_interpolation: str, expected_request_params: dict -): - config = {"page_limit": "config_limit", "page_token": "config_token"} - parameters = {"page_limit": "parameters_limit", "page_token": "parameters_token"} - page_size_request_option = RequestOption( - inject_into=RequestOptionType.request_parameter, - field_name=field_name_page_size_interpolation, - parameters=parameters, - ) - cursor_value = "{{ response.next }}" - url_base = "https://airbyte.io" - limit = 50 - strategy = CursorPaginationStrategy( - page_size=limit, - cursor_value=cursor_value, - stop_condition=None, - decoder=JsonDecoder(parameters={}), - config=config, - parameters=parameters, - ) - paginator = DefaultPaginator( - page_size_option=page_size_request_option, - page_token_option=RequestOption( - inject_into=RequestOptionType.request_parameter, field_name=field_name_page_token_interpolation, parameters=parameters - ), - pagination_strategy=strategy, - config=config, - url_base=url_base, - parameters=parameters, - ) - response = requests.Response() - response.headers = {"A_HEADER": "HEADER_VALUE"} - response_body = {"next": "https://airbyte.io/next_url"} - response._content = json.dumps(response_body).encode("utf-8") - last_record = {"id": 1} - paginator.next_page_token(response, 2, last_record) - actual_request_params = paginator.get_request_params() - assert actual_request_params == expected_request_params - - -def test_page_size_option_cannot_be_set_if_strategy_has_no_limit(): - page_size_request_option = RequestOption(inject_into=RequestOptionType.request_parameter, field_name="page_size", parameters={}) - page_token_request_option = RequestOption(inject_into=RequestOptionType.request_parameter, field_name="offset", parameters={}) - cursor_value = "{{ response.next }}" - url_base = "https://airbyte.io" - config = {} - parameters = {} - strategy = CursorPaginationStrategy(page_size=None, cursor_value=cursor_value, config=config, parameters=parameters) - try: - DefaultPaginator( - page_size_option=page_size_request_option, - page_token_option=page_token_request_option, - pagination_strategy=strategy, - config=config, - url_base=url_base, - parameters={}, - ) - assert False - except ValueError: - pass - - -@pytest.mark.parametrize( - "inject_on_first_request", - [ - (True), - (False), - ], - ids=[ - "test_reset_inject_on_first_request", - "test_reset_no_inject_on_first_request", - ], -) -def test_reset(inject_on_first_request): - page_size_request_option = RequestOption(inject_into=RequestOptionType.request_parameter, field_name="limit", parameters={}) - page_token_request_option = RequestOption(inject_into=RequestOptionType.request_parameter, field_name="offset", parameters={}) - url_base = "https://airbyte.io" - config = {} - strategy = OffsetIncrement(config={}, page_size=2, inject_on_first_request=inject_on_first_request, parameters={}) - paginator = DefaultPaginator( - strategy, config, url_base, parameters={}, page_size_option=page_size_request_option, page_token_option=page_token_request_option - ) - initial_request_parameters = paginator.get_request_params() - response = requests.Response() - response._content = json.dumps({}).encode("utf-8") - paginator.next_page_token(response, 2, {"a key": "a value"}) - request_parameters_for_second_request = paginator.get_request_params() - paginator.reset() - request_parameters_after_reset = paginator.get_request_params() - assert initial_request_parameters == request_parameters_after_reset - assert request_parameters_for_second_request != request_parameters_after_reset - - -def test_initial_token_with_offset_pagination(): - page_size_request_option = RequestOption(inject_into=RequestOptionType.request_parameter, field_name="limit", parameters={}) - page_token_request_option = RequestOption(inject_into=RequestOptionType.request_parameter, field_name="offset", parameters={}) - url_base = "https://airbyte.io" - config = {} - strategy = OffsetIncrement(config={}, page_size=2, parameters={}, inject_on_first_request=True) - paginator = DefaultPaginator( - strategy, config, url_base, parameters={}, page_size_option=page_size_request_option, page_token_option=page_token_request_option - ) - initial_request_parameters = paginator.get_request_params() - - assert initial_request_parameters == {"limit": 2, "offset": 0} - - -def test_limit_page_fetched(): - maximum_number_of_pages = 5 - number_of_next_performed = maximum_number_of_pages - 1 - paginator = PaginatorTestReadDecorator( - DefaultPaginator( - page_size_option=MagicMock(), - page_token_option=MagicMock(), - pagination_strategy=MagicMock(), - config=MagicMock(), - url_base=MagicMock(), - parameters={}, - ), - maximum_number_of_pages, - ) - - for _ in range(number_of_next_performed): - last_token = paginator.next_page_token(MagicMock(), 1, MagicMock()) - assert last_token - - assert not paginator.next_page_token(MagicMock(), 1, MagicMock()) - - -def test_paginator_with_page_option_no_page_size(): - pagination_strategy = OffsetIncrement(config={}, page_size=None, parameters={}) - - with pytest.raises(ValueError): - DefaultPaginator( - page_size_option=MagicMock(), - page_token_option=RequestOption("limit", RequestOptionType.request_parameter, parameters={}), - pagination_strategy=pagination_strategy, - config=MagicMock(), - url_base=MagicMock(), - parameters={}, - ), diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_no_paginator.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_no_paginator.py deleted file mode 100644 index 12b81010f43b..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_no_paginator.py +++ /dev/null @@ -1,12 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import requests -from airbyte_cdk.sources.declarative.requesters.paginators.no_pagination import NoPagination - - -def test(): - paginator = NoPagination(parameters={}) - next_page_token = paginator.next_page_token(requests.Response(), 0, []) - assert next_page_token == {} diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_offset_increment.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_offset_increment.py deleted file mode 100644 index d655dc9e6fa3..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_offset_increment.py +++ /dev/null @@ -1,80 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -from typing import Any, Optional - -import pytest -import requests -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.offset_increment import OffsetIncrement - - -@pytest.mark.parametrize( - "page_size, parameters, last_page_size, last_record, expected_next_page_token, expected_offset", - [ - pytest.param("2", {}, 2, {"id": 1}, 2, 2, id="test_same_page_size"), - pytest.param(2, {}, 2, {"id": 1}, 2, 2, id="test_same_page_size"), - pytest.param("{{ parameters['page_size'] }}", {"page_size": 3}, 2, {"id": 1}, None, 0, id="test_larger_page_size"), - pytest.param(None, {}, 0, [], None, 0, id="test_stop_if_no_records"), - pytest.param("{{ response['page_metadata']['limit'] }}", {}, 2, {"id": 1}, None, 0, id="test_page_size_from_response"), - ], -) -def test_offset_increment_paginator_strategy(page_size, parameters, last_page_size, last_record, expected_next_page_token, expected_offset): - paginator_strategy = OffsetIncrement(page_size=page_size, parameters=parameters, config={}) - assert paginator_strategy._offset == 0 - - response = requests.Response() - - response.headers = {"A_HEADER": "HEADER_VALUE"} - response_body = {"next": "https://airbyte.io/next_url", "page_metadata": {"limit": 5}} - response._content = json.dumps(response_body).encode("utf-8") - - next_page_token = paginator_strategy.next_page_token(response, last_page_size, last_record) - assert expected_next_page_token == next_page_token - assert expected_offset == paginator_strategy._offset - - paginator_strategy.reset() - assert 0 == paginator_strategy._offset - - -def test_offset_increment_paginator_strategy_rises(): - paginator_strategy = OffsetIncrement(page_size="{{ parameters['page_size'] }}", parameters={"page_size": "invalid value"}, config={}) - with pytest.raises(Exception) as exc: - paginator_strategy.get_page_size() - assert str(exc.value) == "invalid value is of type . Expected " - - -@pytest.mark.parametrize( - "inject_on_first_request, expected_initial_token", - [ - pytest.param(True, 0, id="test_with_inject_offset"), - pytest.param(False, None, id="test_without_inject_offset"), - ], -) -def test_offset_increment_paginator_strategy_initial_token(inject_on_first_request: bool, expected_initial_token: Optional[Any]): - paginator_strategy = OffsetIncrement(page_size=20, parameters={}, config={}, inject_on_first_request=inject_on_first_request) - - assert paginator_strategy.initial_token == expected_initial_token - - -@pytest.mark.parametrize( - "reset_value, expected_initial_token, expected_error", - [ - pytest.param(25, 25, None, id="test_reset_with_offset_value"), - pytest.param(None, 0, None, id="test_reset_with_default"), - pytest.param("Nope", None, ValueError, id="test_reset_with_invalid_value"), - ], -) -def test_offset_increment_reset(reset_value, expected_initial_token, expected_error): - paginator_strategy = OffsetIncrement(page_size=20, parameters={}, config={}, inject_on_first_request=True) - - if expected_error: - with pytest.raises(expected_error): - paginator_strategy.reset(reset_value=reset_value) - else: - if reset_value is None: - paginator_strategy.reset() - else: - paginator_strategy.reset(reset_value=reset_value) - assert paginator_strategy.initial_token == expected_initial_token diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_page_increment.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_page_increment.py deleted file mode 100644 index da2bf6d9450e..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_page_increment.py +++ /dev/null @@ -1,83 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -from typing import Any, Optional - -import pytest -import requests -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.page_increment import PageIncrement - - -@pytest.mark.parametrize( - "page_size, start_from, last_page_size, last_record, expected_next_page_token, expected_offset", - [ - pytest.param(2, 1, 2, {"id": 1}, 2, 2, id="test_same_page_size_start_from_0"), - pytest.param(3, 1, 2, {"id": 1}, None, 1, id="test_larger_page_size_start_from_0"), - pytest.param(2, 0, 2, {"id": 1}, 1, 1, id="test_same_page_size_start_from_1"), - pytest.param(3, 0, 2, {"id": 1}, None, 0, id="test_larger_page_size_start_from_0"), - pytest.param(None, 0, 0, None, None, 0, id="test_no_page_size"), - pytest.param("2", 0, 2, {"id": 1}, 1, 1, id="test_page_size_from_string"), - pytest.param("{{ config['value'] }}", 0, 2, {"id": 1}, 1, 1, id="test_page_size_from_config"), - ], -) -def test_page_increment_paginator_strategy(page_size, start_from, last_page_size, last_record, expected_next_page_token, expected_offset): - paginator_strategy = PageIncrement(page_size=page_size, parameters={}, start_from_page=start_from, config={"value": 2}) - assert paginator_strategy._page == start_from - - response = requests.Response() - - response.headers = {"A_HEADER": "HEADER_VALUE"} - response_body = {"next": "https://airbyte.io/next_url"} - response._content = json.dumps(response_body).encode("utf-8") - - next_page_token = paginator_strategy.next_page_token(response, last_page_size, last_record) - assert expected_next_page_token == next_page_token - assert expected_offset == paginator_strategy._page - - paginator_strategy.reset() - assert start_from == paginator_strategy._page - - -@pytest.mark.parametrize("page_size", [pytest.param("{{ config['value'] }}"), pytest.param("not-an-integer")]) -def test_page_increment_paginator_strategy_malformed_page_size(page_size): - with pytest.raises(Exception, match=".* is of type . Expected "): - PageIncrement(page_size=page_size, parameters={}, start_from_page=0, config={"value": "not-an-integer"}) - - -@pytest.mark.parametrize( - "inject_on_first_request, start_from_page, expected_initial_token", - [ - pytest.param(True, 0, 0, id="test_with_inject_offset_page_start_from_0"), - pytest.param(True, 12, 12, id="test_with_inject_offset_page_start_from_12"), - pytest.param(False, 2, None, id="test_without_inject_offset"), - ], -) -def test_page_increment_paginator_strategy_initial_token( - inject_on_first_request: bool, start_from_page: int, expected_initial_token: Optional[Any] -): - paginator_strategy = PageIncrement( - page_size=20, parameters={}, start_from_page=start_from_page, inject_on_first_request=inject_on_first_request, config={} - ) - - assert paginator_strategy.initial_token == expected_initial_token - - -@pytest.mark.parametrize( - "reset_value, expected_initial_token, expected_error", - [ - pytest.param(25, 25, None, id="test_reset_with_offset_value"), - pytest.param(None, 0, None, id="test_reset_with_default"), - pytest.param("Nope", None, ValueError, id="test_reset_with_invalid_value"), - ], -) -def test_offset_increment_reset(reset_value, expected_initial_token, expected_error): - paginator_strategy = PageIncrement(page_size=100, parameters={}, config={}, inject_on_first_request=True) - - if expected_error: - with pytest.raises(expected_error): - paginator_strategy.reset(reset_value=reset_value) - else: - paginator_strategy.reset(reset_value=reset_value) - assert paginator_strategy.initial_token == expected_initial_token diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_request_option.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_request_option.py deleted file mode 100644 index 5caa11f57f16..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_request_option.py +++ /dev/null @@ -1,43 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType - - -@pytest.mark.parametrize( - "option_type, field_name, expected_field_name", - [ - (RequestOptionType.request_parameter, "field", "field"), - (RequestOptionType.header, "field", "field"), - (RequestOptionType.body_data, "field", "field"), - (RequestOptionType.body_json, "field", "field"), - (RequestOptionType.request_parameter, "since_{{ parameters['cursor_field'] }}", "since_updated_at"), - (RequestOptionType.header, "since_{{ parameters['cursor_field'] }}", "since_updated_at"), - (RequestOptionType.body_data, "since_{{ parameters['cursor_field'] }}", "since_updated_at"), - (RequestOptionType.body_json, "since_{{ parameters['cursor_field'] }}", "since_updated_at"), - (RequestOptionType.request_parameter, "since_{{ config['cursor_field'] }}", "since_created_at"), - (RequestOptionType.header, "since_{{ config['cursor_field'] }}", "since_created_at"), - (RequestOptionType.body_data, "since_{{ config['cursor_field'] }}", "since_created_at"), - (RequestOptionType.body_json, "since_{{ config['cursor_field'] }}", "since_created_at"), - ], - ids=[ - "test_limit_param_with_field_name", - "test_limit_header_with_field_name", - "test_limit_data_with_field_name", - "test_limit_json_with_field_name", - "test_limit_param_with_parameters_interpolation", - "test_limit_header_with_parameters_interpolation", - "test_limit_data_with_parameters_interpolation", - "test_limit_json_with_parameters_interpolation", - "test_limit_param_with_config_interpolation", - "test_limit_header_with_config_interpolation", - "test_limit_data_with_config_interpolation", - "test_limit_json_with_config_interpolation", - ], -) -def test_request_option(option_type: RequestOptionType, field_name: str, expected_field_name: str): - request_option = RequestOption(inject_into=option_type, field_name=field_name, parameters={"cursor_field": "updated_at"}) - assert request_option.field_name.eval({"cursor_field": "created_at"}) == expected_field_name - assert request_option.inject_into == option_type diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_stop_condition.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_stop_condition.py deleted file mode 100644 index 86c5e65fcda9..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/paginators/test_stop_condition.py +++ /dev/null @@ -1,103 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from unittest.mock import Mock, call - -from airbyte_cdk.sources.declarative.incremental.declarative_cursor import DeclarativeCursor -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import PaginationStrategy -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.stop_condition import ( - CursorStopCondition, - PaginationStopCondition, - StopConditionPaginationStrategyDecorator, -) -from airbyte_cdk.sources.types import Record -from pytest import fixture - -ANY_RECORD = Mock() -NO_RECORD = None -ANY_RESPONSE = Mock() - - -@fixture -def mocked_cursor(): - return Mock(spec=DeclarativeCursor) - - -@fixture -def mocked_pagination_strategy(): - return Mock(spec=PaginationStrategy) - - -@fixture -def mocked_stop_condition(): - return Mock(spec=PaginationStopCondition) - - -def test_given_record_should_be_synced_when_is_met_return_false(mocked_cursor): - mocked_cursor.should_be_synced.return_value = True - assert not CursorStopCondition(mocked_cursor).is_met(ANY_RECORD) - - -def test_given_record_should_not_be_synced_when_is_met_return_true(mocked_cursor): - mocked_cursor.should_be_synced.return_value = False - assert CursorStopCondition(mocked_cursor).is_met(ANY_RECORD) - - -def test_given_stop_condition_is_met_when_next_page_token_then_return_none(mocked_pagination_strategy, mocked_stop_condition): - mocked_stop_condition.is_met.return_value = True - last_record = Mock(spec=Record) - - decorator = StopConditionPaginationStrategyDecorator(mocked_pagination_strategy, mocked_stop_condition) - - assert not decorator.next_page_token(ANY_RESPONSE, 2, last_record) - mocked_stop_condition.is_met.assert_has_calls([call(last_record)]) - - -def test_given_last_record_meets_condition_when_next_page_token_then_do_not_check_for_other_records( - mocked_pagination_strategy, mocked_stop_condition -): - mocked_stop_condition.is_met.return_value = True - last_record = Mock(spec=Record) - - StopConditionPaginationStrategyDecorator(mocked_pagination_strategy, mocked_stop_condition).next_page_token( - ANY_RESPONSE, 2, last_record - ) - - mocked_stop_condition.is_met.assert_called_once_with(last_record) - - -def test_given_stop_condition_is_not_met_when_next_page_token_then_delegate(mocked_pagination_strategy, mocked_stop_condition): - mocked_stop_condition.is_met.return_value = False - last_record = Mock(spec=Record) - decorator = StopConditionPaginationStrategyDecorator(mocked_pagination_strategy, mocked_stop_condition) - - next_page_token = decorator.next_page_token(ANY_RESPONSE, 2, last_record) - - assert next_page_token == mocked_pagination_strategy.next_page_token.return_value - mocked_pagination_strategy.next_page_token.assert_called_once_with(ANY_RESPONSE, 2, last_record) - mocked_stop_condition.is_met.assert_has_calls([call(last_record)]) - - -def test_given_no_records_when_next_page_token_then_delegate(mocked_pagination_strategy, mocked_stop_condition): - decorator = StopConditionPaginationStrategyDecorator(mocked_pagination_strategy, mocked_stop_condition) - - next_page_token = decorator.next_page_token(ANY_RESPONSE, 0, NO_RECORD) - - assert next_page_token == mocked_pagination_strategy.next_page_token.return_value - mocked_pagination_strategy.next_page_token.assert_called_once_with(ANY_RESPONSE, 0, NO_RECORD) - - -def test_when_reset_then_delegate(mocked_pagination_strategy, mocked_stop_condition): - decorator = StopConditionPaginationStrategyDecorator(mocked_pagination_strategy, mocked_stop_condition) - decorator.reset() - mocked_pagination_strategy.reset.assert_called_once_with() - - -def test_when_get_page_size_then_delegate(mocked_pagination_strategy, mocked_stop_condition): - decorator = StopConditionPaginationStrategyDecorator(mocked_pagination_strategy, mocked_stop_condition) - - page_size = decorator.get_page_size() - - assert page_size == mocked_pagination_strategy.get_page_size.return_value - mocked_pagination_strategy.get_page_size.assert_called_once_with() diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/request_options/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/request_options/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/request_options/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/request_options/test_datetime_based_request_options_provider.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/request_options/test_datetime_based_request_options_provider.py deleted file mode 100644 index 816f83f94f8a..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/request_options/test_datetime_based_request_options_provider.py +++ /dev/null @@ -1,120 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -import pytest -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType -from airbyte_cdk.sources.declarative.requesters.request_options import DatetimeBasedRequestOptionsProvider -from airbyte_cdk.sources.declarative.types import StreamSlice - - -@pytest.mark.parametrize( - "start_time_option, end_time_option, partition_field_start, partition_field_end, stream_slice, expected_request_options", - [ - pytest.param( - RequestOption(field_name="after", inject_into=RequestOptionType.request_parameter, parameters={}), - RequestOption(field_name="before", inject_into=RequestOptionType.request_parameter, parameters={}), - "custom_start", - "custom_end", - StreamSlice(cursor_slice={"custom_start": "2024-06-01", "custom_end": "2024-06-02"}, partition={}), - {"after": "2024-06-01", "before": "2024-06-02"}, - id="test_request_params", - ), - pytest.param( - RequestOption(field_name="after", inject_into=RequestOptionType.request_parameter, parameters={}), - RequestOption(field_name="before", inject_into=RequestOptionType.request_parameter, parameters={}), - None, - None, - StreamSlice(cursor_slice={"start_time": "2024-06-01", "end_time": "2024-06-02"}, partition={}), - {"after": "2024-06-01", "before": "2024-06-02"}, - id="test_request_params_with_default_partition_fields", - ), - pytest.param( - None, - RequestOption(field_name="before", inject_into=RequestOptionType.request_parameter, parameters={}), - None, - None, - StreamSlice(cursor_slice={"start_time": "2024-06-01", "end_time": "2024-06-02"}, partition={}), - {"before": "2024-06-02"}, - id="test_request_params_no_start_time_option", - ), - pytest.param( - RequestOption(field_name="after", inject_into=RequestOptionType.request_parameter, parameters={}), - None, - None, - None, - StreamSlice(cursor_slice={"start_time": "2024-06-01", "end_time": "2024-06-02"}, partition={}), - {"after": "2024-06-01"}, - id="test_request_params_no_end_time_option", - ), - pytest.param( - RequestOption(field_name="after", inject_into=RequestOptionType.request_parameter, parameters={}), - RequestOption(field_name="before", inject_into=RequestOptionType.request_parameter, parameters={}), - None, - None, - None, - {}, - id="test_request_params_no_slice", - ), - pytest.param( - RequestOption(field_name="after", inject_into=RequestOptionType.header, parameters={}), - RequestOption(field_name="before", inject_into=RequestOptionType.header, parameters={}), - "custom_start", - "custom_end", - StreamSlice(cursor_slice={"custom_start": "2024-06-01", "custom_end": "2024-06-02"}, partition={}), - {"after": "2024-06-01", "before": "2024-06-02"}, - id="test_request_headers", - ), - pytest.param( - RequestOption(field_name="after", inject_into=RequestOptionType.body_data, parameters={}), - RequestOption(field_name="before", inject_into=RequestOptionType.body_data, parameters={}), - "custom_start", - "custom_end", - StreamSlice(cursor_slice={"custom_start": "2024-06-01", "custom_end": "2024-06-02"}, partition={}), - {"after": "2024-06-01", "before": "2024-06-02"}, - id="test_request_request_body_data", - ), - pytest.param( - RequestOption(field_name="after", inject_into=RequestOptionType.body_json, parameters={}), - RequestOption(field_name="before", inject_into=RequestOptionType.body_json, parameters={}), - "custom_start", - "custom_end", - StreamSlice(cursor_slice={"custom_start": "2024-06-01", "custom_end": "2024-06-02"}, partition={}), - {"after": "2024-06-01", "before": "2024-06-02"}, - id="test_request_request_body_json", - ), - ], -) -def test_datetime_based_request_options_provider( - start_time_option, - end_time_option, - partition_field_start, - partition_field_end, - stream_slice, - expected_request_options -): - config = {} - request_options_provider = DatetimeBasedRequestOptionsProvider( - start_time_option=start_time_option, - end_time_option=end_time_option, - partition_field_start=partition_field_start, - partition_field_end=partition_field_end, - config=config, - parameters={} - ) - - request_option_type = start_time_option.inject_into if isinstance(start_time_option, RequestOption) else None - match request_option_type: - case RequestOptionType.request_parameter: - actual_request_options = request_options_provider.get_request_params(stream_slice=stream_slice) - case RequestOptionType.header: - actual_request_options = request_options_provider.get_request_headers(stream_slice=stream_slice) - case RequestOptionType.body_data: - actual_request_options = request_options_provider.get_request_body_data(stream_slice=stream_slice) - case RequestOptionType.body_json: - actual_request_options = request_options_provider.get_request_body_json(stream_slice=stream_slice) - case _: - # We defer to testing the default RequestOptions using get_request_params() - actual_request_options = request_options_provider.get_request_params(stream_slice=stream_slice) - - assert actual_request_options == expected_request_options diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/request_options/test_interpolated_request_options_provider.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/request_options/test_interpolated_request_options_provider.py deleted file mode 100644 index 19759832452b..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/request_options/test_interpolated_request_options_provider.py +++ /dev/null @@ -1,101 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -from airbyte_cdk.sources.declarative.requesters.request_options.interpolated_request_options_provider import ( - InterpolatedRequestOptionsProvider, -) - -state = {"date": "2021-01-01"} -stream_slice = {"start_date": "2020-01-01"} -next_page_token = {"offset": 12345, "page": 27} -config = {"option": "OPTION"} - - -@pytest.mark.parametrize( - "test_name, input_request_params, expected_request_params", - [ - ("test_static_param", {"a_static_request_param": "a_static_value"}, {"a_static_request_param": "a_static_value"}), - ("test_value_depends_on_state", {"read_from_state": "{{ stream_state['date'] }}"}, {"read_from_state": "2021-01-01"}), - ("test_value_depends_on_stream_slice", {"read_from_slice": "{{ stream_slice['start_date'] }}"}, {"read_from_slice": "2020-01-01"}), - ("test_value_depends_on_next_page_token", {"read_from_token": "{{ next_page_token['offset'] }}"}, {"read_from_token": "12345"}), - ("test_value_depends_on_config", {"read_from_config": "{{ config['option'] }}"}, {"read_from_config": "OPTION"}), - ( - "test_parameter_is_interpolated", - {"{{ stream_state['date'] }} - {{stream_slice['start_date']}} - {{next_page_token['offset']}} - {{config['option']}}": "ABC"}, - {"2021-01-01 - 2020-01-01 - 12345 - OPTION": "ABC"}, - ), - ("test_boolean_false_value", {"boolean_false": "{{ False }}"}, {"boolean_false": "False"}), - ("test_integer_falsy_value", {"integer_falsy": "{{ 0 }}"}, {"integer_falsy": "0"}), - ("test_number_falsy_value", {"number_falsy": "{{ 0.0 }}"}, {"number_falsy": "0.0"}), - ("test_string_falsy_value", {"string_falsy": "{{ '' }}"}, {}), - ("test_none_value", {"none_value": "{{ None }}"}, {"none_value": "None"}), - ], -) -def test_interpolated_request_params(test_name, input_request_params, expected_request_params): - provider = InterpolatedRequestOptionsProvider(config=config, request_parameters=input_request_params, parameters={}) - - actual_request_params = provider.get_request_params(stream_state=state, stream_slice=stream_slice, next_page_token=next_page_token) - - assert actual_request_params == expected_request_params - - -@pytest.mark.parametrize( - "test_name, input_request_json, expected_request_json", - [ - ("test_static_json", {"a_static_request_param": "a_static_value"}, {"a_static_request_param": "a_static_value"}), - ("test_value_depends_on_state", {"read_from_state": "{{ stream_state['date'] }}"}, {"read_from_state": "2021-01-01"}), - ("test_value_depends_on_stream_slice", {"read_from_slice": "{{ stream_slice['start_date'] }}"}, {"read_from_slice": "2020-01-01"}), - ("test_value_depends_on_next_page_token", {"read_from_token": "{{ next_page_token['offset'] }}"}, {"read_from_token": 12345}), - ("test_value_depends_on_config", {"read_from_config": "{{ config['option'] }}"}, {"read_from_config": "OPTION"}), - ( - "test_interpolated_keys", - {"{{ stream_state['date'] }}": 123, "{{ config['option'] }}": "ABC"}, - {"2021-01-01": 123, "OPTION": "ABC"}, - ), - ("test_boolean_false_value", {"boolean_false": "{{ False }}"}, {"boolean_false": False}), - ("test_integer_falsy_value", {"integer_falsy": "{{ 0 }}"}, {"integer_falsy": 0}), - ("test_number_falsy_value", {"number_falsy": "{{ 0.0 }}"}, {"number_falsy": 0.0}), - ("test_string_falsy_value", {"string_falsy": "{{ '' }}"}, {}), - ("test_none_value", {"none_value": "{{ None }}"}, {}), - ("test_string", """{"nested": { "key": "{{ config['option'] }}" }}""", {"nested": {"key": "OPTION"}}), - ("test_nested_objects", {"nested": {"key": "{{ config['option'] }}"}}, {"nested": {"key": "OPTION"}}), - ( - "test_nested_objects_interpolated keys", - {"nested": {"{{ stream_state['date'] }}": "{{ config['option'] }}"}}, - {"nested": {"2021-01-01": "OPTION"}}, - ), - ], -) -def test_interpolated_request_json(test_name, input_request_json, expected_request_json): - provider = InterpolatedRequestOptionsProvider(config=config, request_body_json=input_request_json, parameters={}) - - actual_request_json = provider.get_request_body_json(stream_state=state, stream_slice=stream_slice, next_page_token=next_page_token) - - assert actual_request_json == expected_request_json - - -@pytest.mark.parametrize( - "test_name, input_request_data, expected_request_data", - [ - ("test_static_map_data", {"a_static_request_param": "a_static_value"}, {"a_static_request_param": "a_static_value"}), - ("test_map_depends_on_stream_slice", {"read_from_slice": "{{ stream_slice['start_date'] }}"}, {"read_from_slice": "2020-01-01"}), - ("test_map_depends_on_config", {"read_from_config": "{{ config['option'] }}"}, {"read_from_config": "OPTION"}), - ("test_defaults_to_empty_dict", None, {}), - ("test_interpolated_keys", {"{{ stream_state['date'] }} - {{ next_page_token['offset'] }}": "ABC"}, {"2021-01-01 - 12345": "ABC"}), - ], -) -def test_interpolated_request_data(test_name, input_request_data, expected_request_data): - provider = InterpolatedRequestOptionsProvider(config=config, request_body_data=input_request_data, parameters={}) - - actual_request_data = provider.get_request_body_data(stream_state=state, stream_slice=stream_slice, next_page_token=next_page_token) - - assert actual_request_data == expected_request_data - - -def test_error_on_create_for_both_request_json_and_data(): - request_json = {"body_key": "{{ stream_slice['start_date'] }}"} - request_data = "interpolate_me=5&invalid={{ config['option'] }}" - with pytest.raises(ValueError): - InterpolatedRequestOptionsProvider(config=config, request_body_json=request_json, request_body_data=request_data, parameters={}) diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/test_http_job_repository.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/test_http_job_repository.py deleted file mode 100644 index 90c1f9854baf..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/test_http_job_repository.py +++ /dev/null @@ -1,246 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - - -import json -from unittest import TestCase -from unittest.mock import Mock - -import pytest -from airbyte_cdk.sources.declarative.async_job.status import AsyncJobStatus -from airbyte_cdk.sources.declarative.decoders import NoopDecoder -from airbyte_cdk.sources.declarative.decoders.json_decoder import JsonDecoder -from airbyte_cdk.sources.declarative.extractors import DpathExtractor, RecordSelector, ResponseToFileExtractor -from airbyte_cdk.sources.declarative.requesters.error_handlers import DefaultErrorHandler -from airbyte_cdk.sources.declarative.requesters.http_job_repository import AsyncHttpJobRepository -from airbyte_cdk.sources.declarative.requesters.http_requester import HttpRequester -from airbyte_cdk.sources.declarative.requesters.paginators import DefaultPaginator -from airbyte_cdk.sources.declarative.requesters.paginators.strategies.cursor_pagination_strategy import CursorPaginationStrategy -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType -from airbyte_cdk.sources.declarative.requesters.requester import HttpMethod -from airbyte_cdk.sources.declarative.retrievers.simple_retriever import SimpleRetriever -from airbyte_cdk.sources.types import StreamSlice -from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer -from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse - -_ANY_CONFIG = {} -_ANY_SLICE = StreamSlice(partition={}, cursor_slice={}) -_URL_BASE = "https://api.sendgrid.com/v3/" -_EXPORT_PATH = "marketing/contacts/exports" -_EXPORT_URL = f"{_URL_BASE}{_EXPORT_PATH}" -_A_JOB_ID = "a-job-id" -_ANOTHER_JOB_ID = "another-job-id" -_JOB_FIRST_URL = "https://job.result.api.com/1" -_JOB_SECOND_URL = "https://job.result.api.com/2" -_A_CSV_WITH_ONE_RECORD = """id,value -a_record_id,a_value -""" -_A_CURSOR_FOR_PAGINATION = "a-cursor-for-pagination" - - -class HttpJobRepositoryTest(TestCase): - def setUp(self) -> None: - message_repository = Mock() - error_handler = DefaultErrorHandler(config=_ANY_CONFIG, parameters={}) - - self._create_job_requester = HttpRequester( - name="stream : create_job", - url_base=_URL_BASE, - path=_EXPORT_PATH, - error_handler=error_handler, - http_method=HttpMethod.POST, - config=_ANY_CONFIG, - disable_retries=False, - parameters={}, - message_repository=message_repository, - use_cache=False, - stream_response=False, - ) - - self._polling_job_requester = HttpRequester( - name="stream : polling", - url_base=_URL_BASE, - path=_EXPORT_PATH + "/{{stream_slice['create_job_response'].json()['id']}}", - error_handler=error_handler, - http_method=HttpMethod.GET, - config=_ANY_CONFIG, - disable_retries=False, - parameters={}, - message_repository=message_repository, - use_cache=False, - stream_response=False, - ) - - self._download_retriever = SimpleRetriever( - requester=HttpRequester( - name="stream : fetch_result", - url_base="", - path="{{stream_slice['url']}}", - error_handler=error_handler, - http_method=HttpMethod.GET, - config=_ANY_CONFIG, - disable_retries=False, - parameters={}, - message_repository=message_repository, - use_cache=False, - stream_response=True, - ), - record_selector=RecordSelector( - extractor=ResponseToFileExtractor(), - record_filter=None, - transformations=[], - schema_normalization=TypeTransformer(TransformConfig.NoTransform), - config=_ANY_CONFIG, - parameters={}, - ), - primary_key=None, - name="any name", - paginator=DefaultPaginator( - decoder=NoopDecoder(), - page_size_option=None, - page_token_option=RequestOption( - field_name="locator", - inject_into=RequestOptionType.request_parameter, - parameters={}, - ), - pagination_strategy=CursorPaginationStrategy( - cursor_value="{{ headers['Sforce-Locator'] }}", - decoder=NoopDecoder(), - config=_ANY_CONFIG, - parameters={}, - ), - url_base=_URL_BASE, - config=_ANY_CONFIG, - parameters={}, - ), - config=_ANY_CONFIG, - parameters={}, - ) - - self._repository = AsyncHttpJobRepository( - creation_requester=self._create_job_requester, - polling_requester=self._polling_job_requester, - download_retriever=self._download_retriever, - abort_requester=None, - delete_requester=None, - status_extractor=DpathExtractor(decoder=JsonDecoder(parameters={}), field_path=["status"], config={}, parameters={} or {}), - status_mapping={ - "ready": AsyncJobStatus.COMPLETED, - "failure": AsyncJobStatus.FAILED, - "pending": AsyncJobStatus.RUNNING, - }, - urls_extractor=DpathExtractor(decoder=JsonDecoder(parameters={}), field_path=["urls"], config={}, parameters={} or {}), - ) - - self._http_mocker = HttpMocker() - self._http_mocker.__enter__() - - def tearDown(self) -> None: - self._http_mocker.__exit__(None, None, None) - - def test_given_different_statuses_when_update_jobs_status_then_update_status_properly(self) -> None: - self._mock_create_response(_A_JOB_ID) - self._http_mocker.get( - HttpRequest(url=f"{_EXPORT_URL}/{_A_JOB_ID}"), - [ - HttpResponse(body=json.dumps({"id": _A_JOB_ID, "status": "pending"})), - HttpResponse(body=json.dumps({"id": _A_JOB_ID, "status": "failure"})), - HttpResponse(body=json.dumps({"id": _A_JOB_ID, "status": "ready"})), - ] - ) - job = self._repository.start(_ANY_SLICE) - - self._repository.update_jobs_status([job]) - assert job.status() == AsyncJobStatus.RUNNING - self._repository.update_jobs_status([job]) - assert job.status() == AsyncJobStatus.FAILED - self._repository.update_jobs_status([job]) - assert job.status() == AsyncJobStatus.COMPLETED - - def test_given_unknown_status_when_update_jobs_status_then_raise_error(self) -> None: - self._mock_create_response(_A_JOB_ID) - self._http_mocker.get( - HttpRequest(url=f"{_EXPORT_URL}/{_A_JOB_ID}"), - HttpResponse(body=json.dumps({"id": _A_JOB_ID, "status": "invalid_status"})), - ) - job = self._repository.start(_ANY_SLICE) - - with pytest.raises(ValueError): - self._repository.update_jobs_status([job]) - - def test_given_multiple_jobs_when_update_jobs_status_then_all_the_jobs_are_updated(self) -> None: - self._mock_create_response(_A_JOB_ID) - self._http_mocker.get( - HttpRequest(url=f"{_EXPORT_URL}/{_A_JOB_ID}"), - HttpResponse(body=json.dumps({"id": _A_JOB_ID, "status": "ready"})), - ) - self._mock_create_response(_ANOTHER_JOB_ID) - self._http_mocker.get( - HttpRequest(url=f"{_EXPORT_URL}/{_ANOTHER_JOB_ID}"), - HttpResponse(body=json.dumps({"id": _A_JOB_ID, "status": "ready"})), - ) - a_job = self._repository.start(_ANY_SLICE) - another_job = self._repository.start(_ANY_SLICE) - - self._repository.update_jobs_status([a_job, another_job]) - - assert a_job.status() == AsyncJobStatus.COMPLETED - assert another_job.status() == AsyncJobStatus.COMPLETED - - def test_given_pagination_when_fetch_records_then_yield_records_from_all_pages(self) -> None: - self._mock_create_response(_A_JOB_ID) - self._http_mocker.get( - HttpRequest(url=f"{_EXPORT_URL}/{_A_JOB_ID}"), - HttpResponse(body=json.dumps({ - "id": _A_JOB_ID, - "status": "ready", - "urls": [_JOB_FIRST_URL] - })) - ) - self._http_mocker.get( - HttpRequest(url=_JOB_FIRST_URL), - HttpResponse(body=_A_CSV_WITH_ONE_RECORD, headers={"Sforce-Locator": _A_CURSOR_FOR_PAGINATION}), - ) - self._http_mocker.get( - HttpRequest(url=_JOB_FIRST_URL, query_params={"locator": _A_CURSOR_FOR_PAGINATION}), - HttpResponse(body=_A_CSV_WITH_ONE_RECORD), - ) - - job = self._repository.start(_ANY_SLICE) - self._repository.update_jobs_status([job]) - records = list(self._repository.fetch_records(job)) - - assert len(records) == 2 - - def test_given_multiple_urls_when_fetch_records_then_fetch_from_multiple_urls(self) -> None: - self._mock_create_response(_A_JOB_ID) - self._http_mocker.get( - HttpRequest(url=f"{_EXPORT_URL}/{_A_JOB_ID}"), - HttpResponse(body=json.dumps({ - "id": _A_JOB_ID, - "status": "ready", - "urls": [ - _JOB_FIRST_URL, - _JOB_SECOND_URL, - ] - })) - ) - self._http_mocker.get( - HttpRequest(url=_JOB_FIRST_URL), - HttpResponse(body=_A_CSV_WITH_ONE_RECORD), - ) - self._http_mocker.get( - HttpRequest(url=_JOB_SECOND_URL), - HttpResponse(body=_A_CSV_WITH_ONE_RECORD), - ) - - job = self._repository.start(_ANY_SLICE) - self._repository.update_jobs_status([job]) - records = list(self._repository.fetch_records(job)) - - assert len(records) == 2 - - def _mock_create_response(self, job_id: str) -> None: - self._http_mocker.post( - HttpRequest(url=_EXPORT_URL), - HttpResponse(body=json.dumps({"id": job_id})), - ) diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/test_http_requester.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/test_http_requester.py deleted file mode 100644 index 404bf9f50e15..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/test_http_requester.py +++ /dev/null @@ -1,690 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Mapping, Optional -from unittest import mock -from unittest.mock import MagicMock -from urllib.parse import parse_qs, urlparse - -import pytest as pytest -import requests -from airbyte_cdk.sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies import ConstantBackoffStrategy, ExponentialBackoffStrategy -from airbyte_cdk.sources.declarative.requesters.error_handlers.default_error_handler import DefaultErrorHandler -from airbyte_cdk.sources.declarative.requesters.error_handlers.error_handler import ErrorHandler -from airbyte_cdk.sources.declarative.requesters.http_requester import HttpMethod, HttpRequester -from airbyte_cdk.sources.declarative.requesters.request_options import InterpolatedRequestOptionsProvider -from airbyte_cdk.sources.message import MessageRepository -from airbyte_cdk.sources.streams.http.exceptions import RequestBodyException, UserDefinedBackoffException -from airbyte_cdk.sources.types import Config -from requests import PreparedRequest - - -@pytest.fixture -def http_requester_factory(): - def factory( - name: str = "name", - url_base: str = "https://test_base_url.com", - path: str = "/", - http_method: str = HttpMethod.GET, - request_options_provider: Optional[InterpolatedRequestOptionsProvider] = None, - authenticator: Optional[DeclarativeAuthenticator] = None, - error_handler: Optional[ErrorHandler] = None, - config: Optional[Config] = None, - parameters: Mapping[str, Any] = None, - disable_retries: bool = False, - message_repository: Optional[MessageRepository] = None, - use_cache: bool = False, - ) -> HttpRequester: - return HttpRequester( - name=name, - url_base=url_base, - path=path, - config=config or {}, - parameters=parameters or {}, - authenticator=authenticator, - http_method=http_method, - request_options_provider=request_options_provider, - error_handler=error_handler, - disable_retries=disable_retries, - message_repository=message_repository or MagicMock(), - use_cache=use_cache, - ) - - return factory - - -def test_http_requester(): - http_method = HttpMethod.GET - - request_options_provider = MagicMock() - request_params = {"param": "value"} - request_body_data = "body_key_1=value_1&body_key_2=value2" - request_body_json = {"body_field": "body_value"} - request_options_provider.get_request_params.return_value = request_params - request_options_provider.get_request_body_data.return_value = request_body_data - request_options_provider.get_request_body_json.return_value = request_body_json - - request_headers_provider = MagicMock() - request_headers = {"header": "value"} - request_headers_provider.get_request_headers.return_value = request_headers - - authenticator = MagicMock() - - error_handler = MagicMock() - max_retries = 10 - backoff_time = 1000 - response_status = MagicMock() - response_status.retry_in.return_value = 10 - error_handler.max_retries = max_retries - error_handler.backoff_time.return_value = backoff_time - - config = {"url": "https://airbyte.io"} - stream_slice = {"id": "1234"} - - name = "stream_name" - - requester = HttpRequester( - name=name, - url_base=InterpolatedString.create("{{ config['url'] }}", parameters={}), - path=InterpolatedString.create("v1/{{ stream_slice['id'] }}", parameters={}), - http_method=http_method, - request_options_provider=request_options_provider, - authenticator=authenticator, - error_handler=error_handler, - config=config, - parameters={}, - ) - - assert requester.get_url_base() == "https://airbyte.io/" - assert requester.get_path(stream_state={}, stream_slice=stream_slice, next_page_token={}) == "v1/1234" - assert requester.get_authenticator() == authenticator - assert requester.get_method() == http_method - assert requester.get_request_params(stream_state={}, stream_slice=None, next_page_token=None) == request_params - assert requester.get_request_body_data(stream_state={}, stream_slice=None, next_page_token=None) == request_body_data - assert requester.get_request_body_json(stream_state={}, stream_slice=None, next_page_token=None) == request_body_json - - -@pytest.mark.parametrize( - "test_name, base_url, expected_base_url", - [ - ("test_no_trailing_slash", "https://example.com", "https://example.com/"), - ("test_with_trailing_slash", "https://example.com/", "https://example.com/"), - ("test_with_v1_no_trailing_slash", "https://example.com/v1", "https://example.com/v1/"), - ("test_with_v1_with_trailing_slash", "https://example.com/v1/", "https://example.com/v1/"), - ], -) -def test_base_url_has_a_trailing_slash(test_name, base_url, expected_base_url): - requester = HttpRequester( - name="name", - url_base=base_url, - path="deals", - http_method=HttpMethod.GET, - request_options_provider=MagicMock(), - authenticator=MagicMock(), - error_handler=MagicMock(), - config={}, - parameters={}, - ) - assert requester.get_url_base() == expected_base_url - - -@pytest.mark.parametrize( - "test_name, path, expected_path", - [ - ("test_no_leading_slash", "deals", "deals"), - ("test_with_leading_slash", "/deals", "deals"), - ("test_with_v1_no_leading_slash", "v1/deals", "v1/deals"), - ("test_with_v1_with_leading_slash", "/v1/deals", "v1/deals"), - ("test_with_v1_with_trailing_slash", "v1/deals/", "v1/deals/"), - ], -) -def test_path(test_name, path, expected_path): - requester = HttpRequester( - name="name", - url_base="https://example.com", - path=path, - http_method=HttpMethod.GET, - request_options_provider=MagicMock(), - authenticator=MagicMock(), - error_handler=MagicMock(), - config={}, - parameters={}, - ) - assert requester.get_path(stream_state={}, stream_slice={}, next_page_token={}) == expected_path - - -def create_requester( - url_base: Optional[str] = None, - parameters: Optional[Mapping[str, Any]] = {}, - config: Optional[Config] = None, - path: Optional[str] = None, - authenticator: Optional[DeclarativeAuthenticator] = None, - error_handler: Optional[ErrorHandler] = None, -) -> HttpRequester: - requester = HttpRequester( - name="name", - url_base=url_base or "https://example.com", - path=path or "deals", - http_method=HttpMethod.GET, - request_options_provider=None, - authenticator=authenticator, - error_handler=error_handler, - config=config or {}, - parameters=parameters or {}, - ) - requester._http_client._session.send = MagicMock() - req = requests.Response() - req.status_code = 200 - requester._http_client._session.send.return_value = req - return requester - - -def test_basic_send_request(): - options_provider = MagicMock() - options_provider.get_request_headers.return_value = {"my_header": "my_value"} - requester = create_requester() - requester._request_options_provider = options_provider - requester.send_request() - sent_request: PreparedRequest = requester._http_client._session.send.call_args_list[0][0][0] - assert sent_request.method == "GET" - assert sent_request.url == "https://example.com/deals" - assert sent_request.headers["my_header"] == "my_value" - assert sent_request.body is None - - -@pytest.mark.parametrize( - "provider_data, provider_json, param_data, param_json, authenticator_data, authenticator_json, expected_exception, expected_body", - [ - # merging data params from the three sources - ({"field": "value"}, None, None, None, None, None, None, "field=value"), - ({"field": "value"}, None, {"field2": "value"}, None, None, None, None, "field=value&field2=value"), - ({"field": "value"}, None, {"field2": "value"}, None, {"authfield": "val"}, None, None, "field=value&field2=value&authfield=val"), - ({"field": "value"}, None, {"field": "value"}, None, None, None, ValueError, None), - ({"field": "value"}, None, None, None, {"field": "value"}, None, ValueError, None), - ({"field": "value"}, None, {"field2": "value"}, None, {"field": "value"}, None, ValueError, None), - # merging json params from the three sources - (None, {"field": "value"}, None, None, None, None, None, '{"field": "value"}'), - (None, {"field": "value"}, None, {"field2": "value"}, None, None, None, '{"field": "value", "field2": "value"}'), - ( - None, - {"field": "value"}, - None, - {"field2": "value"}, - None, - {"authfield": "val"}, - None, - '{"field": "value", "field2": "value", "authfield": "val"}', - ), - (None, {"field": "value"}, None, {"field": "value"}, None, None, ValueError, None), - (None, {"field": "value"}, None, None, None, {"field": "value"}, ValueError, None), - # raise on mixed data and json params - ({"field": "value"}, {"field": "value"}, None, None, None, None, RequestBodyException, None), - ({"field": "value"}, None, None, {"field": "value"}, None, None, RequestBodyException, None), - (None, None, {"field": "value"}, {"field": "value"}, None, None, RequestBodyException, None), - (None, None, None, None, {"field": "value"}, {"field": "value"}, RequestBodyException, None), - ({"field": "value"}, None, None, None, None, {"field": "value"}, RequestBodyException, None), - ], -) -def test_send_request_data_json( - provider_data, provider_json, param_data, param_json, authenticator_data, authenticator_json, expected_exception, expected_body -): - options_provider = MagicMock() - options_provider.get_request_body_data.return_value = provider_data - options_provider.get_request_body_json.return_value = provider_json - authenticator = MagicMock() - authenticator.get_request_body_data.return_value = authenticator_data - authenticator.get_request_body_json.return_value = authenticator_json - requester = create_requester(authenticator=authenticator) - requester._request_options_provider = options_provider - if expected_exception is not None: - with pytest.raises(expected_exception): - requester.send_request(request_body_data=param_data, request_body_json=param_json) - else: - requester.send_request(request_body_data=param_data, request_body_json=param_json) - sent_request: PreparedRequest = requester._http_client._session.send.call_args_list[0][0][0] - if expected_body is not None: - assert sent_request.body == expected_body.decode("UTF-8") if not isinstance(expected_body, str) else expected_body - - -@pytest.mark.parametrize( - "provider_data, param_data, authenticator_data, expected_exception, expected_body", - [ - # assert body string from one source works - ("field=value", None, None, None, "field=value"), - (None, "field=value", None, None, "field=value"), - (None, None, "field=value", None, "field=value"), - # assert body string from multiple sources fails - ("field=value", "field=value", None, ValueError, None), - ("field=value", None, "field=value", ValueError, None), - (None, "field=value", "field=value", ValueError, None), - ("field=value", "field=value", "field=value", ValueError, None), - # assert body string and mapping from different source fails - ("field=value", {"abc": "def"}, None, ValueError, None), - ({"abc": "def"}, "field=value", None, ValueError, None), - ("field=value", None, {"abc": "def"}, ValueError, None), - ], -) -def test_send_request_string_data(provider_data, param_data, authenticator_data, expected_exception, expected_body): - options_provider = MagicMock() - options_provider.get_request_body_data.return_value = provider_data - authenticator = MagicMock() - authenticator.get_request_body_data.return_value = authenticator_data - requester = create_requester(authenticator=authenticator) - requester._request_options_provider = options_provider - if expected_exception is not None: - with pytest.raises(expected_exception): - requester.send_request(request_body_data=param_data) - else: - requester.send_request(request_body_data=param_data) - sent_request: PreparedRequest = requester._http_client._session.send.call_args_list[0][0][0] - if expected_body is not None: - assert sent_request.body == expected_body - - -@pytest.mark.parametrize( - "provider_headers, param_headers, authenticator_headers, expected_exception, expected_headers", - [ - # merging headers from the three sources - ({"header": "value"}, None, None, None, {"header": "value"}), - ({"header": "value"}, {"header2": "value"}, None, None, {"header": "value", "header2": "value"}), - ( - {"header": "value"}, - {"header2": "value"}, - {"authheader": "val"}, - None, - {"header": "value", "header2": "value", "authheader": "val"}, - ), - # raise on conflicting headers - ({"header": "value"}, {"header": "value"}, None, ValueError, None), - ({"header": "value"}, None, {"header": "value"}, ValueError, None), - ({"header": "value"}, {"header2": "value"}, {"header": "value"}, ValueError, None), - ], -) -def test_send_request_headers(provider_headers, param_headers, authenticator_headers, expected_exception, expected_headers): - # headers set by the requests framework, do not validate - default_headers = {"User-Agent": mock.ANY, "Accept-Encoding": mock.ANY, "Accept": mock.ANY, "Connection": mock.ANY} - options_provider = MagicMock() - options_provider.get_request_headers.return_value = provider_headers - authenticator = MagicMock() - authenticator.get_auth_header.return_value = authenticator_headers or {} - requester = create_requester(authenticator=authenticator) - requester._request_options_provider = options_provider - if expected_exception is not None: - with pytest.raises(expected_exception): - requester.send_request(request_headers=param_headers) - else: - requester.send_request(request_headers=param_headers) - sent_request: PreparedRequest = requester._http_client._session.send.call_args_list[0][0][0] - assert sent_request.headers == {**default_headers, **expected_headers} - - -@pytest.mark.parametrize( - "provider_params, param_params, authenticator_params, expected_exception, expected_params", - [ - # merging params from the three sources - ({"param": "value"}, None, None, None, {"param": "value"}), - ({"param": "value"}, {"param2": "value"}, None, None, {"param": "value", "param2": "value"}), - ({"param": "value"}, {"param2": "value"}, {"authparam": "val"}, None, {"param": "value", "param2": "value", "authparam": "val"}), - # raise on conflicting params - ({"param": "value"}, {"param": "value"}, None, ValueError, None), - ({"param": "value"}, None, {"param": "value"}, ValueError, None), - ({"param": "value"}, {"param2": "value"}, {"param": "value"}, ValueError, None), - ], -) -def test_send_request_params(provider_params, param_params, authenticator_params, expected_exception, expected_params): - options_provider = MagicMock() - options_provider.get_request_params.return_value = provider_params - authenticator = MagicMock() - authenticator.get_request_params.return_value = authenticator_params - requester = create_requester(authenticator=authenticator) - requester._request_options_provider = options_provider - if expected_exception is not None: - with pytest.raises(expected_exception): - requester.send_request(request_params=param_params) - else: - requester.send_request(request_params=param_params) - sent_request: PreparedRequest = requester._http_client._session.send.call_args_list[0][0][0] - parsed_url = urlparse(sent_request.url) - query_params = {key: value[0] for key, value in parse_qs(parsed_url.query).items()} - assert query_params == expected_params - - -@pytest.mark.parametrize( - "request_parameters, config, expected_query_params", - [ - pytest.param( - {"k": '{"updatedDateFrom": "2023-08-20T00:00:00Z", "updatedDateTo": "2023-08-20T23:59:59Z"}'}, - {}, - "k=%7B%22updatedDateFrom%22%3A+%222023-08-20T00%3A00%3A00Z%22%2C+%22updatedDateTo%22%3A+%222023-08-20T23%3A59%3A59Z%22%7D", - id="test-request-parameter-dictionary", - ), - pytest.param( - {"k": "1,2"}, - {}, - "k=1%2C2", # k=1,2 - id="test-request-parameter-comma-separated-numbers", - ), - pytest.param( - {"k": "a,b"}, - {}, - "k=a%2Cb", # k=a,b - id="test-request-parameter-comma-separated-strings", - ), - pytest.param( - {"k": '{{ config["k"] }}'}, - {"k": {"updatedDateFrom": "2023-08-20T00:00:00Z", "updatedDateTo": "2023-08-20T23:59:59Z"}}, - # {'updatedDateFrom': '2023-08-20T00:00:00Z', 'updatedDateTo': '2023-08-20T23:59:59Z'} - "k=%7B%27updatedDateFrom%27%3A+%272023-08-20T00%3A00%3A00Z%27%2C+%27updatedDateTo%27%3A+%272023-08-20T23%3A59%3A59Z%27%7D", - id="test-request-parameter-from-config-object", - ), - pytest.param( - {"k": "[1,2]"}, - {}, - "k=1&k=2", - id="test-request-parameter-list-of-numbers", - ), - pytest.param( - {"k": '["a", "b"]'}, - {}, - "k=a&k=b", - id="test-request-parameter-list-of-strings", - ), - pytest.param( - {"k": '{{ config["k"] }}'}, - {"k": [1, 2]}, - "k=1&k=2", - id="test-request-parameter-from-config-list-of-numbers", - ), - pytest.param( - {"k": '{{ config["k"] }}'}, - {"k": ["a", "b"]}, - "k=a&k=b", - id="test-request-parameter-from-config-list-of-strings", - ), - pytest.param( - {"k": '{{ config["k"] }}'}, - {"k": ["a,b"]}, - "k=a%2Cb", - id="test-request-parameter-from-config-comma-separated-strings", - ), - pytest.param( - {'["a", "b"]': '{{ config["k"] }}'}, - {"k": [1, 2]}, - "%5B%22a%22%2C+%22b%22%5D=1&%5B%22a%22%2C+%22b%22%5D=2", - id="test-key-with-list-to-be-interpolated", - ), - ], -) -def test_request_param_interpolation(request_parameters, config, expected_query_params): - options_provider = InterpolatedRequestOptionsProvider( - config=config, - request_parameters=request_parameters, - request_body_data={}, - request_headers={}, - parameters={}, - ) - requester = create_requester(error_handler=DefaultErrorHandler(parameters={}, config={})) - requester._request_options_provider = options_provider - requester.send_request() - sent_request: PreparedRequest = requester._http_client._session.send.call_args_list[0][0][0] - assert sent_request.url.split("?", 1)[-1] == expected_query_params - - -@pytest.mark.parametrize( - "request_parameters, config, invalid_value_for_key", - [ - pytest.param( - {"k": {"updatedDateFrom": "2023-08-20T00:00:00Z", "updatedDateTo": "2023-08-20T23:59:59Z"}}, - {}, - "k", - id="test-request-parameter-object-of-the-updated-info", - ), - pytest.param( - {"a": '{{ config["k"] }}', "b": {"end_timestamp": 1699109113}}, - {"k": 1699108113}, - "b", - id="test-key-with-multiple-keys", - ), - ], -) -def test_request_param_interpolation_with_incorrect_values(request_parameters, config, invalid_value_for_key): - options_provider = InterpolatedRequestOptionsProvider( - config=config, - request_parameters=request_parameters, - request_body_data={}, - request_headers={}, - parameters={}, - ) - requester = create_requester() - requester._request_options_provider = options_provider - with pytest.raises(ValueError) as error: - requester.send_request() - - assert ( - error.value.args[0] == f"Invalid value for `{invalid_value_for_key}` parameter. The values of request params cannot be an object." - ) - - -@pytest.mark.parametrize( - "request_body_data, config, expected_request_body_data", - [ - pytest.param( - {"k": '{"updatedDateFrom": "2023-08-20T00:00:00Z", "updatedDateTo": "2023-08-20T23:59:59Z"}'}, - {}, - # k={"updatedDateFrom": "2023-08-20T00:00:00Z", "updatedDateTo": "2023-08-20T23:59:59Z"} - "k=%7B%22updatedDateFrom%22%3A+%222023-08-20T00%3A00%3A00Z%22%2C+%22updatedDateTo%22%3A+%222023-08-20T23%3A59%3A59Z%22%7D", - id="test-request-body-dictionary", - ), - pytest.param( - {"k": "1,2"}, - {}, - "k=1%2C2", # k=1,2 - id="test-request-body-comma-separated-numbers", - ), - pytest.param( - {"k": "a,b"}, - {}, - "k=a%2Cb", # k=a,b - id="test-request-body-comma-separated-strings", - ), - pytest.param( - {"k": "[1,2]"}, - {}, - "k=1&k=2", - id="test-request-body-list-of-numbers", - ), - pytest.param( - {"k": '["a", "b"]'}, - {}, - "k=a&k=b", - id="test-request-body-list-of-strings", - ), - pytest.param( - {"k": '{{ config["k"] }}'}, - {"k": {"updatedDateFrom": "2023-08-20T00:00:00Z", "updatedDateTo": "2023-08-20T23:59:59Z"}}, - # k={'updatedDateFrom': '2023-08-20T00:00:00Z', 'updatedDateTo': '2023-08-20T23:59:59Z'} - "k=%7B%27updatedDateFrom%27%3A+%272023-08-20T00%3A00%3A00Z%27%2C+%27updatedDateTo%27%3A+%272023-08-20T23%3A59%3A59Z%27%7D", - id="test-request-body-from-config-object", - ), - pytest.param( - {"k": '{{ config["k"] }}'}, - {"k": [1, 2]}, - "k=1&k=2", - id="test-request-body-from-config-list-of-numbers", - ), - pytest.param( - {"k": '{{ config["k"] }}'}, - {"k": ["a", "b"]}, - "k=a&k=b", - id="test-request-body-from-config-list-of-strings", - ), - pytest.param( - {"k": '{{ config["k"] }}'}, - {"k": ["a,b"]}, - "k=a%2Cb", # k=a,b - id="test-request-body-from-config-comma-separated-strings", - ), - pytest.param( - {'["a", "b"]': '{{ config["k"] }}'}, - {"k": [1, 2]}, - "%5B%22a%22%2C+%22b%22%5D=1&%5B%22a%22%2C+%22b%22%5D=2", # ["a", "b"]=1&["a", "b"]=2 - id="test-key-with-list-is-not-interpolated", - ), - pytest.param( - {"k": "{'updatedDateFrom': '2023-08-20T00:00:00Z', 'updatedDateTo': '2023-08-20T23:59:59Z'}"}, - {}, - # k={'updatedDateFrom': '2023-08-20T00:00:00Z', 'updatedDateTo': '2023-08-20T23:59:59Z'} - "k=%7B%27updatedDateFrom%27%3A+%272023-08-20T00%3A00%3A00Z%27%2C+%27updatedDateTo%27%3A+%272023-08-20T23%3A59%3A59Z%27%7D", - id="test-single-quotes-are-retained", - ), - ], -) -def test_request_body_interpolation(request_body_data, config, expected_request_body_data): - options_provider = InterpolatedRequestOptionsProvider( - config=config, - request_parameters={}, - request_body_data=request_body_data, - request_headers={}, - parameters={}, - ) - requester = create_requester(error_handler=DefaultErrorHandler(parameters={}, config={})) - requester._request_options_provider = options_provider - requester.send_request() - sent_request: PreparedRequest = requester._http_client._session.send.call_args_list[0][0][0] - assert sent_request.body == expected_request_body_data - - -@pytest.mark.parametrize( - "requester_path, param_path, expected_path", - [ - ("deals", None, "/deals"), - ("deals", "deals2", "/deals2"), - ("deals", "/deals2", "/deals2"), - ( - "deals/{{ stream_slice.start }}/{{ next_page_token.next_page_token }}/{{ config.config_key }}/{{ parameters.param_key }}", - None, - "/deals/2012/pagetoken/config_value/param_value", - ), - ], -) -def test_send_request_path(requester_path, param_path, expected_path): - requester = create_requester(config={"config_key": "config_value"}, path=requester_path, parameters={"param_key": "param_value"}) - requester.send_request(stream_slice={"start": "2012"}, next_page_token={"next_page_token": "pagetoken"}, path=param_path) - sent_request: PreparedRequest = requester._http_client._session.send.call_args_list[0][0][0] - parsed_url = urlparse(sent_request.url) - assert parsed_url.path == expected_path - - -def test_send_request_url_base(): - requester = create_requester( - url_base="https://example.org/{{ config.config_key }}/{{ parameters.param_key }}", - config={"config_key": "config_value"}, - parameters={"param_key": "param_value"}, - error_handler=DefaultErrorHandler(parameters={}, config={}), - ) - requester.send_request() - sent_request: PreparedRequest = requester._http_client._session.send.call_args_list[0][0][0] - assert sent_request.url == "https://example.org/config_value/param_value/deals" - - -def test_send_request_stream_slice_next_page_token(): - options_provider = MagicMock() - requester = create_requester(error_handler=DefaultErrorHandler(parameters={}, config={})) - requester._request_options_provider = options_provider - stream_slice = {"id": "1234"} - next_page_token = {"next_page_token": "next_page_token"} - requester.send_request(stream_slice=stream_slice, next_page_token=next_page_token) - options_provider.get_request_params.assert_called_once_with( - stream_state=None, stream_slice=stream_slice, next_page_token=next_page_token - ) - options_provider.get_request_body_data.assert_called_once_with( - stream_state=None, stream_slice=stream_slice, next_page_token=next_page_token - ) - options_provider.get_request_body_json.assert_called_once_with( - stream_state=None, stream_slice=stream_slice, next_page_token=next_page_token - ) - options_provider.get_request_headers.assert_called_once_with( - stream_state=None, stream_slice=stream_slice, next_page_token=next_page_token - ) - - -@pytest.mark.parametrize( - "test_name, base_url, path, expected_full_url", - [ - ("test_no_slashes", "https://airbyte.io", "my_endpoint", "https://airbyte.io/my_endpoint"), - ("test_trailing_slash_on_base_url", "https://airbyte.io/", "my_endpoint", "https://airbyte.io/my_endpoint"), - ( - "test_trailing_slash_on_base_url_and_leading_slash_on_path", - "https://airbyte.io/", - "/my_endpoint", - "https://airbyte.io/my_endpoint", - ), - ("test_leading_slash_on_path", "https://airbyte.io", "/my_endpoint", "https://airbyte.io/my_endpoint"), - ("test_trailing_slash_on_path", "https://airbyte.io", "/my_endpoint/", "https://airbyte.io/my_endpoint/"), - ("test_nested_path_no_leading_slash", "https://airbyte.io", "v1/my_endpoint", "https://airbyte.io/v1/my_endpoint"), - ("test_nested_path_with_leading_slash", "https://airbyte.io", "/v1/my_endpoint", "https://airbyte.io/v1/my_endpoint"), - ], -) -def test_join_url(test_name, base_url, path, expected_full_url): - requester = HttpRequester( - name="name", - url_base=base_url, - path=path, - http_method=HttpMethod.GET, - request_options_provider=None, - config={}, - parameters={}, - error_handler=DefaultErrorHandler(parameters={}, config={}), - ) - requester._http_client._session.send = MagicMock() - response = requests.Response() - response.status_code = 200 - requester._http_client._session.send.return_value = response - requester.send_request() - sent_request: PreparedRequest = requester._http_client._session.send.call_args_list[0][0][0] - assert sent_request.url == expected_full_url - - -@pytest.mark.usefixtures("mock_sleep") -def test_request_attempt_count_is_tracked_across_retries(http_requester_factory): - request_mock = MagicMock(spec=requests.PreparedRequest) - request_mock.headers = {} - request_mock.url = "https://example.com/deals" - request_mock.method = "GET" - request_mock.body = {} - backoff_strategy = ConstantBackoffStrategy(parameters={}, config={}, backoff_time_in_seconds=0.1) - error_handler = DefaultErrorHandler(parameters={}, config={}, max_retries=1, backoff_strategies=[backoff_strategy]) - http_requester = http_requester_factory(error_handler=error_handler) - http_requester._http_client._session.send = MagicMock() - response = requests.Response() - response.status_code = 500 - http_requester._http_client._session.send.return_value = response - - with pytest.raises(UserDefinedBackoffException): - http_requester._http_client._send_with_retry(request=request_mock, request_kwargs={}) - - assert http_requester._http_client._request_attempt_count.get(request_mock) == http_requester._http_client._max_retries + 1 - - -@pytest.mark.usefixtures("mock_sleep") -def test_request_attempt_count_with_exponential_backoff_strategy(http_requester_factory): - request_mock = MagicMock(spec=requests.PreparedRequest) - request_mock.headers = {} - request_mock.url = "https://example.com/deals" - request_mock.method = "GET" - request_mock.body = {} - backoff_strategy = ExponentialBackoffStrategy(parameters={}, config={}, factor=0.01) - error_handler = DefaultErrorHandler(parameters={}, config={}, max_retries=2, backoff_strategies=[backoff_strategy]) - http_requester = http_requester_factory(error_handler=error_handler) - http_requester._http_client._session.send = MagicMock() - response = requests.Response() - response.status_code = 500 - http_requester._http_client._session.send.return_value = response - - with pytest.raises(UserDefinedBackoffException): - http_requester._http_client._send_with_retry(request=request_mock, request_kwargs={}) - - assert http_requester._http_client._request_attempt_count.get(request_mock) == http_requester._http_client._max_retries + 1 diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/test_interpolated_request_input_provider.py b/airbyte-cdk/python/unit_tests/sources/declarative/requesters/test_interpolated_request_input_provider.py deleted file mode 100644 index 3f80b7eefd31..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/requesters/test_interpolated_request_input_provider.py +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest as pytest -from airbyte_cdk.sources.declarative.interpolation.interpolated_mapping import InterpolatedMapping -from airbyte_cdk.sources.declarative.requesters.request_options.interpolated_request_input_provider import InterpolatedRequestInputProvider - - -@pytest.mark.parametrize( - "test_name, input_request_data, expected_request_data", - [ - ("test_static_map_data", {"a_static_request_param": "a_static_value"}, {"a_static_request_param": "a_static_value"}), - ("test_map_depends_on_stream_slice", {"read_from_slice": "{{ stream_slice['slice_key'] }}"}, {"read_from_slice": "slice_value"}), - ("test_map_depends_on_config", {"read_from_config": "{{ config['config_key'] }}"}, {"read_from_config": "value_of_config"}), - ( - "test_map_depends_on_parameters", - {"read_from_parameters": "{{ parameters['read_from_parameters'] }}"}, - {"read_from_parameters": "value_of_parameters"}, - ), - ("test_defaults_to_empty_dictionary", None, {}), - ], -) -def test_initialize_interpolated_mapping_request_input_provider(test_name, input_request_data, expected_request_data): - config = {"config_key": "value_of_config"} - stream_slice = {"slice_key": "slice_value"} - parameters = {"read_from_parameters": "value_of_parameters"} - provider = InterpolatedRequestInputProvider(request_inputs=input_request_data, config=config, parameters=parameters) - actual_request_data = provider.eval_request_inputs(stream_state={}, stream_slice=stream_slice) - - assert isinstance(provider._interpolator, InterpolatedMapping) - assert actual_request_data == expected_request_data diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/retrievers/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/retrievers/__init__.py deleted file mode 100644 index 46b7376756ec..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/retrievers/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/retrievers/test_simple_retriever.py b/airbyte-cdk/python/unit_tests/sources/declarative/retrievers/test_simple_retriever.py deleted file mode 100644 index 2fd0594bf1b0..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/retrievers/test_simple_retriever.py +++ /dev/null @@ -1,762 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -from unittest.mock import MagicMock, Mock, patch - -import pytest -import requests -from airbyte_cdk import YamlDeclarativeSource -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, Level, SyncMode, Type -from airbyte_cdk.sources.declarative.auth.declarative_authenticator import NoAuth -from airbyte_cdk.sources.declarative.incremental import DatetimeBasedCursor, DeclarativeCursor, ResumableFullRefreshCursor -from airbyte_cdk.sources.declarative.models import DeclarativeStream as DeclarativeStreamModel -from airbyte_cdk.sources.declarative.parsers.model_to_component_factory import ModelToComponentFactory -from airbyte_cdk.sources.declarative.partition_routers import SinglePartitionRouter -from airbyte_cdk.sources.declarative.requesters.paginators import DefaultPaginator -from airbyte_cdk.sources.declarative.requesters.paginators.strategies import PageIncrement -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOptionType -from airbyte_cdk.sources.declarative.requesters.requester import HttpMethod -from airbyte_cdk.sources.declarative.retrievers.simple_retriever import SimpleRetriever, SimpleRetrieverTestReadDecorator -from airbyte_cdk.sources.types import Record, StreamSlice - -A_SLICE_STATE = {"slice_state": "slice state value"} -A_STREAM_SLICE = StreamSlice(cursor_slice={"stream slice": "slice value"}, partition={}) -A_STREAM_STATE = {"stream state": "state value"} - -primary_key = "pk" -records = [{"id": 1}, {"id": 2}] -request_response_logs = [ - AirbyteLogMessage(level=Level.INFO, message="request:{}"), - AirbyteLogMessage(level=Level.INFO, message="response{}"), -] -config = {} - - -@patch.object(SimpleRetriever, "_read_pages", return_value=iter([])) -def test_simple_retriever_full(mock_http_stream): - requester = MagicMock() - request_params = {"param": "value"} - requester.get_request_params.return_value = request_params - - paginator = MagicMock() - next_page_token = {"cursor": "cursor_value"} - paginator.path.return_value = None - paginator.next_page_token.return_value = next_page_token - paginator.get_requesyyt_headers.return_value = {} - - record_selector = MagicMock() - record_selector.select_records.return_value = records - - cursor = MagicMock(spec=DeclarativeCursor) - stream_slices = [{"date": "2022-01-01"}, {"date": "2022-01-02"}] - cursor.stream_slices.return_value = stream_slices - - response = requests.Response() - response.status_code = 200 - - underlying_state = {"date": "2021-01-01"} - cursor.get_stream_state.return_value = underlying_state - - requester.get_authenticator.return_value = NoAuth({}) - url_base = "https://airbyte.io" - requester.get_url_base.return_value = url_base - path = "/v1" - requester.get_path.return_value = path - http_method = HttpMethod.GET - requester.get_method.return_value = http_method - should_retry = True - requester.interpret_response_status.return_value = should_retry - request_body_json = {"body": "json"} - requester.request_body_json.return_value = request_body_json - - request_body_data = {"body": "data"} - requester.get_request_body_data.return_value = request_body_data - request_body_json = {"body": "json"} - requester.get_request_body_json.return_value = request_body_json - request_kwargs = {"kwarg": "value"} - requester.request_kwargs.return_value = request_kwargs - - retriever = SimpleRetriever( - name="stream_name", - primary_key=primary_key, - requester=requester, - paginator=paginator, - record_selector=record_selector, - stream_slicer=cursor, - cursor=cursor, - parameters={}, - config={}, - ) - - assert retriever.primary_key == primary_key - assert retriever.state == underlying_state - assert retriever._next_page_token(response) == next_page_token - assert retriever._request_params(None, None, None) == {} - assert retriever.stream_slices() == stream_slices - - assert retriever._last_response is None - assert retriever._last_record is None - assert list(retriever._parse_response(response, stream_state={}, records_schema={})) == records - assert retriever._last_response == response - assert retriever._last_page_size == 2 - - [r for r in retriever.read_records(SyncMode.full_refresh)] - paginator.reset.assert_called() - - -@patch.object(SimpleRetriever, "_read_pages", return_value=iter([*request_response_logs, *records])) -def test_simple_retriever_with_request_response_logs(mock_http_stream): - requester = MagicMock() - paginator = MagicMock() - record_selector = MagicMock() - stream_slicer = DatetimeBasedCursor( - start_datetime="", - end_datetime="", - step="P1D", - cursor_field="id", - datetime_format="", - cursor_granularity="P1D", - config={}, - parameters={}, - ) - - retriever = SimpleRetriever( - name="stream_name", - primary_key=primary_key, - requester=requester, - paginator=paginator, - record_selector=record_selector, - stream_slicer=stream_slicer, - parameters={}, - config={}, - ) - - actual_messages = [r for r in retriever.read_records(SyncMode.full_refresh)] - paginator.reset.assert_called() - - assert isinstance(actual_messages[0], AirbyteLogMessage) - assert isinstance(actual_messages[1], AirbyteLogMessage) - assert actual_messages[2] == records[0] - assert actual_messages[3] == records[1] - - -@pytest.mark.parametrize( - "initial_state, expected_reset_value, expected_next_page", - [ - pytest.param(None, None, 1, id="test_initial_sync_no_state"), - pytest.param({"next_page_token": 10}, 10, 11, id="test_reset_with_next_page_token"), - ], -) -def test_simple_retriever_resumable_full_refresh_cursor_page_increment(initial_state, expected_reset_value, expected_next_page): - expected_records = [ - Record(data={"id": "abc"}, associated_slice=None), - Record(data={"id": "def"}, associated_slice=None), - Record(data={"id": "ghi"}, associated_slice=None), - Record(data={"id": "jkl"}, associated_slice=None), - Record(data={"id": "mno"}, associated_slice=None), - Record(data={"id": "123"}, associated_slice=None), - Record(data={"id": "456"}, associated_slice=None), - Record(data={"id": "789"}, associated_slice=None), - ] - - response = requests.Response() - response.status_code = 200 - response._content = json.dumps({"data": [record.data for record in expected_records[:5]]}).encode("utf-8") - - requester = MagicMock() - requester.send_request.side_effect = [ - response, - response, - ] - - record_selector = MagicMock() - record_selector.select_records.side_effect = [ - [ - expected_records[0], - expected_records[1], - expected_records[2], - expected_records[3], - expected_records[4], - ], - [ - expected_records[5], - expected_records[6], - expected_records[7], - ], - ] - - page_increment_strategy = PageIncrement(config={}, page_size=5, parameters={}) - paginator = DefaultPaginator(config={}, pagination_strategy=page_increment_strategy, url_base="https://airbyte.io", parameters={}) - paginator.reset = Mock(wraps=paginator.reset) - - stream_slicer = ResumableFullRefreshCursor(parameters={}) - if initial_state: - stream_slicer.set_initial_state(initial_state) - - retriever = SimpleRetriever( - name="stream_name", - primary_key=primary_key, - requester=requester, - paginator=paginator, - record_selector=record_selector, - stream_slicer=stream_slicer, - cursor=stream_slicer, - parameters={}, - config={}, - ) - - stream_slice = list(stream_slicer.stream_slices())[0] - actual_records = [r for r in retriever.read_records(records_schema={}, stream_slice=stream_slice)] - - assert len(actual_records) == 5 - assert actual_records == expected_records[:5] - assert retriever.state == {"next_page_token": expected_next_page} - - actual_records = [r for r in retriever.read_records(records_schema={}, stream_slice=stream_slice)] - assert len(actual_records) == 3 - assert actual_records == expected_records[5:] - assert retriever.state == {"__ab_full_refresh_sync_complete": True} - - paginator.reset.assert_called_once_with(reset_value=expected_reset_value) - - -@pytest.mark.parametrize( - "initial_state, expected_reset_value, expected_next_page", - [ - pytest.param(None, None, 1, id="test_initial_sync_no_state"), - pytest.param( - {"next_page_token": "https://for-all-mankind.nasa.com/api/v1/astronauts?next_page=tracy_stevens"}, - "https://for-all-mankind.nasa.com/api/v1/astronauts?next_page=tracy_stevens", - "https://for-all-mankind.nasa.com/api/v1/astronauts?next_page=gordo_stevens", - id="test_reset_with_next_page_token", - ), - ], -) -def test_simple_retriever_resumable_full_refresh_cursor_reset_cursor_pagination( - initial_state, expected_reset_value, expected_next_page, requests_mock -): - expected_records = [ - Record(data={"name": "ed_baldwin"}, associated_slice=None), - Record(data={"name": "danielle_poole"}, associated_slice=None), - Record(data={"name": "tracy_stevens"}, associated_slice=None), - Record(data={"name": "deke_slayton"}, associated_slice=None), - Record(data={"name": "molly_cobb"}, associated_slice=None), - Record(data={"name": "gordo_stevens"}, associated_slice=None), - Record(data={"name": "margo_madison"}, associated_slice=None), - Record(data={"name": "ellen_waverly"}, associated_slice=None), - ] - - content = """ -name: users -type: DeclarativeStream -retriever: - type: SimpleRetriever - decoder: - type: JsonDecoder - paginator: - type: "DefaultPaginator" - page_token_option: - type: RequestPath - pagination_strategy: - type: "CursorPagination" - cursor_value: "{{ response.next_page }}" - requester: - path: /astronauts - type: HttpRequester - url_base: "https://for-all-mankind.nasa.com/api/v1" - http_method: GET - authenticator: - type: ApiKeyAuthenticator - api_token: "{{ config['api_key'] }}" - inject_into: - type: RequestOption - field_name: Api-Key - inject_into: header - request_headers: {} - request_body_json: {} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: ["data"] - partition_router: [] -primary_key: [] - """ - - factory = ModelToComponentFactory() - stream_manifest = YamlDeclarativeSource._parse(content) - stream = factory.create_component(model_type=DeclarativeStreamModel, component_definition=stream_manifest, config={}) - response_body = { - "data": [r.data for r in expected_records[:5]], - "next_page": "https://for-all-mankind.nasa.com/api/v1/astronauts?next_page=gordo_stevens", - } - requests_mock.get("https://for-all-mankind.nasa.com/api/v1/astronauts", json=response_body) - requests_mock.get("https://for-all-mankind.nasa.com/astronauts?next_page=tracy_stevens", json=response_body) - response_body_2 = { - "data": [r.data for r in expected_records[5:]], - } - requests_mock.get("https://for-all-mankind.nasa.com/api/v1/astronauts?next_page=gordo_stevens", json=response_body_2) - stream.retriever.paginator.reset = Mock(wraps=stream.retriever.paginator.reset) - stream_slicer = ResumableFullRefreshCursor(parameters={}) - if initial_state: - stream_slicer.set_initial_state(initial_state) - stream.retriever.stream_slices = stream_slicer - stream.retriever.cursor = stream_slicer - stream_slice = list(stream_slicer.stream_slices())[0] - actual_records = [r for r in stream.retriever.read_records(records_schema={}, stream_slice=stream_slice)] - - assert len(actual_records) == 5 - assert actual_records == expected_records[:5] - assert stream.retriever.state == {"next_page_token": "https://for-all-mankind.nasa.com/api/v1/astronauts?next_page=gordo_stevens"} - requests_mock.get("https://for-all-mankind.nasa.com/astronauts?next_page=tracy_stevens", json=response_body) - requests_mock.get("https://for-all-mankind.nasa.com/astronauts?next_page=gordo_stevens", json=response_body_2) - actual_records = [r for r in stream.retriever.read_records(records_schema={}, stream_slice=stream_slice)] - assert len(actual_records) == 3 - assert actual_records == expected_records[5:] - assert stream.retriever.state == {"__ab_full_refresh_sync_complete": True} - - stream.retriever.paginator.reset.assert_called_once_with(reset_value=expected_reset_value) - - -def test_simple_retriever_resumable_full_refresh_cursor_reset_skip_completed_stream(): - expected_records = [ - Record(data={"id": "abc"}, associated_slice=None), - Record(data={"id": "def"}, associated_slice=None), - ] - - response = requests.Response() - response.status_code = 200 - response._content = json.dumps({}).encode("utf-8") - - requester = MagicMock() - requester.send_request.side_effect = [ - response, - ] - - record_selector = MagicMock() - record_selector.select_records.return_value = [ - expected_records[0], - expected_records[1], - ] - - page_increment_strategy = PageIncrement(config={}, page_size=5, parameters={}) - paginator = DefaultPaginator(config={}, pagination_strategy=page_increment_strategy, url_base="https://airbyte.io", parameters={}) - paginator.reset = Mock(wraps=paginator.reset) - - stream_slicer = ResumableFullRefreshCursor(parameters={}) - stream_slicer.set_initial_state({"__ab_full_refresh_sync_complete": True}) - - retriever = SimpleRetriever( - name="stream_name", - primary_key=primary_key, - requester=requester, - paginator=paginator, - record_selector=record_selector, - stream_slicer=stream_slicer, - cursor=stream_slicer, - parameters={}, - config={}, - ) - - stream_slice = list(stream_slicer.stream_slices())[0] - actual_records = [r for r in retriever.read_records(records_schema={}, stream_slice=stream_slice)] - - assert len(actual_records) == 0 - assert retriever.state == {"__ab_full_refresh_sync_complete": True} - - paginator.reset.assert_not_called() - - -@pytest.mark.parametrize( - "test_name, paginator_mapping, request_options_provider_mapping, expected_mapping", - [ - ("test_empty_headers", {}, {}, {}), - ("test_header_from_pagination_and_slicer", {"offset": 1000}, {"key": "value"}, {"key": "value", "offset": 1000}), - ("test_header_from_stream_slicer", {}, {"slice": "slice_value"}, {"slice": "slice_value"}), - ("test_duplicate_header_slicer_paginator", {"k": "v"}, {"k": "slice_value"}, None), - ], -) -def test_get_request_options_from_pagination(test_name, paginator_mapping, request_options_provider_mapping, expected_mapping): - # This test does not test request headers because they must be strings - paginator = MagicMock() - paginator.get_request_params.return_value = paginator_mapping - paginator.get_request_body_data.return_value = paginator_mapping - paginator.get_request_body_json.return_value = paginator_mapping - - request_options_provider = MagicMock() - request_options_provider.get_request_params.return_value = request_options_provider_mapping - request_options_provider.get_request_body_data.return_value = request_options_provider_mapping - request_options_provider.get_request_body_json.return_value = request_options_provider_mapping - - record_selector = MagicMock() - retriever = SimpleRetriever( - name="stream_name", - primary_key=primary_key, - requester=MagicMock(), - record_selector=record_selector, - paginator=paginator, - request_option_provider=request_options_provider, - parameters={}, - config={}, - ) - - request_option_type_to_method = { - RequestOptionType.request_parameter: retriever._request_params, - RequestOptionType.body_data: retriever._request_body_data, - RequestOptionType.body_json: retriever._request_body_json, - } - - for _, method in request_option_type_to_method.items(): - if expected_mapping is not None: - actual_mapping = method(None, None, None) - assert actual_mapping == expected_mapping - else: - try: - method(None, None, None) - assert False - except ValueError: - pass - - -@pytest.mark.parametrize( - "test_name, paginator_mapping, expected_mapping", - [ - ("test_only_base_headers", {}, {"key": "value"}), - ("test_header_from_pagination", {"offset": 1000}, {"key": "value", "offset": "1000"}), - ("test_duplicate_header", {"key": 1000}, None), - ], -) -def test_get_request_headers(test_name, paginator_mapping, expected_mapping): - # This test is separate from the other request options because request headers must be strings - paginator = MagicMock() - paginator.get_request_headers.return_value = paginator_mapping - requester = MagicMock(use_cache=False) - - stream_slicer = MagicMock() - stream_slicer.get_request_headers.return_value = {"key": "value"} - - record_selector = MagicMock() - retriever = SimpleRetriever( - name="stream_name", - primary_key=primary_key, - requester=requester, - record_selector=record_selector, - stream_slicer=stream_slicer, - paginator=paginator, - parameters={}, - config={}, - ) - - request_option_type_to_method = { - RequestOptionType.header: retriever._request_headers, - } - - for _, method in request_option_type_to_method.items(): - if expected_mapping: - actual_mapping = method(None, None, None) - assert actual_mapping == expected_mapping - else: - try: - method(None, None, None) - assert False - except ValueError: - pass - - -@pytest.mark.parametrize( - "test_name, paginator_mapping, ignore_stream_slicer_parameters_on_paginated_requests, next_page_token, expected_mapping", - [ - ( - "test_do_not_ignore_stream_slicer_params_if_ignore_is_true_but_no_next_page_token", - {"key_from_pagination": "1000"}, - True, - None, - {"key_from_pagination": "1000"}, - ), - ( - "test_do_not_ignore_stream_slicer_params_if_ignore_is_false_and_no_next_page_token", - {"key_from_pagination": "1000"}, - False, - None, - {"key_from_pagination": "1000", "key_from_slicer": "value"}, - ), - ( - "test_ignore_stream_slicer_params_on_paginated_request", - {"key_from_pagination": "1000"}, - True, - {"page": 2}, - {"key_from_pagination": "1000"}, - ), - ( - "test_do_not_ignore_stream_slicer_params_on_paginated_request", - {"key_from_pagination": "1000"}, - False, - {"page": 2}, - {"key_from_pagination": "1000", "key_from_slicer": "value"}, - ), - ], -) -def test_ignore_stream_slicer_parameters_on_paginated_requests( - test_name, paginator_mapping, ignore_stream_slicer_parameters_on_paginated_requests, next_page_token, expected_mapping -): - # This test is separate from the other request options because request headers must be strings - paginator = MagicMock() - paginator.get_request_headers.return_value = paginator_mapping - requester = MagicMock(use_cache=False) - - stream_slicer = MagicMock() - stream_slicer.get_request_headers.return_value = {"key_from_slicer": "value"} - - record_selector = MagicMock() - retriever = SimpleRetriever( - name="stream_name", - primary_key=primary_key, - requester=requester, - record_selector=record_selector, - stream_slicer=stream_slicer, - paginator=paginator, - ignore_stream_slicer_parameters_on_paginated_requests=ignore_stream_slicer_parameters_on_paginated_requests, - parameters={}, - config={}, - ) - - request_option_type_to_method = { - RequestOptionType.header: retriever._request_headers, - } - - for _, method in request_option_type_to_method.items(): - actual_mapping = method(None, None, next_page_token={"next_page_token": "1000"}) - assert actual_mapping == expected_mapping - - -@pytest.mark.parametrize( - "test_name, request_options_provider_body_data, paginator_body_data, expected_body_data", - [ - ("test_only_slicer_mapping", {"key": "value"}, {}, {"key": "value"}), - ("test_only_slicer_string", "key=value", {}, "key=value"), - ("test_slicer_mapping_and_paginator_no_duplicate", {"key": "value"}, {"offset": 1000}, {"key": "value", "offset": 1000}), - ("test_slicer_mapping_and_paginator_with_duplicate", {"key": "value"}, {"key": 1000}, None), - ("test_slicer_string_and_paginator", "key=value", {"offset": 1000}, None), - ], -) -def test_request_body_data(test_name, request_options_provider_body_data, paginator_body_data, expected_body_data): - paginator = MagicMock() - paginator.get_request_body_data.return_value = paginator_body_data - requester = MagicMock(use_cache=False) - - # stream_slicer = MagicMock() - # stream_slicer.get_request_body_data.return_value = request_options_provider_body_data - request_option_provider = MagicMock() - request_option_provider.get_request_body_data.return_value = request_options_provider_body_data - - record_selector = MagicMock() - retriever = SimpleRetriever( - name="stream_name", - primary_key=primary_key, - requester=requester, - record_selector=record_selector, - paginator=paginator, - request_option_provider=request_option_provider, - parameters={}, - config={}, - ) - - if expected_body_data: - actual_body_data = retriever._request_body_data(None, None, None) - assert actual_body_data == expected_body_data - else: - try: - retriever._request_body_data(None, None, None) - assert False - except ValueError: - pass - - -@pytest.mark.parametrize( - "test_name, requester_path, paginator_path, expected_path", - [ - ("test_path_from_requester", "/v1/path", None, None), - ("test_path_from_paginator", "/v1/path/", "/v2/paginator", "/v2/paginator"), - ], -) -def test_path(test_name, requester_path, paginator_path, expected_path): - paginator = MagicMock() - paginator.path.return_value = paginator_path - requester = MagicMock(use_cache=False) - - requester.get_path.return_value = requester_path - - record_selector = MagicMock() - retriever = SimpleRetriever( - name="stream_name", - primary_key=primary_key, - requester=requester, - record_selector=record_selector, - paginator=paginator, - parameters={}, - config={}, - ) - - actual_path = retriever._paginator_path() - assert actual_path == expected_path - - -def test_limit_stream_slices(): - maximum_number_of_slices = 4 - stream_slicer = MagicMock() - stream_slicer.stream_slices.return_value = _generate_slices(maximum_number_of_slices * 2) - retriever = SimpleRetrieverTestReadDecorator( - name="stream_name", - primary_key=primary_key, - requester=MagicMock(), - paginator=MagicMock(), - record_selector=MagicMock(), - stream_slicer=stream_slicer, - maximum_number_of_slices=maximum_number_of_slices, - parameters={}, - config={}, - ) - - truncated_slices = list(retriever.stream_slices()) - - assert truncated_slices == _generate_slices(maximum_number_of_slices) - - -@pytest.mark.parametrize( - "test_name, first_greater_than_second", - [ - ("test_first_greater_than_second", True), - ("test_second_greater_than_first", False), - ], -) -def test_when_read_records_then_cursor_close_slice_with_greater_record(test_name, first_greater_than_second): - first_record = Record({"first": 1}, StreamSlice(cursor_slice={}, partition={})) - second_record = Record({"second": 2}, StreamSlice(cursor_slice={}, partition={})) - records = [first_record, second_record] - record_selector = MagicMock() - record_selector.select_records.return_value = records - cursor = MagicMock(spec=DeclarativeCursor) - cursor.is_greater_than_or_equal.return_value = first_greater_than_second - paginator = MagicMock() - paginator.get_request_headers.return_value = {} - - retriever = SimpleRetriever( - name="stream_name", - primary_key=primary_key, - requester=MagicMock(), - paginator=paginator, - record_selector=record_selector, - stream_slicer=cursor, - cursor=cursor, - parameters={}, - config={}, - ) - stream_slice = StreamSlice(cursor_slice={}, partition={"repository": "airbyte"}) - - def retriever_read_pages(_, __, ___): - return retriever._parse_records(response=MagicMock(), stream_state={}, stream_slice=stream_slice, records_schema={}) - - with patch.object( - SimpleRetriever, - "_read_pages", - return_value=iter([first_record, second_record]), - side_effect=retriever_read_pages, - ): - list(retriever.read_records(stream_slice=stream_slice, records_schema={})) - cursor.close_slice.assert_called_once_with(stream_slice, first_record if first_greater_than_second else second_record) - - -def test_given_stream_data_is_not_record_when_read_records_then_update_slice_with_optional_record(): - stream_data = [AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=Level.INFO, message="a log message"))] - record_selector = MagicMock() - record_selector.select_records.return_value = [] - cursor = MagicMock(spec=DeclarativeCursor) - - retriever = SimpleRetriever( - name="stream_name", - primary_key=primary_key, - requester=MagicMock(), - paginator=Mock(), - record_selector=record_selector, - stream_slicer=cursor, - cursor=cursor, - parameters={}, - config={}, - ) - stream_slice = StreamSlice(cursor_slice={}, partition={"repository": "airbyte"}) - - def retriever_read_pages(_, __, ___): - return retriever._parse_records(response=MagicMock(), stream_state={}, stream_slice=stream_slice, records_schema={}) - - with patch.object( - SimpleRetriever, - "_read_pages", - return_value=iter(stream_data), - side_effect=retriever_read_pages, - ): - list(retriever.read_records(stream_slice=stream_slice, records_schema={})) - cursor.observe.assert_not_called() - cursor.close_slice.assert_called_once_with(stream_slice, None) - - -def _generate_slices(number_of_slices): - return [{"date": f"2022-01-0{day + 1}"} for day in range(number_of_slices)] - - -@patch.object(SimpleRetriever, "_read_pages", return_value=iter([])) -def test_given_state_selector_when_read_records_use_stream_state(http_stream_read_pages, mocker): - requester = MagicMock() - paginator = MagicMock() - record_selector = MagicMock() - cursor = MagicMock(spec=DeclarativeCursor) - cursor.select_state = MagicMock(return_value=A_SLICE_STATE) - cursor.get_stream_state = MagicMock(return_value=A_STREAM_STATE) - - retriever = SimpleRetriever( - name="stream_name", - primary_key=primary_key, - requester=requester, - paginator=paginator, - record_selector=record_selector, - stream_slicer=cursor, - cursor=cursor, - parameters={}, - config={}, - ) - - list(retriever.read_records(stream_slice=A_STREAM_SLICE, records_schema={})) - - http_stream_read_pages.assert_called_once_with(mocker.ANY, A_STREAM_STATE, A_STREAM_SLICE) - - -def test_emit_log_request_response_messages(mocker): - record_selector = MagicMock() - record_selector.select_records.return_value = records - - request = requests.PreparedRequest() - request.headers = {"header": "value"} - request.url = "http://byrde.enterprises.com/casinos" - - response = requests.Response() - response.request = request - response.status_code = 200 - - format_http_message_mock = mocker.patch("airbyte_cdk.sources.declarative.retrievers.simple_retriever.format_http_message") - requester = MagicMock() - retriever = SimpleRetrieverTestReadDecorator( - name="stream_name", - primary_key=primary_key, - requester=requester, - paginator=MagicMock(), - record_selector=record_selector, - stream_slicer=SinglePartitionRouter(parameters={}), - parameters={}, - config={}, - ) - - retriever._fetch_next_page(stream_state={}, stream_slice=StreamSlice(cursor_slice={}, partition={})) - - assert requester.send_request.call_args_list[0][1]["log_formatter"] is not None - assert requester.send_request.call_args_list[0][1]["log_formatter"](response) == format_http_message_mock.return_value diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/schema/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/schema/__init__.py deleted file mode 100644 index 655bcbe54fb8..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/schema/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -from .source_test.SourceTest import SourceTest - -__all__ = ["SourceTest"] diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/schema/source_test/SourceTest.py b/airbyte-cdk/python/unit_tests/sources/declarative/schema/source_test/SourceTest.py deleted file mode 100644 index 8d6a26cb7657..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/schema/source_test/SourceTest.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -class SourceTest: - def __init__(self): - pass diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/schema/source_test/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/schema/source_test/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/schema/source_test/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/schema/source_test/schemas/sample_stream.json b/airbyte-cdk/python/unit_tests/sources/declarative/schema/source_test/schemas/sample_stream.json deleted file mode 100644 index 6ef7fbed5577..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/schema/source_test/schemas/sample_stream.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": ["null", "object"], - "properties": { - "type": { - "$ref": "sample_shared_schema.json" - }, - "id": { - "type": ["null", "string"] - } - } -} diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/schema/source_test/schemas/shared/sample_shared_schema.json b/airbyte-cdk/python/unit_tests/sources/declarative/schema/source_test/schemas/shared/sample_shared_schema.json deleted file mode 100644 index 95ea8a1655f2..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/schema/source_test/schemas/shared/sample_shared_schema.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": ["null", "object"], - "properties": { - "id_internal": { - "type": ["null", "integer"] - }, - "name": { - "type": ["null", "string"] - } - } -} diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/schema/test_default_schema_loader.py b/airbyte-cdk/python/unit_tests/sources/declarative/schema/test_default_schema_loader.py deleted file mode 100644 index c04c4fdcd33a..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/schema/test_default_schema_loader.py +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from unittest.mock import MagicMock - -import pytest -from airbyte_cdk.sources.declarative.schema import DefaultSchemaLoader - - -@pytest.mark.parametrize( - "found_schema, found_error, expected_schema", - [ - pytest.param( - {"type": "object", "properties": {}}, None, {"type": "object", "properties": {}}, id="test_has_schema_in_default_location" - ), - pytest.param(None, FileNotFoundError, {}, id="test_schema_file_does_not_exist"), - ], -) -def test_get_json_schema(found_schema, found_error, expected_schema): - default_schema_loader = DefaultSchemaLoader({}, {}) - - json_file_schema_loader = MagicMock() - if found_schema: - json_file_schema_loader.get_json_schema.return_value = {"type": "object", "properties": {}} - if found_error: - json_file_schema_loader.get_json_schema.side_effect = found_error - - default_schema_loader.default_loader = json_file_schema_loader - - actual_schema = default_schema_loader.get_json_schema() - assert actual_schema == expected_schema diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/schema/test_inline_schema_loader.py b/airbyte-cdk/python/unit_tests/sources/declarative/schema/test_inline_schema_loader.py deleted file mode 100644 index ad44ee334cfc..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/schema/test_inline_schema_loader.py +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -from airbyte_cdk.sources.declarative.schema import InlineSchemaLoader - - -@pytest.mark.parametrize( - "test_name, input_schema, expected_schema", - [ - ("schema", {"k": "string"}, {"k": "string"}), - ("empty_schema", {}, {}), - ], -) -def test_static_schema_loads(test_name, input_schema, expected_schema): - schema_loader = InlineSchemaLoader(input_schema, {}) - - assert schema_loader.get_json_schema() == expected_schema diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/schema/test_json_file_schema_loader.py b/airbyte-cdk/python/unit_tests/sources/declarative/schema/test_json_file_schema_loader.py deleted file mode 100644 index 8ef467618634..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/schema/test_json_file_schema_loader.py +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -from unittest.mock import patch - -import pytest -from airbyte_cdk.sources.declarative.schema.json_file_schema_loader import JsonFileSchemaLoader, _default_file_path - - -@pytest.mark.parametrize( - "test_name, input_path, expected_resource, expected_path", - [ - ("path_prefixed_with_dot", "./source_example/schemas/lists.json", "source_example", "schemas/lists.json"), - ("path_prefixed_with_slash", "/source_example/schemas/lists.json", "source_example", "schemas/lists.json"), - ("path_starting_with_source", "source_example/schemas/lists.json", "source_example", "schemas/lists.json"), - ("path_starting_missing_source", "schemas/lists.json", "schemas", "lists.json"), - ("path_with_file_only", "lists.json", "", "lists.json"), - ("empty_path_does_not_crash", "", "", ""), - ("empty_path_with_slash_does_not_crash", "/", "", ""), - ], -) -def test_extract_resource_and_schema_path(test_name, input_path, expected_resource, expected_path): - json_schema = JsonFileSchemaLoader({}, {}, input_path) - actual_resource, actual_path = json_schema.extract_resource_and_schema_path(input_path) - - assert actual_resource == expected_resource - assert actual_path == expected_path - - -@patch("airbyte_cdk.sources.declarative.schema.json_file_schema_loader.sys") -def test_exclude_cdk_packages(mocked_sys): - keys = ["airbyte_cdk.sources.concurrent_source.concurrent_source_adapter", "source_gitlab.utils"] - mocked_sys.modules = {key: "" for key in keys} - - default_file_path = _default_file_path() - - assert "source_gitlab" in default_file_path diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/spec/test_spec.py b/airbyte-cdk/python/unit_tests/sources/declarative/spec/test_spec.py deleted file mode 100644 index 1e1ef498082f..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/spec/test_spec.py +++ /dev/null @@ -1,36 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -from airbyte_cdk.models import AdvancedAuth, AuthFlowType, ConnectorSpecification -from airbyte_cdk.sources.declarative.models.declarative_component_schema import AuthFlow -from airbyte_cdk.sources.declarative.spec.spec import Spec - - -@pytest.mark.parametrize( - "spec, expected_connection_specification", - [ - ( - Spec(connection_specification={"client_id": "my_client_id"}, parameters={}), - ConnectorSpecification(connectionSpecification={"client_id": "my_client_id"}), - ), - ( - Spec(connection_specification={"client_id": "my_client_id"}, parameters={}, documentation_url="https://airbyte.io"), - ConnectorSpecification(connectionSpecification={"client_id": "my_client_id"}, documentationUrl="https://airbyte.io"), - ), - ( - Spec(connection_specification={"client_id": "my_client_id"}, parameters={}, advanced_auth=AuthFlow(auth_flow_type="oauth2.0")), - ConnectorSpecification( - connectionSpecification={"client_id": "my_client_id"}, advanced_auth=AdvancedAuth(auth_flow_type=AuthFlowType.oauth2_0) - ), - ), - ], - ids=[ - "test_only_connection_specification", - "test_with_doc_url", - "test_auth_flow", - ], -) -def test_spec(spec, expected_connection_specification): - assert spec.generate_spec() == expected_connection_specification diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/states/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/states/__init__.py deleted file mode 100644 index 46b7376756ec..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/states/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/__init__.py b/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/__init__.py deleted file mode 100644 index 46b7376756ec..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/stream_slicers/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/test_declarative_stream.py b/airbyte-cdk/python/unit_tests/sources/declarative/test_declarative_stream.py deleted file mode 100644 index 8906b625fb8f..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/test_declarative_stream.py +++ /dev/null @@ -1,221 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from unittest.mock import MagicMock - -import pytest -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, AirbyteTraceMessage, Level, SyncMode, TraceType, Type -from airbyte_cdk.sources.declarative.declarative_stream import DeclarativeStream -from airbyte_cdk.sources.types import StreamSlice - -SLICE_NOT_CONSIDERED_FOR_EQUALITY = {} - -_name = "stream" -_primary_key = "pk" -_cursor_field = "created_at" -_json_schema = {"name": {"type": "string"}} - - -def test_declarative_stream(): - schema_loader = _schema_loader() - - state = MagicMock() - records = [ - {"pk": 1234, "field": "value"}, - {"pk": 4567, "field": "different_value"}, - AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=Level.INFO, message="This is a log message")), - AirbyteMessage(type=Type.TRACE, trace=AirbyteTraceMessage(type=TraceType.ERROR, emitted_at=12345)), - ] - stream_slices = [ - StreamSlice(partition={}, cursor_slice={"date": "2021-01-01"}), - StreamSlice(partition={}, cursor_slice={"date": "2021-01-02"}), - StreamSlice(partition={}, cursor_slice={"date": "2021-01-03"}), - ] - - retriever = MagicMock() - retriever.state = state - retriever.read_records.return_value = records - retriever.stream_slices.return_value = stream_slices - - config = {"api_key": "open_sesame"} - - stream = DeclarativeStream( - name=_name, - primary_key=_primary_key, - stream_cursor_field="{{ parameters['cursor_field'] }}", - schema_loader=schema_loader, - retriever=retriever, - config=config, - parameters={"cursor_field": "created_at"}, - ) - - assert stream.name == _name - assert stream.get_json_schema() == _json_schema - assert stream.state == state - input_slice = stream_slices[0] - assert list(stream.read_records(SyncMode.full_refresh, _cursor_field, input_slice, state)) == records - assert stream.primary_key == _primary_key - assert stream.cursor_field == _cursor_field - assert stream.stream_slices(sync_mode=SyncMode.incremental, cursor_field=_cursor_field, stream_state=None) == stream_slices - - -def test_declarative_stream_using_empty_slice(): - """ - Tests that a declarative_stream - """ - schema_loader = _schema_loader() - - records = [ - {"pk": 1234, "field": "value"}, - {"pk": 4567, "field": "different_value"}, - AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=Level.INFO, message="This is a log message")), - AirbyteMessage(type=Type.TRACE, trace=AirbyteTraceMessage(type=TraceType.ERROR, emitted_at=12345)), - ] - - retriever = MagicMock() - retriever.read_records.return_value = records - - config = {"api_key": "open_sesame"} - - stream = DeclarativeStream( - name=_name, - primary_key=_primary_key, - stream_cursor_field="{{ parameters['cursor_field'] }}", - schema_loader=schema_loader, - retriever=retriever, - config=config, - parameters={"cursor_field": "created_at"}, - ) - - assert stream.name == _name - assert stream.get_json_schema() == _json_schema - assert list(stream.read_records(SyncMode.full_refresh, _cursor_field, {})) == records - - -def test_read_records_raises_exception_if_stream_slice_is_not_per_partition_stream_slice(): - schema_loader = _schema_loader() - - retriever = MagicMock() - retriever.state = MagicMock() - retriever.read_records.return_value = [] - stream_slice = {"date": "2021-01-01"} - retriever.stream_slices.return_value = [stream_slice] - - stream = DeclarativeStream( - name=_name, - primary_key=_primary_key, - stream_cursor_field="{{ parameters['cursor_field'] }}", - schema_loader=schema_loader, - retriever=retriever, - config={}, - parameters={"cursor_field": "created_at"}, - ) - - with pytest.raises(ValueError): - list(stream.read_records(SyncMode.full_refresh, _cursor_field, stream_slice, MagicMock())) - - -def test_state_checkpoint_interval(): - stream = DeclarativeStream( - name="any name", - primary_key="any primary key", - stream_cursor_field="{{ parameters['cursor_field'] }}", - schema_loader=MagicMock(), - retriever=MagicMock(), - config={}, - parameters={}, - ) - - assert stream.state_checkpoint_interval is None - - -def test_state_migrations(): - intermediate_state = {"another_key", "another_value"} - final_state = {"yet_another_key", "yet_another_value"} - first_state_migration = MagicMock() - first_state_migration.should_migrate.return_value = True - first_state_migration.migrate.return_value = intermediate_state - second_state_migration = MagicMock() - second_state_migration.should_migrate.return_value = True - second_state_migration.migrate.return_value = final_state - - stream = DeclarativeStream( - name="any name", - primary_key="any primary key", - stream_cursor_field="{{ parameters['cursor_field'] }}", - schema_loader=MagicMock(), - retriever=MagicMock(), - state_migrations=[first_state_migration, second_state_migration], - config={}, - parameters={}, - ) - - input_state = {"a_key": "a_value"} - - stream.state = input_state - assert stream.state == final_state - first_state_migration.should_migrate.assert_called_once_with(input_state) - first_state_migration.migrate.assert_called_once_with(input_state) - second_state_migration.should_migrate.assert_called_once_with(intermediate_state) - second_state_migration.migrate.assert_called_once_with(intermediate_state) - - -def test_no_state_migration_is_applied_if_the_state_should_not_be_migrated(): - state_migration = MagicMock() - state_migration.should_migrate.return_value = False - - stream = DeclarativeStream( - name="any name", - primary_key="any primary key", - stream_cursor_field="{{ parameters['cursor_field'] }}", - schema_loader=MagicMock(), - retriever=MagicMock(), - state_migrations=[state_migration], - config={}, - parameters={}, - ) - - input_state = {"a_key": "a_value"} - - stream.state = input_state - assert stream.state == input_state - state_migration.should_migrate.assert_called_once_with(input_state) - assert not state_migration.migrate.called - - -@pytest.mark.parametrize( - "use_cursor, expected_supports_checkpointing", - [ - pytest.param(True, True, id="test_retriever_has_cursor"), - pytest.param(False, False, id="test_retriever_has_cursor"), - ], -) -def test_is_resumable(use_cursor, expected_supports_checkpointing): - schema_loader = _schema_loader() - - state = MagicMock() - - retriever = MagicMock() - retriever.state = state - retriever.cursor = MagicMock() if use_cursor else None - - config = {"api_key": "open_sesame"} - - stream = DeclarativeStream( - name=_name, - primary_key=_primary_key, - stream_cursor_field="{{ parameters['cursor_field'] }}", - schema_loader=schema_loader, - retriever=retriever, - config=config, - parameters={"cursor_field": "created_at"}, - ) - - assert stream.is_resumable == expected_supports_checkpointing - - -def _schema_loader(): - schema_loader = MagicMock() - schema_loader.get_json_schema.return_value = _json_schema - return schema_loader diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/test_manifest_declarative_source.py b/airbyte-cdk/python/unit_tests/sources/declarative/test_manifest_declarative_source.py deleted file mode 100644 index 2d350fa12b4b..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/test_manifest_declarative_source.py +++ /dev/null @@ -1,1316 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import logging -import os -import sys -from copy import deepcopy -from pathlib import Path -from typing import Any, List, Mapping -from unittest.mock import call, patch - -import pytest -import requests -import yaml -from airbyte_cdk.models import ( - AirbyteLogMessage, - AirbyteMessage, - AirbyteStream, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteStream, - DestinationSyncMode, - Level, - SyncMode, - Type, -) -from airbyte_cdk.sources.declarative.declarative_stream import DeclarativeStream -from airbyte_cdk.sources.declarative.manifest_declarative_source import ManifestDeclarativeSource -from airbyte_cdk.sources.declarative.retrievers.simple_retriever import SimpleRetriever -from jsonschema.exceptions import ValidationError - -logger = logging.getLogger("airbyte") - -EXTERNAL_CONNECTION_SPECIFICATION = { - "type": "object", - "required": ["api_token"], - "additionalProperties": False, - "properties": {"api_token": {"type": "string"}}, -} - - -class MockManifestDeclarativeSource(ManifestDeclarativeSource): - """ - Mock test class that is needed to monkey patch how we read from various files that make up a declarative source because of how our - tests write configuration files during testing. It is also used to properly namespace where files get written in specific - cases like when we temporarily write files like spec.yaml to the package unit_tests, which is the directory where it will - be read in during the tests. - """ - - -class TestManifestDeclarativeSource: - @pytest.fixture - def use_external_yaml_spec(self): - # Our way of resolving the absolute path to root of the airbyte-cdk unit test directory where spec.yaml files should - # be written to (i.e. ~/airbyte/airbyte-cdk/python/unit-tests) because that is where they are read from during testing. - module = sys.modules[__name__] - module_path = os.path.abspath(module.__file__) - test_path = os.path.dirname(module_path) - spec_root = test_path.split("/sources/declarative")[0] - - spec = {"documentationUrl": "https://airbyte.com/#yaml-from-external", "connectionSpecification": EXTERNAL_CONNECTION_SPECIFICATION} - - yaml_path = os.path.join(spec_root, "spec.yaml") - with open(yaml_path, "w") as f: - f.write(yaml.dump(spec)) - yield - os.remove(yaml_path) - - def test_valid_manifest(self): - manifest = { - "version": "3.8.2", - "definitions": {}, - "description": "This is a sample source connector that is very valid.", - "streams": [ - { - "type": "DeclarativeStream", - "$parameters": {"name": "lists", "primary_key": "id", "url_base": "https://api.sendgrid.com"}, - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": { - "type": "CursorPagination", - "cursor_value": "{{ response._metadata.next }}", - "page_size": 10, - }, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": "{{ 10 }}"}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - { - "type": "DeclarativeStream", - "$parameters": {"name": "stream_with_custom_requester", "primary_key": "id", "url_base": "https://api.sendgrid.com"}, - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": { - "type": "CursorPagination", - "cursor_value": "{{ response._metadata.next }}", - "page_size": 10, - }, - }, - "requester": { - "type": "CustomRequester", - "class_name": "unit_tests.sources.declarative.external_component.SampleCustomComponent", - "path": "/v3/marketing/lists", - "custom_request_parameters": {"page_size": 10}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - ], - "check": {"type": "CheckStream", "stream_names": ["lists"]}, - } - source = ManifestDeclarativeSource(source_config=manifest) - - check_stream = source.connection_checker - check_stream.check_connection(source, logging.getLogger(""), {}) - - streams = source.streams({}) - assert len(streams) == 2 - assert isinstance(streams[0], DeclarativeStream) - assert isinstance(streams[1], DeclarativeStream) - assert source.resolved_manifest["description"] == "This is a sample source connector that is very valid." - - def test_manifest_with_spec(self): - manifest = { - "version": "0.29.3", - "definitions": { - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": {"type": "CursorPagination", "cursor_value": "{{ response._metadata.next }}"}, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": "{{ 10 }}"}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - "streams": [ - { - "type": "DeclarativeStream", - "$parameters": {"name": "lists", "primary_key": "id", "url_base": "https://api.sendgrid.com"}, - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": {"type": "CursorPagination", "cursor_value": "{{ response._metadata.next }}"}, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": "{{ 10 }}"}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - } - ], - "check": {"type": "CheckStream", "stream_names": ["lists"]}, - "spec": { - "type": "Spec", - "documentation_url": "https://airbyte.com/#yaml-from-manifest", - "connection_specification": { - "title": "Test Spec", - "type": "object", - "required": ["api_key"], - "additionalProperties": False, - "properties": { - "api_key": {"type": "string", "airbyte_secret": True, "title": "API Key", "description": "Test API Key", "order": 0} - }, - }, - }, - } - source = ManifestDeclarativeSource(source_config=manifest) - connector_specification = source.spec(logger) - assert connector_specification is not None - assert connector_specification.documentationUrl == "https://airbyte.com/#yaml-from-manifest" - assert connector_specification.connectionSpecification["title"] == "Test Spec" - assert connector_specification.connectionSpecification["required"][0] == "api_key" - assert connector_specification.connectionSpecification["additionalProperties"] is False - assert connector_specification.connectionSpecification["properties"]["api_key"] == { - "type": "string", - "airbyte_secret": True, - "title": "API Key", - "description": "Test API Key", - "order": 0, - } - - def test_manifest_with_external_spec(self, use_external_yaml_spec): - manifest = { - "version": "0.29.3", - "definitions": { - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": {"type": "CursorPagination", "cursor_value": "{{ response._metadata.next }}"}, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": "{{ 10 }}"}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - "streams": [ - { - "type": "DeclarativeStream", - "$parameters": {"name": "lists", "primary_key": "id", "url_base": "https://api.sendgrid.com"}, - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": {"type": "CursorPagination", "cursor_value": "{{ response._metadata.next }}"}, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": "{{ 10 }}"}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - } - ], - "check": {"type": "CheckStream", "stream_names": ["lists"]}, - } - source = MockManifestDeclarativeSource(source_config=manifest) - - connector_specification = source.spec(logger) - - assert connector_specification.documentationUrl == "https://airbyte.com/#yaml-from-external" - assert connector_specification.connectionSpecification == EXTERNAL_CONNECTION_SPECIFICATION - - def test_source_is_not_created_if_toplevel_fields_are_unknown(self): - manifest = { - "version": "0.29.3", - "definitions": { - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": {"type": "CursorPagination", "cursor_value": "{{ response._metadata.next }}"}, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": 10}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - "streams": [ - { - "type": "DeclarativeStream", - "$parameters": {"name": "lists", "primary_key": "id", "url_base": "https://api.sendgrid.com"}, - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": {"type": "CursorPagination", "cursor_value": "{{ response._metadata.next }}"}, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": 10}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - } - ], - "check": {"type": "CheckStream", "stream_names": ["lists"]}, - "not_a_valid_field": "error", - } - with pytest.raises(ValidationError): - ManifestDeclarativeSource(source_config=manifest) - - def test_source_missing_checker_fails_validation(self): - manifest = { - "version": "0.29.3", - "definitions": { - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": {"type": "CursorPagination", "cursor_value": "{{ response._metadata.next }}"}, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": 10}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - "streams": [ - { - "type": "DeclarativeStream", - "$parameters": {"name": "lists", "primary_key": "id", "url_base": "https://api.sendgrid.com"}, - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": {"type": "CursorPagination", "cursor_value": "{{ response._metadata.next }}"}, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": 10}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - } - ], - "check": {"type": "CheckStream"}, - } - with pytest.raises(ValidationError): - ManifestDeclarativeSource(source_config=manifest) - - def test_source_with_missing_streams_fails(self): - manifest = {"version": "0.29.3", "definitions": None, "check": {"type": "CheckStream", "stream_names": ["lists"]}} - with pytest.raises(ValidationError): - ManifestDeclarativeSource(source_config=manifest) - - def test_source_with_missing_version_fails(self): - manifest = { - "definitions": { - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": {"type": "CursorPagination", "cursor_value": "{{ response._metadata.next }}"}, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": 10}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - "streams": [ - { - "type": "DeclarativeStream", - "$parameters": {"name": "lists", "primary_key": "id", "url_base": "https://api.sendgrid.com"}, - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": {"type": "CursorPagination", "cursor_value": "{{ response._metadata.next }}"}, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": 10}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - } - ], - "check": {"type": "CheckStream", "stream_names": ["lists"]}, - } - with pytest.raises(ValidationError): - ManifestDeclarativeSource(source_config=manifest) - - @pytest.mark.parametrize( - "cdk_version, manifest_version, expected_error", - [ - pytest.param("0.35.0", "0.30.0", None, id="manifest_version_less_than_cdk_package_should_run"), - pytest.param("1.5.0", "0.29.0", None, id="manifest_version_less_than_cdk_major_package_should_run"), - pytest.param("0.29.0", "0.29.0", None, id="manifest_version_matching_cdk_package_should_run"), - pytest.param( - "0.29.0", - "0.25.0", - ValidationError, - id="manifest_version_before_beta_that_uses_the_beta_0.29.0_cdk_package_should_throw_error", - ), - pytest.param( - "1.5.0", - "0.25.0", - ValidationError, - id="manifest_version_before_beta_that_uses_package_later_major_version_than_beta_0.29.0_cdk_package_should_throw_error", - ), - pytest.param("0.34.0", "0.35.0", ValidationError, id="manifest_version_greater_than_cdk_package_should_throw_error"), - pytest.param("0.29.0", "-1.5.0", ValidationError, id="manifest_version_has_invalid_major_format"), - pytest.param("0.29.0", "0.invalid.0", ValidationError, id="manifest_version_has_invalid_minor_format"), - pytest.param("0.29.0", "0.29.0.1", ValidationError, id="manifest_version_has_extra_version_parts"), - pytest.param("0.29.0", "5.0", ValidationError, id="manifest_version_has_too_few_version_parts"), - pytest.param("0.29.0:dev", "0.29.0", ValidationError, id="manifest_version_has_extra_release"), - ], - ) - @patch("importlib.metadata.version") - def test_manifest_versions(self, version, cdk_version, manifest_version, expected_error): - # Used to mock the metadata.version() for test scenarios which normally returns the actual version of the airbyte-cdk package - version.return_value = cdk_version - - manifest = { - "version": manifest_version, - "definitions": {}, - "streams": [ - { - "type": "DeclarativeStream", - "$parameters": {"name": "lists", "primary_key": "id", "url_base": "https://api.sendgrid.com"}, - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": { - "type": "CursorPagination", - "cursor_value": "{{ response._metadata.next }}", - "page_size": 10, - }, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": "{{ 10 }}"}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - { - "type": "DeclarativeStream", - "$parameters": {"name": "stream_with_custom_requester", "primary_key": "id", "url_base": "https://api.sendgrid.com"}, - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": { - "type": "CursorPagination", - "cursor_value": "{{ response._metadata.next }}", - "page_size": 10, - }, - }, - "requester": { - "type": "CustomRequester", - "class_name": "unit_tests.sources.declarative.external_component.SampleCustomComponent", - "path": "/v3/marketing/lists", - "custom_request_parameters": {"page_size": 10}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - ], - "check": {"type": "CheckStream", "stream_names": ["lists"]}, - } - if expected_error: - with pytest.raises(expected_error): - ManifestDeclarativeSource(source_config=manifest) - else: - ManifestDeclarativeSource(source_config=manifest) - - def test_source_with_invalid_stream_config_fails_validation(self): - manifest = { - "version": "0.29.3", - "definitions": { - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - } - }, - "streams": [ - { - "type": "DeclarativeStream", - "$parameters": {"name": "lists", "primary_key": "id", "url_base": "https://api.sendgrid.com"}, - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - } - ], - "check": {"type": "CheckStream", "stream_names": ["lists"]}, - } - with pytest.raises(ValidationError): - ManifestDeclarativeSource(source_config=manifest) - - def test_source_with_no_external_spec_and_no_in_yaml_spec_fails(self): - manifest = { - "version": "0.29.3", - "definitions": { - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": {"type": "CursorPagination", "cursor_value": "{{ response._metadata.next }}"}, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": "{{ 10 }}"}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - "streams": [ - { - "type": "DeclarativeStream", - "$parameters": {"name": "lists", "primary_key": "id", "url_base": "https://api.sendgrid.com"}, - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": {"type": "CursorPagination", "cursor_value": "{{ response._metadata.next }}"}, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": "{{ 10 }}"}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - } - ], - "check": {"type": "CheckStream", "stream_names": ["lists"]}, - } - source = ManifestDeclarativeSource(source_config=manifest) - - # We expect to fail here because we have not created a temporary spec.yaml file - with pytest.raises(FileNotFoundError): - source.spec(logger) - - def test_manifest_without_at_least_one_stream(self): - manifest = { - "version": "0.29.3", - "definitions": { - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": {"type": "CursorPagination", "cursor_value": "{{ response._metadata.next }}"}, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": 10}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - "streams": [], - "check": {"type": "CheckStream", "stream_names": ["lists"]}, - } - with pytest.raises(ValidationError): - ManifestDeclarativeSource(source_config=manifest) - - @patch("airbyte_cdk.sources.declarative.declarative_source.DeclarativeSource.read") - def test_given_debug_when_read_then_set_log_level(self, declarative_source_read): - any_valid_manifest = { - "version": "0.29.3", - "definitions": { - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": {"type": "CursorPagination", "cursor_value": "{{ response._metadata.next }}"}, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": "10"}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - "streams": [ - { - "type": "DeclarativeStream", - "$parameters": {"name": "lists", "primary_key": "id", "url_base": "https://api.sendgrid.com"}, - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": { - "type": "CursorPagination", - "cursor_value": "{{ response._metadata.next }}", - "page_size": 10, - }, - }, - "requester": { - "path": "/v3/marketing/lists", - "authenticator": {"type": "BearerAuthenticator", "api_token": "{{ config.apikey }}"}, - "request_parameters": {"page_size": "{{ 10 }}"}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - { - "type": "DeclarativeStream", - "$parameters": {"name": "stream_with_custom_requester", "primary_key": "id", "url_base": "https://api.sendgrid.com"}, - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": { - "type": "CursorPagination", - "cursor_value": "{{ response._metadata.next }}", - "page_size": 10, - }, - }, - "requester": { - "type": "CustomRequester", - "class_name": "unit_tests.sources.declarative.external_component.SampleCustomComponent", - "path": "/v3/marketing/lists", - "custom_request_parameters": {"page_size": 10}, - }, - "record_selector": {"extractor": {"field_path": ["result"]}}, - }, - }, - ], - "check": {"type": "CheckStream", "stream_names": ["lists"]}, - } - source = ManifestDeclarativeSource(source_config=any_valid_manifest, debug=True) - - debug_logger = logging.getLogger("logger.debug") - list(source.read(debug_logger, {}, {}, {})) - - assert debug_logger.isEnabledFor(logging.DEBUG) - - -def request_log_message(request: dict) -> AirbyteMessage: - return AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=Level.INFO, message=f"request:{json.dumps(request)}")) - - -def response_log_message(response: dict) -> AirbyteMessage: - return AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=Level.INFO, message=f"response:{json.dumps(response)}")) - - -def _create_request(): - url = "https://example.com/api" - headers = {"Content-Type": "application/json"} - return requests.Request("POST", url, headers=headers, json={"key": "value"}).prepare() - - -def _create_response(body): - response = requests.Response() - response.status_code = 200 - response._content = bytes(json.dumps(body), "utf-8") - response.headers["Content-Type"] = "application/json" - return response - - -def _create_page(response_body): - response = _create_response(response_body) - response.request = _create_request() - return response - - -@pytest.mark.parametrize( - "test_name, manifest, pages, expected_records, expected_calls", - [ - ( - "test_read_manifest_no_pagination_no_partitions", - { - "version": "0.34.2", - "type": "DeclarativeSource", - "check": {"type": "CheckStream", "stream_names": ["Rates"]}, - "streams": [ - { - "type": "DeclarativeStream", - "name": "Rates", - "primary_key": [], - "schema_loader": { - "type": "InlineSchemaLoader", - "schema": { - "$schema": "http://json-schema.org/schema#", - "properties": { - "ABC": {"type": "number"}, - "AED": {"type": "number"}, - }, - "type": "object", - }, - }, - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "url_base": "https://api.apilayer.com", - "path": "/exchangerates_data/latest", - "http_method": "GET", - "request_parameters": {}, - "request_headers": {}, - "request_body_json": {}, - "authenticator": { - "type": "ApiKeyAuthenticator", - "header": "apikey", - "api_token": "{{ config['api_key'] }}", - }, - }, - "record_selector": {"type": "RecordSelector", "extractor": {"type": "DpathExtractor", "field_path": ["rates"]}}, - "paginator": {"type": "NoPagination"}, - }, - } - ], - "spec": { - "connection_specification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": ["api_key"], - "properties": {"api_key": {"type": "string", "title": "API Key", "airbyte_secret": True}}, - "additionalProperties": True, - }, - "documentation_url": "https://example.org", - "type": "Spec", - }, - }, - ( - _create_page({"rates": [{"ABC": 0}, {"AED": 1}], "_metadata": {"next": "next"}}), - _create_page({"rates": [{"USD": 2}], "_metadata": {"next": "next"}}), - ) - * 10, - [{"ABC": 0}, {"AED": 1}], - [call({}, {})], - ), - ( - "test_read_manifest_with_added_fields", - { - "version": "0.34.2", - "type": "DeclarativeSource", - "check": {"type": "CheckStream", "stream_names": ["Rates"]}, - "streams": [ - { - "type": "DeclarativeStream", - "name": "Rates", - "primary_key": [], - "schema_loader": { - "type": "InlineSchemaLoader", - "schema": { - "$schema": "http://json-schema.org/schema#", - "properties": { - "ABC": {"type": "number"}, - "AED": {"type": "number"}, - }, - "type": "object", - }, - }, - "transformations": [ - { - "type": "AddFields", - "fields": [{"type": "AddedFieldDefinition", "path": ["added_field_key"], "value": "added_field_value"}], - } - ], - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "url_base": "https://api.apilayer.com", - "path": "/exchangerates_data/latest", - "http_method": "GET", - "request_parameters": {}, - "request_headers": {}, - "request_body_json": {}, - "authenticator": { - "type": "ApiKeyAuthenticator", - "header": "apikey", - "api_token": "{{ config['api_key'] }}", - }, - }, - "record_selector": {"type": "RecordSelector", "extractor": {"type": "DpathExtractor", "field_path": ["rates"]}}, - "paginator": {"type": "NoPagination"}, - }, - } - ], - "spec": { - "connection_specification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": ["api_key"], - "properties": {"api_key": {"type": "string", "title": "API Key", "airbyte_secret": True}}, - "additionalProperties": True, - }, - "documentation_url": "https://example.org", - "type": "Spec", - }, - }, - ( - _create_page({"rates": [{"ABC": 0}, {"AED": 1}], "_metadata": {"next": "next"}}), - _create_page({"rates": [{"USD": 2}], "_metadata": {"next": "next"}}), - ) - * 10, - [{"ABC": 0, "added_field_key": "added_field_value"}, {"AED": 1, "added_field_key": "added_field_value"}], - [call({}, {})], - ), - ( - "test_read_with_pagination_no_partitions", - { - "version": "0.34.2", - "type": "DeclarativeSource", - "check": {"type": "CheckStream", "stream_names": ["Rates"]}, - "streams": [ - { - "type": "DeclarativeStream", - "name": "Rates", - "primary_key": [], - "schema_loader": { - "type": "InlineSchemaLoader", - "schema": { - "$schema": "http://json-schema.org/schema#", - "properties": { - "ABC": {"type": "number"}, - "AED": {"type": "number"}, - "USD": {"type": "number"}, - }, - "type": "object", - }, - }, - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "url_base": "https://api.apilayer.com", - "path": "/exchangerates_data/latest", - "http_method": "GET", - "request_parameters": {}, - "request_headers": {}, - "request_body_json": {}, - "authenticator": { - "type": "ApiKeyAuthenticator", - "header": "apikey", - "api_token": "{{ config['api_key'] }}", - }, - }, - "record_selector": {"type": "RecordSelector", "extractor": {"type": "DpathExtractor", "field_path": ["rates"]}}, - "paginator": { - "type": "DefaultPaginator", - "page_size": 2, - "page_size_option": {"inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"inject_into": "path", "type": "RequestPath"}, - "pagination_strategy": { - "type": "CursorPagination", - "cursor_value": "{{ response._metadata.next }}", - "page_size": 2, - }, - }, - }, - } - ], - "spec": { - "connection_specification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": ["api_key"], - "properties": {"api_key": {"type": "string", "title": "API Key", "airbyte_secret": True}}, - "additionalProperties": True, - }, - "documentation_url": "https://example.org", - "type": "Spec", - }, - }, - ( - _create_page({"rates": [{"ABC": 0}, {"AED": 1}], "_metadata": {"next": "next"}}), - _create_page({"rates": [{"USD": 2}], "_metadata": {}}), - ) - * 10, - [{"ABC": 0}, {"AED": 1}, {"USD": 2}], - [call({}, {}), call({"next_page_token": "next"}, {"next_page_token": "next"})], - ), - ( - "test_no_pagination_with_partition_router", - { - "version": "0.34.2", - "type": "DeclarativeSource", - "check": {"type": "CheckStream", "stream_names": ["Rates"]}, - "streams": [ - { - "type": "DeclarativeStream", - "name": "Rates", - "primary_key": [], - "schema_loader": { - "type": "InlineSchemaLoader", - "schema": { - "$schema": "http://json-schema.org/schema#", - "properties": {"ABC": {"type": "number"}, "AED": {"type": "number"}, "partition": {"type": "number"}}, - "type": "object", - }, - }, - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "url_base": "https://api.apilayer.com", - "path": "/exchangerates_data/latest", - "http_method": "GET", - "request_parameters": {}, - "request_headers": {}, - "request_body_json": {}, - "authenticator": { - "type": "ApiKeyAuthenticator", - "header": "apikey", - "api_token": "{{ config['api_key'] }}", - }, - }, - "partition_router": {"type": "ListPartitionRouter", "values": ["0", "1"], "cursor_field": "partition"}, - "record_selector": {"type": "RecordSelector", "extractor": {"type": "DpathExtractor", "field_path": ["rates"]}}, - "paginator": {"type": "NoPagination"}, - }, - } - ], - "spec": { - "connection_specification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": ["api_key"], - "properties": {"api_key": {"type": "string", "title": "API Key", "airbyte_secret": True}}, - "additionalProperties": True, - }, - "documentation_url": "https://example.org", - "type": "Spec", - }, - }, - ( - _create_page({"rates": [{"ABC": 0, "partition": 0}, {"AED": 1, "partition": 0}], "_metadata": {"next": "next"}}), - _create_page({"rates": [{"ABC": 2, "partition": 1}], "_metadata": {"next": "next"}}), - ), - [{"ABC": 0, "partition": 0}, {"AED": 1, "partition": 0}, {"ABC": 2, "partition": 1}], - [ - call({"states": []}, {"partition": "0"}, None), - call( - {"states": [{"partition": {"partition": "0"}, "cursor": {"__ab_full_refresh_sync_complete": True}}]}, - {"partition": "1"}, - None, - ), - ], - ), - ( - "test_with_pagination_and_partition_router", - { - "version": "0.34.2", - "type": "DeclarativeSource", - "check": {"type": "CheckStream", "stream_names": ["Rates"]}, - "streams": [ - { - "type": "DeclarativeStream", - "name": "Rates", - "primary_key": [], - "schema_loader": { - "type": "InlineSchemaLoader", - "schema": { - "$schema": "http://json-schema.org/schema#", - "properties": {"ABC": {"type": "number"}, "AED": {"type": "number"}, "partition": {"type": "number"}}, - "type": "object", - }, - }, - "retriever": { - "type": "SimpleRetriever", - "requester": { - "type": "HttpRequester", - "url_base": "https://api.apilayer.com", - "path": "/exchangerates_data/latest", - "http_method": "GET", - "request_parameters": {}, - "request_headers": {}, - "request_body_json": {}, - "authenticator": { - "type": "ApiKeyAuthenticator", - "header": "apikey", - "api_token": "{{ config['api_key'] }}", - }, - }, - "partition_router": {"type": "ListPartitionRouter", "values": ["0", "1"], "cursor_field": "partition"}, - "record_selector": {"type": "RecordSelector", "extractor": {"type": "DpathExtractor", "field_path": ["rates"]}}, - "paginator": { - "type": "DefaultPaginator", - "page_size": 2, - "page_size_option": {"inject_into": "request_parameter", "field_name": "page_size"}, - "page_token_option": {"inject_into": "path", "type": "RequestPath"}, - "pagination_strategy": { - "type": "CursorPagination", - "cursor_value": "{{ response._metadata.next }}", - "page_size": 2, - }, - }, - }, - } - ], - "spec": { - "connection_specification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": ["api_key"], - "properties": {"api_key": {"type": "string", "title": "API Key", "airbyte_secret": True}}, - "additionalProperties": True, - }, - "documentation_url": "https://example.org", - "type": "Spec", - }, - }, - ( - _create_page({"rates": [{"ABC": 0, "partition": 0}, {"AED": 1, "partition": 0}], "_metadata": {"next": "next"}}), - _create_page({"rates": [{"USD": 3, "partition": 0}], "_metadata": {}}), - _create_page({"rates": [{"ABC": 2, "partition": 1}], "_metadata": {}}), - ), - [{"ABC": 0, "partition": 0}, {"AED": 1, "partition": 0}, {"USD": 3, "partition": 0}, {"ABC": 2, "partition": 1}], - [ - call({"states": []}, {"partition": "0"}, None), - call({"states": []}, {"partition": "0"}, {"next_page_token": "next"}), - call( - {"states": [{"partition": {"partition": "0"}, "cursor": {"__ab_full_refresh_sync_complete": True}}]}, - {"partition": "1"}, - None, - ), - ], - ), - ], -) -def test_read_manifest_declarative_source(test_name, manifest, pages, expected_records, expected_calls): - _stream_name = "Rates" - with patch.object(SimpleRetriever, "_fetch_next_page", side_effect=pages) as mock_retriever: - output_data = [message.record.data for message in _run_read(manifest, _stream_name) if message.record] - assert output_data == expected_records - mock_retriever.assert_has_calls(expected_calls) - - -def test_only_parent_streams_use_cache(): - applications_stream = { - "type": "DeclarativeStream", - "$parameters": {"name": "applications", "primary_key": "id", "url_base": "https://harvest.greenhouse.io/v1/"}, - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "per_page"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": { - "type": "CursorPagination", - "cursor_value": "{{ headers['link']['next']['url'] }}", - "stop_condition": "{{ 'next' not in headers['link'] }}", - "page_size": 100, - }, - }, - "requester": { - "path": "applications", - "authenticator": {"type": "BasicHttpAuthenticator", "username": "{{ config['api_key'] }}"}, - }, - "record_selector": {"extractor": {"type": "DpathExtractor", "field_path": []}}, - }, - } - - manifest = { - "version": "0.29.3", - "definitions": {}, - "streams": [ - deepcopy(applications_stream), - { - "type": "DeclarativeStream", - "$parameters": {"name": "applications_interviews", "primary_key": "id", "url_base": "https://harvest.greenhouse.io/v1/"}, - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "per_page"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": { - "type": "CursorPagination", - "cursor_value": "{{ headers['link']['next']['url'] }}", - "stop_condition": "{{ 'next' not in headers['link'] }}", - "page_size": 100, - }, - }, - "requester": { - "path": "applications_interviews", - "authenticator": {"type": "BasicHttpAuthenticator", "username": "{{ config['api_key'] }}"}, - }, - "record_selector": {"extractor": {"type": "DpathExtractor", "field_path": []}}, - "partition_router": { - "parent_stream_configs": [ - {"parent_key": "id", "partition_field": "parent_id", "stream": deepcopy(applications_stream)} - ], - "type": "SubstreamPartitionRouter", - }, - }, - }, - { - "type": "DeclarativeStream", - "$parameters": {"name": "jobs", "primary_key": "id", "url_base": "https://harvest.greenhouse.io/v1/"}, - "schema_loader": { - "name": "{{ parameters.stream_name }}", - "file_path": "./source_sendgrid/schemas/{{ parameters.name }}.yaml", - }, - "retriever": { - "paginator": { - "type": "DefaultPaginator", - "page_size": 10, - "page_size_option": {"type": "RequestOption", "inject_into": "request_parameter", "field_name": "per_page"}, - "page_token_option": {"type": "RequestPath"}, - "pagination_strategy": { - "type": "CursorPagination", - "cursor_value": "{{ headers['link']['next']['url'] }}", - "stop_condition": "{{ 'next' not in headers['link'] }}", - "page_size": 100, - }, - }, - "requester": { - "path": "jobs", - "authenticator": {"type": "BasicHttpAuthenticator", "username": "{{ config['api_key'] }}"}, - }, - "record_selector": {"extractor": {"type": "DpathExtractor", "field_path": []}}, - }, - }, - ], - "check": {"type": "CheckStream", "stream_names": ["applications"]}, - } - source = ManifestDeclarativeSource(source_config=manifest) - - streams = source.streams({}) - assert len(streams) == 3 - - # Main stream with caching (parent for substream `applications_interviews`) - assert streams[0].name == "applications" - assert streams[0].retriever.requester.use_cache - - # Substream - assert streams[1].name == "applications_interviews" - assert not streams[1].retriever.requester.use_cache - - # Parent stream created for substream - assert streams[1].retriever.stream_slicer._partition_router.parent_stream_configs[0].stream.name == "applications" - assert streams[1].retriever.stream_slicer._partition_router.parent_stream_configs[0].stream.retriever.requester.use_cache - - # Main stream without caching - assert streams[2].name == "jobs" - assert not streams[2].retriever.requester.use_cache - - -def _run_read(manifest: Mapping[str, Any], stream_name: str) -> List[AirbyteMessage]: - source = ManifestDeclarativeSource(source_config=manifest) - catalog = ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=AirbyteStream(name=stream_name, json_schema={}, supported_sync_modes=[SyncMode.full_refresh]), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.append, - ) - ] - ) - return list(source.read(logger, {}, catalog, {})) - - -def test_declarative_component_schema_valid_ref_links(): - def load_yaml(file_path) -> Mapping[str, Any]: - with open(file_path, "r") as file: - return yaml.safe_load(file) - - def extract_refs(data, base_path="#") -> List[str]: - refs = [] - if isinstance(data, dict): - for key, value in data.items(): - if key == "$ref" and isinstance(value, str) and value.startswith("#"): - ref_path = value - refs.append(ref_path) - else: - refs.extend(extract_refs(value, base_path)) - elif isinstance(data, list): - for item in data: - refs.extend(extract_refs(item, base_path)) - return refs - - def resolve_pointer(data: Mapping[str, Any], pointer: str) -> bool: - parts = pointer.split("/")[1:] # Skip the first empty part due to leading '#/' - current = data - try: - for part in parts: - part = part.replace("~1", "/").replace("~0", "~") # Unescape JSON Pointer - current = current[part] - return True - except (KeyError, TypeError): - return False - - def validate_refs(yaml_file: str) -> List[str]: - data = load_yaml(yaml_file) - refs = extract_refs(data) - invalid_refs = [ref for ref in refs if not resolve_pointer(data, ref.replace("#", ""))] - return invalid_refs - - yaml_file_path = ( - Path(__file__).resolve().parent.parent.parent.parent / "airbyte_cdk/sources/declarative/declarative_component_schema.yaml" - ) - assert not validate_refs(yaml_file_path) diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/test_types.py b/airbyte-cdk/python/unit_tests/sources/declarative/test_types.py deleted file mode 100644 index b6eb42f940b6..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/test_types.py +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -import pytest -from airbyte_cdk.sources.types import StreamSlice - - -@pytest.mark.parametrize( - "stream_slice, expected_partition", - [ - pytest.param(StreamSlice(partition={}, cursor_slice={}), {}, id="test_partition_with_empty_partition"), - pytest.param( - StreamSlice(partition=StreamSlice(partition={}, cursor_slice={}), cursor_slice={}), {}, id="test_partition_nested_empty" - ), - pytest.param( - StreamSlice(partition={"key": "value"}, cursor_slice={}), {"key": "value"}, id="test_partition_with_mapping_partition" - ), - pytest.param(StreamSlice(partition={}, cursor_slice={"cursor": "value"}), {}, id="test_partition_with_only_cursor"), - pytest.param( - StreamSlice(partition=StreamSlice(partition={}, cursor_slice={}), cursor_slice={"cursor": "value"}), - {}, - id="test_partition_nested_empty_and_cursor_value_mapping", - ), - pytest.param( - StreamSlice(partition=StreamSlice(partition={}, cursor_slice={"cursor": "value"}), cursor_slice={}), - {}, - id="test_partition_nested_empty_and_cursor_value", - ), - ], -) -def test_partition(stream_slice, expected_partition): - partition = stream_slice.partition - - assert partition == expected_partition - - -@pytest.mark.parametrize( - "stream_slice, expected_cursor_slice", - [ - pytest.param(StreamSlice(partition={}, cursor_slice={}), {}, id="test_cursor_slice_with_empty_cursor"), - pytest.param( - StreamSlice(partition={}, cursor_slice=StreamSlice(partition={}, cursor_slice={})), {}, id="test_cursor_slice_nested_empty" - ), - pytest.param( - StreamSlice(partition={}, cursor_slice={"key": "value"}), {"key": "value"}, id="test_cursor_slice_with_mapping_cursor_slice" - ), - pytest.param(StreamSlice(partition={"partition": "value"}, cursor_slice={}), {}, id="test_cursor_slice_with_only_partition"), - pytest.param( - StreamSlice(partition={"partition": "value"}, cursor_slice=StreamSlice(partition={}, cursor_slice={})), - {}, - id="test_cursor_slice_nested_empty_and_partition_mapping", - ), - pytest.param( - StreamSlice(partition=StreamSlice(partition={"partition": "value"}, cursor_slice={}), cursor_slice={}), - {}, - id="test_cursor_slice_nested_empty_and_partition", - ), - ], -) -def test_cursor_slice(stream_slice, expected_cursor_slice): - cursor_slice = stream_slice.cursor_slice - - assert cursor_slice == expected_cursor_slice diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/test_yaml_declarative_source.py b/airbyte-cdk/python/unit_tests/sources/declarative/test_yaml_declarative_source.py deleted file mode 100644 index 9f5ead4db775..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/test_yaml_declarative_source.py +++ /dev/null @@ -1,148 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -import os -import tempfile - -import pytest -from airbyte_cdk.sources.declarative.parsers.custom_exceptions import UndefinedReferenceException -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource -from yaml.parser import ParserError - -logger = logging.getLogger("airbyte") - - -EXTERNAL_CONNECTION_SPECIFICATION = { - "type": "object", - "required": ["api_token"], - "additionalProperties": False, - "properties": {"api_token": {"type": "string"}}, -} - - -class MockYamlDeclarativeSource(YamlDeclarativeSource): - """ - Mock test class that is needed to monkey patch how we read from various files that make up a declarative source because of how our - tests write configuration files during testing. It is also used to properly namespace where files get written in specific - cases like when we temporarily write files like spec.yaml to the package unit_tests, which is the directory where it will - be read in during the tests. - """ - - def _read_and_parse_yaml_file(self, path_to_yaml_file): - """ - We override the default behavior because we use tempfile to write the yaml manifest to a temporary directory which is - not mounted during runtime which prevents pkgutil.get_data() from being able to find the yaml file needed to generate - # the declarative source. For tests we use open() which supports using an absolute path. - """ - with open(path_to_yaml_file, "r") as f: - config_content = f.read() - parsed_config = YamlDeclarativeSource._parse(config_content) - return parsed_config - - -class TestYamlDeclarativeSource: - def test_source_is_created_if_toplevel_fields_are_known(self): - content = """ - version: "0.29.3" - definitions: - schema_loader: - name: "{{ parameters.stream_name }}" - file_path: "./source_sendgrid/schemas/{{ parameters.name }}.yaml" - retriever: - paginator: - type: "DefaultPaginator" - page_size: 10 - page_size_option: - inject_into: request_parameter - field_name: page_size - page_token_option: - type: RequestPath - pagination_strategy: - type: "CursorPagination" - cursor_value: "{{ response._metadata.next }}" - requester: - url_base: "https://api.sendgrid.com" - path: "/v3/marketing/lists" - authenticator: - type: "BearerAuthenticator" - api_token: "{{ config.apikey }}" - request_parameters: - page_size: "{{ 10 }}" - record_selector: - extractor: - field_path: ["result"] - streams: - - type: DeclarativeStream - $parameters: - name: "lists" - primary_key: id - schema_loader: "#/definitions/schema_loader" - retriever: "#/definitions/retriever" - check: - type: CheckStream - stream_names: ["lists"] - """ - temporary_file = TestFileContent(content) - MockYamlDeclarativeSource(temporary_file.filename) - - def test_source_fails_for_invalid_yaml(self): - content = """ - version: "version" - definitions: - this is not parsable yaml: " at all - streams: - - type: DeclarativeStream - $parameters: - name: "lists" - primary_key: id - url_base: "https://api.sendgrid.com" - check: - type: CheckStream - stream_names: ["lists"] - """ - temporary_file = TestFileContent(content) - with pytest.raises(ParserError): - MockYamlDeclarativeSource(temporary_file.filename) - - def test_source_with_missing_reference_fails(self): - content = """ - version: "version" - definitions: - schema_loader: - name: "{{ parameters.stream_name }}" - file_path: "./source_sendgrid/schemas/{{ parameters.name }}.yaml" - streams: - - type: DeclarativeStream - $parameters: - name: "lists" - primary_key: id - url_base: "https://api.sendgrid.com" - schema_loader: "#/definitions/schema_loader" - retriever: "#/definitions/retriever" - check: - type: CheckStream - stream_names: ["lists"] - """ - temporary_file = TestFileContent(content) - with pytest.raises(UndefinedReferenceException): - MockYamlDeclarativeSource(temporary_file.filename) - - -class TestFileContent: - def __init__(self, content): - self.file = tempfile.NamedTemporaryFile(mode="w", delete=False) - - with self.file as f: - f.write(content) - - @property - def filename(self): - return self.file.name - - def __enter__(self): - return self - - def __exit__(self, type, value, traceback): - os.unlink(self.filename) diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/transformations/test_add_fields.py b/airbyte-cdk/python/unit_tests/sources/declarative/transformations/test_add_fields.py deleted file mode 100644 index 9b46cf49b99b..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/transformations/test_add_fields.py +++ /dev/null @@ -1,136 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, List, Mapping, Optional, Tuple - -import pytest -from airbyte_cdk.sources.declarative.transformations import AddFields -from airbyte_cdk.sources.declarative.transformations.add_fields import AddedFieldDefinition -from airbyte_cdk.sources.types import FieldPointer - - -@pytest.mark.parametrize( - ["input_record", "field", "field_type", "kwargs", "expected"], - [ - pytest.param({"k": "v"}, [(["path"], "static_value")], None, {}, {"k": "v", "path": "static_value"}, id="add new static value"), - pytest.param({"k": "v"}, [(["path"], "{{ 1 }}")], None, {}, {"k": "v", "path": 1}, id="add an expression evaluated as a number"), - pytest.param( - {"k": "v"}, - [(["path"], "{{ 1 }}")], - str, - {}, - {"k": "v", "path": "1"}, - id="add an expression evaluated as a string using the value_type field", - ), - pytest.param( - {"k": "v"}, - [(["path"], "static_value"), (["path2"], "static_value2")], - None, - {}, - {"k": "v", "path": "static_value", "path2": "static_value2"}, - id="add new multiple static values", - ), - pytest.param( - {"k": "v"}, - [(["nested", "path"], "static_value")], - None, - {}, - {"k": "v", "nested": {"path": "static_value"}}, - id="set static value at nested path", - ), - pytest.param({"k": "v"}, [(["k"], "new_value")], None, {}, {"k": "new_value"}, id="update value which already exists"), - pytest.param({"k": [0, 1]}, [(["k", 3], "v")], None, {}, {"k": [0, 1, None, "v"]}, id="Set element inside array"), - pytest.param( - {"k": "v"}, - [(["k2"], '{{ config["shop"] }}')], - None, - {"config": {"shop": "in-n-out"}}, - {"k": "v", "k2": "in-n-out"}, - id="set a value from the config using bracket notation", - ), - pytest.param( - {"k": "v"}, - [(["k2"], "{{ config.shop }}")], - None, - {"config": {"shop": "in-n-out"}}, - {"k": "v", "k2": "in-n-out"}, - id="set a value from the config using dot notation", - ), - pytest.param( - {"k": "v"}, - [(["k2"], '{{ stream_state["cursor"] }}')], - None, - {"stream_state": {"cursor": "t0"}}, - {"k": "v", "k2": "t0"}, - id="set a value from the state using bracket notation", - ), - pytest.param( - {"k": "v"}, - [(["k2"], "{{ stream_state.cursor }}")], - None, - {"stream_state": {"cursor": "t0"}}, - {"k": "v", "k2": "t0"}, - id="set a value from the state using dot notation", - ), - pytest.param( - {"k": "v"}, - [(["k2"], '{{ stream_slice["start_date"] }}')], - None, - {"stream_slice": {"start_date": "oct1"}}, - {"k": "v", "k2": "oct1"}, - id="set a value from the stream slice using bracket notation", - ), - pytest.param( - {"k": "v"}, - [(["k2"], "{{ stream_slice.start_date }}")], - None, - {"stream_slice": {"start_date": "oct1"}}, - {"k": "v", "k2": "oct1"}, - id="set a value from the stream slice using dot notation", - ), - pytest.param( - {"k": "v"}, - [(["k2"], "{{ record.k }}")], - None, - {}, - {"k": "v", "k2": "v"}, - id="set a value from a field in the record using dot notation", - ), - pytest.param( - {"k": "v"}, - [(["k2"], '{{ record["k"] }}')], - None, - {}, - {"k": "v", "k2": "v"}, - id="set a value from a field in the record using bracket notation", - ), - pytest.param( - {"k": {"nested": "v"}}, - [(["k2"], "{{ record.k.nested }}")], - None, - {}, - {"k": {"nested": "v"}, "k2": "v"}, - id="set a value from a nested field in the record using bracket notation", - ), - pytest.param( - {"k": {"nested": "v"}}, - [(["k2"], '{{ record["k"]["nested"] }}')], - None, - {}, - {"k": {"nested": "v"}, "k2": "v"}, - id="set a value from a nested field in the record using bracket notation", - ), - pytest.param({"k": "v"}, [(["k2"], "{{ 2 + 2 }}")], None, {}, {"k": "v", "k2": 4}, id="set a value from a jinja expression"), - ], -) -def test_add_fields( - input_record: Mapping[str, Any], - field: List[Tuple[FieldPointer, str]], - field_type: Optional[str], - kwargs: Mapping[str, Any], - expected: Mapping[str, Any], -): - inputs = [AddedFieldDefinition(path=v[0], value=v[1], value_type=field_type, parameters={}) for v in field] - AddFields(fields=inputs, parameters={"alas": "i live"}).transform(input_record, **kwargs) - assert input_record == expected diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/transformations/test_keys_to_lower_transformation.py b/airbyte-cdk/python/unit_tests/sources/declarative/transformations/test_keys_to_lower_transformation.py deleted file mode 100644 index 7464b9f04fd2..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/transformations/test_keys_to_lower_transformation.py +++ /dev/null @@ -1,13 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.transformations.keys_to_lower_transformation import KeysToLowerTransformation - -_ANY_VALUE = -1 - - -def test_transform() -> None: - record = {"wIth_CapITal": _ANY_VALUE, "anOThEr_witH_Caps": _ANY_VALUE} - KeysToLowerTransformation().transform(record) - assert {"with_capital": _ANY_VALUE, "another_with_caps": _ANY_VALUE} diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/transformations/test_remove_fields.py b/airbyte-cdk/python/unit_tests/sources/declarative/transformations/test_remove_fields.py deleted file mode 100644 index 89b17e8d0f75..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/declarative/transformations/test_remove_fields.py +++ /dev/null @@ -1,89 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, List, Mapping - -import pytest -from airbyte_cdk.sources.declarative.transformations import RemoveFields -from airbyte_cdk.sources.types import FieldPointer - - -@pytest.mark.parametrize( - ["input_record", "field_pointers", "condition", "expected"], - [ - pytest.param({"k1": "v", "k2": "v"}, [["k1"]], None, {"k2": "v"}, id="remove a field that exists (flat dict), condition = None"), - pytest.param({"k1": "v", "k2": "v"}, [["k1"]], "", {"k2": "v"}, id="remove a field that exists (flat dict)"), - pytest.param({"k1": "v", "k2": "v"}, [["k3"]], "", {"k1": "v", "k2": "v"}, id="remove a field that doesn't exist (flat dict)"), - pytest.param({"k1": "v", "k2": "v"}, [["k1"], ["k2"]], "", {}, id="remove multiple fields that exist (flat dict)"), - # TODO: should we instead splice the element out of the array? I think that's the more intuitive solution - # Otherwise one could just set the field's value to null. - pytest.param({"k1": [1, 2]}, [["k1", 0]], "", {"k1": [None, 2]}, id="remove field inside array (int index)"), - pytest.param({"k1": [1, 2]}, [["k1", "0"]], "", {"k1": [None, 2]}, id="remove field inside array (string index)"), - pytest.param( - {"k1": "v", "k2": "v", "k3": [0, 1], "k4": "v"}, - [["k1"], ["k2"], ["k3", 0]], - "", - {"k3": [None, 1], "k4": "v"}, - id="test all cases (flat)", - ), - pytest.param({"k1": [0, 1]}, [[".", "k1", 10]], "", {"k1": [0, 1]}, id="remove array index that doesn't exist (flat)"), - pytest.param( - {".": {"k1": [0, 1]}}, [[".", "k1", 10]], "", {".": {"k1": [0, 1]}}, id="remove array index that doesn't exist (nested)" - ), - pytest.param({".": {"k2": "v", "k1": "v"}}, [[".", "k1"]], "", {".": {"k2": "v"}}, id="remove nested field that exists"), - pytest.param( - {".": {"k2": "v", "k1": "v"}}, [[".", "k3"]], "", {".": {"k2": "v", "k1": "v"}}, id="remove field that doesn't exist (nested)" - ), - pytest.param( - {".": {"k2": "v", "k1": "v"}}, [[".", "k1"], [".", "k2"]], "", {".": {}}, id="remove multiple fields that exist (nested)" - ), - pytest.param( - {".": {"k1": [0, 1]}}, - [[".", "k1", 0]], - "", - {".": {"k1": [None, 1]}}, - id="remove multiple fields that exist in arrays (nested)", - ), - pytest.param( - {".": {"k1": [{"k2": "v", "k3": "v"}, {"k4": "v"}]}}, - [[".", "k1", 0, "k2"], [".", "k1", 1, "k4"]], - "", - {".": {"k1": [{"k3": "v"}, {}]}}, - id="remove fields that exist in arrays (deeply nested)", - ), - pytest.param( - {"k1": "v", "k2": "v"}, - [["**"]], - "{{ False }}", - {"k1": "v", "k2": "v"}, - id="do not remove any field if condition is boolean False", - ), - pytest.param({"k1": "v", "k2": "v"}, [["**"]], "{{ True }}", {}, id="remove all field if condition is boolean True"), - pytest.param( - {"k1": "v", "k2": "v1", "k3": "v1", "k4": {"k_nested": "v1", "k_nested2": "v2"}}, - [["**"]], - "{{ property == 'v1' }}", - {"k1": "v", "k4": {"k_nested2": "v2"}}, - id="recursively remove any field that matches property condition and leave that does not", - ), - pytest.param( - {"k1": "v", "k2": "some_long_string", "k3": "some_long_string", "k4": {"k_nested": "v1", "k_nested2": "v2"}}, - [["**"]], - "{{ property|length > 5 }}", - {"k1": "v", "k4": {"k_nested": "v1", "k_nested2": "v2"}}, - id="remove any field that have length > 5 and leave that does not", - ), - pytest.param( - {"k1": 255, "k2": "some_string", "k3": "some_long_string", "k4": {"k_nested": 123123, "k_nested2": "v2"}}, - [["**"]], - "{{ property is integer }}", - {"k2": "some_string", "k3": "some_long_string", "k4": {"k_nested2": "v2"}}, - id="recursively remove any field that of type integer and leave that does not", - ), - ], -) -def test_remove_fields(input_record: Mapping[str, Any], field_pointers: List[FieldPointer], condition: str, expected: Mapping[str, Any]): - transformation = RemoveFields(field_pointers=field_pointers, condition=condition, parameters={}) - transformation.transform(input_record) - assert input_record == expected diff --git a/airbyte-cdk/python/unit_tests/sources/embedded/test_embedded_integration.py b/airbyte-cdk/python/unit_tests/sources/embedded/test_embedded_integration.py deleted file mode 100644 index 7560dc403ecd..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/embedded/test_embedded_integration.py +++ /dev/null @@ -1,162 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import unittest -from typing import Any, Mapping, Optional -from unittest.mock import MagicMock - -from airbyte_cdk.models import ( - AirbyteCatalog, - AirbyteLogMessage, - AirbyteMessage, - AirbyteRecordMessage, - AirbyteStateMessage, - AirbyteStream, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteStream, - ConnectorSpecification, - DestinationSyncMode, - Level, - SyncMode, - Type, -) -from airbyte_cdk.sources.embedded.base_integration import BaseEmbeddedIntegration -from airbyte_cdk.utils import AirbyteTracedException - - -class TestIntegration(BaseEmbeddedIntegration): - def _handle_record(self, record: AirbyteRecordMessage, id: Optional[str]) -> Mapping[str, Any]: - return {"data": record.data, "id": id} - - -class EmbeddedIntegrationTestCase(unittest.TestCase): - def setUp(self): - self.source_class = MagicMock() - self.source = MagicMock() - self.source_class.return_value = self.source - self.source.spec.return_value = ConnectorSpecification( - connectionSpecification={ - "properties": { - "test": { - "type": "string", - } - } - } - ) - self.config = {"test": "abc"} - self.integration = TestIntegration(self.source, self.config) - self.stream1 = AirbyteStream( - name="test", - source_defined_primary_key=[["test"]], - json_schema={}, - supported_sync_modes=[SyncMode.full_refresh, SyncMode.incremental], - ) - self.stream2 = AirbyteStream(name="test2", json_schema={}, supported_sync_modes=[SyncMode.full_refresh]) - self.source.discover.return_value = AirbyteCatalog(streams=[self.stream2, self.stream1]) - - def test_integration(self): - self.source.read.return_value = [ - AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=Level.INFO, message="test")), - AirbyteMessage(type=Type.RECORD, record=AirbyteRecordMessage(stream="test", data={"test": 1}, emitted_at=1)), - AirbyteMessage(type=Type.RECORD, record=AirbyteRecordMessage(stream="test", data={"test": 2}, emitted_at=2)), - AirbyteMessage(type=Type.RECORD, record=AirbyteRecordMessage(stream="test", data={"test": 3}, emitted_at=3)), - ] - result = list(self.integration._load_data("test", None)) - self.assertEqual( - result, - [ - {"data": {"test": 1}, "id": "1"}, - {"data": {"test": 2}, "id": "2"}, - {"data": {"test": 3}, "id": "3"}, - ], - ) - self.source.discover.assert_called_once_with(self.config) - self.source.read.assert_called_once_with( - self.config, - ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=self.stream1, - sync_mode=SyncMode.incremental, - destination_sync_mode=DestinationSyncMode.append, - primary_key=[["test"]], - ) - ] - ), - None, - ) - - def test_failed_check(self): - self.config = {"test": 123} - with self.assertRaises(AirbyteTracedException) as error: - TestIntegration(self.source, self.config) - assert str(error.exception) == "123 is not of type 'string'" - - def test_state(self): - state = AirbyteStateMessage(data={}) - self.source.read.return_value = [ - AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=Level.INFO, message="test")), - AirbyteMessage(type=Type.RECORD, record=AirbyteRecordMessage(stream="test", data={"test": 1}, emitted_at=1)), - AirbyteMessage(type=Type.STATE, state=state), - ] - result = list(self.integration._load_data("test", None)) - self.assertEqual( - result, - [ - {"data": {"test": 1}, "id": "1"}, - ], - ) - self.integration.last_state = state - - def test_incremental(self): - state = AirbyteStateMessage(data={}) - list(self.integration._load_data("test", state)) - self.source.read.assert_called_once_with( - self.config, - ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=self.stream1, - sync_mode=SyncMode.incremental, - destination_sync_mode=DestinationSyncMode.append, - primary_key=[["test"]], - ) - ] - ), - state, - ) - - def test_incremental_without_state(self): - list(self.integration._load_data("test")) - self.source.read.assert_called_once_with( - self.config, - ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=self.stream1, - sync_mode=SyncMode.incremental, - destination_sync_mode=DestinationSyncMode.append, - primary_key=[["test"]], - ) - ] - ), - None, - ) - - def test_incremental_unsupported(self): - state = AirbyteStateMessage(data={}) - list(self.integration._load_data("test2", state)) - self.source.read.assert_called_once_with( - self.config, - ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=self.stream2, - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.append, - ) - ] - ), - state, - ) diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/__init__.py b/airbyte-cdk/python/unit_tests/sources/file_based/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/availability_strategy/__init__.py b/airbyte-cdk/python/unit_tests/sources/file_based/availability_strategy/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/availability_strategy/test_default_file_based_availability_strategy.py b/airbyte-cdk/python/unit_tests/sources/file_based/availability_strategy/test_default_file_based_availability_strategy.py deleted file mode 100644 index 7206d234939d..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/availability_strategy/test_default_file_based_availability_strategy.py +++ /dev/null @@ -1,100 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import unittest -from datetime import datetime -from unittest.mock import Mock, PropertyMock - -from airbyte_cdk.sources.file_based.availability_strategy.default_file_based_availability_strategy import ( - DefaultFileBasedAvailabilityStrategy, -) -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig -from airbyte_cdk.sources.file_based.config.jsonl_format import JsonlFormat -from airbyte_cdk.sources.file_based.exceptions import CustomFileBasedException -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.stream import AbstractFileBasedStream - -_FILE_WITH_UNKNOWN_EXTENSION = RemoteFile(uri="a.unknown_extension", last_modified=datetime.now(), file_type="csv") -_ANY_CONFIG = FileBasedStreamConfig( - name="config.name", - file_type="parquet", - format=JsonlFormat(), -) -_ANY_SCHEMA = {"key": "value"} - - -class DefaultFileBasedAvailabilityStrategyTest(unittest.TestCase): - def setUp(self) -> None: - self._stream_reader = Mock(spec=AbstractFileBasedStreamReader) - self._strategy = DefaultFileBasedAvailabilityStrategy(self._stream_reader) - - self._parser = Mock(spec=FileTypeParser) - self._parser.check_config.return_value = (True, None) - self._stream = Mock(spec=AbstractFileBasedStream) - self._stream.get_parser.return_value = self._parser - self._stream.catalog_schema = _ANY_SCHEMA - self._stream.config = _ANY_CONFIG - self._stream.validation_policy = PropertyMock(validate_schema_before_sync=False) - self._stream.stream_reader = self._stream_reader - - def test_given_file_extension_does_not_match_when_check_availability_and_parsability_then_stream_is_still_available(self) -> None: - """ - Before, we had a validation on the file extension but it turns out that in production, users sometimes have mismatch there. The - example we've seen was for JSONL parser but the file extension was just `.json`. Note that there we more than one record extracted - from this stream so it's not just that the file is one JSON object - """ - self._stream.get_files.return_value = [_FILE_WITH_UNKNOWN_EXTENSION] - self._parser.parse_records.return_value = [{"a record": 1}] - - is_available, reason = self._strategy.check_availability_and_parsability(self._stream, Mock(), Mock()) - - assert is_available - - def test_not_available_given_no_files(self) -> None: - """ - If no files are returned, then the stream is not available. - """ - self._stream.get_files.return_value = [] - - is_available, reason = self._strategy.check_availability_and_parsability(self._stream, Mock(), Mock()) - - assert not is_available - assert "No files were identified in the stream" in reason - - def test_parse_records_is_not_called_with_parser_max_n_files_for_parsability_set(self) -> None: - """ - If the stream parser sets parser_max_n_files_for_parsability to 0, then we should not call parse_records on it - """ - self._parser.parser_max_n_files_for_parsability = 0 - self._stream.get_files.return_value = [_FILE_WITH_UNKNOWN_EXTENSION] - - is_available, reason = self._strategy.check_availability_and_parsability(self._stream, Mock(), Mock()) - - assert is_available - assert not self._parser.parse_records.called - assert self._stream_reader.open_file.called - - def test_passing_config_check(self) -> None: - """ - Test if the DefaultFileBasedAvailabilityStrategy correctly handles the check_config method defined on the parser. - """ - self._parser.check_config.return_value = (False, "Ran into error") - is_available, error_message = self._strategy.check_availability_and_parsability(self._stream, Mock(), Mock()) - assert not is_available - assert "Ran into error" in error_message - - def test_catching_and_raising_custom_file_based_exception(self) -> None: - """ - Test if the DefaultFileBasedAvailabilityStrategy correctly handles the CustomFileBasedException - by raising a CheckAvailabilityError when the get_files method is called. - """ - # Mock the get_files method to raise CustomFileBasedException when called - self._stream.get_files.side_effect = CustomFileBasedException("Custom exception for testing.") - - # Invoke the check_availability_and_parsability method and check if it correctly handles the exception - is_available, error_message = self._strategy.check_availability_and_parsability(self._stream, Mock(), Mock()) - assert not is_available - assert "Custom exception for testing." in error_message diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/config/__init__.py b/airbyte-cdk/python/unit_tests/sources/file_based/config/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/config/test_abstract_file_based_spec.py b/airbyte-cdk/python/unit_tests/sources/file_based/config/test_abstract_file_based_spec.py deleted file mode 100644 index 3c3d72c23300..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/config/test_abstract_file_based_spec.py +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Type - -import pytest -from airbyte_cdk.sources.file_based.config.file_based_stream_config import AvroFormat, CsvFormat, ParquetFormat -from jsonschema import ValidationError, validate -from pydantic.v1 import BaseModel - - -@pytest.mark.parametrize( - "file_format, file_type, expected_error", - [ - pytest.param(ParquetFormat, "parquet", None, id="test_parquet_format_is_a_valid_parquet_file_type"), - pytest.param(AvroFormat, "avro", None, id="test_avro_format_is_a_valid_avro_file_type"), - pytest.param(CsvFormat, "parquet", ValidationError, id="test_csv_format_is_not_a_valid_parquet_file_type"), - ], -) -def test_parquet_file_type_is_not_a_valid_csv_file_type(file_format: BaseModel, file_type: str, expected_error: Type[Exception]) -> None: - format_config = {file_type: {"filetype": file_type, "decimal_as_float": True}} - - if expected_error: - with pytest.raises(expected_error): - validate(instance=format_config[file_type], schema=file_format.schema()) - else: - validate(instance=format_config[file_type], schema=file_format.schema()) diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/config/test_csv_format.py b/airbyte-cdk/python/unit_tests/sources/file_based/config/test_csv_format.py deleted file mode 100644 index c233bd7ac9e9..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/config/test_csv_format.py +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import unittest - -import pytest -from airbyte_cdk.sources.file_based.config.csv_format import CsvFormat, CsvHeaderAutogenerated, CsvHeaderFromCsv, CsvHeaderUserProvided -from pydantic.v1.error_wrappers import ValidationError - - -class CsvHeaderDefinitionTest(unittest.TestCase): - def test_given_user_provided_and_not_column_names_provided_then_raise_exception(self) -> None: - with pytest.raises(ValidationError): - CsvHeaderUserProvided(column_names=[]) - - def test_given_user_provided_and_column_names_then_config_is_valid(self) -> None: - # no error means that this test succeeds - CsvHeaderUserProvided(column_names=["1", "2", "3"]) - - def test_given_user_provided_then_csv_does_not_have_header_row(self) -> None: - assert not CsvHeaderUserProvided(column_names=["1", "2", "3"]).has_header_row() - - def test_given_autogenerated_then_csv_does_not_have_header_row(self) -> None: - assert not CsvHeaderAutogenerated().has_header_row() - - def test_given_from_csv_then_csv_has_header_row(self) -> None: - assert CsvHeaderFromCsv().has_header_row() - - -class CsvDelimiterTest(unittest.TestCase): - def test_tab_delimter(self): - assert CsvFormat(delimiter=r"\t").delimiter == "\t" - assert len(CsvFormat(delimiter=r"\t").delimiter) == 1 diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/config/test_file_based_stream_config.py b/airbyte-cdk/python/unit_tests/sources/file_based/config/test_file_based_stream_config.py deleted file mode 100644 index 4c5d69a7dab5..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/config/test_file_based_stream_config.py +++ /dev/null @@ -1,84 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Mapping, Type - -import pytest as pytest -from airbyte_cdk.sources.file_based.config.file_based_stream_config import CsvFormat, FileBasedStreamConfig -from pydantic.v1.error_wrappers import ValidationError - - -@pytest.mark.parametrize( - "file_type, input_format, expected_format, expected_error", - [ - pytest.param( - "csv", - {"filetype": "csv", "delimiter": "d", "quote_char": "q", "escape_char": "e", "encoding": "ascii", "double_quote": True}, - {"filetype": "csv", "delimiter": "d", "quote_char": "q", "escape_char": "e", "encoding": "ascii", "double_quote": True}, - None, - id="test_valid_format", - ), - pytest.param( - "csv", - {"filetype": "csv", "double_quote": False}, - {"delimiter": ",", "quote_char": '"', "encoding": "utf8", "double_quote": False}, - None, - id="test_default_format_values", - ), - pytest.param( - "csv", {"filetype": "csv", "delimiter": "nope", "double_quote": True}, None, ValidationError, id="test_invalid_delimiter" - ), - pytest.param( - "csv", {"filetype": "csv", "quote_char": "nope", "double_quote": True}, None, ValidationError, id="test_invalid_quote_char" - ), - pytest.param( - "csv", {"filetype": "csv", "escape_char": "nope", "double_quote": True}, None, ValidationError, id="test_invalid_escape_char" - ), - pytest.param( - "csv", - {"filetype": "csv", "delimiter": ",", "quote_char": '"', "encoding": "not_a_format", "double_quote": True}, - {}, - ValidationError, - id="test_invalid_encoding_type", - ), - pytest.param( - "invalid", {"filetype": "invalid", "double_quote": False}, {}, ValidationError, id="test_config_format_file_type_mismatch" - ), - ], -) -def test_csv_config( - file_type: str, input_format: Mapping[str, Any], expected_format: Mapping[str, Any], expected_error: Type[Exception] -) -> None: - stream_config = {"name": "stream1", "file_type": file_type, "globs": ["*"], "validation_policy": "Emit Record", "format": input_format} - - if expected_error: - with pytest.raises(expected_error): - FileBasedStreamConfig(**stream_config) - else: - actual_config = FileBasedStreamConfig(**stream_config) - if actual_config.format is not None: - for expected_format_field, expected_format_value in expected_format.items(): - assert isinstance(actual_config.format, CsvFormat) - assert getattr(actual_config.format, expected_format_field) == expected_format_value - else: - assert False, "Expected format to be set" - - -def test_invalid_validation_policy() -> None: - stream_config = { - "name": "stream1", - "file_type": "csv", - "globs": ["*"], - "validation_policy": "Not Valid Policy", - "format": { - "filetype": "csv", - "delimiter": "d", - "quote_char": "q", - "escape_char": "e", - "encoding": "ascii", - "double_quote": True, - }, - } - with pytest.raises(ValidationError): - FileBasedStreamConfig(**stream_config) diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/discovery_policy/__init__.py b/airbyte-cdk/python/unit_tests/sources/file_based/discovery_policy/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/discovery_policy/test_default_discovery_policy.py b/airbyte-cdk/python/unit_tests/sources/file_based/discovery_policy/test_default_discovery_policy.py deleted file mode 100644 index b7ad67115cff..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/discovery_policy/test_default_discovery_policy.py +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import unittest -from unittest.mock import Mock - -from airbyte_cdk.sources.file_based.discovery_policy.default_discovery_policy import DefaultDiscoveryPolicy -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser - - -class DefaultDiscoveryPolicyTest(unittest.TestCase): - def setUp(self) -> None: - self._policy = DefaultDiscoveryPolicy() - - self._parser = Mock(spec=FileTypeParser) - self._parser.parser_max_n_files_for_schema_inference = None - - def test_hardcoded_schema_inference_file_limit_is_returned(self) -> None: - """ - If the parser is not providing a limit, then we should use the hardcoded limit - """ - assert self._policy.get_max_n_files_for_schema_inference(self._parser) == 10 - - def test_parser_limit_is_respected(self) -> None: - """ - If the parser is providing a limit, then we should use that limit - """ - self._parser.parser_max_n_files_for_schema_inference = 1 - - assert self._policy.get_max_n_files_for_schema_inference(self._parser) == 1 diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/file_types/__init__.py b/airbyte-cdk/python/unit_tests/sources/file_based/file_types/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_avro_parser.py b/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_avro_parser.py deleted file mode 100644 index a45d424b7a2b..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_avro_parser.py +++ /dev/null @@ -1,250 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import datetime -import uuid - -import pytest -from airbyte_cdk.sources.file_based.config.avro_format import AvroFormat -from airbyte_cdk.sources.file_based.file_types import AvroParser - -_default_avro_format = AvroFormat() -_double_as_string_avro_format = AvroFormat(double_as_string=True) -_uuid_value = uuid.uuid4() - - -@pytest.mark.parametrize( - "avro_format, avro_type, expected_json_type, expected_error", - [ - # Primitive types - pytest.param(_default_avro_format, "null", {"type": "null"}, None, id="test_null"), - pytest.param(_default_avro_format, "boolean", {"type": "boolean"}, None, id="test_boolean"), - pytest.param(_default_avro_format, "int", {"type": "integer"}, None, id="test_int"), - pytest.param(_default_avro_format, "long", {"type": "integer"}, None, id="test_long"), - pytest.param(_default_avro_format, "float", {"type": "number"}, None, id="test_float"), - pytest.param(_default_avro_format, "double", {"type": "number"}, None, id="test_double"), - pytest.param(_double_as_string_avro_format, "double", {"type": "string"}, None, id="test_double_as_string"), - pytest.param(_default_avro_format, "bytes", {"type": "string"}, None, id="test_bytes"), - pytest.param(_default_avro_format, "string", {"type": "string"}, None, id="test_string"), - pytest.param(_default_avro_format, "void", None, ValueError, id="test_invalid_type"), - # Complex types - pytest.param( - _default_avro_format, - { - "type": "record", - "name": "SubRecord", - "fields": [{"name": "precise", "type": "double"}, {"name": "robo", "type": "bytes"}, {"name": "simple", "type": "long"}], - }, - { - "type": "object", - "properties": { - "precise": {"type": "number"}, - "robo": {"type": "string"}, - "simple": {"type": "integer"}, - }, - }, - None, - id="test_record", - ), - pytest.param( - _default_avro_format, - { - "type": "record", - "name": "SubRecord", - "fields": [{"name": "precise", "type": "double"}, {"name": "obj_array", "type": {"type": "array", "items": "float"}}], - }, - {"type": "object", "properties": {"precise": {"type": "number"}, "obj_array": {"type": "array", "items": {"type": "number"}}}}, - None, - id="test_record_with_nested_array", - ), - pytest.param( - _default_avro_format, - { - "type": "record", - "name": "SubRecord", - "fields": [ - { - "name": "nested_record", - "type": {"type": "record", "name": "SubRecord", "fields": [{"name": "question", "type": "boolean"}]}, - } - ], - }, - { - "type": "object", - "properties": { - "nested_record": { - "type": "object", - "properties": {"question": {"type": "boolean"}}, - } - }, - }, - None, - id="test_record_with_nested_record", - ), - pytest.param( - _default_avro_format, {"type": "array", "items": "float"}, {"type": "array", "items": {"type": "number"}}, None, id="test_array" - ), - pytest.param( - _default_avro_format, - {"type": "array", "items": {"type": "record", "name": "SubRecord", "fields": [{"name": "precise", "type": "double"}]}}, - { - "type": "array", - "items": { - "type": "object", - "properties": { - "precise": {"type": "number"}, - }, - }, - }, - None, - id="test_array_of_records", - ), - pytest.param(_default_avro_format, {"type": "array", "not_items": "string"}, None, ValueError, id="test_array_missing_items"), - pytest.param( - _default_avro_format, {"type": "array", "items": "invalid_avro_type"}, None, ValueError, id="test_array_invalid_item_type" - ), - pytest.param( - _default_avro_format, - {"type": "enum", "name": "IMF", "symbols": ["Ethan", "Benji", "Luther"]}, - {"type": "string", "enum": ["Ethan", "Benji", "Luther"]}, - None, - id="test_enum", - ), - pytest.param(_default_avro_format, {"type": "enum", "name": "IMF"}, None, ValueError, id="test_enum_missing_symbols"), - pytest.param( - _default_avro_format, {"type": "enum", "symbols": ["mission", "not", "accepted"]}, None, ValueError, id="test_enum_missing_name" - ), - pytest.param( - _default_avro_format, - {"type": "map", "values": "int"}, - {"type": "object", "additionalProperties": {"type": "integer"}}, - None, - id="test_map", - ), - pytest.param( - _default_avro_format, - {"type": "map", "values": {"type": "record", "name": "SubRecord", "fields": [{"name": "agent", "type": "string"}]}}, - {"type": "object", "additionalProperties": {"type": "object", "properties": {"agent": {"type": "string"}}}}, - None, - id="test_map_object", - ), - pytest.param(_default_avro_format, {"type": "map"}, None, ValueError, id="test_map_missing_values"), - pytest.param( - _default_avro_format, - {"type": "fixed", "name": "limit", "size": 12}, - {"type": "string", "pattern": "^[0-9A-Fa-f]{24}$"}, - None, - id="test_fixed", - ), - pytest.param(_default_avro_format, {"type": "fixed", "name": "limit"}, None, ValueError, id="test_fixed_missing_size"), - pytest.param( - _default_avro_format, {"type": "fixed", "name": "limit", "size": "50"}, None, ValueError, id="test_fixed_size_not_integer" - ), - # Logical types - pytest.param( - _default_avro_format, - {"type": "bytes", "logicalType": "decimal", "precision": 9, "scale": 4}, - {"type": "string", "pattern": f"^-?\\d{{{1, 5}}}(?:\\.\\d{1, 4})?$"}, - None, - id="test_decimal", - ), - pytest.param( - _default_avro_format, - {"type": "bytes", "logicalType": "decimal", "scale": 4}, - None, - ValueError, - id="test_decimal_missing_precision", - ), - pytest.param( - _default_avro_format, - {"type": "bytes", "logicalType": "decimal", "precision": 9}, - None, - ValueError, - id="test_decimal_missing_scale", - ), - pytest.param(_default_avro_format, {"type": "bytes", "logicalType": "uuid"}, {"type": "string"}, None, id="test_uuid"), - pytest.param( - _default_avro_format, {"type": "int", "logicalType": "date"}, {"type": "string", "format": "date"}, None, id="test_date" - ), - pytest.param(_default_avro_format, {"type": "int", "logicalType": "time-millis"}, {"type": "integer"}, None, id="test_time_millis"), - pytest.param( - _default_avro_format, {"type": "long", "logicalType": "time-micros"}, {"type": "integer"}, None, id="test_time_micros" - ), - pytest.param( - _default_avro_format, - {"type": "long", "logicalType": "timestamp-millis"}, - {"type": "string", "format": "date-time"}, - None, - id="test_timestamp_millis", - ), - pytest.param( - _default_avro_format, {"type": "long", "logicalType": "timestamp-micros"}, {"type": "string"}, None, id="test_timestamp_micros" - ), - pytest.param( - _default_avro_format, - {"type": "long", "logicalType": "local-timestamp-millis"}, - {"type": "string", "format": "date-time"}, - None, - id="test_local_timestamp_millis", - ), - pytest.param( - _default_avro_format, - {"type": "long", "logicalType": "local-timestamp-micros"}, - {"type": "string"}, - None, - id="test_local_timestamp_micros", - ), - pytest.param( - _default_avro_format, - {"type": "string", "logicalType": "invalid-logical-type"}, - None, - ValueError, - id="test_invalid_logical_type", - ), - ], -) -def test_convert_primitive_avro_type_to_json(avro_format, avro_type, expected_json_type, expected_error): - if expected_error: - with pytest.raises(expected_error): - AvroParser._convert_avro_type_to_json(avro_format, "field_name", avro_type) - else: - actual_json_type = AvroParser._convert_avro_type_to_json(avro_format, "field_name", avro_type) - assert actual_json_type == expected_json_type - - -@pytest.mark.parametrize( - "avro_format, record_type, record_value, expected_value", - [ - pytest.param(_default_avro_format, "boolean", True, True, id="test_boolean"), - pytest.param(_default_avro_format, "int", 123, 123, id="test_int"), - pytest.param(_default_avro_format, "long", 123, 123, id="test_long"), - pytest.param(_default_avro_format, "float", 123.456, 123.456, id="test_float"), - pytest.param(_default_avro_format, "double", 123.456, 123.456, id="test_double_default_config"), - pytest.param(_double_as_string_avro_format, "double", 123.456, "123.456", id="test_double_as_string"), - pytest.param(_default_avro_format, "bytes", b"hello world", "hello world", id="test_bytes"), - pytest.param(_default_avro_format, "string", "hello world", "hello world", id="test_string"), - pytest.param(_default_avro_format, {"logicalType": "decimal"}, 3.1415, "3.1415", id="test_decimal"), - pytest.param(_default_avro_format, {"logicalType": "uuid"}, _uuid_value, str(_uuid_value), id="test_uuid"), - pytest.param(_default_avro_format, {"logicalType": "date"}, datetime.date(2023, 8, 7), "2023-08-07", id="test_date"), - pytest.param(_default_avro_format, {"logicalType": "time-millis"}, 70267068, 70267068, id="test_time_millis"), - pytest.param(_default_avro_format, {"logicalType": "time-micros"}, 70267068, 70267068, id="test_time_micros"), - pytest.param( - _default_avro_format, - {"logicalType": "local-timestamp-millis"}, - datetime.datetime(2023, 8, 7, 19, 31, 7, 68000, tzinfo=datetime.timezone.utc), - "2023-08-07T19:31:07.068+00:00", - id="test_timestamp_millis", - ), - pytest.param( - _default_avro_format, - {"logicalType": "local-timestamp-micros"}, - datetime.datetime(2023, 8, 7, 19, 31, 7, 68000, tzinfo=datetime.timezone.utc), - "2023-08-07T19:31:07.068000+00:00", - id="test_timestamo_micros", - ), - ], -) -def test_to_output_value(avro_format, record_type, record_value, expected_value): - parser = AvroParser() - assert parser._to_output_value(avro_format, record_type, record_value) == expected_value diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_csv_parser.py b/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_csv_parser.py deleted file mode 100644 index 9280ffb60e69..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_csv_parser.py +++ /dev/null @@ -1,645 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import asyncio -import csv -import io -import logging -import unittest -from datetime import datetime -from typing import Any, Dict, Generator, List, Set -from unittest import TestCase, mock -from unittest.mock import Mock - -import pytest -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.file_based.config.csv_format import ( - DEFAULT_FALSE_VALUES, - DEFAULT_TRUE_VALUES, - CsvFormat, - CsvHeaderAutogenerated, - CsvHeaderUserProvided, - InferenceType, -) -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig -from airbyte_cdk.sources.file_based.exceptions import RecordParseError -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode -from airbyte_cdk.sources.file_based.file_types.csv_parser import CsvParser, _CsvReader -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.utils.traced_exception import AirbyteTracedException - -PROPERTY_TYPES = { - "col1": "null", - "col2": "boolean", - "col3": "integer", - "col4": "number", - "col5": "string", - "col6": "object", - "col7": "array", - "col8": "array", - "col9": "array", - "col10": "string", -} - -logger = logging.getLogger() - - -@pytest.mark.parametrize( - "row, true_values, false_values, expected_output", - [ - pytest.param( - { - "col1": "", - "col2": "true", - "col3": "1", - "col4": "1.1", - "col5": "asdf", - "col6": '{"a": "b"}', - "col7": "[1, 2]", - "col8": '["1", "2"]', - "col9": '[{"a": "b"}, {"a": "c"}]', - "col10": "asdf", - }, - DEFAULT_TRUE_VALUES, - DEFAULT_FALSE_VALUES, - { - "col1": None, - "col2": True, - "col3": 1, - "col4": 1.1, - "col5": "asdf", - "col6": {"a": "b"}, - "col7": [1, 2], - "col8": ["1", "2"], - "col9": [{"a": "b"}, {"a": "c"}], - "col10": "asdf", - }, - id="cast-all-cols", - ), - pytest.param({"col1": "1"}, DEFAULT_TRUE_VALUES, DEFAULT_FALSE_VALUES, {"col1": "1"}, id="cannot-cast-to-null"), - pytest.param({"col2": "1"}, DEFAULT_TRUE_VALUES, DEFAULT_FALSE_VALUES, {"col2": True}, id="cast-1-to-bool"), - pytest.param({"col2": "0"}, DEFAULT_TRUE_VALUES, DEFAULT_FALSE_VALUES, {"col2": False}, id="cast-0-to-bool"), - pytest.param({"col2": "yes"}, DEFAULT_TRUE_VALUES, DEFAULT_FALSE_VALUES, {"col2": True}, id="cast-yes-to-bool"), - pytest.param( - {"col2": "this_is_a_true_value"}, - ["this_is_a_true_value"], - DEFAULT_FALSE_VALUES, - {"col2": True}, - id="cast-custom-true-value-to-bool", - ), - pytest.param( - {"col2": "this_is_a_false_value"}, - DEFAULT_TRUE_VALUES, - ["this_is_a_false_value"], - {"col2": False}, - id="cast-custom-false-value-to-bool", - ), - pytest.param({"col2": "no"}, DEFAULT_TRUE_VALUES, DEFAULT_FALSE_VALUES, {"col2": False}, id="cast-no-to-bool"), - pytest.param({"col2": "10"}, DEFAULT_TRUE_VALUES, DEFAULT_FALSE_VALUES, {"col2": "10"}, id="cannot-cast-to-bool"), - pytest.param({"col3": "1.1"}, DEFAULT_TRUE_VALUES, DEFAULT_FALSE_VALUES, {"col3": "1.1"}, id="cannot-cast-to-int"), - pytest.param({"col4": "asdf"}, DEFAULT_TRUE_VALUES, DEFAULT_FALSE_VALUES, {"col4": "asdf"}, id="cannot-cast-to-float"), - pytest.param({"col6": "{'a': 'b'}"}, DEFAULT_TRUE_VALUES, DEFAULT_FALSE_VALUES, {"col6": "{'a': 'b'}"}, id="cannot-cast-to-dict"), - pytest.param( - {"col7": "['a', 'b']"}, DEFAULT_TRUE_VALUES, DEFAULT_FALSE_VALUES, {"col7": "['a', 'b']"}, id="cannot-cast-to-list-of-ints" - ), - pytest.param( - {"col8": "['a', 'b']"}, DEFAULT_TRUE_VALUES, DEFAULT_FALSE_VALUES, {"col8": "['a', 'b']"}, id="cannot-cast-to-list-of-strings" - ), - pytest.param( - {"col9": "['a', 'b']"}, DEFAULT_TRUE_VALUES, DEFAULT_FALSE_VALUES, {"col9": "['a', 'b']"}, id="cannot-cast-to-list-of-objects" - ), - pytest.param({"col11": "x"}, DEFAULT_TRUE_VALUES, DEFAULT_FALSE_VALUES, {}, id="item-not-in-props-doesn't-error"), - ], -) -def test_cast_to_python_type(row: Dict[str, str], true_values: Set[str], false_values: Set[str], expected_output: Dict[str, Any]) -> None: - csv_format = CsvFormat(true_values=true_values, false_values=false_values) - assert CsvParser._cast_types(row, PROPERTY_TYPES, csv_format, logger) == expected_output - - -@pytest.mark.parametrize( - "row, strings_can_be_null, expected_output", - [ - pytest.param( - {"id": "1", "name": "bob", "age": 10, "is_cool": False}, - False, - {"id": "1", "name": "bob", "age": 10, "is_cool": False}, - id="test-no-values-are-null", - ), - pytest.param( - {"id": "1", "name": "bob", "age": "null", "is_cool": "null"}, - False, - {"id": "1", "name": "bob", "age": None, "is_cool": None}, - id="test-non-string-values-are-none-if-in-null-values", - ), - pytest.param( - {"id": "1", "name": "null", "age": 10, "is_cool": False}, - False, - {"id": "1", "name": "null", "age": 10, "is_cool": False}, - id="test-string-values-are-not-none-if-strings-cannot-be-null", - ), - pytest.param( - {"id": "1", "name": "null", "age": 10, "is_cool": False}, - True, - {"id": "1", "name": None, "age": 10, "is_cool": False}, - id="test-string-values-none-if-strings-can-be-null", - ), - ], -) -def test_to_nullable(row, strings_can_be_null, expected_output): - property_types = {"id": "string", "name": "string", "age": "integer", "is_cool": "boolean"} - null_values = {"null"} - nulled_row = CsvParser._to_nullable(row, property_types, null_values, strings_can_be_null) - assert nulled_row == expected_output - - -_DEFAULT_TRUE_VALUES = {"1", "yes", "yeah", "right"} -_DEFAULT_FALSE_VALUES = {"0", "no", "nop", "wrong"} - - -class SchemaInferenceTestCase(TestCase): - _A_NULL_VALUE = "null" - _HEADER_NAME = "header" - - def setUp(self) -> None: - self._config_format = CsvFormat() - self._config_format.true_values = _DEFAULT_TRUE_VALUES - self._config_format.false_values = _DEFAULT_FALSE_VALUES - self._config_format.null_values = {self._A_NULL_VALUE} - self._config_format.inference_type = InferenceType.NONE - self._config = Mock() - self._config.get_input_schema.return_value = None - self._config.format = self._config_format - - self._file = RemoteFile(uri="a uri", last_modified=datetime.now()) - self._stream_reader = Mock(spec=AbstractFileBasedStreamReader) - self._logger = Mock(spec=logging.Logger) - self._csv_reader = Mock(spec=_CsvReader) - self._parser = CsvParser(self._csv_reader) - - def test_given_user_schema_defined_when_infer_schema_then_return_user_schema(self) -> None: - self._config.get_input_schema.return_value = {self._HEADER_NAME: {"type": "potato"}} - self._test_infer_schema(list(_DEFAULT_TRUE_VALUES.union(_DEFAULT_FALSE_VALUES)), "potato") - - def test_given_booleans_only_when_infer_schema_then_type_is_boolean(self) -> None: - self._config_format.inference_type = InferenceType.PRIMITIVE_TYPES_ONLY - self._test_infer_schema(list(_DEFAULT_TRUE_VALUES.union(_DEFAULT_FALSE_VALUES)), "boolean") - - def test_given_integers_only_when_infer_schema_then_type_is_integer(self) -> None: - self._config_format.inference_type = InferenceType.PRIMITIVE_TYPES_ONLY - self._test_infer_schema(["2", "90329", "5645"], "integer") - - def test_given_integer_overlap_with_bool_value_only_when_infer_schema_then_type_is_integer(self) -> None: - self._config_format.inference_type = InferenceType.PRIMITIVE_TYPES_ONLY - self._test_infer_schema(["1", "90329", "5645"], "integer") # here, "1" is also considered a boolean - - def test_given_numbers_and_integers_when_infer_schema_then_type_is_number(self) -> None: - self._config_format.inference_type = InferenceType.PRIMITIVE_TYPES_ONLY - self._test_infer_schema(["2", "90329", "2.312"], "number") - - def test_given_arrays_when_infer_schema_then_type_is_string(self) -> None: - self._config_format.inference_type = InferenceType.PRIMITIVE_TYPES_ONLY - self._test_infer_schema(['["first_item", "second_item"]', '["first_item_again", "second_item_again"]'], "string") - - def test_given_objects_when_infer_schema_then_type_is_object(self) -> None: - self._config_format.inference_type = InferenceType.PRIMITIVE_TYPES_ONLY - self._test_infer_schema(['{"object1_key": 1}', '{"object2_key": 2}'], "string") - - def test_given_strings_only_when_infer_schema_then_type_is_string(self) -> None: - self._config_format.inference_type = InferenceType.PRIMITIVE_TYPES_ONLY - self._test_infer_schema(["a string", "another string"], "string") - - def test_given_a_null_value_when_infer_then_ignore_null(self) -> None: - self._config_format.inference_type = InferenceType.PRIMITIVE_TYPES_ONLY - self._test_infer_schema(["2", "90329", "5645", self._A_NULL_VALUE], "integer") - - def test_given_only_null_values_when_infer_then_type_is_string(self) -> None: - self._config_format.inference_type = InferenceType.PRIMITIVE_TYPES_ONLY - self._test_infer_schema([self._A_NULL_VALUE, self._A_NULL_VALUE, self._A_NULL_VALUE], "string") - - def test_given_big_file_when_infer_schema_then_stop_early(self) -> None: - self._config_format.inference_type = InferenceType.PRIMITIVE_TYPES_ONLY - self._csv_reader.read_data.return_value = ({self._HEADER_NAME: row} for row in ["2." + "2" * 1_000_000] + ["this is a string"]) - inferred_schema = self._infer_schema() - # since the type is number, we know the string at the end was not considered - assert inferred_schema == {self._HEADER_NAME: {"type": "number"}} - - def test_given_empty_csv_file_when_infer_schema_then_raise_config_error(self) -> None: - self._csv_reader.read_data.return_value = [] - with pytest.raises(AirbyteTracedException) as exception: - self._infer_schema() - assert exception.value.failure_type == FailureType.config_error - - def _test_infer_schema(self, rows: List[str], expected_type: str) -> None: - self._csv_reader.read_data.return_value = ({self._HEADER_NAME: row} for row in rows) - inferred_schema = self._infer_schema() - assert inferred_schema == {self._HEADER_NAME: {"type": expected_type}} - - def _infer_schema(self): - loop = asyncio.new_event_loop() - task = loop.create_task(self._parser.infer_schema(self._config, self._file, self._stream_reader, self._logger)) - loop.run_until_complete(task) - return task.result() - - -class CsvFileBuilder: - def __init__(self) -> None: - self._prefixed_rows: List[str] = [] - self._data: List[str] = [] - - def with_prefixed_rows(self, rows: List[str]) -> "CsvFileBuilder": - self._prefixed_rows = rows - return self - - def with_data(self, data: List[str]) -> "CsvFileBuilder": - self._data = data - return self - - def build(self) -> io.StringIO: - return io.StringIO("\n".join(self._prefixed_rows + self._data)) - - -class CsvReaderTest(unittest.TestCase): - _CONFIG_NAME = "config_name" - - def setUp(self) -> None: - self._config_format = CsvFormat() - self._config = Mock() - self._config.name = self._CONFIG_NAME - self._config.format = self._config_format - - self._file = RemoteFile(uri="a uri", last_modified=datetime.now()) - self._stream_reader = Mock(spec=AbstractFileBasedStreamReader) - self._logger = Mock(spec=logging.Logger) - self._csv_reader = _CsvReader() - - def test_given_skip_rows_when_read_data_then_do_not_considered_prefixed_rows(self) -> None: - self._config_format.skip_rows_before_header = 2 - self._stream_reader.open_file.return_value = ( - CsvFileBuilder() - .with_prefixed_rows(["first line", "second line"]) - .with_data( - [ - "header", - "a value", - "another value", - ] - ) - .build() - ) - - data_generator = self._read_data() - - assert list(data_generator) == [{"header": "a value"}, {"header": "another value"}] - - def test_given_autogenerated_headers_when_read_data_then_generate_headers_with_format_fX(self) -> None: - self._config_format.header_definition = CsvHeaderAutogenerated() - self._stream_reader.open_file.return_value = CsvFileBuilder().with_data(["0,1,2,3,4,5,6"]).build() - - data_generator = self._read_data() - - assert list(data_generator) == [{"f0": "0", "f1": "1", "f2": "2", "f3": "3", "f4": "4", "f5": "5", "f6": "6"}] - - def test_given_skip_row_before_and_after_and_autogenerated_headers_when_read_data_then_generate_headers_with_format_fX(self) -> None: - self._config_format.header_definition = CsvHeaderAutogenerated() - self._config_format.skip_rows_before_header = 1 - self._config_format.skip_rows_after_header = 2 - self._stream_reader.open_file.return_value = ( - CsvFileBuilder().with_data(["skip before", "skip after 1", "skip after 2", "0,1,2,3,4,5,6"]).build() - ) - - data_generator = self._read_data() - - assert list(data_generator) == [{"f0": "0", "f1": "1", "f2": "2", "f3": "3", "f4": "4", "f5": "5", "f6": "6"}] - - def test_given_user_provided_headers_when_read_data_then_use_user_provided_headers(self) -> None: - self._config_format.header_definition = CsvHeaderUserProvided(column_names=["first", "second", "third", "fourth"]) - self._stream_reader.open_file.return_value = CsvFileBuilder().with_data(["0,1,2,3"]).build() - - data_generator = self._read_data() - - assert list(data_generator) == [{"first": "0", "second": "1", "third": "2", "fourth": "3"}] - - def test_given_len_mistmatch_on_user_provided_headers_when_read_data_then_raise_error(self) -> None: - self._config_format.header_definition = CsvHeaderUserProvided(column_names=["missing", "one", "column"]) - self._stream_reader.open_file.return_value = CsvFileBuilder().with_data(["0,1,2,3"]).build() - - with pytest.raises(RecordParseError): - list(self._read_data()) - - def test_given_skip_rows_after_header_when_read_data_then_do_not_parse_skipped_rows(self) -> None: - self._config_format.skip_rows_after_header = 1 - self._stream_reader.open_file.return_value = ( - CsvFileBuilder() - .with_data( - [ - "header1,header2", - "skipped row: important that the is no comma in this string to test if columns do not match in skipped rows", - "a value 1,a value 2", - "another value 1,another value 2", - ] - ) - .build() - ) - - data_generator = self._read_data() - - assert list(data_generator) == [ - {"header1": "a value 1", "header2": "a value 2"}, - {"header1": "another value 1", "header2": "another value 2"}, - ] - - def test_given_quote_delimiter_when_read_data_then_parse_properly(self) -> None: - self._config_format.delimiter = "|" - self._stream_reader.open_file.return_value = ( - CsvFileBuilder() - .with_data( - [ - "header1|header2", - "a value 1|a value 2", - ] - ) - .build() - ) - - data_generator = self._read_data() - - assert list(data_generator) == [{"header1": "a value 1", "header2": "a value 2"}] - - def test_given_quote_char_when_read_data_then_parse_properly(self) -> None: - self._config_format.quote_char = "|" - self._stream_reader.open_file.return_value = ( - CsvFileBuilder() - .with_data( - [ - "header1,header2", - "|a,value,1|,|a,value,2|", - ] - ) - .build() - ) - - data_generator = self._read_data() - - assert list(data_generator) == [{"header1": "a,value,1", "header2": "a,value,2"}] - - def test_given_escape_char_when_read_data_then_parse_properly(self) -> None: - self._config_format.escape_char = "|" - self._stream_reader.open_file.return_value = ( - CsvFileBuilder() - .with_data( - [ - "header1,header2", - '"a |"value|", 1",a value 2', - ] - ) - .build() - ) - - data_generator = self._read_data() - - assert list(data_generator) == [{"header1": 'a "value", 1', "header2": "a value 2"}] - - def test_given_double_quote_on_when_read_data_then_parse_properly(self) -> None: - self._config_format.double_quote = True - self._stream_reader.open_file.return_value = ( - CsvFileBuilder() - .with_data( - [ - "header1,header2", - '1,"Text with doublequote: ""This is a text."""', - ] - ) - .build() - ) - - data_generator = self._read_data() - - assert list(data_generator) == [{"header1": "1", "header2": 'Text with doublequote: "This is a text."'}] - - def test_given_double_quote_off_when_read_data_then_parse_properly(self) -> None: - self._config_format.double_quote = False - self._stream_reader.open_file.return_value = ( - CsvFileBuilder() - .with_data( - [ - "header1,header2", - '1,"Text with doublequote: ""This is a text."""', - ] - ) - .build() - ) - - data_generator = self._read_data() - - assert list(data_generator) == [{"header1": "1", "header2": 'Text with doublequote: "This is a text."""'}] - - def test_given_generator_closed_when_read_data_then_unregister_dialect(self) -> None: - self._stream_reader.open_file.return_value = ( - CsvFileBuilder() - .with_data( - [ - "header", - "a value", - "another value", - ] - ) - .build() - ) - - dialects_before = set(csv.list_dialects()) - data_generator = self._read_data() - next(data_generator) - [new_dialect] = set(csv.list_dialects()) - dialects_before - assert self._CONFIG_NAME in new_dialect - data_generator.close() - assert new_dialect not in csv.list_dialects() - - def test_given_too_many_values_for_columns_when_read_data_then_raise_exception_and_unregister_dialect(self) -> None: - self._stream_reader.open_file.return_value = ( - CsvFileBuilder() - .with_data( - [ - "header", - "a value", - "too many values,value,value,value", - ] - ) - .build() - ) - - dialects_before = set(csv.list_dialects()) - data_generator = self._read_data() - next(data_generator) - [new_dialect] = set(csv.list_dialects()) - dialects_before - assert self._CONFIG_NAME in new_dialect - - with pytest.raises(RecordParseError): - next(data_generator) - assert new_dialect not in csv.list_dialects() - - def test_given_too_few_values_for_columns_when_read_data_then_raise_exception_and_unregister_dialect(self) -> None: - self._stream_reader.open_file.return_value = ( - CsvFileBuilder() - .with_data( - [ - "header1,header2,header3", - "value1,value2,value3", - "a value", - ] - ) - .build() - ) - - dialects_before = set(csv.list_dialects()) - data_generator = self._read_data() - next(data_generator) - [new_dialect] = set(csv.list_dialects()) - dialects_before - assert self._CONFIG_NAME in new_dialect - - with pytest.raises(RecordParseError): - next(data_generator) - assert new_dialect not in csv.list_dialects() - - def test_parse_field_size_larger_than_default_python_maximum(self) -> None: - # The field size for the csv module will be set as a side-effect of initializing the CsvParser class. - assert csv.field_size_limit() == 2**31 - long_string = 130 * 1024 * "a" - assert len(long_string.encode("utf-8")) > (128 * 1024) - self._stream_reader.open_file.return_value = ( - CsvFileBuilder() - .with_data( - [ - "header1,header2", - f'1,"{long_string}"', - ] - ) - .build() - ) - - data_generator = self._read_data() - assert list(data_generator) == [{"header1": "1", "header2": long_string}] - - def test_read_data_with_encoding_error(self) -> None: - self._stream_reader.open_file.return_value = CsvFileBuilder().with_data(["something"]).build() - self._csv_reader._get_headers = Mock(side_effect=UnicodeDecodeError("encoding", b"", 0, 1, "reason")) - - with pytest.raises(AirbyteTracedException) as ate: - data_generator = self._read_data() - assert len(list(data_generator)) == 0 - - assert "encoding" in ate.value.message - assert self._csv_reader._get_headers.called - - def _read_data(self) -> Generator[Dict[str, str], None, None]: - data_generator = self._csv_reader.read_data( - self._config, - self._file, - self._stream_reader, - self._logger, - FileReadMode.READ, - ) - return data_generator - - -_TOO_MANY_VALUES = [ - "header", - "too many values,value,value,value", -] - -_TOO_FEW_VALUES = [ - "header1,header2,header3", - "a value", - "value1,value2,value3", -] - - -@pytest.mark.parametrize( - "ignore_errors_on_fields_mismatch, data, error_message", - [ - ( - True, - _TOO_MANY_VALUES, - "Skipping record in line 2 of file a uri; invalid CSV row with missing column.", - ), - ( - False, - _TOO_MANY_VALUES, - None, - ), - ( - True, - _TOO_FEW_VALUES, - "Skipping record in line 2 of file a uri; invalid CSV row with extra column.", - ), - ( - False, - _TOO_FEW_VALUES, - None, - ), - ], -) -def test_mismatch_between_values_and_header(ignore_errors_on_fields_mismatch, data, error_message) -> None: - config_format = CsvFormat() - config = Mock() - config.name = "config_name" - config.format = config_format - - file = RemoteFile(uri="a uri", last_modified=datetime.now()) - stream_reader = Mock(spec=AbstractFileBasedStreamReader) - logger = Mock(spec=logging.Logger) - csv_reader = _CsvReader() - - config_format.ignore_errors_on_fields_mismatch = ignore_errors_on_fields_mismatch - stream_reader.open_file.return_value = CsvFileBuilder().with_data(data).build() - - data_generator = csv_reader.read_data( - config, - file, - stream_reader, - logger, - FileReadMode.READ, - ) - - # Check if exception is raised only when skip_wrong_number_of_fields_error is False - if not ignore_errors_on_fields_mismatch: - with pytest.raises(RecordParseError): - print(list(data_generator)) - else: - # Expect no exception when skip_wrong_number_of_fields_error is True - list(data_generator) - logger.error.assert_called_with(error_message) - - -def test_encoding_is_passed_to_stream_reader() -> None: - parser = CsvParser() - encoding = "ascii" - stream_reader = Mock() - mock_obj = stream_reader.open_file.return_value - mock_obj.__enter__ = Mock(return_value=io.StringIO("c1,c2\nv1,v2")) - mock_obj.__exit__ = Mock(return_value=None) - file = RemoteFile(uri="s3://bucket/key.csv", last_modified=datetime.now()) - config = FileBasedStreamConfig(name="test", validation_policy="Emit Record", file_type="csv", format=CsvFormat(encoding=encoding)) - list(parser.parse_records(config, file, stream_reader, logger, {"properties": {"c1": {"type": "string"}, "c2": {"type": "string"}}})) - stream_reader.open_file.assert_has_calls( - [ - mock.call(file, FileReadMode.READ, encoding, logger), - mock.call().__enter__(), - mock.call().__exit__(None, None, None), - ] - ) - - mock_obj.__enter__ = Mock(return_value=io.StringIO("c1,c2\nv1,v2")) - loop = asyncio.get_event_loop() - loop.run_until_complete(parser.infer_schema(config, file, stream_reader, logger)) - stream_reader.open_file.assert_called_with(file, FileReadMode.READ, encoding, logger) - stream_reader.open_file.assert_has_calls( - [ - mock.call(file, FileReadMode.READ, encoding, logger), - mock.call().__enter__(), - mock.call().__exit__(None, None, None), - mock.call(file, FileReadMode.READ, encoding, logger), - mock.call().__enter__(), - mock.call().__exit__(None, None, None), - ] - ) diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_excel_parser.py b/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_excel_parser.py deleted file mode 100644 index bd9d8338f094..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_excel_parser.py +++ /dev/null @@ -1,122 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - - -import datetime -from io import BytesIO -from unittest.mock import MagicMock, Mock, mock_open, patch - -import pandas as pd -import pytest -from airbyte_cdk.sources.file_based.config.file_based_stream_config import ExcelFormat, FileBasedStreamConfig, ValidationPolicy -from airbyte_cdk.sources.file_based.exceptions import ConfigValidationError, RecordParseError -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader -from airbyte_cdk.sources.file_based.file_types.excel_parser import ExcelParser -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.schema_helpers import SchemaType - - -@pytest.fixture -def mock_stream_reader(): - return Mock(spec=AbstractFileBasedStreamReader) - - -@pytest.fixture -def mock_logger(): - return Mock() - - -@pytest.fixture -def file_config(): - return FileBasedStreamConfig( - name="test.xlsx", - file_type="excel", - format=ExcelFormat(sheet_name="Sheet1"), - validation_policy=ValidationPolicy.emit_record, - ) - - -@pytest.fixture -def remote_file(): - return RemoteFile(uri="s3://mybucket/test.xlsx", last_modified=datetime.datetime.now()) - - -@pytest.fixture -def setup_parser(remote_file): - parser = ExcelParser() - - # Sample data for the mock Excel file - data = pd.DataFrame( - { - "column1": [1, 2, 3], - "column2": ["a", "b", "c"], - "column3": [True, False, True], - "column4": pd.to_datetime(["2021-01-01", "2022-01-01", "2023-01-01"]), - } - ) - - # Convert the DataFrame to an Excel byte stream - excel_bytes = BytesIO() - with pd.ExcelWriter(excel_bytes, engine="xlsxwriter") as writer: - data.to_excel(writer, index=False) - excel_bytes.seek(0) - - # Mock the stream_reader's open_file method to return the Excel byte stream - stream_reader = MagicMock(spec=AbstractFileBasedStreamReader) - stream_reader.open_file.return_value = BytesIO(excel_bytes.read()) - - return parser, FileBasedStreamConfig(name="test_stream", format=ExcelFormat()), remote_file, stream_reader, MagicMock(), data - - -@patch("pandas.ExcelFile") -@pytest.mark.asyncio -async def test_infer_schema(mock_excel_file, setup_parser): - parser, config, file, stream_reader, logger, data = setup_parser - - # Mock the parse method of the pandas ExcelFile object - mock_excel_file.return_value.parse.return_value = data - - # Call infer_schema - schema = await parser.infer_schema(config, file, stream_reader, logger) - - # Define the expected schema - expected_schema: SchemaType = { - "column1": {"type": "number"}, - "column2": {"type": "string"}, - "column3": {"type": "boolean"}, - "column4": {"type": "string", "format": "date-time"}, - } - - # Validate the schema - assert schema == expected_schema - - # Assert that the stream_reader's open_file was called correctly - stream_reader.open_file.assert_called_once_with(file, parser.file_read_mode, parser.ENCODING, logger) - - # Assert that the logger was not used for warnings/errors - logger.info.assert_not_called() - logger.error.assert_not_called() - - -def test_invalid_format(mock_stream_reader, mock_logger, remote_file): - parser = ExcelParser() - invalid_config = FileBasedStreamConfig( - name="test.xlsx", - file_type="csv", - format={"filetype": "csv"}, - validation_policy=ValidationPolicy.emit_record, - ) - - with pytest.raises(ConfigValidationError): - list(parser.parse_records(invalid_config, remote_file, mock_stream_reader, mock_logger)) - - -def test_file_read_error(mock_stream_reader, mock_logger, file_config, remote_file): - parser = ExcelParser() - with patch("builtins.open", mock_open(read_data=b"corrupted data")): - with patch("pandas.ExcelFile") as mock_excel: - mock_excel.return_value.parse.side_effect = ValueError("Failed to parse file") - - with pytest.raises(RecordParseError): - list(parser.parse_records(file_config, remote_file, mock_stream_reader, mock_logger)) diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_jsonl_parser.py b/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_jsonl_parser.py deleted file mode 100644 index af5d83d77d04..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_jsonl_parser.py +++ /dev/null @@ -1,158 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import asyncio -import io -import json -from typing import Any, Dict -from unittest.mock import MagicMock, Mock - -import pytest -from airbyte_cdk.sources.file_based.exceptions import RecordParseError -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader -from airbyte_cdk.sources.file_based.file_types import JsonlParser - -JSONL_CONTENT_WITHOUT_MULTILINE_JSON_OBJECTS = [ - b'{"a": 1, "b": "1"}', - b'{"a": 2, "b": "2"}', -] -JSONL_CONTENT_WITH_MULTILINE_JSON_OBJECTS = [ - b"{", - b' "a": 1,', - b' "b": "1"', - b"}", - b"{", - b' "a": 2,', - b' "b": "2"', - b"}", -] -INVALID_JSON_CONTENT = [ - b"{", - b' "a": 1,', - b' "b": "1"', - b"{", - b' "a": 2,', - b' "b": "2"', - b"}", -] - - -@pytest.fixture -def stream_reader() -> MagicMock: - return MagicMock(spec=AbstractFileBasedStreamReader) - - -def _infer_schema(stream_reader: MagicMock) -> Dict[str, Any]: - loop = asyncio.new_event_loop() - task = loop.create_task(JsonlParser().infer_schema(Mock(), Mock(), stream_reader, Mock())) - loop.run_until_complete(task) - return task.result() # type: ignore # asyncio has no typing - - -def test_when_infer_then_return_proper_types(stream_reader: MagicMock) -> None: - record = {"col1": 1, "col2": 2.2, "col3": "3", "col4": ["a", "list"], "col5": {"inner": "obj"}, "col6": None, "col7": True} - stream_reader.open_file.return_value.__enter__.return_value = io.BytesIO(json.dumps(record).encode("utf-8")) - - schema = _infer_schema(stream_reader) - - assert schema == { - "col1": {"type": "integer"}, - "col2": {"type": "number"}, - "col3": {"type": "string"}, - "col4": {"type": "array"}, - "col5": {"type": "object"}, - "col6": {"type": "null"}, - "col7": {"type": "boolean"}, - } - - -def test_given_str_io_when_infer_then_return_proper_types(stream_reader: MagicMock) -> None: - stream_reader.open_file.return_value.__enter__.return_value = io.StringIO('{"col": 1}') - - schema = _infer_schema(stream_reader) - - assert schema == {"col": {"type": "integer"}} - - -def test_given_empty_record_when_infer_then_return_empty_schema(stream_reader: MagicMock) -> None: - stream_reader.open_file.return_value.__enter__.return_value = io.BytesIO("{}".encode("utf-8")) - schema = _infer_schema(stream_reader) - assert schema == {} - - -def test_given_no_records_when_infer_then_return_empty_schema(stream_reader: MagicMock) -> None: - stream_reader.open_file.return_value.__enter__.return_value = io.BytesIO("".encode("utf-8")) - schema = _infer_schema(stream_reader) - assert schema == {} - - -def test_given_limit_hit_when_infer_then_stop_considering_records(stream_reader: MagicMock) -> None: - jsonl_file_content = '{"key": 2.' + "2" * JsonlParser.MAX_BYTES_PER_FILE_FOR_SCHEMA_INFERENCE + '}\n{"key": "a string"}' - stream_reader.open_file.return_value.__enter__.return_value = io.BytesIO(jsonl_file_content.encode("utf-8")) - - schema = _infer_schema(stream_reader) - - assert schema == {"key": {"type": "number"}} - - -def test_given_multiline_json_objects_and_read_limit_hit_when_infer_then_return_parse_until_at_least_one_record( - stream_reader: MagicMock, -) -> None: - jsonl_file_content = '{\n"key": 2.' + "2" * JsonlParser.MAX_BYTES_PER_FILE_FOR_SCHEMA_INFERENCE + "\n}" - stream_reader.open_file.return_value.__enter__.return_value = io.BytesIO(jsonl_file_content.encode("utf-8")) - - schema = _infer_schema(stream_reader) - - assert schema == {"key": {"type": "number"}} - - -def test_given_multiline_json_objects_and_hits_read_limit_when_infer_then_return_proper_types(stream_reader: MagicMock) -> None: - stream_reader.open_file.return_value.__enter__.return_value = JSONL_CONTENT_WITH_MULTILINE_JSON_OBJECTS - schema = _infer_schema(stream_reader) - assert schema == {"a": {"type": "integer"}, "b": {"type": "string"}} - - -def test_given_multiple_records_then_merge_types(stream_reader: MagicMock) -> None: - stream_reader.open_file.return_value.__enter__.return_value = io.BytesIO('{"col1": 1}\n{"col1": 2.3}'.encode("utf-8")) - schema = _infer_schema(stream_reader) - assert schema == {"col1": {"type": "number"}} - - -def test_given_one_json_per_line_when_parse_records_then_return_records(stream_reader: MagicMock) -> None: - stream_reader.open_file.return_value.__enter__.return_value = JSONL_CONTENT_WITHOUT_MULTILINE_JSON_OBJECTS - records = list(JsonlParser().parse_records(Mock(), Mock(), stream_reader, Mock(), None)) - assert records == [{"a": 1, "b": "1"}, {"a": 2, "b": "2"}] - - -def test_given_one_json_per_line_when_parse_records_then_do_not_send_warning(stream_reader: MagicMock) -> None: - stream_reader.open_file.return_value.__enter__.return_value = JSONL_CONTENT_WITHOUT_MULTILINE_JSON_OBJECTS - logger = Mock() - - list(JsonlParser().parse_records(Mock(), Mock(), stream_reader, logger, None)) - - assert logger.warning.call_count == 0 - - -def test_given_multiline_json_object_when_parse_records_then_return_records(stream_reader: MagicMock) -> None: - stream_reader.open_file.return_value.__enter__.return_value = JSONL_CONTENT_WITH_MULTILINE_JSON_OBJECTS - records = list(JsonlParser().parse_records(Mock(), Mock(), stream_reader, Mock(), None)) - assert records == [{"a": 1, "b": "1"}, {"a": 2, "b": "2"}] - - -def test_given_multiline_json_object_when_parse_records_then_log_once_one_record_yielded(stream_reader: MagicMock) -> None: - stream_reader.open_file.return_value.__enter__.return_value = JSONL_CONTENT_WITH_MULTILINE_JSON_OBJECTS - logger = Mock() - - next(iter(JsonlParser().parse_records(Mock(), Mock(), stream_reader, logger, None))) - - assert logger.warning.call_count == 1 - - -def test_given_unparsable_json_when_parse_records_then_raise_error(stream_reader: MagicMock) -> None: - stream_reader.open_file.return_value.__enter__.return_value = INVALID_JSON_CONTENT - logger = Mock() - - with pytest.raises(RecordParseError): - list(JsonlParser().parse_records(Mock(), Mock(), stream_reader, logger, None)) - assert logger.warning.call_count == 0 diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_parquet_parser.py b/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_parquet_parser.py deleted file mode 100644 index c4768facc7dd..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_parquet_parser.py +++ /dev/null @@ -1,275 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import asyncio -import datetime -import math -from typing import Any, Mapping, Union -from unittest.mock import Mock - -import pyarrow as pa -import pytest -from airbyte_cdk.sources.file_based.config.csv_format import CsvFormat -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig, ValidationPolicy -from airbyte_cdk.sources.file_based.config.jsonl_format import JsonlFormat -from airbyte_cdk.sources.file_based.config.parquet_format import ParquetFormat -from airbyte_cdk.sources.file_based.file_types import ParquetParser -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from pyarrow import Scalar - -_default_parquet_format = ParquetFormat() -_decimal_as_float_parquet_format = ParquetFormat(decimal_as_float=True) - - -@pytest.mark.parametrize( - "parquet_type, expected_type, parquet_format", - [ - pytest.param(pa.bool_(), {"type": "boolean"}, _default_parquet_format, id="test_parquet_bool"), - pytest.param(pa.int8(), {"type": "integer"}, _default_parquet_format, id="test_parquet_int8"), - pytest.param(pa.int16(), {"type": "integer"}, _default_parquet_format, id="test_parquet_int16"), - pytest.param(pa.int32(), {"type": "integer"}, _default_parquet_format, id="test_parquet_int32"), - pytest.param(pa.int64(), {"type": "integer"}, _default_parquet_format, id="test_parquet_int64"), - pytest.param(pa.uint8(), {"type": "integer"}, _default_parquet_format, id="test_parquet_uint8"), - pytest.param(pa.uint16(), {"type": "integer"}, _default_parquet_format, id="test_parquet_uint16"), - pytest.param(pa.uint32(), {"type": "integer"}, _default_parquet_format, id="test_parquet_uint32"), - pytest.param(pa.uint64(), {"type": "integer"}, _default_parquet_format, id="test_parquet_uint64"), - pytest.param(pa.float16(), {"type": "number"}, _default_parquet_format, id="test_parquet_float16"), - pytest.param(pa.float32(), {"type": "number"}, _default_parquet_format, id="test_parquet_float32"), - pytest.param(pa.float64(), {"type": "number"}, _default_parquet_format, id="test_parquet_float64"), - pytest.param(pa.time32("s"), {"type": "string"}, _default_parquet_format, id="test_parquet_time32s"), - pytest.param(pa.time32("ms"), {"type": "string"}, _default_parquet_format, id="test_parquet_time32ms"), - pytest.param(pa.time64("us"), {"type": "string"}, _default_parquet_format, id="test_parquet_time64us"), - pytest.param(pa.time64("ns"), {"type": "string"}, _default_parquet_format, id="test_parquet_time64us"), - pytest.param(pa.timestamp("s"), {"type": "string", "format": "date-time"}, _default_parquet_format, id="test_parquet_timestamps_s"), - pytest.param( - pa.timestamp("ms"), {"type": "string", "format": "date-time"}, _default_parquet_format, id="test_parquet_timestamp_ms" - ), - pytest.param( - pa.timestamp("s", "utc"), - {"type": "string", "format": "date-time"}, - _default_parquet_format, - id="test_parquet_timestamps_s_with_tz", - ), - pytest.param( - pa.timestamp("ms", "est"), - {"type": "string", "format": "date-time"}, - _default_parquet_format, - id="test_parquet_timestamps_ms_with_tz", - ), - pytest.param(pa.date32(), {"type": "string", "format": "date"}, _default_parquet_format, id="test_parquet_date32"), - pytest.param(pa.date64(), {"type": "string", "format": "date"}, _default_parquet_format, id="test_parquet_date64"), - pytest.param(pa.duration("s"), {"type": "integer"}, _default_parquet_format, id="test_duration_s"), - pytest.param(pa.duration("ms"), {"type": "integer"}, _default_parquet_format, id="test_duration_ms"), - pytest.param(pa.duration("us"), {"type": "integer"}, _default_parquet_format, id="test_duration_us"), - pytest.param(pa.duration("ns"), {"type": "integer"}, _default_parquet_format, id="test_duration_ns"), - pytest.param(pa.month_day_nano_interval(), {"type": "array"}, _default_parquet_format, id="test_parquet_month_day_nano_interval"), - pytest.param(pa.binary(), {"type": "string"}, _default_parquet_format, id="test_binary"), - pytest.param(pa.binary(2), {"type": "string"}, _default_parquet_format, id="test_fixed_size_binary"), - pytest.param(pa.string(), {"type": "string"}, _default_parquet_format, id="test_parquet_string"), - pytest.param(pa.utf8(), {"type": "string"}, _default_parquet_format, id="test_utf8"), - pytest.param(pa.large_binary(), {"type": "string"}, _default_parquet_format, id="test_large_binary"), - pytest.param(pa.large_string(), {"type": "string"}, _default_parquet_format, id="test_large_string"), - pytest.param(pa.large_utf8(), {"type": "string"}, _default_parquet_format, id="test_large_utf8"), - pytest.param(pa.dictionary(pa.int32(), pa.string()), {"type": "object"}, _default_parquet_format, id="test_dictionary"), - pytest.param(pa.struct([pa.field("field", pa.int32())]), {"type": "object"}, _default_parquet_format, id="test_struct"), - pytest.param(pa.list_(pa.int32()), {"type": "array"}, _default_parquet_format, id="test_list"), - pytest.param(pa.large_list(pa.int32()), {"type": "array"}, _default_parquet_format, id="test_large_list"), - pytest.param(pa.decimal128(2), {"type": "string"}, _default_parquet_format, id="test_decimal128"), - pytest.param(pa.decimal256(2), {"type": "string"}, _default_parquet_format, id="test_decimal256"), - pytest.param(pa.decimal128(2), {"type": "number"}, _decimal_as_float_parquet_format, id="test_decimal128_as_float"), - pytest.param(pa.decimal256(2), {"type": "number"}, _decimal_as_float_parquet_format, id="test_decimal256_as_float"), - pytest.param(pa.map_(pa.int32(), pa.int32()), {"type": "object"}, _default_parquet_format, id="test_map"), - pytest.param(pa.null(), {"type": "null"}, _default_parquet_format, id="test_null"), - ], -) -def test_type_mapping(parquet_type: pa.DataType, expected_type: Mapping[str, str], parquet_format: ParquetFormat) -> None: - if expected_type is None: - with pytest.raises(ValueError): - ParquetParser.parquet_type_to_schema_type(parquet_type, parquet_format) - else: - assert ParquetParser.parquet_type_to_schema_type(parquet_type, parquet_format) == expected_type - - -@pytest.mark.parametrize( - "pyarrow_type, parquet_format, parquet_object, expected_value", - [ - pytest.param(pa.bool_(), _default_parquet_format, True, True, id="test_bool"), - pytest.param(pa.int8(), _default_parquet_format, -1, -1, id="test_int8"), - pytest.param(pa.int16(), _default_parquet_format, 2, 2, id="test_int16"), - pytest.param(pa.int32(), _default_parquet_format, 3, 3, id="test_int32"), - pytest.param(pa.int64(), _default_parquet_format, 4, 4, id="test_int64"), - pytest.param(pa.uint8(), _default_parquet_format, 4, 4, id="test_parquet_uint8"), - pytest.param(pa.uint16(), _default_parquet_format, 5, 5, id="test_parquet_uint16"), - pytest.param(pa.uint32(), _default_parquet_format, 6, 6, id="test_parquet_uint32"), - pytest.param(pa.uint64(), _default_parquet_format, 6, 6, id="test_parquet_uint64"), - pytest.param(pa.float32(), _default_parquet_format, 2.7, 2.7, id="test_parquet_float32"), - pytest.param(pa.float64(), _default_parquet_format, 3.14, 3.14, id="test_parquet_float64"), - pytest.param(pa.time32("s"), _default_parquet_format, datetime.time(1, 2, 3), "01:02:03", id="test_parquet_time32s"), - pytest.param(pa.time32("ms"), _default_parquet_format, datetime.time(3, 4, 5), "03:04:05", id="test_parquet_time32ms"), - pytest.param(pa.time64("us"), _default_parquet_format, datetime.time(6, 7, 8), "06:07:08", id="test_parquet_time64us"), - pytest.param(pa.time64("ns"), _default_parquet_format, datetime.time(9, 10, 11), "09:10:11", id="test_parquet_time64us"), - pytest.param( - pa.timestamp("s"), - _default_parquet_format, - datetime.datetime(2023, 7, 7, 10, 11, 12), - "2023-07-07T10:11:12", - id="test_parquet_timestamps_s", - ), - pytest.param( - pa.timestamp("ms"), - _default_parquet_format, - datetime.datetime(2024, 8, 8, 11, 12, 13), - "2024-08-08T11:12:13", - id="test_parquet_timestamp_ms", - ), - pytest.param( - pa.timestamp("s", "utc"), - _default_parquet_format, - datetime.datetime(2020, 1, 1, 1, 1, 1, tzinfo=datetime.timezone.utc), - "2020-01-01T01:01:01+00:00", - id="test_parquet_timestamps_s_with_tz", - ), - pytest.param( - pa.timestamp("ms", "utc"), - _default_parquet_format, - datetime.datetime(2021, 2, 3, 4, 5, tzinfo=datetime.timezone.utc), - "2021-02-03T04:05:00+00:00", - id="test_parquet_timestamps_ms_with_tz", - ), - pytest.param(pa.date32(), _default_parquet_format, datetime.date(2023, 7, 7), "2023-07-07", id="test_parquet_date32"), - pytest.param(pa.date64(), _default_parquet_format, datetime.date(2023, 7, 8), "2023-07-08", id="test_parquet_date64"), - pytest.param(pa.duration("s"), _default_parquet_format, 12345, 12345, id="test_duration_s"), - pytest.param(pa.duration("ms"), _default_parquet_format, 12345, 12345, id="test_duration_ms"), - pytest.param(pa.duration("us"), _default_parquet_format, 12345, 12345, id="test_duration_us"), - pytest.param(pa.duration("ns"), _default_parquet_format, 12345, 12345, id="test_duration_ns"), - pytest.param( - pa.month_day_nano_interval(), - _default_parquet_format, - datetime.timedelta(days=3, microseconds=4), - [0, 3, 4000], - id="test_parquet_month_day_nano_interval", - ), - pytest.param(pa.binary(), _default_parquet_format, b"this is a binary string", "this is a binary string", id="test_binary"), - pytest.param(pa.binary(2), _default_parquet_format, b"t1", "t1", id="test_fixed_size_binary"), - pytest.param(pa.string(), _default_parquet_format, "this is a string", "this is a string", id="test_parquet_string"), - pytest.param(pa.utf8(), _default_parquet_format, "utf8".encode("utf8"), "utf8", id="test_utf8"), - pytest.param(pa.large_binary(), _default_parquet_format, b"large binary string", "large binary string", id="test_large_binary"), - pytest.param(pa.large_string(), _default_parquet_format, "large string", "large string", id="test_large_string"), - pytest.param(pa.large_utf8(), _default_parquet_format, "large utf8", "large utf8", id="test_large_utf8"), - pytest.param(pa.struct([pa.field("field", pa.int32())]), _default_parquet_format, {"field": 1}, {"field": 1}, id="test_struct"), - pytest.param(pa.list_(pa.int32()), _default_parquet_format, [1, 2, 3], [1, 2, 3], id="test_list"), - pytest.param(pa.large_list(pa.int32()), _default_parquet_format, [4, 5, 6], [4, 5, 6], id="test_large_list"), - pytest.param(pa.decimal128(5, 3), _default_parquet_format, 12, "12.000", id="test_decimal128"), - pytest.param(pa.decimal256(8, 2), _default_parquet_format, 13, "13.00", id="test_decimal256"), - pytest.param(pa.decimal128(5, 3), _decimal_as_float_parquet_format, 12, 12.000, id="test_decimal128"), - pytest.param(pa.decimal256(8, 2), _decimal_as_float_parquet_format, 13, 13.00, id="test_decimal256"), - pytest.param( - pa.map_(pa.string(), pa.int32()), _default_parquet_format, {"hello": 1, "world": 2}, {"hello": 1, "world": 2}, id="test_map" - ), - pytest.param(pa.null(), _default_parquet_format, None, None, id="test_null"), - ], -) -def test_value_transformation( - pyarrow_type: pa.DataType, parquet_format: ParquetFormat, parquet_object: Scalar, expected_value: Any -) -> None: - pyarrow_value = pa.array([parquet_object], type=pyarrow_type)[0] - py_value = ParquetParser._to_output_value(pyarrow_value, parquet_format) - if isinstance(py_value, float): - assert math.isclose(py_value, expected_value, abs_tol=0.01) - else: - assert py_value == expected_value - - -def test_value_dictionary() -> None: - # Setting the dictionary is more involved than other data types so we test it in a separate test - dictionary_values = ["apple", "banana", "cherry"] - indices = [0, 1, 2, 0, 1] - indices_array = pa.array(indices, type=pa.int8()) - dictionary = pa.DictionaryArray.from_arrays(indices_array, dictionary_values) - py_value = ParquetParser._to_output_value(dictionary, _default_parquet_format) - assert py_value == {"indices": [0, 1, 2, 0, 1], "values": ["apple", "banana", "cherry"]} - - -@pytest.mark.parametrize( - "parquet_type, parquet_format", - [ - pytest.param(pa.bool_(), _default_parquet_format, id="test_parquet_bool"), - pytest.param(pa.int8(), _default_parquet_format, id="test_parquet_int8"), - pytest.param(pa.int16(), _default_parquet_format, id="test_parquet_int16"), - pytest.param(pa.int32(), _default_parquet_format, id="test_parquet_int32"), - pytest.param(pa.int64(), _default_parquet_format, id="test_parquet_int64"), - pytest.param(pa.uint8(), _default_parquet_format, id="test_parquet_uint8"), - pytest.param(pa.uint16(), _default_parquet_format, id="test_parquet_uint16"), - pytest.param(pa.uint32(), _default_parquet_format, id="test_parquet_uint32"), - pytest.param(pa.uint64(), _default_parquet_format, id="test_parquet_uint64"), - pytest.param(pa.float16(), _default_parquet_format, id="test_parquet_float16"), - pytest.param(pa.float32(), _default_parquet_format, id="test_parquet_float32"), - pytest.param(pa.float64(), _default_parquet_format, id="test_parquet_float64"), - pytest.param(pa.time32("s"), _default_parquet_format, id="test_parquet_time32s"), - pytest.param(pa.time32("ms"), _default_parquet_format, id="test_parquet_time32ms"), - pytest.param(pa.time64("us"), _default_parquet_format, id="test_parquet_time64us"), - pytest.param(pa.time64("ns"), _default_parquet_format, id="test_parquet_time64ns"), - pytest.param(pa.timestamp("s"), _default_parquet_format, id="test_parquet_timestamps_s"), - pytest.param(pa.timestamp("ms"), _default_parquet_format, id="test_parquet_timestamp_ms"), - pytest.param(pa.timestamp("s", "utc"), _default_parquet_format, id="test_parquet_timestamps_s_with_tz"), - pytest.param(pa.timestamp("ms", "est"), _default_parquet_format, id="test_parquet_timestamps_ms_with_tz"), - pytest.param(pa.date32(), _default_parquet_format, id="test_parquet_date32"), - pytest.param(pa.date64(), _default_parquet_format, id="test_parquet_date64"), - pytest.param(pa.duration("s"), _default_parquet_format, id="test_duration_s"), - pytest.param(pa.duration("ms"), _default_parquet_format, id="test_duration_ms"), - pytest.param(pa.duration("us"), _default_parquet_format, id="test_duration_us"), - pytest.param(pa.duration("ns"), _default_parquet_format, id="test_duration_ns"), - pytest.param(pa.month_day_nano_interval(), _default_parquet_format, id="test_parquet_month_day_nano_interval"), - pytest.param(pa.binary(), _default_parquet_format, id="test_binary"), - pytest.param(pa.binary(2), _default_parquet_format, id="test_fixed_size_binary"), - pytest.param(pa.string(), _default_parquet_format, id="test_parquet_string"), - pytest.param(pa.utf8(), _default_parquet_format, id="test_utf8"), - pytest.param(pa.large_binary(), _default_parquet_format, id="test_large_binary"), - pytest.param(pa.large_string(), _default_parquet_format, id="test_large_string"), - pytest.param(pa.large_utf8(), _default_parquet_format, id="test_large_utf8"), - pytest.param(pa.dictionary(pa.int32(), pa.string()), _default_parquet_format, id="test_dictionary"), - pytest.param(pa.struct([pa.field("field", pa.int32())]), _default_parquet_format, id="test_struct"), - pytest.param(pa.list_(pa.int32()), _default_parquet_format, id="test_list"), - pytest.param(pa.large_list(pa.int32()), _default_parquet_format, id="test_large_list"), - pytest.param(pa.decimal128(2), _default_parquet_format, id="test_decimal128"), - pytest.param(pa.decimal256(2), _default_parquet_format, id="test_decimal256"), - pytest.param(pa.decimal128(2), _decimal_as_float_parquet_format, id="test_decimal128_as_float"), - pytest.param(pa.decimal256(2), _decimal_as_float_parquet_format, id="test_decimal256_as_float"), - pytest.param(pa.map_(pa.int32(), pa.int32()), _default_parquet_format, id="test_map"), - pytest.param(pa.null(), _default_parquet_format, id="test_null"), - ], -) -def test_null_value_does_not_throw(parquet_type, parquet_format) -> None: - pyarrow_value = pa.scalar(None, type=parquet_type) - assert ParquetParser._to_output_value(pyarrow_value, parquet_format) is None - - -@pytest.mark.parametrize( - "file_format", - [ - pytest.param( - CsvFormat( - filetype="csv", - delimiter=",", - escape_char="\\", - quote_char='"', - ), - id="test_csv_format", - ), - pytest.param(JsonlFormat(), id="test_jsonl_format"), - ], -) -def test_wrong_file_format(file_format: Union[CsvFormat, JsonlFormat]) -> None: - parser = ParquetParser() - config = FileBasedStreamConfig( - name="test.parquet", - file_type=file_format.filetype, - format={file_format.filetype: file_format}, - validation_policy=ValidationPolicy.emit_record, - ) - file = RemoteFile(uri="s3://mybucket/test.parquet", last_modified=datetime.datetime.now()) - stream_reader = Mock() - logger = Mock() - with pytest.raises(ValueError): - asyncio.get_event_loop().run_until_complete(parser.infer_schema(config, file, stream_reader, logger)) diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_unstructured_parser.py b/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_unstructured_parser.py deleted file mode 100644 index 9bc096c5136e..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_unstructured_parser.py +++ /dev/null @@ -1,593 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import asyncio -from datetime import datetime -from unittest import mock -from unittest.mock import MagicMock, call, mock_open, patch - -import pytest -import requests -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig -from airbyte_cdk.sources.file_based.config.unstructured_format import APIParameterConfigModel, APIProcessingConfigModel, UnstructuredFormat -from airbyte_cdk.sources.file_based.exceptions import RecordParseError -from airbyte_cdk.sources.file_based.file_types import UnstructuredParser -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from unstructured.documents.elements import ElementMetadata, Formula, ListItem, Text, Title -from unstructured.file_utils.filetype import FileType - -FILE_URI = "path/to/file.xyz" - - -@pytest.mark.parametrize( - "filetype, format_config, raises", - [ - pytest.param( - FileType.MD, - UnstructuredFormat(skip_unprocessable_files=False), - False, - id="markdown_file", - ), - pytest.param( - FileType.CSV, - UnstructuredFormat(skip_unprocessable_files=False), - True, - id="wrong_file_format", - ), - pytest.param( - FileType.CSV, - UnstructuredFormat(skip_unprocessable_files=True), - False, - id="wrong_file_format_skipping", - ), - pytest.param( - FileType.PDF, - UnstructuredFormat(skip_unprocessable_files=False), - False, - id="pdf_file", - ), - pytest.param( - FileType.DOCX, - UnstructuredFormat(skip_unprocessable_files=False), - False, - id="docx_file", - ), - pytest.param( - FileType.PPTX, - UnstructuredFormat(skip_unprocessable_files=False), - False, - id="pptx_file", - ), - ], -) -@patch("airbyte_cdk.sources.file_based.file_types.unstructured_parser.detect_filetype") -def test_infer_schema(mock_detect_filetype, filetype, format_config, raises): - # use a fresh event loop to avoid leaking into other tests - main_loop = asyncio.get_event_loop() - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - - stream_reader = MagicMock() - mock_open(stream_reader.open_file) - fake_file = MagicMock() - fake_file.uri = FILE_URI - logger = MagicMock() - mock_detect_filetype.return_value = filetype - config = MagicMock() - config.format = format_config - if raises: - with pytest.raises(RecordParseError): - loop.run_until_complete(UnstructuredParser().infer_schema(config, fake_file, stream_reader, logger)) - else: - schema = loop.run_until_complete(UnstructuredParser().infer_schema(config, MagicMock(), MagicMock(), MagicMock())) - assert schema == { - "content": {"type": "string", "description": "Content of the file as markdown. Might be null if the file could not be parsed"}, - "document_key": {"type": "string", "description": "Unique identifier of the document, e.g. the file path"}, - "_ab_source_file_parse_error": { - "type": "string", - "description": "Error message if the file could not be parsed even though the file is supported", - }, - } - loop.close() - asyncio.set_event_loop(main_loop) - - -@pytest.mark.parametrize( - "filetype, format_config, parse_result, raises, expected_records, parsing_error", - [ - pytest.param( - FileType.MD, - UnstructuredFormat(skip_unprocessable_files=False), - "test", - False, - [ - { - "content": "test", - "document_key": FILE_URI, - "_ab_source_file_parse_error": None, - } - ], - False, - id="markdown_file", - ), - pytest.param( - FileType.CSV, - UnstructuredFormat(skip_unprocessable_files=False), - None, - True, - None, - False, - id="wrong_file_format", - ), - pytest.param( - FileType.CSV, - UnstructuredFormat(skip_unprocessable_files=True), - None, - False, - [ - { - "content": None, - "document_key": FILE_URI, - "_ab_source_file_parse_error": "Error parsing record. This could be due to a mismatch between the config's file type and the actual file type, or because the file or record is not parseable. Contact Support if you need assistance.\nfilename=path/to/file.xyz message=File type FileType.CSV is not supported. Supported file types are FileType.MD, FileType.PDF, FileType.DOCX, FileType.PPTX, FileType.TXT", - } - ], - False, - id="skip_unprocessable_files", - ), - pytest.param( - FileType.PDF, - UnstructuredFormat(skip_unprocessable_files=False), - [ - Title("heading"), - Text("This is the text"), - ListItem("This is a list item"), - Formula("This is a formula"), - ], - False, - [ - { - "content": "# heading\n\nThis is the text\n\n- This is a list item\n\n```\nThis is a formula\n```", - "document_key": FILE_URI, - "_ab_source_file_parse_error": None, - } - ], - False, - id="pdf_file", - ), - pytest.param( - FileType.PDF, - UnstructuredFormat(skip_unprocessable_files=False), - [ - Title("first level heading", metadata=ElementMetadata(category_depth=1)), - Title("second level heading", metadata=ElementMetadata(category_depth=2)), - ], - False, - [ - { - "content": "# first level heading\n\n## second level heading", - "document_key": FILE_URI, - "_ab_source_file_parse_error": None, - } - ], - False, - id="multi_level_headings", - ), - pytest.param( - FileType.DOCX, - UnstructuredFormat(skip_unprocessable_files=False), - [ - Title("heading"), - Text("This is the text"), - ListItem("This is a list item"), - Formula("This is a formula"), - ], - False, - [ - { - "content": "# heading\n\nThis is the text\n\n- This is a list item\n\n```\nThis is a formula\n```", - "document_key": FILE_URI, - "_ab_source_file_parse_error": None, - } - ], - False, - id="docx_file", - ), - pytest.param( - FileType.DOCX, - UnstructuredFormat(skip_unprocessable_files=True), - "", - False, - [ - { - "content": None, - "document_key": FILE_URI, - "_ab_source_file_parse_error": "Error parsing record. This could be due to a mismatch between the config's file type and the actual file type, or because the file or record is not parseable. Contact Support if you need assistance.\nfilename=path/to/file.xyz message=weird parsing error", - } - ], - True, - id="exception_during_parsing", - ), - ], -) -@patch("unstructured.partition.pdf.partition_pdf") -@patch("unstructured.partition.pptx.partition_pptx") -@patch("unstructured.partition.docx.partition_docx") -@patch("airbyte_cdk.sources.file_based.file_types.unstructured_parser.detect_filetype") -def test_parse_records( - mock_detect_filetype, - mock_partition_docx, - mock_partition_pptx, - mock_partition_pdf, - filetype, - format_config, - parse_result, - raises, - expected_records, - parsing_error, -): - stream_reader = MagicMock() - mock_open(stream_reader.open_file, read_data=bytes(str(parse_result), "utf-8")) - fake_file = RemoteFile(uri=FILE_URI, last_modified=datetime.now()) - fake_file.uri = FILE_URI - logger = MagicMock() - config = MagicMock() - config.format = format_config - mock_detect_filetype.return_value = filetype - if parsing_error: - mock_partition_docx.side_effect = Exception("weird parsing error") - mock_partition_pptx.side_effect = Exception("weird parsing error") - mock_partition_pdf.side_effect = Exception("weird parsing error") - else: - mock_partition_docx.return_value = parse_result - mock_partition_pptx.return_value = parse_result - mock_partition_pdf.return_value = parse_result - if raises: - with pytest.raises(RecordParseError): - list(UnstructuredParser().parse_records(config, fake_file, stream_reader, logger, MagicMock())) - else: - assert list(UnstructuredParser().parse_records(config, fake_file, stream_reader, logger, MagicMock())) == expected_records - - -@pytest.mark.parametrize( - "format_config, raises_for_status, json_response, is_ok, expected_error", - [ - pytest.param( - UnstructuredFormat(skip_unprocessable_file_types=False), - False, - {"status": "ok"}, - True, - None, - id="local", - ), - pytest.param( - UnstructuredFormat(skip_unprocessable_file_types=False, strategy="fast"), - False, - {"status": "ok"}, - True, - None, - id="local_ok_strategy", - ), - pytest.param( - UnstructuredFormat(skip_unprocessable_file_types=False, strategy="hi_res"), - False, - {"status": "ok"}, - False, - "Hi-res strategy is not supported for local processing", - id="local_unsupported_strategy", - ), - pytest.param( - UnstructuredFormat(skip_unprocessable_file_types=False, processing=APIProcessingConfigModel(mode="api", api_key="test")), - False, - [{"type": "Title", "text": "Airbyte source connection test"}], - True, - None, - id="api_ok", - ), - pytest.param( - UnstructuredFormat(skip_unprocessable_file_types=False, processing=APIProcessingConfigModel(mode="api", api_key="test")), - True, - None, - False, - "API error", - id="api_error", - ), - pytest.param( - UnstructuredFormat(skip_unprocessable_file_types=False, processing=APIProcessingConfigModel(mode="api", api_key="test")), - False, - {"unexpected": "response"}, - False, - "Error", - id="unexpected_handling_error", - ), - ], -) -@patch("airbyte_cdk.sources.file_based.file_types.unstructured_parser.requests") -def test_check_config(requests_mock, format_config, raises_for_status, json_response, is_ok, expected_error): - mock_response = MagicMock() - mock_response.json.return_value = json_response - if raises_for_status: - mock_response.raise_for_status.side_effect = Exception("API error") - requests_mock.post.return_value = mock_response - result, error = UnstructuredParser().check_config(FileBasedStreamConfig(name="test", format=format_config)) - assert result == is_ok - if expected_error: - assert expected_error in error - - -@pytest.mark.parametrize( - "filetype, format_config, raises_for_status, file_content, json_response, expected_requests, raises, expected_records, http_status_code", - [ - pytest.param( - FileType.PDF, - UnstructuredFormat(skip_unprocessable_file_types=False, processing=APIProcessingConfigModel(mode="api", api_key="test")), - None, - "test", - [{"type": "Text", "text": "test"}], - [ - call( - "https://api.unstructured.io/general/v0/general", - headers={"accept": "application/json", "unstructured-api-key": "test"}, - data={"strategy": "auto"}, - files={"files": ("filename", mock.ANY, "application/pdf")}, - ) - ], - False, - [{"content": "test", "document_key": FILE_URI, "_ab_source_file_parse_error": None}], - 200, - id="basic_request", - ), - pytest.param( - FileType.PDF, - UnstructuredFormat( - skip_unprocessable_file_types=False, - strategy="hi_res", - processing=APIProcessingConfigModel( - mode="api", - api_key="test", - api_url="http://localhost:8000", - parameters=[ - APIParameterConfigModel(name="include_page_breaks", value="true"), - APIParameterConfigModel(name="ocr_languages", value="eng"), - APIParameterConfigModel(name="ocr_languages", value="kor"), - ], - ), - ), - None, - "test", - [{"type": "Text", "text": "test"}], - [ - call( - "http://localhost:8000/general/v0/general", - headers={"accept": "application/json", "unstructured-api-key": "test"}, - data={"strategy": "hi_res", "include_page_breaks": "true", "ocr_languages": ["eng", "kor"]}, - files={"files": ("filename", mock.ANY, "application/pdf")}, - ) - ], - False, - [{"content": "test", "document_key": FILE_URI, "_ab_source_file_parse_error": None}], - 200, - id="request_with_params", - ), - pytest.param( - FileType.MD, - UnstructuredFormat(skip_unprocessable_file_types=False, processing=APIProcessingConfigModel(mode="api", api_key="test")), - None, - "# Mymarkdown", - None, - None, - False, - [{"content": "# Mymarkdown", "document_key": FILE_URI, "_ab_source_file_parse_error": None}], - 200, - id="handle_markdown_locally", - ), - pytest.param( - FileType.PDF, - UnstructuredFormat(skip_unprocessable_file_types=False, processing=APIProcessingConfigModel(mode="api", api_key="test")), - [ - requests.exceptions.RequestException("API error"), - requests.exceptions.RequestException("API error"), - requests.exceptions.RequestException("API error"), - requests.exceptions.RequestException("API error"), - requests.exceptions.RequestException("API error"), - ], - "test", - None, - [ - call( - "https://api.unstructured.io/general/v0/general", - headers={"accept": "application/json", "unstructured-api-key": "test"}, - data={"strategy": "auto"}, - files={"files": ("filename", mock.ANY, "application/pdf")}, - ), - call().raise_for_status(), - call( - "https://api.unstructured.io/general/v0/general", - headers={"accept": "application/json", "unstructured-api-key": "test"}, - data={"strategy": "auto"}, - files={"files": ("filename", mock.ANY, "application/pdf")}, - ), - call().raise_for_status(), - call( - "https://api.unstructured.io/general/v0/general", - headers={"accept": "application/json", "unstructured-api-key": "test"}, - data={"strategy": "auto"}, - files={"files": ("filename", mock.ANY, "application/pdf")}, - ), - call().raise_for_status(), - call( - "https://api.unstructured.io/general/v0/general", - headers={"accept": "application/json", "unstructured-api-key": "test"}, - data={"strategy": "auto"}, - files={"files": ("filename", mock.ANY, "application/pdf")}, - ), - call().raise_for_status(), - call( - "https://api.unstructured.io/general/v0/general", - headers={"accept": "application/json", "unstructured-api-key": "test"}, - data={"strategy": "auto"}, - files={"files": ("filename", mock.ANY, "application/pdf")}, - ), - call().raise_for_status(), - ], - True, - None, - 200, - id="retry_and_raise_on_api_error", - ), - pytest.param( - FileType.PDF, - UnstructuredFormat(skip_unprocessable_file_types=False, processing=APIProcessingConfigModel(mode="api", api_key="test")), - [ - requests.exceptions.RequestException("API error"), - requests.exceptions.RequestException("API error"), - None, - ], - "test", - [{"type": "Text", "text": "test"}], - [ - call( - "https://api.unstructured.io/general/v0/general", - headers={"accept": "application/json", "unstructured-api-key": "test"}, - data={"strategy": "auto"}, - files={"files": ("filename", mock.ANY, "application/pdf")}, - ), - call().raise_for_status(), - call( - "https://api.unstructured.io/general/v0/general", - headers={"accept": "application/json", "unstructured-api-key": "test"}, - data={"strategy": "auto"}, - files={"files": ("filename", mock.ANY, "application/pdf")}, - ), - call().raise_for_status(), - call( - "https://api.unstructured.io/general/v0/general", - headers={"accept": "application/json", "unstructured-api-key": "test"}, - data={"strategy": "auto"}, - files={"files": ("filename", mock.ANY, "application/pdf")}, - ), - call().raise_for_status(), - ], - False, - [{"content": "test", "document_key": FILE_URI, "_ab_source_file_parse_error": None}], - 200, - id="retry_and_recover", - ), - pytest.param( - FileType.PDF, - UnstructuredFormat(skip_unprocessable_file_types=False, processing=APIProcessingConfigModel(mode="api", api_key="test")), - [ - Exception("Unexpected error"), - ], - "test", - [{"type": "Text", "text": "test"}], - [ - call( - "https://api.unstructured.io/general/v0/general", - headers={"accept": "application/json", "unstructured-api-key": "test"}, - data={"strategy": "auto"}, - files={"files": ("filename", mock.ANY, "application/pdf")}, - ), - call().raise_for_status(), - ], - True, - None, - 200, - id="no_retry_on_unexpected_error", - ), - pytest.param( - FileType.PDF, - UnstructuredFormat(skip_unprocessable_file_types=False, processing=APIProcessingConfigModel(mode="api", api_key="test")), - [ - requests.exceptions.RequestException("API error", response=MagicMock(status_code=400)), - ], - "test", - [{"type": "Text", "text": "test"}], - [ - call( - "https://api.unstructured.io/general/v0/general", - headers={"accept": "application/json", "unstructured-api-key": "test"}, - data={"strategy": "auto"}, - files={"files": ("filename", mock.ANY, "application/pdf")}, - ), - call().raise_for_status(), - ], - True, - None, - 400, - id="no_retry_on_400_error", - ), - pytest.param( - FileType.PDF, - UnstructuredFormat(skip_unprocessable_file_types=False, processing=APIProcessingConfigModel(mode="api", api_key="test")), - None, - "test", - [{"detail": "Something went wrong"}], - [ - call( - "https://api.unstructured.io/general/v0/general", - headers={"accept": "application/json", "unstructured-api-key": "test"}, - data={"strategy": "auto"}, - files={"files": ("filename", mock.ANY, "application/pdf")}, - ), - ], - False, - [ - { - "content": None, - "document_key": FILE_URI, - "_ab_source_file_parse_error": "Error parsing record. This could be due to a mismatch between the config's file type and the actual file type, or because the file or record is not parseable. Contact Support if you need assistance.\nfilename=path/to/file.xyz message=[{'detail': 'Something went wrong'}]", - } - ], - 422, - id="error_record_on_422_error", - ), - ], -) -@patch("airbyte_cdk.sources.file_based.file_types.unstructured_parser.requests") -@patch("airbyte_cdk.sources.file_based.file_types.unstructured_parser.detect_filetype") -@patch("time.sleep", side_effect=lambda _: None) -def test_parse_records_remotely( - time_mock, - mock_detect_filetype, - requests_mock, - filetype, - format_config, - raises_for_status, - file_content, - json_response, - expected_requests, - raises, - expected_records, - http_status_code, -): - stream_reader = MagicMock() - mock_open(stream_reader.open_file, read_data=bytes(str(file_content), "utf-8")) - fake_file = RemoteFile(uri=FILE_URI, last_modified=datetime.now()) - fake_file.uri = FILE_URI - logger = MagicMock() - config = MagicMock() - config.format = format_config - mock_detect_filetype.return_value = filetype - mock_response = MagicMock() - mock_response.json.return_value = json_response - mock_response.status_code = http_status_code - if raises_for_status: - mock_response.raise_for_status.side_effect = raises_for_status - requests_mock.post.return_value = mock_response - requests_mock.exceptions.RequestException = requests.exceptions.RequestException - - if raises: - with pytest.raises(AirbyteTracedException) as exc: - list(UnstructuredParser().parse_records(config, fake_file, stream_reader, logger, MagicMock())) - # Failures from the API are treated as config errors - assert exc.value.failure_type == FailureType.config_error - else: - assert list(UnstructuredParser().parse_records(config, fake_file, stream_reader, logger, MagicMock())) == expected_records - - if expected_requests: - requests_mock.post.assert_has_calls(expected_requests) - else: - requests_mock.post.assert_not_called() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/helpers.py b/airbyte-cdk/python/unit_tests/sources/file_based/helpers.py deleted file mode 100644 index 6d4966e2c2c9..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/helpers.py +++ /dev/null @@ -1,70 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from datetime import datetime -from io import IOBase -from typing import Any, Dict, List, Mapping, Optional - -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig -from airbyte_cdk.sources.file_based.discovery_policy import DefaultDiscoveryPolicy -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode -from airbyte_cdk.sources.file_based.file_types.csv_parser import CsvParser -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser -from airbyte_cdk.sources.file_based.file_types.jsonl_parser import JsonlParser -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.schema_validation_policies import AbstractSchemaValidationPolicy -from airbyte_cdk.sources.file_based.stream.concurrent.cursor import FileBasedConcurrentCursor -from airbyte_cdk.sources.file_based.stream.cursor import DefaultFileBasedCursor -from unit_tests.sources.file_based.in_memory_files_source import InMemoryFilesStreamReader - - -class EmptySchemaParser(CsvParser): - async def infer_schema( - self, config: FileBasedStreamConfig, file: RemoteFile, stream_reader: AbstractFileBasedStreamReader, logger: logging.Logger - ) -> Dict[str, Any]: - return {} - - -class LowInferenceLimitDiscoveryPolicy(DefaultDiscoveryPolicy): - def get_max_n_files_for_schema_inference(self, parser: FileTypeParser) -> int: - return 1 - - -class LowInferenceBytesJsonlParser(JsonlParser): - MAX_BYTES_PER_FILE_FOR_SCHEMA_INFERENCE = 1 - - -class TestErrorListMatchingFilesInMemoryFilesStreamReader(InMemoryFilesStreamReader): - def get_matching_files( - self, - globs: List[str], - from_date: Optional[datetime] = None, - ) -> List[RemoteFile]: - raise Exception("Error listing files") - - -class TestErrorOpenFileInMemoryFilesStreamReader(InMemoryFilesStreamReader): - def open_file(self, file: RemoteFile, file_read_mode: FileReadMode, encoding: Optional[str], logger: logging.Logger) -> IOBase: - raise Exception("Error opening file") - - -class FailingSchemaValidationPolicy(AbstractSchemaValidationPolicy): - ALWAYS_FAIL = "always_fail" - validate_schema_before_sync = True - - def record_passes_validation_policy(self, record: Mapping[str, Any], schema: Optional[Mapping[str, Any]]) -> bool: - return False - - -class LowHistoryLimitCursor(DefaultFileBasedCursor): - DEFAULT_MAX_HISTORY_SIZE = 3 - - -class LowHistoryLimitConcurrentCursor(FileBasedConcurrentCursor): - DEFAULT_MAX_HISTORY_SIZE = 3 - - -def make_remote_files(files: List[str]) -> List[RemoteFile]: - return [RemoteFile(uri=f, last_modified=datetime.strptime("2023-06-05T03:54:07.000Z", "%Y-%m-%dT%H:%M:%S.%fZ")) for f in files] diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/in_memory_files_source.py b/airbyte-cdk/python/unit_tests/sources/file_based/in_memory_files_source.py deleted file mode 100644 index 0a2681911211..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/in_memory_files_source.py +++ /dev/null @@ -1,231 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import csv -import io -import json -import logging -import tempfile -from datetime import datetime -from io import IOBase -from typing import Any, Iterable, List, Mapping, Optional - -import avro.io as ai -import avro.schema as avro_schema -import pandas as pd -import pyarrow as pa -import pyarrow.parquet as pq -from airbyte_cdk.models import ConfiguredAirbyteCatalog, ConfiguredAirbyteCatalogSerializer -from airbyte_cdk.sources.file_based.availability_strategy import AbstractFileBasedAvailabilityStrategy, DefaultFileBasedAvailabilityStrategy -from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec -from airbyte_cdk.sources.file_based.discovery_policy import AbstractDiscoveryPolicy, DefaultDiscoveryPolicy -from airbyte_cdk.sources.file_based.file_based_source import FileBasedSource -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.schema_validation_policies import DEFAULT_SCHEMA_VALIDATION_POLICIES, AbstractSchemaValidationPolicy -from airbyte_cdk.sources.file_based.stream.cursor import AbstractFileBasedCursor, DefaultFileBasedCursor -from airbyte_cdk.sources.source import TState -from avro import datafile -from pydantic.v1 import AnyUrl - - -class InMemoryFilesSource(FileBasedSource): - _concurrency_level = 10 - - def __init__( - self, - files: Mapping[str, Any], - file_type: str, - availability_strategy: Optional[AbstractFileBasedAvailabilityStrategy], - discovery_policy: Optional[AbstractDiscoveryPolicy], - validation_policies: Mapping[str, AbstractSchemaValidationPolicy], - parsers: Mapping[str, FileTypeParser], - stream_reader: Optional[AbstractFileBasedStreamReader], - catalog: Optional[Mapping[str, Any]], - config: Optional[Mapping[str, Any]], - state: Optional[TState], - file_write_options: Mapping[str, Any], - cursor_cls: Optional[AbstractFileBasedCursor], - ): - # Attributes required for test purposes - self.files = files - self.file_type = file_type - self.catalog = catalog - self.configured_catalog = ConfiguredAirbyteCatalogSerializer.load(self.catalog) if self.catalog else None - self.config = config - self.state = state - - # Source setup - stream_reader = stream_reader or InMemoryFilesStreamReader(files=files, file_type=file_type, file_write_options=file_write_options) - availability_strategy = availability_strategy or DefaultFileBasedAvailabilityStrategy(stream_reader) # type: ignore[assignment] - super().__init__( - stream_reader, - spec_class=InMemorySpec, - catalog=self.configured_catalog, - config=self.config, - state=self.state, - availability_strategy=availability_strategy, - discovery_policy=discovery_policy or DefaultDiscoveryPolicy(), - parsers=parsers, - validation_policies=validation_policies or DEFAULT_SCHEMA_VALIDATION_POLICIES, - cursor_cls=cursor_cls or DefaultFileBasedCursor, - ) - - def read_catalog(self, catalog_path: str) -> ConfiguredAirbyteCatalog: - return self.configured_catalog - - -class InMemoryFilesStreamReader(AbstractFileBasedStreamReader): - def __init__(self, files: Mapping[str, Mapping[str, Any]], file_type: str, file_write_options: Optional[Mapping[str, Any]] = None): - self.files = files - self.file_type = file_type - self.file_write_options = file_write_options - super().__init__() - - @property - def config(self) -> Optional[AbstractFileBasedSpec]: - return self._config - - @config.setter - def config(self, value: AbstractFileBasedSpec) -> None: - self._config = value - - def get_matching_files( - self, - globs: List[str], - prefix: Optional[str], - logger: logging.Logger, - ) -> Iterable[RemoteFile]: - yield from self.filter_files_by_globs_and_start_date( - [ - RemoteFile( - uri=f, - mime_type=data.get("mime_type", None), - last_modified=datetime.strptime(data["last_modified"], "%Y-%m-%dT%H:%M:%S.%fZ"), - ) - for f, data in self.files.items() - ], - globs, - ) - - def open_file(self, file: RemoteFile, mode: FileReadMode, encoding: Optional[str], logger: logging.Logger) -> IOBase: - if self.file_type == "csv": - return self._make_csv_file_contents(file.uri) - elif self.file_type == "jsonl": - return self._make_jsonl_file_contents(file.uri) - elif self.file_type == "unstructured": - return self._make_binary_file_contents(file.uri) - else: - raise NotImplementedError(f"No implementation for file type: {self.file_type}") - - def _make_csv_file_contents(self, file_name: str) -> IOBase: - - # Some tests define the csv as an array of strings to make it easier to validate the handling - # of quotes, delimiter, and escpare chars. - if isinstance(self.files[file_name]["contents"][0], str): - return io.StringIO("\n".join([s.strip() for s in self.files[file_name]["contents"]])) - - fh = io.StringIO() - - if self.file_write_options: - csv.register_dialect("in_memory_dialect", **self.file_write_options) - writer = csv.writer(fh, dialect="in_memory_dialect") - writer.writerows(self.files[file_name]["contents"]) - csv.unregister_dialect("in_memory_dialect") - else: - writer = csv.writer(fh) - writer.writerows(self.files[file_name]["contents"]) - fh.seek(0) - return fh - - def _make_jsonl_file_contents(self, file_name: str) -> IOBase: - fh = io.BytesIO() - - for line in self.files[file_name]["contents"]: - try: - fh.write((json.dumps(line) + "\n").encode("utf-8")) - except TypeError: - # Intentionally trigger json validation error - fh.write((str(line) + "\n").encode("utf-8")) - fh.seek(0) - return fh - - def _make_binary_file_contents(self, file_name: str) -> IOBase: - fh = io.BytesIO() - - fh.write(self.files[file_name]["contents"]) - fh.seek(0) - return fh - - -class InMemorySpec(AbstractFileBasedSpec): - @classmethod - def documentation_url(cls) -> AnyUrl: - return AnyUrl(scheme="https", url="https://docs.airbyte.com/integrations/sources/in_memory_files") # type: ignore - - -class TemporaryParquetFilesStreamReader(InMemoryFilesStreamReader): - """ - A file reader that writes RemoteFiles to a temporary file and then reads them back. - """ - - def open_file(self, file: RemoteFile, mode: FileReadMode, encoding: Optional[str], logger: logging.Logger) -> IOBase: - return io.BytesIO(self._create_file(file.uri)) - - def _create_file(self, file_name: str) -> bytes: - contents = self.files[file_name]["contents"] - schema = self.files[file_name].get("schema") - - df = pd.DataFrame(contents[1:], columns=contents[0]) - with tempfile.TemporaryFile() as fp: - table = pa.Table.from_pandas(df, schema) - pq.write_table(table, fp) - - fp.seek(0) - return fp.read() - - -class TemporaryAvroFilesStreamReader(InMemoryFilesStreamReader): - """ - A file reader that writes RemoteFiles to a temporary file and then reads them back. - """ - - def open_file(self, file: RemoteFile, mode: FileReadMode, encoding: Optional[str], logger: logging.Logger) -> IOBase: - return io.BytesIO(self._make_file_contents(file.uri)) - - def _make_file_contents(self, file_name: str) -> bytes: - contents = self.files[file_name]["contents"] - schema = self.files[file_name]["schema"] - stream_schema = avro_schema.make_avsc_object(schema) - - rec_writer = ai.DatumWriter(stream_schema) - with tempfile.TemporaryFile() as fp: - file_writer = datafile.DataFileWriter(fp, rec_writer, stream_schema) - for content in contents: - data = {col["name"]: content[i] for i, col in enumerate(schema["fields"])} - file_writer.append(data) - file_writer.flush() - fp.seek(0) - return fp.read() - - -class TemporaryExcelFilesStreamReader(InMemoryFilesStreamReader): - """ - A file reader that writes RemoteFiles to a temporary file and then reads them back. - """ - - def open_file(self, file: RemoteFile, mode: FileReadMode, encoding: Optional[str], logger: logging.Logger) -> IOBase: - return io.BytesIO(self._make_file_contents(file.uri)) - - def _make_file_contents(self, file_name: str) -> bytes: - contents = self.files[file_name]["contents"] - df = pd.DataFrame(contents) - - with io.BytesIO() as fp: - writer = pd.ExcelWriter(fp, engine="xlsxwriter") - df.to_excel(writer, index=False, sheet_name="Sheet1") - writer._save() - fp.seek(0) - return fp.read() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/__init__.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/avro_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/avro_scenarios.py deleted file mode 100644 index 7b891a168f7a..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/avro_scenarios.py +++ /dev/null @@ -1,750 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import datetime -import decimal - -from unit_tests.sources.file_based.in_memory_files_source import TemporaryAvroFilesStreamReader -from unit_tests.sources.file_based.scenarios.file_based_source_builder import FileBasedSourceBuilder -from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenarioBuilder - -_single_avro_file = { - "a.avro": { - "schema": { - "type": "record", - "name": "sampleAvro", - "fields": [ - {"name": "col1", "type": "string"}, - {"name": "col2", "type": "int"}, - ], - }, - "contents": [ - ("val11", 12), - ("val21", 22), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } -} - -_multiple_avro_combine_schema_file = { - "a.avro": { - "schema": { - "type": "record", - "name": "sampleAvro", - "fields": [ - {"name": "col_double", "type": "double"}, - {"name": "col_string", "type": "string"}, - {"name": "col_album", "type": {"type": "record", "name": "Album", "fields": [{"name": "album", "type": "string"}]}}, - ], - }, - "contents": [ - (20.02, "Robbers", {"album": "The 1975"}), - (20.23, "Somebody Else", {"album": "I Like It When You Sleep, for You Are So Beautiful yet So Unaware of It"}), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.avro": { - "schema": { - "type": "record", - "name": "sampleAvro", - "fields": [ - {"name": "col_double", "type": "double"}, - {"name": "col_string", "type": "string"}, - {"name": "col_song", "type": {"type": "record", "name": "Song", "fields": [{"name": "title", "type": "string"}]}}, - ], - }, - "contents": [ - (1975.1975, "It's Not Living (If It's Not with You)", {"title": "Love It If We Made It"}), - (5791.5791, "The 1975", {"title": "About You"}), - ], - "last_modified": "2023-06-06T03:54:07.000Z", - }, -} - -_avro_all_types_file = { - "a.avro": { - "schema": { - "type": "record", - "name": "sampleAvro", - "fields": [ - # Primitive Types - {"name": "col_bool", "type": "boolean"}, - {"name": "col_int", "type": "int"}, - {"name": "col_long", "type": "long"}, - {"name": "col_float", "type": "float"}, - {"name": "col_double", "type": "double"}, - {"name": "col_bytes", "type": "bytes"}, - {"name": "col_string", "type": "string"}, - # Complex Types - { - "name": "col_record", - "type": { - "type": "record", - "name": "SongRecord", - "fields": [ - {"name": "artist", "type": "string"}, - {"name": "song", "type": "string"}, - {"name": "year", "type": "int"}, - ], - }, - }, - {"name": "col_enum", "type": {"type": "enum", "name": "Genre", "symbols": ["POP_ROCK", "INDIE_ROCK", "ALTERNATIVE_ROCK"]}}, - {"name": "col_array", "type": {"type": "array", "items": "string"}}, - {"name": "col_map", "type": {"type": "map", "values": "string"}}, - {"name": "col_fixed", "type": {"type": "fixed", "name": "MyFixed", "size": 4}}, - # Logical Types - {"name": "col_decimal", "type": {"type": "bytes", "logicalType": "decimal", "precision": 10, "scale": 5}}, - {"name": "col_uuid", "type": {"type": "string", "logicalType": "uuid"}}, - {"name": "col_date", "type": {"type": "int", "logicalType": "date"}}, - {"name": "col_time_millis", "type": {"type": "int", "logicalType": "time-millis"}}, - {"name": "col_time_micros", "type": {"type": "long", "logicalType": "time-micros"}}, - {"name": "col_timestamp_millis", "type": {"type": "long", "logicalType": "timestamp-millis"}}, - {"name": "col_timestamp_micros", "type": {"type": "long", "logicalType": "timestamp-micros"}}, - ], - }, - "contents": [ - ( - True, - 27, - 1992, - 999.09723456, - 9123456.12394, - b"\x00\x01\x02\x03", - "Love It If We Made It", - {"artist": "The 1975", "song": "About You", "year": 2022}, - "POP_ROCK", - [ - "The 1975", - "I Like It When You Sleep, for You Are So Beautiful yet So Unaware of It", - "The 1975 A Brief Inquiry into Online Relationships", - "Notes on a Conditional Form", - "Being Funny in a Foreign Language", - ], - {"lead_singer": "Matty Healy", "lead_guitar": "Adam Hann", "bass_guitar": "Ross MacDonald", "drummer": "George Daniel"}, - b"\x12\x34\x56\x78", - decimal.Decimal("1234.56789"), - "123e4567-e89b-12d3-a456-426655440000", - datetime.date(2022, 5, 29), - datetime.time(6, 0, 0, 456000), - datetime.time(12, 0, 0, 456789), - datetime.datetime(2022, 5, 29, 0, 0, 0, 456000, tzinfo=datetime.timezone.utc), - datetime.datetime(2022, 5, 30, 0, 0, 0, 456789, tzinfo=datetime.timezone.utc), - ), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } -} - -_multiple_avro_stream_file = { - "odesza_songs.avro": { - "schema": { - "type": "record", - "name": "sampleAvro", - "fields": [ - {"name": "col_title", "type": "string"}, - { - "name": "col_album", - "type": { - "type": "enum", - "name": "Album", - "symbols": ["SUMMERS_GONE", "IN_RETURN", "A_MOMENT_APART", "THE_LAST_GOODBYE"], - }, - }, - {"name": "col_year", "type": "int"}, - {"name": "col_vocals", "type": "boolean"}, - ], - }, - "contents": [ - ("Late Night", "A_MOMENT_APART", 2017, False), - ("White Lies", "IN_RETURN", 2014, True), - ("Wide Awake", "THE_LAST_GOODBYE", 2022, True), - ("Sun Models", "SUMMERS_GONE", 2012, True), - ("All We Need", "IN_RETURN", 2014, True), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "california_festivals.avro": { - "schema": { - "type": "record", - "name": "sampleAvro", - "fields": [ - {"name": "col_name", "type": "string"}, - { - "name": "col_location", - "type": { - "type": "record", - "name": "LocationRecord", - "fields": [ - {"name": "country", "type": "string"}, - {"name": "state", "type": "string"}, - {"name": "city", "type": "string"}, - ], - }, - }, - {"name": "col_attendance", "type": "long"}, - ], - }, - "contents": [ - ("Coachella", {"country": "USA", "state": "California", "city": "Indio"}, 250000), - ("CRSSD", {"country": "USA", "state": "California", "city": "San Diego"}, 30000), - ("Lightning in a Bottle", {"country": "USA", "state": "California", "city": "Buena Vista Lake"}, 18000), - ("Outside Lands", {"country": "USA", "state": "California", "city": "San Francisco"}, 220000), - ], - "last_modified": "2023-06-06T03:54:07.000Z", - }, -} - -single_avro_scenario = ( - TestScenarioBuilder() - .set_name("single_avro_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "avro"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryAvroFilesStreamReader(files=_single_avro_file, file_type="avro")) - .set_file_type("avro") - ) - .set_expected_check_status("SUCCEEDED") - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": 12, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.avro", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21", - "col2": 22, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.avro", - }, - "stream": "stream1", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "integer"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) -).build() - -multiple_avro_combine_schema_scenario = ( - TestScenarioBuilder() - .set_name("multiple_avro_combine_schema_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "avro"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryAvroFilesStreamReader(files=_multiple_avro_combine_schema_file, file_type="avro")) - .set_file_type("avro") - ) - .set_expected_records( - [ - { - "data": { - "col_double": 20.02, - "col_string": "Robbers", - "col_album": {"album": "The 1975"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.avro", - }, - "stream": "stream1", - }, - { - "data": { - "col_double": 20.23, - "col_string": "Somebody Else", - "col_album": {"album": "I Like It When You Sleep, for You Are So Beautiful yet So Unaware of It"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.avro", - }, - "stream": "stream1", - }, - { - "data": { - "col_double": 1975.1975, - "col_string": "It's Not Living (If It's Not with You)", - "col_song": {"title": "Love It If We Made It"}, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.avro", - }, - "stream": "stream1", - }, - { - "data": { - "col_double": 5791.5791, - "col_string": "The 1975", - "col_song": {"title": "About You"}, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.avro", - }, - "stream": "stream1", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col_double": {"type": ["null", "number"]}, - "col_string": {"type": ["null", "string"]}, - "col_album": { - "properties": { - "album": {"type": ["null", "string"]}, - }, - "type": ["null", "object"], - }, - "col_song": { - "properties": { - "title": {"type": ["null", "string"]}, - }, - "type": ["null", "object"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) -).build() - -avro_all_types_scenario = ( - TestScenarioBuilder() - .set_name("avro_all_types_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "avro"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryAvroFilesStreamReader(files=_avro_all_types_file, file_type="avro")) - .set_file_type("avro") - ) - .set_expected_records( - [ - { - "data": { - "col_bool": True, - "col_int": 27, - "col_long": 1992, - "col_float": 999.09723456, - "col_double": 9123456.12394, - "col_bytes": "\x00\x01\x02\x03", - "col_string": "Love It If We Made It", - "col_record": {"artist": "The 1975", "song": "About You", "year": 2022}, - "col_enum": "POP_ROCK", - "col_array": [ - "The 1975", - "I Like It When You Sleep, for You Are So Beautiful yet So Unaware of It", - "The 1975 A Brief Inquiry into Online Relationships", - "Notes on a Conditional Form", - "Being Funny in a Foreign Language", - ], - "col_map": { - "lead_singer": "Matty Healy", - "lead_guitar": "Adam Hann", - "bass_guitar": "Ross MacDonald", - "drummer": "George Daniel", - }, - "col_fixed": "\x12\x34\x56\x78", - "col_decimal": "1234.56789", - "col_uuid": "123e4567-e89b-12d3-a456-426655440000", - "col_date": "2022-05-29", - "col_time_millis": "06:00:00.456000", - "col_time_micros": "12:00:00.456789", - "col_timestamp_millis": "2022-05-29T00:00:00.456+00:00", - "col_timestamp_micros": "2022-05-30T00:00:00.456789+00:00", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.avro", - }, - "stream": "stream1", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col_array": {"items": {"type": ["null", "string"]}, "type": ["null", "array"]}, - "col_bool": {"type": ["null", "boolean"]}, - "col_bytes": {"type": ["null", "string"]}, - "col_double": {"type": ["null", "number"]}, - "col_enum": {"enum": ["POP_ROCK", "INDIE_ROCK", "ALTERNATIVE_ROCK"], "type": ["null", "string"]}, - "col_fixed": {"pattern": "^[0-9A-Fa-f]{8}$", "type": ["null", "string"]}, - "col_float": {"type": ["null", "number"]}, - "col_int": {"type": ["null", "integer"]}, - "col_long": {"type": ["null", "integer"]}, - "col_map": {"additionalProperties": {"type": ["null", "string"]}, "type": ["null", "object"]}, - "col_record": { - "properties": { - "artist": {"type": ["null", "string"]}, - "song": {"type": ["null", "string"]}, - "year": {"type": ["null", "integer"]}, - }, - "type": ["null", "object"], - }, - "col_string": {"type": ["null", "string"]}, - "col_decimal": {"pattern": "^-?\\d{(1, 5)}(?:\\.\\d(1, 5))?$", "type": ["null", "string"]}, - "col_uuid": {"type": ["null", "string"]}, - "col_date": {"format": "date", "type": ["null", "string"]}, - "col_time_millis": {"type": ["null", "integer"]}, - "col_time_micros": {"type": ["null", "integer"]}, - "col_timestamp_millis": {"format": "date-time", "type": ["null", "string"]}, - "col_timestamp_micros": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) -).build() - -multiple_streams_avro_scenario = ( - TestScenarioBuilder() - .set_name("multiple_streams_avro_stream") - .set_config( - { - "streams": [ - { - "name": "songs_stream", - "format": {"filetype": "avro"}, - "globs": ["*_songs.avro"], - "validation_policy": "Emit Record", - }, - { - "name": "festivals_stream", - "format": {"filetype": "avro"}, - "globs": ["*_festivals.avro"], - "validation_policy": "Emit Record", - }, - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryAvroFilesStreamReader(files=_multiple_avro_stream_file, file_type="avro")) - .set_file_type("avro") - ) - .set_expected_records( - [ - { - "data": { - "col_title": "Late Night", - "col_album": "A_MOMENT_APART", - "col_year": 2017, - "col_vocals": False, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "odesza_songs.avro", - }, - "stream": "songs_stream", - }, - { - "data": { - "col_title": "White Lies", - "col_album": "IN_RETURN", - "col_year": 2014, - "col_vocals": True, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "odesza_songs.avro", - }, - "stream": "songs_stream", - }, - { - "data": { - "col_title": "Wide Awake", - "col_album": "THE_LAST_GOODBYE", - "col_year": 2022, - "col_vocals": True, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "odesza_songs.avro", - }, - "stream": "songs_stream", - }, - { - "data": { - "col_title": "Sun Models", - "col_album": "SUMMERS_GONE", - "col_year": 2012, - "col_vocals": True, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "odesza_songs.avro", - }, - "stream": "songs_stream", - }, - { - "data": { - "col_title": "All We Need", - "col_album": "IN_RETURN", - "col_year": 2014, - "col_vocals": True, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "odesza_songs.avro", - }, - "stream": "songs_stream", - }, - { - "data": { - "col_name": "Coachella", - "col_location": {"country": "USA", "state": "California", "city": "Indio"}, - "col_attendance": 250000, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "california_festivals.avro", - }, - "stream": "festivals_stream", - }, - { - "data": { - "col_name": "CRSSD", - "col_location": {"country": "USA", "state": "California", "city": "San Diego"}, - "col_attendance": 30000, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "california_festivals.avro", - }, - "stream": "festivals_stream", - }, - { - "data": { - "col_name": "Lightning in a Bottle", - "col_location": {"country": "USA", "state": "California", "city": "Buena Vista Lake"}, - "col_attendance": 18000, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "california_festivals.avro", - }, - "stream": "festivals_stream", - }, - { - "data": { - "col_name": "Outside Lands", - "col_location": {"country": "USA", "state": "California", "city": "San Francisco"}, - "col_attendance": 220000, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "california_festivals.avro", - }, - "stream": "festivals_stream", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col_title": {"type": ["null", "string"]}, - "col_album": { - "type": ["null", "string"], - "enum": ["SUMMERS_GONE", "IN_RETURN", "A_MOMENT_APART", "THE_LAST_GOODBYE"], - }, - "col_year": {"type": ["null", "integer"]}, - "col_vocals": {"type": ["null", "boolean"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "songs_stream", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col_name": {"type": ["null", "string"]}, - "col_location": { - "properties": { - "country": {"type": ["null", "string"]}, - "state": {"type": ["null", "string"]}, - "city": {"type": ["null", "string"]}, - }, - "type": ["null", "object"], - }, - "col_attendance": {"type": ["null", "integer"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "festivals_stream", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - ] - } - ) -).build() - -avro_file_with_double_as_number_scenario = ( - TestScenarioBuilder() - .set_name("avro_file_with_double_as_number_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "format": {"filetype": "avro", "double_as_string": False}, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryAvroFilesStreamReader(files=_multiple_avro_combine_schema_file, file_type="avro")) - .set_file_type("avro") - ) - .set_expected_records( - [ - { - "data": { - "col_double": 20.02, - "col_string": "Robbers", - "col_album": {"album": "The 1975"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.avro", - }, - "stream": "stream1", - }, - { - "data": { - "col_double": 20.23, - "col_string": "Somebody Else", - "col_album": {"album": "I Like It When You Sleep, for You Are So Beautiful yet So Unaware of It"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.avro", - }, - "stream": "stream1", - }, - { - "data": { - "col_double": 1975.1975, - "col_string": "It's Not Living (If It's Not with You)", - "col_song": {"title": "Love It If We Made It"}, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.avro", - }, - "stream": "stream1", - }, - { - "data": { - "col_double": 5791.5791, - "col_string": "The 1975", - "col_song": {"title": "About You"}, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.avro", - }, - "stream": "stream1", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col_double": {"type": ["null", "number"]}, - "col_string": {"type": ["null", "string"]}, - "col_album": { - "properties": { - "album": {"type": ["null", "string"]}, - }, - "type": ["null", "object"], - }, - "col_song": { - "properties": { - "title": {"type": ["null", "string"]}, - }, - "type": ["null", "object"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) -).build() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/check_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/check_scenarios.py deleted file mode 100644 index 26136d9cf025..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/check_scenarios.py +++ /dev/null @@ -1,220 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.file_based.exceptions import FileBasedSourceError -from unit_tests.sources.file_based.helpers import ( - FailingSchemaValidationPolicy, - TestErrorListMatchingFilesInMemoryFilesStreamReader, - TestErrorOpenFileInMemoryFilesStreamReader, -) -from unit_tests.sources.file_based.scenarios.file_based_source_builder import FileBasedSourceBuilder -from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenarioBuilder - -_base_success_scenario = ( - TestScenarioBuilder() - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_check_status("SUCCEEDED") -) - - -success_csv_scenario = (_base_success_scenario.copy().set_name("success_csv_scenario")).build() - - -success_multi_stream_scenario = ( - _base_success_scenario.copy() - .set_name("success_multi_stream_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv", "*.gz"], - "validation_policy": "Emit Record", - }, - { - "name": "stream2", - "format": {"filetype": "csv"}, - "globs": ["*.csv", "*.gz"], - "validation_policy": "Emit Record", - }, - ] - } - ) -).build() - - -success_extensionless_scenario = ( - _base_success_scenario.copy() - .set_name("success_extensionless_file_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - _base_success_scenario.source_builder.copy().set_files( - { - "a": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - ) -).build() - - -success_user_provided_schema_scenario = ( - _base_success_scenario.copy() - .set_name("success_user_provided_schema_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "string", "col2": "string"}', - } - ], - } - ) -).build() - - -_base_failure_scenario = _base_success_scenario.copy().set_expected_check_status("FAILED") - - -error_empty_stream_scenario = ( - _base_failure_scenario.copy() - .set_name("error_empty_stream_scenario") - .set_source_builder(_base_failure_scenario.copy().source_builder.copy().set_files({})) - .set_expected_check_error(None, FileBasedSourceError.EMPTY_STREAM.value) -).build() - - -error_listing_files_scenario = ( - _base_failure_scenario.copy() - .set_name("error_listing_files_scenario") - .set_source_builder( - _base_failure_scenario.source_builder.copy().set_stream_reader( - TestErrorListMatchingFilesInMemoryFilesStreamReader(files=_base_failure_scenario.source_builder._files, file_type="csv") - ) - ) - .set_expected_check_error(None, FileBasedSourceError.ERROR_LISTING_FILES.value) -).build() - - -error_reading_file_scenario = ( - _base_failure_scenario.copy() - .set_name("error_reading_file_scenario") - .set_source_builder( - _base_failure_scenario.source_builder.copy().set_stream_reader( - TestErrorOpenFileInMemoryFilesStreamReader(files=_base_failure_scenario.source_builder._files, file_type="csv") - ) - ) - .set_expected_check_error(None, FileBasedSourceError.ERROR_READING_FILE.value) -).build() - - -error_record_validation_user_provided_schema_scenario = ( - _base_failure_scenario.copy() - .set_name("error_record_validation_user_provided_schema_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "always_fail", - "input_schema": '{"col1": "number", "col2": "string"}', - } - ], - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - .set_validation_policies({FailingSchemaValidationPolicy.ALWAYS_FAIL: FailingSchemaValidationPolicy()}) - ) - .set_expected_check_error(None, FileBasedSourceError.ERROR_VALIDATING_RECORD.value) -).build() - - -error_multi_stream_scenario = ( - _base_failure_scenario.copy() - .set_name("error_multi_stream_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - }, - { - "name": "stream2", - "format": {"filetype": "jsonl"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - }, - ], - } - ) - .set_expected_check_error(None, FileBasedSourceError.ERROR_READING_FILE.value) -).build() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/concurrent_incremental_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/concurrent_incremental_scenarios.py deleted file mode 100644 index e5a7ee419452..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/concurrent_incremental_scenarios.py +++ /dev/null @@ -1,2865 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.file_based.stream.concurrent.cursor import FileBasedConcurrentCursor -from airbyte_cdk.test.state_builder import StateBuilder -from unit_tests.sources.file_based.helpers import LowHistoryLimitConcurrentCursor -from unit_tests.sources.file_based.scenarios.file_based_source_builder import FileBasedSourceBuilder -from unit_tests.sources.file_based.scenarios.scenario_builder import IncrementalScenarioConfig, TestScenarioBuilder - -single_csv_input_state_is_earlier_scenario_concurrent = ( - TestScenarioBuilder() - .set_name("single_csv_input_state_is_earlier_concurrent") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - .set_cursor_cls(FileBasedConcurrentCursor) - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": {"some_old_file.csv": "2023-06-01T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-01T03:54:07.000000Z_some_old_file.csv", - }, - ) - .build(), - ) - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21", - "col2": "val22", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "history": {"some_old_file.csv": "2023-06-01T03:54:07.000000Z", "a.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_a.csv", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - } - ] - } - ) -).build() - -single_csv_file_is_skipped_if_same_modified_at_as_in_history_concurrent = ( - TestScenarioBuilder() - .set_name("single_csv_file_is_skipped_if_same_modified_at_as_in_history_concurrent") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - .set_cursor_cls(FileBasedConcurrentCursor) - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_a.csv", - }, - ) - .build(), - ) - ) - .set_expected_records( - [ - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_a.csv", - } - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - } - ] - } - ) -).build() - -single_csv_file_is_synced_if_modified_at_is_more_recent_than_in_history_concurrent = ( - TestScenarioBuilder() - .set_name("single_csv_file_is_synced_if_modified_at_is_more_recent_than_in_history_concurrent") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - .set_cursor_cls(FileBasedConcurrentCursor) - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": {"a.csv": "2023-06-01T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-01T03:54:07.000000Z_a.csv", - }, - ) - .build(), - ) - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21", - "col2": "val22", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_a.csv", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - } - ] - } - ) -).build() - -single_csv_no_input_state_scenario_concurrent = ( - TestScenarioBuilder() - .set_name("single_csv_input_state_is_earlier_again_concurrent") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - } - } - ) - .set_file_type("csv") - .set_cursor_cls(FileBasedConcurrentCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21", - "col2": "val22", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_a.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=[], - ) - ) -).build() - -multi_csv_same_timestamp_scenario_concurrent = ( - TestScenarioBuilder() - .set_name("multi_csv_same_timestamp_concurrent") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(FileBasedConcurrentCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z", "b.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_b.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=[], - ) - ) -).build() - -single_csv_input_state_is_later_scenario_concurrent = ( - TestScenarioBuilder() - .set_name("single_csv_input_state_is_later_concurrent") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - } - } - ) - .set_file_type("csv") - .set_cursor_cls(FileBasedConcurrentCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21", - "col2": "val22", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "history": { - "recent_file.csv": "2023-07-15T23:59:59.000000Z", - "a.csv": "2023-06-05T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-07-15T23:59:59.000000Z_recent_file.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": {"recent_file.csv": "2023-07-15T23:59:59.000000Z"}, - "_ab_source_file_last_modified": "2023-07-15T23:59:59.000000Z_recent_file.csv", - }, - ) - .build(), - ) - ) -).build() - -multi_csv_different_timestamps_scenario_concurrent = ( - TestScenarioBuilder() - .set_name("multi_csv_stream_different_timestamps_concurrent") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-04T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(FileBasedConcurrentCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-04T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-04T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "history": { - "a.csv": "2023-06-04T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-04T03:54:07.000000Z_a.csv", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": {"a.csv": "2023-06-04T03:54:07.000000Z", "b.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_b.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=[], - ) - ) -).build() - -multi_csv_per_timestamp_scenario_concurrent = ( - TestScenarioBuilder() - .set_name("multi_csv_per_timestamp_concurrent") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-06T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(FileBasedConcurrentCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z", "b.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_b.csv", - }, - { - "data": { - "col1": "val11c", - "col2": "val12c", - "col3": "val13c", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21c", - "col2": "val22c", - "col3": "val23c", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "history": { - "a.csv": "2023-06-05T03:54:07.000000Z", - "b.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-06T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z_c.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=[], - ) - ) -).build() - -multi_csv_skip_file_if_already_in_history_concurrent = ( - TestScenarioBuilder() - .set_name("skip_files_already_in_history_concurrent") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-06T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(FileBasedConcurrentCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - # {"data": {"col1": "val11a", "col2": "val12a"}, "stream": "stream1"}, # this file is skipped - # {"data": {"col1": "val21a", "col2": "val22a"}, "stream": "stream1"}, # this file is skipped - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z", "b.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_b.csv", - }, - { - "data": { - "col1": "val11c", - "col2": "val12c", - "col3": "val13c", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21c", - "col2": "val22c", - "col3": "val23c", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "history": { - "a.csv": "2023-06-05T03:54:07.000000Z", - "b.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-06T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z_c.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - {"history": {"a.csv": "2023-06-05T03:54:07.000000Z"}, "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_a.csv"}, - ) - .build(), - ) - ) -).build() - -multi_csv_include_missing_files_within_history_range_concurrent_cursor_is_newer = ( - TestScenarioBuilder() - .set_name("multi_csv_include_missing_files_within_history_range_concurrent_cursor_is_newer") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-06T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(FileBasedConcurrentCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - # {"data": {"col1": "val11a", "col2": "val12a"}, "stream": "stream1"}, # this file is skipped - # {"data": {"col1": "val21a", "col2": "val22a"}, "stream": "stream1"}, # this file is skipped - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - # {"data": {"col1": "val11c", "col2": "val12c", "col3": "val13c"}, "stream": "stream1"}, # this file is skipped - # {"data": {"col1": "val21c", "col2": "val22c", "col3": "val23c"}, "stream": "stream1"}, # this file is skipped - { - "history": { - "a.csv": "2023-06-05T03:54:07.000000Z", - "b.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-06T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z_c.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z", "c.csv": "2023-06-06T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z_c.csv", - }, - ) - .build(), - ) - ) -).build() - -multi_csv_include_missing_files_within_history_range_concurrent_cursor_is_older = ( - TestScenarioBuilder() - .set_name("multi_csv_include_missing_files_within_history_range_concurrent_cursor_is_older") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-06T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(FileBasedConcurrentCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - # {"data": {"col1": "val11a", "col2": "val12a"}, "stream": "stream1"}, # this file is skipped - # {"data": {"col1": "val21a", "col2": "val22a"}, "stream": "stream1"}, # this file is skipped - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - # {"data": {"col1": "val11c", "col2": "val12c", "col3": "val13c"}, "stream": "stream1"}, # this file is skipped - # {"data": {"col1": "val21c", "col2": "val22c", "col3": "val23c"}, "stream": "stream1"}, # this file is skipped - { - "history": { - "a.csv": "2023-06-05T03:54:07.000000Z", - "b.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-06T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z_c.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z", "c.csv": "2023-06-06T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-03T03:54:07.000000Z_x.csv", - }, - ) - .build() - ) - ) -).build() - -multi_csv_remove_old_files_if_history_is_full_scenario_concurrent_cursor_is_newer = ( - TestScenarioBuilder() - .set_name("multi_csv_remove_old_files_if_history_is_full_scenario_concurrent_cursor_is_newer") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-06T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-07T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-10T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(LowHistoryLimitConcurrentCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "history": { - "very_old_file.csv": "2023-06-02T03:54:07.000000Z", - "old_file_same_timestamp_as_a.csv": "2023-06-06T03:54:07.000000Z", - "a.csv": "2023-06-06T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z_old_file_same_timestamp_as_a.csv", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-07T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-07T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": { - "old_file_same_timestamp_as_a.csv": "2023-06-06T03:54:07.000000Z", - "a.csv": "2023-06-06T03:54:07.000000Z", - "b.csv": "2023-06-07T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-07T03:54:07.000000Z_b.csv", - }, - { - "data": { - "col1": "val11c", - "col2": "val12c", - "col3": "val13c", - "_ab_source_file_last_modified": "2023-06-10T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21c", - "col2": "val22c", - "col3": "val23c", - "_ab_source_file_last_modified": "2023-06-10T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "history": { - "old_file_same_timestamp_as_a.csv": "2023-06-06T03:54:07.000000Z", - "b.csv": "2023-06-07T03:54:07.000000Z", - "c.csv": "2023-06-10T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-10T03:54:07.000000Z_c.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": { - "very_very_old_file.csv": "2023-06-01T03:54:07.000000Z", - "very_old_file.csv": "2023-06-02T03:54:07.000000Z", - "old_file_same_timestamp_as_a.csv": "2023-06-06T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z_old_file_same_timestamp_as_a.csv", - }, - ) - .build(), - ) - ) -).build() - -multi_csv_remove_old_files_if_history_is_full_scenario_concurrent_cursor_is_older = ( - TestScenarioBuilder() - .set_name("multi_csv_remove_old_files_if_history_is_full_scenario_concurrent_cursor_is_older") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-06T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-07T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-10T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(LowHistoryLimitConcurrentCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "history": { - "very_old_file.csv": "2023-06-02T03:54:07.000000Z", - "old_file_same_timestamp_as_a.csv": "2023-06-06T03:54:07.000000Z", - "a.csv": "2023-06-06T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z_old_file_same_timestamp_as_a.csv", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-07T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-07T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": { - "old_file_same_timestamp_as_a.csv": "2023-06-06T03:54:07.000000Z", - "a.csv": "2023-06-06T03:54:07.000000Z", - "b.csv": "2023-06-07T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-07T03:54:07.000000Z_b.csv", - }, - { - "data": { - "col1": "val11c", - "col2": "val12c", - "col3": "val13c", - "_ab_source_file_last_modified": "2023-06-10T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21c", - "col2": "val22c", - "col3": "val23c", - "_ab_source_file_last_modified": "2023-06-10T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "history": { - "old_file_same_timestamp_as_a.csv": "2023-06-06T03:54:07.000000Z", - "b.csv": "2023-06-07T03:54:07.000000Z", - "c.csv": "2023-06-10T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-10T03:54:07.000000Z_c.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": { - "very_very_old_file.csv": "2023-06-01T03:54:07.000000Z", - "very_old_file.csv": "2023-06-02T03:54:07.000000Z", - "old_file_same_timestamp_as_a.csv": "2023-06-06T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-05-01T03:54:07.000000Z_very_very_very_old_file.csv", - }, - ) - .build(), - ) - ) -).build() - -multi_csv_same_timestamp_more_files_than_history_size_scenario_concurrent_cursor_is_newer = ( - TestScenarioBuilder() - .set_name("multi_csv_same_timestamp_more_files_than_history_size_scenario_concurrent_cursor_is_newer") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - "days_to_sync_if_history_is_full": 3, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "d.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11d", "val12d", "val13d"), - ("val21d", "val22d", "val23d"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(LowHistoryLimitConcurrentCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11c", - "col2": "val12c", - "col3": "val13c", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21c", - "col2": "val22c", - "col3": "val23c", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11d", - "col2": "val12d", - "col3": "val13d", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "d.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21d", - "col2": "val22d", - "col3": "val23d", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "d.csv", - }, - "stream": "stream1", - }, - { - "history": { - "b.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-05T03:54:07.000000Z", - "d.csv": "2023-06-05T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_d.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=[], - ) - ) -).build() - -multi_csv_same_timestamp_more_files_than_history_size_scenario_concurrent_cursor_is_older = ( - TestScenarioBuilder() - .set_name("multi_csv_same_timestamp_more_files_than_history_size_scenario_concurrent_cursor_is_older") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - "days_to_sync_if_history_is_full": 3, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "d.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11d", "val12d", "val13d"), - ("val21d", "val22d", "val23d"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(LowHistoryLimitConcurrentCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11c", - "col2": "val12c", - "col3": "val13c", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21c", - "col2": "val22c", - "col3": "val23c", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11d", - "col2": "val12d", - "col3": "val13d", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "d.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21d", - "col2": "val22d", - "col3": "val23d", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "d.csv", - }, - "stream": "stream1", - }, - { - "history": { - "b.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-05T03:54:07.000000Z", - "d.csv": "2023-06-05T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_d.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=[], - ) - ) -).build() - -multi_csv_sync_recent_files_if_history_is_incomplete_scenario_concurrent_cursor_is_older = ( - TestScenarioBuilder() - .set_name("multi_csv_sync_recent_files_if_history_is_incomplete_scenario_concurrent_cursor_is_older") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - "days_to_sync_if_history_is_full": 3, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "d.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11d", "val12d", "val13d"), - ("val21d", "val22d", "val23d"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - } - ) - .set_cursor_cls(LowHistoryLimitConcurrentCursor) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "history": { - "b.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-05T03:54:07.000000Z", - "d.csv": "2023-06-05T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_d.csv", - } - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": { - "b.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-05T03:54:07.000000Z", - "d.csv": "2023-06-05T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_b.csv", - }, - ) - .build(), - ) - ) -).build() - -multi_csv_sync_recent_files_if_history_is_incomplete_scenario_concurrent_cursor_is_newer = ( - TestScenarioBuilder() - .set_name("multi_csv_sync_recent_files_if_history_is_incomplete_scenario_concurrent_cursor_is_newer") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - "days_to_sync_if_history_is_full": 3, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "d.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11d", "val12d", "val13d"), - ("val21d", "val22d", "val23d"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - } - ) - .set_cursor_cls(LowHistoryLimitConcurrentCursor) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "history": { - "b.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-05T03:54:07.000000Z", - "d.csv": "2023-06-05T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_d.csv", - } - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": { - "b.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-05T03:54:07.000000Z", - "d.csv": "2023-06-05T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_d.csv", - }, - ) - .build(), - ) - ) -).build() - - -multi_csv_sync_files_within_time_window_if_history_is_incomplete__different_timestamps_scenario_concurrent_cursor_is_older = ( - TestScenarioBuilder() - .set_name("multi_csv_sync_files_within_time_window_if_history_is_incomplete__different_timestamps_scenario_concurrent_cursor_is_older") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - "days_to_sync_if_history_is_full": 3, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-06T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-07T03:54:07.000000Z", - }, - "d.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11d", "val12d", "val13d"), - ("val21d", "val22d", "val23d"), - ], - "last_modified": "2023-06-08T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(LowHistoryLimitConcurrentCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - # {"data": {"col1": "val11a", "col2": "val12a"}, "stream": "stream1"}, # This file is skipped because it is older than the time_window - # {"data": {"col1": "val21a", "col2": "val22a"}, "stream": "stream1"}, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": { - "c.csv": "2023-06-07T03:54:07.000000Z", - "d.csv": "2023-06-08T03:54:07.000000Z", - "e.csv": "2023-06-08T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-08T03:54:07.000000Z_e.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": { - "c.csv": "2023-06-07T03:54:07.000000Z", - "d.csv": "2023-06-08T03:54:07.000000Z", - "e.csv": "2023-06-08T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-08T03:54:07.000000Z_e.csv", - }, - ) - .build(), - ) - ) -).build() - -multi_csv_sync_files_within_time_window_if_history_is_incomplete__different_timestamps_scenario_concurrent_cursor_is_newer = ( - TestScenarioBuilder() - .set_name("multi_csv_sync_files_within_time_window_if_history_is_incomplete__different_timestamps_scenario_concurrent_cursor_is_newer") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - "days_to_sync_if_history_is_full": 3, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-06T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-07T03:54:07.000000Z", - }, - "d.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11d", "val12d", "val13d"), - ("val21d", "val22d", "val23d"), - ], - "last_modified": "2023-06-08T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(LowHistoryLimitConcurrentCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - # {"data": {"col1": "val11a", "col2": "val12a"}, "stream": "stream1"}, # This file is skipped because it is older than the time_window - # {"data": {"col1": "val21a", "col2": "val22a"}, "stream": "stream1"}, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": { - "c.csv": "2023-06-07T03:54:07.000000Z", - "d.csv": "2023-06-08T03:54:07.000000Z", - "e.csv": "2023-06-08T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-08T03:54:07.000000Z_e.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": { - "c.csv": "2023-06-07T03:54:07.000000Z", - "d.csv": "2023-06-08T03:54:07.000000Z", - "e.csv": "2023-06-08T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-08T03:54:07.000000Z_e.csv", - }, - ) - .build(), - ) - ) -).build() - -multi_csv_sync_files_within_history_time_window_if_history_is_incomplete_different_timestamps_scenario_concurrent_cursor_is_newer = ( - TestScenarioBuilder() - .set_name( - "multi_csv_sync_files_within_history_time_window_if_history_is_incomplete_different_timestamps_scenario_concurrent_cursor_is_newer" - ) - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - "days_to_sync_if_history_is_full": 3, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-06T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-07T03:54:07.000000Z", - }, - "d.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11d", "val12d", "val13d"), - ("val21d", "val22d", "val23d"), - ], - "last_modified": "2023-06-08T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(LowHistoryLimitConcurrentCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "history": { - "a.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-07T03:54:07.000000Z", - "d.csv": "2023-06-08T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-08T03:54:07.000000Z_d.csv", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": { - "b.csv": "2023-06-06T03:54:07.000000Z", - "c.csv": "2023-06-07T03:54:07.000000Z", - "d.csv": "2023-06-08T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-08T03:54:07.000000Z_d.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": { - "old_file.csv": "2023-06-05T00:00:00.000000Z", - "c.csv": "2023-06-07T03:54:07.000000Z", - "d.csv": "2023-06-08T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-08T03:54:07.000000Z_d.csv", - }, - ) - .build(), - ) - ) -).build() - -multi_csv_sync_files_within_history_time_window_if_history_is_incomplete_different_timestamps_scenario_concurrent_cursor_is_older = ( - TestScenarioBuilder() - .set_name( - "multi_csv_sync_files_within_history_time_window_if_history_is_incomplete_different_timestamps_scenario_concurrent_cursor_is_older" - ) - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - "days_to_sync_if_history_is_full": 3, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-06T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-07T03:54:07.000000Z", - }, - "d.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11d", "val12d", "val13d"), - ("val21d", "val22d", "val23d"), - ], - "last_modified": "2023-06-08T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(LowHistoryLimitConcurrentCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "history": { - "a.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-07T03:54:07.000000Z", - "d.csv": "2023-06-08T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-08T03:54:07.000000Z_d.csv", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": { - "b.csv": "2023-06-06T03:54:07.000000Z", - "c.csv": "2023-06-07T03:54:07.000000Z", - "d.csv": "2023-06-08T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-08T03:54:07.000000Z_d.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": { - "old_file.csv": "2023-06-05T00:00:00.000000Z", - "c.csv": "2023-06-07T03:54:07.000000Z", - "d.csv": "2023-06-08T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-04T00:00:00.000000Z_very_old_file.csv", - }, - ) - .build(), - ) - ) -).build() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py deleted file mode 100644 index 3f0579677f2a..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py +++ /dev/null @@ -1,3342 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.models import AirbyteAnalyticsTraceMessage, SyncMode -from airbyte_cdk.sources.file_based.config.csv_format import CsvFormat -from airbyte_cdk.sources.file_based.exceptions import ConfigValidationError, FileBasedSourceError -from airbyte_cdk.test.catalog_builder import CatalogBuilder -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from unit_tests.sources.file_based.helpers import EmptySchemaParser, LowInferenceLimitDiscoveryPolicy -from unit_tests.sources.file_based.in_memory_files_source import InMemoryFilesSource -from unit_tests.sources.file_based.scenarios.file_based_source_builder import FileBasedSourceBuilder -from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenario, TestScenarioBuilder - -single_csv_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("single_csv_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_spec( - { - "documentationUrl": "https://docs.airbyte.com/integrations/sources/in_memory_files", - "connectionSpecification": { - "title": "InMemorySpec", - "description": "Used during spec; allows the developer to configure the cloud provider specific options\nthat are needed when users configure a file-based source.", - "type": "object", - "properties": { - "start_date": { - "title": "Start Date", - "description": "UTC date and time in the format 2017-01-25T00:00:00.000000Z. Any file modified before this date will not be replicated.", - "examples": ["2021-01-01T00:00:00.000000Z"], - "format": "date-time", - "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{6}Z$", - "pattern_descriptor": "YYYY-MM-DDTHH:mm:ss.SSSSSSZ", - "order": 1, - "type": "string", - }, - "streams": { - "title": "The list of streams to sync", - "description": 'Each instance of this configuration defines a stream. Use this to define which files belong in the stream, their format, and how they should be parsed and validated. When sending data to warehouse destination such as Snowflake or BigQuery, each stream is a separate table.', - "order": 10, - "type": "array", - "items": { - "title": "FileBasedStreamConfig", - "type": "object", - "properties": { - "name": {"title": "Name", "description": "The name of the stream.", "type": "string"}, - "globs": { - "title": "Globs", - "description": 'The pattern used to specify which files should be selected from the file system. For more information on glob pattern matching look here.', - "type": "array", - "items": {"type": "string"}, - "order": 1, - "default": ["**"], - }, - "legacy_prefix": { - "title": "Legacy Prefix", - "airbyte_hidden": True, - "type": "string", - "description": "The path prefix configured in v3 versions of the S3 connector. This option is deprecated in favor of a single glob.", - }, - "validation_policy": { - "title": "Validation Policy", - "description": "The name of the validation policy that dictates sync behavior when a record does not adhere to the stream schema.", - "default": "Emit Record", - "enum": ["Emit Record", "Skip Record", "Wait for Discover"], - }, - "input_schema": { - "title": "Input Schema", - "description": "The schema that will be used to validate records extracted from the file. This will override the stream schema that is auto-detected from incoming files.", - "type": "string", - }, - "primary_key": { - "title": "Primary Key", - "description": "The column or columns (for a composite key) that serves as the unique identifier of a record. If empty, the primary key will default to the parser's default primary key.", - "type": "string", - "airbyte_hidden": True, - }, - "days_to_sync_if_history_is_full": { - "title": "Days To Sync If History Is Full", - "description": "When the state history of the file store is full, syncs will only read files that were last modified in the provided day range.", - "default": 3, - "type": "integer", - }, - "format": { - "title": "Format", - "description": "The configuration options that are used to alter how to read incoming files that deviate from the standard formatting.", - "type": "object", - "oneOf": [ - { - "title": "Avro Format", - "type": "object", - "properties": { - "filetype": {"title": "Filetype", "default": "avro", "const": "avro", "type": "string"}, - "double_as_string": { - "title": "Convert Double Fields to Strings", - "description": "Whether to convert double fields to strings. This is recommended if you have decimal numbers with a high degree of precision because there can be a loss precision when handling floating point numbers.", - "default": False, - "type": "boolean", - }, - }, - "required": ["filetype"], - }, - { - "title": "CSV Format", - "type": "object", - "properties": { - "filetype": {"title": "Filetype", "default": "csv", "const": "csv", "type": "string"}, - "delimiter": { - "title": "Delimiter", - "description": "The character delimiting individual cells in the CSV data. This may only be a 1-character string. For tab-delimited data enter '\\t'.", - "default": ",", - "type": "string", - }, - "quote_char": { - "title": "Quote Character", - "description": "The character used for quoting CSV values. To disallow quoting, make this field blank.", - "default": '"', - "type": "string", - }, - "escape_char": { - "title": "Escape Character", - "description": "The character used for escaping special characters. To disallow escaping, leave this field blank.", - "type": "string", - }, - "encoding": { - "title": "Encoding", - "description": 'The character encoding of the CSV data. Leave blank to default to UTF8. See list of python encodings for allowable options.', - "default": "utf8", - "type": "string", - }, - "double_quote": { - "title": "Double Quote", - "description": "Whether two quotes in a quoted CSV value denote a single quote in the data.", - "default": True, - "type": "boolean", - }, - "null_values": { - "title": "Null Values", - "description": "A set of case-sensitive strings that should be interpreted as null values. For example, if the value 'NA' should be interpreted as null, enter 'NA' in this field.", - "default": [], - "type": "array", - "items": {"type": "string"}, - "uniqueItems": True, - }, - "strings_can_be_null": { - "title": "Strings Can Be Null", - "description": "Whether strings can be interpreted as null values. If true, strings that match the null_values set will be interpreted as null. If false, strings that match the null_values set will be interpreted as the string itself.", - "default": True, - "type": "boolean", - }, - "skip_rows_before_header": { - "title": "Skip Rows Before Header", - "description": "The number of rows to skip before the header row. For example, if the header row is on the 3rd row, enter 2 in this field.", - "default": 0, - "type": "integer", - }, - "skip_rows_after_header": { - "title": "Skip Rows After Header", - "description": "The number of rows to skip after the header row.", - "default": 0, - "type": "integer", - }, - "header_definition": { - "title": "CSV Header Definition", - "type": "object", - "description": "How headers will be defined. `User Provided` assumes the CSV does not have a header row and uses the headers provided and `Autogenerated` assumes the CSV does not have a header row and the CDK will generate headers using for `f{i}` where `i` is the index starting from 0. Else, the default behavior is to use the header from the CSV file. If a user wants to autogenerate or provide column names for a CSV having headers, they can skip rows.", - "default": {"header_definition_type": "From CSV"}, - "oneOf": [ - { - "title": "From CSV", - "type": "object", - "properties": { - "header_definition_type": { - "title": "Header Definition Type", - "default": "From CSV", - "const": "From CSV", - "type": "string", - }, - }, - "required": ["header_definition_type"], - }, - { - "title": "Autogenerated", - "type": "object", - "properties": { - "header_definition_type": { - "title": "Header Definition Type", - "default": "Autogenerated", - "const": "Autogenerated", - "type": "string", - }, - }, - "required": ["header_definition_type"], - }, - { - "title": "User Provided", - "type": "object", - "properties": { - "header_definition_type": { - "title": "Header Definition Type", - "default": "User Provided", - "const": "User Provided", - "type": "string", - }, - "column_names": { - "title": "Column Names", - "description": "The column names that will be used while emitting the CSV records", - "type": "array", - "items": {"type": "string"}, - }, - }, - "required": ["column_names", "header_definition_type"], - }, - ], - }, - "true_values": { - "title": "True Values", - "description": "A set of case-sensitive strings that should be interpreted as true values.", - "default": ["y", "yes", "t", "true", "on", "1"], - "type": "array", - "items": {"type": "string"}, - "uniqueItems": True, - }, - "false_values": { - "title": "False Values", - "description": "A set of case-sensitive strings that should be interpreted as false values.", - "default": ["n", "no", "f", "false", "off", "0"], - "type": "array", - "items": {"type": "string"}, - "uniqueItems": True, - }, - "inference_type": { - "title": "Inference Type", - "description": "How to infer the types of the columns. If none, inference default to strings.", - "default": "None", - "airbyte_hidden": True, - "enum": ["None", "Primitive Types Only"], - }, - "ignore_errors_on_fields_mismatch": { - "type": "boolean", - "title": "Ignore errors on field mismatch", - "default": False, - "description": "Whether to ignore errors that occur when the number of fields in the CSV does not match the number of columns in the schema.", - }, - }, - "required": ["filetype"], - }, - { - "title": "Jsonl Format", - "type": "object", - "properties": { - "filetype": {"title": "Filetype", "default": "jsonl", "const": "jsonl", "type": "string"} - }, - "required": ["filetype"], - }, - { - "title": "Parquet Format", - "type": "object", - "properties": { - "filetype": { - "title": "Filetype", - "default": "parquet", - "const": "parquet", - "type": "string", - }, - "decimal_as_float": { - "title": "Convert Decimal Fields to Floats", - "description": "Whether to convert decimal fields to floats. There is a loss of precision when converting decimals to floats, so this is not recommended.", - "default": False, - "type": "boolean", - }, - }, - "required": ["filetype"], - }, - { - "title": "Unstructured Document Format", - "type": "object", - "properties": { - "filetype": { - "title": "Filetype", - "default": "unstructured", - "const": "unstructured", - "type": "string", - }, - "skip_unprocessable_files": { - "type": "boolean", - "default": True, - "title": "Skip Unprocessable Files", - "description": "If true, skip files that cannot be parsed and pass the error message along as the _ab_source_file_parse_error field. If false, fail the sync.", - "always_show": True, - }, - "strategy": { - "type": "string", - "always_show": True, - "order": 0, - "default": "auto", - "title": "Parsing Strategy", - "enum": ["auto", "fast", "ocr_only", "hi_res"], - "description": "The strategy used to parse documents. `fast` extracts text directly from the document which doesn't work for all files. `ocr_only` is more reliable, but slower. `hi_res` is the most reliable, but requires an API key and a hosted instance of unstructured and can't be used with local mode. See the unstructured.io documentation for more details: https://unstructured-io.github.io/unstructured/core/partition.html#partition-pdf", - }, - "processing": { - "title": "Processing", - "description": "Processing configuration", - "default": {"mode": "local"}, - "type": "object", - "oneOf": [ - { - "title": "Local", - "type": "object", - "properties": { - "mode": { - "title": "Mode", - "default": "local", - "const": "local", - "enum": ["local"], - "type": "string", - } - }, - "description": "Process files locally, supporting `fast` and `ocr` modes. This is the default option.", - "required": ["mode"], - }, - { - "title": "via API", - "type": "object", - "properties": { - "mode": { - "title": "Mode", - "default": "api", - "const": "api", - "enum": ["api"], - "type": "string", - }, - "api_key": { - "title": "API Key", - "description": "The API key to use matching the environment", - "default": "", - "always_show": True, - "airbyte_secret": True, - "type": "string", - }, - "api_url": { - "title": "API URL", - "description": "The URL of the unstructured API to use", - "default": "https://api.unstructured.io", - "always_show": True, - "examples": ["https://api.unstructured.com"], - "type": "string", - }, - "parameters": { - "title": "Additional URL Parameters", - "description": "List of parameters send to the API", - "default": [], - "always_show": True, - "type": "array", - "items": { - "title": "APIParameterConfigModel", - "type": "object", - "properties": { - "name": { - "title": "Parameter name", - "description": "The name of the unstructured API parameter to use", - "examples": ["combine_under_n_chars", "languages"], - "type": "string", - }, - "value": { - "title": "Value", - "description": "The value of the parameter", - "examples": ["true", "hi_res"], - "type": "string", - }, - }, - "required": ["name", "value"], - }, - }, - }, - "description": "Process files via an API, using the `hi_res` mode. This option is useful for increased performance and accuracy, but requires an API key and a hosted instance of unstructured.", - "required": ["mode"], - }, - ], - }, - }, - "description": "Extract text from document formats (.pdf, .docx, .md, .pptx) and emit as one record per file.", - "required": ["filetype"], - }, - { - "title": "Excel Format", - "type": "object", - "properties": { - "filetype": {"title": "Filetype", "default": "excel", "const": "excel", "type": "string"} - }, - "required": ["filetype"], - }, - ], - }, - "schemaless": { - "title": "Schemaless", - "description": "When enabled, syncs will not validate or structure records against the stream's schema.", - "default": False, - "type": "boolean", - }, - "recent_n_files_to_read_for_schema_discovery": { - "title": "Files To Read For Schema Discover", - "description": "The number of resent files which will be used to discover the schema for this stream.", - "exclusiveMinimum": 0, - "type": "integer", - }, - }, - "required": ["name", "format"], - }, - }, - }, - "required": ["streams"], - }, - "supportsDBT": False, - "supportsNormalization": False, - } - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21", - "col2": "val22", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -csv_analytics_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_analytics") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["a.csv"], - "validation_policy": "Emit Record", - }, - { - "name": "stream2", - "format": {"filetype": "csv"}, - "globs": ["b.csv"], - "validation_policy": "Emit Record", - }, - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "col3": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream2", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream2", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream2", - }, - ] - ) - .set_expected_analytics( - [ - AirbyteAnalyticsTraceMessage(type="file-cdk-csv-stream-count", value="2"), - ] - ) -).build() - -multi_csv_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("multi_csv_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "col3": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -multi_csv_stream_n_file_exceeds_limit_for_inference = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("multi_csv_stream_n_file_exceeds_limit_for_inference") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("csv") - .set_discovery_policy(LowInferenceLimitDiscoveryPolicy()) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -multi_csv_stream_n_file_exceeds_config_limit_for_inference = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("multi_csv_stream_n_file_exceeds_config_limit_for_inference") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*"], - "validation_policy": "Emit Record", - "recent_n_files_to_read_for_schema_discovery": 3, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3", "col4"), - ("val11c", "val12c", "val13c", "val14c"), - ("val21c", "val22c", "val23c", "val24c"), - ], - "last_modified": "2023-06-06T03:54:07.000Z", - }, - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "col3": {"type": ["null", "string"]}, - "col4": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11c", - "col2": "val12c", - "col3": "val13c", - "col4": "val14c", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21c", - "col2": "val22c", - "col3": "val23c", - "col4": "val24c", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -invalid_csv_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("invalid_csv_scenario") # too many values for the number of headers - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1",), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records([]) - .set_expected_discover_error(AirbyteTracedException, FileBasedSourceError.SCHEMA_INFERENCE_ERROR.value) - .set_expected_logs( - { - "read": [ - { - "level": "ERROR", - "message": f"{FileBasedSourceError.INVALID_SCHEMA_ERROR.value} stream=stream1 file=a.csv line_no=1 n_skipped=0", - }, - ] - } - ) - .set_expected_read_error( - AirbyteTracedException, - "Please check the logged errors for more information.", - ) -).build() - -invalid_csv_multi_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("invalid_csv_multi_scenario") # too many values for the number of headers - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*"], - "validation_policy": "Emit Record", - }, - { - "name": "stream2", - "format": {"filetype": "csv"}, - "globs": ["b.csv"], - "validation_policy": "Emit Record", - }, - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1",), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.csv": { - "contents": [ - ("col3",), - ("val13b", "val14b"), - ("val23b", "val24b"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - { - "json_schema": { - "type": "object", - "properties": { - "col3": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream2", - "source_defined_cursor": True, - "default_cursor_field": ["_ab_source_file_last_modified"], - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - ] - } - ) - .set_expected_records([]) - .set_expected_discover_error(AirbyteTracedException, FileBasedSourceError.SCHEMA_INFERENCE_ERROR.value) - .set_expected_logs( - { - "read": [ - { - "level": "ERROR", - "message": f"{FileBasedSourceError.ERROR_PARSING_RECORD.value} stream=stream1 file=a.csv line_no=1 n_skipped=0", - }, - { - "level": "ERROR", - "message": f"{FileBasedSourceError.ERROR_PARSING_RECORD.value} stream=stream2 file=b.csv line_no=1 n_skipped=0", - }, - ] - } - ) - .set_expected_read_error(AirbyteTracedException, "Please check the logged errors for more information.") -).build() - -csv_single_stream_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_single_stream_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.jsonl": { - "contents": [ - {"col1": "val11b", "col2": "val12b", "col3": "val13b"}, - {"col1": "val12b", "col2": "val22b", "col3": "val23b"}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "source_defined_cursor": True, - "default_cursor_field": ["_ab_source_file_last_modified"], - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -csv_multi_stream_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_multi_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - }, - { - "name": "stream2", - "format": {"filetype": "csv"}, - "globs": ["b.csv"], - "validation_policy": "Emit Record", - }, - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.csv": { - "contents": [ - ("col3",), - ("val13b",), - ("val23b",), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "col3": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "source_defined_cursor": True, - "default_cursor_field": ["_ab_source_file_last_modified"], - }, - { - "json_schema": { - "type": "object", - "properties": { - "col3": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream2", - "source_defined_cursor": True, - "default_cursor_field": ["_ab_source_file_last_modified"], - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": {"col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "b.csv"}, - "stream": "stream1", - }, - { - "data": {"col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "b.csv"}, - "stream": "stream1", - }, - { - "data": {"col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "b.csv"}, - "stream": "stream2", - }, - { - "data": {"col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "b.csv"}, - "stream": "stream2", - }, - ] - ) -).build() - -csv_custom_format_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_custom_format") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "format": { - "filetype": "csv", - "delimiter": "#", - "quote_char": "|", - "escape_char": "!", - "double_quote": True, - }, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11", "val12", "val |13|"), - ("val21", "val22", "val23"), - ("val,31", "val |,32|", "val, !!!! 33"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - .set_file_write_options( - { - "delimiter": "#", - "quotechar": "|", - } - ) - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "default_cursor_field": ["_ab_source_file_last_modified"], - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "col3": "val |13|", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21", - "col2": "val22", - "col3": "val23", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val,31", - "col2": "val |,32|", - "col3": "val, !! 33", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -multi_stream_custom_format = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("multi_stream_custom_format_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*.csv"], - "validation_policy": "Emit Record", - "format": {"filetype": "csv", "delimiter": "#", "escape_char": "!", "double_quote": True, "newlines_in_values": False}, - }, - { - "name": "stream2", - "globs": ["b.csv"], - "validation_policy": "Emit Record", - "format": { - "filetype": "csv", - "delimiter": "#", - "escape_char": "@", - "double_quote": True, - "newlines_in_values": False, - }, - }, - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val !! 12a"), - ("val !! 21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.csv": { - "contents": [ - ("col3",), - ("val @@@@ 13b",), - ("val23b",), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("csv") - .set_file_write_options( - { - "delimiter": "#", - } - ) - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "source_defined_cursor": True, - "default_cursor_field": ["_ab_source_file_last_modified"], - }, - { - "json_schema": { - "type": "object", - "properties": { - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream2", - "source_defined_cursor": True, - "default_cursor_field": ["_ab_source_file_last_modified"], - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val ! 12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val ! 21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col3": "val @@@@ 13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": {"col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "b.csv"}, - "stream": "stream1", - }, - { - "data": { - "col3": "val @@ 13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream2", - }, - { - "data": {"col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "b.csv"}, - "stream": "stream2", - }, - ] - ) -).build() - -empty_schema_inference_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("empty_schema_inference_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - .set_parsers({CsvFormat: EmptySchemaParser()}) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_discover_error(AirbyteTracedException, FileBasedSourceError.SCHEMA_INFERENCE_ERROR.value) -).build() - -schemaless_csv_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("schemaless_csv_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*"], - "validation_policy": "Skip Record", - "schemaless": True, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "data": {"type": "object"}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "data": {"col1": "val11a", "col2": "val12a"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "data": {"col1": "val21a", "col2": "val22a"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "data": {"col1": "val11b", "col2": "val12b", "col3": "val13b"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "data": {"col1": "val21b", "col2": "val22b", "col3": "val23b"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -schemaless_csv_multi_stream_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("schemaless_csv_multi_stream_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["a.csv"], - "validation_policy": "Skip Record", - "schemaless": True, - }, - { - "name": "stream2", - "format": {"filetype": "csv"}, - "globs": ["b.csv"], - "validation_policy": "Skip Record", - }, - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.csv": { - "contents": [ - ("col3",), - ("val13b",), - ("val23b",), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "data": {"type": "object"}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "source_defined_cursor": True, - "default_cursor_field": ["_ab_source_file_last_modified"], - }, - { - "json_schema": { - "type": "object", - "properties": { - "col3": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream2", - "source_defined_cursor": True, - "default_cursor_field": ["_ab_source_file_last_modified"], - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - ] - } - ) - .set_expected_records( - [ - { - "data": { - "data": {"col1": "val11a", "col2": "val12a"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "data": {"col1": "val21a", "col2": "val22a"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": {"col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "b.csv"}, - "stream": "stream2", - }, - { - "data": {"col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "b.csv"}, - "stream": "stream2", - }, - ] - ) -).build() - -schemaless_with_user_input_schema_fails_connection_check_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("schemaless_with_user_input_schema_fails_connection_check_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*"], - "validation_policy": "Skip Record", - "input_schema": '{"col1": "string", "col2": "string", "col3": "string"}', - "schemaless": True, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("csv") - ) - .set_catalog(CatalogBuilder().with_stream("stream1", SyncMode.full_refresh).build()) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "data": {"type": "object"}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_check_status("FAILED") - .set_expected_check_error(None, FileBasedSourceError.CONFIG_VALIDATION_ERROR.value) - .set_expected_discover_error(ConfigValidationError, FileBasedSourceError.CONFIG_VALIDATION_ERROR.value) - .set_expected_read_error(ConfigValidationError, FileBasedSourceError.CONFIG_VALIDATION_ERROR.value) -).build() - -schemaless_with_user_input_schema_fails_connection_check_multi_stream_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("schemaless_with_user_input_schema_fails_connection_check_multi_stream_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["a.csv"], - "validation_policy": "Skip Record", - "schemaless": True, - "input_schema": '{"col1": "string", "col2": "string", "col3": "string"}', - }, - { - "name": "stream2", - "format": {"filetype": "csv"}, - "globs": ["b.csv"], - "validation_policy": "Skip Record", - }, - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.csv": { - "contents": [ - ("col3",), - ("val13b",), - ("val23b",), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("csv") - ) - .set_catalog(CatalogBuilder().with_stream("stream1", SyncMode.full_refresh).with_stream("stream2", SyncMode.full_refresh).build()) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "data": {"type": "object"}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "source_defined_cursor": True, - "default_cursor_field": ["_ab_source_file_last_modified"], - }, - { - "json_schema": { - "type": "object", - "properties": { - "col3": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream2", - "source_defined_cursor": True, - "default_cursor_field": ["_ab_source_file_last_modified"], - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - ] - } - ) - .set_expected_check_status("FAILED") - .set_expected_check_error(None, FileBasedSourceError.CONFIG_VALIDATION_ERROR.value) - .set_expected_discover_error(ConfigValidationError, FileBasedSourceError.CONFIG_VALIDATION_ERROR.value) - .set_expected_read_error(ConfigValidationError, FileBasedSourceError.CONFIG_VALIDATION_ERROR.value) -).build() - -csv_string_can_be_null_with_input_schemas_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_string_can_be_null_with_input_schema") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "string", "col2": "string"}', - "format": { - "filetype": "csv", - "null_values": ["null"], - }, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("2", "null"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": "string"}, - "col2": {"type": "string"}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "2", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -csv_string_are_not_null_if_strings_can_be_null_is_false_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_string_are_not_null_if_strings_can_be_null_is_false") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "string", "col2": "string"}', - "format": { - "filetype": "csv", - "null_values": ["null"], - "strings_can_be_null": False, - }, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("2", "null"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": "string"}, - "col2": {"type": "string"}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "2", - "col2": "null", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -csv_string_not_null_if_no_null_values_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_string_not_null_if_no_null_values") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "format": { - "filetype": "csv", - }, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("2", "null"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "2", - "col2": "null", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -csv_strings_can_be_null_not_quoted_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_strings_can_be_null_no_input_schema") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "format": {"filetype": "csv", "null_values": ["null"]}, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("2", "null"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "2", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -csv_newline_in_values_quoted_value_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_newline_in_values_quoted_value") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "format": { - "filetype": "csv", - }, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - '''"col1","col2"''', - '''"2","val\n2"''', - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "2", - "col2": "val\n2", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -csv_newline_in_values_not_quoted_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_newline_in_values_not_quoted") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "format": { - "filetype": "csv", - }, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - """col1,col2""", - """2,val\n2""", - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - # Note that the value for col2 is truncated to "val" because the newline is not escaped - { - "data": { - "col1": "2", - "col2": "val", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) - .set_expected_read_error( - AirbyteTracedException, - f"{FileBasedSourceError.ERROR_PARSING_RECORD.value} stream=stream1 file=a.csv line_no=2 n_skipped=0", - ) - .set_expected_discover_error(AirbyteTracedException, FileBasedSourceError.SCHEMA_INFERENCE_ERROR.value) - .set_expected_read_error( - AirbyteTracedException, - "Please check the logged errors for more information.", - ) -).build() - -csv_escape_char_is_set_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_escape_char_is_set") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "format": { - "filetype": "csv", - "double_quotes": False, - "quote_char": '"', - "delimiter": ",", - "escape_char": "\\", - }, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - """col1,col2""", - '''val11,"val\\"2"''', - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": 'val"2', - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -csv_double_quote_is_set_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_doublequote_is_set") - # This scenario tests that quotes are properly escaped when double_quotes is True - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "format": { - "filetype": "csv", - "double_quotes": True, - "quote_char": '"', - "delimiter": ",", - }, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - """col1,col2""", - '''val11,"val""2"''', - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": 'val"2', - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -csv_custom_delimiter_with_escape_char_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_custom_delimiter_with_escape_char") - # This scenario tests that a value can contain the delimiter if it is wrapped in the quote_char - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "format": {"filetype": "csv", "double_quotes": True, "quote_char": "@", "delimiter": "|", "escape_char": "+"}, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - """col1|col2""", - """val"1,1|val+|2""", - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": 'val"1,1', - "col2": "val|2", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -csv_custom_delimiter_in_double_quotes_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_custom_delimiter_in_double_quotes") - # This scenario tests that a value can contain the delimiter if it is wrapped in the quote_char - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "format": { - "filetype": "csv", - "double_quotes": True, - "quote_char": "@", - "delimiter": "|", - }, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - """col1|col2""", - """val"1,1|@val|2@""", - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": 'val"1,1', - "col2": "val|2", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -csv_skip_before_header_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_skip_before_header") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "format": {"filetype": "csv", "skip_rows_before_header": 2}, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("skip_this", "skip_this"), - ("skip_this_too", "skip_this_too"), - ("col1", "col2"), - ("val11", "val12"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -csv_skip_after_header_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_skip_after_header") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "format": {"filetype": "csv", "skip_rows_after_header": 2}, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("skip_this", "skip_this"), - ("skip_this_too", "skip_this_too"), - ("val11", "val12"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -csv_skip_before_and_after_header_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_skip_before_after_header") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "format": { - "filetype": "csv", - "skip_rows_before_header": 1, - "skip_rows_after_header": 1, - }, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("skip_this", "skip_this"), - ("col1", "col2"), - ("skip_this_too", "skip_this_too"), - ("val11", "val12"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -csv_autogenerate_column_names_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_autogenerate_column_names") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "format": { - "filetype": "csv", - "header_definition": {"header_definition_type": "Autogenerated"}, - }, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("val11", "val12"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "f0": {"type": ["null", "string"]}, - "f1": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "f0": "val11", - "f1": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -csv_custom_bool_values_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_custom_bool_values") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "boolean", "col2": "boolean"}', - "format": { - "filetype": "csv", - "true_values": ["this_is_true"], - "false_values": ["this_is_false"], - }, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("this_is_true", "this_is_false"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": "boolean"}, - "col2": {"type": "boolean"}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": True, - "col2": False, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -csv_custom_null_values_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_custom_null_values") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "boolean", "col2": "string"}', - "format": { - "filetype": "csv", - "null_values": ["null"], - }, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("null", "na"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": "boolean"}, - "col2": {"type": "string"}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col2": "na", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -).build() - -earlier_csv_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("earlier_csv_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ], - "start_date": "2023-06-10T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_check_status("FAILED") - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - "data": {"type": "object"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records(None) -).build() - -csv_no_records_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("csv_empty_no_records") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "boolean", "col2": "string"}', - "format": { - "filetype": "csv", - "null_values": ["null"], - }, - } - ], - "start_date": "2023-06-04T03:54:07.000000Z", - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [("col1", "col2")], # column headers, but no data rows - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": "boolean"}, - "col2": {"type": "string"}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records([]) -).build() - -csv_no_files_scenario: TestScenario[InMemoryFilesSource] = ( - TestScenarioBuilder[InMemoryFilesSource]() - .set_name("no_files_csv_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ], - "start_date": "2023-06-10T03:54:07.000000Z", - } - ) - .set_source_builder(FileBasedSourceBuilder().set_files({}).set_file_type("csv")) - .set_expected_check_status("FAILED") - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - "data": {"type": "object"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records(None) -).build() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/excel_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/excel_scenarios.py deleted file mode 100644 index 6653296535d5..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/excel_scenarios.py +++ /dev/null @@ -1,436 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -import datetime - -from unit_tests.sources.file_based.in_memory_files_source import TemporaryExcelFilesStreamReader -from unit_tests.sources.file_based.scenarios.file_based_source_builder import FileBasedSourceBuilder -from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenarioBuilder - -_single_excel_file = { - "a.xlsx": { - "contents": [ - {"col1": "val11", "col2": "val12"}, - {"col1": "val21", "col2": "val22"}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } -} - -_multiple_excel_combine_schema_file = { - "a.xlsx": { - "contents": [ - {"col_double": 20.02, "col_string": "Robbers", "col_album": "The 1975"}, - { - "col_double": 20.23, - "col_string": "Somebody Else", - "col_album": "I Like It When You Sleep, for You Are So Beautiful yet So Unaware of It", - }, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.xlsx": { - "contents": [ - {"col_double": 1975.1975, "col_string": "It's Not Living (If It's Not with You)", "col_song": "Love It If We Made It"}, - {"col_double": 5791.5791, "col_string": "The 1975", "col_song": "About You"}, - ], - "last_modified": "2023-06-06T03:54:07.000Z", - }, -} - -_excel_all_types_file = { - "a.xlsx": { - "contents": [ - { - "col_bool": True, - "col_int": 27, - "col_long": 1992, - "col_float": 999.09723456, - "col_string": "Love It If We Made It", - "col_date": datetime.date(2022, 5, 29), - "col_time_millis": datetime.time(6, 0, 0, 456000), - "col_time_micros": datetime.time(12, 0, 0, 456789), - } - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } -} - -_multiple_excel_stream_file = { - "odesza_songs.xlsx": { - "contents": [ - {"col_title": "Late Night", "col_album": "A_MOMENT_APART", "col_year": 2017, "col_vocals": False}, - {"col_title": "White Lies", "col_album": "IN_RETURN", "col_year": 2014, "col_vocals": True}, - {"col_title": "Wide Awake", "col_album": "THE_LAST_GOODBYE", "col_year": 2022, "col_vocals": True}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "california_festivals.xlsx": { - "contents": [ - { - "col_name": "Lightning in a Bottle", - "col_location": {"country": "USA", "state": "California", "city": "Buena Vista Lake"}, - "col_attendance": 18000, - }, - { - "col_name": "Outside Lands", - "col_location": {"country": "USA", "state": "California", "city": "San Francisco"}, - "col_attendance": 220000, - }, - ], - "last_modified": "2023-06-06T03:54:07.000Z", - }, -} - -single_excel_scenario = ( - TestScenarioBuilder() - .set_name("single_excel_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "excel"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryExcelFilesStreamReader(files=_single_excel_file, file_type="excel")) - .set_file_type("excel") - ) - .set_expected_check_status("SUCCEEDED") - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.xlsx", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21", - "col2": "val22", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.xlsx", - }, - "stream": "stream1", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) -).build() - -multiple_excel_combine_schema_scenario = ( - TestScenarioBuilder() - .set_name("multiple_excel_combine_schema_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "excel"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryExcelFilesStreamReader(files=_multiple_excel_combine_schema_file, file_type="excel")) - .set_file_type("excel") - ) - .set_expected_records( - [ - { - "data": { - "col_double": 20.02, - "col_string": "Robbers", - "col_album": "The 1975", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.xlsx", - }, - "stream": "stream1", - }, - { - "data": { - "col_double": 20.23, - "col_string": "Somebody Else", - "col_album": "I Like It When You Sleep, for You Are So Beautiful yet So Unaware of It", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.xlsx", - }, - "stream": "stream1", - }, - { - "data": { - "col_double": 1975.1975, - "col_string": "It's Not Living (If It's Not with You)", - "col_song": "Love It If We Made It", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.xlsx", - }, - "stream": "stream1", - }, - { - "data": { - "col_double": 5791.5791, - "col_string": "The 1975", - "col_song": "About You", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.xlsx", - }, - "stream": "stream1", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col_double": {"type": ["null", "number"]}, - "col_string": {"type": ["null", "string"]}, - "col_album": {"type": ["null", "string"]}, - "col_song": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) -).build() - -excel_all_types_scenario = ( - TestScenarioBuilder() - .set_name("excel_all_types_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "excel"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryExcelFilesStreamReader(files=_excel_all_types_file, file_type="excel")) - .set_file_type("excel") - ) - .set_expected_records( - [ - { - "data": { - "col_bool": True, - "col_int": 27, - "col_long": 1992, - "col_float": 999.09723456, - "col_string": "Love It If We Made It", - "col_date": "2022-05-29T00:00:00.000000", - "col_time_millis": "06:00:00.456000", - "col_time_micros": "12:00:00.456789", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.xlsx", - }, - "stream": "stream1", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col_bool": {"type": ["null", "boolean"]}, - "col_int": {"type": ["null", "number"]}, - "col_long": {"type": ["null", "number"]}, - "col_float": {"type": ["null", "number"]}, - "col_string": {"type": ["null", "string"]}, - "col_date": {"format": "date-time", "type": ["null", "string"]}, - "col_time_millis": {"type": ["null", "string"]}, - "col_time_micros": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) -).build() - -multiple_streams_excel_scenario = ( - TestScenarioBuilder() - .set_name("multiple_streams_excel_stream") - .set_config( - { - "streams": [ - { - "name": "songs_stream", - "format": {"filetype": "excel"}, - "globs": ["*_songs.xlsx"], - "validation_policy": "Emit Record", - }, - { - "name": "festivals_stream", - "format": {"filetype": "excel"}, - "globs": ["*_festivals.xlsx"], - "validation_policy": "Emit Record", - }, - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryExcelFilesStreamReader(files=_multiple_excel_stream_file, file_type="excel")) - .set_file_type("excel") - ) - .set_expected_records( - [ - { - "data": { - "col_title": "Late Night", - "col_album": "A_MOMENT_APART", - "col_year": 2017, - "col_vocals": False, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "odesza_songs.xlsx", - }, - "stream": "songs_stream", - }, - { - "data": { - "col_title": "White Lies", - "col_album": "IN_RETURN", - "col_year": 2014, - "col_vocals": True, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "odesza_songs.xlsx", - }, - "stream": "songs_stream", - }, - { - "data": { - "col_title": "Wide Awake", - "col_album": "THE_LAST_GOODBYE", - "col_year": 2022, - "col_vocals": True, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "odesza_songs.xlsx", - }, - "stream": "songs_stream", - }, - { - "data": { - "col_name": "Lightning in a Bottle", - "col_location": "{'country': 'USA', 'state': 'California', 'city': 'Buena Vista Lake'}", - "col_attendance": 18000, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "california_festivals.xlsx", - }, - "stream": "festivals_stream", - }, - { - "data": { - "col_name": "Outside Lands", - "col_location": "{'country': 'USA', 'state': 'California', 'city': 'San Francisco'}", - "col_attendance": 220000, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "california_festivals.xlsx", - }, - "stream": "festivals_stream", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col_title": {"type": ["null", "string"]}, - "col_album": {"type": ["null", "string"]}, - "col_year": {"type": ["null", "number"]}, - "col_vocals": {"type": ["null", "boolean"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "songs_stream", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col_name": {"type": ["null", "string"]}, - "col_location": {"type": ["null", "string"]}, - "col_attendance": {"type": ["null", "number"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "festivals_stream", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - ] - } - ) -).build() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/file_based_source_builder.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/file_based_source_builder.py deleted file mode 100644 index 6675df380c7c..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/file_based_source_builder.py +++ /dev/null @@ -1,93 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from copy import deepcopy -from typing import Any, Mapping, Optional, Type - -from airbyte_cdk.sources.file_based.availability_strategy.abstract_file_based_availability_strategy import ( - AbstractFileBasedAvailabilityStrategy, -) -from airbyte_cdk.sources.file_based.discovery_policy import AbstractDiscoveryPolicy, DefaultDiscoveryPolicy -from airbyte_cdk.sources.file_based.file_based_source import default_parsers -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser -from airbyte_cdk.sources.file_based.schema_validation_policies import AbstractSchemaValidationPolicy -from airbyte_cdk.sources.file_based.stream.cursor import AbstractFileBasedCursor -from airbyte_cdk.sources.source import TState -from unit_tests.sources.file_based.in_memory_files_source import InMemoryFilesSource -from unit_tests.sources.file_based.scenarios.scenario_builder import SourceBuilder - - -class FileBasedSourceBuilder(SourceBuilder[InMemoryFilesSource]): - def __init__(self) -> None: - self._files: Mapping[str, Any] = {} - self._file_type: Optional[str] = None - self._availability_strategy: Optional[AbstractFileBasedAvailabilityStrategy] = None - self._discovery_policy: AbstractDiscoveryPolicy = DefaultDiscoveryPolicy() - self._validation_policies: Optional[Mapping[str, AbstractSchemaValidationPolicy]] = None - self._parsers = default_parsers - self._stream_reader: Optional[AbstractFileBasedStreamReader] = None - self._file_write_options: Mapping[str, Any] = {} - self._cursor_cls: Optional[Type[AbstractFileBasedCursor]] = None - self._config: Optional[Mapping[str, Any]] = None - self._state: Optional[TState] = None - - def build( - self, configured_catalog: Optional[Mapping[str, Any]], config: Optional[Mapping[str, Any]], state: Optional[TState] - ) -> InMemoryFilesSource: - if self._file_type is None: - raise ValueError("file_type is not set") - return InMemoryFilesSource( - self._files, - self._file_type, - self._availability_strategy, - self._discovery_policy, - self._validation_policies, - self._parsers, - self._stream_reader, - configured_catalog, - config, - state, - self._file_write_options, - self._cursor_cls, - ) - - def set_files(self, files: Mapping[str, Any]) -> "FileBasedSourceBuilder": - self._files = files - return self - - def set_file_type(self, file_type: str) -> "FileBasedSourceBuilder": - self._file_type = file_type - return self - - def set_parsers(self, parsers: Mapping[Type[Any], FileTypeParser]) -> "FileBasedSourceBuilder": - self._parsers = parsers - return self - - def set_availability_strategy(self, availability_strategy: AbstractFileBasedAvailabilityStrategy) -> "FileBasedSourceBuilder": - self._availability_strategy = availability_strategy - return self - - def set_discovery_policy(self, discovery_policy: AbstractDiscoveryPolicy) -> "FileBasedSourceBuilder": - self._discovery_policy = discovery_policy - return self - - def set_validation_policies(self, validation_policies: Mapping[str, AbstractSchemaValidationPolicy]) -> "FileBasedSourceBuilder": - self._validation_policies = validation_policies - return self - - def set_stream_reader(self, stream_reader: AbstractFileBasedStreamReader) -> "FileBasedSourceBuilder": - self._stream_reader = stream_reader - return self - - def set_cursor_cls(self, cursor_cls: AbstractFileBasedCursor) -> "FileBasedSourceBuilder": - self._cursor_cls = cursor_cls - return self - - def set_file_write_options(self, file_write_options: Mapping[str, Any]) -> "FileBasedSourceBuilder": - self._file_write_options = file_write_options - return self - - def copy(self) -> "FileBasedSourceBuilder": - return deepcopy(self) diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/incremental_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/incremental_scenarios.py deleted file mode 100644 index 95cde6b73a48..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/incremental_scenarios.py +++ /dev/null @@ -1,1941 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.file_based.stream.cursor import DefaultFileBasedCursor -from airbyte_cdk.test.state_builder import StateBuilder -from unit_tests.sources.file_based.helpers import LowHistoryLimitCursor -from unit_tests.sources.file_based.scenarios.file_based_source_builder import FileBasedSourceBuilder -from unit_tests.sources.file_based.scenarios.scenario_builder import IncrementalScenarioConfig, TestScenarioBuilder - -single_csv_input_state_is_earlier_scenario = ( - TestScenarioBuilder() - .set_name("single_csv_input_state_is_earlier") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - .set_cursor_cls(DefaultFileBasedCursor) - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": {"some_old_file.csv": "2023-06-01T03:54:07.000000Z"}, - }, - ) - .build(), - ) - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21", - "col2": "val22", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "history": {"some_old_file.csv": "2023-06-01T03:54:07.000000Z", "a.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_a.csv", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - } - ] - } - ) -).build() - -single_csv_file_is_skipped_if_same_modified_at_as_in_history = ( - TestScenarioBuilder() - .set_name("single_csv_file_is_skipped_if_same_modified_at_as_in_history") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - .set_cursor_cls(DefaultFileBasedCursor) - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z"}, - }, - ) - .build(), - ) - ) - .set_expected_records( - [ - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_a.csv", - } - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - } - ] - } - ) -).build() - -single_csv_file_is_synced_if_modified_at_is_more_recent_than_in_history = ( - TestScenarioBuilder() - .set_name("single_csv_file_is_synced_if_modified_at_is_more_recent_than_in_history") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - .set_cursor_cls(DefaultFileBasedCursor) - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": {"a.csv": "2023-06-01T03:54:07.000000Z"}, - }, - ) - .build(), - ) - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21", - "col2": "val22", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_a.csv", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - } - ] - } - ) -).build() - -single_csv_no_input_state_scenario = ( - TestScenarioBuilder() - .set_name("single_csv_input_state_is_earlier_again") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - } - } - ) - .set_file_type("csv") - .set_cursor_cls(DefaultFileBasedCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21", - "col2": "val22", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_a.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder().build(), - ) - ) -).build() - -multi_csv_same_timestamp_scenario = ( - TestScenarioBuilder() - .set_name("multi_csv_same_timestamp") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(DefaultFileBasedCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z", "b.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_b.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder().build(), - ) - ) -).build() - -single_csv_input_state_is_later_scenario = ( - TestScenarioBuilder() - .set_name("single_csv_input_state_is_later") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - } - } - ) - .set_file_type("csv") - .set_cursor_cls(DefaultFileBasedCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21", - "col2": "val22", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "history": { - "recent_file.csv": "2023-07-15T23:59:59.000000Z", - "a.csv": "2023-06-05T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-07-15T23:59:59.000000Z_recent_file.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": {"recent_file.csv": "2023-07-15T23:59:59.000000Z"}, - }, - ) - .build(), - ) - ) -).build() - -multi_csv_different_timestamps_scenario = ( - TestScenarioBuilder() - .set_name("multi_csv_stream_different_timestamps") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-04T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(DefaultFileBasedCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-04T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-04T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "history": { - "a.csv": "2023-06-04T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-04T03:54:07.000000Z_a.csv", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": {"a.csv": "2023-06-04T03:54:07.000000Z", "b.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_b.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder().build(), - ) - ) -).build() - -multi_csv_per_timestamp_scenario = ( - TestScenarioBuilder() - .set_name("multi_csv_per_timestamp") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-06T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(DefaultFileBasedCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z", "b.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_b.csv", - }, - { - "data": { - "col1": "val11c", - "col2": "val12c", - "col3": "val13c", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21c", - "col2": "val22c", - "col3": "val23c", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "history": { - "a.csv": "2023-06-05T03:54:07.000000Z", - "b.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-06T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z_c.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder().build(), - ) - ) -).build() - -multi_csv_skip_file_if_already_in_history = ( - TestScenarioBuilder() - .set_name("skip_files_already_in_history") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-06T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(DefaultFileBasedCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - # {"data": {"col1": "val11a", "col2": "val12a"}, "stream": "stream1"}, # this file is skipped - # {"data": {"col1": "val21a", "col2": "val22a"}, "stream": "stream1"}, # this file is skipped - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z", "b.csv": "2023-06-05T03:54:07.000000Z"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_b.csv", - }, - { - "data": { - "col1": "val11c", - "col2": "val12c", - "col3": "val13c", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21c", - "col2": "val22c", - "col3": "val23c", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "history": { - "a.csv": "2023-06-05T03:54:07.000000Z", - "b.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-06T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z_c.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z"}, - }, - ) - .build(), - ) - ) -).build() - -multi_csv_include_missing_files_within_history_range = ( - TestScenarioBuilder() - .set_name("include_missing_files_within_history_range") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-06T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(DefaultFileBasedCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - # {"data": {"col1": "val11a", "col2": "val12a"}, "stream": "stream1"}, # this file is skipped - # {"data": {"col1": "val21a", "col2": "val22a"}, "stream": "stream1"}, # this file is skipped - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - # {"data": {"col1": "val11c", "col2": "val12c", "col3": "val13c"}, "stream": "stream1"}, # this file is skipped - # {"data": {"col1": "val21c", "col2": "val22c", "col3": "val23c"}, "stream": "stream1"}, # this file is skipped - { - "history": { - "a.csv": "2023-06-05T03:54:07.000000Z", - "b.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-06T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z_c.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": {"a.csv": "2023-06-05T03:54:07.000000Z", "c.csv": "2023-06-06T03:54:07.000000Z"}, - }, - ) - .build(), - ) - ) -).build() - -multi_csv_remove_old_files_if_history_is_full_scenario = ( - TestScenarioBuilder() - .set_name("multi_csv_remove_old_files_if_history_is_full") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-06T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-07T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-10T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(LowHistoryLimitCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "history": { - "very_old_file.csv": "2023-06-02T03:54:07.000000Z", - "old_file_same_timestamp_as_a.csv": "2023-06-06T03:54:07.000000Z", - "a.csv": "2023-06-06T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z_old_file_same_timestamp_as_a.csv", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-07T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-07T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": { - "old_file_same_timestamp_as_a.csv": "2023-06-06T03:54:07.000000Z", - "a.csv": "2023-06-06T03:54:07.000000Z", - "b.csv": "2023-06-07T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-07T03:54:07.000000Z_b.csv", - }, - { - "data": { - "col1": "val11c", - "col2": "val12c", - "col3": "val13c", - "_ab_source_file_last_modified": "2023-06-10T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21c", - "col2": "val22c", - "col3": "val23c", - "_ab_source_file_last_modified": "2023-06-10T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "history": { - "old_file_same_timestamp_as_a.csv": "2023-06-06T03:54:07.000000Z", - "b.csv": "2023-06-07T03:54:07.000000Z", - "c.csv": "2023-06-10T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-10T03:54:07.000000Z_c.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": { - "very_very_old_file.csv": "2023-06-01T03:54:07.000000Z", - "very_old_file.csv": "2023-06-02T03:54:07.000000Z", - "old_file_same_timestamp_as_a.csv": "2023-06-06T03:54:07.000000Z", - }, - }, - ) - .build(), - ) - ) -).build() - -multi_csv_same_timestamp_more_files_than_history_size_scenario = ( - TestScenarioBuilder() - .set_name("multi_csv_same_timestamp_more_files_than_history_size") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - "days_to_sync_if_history_is_full": 3, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "d.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11d", "val12d", "val13d"), - ("val21d", "val22d", "val23d"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(LowHistoryLimitCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11c", - "col2": "val12c", - "col3": "val13c", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21c", - "col2": "val22c", - "col3": "val23c", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11d", - "col2": "val12d", - "col3": "val13d", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "d.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21d", - "col2": "val22d", - "col3": "val23d", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "d.csv", - }, - "stream": "stream1", - }, - { - "history": { - "b.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-05T03:54:07.000000Z", - "d.csv": "2023-06-05T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_d.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder().build(), - ) - ) -).build() - -multi_csv_sync_recent_files_if_history_is_incomplete_scenario = ( - TestScenarioBuilder() - .set_name("multi_csv_sync_recent_files_if_history_is_incomplete") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - "days_to_sync_if_history_is_full": 3, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "d.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11d", "val12d", "val13d"), - ("val21d", "val22d", "val23d"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - } - ) - .set_cursor_cls(LowHistoryLimitCursor) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "history": { - "b.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-05T03:54:07.000000Z", - "d.csv": "2023-06-05T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z_d.csv", - } - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": { - "b.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-05T03:54:07.000000Z", - "d.csv": "2023-06-05T03:54:07.000000Z", - }, - }, - ) - .build(), - ) - ) -).build() - -multi_csv_sync_files_within_time_window_if_history_is_incomplete__different_timestamps_scenario = ( - TestScenarioBuilder() - .set_name("multi_csv_sync_recent_files_if_history_is_incomplete__different_timestamps") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - "days_to_sync_if_history_is_full": 3, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-06T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-07T03:54:07.000000Z", - }, - "d.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11d", "val12d", "val13d"), - ("val21d", "val22d", "val23d"), - ], - "last_modified": "2023-06-08T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(LowHistoryLimitCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - # {"data": {"col1": "val11a", "col2": "val12a"}, "stream": "stream1"}, # This file is skipped because it is older than the time_window - # {"data": {"col1": "val21a", "col2": "val22a"}, "stream": "stream1"}, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": { - "c.csv": "2023-06-07T03:54:07.000000Z", - "d.csv": "2023-06-08T03:54:07.000000Z", - "e.csv": "2023-06-08T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-08T03:54:07.000000Z_e.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": { - "c.csv": "2023-06-07T03:54:07.000000Z", - "d.csv": "2023-06-08T03:54:07.000000Z", - "e.csv": "2023-06-08T03:54:07.000000Z", - }, - }, - ) - .build(), - ) - ) -).build() - -multi_csv_sync_files_within_history_time_window_if_history_is_incomplete_different_timestamps_scenario = ( - TestScenarioBuilder() - .set_name("multi_csv_sync_files_within_history_time_window_if_history_is_incomplete_different_timestamps") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - "days_to_sync_if_history_is_full": 3, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-06T03:54:07.000000Z", - }, - "c.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11c", "val12c", "val13c"), - ("val21c", "val22c", "val23c"), - ], - "last_modified": "2023-06-07T03:54:07.000000Z", - }, - "d.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11d", "val12d", "val13d"), - ("val21d", "val22d", "val23d"), - ], - "last_modified": "2023-06-08T03:54:07.000000Z", - }, - } - ) - .set_file_type("csv") - .set_cursor_cls(LowHistoryLimitCursor) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "history": { - "a.csv": "2023-06-05T03:54:07.000000Z", - "c.csv": "2023-06-07T03:54:07.000000Z", - "d.csv": "2023-06-08T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-08T03:54:07.000000Z_d.csv", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "history": { - "b.csv": "2023-06-06T03:54:07.000000Z", - "c.csv": "2023-06-07T03:54:07.000000Z", - "d.csv": "2023-06-08T03:54:07.000000Z", - }, - "_ab_source_file_last_modified": "2023-06-08T03:54:07.000000Z_d.csv", - }, - ] - ) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=StateBuilder() - .with_stream_state( - "stream1", - { - "history": { - "old_file.csv": "2023-06-05T00:00:00.000000Z", - "c.csv": "2023-06-07T03:54:07.000000Z", - "d.csv": "2023-06-08T03:54:07.000000Z", - }, - }, - ) - .build(), - ) - ) -).build() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/jsonl_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/jsonl_scenarios.py deleted file mode 100644 index 23e879306e4c..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/jsonl_scenarios.py +++ /dev/null @@ -1,941 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.file_based.config.jsonl_format import JsonlFormat -from airbyte_cdk.sources.file_based.exceptions import FileBasedSourceError -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from unit_tests.sources.file_based.helpers import LowInferenceBytesJsonlParser, LowInferenceLimitDiscoveryPolicy -from unit_tests.sources.file_based.scenarios.file_based_source_builder import FileBasedSourceBuilder -from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenarioBuilder - -single_jsonl_scenario = ( - TestScenarioBuilder() - .set_name("single_jsonl_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "jsonl"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.jsonl": { - "contents": [ - {"col1": "val11", "col2": "val12"}, - {"col1": "val21", "col2": "val22"}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("jsonl") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": { - "type": "string", - }, - "_ab_source_file_url": { - "type": "string", - }, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.jsonl", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21", - "col2": "val22", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.jsonl", - }, - "stream": "stream1", - }, - ] - ) -).build() - - -multi_jsonl_with_different_keys_scenario = ( - TestScenarioBuilder() - .set_name("multi_jsonl_with_different_keys_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "jsonl"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.jsonl": { - "contents": [ - {"col1": "val11a", "col2": "val12a"}, - {"col1": "val21a", "col2": "val22a"}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.jsonl": { - "contents": [ - {"col1": "val11b", "col2": "val12b", "col3": "val13b"}, - {"col1": "val21b", "col3": "val23b"}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("jsonl") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "col3": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": { - "type": "string", - }, - "_ab_source_file_url": { - "type": "string", - }, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.jsonl", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.jsonl", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.jsonl", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.jsonl", - }, - "stream": "stream1", - }, - ] - ) -).build() - - -multi_jsonl_stream_n_file_exceeds_limit_for_inference = ( - TestScenarioBuilder() - .set_name("multi_jsonl_stream_n_file_exceeds_limit_for_inference") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "jsonl"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.jsonl": { - "contents": [ - {"col1": "val11a", "col2": "val12a"}, - {"col1": "val21a", "col2": "val22a"}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.jsonl": { - "contents": [ - {"col1": "val11b", "col2": "val12b", "col3": "val13b"}, - {"col1": "val21b", "col3": "val23b"}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("jsonl") - .set_discovery_policy(LowInferenceLimitDiscoveryPolicy()) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": { - "type": "string", - }, - "_ab_source_file_url": { - "type": "string", - }, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.jsonl", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.jsonl", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.jsonl", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.jsonl", - }, - "stream": "stream1", - }, - ] - ) -).build() - - -multi_jsonl_stream_n_bytes_exceeds_limit_for_inference = ( - TestScenarioBuilder() - .set_name("multi_jsonl_stream_n_bytes_exceeds_limit_for_inference") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "jsonl"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.jsonl": { - "contents": [ - {"col1": "val11a", "col2": "val12a"}, - {"col1": "val21a", "col2": "val22a"}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.jsonl": { - "contents": [ - {"col1": "val11b", "col2": "val12b"}, - {"col1": "val21b", "col2": "val22b", "col3": "val23b"}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("jsonl") - .set_parsers({JsonlFormat: LowInferenceBytesJsonlParser()}) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "col2": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": { - "type": "string", - }, - "_ab_source_file_url": { - "type": "string", - }, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.jsonl", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.jsonl", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.jsonl", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.jsonl", - }, - "stream": "stream1", - }, - ] - ) -).build() - - -invalid_jsonl_scenario = ( - TestScenarioBuilder() - .set_name("invalid_jsonl_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "jsonl"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.jsonl": { - "contents": [ - {"col1": "val1"}, - "invalid", - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("jsonl") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": { - "type": "string", - }, - "_ab_source_file_url": { - "type": "string", - }, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records([]) - .set_expected_discover_error(AirbyteTracedException, FileBasedSourceError.SCHEMA_INFERENCE_ERROR.value) - .set_expected_read_error(AirbyteTracedException, "Please check the logged errors for more information.") - .set_expected_logs( - { - "read": [ - { - "level": "ERROR", - "message": f"{FileBasedSourceError.ERROR_PARSING_RECORD.value} stream=stream1 file=a.jsonl line_no=2 n_skipped=0", - }, - ] - } - ) -).build() - - -jsonl_multi_stream_scenario = ( - TestScenarioBuilder() - .set_name("jsonl_multi_stream_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "jsonl"}, - "globs": ["*.jsonl"], - "validation_policy": "Emit Record", - }, - { - "name": "stream2", - "format": {"filetype": "jsonl"}, - "globs": ["b.jsonl"], - "validation_policy": "Emit Record", - }, - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.jsonl": { - "contents": [ - {"col1": 1, "col2": "record1"}, - {"col1": 2, "col2": "record2"}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.jsonl": { - "contents": [ - {"col3": 1.1}, - {"col3": 2.2}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("jsonl") - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "integer"]}, - "col2": { - "type": ["null", "string"], - }, - "col3": {"type": ["null", "number"]}, - "_ab_source_file_last_modified": { - "type": "string", - }, - "_ab_source_file_url": { - "type": "string", - }, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "source_defined_cursor": True, - "default_cursor_field": ["_ab_source_file_last_modified"], - }, - { - "json_schema": { - "type": "object", - "properties": { - "col3": {"type": ["null", "number"]}, - "_ab_source_file_last_modified": { - "type": "string", - }, - "_ab_source_file_url": { - "type": "string", - }, - }, - }, - "name": "stream2", - "source_defined_cursor": True, - "default_cursor_field": ["_ab_source_file_last_modified"], - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": 1, - "col2": "record1", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.jsonl", - }, - "stream": "stream1", - }, - { - "data": { - "col1": 2, - "col2": "record2", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.jsonl", - }, - "stream": "stream1", - }, - { - "data": {"col3": 1.1, "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "b.jsonl"}, - "stream": "stream1", - }, - { - "data": {"col3": 2.2, "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "b.jsonl"}, - "stream": "stream1", - }, - { - "data": {"col3": 1.1, "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "b.jsonl"}, - "stream": "stream2", - }, - { - "data": {"col3": 2.2, "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "b.jsonl"}, - "stream": "stream2", - }, - ] - ) -).build() - - -schemaless_jsonl_scenario = ( - TestScenarioBuilder() - .set_name("schemaless_jsonl_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "jsonl"}, - "globs": ["*"], - "validation_policy": "Skip Record", - "schemaless": True, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.jsonl": { - "contents": [ - {"col1": 1, "col2": "record1"}, - {"col1": 2, "col2": "record2"}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.jsonl": { - "contents": [ - {"col1": 3, "col2": "record3", "col3": 1.1}, - {"col1": 4, "col2": "record4", "col3": 1.1}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("jsonl") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "data": {"type": "object"}, - "_ab_source_file_last_modified": { - "type": "string", - }, - "_ab_source_file_url": { - "type": "string", - }, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "data": {"col1": 1, "col2": "record1"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.jsonl", - }, - "stream": "stream1", - }, - { - "data": { - "data": {"col1": 2, "col2": "record2"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.jsonl", - }, - "stream": "stream1", - }, - { - "data": { - "data": {"col1": 3, "col2": "record3", "col3": 1.1}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.jsonl", - }, - "stream": "stream1", - }, - { - "data": { - "data": {"col1": 4, "col2": "record4", "col3": 1.1}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.jsonl", - }, - "stream": "stream1", - }, - ] - ) -).build() - - -schemaless_jsonl_multi_stream_scenario = ( - TestScenarioBuilder() - .set_name("schemaless_jsonl_multi_stream_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "jsonl"}, - "globs": ["a.jsonl"], - "validation_policy": "Skip Record", - "schemaless": True, - }, - { - "name": "stream2", - "format": {"filetype": "jsonl"}, - "globs": ["b.jsonl"], - "validation_policy": "Skip Record", - }, - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.jsonl": { - "contents": [ - {"col1": 1, "col2": "record1"}, - {"col1": 2, "col2": "record2"}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.jsonl": { - "contents": [ - {"col3": 1.1}, - {"col3": 2.2}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("jsonl") - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "data": {"type": "object"}, - "_ab_source_file_last_modified": { - "type": "string", - }, - "_ab_source_file_url": { - "type": "string", - }, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - "source_defined_cursor": True, - "default_cursor_field": ["_ab_source_file_last_modified"], - }, - { - "json_schema": { - "type": "object", - "properties": { - "col3": {"type": ["null", "number"]}, - "_ab_source_file_last_modified": { - "type": "string", - }, - "_ab_source_file_url": { - "type": "string", - }, - }, - }, - "name": "stream2", - "source_defined_cursor": True, - "default_cursor_field": ["_ab_source_file_last_modified"], - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - ] - } - ) - .set_expected_records( - [ - { - "data": { - "data": {"col1": 1, "col2": "record1"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.jsonl", - }, - "stream": "stream1", - }, - { - "data": { - "data": {"col1": 2, "col2": "record2"}, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.jsonl", - }, - "stream": "stream1", - }, - { - "data": {"col3": 1.1, "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "b.jsonl"}, - "stream": "stream2", - }, - { - "data": {"col3": 2.2, "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "b.jsonl"}, - "stream": "stream2", - }, - ] - ) -).build() - -jsonl_user_input_schema_scenario = ( - TestScenarioBuilder() - .set_name("jsonl_user_input_schema_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "jsonl"}, - "globs": ["*"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "integer", "col2": "string"}', - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.jsonl": { - "contents": [ - {"col1": 1, "col2": "val12"}, - {"col1": 2, "col2": "val22"}, - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("jsonl") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": "integer"}, - "col2": { - "type": "string", - }, - "_ab_source_file_last_modified": { - "type": "string", - }, - "_ab_source_file_url": { - "type": "string", - }, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": 1, - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.jsonl", - }, - "stream": "stream1", - }, - { - "data": { - "col1": 2, - "col2": "val22", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.jsonl", - }, - "stream": "stream1", - }, - ] - ) -).build() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/parquet_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/parquet_scenarios.py deleted file mode 100644 index 732660e564d8..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/parquet_scenarios.py +++ /dev/null @@ -1,763 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import datetime -import decimal - -import pyarrow as pa -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from unit_tests.sources.file_based.in_memory_files_source import TemporaryParquetFilesStreamReader -from unit_tests.sources.file_based.scenarios.file_based_source_builder import FileBasedSourceBuilder -from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenarioBuilder - -_single_parquet_file = { - "a.parquet": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } -} - -_single_partitioned_parquet_file = { - "path_prefix/partition1=1/partition2=2/a.parquet": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } -} - -_parquet_file_with_decimal = { - "a.parquet": { - "contents": [ - ("col1",), - (decimal.Decimal("13.00"),), - ], - "schema": pa.schema( - [ - pa.field("col1", pa.decimal128(5, 2)), - ] - ), - "last_modified": "2023-06-05T03:54:07.000Z", - } -} - -_multiple_parquet_file = { - "a.parquet": { - "contents": [ - ("col1", "col2"), - ("val11a", "val12a"), - ("val21a", "val22a"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.parquet": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, -} - -_parquet_file_with_various_types = { - "a.parquet": { - "contents": [ - ( - "col_bool", - "col_int8", - "col_int16", - "col_int32", - "col_uint8", - "col_uint16", - "col_uint32", - "col_uint64", - "col_float32", - "col_float64", - "col_string", - "col_date32", - "col_date64", - "col_timestamp_without_tz", - "col_timestamp_with_tz", - "col_time32s", - "col_time32ms", - "col_time64us", - "col_struct", - "col_list", - "col_duration", - "col_binary", - ), - ( - True, - -1, - 1, - 2, - 2, - 3, - 4, - 5, - 3.14, - 5.0, - "2020-01-01", - datetime.date(2021, 1, 1), - datetime.date(2022, 1, 1), - datetime.datetime(2023, 1, 1, 1, 2, 3), - datetime.datetime(2024, 3, 4, 5, 6, 7, tzinfo=datetime.timezone.utc), - datetime.time(1, 2, 3), - datetime.time(2, 3, 4), - datetime.time(1, 2, 3, 4), - {"struct_key": "struct_value"}, - [1, 2, 3, 4], - 12345, - b"binary string. Hello world!", - ), - ], - "schema": pa.schema( - [ - pa.field("col_bool", pa.bool_()), - pa.field("col_int8", pa.int8()), - pa.field("col_int16", pa.int16()), - pa.field("col_int32", pa.int32()), - pa.field("col_uint8", pa.uint8()), - pa.field("col_uint16", pa.uint16()), - pa.field("col_uint32", pa.uint32()), - pa.field("col_uint64", pa.uint64()), - pa.field("col_float32", pa.float32()), - pa.field("col_float64", pa.float64()), - pa.field("col_string", pa.string()), - pa.field("col_date32", pa.date32()), - pa.field("col_date64", pa.date64()), - pa.field("col_timestamp_without_tz", pa.timestamp("s")), - pa.field("col_timestamp_with_tz", pa.timestamp("s", tz="UTC")), - pa.field("col_time32s", pa.time32("s")), - pa.field("col_time32ms", pa.time32("ms")), - pa.field("col_time64us", pa.time64("us")), - pa.field("col_struct", pa.struct([pa.field("struct_key", pa.string())])), - pa.field("col_list", pa.list_(pa.int32())), - pa.field("col_duration", pa.duration("s")), - pa.field("col_binary", pa.binary()), - ] - ), - "last_modified": "2023-06-05T03:54:07.000Z", - } -} - -single_parquet_scenario = ( - TestScenarioBuilder() - .set_name("single_parquet_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "parquet"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryParquetFilesStreamReader(files=_single_parquet_file, file_type="parquet")) - .set_file_type("parquet") - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.parquet", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21", - "col2": "val22", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.parquet", - }, - "stream": "stream1", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) -).build() - -single_partitioned_parquet_scenario = ( - TestScenarioBuilder() - .set_name("single_partitioned_parquet_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "parquet"}, - "globs": ["path_prefix/**/*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryParquetFilesStreamReader(files=_single_partitioned_parquet_file, file_type="parquet")) - .set_file_type("parquet") - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "partition1": "1", - "partition2": "2", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "path_prefix/partition1=1/partition2=2/a.parquet", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21", - "col2": "val22", - "partition1": "1", - "partition2": "2", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "path_prefix/partition1=1/partition2=2/a.parquet", - }, - "stream": "stream1", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "partition1": {"type": ["null", "string"]}, - "partition2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) -).build() - -multi_parquet_scenario = ( - TestScenarioBuilder() - .set_name("multi_parquet_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "parquet"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_file_type("parquet") - .set_stream_reader(TemporaryParquetFilesStreamReader(files=_multiple_parquet_file, file_type="parquet")) - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "col3": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": "val12a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.parquet", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21a", - "col2": "val22a", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.parquet", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.parquet", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.parquet", - }, - "stream": "stream1", - }, - ] - ) -).build() - -parquet_various_types_scenario = ( - TestScenarioBuilder() - .set_name("parquet_various_types") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "parquet"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryParquetFilesStreamReader(files=_parquet_file_with_various_types, file_type="parquet")) - .set_file_type("parquet") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col_bool": { - "type": ["null", "boolean"], - }, - "col_int8": { - "type": ["null", "integer"], - }, - "col_int16": { - "type": ["null", "integer"], - }, - "col_int32": { - "type": ["null", "integer"], - }, - "col_uint8": { - "type": ["null", "integer"], - }, - "col_uint16": { - "type": ["null", "integer"], - }, - "col_uint32": { - "type": ["null", "integer"], - }, - "col_uint64": { - "type": ["null", "integer"], - }, - "col_float32": { - "type": ["null", "number"], - }, - "col_float64": { - "type": ["null", "number"], - }, - "col_string": { - "type": ["null", "string"], - }, - "col_date32": {"type": ["null", "string"], "format": "date"}, - "col_date64": {"type": ["null", "string"], "format": "date"}, - "col_timestamp_without_tz": {"type": ["null", "string"], "format": "date-time"}, - "col_timestamp_with_tz": {"type": ["null", "string"], "format": "date-time"}, - "col_time32s": { - "type": ["null", "string"], - }, - "col_time32ms": { - "type": ["null", "string"], - }, - "col_time64us": { - "type": ["null", "string"], - }, - "col_struct": { - "type": ["null", "object"], - }, - "col_list": { - "type": ["null", "array"], - }, - "col_duration": { - "type": ["null", "integer"], - }, - "col_binary": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": { - "type": "string", - }, - "_ab_source_file_url": { - "type": "string", - }, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col_bool": True, - "col_int8": -1, - "col_int16": 1, - "col_int32": 2, - "col_uint8": 2, - "col_uint16": 3, - "col_uint32": 4, - "col_uint64": 5, - "col_float32": 3.14, - "col_float64": 5.0, - "col_string": "2020-01-01", - "col_date32": "2021-01-01", - "col_date64": "2022-01-01", - "col_timestamp_without_tz": "2023-01-01T01:02:03", - "col_timestamp_with_tz": "2024-03-04T05:06:07+00:00", - "col_time32s": "01:02:03", - "col_time32ms": "02:03:04", - "col_time64us": "01:02:03.000004", - "col_struct": {"struct_key": "struct_value"}, - "col_list": [1, 2, 3, 4], - "col_duration": 12345, - "col_binary": "binary string. Hello world!", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.parquet", - }, - "stream": "stream1", - }, - ] - ) -).build() - -parquet_file_with_decimal_no_config_scenario = ( - TestScenarioBuilder() - .set_name("parquet_file_with_decimal_no_config") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "parquet"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryParquetFilesStreamReader(files=_parquet_file_with_decimal, file_type="parquet")) - .set_file_type("parquet") - ) - .set_expected_records( - [ - { - "data": { - "col1": "13.00", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.parquet", - }, - "stream": "stream1", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) -).build() - -parquet_file_with_decimal_as_string_scenario = ( - TestScenarioBuilder() - .set_name("parquet_file_with_decimal_as_string") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "format": {"filetype": "parquet", "decimal_as_float": False}, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryParquetFilesStreamReader(files=_parquet_file_with_decimal, file_type="parquet")) - .set_file_type("parquet") - ) - .set_expected_records( - [ - { - "data": { - "col1": "13.00", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.parquet", - }, - "stream": "stream1", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) -).build() - -parquet_file_with_decimal_as_float_scenario = ( - TestScenarioBuilder() - .set_name("parquet_file_with_decimal_as_float") - .set_config( - { - "streams": [ - { - "name": "stream1", - "globs": ["*"], - "validation_policy": "Emit Record", - "format": {"filetype": "parquet", "decimal_as_float": True}, - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryParquetFilesStreamReader(files=_parquet_file_with_decimal, file_type="parquet")) - .set_file_type("parquet") - ) - .set_expected_records( - [ - { - "data": {"col1": 13.00, "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "a.parquet"}, - "stream": "stream1", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "number"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) -).build() - -parquet_file_with_decimal_legacy_config_scenario = ( - TestScenarioBuilder() - .set_name("parquet_file_with_decimal_legacy_config") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": { - "filetype": "parquet", - }, - "globs": ["*"], - "validation_policy": "emit_record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryParquetFilesStreamReader(files=_parquet_file_with_decimal, file_type="parquet")) - .set_file_type("parquet") - ) - .set_expected_records( - [ - { - "data": {"col1": 13.00, "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "a.parquet"}, - "stream": "stream1", - }, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "number"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) -).build() - -parquet_with_invalid_config_scenario = ( - TestScenarioBuilder() - .set_name("parquet_with_invalid_config") - .set_config({"streams": [{"name": "stream1", "globs": ["*"], "validation_policy": "Emit Record", "format": {"filetype": "csv"}}]}) - .set_source_builder( - FileBasedSourceBuilder() - .set_stream_reader(TemporaryParquetFilesStreamReader(files=_single_parquet_file, file_type="parquet")) - .set_file_type("parquet") - ) - .set_expected_records([]) - .set_expected_logs({"read": [{"level": "ERROR", "message": "Error parsing record"}]}) - .set_expected_discover_error(AirbyteTracedException, "Error inferring schema from files") - .set_expected_read_error(AirbyteTracedException, "Please check the logged errors for more information.") - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": ["null", "string"]}, - "col2": {"type": ["null", "string"]}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) -).build() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/scenario_builder.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/scenario_builder.py deleted file mode 100644 index 8158225ac8f4..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/scenario_builder.py +++ /dev/null @@ -1,243 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -from abc import ABC, abstractmethod -from copy import deepcopy -from dataclasses import dataclass, field -from typing import Any, Generic, List, Mapping, Optional, Set, Tuple, Type, TypeVar - -from airbyte_cdk.models import ( - AirbyteAnalyticsTraceMessage, - AirbyteStateMessageSerializer, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteCatalogSerializer, - SyncMode, -) -from airbyte_cdk.sources import AbstractSource -from airbyte_cdk.sources.source import TState - - -@dataclass -class IncrementalScenarioConfig: - input_state: List[Mapping[str, Any]] = field(default_factory=list) - expected_output_state: Optional[Mapping[str, Any]] = None - - -SourceType = TypeVar("SourceType", bound=AbstractSource) - - -class SourceBuilder(ABC, Generic[SourceType]): - """ - A builder that creates a source instance of type SourceType - """ - - @abstractmethod - def build( - self, configured_catalog: Optional[Mapping[str, Any]], config: Optional[Mapping[str, Any]], state: Optional[TState] - ) -> SourceType: - raise NotImplementedError() - - -class TestScenario(Generic[SourceType]): - def __init__( - self, - name: str, - config: Mapping[str, Any], - source: SourceType, - expected_spec: Optional[Mapping[str, Any]], - expected_check_status: Optional[str], - expected_catalog: Optional[Mapping[str, Any]], - expected_logs: Optional[Mapping[str, List[Mapping[str, Any]]]], - expected_records: List[Mapping[str, Any]], - expected_check_error: Tuple[Optional[Type[Exception]], Optional[str]], - expected_discover_error: Tuple[Optional[Type[Exception]], Optional[str]], - expected_read_error: Tuple[Optional[Type[Exception]], Optional[str]], - incremental_scenario_config: Optional[IncrementalScenarioConfig], - expected_analytics: Optional[List[AirbyteAnalyticsTraceMessage]] = None, - log_levels: Optional[Set[str]] = None, - catalog: Optional[ConfiguredAirbyteCatalog] = None, - ): - if log_levels is None: - log_levels = {"ERROR", "WARN", "WARNING"} - self.name = name - self.config = config - self.catalog = catalog - self.source = source - self.expected_spec = expected_spec - self.expected_check_status = expected_check_status - self.expected_catalog = expected_catalog - self.expected_logs = expected_logs - self.expected_records = expected_records - self.expected_check_error = expected_check_error - self.expected_discover_error = expected_discover_error - self.expected_read_error = expected_read_error - self.incremental_scenario_config = incremental_scenario_config - self.expected_analytics = expected_analytics - self.log_levels = log_levels - self.validate() - - def validate(self) -> None: - assert self.name - - def configured_catalog(self, sync_mode: SyncMode) -> Optional[Mapping[str, Any]]: - # The preferred way of returning the catalog for the TestScenario is by providing it at the initialization. The previous solution - # relied on `self.source.streams` which might raise an exception hence screwing the tests results as the user might expect the - # exception to be raised as part of the actual check/discover/read commands - # Note that to avoid a breaking change, we still attempt to automatically generate the catalog based on the streams - if self.catalog: - return ConfiguredAirbyteCatalogSerializer.dump(self.catalog) - - catalog: Mapping[str, Any] = {"streams": []} - for stream in catalog["streams"]: - catalog["streams"].append( - { - "stream": { - "name": stream["name"], - "json_schema": {}, - "supported_sync_modes": [sync_mode.value], - }, - "sync_mode": sync_mode.value, - "destination_sync_mode": "append", - } - ) - - return catalog - - def input_state(self) -> List[Mapping[str, Any]]: - if self.incremental_scenario_config: - return self.incremental_scenario_config.input_state - else: - return [] - - -class TestScenarioBuilder(Generic[SourceType]): - """ - A builder that creates a TestScenario instance for a source of type SourceType - """ - - def __init__(self) -> None: - self._name = "" - self._config: Mapping[str, Any] = {} - self._catalog: Optional[ConfiguredAirbyteCatalog] = None - self._expected_spec: Optional[Mapping[str, Any]] = None - self._expected_check_status: Optional[str] = None - self._expected_catalog: Mapping[str, Any] = {} - self._expected_logs: Optional[Mapping[str, Any]] = None - self._expected_records: List[Mapping[str, Any]] = [] - self._expected_check_error: Tuple[Optional[Type[Exception]], Optional[str]] = None, None - self._expected_discover_error: Tuple[Optional[Type[Exception]], Optional[str]] = None, None - self._expected_read_error: Tuple[Optional[Type[Exception]], Optional[str]] = None, None - self._incremental_scenario_config: Optional[IncrementalScenarioConfig] = None - self._expected_analytics: Optional[List[AirbyteAnalyticsTraceMessage]] = None - self.source_builder: Optional[SourceBuilder[SourceType]] = None - self._log_levels = None - - def set_name(self, name: str) -> "TestScenarioBuilder[SourceType]": - self._name = name - return self - - def set_config(self, config: Mapping[str, Any]) -> "TestScenarioBuilder[SourceType]": - self._config = config - return self - - def set_expected_spec(self, expected_spec: Mapping[str, Any]) -> "TestScenarioBuilder[SourceType]": - self._expected_spec = expected_spec - return self - - def set_catalog(self, catalog: ConfiguredAirbyteCatalog) -> "TestScenarioBuilder[SourceType]": - self._catalog = catalog - return self - - def set_expected_check_status(self, expected_check_status: str) -> "TestScenarioBuilder[SourceType]": - self._expected_check_status = expected_check_status - return self - - def set_expected_catalog(self, expected_catalog: Mapping[str, Any]) -> "TestScenarioBuilder[SourceType]": - self._expected_catalog = expected_catalog - return self - - def set_expected_logs(self, expected_logs: Mapping[str, List[Mapping[str, Any]]]) -> "TestScenarioBuilder[SourceType]": - self._expected_logs = expected_logs - return self - - def set_expected_records(self, expected_records: Optional[List[Mapping[str, Any]]]) -> "TestScenarioBuilder[SourceType]": - self._expected_records = expected_records - return self - - def set_incremental_scenario_config(self, incremental_scenario_config: IncrementalScenarioConfig) -> "TestScenarioBuilder[SourceType]": - self._incremental_scenario_config = incremental_scenario_config - return self - - def set_expected_check_error(self, error: Optional[Type[Exception]], message: str) -> "TestScenarioBuilder[SourceType]": - self._expected_check_error = error, message - return self - - def set_expected_discover_error(self, error: Type[Exception], message: str) -> "TestScenarioBuilder[SourceType]": - self._expected_discover_error = error, message - return self - - def set_expected_read_error(self, error: Type[Exception], message: str) -> "TestScenarioBuilder[SourceType]": - self._expected_read_error = error, message - return self - - def set_log_levels(self, levels: Set[str]) -> "TestScenarioBuilder": - self._log_levels = levels - return self - - def set_source_builder(self, source_builder: SourceBuilder[SourceType]) -> "TestScenarioBuilder[SourceType]": - self.source_builder = source_builder - return self - - def set_expected_analytics(self, expected_analytics: Optional[List[AirbyteAnalyticsTraceMessage]]) -> "TestScenarioBuilder[SourceType]": - self._expected_analytics = expected_analytics - return self - - def copy(self) -> "TestScenarioBuilder[SourceType]": - return deepcopy(self) - - def build(self) -> "TestScenario[SourceType]": - if self.source_builder is None: - raise ValueError("source_builder is not set") - if self._incremental_scenario_config and self._incremental_scenario_config.input_state: - state = [ - AirbyteStateMessageSerializer.load(s) if isinstance(s, dict) else s for s in self._incremental_scenario_config.input_state - ] - else: - state = None - source = self.source_builder.build( - self._configured_catalog(SyncMode.incremental if self._incremental_scenario_config else SyncMode.full_refresh), - self._config, - state, - ) - return TestScenario( - self._name, - self._config, - source, - self._expected_spec, - self._expected_check_status, - self._expected_catalog, - self._expected_logs, - self._expected_records, - self._expected_check_error, - self._expected_discover_error, - self._expected_read_error, - self._incremental_scenario_config, - self._expected_analytics, - self._log_levels, - self._catalog, - ) - - def _configured_catalog(self, sync_mode: SyncMode) -> Optional[Mapping[str, Any]]: - if not self._expected_catalog: - return None - catalog: Mapping[str, Any] = {"streams": []} - for stream in self._expected_catalog["streams"]: - catalog["streams"].append( - { - "stream": stream, - "sync_mode": sync_mode.value, - "destination_sync_mode": "append", - } - ) - - return catalog diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/unstructured_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/unstructured_scenarios.py deleted file mode 100644 index 97c0c491510a..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/unstructured_scenarios.py +++ /dev/null @@ -1,602 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import base64 - -import nltk -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from unit_tests.sources.file_based.scenarios.file_based_source_builder import FileBasedSourceBuilder -from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenarioBuilder - -# import nltk data for pdf parser -nltk.download("punkt") -nltk.download("averaged_perceptron_tagger") - -json_schema = { - "type": "object", - "properties": { - "content": { - "type": ["null", "string"], - "description": "Content of the file as markdown. Might be null if the file could not be parsed", - }, - "document_key": {"type": ["null", "string"], "description": "Unique identifier of the document, e.g. the file path"}, - "_ab_source_file_parse_error": { - "type": ["null", "string"], - "description": "Error message if the file could not be parsed even though the file is supported", - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, -} - -simple_markdown_scenario = ( - TestScenarioBuilder() - .set_name("simple_markdown_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "unstructured"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.md": { - "contents": bytes( - "# Title 1\n\n## Title 2\n\n### Title 3\n\n#### Title 4\n\n##### Title 5\n\n###### Title 6\n\n", "UTF-8" - ), - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.md": { - "contents": bytes("Just some text", "UTF-8"), - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "c": { - "contents": bytes("Detected via mime type", "UTF-8"), - "last_modified": "2023-06-05T03:54:07.000Z", - "mime_type": "text/markdown", - }, - } - ) - .set_file_type("unstructured") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": json_schema, - "name": "stream1", - "source_defined_cursor": True, - "source_defined_primary_key": [["document_key"]], - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "document_key": "a.md", - "content": "# Title 1\n\n## Title 2\n\n### Title 3\n\n#### Title 4\n\n##### Title 5\n\n###### Title 6\n\n", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.md", - }, - "stream": "stream1", - }, - { - "data": { - "document_key": "b.md", - "content": "Just some text", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.md", - }, - "stream": "stream1", - }, - { - "data": { - "document_key": "c", - "content": "Detected via mime type", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "c", - }, - "stream": "stream1", - }, - ] - ) -).build() - -simple_txt_scenario = ( - TestScenarioBuilder() - .set_name("simple_txt_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "unstructured"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.txt": { - "contents": bytes("Just some raw text", "UTF-8"), - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b": { - "contents": bytes("Detected via mime type", "UTF-8"), - "last_modified": "2023-06-05T03:54:07.000Z", - "mime_type": "text/plain", - }, - } - ) - .set_file_type("unstructured") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": json_schema, - "name": "stream1", - "source_defined_cursor": True, - "source_defined_primary_key": [["document_key"]], - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "document_key": "a.txt", - "content": "Just some raw text", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.txt", - }, - "stream": "stream1", - }, - { - "data": { - "document_key": "b", - "content": "Detected via mime type", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b", - }, - "stream": "stream1", - }, - ] - ) -).build() - -# If skip unprocessable file types is set to false, then discover will fail if it encounters a non-matching file type -unstructured_invalid_file_type_discover_scenario_no_skip = ( - TestScenarioBuilder() - .set_name("unstructured_invalid_file_type_discover_scenario_no_skip") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "unstructured", "skip_unprocessable_files": False}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": bytes("Just a humble text file", "UTF-8"), - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("unstructured") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": json_schema, - "name": "stream1", - "source_defined_cursor": True, - "source_defined_primary_key": [["document_key"]], - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records([]) - .set_expected_discover_error(AirbyteTracedException, "Error inferring schema from files") - .set_expected_read_error( - AirbyteTracedException, - "Please check the logged errors for more information.", - ) -).build() - -# If skip unprocessable file types is set to true, then discover will succeed even if there are non-matching file types -unstructured_invalid_file_type_discover_scenario_skip = ( - TestScenarioBuilder() - .set_name("unstructured_invalid_file_type_discover_scenario_skip") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "unstructured", "skip_unprocessable_files": True}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": bytes("Just a humble text file", "UTF-8"), - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("unstructured") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": json_schema, - "name": "stream1", - "source_defined_cursor": True, - "source_defined_primary_key": [["document_key"]], - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "document_key": "a.csv", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - "_ab_source_file_parse_error": "Error parsing record. This could be due to a mismatch between the config's file type and the actual file type, or because the file or record is not parseable. Contact Support if you need assistance.\nfilename=a.csv message=File type FileType.CSV is not supported. Supported file types are FileType.MD, FileType.PDF, FileType.DOCX, FileType.PPTX, FileType.TXT", - }, - "stream": "stream1", - } - ] - ) -).build() - -# TODO When working on https://github.com/airbytehq/airbyte/issues/31605, this test should be split into two tests: -# 1. Test that the file is skipped if skip_unprocessable_files is set to true -# 2. Test that the sync fails if skip_unprocessable_files is set to false -unstructured_invalid_file_type_read_scenario = ( - TestScenarioBuilder() - .set_name("unstructured_invalid_file_type_read_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "unstructured", "skip_unprocessable_files": False}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.md": { - "contents": bytes("A harmless markdown file", "UTF-8"), - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.csv": { - "contents": bytes("An evil text file", "UTF-8"), - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("unstructured") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": json_schema, - "name": "stream1", - "source_defined_cursor": True, - "source_defined_primary_key": [["document_key"]], - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "document_key": "a.md", - "content": "A harmless markdown file", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.md", - }, - "stream": "stream1", - }, - ] - ) -).build() - -pdf_file = base64.b64decode( - "JVBERi0xLjEKJcKlwrHDqwoKMSAwIG9iagogIDw8IC9UeXBlIC9DYXRhbG9nCiAgICAgL1BhZ2VzIDIgMCBSCiAgPj4KZW5kb2JqCgoyIDAgb2JqCiAgPDwgL1R5cGUgL1BhZ2VzCiAgICAgL0tpZHMgWzMgMCBSXQogICAgIC9Db3VudCAxCiAgICAgL01lZGlhQm94IFswIDAgMzAwIDE0NF0KICA+PgplbmRvYmoKCjMgMCBvYmoKICA8PCAgL1R5cGUgL1BhZ2UKICAgICAgL1BhcmVudCAyIDAgUgogICAgICAvUmVzb3VyY2VzCiAgICAgICA8PCAvRm9udAogICAgICAgICAgIDw8IC9GMQogICAgICAgICAgICAgICA8PCAvVHlwZSAvRm9udAogICAgICAgICAgICAgICAgICAvU3VidHlwZSAvVHlwZTEKICAgICAgICAgICAgICAgICAgL0Jhc2VGb250IC9UaW1lcy1Sb21hbgogICAgICAgICAgICAgICA+PgogICAgICAgICAgID4+CiAgICAgICA+PgogICAgICAvQ29udGVudHMgNCAwIFIKICA+PgplbmRvYmoKCjQgMCBvYmoKICA8PCAvTGVuZ3RoIDU1ID4+CnN0cmVhbQogIEJUCiAgICAvRjEgMTggVGYKICAgIDAgMCBUZAogICAgKEhlbGxvIFdvcmxkKSBUagogIEVUCmVuZHN0cmVhbQplbmRvYmoKCnhyZWYKMCA1CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxOCAwMDAwMCBuIAowMDAwMDAwMDc3IDAwMDAwIG4gCjAwMDAwMDAxNzggMDAwMDAgbiAKMDAwMDAwMDQ1NyAwMDAwMCBuIAp0cmFpbGVyCiAgPDwgIC9Sb290IDEgMCBSCiAgICAgIC9TaXplIDUKICA+PgpzdGFydHhyZWYKNTY1CiUlRU9GCg==" -) - -docx_file = base64.b64decode( - "UEsDBBQACAgIAEkqVFcAAAAAAAAAAAAAAAASAAAAd29yZC9udW1iZXJpbmcueG1spZNNTsMwEIVPwB0i79skFSAUNe2CCjbsgAO4jpNYtT3W2Eno7XGbv1IklIZV5Izf98bj5/X2S8mg5mgF6JTEy4gEXDPIhC5S8vnxsngigXVUZ1SC5ik5cku2m7t1k+hK7Tn6fYFHaJsolpLSOZOEoWUlV9QuwXDtizmgos4vsQgVxUNlFgyUoU7shRTuGK6i6JF0GEhJhTrpEAslGIKF3J0kCeS5YLz79Aqc4ttKdsAqxbU7O4bIpe8BtC2FsT1NzaX5YtlD6r8OUSvZ72vMFLcMaePnrGRr1ABmBoFxa/3fXVsciHE0YYAnxKCY0sJPz74TRYUeMKd0XIEG76X37oZ2Ro0HGWdh5ZRG2tKb2CPF4+8u6Ix5XuqNmJTiK4JXuQqHQM5BsJKi6wFyDkECO/DsmeqaDmHOiklxviJlghZI1RhSe9PNxtFVXN5LavhIK/5He0WozBj3+zm0ixcYP9wGWPWAcPMNUEsHCEkTQ39oAQAAPQUAAFBLAwQUAAgICABJKlRXAAAAAAAAAAAAAAAAEQAAAHdvcmQvc2V0dGluZ3MueG1spZVLbtswEIZP0DsY3Nt6xHYLIXKAJGi7aFZODzAmKYkwXyApq759qQcl2wEKxV2J/IfzzXA0Gj0+/RF8caLGMiVzlKxitKASK8JkmaPf79+X39DCOpAEuJI0R2dq0dPuy2OTWeqcP2UXniBtJnCOKud0FkUWV1SAXSlNpTcWyghwfmvKSIA51nqJldDg2IFx5s5RGsdbNGBUjmojswGxFAwbZVXhWpdMFQXDdHgEDzMnbu/yqnAtqHRdxMhQ7nNQ0lZM20AT99K8sQqQ078ucRI8nGv0nGjEQOMLLXgfqFGGaKMwtdarr71xJCbxjAK2iNFjTgrXMUMmApgcMW1z3IDG2Csfeyhah5ouMtXC8jmJ9KZf7GDAnD9mAXfU89Jfs1ldfEPwXq42Y0Peg8AVGBcA/B4CV/hIyQvIE4zNTMpZ7XxDIgxKA2JqUvupN5vEN+2yr0DTiVb+H+2HUbWe2n19D+3iC0w2nwOkAbDzI5AwqzmcnwEfS5+WJN1VF012At/NCYq6Q7SAmrt3OOyd0sH4NY17cz8Kp9W+H6sjZIP8UoLwn9fV1HxThLam2rD5N2hDRlcxudm3TvQNtO7DHsokR5yVlUtavvM74qd2tzmU6WBLO1va27oNYOyHoT89LCYtDdrFuYegPUzaOmjrSdsEbTNp26BtW606a2o4k0dfhrBs9UJxrhpKfk72D9JQj/Ar2/0FUEsHCAbSYFUWAgAADwcAAFBLAwQUAAgICABJKlRXAAAAAAAAAAAAAAAAEgAAAHdvcmQvZm9udFRhYmxlLnhtbKWUTU7DMBCFT8AdIu/bpAgQippUCAQbdsABBsdJrNoea+w09Pa4ND9QJJSGVZSM3/fG4xevNx9aRTtBTqLJ2GqZsEgYjoU0VcbeXh8XtyxyHkwBCo3I2F44tskv1m1aovEuCnLjUs0zVntv0zh2vBYa3BKtMKFYImnw4ZWqWANtG7vgqC14+S6V9Pv4MkluWIfBjDVk0g6x0JITOiz9QZJiWUouukevoCm+R8kD8kYL478cYxIq9IDG1dK6nqbn0kKx7iG7vzax06pf19opbgVBG85Cq6NRi1RYQi6cC18fjsWBuEomDPCAGBRTWvjp2XeiQZoBc0jGCWjwXgbvbmhfqHEj4yycmtLIsfQs3wlo/7sLmDHP73orJ6X4hBBUvqEhkHMQvAbyPUDNISjkW1Hcg9nBEOaimhTnE1IhoSLQY0jdWSe7Sk7i8lKDFSOt+h/tibCxY9yv5tC+/YGr6/MAlz0g7+6/qE0N6BD+O5KgWJyv4+5izD8BUEsHCK2HbQB5AQAAWgUAAFBLAwQUAAgICABJKlRXAAAAAAAAAAAAAAAADwAAAHdvcmQvc3R5bGVzLnhtbN2X7W7aMBSGr2D3gPK/TUgCQ6hp1Q91m1R11dpdwCExxMKxLduBsqufnS8gCVUakNYOfgQf+7zn+PFxbC6uXhMyWCEhMaOBNTx3rAGiIYswXQTW75f7s4k1kApoBIRRFFgbJK2ryy8X66lUG4LkQPtTOU3CwIqV4lPblmGMEpDnjCOqO+dMJKB0UyzsBMQy5WchSzgoPMMEq43tOs7YKmRYYKWCTguJswSHgkk2V8ZlyuZzHKLiUXqILnFzlzsWpgmiKotoC0R0DozKGHNZqiV91XRnXIqs3prEKiHluDXvEi0SsNaLkZA80JqJiAsWIim19S7vrBSHTgeARqLy6JLCfswykwQwrWRMadSEqtjnOnYBLZPaTmTLQpIuieRdD3gmQGyaWUAPnrv+HHeq4pqC9lKpqAqyj0QYg1ClAOmjQFi4RNEt0BVUxRwtOpVzTSnCsBCQbItUvmtlh06tXJ5j4GirtjhO7ZtgKd+Wu99HbWcHDkfvE3BLgUv9AoxYeIfmkBIlTVM8iaJZtLLHPaNKDtZTkCHGgXUtMOjw62kodxoIpLqWGHZM8TWV1XjbSMk/2rwCvVFct7TcyrqNAF2UNkSNzS6Ssesp8nor0+QQ4kyCYLOp3a9jq2j8Sok2QKpYIcsL2V0hu8ElOye0hNpw7c5BmPrisVHNun5EgfVo6jGbd5R76qMoY0whQeV0aD4oj525NuUVzAjak34xlk762cjBY4co7ZP4jsAcm03hOO8YDPMlmoFE0U9a9m4Dai/0qtrsxeIsEeKPO0MKQWN+0Aska3YOC3QjECxvkN7wVTpOUT3VSsNcIX2ODl3HzGeWDQ4s33HeXvmqyLeV6TvNysxtO1XYB6p7EKr7qaB6465QZ3XlCrLXsv1z25GQvYOQvY8NebLP2O3LOGSEiapuPfNtvHsnLe/eyQng+wfh+58JvjvpCn8P9jj7NGD7LbD9E8AeHYQ9+lSw/VPCPnirOBL2+CDs8f8JG9fC/hP4L1jpm1DjjpNZPzT18R71999BRi0oR0ehfE5nqpVm1fGhgXpuL6In/OuCayl22BBey03SO3CTLH/Jy79QSwcI2niuUysDAADPEgAAUEsDBBQACAgIAEkqVFcAAAAAAAAAAAAAAAARAAAAd29yZC9kb2N1bWVudC54bWyllV1u2zAMx0+wOwR6bx0H6VYYTfrQoMOAbQja7QCKJNtCJVGg5GTZ6Ud/t2lRuJlfZIrij3/JNHVz+8ea2V5h0OBWLL2cs5lyAqR2xYr9/nV/cc1mIXInuQGnVuyoArtdf7o5ZBJEZZWLMyK4kFmxYmWMPkuSIEplebgErxw5c0DLI5lYJJbjU+UvBFjPo95po+MxWcznn1mHgRWr0GUd4sJqgRAgj3VIBnmuheqGPgKn5G1DNp3kJmOCypAGcKHUPvQ0ey6NnGUP2b+3ib01/bqDn5JNIj/Q57CmTXQAlB5BqBBodtM6B2I6n3CANWKImCLhZc5eieXaDZi6OE5AQ+5Lyt0dWoMaNzKeRTBThLSu73qHHI+vVfAzzvN5vNeTqviEQFGxwqEgz0GIkmPsAeYcggHxpOQdd3s+FLMsJpXzCUlqXiC3Y5GGD33ZdH5SLo8l92qkFf9H+4pQ+bHcl+fQnv2B6dXHAIsesKYWuOPiqSA9Ts4OmQAD1Ivum4cljR/ksR49uanDyocVm3cP66Y2yrye3L6eetionFcmvuHZ4ovJdJl5jvybHGbTRqzfYj3gFklbMtrvCXlD8Mt0HbEZoqEle15jWJui8zRXRBY8F9QjPKqgcK/Y+g5cpPZZL4zt8lZXHRKUiG2wLx7/Ereky+nqetnIoJaVLhbtO6AmBmEBI3Id24P3xQ9eb2wHMQL9A+myXR3Bj4ZReRwt1EX5zCwVl4p2+mXRmDlA7M0uw8/K/jp6RU66H7EO7Xbda0/6AkjGy3L9D1BLBwi8KP69SwIAAHEHAABQSwMEFAAICAgASSpUVwAAAAAAAAAAAAAAABwAAAB3b3JkL19yZWxzL2RvY3VtZW50LnhtbC5yZWxzrZJNasMwEIVP0DuI2dey0x9KiZxNCGRb3AMo8viHWiMhTUp9+4qUJA4E04WX74l5882M1psfO4hvDLF3pKDIchBIxtU9tQo+q93jG4jImmo9OEIFI0bYlA/rDxw0p5rY9T6KFEJRQcfs36WMpkOrY+Y8UnppXLCakwyt9Np86RblKs9fZZhmQHmTKfa1grCvCxDV6PE/2a5peoNbZ44Wie+0kJxqMQXq0CIrOMk/s8hSGMj7DKslGSIyp+XGK8bZmUN4WhKhccSVPgyTVVysOYjnJSHoaA8Y0txXiIs1B/Gy6DF4HHB6ipM+t5c3n7z8BVBLBwiQAKvr8QAAACwDAABQSwMEFAAICAgASSpUVwAAAAAAAAAAAAAAAAsAAABfcmVscy8ucmVsc43POw7CMAwG4BNwh8g7TcuAEGrSBSF1ReUAUeKmEc1DSXj09mRgAMTAaPv3Z7ntHnYmN4zJeMegqWog6KRXxmkG5+G43gFJWTglZu+QwYIJOr5qTziLXHbSZEIiBXGJwZRz2FOa5IRWpMoHdGUy+mhFLmXUNAh5ERrppq63NL4bwD9M0isGsVcNkGEJ+I/tx9FIPHh5tejyjxNfiSKLqDEzuPuoqHq1q8IC5S39eJE/AVBLBwgtaM8isQAAACoBAABQSwMEFAAICAgASSpUVwAAAAAAAAAAAAAAABUAAAB3b3JkL3RoZW1lL3RoZW1lMS54bWztWUtv2zYcvw/YdyB0b2XZVuoEdYrYsdutTRskboceaYmW2FCiQNJJfBva44ABw7phhxXYbYdhW4EW2KX7NNk6bB3Qr7C/HpYpm86jTbcOrQ82Sf3+7wdJ+fKVw4ihfSIk5XHbci7WLERij/s0DtrW7UH/QstCUuHYx4zHpG1NiLSurH/4wWW8pkISEQT0sVzDbStUKlmzbenBMpYXeUJieDbiIsIKpiKwfYEPgG/E7HqttmJHmMYWinEEbG+NRtQjaJCytNanzHsMvmIl0wWPiV0vk6hTZFh/z0l/5ER2mUD7mLUtkOPzgwE5VBZiWCp40LZq2cey1y/bJRFTS2g1un72KegKAn+vntGJYFgSOv3m6qXNkn8957+I6/V63Z5T8ssA2PPAUmcB2+y3nM6UpwbKh4u8uzW31qziNf6NBfxqp9NxVyv4xgzfXMC3aivNjXoF35zh3UX9Oxvd7koF787wKwv4/qXVlWYVn4FCRuO9BXQazzIyJWTE2TUjvAXw1jQBZihby66cPlbLci3C97joAyALLlY0RmqSkBH2ANfFjA4FTQXgNYK1J/mSJxeWUllIeoImqm19nGCoiBnk5bMfXz57go7uPz26/8vRgwdH9382UF3DcaBTvfj+i78ffYr+evLdi4dfmfFSx//+02e//fqlGah04POvH//x9PHzbz7/84eHBviGwEMdPqARkegmOUA7PALDDALIUJyNYhBiqlNsxIHEMU5pDOieCivomxPMsAHXIVUP3hHQAkzAq+N7FYV3QzFW1AC8HkYV4BbnrMOF0abrqSzdC+M4MAsXYx23g/G+SXZ3Lr69cQK5TE0suyGpqLnNIOQ4IDFRKH3G9wgxkN2ltOLXLeoJLvlIobsUdTA1umRAh8pMdI1GEJeJSUGId8U3W3dQhzMT+02yX0VCVWBmYklYxY1X8VjhyKgxjpiOvIFVaFJydyK8isOlgkgHhHHU84mUJppbYlJR9zq0DnPYt9gkqiKFonsm5A3MuY7c5HvdEEeJUWcahzr2I7kHKYrRNldGJXi1QtI5xAHHS8N9hxJ1ttq+TYPQnCDpk7EwlQTh1XqcsBEmcdHhK706ovFxjTuCvo3Pu3FDq3z+7aP/UcveACeYama+US/DzbfnLhc+ffu78yYex9sECuJ9c37fnN/F5rysns+/Jc+6sK0ftDM20dJT94gytqsmjNyQWf+WYJ7fh8VskhGVh/wkhGEhroILBM7GSHD1CVXhbogTEONkEgJZsA4kSriEq4W1lHd2P6Vgc7bmTi+VgMZqi/v5ckO/bJZsslkgdUGNlMFphTUuvZ4wJweeUprjmqW5x0qzNW9C3SCcvkpwVuq5aEgUzIif+j1nMA3LGwyRU9NiFGKfGJY1+5zGG/GmeyYlzsfJtQUn24vVxOLqDB20rVW37lrIw0nbGsFpCYZRAvxk2mkwC+K25ancwJNrcc7iVXNWOTV3mcEVEYmQahPLMKfKHk1fpcQz/etuM/XD+RhgaCan06LRcv5DLez50JLRiHhqycpsWjzjY0XEbugfoCEbix0Mejfz7PKphE5fn04E5HazSLxq4Ra1Mf/KpqgZzJIQF9ne0mKfw7NxqUM209Szl+j+iqY0ztEU9901Jc1cOJ82/OzSBLu4wCjN0bbFhQo5dKEkpF5fwL6fyQK9EJRFqhJi6QvoVFeyP+tbOY+8yQWh2qEBEhQ6nQoFIduqsPMEZk5d3x6njIo+U6ork/x3SPYJG6TVu5Lab6Fw2k0KR2S4+aDZpuoaBv23+ODSfKWNZyaoeZbNr6k1fW0rWH09FU6zAWvi6maL6+7SnWd+q03gloHSL2jcVHhsdjwd8B2IPir3eQSJeKFVlF+5OASdW5pxKat/6xTUWhLv8zw7as5uLHH28eJe3dmuwdfu8a62F0vU1u4h2Wzhjyg+vAeyN+F6M2b5ikxglg+2RWbwkPuTYshk3hJyR0xbOot3yAhR/3Aa1jmPFv/0lJv5Ti4gtb0kbJxMWOBnm0hJXD+ZuKSY3vFK4uwWZ2LAZpJzfB7lskWWnmLx67jsFMqbXWbM3tO67BSBegWXqcPjXVZ4yjYlHjlUAnenf11B/tqzlF3/B1BLBwghWqKELAYAANsdAABQSwMEFAAICAgASSpUVwAAAAAAAAAAAAAAABMAAABbQ29udGVudF9UeXBlc10ueG1stZNNbsIwEIVP0DtE3lbE0EVVVQQW/Vm2XdADDM4ErPpPnoHC7TsJkAUCqZWajWX7zbz3eSRP5zvvii1msjFUalKOVYHBxNqGVaU+F6+jB1UQQ6jBxYCV2iOp+exmutgnpEKaA1VqzZwetSazRg9UxoRBlCZmDyzHvNIJzBesUN+Nx/faxMAYeMSth5pNn7GBjePi6XDfWlcKUnLWAAuXFjNVvOxEPGC2Z/2Lvm2oz2BGR5Ayo+tqaG0T3Z4HiEptwrtMJtsa/xQRm8YarKPZeGkpv2OuU44GiWSo3pWEzLI7pn5A5jfwYqvbSn1Sy+Mjh0HgvcNrAJ02aHwjXgtYOrxM0MuDQoSNX2KW/WWIXh4Uolc82HAZpC/5Rw6Wj3pl+J10WCenSN399tkPUEsHCDOvD7csAQAALQQAAFBLAQIUABQACAgIAEkqVFdJE0N/aAEAAD0FAAASAAAAAAAAAAAAAAAAAAAAAAB3b3JkL251bWJlcmluZy54bWxQSwECFAAUAAgICABJKlRXBtJgVRYCAAAPBwAAEQAAAAAAAAAAAAAAAACoAQAAd29yZC9zZXR0aW5ncy54bWxQSwECFAAUAAgICABJKlRXrYdtAHkBAABaBQAAEgAAAAAAAAAAAAAAAAD9AwAAd29yZC9mb250VGFibGUueG1sUEsBAhQAFAAICAgASSpUV9p4rlMrAwAAzxIAAA8AAAAAAAAAAAAAAAAAtgUAAHdvcmQvc3R5bGVzLnhtbFBLAQIUABQACAgIAEkqVFe8KP69SwIAAHEHAAARAAAAAAAAAAAAAAAAAB4JAAB3b3JkL2RvY3VtZW50LnhtbFBLAQIUABQACAgIAEkqVFeQAKvr8QAAACwDAAAcAAAAAAAAAAAAAAAAAKgLAAB3b3JkL19yZWxzL2RvY3VtZW50LnhtbC5yZWxzUEsBAhQAFAAICAgASSpUVy1ozyKxAAAAKgEAAAsAAAAAAAAAAAAAAAAA4wwAAF9yZWxzLy5yZWxzUEsBAhQAFAAICAgASSpUVyFaooQsBgAA2x0AABUAAAAAAAAAAAAAAAAAzQ0AAHdvcmQvdGhlbWUvdGhlbWUxLnhtbFBLAQIUABQACAgIAEkqVFczrw+3LAEAAC0EAAATAAAAAAAAAAAAAAAAADwUAABbQ29udGVudF9UeXBlc10ueG1sUEsFBgAAAAAJAAkAQgIAAKkVAAAAAA==" -) - -pptx_file = base64.b64decode( - "UEsDBBQAAAAIAHFwW1fGr8RntAEAALoMAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbM2XyU7DMBCG7zxFlEsOqHHZFzXlwHJiqQQ8gEmmrcGxLc+00Ldnki6q2FKWCl8S2TPz/58nUTTpnLyUOhqDR2VNlmyl7SQCk9tCmUGW3N9dtA6TCEmaQmprIEsmgMlJd6NzN3GAERcbzOIhkTsWAvMhlBJT68BwpG99KYmXfiCczJ/kAMR2u70vcmsIDLWo0oi7nTPoy5Gm6PyFt2uQ+EGZODqd5lVWWSyd0yqXxGExNsUbk5bt91UOhc1HJZekzgPyvU4vNS8VS/lbIOKDYSw+NH10MHjjqsqKug58XONB4/dIZ61IubLOwaFyuMkJnzhUkc8NZnU3/Ai9KiDqSU/XsuQswc3oeetQcH76tUpzQ6ECKqBoOZYETwoWzF9659bD983nPaqqV3R0jkT11GvbXx/33fszE16FYF63DoiFdimVaYJBzZuXcmJHhMuLrb8mW9L+MVM7RKgQO7UdINNOgEy7ATLtBci0HyDTQYBMhwEyHf0305VEnqtwebGeb+ZUeyWmGc16OJoISD5ouKWJhj8fQpakGyl4EIfp9fdtqGWaHMcKntcyei2E5wSi/vXovgJQSwMEFAAAAAgAcXBbV/ENN+wAAQAA4QIAAAsAAABfcmVscy8ucmVsc62Sz04DIRCH7z4F2QunLttqjDFlezEmvRlTH2CE6S51gQlMTfv2ool/arZNDz3C/PjmG2C+2PlBvGPKLgYtp3UjBQYTrQudli+rx8mdFJkhWBhiQC33mOWivZo/4wBczuTeURYFErKuema6VyqbHj3kOhKGUlnH5IHLMnWKwLxBh2rWNLcq/WVU7QFTLK2u0tJOK7HaE57Djuu1M/gQzdZj4JEW/xKFDKlD1hURK0qYy+ZXui7kSo0Lzc4XOj6s8shggUFxv/WvAdzwa2OjeUqxhH5q9YawOyZ0fVkhExNOqPTHxA7ziNZn4tQN3VzyyXDHGCza00pA9G2kDn5m+wFQSwMEFAAAAAgAcXBbVwV3nA87AgAAtAwAABQAAABwcHQvcHJlc2VudGF0aW9uLnhtbO2X327aMBTG7/cUlm+4mGj+EJI0wlRaJ6RJnYQKfQDXOUBUx4lsh0GffnZwSGCa1AfIne1zvu+c/GxZzuLpVHJ0BKmKSpBJ8OBPEAhW5YXYk8nbdjVNJ0hpKnLKKwFkcgY1eVp+W9RZLUGB0FQbJTIuQmWU4IPWdeZ5ih2gpOqhqkGY2K6SJdVmKvdeLukf415yL/T92CtpIbDTy6/oq92uYPCzYk1pyl9MJPC2D3UoatW51V9xG37FbUuKHmHTvCvQq0poRXCAEW109VyVVqTWBdONGRDs46XhoXj+myoN8lf+ovTdCipygsMgSqJ0FkcpRjKzKyYSYG+58P4jvx1fTObxQJ306mHu5hOxE8GPQRT5vo8ROxMcp/O0nehzDQQrJgFEdJpZhzoTlQblZNdMK+s82qwcdrThegsnvdFnDssFtWvrtXSj17VEnJqzg0FM3zZtd8MUfuRBbXJKKl8sOET5XhDMMTI5W/q++SQ4miehrS41b1OAvogf8qPdALvNwk1N6GBKmbO0bgTTNj7oQhmnILU+HyBNicB62riqeJGvCs7biT0Z8MwlOlJTTZ8C1/JNVlu15bajzLD7Xoop1zaTZkDvAkAvAabuAkz1OF4tDu/Kw6EJezQdhJFP2POZ9Xwux3Lkc4Hi+EQ9n2CWBPEIqKPiAM0HgNIwTUdAHRUHKO4BhWEa+yOgjooDlAwAJdFsvKOvVBygtAdk6YyX9JWKA/Q4ABTPk/GSvlJpX7L/PjG923+N5V9QSwMEFAAAAAgAcXBbV1KcUMkcAQAAcQQAAB8AAABwcHQvX3JlbHMvcHJlc2VudGF0aW9uLnhtbC5yZWxzrZTBTsMwDIbvPEWUS0407YCB0NJdENIOSIiNB8hat41IkygOg709EUxbW20Vhx792/79yYqzWH63muzAo7JGsCxJGQFT2FKZWrD3zfP1AyMYpCmltgYE2wOyZX61eAMtQ+zBRjkk0cSgoE0I7pFzLBpoJSbWgYmZyvpWhhj6mjtZfMga+CxN59x3PWje8ySrUlC/KjNKNnsH//G2VaUKeLLFZwsmnBnBUasSXiQG8NFW+hqCoB2xV5El0Z/y81izKbGcVyYOXEMIce14QhskhoVZslXmEuHNtISAr966HttBGlvT7ZQQOwVfA4ijNAZxNyVEiL1wAvgN/8TR9zKflEFuNazDXkNnFR1xDOR+8nsaXNJBPW6D936K/AdQSwMEFAAAAAgAcXBbV6YtojXuBgAA0i4AACEAAABwcHQvc2xpZGVNYXN0ZXJzL3NsaWRlTWFzdGVyMS54bWztWu9u4zYS/35PIeg+5MPBK4ki9cdYp4iddW+BdBs06QPQEm3rQks6ik6TPRTYd+gb9C3a+3aPsk9yQ0q0ZMeJE6zTru8MLCxqOBrOzG9mSE727Td3C27dMlFlRT448d64JxbLkyLN8tng5MfrcS86sSpJ85TyImeDk3tWnXxz+pe3Zb/i6Xe0kkxYICKv+nRgz6Us+45TJXO2oNWbomQ5zE0LsaASXsXMSQX9CUQvuINcN3AWNMvt5nvxnO+L6TRL2HmRLBcsl7UQwTiVoH41z8rKSCufI60UrAIx+us1lU7BvuSKp+o5mdW/P7CplaV3A9tzXQ84aF9LZiMurFvKB/Zk5tnO6VunYW5G6uOqvBaMqVF++60or8pLoVf4cHspQCaItK2cLtjAVgL0RMPm1B/pgbPx+cwMaf9uKhbqCe6xQEPXtu7Vr6No7E5aSU1MWmoy/34LbzJ/t4XbMQs4nUWVVbVyD81BxpzrTHJmXXKasHnBU4gVb2Wh0b0qL4rkprLyAmxTrqhNXXHU9qtnObfkfQlipRJrG5eoSaerSLXdK5iEgLA2F4U48KN1/0QIxYHb2O152HfddetpvxSV/JYVC0sNBrZgidSBQG8vKlmzGhatUtUoJO+GRXqvOCfwBCdBwsH380J8tC3+Pq8GduxhDGtL/aI1tS3RnZmszUg+KrhGieYJyBnYiRRalxzi+2wpi2nWaFQvqaZ4Ja/kPWfa7FL9aLIAhTiFfLdZ3vvxyraqhRxxRvNVWMjTEc+SG0sWFkszaTV5r2GA6gAi1UJSL6dFsjy9pIL+sCG5cZH2jfGJYwLp8XDyV+GksOpGE9pHNCkH2U1qf0lQeRA9yHWfiCpMEIkD/+uPqhcHUqmQvuWriPnCwFLe03FVrQWWY1ZbW9J74ZJXLCny1OLslvFniEcvFH89z8TzpfsvlD4ulkLOny0ev1R8Nt0qfd8pjU1Kn1O5vkH4+0jpVIJ1HyEXKJ82qY2+JLUDn8C/jdRGnu+vUtsPiIfI15/Za/uF001mPb7lnoodymcQFVwrm7KpAl2501P+0JAUPEvHGedbjkHyrj4dySyXNSUk7Va6Yq7fWjmOWUkPG0XqcUdBHd1Tnuog+hcZjs7O3Yj03kVnQS+KMOkNz/G73miIR6Mzl8TjEf7ZNjEBkSazBRtns6Vg3y9rKJ6TFJ6DQsfz24SYqpPhvlOCmJQYF4Uqgt2kwPtIiikgrmH855IKWKFJDP/FieF7CD+dGVFM/qczwxy2vr7c2G9MBiYmr0AXZn1YLiYbkUn2EZlwlQTR24ITvzg4A0L8/++y/bWG5qpsj7zxODg/i3uuG4170RBHvRhBAR8GBE7LEQ6j4XhVtisVeTlEx3Or9edPv/3186ff91Ctne7NHcIH0G9G1lJkYMhwGAdoFA17Qw+Pe/g8Dntn44D0xsTHeDSMzkb+u59VM8HD/UQw3Wd4n5oOhYcf9CgWWSKKqpjKN0mxaJodTln8xERZZLrf4blN00RDhJAbx2FIvLjJE9DNPLW2TtvHSLj4jpbWZObBzi498O8djNIbGE1mSNGQoiFFgxFNEpZL4GgGhoIMZcXjG4pvKNhQsKEQQyGGEhgK1Jg5z/IbcIZ62Na04H+vCWZU1xioEhf0vljK92mDRIdS9x08HOLID3AMudNXFPE+9R58vcZL3A4v2sHrdXj9Hbyow4t38PodXrKDF3d4gx28pMMb7uANOrzRDt6wwxvv4I26WLg7mNeAM1vHQ+DlnS4tlR6rLsQT+7QF9emaTq4+tid6qKu6qDJ6kQ/Fje6/qR5i3rzC1BxKRJbPLpd5ItV8vbMlQ9XX06PLpCmTqxK5mp0sPxR5fTnuVGEo7yD3hon8BRXZ2ay3YKFSVBfHKWzDA/tvi3/0uGz2OLoxwWjT2Ks2JpKqkb21eq97tdT72QMXL6i4gB0Uo1gZluVQpsFVPUMwd4jX9j9IdLdhMC5gI2uNPhMZ5bUzJsvRnAorgZ+B/fnTr/YmVPUB4jWgyh+DKn8MqvxpqPQQtXCE4H3ShQNFJCSHBMcvD+BA0QHAgVo4/BYO00fu4IGi4MDTA71aJdsjHn6LB+7g0fRoDxiPLfnhHgAeuMWDtHggl4T4kPH4z78PEw7SwhF04CAeDg4Zjq3l6hDwCFo8wg4ecehFRzz+BDzCFo9o87B7xOOPxyNq8Yg7eERRcODb+YHiEZuLYudqWPYLOWdidVGELy5r1BrrHvbdWpb1W+WrINhtiR7ClWL7Dc844eif7Vcu3Ug/+ufxK5Afeq9UIg/NQdvvJF6EoujooCduCXqPPTro8WN7iP1jjX7qHA3qHov0UwfbgITHIr1+0uweLp3u34Cczn9GP/0vUEsDBBQAAAAIAHFwW1e+a0K9DQEAAMYHAAAsAAAAcHB0L3NsaWRlTWFzdGVycy9fcmVscy9zbGlkZU1hc3RlcjEueG1sLnJlbHPF1d1qwyAUB/D7PYV449VikrZpWmp6MwaFXY3uAURPPliionYsbz/ZGDSwyQYFbwQ/zv/8ODceju/TiN7AukErRoosJwiU0HJQHSMv58f7miDnuZJ81AoYmcGRY3N3eIaR+1Dj+sE4FEKUY7j33uwpdaKHibtMG1DhptV24j5sbUcNF6+8A1rmeUXtdQZuFpnoJBm2J1lgdJ4N/CVbt+0g4EGLywTK/9CCunGQ8MRnffEhltsOPMNZdn2+eFRkoQWmv8jypLQ8aks7tvjcylvafKiFherz5GuNOm7K+O+IyphslVK2isnWKWXrmGyTUraJyaqUsiom26aUbWOyOqWsjsl2KWW7bxldfL/NB1BLAwQUAAAACABxcFtXAP3sDSoEAAAFEQAAIQAAAHBwdC9zbGlkZUxheW91dHMvc2xpZGVMYXlvdXQxLnhtbM1YXY7bNhB+7ykI9cFPCvVDSbQRb2DJq6LAZncRbw7AlWhbCCWqJO3YKQLkWu1xcpJSlGR5f9o6gAP4xaKomeE3882QHL99tysZ2FIhC15NR+4bZwRolfG8qFbT0ceH1MYjIBWpcsJ4RaejPZWjd1e/vK0nkuU3ZM83CmgTlZyQqbVWqp5AKLM1LYl8w2ta6W9LLkqi9KtYwVyQz9p0yaDnOCEsSVFZnb44RZ8vl0VG5zzblLRSrRFBGVEavlwXteyt1adYqwWV2ozRfgpJ7Ws6tVShGLWAERNbPeFaV9rzbMFyUJFSTzw0EmDBipyaT7J+EJQ2o2r7m6gX9b0wGrfbewGKvLHQaVqw+9CJwVbJDOAz9VU/JJPdUpTNUwcC7KaWY4F98wubObpTIGsns2E2W9+9Iputr1+Rhv0C8GjRxqsW3Et3POtJINyDVz1eWd/w7JMEFdf+NO637h0kWp+bZ73uop4pYaxZfSSa7/B4ffl6MEIcYKf10nN9B3nB07hEUeQhp/PXRZHjtBLHXstuCbWLeb5vtB/107BCJkyqhdozal7q5sfAEDoYjOiCsWhlf1xYQJYqYZRUh2irq4QV2SegOKB5ocB7IhUVwOSXLi9tsgGhDBRjklb5PRHkwzPLLdjaIO0Rwp6ff2fJ71labB7bNb1zECU3jy1RepHdoHI6Ya4fuWHHmI9xqAvwKWOhpgsfGIsCL3Re5OlJjJnxlrlaFpRE3Ji0L6pcV78ZEraqTOZZxsDmVm92xkBOlx+6AHFd5WnBmHlpNhWaMAG2hOmNYucaRVVUqp2JAucA9SDcvg124GAfHvB1UL0BKgqiJjIXiNcb8PoD3rGL0GXi9Qe8aMB7SMPLA4wGwMERYOxhfJmAgwFwOAD2PBw6lwk4HABHR4Aj5F9ozUUDYDwAbtBeaNHhAfD4CHAYRBdadOO6Hx+dHmc47mV/+v78Ex/1J/6cKAruGcnomrNcg/DPcfLnSnv9RV+xCVv2p7/z38c//IFb1VLfrxsv/gziZDZ3cGBf41loY4wCO56jazuJUZLMnGCcJuhrf1vPtauqKGlarDaC3m2UdSpbLvQi6PoDIxrA+TkJek5Szpt0OGYFnYOVpS4cQ8sfGyL0Cj0z/3Mx+xFmzhuR8HAvbRoocLspH5/FJTjLPZXl2vSrofF+QtImbpqG89nY1ndX3T/HCNtjT6dvHAaeN8YownF6SFrZeF5pdKfm6vdvf/36/dvfZ8hVeNyu6hv3jVTdCGxEoR2J43HoJTi2YxelNpqPI3uWhoGdBj5CSYxniX/9tWl7XTTJBDVt9O9534C76EULXhaZ4JIv1ZuMl10vD2v+mYqaF6add52uATfbt++G2ImCAPsdTRpb/zRoYduMmxRh4j2p77YmSUqz4SZmqi6qVZcjgwg8+v/i6h9QSwMEFAAAAAgAcXBbV4Bl4Yi3AAAANgEAACwAAABwcHQvc2xpZGVMYXlvdXRzL19yZWxzL3NsaWRlTGF5b3V0MS54bWwucmVsc43PvQ7CIBAH8N2nICxMQutgjCntYkwcXIw+wAWuLbEFwqHRt5fRJg6O9/X755ruNU/siYlc8FrUshIMvQnW+UGL2/W43glGGbyFKXjU4o0kunbVXHCCXG5odJFYQTxpPuYc90qRGXEGkiGiL5M+pBlyKdOgIpg7DKg2VbVV6dvg7cJkJ6t5Otmas+s74j926Htn8BDMY0aff0QompzFM1DGVFhIA2bNpfzuL5ZqWSK4ahu1eLf9AFBLAwQUAAAACABxcFtXN8Y1+I0DAADNCwAAIgAAAHBwdC9zbGlkZUxheW91dHMvc2xpZGVMYXlvdXQxMC54bWy1VsGO2zYQvfcrCPXgk5aSLHtlI97AkldFgU12UTu9MxK9JkKJLEk7dooA+a32c/IlHVKS197sAnbrXkSKGr5582Yozpu324qjDVWaiXrSC6+CHqJ1IUpWP056Hxa5n/SQNqQuCRc1nfR2VPfe3vz0Ro41L+/ITqwNAohaj8nEWxkjxxjrYkUroq+EpDV8WwpVEQOv6hGXinwG6IrjKAiGuCKs9tr96pT9YrlkBZ2JYl3R2jQginJigL5eMak7NHkKmlRUA4zbfUzJ7CSdeKCLWWw95OzUBlZC7wZCL+a8RDWpYGHBDKcI9EG/gzErCEcLujXOTMuFotTO6s0vSs7lg3K7328eFGKlRWtRPNx+aM1ws8lN8LPtj92UjLdLVdkRVEHbiRd4aGef2K4BCVQ0i8XTarG6f8G2WN2+YI07B/jAqY2qIfdjOJF3JEq4j6rjq+WdKD5pVAuIx4bfhLe3aGK2o1y1KTAWyutksB/xoXPdiWW2qSh31slHGN0iGXNt5mbHqXuR9uFoKODLCRS4R2v/w9xDujIZp6TeC2JuMs6KT8gIREtm0DuiDVXIkYHjAJBWHeM0cpC0Lh+IIr89Q25UlI50xxB3Er4uZL8T8qim0AMnBV0JXgKV6BLiWqk8JBSDQ9BUuwf+t0+bz1Hc/kUAhRJL2ntFf2kF2vC90P8xH1YVlw59lA/ceTtyGZ7pck4LAeea0w3lJ8BHZ8IvVkydjt4/Ez0Xa2VWJ8PH58Kz5Yvolz4JcXcSZsTQowPQv8QBKKHg9Re4KghfdqUfXO5vs4Rrwkbx5yDNprMgGfi3yXToJ0k88NNZfOtnaZxl02AwyrP4a3frlBCqYRXN2eNa0fu1vUxOy0qIo2sc9p8yAgQun5NBl5NcCHsKD7MSXyIrS6OatPyxJgo8dJn5N3+lVzJzWUWGnSJzzkqK3q+rj890GVxCF+i4APpFaaL/oWizMM+Hs+nID4IE+sA0TvxRBOWbDgdRNEri6yTN90WrbeQ1sDu1Vr9/++vn79/+vkCt4sNOC26EO23aGVorBoGk6WgYZUnqp2Gc+/FsdO1P8+HAzwf9OM7SZJr1b7/aji2Mx4Wirh38tewayTD+oZWsWKGEFktzVYiq7UmxFJ+pkoK5tjQM2kZyQ+zVMAqDUXQ9GsZtmoBbNzq2uOkpXYlw9Y7I+40rksrdc5lbktA3tzXyZIIP+vCbfwBQSwMEFAAAAAgAcXBbV4Bl4Yi3AAAANgEAAC0AAABwcHQvc2xpZGVMYXlvdXRzL19yZWxzL3NsaWRlTGF5b3V0MTAueG1sLnJlbHONz70OwiAQB/DdpyAsTELrYIwp7WJMHFyMPsAFri2xBcKh0beX0SYOjvf1++ea7jVP7ImJXPBa1LISDL0J1vlBi9v1uN4JRhm8hSl41OKNJLp21VxwglxuaHSRWEE8aT7mHPdKkRlxBpIhoi+TPqQZcinToCKYOwyoNlW1Venb4O3CZCereTrZmrPrO+I/duh7Z/AQzGNGn39EKJqcxTNQxlRYSANmzaX87i+WalkiuGobtXi3/QBQSwMEFAAAAAgAcXBbV0uJUFfAAwAArQwAACIAAABwcHQvc2xpZGVMYXlvdXRzL3NsaWRlTGF5b3V0MTEueG1stVfRkps2FH3vV2jog59YAQaMPfFmDF46ndlkd2on7wrIayYCUUl27HQyk99qPydf0isBXtvrpPbUeTEgro7OPecKXb96vSkZWlMhC16Ne+6N00O0ynheVE/j3rt5akc9JBWpcsJ4Rce9LZW917e/vKpHkuX3ZMtXCgFEJUdkbC2VqkcYy2xJSyJveE0reLfgoiQKHsUTzgX5BNAlw57jhLgkRWW188U58/liUWR0yrNVSSvVgAjKiAL6clnUskOrz0GrBZUAY2YfUlLbmo4t0EXNC8XopMrnGwuZeLGGN651CxJkM5ajipQw8B5Ci4wwZOIRCIbmdKNMmKznglJ9V61/E/WsfhRm9tv1o0BFrtFaFAu3L9ow3EwyN/ho+lN3S0abhSj1FdRBm7HlWGirf7EeAxIoawaz59Fs+XAiNlvenYjG3QJ4b1GdVUPuZTqedVoUd5deR1zW9zz7KFHFITGtQ5PnLqJJXl/rZeuJ0lAW4qIA5xqLrE4dHYr3OcnTAoWhN/SdJnVv4If96FArzwkG5r3WIIgCN/CCYyVku4TaxDzf6tkf4AoKaEZji5L3LTMyYlLN1JZR81DrH0NKQDAjsM8sWtnvZhaSpUoYJdXOD3WbsCL7iBRHNC8UekOkogIZCWBXAqSmpAwxA0mr/JEI8scRckO9Nrw7vrhz8Ps+9l/6qBV6ZCSjS85yoOJdw1It3JGjsP7mefL5zvrBwPuBsaHjDqOfaWytlV+znYP/02jN2/gsD4zG3WoHS7oXLjmjGYfPFKNrys6A9y6Eny8LcT56/0L0lK+EWp4N718KXyxOol97i/ndFpsSRQ92Vv8aOyuHnSQ/w1FI2KLbU86PNxU+VfvfqfYFHH86i7+COJlMnSiw76JJaEeRH9jx1L+zk9hPkokTDNPE/9KdqjmkqoqSpsXTStCHlT4kz3PFxd4Au/1nR4DA9T0JOk9SzvUu3HfFv4YrCyUaW/5cEQErdM78x+fuEmeuq0jYKTJjRU7R21X54UiX4Bq6QEcJ0Cel8X5C0SZumobTydB2nAj63NiP7KEH5RuHgecNI38QxemuaKXOvAJ259bqt69///rt6z9XqFW830HCiXAvVXuHVqKAROJ4GHpJFNux66e2Px0O7EkaBnYa9H0/iaNJ0r/7ojtR1x9lgpp29/e8a5Rd/0WrXBaZ4JIv1E3Gy7bnxjX/REXNC9N2u07bKK+J/niHrud5/cGwswm4dVfDFje9sikRJt6Q+mFtiqQ051xihmr4X9DWyHMI3vufcfsvUEsDBBQAAAAIAHFwW1eAZeGItwAAADYBAAAtAAAAcHB0L3NsaWRlTGF5b3V0cy9fcmVscy9zbGlkZUxheW91dDExLnhtbC5yZWxzjc+9DsIgEAfw3acgLExC62CMKe1iTBxcjD7ABa4tsQXCodG3l9EmDo739fvnmu41T+yJiVzwWtSyEgy9Cdb5QYvb9bjeCUYZvIUpeNTijSS6dtVccIJcbmh0kVhBPGk+5hz3SpEZcQaSIaIvkz6kGXIp06AimDsMqDZVtVXp2+DtwmQnq3k62Zqz6zviP3boe2fwEMxjRp9/RCianMUzUMZUWEgDZs2l/O4vlmpZIrhqG7V4t/0AUEsDBBQAAAAIAHFwW1eTCm11IQYAAOcdAAAUAAAAcHB0L3RoZW1lL3RoZW1lMS54bWztWU1v2zYYvg/YfyB0b2XZVuoEdYrYsdutTRskboceaYmW2FCiQNJJfBva44ABw7phlwG77TBsK9ACu3S/JluHrQP6F/bqwzJl04nTZluB1gebpJ73+4OkfPXaccTQIRGS8rhtOZdrFiKxx30aB23r7qB/qWUhqXDsY8Zj0rYmRFrXNj/84CreUCGJCAL6WG7gthUqlWzYtvRgGcvLPCExPBtxEWEFUxHYvsBHwDdidr1WW7MjTGMLxTgCtndGI+oRNEhZWptT5j0GX7GS6YLHxL6XSdQpMqx/4KQ/ciK7TKBDzNoWyPH50YAcKwsxLBU8aFu17GPZm1ftkoipJbQaXT/7FHQFgX9Qz+hEMCwJnX5z/cp2yb+e81/E9Xq9bs8p+WUA7HlgqbOAbfZbTmfKUwPlw0Xe3Zpba1bxGv/GAn690+m46xV8Y4ZvLuBbtbXmVr2Cb87w7qL+na1ud62Cd2f4tQV8/8r6WrOKz0Aho/HBAjqNZxmZEjLi7IYR3gJ4a5oAM5StZVdOH6tluRbhB1z0AZAFFysaIzVJyAh7gOtiRoeCpgLwBsHak3zJkwtLqSwkPUET1bY+TjBUxAzy6vmPr54/Ra+ePzl5+Ozk4S8njx6dPPzZQHgDx4FO+PL7L/7+9lP019PvXj7+yoyXOv73nz777dcvzUClA198/eSPZ09efPP5nz88NsC3BB7q8AGNiES3yRHa4xHYZhBAhuJ8FIMQU51iKw4kjnFKY0D3VFhB355ghg24Dql68J6ALmACXh8/qCi8H4qxogbgzTCqAHc4Zx0ujDbdTGXpXhjHgVm4GOu4PYwPTbK7c/HtjRNIZ2pi2Q1JRc1dBiHHAYmJQukzfkCIgew+pRW/7lBPcMlHCt2nqIOp0SUDOlRmohs0grhMTApCvCu+2bmHOpyZ2G+TwyoSqgIzE0vCKm68jscKR0aNccR05C2sQpOS+xPhVRwuFUQ6IIyjnk+kNNHcEZOKujehe5jDvsMmURUpFD0wIW9hznXkNj/ohjhKjDrTONSxH8kDSFGMdrkyKsGrFZLOIQ44Xhrue5So89X2XRqE5gRJn4yFqSQIr9bjhI0wiYsmX2nXEY3f9+6Ve/eWoMbime/Yy3DzfbrLhU/f/ja9jcfxLoHKeN+l33fpd7FLL6vni+/Ns3Zs64fujE209AQ+ooztqwkjt2TWyCWY5/dhMZtkROWBPwlhWIir4AKBszESXH1CVbgf4gTEOJmEQBasA4kSLuGaYS3lnd1VKdicrbnTCyagsdrhfr7c0C+eJZtsFkhdUCNlsKqwxpU3E+bkwBWlOa5ZmnuqNFvzJtQNwulrBWetnouGRMGM+KnfcwbTsPyLIXJqWoxC7BPDsmaf0/hXvOmeS4mLcXJtwcn2YjWxuDpDR21r3a27FvJw0rZGcGyCYZQAP5l2GsyCuG15Kjfw7Fqcs3jdnFVOzV1mcEVEIqTaxjLMqbJH09cq8Uz/uttM/XAxBhiayWpaNFrO/6iFPR9aMhoRTy1ZmU2LZ3ysiNgP/SM0ZGOxh0HvZp5dPpXQ6evTiYDcbhaJVy3cojbmX98UNYNZEuIi21ta7HN4Ni51yGaaevYS3V/TlMYFmuK+u6akmQvn04af3Z5gFxcYpTnatrhQIYculITU6wvY9zNZoBeCskhVQix9GZ3qSg5nfSvnkTe5IFR7NECCQqdToSBkVxV2nsHMqevb45RR0WdKdWWS/w7JIWGDtHrXUvstFE67SeGIDDcfNNtUXcOg/xYfXJqvtfHMBDXPs/k1taavbQXrb6bCKhuwJq5utrjuLt155rfaBG4ZKP2Cxk2Fx2bH0wHfg+ijcp9HkIiXWkX5lYtD0LmlGZey+q9OQa0l8b7Is6Pm7MYSZ58u7vWd7Rp87Z7uanuxRG3tHpLNFv6U4sMHIHsbrjdjlq/IBGb5YFdkBg+5PymGTOYtIXfEtKWzeI+MEPWPp2Gd82jxr0+5me/lAlLbS8LG2YQFfraJlMT1s4lLiukdryTObnEmBmwmOcfnUS5bZOkpFr+Jy1ZQ3uwyY/au6rIVAvUaLlPHp7us8JRtSjxyrATuTv/Ggvy1Zym7+Q9QSwMEFAAAAAgAcXBbVwFX6IttAwAAlgsAACEAAABwcHQvc2xpZGVMYXlvdXRzL3NsaWRlTGF5b3V0Mi54bWy1VtFymzoQfb9foaEPfiICDA721OkYHO7cmbTJ1OkHKCCCWoF0Jdm12+lMf6v9nH5JJQGOnaYzzpS+ICFWZ3fPHqR9+WpbU7DBQhLWzEf+mTcCuMlZQZr7+ejdbebGIyAVagpEWYPnox2Wo1cX/7zkM0mLK7RjawU0RCNnaO5USvEZhDKvcI3kGeO40d9KJmqk9Ku4h4VAHzV0TWHgeRNYI9I43X5xyn5WliTHS5ava9yoFkRgipQOX1aEyx6Nn4LGBZYaxu4+DkntOJ477O69A6yR2OhX37nQeecrWoAG1XrhliiKgSYHpKxRGskaSH4rMDazZvOv4Ct+I+y+N5sbAUhhcLr9Duw+dGaw3WQn8NH2+36KZttS1GbUZIDt3PEcsDNPaNbwVoG8XcwfVvPq+gnbvLp8whr2DuCBU5NVG9yv6QTOER3+Pqs+XsmvWP5BgobpfEz6bXp7izZnM/KqY14ZKKenwXyEh85lT5baJqzYGSd3erSLaEalWqkdxfaFm4cNQ+h4KdK6dnDjvls5QNYqpRg1e0LURUpJ/gEoBnBBFHiNpMIC2GD0X6AhDTvKcmQhcVPcIIHePkJuWeQ26D5C2FP4eyLHPZGdmsANRTmuGC10EMGf0UqK7YPJAIxyk/KG7qn7Q4aNbC3B8ohh2Hs7cuk/0+UK50z/oxRvMD0BPngm/G1FxOno42eiZ2wtVHUyfPhceFI+iT60tsNe20uk8JGwx0OcF4XS2X3SZz6ipdOJ3RtO7aU+8k0Wn6MkXSy9OHIv48XEjeMwcpNleOmmSZimCy+aZmn4pb8+Cp2qIjXOyP1a4Ou1uR5Oq4oPg3Pojx8qogMYviZRX5OMMfMXHlYlHKIqpRJtWf5fI6E99JUZ8BwalpFJz8iKkgKDN+v67hEv0RC86NZJQz9JTfAXRJv6WTZZLqau58W6oUvC2J0GWr7JJAqCaRyex0m2F600mTc6ulO1+uPrtxc/vn4fQKvwsHfSN8KVVN0MrAXRiSTJdBKkceImfpi54XJ67i6ySeRm0TgM0yRepOPLL6YH88NZLrDt6/4r+o7QD3/pCWuSCyZZqc5yVnfNJeTsIxacEdtf+l7XEW6QuRomfjj2wyCKuzLp2PrRRgvb/tBKhIrXiF9vrEhqe8+ldonrBrjTyIMJPGioL34CUEsDBBQAAAAIAHFwW1eAZeGItwAAADYBAAAsAAAAcHB0L3NsaWRlTGF5b3V0cy9fcmVscy9zbGlkZUxheW91dDIueG1sLnJlbHONz70OwiAQB/DdpyAsTELrYIwp7WJMHFyMPsAFri2xBcKh0beX0SYOjvf1++ea7jVP7ImJXPBa1LISDL0J1vlBi9v1uN4JRhm8hSl41OKNJLp21VxwglxuaHSRWEE8aT7mHPdKkRlxBpIhoi+TPqQZcinToCKYOwyoNlW1Venb4O3CZCereTrZmrPrO+I/duh7Z/AQzGNGn39EKJqcxTNQxlRYSANmzaX87i+WalkiuGobtXi3/QBQSwMEFAAAAAgAcXBbV4tg7VpjBAAAWBEAACEAAABwcHQvc2xpZGVMYXlvdXRzL3NsaWRlTGF5b3V0My54bWzNWNtu2zYYvt9TCOqFrxRSEnUK6hSWHG0D0iSo0wdgJNoWSh1G0q69oUBfa3ucPslISrIcN2ndzgtyI1LUf/j+A/nz1+s3m5Iaa8J4UVfjkX0GRwapsjovqsV49P4utcKRwQWuckzrioxHW8JHby5+ed2cc5pf4W29EoYUUfFzPDaXQjTnAPBsSUrMz+qGVPLbvGYlFvKVLUDO8EcpuqTAgdAHJS4qs+Nnx/DX83mRkWmdrUpSiVYIIxQLCZ8vi4b30ppjpDWMcClGcz+EJLYNGZucZL8RnJuGJmRruWSbF9L2bEZzo8KlXJiRTLEbipAw/ZU3d4wQNavWv7Jm1twyzXS9vmVGkSshHbMJug8dGWiZ9AQcsC/6KT7fzFmpRukNYzM2oWls1ROoNbIRRtYuZsNqtrx5hDZbXj5CDXoFYE+psqoF97U5Tm/OXSEoMeydVT1e3lzV2QduVLW0R5nfmrejaG1WY7PsXC+UKLN3g/oI9pXzxz0ROI5ru9pEhKAfwQOnBEHgINgZa7u+AwPv0GTeqRCbuM63ivtejtJUXGXLWmapaGVSLmZiS4mer6ndKBK6qMYmNdVaTubv5BL/U2KBSue9DnyGpQcwpZ3ajrOd70ls1EObyKQQiuV2NEllvZ+ZBi9FQgmudmEUFwktsg+GqA2SF8J4i7kgzNAulJtXSlTShdahRZIqv8UMvzuQ3CJqtBd660Ef+KfD7+7Cr9x8S3FGljWVm8FwTpEJyvumVLQZyH8qIZwI+oGcfyMhPAjtMPjhhLh/OiFKzK707iqqXJ40aqoFrK7laQoO0sRRaaK9VNMiTwtK9Ys6v0hCmbHGVGbfxtY0oqhEuxJ4EPYbd0fcvg1yQK/pYdbpqTMgRV7gwCPh2uEzwnUGuO4AN7IROhqu/4xw3QEuGuDabqBRHIcXPSNeNOD19vCGThi+SLzegNcf8DpO6MMXidcf8AZ7eAPkHr/dnhNvMOANB7wK7PH77TnxhgPeaA+v7wUvc79FT9Z8hV4S7Ir7f7wDqEKnrwD8wR3gZ+o86uv8FAvyoM67p6jzuTB1HJaYzvt6D79d8MFjZflBLQY7v87ljV1Z8ZcXJ5MpDD3rMpz4Vhgiz4qn6NJKYpQkE+hFaYI+9R1ALk0VRUnSYrFi5GYlzGPDYQMnALY7eF0COP3dy+tjkta1ivd+VNApojIXrA3LHyvMpIY+Mt+5iv1IZE7rEb/3yEzuPmJcr8r7A794p/CL7H6l6Edd4/wPSZvYaepPJ5EFYSh78hiFVuTI9I19z3GiEAVhnO6SlivLK4nu2Fz98vnvV18+/3OCXAX73a88e6646GbGihXSkDiOfCcJYyu2UWqhaRRYk9T3rNRzEUricJK4l59UF22j84wR3Zr/nvdNvY2+auvLImM1r+fiLKvL7v8AaOqPhDV1oX8R2LBr6vV5HfnQR6Hb9X0aWj9qsKDt7nWGUPYWNzdrnSOlPlATvdQU1aJLkYEE7P0SufgXUEsDBBQAAAAIAHFwW1eAZeGItwAAADYBAAAsAAAAcHB0L3NsaWRlTGF5b3V0cy9fcmVscy9zbGlkZUxheW91dDMueG1sLnJlbHONz70OwiAQB/DdpyAsTELrYIwp7WJMHFyMPsAFri2xBcKh0beX0SYOjvf1++ea7jVP7ImJXPBa1LISDL0J1vlBi9v1uN4JRhm8hSl41OKNJLp21VxwglxuaHSRWEE8aT7mHPdKkRlxBpIhoi+TPqQZcinToCKYOwyoNlW1Venb4O3CZCereTrZmrPrO+I/duh7Z/AQzGNGn39EKJqcxTNQxlRYSANmzaX87i+WalkiuGobtXi3/QBQSwMEFAAAAAgAcXBbV0/KghwIBAAAaBIAACEAAABwcHQvc2xpZGVMYXlvdXRzL3NsaWRlTGF5b3V0NC54bWztWN1y2jgUvt+n0LgXXDmyjWwMU9LBJt7ZmbTJFPoAii2Ct7LllQSB7nSmr7X7OH2SlYSNIaEFtlzmBgv503f+j+3z9t2qoGBJuMhZOey4V04HkDJlWV4+DjufpokddoCQuMwwZSUZdtZEdN5d//a2Ggia3eI1W0igKEoxwENrLmU1gFCkc1JgccUqUqp7M8YLLNVf/ggzjp8UdUGh5zgBLHBeWvV5fsp5NpvlKRmzdFGQUm5IOKFYKvXFPK9Ew1adwlZxIhSNOb2vklxXZGjJJ3b38KcFDI4v1Y5rXSvT0wnNQIkLtTF9YiBmpVQ05paoppwQvSqXv/NqUt1zc+LD8p6DPNMM9UkL1jdqGNwcMgv47Phjs8SD1YwX+qo8AVZDy7HAWv9CvUdWEqSbzbTdTed3B7Dp/OYAGjYC4I5QbdVGuZfmeI0501xSAtytVY2+orpl6WcBSqbs0eZvzNsiNjbrazVv3K6prMYN+ibcFS4aZ8lVxLK1FvKgrmYTD6iQE7mmxPyp9I9Rgyt9KVZJbZHS/jSxgChkTAkutw6R1zHN089AMkCyXIL3WEjCgVFGlYCi1N6RxkeGkpTZPeb44zPmjRcro3SjIWxc+GNHdhtH1tkE7ilOyZzRTCnh/ZpbxRdVDZjOLCVp1YJ/4NsDWYb8nioOkz5u4Dh6vZdwyOmGgVMnEvI9vx90n6eTqEX8NGpmvaRurUZGZtq9Wn8vdJoM3QGopXcAi3axXovtHsA6u9hui0Uvse6eDqjF+sewfosNjmGDFts7hu212PAYNmyx/WPYDQDuB8ZUU6XTfUm3ZfOL1aUzyBSX2Ksu2EjbE+meKXJCUlZmgJIloSfQe2fST+c5P529eyZ7whZczk+mR+fS57OD7Jfua+hnfa170b7mnd/XAhS+NrbXxvba2F4b27mNzW8a2xhLstfV0CVegjNpvXhvcy73UjxTXzDair/9KB6NndC3b8JRYIch8u1ojG7sOEJxPHL8fhKjr80HUaZMlXlBkvxxwcndQn/znBYVF3o96HbbiCgFLh+ToIlJwpiuwt2o+JeIykzyTVj+WmCuJDSROfJKfU5kLuuRXuORCc0zAj4siodnfgku4RdBM0V90DVHnsr/K2ljN0mC8ahvO06Y2GGEQrvvqfSNAt/z+iHqhVGyTVqhLS+Vdqfm6vdv/7z5/u3fC+Qq3B0IqCfCrZD1Cix4rgyJon7gxWFkRy5KbDTu9+xREvh24ncRiqNwFHdvvurBgosGKSdmUvFH1sw4XPRiylHkKWeCzeRVyop6XAIr9kR4xXIzMXGdesaxxPrR0As9D6E+6tVhUro1V6Mt3Iw7TIpQ/h5Xd0uTJIV5zsVmq8rLxzpHWgjcGRFd/wdQSwMEFAAAAAgAcXBbV4Bl4Yi3AAAANgEAACwAAABwcHQvc2xpZGVMYXlvdXRzL19yZWxzL3NsaWRlTGF5b3V0NC54bWwucmVsc43PvQ7CIBAH8N2nICxMQutgjCntYkwcXIw+wAWuLbEFwqHRt5fRJg6O9/X755ruNU/siYlc8FrUshIMvQnW+UGL2/W43glGGbyFKXjU4o0kunbVXHCCXG5odJFYQTxpPuYc90qRGXEGkiGiL5M+pBlyKdOgIpg7DKg2VbVV6dvg7cJkJ6t5Otmas+s74j926Htn8BDMY0aff0QompzFM1DGVFhIA2bNpfzuL5ZqWSK4ahu1eLf9AFBLAwQUAAAACABxcFtX6aTEj+MEAAA2HAAAIQAAAHBwdC9zbGlkZUxheW91dHMvc2xpZGVMYXlvdXQ1LnhtbO1Z3ZKiOBS+36eg2AuvGAgECNbYUy3dbm1VT3fX6DxAGmLLDhA2ibbO1lTNa+0+zjzJJgiitto4erFV6w3EcPLl/H4cyfsP8yzVZoTxhOa9DnhndTSSRzRO8ude5/NoYKCOxgXOY5zSnPQ6C8I7H65+eV90eRrf4QWdCk1C5LyLe/pEiKJrmjyakAzzd7QguXw2pizDQv5kz2bM8IuEzlLTtizPzHCS69V61mY9HY+TiNzQaJqRXCxBGEmxkOrzSVLwGq1og1YwwiVMuXpTJbEoSE8XL3Q0H73Qh6c/dK0UZjM5DfQraX80TGMtx5mcCGlWYJZwmpdPeDFihKhRPvuNFcPikZUL7mePTEtiBVAt1M3qQSVmLheVA3Nr+XM9xN35mGXqLr2hzXu6pWsLdTXVHJkLLVpORs1sNHnYIRtNbndIm/UG5tqmyqqlcq/NsWtzRolIiQZWVtX68uKORl+4llNpjzJ/ad5KYmmzuheT2vUKSq/doB6a65vz2lli3qfxQm3yJO/lJO6mXAzFIiXleJaCSo2YjD8tXbs2bW6KF+pSSjNpXYplGegkNz4PdY1nIkwJzlfuE1dhmkRfNEE1EidC+4i5IEwrVZdFIxEVuij3KCFJHj9ihj9tIS81KkoTa3vM2uH73e6s3K5i/pjiiExoGksN7HNEQPlTlxvNG/E9gdiRktD1ZTWVuQZcxwXA2cxOaEELILTMOs8JfM/eTj1e7bAdYQ3n0YRKtnjS9wVbyzC7K5M6yWNZ4GpYAkzvJYmZTS5o/KtMX6g0farN3EgZObQbwNqqVqjWa1S7QXUa1ABA2BYVoNeoToMKG1Tg+MBrDeu9hoUNrLsGi2yEToF1G1ivgbVt5FmnwHoNrL8G60OndcR2wfoNLGpgFWb7kO2ARQ1ssAbruf5JIQv2MpraRAqsqOtEhlNlXBIc32C4n2ExqK9eormQVm8QmXMakSk/TXA6rmjMPoXGbOBD5LsHaMwJXCCLoy2Pvf2mathpHy/t4px9bLOLSfZxyK5c20cMB2W3qv2g7FYJH5TdqsuDslvFdlD2v1FB21uCI7cckojmsZaSGUlbwNtHwo8mCWuP7hyJPqBTJiat4eGx8Ml4J/q5uzN3b3cGz9edqQT+c4qZTKmK45zjOc6DrmW7B3s14Evmu/Rql17t0qv9n3s171Cv5p7eq21SGTyJyvb1aw2VXfq1S7926dcu/dqS2/ya226wIBvE5p2jX4uFvv13FFinft80V+4dp3FpxV9uP7y+sZBr3KJrz0AIukb/Bt4aYR+G4bXlBoMQfqu/b8fSVJFkZJA8Txl5mAq9bVSAafsmcJqISAXOHxNUx2RAqarC9aj454jKWLBdTTR444PnMZE5r0eC2iPDNImJdj/Nnrb8gs7hF57GEnqna974iPJTSRuCwcC7uQ4My0IDA/UhMgJbpm/fc207QNBH/cEqabmyPJfatc3VH9///vXH93/OkKvm+tmOfCPccVGNtClLpCH9fuDZIeobfQAHBrwJfON64LnGwHUgDPvoOnRuv6kzIgC7ESPlwdPvcX1kBeCrQ6ssiRjldCzeRTSrTr/Mgr4QVtCkPAADVnVkNcOSXYPAAi7yHa+KklStvpfKmstzqzJDUvYRFw+zMkey8jUXllNFkj9XKdKImGsHflf/AlBLAwQUAAAACABxcFtXgGXhiLcAAAA2AQAALAAAAHBwdC9zbGlkZUxheW91dHMvX3JlbHMvc2xpZGVMYXlvdXQ1LnhtbC5yZWxzjc+9DsIgEAfw3acgLExC62CMKe1iTBxcjD7ABa4tsQXCodG3l9EmDo739fvnmu41T+yJiVzwWtSyEgy9Cdb5QYvb9bjeCUYZvIUpeNTijSS6dtVccIJcbmh0kVhBPGk+5hz3SpEZcQaSIaIvkz6kGXIp06AimDsMqDZVtVXp2+DtwmQnq3k62Zqz6zviP3boe2fwEMxjRp9/RCianMUzUMZUWEgDZs2l/O4vlmpZIrhqG7V4t/0AUEsDBBQAAAAIAHFwW1cttCb1EgMAALgIAAAhAAAAcHB0L3NsaWRlTGF5b3V0cy9zbGlkZUxheW91dDYueG1stVbdbtowFL7fU1jZBVepkxAgoMFEQjNNakc12gfwEgPRHNuzDYNNlfZa2+P0SXbsEMq6TuoFu4md4/Pzne8c5+TN213N0JYqXQk+7oQXQQdRXoiy4qtx5+4295MO0obwkjDB6bizp7rzdvLqjRxpVl6RvdgYBC64HpGxtzZGjjDWxZrWRF8ISTmcLYWqiYFXtcKlIl/Bdc1wFAR9XJOKewd79RJ7sVxWBZ2JYlNTbhonijJiAL5eV1K33uRLvElFNbhx1n9CMntJx56pDKNzzvYecqpqC8LQm0D2xYKViJMaBLdWCzk1e6LlraLU7vj2nZILeaOcwYftjUJVaR0cDD18ODio4cbIbfAT81W7JaPdUtV2BS7QbuwFHtrbJ7YyujOoaITFo7RYz5/RLdaXz2jjNgA+CWqzasD9nU7k/cFDeMyqxavllSg+a8QF5GPTb9I7ajQ521WuT4n3WhrsIT4NrluyzC4V5d4G+QSrE5IR02Zh9oy6F2kfDoYCvIxAW3uU+3cLD+naZIwSfiTETDJWFZ+REYiWlUHXRBuqkAMDlwBcWnaM48i5pLy8IYp8fOK5YVE60C1C3FL4byK7LZEzYii6YaSga8FKQBCdg9PSQMrf4FoQtvQgINQ9DM7H8RLug83iey/NprMg6fmXybTvJ0nc89NZfOlnaZxl06A3zLP4vr1hJaRqqprm1Wqj6HxjvJeWKsTRAIfdx4oAgPPXJG5rkgthe+G0Kt1zVGVpVFOWLxuiIEJbmfB8lTkvI72WkQWrSoo+bOpPT3iJz8ELTBdw/Sw10X9o2izM8/5sOvSDIIGZl8aJP4ygfdN+L4qGSTxI0vzYtNpmzgHdS3v14cfP1w8/fp2hV/HpfIGP/ZU2hx3aqAoSSdNhP8qS1E/DOPfj2XDgT/N+z8973TjO0mSadS/v7ZwK41GhqBt978t2aIbxX2OzrgoltFiai0LUh/mLpfhKlRSVG8FhcBiaW8LG3iAaBNFgcGxggNauDixuZqfrEKauiZxvXY/U7mObOZGEX4RDizyq4JNfjslvUEsDBBQAAAAIAHFwW1eAZeGItwAAADYBAAAsAAAAcHB0L3NsaWRlTGF5b3V0cy9fcmVscy9zbGlkZUxheW91dDYueG1sLnJlbHONz70OwiAQB/DdpyAsTELrYIwp7WJMHFyMPsAFri2xBcKh0beX0SYOjvf1++ea7jVP7ImJXPBa1LISDL0J1vlBi9v1uN4JRhm8hSl41OKNJLp21VxwglxuaHSRWEE8aT7mHPdKkRlxBpIhoi+TPqQZcinToCKYOwyoNlW1Venb4O3CZCereTrZmrPrO+I/duh7Z/AQzGNGn39EKJqcxTNQxlRYSANmzaX87i+WalkiuGobtXi3/QBQSwMEFAAAAAgAcXBbV+sXn3fmAgAAZwcAACEAAABwcHQvc2xpZGVMYXlvdXRzL3NsaWRlTGF5b3V0Ny54bWy1VdFumzAUfd9XIPaQJ2ogJIWoSRVImSZ1bbS0H+CCSVDB9mwnSzZV6m9tn9Mv2bWBNGs7qQ/ZC7Yv917fc87V9dn5tq6sDRGyZHTc807cnkVoxvKSLse925vUCXuWVJjmuGKUjHs7Invnkw9nfCSr/BLv2FpZkILKER7bK6X4CCGZrUiN5QnjhMK/gokaKziKJcoF/g6p6wr5rjtENS6p3caL98SzoigzMmPZuiZUNUkEqbCC8uWq5LLLxt+TjQsiIY2J/rskteNkbN9VmN7blnETGzB49gSQZ4sqtyiuwRAbD22U/EYQond080nwBZ8L43u1mQurzHVsG2Oj9kfrhpogs0EvwpfdFo+2haj1ChRY27Ht2tZOf5G2ka2yssaYPVuz1fUbvtnq4g1v1F2ADi7VqJriXsPxOzgzrIg1r3BGVqzKibC8PcCudMkvWXYvLcoAmmaiQbr3aODrla9a6nNlW/IHiIirwoYLoVzPtTuGtDM6rEt2PKptzPKdvvQOVmPEo0qqhdpVxBy4/hSgoEbxcxAn05kbDpyLcDp0wjAYOPEsuHCSOEiSqTuI0iR46PohB6iqrElaLteCXK+VrXMJYATaYDm2CXVuF1B3rZKKYLqnXE085J8ir69pVoZsKMAIR/M5FvjrixSNINyA7BChTo1/a9LvNEkZU6DEoSr+MVQplGhk+bbGAm7olPGOp8xxGQk6RhZVmRPral3fveClfwxeYBZC6jep8f9D0yZemg5n08hx3RAmdByETuRD+8bDge9HYXAaxum+aaVGTqG69/bq0+Ovj0+Pv4/Qq+hwLMKMupSq3VlrUQKQOI6GfhLGTuwFqRPMolNnmg4HTjroB0ESh9Okf/Ggx6sXjDJBzKD+nHcj3gteDfm6zASTrFAnGavb1wJx9p0IzkrzYHhuO+I3uNLyeH4URaEXtjJBbd1qqkXNuDctUokvmF9vTJPAZSByYkwcXrS2R55d0MELOfkDUEsDBBQAAAAIAHFwW1eAZeGItwAAADYBAAAsAAAAcHB0L3NsaWRlTGF5b3V0cy9fcmVscy9zbGlkZUxheW91dDcueG1sLnJlbHONz70OwiAQB/DdpyAsTELrYIwp7WJMHFyMPsAFri2xBcKh0beX0SYOjvf1++ea7jVP7ImJXPBa1LISDL0J1vlBi9v1uN4JRhm8hSl41OKNJLp21VxwglxuaHSRWEE8aT7mHPdKkRlxBpIhoi+TPqQZcinToCKYOwyoNlW1Venb4O3CZCereTrZmrPrO+I/duh7Z/AQzGNGn39EKJqcxTNQxlRYSANmzaX87i+WalkiuGobtXi3/QBQSwMEFAAAAAgAcXBbV83KitWyBAAAwhIAACEAAABwcHQvc2xpZGVMYXlvdXRzL3NsaWRlTGF5b3V0OC54bWzNWN1yozYYve9TMPTCVwQE4i+zzo4hodOZbJJZZx9AAdmmC4hKstduZ2f2tdrH2SepJMB2HMfGiS96Y2T56Ejfdz4dYX34uCwLbYEpy0k1HIALa6DhKiVZXk2Hgy+PiREMNMZRlaGCVHg4WGE2+Hj1y4f6khXZLVqROdcERcUu0VCfcV5fmiZLZ7hE7ILUuBK/TQgtERdf6dTMKPomqMvCtC3LM0uUV3o7nvYZTyaTPMXXJJ2XuOINCcUF4mL5bJbXrGOr+7DVFDNBo0Y/XxJf1Xiok6c/Hpe6pmB0ITqAfiUiT8dFplWoFB0xqbhg0L7lfKbFqJZMCsPqR4qxbFWL32g9rh+oGnq3eKBankmqlkI32x9amNkMUg1zZ/i0a6LL5YSW8ikyoi2HuqVrK/lpyj685FradKab3nR2vwebzm72oM1uAnNrUhlVs7iX4dhdOI85L7AG1lF162X1LUm/Mq0iIh4ZfhPeGtHELJ/1rE0/l1R6lwb5o7k9OdufCej6QkgVou07lruTE8eyAgc4TawAeHaL2I6YtTPwZUSylRz9JJ4iUlSlMyIK9anhLBgf81WBVXtRgFpCimk11Atd9mV48ll0sb/EUiy5pqcu8DW+aW/x1PJDxUXF0AKJfajjyvgy1jVW8rjAqFprx6/iIk+/apxoOMu59gkxjqmm8iZ2rWCU7FzNoShxlT0gij7vMDcrqlXsXcxmp/brmjv6zi54KFCKZ6TIxCLs91VAni03kP7iO67vSkFfU98FAPhuW+lu4DpAlEJP9V+TfEdpR1bfjsaqab/E2sE21t5gnT1YuI11Nli4B2ttY+EG6x7DuhusdwzrbbD+May/wQbHsMEGGx7Dhq/uIbkZBWC9Wd65p2QFqS3Fnu0ps5vt2ZTgxCnHOCVVphV4gYse9PaJ9I+znPZnd05kT8icitOvLz08lT6f7GU/t5vB9Qkmpd62Mucch5n0EF0V8AwVE70xOPs9pxuAjgusQ8cb9EJgee82OK1E9Fa9H+RVJnxeNtWo+Z14JzR39ieAB/yvpeqi6MVnH/DIli8EEPbmsw74aMsHHB94fQnDA17b8QV2ELyJb8ePWz7bDjzrTXw7nt3x+dDpLUh4wNdbPknWW5DwgPd3fJ7rv02P/8f5cJoTuZ0TXSOOnzkRPIcTZfyFDwHrsBGZR+3CXOd1Iv4cySj+dqN4dG0FrnETjDwjCKBrRNfwxogjGMcjyw2TGH7v/mplIlSelzjJp3OK7+dc7ysHMG3fBM4m62IB5z8dvE6ThBCp97Yq7jlUmXDayPLnHFExQ6fMkXfgU5Q5b0b8LiPjIs+wdjcvn3by4p0jL6zIBPXe1Bw5Pd9UtDFIEu96FBriHE2MIIKBEdqifCPPte0wgH4QJeuiZTLySqyub63+/PHPrz9//HuGWjW3rxiE99wy3ra0Oc1FIFEUenYcREYEYGLA69A3RonnGonrQBhHwSh2br7LqwoAL1OK1R3I71l3ewLgi/uTMk8pYWTCL1JSthcxZk2+YVqTXN3FAKu9PVkg+Q4cQMu3PdfrvEWsrXuq1ZrNTYoqkYJ+QvX9QhVJqRw1Vl11Xk3bGtlAzK3Lp6v/AFBLAwQUAAAACABxcFtXgGXhiLcAAAA2AQAALAAAAHBwdC9zbGlkZUxheW91dHMvX3JlbHMvc2xpZGVMYXlvdXQ4LnhtbC5yZWxzjc+9DsIgEAfw3acgLExC62CMKe1iTBxcjD7ABa4tsQXCodG3l9EmDo739fvnmu41T+yJiVzwWtSyEgy9Cdb5QYvb9bjeCUYZvIUpeNTijSS6dtVccIJcbmh0kVhBPGk+5hz3SpEZcQaSIaIvkz6kGXIp06AimDsMqDZVtVXp2+DtwmQnq3k62Zqz6zviP3boe2fwEMxjRp9/RCianMUzUMZUWEgDZs2l/O4vlmpZIrhqG7V4t/0AUEsDBBQAAAAIAHFwW1da07SSeQQAADESAAAhAAAAcHB0L3NsaWRlTGF5b3V0cy9zbGlkZUxheW91dDkueG1svVjdcps4FL7fp2Doha+I+BEgMnU6Bsc7O5MmmSZ9AAVkmyl/K8mOvTud6WvtPk6fpJIAQ5ykYV1mb4wsjj6d75yjT0LvP+zyTNsSytKymE6sM3OikSIuk7RYTSef7xcGmmiM4yLBWVmQ6WRP2OTDxW/vq3OWJVd4X264JiAKdo6n+prz6hwAFq9JjtlZWZFCvFuWNMdc/KUrkFD8KKDzDNim6YEcp4XejKdDxpfLZRqTeRlvclLwGoSSDHPhPlunFWvRqiFoFSVMwKjRT13i+4pM9SqN73e6pszoVnRY+oVgHt9liVbgXHTcpjHfUKI9pnytRbiSSMqGVfeUENkqtr/T6q66pWro9faWamkioRoIHTQvGjNQD1INcDR81Tbx+W5Jc/kUEdF2U93Utb38BbKP7LgW151x1xuvb16wjdeXL1iDdgLQm1Syqp17Tsdu6dynPCOadWDV+suqqzL+wrSiFHwk/ZrewaLmLJ/Vugk/l1B6Gwb5EvQnZy9HwvID20ZIcYRIpNQ8iooLkQfNhq3reb6DjimzZgq+C8tkLwc/iKegiot4XYpKfaghM8bv+D4jqr3NrEqaZKtiqme67EvI8pPoYn+JAJlyyoeW+cG+bvdwKvmjiFExNMNiIeqkMD7f6RrLeZQRXBySxy+iLI2/aLzUSJJy7SNmnFBNBU4sW4Eo0bmaQ0GSIrnFFH86Qq49qhT3ljNo0/160h39aBncZjgm6zJLhBP2GCUgVqAuptp11qcVgmfZvu/+pA6gZcliGVoIr2Y/x/RKLaW0SIS0yKYatbkW8gmOasKxDzMeqkE17Q4Kur60GoRnoz6e3eE5HV5gQTgYD/bxnA4PdniW41veYECzDwg7QLcHiETSTgN0O0CvAxRF4JmnAXodoN8D9KEzPCdPAP0OEHWAEm14Up4Aog4w6AF6rn9iUoJXNWlc7YCHDUOux75wOGMIh1ymuqK3xtmy0RD7lzTEdcRWUe8Vr4gIMsU/+//VEAuOqyGWPa6GWObIGhKMLCHByAoSjCwgwcj6EYwsH8Ew9ZDowuBwdPnFE45cf+qAw56ccE5RIrdVojnmT48wcAwlSvgzHbLMnwsReFMuwCGuS/EtIln87YbRbG4i17hEM89ACLpGOIeXRhTCKJqZbrCI4Nf2yyYRVHmak0W6Eue2mw3Xh6bDArYPLKeLunBg/N3Ba3OyKEuZ735W3DGysuS0TsufG0zFDG1m3jhm/pfMjBsRv43IXZYmRLve5A9HcfHGiIv4qhfQL4bmjd3zpKKNrMXCm88CwzTRwkAhREZgi/INPde2AwR9FC4ORcsk80J4N7RWv3/75933b/+OUKug/0UvtOeK8aalbWgqiIRh4NkRCo3QggsDzgPfmC0811i4DoRRiGaRc/lV3gxY8DymRF05/JG0lxUWfHZdkacxLVm55GdxmTf3HqAqHwmtylRdfVhmc1mxxUJWHYQC2/ECJ2jSJHxrn8pbUF9cqBLJ6Edc3WxVkeRKUSPVVaXFqqmRzgT07noufgBQSwMEFAAAAAgAcXBbV4Bl4Yi3AAAANgEAACwAAABwcHQvc2xpZGVMYXlvdXRzL19yZWxzL3NsaWRlTGF5b3V0OS54bWwucmVsc43PvQ7CIBAH8N2nICxMQutgjCntYkwcXIw+wAWuLbEFwqHRt5fRJg6O9/X755ruNU/siYlc8FrUshIMvQnW+UGL2/W43glGGbyFKXjU4o0kunbVXHCCXG5odJFYQTxpPuYc90qRGXEGkiGiL5M+pBlyKdOgIpg7DKg2VbVV6dvg7cJkJ6t5Otmas+s74j926Htn8BDMY0aff0QompzFM1DGVFhIA2bNpfzuL5ZqWSK4ahu1eLf9AFBLAwQUAAAACABxcFtX6ORJ0TkDAACzJAAAKAAAAHBwdC9wcmludGVyU2V0dGluZ3MvcHJpbnRlclNldHRpbmdzMS5iaW7tWc9u2jAYz3orb7BbljsxUFbYlFIxKBoSbaMSKu1UuYnL3IY4cswYe6S93+5zAgETMIQd1iTqoVVw7C+/P/YX+8uJoijv+N/v94piXP6cuOoPRANMvAutqlc0FXk2cbA3vtBGVq/c1C5bJeND97ZjfTOvVN/FAVPN0ZdBv6NqZQDavu8iALpWVzUH/aGl8hgAXN1oqvadMf8zALPZTIdhL90mk7BjAExKfETZfMCDlfkA3WGOxh+ziL4Bh7c62Gat0qnxguYtHmIZzKfYY7oJx6hH6ATyy+uvhOJfxGPQvUOBAcL+fNhy+O7xDNsviOk2RZARGo85NQLGb4+F7s/kcdHXAMt7B0JihiZtSuF8HRSGP8OrNShJjMO0wpEctNtq1AwQXcijLREFDDLUc+FYjMHvozGirYoB4ssIIFjJBmLYq7bDkG8pRhww4zYWx4cdpEQFq5sKZsWKoQ1dLlNxbEgQWi2EagbXwT3PctguWD7aQSrb2SgGXLilICGWtSURTB+txXN8yN/7D9h7Ig+xZru8MK9Ns2uGfTvEQTdwgtZSrfQ5xrW0th3pm2ic6NxBFgKiAWIM0Q0Qx3slNUtwS7BL9HCF1KLQC9zo9TaMsETQcy1+CkoCvNFQzYYZFiZjmHP1JRwEPB4suxmQe2+CbTvP04AhJ2y8QzbLoxf/RjARdY/K+28tdgVndfFNFDd/bJxvNAsmZXYe8Ald8ImQZLg9EyLLytXmLk8lzY3G7hnwqZ7lGcCl6PO9Cpcn19n4OGJ5SNFr/CMPFjJHp2L4lqQlOhUqS6ej+Jamdd93ipuqZeQEoFk4vUie1Db794uy/lYlpVLRa5W0tRM299FWBKloVtKs/XUKKVYZ1LRI5UDjHVgSaQzUANE3kVbpRFGUP6UCfLHpEns6Qd6ScVjP9QlxFyrkujKXhpiwWMOh2I5qE8B3njZX7SsWTsP/Q55IOJaAk+gQH+e9eL2Xkqhehj7hbGOed4jr8mcWzYskr3Aoo1MEsuZBD9OAhSm7UA5sscrHghjAAnqRJCUqWKvWG/Xm2Xm9kVlPovMp9Apmyhar5ElLulrSmCeepF7Pyf+/8xVFPrj5/QtQSwMEFAAAAAgAcXBbV1ycRxREAQAAiQIAABEAAABwcHQvcHJlc1Byb3BzLnhtbLWSy07DMBBF90j8Q+S9aztJ81KTKmmChMSCBXyAlTitpfgh230gxL8TQgoUNt2wm9Ho3jl3NKv1SQzegRnLlcwBWWDgMdmqjsttDp6f7mACPOuo7OigJMvBC7NgXdzerHSmDbNMOupG6aPxRiNpM5qDnXM6Q8i2OyaoXSjN5DjrlRHUja3Zos7Q47hADMjHOEKCcglmvblGr/qet6xW7V6MAJ8mhg0Tid1xbc9u+hq3nzkukIoxJDu5B+vmytsbnoPXJo42TRqWMMLBBoYk9GGVNhWMahLEGBNc+vHbh5qEWcdtS013L+iWNR13NXX0DEfCP3iCt0ZZ1btFq8ScE2l1ZEYrPkUleL7XgQ45wAAVKzTBXTLWASlx5JcwTpMShoGfwrKqa1hVZbKMIh8vCf5iZD3dD25irDX/Lzz0fU30+3uKd1BLAwQUAAAACABxcFtXZzMmjZsBAACCAwAAEQAAAHBwdC92aWV3UHJvcHMueG1sjVPBTuMwEL2vxD9YvoOTCEKJmnJBcEFapIa9G2eaGjm25XFLy9fvJG5pCz1wmzfjeX5vxp7eb3rD1hBQO1vz/CrjDKxyrbZdzV+bx8sJZxilbaVxFmq+BeT3s4s/U1+tNXy8BEYEFitZ82WMvhIC1RJ6iVfOg6XawoVeRoKhE22QH0TcG1FkWSl6qS3f9Yff9LvFQit4cGrVg42JJICRkcTjUnvcs/nfsPkASDRj96kkIzH+I3c1R9M2y1X/ZqU2Q4bPyLgdSEb4EgZMPNEFaJ9hERl+0hhvyiLj4rjWOD+W7q7LciyJnzxodAsHqOamTYihlb5xT0G3NacNJfj37R1URLpuVKV2Z9cyzJU0sM/jAGZTWeGGDSsurjkjmjwbZVB6eyYtvvp85YLutGWbml/mN3nB2XaIKEjn1EFxtyIDzxi/Yka9NGLahgufnHlHaou83M0mHUnJyWR/74FEHM8gaTqdkHURsIFNPBra0Ti/GSdn54yfps8bz0bT2XfH4qyEjtY091LRS2eKmm/pMRCB2u7DxJK+z+w/UEsDBBQAAAAIAHFwW1fY/Y2PpQAAALYAAAATAAAAcHB0L3RhYmxlU3R5bGVzLnhtbA3MSQ6CMBhA4b2Jd2j+fS1DUSQUwiArd+oBKpQh6UBooxLj3WX58pIvzT9KopdY7GQ0A//gARK6Nd2kBwaPe4NjQNZx3XFptGCwCgt5tt+lPHFPeXOrFFfr0KZom3AGo3NzQohtR6G4PZhZ6O31ZlHcbbkMpFv4e9OVJIHnHYnikwbUiZ7BN6qCIKK0wKfL5YhpSANcejTGcVTW1bmp/SosfkCyP1BLAwQUAAAACABxcFtXN2scvHQBAACZAwAAFQAAAHBwdC9zbGlkZXMvc2xpZGUxLnhtbK2T30rDMBTG732KkJteuWwTRMragYre+GfQ+QBZe7YW0yTkZHV9e5O0tUMnDPQmJ8k53++cD5LF8lAL0oDBSskkmk2mEQGZq6KSuyR6Wz9c3kQELZcFF0pCErWA0TK9WOgYRUGcWGLME1paq2PGMC+h5jhRGqTLbZWpuXVHs2OF4R8OWgs2n06vWc0rSXu9PkevDSBIy60b9BTEnANR222Vw73K97VjdRADIkCxrDTS1DnLM1H4iHptAPxONo9GZ3plQvqlWRlSFQmdUSJ5DQmlrE/0ZawThQ37Jt8dlaDuCn+i5wN6XVkBZPbVoSvlTvqk8nckUjm2H6Vr9VXR9fdRl8S22qFyawKNDlP5PDvuj8Ng9nCritb32bgYLnks0Ga2FRAO2i9hEpsG6oL5rV9NWHVgDyA2mP3d8tVgOdtvbHA9/w/XuN90rl2Twyj5o3t2yh0b3wwbn1EuzDPXr00w4B6mBXMXrrT7D/38YwkLPyv9BFBLAwQUAAAACABxcFtXNuhQzbcAAAA2AQAAIAAAAHBwdC9zbGlkZXMvX3JlbHMvc2xpZGUxLnhtbC5yZWxzjc+9CsIwEAfw3acIWTKZtA4i0tRFBMFJ9AGO5NoG2yTkoti3N6MFB8f7+v255vCeRvbCRC54LWpZCYbeBOt8r8X9dlrvBKMM3sIYPGoxI4lDu2quOEIuNzS4SKwgnjQfco57pcgMOAHJENGXSRfSBLmUqVcRzAN6VJuq2qr0bfB2YbKz1Tydbc3ZbY74jx26zhk8BvOc0OcfEYpGZ/ECc3jmwkLqMWsu5Xd/sVTLEsFV26jFu+0HUEsDBBQAAAAIAHFwW1daoA6towUAAOMPAAAXAAAAZG9jUHJvcHMvdGh1bWJuYWlsLmpwZWftVmtwE1UUPrt7NyltzRAoLRQHwrsywKQtQisCJmnappQ2pC2vcYZJk00TmiZhd9OWTp2R+kD9Iw/ffywFFR1nHFS0oI6tIqCjA4gFCgxjEbX4Gh6Kr4F47m5eQBCUv707e++Xc7577vnOvXM3kWORr2F4RamtFBiGgXJ8IHJa222zWFbZHdWltkorOgC0252hkJ81ADQFZNFRZjYsX7HSoO0HFsZABuRChtMlhUx2eyVgo1y4rl06AgwdD89M7f/XluEWJBcAk4Y46JZcTYhbAXi/KyTKAJozaC9qkUOItXcizhIxQcRGihtUXEJxvYqXK5xahwUxzUXn8jrdiNsRz6hPsjckYTUHpWWVCQFB9LkMtBZ2Mejx+YWkdG/ivsXW5A/H1huHb6bUWLMIxzyq3SuWO6K40+W01iCejHh/SDZT+1TEP4Ub60yIpwOwIzxiaZ3KZ+9t89YuQ5yN2O2TbbVRe1ugvqpanct2NQYXOaKc/S7JgjWDiYhPeQVbpZoPB26hxErrhXicN1wejc9VSM011licNq+lSo3DiaudFXbEuYgfE4OOajVnrkvwlznU+NzekGyP5sANBvxVlWpMohMkRaNil7215epcMkfGTVTnkpUeX6ktym8P+ZWziLmRbWLYURflHHSK1jI1DrkgBOqiMfnRbmcJre0sxAtgKeMEAYJQj70LAnAZDOCAMjDjGAIRPR7wgR8tAnoFtPiYO6ARbal5doWj4gSjQZk9SGfjKqk56gpno5wgySFGUojvPFJJ5pMiUgwGspDcRxaQErQWk3nxufak9elaZ+Nx1kAYo1LeUjBvyA3nJdbrEFf5XAeePHfV7OB1OQuxfJIrABJWIMacmax/X/v7oxMx+kj3/Ycz97VD9c3qy5/hB/k+7Pv5kwkGf4I/iU8/mDA3v5JRE74+JQ8pKYNkDb34yuDEfgB5wSTeVSt6AhtyEx5aCWF91aUq6JiRsBqPGn829hm3GLcZf7ymyimrxG3mdnIfcLu43dznYOB6uF7uQ24v9wb3XtJe3fh8xPde0RtTSz2pai2AX2fWjdVN0pXoxuum6CoT8XQ5unxduW4aesbG9y15vWQtPliBfayqqddSeXXo9UGLokBSKhyAtdec/+hsMo7kE9s1p7aInuUYQ2PVlGhMYNBM1xRr8jUVFMfy00xDXzH21qtOnesGCoQkVrLOmcqpo2eVzm5WfBIIstAq04vWEgytFX0NXtlQYDTONZjwUyUYbAHXrBkGp99vUFySQRQkQWwW3LOAfgfVK/qiQ/m+MdkHEjZ5McD8X/DOOpiwrQwDvC4B5MxO2PLwThz1IkD3HFdYbI7e+QzzBYDkKSxQf2Wa8W46FYlcxPtKuwng8sZI5O+uSOTyVox/EqDHHxkA2drq8wAsXkxvfUgDwuQCT2fju4AZG8elTB5e4BSzAOt9QKL2quja5dHf6sh2sjEGA51cnN1DqZETYKH/Hm6r0SC3G4OJ9IA+DXoY4Bg9sHqG0zORPTAec+VVQuzDyrAc4TXatGHpGUjYORxYhuNYwvE8QWnMA+gHoudHTMg3aUYucWonrskqWLdxS9ok847eUY5D5yYX1osdw9Kzc0aPyZ0ydVreXdNn3z1nblHxPZYSa2lZua2iprZu6TLcXpdb8DR4faslOdzc0rq27aGHH3l0/WOPP7Fp81NPP/Psc8+/0LV120svv7L91dfefOvtne+8271r90cf7/lk7779n3725eGv+o4cPdZ/fOD0N2e+/e77wbM/nL9w8dffLv3+x59/UV1UZ6yl1IVFYFhCOKKluhi2hRL0hJ+QrxlhWqJ1rhk5sWBdWpZ545YdvcMmFTrOjaoXD6VnT549MOU8laYouzVhHf9LWVxYQtdxyOTwwOk5PSyEK1fyoJN9MB2GhqFhaBgahob/OET6/wFQSwMEFAAAAAgAcXBbV4sU/ON5AQAA2wIAABEAAABkb2NQcm9wcy9jb3JlLnhtbI2SzU7DMBCE7zxF1EtOqeMWSomSIAHiBBJSi0DcjL1NDYlt2dumeXucpE356YFbVjP7aTyb9HpXlcEWrJNaZSEdx2EAimshVZGFz8v7aB4GDpkSrNQKsrABF17nZyk3CdcWnqw2YFGCCzxIuYSbbLRGNAkhjq+hYm7sHcqLK20rhn60BTGMf7ICyCSOZ6QCZIIhIy0wMgNxtEcKPiDNxpYdQHACJVSg0BE6puToRbCVO7nQKd+clcTGwEnrQRzcOycHY13X43raWX1+Sl4fHxbdUyOp2qo4jPJU8AQllkC6T7d5/wCO/cAtMNTWD77ET2hqbYXrJQGOW2nQHyMvQIFlCCLYOH+NwDS41ioyBncp+eVtSSVz+OgPt5Igbpp8gbCF4JYp1aTkr9xuWNjK9u457RzDmO5b7JP6AP71Sd/VQXmZ3t4t70f5JKbTKKbR5HIZXyX0PKGztzbdj/0jsNoH+D/xIrmYfyMeAF1+7uGFto3vjvz5H/MvUEsDBBQAAAAIAHFwW1ee0I557wEAAG0EAAAQAAAAZG9jUHJvcHMvYXBwLnhtbJ1UwY7TMBC9I/EPlk9waJNChVDlZgVdrXqgNFKzy3mwJ42FY0e26W75eiYJyaZQIUFO7808vRnP2BE3T7VhJ/RBO7vmi3nKGVrplLbHNb8v7mbvOQsRrALjLK75GQO/yV6+ELl3DfqoMTCysGHNqxibVZIEWWENYU5pS5nS+RoiUX9MXFlqibdOfq/RxuRNmr5L8CmiVahmzWjIe8fVKf6vqXKy7S88FOeG/DJRuAim0DVmC5E8E/HFeRWyVCQ9EB+axmgJkaaR7bT0Lrgysh1IbaMLFcvdI/rcERPJVEvjwEDlO3bXdZft7SxIj2jZoXKP7NVy9fa1SK4IRQ4ejh6aqmtlwsTBaIVd9BcSn13sAz0QW60U2mfdBRe73cbopksMUBwkGNzQeLISTECyHgNii9CuPgftSXmKqxPK6DwL+gctf8nZVwjYDnXNT+A12Mh7WU86bJoQfVbQwsh75B2cyqZYL9u99OCvwt6rOx0rdDQY/qFEer1EMh6T8OUA+hL7klYSr8xjMZ1H1wOfdLnvLia7Poih3m8VdmDhiG1iRBtXN2DPFBrRJ22/hfumcLcQcdjiZVAcKvCo6FmMWx4DYksNe0P6j9R9e+hLPtKwqcAeUQ0WfybaB/PQ/z2yxXKe0tc9jCHW3vfhWWc/AVBLAQIUAxQAAAAIAHFwW1fGr8RntAEAALoMAAATAAAAAAAAAAAAAACAAQAAAABbQ29udGVudF9UeXBlc10ueG1sUEsBAhQDFAAAAAgAcXBbV/ENN+wAAQAA4QIAAAsAAAAAAAAAAAAAAIAB5QEAAF9yZWxzLy5yZWxzUEsBAhQDFAAAAAgAcXBbVwV3nA87AgAAtAwAABQAAAAAAAAAAAAAAIABDgMAAHBwdC9wcmVzZW50YXRpb24ueG1sUEsBAhQDFAAAAAgAcXBbV1KcUMkcAQAAcQQAAB8AAAAAAAAAAAAAAIABewUAAHBwdC9fcmVscy9wcmVzZW50YXRpb24ueG1sLnJlbHNQSwECFAMUAAAACABxcFtXpi2iNe4GAADSLgAAIQAAAAAAAAAAAAAAgAHUBgAAcHB0L3NsaWRlTWFzdGVycy9zbGlkZU1hc3RlcjEueG1sUEsBAhQDFAAAAAgAcXBbV75rQr0NAQAAxgcAACwAAAAAAAAAAAAAAIABAQ4AAHBwdC9zbGlkZU1hc3RlcnMvX3JlbHMvc2xpZGVNYXN0ZXIxLnhtbC5yZWxzUEsBAhQDFAAAAAgAcXBbVwD97A0qBAAABREAACEAAAAAAAAAAAAAAIABWA8AAHBwdC9zbGlkZUxheW91dHMvc2xpZGVMYXlvdXQxLnhtbFBLAQIUAxQAAAAIAHFwW1eAZeGItwAAADYBAAAsAAAAAAAAAAAAAACAAcETAABwcHQvc2xpZGVMYXlvdXRzL19yZWxzL3NsaWRlTGF5b3V0MS54bWwucmVsc1BLAQIUAxQAAAAIAHFwW1c3xjX4jQMAAM0LAAAiAAAAAAAAAAAAAACAAcIUAABwcHQvc2xpZGVMYXlvdXRzL3NsaWRlTGF5b3V0MTAueG1sUEsBAhQDFAAAAAgAcXBbV4Bl4Yi3AAAANgEAAC0AAAAAAAAAAAAAAIABjxgAAHBwdC9zbGlkZUxheW91dHMvX3JlbHMvc2xpZGVMYXlvdXQxMC54bWwucmVsc1BLAQIUAxQAAAAIAHFwW1dLiVBXwAMAAK0MAAAiAAAAAAAAAAAAAACAAZEZAABwcHQvc2xpZGVMYXlvdXRzL3NsaWRlTGF5b3V0MTEueG1sUEsBAhQDFAAAAAgAcXBbV4Bl4Yi3AAAANgEAAC0AAAAAAAAAAAAAAIABkR0AAHBwdC9zbGlkZUxheW91dHMvX3JlbHMvc2xpZGVMYXlvdXQxMS54bWwucmVsc1BLAQIUAxQAAAAIAHFwW1eTCm11IQYAAOcdAAAUAAAAAAAAAAAAAACAAZMeAABwcHQvdGhlbWUvdGhlbWUxLnhtbFBLAQIUAxQAAAAIAHFwW1cBV+iLbQMAAJYLAAAhAAAAAAAAAAAAAACAAeYkAABwcHQvc2xpZGVMYXlvdXRzL3NsaWRlTGF5b3V0Mi54bWxQSwECFAMUAAAACABxcFtXgGXhiLcAAAA2AQAALAAAAAAAAAAAAAAAgAGSKAAAcHB0L3NsaWRlTGF5b3V0cy9fcmVscy9zbGlkZUxheW91dDIueG1sLnJlbHNQSwECFAMUAAAACABxcFtXi2DtWmMEAABYEQAAIQAAAAAAAAAAAAAAgAGTKQAAcHB0L3NsaWRlTGF5b3V0cy9zbGlkZUxheW91dDMueG1sUEsBAhQDFAAAAAgAcXBbV4Bl4Yi3AAAANgEAACwAAAAAAAAAAAAAAIABNS4AAHBwdC9zbGlkZUxheW91dHMvX3JlbHMvc2xpZGVMYXlvdXQzLnhtbC5yZWxzUEsBAhQDFAAAAAgAcXBbV0/KghwIBAAAaBIAACEAAAAAAAAAAAAAAIABNi8AAHBwdC9zbGlkZUxheW91dHMvc2xpZGVMYXlvdXQ0LnhtbFBLAQIUAxQAAAAIAHFwW1eAZeGItwAAADYBAAAsAAAAAAAAAAAAAACAAX0zAABwcHQvc2xpZGVMYXlvdXRzL19yZWxzL3NsaWRlTGF5b3V0NC54bWwucmVsc1BLAQIUAxQAAAAIAHFwW1fppMSP4wQAADYcAAAhAAAAAAAAAAAAAACAAX40AABwcHQvc2xpZGVMYXlvdXRzL3NsaWRlTGF5b3V0NS54bWxQSwECFAMUAAAACABxcFtXgGXhiLcAAAA2AQAALAAAAAAAAAAAAAAAgAGgOQAAcHB0L3NsaWRlTGF5b3V0cy9fcmVscy9zbGlkZUxheW91dDUueG1sLnJlbHNQSwECFAMUAAAACABxcFtXLbQm9RIDAAC4CAAAIQAAAAAAAAAAAAAAgAGhOgAAcHB0L3NsaWRlTGF5b3V0cy9zbGlkZUxheW91dDYueG1sUEsBAhQDFAAAAAgAcXBbV4Bl4Yi3AAAANgEAACwAAAAAAAAAAAAAAIAB8j0AAHBwdC9zbGlkZUxheW91dHMvX3JlbHMvc2xpZGVMYXlvdXQ2LnhtbC5yZWxzUEsBAhQDFAAAAAgAcXBbV+sXn3fmAgAAZwcAACEAAAAAAAAAAAAAAIAB8z4AAHBwdC9zbGlkZUxheW91dHMvc2xpZGVMYXlvdXQ3LnhtbFBLAQIUAxQAAAAIAHFwW1eAZeGItwAAADYBAAAsAAAAAAAAAAAAAACAARhCAABwcHQvc2xpZGVMYXlvdXRzL19yZWxzL3NsaWRlTGF5b3V0Ny54bWwucmVsc1BLAQIUAxQAAAAIAHFwW1fNyorVsgQAAMISAAAhAAAAAAAAAAAAAACAARlDAABwcHQvc2xpZGVMYXlvdXRzL3NsaWRlTGF5b3V0OC54bWxQSwECFAMUAAAACABxcFtXgGXhiLcAAAA2AQAALAAAAAAAAAAAAAAAgAEKSAAAcHB0L3NsaWRlTGF5b3V0cy9fcmVscy9zbGlkZUxheW91dDgueG1sLnJlbHNQSwECFAMUAAAACABxcFtXWtO0knkEAAAxEgAAIQAAAAAAAAAAAAAAgAELSQAAcHB0L3NsaWRlTGF5b3V0cy9zbGlkZUxheW91dDkueG1sUEsBAhQDFAAAAAgAcXBbV4Bl4Yi3AAAANgEAACwAAAAAAAAAAAAAAIABw00AAHBwdC9zbGlkZUxheW91dHMvX3JlbHMvc2xpZGVMYXlvdXQ5LnhtbC5yZWxzUEsBAhQDFAAAAAgAcXBbV+jkSdE5AwAAsyQAACgAAAAAAAAAAAAAAIABxE4AAHBwdC9wcmludGVyU2V0dGluZ3MvcHJpbnRlclNldHRpbmdzMS5iaW5QSwECFAMUAAAACABxcFtXXJxHFEQBAACJAgAAEQAAAAAAAAAAAAAAgAFDUgAAcHB0L3ByZXNQcm9wcy54bWxQSwECFAMUAAAACABxcFtXZzMmjZsBAACCAwAAEQAAAAAAAAAAAAAAgAG2UwAAcHB0L3ZpZXdQcm9wcy54bWxQSwECFAMUAAAACABxcFtX2P2Nj6UAAAC2AAAAEwAAAAAAAAAAAAAAgAGAVQAAcHB0L3RhYmxlU3R5bGVzLnhtbFBLAQIUAxQAAAAIAHFwW1c3axy8dAEAAJkDAAAVAAAAAAAAAAAAAACAAVZWAABwcHQvc2xpZGVzL3NsaWRlMS54bWxQSwECFAMUAAAACABxcFtXNuhQzbcAAAA2AQAAIAAAAAAAAAAAAAAAgAH9VwAAcHB0L3NsaWRlcy9fcmVscy9zbGlkZTEueG1sLnJlbHNQSwECFAMUAAAACABxcFtXWqAOraMFAADjDwAAFwAAAAAAAAAAAAAAgAHyWAAAZG9jUHJvcHMvdGh1bWJuYWlsLmpwZWdQSwECFAMUAAAACABxcFtXixT843kBAADbAgAAEQAAAAAAAAAAAAAAgAHKXgAAZG9jUHJvcHMvY29yZS54bWxQSwECFAMUAAAACABxcFtXntCOee8BAABtBAAAEAAAAAAAAAAAAAAAgAFyYAAAZG9jUHJvcHMvYXBwLnhtbFBLBQYAAAAAJgAmAKMLAACPYgAAAAA=" -) - -simple_unstructured_scenario = ( - TestScenarioBuilder() - .set_name("simple_unstructured_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "unstructured"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "sample.pdf": { - # minimal pdf file inlined as base 64 - "contents": pdf_file, - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "sample.docx": { - # minimal docx file inlined as base 64 - "contents": docx_file, - "last_modified": "2023-06-06T03:54:07.000Z", - }, - "sample.pptx": { - # minimal pptx file inlined as base 64 - "contents": pptx_file, - "last_modified": "2023-06-07T03:54:07.000Z", - }, - } - ) - .set_file_type("unstructured") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": json_schema, - "name": "stream1", - "source_defined_cursor": True, - "source_defined_primary_key": [["document_key"]], - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "document_key": "sample.pdf", - "content": "# Hello World", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "sample.pdf", - }, - "stream": "stream1", - }, - { - "data": { - "document_key": "sample.docx", - "content": "# Content", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "sample.docx", - }, - "stream": "stream1", - }, - { - "data": { - "document_key": "sample.pptx", - "content": "# Title", - "_ab_source_file_last_modified": "2023-06-07T03:54:07.000000Z", - "_ab_source_file_url": "sample.pptx", - }, - "stream": "stream1", - }, - ] - ) -).build() - -corrupted_file_scenario = ( - TestScenarioBuilder() - .set_name("corrupted_file_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "unstructured"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "sample.pdf": { - # bytes that can't be parsed as pdf - "contents": bytes("___ corrupted file ___", "utf-8"), - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("unstructured") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": json_schema, - "name": "stream1", - "source_defined_cursor": True, - "source_defined_primary_key": [["document_key"]], - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "document_key": "sample.pdf", - "_ab_source_file_parse_error": "Error parsing record. This could be due to a mismatch between the config's file type and the actual file type, or because the file or record is not parseable. Contact Support if you need assistance.\nfilename=sample.pdf message=No /Root object! - Is this really a PDF?", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "sample.pdf", - }, - "stream": "stream1", - }, - ] - ) -).build() - -no_file_extension_unstructured_scenario = ( - TestScenarioBuilder() - .set_name("no_file_extension_unstructured_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "unstructured"}, - "globs": ["*"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "pdf_without_extension": { - # same file, but can't be detected via file extension - "contents": pdf_file, - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "docx_without_extension": { - # same file, but can't be detected via file extesion - "contents": docx_file, - "last_modified": "2023-06-06T03:54:07.000Z", - }, - "pptx_without_extension": { - # minimal pptx file inlined as base 64 - "contents": pptx_file, - "last_modified": "2023-06-07T03:54:07.000Z", - }, - } - ) - .set_file_type("unstructured") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": json_schema, - "name": "stream1", - "source_defined_cursor": True, - "source_defined_primary_key": [["document_key"]], - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "document_key": "pdf_without_extension", - "content": "# Hello World", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "pdf_without_extension", - }, - "stream": "stream1", - }, - { - "data": { - "document_key": "docx_without_extension", - "content": "# Content", - "_ab_source_file_last_modified": "2023-06-06T03:54:07.000000Z", - "_ab_source_file_url": "docx_without_extension", - }, - "stream": "stream1", - }, - { - "data": { - "document_key": "pptx_without_extension", - "content": "# Title", - "_ab_source_file_last_modified": "2023-06-07T03:54:07.000000Z", - "_ab_source_file_url": "pptx_without_extension", - }, - "stream": "stream1", - }, - ] - ) -).build() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/user_input_schema_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/user_input_schema_scenarios.py deleted file mode 100644 index 3c10e701c629..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/user_input_schema_scenarios.py +++ /dev/null @@ -1,758 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.file_based.exceptions import ConfigValidationError, FileBasedSourceError -from airbyte_cdk.test.catalog_builder import CatalogBuilder -from unit_tests.sources.file_based.scenarios.file_based_source_builder import FileBasedSourceBuilder -from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenarioBuilder - -""" -User input schema rules: - - `check`: Successful if the schema conforms to a record, otherwise ConfigValidationError. - - `discover`: User-input schema is output if the schema is valid, otherwise ConfigValidationError. - - `read`: If the schema is valid, record values are cast to types in the schema; if this is successful - the records are emitted. otherwise an error is logged. If the schema is not valid, ConfigValidationError. -""" - - -_base_user_input_schema_scenario = ( - TestScenarioBuilder() - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11", "val12"), - ("val21", "val22"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - } - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": "string"}, - "col2": {"type": "string"}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11", - "col2": "val12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val21", - "col2": "val22", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - ] - ) -) - - -valid_single_stream_user_input_schema_scenario = ( - _base_user_input_schema_scenario.copy() - .set_name("valid_single_stream_user_input_schema_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "string", "col2": "string"}', - } - ] - } - ) - .set_expected_check_status("SUCCEEDED") -).build() - - -single_stream_user_input_schema_scenario_schema_is_invalid = ( - _base_user_input_schema_scenario.copy() - .set_name("single_stream_user_input_schema_scenario_schema_is_invalid") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "x", "col2": "string"}', - } - ] - } - ) - .set_catalog(CatalogBuilder().with_stream("stream1", SyncMode.full_refresh).build()) - .set_expected_check_status("FAILED") - .set_expected_check_error(None, FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA.value) - .set_expected_discover_error(ConfigValidationError, FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA.value) - .set_expected_read_error(ConfigValidationError, FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA.value) -).build() - - -single_stream_user_input_schema_scenario_emit_nonconforming_records = ( - _base_user_input_schema_scenario.copy() - .set_name("single_stream_user_input_schema_scenario_emit_nonconforming_records") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "integer", "col2": "string"}', - } - ] - } - ) - .set_expected_check_status("FAILED") - .set_expected_check_error(None, FileBasedSourceError.SCHEMA_INFERENCE_ERROR.value) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": "integer"}, - "col2": {"type": "string"}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) -).build() - - -single_stream_user_input_schema_scenario_skip_nonconforming_records = ( - _base_user_input_schema_scenario.copy() - .set_name("single_stream_user_input_schema_scenario_skip_nonconforming_records") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*"], - "validation_policy": "Skip Record", - "input_schema": '{"col1": "integer", "col2": "string"}', - } - ] - } - ) - .set_expected_check_status("FAILED") - .set_expected_check_error(None, FileBasedSourceError.SCHEMA_INFERENCE_ERROR.value) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": "integer"}, - "col2": {"type": "string"}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) - .set_expected_records([]) - .set_expected_logs( - { - "read": [ - { - "level": "WARN", - "message": "Records in file did not pass validation policy. stream=stream1 file=a.csv n_skipped=2 validation_policy=skip_record", - }, - { - "level": "WARN", - "message": "Could not cast the value to the expected type.: col1: value=val11,expected_type=integer", - }, - { - "level": "WARN", - "message": "Could not cast the value to the expected type.: col1: value=val21,expected_type=integer", - }, - ] - } - ) -).build() - - -_base_multi_stream_user_input_schema_scenario = ( - TestScenarioBuilder() - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val11a", 21), - ("val12a", 22), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.csv": { - "contents": [ - ("col1", "col2", "col3"), - ("val11b", "val12b", "val13b"), - ("val21b", "val22b", "val23b"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "c.csv": { - "contents": [ - ("col1",), - ("val11c",), - ("val21c",), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": "string", - }, - "col2": { - "type": "integer", - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": "string", - }, - "col2": { - "type": "string", - }, - "col3": { - "type": "string", - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream2", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream3", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": 21, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val12a", - "col2": 22, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - # The files in b.csv are emitted despite having an invalid schema - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream2", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream2", - }, - { - "data": {"col1": "val11c", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "c.csv"}, - "stream": "stream3", - }, - { - "data": {"col1": "val21c", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "c.csv"}, - "stream": "stream3", - }, - ] - ) -) - - -valid_multi_stream_user_input_schema_scenario = ( - _base_multi_stream_user_input_schema_scenario.copy() - .set_name("valid_multi_stream_user_input_schema_scenario") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["a.csv"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "string", "col2": "integer"}', - }, - { - "name": "stream2", - "format": {"filetype": "csv"}, - "globs": ["b.csv"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "string", "col2": "string", "col3": "string"}', - }, - { - "name": "stream3", - "format": {"filetype": "csv"}, - "globs": ["c.csv"], - "validation_policy": "Emit Record", - }, - ] - } - ) - .set_expected_check_status("SUCCEEDED") -).build() - - -multi_stream_user_input_schema_scenario_schema_is_invalid = ( - _base_multi_stream_user_input_schema_scenario.copy() - .set_name("multi_stream_user_input_schema_scenario_schema_is_invalid") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["a.csv"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "string", "col2": "integer"}', - }, - { - "name": "stream2", - "format": {"filetype": "csv"}, - "globs": ["b.csv"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "x", "col2": "string", "col3": "string"}', # this stream's schema is invalid - }, - { - "name": "stream3", - "format": {"filetype": "csv"}, - "globs": ["c.csv"], - "validation_policy": "Emit Record", - }, - ] - } - ) - .set_catalog( - CatalogBuilder() - .with_stream("stream1", SyncMode.full_refresh) - .with_stream("stream2", SyncMode.full_refresh) - .with_stream("stream3", SyncMode.full_refresh) - .build() - ) - .set_expected_check_status("FAILED") - .set_expected_check_error(None, FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA.value) - .set_expected_discover_error(ConfigValidationError, FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA.value) - .set_expected_read_error(ConfigValidationError, FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA.value) -).build() - - -multi_stream_user_input_schema_scenario_emit_nonconforming_records = ( - _base_multi_stream_user_input_schema_scenario.copy() - .set_name("multi_stream_user_input_schema_scenario_emit_nonconforming_records") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["a.csv"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "string", "col2": "integer"}', - }, - { - "name": "stream2", - "format": {"filetype": "csv"}, - "globs": ["b.csv"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "string", "col2": "integer", "col3": "string"}', # this stream's records do not conform to the schema - }, - { - "name": "stream3", - "format": {"filetype": "csv"}, - "globs": ["c.csv"], - "validation_policy": "Emit Record", - }, - ] - } - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": "string"}, - "col2": {"type": "integer"}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": "string"}, - "col2": {"type": "integer"}, - "col3": {"type": "string"}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream2", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream3", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - ] - } - ) - .set_expected_check_status("FAILED") - .set_expected_check_error(None, FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA.value) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": 21, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val12a", - "col2": 22, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val11b", - "col2": "val12b", - "col3": "val13b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream2", - }, - { - "data": { - "col1": "val21b", - "col2": "val22b", - "col3": "val23b", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream2", - }, - { - "data": {"col1": "val11c", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "c.csv"}, - "stream": "stream3", - }, - { - "data": {"col1": "val21c", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "c.csv"}, - "stream": "stream3", - }, - ] - ) - .set_expected_logs( - { - "read": [ - { - "level": "WARN", - "message": "Could not cast the value to the expected type.: col2: value=val12b,expected_type=integer", - }, - { - "level": "WARN", - "message": "Could not cast the value to the expected type.: col2: value=val22b,expected_type=integer", - }, - ] - } - ) -).build() - - -multi_stream_user_input_schema_scenario_skip_nonconforming_records = ( - _base_multi_stream_user_input_schema_scenario.copy() - .set_name("multi_stream_user_input_schema_scenario_skip_nonconforming_records") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["a.csv"], - "validation_policy": "Emit Record", - "input_schema": '{"col1": "string", "col2": "integer"}', - }, - { - "name": "stream2", - "format": {"filetype": "csv"}, - "globs": ["b.csv"], - "validation_policy": "Skip Record", - "input_schema": '{"col1": "string", "col2": "integer", "col3": "string"}', # this stream's records do not conform to the schema - }, - { - "name": "stream3", - "format": {"filetype": "csv"}, - "globs": ["c.csv"], - "validation_policy": "Emit Record", - }, - ] - } - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": "string"}, - "col2": {"type": "integer"}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": {"type": "string"}, - "col2": {"type": "integer"}, - "col3": {"type": "string"}, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream2", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": ["null", "string"], - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream3", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - ] - } - ) - .set_expected_check_status("FAILED") - .set_expected_check_error(None, FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA.value) - .set_expected_records( - [ - { - "data": { - "col1": "val11a", - "col2": 21, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val12a", - "col2": 22, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - # {"data": {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - # "_ab_source_file_url": "b.csv"}, "stream": "stream2"}, - # {"data": {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - # "_ab_source_file_url": "b.csv"}, "stream": "stream2"}, - { - "data": {"col1": "val11c", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "c.csv"}, - "stream": "stream3", - }, - { - "data": {"col1": "val21c", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "c.csv"}, - "stream": "stream3", - }, - ] - ) - .set_expected_logs( - { - "read": [ - { - "level": "WARN", - "message": "Records in file did not pass validation policy. stream=stream2 file=b.csv n_skipped=2 validation_policy=skip_record", - }, - { - "level": "WARN", - "message": "Could not cast the value to the expected type.: col2: value=val12b,expected_type=integer", - }, - { - "level": "WARN", - "message": "Could not cast the value to the expected type.: col2: value=val22b,expected_type=integer", - }, - ] - } - ) -).build() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/validation_policy_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/validation_policy_scenarios.py deleted file mode 100644 index 47e37dffd9c4..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/validation_policy_scenarios.py +++ /dev/null @@ -1,729 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from unit_tests.sources.file_based.scenarios.file_based_source_builder import FileBasedSourceBuilder -from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenarioBuilder - -_base_single_stream_scenario = ( - TestScenarioBuilder() - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a.csv": { - "contents": [ - ("col1", "col2"), - ("val_a_11", "1"), - ("val_a_12", "2"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b.csv": { # The records in this file do not conform to the schema - "contents": [ - ("col1", "col2"), - ("val_b_11", "this is text that will trigger validation policy"), - ("val_b_12", "2"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "c.csv": { - "contents": [ - ("col1",), - ("val_c_11",), - ("val_c_12", "val_c_22"), # This record is not parsable - ("val_c_13",), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "d.csv": { - "contents": [ - ("col1",), - ("val_d_11",), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": "string", - }, - "col2": { - "type": "integer", - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - } - ] - } - ) -) - - -_base_multi_stream_scenario = ( - TestScenarioBuilder() - .set_source_builder( - FileBasedSourceBuilder() - .set_files( - { - "a/a1.csv": { - "contents": [ - ("col1", "col2"), - ("val_aa1_11", "1"), - ("val_aa1_12", "2"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "a/a2.csv": { - "contents": [ - ("col1", "col2"), - ("val_aa2_11", "this is text that will trigger validation policy"), - ("val_aa2_12", "2"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "a/a3.csv": { - "contents": [ - ("col1",), - ("val_aa3_11",), - ("val_aa3_12", "val_aa3_22"), # This record is not parsable - ("val_aa3_13",), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "a/a4.csv": { - "contents": [ - ("col1",), - ("val_aa4_11",), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b/b1.csv": { # The records in this file do not conform to the schema - "contents": [ - ("col1", "col2"), - ("val_bb1_11", "1"), - ("val_bb1_12", "2"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b/b2.csv": { - "contents": [ - ("col1", "col2"), - ("val_bb2_11", "this is text that will trigger validation policy"), - ("val_bb2_12", "2"), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - "b/b3.csv": { - "contents": [ - ("col1",), - ("val_bb3_11",), - ("val_bb3_12",), - ], - "last_modified": "2023-06-05T03:54:07.000Z", - }, - } - ) - .set_file_type("csv") - ) - .set_expected_catalog( - { - "streams": [ - { - "default_cursor_field": ["_ab_source_file_last_modified"], - "json_schema": { - "type": "object", - "properties": { - "col1": { - "type": "string", - }, - "col2": { - "type": "integer", - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream1", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - { - "json_schema": { - "default_cursor_field": ["_ab_source_file_last_modified"], - "type": "object", - "properties": { - "col1": { - "type": "string", - }, - "col2": { - "type": "integer", - }, - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - }, - }, - "name": "stream2", - "source_defined_cursor": True, - "supported_sync_modes": ["full_refresh", "incremental"], - "is_resumable": True, - }, - ] - } - ) -) - - -skip_record_scenario_single_stream = ( - _base_single_stream_scenario.copy() - .set_name("skip_record_scenario_single_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Skip Record", - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val_a_11", - "col2": 1, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val_a_12", - "col2": 2, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - # {"data": {"col1": "val_b_11", "col2": "this is text that will trigger validation policy", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, # This record is skipped because it does not conform - { - "data": { - "col1": "val_b_12", - "col2": 2, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val_c_11", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - # {"data": {"col1": "val_c_12", None: "val_c_22", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "c.csv"}, "stream": "stream1"}, # This record is malformed so should not be emitted - # {"data": {"col1": "val_c_13", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "c.csv"}, "stream": "stream1"}, # Skipped since previous record is malformed - { - "data": { - "col1": "val_d_11", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "d.csv", - }, - "stream": "stream1", - }, - ] - ) - .set_expected_logs( - { - "read": [ - { - "level": "WARN", - "message": "Records in file did not pass validation policy. stream=stream1 file=b.csv n_skipped=1 validation_policy=skip_record", - }, - { - "level": "ERROR", - "message": "Error parsing record. This could be due to a mismatch between the config's file type and the actual file type, or because the file or record is not parseable. stream=stream1 file=c.csv line_no=2 n_skipped=0", - }, - { - "level": "WARN", - "message": "Could not cast the value to the expected type.: col2: value=this is text that will trigger validation policy,expected_type=integer", - }, - ] - } - ) - .set_expected_read_error( - AirbyteTracedException, - "Please check the logged errors for more information.", - ) -).build() - - -skip_record_scenario_multi_stream = ( - _base_multi_stream_scenario.copy() - .set_name("skip_record_scenario_multi_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["a/*.csv"], - "validation_policy": "Skip Record", - }, - { - "name": "stream2", - "format": {"filetype": "csv"}, - "globs": ["b/*.csv"], - "validation_policy": "Skip Record", - }, - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val_aa1_11", - "col2": 1, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a/a1.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val_aa1_12", - "col2": 2, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a/a1.csv", - }, - "stream": "stream1", - }, - # {"data": {"col1": "val_aa2_11", "col2": "this is text that will trigger validation policy", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "a/a2.csv"}, "stream": "stream1"}, # This record is skipped because it does not conform - { - "data": { - "col1": "val_aa2_12", - "col2": 2, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a/a2.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val_aa3_11", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a/a3.csv", - }, - "stream": "stream1", - }, - # {"data": {"col1": "val_aa3_12", None: "val_aa3_22", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "a/a3.csv"}, "stream": "stream1"}, # This record is malformed so should not be emitted - # {"data": {"col1": "val_aa3_13", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "a/a3.csv"}, "stream": "stream1"}, # Skipped since previous record is malformed - { - "data": { - "col1": "val_aa4_11", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a/a4.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val_bb1_11", - "col2": 1, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b/b1.csv", - }, - "stream": "stream2", - }, - { - "data": { - "col1": "val_bb1_12", - "col2": 2, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b/b1.csv", - }, - "stream": "stream2", - }, - # {"data": {"col1": "val_bb2_11", "col2": "val_bb2_21", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "b/b2.csv"}, "stream": "stream2"}, # This record is skipped because it does not conform - { - "data": { - "col1": "val_bb2_12", - "col2": 2, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b/b2.csv", - }, - "stream": "stream2", - }, - { - "data": { - "col1": "val_bb3_11", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b/b3.csv", - }, - "stream": "stream2", - }, - { - "data": { - "col1": "val_bb3_12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b/b3.csv", - }, - "stream": "stream2", - }, - ] - ) - .set_expected_logs( - { - "read": [ - { - "level": "WARN", - "message": "Records in file did not pass validation policy. stream=stream1 file=a/a2.csv n_skipped=1 validation_policy=skip_record", - }, - { - "level": "ERROR", - "message": "Error parsing record. This could be due to a mismatch between the config's file type and the actual file type, or because the file or record is not parseable. stream=stream1 file=a/a3.csv line_no=2 n_skipped=0", - }, - { - "level": "WARN", - "message": "Records in file did not pass validation policy. stream=stream2 file=b/b2.csv n_skipped=1 validation_policy=skip_record", - }, - { - "level": "WARN", - "message": "Could not cast the value to the expected type.: col2: value=this is text that will trigger validation policy,expected_type=integer", - }, - { - "level": "WARN", - "message": "Could not cast the value to the expected type.: col2: value=this is text that will trigger validation policy,expected_type=integer", - }, - ] - } - ) - .set_expected_read_error( - AirbyteTracedException, - "Please check the logged errors for more information.", - ) -).build() - - -emit_record_scenario_single_stream = ( - _base_single_stream_scenario.copy() - .set_name("emit_record_scenario_single_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Emit Record", - } - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val_a_11", - "col2": 1, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val_a_12", - "col2": 2, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val_b_11", - "col2": "this is text that will trigger validation policy", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, # This record is skipped because it does not conform - { - "data": { - "col1": "val_b_12", - "col2": 2, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val_c_11", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "c.csv", - }, - "stream": "stream1", - }, - # {"data": {"col1": "val_c_12", None: "val_c_22", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "c.csv"}, "stream": "stream1"}, # This record is malformed so should not be emitted - # {"data": {"col1": "val_c_13", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "c.csv"}, "stream": "stream1"}, # No more records from this stream are emitted after we hit a parse error - { - "data": { - "col1": "val_d_11", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "d.csv", - }, - "stream": "stream1", - }, - ] - ) - .set_expected_read_error( - AirbyteTracedException, - "Please check the logged errors for more information.", - ) -).build() - - -emit_record_scenario_multi_stream = ( - _base_multi_stream_scenario.copy() - .set_name("emit_record_scenario_multi_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["a/*.csv"], - "validation_policy": "Emit Record", - }, - { - "name": "stream2", - "format": {"filetype": "csv"}, - "globs": ["b/*.csv"], - "validation_policy": "Emit Record", - }, - ] - } - ) - .set_expected_records( - [ - { - "data": { - "col1": "val_aa1_11", - "col2": 1, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a/a1.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val_aa1_12", - "col2": 2, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a/a1.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val_aa2_11", - "col2": "this is text that will trigger validation policy", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a/a2.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val_aa2_12", - "col2": 2, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a/a2.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val_aa3_11", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a/a3.csv", - }, - "stream": "stream1", - }, - # {"data": {"col1": "val_aa3_12", None: "val_aa3_22", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "a/a3.csv"}, "stream": "stream1"}, # This record is malformed so should not be emitted - # {"data": {"col1": "val_aa3_13", "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", "_ab_source_file_url": "a/a3.csv"}, "stream": "stream1"}, # Skipped since previous record is malformed - { - "data": { - "col1": "val_aa4_11", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "a/a4.csv", - }, - "stream": "stream1", - }, - { - "data": { - "col1": "val_bb1_11", - "col2": 1, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b/b1.csv", - }, - "stream": "stream2", - }, - { - "data": { - "col1": "val_bb1_12", - "col2": 2, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b/b1.csv", - }, - "stream": "stream2", - }, - { - "data": { - "col1": "val_bb2_11", - "col2": "this is text that will trigger validation policy", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b/b2.csv", - }, - "stream": "stream2", - }, - { - "data": { - "col1": "val_bb2_12", - "col2": 2, - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b/b2.csv", - }, - "stream": "stream2", - }, - { - "data": { - "col1": "val_bb3_11", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b/b3.csv", - }, - "stream": "stream2", - }, - { - "data": { - "col1": "val_bb3_12", - "_ab_source_file_last_modified": "2023-06-05T03:54:07.000000Z", - "_ab_source_file_url": "b/b3.csv", - }, - "stream": "stream2", - }, - ] - ) - .set_expected_read_error( - AirbyteTracedException, - "Please check the logged errors for more information.", - ) -).build() - - -wait_for_rediscovery_scenario_single_stream = ( - _base_single_stream_scenario.copy() - .set_name("wait_for_rediscovery_scenario_single_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["*.csv"], - "validation_policy": "Wait for Discover", - } - ] - } - ) - .set_expected_records(None) # When syncing streams concurrently we don't know how many records will be emitted before the sync stops - .set_expected_logs( - { - "read": [ - { - "level": "WARN", - "message": "Stopping sync in accordance with the configured validation policy. Records in file did not conform to the schema. stream=stream1 file=b.csv validation_policy=Wait for Discover n_skipped=0", - }, - { - "level": "WARN", - "message": "Could not cast the value to the expected type.: col2: value=this is text that will trigger validation policy,expected_type=integer", - }, - ] - } - ) -).build() - - -wait_for_rediscovery_scenario_multi_stream = ( - _base_multi_stream_scenario.copy() - .set_name("wait_for_rediscovery_scenario_multi_stream") - .set_config( - { - "streams": [ - { - "name": "stream1", - "format": {"filetype": "csv"}, - "globs": ["a/*.csv"], - "validation_policy": "Wait for Discover", - }, - { - "name": "stream2", - "format": {"filetype": "csv"}, - "globs": ["b/*.csv"], - "validation_policy": "Wait for Discover", - }, - ] - } - ) - .set_expected_records(None) # When syncing streams concurrently we don't know how many records will be emitted before the sync stops - .set_expected_logs( - { - "read": [ - { - "level": "WARN", - "message": "Stopping sync in accordance with the configured validation policy. Records in file did not conform to the schema. stream=stream1 file=a/a2.csv validation_policy=Wait for Discover n_skipped=0", - }, - { - "level": "WARN", - "message": "Stopping sync in accordance with the configured validation policy. Records in file did not conform to the schema. stream=stream2 file=b/b2.csv validation_policy=Wait for Discover n_skipped=0", - }, - { - "level": "WARN", - "message": "Could not cast the value to the expected type.: col2: value=this is text that will trigger validation policy,expected_type=integer", - }, - { - "level": "WARN", - "message": "Could not cast the value to the expected type.: col2: value=this is text that will trigger validation policy,expected_type=integer", - }, - ] - } - ) -).build() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/schema_validation_policies/test_default_schema_validation_policy.py b/airbyte-cdk/python/unit_tests/sources/file_based/schema_validation_policies/test_default_schema_validation_policy.py deleted file mode 100644 index a7d2bfb7c019..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/schema_validation_policies/test_default_schema_validation_policy.py +++ /dev/null @@ -1,50 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Mapping - -import pytest -from airbyte_cdk.sources.file_based.config.file_based_stream_config import ValidationPolicy -from airbyte_cdk.sources.file_based.exceptions import StopSyncPerValidationPolicy -from airbyte_cdk.sources.file_based.schema_validation_policies import DEFAULT_SCHEMA_VALIDATION_POLICIES - -CONFORMING_RECORD = { - "col1": "val1", - "col2": 1, -} - -NONCONFORMING_RECORD = { - "col1": "val1", - "extra_col": "x", -} - - -SCHEMA = { - "type": "object", - "properties": { - "col1": {"type": "string"}, - "col2": {"type": "integer"}, - }, -} - - -@pytest.mark.parametrize( - "record,schema,validation_policy,expected_result", - [ - pytest.param(CONFORMING_RECORD, SCHEMA, ValidationPolicy.emit_record, True, id="record-conforms_emit_record"), - pytest.param(NONCONFORMING_RECORD, SCHEMA, ValidationPolicy.emit_record, True, id="nonconforming_emit_record"), - pytest.param(CONFORMING_RECORD, SCHEMA, ValidationPolicy.skip_record, True, id="record-conforms_skip_record"), - pytest.param(NONCONFORMING_RECORD, SCHEMA, ValidationPolicy.skip_record, False, id="nonconforming_skip_record"), - pytest.param(CONFORMING_RECORD, SCHEMA, ValidationPolicy.wait_for_discover, True, id="record-conforms_wait_for_discover"), - pytest.param(NONCONFORMING_RECORD, SCHEMA, ValidationPolicy.wait_for_discover, False, id="nonconforming_wait_for_discover"), - ], -) -def test_record_passes_validation_policy( - record: Mapping[str, Any], schema: Mapping[str, Any], validation_policy: ValidationPolicy, expected_result: bool -) -> None: - if validation_policy == ValidationPolicy.wait_for_discover and expected_result is False: - with pytest.raises(StopSyncPerValidationPolicy): - DEFAULT_SCHEMA_VALIDATION_POLICIES[validation_policy].record_passes_validation_policy(record, schema) - else: - assert DEFAULT_SCHEMA_VALIDATION_POLICIES[validation_policy].record_passes_validation_policy(record, schema) == expected_result diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/stream/__init__.py b/airbyte-cdk/python/unit_tests/sources/file_based/stream/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/stream/concurrent/__init__.py b/airbyte-cdk/python/unit_tests/sources/file_based/stream/concurrent/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/stream/concurrent/test_adapters.py b/airbyte-cdk/python/unit_tests/sources/file_based/stream/concurrent/test_adapters.py deleted file mode 100644 index 9d10ff5e051b..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/stream/concurrent/test_adapters.py +++ /dev/null @@ -1,362 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import logging -import unittest -from datetime import datetime -from unittest.mock import MagicMock, Mock - -import pytest -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, AirbyteStream, Level, SyncMode -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.file_based.availability_strategy import DefaultFileBasedAvailabilityStrategy -from airbyte_cdk.sources.file_based.config.csv_format import CsvFormat -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig -from airbyte_cdk.sources.file_based.discovery_policy import DefaultDiscoveryPolicy -from airbyte_cdk.sources.file_based.exceptions import FileBasedErrorsCollector -from airbyte_cdk.sources.file_based.file_types import default_parsers -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.schema_validation_policies import EmitRecordPolicy -from airbyte_cdk.sources.file_based.stream import DefaultFileBasedStream -from airbyte_cdk.sources.file_based.stream.concurrent.adapters import ( - FileBasedStreamFacade, - FileBasedStreamPartition, - FileBasedStreamPartitionGenerator, -) -from airbyte_cdk.sources.file_based.stream.concurrent.cursor import FileBasedFinalStateCursor -from airbyte_cdk.sources.message import InMemoryMessageRepository -from airbyte_cdk.sources.streams.concurrent.cursor import Cursor -from airbyte_cdk.sources.streams.concurrent.exceptions import ExceptionWithDisplayMessage -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record -from airbyte_cdk.sources.utils.slice_logger import SliceLogger -from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer -from freezegun import freeze_time - -_ANY_SYNC_MODE = SyncMode.full_refresh -_ANY_STATE = {"state_key": "state_value"} -_ANY_CURSOR_FIELD = ["a", "cursor", "key"] -_STREAM_NAME = "stream" -_ANY_CURSOR = Mock(spec=FileBasedFinalStateCursor) - - -@pytest.mark.parametrize( - "sync_mode", - [ - pytest.param(SyncMode.full_refresh, id="test_full_refresh"), - pytest.param(SyncMode.incremental, id="test_incremental"), - ], -) -def test_file_based_stream_partition_generator(sync_mode): - stream = Mock() - message_repository = Mock() - stream_slices = [ - {"files": [RemoteFile(uri="1", last_modified=datetime.now())]}, - {"files": [RemoteFile(uri="2", last_modified=datetime.now())]}, - ] - stream.stream_slices.return_value = stream_slices - - partition_generator = FileBasedStreamPartitionGenerator( - stream, message_repository, _ANY_SYNC_MODE, _ANY_CURSOR_FIELD, _ANY_STATE, _ANY_CURSOR - ) - - partitions = list(partition_generator.generate()) - slices = [partition.to_slice() for partition in partitions] - assert slices == stream_slices - stream.stream_slices.assert_called_once_with(sync_mode=_ANY_SYNC_MODE, cursor_field=_ANY_CURSOR_FIELD, stream_state=_ANY_STATE) - - -@pytest.mark.parametrize( - "transformer, expected_records", - [ - pytest.param( - TypeTransformer(TransformConfig.NoTransform), - [Record({"data": "1"}, Mock(spec=FileBasedStreamPartition, stream_name=Mock(return_value=_STREAM_NAME))), Record({"data": "2"}, Mock(spec=FileBasedStreamPartition, stream_name=Mock(return_value=_STREAM_NAME)))], - id="test_no_transform", - ), - pytest.param( - TypeTransformer(TransformConfig.DefaultSchemaNormalization), - [Record({"data": 1}, Mock(spec=FileBasedStreamPartition, stream_name=Mock(return_value=_STREAM_NAME))), Record({"data": 2}, Mock(spec=FileBasedStreamPartition, stream_name=Mock(return_value=_STREAM_NAME)))], - id="test_default_transform", - ), - ], -) -def test_file_based_stream_partition(transformer, expected_records): - stream = Mock() - stream.name = _STREAM_NAME - stream.get_json_schema.return_value = {"type": "object", "properties": {"data": {"type": ["integer"]}}} - stream.transformer = transformer - message_repository = InMemoryMessageRepository() - _slice = None - sync_mode = SyncMode.full_refresh - cursor_field = None - state = None - partition = FileBasedStreamPartition(stream, _slice, message_repository, sync_mode, cursor_field, state, _ANY_CURSOR) - - a_log_message = AirbyteMessage( - type=MessageType.LOG, - log=AirbyteLogMessage( - level=Level.INFO, - message='slice:{"partition": 1}', - ), - ) - - stream_data = [a_log_message, {"data": "1"}, {"data": "2"}] - stream.read_records.return_value = stream_data - - records = list(partition.read()) - messages = list(message_repository.consume_queue()) - - assert records == expected_records - assert messages == [a_log_message] - - -@pytest.mark.parametrize( - "exception_type, expected_display_message", - [ - pytest.param(Exception, None, id="test_exception_no_display_message"), - pytest.param(ExceptionWithDisplayMessage, "display_message", id="test_exception_no_display_message"), - ], -) -def test_file_based_stream_partition_raising_exception(exception_type, expected_display_message): - stream = Mock() - stream.get_error_display_message.return_value = expected_display_message - - message_repository = InMemoryMessageRepository() - _slice = None - - partition = FileBasedStreamPartition(stream, _slice, message_repository, _ANY_SYNC_MODE, _ANY_CURSOR_FIELD, _ANY_STATE, _ANY_CURSOR) - - stream.read_records.side_effect = Exception() - - with pytest.raises(exception_type) as e: - list(partition.read()) - if isinstance(e, ExceptionWithDisplayMessage): - assert e.display_message == "display message" - - -@freeze_time("2023-06-09T00:00:00Z") -@pytest.mark.parametrize( - "_slice, expected_hash", - [ - pytest.param( - {"files": [RemoteFile(uri="1", last_modified=datetime.strptime("2023-06-09T00:00:00Z", "%Y-%m-%dT%H:%M:%SZ"))]}, - hash(("stream", "2023-06-09T00:00:00.000000Z_1")), - id="test_hash_with_slice", - ), - pytest.param(None, hash("stream"), id="test_hash_no_slice"), - ], -) -def test_file_based_stream_partition_hash(_slice, expected_hash): - stream = Mock() - stream.name = "stream" - partition = FileBasedStreamPartition(stream, _slice, Mock(), _ANY_SYNC_MODE, _ANY_CURSOR_FIELD, _ANY_STATE, _ANY_CURSOR) - - _hash = partition.__hash__() - assert _hash == expected_hash - - -class StreamFacadeTest(unittest.TestCase): - def setUp(self): - self._abstract_stream = Mock() - self._abstract_stream.name = "stream" - self._abstract_stream.as_airbyte_stream.return_value = AirbyteStream( - name="stream", - json_schema={"type": "object"}, - supported_sync_modes=[SyncMode.full_refresh], - ) - self._legacy_stream = DefaultFileBasedStream( - cursor=FileBasedFinalStateCursor(stream_config=MagicMock(), stream_namespace=None, message_repository=Mock()), - config=FileBasedStreamConfig(name="stream", format=CsvFormat()), - catalog_schema={}, - stream_reader=MagicMock(), - availability_strategy=DefaultFileBasedAvailabilityStrategy(MagicMock()), - discovery_policy=DefaultDiscoveryPolicy(), - parsers=default_parsers, - validation_policy=EmitRecordPolicy(), - errors_collector=FileBasedErrorsCollector(), - ) - self._cursor = Mock(spec=Cursor) - self._logger = Mock() - self._slice_logger = Mock() - self._slice_logger.should_log_slice_message.return_value = False - self._facade = FileBasedStreamFacade(self._abstract_stream, self._legacy_stream, self._cursor, self._slice_logger, self._logger) - self._source = Mock() - - self._stream = Mock() - self._stream.primary_key = "id" - - def test_name_is_delegated_to_wrapped_stream(self): - assert self._facade.name == self._abstract_stream.name - - def test_cursor_field_is_a_string(self): - self._abstract_stream.cursor_field = "cursor_field" - assert self._facade.cursor_field == "cursor_field" - - def test_source_defined_cursor_is_true(self): - assert self._facade.source_defined_cursor - - def test_json_schema_is_delegated_to_wrapped_stream(self): - json_schema = {"type": "object"} - self._abstract_stream.get_json_schema.return_value = json_schema - assert self._facade.get_json_schema() == json_schema - self._abstract_stream.get_json_schema.assert_called_once_with() - - def test_given_cursor_is_noop_when_supports_incremental_then_return_legacy_stream_response(self): - assert ( - FileBasedStreamFacade( - self._abstract_stream, self._legacy_stream, _ANY_CURSOR, Mock(spec=SliceLogger), Mock(spec=logging.Logger) - ).supports_incremental - == self._legacy_stream.supports_incremental - ) - - def test_given_cursor_is_not_noop_when_supports_incremental_then_return_true(self): - assert FileBasedStreamFacade( - self._abstract_stream, self._legacy_stream, Mock(spec=Cursor), Mock(spec=SliceLogger), Mock(spec=logging.Logger) - ).supports_incremental - - def test_full_refresh(self): - expected_stream_data = [{"data": 1}, {"data": 2}] - - partition = Mock() - records = [Record(data, partition) for data in expected_stream_data] - partition.read.return_value = records - self._abstract_stream.generate_partitions.return_value = [partition] - - actual_stream_data = list(self._facade.read_records(SyncMode.full_refresh, None, {}, None)) - - assert actual_stream_data == expected_stream_data - - def test_read_records(self): - expected_stream_data = [{"data": 1}, {"data": 2}] - records = [Record(data, "stream") for data in expected_stream_data] - partition = Mock() - partition.read.return_value = records - self._abstract_stream.generate_partitions.return_value = [partition] - - actual_stream_data = list(self._facade.read(None, None, None, None, None, None)) - - assert actual_stream_data == expected_stream_data - - def test_create_from_stream_stream(self): - stream = Mock() - stream.name = "stream" - stream.primary_key = "id" - stream.cursor_field = "cursor" - - facade = FileBasedStreamFacade.create_from_stream(stream, self._source, self._logger, _ANY_STATE, self._cursor) - - assert facade.name == "stream" - assert facade.cursor_field == "cursor" - assert facade._abstract_stream._primary_key == ["id"] - - def test_create_from_stream_stream_with_none_primary_key(self): - stream = Mock() - stream.name = "stream" - stream.primary_key = None - stream.cursor_field = [] - - facade = FileBasedStreamFacade.create_from_stream(stream, self._source, self._logger, _ANY_STATE, self._cursor) - assert facade._abstract_stream._primary_key == [] - - def test_create_from_stream_with_composite_primary_key(self): - stream = Mock() - stream.name = "stream" - stream.primary_key = ["id", "name"] - stream.cursor_field = [] - - facade = FileBasedStreamFacade.create_from_stream(stream, self._source, self._logger, _ANY_STATE, self._cursor) - assert facade._abstract_stream._primary_key == ["id", "name"] - - def test_create_from_stream_with_empty_list_cursor(self): - stream = Mock() - stream.primary_key = "id" - stream.cursor_field = [] - - facade = FileBasedStreamFacade.create_from_stream(stream, self._source, self._logger, _ANY_STATE, self._cursor) - - assert facade.cursor_field == [] - - def test_create_from_stream_raises_exception_if_primary_key_is_nested(self): - stream = Mock() - stream.name = "stream" - stream.primary_key = [["field", "id"]] - - with self.assertRaises(ValueError): - FileBasedStreamFacade.create_from_stream(stream, self._source, self._logger, _ANY_STATE, self._cursor) - - def test_create_from_stream_raises_exception_if_primary_key_has_invalid_type(self): - stream = Mock() - stream.name = "stream" - stream.primary_key = 123 - - with self.assertRaises(ValueError): - FileBasedStreamFacade.create_from_stream(stream, self._source, self._logger, _ANY_STATE, self._cursor) - - def test_create_from_stream_raises_exception_if_cursor_field_is_nested(self): - stream = Mock() - stream.name = "stream" - stream.primary_key = "id" - stream.cursor_field = ["field", "cursor"] - - with self.assertRaises(ValueError): - FileBasedStreamFacade.create_from_stream(stream, self._source, self._logger, _ANY_STATE, self._cursor) - - def test_create_from_stream_with_cursor_field_as_list(self): - stream = Mock() - stream.name = "stream" - stream.primary_key = "id" - stream.cursor_field = ["cursor"] - - facade = FileBasedStreamFacade.create_from_stream(stream, self._source, self._logger, _ANY_STATE, self._cursor) - assert facade.cursor_field == "cursor" - - def test_create_from_stream_none_message_repository(self): - self._stream.name = "stream" - self._stream.primary_key = "id" - self._stream.cursor_field = "cursor" - self._source.message_repository = None - - with self.assertRaises(ValueError): - FileBasedStreamFacade.create_from_stream(self._stream, self._source, self._logger, {}, self._cursor) - - def test_get_error_display_message_no_display_message(self): - self._stream.get_error_display_message.return_value = "display_message" - - facade = FileBasedStreamFacade.create_from_stream(self._stream, self._source, self._logger, _ANY_STATE, self._cursor) - - expected_display_message = None - e = Exception() - - display_message = facade.get_error_display_message(e) - - assert display_message == expected_display_message - - def test_get_error_display_message_with_display_message(self): - self._stream.get_error_display_message.return_value = "display_message" - - facade = FileBasedStreamFacade.create_from_stream(self._stream, self._source, self._logger, _ANY_STATE, self._cursor) - - expected_display_message = "display_message" - e = ExceptionWithDisplayMessage("display_message") - - display_message = facade.get_error_display_message(e) - - assert display_message == expected_display_message - - -@pytest.mark.parametrize( - "exception, expected_display_message", - [ - pytest.param(Exception("message"), None, id="test_no_display_message"), - pytest.param(ExceptionWithDisplayMessage("message"), "message", id="test_no_display_message"), - ], -) -def test_get_error_display_message(exception, expected_display_message): - stream = Mock() - legacy_stream = Mock() - cursor = Mock(spec=Cursor) - facade = FileBasedStreamFacade(stream, legacy_stream, cursor, Mock().Mock(), Mock()) - - display_message = facade.get_error_display_message(exception) - - assert display_message == expected_display_message diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/stream/concurrent/test_file_based_concurrent_cursor.py b/airbyte-cdk/python/unit_tests/sources/file_based/stream/concurrent/test_file_based_concurrent_cursor.py deleted file mode 100644 index 96c907901a38..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/stream/concurrent/test_file_based_concurrent_cursor.py +++ /dev/null @@ -1,455 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - - -from datetime import datetime -from typing import Any, Dict, List, MutableMapping, Optional, Tuple -from unittest.mock import MagicMock - -import pytest -from airbyte_cdk.models import AirbyteStateMessage, SyncMode -from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.stream.concurrent.adapters import FileBasedStreamPartition -from airbyte_cdk.sources.file_based.stream.concurrent.cursor import FileBasedConcurrentCursor -from airbyte_cdk.sources.streams.concurrent.cursor import CursorField -from freezegun import freeze_time - -DATE_TIME_FORMAT = FileBasedConcurrentCursor.DATE_TIME_FORMAT -MOCK_DAYS_TO_SYNC_IF_HISTORY_IS_FULL = 3 - - -def _make_cursor(input_state: Optional[MutableMapping[str, Any]]) -> FileBasedConcurrentCursor: - stream = MagicMock() - stream.name = "test" - stream.namespace = None - stream_config = MagicMock() - stream_config.days_to_sync_if_history_is_full = MOCK_DAYS_TO_SYNC_IF_HISTORY_IS_FULL - cursor = FileBasedConcurrentCursor( - stream_config, - stream.name, - None, - input_state, - MagicMock(), - ConnectorStateManager(state=[AirbyteStateMessage(input_state)] if input_state is not None else None), - CursorField(FileBasedConcurrentCursor.CURSOR_FIELD), - ) - return cursor - - -@pytest.mark.parametrize( - "input_state, expected_cursor_value", - [ - pytest.param({}, (datetime.min, ""), id="no-state-gives-min-cursor"), - pytest.param({"history": {}}, (datetime.min, ""), id="missing-cursor-field-gives-min-cursor"), - pytest.param( - {"history": {"a.csv": "2021-01-01T00:00:00.000000Z"}, "_ab_source_file_last_modified": "2021-01-01T00:00:00.000000Z_a.csv"}, - (datetime.strptime("2021-01-01T00:00:00.000000Z", DATE_TIME_FORMAT), "a.csv"), - id="cursor-value-matches-earliest-file", - ), - pytest.param( - {"history": {"a.csv": "2021-01-01T00:00:00.000000Z"}, "_ab_source_file_last_modified": "2020-01-01T00:00:00.000000Z_a.csv"}, - (datetime.strptime("2020-01-01T00:00:00.000000Z", DATE_TIME_FORMAT), "a.csv"), - id="cursor-value-is-earlier", - ), - pytest.param( - {"history": {"a.csv": "2022-01-01T00:00:00.000000Z"}, "_ab_source_file_last_modified": "2021-01-01T00:00:00.000000Z_a.csv"}, - (datetime.strptime("2021-01-01T00:00:00.000000Z", DATE_TIME_FORMAT), "a.csv"), - id="cursor-value-is-later", - ), - pytest.param( - { - "history": { - "a.csv": "2021-01-01T00:00:00.000000Z", - "b.csv": "2021-01-02T00:00:00.000000Z", - "c.csv": "2021-01-03T00:00:00.000000Z", - }, - "_ab_source_file_last_modified": "2021-01-04T00:00:00.000000Z_d.csv", - }, - (datetime.strptime("2021-01-01T00:00:00.000000Z", DATE_TIME_FORMAT), "a.csv"), - id="cursor-not-earliest", - ), - pytest.param( - {"history": {"b.csv": "2020-12-31T00:00:00.000000Z"}, "_ab_source_file_last_modified": "2021-01-01T00:00:00.000000Z_a.csv"}, - (datetime.strptime("2020-12-31T00:00:00.000000Z", DATE_TIME_FORMAT), "b.csv"), - id="state-with-cursor-and-earlier-history", - ), - pytest.param( - {"history": {"b.csv": "2021-01-02T00:00:00.000000Z"}, "_ab_source_file_last_modified": "2021-01-01T00:00:00.000000Z_a.csv"}, - (datetime.strptime("2021-01-01T00:00:00.000000Z", DATE_TIME_FORMAT), "a.csv"), - id="state-with-cursor-and-later-history", - ), - ], -) -def test_compute_prev_sync_cursor(input_state: MutableMapping[str, Any], expected_cursor_value: Tuple[datetime, str]): - cursor = _make_cursor(input_state) - assert cursor._compute_prev_sync_cursor(input_state) == expected_cursor_value - - -@pytest.mark.parametrize( - "initial_state, pending_files, file_to_add, expected_history, expected_pending_files, expected_cursor_value", - [ - pytest.param( - {"history": {}}, - [("newfile.csv", "2021-01-05T00:00:00.000000Z")], - ("newfile.csv", "2021-01-05T00:00:00.000000Z"), - {"newfile.csv": "2021-01-05T00:00:00.000000Z"}, - [], - "2021-01-05T00:00:00.000000Z_newfile.csv", - id="add-to-empty-history-single-pending-file", - ), - pytest.param( - {"history": {}}, - [("newfile.csv", "2021-01-05T00:00:00.000000Z"), ("pending.csv", "2020-01-05T00:00:00.000000Z")], - ("newfile.csv", "2021-01-05T00:00:00.000000Z"), - {"newfile.csv": "2021-01-05T00:00:00.000000Z"}, - [("pending.csv", "2020-01-05T00:00:00.000000Z")], - "2020-01-05T00:00:00.000000Z_pending.csv", - id="add-to-empty-history-pending-file-is-older", - ), - pytest.param( - {"history": {}}, - [("newfile.csv", "2021-01-05T00:00:00.000000Z"), ("pending.csv", "2022-01-05T00:00:00.000000Z")], - ("newfile.csv", "2021-01-05T00:00:00.000000Z"), - {"newfile.csv": "2021-01-05T00:00:00.000000Z"}, - [("pending.csv", "2022-01-05T00:00:00.000000Z")], - "2022-01-05T00:00:00.000000Z_pending.csv", - id="add-to-empty-history-pending-file-is-newer", - ), - pytest.param( - {"history": {"existing.csv": "2021-01-04T00:00:00.000000Z"}}, - [("newfile.csv", "2021-01-05T00:00:00.000000Z")], - ("newfile.csv", "2021-01-05T00:00:00.000000Z"), - {"existing.csv": "2021-01-04T00:00:00.000000Z", "newfile.csv": "2021-01-05T00:00:00.000000Z"}, - [], - "2021-01-05T00:00:00.000000Z_newfile.csv", - id="add-to-nonempty-history-single-pending-file", - ), - pytest.param( - {"history": {"existing.csv": "2021-01-04T00:00:00.000000Z"}}, - [("newfile.csv", "2021-01-05T00:00:00.000000Z"), ("pending.csv", "2020-01-05T00:00:00.000000Z")], - ("newfile.csv", "2021-01-05T00:00:00.000000Z"), - {"existing.csv": "2021-01-04T00:00:00.000000Z", "newfile.csv": "2021-01-05T00:00:00.000000Z"}, - [("pending.csv", "2020-01-05T00:00:00.000000Z")], - "2020-01-05T00:00:00.000000Z_pending.csv", - id="add-to-nonempty-history-pending-file-is-older", - ), - pytest.param( - {"history": {"existing.csv": "2021-01-04T00:00:00.000000Z"}}, - [("newfile.csv", "2021-01-05T00:00:00.000000Z"), ("pending.csv", "2022-01-05T00:00:00.000000Z")], - ("newfile.csv", "2021-01-05T00:00:00.000000Z"), - {"existing.csv": "2021-01-04T00:00:00.000000Z", "newfile.csv": "2021-01-05T00:00:00.000000Z"}, - [("pending.csv", "2022-01-05T00:00:00.000000Z")], - "2022-01-05T00:00:00.000000Z_pending.csv", - id="add-to-nonempty-history-pending-file-is-newer", - ), - ], -) -def test_add_file( - initial_state: MutableMapping[str, Any], - pending_files: List[Tuple[str, str]], - file_to_add: Tuple[str, str], - expected_history: Dict[str, Any], - expected_pending_files: List[Tuple[str, str]], - expected_cursor_value: str, -): - cursor = _make_cursor(initial_state) - mock_message_repository = MagicMock() - cursor._message_repository = mock_message_repository - stream = MagicMock() - - cursor.set_pending_partitions( - [ - FileBasedStreamPartition( - stream, - {"files": [RemoteFile(uri=uri, last_modified=datetime.strptime(timestamp, DATE_TIME_FORMAT))]}, - mock_message_repository, - SyncMode.full_refresh, - FileBasedConcurrentCursor.CURSOR_FIELD, - initial_state, - cursor, - ) - for uri, timestamp in pending_files - ] - ) - - uri, timestamp = file_to_add - cursor.add_file(RemoteFile(uri=uri, last_modified=datetime.strptime(timestamp, DATE_TIME_FORMAT))) - assert cursor._file_to_datetime_history == expected_history - assert cursor._pending_files == { - uri: RemoteFile(uri=uri, last_modified=datetime.strptime(timestamp, DATE_TIME_FORMAT)) for uri, timestamp in expected_pending_files - } - assert ( - mock_message_repository.emit_message.call_args_list[0].args[0].state.stream.stream_state._ab_source_file_last_modified - == expected_cursor_value - ) - - -@pytest.mark.parametrize( - "initial_state, pending_files, file_to_add, expected_history, expected_pending_files, expected_cursor_value", - [ - pytest.param( - {"history": {}}, - [], - ("newfile.csv", "2021-01-05T00:00:00.000000Z"), - {"newfile.csv": "2021-01-05T00:00:00.000000Z"}, - [], - "2021-01-05T00:00:00.000000Z_newfile.csv", - id="add-to-empty-history-no-pending-files", - ), - pytest.param( - {"history": {}}, - [("pending.csv", "2021-01-05T00:00:00.000000Z")], - ("newfile.csv", "2021-01-05T00:00:00.000000Z"), - {"newfile.csv": "2021-01-05T00:00:00.000000Z"}, - [("pending.csv", "2021-01-05T00:00:00.000000Z")], - "2021-01-05T00:00:00.000000Z_pending.csv", - id="add-to-empty-history-file-not-in-pending-files", - ), - ], -) -def test_add_file_invalid( - initial_state: MutableMapping[str, Any], - pending_files: List[Tuple[str, str]], - file_to_add: Tuple[str, str], - expected_history: Dict[str, Any], - expected_pending_files: List[Tuple[str, str]], - expected_cursor_value: str, -): - cursor = _make_cursor(initial_state) - cursor._pending_files = { - uri: RemoteFile(uri=uri, last_modified=datetime.strptime(timestamp, DATE_TIME_FORMAT)) for uri, timestamp in pending_files - } - mock_message_repository = MagicMock() - cursor._message_repository = mock_message_repository - - uri, timestamp = file_to_add - cursor.add_file(RemoteFile(uri=uri, last_modified=datetime.strptime(timestamp, DATE_TIME_FORMAT))) - assert cursor._file_to_datetime_history == expected_history - assert cursor._pending_files == { - uri: RemoteFile(uri=uri, last_modified=datetime.strptime(timestamp, DATE_TIME_FORMAT)) for uri, timestamp in expected_pending_files - } - assert mock_message_repository.emit_message.call_args_list[0].args[0].log.level.value == "WARN" - assert ( - mock_message_repository.emit_message.call_args_list[1].args[0].state.stream.stream_state._ab_source_file_last_modified - == expected_cursor_value - ) - - -@pytest.mark.parametrize( - "input_state, pending_files, expected_cursor_value", - [ - pytest.param({}, [], f"{datetime.min.strftime('%Y-%m-%dT%H:%M:%S.%fZ')}_", id="no-state-no-pending"), - pytest.param( - {"history": {"a.csv": "2021-01-01T00:00:00.000000Z"}}, [], "2021-01-01T00:00:00.000000Z_a.csv", id="no-pending-with-history" - ), - pytest.param( - {"history": {}}, [("b.csv", "2021-01-02T00:00:00.000000Z")], "2021-01-02T00:00:00.000000Z_b.csv", id="pending-no-history" - ), - pytest.param( - {"history": {"a.csv": "2022-01-01T00:00:00.000000Z"}}, - [("b.csv", "2021-01-02T00:00:00.000000Z")], - "2021-01-01T00:00:00.000000Z_a.csv", - id="with-pending-before-history", - ), - pytest.param( - {"history": {"a.csv": "2021-01-01T00:00:00.000000Z"}}, - [("b.csv", "2022-01-02T00:00:00.000000Z")], - "2022-01-01T00:00:00.000000Z_a.csv", - id="with-pending-after-history", - ), - ], -) -def test_get_new_cursor_value(input_state: MutableMapping[str, Any], pending_files: List[Tuple[str, str]], expected_cursor_value: str): - cursor = _make_cursor(input_state) - pending_partitions = [] - for url, timestamp in pending_files: - partition = MagicMock() - partition.to_slice = lambda *args, **kwargs: { - "files": [RemoteFile(uri=url, last_modified=datetime.strptime(timestamp, DATE_TIME_FORMAT))] - } - pending_partitions.append(partition) - - cursor.set_pending_partitions(pending_partitions) - - -@pytest.mark.parametrize( - "all_files, history, is_history_full, prev_cursor_value, expected_files_to_sync", - [ - pytest.param( - [RemoteFile(uri="new.csv", last_modified=datetime.strptime("2021-01-03T00:00:00.000000Z", "%Y-%m-%dT%H:%M:%S.%fZ"))], - {}, - False, - (datetime.min, ""), - ["new.csv"], - id="empty-history-one-new-file", - ), - pytest.param( - [RemoteFile(uri="a.csv", last_modified=datetime.strptime("2021-01-02T00:00:00.000000Z", "%Y-%m-%dT%H:%M:%S.%fZ"))], - {"a.csv": "2021-01-01T00:00:00.000000Z"}, - False, - (datetime.min, ""), - ["a.csv"], - id="non-empty-history-file-in-history-modified", - ), - pytest.param( - [RemoteFile(uri="a.csv", last_modified=datetime.strptime("2021-01-01T00:00:00.000000Z", "%Y-%m-%dT%H:%M:%S.%fZ"))], - {"a.csv": "2021-01-01T00:00:00.000000Z"}, - False, - (datetime.min, ""), - [], - id="non-empty-history-file-in-history-not-modified", - ), - ], -) -def test_get_files_to_sync(all_files, history, is_history_full, prev_cursor_value, expected_files_to_sync): - cursor = _make_cursor({}) - cursor._file_to_datetime_history = history - cursor._prev_cursor_value = prev_cursor_value - cursor._is_history_full = MagicMock(return_value=is_history_full) - files_to_sync = list(cursor.get_files_to_sync(all_files, MagicMock())) - assert [f.uri for f in files_to_sync] == expected_files_to_sync - - -@freeze_time("2023-06-16T00:00:00Z") -@pytest.mark.parametrize( - "file_to_check, history, is_history_full, prev_cursor_value, sync_start, expected_should_sync", - [ - pytest.param( - RemoteFile(uri="new.csv", last_modified=datetime.strptime("2021-01-03T00:00:00.000000Z", DATE_TIME_FORMAT)), - {}, - False, - (datetime.min, ""), - datetime.min, - True, - id="file-not-in-history-not-full-old-cursor", - ), - pytest.param( - RemoteFile(uri="new.csv", last_modified=datetime.strptime("2021-01-03T00:00:00.000000Z", DATE_TIME_FORMAT)), - {}, - False, - (datetime.strptime("2024-01-02T00:00:00.000000Z", DATE_TIME_FORMAT), ""), - datetime.min, - True, - id="file-not-in-history-not-full-new-cursor", - ), - pytest.param( - RemoteFile(uri="a.csv", last_modified=datetime.strptime("2021-01-01T00:00:00.000000Z", DATE_TIME_FORMAT)), - {"a.csv": "2021-01-01T00:00:00.000000Z"}, - False, - (datetime.min, ""), - datetime.min, - False, - id="file-in-history-not-modified", - ), - pytest.param( - RemoteFile(uri="a.csv", last_modified=datetime.strptime("2020-01-01T00:00:00.000000Z", DATE_TIME_FORMAT)), - {"a.csv": "2021-01-01T00:00:00.000000Z"}, - False, - (datetime.min, ""), - datetime.min, - False, - id="file-in-history-modified-before", - ), - pytest.param( - RemoteFile(uri="a.csv", last_modified=datetime.strptime("2022-01-01T00:00:00.000000Z", DATE_TIME_FORMAT)), - {"a.csv": "2021-01-01T00:00:00.000000Z"}, - False, - (datetime.min, ""), - datetime.min, - True, - id="file-in-history-modified-after", - ), - pytest.param( - RemoteFile(uri="new.csv", last_modified=datetime.strptime("2022-01-01T00:00:00.000000Z", DATE_TIME_FORMAT)), - {}, - True, - (datetime.strptime("2021-01-02T00:00:00.000000Z", DATE_TIME_FORMAT), "a.csv"), - datetime.min, - True, - id="history-full-file-modified-after-cursor", - ), - pytest.param( - RemoteFile(uri="new1.csv", last_modified=datetime.strptime("2021-01-01T00:00:00.000000Z", DATE_TIME_FORMAT)), - {}, - True, - (datetime.strptime("2021-01-01T00:00:00.000000Z", DATE_TIME_FORMAT), "new0.csv"), - datetime.min, - True, - id="history-full-modified-eq-cursor-uri-gt", - ), - pytest.param( - RemoteFile(uri="new0.csv", last_modified=datetime.strptime("2021-01-01T00:00:00.000000Z", DATE_TIME_FORMAT)), - {}, - True, - (datetime.strptime("2021-01-01T00:00:00.000000Z", DATE_TIME_FORMAT), "new1.csv"), - datetime.min, - False, - id="history-full-modified-eq-cursor-uri-lt", - ), - pytest.param( - RemoteFile(uri="new.csv", last_modified=datetime.strptime("2020-01-01T00:00:00.000000Z", DATE_TIME_FORMAT)), - {}, - True, - (datetime.strptime("2021-01-01T00:00:00.000000Z", DATE_TIME_FORMAT), "a.csv"), - datetime.min, - True, - id="history-full-modified-before-cursor-and-after-sync-start", - ), - pytest.param( - RemoteFile(uri="new.csv", last_modified=datetime.strptime("2021-01-01T00:00:00.000000Z", DATE_TIME_FORMAT)), - {}, - True, - (datetime.strptime("2022-01-01T00:00:00.000000Z", DATE_TIME_FORMAT), "a.csv"), - datetime.strptime("2024-01-01T00:00:00.000000Z", DATE_TIME_FORMAT), - False, - id="history-full-modified-before-cursor-and-before-sync-start", - ), - ], -) -def test_should_sync_file( - file_to_check: RemoteFile, - history: Dict[str, Any], - is_history_full: bool, - prev_cursor_value: Tuple[datetime, str], - sync_start: datetime, - expected_should_sync: bool, -): - cursor = _make_cursor({}) - cursor._file_to_datetime_history = history - cursor._prev_cursor_value = prev_cursor_value - cursor._sync_start = sync_start - cursor._is_history_full = MagicMock(return_value=is_history_full) - should_sync = cursor._should_sync_file(file_to_check, MagicMock()) - assert should_sync == expected_should_sync - - -@freeze_time("2023-06-16T00:00:00Z") -@pytest.mark.parametrize( - "input_history, is_history_full, expected_start_time", - [ - pytest.param({}, False, datetime.min, id="empty-history"), - pytest.param( - {"a.csv": "2021-01-01T00:00:00.000000Z"}, - False, - datetime.strptime("2021-01-01T00:00:00.000000Z", DATE_TIME_FORMAT), - id="non-full-history", - ), - pytest.param( - {f"file{i}.csv": f"2021-01-0{i}T00:00:00.000000Z" for i in range(1, 4)}, # all before the time window - True, - datetime.strptime("2021-01-01T00:00:00.000000Z", DATE_TIME_FORMAT), # Time window start time - id="full-history-earliest-before-window", - ), - pytest.param( - {f"file{i}.csv": f"2024-01-0{i}T00:00:00.000000Z" for i in range(1, 4)}, # all after the time window - True, - datetime.strptime("2023-06-13T00:00:00.000000Z", DATE_TIME_FORMAT), # Earliest file time - id="full-history-earliest-after-window", - ), - ], -) -def test_compute_start_time(input_history, is_history_full, expected_start_time, monkeypatch): - cursor = _make_cursor({"history": input_history}) - cursor._file_to_datetime_history = input_history - cursor._is_history_full = MagicMock(return_value=is_history_full) - assert cursor._compute_start_time() == expected_start_time diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/stream/test_default_file_based_cursor.py b/airbyte-cdk/python/unit_tests/sources/file_based/stream/test_default_file_based_cursor.py deleted file mode 100644 index 957ed912aa4b..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/stream/test_default_file_based_cursor.py +++ /dev/null @@ -1,310 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from datetime import datetime, timedelta -from typing import Any, List, Mapping -from unittest.mock import MagicMock - -import pytest -from airbyte_cdk.sources.file_based.config.csv_format import CsvFormat -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig, ValidationPolicy -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.stream.cursor.default_file_based_cursor import DefaultFileBasedCursor -from freezegun import freeze_time - - -@pytest.mark.parametrize( - "files_to_add, expected_start_time, expected_state_dict", - [ - pytest.param( - [ - RemoteFile( - uri="a.csv", last_modified=datetime.strptime("2021-01-01T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - RemoteFile( - uri="b.csv", last_modified=datetime.strptime("2021-01-02T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - RemoteFile( - uri="c.csv", last_modified=datetime.strptime("2020-12-31T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - ], - [datetime(2021, 1, 1), datetime(2021, 1, 1), datetime(2020, 12, 31)], - { - "history": { - "a.csv": "2021-01-01T00:00:00.000000Z", - "b.csv": "2021-01-02T00:00:00.000000Z", - "c.csv": "2020-12-31T00:00:00.000000Z", - }, - "_ab_source_file_last_modified": "2021-01-02T00:00:00.000000Z_b.csv", - }, - id="test_file_start_time_is_earliest_time_in_history", - ), - pytest.param( - [ - RemoteFile( - uri="a.csv", last_modified=datetime.strptime("2021-01-01T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - RemoteFile( - uri="b.csv", last_modified=datetime.strptime("2021-01-02T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - RemoteFile( - uri="c.csv", last_modified=datetime.strptime("2021-01-03T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - RemoteFile( - uri="d.csv", last_modified=datetime.strptime("2021-01-04T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - ], - [datetime(2021, 1, 1), datetime(2021, 1, 1), datetime(2021, 1, 1), datetime(2021, 1, 2)], - { - "history": { - "b.csv": "2021-01-02T00:00:00.000000Z", - "c.csv": "2021-01-03T00:00:00.000000Z", - "d.csv": "2021-01-04T00:00:00.000000Z", - }, - "_ab_source_file_last_modified": "2021-01-04T00:00:00.000000Z_d.csv", - }, - id="test_earliest_file_is_removed_from_history_if_history_is_full", - ), - pytest.param( - [ - RemoteFile( - uri="a.csv", last_modified=datetime.strptime("2021-01-01T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - RemoteFile( - uri="file_with_same_timestamp_as_b.csv", - last_modified=datetime.strptime("2021-01-02T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), - file_type="csv", - ), - RemoteFile( - uri="b.csv", last_modified=datetime.strptime("2021-01-02T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - RemoteFile( - uri="c.csv", last_modified=datetime.strptime("2021-01-03T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - RemoteFile( - uri="d.csv", last_modified=datetime.strptime("2021-01-04T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - ], - [ - datetime(2021, 1, 1), - datetime(2021, 1, 1), - datetime(2021, 1, 1), - datetime(2021, 1, 2), - datetime(2021, 1, 2), - ], - { - "history": { - "file_with_same_timestamp_as_b.csv": "2021-01-02T00:00:00.000000Z", - "c.csv": "2021-01-03T00:00:00.000000Z", - "d.csv": "2021-01-04T00:00:00.000000Z", - }, - "_ab_source_file_last_modified": "2021-01-04T00:00:00.000000Z_d.csv", - }, - id="test_files_are_sorted_by_timestamp_and_by_name", - ), - ], -) -def test_add_file(files_to_add: List[RemoteFile], expected_start_time: List[datetime], expected_state_dict: Mapping[str, Any]) -> None: - cursor = get_cursor(max_history_size=3, days_to_sync_if_history_is_full=3) - assert cursor._compute_start_time() == datetime.min - - for index, f in enumerate(files_to_add): - cursor.add_file(f) - assert cursor._compute_start_time() == expected_start_time[index] - assert cursor.get_state() == expected_state_dict - - -@pytest.mark.parametrize( - "files, expected_files_to_sync, max_history_size, history_is_partial", - [ - pytest.param( - [ - RemoteFile( - uri="a.csv", last_modified=datetime.strptime("2021-01-01T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - RemoteFile( - uri="b.csv", last_modified=datetime.strptime("2021-01-02T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - RemoteFile( - uri="c.csv", last_modified=datetime.strptime("2020-12-31T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - ], - [ - RemoteFile( - uri="a.csv", last_modified=datetime.strptime("2021-01-01T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - RemoteFile( - uri="b.csv", last_modified=datetime.strptime("2021-01-02T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - RemoteFile( - uri="c.csv", last_modified=datetime.strptime("2020-12-31T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - ], - 3, - True, - id="test_all_files_should_be_synced", - ), - pytest.param( - [ - RemoteFile( - uri="a.csv", last_modified=datetime.strptime("2021-01-01T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - RemoteFile( - uri="b.csv", last_modified=datetime.strptime("2021-01-02T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - RemoteFile( - uri="c.csv", last_modified=datetime.strptime("2020-12-31T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - ], - [ - RemoteFile( - uri="a.csv", last_modified=datetime.strptime("2021-01-01T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - RemoteFile( - uri="b.csv", last_modified=datetime.strptime("2021-01-02T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - RemoteFile( - uri="c.csv", last_modified=datetime.strptime("2020-12-31T00:00:00.000Z", "%Y-%m-%dT%H:%M:%S.%fZ"), file_type="csv" - ), - ], - 2, - True, - id="test_sync_more_files_than_history_size", - ), - ], -) -def test_get_files_to_sync( - files: List[RemoteFile], expected_files_to_sync: List[RemoteFile], max_history_size: int, history_is_partial: bool -) -> None: - logger = MagicMock() - cursor = get_cursor(max_history_size, 3) - - files_to_sync = list(cursor.get_files_to_sync(files, logger)) - for f in files_to_sync: - cursor.add_file(f) - - assert files_to_sync == expected_files_to_sync - assert cursor._is_history_full() == history_is_partial - - -@freeze_time("2023-06-16T00:00:00Z") -def test_only_recent_files_are_synced_if_history_is_full() -> None: - logger = MagicMock() - cursor = get_cursor(2, 3) - - files_in_history = [ - RemoteFile(uri="b1.csv", last_modified=datetime(2021, 1, 2), file_type="csv"), - RemoteFile(uri="b2.csv", last_modified=datetime(2021, 1, 3), file_type="csv"), - ] - - state = { - "history": {f.uri: f.last_modified.strftime(DefaultFileBasedCursor.DATE_TIME_FORMAT) for f in files_in_history}, - } - cursor.set_initial_state(state) - - files = [ - RemoteFile(uri="a.csv", last_modified=datetime(2021, 1, 1), file_type="csv"), - RemoteFile(uri="c.csv", last_modified=datetime(2021, 1, 2), file_type="csv"), - RemoteFile(uri="d.csv", last_modified=datetime(2021, 1, 4), file_type="csv"), - ] - - expected_files_to_sync = [ - RemoteFile(uri="c.csv", last_modified=datetime(2021, 1, 2), file_type="csv"), - RemoteFile(uri="d.csv", last_modified=datetime(2021, 1, 4), file_type="csv"), - ] - - files_to_sync = list(cursor.get_files_to_sync(files, logger)) - assert files_to_sync == expected_files_to_sync - logger.warning.assert_called_once() - - -@pytest.mark.parametrize( - "modified_at_delta, should_sync_file", - [ - pytest.param(timedelta(days=-1), False, id="test_modified_at_is_earlier"), - pytest.param(timedelta(days=0), False, id="test_modified_at_is_equal"), - pytest.param(timedelta(days=1), True, id="test_modified_at_is_more_recent"), - ], -) -def test_sync_file_already_present_in_history(modified_at_delta: timedelta, should_sync_file: bool) -> None: - logger = MagicMock() - cursor = get_cursor(2, 3) - original_modified_at = datetime(2021, 1, 2) - filename = "a.csv" - files_in_history = [ - RemoteFile(uri=filename, last_modified=original_modified_at, file_type="csv"), - ] - - state = { - "history": {f.uri: f.last_modified.strftime(DefaultFileBasedCursor.DATE_TIME_FORMAT) for f in files_in_history}, - } - cursor.set_initial_state(state) - - files = [ - RemoteFile(uri=filename, last_modified=original_modified_at + modified_at_delta, file_type="csv"), - ] - - files_to_sync = list(cursor.get_files_to_sync(files, logger)) - assert bool(files_to_sync) == should_sync_file - - -@freeze_time("2023-06-06T00:00:00Z") -@pytest.mark.parametrize( - "file_name, last_modified, earliest_dt_in_history, should_sync_file", - [ - pytest.param("a.csv", datetime(2023, 6, 3), datetime(2023, 6, 6), True, id="test_last_modified_is_equal_to_time_buffer"), - pytest.param("b.csv", datetime(2023, 6, 6), datetime(2023, 6, 6), False, id="test_file_was_already_synced"), - pytest.param("b.csv", datetime(2023, 6, 7), datetime(2023, 6, 6), True, id="test_file_was_synced_in_the_past"), - pytest.param( - "b.csv", - datetime(2023, 6, 3), - datetime(2023, 6, 6), - False, - id="test_file_was_synced_in_the_past_but_last_modified_is_earlier_in_history", - ), - pytest.param( - "a.csv", - datetime(2023, 6, 3), - datetime(2023, 6, 3), - False, - id="test_last_modified_is_equal_to_earliest_dt_in_history_and_lexicographically_smaller", - ), - pytest.param( - "c.csv", - datetime(2023, 6, 3), - datetime(2023, 6, 3), - True, - id="test_last_modified_is_equal_to_earliest_dt_in_history_and_lexicographically_greater", - ), - ], -) -def test_should_sync_file(file_name: str, last_modified: datetime, earliest_dt_in_history: datetime, should_sync_file: bool) -> None: - logger = MagicMock() - cursor = get_cursor(1, 3) - - cursor.add_file(RemoteFile(uri="b.csv", last_modified=earliest_dt_in_history, file_type="csv")) - cursor._start_time = cursor._compute_start_time() - cursor._initial_earliest_file_in_history = cursor._compute_earliest_file_in_history() - - assert ( - bool(list(cursor.get_files_to_sync([RemoteFile(uri=file_name, last_modified=last_modified, file_type="csv")], logger))) - == should_sync_file - ) - - -def test_set_initial_state_no_history() -> None: - cursor = get_cursor(1, 3) - cursor.set_initial_state({}) - - -def get_cursor(max_history_size: int, days_to_sync_if_history_is_full: int) -> DefaultFileBasedCursor: - cursor_cls = DefaultFileBasedCursor - cursor_cls.DEFAULT_MAX_HISTORY_SIZE = max_history_size - config = FileBasedStreamConfig( - format=CsvFormat(), - name="test", - validation_policy=ValidationPolicy.emit_record, - days_to_sync_if_history_is_full=days_to_sync_if_history_is_full, - ) - return cursor_cls(config) diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/stream/test_default_file_based_stream.py b/airbyte-cdk/python/unit_tests/sources/file_based/stream/test_default_file_based_stream.py deleted file mode 100644 index ae2b87d24b27..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/stream/test_default_file_based_stream.py +++ /dev/null @@ -1,252 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import traceback -import unittest -from datetime import datetime, timezone -from typing import Any, Iterable, Iterator, Mapping -from unittest.mock import Mock - -import pytest -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, Level -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.file_based.availability_strategy import AbstractFileBasedAvailabilityStrategy -from airbyte_cdk.sources.file_based.discovery_policy import AbstractDiscoveryPolicy -from airbyte_cdk.sources.file_based.exceptions import FileBasedErrorsCollector, FileBasedSourceError -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader -from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.schema_validation_policies import AbstractSchemaValidationPolicy -from airbyte_cdk.sources.file_based.stream.cursor import AbstractFileBasedCursor -from airbyte_cdk.sources.file_based.stream.default_file_based_stream import DefaultFileBasedStream -from airbyte_cdk.utils.traced_exception import AirbyteTracedException - - -class MockFormat: - pass - - -@pytest.mark.parametrize( - "input_schema, expected_output", - [ - pytest.param({}, {}, id="empty-schema"), - pytest.param( - {"type": "string"}, - {"type": ["null", "string"]}, - id="simple-schema", - ), - pytest.param( - {"type": ["string"]}, - {"type": ["null", "string"]}, - id="simple-schema-list-type", - ), - pytest.param( - {"type": ["null", "string"]}, - {"type": ["null", "string"]}, - id="simple-schema-already-has-null", - ), - pytest.param( - {"properties": {"type": "string"}}, - {"properties": {"type": ["null", "string"]}}, - id="nested-schema", - ), - pytest.param( - {"items": {"type": "string"}}, - {"items": {"type": ["null", "string"]}}, - id="array-schema", - ), - pytest.param( - {"type": "object", "properties": {"prop": {"type": "string"}}}, - { - "type": ["null", "object"], - "properties": {"prop": {"type": ["null", "string"]}}, - }, - id="deeply-nested-schema", - ), - ], -) -def test_fill_nulls(input_schema: Mapping[str, Any], expected_output: Mapping[str, Any]) -> None: - assert DefaultFileBasedStream._fill_nulls(input_schema) == expected_output - - -class DefaultFileBasedStreamTest(unittest.TestCase): - _NOW = datetime(2022, 10, 22, tzinfo=timezone.utc) - _A_RECORD = {"a_record": 1} - - def setUp(self) -> None: - self._stream_config = Mock() - self._stream_config.format = MockFormat() - self._stream_config.name = "a stream name" - self._catalog_schema = Mock() - self._stream_reader = Mock(spec=AbstractFileBasedStreamReader) - self._availability_strategy = Mock(spec=AbstractFileBasedAvailabilityStrategy) - self._discovery_policy = Mock(spec=AbstractDiscoveryPolicy) - self._parser = Mock(spec=FileTypeParser) - self._validation_policy = Mock(spec=AbstractSchemaValidationPolicy) - self._validation_policy.name = "validation policy name" - self._cursor = Mock(spec=AbstractFileBasedCursor) - - self._stream = DefaultFileBasedStream( - config=self._stream_config, - catalog_schema=self._catalog_schema, - stream_reader=self._stream_reader, - availability_strategy=self._availability_strategy, - discovery_policy=self._discovery_policy, - parsers={MockFormat: self._parser}, - validation_policy=self._validation_policy, - cursor=self._cursor, - errors_collector=FileBasedErrorsCollector(), - ) - - def test_when_read_records_from_slice_then_return_records(self) -> None: - self._parser.parse_records.return_value = [self._A_RECORD] - messages = list(self._stream.read_records_from_slice({"files": [RemoteFile(uri="uri", last_modified=self._NOW)]})) - assert list(map(lambda message: message.record.data["data"], messages)) == [self._A_RECORD] - - def test_when_transform_record_then_return_updated_record(self) -> None: - file = RemoteFile(uri="uri", last_modified=self._NOW) - last_updated = self._NOW.isoformat() - transformed_record = self._stream.transform_record(self._A_RECORD, file, last_updated) - assert transformed_record[self._stream.ab_last_mod_col] == last_updated - assert transformed_record[self._stream.ab_file_name_col] == file.uri - - def test_given_exception_when_read_records_from_slice_then_do_process_other_files( - self, - ) -> None: - """ - The current behavior for source-s3 v3 does not fail sync on some errors and hence, we will keep this behaviour for now. One example - we can easily reproduce this is by having a file with gzip extension that is not actually a gzip file. The reader will fail to open - the file but the sync won't fail. - Ticket: https://github.com/airbytehq/airbyte/issues/29680 - """ - self._parser.parse_records.side_effect = [ - ValueError("An error"), - [self._A_RECORD], - ] - - messages = list( - self._stream.read_records_from_slice( - { - "files": [ - RemoteFile(uri="invalid_file", last_modified=self._NOW), - RemoteFile(uri="valid_file", last_modified=self._NOW), - ] - } - ) - ) - - assert messages[0].log.level == Level.ERROR - assert messages[1].record.data["data"] == self._A_RECORD - - def test_given_traced_exception_when_read_records_from_slice_then_fail( - self, - ) -> None: - """ - When a traced exception is raised, the stream shouldn't try to handle but pass it on to the caller. - """ - self._parser.parse_records.side_effect = [AirbyteTracedException("An error")] - - with pytest.raises(AirbyteTracedException): - list( - self._stream.read_records_from_slice( - { - "files": [ - RemoteFile(uri="invalid_file", last_modified=self._NOW), - RemoteFile(uri="valid_file", last_modified=self._NOW), - ] - } - ) - ) - - def test_given_exception_after_skipping_records_when_read_records_from_slice_then_send_warning( - self, - ) -> None: - self._stream_config.schemaless = False - self._validation_policy.record_passes_validation_policy.return_value = False - self._parser.parse_records.side_effect = [self._iter([self._A_RECORD, ValueError("An error")])] - - messages = list( - self._stream.read_records_from_slice( - { - "files": [ - RemoteFile(uri="invalid_file", last_modified=self._NOW), - RemoteFile(uri="valid_file", last_modified=self._NOW), - ] - } - ) - ) - - assert messages[0].log.level == Level.ERROR - assert messages[1].log.level == Level.WARN - - def test_override_max_n_files_for_schema_inference_is_respected(self) -> None: - self._discovery_policy.n_concurrent_requests = 1 - self._discovery_policy.get_max_n_files_for_schema_inference.return_value = 3 - self._stream.config.input_schema = None - self._stream.config.schemaless = None - self._parser.infer_schema.return_value = {"data": {"type": "string"}} - files = [RemoteFile(uri=f"file{i}", last_modified=self._NOW) for i in range(10)] - self._stream_reader.get_matching_files.return_value = files - self._stream.config.recent_n_files_to_read_for_schema_discovery = 3 - - schema = self._stream.get_json_schema() - - assert schema == { - "type": "object", - "properties": { - "_ab_source_file_last_modified": {"type": "string"}, - "_ab_source_file_url": {"type": "string"}, - "data": {"type": ["null", "string"]}, - }, - } - assert self._parser.infer_schema.call_count == 3 - - def _iter(self, x: Iterable[Any]) -> Iterator[Any]: - for item in x: - if isinstance(item, Exception): - raise item - yield item - - -class TestFileBasedErrorCollector: - test_error_collector: FileBasedErrorsCollector = FileBasedErrorsCollector() - - @pytest.mark.parametrize( - "stream, file, line_no, n_skipped, collector_expected_len", - ( - ("stream_1", "test.csv", 1, 1, 1), - ("stream_2", "test2.csv", 2, 2, 2), - ), - ids=[ - "Single error", - "Multiple errors", - ], - ) - def test_collect_parsing_error(self, stream, file, line_no, n_skipped, collector_expected_len) -> None: - test_error_pattern = "Error parsing record." - # format the error body - test_error = ( - AirbyteMessage( - type=MessageType.LOG, - log=AirbyteLogMessage( - level=Level.ERROR, - message=f"{FileBasedSourceError.ERROR_PARSING_RECORD.value} stream={stream} file={file} line_no={line_no} n_skipped={n_skipped}", - stack_trace=traceback.format_exc(), - ), - ), - ) - # collecting the error - self.test_error_collector.collect(test_error) - # check the error has been collected - assert len(self.test_error_collector.errors) == collector_expected_len - # check for the patern presence for the collected errors - for error in self.test_error_collector.errors: - assert test_error_pattern in error[0].log.message - - def test_yield_and_raise_collected(self) -> None: - # we expect the following method will raise the AirbyteTracedException - with pytest.raises(AirbyteTracedException) as parse_error: - list(self.test_error_collector.yield_and_raise_collected()) - assert parse_error.value.message == "Some errors occured while reading from the source." - assert parse_error.value.internal_message == "Please check the logged errors for more information." diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/test_file_based_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/test_file_based_scenarios.py deleted file mode 100644 index 247a9f349a13..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/test_file_based_scenarios.py +++ /dev/null @@ -1,336 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from pathlib import PosixPath - -import pytest -from _pytest.capture import CaptureFixture -from airbyte_cdk.sources.abstract_source import AbstractSource -from freezegun import freeze_time -from unit_tests.sources.file_based.scenarios.avro_scenarios import ( - avro_all_types_scenario, - avro_file_with_double_as_number_scenario, - multiple_avro_combine_schema_scenario, - multiple_streams_avro_scenario, - single_avro_scenario, -) -from unit_tests.sources.file_based.scenarios.check_scenarios import ( - error_empty_stream_scenario, - error_listing_files_scenario, - error_multi_stream_scenario, - error_reading_file_scenario, - error_record_validation_user_provided_schema_scenario, - success_csv_scenario, - success_extensionless_scenario, - success_multi_stream_scenario, - success_user_provided_schema_scenario, -) -from unit_tests.sources.file_based.scenarios.concurrent_incremental_scenarios import ( - multi_csv_different_timestamps_scenario_concurrent, - multi_csv_include_missing_files_within_history_range_concurrent_cursor_is_newer, - multi_csv_include_missing_files_within_history_range_concurrent_cursor_is_older, - multi_csv_per_timestamp_scenario_concurrent, - multi_csv_remove_old_files_if_history_is_full_scenario_concurrent_cursor_is_newer, - multi_csv_remove_old_files_if_history_is_full_scenario_concurrent_cursor_is_older, - multi_csv_same_timestamp_more_files_than_history_size_scenario_concurrent_cursor_is_newer, - multi_csv_same_timestamp_more_files_than_history_size_scenario_concurrent_cursor_is_older, - multi_csv_same_timestamp_scenario_concurrent, - multi_csv_skip_file_if_already_in_history_concurrent, - multi_csv_sync_files_within_history_time_window_if_history_is_incomplete_different_timestamps_scenario_concurrent_cursor_is_newer, - multi_csv_sync_files_within_history_time_window_if_history_is_incomplete_different_timestamps_scenario_concurrent_cursor_is_older, - multi_csv_sync_files_within_time_window_if_history_is_incomplete__different_timestamps_scenario_concurrent_cursor_is_newer, - multi_csv_sync_files_within_time_window_if_history_is_incomplete__different_timestamps_scenario_concurrent_cursor_is_older, - multi_csv_sync_recent_files_if_history_is_incomplete_scenario_concurrent_cursor_is_newer, - multi_csv_sync_recent_files_if_history_is_incomplete_scenario_concurrent_cursor_is_older, - single_csv_file_is_skipped_if_same_modified_at_as_in_history_concurrent, - single_csv_file_is_synced_if_modified_at_is_more_recent_than_in_history_concurrent, - single_csv_input_state_is_earlier_scenario_concurrent, - single_csv_input_state_is_later_scenario_concurrent, - single_csv_no_input_state_scenario_concurrent, -) -from unit_tests.sources.file_based.scenarios.csv_scenarios import ( - csv_analytics_scenario, - csv_autogenerate_column_names_scenario, - csv_custom_bool_values_scenario, - csv_custom_delimiter_in_double_quotes_scenario, - csv_custom_delimiter_with_escape_char_scenario, - csv_custom_format_scenario, - csv_custom_null_values_scenario, - csv_double_quote_is_set_scenario, - csv_escape_char_is_set_scenario, - csv_multi_stream_scenario, - csv_newline_in_values_not_quoted_scenario, - csv_newline_in_values_quoted_value_scenario, - csv_no_files_scenario, - csv_no_records_scenario, - csv_single_stream_scenario, - csv_skip_after_header_scenario, - csv_skip_before_and_after_header_scenario, - csv_skip_before_header_scenario, - csv_string_are_not_null_if_strings_can_be_null_is_false_scenario, - csv_string_can_be_null_with_input_schemas_scenario, - csv_string_not_null_if_no_null_values_scenario, - csv_strings_can_be_null_not_quoted_scenario, - earlier_csv_scenario, - empty_schema_inference_scenario, - invalid_csv_multi_scenario, - invalid_csv_scenario, - multi_csv_scenario, - multi_csv_stream_n_file_exceeds_config_limit_for_inference, - multi_csv_stream_n_file_exceeds_limit_for_inference, - multi_stream_custom_format, - schemaless_csv_multi_stream_scenario, - schemaless_csv_scenario, - schemaless_with_user_input_schema_fails_connection_check_multi_stream_scenario, - schemaless_with_user_input_schema_fails_connection_check_scenario, - single_csv_scenario, -) -from unit_tests.sources.file_based.scenarios.excel_scenarios import ( - excel_all_types_scenario, - multiple_excel_combine_schema_scenario, - multiple_streams_excel_scenario, - single_excel_scenario, -) -from unit_tests.sources.file_based.scenarios.incremental_scenarios import ( - multi_csv_different_timestamps_scenario, - multi_csv_include_missing_files_within_history_range, - multi_csv_per_timestamp_scenario, - multi_csv_remove_old_files_if_history_is_full_scenario, - multi_csv_same_timestamp_more_files_than_history_size_scenario, - multi_csv_same_timestamp_scenario, - multi_csv_skip_file_if_already_in_history, - multi_csv_sync_files_within_history_time_window_if_history_is_incomplete_different_timestamps_scenario, - multi_csv_sync_files_within_time_window_if_history_is_incomplete__different_timestamps_scenario, - multi_csv_sync_recent_files_if_history_is_incomplete_scenario, - single_csv_file_is_skipped_if_same_modified_at_as_in_history, - single_csv_file_is_synced_if_modified_at_is_more_recent_than_in_history, - single_csv_input_state_is_earlier_scenario, - single_csv_input_state_is_later_scenario, - single_csv_no_input_state_scenario, -) -from unit_tests.sources.file_based.scenarios.jsonl_scenarios import ( - invalid_jsonl_scenario, - jsonl_multi_stream_scenario, - jsonl_user_input_schema_scenario, - multi_jsonl_stream_n_bytes_exceeds_limit_for_inference, - multi_jsonl_stream_n_file_exceeds_limit_for_inference, - multi_jsonl_with_different_keys_scenario, - schemaless_jsonl_multi_stream_scenario, - schemaless_jsonl_scenario, - single_jsonl_scenario, -) -from unit_tests.sources.file_based.scenarios.parquet_scenarios import ( - multi_parquet_scenario, - parquet_file_with_decimal_as_float_scenario, - parquet_file_with_decimal_as_string_scenario, - parquet_file_with_decimal_no_config_scenario, - parquet_various_types_scenario, - parquet_with_invalid_config_scenario, - single_parquet_scenario, - single_partitioned_parquet_scenario, -) -from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenario -from unit_tests.sources.file_based.scenarios.unstructured_scenarios import ( - corrupted_file_scenario, - no_file_extension_unstructured_scenario, - simple_markdown_scenario, - simple_txt_scenario, - simple_unstructured_scenario, - unstructured_invalid_file_type_discover_scenario_no_skip, - unstructured_invalid_file_type_discover_scenario_skip, - unstructured_invalid_file_type_read_scenario, -) -from unit_tests.sources.file_based.scenarios.user_input_schema_scenarios import ( - multi_stream_user_input_schema_scenario_emit_nonconforming_records, - multi_stream_user_input_schema_scenario_schema_is_invalid, - multi_stream_user_input_schema_scenario_skip_nonconforming_records, - single_stream_user_input_schema_scenario_emit_nonconforming_records, - single_stream_user_input_schema_scenario_schema_is_invalid, - single_stream_user_input_schema_scenario_skip_nonconforming_records, - valid_multi_stream_user_input_schema_scenario, - valid_single_stream_user_input_schema_scenario, -) -from unit_tests.sources.file_based.scenarios.validation_policy_scenarios import ( - emit_record_scenario_multi_stream, - emit_record_scenario_single_stream, - skip_record_scenario_multi_stream, - skip_record_scenario_single_stream, - wait_for_rediscovery_scenario_multi_stream, - wait_for_rediscovery_scenario_single_stream, -) -from unit_tests.sources.file_based.test_scenarios import verify_check, verify_discover, verify_read, verify_spec - -discover_failure_scenarios = [ - empty_schema_inference_scenario, -] - -discover_success_scenarios = [ - csv_no_records_scenario, - csv_multi_stream_scenario, - csv_single_stream_scenario, - invalid_csv_scenario, - invalid_csv_multi_scenario, - single_csv_scenario, - multi_csv_scenario, - multi_csv_stream_n_file_exceeds_limit_for_inference, - multi_csv_stream_n_file_exceeds_config_limit_for_inference, - single_csv_input_state_is_earlier_scenario, - single_csv_no_input_state_scenario, - single_csv_input_state_is_later_scenario, - multi_csv_same_timestamp_scenario, - multi_csv_different_timestamps_scenario, - multi_csv_per_timestamp_scenario, - multi_csv_skip_file_if_already_in_history, - multi_csv_include_missing_files_within_history_range, - multi_csv_remove_old_files_if_history_is_full_scenario, - multi_csv_same_timestamp_more_files_than_history_size_scenario, - multi_csv_sync_recent_files_if_history_is_incomplete_scenario, - multi_csv_sync_files_within_time_window_if_history_is_incomplete__different_timestamps_scenario, - multi_csv_sync_files_within_history_time_window_if_history_is_incomplete_different_timestamps_scenario, - single_csv_file_is_skipped_if_same_modified_at_as_in_history, - single_csv_file_is_synced_if_modified_at_is_more_recent_than_in_history, - csv_custom_format_scenario, - multi_stream_custom_format, - single_parquet_scenario, - multi_parquet_scenario, - parquet_various_types_scenario, - parquet_file_with_decimal_no_config_scenario, - parquet_file_with_decimal_as_string_scenario, - parquet_file_with_decimal_as_float_scenario, - schemaless_csv_scenario, - schemaless_csv_multi_stream_scenario, - schemaless_with_user_input_schema_fails_connection_check_multi_stream_scenario, - schemaless_with_user_input_schema_fails_connection_check_scenario, - single_stream_user_input_schema_scenario_schema_is_invalid, - single_stream_user_input_schema_scenario_emit_nonconforming_records, - single_stream_user_input_schema_scenario_skip_nonconforming_records, - multi_stream_user_input_schema_scenario_emit_nonconforming_records, - multi_stream_user_input_schema_scenario_skip_nonconforming_records, - multi_stream_user_input_schema_scenario_schema_is_invalid, - valid_multi_stream_user_input_schema_scenario, - valid_single_stream_user_input_schema_scenario, - single_jsonl_scenario, - multi_jsonl_with_different_keys_scenario, - multi_jsonl_stream_n_file_exceeds_limit_for_inference, - multi_jsonl_stream_n_bytes_exceeds_limit_for_inference, - invalid_jsonl_scenario, - jsonl_multi_stream_scenario, - jsonl_user_input_schema_scenario, - schemaless_jsonl_scenario, - schemaless_jsonl_multi_stream_scenario, - csv_string_can_be_null_with_input_schemas_scenario, - csv_string_are_not_null_if_strings_can_be_null_is_false_scenario, - csv_string_not_null_if_no_null_values_scenario, - csv_strings_can_be_null_not_quoted_scenario, - csv_newline_in_values_quoted_value_scenario, - csv_escape_char_is_set_scenario, - csv_double_quote_is_set_scenario, - csv_custom_delimiter_with_escape_char_scenario, - csv_custom_delimiter_in_double_quotes_scenario, - csv_skip_before_header_scenario, - csv_skip_after_header_scenario, - csv_skip_before_and_after_header_scenario, - csv_custom_bool_values_scenario, - csv_custom_null_values_scenario, - single_avro_scenario, - avro_all_types_scenario, - multiple_avro_combine_schema_scenario, - multiple_streams_avro_scenario, - avro_file_with_double_as_number_scenario, - excel_all_types_scenario, - multiple_excel_combine_schema_scenario, - multiple_streams_excel_scenario, - single_excel_scenario, - csv_newline_in_values_not_quoted_scenario, - csv_autogenerate_column_names_scenario, - parquet_with_invalid_config_scenario, - single_partitioned_parquet_scenario, - simple_markdown_scenario, - simple_txt_scenario, - simple_unstructured_scenario, - corrupted_file_scenario, - no_file_extension_unstructured_scenario, - unstructured_invalid_file_type_discover_scenario_no_skip, - unstructured_invalid_file_type_discover_scenario_skip, - unstructured_invalid_file_type_read_scenario, - multi_csv_different_timestamps_scenario_concurrent, - multi_csv_include_missing_files_within_history_range_concurrent_cursor_is_newer, - multi_csv_include_missing_files_within_history_range_concurrent_cursor_is_older, - multi_csv_per_timestamp_scenario_concurrent, - multi_csv_remove_old_files_if_history_is_full_scenario_concurrent_cursor_is_newer, - multi_csv_remove_old_files_if_history_is_full_scenario_concurrent_cursor_is_older, - multi_csv_same_timestamp_more_files_than_history_size_scenario_concurrent_cursor_is_newer, - multi_csv_same_timestamp_more_files_than_history_size_scenario_concurrent_cursor_is_older, - multi_csv_same_timestamp_scenario_concurrent, - multi_csv_skip_file_if_already_in_history_concurrent, - multi_csv_sync_files_within_history_time_window_if_history_is_incomplete_different_timestamps_scenario_concurrent_cursor_is_newer, - multi_csv_sync_files_within_history_time_window_if_history_is_incomplete_different_timestamps_scenario_concurrent_cursor_is_older, - multi_csv_sync_files_within_time_window_if_history_is_incomplete__different_timestamps_scenario_concurrent_cursor_is_newer, - multi_csv_sync_files_within_time_window_if_history_is_incomplete__different_timestamps_scenario_concurrent_cursor_is_older, - multi_csv_sync_recent_files_if_history_is_incomplete_scenario_concurrent_cursor_is_newer, - multi_csv_sync_recent_files_if_history_is_incomplete_scenario_concurrent_cursor_is_older, - single_csv_file_is_skipped_if_same_modified_at_as_in_history_concurrent, - single_csv_file_is_synced_if_modified_at_is_more_recent_than_in_history_concurrent, - single_csv_input_state_is_earlier_scenario_concurrent, - single_csv_input_state_is_later_scenario_concurrent, - single_csv_no_input_state_scenario_concurrent, - earlier_csv_scenario, - csv_no_files_scenario, -] - -discover_scenarios = discover_failure_scenarios + discover_success_scenarios - -read_scenarios = discover_success_scenarios + [ - emit_record_scenario_multi_stream, - emit_record_scenario_single_stream, - skip_record_scenario_multi_stream, - skip_record_scenario_single_stream, - csv_analytics_scenario, - wait_for_rediscovery_scenario_multi_stream, - wait_for_rediscovery_scenario_single_stream, -] - -spec_scenarios = [ - single_csv_scenario, -] - -check_scenarios = [ - error_empty_stream_scenario, - error_listing_files_scenario, - error_reading_file_scenario, - error_record_validation_user_provided_schema_scenario, - error_multi_stream_scenario, - success_csv_scenario, - success_extensionless_scenario, - success_multi_stream_scenario, - success_user_provided_schema_scenario, - schemaless_with_user_input_schema_fails_connection_check_multi_stream_scenario, - schemaless_with_user_input_schema_fails_connection_check_scenario, - valid_single_stream_user_input_schema_scenario, - single_avro_scenario, - single_excel_scenario, - earlier_csv_scenario, - csv_no_files_scenario, -] - - -@pytest.mark.parametrize("scenario", discover_scenarios, ids=[s.name for s in discover_scenarios]) -def test_file_based_discover(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario[AbstractSource]) -> None: - verify_discover(capsys, tmp_path, scenario) - - -@pytest.mark.parametrize("scenario", read_scenarios, ids=[s.name for s in read_scenarios]) -@freeze_time("2023-06-09T00:00:00Z") -def test_file_based_read(scenario: TestScenario[AbstractSource]) -> None: - verify_read(scenario) - - -@pytest.mark.parametrize("scenario", spec_scenarios, ids=[c.name for c in spec_scenarios]) -def test_file_based_spec(capsys: CaptureFixture[str], scenario: TestScenario[AbstractSource]) -> None: - verify_spec(capsys, scenario) - - -@pytest.mark.parametrize("scenario", check_scenarios, ids=[c.name for c in check_scenarios]) -def test_file_based_check(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario[AbstractSource]) -> None: - verify_check(capsys, tmp_path, scenario) diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/test_file_based_stream_reader.py b/airbyte-cdk/python/unit_tests/sources/file_based/test_file_based_stream_reader.py deleted file mode 100644 index 5abbecc0434d..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/test_file_based_stream_reader.py +++ /dev/null @@ -1,272 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from io import IOBase -from typing import Any, Iterable, List, Mapping, Optional, Set - -import pytest -from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader -from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from pydantic.v1 import AnyUrl -from unit_tests.sources.file_based.helpers import make_remote_files - -reader = AbstractFileBasedStreamReader - -""" -The rules are: - -- All files at top-level: /* -- All files at top-level of mydir: mydir/* -- All files anywhere under mydir: mydir/**/* -- All files in any directory: **/* -- All files in any directory that end in .csv: **/*.csv -- All files in any directory that have a .csv extension: **/*.csv* -""" - -FILEPATHS = [ - "a", - "a.csv", - "a.csv.gz", - "a.jsonl", - "a/b", - "a/b.csv", - "a/b.csv.gz", - "a/b.jsonl", - "a/c", - "a/c.csv", - "a/c.csv.gz", - "a/c.jsonl", - "a/b/c", - "a/b/c.csv", - "a/b/c.csv.gz", - "a/b/c.jsonl", - "a/c/c", - "a/c/c.csv", - "a/c/c.csv.gz", - "a/c/c.jsonl", - "a/b/c/d", - "a/b/c/d.csv", - "a/b/c/d.csv.gz", - "a/b/c/d.jsonl", -] -FILES = make_remote_files(FILEPATHS) - -DEFAULT_CONFIG = { - "streams": [], -} - - -class TestStreamReader(AbstractFileBasedStreamReader): - @property - def config(self) -> Optional[AbstractFileBasedSpec]: - return self._config - - @config.setter - def config(self, value: AbstractFileBasedSpec) -> None: - self._config = value - - def get_matching_files(self, globs: List[str]) -> Iterable[RemoteFile]: - pass - - def open_file(self, file: RemoteFile) -> IOBase: - pass - - -class TestSpec(AbstractFileBasedSpec): - @classmethod - def documentation_url(cls) -> AnyUrl: - return AnyUrl(scheme="https", url="https://docs.airbyte.com/integrations/sources/test") # type: ignore - - -@pytest.mark.parametrize( - "globs,config,expected_matches,expected_path_prefixes", - [ - pytest.param([], DEFAULT_CONFIG, set(), set(), id="no-globs"), - pytest.param([""], DEFAULT_CONFIG, set(), set(), id="empty-string"), - pytest.param(["**"], DEFAULT_CONFIG, set(FILEPATHS), set(), id="**"), - pytest.param( - ["**/*.csv"], DEFAULT_CONFIG, {"a.csv", "a/b.csv", "a/c.csv", "a/b/c.csv", "a/c/c.csv", "a/b/c/d.csv"}, set(), id="**/*.csv" - ), - pytest.param( - ["**/*.csv*"], - DEFAULT_CONFIG, - { - "a.csv", - "a.csv.gz", - "a/b.csv", - "a/b.csv.gz", - "a/c.csv", - "a/c.csv.gz", - "a/b/c.csv", - "a/b/c.csv.gz", - "a/c/c.csv", - "a/c/c.csv.gz", - "a/b/c/d.csv", - "a/b/c/d.csv.gz", - }, - set(), - id="**/*.csv*", - ), - pytest.param(["*"], DEFAULT_CONFIG, {"a", "a.csv", "a.csv.gz", "a.jsonl"}, set(), id="*"), - pytest.param(["*.csv"], DEFAULT_CONFIG, {"a.csv"}, set(), id="*.csv"), - pytest.param(["*.csv*"], DEFAULT_CONFIG, {"a.csv", "a.csv.gz"}, set(), id="*.csv*"), - pytest.param( - ["*/*"], - DEFAULT_CONFIG, - {"a/b", "a/b.csv", "a/b.csv.gz", "a/b.jsonl", "a/c", "a/c.csv", "a/c.csv.gz", "a/c.jsonl"}, - set(), - id="*/*", - ), - pytest.param(["*/*.csv"], DEFAULT_CONFIG, {"a/b.csv", "a/c.csv"}, set(), id="*/*.csv"), - pytest.param(["*/*.csv*"], DEFAULT_CONFIG, {"a/b.csv", "a/b.csv.gz", "a/c.csv", "a/c.csv.gz"}, set(), id="*/*.csv*"), - pytest.param( - ["*/**"], - DEFAULT_CONFIG, - { - "a/b", - "a/b.csv", - "a/b.csv.gz", - "a/b.jsonl", - "a/c", - "a/c.csv", - "a/c.csv.gz", - "a/c.jsonl", - "a/b/c", - "a/b/c.csv", - "a/b/c.csv.gz", - "a/b/c.jsonl", - "a/c/c", - "a/c/c.csv", - "a/c/c.csv.gz", - "a/c/c.jsonl", - "a/b/c/d", - "a/b/c/d.csv", - "a/b/c/d.csv.gz", - "a/b/c/d.jsonl", - }, - set(), - id="*/**", - ), - pytest.param( - ["a/*"], - DEFAULT_CONFIG, - {"a/b", "a/b.csv", "a/b.csv.gz", "a/b.jsonl", "a/c", "a/c.csv", "a/c.csv.gz", "a/c.jsonl"}, - {"a/"}, - id="a/*", - ), - pytest.param(["a/*.csv"], DEFAULT_CONFIG, {"a/b.csv", "a/c.csv"}, {"a/"}, id="a/*.csv"), - pytest.param(["a/*.csv*"], DEFAULT_CONFIG, {"a/b.csv", "a/b.csv.gz", "a/c.csv", "a/c.csv.gz"}, {"a/"}, id="a/*.csv*"), - pytest.param(["a/b/*"], DEFAULT_CONFIG, {"a/b/c", "a/b/c.csv", "a/b/c.csv.gz", "a/b/c.jsonl"}, {"a/b/"}, id="a/b/*"), - pytest.param(["a/b/*.csv"], DEFAULT_CONFIG, {"a/b/c.csv"}, {"a/b/"}, id="a/b/*.csv"), - pytest.param(["a/b/*.csv*"], DEFAULT_CONFIG, {"a/b/c.csv", "a/b/c.csv.gz"}, {"a/b/"}, id="a/b/*.csv*"), - pytest.param( - ["a/*/*"], - DEFAULT_CONFIG, - {"a/b/c", "a/b/c.csv", "a/b/c.csv.gz", "a/b/c.jsonl", "a/c/c", "a/c/c.csv", "a/c/c.csv.gz", "a/c/c.jsonl"}, - {"a/"}, - id="a/*/*", - ), - pytest.param(["a/*/*.csv"], DEFAULT_CONFIG, {"a/b/c.csv", "a/c/c.csv"}, {"a/"}, id="a/*/*.csv"), - pytest.param(["a/*/*.csv*"], DEFAULT_CONFIG, {"a/b/c.csv", "a/b/c.csv.gz", "a/c/c.csv", "a/c/c.csv.gz"}, {"a/"}, id="a/*/*.csv*"), - pytest.param( - ["a/**/*"], - DEFAULT_CONFIG, - { - "a/b", - "a/b.csv", - "a/b.csv.gz", - "a/b.jsonl", - "a/c", - "a/c.csv", - "a/c.csv.gz", - "a/c.jsonl", - "a/b/c", - "a/b/c.csv", - "a/b/c.csv.gz", - "a/b/c.jsonl", - "a/c/c", - "a/c/c.csv", - "a/c/c.csv.gz", - "a/c/c.jsonl", - "a/b/c/d", - "a/b/c/d.csv", - "a/b/c/d.csv.gz", - "a/b/c/d.jsonl", - }, - {"a/"}, - id="a/**/*", - ), - pytest.param( - ["a/**/*.csv"], DEFAULT_CONFIG, {"a/b.csv", "a/c.csv", "a/b/c.csv", "a/c/c.csv", "a/b/c/d.csv"}, {"a/"}, id="a/**/*.csv" - ), - pytest.param( - ["a/**/*.csv*"], - DEFAULT_CONFIG, - { - "a/b.csv", - "a/b.csv.gz", - "a/c.csv", - "a/c.csv.gz", - "a/b/c.csv", - "a/b/c.csv.gz", - "a/c/c.csv", - "a/c/c.csv.gz", - "a/b/c/d.csv", - "a/b/c/d.csv.gz", - }, - {"a/"}, - id="a/**/*.csv*", - ), - pytest.param( - ["**/*.csv", "**/*.gz"], - DEFAULT_CONFIG, - { - "a.csv", - "a.csv.gz", - "a/b.csv", - "a/b.csv.gz", - "a/c.csv", - "a/c.csv.gz", - "a/b/c.csv", - "a/b/c.csv.gz", - "a/c/c.csv", - "a/c/c.csv.gz", - "a/b/c/d.csv", - "a/b/c/d.csv.gz", - }, - set(), - id="**/*.csv,**/*.gz", - ), - pytest.param(["*.csv", "*.gz"], DEFAULT_CONFIG, {"a.csv", "a.csv.gz"}, set(), id="*.csv,*.gz"), - pytest.param( - ["a/*.csv", "a/*/*.csv"], DEFAULT_CONFIG, {"a/b.csv", "a/c.csv", "a/b/c.csv", "a/c/c.csv"}, {"a/"}, id="a/*.csv,a/*/*.csv" - ), - pytest.param(["a/*.csv", "a/b/*.csv"], DEFAULT_CONFIG, {"a/b.csv", "a/c.csv", "a/b/c.csv"}, {"a/", "a/b/"}, id="a/*.csv,a/b/*.csv"), - pytest.param( - ["**/*.csv"], - {"start_date": "2023-06-01T03:54:07.000Z", "streams": []}, - {"a.csv", "a/b.csv", "a/c.csv", "a/b/c.csv", "a/c/c.csv", "a/b/c/d.csv"}, - set(), - id="all_csvs_modified_after_start_date", - ), - pytest.param( - ["**/*.csv"], {"start_date": "2023-06-10T03:54:07.000Z", "streams": []}, set(), set(), id="all_csvs_modified_before_start_date" - ), - pytest.param( - ["**/*.csv"], - {"start_date": "2023-06-05T03:54:07.000Z", "streams": []}, - {"a.csv", "a/b.csv", "a/c.csv", "a/b/c.csv", "a/c/c.csv", "a/b/c/d.csv"}, - set(), - id="all_csvs_modified_exactly_on_start_date", - ), - ], -) -def test_globs_and_prefixes_from_globs( - globs: List[str], config: Mapping[str, Any], expected_matches: Set[str], expected_path_prefixes: Set[str] -) -> None: - reader = TestStreamReader() - reader.config = TestSpec(**config) - assert set([f.uri for f in reader.filter_files_by_globs_and_start_date(FILES, globs)]) == expected_matches - assert set(reader.get_prefixes_from_globs(globs)) == expected_path_prefixes diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py deleted file mode 100644 index b381e6886c3e..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py +++ /dev/null @@ -1,258 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import math -from pathlib import Path, PosixPath -from typing import Any, Dict, List, Mapping, Optional, Union - -import pytest -from _pytest.capture import CaptureFixture -from _pytest.reports import ExceptionInfo -from airbyte_cdk.entrypoint import launch -from airbyte_cdk.models import AirbyteAnalyticsTraceMessage, AirbyteLogMessage, AirbyteMessage, ConfiguredAirbyteCatalogSerializer, SyncMode -from airbyte_cdk.sources import AbstractSource -from airbyte_cdk.sources.file_based.stream.concurrent.cursor import AbstractConcurrentFileBasedCursor -from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput -from airbyte_cdk.test.entrypoint_wrapper import read as entrypoint_read -from airbyte_cdk.utils import message_utils -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenario - - -def verify_discover(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario[AbstractSource]) -> None: - expected_exc, expected_msg = scenario.expected_discover_error - expected_logs = scenario.expected_logs - if expected_exc: - with pytest.raises(expected_exc) as exc: - discover(capsys, tmp_path, scenario) - if expected_msg: - assert expected_msg in get_error_message_from_exc(exc) - elif scenario.expected_catalog: - output = discover(capsys, tmp_path, scenario) - catalog, logs = output["catalog"], output["logs"] - assert catalog == scenario.expected_catalog - if expected_logs: - discover_logs = expected_logs.get("discover") - logs = [log for log in logs if log.get("log", {}).get("level") in ("ERROR", "WARN")] - _verify_expected_logs(logs, discover_logs) - - -def verify_read(scenario: TestScenario[AbstractSource]) -> None: - if scenario.incremental_scenario_config: - run_test_read_incremental(scenario) - else: - run_test_read_full_refresh(scenario) - - -def run_test_read_full_refresh(scenario: TestScenario[AbstractSource]) -> None: - expected_exc, expected_msg = scenario.expected_read_error - output = read(scenario) - if expected_exc: - assert_exception(expected_exc, output) - if expected_msg: - assert expected_msg in output.errors[-1].trace.error.internal_message - else: - _verify_read_output(output, scenario) - - -def run_test_read_incremental(scenario: TestScenario[AbstractSource]) -> None: - expected_exc, expected_msg = scenario.expected_read_error - output = read_with_state(scenario) - if expected_exc: - assert_exception(expected_exc, output) - else: - _verify_read_output(output, scenario) - - -def assert_exception(expected_exception: type[BaseException], output: EntrypointOutput) -> None: - assert expected_exception.__name__ in output.errors[-1].trace.error.stack_trace - - -def _verify_read_output(output: EntrypointOutput, scenario: TestScenario[AbstractSource]) -> None: - records_and_state_messages, log_messages = output.records_and_state_messages, output.logs - logs = [message.log for message in log_messages if message.log.level.value in scenario.log_levels] - if scenario.expected_records is None: - return - - expected_records = [r for r in scenario.expected_records] if scenario.expected_records else [] - - sorted_expected_records = sorted( - filter(lambda e: "data" in e, expected_records), - key=lambda record: ",".join( - f"{k}={v}" for k, v in sorted(record["data"].items(), key=lambda items: (items[0], items[1])) if k != "emitted_at" - ), - ) - sorted_records = sorted( - filter(lambda r: r.record, records_and_state_messages), - key=lambda record: ",".join( - f"{k}={v}" for k, v in sorted(record.record.data.items(), key=lambda items: (items[0], items[1])) if k != "emitted_at" - ), - ) - - assert len(sorted_records) == len(sorted_expected_records) - - for actual, expected in zip(sorted_records, sorted_expected_records): - if actual.record: - assert len(actual.record.data) == len(expected["data"]) - for key, value in actual.record.data.items(): - if isinstance(value, float): - assert math.isclose(value, expected["data"][key], abs_tol=1e-04) - else: - assert value == expected["data"][key] - assert actual.record.stream == expected["stream"] - - expected_states = list(filter(lambda e: "data" not in e, expected_records)) - states = list(filter(lambda r: r.state, records_and_state_messages)) - assert len(states) > 0, "No state messages emitted. Successful syncs should emit at least one stream state." - _verify_state_record_counts(sorted_records, states) - - if hasattr(scenario.source, "cursor_cls") and issubclass(scenario.source.cursor_cls, AbstractConcurrentFileBasedCursor): - # Only check the last state emitted because we don't know the order the others will be in. - # This may be needed for non-file-based concurrent scenarios too. - assert {k: v for k, v in states[-1].state.stream.stream_state.__dict__.items()} == expected_states[-1] - else: - for actual, expected in zip(states, expected_states): # states should be emitted in sorted order - assert {k: v for k, v in actual.state.stream.stream_state.__dict__.items()} == expected - - if scenario.expected_logs: - read_logs = scenario.expected_logs.get("read") - assert len(logs) == (len(read_logs) if read_logs else 0) - _verify_expected_logs(logs, read_logs) - - if scenario.expected_analytics: - analytics = output.analytics_messages - - _verify_analytics(analytics, scenario.expected_analytics) - - -def _verify_state_record_counts(records: List[AirbyteMessage], states: List[AirbyteMessage]) -> None: - actual_record_counts = {} - for record in records: - stream_descriptor = message_utils.get_stream_descriptor(record) - actual_record_counts[stream_descriptor] = actual_record_counts.get(stream_descriptor, 0) + 1 - - state_record_count_sums = {} - for state_message in states: - stream_descriptor = message_utils.get_stream_descriptor(state_message) - state_record_count_sums[stream_descriptor] = ( - state_record_count_sums.get(stream_descriptor, 0) + state_message.state.sourceStats.recordCount - ) - - for stream, actual_count in actual_record_counts.items(): - assert actual_count == state_record_count_sums.get(stream) - - # We can have extra keys in state_record_count_sums if we processed a stream and reported 0 records - extra_keys = state_record_count_sums.keys() - actual_record_counts.keys() - for stream in extra_keys: - assert state_record_count_sums[stream] == 0 - - -def _verify_analytics(analytics: List[AirbyteMessage], expected_analytics: Optional[List[AirbyteAnalyticsTraceMessage]]) -> None: - if expected_analytics: - assert len(analytics) == len( - expected_analytics - ), f"Number of actual analytics messages ({len(analytics)}) did not match expected ({len(expected_analytics)})" - for actual, expected in zip(analytics, expected_analytics): - actual_type, actual_value = actual.trace.analytics.type, actual.trace.analytics.value - expected_type = expected.type - expected_value = expected.value - assert actual_type == expected_type - assert actual_value == expected_value - - -def _verify_expected_logs(logs: List[AirbyteLogMessage], expected_logs: Optional[List[Mapping[str, Any]]]) -> None: - if expected_logs: - for actual, expected in zip(logs, expected_logs): - actual_level, actual_message = actual.level.value, actual.message - expected_level = expected["level"] - expected_message = expected["message"] - assert actual_level == expected_level - assert expected_message in actual_message - - -def verify_spec(capsys: CaptureFixture[str], scenario: TestScenario[AbstractSource]) -> None: - assert spec(capsys, scenario) == scenario.expected_spec - - -def verify_check(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario[AbstractSource]) -> None: - expected_exc, expected_msg = scenario.expected_check_error - - if expected_exc: - with pytest.raises(expected_exc) as exc: - check(capsys, tmp_path, scenario) - - if expected_msg: - assert expected_msg in exc.value.message - - else: - output = check(capsys, tmp_path, scenario) - assert output["status"] == scenario.expected_check_status - - -def spec(capsys: CaptureFixture[str], scenario: TestScenario[AbstractSource]) -> Mapping[str, Any]: - launch( - scenario.source, - ["spec"], - ) - captured = capsys.readouterr() - return json.loads(captured.out.splitlines()[0])["spec"] # type: ignore - - -def check(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario[AbstractSource]) -> Dict[str, Any]: - launch( - scenario.source, - ["check", "--config", make_file(tmp_path / "config.json", scenario.config)], - ) - captured = capsys.readouterr() - return _find_connection_status(captured.out.splitlines()) - - -def _find_connection_status(output: List[str]) -> Mapping[str, Any]: - for line in output: - json_line = json.loads(line) - if "connectionStatus" in json_line: - return json_line["connectionStatus"] - raise ValueError("No valid connectionStatus found in output") - - -def discover(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario[AbstractSource]) -> Dict[str, Any]: - launch( - scenario.source, - ["discover", "--config", make_file(tmp_path / "config.json", scenario.config)], - ) - output = [json.loads(line) for line in capsys.readouterr().out.splitlines()] - [catalog] = [o["catalog"] for o in output if o.get("catalog")] # type: ignore - return { - "catalog": catalog, - "logs": [o["log"] for o in output if o.get("log")], - } - - -def read(scenario: TestScenario[AbstractSource]) -> EntrypointOutput: - return entrypoint_read( - scenario.source, - scenario.config, - ConfiguredAirbyteCatalogSerializer.load(scenario.configured_catalog(SyncMode.full_refresh)), - ) - - -def read_with_state(scenario: TestScenario[AbstractSource]) -> EntrypointOutput: - return entrypoint_read( - scenario.source, - scenario.config, - ConfiguredAirbyteCatalogSerializer.load(scenario.configured_catalog(SyncMode.incremental)), - scenario.input_state(), - ) - - -def make_file(path: Path, file_contents: Optional[Union[Mapping[str, Any], List[Mapping[str, Any]]]]) -> str: - path.write_text(json.dumps(file_contents)) - return str(path) - - -def get_error_message_from_exc(exc: ExceptionInfo[Any]) -> str: - if isinstance(exc.value, AirbyteTracedException): - return exc.value.message - return str(exc.value.args[0]) diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/test_schema_helpers.py b/airbyte-cdk/python/unit_tests/sources/file_based/test_schema_helpers.py deleted file mode 100644 index 90e01942d98f..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/test_schema_helpers.py +++ /dev/null @@ -1,364 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Mapping, Optional - -import pytest -from airbyte_cdk.sources.file_based.exceptions import ConfigValidationError, SchemaInferenceError -from airbyte_cdk.sources.file_based.schema_helpers import ( - ComparableType, - SchemaType, - conforms_to_schema, - merge_schemas, - type_mapping_to_jsonschema, -) - -COMPLETE_CONFORMING_RECORD = { - "null_field": None, - "boolean_field": True, - "integer_field": 1, - "number_field": 1.5, - "string_field": "val1", - "array_field": [1.1, 2.2], - "object_field": {"col": "val"}, -} - - -NONCONFORMING_EXTRA_COLUMN_RECORD = { - "null_field": None, - "boolean_field": True, - "integer_field": 1, - "number_field": 1.5, - "string_field": "val1", - "array_field": [1.1, 2.2], - "object_field": {"col": "val"}, - "column_x": "extra", -} - -CONFORMING_WITH_MISSING_COLUMN_RECORD = { - "null_field": None, - "boolean_field": True, - "integer_field": 1, - "number_field": 1.5, - "string_field": "val1", - "array_field": [1.1, 2.2], -} - -CONFORMING_WITH_NARROWER_TYPE_RECORD = { - "null_field": None, - "boolean_field": True, - "integer_field": True, - "number_field": True, - "string_field": True, - "array_field": [1.1, 2.2], - "object_field": {"col": "val"}, -} - -NONCONFORMING_WIDER_TYPE_RECORD = { - "null_field": "not None", - "boolean_field": True, - "integer_field": 1, - "number_field": 1.5, - "string_field": "val1", - "array_field": [1.1, 2.2], - "object_field": {"col": "val"}, -} - -NONCONFORMING_NON_OBJECT_RECORD = { - "null_field": None, - "boolean_field": True, - "integer_field": 1, - "number_field": 1.5, - "string_field": "val1", - "array_field": [1.1, 2.2], - "object_field": "not an object", -} - -NONCONFORMING_NON_ARRAY_RECORD = { - "null_field": None, - "boolean_field": True, - "integer_field": 1, - "number_field": 1.5, - "string_field": "val1", - "array_field": "not an array", - "object_field": {"col": "val"}, -} - -CONFORMING_MIXED_TYPE_NARROWER_RECORD = { - "null_field": None, - "boolean_field": True, - "integer_field": 1, - "number_field": 1.5, - "string_field": "val1", - "array_field": [1.1, 2.2], - "object_field": {"col": "val"}, -} - -NONCONFORMING_MIXED_TYPE_WIDER_RECORD = { - "null_field": None, - "boolean_field": True, - "integer_field": 1, - "number_field": 1.5, - "string_field": "val1", - "array_field": [1.1, 2.2], - "object_field": {"col": "val"}, -} - -CONFORMING_MIXED_TYPE_WITHIN_TYPE_RANGE_RECORD = { - "null_field": None, - "boolean_field": True, - "integer_field": 1, - "number_field": 1.5, - "string_field": "val1", - "array_field": [1.1, 2.2], - "object_field": {"col": "val"}, -} - -NONCONFORMING_INVALID_ARRAY_RECORD = { - "null_field": None, - "boolean_field": True, - "integer_field": 1, - "number_field": 1.5, - "string_field": ["this should not be an array"], - "array_field": [1.1, 2.2], - "object_field": {"col": "val"}, -} - -NONCONFORMING_TOO_WIDE_ARRAY_RECORD = { - "null_field": None, - "boolean_field": True, - "integer_field": 1, - "number_field": 1.5, - "string_field": "okay", - "array_field": ["val1", "val2"], - "object_field": {"col": "val"}, -} - - -CONFORMING_NARROWER_ARRAY_RECORD = { - "null_field": None, - "boolean_field": True, - "integer_field": 1, - "number_field": 1.5, - "string_field": "okay", - "array_field": [1, 2], - "object_field": {"col": "val"}, -} - - -NONCONFORMING_INVALID_OBJECT_RECORD = { - "null_field": None, - "boolean_field": True, - "integer_field": 1, - "number_field": 1.5, - "string_field": {"this": "should not be an object"}, - "array_field": [1.1, 2.2], - "object_field": {"col": "val"}, -} - - -SCHEMA = { - "type": "object", - "properties": { - "null_field": {"type": "null"}, - "boolean_field": {"type": "boolean"}, - "integer_field": {"type": "integer"}, - "number_field": {"type": "number"}, - "string_field": {"type": "string"}, - "array_field": { - "type": "array", - "items": { - "type": "number", - }, - }, - "object_field": {"type": "object"}, - }, -} - - -@pytest.mark.parametrize( - "record,schema,expected_result", - [ - pytest.param(COMPLETE_CONFORMING_RECORD, SCHEMA, True, id="record-conforms"), - pytest.param(NONCONFORMING_EXTRA_COLUMN_RECORD, SCHEMA, False, id="nonconforming-extra-column"), - pytest.param(CONFORMING_WITH_MISSING_COLUMN_RECORD, SCHEMA, True, id="record-conforms-with-missing-column"), - pytest.param(CONFORMING_WITH_NARROWER_TYPE_RECORD, SCHEMA, True, id="record-conforms-with-narrower-type"), - pytest.param(NONCONFORMING_WIDER_TYPE_RECORD, SCHEMA, False, id="nonconforming-wider-type"), - pytest.param(NONCONFORMING_NON_OBJECT_RECORD, SCHEMA, False, id="nonconforming-string-is-not-an-object"), - pytest.param(NONCONFORMING_NON_ARRAY_RECORD, SCHEMA, False, id="nonconforming-string-is-not-an-array"), - pytest.param(NONCONFORMING_TOO_WIDE_ARRAY_RECORD, SCHEMA, False, id="nonconforming-array-values-too-wide"), - pytest.param(CONFORMING_NARROWER_ARRAY_RECORD, SCHEMA, True, id="conforming-array-values-narrower-than-schema"), - pytest.param(NONCONFORMING_INVALID_ARRAY_RECORD, SCHEMA, False, id="nonconforming-array-is-not-a-string"), - pytest.param(NONCONFORMING_INVALID_OBJECT_RECORD, SCHEMA, False, id="nonconforming-object-is-not-a-string"), - ], -) -def test_conforms_to_schema(record: Mapping[str, Any], schema: Mapping[str, Any], expected_result: bool) -> None: - assert conforms_to_schema(record, schema) == expected_result - - -def test_comparable_types() -> None: - assert ComparableType.OBJECT > ComparableType.STRING - assert ComparableType.STRING > ComparableType.NUMBER - assert ComparableType.NUMBER > ComparableType.INTEGER - assert ComparableType.INTEGER > ComparableType.BOOLEAN - assert ComparableType["OBJECT"] == ComparableType.OBJECT - - -@pytest.mark.parametrize( - "schema1,schema2,expected_result", - [ - pytest.param({}, {}, {}, id="empty-schemas"), - pytest.param({"a": None}, {}, None, id="null-value-in-schema"), - pytest.param({"a": {"type": "integer"}}, {}, {"a": {"type": "integer"}}, id="single-key-schema1"), - pytest.param({}, {"a": {"type": "integer"}}, {"a": {"type": "integer"}}, id="single-key-schema2"), - pytest.param({"a": {"type": "integer"}}, {"a": {"type": "integer"}}, {"a": {"type": "integer"}}, id="single-key-both-schemas"), - pytest.param({"a": {"type": "integer"}}, {"a": {"type": "number"}}, {"a": {"type": "number"}}, id="single-key-schema2-is-wider"), - pytest.param({"a": {"type": "number"}}, {"a": {"type": "integer"}}, {"a": {"type": "number"}}, id="single-key-schema1-is-wider"), - pytest.param({"a": {"type": "array"}}, {"a": {"type": "integer"}}, None, id="single-key-with-array-schema1"), - pytest.param({"a": {"type": "integer"}}, {"a": {"type": "array"}}, None, id="single-key-with-array-schema2"), - pytest.param( - {"a": {"type": "object", "properties": {"b": {"type": "integer"}}}}, - {"a": {"type": "object", "properties": {"b": {"type": "integer"}}}}, - {"a": {"type": "object", "properties": {"b": {"type": "integer"}}}}, - id="single-key-same-object", - ), - pytest.param( - {"a": {"type": "object", "properties": {"b": {"type": "integer"}}}}, - {"a": {"type": "object", "properties": {"b": {"type": "string"}}}}, - None, - id="single-key-different-objects", - ), - pytest.param( - {"a": {"type": "object", "properties": {"b": {"type": "integer"}}}}, - {"a": {"type": "number"}}, - None, - id="single-key-with-object-schema1", - ), - pytest.param( - {"a": {"type": "number"}}, - {"a": {"type": "object", "properties": {"b": {"type": "integer"}}}}, - None, - id="single-key-with-object-schema2", - ), - pytest.param( - {"a": {"type": "array", "items": {"type": "number"}}}, - {"a": {"type": "array", "items": {"type": "number"}}}, - {"a": {"type": "array", "items": {"type": "number"}}}, - id="equal-arrays-in-both-schemas", - ), - pytest.param( - {"a": {"type": "array", "items": {"type": "integer"}}}, - {"a": {"type": "array", "items": {"type": "number"}}}, - None, - id="different-arrays-in-both-schemas", - ), - pytest.param( - {"a": {"type": "integer"}, "b": {"type": "string"}}, - {"c": {"type": "number"}}, - {"a": {"type": "integer"}, "b": {"type": "string"}, "c": {"type": "number"}}, - id="", - ), - pytest.param({"a": {"type": "invalid_type"}}, {"b": {"type": "integer"}}, None, id="invalid-type"), - pytest.param( - {"a": {"type": "object"}}, - {"a": {"type": "null"}}, - {"a": {"type": "object"}}, - id="single-key-with-null-object-schema2", - ), - pytest.param( - {"a": {"type": "object"}}, - {"b": {"type": "null"}}, - {"a": {"type": "object"}, "b": {"type": "null"}}, - id="new-key-with-null-type", - ), - pytest.param( - {"a": {"type": "null"}}, - {"a": {"type": "object"}}, - {"a": {"type": "object"}}, - id="single-key-with-null-object-schema1", - ), - ], -) -def test_merge_schemas(schema1: SchemaType, schema2: SchemaType, expected_result: Optional[SchemaType]) -> None: - if expected_result is not None: - assert merge_schemas(schema1, schema2) == expected_result - else: - with pytest.raises(SchemaInferenceError): - merge_schemas(schema1, schema2) - - -@pytest.mark.parametrize( - "type_mapping,expected_schema,expected_exc_msg", - [ - pytest.param( - '{"col1": "null", "col2": "array", "col3": "boolean", "col4": "float", "col5": "integer", "col6": "number", "col7": "object", "col8": "string"}', - { - "type": "object", - "properties": { - "col1": {"type": "null"}, - "col2": {"type": "array"}, - "col3": {"type": "boolean"}, - "col4": {"type": "number"}, - "col5": {"type": "integer"}, - "col6": {"type": "number"}, - "col7": {"type": "object"}, - "col8": {"type": "string"}, - }, - }, - None, - id="valid_all_types", - ), - pytest.param( - '{"col1 ": " string", "col2": " integer"}', - {"type": "object", "properties": {"col1": {"type": "string"}, "col2": {"type": "integer"}}}, - None, - id="valid_extra_spaces", - ), - pytest.param( - "", - None, - None, - id="valid_empty_string", - ), - pytest.param( - '{"col1": "x", "col2": "integer"}', - None, - "Invalid type 'x' for property 'col1'", - id="invalid_type", - ), - pytest.param( - '{"col1": "", "col2": "integer"}', - None, - "Invalid input schema", - id="invalid_missing_type", - ), - pytest.param( - '{"": "string", "col2": "integer"}', - None, - "Invalid input schema", - id="invalid_missing_name", - ), - pytest.param( - '{"type": "object", "properties": {"col1": {"type": "string"}, "col2": {"type": "integer"}}}', - None, - "Invalid input schema; nested schemas are not supported.", - id="invalid_nested_input_string", - ), - pytest.param( - '{"type": "object", "properties": {"col1": {"type": "string"}, "col2": {"type": "integer"}}}', - None, - "Invalid input schema; nested schemas are not supported.", - id="invalid_nested_input_json", - ), - ], -) -def test_type_mapping_to_jsonschema( - type_mapping: Mapping[str, Any], expected_schema: Optional[Mapping[str, Any]], expected_exc_msg: Optional[str] -) -> None: - if expected_exc_msg: - with pytest.raises(ConfigValidationError) as exc: - type_mapping_to_jsonschema(type_mapping) - assert expected_exc_msg in exc.value.args[0] - else: - assert type_mapping_to_jsonschema(type_mapping) == expected_schema diff --git a/airbyte-cdk/python/unit_tests/sources/fixtures/__init__.py b/airbyte-cdk/python/unit_tests/sources/fixtures/__init__.py deleted file mode 100644 index 46b7376756ec..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/fixtures/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/fixtures/source_test_fixture.py b/airbyte-cdk/python/unit_tests/sources/fixtures/source_test_fixture.py deleted file mode 100644 index 6f3cd57b1ccc..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/fixtures/source_test_fixture.py +++ /dev/null @@ -1,154 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import logging -from abc import ABC -from typing import Any, Iterable, List, Mapping, Optional, Tuple, Union - -import requests -from airbyte_cdk.models import ( - AirbyteStream, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteStream, - ConnectorSpecification, - DestinationSyncMode, - SyncMode, -) -from airbyte_cdk.sources import AbstractSource -from airbyte_cdk.sources.streams import Stream -from airbyte_cdk.sources.streams.http import HttpStream -from airbyte_cdk.sources.streams.http.requests_native_auth import Oauth2Authenticator -from requests.auth import AuthBase - - -class SourceTestFixture(AbstractSource): - """ - This is a concrete implementation of a Source connector that provides implementations of all the methods needed to run sync - operations. For simplicity, it also overrides functions that read from files in favor of returning the data directly avoiding - the need to load static files (ex. spec.yaml, config.json, configured_catalog.json) into the unit-test package. - """ - - def __init__(self, streams: Optional[List[Stream]] = None, authenticator: Optional[AuthBase] = None): - self._streams = streams - self._authenticator = authenticator - - def spec(self, logger: logging.Logger) -> ConnectorSpecification: - return ConnectorSpecification( - connectionSpecification={ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Test Fixture Spec", - "type": "object", - "required": ["api_token"], - "properties": { - "api_token": { - "type": "string", - "title": "API token", - "description": "The token used to authenticate requests to the API.", - "airbyte_secret": True, - } - }, - } - ) - - def read_config(self, config_path: str) -> Mapping[str, Any]: - return {"api_token": "just_some_token"} - - @classmethod - def read_catalog(cls, catalog_path: str) -> ConfiguredAirbyteCatalog: - return ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=AirbyteStream( - name="http_test_stream", - json_schema={}, - supported_sync_modes=[SyncMode.full_refresh, SyncMode.incremental], - default_cursor_field=["updated_at"], - source_defined_cursor=True, - source_defined_primary_key=[["id"]], - ), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.overwrite, - ) - ] - ) - - def check_connection(self, *args, **kwargs) -> Tuple[bool, Optional[Any]]: - return True, "" - - def streams(self, *args, **kwargs) -> List[Stream]: - return [HttpTestStream(authenticator=self._authenticator)] - - -class HttpTestStream(HttpStream, ABC): - url_base = "https://airbyte.com/api/v1/" - - @property - def cursor_field(self) -> Union[str, List[str]]: - return ["updated_at"] - - @property - def availability_strategy(self): - return None - - def primary_key(self) -> Optional[Union[str, List[str], List[List[str]]]]: - return "id" - - def path( - self, - *, - stream_state: Mapping[str, Any] = None, - stream_slice: Mapping[str, Any] = None, - next_page_token: Mapping[str, Any] = None, - ) -> str: - return "cast" - - def parse_response( - self, - response: requests.Response, - *, - stream_state: Mapping[str, Any], - stream_slice: Mapping[str, Any] = None, - next_page_token: Mapping[str, Any] = None, - ) -> Iterable[Mapping]: - body = response.json() or {} - return body["records"] - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - return None - - def get_json_schema(self) -> Mapping[str, Any]: - return {} - - -def fixture_mock_send(self, request, **kwargs) -> requests.Response: - """ - Helper method that can be used by a test to patch the Session.send() function and mock the outbound send operation to provide - faster and more reliable responses compared to actual API requests - """ - response = requests.Response() - response.request = request - response.status_code = 200 - response.headers = {"header": "value"} - response_body = { - "records": [ - {"id": 1, "name": "Celine Song", "position": "director"}, - {"id": 2, "name": "Shabier Kirchner", "position": "cinematographer"}, - {"id": 3, "name": "Christopher Bear", "position": "composer"}, - {"id": 4, "name": "Daniel Rossen", "position": "composer"}, - ] - } - response._content = json.dumps(response_body).encode("utf-8") - return response - - -class SourceFixtureOauthAuthenticator(Oauth2Authenticator): - """ - Test OAuth authenticator that only overrides the request and response aspect of the authenticator flow - """ - - def refresh_access_token(self) -> Tuple[str, int]: - response = requests.request(method="POST", url=self.get_token_refresh_endpoint(), params={}) - response.raise_for_status() - return "some_access_token", 1800 # Mock oauth response values to be used during the data retrieval step diff --git a/airbyte-cdk/python/unit_tests/sources/message/__init__.py b/airbyte-cdk/python/unit_tests/sources/message/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/message/test_repository.py b/airbyte-cdk/python/unit_tests/sources/message/test_repository.py deleted file mode 100644 index 48778b657cb8..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/message/test_repository.py +++ /dev/null @@ -1,144 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from unittest.mock import Mock - -import pytest -from airbyte_cdk.models import AirbyteControlConnectorConfigMessage, AirbyteControlMessage, AirbyteMessage, Level, OrchestratorType, Type -from airbyte_cdk.sources.message import ( - InMemoryMessageRepository, - LogAppenderMessageRepositoryDecorator, - MessageRepository, - NoopMessageRepository, -) - -A_CONTROL = AirbyteControlMessage( - type=OrchestratorType.CONNECTOR_CONFIG, - emitted_at=0, - connectorConfig=AirbyteControlConnectorConfigMessage(config={"a config": "value"}), -) -ANY_MESSAGE = AirbyteMessage( - type=Type.CONTROL, - control=AirbyteControlMessage( - type=OrchestratorType.CONNECTOR_CONFIG, - emitted_at=0, - connectorConfig=AirbyteControlConnectorConfigMessage(config={"any message": "value"}), - ), -) -ANOTHER_CONTROL = AirbyteControlMessage( - type=OrchestratorType.CONNECTOR_CONFIG, - emitted_at=0, - connectorConfig=AirbyteControlConnectorConfigMessage(config={"another config": "another value"}), -) -UNKNOWN_LEVEL = "potato" - - -class TestInMemoryMessageRepository: - def test_given_no_messages_when_consume_queue_then_return_empty(self): - repo = InMemoryMessageRepository() - messages = list(repo.consume_queue()) - assert messages == [] - - def test_given_messages_when_consume_queue_then_return_messages(self): - repo = InMemoryMessageRepository() - first_message = AirbyteMessage(type=Type.CONTROL, control=A_CONTROL) - repo.emit_message(first_message) - second_message = AirbyteMessage(type=Type.CONTROL, control=ANOTHER_CONTROL) - repo.emit_message(second_message) - - messages = repo.consume_queue() - - assert list(messages) == [first_message, second_message] - - def test_given_message_is_consumed_when_consume_queue_then_remove_message_from_queue(self): - repo = InMemoryMessageRepository() - first_message = AirbyteMessage(type=Type.CONTROL, control=A_CONTROL) - repo.emit_message(first_message) - second_message = AirbyteMessage(type=Type.CONTROL, control=ANOTHER_CONTROL) - repo.emit_message(second_message) - - message_generator = repo.consume_queue() - consumed_message = next(message_generator) - assert consumed_message == first_message - - second_message_generator = repo.consume_queue() - assert list(second_message_generator) == [second_message] - - def test_given_log_level_is_severe_enough_when_log_message_then_allow_message_to_be_consumed(self): - repo = InMemoryMessageRepository(Level.DEBUG) - repo.log_message(Level.INFO, lambda: {"message": "this is a log message"}) - assert list(repo.consume_queue()) - - def test_given_log_level_is_severe_enough_when_log_message_then_filter_secrets(self, mocker): - filtered_message = "a filtered message" - mocker.patch("airbyte_cdk.sources.message.repository.filter_secrets", return_value=filtered_message) - repo = InMemoryMessageRepository(Level.DEBUG) - - repo.log_message(Level.INFO, lambda: {"message": "this is a log message"}) - - assert list(repo.consume_queue())[0].log.message == filtered_message - - def test_given_log_level_not_severe_enough_when_log_message_then_do_not_allow_message_to_be_consumed(self): - repo = InMemoryMessageRepository(Level.ERROR) - repo.log_message(Level.INFO, lambda: {"message": "this is a log message"}) - assert not list(repo.consume_queue()) - - def test_given_unknown_log_level_as_threshold_when_log_message_then_allow_message_to_be_consumed(self): - repo = InMemoryMessageRepository(UNKNOWN_LEVEL) - repo.log_message(Level.DEBUG, lambda: {"message": "this is a log message"}) - assert list(repo.consume_queue()) - - -class TestNoopMessageRepository: - def test_given_message_emitted_when_consume_queue_then_return_empty(self): - repo = NoopMessageRepository() - repo.emit_message(AirbyteMessage(type=Type.CONTROL, control=A_CONTROL)) - repo.log_message(Level.INFO, lambda: {"message": "this is a log message"}) - - assert not list(repo.consume_queue()) - - -class TestLogAppenderMessageRepositoryDecorator: - - _DICT_TO_APPEND = {"airbyte_cdk": {"stream": {"is_substream": False}}} - - @pytest.fixture() - def decorated(self): - return Mock(spec=MessageRepository) - - def test_when_emit_message_then_delegate_call(self, decorated): - repo = LogAppenderMessageRepositoryDecorator(self._DICT_TO_APPEND, decorated, Level.DEBUG) - repo.emit_message(ANY_MESSAGE) - decorated.emit_message.assert_called_once_with(ANY_MESSAGE) - - def test_when_log_message_then_append(self, decorated): - repo = LogAppenderMessageRepositoryDecorator({"a": {"dict_to_append": "appended value"}}, decorated, Level.DEBUG) - repo.log_message(Level.INFO, lambda: {"a": {"original": "original value"}}) - assert decorated.log_message.call_args_list[0].args[1]() == { - "a": {"dict_to_append": "appended value", "original": "original value"} - } - - def test_given_value_clash_when_log_message_then_overwrite_value(self, decorated): - repo = LogAppenderMessageRepositoryDecorator({"clash": "appended value"}, decorated, Level.DEBUG) - repo.log_message(Level.INFO, lambda: {"clash": "original value"}) - assert decorated.log_message.call_args_list[0].args[1]() == {"clash": "appended value"} - - def test_given_log_level_is_severe_enough_when_log_message_then_allow_message_to_be_consumed(self, decorated): - repo = LogAppenderMessageRepositoryDecorator(self._DICT_TO_APPEND, decorated, Level.DEBUG) - repo.log_message(Level.INFO, lambda: {}) - assert decorated.log_message.call_count == 1 - - def test_given_log_level_not_severe_enough_when_log_message_then_do_not_allow_message_to_be_consumed(self, decorated): - repo = LogAppenderMessageRepositoryDecorator(self._DICT_TO_APPEND, decorated, Level.ERROR) - repo.log_message(Level.INFO, lambda: {}) - assert decorated.log_message.call_count == 0 - - def test_when_consume_queue_then_return_delegate_queue(self, decorated): - repo = LogAppenderMessageRepositoryDecorator(self._DICT_TO_APPEND, decorated, Level.DEBUG) - queue = [ANY_MESSAGE, ANY_MESSAGE, ANY_MESSAGE] - decorated.consume_queue.return_value = iter(queue) - - result = list(repo.consume_queue()) - - assert result == queue diff --git a/airbyte-cdk/python/unit_tests/sources/mock_server_tests/mock_source_fixture.py b/airbyte-cdk/python/unit_tests/sources/mock_server_tests/mock_source_fixture.py deleted file mode 100644 index ece5039ba465..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/mock_server_tests/mock_source_fixture.py +++ /dev/null @@ -1,390 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -import logging -from abc import ABC -from datetime import datetime, timezone -from typing import Any, Dict, Iterable, List, Mapping, MutableMapping, Optional, Tuple - -import pendulum -import requests -from airbyte_cdk.models import ConnectorSpecification, SyncMode -from airbyte_cdk.sources import AbstractSource, Source -from airbyte_cdk.sources.streams import CheckpointMixin, IncrementalMixin, Stream -from airbyte_cdk.sources.streams.core import StreamData -from airbyte_cdk.sources.streams.http import HttpStream -from airbyte_cdk.sources.streams.http.availability_strategy import HttpAvailabilityStrategy -from requests import HTTPError - - -class FixtureAvailabilityStrategy(HttpAvailabilityStrategy): - """ - Inherit from HttpAvailabilityStrategy with slight modification to 403 error message. - """ - - def reasons_for_unavailable_status_codes( - self, stream: Stream, logger: logging.Logger, source: Source, error: HTTPError - ) -> Dict[int, str]: - reasons_for_codes: Dict[int, str] = { - requests.codes.FORBIDDEN: "This is likely due to insufficient permissions for your Notion integration. " - "Please make sure your integration has read access for the resources you are trying to sync" - } - return reasons_for_codes - - -class IntegrationStream(HttpStream, ABC): - - url_base = "https://api.airbyte-test.com/v1/" - primary_key = "id" - page_size = 100 - raise_on_http_errors = True - current_page = 0 - - def __init__(self, config: Mapping[str, Any], **kwargs): - super().__init__(**kwargs) - self.start_date = config.get("start_date") - - @property - def availability_strategy(self) -> HttpAvailabilityStrategy: - return FixtureAvailabilityStrategy() - - def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapping]: - data = response.json().get("data", []) - yield from data - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - has_more = response.json().get("has_more") - if has_more: - self.current_page += 1 - return {"page": self.current_page} - else: - return None - - -class IncrementalIntegrationStream(IntegrationStream, IncrementalMixin, ABC): - cursor_field = "created_at" - _state = {} - - @property - def state(self) -> MutableMapping[str, Any]: - return self._state - - @state.setter - def state(self, value: MutableMapping[str, Any]) -> None: - self._state = value - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: Optional[List[str]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - for record in super().read_records(sync_mode, cursor_field, stream_slice, stream_state): - self.state = {self.cursor_field: record.get(self.cursor_field)} - yield record - - -class Users(IntegrationStream): - def path(self, **kwargs) -> str: - return "users" - - def get_json_schema(self) -> Mapping[str, Any]: - return { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "additionalProperties": True, - "properties": { - "type": {"type": "string"}, - "id": {"type": "string"}, - "created_at": {"type": "string", "format": "date-time"}, - "first_name": {"type": "string"}, - "last_name": {"type": "string"}, - }, - } - - -class Planets(IncrementalIntegrationStream): - def __init__(self, **kwargs): - super().__init__(**kwargs) - self._state: MutableMapping[str, Any] = {} - - def path(self, **kwargs) -> str: - return "planets" - - def get_json_schema(self) -> Mapping[str, Any]: - return { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "additionalProperties": True, - "properties": { - "type": {"type": "string"}, - "id": {"type": "string"}, - "created_at": {"type": "string", "format": "date-time"}, - "name": {"type": "string"}, - }, - } - - def request_params( - self, - stream_state: Optional[Mapping[str, Any]], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> MutableMapping[str, Any]: - return {"start_date": stream_slice.get("start_date"), "end_date": stream_slice.get("end_date")} - - def stream_slices( - self, *, sync_mode: SyncMode, cursor_field: Optional[List[str]] = None, stream_state: Optional[Mapping[str, Any]] = None - ) -> Iterable[Optional[Mapping[str, Any]]]: - start_date = pendulum.parse(self.start_date) - - if stream_state: - start_date = pendulum.parse(stream_state.get(self.cursor_field)) - - date_slices = [] - - end_date = datetime.now(timezone.utc).replace(microsecond=0) - while start_date < end_date: - end_date_slice = min(start_date.add(days=7), end_date) - - date_slice = { - "start_date": start_date.strftime("%Y-%m-%dT%H:%M:%SZ"), - "end_date": end_date_slice.strftime("%Y-%m-%dT%H:%M:%SZ"), - } - - date_slices.append(date_slice) - start_date = end_date_slice - - return date_slices - - -class Legacies(IntegrationStream): - """ - Incremental stream that uses the legacy method get_updated_state() to manage stream state. New connectors use the state - property and setter methods. - """ - - cursor_field = "created_at" - - def path(self, **kwargs) -> str: - return "legacies" - - def get_json_schema(self) -> Mapping[str, Any]: - return { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "additionalProperties": True, - "properties": { - "type": {"type": "string"}, - "id": {"type": "string"}, - "created_at": {"type": "string", "format": "date-time"}, - "quote": {"type": "string"}, - }, - } - - def get_updated_state( - self, current_stream_state: MutableMapping[str, Any], latest_record: Mapping[str, Any] - ) -> MutableMapping[str, Any]: - latest_state = latest_record.get(self.cursor_field) - current_state = current_stream_state.get(self.cursor_field) or latest_state - if current_state: - return {self.cursor_field: max(latest_state, current_state)} - return {} - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: Optional[List[str]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - yield from super().read_records(sync_mode, cursor_field, stream_slice, stream_state) - - def request_params( - self, - stream_state: Optional[Mapping[str, Any]], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> MutableMapping[str, Any]: - return {"start_date": stream_slice.get("start_date"), "end_date": stream_slice.get("end_date")} - - def stream_slices( - self, *, sync_mode: SyncMode, cursor_field: Optional[List[str]] = None, stream_state: Optional[Mapping[str, Any]] = None - ) -> Iterable[Optional[Mapping[str, Any]]]: - start_date = pendulum.parse(self.start_date) - - if stream_state: - start_date = pendulum.parse(stream_state.get(self.cursor_field)) - - date_slices = [] - - end_date = datetime.now(timezone.utc).replace(microsecond=0) - while start_date < end_date: - end_date_slice = min(start_date.add(days=7), end_date) - - date_slice = { - "start_date": start_date.strftime("%Y-%m-%dT%H:%M:%SZ"), - "end_date": end_date_slice.strftime("%Y-%m-%dT%H:%M:%SZ"), - } - - date_slices.append(date_slice) - start_date = end_date_slice - - return date_slices - - -class Dividers(IntegrationStream): - def path(self, **kwargs) -> str: - return "dividers" - - def get_json_schema(self) -> Mapping[str, Any]: - return { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "additionalProperties": True, - "properties": { - "type": {"type": "string"}, - "id": {"type": "string"}, - "created_at": {"type": "string", "format": "date-time"}, - "divide_category": {"type": "string"}, - }, - } - - def stream_slices( - self, *, sync_mode: SyncMode, cursor_field: Optional[List[str]] = None, stream_state: Optional[Mapping[str, Any]] = None - ) -> Iterable[Optional[Mapping[str, Any]]]: - return [{"divide_category": "dukes"}, {"divide_category": "mentats"}] - - def request_params( - self, - stream_state: Optional[Mapping[str, Any]], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> MutableMapping[str, Any]: - return {"category": stream_slice.get("divide_category")} - - -class JusticeSongs(HttpStream, CheckpointMixin, ABC): - url_base = "https://api.airbyte-test.com/v1/" - primary_key = "id" - - def __init__(self, config: Mapping[str, Any], **kwargs): - super().__init__(**kwargs) - self._state: MutableMapping[str, Any] = {} - - def path(self, **kwargs) -> str: - return "justice_songs" - - def get_json_schema(self) -> Mapping[str, Any]: - return { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "additionalProperties": True, - "properties": { - "type": {"type": "string"}, - "id": {"type": "string"}, - "created_at": {"type": "string", "format": "date-time"}, - "name": {"type": "string"}, - "album": {"type": "string"}, - }, - } - - @property - def availability_strategy(self) -> HttpAvailabilityStrategy: - return FixtureAvailabilityStrategy() - - def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapping]: - data = response.json().get("data", []) - yield from data - - @property - def state(self) -> MutableMapping[str, Any]: - return self._state - - @state.setter - def state(self, value: MutableMapping[str, Any]) -> None: - self._state = value - - def request_params( - self, - stream_state: Optional[Mapping[str, Any]], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> MutableMapping[str, Any]: - return {"page": next_page_token.get("page")} - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: Optional[List[str]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - yield from self._read_single_page(cursor_field, stream_slice, stream_state) - - def _read_single_page( - self, - cursor_field: Optional[List[str]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - next_page_token = stream_slice - request_headers = self.request_headers(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token) - request_params = self.request_params(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token) - - request, response = self._http_client.send_request( - http_method=self.http_method, - url=self._join_url( - self.url_base, - self.path(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - ), - request_kwargs=self.request_kwargs(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - headers=request_headers, - params=request_params, - json=self.request_body_json(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - data=self.request_body_data(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token), - dedupe_query_params=True, - ) - yield from self.parse_response(response=response) - - self.next_page_token(response) - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - current_page = self._state.get("page") or 0 - has_more = response.json().get("has_more") - if has_more: - self._state = {"page": current_page + 1} - else: - self._state = {"__ab_full_refresh_sync_complete": True} - - -class SourceFixture(AbstractSource): - def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, any]: - return True, None - - def streams(self, config: Mapping[str, Any]) -> List[Stream]: - return [ - Dividers(config=config), - JusticeSongs(config=config), - Legacies(config=config), - Planets(config=config), - Users(config=config), - ] - - def spec(self, logger: logging.Logger) -> ConnectorSpecification: - return ConnectorSpecification( - connectionSpecification={ - "properties": { - "start_date": { - "title": "Start Date", - "description": "UTC date and time in the format YYYY-MM-DDTHH:MM:SS.000Z. During incremental sync, any data generated before this date will not be replicated. If left blank, the start date will be set to 2 years before the present date.", - "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$", - "pattern_descriptor": "YYYY-MM-DDTHH:MM:SS.000Z", - "examples": ["2020-11-16T00:00:00.000Z"], - "type": "string", - "format": "date-time", - } - } - } - ) diff --git a/airbyte-cdk/python/unit_tests/sources/mock_server_tests/test_helpers/__init__.py b/airbyte-cdk/python/unit_tests/sources/mock_server_tests/test_helpers/__init__.py deleted file mode 100644 index 7cad347c9fde..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/mock_server_tests/test_helpers/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from .airbyte_message_assertions import emits_successful_sync_status_messages, validate_message_order - -__all__ = ["emits_successful_sync_status_messages", "validate_message_order"] diff --git a/airbyte-cdk/python/unit_tests/sources/mock_server_tests/test_helpers/airbyte_message_assertions.py b/airbyte-cdk/python/unit_tests/sources/mock_server_tests/test_helpers/airbyte_message_assertions.py deleted file mode 100644 index 04b65594cf01..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/mock_server_tests/test_helpers/airbyte_message_assertions.py +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from typing import List - -import pytest -from airbyte_cdk.models import AirbyteMessage, AirbyteStreamStatus, Type - - -def emits_successful_sync_status_messages(status_messages: List[AirbyteStreamStatus]) -> bool: - return ( - len(status_messages) == 3 - and status_messages[0] == AirbyteStreamStatus.STARTED - and status_messages[1] == AirbyteStreamStatus.RUNNING - and status_messages[2] == AirbyteStreamStatus.COMPLETE - ) - - -def validate_message_order(expected_message_order: List[Type], messages: List[AirbyteMessage]): - if len(expected_message_order) != len(messages): - pytest.fail(f"Expected message order count {len(expected_message_order)} did not match actual messages {len(messages)}") - - for i, message in enumerate(messages): - if message.type != expected_message_order[i]: - pytest.fail( - f"At index {i} actual message type {message.type.name} did not match expected message type {expected_message_order[i].name}" - ) diff --git a/airbyte-cdk/python/unit_tests/sources/mock_server_tests/test_mock_server_abstract_source.py b/airbyte-cdk/python/unit_tests/sources/mock_server_tests/test_mock_server_abstract_source.py deleted file mode 100644 index c7fd2cef433e..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/mock_server_tests/test_mock_server_abstract_source.py +++ /dev/null @@ -1,552 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from datetime import datetime, timedelta, timezone -from typing import List, Optional -from unittest import TestCase - -import freezegun -from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, SyncMode, Type -from airbyte_cdk.test.catalog_builder import CatalogBuilder -from airbyte_cdk.test.entrypoint_wrapper import read -from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest -from airbyte_cdk.test.mock_http.response_builder import ( - FieldPath, - FieldUpdatePaginationStrategy, - HttpResponseBuilder, - RecordBuilder, - create_record_builder, - create_response_builder, -) -from airbyte_cdk.test.state_builder import StateBuilder -from unit_tests.sources.mock_server_tests.mock_source_fixture import SourceFixture -from unit_tests.sources.mock_server_tests.test_helpers import emits_successful_sync_status_messages, validate_message_order - -_NOW = datetime.now(timezone.utc) - - -class RequestBuilder: - @classmethod - def dividers_endpoint(cls) -> "RequestBuilder": - return cls("dividers") - - @classmethod - def justice_songs_endpoint(cls) -> "RequestBuilder": - return cls("justice_songs") - - @classmethod - def legacies_endpoint(cls) -> "RequestBuilder": - return cls("legacies") - - @classmethod - def planets_endpoint(cls) -> "RequestBuilder": - return cls("planets") - - @classmethod - def users_endpoint(cls) -> "RequestBuilder": - return cls("users") - - def __init__(self, resource: str) -> None: - self._resource = resource - self._start_date: Optional[datetime] = None - self._end_date: Optional[datetime] = None - self._category: Optional[str] = None - self._page: Optional[int] = None - - def with_start_date(self, start_date: datetime) -> "RequestBuilder": - self._start_date = start_date - return self - - def with_end_date(self, end_date: datetime) -> "RequestBuilder": - self._end_date = end_date - return self - - def with_category(self, category: str) -> "RequestBuilder": - self._category = category - return self - - def with_page(self, page: int) -> "RequestBuilder": - self._page = page - return self - - def build(self) -> HttpRequest: - query_params = {} - if self._start_date: - query_params["start_date"] = self._start_date.strftime("%Y-%m-%dT%H:%M:%SZ") - if self._end_date: - query_params["end_date"] = self._end_date.strftime("%Y-%m-%dT%H:%M:%SZ") - if self._category: - query_params["category"] = self._category - if self._page: - query_params["page"] = self._page - - return HttpRequest( - url=f"https://api.airbyte-test.com/v1/{self._resource}", - query_params=query_params, - ) - - -def _create_catalog(names_and_sync_modes: List[tuple[str, SyncMode]]) -> ConfiguredAirbyteCatalog: - catalog_builder = CatalogBuilder() - for stream_name, sync_mode in names_and_sync_modes: - catalog_builder.with_stream(name=stream_name, sync_mode=sync_mode) - return catalog_builder.build() - - -def _create_dividers_request() -> RequestBuilder: - return RequestBuilder.dividers_endpoint() - - -def _create_legacies_request() -> RequestBuilder: - return RequestBuilder.legacies_endpoint() - - -def _create_planets_request() -> RequestBuilder: - return RequestBuilder.planets_endpoint() - - -def _create_users_request() -> RequestBuilder: - return RequestBuilder.users_endpoint() - - -def _create_justice_songs_request() -> RequestBuilder: - return RequestBuilder.justice_songs_endpoint() - - -RESPONSE_TEMPLATE = {"object": "list", "has_more": False, "data": [{"id": "123", "created_at": "2024-01-01T07:04:28.000Z"}]} - -USER_TEMPLATE = { - "object": "list", - "has_more": False, - "data": [ - { - "id": "123", - "created_at": "2024-01-01T07:04:28", - "first_name": "Paul", - "last_name": "Atreides", - } - ], -} - -PLANET_TEMPLATE = { - "object": "list", - "has_more": False, - "data": [ - { - "id": "456", - "created_at": "2024-01-01T07:04:28.000Z", - "name": "Giedi Prime", - } - ], -} - -LEGACY_TEMPLATE = { - "object": "list", - "has_more": False, - "data": [ - { - "id": "l3g4cy", - "created_at": "2024-02-01T07:04:28.000Z", - "quote": "What do you leave behind?", - } - ], -} - -DIVIDER_TEMPLATE = { - "object": "list", - "has_more": False, - "data": [ - { - "id": "l3t0", - "created_at": "2024-02-01T07:04:28.000Z", - "divide_category": "dukes", - } - ], -} - - -JUSTICE_SONGS_TEMPLATE = { - "object": "list", - "has_more": False, - "data": [ - { - "id": "cross_01", - "created_at": "2024-02-01T07:04:28.000Z", - "name": "Genesis", - "album": "Cross", - }, - { - "id": "hyperdrama_01", - "created_at": "2024-02-01T07:04:28.000Z", - "name": "dukes", - "album": "", - }, - ], -} - - -RESOURCE_TO_TEMPLATE = { - "dividers": DIVIDER_TEMPLATE, - "justice_songs": JUSTICE_SONGS_TEMPLATE, - "legacies": LEGACY_TEMPLATE, - "planets": PLANET_TEMPLATE, - "users": USER_TEMPLATE, -} - - -def _create_response(pagination_has_more: bool = False) -> HttpResponseBuilder: - return create_response_builder( - response_template=RESPONSE_TEMPLATE, - records_path=FieldPath("data"), - pagination_strategy=FieldUpdatePaginationStrategy(FieldPath("has_more"), pagination_has_more), - ) - - -def _create_record(resource: str) -> RecordBuilder: - return create_record_builder( - response_template=RESOURCE_TO_TEMPLATE.get(resource), - records_path=FieldPath("data"), - record_id_path=FieldPath("id"), - record_cursor_path=FieldPath("created_at"), - ) - - -class FullRefreshStreamTest(TestCase): - @HttpMocker() - def test_full_refresh_sync(self, http_mocker): - start_datetime = _NOW - timedelta(days=14) - config = {"start_date": start_datetime.strftime("%Y-%m-%dT%H:%M:%SZ")} - - http_mocker.get( - _create_users_request().build(), - _create_response().with_record(record=_create_record("users")).with_record(record=_create_record("users")).build(), - ) - - source = SourceFixture() - actual_messages = read(source, config=config, catalog=_create_catalog([("users", SyncMode.full_refresh)])) - - assert emits_successful_sync_status_messages(actual_messages.get_stream_statuses("users")) - assert len(actual_messages.records) == 2 - assert len(actual_messages.state_messages) == 1 - validate_message_order([Type.RECORD, Type.RECORD, Type.STATE], actual_messages.records_and_state_messages) - assert actual_messages.state_messages[0].state.stream.stream_descriptor.name == "users" - assert actual_messages.state_messages[0].state.stream.stream_state == AirbyteStateBlob(__ab_full_refresh_sync_complete=True) - assert actual_messages.state_messages[0].state.sourceStats.recordCount == 2.0 - - @HttpMocker() - def test_substream_resumable_full_refresh_with_parent_slices(self, http_mocker): - start_datetime = _NOW - timedelta(days=14) - config = {"start_date": start_datetime.strftime("%Y-%m-%dT%H:%M:%SZ")} - - expected_first_substream_per_stream_state = [ - {"partition": {"divide_category": "dukes"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - ] - - expected_second_substream_per_stream_state = [ - {"partition": {"divide_category": "dukes"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - {"partition": {"divide_category": "mentats"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - ] - - http_mocker.get( - _create_dividers_request().with_category("dukes").build(), - _create_response().with_record(record=_create_record("dividers")).with_record(record=_create_record("dividers")).build(), - ) - - http_mocker.get( - _create_dividers_request().with_category("mentats").build(), - _create_response().with_record(record=_create_record("dividers")).with_record(record=_create_record("dividers")).build(), - ) - - source = SourceFixture() - actual_messages = read(source, config=config, catalog=_create_catalog([("dividers", SyncMode.full_refresh)])) - - assert emits_successful_sync_status_messages(actual_messages.get_stream_statuses("dividers")) - assert len(actual_messages.records) == 4 - assert len(actual_messages.state_messages) == 2 - validate_message_order( - [Type.RECORD, Type.RECORD, Type.STATE, Type.RECORD, Type.RECORD, Type.STATE], actual_messages.records_and_state_messages - ) - assert actual_messages.state_messages[0].state.stream.stream_state == AirbyteStateBlob( - states=expected_first_substream_per_stream_state - ) - assert actual_messages.state_messages[0].state.sourceStats.recordCount == 2.0 - assert actual_messages.state_messages[1].state.stream.stream_state == AirbyteStateBlob( - states=expected_second_substream_per_stream_state - ) - assert actual_messages.state_messages[1].state.sourceStats.recordCount == 2.0 - - -@freezegun.freeze_time(_NOW) -class IncrementalStreamTest(TestCase): - @HttpMocker() - def test_incremental_sync(self, http_mocker): - start_datetime = _NOW - timedelta(days=14) - config = {"start_date": start_datetime.strftime("%Y-%m-%dT%H:%M:%SZ")} - - last_record_date_0 = (start_datetime + timedelta(days=4)).strftime("%Y-%m-%dT%H:%M:%SZ") - http_mocker.get( - _create_planets_request().with_start_date(start_datetime).with_end_date(start_datetime + timedelta(days=7)).build(), - _create_response() - .with_record(record=_create_record("planets").with_cursor(last_record_date_0)) - .with_record(record=_create_record("planets").with_cursor(last_record_date_0)) - .with_record(record=_create_record("planets").with_cursor(last_record_date_0)) - .build(), - ) - - last_record_date_1 = (_NOW - timedelta(days=1)).strftime("%Y-%m-%dT%H:%M:%SZ") - http_mocker.get( - _create_planets_request().with_start_date(start_datetime + timedelta(days=7)).with_end_date(_NOW).build(), - _create_response() - .with_record(record=_create_record("planets").with_cursor(last_record_date_1)) - .with_record(record=_create_record("planets").with_cursor(last_record_date_1)) - .build(), - ) - - source = SourceFixture() - actual_messages = read(source, config=config, catalog=_create_catalog([("planets", SyncMode.incremental)])) - - assert emits_successful_sync_status_messages(actual_messages.get_stream_statuses("planets")) - assert len(actual_messages.records) == 5 - assert len(actual_messages.state_messages) == 2 - validate_message_order( - [Type.RECORD, Type.RECORD, Type.RECORD, Type.STATE, Type.RECORD, Type.RECORD, Type.STATE], - actual_messages.records_and_state_messages, - ) - assert actual_messages.state_messages[0].state.stream.stream_descriptor.name == "planets" - assert actual_messages.state_messages[0].state.stream.stream_state == AirbyteStateBlob(created_at=last_record_date_0) - assert actual_messages.state_messages[0].state.sourceStats.recordCount == 3.0 - assert actual_messages.state_messages[1].state.stream.stream_descriptor.name == "planets" - assert actual_messages.state_messages[1].state.stream.stream_state == AirbyteStateBlob(created_at=last_record_date_1) - assert actual_messages.state_messages[1].state.sourceStats.recordCount == 2.0 - - @HttpMocker() - def test_incremental_running_as_full_refresh(self, http_mocker): - start_datetime = _NOW - timedelta(days=14) - config = {"start_date": start_datetime.strftime("%Y-%m-%dT%H:%M:%SZ")} - - last_record_date_0 = (start_datetime + timedelta(days=4)).strftime("%Y-%m-%dT%H:%M:%SZ") - http_mocker.get( - _create_planets_request().with_start_date(start_datetime).with_end_date(start_datetime + timedelta(days=7)).build(), - _create_response() - .with_record(record=_create_record("planets").with_cursor(last_record_date_0)) - .with_record(record=_create_record("planets").with_cursor(last_record_date_0)) - .with_record(record=_create_record("planets").with_cursor(last_record_date_0)) - .build(), - ) - - last_record_date_1 = (_NOW - timedelta(days=1)).strftime("%Y-%m-%dT%H:%M:%SZ") - http_mocker.get( - _create_planets_request().with_start_date(start_datetime + timedelta(days=7)).with_end_date(_NOW).build(), - _create_response() - .with_record(record=_create_record("planets").with_cursor(last_record_date_1)) - .with_record(record=_create_record("planets").with_cursor(last_record_date_1)) - .build(), - ) - - source = SourceFixture() - actual_messages = read(source, config=config, catalog=_create_catalog([("planets", SyncMode.full_refresh)])) - - assert emits_successful_sync_status_messages(actual_messages.get_stream_statuses("planets")) - assert len(actual_messages.records) == 5 - assert len(actual_messages.state_messages) == 2 - validate_message_order( - [Type.RECORD, Type.RECORD, Type.RECORD, Type.STATE, Type.RECORD, Type.RECORD, Type.STATE], - actual_messages.records_and_state_messages, - ) - - assert actual_messages.state_messages[0].state.stream.stream_descriptor.name == "planets" - assert actual_messages.state_messages[0].state.stream.stream_state == AirbyteStateBlob(created_at=last_record_date_0) - assert actual_messages.state_messages[0].state.sourceStats.recordCount == 3.0 - assert actual_messages.state_messages[1].state.stream.stream_descriptor.name == "planets" - assert actual_messages.state_messages[1].state.stream.stream_state == AirbyteStateBlob(created_at=last_record_date_1) - assert actual_messages.state_messages[1].state.sourceStats.recordCount == 2.0 - - @HttpMocker() - def test_legacy_incremental_sync(self, http_mocker): - start_datetime = _NOW - timedelta(days=14) - config = {"start_date": start_datetime.strftime("%Y-%m-%dT%H:%M:%SZ")} - - last_record_date_0 = (start_datetime + timedelta(days=4)).strftime("%Y-%m-%dT%H:%M:%SZ") - http_mocker.get( - _create_legacies_request().with_start_date(start_datetime).with_end_date(start_datetime + timedelta(days=7)).build(), - _create_response() - .with_record(record=_create_record("legacies").with_cursor(last_record_date_0)) - .with_record(record=_create_record("legacies").with_cursor(last_record_date_0)) - .with_record(record=_create_record("legacies").with_cursor(last_record_date_0)) - .build(), - ) - - last_record_date_1 = (_NOW - timedelta(days=1)).strftime("%Y-%m-%dT%H:%M:%SZ") - http_mocker.get( - _create_legacies_request().with_start_date(start_datetime + timedelta(days=7)).with_end_date(_NOW).build(), - _create_response() - .with_record(record=_create_record("legacies").with_cursor(last_record_date_1)) - .with_record(record=_create_record("legacies").with_cursor(last_record_date_1)) - .build(), - ) - - source = SourceFixture() - actual_messages = read(source, config=config, catalog=_create_catalog([("legacies", SyncMode.incremental)])) - - assert emits_successful_sync_status_messages(actual_messages.get_stream_statuses("legacies")) - assert len(actual_messages.records) == 5 - assert len(actual_messages.state_messages) == 2 - validate_message_order( - [Type.RECORD, Type.RECORD, Type.RECORD, Type.STATE, Type.RECORD, Type.RECORD, Type.STATE], - actual_messages.records_and_state_messages, - ) - assert actual_messages.state_messages[0].state.stream.stream_descriptor.name == "legacies" - assert actual_messages.state_messages[0].state.stream.stream_state == AirbyteStateBlob(created_at=last_record_date_0) - assert actual_messages.state_messages[0].state.sourceStats.recordCount == 3.0 - assert actual_messages.state_messages[1].state.stream.stream_descriptor.name == "legacies" - assert actual_messages.state_messages[1].state.stream.stream_state == AirbyteStateBlob(created_at=last_record_date_1) - assert actual_messages.state_messages[1].state.sourceStats.recordCount == 2.0 - - @HttpMocker() - def test_legacy_no_records_retains_incoming_state(self, http_mocker): - start_datetime = _NOW - timedelta(days=14) - config = {"start_date": start_datetime.strftime("%Y-%m-%dT%H:%M:%SZ")} - - last_record_date_1 = (_NOW - timedelta(days=1)).strftime("%Y-%m-%dT%H:%M:%SZ") - http_mocker.get( - _create_legacies_request().with_start_date(_NOW - timedelta(days=1)).with_end_date(_NOW).build(), - _create_response().build(), - ) - - incoming_state = AirbyteStateBlob(created_at=last_record_date_1) - state = StateBuilder().with_stream_state("legacies", incoming_state).build() - - source = SourceFixture() - actual_messages = read(source, config=config, catalog=_create_catalog([("legacies", SyncMode.incremental)]), state=state) - - assert actual_messages.state_messages[0].state.stream.stream_descriptor.name == "legacies" - assert actual_messages.state_messages[0].state.stream.stream_state == incoming_state - assert actual_messages.state_messages[0].state.sourceStats.recordCount == 0.0 - - @HttpMocker() - def test_legacy_no_slices_retains_incoming_state(self, http_mocker): - start_datetime = _NOW - timedelta(days=14) - config = {"start_date": start_datetime.strftime("%Y-%m-%dT%H:%M:%SZ")} - - last_record_date_1 = _NOW.strftime("%Y-%m-%dT%H:%M:%SZ") - - incoming_state = AirbyteStateBlob(created_at=last_record_date_1) - state = StateBuilder().with_stream_state("legacies", incoming_state).build() - - source = SourceFixture() - actual_messages = read(source, config=config, catalog=_create_catalog([("legacies", SyncMode.incremental)]), state=state) - - assert actual_messages.state_messages[0].state.stream.stream_descriptor.name == "legacies" - assert actual_messages.state_messages[0].state.stream.stream_state == incoming_state - assert actual_messages.state_messages[0].state.sourceStats.recordCount == 0.0 - - -@freezegun.freeze_time(_NOW) -class MultipleStreamTest(TestCase): - @HttpMocker() - def test_incremental_and_full_refresh_streams(self, http_mocker): - start_datetime = _NOW - timedelta(days=14) - config = {"start_date": start_datetime.strftime("%Y-%m-%dT%H:%M:%SZ")} - - expected_first_substream_per_stream_state = [ - {"partition": {"divide_category": "dukes"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - ] - - expected_second_substream_per_stream_state = [ - {"partition": {"divide_category": "dukes"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - {"partition": {"divide_category": "mentats"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - ] - - # Mocks for users full refresh stream - http_mocker.get( - _create_users_request().build(), - _create_response().with_record(record=_create_record("users")).with_record(record=_create_record("users")).build(), - ) - - # Mocks for planets incremental stream - last_record_date_0 = (start_datetime + timedelta(days=4)).strftime("%Y-%m-%dT%H:%M:%SZ") - http_mocker.get( - _create_planets_request().with_start_date(start_datetime).with_end_date(start_datetime + timedelta(days=7)).build(), - _create_response() - .with_record(record=_create_record("planets").with_cursor(last_record_date_0)) - .with_record(record=_create_record("planets").with_cursor(last_record_date_0)) - .with_record(record=_create_record("planets").with_cursor(last_record_date_0)) - .build(), - ) - - last_record_date_1 = (_NOW - timedelta(days=1)).strftime("%Y-%m-%dT%H:%M:%SZ") - http_mocker.get( - _create_planets_request().with_start_date(start_datetime + timedelta(days=7)).with_end_date(_NOW).build(), - _create_response() - .with_record(record=_create_record("planets").with_cursor(last_record_date_1)) - .with_record(record=_create_record("planets").with_cursor(last_record_date_1)) - .build(), - ) - - # Mocks for dividers full refresh stream - http_mocker.get( - _create_dividers_request().with_category("dukes").build(), - _create_response().with_record(record=_create_record("dividers")).with_record(record=_create_record("dividers")).build(), - ) - - http_mocker.get( - _create_dividers_request().with_category("mentats").build(), - _create_response().with_record(record=_create_record("dividers")).with_record(record=_create_record("dividers")).build(), - ) - - source = SourceFixture() - actual_messages = read( - source, - config=config, - catalog=_create_catalog( - [("users", SyncMode.full_refresh), ("planets", SyncMode.incremental), ("dividers", SyncMode.full_refresh)] - ), - ) - - assert emits_successful_sync_status_messages(actual_messages.get_stream_statuses("users")) - assert emits_successful_sync_status_messages(actual_messages.get_stream_statuses("planets")) - assert emits_successful_sync_status_messages(actual_messages.get_stream_statuses("dividers")) - - assert len(actual_messages.records) == 11 - assert len(actual_messages.state_messages) == 5 - validate_message_order( - [ - Type.RECORD, - Type.RECORD, - Type.STATE, - Type.RECORD, - Type.RECORD, - Type.RECORD, - Type.STATE, - Type.RECORD, - Type.RECORD, - Type.STATE, - Type.RECORD, - Type.RECORD, - Type.STATE, - Type.RECORD, - Type.RECORD, - Type.STATE, - ], - actual_messages.records_and_state_messages, - ) - assert actual_messages.state_messages[0].state.stream.stream_descriptor.name == "users" - assert actual_messages.state_messages[0].state.stream.stream_state == AirbyteStateBlob(__ab_full_refresh_sync_complete=True) - assert actual_messages.state_messages[0].state.sourceStats.recordCount == 2.0 - assert actual_messages.state_messages[1].state.stream.stream_descriptor.name == "planets" - assert actual_messages.state_messages[1].state.stream.stream_state == AirbyteStateBlob(created_at=last_record_date_0) - assert actual_messages.state_messages[1].state.sourceStats.recordCount == 3.0 - assert actual_messages.state_messages[2].state.stream.stream_descriptor.name == "planets" - assert actual_messages.state_messages[2].state.stream.stream_state == AirbyteStateBlob(created_at=last_record_date_1) - assert actual_messages.state_messages[2].state.sourceStats.recordCount == 2.0 - assert actual_messages.state_messages[3].state.stream.stream_descriptor.name == "dividers" - assert actual_messages.state_messages[3].state.stream.stream_state == AirbyteStateBlob( - states=expected_first_substream_per_stream_state - ) - assert actual_messages.state_messages[3].state.sourceStats.recordCount == 2.0 - assert actual_messages.state_messages[4].state.stream.stream_descriptor.name == "dividers" - assert actual_messages.state_messages[4].state.stream.stream_state == AirbyteStateBlob( - states=expected_second_substream_per_stream_state - ) - assert actual_messages.state_messages[4].state.sourceStats.recordCount == 2.0 diff --git a/airbyte-cdk/python/unit_tests/sources/mock_server_tests/test_resumable_full_refresh.py b/airbyte-cdk/python/unit_tests/sources/mock_server_tests/test_resumable_full_refresh.py deleted file mode 100644 index f5a9e8578ab9..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/mock_server_tests/test_resumable_full_refresh.py +++ /dev/null @@ -1,278 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from datetime import datetime, timezone -from typing import Any, Dict, List, Optional -from unittest import TestCase - -import freezegun -from airbyte_cdk.models import AirbyteStateBlob, AirbyteStreamStatus, ConfiguredAirbyteCatalog, FailureType, SyncMode, Type -from airbyte_cdk.test.catalog_builder import ConfiguredAirbyteStreamBuilder -from airbyte_cdk.test.entrypoint_wrapper import read -from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest -from airbyte_cdk.test.mock_http.response_builder import ( - FieldPath, - FieldUpdatePaginationStrategy, - HttpResponseBuilder, - RecordBuilder, - create_record_builder, - create_response_builder, -) -from airbyte_cdk.test.state_builder import StateBuilder -from unit_tests.sources.mock_server_tests.mock_source_fixture import SourceFixture -from unit_tests.sources.mock_server_tests.test_helpers import emits_successful_sync_status_messages, validate_message_order - -_NOW = datetime.now(timezone.utc) - - -class RequestBuilder: - @classmethod - def justice_songs_endpoint(cls) -> "RequestBuilder": - return cls("justice_songs") - - def __init__(self, resource: str) -> None: - self._resource = resource - self._page: Optional[int] = None - - def with_page(self, page: int) -> "RequestBuilder": - self._page = page - return self - - def build(self) -> HttpRequest: - query_params = {} - if self._page: - query_params["page"] = self._page - - return HttpRequest( - url=f"https://api.airbyte-test.com/v1/{self._resource}", - query_params=query_params, - ) - - -def _create_catalog(names_and_sync_modes: List[tuple[str, SyncMode, Dict[str, Any]]]) -> ConfiguredAirbyteCatalog: - stream_builder = ConfiguredAirbyteStreamBuilder() - streams = [] - for stream_name, sync_mode, json_schema in names_and_sync_modes: - streams.append(stream_builder.with_name(stream_name).with_sync_mode(sync_mode).with_json_schema(json_schema or {})) - - return ConfiguredAirbyteCatalog(streams=list(map(lambda builder: builder.build(), streams))) - - -def _create_justice_songs_request() -> RequestBuilder: - return RequestBuilder.justice_songs_endpoint() - - -RESPONSE_TEMPLATE = {"object": "list", "has_more": False, "data": [{"id": "123", "created_at": "2024-01-01T07:04:28.000Z"}]} - - -JUSTICE_SONGS_TEMPLATE = { - "object": "list", - "has_more": False, - "data": [ - { - "id": "cross_01", - "created_at": "2024-02-01T07:04:28.000Z", - "name": "Genesis", - "album": "Cross", - }, - { - "id": "hyperdrama_01", - "created_at": "2024-02-01T07:04:28.000Z", - "name": "dukes", - "album": "", - }, - ], -} - - -RESOURCE_TO_TEMPLATE = { - "justice_songs": JUSTICE_SONGS_TEMPLATE, -} - - -def _create_response(pagination_has_more: bool = False) -> HttpResponseBuilder: - return create_response_builder( - response_template=RESPONSE_TEMPLATE, - records_path=FieldPath("data"), - pagination_strategy=FieldUpdatePaginationStrategy(FieldPath("has_more"), pagination_has_more), - ) - - -def _create_record(resource: str) -> RecordBuilder: - return create_record_builder( - response_template=RESOURCE_TO_TEMPLATE.get(resource), - records_path=FieldPath("data"), - record_id_path=FieldPath("id"), - record_cursor_path=FieldPath("created_at"), - ) - - -@freezegun.freeze_time(_NOW) -class ResumableFullRefreshStreamTest(TestCase): - @HttpMocker() - def test_resumable_full_refresh_sync(self, http_mocker): - config = {} - - http_mocker.get( - _create_justice_songs_request().build(), - _create_response(pagination_has_more=True) - .with_pagination() - .with_record(record=_create_record("justice_songs")) - .with_record(record=_create_record("justice_songs")) - .build(), - ) - - http_mocker.get( - _create_justice_songs_request().with_page(1).build(), - _create_response(pagination_has_more=True) - .with_pagination() - .with_record(record=_create_record("justice_songs")) - .with_record(record=_create_record("justice_songs")) - .build(), - ) - - http_mocker.get( - _create_justice_songs_request().with_page(2).build(), - _create_response(pagination_has_more=False).with_pagination().with_record(record=_create_record("justice_songs")).build(), - ) - - source = SourceFixture() - actual_messages = read(source, config=config, catalog=_create_catalog([("justice_songs", SyncMode.full_refresh, {})])) - - assert emits_successful_sync_status_messages(actual_messages.get_stream_statuses("justice_songs")) - assert len(actual_messages.records) == 5 - assert len(actual_messages.state_messages) == 4 - validate_message_order( - [Type.RECORD, Type.RECORD, Type.STATE, Type.RECORD, Type.RECORD, Type.STATE, Type.RECORD, Type.STATE, Type.STATE], - actual_messages.records_and_state_messages, - ) - assert actual_messages.state_messages[0].state.stream.stream_descriptor.name == "justice_songs" - assert actual_messages.state_messages[0].state.stream.stream_state == AirbyteStateBlob(page=1) - assert actual_messages.state_messages[0].state.sourceStats.recordCount == 2.0 - assert actual_messages.state_messages[1].state.stream.stream_descriptor.name == "justice_songs" - assert actual_messages.state_messages[1].state.stream.stream_state == AirbyteStateBlob(page=2) - assert actual_messages.state_messages[1].state.sourceStats.recordCount == 2.0 - assert actual_messages.state_messages[2].state.stream.stream_descriptor.name == "justice_songs" - assert actual_messages.state_messages[2].state.stream.stream_state == AirbyteStateBlob(__ab_full_refresh_sync_complete=True) - assert actual_messages.state_messages[2].state.sourceStats.recordCount == 1.0 - assert actual_messages.state_messages[3].state.stream.stream_descriptor.name == "justice_songs" - assert actual_messages.state_messages[3].state.stream.stream_state == AirbyteStateBlob(__ab_full_refresh_sync_complete=True) - assert actual_messages.state_messages[3].state.sourceStats.recordCount == 0.0 - - @HttpMocker() - def test_resumable_full_refresh_second_attempt(self, http_mocker): - config = {} - - state = StateBuilder().with_stream_state("justice_songs", {"page": 100}).build() - - http_mocker.get( - _create_justice_songs_request().with_page(100).build(), - _create_response(pagination_has_more=True) - .with_pagination() - .with_record(record=_create_record("justice_songs")) - .with_record(record=_create_record("justice_songs")) - .with_record(record=_create_record("justice_songs")) - .build(), - ) - - http_mocker.get( - _create_justice_songs_request().with_page(101).build(), - _create_response(pagination_has_more=True) - .with_pagination() - .with_record(record=_create_record("justice_songs")) - .with_record(record=_create_record("justice_songs")) - .with_record(record=_create_record("justice_songs")) - .build(), - ) - - http_mocker.get( - _create_justice_songs_request().with_page(102).build(), - _create_response(pagination_has_more=False) - .with_pagination() - .with_record(record=_create_record("justice_songs")) - .with_record(record=_create_record("justice_songs")) - .build(), - ) - - source = SourceFixture() - actual_messages = read(source, config=config, catalog=_create_catalog([("justice_songs", SyncMode.full_refresh, {})]), state=state) - - assert emits_successful_sync_status_messages(actual_messages.get_stream_statuses("justice_songs")) - assert len(actual_messages.records) == 8 - assert len(actual_messages.state_messages) == 4 - validate_message_order( - [ - Type.RECORD, - Type.RECORD, - Type.RECORD, - Type.STATE, - Type.RECORD, - Type.RECORD, - Type.RECORD, - Type.STATE, - Type.RECORD, - Type.RECORD, - Type.STATE, - Type.STATE, - ], - actual_messages.records_and_state_messages, - ) - assert actual_messages.state_messages[0].state.stream.stream_descriptor.name == "justice_songs" - assert actual_messages.state_messages[0].state.stream.stream_state == AirbyteStateBlob(page=101) - assert actual_messages.state_messages[0].state.sourceStats.recordCount == 3.0 - assert actual_messages.state_messages[1].state.stream.stream_descriptor.name == "justice_songs" - assert actual_messages.state_messages[1].state.stream.stream_state == AirbyteStateBlob(page=102) - assert actual_messages.state_messages[1].state.sourceStats.recordCount == 3.0 - assert actual_messages.state_messages[2].state.stream.stream_descriptor.name == "justice_songs" - assert actual_messages.state_messages[2].state.stream.stream_state == AirbyteStateBlob(__ab_full_refresh_sync_complete=True) - assert actual_messages.state_messages[2].state.sourceStats.recordCount == 2.0 - assert actual_messages.state_messages[3].state.stream.stream_descriptor.name == "justice_songs" - assert actual_messages.state_messages[3].state.stream.stream_state == AirbyteStateBlob(__ab_full_refresh_sync_complete=True) - assert actual_messages.state_messages[3].state.sourceStats.recordCount == 0.0 - - @HttpMocker() - def test_resumable_full_refresh_failure(self, http_mocker): - config = {} - - http_mocker.get( - _create_justice_songs_request().build(), - _create_response(pagination_has_more=True) - .with_pagination() - .with_record(record=_create_record("justice_songs")) - .with_record(record=_create_record("justice_songs")) - .build(), - ) - - http_mocker.get( - _create_justice_songs_request().with_page(1).build(), - _create_response(pagination_has_more=True) - .with_pagination() - .with_record(record=_create_record("justice_songs")) - .with_record(record=_create_record("justice_songs")) - .build(), - ) - - http_mocker.get(_create_justice_songs_request().with_page(2).build(), _create_response().with_status_code(status_code=400).build()) - - source = SourceFixture() - actual_messages = read( - source, config=config, catalog=_create_catalog([("justice_songs", SyncMode.full_refresh, {})]), expecting_exception=True - ) - - status_messages = actual_messages.get_stream_statuses("justice_songs") - assert status_messages[-1] == AirbyteStreamStatus.INCOMPLETE - assert len(actual_messages.records) == 4 - assert len(actual_messages.state_messages) == 2 - - validate_message_order( - [Type.RECORD, Type.RECORD, Type.STATE, Type.RECORD, Type.RECORD, Type.STATE], actual_messages.records_and_state_messages - ) - assert actual_messages.state_messages[0].state.stream.stream_descriptor.name == "justice_songs" - assert actual_messages.state_messages[0].state.stream.stream_state == AirbyteStateBlob(page=1) - assert actual_messages.state_messages[1].state.stream.stream_descriptor.name == "justice_songs" - assert actual_messages.state_messages[1].state.stream.stream_state == AirbyteStateBlob(page=2) - - assert actual_messages.errors[0].trace.error.failure_type == FailureType.system_error - assert actual_messages.errors[0].trace.error.stream_descriptor.name == "justice_songs" - assert "Bad request" in actual_messages.errors[0].trace.error.message diff --git a/airbyte-cdk/python/unit_tests/sources/streams/__init__.py b/airbyte-cdk/python/unit_tests/sources/streams/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/streams/checkpoint/__init__.py b/airbyte-cdk/python/unit_tests/sources/streams/checkpoint/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/streams/checkpoint/test_checkpoint_reader.py b/airbyte-cdk/python/unit_tests/sources/streams/checkpoint/test_checkpoint_reader.py deleted file mode 100644 index 01ddd363b0d3..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/checkpoint/test_checkpoint_reader.py +++ /dev/null @@ -1,350 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from unittest.mock import Mock - -import pytest -from airbyte_cdk.sources.streams.checkpoint import ( - CursorBasedCheckpointReader, - FullRefreshCheckpointReader, - IncrementalCheckpointReader, - LegacyCursorBasedCheckpointReader, - ResumableFullRefreshCheckpointReader, -) -from airbyte_cdk.sources.types import StreamSlice - - -def test_incremental_checkpoint_reader_next_slice(): - stream_slices = [ - {"start_date": "2024-01-01", "end_date": "2024-02-01"}, - {"start_date": "2024-02-01", "end_date": "2024-03-01"}, - {"start_date": "2024-03-01", "end_date": "2024-04-01"}, - ] - checkpoint_reader = IncrementalCheckpointReader(stream_slices=stream_slices, stream_state={}) - - assert checkpoint_reader.next() == stream_slices[0] - checkpoint_reader.observe({"updated_at": "2024-01-15"}) - assert checkpoint_reader.get_checkpoint() == {"updated_at": "2024-01-15"} - assert checkpoint_reader.next() == stream_slices[1] - checkpoint_reader.observe({"updated_at": "2024-02-15"}) - assert checkpoint_reader.get_checkpoint() == {"updated_at": "2024-02-15"} - assert checkpoint_reader.next() == stream_slices[2] - checkpoint_reader.observe({"updated_at": "2024-03-15"}) - assert checkpoint_reader.get_checkpoint() == {"updated_at": "2024-03-15"} - - # Validate that after iterating over every slice, the final get_checkpoint() call is None so that - # no duplicate final state message is emitted - assert checkpoint_reader.next() is None - assert checkpoint_reader.get_checkpoint() is None - - -def test_incremental_checkpoint_reader_incoming_state(): - incoming_state = {"updated_at": "2024-04-01"} - checkpoint_reader = IncrementalCheckpointReader(stream_slices=[], stream_state=incoming_state) - - assert checkpoint_reader.get_checkpoint() == incoming_state - - expected_state = {"cursor": "new_state_value"} - checkpoint_reader.observe(expected_state) - - assert checkpoint_reader.get_checkpoint() == expected_state - - -def test_resumable_full_refresh_checkpoint_reader_next(): - checkpoint_reader = ResumableFullRefreshCheckpointReader(stream_state={"synthetic_page_number": 55}) - - checkpoint_reader.observe({"synthetic_page_number": 56}) - assert checkpoint_reader.next() == {"synthetic_page_number": 56} - - checkpoint_reader.observe({"synthetic_page_number": 57}) - assert checkpoint_reader.next() == {"synthetic_page_number": 57} - - checkpoint_reader.observe({"__ab_full_refresh_sync_complete": True}) - assert checkpoint_reader.next() is None - - -def test_resumable_full_refresh_checkpoint_reader_no_incoming_state(): - checkpoint_reader = ResumableFullRefreshCheckpointReader(stream_state={}) - - checkpoint_reader.observe({"synthetic_page_number": 1}) - assert checkpoint_reader.next() == {"synthetic_page_number": 1} - - checkpoint_reader.observe({"synthetic_page_number": 2}) - assert checkpoint_reader.next() == {"synthetic_page_number": 2} - - checkpoint_reader.observe({"__ab_full_refresh_sync_complete": True}) - assert checkpoint_reader.next() is None - - -def test_full_refresh_checkpoint_reader_next(): - checkpoint_reader = FullRefreshCheckpointReader([{}]) - - assert checkpoint_reader.next() == {} - assert checkpoint_reader.get_checkpoint() is None - assert checkpoint_reader.next() is None - assert checkpoint_reader.get_checkpoint() == {"__ab_no_cursor_state_message": True} - - -def test_full_refresh_checkpoint_reader_substream(): - checkpoint_reader = FullRefreshCheckpointReader([{"partition": 1}, {"partition": 2}]) - - assert checkpoint_reader.next() == {"partition": 1} - assert checkpoint_reader.get_checkpoint() is None - assert checkpoint_reader.next() == {"partition": 2} - assert checkpoint_reader.get_checkpoint() is None - assert checkpoint_reader.next() is None - assert checkpoint_reader.get_checkpoint() == {"__ab_no_cursor_state_message": True} - - -def test_cursor_based_checkpoint_reader_incremental(): - expected_slices = [ - StreamSlice(cursor_slice={"start_date": "2024-01-01", "end_date": "2024-02-01"}, partition={}), - StreamSlice(cursor_slice={"start_date": "2024-02-01", "end_date": "2024-03-01"}, partition={}), - StreamSlice(cursor_slice={"start_date": "2024-03-01", "end_date": "2024-04-01"}, partition={}), - ] - - expected_stream_state = {"end_date": "2024-02-01"} - - incremental_cursor = Mock() - incremental_cursor.stream_slices.return_value = expected_slices - incremental_cursor.select_state.return_value = expected_stream_state - incremental_cursor.get_stream_state.return_value = expected_stream_state - - checkpoint_reader = CursorBasedCheckpointReader( - cursor=incremental_cursor, stream_slices=incremental_cursor.stream_slices(), read_state_from_cursor=False - ) - - assert checkpoint_reader.next() == expected_slices[0] - actual_state = checkpoint_reader.get_checkpoint() - assert actual_state == expected_stream_state - assert checkpoint_reader.next() == expected_slices[1] - assert checkpoint_reader.next() == expected_slices[2] - finished = checkpoint_reader.next() - assert finished is None - - # A finished checkpoint_reader should return None for the final checkpoint to avoid emitting duplicate state - assert checkpoint_reader.get_checkpoint() is None - - -def test_cursor_based_checkpoint_reader_resumable_full_refresh(): - expected_slices = [ - StreamSlice(cursor_slice={}, partition={}), - StreamSlice(cursor_slice={"next_page_token": 2}, partition={}), - StreamSlice(cursor_slice={"next_page_token": 3}, partition={}), - StreamSlice(cursor_slice={"next_page_token": 4}, partition={}), - StreamSlice(cursor_slice={"__ab_full_refresh_sync_complete": True}, partition={}), - ] - - expected_stream_state = {"next_page_token": 2} - - rfr_cursor = Mock() - rfr_cursor.stream_slices.return_value = [StreamSlice(cursor_slice={}, partition={})] - rfr_cursor.select_state.side_effect = expected_slices - rfr_cursor.get_stream_state.return_value = expected_stream_state - - checkpoint_reader = CursorBasedCheckpointReader( - cursor=rfr_cursor, stream_slices=rfr_cursor.stream_slices(), read_state_from_cursor=True - ) - - assert checkpoint_reader.next() == expected_slices[0] - actual_state = checkpoint_reader.get_checkpoint() - assert actual_state == expected_stream_state - assert checkpoint_reader.next() == expected_slices[1] - assert checkpoint_reader.next() == expected_slices[2] - assert checkpoint_reader.next() == expected_slices[3] - finished = checkpoint_reader.next() - assert finished is None - - # A finished checkpoint_reader should return None for the final checkpoint to avoid emitting duplicate state - assert checkpoint_reader.get_checkpoint() is None - - -def test_cursor_based_checkpoint_reader_resumable_full_refresh_parents(): - expected_slices = [ - StreamSlice(cursor_slice={"next_page_token": 2}, partition={"parent_id": "zaheer"}), - StreamSlice(cursor_slice={"next_page_token": 3}, partition={"parent_id": "zaheer"}), - StreamSlice(cursor_slice={"next_page_token": 2}, partition={"parent_id": "pli"}), - StreamSlice(cursor_slice={"next_page_token": 3}, partition={"parent_id": "pli"}), - ] - - expected_stream_state = {"next_page_token": 2} - - rfr_cursor = Mock() - rfr_cursor.stream_slices.return_value = [ - StreamSlice(cursor_slice={}, partition={"parent_id": "zaheer"}), - StreamSlice(cursor_slice={}, partition={"parent_id": "pli"}), - ] - rfr_cursor.select_state.side_effect = [ - {"next_page_token": 2}, - {"next_page_token": 3}, - {"__ab_full_refresh_sync_complete": True}, - {"next_page_token": 2}, - {"next_page_token": 3}, - {"__ab_full_refresh_sync_complete": True}, - ] - rfr_cursor.get_stream_state.return_value = expected_stream_state - - checkpoint_reader = CursorBasedCheckpointReader( - cursor=rfr_cursor, stream_slices=rfr_cursor.stream_slices(), read_state_from_cursor=True - ) - - assert checkpoint_reader.next() == expected_slices[0] - actual_state = checkpoint_reader.get_checkpoint() - assert actual_state == expected_stream_state - assert checkpoint_reader.next() == expected_slices[1] - assert checkpoint_reader.next() == expected_slices[2] - assert checkpoint_reader.next() == expected_slices[3] - finished = checkpoint_reader.next() - assert finished is None - - # A finished checkpoint_reader should return None for the final checkpoint to avoid emitting duplicate state - assert checkpoint_reader.get_checkpoint() is None - - -def test_cursor_based_checkpoint_reader_skip_completed_parent_slices(): - expected_slices = [ - StreamSlice(cursor_slice={"next_page_token": 2}, partition={"parent_id": "bolin"}), - StreamSlice(cursor_slice={"next_page_token": 3}, partition={"parent_id": "bolin"}), - StreamSlice(cursor_slice={"next_page_token": 7}, partition={"parent_id": "pabu"}), - StreamSlice(cursor_slice={"next_page_token": 8}, partition={"parent_id": "pabu"}), - ] - - expected_stream_state = {"next_page_token": 2} - - rfr_cursor = Mock() - rfr_cursor.stream_slices.return_value = [ - StreamSlice(cursor_slice={}, partition={"parent_id": "korra"}), - StreamSlice(cursor_slice={}, partition={"parent_id": "mako"}), - StreamSlice(cursor_slice={}, partition={"parent_id": "bolin"}), - StreamSlice(cursor_slice={}, partition={"parent_id": "asami"}), - StreamSlice(cursor_slice={}, partition={"parent_id": "naga"}), - StreamSlice(cursor_slice={}, partition={"parent_id": "pabu"}), - ] - rfr_cursor.select_state.side_effect = [ - {"__ab_full_refresh_sync_complete": True}, - {"__ab_full_refresh_sync_complete": True}, - {"next_page_token": 2}, - {"next_page_token": 3}, - {"__ab_full_refresh_sync_complete": True}, - {"__ab_full_refresh_sync_complete": True}, - {"__ab_full_refresh_sync_complete": True}, - {"next_page_token": 7}, - {"next_page_token": 8}, - ] - rfr_cursor.get_stream_state.return_value = expected_stream_state - - checkpoint_reader = CursorBasedCheckpointReader( - cursor=rfr_cursor, stream_slices=rfr_cursor.stream_slices(), read_state_from_cursor=True - ) - - assert checkpoint_reader.next() == expected_slices[0] - actual_state = checkpoint_reader.get_checkpoint() - assert actual_state == expected_stream_state - assert checkpoint_reader.next() == expected_slices[1] - assert checkpoint_reader.next() == expected_slices[2] - assert checkpoint_reader.next() == expected_slices[3] - finished = checkpoint_reader.next() - assert finished is None - - # A finished checkpoint_reader should return None for the final checkpoint to avoid emitting duplicate state - assert checkpoint_reader.get_checkpoint() is None - - -def test_cursor_based_checkpoint_reader_sync_first_parent_slice(): - expected_slices = [ - StreamSlice(cursor_slice={"next_page_token": 3}, partition={"parent_id": "bolin"}), - StreamSlice(cursor_slice={"next_page_token": 4}, partition={"parent_id": "bolin"}), - StreamSlice(cursor_slice={"next_page_token": 4}, partition={"parent_id": "bolin"}), - ] - - expected_stream_state = {"next_page_token": 3} - - rfr_cursor = Mock() - rfr_cursor.stream_slices.return_value = [ - StreamSlice(cursor_slice={}, partition={"parent_id": "bolin"}), - StreamSlice(cursor_slice={}, partition={"parent_id": "asami"}), - StreamSlice(cursor_slice={}, partition={"parent_id": "naga"}), - ] - rfr_cursor.select_state.side_effect = [ - {"next_page_token": 3}, # Accounts for the first invocation when checking if partition was already successful - {"next_page_token": 4}, - {"next_page_token": 4}, - {"__ab_full_refresh_sync_complete": True}, - {"__ab_full_refresh_sync_complete": True}, - {"__ab_full_refresh_sync_complete": True}, - ] - rfr_cursor.get_stream_state.return_value = expected_stream_state - - checkpoint_reader = CursorBasedCheckpointReader( - cursor=rfr_cursor, stream_slices=rfr_cursor.stream_slices(), read_state_from_cursor=True - ) - - assert checkpoint_reader.next() == expected_slices[0] - actual_state = checkpoint_reader.get_checkpoint() - assert actual_state == expected_stream_state - assert checkpoint_reader.next() == expected_slices[1] - assert checkpoint_reader.next() == expected_slices[2] - finished = checkpoint_reader.next() - assert finished is None - - # A finished checkpoint_reader should return None for the final checkpoint to avoid emitting duplicate state - assert checkpoint_reader.get_checkpoint() is None - - -def test_cursor_based_checkpoint_reader_resumable_full_refresh_invalid_slice(): - rfr_cursor = Mock() - rfr_cursor.stream_slices.return_value = [{"invalid": "stream_slice"}] - rfr_cursor.select_state.side_effect = [StreamSlice(cursor_slice={"invalid": "stream_slice"}, partition={})] - - checkpoint_reader = CursorBasedCheckpointReader( - cursor=rfr_cursor, stream_slices=rfr_cursor.stream_slices(), read_state_from_cursor=True - ) - - with pytest.raises(ValueError): - checkpoint_reader.next() - - -def test_legacy_cursor_based_checkpoint_reader_resumable_full_refresh(): - expected_mapping_slices = [ - {"parent_id": 400, "partition": {"parent_id": 400}, "cursor_slice": {}}, - {"parent_id": 400, "next_page_token": 2, "partition": {"parent_id": 400}, "cursor_slice": {"next_page_token": 2}}, - {"parent_id": 400, "next_page_token": 2, "partition": {"parent_id": 400}, "cursor_slice": {"next_page_token": 2}}, - {"parent_id": 400, "next_page_token": 3, "partition": {"parent_id": 400}, "cursor_slice": {"next_page_token": 3}}, - {"parent_id": 400, "next_page_token": 4, "partition": {"parent_id": 400}, "cursor_slice": {"next_page_token": 4}}, - { - "parent_id": 400, - "__ab_full_refresh_sync_complete": True, - "partition": {"parent_id": 400}, - "cursor_slice": {"__ab_full_refresh_sync_complete": True}, - }, - ] - - mocked_state = [ - {}, - {"next_page_token": 2}, - {"next_page_token": 3}, - {"next_page_token": 4}, - {"__ab_full_refresh_sync_complete": True}, - ] - - expected_stream_state = {"next_page_token": 2} - - rfr_cursor = Mock() - rfr_cursor.stream_slices.return_value = [{"parent_id": 400}] - rfr_cursor.select_state.side_effect = mocked_state - rfr_cursor.get_stream_state.return_value = expected_stream_state - - checkpoint_reader = LegacyCursorBasedCheckpointReader( - cursor=rfr_cursor, stream_slices=rfr_cursor.stream_slices(), read_state_from_cursor=True - ) - - assert checkpoint_reader.next() == expected_mapping_slices[0] - actual_state = checkpoint_reader.get_checkpoint() - assert actual_state == expected_stream_state - assert checkpoint_reader.next() == expected_mapping_slices[2] - assert checkpoint_reader.next() == expected_mapping_slices[3] - assert checkpoint_reader.next() == expected_mapping_slices[4] - finished = checkpoint_reader.next() - assert finished is None - - # A finished checkpoint_reader should return None for the final checkpoint to avoid emitting duplicate state - assert checkpoint_reader.get_checkpoint() is None diff --git a/airbyte-cdk/python/unit_tests/sources/streams/checkpoint/test_substream_resumable_full_refresh_cursor.py b/airbyte-cdk/python/unit_tests/sources/streams/checkpoint/test_substream_resumable_full_refresh_cursor.py deleted file mode 100644 index 4944518535f9..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/checkpoint/test_substream_resumable_full_refresh_cursor.py +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -import pytest -from airbyte_cdk.sources.streams.checkpoint.substream_resumable_full_refresh_cursor import SubstreamResumableFullRefreshCursor -from airbyte_cdk.sources.types import StreamSlice -from airbyte_cdk.utils import AirbyteTracedException - - -def test_substream_resumable_full_refresh_cursor(): - """ - Test scenario where a set of parent record partitions are iterated over by the cursor resulting in a completed sync - """ - expected_starting_state = {"states": []} - - expected_ending_state = { - "states": [ - {"partition": {"musician_id": "kousei_arima"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - {"partition": {"musician_id": "kaori_miyazono"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - ] - } - - partitions = [ - StreamSlice(partition={"musician_id": "kousei_arima"}, cursor_slice={}), - StreamSlice(partition={"musician_id": "kaori_miyazono"}, cursor_slice={}), - ] - - cursor = SubstreamResumableFullRefreshCursor() - - starting_state = cursor.get_stream_state() - assert starting_state == expected_starting_state - - for partition in partitions: - partition_state = cursor.select_state(partition) - assert partition_state is None - cursor.close_slice(partition) - - ending_state = cursor.get_stream_state() - assert ending_state == expected_ending_state - - -def test_substream_resumable_full_refresh_cursor_with_state(): - """ - Test scenario where a set of parent record partitions are iterated over and previously completed parents are skipped - """ - initial_state = { - "states": [ - {"partition": {"musician_id": "kousei_arima"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - {"partition": {"musician_id": "kaori_miyazono"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - {"partition": {"musician_id": "takeshi_aiza"}, "cursor": {}}, - ] - } - - expected_ending_state = { - "states": [ - {"partition": {"musician_id": "kousei_arima"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - {"partition": {"musician_id": "kaori_miyazono"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - {"partition": {"musician_id": "takeshi_aiza"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - {"partition": {"musician_id": "emi_igawa"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - ] - } - - partitions = [ - StreamSlice(partition={"musician_id": "kousei_arima"}, cursor_slice={}), - StreamSlice(partition={"musician_id": "kaori_miyazono"}, cursor_slice={}), - StreamSlice(partition={"musician_id": "takeshi_aiza"}, cursor_slice={}), - StreamSlice(partition={"musician_id": "emi_igawa"}, cursor_slice={}), - ] - - cursor = SubstreamResumableFullRefreshCursor() - cursor.set_initial_state(initial_state) - - starting_state = cursor.get_stream_state() - assert starting_state == initial_state - - for i, partition in enumerate(partitions): - partition_state = cursor.select_state(partition) - if i < len(initial_state.get("states")): - assert partition_state == initial_state.get("states")[i].get("cursor") - else: - assert partition_state is None - cursor.close_slice(partition) - - ending_state = cursor.get_stream_state() - assert ending_state == expected_ending_state - - -def test_set_initial_state_invalid_incoming_state(): - bad_state = {"next_page_token": 2} - cursor = SubstreamResumableFullRefreshCursor() - - with pytest.raises(AirbyteTracedException): - cursor.set_initial_state(bad_state) - - -def test_select_state_without_slice(): - cursor = SubstreamResumableFullRefreshCursor() - - with pytest.raises(ValueError): - cursor.select_state() diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/__init__.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/__init__.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/incremental_scenarios.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/incremental_scenarios.py deleted file mode 100644 index f3a4df1433cf..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/incremental_scenarios.py +++ /dev/null @@ -1,257 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -from airbyte_cdk.sources.streams.concurrent.cursor import CursorField -from airbyte_cdk.sources.streams.concurrent.state_converters.abstract_stream_state_converter import ConcurrencyCompatibleStateType -from airbyte_cdk.test.state_builder import StateBuilder -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from unit_tests.sources.file_based.scenarios.scenario_builder import IncrementalScenarioConfig, TestScenarioBuilder -from unit_tests.sources.streams.concurrent.scenarios.stream_facade_builder import StreamFacadeSourceBuilder -from unit_tests.sources.streams.concurrent.scenarios.utils import MockStream - -_NO_SLICE_BOUNDARIES = None -_NO_INPUT_STATE = [] -test_incremental_stream_without_slice_boundaries_no_input_state = ( - TestScenarioBuilder() - .set_name("test_incremental_stream_without_slice_boundaries_no_input_state") - .set_config({}) - .set_source_builder( - StreamFacadeSourceBuilder() - .set_streams( - [ - MockStream( - [ - ({"from": 0, "to": 1}, [{"id": "1", "cursor_field": 0}, {"id": "2", "cursor_field": 1}]), - ({"from": 1, "to": 2}, [{"id": "3", "cursor_field": 2}, {"id": "4", "cursor_field": 3}]), - ], - "stream1", - cursor_field="cursor_field", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - ) - ] - ) - .set_incremental(CursorField("cursor_field"), _NO_SLICE_BOUNDARIES) - .set_input_state(_NO_INPUT_STATE) - ) - .set_expected_read_error(AirbyteTracedException, "Concurrent read failure") - .set_log_levels({"ERROR", "WARN", "WARNING", "INFO", "DEBUG"}) - .set_incremental_scenario_config(IncrementalScenarioConfig(input_state=_NO_INPUT_STATE)) - .build() -) - - -test_incremental_stream_with_slice_boundaries_no_input_state = ( - TestScenarioBuilder() - .set_name("test_incremental_stream_with_slice_boundaries_no_input_state") - .set_config({}) - .set_source_builder( - StreamFacadeSourceBuilder() - .set_streams( - [ - MockStream( - [ - ({"from": 0, "to": 1}, [{"id": "1", "cursor_field": 0}, {"id": "2", "cursor_field": 1}]), - ({"from": 1, "to": 2}, [{"id": "3", "cursor_field": 2}, {"id": "4", "cursor_field": 3}]), - ], - "stream1", - cursor_field="cursor_field", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - ) - ] - ) - .set_incremental(CursorField("cursor_field"), ("from", "to")) - .set_input_state(_NO_INPUT_STATE) - ) - .set_expected_records( - [ - {"data": {"id": "1", "cursor_field": 0}, "stream": "stream1"}, - {"data": {"id": "2", "cursor_field": 1}, "stream": "stream1"}, - {"cursor_field": 1}, - {"data": {"id": "3", "cursor_field": 2}, "stream": "stream1"}, - {"data": {"id": "4", "cursor_field": 3}, "stream": "stream1"}, - {"cursor_field": 3}, - {"cursor_field": 3}, # see Cursor.ensure_at_least_one_state_emitted - ] - ) - .set_log_levels({"ERROR", "WARN", "WARNING", "INFO", "DEBUG"}) - .set_incremental_scenario_config(IncrementalScenarioConfig(input_state=_NO_INPUT_STATE)) - .build() -) - - -LEGACY_STATE = StateBuilder().with_stream_state("stream1", {"cursor_field": 0}).build() -test_incremental_stream_without_slice_boundaries_with_legacy_state = ( - TestScenarioBuilder() - .set_name("test_incremental_stream_without_slice_boundaries_with_legacy_state") - .set_config({}) - .set_source_builder( - StreamFacadeSourceBuilder() - .set_streams( - [ - MockStream( - [ - ({"from": 0, "to": 1}, [{"id": "1", "cursor_field": 0}, {"id": "2", "cursor_field": 1}]), - ({"from": 1, "to": 2}, [{"id": "3", "cursor_field": 2}, {"id": "4", "cursor_field": 3}]), - ], - "stream1", - cursor_field="cursor_field", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - ) - ] - ) - .set_incremental(CursorField("cursor_field"), _NO_SLICE_BOUNDARIES) - .set_input_state(LEGACY_STATE) - ) - .set_expected_read_error(AirbyteTracedException, "Concurrent read failure") - .set_log_levels({"ERROR", "WARN", "WARNING", "INFO", "DEBUG"}) - .set_incremental_scenario_config(IncrementalScenarioConfig(input_state=LEGACY_STATE)) - .build() -) - - -test_incremental_stream_with_slice_boundaries_with_legacy_state = ( - TestScenarioBuilder() - .set_name("test_incremental_stream_with_slice_boundaries_with_legacy_state") - .set_config({}) - .set_source_builder( - StreamFacadeSourceBuilder() - .set_streams( - [ - MockStream( - [ - ({"from": 0, "to": 1}, [{"id": "1", "cursor_field": 0}, {"id": "2", "cursor_field": 1}]), - ({"from": 1, "to": 2}, [{"id": "3", "cursor_field": 2}, {"id": "4", "cursor_field": 3}]), - ], - "stream1", - cursor_field="cursor_field", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - ) - ] - ) - .set_incremental(CursorField("cursor_field"), ("from", "to")) - .set_input_state(LEGACY_STATE) - ) - .set_expected_records( - [ - {"data": {"id": "1", "cursor_field": 0}, "stream": "stream1"}, - {"data": {"id": "2", "cursor_field": 1}, "stream": "stream1"}, - {"cursor_field": 1}, - {"data": {"id": "3", "cursor_field": 2}, "stream": "stream1"}, - {"data": {"id": "4", "cursor_field": 3}, "stream": "stream1"}, - {"cursor_field": 3}, - {"cursor_field": 3}, # see Cursor.ensure_at_least_one_state_emitted - ] - ) - .set_log_levels({"ERROR", "WARN", "WARNING", "INFO", "DEBUG"}) - .set_incremental_scenario_config(IncrementalScenarioConfig(input_state=LEGACY_STATE)) - .build() -) - - -CONCURRENT_STATE = ( - StateBuilder() - .with_stream_state( - "stream1", - { - "slices": [{"start": 0, "end": 0}], - "state_type": ConcurrencyCompatibleStateType.date_range.value, - }, - ) - .build() -) -test_incremental_stream_without_slice_boundaries_with_concurrent_state = ( - TestScenarioBuilder() - .set_name("test_incremental_stream_without_slice_boundaries_with_concurrent_state") - .set_config({}) - .set_source_builder( - StreamFacadeSourceBuilder() - .set_streams( - [ - MockStream( - [ - ({"from": 0, "to": 1}, [{"id": "1", "cursor_field": 0}, {"id": "2", "cursor_field": 1}]), - ({"from": 1, "to": 2}, [{"id": "3", "cursor_field": 2}, {"id": "4", "cursor_field": 3}]), - ], - "stream1", - cursor_field="cursor_field", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - ) - ] - ) - .set_incremental(CursorField("cursor_field"), _NO_SLICE_BOUNDARIES) - .set_input_state(CONCURRENT_STATE) - ) - .set_expected_read_error(AirbyteTracedException, "Concurrent read failure") - .set_log_levels({"ERROR", "WARN", "WARNING", "INFO", "DEBUG"}) - .set_incremental_scenario_config(IncrementalScenarioConfig(input_state=CONCURRENT_STATE)) - .build() -) - - -test_incremental_stream_with_slice_boundaries_with_concurrent_state = ( - TestScenarioBuilder() - .set_name("test_incremental_stream_with_slice_boundaries_with_concurrent_state") - .set_config({}) - .set_source_builder( - StreamFacadeSourceBuilder() - .set_streams( - [ - MockStream( - [ - ({"from": 0, "to": 1}, [{"id": "1", "cursor_field": 0}, {"id": "2", "cursor_field": 1}]), - ({"from": 1, "to": 2}, [{"id": "3", "cursor_field": 2}, {"id": "4", "cursor_field": 3}]), - ], - "stream1", - cursor_field="cursor_field", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - ) - ] - ) - .set_incremental(CursorField("cursor_field"), ("from", "to")) - .set_input_state(CONCURRENT_STATE) - ) - .set_expected_records( - [ - {"data": {"id": "1", "cursor_field": 0}, "stream": "stream1"}, - {"data": {"id": "2", "cursor_field": 1}, "stream": "stream1"}, - {"cursor_field": 1}, - {"data": {"id": "3", "cursor_field": 2}, "stream": "stream1"}, - {"data": {"id": "4", "cursor_field": 3}, "stream": "stream1"}, - {"cursor_field": 3}, - {"cursor_field": 3}, # see Cursor.ensure_at_least_one_state_emitted - ] - ) - .set_log_levels({"ERROR", "WARN", "WARNING", "INFO", "DEBUG"}) - .set_incremental_scenario_config(IncrementalScenarioConfig(input_state=CONCURRENT_STATE)) - .build() -) diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/stream_facade_builder.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/stream_facade_builder.py deleted file mode 100644 index 4d4fb5c474f2..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/stream_facade_builder.py +++ /dev/null @@ -1,123 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import concurrent -import logging -from typing import Any, List, Mapping, Optional, Tuple, Union - -from airbyte_cdk.models import ( - AirbyteStateMessage, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteStream, - ConnectorSpecification, - DestinationSyncMode, - SyncMode, -) -from airbyte_cdk.sources.concurrent_source.concurrent_source import ConcurrentSource -from airbyte_cdk.sources.concurrent_source.concurrent_source_adapter import ConcurrentSourceAdapter -from airbyte_cdk.sources.concurrent_source.thread_pool_manager import ThreadPoolManager -from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager -from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository -from airbyte_cdk.sources.source import TState -from airbyte_cdk.sources.streams import Stream -from airbyte_cdk.sources.streams.concurrent.cursor import CursorField -from airbyte_cdk.sources.streams.concurrent.state_converters.datetime_stream_state_converter import EpochValueConcurrentStreamStateConverter -from unit_tests.sources.file_based.scenarios.scenario_builder import SourceBuilder -from unit_tests.sources.streams.concurrent.scenarios.thread_based_concurrent_stream_source_builder import NeverLogSliceLogger - -_CURSOR_FIELD = "cursor_field" -_NO_STATE = None - - -class StreamFacadeConcurrentConnectorStateConverter(EpochValueConcurrentStreamStateConverter): - pass - - -class StreamFacadeSource(ConcurrentSourceAdapter): - def __init__( - self, - streams: List[Stream], - threadpool: concurrent.futures.ThreadPoolExecutor, - cursor_field: Optional[CursorField] = None, - cursor_boundaries: Optional[Tuple[str, str]] = None, - input_state: Optional[List[Mapping[str, Any]]] = _NO_STATE, - ): - self._message_repository = InMemoryMessageRepository() - threadpool_manager = ThreadPoolManager(threadpool, streams[0].logger) - concurrent_source = ConcurrentSource(threadpool_manager, streams[0].logger, NeverLogSliceLogger(), self._message_repository) - super().__init__(concurrent_source) - self._streams = streams - self._threadpool = threadpool_manager - self._cursor_field = cursor_field - self._cursor_boundaries = cursor_boundaries - self._state = [AirbyteStateMessage(s) for s in input_state] if input_state else None - - def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Optional[Any]]: - return True, None - - def streams(self, config: Mapping[str, Any]) -> List[Stream]: - state_manager = ConnectorStateManager( - state=self._state, - ) # The input values into the AirbyteStream are dummy values; the connector state manager only uses `name` and `namespace` - state_converter = StreamFacadeConcurrentConnectorStateConverter() - - return [ - self.convert_to_concurrent_stream(stream.logger, stream, state_manager, self.initialize_cursor( - stream, state_manager, state_converter, self._cursor_boundaries, None, EpochValueConcurrentStreamStateConverter.get_end_provider()) - ) - for stream in self._streams - ] - - @property - def message_repository(self) -> Union[None, MessageRepository]: - return self._message_repository - - def spec(self, logger: logging.Logger) -> ConnectorSpecification: - return ConnectorSpecification(connectionSpecification={}) - - def read_catalog(self, catalog_path: str) -> ConfiguredAirbyteCatalog: - return ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=s.as_airbyte_stream(), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.overwrite, - ) - for s in self._streams - ] - ) - - -class StreamFacadeSourceBuilder(SourceBuilder[StreamFacadeSource]): - def __init__(self): - self._source = None - self._streams = [] - self._max_workers = 1 - self._cursor_field = None - self._cursor_boundaries = None - self._input_state = None - self._raw_input_state = None - - def set_streams(self, streams: List[Stream]) -> "StreamFacadeSourceBuilder": - self._streams = streams - return self - - def set_max_workers(self, max_workers: int) -> "StreamFacadeSourceBuilder": - self._max_workers = max_workers - return self - - def set_incremental(self, cursor_field: CursorField, cursor_boundaries: Optional[Tuple[str, str]]) -> "StreamFacadeSourceBuilder": - self._cursor_field = cursor_field - self._cursor_boundaries = cursor_boundaries - return self - - def set_input_state(self, state: List[Mapping[str, Any]]) -> "StreamFacadeSourceBuilder": - self._input_state = state - return self - - def build( - self, configured_catalog: Optional[Mapping[str, Any]], config: Optional[Mapping[str, Any]], state: Optional[TState] - ) -> StreamFacadeSource: - threadpool = concurrent.futures.ThreadPoolExecutor(max_workers=self._max_workers, thread_name_prefix="workerpool") - return StreamFacadeSource(self._streams, threadpool, self._cursor_field, self._cursor_boundaries, state) diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/stream_facade_scenarios.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/stream_facade_scenarios.py deleted file mode 100644 index 41483282821c..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/stream_facade_scenarios.py +++ /dev/null @@ -1,456 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -from airbyte_cdk.sources.streams.concurrent.cursor import CursorField -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from unit_tests.sources.file_based.scenarios.scenario_builder import IncrementalScenarioConfig, TestScenarioBuilder -from unit_tests.sources.streams.concurrent.scenarios.stream_facade_builder import StreamFacadeSourceBuilder -from unit_tests.sources.streams.concurrent.scenarios.utils import MockStream - -_stream1 = MockStream( - [ - (None, [{"id": "1"}, {"id": "2"}]), - ], - "stream1", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, -) - -_stream_raising_exception = MockStream( - [ - (None, [{"id": "1"}, ValueError("test exception")]), - ], - "stream1", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, -) - -_stream_with_primary_key = MockStream( - [ - (None, [{"id": "1"}, {"id": "2"}]), - ], - "stream1", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - primary_key="id", -) - -_stream2 = MockStream( - [ - (None, [{"id": "A"}, {"id": "B"}]), - ], - "stream2", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, -) - -_stream_with_single_slice = MockStream( - [ - ({"slice_key": "s1"}, [{"id": "1"}, {"id": "2"}]), - ], - "stream1", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, -) - -_stream_with_multiple_slices = MockStream( - [ - ({"slice_key": "s1"}, [{"id": "1"}, {"id": "2"}]), - ({"slice_key": "s2"}, [{"id": "3"}, {"id": "4"}]), - ], - "stream1", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, -) - -test_stream_facade_single_stream = ( - TestScenarioBuilder() - .set_name("test_stream_facade_single_stream") - .set_config({}) - .set_source_builder(StreamFacadeSourceBuilder().set_streams([_stream1])) - .set_expected_records( - [ - {"data": {"id": "1"}, "stream": "stream1"}, - {"data": {"id": "2"}, "stream": "stream1"}, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh"], - } - ] - } - ) - .set_expected_logs( - { - "read": [ - {"level": "INFO", "message": "Starting syncing"}, - {"level": "INFO", "message": "Marking stream stream1 as STARTED"}, - {"level": "INFO", "message": "Syncing stream: stream1"}, - {"level": "INFO", "message": "Marking stream stream1 as RUNNING"}, - {"level": "INFO", "message": "Read 2 records from stream1 stream"}, - {"level": "INFO", "message": "Marking stream stream1 as STOPPED"}, - {"level": "INFO", "message": "Finished syncing stream1"}, - {"level": "INFO", "message": "Finished syncing"}, - ] - } - ) - .set_log_levels({"ERROR", "WARN", "WARNING", "INFO", "DEBUG"}) - .build() -) - -test_stream_facade_raises_exception = ( - TestScenarioBuilder() - .set_name("test_stream_facade_raises_exception") - .set_config({}) - .set_source_builder(StreamFacadeSourceBuilder().set_streams([_stream_raising_exception])) - .set_expected_records( - [ - {"data": {"id": "1"}, "stream": "stream1"}, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh"], - } - ] - } - ) - .set_expected_read_error(AirbyteTracedException, "Concurrent read failure") - .build() -) - -test_stream_facade_single_stream_with_primary_key = ( - TestScenarioBuilder() - .set_name("test_stream_facade_stream_with_primary_key") - .set_config({}) - .set_source_builder(StreamFacadeSourceBuilder().set_streams([_stream1])) - .set_expected_records( - [ - {"data": {"id": "1"}, "stream": "stream1"}, - {"data": {"id": "2"}, "stream": "stream1"}, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh"], - } - ] - } - ) - .build() -) - -test_stream_facade_multiple_streams = ( - TestScenarioBuilder() - .set_name("test_stream_facade_multiple_streams") - .set_config({}) - .set_source_builder(StreamFacadeSourceBuilder().set_streams([_stream1, _stream2])) - .set_expected_records( - [ - {"data": {"id": "1"}, "stream": "stream1"}, - {"data": {"id": "2"}, "stream": "stream1"}, - {"data": {"id": "A"}, "stream": "stream2"}, - {"data": {"id": "B"}, "stream": "stream2"}, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh"], - }, - { - "json_schema": { - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - "name": "stream2", - "supported_sync_modes": ["full_refresh"], - }, - ] - } - ) - .build() -) - -test_stream_facade_single_stream_with_single_slice = ( - TestScenarioBuilder() - .set_name("test_stream_facade_single_stream_with_single_slice") - .set_config({}) - .set_source_builder(StreamFacadeSourceBuilder().set_streams([_stream1])) - .set_expected_records( - [ - {"data": {"id": "1"}, "stream": "stream1"}, - {"data": {"id": "2"}, "stream": "stream1"}, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh"], - } - ] - } - ) - .build() -) - -test_stream_facade_single_stream_with_multiple_slices = ( - TestScenarioBuilder() - .set_name("test_stream_facade_single_stream_with_multiple_slice") - .set_config({}) - .set_source_builder(StreamFacadeSourceBuilder().set_streams([_stream_with_multiple_slices])) - .set_expected_records( - [ - {"data": {"id": "1"}, "stream": "stream1"}, - {"data": {"id": "2"}, "stream": "stream1"}, - {"data": {"id": "3"}, "stream": "stream1"}, - {"data": {"id": "4"}, "stream": "stream1"}, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh"], - } - ] - } - ) - .build() -) - -test_stream_facade_single_stream_with_multiple_slices_with_concurrency_level_two = ( - TestScenarioBuilder() - .set_name("test_stream_facade_single_stream_with_multiple_slice_with_concurrency_level_two") - .set_config({}) - .set_source_builder(StreamFacadeSourceBuilder().set_streams([_stream_with_multiple_slices])) - .set_expected_records( - [ - {"data": {"id": "1"}, "stream": "stream1"}, - {"data": {"id": "2"}, "stream": "stream1"}, - {"data": {"id": "3"}, "stream": "stream1"}, - {"data": {"id": "4"}, "stream": "stream1"}, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh"], - } - ] - } - ) - .build() -) - - -test_incremental_stream_with_slice_boundaries = ( - TestScenarioBuilder() - .set_name("test_incremental_stream_with_slice_boundaries") - .set_config({}) - .set_source_builder( - StreamFacadeSourceBuilder() - .set_streams( - [ - MockStream( - [ - ({"from": 0, "to": 1}, [{"id": "1", "cursor_field": 0}, {"id": "2", "cursor_field": 1}]), - ({"from": 1, "to": 2}, [{"id": "3", "cursor_field": 2}, {"id": "4", "cursor_field": 3}]), - ], - "stream1", - cursor_field="cursor_field", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - ) - ] - ) - .set_incremental(CursorField("cursor_field"), ("from", "to")) - ) - .set_expected_records( - [ - {"data": {"id": "1", "cursor_field": 0}, "stream": "stream1"}, - {"data": {"id": "2", "cursor_field": 1}, "stream": "stream1"}, - {"cursor_field": 1}, - {"data": {"id": "3", "cursor_field": 2}, "stream": "stream1"}, - {"data": {"id": "4", "cursor_field": 3}, "stream": "stream1"}, - {"cursor_field": 3}, - {"cursor_field": 3}, # see Cursor.ensure_at_least_one_state_emitted - ] - ) - .set_log_levels({"ERROR", "WARN", "WARNING", "INFO", "DEBUG"}) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=[], - ) - ) - .build() -) - - -_NO_SLICE_BOUNDARIES = None -test_incremental_stream_without_slice_boundaries = ( - TestScenarioBuilder() - .set_name("test_incremental_stream_without_slice_boundaries") - .set_config({}) - .set_source_builder( - StreamFacadeSourceBuilder() - .set_streams( - [ - MockStream( - [ - (None, [{"id": "1", "cursor_field": 0}, {"id": "2", "cursor_field": 3}]), - ], - "stream1", - cursor_field="cursor_field", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - ) - ] - ) - .set_incremental(CursorField("cursor_field"), _NO_SLICE_BOUNDARIES) - ) - .set_expected_records( - [ - {"data": {"id": "1", "cursor_field": 0}, "stream": "stream1"}, - {"data": {"id": "2", "cursor_field": 3}, "stream": "stream1"}, - {"cursor_field": 3}, - {"cursor_field": 3}, # see Cursor.ensure_at_least_one_state_emitted - ] - ) - .set_log_levels({"ERROR", "WARN", "WARNING", "INFO", "DEBUG"}) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=[], - ) - ) - .build() -) - -test_incremental_stream_with_many_slices_but_without_slice_boundaries = ( - TestScenarioBuilder() - .set_name("test_incremental_stream_with_many_slices_but_without_slice_boundaries") - .set_config({}) - .set_source_builder( - StreamFacadeSourceBuilder() - .set_streams( - [ - MockStream( - [ - ({"parent_id": 1}, [{"id": "1", "cursor_field": 0}]), - ({"parent_id": 309}, [{"id": "3", "cursor_field": 0}]), - ], - "stream1", - cursor_field="cursor_field", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - ) - ] - ) - .set_incremental(CursorField("cursor_field"), _NO_SLICE_BOUNDARIES) - ) - .set_expected_read_error(AirbyteTracedException, "Concurrent read failure") - .set_log_levels({"ERROR", "WARN", "WARNING", "INFO", "DEBUG"}) - .set_incremental_scenario_config( - IncrementalScenarioConfig( - input_state=[], - ) - ) - .build() -) diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/test_concurrent_scenarios.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/test_concurrent_scenarios.py deleted file mode 100644 index af2249873035..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/test_concurrent_scenarios.py +++ /dev/null @@ -1,76 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from pathlib import PosixPath - -import pytest -from _pytest.capture import CaptureFixture -from freezegun import freeze_time -from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenario -from unit_tests.sources.file_based.test_scenarios import verify_discover, verify_read -from unit_tests.sources.streams.concurrent.scenarios.incremental_scenarios import ( - test_incremental_stream_with_slice_boundaries_no_input_state, - test_incremental_stream_with_slice_boundaries_with_concurrent_state, - test_incremental_stream_with_slice_boundaries_with_legacy_state, - test_incremental_stream_without_slice_boundaries_no_input_state, - test_incremental_stream_without_slice_boundaries_with_concurrent_state, - test_incremental_stream_without_slice_boundaries_with_legacy_state, -) -from unit_tests.sources.streams.concurrent.scenarios.stream_facade_scenarios import ( - test_incremental_stream_with_many_slices_but_without_slice_boundaries, - test_incremental_stream_with_slice_boundaries, - test_incremental_stream_without_slice_boundaries, - test_stream_facade_multiple_streams, - test_stream_facade_raises_exception, - test_stream_facade_single_stream, - test_stream_facade_single_stream_with_multiple_slices, - test_stream_facade_single_stream_with_multiple_slices_with_concurrency_level_two, - test_stream_facade_single_stream_with_primary_key, - test_stream_facade_single_stream_with_single_slice, -) -from unit_tests.sources.streams.concurrent.scenarios.thread_based_concurrent_stream_scenarios import ( - test_concurrent_cdk_multiple_streams, - test_concurrent_cdk_partition_raises_exception, - test_concurrent_cdk_single_stream, - test_concurrent_cdk_single_stream_multiple_partitions, - test_concurrent_cdk_single_stream_multiple_partitions_concurrency_level_two, - test_concurrent_cdk_single_stream_with_primary_key, -) - -scenarios = [ - test_concurrent_cdk_single_stream, - test_concurrent_cdk_multiple_streams, - test_concurrent_cdk_single_stream_multiple_partitions, - test_concurrent_cdk_single_stream_multiple_partitions_concurrency_level_two, - test_concurrent_cdk_single_stream_with_primary_key, - test_concurrent_cdk_partition_raises_exception, - # test streams built using the facade - test_stream_facade_single_stream, - test_stream_facade_multiple_streams, - test_stream_facade_single_stream_with_primary_key, - test_stream_facade_single_stream_with_single_slice, - test_stream_facade_single_stream_with_multiple_slices, - test_stream_facade_single_stream_with_multiple_slices_with_concurrency_level_two, - test_stream_facade_raises_exception, - test_incremental_stream_with_slice_boundaries, - test_incremental_stream_without_slice_boundaries, - test_incremental_stream_with_many_slices_but_without_slice_boundaries, - test_incremental_stream_with_slice_boundaries_no_input_state, - test_incremental_stream_with_slice_boundaries_with_concurrent_state, - test_incremental_stream_with_slice_boundaries_with_legacy_state, - test_incremental_stream_without_slice_boundaries_no_input_state, - test_incremental_stream_without_slice_boundaries_with_concurrent_state, - test_incremental_stream_without_slice_boundaries_with_legacy_state, -] - - -@pytest.mark.parametrize("scenario", scenarios, ids=[s.name for s in scenarios]) -@freeze_time("2023-06-09T00:00:00Z") -def test_concurrent_read(scenario: TestScenario) -> None: - verify_read(scenario) - - -@pytest.mark.parametrize("scenario", scenarios, ids=[s.name for s in scenarios]) -def test_concurrent_discover(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> None: - verify_discover(capsys, tmp_path, scenario) diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_scenarios.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_scenarios.py deleted file mode 100644 index 919b88d61cc7..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_scenarios.py +++ /dev/null @@ -1,420 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import logging - -from airbyte_cdk.sources.message import InMemoryMessageRepository -from airbyte_cdk.sources.streams.concurrent.availability_strategy import AlwaysAvailableAvailabilityStrategy -from airbyte_cdk.sources.streams.concurrent.cursor import FinalStateCursor -from airbyte_cdk.sources.streams.concurrent.default_stream import DefaultStream -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenarioBuilder -from unit_tests.sources.streams.concurrent.scenarios.thread_based_concurrent_stream_source_builder import ( - ConcurrentSourceBuilder, - InMemoryPartition, - InMemoryPartitionGenerator, -) - -_message_repository = InMemoryMessageRepository() - -_id_only_stream = DefaultStream( - partition_generator=InMemoryPartitionGenerator( - [InMemoryPartition("partition1", "stream1", None, [Record({"id": "1"}, InMemoryPartition("partition1", "stream1", None, [])), Record({"id": "2"}, InMemoryPartition("partition1", "stream1", None, []))])] - ), - name="stream1", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - availability_strategy=AlwaysAvailableAvailabilityStrategy(), - primary_key=[], - cursor_field=None, - logger=logging.getLogger("test_logger"), - cursor=FinalStateCursor(stream_name="stream1", stream_namespace=None, message_repository=_message_repository), -) - -_id_only_stream_with_slice_logger = DefaultStream( - partition_generator=InMemoryPartitionGenerator( - [InMemoryPartition("partition1", "stream1", None, [Record({"id": "1"}, "stream1"), Record({"id": "2"}, "stream1")])] - ), - name="stream1", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - availability_strategy=AlwaysAvailableAvailabilityStrategy(), - primary_key=[], - cursor_field=None, - logger=logging.getLogger("test_logger"), - cursor=FinalStateCursor(stream_name="stream1", stream_namespace=None, message_repository=_message_repository), -) - -_id_only_stream_with_primary_key = DefaultStream( - partition_generator=InMemoryPartitionGenerator( - [InMemoryPartition("partition1", "stream1", None, [Record({"id": "1"}, InMemoryPartition("partition1", "stream1", None, [])), Record({"id": "2"}, InMemoryPartition("partition1", "stream1", None, []))])] - ), - name="stream1", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - availability_strategy=AlwaysAvailableAvailabilityStrategy(), - primary_key=["id"], - cursor_field=None, - logger=logging.getLogger("test_logger"), - cursor=FinalStateCursor(stream_name="stream1", stream_namespace=None, message_repository=_message_repository), -) - -_id_only_stream_multiple_partitions = DefaultStream( - partition_generator=InMemoryPartitionGenerator( - [ - InMemoryPartition("partition1", "stream1", {"p": "1"}, [Record({"id": "1"}, InMemoryPartition("partition1", "stream1", None, [])), Record({"id": "2"}, InMemoryPartition("partition1", "stream1", None, []))]), - InMemoryPartition("partition2", "stream1", {"p": "2"}, [Record({"id": "3"}, InMemoryPartition("partition1", "stream1", None, [])), Record({"id": "4"}, InMemoryPartition("partition1", "stream1", None, []))]), - ] - ), - name="stream1", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - availability_strategy=AlwaysAvailableAvailabilityStrategy(), - primary_key=[], - cursor_field=None, - logger=logging.getLogger("test_logger"), - cursor=FinalStateCursor(stream_name="stream1", stream_namespace=None, message_repository=_message_repository), -) - -_id_only_stream_multiple_partitions_concurrency_level_two = DefaultStream( - partition_generator=InMemoryPartitionGenerator( - [ - InMemoryPartition("partition1", "stream1", {"p": "1"}, [Record({"id": "1"}, InMemoryPartition("partition1", "stream1", None, [])), Record({"id": "2"}, InMemoryPartition("partition1", "stream1", None, []))]), - InMemoryPartition("partition2", "stream1", {"p": "2"}, [Record({"id": "3"}, InMemoryPartition("partition1", "stream1", None, [])), Record({"id": "4"}, InMemoryPartition("partition1", "stream1", None, []))]), - ] - ), - name="stream1", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - availability_strategy=AlwaysAvailableAvailabilityStrategy(), - primary_key=[], - cursor_field=None, - logger=logging.getLogger("test_logger"), - cursor=FinalStateCursor(stream_name="stream1", stream_namespace=None, message_repository=_message_repository), -) - -_stream_raising_exception = DefaultStream( - partition_generator=InMemoryPartitionGenerator( - [InMemoryPartition("partition1", "stream1", None, [Record({"id": "1"}, InMemoryPartition("partition1", "stream1", None, [])), ValueError("test exception")])] - ), - name="stream1", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - availability_strategy=AlwaysAvailableAvailabilityStrategy(), - primary_key=[], - cursor_field=None, - logger=logging.getLogger("test_logger"), - cursor=FinalStateCursor(stream_name="stream1", stream_namespace=None, message_repository=_message_repository), -) - -test_concurrent_cdk_single_stream = ( - TestScenarioBuilder() - .set_name("test_concurrent_cdk_single_stream") - .set_config({}) - .set_source_builder( - ConcurrentSourceBuilder() - .set_streams( - [ - _id_only_stream, - ] - ) - .set_message_repository(_message_repository) - ) - .set_expected_records( - [ - {"data": {"id": "1"}, "stream": "stream1"}, - {"data": {"id": "2"}, "stream": "stream1"}, - ] - ) - .set_expected_logs( - { - "read": [ - {"level": "INFO", "message": "Starting syncing"}, - {"level": "INFO", "message": "Marking stream stream1 as STARTED"}, - {"level": "INFO", "message": "Syncing stream: stream1"}, - {"level": "INFO", "message": "Marking stream stream1 as RUNNING"}, - {"level": "INFO", "message": "Read 2 records from stream1 stream"}, - {"level": "INFO", "message": "Marking stream stream1 as STOPPED"}, - {"level": "INFO", "message": "Finished syncing stream1"}, - {"level": "INFO", "message": "Finished syncing"}, - ] - } - ) - .set_log_levels({"ERROR", "WARN", "WARNING", "INFO", "DEBUG"}) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh"], - } - ] - } - ) - .build() -) - -test_concurrent_cdk_single_stream_with_primary_key = ( - TestScenarioBuilder() - .set_name("test_concurrent_cdk_single_stream_with_primary_key") - .set_config({}) - .set_source_builder( - ConcurrentSourceBuilder() - .set_streams( - [ - _id_only_stream_with_primary_key, - ] - ) - .set_message_repository(_message_repository) - ) - .set_expected_records( - [ - {"data": {"id": "1"}, "stream": "stream1"}, - {"data": {"id": "2"}, "stream": "stream1"}, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh"], - "source_defined_primary_key": [["id"]], - } - ] - } - ) - .build() -) - -test_concurrent_cdk_multiple_streams = ( - TestScenarioBuilder() - .set_name("test_concurrent_cdk_multiple_streams") - .set_config({}) - .set_source_builder( - ConcurrentSourceBuilder() - .set_streams( - [ - _id_only_stream, - DefaultStream( - partition_generator=InMemoryPartitionGenerator( - [ - InMemoryPartition( - "partition1", - "stream2", - None, - [Record({"id": "10", "key": "v1"}, InMemoryPartition("partition1", "stream2", None, [])), - Record({"id": "20", "key": "v2"}, InMemoryPartition("partition1", "stream2", None, []))], - ) - ] - ), - name="stream2", - json_schema={ - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - "key": {"type": ["null", "string"]}, - }, - }, - availability_strategy=AlwaysAvailableAvailabilityStrategy(), - primary_key=[], - cursor_field=None, - logger=logging.getLogger("test_logger"), - cursor=FinalStateCursor(stream_name="stream2", stream_namespace=None, message_repository=_message_repository), - ), - ] - ) - .set_message_repository(_message_repository) - ) - .set_expected_records( - [ - {"data": {"id": "1"}, "stream": "stream1"}, - {"data": {"id": "2"}, "stream": "stream1"}, - {"data": {"id": "10", "key": "v1"}, "stream": "stream2"}, - {"data": {"id": "20", "key": "v2"}, "stream": "stream2"}, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh"], - }, - { - "json_schema": { - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - "key": {"type": ["null", "string"]}, - }, - }, - "name": "stream2", - "supported_sync_modes": ["full_refresh"], - }, - ] - } - ) - .build() -) - -test_concurrent_cdk_partition_raises_exception = ( - TestScenarioBuilder() - .set_name("test_concurrent_cdk_partition_raises_exception") - .set_config({}) - .set_source_builder( - ConcurrentSourceBuilder() - .set_streams( - [ - _stream_raising_exception, - ] - ) - .set_message_repository(_message_repository) - ) - .set_expected_records( - [ - {"data": {"id": "1"}, "stream": "stream1"}, - ] - ) - .set_expected_read_error(AirbyteTracedException, "Concurrent read failure") - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh"], - } - ] - } - ) - .build() -) - -test_concurrent_cdk_single_stream_multiple_partitions = ( - TestScenarioBuilder() - .set_name("test_concurrent_cdk_single_stream_multiple_partitions") - .set_config({}) - .set_source_builder( - ConcurrentSourceBuilder() - .set_streams( - [ - _id_only_stream_multiple_partitions, - ] - ) - .set_message_repository(_message_repository) - ) - .set_expected_records( - [ - {"data": {"id": "1"}, "stream": "stream1"}, - {"data": {"id": "2"}, "stream": "stream1"}, - {"data": {"id": "3"}, "stream": "stream1"}, - {"data": {"id": "4"}, "stream": "stream1"}, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh"], - } - ] - } - ) - .build() -) - -test_concurrent_cdk_single_stream_multiple_partitions_concurrency_level_two = ( - TestScenarioBuilder() - .set_name("test_concurrent_cdk_single_stream_multiple_partitions_concurrency_level_2") - .set_config({}) - .set_source_builder( - ConcurrentSourceBuilder() - .set_streams( - [ - _id_only_stream_multiple_partitions_concurrency_level_two, - ] - ) - .set_message_repository(_message_repository) - ) - .set_expected_records( - [ - {"data": {"id": "1"}, "stream": "stream1"}, - {"data": {"id": "2"}, "stream": "stream1"}, - {"data": {"id": "3"}, "stream": "stream1"}, - {"data": {"id": "4"}, "stream": "stream1"}, - ] - ) - .set_expected_catalog( - { - "streams": [ - { - "json_schema": { - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - }, - }, - "name": "stream1", - "supported_sync_modes": ["full_refresh"], - } - ] - } - ) - .build() -) diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_source_builder.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_source_builder.py deleted file mode 100644 index 17a4b39547ab..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_source_builder.py +++ /dev/null @@ -1,150 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import json -import logging -from typing import Any, Iterable, List, Mapping, Optional, Tuple, Union - -from airbyte_cdk.models import ConfiguredAirbyteCatalog, ConfiguredAirbyteStream, ConnectorSpecification, DestinationSyncMode, SyncMode -from airbyte_cdk.sources.concurrent_source.concurrent_source import ConcurrentSource -from airbyte_cdk.sources.concurrent_source.concurrent_source_adapter import ConcurrentSourceAdapter -from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository -from airbyte_cdk.sources.streams import Stream -from airbyte_cdk.sources.streams.concurrent.adapters import StreamFacade -from airbyte_cdk.sources.streams.concurrent.cursor import FinalStateCursor -from airbyte_cdk.sources.streams.concurrent.default_stream import DefaultStream -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.partition_generator import PartitionGenerator -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record -from airbyte_cdk.sources.streams.core import StreamData -from airbyte_cdk.sources.utils.slice_logger import SliceLogger -from unit_tests.sources.file_based.scenarios.scenario_builder import SourceBuilder - - -class LegacyStream(Stream): - def primary_key(self) -> Optional[Union[str, List[str], List[List[str]]]]: - return None - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: Optional[List[str]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - yield from [] - - -class ConcurrentCdkSource(ConcurrentSourceAdapter): - def __init__(self, streams: List[DefaultStream], message_repository: Optional[MessageRepository], max_workers, timeout_in_seconds): - concurrent_source = ConcurrentSource.create(1, 1, streams[0]._logger, NeverLogSliceLogger(), message_repository) - super().__init__(concurrent_source) - self._streams = streams - self._message_repository = message_repository - - def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Optional[Any]]: - # Check is not verified because it is up to the source to implement this method - return True, None - - def streams(self, config: Mapping[str, Any]) -> List[Stream]: - return [ - StreamFacade( - s, - LegacyStream(), - FinalStateCursor(stream_name=s.name, stream_namespace=s.namespace, message_repository=self.message_repository), - NeverLogSliceLogger(), - s._logger, - ) - for s in self._streams - ] - - def spec(self, *args: Any, **kwargs: Any) -> ConnectorSpecification: - return ConnectorSpecification(connectionSpecification={}) - - def read_catalog(self, catalog_path: str) -> ConfiguredAirbyteCatalog: - return ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=StreamFacade( - s, - LegacyStream(), - FinalStateCursor(stream_name=s.name, stream_namespace=s.namespace, message_repository=InMemoryMessageRepository()), - NeverLogSliceLogger(), - s._logger, - ).as_airbyte_stream(), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.overwrite, - ) - for s in self._streams - ] - ) - - @property - def message_repository(self) -> Union[None, MessageRepository]: - return self._message_repository - - -class InMemoryPartitionGenerator(PartitionGenerator): - def __init__(self, partitions: List[Partition]): - self._partitions = partitions - - def generate(self) -> Iterable[Partition]: - yield from self._partitions - - -class InMemoryPartition(Partition): - def stream_name(self) -> str: - return self._stream_name - - def __init__(self, name, stream_name, _slice, records): - self._name = name - self._stream_name = stream_name - self._slice = _slice - self._records = records - self._is_closed = False - - def read(self) -> Iterable[Record]: - for record_or_exception in self._records: - if isinstance(record_or_exception, Exception): - raise record_or_exception - else: - yield record_or_exception - - def to_slice(self) -> Optional[Mapping[str, Any]]: - return self._slice - - def __hash__(self) -> int: - if self._slice: - # Convert the slice to a string so that it can be hashed - s = json.dumps(self._slice, sort_keys=True) - return hash((self._name, s)) - else: - return hash(self._name) - - def close(self) -> None: - self._is_closed = True - - def is_closed(self) -> bool: - return self._is_closed - - -class ConcurrentSourceBuilder(SourceBuilder[ConcurrentCdkSource]): - def __init__(self): - self._streams: List[DefaultStream] = [] - self._message_repository = None - - def build(self, configured_catalog: Optional[Mapping[str, Any]], _, __) -> ConcurrentCdkSource: - return ConcurrentCdkSource(self._streams, self._message_repository, 1, 1) - - def set_streams(self, streams: List[DefaultStream]) -> "ConcurrentSourceBuilder": - self._streams = streams - return self - - def set_message_repository(self, message_repository: MessageRepository) -> "ConcurrentSourceBuilder": - self._message_repository = message_repository - return self - - -class NeverLogSliceLogger(SliceLogger): - def should_log_slice_message(self, logger: logging.Logger) -> bool: - return False diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/utils.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/utils.py deleted file mode 100644 index 85f6a1f7c634..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/scenarios/utils.py +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -from typing import Any, Iterable, List, Mapping, Optional, Tuple, Union - -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.streams import Stream -from airbyte_cdk.sources.streams.core import StreamData - - -class MockStream(Stream): - def __init__( - self, - slices_and_records_or_exception: Iterable[Tuple[Optional[Mapping[str, Any]], Iterable[Union[Exception, Mapping[str, Any]]]]], - name, - json_schema, - primary_key=None, - cursor_field=None, - ): - self._slices_and_records_or_exception = slices_and_records_or_exception - self._name = name - self._json_schema = json_schema - self._primary_key = primary_key - self._cursor_field = cursor_field - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: Optional[List[str]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - for _slice, records_or_exception in self._slices_and_records_or_exception: - if stream_slice == _slice: - for item in records_or_exception: - if isinstance(item, Exception): - raise item - yield item - - @property - def primary_key(self) -> Optional[Union[str, List[str], List[List[str]]]]: - return self._primary_key - - @property - def name(self) -> str: - return self._name - - @property - def cursor_field(self) -> Union[str, List[str]]: - return self._cursor_field or [] - - def get_json_schema(self) -> Mapping[str, Any]: - return self._json_schema - - def stream_slices( - self, *, sync_mode: SyncMode, cursor_field: Optional[List[str]] = None, stream_state: Optional[Mapping[str, Any]] = None - ) -> Iterable[Optional[Mapping[str, Any]]]: - if self._slices_and_records_or_exception: - yield from [_slice for _slice, records_or_exception in self._slices_and_records_or_exception] - else: - yield None diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_adapters.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_adapters.py deleted file mode 100644 index b8cd21b5cd71..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_adapters.py +++ /dev/null @@ -1,387 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import logging -import unittest -from unittest.mock import Mock - -import pytest -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, AirbyteStream, Level, SyncMode -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.message import InMemoryMessageRepository -from airbyte_cdk.sources.streams.concurrent.adapters import ( - AvailabilityStrategyFacade, - CursorPartitionGenerator, - StreamFacade, - StreamPartition, - StreamPartitionGenerator, -) -from airbyte_cdk.sources.streams.concurrent.availability_strategy import STREAM_AVAILABLE, StreamAvailable, StreamUnavailable -from airbyte_cdk.sources.streams.concurrent.cursor import Cursor -from airbyte_cdk.sources.streams.concurrent.exceptions import ExceptionWithDisplayMessage -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record -from airbyte_cdk.sources.streams.core import Stream -from airbyte_cdk.sources.types import StreamSlice -from airbyte_cdk.sources.utils.slice_logger import SliceLogger -from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer - -_ANY_SYNC_MODE = SyncMode.full_refresh -_ANY_STATE = {"state_key": "state_value"} -_ANY_CURSOR_FIELD = ["a", "cursor", "key"] -_STREAM_NAME = "stream" -_ANY_CURSOR = Mock(spec=Cursor) - - -@pytest.mark.parametrize( - "stream_availability, expected_available, expected_message", - [ - pytest.param(StreamAvailable(), True, None, id="test_stream_is_available"), - pytest.param(STREAM_AVAILABLE, True, None, id="test_stream_is_available_using_singleton"), - pytest.param(StreamUnavailable("message"), False, "message", id="test_stream_is_available"), - ], -) -def test_availability_strategy_facade(stream_availability, expected_available, expected_message): - strategy = Mock() - strategy.check_availability.return_value = stream_availability - facade = AvailabilityStrategyFacade(strategy) - - logger = Mock() - available, message = facade.check_availability(Mock(), logger, Mock()) - - assert available == expected_available - assert message == expected_message - - strategy.check_availability.assert_called_once_with(logger) - - -@pytest.mark.parametrize( - "sync_mode", - [ - pytest.param(SyncMode.full_refresh, id="test_full_refresh"), - pytest.param(SyncMode.incremental, id="test_incremental"), - ], -) -def test_stream_partition_generator(sync_mode): - stream = Mock() - message_repository = Mock() - stream_slices = [{"slice": 1}, {"slice": 2}] - stream.stream_slices.return_value = stream_slices - - partition_generator = StreamPartitionGenerator(stream, message_repository, _ANY_SYNC_MODE, _ANY_CURSOR_FIELD, _ANY_STATE, _ANY_CURSOR) - - partitions = list(partition_generator.generate()) - slices = [partition.to_slice() for partition in partitions] - assert slices == stream_slices - stream.stream_slices.assert_called_once_with(sync_mode=_ANY_SYNC_MODE, cursor_field=_ANY_CURSOR_FIELD, stream_state=_ANY_STATE) - - -@pytest.mark.parametrize( - "transformer, expected_records", - [ - pytest.param( - TypeTransformer(TransformConfig.NoTransform), - [Record({"data": "1"}, None), Record({"data": "2"}, None)], - id="test_no_transform", - ), - pytest.param( - TypeTransformer(TransformConfig.DefaultSchemaNormalization), - [Record({"data": 1}, None), Record({"data": 2}, None)], - id="test_default_transform", - ), - ], -) -def test_stream_partition(transformer, expected_records): - stream = Mock() - stream.name = _STREAM_NAME - stream.get_json_schema.return_value = {"type": "object", "properties": {"data": {"type": ["integer"]}}} - stream.transformer = transformer - message_repository = InMemoryMessageRepository() - _slice = None - sync_mode = SyncMode.full_refresh - cursor_field = None - state = None - partition = StreamPartition(stream, _slice, message_repository, sync_mode, cursor_field, state, _ANY_CURSOR) - - a_log_message = AirbyteMessage( - type=MessageType.LOG, - log=AirbyteLogMessage( - level=Level.INFO, - message='slice:{"partition": 1}', - ), - ) - for record in expected_records: - record.partition = partition - - stream_data = [a_log_message, {"data": "1"}, {"data": "2"}] - stream.read_records.return_value = stream_data - - records = list(partition.read()) - messages = list(message_repository.consume_queue()) - - assert records == expected_records - assert messages == [a_log_message] - - -@pytest.mark.parametrize( - "exception_type, expected_display_message", - [ - pytest.param(Exception, None, id="test_exception_no_display_message"), - pytest.param(ExceptionWithDisplayMessage, "display_message", id="test_exception_no_display_message"), - ], -) -def test_stream_partition_raising_exception(exception_type, expected_display_message): - stream = Mock() - stream.get_error_display_message.return_value = expected_display_message - - message_repository = InMemoryMessageRepository() - _slice = None - - partition = StreamPartition(stream, _slice, message_repository, _ANY_SYNC_MODE, _ANY_CURSOR_FIELD, _ANY_STATE, _ANY_CURSOR) - - stream.read_records.side_effect = Exception() - - with pytest.raises(exception_type) as e: - list(partition.read()) - if isinstance(e, ExceptionWithDisplayMessage): - assert e.display_message == "display message" - - -@pytest.mark.parametrize( - "_slice, expected_hash", - [ - pytest.param({"partition": 1, "k": "v"}, hash(("stream", '{"k": "v", "partition": 1}')), id="test_hash_with_slice"), - pytest.param(None, hash("stream"), id="test_hash_no_slice"), - ], -) -def test_stream_partition_hash(_slice, expected_hash): - stream = Mock() - stream.name = "stream" - partition = StreamPartition(stream, _slice, Mock(), _ANY_SYNC_MODE, _ANY_CURSOR_FIELD, _ANY_STATE, _ANY_CURSOR) - - _hash = partition.__hash__() - assert _hash == expected_hash - - -class StreamFacadeTest(unittest.TestCase): - def setUp(self): - self._abstract_stream = Mock() - self._abstract_stream.name = "stream" - self._abstract_stream.as_airbyte_stream.return_value = AirbyteStream( - name="stream", - json_schema={"type": "object"}, - supported_sync_modes=[SyncMode.full_refresh], - ) - self._legacy_stream = Mock(spec=Stream) - self._cursor = Mock(spec=Cursor) - self._logger = Mock() - self._slice_logger = Mock() - self._slice_logger.should_log_slice_message.return_value = False - self._facade = StreamFacade(self._abstract_stream, self._legacy_stream, self._cursor, self._slice_logger, self._logger) - self._source = Mock() - - self._stream = Mock() - self._stream.primary_key = "id" - - def test_name_is_delegated_to_wrapped_stream(self): - assert self._facade.name == self._abstract_stream.name - - def test_cursor_field_is_a_string(self): - self._abstract_stream.cursor_field = "cursor_field" - assert self._facade.cursor_field == "cursor_field" - - def test_none_cursor_field_is_converted_to_an_empty_list(self): - self._abstract_stream.cursor_field = None - assert self._facade.cursor_field == [] - - def test_source_defined_cursor_is_true(self): - assert self._facade.source_defined_cursor - - def test_json_schema_is_delegated_to_wrapped_stream(self): - json_schema = {"type": "object"} - self._abstract_stream.get_json_schema.return_value = json_schema - assert self._facade.get_json_schema() == json_schema - self._abstract_stream.get_json_schema.assert_called_once_with() - - def test_given_cursor_is_noop_when_supports_incremental_then_return_legacy_stream_response(self): - assert ( - StreamFacade( - self._abstract_stream, self._legacy_stream, _ANY_CURSOR, Mock(spec=SliceLogger), Mock(spec=logging.Logger) - ).supports_incremental - == self._legacy_stream.supports_incremental - ) - - def test_given_cursor_is_not_noop_when_supports_incremental_then_return_true(self): - assert StreamFacade( - self._abstract_stream, self._legacy_stream, Mock(spec=Cursor), Mock(spec=SliceLogger), Mock(spec=logging.Logger) - ).supports_incremental - - def test_check_availability_is_delegated_to_wrapped_stream(self): - availability = StreamAvailable() - self._abstract_stream.check_availability.return_value = availability - assert self._facade.check_availability(Mock(), Mock()) == (availability.is_available(), availability.message()) - self._abstract_stream.check_availability.assert_called_once_with() - - def test_full_refresh(self): - expected_stream_data = [{"data": 1}, {"data": 2}] - records = [Record(data, "stream") for data in expected_stream_data] - - partition = Mock() - partition.read.return_value = records - self._abstract_stream.generate_partitions.return_value = [partition] - - actual_stream_data = list(self._facade.read_records(SyncMode.full_refresh, None, None, None)) - - assert actual_stream_data == expected_stream_data - - def test_read_records(self): - expected_stream_data = [{"data": 1}, {"data": 2}] - records = [Record(data, "stream") for data in expected_stream_data] - partition = Mock() - partition.read.return_value = records - self._abstract_stream.generate_partitions.return_value = [partition] - - actual_stream_data = list(self._facade.read(None, None, None, None, None, None)) - - assert actual_stream_data == expected_stream_data - - def test_create_from_stream_stream(self): - stream = Mock() - stream.name = "stream" - stream.primary_key = "id" - stream.cursor_field = "cursor" - - facade = StreamFacade.create_from_stream(stream, self._source, self._logger, _ANY_STATE, self._cursor) - - assert facade.name == "stream" - assert facade.cursor_field == "cursor" - assert facade._abstract_stream._primary_key == ["id"] - - def test_create_from_stream_stream_with_none_primary_key(self): - stream = Mock() - stream.name = "stream" - stream.primary_key = None - stream.cursor_field = [] - - facade = StreamFacade.create_from_stream(stream, self._source, self._logger, _ANY_STATE, self._cursor) - assert facade._abstract_stream._primary_key == [] - - def test_create_from_stream_with_composite_primary_key(self): - stream = Mock() - stream.name = "stream" - stream.primary_key = ["id", "name"] - stream.cursor_field = [] - - facade = StreamFacade.create_from_stream(stream, self._source, self._logger, _ANY_STATE, self._cursor) - assert facade._abstract_stream._primary_key == ["id", "name"] - - def test_create_from_stream_with_empty_list_cursor(self): - stream = Mock() - stream.primary_key = "id" - stream.cursor_field = [] - - facade = StreamFacade.create_from_stream(stream, self._source, self._logger, _ANY_STATE, self._cursor) - - assert facade.cursor_field == [] - - def test_create_from_stream_raises_exception_if_primary_key_is_nested(self): - stream = Mock() - stream.name = "stream" - stream.primary_key = [["field", "id"]] - - with self.assertRaises(ValueError): - StreamFacade.create_from_stream(stream, self._source, self._logger, _ANY_STATE, self._cursor) - - def test_create_from_stream_raises_exception_if_primary_key_has_invalid_type(self): - stream = Mock() - stream.name = "stream" - stream.primary_key = 123 - - with self.assertRaises(ValueError): - StreamFacade.create_from_stream(stream, self._source, self._logger, _ANY_STATE, self._cursor) - - def test_create_from_stream_raises_exception_if_cursor_field_is_nested(self): - stream = Mock() - stream.name = "stream" - stream.primary_key = "id" - stream.cursor_field = ["field", "cursor"] - - with self.assertRaises(ValueError): - StreamFacade.create_from_stream(stream, self._source, self._logger, _ANY_STATE, self._cursor) - - def test_create_from_stream_with_cursor_field_as_list(self): - stream = Mock() - stream.name = "stream" - stream.primary_key = "id" - stream.cursor_field = ["cursor"] - - facade = StreamFacade.create_from_stream(stream, self._source, self._logger, _ANY_STATE, self._cursor) - assert facade.cursor_field == "cursor" - - def test_create_from_stream_none_message_repository(self): - self._stream.name = "stream" - self._stream.primary_key = "id" - self._stream.cursor_field = "cursor" - self._source.message_repository = None - - with self.assertRaises(ValueError): - StreamFacade.create_from_stream(self._stream, self._source, self._logger, {}, self._cursor) - - def test_get_error_display_message_no_display_message(self): - self._stream.get_error_display_message.return_value = "display_message" - - facade = StreamFacade.create_from_stream(self._stream, self._source, self._logger, _ANY_STATE, self._cursor) - - expected_display_message = None - e = Exception() - - display_message = facade.get_error_display_message(e) - - assert display_message == expected_display_message - - def test_get_error_display_message_with_display_message(self): - self._stream.get_error_display_message.return_value = "display_message" - - facade = StreamFacade.create_from_stream(self._stream, self._source, self._logger, _ANY_STATE, self._cursor) - - expected_display_message = "display_message" - e = ExceptionWithDisplayMessage("display_message") - - display_message = facade.get_error_display_message(e) - - assert display_message == expected_display_message - - -@pytest.mark.parametrize( - "exception, expected_display_message", - [ - pytest.param(Exception("message"), None, id="test_no_display_message"), - pytest.param(ExceptionWithDisplayMessage("message"), "message", id="test_no_display_message"), - ], -) -def test_get_error_display_message(exception, expected_display_message): - stream = Mock() - legacy_stream = Mock() - cursor = Mock(spec=Cursor) - facade = StreamFacade(stream, legacy_stream, cursor, Mock().Mock(), Mock()) - - display_message = facade.get_error_display_message(exception) - - assert display_message == expected_display_message - - -def test_cursor_partition_generator(): - stream = Mock() - cursor = Mock() - message_repository = Mock() - cursor_field = Mock() - - expected_slices = [StreamSlice(partition={}, cursor_slice={"start": 1, "end": 2})] - cursor.generate_slices.return_value = [(1, 2)] - - partition_generator = CursorPartitionGenerator(stream, message_repository, cursor, cursor_field) - - partitions = list(partition_generator.generate()) - generated_slices = [partition.to_slice() for partition in partitions] - - assert all(isinstance(partition, StreamPartition) for partition in partitions), "Not all partitions are instances of StreamPartition" - assert generated_slices == expected_slices, f"Expected {expected_slices}, but got {generated_slices}" diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_concurrent_read_processor.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_concurrent_read_processor.py deleted file mode 100644 index 9d561cf65bfc..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_concurrent_read_processor.py +++ /dev/null @@ -1,756 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import logging -import unittest -from unittest.mock import Mock, call - -import freezegun -import pytest -from airbyte_cdk.models import ( - AirbyteLogMessage, - AirbyteMessage, - AirbyteRecordMessage, - AirbyteStream, - AirbyteStreamStatus, - AirbyteStreamStatusTraceMessage, - AirbyteTraceMessage, -) -from airbyte_cdk.models import Level as LogLevel -from airbyte_cdk.models import StreamDescriptor, SyncMode, TraceType -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.concurrent_source.concurrent_read_processor import ConcurrentReadProcessor -from airbyte_cdk.sources.concurrent_source.partition_generation_completed_sentinel import PartitionGenerationCompletedSentinel -from airbyte_cdk.sources.concurrent_source.stream_thread_exception import StreamThreadException -from airbyte_cdk.sources.concurrent_source.thread_pool_manager import ThreadPoolManager -from airbyte_cdk.sources.message import LogMessage, MessageRepository -from airbyte_cdk.sources.streams.concurrent.abstract_stream import AbstractStream -from airbyte_cdk.sources.streams.concurrent.partition_enqueuer import PartitionEnqueuer -from airbyte_cdk.sources.streams.concurrent.partition_reader import PartitionReader -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record -from airbyte_cdk.sources.streams.concurrent.partitions.types import PartitionCompleteSentinel -from airbyte_cdk.sources.utils.slice_logger import SliceLogger -from airbyte_cdk.utils.traced_exception import AirbyteTracedException - -_STREAM_NAME = "stream" -_ANOTHER_STREAM_NAME = "stream2" -_ANY_AIRBYTE_MESSAGE = Mock(spec=AirbyteMessage) -_IS_SUCCESSFUL = True - - -class TestConcurrentReadProcessor(unittest.TestCase): - def setUp(self): - self._partition_enqueuer = Mock(spec=PartitionEnqueuer) - self._thread_pool_manager = Mock(spec=ThreadPoolManager) - - self._an_open_partition = Mock(spec=Partition) - self._log_message = Mock(spec=LogMessage) - self._an_open_partition.to_slice.return_value = self._log_message - self._an_open_partition.stream_name.return_value = _STREAM_NAME - - self._a_closed_partition = Mock(spec=Partition) - self._a_closed_partition.stream_name.return_value = _ANOTHER_STREAM_NAME - - self._logger = Mock(spec=logging.Logger) - self._slice_logger = Mock(spec=SliceLogger) - self._slice_logger.create_slice_log_message.return_value = self._log_message - self._message_repository = Mock(spec=MessageRepository) - self._message_repository.consume_queue.return_value = [] - self._partition_reader = Mock(spec=PartitionReader) - - self._stream = Mock(spec=AbstractStream) - self._stream.name = _STREAM_NAME - self._stream.as_airbyte_stream.return_value = AirbyteStream( - name=_STREAM_NAME, - json_schema={}, - supported_sync_modes=[SyncMode.full_refresh], - ) - self._another_stream = Mock(spec=AbstractStream) - self._another_stream.name = _ANOTHER_STREAM_NAME - self._another_stream.as_airbyte_stream.return_value = AirbyteStream( - name=_ANOTHER_STREAM_NAME, - json_schema={}, - supported_sync_modes=[SyncMode.full_refresh], - ) - - self._record_data = {"id": 1, "value": "A"} - self._partition = Mock(spec=Partition) - self._partition.stream_name = lambda: _STREAM_NAME - self._record = Mock(spec=Record) - self._record.partition = self._partition - self._record.data = self._record_data - - def test_stream_is_not_done_initially(self): - stream_instances_to_read_from = [self._stream] - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - assert not handler._is_stream_done(self._stream.name) - - def test_handle_partition_done_no_other_streams_to_generate_partitions_for(self): - stream_instances_to_read_from = [self._stream] - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - handler.start_next_partition_generator() - handler.on_partition(self._an_open_partition) - - sentinel = PartitionGenerationCompletedSentinel(self._stream) - messages = list(handler.on_partition_generation_completed(sentinel)) - - expected_messages = [] - assert messages == expected_messages - - @freezegun.freeze_time("2020-01-01T00:00:00") - def test_handle_last_stream_partition_done(self): - in_order_validation_mock = Mock() - in_order_validation_mock.attach_mock(self._another_stream, "_another_stream") - in_order_validation_mock.attach_mock(self._message_repository, "_message_repository") - self._message_repository.consume_queue.return_value = iter([_ANY_AIRBYTE_MESSAGE]) - stream_instances_to_read_from = [self._another_stream] - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - handler.start_next_partition_generator() - - sentinel = PartitionGenerationCompletedSentinel(self._another_stream) - messages = list(handler.on_partition_generation_completed(sentinel)) - - expected_messages = [ - _ANY_AIRBYTE_MESSAGE, - AirbyteMessage( - type=MessageType.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - emitted_at=1577836800000.0, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name=_ANOTHER_STREAM_NAME), - status=AirbyteStreamStatus(AirbyteStreamStatus.COMPLETE), - ), - ), - ), - ] - assert messages == expected_messages - assert in_order_validation_mock.mock_calls.index( - call._another_stream.cursor.ensure_at_least_one_state_emitted - ) < in_order_validation_mock.mock_calls.index(call._message_repository.consume_queue) - - def test_handle_partition(self): - stream_instances_to_read_from = [self._another_stream] - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - - handler.on_partition(self._a_closed_partition) - - self._thread_pool_manager.submit.assert_called_with(self._partition_reader.process_partition, self._a_closed_partition) - assert self._a_closed_partition in handler._streams_to_running_partitions[_ANOTHER_STREAM_NAME] - - def test_handle_partition_emits_log_message_if_it_should_be_logged(self): - stream_instances_to_read_from = [self._stream] - self._slice_logger = Mock(spec=SliceLogger) - self._slice_logger.should_log_slice_message.return_value = True - self._slice_logger.create_slice_log_message.return_value = self._log_message - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - - handler.on_partition(self._an_open_partition) - - self._thread_pool_manager.submit.assert_called_with(self._partition_reader.process_partition, self._an_open_partition) - self._message_repository.emit_message.assert_called_with(self._log_message) - - assert self._an_open_partition in handler._streams_to_running_partitions[_STREAM_NAME] - - @freezegun.freeze_time("2020-01-01T00:00:00") - def test_handle_on_partition_complete_sentinel_with_messages_from_repository(self): - stream_instances_to_read_from = [self._stream] - partition = Mock(spec=Partition) - log_message = Mock(spec=LogMessage) - partition.to_slice.return_value = log_message - partition.stream_name.return_value = _STREAM_NAME - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - handler.start_next_partition_generator() - handler.on_partition(partition) - - sentinel = PartitionCompleteSentinel(partition) - - self._message_repository.consume_queue.return_value = [ - AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=LogLevel.INFO, message="message emitted from the repository")) - ] - - messages = list(handler.on_partition_complete_sentinel(sentinel)) - - expected_messages = [ - AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=LogLevel.INFO, message="message emitted from the repository")) - ] - assert messages == expected_messages - - partition.close.assert_called_once() - - @freezegun.freeze_time("2020-01-01T00:00:00") - def test_handle_on_partition_complete_sentinel_yields_status_message_if_the_stream_is_done(self): - self._streams_currently_generating_partitions = [self._another_stream] - stream_instances_to_read_from = [self._another_stream] - log_message = Mock(spec=LogMessage) - self._a_closed_partition.to_slice.return_value = log_message - self._message_repository.consume_queue.return_value = [] - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - handler.start_next_partition_generator() - handler.on_partition(self._a_closed_partition) - list(handler.on_partition_generation_completed(PartitionGenerationCompletedSentinel(self._another_stream))) - - sentinel = PartitionCompleteSentinel(self._a_closed_partition) - - messages = list(handler.on_partition_complete_sentinel(sentinel)) - - expected_messages = [ - AirbyteMessage( - type=MessageType.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor( - name=_ANOTHER_STREAM_NAME, - ), - status=AirbyteStreamStatus.COMPLETE, - ), - emitted_at=1577836800000.0, - ), - ) - ] - assert messages == expected_messages - self._a_closed_partition.close.assert_called_once() - - @freezegun.freeze_time("2020-01-01T00:00:00") - def test_given_exception_on_partition_complete_sentinel_then_yield_error_trace_message_and_stream_is_incomplete(self) -> None: - self._a_closed_partition.stream_name.return_value = self._stream.name - self._a_closed_partition.close.side_effect = ValueError - - handler = ConcurrentReadProcessor( - [self._stream], - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - handler.start_next_partition_generator() - handler.on_partition(self._a_closed_partition) - list(handler.on_partition_generation_completed(PartitionGenerationCompletedSentinel(self._stream))) - messages = list(handler.on_partition_complete_sentinel(PartitionCompleteSentinel(self._a_closed_partition))) - - expected_status_message = AirbyteMessage( - type=MessageType.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor( - name=self._stream.name, - ), - status=AirbyteStreamStatus.INCOMPLETE, - ), - emitted_at=1577836800000.0, - ), - ) - assert list(map(lambda message: message.trace.type, messages)) == [TraceType.ERROR, TraceType.STREAM_STATUS] - assert messages[1] == expected_status_message - - @freezegun.freeze_time("2020-01-01T00:00:00") - def test_handle_on_partition_complete_sentinel_yields_no_status_message_if_the_stream_is_not_done(self): - stream_instances_to_read_from = [self._stream] - partition = Mock(spec=Partition) - log_message = Mock(spec=LogMessage) - partition.to_slice.return_value = log_message - partition.stream_name.return_value = _STREAM_NAME - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - handler.start_next_partition_generator() - - sentinel = PartitionCompleteSentinel(partition) - - messages = list(handler.on_partition_complete_sentinel(sentinel)) - - expected_messages = [] - assert messages == expected_messages - partition.close.assert_called_once() - - @freezegun.freeze_time("2020-01-01T00:00:00") - def test_on_record_no_status_message_no_repository_messge(self): - stream_instances_to_read_from = [self._stream] - partition = Mock(spec=Partition) - log_message = Mock(spec=LogMessage) - partition.to_slice.return_value = log_message - partition.stream_name.return_value = _STREAM_NAME - self._message_repository.consume_queue.return_value = [] - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - - # Simulate a first record - list(handler.on_record(self._record)) - - messages = list(handler.on_record(self._record)) - - expected_messages = [ - AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage( - stream=_STREAM_NAME, - data=self._record_data, - emitted_at=1577836800000, - ), - ) - ] - assert messages == expected_messages - - @freezegun.freeze_time("2020-01-01T00:00:00") - def test_on_record_with_repository_messge(self): - stream_instances_to_read_from = [self._stream] - partition = Mock(spec=Partition) - log_message = Mock(spec=LogMessage) - partition.to_slice.return_value = log_message - partition.stream_name.return_value = _STREAM_NAME - slice_logger = Mock(spec=SliceLogger) - slice_logger.should_log_slice_message.return_value = True - slice_logger.create_slice_log_message.return_value = log_message - self._message_repository.consume_queue.return_value = [ - AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=LogLevel.INFO, message="message emitted from the repository")) - ] - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - - stream = Mock(spec=AbstractStream) - stream.name = _STREAM_NAME - stream.as_airbyte_stream.return_value = AirbyteStream( - name=_STREAM_NAME, - json_schema={}, - supported_sync_modes=[SyncMode.full_refresh], - ) - - # Simulate a first record - list(handler.on_record(self._record)) - - messages = list(handler.on_record(self._record)) - - expected_messages = [ - AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage( - stream=_STREAM_NAME, - data=self._record_data, - emitted_at=1577836800000, - ), - ), - AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=LogLevel.INFO, message="message emitted from the repository")), - ] - assert messages == expected_messages - assert handler._record_counter[_STREAM_NAME] == 2 - - @freezegun.freeze_time("2020-01-01T00:00:00") - def test_on_record_emits_status_message_on_first_record_no_repository_message(self): - self._streams_currently_generating_partitions = [_STREAM_NAME] - stream_instances_to_read_from = [self._stream] - partition = Mock(spec=Partition) - partition.stream_name.return_value = _STREAM_NAME - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - - messages = list(handler.on_record(self._record)) - - expected_messages = [ - AirbyteMessage( - type=MessageType.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - emitted_at=1577836800000.0, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name=_STREAM_NAME), status=AirbyteStreamStatus(AirbyteStreamStatus.RUNNING) - ), - ), - ), - AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage( - stream=_STREAM_NAME, - data=self._record_data, - emitted_at=1577836800000, - ), - ), - ] - assert messages == expected_messages - - @freezegun.freeze_time("2020-01-01T00:00:00") - def test_on_record_emits_status_message_on_first_record_with_repository_message(self): - stream_instances_to_read_from = [self._stream] - partition = Mock(spec=Partition) - log_message = Mock(spec=LogMessage) - partition.to_slice.return_value = log_message - partition.stream_name.return_value = _STREAM_NAME - self._message_repository.consume_queue.return_value = [ - AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=LogLevel.INFO, message="message emitted from the repository")) - ] - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - - stream = Mock(spec=AbstractStream) - stream.name = _STREAM_NAME - stream.as_airbyte_stream.return_value = AirbyteStream( - name=_STREAM_NAME, - json_schema={}, - supported_sync_modes=[SyncMode.full_refresh], - ) - - messages = list(handler.on_record(self._record)) - - expected_messages = [ - AirbyteMessage( - type=MessageType.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - emitted_at=1577836800000.0, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name=_STREAM_NAME), status=AirbyteStreamStatus(AirbyteStreamStatus.RUNNING) - ), - ), - ), - AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage( - stream=_STREAM_NAME, - data=self._record_data, - emitted_at=1577836800000, - ), - ), - AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=LogLevel.INFO, message="message emitted from the repository")), - ] - assert messages == expected_messages - - @freezegun.freeze_time("2020-01-01T00:00:00") - def test_on_exception_return_trace_message_and_on_stream_complete_return_stream_status(self): - stream_instances_to_read_from = [self._stream, self._another_stream] - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - - handler.start_next_partition_generator() - handler.on_partition(self._an_open_partition) - list(handler.on_partition_generation_completed(PartitionGenerationCompletedSentinel(self._stream))) - list(handler.on_partition_generation_completed(PartitionGenerationCompletedSentinel(self._another_stream))) - - another_stream = Mock(spec=AbstractStream) - another_stream.name = _STREAM_NAME - another_stream.as_airbyte_stream.return_value = AirbyteStream( - name=_ANOTHER_STREAM_NAME, - json_schema={}, - supported_sync_modes=[SyncMode.full_refresh], - ) - - exception = StreamThreadException(RuntimeError("Something went wrong"), _STREAM_NAME) - - exception_messages = list(handler.on_exception(exception)) - assert len(exception_messages) == 1 - assert "StreamThreadException" in exception_messages[0].trace.error.stack_trace - - assert list(handler.on_partition_complete_sentinel(PartitionCompleteSentinel(self._an_open_partition))) == [ - AirbyteMessage( - type=MessageType.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - emitted_at=1577836800000.0, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name=_STREAM_NAME), status=AirbyteStreamStatus(AirbyteStreamStatus.INCOMPLETE) - ), - ), - ) - ] - with pytest.raises(AirbyteTracedException): - handler.is_done() - - @freezegun.freeze_time("2020-01-01T00:00:00") - def test_given_underlying_exception_is_traced_exception_on_exception_return_trace_message_and_on_stream_complete_return_stream_status( - self, - ): - stream_instances_to_read_from = [self._stream, self._another_stream] - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - - handler.start_next_partition_generator() - handler.on_partition(self._an_open_partition) - list(handler.on_partition_generation_completed(PartitionGenerationCompletedSentinel(self._stream))) - list(handler.on_partition_generation_completed(PartitionGenerationCompletedSentinel(self._another_stream))) - - another_stream = Mock(spec=AbstractStream) - another_stream.name = _STREAM_NAME - another_stream.as_airbyte_stream.return_value = AirbyteStream( - name=_ANOTHER_STREAM_NAME, - json_schema={}, - supported_sync_modes=[SyncMode.full_refresh], - ) - - underlying_exception = AirbyteTracedException() - exception = StreamThreadException(underlying_exception, _STREAM_NAME) - - exception_messages = list(handler.on_exception(exception)) - assert len(exception_messages) == 1 - assert "AirbyteTracedException" in exception_messages[0].trace.error.stack_trace - - assert list(handler.on_partition_complete_sentinel(PartitionCompleteSentinel(self._an_open_partition))) == [ - AirbyteMessage( - type=MessageType.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - emitted_at=1577836800000.0, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name=_STREAM_NAME), status=AirbyteStreamStatus(AirbyteStreamStatus.INCOMPLETE) - ), - ), - ) - ] - with pytest.raises(AirbyteTracedException): - handler.is_done() - - def test_given_partition_completion_is_not_success_then_do_not_close_partition(self): - stream_instances_to_read_from = [self._stream, self._another_stream] - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - - handler.start_next_partition_generator() - handler.on_partition(self._an_open_partition) - list(handler.on_partition_generation_completed(PartitionGenerationCompletedSentinel(self._stream))) - - list(handler.on_partition_complete_sentinel(PartitionCompleteSentinel(self._an_open_partition, not _IS_SUCCESSFUL))) - - assert self._an_open_partition.close.call_count == 0 - - def test_given_partition_completion_is_not_success_then_do_not_close_partition(self): - stream_instances_to_read_from = [self._stream, self._another_stream] - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - - handler.start_next_partition_generator() - handler.on_partition(self._an_open_partition) - list(handler.on_partition_generation_completed(PartitionGenerationCompletedSentinel(self._stream))) - - list(handler.on_partition_complete_sentinel(PartitionCompleteSentinel(self._an_open_partition, not _IS_SUCCESSFUL))) - - assert self._an_open_partition.close.call_count == 0 - - def test_is_done_is_false_if_there_are_any_instances_to_read_from(self): - stream_instances_to_read_from = [self._stream] - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - - assert not handler.is_done() - - def test_is_done_is_false_if_there_are_streams_still_generating_partitions(self): - stream_instances_to_read_from = [self._stream] - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - - handler.start_next_partition_generator() - - assert not handler.is_done() - - def test_is_done_is_false_if_all_partitions_are_not_closed(self): - stream_instances_to_read_from = [self._stream] - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - - handler.start_next_partition_generator() - handler.on_partition(self._an_open_partition) - handler.on_partition_generation_completed(PartitionGenerationCompletedSentinel(self._stream)) - - assert not handler.is_done() - - def test_is_done_is_true_if_all_partitions_are_closed_and_no_streams_are_generating_partitions_and_none_are_still_to_run(self): - stream_instances_to_read_from = [] - - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - - assert handler.is_done() - - @freezegun.freeze_time("2020-01-01T00:00:00") - def test_start_next_partition_generator(self): - stream_instances_to_read_from = [self._stream] - handler = ConcurrentReadProcessor( - stream_instances_to_read_from, - self._partition_enqueuer, - self._thread_pool_manager, - self._logger, - self._slice_logger, - self._message_repository, - self._partition_reader, - ) - - status_message = handler.start_next_partition_generator() - - assert status_message == AirbyteMessage( - type=MessageType.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - emitted_at=1577836800000.0, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name=_STREAM_NAME), status=AirbyteStreamStatus(AirbyteStreamStatus.STARTED) - ), - ), - ) - - assert _STREAM_NAME in handler._streams_currently_generating_partitions - self._thread_pool_manager.submit.assert_called_with(self._partition_enqueuer.generate_partitions, self._stream) diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_cursor.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_cursor.py deleted file mode 100644 index 1327bafda7ea..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_cursor.py +++ /dev/null @@ -1,897 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from datetime import datetime, timedelta, timezone -from functools import partial -from typing import Any, Mapping, Optional -from unittest import TestCase -from unittest.mock import Mock - -import freezegun -import pytest -from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager -from airbyte_cdk.sources.declarative.datetime.min_max_datetime import MinMaxDatetime -from airbyte_cdk.sources.declarative.incremental.datetime_based_cursor import DatetimeBasedCursor -from airbyte_cdk.sources.message import MessageRepository -from airbyte_cdk.sources.streams.concurrent.cursor import ConcurrentCursor, CursorField, CursorValueType -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record -from airbyte_cdk.sources.streams.concurrent.state_converters.abstract_stream_state_converter import ConcurrencyCompatibleStateType -from airbyte_cdk.sources.streams.concurrent.state_converters.datetime_stream_state_converter import ( - EpochValueConcurrentStreamStateConverter, - IsoMillisConcurrentStreamStateConverter, -) -from isodate import parse_duration - -_A_STREAM_NAME = "a stream name" -_A_STREAM_NAMESPACE = "a stream namespace" -_A_CURSOR_FIELD_KEY = "a_cursor_field_key" -_NO_STATE = {} -_NO_PARTITION_IDENTIFIER = None -_NO_SLICE = None -_NO_SLICE_BOUNDARIES = None -_LOWER_SLICE_BOUNDARY_FIELD = "lower_boundary" -_UPPER_SLICE_BOUNDARY_FIELD = "upper_boundary" -_SLICE_BOUNDARY_FIELDS = (_LOWER_SLICE_BOUNDARY_FIELD, _UPPER_SLICE_BOUNDARY_FIELD) -_A_VERY_HIGH_CURSOR_VALUE = 1000000000 -_NO_LOOKBACK_WINDOW = timedelta(seconds=0) - - -def _partition(_slice: Optional[Mapping[str, Any]], _stream_name: Optional[str] = Mock()) -> Partition: - partition = Mock(spec=Partition) - partition.to_slice.return_value = _slice - partition.stream_name.return_value = _stream_name - return partition - - -def _record(cursor_value: CursorValueType, partition: Optional[Partition] = Mock(spec=Partition)) -> Record: - return Record(data={_A_CURSOR_FIELD_KEY: cursor_value}, partition=partition) - - -class ConcurrentCursorStateTest(TestCase): - def setUp(self) -> None: - self._message_repository = Mock(spec=MessageRepository) - self._state_manager = Mock(spec=ConnectorStateManager) - - def _cursor_with_slice_boundary_fields(self, is_sequential_state=True) -> ConcurrentCursor: - return ConcurrentCursor( - _A_STREAM_NAME, - _A_STREAM_NAMESPACE, - {}, - self._message_repository, - self._state_manager, - EpochValueConcurrentStreamStateConverter(is_sequential_state), - CursorField(_A_CURSOR_FIELD_KEY), - _SLICE_BOUNDARY_FIELDS, - None, - EpochValueConcurrentStreamStateConverter.get_end_provider(), - _NO_LOOKBACK_WINDOW, - ) - - def _cursor_without_slice_boundary_fields(self) -> ConcurrentCursor: - return ConcurrentCursor( - _A_STREAM_NAME, - _A_STREAM_NAMESPACE, - {}, - self._message_repository, - self._state_manager, - EpochValueConcurrentStreamStateConverter(is_sequential_state=True), - CursorField(_A_CURSOR_FIELD_KEY), - None, - None, - EpochValueConcurrentStreamStateConverter.get_end_provider(), - _NO_LOOKBACK_WINDOW, - ) - - def test_given_boundary_fields_when_close_partition_then_emit_state(self) -> None: - cursor = self._cursor_with_slice_boundary_fields() - cursor.close_partition( - _partition( - {_LOWER_SLICE_BOUNDARY_FIELD: 12, _UPPER_SLICE_BOUNDARY_FIELD: 30}, - ) - ) - - self._message_repository.emit_message.assert_called_once_with(self._state_manager.create_state_message.return_value) - self._state_manager.update_state_for_stream.assert_called_once_with( - _A_STREAM_NAME, - _A_STREAM_NAMESPACE, - {_A_CURSOR_FIELD_KEY: 0}, # State message is updated to the legacy format before being emitted - ) - - def test_given_state_not_sequential_when_close_partition_then_emit_state(self) -> None: - cursor = self._cursor_with_slice_boundary_fields(is_sequential_state=False) - cursor.close_partition( - _partition( - {_LOWER_SLICE_BOUNDARY_FIELD: 12, _UPPER_SLICE_BOUNDARY_FIELD: 30}, - ) - ) - - self._message_repository.emit_message.assert_called_once_with(self._state_manager.create_state_message.return_value) - self._state_manager.update_state_for_stream.assert_called_once_with( - _A_STREAM_NAME, - _A_STREAM_NAMESPACE, - {"slices": [{"end": 0, "start": 0}, {"end": 30, "start": 12}], "state_type": "date-range"}, - ) - - def test_close_partition_emits_message_to_lower_boundary_when_no_prior_state_exists(self) -> None: - self._cursor_with_slice_boundary_fields().close_partition( - _partition( - {_LOWER_SLICE_BOUNDARY_FIELD: 0, _UPPER_SLICE_BOUNDARY_FIELD: 30}, - ) - ) - - self._message_repository.emit_message.assert_called_once_with(self._state_manager.create_state_message.return_value) - self._state_manager.update_state_for_stream.assert_called_once_with( - _A_STREAM_NAME, - _A_STREAM_NAMESPACE, - {_A_CURSOR_FIELD_KEY: 0}, # State message is updated to the lower slice boundary - ) - - def test_given_boundary_fields_and_record_observed_when_close_partition_then_ignore_records(self) -> None: - cursor = self._cursor_with_slice_boundary_fields() - cursor.observe(_record(_A_VERY_HIGH_CURSOR_VALUE)) - - cursor.close_partition(_partition({_LOWER_SLICE_BOUNDARY_FIELD: 12, _UPPER_SLICE_BOUNDARY_FIELD: 30})) - - assert self._state_manager.update_state_for_stream.call_args_list[0].args[2][_A_CURSOR_FIELD_KEY] != _A_VERY_HIGH_CURSOR_VALUE - - def test_given_no_boundary_fields_when_close_partition_then_emit_state(self) -> None: - cursor = self._cursor_without_slice_boundary_fields() - partition = _partition(_NO_SLICE) - cursor.observe(_record(10, partition=partition)) - cursor.close_partition(partition) - - self._state_manager.update_state_for_stream.assert_called_once_with( - _A_STREAM_NAME, - _A_STREAM_NAMESPACE, - {"a_cursor_field_key": 10}, - ) - - def test_given_no_boundary_fields_when_close_multiple_partitions_then_raise_exception(self) -> None: - cursor = self._cursor_without_slice_boundary_fields() - partition = _partition(_NO_SLICE) - cursor.observe(_record(10, partition=partition)) - cursor.close_partition(partition) - - with pytest.raises(ValueError): - cursor.close_partition(partition) - - def test_given_no_records_observed_when_close_partition_then_do_not_emit_state(self) -> None: - cursor = self._cursor_without_slice_boundary_fields() - cursor.close_partition(_partition(_NO_SLICE)) - assert self._message_repository.emit_message.call_count == 0 - - def test_given_slice_boundaries_and_no_slice_when_close_partition_then_raise_error(self) -> None: - cursor = self._cursor_with_slice_boundary_fields() - with pytest.raises(KeyError): - cursor.close_partition(_partition(_NO_SLICE)) - - def test_given_slice_boundaries_not_matching_slice_when_close_partition_then_raise_error(self) -> None: - cursor = self._cursor_with_slice_boundary_fields() - with pytest.raises(KeyError): - cursor.close_partition(_partition({"not_matching_key": "value"})) - - @freezegun.freeze_time(time_to_freeze=datetime.fromtimestamp(50, timezone.utc)) - def test_given_no_state_when_generate_slices_then_create_slice_from_start_to_end(self): - start = datetime.fromtimestamp(10, timezone.utc) - cursor = ConcurrentCursor( - _A_STREAM_NAME, - _A_STREAM_NAMESPACE, - _NO_STATE, - self._message_repository, - self._state_manager, - EpochValueConcurrentStreamStateConverter(is_sequential_state=False), - CursorField(_A_CURSOR_FIELD_KEY), - _SLICE_BOUNDARY_FIELDS, - start, - EpochValueConcurrentStreamStateConverter.get_end_provider(), - _NO_LOOKBACK_WINDOW, - ) - - slices = list(cursor.generate_slices()) - - assert slices == [ - (datetime.fromtimestamp(10, timezone.utc), datetime.fromtimestamp(50, timezone.utc)), - ] - - @freezegun.freeze_time(time_to_freeze=datetime.fromtimestamp(50, timezone.utc)) - def test_given_one_slice_when_generate_slices_then_create_slice_from_slice_upper_boundary_to_end(self): - start = datetime.fromtimestamp(0, timezone.utc) - cursor = ConcurrentCursor( - _A_STREAM_NAME, - _A_STREAM_NAMESPACE, - { - "state_type": ConcurrencyCompatibleStateType.date_range.value, - "slices": [ - {EpochValueConcurrentStreamStateConverter.START_KEY: 0, EpochValueConcurrentStreamStateConverter.END_KEY: 20}, - ], - }, - self._message_repository, - self._state_manager, - EpochValueConcurrentStreamStateConverter(is_sequential_state=False), - CursorField(_A_CURSOR_FIELD_KEY), - _SLICE_BOUNDARY_FIELDS, - start, - EpochValueConcurrentStreamStateConverter.get_end_provider(), - _NO_LOOKBACK_WINDOW, - ) - - slices = list(cursor.generate_slices()) - - assert slices == [ - (datetime.fromtimestamp(20, timezone.utc), datetime.fromtimestamp(50, timezone.utc)), - ] - - @freezegun.freeze_time(time_to_freeze=datetime.fromtimestamp(50, timezone.utc)) - def test_given_start_after_slices_when_generate_slices_then_generate_from_start(self): - start = datetime.fromtimestamp(30, timezone.utc) - cursor = ConcurrentCursor( - _A_STREAM_NAME, - _A_STREAM_NAMESPACE, - { - "state_type": ConcurrencyCompatibleStateType.date_range.value, - "slices": [ - {EpochValueConcurrentStreamStateConverter.START_KEY: 0, EpochValueConcurrentStreamStateConverter.END_KEY: 20}, - ], - }, - self._message_repository, - self._state_manager, - EpochValueConcurrentStreamStateConverter(is_sequential_state=False), - CursorField(_A_CURSOR_FIELD_KEY), - _SLICE_BOUNDARY_FIELDS, - start, - EpochValueConcurrentStreamStateConverter.get_end_provider(), - _NO_LOOKBACK_WINDOW, - ) - - slices = list(cursor.generate_slices()) - - assert slices == [ - (datetime.fromtimestamp(30, timezone.utc), datetime.fromtimestamp(50, timezone.utc)), - ] - - @freezegun.freeze_time(time_to_freeze=datetime.fromtimestamp(50, timezone.utc)) - def test_given_state_with_gap_and_start_after_slices_when_generate_slices_then_generate_from_start(self): - start = datetime.fromtimestamp(30, timezone.utc) - cursor = ConcurrentCursor( - _A_STREAM_NAME, - _A_STREAM_NAMESPACE, - { - "state_type": ConcurrencyCompatibleStateType.date_range.value, - "slices": [ - {EpochValueConcurrentStreamStateConverter.START_KEY: 0, EpochValueConcurrentStreamStateConverter.END_KEY: 10}, - {EpochValueConcurrentStreamStateConverter.START_KEY: 15, EpochValueConcurrentStreamStateConverter.END_KEY: 20}, - ], - }, - self._message_repository, - self._state_manager, - EpochValueConcurrentStreamStateConverter(is_sequential_state=False), - CursorField(_A_CURSOR_FIELD_KEY), - _SLICE_BOUNDARY_FIELDS, - start, - EpochValueConcurrentStreamStateConverter.get_end_provider(), - _NO_LOOKBACK_WINDOW, - ) - - slices = list(cursor.generate_slices()) - - assert slices == [ - (datetime.fromtimestamp(30, timezone.utc), datetime.fromtimestamp(50, timezone.utc)), - ] - - @freezegun.freeze_time(time_to_freeze=datetime.fromtimestamp(50, timezone.utc)) - def test_given_small_slice_range_when_generate_slices_then_create_many_slices(self): - start = datetime.fromtimestamp(0, timezone.utc) - small_slice_range = timedelta(seconds=10) - cursor = ConcurrentCursor( - _A_STREAM_NAME, - _A_STREAM_NAMESPACE, - { - "state_type": ConcurrencyCompatibleStateType.date_range.value, - "slices": [ - {EpochValueConcurrentStreamStateConverter.START_KEY: 0, EpochValueConcurrentStreamStateConverter.END_KEY: 20}, - ], - }, - self._message_repository, - self._state_manager, - EpochValueConcurrentStreamStateConverter(is_sequential_state=False), - CursorField(_A_CURSOR_FIELD_KEY), - _SLICE_BOUNDARY_FIELDS, - start, - EpochValueConcurrentStreamStateConverter.get_end_provider(), - _NO_LOOKBACK_WINDOW, - small_slice_range, - ) - - slices = list(cursor.generate_slices()) - - assert slices == [ - (datetime.fromtimestamp(20, timezone.utc), datetime.fromtimestamp(30, timezone.utc)), - (datetime.fromtimestamp(30, timezone.utc), datetime.fromtimestamp(40, timezone.utc)), - (datetime.fromtimestamp(40, timezone.utc), datetime.fromtimestamp(50, timezone.utc)), - ] - - @freezegun.freeze_time(time_to_freeze=datetime.fromtimestamp(50, timezone.utc)) - def test_given_difference_between_slices_match_slice_range_when_generate_slices_then_create_one_slice(self): - start = datetime.fromtimestamp(0, timezone.utc) - small_slice_range = timedelta(seconds=10) - cursor = ConcurrentCursor( - _A_STREAM_NAME, - _A_STREAM_NAMESPACE, - { - "state_type": ConcurrencyCompatibleStateType.date_range.value, - "slices": [ - {EpochValueConcurrentStreamStateConverter.START_KEY: 0, EpochValueConcurrentStreamStateConverter.END_KEY: 30}, - {EpochValueConcurrentStreamStateConverter.START_KEY: 40, EpochValueConcurrentStreamStateConverter.END_KEY: 50}, - ], - }, - self._message_repository, - self._state_manager, - EpochValueConcurrentStreamStateConverter(is_sequential_state=False), - CursorField(_A_CURSOR_FIELD_KEY), - _SLICE_BOUNDARY_FIELDS, - start, - EpochValueConcurrentStreamStateConverter.get_end_provider(), - _NO_LOOKBACK_WINDOW, - small_slice_range, - ) - - slices = list(cursor.generate_slices()) - - assert slices == [ - (datetime.fromtimestamp(30, timezone.utc), datetime.fromtimestamp(40, timezone.utc)), - ] - - @freezegun.freeze_time(time_to_freeze=datetime.fromtimestamp(50, timezone.utc)) - def test_given_non_continuous_state_when_generate_slices_then_create_slices_between_gaps_and_after(self): - cursor = ConcurrentCursor( - _A_STREAM_NAME, - _A_STREAM_NAMESPACE, - { - "state_type": ConcurrencyCompatibleStateType.date_range.value, - "slices": [ - {EpochValueConcurrentStreamStateConverter.START_KEY: 0, EpochValueConcurrentStreamStateConverter.END_KEY: 10}, - {EpochValueConcurrentStreamStateConverter.START_KEY: 20, EpochValueConcurrentStreamStateConverter.END_KEY: 25}, - {EpochValueConcurrentStreamStateConverter.START_KEY: 30, EpochValueConcurrentStreamStateConverter.END_KEY: 40}, - ], - }, - self._message_repository, - self._state_manager, - EpochValueConcurrentStreamStateConverter(is_sequential_state=False), - CursorField(_A_CURSOR_FIELD_KEY), - _SLICE_BOUNDARY_FIELDS, - None, - EpochValueConcurrentStreamStateConverter.get_end_provider(), - _NO_LOOKBACK_WINDOW, - ) - - slices = list(cursor.generate_slices()) - - assert slices == [ - (datetime.fromtimestamp(10, timezone.utc), datetime.fromtimestamp(20, timezone.utc)), - (datetime.fromtimestamp(25, timezone.utc), datetime.fromtimestamp(30, timezone.utc)), - (datetime.fromtimestamp(40, timezone.utc), datetime.fromtimestamp(50, timezone.utc)), - ] - - @freezegun.freeze_time(time_to_freeze=datetime.fromtimestamp(50, timezone.utc)) - def test_given_lookback_window_when_generate_slices_then_apply_lookback_on_most_recent_slice(self): - start = datetime.fromtimestamp(0, timezone.utc) - lookback_window = timedelta(seconds=10) - cursor = ConcurrentCursor( - _A_STREAM_NAME, - _A_STREAM_NAMESPACE, - { - "state_type": ConcurrencyCompatibleStateType.date_range.value, - "slices": [ - {EpochValueConcurrentStreamStateConverter.START_KEY: 0, EpochValueConcurrentStreamStateConverter.END_KEY: 20}, - {EpochValueConcurrentStreamStateConverter.START_KEY: 30, EpochValueConcurrentStreamStateConverter.END_KEY: 40}, - ], - }, - self._message_repository, - self._state_manager, - EpochValueConcurrentStreamStateConverter(is_sequential_state=False), - CursorField(_A_CURSOR_FIELD_KEY), - _SLICE_BOUNDARY_FIELDS, - start, - EpochValueConcurrentStreamStateConverter.get_end_provider(), - lookback_window, - ) - - slices = list(cursor.generate_slices()) - - assert slices == [ - (datetime.fromtimestamp(20, timezone.utc), datetime.fromtimestamp(30, timezone.utc)), - (datetime.fromtimestamp(30, timezone.utc), datetime.fromtimestamp(50, timezone.utc)), - ] - - @freezegun.freeze_time(time_to_freeze=datetime.fromtimestamp(50, timezone.utc)) - def test_given_start_is_before_first_slice_lower_boundary_when_generate_slices_then_generate_slice_before(self): - start = datetime.fromtimestamp(0, timezone.utc) - cursor = ConcurrentCursor( - _A_STREAM_NAME, - _A_STREAM_NAMESPACE, - { - "state_type": ConcurrencyCompatibleStateType.date_range.value, - "slices": [ - {EpochValueConcurrentStreamStateConverter.START_KEY: 10, EpochValueConcurrentStreamStateConverter.END_KEY: 20}, - ], - }, - self._message_repository, - self._state_manager, - EpochValueConcurrentStreamStateConverter(is_sequential_state=False), - CursorField(_A_CURSOR_FIELD_KEY), - _SLICE_BOUNDARY_FIELDS, - start, - EpochValueConcurrentStreamStateConverter.get_end_provider(), - _NO_LOOKBACK_WINDOW, - ) - - slices = list(cursor.generate_slices()) - - assert slices == [ - (datetime.fromtimestamp(0, timezone.utc), datetime.fromtimestamp(10, timezone.utc)), - (datetime.fromtimestamp(20, timezone.utc), datetime.fromtimestamp(50, timezone.utc)), - ] - - -@freezegun.freeze_time(time_to_freeze=datetime(2024, 4, 1, 0, 0, 0, 0, tzinfo=timezone.utc)) -@pytest.mark.parametrize( - "start_datetime,end_datetime,step,cursor_field,lookback_window,state,expected_slices", - [ - pytest.param( - "{{ config.start_time }}", - "{{ config.end_time or now_utc() }}", - "P10D", - "updated_at", - "P5D", - {}, - [ - (datetime(2024, 1, 1, 0, 0, tzinfo=timezone.utc), datetime(2024, 1, 10, 23, 59, 59, tzinfo=timezone.utc)), - (datetime(2024, 1, 11, 0, 0, tzinfo=timezone.utc), datetime(2024, 1, 20, 23, 59, 59, tzinfo=timezone.utc)), - (datetime(2024, 1, 21, 0, 0, tzinfo=timezone.utc), datetime(2024, 1, 30, 23, 59, 59, tzinfo=timezone.utc)), - (datetime(2024, 1, 31, 0, 0, tzinfo=timezone.utc), datetime(2024, 2, 9, 23, 59, 59, tzinfo=timezone.utc)), - (datetime(2024, 2, 10, 0, 0, tzinfo=timezone.utc), datetime(2024, 2, 19, 23, 59, 59, tzinfo=timezone.utc)), - (datetime(2024, 2, 20, 0, 0, tzinfo=timezone.utc), datetime(2024, 2, 29, 23, 59, 59, tzinfo=timezone.utc)) - ], - id="test_datetime_based_cursor_all_fields", - ), - pytest.param( - "{{ config.start_time }}", - "{{ config.end_time or '2024-01-01T00:00:00.000000+0000' }}", - "P10D", - "updated_at", - "P5D", - { - "slices": [ - { - "start": "2024-01-01T00:00:00.000000+0000", - "end": "2024-02-10T00:00:00.000000+0000", - } - ], - "state_type": "date-range" - }, - [ - (datetime(2024, 2, 5, 0, 0, 0, tzinfo=timezone.utc), datetime(2024, 2, 14, 23, 59, 59, tzinfo=timezone.utc)), - (datetime(2024, 2, 15, 0, 0, 0, tzinfo=timezone.utc), datetime(2024, 2, 24, 23, 59, 59, tzinfo=timezone.utc)), - (datetime(2024, 2, 25, 0, 0, 0, tzinfo=timezone.utc), datetime(2024, 2, 29, 23, 59, 59, tzinfo=timezone.utc)) - ], - id="test_datetime_based_cursor_with_state", - ), - pytest.param( - "{{ config.start_time }}", - "{{ config.missing or now_utc().strftime('%Y-%m-%dT%H:%M:%S.%fZ') }}", - "P20D", - "updated_at", - "P1D", - { - "slices": [ - { - "start": "2024-01-01T00:00:00.000000+0000", - "end": "2024-01-21T00:00:00.000000+0000", - } - ], - "state_type": "date-range" - }, - [ - (datetime(2024, 1, 20, 0, 0, tzinfo=timezone.utc), datetime(2024, 2, 8, 23, 59, 59, tzinfo=timezone.utc)), - (datetime(2024, 2, 9, 0, 0, tzinfo=timezone.utc), datetime(2024, 2, 28, 23, 59, 59, tzinfo=timezone.utc)), - (datetime(2024, 2, 29, 0, 0, tzinfo=timezone.utc), datetime(2024, 3, 19, 23, 59, 59, tzinfo=timezone.utc)), - (datetime(2024, 3, 20, 0, 0, tzinfo=timezone.utc), datetime(2024, 3, 31, 23, 59, 59, tzinfo=timezone.utc)), - ], - id="test_datetime_based_cursor_with_state_and_end_date", - ), - pytest.param( - "{{ config.start_time }}", - "{{ config.end_time }}", - "P1M", - "updated_at", - "P5D", - {}, - [ - (datetime(2024, 1, 1, 0, 0, 0, tzinfo=timezone.utc), datetime(2024, 1, 31, 23, 59, 59, tzinfo=timezone.utc)), - (datetime(2024, 2, 1, 0, 0, 0, tzinfo=timezone.utc), datetime(2024, 2, 29, 23, 59, 59, tzinfo=timezone.utc)), - ], - id="test_datetime_based_cursor_using_large_step_duration", - ), - ] -) -def test_generate_slices_concurrent_cursor_from_datetime_based_cursor( - start_datetime, - end_datetime, - step, - cursor_field, - lookback_window, - state, - expected_slices, -): - message_repository = Mock(spec=MessageRepository) - state_manager = Mock(spec=ConnectorStateManager) - - config = { - "start_time": "2024-01-01T00:00:00.000000+0000", - "end_time": "2024-03-01T00:00:00.000000+0000", - } - - datetime_based_cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime=start_datetime, parameters={}), - end_datetime=MinMaxDatetime(datetime=end_datetime, parameters={}), - step=step, - cursor_field=cursor_field, - partition_field_start="start", - partition_field_end="end", - datetime_format="%Y-%m-%dT%H:%M:%S.%f%z", - cursor_granularity="PT1S", - lookback_window=lookback_window, - is_compare_strictly=True, - config=config, - parameters={}, - ) - - # I don't love that we're back to this inching close to interpolation at parse time instead of runtime - # We also might need to add a wrapped class that exposes these fields publicly or live with ugly private access - interpolated_state_date = datetime_based_cursor._start_datetime - start_date = interpolated_state_date.get_datetime(config=config) - - interpolated_end_date = datetime_based_cursor._end_datetime - interpolated_end_date_provider = partial(interpolated_end_date.get_datetime, config) - - interpolated_cursor_field = datetime_based_cursor.cursor_field - cursor_field = CursorField(cursor_field_key=interpolated_cursor_field.eval(config=config)) - - lower_slice_boundary = datetime_based_cursor._partition_field_start.eval(config=config) - upper_slice_boundary = datetime_based_cursor._partition_field_end.eval(config=config) - slice_boundary_fields = (lower_slice_boundary, upper_slice_boundary) - - # DatetimeBasedCursor returns an isodate.Duration if step uses month or year precision. This still works in our - # code, but mypy may complain when we actually implement this in the concurrent low-code source. To fix this, we - # may need to convert a Duration to timedelta by multiplying month by 30 (but could lose precision). - step_length = datetime_based_cursor._step - - lookback_window = parse_duration(datetime_based_cursor.lookback_window) if datetime_based_cursor.lookback_window else None - - cursor_granularity = parse_duration(datetime_based_cursor.cursor_granularity) if datetime_based_cursor.cursor_granularity else None - - cursor = ConcurrentCursor( - stream_name=_A_STREAM_NAME, - stream_namespace=_A_STREAM_NAMESPACE, - stream_state=state, - message_repository=message_repository, - connector_state_manager=state_manager, - connector_state_converter=IsoMillisConcurrentStreamStateConverter(is_sequential_state=True), - cursor_field=cursor_field, - slice_boundary_fields=slice_boundary_fields, - start=start_date, - end_provider=interpolated_end_date_provider, - lookback_window=lookback_window, - slice_range=step_length, - cursor_granularity=cursor_granularity, - ) - - actual_slices = list(cursor.generate_slices()) - assert actual_slices == expected_slices - - -@freezegun.freeze_time(time_to_freeze=datetime(2024, 9, 1, 0, 0, 0, 0, tzinfo=timezone.utc)) -def test_observe_concurrent_cursor_from_datetime_based_cursor(): - message_repository = Mock(spec=MessageRepository) - state_manager = Mock(spec=ConnectorStateManager) - - config = { - "start_time": "2024-08-01T00:00:00.000000+0000", - "dynamic_cursor_key": "updated_at" - } - - datetime_based_cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="{{ config.start_time }}", parameters={}), - cursor_field="{{ config.dynamic_cursor_key }}", - datetime_format="%Y-%m-%dT%H:%M:%S.%f%z", - config=config, - parameters={}, - ) - - interpolated_state_date = datetime_based_cursor._start_datetime - start_date = interpolated_state_date.get_datetime(config=config) - - interpolated_cursor_field = datetime_based_cursor.cursor_field - cursor_field = CursorField(cursor_field_key=interpolated_cursor_field.eval(config=config)) - - step_length = datetime_based_cursor._step - - concurrent_cursor = ConcurrentCursor( - stream_name="gods", - stream_namespace=_A_STREAM_NAMESPACE, - stream_state={}, - message_repository=message_repository, - connector_state_manager=state_manager, - connector_state_converter=IsoMillisConcurrentStreamStateConverter(is_sequential_state=True), - cursor_field=cursor_field, - slice_boundary_fields=None, - start=start_date, - end_provider=IsoMillisConcurrentStreamStateConverter.get_end_provider(), - slice_range=step_length, - ) - - partition = _partition( - {_LOWER_SLICE_BOUNDARY_FIELD: "2024-08-01T00:00:00.000000+0000", _UPPER_SLICE_BOUNDARY_FIELD: "2024-09-01T00:00:00.000000+0000"}, - _stream_name="gods", - ) - - record_1 = Record( - partition=partition, data={"id": "999", "updated_at": "2024-08-23T00:00:00.000000+0000", "name": "kratos", "mythology": "greek"}, - ) - record_2 = Record( - partition=partition, data={"id": "1000", "updated_at": "2024-08-22T00:00:00.000000+0000", "name": "odin", "mythology": "norse"}, - ) - record_3 = Record( - partition=partition, data={"id": "500", "updated_at": "2024-08-24T00:00:00.000000+0000", "name": "freya", "mythology": "norse"}, - ) - - concurrent_cursor.observe(record_1) - actual_most_recent_record = concurrent_cursor._most_recent_cursor_value_per_partition[partition] - assert actual_most_recent_record == concurrent_cursor._extract_cursor_value(record_1) - - concurrent_cursor.observe(record_2) - actual_most_recent_record = concurrent_cursor._most_recent_cursor_value_per_partition[partition] - assert actual_most_recent_record == concurrent_cursor._extract_cursor_value(record_1) - - concurrent_cursor.observe(record_3) - actual_most_recent_record = concurrent_cursor._most_recent_cursor_value_per_partition[partition] - assert actual_most_recent_record == concurrent_cursor._extract_cursor_value(record_3) - - -@freezegun.freeze_time(time_to_freeze=datetime(2024, 9, 1, 0, 0, 0, 0, tzinfo=timezone.utc)) -def test_close_partition_concurrent_cursor_from_datetime_based_cursor(): - message_repository = Mock(spec=MessageRepository) - state_manager = Mock(spec=ConnectorStateManager) - - config = { - "start_time": "2024-08-01T00:00:00.000000+0000", - "dynamic_cursor_key": "updated_at" - } - - datetime_based_cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="{{ config.start_time }}", parameters={}), - cursor_field="{{ config.dynamic_cursor_key }}", - datetime_format="%Y-%m-%dT%H:%M:%S.%f%z", - config=config, - parameters={}, - ) - - interpolated_state_date = datetime_based_cursor._start_datetime - start_date = interpolated_state_date.get_datetime(config=config) - - interpolated_cursor_field = datetime_based_cursor.cursor_field - cursor_field = CursorField(cursor_field_key=interpolated_cursor_field.eval(config=config)) - - step_length = datetime_based_cursor._step - - concurrent_cursor = ConcurrentCursor( - stream_name="gods", - stream_namespace=_A_STREAM_NAMESPACE, - stream_state={}, - message_repository=message_repository, - connector_state_manager=state_manager, - connector_state_converter=IsoMillisConcurrentStreamStateConverter(is_sequential_state=False), - cursor_field=cursor_field, - slice_boundary_fields=None, - start=start_date, - end_provider=IsoMillisConcurrentStreamStateConverter.get_end_provider(), - slice_range=step_length, - ) - - partition = _partition( - {_LOWER_SLICE_BOUNDARY_FIELD: "2024-08-01T00:00:00.000000+0000", _UPPER_SLICE_BOUNDARY_FIELD: "2024-09-01T00:00:00.000000+0000"}, - _stream_name="gods", - ) - - record_1 = Record( - partition=partition, data={"id": "999", "updated_at": "2024-08-23T00:00:00.000000+0000", "name": "kratos", "mythology": "greek"}, - ) - concurrent_cursor.observe(record_1) - - concurrent_cursor.close_partition(partition) - - message_repository.emit_message.assert_called_once_with(state_manager.create_state_message.return_value) - state_manager.update_state_for_stream.assert_called_once_with( - "gods", - _A_STREAM_NAMESPACE, - { - "slices": [{"end": "2024-08-23T00:00:00.000Z", "start": "2024-08-01T00:00:00.000Z"}], - "state_type": "date-range" - }, - ) - - -@freezegun.freeze_time(time_to_freeze=datetime(2024, 9, 1, 0, 0, 0, 0, tzinfo=timezone.utc)) -def test_close_partition_with_slice_range_concurrent_cursor_from_datetime_based_cursor(): - message_repository = Mock(spec=MessageRepository) - state_manager = Mock(spec=ConnectorStateManager) - - config = { - "start_time": "2024-07-01T00:00:00.000000+0000", - "dynamic_cursor_key": "updated_at" - } - - datetime_based_cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="{{ config.start_time }}", parameters={}), - cursor_field="{{ config.dynamic_cursor_key }}", - datetime_format="%Y-%m-%dT%H:%M:%S.%f%z", - step="P15D", - cursor_granularity="P1D", - config=config, - parameters={}, - ) - - interpolated_state_date = datetime_based_cursor._start_datetime - start_date = interpolated_state_date.get_datetime(config=config) - - interpolated_cursor_field = datetime_based_cursor.cursor_field - cursor_field = CursorField(cursor_field_key=interpolated_cursor_field.eval(config=config)) - - lower_slice_boundary = datetime_based_cursor._partition_field_start.eval(config=config) - upper_slice_boundary = datetime_based_cursor._partition_field_end.eval(config=config) - slice_boundary_fields = (lower_slice_boundary, upper_slice_boundary) - - step_length = datetime_based_cursor._step - - concurrent_cursor = ConcurrentCursor( - stream_name="gods", - stream_namespace=_A_STREAM_NAMESPACE, - stream_state={}, - message_repository=message_repository, - connector_state_manager=state_manager, - connector_state_converter=IsoMillisConcurrentStreamStateConverter(is_sequential_state=False, cursor_granularity=None), - cursor_field=cursor_field, - slice_boundary_fields=slice_boundary_fields, - start=start_date, - slice_range=step_length, - cursor_granularity=None, - end_provider=IsoMillisConcurrentStreamStateConverter.get_end_provider(), - ) - - partition_0 = _partition( - {"start_time": "2024-07-01T00:00:00.000000+0000", "end_time": "2024-07-16T00:00:00.000000+0000"}, _stream_name="gods", - ) - partition_3 = _partition( - {"start_time": "2024-08-15T00:00:00.000000+0000", "end_time": "2024-08-30T00:00:00.000000+0000"}, _stream_name="gods", - ) - record_1 = Record( - partition=partition_0, data={"id": "1000", "updated_at": "2024-07-05T00:00:00.000000+0000", "name": "loki", "mythology": "norse"}, - ) - record_2 = Record( - partition=partition_3, data={"id": "999", "updated_at": "2024-08-20T00:00:00.000000+0000", "name": "kratos", "mythology": "greek"}, - ) - - concurrent_cursor.observe(record_1) - concurrent_cursor.close_partition(partition_0) - concurrent_cursor.observe(record_2) - concurrent_cursor.close_partition(partition_3) - - message_repository.emit_message.assert_called_with(state_manager.create_state_message.return_value) - assert message_repository.emit_message.call_count == 2 - state_manager.update_state_for_stream.assert_called_with( - "gods", - _A_STREAM_NAMESPACE, - { - "slices": [ - {"start": "2024-07-01T00:00:00.000Z", "end": "2024-07-16T00:00:00.000Z"}, - {"start": "2024-08-15T00:00:00.000Z", "end": "2024-08-30T00:00:00.000Z"} - - ], - "state_type": "date-range" - }, - ) - assert state_manager.update_state_for_stream.call_count == 2 - - -@freezegun.freeze_time(time_to_freeze=datetime(2024, 9, 1, 0, 0, 0, 0, tzinfo=timezone.utc)) -def test_close_partition_with_slice_range_granularity_concurrent_cursor_from_datetime_based_cursor(): - message_repository = Mock(spec=MessageRepository) - state_manager = Mock(spec=ConnectorStateManager) - - config = { - "start_time": "2024-07-01T00:00:00.000000+0000", - "dynamic_cursor_key": "updated_at" - } - - datetime_based_cursor = DatetimeBasedCursor( - start_datetime=MinMaxDatetime(datetime="{{ config.start_time }}", parameters={}), - cursor_field="{{ config.dynamic_cursor_key }}", - datetime_format="%Y-%m-%dT%H:%M:%S.%f%z", - step="P15D", - cursor_granularity="P1D", - config=config, - parameters={}, - ) - - interpolated_state_date = datetime_based_cursor._start_datetime - start_date = interpolated_state_date.get_datetime(config=config) - - interpolated_cursor_field = datetime_based_cursor.cursor_field - cursor_field = CursorField(cursor_field_key=interpolated_cursor_field.eval(config=config)) - - lower_slice_boundary = datetime_based_cursor._partition_field_start.eval(config=config) - upper_slice_boundary = datetime_based_cursor._partition_field_end.eval(config=config) - slice_boundary_fields = (lower_slice_boundary, upper_slice_boundary) - - step_length = datetime_based_cursor._step - - cursor_granularity = parse_duration(datetime_based_cursor.cursor_granularity) if datetime_based_cursor.cursor_granularity else None - - concurrent_cursor = ConcurrentCursor( - stream_name="gods", - stream_namespace=_A_STREAM_NAMESPACE, - stream_state={}, - message_repository=message_repository, - connector_state_manager=state_manager, - connector_state_converter=IsoMillisConcurrentStreamStateConverter(is_sequential_state=False, cursor_granularity=cursor_granularity), - cursor_field=cursor_field, - slice_boundary_fields=slice_boundary_fields, - start=start_date, - slice_range=step_length, - cursor_granularity=cursor_granularity, - end_provider=IsoMillisConcurrentStreamStateConverter.get_end_provider(), - ) - - partition_0 = _partition( - {"start_time": "2024-07-01T00:00:00.000000+0000", "end_time": "2024-07-15T00:00:00.000000+0000"}, _stream_name="gods", - ) - partition_1 = _partition( - {"start_time": "2024-07-16T00:00:00.000000+0000", "end_time": "2024-07-31T00:00:00.000000+0000"}, _stream_name="gods", - ) - partition_3 = _partition( - {"start_time": "2024-08-15T00:00:00.000000+0000", "end_time": "2024-08-29T00:00:00.000000+0000"}, _stream_name="gods", - ) - record_1 = Record( - partition=partition_0, data={"id": "1000", "updated_at": "2024-07-05T00:00:00.000000+0000", "name": "loki", "mythology": "norse"}, - ) - record_2 = Record( - partition=partition_1, data={"id": "2000", "updated_at": "2024-07-25T00:00:00.000000+0000", "name": "freya", "mythology": "norse"}, - ) - record_3 = Record( - partition=partition_3, data={"id": "999", "updated_at": "2024-08-20T00:00:00.000000+0000", "name": "kratos", "mythology": "greek"}, - ) - - concurrent_cursor.observe(record_1) - concurrent_cursor.close_partition(partition_0) - concurrent_cursor.observe(record_2) - concurrent_cursor.close_partition(partition_1) - concurrent_cursor.observe(record_3) - concurrent_cursor.close_partition(partition_3) - - message_repository.emit_message.assert_called_with(state_manager.create_state_message.return_value) - assert message_repository.emit_message.call_count == 3 - state_manager.update_state_for_stream.assert_called_with( - "gods", - _A_STREAM_NAMESPACE, - { - "slices": [ - {"start": "2024-07-01T00:00:00.000Z", "end": "2024-07-31T00:00:00.000Z"}, - {"start": "2024-08-15T00:00:00.000Z", "end": "2024-08-29T00:00:00.000Z"} - - ], - "state_type": "date-range" - }, - ) - assert state_manager.update_state_for_stream.call_count == 3 diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_datetime_state_converter.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_datetime_state_converter.py deleted file mode 100644 index 7a8e4027b43d..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_datetime_state_converter.py +++ /dev/null @@ -1,369 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from datetime import datetime, timezone - -import pytest -from airbyte_cdk.sources.streams.concurrent.cursor import CursorField -from airbyte_cdk.sources.streams.concurrent.state_converters.abstract_stream_state_converter import ConcurrencyCompatibleStateType -from airbyte_cdk.sources.streams.concurrent.state_converters.datetime_stream_state_converter import ( - EpochValueConcurrentStreamStateConverter, - IsoMillisConcurrentStreamStateConverter, -) - - -@pytest.mark.parametrize( - "converter, input_state, is_compatible", - [ - pytest.param( - EpochValueConcurrentStreamStateConverter(), - {"state_type": "date-range"}, - True, - id="no-input-state-is-compatible-epoch", - ), - pytest.param( - EpochValueConcurrentStreamStateConverter(), - { - "created_at": "2022_05_22", - "state_type": ConcurrencyCompatibleStateType.date_range.value, - }, - True, - id="input-state-with-date_range-is-compatible-epoch", - ), - pytest.param( - EpochValueConcurrentStreamStateConverter(), - { - "created_at": "2022_05_22", - "state_type": "fake", - }, - False, - id="input-state-with-fake-state-type-is-not-compatible-epoch", - ), - pytest.param( - EpochValueConcurrentStreamStateConverter(), - { - "created_at": "2022_05_22", - }, - False, - id="input-state-without-state_type-is-not-compatible-epoch", - ), - pytest.param( - IsoMillisConcurrentStreamStateConverter(), - {"state_type": "date-range"}, - True, - id="no-input-state-is-compatible-isomillis", - ), - pytest.param( - IsoMillisConcurrentStreamStateConverter(), - { - "created_at": "2022_05_22", - "state_type": ConcurrencyCompatibleStateType.date_range.value, - }, - True, - id="input-state-with-date_range-is-compatible-isomillis", - ), - pytest.param( - IsoMillisConcurrentStreamStateConverter(), - { - "created_at": "2022_05_22", - "state_type": "fake", - }, - False, - id="input-state-with-fake-state-type-is-not-compatible-isomillis", - ), - pytest.param( - IsoMillisConcurrentStreamStateConverter(), - { - "created_at": "2022_05_22", - }, - False, - id="input-state-without-state_type-is-not-compatible-isomillis", - ), - ], -) -def test_concurrent_stream_state_converter_is_state_message_compatible(converter, input_state, is_compatible): - assert converter.is_state_message_compatible(input_state) == is_compatible - - -@pytest.mark.parametrize( - "converter,start,state,expected_start", - [ - pytest.param( - EpochValueConcurrentStreamStateConverter(), - None, - {}, - EpochValueConcurrentStreamStateConverter().zero_value, - id="epoch-converter-no-state-no-start-start-is-zero-value", - ), - pytest.param( - EpochValueConcurrentStreamStateConverter(), - datetime.fromtimestamp(1617030403, timezone.utc), - {}, - datetime(2021, 3, 29, 15, 6, 43, tzinfo=timezone.utc), - id="epoch-converter-no-state-with-start-start-is-start", - ), - pytest.param( - EpochValueConcurrentStreamStateConverter(), - None, - {"created_at": 1617030404}, - datetime(2021, 3, 29, 15, 6, 44, tzinfo=timezone.utc), - id="epoch-converter-state-without-start-start-is-from-state", - ), - pytest.param( - EpochValueConcurrentStreamStateConverter(), - datetime.fromtimestamp(1617030404, timezone.utc), - {"created_at": 1617030403}, - datetime(2021, 3, 29, 15, 6, 44, tzinfo=timezone.utc), - id="epoch-converter-state-before-start-start-is-start", - ), - pytest.param( - EpochValueConcurrentStreamStateConverter(), - datetime.fromtimestamp(1617030403, timezone.utc), - {"created_at": 1617030404}, - datetime(2021, 3, 29, 15, 6, 44, tzinfo=timezone.utc), - id="epoch-converter-state-after-start-start-is-from-state", - ), - pytest.param( - IsoMillisConcurrentStreamStateConverter(), - None, - {}, - IsoMillisConcurrentStreamStateConverter().zero_value, - id="isomillis-converter-no-state-no-start-start-is-zero-value", - ), - pytest.param( - IsoMillisConcurrentStreamStateConverter(), - datetime(2021, 8, 22, 5, 3, 27, tzinfo=timezone.utc), - {}, - datetime(2021, 8, 22, 5, 3, 27, tzinfo=timezone.utc), - id="isomillis-converter-no-state-with-start-start-is-start", - ), - pytest.param( - IsoMillisConcurrentStreamStateConverter(), - None, - {"created_at": "2021-08-22T05:03:27.000Z"}, - datetime(2021, 8, 22, 5, 3, 27, tzinfo=timezone.utc), - id="isomillis-converter-state-without-start-start-is-from-state", - ), - pytest.param( - IsoMillisConcurrentStreamStateConverter(), - datetime(2022, 8, 22, 5, 3, 27, tzinfo=timezone.utc), - {"created_at": "2021-08-22T05:03:27.000Z"}, - datetime(2022, 8, 22, 5, 3, 27, tzinfo=timezone.utc), - id="isomillis-converter-state-before-start-start-is-start", - ), - pytest.param( - IsoMillisConcurrentStreamStateConverter(), - datetime(2022, 8, 22, 5, 3, 27, tzinfo=timezone.utc), - {"created_at": "2023-08-22T05:03:27.000Z"}, - datetime(2023, 8, 22, 5, 3, 27, tzinfo=timezone.utc), - id="isomillis-converter-state-after-start-start-is-from-state", - ), - ], -) -def test_get_sync_start(converter, start, state, expected_start): - assert converter._get_sync_start(CursorField("created_at"), state, start) == expected_start - - -@pytest.mark.parametrize( - "converter, start, sequential_state, expected_output_state", - [ - pytest.param( - EpochValueConcurrentStreamStateConverter(), - datetime.fromtimestamp(0, timezone.utc), - {}, - { - "legacy": {}, - "slices": [ - { - "start": EpochValueConcurrentStreamStateConverter().zero_value, - "end": EpochValueConcurrentStreamStateConverter().zero_value, - } - ], - "state_type": "date-range", - }, - id="empty-input-state-epoch", - ), - pytest.param( - EpochValueConcurrentStreamStateConverter(), - datetime.fromtimestamp(1577836800, timezone.utc), - {"created": 1617030403}, - { - "state_type": "date-range", - "slices": [ - { - "start": datetime(2020, 1, 1, tzinfo=timezone.utc), - "end": datetime(2021, 3, 29, 15, 6, 43, tzinfo=timezone.utc), - } - ], - "legacy": {"created": 1617030403}, - }, - id="with-input-state-epoch", - ), - pytest.param( - IsoMillisConcurrentStreamStateConverter(), - datetime(2020, 1, 1, tzinfo=timezone.utc), - {"created": "2021-08-22T05:03:27.000Z"}, - { - "state_type": "date-range", - "slices": [ - { - "start": datetime(2020, 1, 1, tzinfo=timezone.utc), - "end": datetime(2021, 8, 22, 5, 3, 27, tzinfo=timezone.utc), - } - ], - "legacy": {"created": "2021-08-22T05:03:27.000Z"}, - }, - id="with-input-state-isomillis", - ), - ], -) -def test_convert_from_sequential_state(converter, start, sequential_state, expected_output_state): - comparison_format = "%Y-%m-%dT%H:%M:%S.%f" - if expected_output_state["slices"]: - _, conversion = converter.convert_from_sequential_state(CursorField("created"), sequential_state, start) - assert conversion["state_type"] == expected_output_state["state_type"] - assert conversion["legacy"] == expected_output_state["legacy"] - for actual, expected in zip(conversion["slices"], expected_output_state["slices"]): - assert actual["start"].strftime(comparison_format) == expected["start"].strftime(comparison_format) - assert actual["end"].strftime(comparison_format) == expected["end"].strftime(comparison_format) - else: - _, conversion = converter.convert_from_sequential_state(CursorField("created"), sequential_state, start) - assert conversion == expected_output_state - - -@pytest.mark.parametrize( - "converter, concurrent_state, expected_output_state", - [ - pytest.param( - EpochValueConcurrentStreamStateConverter(), - { - "state_type": "date-range", - "slices": [ - { - "start": datetime(1970, 1, 3, 0, 0, 0, tzinfo=timezone.utc), - "end": datetime(2021, 3, 29, 15, 6, 43, tzinfo=timezone.utc), - } - ], - }, - {"created": 172800}, - id="epoch-single-slice", - ), - pytest.param( - EpochValueConcurrentStreamStateConverter(), - { - "state_type": "date-range", - "slices": [ - { - "start": datetime(1970, 1, 3, 0, 0, 0, tzinfo=timezone.utc), - "end": datetime(2021, 3, 29, 15, 6, 43, tzinfo=timezone.utc), - }, - { - "start": datetime(2020, 1, 1, 0, 0, 0, tzinfo=timezone.utc), - "end": datetime(2022, 3, 29, 15, 6, 43, tzinfo=timezone.utc), - }, - ], - }, - {"created": 172800}, - id="epoch-overlapping-slices", - ), - pytest.param( - EpochValueConcurrentStreamStateConverter(), - { - "state_type": "date-range", - "slices": [ - { - "start": datetime(1970, 1, 3, 0, 0, 0, tzinfo=timezone.utc), - "end": datetime(2021, 3, 29, 15, 6, 43, tzinfo=timezone.utc), - }, - { - "start": datetime(2022, 1, 1, 0, 0, 0, tzinfo=timezone.utc), - "end": datetime(2023, 3, 29, 15, 6, 43, tzinfo=timezone.utc), - }, - ], - }, - {"created": 172800}, - id="epoch-multiple-slices", - ), - pytest.param( - IsoMillisConcurrentStreamStateConverter(), - { - "state_type": "date-range", - "slices": [ - { - "start": datetime(1970, 1, 3, 0, 0, 0, tzinfo=timezone.utc), - "end": datetime(2021, 3, 29, 15, 6, 43, tzinfo=timezone.utc), - } - ], - }, - {"created": "1970-01-03T00:00:00.000Z"}, - id="isomillis-single-slice", - ), - pytest.param( - IsoMillisConcurrentStreamStateConverter(), - { - "state_type": "date-range", - "slices": [ - { - "start": datetime(1970, 1, 1, 0, 0, 0, tzinfo=timezone.utc), - "end": datetime(2021, 3, 29, 15, 6, 43, tzinfo=timezone.utc), - }, - { - "start": datetime(2020, 1, 1, 0, 0, 0, tzinfo=timezone.utc), - "end": datetime(2022, 3, 29, 15, 6, 43, tzinfo=timezone.utc), - }, - ], - }, - {"created": "1970-01-01T00:00:00.000Z"}, - id="isomillis-overlapping-slices", - ), - pytest.param( - IsoMillisConcurrentStreamStateConverter(), - { - "state_type": "date-range", - "slices": [ - { - "start": datetime(1970, 1, 1, 0, 0, 0, tzinfo=timezone.utc), - "end": datetime(2021, 3, 29, 15, 6, 43, tzinfo=timezone.utc), - }, - { - "start": datetime(2022, 1, 1, 0, 0, 0, tzinfo=timezone.utc), - "end": datetime(2023, 3, 29, 15, 6, 43, tzinfo=timezone.utc), - }, - ], - }, - {"created": "1970-01-01T00:00:00.000Z"}, - id="isomillis-multiple-slices", - ), - ], -) -def test_convert_to_sequential_state(converter, concurrent_state, expected_output_state): - assert converter.convert_to_state_message(CursorField("created"), concurrent_state) == expected_output_state - - -@pytest.mark.parametrize( - "converter, concurrent_state, expected_output_state", - [ - pytest.param( - EpochValueConcurrentStreamStateConverter(), - { - "state_type": ConcurrencyCompatibleStateType.date_range.value, - "start": EpochValueConcurrentStreamStateConverter().zero_value, - }, - {"created": 0}, - id="empty-slices-epoch", - ), - pytest.param( - IsoMillisConcurrentStreamStateConverter(), - { - "state_type": ConcurrencyCompatibleStateType.date_range.value, - "start": datetime(2021, 8, 22, 5, 3, 27, tzinfo=timezone.utc), - }, - {"created": "2021-08-22T05:03:27.000Z"}, - id="empty-slices-isomillis", - ), - ], -) -def test_convert_to_sequential_state_no_slices_returns_legacy_state(converter, concurrent_state, expected_output_state): - with pytest.raises(RuntimeError): - converter.convert_to_state_message(CursorField("created"), concurrent_state) diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_default_stream.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_default_stream.py deleted file mode 100644 index eef8c9fd6bb2..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_default_stream.py +++ /dev/null @@ -1,197 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import unittest -from unittest.mock import Mock - -from airbyte_cdk.models import AirbyteStream, SyncMode -from airbyte_cdk.sources.message import InMemoryMessageRepository -from airbyte_cdk.sources.streams.concurrent.availability_strategy import STREAM_AVAILABLE -from airbyte_cdk.sources.streams.concurrent.cursor import Cursor, FinalStateCursor -from airbyte_cdk.sources.streams.concurrent.default_stream import DefaultStream - - -class ThreadBasedConcurrentStreamTest(unittest.TestCase): - def setUp(self): - self._partition_generator = Mock() - self._name = "name" - self._json_schema = {} - self._availability_strategy = Mock() - self._primary_key = [] - self._cursor_field = None - self._logger = Mock() - self._cursor = Mock(spec=Cursor) - self._message_repository = InMemoryMessageRepository() - self._stream = DefaultStream( - self._partition_generator, - self._name, - self._json_schema, - self._availability_strategy, - self._primary_key, - self._cursor_field, - self._logger, - FinalStateCursor(stream_name=self._name, stream_namespace=None, message_repository=self._message_repository), - ) - - def test_get_json_schema(self): - json_schema = self._stream.get_json_schema() - assert json_schema == self._json_schema - - def test_check_availability(self): - self._availability_strategy.check_availability.return_value = STREAM_AVAILABLE - availability = self._stream.check_availability() - assert availability == STREAM_AVAILABLE - self._availability_strategy.check_availability.assert_called_once_with(self._logger) - - def test_check_for_error_raises_an_exception_if_any_of_the_futures_are_not_done(self): - futures = [Mock() for _ in range(3)] - for f in futures: - f.exception.return_value = None - futures[0].done.return_value = False - - with self.assertRaises(Exception): - self._stream._check_for_errors(futures) - - def test_check_for_error_raises_an_exception_if_any_of_the_futures_raised_an_exception(self): - futures = [Mock() for _ in range(3)] - for f in futures: - f.exception.return_value = None - futures[0].exception.return_value = Exception("error") - - with self.assertRaises(Exception): - self._stream._check_for_errors(futures) - - def test_as_airbyte_stream(self): - expected_airbyte_stream = AirbyteStream( - name=self._name, - json_schema=self._json_schema, - supported_sync_modes=[SyncMode.full_refresh], - source_defined_cursor=None, - default_cursor_field=None, - source_defined_primary_key=None, - namespace=None, - ) - actual_airbyte_stream = self._stream.as_airbyte_stream() - - assert actual_airbyte_stream == expected_airbyte_stream - - def test_as_airbyte_stream_with_primary_key(self): - json_schema = { - "type": "object", - "properties": { - "id_a": {"type": ["null", "string"]}, - "id_b": {"type": ["null", "string"]}, - }, - } - stream = DefaultStream( - self._partition_generator, - self._name, - json_schema, - self._availability_strategy, - ["id"], - self._cursor_field, - self._logger, - FinalStateCursor(stream_name=self._name, stream_namespace=None, message_repository=self._message_repository), - ) - - expected_airbyte_stream = AirbyteStream( - name=self._name, - json_schema=json_schema, - supported_sync_modes=[SyncMode.full_refresh], - source_defined_cursor=None, - default_cursor_field=None, - source_defined_primary_key=[["id"]], - namespace=None, - ) - - airbyte_stream = stream.as_airbyte_stream() - assert airbyte_stream == expected_airbyte_stream - - def test_as_airbyte_stream_with_composite_primary_key(self): - json_schema = { - "type": "object", - "properties": { - "id_a": {"type": ["null", "string"]}, - "id_b": {"type": ["null", "string"]}, - }, - } - stream = DefaultStream( - self._partition_generator, - self._name, - json_schema, - self._availability_strategy, - ["id_a", "id_b"], - self._cursor_field, - self._logger, - FinalStateCursor(stream_name=self._name, stream_namespace=None, message_repository=self._message_repository), - ) - - expected_airbyte_stream = AirbyteStream( - name=self._name, - json_schema=json_schema, - supported_sync_modes=[SyncMode.full_refresh], - source_defined_cursor=None, - default_cursor_field=None, - source_defined_primary_key=[["id_a", "id_b"]], - namespace=None, - ) - - airbyte_stream = stream.as_airbyte_stream() - assert airbyte_stream == expected_airbyte_stream - - def test_as_airbyte_stream_with_a_cursor(self): - json_schema = { - "type": "object", - "properties": { - "id": {"type": ["null", "string"]}, - "date": {"type": ["null", "string"]}, - }, - } - stream = DefaultStream( - self._partition_generator, - self._name, - json_schema, - self._availability_strategy, - self._primary_key, - "date", - self._logger, - FinalStateCursor(stream_name=self._name, stream_namespace=None, message_repository=self._message_repository), - ) - - expected_airbyte_stream = AirbyteStream( - name=self._name, - json_schema=json_schema, - supported_sync_modes=[SyncMode.full_refresh, SyncMode.incremental], - source_defined_cursor=True, - default_cursor_field=["date"], - source_defined_primary_key=None, - namespace=None, - ) - - airbyte_stream = stream.as_airbyte_stream() - assert airbyte_stream == expected_airbyte_stream - - def test_as_airbyte_stream_with_namespace(self): - stream = DefaultStream( - self._partition_generator, - self._name, - self._json_schema, - self._availability_strategy, - self._primary_key, - self._cursor_field, - self._logger, - FinalStateCursor(stream_name=self._name, stream_namespace=None, message_repository=self._message_repository), - namespace="test", - ) - expected_airbyte_stream = AirbyteStream( - name=self._name, - json_schema=self._json_schema, - supported_sync_modes=[SyncMode.full_refresh], - source_defined_cursor=None, - default_cursor_field=None, - source_defined_primary_key=None, - namespace="test", - ) - actual_airbyte_stream = stream.as_airbyte_stream() - - assert actual_airbyte_stream == expected_airbyte_stream diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_partition_enqueuer.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_partition_enqueuer.py deleted file mode 100644 index da67ff82588d..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_partition_enqueuer.py +++ /dev/null @@ -1,97 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import unittest -from queue import Queue -from typing import Callable, Iterable, List -from unittest.mock import Mock, patch - -from airbyte_cdk.sources.concurrent_source.partition_generation_completed_sentinel import PartitionGenerationCompletedSentinel -from airbyte_cdk.sources.concurrent_source.stream_thread_exception import StreamThreadException -from airbyte_cdk.sources.concurrent_source.thread_pool_manager import ThreadPoolManager -from airbyte_cdk.sources.streams.concurrent.abstract_stream import AbstractStream -from airbyte_cdk.sources.streams.concurrent.partition_enqueuer import PartitionEnqueuer -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.types import QueueItem - -_SOME_PARTITIONS: List[Partition] = [Mock(spec=Partition), Mock(spec=Partition)] -_A_STREAM_NAME = "a_stream_name" - - -class PartitionEnqueuerTest(unittest.TestCase): - def setUp(self) -> None: - self._queue: Queue[QueueItem] = Queue() - self._thread_pool_manager = Mock(spec=ThreadPoolManager) - self._thread_pool_manager.prune_to_validate_has_reached_futures_limit.return_value = False - self._partition_generator = PartitionEnqueuer(self._queue, self._thread_pool_manager) - - @patch("airbyte_cdk.sources.streams.concurrent.partition_enqueuer.time.sleep") - def test_given_no_partitions_when_generate_partitions_then_do_not_wait(self, mocked_sleep): - self._thread_pool_manager.prune_to_validate_has_reached_futures_limit.return_value = True # shouldn't be called but just in case - stream = self._a_stream([]) - - self._partition_generator.generate_partitions(stream) - - assert mocked_sleep.call_count == 0 - - def test_given_no_partitions_when_generate_partitions_then_only_push_sentinel(self): - self._thread_pool_manager.prune_to_validate_has_reached_futures_limit.return_value = True - stream = self._a_stream([]) - - self._partition_generator.generate_partitions(stream) - - assert self._consume_queue() == [PartitionGenerationCompletedSentinel(stream)] - - def test_given_partitions_when_generate_partitions_then_return_partitions_before_sentinel(self): - self._thread_pool_manager.prune_to_validate_has_reached_futures_limit.return_value = False - stream = self._a_stream(_SOME_PARTITIONS) - - self._partition_generator.generate_partitions(stream) - - assert self._consume_queue() == _SOME_PARTITIONS + [PartitionGenerationCompletedSentinel(stream)] - - @patch("airbyte_cdk.sources.streams.concurrent.partition_enqueuer.time.sleep") - def test_given_partition_but_limit_reached_when_generate_partitions_then_wait_until_not_hitting_limit(self, mocked_sleep): - self._thread_pool_manager.prune_to_validate_has_reached_futures_limit.side_effect = [True, True, False] - stream = self._a_stream([Mock(spec=Partition)]) - - self._partition_generator.generate_partitions(stream) - - assert mocked_sleep.call_count == 2 - - def test_given_exception_when_generate_partitions_then_return_exception_and_sentinel(self): - stream = Mock(spec=AbstractStream) - stream.name = _A_STREAM_NAME - exception = ValueError() - stream.generate_partitions.side_effect = self._partitions_before_raising(_SOME_PARTITIONS, exception) - - self._partition_generator.generate_partitions(stream) - - queue_content = self._consume_queue() - assert queue_content == _SOME_PARTITIONS + [ - StreamThreadException(exception, _A_STREAM_NAME), - PartitionGenerationCompletedSentinel(stream), - ] - - def _partitions_before_raising(self, partitions: List[Partition], exception: Exception) -> Callable[[], Iterable[Partition]]: - def inner_function() -> Iterable[Partition]: - for partition in partitions: - yield partition - raise exception - - return inner_function - - @staticmethod - def _a_stream(partitions: List[Partition]) -> AbstractStream: - stream = Mock(spec=AbstractStream) - stream.generate_partitions.return_value = iter(partitions) - return stream - - def _consume_queue(self) -> List[QueueItem]: - queue_content: List[QueueItem] = [] - while queue_item := self._queue.get(): - if isinstance(queue_item, PartitionGenerationCompletedSentinel): - queue_content.append(queue_item) - break - queue_content.append(queue_item) - return queue_content diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_partition_reader.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_partition_reader.py deleted file mode 100644 index 226652be82a1..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_partition_reader.py +++ /dev/null @@ -1,72 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import unittest -from queue import Queue -from typing import Callable, Iterable, List -from unittest.mock import Mock - -import pytest -from airbyte_cdk.sources.concurrent_source.stream_thread_exception import StreamThreadException -from airbyte_cdk.sources.streams.concurrent.partition_reader import PartitionReader -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record -from airbyte_cdk.sources.streams.concurrent.partitions.types import PartitionCompleteSentinel, QueueItem - -_RECORDS = [ - Record({"id": 1, "name": "Jack"}, "stream"), - Record({"id": 2, "name": "John"}, "stream"), -] - - -class PartitionReaderTest(unittest.TestCase): - def setUp(self) -> None: - self._queue: Queue[QueueItem] = Queue() - self._partition_reader = PartitionReader(self._queue) - - def test_given_no_records_when_process_partition_then_only_emit_sentinel(self): - self._partition_reader.process_partition(self._a_partition([])) - - while queue_item := self._queue.get(): - if not isinstance(queue_item, PartitionCompleteSentinel): - pytest.fail("Only one PartitionCompleteSentinel is expected") - break - - def test_given_read_partition_successful_when_process_partition_then_queue_records_and_sentinel(self): - partition = self._a_partition(_RECORDS) - self._partition_reader.process_partition(partition) - - queue_content = self._consume_queue() - - assert queue_content == _RECORDS + [PartitionCompleteSentinel(partition)] - - def test_given_exception_when_process_partition_then_queue_records_and_exception_and_sentinel(self): - partition = Mock() - exception = ValueError() - partition.read.side_effect = self._read_with_exception(_RECORDS, exception) - self._partition_reader.process_partition(partition) - - queue_content = self._consume_queue() - - assert queue_content == _RECORDS + [StreamThreadException(exception, partition.stream_name()), PartitionCompleteSentinel(partition)] - - def _a_partition(self, records: List[Record]) -> Partition: - partition = Mock(spec=Partition) - partition.read.return_value = iter(records) - return partition - - @staticmethod - def _read_with_exception(records: List[Record], exception: Exception) -> Callable[[], Iterable[Record]]: - def mocked_function() -> Iterable[Record]: - yield from records - raise exception - - return mocked_function - - def _consume_queue(self): - queue_content = [] - while queue_item := self._queue.get(): - queue_content.append(queue_item) - if isinstance(queue_item, PartitionCompleteSentinel): - break - return queue_content diff --git a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_thread_pool_manager.py b/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_thread_pool_manager.py deleted file mode 100644 index 197f9b3431e8..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/concurrent/test_thread_pool_manager.py +++ /dev/null @@ -1,81 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -from concurrent.futures import Future, ThreadPoolExecutor -from unittest import TestCase -from unittest.mock import Mock - -from airbyte_cdk.sources.concurrent_source.thread_pool_manager import ThreadPoolManager - - -class ThreadPoolManagerTest(TestCase): - def setUp(self): - self._threadpool = Mock(spec=ThreadPoolExecutor) - self._thread_pool_manager = ThreadPoolManager(self._threadpool, Mock(), max_concurrent_tasks=1) - self._fn = lambda x: x - self._arg = "arg" - - def test_submit_calls_underlying_thread_pool(self): - self._thread_pool_manager.submit(self._fn, self._arg) - self._threadpool.submit.assert_called_with(self._fn, self._arg) - - assert len(self._thread_pool_manager._futures) == 1 - - def test_given_exception_during_pruning_when_check_for_errors_and_shutdown_then_shutdown_and_raise(self): - future = Mock(spec=Future) - future.exception.return_value = RuntimeError - future.done.side_effect = [True, True] - - self._thread_pool_manager._futures = [future] - self._thread_pool_manager.prune_to_validate_has_reached_futures_limit() - - with self.assertRaises(RuntimeError): - self._thread_pool_manager.check_for_errors_and_shutdown() - self._threadpool.shutdown.assert_called_with(wait=False, cancel_futures=True) - - def test_is_done_is_false_if_not_all_futures_are_done(self): - future = Mock(spec=Future) - future.done.return_value = False - - self._thread_pool_manager._futures = [future] - - assert not self._thread_pool_manager.is_done() - - def test_is_done_is_true_if_all_futures_are_done(self): - future = Mock(spec=Future) - future.done.return_value = True - - self._thread_pool_manager._futures = [future] - - assert self._thread_pool_manager.is_done() - - def test_threadpool_shutdown_if_errors(self): - future = Mock(spec=Future) - future.exception.return_value = RuntimeError - - self._thread_pool_manager._futures = [future] - - with self.assertRaises(RuntimeError): - self._thread_pool_manager.check_for_errors_and_shutdown() - self._threadpool.shutdown.assert_called_with(wait=False, cancel_futures=True) - - def test_check_for_errors_and_shutdown_raises_error_if_futures_are_not_done(self): - future = Mock(spec=Future) - future.exception.return_value = None - future.done.return_value = False - - self._thread_pool_manager._futures = [future] - - with self.assertRaises(RuntimeError): - self._thread_pool_manager.check_for_errors_and_shutdown() - self._threadpool.shutdown.assert_called_with(wait=False, cancel_futures=True) - - def test_check_for_errors_and_shutdown_does_not_raise_error_if_futures_are_done(self): - future = Mock(spec=Future) - future.exception.return_value = None - future.done.return_value = True - - self._thread_pool_manager._futures = [future] - - self._thread_pool_manager.check_for_errors_and_shutdown() - self._threadpool.shutdown.assert_called_with(wait=False, cancel_futures=True) diff --git a/airbyte-cdk/python/unit_tests/sources/streams/http/__init__.py b/airbyte-cdk/python/unit_tests/sources/streams/http/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/streams/http/error_handlers/__init__.py b/airbyte-cdk/python/unit_tests/sources/streams/http/error_handlers/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/streams/http/error_handlers/test_default_backoff_strategy.py b/airbyte-cdk/python/unit_tests/sources/streams/http/error_handlers/test_default_backoff_strategy.py deleted file mode 100644 index 67e7e3503c6c..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/http/error_handlers/test_default_backoff_strategy.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from typing import Optional, Union - -import requests -from airbyte_cdk.sources.streams.http.error_handlers import BackoffStrategy, DefaultBackoffStrategy - -_ANY_ATTEMPT_COUNT = 123 - - -def test_given_no_arguments_default_backoff_strategy_returns_default_values(): - response = requests.Response() - backoff_strategy = DefaultBackoffStrategy() - assert backoff_strategy.backoff_time(response, _ANY_ATTEMPT_COUNT) is None - - -class CustomBackoffStrategy(BackoffStrategy): - def backoff_time( - self, response_or_exception: Optional[Union[requests.Response, requests.RequestException]], attempt_count: int - ) -> Optional[float]: - return response_or_exception.headers["Retry-After"] - - -def test_given_valid_arguments_default_backoff_strategy_returns_values(): - - response = requests.Response() - response.headers["Retry-After"] = 123 - backoff_strategy = CustomBackoffStrategy() - assert backoff_strategy.backoff_time(response, _ANY_ATTEMPT_COUNT) == 123 diff --git a/airbyte-cdk/python/unit_tests/sources/streams/http/error_handlers/test_http_status_error_handler.py b/airbyte-cdk/python/unit_tests/sources/streams/http/error_handlers/test_http_status_error_handler.py deleted file mode 100644 index 6da3e15b2a69..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/http/error_handlers/test_http_status_error_handler.py +++ /dev/null @@ -1,112 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -from unittest.mock import MagicMock - -import pytest -import requests -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.streams.http.error_handlers import ErrorResolution, HttpStatusErrorHandler, ResponseAction - -logger = MagicMock() - - -def test_given_ok_response_http_status_error_handler_returns_success_action(mocker): - mocked_response = MagicMock(spec=requests.Response) - mocked_response.ok = True - mocked_response.status_code = 200 - error_resolution = HttpStatusErrorHandler(logger).interpret_response(mocked_response) - assert isinstance(error_resolution, ErrorResolution) - assert error_resolution.response_action == ResponseAction.SUCCESS - assert error_resolution.failure_type is None - assert error_resolution.error_message is None - - -@pytest.mark.parametrize( - "error, expected_action, expected_failure_type, expected_error_message", - [ - (403, ResponseAction.FAIL, FailureType.config_error, "Forbidden. You don't have permission to access this resource."), - (404, ResponseAction.FAIL, FailureType.system_error, "Not found. The requested resource was not found on the server."), - ], -) -def test_given_error_code_in_response_http_status_error_handler_returns_expected_actions( - error, expected_action, expected_failure_type, expected_error_message -): - response = requests.Response() - response.status_code = error - error_resolution = HttpStatusErrorHandler(logger).interpret_response(response) - assert error_resolution.response_action == expected_action - assert error_resolution.failure_type == expected_failure_type - assert error_resolution.error_message == expected_error_message - - -def test_given_no_response_argument_returns_expected_action(): - - error_resolution = HttpStatusErrorHandler(logger).interpret_response() - - assert error_resolution.response_action == ResponseAction.FAIL - assert error_resolution.failure_type == FailureType.system_error - - -def test_given_unmapped_status_error_returns_retry_action_as_transient_error(): - - response = requests.Response() - response.status_code = 508 - - error_resolution = HttpStatusErrorHandler(logger).interpret_response(response) - - assert error_resolution.response_action == ResponseAction.RETRY - assert error_resolution.failure_type == FailureType.system_error - assert error_resolution.error_message == "Unexpected HTTP Status Code in error handler: 508" - - -def test_given_requests_exception_returns_retry_action_as_transient_error(): - - error_resolution = HttpStatusErrorHandler(logger).interpret_response(requests.RequestException()) - - assert error_resolution.response_action == ResponseAction.RETRY - assert error_resolution.failure_type - - -def test_given_unmapped_exception_returns_retry_action_as_system_error(): - - error_resolution = HttpStatusErrorHandler(logger).interpret_response(Exception()) - - assert error_resolution.response_action == ResponseAction.RETRY - assert error_resolution.failure_type == FailureType.system_error - - -def test_given_unexpected_response_type_returns_fail_action_as_system_error(): - - error_resolution = HttpStatusErrorHandler(logger).interpret_response("unexpected response type") - - assert error_resolution.response_action == ResponseAction.FAIL - assert error_resolution.failure_type == FailureType.system_error - assert error_resolution.error_message == "Received unexpected response type: " - - -def test_given_injected_error_mapping_returns_expected_action(): - - default_error_handler = HttpStatusErrorHandler(logger) - - mock_response = MagicMock(spec=requests.Response) - mock_response.status_code = 509 - mock_response.ok = False - - default_error_resolution = default_error_handler.interpret_response(mock_response) - - assert default_error_resolution.response_action == ResponseAction.RETRY - assert default_error_resolution.failure_type == FailureType.system_error - assert default_error_resolution.error_message == f"Unexpected HTTP Status Code in error handler: {mock_response.status_code}" - - mapped_error_resolution = ErrorResolution( - response_action=ResponseAction.IGNORE, failure_type=FailureType.transient_error, error_message="Injected mapping" - ) - - error_mapping = {509: mapped_error_resolution} - - actual_error_resolution = HttpStatusErrorHandler(logger, error_mapping).interpret_response(mock_response) - - assert actual_error_resolution.response_action == mapped_error_resolution.response_action - assert actual_error_resolution.failure_type == mapped_error_resolution.failure_type - assert actual_error_resolution.error_message == mapped_error_resolution.error_message diff --git a/airbyte-cdk/python/unit_tests/sources/streams/http/error_handlers/test_json_error_message_parser.py b/airbyte-cdk/python/unit_tests/sources/streams/http/error_handlers/test_json_error_message_parser.py deleted file mode 100644 index 90ea36bc6622..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/http/error_handlers/test_json_error_message_parser.py +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -import requests -from airbyte_cdk.sources.streams.http.error_handlers import JsonErrorMessageParser - - -@pytest.mark.parametrize( - "response_body,expected_error_message", - [ - (b'{"message": "json error message"}', "json error message"), - (b'[{"message": "list error message"}]', "list error message"), - (b'[{"message": "list error message 1"}, {"message": "list error message 2"}]', "list error message 1, list error message 2"), - (b'{"error": "messages error message"}', "messages error message"), - (b'[{"errors": "list error message 1"}, {"errors": "list error message 2"}]', "list error message 1, list error message 2"), - (b'{"failures": "failures error message"}', "failures error message"), - (b'{"failure": "failure error message"}', "failure error message"), - (b'{"detail": "detail error message"}', "detail error message"), - (b'{"err": "err error message"}', "err error message"), - (b'{"error_message": "error_message error message"}', "error_message error message"), - (b'{"msg": "msg error message"}', "msg error message"), - (b'{"reason": "reason error message"}', "reason error message"), - (b'{"status_message": "status_message error message"}', "status_message error message"),], -) -def test_given_error_message_in_response_body_parse_response_error_message_returns_error_message(response_body, expected_error_message): - response = requests.Response() - response._content = response_body - error_message = JsonErrorMessageParser().parse_response_error_message(response) - assert error_message == expected_error_message - - -def test_given_invalid_json_body_parse_response_error_message_returns_none(): - response = requests.Response() - response._content = b"invalid json body" - error_message = JsonErrorMessageParser().parse_response_error_message(response) - assert error_message == "invalid json body" diff --git a/airbyte-cdk/python/unit_tests/sources/streams/http/error_handlers/test_response_models.py b/airbyte-cdk/python/unit_tests/sources/streams/http/error_handlers/test_response_models.py deleted file mode 100644 index a19d3c8d5fe0..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/http/error_handlers/test_response_models.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from unittest import TestCase - -import requests -import requests_mock -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ResponseAction, create_fallback_error_resolution -from airbyte_cdk.utils.airbyte_secrets_utils import update_secrets - -_A_SECRET = "a-secret" -_A_URL = "https://a-url.com" - - -class DefaultErrorResolutionTest(TestCase): - def setUp(self) -> None: - update_secrets([_A_SECRET]) - - def tearDown(self) -> None: - # to avoid other tests being impacted by added secrets - update_secrets([]) - - def test_given_none_when_create_fallback_error_resolution_then_return_error_resolution(self) -> None: - error_resolution = create_fallback_error_resolution(None) - - assert error_resolution.failure_type == FailureType.system_error - assert error_resolution.response_action == ResponseAction.RETRY - assert ( - error_resolution.error_message - == "Error handler did not receive a valid response or exception. This is unexpected please contact Airbyte Support" - ) - - def test_given_exception_when_create_fallback_error_resolution_then_return_error_resolution(self) -> None: - exception = ValueError("This is an exception") - - error_resolution = create_fallback_error_resolution(exception) - - assert error_resolution.failure_type == FailureType.system_error - assert error_resolution.response_action == ResponseAction.RETRY - assert error_resolution.error_message - assert "ValueError" in error_resolution.error_message - assert str(exception) in error_resolution.error_message - - def test_given_response_can_raise_for_status_when_create_fallback_error_resolution_then_error_resolution(self) -> None: - response = self._create_response(512) - - error_resolution = create_fallback_error_resolution(response) - - assert error_resolution.failure_type == FailureType.system_error - assert error_resolution.response_action == ResponseAction.RETRY - assert error_resolution.error_message and "512 Server Error: None for url: https://a-url.com/" in error_resolution.error_message - - def test_given_response_is_ok_when_create_fallback_error_resolution_then_error_resolution(self) -> None: - response = self._create_response(205) - - error_resolution = create_fallback_error_resolution(response) - - assert error_resolution.failure_type == FailureType.system_error - assert error_resolution.response_action == ResponseAction.RETRY - assert error_resolution.error_message and str(response.status_code) in error_resolution.error_message - - def _create_response(self, status_code: int) -> requests.Response: - with requests_mock.Mocker() as http_mocker: - http_mocker.get(_A_URL, status_code=status_code) - return requests.get(_A_URL) diff --git a/airbyte-cdk/python/unit_tests/sources/streams/http/requests_native_auth/__init__.py b/airbyte-cdk/python/unit_tests/sources/streams/http/requests_native_auth/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/sources/streams/http/requests_native_auth/test_requests_native_auth.py b/airbyte-cdk/python/unit_tests/sources/streams/http/requests_native_auth/test_requests_native_auth.py deleted file mode 100644 index 50bd3d8faf7a..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/http/requests_native_auth/test_requests_native_auth.py +++ /dev/null @@ -1,424 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import logging -from typing import Optional, Union -from unittest.mock import Mock - -import freezegun -import pendulum -import pytest -import requests -from airbyte_cdk.models import FailureType, OrchestratorType, Type -from airbyte_cdk.sources.streams.http.requests_native_auth import ( - BasicHttpAuthenticator, - MultipleTokenAuthenticator, - Oauth2Authenticator, - SingleUseRefreshTokenOauth2Authenticator, - TokenAuthenticator, -) -from airbyte_cdk.utils import AirbyteTracedException -from requests import Response -from requests.exceptions import RequestException - -LOGGER = logging.getLogger(__name__) - -resp = Response() - - -def test_token_authenticator(): - """ - Should match passed in token, no matter how many times token is retrieved. - """ - token_auth = TokenAuthenticator(token="test-token") - header1 = token_auth.get_auth_header() - header2 = token_auth.get_auth_header() - - prepared_request = requests.PreparedRequest() - prepared_request.headers = {} - token_auth(prepared_request) - - assert {"Authorization": "Bearer test-token"} == prepared_request.headers - assert {"Authorization": "Bearer test-token"} == header1 - assert {"Authorization": "Bearer test-token"} == header2 - - -def test_basic_http_authenticator(): - """ - Should match passed in token, no matter how many times token is retrieved. - """ - token_auth = BasicHttpAuthenticator(username="user", password="password") - header1 = token_auth.get_auth_header() - header2 = token_auth.get_auth_header() - - prepared_request = requests.PreparedRequest() - prepared_request.headers = {} - token_auth(prepared_request) - - assert {"Authorization": "Basic dXNlcjpwYXNzd29yZA=="} == prepared_request.headers - assert {"Authorization": "Basic dXNlcjpwYXNzd29yZA=="} == header1 - assert {"Authorization": "Basic dXNlcjpwYXNzd29yZA=="} == header2 - - -def test_multiple_token_authenticator(): - multiple_token_auth = MultipleTokenAuthenticator(tokens=["token1", "token2"]) - header1 = multiple_token_auth.get_auth_header() - header2 = multiple_token_auth.get_auth_header() - header3 = multiple_token_auth.get_auth_header() - - prepared_request = requests.PreparedRequest() - prepared_request.headers = {} - multiple_token_auth(prepared_request) - - assert {"Authorization": "Bearer token2"} == prepared_request.headers - assert {"Authorization": "Bearer token1"} == header1 - assert {"Authorization": "Bearer token2"} == header2 - assert {"Authorization": "Bearer token1"} == header3 - - -class TestOauth2Authenticator: - """ - Test class for OAuth2Authenticator. - """ - - refresh_endpoint = "refresh_end" - client_id = "client_id" - client_secret = "client_secret" - refresh_token = "refresh_token" - - def test_get_auth_header_fresh(self, mocker): - """ - Should not retrieve new token if current token is valid. - """ - oauth = Oauth2Authenticator( - token_refresh_endpoint=TestOauth2Authenticator.refresh_endpoint, - client_id=TestOauth2Authenticator.client_id, - client_secret=TestOauth2Authenticator.client_secret, - refresh_token=TestOauth2Authenticator.refresh_token, - ) - - mocker.patch.object(Oauth2Authenticator, "refresh_access_token", return_value=("access_token", 1000)) - header = oauth.get_auth_header() - assert {"Authorization": "Bearer access_token"} == header - - def test_get_auth_header_expired(self, mocker): - """ - Should retrieve new token if current token is expired. - """ - oauth = Oauth2Authenticator( - token_refresh_endpoint=TestOauth2Authenticator.refresh_endpoint, - client_id=TestOauth2Authenticator.client_id, - client_secret=TestOauth2Authenticator.client_secret, - refresh_token=TestOauth2Authenticator.refresh_token, - ) - - expire_immediately = 0 - mocker.patch.object(Oauth2Authenticator, "refresh_access_token", return_value=("access_token_1", expire_immediately)) - oauth.get_auth_header() # Set the first expired token. - - valid_100_secs = 100 - mocker.patch.object(Oauth2Authenticator, "refresh_access_token", return_value=("access_token_2", valid_100_secs)) - header = oauth.get_auth_header() - assert {"Authorization": "Bearer access_token_2"} == header - - def test_refresh_request_body(self): - """ - Request body should match given configuration. - """ - scopes = ["scope1", "scope2"] - oauth = Oauth2Authenticator( - token_refresh_endpoint="refresh_end", - client_id="some_client_id", - client_secret="some_client_secret", - refresh_token="some_refresh_token", - scopes=["scope1", "scope2"], - token_expiry_date=pendulum.now().add(days=3), - grant_type="some_grant_type", - refresh_request_body={"custom_field": "in_outbound_request", "another_field": "exists_in_body", "scopes": ["no_override"]}, - ) - body = oauth.build_refresh_request_body() - expected = { - "grant_type": "some_grant_type", - "client_id": "some_client_id", - "client_secret": "some_client_secret", - "refresh_token": "some_refresh_token", - "scopes": scopes, - "custom_field": "in_outbound_request", - "another_field": "exists_in_body", - } - assert body == expected - - def test_refresh_access_token(self, mocker): - oauth = Oauth2Authenticator( - token_refresh_endpoint="refresh_end", - client_id="some_client_id", - client_secret="some_client_secret", - refresh_token="some_refresh_token", - scopes=["scope1", "scope2"], - token_expiry_date=pendulum.now().add(days=3), - refresh_request_body={"custom_field": "in_outbound_request", "another_field": "exists_in_body", "scopes": ["no_override"]}, - ) - - resp.status_code = 200 - mocker.patch.object(resp, "json", return_value={"access_token": "access_token", "expires_in": 1000}) - mocker.patch.object(requests, "request", side_effect=mock_request, autospec=True) - token, expires_in = oauth.refresh_access_token() - - assert isinstance(expires_in, int) - assert ("access_token", 1000) == (token, expires_in) - - # Test with expires_in as str - mocker.patch.object(resp, "json", return_value={"access_token": "access_token", "expires_in": "2000"}) - token, expires_in = oauth.refresh_access_token() - - assert isinstance(expires_in, str) - assert ("access_token", "2000") == (token, expires_in) - - # Test with expires_in as str - mocker.patch.object(resp, "json", return_value={"access_token": "access_token", "expires_in": "2022-04-24T00:00:00Z"}) - token, expires_in = oauth.refresh_access_token() - - assert isinstance(expires_in, str) - assert ("access_token", "2022-04-24T00:00:00Z") == (token, expires_in) - - @pytest.mark.parametrize( - "expires_in_response, token_expiry_date_format, expected_token_expiry_date", - [ - (3600, None, pendulum.datetime(year=2022, month=1, day=1, hour=1)), - ("90012", None, pendulum.datetime(year=2022, month=1, day=2, hour=1, second=12)), - ("2024-02-28", "YYYY-MM-DD", pendulum.datetime(year=2024, month=2, day=28)), - ("2022-02-12T00:00:00.000000+00:00", "YYYY-MM-DDTHH:mm:ss.SSSSSSZ", pendulum.datetime(year=2022, month=2, day=12)), - ], - ids=["seconds", "string_of_seconds", "simple_date", "simple_datetime"], - ) - @freezegun.freeze_time("2022-01-01") - def test_parse_refresh_token_lifespan( - self, - mocker, - expires_in_response: Union[str, int], - token_expiry_date_format: Optional[str], - expected_token_expiry_date: pendulum.DateTime, - ): - oauth = Oauth2Authenticator( - token_refresh_endpoint="refresh_end", - client_id="some_client_id", - client_secret="some_client_secret", - refresh_token="some_refresh_token", - scopes=["scope1", "scope2"], - token_expiry_date=pendulum.now().subtract(days=3), - token_expiry_date_format=token_expiry_date_format, - token_expiry_is_time_of_expiration=bool(token_expiry_date_format), - refresh_request_body={"custom_field": "in_outbound_request", "another_field": "exists_in_body", "scopes": ["no_override"]}, - ) - - resp.status_code = 200 - mocker.patch.object(resp, "json", return_value={"access_token": "access_token", "expires_in": expires_in_response}) - mocker.patch.object(requests, "request", side_effect=mock_request, autospec=True) - token, expire_in = oauth.refresh_access_token() - expires_datetime = oauth._parse_token_expiration_date(expire_in) - - assert isinstance(expires_datetime, pendulum.DateTime) - assert ("access_token", expected_token_expiry_date) == (token, expires_datetime) - - @pytest.mark.usefixtures("mock_sleep") - @pytest.mark.parametrize("error_code", (429, 500, 502, 504)) - def test_refresh_access_token_retry(self, error_code, requests_mock): - oauth = Oauth2Authenticator( - f"https://{TestOauth2Authenticator.refresh_endpoint}", - TestOauth2Authenticator.client_id, - TestOauth2Authenticator.client_secret, - TestOauth2Authenticator.refresh_token, - ) - requests_mock.post( - f"https://{TestOauth2Authenticator.refresh_endpoint}", - [{"status_code": error_code}, {"status_code": error_code}, {"json": {"access_token": "token", "expires_in": 10}}], - ) - token, expires_in = oauth.refresh_access_token() - assert isinstance(expires_in, int) - assert (token, expires_in) == ("token", 10) - assert requests_mock.call_count == 3 - - def test_auth_call_method(self, mocker): - oauth = Oauth2Authenticator( - token_refresh_endpoint=TestOauth2Authenticator.refresh_endpoint, - client_id=TestOauth2Authenticator.client_id, - client_secret=TestOauth2Authenticator.client_secret, - refresh_token=TestOauth2Authenticator.refresh_token, - ) - - mocker.patch.object(Oauth2Authenticator, "refresh_access_token", return_value=("access_token", 1000)) - prepared_request = requests.PreparedRequest() - prepared_request.headers = {} - oauth(prepared_request) - - assert {"Authorization": "Bearer access_token"} == prepared_request.headers - - @pytest.mark.parametrize( - ("config_codes", "response_code", "config_key", "response_key", "config_values", "response_value", "wrapped"), - ( - ((400,), 400, "error", "error", ("invalid_grant",), "invalid_grant", True), - ((401,), 400, "error", "error", ("invalid_grant",), "invalid_grant", False), - ((400,), 400, "error_key", "error", ("invalid_grant",), "invalid_grant", False), - ((400,), 400, "error", "error", ("invalid_grant",), "valid_grant", False), - ((), 400, "", "error", (), "valid_grant", False), - ), - ) - def test_refresh_access_token_wrapped( - self, requests_mock, config_codes, response_code, config_key, response_key, config_values, response_value, wrapped - ): - oauth = Oauth2Authenticator( - f"https://{TestOauth2Authenticator.refresh_endpoint}", - TestOauth2Authenticator.client_id, - TestOauth2Authenticator.client_secret, - TestOauth2Authenticator.refresh_token, - refresh_token_error_status_codes=config_codes, - refresh_token_error_key=config_key, - refresh_token_error_values=config_values, - ) - error_content = {response_key: response_value} - requests_mock.post(f"https://{TestOauth2Authenticator.refresh_endpoint}", status_code=response_code, json=error_content) - - exception_to_raise = AirbyteTracedException if wrapped else RequestException - with pytest.raises(exception_to_raise) as exc_info: - oauth.refresh_access_token() - - if wrapped: - error_message = "Refresh token is invalid or expired. Please re-authenticate from Sources//Settings." - assert exc_info.value.internal_message == error_message - assert exc_info.value.message == error_message - assert exc_info.value.failure_type == FailureType.config_error - - -class TestSingleUseRefreshTokenOauth2Authenticator: - @pytest.fixture - def connector_config(self): - return { - "credentials": { - "access_token": "my_access_token", - "refresh_token": "my_refresh_token", - "client_id": "my_client_id", - "client_secret": "my_client_secret", - "token_expiry_date": "2022-12-31T00:00:00+00:00", - } - } - - @pytest.fixture - def invalid_connector_config(self): - return {"no_credentials_key": "foo"} - - def test_init(self, connector_config): - authenticator = SingleUseRefreshTokenOauth2Authenticator( - connector_config, - token_refresh_endpoint="foobar", - client_id=connector_config["credentials"]["client_id"], - client_secret=connector_config["credentials"]["client_secret"], - ) - assert authenticator.access_token == connector_config["credentials"]["access_token"] - assert authenticator.get_refresh_token() == connector_config["credentials"]["refresh_token"] - assert authenticator.get_token_expiry_date() == pendulum.parse(connector_config["credentials"]["token_expiry_date"]) - - @freezegun.freeze_time("2022-12-31") - @pytest.mark.parametrize( - "test_name, expires_in_value, expiry_date_format, expected_expiry_date", - [ - ("number_of_seconds", 42, None, "2022-12-31T00:00:42+00:00"), - ("string_of_seconds", "42", None, "2022-12-31T00:00:42+00:00"), - ("date_format", "2023-04-04", "YYYY-MM-DD", "2023-04-04T00:00:00+00:00"), - ], - ) - def test_given_no_message_repository_get_access_token( - self, test_name, expires_in_value, expiry_date_format, expected_expiry_date, capsys, mocker, connector_config - ): - authenticator = SingleUseRefreshTokenOauth2Authenticator( - connector_config, - token_refresh_endpoint="foobar", - client_id=connector_config["credentials"]["client_id"], - client_secret=connector_config["credentials"]["client_secret"], - token_expiry_date_format=expiry_date_format, - ) - authenticator.refresh_access_token = mocker.Mock(return_value=("new_access_token", expires_in_value, "new_refresh_token")) - authenticator.token_has_expired = mocker.Mock(return_value=True) - access_token = authenticator.get_access_token() - captured = capsys.readouterr() - airbyte_message = json.loads(captured.out) - expected_new_config = connector_config.copy() - expected_new_config["credentials"]["access_token"] = "new_access_token" - expected_new_config["credentials"]["refresh_token"] = "new_refresh_token" - expected_new_config["credentials"]["token_expiry_date"] = expected_expiry_date - assert airbyte_message["control"]["connectorConfig"]["config"] == expected_new_config - assert authenticator.access_token == access_token == "new_access_token" - assert authenticator.get_refresh_token() == "new_refresh_token" - assert authenticator.get_token_expiry_date() > pendulum.now() - authenticator.token_has_expired = mocker.Mock(return_value=False) - access_token = authenticator.get_access_token() - captured = capsys.readouterr() - assert not captured.out - assert authenticator.access_token == access_token == "new_access_token" - - def test_given_message_repository_when_get_access_token_then_emit_message(self, mocker, connector_config): - message_repository = Mock() - authenticator = SingleUseRefreshTokenOauth2Authenticator( - connector_config, - token_refresh_endpoint="foobar", - client_id=connector_config["credentials"]["client_id"], - client_secret=connector_config["credentials"]["client_secret"], - token_expiry_date_format="YYYY-MM-DD", - message_repository=message_repository, - ) - authenticator.refresh_access_token = mocker.Mock(return_value=("new_access_token", "2023-04-04", "new_refresh_token")) - authenticator.token_has_expired = mocker.Mock(return_value=True) - - authenticator.get_access_token() - - emitted_message = message_repository.emit_message.call_args_list[0].args[0] - assert emitted_message.type == Type.CONTROL - assert emitted_message.control.type == OrchestratorType.CONNECTOR_CONFIG - assert emitted_message.control.connectorConfig.config["credentials"]["access_token"] == "new_access_token" - assert emitted_message.control.connectorConfig.config["credentials"]["refresh_token"] == "new_refresh_token" - assert emitted_message.control.connectorConfig.config["credentials"]["token_expiry_date"] == "2023-04-04T00:00:00+00:00" - assert emitted_message.control.connectorConfig.config["credentials"]["client_id"] == "my_client_id" - assert emitted_message.control.connectorConfig.config["credentials"]["client_secret"] == "my_client_secret" - - def test_given_message_repository_when_get_access_token_then_log_request(self, mocker, connector_config): - message_repository = Mock() - authenticator = SingleUseRefreshTokenOauth2Authenticator( - connector_config, - token_refresh_endpoint="foobar", - client_id=connector_config["credentials"]["client_id"], - client_secret=connector_config["credentials"]["client_secret"], - message_repository=message_repository, - ) - mocker.patch("airbyte_cdk.sources.streams.http.requests_native_auth.abstract_oauth.requests.request") - mocker.patch( - "airbyte_cdk.sources.streams.http.requests_native_auth.abstract_oauth.format_http_message", return_value="formatted json" - ) - authenticator.token_has_expired = mocker.Mock(return_value=True) - - authenticator.get_access_token() - - assert message_repository.log_message.call_count == 1 - - def test_refresh_access_token(self, mocker, connector_config): - authenticator = SingleUseRefreshTokenOauth2Authenticator( - connector_config, - token_refresh_endpoint="foobar", - client_id=connector_config["credentials"]["client_id"], - client_secret=connector_config["credentials"]["client_secret"], - ) - - authenticator._get_refresh_access_token_response = mocker.Mock( - return_value={ - authenticator.get_access_token_name(): "new_access_token", - authenticator.get_expires_in_name(): "42", - authenticator.get_refresh_token_name(): "new_refresh_token", - } - ) - assert authenticator.refresh_access_token() == ("new_access_token", "42", "new_refresh_token") - - -def mock_request(method, url, data): - if url == "refresh_end": - return resp - raise Exception(f"Error while refreshing access token with request: {method}, {url}, {data}") diff --git a/airbyte-cdk/python/unit_tests/sources/streams/http/test_availability_strategy.py b/airbyte-cdk/python/unit_tests/sources/streams/http/test_availability_strategy.py deleted file mode 100644 index 42975d8ed5a9..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/http/test_availability_strategy.py +++ /dev/null @@ -1,153 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import io -import json -import logging -from typing import Any, Iterable, Mapping, Optional - -import pytest -import requests -from airbyte_cdk.sources.streams.http.availability_strategy import HttpAvailabilityStrategy -from airbyte_cdk.sources.streams.http.http import HttpStream - -logger = logging.getLogger("airbyte") - - -class MockHttpStream(HttpStream): - url_base = "https://test_base_url.com" - primary_key = "" - - def __init__(self, **kwargs): - super().__init__(**kwargs) - self.resp_counter = 1 - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - return None - - def path(self, **kwargs) -> str: - return "" - - def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapping]: - stub_resp = {"data": self.resp_counter} - self.resp_counter += 1 - yield stub_resp - - pass - - def retry_factor(self) -> float: - return 0.01 - - -@pytest.mark.parametrize( - ("status_code", "json_contents", "expected_is_available", "expected_messages"), - [ - ( - 403, - {"error": "Something went wrong"}, - False, - [ - "Forbidden. You don't have permission to access this resource.", - "Forbidden. You don't have permission to access this resource.", - ], - ), - (200, {}, True, []), - ], -) -@pytest.mark.parametrize( - ("include_source", "expected_docs_url_messages"), - [ - (True, ["Forbidden. You don't have permission to access this resource."]), - (False, ["Forbidden. You don't have permission to access this resource."]), - ], -) -@pytest.mark.parametrize("records_as_list", [True, False]) -def test_default_http_availability_strategy( - mocker, - status_code, - json_contents, - expected_is_available, - expected_messages, - include_source, - expected_docs_url_messages, - records_as_list, -): - class MockListHttpStream(MockHttpStream): - def read_records(self, *args, **kvargs): - if records_as_list: - return list(super().read_records(*args, **kvargs)) - else: - return super().read_records(*args, **kvargs) - - http_stream = MockListHttpStream() - response = requests.Response() - response.status_code = status_code - response.raw = io.BytesIO(json.dumps(json_contents).encode("utf-8")) - mocker.patch.object(requests.Session, "send", return_value=response) - - actual_is_available, reason = HttpAvailabilityStrategy().check_availability(http_stream, logger) - - assert actual_is_available == expected_is_available - if expected_is_available: - assert reason is None - else: - all_expected_messages = expected_messages + expected_docs_url_messages - for message in all_expected_messages: - assert message in reason - - -def test_http_availability_raises_unhandled_error(mocker): - http_stream = MockHttpStream() - - req = requests.Response() - req.status_code = 404 - mocker.patch.object(requests.Session, "send", return_value=req) - - assert (False, "Not found. The requested resource was not found on the server.") == HttpAvailabilityStrategy().check_availability( - http_stream, logger - ) - - -def test_send_handles_retries_when_checking_availability(mocker, caplog): - mocker.patch("time.sleep", lambda x: None) - http_stream = MockHttpStream() - - req_1 = requests.Response() - req_1.status_code = 429 - req_2 = requests.Response() - req_2.status_code = 503 - req_3 = requests.Response() - req_3.status_code = 200 - mock_send = mocker.patch.object(requests.Session, "send", side_effect=[req_1, req_2, req_3]) - - with caplog.at_level(logging.INFO): - stream_is_available, _ = HttpAvailabilityStrategy().check_availability(stream=http_stream, logger=logger) - - assert stream_is_available - assert mock_send.call_count == 3 - for message in ["Caught retryable error", "Service unavailable", "Service unavailable"]: - assert message in caplog.text - - -@pytest.mark.parametrize("records_as_list", [True, False]) -def test_http_availability_strategy_on_empty_stream(mocker, records_as_list): - class MockEmptyHttpStream(mocker.MagicMock, MockHttpStream): - def __init__(self, *args, **kvargs): - mocker.MagicMock.__init__(self) - self.read_records = mocker.MagicMock() - - empty_stream = MockEmptyHttpStream() - assert isinstance(empty_stream, HttpStream) - - # Generator should have no values to generate - if records_as_list: - empty_stream.read_records.return_value = [] - else: - empty_stream.read_records.return_value = iter([]) - - logger = logging.getLogger("airbyte.test-source") - stream_is_available, _ = HttpAvailabilityStrategy().check_availability(stream=empty_stream, logger=logger) - - assert stream_is_available - assert empty_stream.read_records.called diff --git a/airbyte-cdk/python/unit_tests/sources/streams/http/test_http.py b/airbyte-cdk/python/unit_tests/sources/streams/http/test_http.py deleted file mode 100644 index 8737289a780f..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/http/test_http.py +++ /dev/null @@ -1,1359 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import json -import logging -from http import HTTPStatus -from typing import Any, Callable, Iterable, List, Mapping, MutableMapping, Optional, Tuple, Union -from unittest.mock import ANY, MagicMock, patch - -import pytest -import requests -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, Level, SyncMode, Type -from airbyte_cdk.sources.streams import CheckpointMixin -from airbyte_cdk.sources.streams.checkpoint import ResumableFullRefreshCursor -from airbyte_cdk.sources.streams.checkpoint.substream_resumable_full_refresh_cursor import SubstreamResumableFullRefreshCursor -from airbyte_cdk.sources.streams.core import StreamData -from airbyte_cdk.sources.streams.http import HttpStream, HttpSubStream -from airbyte_cdk.sources.streams.http.error_handlers import ErrorHandler, HttpStatusErrorHandler -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ResponseAction -from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException, RequestBodyException, UserDefinedBackoffException -from airbyte_cdk.sources.streams.http.http_client import MessageRepresentationAirbyteTracedErrors -from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator - - -class StubBasicReadHttpStream(HttpStream): - url_base = "https://test_base_url.com" - primary_key = "" - - def __init__(self, deduplicate_query_params: bool = False, **kwargs): - super().__init__(**kwargs) - self.resp_counter = 1 - self._deduplicate_query_params = deduplicate_query_params - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - return None - - def path(self, **kwargs) -> str: - return "" - - def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapping]: - stubResp = {"data": self.resp_counter} - self.resp_counter += 1 - yield stubResp - - def must_deduplicate_query_params(self) -> bool: - return self._deduplicate_query_params - - @property - def cursor_field(self) -> Union[str, List[str]]: - return ["updated_at"] - - -def test_default_authenticator(): - stream = StubBasicReadHttpStream() - assert stream._http_client._session.auth is None - - -def test_requests_native_token_authenticator(): - stream = StubBasicReadHttpStream(authenticator=TokenAuthenticator("test-token")) - assert isinstance(stream._http_client._session.auth, TokenAuthenticator) - - -def test_request_kwargs_used(mocker, requests_mock): - stream = StubBasicReadHttpStream() - request_kwargs = {"cert": None, "proxies": "google.com"} - mocker.patch.object(stream, "request_kwargs", return_value=request_kwargs) - send_mock = mocker.patch.object(stream._http_client._session, "send", wraps=stream._http_client._session.send) - requests_mock.register_uri("GET", stream.url_base) - - list(stream.read_records(sync_mode=SyncMode.full_refresh)) - - stream._http_client._session.send.assert_any_call(ANY, **request_kwargs) - assert send_mock.call_count == 1 - - -def test_stub_basic_read_http_stream_read_records(mocker): - stream = StubBasicReadHttpStream() - blank_response = {} # Send a blank response is fine as we ignore the response in `parse_response anyway. - mocker.patch.object(stream._http_client, "send_request", return_value=(None, blank_response)) - - records = list(stream.read_records(SyncMode.full_refresh)) - - assert [{"data": 1}] == records - - -class StubNextPageTokenHttpStream(StubBasicReadHttpStream): - current_page = 0 - - def __init__(self, pages: int = 5): - super().__init__() - self._pages = pages - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - while self.current_page < self._pages: - page_token = {"page": self.current_page} - self.current_page += 1 - return page_token - return None - - -def test_next_page_token_is_input_to_other_methods(mocker): - """Validates that the return value from next_page_token is passed into other methods that need it like request_params, headers, body, etc..""" - pages = 5 - stream = StubNextPageTokenHttpStream(pages=pages) - blank_response = {} # Send a blank response is fine as we ignore the response in `parse_response anyway. - mocker.patch.object(stream._http_client, "send_request", return_value=(None, blank_response)) - - methods = ["request_params", "request_headers", "request_body_json"] - for method in methods: - # Wrap all methods we're interested in testing with mocked objects so we can later spy on their input args and verify they were what we expect - mocker.patch.object(stream, method, wraps=getattr(stream, method)) - - records = list(stream.read_records(SyncMode.full_refresh)) - - # Since we have 5 pages, we expect 5 tokens which are {"page":1}, {"page":2}, etc... - expected_next_page_tokens = [{"page": i} for i in range(pages)] - for method in methods: - # First assert that they were called with no next_page_token. This is the first call in the pagination loop. - getattr(stream, method).assert_any_call(next_page_token=None, stream_slice=None, stream_state={}) - for token in expected_next_page_tokens: - # Then verify that each method - getattr(stream, method).assert_any_call(next_page_token=token, stream_slice=None, stream_state={}) - - expected = [{"data": 1}, {"data": 2}, {"data": 3}, {"data": 4}, {"data": 5}, {"data": 6}] - - assert records == expected - - -class StubBadUrlHttpStream(StubBasicReadHttpStream): - url_base = "bad_url" - - -def test_stub_bad_url_http_stream_read_records(mocker): - stream = StubBadUrlHttpStream() - - with pytest.raises(requests.exceptions.RequestException): - list(stream.read_records(SyncMode.full_refresh)) - - -class StubCustomBackoffHttpStream(StubBasicReadHttpStream): - def backoff_time(self, response: requests.Response) -> Optional[float]: - return 0.5 - - -def test_stub_custom_backoff_http_stream(mocker): - mocker.patch("time.sleep", lambda x: None) - stream = StubCustomBackoffHttpStream() - req = requests.Response() - req.status_code = 429 - - send_mock = mocker.patch.object(requests.Session, "send", return_value=req) - - with pytest.raises(UserDefinedBackoffException): - list(stream.read_records(SyncMode.full_refresh)) - assert send_mock.call_count == stream.max_retries + 1 - - # TODO(davin): Figure out how to assert calls. - - -@pytest.mark.parametrize("retries", [-20, -1, 0, 1, 2, 10]) -def test_stub_custom_backoff_http_stream_retries(mocker, retries): - mocker.patch("time.sleep", lambda x: None) - - class StubCustomBackoffHttpStreamRetries(StubCustomBackoffHttpStream): - @property - def max_retries(self): - return retries - - def get_error_handler(self) -> Optional[ErrorHandler]: - return HttpStatusErrorHandler(logging.Logger, max_retries=retries) - - stream = StubCustomBackoffHttpStreamRetries() - req = requests.Response() - req.status_code = HTTPStatus.TOO_MANY_REQUESTS - send_mock = mocker.patch.object(requests.Session, "send", return_value=req) - - with pytest.raises(UserDefinedBackoffException, match="Too many requests") as excinfo: - list(stream.read_records(SyncMode.full_refresh)) - assert isinstance(excinfo.value.request, requests.PreparedRequest) - assert isinstance(excinfo.value.response, requests.Response) - if retries <= 0: - assert send_mock.call_count == 1 - else: - assert send_mock.call_count == stream.max_retries + 1 - - -def test_stub_custom_backoff_http_stream_endless_retries(mocker): - mocker.patch("time.sleep", lambda x: None) - - class StubCustomBackoffHttpStreamRetries(StubCustomBackoffHttpStream): - def get_error_handler(self) -> Optional[ErrorHandler]: - return HttpStatusErrorHandler(logging.Logger, max_retries=99999) - - infinite_number = 20 - - stream = StubCustomBackoffHttpStreamRetries() - req = requests.Response() - req.status_code = HTTPStatus.TOO_MANY_REQUESTS - send_mock = mocker.patch.object(requests.Session, "send", side_effect=[req] * infinite_number) - - # Expecting mock object to raise a RuntimeError when the end of side_effect list parameter reached. - with pytest.raises(RuntimeError): - list(stream.read_records(SyncMode.full_refresh)) - assert send_mock.call_count == infinite_number + 1 - - -@pytest.mark.parametrize("http_code", [400, 401, 403]) -def test_4xx_error_codes_http_stream(mocker, http_code): - stream = StubCustomBackoffHttpStream() - req = requests.Response() - req.status_code = http_code - mocker.patch.object(requests.Session, "send", return_value=req) - - with pytest.raises(MessageRepresentationAirbyteTracedErrors): - list(stream.read_records(SyncMode.full_refresh)) - - -class AutoFailFalseHttpStream(StubBasicReadHttpStream): - raise_on_http_errors = False - max_retries = 3 - - def get_error_handler(self) -> Optional[ErrorHandler]: - return HttpStatusErrorHandler(logging.getLogger(), max_retries=3) - - -def test_raise_on_http_errors_off_429(mocker): - mocker.patch("time.sleep", lambda x: None) - stream = AutoFailFalseHttpStream() - req = requests.Response() - req.status_code = 429 - - mocker.patch.object(requests.Session, "send", return_value=req) - with pytest.raises(DefaultBackoffException, match="Too many requests"): - stream.exit_on_rate_limit = True - list(stream.read_records(SyncMode.full_refresh)) - - -@pytest.mark.parametrize("status_code", [500, 501, 503, 504]) -def test_raise_on_http_errors_off_5xx(mocker, status_code): - mocker.patch("time.sleep", lambda x: None) - stream = AutoFailFalseHttpStream() - req = requests.Response() - req.status_code = status_code - - send_mock = mocker.patch.object(requests.Session, "send", return_value=req) - with pytest.raises(DefaultBackoffException): - list(stream.read_records(SyncMode.full_refresh)) - assert send_mock.call_count == stream.max_retries + 1 - - -@pytest.mark.parametrize("status_code", [400, 401, 402, 403, 416]) -def test_raise_on_http_errors_off_non_retryable_4xx(mocker, status_code): - stream = AutoFailFalseHttpStream() - req = requests.PreparedRequest() - res = requests.Response() - res.status_code = status_code - - mocker.patch.object(requests.Session, "send", return_value=res) - response = stream._http_client._session.send(req) - assert response.status_code == status_code - - -@pytest.mark.parametrize( - "error", - ( - requests.exceptions.ConnectTimeout, - requests.exceptions.ConnectionError, - requests.exceptions.ChunkedEncodingError, - requests.exceptions.ReadTimeout, - ), -) -def test_raise_on_http_errors(mocker, error): - mocker.patch("time.sleep", lambda x: None) - stream = AutoFailFalseHttpStream() - send_mock = mocker.patch.object(requests.Session, "send", side_effect=error()) - - with pytest.raises(DefaultBackoffException): - list(stream.read_records(SyncMode.full_refresh)) - assert send_mock.call_count == stream.max_retries + 1 - - -class PostHttpStream(StubBasicReadHttpStream): - http_method = "POST" - - def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapping]: - """Returns response data as is""" - yield response.json() - - -class TestRequestBody: - """Suite of different tests for request bodies""" - - json_body = {"key": "value"} - data_body = "key:value" - form_body = {"key1": "value1", "key2": 1234} - urlencoded_form_body = "key1=value1&key2=1234" - - def request2response(self, request, context): - return json.dumps({"body": request.text, "content_type": request.headers.get("Content-Type")}) - - def test_json_body(self, mocker, requests_mock): - - stream = PostHttpStream() - mocker.patch.object(stream, "request_body_json", return_value=self.json_body) - - requests_mock.register_uri("POST", stream.url_base, text=self.request2response) - response = list(stream.read_records(sync_mode=SyncMode.full_refresh))[0] - - assert response["content_type"] == "application/json" - assert json.loads(response["body"]) == self.json_body - - def test_text_body(self, mocker, requests_mock): - - stream = PostHttpStream() - mocker.patch.object(stream, "request_body_data", return_value=self.data_body) - - requests_mock.register_uri("POST", stream.url_base, text=self.request2response) - response = list(stream.read_records(sync_mode=SyncMode.full_refresh))[0] - - assert response["content_type"] is None - assert response["body"] == self.data_body - - def test_form_body(self, mocker, requests_mock): - - stream = PostHttpStream() - mocker.patch.object(stream, "request_body_data", return_value=self.form_body) - - requests_mock.register_uri("POST", stream.url_base, text=self.request2response) - response = list(stream.read_records(sync_mode=SyncMode.full_refresh))[0] - - assert response["content_type"] == "application/x-www-form-urlencoded" - assert response["body"] == self.urlencoded_form_body - - def test_text_json_body(self, mocker, requests_mock): - """checks a exception if both functions were overridden""" - stream = PostHttpStream() - mocker.patch.object(stream, "request_body_data", return_value=self.data_body) - mocker.patch.object(stream, "request_body_json", return_value=self.json_body) - requests_mock.register_uri("POST", stream.url_base, text=self.request2response) - with pytest.raises(RequestBodyException): - list(stream.read_records(sync_mode=SyncMode.full_refresh)) - - def test_body_for_all_methods(self, mocker, requests_mock): - """Stream must send a body for GET/POST/PATCH/PUT methods only""" - stream = PostHttpStream() - methods = { - "POST": True, - "PUT": True, - "PATCH": True, - "GET": True, - "DELETE": False, - "OPTIONS": False, - } - for method, with_body in methods.items(): - stream.http_method = method - mocker.patch.object(stream, "request_body_data", return_value=self.data_body) - requests_mock.register_uri(method, stream.url_base, text=self.request2response) - response = list(stream.read_records(sync_mode=SyncMode.full_refresh))[0] - if with_body: - assert response["body"] == self.data_body - else: - assert response["body"] is None - - -class CacheHttpStream(StubBasicReadHttpStream): - use_cache = True - - def get_json_schema(self) -> Mapping[str, Any]: - return {} - - -class CacheHttpSubStream(HttpSubStream): - url_base = "https://example.com" - primary_key = "" - - def __init__(self, parent): - super().__init__(parent=parent) - - def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapping]: - return [] - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - return None - - def path(self, **kwargs) -> str: - return "" - - -def test_caching_filename(): - stream = CacheHttpStream() - assert stream.cache_filename == f"{stream.name}.sqlite" - - -def test_caching_sessions_are_different(): - stream_1 = CacheHttpStream() - stream_2 = CacheHttpStream() - - assert stream_1._http_client._session != stream_2._http_client._session - assert stream_1.cache_filename == stream_2.cache_filename - - -# def test_cached_streams_wortk_when_request_path_is_not_set(mocker, requests_mock): -# This test verifies that HttpStreams with a cached session work even if the path is not set -# For instance, when running in a unit test -# stream = CacheHttpStream() -# with mocker.patch.object(stream._session, "send", wraps=stream._session.send): -# requests_mock.register_uri("GET", stream.url_base) -# records = list(stream.read_records(sync_mode=SyncMode.full_refresh)) -# assert records == [{"data": 1}] -# "" - - -def test_parent_attribute_exist(): - parent_stream = CacheHttpStream() - child_stream = CacheHttpSubStream(parent=parent_stream) - - assert child_stream.parent == parent_stream - - -def test_that_response_was_cached(mocker, requests_mock): - requests_mock.register_uri("GET", "https://google.com/", text="text") - stream = CacheHttpStream() - stream._http_client.clear_cache() - mocker.patch.object(stream, "url_base", "https://google.com/") - records = list(stream.read_records(sync_mode=SyncMode.full_refresh)) - - assert requests_mock.called - - requests_mock.reset_mock() - new_records = list(stream.read_records(sync_mode=SyncMode.full_refresh)) - - assert len(records) == len(new_records) - assert not requests_mock.called - - -class CacheHttpStreamWithSlices(CacheHttpStream): - paths = ["", "search"] - - def path(self, stream_slice: Mapping[str, Any] = None, **kwargs) -> str: - return f'{stream_slice["path"]}' if stream_slice else "" - - def stream_slices(self, **kwargs) -> Iterable[Optional[Mapping[str, Any]]]: - for path in self.paths: - yield {"path": path} - - def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapping]: - yield {"value": len(response.text)} - - -@patch("airbyte_cdk.sources.streams.core.logging", MagicMock()) -def test_using_cache(mocker, requests_mock): - requests_mock.register_uri("GET", "https://google.com/", text="text") - requests_mock.register_uri("GET", "https://google.com/search", text="text") - - parent_stream = CacheHttpStreamWithSlices() - mocker.patch.object(parent_stream, "url_base", "https://google.com/") - parent_stream._http_client._session.cache.clear() - - assert requests_mock.call_count == 0 - assert len(parent_stream._http_client._session.cache.responses) == 0 - - for _slice in parent_stream.stream_slices(): - list(parent_stream.read_records(sync_mode=SyncMode.full_refresh, stream_slice=_slice)) - - assert requests_mock.call_count == 2 - assert len(parent_stream._http_client._session.cache.responses) == 2 - - child_stream = CacheHttpSubStream(parent=parent_stream) - - for _slice in child_stream.stream_slices(sync_mode=SyncMode.full_refresh): - pass - - assert requests_mock.call_count == 2 - assert len(parent_stream._http_client._session.cache.responses) == 2 - assert parent_stream._http_client._session.cache.contains(url="https://google.com/") - assert parent_stream._http_client._session.cache.contains(url="https://google.com/search") - - -class AutoFailTrueHttpStream(StubBasicReadHttpStream): - raise_on_http_errors = True - - def should_retry(self, *args, **kwargs): - return True - - -@pytest.mark.parametrize( - "response_status_code,should_retry, raise_on_http_errors, expected_response_action", - [ - (300, True, True, ResponseAction.RETRY), - (200, False, True, ResponseAction.SUCCESS), - (503, False, True, ResponseAction.FAIL), - (503, False, False, ResponseAction.IGNORE), - ], -) -def test_http_stream_adapter_http_status_error_handler_should_retry_false_raise_on_http_errors( - mocker, response_status_code: int, should_retry: bool, raise_on_http_errors: bool, expected_response_action: ResponseAction -): - stream = AutoFailTrueHttpStream() - mocker.patch.object(stream, "should_retry", return_value=should_retry) - mocker.patch.object(stream, "raise_on_http_errors", raise_on_http_errors) - res = requests.Response() - res.status_code = response_status_code - error_handler = stream.get_error_handler() - error_resolution = error_handler.interpret_response(res) - assert error_resolution.response_action == expected_response_action - - -@pytest.mark.parametrize("status_code", range(400, 600)) -def test_send_raise_on_http_errors_logs(mocker, status_code): - mocker.patch("time.sleep", lambda x: None) - stream = AutoFailTrueHttpStream() - res = requests.Response() - res.status_code = status_code - mocker.patch.object(requests.Session, "send", return_value=res) - mocker.patch.object(stream._http_client, "_logger") - with pytest.raises(requests.exceptions.HTTPError): - response = stream._http_client.send_request("GET", "https://g", {}, exit_on_rate_limit=True) - stream._http_client.logger.error.assert_called_with(response.text) - assert response.status_code == status_code - - -@pytest.mark.parametrize( - "api_response, expected_message", - [ - ({"error": "something broke"}, "something broke"), - ({"error": {"message": "something broke"}}, "something broke"), - ({"error": "err-001", "message": "something broke"}, "something broke"), - ({"failure": {"message": "something broke"}}, "something broke"), - ({"error": {"errors": [{"message": "one"}, {"message": "two"}, {"message": "three"}]}}, "one, two, three"), - ({"errors": ["one", "two", "three"]}, "one, two, three"), - ({"messages": ["one", "two", "three"]}, "one, two, three"), - ({"errors": [{"message": "one"}, {"message": "two"}, {"message": "three"}]}, "one, two, three"), - ({"error": [{"message": "one"}, {"message": "two"}, {"message": "three"}]}, "one, two, three"), - ({"errors": [{"error": "one"}, {"error": "two"}, {"error": "three"}]}, "one, two, three"), - ({"failures": [{"message": "one"}, {"message": "two"}, {"message": "three"}]}, "one, two, three"), - (["one", "two", "three"], "one, two, three"), - ([{"error": "one"}, {"error": "two"}, {"error": "three"}], "one, two, three"), - ({"error": True}, None), - ({"something_else": "hi"}, None), - ({}, None), - ], -) -def test_default_parse_response_error_message(api_response: dict, expected_message: Optional[str]): - stream = StubBasicReadHttpStream() - response = MagicMock() - response.json.return_value = api_response - - message = stream.parse_response_error_message(response) - assert message == expected_message - - -def test_default_parse_response_error_message_not_json(requests_mock): - stream = StubBasicReadHttpStream() - requests_mock.register_uri("GET", "mock://test.com/not_json", text="this is not json") - response = requests.get("mock://test.com/not_json") - - message = stream.parse_response_error_message(response) - assert message is None - - -def test_default_get_error_display_message_handles_http_error(mocker): - stream = StubBasicReadHttpStream() - mocker.patch.object(stream, "parse_response_error_message", return_value="my custom message") - - non_http_err_msg = stream.get_error_display_message(RuntimeError("not me")) - assert non_http_err_msg is None - - response = requests.Response() - http_exception = requests.HTTPError(response=response) - http_err_msg = stream.get_error_display_message(http_exception) - assert http_err_msg == "my custom message" - - -@pytest.mark.parametrize( - "test_name, base_url, path, expected_full_url", - [ - ("test_no_slashes", "https://airbyte.io", "my_endpoint", "https://airbyte.io/my_endpoint"), - ("test_trailing_slash_on_base_url", "https://airbyte.io/", "my_endpoint", "https://airbyte.io/my_endpoint"), - ( - "test_trailing_slash_on_base_url_and_leading_slash_on_path", - "https://airbyte.io/", - "/my_endpoint", - "https://airbyte.io/my_endpoint", - ), - ("test_leading_slash_on_path", "https://airbyte.io", "/my_endpoint", "https://airbyte.io/my_endpoint"), - ("test_trailing_slash_on_path", "https://airbyte.io", "/my_endpoint/", "https://airbyte.io/my_endpoint/"), - ("test_nested_path_no_leading_slash", "https://airbyte.io", "v1/my_endpoint", "https://airbyte.io/v1/my_endpoint"), - ("test_nested_path_with_leading_slash", "https://airbyte.io", "/v1/my_endpoint", "https://airbyte.io/v1/my_endpoint"), - ], -) -def test_join_url(test_name, base_url, path, expected_full_url): - actual_url = HttpStream._join_url(base_url, path) - assert actual_url == expected_full_url - - -@pytest.mark.parametrize( - "deduplicate_query_params, path, params, expected_url", - [ - pytest.param( - True, "v1/endpoint?param1=value1", {}, "https://test_base_url.com/v1/endpoint?param1=value1", id="test_params_only_in_path" - ), - pytest.param( - True, "v1/endpoint", {"param1": "value1"}, "https://test_base_url.com/v1/endpoint?param1=value1", id="test_params_only_in_path" - ), - pytest.param(True, "v1/endpoint", None, "https://test_base_url.com/v1/endpoint", id="test_params_is_none_and_no_params_in_path"), - pytest.param( - True, - "v1/endpoint?param1=value1", - None, - "https://test_base_url.com/v1/endpoint?param1=value1", - id="test_params_is_none_and_no_params_in_path", - ), - pytest.param( - True, - "v1/endpoint?param1=value1", - {"param2": "value2"}, - "https://test_base_url.com/v1/endpoint?param1=value1¶m2=value2", - id="test_no_duplicate_params", - ), - pytest.param( - True, - "v1/endpoint?param1=value1", - {"param1": "value1"}, - "https://test_base_url.com/v1/endpoint?param1=value1", - id="test_duplicate_params_same_value", - ), - pytest.param( - True, - "v1/endpoint?param1=1", - {"param1": 1}, - "https://test_base_url.com/v1/endpoint?param1=1", - id="test_duplicate_params_same_value_not_string", - ), - pytest.param( - True, - "v1/endpoint?param1=value1", - {"param1": "value2"}, - "https://test_base_url.com/v1/endpoint?param1=value1¶m1=value2", - id="test_duplicate_params_different_value", - ), - pytest.param( - False, - "v1/endpoint?param1=value1", - {"param1": "value2"}, - "https://test_base_url.com/v1/endpoint?param1=value1¶m1=value2", - id="test_same_params_different_value_no_deduplication", - ), - pytest.param( - False, - "v1/endpoint?param1=value1", - {"param1": "value1"}, - "https://test_base_url.com/v1/endpoint?param1=value1¶m1=value1", - id="test_same_params_same_value_no_deduplication", - ), - ], -) -def test_duplicate_request_params_are_deduped(deduplicate_query_params, path, params, expected_url): - - stream = StubBasicReadHttpStream(deduplicate_query_params) - - if expected_url is None: - with pytest.raises(ValueError): - stream._http_client._create_prepared_request( - http_method=stream.http_method, - url=stream._join_url(stream.url_base, path), - params=params, - dedupe_query_params=deduplicate_query_params, - ) - else: - prepared_request = stream._http_client._create_prepared_request( - http_method=stream.http_method, - url=stream._join_url(stream.url_base, path), - params=params, - dedupe_query_params=deduplicate_query_params, - ) - assert prepared_request.url == expected_url - - -def test_connection_pool(): - stream = StubBasicReadHttpStream(authenticator=TokenAuthenticator("test-token")) - assert stream._http_client._session.adapters["https://"]._pool_connections == 20 - - -class StubParentHttpStream(HttpStream, CheckpointMixin): - primary_key = "primary_key" - - counter = 0 - - def __init__(self, records: List[Mapping[str, Any]]): - super().__init__() - self._records = records - self._state: MutableMapping[str, Any] = {} - - @property - def url_base(self) -> str: - return "https://airbyte.io/api/v1" - - def path( - self, - *, - stream_state: Optional[Mapping[str, Any]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> str: - return "/stub" - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - return {"__ab_full_refresh_sync_complete": True} - - def _read_single_page( - self, - records_generator_fn: Callable[ - [requests.PreparedRequest, requests.Response, Mapping[str, Any], Optional[Mapping[str, Any]]], Iterable[StreamData] - ], - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - yield from self._records - - self.state = {"__ab_full_refresh_sync_complete": True} - - def parse_response( - self, - response: requests.Response, - *, - stream_state: Mapping[str, Any], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Iterable[Mapping[str, Any]]: - return [] - - def get_json_schema(self) -> Mapping[str, Any]: - return {} - - -class StubParentResumableFullRefreshStream(HttpStream, CheckpointMixin): - primary_key = "primary_key" - - counter = 0 - - def __init__(self, record_pages: List[List[Mapping[str, Any]]]): - super().__init__() - self._record_pages = record_pages - self._state: MutableMapping[str, Any] = {} - - @property - def url_base(self) -> str: - return "https://airbyte.io/api/v1" - - def path( - self, - *, - stream_state: Optional[Mapping[str, Any]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> str: - return "/stub" - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - return {"__ab_full_refresh_sync_complete": True} - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: Optional[List[str]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - page_number = self.state.get("page") or 1 - yield from self._record_pages[page_number - 1] - - if page_number < len(self._record_pages): - self.state = {"page": page_number + 1} - else: - self.state = {"__ab_full_refresh_sync_complete": True} - - def parse_response( - self, - response: requests.Response, - *, - stream_state: Mapping[str, Any], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Iterable[Mapping[str, Any]]: - return [] - - def get_json_schema(self) -> Mapping[str, Any]: - return {} - - -class StubHttpSubstream(HttpSubStream): - primary_key = "primary_key" - - @property - def url_base(self) -> str: - return "https://airbyte.io/api/v1" - - def path( - self, - *, - stream_state: Optional[Mapping[str, Any]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> str: - return "/stub" - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - return None - - def _read_pages( - self, - records_generator_fn: Callable[ - [requests.PreparedRequest, requests.Response, Mapping[str, Any], Optional[Mapping[str, Any]]], Iterable[StreamData] - ], - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - return [ - {"id": "abc", "parent": stream_slice.get("id")}, - {"id", "def", "parent", stream_slice.get("id")}, - ] - - def parse_response( - self, - response: requests.Response, - *, - stream_state: Mapping[str, Any], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Iterable[Mapping[str, Any]]: - return [] - - -def test_substream_with_incremental_parent(): - expected_slices = [ - {"parent": {"id": "abc"}}, - {"parent": {"id": "def"}}, - ] - - parent_records = [ - {"id": "abc"}, - {"id": "def"}, - ] - - parent_stream = StubParentHttpStream(records=parent_records) - substream = StubHttpSubstream(parent=parent_stream) - - actual_slices = [slice for slice in substream.stream_slices(sync_mode=SyncMode.full_refresh)] - assert actual_slices == expected_slices - - -def test_substream_with_resumable_full_refresh_parent(): - parent_pages = [ - [ - {"id": "page_1_abc"}, - {"id": "page_1_def"}, - ], - [ - {"id": "page_2_abc"}, - {"id": "page_2_def"}, - ], - [ - {"id": "page_3_abc"}, - {"id": "page_3_def"}, - ], - ] - - expected_slices = [ - {"parent": {"id": "page_1_abc"}}, - {"parent": {"id": "page_1_def"}}, - {"parent": {"id": "page_2_abc"}}, - {"parent": {"id": "page_2_def"}}, - {"parent": {"id": "page_3_abc"}}, - {"parent": {"id": "page_3_def"}}, - ] - - parent_stream = StubParentResumableFullRefreshStream(record_pages=parent_pages) - substream = StubHttpSubstream(parent=parent_stream) - - actual_slices = [slice for slice in substream.stream_slices(sync_mode=SyncMode.full_refresh)] - assert actual_slices == expected_slices - - -def test_substream_skips_non_record_messages(): - expected_slices = [ - {"parent": {"id": "abc"}}, - {"parent": {"id": "def"}}, - {"parent": {"id": "ghi"}}, - ] - - parent_records = [ - {"id": "abc"}, - AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=Level.INFO, message="should_not_be_parent_record")), - {"id": "def"}, - {"id": "ghi"}, - ] - - parent_stream = StubParentHttpStream(records=parent_records) - substream = StubHttpSubstream(parent=parent_stream) - - actual_slices = [slice for slice in substream.stream_slices(sync_mode=SyncMode.full_refresh)] - assert actual_slices == expected_slices - - -class StubFullRefreshHttpStream(HttpStream): - url_base = "https://test_base_url.com" - primary_key = "id" - - def __init__(self, deduplicate_query_params: bool = False, pages: int = 5, **kwargs): - super().__init__(**kwargs) - self._pages_request_count = 0 - self._page_counter = 0 - self.resp_counter = 0 - self._deduplicate_query_params = deduplicate_query_params - self._pages = pages - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - current_page = self.cursor.get_stream_state().get("page", 1) - if current_page < self._pages: - current_page += 1 - page_token = {"page": current_page} - return page_token - return None - - def path(self, **kwargs) -> str: - return "" - - def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapping]: - self.resp_counter += 1 - stubResp = {"data": self.resp_counter} - yield stubResp - - def must_deduplicate_query_params(self) -> bool: - return self._deduplicate_query_params - - -class StubFullRefreshLegacySliceHttpStream(StubFullRefreshHttpStream): - def stream_slices( - self, *, sync_mode: SyncMode, cursor_field: Optional[List[str]] = None, stream_state: Optional[Mapping[str, Any]] = None - ) -> Iterable[Optional[Mapping[str, Any]]]: - yield from [{}] - - -def test_resumable_full_refresh_read_from_start(mocker): - """ - Validates the default behavior of a stream that supports resumable full refresh by using read_records() which gets one - page per invocation and emits state afterward. - parses over - """ - pages = 5 - stream = StubFullRefreshHttpStream(pages=pages) - blank_response = {} # Send a blank response is fine as we ignore the response in `parse_response anyway. - mocker.patch.object(stream._http_client, "send_request", return_value=(None, blank_response)) - - # Wrap all methods we're interested in testing with mocked objects to spy on their input args and verify they were what we expect - mocker.patch.object(stream, "_read_single_page", wraps=getattr(stream, "_read_single_page")) - methods = ["request_params", "request_headers", "request_body_json"] - for method in methods: - mocker.patch.object(stream, method, wraps=getattr(stream, method)) - - checkpoint_reader = stream._get_checkpoint_reader( - cursor_field=[], logger=logging.getLogger("airbyte"), sync_mode=SyncMode.full_refresh, stream_state={} - ) - next_stream_slice = checkpoint_reader.next() - records = [] - - expected_checkpoints = [{"page": 2}, {"page": 3}, {"page": 4}, {"page": 5}, {"__ab_full_refresh_sync_complete": True}] - i = 0 - while next_stream_slice is not None: - next_records = list(stream.read_records(SyncMode.full_refresh, stream_slice=next_stream_slice)) - records.extend(next_records) - checkpoint_reader.observe(stream.state) - assert checkpoint_reader.get_checkpoint() == expected_checkpoints[i] - next_stream_slice = checkpoint_reader.next() - i += 1 - - assert getattr(stream, "_read_single_page").call_count == 5 - - # Since we have 5 pages, and we don't pass in the first page, we expect 4 tokens starting at {"page":2}, {"page":3}, etc... - expected_next_page_tokens = expected_checkpoints[:4] - for method in methods: - # First assert that they were called with no next_page_token. This is the first call in the pagination loop. - getattr(stream, method).assert_any_call(next_page_token=None, stream_slice={}, stream_state={}) - for token in expected_next_page_tokens: - # Then verify that each method - getattr(stream, method).assert_any_call(next_page_token=token, stream_slice=token, stream_state={}) - - expected = [{"data": 1}, {"data": 2}, {"data": 3}, {"data": 4}, {"data": 5}] - - assert records == expected - - -def test_resumable_full_refresh_read_from_state(mocker): - """ - Validates the default behavior of a stream that supports resumable full refresh with an incoming state by using - read_records() which gets one page per invocation and emits state afterward. - parses over - """ - pages = 5 - stream = StubFullRefreshHttpStream(pages=pages) - blank_response = {} # Send a blank response is fine as we ignore the response in `parse_response anyway. - mocker.patch.object(stream._http_client, "send_request", return_value=(None, blank_response)) - - # Wrap all methods we're interested in testing with mocked objects to spy on their input args and verify they were what we expect - mocker.patch.object(stream, "_read_single_page", wraps=getattr(stream, "_read_single_page")) - methods = ["request_params", "request_headers", "request_body_json"] - for method in methods: - mocker.patch.object(stream, method, wraps=getattr(stream, method)) - - checkpoint_reader = stream._get_checkpoint_reader( - cursor_field=[], logger=logging.getLogger("airbyte"), sync_mode=SyncMode.full_refresh, stream_state={"page": 3} - ) - next_stream_slice = checkpoint_reader.next() - records = [] - - expected_checkpoints = [{"page": 4}, {"page": 5}, {"__ab_full_refresh_sync_complete": True}] - i = 0 - while next_stream_slice is not None: - next_records = list(stream.read_records(SyncMode.full_refresh, stream_slice=next_stream_slice)) - records.extend(next_records) - checkpoint_reader.observe(stream.state) - assert checkpoint_reader.get_checkpoint() == expected_checkpoints[i] - next_stream_slice = checkpoint_reader.next() - i += 1 - - assert getattr(stream, "_read_single_page").call_count == 3 - - # Since we start at page 3, we expect 3 tokens starting at {"page":3}, {"page":4}, etc... - expected_next_page_tokens = [{"page": 3}, {"page": 4}, {"page": 5}] - for method in methods: - for token in expected_next_page_tokens: - # Then verify that each method - getattr(stream, method).assert_any_call(next_page_token=token, stream_slice=token, stream_state={}) - - expected = [{"data": 1}, {"data": 2}, {"data": 3}] - - assert records == expected - - -def test_resumable_full_refresh_legacy_stream_slice(mocker): - """ - Validates the default behavior of a stream that supports resumable full refresh where incoming stream slices use the - legacy Mapping format - """ - pages = 5 - stream = StubFullRefreshLegacySliceHttpStream(pages=pages) - blank_response = {} # Send a blank response is fine as we ignore the response in `parse_response anyway. - mocker.patch.object(stream._http_client, "send_request", return_value=(None, blank_response)) - - # Wrap all methods we're interested in testing with mocked objects to spy on their input args and verify they were what we expect - mocker.patch.object(stream, "_read_single_page", wraps=getattr(stream, "_read_single_page")) - methods = ["request_params", "request_headers", "request_body_json"] - for method in methods: - mocker.patch.object(stream, method, wraps=getattr(stream, method)) - - checkpoint_reader = stream._get_checkpoint_reader( - cursor_field=[], logger=logging.getLogger("airbyte"), sync_mode=SyncMode.full_refresh, stream_state={"page": 2} - ) - next_stream_slice = checkpoint_reader.next() - records = [] - - expected_checkpoints = [{"page": 3}, {"page": 4}, {"page": 5}, {"__ab_full_refresh_sync_complete": True}] - i = 0 - while next_stream_slice is not None: - next_records = list(stream.read_records(SyncMode.full_refresh, stream_slice=next_stream_slice)) - records.extend(next_records) - checkpoint_reader.observe(stream.state) - assert checkpoint_reader.get_checkpoint() == expected_checkpoints[i] - next_stream_slice = checkpoint_reader.next() - i += 1 - - assert getattr(stream, "_read_single_page").call_count == 4 - - # Since we start at page 3, we expect 3 tokens starting at {"page":3}, {"page":4}, etc... - expected_next_page_tokens = [{"page": 2}, {"page": 3}, {"page": 4}, {"page": 5}] - for method in methods: - for token in expected_next_page_tokens: - # Then verify that each method - getattr(stream, method).assert_any_call(next_page_token=token, stream_slice=token, stream_state={}) - - expected = [{"data": 1}, {"data": 2}, {"data": 3}, {"data": 4}] - - assert records == expected - - -class StubSubstreamResumableFullRefreshStream(HttpSubStream, CheckpointMixin): - primary_key = "primary_key" - - counter = 0 - - def __init__(self, parent: HttpStream, partition_id_to_child_records: Mapping[str, List[Mapping[str, Any]]]): - super().__init__(parent=parent) - self._partition_id_to_child_records = partition_id_to_child_records - # self._state: MutableMapping[str, Any] = {} - - @property - def url_base(self) -> str: - return "https://airbyte.io/api/v1" - - def path( - self, - *, - stream_state: Optional[Mapping[str, Any]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> str: - return f"/parents/{stream_slice.get('parent_id')}/children" - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - return None - - # def read_records( - # self, - # sync_mode: SyncMode, - # cursor_field: Optional[List[str]] = None, - # stream_slice: Optional[Mapping[str, Any]] = None, - # stream_state: Optional[Mapping[str, Any]] = None, - # ) -> Iterable[StreamData]: - # page_number = self.state.get("page") or 1 - # yield from self._record_pages[page_number - 1] - # - # if page_number < len(self._record_pages): - # self.state = {"page": page_number + 1} - # else: - # self.state = {"__ab_full_refresh_sync_complete": True} - - def _fetch_next_page( - self, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Tuple[requests.PreparedRequest, requests.Response]: - return requests.PreparedRequest(), requests.Response() - - def parse_response( - self, - response: requests.Response, - *, - stream_state: Mapping[str, Any], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Iterable[Mapping[str, Any]]: - partition_id = stream_slice.get("parent").get("parent_id") - if partition_id in self._partition_id_to_child_records: - yield from self._partition_id_to_child_records.get(partition_id) - else: - raise Exception(f"No mocked output supplied for parent partition_id: {partition_id}") - - def get_json_schema(self) -> Mapping[str, Any]: - return {} - - -def test_substream_resumable_full_refresh_read_from_start(mocker): - """ - Validates the default behavior of a stream that supports resumable full refresh by using read_records() which gets one - page per invocation and emits state afterward. - parses over - """ - - parent_records = [ - {"parent_id": "100", "name": "christopher_nolan"}, - {"parent_id": "101", "name": "celine_song"}, - {"parent_id": "102", "name": "david_fincher"}, - ] - parent_stream = StubParentHttpStream(records=parent_records) - - parents_to_children_records = { - "100": [ - {"id": "a200", "parent_id": "100", "film": "interstellar"}, - {"id": "a201", "parent_id": "100", "film": "oppenheimer"}, - {"id": "a202", "parent_id": "100", "film": "inception"}, - ], - "101": [{"id": "b200", "parent_id": "101", "film": "past_lives"}, {"id": "b201", "parent_id": "101", "film": "materialists"}], - "102": [ - {"id": "c200", "parent_id": "102", "film": "the_social_network"}, - {"id": "c201", "parent_id": "102", "film": "gone_girl"}, - {"id": "c202", "parent_id": "102", "film": "the_curious_case_of_benjamin_button"}, - ], - } - stream = StubSubstreamResumableFullRefreshStream(parent=parent_stream, partition_id_to_child_records=parents_to_children_records) - - blank_response = {} # Send a blank response is fine as we ignore the response in `parse_response anyway. - mocker.patch.object(stream._http_client, "send_request", return_value=(None, blank_response)) - - # Wrap all methods we're interested in testing with mocked objects to spy on their input args and verify they were what we expect - mocker.patch.object(stream, "_read_pages", wraps=getattr(stream, "_read_pages")) - - checkpoint_reader = stream._get_checkpoint_reader( - cursor_field=[], logger=logging.getLogger("airbyte"), sync_mode=SyncMode.full_refresh, stream_state={} - ) - next_stream_slice = checkpoint_reader.next() - records = [] - - expected_checkpoints = [ - { - "states": [ - { - "cursor": {"__ab_full_refresh_sync_complete": True}, - "partition": {"parent": {"name": "christopher_nolan", "parent_id": "100"}}, - } - ] - }, - { - "states": [ - { - "cursor": {"__ab_full_refresh_sync_complete": True}, - "partition": {"parent": {"name": "christopher_nolan", "parent_id": "100"}}, - }, - {"cursor": {"__ab_full_refresh_sync_complete": True}, "partition": {"parent": {"name": "celine_song", "parent_id": "101"}}}, - ] - }, - { - "states": [ - { - "cursor": {"__ab_full_refresh_sync_complete": True}, - "partition": {"parent": {"name": "christopher_nolan", "parent_id": "100"}}, - }, - {"cursor": {"__ab_full_refresh_sync_complete": True}, "partition": {"parent": {"name": "celine_song", "parent_id": "101"}}}, - { - "cursor": {"__ab_full_refresh_sync_complete": True}, - "partition": {"parent": {"name": "david_fincher", "parent_id": "102"}}, - }, - ] - }, - ] - - i = 0 - while next_stream_slice is not None: - next_records = list(stream.read_records(SyncMode.full_refresh, stream_slice=next_stream_slice)) - records.extend(next_records) - checkpoint_reader.observe(stream.state) - assert checkpoint_reader.get_checkpoint() == expected_checkpoints[i] - next_stream_slice = checkpoint_reader.next() - i += 1 - - assert getattr(stream, "_read_pages").call_count == 3 - - expected = [ - {"film": "interstellar", "id": "a200", "parent_id": "100"}, - {"film": "oppenheimer", "id": "a201", "parent_id": "100"}, - {"film": "inception", "id": "a202", "parent_id": "100"}, - {"film": "past_lives", "id": "b200", "parent_id": "101"}, - {"film": "materialists", "id": "b201", "parent_id": "101"}, - {"film": "the_social_network", "id": "c200", "parent_id": "102"}, - {"film": "gone_girl", "id": "c201", "parent_id": "102"}, - {"film": "the_curious_case_of_benjamin_button", "id": "c202", "parent_id": "102"}, - ] - - assert records == expected - - -def test_substream_resumable_full_refresh_read_from_state(mocker): - """ - Validates the default behavior of a stream that supports resumable full refresh by using read_records() which gets one - page per invocation and emits state afterward. - parses over - """ - - parent_records = [ - {"parent_id": "100", "name": "christopher_nolan"}, - {"parent_id": "101", "name": "celine_song"}, - ] - parent_stream = StubParentHttpStream(records=parent_records) - - parents_to_children_records = { - "100": [ - {"id": "a200", "parent_id": "100", "film": "interstellar"}, - {"id": "a201", "parent_id": "100", "film": "oppenheimer"}, - {"id": "a202", "parent_id": "100", "film": "inception"}, - ], - "101": [{"id": "b200", "parent_id": "101", "film": "past_lives"}, {"id": "b201", "parent_id": "101", "film": "materialists"}], - } - stream = StubSubstreamResumableFullRefreshStream(parent=parent_stream, partition_id_to_child_records=parents_to_children_records) - - blank_response = {} # Send a blank response is fine as we ignore the response in `parse_response anyway. - mocker.patch.object(stream._http_client, "send_request", return_value=(None, blank_response)) - - # Wrap all methods we're interested in testing with mocked objects to spy on their input args and verify they were what we expect - mocker.patch.object(stream, "_read_pages", wraps=getattr(stream, "_read_pages")) - - checkpoint_reader = stream._get_checkpoint_reader( - cursor_field=[], - logger=logging.getLogger("airbyte"), - sync_mode=SyncMode.full_refresh, - stream_state={ - "states": [ - { - "cursor": {"__ab_full_refresh_sync_complete": True}, - "partition": {"parent": {"name": "christopher_nolan", "parent_id": "100"}}, - }, - ] - }, - ) - next_stream_slice = checkpoint_reader.next() - records = [] - - expected_checkpoints = [ - { - "states": [ - { - "cursor": {"__ab_full_refresh_sync_complete": True}, - "partition": {"parent": {"name": "christopher_nolan", "parent_id": "100"}}, - }, - {"cursor": {"__ab_full_refresh_sync_complete": True}, "partition": {"parent": {"name": "celine_song", "parent_id": "101"}}}, - ] - }, - ] - - i = 0 - while next_stream_slice is not None: - next_records = list(stream.read_records(SyncMode.full_refresh, stream_slice=next_stream_slice)) - records.extend(next_records) - checkpoint_reader.observe(stream.state) - assert checkpoint_reader.get_checkpoint() == expected_checkpoints[i] - next_stream_slice = checkpoint_reader.next() - i += 1 - - assert getattr(stream, "_read_pages").call_count == 1 - - expected = [ - {"film": "past_lives", "id": "b200", "parent_id": "101"}, - {"film": "materialists", "id": "b201", "parent_id": "101"}, - ] - - assert records == expected - - -class StubWithCursorFields(StubBasicReadHttpStream): - def __init__(self, has_multiple_slices: bool, set_cursor_field: List[str], deduplicate_query_params: bool = False, **kwargs): - self.has_multiple_slices = has_multiple_slices - self._cursor_field = set_cursor_field - super().__init__() - - @property - def cursor_field(self) -> Union[str, List[str]]: - return self._cursor_field - - -@pytest.mark.parametrize( - "cursor_field, is_substream, expected_cursor", - [ - pytest.param([], False, ResumableFullRefreshCursor(), id="test_stream_supports_resumable_full_refresh_cursor"), - pytest.param(["updated_at"], False, None, id="test_incremental_stream_does_not_use_cursor"), - pytest.param(["updated_at"], True, None, id="test_incremental_substream_does_not_use_cursor"), - pytest.param( - [], - True, - SubstreamResumableFullRefreshCursor(), - id="test_full_refresh_substream_automatically_applies_substream_resumable_full_refresh_cursor", - ), - ], -) -def test_get_cursor(cursor_field, is_substream, expected_cursor): - stream = StubWithCursorFields(set_cursor_field=cursor_field, has_multiple_slices=is_substream) - actual_cursor = stream.get_cursor() - - assert actual_cursor == expected_cursor diff --git a/airbyte-cdk/python/unit_tests/sources/streams/http/test_http_client.py b/airbyte-cdk/python/unit_tests/sources/streams/http/test_http_client.py deleted file mode 100644 index 0c0f3c62b739..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/http/test_http_client.py +++ /dev/null @@ -1,570 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -import logging -from datetime import timedelta -from unittest.mock import MagicMock, patch - -import pytest -import requests -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.streams.call_rate import CachedLimiterSession, LimiterSession -from airbyte_cdk.sources.streams.http import HttpClient -from airbyte_cdk.sources.streams.http.error_handlers import BackoffStrategy, ErrorResolution, HttpStatusErrorHandler, ResponseAction -from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException, RequestBodyException, UserDefinedBackoffException -from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from requests_cache import CachedRequest - - -def test_http_client(): - return HttpClient(name="StubHttpClient", logger=MagicMock()) - - -def test_cache_http_client(): - return HttpClient(name="StubCacheHttpClient", logger=MagicMock(), use_cache=True) - - -def test_cache_filename(): - http_client = test_http_client() - http_client.cache_filename == f"{http_client._name}.sqlite" - - -@pytest.mark.parametrize( - "use_cache, expected_session", - [ - (True, CachedLimiterSession), - (False, LimiterSession), - ], -) -def test_request_session_returns_valid_session(use_cache, expected_session): - http_client = HttpClient(name="test", logger=MagicMock(), use_cache=use_cache) - assert isinstance(http_client._request_session(), expected_session) - - -@pytest.mark.parametrize( - "deduplicate_query_params, url, params, expected_url", - [ - pytest.param( - True, - "https://test_base_url.com/v1/endpoint?param1=value1", - {}, - "https://test_base_url.com/v1/endpoint?param1=value1", - id="test_params_only_in_path", - ), - pytest.param( - True, - "https://test_base_url.com/v1/endpoint", - {"param1": "value1"}, - "https://test_base_url.com/v1/endpoint?param1=value1", - id="test_params_only_in_path", - ), - pytest.param( - True, - "https://test_base_url.com/v1/endpoint", - None, - "https://test_base_url.com/v1/endpoint", - id="test_params_is_none_and_no_params_in_path", - ), - pytest.param( - True, - "https://test_base_url.com/v1/endpoint?param1=value1", - None, - "https://test_base_url.com/v1/endpoint?param1=value1", - id="test_params_is_none_and_no_params_in_path", - ), - pytest.param( - True, - "https://test_base_url.com/v1/endpoint?param1=value1", - {"param2": "value2"}, - "https://test_base_url.com/v1/endpoint?param1=value1¶m2=value2", - id="test_no_duplicate_params", - ), - pytest.param( - True, - "https://test_base_url.com/v1/endpoint?param1=value1", - {"param1": "value1"}, - "https://test_base_url.com/v1/endpoint?param1=value1", - id="test_duplicate_params_same_value", - ), - pytest.param( - True, - "https://test_base_url.com/v1/endpoint?param1=1", - {"param1": 1}, - "https://test_base_url.com/v1/endpoint?param1=1", - id="test_duplicate_params_same_value_not_string", - ), - pytest.param( - True, - "https://test_base_url.com/v1/endpoint?param1=value1", - {"param1": "value2"}, - "https://test_base_url.com/v1/endpoint?param1=value1¶m1=value2", - id="test_duplicate_params_different_value", - ), - pytest.param( - False, - "https://test_base_url.com/v1/endpoint?param1=value1", - {"param1": "value2"}, - "https://test_base_url.com/v1/endpoint?param1=value1¶m1=value2", - id="test_same_params_different_value_no_deduplication", - ), - pytest.param( - False, - "https://test_base_url.com/v1/endpoint?param1=value1", - {"param1": "value1"}, - "https://test_base_url.com/v1/endpoint?param1=value1¶m1=value1", - id="test_same_params_same_value_no_deduplication", - ), - ], -) -def test_duplicate_request_params_are_deduped(deduplicate_query_params, url, params, expected_url): - http_client = test_http_client() - - if expected_url is None: - with pytest.raises(ValueError): - http_client._create_prepared_request(http_method="get", url=url, dedupe_query_params=deduplicate_query_params, params=params) - else: - prepared_request = http_client._create_prepared_request( - http_method="get", url=url, dedupe_query_params=deduplicate_query_params, params=params - ) - assert prepared_request.url == expected_url - - -def test_create_prepared_response_given_given_both_json_and_data_raises_request_body_exception(): - http_client = test_http_client() - - with pytest.raises(RequestBodyException): - http_client._create_prepared_request( - http_method="get", url="https://test_base_url.com/v1/endpoint", json={"test": "json"}, data={"test": "data"} - ) - - -@pytest.mark.parametrize( - "json, data", - [ - ({"test": "json"}, None), - (None, {"test": "data"}), - ], -) -def test_create_prepared_response_given_either_json_or_data_returns_valid_request(json, data): - http_client = test_http_client() - prepared_request = http_client._create_prepared_request( - http_method="get", url="https://test_base_url.com/v1/endpoint", json=json, data=data - ) - assert prepared_request - assert isinstance(prepared_request, requests.PreparedRequest) - - -def test_connection_pool(): - http_client = HttpClient(name="test", logger=MagicMock(), authenticator=TokenAuthenticator("test-token")) - assert http_client._session.adapters["https://"]._pool_connections == 20 - - -def test_valid_basic_send_request(mocker): - http_client = test_http_client() - mocked_response = MagicMock(spec=requests.Response) - mocked_response.status_code = 200 - mocked_response.headers = {} - mocker.patch.object(requests.Session, "send", return_value=mocked_response) - returned_request, returned_response = http_client.send_request( - http_method="get", url="https://test_base_url.com/v1/endpoint", request_kwargs={} - ) - - assert isinstance(returned_request, requests.PreparedRequest) - assert returned_response == mocked_response - - -def test_send_raises_airbyte_traced_exception_with_fail_response_action(): - mocked_session = MagicMock(spec=requests.Session) - http_client = HttpClient( - name="test", - logger=MagicMock(), - error_handler=HttpStatusErrorHandler( - logger=MagicMock(), error_mapping={400: ErrorResolution(ResponseAction.FAIL, FailureType.system_error, "test error message")} - ), - session=mocked_session, - ) - prepared_request = requests.PreparedRequest() - mocked_response = requests.Response() - mocked_response.status_code = 400 - mocked_session.send.return_value = mocked_response - - with pytest.raises(AirbyteTracedException): - http_client._send(prepared_request, {}) - - assert http_client._session.send.call_count == 1 - - -def test_send_ignores_with_ignore_reponse_action_and_returns_response(): - mocked_session = MagicMock(spec=requests.Session) - mocked_response = MagicMock(spec=requests.Response) - mocked_response.status_code = 300 - mocked_response.headers = {} - mocked_session.send.return_value = mocked_response - mocked_logger = MagicMock(spec=logging.Logger) - http_client = HttpClient( - name="test", - logger=mocked_logger, - error_handler=HttpStatusErrorHandler( - logger=MagicMock(), error_mapping={300: ErrorResolution(ResponseAction.IGNORE, FailureType.system_error, "test ignore message")} - ), - session=mocked_session, - ) - - prepared_request = http_client._create_prepared_request(http_method="get", url="https://test_base_url.com/v1/endpoint") - - returned_response = http_client._send(prepared_request, {}) - - mocked_logger.info.call_count == 1 - assert isinstance(returned_response, requests.Response) - assert returned_response == mocked_response - - -class CustomBackoffStrategy(BackoffStrategy): - def __init__(self, backoff_time_value: float) -> None: - self._backoff_time_value = backoff_time_value - - def backoff_time(self, *args, **kwargs) -> float: - return self._backoff_time_value - - -@pytest.mark.parametrize("backoff_time_value, exception_type", [(0.1, UserDefinedBackoffException), (None, DefaultBackoffException)]) -def test_raises_backoff_exception_with_retry_response_action(mocker, backoff_time_value, exception_type): - http_client = HttpClient( - name="test", - logger=MagicMock(), - error_handler=HttpStatusErrorHandler( - logger=MagicMock(), error_mapping={408: ErrorResolution(ResponseAction.FAIL, FailureType.system_error, "test retry message")} - ), - backoff_strategy=CustomBackoffStrategy(backoff_time_value=backoff_time_value), - ) - prepared_request = http_client._create_prepared_request(http_method="get", url="https://test_base_url.com/v1/endpoint") - mocked_response = MagicMock(spec=requests.Response) - mocked_response.status_code = 408 - mocked_response.headers = {} - http_client._logger.info = MagicMock() - - mocker.patch.object(requests.Session, "send", return_value=mocked_response) - mocker.patch.object( - http_client._error_handler, - "interpret_response", - return_value=ErrorResolution(ResponseAction.RETRY, FailureType.system_error, "test retry message"), - ) - - with pytest.raises(exception_type): - http_client._send(prepared_request, {}) - - -@pytest.mark.parametrize("backoff_time_value, exception_type", [(0.1, UserDefinedBackoffException), (None, DefaultBackoffException)]) -def test_raises_backoff_exception_with_response_with_unmapped_error(mocker, backoff_time_value, exception_type): - http_client = HttpClient( - name="test", - logger=MagicMock(), - error_handler=HttpStatusErrorHandler( - logger=MagicMock(), error_mapping={408: ErrorResolution(ResponseAction.FAIL, FailureType.system_error, "test retry message")} - ), - backoff_strategy=CustomBackoffStrategy(backoff_time_value=backoff_time_value), - ) - prepared_request = requests.PreparedRequest() - mocked_response = MagicMock(spec=requests.Response) - mocked_response.status_code = 508 - mocked_response.headers = {} - mocked_response.ok = False - - mocker.patch.object(requests.Session, "send", return_value=mocked_response) - - with pytest.raises(exception_type): - http_client._send(prepared_request, {}) - - -@pytest.mark.usefixtures("mock_sleep") -def test_send_request_given_retry_response_action_retries_and_returns_valid_response(): - mocked_session = MagicMock(spec=requests.Session) - valid_response = MagicMock(spec=requests.Response) - valid_response.status_code = 200 - valid_response.ok = True - valid_response.headers = {} - call_count = 2 - - def update_response(*args, **kwargs): - if http_client._session.send.call_count == call_count: - return valid_response - else: - retry_response = MagicMock(spec=requests.Response) - retry_response.ok = False - retry_response.status_code = 408 - retry_response.headers = {} - return retry_response - - mocked_session.send.side_effect = update_response - - http_client = HttpClient( - name="test", - logger=MagicMock(), - error_handler=HttpStatusErrorHandler( - logger=MagicMock(), error_mapping={408: ErrorResolution(ResponseAction.RETRY, FailureType.system_error, "test retry message")} - ), - session=mocked_session, - ) - - prepared_request = requests.PreparedRequest() - - returned_response = http_client._send_with_retry(prepared_request, request_kwargs={}) - - assert http_client._session.send.call_count == call_count - assert returned_response == valid_response - - -def test_session_request_exception_raises_backoff_exception(): - error_handler = HttpStatusErrorHandler( - logger=MagicMock(), - error_mapping={ - requests.exceptions.RequestException: ErrorResolution(ResponseAction.RETRY, FailureType.system_error, "test retry message") - }, - ) - mocked_session = MagicMock(spec=requests.Session) - mocked_session.send.side_effect = requests.RequestException - http_client = HttpClient(name="test", logger=MagicMock(), error_handler=error_handler, session=mocked_session) - prepared_request = requests.PreparedRequest() - - with pytest.raises(DefaultBackoffException): - http_client._send(prepared_request, {}) - - -def test_that_response_was_cached(requests_mock): - cached_http_client = test_cache_http_client() - - assert isinstance(cached_http_client._session, CachedLimiterSession) - - cached_http_client._session.cache.clear() - - prepared_request = cached_http_client._create_prepared_request(http_method="GET", url="https://google.com/") - - requests_mock.register_uri("GET", "https://google.com/", json='{"test": "response"}') - - cached_http_client._send(prepared_request, {}) - - assert requests_mock.called - requests_mock.reset_mock() - - second_response = cached_http_client._send(prepared_request, {}) - - assert isinstance(second_response.request, CachedRequest) - assert not requests_mock.called - - -def test_send_handles_response_action_given_session_send_raises_request_exception(): - error_resolution = ErrorResolution(ResponseAction.FAIL, FailureType.system_error, "test fail message") - - custom_error_handler = HttpStatusErrorHandler(logger=MagicMock(), error_mapping={requests.RequestException: error_resolution}) - - mocked_session = MagicMock(spec=requests.Session) - mocked_session.send.side_effect = requests.RequestException - - http_client = HttpClient(name="test", logger=MagicMock(), error_handler=custom_error_handler, session=mocked_session) - prepared_request = requests.PreparedRequest() - - with pytest.raises(AirbyteTracedException) as e: - http_client._send(prepared_request, {}) - assert e.internal_message == error_resolution.error_message - assert e.message == error_resolution.error_message - assert e.failure_type == error_resolution.failure_type - - -@pytest.mark.usefixtures("mock_sleep") -def test_send_request_given_request_exception_and_retry_response_action_retries_and_returns_valid_response(): - mocked_session = MagicMock(spec=requests.Session) - - def update_response(*args, **kwargs): - if mocked_session.send.call_count == call_count: - return valid_response - else: - raise requests.RequestException() - - mocked_session.send.side_effect = update_response - - valid_response = MagicMock(spec=requests.Response) - valid_response.status_code = 200 - valid_response.ok = True - valid_response.headers = {} - call_count = 2 - - http_client = HttpClient( - name="test", - logger=MagicMock(), - error_handler=HttpStatusErrorHandler( - logger=MagicMock(), error_mapping={408: ErrorResolution(ResponseAction.RETRY, FailureType.system_error, "test retry message")} - ), - session=mocked_session, - ) - - prepared_request = requests.PreparedRequest() - - returned_response = http_client._send_with_retry(prepared_request, request_kwargs={}) - - assert http_client._session.send.call_count == call_count - assert returned_response == valid_response - - -def test_disable_retries(): - class BackoffStrategy: - def backoff_time(self, *args, **kwargs): - return 0.001 - - http_client = HttpClient( - name="test", - logger=MagicMock(), - error_handler=HttpStatusErrorHandler(logger=MagicMock()), - backoff_strategy=BackoffStrategy(), - disable_retries=True, - ) - - mocked_response = MagicMock(spec=requests.Response) - mocked_response.status_code = 429 - mocked_response.headers = {} - mocked_response.ok = False - session_send = MagicMock(spec=requests.Session.send) - session_send.return_value = mocked_response - - with patch.object(requests.Session, "send", return_value=mocked_response) as mocked_send: - with pytest.raises(UserDefinedBackoffException): - http_client.send_request(http_method="get", url="https://test_base_url.com/v1/endpoint", request_kwargs={}) - assert mocked_send.call_count == 1 - - -@pytest.mark.usefixtures("mock_sleep") -def test_default_max_retries(): - class BackoffStrategy: - def backoff_time(self, *args, **kwargs): - return 0.001 - - http_client = HttpClient( - name="test", logger=MagicMock(), error_handler=HttpStatusErrorHandler(logger=MagicMock()), backoff_strategy=BackoffStrategy() - ) - - mocked_response = MagicMock(spec=requests.Response) - mocked_response.status_code = 429 - mocked_response.headers = {} - mocked_response.ok = False - session_send = MagicMock(spec=requests.Session.send) - session_send.return_value = mocked_response - - with patch.object(requests.Session, "send", return_value=mocked_response) as mocked_send: - with pytest.raises(UserDefinedBackoffException): - http_client.send_request(http_method="get", url="https://test_base_url.com/v1/endpoint", request_kwargs={}) - assert mocked_send.call_count == 6 - - -@pytest.mark.usefixtures("mock_sleep") -def test_backoff_strategy_max_retries(): - class BackoffStrategy: - def backoff_time(self, *args, **kwargs): - return 0.001 - - retries = 3 - - http_client = HttpClient( - name="test", - logger=MagicMock(), - error_handler=HttpStatusErrorHandler(logger=MagicMock(), max_retries=retries), - backoff_strategy=BackoffStrategy(), - ) - - mocked_response = MagicMock(spec=requests.Response) - mocked_response.status_code = 429 - mocked_response.headers = {} - mocked_response.ok = False - session_send = MagicMock(spec=requests.Session.send) - session_send.return_value = mocked_response - - with patch.object(requests.Session, "send", return_value=mocked_response) as mocked_send: - with pytest.raises(UserDefinedBackoffException): - http_client.send_request(http_method="get", url="https://test_base_url.com/v1/endpoint", request_kwargs={}) - assert mocked_send.call_count == retries + 1 - - -@pytest.mark.usefixtures("mock_sleep") -def test_backoff_strategy_max_time(): - error_handler = HttpStatusErrorHandler( - logger=MagicMock(), - error_mapping={requests.RequestException: ErrorResolution(ResponseAction.RETRY, FailureType.system_error, "test retry message")}, - max_retries=10, - max_time=timedelta(seconds=2), - ) - - class BackoffStrategy: - def backoff_time(self, *args, **kwargs): - return 1 - - http_client = HttpClient(name="test", logger=MagicMock(), error_handler=error_handler, backoff_strategy=BackoffStrategy()) - - mocked_response = MagicMock(spec=requests.Response) - mocked_response.status_code = 429 - mocked_response.headers = {} - mocked_response.ok = False - session_send = MagicMock(spec=requests.Session.send) - session_send.return_value = mocked_response - - with patch.object(requests.Session, "send", return_value=mocked_response) as mocked_send: - with pytest.raises(UserDefinedBackoffException): - http_client.send_request(http_method="get", url="https://test_base_url.com/v1/endpoint", request_kwargs={}) - assert mocked_send.call_count == 2 - - -@pytest.mark.usefixtures("mock_sleep") -def test_send_emit_stream_status_with_rate_limit_reason(capsys): - class BackoffStrategy: - def backoff_time(self, *args, **kwargs): - return 0.001 - - http_client = HttpClient( - name="test", logger=MagicMock(), error_handler=HttpStatusErrorHandler(logger=MagicMock()), backoff_strategy=BackoffStrategy() - ) - - mocked_response = MagicMock(spec=requests.Response) - mocked_response.status_code = 429 - mocked_response.headers = {} - mocked_response.ok = False - session_send = MagicMock(spec=requests.Session.send) - session_send.return_value = mocked_response - - with patch.object(requests.Session, "send", return_value=mocked_response) as mocked_send: - with pytest.raises(UserDefinedBackoffException): - http_client.send_request(http_method="get", url="https://test_base_url.com/v1/endpoint", request_kwargs={}) - - trace_messages = capsys.readouterr().out.split() - assert len(trace_messages) == mocked_send.call_count - - -@pytest.mark.parametrize( - "exit_on_rate_limit, expected_call_count, expected_error", [[True, 6, DefaultBackoffException], [False, 38, OverflowError]] -) -@pytest.mark.usefixtures("mock_sleep") -def test_backoff_strategy_endless(exit_on_rate_limit, expected_call_count, expected_error): - http_client = HttpClient(name="test", logger=MagicMock(), error_handler=HttpStatusErrorHandler(logger=MagicMock())) - - mocked_response = MagicMock(spec=requests.Response) - mocked_response.status_code = 429 - mocked_response.headers = {} - mocked_response.ok = False - session_send = MagicMock(spec=requests.Session.send) - session_send.return_value = mocked_response - - with patch.object(requests.Session, "send", return_value=mocked_response) as mocked_send: - with pytest.raises(expected_error): - http_client.send_request( - http_method="get", url="https://test_base_url.com/v1/endpoint", request_kwargs={}, exit_on_rate_limit=exit_on_rate_limit - ) - assert mocked_send.call_count == expected_call_count - - -def test_given_different_headers_then_response_is_not_cached(requests_mock): - http_client = HttpClient(name="test", logger=MagicMock(), use_cache=True) - first_request_headers = {"header_key": "first"} - second_request_headers = {"header_key": "second"} - requests_mock.register_uri("GET", "https://google.com/", request_headers=first_request_headers, json={"test": "first response"}) - requests_mock.register_uri("GET", "https://google.com/", request_headers=second_request_headers, json={"test": "second response"}) - - http_client.send_request("GET", "https://google.com/", headers=first_request_headers, request_kwargs={}) - _, second_response = http_client.send_request("GET", "https://google.com/", headers=second_request_headers, request_kwargs={}) - - assert second_response.json()["test"] == "second response" diff --git a/airbyte-cdk/python/unit_tests/sources/streams/test_call_rate.py b/airbyte-cdk/python/unit_tests/sources/streams/test_call_rate.py deleted file mode 100644 index c78d494ba413..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/test_call_rate.py +++ /dev/null @@ -1,300 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import os -import tempfile -import time -from datetime import datetime, timedelta -from typing import Any, Iterable, Mapping, Optional - -import pytest -import requests -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.streams.call_rate import ( - APIBudget, - CallRateLimitHit, - FixedWindowCallRatePolicy, - HttpRequestMatcher, - MovingWindowCallRatePolicy, - Rate, - UnlimitedCallRatePolicy, -) -from airbyte_cdk.sources.streams.http import HttpStream -from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator -from airbyte_cdk.utils.constants import ENV_REQUEST_CACHE_PATH -from requests import Request - - -class StubDummyHttpStream(HttpStream): - url_base = "https://test_base_url.com" - primary_key = "some_key" - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - return {"next_page_token": True} # endless pages - - def path(self, **kwargs) -> str: - return "" - - def parse_response(self, *args, **kwargs) -> Iterable[Mapping]: - yield {"data": "some_data"} - - -class StubDummyCacheHttpStream(StubDummyHttpStream): - use_cache = True - - -@pytest.fixture(name="enable_cache") -def enable_cache_fixture(): - prev_cache_path = os.environ.get(ENV_REQUEST_CACHE_PATH) - with tempfile.TemporaryDirectory() as temp_dir: - os.environ[ENV_REQUEST_CACHE_PATH] = temp_dir - yield - - if prev_cache_path is not None: - os.environ[ENV_REQUEST_CACHE_PATH] = prev_cache_path - - -class TestHttpRequestMatcher: - try_all_types_of_requests = pytest.mark.parametrize( - "request_factory", - [Request, lambda *args, **kwargs: Request(*args, **kwargs).prepare()], - ) - - @try_all_types_of_requests - def test_url(self, request_factory): - matcher = HttpRequestMatcher(url="http://some_url/") - assert not matcher(request_factory(url="http://some_wrong_url")) - assert matcher(request_factory(url="http://some_url")) - - @try_all_types_of_requests - def test_method(self, request_factory): - matcher = HttpRequestMatcher(method="GET") - assert not matcher(request_factory(url="http://some_url")) - assert not matcher(request_factory(url="http://some_url", method="POST")) - assert matcher(request_factory(url="http://some_url", method="GET")) - - @try_all_types_of_requests - def test_params(self, request_factory): - matcher = HttpRequestMatcher(params={"param1": 10, "param2": 15}) - assert not matcher(request_factory(url="http://some_url/")) - assert not matcher(request_factory(url="http://some_url/", params={"param1": 10, "param3": 100})) - assert not matcher(request_factory(url="http://some_url/", params={"param1": 10, "param2": 10})) - assert matcher(request_factory(url="http://some_url/", params={"param1": 10, "param2": 15, "param3": 100})) - - @try_all_types_of_requests - def test_header(self, request_factory): - matcher = HttpRequestMatcher(headers={"header1": 10, "header2": 15}) - assert not matcher(request_factory(url="http://some_url")) - assert not matcher(request_factory(url="http://some_url", headers={"header1": "10", "header3": "100"})) - assert not matcher(request_factory(url="http://some_url", headers={"header1": "10", "header2": "10"})) - assert matcher(request_factory(url="http://some_url", headers={"header1": "10", "header2": "15", "header3": "100"})) - - @try_all_types_of_requests - def test_combination(self, request_factory): - matcher = HttpRequestMatcher(method="GET", url="http://some_url/", headers={"header1": 10}, params={"param2": "test"}) - assert matcher(request_factory(method="GET", url="http://some_url", headers={"header1": "10"}, params={"param2": "test"})) - assert not matcher(request_factory(method="GET", url="http://some_url", headers={"header1": "10"})) - assert not matcher(request_factory(method="GET", url="http://some_url")) - assert not matcher(request_factory(url="http://some_url")) - - -def test_http_request_matching(mocker): - """Test policy lookup based on matchers.""" - users_policy = mocker.Mock(spec=MovingWindowCallRatePolicy) - groups_policy = mocker.Mock(spec=MovingWindowCallRatePolicy) - root_policy = mocker.Mock(spec=MovingWindowCallRatePolicy) - - users_policy.matches.side_effect = HttpRequestMatcher(url="http://domain/api/users", method="GET") - groups_policy.matches.side_effect = HttpRequestMatcher(url="http://domain/api/groups", method="POST") - root_policy.matches.side_effect = HttpRequestMatcher(method="GET") - api_budget = APIBudget( - policies=[ - users_policy, - groups_policy, - root_policy, - ] - ) - - api_budget.acquire_call(Request("POST", url="http://domain/unmatched_endpoint"), block=False), "unrestricted call" - users_policy.try_acquire.assert_not_called() - groups_policy.try_acquire.assert_not_called() - root_policy.try_acquire.assert_not_called() - - users_request = Request("GET", url="http://domain/api/users") - api_budget.acquire_call(users_request, block=False), "first call, first matcher" - users_policy.try_acquire.assert_called_once_with(users_request, weight=1) - groups_policy.try_acquire.assert_not_called() - root_policy.try_acquire.assert_not_called() - - api_budget.acquire_call(Request("GET", url="http://domain/api/users"), block=False), "second call, first matcher" - assert users_policy.try_acquire.call_count == 2 - groups_policy.try_acquire.assert_not_called() - root_policy.try_acquire.assert_not_called() - - group_request = Request("POST", url="http://domain/api/groups") - api_budget.acquire_call(group_request, block=False), "first call, second matcher" - assert users_policy.try_acquire.call_count == 2 - groups_policy.try_acquire.assert_called_once_with(group_request, weight=1) - root_policy.try_acquire.assert_not_called() - - api_budget.acquire_call(Request("POST", url="http://domain/api/groups"), block=False), "second call, second matcher" - assert users_policy.try_acquire.call_count == 2 - assert groups_policy.try_acquire.call_count == 2 - root_policy.try_acquire.assert_not_called() - - any_get_request = Request("GET", url="http://domain/api/") - api_budget.acquire_call(any_get_request, block=False), "first call, third matcher" - assert users_policy.try_acquire.call_count == 2 - assert groups_policy.try_acquire.call_count == 2 - root_policy.try_acquire.assert_called_once_with(any_get_request, weight=1) - - -class TestUnlimitedCallRatePolicy: - def test_try_acquire(self, mocker): - policy = UnlimitedCallRatePolicy(matchers=[]) - assert policy.matches(mocker.Mock()), "should match anything" - policy.try_acquire(mocker.Mock(), weight=1) - policy.try_acquire(mocker.Mock(), weight=10) - - def test_update(self): - policy = UnlimitedCallRatePolicy(matchers=[]) - policy.update(available_calls=10, call_reset_ts=datetime.now()) - policy.update(available_calls=None, call_reset_ts=datetime.now()) - policy.update(available_calls=10, call_reset_ts=None) - - -class TestFixedWindowCallRatePolicy: - def test_limit_rate(self, mocker): - policy = FixedWindowCallRatePolicy(matchers=[], next_reset_ts=datetime.now(), period=timedelta(hours=1), call_limit=100) - policy.try_acquire(mocker.Mock(), weight=1) - policy.try_acquire(mocker.Mock(), weight=20) - with pytest.raises(ValueError, match="Weight can not exceed the call limit"): - policy.try_acquire(mocker.Mock(), weight=101) - - with pytest.raises(CallRateLimitHit) as exc: - policy.try_acquire(mocker.Mock(), weight=100 - 20 - 1 + 1) - - assert exc.value.time_to_wait - assert exc.value.weight == 100 - 20 - 1 + 1 - assert exc.value.item - - def test_update_available_calls(self, mocker): - policy = FixedWindowCallRatePolicy(matchers=[], next_reset_ts=datetime.now(), period=timedelta(hours=1), call_limit=100) - # update to decrease number of calls available - policy.update(available_calls=2, call_reset_ts=None) - # hit the limit with weight=3 - with pytest.raises(CallRateLimitHit): - policy.try_acquire(mocker.Mock(), weight=3) - # ok with less weight=1 - policy.try_acquire(mocker.Mock(), weight=1) - - # update to increase number of calls available, ignored - policy.update(available_calls=20, call_reset_ts=None) - # so we still hit the limit with weight=3 - with pytest.raises(CallRateLimitHit): - policy.try_acquire(mocker.Mock(), weight=3) - - -class TestMovingWindowCallRatePolicy: - def test_no_rates(self): - """should raise a ValueError when no rates provided""" - with pytest.raises(ValueError, match="The list of rates can not be empty"): - MovingWindowCallRatePolicy(rates=[], matchers=[]) - - def test_limit_rate(self): - """try_acquire must respect configured call rate and throw CallRateLimitHit when hit the limit.""" - policy = MovingWindowCallRatePolicy(rates=[Rate(10, timedelta(minutes=1))], matchers=[]) - - for i in range(10): - policy.try_acquire("call", weight=1), f"{i + 1} call" - - with pytest.raises(CallRateLimitHit) as excinfo1: - policy.try_acquire("call", weight=1), "call over limit" - assert excinfo1.value.time_to_wait.total_seconds() == pytest.approx(60, 0.1) - - time.sleep(0.5) - - with pytest.raises(CallRateLimitHit) as excinfo2: - policy.try_acquire("call", weight=1), "call over limit" - assert excinfo2.value.time_to_wait < excinfo1.value.time_to_wait, "time to wait must decrease over time" - - def test_limit_rate_support_custom_weight(self): - """try_acquire must take into account provided weight and throw CallRateLimitHit when hit the limit.""" - policy = MovingWindowCallRatePolicy(rates=[Rate(10, timedelta(minutes=1))], matchers=[]) - - policy.try_acquire("call", weight=2), "1st call with weight of 2" - with pytest.raises(CallRateLimitHit) as excinfo: - policy.try_acquire("call", weight=9), "2nd call, over limit since 2 + 9 = 11 > 10" - assert excinfo.value.time_to_wait.total_seconds() == pytest.approx(60, 0.1), "should wait 1 minute before next call" - - def test_multiple_limit_rates(self): - """try_acquire must take into all call rates and apply stricter.""" - policy = MovingWindowCallRatePolicy( - matchers=[], - rates=[ - Rate(10, timedelta(minutes=10)), - Rate(3, timedelta(seconds=10)), - Rate(2, timedelta(hours=1)), - ], - ) - - policy.try_acquire("call", weight=2), "1 call" - - with pytest.raises(CallRateLimitHit) as excinfo: - policy.try_acquire("call", weight=1), "1 call" - - assert excinfo.value.time_to_wait.total_seconds() == pytest.approx(3600, 0.1) - assert str(excinfo.value) == "Bucket for item=call with Rate limit=2/1.0h is already full" - - -class TestHttpStreamIntegration: - def test_without_cache(self, mocker, requests_mock): - """Test that HttpStream will use call budget when provided""" - requests_mock.get(f"{StubDummyHttpStream.url_base}/", json={"data": "test"}) - - mocker.patch.object(MovingWindowCallRatePolicy, "try_acquire") - - api_budget = APIBudget( - policies=[ - MovingWindowCallRatePolicy( - matchers=[HttpRequestMatcher(url=f"{StubDummyHttpStream.url_base}/", method="GET")], - rates=[ - Rate(2, timedelta(minutes=1)), - ], - ), - ] - ) - - stream = StubDummyHttpStream(api_budget=api_budget, authenticator=TokenAuthenticator(token="ABCD")) - for i in range(10): - records = stream.read_records(SyncMode.full_refresh) - assert next(records) == {"data": "some_data"} - - assert MovingWindowCallRatePolicy.try_acquire.call_count == 10 - - @pytest.mark.usefixtures("enable_cache") - def test_with_cache(self, mocker, requests_mock): - """Test that HttpStream will use call budget when provided and not cached""" - requests_mock.get(f"{StubDummyHttpStream.url_base}/", json={"data": "test"}) - - mocker.patch.object(MovingWindowCallRatePolicy, "try_acquire") - - api_budget = APIBudget( - policies=[ - MovingWindowCallRatePolicy( - matchers=[ - HttpRequestMatcher(url=f"{StubDummyHttpStream.url_base}/", method="GET"), - ], - rates=[ - Rate(2, timedelta(minutes=1)), - ], - ) - ] - ) - - stream = StubDummyCacheHttpStream(api_budget=api_budget) - for i in range(10): - records = stream.read_records(SyncMode.full_refresh) - assert next(records) == {"data": "some_data"} - - assert MovingWindowCallRatePolicy.try_acquire.call_count == 1 diff --git a/airbyte-cdk/python/unit_tests/sources/streams/test_stream_read.py b/airbyte-cdk/python/unit_tests/sources/streams/test_stream_read.py deleted file mode 100644 index 5b82ab119d03..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/test_stream_read.py +++ /dev/null @@ -1,593 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from copy import deepcopy -from typing import Any, Dict, Iterable, List, Mapping, MutableMapping, Optional, Union -from unittest.mock import Mock - -import pytest -from airbyte_cdk.models import ( - AirbyteLogMessage, - AirbyteMessage, - AirbyteStateBlob, - AirbyteStateMessage, - AirbyteStateType, - AirbyteStream, - AirbyteStreamState, - ConfiguredAirbyteStream, - DestinationSyncMode, - Level, - StreamDescriptor, - SyncMode, -) -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.concurrent_source.concurrent_read_processor import ConcurrentReadProcessor -from airbyte_cdk.sources.concurrent_source.thread_pool_manager import ThreadPoolManager -from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager -from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository -from airbyte_cdk.sources.streams import Stream -from airbyte_cdk.sources.streams.concurrent.adapters import StreamFacade -from airbyte_cdk.sources.streams.concurrent.cursor import Cursor, FinalStateCursor -from airbyte_cdk.sources.streams.concurrent.partition_enqueuer import PartitionEnqueuer -from airbyte_cdk.sources.streams.concurrent.partition_reader import PartitionReader -from airbyte_cdk.sources.streams.concurrent.partitions.partition import Partition -from airbyte_cdk.sources.streams.concurrent.partitions.record import Record -from airbyte_cdk.sources.streams.core import CheckpointMixin, StreamData -from airbyte_cdk.sources.utils.schema_helpers import InternalConfig -from airbyte_cdk.sources.utils.slice_logger import DebugSliceLogger - -_A_CURSOR_FIELD = ["NESTED", "CURSOR"] -_DEFAULT_INTERNAL_CONFIG = InternalConfig() -_STREAM_NAME = "STREAM" -_NO_STATE = None - - -class _MockStream(Stream): - def __init__(self, slice_to_records: Mapping[str, List[Mapping[str, Any]]], json_schema: Dict[str, Any] = None): - self._slice_to_records = slice_to_records - self._mocked_json_schema = json_schema or {} - - @property - def primary_key(self) -> Optional[Union[str, List[str], List[List[str]]]]: - return None - - def stream_slices( - self, *, sync_mode: SyncMode, cursor_field: Optional[List[str]] = None, stream_state: Optional[Mapping[str, Any]] = None - ) -> Iterable[Optional[Mapping[str, Any]]]: - for partition in self._slice_to_records.keys(): - yield {"partition_key": partition} - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: Optional[List[str]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - yield from self._slice_to_records[stream_slice["partition_key"]] - - def get_json_schema(self) -> Mapping[str, Any]: - return self._mocked_json_schema - - -class _MockIncrementalStream(_MockStream, CheckpointMixin): - _state = {} - - @property - def state(self) -> MutableMapping[str, Any]: - return self._state - - @state.setter - def state(self, value: MutableMapping[str, Any]) -> None: - """State setter, accept state serialized by state getter.""" - self._state = value - - @property - def cursor_field(self) -> Union[str, List[str]]: - return ["created_at"] - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: Optional[List[str]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - cursor = self.cursor_field[0] - for record in self._slice_to_records[stream_slice["partition_key"]]: - yield record - if cursor not in self._state: - self._state[cursor] = record.get(cursor) - else: - self._state[cursor] = max(self._state[cursor], record.get(cursor)) - - -class MockConcurrentCursor(Cursor): - _state: MutableMapping[str, Any] - _message_repository: MessageRepository - - def __init__(self, message_repository: MessageRepository): - self._message_repository = message_repository - self._state = {} - - @property - def state(self) -> MutableMapping[str, Any]: - return self._state - - def observe(self, record: Record) -> None: - partition = str(record.data.get("partition")) - timestamp = record.data.get("created_at") - self._state[partition] = {"created_at": timestamp} - - def close_partition(self, partition: Partition) -> None: - self._message_repository.emit_message( - AirbyteMessage( - type=MessageType.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="__mock_stream", namespace=None), - stream_state=AirbyteStateBlob(**self._state), - ), - ), - ) - ) - - def ensure_at_least_one_state_emitted(self) -> None: - pass - - -def _stream(slice_to_partition_mapping, slice_logger, logger, message_repository, json_schema=None): - return _MockStream(slice_to_partition_mapping, json_schema=json_schema) - - -def _concurrent_stream(slice_to_partition_mapping, slice_logger, logger, message_repository, cursor: Optional[Cursor] = None): - stream = _stream(slice_to_partition_mapping, slice_logger, logger, message_repository) - cursor = cursor or FinalStateCursor(stream_name=stream.name, stream_namespace=stream.namespace, message_repository=message_repository) - source = Mock() - source._slice_logger = slice_logger - source.message_repository = message_repository - stream = StreamFacade.create_from_stream(stream, source, logger, _NO_STATE, cursor) - stream.logger.setLevel(logger.level) - return stream - - -def _incremental_stream(slice_to_partition_mapping, slice_logger, logger, message_repository, timestamp): - stream = _MockIncrementalStream(slice_to_partition_mapping) - return stream - - -def _incremental_concurrent_stream(slice_to_partition_mapping, slice_logger, logger, message_repository, cursor): - stream = _concurrent_stream(slice_to_partition_mapping, slice_logger, logger, message_repository, cursor) - return stream - - -def _stream_with_no_cursor_field(slice_to_partition_mapping, slice_logger, logger, message_repository): - def get_updated_state(current_stream_state: MutableMapping[str, Any], latest_record: Mapping[str, Any]) -> MutableMapping[str, Any]: - raise Exception("I shouldn't be invoked by a full_refresh stream") - - mock_stream = _MockStream(slice_to_partition_mapping) - mock_stream.get_updated_state = get_updated_state - return mock_stream - - -@pytest.mark.parametrize( - "constructor", - [ - pytest.param(_stream, id="synchronous_reader"), - pytest.param(_concurrent_stream, id="concurrent_reader"), - ], -) -def test_full_refresh_read_a_single_slice_with_debug(constructor): - # This test verifies that a concurrent stream adapted from a Stream behaves the same as the Stream object. - # It is done by running the same test cases on both streams - configured_stream = ConfiguredAirbyteStream( - stream=AirbyteStream(name="mock_stream", supported_sync_modes=[SyncMode.full_refresh], json_schema={}), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.overwrite, - ) - internal_config = InternalConfig() - records = [ - {"id": 1, "partition_key": 1}, - {"id": 2, "partition_key": 1}, - ] - slice_to_partition = {1: records} - slice_logger = DebugSliceLogger() - logger = _mock_logger(True) - message_repository = InMemoryMessageRepository(Level.DEBUG) - stream = constructor(slice_to_partition, slice_logger, logger, message_repository) - state_manager = ConnectorStateManager() - - expected_records = [ - AirbyteMessage( - type=MessageType.LOG, - log=AirbyteLogMessage( - level=Level.INFO, - message='slice:{"partition_key": 1}', - ), - ), - *records, - ] - - # Synchronous streams emit a final state message to indicate that the stream has finished reading - # Concurrent streams don't emit their own state messages - the concurrent source observes the cursor - # and emits the state messages. Therefore, we can only check the value of the cursor's state at the end - if constructor == _stream: - expected_records.append( - AirbyteMessage( - type=MessageType.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="__mock_stream", namespace=None), - stream_state=AirbyteStateBlob(__ab_no_cursor_state_message=True), - ), - ), - ), - ) - - actual_records = _read(stream, configured_stream, logger, slice_logger, message_repository, state_manager, internal_config) - - if constructor == _concurrent_stream: - assert hasattr(stream._cursor, "state") - assert str(stream._cursor.state) == "{'__ab_no_cursor_state_message': True}" - - assert actual_records == expected_records - - -@pytest.mark.parametrize( - "constructor", - [ - pytest.param(_stream, id="synchronous_reader"), - pytest.param(_concurrent_stream, id="concurrent_reader"), - ], -) -def test_full_refresh_read_a_single_slice(constructor): - # This test verifies that a concurrent stream adapted from a Stream behaves the same as the Stream object. - # It is done by running the same test cases on both streams - configured_stream = ConfiguredAirbyteStream( - stream=AirbyteStream(name="mock_stream", supported_sync_modes=[SyncMode.full_refresh], json_schema={}), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.overwrite, - ) - internal_config = InternalConfig() - logger = _mock_logger() - slice_logger = DebugSliceLogger() - message_repository = InMemoryMessageRepository(Level.INFO) - state_manager = ConnectorStateManager() - - records = [ - {"id": 1, "partition": 1}, - {"id": 2, "partition": 1}, - ] - slice_to_partition = {1: records} - stream = constructor(slice_to_partition, slice_logger, logger, message_repository) - - expected_records = [*records] - - # Synchronous streams emit a final state message to indicate that the stream has finished reading - # Concurrent streams don't emit their own state messages - the concurrent source observes the cursor - # and emits the state messages. Therefore, we can only check the value of the cursor's state at the end - if constructor == _stream: - expected_records.append( - AirbyteMessage( - type=MessageType.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="__mock_stream", namespace=None), - stream_state=AirbyteStateBlob(__ab_no_cursor_state_message=True), - ), - ), - ), - ) - - actual_records = _read(stream, configured_stream, logger, slice_logger, message_repository, state_manager, internal_config) - - if constructor == _concurrent_stream: - assert hasattr(stream._cursor, "state") - assert str(stream._cursor.state) == "{'__ab_no_cursor_state_message': True}" - - assert actual_records == expected_records - - -@pytest.mark.parametrize( - "constructor", - [ - pytest.param(_stream, id="synchronous_reader"), - pytest.param(_concurrent_stream, id="concurrent_reader"), - pytest.param(_stream_with_no_cursor_field, id="no_cursor_field"), - ], -) -def test_full_refresh_read_two_slices(constructor): - # This test verifies that a concurrent stream adapted from a Stream behaves the same as the Stream object - # It is done by running the same test cases on both streams - configured_stream = ConfiguredAirbyteStream( - stream=AirbyteStream(name="mock_stream", supported_sync_modes=[SyncMode.full_refresh], json_schema={}), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.overwrite, - ) - internal_config = InternalConfig() - logger = _mock_logger() - slice_logger = DebugSliceLogger() - message_repository = InMemoryMessageRepository(Level.INFO) - state_manager = ConnectorStateManager() - - records_partition_1 = [ - {"id": 1, "partition": 1}, - {"id": 2, "partition": 1}, - ] - records_partition_2 = [ - {"id": 3, "partition": 2}, - {"id": 4, "partition": 2}, - ] - slice_to_partition = {1: records_partition_1, 2: records_partition_2} - stream = constructor(slice_to_partition, slice_logger, logger, message_repository) - - expected_records = [ - *records_partition_1, - *records_partition_2, - ] - - # Synchronous streams emit a final state message to indicate that the stream has finished reading - # Concurrent streams don't emit their own state messages - the concurrent source observes the cursor - # and emits the state messages. Therefore, we can only check the value of the cursor's state at the end - if constructor == _stream or constructor == _stream_with_no_cursor_field: - expected_records.append( - AirbyteMessage( - type=MessageType.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="__mock_stream", namespace=None), - stream_state=AirbyteStateBlob(__ab_no_cursor_state_message=True), - ), - ), - ), - ) - - actual_records = _read(stream, configured_stream, logger, slice_logger, message_repository, state_manager, internal_config) - - if constructor == _concurrent_stream: - assert hasattr(stream._cursor, "state") - assert str(stream._cursor.state) == "{'__ab_no_cursor_state_message': True}" - - for record in expected_records: - assert record in actual_records - assert len(actual_records) == len(expected_records) - - -def test_incremental_read_two_slices(): - # This test verifies that a stream running in incremental mode emits state messages correctly - configured_stream = ConfiguredAirbyteStream( - stream=AirbyteStream(name="mock_stream", supported_sync_modes=[SyncMode.full_refresh, SyncMode.incremental], json_schema={}), - sync_mode=SyncMode.incremental, - cursor_field=["created_at"], - destination_sync_mode=DestinationSyncMode.overwrite, - ) - internal_config = InternalConfig() - logger = _mock_logger() - slice_logger = DebugSliceLogger() - message_repository = InMemoryMessageRepository(Level.INFO) - state_manager = ConnectorStateManager() - timestamp = "1708899427" - - records_partition_1 = [ - {"id": 1, "partition": 1, "created_at": "1708899000"}, - {"id": 2, "partition": 1, "created_at": "1708899000"}, - ] - records_partition_2 = [ - {"id": 3, "partition": 2, "created_at": "1708899400"}, - {"id": 4, "partition": 2, "created_at": "1708899427"}, - ] - slice_to_partition = {1: records_partition_1, 2: records_partition_2} - stream = _incremental_stream(slice_to_partition, slice_logger, logger, message_repository, timestamp) - - expected_records = [ - *records_partition_1, - _create_state_message("__mock_incremental_stream", {"created_at": timestamp}), - *records_partition_2, - _create_state_message("__mock_incremental_stream", {"created_at": timestamp}), - ] - - actual_records = _read(stream, configured_stream, logger, slice_logger, message_repository, state_manager, internal_config) - - for record in expected_records: - assert record in actual_records - assert len(actual_records) == len(expected_records) - - -def test_concurrent_incremental_read_two_slices(): - # This test verifies that an incremental concurrent stream manages state correctly for multiple slices syncing concurrently - configured_stream = ConfiguredAirbyteStream( - stream=AirbyteStream(name="mock_stream", supported_sync_modes=[SyncMode.full_refresh, SyncMode.incremental], json_schema={}), - sync_mode=SyncMode.incremental, - destination_sync_mode=DestinationSyncMode.overwrite, - ) - internal_config = InternalConfig() - logger = _mock_logger() - slice_logger = DebugSliceLogger() - message_repository = InMemoryMessageRepository(Level.INFO) - state_manager = ConnectorStateManager() - slice_timestamp_1 = "1708850000" - slice_timestamp_2 = "1708950000" - cursor = MockConcurrentCursor(message_repository) - - records_partition_1 = [ - {"id": 1, "partition": 1, "created_at": "1708800000"}, - {"id": 2, "partition": 1, "created_at": slice_timestamp_1}, - ] - records_partition_2 = [ - {"id": 3, "partition": 2, "created_at": "1708900000"}, - {"id": 4, "partition": 2, "created_at": slice_timestamp_2}, - ] - slice_to_partition = {1: records_partition_1, 2: records_partition_2} - stream = _incremental_concurrent_stream(slice_to_partition, slice_logger, logger, message_repository, cursor) - - expected_records = [ - *records_partition_1, - *records_partition_2, - ] - - expected_state = _create_state_message( - "__mock_stream", {"1": {"created_at": slice_timestamp_1}, "2": {"created_at": slice_timestamp_2}} - ) - - actual_records = _read(stream, configured_stream, logger, slice_logger, message_repository, state_manager, internal_config) - - handler = ConcurrentReadProcessor( - [stream], - Mock(spec=PartitionEnqueuer), - Mock(spec=ThreadPoolManager), - logger, - slice_logger, - message_repository, - Mock(spec=PartitionReader), - ) - - for record in expected_records: - assert record in actual_records - - # We need run on_record to update cursor with record cursor value - for record in actual_records: - list(handler.on_record(Record(record, Mock(spec=Partition, **{"stream_name.return_value": "__mock_stream"})))) - - assert len(actual_records) == len(expected_records) - - # We don't have a real source that reads from the message_repository for state, so we read from the queue directly to verify - # the cursor observed records correctly and updated partition states - mock_partition = Mock() - cursor.close_partition(mock_partition) - actual_state = [state for state in message_repository.consume_queue()] - assert len(actual_state) == 1 - assert actual_state[0] == expected_state - - -def setup_stream_dependencies(configured_json_schema): - configured_stream = ConfiguredAirbyteStream( - stream=AirbyteStream(name="mock_stream", supported_sync_modes=[SyncMode.full_refresh], json_schema=configured_json_schema), - sync_mode=SyncMode.full_refresh, - destination_sync_mode=DestinationSyncMode.overwrite, - ) - internal_config = InternalConfig() - logger = _mock_logger() - slice_logger = DebugSliceLogger() - message_repository = InMemoryMessageRepository(Level.INFO) - state_manager = ConnectorStateManager() - return configured_stream, internal_config, logger, slice_logger, message_repository, state_manager - - -def test_configured_json_schema(): - current_json_schema = { - "$schema": "https://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "id": {"type": ["null", "number"]}, - "name": {"type": ["null", "string"]}, - }, - } - - configured_stream, internal_config, logger, slice_logger, message_repository, state_manager = setup_stream_dependencies( - current_json_schema - ) - records = [ - {"id": 1, "partition": 1}, - {"id": 2, "partition": 1}, - ] - - slice_to_partition = {1: records} - stream = _stream(slice_to_partition, slice_logger, logger, message_repository, json_schema=current_json_schema) - assert not stream.configured_json_schema - _read(stream, configured_stream, logger, slice_logger, message_repository, state_manager, internal_config) - assert stream.configured_json_schema == current_json_schema - - -def test_configured_json_schema_with_invalid_properties(): - """ - Configured Schemas can have very old fields, so we need to housekeeping ourselves. - The purpose of this test in ensure that correct cleanup occurs when configured catalog schema is compared with current stream schema. - """ - old_user_insights = "old_user_insights" - old_feature_info = "old_feature_info" - configured_json_schema = { - "$schema": "https://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "id": {"type": ["null", "number"]}, - "name": {"type": ["null", "string"]}, - "cost_per_conversation": {"type": ["null", "string"]}, - old_user_insights: {"type": ["null", "string"]}, - old_feature_info: {"type": ["null", "string"]}, - }, - } - # stream schema is updated e.g. some fields in new api version are deprecated - stream_schema = deepcopy(configured_json_schema) - del stream_schema["properties"][old_user_insights] - del stream_schema["properties"][old_feature_info] - - configured_stream, internal_config, logger, slice_logger, message_repository, state_manager = setup_stream_dependencies( - configured_json_schema - ) - records = [ - {"id": 1, "partition": 1}, - {"id": 2, "partition": 1}, - ] - - slice_to_partition = {1: records} - stream = _stream(slice_to_partition, slice_logger, logger, message_repository, json_schema=stream_schema) - assert not stream.configured_json_schema - _read(stream, configured_stream, logger, slice_logger, message_repository, state_manager, internal_config) - assert stream.configured_json_schema != configured_json_schema - configured_json_schema_properties = stream.configured_json_schema["properties"] - assert old_user_insights not in configured_json_schema_properties - assert old_feature_info not in configured_json_schema_properties - for stream_schema_property in stream_schema["properties"]: - assert ( - stream_schema_property in configured_json_schema_properties - ), f"Stream schema property: {stream_schema_property} missing in configured schema" - assert stream_schema["properties"][stream_schema_property] == configured_json_schema_properties[stream_schema_property] - - -def _read(stream, configured_stream, logger, slice_logger, message_repository, state_manager, internal_config): - records = [] - for record in stream.read(configured_stream, logger, slice_logger, {}, state_manager, internal_config): - for message in message_repository.consume_queue(): - records.append(message) - records.append(record) - return records - - -def _mock_partition_generator(name: str, slices, records_per_partition, *, available=True, debug_log=False): - stream = Mock() - stream.name = name - stream.get_json_schema.return_value = {} - stream.generate_partitions.return_value = iter(slices) - stream.read_records.side_effect = [iter(records) for records in records_per_partition] - stream.logger.isEnabledFor.return_value = debug_log - if available: - stream.check_availability.return_value = True, None - else: - stream.check_availability.return_value = False, "A reason why the stream is unavailable" - return stream - - -def _mock_logger(enabled_for_debug=False): - logger = Mock() - logger.isEnabledFor.return_value = enabled_for_debug - logger.level = logging.DEBUG if enabled_for_debug else logging.INFO - return logger - - -def _create_state_message(stream: str, state: Mapping[str, Any]) -> AirbyteMessage: - return AirbyteMessage( - type=MessageType.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name=stream, namespace=None), - stream_state=AirbyteStateBlob(**state), - ), - ), - ) diff --git a/airbyte-cdk/python/unit_tests/sources/streams/test_streams_core.py b/airbyte-cdk/python/unit_tests/sources/streams/test_streams_core.py deleted file mode 100644 index 9f356b5c80bb..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/test_streams_core.py +++ /dev/null @@ -1,446 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -from typing import Any, Iterable, List, Mapping, MutableMapping, Optional -from unittest import mock - -import pytest -import requests -from airbyte_cdk.models import AirbyteStream, SyncMode -from airbyte_cdk.sources.streams import CheckpointMixin, Stream -from airbyte_cdk.sources.streams.checkpoint import ( - Cursor, - CursorBasedCheckpointReader, - FullRefreshCheckpointReader, - IncrementalCheckpointReader, - LegacyCursorBasedCheckpointReader, - ResumableFullRefreshCheckpointReader, - ResumableFullRefreshCursor, -) -from airbyte_cdk.sources.streams.http import HttpStream, HttpSubStream -from airbyte_cdk.sources.types import StreamSlice - -logger = logging.getLogger("airbyte") - - -class StreamStubFullRefresh(Stream): - """ - Stub full refresh class to assist with testing. - """ - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: List[str] = None, - stream_slice: Mapping[str, Any] = None, - stream_state: Mapping[str, Any] = None, - ) -> Iterable[Mapping[str, Any]]: - pass - - primary_key = None - - -class StreamStubIncremental(Stream, CheckpointMixin): - """ - Stub full incremental class to assist with testing. - """ - - _state = {} - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: List[str] = None, - stream_slice: Mapping[str, Any] = None, - stream_state: Mapping[str, Any] = None, - ) -> Iterable[Mapping[str, Any]]: - pass - - cursor_field = "test_cursor" - primary_key = "primary_key" - namespace = "test_namespace" - - @property - def state(self) -> MutableMapping[str, Any]: - return self._state - - @state.setter - def state(self, value: MutableMapping[str, Any]) -> None: - self._state = value - - -class StreamStubResumableFullRefresh(Stream, CheckpointMixin): - """ - Stub full incremental class to assist with testing. - """ - - _state = {} - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: List[str] = None, - stream_slice: Mapping[str, Any] = None, - stream_state: Mapping[str, Any] = None, - ) -> Iterable[Mapping[str, Any]]: - pass - - primary_key = "primary_key" - - @property - def state(self) -> MutableMapping[str, Any]: - return self._state - - @state.setter - def state(self, value: MutableMapping[str, Any]) -> None: - self._state = value - - -class StreamStubLegacyStateInterface(Stream): - """ - Stub full incremental class to assist with testing. - """ - - _state = {} - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: List[str] = None, - stream_slice: Mapping[str, Any] = None, - stream_state: Mapping[str, Any] = None, - ) -> Iterable[Mapping[str, Any]]: - pass - - cursor_field = "test_cursor" - primary_key = "primary_key" - namespace = "test_namespace" - - def get_updated_state( - self, current_stream_state: MutableMapping[str, Any], latest_record: Mapping[str, Any] - ) -> MutableMapping[str, Any]: - return {} - - -class StreamStubIncrementalEmptyNamespace(Stream): - """ - Stub full incremental class, with empty namespace, to assist with testing. - """ - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: List[str] = None, - stream_slice: Mapping[str, Any] = None, - stream_state: Mapping[str, Any] = None, - ) -> Iterable[Mapping[str, Any]]: - pass - - cursor_field = "test_cursor" - primary_key = "primary_key" - namespace = "" - - -class HttpSubStreamStubFullRefreshLegacySlices(HttpSubStream): - """ - Stub substream full refresh class to assist with testing. - """ - - primary_key = "primary_key" - - @property - def url_base(self) -> str: - return "https://airbyte.io/api/v1" - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - pass - - def path( - self, - *, - stream_state: Optional[Mapping[str, Any]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> str: - return "/stub" - - def parse_response( - self, - response: requests.Response, - *, - stream_state: Mapping[str, Any], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Iterable[Mapping[str, Any]]: - return [] - - -class CursorBasedStreamStubFullRefresh(StreamStubFullRefresh): - def get_cursor(self) -> Optional[Cursor]: - return ResumableFullRefreshCursor() - - -class LegacyCursorBasedStreamStubFullRefresh(CursorBasedStreamStubFullRefresh): - def stream_slices( - self, *, sync_mode: SyncMode, cursor_field: Optional[List[str]] = None, stream_state: Optional[Mapping[str, Any]] = None - ) -> Iterable[Optional[Mapping[str, Any]]]: - yield from [{}] - - -class MultipleSlicesStreamStub(HttpStream): - """ - Stub full refresh class that returns multiple StreamSlice instances to assist with testing. - """ - - primary_key = "primary_key" - - @property - def url_base(self) -> str: - return "https://airbyte.io/api/v1" - - def stream_slices( - self, *, sync_mode: SyncMode, cursor_field: Optional[List[str]] = None, stream_state: Optional[Mapping[str, Any]] = None - ) -> Iterable[Optional[Mapping[str, Any]]]: - yield from [ - StreamSlice(partition={"parent_id": "korra"}, cursor_slice={}), - StreamSlice(partition={"parent_id": "asami"}, cursor_slice={}), - ] - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - pass - - def path( - self, - *, - stream_state: Optional[Mapping[str, Any]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> str: - return "/stub" - - def parse_response( - self, - response: requests.Response, - *, - stream_state: Mapping[str, Any], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Iterable[Mapping[str, Any]]: - return [] - - -class ParentHttpStreamStub(HttpStream): - primary_key = "primary_key" - url_base = "https://airbyte.io/api/v1" - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: List[str] = None, - stream_slice: Mapping[str, Any] = None, - stream_state: Mapping[str, Any] = None, - ) -> Iterable[Mapping[str, Any]]: - return [{"id": 400, "name": "a_parent_record"}] - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - return None - - def path( - self, - *, - stream_state: Optional[Mapping[str, Any]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> str: - return "/parent" - - def parse_response( - self, - response: requests.Response, - *, - stream_state: Mapping[str, Any], - stream_slice: Optional[Mapping[str, Any]] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Iterable[Mapping[str, Any]]: - return [] - - -def test_as_airbyte_stream_full_refresh(mocker): - """ - Should return an full refresh AirbyteStream with information matching the - provided Stream interface. - """ - test_stream = StreamStubFullRefresh() - - mocker.patch.object(StreamStubFullRefresh, "get_json_schema", return_value={}) - airbyte_stream = test_stream.as_airbyte_stream() - - exp = AirbyteStream(name="stream_stub_full_refresh", json_schema={}, supported_sync_modes=[SyncMode.full_refresh], is_resumable=False) - assert airbyte_stream == exp - - -def test_as_airbyte_stream_incremental(mocker): - """ - Should return an incremental refresh AirbyteStream with information matching - the provided Stream interface. - """ - test_stream = StreamStubIncremental() - - mocker.patch.object(StreamStubIncremental, "get_json_schema", return_value={}) - airbyte_stream = test_stream.as_airbyte_stream() - - exp = AirbyteStream( - name="stream_stub_incremental", - namespace="test_namespace", - json_schema={}, - supported_sync_modes=[SyncMode.full_refresh, SyncMode.incremental], - default_cursor_field=["test_cursor"], - source_defined_cursor=True, - source_defined_primary_key=[["primary_key"]], - is_resumable=True, - ) - assert airbyte_stream == exp - - -def test_supports_incremental_cursor_set(): - """ - Should return true if cursor is set. - """ - test_stream = StreamStubIncremental() - test_stream.cursor_field = "test_cursor" - - assert test_stream.supports_incremental - - -def test_supports_incremental_cursor_not_set(): - """ - Should return false if cursor is not. - """ - test_stream = StreamStubFullRefresh() - - assert not test_stream.supports_incremental - - -def test_namespace_set(): - """ - Should allow namespace property to be set. - """ - test_stream = StreamStubIncremental() - - assert test_stream.namespace == "test_namespace" - - -def test_namespace_set_to_empty_string(mocker): - """ - Should not set namespace property if equal to empty string. - """ - test_stream = StreamStubIncremental() - - mocker.patch.object(StreamStubIncremental, "get_json_schema", return_value={}) - mocker.patch.object(StreamStubIncremental, "namespace", "") - - airbyte_stream = test_stream.as_airbyte_stream() - - exp = AirbyteStream( - name="stream_stub_incremental", - json_schema={}, - supported_sync_modes=[SyncMode.full_refresh, SyncMode.incremental], - default_cursor_field=["test_cursor"], - source_defined_cursor=True, - source_defined_primary_key=[["primary_key"]], - namespace=None, - is_resumable=True, - ) - assert airbyte_stream == exp - - -def test_namespace_not_set(): - """ - Should be equal to unset value of None. - """ - test_stream = StreamStubFullRefresh() - - assert test_stream.namespace is None - - -@pytest.mark.parametrize( - "test_input, expected", - [("key", [["key"]]), (["key1", "key2"], [["key1"], ["key2"]]), ([["key1", "key2"], ["key3"]], [["key1", "key2"], ["key3"]])], -) -def test_wrapped_primary_key_various_argument(test_input, expected): - """ - Should always wrap primary key into list of lists. - """ - - wrapped = Stream._wrapped_primary_key(test_input) - - assert wrapped == expected - - -@mock.patch("airbyte_cdk.sources.utils.schema_helpers.ResourceSchemaLoader.get_schema") -def test_get_json_schema_is_cached(mocked_method): - stream = StreamStubFullRefresh() - for i in range(5): - stream.get_json_schema() - assert mocked_method.call_count == 1 - - -@pytest.mark.parametrize( - "stream, stream_state, expected_checkpoint_reader_type", - [ - pytest.param(StreamStubIncremental(), {}, IncrementalCheckpointReader, id="test_incremental_checkpoint_reader"), - pytest.param(StreamStubFullRefresh(), {}, FullRefreshCheckpointReader, id="test_full_refresh_checkpoint_reader"), - pytest.param( - StreamStubResumableFullRefresh(), {}, ResumableFullRefreshCheckpointReader, id="test_resumable_full_refresh_checkpoint_reader" - ), - pytest.param( - StreamStubLegacyStateInterface(), {}, IncrementalCheckpointReader, id="test_incremental_checkpoint_reader_with_legacy_state" - ), - pytest.param( - CursorBasedStreamStubFullRefresh(), - {"next_page_token": 10}, - CursorBasedCheckpointReader, - id="test_checkpoint_reader_using_rfr_cursor", - ), - pytest.param( - LegacyCursorBasedStreamStubFullRefresh(), - {}, - LegacyCursorBasedCheckpointReader, - id="test_full_refresh_checkpoint_reader_for_legacy_slice_format", - ), - ], -) -def test_get_checkpoint_reader(stream: Stream, stream_state, expected_checkpoint_reader_type): - checkpoint_reader = stream._get_checkpoint_reader( - logger=logger, - cursor_field=["updated_at"], - sync_mode=SyncMode.incremental, - stream_state=stream_state, - ) - - assert isinstance(checkpoint_reader, expected_checkpoint_reader_type) - - if isinstance(checkpoint_reader, CursorBasedCheckpointReader): - cursor = checkpoint_reader._cursor - if isinstance(cursor, ResumableFullRefreshCursor): - actual_cursor_state = cursor.get_stream_state() - - assert actual_cursor_state == stream_state - - -def test_checkpoint_reader_with_no_partitions(): - """ - Tests the edge case where an incremental stream might not generate any partitions, but should still attempt at least - one iteration of calling read_records() - """ - stream = StreamStubIncremental() - checkpoint_reader = stream._get_checkpoint_reader( - logger=logger, - cursor_field=["updated_at"], - sync_mode=SyncMode.incremental, - stream_state={}, - ) - - assert checkpoint_reader.next() == {} diff --git a/airbyte-cdk/python/unit_tests/sources/streams/utils/test_stream_helper.py b/airbyte-cdk/python/unit_tests/sources/streams/utils/test_stream_helper.py deleted file mode 100644 index da76a78714d7..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/streams/utils/test_stream_helper.py +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -from airbyte_cdk.sources.streams.http.availability_strategy import HttpAvailabilityStrategy - - -class MockStream: - def __init__(self, records, exit_on_rate_limit=True): - self.records = records - self._exit_on_rate_limit = exit_on_rate_limit - type(self).exit_on_rate_limit = property( - lambda self: self._get_exit_on_rate_limit(), lambda self, value: self._set_exit_on_rate_limit(value) - ) - - def _get_exit_on_rate_limit(self): - return self._exit_on_rate_limit - - def _set_exit_on_rate_limit(self, value): - self._exit_on_rate_limit = value - - def read_records(self, sync_mode, stream_slice): - return self.records - - -@pytest.mark.parametrize( - "records, stream_slice, exit_on_rate_limit, expected_result, raises_exception", - [ - ([{"id": 1}], None, True, {"id": 1}, False), # Single record, with setter - ([{"id": 1}, {"id": 2}], None, True, {"id": 1}, False), # Multiple records, with setter - ([], None, True, None, True), # No records, with setter - ], -) -def test_get_first_record_for_slice(records, stream_slice, exit_on_rate_limit, expected_result, raises_exception): - stream = MockStream(records, exit_on_rate_limit) - - if raises_exception: - with pytest.raises(StopIteration): - HttpAvailabilityStrategy().get_first_record_for_slice(stream, stream_slice) - else: - result = HttpAvailabilityStrategy().get_first_record_for_slice(stream, stream_slice) - assert result == expected_result - - assert stream.exit_on_rate_limit == exit_on_rate_limit diff --git a/airbyte-cdk/python/unit_tests/sources/test_abstract_source.py b/airbyte-cdk/python/unit_tests/sources/test_abstract_source.py deleted file mode 100644 index 9de46b9e116f..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/test_abstract_source.py +++ /dev/null @@ -1,1713 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import copy -import datetime -import logging -from typing import Any, Callable, Dict, Iterable, List, Mapping, MutableMapping, Optional, Tuple, Union -from unittest.mock import Mock - -import pytest -from airbyte_cdk.models import ( - AirbyteCatalog, - AirbyteConnectionStatus, - AirbyteErrorTraceMessage, - AirbyteLogMessage, - AirbyteMessage, - AirbyteRecordMessage, - AirbyteStateBlob, - AirbyteStateMessage, - AirbyteStateType, - AirbyteStream, - AirbyteStreamState, - AirbyteStreamStatus, - AirbyteStreamStatusTraceMessage, - AirbyteTraceMessage, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteStream, - DestinationSyncMode, - FailureType, - Level, - Status, - StreamDescriptor, - SyncMode, - TraceType, -) -from airbyte_cdk.models import Type -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources import AbstractSource -from airbyte_cdk.sources.message import MessageRepository -from airbyte_cdk.sources.streams import IncrementalMixin, Stream -from airbyte_cdk.sources.utils.record_helper import stream_data_to_airbyte_message -from airbyte_cdk.utils.airbyte_secrets_utils import update_secrets -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from pytest import fixture - -logger = logging.getLogger("airbyte") - - -class MockSource(AbstractSource): - def __init__( - self, - check_lambda: Callable[[], Tuple[bool, Optional[Any]]] = None, - streams: List[Stream] = None, - message_repository: MessageRepository = None, - exception_on_missing_stream: bool = True, - stop_sync_on_stream_failure: bool = False, - ): - self._streams = streams - self.check_lambda = check_lambda - self.exception_on_missing_stream = exception_on_missing_stream - self._message_repository = message_repository - self._stop_sync_on_stream_failure = stop_sync_on_stream_failure - - def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Optional[Any]]: - if self.check_lambda: - return self.check_lambda() - return False, "Missing callable." - - def streams(self, config: Mapping[str, Any]) -> List[Stream]: - if not self._streams: - raise Exception("Stream is not set") - return self._streams - - @property - def raise_exception_on_missing_stream(self) -> bool: - return self.exception_on_missing_stream - - @property - def per_stream_state_enabled(self) -> bool: - return self.per_stream - - @property - def message_repository(self): - return self._message_repository - - -class MockSourceWithStopSyncFalseOverride(MockSource): - @property - def stop_sync_on_stream_failure(self) -> bool: - return False - - -class StreamNoStateMethod(Stream): - name = "managers" - primary_key = None - - def read_records(self, *args, **kwargs) -> Iterable[Mapping[str, Any]]: - return {} - - -class MockStreamOverridesStateMethod(Stream, IncrementalMixin): - name = "teams" - primary_key = None - cursor_field = "updated_at" - _cursor_value = "" - start_date = "1984-12-12" - - def read_records(self, *args, **kwargs) -> Iterable[Mapping[str, Any]]: - return {} - - @property - def state(self) -> MutableMapping[str, Any]: - return {self.cursor_field: self._cursor_value} if self._cursor_value else {} - - @state.setter - def state(self, value: MutableMapping[str, Any]): - self._cursor_value = value.get(self.cursor_field, self.start_date) - - -class StreamRaisesException(Stream): - name = "lamentations" - primary_key = None - - def __init__(self, exception_to_raise): - self._exception_to_raise = exception_to_raise - - def read_records(self, *args, **kwargs) -> Iterable[Mapping[str, Any]]: - raise self._exception_to_raise - - -MESSAGE_FROM_REPOSITORY = Mock() - - -@fixture -def message_repository(): - message_repository = Mock(spec=MessageRepository) - message_repository.consume_queue.return_value = [message for message in [MESSAGE_FROM_REPOSITORY]] - return message_repository - - -def test_successful_check(): - """Tests that if a source returns TRUE for the connection check the appropriate connectionStatus success message is returned""" - expected = AirbyteConnectionStatus(status=Status.SUCCEEDED) - assert MockSource(check_lambda=lambda: (True, None)).check(logger, {}) == expected - - -def test_failed_check(): - """Tests that if a source returns FALSE for the connection check the appropriate connectionStatus failure message is returned""" - expected = AirbyteConnectionStatus(status=Status.FAILED, message="'womp womp'") - assert MockSource(check_lambda=lambda: (False, "womp womp")).check(logger, {}) == expected - - -def test_raising_check(mocker): - """Tests that if a source raises an unexpected exception the appropriate connectionStatus failure message is returned.""" - check_lambda = mocker.Mock(side_effect=BaseException("this should fail")) - with pytest.raises(BaseException): - MockSource(check_lambda=check_lambda).check(logger, {}) - - -class MockStream(Stream): - def __init__( - self, - inputs_and_mocked_outputs: List[Tuple[Mapping[str, Any], Iterable[Mapping[str, Any]]]] = None, - name: str = None, - ): - self._inputs_and_mocked_outputs = inputs_and_mocked_outputs - self._name = name - - @property - def name(self): - return self._name - - def read_records(self, **kwargs) -> Iterable[Mapping[str, Any]]: # type: ignore - # Remove None values - kwargs = {k: v for k, v in kwargs.items() if v is not None} - if self._inputs_and_mocked_outputs: - for _input, output in self._inputs_and_mocked_outputs: - if kwargs == _input: - return output - - raise Exception(f"No mocked output supplied for input: {kwargs}. Mocked inputs/outputs: {self._inputs_and_mocked_outputs}") - - @property - def primary_key(self) -> Optional[Union[str, List[str], List[List[str]]]]: - return "pk" - - @property - def cursor_field(self) -> Union[str, List[str]]: - return ["updated_at"] - - -class MockStreamWithCursor(MockStream): - cursor_field = "cursor" - - def __init__(self, inputs_and_mocked_outputs: List[Tuple[Mapping[str, Any], Iterable[Mapping[str, Any]]]], name: str): - super().__init__(inputs_and_mocked_outputs, name) - - -class MockStreamWithState(MockStreamWithCursor): - def __init__(self, inputs_and_mocked_outputs: List[Tuple[Mapping[str, Any], Iterable[Mapping[str, Any]]]], name: str, state=None): - super().__init__(inputs_and_mocked_outputs, name) - self._state = state - - @property - def state(self): - return self._state - - @state.setter - def state(self, value): - pass - - -class MockStreamEmittingAirbyteMessages(MockStreamWithState): - def __init__( - self, inputs_and_mocked_outputs: List[Tuple[Mapping[str, Any], Iterable[AirbyteMessage]]] = None, name: str = None, state=None - ): - super().__init__(inputs_and_mocked_outputs, name, state) - self._inputs_and_mocked_outputs = inputs_and_mocked_outputs - self._name = name - - @property - def name(self): - return self._name - - @property - def primary_key(self) -> Optional[Union[str, List[str], List[List[str]]]]: - return "pk" - - @property - def state(self) -> MutableMapping[str, Any]: - return {self.cursor_field: self._cursor_value} if self._cursor_value else {} - - @state.setter - def state(self, value: MutableMapping[str, Any]): - self._cursor_value = value.get(self.cursor_field) - - -class MockResumableFullRefreshStream(Stream): - def __init__( - self, - inputs_and_mocked_outputs: List[Tuple[Mapping[str, Any], Mapping[str, Any]]] = None, - name: str = None, - ): - self._inputs_and_mocked_outputs = inputs_and_mocked_outputs - self._name = name - self._state = {} - - @property - def name(self): - return self._name - - def read_records(self, **kwargs) -> Iterable[Mapping[str, Any]]: # type: ignore - output = None - next_page_token = {} - kwargs = {k: v for k, v in kwargs.items() if v is not None} - if self._inputs_and_mocked_outputs: - for _input, mocked_output in self._inputs_and_mocked_outputs: - if kwargs == _input: - if "error" in mocked_output: - raise AirbyteTracedException(message=mocked_output.get("error")) - else: - next_page_token = mocked_output.get("next_page") - output = mocked_output.get("records") - - if output is None: - raise Exception(f"No mocked output supplied for input: {kwargs}. Mocked inputs/outputs: {self._inputs_and_mocked_outputs}") - - self.state = next_page_token or {"__ab_full_refresh_sync_complete": True} - yield from output - - @property - def primary_key(self) -> Optional[Union[str, List[str], List[List[str]]]]: - return "id" - - @property - def state(self) -> MutableMapping[str, Any]: - return self._state - - @state.setter - def state(self, value: MutableMapping[str, Any]): - self._state = value - - -def test_discover(mocker): - """Tests that the appropriate AirbyteCatalog is returned from the discover method""" - airbyte_stream1 = AirbyteStream( - name="1", - json_schema={}, - supported_sync_modes=[SyncMode.full_refresh, SyncMode.incremental], - default_cursor_field=["cursor"], - source_defined_cursor=True, - source_defined_primary_key=[["pk"]], - ) - airbyte_stream2 = AirbyteStream(name="2", json_schema={}, supported_sync_modes=[SyncMode.full_refresh]) - - stream1 = MockStream() - stream2 = MockStream() - mocker.patch.object(stream1, "as_airbyte_stream", return_value=airbyte_stream1) - mocker.patch.object(stream2, "as_airbyte_stream", return_value=airbyte_stream2) - - expected = AirbyteCatalog(streams=[airbyte_stream1, airbyte_stream2]) - src = MockSource(check_lambda=lambda: (True, None), streams=[stream1, stream2]) - - assert src.discover(logger, {}) == expected - - -def test_read_nonexistent_stream_raises_exception(mocker): - """Tests that attempting to sync a stream which the source does not return from the `streams` method raises an exception""" - s1 = MockStream(name="s1") - s2 = MockStream(name="this_stream_doesnt_exist_in_the_source") - - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - - src = MockSource(streams=[s1]) - catalog = ConfiguredAirbyteCatalog(streams=[_configured_stream(s2, SyncMode.full_refresh)]) - with pytest.raises(AirbyteTracedException) as exc_info: - list(src.read(logger, {}, catalog)) - - assert exc_info.value.failure_type == FailureType.config_error - assert "not found in the source" in exc_info.value.message - - -def test_read_nonexistent_stream_without_raises_exception(mocker, as_stream_status): - """Tests that attempting to sync a stream which the source does not return from the `streams` method raises an exception""" - s1 = MockStream(name="s1") - s2 = MockStream(name="this_stream_doesnt_exist_in_the_source") - - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - - src = MockSource(streams=[s1], exception_on_missing_stream=False) - - catalog = ConfiguredAirbyteCatalog(streams=[_configured_stream(s2, SyncMode.full_refresh)]) - messages = list(src.read(logger, {}, catalog)) - messages = _fix_emitted_at(messages) - - expected = _fix_emitted_at([as_stream_status("this_stream_doesnt_exist_in_the_source", AirbyteStreamStatus.INCOMPLETE)]) - - assert messages == expected - - -def test_read_stream_emits_repository_message_before_record(mocker, message_repository): - stream = MockStream(name="my_stream") - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - mocker.patch.object(MockStream, "read_records", side_effect=[[{"a record": "a value"}, {"another record": "another value"}]]) - message_repository.consume_queue.side_effect = [[message for message in [MESSAGE_FROM_REPOSITORY]], [], []] - - source = MockSource(streams=[stream], message_repository=message_repository) - - messages = list(source.read(logger, {}, ConfiguredAirbyteCatalog(streams=[_configured_stream(stream, SyncMode.full_refresh)]))) - - assert messages.count(MESSAGE_FROM_REPOSITORY) == 1 - record_messages = (message for message in messages if message.type == Type.RECORD) - assert all(messages.index(MESSAGE_FROM_REPOSITORY) < messages.index(record) for record in record_messages) - - -def test_read_stream_emits_repository_message_on_error(mocker, message_repository): - stream = MockStream(name="my_stream") - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - mocker.patch.object(MockStream, "read_records", side_effect=RuntimeError("error")) - message_repository.consume_queue.return_value = [message for message in [MESSAGE_FROM_REPOSITORY]] - - source = MockSource(streams=[stream], message_repository=message_repository) - - with pytest.raises(AirbyteTracedException): - messages = list(source.read(logger, {}, ConfiguredAirbyteCatalog(streams=[_configured_stream(stream, SyncMode.full_refresh)]))) - assert MESSAGE_FROM_REPOSITORY in messages - - -def test_read_stream_with_error_gets_display_message(mocker): - stream = MockStream(name="my_stream") - - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - mocker.patch.object(MockStream, "read_records", side_effect=RuntimeError("oh no!")) - - source = MockSource(streams=[stream]) - catalog = ConfiguredAirbyteCatalog(streams=[_configured_stream(stream, SyncMode.full_refresh)]) - - # without get_error_display_message - with pytest.raises(AirbyteTracedException): - list(source.read(logger, {}, catalog)) - - mocker.patch.object(MockStream, "get_error_display_message", return_value="my message") - - with pytest.raises(AirbyteTracedException) as exc: - list(source.read(logger, {}, catalog)) - assert "oh no!" in exc.value.message - - -GLOBAL_EMITTED_AT = 1 - - -def _as_record(stream: str, data: Dict[str, Any]) -> AirbyteMessage: - return AirbyteMessage( - type=Type.RECORD, - record=AirbyteRecordMessage(stream=stream, data=data, emitted_at=GLOBAL_EMITTED_AT), - ) - - -def _as_records(stream: str, data: List[Dict[str, Any]]) -> List[AirbyteMessage]: - return [_as_record(stream, datum) for datum in data] - - -# TODO: Replace call of this function to fixture in the tests -def _as_stream_status(stream: str, status: AirbyteStreamStatus) -> AirbyteMessage: - trace_message = AirbyteTraceMessage( - emitted_at=datetime.datetime.now().timestamp() * 1000.0, - type=TraceType.STREAM_STATUS, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name=stream), - status=status, - ), - ) - - return AirbyteMessage(type=MessageType.TRACE, trace=trace_message) - - -def _as_state(stream_name: str = "", per_stream_state: Dict[str, Any] = None): - return AirbyteMessage( - type=Type.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name=stream_name), stream_state=AirbyteStateBlob(per_stream_state) - ), - ), - ) - - -def _as_error_trace( - stream: str, error_message: str, internal_message: Optional[str], failure_type: Optional[FailureType], stack_trace: Optional[str] -) -> AirbyteMessage: - trace_message = AirbyteTraceMessage( - emitted_at=datetime.datetime.now().timestamp() * 1000.0, - type=TraceType.ERROR, - error=AirbyteErrorTraceMessage( - stream_descriptor=StreamDescriptor(name=stream), - message=error_message, - internal_message=internal_message, - failure_type=failure_type, - stack_trace=stack_trace, - ), - ) - - return AirbyteMessage(type=MessageType.TRACE, trace=trace_message) - - -def _configured_stream(stream: Stream, sync_mode: SyncMode): - return ConfiguredAirbyteStream( - stream=stream.as_airbyte_stream(), - sync_mode=sync_mode, - destination_sync_mode=DestinationSyncMode.overwrite, - ) - - -def _fix_emitted_at(messages: List[AirbyteMessage]) -> List[AirbyteMessage]: - for msg in messages: - if msg.type == Type.RECORD and msg.record: - msg.record.emitted_at = GLOBAL_EMITTED_AT - if msg.type == Type.TRACE and msg.trace: - msg.trace.emitted_at = GLOBAL_EMITTED_AT - return messages - - -def test_valid_full_refresh_read_no_slices(mocker): - """Tests that running a full refresh sync on streams which don't specify slices produces the expected AirbyteMessages""" - stream_output = [{"k1": "v1"}, {"k2": "v2"}] - s1 = MockStream([({"stream_slice": {}, "stream_state": {}, "sync_mode": SyncMode.full_refresh}, stream_output)], name="s1") - s2 = MockStream([({"stream_slice": {}, "stream_state": {}, "sync_mode": SyncMode.full_refresh}, stream_output)], name="s2") - - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - mocker.patch.object(MockStream, "cursor_field", return_value=[]) - - src = MockSource(streams=[s1, s2]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(s1, SyncMode.full_refresh), - _configured_stream(s2, SyncMode.full_refresh), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_stream_status("s1", AirbyteStreamStatus.RUNNING), - *_as_records("s1", stream_output), - _as_state("s1", {"__ab_no_cursor_state_message": True}), - _as_stream_status("s1", AirbyteStreamStatus.COMPLETE), - _as_stream_status("s2", AirbyteStreamStatus.STARTED), - _as_stream_status("s2", AirbyteStreamStatus.RUNNING), - *_as_records("s2", stream_output), - _as_state("s2", {"__ab_no_cursor_state_message": True}), - _as_stream_status("s2", AirbyteStreamStatus.COMPLETE), - ] - ) - messages = _fix_emitted_at(list(src.read(logger, {}, catalog))) - - assert messages == expected - - -def test_valid_full_refresh_read_with_slices(mocker): - """Tests that running a full refresh sync on streams which use slices produces the expected AirbyteMessages""" - slices = [{"1": "1"}, {"2": "2"}] - # When attempting to sync a slice, just output that slice as a record - s1 = MockStream( - [({"stream_state": {}, "sync_mode": SyncMode.full_refresh, "stream_slice": s}, [s]) for s in slices], - name="s1", - ) - s2 = MockStream( - [({"stream_state": {}, "sync_mode": SyncMode.full_refresh, "stream_slice": s}, [s]) for s in slices], - name="s2", - ) - - mocker.patch.object(MockStream, "cursor_field", return_value=None) - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - mocker.patch.object(MockStream, "stream_slices", return_value=slices) - - src = MockSource(streams=[s1, s2]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(s1, SyncMode.full_refresh), - _configured_stream(s2, SyncMode.full_refresh), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_stream_status("s1", AirbyteStreamStatus.RUNNING), - *_as_records("s1", slices), - _as_state("s1", {"__ab_no_cursor_state_message": True}), - _as_stream_status("s1", AirbyteStreamStatus.COMPLETE), - _as_stream_status("s2", AirbyteStreamStatus.STARTED), - _as_stream_status("s2", AirbyteStreamStatus.RUNNING), - *_as_records("s2", slices), - _as_state("s2", {"__ab_no_cursor_state_message": True}), - _as_stream_status("s2", AirbyteStreamStatus.COMPLETE), - ] - ) - - messages = _fix_emitted_at(list(src.read(logger, {}, catalog))) - - assert messages == expected - - -@pytest.mark.parametrize( - "slices", - [[{"1": "1"}, {"2": "2"}], [{"date": datetime.date(year=2023, month=1, day=1)}, {"date": datetime.date(year=2023, month=1, day=1)}]], -) -def test_read_full_refresh_with_slices_sends_slice_messages(mocker, slices): - """Given the logger is debug and a full refresh, AirbyteMessages are sent for slices""" - debug_logger = logging.getLogger("airbyte.debug") - debug_logger.setLevel(logging.DEBUG) - stream = MockStream( - [({"stream_state": {}, "sync_mode": SyncMode.full_refresh, "stream_slice": s}, [s]) for s in slices], - name="s1", - ) - - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - mocker.patch.object(MockStream, "stream_slices", return_value=slices) - - src = MockSource(streams=[stream]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(stream, SyncMode.full_refresh), - ] - ) - - messages = src.read(debug_logger, {}, catalog) - - assert 2 == len(list(filter(lambda message: message.log and message.log.message.startswith("slice:"), messages))) - - -def test_read_incremental_with_slices_sends_slice_messages(mocker): - """Given the logger is debug and a incremental, AirbyteMessages are sent for slices""" - debug_logger = logging.getLogger("airbyte.debug") - debug_logger.setLevel(logging.DEBUG) - slices = [{"1": "1"}, {"2": "2"}] - stream = MockStream( - [({"sync_mode": SyncMode.incremental, "stream_slice": s, "stream_state": {}}, [s]) for s in slices], - name="s1", - ) - - MockStream.supports_incremental = mocker.PropertyMock(return_value=True) - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - mocker.patch.object(MockStream, "stream_slices", return_value=slices) - - src = MockSource(streams=[stream]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(stream, SyncMode.incremental), - ] - ) - - messages = src.read(debug_logger, {}, catalog) - - assert 2 == len(list(filter(lambda message: message.log and message.log.message.startswith("slice:"), messages))) - - -class TestIncrementalRead: - def test_with_state_attribute(self, mocker): - """Test correct state passing for the streams that have a state attribute""" - stream_output = [{"k1": "v1"}, {"k2": "v2"}] - old_state = {"cursor": "old_value"} - input_state = [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState(stream_descriptor=StreamDescriptor(name="s1"), stream_state=AirbyteStateBlob(old_state)), - ), - ] - new_state_from_connector = {"cursor": "new_value"} - - stream_1 = MockStreamWithState( - [ - ( - {"sync_mode": SyncMode.incremental, "stream_slice": {}, "stream_state": old_state}, - stream_output, - ) - ], - name="s1", - ) - stream_2 = MockStreamWithState( - [({"sync_mode": SyncMode.incremental, "stream_slice": {}, "stream_state": {}}, stream_output)], - name="s2", - ) - - # Mock the stream's getter property for each time the stream reads self.state while syncing a stream - getter_mock = Mock(wraps=MockStreamWithState.state.fget) - getter_mock.side_effect = [ - old_state, # stream s1: Setting the checkpoint reader state to self.state if implemented - old_state, # stream s1: observe state after first record - old_state, # stream s1: observe state after second record - new_state_from_connector, # stream s2: observe state after first slice - {}, # stream s2: Setting the checkpoint reader state to self.state if implemented - {}, # stream s2: observe state after first record - {}, # stream s2: observe state after second record - new_state_from_connector, # stream s2: observe state after first slice - ] - mock_get_property = MockStreamWithState.state.getter(getter_mock) - state_property = mocker.patch.object( - MockStreamWithState, - "state", - mock_get_property, - ) - - mocker.patch.object(MockStreamWithState, "get_json_schema", return_value={}) - src = MockSource(streams=[stream_1, stream_2]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(stream_1, SyncMode.incremental), - _configured_stream(stream_2, SyncMode.incremental), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_stream_status("s1", AirbyteStreamStatus.RUNNING), - _as_record("s1", stream_output[0]), - _as_record("s1", stream_output[1]), - _as_state("s1", new_state_from_connector), - _as_stream_status("s1", AirbyteStreamStatus.COMPLETE), - _as_stream_status("s2", AirbyteStreamStatus.STARTED), - _as_stream_status("s2", AirbyteStreamStatus.RUNNING), - _as_record("s2", stream_output[0]), - _as_record("s2", stream_output[1]), - _as_state("s2", new_state_from_connector), - _as_stream_status("s2", AirbyteStreamStatus.COMPLETE), - ] - ) - messages = _fix_emitted_at(list(src.read(logger, {}, catalog, state=input_state))) - - assert messages == expected - - # The state getter is called when we call the stream's observe method. We call self.state at the start of each stream (2 times), - # once for each record (4 times), and at the end of each slice (2 times) - assert len(state_property.fget.mock_calls) == 8 - - def test_with_checkpoint_interval(self, mocker): - """Tests that an incremental read which doesn't specify a checkpoint interval outputs a STATE message - after reading N records within a stream. - """ - input_state = [] - stream_output = [{"k1": "v1"}, {"k2": "v2"}] - - stream_1 = MockStream( - [({"sync_mode": SyncMode.incremental, "stream_slice": {}, "stream_state": {}}, stream_output)], - name="s1", - ) - stream_2 = MockStream( - [({"sync_mode": SyncMode.incremental, "stream_slice": {}, "stream_state": {}}, stream_output)], - name="s2", - ) - state = {"cursor": "value"} - mocker.patch.object(MockStream, "get_updated_state", return_value=state) - mocker.patch.object(MockStream, "supports_incremental", return_value=True) - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - # Tell the source to output one state message per record - mocker.patch.object( - MockStream, - "state_checkpoint_interval", - new_callable=mocker.PropertyMock, - return_value=1, - ) - - src = MockSource(streams=[stream_1, stream_2]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(stream_1, SyncMode.incremental), - _configured_stream(stream_2, SyncMode.incremental), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_stream_status("s1", AirbyteStreamStatus.RUNNING), - _as_record("s1", stream_output[0]), - _as_state("s1", state), - _as_record("s1", stream_output[1]), - _as_state("s1", state), - _as_state("s1", state), - _as_stream_status("s1", AirbyteStreamStatus.COMPLETE), - _as_stream_status("s2", AirbyteStreamStatus.STARTED), - _as_stream_status("s2", AirbyteStreamStatus.RUNNING), - _as_record("s2", stream_output[0]), - _as_state("s2", state), - _as_record("s2", stream_output[1]), - _as_state("s2", state), - _as_state("s2", state), - _as_stream_status("s2", AirbyteStreamStatus.COMPLETE), - ] - ) - messages = _fix_emitted_at(list(src.read(logger, {}, catalog, state=input_state))) - - assert messages == expected - - def test_with_no_interval(self, mocker): - """Tests that an incremental read which doesn't specify a checkpoint interval outputs - a STATE message only after fully reading the stream and does not output any STATE messages during syncing the stream. - """ - input_state = [] - stream_output = [{"k1": "v1"}, {"k2": "v2"}] - - stream_1 = MockStream( - [({"sync_mode": SyncMode.incremental, "stream_slice": {}, "stream_state": {}}, stream_output)], - name="s1", - ) - stream_2 = MockStream( - [({"sync_mode": SyncMode.incremental, "stream_slice": {}, "stream_state": {}}, stream_output)], - name="s2", - ) - state = {"cursor": "value"} - mocker.patch.object(MockStream, "get_updated_state", return_value=state) - mocker.patch.object(MockStream, "supports_incremental", return_value=True) - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - - src = MockSource(streams=[stream_1, stream_2]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(stream_1, SyncMode.incremental), - _configured_stream(stream_2, SyncMode.incremental), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_stream_status("s1", AirbyteStreamStatus.RUNNING), - *_as_records("s1", stream_output), - _as_state("s1", state), - _as_stream_status("s1", AirbyteStreamStatus.COMPLETE), - _as_stream_status("s2", AirbyteStreamStatus.STARTED), - _as_stream_status("s2", AirbyteStreamStatus.RUNNING), - *_as_records("s2", stream_output), - _as_state("s2", state), - _as_stream_status("s2", AirbyteStreamStatus.COMPLETE), - ] - ) - - messages = _fix_emitted_at(list(src.read(logger, {}, catalog, state=input_state))) - - assert messages == expected - - def test_with_slices(self, mocker): - """Tests that an incremental read which uses slices outputs each record in the slice followed by a STATE message, for each slice""" - input_state = [] - slices = [{"1": "1"}, {"2": "2"}] - stream_output = [{"k1": "v1"}, {"k2": "v2"}, {"k3": "v3"}] - - stream_1 = MockStream( - [ - ( - { - "sync_mode": SyncMode.incremental, - "stream_slice": s, - "stream_state": mocker.ANY, - }, - stream_output, - ) - for s in slices - ], - name="s1", - ) - stream_2 = MockStream( - [ - ( - { - "sync_mode": SyncMode.incremental, - "stream_slice": s, - "stream_state": mocker.ANY, - }, - stream_output, - ) - for s in slices - ], - name="s2", - ) - state = {"cursor": "value"} - mocker.patch.object(MockStream, "get_updated_state", return_value=state) - mocker.patch.object(MockStream, "supports_incremental", return_value=True) - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - mocker.patch.object(MockStream, "stream_slices", return_value=slices) - - src = MockSource(streams=[stream_1, stream_2]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(stream_1, SyncMode.incremental), - _configured_stream(stream_2, SyncMode.incremental), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_stream_status("s1", AirbyteStreamStatus.RUNNING), - # stream 1 slice 1 - *_as_records("s1", stream_output), - _as_state("s1", state), - # stream 1 slice 2 - *_as_records("s1", stream_output), - _as_state("s1", state), - _as_stream_status("s1", AirbyteStreamStatus.COMPLETE), - _as_stream_status("s2", AirbyteStreamStatus.STARTED), - _as_stream_status("s2", AirbyteStreamStatus.RUNNING), - # stream 2 slice 1 - *_as_records("s2", stream_output), - _as_state("s2", state), - # stream 2 slice 2 - *_as_records("s2", stream_output), - _as_state("s2", state), - _as_stream_status("s2", AirbyteStreamStatus.COMPLETE), - ] - ) - - messages = _fix_emitted_at(list(src.read(logger, {}, catalog, state=input_state))) - - assert messages == expected - - @pytest.mark.parametrize("slices", [pytest.param([], id="test_slices_as_list"), pytest.param(iter([]), id="test_slices_as_iterator")]) - def test_no_slices(self, mocker, slices): - """ - Tests that an incremental read returns at least one state messages even if no records were read: - 1. outputs a state message after reading the entire stream - """ - state = {"cursor": "value"} - input_state = [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState(stream_descriptor=StreamDescriptor(name="s1"), stream_state=AirbyteStateBlob(state)), - ), - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState(stream_descriptor=StreamDescriptor(name="s2"), stream_state=AirbyteStateBlob(state)), - ), - ] - - stream_output = [{"k1": "v1"}, {"k2": "v2"}, {"k3": "v3"}] - stream_1 = MockStreamWithState( - [ - ( - { - "sync_mode": SyncMode.incremental, - "stream_slice": s, - "stream_state": mocker.ANY, - }, - stream_output, - ) - for s in slices - ], - name="s1", - state=state, - ) - stream_2 = MockStreamWithState( - [ - ( - { - "sync_mode": SyncMode.incremental, - "stream_slice": s, - "stream_state": mocker.ANY, - }, - stream_output, - ) - for s in slices - ], - name="s2", - state=state, - ) - - mocker.patch.object(MockStreamWithState, "supports_incremental", return_value=True) - mocker.patch.object(MockStreamWithState, "get_json_schema", return_value={}) - mocker.patch.object(MockStreamWithState, "stream_slices", return_value=slices) - mocker.patch.object( - MockStreamWithState, - "state_checkpoint_interval", - new_callable=mocker.PropertyMock, - return_value=2, - ) - - src = MockSource(streams=[stream_1, stream_2]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(stream_1, SyncMode.incremental), - _configured_stream(stream_2, SyncMode.incremental), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_state("s1", state), - _as_stream_status("s1", AirbyteStreamStatus.COMPLETE), - _as_stream_status("s2", AirbyteStreamStatus.STARTED), - _as_state("s2", state), - _as_stream_status("s2", AirbyteStreamStatus.COMPLETE), - ] - ) - - messages = _fix_emitted_at(list(src.read(logger, {}, catalog, state=input_state))) - - assert messages == expected - - def test_with_slices_and_interval(self, mocker): - """ - Tests that an incremental read which uses slices and a checkpoint interval: - 1. outputs all records - 2. outputs a state message every N records (N=checkpoint_interval) - 3. outputs a state message after reading the entire slice - """ - input_state = [] - slices = [{"1": "1"}, {"2": "2"}] - stream_output = [{"k1": "v1"}, {"k2": "v2"}, {"k3": "v3"}] - stream_1 = MockStream( - [ - ( - { - "sync_mode": SyncMode.incremental, - "stream_slice": s, - "stream_state": mocker.ANY, - }, - stream_output, - ) - for s in slices - ], - name="s1", - ) - stream_2 = MockStream( - [ - ( - { - "sync_mode": SyncMode.incremental, - "stream_slice": s, - "stream_state": mocker.ANY, - }, - stream_output, - ) - for s in slices - ], - name="s2", - ) - state = {"cursor": "value"} - mocker.patch.object(MockStream, "get_updated_state", return_value=state) - mocker.patch.object(MockStream, "supports_incremental", return_value=True) - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - mocker.patch.object(MockStream, "stream_slices", return_value=slices) - mocker.patch.object( - MockStream, - "state_checkpoint_interval", - new_callable=mocker.PropertyMock, - return_value=2, - ) - - src = MockSource(streams=[stream_1, stream_2]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(stream_1, SyncMode.incremental), - _configured_stream(stream_2, SyncMode.incremental), - ] - ) - - expected = _fix_emitted_at( - [ - # stream 1 slice 1 - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_stream_status("s1", AirbyteStreamStatus.RUNNING), - _as_record("s1", stream_output[0]), - _as_record("s1", stream_output[1]), - _as_state("s1", state), - _as_record("s1", stream_output[2]), - _as_state("s1", state), - # stream 1 slice 2 - _as_record("s1", stream_output[0]), - _as_state("s1", state), - _as_record("s1", stream_output[1]), - _as_record("s1", stream_output[2]), - _as_state("s1", state), - _as_state("s1", state), - _as_stream_status("s1", AirbyteStreamStatus.COMPLETE), - # stream 2 slice 1 - _as_stream_status("s2", AirbyteStreamStatus.STARTED), - _as_stream_status("s2", AirbyteStreamStatus.RUNNING), - _as_record("s2", stream_output[0]), - _as_record("s2", stream_output[1]), - _as_state("s2", state), - _as_record("s2", stream_output[2]), - _as_state("s2", state), - # stream 2 slice 2 - _as_record("s2", stream_output[0]), - _as_state("s2", state), - _as_record("s2", stream_output[1]), - _as_record("s2", stream_output[2]), - _as_state("s2", state), - _as_state("s2", state), - _as_stream_status("s2", AirbyteStreamStatus.COMPLETE), - ] - ) - - messages = _fix_emitted_at(list(src.read(logger, {}, catalog, state=input_state))) - - assert messages == expected - - def test_emit_non_records(self, mocker): - """ - Tests that an incremental read which uses slices and a checkpoint interval: - 1. outputs all records - 2. outputs a state message every N records (N=checkpoint_interval) - 3. outputs a state message after reading the entire slice - """ - - input_state = [] - slices = [{"1": "1"}, {"2": "2"}] - stream_output = [ - {"k1": "v1"}, - AirbyteLogMessage(level=Level.INFO, message="HELLO"), - {"k2": "v2"}, - {"k3": "v3"}, - ] - stream_1 = MockStreamEmittingAirbyteMessages( - [ - ( - { - "sync_mode": SyncMode.incremental, - "stream_slice": s, - "stream_state": mocker.ANY, - }, - stream_output, - ) - for s in slices - ], - name="s1", - state=copy.deepcopy(input_state), - ) - stream_2 = MockStreamEmittingAirbyteMessages( - [ - ( - { - "sync_mode": SyncMode.incremental, - "stream_slice": s, - "stream_state": mocker.ANY, - }, - stream_output, - ) - for s in slices - ], - name="s2", - state=copy.deepcopy(input_state), - ) - - state = {"cursor": "value"} - getter_mock = Mock(wraps=MockStreamEmittingAirbyteMessages.state.fget) - getter_mock.return_value = state - mock_get_property = MockStreamEmittingAirbyteMessages.state.getter(getter_mock) - mocker.patch.object( - MockStreamEmittingAirbyteMessages, - "state", - mock_get_property, - ) - - mocker.patch.object(MockStreamWithState, "supports_incremental", return_value=True) - mocker.patch.object(MockStreamWithState, "get_json_schema", return_value={}) - mocker.patch.object(MockStreamWithState, "stream_slices", return_value=slices) - mocker.patch.object( - MockStreamWithState, - "state_checkpoint_interval", - new_callable=mocker.PropertyMock, - return_value=2, - ) - - src = MockSource(streams=[stream_1, stream_2]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(stream_1, SyncMode.incremental), - _configured_stream(stream_2, SyncMode.incremental), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_stream_status("s1", AirbyteStreamStatus.RUNNING), - # stream 1 slice 1 - stream_data_to_airbyte_message("s1", stream_output[0]), - stream_data_to_airbyte_message("s1", stream_output[1]), - stream_data_to_airbyte_message("s1", stream_output[2]), - _as_state("s1", state), - stream_data_to_airbyte_message("s1", stream_output[3]), - _as_state("s1", state), - # stream 1 slice 2 - stream_data_to_airbyte_message("s1", stream_output[0]), - _as_state("s1", state), - stream_data_to_airbyte_message("s1", stream_output[1]), - stream_data_to_airbyte_message("s1", stream_output[2]), - stream_data_to_airbyte_message("s1", stream_output[3]), - _as_state("s1", state), - _as_state("s1", state), - _as_stream_status("s1", AirbyteStreamStatus.COMPLETE), - # stream 2 slice 1 - _as_stream_status("s2", AirbyteStreamStatus.STARTED), - _as_stream_status("s2", AirbyteStreamStatus.RUNNING), - stream_data_to_airbyte_message("s2", stream_output[0]), - stream_data_to_airbyte_message("s2", stream_output[1]), - stream_data_to_airbyte_message("s2", stream_output[2]), - _as_state("s2", state), - stream_data_to_airbyte_message("s2", stream_output[3]), - _as_state("s2", state), - # stream 2 slice 2 - stream_data_to_airbyte_message("s2", stream_output[0]), - _as_state("s2", state), - stream_data_to_airbyte_message("s2", stream_output[1]), - stream_data_to_airbyte_message("s2", stream_output[2]), - stream_data_to_airbyte_message("s2", stream_output[3]), - _as_state("s2", state), - _as_state("s2", state), - _as_stream_status("s2", AirbyteStreamStatus.COMPLETE), - ] - ) - - messages = _fix_emitted_at(list(src.read(logger, {}, catalog, state=input_state))) - - assert messages == expected - - def test_without_state_attribute_for_stream_with_desc_records(self, mocker): - """ - This test will check that the state resolved by get_updated_state is used and returned in the state message. - In this scenario records are returned in descending order, but we keep the "highest" cursor in the state. - """ - stream_cursor = MockStreamWithCursor.cursor_field - stream_output = [{f"k{cursor_id}": f"v{cursor_id}", stream_cursor: cursor_id} for cursor_id in range(5, 1, -1)] - initial_state = {stream_cursor: 1} - stream_name = "stream_with_cursor" - input_state = [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name=stream_name), stream_state=AirbyteStateBlob(initial_state) - ), - ), - ] - stream_with_cursor = MockStreamWithCursor( - [({"sync_mode": SyncMode.incremental, "stream_slice": {}, "stream_state": initial_state}, stream_output)], - name=stream_name, - ) - - def mock_get_updated_state(current_stream, current_stream_state, latest_record): - state_cursor_value = current_stream_state.get(current_stream.cursor_field, 0) - latest_record_value = latest_record.get(current_stream.cursor_field) - return {current_stream.cursor_field: max(latest_record_value, state_cursor_value)} - - mocker.patch.object(MockStreamWithCursor, "get_updated_state", mock_get_updated_state) - mocker.patch.object(MockStreamWithCursor, "get_json_schema", return_value={}) - src = MockSource(streams=[stream_with_cursor]) - - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(stream_with_cursor, SyncMode.incremental), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status(stream_name, AirbyteStreamStatus.STARTED), - _as_stream_status(stream_name, AirbyteStreamStatus.RUNNING), - _as_record(stream_name, stream_output[0]), - _as_record(stream_name, stream_output[1]), - _as_record(stream_name, stream_output[2]), - _as_record(stream_name, stream_output[3]), - _as_state(stream_name, {stream_cursor: stream_output[0][stream_cursor]}), - _as_stream_status(stream_name, AirbyteStreamStatus.COMPLETE), - ] - ) - messages = _fix_emitted_at(list(src.read(logger, {}, catalog, state=input_state))) - assert messages - assert messages == expected - - -class TestResumableFullRefreshRead: - def test_resumable_full_refresh_multiple_pages(self, mocker): - """Tests that running a resumable full refresh sync from the first attempt with no prior state""" - responses = [ - {"records": [{"1": "1"}, {"2": "2"}], "next_page": {"page": 1}}, - {"records": [{"3": "3"}, {"4": "4"}], "next_page": {"page": 2}}, - {"records": [{"3": "3"}, {"4": "4"}]}, - ] - # When attempting to sync a slice, just output that slice as a record - - # We've actually removed this filtering logic and will rely on the platform to dicate whether to pass state to the connector - # So in reality we can probably get rid of this test entirely - s1 = MockResumableFullRefreshStream( - [ - ({"stream_state": {}, "sync_mode": SyncMode.full_refresh, "stream_slice": {}}, responses[0]), - ({"stream_state": {}, "sync_mode": SyncMode.full_refresh, "stream_slice": {"page": 1}}, responses[1]), - ({"stream_state": {}, "sync_mode": SyncMode.full_refresh, "stream_slice": {"page": 2}}, responses[2]), - ], - name="s1", - ) - - mocker.patch.object(MockResumableFullRefreshStream, "get_json_schema", return_value={}) - - src = MockSource(streams=[s1]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(s1, SyncMode.full_refresh), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_stream_status("s1", AirbyteStreamStatus.RUNNING), - *_as_records("s1", responses[0]["records"]), - _as_state("s1", {"page": 1}), - *_as_records("s1", responses[1]["records"]), - _as_state("s1", {"page": 2}), - *_as_records("s1", responses[2]["records"]), - _as_state("s1", {"__ab_full_refresh_sync_complete": True}), - _as_state("s1", {"__ab_full_refresh_sync_complete": True}), - _as_stream_status("s1", AirbyteStreamStatus.COMPLETE), - ] - ) - - messages = _fix_emitted_at(list(src.read(logger, {}, catalog))) - - assert messages == expected - - def test_resumable_full_refresh_with_incoming_state(self, mocker): - """Tests that running a resumable full refresh sync from the second attempt with partial state passed in""" - responses = [ - {"records": [{"100": "100"}, {"200": "200"}], "next_page": {"page": 11}}, - {"records": [{"300": "300"}, {"400": "400"}], "next_page": {"page": 12}}, - {"records": [{"500": "500"}, {"600": "600"}], "next_page": {"page": 13}}, - {"records": [{"700": "700"}, {"800": "800"}]}, - ] - # When attempting to sync a slice, just output that slice as a record - - # We've actually removed this filtering logic and will rely on the platform to dicate whether to pass state to the connector - # So in reality we can probably get rid of this test entirely - s1 = MockResumableFullRefreshStream( - [ - ({"stream_state": {"page": 10}, "sync_mode": SyncMode.full_refresh, "stream_slice": {"page": 10}}, responses[0]), - ({"stream_state": {"page": 10}, "sync_mode": SyncMode.full_refresh, "stream_slice": {"page": 11}}, responses[1]), - ({"stream_state": {"page": 10}, "sync_mode": SyncMode.full_refresh, "stream_slice": {"page": 12}}, responses[2]), - ({"stream_state": {"page": 10}, "sync_mode": SyncMode.full_refresh, "stream_slice": {"page": 13}}, responses[3]), - ], - name="s1", - ) - - mocker.patch.object(MockResumableFullRefreshStream, "get_json_schema", return_value={}) - - state = [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="s1"), - stream_state=AirbyteStateBlob({"page": 10}), - ), - ) - ] - - src = MockSource(streams=[s1]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(s1, SyncMode.full_refresh), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_stream_status("s1", AirbyteStreamStatus.RUNNING), - *_as_records("s1", responses[0]["records"]), - _as_state("s1", {"page": 11}), - *_as_records("s1", responses[1]["records"]), - _as_state("s1", {"page": 12}), - *_as_records("s1", responses[2]["records"]), - _as_state("s1", {"page": 13}), - *_as_records("s1", responses[3]["records"]), - _as_state("s1", {"__ab_full_refresh_sync_complete": True}), - _as_state("s1", {"__ab_full_refresh_sync_complete": True}), - _as_stream_status("s1", AirbyteStreamStatus.COMPLETE), - ] - ) - - messages = _fix_emitted_at(list(src.read(logger, {}, catalog, state))) - - assert messages == expected - - def test_resumable_full_refresh_partial_failure(self, mocker): - """Tests that running a resumable full refresh sync from the first attempt that fails before completing successfully""" - expected_error_message = "I have failed you Anakin." - responses = [ - {"records": [{"1": "1"}, {"2": "2"}], "next_page": {"page": 1}}, - {"records": [{"3": "3"}, {"4": "4"}], "next_page": {"page": 2}}, - {"error": expected_error_message}, - ] - # When attempting to sync a slice, just output that slice as a record - - # We've actually removed this filtering logic and will rely on the platform to dicate whether to pass state to the connector - # So in reality we can probably get rid of this test entirely - s1 = MockResumableFullRefreshStream( - [ - ({"stream_state": {}, "sync_mode": SyncMode.full_refresh, "stream_slice": {}}, responses[0]), - ({"stream_state": {}, "sync_mode": SyncMode.full_refresh, "stream_slice": {"page": 1}}, responses[1]), - ({"stream_state": {}, "sync_mode": SyncMode.full_refresh, "stream_slice": {"page": 2}}, responses[2]), - ], - name="s1", - ) - - mocker.patch.object(MockResumableFullRefreshStream, "get_json_schema", return_value={}) - - src = MockSource(streams=[s1]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(s1, SyncMode.full_refresh), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_stream_status("s1", AirbyteStreamStatus.RUNNING), - *_as_records("s1", responses[0]["records"]), - _as_state("s1", {"page": 1}), - *_as_records("s1", responses[1]["records"]), - _as_state("s1", {"page": 2}), - _as_stream_status("s1", AirbyteStreamStatus.INCOMPLETE), - _as_error_trace("s1", expected_error_message, None, FailureType.system_error, None), - ] - ) - - messages = [] - with pytest.raises(AirbyteTracedException) as exc: - for message in src.read(logger, {}, catalog): - messages.append(_remove_stack_trace(message)) - - assert _fix_emitted_at(messages) == expected - assert "s1" in exc.value.message - assert exc.value.failure_type == FailureType.config_error - - def test_resumable_full_refresh_skip_prior_successful_streams(self, mocker): - """ - Tests that running a resumable full refresh sync from the second attempt where one stream was successful - and should not be synced. The other should sync beginning at the partial state passed in. - """ - responses = [ - {"records": [{"100": "100"}, {"200": "200"}], "next_page": {"page": 11}}, - {"records": [{"300": "300"}, {"400": "400"}], "next_page": {"page": 12}}, - {"records": [{"500": "500"}, {"600": "600"}], "next_page": {"page": 13}}, - {"records": [{"700": "700"}, {"800": "800"}]}, - ] - # When attempting to sync a slice, just output that slice as a record - - # We've actually removed this filtering logic and will rely on the platform to dicate whether to pass state to the connector - # So in reality we can probably get rid of this test entirely - s1 = MockResumableFullRefreshStream( - [ - ({"stream_state": {"page": 10}, "sync_mode": SyncMode.full_refresh, "stream_slice": {"page": 10}}, responses[0]), - ({"stream_state": {"page": 10}, "sync_mode": SyncMode.full_refresh, "stream_slice": {"page": 11}}, responses[1]), - ({"stream_state": {"page": 10}, "sync_mode": SyncMode.full_refresh, "stream_slice": {"page": 12}}, responses[2]), - ({"stream_state": {"page": 10}, "sync_mode": SyncMode.full_refresh, "stream_slice": {"page": 13}}, responses[3]), - ], - name="s1", - ) - - s2 = MockResumableFullRefreshStream( - [ - ({"stream_state": {"page": 10}, "sync_mode": SyncMode.full_refresh, "stream_slice": {"page": 10}}, responses[0]), - ({"stream_state": {"page": 10}, "sync_mode": SyncMode.full_refresh, "stream_slice": {"page": 11}}, responses[1]), - ({"stream_state": {"page": 10}, "sync_mode": SyncMode.full_refresh, "stream_slice": {"page": 12}}, responses[2]), - ({"stream_state": {"page": 10}, "sync_mode": SyncMode.full_refresh, "stream_slice": {"page": 13}}, responses[3]), - ], - name="s2", - ) - - mocker.patch.object(MockResumableFullRefreshStream, "get_json_schema", return_value={}) - - state = [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="s1"), - stream_state=AirbyteStateBlob({"__ab_full_refresh_sync_complete": True}), - ), - ), - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="s2"), - stream_state=AirbyteStateBlob({"page": 10}), - ), - ), - ] - - src = MockSource(streams=[s1, s2]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(s1, SyncMode.full_refresh), - _configured_stream(s2, SyncMode.full_refresh), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_state("s1", {"__ab_full_refresh_sync_complete": True}), - _as_stream_status("s1", AirbyteStreamStatus.COMPLETE), - _as_stream_status("s2", AirbyteStreamStatus.STARTED), - _as_stream_status("s2", AirbyteStreamStatus.RUNNING), - *_as_records("s2", responses[0]["records"]), - _as_state("s2", {"page": 11}), - *_as_records("s2", responses[1]["records"]), - _as_state("s2", {"page": 12}), - *_as_records("s2", responses[2]["records"]), - _as_state("s2", {"page": 13}), - *_as_records("s2", responses[3]["records"]), - _as_state("s2", {"__ab_full_refresh_sync_complete": True}), - _as_state("s2", {"__ab_full_refresh_sync_complete": True}), - _as_stream_status("s2", AirbyteStreamStatus.COMPLETE), - ] - ) - - messages = _fix_emitted_at(list(src.read(logger, {}, catalog, state))) - - assert messages == expected - - -@pytest.mark.parametrize( - "exception_to_raise,expected_error_message,expected_internal_message", - [ - pytest.param( - AirbyteTracedException(message="I was born only to crash like Icarus"), - "I was born only to crash like Icarus", - None, - id="test_raises_traced_exception", - ), - pytest.param( - Exception("Generic connector error message"), - "Something went wrong in the connector. See the logs for more details.", - "Generic connector error message", - id="test_raises_generic_exception", - ), - ], -) -def test_continue_sync_with_failed_streams(mocker, exception_to_raise, expected_error_message, expected_internal_message): - """ - Tests that running a sync for a connector with multiple streams will continue syncing when one stream fails - with an error. This source does not override the default behavior defined in the AbstractSource class. - """ - stream_output = [{"k1": "v1"}, {"k2": "v2"}] - s1 = MockStream([({"sync_mode": SyncMode.full_refresh}, stream_output)], name="s1") - s2 = StreamRaisesException(exception_to_raise=exception_to_raise) - s3 = MockStream([({"sync_mode": SyncMode.full_refresh}, stream_output)], name="s3") - - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - mocker.patch.object(StreamRaisesException, "get_json_schema", return_value={}) - - src = MockSource(streams=[s1, s2, s3]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(s1, SyncMode.full_refresh), - _configured_stream(s2, SyncMode.full_refresh), - _configured_stream(s3, SyncMode.full_refresh), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_stream_status("s1", AirbyteStreamStatus.RUNNING), - *_as_records("s1", stream_output), - _as_stream_status("s1", AirbyteStreamStatus.COMPLETE), - _as_stream_status("lamentations", AirbyteStreamStatus.STARTED), - _as_stream_status("lamentations", AirbyteStreamStatus.INCOMPLETE), - _as_error_trace("lamentations", expected_error_message, expected_internal_message, FailureType.system_error, None), - _as_stream_status("s3", AirbyteStreamStatus.STARTED), - _as_stream_status("s3", AirbyteStreamStatus.RUNNING), - *_as_records("s3", stream_output), - _as_stream_status("s3", AirbyteStreamStatus.COMPLETE), - ] - ) - - with pytest.raises(AirbyteTracedException) as exc: - messages = [_remove_stack_trace(message) for message in src.read(logger, {}, catalog)] - messages = _fix_emitted_at(messages) - - assert messages == expected - - assert "lamentations" in exc.value.message - assert exc.value.failure_type == FailureType.config_error - - -def test_continue_sync_source_override_false(mocker): - """ - Tests that running a sync for a connector explicitly overriding the default AbstractSource.stop_sync_on_stream_failure - property to be False which will continue syncing stream even if one encountered an exception. - """ - update_secrets(["API_KEY_VALUE"]) - - stream_output = [{"k1": "v1"}, {"k2": "v2"}] - s1 = MockStream([({"sync_mode": SyncMode.full_refresh}, stream_output)], name="s1") - s2 = StreamRaisesException(exception_to_raise=AirbyteTracedException(message="I was born only to crash like Icarus")) - s3 = MockStream([({"sync_mode": SyncMode.full_refresh}, stream_output)], name="s3") - - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - mocker.patch.object(StreamRaisesException, "get_json_schema", return_value={}) - - src = MockSourceWithStopSyncFalseOverride(streams=[s1, s2, s3]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(s1, SyncMode.full_refresh), - _configured_stream(s2, SyncMode.full_refresh), - _configured_stream(s3, SyncMode.full_refresh), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_stream_status("s1", AirbyteStreamStatus.RUNNING), - *_as_records("s1", stream_output), - _as_stream_status("s1", AirbyteStreamStatus.COMPLETE), - _as_stream_status("lamentations", AirbyteStreamStatus.STARTED), - _as_stream_status("lamentations", AirbyteStreamStatus.INCOMPLETE), - _as_error_trace("lamentations", "I was born only to crash like Icarus", None, FailureType.system_error, None), - _as_stream_status("s3", AirbyteStreamStatus.STARTED), - _as_stream_status("s3", AirbyteStreamStatus.RUNNING), - *_as_records("s3", stream_output), - _as_stream_status("s3", AirbyteStreamStatus.COMPLETE), - ] - ) - - with pytest.raises(AirbyteTracedException) as exc: - messages = [_remove_stack_trace(message) for message in src.read(logger, {}, catalog)] - messages = _fix_emitted_at(messages) - - assert messages == expected - - assert "lamentations" in exc.value.message - assert exc.value.failure_type == FailureType.config_error - - -def test_sync_error_trace_messages_obfuscate_secrets(mocker): - """ - Tests that exceptions emitted as trace messages by a source have secrets properly sanitized - """ - update_secrets(["API_KEY_VALUE"]) - - stream_output = [{"k1": "v1"}, {"k2": "v2"}] - s1 = MockStream([({"sync_mode": SyncMode.full_refresh}, stream_output)], name="s1") - s2 = StreamRaisesException( - exception_to_raise=AirbyteTracedException(message="My api_key value API_KEY_VALUE flew too close to the sun.") - ) - s3 = MockStream([({"sync_mode": SyncMode.full_refresh}, stream_output)], name="s3") - - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - mocker.patch.object(StreamRaisesException, "get_json_schema", return_value={}) - - src = MockSource(streams=[s1, s2, s3]) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(s1, SyncMode.full_refresh), - _configured_stream(s2, SyncMode.full_refresh), - _configured_stream(s3, SyncMode.full_refresh), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_stream_status("s1", AirbyteStreamStatus.RUNNING), - *_as_records("s1", stream_output), - _as_stream_status("s1", AirbyteStreamStatus.COMPLETE), - _as_stream_status("lamentations", AirbyteStreamStatus.STARTED), - _as_stream_status("lamentations", AirbyteStreamStatus.INCOMPLETE), - _as_error_trace("lamentations", "My api_key value **** flew too close to the sun.", None, FailureType.system_error, None), - _as_stream_status("s3", AirbyteStreamStatus.STARTED), - _as_stream_status("s3", AirbyteStreamStatus.RUNNING), - *_as_records("s3", stream_output), - _as_stream_status("s3", AirbyteStreamStatus.COMPLETE), - ] - ) - - with pytest.raises(AirbyteTracedException) as exc: - messages = [_remove_stack_trace(message) for message in src.read(logger, {}, catalog)] - messages = _fix_emitted_at(messages) - - assert messages == expected - - assert "lamentations" in exc.value.message - assert exc.value.failure_type == FailureType.config_error - - -def test_continue_sync_with_failed_streams_with_override_false(mocker): - """ - Tests that running a sync for a connector with multiple streams and stop_sync_on_stream_failure enabled stops - the sync when one stream fails with an error. - """ - stream_output = [{"k1": "v1"}, {"k2": "v2"}] - s1 = MockStream([({"stream_state": {}, "stream_slice": {}, "sync_mode": SyncMode.full_refresh}, stream_output)], name="s1") - s2 = StreamRaisesException(AirbyteTracedException(message="I was born only to crash like Icarus")) - s3 = MockStream([({"stream_state": {}, "stream_slice": {}, "sync_mode": SyncMode.full_refresh}, stream_output)], name="s3") - - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - mocker.patch.object(StreamRaisesException, "get_json_schema", return_value={}) - - src = MockSource(streams=[s1, s2, s3]) - mocker.patch.object(MockSource, "stop_sync_on_stream_failure", return_value=True) - catalog = ConfiguredAirbyteCatalog( - streams=[ - _configured_stream(s1, SyncMode.full_refresh), - _configured_stream(s2, SyncMode.full_refresh), - _configured_stream(s3, SyncMode.full_refresh), - ] - ) - - expected = _fix_emitted_at( - [ - _as_stream_status("s1", AirbyteStreamStatus.STARTED), - _as_stream_status("s1", AirbyteStreamStatus.RUNNING), - *_as_records("s1", stream_output), - _as_stream_status("s1", AirbyteStreamStatus.COMPLETE), - _as_stream_status("lamentations", AirbyteStreamStatus.STARTED), - _as_stream_status("lamentations", AirbyteStreamStatus.INCOMPLETE), - _as_error_trace("lamentations", "I was born only to crash like Icarus", None, FailureType.system_error, None), - ] - ) - - with pytest.raises(AirbyteTracedException) as exc: - messages = [_remove_stack_trace(message) for message in src.read(logger, {}, catalog)] - messages = _fix_emitted_at(messages) - - assert messages == expected - - assert "lamentations" in exc.value.message - assert exc.value.failure_type == FailureType.config_error - - -# TODO: Replace call of this function to fixture in the tests -def _remove_stack_trace(message: AirbyteMessage) -> AirbyteMessage: - """ - Helper method that removes the stack trace from Airbyte trace messages to make asserting against expected records easier - """ - if message.trace and message.trace.error and message.trace.error.stack_trace: - message.trace.error.stack_trace = None - return message - - -def test_read_nonexistent_stream_emit_incomplete_stream_status(mocker, remove_stack_trace, as_stream_status): - """ - Tests that attempting to sync a stream which the source does not return from the `streams` method emit incomplete stream status - """ - s1 = MockStream(name="s1") - s2 = MockStream(name="this_stream_doesnt_exist_in_the_source") - - mocker.patch.object(MockStream, "get_json_schema", return_value={}) - - src = MockSource(streams=[s1]) - catalog = ConfiguredAirbyteCatalog(streams=[_configured_stream(s2, SyncMode.full_refresh)]) - - expected = _fix_emitted_at([as_stream_status("this_stream_doesnt_exist_in_the_source", AirbyteStreamStatus.INCOMPLETE)]) - - expected_error_message = ( - "The stream 'this_stream_doesnt_exist_in_the_source' in your connection configuration was not found in the " - "source. Refresh the schema in your replication settings and remove this stream from future sync attempts." - ) - - with pytest.raises(AirbyteTracedException) as exc_info: - messages = [remove_stack_trace(message) for message in src.read(logger, {}, catalog)] - messages = _fix_emitted_at(messages) - - assert messages == expected - - assert expected_error_message in exc_info.value.message - assert exc_info.value.failure_type == FailureType.config_error diff --git a/airbyte-cdk/python/unit_tests/sources/test_config.py b/airbyte-cdk/python/unit_tests/sources/test_config.py deleted file mode 100644 index 8cac7992a671..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/test_config.py +++ /dev/null @@ -1,92 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import List, Union - -from airbyte_cdk.sources.config import BaseConfig -from pydantic.v1 import BaseModel, Field - - -class InnerClass(BaseModel): - field1: str - field2: int - - -class Choice1(BaseModel): - selected_strategy = Field("option1", const=True) - - name: str - count: int - - -class Choice2(BaseModel): - selected_strategy = Field("option2", const=True) - - sequence: List[str] - - -class SomeSourceConfig(BaseConfig): - class Config: - title = "Some Source" - - items: List[InnerClass] - choice: Union[Choice1, Choice2] - - -class TestBaseConfig: - EXPECTED_SCHEMA = { - "properties": { - "choice": { - "oneOf": [ - { - "properties": { - "count": {"title": "Count", "type": "integer"}, - "name": {"title": "Name", "type": "string"}, - "selected_strategy": { - "const": "option1", - "title": "Selected " "Strategy", - "type": "string", - "default": "option1", - }, - }, - "required": ["name", "count"], - "title": "Choice1", - "type": "object", - }, - { - "properties": { - "selected_strategy": { - "const": "option2", - "title": "Selected " "Strategy", - "type": "string", - "default": "option2", - }, - "sequence": {"items": {"type": "string"}, "title": "Sequence", "type": "array"}, - }, - "required": ["sequence"], - "title": "Choice2", - "type": "object", - }, - ], - "title": "Choice", - }, - "items": { - "items": { - "properties": {"field1": {"title": "Field1", "type": "string"}, "field2": {"title": "Field2", "type": "integer"}}, - "required": ["field1", "field2"], - "title": "InnerClass", - "type": "object", - }, - "title": "Items", - "type": "array", - }, - }, - "required": ["items", "choice"], - "title": "Some Source", - "type": "object", - } - - def test_schema_postprocessing(self): - schema = SomeSourceConfig.schema() - assert schema == self.EXPECTED_SCHEMA diff --git a/airbyte-cdk/python/unit_tests/sources/test_connector_state_manager.py b/airbyte-cdk/python/unit_tests/sources/test_connector_state_manager.py deleted file mode 100644 index 1a5526b105d5..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/test_connector_state_manager.py +++ /dev/null @@ -1,430 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from contextlib import nullcontext as does_not_raise -from typing import List - -import pytest -from airbyte_cdk.models import ( - AirbyteMessage, - AirbyteStateBlob, - AirbyteStateMessage, - AirbyteStateMessageSerializer, - AirbyteStateType, - AirbyteStreamState, - StreamDescriptor, -) -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager, HashableStreamDescriptor - - -@pytest.mark.parametrize( - "input_stream_state, expected_stream_state, expected_error", - ( - pytest.param( - [ - { - "type": "STREAM", - "stream": {"stream_descriptor": {"name": "actors", "namespace": "public"}, "stream_state": {"id": "mando_michael"}}, - }, - { - "type": "STREAM", - "stream": {"stream_descriptor": {"name": "actresses", "namespace": "public"}, "stream_state": {"id": "seehorn_rhea"}}, - }, - ], - { - HashableStreamDescriptor(name="actors", namespace="public"): AirbyteStateBlob({"id": "mando_michael"}), - HashableStreamDescriptor(name="actresses", namespace="public"): AirbyteStateBlob({"id": "seehorn_rhea"}), - }, - does_not_raise(), - id="test_incoming_per_stream_state", - ), - pytest.param([], {}, does_not_raise(), id="test_incoming_empty_stream_state"), - pytest.param( - [{"type": "STREAM", "stream": {"stream_descriptor": {"name": "actresses", "namespace": "public"}}}], - {HashableStreamDescriptor(name="actresses", namespace="public"): None}, - does_not_raise(), - id="test_stream_states_that_have_none_state_blob", - ), - pytest.param( - [ - { - "type": "GLOBAL", - "global": { - "shared_state": {"television": "better_call_saul"}, - "stream_states": [ - { - "stream_descriptor": {"name": "actors", "namespace": "public"}, - "stream_state": {"id": "mando_michael"}, - }, - { - "stream_descriptor": {"name": "actresses", "namespace": "public"}, - "stream_state": {"id": "seehorn_rhea"}, - }, - ], - }, - }, - ], - { - HashableStreamDescriptor(name="actors", namespace="public"): AirbyteStateBlob({"id": "mando_michael"}), - HashableStreamDescriptor(name="actresses", namespace="public"): AirbyteStateBlob({"id": "seehorn_rhea"}), - }, - pytest.raises(ValueError), - id="test_incoming_global_state_with_shared_state_throws_error", - ), - pytest.param( - [ - { - "type": "GLOBAL", - "global": { - "stream_states": [ - {"stream_descriptor": {"name": "actors", "namespace": "public"}, "stream_state": {"id": "mando_michael"}}, - ], - }, - }, - ], - { - HashableStreamDescriptor(name="actors", namespace="public"): AirbyteStateBlob({"id": "mando_michael"}), - }, - does_not_raise(), - id="test_incoming_global_state_without_shared", - ), - pytest.param( - [ - { - "type": "GLOBAL", - "global": { - "shared_state": None, - "stream_states": [ - { - "stream_descriptor": {"name": "actors", "namespace": "public"}, - "stream_state": {"id": "mando_michael"}, - }, - ], - }, - }, - ], - { - HashableStreamDescriptor(name="actors", namespace="public"): AirbyteStateBlob({"id": "mando_michael"}), - }, - does_not_raise(), - id="test_incoming_global_state_with_none_shared", - ), - pytest.param( - [ - { - "type": "GLOBAL", - "global": { - "stream_states": [ - {"stream_descriptor": {"name": "actresses", "namespace": "public"}}, - ], - }, - }, - ], - {HashableStreamDescriptor(name="actresses", namespace="public"): None}, - does_not_raise(), - id="test_incoming_global_state_without_stream_state", - ), - ), -) -def test_initialize_state_manager(input_stream_state, expected_stream_state, expected_error): - if isinstance(input_stream_state, List): - input_stream_state = [AirbyteStateMessageSerializer.load(state_obj) for state_obj in list(input_stream_state)] - - with expected_error: - state_manager = ConnectorStateManager(input_stream_state) - - assert state_manager.per_stream_states == expected_stream_state - - -@pytest.mark.parametrize( - "input_state, stream_name, namespace, expected_state", - [ - pytest.param( - [ - { - "type": "STREAM", - "stream": {"stream_descriptor": {"name": "users", "namespace": "public"}, "stream_state": {"created_at": 12345}}, - }, - { - "type": "STREAM", - "stream": {"stream_descriptor": {"name": "accounts", "namespace": "public"}, "stream_state": {"id": "abc"}}, - }, - ], - "users", - "public", - {"created_at": 12345}, - id="test_get_stream_only", - ), - pytest.param( - [ - { - "type": "STREAM", - "stream": {"stream_descriptor": {"name": "users"}, "stream_state": {"created_at": 12345}}, - }, - {"type": "STREAM", "stream": {"stream_descriptor": {"name": "accounts"}, "stream_state": {"id": "abc"}}}, - ], - "users", - None, - {"created_at": 12345}, - id="test_get_stream_without_namespace", - ), - pytest.param( - [ - {"type": "STREAM", "stream": {"stream_descriptor": {"name": "users"}}}, - {"type": "STREAM", "stream": {"stream_descriptor": {"name": "accounts"}, "stream_state": {"id": "abc"}}}, - ], - "users", - None, - {}, - id="test_get_stream_without_stream_state", - ), - pytest.param( - [ - { - "type": "STREAM", - "stream": {"stream_descriptor": {"name": "users", "namespace": "public"}, "stream_state": {"created_at": 12345}}, - }, - { - "type": "STREAM", - "stream": {"stream_descriptor": {"name": "accounts", "namespace": "public"}, "stream_state": {"id": "abc"}}, - }, - ], - "missing", - "public", - {}, - id="test_get_missing_stream", - ), - pytest.param( - [ - { - "type": "STREAM", - "stream": {"stream_descriptor": {"name": "users", "namespace": "public"}, "stream_state": {"created_at": 12345}}, - }, - { - "type": "STREAM", - "stream": {"stream_descriptor": {"name": "accounts", "namespace": "public"}, "stream_state": {"id": "abc"}}, - }, - ], - "users", - "wrong_namespace", - {}, - id="test_get_stream_wrong_namespace", - ), - pytest.param([], "users", "public", {}, id="test_get_empty_stream_state_defaults_to_empty_dictionary"), - pytest.param( - [ - { - "type": "STREAM", - "stream": {"stream_descriptor": {"name": "users", "namespace": "public"}, "stream_state": None}, - }, - ], - "users", - "public", - {}, - id="test_get_stream_with_stream_state_none_returns_empty_map", - ), - ], -) -def test_get_stream_state(input_state, stream_name, namespace, expected_state): - state_messages = [AirbyteStateMessageSerializer.load(state_obj) for state_obj in list(input_state)] - state_manager = ConnectorStateManager(state_messages) - - actual_state = state_manager.get_stream_state(stream_name, namespace) - - assert actual_state == expected_state - - -def test_get_state_returns_deep_copy(): - input_state = [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="episodes", namespace="public"), - stream_state=AirbyteStateBlob({"id": [109]}), - ), - ) - ] - state_manager = ConnectorStateManager(input_state) - - per_stream_state = state_manager.get_stream_state("episodes", "public") - per_stream_state["id"].append(309) - - assert state_manager.get_stream_state("episodes", "public") == {"id": [109]} - - -@pytest.mark.parametrize( - "start_state, update_name, update_namespace, update_value", - [ - pytest.param( - [ - { - "type": "STREAM", - "stream": {"stream_descriptor": {"name": "actors", "namespace": "public"}, "stream_state": {"id": "mckean_michael"}}, - }, - { - "type": "STREAM", - "stream": {"stream_descriptor": {"name": "actresses", "namespace": "public"}, "stream_state": {"id": "seehorn_rhea"}}, - }, - ], - "actors", - "public", - {"id": "fabian_patrick"}, - id="test_update_existing_stream_state", - ), - pytest.param( - [], - "actresses", - None, - {"id": "seehorn_rhea"}, - id="test_update_first_time_sync_without_namespace", - ), - pytest.param( - [ - { - "type": "STREAM", - "stream": {"stream_descriptor": {"name": "actresses", "namespace": "public"}, "stream_state": {"id": "seehorn_rhea"}}, - } - ], - "actors", - "public", - {"id": "banks_jonathan"}, - id="test_update_missing_state", - ), - pytest.param( - [ - { - "type": "STREAM", - "stream": {"stream_descriptor": {"name": "actresses", "namespace": "public"}, "stream_state": {"id": "seehorn_rhea"}}, - } - ], - "actors", - "public", - {"id": "banks_jonathan"}, - id="test_ignore_when_per_stream_state_value_is_none", - ), - ], -) -def test_update_state_for_stream(start_state, update_name, update_namespace, update_value): - state_messages = [AirbyteStateMessage(state_obj) for state_obj in list(start_state)] - state_manager = ConnectorStateManager(state_messages) - - state_manager.update_state_for_stream(update_name, update_namespace, update_value) - - assert state_manager.per_stream_states[HashableStreamDescriptor(name=update_name, namespace=update_namespace)] == AirbyteStateBlob( - update_value - ) - - -@pytest.mark.parametrize( - "start_state, update_name, update_namespace, expected_state_message", - [ - pytest.param( - [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="episodes", namespace="public"), - stream_state=AirbyteStateBlob({"created_at": "2022_05_22"}), - ), - ), - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="seasons", namespace="public"), - stream_state=AirbyteStateBlob({"id": 1}), - ), - ), - ], - "episodes", - "public", - AirbyteMessage( - type=MessageType.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="episodes", namespace="public"), - stream_state=AirbyteStateBlob({"created_at": "2022_05_22"}), - ), - ), - ), - id="test_emit_state_message", - ), - pytest.param( - [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="episodes", namespace="public"), - stream_state=None, - ), - ), - ], - "episodes", - "public", - AirbyteMessage( - type=MessageType.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="episodes", namespace="public"), - stream_state=AirbyteStateBlob(), - ), - ), - ), - id="test_always_emit_message_with_stream_state_blob", - ), - pytest.param( - [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="episodes", namespace="public"), - stream_state=AirbyteStateBlob({"id": 507}), - ), - ) - ], - "missing", - "public", - AirbyteMessage( - type=MessageType.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="missing", namespace="public"), stream_state=AirbyteStateBlob() - ), - ), - ), - id="test_emit_state_nonexistent_stream_name", - ), - pytest.param( - [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="episodes", namespace="public"), - stream_state=AirbyteStateBlob({"id": 507}), - ), - ) - ], - "episodes", - "nonexistent", - AirbyteMessage( - type=MessageType.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="episodes", namespace="nonexistent"), stream_state=AirbyteStateBlob() - ), - ), - ), - id="test_emit_state_wrong_namespace", - ), - ], -) -def test_create_state_message(start_state, update_name, update_namespace, expected_state_message): - state_manager = ConnectorStateManager(start_state) - - actual_state_message = state_manager.create_state_message(stream_name=update_name, namespace=update_namespace) - assert actual_state_message == expected_state_message diff --git a/airbyte-cdk/python/unit_tests/sources/test_http_logger.py b/airbyte-cdk/python/unit_tests/sources/test_http_logger.py deleted file mode 100644 index 5711d3529211..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/test_http_logger.py +++ /dev/null @@ -1,252 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -import requests -from airbyte_cdk.sources.http_logger import format_http_message - -A_TITLE = "a title" -A_DESCRIPTION = "a description" -A_STREAM_NAME = "a stream name" -ANY_REQUEST = requests.Request(method="POST", url="http://a-url.com", headers={}, params={}).prepare() - - -class ResponseBuilder: - def __init__(self): - self._body_content = "" - self._headers = {} - self._request = ANY_REQUEST - self._status_code = 100 - - def body_content(self, body_content: bytes) -> "ResponseBuilder": - self._body_content = body_content - return self - - def headers(self, headers: dict) -> "ResponseBuilder": - self._headers = headers - return self - - def request(self, request: requests.PreparedRequest) -> "ResponseBuilder": - self._request = request - return self - - def status_code(self, status_code: int) -> "ResponseBuilder": - self._status_code = status_code - return self - - def build(self): - response = requests.Response() - response._content = self._body_content - response.headers = self._headers - response.request = self._request - response.status_code = self._status_code - return response - - -EMPTY_RESPONSE = {"body": {"content": ""}, "headers": {}, "status_code": 100} - - -@pytest.mark.parametrize( - "test_name, http_method, url, headers, params, body_json, body_data, expected_airbyte_message", - [ - ( - "test_basic_get_request", - "GET", - "https://airbyte.io", - {}, - {}, - {}, - {}, - { - "airbyte_cdk": {"stream": {"name": A_STREAM_NAME}}, - "http": { - "title": A_TITLE, - "description": A_DESCRIPTION, - "request": {"method": "GET", "body": {"content": None}, "headers": {}}, - "response": EMPTY_RESPONSE, - }, - "log": {"level": "debug"}, - "url": {"full": "https://airbyte.io/"}, - }, - ), - ( - "test_get_request_with_headers", - "GET", - "https://airbyte.io", - {"h1": "v1", "h2": "v2"}, - {}, - {}, - {}, - { - "airbyte_cdk": {"stream": {"name": A_STREAM_NAME}}, - "http": { - "title": A_TITLE, - "description": A_DESCRIPTION, - "request": {"method": "GET", "body": {"content": None}, "headers": {"h1": "v1", "h2": "v2"}}, - "response": EMPTY_RESPONSE, - }, - "log": {"level": "debug"}, - "url": {"full": "https://airbyte.io/"}, - }, - ), - ( - "test_get_request_with_request_params", - "GET", - "https://airbyte.io", - {}, - {"p1": "v1", "p2": "v2"}, - {}, - {}, - { - "airbyte_cdk": {"stream": {"name": A_STREAM_NAME}}, - "http": { - "title": A_TITLE, - "description": A_DESCRIPTION, - "request": {"method": "GET", "body": {"content": None}, "headers": {}}, - "response": EMPTY_RESPONSE, - }, - "log": {"level": "debug"}, - "url": {"full": "https://airbyte.io/?p1=v1&p2=v2"}, - }, - ), - ( - "test_get_request_with_request_body_json", - "GET", - "https://airbyte.io", - {"Content-Type": "application/json"}, - {}, - {"b1": "v1", "b2": "v2"}, - {}, - { - "airbyte_cdk": {"stream": {"name": A_STREAM_NAME}}, - "http": { - "title": A_TITLE, - "description": A_DESCRIPTION, - "request": { - "method": "GET", - "body": {"content": '{"b1": "v1", "b2": "v2"}'}, - "headers": {"Content-Type": "application/json", "Content-Length": "24"}, - }, - "response": EMPTY_RESPONSE, - }, - "log": {"level": "debug"}, - "url": {"full": "https://airbyte.io/"}, - }, - ), - ( - "test_get_request_with_headers_params_and_body", - "GET", - "https://airbyte.io", - {"Content-Type": "application/json", "h1": "v1"}, - {"p1": "v1", "p2": "v2"}, - {"b1": "v1", "b2": "v2"}, - {}, - { - "airbyte_cdk": {"stream": {"name": A_STREAM_NAME}}, - "http": { - "title": A_TITLE, - "description": A_DESCRIPTION, - "request": { - "method": "GET", - "body": {"content": '{"b1": "v1", "b2": "v2"}'}, - "headers": {"Content-Type": "application/json", "Content-Length": "24", "h1": "v1"}, - }, - "response": EMPTY_RESPONSE, - }, - "log": {"level": "debug"}, - "url": {"full": "https://airbyte.io/?p1=v1&p2=v2"}, - }, - ), - ( - "test_get_request_with_request_body_data", - "GET", - "https://airbyte.io", - {"Content-Type": "application/x-www-form-urlencoded"}, - {}, - {}, - {"b1": "v1", "b2": "v2"}, - { - "airbyte_cdk": {"stream": {"name": A_STREAM_NAME}}, - "http": { - "title": A_TITLE, - "description": A_DESCRIPTION, - "request": { - "method": "GET", - "body": {"content": "b1=v1&b2=v2"}, - "headers": {"Content-Type": "application/x-www-form-urlencoded", "Content-Length": "11"}, - }, - "response": EMPTY_RESPONSE, - }, - "log": {"level": "debug"}, - "url": {"full": "https://airbyte.io/"}, - }, - ), - ( - "test_basic_post_request", - "POST", - "https://airbyte.io", - {}, - {}, - {}, - {}, - { - "airbyte_cdk": {"stream": {"name": A_STREAM_NAME}}, - "http": { - "title": A_TITLE, - "description": A_DESCRIPTION, - "request": {"method": "POST", "body": {"content": None}, "headers": {"Content-Length": "0"}}, - "response": EMPTY_RESPONSE, - }, - "log": {"level": "debug"}, - "url": {"full": "https://airbyte.io/"}, - }, - ), - ], -) -def test_prepared_request_to_airbyte_message(test_name, http_method, url, headers, params, body_json, body_data, expected_airbyte_message): - request = requests.Request(method=http_method, url=url, headers=headers, params=params) - if body_json: - request.json = body_json - if body_data: - request.data = body_data - prepared_request = request.prepare() - - actual_airbyte_message = format_http_message(ResponseBuilder().request(prepared_request).build(), A_TITLE, A_DESCRIPTION, A_STREAM_NAME) - - assert actual_airbyte_message == expected_airbyte_message - - -@pytest.mark.parametrize( - "test_name, response_body, response_headers, status_code, expected_airbyte_message", - [ - ("test_response_no_body_no_headers", b"", {}, 200, {"body": {"content": ""}, "headers": {}, "status_code": 200}), - ( - "test_response_no_body_with_headers", - b"", - {"h1": "v1", "h2": "v2"}, - 200, - {"body": {"content": ""}, "headers": {"h1": "v1", "h2": "v2"}, "status_code": 200}, - ), - ( - "test_response_with_body_no_headers", - b'{"b1": "v1", "b2": "v2"}', - {}, - 200, - {"body": {"content": '{"b1": "v1", "b2": "v2"}'}, "headers": {}, "status_code": 200}, - ), - ( - "test_response_with_body_and_headers", - b'{"b1": "v1", "b2": "v2"}', - {"h1": "v1", "h2": "v2"}, - 200, - {"body": {"content": '{"b1": "v1", "b2": "v2"}'}, "headers": {"h1": "v1", "h2": "v2"}, "status_code": 200}, - ), - ], -) -def test_response_to_airbyte_message(test_name, response_body, response_headers, status_code, expected_airbyte_message): - response = ResponseBuilder().body_content(response_body).headers(response_headers).status_code(status_code).build() - - actual_airbyte_message = format_http_message(response, A_TITLE, A_DESCRIPTION, A_STREAM_NAME) - - assert actual_airbyte_message["http"]["response"] == expected_airbyte_message diff --git a/airbyte-cdk/python/unit_tests/sources/test_integration_source.py b/airbyte-cdk/python/unit_tests/sources/test_integration_source.py deleted file mode 100644 index 17628a0263cd..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/test_integration_source.py +++ /dev/null @@ -1,86 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import os -from typing import Any, List, Mapping -from unittest import mock -from unittest.mock import patch - -import pytest -import requests -from airbyte_cdk.entrypoint import launch -from airbyte_cdk.utils import AirbyteTracedException -from unit_tests.sources.fixtures.source_test_fixture import ( - HttpTestStream, - SourceFixtureOauthAuthenticator, - SourceTestFixture, - fixture_mock_send, -) - - -@pytest.mark.parametrize( - "deployment_mode, url_base, expected_records, expected_error", - [ - pytest.param("CLOUD", "https://airbyte.com/api/v1/", [], None, id="test_cloud_read_with_public_endpoint"), - pytest.param("CLOUD", "http://unsecured.com/api/v1/", [], "system_error", id="test_cloud_read_with_unsecured_url"), - pytest.param("CLOUD", "https://172.20.105.99/api/v1/", [], "config_error", id="test_cloud_read_with_private_endpoint"), - pytest.param("CLOUD", "https://localhost:80/api/v1/", [], "config_error", id="test_cloud_read_with_localhost"), - pytest.param("OSS", "https://airbyte.com/api/v1/", [], None, id="test_oss_read_with_public_endpoint"), - pytest.param("OSS", "https://172.20.105.99/api/v1/", [], None, id="test_oss_read_with_private_endpoint"), - ], -) -@patch.object(requests.Session, "send", fixture_mock_send) -def test_external_request_source(capsys, deployment_mode, url_base, expected_records, expected_error): - source = SourceTestFixture() - - with mock.patch.dict(os.environ, {"DEPLOYMENT_MODE": deployment_mode}, clear=False): # clear=True clears the existing os.environ dict - with mock.patch.object(HttpTestStream, "url_base", url_base): - args = ["read", "--config", "config.json", "--catalog", "configured_catalog.json"] - if expected_error: - with pytest.raises(AirbyteTracedException): - launch(source, args) - messages = [json.loads(line) for line in capsys.readouterr().out.splitlines()] - assert contains_error_trace_message(messages, expected_error) - else: - launch(source, args) - - -@pytest.mark.parametrize( - "deployment_mode, token_refresh_url, expected_records, expected_error", - [ - pytest.param("CLOUD", "https://airbyte.com/api/v1/", [], None, id="test_cloud_read_with_public_endpoint"), - pytest.param("CLOUD", "http://unsecured.com/api/v1/", [], "system_error", id="test_cloud_read_with_unsecured_url"), - pytest.param("CLOUD", "https://172.20.105.99/api/v1/", [], "config_error", id="test_cloud_read_with_private_endpoint"), - pytest.param("OSS", "https://airbyte.com/api/v1/", [], None, id="test_oss_read_with_public_endpoint"), - pytest.param("OSS", "https://172.20.105.99/api/v1/", [], None, id="test_oss_read_with_private_endpoint"), - ], -) -@patch.object(requests.Session, "send", fixture_mock_send) -def test_external_oauth_request_source(capsys, deployment_mode, token_refresh_url, expected_records, expected_error): - oauth_authenticator = SourceFixtureOauthAuthenticator( - client_id="nora", client_secret="hae_sung", refresh_token="arthur", token_refresh_endpoint=token_refresh_url - ) - source = SourceTestFixture(authenticator=oauth_authenticator) - - with mock.patch.dict(os.environ, {"DEPLOYMENT_MODE": deployment_mode}, clear=False): # clear=True clears the existing os.environ dict - args = ["read", "--config", "config.json", "--catalog", "configured_catalog.json"] - if expected_error: - with pytest.raises(AirbyteTracedException): - launch(source, args) - messages = [json.loads(line) for line in capsys.readouterr().out.splitlines()] - assert contains_error_trace_message(messages, expected_error) - else: - launch(source, args) - - -def contains_error_trace_message(messages: List[Mapping[str, Any]], expected_error: str) -> bool: - for message in messages: - if message.get("type") != "TRACE": - continue - elif message.get("trace").get("type") != "ERROR": - continue - elif message.get("trace").get("error").get("failure_type") == expected_error: - return True - return False diff --git a/airbyte-cdk/python/unit_tests/sources/test_source.py b/airbyte-cdk/python/unit_tests/sources/test_source.py deleted file mode 100644 index d548a51b1ebb..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/test_source.py +++ /dev/null @@ -1,477 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import logging -import tempfile -from contextlib import nullcontext as does_not_raise -from typing import Any, List, Mapping, MutableMapping, Optional, Tuple, Union - -import pytest -from airbyte_cdk.models import ( - AirbyteGlobalState, - AirbyteStateBlob, - AirbyteStateMessage, - AirbyteStateMessageSerializer, - AirbyteStateType, - AirbyteStreamState, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteCatalogSerializer, - StreamDescriptor, - SyncMode, - Type, -) -from airbyte_cdk.sources import AbstractSource, Source -from airbyte_cdk.sources.streams.core import Stream -from airbyte_cdk.sources.streams.http.http import HttpStream -from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer -from orjson import orjson -from serpyco_rs import SchemaValidationError - - -class MockSource(Source): - def read( - self, logger: logging.Logger, config: Mapping[str, Any], catalog: ConfiguredAirbyteCatalog, state: MutableMapping[str, Any] = None - ): - pass - - def check(self, logger: logging.Logger, config: Mapping[str, Any]): - pass - - def discover(self, logger: logging.Logger, config: Mapping[str, Any]): - pass - - -class MockAbstractSource(AbstractSource): - def __init__(self, streams: Optional[List[Stream]] = None): - self._streams = streams - - def check_connection(self, *args, **kwargs) -> Tuple[bool, Optional[Any]]: - return True, "" - - def streams(self, *args, **kwargs) -> List[Stream]: - if self._streams: - return self._streams - return [] - - -@pytest.fixture -def source(): - return MockSource() - - -@pytest.fixture -def catalog(): - configured_catalog = { - "streams": [ - { - "stream": {"name": "mock_http_stream", "json_schema": {}, "supported_sync_modes": ["full_refresh"]}, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh", - }, - { - "stream": {"name": "mock_stream", "json_schema": {}, "supported_sync_modes": ["full_refresh"]}, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh", - }, - ] - } - return ConfiguredAirbyteCatalogSerializer.load(configured_catalog) - - -@pytest.fixture -def abstract_source(mocker): - mocker.patch.multiple(HttpStream, __abstractmethods__=set()) - mocker.patch.multiple(Stream, __abstractmethods__=set()) - - class MockHttpStream(mocker.MagicMock, HttpStream): - url_base = "http://example.com" - path = "/dummy/path" - get_json_schema = mocker.MagicMock() - _state = {} - - @property - def cursor_field(self) -> Union[str, List[str]]: - return ["updated_at"] - - def get_backoff_strategy(self): - return None - - def get_error_handler(self): - return None - - def __init__(self, *args, **kvargs): - mocker.MagicMock.__init__(self) - HttpStream.__init__(self, *args, kvargs) - self.read_records = mocker.MagicMock() - - @property - def availability_strategy(self): - return None - - @property - def state(self) -> MutableMapping[str, Any]: - return self._state - - @state.setter - def state(self, value: MutableMapping[str, Any]) -> None: - self._state = value - - class MockStream(mocker.MagicMock, Stream): - page_size = None - get_json_schema = mocker.MagicMock() - - def __init__(self, **kwargs): - mocker.MagicMock.__init__(self) - self.read_records = mocker.MagicMock() - - streams = [MockHttpStream(), MockStream()] - - class MockAbstractSource(AbstractSource): - def check_connection(self): - return True, None - - def streams(self, config): - self.streams_config = config - return streams - - return MockAbstractSource() - - -@pytest.mark.parametrize( - "incoming_state, expected_state, expected_error", - [ - pytest.param( - [ - { - "type": "STREAM", - "stream": { - "stream_state": {"created_at": "2009-07-19"}, - "stream_descriptor": {"name": "movies", "namespace": "public"}, - }, - } - ], - [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="movies", namespace="public"), - stream_state=AirbyteStateBlob({"created_at": "2009-07-19"}), - ), - ) - ], - does_not_raise(), - id="test_incoming_stream_state", - ), - pytest.param( - [ - { - "type": "STREAM", - "stream": { - "stream_state": {"created_at": "2009-07-19"}, - "stream_descriptor": {"name": "movies", "namespace": "public"}, - }, - }, - { - "type": "STREAM", - "stream": { - "stream_state": {"id": "villeneuve_denis"}, - "stream_descriptor": {"name": "directors", "namespace": "public"}, - }, - }, - { - "type": "STREAM", - "stream": { - "stream_state": {"created_at": "1995-12-27"}, - "stream_descriptor": {"name": "actors", "namespace": "public"}, - }, - }, - ], - [ - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="movies", namespace="public"), - stream_state=AirbyteStateBlob({"created_at": "2009-07-19"}), - ), - ), - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="directors", namespace="public"), - stream_state=AirbyteStateBlob({"id": "villeneuve_denis"}), - ), - ), - AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="actors", namespace="public"), - stream_state=AirbyteStateBlob({"created_at": "1995-12-27"}), - ), - ), - ], - does_not_raise(), - id="test_incoming_multiple_stream_states", - ), - pytest.param( - [ - { - "type": "GLOBAL", - "global": { - "shared_state": {"shared_key": "shared_val"}, - "stream_states": [ - {"stream_state": {"created_at": "2009-07-19"}, "stream_descriptor": {"name": "movies", "namespace": "public"}} - ], - }, - } - ], - [ - AirbyteStateMessage( - type=AirbyteStateType.GLOBAL, - global_=AirbyteGlobalState( - shared_state=AirbyteStateBlob({"shared_key": "shared_val"}), - stream_states=[ - AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="movies", namespace="public"), - stream_state=AirbyteStateBlob({"created_at": "2009-07-19"}), - ) - ], - ), - ), - ], - does_not_raise(), - id="test_incoming_global_state", - ), - pytest.param([], [], does_not_raise(), id="test_empty_incoming_stream_state"), - pytest.param(None, [], does_not_raise(), id="test_none_incoming_state"), - pytest.param( - [ - { - "type": "NOT_REAL", - "stream": { - "stream_state": {"created_at": "2009-07-19"}, - "stream_descriptor": {"name": "movies", "namespace": "public"}, - }, - } - ], - None, - pytest.raises(SchemaValidationError), - id="test_invalid_stream_state_invalid_type", - ), - pytest.param( - [{"type": "STREAM", "stream": {"stream_state": {"created_at": "2009-07-19"}}}], - None, - pytest.raises(SchemaValidationError), - id="test_invalid_stream_state_missing_descriptor", - ), - pytest.param( - [{"type": "GLOBAL", "global": {"shared_state": {"shared_key": "shared_val"}}}], - None, - pytest.raises(SchemaValidationError), - id="test_invalid_global_state_missing_streams", - ), - pytest.param( - [ - { - "type": "GLOBAL", - "global": { - "shared_state": {"shared_key": "shared_val"}, - "stream_states": { - "stream_state": {"created_at": "2009-07-19"}, - "stream_descriptor": {"name": "movies", "namespace": "public"}, - }, - }, - } - ], - None, - pytest.raises(SchemaValidationError), - id="test_invalid_global_state_streams_not_list", - ), - ], -) -def test_read_state(source, incoming_state, expected_state, expected_error): - with tempfile.NamedTemporaryFile("w") as state_file: - state_file.write(json.dumps(incoming_state)) - state_file.flush() - with expected_error: - actual = source.read_state(state_file.name) - if expected_state and actual: - assert AirbyteStateMessageSerializer.dump(actual[0]) == AirbyteStateMessageSerializer.dump(expected_state[0]) - - -def test_read_invalid_state(source): - with tempfile.NamedTemporaryFile("w") as state_file: - state_file.write("invalid json content") - state_file.flush() - with pytest.raises(ValueError, match="Could not read json file"): - source.read_state(state_file.name) - - -@pytest.mark.parametrize( - "source, expected_state", - [ - pytest.param(MockAbstractSource(), [], id="test_source_not_implementing_read_returns_per_stream_format"), - ], -) -def test_read_state_nonexistent(source, expected_state): - assert source.read_state("") == expected_state - - -def test_read_catalog(source): - configured_catalog = { - "streams": [ - { - "stream": { - "name": "mystream", - "json_schema": {"type": "object", "properties": {"k": "v"}}, - "supported_sync_modes": ["full_refresh"], - }, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh", - } - ] - } - expected = ConfiguredAirbyteCatalogSerializer.load(configured_catalog) - with tempfile.NamedTemporaryFile("w") as catalog_file: - catalog_file.write(orjson.dumps(ConfiguredAirbyteCatalogSerializer.dump(expected)).decode()) - catalog_file.flush() - actual = source.read_catalog(catalog_file.name) - assert actual == expected - - -def test_internal_config(abstract_source, catalog): - streams = abstract_source.streams(None) - assert len(streams) == 2 - http_stream, non_http_stream = streams - assert isinstance(http_stream, HttpStream) - assert not isinstance(non_http_stream, HttpStream) - http_stream.read_records.return_value = [{}] * 3 - non_http_stream.read_records.return_value = [{}] * 3 - - # Test with empty config - logger = logging.getLogger(f"airbyte.{getattr(abstract_source, 'name', '')}") - records = [r for r in abstract_source.read(logger=logger, config={}, catalog=catalog, state={})] - # 3 for http stream, 3 for non http stream, 1 for state message for each stream (2x) and 3 for stream status messages for each stream (2x) - assert len(records) == 3 + 3 + 1 + 1 + 3 + 3 - assert http_stream.read_records.called - assert non_http_stream.read_records.called - # Make sure page_size havent been set - assert not http_stream.page_size - assert not non_http_stream.page_size - # Test with records limit set to 1 - internal_config = {"some_config": 100, "_limit": 1} - records = [r for r in abstract_source.read(logger=logger, config=internal_config, catalog=catalog, state={})] - # 1 from http stream + 1 from non http stream, 1 for state message for each stream (2x) and 3 for stream status messages for each stream (2x) - assert len(records) == 1 + 1 + 1 + 1 + 3 + 3 - assert "_limit" not in abstract_source.streams_config - assert "some_config" in abstract_source.streams_config - # Test with records limit set to number that exceeds expceted records - internal_config = {"some_config": 100, "_limit": 20} - records = [r for r in abstract_source.read(logger=logger, config=internal_config, catalog=catalog, state={})] - assert len(records) == 3 + 3 + 1 + 1 + 3 + 3 - - # Check if page_size paramter is set to http instance only - internal_config = {"some_config": 100, "_page_size": 2} - records = [r for r in abstract_source.read(logger=logger, config=internal_config, catalog=catalog, state={})] - assert "_page_size" not in abstract_source.streams_config - assert "some_config" in abstract_source.streams_config - assert len(records) == 3 + 3 + 1 + 1 + 3 + 3 - assert http_stream.page_size == 2 - # Make sure page_size havent been set for non http streams - assert not non_http_stream.page_size - - -def test_internal_config_limit(mocker, abstract_source, catalog): - logger_mock = mocker.MagicMock() - logger_mock.level = logging.DEBUG - del catalog.streams[1] - STREAM_LIMIT = 2 - SLICE_DEBUG_LOG_COUNT = 1 - FULL_RECORDS_NUMBER = 3 - TRACE_STATUS_COUNT = 3 - STATE_COUNT = 1 - streams = abstract_source.streams(None) - http_stream = streams[0] - http_stream.read_records.return_value = [{}] * FULL_RECORDS_NUMBER - internal_config = {"some_config": 100, "_limit": STREAM_LIMIT} - - catalog.streams[0].sync_mode = SyncMode.full_refresh - records = [r for r in abstract_source.read(logger=logger_mock, config=internal_config, catalog=catalog, state={})] - assert len(records) == STREAM_LIMIT + SLICE_DEBUG_LOG_COUNT + TRACE_STATUS_COUNT + STATE_COUNT - logger_info_args = [call[0][0] for call in logger_mock.info.call_args_list] - # Check if log line matches number of limit - read_log_record = [_l for _l in logger_info_args if _l.startswith("Read")] - assert read_log_record[0].startswith(f"Read {STREAM_LIMIT} ") - - # No limit, check if state record produced for incremental stream - catalog.streams[0].sync_mode = SyncMode.incremental - records = [r for r in abstract_source.read(logger=logger_mock, config={}, catalog=catalog, state={})] - assert len(records) == FULL_RECORDS_NUMBER + SLICE_DEBUG_LOG_COUNT + TRACE_STATUS_COUNT + 1 - assert records[-2].type == Type.STATE - assert records[-1].type == Type.TRACE - - # Set limit and check if state is produced when limit is set for incremental stream - logger_mock.reset_mock() - records = [r for r in abstract_source.read(logger=logger_mock, config=internal_config, catalog=catalog, state={})] - assert len(records) == STREAM_LIMIT + SLICE_DEBUG_LOG_COUNT + TRACE_STATUS_COUNT + 1 - assert records[-2].type == Type.STATE - assert records[-1].type == Type.TRACE - logger_info_args = [call[0][0] for call in logger_mock.info.call_args_list] - read_log_record = [_l for _l in logger_info_args if _l.startswith("Read")] - assert read_log_record[0].startswith(f"Read {STREAM_LIMIT} ") - - -SCHEMA = {"type": "object", "properties": {"value": {"type": "string"}}} - - -def test_source_config_no_transform(mocker, abstract_source, catalog): - SLICE_DEBUG_LOG_COUNT = 1 - TRACE_STATUS_COUNT = 3 - STATE_COUNT = 1 - # Read operation has an extra get_json_schema call when filtering invalid fields - GET_JSON_SCHEMA_COUNT_WHEN_FILTERING = 1 - logger_mock = mocker.MagicMock() - logger_mock.level = logging.DEBUG - streams = abstract_source.streams(None) - http_stream, non_http_stream = streams - http_stream.get_json_schema.return_value = non_http_stream.get_json_schema.return_value = SCHEMA - http_stream.read_records.return_value, non_http_stream.read_records.return_value = [[{"value": 23}] * 5] * 2 - records = [r for r in abstract_source.read(logger=logger_mock, config={}, catalog=catalog, state={})] - assert len(records) == 2 * (5 + SLICE_DEBUG_LOG_COUNT + TRACE_STATUS_COUNT + STATE_COUNT) - assert [r.record.data for r in records if r.type == Type.RECORD] == [{"value": 23}] * 2 * 5 - assert http_stream.get_json_schema.call_count == 5 + GET_JSON_SCHEMA_COUNT_WHEN_FILTERING - assert non_http_stream.get_json_schema.call_count == 5 + GET_JSON_SCHEMA_COUNT_WHEN_FILTERING - - -def test_source_config_transform(mocker, abstract_source, catalog): - logger_mock = mocker.MagicMock() - logger_mock.level = logging.DEBUG - SLICE_DEBUG_LOG_COUNT = 2 - TRACE_STATUS_COUNT = 6 - STATE_COUNT = 2 - streams = abstract_source.streams(None) - http_stream, non_http_stream = streams - http_stream.transformer = TypeTransformer(TransformConfig.DefaultSchemaNormalization) - non_http_stream.transformer = TypeTransformer(TransformConfig.DefaultSchemaNormalization) - http_stream.get_json_schema.return_value = non_http_stream.get_json_schema.return_value = SCHEMA - http_stream.read_records.return_value, non_http_stream.read_records.return_value = [{"value": 23}], [{"value": 23}] - records = [r for r in abstract_source.read(logger=logger_mock, config={}, catalog=catalog, state={})] - assert len(records) == 2 + SLICE_DEBUG_LOG_COUNT + TRACE_STATUS_COUNT + STATE_COUNT - assert [r.record.data for r in records if r.type == Type.RECORD] == [{"value": "23"}] * 2 - - -def test_source_config_transform_and_no_transform(mocker, abstract_source, catalog): - logger_mock = mocker.MagicMock() - logger_mock.level = logging.DEBUG - SLICE_DEBUG_LOG_COUNT = 2 - TRACE_STATUS_COUNT = 6 - STATE_COUNT = 2 - streams = abstract_source.streams(None) - http_stream, non_http_stream = streams - http_stream.transformer = TypeTransformer(TransformConfig.DefaultSchemaNormalization) - http_stream.get_json_schema.return_value = non_http_stream.get_json_schema.return_value = SCHEMA - http_stream.read_records.return_value, non_http_stream.read_records.return_value = [{"value": 23}], [{"value": 23}] - records = [r for r in abstract_source.read(logger=logger_mock, config={}, catalog=catalog, state={})] - assert len(records) == 2 + SLICE_DEBUG_LOG_COUNT + TRACE_STATUS_COUNT + STATE_COUNT - assert [r.record.data for r in records if r.type == Type.RECORD] == [{"value": "23"}, {"value": 23}] diff --git a/airbyte-cdk/python/unit_tests/sources/test_source_read.py b/airbyte-cdk/python/unit_tests/sources/test_source_read.py deleted file mode 100644 index 05c71d1eae39..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/test_source_read.py +++ /dev/null @@ -1,422 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -import logging -from typing import Any, Iterable, List, Mapping, Optional, Tuple, Union -from unittest.mock import Mock - -import freezegun -from airbyte_cdk.models import ( - AirbyteMessage, - AirbyteRecordMessage, - AirbyteStream, - AirbyteStreamStatus, - AirbyteStreamStatusTraceMessage, - AirbyteTraceMessage, - ConfiguredAirbyteCatalog, - ConfiguredAirbyteStream, - DestinationSyncMode, - StreamDescriptor, - SyncMode, - TraceType, -) -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources import AbstractSource -from airbyte_cdk.sources.concurrent_source.concurrent_source import ConcurrentSource -from airbyte_cdk.sources.concurrent_source.concurrent_source_adapter import ConcurrentSourceAdapter -from airbyte_cdk.sources.message import InMemoryMessageRepository -from airbyte_cdk.sources.streams import Stream -from airbyte_cdk.sources.streams.concurrent.adapters import StreamFacade -from airbyte_cdk.sources.streams.concurrent.cursor import FinalStateCursor -from airbyte_cdk.sources.streams.core import StreamData -from airbyte_cdk.utils import AirbyteTracedException -from unit_tests.sources.streams.concurrent.scenarios.thread_based_concurrent_stream_source_builder import NeverLogSliceLogger - - -class _MockStream(Stream): - def __init__(self, slice_to_records: Mapping[str, List[Mapping[str, Any]]], name: str): - self._slice_to_records = slice_to_records - self._name = name - - @property - def name(self) -> str: - return self._name - - @property - def primary_key(self) -> Optional[Union[str, List[str], List[List[str]]]]: - return None - - def stream_slices( - self, *, sync_mode: SyncMode, cursor_field: Optional[List[str]] = None, stream_state: Optional[Mapping[str, Any]] = None - ) -> Iterable[Optional[Mapping[str, Any]]]: - for partition in self._slice_to_records.keys(): - yield {"partition": partition} - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: Optional[List[str]] = None, - stream_slice: Optional[Mapping[str, Any]] = None, - stream_state: Optional[Mapping[str, Any]] = None, - ) -> Iterable[StreamData]: - for record_or_exception in self._slice_to_records[stream_slice["partition"]]: - if isinstance(record_or_exception, Exception): - raise record_or_exception - else: - yield record_or_exception - - def get_json_schema(self) -> Mapping[str, Any]: - return {} - - -class _MockSource(AbstractSource): - message_repository = InMemoryMessageRepository() - - def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Optional[Any]]: - pass - - def set_streams(self, streams): - self._streams = streams - - def streams(self, config: Mapping[str, Any]) -> List[Stream]: - return self._streams - - -class _MockConcurrentSource(ConcurrentSourceAdapter): - message_repository = InMemoryMessageRepository() - - def __init__(self, logger): - concurrent_source = ConcurrentSource.create(1, 1, logger, NeverLogSliceLogger(), self.message_repository) - super().__init__(concurrent_source) - - def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Optional[Any]]: - pass - - def set_streams(self, streams): - self._streams = streams - - def streams(self, config: Mapping[str, Any]) -> List[Stream]: - return self._streams - - -@freezegun.freeze_time("2020-01-01T00:00:00") -def test_concurrent_source_yields_the_same_messages_as_abstract_source_when_no_exceptions_are_raised(): - records_stream_1_partition_1 = [ - {"id": 1, "partition": "1"}, - {"id": 2, "partition": "1"}, - ] - records_stream_1_partition_2 = [ - {"id": 3, "partition": "2"}, - {"id": 4, "partition": "2"}, - ] - records_stream_2_partition_1 = [ - {"id": 100, "partition": "A"}, - {"id": 200, "partition": "A"}, - ] - records_stream_2_partition_2 = [ - {"id": 300, "partition": "B"}, - {"id": 400, "partition": "B"}, - ] - stream_1_slice_to_partition = {"1": records_stream_1_partition_1, "2": records_stream_1_partition_2} - stream_2_slice_to_partition = {"A": records_stream_2_partition_1, "B": records_stream_2_partition_2} - state = None - logger = _init_logger() - - source, concurrent_source = _init_sources([stream_1_slice_to_partition, stream_2_slice_to_partition], state, logger) - - config = {} - catalog = _create_configured_catalog(source._streams) - # FIXME this is currently unused in this test - # messages_from_abstract_source = _read_from_source(source, logger, config, catalog, state, None) - messages_from_concurrent_source = _read_from_source(concurrent_source, logger, config, catalog, state, None) - - expected_messages = [ - AirbyteMessage( - type=MessageType.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - emitted_at=1577836800000.0, - error=None, - estimate=None, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name="stream0"), status=AirbyteStreamStatus(AirbyteStreamStatus.STARTED) - ), - ), - ), - AirbyteMessage( - type=MessageType.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - emitted_at=1577836800000.0, - error=None, - estimate=None, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name="stream0"), status=AirbyteStreamStatus(AirbyteStreamStatus.RUNNING) - ), - ), - ), - AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage( - stream="stream0", - data=records_stream_1_partition_1[0], - emitted_at=1577836800000, - ), - ), - AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage( - stream="stream0", - data=records_stream_1_partition_1[1], - emitted_at=1577836800000, - ), - ), - AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage( - stream="stream0", - data=records_stream_1_partition_2[0], - emitted_at=1577836800000, - ), - ), - AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage( - stream="stream0", - data=records_stream_1_partition_2[1], - emitted_at=1577836800000, - ), - ), - AirbyteMessage( - type=MessageType.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - emitted_at=1577836800000.0, - error=None, - estimate=None, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name="stream0"), status=AirbyteStreamStatus(AirbyteStreamStatus.COMPLETE) - ), - ), - ), - AirbyteMessage( - type=MessageType.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - emitted_at=1577836800000.0, - error=None, - estimate=None, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name="stream1"), status=AirbyteStreamStatus(AirbyteStreamStatus.STARTED) - ), - ), - ), - AirbyteMessage( - type=MessageType.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - emitted_at=1577836800000.0, - error=None, - estimate=None, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name="stream1"), status=AirbyteStreamStatus(AirbyteStreamStatus.RUNNING) - ), - ), - ), - AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage( - stream="stream1", - data=records_stream_2_partition_1[0], - emitted_at=1577836800000, - ), - ), - AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage( - stream="stream1", - data=records_stream_2_partition_1[1], - emitted_at=1577836800000, - ), - ), - AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage( - stream="stream1", - data=records_stream_2_partition_2[0], - emitted_at=1577836800000, - ), - ), - AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage( - stream="stream1", - data=records_stream_2_partition_2[1], - emitted_at=1577836800000, - ), - ), - AirbyteMessage( - type=MessageType.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - emitted_at=1577836800000.0, - error=None, - estimate=None, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name="stream1"), status=AirbyteStreamStatus(AirbyteStreamStatus.COMPLETE) - ), - ), - ), - ] - _verify_messages(expected_messages, messages_from_concurrent_source) - - -@freezegun.freeze_time("2020-01-01T00:00:00") -def test_concurrent_source_yields_the_same_messages_as_abstract_source_when_a_traced_exception_is_raised(): - records = [{"id": 1, "partition": "1"}, AirbyteTracedException()] - stream_slice_to_partition = {"1": records} - - logger = _init_logger() - state = None - source, concurrent_source = _init_sources([stream_slice_to_partition], state, logger) - config = {} - catalog = _create_configured_catalog(source._streams) - messages_from_abstract_source = _read_from_source(source, logger, config, catalog, state, AirbyteTracedException) - messages_from_concurrent_source = _read_from_source(concurrent_source, logger, config, catalog, state, AirbyteTracedException) - - _assert_status_messages(messages_from_abstract_source, messages_from_concurrent_source) - _assert_record_messages(messages_from_abstract_source, messages_from_concurrent_source) - _assert_errors(messages_from_abstract_source, messages_from_concurrent_source) - - -@freezegun.freeze_time("2020-01-01T00:00:00") -def test_concurrent_source_yields_the_same_messages_as_abstract_source_when_an_exception_is_raised(): - records = [{"id": 1, "partition": "1"}, RuntimeError()] - stream_slice_to_partition = {"1": records} - logger = _init_logger() - - state = None - - source, concurrent_source = _init_sources([stream_slice_to_partition], state, logger) - config = {} - catalog = _create_configured_catalog(source._streams) - messages_from_abstract_source = _read_from_source(source, logger, config, catalog, state, AirbyteTracedException) - messages_from_concurrent_source = _read_from_source(concurrent_source, logger, config, catalog, state, AirbyteTracedException) - - _assert_status_messages(messages_from_abstract_source, messages_from_concurrent_source) - _assert_record_messages(messages_from_abstract_source, messages_from_concurrent_source) - _assert_errors(messages_from_abstract_source, messages_from_concurrent_source) - - -def _assert_status_messages(messages_from_abstract_source, messages_from_concurrent_source): - status_from_concurrent_source = [ - message - for message in messages_from_concurrent_source - if message.type == MessageType.TRACE and message.trace.type == TraceType.STREAM_STATUS - ] - - assert status_from_concurrent_source - _verify_messages( - [ - message - for message in messages_from_abstract_source - if message.type == MessageType.TRACE and message.trace.type == TraceType.STREAM_STATUS - ], - status_from_concurrent_source, - ) - - -def _assert_record_messages(messages_from_abstract_source, messages_from_concurrent_source): - records_from_concurrent_source = [message for message in messages_from_concurrent_source if message.type == MessageType.RECORD] - - assert records_from_concurrent_source - _verify_messages( - [message for message in messages_from_abstract_source if message.type == MessageType.RECORD], - records_from_concurrent_source, - ) - - -def _assert_errors(messages_from_abstract_source, messages_from_concurrent_source): - errors_from_concurrent_source = [ - message - for message in messages_from_concurrent_source - if message.type == MessageType.TRACE and message.trace.type == TraceType.ERROR - ] - errors_from_abstract_source = [ - message for message in messages_from_abstract_source if message.type == MessageType.TRACE and message.trace.type == TraceType.ERROR - ] - - assert errors_from_concurrent_source - # exceptions might differ from both framework hence we only assert the count - assert len(errors_from_concurrent_source) == len(errors_from_abstract_source) - - -def _init_logger(): - logger = Mock() - logger.level = logging.INFO - logger.isEnabledFor.return_value = False - return logger - - -def _init_sources(stream_slice_to_partitions, state, logger): - source = _init_source(stream_slice_to_partitions, state, logger, _MockSource()) - concurrent_source = _init_source(stream_slice_to_partitions, state, logger, _MockConcurrentSource(logger)) - return source, concurrent_source - - -def _init_source(stream_slice_to_partitions, state, logger, source): - streams = [ - StreamFacade.create_from_stream( - _MockStream(stream_slices, f"stream{i}"), - source, - logger, - state, - FinalStateCursor(stream_name=f"stream{i}", stream_namespace=None, message_repository=InMemoryMessageRepository()), - ) - for i, stream_slices in enumerate(stream_slice_to_partitions) - ] - source.set_streams(streams) - return source - - -def _create_configured_catalog(streams): - return ConfiguredAirbyteCatalog( - streams=[ - ConfiguredAirbyteStream( - stream=AirbyteStream(name=s.name, json_schema={}, supported_sync_modes=[SyncMode.full_refresh]), - sync_mode=SyncMode.full_refresh, - cursor_field=None, - destination_sync_mode=DestinationSyncMode.overwrite, - ) - for s in streams - ] - ) - - -def _read_from_source(source, logger, config, catalog, state, expected_exception): - messages = [] - try: - for m in source.read(logger, config, catalog, state): - messages.append(m) - except Exception as e: - if expected_exception: - assert isinstance(e, expected_exception) - return messages - - -def _verify_messages(expected_messages, messages_from_concurrent_source): - assert _compare(expected_messages, messages_from_concurrent_source) - - -def _compare(s, t): - # Use a compare method that does not require ordering or hashing the elements - # We can't rely on the ordering because of the multithreading - # AirbyteMessage does not implement __eq__ and __hash__ - t = list(t) - try: - for elem in s: - t.remove(elem) - except ValueError: - print(f"ValueError: {elem}") - return False - return not t diff --git a/airbyte-cdk/python/unit_tests/sources/utils/test_record_helper.py b/airbyte-cdk/python/unit_tests/sources/utils/test_record_helper.py deleted file mode 100644 index b5476180309b..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/utils/test_record_helper.py +++ /dev/null @@ -1,85 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from unittest.mock import MagicMock - -import pytest -from airbyte_cdk.models import ( - AirbyteLogMessage, - AirbyteMessage, - AirbyteRecordMessage, - AirbyteStateMessage, - AirbyteStateType, - AirbyteTraceMessage, - Level, - TraceType, -) -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.utils.record_helper import stream_data_to_airbyte_message - -NOW = 1234567 -STREAM_NAME = "my_stream" - - -@pytest.mark.parametrize( - "test_name, data, expected_message", - [ - ( - "test_data_to_airbyte_record", - {"id": 0, "field_A": 1.0, "field_B": "airbyte"}, - AirbyteMessage( - type=MessageType.RECORD, - record=AirbyteRecordMessage(stream="my_stream", data={"id": 0, "field_A": 1.0, "field_B": "airbyte"}, emitted_at=NOW), - ), - ), - ], -) -def test_data_or_record_to_airbyte_record(test_name, data, expected_message): - transformer = MagicMock() - schema = {} - message = stream_data_to_airbyte_message(STREAM_NAME, data, transformer, schema) - message.record.emitted_at = NOW - - if isinstance(data, dict): - transformer.transform.assert_called_with(data, schema) - else: - assert not transformer.transform.called - assert message == expected_message - - -@pytest.mark.parametrize( - "test_name, data, expected_message", - [ - ( - "test_log_message_to_airbyte_record", - AirbyteLogMessage(level=Level.INFO, message="Hello, this is a log message"), - AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=Level.INFO, message="Hello, this is a log message")), - ), - ( - "test_trace_message_to_airbyte_record", - AirbyteTraceMessage(type=TraceType.ERROR, emitted_at=101), - AirbyteMessage(type=MessageType.TRACE, trace=AirbyteTraceMessage(type=TraceType.ERROR, emitted_at=101)), - ), - ], -) -def test_log_or_trace_to_message(test_name, data, expected_message): - transformer = MagicMock() - schema = {} - message = stream_data_to_airbyte_message(STREAM_NAME, data, transformer, schema) - - assert not transformer.transform.called - assert message == expected_message - - -@pytest.mark.parametrize( - "test_name, data", - [ - ("test_log_message_to_airbyte_record", AirbyteStateMessage(type=AirbyteStateType.STREAM)), - ], -) -def test_state_message_to_message(test_name, data): - transformer = MagicMock() - schema = {} - with pytest.raises(ValueError): - stream_data_to_airbyte_message(STREAM_NAME, data, transformer, schema) diff --git a/airbyte-cdk/python/unit_tests/sources/utils/test_schema_helpers.py b/airbyte-cdk/python/unit_tests/sources/utils/test_schema_helpers.py deleted file mode 100644 index 76b7a9b1c772..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/utils/test_schema_helpers.py +++ /dev/null @@ -1,206 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import json -import logging -import os -import shutil -import sys -import traceback -from collections.abc import Mapping -from pathlib import Path - -import jsonref -import pytest -from airbyte_cdk.models import ConnectorSpecification, ConnectorSpecificationSerializer, FailureType -from airbyte_cdk.sources.utils.schema_helpers import InternalConfig, ResourceSchemaLoader, check_config_against_spec_or_exit -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from pytest import fixture -from pytest import raises as pytest_raises - -logger = logging.getLogger("airbyte") - - -MODULE = sys.modules[__name__] -MODULE_NAME = MODULE.__name__.split(".")[0] -SCHEMAS_ROOT = "/".join(os.path.abspath(MODULE.__file__).split("/")[:-1]) / Path("schemas") - - -@fixture(autouse=True, scope="session") -def create_and_teardown_schemas_dir(): - os.mkdir(SCHEMAS_ROOT) - os.mkdir(SCHEMAS_ROOT / "shared") - yield - shutil.rmtree(SCHEMAS_ROOT) - - -def create_schema(name: str, content: Mapping): - with open(SCHEMAS_ROOT / f"{name}.json", "w") as f: - f.write(json.dumps(content)) - - -@fixture -def spec_object() -> ConnectorSpecification: - spec = { - "connectionSpecification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": ["api_token"], - "additionalProperties": False, - "properties": { - "api_token": {"title": "API Token", "type": "string"}, - }, - }, - } - yield ConnectorSpecificationSerializer.load(spec) - - -def test_check_config_against_spec_or_exit_does_not_print_schema(capsys, spec_object): - config = {"super_secret_token": "really_a_secret"} - - with pytest_raises(AirbyteTracedException) as ex_info: - check_config_against_spec_or_exit(config, spec_object) - - exc = ex_info.value - traceback.print_exception(type(exc), exc, exc.__traceback__) - out, err = capsys.readouterr() - assert "really_a_secret" not in out + err - assert exc.failure_type == FailureType.config_error, "failure_type should be config_error" - - -def test_should_not_fail_validation_for_valid_config(spec_object): - config = {"api_token": "something"} - check_config_against_spec_or_exit(config, spec_object) - assert True, "should pass validation with valid config" - - -class TestResourceSchemaLoader: - # Test that a simple schema is loaded correctly - @staticmethod - def test_inline_schema_resolves(): - expected_schema = { - "type": ["null", "object"], - "properties": { - "str": {"type": "string"}, - "int": {"type": "integer"}, - "obj": { - "type": ["null", "object"], - "properties": {"k1": {"type": "string"}}, - }, - }, - } - - create_schema("simple_schema", expected_schema) - resolver = ResourceSchemaLoader(MODULE_NAME) - actual_schema = resolver.get_schema("simple_schema") - assert actual_schema == expected_schema - - @staticmethod - def test_shared_schemas_resolves(): - expected_schema = { - "type": ["null", "object"], - "properties": { - "str": {"type": "string"}, - "int": {"type": "integer"}, - "obj": { - "type": ["null", "object"], - "properties": {"k1": {"type": "string"}}, - }, - }, - } - - partial_schema = { - "type": ["null", "object"], - "properties": { - "str": {"type": "string"}, - "int": {"type": "integer"}, - "obj": {"$ref": "shared_schema.json"}, - }, - } - - referenced_schema = { - "type": ["null", "object"], - "properties": {"k1": {"type": "string"}}, - } - - create_schema("complex_schema", partial_schema) - create_schema("shared/shared_schema", referenced_schema) - - resolver = ResourceSchemaLoader(MODULE_NAME) - - actual_schema = resolver.get_schema("complex_schema") - assert actual_schema == expected_schema - - @staticmethod - def test_shared_schemas_resolves_nested(): - expected_schema = { - "type": ["null", "object"], - "properties": { - "str": {"type": "string"}, - "int": {"type": "integer"}, - "one_of": { - "oneOf": [ - {"type": "string"}, - { - "type": ["null", "object"], - "properties": {"k1": {"type": "string"}}, - }, - ] - }, - "obj": { - "type": ["null", "object"], - "properties": {"k1": {"type": "string"}}, - }, - }, - } - partial_schema = { - "type": ["null", "object"], - "properties": { - "str": {"type": "string"}, - "int": {"type": "integer"}, - "one_of": { - "oneOf": [ - {"type": "string"}, - {"$ref": "shared_schema.json#/definitions/type_one"}, - ] - }, - "obj": {"$ref": "shared_schema.json#/definitions/type_one"}, - }, - } - - referenced_schema = { - "definitions": { - "type_one": {"$ref": "shared_schema.json#/definitions/type_nested"}, - "type_nested": { - "type": ["null", "object"], - "properties": {"k1": {"type": "string"}}, - }, - } - } - - create_schema("complex_schema", partial_schema) - create_schema("shared/shared_schema", referenced_schema) - - resolver = ResourceSchemaLoader(MODULE_NAME) - - actual_schema = resolver.get_schema("complex_schema") - assert actual_schema == expected_schema - # Make sure generated schema is JSON serializable - assert json.dumps(actual_schema) - assert jsonref.JsonRef.replace_refs(actual_schema) - - -@pytest.mark.parametrize( - "limit, record_count, expected", - [ - pytest.param(None, sys.maxsize, False, id="test_no_limit"), - pytest.param(1, 1, True, id="test_record_count_is_exactly_the_limit"), - pytest.param(1, 2, True, id="test_record_count_is_more_than_the_limit"), - pytest.param(1, 0, False, id="test_record_count_is_less_than_the_limit"), - ], -) -def test_internal_config(limit, record_count, expected): - config = InternalConfig(_limit=limit) - assert config.is_limit_reached(record_count) == expected diff --git a/airbyte-cdk/python/unit_tests/sources/utils/test_slice_logger.py b/airbyte-cdk/python/unit_tests/sources/utils/test_slice_logger.py deleted file mode 100644 index 0796e8769179..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/utils/test_slice_logger.py +++ /dev/null @@ -1,46 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging - -import pytest -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, Level -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.utils.slice_logger import AlwaysLogSliceLogger, DebugSliceLogger - - -@pytest.mark.parametrize( - "slice_logger, level, should_log", - [ - pytest.param(DebugSliceLogger(), logging.DEBUG, True, id="debug_logger_should_log_if_level_is_debug"), - pytest.param(DebugSliceLogger(), logging.INFO, False, id="debug_logger_should_not_log_if_level_is_info"), - pytest.param(DebugSliceLogger(), logging.WARN, False, id="debug_logger_should_not_log_if_level_is_warn"), - pytest.param(DebugSliceLogger(), logging.WARNING, False, id="debug_logger_should_not_log_if_level_is_warning"), - pytest.param(DebugSliceLogger(), logging.ERROR, False, id="debug_logger_should_not_log_if_level_is_error"), - pytest.param(DebugSliceLogger(), logging.CRITICAL, False, id="always_log_logger_should_not_log_if_level_is_critical"), - pytest.param(AlwaysLogSliceLogger(), logging.DEBUG, True, id="always_log_logger_should_log_if_level_is_debug"), - pytest.param(AlwaysLogSliceLogger(), logging.INFO, True, id="always_log_logger_should_log_if_level_is_info"), - pytest.param(AlwaysLogSliceLogger(), logging.WARN, True, id="always_log_logger_should_log_if_level_is_warn"), - pytest.param(AlwaysLogSliceLogger(), logging.WARNING, True, id="always_log_logger_should_log_if_level_is_warning"), - pytest.param(AlwaysLogSliceLogger(), logging.ERROR, True, id="always_log_logger_should_log_if_level_is_error"), - pytest.param(AlwaysLogSliceLogger(), logging.CRITICAL, True, id="always_log_logger_should_log_if_level_is_critical"), - ], -) -def test_should_log_slice_message(slice_logger, level, should_log): - logger = logging.Logger(name="name", level=level) - assert slice_logger.should_log_slice_message(logger) == should_log - - -@pytest.mark.parametrize( - "_slice, expected_message", - [ - pytest.param(None, "slice:null", id="test_none_slice"), - pytest.param({}, "slice:{}", id="test_empty_slice"), - pytest.param({"key": "value"}, 'slice:{"key": "value"}', id="test_dict"), - ], -) -def test_create_slice_log_message(_slice, expected_message): - expected_log_message = AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=Level.INFO, message=expected_message)) - log_message = DebugSliceLogger().create_slice_log_message(_slice) - assert log_message == expected_log_message diff --git a/airbyte-cdk/python/unit_tests/sources/utils/test_transform.py b/airbyte-cdk/python/unit_tests/sources/utils/test_transform.py deleted file mode 100644 index 9b3f73989926..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/utils/test_transform.py +++ /dev/null @@ -1,266 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json - -import pytest -from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer - -SIMPLE_SCHEMA = {"type": "object", "properties": {"value": {"type": "string"}}} -COMPLEX_SCHEMA = { - "type": "object", - "properties": { - "value": {"type": "boolean", "format": "even", "is_positive": True}, - "prop": {"type": "string"}, - "prop_with_null": {"type": ["string", "null"]}, - "number_prop": {"type": "number"}, - "int_prop": {"type": ["integer", "null"]}, - "too_many_types": {"type": ["boolean", "null", "string"]}, - "def": { - "type": "object", - "properties": {"dd": {"$ref": "#/definitions/my_type"}}, - }, - "array": {"type": "array", "items": {"$ref": "#/definitions/str_type"}}, - "nested": {"$ref": "#/definitions/nested_type"}, - "list_of_lists": { - "type": "array", - "items": {"type": "array", "items": {"type": "string"}}, - }, - }, - "definitions": { - "str_type": {"type": "string"}, - "nested_type": {"type": "object", "properties": {"a": {"type": "string"}}}, - }, -} -VERY_NESTED_SCHEMA = { - "type": ["null", "object"], - "properties": { - "very_nested_value": { - "type": ["null", "object"], - "properties": { - "very_nested_value": { - "type": ["null", "object"], - "properties": { - "very_nested_value": { - "type": ["null", "object"], - "properties": { - "very_nested_value": { - "type": ["null", "object"], - "properties": {"very_nested_value": {"type": ["null", "number"]}}, - } - }, - } - }, - } - }, - } - }, -} - - -@pytest.mark.parametrize( - "schema, actual, expected, expected_warns", - [ - (SIMPLE_SCHEMA, {"value": 12}, {"value": "12"}, None), - (SIMPLE_SCHEMA, {"value": 12}, {"value": "12"}, None), - (SIMPLE_SCHEMA, {"value": 12, "unexpected_value": "unexpected"}, {"value": "12", "unexpected_value": "unexpected"}, None), - (COMPLEX_SCHEMA, {"value": 1, "array": ["111", 111, {1: 111}]}, {"value": True, "array": ["111", "111", "{1: 111}"]}, None), - ( - COMPLEX_SCHEMA, - {"value": 1, "list_of_lists": [["111"], [111], [11], [{1: 1}]]}, - {"value": True, "list_of_lists": [["111"], ["111"], ["11"], ["{1: 1}"]]}, - None, - ), - (COMPLEX_SCHEMA, {"value": 1, "nested": {"a": [1, 2, 3]}}, {"value": True, "nested": {"a": "[1, 2, 3]"}}, None), - (COMPLEX_SCHEMA, {"value": "false", "nested": {"a": [1, 2, 3]}}, {"value": False, "nested": {"a": "[1, 2, 3]"}}, None), - (COMPLEX_SCHEMA, {}, {}, None), - (COMPLEX_SCHEMA, {"int_prop": "12"}, {"int_prop": 12}, None), - # Skip invalid formattted field and process other fields. - ( - COMPLEX_SCHEMA, - {"prop": 12, "number_prop": "aa12", "array": [12]}, - {"prop": "12", "number_prop": "aa12", "array": ["12"]}, - "Failed to transform value 'aa12' of type 'string' to 'number', key path: '.number_prop'", - ), - # Field too_many_types have ambigious type, skip formatting - ( - COMPLEX_SCHEMA, - {"prop": 12, "too_many_types": 1212, "array": [12]}, - {"prop": "12", "too_many_types": 1212, "array": ["12"]}, - "Failed to transform value 1212 of type 'integer' to '['boolean', 'null', 'string']', key path: '.too_many_types'", - ), - # Test null field - (COMPLEX_SCHEMA, {"prop": None, "array": [12]}, {"prop": "None", "array": ["12"]}, None), - # If field can be null do not convert - (COMPLEX_SCHEMA, {"prop_with_null": None, "array": [12]}, {"prop_with_null": None, "array": ["12"]}, None), - ( - VERY_NESTED_SCHEMA, - {"very_nested_value": {"very_nested_value": {"very_nested_value": {"very_nested_value": {"very_nested_value": "2"}}}}}, - {"very_nested_value": {"very_nested_value": {"very_nested_value": {"very_nested_value": {"very_nested_value": 2.0}}}}}, - None, - ), - (VERY_NESTED_SCHEMA, {"very_nested_value": {"very_nested_value": None}}, {"very_nested_value": {"very_nested_value": None}}, None), - # Object without properties - ({"type": "object"}, {"value": 12}, {"value": 12}, None), - ( - # Array without items - {"type": "object", "properties": {"value": {"type": "array"}}}, - {"value": [12]}, - {"value": [12]}, - None, - ), - ( - # Array without items and value is not an array - {"type": "object", "properties": {"value": {"type": "array"}}}, - {"value": "12"}, - {"value": ["12"]}, - None, - ), - ( - {"type": "object", "properties": {"value": {"type": "array"}}}, - {"value": 12}, - {"value": [12]}, - None, - ), - ( - {"type": "object", "properties": {"value": {"type": "array"}}}, - {"value": None}, - {"value": [None]}, - None, - ), - ( - {"type": "object", "properties": {"value": {"type": ["null", "array"]}}}, - {"value": None}, - {"value": None}, - None, - ), - ( - {"type": "object", "properties": {"value": {"type": "array", "items": {"type": ["string"]}}}}, - {"value": 10}, - {"value": ["10"]}, - None, - ), - ( - {"type": "object", "properties": {"value": {"type": "array", "items": {"type": ["object"]}}}}, - {"value": "string"}, - {"value": "string"}, - "Failed to transform value 'string' of type 'string' to 'array', key path: '.value'", - ), - ( - {"type": "object", "properties": {"value": {"type": "array", "items": {"type": ["string"]}}}}, - {"value": {"key": "value"}}, - {"value": {"key": "value"}}, - "Failed to transform value {'key': 'value'} of type 'object' to 'array', key path: '.value'", - ), - ( - # Schema root object is not an object, no convertion should happen - {"type": "integer"}, - {"value": "12"}, - {"value": "12"}, - "Failed to transform value {'value': '12'} of type 'object' to 'integer', key path: '.'", - ), - ( - # More than one type except null, no conversion should happen - {"type": "object", "properties": {"value": {"type": ["string", "boolean", "null"]}}}, - {"value": 12}, - {"value": 12}, - "Failed to transform value 12 of type 'integer' to '['string', 'boolean', 'null']', key path: '.value'", - ), - ( - # Oneof not suported, no conversion for one_of_value should happen - {"type": "object", "properties": {"one_of_value": {"oneOf": ["string", "boolean", "null"]}, "value_2": {"type": "string"}}}, - {"one_of_value": 12, "value_2": 12}, - {"one_of_value": 12, "value_2": "12"}, - None, - ), - ( - # Case for #7076 issue (Facebook marketing: print tons of WARN message) - { - "properties": { - "cpc": {"type": ["null", "number"]}, - }, - }, - {"cpc": "6.6666"}, - {"cpc": 6.6666}, - None, - ), - ( - {"type": "object", "properties": {"value": {"type": "array", "items": {"type": "string"}}}}, - {"value": {"key": "value"}}, - {"value": {"key": "value"}}, - "Failed to transform value {'key': 'value'} of type 'object' to 'array', key path: '.value'", - ), - ( - {"type": "object", "properties": {"value1": {"type": "object", "properties": {"value2": {"type": "string"}}}}}, - {"value1": "value2"}, - {"value1": "value2"}, - "Failed to transform value 'value2' of type 'string' to 'object', key path: '.value1'", - ), - ( - {"type": "object", "properties": {"value": {"type": "array", "items": {"type": "object"}}}}, - {"value": ["one", "two"]}, - {"value": ["one", "two"]}, - "Failed to transform value 'one' of type 'string' to 'object', key path: '.value.0'", - ), - ], -) -def test_transform(schema, actual, expected, expected_warns, caplog): - t = TypeTransformer(TransformConfig.DefaultSchemaNormalization) - t.transform(actual, schema) - assert json.dumps(actual) == json.dumps(expected) - if expected_warns: - record = caplog.records[0] - assert record.name == "airbyte" - assert record.levelname == "WARNING" - assert record.message == expected_warns - else: - assert len(caplog.records) == 0 - - -def test_transform_wrong_config(): - with pytest.raises(Exception, match="NoTransform option cannot be combined with other flags."): - TypeTransformer(TransformConfig.NoTransform | TransformConfig.DefaultSchemaNormalization) - - with pytest.raises(Exception, match="Please set TransformConfig.CustomSchemaNormalization config before registering custom normalizer"): - - class NotAStream: - transformer = TypeTransformer(TransformConfig.DefaultSchemaNormalization) - - @transformer.registerCustomTransform - def transform_cb(instance, schema): - pass - - -def test_custom_transform(): - class NotAStream: - transformer = TypeTransformer(TransformConfig.CustomSchemaNormalization) - - @transformer.registerCustomTransform - def transform_cb(instance, schema): - # Check no default conversion applied - assert instance == 12 - assert schema == SIMPLE_SCHEMA["properties"]["value"] - return "transformed" - - s = NotAStream() - obj = {"value": 12} - s.transformer.transform(obj, SIMPLE_SCHEMA) - assert obj == {"value": "transformed"} - - -def test_custom_transform_with_default_normalization(): - class NotAStream: - transformer = TypeTransformer(TransformConfig.CustomSchemaNormalization | TransformConfig.DefaultSchemaNormalization) - - @transformer.registerCustomTransform - def transform_cb(instance, schema): - # Check default conversion applied - assert instance == "12" - assert schema == SIMPLE_SCHEMA["properties"]["value"] - return "transformed" - - s = NotAStream() - obj = {"value": 12} - s.transformer.transform(obj, SIMPLE_SCHEMA) - assert obj == {"value": "transformed"} diff --git a/airbyte-cdk/python/unit_tests/test/__init__.py b/airbyte-cdk/python/unit_tests/test/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/test/mock_http/__init__.py b/airbyte-cdk/python/unit_tests/test/mock_http/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/test/mock_http/test_matcher.py b/airbyte-cdk/python/unit_tests/test/mock_http/test_matcher.py deleted file mode 100644 index 61a9ecfec2f9..000000000000 --- a/airbyte-cdk/python/unit_tests/test/mock_http/test_matcher.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -from unittest import TestCase -from unittest.mock import Mock - -from airbyte_cdk.test.mock_http.matcher import HttpRequestMatcher -from airbyte_cdk.test.mock_http.request import HttpRequest - - -class HttpRequestMatcherTest(TestCase): - def setUp(self) -> None: - self._a_request = Mock(spec=HttpRequest) - self._another_request = Mock(spec=HttpRequest) - self._request_to_match = Mock(spec=HttpRequest) - self._matcher = HttpRequestMatcher(self._request_to_match, 1) - - def test_given_request_matches_when_matches_then_has_expected_match_count(self): - self._a_request.matches.return_value = True - self._matcher.matches(self._a_request) - assert self._matcher.has_expected_match_count() - - def test_given_request_does_not_match_when_matches_then_does_not_have_expected_match_count(self): - self._a_request.matches.return_value = False - self._matcher.matches(self._a_request) - - assert not self._matcher.has_expected_match_count() - assert self._matcher.actual_number_of_matches == 0 - - def test_given_many_requests_with_some_match_when_matches_then_has_expected_match_count(self): - self._a_request.matches.return_value = True - self._another_request.matches.return_value = False - self._matcher.matches(self._a_request) - self._matcher.matches(self._another_request) - - assert self._matcher.has_expected_match_count() - assert self._matcher.actual_number_of_matches == 1 - - def test_given_expected_number_of_requests_met_when_matches_then_has_expected_match_count(self): - _matcher = HttpRequestMatcher(self._request_to_match, 2) - self._a_request.matches.return_value = True - _matcher.matches(self._a_request) - _matcher.matches(self._a_request) - - assert _matcher.has_expected_match_count() - assert _matcher.actual_number_of_matches == 2 - - def test_given_expected_number_of_requests_not_met_when_matches_then_does_not_have_expected_match_count(self): - _matcher = HttpRequestMatcher(self._request_to_match, 2) - self._a_request.matches.side_effect = [True, False] - _matcher.matches(self._a_request) - _matcher.matches(self._a_request) - - assert not _matcher.has_expected_match_count() diff --git a/airbyte-cdk/python/unit_tests/test/mock_http/test_mocker.py b/airbyte-cdk/python/unit_tests/test/mock_http/test_mocker.py deleted file mode 100644 index 2df549e2bb9f..000000000000 --- a/airbyte-cdk/python/unit_tests/test/mock_http/test_mocker.py +++ /dev/null @@ -1,242 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -from unittest import TestCase - -import pytest -import requests -from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse - -# Ensure that the scheme is HTTP as requests only partially supports other schemes -# see https://github.com/psf/requests/blob/0b4d494192de489701d3a2e32acef8fb5d3f042e/src/requests/models.py#L424-L429 -_A_URL = "http://test.com/" -_ANOTHER_URL = "http://another-test.com/" -_A_RESPONSE_BODY = "a body" -_ANOTHER_RESPONSE_BODY = "another body" -_A_RESPONSE = HttpResponse("any response") -_SOME_QUERY_PARAMS = {"q1": "query value"} -_SOME_HEADERS = {"h1": "header value"} -_OTHER_HEADERS = {"h2": "another header value"} -_SOME_REQUEST_BODY_MAPPING = {"first_field": "first_value", "second_field": 2} -_SOME_REQUEST_BODY_STR = "some_request_body" - - -class HttpMockerTest(TestCase): - @HttpMocker() - def test_given_get_request_match_when_decorate_then_return_response(self, http_mocker): - http_mocker.get( - HttpRequest(_A_URL, _SOME_QUERY_PARAMS, _SOME_HEADERS), - HttpResponse(_A_RESPONSE_BODY, 474, _OTHER_HEADERS), - ) - - response = requests.get(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS) - - assert response.text == _A_RESPONSE_BODY - assert response.status_code == 474 - assert response.headers == _OTHER_HEADERS - - @HttpMocker() - def test_given_delete_request_match_when_decorate_then_return_response(self, http_mocker): - http_mocker.delete( - HttpRequest(_A_URL, headers=_SOME_HEADERS), - HttpResponse(_A_RESPONSE_BODY, 204, _OTHER_HEADERS), - ) - - response = requests.delete(_A_URL, headers=_SOME_HEADERS) - - assert response.text == _A_RESPONSE_BODY - assert response.status_code == 204 - assert response.headers == _OTHER_HEADERS - - @HttpMocker() - def test_given_loose_headers_matching_when_decorate_then_match(self, http_mocker): - http_mocker.get( - HttpRequest(_A_URL, _SOME_QUERY_PARAMS, _SOME_HEADERS), - HttpResponse(_A_RESPONSE_BODY, 474), - ) - - requests.get(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS | {"more strict query param key": "any value"}) - - @HttpMocker() - def test_given_post_request_match_when_decorate_then_return_response(self, http_mocker): - http_mocker.post( - HttpRequest(_A_URL, _SOME_QUERY_PARAMS, _SOME_HEADERS, _SOME_REQUEST_BODY_STR), - HttpResponse(_A_RESPONSE_BODY, 474), - ) - - response = requests.post(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS, data=_SOME_REQUEST_BODY_STR) - - assert response.text == _A_RESPONSE_BODY - assert response.status_code == 474 - - @HttpMocker() - def test_given_multiple_responses_when_decorate_get_request_then_return_response(self, http_mocker): - http_mocker.get( - HttpRequest(_A_URL, _SOME_QUERY_PARAMS, _SOME_HEADERS), - [HttpResponse(_A_RESPONSE_BODY, 1), HttpResponse(_ANOTHER_RESPONSE_BODY, 2)], - ) - - first_response = requests.get(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS) - second_response = requests.get(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS) - - assert first_response.text == _A_RESPONSE_BODY - assert first_response.status_code == 1 - assert second_response.text == _ANOTHER_RESPONSE_BODY - assert second_response.status_code == 2 - - @HttpMocker() - def test_given_multiple_responses_when_decorate_delete_request_then_return_response(self, http_mocker): - http_mocker.delete( - HttpRequest(_A_URL, headers=_SOME_HEADERS), - [HttpResponse(_A_RESPONSE_BODY, 1), HttpResponse(_ANOTHER_RESPONSE_BODY, 2)], - ) - - first_response = requests.delete(_A_URL, headers=_SOME_HEADERS) - second_response = requests.delete(_A_URL, headers=_SOME_HEADERS) - - assert first_response.text == _A_RESPONSE_BODY - assert first_response.status_code == 1 - assert second_response.text == _ANOTHER_RESPONSE_BODY - assert second_response.status_code == 2 - - @HttpMocker() - def test_given_multiple_responses_when_decorate_post_request_then_return_response(self, http_mocker): - http_mocker.post( - HttpRequest(_A_URL, _SOME_QUERY_PARAMS, _SOME_HEADERS, _SOME_REQUEST_BODY_STR), - [HttpResponse(_A_RESPONSE_BODY, 1), HttpResponse(_ANOTHER_RESPONSE_BODY, 2)], - ) - - first_response = requests.post(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS, data=_SOME_REQUEST_BODY_STR) - second_response = requests.post(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS, data=_SOME_REQUEST_BODY_STR) - - assert first_response.text == _A_RESPONSE_BODY - assert first_response.status_code == 1 - assert second_response.text == _ANOTHER_RESPONSE_BODY - assert second_response.status_code == 2 - - @HttpMocker() - def test_given_more_requests_than_responses_when_decorate_then_raise_error(self, http_mocker): - http_mocker.get( - HttpRequest(_A_URL, _SOME_QUERY_PARAMS, _SOME_HEADERS), - [HttpResponse(_A_RESPONSE_BODY, 1), HttpResponse(_ANOTHER_RESPONSE_BODY, 2)], - ) - - last_response = [requests.get(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS) for _ in range(10)][-1] - - assert last_response.text == _ANOTHER_RESPONSE_BODY - assert last_response.status_code == 2 - - @HttpMocker() - def test_given_all_requests_match_when_decorate_then_do_not_raise(self, http_mocker): - http_mocker.get( - HttpRequest(_A_URL, _SOME_QUERY_PARAMS, _SOME_HEADERS), - _A_RESPONSE, - ) - requests.get(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS) - - def test_given_missing_requests_when_decorate_then_raise(self): - @HttpMocker() - def decorated_function(http_mocker): - http_mocker.get( - HttpRequest(_A_URL), - _A_RESPONSE, - ) - - with pytest.raises(ValueError) as exc_info: - decorated_function() - assert "Invalid number of matches" in str(exc_info.value) - - def test_given_assertion_error_when_decorate_then_raise_assertion_error(self): - @HttpMocker() - def decorated_function(http_mocker): - http_mocker.get( - HttpRequest(_A_URL), - _A_RESPONSE, - ) - requests.get(_A_URL) - assert False - - with pytest.raises(AssertionError): - decorated_function() - - def test_given_assertion_error_but_missing_request_when_decorate_then_raise_missing_http_request(self): - @HttpMocker() - def decorated_function(http_mocker): - http_mocker.get( - HttpRequest(_A_URL), - _A_RESPONSE, - ) - assert False - - with pytest.raises(ValueError) as exc_info: - decorated_function() - assert "Invalid number of matches" in str(exc_info.value) - - def test_given_request_does_not_match_when_decorate_then_raise(self): - @HttpMocker() - def decorated_function(http_mocker): - http_mocker.get( - HttpRequest(_A_URL), - _A_RESPONSE, - ) - requests.get(_ANOTHER_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS) - - with pytest.raises(ValueError) as exc_info: - decorated_function() - assert "No matcher matches" in str(exc_info.value) - - def test_given_request_matches_multiple_matchers_when_decorate_then_match_first_one(self): - less_granular_headers = {"less_granular": "1"} - more_granular_headers = {"more_granular": "2"} | less_granular_headers - - @HttpMocker() - def decorated_function(http_mocker): - http_mocker.get( - HttpRequest(_A_URL, headers=more_granular_headers), - _A_RESPONSE, - ) - http_mocker.get( - HttpRequest(_A_URL, headers=less_granular_headers), - _A_RESPONSE, - ) - requests.get(_A_URL, headers=more_granular_headers) - - with pytest.raises(ValueError) as exc_info: - decorated_function() - assert "more_granular" in str(exc_info.value) # the matcher corresponding to the first `http_mocker.get` is not matched - - def test_given_exact_number_of_call_provided_when_assert_number_of_calls_then_do_not_raise(self): - @HttpMocker() - def decorated_function(http_mocker): - request = HttpRequest(_A_URL) - http_mocker.get(request, _A_RESPONSE) - - requests.get(_A_URL) - requests.get(_A_URL) - - http_mocker.assert_number_of_calls(request, 2) - - decorated_function() - # then do not raise - - def test_given_invalid_number_of_call_provided_when_assert_number_of_calls_then_raise(self): - @HttpMocker() - def decorated_function(http_mocker): - request = HttpRequest(_A_URL) - http_mocker.get(request, _A_RESPONSE) - - requests.get(_A_URL) - requests.get(_A_URL) - - http_mocker.assert_number_of_calls(request, 1) - - with pytest.raises(AssertionError): - decorated_function() - - def test_given_unknown_request_when_assert_number_of_calls_then_raise(self): - @HttpMocker() - def decorated_function(http_mocker): - http_mocker.get(HttpRequest(_A_URL), _A_RESPONSE) - http_mocker.assert_number_of_calls(HttpRequest(_ANOTHER_URL), 1) - - with pytest.raises(ValueError): - decorated_function() diff --git a/airbyte-cdk/python/unit_tests/test/mock_http/test_request.py b/airbyte-cdk/python/unit_tests/test/mock_http/test_request.py deleted file mode 100644 index a5a94ea05580..000000000000 --- a/airbyte-cdk/python/unit_tests/test/mock_http/test_request.py +++ /dev/null @@ -1,117 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -from unittest import TestCase - -import pytest -from airbyte_cdk.test.mock_http.request import ANY_QUERY_PARAMS, HttpRequest - - -class HttpRequestMatcherTest(TestCase): - def test_given_query_params_as_dict_and_string_then_query_params_are_properly_considered(self): - with_string = HttpRequest("mock://test.com/path", query_params="a_query_param=q1&a_list_param=first&a_list_param=second") - with_dict = HttpRequest("mock://test.com/path", query_params={"a_query_param": "q1", "a_list_param": ["first", "second"]}) - assert with_string.matches(with_dict) and with_dict.matches(with_string) - - def test_given_query_params_in_url_and_also_provided_then_raise_error(self): - with pytest.raises(ValueError): - HttpRequest("mock://test.com/path?a_query_param=1", query_params={"another_query_param": "2"}) - - def test_given_same_url_query_params_and_subset_headers_when_matches_then_return_true(self): - request_to_match = HttpRequest("mock://test.com/path", {"a_query_param": "q1"}, {"first_header": "h1"}) - actual_request = HttpRequest("mock://test.com/path", {"a_query_param": "q1"}, {"first_header": "h1", "second_header": "h2"}) - assert actual_request.matches(request_to_match) - - def test_given_url_differs_when_matches_then_return_false(self): - assert not HttpRequest("mock://test.com/another_path").matches(HttpRequest("mock://test.com/path")) - - def test_given_query_params_differs_when_matches_then_return_false(self): - request_to_match = HttpRequest("mock://test.com/path", {"a_query_param": "q1"}) - actual_request = HttpRequest("mock://test.com/path", {"another_query_param": "q2"}) - assert not actual_request.matches(request_to_match) - - def test_given_query_params_is_subset_differs_when_matches_then_return_false(self): - request_to_match = HttpRequest("mock://test.com/path", {"a_query_param": "q1"}) - actual_request = HttpRequest("mock://test.com/path", {"a_query_param": "q1", "another_query_param": "q2"}) - assert not actual_request.matches(request_to_match) - - def test_given_headers_is_subset_differs_when_matches_then_return_true(self): - request_to_match = HttpRequest("mock://test.com/path", headers={"first_header": "h1"}) - actual_request = HttpRequest("mock://test.com/path", headers={"first_header": "h1", "second_header": "h2"}) - assert actual_request.matches(request_to_match) - - def test_given_headers_value_does_not_match_differs_when_matches_then_return_false(self): - request_to_match = HttpRequest("mock://test.com/path", headers={"first_header": "h1"}) - actual_request = HttpRequest("mock://test.com/path", headers={"first_header": "value does not match"}) - assert not actual_request.matches(request_to_match) - - def test_given_same_body_mappings_value_when_matches_then_return_true(self): - request_to_match = HttpRequest("mock://test.com/path", body={"first_field": "first_value", "second_field": 2}) - actual_request = HttpRequest("mock://test.com/path", body={"first_field": "first_value", "second_field": 2}) - assert actual_request.matches(request_to_match) - - def test_given_bodies_are_mapping_and_differs_when_matches_then_return_false(self): - request_to_match = HttpRequest("mock://test.com/path", body={"first_field": "first_value"}) - actual_request = HttpRequest("mock://test.com/path", body={"first_field": "value does not match"}) - assert not actual_request.matches(request_to_match) - - def test_given_same_mapping_and_bytes_when_matches_then_return_true(self): - request_to_match = HttpRequest("mock://test.com/path", body={"first_field": "first_value"}) - actual_request = HttpRequest("mock://test.com/path", body=b'{"first_field": "first_value"}') - assert actual_request.matches(request_to_match) - - def test_given_different_mapping_and_bytes_when_matches_then_return_false(self): - request_to_match = HttpRequest("mock://test.com/path", body={"first_field": "first_value"}) - actual_request = HttpRequest("mock://test.com/path", body=b'{"first_field": "another value"}') - assert not actual_request.matches(request_to_match) - - def test_given_same_mapping_and_str_when_matches_then_return_true(self): - request_to_match = HttpRequest("mock://test.com/path", body={"first_field": "first_value"}) - actual_request = HttpRequest("mock://test.com/path", body='{"first_field": "first_value"}') - assert actual_request.matches(request_to_match) - - def test_given_different_mapping_and_str_when_matches_then_return_false(self): - request_to_match = HttpRequest("mock://test.com/path", body={"first_field": "first_value"}) - actual_request = HttpRequest("mock://test.com/path", body='{"first_field": "another value"}') - assert not actual_request.matches(request_to_match) - - def test_given_same_bytes_and_mapping_when_matches_then_return_true(self): - request_to_match = HttpRequest("mock://test.com/path", body=b'{"first_field": "first_value"}') - actual_request = HttpRequest("mock://test.com/path", body={"first_field": "first_value"}) - assert actual_request.matches(request_to_match) - - def test_given_different_bytes_and_mapping_when_matches_then_return_false(self): - request_to_match = HttpRequest("mock://test.com/path", body=b'{"first_field": "first_value"}') - actual_request = HttpRequest("mock://test.com/path", body={"first_field": "another value"}) - assert not actual_request.matches(request_to_match) - - def test_given_same_str_and_mapping_when_matches_then_return_true(self): - request_to_match = HttpRequest("mock://test.com/path", body='{"first_field": "first_value"}') - actual_request = HttpRequest("mock://test.com/path", body={"first_field": "first_value"}) - assert actual_request.matches(request_to_match) - - def test_given_different_str_and_mapping_when_matches_then_return_false(self): - request_to_match = HttpRequest("mock://test.com/path", body='{"first_field": "first_value"}') - actual_request = HttpRequest("mock://test.com/path", body={"first_field": "another value"}) - assert not actual_request.matches(request_to_match) - - def test_given_same_body_str_value_when_matches_then_return_true(self): - request_to_match = HttpRequest("mock://test.com/path", body="some_request_body") - actual_request = HttpRequest("mock://test.com/path", body="some_request_body") - assert actual_request.matches(request_to_match) - - def test_given_body_str_value_differs_when_matches_then_return_false(self): - request_to_match = HttpRequest("mock://test.com/path", body="some_request_body") - actual_request = HttpRequest("mock://test.com/path", body="another_request_body") - assert not actual_request.matches(request_to_match) - - def test_given_any_matcher_for_query_param_when_matches_then_return_true(self): - request_to_match = HttpRequest("mock://test.com/path", {"a_query_param": "q1"}) - actual_request = HttpRequest("mock://test.com/path", ANY_QUERY_PARAMS) - - assert actual_request.matches(request_to_match) - assert request_to_match.matches(actual_request) - - def test_given_any_matcher_for_both_when_matches_then_return_true(self): - request_to_match = HttpRequest("mock://test.com/path", ANY_QUERY_PARAMS) - actual_request = HttpRequest("mock://test.com/path", ANY_QUERY_PARAMS) - assert actual_request.matches(request_to_match) diff --git a/airbyte-cdk/python/unit_tests/test/mock_http/test_response_builder.py b/airbyte-cdk/python/unit_tests/test/mock_http/test_response_builder.py deleted file mode 100644 index c8ccdc41b9bf..000000000000 --- a/airbyte-cdk/python/unit_tests/test/mock_http/test_response_builder.py +++ /dev/null @@ -1,175 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -import json -from copy import deepcopy -from pathlib import Path as FilePath -from typing import Any, Dict, Optional, Union -from unittest import TestCase -from unittest.mock import Mock - -import pytest -from airbyte_cdk.test.mock_http.response import HttpResponse -from airbyte_cdk.test.mock_http.response_builder import ( - FieldPath, - FieldUpdatePaginationStrategy, - HttpResponseBuilder, - NestedPath, - PaginationStrategy, - Path, - RecordBuilder, - create_record_builder, - create_response_builder, - find_template, -) - -_RECORDS_FIELD = "records_field" -_ID_FIELD = "record_id" -_CURSOR_FIELD = "record_cursor" -_ANY_RECORD = {"a_record_field": "a record value"} -_SOME_RECORDS = {_RECORDS_FIELD: [_ANY_RECORD]} -_A_RESPONSE_TEMPLATE = _SOME_RECORDS - -_RECORD_BUILDER = 0 -_RESPONSE_BUILDER = 1 - - -def _record_builder( - response_template: Dict[str, Any], - records_path: Union[FieldPath, NestedPath], - record_id_path: Optional[Path] = None, - record_cursor_path: Optional[Union[FieldPath, NestedPath]] = None, -) -> RecordBuilder: - return create_record_builder(deepcopy(response_template), records_path, record_id_path, record_cursor_path) - - -def _any_record_builder() -> RecordBuilder: - return create_record_builder({"record_path": [{"a_record": "record value"}]}, FieldPath("record_path")) - - -def _response_builder( - response_template: Dict[str, Any], records_path: Union[FieldPath, NestedPath], pagination_strategy: Optional[PaginationStrategy] = None -) -> HttpResponseBuilder: - return create_response_builder(deepcopy(response_template), records_path, pagination_strategy=pagination_strategy) - - -def _body(response: HttpResponse) -> Dict[str, Any]: - return json.loads(response.body) - - -class RecordBuilderTest(TestCase): - def test_given_with_id_when_build_then_set_id(self) -> None: - builder = _record_builder({_RECORDS_FIELD: [{_ID_FIELD: "an id"}]}, FieldPath(_RECORDS_FIELD), FieldPath(_ID_FIELD)) - record = builder.with_id("another id").build() - assert record[_ID_FIELD] == "another id" - - def test_given_nested_id_when_build_then_set_id(self) -> None: - builder = _record_builder( - {_RECORDS_FIELD: [{"nested": {_ID_FIELD: "id"}}]}, FieldPath(_RECORDS_FIELD), NestedPath(["nested", _ID_FIELD]) - ) - record = builder.with_id("another id").build() - assert record["nested"][_ID_FIELD] == "another id" - - def test_given_id_path_not_provided_but_with_id_when_build_then_raise_error(self) -> None: - builder = _record_builder(_A_RESPONSE_TEMPLATE, FieldPath(_RECORDS_FIELD), None) - with pytest.raises(ValueError): - builder.with_id("any_id").build() - - def test_given_no_id_in_template_for_path_when_build_then_raise_error(self) -> None: - with pytest.raises(ValueError): - _record_builder({_RECORDS_FIELD: [{"record without id": "should fail"}]}, FieldPath(_RECORDS_FIELD), FieldPath(_ID_FIELD)) - - def test_given_with_cursor_when_build_then_set_id(self) -> None: - builder = _record_builder( - {_RECORDS_FIELD: [{_CURSOR_FIELD: "a cursor"}]}, FieldPath(_RECORDS_FIELD), record_cursor_path=FieldPath(_CURSOR_FIELD) - ) - record = builder.with_cursor("another cursor").build() - assert record[_CURSOR_FIELD] == "another cursor" - - def test_given_nested_cursor_when_build_then_set_cursor(self) -> None: - builder = _record_builder( - {_RECORDS_FIELD: [{"nested": {_CURSOR_FIELD: "a cursor"}}]}, - FieldPath(_RECORDS_FIELD), - record_cursor_path=NestedPath(["nested", _CURSOR_FIELD]), - ) - record = builder.with_cursor("another cursor").build() - assert record["nested"][_CURSOR_FIELD] == "another cursor" - - def test_given_with_field_when_build_then_write_field(self) -> None: - builder = _any_record_builder() - record = builder.with_field(FieldPath("to_write_field"), "a field value").build() - assert record["to_write_field"] == "a field value" - - def test_given_nested_cursor_when_build_then_write_field(self) -> None: - builder = _any_record_builder() - record = builder.with_field(NestedPath(["path", "to_write_field"]), "a field value").build() - assert record["path"]["to_write_field"] == "a field value" - - def test_given_cursor_path_not_provided_but_with_id_when_build_then_raise_error(self) -> None: - builder = _record_builder(_A_RESPONSE_TEMPLATE, FieldPath(_RECORDS_FIELD)) - with pytest.raises(ValueError): - builder.with_cursor("any cursor").build() - - def test_given_no_cursor_in_template_for_path_when_build_then_raise_error(self) -> None: - with pytest.raises(ValueError): - _record_builder( - {_RECORDS_FIELD: [{"record without cursor": "should fail"}]}, - FieldPath(_RECORDS_FIELD), - record_cursor_path=FieldPath(_ID_FIELD), - ) - - -class HttpResponseBuilderTest(TestCase): - def test_given_records_in_template_but_no_with_records_when_build_then_no_records(self) -> None: - builder = _response_builder({_RECORDS_FIELD: [{"a_record_field": "a record value"}]}, FieldPath(_RECORDS_FIELD)) - response = builder.build() - assert len(_body(response)[_RECORDS_FIELD]) == 0 - - def test_given_many_records_when_build_then_response_has_records(self) -> None: - builder = _response_builder(_A_RESPONSE_TEMPLATE, FieldPath(_RECORDS_FIELD)) - a_record_builder = Mock(spec=RecordBuilder) - a_record_builder.build.return_value = {"a record": 1} - another_record_builder = Mock(spec=RecordBuilder) - another_record_builder.build.return_value = {"another record": 2} - - response = builder.with_record(a_record_builder).with_record(another_record_builder).build() - - assert len(_body(response)[_RECORDS_FIELD]) == 2 - - def test_when_build_then_default_status_code_is_200(self) -> None: - builder = _response_builder(_A_RESPONSE_TEMPLATE, FieldPath(_RECORDS_FIELD)) - response = builder.build() - assert response.status_code == 200 - - def test_given_status_code_when_build_then_status_code_is_set(self) -> None: - builder = _response_builder(_A_RESPONSE_TEMPLATE, FieldPath(_RECORDS_FIELD)) - response = builder.with_status_code(239).build() - assert response.status_code == 239 - - def test_given_pagination_with_strategy_when_build_then_apply_strategy(self) -> None: - builder = _response_builder( - {"has_more_pages": False} | _SOME_RECORDS, - FieldPath(_RECORDS_FIELD), - pagination_strategy=FieldUpdatePaginationStrategy(FieldPath("has_more_pages"), "yes more page"), - ) - - response = builder.with_pagination().build() - - assert _body(response)["has_more_pages"] == "yes more page" - - def test_given_no_pagination_strategy_but_pagination_when_build_then_raise_error(self) -> None: - builder = _response_builder(_A_RESPONSE_TEMPLATE, FieldPath(_RECORDS_FIELD)) - with pytest.raises(ValueError): - builder.with_pagination() - - -class UtilMethodsTest(TestCase): - def test_from_resource_file(self) -> None: - template = find_template("test-resource", __file__) - assert template == {"test-source template": "this is a template for test-resource"} - - def test_given_cwd_doesnt_have_unit_tests_as_parent_when_from_resource_file__then_raise_error(self) -> None: - with pytest.raises(ValueError): - find_template("test-resource", str(FilePath(__file__).parent.parent.parent.parent)) - - def test_given_records_path_invalid_when_create_builders_from_resource_then_raise_exception(self) -> None: - with pytest.raises(ValueError): - create_record_builder(_A_RESPONSE_TEMPLATE, NestedPath(["invalid", "record", "path"])) diff --git a/airbyte-cdk/python/unit_tests/test/test_entrypoint_wrapper.py b/airbyte-cdk/python/unit_tests/test/test_entrypoint_wrapper.py deleted file mode 100644 index 11dfc5877572..000000000000 --- a/airbyte-cdk/python/unit_tests/test/test_entrypoint_wrapper.py +++ /dev/null @@ -1,348 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -import json -import logging -import os -from typing import Any, Iterator, List, Mapping, Optional -from unittest import TestCase -from unittest.mock import Mock, patch - -from airbyte_cdk.models import ( - AirbyteAnalyticsTraceMessage, - AirbyteCatalog, - AirbyteErrorTraceMessage, - AirbyteLogMessage, - AirbyteMessage, - AirbyteMessageSerializer, - AirbyteRecordMessage, - AirbyteStateBlob, - AirbyteStateMessage, - AirbyteStreamState, - AirbyteStreamStateSerializer, - AirbyteStreamStatus, - AirbyteStreamStatusTraceMessage, - AirbyteTraceMessage, - ConfiguredAirbyteCatalogSerializer, - Level, - StreamDescriptor, - TraceType, - Type, -) -from airbyte_cdk.sources.abstract_source import AbstractSource -from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, discover, read -from airbyte_cdk.test.state_builder import StateBuilder -from orjson import orjson - - -def _a_state_message(stream_name: str, stream_state: Mapping[str, Any]) -> AirbyteMessage: - return AirbyteMessage( - type=Type.STATE, - state=AirbyteStateMessage( - stream=AirbyteStreamState(stream_descriptor=StreamDescriptor(name=stream_name), stream_state=AirbyteStateBlob(**stream_state)) - ), - ) - - -def _a_status_message(stream_name: str, status: AirbyteStreamStatus) -> AirbyteMessage: - return AirbyteMessage( - type=Type.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - emitted_at=0, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name=stream_name), - status=status, - ), - ), - ) - - -_A_CATALOG_MESSAGE = AirbyteMessage( - type=Type.CATALOG, - catalog=AirbyteCatalog(streams=[]), -) -_A_RECORD = AirbyteMessage( - type=Type.RECORD, record=AirbyteRecordMessage(stream="stream", data={"record key": "record value"}, emitted_at=0) -) -_A_STATE_MESSAGE = _a_state_message("stream_name", {"state key": "state value for _A_STATE_MESSAGE"}) -_A_LOG = AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=Level.INFO, message="This is an Airbyte log message")) -_AN_ERROR_MESSAGE = AirbyteMessage( - type=Type.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.ERROR, - emitted_at=0, - error=AirbyteErrorTraceMessage(message="AirbyteErrorTraceMessage message"), - ), -) -_AN_ANALYTIC_MESSAGE = AirbyteMessage( - type=Type.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.ANALYTICS, - emitted_at=0, - analytics=AirbyteAnalyticsTraceMessage(type="an analytic type", value="an analytic value"), - ), -) - -_A_STREAM_NAME = "a stream name" -_A_CONFIG = {"config_key": "config_value"} -_A_CATALOG = ConfiguredAirbyteCatalogSerializer.load( - { - "streams": [ - { - "stream": { - "name": "a_stream_name", - "json_schema": {}, - "supported_sync_modes": ["full_refresh"], - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "append", - } - ] - } -) -_A_STATE = StateBuilder().with_stream_state(_A_STREAM_NAME, {"state_key": "state_value"}).build() -_A_LOG_MESSAGE = "a log message" - - -def _to_entrypoint_output(messages: List[AirbyteMessage]) -> Iterator[str]: - return (orjson.dumps(AirbyteMessageSerializer.dump(message)).decode() for message in messages) - - -def _a_mocked_source() -> AbstractSource: - source = Mock(spec=AbstractSource) - source.message_repository = None - return source - - -def _validate_tmp_json_file(expected, file_path) -> None: - with open(file_path) as file: - assert json.load(file) == expected - - -def _validate_tmp_catalog(expected, file_path) -> None: - assert ConfiguredAirbyteCatalogSerializer.load( - orjson.loads( - open(file_path).read() - ) - ) == expected - - -def _create_tmp_file_validation(entrypoint, expected_config, expected_catalog: Optional[Any] = None, expected_state: Optional[Any] = None): - def _validate_tmp_files(self): - _validate_tmp_json_file(expected_config, entrypoint.parse_args.call_args.args[0][2]) - if expected_catalog: - _validate_tmp_catalog(expected_catalog, entrypoint.parse_args.call_args.args[0][4]) - if expected_state: - _validate_tmp_json_file(expected_state, entrypoint.parse_args.call_args.args[0][6]) - return entrypoint.return_value.run.return_value - - return _validate_tmp_files - - -class EntrypointWrapperDiscoverTest(TestCase): - def setUp(self) -> None: - self._a_source = _a_mocked_source() - - @staticmethod - def test_init_validation_error(): - invalid_message = '{"type": "INVALID_TYPE"}' - entrypoint_output = EntrypointOutput([invalid_message]) - messages = entrypoint_output._messages - assert len(messages) == 1 - assert messages[0].type == Type.LOG - assert messages[0].log.level == Level.INFO - assert messages[0].log.message == invalid_message - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_when_discover_then_ensure_parameters(self, entrypoint): - entrypoint.return_value.run.side_effect = _create_tmp_file_validation(entrypoint, _A_CONFIG) - - discover(self._a_source, _A_CONFIG) - - entrypoint.assert_called_once_with(self._a_source) - entrypoint.return_value.run.assert_called_once_with(entrypoint.parse_args.return_value) - assert entrypoint.parse_args.call_count == 1 - assert entrypoint.parse_args.call_args.args[0][0] == "discover" - assert entrypoint.parse_args.call_args.args[0][1] == "--config" - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_when_discover_then_ensure_files_are_temporary(self, entrypoint): - discover(self._a_source, _A_CONFIG) - - assert not os.path.exists(entrypoint.parse_args.call_args.args[0][2]) - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_logging_during_discover_when_discover_then_output_has_logs(self, entrypoint): - def _do_some_logging(self): - logging.getLogger("any logger").info(_A_LOG_MESSAGE) - return entrypoint.return_value.run.return_value - - entrypoint.return_value.run.side_effect = _do_some_logging - - output = discover(self._a_source, _A_CONFIG) - - assert len(output.logs) == 1 - assert output.logs[0].log.message == _A_LOG_MESSAGE - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_record_when_discover_then_output_has_record(self, entrypoint): - entrypoint.return_value.run.return_value = _to_entrypoint_output([_A_CATALOG_MESSAGE]) - output = discover(self._a_source, _A_CONFIG) - assert AirbyteMessageSerializer.dump(output.catalog) == AirbyteMessageSerializer.dump(_A_CATALOG_MESSAGE) - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_log_when_discover_then_output_has_log(self, entrypoint): - entrypoint.return_value.run.return_value = _to_entrypoint_output([_A_LOG]) - output = discover(self._a_source, _A_CONFIG) - assert AirbyteMessageSerializer.dump(output.logs[0]) == AirbyteMessageSerializer.dump(_A_LOG) - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_trace_message_when_discover_then_output_has_trace_messages(self, entrypoint): - entrypoint.return_value.run.return_value = _to_entrypoint_output([_AN_ANALYTIC_MESSAGE]) - output = discover(self._a_source, _A_CONFIG) - assert AirbyteMessageSerializer.dump(output.analytics_messages[0]) == AirbyteMessageSerializer.dump(_AN_ANALYTIC_MESSAGE) - - @patch("airbyte_cdk.test.entrypoint_wrapper.print", create=True) - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_unexpected_exception_when_discover_then_print(self, entrypoint, print_mock): - entrypoint.return_value.run.side_effect = ValueError("This error should be printed") - discover(self._a_source, _A_CONFIG) - assert print_mock.call_count > 0 - - @patch("airbyte_cdk.test.entrypoint_wrapper.print", create=True) - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_expected_exception_when_discover_then_do_not_print(self, entrypoint, print_mock): - entrypoint.return_value.run.side_effect = ValueError("This error should not be printed") - discover(self._a_source, _A_CONFIG, expecting_exception=True) - assert print_mock.call_count == 0 - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_uncaught_exception_when_read_then_output_has_error(self, entrypoint): - entrypoint.return_value.run.side_effect = ValueError("An error") - output = discover(self._a_source, _A_CONFIG) - assert output.errors - - -class EntrypointWrapperReadTest(TestCase): - def setUp(self) -> None: - self._a_source = _a_mocked_source() - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_when_read_then_ensure_parameters(self, entrypoint): - entrypoint.return_value.run.side_effect = _create_tmp_file_validation(entrypoint, _A_CONFIG, _A_CATALOG, _A_STATE) - - read(self._a_source, _A_CONFIG, _A_CATALOG, _A_STATE) - - entrypoint.assert_called_once_with(self._a_source) - entrypoint.return_value.run.assert_called_once_with(entrypoint.parse_args.return_value) - assert entrypoint.parse_args.call_count == 1 - assert entrypoint.parse_args.call_args.args[0][0] == "read" - assert entrypoint.parse_args.call_args.args[0][1] == "--config" - assert entrypoint.parse_args.call_args.args[0][3] == "--catalog" - assert entrypoint.parse_args.call_args.args[0][5] == "--state" - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_when_read_then_ensure_files_are_temporary(self, entrypoint): - read(self._a_source, _A_CONFIG, _A_CATALOG, _A_STATE) - - assert not os.path.exists(entrypoint.parse_args.call_args.args[0][2]) - assert not os.path.exists(entrypoint.parse_args.call_args.args[0][4]) - assert not os.path.exists(entrypoint.parse_args.call_args.args[0][6]) - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_logging_during_run_when_read_then_output_has_logs(self, entrypoint): - def _do_some_logging(self): - logging.getLogger("any logger").info(_A_LOG_MESSAGE) - return entrypoint.return_value.run.return_value - - entrypoint.return_value.run.side_effect = _do_some_logging - - output = read(self._a_source, _A_CONFIG, _A_CATALOG, _A_STATE) - - assert len(output.logs) == 1 - assert output.logs[0].log.message == _A_LOG_MESSAGE - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_record_when_read_then_output_has_record(self, entrypoint): - entrypoint.return_value.run.return_value = _to_entrypoint_output([_A_RECORD]) - output = read(self._a_source, _A_CONFIG, _A_CATALOG, _A_STATE) - assert AirbyteMessageSerializer.dump(output.records[0]) == AirbyteMessageSerializer.dump(_A_RECORD) - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_state_message_when_read_then_output_has_state_message(self, entrypoint): - entrypoint.return_value.run.return_value = _to_entrypoint_output([_A_STATE_MESSAGE]) - output = read(self._a_source, _A_CONFIG, _A_CATALOG, _A_STATE) - assert AirbyteMessageSerializer.dump(output.state_messages[0]) == AirbyteMessageSerializer.dump(_A_STATE_MESSAGE) - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_state_message_and_records_when_read_then_output_has_records_and_state_message(self, entrypoint): - entrypoint.return_value.run.return_value = _to_entrypoint_output([_A_RECORD, _A_STATE_MESSAGE]) - output = read(self._a_source, _A_CONFIG, _A_CATALOG, _A_STATE) - assert [AirbyteMessageSerializer.dump(message) for message in output.records_and_state_messages] == [ - AirbyteMessageSerializer.dump(message) for message in (_A_RECORD, _A_STATE_MESSAGE) - ] - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_many_state_messages_and_records_when_read_then_output_has_records_and_state_message(self, entrypoint): - state_value = {"state_key": "last state value"} - last_emitted_state = AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="stream_name"), stream_state=AirbyteStateBlob(**state_value) - ) - entrypoint.return_value.run.return_value = _to_entrypoint_output([_A_STATE_MESSAGE, _a_state_message("stream_name", state_value)]) - - output = read(self._a_source, _A_CONFIG, _A_CATALOG, _A_STATE) - - assert AirbyteStreamStateSerializer.dump(output.most_recent_state) == AirbyteStreamStateSerializer.dump(last_emitted_state) - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_log_when_read_then_output_has_log(self, entrypoint): - entrypoint.return_value.run.return_value = _to_entrypoint_output([_A_LOG]) - output = read(self._a_source, _A_CONFIG, _A_CATALOG, _A_STATE) - assert AirbyteMessageSerializer.dump(output.logs[0]) == AirbyteMessageSerializer.dump(_A_LOG) - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_trace_message_when_read_then_output_has_trace_messages(self, entrypoint): - entrypoint.return_value.run.return_value = _to_entrypoint_output([_AN_ANALYTIC_MESSAGE]) - output = read(self._a_source, _A_CONFIG, _A_CATALOG, _A_STATE) - assert AirbyteMessageSerializer.dump(output.analytics_messages[0]) == AirbyteMessageSerializer.dump(_AN_ANALYTIC_MESSAGE) - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_stream_statuses_when_read_then_return_statuses(self, entrypoint): - status_messages = [ - _a_status_message(_A_STREAM_NAME, AirbyteStreamStatus.STARTED), - _a_status_message(_A_STREAM_NAME, AirbyteStreamStatus.COMPLETE), - ] - entrypoint.return_value.run.return_value = _to_entrypoint_output(status_messages) - output = read(self._a_source, _A_CONFIG, _A_CATALOG, _A_STATE) - assert output.get_stream_statuses(_A_STREAM_NAME) == [AirbyteStreamStatus.STARTED, AirbyteStreamStatus.COMPLETE] - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_stream_statuses_for_many_streams_when_read_then_filter_other_streams(self, entrypoint): - status_messages = [ - _a_status_message(_A_STREAM_NAME, AirbyteStreamStatus.STARTED), - _a_status_message("another stream name", AirbyteStreamStatus.INCOMPLETE), - _a_status_message(_A_STREAM_NAME, AirbyteStreamStatus.COMPLETE), - ] - entrypoint.return_value.run.return_value = _to_entrypoint_output(status_messages) - output = read(self._a_source, _A_CONFIG, _A_CATALOG, _A_STATE) - assert len(output.get_stream_statuses(_A_STREAM_NAME)) == 2 - - @patch("airbyte_cdk.test.entrypoint_wrapper.print", create=True) - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_unexpected_exception_when_read_then_print(self, entrypoint, print_mock): - entrypoint.return_value.run.side_effect = ValueError("This error should be printed") - read(self._a_source, _A_CONFIG, _A_CATALOG, _A_STATE) - assert print_mock.call_count > 0 - - @patch("airbyte_cdk.test.entrypoint_wrapper.print", create=True) - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_expected_exception_when_read_then_do_not_print(self, entrypoint, print_mock): - entrypoint.return_value.run.side_effect = ValueError("This error should not be printed") - read(self._a_source, _A_CONFIG, _A_CATALOG, _A_STATE, expecting_exception=True) - assert print_mock.call_count == 0 - - @patch("airbyte_cdk.test.entrypoint_wrapper.AirbyteEntrypoint") - def test_given_uncaught_exception_when_read_then_output_has_error(self, entrypoint): - entrypoint.return_value.run.side_effect = ValueError("An error") - output = read(self._a_source, _A_CONFIG, _A_CATALOG, _A_STATE) - assert output.errors diff --git a/airbyte-cdk/python/unit_tests/test_config_observation.py b/airbyte-cdk/python/unit_tests/test_config_observation.py deleted file mode 100644 index a182854493dc..000000000000 --- a/airbyte-cdk/python/unit_tests/test_config_observation.py +++ /dev/null @@ -1,88 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import time - -import pytest -from airbyte_cdk.config_observation import ConfigObserver, ObservedDict, create_connector_config_control_message, observe_connector_config -from airbyte_cdk.models import AirbyteControlConnectorConfigMessage, OrchestratorType, Type - - -class TestObservedDict: - def test_update_called_on_set_item(self, mocker): - mock_observer = mocker.Mock() - my_observed_dict = ObservedDict( - {"key": "value", "nested_dict": {"key": "value"}, "list_of_dict": [{"key": "value"}, {"key": "value"}]}, mock_observer - ) - assert mock_observer.update.call_count == 0 - - my_observed_dict["nested_dict"]["key"] = "new_value" - assert mock_observer.update.call_count == 1 - - # Setting the same value again should call observer's update - my_observed_dict["key"] = "new_value" - assert mock_observer.update.call_count == 2 - - my_observed_dict["nested_dict"]["new_key"] = "value" - assert mock_observer.update.call_count == 3 - - my_observed_dict["list_of_dict"][0]["key"] = "new_value" - assert mock_observer.update.call_count == 4 - - my_observed_dict["list_of_dict"][0]["new_key"] = "new_value" - assert mock_observer.update.call_count == 5 - - my_observed_dict["new_list_of_dicts"] = [{"foo": "bar"}] - assert mock_observer.update.call_count == 6 - - my_observed_dict["new_list_of_dicts"][0]["new_key"] = "new_value" - assert mock_observer.update.call_count == 7 - - -class TestConfigObserver: - def test_update(self, capsys): - config_observer = ConfigObserver() - config_observer.set_config(ObservedDict({"key": "value"}, config_observer)) - before_time = time.time() * 1000 - config_observer.update() - after_time = time.time() * 1000 - captured = capsys.readouterr() - airbyte_message = json.loads(captured.out) - assert airbyte_message["type"] == "CONTROL" - assert "control" in airbyte_message - raw_control_message = airbyte_message["control"] - assert raw_control_message["type"] == "CONNECTOR_CONFIG" - assert raw_control_message["connectorConfig"] == {"config": dict(config_observer.config)} - assert before_time < raw_control_message["emitted_at"] < after_time - - -def test_observe_connector_config(capsys): - non_observed_config = {"foo": "bar"} - observed_config = observe_connector_config(non_observed_config) - observer = observed_config.observer - assert isinstance(observed_config, ObservedDict) - assert isinstance(observer, ConfigObserver) - assert observed_config.observer.config == observed_config - observed_config["foo"] = "foo" - captured = capsys.readouterr() - airbyte_message = json.loads(captured.out) - assert airbyte_message["control"]["connectorConfig"] == {"config": {"foo": "foo"}} - - -def test_observe_already_observed_config(): - observed_config = observe_connector_config({"foo": "bar"}) - with pytest.raises(ValueError): - observe_connector_config(observed_config) - - -def test_create_connector_config_control_message(): - A_CONFIG = {"config key": "config value"} - - message = create_connector_config_control_message(A_CONFIG) - - assert message.type == Type.CONTROL - assert message.control.type == OrchestratorType.CONNECTOR_CONFIG - assert message.control.connectorConfig == AirbyteControlConnectorConfigMessage(config=A_CONFIG) - assert message.control.emitted_at is not None diff --git a/airbyte-cdk/python/unit_tests/test_connector.py b/airbyte-cdk/python/unit_tests/test_connector.py deleted file mode 100644 index ea7de2e40695..000000000000 --- a/airbyte-cdk/python/unit_tests/test_connector.py +++ /dev/null @@ -1,133 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import json -import logging -import os -import sys -import tempfile -from pathlib import Path -from typing import Any, Mapping - -import pytest -import yaml -from airbyte_cdk import Connector -from airbyte_cdk.models import AirbyteConnectionStatus - -logger = logging.getLogger("airbyte") - -MODULE = sys.modules[__name__] -MODULE_PATH = os.path.abspath(MODULE.__file__) -SPEC_ROOT = os.path.dirname(MODULE_PATH) - - -class MockConnector(Connector): - def check(self, logger: logging.Logger, config: Mapping[str, Any]) -> AirbyteConnectionStatus: - pass - - -@pytest.fixture() -def mock_config(): - return {"bogus": "file"} - - -@pytest.fixture -def nonempty_file(mock_config): - with tempfile.NamedTemporaryFile("w") as file: - file.write(json.dumps(mock_config)) - file.flush() - yield file - - -@pytest.fixture -def nonjson_file(mock_config): - with tempfile.NamedTemporaryFile("w") as file: - file.write("the content of this file is not JSON") - file.flush() - yield file - - -@pytest.fixture -def integration(): - return MockConnector() - - -def test_read_config(nonempty_file, integration: Connector, mock_config): - actual = integration.read_config(nonempty_file.name) - assert actual == mock_config - - -def test_read_non_json_config(nonjson_file, integration: Connector): - with pytest.raises(ValueError, match="Could not read json file"): - integration.read_config(nonjson_file.name) - - -def test_write_config(integration, mock_config): - config_path = Path(tempfile.gettempdir()) / "config.json" - integration.write_config(mock_config, str(config_path)) - with open(config_path, "r") as actual: - assert json.loads(actual.read()) == mock_config - - -class TestConnectorSpec: - CONNECTION_SPECIFICATION = { - "type": "object", - "required": ["api_token"], - "additionalProperties": False, - "properties": {"api_token": {"type": "string"}}, - } - - @pytest.fixture - def use_json_spec(self): - spec = { - "documentationUrl": "https://airbyte.com/#json", - "connectionSpecification": self.CONNECTION_SPECIFICATION, - } - - json_path = os.path.join(SPEC_ROOT, "spec.json") - with open(json_path, "w") as f: - f.write(json.dumps(spec)) - yield - os.remove(json_path) - - @pytest.fixture - def use_invalid_json_spec(self): - json_path = os.path.join(SPEC_ROOT, "spec.json") - with open(json_path, "w") as f: - f.write("the content of this file is not JSON") - yield - os.remove(json_path) - - @pytest.fixture - def use_yaml_spec(self): - spec = {"documentationUrl": "https://airbyte.com/#yaml", "connectionSpecification": self.CONNECTION_SPECIFICATION} - - yaml_path = os.path.join(SPEC_ROOT, "spec.yaml") - with open(yaml_path, "w") as f: - f.write(yaml.dump(spec)) - yield - os.remove(yaml_path) - - def test_spec_from_json_file(self, integration, use_json_spec): - connector_spec = integration.spec(logger) - assert connector_spec.documentationUrl == "https://airbyte.com/#json" - assert connector_spec.connectionSpecification == self.CONNECTION_SPECIFICATION - - def test_spec_from_improperly_formatted_json_file(self, integration, use_invalid_json_spec): - with pytest.raises(ValueError, match="Could not read json spec file"): - integration.spec(logger) - - def test_spec_from_yaml_file(self, integration, use_yaml_spec): - connector_spec = integration.spec(logger) - assert connector_spec.documentationUrl == "https://airbyte.com/#yaml" - assert connector_spec.connectionSpecification == self.CONNECTION_SPECIFICATION - - def test_multiple_spec_files_raises_exception(self, integration, use_yaml_spec, use_json_spec): - with pytest.raises(RuntimeError, match="spec.yaml or spec.json"): - integration.spec(logger) - - def test_no_spec_file_raises_exception(self, integration): - with pytest.raises(FileNotFoundError, match="Unable to find spec."): - integration.spec(logger) diff --git a/airbyte-cdk/python/unit_tests/test_counter.py b/airbyte-cdk/python/unit_tests/test_counter.py deleted file mode 100644 index 7f17ff7634c2..000000000000 --- a/airbyte-cdk/python/unit_tests/test_counter.py +++ /dev/null @@ -1,55 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from unittest import mock - -from airbyte_cdk.utils.event_timing import create_timer - - -def test_counter_init(): - with create_timer("Counter") as timer: - assert timer.name == "Counter" - - -def test_counter_start_event(): - with create_timer("Counter") as timer: - with mock.patch("airbyte_cdk.utils.event_timing.EventTimer.start_event") as mock_start_event: - timer.start_event("test_event") - mock_start_event.assert_called_with("test_event") - - -def test_counter_finish_event(): - with create_timer("Counter") as timer: - with mock.patch("airbyte_cdk.utils.event_timing.EventTimer.finish_event") as mock_finish_event: - timer.finish_event("test_event") - mock_finish_event.assert_called_with("test_event") - - -def test_timer_multiple_events(): - with create_timer("Counter") as timer: - for i in range(10): - timer.start_event("test_event") - timer.finish_event() - assert timer.count == 10 - - -def test_report_is_ordered_by_name_by_default(): - names = ["j", "b", "g", "d", "e", "f", "c", "h", "i", "a"] - - with create_timer("Source Counter") as timer: - for name in names: - timer.start_event(name) - timer.finish_event() - report = timer.report().split("\n")[1:] # ignore the first line - report_names = [line.split(" ")[0] for line in report] - assert report_names == sorted(names) - - -def test_double_finish_is_safely_ignored(): - with create_timer("Source Counter") as timer: - timer.start_event("test_event") - timer.finish_event() - timer.finish_event() - assert timer.count == 1 diff --git a/airbyte-cdk/python/unit_tests/test_entrypoint.py b/airbyte-cdk/python/unit_tests/test_entrypoint.py deleted file mode 100644 index 123a445054f2..000000000000 --- a/airbyte-cdk/python/unit_tests/test_entrypoint.py +++ /dev/null @@ -1,554 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import os -from argparse import Namespace -from collections import defaultdict -from copy import deepcopy -from typing import Any, List, Mapping, MutableMapping, Union -from unittest import mock -from unittest.mock import MagicMock, patch - -import freezegun -import pytest -import requests -from airbyte_cdk import AirbyteEntrypoint -from airbyte_cdk import entrypoint as entrypoint_module -from airbyte_cdk.models import ( - AirbyteCatalog, - AirbyteConnectionStatus, - AirbyteControlConnectorConfigMessage, - AirbyteControlMessage, - AirbyteMessage, - AirbyteMessageSerializer, - AirbyteRecordMessage, - AirbyteStateBlob, - AirbyteStateMessage, - AirbyteStateStats, - AirbyteStateType, - AirbyteStream, - AirbyteStreamState, - AirbyteStreamStatus, - AirbyteStreamStatusTraceMessage, - AirbyteTraceMessage, - ConnectorSpecification, - FailureType, - OrchestratorType, - Status, - StreamDescriptor, - SyncMode, - TraceType, - Type, -) -from airbyte_cdk.sources import Source -from airbyte_cdk.sources.connector_state_manager import HashableStreamDescriptor -from airbyte_cdk.utils import AirbyteTracedException -from orjson import orjson - - -class MockSource(Source): - def read(self, **kwargs): - pass - - def discover(self, **kwargs): - pass - - def check(self, **kwargs): - pass - - @property - def message_repository(self): - pass - - -def _as_arglist(cmd: str, named_args: Mapping[str, Any]) -> List[str]: - out = [cmd] - for k, v in named_args.items(): - out.append(f"--{k}") - if v: - out.append(v) - return out - - -@pytest.fixture -def spec_mock(mocker): - expected = ConnectorSpecification(connectionSpecification={}) - mock = MagicMock(return_value=expected) - mocker.patch.object(MockSource, "spec", mock) - return mock - - -MESSAGE_FROM_REPOSITORY = AirbyteMessage( - type=Type.CONTROL, - control=AirbyteControlMessage( - type=OrchestratorType.CONNECTOR_CONFIG, - emitted_at=10, - connectorConfig=AirbyteControlConnectorConfigMessage(config={"any config": "a config value"}), - ), -) - - -@pytest.fixture -def entrypoint(mocker) -> AirbyteEntrypoint: - message_repository = MagicMock() - message_repository.consume_queue.side_effect = [[message for message in [MESSAGE_FROM_REPOSITORY]], [], []] - mocker.patch.object(MockSource, "message_repository", new_callable=mocker.PropertyMock, return_value=message_repository) - return AirbyteEntrypoint(MockSource()) - - -def test_airbyte_entrypoint_init(mocker): - mocker.patch.object(entrypoint_module, "init_uncaught_exception_handler") - AirbyteEntrypoint(MockSource()) - entrypoint_module.init_uncaught_exception_handler.assert_called_once_with(entrypoint_module.logger) - - -@pytest.mark.parametrize( - ["cmd", "args", "expected_args"], - [ - ("spec", {"debug": ""}, {"command": "spec", "debug": True}), - ("check", {"config": "config_path"}, {"command": "check", "config": "config_path", "debug": False}), - ("discover", {"config": "config_path", "debug": ""}, {"command": "discover", "config": "config_path", "debug": True}), - ( - "read", - {"config": "config_path", "catalog": "catalog_path", "state": "None"}, - {"command": "read", "config": "config_path", "catalog": "catalog_path", "state": "None", "debug": False}, - ), - ( - "read", - {"config": "config_path", "catalog": "catalog_path", "state": "state_path", "debug": ""}, - {"command": "read", "config": "config_path", "catalog": "catalog_path", "state": "state_path", "debug": True}, - ), - ], -) -def test_parse_valid_args(cmd: str, args: Mapping[str, Any], expected_args, entrypoint: AirbyteEntrypoint): - arglist = _as_arglist(cmd, args) - parsed_args = entrypoint.parse_args(arglist) - assert vars(parsed_args) == expected_args - - -@pytest.mark.parametrize( - ["cmd", "args"], - [ - ("check", {"config": "config_path"}), - ("discover", {"config": "config_path"}), - ("read", {"config": "config_path", "catalog": "catalog_path"}), - ], -) -def test_parse_missing_required_args(cmd: str, args: MutableMapping[str, Any], entrypoint: AirbyteEntrypoint): - required_args = {"check": ["config"], "discover": ["config"], "read": ["config", "catalog"]} - for required_arg in required_args[cmd]: - argcopy = deepcopy(args) - del argcopy[required_arg] - with pytest.raises(BaseException): - entrypoint.parse_args(_as_arglist(cmd, argcopy)) - - -def _wrap_message(submessage: Union[AirbyteConnectionStatus, ConnectorSpecification, AirbyteRecordMessage, AirbyteCatalog]) -> str: - if isinstance(submessage, AirbyteConnectionStatus): - message = AirbyteMessage(type=Type.CONNECTION_STATUS, connectionStatus=submessage) - elif isinstance(submessage, ConnectorSpecification): - message = AirbyteMessage(type=Type.SPEC, spec=submessage) - elif isinstance(submessage, AirbyteCatalog): - message = AirbyteMessage(type=Type.CATALOG, catalog=submessage) - elif isinstance(submessage, AirbyteRecordMessage): - message = AirbyteMessage(type=Type.RECORD, record=submessage) - elif isinstance(submessage, AirbyteTraceMessage): - message = AirbyteMessage(type=Type.TRACE, trace=submessage) - else: - raise Exception(f"Unknown message type: {submessage}") - - return orjson.dumps(AirbyteMessageSerializer.dump(message)).decode() - - -def test_run_spec(entrypoint: AirbyteEntrypoint, mocker): - parsed_args = Namespace(command="spec") - expected = ConnectorSpecification(connectionSpecification={"hi": "hi"}) - mocker.patch.object(MockSource, "spec", return_value=expected) - - messages = list(entrypoint.run(parsed_args)) - - assert [orjson.dumps(AirbyteMessageSerializer.dump(MESSAGE_FROM_REPOSITORY)).decode(), _wrap_message(expected)] == messages - - -@pytest.fixture -def config_mock(mocker, request): - config = request.param if hasattr(request, "param") else {"username": "fake"} - mocker.patch.object(MockSource, "read_config", return_value=config) - mocker.patch.object(MockSource, "configure", return_value=config) - return config - - -@pytest.mark.parametrize( - "config_mock, schema, config_valid", - [ - ({"username": "fake"}, {"type": "object", "properties": {"name": {"type": "string"}}, "additionalProperties": False}, False), - ({"username": "fake"}, {"type": "object", "properties": {"username": {"type": "string"}}, "additionalProperties": False}, True), - ({"username": "fake"}, {"type": "object", "properties": {"user": {"type": "string"}}}, True), - ({"username": "fake"}, {"type": "object", "properties": {"user": {"type": "string", "airbyte_secret": True}}}, True), - ( - {"username": "fake", "_limit": 22}, - {"type": "object", "properties": {"username": {"type": "string"}}, "additionalProperties": False}, - True, - ), - ], - indirect=["config_mock"], -) -def test_config_validate(entrypoint: AirbyteEntrypoint, mocker, config_mock, schema, config_valid): - parsed_args = Namespace(command="check", config="config_path") - check_value = AirbyteConnectionStatus(status=Status.SUCCEEDED) - mocker.patch.object(MockSource, "check", return_value=check_value) - mocker.patch.object(MockSource, "spec", return_value=ConnectorSpecification(connectionSpecification=schema)) - - messages = list(entrypoint.run(parsed_args)) - if config_valid: - assert [orjson.dumps(AirbyteMessageSerializer.dump(MESSAGE_FROM_REPOSITORY)).decode(), _wrap_message(check_value)] == messages - else: - assert len(messages) == 2 - assert messages[0] == orjson.dumps(AirbyteMessageSerializer.dump(MESSAGE_FROM_REPOSITORY)).decode() - connection_status_message = AirbyteMessage(**orjson.loads(messages[1])) - assert connection_status_message.type == Type.CONNECTION_STATUS.value - assert connection_status_message.connectionStatus.get("status") == Status.FAILED.value - assert connection_status_message.connectionStatus.get("message").startswith("Config validation error:") - - -def test_run_check(entrypoint: AirbyteEntrypoint, mocker, spec_mock, config_mock): - parsed_args = Namespace(command="check", config="config_path") - check_value = AirbyteConnectionStatus(status=Status.SUCCEEDED) - mocker.patch.object(MockSource, "check", return_value=check_value) - - messages = list(entrypoint.run(parsed_args)) - - assert [orjson.dumps(AirbyteMessageSerializer.dump(MESSAGE_FROM_REPOSITORY)).decode(), _wrap_message(check_value)] == messages - assert spec_mock.called - - -@freezegun.freeze_time("1970-01-01T00:00:00.001Z") -def test_run_check_with_exception(entrypoint: AirbyteEntrypoint, mocker, spec_mock, config_mock): - exception = ValueError("Any error") - parsed_args = Namespace(command="check", config="config_path") - mocker.patch.object(MockSource, "check", side_effect=exception) - - with pytest.raises(ValueError): - list(entrypoint.run(parsed_args)) - - -@freezegun.freeze_time("1970-01-01T00:00:00.001Z") -def test_run_check_with_traced_exception(entrypoint: AirbyteEntrypoint, mocker, spec_mock, config_mock): - exception = AirbyteTracedException.from_exception(ValueError("Any error")) - parsed_args = Namespace(command="check", config="config_path") - mocker.patch.object(MockSource, "check", side_effect=exception) - - with pytest.raises(AirbyteTracedException): - list(entrypoint.run(parsed_args)) - - -@freezegun.freeze_time("1970-01-01T00:00:00.001Z") -def test_run_check_with_config_error(entrypoint: AirbyteEntrypoint, mocker, spec_mock, config_mock): - exception = AirbyteTracedException.from_exception(ValueError("Any error")) - exception.failure_type = FailureType.config_error - parsed_args = Namespace(command="check", config="config_path") - mocker.patch.object(MockSource, "check", side_effect=exception) - - messages = list(entrypoint.run(parsed_args)) - expected_trace = exception.as_airbyte_message() - expected_trace.emitted_at = 1 - expected_trace.trace.emitted_at = 1 - expected_messages = [ - orjson.dumps(AirbyteMessageSerializer.dump(MESSAGE_FROM_REPOSITORY)).decode(), - orjson.dumps(AirbyteMessageSerializer.dump(expected_trace)).decode(), - _wrap_message( - AirbyteConnectionStatus( - status=Status.FAILED, - message=AirbyteTracedException.from_exception(exception).message - ) - ), - ] - assert messages == expected_messages - - -@freezegun.freeze_time("1970-01-01T00:00:00.001Z") -def test_run_check_with_transient_error(entrypoint: AirbyteEntrypoint, mocker, spec_mock, config_mock): - exception = AirbyteTracedException.from_exception(ValueError("Any error")) - exception.failure_type = FailureType.transient_error - parsed_args = Namespace(command="check", config="config_path") - mocker.patch.object(MockSource, "check", side_effect=exception) - - with pytest.raises(AirbyteTracedException): - list(entrypoint.run(parsed_args)) - - -def test_run_discover(entrypoint: AirbyteEntrypoint, mocker, spec_mock, config_mock): - parsed_args = Namespace(command="discover", config="config_path") - expected = AirbyteCatalog(streams=[AirbyteStream(name="stream", json_schema={"k": "v"}, supported_sync_modes=[SyncMode.full_refresh])]) - mocker.patch.object(MockSource, "discover", return_value=expected) - - messages = list(entrypoint.run(parsed_args)) - - assert [orjson.dumps(AirbyteMessageSerializer.dump(MESSAGE_FROM_REPOSITORY)).decode(), _wrap_message(expected)] == messages - assert spec_mock.called - - -def test_run_discover_with_exception(entrypoint: AirbyteEntrypoint, mocker, spec_mock, config_mock): - parsed_args = Namespace(command="discover", config="config_path") - mocker.patch.object(MockSource, "discover", side_effect=ValueError("Any error")) - - with pytest.raises(ValueError): - messages = list(entrypoint.run(parsed_args)) - assert [orjson.dumps(AirbyteMessageSerializer.dump(MESSAGE_FROM_REPOSITORY)).decode()] == messages - - -def test_run_read(entrypoint: AirbyteEntrypoint, mocker, spec_mock, config_mock): - parsed_args = Namespace(command="read", config="config_path", state="statepath", catalog="catalogpath") - expected = AirbyteRecordMessage(stream="stream", data={"data": "stuff"}, emitted_at=1) - mocker.patch.object(MockSource, "read_state", return_value={}) - mocker.patch.object(MockSource, "read_catalog", return_value={}) - mocker.patch.object(MockSource, "read", return_value=[AirbyteMessage(record=expected, type=Type.RECORD)]) - - messages = list(entrypoint.run(parsed_args)) - - assert [orjson.dumps(AirbyteMessageSerializer.dump(MESSAGE_FROM_REPOSITORY)).decode(), _wrap_message(expected)] == messages - assert spec_mock.called - - -def test_given_message_emitted_during_config_when_read_then_emit_message_before_next_steps( - entrypoint: AirbyteEntrypoint, mocker, spec_mock, config_mock -): - parsed_args = Namespace(command="read", config="config_path", state="statepath", catalog="catalogpath") - mocker.patch.object(MockSource, "read_catalog", side_effect=ValueError) - - messages = entrypoint.run(parsed_args) - assert next(messages) == orjson.dumps(AirbyteMessageSerializer.dump(MESSAGE_FROM_REPOSITORY)).decode() - with pytest.raises(ValueError): - next(messages) - - -def test_run_read_with_exception(entrypoint: AirbyteEntrypoint, mocker, spec_mock, config_mock): - parsed_args = Namespace(command="read", config="config_path", state="statepath", catalog="catalogpath") - mocker.patch.object(MockSource, "read_state", return_value={}) - mocker.patch.object(MockSource, "read_catalog", return_value={}) - mocker.patch.object(MockSource, "read", side_effect=ValueError("Any error")) - - with pytest.raises(ValueError): - messages = list(entrypoint.run(parsed_args)) - assert [orjson.dumps(AirbyteMessageSerializer.dump(MESSAGE_FROM_REPOSITORY)).decode()] == messages - - -def test_invalid_command(entrypoint: AirbyteEntrypoint, config_mock): - with pytest.raises(Exception): - list(entrypoint.run(Namespace(command="invalid", config="conf"))) - - -@pytest.mark.parametrize( - "deployment_mode, url, expected_error", - [ - pytest.param("CLOUD", "https://airbyte.com", None, id="test_cloud_public_endpoint_is_successful"), - pytest.param("CLOUD", "https://192.168.27.30", AirbyteTracedException, id="test_cloud_private_ip_address_is_rejected"), - pytest.param("CLOUD", "https://localhost:8080/api/v1/cast", AirbyteTracedException, id="test_cloud_private_endpoint_is_rejected"), - pytest.param("CLOUD", "http://past.lives.net/api/v1/inyun", ValueError, id="test_cloud_unsecured_endpoint_is_rejected"), - pytest.param("CLOUD", "https://not:very/cash:443.money", ValueError, id="test_cloud_invalid_url_format"), - pytest.param("CLOUD", "https://192.168.27.30 ", ValueError, id="test_cloud_incorrect_ip_format_is_rejected"), - pytest.param("cloud", "https://192.168.27.30", AirbyteTracedException, id="test_case_insensitive_cloud_environment_variable"), - pytest.param("OSS", "https://airbyte.com", None, id="test_oss_public_endpoint_is_successful"), - pytest.param("OSS", "https://192.168.27.30", None, id="test_oss_private_endpoint_is_successful"), - pytest.param("OSS", "https://localhost:8080/api/v1/cast", None, id="test_oss_private_endpoint_is_successful"), - pytest.param("OSS", "http://past.lives.net/api/v1/inyun", None, id="test_oss_unsecured_endpoint_is_successful"), - ], -) -@patch.object(requests.Session, "send", lambda self, request, **kwargs: requests.Response()) -def test_filter_internal_requests(deployment_mode, url, expected_error): - with mock.patch.dict(os.environ, {"DEPLOYMENT_MODE": deployment_mode}, clear=False): - AirbyteEntrypoint(source=MockSource()) - - session = requests.Session() - - prepared_request = requests.PreparedRequest() - prepared_request.method = "GET" - prepared_request.headers = {"header": "value"} - prepared_request.url = url - - if expected_error: - with pytest.raises(expected_error): - session.send(request=prepared_request) - else: - actual_response = session.send(request=prepared_request) - assert isinstance(actual_response, requests.Response) - - -@pytest.mark.parametrize( - "incoming_message, stream_message_count, expected_message, expected_records_by_stream", - [ - pytest.param( - AirbyteMessage(type=Type.RECORD, record=AirbyteRecordMessage(stream="customers", data={"id": "12345"}, emitted_at=1)), - {HashableStreamDescriptor(name="customers"): 100.0}, - AirbyteMessage(type=Type.RECORD, record=AirbyteRecordMessage(stream="customers", data={"id": "12345"}, emitted_at=1)), - {HashableStreamDescriptor(name="customers"): 101.0}, - id="test_handle_record_message", - ), - pytest.param( - AirbyteMessage( - type=Type.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="customers"), stream_state=AirbyteStateBlob(updated_at="2024-02-02") - ), - ), - ), - {HashableStreamDescriptor(name="customers"): 100.0}, - AirbyteMessage( - type=Type.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="customers"), stream_state=AirbyteStateBlob(updated_at="2024-02-02") - ), - sourceStats=AirbyteStateStats(recordCount=100.0), - ), - ), - {HashableStreamDescriptor(name="customers"): 0.0}, - id="test_handle_state_message", - ), - pytest.param( - AirbyteMessage(type=Type.RECORD, record=AirbyteRecordMessage(stream="customers", data={"id": "12345"}, emitted_at=1)), - defaultdict(float), - AirbyteMessage(type=Type.RECORD, record=AirbyteRecordMessage(stream="customers", data={"id": "12345"}, emitted_at=1)), - {HashableStreamDescriptor(name="customers"): 1.0}, - id="test_handle_first_record_message", - ), - pytest.param( - AirbyteMessage( - type=Type.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name="customers"), status=AirbyteStreamStatus.COMPLETE - ), - emitted_at=1, - ), - ), - {HashableStreamDescriptor(name="customers"): 5.0}, - AirbyteMessage( - type=Type.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.STREAM_STATUS, - stream_status=AirbyteStreamStatusTraceMessage( - stream_descriptor=StreamDescriptor(name="customers"), status=AirbyteStreamStatus.COMPLETE - ), - emitted_at=1, - ), - ), - {HashableStreamDescriptor(name="customers"): 5.0}, - id="test_handle_other_message_type", - ), - pytest.param( - AirbyteMessage(type=Type.RECORD, record=AirbyteRecordMessage(stream="others", data={"id": "12345"}, emitted_at=1)), - {HashableStreamDescriptor(name="customers"): 100.0, HashableStreamDescriptor(name="others"): 27.0}, - AirbyteMessage(type=Type.RECORD, record=AirbyteRecordMessage(stream="others", data={"id": "12345"}, emitted_at=1)), - {HashableStreamDescriptor(name="customers"): 100.0, HashableStreamDescriptor(name="others"): 28.0}, - id="test_handle_record_message_for_other_stream", - ), - pytest.param( - AirbyteMessage( - type=Type.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="others"), stream_state=AirbyteStateBlob(updated_at="2024-02-02") - ), - ), - ), - {HashableStreamDescriptor(name="customers"): 100.0, HashableStreamDescriptor(name="others"): 27.0}, - AirbyteMessage( - type=Type.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="others"), stream_state=AirbyteStateBlob(updated_at="2024-02-02") - ), - sourceStats=AirbyteStateStats(recordCount=27.0), - ), - ), - {HashableStreamDescriptor(name="customers"): 100.0, HashableStreamDescriptor(name="others"): 0.0}, - id="test_handle_state_message_for_other_stream", - ), - pytest.param( - AirbyteMessage( - type=Type.RECORD, record=AirbyteRecordMessage(stream="customers", namespace="public", data={"id": "12345"}, emitted_at=1) - ), - {HashableStreamDescriptor(name="customers", namespace="public"): 100.0}, - AirbyteMessage( - type=Type.RECORD, record=AirbyteRecordMessage(stream="customers", namespace="public", data={"id": "12345"}, emitted_at=1) - ), - {HashableStreamDescriptor(name="customers", namespace="public"): 101.0}, - id="test_handle_record_message_with_descriptor", - ), - pytest.param( - AirbyteMessage( - type=Type.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="customers", namespace="public"), - stream_state=AirbyteStateBlob(updated_at="2024-02-02"), - ), - ), - ), - {HashableStreamDescriptor(name="customers", namespace="public"): 100.0}, - AirbyteMessage( - type=Type.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="customers", namespace="public"), - stream_state=AirbyteStateBlob(updated_at="2024-02-02"), - ), - sourceStats=AirbyteStateStats(recordCount=100.0), - ), - ), - {HashableStreamDescriptor(name="customers", namespace="public"): 0.0}, - id="test_handle_state_message_with_descriptor", - ), - pytest.param( - AirbyteMessage( - type=Type.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="others", namespace="public"), - stream_state=AirbyteStateBlob(updated_at="2024-02-02"), - ), - ), - ), - {HashableStreamDescriptor(name="customers", namespace="public"): 100.0}, - AirbyteMessage( - type=Type.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="others", namespace="public"), - stream_state=AirbyteStateBlob(updated_at="2024-02-02"), - ), - sourceStats=AirbyteStateStats(recordCount=0.0), - ), - ), - { - HashableStreamDescriptor(name="customers", namespace="public"): 100.0, - HashableStreamDescriptor(name="others", namespace="public"): 0.0, - }, - id="test_handle_state_message_no_records", - ), - ], -) -def test_handle_record_counts(incoming_message, stream_message_count, expected_message, expected_records_by_stream): - entrypoint = AirbyteEntrypoint(source=MockSource()) - actual_message = entrypoint.handle_record_counts(message=incoming_message, stream_message_count=stream_message_count) - assert actual_message == expected_message - - for stream_descriptor, message_count in stream_message_count.items(): - assert isinstance(message_count, float) - # Python assertions against different number types won't fail if the value is equivalent - assert message_count == expected_records_by_stream[stream_descriptor] - - if actual_message.type == Type.STATE: - assert isinstance(actual_message.state.sourceStats.recordCount, float), "recordCount value should be expressed as a float" diff --git a/airbyte-cdk/python/unit_tests/test_exception_handler.py b/airbyte-cdk/python/unit_tests/test_exception_handler.py deleted file mode 100644 index f135c19fd5a9..000000000000 --- a/airbyte-cdk/python/unit_tests/test_exception_handler.py +++ /dev/null @@ -1,89 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import json -import subprocess -import sys - -import pytest -from airbyte_cdk.exception_handler import assemble_uncaught_exception -from airbyte_cdk.models import ( - AirbyteErrorTraceMessage, - AirbyteLogMessage, - AirbyteMessage, - AirbyteMessageSerializer, - AirbyteTraceMessage, - FailureType, - Level, - TraceType, -) -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.sources.streams.concurrent.exceptions import ExceptionWithDisplayMessage -from airbyte_cdk.utils.traced_exception import AirbyteTracedException - - -def test_given_exception_is_traced_exception_when_assemble_uncaught_exception_then_return_same_exception(): - exception = AirbyteTracedException() - assembled_exception = assemble_uncaught_exception(type(exception), exception) - assert exception == assembled_exception - - -def test_given_exception_not_traced_exception_when_assemble_uncaught_exception_then_return_traced_exception(): - exception = ValueError("any error") - assembled_exception = assemble_uncaught_exception(type(exception), exception) - assert isinstance(assembled_exception, AirbyteTracedException) - - -def test_given_exception_with_display_message_when_assemble_uncaught_exception_then_internal_message_contains_display_message(): - display_message = "some display message" - exception = ExceptionWithDisplayMessage(display_message) - assembled_exception = assemble_uncaught_exception(type(exception), exception) - assert display_message in assembled_exception.internal_message - - -def test_uncaught_exception_handler(): - cmd = "from airbyte_cdk.logger import init_logger; from airbyte_cdk.exception_handler import init_uncaught_exception_handler; logger = init_logger('airbyte'); init_uncaught_exception_handler(logger); raise 1" - exception_message = "exceptions must derive from BaseException" - exception_trace = ( - "Traceback (most recent call last):\n" - ' File "", line 1, in \n' - "TypeError: exceptions must derive from BaseException" - ) - - expected_log_message = AirbyteMessage( - type=MessageType.LOG, log=AirbyteLogMessage(level=Level.FATAL, message=f"{exception_message}\n{exception_trace}") - ) - - expected_trace_message = AirbyteMessage( - type=MessageType.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.ERROR, - emitted_at=0.0, - error=AirbyteErrorTraceMessage( - failure_type=FailureType.system_error, - message="Something went wrong in the connector. See the logs for more details.", - internal_message=exception_message, - stack_trace=f"{exception_trace}\n", - ), - ), - ) - - with pytest.raises(subprocess.CalledProcessError) as err: - subprocess.check_output([sys.executable, "-c", cmd], stderr=subprocess.STDOUT) - - assert not err.value.stderr, "nothing on the stderr" - - stdout_lines = err.value.output.decode("utf-8").strip().split("\n") - assert len(stdout_lines) == 2 - - log_output, trace_output = stdout_lines - - out_log_message = AirbyteMessageSerializer.load(json.loads(log_output)) - assert out_log_message == expected_log_message, "Log message should be emitted in expected form" - - out_trace_message = AirbyteMessageSerializer.load(json.loads(trace_output)) - assert out_trace_message.trace.emitted_at > 0 - out_trace_message.trace.emitted_at = 0.0 # set a specific emitted_at value for testing - assert out_trace_message == expected_trace_message, "Trace message should be emitted in expected form" diff --git a/airbyte-cdk/python/unit_tests/test_logger.py b/airbyte-cdk/python/unit_tests/test_logger.py deleted file mode 100644 index 3b6db8b89232..000000000000 --- a/airbyte-cdk/python/unit_tests/test_logger.py +++ /dev/null @@ -1,97 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import logging -from typing import Dict - -import pytest -from airbyte_cdk.logger import AirbyteLogFormatter - - -@pytest.fixture(scope="session") -def logger(): - logger = logging.getLogger("airbyte.Testlogger") - return logger - - -def test_formatter(logger, caplog): - formatter = AirbyteLogFormatter() - logger.info("Test formatter") - record = caplog.records[0] - formatted_record = formatter.format(record) - formatted_record_data = json.loads(formatted_record) - assert formatted_record_data.get("type") == "LOG" - log = formatted_record_data.get("log") - assert isinstance(log, Dict) - level = log.get("level") - message = log.get("message") - assert level == "INFO" - assert message == "Test formatter" - - -def test_level_transform(logger, caplog): - formatter = AirbyteLogFormatter() - logger.warning("Test level transform warn") - logger.critical("Test level transform critical") - record_warn = caplog.records[0] - record_critical = caplog.records[1] - formatted_record_warn = formatter.format(record_warn) - formatted_record_warn_data = json.loads(formatted_record_warn) - log_warn = formatted_record_warn_data.get("log") - level_warn = log_warn.get("level") - formatted_record_critical = formatter.format(record_critical) - formatted_record_critical_data = json.loads(formatted_record_critical) - log_critical = formatted_record_critical_data.get("log") - level_critical = log_critical.get("level") - assert level_warn == "WARN" - assert level_critical == "FATAL" - - -def test_debug(logger, caplog): - # Test debug logger in isolation since the default logger is initialized to TRACE (15) instead of DEBUG (10). - formatter = AirbyteLogFormatter() - debug_logger = logging.getLogger("airbyte.Debuglogger") - debug_logger.setLevel(logging.DEBUG) - debug_logger.debug("Test debug 1", extra={"extra_field": "extra value"}) - record = caplog.records[0] - formatted_record = json.loads(formatter.format(record)) - assert formatted_record["type"] == "DEBUG" - assert formatted_record["message"] == "Test debug 1" - assert formatted_record["data"]["extra_field"] == "extra value" - - -def test_default_debug_is_ignored(logger, caplog): - logger.debug("Test debug that is ignored since log level is TRACE") - assert len(caplog.records) == 0 - - -def test_info(logger, caplog): - logger.info("Test info 1") - logger.info("Test info 2") - assert len(caplog.records) == 2 - first_record = caplog.records[0] - assert first_record.levelname == "INFO" - assert first_record.message == "Test info 1" - - -def test_warn(logger, caplog): - logger.warn("Test warn 1") - record = caplog.records[0] - assert record.levelname == "WARNING" - assert record.message == "Test warn 1" - - -def test_error(logger, caplog): - logger.error("Test error 1") - record = caplog.records[0] - assert record.levelname == "ERROR" - assert record.message == "Test error 1" - - -def test_fatal(logger, caplog): - logger.fatal("Test fatal 1") - record = caplog.records[0] - assert record.levelname == "CRITICAL" - assert record.message == "Test fatal 1" diff --git a/airbyte-cdk/python/unit_tests/test_secure_logger.py b/airbyte-cdk/python/unit_tests/test_secure_logger.py deleted file mode 100644 index 44e0a3d9006c..000000000000 --- a/airbyte-cdk/python/unit_tests/test_secure_logger.py +++ /dev/null @@ -1,240 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import logging -import sys -from argparse import Namespace -from typing import Any, Iterable, Mapping, MutableMapping - -import pytest -from airbyte_cdk import AirbyteEntrypoint -from airbyte_cdk.logger import AirbyteLogFormatter -from airbyte_cdk.models import AirbyteMessage, AirbyteRecordMessage, ConfiguredAirbyteCatalog, ConnectorSpecification, Type -from airbyte_cdk.sources import Source - -SECRET_PROPERTY = "api_token" -ANOTHER_SECRET_PROPERTY = "another_api_token" -ANOTHER_NOT_SECRET_PROPERTY = "not_secret_property" - -NOT_SECRET_PROPERTY = "explicitly_not_secret_property" - -I_AM_A_SECRET_VALUE = "I am a secret" -ANOTHER_SECRET_VALUE = "Another secret" -SECRET_INTEGER_VALUE = 123456789 -NOT_A_SECRET_VALUE = "I am not a secret" -ANOTHER_NOT_SECRET_VALUE = "I am not a secret" - - -class MockSource(Source): - def read( - self, - logger: logging.Logger, - config: Mapping[str, Any], - catalog: ConfiguredAirbyteCatalog, - state: MutableMapping[str, Any] = None, - ) -> Iterable[AirbyteMessage]: - logger.info(I_AM_A_SECRET_VALUE) - logger.info(I_AM_A_SECRET_VALUE + " plus Some non secret Value in the same log record" + NOT_A_SECRET_VALUE) - logger.info(NOT_A_SECRET_VALUE) - yield AirbyteMessage( - record=AirbyteRecordMessage(stream="stream", data={"data": "stuff"}, emitted_at=1), - type=Type.RECORD, - ) - - def discover(self, **kwargs): - pass - - def check(self, **kwargs): - pass - - -spec_with_airbyte_secrets = { - "type": "object", - "required": ["api_token"], - "additionalProperties": False, - "properties": { - SECRET_PROPERTY: {"type": "string", "airbyte_secret": True}, - NOT_SECRET_PROPERTY: {"type": "string", "airbyte_secret": False}, - }, -} - -spec_with_airbyte_secrets_config = { - SECRET_PROPERTY: I_AM_A_SECRET_VALUE, - NOT_SECRET_PROPERTY: NOT_A_SECRET_VALUE, -} - -spec_with_multiple_airbyte_secrets = { - "type": "object", - "required": ["api_token"], - "additionalProperties": True, - "properties": { - SECRET_PROPERTY: {"type": "string", "airbyte_secret": True}, - ANOTHER_SECRET_PROPERTY: {"type": "string", "airbyte_secret": True}, - NOT_SECRET_PROPERTY: {"type": "string", "airbyte_secret": False}, - ANOTHER_NOT_SECRET_PROPERTY: {"type": "string"}, - }, -} - -spec_with_multiple_airbyte_secrets_config = { - SECRET_PROPERTY: I_AM_A_SECRET_VALUE, - NOT_SECRET_PROPERTY: NOT_A_SECRET_VALUE, - ANOTHER_SECRET_PROPERTY: ANOTHER_SECRET_VALUE, - ANOTHER_NOT_SECRET_PROPERTY: ANOTHER_NOT_SECRET_VALUE, -} - -spec_with_airbyte_secrets_not_string = { - "type": "object", - "required": ["api_token"], - "additionalProperties": True, - "properties": { - SECRET_PROPERTY: {"type": "string", "airbyte_secret": True}, - ANOTHER_SECRET_PROPERTY: {"type": "integer", "airbyte_secret": True}, - }, -} - -spec_with_airbyte_secrets_not_string_config = { - SECRET_PROPERTY: I_AM_A_SECRET_VALUE, - ANOTHER_SECRET_PROPERTY: SECRET_INTEGER_VALUE, -} - - -@pytest.fixture -def simple_config(): - yield { - SECRET_PROPERTY: I_AM_A_SECRET_VALUE, - ANOTHER_SECRET_PROPERTY: ANOTHER_SECRET_VALUE, - } - - -@pytest.mark.parametrize( - "source_spec, config", - [ - [spec_with_airbyte_secrets, spec_with_airbyte_secrets_config], - [spec_with_multiple_airbyte_secrets, spec_with_multiple_airbyte_secrets_config], - [ - spec_with_airbyte_secrets_not_string, - spec_with_airbyte_secrets_not_string_config, - ], - ], - ids=[ - "spec_with_airbyte_secrets", - "spec_with_multiple_airbyte_secrets", - "spec_with_airbyte_secrets_not_string", - ], -) -def test_airbyte_secret_is_masked_on_logger_output(source_spec, mocker, config, caplog): - caplog.set_level(logging.DEBUG, logger="airbyte.test") - caplog.handler.setFormatter(AirbyteLogFormatter()) - entrypoint = AirbyteEntrypoint(MockSource()) - parsed_args = Namespace(command="read", config="", state="", catalog="") - mocker.patch.object( - MockSource, - "spec", - return_value=ConnectorSpecification(connectionSpecification=source_spec), - ) - mocker.patch.object(MockSource, "configure", return_value=config) - mocker.patch.object(MockSource, "read_config", return_value=None) - mocker.patch.object(MockSource, "read_state", return_value={}) - mocker.patch.object(MockSource, "read_catalog", return_value={}) - list(entrypoint.run(parsed_args)) - log_result = caplog.text - expected_secret_values = [config[k] for k, v in source_spec["properties"].items() if v.get("airbyte_secret")] - expected_plain_text_values = [config[k] for k, v in source_spec["properties"].items() if not v.get("airbyte_secret")] - assert all([str(v) not in log_result for v in expected_secret_values]) - assert all([str(v) in log_result for v in expected_plain_text_values]) - - -def test_airbyte_secrets_are_masked_on_uncaught_exceptions(mocker, caplog, capsys): - caplog.set_level(logging.DEBUG, logger="airbyte.test") - caplog.handler.setFormatter(AirbyteLogFormatter()) - - class BrokenSource(MockSource): - def read( - self, - logger: logging.Logger, - config: Mapping[str, Any], - catalog: ConfiguredAirbyteCatalog, - state: MutableMapping[str, Any] = None, - ): - raise Exception("Exception:" + I_AM_A_SECRET_VALUE) - - entrypoint = AirbyteEntrypoint(BrokenSource()) - parsed_args = Namespace(command="read", config="", state="", catalog="") - source_spec = { - "type": "object", - "required": ["api_token"], - "additionalProperties": False, - "properties": { - SECRET_PROPERTY: {"type": "string", "airbyte_secret": True}, - NOT_SECRET_PROPERTY: {"type": "string", "airbyte_secret": False}, - }, - } - simple_config = { - SECRET_PROPERTY: I_AM_A_SECRET_VALUE, - NOT_SECRET_PROPERTY: NOT_A_SECRET_VALUE, - } - mocker.patch.object( - MockSource, - "spec", - return_value=ConnectorSpecification(connectionSpecification=source_spec), - ) - mocker.patch.object(MockSource, "configure", return_value=simple_config) - mocker.patch.object(MockSource, "read_config", return_value=None) - mocker.patch.object(MockSource, "read_state", return_value={}) - mocker.patch.object(MockSource, "read_catalog", return_value={}) - - try: - list(entrypoint.run(parsed_args)) - except Exception: - sys.excepthook(*sys.exc_info()) - assert I_AM_A_SECRET_VALUE not in capsys.readouterr().out, "Should have filtered non-secret value from exception trace message" - assert I_AM_A_SECRET_VALUE not in caplog.text, "Should have filtered secret value from exception log message" - - -def test_non_airbyte_secrets_are_not_masked_on_uncaught_exceptions(mocker, caplog, capsys): - caplog.set_level(logging.DEBUG, logger="airbyte.test") - caplog.handler.setFormatter(AirbyteLogFormatter()) - - class BrokenSource(MockSource): - def read( - self, - logger: logging.Logger, - config: Mapping[str, Any], - catalog: ConfiguredAirbyteCatalog, - state: MutableMapping[str, Any] = None, - ): - raise Exception("Exception:" + NOT_A_SECRET_VALUE) - - entrypoint = AirbyteEntrypoint(BrokenSource()) - parsed_args = Namespace(command="read", config="", state="", catalog="") - source_spec = { - "type": "object", - "required": ["api_token"], - "additionalProperties": False, - "properties": { - SECRET_PROPERTY: {"type": "string", "airbyte_secret": True}, - NOT_SECRET_PROPERTY: {"type": "string", "airbyte_secret": False}, - }, - } - simple_config = { - SECRET_PROPERTY: I_AM_A_SECRET_VALUE, - NOT_SECRET_PROPERTY: NOT_A_SECRET_VALUE, - } - mocker.patch.object( - MockSource, - "spec", - return_value=ConnectorSpecification(connectionSpecification=source_spec), - ) - mocker.patch.object(MockSource, "configure", return_value=simple_config) - mocker.patch.object(MockSource, "read_config", return_value=None) - mocker.patch.object(MockSource, "read_state", return_value={}) - mocker.patch.object(MockSource, "read_catalog", return_value={}) - mocker.patch.object(MockSource, "read", side_effect=Exception("Exception:" + NOT_A_SECRET_VALUE)) - - try: - list(entrypoint.run(parsed_args)) - except Exception: - sys.excepthook(*sys.exc_info()) - assert NOT_A_SECRET_VALUE in capsys.readouterr().out, "Should not have filtered non-secret value from exception trace message" - assert NOT_A_SECRET_VALUE in caplog.text, "Should not have filtered non-secret value from exception log message" diff --git a/airbyte-cdk/python/unit_tests/utils/__init__.py b/airbyte-cdk/python/unit_tests/utils/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/airbyte-cdk/python/unit_tests/utils/test_datetime_format_inferrer.py b/airbyte-cdk/python/unit_tests/utils/test_datetime_format_inferrer.py deleted file mode 100644 index 5e76b9cfa193..000000000000 --- a/airbyte-cdk/python/unit_tests/utils/test_datetime_format_inferrer.py +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Dict, List - -import pytest -from airbyte_cdk.models import AirbyteRecordMessage -from airbyte_cdk.utils.datetime_format_inferrer import DatetimeFormatInferrer - -NOW = 1234567 - - -@pytest.mark.parametrize( - "test_name,input_records,expected_candidate_fields", - [ - ("empty", [], {}), - ("simple_match", [{"d": "2022-02-03"}], {"d": "%Y-%m-%d"}), - ("timestamp_match_integer", [{"d": 1686058051}], {"d": "%s"}), - ("timestamp_match_string", [{"d": "1686058051"}], {"d": "%s"}), - ("timestamp_ms_match_integer", [{"d": 1686058051000}], {"d": "%ms"}), - ("timestamp_ms_match_string", [{"d": "1686058051000"}], {"d": "%ms"}), - ("timestamp_no_match_integer", [{"d": 99}], {}), - ("timestamp_no_match_string", [{"d": "99999999999999999999"}], {}), - ("timestamp_overflow", [{"d": f"{10**100}_100"}], {}), # this case was previously causing OverflowError hence this test - ("simple_no_match", [{"d": "20220203"}], {}), - ("multiple_match", [{"d": "2022-02-03", "e": "2022-02-03"}], {"d": "%Y-%m-%d", "e": "%Y-%m-%d"}), - ( - "multiple_no_match", - [{"d": "20220203", "r": "ccc", "e": {"something-else": "2023-03-03"}, "s": ["2023-03-03"], "x": False, "y": 123}], - {}, - ), - ("format_1", [{"d": "2022-02-03"}], {"d": "%Y-%m-%d"}), - ("format_2", [{"d": "2022-02-03 12:34:56"}], {"d": "%Y-%m-%d %H:%M:%S"}), - ("format_3", [{"d": "2022-02-03T12:34:56Z"}], {"d": "%Y-%m-%dT%H:%M:%SZ"}), - ("format_4 1", [{"d": "2022-02-03T12:34:56.000Z"}], {"d": "%Y-%m-%dT%H:%M:%S.%fZ"}), - ("format_4 2", [{"d": "2022-02-03T12:34:56.000000Z"}], {"d": "%Y-%m-%dT%H:%M:%S.%fZ"}), - ("format_5", [{"d": "2022-02-03 12:34:56.123456+00:00"}], {"d": "%Y-%m-%d %H:%M:%S.%f%z"}), - ("format_5 2", [{"d": "2022-02-03 12:34:56.123456+02:00"}], {"d": "%Y-%m-%d %H:%M:%S.%f%z"}), - ("format_6", [{"d": "2022-02-03T12:34:56.123456+0000"}], {"d": "%Y-%m-%dT%H:%M:%S.%f%z"}), - ("format_6 2", [{"d": "2022-02-03T12:34:56.123456+00:00"}], {"d": "%Y-%m-%dT%H:%M:%S.%f%z"}), - ("format_6 3", [{"d": "2022-02-03T12:34:56.123456-03:00"}], {"d": "%Y-%m-%dT%H:%M:%S.%f%z"}), - ("format_7", [{"d": "03/02/2022 12:34"}], {"d": "%d/%m/%Y %H:%M"}), - ("format_8", [{"d": "2022-02"}], {"d": "%Y-%m"}), - ("format_9", [{"d": "03-02-2022"}], {"d": "%d-%m-%Y"}), - ("limit_down", [{"d": "2022-02-03", "x": "2022-02-03"}, {"d": "2022-02-03", "x": "another thing"}], {"d": "%Y-%m-%d"}), - ("limit_down all", [{"d": "2022-02-03", "x": "2022-02-03"}, {"d": "also another thing", "x": "another thing"}], {}), - ("limit_down empty", [{"d": "2022-02-03", "x": "2022-02-03"}, {}], {}), - ("limit_down unsupported type", [{"d": "2022-02-03"}, {"d": False}], {}), - ("limit_down complex type", [{"d": "2022-02-03"}, {"d": {"date": "2022-03-03"}}], {}), - ("limit_down different format", [{"d": "2022-02-03"}, {"d": 1686058051}], {}), - ("limit_down different format", [{"d": "2022-02-03"}, {"d": "2022-02-03T12:34:56.000000Z"}], {}), - ("no scope expand", [{}, {"d": "2022-02-03"}], {}), - ], -) -def test_schema_inferrer(test_name, input_records: List, expected_candidate_fields: Dict[str, str]): - inferrer = DatetimeFormatInferrer() - for record in input_records: - inferrer.accumulate(AirbyteRecordMessage(stream="abc", data=record, emitted_at=NOW)) - assert inferrer.get_inferred_datetime_formats() == expected_candidate_fields diff --git a/airbyte-cdk/python/unit_tests/utils/test_mapping_helpers.py b/airbyte-cdk/python/unit_tests/utils/test_mapping_helpers.py deleted file mode 100644 index f5dc979e3477..000000000000 --- a/airbyte-cdk/python/unit_tests/utils/test_mapping_helpers.py +++ /dev/null @@ -1,54 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -from airbyte_cdk.utils.mapping_helpers import combine_mappings - - -def test_basic_merge(): - mappings = [{"a": 1}, {"b": 2}, {"c": 3}, {}] - result = combine_mappings(mappings) - assert result == {"a": 1, "b": 2, "c": 3} - - -def test_combine_with_string(): - mappings = [{"a": 1}, "option"] - with pytest.raises(ValueError, match="Cannot combine multiple options if one is a string"): - combine_mappings(mappings) - - -def test_overlapping_keys(): - mappings = [{"a": 1, "b": 2}, {"b": 3}] - with pytest.raises(ValueError, match="Duplicate keys found"): - combine_mappings(mappings) - - -def test_multiple_strings(): - mappings = ["option1", "option2"] - with pytest.raises(ValueError, match="Cannot combine multiple string options"): - combine_mappings(mappings) - - -def test_handle_none_values(): - mappings = [{"a": 1}, None, {"b": 2}] - result = combine_mappings(mappings) - assert result == {"a": 1, "b": 2} - - -def test_empty_mappings(): - mappings = [] - result = combine_mappings(mappings) - assert result == {} - - -def test_single_mapping(): - mappings = [{"a": 1}] - result = combine_mappings(mappings) - assert result == {"a": 1} - - -def test_combine_with_string_and_empty_mappings(): - mappings = ["option", {}] - result = combine_mappings(mappings) - assert result == "option" diff --git a/airbyte-cdk/python/unit_tests/utils/test_message_utils.py b/airbyte-cdk/python/unit_tests/utils/test_message_utils.py deleted file mode 100644 index 84fabf1a8fa8..000000000000 --- a/airbyte-cdk/python/unit_tests/utils/test_message_utils.py +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -import pytest -from airbyte_cdk.models import ( - AirbyteControlConnectorConfigMessage, - AirbyteControlMessage, - AirbyteMessage, - AirbyteRecordMessage, - AirbyteStateBlob, - AirbyteStateMessage, - AirbyteStateStats, - AirbyteStateType, - AirbyteStreamState, - OrchestratorType, - StreamDescriptor, - Type, -) -from airbyte_cdk.sources.connector_state_manager import HashableStreamDescriptor -from airbyte_cdk.utils.message_utils import get_stream_descriptor - - -def test_get_record_message_stream_descriptor(): - message = AirbyteMessage( - type=Type.RECORD, - record=AirbyteRecordMessage( - stream="test_stream", - namespace="test_namespace", - data={"id": "12345"}, - emitted_at=1, - ), - ) - expected_descriptor = HashableStreamDescriptor(name="test_stream", namespace="test_namespace") - assert get_stream_descriptor(message) == expected_descriptor - - -def test_get_record_message_stream_descriptor_no_namespace(): - message = AirbyteMessage( - type=Type.RECORD, - record=AirbyteRecordMessage(stream="test_stream", data={"id": "12345"}, emitted_at=1), - ) - expected_descriptor = HashableStreamDescriptor(name="test_stream", namespace=None) - assert get_stream_descriptor(message) == expected_descriptor - - -def test_get_state_message_stream_descriptor(): - message = AirbyteMessage( - type=Type.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="test_stream", namespace="test_namespace"), - stream_state=AirbyteStateBlob(updated_at="2024-02-02"), - ), - sourceStats=AirbyteStateStats(recordCount=27.0), - ), - ) - expected_descriptor = HashableStreamDescriptor(name="test_stream", namespace="test_namespace") - assert get_stream_descriptor(message) == expected_descriptor - - -def test_get_state_message_stream_descriptor_no_namespace(): - message = AirbyteMessage( - type=Type.STATE, - state=AirbyteStateMessage( - type=AirbyteStateType.STREAM, - stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name="test_stream"), - stream_state=AirbyteStateBlob(updated_at="2024-02-02"), - ), - sourceStats=AirbyteStateStats(recordCount=27.0), - ), - ) - expected_descriptor = HashableStreamDescriptor(name="test_stream", namespace=None) - assert get_stream_descriptor(message) == expected_descriptor - - -def test_get_other_message_stream_descriptor_fails(): - message = AirbyteMessage( - type=Type.CONTROL, - control=AirbyteControlMessage( - type=OrchestratorType.CONNECTOR_CONFIG, - emitted_at=10, - connectorConfig=AirbyteControlConnectorConfigMessage(config={"any config": "a config value"}), - ), - ) - with pytest.raises(NotImplementedError): - get_stream_descriptor(message) diff --git a/airbyte-cdk/python/unit_tests/utils/test_rate_limiting.py b/airbyte-cdk/python/unit_tests/utils/test_rate_limiting.py deleted file mode 100644 index bc9d3ece61b8..000000000000 --- a/airbyte-cdk/python/unit_tests/utils/test_rate_limiting.py +++ /dev/null @@ -1,27 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -from airbyte_cdk.sources.streams.http.rate_limiting import default_backoff_handler -from requests import exceptions - - -def helper_with_exceptions(exception_type): - raise exception_type - - -@pytest.mark.usefixtures("mock_sleep") -@pytest.mark.parametrize( - "max_tries, max_time, factor, exception_to_raise", - [ - (1, None, 1, exceptions.ConnectTimeout), - (1, 1, 0, exceptions.ReadTimeout), - (2, 2, 1, exceptions.ConnectionError), - (3, 3, 1, exceptions.ChunkedEncodingError), - ], -) -def test_default_backoff_handler(max_tries: int, max_time: int, factor: int, exception_to_raise: Exception): - backoff_handler = default_backoff_handler(max_tries=max_tries, max_time=max_time, factor=factor)(helper_with_exceptions) - with pytest.raises(exception_to_raise): - backoff_handler(exception_to_raise) diff --git a/airbyte-cdk/python/unit_tests/utils/test_schema_inferrer.py b/airbyte-cdk/python/unit_tests/utils/test_schema_inferrer.py deleted file mode 100644 index 98d227c40ec6..000000000000 --- a/airbyte-cdk/python/unit_tests/utils/test_schema_inferrer.py +++ /dev/null @@ -1,351 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import List, Mapping - -import pytest -from airbyte_cdk.models import AirbyteRecordMessage -from airbyte_cdk.utils.schema_inferrer import SchemaInferrer, SchemaValidationException - -NOW = 1234567 - - -@pytest.mark.parametrize( - "input_records,expected_schemas", - [ - pytest.param( - [ - {"stream": "my_stream", "data": {"field_A": "abc"}}, - {"stream": "my_stream", "data": {"field_A": "def"}}, - ], - {"my_stream": {"field_A": {"type": ["string", "null"]}}}, - id="test_basic", - ), - pytest.param( - [ - {"stream": "my_stream", "data": {"field_A": 1.0}}, - {"stream": "my_stream", "data": {"field_A": "abc"}}, - ], - {"my_stream": {"field_A": {"type": ["number", "string", "null"]}}}, - id="test_deriving_schema_refine", - ), - pytest.param( - [ - {"stream": "my_stream", "data": {"obj": {"data": [1.0, 2.0, 3.0]}}}, - {"stream": "my_stream", "data": {"obj": {"other_key": "xyz"}}}, - ], - { - "my_stream": { - "obj": { - "type": ["object", "null"], - "properties": { - "data": {"type": ["array", "null"], "items": {"type": ["number", "null"]}}, - "other_key": {"type": ["string", "null"]}, - }, - } - } - }, - id="test_derive_schema_for_nested_structures", - ), - pytest.param( - [ - {"stream": "my_stream", "data": {"field_A": 1}}, - {"stream": "my_stream", "data": {"field_A": 2}}, - ], - {"my_stream": {"field_A": {"type": ["number", "null"]}}}, - id="test_integer_number", - ), - pytest.param( - [ - {"stream": "my_stream", "data": {"field_A": None}}, - ], - {"my_stream": {}}, - id="test_null", - ), - pytest.param( - [ - {"stream": "my_stream", "data": {"field_A": None}}, - {"stream": "my_stream", "data": {"field_A": "abc"}}, - ], - {"my_stream": {"field_A": {"type": ["string", "null"]}}}, - id="test_null_optional", - ), - pytest.param( - [ - {"stream": "my_stream", "data": {"field_A": None}}, - {"stream": "my_stream", "data": {"field_A": {"nested": "abc"}}}, - ], - {"my_stream": {"field_A": {"type": ["object", "null"], "properties": {"nested": {"type": ["string", "null"]}}}}}, - id="test_any_of", - ), - pytest.param( - [ - {"stream": "my_stream", "data": {"field_A": None}}, - {"stream": "my_stream", "data": {"field_A": {"nested": "abc", "nully": None}}}, - ], - {"my_stream": {"field_A": {"type": ["object", "null"], "properties": {"nested": {"type": ["string", "null"]}}}}}, - id="test_any_of_with_null", - ), - pytest.param( - [ - {"stream": "my_stream", "data": {"field_A": None}}, - {"stream": "my_stream", "data": {"field_A": {"nested": "abc", "nully": None}}}, - {"stream": "my_stream", "data": {"field_A": {"nested": "abc", "nully": "a string"}}}, - ], - { - "my_stream": { - "field_A": { - "type": ["object", "null"], - "properties": {"nested": {"type": ["string", "null"]}, "nully": {"type": ["string", "null"]}}, - } - } - }, - id="test_any_of_with_null_union", - ), - pytest.param( - [ - {"stream": "my_stream", "data": {"field_A": {"nested": "abc", "nully": "a string"}}}, - {"stream": "my_stream", "data": {"field_A": None}}, - {"stream": "my_stream", "data": {"field_A": {"nested": "abc", "nully": None}}}, - ], - { - "my_stream": { - "field_A": { - "type": ["object", "null"], - "properties": {"nested": {"type": ["string", "null"]}, "nully": {"type": ["string", "null"]}}, - } - } - }, - id="test_any_of_with_null_union_changed_order", - ), - pytest.param( - [ - {"stream": "my_stream", "data": {"field_A": "abc", "nested": {"field_B": None}}}, - ], - {"my_stream": {"field_A": {"type": ["string", "null"]}, "nested": {"type": ["object", "null"], "properties": {}}}}, - id="test_nested_null", - ), - pytest.param( - [ - {"stream": "my_stream", "data": {"field_A": "abc", "nested": [{"field_B": None, "field_C": "abc"}]}}, - ], - { - "my_stream": { - "field_A": {"type": ["string", "null"]}, - "nested": { - "type": ["array", "null"], - "items": {"type": ["object", "null"], "properties": {"field_C": {"type": ["string", "null"]}}}, - }, - } - }, - id="test_array_nested_null", - ), - pytest.param( - [ - {"stream": "my_stream", "data": {"field_A": "abc", "nested": None}}, - {"stream": "my_stream", "data": {"field_A": "abc", "nested": [{"field_B": None, "field_C": "abc"}]}}, - ], - { - "my_stream": { - "field_A": {"type": ["string", "null"]}, - "nested": { - "type": ["array", "null"], - "items": {"type": ["object", "null"], "properties": {"field_C": {"type": ["string", "null"]}}}, - }, - } - }, - id="test_array_top_level_null", - ), - pytest.param( - [ - {"stream": "my_stream", "data": {"field_A": None}}, - {"stream": "my_stream", "data": {"field_A": "abc"}}, - ], - {"my_stream": {"field_A": {"type": ["string", "null"]}}}, - id="test_null_string", - ), - pytest.param( - [ - { - "stream": "data_with_nested_arrays", - "data": { - "root_property_object": { - "property_array": [ - {"title": "Nested_1", "type": "multi-value", "value": ["XL"]}, - { - "title": "Nested_2", - "type": "location", - "value": {"nested_key_1": "GB", "nested_key_2": "United Kingdom"}, - }, - ], - } - }, - }, - ], - { - "data_with_nested_arrays": { - "root_property_object": { - "type": ["object", "null"], - "properties": { - "property_array": { - "type": ["array", "null"], - "items": { - "type": ["object", "null"], - "properties": { - "title": {"type": ["string", "null"]}, - "type": {"type": ["string", "null"]}, - "value": { - "anyOf": [ - {"type": "array", "items": {"type": "string"}}, - { - "type": "object", - "properties": {"nested_key_1": {"type": "string"}, "nested_key_2": {"type": "string"}}, - }, - ] - }, - }, - }, - } - }, - } - } - }, - id="test_data_with_nested_arrays", - ), - ], -) -def test_schema_derivation(input_records: List, expected_schemas: Mapping): - inferrer = SchemaInferrer() - for record in input_records: - inferrer.accumulate(AirbyteRecordMessage(stream=record["stream"], data=record["data"], emitted_at=NOW)) - - for stream_name, expected_schema in expected_schemas.items(): - assert inferrer.get_stream_schema(stream_name) == { - "$schema": "http://json-schema.org/schema#", - "type": "object", - "properties": expected_schema, - } - - -_STREAM_NAME = "a stream name" -_ANY_VALUE = "any value" -_IS_PK = True -_IS_CURSOR_FIELD = True - - -def _create_inferrer_with_required_field(is_pk: bool, field: List[List[str]]) -> SchemaInferrer: - if is_pk: - return SchemaInferrer(field) - return SchemaInferrer([[]], field) - - -@pytest.mark.parametrize( - "is_pk", - [ - pytest.param(_IS_PK, id="required_field_is_pk"), - pytest.param(_IS_CURSOR_FIELD, id="required_field_is_cursor_field"), - ], -) -def test_field_is_on_root(is_pk: bool): - inferrer = _create_inferrer_with_required_field(is_pk, [["property"]]) - - inferrer.accumulate(AirbyteRecordMessage(stream=_STREAM_NAME, data={"property": _ANY_VALUE}, emitted_at=NOW)) - - assert inferrer.get_stream_schema(_STREAM_NAME)["required"] == ["property"] - assert inferrer.get_stream_schema(_STREAM_NAME)["properties"]["property"]["type"] == "string" - - -@pytest.mark.parametrize( - "is_pk", - [ - pytest.param(_IS_PK, id="required_field_is_pk"), - pytest.param(_IS_CURSOR_FIELD, id="required_field_is_cursor_field"), - ], -) -def test_field_is_nested(is_pk: bool): - inferrer = _create_inferrer_with_required_field(is_pk, [["property", "nested_property"]]) - - inferrer.accumulate(AirbyteRecordMessage(stream=_STREAM_NAME, data={"property": {"nested_property": _ANY_VALUE}}, emitted_at=NOW)) - - assert inferrer.get_stream_schema(_STREAM_NAME)["required"] == ["property"] - assert inferrer.get_stream_schema(_STREAM_NAME)["properties"]["property"]["type"] == "object" - assert inferrer.get_stream_schema(_STREAM_NAME)["properties"]["property"]["required"] == ["nested_property"] - - -@pytest.mark.parametrize( - "is_pk", - [ - pytest.param(_IS_PK, id="required_field_is_pk"), - pytest.param(_IS_CURSOR_FIELD, id="required_field_is_cursor_field"), - ], -) -def test_field_is_composite(is_pk: bool): - inferrer = _create_inferrer_with_required_field(is_pk, [["property 1"], ["property 2"]]) - inferrer.accumulate( - AirbyteRecordMessage(stream=_STREAM_NAME, data={"property 1": _ANY_VALUE, "property 2": _ANY_VALUE}, emitted_at=NOW) - ) - assert inferrer.get_stream_schema(_STREAM_NAME)["required"] == ["property 1", "property 2"] - - -@pytest.mark.parametrize( - "is_pk", - [ - pytest.param(_IS_PK, id="required_field_is_pk"), - pytest.param(_IS_CURSOR_FIELD, id="required_field_is_cursor_field"), - ], -) -def test_field_is_composite_and_nested(is_pk: bool): - inferrer = _create_inferrer_with_required_field(is_pk, [["property 1", "nested"], ["property 2"]]) - - inferrer.accumulate( - AirbyteRecordMessage(stream=_STREAM_NAME, data={"property 1": {"nested": _ANY_VALUE}, "property 2": _ANY_VALUE}, emitted_at=NOW) - ) - - assert inferrer.get_stream_schema(_STREAM_NAME)["required"] == ["property 1", "property 2"] - assert inferrer.get_stream_schema(_STREAM_NAME)["properties"]["property 1"]["type"] == "object" - assert inferrer.get_stream_schema(_STREAM_NAME)["properties"]["property 2"]["type"] == "string" - assert inferrer.get_stream_schema(_STREAM_NAME)["properties"]["property 1"]["required"] == ["nested"] - assert inferrer.get_stream_schema(_STREAM_NAME)["properties"]["property 1"]["properties"]["nested"]["type"] == "string" - - -def test_given_pk_does_not_exist_when_get_inferred_schemas_then_raise_error(): - inferrer = SchemaInferrer([["pk does not exist"]]) - inferrer.accumulate(AirbyteRecordMessage(stream=_STREAM_NAME, data={"id": _ANY_VALUE}, emitted_at=NOW)) - - with pytest.raises(SchemaValidationException) as exception: - inferrer.get_stream_schema(_STREAM_NAME) - - assert len(exception.value.validation_errors) == 1 - - -def test_given_pk_path_is_partially_valid_when_get_inferred_schemas_then_validation_error_mentions_where_the_issue_is(): - inferrer = SchemaInferrer([["id", "nested pk that does not exist"]]) - inferrer.accumulate(AirbyteRecordMessage(stream=_STREAM_NAME, data={"id": _ANY_VALUE}, emitted_at=NOW)) - - with pytest.raises(SchemaValidationException) as exception: - inferrer.get_stream_schema(_STREAM_NAME) - - assert len(exception.value.validation_errors) == 1 - assert "Path ['id']" in exception.value.validation_errors[0] - - -def test_given_composite_pk_but_only_one_path_valid_when_get_inferred_schemas_then_valid_path_is_required(): - inferrer = SchemaInferrer([["id 1"], ["id 2"]]) - inferrer.accumulate(AirbyteRecordMessage(stream=_STREAM_NAME, data={"id 1": _ANY_VALUE}, emitted_at=NOW)) - - with pytest.raises(SchemaValidationException) as exception: - inferrer.get_stream_schema(_STREAM_NAME) - - assert exception.value.schema["required"] == ["id 1"] - - -def test_given_composite_pk_but_only_one_path_valid_when_get_inferred_schemas_then_validation_error_mentions_where_the_issue_is(): - inferrer = SchemaInferrer([["id 1"], ["id 2"]]) - inferrer.accumulate(AirbyteRecordMessage(stream=_STREAM_NAME, data={"id 1": _ANY_VALUE}, emitted_at=NOW)) - - with pytest.raises(SchemaValidationException) as exception: - inferrer.get_stream_schema(_STREAM_NAME) - - assert len(exception.value.validation_errors) == 1 - assert "id 2" in exception.value.validation_errors[0] diff --git a/airbyte-cdk/python/unit_tests/utils/test_secret_utils.py b/airbyte-cdk/python/unit_tests/utils/test_secret_utils.py deleted file mode 100644 index 39c6ff735da0..000000000000 --- a/airbyte-cdk/python/unit_tests/utils/test_secret_utils.py +++ /dev/null @@ -1,135 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import pytest -from airbyte_cdk.utils.airbyte_secrets_utils import add_to_secrets, filter_secrets, get_secret_paths, get_secrets, update_secrets - -SECRET_STRING_KEY = "secret_key1" -SECRET_STRING_VALUE = "secret_value" -SECRET_STRING_2_KEY = "secret_key2" -SECRET_STRING_2_VALUE = "second_secret_val" -SECRET_INT_KEY = "secret_int" -SECRET_INT_VALUE = 1337 -NOT_SECRET_KEY = "not_a_secret" -NOT_SECRET_VALUE = "unimportant value" - - -flat_spec_with_secret = {"properties": {SECRET_STRING_KEY: {"type": "string", "airbyte_secret": True}, NOT_SECRET_KEY: {"type": "string"}}} -flat_config_with_secret = {SECRET_STRING_KEY: SECRET_STRING_VALUE, NOT_SECRET_KEY: NOT_SECRET_VALUE} - -flat_spec_with_secret_int = { - "properties": {SECRET_INT_KEY: {"type": "integer", "airbyte_secret": True}, NOT_SECRET_KEY: {"type": "string"}} -} -flat_config_with_secret_int = {SECRET_INT_KEY: SECRET_INT_VALUE, NOT_SECRET_KEY: NOT_SECRET_VALUE} - -flat_spec_without_secrets = {"properties": {NOT_SECRET_KEY: {"type": "string"}}} -flat_config_without_secrets = {NOT_SECRET_KEY: NOT_SECRET_VALUE} - -spec_with_oneof_secrets = { - "properties": { - SECRET_STRING_KEY: {"type": "string", "airbyte_secret": True}, - NOT_SECRET_KEY: {"type": "string"}, - "credentials": { - "type": "object", - "oneOf": [ - { - "type": "object", - "properties": {SECRET_STRING_2_KEY: {"type": "string", "airbyte_secret": True}, NOT_SECRET_KEY: {"type": "string"}}, - }, - { - "type": "object", - "properties": {SECRET_INT_KEY: {"type": "integer", "airbyte_secret": True}, NOT_SECRET_KEY: {"type": "string"}}, - }, - ], - }, - } -} -config_with_oneof_secrets_1 = { - SECRET_STRING_KEY: SECRET_STRING_VALUE, - NOT_SECRET_KEY: NOT_SECRET_VALUE, - "credentials": {SECRET_STRING_2_KEY: SECRET_STRING_2_VALUE}, -} -config_with_oneof_secrets_2 = { - SECRET_STRING_KEY: SECRET_STRING_VALUE, - NOT_SECRET_KEY: NOT_SECRET_VALUE, - "credentials": {SECRET_INT_KEY: SECRET_INT_VALUE}, -} - -spec_with_nested_secrets = { - "properties": { - SECRET_STRING_KEY: {"type": "string", "airbyte_secret": True}, - NOT_SECRET_KEY: {"type": "string"}, - "credentials": { - "type": "object", - "properties": { - SECRET_STRING_2_KEY: {"type": "string", "airbyte_secret": True}, - NOT_SECRET_KEY: {"type": "string"}, - SECRET_INT_KEY: {"type": "integer", "airbyte_secret": True}, - }, - }, - } -} -config_with_nested_secrets = { - SECRET_STRING_KEY: SECRET_STRING_VALUE, - NOT_SECRET_KEY: NOT_SECRET_VALUE, - "credentials": {SECRET_STRING_2_KEY: SECRET_STRING_2_VALUE, SECRET_INT_KEY: SECRET_INT_VALUE}, -} - - -@pytest.mark.parametrize( - ["spec", "expected"], - [ - (flat_spec_with_secret, [[SECRET_STRING_KEY]]), - (flat_spec_without_secrets, []), - (flat_spec_with_secret_int, [[SECRET_INT_KEY]]), - (spec_with_oneof_secrets, [[SECRET_STRING_KEY], ["credentials", SECRET_STRING_2_KEY], ["credentials", SECRET_INT_KEY]]), - (spec_with_nested_secrets, [[SECRET_STRING_KEY], ["credentials", SECRET_STRING_2_KEY], ["credentials", SECRET_INT_KEY]]), - ], -) -def test_get_secret_paths(spec, expected): - assert get_secret_paths(spec) == expected, f"Expected {spec} to yield secret paths {expected}" - - -@pytest.mark.parametrize( - ["spec", "config", "expected"], - [ - (flat_spec_with_secret, flat_config_with_secret, [SECRET_STRING_VALUE]), - (flat_spec_without_secrets, flat_config_without_secrets, []), - (flat_spec_with_secret_int, flat_config_with_secret_int, [SECRET_INT_VALUE]), - (spec_with_oneof_secrets, config_with_oneof_secrets_1, [SECRET_STRING_VALUE, SECRET_STRING_2_VALUE]), - (spec_with_oneof_secrets, config_with_oneof_secrets_2, [SECRET_STRING_VALUE, SECRET_INT_VALUE]), - (spec_with_nested_secrets, config_with_nested_secrets, [SECRET_STRING_VALUE, SECRET_STRING_2_VALUE, SECRET_INT_VALUE]), - ], -) -def test_get_secrets(spec, config, expected): - assert get_secrets(spec, config) == expected, f"Expected the spec {spec} and config {config} to produce {expected}" - - -def test_secret_filtering(): - sensitive_str = f"{SECRET_STRING_VALUE} {NOT_SECRET_VALUE} {SECRET_STRING_VALUE} {SECRET_STRING_2_VALUE}" - - update_secrets([]) - filtered = filter_secrets(sensitive_str) - assert filtered == sensitive_str - - # the empty secret should not affect the result - update_secrets([""]) - filtered = filter_secrets(sensitive_str) - assert filtered == sensitive_str - - update_secrets([SECRET_STRING_VALUE, SECRET_STRING_2_VALUE]) - filtered = filter_secrets(sensitive_str) - assert filtered == f"**** {NOT_SECRET_VALUE} **** ****" - - -def test_secrets_added_are_filtered(): - ADDED_SECRET = "only_a_secret_if_added" - sensitive_str = f"{ADDED_SECRET} {NOT_SECRET_VALUE}" - - filtered = filter_secrets(sensitive_str) - assert filtered == sensitive_str - - add_to_secrets(ADDED_SECRET) - filtered = filter_secrets(sensitive_str) - assert filtered == f"**** {NOT_SECRET_VALUE}" diff --git a/airbyte-cdk/python/unit_tests/utils/test_stream_status_utils.py b/airbyte-cdk/python/unit_tests/utils/test_stream_status_utils.py deleted file mode 100644 index 4862a1e0118e..000000000000 --- a/airbyte-cdk/python/unit_tests/utils/test_stream_status_utils.py +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.models import AirbyteMessage, AirbyteStream, AirbyteStreamStatus, SyncMode, TraceType -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.utils.stream_status_utils import as_airbyte_message as stream_status_as_airbyte_message - -stream = AirbyteStream(name="name", namespace="namespace", json_schema={}, supported_sync_modes=[SyncMode.full_refresh]) - - -def test_started_as_message(): - stream_status = AirbyteStreamStatus.STARTED - airbyte_message = stream_status_as_airbyte_message(stream, stream_status) - - assert isinstance(airbyte_message, AirbyteMessage) - assert airbyte_message.type == MessageType.TRACE - assert airbyte_message.trace.type == TraceType.STREAM_STATUS - assert airbyte_message.trace.emitted_at > 0 - assert airbyte_message.trace.stream_status.stream_descriptor.name == stream.name - assert airbyte_message.trace.stream_status.stream_descriptor.namespace == stream.namespace - assert airbyte_message.trace.stream_status.status == stream_status - - -def test_running_as_message(): - stream_status = AirbyteStreamStatus.RUNNING - airbyte_message = stream_status_as_airbyte_message(stream, stream_status) - - assert isinstance(airbyte_message, AirbyteMessage) - assert airbyte_message.type == MessageType.TRACE - assert airbyte_message.trace.type == TraceType.STREAM_STATUS - assert airbyte_message.trace.emitted_at > 0 - assert airbyte_message.trace.stream_status.stream_descriptor.name == stream.name - assert airbyte_message.trace.stream_status.stream_descriptor.namespace == stream.namespace - assert airbyte_message.trace.stream_status.status == stream_status - - -def test_complete_as_message(): - stream_status = AirbyteStreamStatus.COMPLETE - airbyte_message = stream_status_as_airbyte_message(stream, stream_status) - - assert isinstance(airbyte_message, AirbyteMessage) - assert airbyte_message.type == MessageType.TRACE - assert airbyte_message.trace.type == TraceType.STREAM_STATUS - assert airbyte_message.trace.emitted_at > 0 - assert airbyte_message.trace.stream_status.stream_descriptor.name == stream.name - assert airbyte_message.trace.stream_status.stream_descriptor.namespace == stream.namespace - assert airbyte_message.trace.stream_status.status == stream_status - - -def test_incomplete_failed_as_message(): - stream_status = AirbyteStreamStatus.INCOMPLETE - airbyte_message = stream_status_as_airbyte_message(stream, stream_status) - - assert isinstance(airbyte_message, AirbyteMessage) - assert airbyte_message.type == MessageType.TRACE - assert airbyte_message.trace.type == TraceType.STREAM_STATUS - assert airbyte_message.trace.emitted_at > 0 - assert airbyte_message.trace.stream_status.stream_descriptor.name == stream.name - assert airbyte_message.trace.stream_status.stream_descriptor.namespace == stream.namespace - assert airbyte_message.trace.stream_status.status == stream_status diff --git a/airbyte-cdk/python/unit_tests/utils/test_traced_exception.py b/airbyte-cdk/python/unit_tests/utils/test_traced_exception.py deleted file mode 100644 index ea559a319467..000000000000 --- a/airbyte-cdk/python/unit_tests/utils/test_traced_exception.py +++ /dev/null @@ -1,136 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import pytest -from airbyte_cdk.models import ( - AirbyteErrorTraceMessage, - AirbyteMessage, - AirbyteMessageSerializer, - AirbyteTraceMessage, - FailureType, - Status, - StreamDescriptor, - TraceType, -) -from airbyte_cdk.models import Type as MessageType -from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from orjson import orjson - -_AN_EXCEPTION = ValueError("An exception") -_A_STREAM_DESCRIPTOR = StreamDescriptor(name="a_stream") -_ANOTHER_STREAM_DESCRIPTOR = StreamDescriptor(name="another_stream") - - -@pytest.fixture -def raised_exception(): - try: - raise RuntimeError("an error has occurred") - except RuntimeError as e: - return e - - -def test_build_from_existing_exception(raised_exception): - traced_exc = AirbyteTracedException.from_exception(raised_exception, message="my user-friendly message") - assert traced_exc.message == "my user-friendly message" - assert traced_exc.internal_message == "an error has occurred" - assert traced_exc.failure_type == FailureType.system_error - assert traced_exc._exception == raised_exception - - -def test_exception_as_airbyte_message(): - traced_exc = AirbyteTracedException("an internal message") - airbyte_message = traced_exc.as_airbyte_message() - - assert isinstance(airbyte_message, AirbyteMessage) - assert airbyte_message.type == MessageType.TRACE - assert airbyte_message.trace.type == TraceType.ERROR - assert airbyte_message.trace.emitted_at > 0 - assert airbyte_message.trace.error.failure_type == FailureType.system_error - assert airbyte_message.trace.error.message == "Something went wrong in the connector. See the logs for more details." - assert airbyte_message.trace.error.internal_message == "an internal message" - assert airbyte_message.trace.error.stack_trace == "airbyte_cdk.utils.traced_exception.AirbyteTracedException: an internal message\n" - - -def test_existing_exception_as_airbyte_message(raised_exception): - traced_exc = AirbyteTracedException.from_exception(raised_exception) - airbyte_message = traced_exc.as_airbyte_message() - - assert isinstance(airbyte_message, AirbyteMessage) - assert airbyte_message.type == MessageType.TRACE - assert airbyte_message.trace.type == TraceType.ERROR - assert airbyte_message.trace.error.message == "Something went wrong in the connector. See the logs for more details." - assert airbyte_message.trace.error.internal_message == "an error has occurred" - assert airbyte_message.trace.error.stack_trace.startswith("Traceback (most recent call last):") - assert airbyte_message.trace.error.stack_trace.endswith( - 'raise RuntimeError("an error has occurred")\n' "RuntimeError: an error has occurred\n" - ) - - -def test_config_error_as_connection_status_message(): - traced_exc = AirbyteTracedException("an internal message", message="Config validation error", failure_type=FailureType.config_error) - airbyte_message = traced_exc.as_connection_status_message() - - assert isinstance(airbyte_message, AirbyteMessage) - assert airbyte_message.type == MessageType.CONNECTION_STATUS - assert airbyte_message.connectionStatus.status == Status.FAILED - assert airbyte_message.connectionStatus.message == "Config validation error" - - -def test_other_error_as_connection_status_message(): - traced_exc = AirbyteTracedException("an internal message", failure_type=FailureType.system_error) - airbyte_message = traced_exc.as_connection_status_message() - - assert airbyte_message is None - - -def test_emit_message(capsys): - traced_exc = AirbyteTracedException( - internal_message="internal message", message="user-friendly message", exception=RuntimeError("oh no") - ) - - expected_message = AirbyteMessage( - type=MessageType.TRACE, - trace=AirbyteTraceMessage( - type=TraceType.ERROR, - emitted_at=0.0, - error=AirbyteErrorTraceMessage( - failure_type=FailureType.system_error, - message="user-friendly message", - internal_message="internal message", - stack_trace="RuntimeError: oh no\n", - ), - ), - ) - - traced_exc.emit_message() - - stdout = capsys.readouterr().out - printed_message = AirbyteMessageSerializer.load(orjson.loads(stdout)) - printed_message.trace.emitted_at = 0.0 - assert printed_message == expected_message - - -def test_given_both_init_and_as_message_with_stream_descriptor_when_as_airbyte_message_use_init_stream_descriptor() -> None: - traced_exc = AirbyteTracedException(stream_descriptor=_A_STREAM_DESCRIPTOR) - message = traced_exc.as_airbyte_message(stream_descriptor=_ANOTHER_STREAM_DESCRIPTOR) - assert message.trace.error.stream_descriptor == _A_STREAM_DESCRIPTOR - - -def test_given_both_init_and_as_sanitized_airbyte_message_with_stream_descriptor_when_as_airbyte_message_use_init_stream_descriptor() -> None: - traced_exc = AirbyteTracedException(stream_descriptor=_A_STREAM_DESCRIPTOR) - message = traced_exc.as_sanitized_airbyte_message(stream_descriptor=_ANOTHER_STREAM_DESCRIPTOR) - assert message.trace.error.stream_descriptor == _A_STREAM_DESCRIPTOR - - -def test_given_both_from_exception_and_as_message_with_stream_descriptor_when_as_airbyte_message_use_init_stream_descriptor() -> None: - traced_exc = AirbyteTracedException.from_exception(_AN_EXCEPTION, stream_descriptor=_A_STREAM_DESCRIPTOR) - message = traced_exc.as_airbyte_message(stream_descriptor=_ANOTHER_STREAM_DESCRIPTOR) - assert message.trace.error.stream_descriptor == _A_STREAM_DESCRIPTOR - - -def test_given_both_from_exception_and_as_sanitized_airbyte_message_with_stream_descriptor_when_as_airbyte_message_use_init_stream_descriptor() -> None: - traced_exc = AirbyteTracedException.from_exception(_AN_EXCEPTION, stream_descriptor=_A_STREAM_DESCRIPTOR) - message = traced_exc.as_sanitized_airbyte_message(stream_descriptor=_ANOTHER_STREAM_DESCRIPTOR) - assert message.trace.error.stream_descriptor == _A_STREAM_DESCRIPTOR diff --git a/airbyte-ci/connectors/auto_merge/pyproject.toml b/airbyte-ci/connectors/auto_merge/pyproject.toml index 545a036cb4c6..e73e19f4c3e2 100644 --- a/airbyte-ci/connectors/auto_merge/pyproject.toml +++ b/airbyte-ci/connectors/auto_merge/pyproject.toml @@ -20,6 +20,9 @@ ruff = "^0.4.3" pytest = "^8.2.0" pyinstrument = "^4.6.2" +[tool.ruff] +line-length = 140 + [tool.ruff.lint] select = [ "I" # isort diff --git a/airbyte-ci/connectors/base_images/README.md b/airbyte-ci/connectors/base_images/README.md index 30630d7d3f32..cb21dc2eb7cb 100644 --- a/airbyte-ci/connectors/base_images/README.md +++ b/airbyte-ci/connectors/base_images/README.md @@ -6,7 +6,7 @@ Our connector build pipeline ([`airbyte-ci`](https://github.com/airbytehq/airbyt Our base images are declared in code, using the [Dagger Python SDK](https://dagger-io.readthedocs.io/en/sdk-python-v0.6.4/). - [Python base image code declaration](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/base_images/base_images/python/bases.py) -- ~Java base image code declaration~ *TODO* +- [Java base image code declaration](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/base_images/base_images/java/bases.py) ## Where are the Dockerfiles? @@ -19,8 +19,13 @@ However, we do artificially generate Dockerfiles for debugging and documentation ### Example for `airbyte/python-connector-base`: ```dockerfile -FROM docker.io/python:3.10.14-slim-bookworm@sha256:3b37199fbc5a730a551909b3efa7b29105c859668b7502451c163f2a4a7ae1ed +FROM docker.io/python:3.10.14-slim-bookworm@sha256:2407c61b1a18067393fecd8a22cf6fceede893b6aaca817bf9fbfe65e33614a3 RUN ln -snf /usr/share/zoneinfo/Etc/UTC /etc/localtime +RUN adduser --uid 1000 --system --group --no-create-home airbyte +RUN mkdir --mode 755 /custom_cache +RUN mkdir --mode 755 /airbyte +RUN chown airbyte:airbyte /airbyte +ENV PIP_CACHE_DIR=/custom_cache/pip RUN pip install --upgrade pip==24.0 setuptools==70.0.0 ENV POETRY_VIRTUALENVS_CREATE=false ENV POETRY_VIRTUALENVS_IN_PROJECT=false @@ -29,7 +34,21 @@ RUN pip install poetry==1.6.1 RUN sh -c apt-get update && apt-get upgrade -y && apt-get dist-upgrade -y && apt-get clean RUN sh -c apt-get install -y socat=1.7.4.4-2 RUN sh -c apt-get update && apt-get install -y tesseract-ocr=5.3.0-2 poppler-utils=22.12.0-2+b1 -RUN mkdir /usr/share/nltk_data +RUN mkdir -p 755 /usr/share/nltk_data +``` + + + +### Example for `airbyte/java-connector-base`: +```dockerfile +FROM docker.io/amazoncorretto:21-al2023@sha256:5454cb606e803fce56861fdbc9eab365eaa2ab4f357ceb8c1d56f4f8c8a7bc33 +RUN sh -c set -o xtrace && yum install -y shadow-utils tar openssl findutils && yum update -y --security && yum clean all && rm -rf /var/cache/yum && groupadd --gid 1000 airbyte && useradd --uid 1000 --gid airbyte --shell /bin/bash --create-home airbyte && mkdir /secrets && mkdir /config && mkdir --mode 755 /airbyte && mkdir --mode 755 /custom_cache && chown -R airbyte:airbyte /airbyte && chown -R airbyte:airbyte /custom_cache && chown -R airbyte:airbyte /secrets && chown -R airbyte:airbyte /config && chown -R airbyte:airbyte /usr/share/pki/ca-trust-source && chown -R airbyte:airbyte /etc/pki/ca-trust && chown -R airbyte:airbyte /tmp +ENV AIRBYTE_SPEC_CMD=/airbyte/javabase.sh --spec +ENV AIRBYTE_CHECK_CMD=/airbyte/javabase.sh --check +ENV AIRBYTE_DISCOVER_CMD=/airbyte/javabase.sh --discover +ENV AIRBYTE_READ_CMD=/airbyte/javabase.sh --read +ENV AIRBYTE_WRITE_CMD=/airbyte/javabase.sh --write +ENV AIRBYTE_ENTRYPOINT=/airbyte/base.sh ``` @@ -39,12 +58,14 @@ RUN mkdir /usr/share/nltk_data ### `airbyte/python-connector-base` -| Version | Published | Docker Image Address | Changelog | +| Version | Published | Docker Image Address | Changelog | |---------|-----------|--------------|-----------| +| 3.0.0 | ✅| docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 | Create airbyte user | +| 3.0.0-rc.1 | ✅| docker.io/airbyte/python-connector-base:3.0.0-rc.1@sha256:ee046486af9ad90b1b248afe5e92846b51375a21463dff1cd377c4f06abb55b5 | Update Python 3.10.4 image + create airbyte user | | 2.0.0 | ✅| docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 | Use Python 3.10 | | 1.2.3 | ✅| docker.io/airbyte/python-connector-base:1.2.3@sha256:a8abfdc75f8e22931657a1ae15069e7b925e74bb7b5ef36371a85e4caeae5696 | Use latest root image version and update system packages | | 1.2.2 | ✅| docker.io/airbyte/python-connector-base:1.2.2@sha256:57703de3b4c4204bd68a7b13c9300f8e03c0189bffddaffc796f1da25d2dbea0 | Fix Python 3.9.19 image digest | -| 1.2.2-rc.1 | ✅| docker.io/airbyte/python-connector-base:1.2.2-rc.1@sha256:a8abfdc75f8e22931657a1ae15069e7b925e74bb7b5ef36371a85e4caeae5696 | | +| 1.2.2-rc.1 | ✅| docker.io/airbyte/python-connector-base:1.2.2-rc.1@sha256:a8abfdc75f8e22931657a1ae15069e7b925e74bb7b5ef36371a85e4caeae5696 | Create an airbyte user and use it | | 1.2.1 | ✅| docker.io/airbyte/python-connector-base:1.2.1@sha256:4a4255e2bccab71fa5912487e42d9755cdecffae77273fed8be01a081cd6e795 | Upgrade to Python 3.9.19 + update pip and setuptools | | 1.2.0 | ✅| docker.io/airbyte/python-connector-base:1.2.0@sha256:c22a9d97464b69d6ef01898edf3f8612dc11614f05a84984451dde195f337db9 | Add CDK system dependencies: nltk data, tesseract, poppler. | | 1.2.0-rc.1 | ✅| docker.io/airbyte/python-connector-base:1.2.0-rc.1@sha256:f6467768b75fb09125f6e6b892b6b48c98d9fe085125f3ff4adc722afb1e5b30 | | @@ -52,6 +73,20 @@ RUN mkdir /usr/share/nltk_data | 1.0.0 | ✅| docker.io/airbyte/python-connector-base:1.0.0@sha256:dd17e347fbda94f7c3abff539be298a65af2d7fc27a307d89297df1081a45c27 | Initial release: based on Python 3.9.18, on slim-bookworm system, with pip==23.2.1 and poetry==1.6.1 | +### `airbyte/java-connector-base` + +| Version | Published | Docker Image Address | Changelog | +|---------|-----------|--------------|-----------| +| 2.0.0 | ✅| docker.io/airbyte/java-connector-base:2.0.0@sha256:5a1a21c75c5e1282606de9fa539ba136520abe2fbd013058e988bb0297a9f454 | ~Release non root base image~ | +| 2.0.0-rc.2 | ✅| docker.io/airbyte/java-connector-base:2.0.0-rc.2@sha256:e5543b3de4c38e9ef45dba886bad5ee319b0d7bfe921f310c788f1d4466e25eb | Fine tune permissions and reproduce platform java base implementation | +| 2.0.0-rc.1 | ✅| docker.io/airbyte/java-connector-base:2.0.0-rc.1@sha256:484b929684b9e4f60d06cde171ee0b8238802cb434403293fcede81c1e73c537 | Make the java base image non root | +| 1.0.0 | ✅| docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a | Create a base image for our java connectors based on Amazon Corretto. | +| 1.0.0-rc.4 | ✅| docker.io/airbyte/java-connector-base:1.0.0-rc.4@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a | Bundle yum calls in a single RUN | +| 1.0.0-rc.3 | ✅| docker.io/airbyte/java-connector-base:1.0.0-rc.3@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a | | +| 1.0.0-rc.2 | ✅| docker.io/airbyte/java-connector-base:1.0.0-rc.2@sha256:fca66e81b4d2e4869a03b57b1b34beb048e74f5d08deb2046c3bb9919e7e2273 | Set entrypoint to base.sh | +| 1.0.0-rc.1 | ✅| docker.io/airbyte/java-connector-base:1.0.0-rc.1@sha256:886a7ce7eccfe3c8fb303511d0e46b83b7edb4f28e3705818c090185ba511fe7 | Create a base image for our java connectors. | + + ## How to release a new base image version (example for Python) ### Requirements @@ -92,8 +127,18 @@ poetry run pytest # Static typing checks poetry run mypy base_images --check-untyped-defs ``` + ## CHANGELOG +### 1.4.0 +- Declare a base image for our java connectors. + +### 1.3.1 +- Update the crane image address. The previous address was deleted by the maintainer. + +### 1.2.0 +- Improve new version prompt to pick bump type with optional pre-release version. + ### 1.1.0 - Add a cache ttl for base image listing to avoid DockerHub rate limiting. @@ -106,4 +151,4 @@ poetry run mypy base_images --check-untyped-defs ### 1.0.1 -- Bumped dependencies ([#42581](https://github.com/airbytehq/airbyte/pull/42581)) +- Bumped dependencies ([#42581](https://github.com/airbytehq/airbyte/pull/42581)) \ No newline at end of file diff --git a/airbyte-ci/connectors/base_images/base_images/bases.py b/airbyte-ci/connectors/base_images/base_images/bases.py index e5f94fc185b7..b794526d637d 100644 --- a/airbyte-ci/connectors/base_images/base_images/bases.py +++ b/airbyte-ci/connectors/base_images/base_images/bases.py @@ -20,6 +20,11 @@ class AirbyteConnectorBaseImage(ABC): Please do not declare any Dagger with_exec instruction in this class as in the abstract class context we have no guarantee about the underlying system used in the base image. """ + USER: str = "airbyte" + USER_ID: int = 1000 + CACHE_DIR_PATH: str = "/custom_cache" + AIRBYTE_DIR_PATH: str = "/airbyte" + @final def __init__(self, dagger_client: dagger.Client, version: semver.VersionInfo): """Initializes the Airbyte base image. @@ -94,9 +99,23 @@ async def run_sanity_checks(self, platform: dagger.Platform): # INSTANCE METHODS: @final def get_base_container(self, platform: dagger.Platform) -> dagger.Container: - """Returns a container using the base image. This container is used to build the Airbyte base image. + """Returns a container using the base image. + This container is used to build the Airbyte base image. + We create the user 'airbyte' with the UID 1000 and GID 1000. Returns: dagger.Container: The container using the base python image. """ - return self.dagger_client.container(platform=platform).from_(self.root_image.address) + return ( + self.dagger_client.container(platform=platform) + .from_(self.root_image.address) + # Set the timezone to UTC + .with_exec(["ln", "-snf", "/usr/share/zoneinfo/Etc/UTC", "/etc/localtime"]) + # Create the user 'airbyte' with the UID 1000 and GID 1000 + .with_exec(["adduser", "--uid", str(self.USER_ID), "--system", "--group", "--no-create-home", self.USER]) + # Create the cache airbyte directories and set the right permissions + .with_exec(["mkdir", "--mode", "755", self.CACHE_DIR_PATH]) + .with_exec(["mkdir", "--mode", "755", self.AIRBYTE_DIR_PATH]) + # Change the owner of the airbyte directory to the user 'airbyte' + .with_exec(["chown", f"{self.USER}:{self.USER}", self.AIRBYTE_DIR_PATH]) + ) diff --git a/airbyte-ci/connectors/base_images/base_images/commands.py b/airbyte-ci/connectors/base_images/base_images/commands.py index 90d86ce383bd..626724cf61fb 100644 --- a/airbyte-ci/connectors/base_images/base_images/commands.py +++ b/airbyte-ci/connectors/base_images/base_images/commands.py @@ -10,9 +10,10 @@ import dagger import inquirer # type: ignore import semver -from base_images import bases, console, consts, errors, hacks, publish, utils, version_registry from jinja2 import Environment, FileSystemLoader +from base_images import bases, console, consts, errors, hacks, publish, utils, version_registry + async def _generate_docs(dagger_client: dagger.Client): """This function will generate the README.md file from the templates/README.md.j2 template. @@ -69,15 +70,20 @@ async def _generate_release(dagger_client: dagger.Client): message=f"Which kind of new version would you like to cut? (latest version is {latest_version}))", choices=[ ("prerelease", latest_version.bump_prerelease()), + ("finalize", latest_version.finalize_version()), ("patch", latest_version.bump_patch()), + ("patch-prerelease", latest_version.bump_patch().bump_prerelease()), ("minor", latest_version.bump_minor()), + ("minor-prerelease", latest_version.bump_minor().bump_prerelease()), ("major", latest_version.bump_major()), + ("major-prerelease", latest_version.bump_major().bump_prerelease()), ], ), inquirer.Text("changelog_entry", message="What should the changelog entry be?", validate=lambda _, entry: len(entry) > 0), inquirer.Confirm("publish_now", message="Would you like to publish it to our remote registry now?"), ] ) + new_version, changelog_entry, publish_now = ( new_version_answers["new_version"], new_version_answers["changelog_entry"], diff --git a/airbyte-ci/connectors/base_images/base_images/consts.py b/airbyte-ci/connectors/base_images/base_images/consts.py index ce3701c300f1..cdee55c11a7e 100644 --- a/airbyte-ci/connectors/base_images/base_images/consts.py +++ b/airbyte-ci/connectors/base_images/base_images/consts.py @@ -2,10 +2,10 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # -"""This module declares constants used by the base_images module. -""" +"""This module declares constants used by the base_images module.""" import dagger + REMOTE_REGISTRY = "docker.io" PLATFORMS_WE_PUBLISH_FOR = (dagger.Platform("linux/amd64"), dagger.Platform("linux/arm64")) diff --git a/airbyte-ci/connectors/base_images/base_images/errors.py b/airbyte-ci/connectors/base_images/base_images/errors.py index 3e009806c80b..78596195cdb5 100644 --- a/airbyte-ci/connectors/base_images/base_images/errors.py +++ b/airbyte-ci/connectors/base_images/base_images/errors.py @@ -2,8 +2,7 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # -"""This module contains the exceptions used by the base_images module. -""" +"""This module contains the exceptions used by the base_images module.""" from typing import Union diff --git a/airbyte-ci/connectors/base_images/base_images/hacks.py b/airbyte-ci/connectors/base_images/base_images/hacks.py index 1d8ab1a9ad48..5f3bf76d2a1f 100644 --- a/airbyte-ci/connectors/base_images/base_images/hacks.py +++ b/airbyte-ci/connectors/base_images/base_images/hacks.py @@ -4,6 +4,7 @@ import dagger + # If we perform addition dagger operations on the container, we need to make sure that a mapping exists for the new field name. DAGGER_FIELD_NAME_TO_DOCKERFILE_INSTRUCTION = { "from": lambda field: f'FROM {field.args.get("address")}', diff --git a/airbyte-cdk/python/airbyte_cdk/connector_builder/__init__.py b/airbyte-ci/connectors/base_images/base_images/java/__init__.py similarity index 100% rename from airbyte-cdk/python/airbyte_cdk/connector_builder/__init__.py rename to airbyte-ci/connectors/base_images/base_images/java/__init__.py diff --git a/airbyte-ci/connectors/base_images/base_images/java/bases.py b/airbyte-ci/connectors/base_images/base_images/java/bases.py new file mode 100644 index 000000000000..3f8545f82278 --- /dev/null +++ b/airbyte-ci/connectors/base_images/base_images/java/bases.py @@ -0,0 +1,130 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# +from __future__ import annotations + +from typing import Callable, Final + +import dagger + +from base_images import bases, published_image +from base_images import sanity_checks as base_sanity_checks +from base_images.python import sanity_checks as python_sanity_checks +from base_images.root_images import AMAZON_CORRETTO_21_AL_2023 +from base_images.utils.dagger import sh_dash_c + + +class AirbyteJavaConnectorBaseImage(bases.AirbyteConnectorBaseImage): + root_image: Final[published_image.PublishedImage] = AMAZON_CORRETTO_21_AL_2023 + repository: Final[str] = "airbyte/java-connector-base" + + DD_AGENT_JAR_URL: Final[str] = "https://dtdg.co/latest-java-tracer" + BASE_SCRIPT_URL = "https://raw.githubusercontent.com/airbytehq/airbyte/6d8a3a2bc4f4ca79f10164447a90fdce5c9ad6f9/airbyte-integrations/bases/base/base.sh" + JAVA_BASE_SCRIPT_URL: Final[str] = ( + "https://raw.githubusercontent.com/airbytehq/airbyte/6d8a3a2bc4f4ca79f10164447a90fdce5c9ad6f9/airbyte-integrations/bases/base-java/javabase.sh" + ) + + def get_container(self, platform: dagger.Platform) -> dagger.Container: + """Returns the container used to build the base image for java connectors + We currently use the Amazon coretto image as a base. + We install some packages required to build java connectors. + We also download the datadog java agent jar and the javabase.sh script. + We set some env variables used by the javabase.sh script. + + Args: + platform (dagger.Platform): The platform this container should be built for. + + Returns: + dagger.Container: The container used to build the base image. + """ + + return ( + self.dagger_client.container(platform=platform) + .from_(self.root_image.address) + # Bundle RUN commands together to reduce the number of layers. + .with_exec( + sh_dash_c( + [ + # Shadow-utils is required to add a user with a specific UID and GID. + # tar is equired to untar java connector binary distributions. + # openssl is required because we need to ssh and scp sometimes. + # findutils is required for xargs, which is shipped as part of findutils. + f"yum install -y shadow-utils tar openssl findutils", + # Update first, but in the same .with_exec step as the package installation. + # Otherwise, we risk caching stale package URLs. + "yum update -y --security", + # Remove any dangly bits. + "yum clean all", + # Remove the yum cache to reduce the image size. + "rm -rf /var/cache/yum", + # Create the group 'airbyte' with the GID 1000 + f"groupadd --gid {self.USER_ID} {self.USER}", + # Create the user 'airbyte' with the UID 1000 + f"useradd --uid {self.USER_ID} --gid {self.USER} --shell /bin/bash --create-home {self.USER}", + # Create mount point for secrets and configs + "mkdir /secrets", + "mkdir /config", + # Create the cache airbyte directories and set the right permissions + f"mkdir --mode 755 {self.AIRBYTE_DIR_PATH}", + f"mkdir --mode 755 {self.CACHE_DIR_PATH}", + # Change the owner of the airbyte directory to the user 'airbyte' + f"chown -R {self.USER}:{self.USER} {self.AIRBYTE_DIR_PATH}", + f"chown -R {self.USER}:{self.USER} {self.CACHE_DIR_PATH}", + f"chown -R {self.USER}:{self.USER} /secrets", + f"chown -R {self.USER}:{self.USER} /config", + f"chown -R {self.USER}:{self.USER} /usr/share/pki/ca-trust-source", + f"chown -R {self.USER}:{self.USER} /etc/pki/ca-trust", + f"chown -R {self.USER}:{self.USER} /tmp", + ] + ) + ) + .with_workdir(self.AIRBYTE_DIR_PATH) + # Copy the datadog java agent jar from the internet. + .with_file("dd-java-agent.jar", self.dagger_client.http(self.DD_AGENT_JAR_URL), owner=self.USER) + # Copy base.sh from the git repo. + .with_file("base.sh", self.dagger_client.http(self.BASE_SCRIPT_URL), owner=self.USER) + # Copy javabase.sh from the git repo. + .with_file("javabase.sh", self.dagger_client.http(self.JAVA_BASE_SCRIPT_URL), owner=self.USER) + # Set a bunch of env variables used by base.sh. + .with_env_variable("AIRBYTE_SPEC_CMD", "/airbyte/javabase.sh --spec") + .with_env_variable("AIRBYTE_CHECK_CMD", "/airbyte/javabase.sh --check") + .with_env_variable("AIRBYTE_DISCOVER_CMD", "/airbyte/javabase.sh --discover") + .with_env_variable("AIRBYTE_READ_CMD", "/airbyte/javabase.sh --read") + .with_env_variable("AIRBYTE_WRITE_CMD", "/airbyte/javabase.sh --write") + .with_env_variable("AIRBYTE_ENTRYPOINT", "/airbyte/base.sh") + .with_entrypoint(["/airbyte/base.sh"]) + .with_user(self.USER) + ) + + async def run_sanity_checks(self, platform: dagger.Platform): + """Runs sanity checks on the base image container. + This method is called before image publication. + Consider it like a pre-flight check before take-off to the remote registry. + + Args: + platform (dagger.Platform): The platform on which the sanity checks should run. + """ + container = await self.get_container(platform) + for expected_rw_dir in [ + self.AIRBYTE_DIR_PATH, + self.CACHE_DIR_PATH, + "/tmp", + "/secrets", + "/config", + "/usr/share/pki/ca-trust-source", + "/etc/pki/ca-trust", + ]: + await base_sanity_checks.check_user_can_write_dir(container, self.USER, expected_rw_dir) + await base_sanity_checks.check_user_can_read_dir(container, self.USER, expected_rw_dir) + await base_sanity_checks.check_user_uid_guid(container, self.USER, self.USER_ID, self.USER_ID) + await base_sanity_checks.check_file_exists(container, "/airbyte/dd-java-agent.jar") + await base_sanity_checks.check_file_exists(container, "/airbyte/base.sh") + await base_sanity_checks.check_file_exists(container, "/airbyte/javabase.sh") + await base_sanity_checks.check_env_var_with_printenv(container, "AIRBYTE_SPEC_CMD", "/airbyte/javabase.sh --spec") + await base_sanity_checks.check_env_var_with_printenv(container, "AIRBYTE_CHECK_CMD", "/airbyte/javabase.sh --check") + await base_sanity_checks.check_env_var_with_printenv(container, "AIRBYTE_DISCOVER_CMD", "/airbyte/javabase.sh --discover") + await base_sanity_checks.check_env_var_with_printenv(container, "AIRBYTE_READ_CMD", "/airbyte/javabase.sh --read") + await base_sanity_checks.check_env_var_with_printenv(container, "AIRBYTE_WRITE_CMD", "/airbyte/javabase.sh --write") + await base_sanity_checks.check_env_var_with_printenv(container, "AIRBYTE_ENTRYPOINT", "/airbyte/base.sh") + await base_sanity_checks.check_a_command_is_available_using_version_option(container, "tar") + await base_sanity_checks.check_a_command_is_available_using_version_option(container, "openssl", "version") diff --git a/airbyte-ci/connectors/base_images/base_images/publish.py b/airbyte-ci/connectors/base_images/base_images/publish.py index 4f4ebcfaf3e9..e6e69fa8b7fe 100644 --- a/airbyte-ci/connectors/base_images/base_images/publish.py +++ b/airbyte-ci/connectors/base_images/base_images/publish.py @@ -4,6 +4,7 @@ import dagger + from base_images import bases, consts, published_image diff --git a/airbyte-ci/connectors/base_images/base_images/python/bases.py b/airbyte-ci/connectors/base_images/base_images/python/bases.py index 00c143fe9acc..191c05c20574 100644 --- a/airbyte-ci/connectors/base_images/base_images/python/bases.py +++ b/airbyte-ci/connectors/base_images/base_images/python/bases.py @@ -6,6 +6,7 @@ from typing import Callable, Final import dagger + from base_images import bases, published_image from base_images import sanity_checks as base_sanity_checks from base_images.python import sanity_checks as python_sanity_checks @@ -30,6 +31,10 @@ class AirbytePythonConnectorBaseImage(bases.AirbyteConnectorBaseImage): }, } + @property + def pip_cache_path(self) -> str: + return f"{self.CACHE_DIR_PATH}/pip" + def install_cdk_system_dependencies(self) -> Callable: def get_nltk_data_dir() -> dagger.Directory: """Returns a dagger directory containing the nltk data. @@ -71,7 +76,9 @@ def with_file_based_connector_dependencies(container: dagger.Container) -> dagge - nltk data """ container = with_tesseract_and_poppler(container) - container = container.with_exec(["mkdir", self.nltk_data_path]).with_directory(self.nltk_data_path, get_nltk_data_dir()) + container = container.with_exec(["mkdir", "-p", "755", self.nltk_data_path]).with_directory( + self.nltk_data_path, get_nltk_data_dir() + ) return container return with_file_based_connector_dependencies @@ -92,18 +99,17 @@ def get_container(self, platform: dagger.Platform) -> dagger.Container: return ( self.get_base_container(platform) - .with_mounted_cache("/root/.cache/pip", pip_cache_volume) - .with_exec(["ln", "-snf", "/usr/share/zoneinfo/Etc/UTC", "/etc/localtime"], use_entrypoint=True) - .with_exec(["pip", "install", "--upgrade", "pip==24.0", "setuptools==70.0.0"], use_entrypoint=True) + .with_mounted_cache(self.pip_cache_path, pip_cache_volume, owner=self.USER) + .with_env_variable("PIP_CACHE_DIR", self.pip_cache_path) + # Upgrade pip to the expected version + .with_exec(["pip", "install", "--upgrade", "pip==24.0", "setuptools==70.0.0"]) # Declare poetry specific environment variables .with_env_variable("POETRY_VIRTUALENVS_CREATE", "false") .with_env_variable("POETRY_VIRTUALENVS_IN_PROJECT", "false") .with_env_variable("POETRY_NO_INTERACTION", "1") .with_exec(["pip", "install", "poetry==1.6.1"]) - .with_exec( - ["sh", "-c", "apt-get update && apt-get upgrade -y && apt-get dist-upgrade -y && apt-get clean"], use_entrypoint=True - ) - .with_exec(["sh", "-c", "apt-get install -y socat=1.7.4.4-2"], use_entrypoint=True) + .with_exec(["sh", "-c", "apt-get update && apt-get upgrade -y && apt-get dist-upgrade -y && apt-get clean"]) + .with_exec(["sh", "-c", "apt-get install -y socat=1.7.4.4-2"]) # Install CDK system dependencies .with_(self.install_cdk_system_dependencies()) ) @@ -121,6 +127,12 @@ async def run_sanity_checks(self, platform: dagger.Platform): await base_sanity_checks.check_a_command_is_available_using_version_option(container, "bash") await python_sanity_checks.check_python_version(container, "3.10.14") await python_sanity_checks.check_pip_version(container, "24.0") + await base_sanity_checks.check_user_exists(container, self.USER, expected_uid=self.USER_ID, expected_gid=self.USER_ID) + await base_sanity_checks.check_user_can_read_dir(container, self.USER, self.AIRBYTE_DIR_PATH) + await base_sanity_checks.check_user_can_read_dir(container, self.USER, self.nltk_data_path) + await base_sanity_checks.check_user_can_read_dir(container, self.USER, self.CACHE_DIR_PATH) + await base_sanity_checks.check_user_can_write_dir(container, self.USER, self.AIRBYTE_DIR_PATH) + await base_sanity_checks.check_user_cant_write_dir(container, self.USER, self.CACHE_DIR_PATH) await python_sanity_checks.check_poetry_version(container, "1.6.1") await python_sanity_checks.check_python_image_has_expected_env_vars(container) await base_sanity_checks.check_a_command_is_available_using_version_option(container, "socat", "-V") diff --git a/airbyte-ci/connectors/base_images/base_images/python/sanity_checks.py b/airbyte-ci/connectors/base_images/base_images/python/sanity_checks.py index 58724281a1e2..798839009669 100644 --- a/airbyte-ci/connectors/base_images/base_images/python/sanity_checks.py +++ b/airbyte-ci/connectors/base_images/base_images/python/sanity_checks.py @@ -3,6 +3,7 @@ # import dagger + from base_images import errors from base_images import sanity_checks as base_sanity_checks diff --git a/airbyte-ci/connectors/base_images/base_images/root_images.py b/airbyte-ci/connectors/base_images/base_images/root_images.py index 190c0a26f79f..0134cd4d34e8 100644 --- a/airbyte-ci/connectors/base_images/base_images/root_images.py +++ b/airbyte-ci/connectors/base_images/base_images/root_images.py @@ -4,6 +4,7 @@ from .published_image import PublishedImage + PYTHON_3_9_18 = PublishedImage( registry="docker.io", repository="python", @@ -22,5 +23,12 @@ registry="docker.io", repository="python", tag="3.10.14-slim-bookworm", - sha="3b37199fbc5a730a551909b3efa7b29105c859668b7502451c163f2a4a7ae1ed", + sha="2407c61b1a18067393fecd8a22cf6fceede893b6aaca817bf9fbfe65e33614a3", +) + +AMAZON_CORRETTO_21_AL_2023 = PublishedImage( + registry="docker.io", + repository="amazoncorretto", + tag="21-al2023", + sha="5454cb606e803fce56861fdbc9eab365eaa2ab4f357ceb8c1d56f4f8c8a7bc33", ) diff --git a/airbyte-ci/connectors/base_images/base_images/sanity_checks.py b/airbyte-ci/connectors/base_images/base_images/sanity_checks.py index efcd8b614000..c57864e265e1 100644 --- a/airbyte-ci/connectors/base_images/base_images/sanity_checks.py +++ b/airbyte-ci/connectors/base_images/base_images/sanity_checks.py @@ -6,6 +6,7 @@ from typing import Optional import dagger + from base_images import errors @@ -99,3 +100,121 @@ async def check_socat_version(container: dagger.Container, expected_socat_versio raise errors.SanityCheckError(f"unexpected socat version: {version_number}") else: raise errors.SanityCheckError(f"Could not find the socat version in the version output: {socat_version_line}") + + +async def check_user_exists(container: dagger.Container, user: str, expected_uid: int, expected_gid: int): + """Check that a user exists in the container, can be impersonated and has the expected user id and group id. + + Args: + container (dagger.Container): The container on which the sanity checks should run. + user (str): The user to impersonate. + expected_uid (int): The expected user id. + expected_gid (int): The expected group id. + + Raises: + errors.SanityCheckError: Raised if the id command could not be executed or if the user does not exist. + """ + container = container.with_user(user) + try: + whoami_output = (await container.with_exec(["whoami"]).stdout()).strip() + except dagger.ExecError as e: + raise errors.SanityCheckError(e) + if whoami_output != user: + raise errors.SanityCheckError(f"The user {user} does not exist in the container.") + user_id = (await container.with_exec(["id", "-u"]).stdout()).strip() + if int(user_id) != expected_uid: + raise errors.SanityCheckError(f"Unexpected user id: {user_id}") + group_id = (await container.with_exec(["id", "-g"]).stdout()).strip() + if int(group_id) != expected_gid: + raise errors.SanityCheckError(f"Unexpected group id: {group_id}") + + +async def check_user_can_read_dir(container: dagger.Container, user: str, dir_path: str): + """Check that the given user has read permissions on files in a given directory. + + Args: + container (dagger.Container): The container on which the sanity checks should run. + user (str): The user to impersonate. + dir_path (str): The directory path to check. + + Raises: + errors.SanityCheckError: Raised if the given user could not read a file created in the given directory. + """ + try: + await container.with_exec(["touch", f"{dir_path}/foo.txt"]).with_user(user).with_exec(["cat", f"{dir_path}/foo.txt"]) + except dagger.ExecError: + raise errors.SanityCheckError(f"{dir_path} is not readable by {user}.") + + +async def check_user_cant_write_dir(container: dagger.Container, user: str, dir_path: str): + """Check that the given user can't write files to a given directory. + + Args: + container (dagger.Container): The container on which the sanity checks should run. + user (str): The user to impersonate. + dir_path (str): The directory path to check. + + Raises: + errors.SanityCheckError: Raised if the user could write a file in the given directory. + """ + try: + await container.with_user(user).with_exec(["touch", f"{dir_path}/foo.txt"]) + except dagger.ExecError: + return + raise errors.SanityCheckError(f"{dir_path} is writable by {user}.") + + +async def check_user_can_write_dir(container: dagger.Container, user: str, dir_path: str): + """Check that the given user has write permissions on files in a given directory. + + Args: + container (dagger.Container): The container on which the sanity checks should run. + user (str): The user to impersonate. + dir_path (str): The directory path to check. + + Raises: + errors.SanityCheckError: Raised if the user could write a file in the given directory. + """ + try: + await container.with_user(user).with_exec(["touch", f"{dir_path}/foo.txt"]) + except dagger.ExecError: + raise errors.SanityCheckError(f"{dir_path} is not writable by the {user}.") + + +async def check_file_exists(container: dagger.Container, file_path: str): + """Check that a file exists in the container. + + Args: + container (dagger.Container): The container on which the sanity checks should run. + file_path (str): The file path to check. + + Raises: + errors.SanityCheckError: Raised if the file does not exist. + """ + try: + await container.with_exec(["test", "-f", file_path]) + except dagger.ExecError: + raise errors.SanityCheckError(f"{file_path} does not exist.") + + +async def check_user_uid_guid(container: dagger.Container, user: str, expected_uid: int, expected_gid: int): + """Check that the given user has the expected user id and group id. + + Args: + container (dagger.Container): The container on which the sanity checks should run. + user (str): The user to impersonate. + expected_uid (int): The expected user id. + expected_gid (int): The expected group id. + + Raises: + errors.SanityCheckError: Raised if the user does not have the expected user id or group id. + """ + try: + user_id = (await container.with_user(user).with_exec(["id", "-u"]).stdout()).strip() + if int(user_id) != expected_uid: + raise errors.SanityCheckError(f"Unexpected user id: {user_id}") + group_id = (await container.with_user(user).with_exec(["id", "-g"]).stdout()).strip() + if int(group_id) != expected_gid: + raise errors.SanityCheckError(f"Unexpected group id: {group_id}") + except dagger.ExecError as e: + raise errors.SanityCheckError(e) diff --git a/airbyte-ci/connectors/base_images/base_images/templates/README.md.j2 b/airbyte-ci/connectors/base_images/base_images/templates/README.md.j2 index ad8dc7387047..c5484077a291 100644 --- a/airbyte-ci/connectors/base_images/base_images/templates/README.md.j2 +++ b/airbyte-ci/connectors/base_images/base_images/templates/README.md.j2 @@ -6,7 +6,7 @@ Our connector build pipeline ([`airbyte-ci`](https://github.com/airbytehq/airbyt Our base images are declared in code, using the [Dagger Python SDK](https://dagger-io.readthedocs.io/en/sdk-python-v0.6.4/). - [Python base image code declaration](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/base_images/base_images/python/bases.py) -- ~Java base image code declaration~ *TODO* +- [Java base image code declaration](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/base_images/base_images/java/bases.py) ## Where are the Dockerfiles? @@ -77,3 +77,27 @@ poetry run pytest poetry run mypy base_images --check-untyped-defs ``` +## CHANGELOG + +### 1.4.0 +- Declare a base image for our java connectors. + +### 1.3.1 +- Update the crane image address. The previous address was deleted by the maintainer. + +### 1.2.0 +- Improve new version prompt to pick bump type with optional pre-release version. + +### 1.1.0 +- Add a cache ttl for base image listing to avoid DockerHub rate limiting. + +### 1.0.4 +- Upgrade Dagger to `0.13.3` + +### 1.0.2 + +- Improved support for images with non-semantic-versioned tags. + +### 1.0.1 + +- Bumped dependencies ([#42581](https://github.com/airbytehq/airbyte/pull/42581)) diff --git a/airbyte-ci/connectors/base_images/base_images/utils/dagger.py b/airbyte-ci/connectors/base_images/base_images/utils/dagger.py new file mode 100644 index 000000000000..0a71d9e80416 --- /dev/null +++ b/airbyte-ci/connectors/base_images/base_images/utils/dagger.py @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + + +def sh_dash_c(lines: list[str]) -> list[str]: + """Wrap sequence of commands in shell for safe usage of dagger Container's with_exec method.""" + return ["sh", "-c", " && ".join(["set -o xtrace"] + lines)] diff --git a/airbyte-ci/connectors/base_images/base_images/utils/docker.py b/airbyte-ci/connectors/base_images/base_images/utils/docker.py index 822d917a7634..b7618fcb4aed 100644 --- a/airbyte-ci/connectors/base_images/base_images/utils/docker.py +++ b/airbyte-ci/connectors/base_images/base_images/utils/docker.py @@ -9,6 +9,7 @@ from typing import List, Tuple import dagger + from base_images import console, published_image @@ -31,10 +32,7 @@ def get_credentials() -> Tuple[str, str]: class CraneClient: - - CRANE_IMAGE_ADDRESS = ( - "gcr.io/go-containerregistry/crane/debug:v0.15.1@sha256:f6ddf8e2c47df889e06e33c3e83b84251ac19c8728a670ff39f2ca9e90c4f905" - ) + CRANE_IMAGE_ADDRESS = "gcr.io/go-containerregistry/crane/debug:c195f151efe3369874c72662cd69ad43ee485128@sha256:94f61956845714bea3b788445454ae4827f49a90dcd9dac28255c4cccb6220ad" def __init__(self, dagger_client: dagger.Client, docker_credentials: Tuple[str, str], cache_ttl_seconds: int = 0): self.docker_hub_username_secret = dagger_client.set_secret("DOCKER_HUB_USERNAME", docker_credentials[0]) diff --git a/airbyte-ci/connectors/base_images/base_images/version_registry.py b/airbyte-ci/connectors/base_images/base_images/version_registry.py index 41337c8006a8..df2a137a6c17 100644 --- a/airbyte-ci/connectors/base_images/base_images/version_registry.py +++ b/airbyte-ci/connectors/base_images/base_images/version_registry.py @@ -11,13 +11,16 @@ import dagger import semver + from base_images import consts, published_image from base_images.bases import AirbyteConnectorBaseImage +from base_images.java.bases import AirbyteJavaConnectorBaseImage from base_images.python.bases import AirbyteManifestOnlyConnectorBaseImage, AirbytePythonConnectorBaseImage from base_images.utils import docker from connector_ops.utils import ConnectorLanguage # type: ignore -MANAGED_BASE_IMAGES = [AirbytePythonConnectorBaseImage] + +MANAGED_BASE_IMAGES = [AirbytePythonConnectorBaseImage, AirbyteJavaConnectorBaseImage] @dataclass @@ -270,6 +273,12 @@ async def get_manifest_only_registry( ) +async def get_java_registry( + dagger_client: dagger.Client, docker_credentials: Tuple[str, str], cache_ttl_seconds: int = 0 +) -> VersionRegistry: + return await VersionRegistry.load(AirbyteJavaConnectorBaseImage, dagger_client, docker_credentials, cache_ttl_seconds=cache_ttl_seconds) + + async def get_registry_for_language( dagger_client: dagger.Client, language: ConnectorLanguage, docker_credentials: Tuple[str, str], cache_ttl_seconds: int = 0 ) -> VersionRegistry: @@ -291,6 +300,8 @@ async def get_registry_for_language( return await get_python_registry(dagger_client, docker_credentials, cache_ttl_seconds=cache_ttl_seconds) elif language is ConnectorLanguage.MANIFEST_ONLY: return await get_manifest_only_registry(dagger_client, docker_credentials, cache_ttl_seconds=cache_ttl_seconds) + elif language is ConnectorLanguage.JAVA: + return await get_java_registry(dagger_client, docker_credentials, cache_ttl_seconds=cache_ttl_seconds) else: raise NotImplementedError(f"Registry for language {language} is not implemented yet.") @@ -298,5 +309,6 @@ async def get_registry_for_language( async def get_all_registries(dagger_client: dagger.Client, docker_credentials: Tuple[str, str]) -> List[VersionRegistry]: return [ await get_python_registry(dagger_client, docker_credentials), - # await get_java_registry(dagger_client), + await get_java_registry(dagger_client, docker_credentials), + # await get_manifest_only_registry(dagger_client, docker_credentials), ] diff --git a/airbyte-ci/connectors/base_images/generated/changelogs/airbyte_java_connector_base.json b/airbyte-ci/connectors/base_images/generated/changelogs/airbyte_java_connector_base.json new file mode 100644 index 000000000000..031227fd0004 --- /dev/null +++ b/airbyte-ci/connectors/base_images/generated/changelogs/airbyte_java_connector_base.json @@ -0,0 +1,37 @@ +[ + { + "version": "2.0.0", + "changelog_entry": "~Release non root base image~", + "dockerfile_example": "FROM docker.io/amazoncorretto:21-al2023@sha256:5454cb606e803fce56861fdbc9eab365eaa2ab4f357ceb8c1d56f4f8c8a7bc33\nRUN sh -c set -o xtrace && yum install -y shadow-utils tar openssl findutils && yum update -y --security && yum clean all && rm -rf /var/cache/yum && groupadd --gid 1000 airbyte && useradd --uid 1000 --gid airbyte --shell /bin/bash --create-home airbyte && mkdir /secrets && mkdir /config && mkdir --mode 755 /airbyte && mkdir --mode 755 /custom_cache && chown -R airbyte:airbyte /airbyte && chown -R airbyte:airbyte /custom_cache && chown -R airbyte:airbyte /secrets && chown -R airbyte:airbyte /config && chown -R airbyte:airbyte /usr/share/pki/ca-trust-source && chown -R airbyte:airbyte /etc/pki/ca-trust && chown -R airbyte:airbyte /tmp\nENV AIRBYTE_SPEC_CMD=/airbyte/javabase.sh --spec\nENV AIRBYTE_CHECK_CMD=/airbyte/javabase.sh --check\nENV AIRBYTE_DISCOVER_CMD=/airbyte/javabase.sh --discover\nENV AIRBYTE_READ_CMD=/airbyte/javabase.sh --read\nENV AIRBYTE_WRITE_CMD=/airbyte/javabase.sh --write\nENV AIRBYTE_ENTRYPOINT=/airbyte/base.sh" + }, + { + "version": "2.0.0-rc.2", + "changelog_entry": "Fine tune permissions and reproduce platform java base implementation", + "dockerfile_example": "FROM docker.io/amazoncorretto:21-al2023@sha256:5454cb606e803fce56861fdbc9eab365eaa2ab4f357ceb8c1d56f4f8c8a7bc33\nRUN sh -c set -o xtrace && yum install -y shadow-utils tar openssl findutils && yum update -y --security && yum clean all && rm -rf /var/cache/yum && groupadd --gid 1000 airbyte && useradd --uid 1000 --gid airbyte --shell /bin/bash --create-home airbyte && mkdir /secrets && mkdir /config && mkdir --mode 755 /airbyte && mkdir --mode 755 /custom_cache && chown -R airbyte:airbyte /airbyte && chown -R airbyte:airbyte /custom_cache && chown -R airbyte:airbyte /secrets && chown -R airbyte:airbyte /config && chown -R airbyte:airbyte /usr/share/pki/ca-trust-source && chown -R airbyte:airbyte /etc/pki/ca-trust && chown -R airbyte:airbyte /tmp\nENV AIRBYTE_SPEC_CMD=/airbyte/javabase.sh --spec\nENV AIRBYTE_CHECK_CMD=/airbyte/javabase.sh --check\nENV AIRBYTE_DISCOVER_CMD=/airbyte/javabase.sh --discover\nENV AIRBYTE_READ_CMD=/airbyte/javabase.sh --read\nENV AIRBYTE_WRITE_CMD=/airbyte/javabase.sh --write\nENV AIRBYTE_ENTRYPOINT=/airbyte/base.sh" + }, + { + "version": "2.0.0-rc.1", + "changelog_entry": " Make the java base image non root", + "dockerfile_example": "FROM docker.io/amazoncorretto:21-al2023@sha256:5454cb606e803fce56861fdbc9eab365eaa2ab4f357ceb8c1d56f4f8c8a7bc33\nRUN sh -c set -o xtrace && yum update -y --security && yum install -y /usr/sbin/adduser tar openssl findutils && yum clean all && adduser --base-dir /airbyte --uid 1000 --user-group --system airbyte && mkdir --mode 755 /airbyte && mkdir --mode 755 /custom_cache && chown -R airbyte:airbyte /airbyte\nENV AIRBYTE_SPEC_CMD=/airbyte/javabase.sh --spec\nENV AIRBYTE_CHECK_CMD=/airbyte/javabase.sh --check\nENV AIRBYTE_DISCOVER_CMD=/airbyte/javabase.sh --discover\nENV AIRBYTE_READ_CMD=/airbyte/javabase.sh --read\nENV AIRBYTE_WRITE_CMD=/airbyte/javabase.sh --write\nENV AIRBYTE_ENTRYPOINT=/airbyte/base.sh" + }, + { + "version": "1.0.0", + "changelog_entry": "Create a base image for our java connectors based on Amazon Corretto.", + "dockerfile_example": "FROM docker.io/amazoncorretto:21-al2023@sha256:5454cb606e803fce56861fdbc9eab365eaa2ab4f357ceb8c1d56f4f8c8a7bc33\nRUN sh -c set -o xtrace && yum update -y --security && yum install -y tar openssl findutils && yum clean all\nENV AIRBYTE_SPEC_CMD=/airbyte/javabase.sh --spec\nENV AIRBYTE_CHECK_CMD=/airbyte/javabase.sh --check\nENV AIRBYTE_DISCOVER_CMD=/airbyte/javabase.sh --discover\nENV AIRBYTE_READ_CMD=/airbyte/javabase.sh --read\nENV AIRBYTE_WRITE_CMD=/airbyte/javabase.sh --write\nENV AIRBYTE_ENTRYPOINT=/airbyte/base.sh" + }, + { + "version": "1.0.0-rc.4", + "changelog_entry": "Bundle yum calls in a single RUN", + "dockerfile_example": "FROM docker.io/amazoncorretto:21-al2023@sha256:5454cb606e803fce56861fdbc9eab365eaa2ab4f357ceb8c1d56f4f8c8a7bc33\nRUN sh -c set -o xtrace && yum update -y --security && yum install -y tar openssl findutils && yum clean all\nENV AIRBYTE_SPEC_CMD=/airbyte/javabase.sh --spec\nENV AIRBYTE_CHECK_CMD=/airbyte/javabase.sh --check\nENV AIRBYTE_DISCOVER_CMD=/airbyte/javabase.sh --discover\nENV AIRBYTE_READ_CMD=/airbyte/javabase.sh --read\nENV AIRBYTE_WRITE_CMD=/airbyte/javabase.sh --write\nENV AIRBYTE_ENTRYPOINT=/airbyte/base.sh" + }, + { + "version": "1.0.0-rc.2", + "changelog_entry": "Set entrypoint to base.sh", + "dockerfile_example": "FROM docker.io/amazoncorretto:21-al2023@sha256:5454cb606e803fce56861fdbc9eab365eaa2ab4f357ceb8c1d56f4f8c8a7bc33\nRUN yum update -y --security\nRUN yum install -y tar openssl findutils\nENV AIRBYTE_SPEC_CMD=/airbyte/javabase.sh --spec\nENV AIRBYTE_CHECK_CMD=/airbyte/javabase.sh --check\nENV AIRBYTE_DISCOVER_CMD=/airbyte/javabase.sh --discover\nENV AIRBYTE_READ_CMD=/airbyte/javabase.sh --read\nENV AIRBYTE_WRITE_CMD=/airbyte/javabase.sh --write\nENV AIRBYTE_ENTRYPOINT=/airbyte/base.sh" + }, + { + "version": "1.0.0-rc.1", + "changelog_entry": "Create a base image for our java connectors.", + "dockerfile_example": "FROM docker.io/amazoncorretto:21-al2023@sha256:5454cb606e803fce56861fdbc9eab365eaa2ab4f357ceb8c1d56f4f8c8a7bc33\nRUN yum update -y --security\nRUN yum install -y tar openssl findutils\nENV AIRBYTE_SPEC_CMD=/airbyte/javabase.sh --spec\nENV AIRBYTE_CHECK_CMD=/airbyte/javabase.sh --check\nENV AIRBYTE_DISCOVER_CMD=/airbyte/javabase.sh --discover\nENV AIRBYTE_READ_CMD=/airbyte/javabase.sh --read\nENV AIRBYTE_WRITE_CMD=/airbyte/javabase.sh --write\nENV AIRBYTE_ENTRYPOINT=/airbyte/base.sh" + } +] diff --git a/airbyte-ci/connectors/base_images/generated/changelogs/airbyte_python_connector_base.json b/airbyte-ci/connectors/base_images/generated/changelogs/airbyte_python_connector_base.json index 08e6c5e1688d..56bce39346fd 100644 --- a/airbyte-ci/connectors/base_images/generated/changelogs/airbyte_python_connector_base.json +++ b/airbyte-ci/connectors/base_images/generated/changelogs/airbyte_python_connector_base.json @@ -1,4 +1,14 @@ [ + { + "version": "3.0.0", + "changelog_entry": "Create airbyte user", + "dockerfile_example": "FROM docker.io/python:3.10.14-slim-bookworm@sha256:2407c61b1a18067393fecd8a22cf6fceede893b6aaca817bf9fbfe65e33614a3\nRUN ln -snf /usr/share/zoneinfo/Etc/UTC /etc/localtime\nRUN adduser --uid 1000 --system --group --no-create-home airbyte\nRUN mkdir --mode 755 /custom_cache\nRUN mkdir --mode 755 /airbyte\nRUN chown airbyte:airbyte /airbyte\nENV PIP_CACHE_DIR=/custom_cache/pip\nRUN pip install --upgrade pip==24.0 setuptools==70.0.0\nENV POETRY_VIRTUALENVS_CREATE=false\nENV POETRY_VIRTUALENVS_IN_PROJECT=false\nENV POETRY_NO_INTERACTION=1\nRUN pip install poetry==1.6.1\nRUN sh -c apt-get update && apt-get upgrade -y && apt-get dist-upgrade -y && apt-get clean\nRUN sh -c apt-get install -y socat=1.7.4.4-2\nRUN sh -c apt-get update && apt-get install -y tesseract-ocr=5.3.0-2 poppler-utils=22.12.0-2+b1\nRUN mkdir -p 755 /usr/share/nltk_data" + }, + { + "version": "3.0.0-rc.1", + "changelog_entry": "Update Python 3.10.4 image + create airbyte user", + "dockerfile_example": "FROM docker.io/python:3.10.14-slim-bookworm@sha256:2407c61b1a18067393fecd8a22cf6fceede893b6aaca817bf9fbfe65e33614a3\nRUN ln -snf /usr/share/zoneinfo/Etc/UTC /etc/localtime\nRUN adduser --uid 1000 --system --group --no-create-home airbyte\nRUN mkdir --mode 755 /custom_cache\nRUN mkdir --mode 755 /airbyte\nRUN chown airbyte:airbyte /airbyte\nENV PIP_CACHE_DIR=/custom_cache/pip\nRUN pip install --upgrade pip==24.0 setuptools==70.0.0\nENV POETRY_VIRTUALENVS_CREATE=false\nENV POETRY_VIRTUALENVS_IN_PROJECT=false\nENV POETRY_NO_INTERACTION=1\nRUN pip install poetry==1.6.1\nRUN sh -c apt-get update && apt-get upgrade -y && apt-get dist-upgrade -y && apt-get clean\nRUN sh -c apt-get install -y socat=1.7.4.4-2\nRUN sh -c apt-get update && apt-get install -y tesseract-ocr=5.3.0-2 poppler-utils=22.12.0-2+b1\nRUN mkdir -p 755 /usr/share/nltk_data" + }, { "version": "2.0.0", "changelog_entry": "Use Python 3.10", @@ -14,6 +24,11 @@ "changelog_entry": "Fix Python 3.9.19 image digest", "dockerfile_example": "FROM docker.io/python:3.9.19-slim-bookworm@sha256:088d9217202188598aac37f8db0929345e124a82134ac66b8bb50ee9750b045b\nRUN ln -snf /usr/share/zoneinfo/Etc/UTC /etc/localtime\nRUN pip install --upgrade pip==24.0 setuptools==70.0.0\nENV POETRY_VIRTUALENVS_CREATE=false\nENV POETRY_VIRTUALENVS_IN_PROJECT=false\nENV POETRY_NO_INTERACTION=1\nRUN pip install poetry==1.6.1\nRUN sh -c apt update && apt-get install -y socat=1.7.4.4-2\nRUN sh -c apt-get update && apt-get install -y tesseract-ocr=5.3.0-2 poppler-utils=22.12.0-2+b1\nRUN mkdir /usr/share/nltk_data" }, + { + "version": "1.2.2-rc.1", + "changelog_entry": "Create an airbyte user and use it", + "dockerfile_example": "FROM docker.io/python:3.9.19-slim-bookworm@sha256:088d9217202188598aac37f8db0929345e124a82134ac66b8bb50ee9750b045b\nRUN ln -snf /usr/share/zoneinfo/Etc/UTC /etc/localtime\nRUN sh -c apt update && apt-get install -y socat=1.7.4.4-2\nRUN adduser --uid 1000 --system --group --no-create-home airbyte\nRUN mkdir --mode 755 /custom_cache\nRUN mkdir --mode 755 /airbyte\nRUN chown airbyte:airbyte /airbyte\nENV PIP_CACHE_DIR=/custom_cache/pip\nRUN pip install --upgrade pip==24.0 setuptools==70.0.0\nENV POETRY_VIRTUALENVS_CREATE=false\nENV POETRY_VIRTUALENVS_IN_PROJECT=false\nENV POETRY_NO_INTERACTION=1\nRUN pip install poetry==1.6.1\nRUN sh -c apt-get update && apt-get install -y tesseract-ocr=5.3.0-2 poppler-utils=22.12.0-2+b1\nRUN mkdir -p 755 /usr/share/nltk_data" + }, { "version": "1.2.1", "changelog_entry": "Upgrade to Python 3.9.19 + update pip and setuptools", diff --git a/airbyte-ci/connectors/base_images/pyproject.toml b/airbyte-ci/connectors/base_images/pyproject.toml index 46a7b98d6a2b..98b8f45e9b36 100644 --- a/airbyte-ci/connectors/base_images/pyproject.toml +++ b/airbyte-ci/connectors/base_images/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "airbyte-connectors-base-images" -version = "1.1.0" +version = "1.5.0" description = "This package is used to generate and publish the base images for Airbyte Connectors." authors = ["Augustin Lafanechere "] readme = "README.md" diff --git a/airbyte-ci/connectors/base_images/tests/test_python/test_bases.py b/airbyte-ci/connectors/base_images/tests/test_python/test_bases.py index 0072790fa7ad..531941a2bb19 100644 --- a/airbyte-ci/connectors/base_images/tests/test_python/test_bases.py +++ b/airbyte-ci/connectors/base_images/tests/test_python/test_bases.py @@ -30,7 +30,7 @@ async def test_run_sanity_checks(self, dagger_client, current_platform, dummy_ve async def test_pip_cache_volume(self, dagger_client, current_platform, dummy_version): base_image_version = bases.AirbytePythonConnectorBaseImage(dagger_client, dummy_version) container = base_image_version.get_container(current_platform) - assert "/root/.cache/pip" in await container.mounts() + assert "/custom_cache/pip" in await container.mounts() async def test_is_using_bookworm(self, dagger_client, current_platform, dummy_version): base_image_version = bases.AirbytePythonConnectorBaseImage(dagger_client, dummy_version) diff --git a/airbyte-ci/connectors/ci_credentials/ci_credentials/main.py b/airbyte-ci/connectors/ci_credentials/ci_credentials/main.py index 9f2f47456848..6f31626adf7b 100644 --- a/airbyte-ci/connectors/ci_credentials/ci_credentials/main.py +++ b/airbyte-ci/connectors/ci_credentials/ci_credentials/main.py @@ -11,6 +11,7 @@ from . import SecretsManager + logger = Logger() ENV_GCP_GSM_CREDENTIALS = "GCP_GSM_CREDENTIALS" diff --git a/airbyte-ci/connectors/ci_credentials/ci_credentials/models.py b/airbyte-ci/connectors/ci_credentials/ci_credentials/models.py index 067e89da1d68..84295b70de45 100644 --- a/airbyte-ci/connectors/ci_credentials/ci_credentials/models.py +++ b/airbyte-ci/connectors/ci_credentials/ci_credentials/models.py @@ -8,6 +8,7 @@ from dataclasses import dataclass + DEFAULT_SECRET_FILE = "config" diff --git a/airbyte-ci/connectors/ci_credentials/ci_credentials/secrets_manager.py b/airbyte-ci/connectors/ci_credentials/ci_credentials/secrets_manager.py index c024caf01587..554d0d3f604f 100644 --- a/airbyte-ci/connectors/ci_credentials/ci_credentials/secrets_manager.py +++ b/airbyte-ci/connectors/ci_credentials/ci_credentials/secrets_manager.py @@ -17,6 +17,7 @@ from .models import DEFAULT_SECRET_FILE, RemoteSecret, Secret + DEFAULT_SECRET_FILE_WITH_EXT = DEFAULT_SECRET_FILE + ".json" GSM_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) diff --git a/airbyte-ci/connectors/common_utils/common_utils/google_api.py b/airbyte-ci/connectors/common_utils/common_utils/google_api.py index 68ff38ae5a9f..69d12894ac90 100644 --- a/airbyte-ci/connectors/common_utils/common_utils/google_api.py +++ b/airbyte-ci/connectors/common_utils/common_utils/google_api.py @@ -11,6 +11,7 @@ from .logger import Logger + TOKEN_TTL = 3600 diff --git a/airbyte-ci/connectors/connector_ops/connector_ops/required_reviewer_checks.py b/airbyte-ci/connectors/connector_ops/connector_ops/required_reviewer_checks.py index f109c4299c86..b28bbbf0d1a8 100644 --- a/airbyte-ci/connectors/connector_ops/connector_ops/required_reviewer_checks.py +++ b/airbyte-ci/connectors/connector_ops/connector_ops/required_reviewer_checks.py @@ -5,8 +5,10 @@ from typing import Dict, List, Optional, Set, Tuple, Union import yaml + from connector_ops import utils + # The breaking change reviewers is still in active use. BREAKING_CHANGE_REVIEWERS = {"breaking-change-reviewers"} CERTIFIED_MANIFEST_ONLY_CONNECTOR_REVIEWERS = {"dev-python"} diff --git a/airbyte-ci/connectors/connector_ops/connector_ops/utils.py b/airbyte-ci/connectors/connector_ops/connector_ops/utils.py index dfbc65734622..32e03ebdbcf0 100644 --- a/airbyte-ci/connectors/connector_ops/connector_ops/utils.py +++ b/airbyte-ci/connectors/connector_ops/connector_ops/utils.py @@ -22,6 +22,7 @@ from rich.console import Console from simpleeval import simple_eval + console = Console() DIFFED_BRANCH = os.environ.get("DIFFED_BRANCH", "origin/master") @@ -128,7 +129,7 @@ def has_local_cdk_ref(build_file: Path) -> bool: """Return true if the build file uses the local CDK. Args: - build_file (Path): Path to the build.gradle file of the project. + build_file (Path): Path to the build.gradle/build.gradle.kts file of the project. Returns: bool: True if using local CDK. @@ -148,7 +149,7 @@ def get_gradle_dependencies_block(build_file: Path) -> str: """Get the dependencies block of a Gradle file. Args: - build_file (Path): Path to the build.gradle file of the project. + build_file (Path): Path to the build.gradle/build.gradle.kts file of the project. Returns: str: The dependencies block of the Gradle file. @@ -215,7 +216,7 @@ def get_all_gradle_dependencies( """Recursively retrieve all transitive dependencies of a Gradle project. Args: - build_file (Path): Path to the build.gradle file of the project. + build_file (Path): Path to the build.gradle/build.gradle.kts file of the project. found_dependencies (List[Path]): List of dependencies that have already been found. Defaults to None. Returns: @@ -225,10 +226,12 @@ def get_all_gradle_dependencies( found_dependencies = [] project_dependencies, test_dependencies = parse_gradle_dependencies(build_file) all_dependencies = project_dependencies + test_dependencies if with_test_dependencies else project_dependencies + valid_build_files = ["build.gradle", "build.gradle.kts"] for dependency_path in all_dependencies: - if dependency_path not in found_dependencies and Path(dependency_path / "build.gradle").exists(): - found_dependencies.append(dependency_path) - get_all_gradle_dependencies(dependency_path / "build.gradle", with_test_dependencies, found_dependencies) + for build_file in valid_build_files: + if dependency_path not in found_dependencies and Path(dependency_path / build_file).exists(): + found_dependencies.append(dependency_path) + get_all_gradle_dependencies(dependency_path / build_file, with_test_dependencies, found_dependencies) return found_dependencies @@ -706,10 +709,14 @@ def __repr__(self) -> str: @functools.lru_cache(maxsize=2) def get_local_dependency_paths(self, with_test_dependencies: bool = True) -> Set[Path]: dependencies_paths = [] + build_script = "build.gradle" + if Path(self.code_directory / "build.gradle.kts").exists(): + build_script = "build.gradle.kts" + if self.language == ConnectorLanguage.JAVA: dependencies_paths += [Path("./airbyte-cdk/java/airbyte-cdk"), Path("./airbyte-cdk/bulk")] dependencies_paths += get_all_gradle_dependencies( - self.code_directory / "build.gradle", with_test_dependencies=with_test_dependencies + self.code_directory / build_script, with_test_dependencies=with_test_dependencies ) return sorted(list(set(dependencies_paths))) diff --git a/airbyte-ci/connectors/connectors_insights/README.md b/airbyte-ci/connectors/connectors_insights/README.md index af70ebff0059..f7c2fbdf3271 100644 --- a/airbyte-ci/connectors/connectors_insights/README.md +++ b/airbyte-ci/connectors/connectors_insights/README.md @@ -56,6 +56,9 @@ This CLI is currently running nightly in GitHub Actions. The workflow can be fou ## Changelog +### 0.3.5 +Fix permissions issue when installing `pylint` in connector container. + ### 0.3.4 Update `dagger` to `0.13.3`. diff --git a/airbyte-ci/connectors/connectors_insights/pyproject.toml b/airbyte-ci/connectors/connectors_insights/pyproject.toml index 3857ce6b3e83..1d98699a1e57 100644 --- a/airbyte-ci/connectors/connectors_insights/pyproject.toml +++ b/airbyte-ci/connectors/connectors_insights/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "connectors-insights" -version = "0.3.4" +version = "0.3.5" description = "" authors = ["Airbyte "] readme = "README.md" diff --git a/airbyte-ci/connectors/connectors_insights/src/connectors_insights/cli.py b/airbyte-ci/connectors/connectors_insights/src/connectors_insights/cli.py index ed400f6ef598..1587db395bd9 100644 --- a/airbyte-ci/connectors/connectors_insights/src/connectors_insights/cli.py +++ b/airbyte-ci/connectors/connectors_insights/src/connectors_insights/cli.py @@ -12,6 +12,7 @@ import dagger from anyio import Semaphore from connector_ops.utils import Connector # type: ignore + from connectors_insights.insights import generate_insights_for_connector from connectors_insights.result_backends import GCSBucket, LocalDir from connectors_insights.utils import gcs_uri_to_bucket_key, get_all_connectors_in_directory, remove_strict_encrypt_suffix diff --git a/airbyte-ci/connectors/connectors_insights/src/connectors_insights/insights.py b/airbyte-ci/connectors/connectors_insights/src/connectors_insights/insights.py index 8cdf36d6b154..5267c88df8ce 100644 --- a/airbyte-ci/connectors/connectors_insights/src/connectors_insights/insights.py +++ b/airbyte-ci/connectors/connectors_insights/src/connectors_insights/insights.py @@ -9,6 +9,7 @@ from typing import TYPE_CHECKING import requests + from connectors_insights.hacks import get_ci_on_master_report from connectors_insights.models import ConnectorInsights from connectors_insights.pylint import get_pylint_output diff --git a/airbyte-ci/connectors/connectors_insights/src/connectors_insights/pylint.py b/airbyte-ci/connectors/connectors_insights/src/connectors_insights/pylint.py index 67bef0b7e535..eef3fe1cd086 100644 --- a/airbyte-ci/connectors/connectors_insights/src/connectors_insights/pylint.py +++ b/airbyte-ci/connectors/connectors_insights/src/connectors_insights/pylint.py @@ -7,6 +7,7 @@ from typing import TYPE_CHECKING from connector_ops.utils import ConnectorLanguage # type: ignore + from connectors_insights.utils import never_fail_exec if TYPE_CHECKING: @@ -45,6 +46,7 @@ async def get_pylint_output(dagger_client: dagger.Client, connector: Connector) return await ( dagger_client.container() .from_(connector.image_address) + .with_user("root") .with_mounted_cache("/root/.cache/pip", pip_cache_volume) .with_new_file("__init__.py", contents="") .with_exec(["pip", "install", "pylint"]) diff --git a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/assets.py b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/assets.py index fa0f86795e47..c78308c980d9 100644 --- a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/assets.py +++ b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/assets.py @@ -6,6 +6,7 @@ from typing import TYPE_CHECKING from connector_ops.utils import Connector # type: ignore + from connectors_qa.models import Check, CheckCategory, CheckResult if TYPE_CHECKING: @@ -27,7 +28,6 @@ class CheckConnectorIconIsAvailable(AssetsCheck): requires_metadata = False def _check_is_valid_svg(self, icon_path: Path) -> Tuple[bool, str | None]: - try: # Ensure the file has an .svg extension if not icon_path.suffix.lower() == ".svg": diff --git a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/documentation/documentation.py b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/documentation/documentation.py index 700b7162ed27..5665882b52ce 100644 --- a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/documentation/documentation.py +++ b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/documentation/documentation.py @@ -7,9 +7,10 @@ import requests # type: ignore from connector_ops.utils import Connector, ConnectorLanguage # type: ignore -from connectors_qa.models import Check, CheckCategory, CheckResult from pydash.objects import get # type: ignore +from connectors_qa.models import Check, CheckCategory, CheckResult + from .helpers import ( generate_description, prepare_changelog_to_compare, diff --git a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/metadata.py b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/metadata.py index d06a7945ef5c..d7f0cd0c5df7 100644 --- a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/metadata.py +++ b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/metadata.py @@ -5,9 +5,10 @@ import toml from connector_ops.utils import Connector, ConnectorLanguage # type: ignore +from metadata_service.validators.metadata_validator import PRE_UPLOAD_VALIDATORS, ValidatorOptions, validate_and_load # type: ignore + from connectors_qa import consts from connectors_qa.models import Check, CheckCategory, CheckResult -from metadata_service.validators.metadata_validator import PRE_UPLOAD_VALIDATORS, ValidatorOptions, validate_and_load # type: ignore class MetadataCheck(Check): @@ -48,7 +49,9 @@ def get_expected_language_tag(self, connector: Connector) -> str: connector.code_directory / consts.PYPROJECT_FILE_NAME ).exists(): return self.PYTHON_LANGUAGE_TAG - elif (connector.code_directory / consts.GRADLE_FILE_NAME).exists(): + elif (connector.code_directory / consts.GRADLE_FILE_NAME).exists() or ( + connector.code_directory / consts.GRADLE_KOTLIN_FILE_NAME + ).exists(): return self.JAVA_LANGUAGE_TAG else: raise ValueError("Could not infer the language tag from the connector directory") diff --git a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/packaging.py b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/packaging.py index 806fcb232c2d..608e9b9dc9fb 100644 --- a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/packaging.py +++ b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/packaging.py @@ -3,9 +3,10 @@ import semver import toml from connector_ops.utils import Connector, ConnectorLanguage # type: ignore +from pydash.objects import get # type: ignore + from connectors_qa import consts from connectors_qa.models import Check, CheckCategory, CheckResult -from pydash.objects import get # type: ignore class PackagingCheck(Check): diff --git a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/security.py b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/security.py index 7c1aa51e2804..623368022530 100644 --- a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/security.py +++ b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/security.py @@ -4,9 +4,10 @@ from typing import Iterable, Optional, Set, Tuple from connector_ops.utils import Connector, ConnectorLanguage # type: ignore +from pydash.objects import get # type: ignore + from connectors_qa import consts from connectors_qa.models import Check, CheckCategory, CheckResult -from pydash.objects import get # type: ignore class SecurityCheck(Check): @@ -26,6 +27,7 @@ class CheckConnectorUsesHTTPSOnly(SecurityCheck): "tests", "unit_tests", "integration_tests", + "test-integration", "build", "source-file", ".pytest_cache", diff --git a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/testing.py b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/testing.py index fb70e431fd91..39860d002a74 100644 --- a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/testing.py +++ b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/testing.py @@ -2,9 +2,10 @@ from connector_ops.utils import Connector # type: ignore -from connectors_qa.models import Check, CheckCategory, CheckResult from pydash.collections import find # type: ignore +from connectors_qa.models import Check, CheckCategory, CheckResult + class TestingCheck(Check): category = CheckCategory.TESTING diff --git a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/cli.py b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/cli.py index 77ec4a0879d0..1f680c3c12ea 100644 --- a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/cli.py +++ b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/cli.py @@ -6,11 +6,12 @@ import asyncclick as click import asyncer from connector_ops.utils import Connector # type: ignore +from jinja2 import Environment, PackageLoader, select_autoescape + from connectors_qa.checks import ENABLED_CHECKS from connectors_qa.consts import CONNECTORS_QA_DOC_TEMPLATE_NAME from connectors_qa.models import Check, CheckCategory, CheckResult, CheckStatus, Report from connectors_qa.utils import get_all_connectors_in_directory, remove_strict_encrypt_suffix -from jinja2 import Environment, PackageLoader, select_autoescape # HELPERS diff --git a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/consts.py b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/consts.py index ba17a607cc18..2d4d863aab65 100644 --- a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/consts.py +++ b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/consts.py @@ -9,6 +9,7 @@ DOCKERFILE_NAME = "Dockerfile" DOCUMENTATION_STANDARDS_URL = "https://hackmd.io/Bz75cgATSbm7DjrAqgl4rw" GRADLE_FILE_NAME = "build.gradle" +GRADLE_KOTLIN_FILE_NAME = "build.gradle.kts" LICENSE_FAQ_URL = "https://docs.airbyte.com/developer-guides/licenses/license-faq" LOW_CODE_MANIFEST_FILE_NAME = "manifest.yaml" METADATA_DOCUMENTATION_URL = "https://docs.airbyte.com/connector-development/connector-metadata-file" diff --git a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/models.py b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/models.py index 5d6eb29fe615..5b823a4830d4 100644 --- a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/models.py +++ b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/models.py @@ -11,6 +11,7 @@ from typing import Dict, List, Optional from connector_ops.utils import Connector, ConnectorLanguage # type: ignore + from connectors_qa import consts ALL_LANGUAGES = [ @@ -289,9 +290,9 @@ def to_json(self) -> str: " ", "_" ) connectors_report[connector_technical_name]["badge_text"] = badge_text - connectors_report[connector_technical_name][ - "badge_url" - ] = f"{self.image_shield_root_url}/{badge_name}-{badge_text}-{connectors_report[connector_technical_name]['badge_color']}" + connectors_report[connector_technical_name]["badge_url"] = ( + f"{self.image_shield_root_url}/{badge_name}-{badge_text}-{connectors_report[connector_technical_name]['badge_color']}" + ) return json.dumps( { "generation_timestamp": datetime.utcnow().isoformat(), diff --git a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/utils.py b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/utils.py index a2ee14c8436a..1833e1e05ac0 100644 --- a/airbyte-ci/connectors/connectors_qa/src/connectors_qa/utils.py +++ b/airbyte-ci/connectors/connectors_qa/src/connectors_qa/utils.py @@ -4,6 +4,7 @@ from typing import Set from connector_ops.utils import Connector # type: ignore + from connectors_qa import consts diff --git a/airbyte-ci/connectors/connectors_qa/tests/integration_tests/test_documentation.py b/airbyte-ci/connectors/connectors_qa/tests/integration_tests/test_documentation.py index afe74946cb10..f28ad4fd8c5a 100644 --- a/airbyte-ci/connectors/connectors_qa/tests/integration_tests/test_documentation.py +++ b/airbyte-ci/connectors/connectors_qa/tests/integration_tests/test_documentation.py @@ -6,23 +6,28 @@ import git import pytest from asyncclick.testing import CliRunner + from connectors_qa.cli import generate_documentation DOCUMENTATION_FILE_PATH_IN_AIRBYTE_REPO = Path("docs/contributing-to-airbyte/resources/qa-checks.md") + @pytest.fixture def airbyte_repo(): return git.Repo(search_parent_directories=True) + @pytest.mark.asyncio async def test_generated_qa_checks_documentation_is_up_to_date(airbyte_repo, tmp_path): # Arrange current_doc = (airbyte_repo.working_dir / DOCUMENTATION_FILE_PATH_IN_AIRBYTE_REPO).read_text() newly_generated_doc_path = tmp_path / "qa-checks.md" - + # Act await CliRunner().invoke(generate_documentation, [str(tmp_path / "qa-checks.md")], catch_exceptions=False) # Assert suggested_command = f"connectors-qa generate-documentation {DOCUMENTATION_FILE_PATH_IN_AIRBYTE_REPO}" - assert newly_generated_doc_path.read_text() == current_doc, f"The generated documentation is not up to date. Please run `{suggested_command}` and commit the changes." + assert ( + newly_generated_doc_path.read_text() == current_doc + ), f"The generated documentation is not up to date. Please run `{suggested_command}` and commit the changes." diff --git a/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_assets.py b/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_assets.py index ed4e8eebbfe9..f26d49671fdd 100644 --- a/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_assets.py +++ b/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_assets.py @@ -42,7 +42,6 @@ def test_fail_when_icon_path_is_not_named_icon_svg(self, tmp_path, mocker): assert result.status == CheckStatus.FAILED assert result.message == "Icon file is not a SVG file" - def test_fail_when_icon_file_is_not_valid_svg(self, tmp_path, mocker): # Arrange connector = mocker.MagicMock() diff --git a/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_documentation.py b/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_documentation.py index 959ba6b48311..f5f58912489a 100644 --- a/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_documentation.py +++ b/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_documentation.py @@ -196,7 +196,6 @@ def test_pass_when_documentation_file_path_exists(self, mocker, tmp_path): class TestCheckDocumentationContent: - def test_fail_when_documentation_file_path_does_not_exists(self, mocker, tmp_path): # Arrange connector = mocker.Mock( @@ -204,7 +203,7 @@ def test_fail_when_documentation_file_path_does_not_exists(self, mocker, tmp_pat ab_internal_sl=300, language="python", connector_type="source", - documentation_file_path=tmp_path / "not_existing_documentation.md" + documentation_file_path=tmp_path / "not_existing_documentation.md", ) # Act @@ -217,11 +216,7 @@ def test_fail_when_documentation_file_path_does_not_exists(self, mocker, tmp_pat def test_fail_when_documentation_file_path_is_none(self, mocker): # Arrange connector = mocker.Mock( - technical_name="test-connector", - ab_internal_sl=300, - language="python", - connector_type="source", - documentation_file_path=None + technical_name="test-connector", ab_internal_sl=300, language="python", connector_type="source", documentation_file_path=None ) # Act @@ -263,34 +258,28 @@ def test_fail_when_documentation_file_has_missing_headers(self, connector_with_i assert "Actual Heading: 'For Airbyte Cloud:'. Expected Heading: 'Setup guide'" in result.message def test_fail_when_documentation_file_not_have_all_required_fields_in_prerequisites_section_content( - self, - connector_with_invalid_documentation + self, connector_with_invalid_documentation ): # Act - result = documentation.CheckPrerequisitesSectionDescribesRequiredFieldsFromSpec()._run( - connector_with_invalid_documentation - ) + result = documentation.CheckPrerequisitesSectionDescribesRequiredFieldsFromSpec()._run(connector_with_invalid_documentation) # Assert assert result.status == CheckStatus.FAILED assert "Missing descriptions for required spec fields: github repositories" in result.message - def test_fail_when_documentation_file_has_invalid_source_section_content( - self, - connector_with_invalid_documentation - ): + def test_fail_when_documentation_file_has_invalid_source_section_content(self, connector_with_invalid_documentation): # Act result = documentation.CheckSourceSectionContent()._run(connector_with_invalid_documentation) # Assert assert result.status == CheckStatus.FAILED assert "Connector GitHub section content does not follow standard template:" in result.message - assert "+ This page contains the setup guide and reference information for the [GitHub]({docs_link}) source connector." in result.message + assert ( + "+ This page contains the setup guide and reference information for the [GitHub]({docs_link}) source connector." + in result.message + ) - def test_fail_when_documentation_file_has_invalid_for_airbyte_cloud_section_content( - self, - connector_with_invalid_documentation - ): + def test_fail_when_documentation_file_has_invalid_for_airbyte_cloud_section_content(self, connector_with_invalid_documentation): # Act result = documentation.CheckForAirbyteCloudSectionContent()._run(connector_with_invalid_documentation) @@ -299,10 +288,7 @@ def test_fail_when_documentation_file_has_invalid_for_airbyte_cloud_section_cont assert "Connector For Airbyte Cloud: section content does not follow standard template:" in result.message assert "+ 1. [Log into your Airbyte Cloud](https://cloud.airbyte.com/workspaces) account." in result.message - def test_fail_when_documentation_file_has_invalid_for_airbyte_open_section_content( - self, - connector_with_invalid_documentation - ): + def test_fail_when_documentation_file_has_invalid_for_airbyte_open_section_content(self, connector_with_invalid_documentation): # Act result = documentation.CheckForAirbyteOpenSectionContent()._run(connector_with_invalid_documentation) @@ -311,23 +297,19 @@ def test_fail_when_documentation_file_has_invalid_for_airbyte_open_section_conte assert "Connector For Airbyte Open Source: section content does not follow standard template" in result.message assert "+ 1. Navigate to the Airbyte Open Source dashboard." in result.message - def test_fail_when_documentation_file_has_invalid_supported_sync_modes_section_content( - self, - connector_with_invalid_documentation - ): + def test_fail_when_documentation_file_has_invalid_supported_sync_modes_section_content(self, connector_with_invalid_documentation): # Act result = documentation.CheckSupportedSyncModesSectionContent()._run(connector_with_invalid_documentation) # Assert assert result.status == CheckStatus.FAILED assert "Connector Supported sync modes section content does not follow standard template:" in result.message - assert ("+ The GitHub source connector supports the following" - " [sync modes](https://docs.airbyte.com/cloud/core-concepts/#connection-sync-modes):") in result.message + assert ( + "+ The GitHub source connector supports the following" + " [sync modes](https://docs.airbyte.com/cloud/core-concepts/#connection-sync-modes):" + ) in result.message - def test_fail_when_documentation_file_has_invalid_tutorials_section_content( - self, - connector_with_invalid_documentation - ): + def test_fail_when_documentation_file_has_invalid_tutorials_section_content(self, connector_with_invalid_documentation): # Act result = documentation.CheckTutorialsSectionContent()._run(connector_with_invalid_documentation) @@ -336,10 +318,7 @@ def test_fail_when_documentation_file_has_invalid_tutorials_section_content( assert "Connector Tutorials section content does not follow standard template:" in result.message assert "+ Now that you have set up the GitHub source connector, check out the following GitHub tutorials:" in result.message - def test_fail_when_documentation_file_has_invalid_changelog_section_content( - self, - connector_with_invalid_documentation - ): + def test_fail_when_documentation_file_has_invalid_changelog_section_content(self, connector_with_invalid_documentation): # Act result = documentation.CheckChangelogSectionContent()._run(connector_with_invalid_documentation) @@ -356,10 +335,7 @@ def test_pass_when_documentation_file_has_correct_headers(self, connector_with_c assert result.status == CheckStatus.PASSED assert result.message == "Documentation guidelines are followed" - def test_pass_when_documentation_file_has_correct_prerequisites_section_content( - self, - connector_with_correct_documentation - ): + def test_pass_when_documentation_file_has_correct_prerequisites_section_content(self, connector_with_correct_documentation): # Act result = documentation.CheckPrerequisitesSectionDescribesRequiredFieldsFromSpec()._run(connector_with_correct_documentation) @@ -367,10 +343,7 @@ def test_pass_when_documentation_file_has_correct_prerequisites_section_content( assert result.status == CheckStatus.PASSED assert "All required fields from spec are present in the connector documentation" in result.message - def test_pass_when_documentation_file_has_correct_source_section_content( - self, - connector_with_correct_documentation - ): + def test_pass_when_documentation_file_has_correct_source_section_content(self, connector_with_correct_documentation): # Act result = documentation.CheckSourceSectionContent()._run(connector_with_correct_documentation) @@ -378,10 +351,7 @@ def test_pass_when_documentation_file_has_correct_source_section_content( assert result.status == CheckStatus.PASSED assert "Documentation guidelines are followed" in result.message - def test_pass_when_documentation_file_has_correct_for_airbyte_cloud_section_content( - self, - connector_with_correct_documentation - ): + def test_pass_when_documentation_file_has_correct_for_airbyte_cloud_section_content(self, connector_with_correct_documentation): # Act result = documentation.CheckForAirbyteCloudSectionContent()._run(connector_with_correct_documentation) @@ -389,10 +359,7 @@ def test_pass_when_documentation_file_has_correct_for_airbyte_cloud_section_cont assert result.status == CheckStatus.PASSED assert "Documentation guidelines are followed" in result.message - def test_pass_when_documentation_file_has_correct_for_airbyte_open_section_content( - self, - connector_with_correct_documentation - ): + def test_pass_when_documentation_file_has_correct_for_airbyte_open_section_content(self, connector_with_correct_documentation): # Act result = documentation.CheckForAirbyteOpenSectionContent()._run(connector_with_correct_documentation) @@ -400,10 +367,7 @@ def test_pass_when_documentation_file_has_correct_for_airbyte_open_section_conte assert result.status == CheckStatus.PASSED assert "Documentation guidelines are followed" in result.message - def test_pass_when_documentation_file_has_correct_supported_sync_modes_section_content( - self, - connector_with_correct_documentation - ): + def test_pass_when_documentation_file_has_correct_supported_sync_modes_section_content(self, connector_with_correct_documentation): # Act result = documentation.CheckSupportedSyncModesSectionContent()._run(connector_with_correct_documentation) @@ -411,10 +375,7 @@ def test_pass_when_documentation_file_has_correct_supported_sync_modes_section_c assert result.status == CheckStatus.PASSED assert "Documentation guidelines are followed" in result.message - def test_pass_when_documentation_file_has_correct_tutorials_section_content( - self, - connector_with_correct_documentation - ): + def test_pass_when_documentation_file_has_correct_tutorials_section_content(self, connector_with_correct_documentation): # Act result = documentation.CheckTutorialsSectionContent()._run(connector_with_correct_documentation) @@ -422,10 +383,7 @@ def test_pass_when_documentation_file_has_correct_tutorials_section_content( assert result.status == CheckStatus.PASSED assert "Documentation guidelines are followed" in result.message - def test_pass_when_documentation_file_has_correct_headers_order( - self, - connector_with_correct_documentation - ): + def test_pass_when_documentation_file_has_correct_headers_order(self, connector_with_correct_documentation): # Act result = documentation.CheckDocumentationHeadersOrder()._run(connector_with_correct_documentation) @@ -433,10 +391,7 @@ def test_pass_when_documentation_file_has_correct_headers_order( assert result.status == CheckStatus.PASSED assert "Documentation guidelines are followed" in result.message - def test_pass_when_documentation_file_has_correct_changelog_section_content( - self, - connector_with_correct_documentation - ): + def test_pass_when_documentation_file_has_correct_changelog_section_content(self, connector_with_correct_documentation): # Act result = documentation.CheckChangelogSectionContent()._run(connector_with_correct_documentation) diff --git a/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_metadata.py b/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_metadata.py index b3b6e952fa44..482a2536b241 100644 --- a/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_metadata.py +++ b/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_metadata.py @@ -4,6 +4,7 @@ import os import pytest + from connectors_qa import consts from connectors_qa.checks import metadata from connectors_qa.models import CheckStatus diff --git a/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_packaging.py b/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_packaging.py index b494c9d40074..56f98ae27081 100644 --- a/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_packaging.py +++ b/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_packaging.py @@ -133,6 +133,7 @@ def test_pass_if_publish_to_pypi_is_disabled(self, mocker): assert result.status == CheckStatus.PASSED assert "PyPi publishing is declared" in result.message + class TestCheckConnectorLicense: def test_fail_when_license_is_missing(self, mocker): # Arrange diff --git a/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_testing.py b/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_testing.py index c6c997b03fd6..99a90b2cb230 100644 --- a/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_testing.py +++ b/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_checks/test_testing.py @@ -2,6 +2,7 @@ import pytest from connector_ops.utils import ConnectorLanguage + from connectors_qa.checks import testing from connectors_qa.models import CheckStatus @@ -56,9 +57,7 @@ "connectorTestSuitesOptions": [ { "suite": testing.AcceptanceTestsEnabledCheck.test_suite_name, - "testSecrets": { - "testSecret": "test" - }, + "testSecrets": {"testSecret": "test"}, }, { "suite": "unit", @@ -71,10 +70,10 @@ OTHER_USAGE_VALUES = ["low", "none", "unknown", None, ""] DYNAMIC_ACCEPTANCE_TESTS_ENABLED_CASES = [ - METADATA_CASE_WITH_ACCEPTANCE_TEST_SUITE_OPTIONS, - METADATA_CASE_WITH_ACCEPTANCE_TEST_SUITE_OPTIONS_NONE_SECRETS, - METADATA_CASE_WITH_ACCEPTANCE_TEST_SUITE_OPTIONS_EMPTY_SECRETS, - METADATA_CASE_WITH_ACCEPTANCE_TEST_SUITE_OPTIONS_NO_SECRETS, + METADATA_CASE_WITH_ACCEPTANCE_TEST_SUITE_OPTIONS, + METADATA_CASE_WITH_ACCEPTANCE_TEST_SUITE_OPTIONS_NONE_SECRETS, + METADATA_CASE_WITH_ACCEPTANCE_TEST_SUITE_OPTIONS_EMPTY_SECRETS, + METADATA_CASE_WITH_ACCEPTANCE_TEST_SUITE_OPTIONS_NO_SECRETS, ] DYNAMIC_ACCEPTANCE_TESTS_DISABLED_CASES = [ @@ -89,21 +88,9 @@ class TestAcceptanceTestsEnabledCheck: @pytest.mark.parametrize( "cases_to_test, usage_values_to_test, expected_result", [ - ( - DYNAMIC_ACCEPTANCE_TESTS_DISABLED_CASES + DYNAMIC_ACCEPTANCE_TESTS_ENABLED_CASES, - OTHER_USAGE_VALUES, - CheckStatus.SKIPPED - ), - ( - DYNAMIC_ACCEPTANCE_TESTS_ENABLED_CASES, - THRESHOLD_USAGE_VALUES, - CheckStatus.PASSED - ), - ( - DYNAMIC_ACCEPTANCE_TESTS_DISABLED_CASES, - THRESHOLD_USAGE_VALUES, - CheckStatus.FAILED - ) + (DYNAMIC_ACCEPTANCE_TESTS_DISABLED_CASES + DYNAMIC_ACCEPTANCE_TESTS_ENABLED_CASES, OTHER_USAGE_VALUES, CheckStatus.SKIPPED), + (DYNAMIC_ACCEPTANCE_TESTS_ENABLED_CASES, THRESHOLD_USAGE_VALUES, CheckStatus.PASSED), + (DYNAMIC_ACCEPTANCE_TESTS_DISABLED_CASES, THRESHOLD_USAGE_VALUES, CheckStatus.FAILED), ], ) def test_check_always_passes_when_usage_threshold_is_not_met(self, mocker, cases_to_test, usage_values_to_test, expected_result): @@ -115,11 +102,13 @@ def test_check_always_passes_when_usage_threshold_is_not_met(self, mocker, cases metadata=metadata_case, language=ConnectorLanguage.PYTHON, connector_type="source", - ab_internal_sl=100 + ab_internal_sl=100, ) # Act result = testing.AcceptanceTestsEnabledCheck().run(connector) # Assert - assert result.status == expected_result, f"Usage value: {usage_value}, metadata case: {metadata_case}, expected result: {expected_result}" + assert ( + result.status == expected_result + ), f"Usage value: {usage_value}, metadata case: {metadata_case}, expected result: {expected_result}" diff --git a/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_models.py b/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_models.py index 442a038f9595..bcb3198e7bca 100644 --- a/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_models.py +++ b/airbyte-ci/connectors/connectors_qa/tests/unit_tests/test_models.py @@ -1,6 +1,7 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. from connector_ops.utils import ConnectorLanguage + from connectors_qa import consts from connectors_qa.checks import ENABLED_CHECKS from connectors_qa.models import CheckStatus diff --git a/airbyte-ci/connectors/erd/src/erd/dbml_assembler.py b/airbyte-ci/connectors/erd/src/erd/dbml_assembler.py index 1e80a737c6a2..116e20e1dfe0 100644 --- a/airbyte-ci/connectors/erd/src/erd/dbml_assembler.py +++ b/airbyte-ci/connectors/erd/src/erd/dbml_assembler.py @@ -4,11 +4,22 @@ from typing import List, Set, Union import yaml -from airbyte_cdk.sources.declarative.parsers.manifest_reference_resolver import ManifestReferenceResolver -from airbyte_protocol.models import AirbyteCatalog, AirbyteStream # type: ignore # missing library stubs or py.typed marker -from erd.relationships import Relationships +from airbyte_cdk.sources.declarative.parsers.manifest_reference_resolver import ( + ManifestReferenceResolver, +) +from airbyte_protocol.models import ( # type: ignore # missing library stubs or py.typed marker + AirbyteCatalog, + AirbyteStream, +) from pydbml import Database # type: ignore # missing library stubs or py.typed marker -from pydbml.classes import Column, Index, Reference, Table # type: ignore # missing library stubs or py.typed marker +from pydbml.classes import ( # type: ignore # missing library stubs or py.typed marker + Column, + Index, + Reference, + Table, +) + +from erd.relationships import Relationships class Source: @@ -25,33 +36,67 @@ def is_dynamic(self, stream_name: str) -> bool: manifest_static_streams = set() if self._has_manifest(): with open(self._get_manifest_path()) as manifest_file: - resolved_manifest = ManifestReferenceResolver().preprocess_manifest(yaml.safe_load(manifest_file)) + resolved_manifest = ManifestReferenceResolver().preprocess_manifest( + yaml.safe_load(manifest_file) + ) for stream in resolved_manifest["streams"]: if "schema_loader" not in stream: # stream is assumed to have `DefaultSchemaLoader` which will show in the schemas folder so we can skip continue if stream["schema_loader"]["type"] == "InlineSchemaLoader": - name = stream["name"] if "name" in stream else stream.get("$parameters").get("name", None) + name = ( + stream["name"] + if "name" in stream + else stream.get("$parameters").get("name", None) + ) if not name: print(f"Could not retrieve name for this stream: {stream}") continue - manifest_static_streams.add(stream["name"] if "name" in stream else stream.get("$parameters").get("name", None)) + manifest_static_streams.add( + stream["name"] + if "name" in stream + else stream.get("$parameters").get("name", None) + ) - return stream_name not in manifest_static_streams | self._get_streams_from_schemas_folder() + return ( + stream_name + not in manifest_static_streams | self._get_streams_from_schemas_folder() + ) def _get_streams_from_schemas_folder(self) -> Set[str]: - schemas_folder = self._source_folder / self._source_technical_name.replace("-", "_") / "schemas" - return {p.name.replace(".json", "") for p in schemas_folder.iterdir() if p.is_file()} if schemas_folder.exists() else set() + schemas_folder = ( + self._source_folder + / self._source_technical_name.replace("-", "_") + / "schemas" + ) + return ( + { + p.name.replace(".json", "") + for p in schemas_folder.iterdir() + if p.is_file() + } + if schemas_folder.exists() + else set() + ) def _get_manifest_path(self) -> Path: - return self._source_folder / self._source_technical_name.replace("-", "_") / "manifest.yaml" + return ( + self._source_folder + / self._source_technical_name.replace("-", "_") + / "manifest.yaml" + ) def _has_manifest(self) -> bool: return self._get_manifest_path().exists() class DbmlAssembler: - def assemble(self, source: Source, discovered_catalog: AirbyteCatalog, relationships: Relationships) -> Database: + def assemble( + self, + source: Source, + discovered_catalog: AirbyteCatalog, + relationships: Relationships, + ) -> Database: database = Database() for stream in discovered_catalog.streams: if source.is_dynamic(stream.name): @@ -66,7 +111,9 @@ def assemble(self, source: Source, discovered_catalog: AirbyteCatalog, relations def _create_table(self, stream: AirbyteStream) -> Table: dbml_table = Table(stream.name) - for property_name, property_information in stream.json_schema.get("properties").items(): + for property_name, property_information in stream.json_schema.get( + "properties" + ).items(): try: dbml_table.add_column( Column( @@ -79,12 +126,20 @@ def _create_table(self, stream: AirbyteStream) -> Table: print(f"Ignoring field {property_name}: {exception}") continue - if stream.source_defined_primary_key and len(stream.source_defined_primary_key) > 1: + if ( + stream.source_defined_primary_key + and len(stream.source_defined_primary_key) > 1 + ): if any(map(lambda key: len(key) != 1, stream.source_defined_primary_key)): - raise ValueError(f"Does not support nested key as part of primary key `{stream.source_defined_primary_key}`") + raise ValueError( + f"Does not support nested key as part of primary key `{stream.source_defined_primary_key}`" + ) composite_key_columns = [ - column for key in stream.source_defined_primary_key for column in dbml_table.columns if column.name in key + column + for key in stream.source_defined_primary_key + for column in dbml_table.columns + if column.name in key ] if len(composite_key_columns) < len(stream.source_defined_primary_key): raise ValueError("Unexpected error: missing PK column from dbml table") @@ -97,11 +152,15 @@ def _create_table(self, stream: AirbyteStream) -> Table: ) return dbml_table - def _add_references(self, source: Source, database: Database, relationships: Relationships) -> None: + def _add_references( + self, source: Source, database: Database, relationships: Relationships + ) -> None: for stream in relationships["streams"]: for column_name, relationship in stream["relations"].items(): if source.is_dynamic(stream["name"]): - print(f"Skipping relationship as stream {stream['name']} from relationship is dynamic") + print( + f"Skipping relationship as stream {stream['name']} from relationship is dynamic" + ) continue try: @@ -109,18 +168,26 @@ def _add_references(self, source: Source, database: Database, relationships: Rel ".", 1 ) # we support the field names having dots but not stream name hence we split on the first dot only except ValueError as exception: - raise ValueError(f"Could not handle relationship {relationship}") from exception + raise ValueError( + f"Could not handle relationship {relationship}" + ) from exception if source.is_dynamic(target_table_name): - print(f"Skipping relationship as target stream {target_table_name} is dynamic") + print( + f"Skipping relationship as target stream {target_table_name} is dynamic" + ) continue try: database.add_reference( Reference( type="<>", # we don't have the information of which relationship type it is so we assume many-to-many for now - col1=self._get_column(database, stream["name"], column_name), - col2=self._get_column(database, target_table_name, target_column_name), + col1=self._get_column( + database, stream["name"], column_name + ), + col2=self._get_column( + database, target_table_name, target_column_name + ), ) ) except ValueError as exception: @@ -136,24 +203,38 @@ def _extract_type(self, property_type: Union[str, List[str]]) -> str: # show this in DBML types.remove("null") if len(types) != 1: - raise ValueError(f"Expected only one type apart from `null` but got {len(types)}: {property_type}") + raise ValueError( + f"Expected only one type apart from `null` but got {len(types)}: {property_type}" + ) return types[0] def _is_pk(self, stream: AirbyteStream, property_name: str) -> bool: return stream.source_defined_primary_key == [[property_name]] - def _get_column(self, database: Database, table_name: str, column_name: str) -> Column: - matching_tables = list(filter(lambda dbml_table: dbml_table.name == table_name, database.tables)) + def _get_column( + self, database: Database, table_name: str, column_name: str + ) -> Column: + matching_tables = list( + filter(lambda dbml_table: dbml_table.name == table_name, database.tables) + ) if len(matching_tables) == 0: raise ValueError(f"Could not find table {table_name}") elif len(matching_tables) > 1: - raise ValueError(f"Unexpected error: many tables found with name {table_name}") + raise ValueError( + f"Unexpected error: many tables found with name {table_name}" + ) table: Table = matching_tables[0] - matching_columns = list(filter(lambda column: column.name == column_name, table.columns)) + matching_columns = list( + filter(lambda column: column.name == column_name, table.columns) + ) if len(matching_columns) == 0: - raise ValueError(f"Could not find column {column_name} in table {table_name}. Columns are: {table.columns}") + raise ValueError( + f"Could not find column {column_name} in table {table_name}. Columns are: {table.columns}" + ) elif len(matching_columns) > 1: - raise ValueError(f"Unexpected error: many columns found with name {column_name} for table {table_name}") + raise ValueError( + f"Unexpected error: many columns found with name {column_name} for table {table_name}" + ) return matching_columns[0] diff --git a/airbyte-ci/connectors/erd/src/erd/erd_service.py b/airbyte-ci/connectors/erd/src/erd/erd_service.py index aff60bd79a9e..47591d365aae 100644 --- a/airbyte-ci/connectors/erd/src/erd/erd_service.py +++ b/airbyte-ci/connectors/erd/src/erd/erd_service.py @@ -7,11 +7,16 @@ import dpath import google.generativeai as genai # type: ignore # missing library stubs or py.typed marker -from airbyte_protocol.models import AirbyteCatalog # type: ignore # missing library stubs or py.typed marker +from airbyte_protocol.models import ( + AirbyteCatalog, # type: ignore # missing library stubs or py.typed marker +) +from markdown_it import MarkdownIt +from pydbml.renderer.dbml.default import ( + DefaultDBMLRenderer, # type: ignore # missing library stubs or py.typed marker +) + from erd.dbml_assembler import DbmlAssembler, Source from erd.relationships import Relationships, RelationshipsMerger -from markdown_it import MarkdownIt -from pydbml.renderer.dbml.default import DefaultDBMLRenderer # type: ignore # missing library stubs or py.typed marker class ErdService: @@ -21,12 +26,18 @@ def __init__(self, source_technical_name: str, source_path: Path) -> None: self._model = genai.GenerativeModel("gemini-1.5-flash") if not self._discovered_catalog_path.exists(): - raise ValueError(f"Could not find discovered catalog at path {self._discovered_catalog_path}") + raise ValueError( + f"Could not find discovered catalog at path {self._discovered_catalog_path}" + ) def generate_estimated_relationships(self) -> None: normalized_catalog = self._normalize_schema_catalog(self._get_catalog()) - estimated_relationships = self._get_relations_from_gemini(source_name=self._source_path.name, catalog=normalized_catalog) - with open(self._estimated_relationships_file, "w") as estimated_relationship_file: + estimated_relationships = self._get_relations_from_gemini( + source_name=self._source_path.name, catalog=normalized_catalog + ) + with open( + self._estimated_relationships_file, "w" + ) as estimated_relationship_file: json.dump(estimated_relationships, estimated_relationship_file, indent=4) def write_dbml_file(self) -> None: @@ -34,7 +45,8 @@ def write_dbml_file(self) -> None: Source(self._source_path, self._source_technical_name), self._get_catalog(), RelationshipsMerger().merge( - self._get_relationships(self._estimated_relationships_file), self._get_relationships(self._confirmed_relationships_file) + self._get_relationships(self._estimated_relationships_file), + self._get_relationships(self._confirmed_relationships_file), ), ) @@ -53,13 +65,19 @@ def _normalize_schema_catalog(catalog: AirbyteCatalog) -> dict[str, Any]: to_rem = dpath.search( stream["json_schema"]["properties"], ["**"], - afilter=lambda x: isinstance(x, dict) and ("array" in str(x.get("type", "")) or "object" in str(x.get("type", ""))), + afilter=lambda x: isinstance(x, dict) + and ( + "array" in str(x.get("type", "")) + or "object" in str(x.get("type", "")) + ), ) for key in to_rem: stream["json_schema"]["properties"].pop(key) return streams # type: ignore # as this comes from an AirbyteCatalog dump, the format should be fine - def _get_relations_from_gemini(self, source_name: str, catalog: dict[str, Any]) -> Relationships: + def _get_relations_from_gemini( + self, source_name: str, catalog: dict[str, Any] + ) -> Relationships: """ :param source_name: @@ -74,9 +92,7 @@ def _get_relations_from_gemini(self, source_name: str, catalog: dict[str, Any]) The current JSON Schema format is as follows: {current_schema}, where "streams" has a list of streams, which represents database tables, and list of properties in each, which in turn, represent DB columns. Streams presented in list are the only available ones. Generate and add a `foreign_key` with reference for each field in top level of properties that is helpful in understanding what the data represents and how are streams related to each other. Pay attention to fields ends with '_id'. - """.format( - source_name=source_name, current_schema=catalog - ) + """.format(source_name=source_name, current_schema=catalog) task = """ Please provide answer in the following format: {streams: [{"name": "", "relations": {"": ""} }]} diff --git a/airbyte-ci/connectors/erd/src/erd/relationships.py b/airbyte-ci/connectors/erd/src/erd/relationships.py index 704af25d489e..432b19981124 100644 --- a/airbyte-ci/connectors/erd/src/erd/relationships.py +++ b/airbyte-ci/connectors/erd/src/erd/relationships.py @@ -16,16 +16,28 @@ class Relationship(TypedDict): class RelationshipsMerger: - def merge(self, estimated_relationships: Relationships, confirmed_relationships: Relationships) -> Relationships: + def merge( + self, + estimated_relationships: Relationships, + confirmed_relationships: Relationships, + ) -> Relationships: streams = [] for estimated_stream in estimated_relationships["streams"]: - confirmed_relationships_for_stream = self._get_stream(confirmed_relationships, estimated_stream["name"]) + confirmed_relationships_for_stream = self._get_stream( + confirmed_relationships, estimated_stream["name"] + ) if confirmed_relationships_for_stream: - streams.append(self._merge_for_stream(estimated_stream, confirmed_relationships_for_stream)) # type: ignore # at this point, we know confirmed_relationships_for_stream is not None + streams.append( + self._merge_for_stream( + estimated_stream, confirmed_relationships_for_stream + ) + ) # type: ignore # at this point, we know confirmed_relationships_for_stream is not None else: streams.append(estimated_stream) - already_processed_streams = set(map(lambda relationship: relationship["name"], streams)) + already_processed_streams = set( + map(lambda relationship: relationship["name"], streams) + ) for confirmed_stream in confirmed_relationships["streams"]: if confirmed_stream["name"] not in already_processed_streams: streams.append( @@ -36,13 +48,20 @@ def merge(self, estimated_relationships: Relationships, confirmed_relationships: ) return {"streams": streams} - def _merge_for_stream(self, estimated: Relationship, confirmed: Relationship) -> Relationship: + def _merge_for_stream( + self, estimated: Relationship, confirmed: Relationship + ) -> Relationship: relations = copy.deepcopy(confirmed.get("relations", {})) # get estimated but filter out false positives for field, target in estimated.get("relations", {}).items(): - false_positives = confirmed["false_positives"] if "false_positives" in confirmed else {} - if field not in relations and (field not in false_positives or false_positives.get(field, None) != target): # type: ignore # at this point, false_positives should not be None + false_positives = ( + confirmed["false_positives"] if "false_positives" in confirmed else {} + ) + if field not in relations and ( + field not in false_positives + or false_positives.get(field, None) != target + ): # type: ignore # at this point, false_positives should not be None relations[field] = target return { @@ -50,7 +69,9 @@ def _merge_for_stream(self, estimated: Relationship, confirmed: Relationship) -> "relations": relations, } - def _get_stream(self, relationships: Relationships, stream_name: str) -> Optional[Relationship]: + def _get_stream( + self, relationships: Relationships, stream_name: str + ) -> Optional[Relationship]: for stream in relationships["streams"]: if stream.get("name", None) == stream_name: return stream diff --git a/airbyte-ci/connectors/erd/tests/test_dbml_assembler.py b/airbyte-ci/connectors/erd/tests/test_dbml_assembler.py index c697505378cd..93c65a702535 100644 --- a/airbyte-ci/connectors/erd/tests/test_dbml_assembler.py +++ b/airbyte-ci/connectors/erd/tests/test_dbml_assembler.py @@ -4,6 +4,7 @@ from unittest.mock import Mock from airbyte_protocol.models import AirbyteCatalog, AirbyteStream, SyncMode + from erd.dbml_assembler import DbmlAssembler, Source from tests.builder import RelationshipBuilder @@ -18,7 +19,9 @@ def setUp(self) -> None: def test_given_no_streams_then_database_is_empty(self) -> None: dbml = self._assembler.assemble( - self._source, AirbyteCatalog(streams=[]), {"streams": [RelationshipBuilder(_A_STREAM_NAME).build()]} + self._source, + AirbyteCatalog(streams=[]), + {"streams": [RelationshipBuilder(_A_STREAM_NAME).build()]}, ) assert not dbml.tables diff --git a/airbyte-ci/connectors/erd/tests/test_relationships.py b/airbyte-ci/connectors/erd/tests/test_relationships.py index f8675cb6bd57..968928eb1763 100644 --- a/airbyte-ci/connectors/erd/tests/test_relationships.py +++ b/airbyte-ci/connectors/erd/tests/test_relationships.py @@ -17,32 +17,72 @@ def setUp(self) -> None: self._merger = RelationshipsMerger() def test_given_no_confirmed_then_return_estimation(self) -> None: - estimated: Relationships = {"streams": [RelationshipBuilder(_A_STREAM_NAME).with_relationship(_A_COLUMN, _A_TARGET).build()]} + estimated: Relationships = { + "streams": [ + RelationshipBuilder(_A_STREAM_NAME) + .with_relationship(_A_COLUMN, _A_TARGET) + .build() + ] + } confirmed: Relationships = {"streams": []} merged = self._merger.merge(estimated, confirmed) assert merged == estimated - def test_given_confirmed_as_false_positive_then_remove_from_estimation(self) -> None: - estimated: Relationships = {"streams": [RelationshipBuilder(_A_STREAM_NAME).with_relationship(_A_COLUMN, _A_TARGET).build()]} - confirmed: Relationships = {"streams": [RelationshipBuilder(_A_STREAM_NAME).with_false_positive(_A_COLUMN, _A_TARGET).build()]} + def test_given_confirmed_as_false_positive_then_remove_from_estimation( + self, + ) -> None: + estimated: Relationships = { + "streams": [ + RelationshipBuilder(_A_STREAM_NAME) + .with_relationship(_A_COLUMN, _A_TARGET) + .build() + ] + } + confirmed: Relationships = { + "streams": [ + RelationshipBuilder(_A_STREAM_NAME) + .with_false_positive(_A_COLUMN, _A_TARGET) + .build() + ] + } merged = self._merger.merge(estimated, confirmed) assert merged == {"streams": [{"name": "a_stream_name", "relations": {}}]} - def test_given_no_estimated_but_confirmed_then_return_confirmed_without_false_positives(self) -> None: + def test_given_no_estimated_but_confirmed_then_return_confirmed_without_false_positives( + self, + ) -> None: estimated: Relationships = {"streams": []} - confirmed: Relationships = {"streams": [RelationshipBuilder(_A_STREAM_NAME).with_relationship(_A_COLUMN, _A_TARGET).build()]} + confirmed: Relationships = { + "streams": [ + RelationshipBuilder(_A_STREAM_NAME) + .with_relationship(_A_COLUMN, _A_TARGET) + .build() + ] + } merged = self._merger.merge(estimated, confirmed) assert merged == confirmed def test_given_different_columns_then_return_both(self) -> None: - estimated: Relationships = {"streams": [RelationshipBuilder(_A_STREAM_NAME).with_relationship(_A_COLUMN, _A_TARGET).build()]} - confirmed: Relationships = {"streams": [RelationshipBuilder(_A_STREAM_NAME).with_relationship(_ANOTHER_COLUMN, _A_TARGET).build()]} + estimated: Relationships = { + "streams": [ + RelationshipBuilder(_A_STREAM_NAME) + .with_relationship(_A_COLUMN, _A_TARGET) + .build() + ] + } + confirmed: Relationships = { + "streams": [ + RelationshipBuilder(_A_STREAM_NAME) + .with_relationship(_ANOTHER_COLUMN, _A_TARGET) + .build() + ] + } merged = self._merger.merge(estimated, confirmed) @@ -58,9 +98,23 @@ def test_given_different_columns_then_return_both(self) -> None: ] } - def test_given_same_column_but_different_value_then_prioritize_confirmed(self) -> None: - estimated: Relationships = {"streams": [RelationshipBuilder(_A_STREAM_NAME).with_relationship(_A_COLUMN, _A_TARGET).build()]} - confirmed: Relationships = {"streams": [RelationshipBuilder(_A_STREAM_NAME).with_relationship(_A_COLUMN, _ANOTHER_TARGET).build()]} + def test_given_same_column_but_different_value_then_prioritize_confirmed( + self, + ) -> None: + estimated: Relationships = { + "streams": [ + RelationshipBuilder(_A_STREAM_NAME) + .with_relationship(_A_COLUMN, _A_TARGET) + .build() + ] + } + confirmed: Relationships = { + "streams": [ + RelationshipBuilder(_A_STREAM_NAME) + .with_relationship(_A_COLUMN, _ANOTHER_TARGET) + .build() + ] + } merged = self._merger.merge(estimated, confirmed) diff --git a/airbyte-ci/connectors/live-tests/README.md b/airbyte-ci/connectors/live-tests/README.md index 84e0ad9e1cf5..3417121ddf61 100644 --- a/airbyte-ci/connectors/live-tests/README.md +++ b/airbyte-ci/connectors/live-tests/README.md @@ -179,11 +179,42 @@ The traffic recorded on the control connector is passed to the target connector ## Changelog +### 0.20.0 +Support multiple connection objects in the regression tests suite. + + +### 0.19.10 +Pin the connection retriever until we make required changes to support the new version. + + +### 0.19.8 + +Give ownership of copied connection object files to the image user to make sure it has permission to write them (config migration). + +### 0.19.7 + +Mount connection objects to readable paths in the container for rootless images. + +### 0.19.6 + +Write connector output to a different in container path to avoid permission issues now that connector images are rootless. + +### 0.19.5 + +Fix `ZeroDivisionError` in Regression test tool + +### 0.19.4 + +Update `connection_retriever` to 0.7.4 + ### 0.19.3 + Update `get_container_from_id` with the correct new Dagger API. ### 0.19.2 + Update Dagger to 0.13.3 + ### 0.19.1 Fixed the `UserDict` type annotation not found bug. diff --git a/airbyte-ci/connectors/live-tests/poetry.lock b/airbyte-ci/connectors/live-tests/poetry.lock index fce51adc8f09..7a016a37a8f1 100644 --- a/airbyte-ci/connectors/live-tests/poetry.lock +++ b/airbyte-ci/connectors/live-tests/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. [[package]] name = "aiofiles" @@ -804,7 +804,7 @@ files = [ [[package]] name = "connection-retriever" -version = "0.7.2" +version = "1.0.0" description = "A tool to retrieve connection information from our Airbyte Cloud config api database" optional = false python-versions = "^3.10" @@ -818,7 +818,7 @@ dpath = "^2.1.6" google-cloud-iam = "^2.14.3" google-cloud-logging = "^3.9.0" google-cloud-secret-manager = "^2.18.3" -inquirer = "^3.2.4" +inquirer = "^3.4" jinja2 = "^3.1.3" pandas-gbq = "^0.22.0" python-dotenv = "^1.0.1" @@ -830,7 +830,7 @@ tqdm = "^4.66.2" type = "git" url = "git@github.com:airbytehq/airbyte-platform-internal" reference = "HEAD" -resolved_reference = "9025e1a46e6c2b366826f30dbcaa3b7d360fd702" +resolved_reference = "d71a5ae1f1621628f49d88832d7496949b89e1c7" subdirectory = "tools/connection-retriever" [[package]] @@ -4674,4 +4674,4 @@ cffi = ["cffi (>=1.11)"] [metadata] lock-version = "2.0" python-versions = "^3.10,<3.12" -content-hash = "dd0d0003a493a32998ceac61f58c840ca163afbe8cf4c2a6eb21d4081633a476" +content-hash = "722640c1c71733afc957dc3c7a2c821993a9a4633846438a446a5888b4be467e" diff --git a/airbyte-ci/connectors/live-tests/pyproject.toml b/airbyte-ci/connectors/live-tests/pyproject.toml index d695cac0ed81..fa4607562198 100644 --- a/airbyte-ci/connectors/live-tests/pyproject.toml +++ b/airbyte-ci/connectors/live-tests/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "live-tests" -version = "0.19.3" +version = "0.20.0" description = "Contains utilities for testing connectors against live data." authors = ["Airbyte "] license = "MIT" @@ -29,7 +29,6 @@ pytest = "^8.1.1" pydash = "~=7.0.7" docker = ">=6,<7" asyncclick = "^8.1.7.1" -# TODO: when this is open-sourced, don't require connection-retriever connection-retriever = {git = "git@github.com:airbytehq/airbyte-platform-internal", subdirectory = "tools/connection-retriever"} duckdb = "<=0.10.1" # Pinned due to this issue https://github.com/duckdb/duckdb/issues/11152 pandas = "^2.2.1" @@ -53,11 +52,13 @@ pandas-stubs = "^2.2.0.240218" types-requests = "^2.31.0.20240311" types-pyyaml = "^6.0.12.20240311" -[tool.ruff.lint] -select = ["I", "F"] +[tool.ruff] target-version = "py310" line-length = 140 +[tool.ruff.lint] +select = ["I", "F"] + [tool.ruff.lint.isort] known-first-party = ["connection-retriever"] diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/commons/backends/base_backend.py b/airbyte-ci/connectors/live-tests/src/live_tests/commons/backends/base_backend.py index 50a0209655cb..303799e245eb 100644 --- a/airbyte-ci/connectors/live-tests/src/live_tests/commons/backends/base_backend.py +++ b/airbyte-ci/connectors/live-tests/src/live_tests/commons/backends/base_backend.py @@ -13,5 +13,4 @@ class BaseBackend(ABC): """ @abstractmethod - def write(self, airbyte_messages: Iterable[AirbyteMessage]) -> None: - ... + def write(self, airbyte_messages: Iterable[AirbyteMessage]) -> None: ... diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/commons/backends/duckdb_backend.py b/airbyte-ci/connectors/live-tests/src/live_tests/commons/backends/duckdb_backend.py index cd6d61ee5d6c..d5bfa0fdff27 100644 --- a/airbyte-ci/connectors/live-tests/src/live_tests/commons/backends/duckdb_backend.py +++ b/airbyte-ci/connectors/live-tests/src/live_tests/commons/backends/duckdb_backend.py @@ -9,6 +9,7 @@ import duckdb from airbyte_protocol.models import AirbyteMessage # type: ignore + from live_tests.commons.backends.file_backend import FileBackend @@ -40,7 +41,7 @@ def jsonl_files_to_insert(self) -> Iterable[Path]: @staticmethod def sanitize_table_name(table_name: str) -> str: - sanitized = table_name.replace(" ", "_") + sanitized = str(table_name).replace(" ", "_") sanitized = re.sub(r"[^\w\s]", "", sanitized) if sanitized and sanitized[0].isdigit(): sanitized = "_" + sanitized diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/commons/backends/file_backend.py b/airbyte-ci/connectors/live-tests/src/live_tests/commons/backends/file_backend.py index a4d0b57c910a..ae3e68c228f8 100644 --- a/airbyte-ci/connectors/live-tests/src/live_tests/commons/backends/file_backend.py +++ b/airbyte-ci/connectors/live-tests/src/live_tests/commons/backends/file_backend.py @@ -10,6 +10,7 @@ from airbyte_protocol.models import AirbyteMessage # type: ignore from airbyte_protocol.models import Type as AirbyteMessageType from cachetools import LRUCache, cached + from live_tests.commons.backends.base_backend import BaseBackend from live_tests.commons.utils import sanitize_stream_name @@ -123,7 +124,11 @@ def _get_filepaths_and_messages(self, message: AirbyteMessage) -> tuple[tuple[st stream_file_path_data_only = self.record_per_stream_directory / f"{sanitize_stream_name(stream_name)}_data_only.jsonl" self.record_per_stream_paths[stream_name] = stream_file_path self.record_per_stream_paths_data_only[stream_name] = stream_file_path_data_only - return (self.RELATIVE_RECORDS_PATH, str(stream_file_path), str(stream_file_path_data_only),), ( + return ( + self.RELATIVE_RECORDS_PATH, + str(stream_file_path), + str(stream_file_path_data_only), + ), ( message.json(sort_keys=True), message.json(sort_keys=True), json.dumps(message.record.data, sort_keys=True), diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/commons/connection_objects_retrieval.py b/airbyte-ci/connectors/live-tests/src/live_tests/commons/connection_objects_retrieval.py index adcb1c6868cb..4ae3957d6d30 100644 --- a/airbyte-ci/connectors/live-tests/src/live_tests/commons/connection_objects_retrieval.py +++ b/airbyte-ci/connectors/live-tests/src/live_tests/commons/connection_objects_retrieval.py @@ -2,20 +2,22 @@ from __future__ import annotations import json -import logging import os +import textwrap from pathlib import Path -from typing import Dict, Optional, Set +from typing import Dict, List, Optional, Set, Tuple import rich from connection_retriever import ConnectionObject, retrieve_objects # type: ignore -from connection_retriever.errors import NotPermittedError # type: ignore +from connection_retriever.retrieval import TestingCandidate, retrieve_testing_candidates +from pydantic import ValidationError + +from live_tests.commons import hacks from live_tests.commons.models import ConnectionSubset from live_tests.commons.utils import build_connection_url from .models import AirbyteCatalog, Command, ConfiguredAirbyteCatalog, ConnectionObjects, SecretDict -LOGGER = logging.getLogger(__name__) console = rich.get_console() @@ -47,9 +49,9 @@ def parse_configured_catalog( if not configured_catalog: return None if isinstance(configured_catalog, str): - catalog = ConfiguredAirbyteCatalog.parse_obj(json.loads(configured_catalog)) - else: - catalog = ConfiguredAirbyteCatalog.parse_obj(configured_catalog) + configured_catalog = json.loads(configured_catalog) + patched_catalog = hacks.patch_configured_catalog(configured_catalog) + catalog = ConfiguredAirbyteCatalog.parse_obj(patched_catalog) if selected_streams: return ConfiguredAirbyteCatalog(streams=[stream for stream in catalog.streams if stream.stream.name in selected_streams]) return catalog @@ -96,13 +98,13 @@ def get_connection_objects( custom_configured_catalog_path: Optional[Path], custom_state_path: Optional[Path], retrieval_reason: Optional[str], - fail_if_missing_objects: bool = True, connector_image: Optional[str] = None, connector_version: Optional[str] = None, - auto_select_connection: bool = False, + auto_select_connections: bool = False, selected_streams: Optional[set[str]] = None, connection_subset: ConnectionSubset = ConnectionSubset.SANDBOXES, -) -> ConnectionObjects: + max_connections: Optional[int] = None, +) -> List[ConnectionObjects]: """This function retrieves the connection objects values. It checks that the required objects are available and raises a UsageError if they are not. If a connection_id is provided, it retrieves the connection objects from the connection. @@ -118,19 +120,20 @@ def get_connection_objects( fail_if_missing_objects (bool, optional): Whether to raise a ValueError if a required object is missing. Defaults to True. connector_image (Optional[str]): The image name for the connector under test. connector_version (Optional[str]): The version for the connector under test. - auto_select_connection (bool, optional): Whether to automatically select a connection if no connection id is passed. Defaults to False. + auto_select_connections (bool, optional): Whether to automatically select connections if no connection id is passed. Defaults to False. selected_streams (Optional[Set[str]]): The set of selected streams to use when auto selecting a connection. connection_subset (ConnectionSubset): The subset of connections to select from. + max_connections (Optional[int]): The maximum number of connections to retrieve. Raises: click.UsageError: If a required object is missing for the command. click.UsageError: If a retrieval reason is missing when passing a connection id. Returns: - ConnectionObjects: The connection objects values. + List[ConnectionObjects]: List of connection objects. """ - if connection_id and auto_select_connection: - raise ValueError("Cannot set both `connection_id` and `auto_select_connection`.") - if auto_select_connection and not connector_image: - raise ValueError("A connector image must be provided when using auto_select_connection.") + if connection_id and auto_select_connections: + raise ValueError("Cannot set both `connection_id` and `auto_select_connections`.") + if auto_select_connections and not connector_image: + raise ValueError("A connector image must be provided when using auto_select_connections.") custom_config = get_connector_config_from_path(custom_config_path) if custom_config_path else None custom_configured_catalog = ( @@ -143,58 +146,79 @@ def get_connection_objects( if not retrieval_reason: raise ValueError("A retrieval reason is required to access the connection objects when passing a connection id.") - connection_object = _get_connection_objects_from_retrieved_objects( + connection_objects = _get_connection_objects_from_retrieved_objects( requested_objects, retrieval_reason=retrieval_reason, source_docker_repository=connector_image, source_docker_image_tag=connector_version, - prompt_for_connection_selection=False, selected_streams=selected_streams, connection_id=connection_id, custom_config=custom_config, custom_configured_catalog=custom_configured_catalog, custom_state=custom_state, connection_subset=connection_subset, + max_connections=max_connections, ) else: - if auto_select_connection: - connection_object = _get_connection_objects_from_retrieved_objects( + if auto_select_connections: + connection_objects = _get_connection_objects_from_retrieved_objects( requested_objects, retrieval_reason=retrieval_reason, source_docker_repository=connector_image, source_docker_image_tag=connector_version, - prompt_for_connection_selection=not is_ci, selected_streams=selected_streams, custom_config=custom_config, custom_configured_catalog=custom_configured_catalog, custom_state=custom_state, connection_subset=connection_subset, + max_connections=max_connections, ) else: # We don't make any requests to the connection-retriever; it is expected that config/catalog/state have been provided if needed for the commands being run. - connection_object = ConnectionObjects( - source_config=custom_config, - destination_config=custom_config, - catalog=None, - configured_catalog=custom_configured_catalog, - state=custom_state, - workspace_id=None, - source_id=None, - destination_id=None, - connection_id=None, - source_docker_image=None, - ) + connection_objects = [ + ConnectionObjects( + source_config=custom_config, + destination_config=custom_config, + catalog=None, + configured_catalog=custom_configured_catalog, + state=custom_state, + workspace_id=None, + source_id=None, + destination_id=None, + connection_id=None, + source_docker_image=None, + ) + ] + if not connection_objects: + raise ValueError("No connection objects could be fetched.") + + all_connection_ids = [connection_object.connection_id for connection_object in connection_objects] + assert len(set(all_connection_ids)) == len(all_connection_ids), "Connection IDs must be unique." + return connection_objects + + +def _find_best_candidates_subset(candidates: List[TestingCandidate]) -> List[Tuple[TestingCandidate, List[str]]]: + """ + This function reduces the list of candidates to the best subset of candidates. + The best subset is the one which maximizes the number of streams tested and minimizes the number of candidates. + """ + candidates_sorted_by_duration = sorted(candidates, key=lambda x: x.last_attempt_duration_in_microseconds) + + tested_streams = set() + candidates_and_streams_to_test = [] - if fail_if_missing_objects: - if not connection_object.source_config and ConnectionObject.SOURCE_CONFIG in requested_objects: - raise ValueError("A source config is required to run the command.") - if not connection_object.catalog and ConnectionObject.CONFIGURED_CATALOG in requested_objects: - raise ValueError("A catalog is required to run the command.") - if not connection_object.state and ConnectionObject.STATE in requested_objects: - raise ValueError("A state is required to run the command.") - return connection_object + for candidate in candidates_sorted_by_duration: + candidate_streams_to_test = [] + for stream in candidate.streams_with_data: + # The candidate is selected if one of its streams has not been tested yet + if stream not in tested_streams: + candidate_streams_to_test.append(stream) + tested_streams.add(stream) + if candidate_streams_to_test: + candidates_and_streams_to_test.append((candidate, candidate_streams_to_test)) + return candidates_and_streams_to_test def _get_connection_objects_from_retrieved_objects( @@ -202,56 +226,92 @@ def _get_connection_objects_from_retrieved_objects( retrieval_reason: str, source_docker_repository: str, source_docker_image_tag: str, - prompt_for_connection_selection: bool, selected_streams: Optional[Set[str]], connection_id: Optional[str] = None, custom_config: Optional[Dict] = None, custom_configured_catalog: Optional[ConfiguredAirbyteCatalog] = None, custom_state: Optional[Dict] = None, connection_subset: ConnectionSubset = ConnectionSubset.SANDBOXES, + max_connections: Optional[int] = None, ): - LOGGER.info("Retrieving connection objects from the database...") - connection_id, retrieved_objects = retrieve_objects( - requested_objects, - retrieval_reason=retrieval_reason, - source_docker_repository=source_docker_repository, - source_docker_image_tag=source_docker_image_tag, - prompt_for_connection_selection=prompt_for_connection_selection, - with_streams=selected_streams, - connection_id=connection_id, - connection_subset=connection_subset, + console.log( + textwrap.dedent( + """ + Retrieving connection objects from the database. + We will build a subset of candidates to test. + This subset should minimize the number of candidates and sync duration while maximizing the number of streams tested. + We patch configured catalogs to only test streams once. + If the max_connections parameter is set, we will only keep the top connections with the most streams to test. + """ + ) ) - - retrieved_source_config = parse_config(retrieved_objects.get(ConnectionObject.SOURCE_CONFIG)) - retrieved_destination_config = parse_config(retrieved_objects.get(ConnectionObject.DESTINATION_CONFIG)) - retrieved_catalog = parse_catalog(retrieved_objects.get(ConnectionObject.CATALOG)) - retrieved_configured_catalog = parse_configured_catalog(retrieved_objects.get(ConnectionObject.CONFIGURED_CATALOG), selected_streams) - retrieved_state = parse_state(retrieved_objects.get(ConnectionObject.STATE)) - - retrieved_source_docker_image = retrieved_objects.get(ConnectionObject.SOURCE_DOCKER_IMAGE) - connection_url = build_connection_url(retrieved_objects.get(ConnectionObject.WORKSPACE_ID), connection_id) - if retrieved_source_docker_image is None: - raise InvalidConnectionError( - f"No docker image was found for connection ID {connection_id}. Please double check that the latest job run used version {source_docker_image_tag}. Connection URL: {connection_url}" + try: + candidates = retrieve_testing_candidates( + source_docker_repository=source_docker_repository, + source_docker_image_tag=source_docker_image_tag, + with_streams=selected_streams, + connection_subset=connection_subset, ) - elif retrieved_source_docker_image.split(":")[0] != source_docker_repository: + except IndexError: raise InvalidConnectionError( - f"The provided docker image ({source_docker_repository}) does not match the image for connection ID {connection_id}. Please double check that this connection is using the correct image. Connection URL: {connection_url}" + f"No candidates were found for the provided source docker image ({source_docker_repository}:{source_docker_image_tag})." ) - elif retrieved_source_docker_image.split(":")[1] != source_docker_image_tag: - raise InvalidConnectionError( - f"The provided docker image tag ({source_docker_image_tag}) does not match the image tag for connection ID {connection_id}. Please double check that this connection is using the correct image tag and the latest job ran using this version. Connection URL: {connection_url}" + # If the connection_id is provided, we filter the candidates to only keep the ones with the same connection_id + if connection_id: + candidates = [candidate for candidate in candidates if candidate.connection_id == connection_id] + + candidates_and_streams_to_test = _find_best_candidates_subset(candidates) + candidates_and_streams_to_test = sorted(candidates_and_streams_to_test, key=lambda x: len(x[1]), reverse=True) + if max_connections: + candidates_and_streams_to_test = candidates_and_streams_to_test[:max_connections] + + number_of_streams_tested = sum([len(streams_to_test) for _, streams_to_test in candidates_and_streams_to_test]) + console.log(f"Selected {len(candidates_and_streams_to_test)} candidates to test {number_of_streams_tested} streams.") + + all_connection_objects = [] + for candidate, streams_to_test in candidates_and_streams_to_test: + retrieved_objects = retrieve_objects( + requested_objects, + retrieval_reason=retrieval_reason, + source_docker_repository=source_docker_repository, + source_docker_image_tag=source_docker_image_tag, + connection_id=candidate.connection_id, + connection_subset=connection_subset, ) + retrieved_objects = retrieved_objects[0] + retrieved_source_config = parse_config(retrieved_objects.source_config) + retrieved_destination_config = parse_config(retrieved_objects.destination_config) + retrieved_catalog = parse_catalog(retrieved_objects.catalog) + retrieved_configured_catalog = parse_configured_catalog(retrieved_objects.configured_catalog, streams_to_test) + retrieved_state = parse_state(retrieved_objects.state) + + retrieved_source_docker_image = retrieved_objects.source_docker_image + connection_url = build_connection_url(retrieved_objects.workspace_id, retrieved_objects.connection_id) + if retrieved_source_docker_image is None: + raise InvalidConnectionError( + f"No docker image was found for connection ID {retrieved_objects.connection_id}. Please double check that the latest job run used version {source_docker_image_tag}. Connection URL: {connection_url}" + ) + elif retrieved_source_docker_image.split(":")[0] != source_docker_repository: + raise InvalidConnectionError( + f"The provided docker image ({source_docker_repository}) does not match the image for connection ID {retrieved_objects.connection_id}. Please double check that this connection is using the correct image. Connection URL: {connection_url}" + ) + elif retrieved_source_docker_image.split(":")[1] != source_docker_image_tag: + raise InvalidConnectionError( + f"The provided docker image tag ({source_docker_image_tag}) does not match the image tag for connection ID {retrieved_objects.connection_id}. Please double check that this connection is using the correct image tag and the latest job ran using this version. Connection URL: {connection_url}" + ) - return ConnectionObjects( - source_config=custom_config if custom_config else retrieved_source_config, - destination_config=custom_config if custom_config else retrieved_destination_config, - catalog=retrieved_catalog, - configured_catalog=custom_configured_catalog if custom_configured_catalog else retrieved_configured_catalog, - state=custom_state if custom_state else retrieved_state, - workspace_id=retrieved_objects.get(ConnectionObject.WORKSPACE_ID), - source_id=retrieved_objects.get(ConnectionObject.SOURCE_ID), - destination_id=retrieved_objects.get(ConnectionObject.DESTINATION_ID), - source_docker_image=retrieved_source_docker_image, - connection_id=connection_id, - ) + all_connection_objects.append( + ConnectionObjects( + source_config=custom_config if custom_config else retrieved_source_config, + destination_config=custom_config if custom_config else retrieved_destination_config, + catalog=retrieved_catalog, + configured_catalog=custom_configured_catalog if custom_configured_catalog else retrieved_configured_catalog, + state=custom_state if custom_state else retrieved_state, + workspace_id=retrieved_objects.workspace_id, + source_id=retrieved_objects.source_id, + destination_id=retrieved_objects.destination_id, + source_docker_image=retrieved_source_docker_image, + connection_id=retrieved_objects.connection_id, + ) + ) + return all_connection_objects diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/commons/connector_runner.py b/airbyte-ci/connectors/live-tests/src/live_tests/commons/connector_runner.py index 1b651fbecca0..a2bd441efab3 100644 --- a/airbyte-ci/connectors/live-tests/src/live_tests/commons/connector_runner.py +++ b/airbyte-ci/connectors/live-tests/src/live_tests/commons/connector_runner.py @@ -15,16 +15,18 @@ import anyio import asyncer import dagger + from live_tests.commons import errors from live_tests.commons.models import Command, ExecutionInputs, ExecutionResult from live_tests.commons.proxy import Proxy class ConnectorRunner: - IN_CONTAINER_CONFIG_PATH = "/data/config.json" - IN_CONTAINER_CONFIGURED_CATALOG_PATH = "/data/catalog.json" - IN_CONTAINER_STATE_PATH = "/data/state.json" - IN_CONTAINER_OUTPUT_PATH = "/output.txt" + DATA_DIR = "/airbyte/data" + IN_CONTAINER_CONFIG_PATH = f"{DATA_DIR}/config.json" + IN_CONTAINER_CONFIGURED_CATALOG_PATH = f"{DATA_DIR}/catalog.json" + IN_CONTAINER_STATE_PATH = f"{DATA_DIR}/state.json" + IN_CONTAINER_OUTPUT_PATH = f"{DATA_DIR}/output.txt" IN_CONTAINER_OBFUSCATOR_PATH = "/user/local/bin/record_obfuscator.py" def __init__( @@ -42,6 +44,7 @@ def __init__( self.state = execution_inputs.state self.duckdb_path = execution_inputs.duckdb_path self.actor_id = execution_inputs.actor_id + self.hashed_connection_id = execution_inputs.hashed_connection_id self.environment_variables = execution_inputs.environment_variables if execution_inputs.environment_variables else {} self.full_command: list[str] = self._get_full_command(execution_inputs.command) @@ -117,6 +120,9 @@ async def _run( self, ) -> ExecutionResult: container = self._connector_under_test_container + current_user = (await container.with_exec(["whoami"]).stdout()).strip() + container = container.with_user(current_user) + container = container.with_exec(["mkdir", "-p", self.DATA_DIR]) # Do not cache downstream dagger layers container = container.with_env_variable("CACHEBUSTER", str(uuid.uuid4())) @@ -130,13 +136,14 @@ async def _run( for env_var_name, env_var_value in self.environment_variables.items(): container = container.with_env_variable(env_var_name, env_var_value) if self.config: - container = container.with_new_file(self.IN_CONTAINER_CONFIG_PATH, contents=json.dumps(dict(self.config))) + container = container.with_new_file(self.IN_CONTAINER_CONFIG_PATH, contents=json.dumps(dict(self.config)), owner=current_user) if self.state: - container = container.with_new_file(self.IN_CONTAINER_STATE_PATH, contents=json.dumps(self.state)) + container = container.with_new_file(self.IN_CONTAINER_STATE_PATH, contents=json.dumps(self.state), owner=current_user) if self.configured_catalog: container = container.with_new_file( self.IN_CONTAINER_CONFIGURED_CATALOG_PATH, contents=self.configured_catalog.json(), + owner=current_user, ) if self.http_proxy: container = await self.http_proxy.bind_container(container) @@ -147,7 +154,7 @@ async def _run( entrypoint = await container.entrypoint() assert entrypoint, "The connector container has no entrypoint" airbyte_command = entrypoint + self.full_command - # We are piping the output to a file to avoid QueryError: file size exceeds limit 134217728 + container = container.with_exec( [ "sh", @@ -181,11 +188,14 @@ async def _run( command=self.command, connector_under_test=self.connector_under_test, actor_id=self.actor_id, + hashed_connection_id=self.hashed_connection_id, + configured_catalog=self.configured_catalog, stdout_file_path=self.stdout_file_path, stderr_file_path=self.stderr_file_path, success=success, http_dump=await self.http_proxy.retrieve_http_dump() if self.http_proxy else None, executed_container=executed_container, + config=self.config, ) await execution_result.save_artifacts(self.output_dir, self.duckdb_path) return execution_result diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/commons/hacks.py b/airbyte-ci/connectors/live-tests/src/live_tests/commons/hacks.py new file mode 100644 index 000000000000..77c2adbd8d7a --- /dev/null +++ b/airbyte-ci/connectors/live-tests/src/live_tests/commons/hacks.py @@ -0,0 +1,23 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + +import copy + +import rich + +console = rich.get_console() + + +def patch_configured_catalog(configured_catalog: dict) -> dict: + """ + The configured catalog extracted from the platform can be incompatible with the airbyte-protocol. + This leads to validation error when we serialize the configured catalog into a ConfiguredAirbyteCatalog object. + This functions is a best effort to patch the configured catalog to make it compatible with the airbyte-protocol. + """ + patched_catalog = copy.deepcopy(configured_catalog) + for stream in patched_catalog["streams"]: + if stream.get("destination_sync_mode") == "overwrite_dedup": + stream["destination_sync_mode"] = "overwrite" + console.log( + f"Stream {stream['stream']['name']} destination_sync_mode has been patched from 'overwrite_dedup' to 'overwrite' to guarantee compatibility with the airbyte-protocol." + ) + return patched_catalog diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/commons/models.py b/airbyte-ci/connectors/live-tests/src/live_tests/commons/models.py index f762a2f94ad2..abca9772135b 100644 --- a/airbyte-ci/connectors/live-tests/src/live_tests/commons/models.py +++ b/airbyte-ci/connectors/live-tests/src/live_tests/commons/models.py @@ -2,6 +2,8 @@ from __future__ import annotations +import _collections_abc +import hashlib import json import logging import tempfile @@ -13,17 +15,21 @@ from pathlib import Path from typing import Any, Dict, List, Optional -import _collections_abc import dagger import requests -from airbyte_protocol.models import AirbyteCatalog # type: ignore -from airbyte_protocol.models import AirbyteMessage # type: ignore -from airbyte_protocol.models import AirbyteStateMessage # type: ignore -from airbyte_protocol.models import AirbyteStreamStatusTraceMessage # type: ignore -from airbyte_protocol.models import ConfiguredAirbyteCatalog # type: ignore -from airbyte_protocol.models import TraceType # type: ignore +from airbyte_protocol.models import ( + AirbyteCatalog, # type: ignore + AirbyteMessage, # type: ignore + AirbyteStateMessage, # type: ignore + AirbyteStreamStatusTraceMessage, # type: ignore + ConfiguredAirbyteCatalog, # type: ignore + TraceType, # type: ignore +) from airbyte_protocol.models import Type as AirbyteMessageType from genson import SchemaBuilder # type: ignore +from mitmproxy import http +from pydantic import ValidationError + from live_tests.commons.backends import DuckDbBackend, FileBackend from live_tests.commons.secret_access import get_airbyte_api_key from live_tests.commons.utils import ( @@ -33,8 +39,6 @@ sanitize_stream_name, sort_dict_keys, ) -from mitmproxy import http -from pydantic import ValidationError class UserDict(_collections_abc.MutableMapping): # type: ignore @@ -138,6 +142,15 @@ class Command(Enum): READ_WITH_STATE = "read-with-state" SPEC = "spec" + def needs_config(self) -> bool: + return self in {Command.CHECK, Command.DISCOVER, Command.READ, Command.READ_WITH_STATE} + + def needs_catalog(self) -> bool: + return self in {Command.READ, Command.READ_WITH_STATE} + + def needs_state(self) -> bool: + return self in {Command.READ_WITH_STATE} + class TargetOrControl(Enum): TARGET = "target" @@ -204,6 +217,7 @@ async def from_image_name( @dataclass class ExecutionInputs: + hashed_connection_id: str connector_under_test: ConnectorUnderTest actor_id: str global_output_dir: Path @@ -235,7 +249,7 @@ def __post_init__(self) -> None: def output_dir(self) -> Path: output_dir = ( self.global_output_dir - / f"command_execution_artifacts/{self.connector_under_test.name}/{self.command.value}/{self.connector_under_test.version}/" + / f"command_execution_artifacts/{self.connector_under_test.name}/{self.command.value}/{self.connector_under_test.version}/{self.hashed_connection_id}" ) output_dir.mkdir(parents=True, exist_ok=True) return output_dir @@ -243,13 +257,16 @@ def output_dir(self) -> Path: @dataclass class ExecutionResult: + hashed_connection_id: str actor_id: str + configured_catalog: ConfiguredAirbyteCatalog connector_under_test: ConnectorUnderTest command: Command stdout_file_path: Path stderr_file_path: Path success: bool executed_container: Optional[dagger.Container] + config: Optional[SecretDict] http_dump: Optional[dagger.File] = None http_flows: list[http.HTTPFlow] = field(default_factory=list) stream_schemas: Optional[dict[str, Any]] = None @@ -268,28 +285,42 @@ def airbyte_messages(self) -> Iterable[AirbyteMessage]: @property def duckdb_schema(self) -> Iterable[str]: - return (self.connector_under_test.target_or_control.value, self.command.value) + return (self.connector_under_test.target_or_control.value, self.command.value, self.hashed_connection_id) + + @property + def configured_streams(self) -> List[str]: + return [stream.stream.name for stream in self.configured_catalog.streams] + + @property + def primary_keys_per_stream(self) -> Dict[str, List[str]]: + return {stream.stream.name: stream.primary_key[0] if stream.primary_key else None for stream in self.configured_catalog.streams} @classmethod async def load( cls: type[ExecutionResult], connector_under_test: ConnectorUnderTest, + hashed_connection_id: str, actor_id: str, + configured_catalog: ConfiguredAirbyteCatalog, command: Command, stdout_file_path: Path, stderr_file_path: Path, success: bool, executed_container: Optional[dagger.Container], + config: Optional[SecretDict] = None, http_dump: Optional[dagger.File] = None, ) -> ExecutionResult: execution_result = cls( + hashed_connection_id, actor_id, + configured_catalog, connector_under_test, command, stdout_file_path, stderr_file_path, success, executed_container, + config, http_dump, ) await execution_result.load_http_flows() @@ -498,3 +529,15 @@ class ConnectionObjects: destination_id: Optional[str] source_docker_image: Optional[str] connection_id: Optional[str] + + @property + def url(self) -> Optional[str]: + if not self.workspace_id or not self.connection_id: + return None + return f"https://cloud.airbyte.com/workspaces/{self.workspace_id}/connections/{self.connection_id}" + + @property + def hashed_connection_id(self) -> Optional[str]: + if not self.connection_id: + return None + return hashlib.sha256(self.connection_id.encode("utf-8")).hexdigest()[:7] diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/commons/proxy.py b/airbyte-ci/connectors/live-tests/src/live_tests/commons/proxy.py index eceb2686ed70..a601ab734fdb 100644 --- a/airbyte-ci/connectors/live-tests/src/live_tests/commons/proxy.py +++ b/airbyte-ci/connectors/live-tests/src/live_tests/commons/proxy.py @@ -45,29 +45,38 @@ def dump_cache_volume(self) -> dagger.CacheVolume: def mitmproxy_dir_cache(self) -> dagger.CacheVolume: return self.dagger_client.cache_volume(self.MITMPROXY_IMAGE) - async def get_container( - self, - ) -> dagger.Container: + def generate_mitmconfig(self): + return ( + self.dagger_client.container() + .from_(self.MITMPROXY_IMAGE) + # Mitmproxy generates its self signed certs at first run, we need to run it once to generate the certs + # They are stored in /root/.mitmproxy + .with_exec(["timeout", "--preserve-status", "1", "mitmdump"]) + .directory("/root/.mitmproxy") + ) + + async def get_container(self, mitm_config: dagger.Directory) -> dagger.Container: """Get a container for the mitmproxy service. If a stream for server replay is provided, it will be used to replay requests to the same URL. Returns: dagger.Container: The container for the mitmproxy service. + mitm_config (dagger.Directory): The directory containing the mitmproxy configuration. """ container_addons_path = "/addons.py" proxy_container = ( self.dagger_client.container() .from_(self.MITMPROXY_IMAGE) - .with_exec(["mkdir", "-p", "/home/mitmproxy/.mitmproxy"]) + .with_exec(["mkdir", "/dumps"]) # This is caching the mitmproxy stream files, which can contain sensitive information # We want to nuke this cache after test suite execution. .with_mounted_cache("/dumps", self.dump_cache_volume) # This is caching the mitmproxy self-signed certificate, no sensitive information is stored in it - .with_mounted_cache("/home/mitmproxy/.mitmproxy", self.mitmproxy_dir_cache) .with_file( container_addons_path, self.dagger_client.host().file(self.MITM_ADDONS_PATH), ) + .with_directory("/root/.mitmproxy", mitm_config) ) # If the proxy was instantiated with a stream for server replay from a previous run, we want to use it. @@ -99,8 +108,8 @@ async def get_container( return proxy_container.with_exec(command) - async def get_service(self) -> dagger.Service: - return (await self.get_container()).with_exposed_port(self.PROXY_PORT).as_service() + async def get_service(self, mitm_config: dagger.Directory) -> dagger.Service: + return (await self.get_container(mitm_config)).with_exposed_port(self.PROXY_PORT).as_service() async def bind_container(self, container: dagger.Container) -> dagger.Container: """Bind a container to the proxy service and set environment variables to use the proxy for HTTP(S) traffic. @@ -111,24 +120,27 @@ async def bind_container(self, container: dagger.Container) -> dagger.Container: Returns: dagger.Container: The container with the proxy service bound and environment variables set. """ - cert_path_in_volume = "/mitmproxy_dir/mitmproxy-ca.pem" - ca_certificate_path = "/usr/local/share/ca-certificates/mitmproxy.crt" + mitmconfig_dir = self.generate_mitmconfig() + pem = mitmconfig_dir.file("mitmproxy-ca.pem") + # Find the python version in the container to get the correct path for the requests cert file + # We will overwrite this file with the mitmproxy self-signed certificate + # I could not find a less brutal way to make Requests trust the mitmproxy self-signed certificate + # I tried running update-ca-certificates + setting REQUESTS_CA_BUNDLE in the container but it did not work python_version_output = (await container.with_exec(["python", "--version"]).stdout()).strip() python_version = python_version_output.split(" ")[-1] python_version_minor_only = ".".join(python_version.split(".")[:-1]) requests_cert_path = f"/usr/local/lib/python{python_version_minor_only}/site-packages/certifi/cacert.pem" + current_user = (await container.with_exec(["whoami"]).stdout()).strip() try: return await ( - container.with_service_binding(self.hostname, await self.get_service()) - .with_mounted_cache("/mitmproxy_dir", self.mitmproxy_dir_cache) - .with_exec(["cp", cert_path_in_volume, requests_cert_path]) - .with_exec(["cp", cert_path_in_volume, ca_certificate_path]) - # The following command make the container use the proxy for all outgoing HTTP requests - .with_env_variable("REQUESTS_CA_BUNDLE", requests_cert_path) - .with_exec(["update-ca-certificates"]) + container.with_user("root") + # Overwrite the requests cert file with the mitmproxy self-signed certificate + .with_file(requests_cert_path, pem, owner=current_user) .with_env_variable("http_proxy", f"{self.hostname}:{self.PROXY_PORT}") .with_env_variable("https_proxy", f"{self.hostname}:{self.PROXY_PORT}") + .with_user(current_user) + .with_service_binding(self.hostname, await self.get_service(mitmconfig_dir)) ) except dagger.DaggerError as e: # This is likely hapenning on Java connector images whose certificates location is different diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/conftest.py b/airbyte-ci/connectors/live-tests/src/live_tests/conftest.py index a9e2f6cd54fd..5e3256b84a78 100644 --- a/airbyte-ci/connectors/live-tests/src/live_tests/conftest.py +++ b/airbyte-ci/connectors/live-tests/src/live_tests/conftest.py @@ -1,20 +1,24 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. from __future__ import annotations +import hashlib import logging import os import textwrap import time import webbrowser from collections.abc import AsyncGenerator, AsyncIterable, Callable, Generator, Iterable +from itertools import product from pathlib import Path -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING, List, Optional import dagger import pytest from airbyte_protocol.models import AirbyteCatalog, AirbyteStateMessage, ConfiguredAirbyteCatalog, ConnectorSpecification # type: ignore from connection_retriever.audit_logging import get_user_email # type: ignore -from connection_retriever.retrieval import ConnectionNotFoundError, NotPermittedError, get_current_docker_image_tag # type: ignore +from connection_retriever.retrieval import ConnectionNotFoundError, get_current_docker_image_tag # type: ignore +from rich.prompt import Confirm, Prompt + from live_tests import stash_keys from live_tests.commons.connection_objects_retrieval import ConnectionObject, InvalidConnectionError, get_connection_objects from live_tests.commons.connector_runner import ConnectorRunner, Proxy @@ -32,10 +36,9 @@ ) from live_tests.commons.secret_access import get_airbyte_api_key from live_tests.commons.segment_tracking import track_usage -from live_tests.commons.utils import build_connection_url, clean_up_artifacts -from live_tests.report import Report, ReportState +from live_tests.commons.utils import clean_up_artifacts +from live_tests.report import PrivateDetailsReport, ReportState, TestReport from live_tests.utils import get_catalog, get_spec -from rich.prompt import Confirm, Prompt if TYPE_CHECKING: from _pytest.config import Config @@ -97,6 +100,11 @@ def pytest_addoption(parser: Parser) -> None: default=ConnectionSubset.SANDBOXES.value, help="Whether to select from sandbox accounts only.", ) + parser.addoption( + "--max-connections", + default=None, + help="The maximum number of connections to retrieve and use for testing.", + ) def pytest_configure(config: Config) -> None: @@ -125,9 +133,10 @@ def pytest_configure(config: Config) -> None: dagger_log_path = test_artifacts_directory / "dagger.log" config.stash[stash_keys.IS_PERMITTED_BOOL] = False report_path = test_artifacts_directory / "report.html" - + private_details_path = test_artifacts_directory / "private_details.html" config.stash[stash_keys.TEST_ARTIFACT_DIRECTORY] = test_artifacts_directory dagger_log_path.touch() + LOGGER.info("Dagger log path: %s", dagger_log_path) config.stash[stash_keys.DAGGER_LOG_PATH] = dagger_log_path config.stash[stash_keys.PR_URL] = get_option_or_fail(config, "--pr-url") _connection_id = config.getoption("--connection-id") @@ -141,6 +150,10 @@ def pytest_configure(config: Config) -> None: custom_state_path = config.getoption("--state-path") config.stash[stash_keys.SELECTED_STREAMS] = set(config.getoption("--stream") or []) config.stash[stash_keys.TEST_EVALUATION_MODE] = TestEvaluationMode(config.getoption("--test-evaluation-mode", "strict")) + config.stash[stash_keys.MAX_CONNECTIONS] = config.getoption("--max-connections") + config.stash[stash_keys.MAX_CONNECTIONS] = ( + int(config.stash[stash_keys.MAX_CONNECTIONS]) if config.stash[stash_keys.MAX_CONNECTIONS] else None + ) if config.stash[stash_keys.RUN_IN_AIRBYTE_CI]: config.stash[stash_keys.SHOULD_READ_WITH_STATE] = bool(config.getoption("--should-read-with-state")) @@ -152,7 +165,7 @@ def pytest_configure(config: Config) -> None: retrieval_reason = f"Running live tests on connection for connector {config.stash[stash_keys.CONNECTOR_IMAGE]} on target versions ({config.stash[stash_keys.TARGET_VERSION]})." try: - config.stash[stash_keys.CONNECTION_OBJECTS] = get_connection_objects( + config.stash[stash_keys.ALL_CONNECTION_OBJECTS] = get_connection_objects( { ConnectionObject.SOURCE_CONFIG, ConnectionObject.CATALOG, @@ -168,12 +181,12 @@ def pytest_configure(config: Config) -> None: Path(custom_configured_catalog_path) if custom_configured_catalog_path else None, Path(custom_state_path) if custom_state_path else None, retrieval_reason, - fail_if_missing_objects=False, connector_image=config.stash[stash_keys.CONNECTOR_IMAGE], connector_version=config.stash[stash_keys.CONTROL_VERSION], - auto_select_connection=config.stash[stash_keys.AUTO_SELECT_CONNECTION], + auto_select_connections=config.stash[stash_keys.AUTO_SELECT_CONNECTION], selected_streams=config.stash[stash_keys.SELECTED_STREAMS], connection_subset=config.stash[stash_keys.CONNECTION_SUBSET], + max_connections=config.stash[stash_keys.MAX_CONNECTIONS], ) config.stash[stash_keys.IS_PERMITTED_BOOL] = True except (ConnectionNotFoundError, InvalidConnectionError) as exc: @@ -183,22 +196,21 @@ def pytest_configure(config: Config) -> None: ) pytest.exit(str(exc)) - config.stash[stash_keys.CONNECTION_ID] = config.stash[stash_keys.CONNECTION_OBJECTS].connection_id # type: ignore - if config.stash[stash_keys.CONTROL_VERSION] == config.stash[stash_keys.TARGET_VERSION]: pytest.exit(f"Control and target versions are the same: {control_version}. Please provide different versions.") - if config.stash[stash_keys.CONNECTION_OBJECTS].workspace_id and config.stash[stash_keys.CONNECTION_ID]: - config.stash[stash_keys.CONNECTION_URL] = build_connection_url( - config.stash[stash_keys.CONNECTION_OBJECTS].workspace_id, - config.stash[stash_keys.CONNECTION_ID], - ) - else: - config.stash[stash_keys.CONNECTION_URL] = None - config.stash[stash_keys.REPORT] = Report( + + config.stash[stash_keys.PRIVATE_DETAILS_REPORT] = PrivateDetailsReport( + private_details_path, + config, + ) + + config.stash[stash_keys.TEST_REPORT] = TestReport( report_path, config, + private_details_url=config.stash[stash_keys.PRIVATE_DETAILS_REPORT].path.resolve().as_uri(), ) - webbrowser.open_new_tab(config.stash[stash_keys.REPORT].path.resolve().as_uri()) + + webbrowser.open_new_tab(config.stash[stash_keys.TEST_REPORT].path.resolve().as_uri()) def get_artifacts_directory(config: pytest.Config) -> Path: @@ -215,7 +227,8 @@ def pytest_collection_modifyitems(config: pytest.Config, items: list[pytest.Item def pytest_terminal_summary(terminalreporter: SugarTerminalReporter, exitstatus: int, config: Config) -> None: - config.stash[stash_keys.REPORT].update(ReportState.FINISHED) + config.stash[stash_keys.TEST_REPORT].update(ReportState.FINISHED) + config.stash[stash_keys.PRIVATE_DETAILS_REPORT].update(ReportState.FINISHED) if not config.stash.get(stash_keys.IS_PERMITTED_BOOL, False): # Don't display the prompt if the tests were not run due to inability to fetch config clean_up_artifacts(MAIN_OUTPUT_DIRECTORY, LOGGER) @@ -264,7 +277,7 @@ def pytest_runtest_makereport(item: pytest.Item, call: pytest.CallInfo) -> Gener # This is to add skipped or failed tests due to upstream fixture failures on setup if report.outcome in ["failed", "skipped"] or report.when == "call": - item.config.stash[stash_keys.REPORT].add_test_result( + item.config.stash[stash_keys.TEST_REPORT].add_test_result( report, item.function.__doc__, # type: ignore ) @@ -353,18 +366,17 @@ def target_version(request: SubRequest) -> str: @pytest.fixture(scope="session") -def connection_id(request: SubRequest) -> Optional[str]: - return request.config.stash[stash_keys.CONNECTION_ID] +def all_connection_objects(request: SubRequest) -> List[ConnectionObjects]: + return request.config.stash[stash_keys.ALL_CONNECTION_OBJECTS] -@pytest.fixture(scope="session") -def connection_objects(request: SubRequest) -> ConnectionObjects: - return request.config.stash[stash_keys.CONNECTION_OBJECTS] - - -@pytest.fixture(scope="session") -def connector_config(connection_objects: ConnectionObjects) -> Optional[SecretDict]: - return connection_objects.source_config +def get_connector_config(connection_objects: ConnectionObjects, control_connector: ConnectorUnderTest) -> Optional[SecretDict]: + if control_connector.actor_type is ActorType.SOURCE: + return connection_objects.source_config + elif control_connector.actor_type is ActorType.DESTINATION: + return connection_objects.destination_config + else: + raise ValueError(f"Actor type {control_connector.actor_type} is not supported") @pytest.fixture(scope="session") @@ -377,34 +389,13 @@ def actor_id(connection_objects: ConnectionObjects, control_connector: Connector raise ValueError(f"Actor type {control_connector.actor_type} is not supported") -@pytest.fixture(scope="session") -def selected_streams(request: SubRequest) -> set[str]: - return request.config.stash[stash_keys.SELECTED_STREAMS] - - -@pytest.fixture(scope="session") -def configured_catalog(connection_objects: ConnectionObjects, selected_streams: Optional[set[str]]) -> ConfiguredAirbyteCatalog: - if not connection_objects.configured_catalog: - pytest.skip("Catalog is not provided. The catalog fixture can't be used.") - assert connection_objects.configured_catalog is not None - return connection_objects.configured_catalog - - -@pytest.fixture(scope="session") -def target_discovered_catalog(discover_target_execution_result: ExecutionResult) -> AirbyteCatalog: - return get_catalog(discover_target_execution_result) - - -@pytest.fixture(scope="session") -def target_spec(spec_target_execution_result: ExecutionResult) -> ConnectorSpecification: - return get_spec(spec_target_execution_result) - - -@pytest.fixture(scope="session", autouse=True) -def primary_keys_per_stream( - configured_catalog: ConfiguredAirbyteCatalog, -) -> dict[str, Optional[list[str]]]: - return {stream.stream.name: stream.primary_key[0] if stream.primary_key else None for stream in configured_catalog.streams} +def get_actor_id(connection_objects: ConnectionObjects, control_connector: ConnectorUnderTest) -> str | None: + if control_connector.actor_type is ActorType.SOURCE: + return connection_objects.source_id + elif control_connector.actor_type is ActorType.DESTINATION: + return connection_objects.destination_id + else: + raise ValueError(f"Actor type {control_connector.actor_type} is not supported") @pytest.fixture(scope="session") @@ -447,528 +438,189 @@ def duckdb_path(request: SubRequest) -> Path: return request.config.stash[stash_keys.DUCKDB_PATH] -@pytest.fixture(scope="session") -def spec_control_execution_inputs( +def get_execution_inputs_for_command( + command: Command, + connection_objects: ConnectionObjects, control_connector: ConnectorUnderTest, - actor_id: str, test_artifacts_directory: Path, duckdb_path: Path, ) -> ExecutionInputs: - return ExecutionInputs( - connector_under_test=control_connector, - actor_id=actor_id, - command=Command.SPEC, - global_output_dir=test_artifacts_directory, - duckdb_path=duckdb_path, - ) - - -@pytest.fixture(scope="session") -def spec_control_connector_runner( - request: SubRequest, + """Get the execution inputs for the given command and connection objects.""" + actor_id = get_actor_id(connection_objects, control_connector) + + inputs_arguments = { + "hashed_connection_id": connection_objects.hashed_connection_id, + "connector_under_test": control_connector, + "actor_id": actor_id, + "global_output_dir": test_artifacts_directory, + "command": command, + "duckdb_path": duckdb_path, + } + + if command.needs_config: + connector_config = get_connector_config(connection_objects, control_connector) + if not connector_config: + pytest.skip("Config is not provided. The config fixture can't be used.") + inputs_arguments["config"] = connector_config + if command.needs_catalog: + configured_catalog = connection_objects.configured_catalog + if not configured_catalog: + pytest.skip("Catalog is not provided. The catalog fixture can't be used.") + inputs_arguments["configured_catalog"] = connection_objects.configured_catalog + if command.needs_state: + state = connection_objects.state + if not state: + pytest.skip("State is not provided. The state fixture can't be used.") + inputs_arguments["state"] = state + + return ExecutionInputs(**inputs_arguments) + + +async def run_command( dagger_client: dagger.Client, - spec_control_execution_inputs: ExecutionInputs, -) -> ConnectorRunner: - runner = ConnectorRunner( - dagger_client, - spec_control_execution_inputs, - request.config.stash[stash_keys.RUN_IN_AIRBYTE_CI], - ) - return runner - - -@pytest.fixture(scope="session") -async def spec_control_execution_result( - request: SubRequest, - spec_control_execution_inputs: ExecutionInputs, - spec_control_connector_runner: ConnectorRunner, -) -> ExecutionResult: - logging.info(f"Running spec for control connector {spec_control_execution_inputs.connector_under_test.name}") - execution_result = await spec_control_connector_runner.run() - request.config.stash[stash_keys.REPORT].add_control_execution_result(execution_result) - return execution_result - - -@pytest.fixture(scope="session") -def spec_target_execution_inputs( - target_connector: ConnectorUnderTest, - actor_id: str, + command: Command, + connection_objects: ConnectionObjects, + connector: ConnectorUnderTest, test_artifacts_directory: Path, duckdb_path: Path, -) -> ExecutionInputs: - return ExecutionInputs( - connector_under_test=target_connector, - actor_id=actor_id, - global_output_dir=test_artifacts_directory, - command=Command.SPEC, - duckdb_path=duckdb_path, - ) - - -@pytest.fixture(scope="session") -def spec_target_connector_runner( - request: SubRequest, - dagger_client: dagger.Client, - spec_target_execution_inputs: ExecutionInputs, -) -> ConnectorRunner: - runner = ConnectorRunner( - dagger_client, - spec_target_execution_inputs, - request.config.stash[stash_keys.RUN_IN_AIRBYTE_CI], - ) - return runner - - -@pytest.fixture(scope="session") -async def spec_target_execution_result( - request: SubRequest, - spec_target_execution_inputs: ExecutionInputs, - spec_target_connector_runner: ConnectorRunner, -) -> ExecutionResult: - logging.info(f"Running spec for target connector {spec_target_execution_inputs.connector_under_test.name}") - execution_result = await spec_target_connector_runner.run() - - request.config.stash[stash_keys.REPORT].add_target_execution_result(execution_result) - - return execution_result - - -@pytest.fixture(scope="session") -def check_control_execution_inputs( - control_connector: ConnectorUnderTest, - actor_id: str, - connector_config: SecretDict, - test_artifacts_directory: Path, - duckdb_path: Path, -) -> ExecutionInputs: - return ExecutionInputs( - connector_under_test=control_connector, - actor_id=actor_id, - global_output_dir=test_artifacts_directory, - command=Command.CHECK, - config=connector_config, - duckdb_path=duckdb_path, - ) - - -@pytest.fixture(scope="session") -async def check_control_connector_runner( - request: SubRequest, - dagger_client: dagger.Client, - check_control_execution_inputs: ExecutionInputs, - connection_id: str, -) -> AsyncGenerator: - proxy = Proxy(dagger_client, "proxy_server_check_control", connection_id) - - runner = ConnectorRunner( - dagger_client, - check_control_execution_inputs, - request.config.stash[stash_keys.RUN_IN_AIRBYTE_CI], - http_proxy=proxy, - ) - yield runner - await proxy.clear_cache_volume() - - -@pytest.fixture(scope="session") -async def check_control_execution_result( - request: SubRequest, - check_control_execution_inputs: ExecutionInputs, - check_control_connector_runner: ConnectorRunner, + runs_in_ci, ) -> ExecutionResult: - logging.info(f"Running check for control connector {check_control_execution_inputs.connector_under_test.name}") - execution_result = await check_control_connector_runner.run() - - request.config.stash[stash_keys.REPORT].add_control_execution_result(execution_result) - - return execution_result - - -@pytest.fixture(scope="session") -def check_target_execution_inputs( - target_connector: ConnectorUnderTest, - actor_id: str, - connector_config: SecretDict, - test_artifacts_directory: Path, - duckdb_path: Path, -) -> ExecutionInputs: - return ExecutionInputs( - connector_under_test=target_connector, - actor_id=actor_id, - global_output_dir=test_artifacts_directory, - command=Command.CHECK, - config=connector_config, - duckdb_path=duckdb_path, - ) - - -@pytest.fixture(scope="session") -async def check_target_connector_runner( - request: SubRequest, - check_control_execution_result: ExecutionResult, - dagger_client: dagger.Client, - check_target_execution_inputs: ExecutionInputs, - connection_id: str, -) -> AsyncGenerator: - proxy = Proxy( - dagger_client, - "proxy_server_check_target", - connection_id, - stream_for_server_replay=check_control_execution_result.http_dump, - ) + """Run the given command for the given connector and connection objects.""" + execution_inputs = get_execution_inputs_for_command(command, connection_objects, connector, test_artifacts_directory, duckdb_path) + logging.info(f"Running {command} for {connector.target_or_control.value} connector {execution_inputs.connector_under_test.name}") + proxy_hostname = f"proxy_server_{command.value}_{execution_inputs.connector_under_test.version.replace('.', '_')}" + proxy = Proxy(dagger_client, proxy_hostname, connection_objects.connection_id) runner = ConnectorRunner( dagger_client, - check_target_execution_inputs, - request.config.stash[stash_keys.RUN_IN_AIRBYTE_CI], - http_proxy=proxy, - ) - yield runner - await proxy.clear_cache_volume() - - -@pytest.fixture(scope="session") -async def check_target_execution_result( - request: SubRequest, - test_artifacts_directory: Path, - check_target_execution_inputs: ExecutionInputs, - check_target_connector_runner: ConnectorRunner, -) -> ExecutionResult: - logging.info(f"Running check for target connector {check_target_execution_inputs.connector_under_test.name}") - execution_result = await check_target_connector_runner.run() - request.config.stash[stash_keys.REPORT].add_target_execution_result(execution_result) - - return execution_result - - -@pytest.fixture(scope="session") -def discover_control_execution_inputs( - control_connector: ConnectorUnderTest, - actor_id: str, - connector_config: SecretDict, - test_artifacts_directory: Path, - duckdb_path: Path, -) -> ExecutionInputs: - return ExecutionInputs( - connector_under_test=control_connector, - actor_id=actor_id, - global_output_dir=test_artifacts_directory, - command=Command.DISCOVER, - config=connector_config, - duckdb_path=duckdb_path, - ) - - -@pytest.fixture(scope="session") -async def discover_control_execution_result( - request: SubRequest, - discover_control_execution_inputs: ExecutionInputs, - discover_control_connector_runner: ConnectorRunner, -) -> ExecutionResult: - logging.info(f"Running discover for control connector {discover_control_execution_inputs.connector_under_test.name}") - execution_result = await discover_control_connector_runner.run() - request.config.stash[stash_keys.REPORT].add_control_execution_result(execution_result) - - return execution_result - - -@pytest.fixture(scope="session") -def discover_target_execution_inputs( - target_connector: ConnectorUnderTest, - actor_id: str, - connector_config: SecretDict, - test_artifacts_directory: Path, - duckdb_path: Path, -) -> ExecutionInputs: - return ExecutionInputs( - connector_under_test=target_connector, - actor_id=actor_id, - global_output_dir=test_artifacts_directory, - command=Command.DISCOVER, - config=connector_config, - duckdb_path=duckdb_path, - ) - - -@pytest.fixture(scope="session") -async def discover_control_connector_runner( - request: SubRequest, - dagger_client: dagger.Client, - discover_control_execution_inputs: ExecutionInputs, - connection_id: str, -) -> AsyncGenerator: - proxy = Proxy(dagger_client, "proxy_server_discover_control", connection_id) - - yield ConnectorRunner( - dagger_client, - discover_control_execution_inputs, - request.config.stash[stash_keys.RUN_IN_AIRBYTE_CI], + execution_inputs, + runs_in_ci, http_proxy=proxy, ) - await proxy.clear_cache_volume() + execution_result = await runner.run() + return execution_result, proxy -@pytest.fixture(scope="session") -async def discover_target_connector_runner( - request: SubRequest, +async def run_command_and_add_to_report( dagger_client: dagger.Client, - discover_control_execution_result: ExecutionResult, - discover_target_execution_inputs: ExecutionInputs, - connection_id: str, -) -> AsyncGenerator: - proxy = Proxy( - dagger_client, - "proxy_server_discover_target", - connection_id, - stream_for_server_replay=discover_control_execution_result.http_dump, - ) - - yield ConnectorRunner( - dagger_client, - discover_target_execution_inputs, - request.config.stash[stash_keys.RUN_IN_AIRBYTE_CI], - http_proxy=proxy, - ) - await proxy.clear_cache_volume() - - -@pytest.fixture(scope="session") -async def discover_target_execution_result( - request: SubRequest, - discover_target_execution_inputs: ExecutionInputs, - discover_target_connector_runner: ConnectorRunner, -) -> ExecutionResult: - logging.info(f"Running discover for target connector {discover_target_execution_inputs.connector_under_test.name}") - execution_result = await discover_target_connector_runner.run() - request.config.stash[stash_keys.REPORT].add_target_execution_result(execution_result) - - return execution_result - - -@pytest.fixture(scope="session") -def read_control_execution_inputs( - control_connector: ConnectorUnderTest, - actor_id: str, - connector_config: SecretDict, - configured_catalog: ConfiguredAirbyteCatalog, + command: Command, + connection_objects: ConnectionObjects, + connector: ConnectorUnderTest, test_artifacts_directory: Path, duckdb_path: Path, -) -> ExecutionInputs: - return ExecutionInputs( - connector_under_test=control_connector, - actor_id=actor_id, - global_output_dir=test_artifacts_directory, - command=Command.READ, - configured_catalog=configured_catalog, - config=connector_config, - duckdb_path=duckdb_path, - ) - - -@pytest.fixture(scope="session") -def read_target_execution_inputs( - target_connector: ConnectorUnderTest, - actor_id: str, - connector_config: SecretDict, - configured_catalog: ConfiguredAirbyteCatalog, - test_artifacts_directory: Path, - duckdb_path: Path, -) -> ExecutionInputs: - return ExecutionInputs( - connector_under_test=target_connector, - actor_id=actor_id, - global_output_dir=test_artifacts_directory, - command=Command.READ, - configured_catalog=configured_catalog, - config=connector_config, - duckdb_path=duckdb_path, - ) - - -@pytest.fixture(scope="session") -async def read_control_connector_runner( - request: SubRequest, - dagger_client: dagger.Client, - read_control_execution_inputs: ExecutionInputs, - connection_id: str, -) -> AsyncGenerator: - proxy = Proxy(dagger_client, "proxy_server_read_control", connection_id) - - yield ConnectorRunner( - dagger_client, - read_control_execution_inputs, - request.config.stash[stash_keys.RUN_IN_AIRBYTE_CI], - http_proxy=proxy, - ) - await proxy.clear_cache_volume() - - -@pytest.fixture(scope="session") -async def read_control_execution_result( - request: SubRequest, - read_control_execution_inputs: ExecutionInputs, - read_control_connector_runner: ConnectorRunner, + runs_in_ci, + test_report: TestReport, + private_details_report: PrivateDetailsReport, ) -> ExecutionResult: - logging.info(f"Running read for control connector {read_control_execution_inputs.connector_under_test.name}") - execution_result = await read_control_connector_runner.run() - - request.config.stash[stash_keys.REPORT].add_control_execution_result(execution_result) - - return execution_result - - -@pytest.fixture(scope="session") -async def read_target_connector_runner( - request: SubRequest, - dagger_client: dagger.Client, - read_target_execution_inputs: ExecutionInputs, - read_control_execution_result: ExecutionResult, - connection_id: str, -) -> AsyncGenerator: - proxy = Proxy( + """Run the given command for the given connector and connection objects and add the results to the test report.""" + execution_result, proxy = await run_command( dagger_client, - "proxy_server_read_target", - connection_id, - stream_for_server_replay=read_control_execution_result.http_dump, - ) - - yield ConnectorRunner( - dagger_client, - read_target_execution_inputs, - request.config.stash[stash_keys.RUN_IN_AIRBYTE_CI], - http_proxy=proxy, - ) - await proxy.clear_cache_volume() - - -@pytest.fixture(scope="session") -async def read_target_execution_result( - request: SubRequest, - record_testsuite_property: Callable, - read_target_execution_inputs: ExecutionInputs, - read_target_connector_runner: ConnectorRunner, -) -> ExecutionResult: - logging.info(f"Running read for target connector {read_target_execution_inputs.connector_under_test.name}") - execution_result = await read_target_connector_runner.run() - - request.config.stash[stash_keys.REPORT].add_target_execution_result(execution_result) - return execution_result - + command, + connection_objects, + connector, + test_artifacts_directory, + duckdb_path, + runs_in_ci, + ) + if connector.target_or_control is TargetOrControl.CONTROL: + test_report.add_control_execution_result(execution_result) + private_details_report.add_control_execution_result(execution_result) + if connector.target_or_control is TargetOrControl.TARGET: + test_report.add_target_execution_result(execution_result) + private_details_report.add_target_execution_result(execution_result) + return execution_result, proxy + + +def generate_execution_results_fixture(command: Command, control_or_target: str) -> Callable: + """Dynamically generate the fixture for the given command and control/target. + This is mainly to avoid code duplication and to make the code more maintainable. + Declaring this explicitly for each command and control/target combination would be cumbersome. + """ -@pytest.fixture(scope="session") -def read_with_state_control_execution_inputs( - control_connector: ConnectorUnderTest, - actor_id: str, - connector_config: SecretDict, - configured_catalog: ConfiguredAirbyteCatalog, - state: dict, - test_artifacts_directory: Path, - duckdb_path: Path, -) -> ExecutionInputs: - if not state: - pytest.skip("The state is not provided. Skipping the test as it's not possible to run a read with state.") - return ExecutionInputs( - connector_under_test=control_connector, - actor_id=actor_id, - global_output_dir=test_artifacts_directory, - command=Command.READ_WITH_STATE, - configured_catalog=configured_catalog, - config=connector_config, - state=state, - duckdb_path=duckdb_path, - ) + if control_or_target not in ["control", "target"]: + raise ValueError("control_or_target should be either 'control' or 'target'") + if command not in [Command.SPEC, Command.CHECK, Command.DISCOVER, Command.READ, Command.READ_WITH_STATE]: + raise ValueError("command should be either 'spec', 'check', 'discover', 'read' or 'read_with_state'") + + if control_or_target == "control": + + @pytest.fixture(scope="session") + async def generated_fixture( + request: SubRequest, dagger_client: dagger.Client, control_connector: ConnectorUnderTest, test_artifacts_directory: Path + ) -> ExecutionResult: + connection_objects = request.param + + execution_results, proxy = await run_command_and_add_to_report( + dagger_client, + command, + connection_objects, + control_connector, + test_artifacts_directory, + request.config.stash[stash_keys.DUCKDB_PATH], + request.config.stash[stash_keys.RUN_IN_AIRBYTE_CI], + request.config.stash[stash_keys.TEST_REPORT], + request.config.stash[stash_keys.PRIVATE_DETAILS_REPORT], + ) + yield execution_results + await proxy.clear_cache_volume() -@pytest.fixture(scope="session") -def read_with_state_target_execution_inputs( - target_connector: ConnectorUnderTest, - actor_id: str, - connector_config: SecretDict, - configured_catalog: ConfiguredAirbyteCatalog, - state: dict, - test_artifacts_directory: Path, - duckdb_path: Path, -) -> ExecutionInputs: - if not state: - pytest.skip("The state is not provided. Skipping the test as it's not possible to run a read with state.") - return ExecutionInputs( - connector_under_test=target_connector, - actor_id=actor_id, - global_output_dir=test_artifacts_directory, - command=Command.READ_WITH_STATE, - configured_catalog=configured_catalog, - config=connector_config, - state=state, - duckdb_path=duckdb_path, - ) + else: + @pytest.fixture(scope="session") + async def generated_fixture( + request: SubRequest, dagger_client: dagger.Client, target_connector: ConnectorUnderTest, test_artifacts_directory: Path + ) -> ExecutionResult: + connection_objects = request.param + + execution_results, proxy = await run_command_and_add_to_report( + dagger_client, + command, + connection_objects, + target_connector, + test_artifacts_directory, + request.config.stash[stash_keys.DUCKDB_PATH], + request.config.stash[stash_keys.RUN_IN_AIRBYTE_CI], + request.config.stash[stash_keys.TEST_REPORT], + request.config.stash[stash_keys.PRIVATE_DETAILS_REPORT], + ) -@pytest.fixture(scope="session") -async def read_with_state_control_connector_runner( - request: SubRequest, - dagger_client: dagger.Client, - read_with_state_control_execution_inputs: ExecutionInputs, - connection_id: str, -) -> AsyncGenerator: - proxy = Proxy(dagger_client, "proxy_server_read_with_state_control", connection_id) + yield execution_results + await proxy.clear_cache_volume() - yield ConnectorRunner( - dagger_client, - read_with_state_control_execution_inputs, - request.config.stash[stash_keys.RUN_IN_AIRBYTE_CI], - http_proxy=proxy, - ) - await proxy.clear_cache_volume() + return generated_fixture -@pytest.fixture(scope="session") -async def read_with_state_control_execution_result( - request: SubRequest, - read_with_state_control_execution_inputs: ExecutionInputs, - read_with_state_control_connector_runner: ConnectorRunner, -) -> ExecutionResult: - if read_with_state_control_execution_inputs.state is None: - pytest.skip("The control state is not provided. Skipping the test as it's not possible to run a read with state.") +def inject_fixtures() -> set[str]: + """Dynamically generate th execution result fixtures for all the combinations of commands and control/target. + The fixtures will be named as __execution_result + Add the generated fixtures to the global namespace. + """ + execution_result_fixture_names = [] + for command, control_or_target in product([command for command in Command], ["control", "target"]): + fixture_name = f"{command.name.lower()}_{control_or_target}_execution_result" + globals()[fixture_name] = generate_execution_results_fixture(command, control_or_target) + execution_result_fixture_names.append(fixture_name) + return set(execution_result_fixture_names) - logging.info(f"Running read with state for control connector {read_with_state_control_execution_inputs.connector_under_test.name}") - execution_result = await read_with_state_control_connector_runner.run() - request.config.stash[stash_keys.REPORT].add_control_execution_result(execution_result) - return execution_result +EXECUTION_RESULT_FIXTURES = inject_fixtures() -@pytest.fixture(scope="session") -async def read_with_state_target_connector_runner( - request: SubRequest, - dagger_client: dagger.Client, - read_with_state_target_execution_inputs: ExecutionInputs, - read_with_state_control_execution_result: ExecutionResult, - connection_id: str, -) -> AsyncGenerator: - proxy = Proxy( - dagger_client, - "proxy_server_read_with_state_target", - connection_id, - stream_for_server_replay=read_with_state_control_execution_result.http_dump, - ) - yield ConnectorRunner( - dagger_client, - read_with_state_target_execution_inputs, - request.config.stash[stash_keys.RUN_IN_AIRBYTE_CI], - http_proxy=proxy, +def pytest_generate_tests(metafunc): + """This function is called for each test function. + It helps in parameterizing the test functions with the connection objects. + It will provide the connection objects to the "*_execution_result" fixtures as parameters. + This will make sure that the tests are run for all the connection objects available in the configuration. + """ + all_connection_objects = metafunc.config.stash[stash_keys.ALL_CONNECTION_OBJECTS] + requested_fixtures = [fixture_name for fixture_name in metafunc.fixturenames if fixture_name in EXECUTION_RESULT_FIXTURES] + assert isinstance(all_connection_objects, list), "all_connection_objects should be a list" + + if not requested_fixtures: + return + metafunc.parametrize( + requested_fixtures, + [[c] * len(requested_fixtures) for c in all_connection_objects], + indirect=requested_fixtures, + ids=[f"CONNECTION {hashlib.sha256(c.connection_id.encode()).hexdigest()[:7]}" for c in all_connection_objects], ) - await proxy.clear_cache_volume() - - -@pytest.fixture(scope="session") -async def read_with_state_target_execution_result( - request: SubRequest, - read_with_state_target_execution_inputs: ExecutionInputs, - read_with_state_target_connector_runner: ConnectorRunner, -) -> ExecutionResult: - if read_with_state_target_execution_inputs.state is None: - pytest.skip("The target state is not provided. Skipping the test as it's not possible to run a read with state.") - logging.info(f"Running read with state for target connector {read_with_state_target_execution_inputs.connector_under_test.name}") - execution_result = await read_with_state_target_connector_runner.run() - request.config.stash[stash_keys.REPORT].add_target_execution_result(execution_result) - - return execution_result diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/regression_tests/test_check.py b/airbyte-ci/connectors/live-tests/src/live_tests/regression_tests/test_check.py index 443ab2f1ac4d..7467fed152b7 100644 --- a/airbyte-ci/connectors/live-tests/src/live_tests/regression_tests/test_check.py +++ b/airbyte-ci/connectors/live-tests/src/live_tests/regression_tests/test_check.py @@ -5,6 +5,7 @@ import pytest from airbyte_protocol.models import Status, Type # type: ignore + from live_tests.commons.models import ExecutionResult from live_tests.consts import MAX_LINES_IN_REPORT from live_tests.utils import fail_test_on_failing_execution_results, is_successful_check, tail_file diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/regression_tests/test_discover.py b/airbyte-ci/connectors/live-tests/src/live_tests/regression_tests/test_discover.py index 61fac4147986..56f955383dbf 100644 --- a/airbyte-ci/connectors/live-tests/src/live_tests/regression_tests/test_discover.py +++ b/airbyte-ci/connectors/live-tests/src/live_tests/regression_tests/test_discover.py @@ -7,6 +7,7 @@ import pytest from _pytest.fixtures import SubRequest from airbyte_protocol.models import AirbyteCatalog, AirbyteStream, Type # type: ignore + from live_tests.commons.models import ExecutionResult from live_tests.utils import fail_test_on_failing_execution_results, get_and_write_diff, get_catalog diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/regression_tests/test_read.py b/airbyte-ci/connectors/live-tests/src/live_tests/regression_tests/test_read.py index 4530d7008660..c55dae963289 100644 --- a/airbyte-ci/connectors/live-tests/src/live_tests/regression_tests/test_read.py +++ b/airbyte-ci/connectors/live-tests/src/live_tests/regression_tests/test_read.py @@ -8,6 +8,7 @@ import pytest from airbyte_protocol.models import AirbyteMessage # type: ignore from deepdiff import DeepDiff # type: ignore + from live_tests.commons.models import ExecutionResult from live_tests.utils import fail_test_on_failing_execution_results, get_and_write_diff, get_test_logger, write_string_to_test_artifact @@ -37,8 +38,6 @@ async def _check_all_pks_are_produced_in_target_version( self, request: SubRequest, record_property: Callable, - configured_streams: Iterable[str], - primary_keys_per_stream: dict[str, Optional[list[str]]], read_with_state_control_execution_result: ExecutionResult, read_with_state_target_execution_result: ExecutionResult, ) -> None: @@ -52,13 +51,13 @@ async def _check_all_pks_are_produced_in_target_version( read_with_state_control_execution_result (ExecutionResult): The control version execution result. read_with_state_target_execution_result (ExecutionResult): The target version execution result. """ - if not primary_keys_per_stream: + if not read_with_state_control_execution_result.primary_keys_per_stream: pytest.skip("No primary keys provided on any stream. Skipping the test.") logger = get_test_logger(request) streams_with_missing_records = set() - for stream_name in configured_streams: - _primary_key = primary_keys_per_stream[stream_name] + for stream_name in read_with_state_control_execution_result.configured_streams: + _primary_key = read_with_state_control_execution_result.primary_keys_per_stream[stream_name] if not _primary_key: # TODO: report skipped PK test per individual stream logger.warning(f"No primary keys provided on stream {stream_name}.") @@ -101,12 +100,11 @@ async def _check_all_pks_are_produced_in_target_version( async def _check_record_counts( self, record_property: Callable, - configured_streams: Iterable[str], read_control_execution_result: ExecutionResult, read_target_execution_result: ExecutionResult, ) -> None: record_count_difference_per_stream: dict[str, dict[str, int]] = {} - for stream_name in configured_streams: + for stream_name in read_control_execution_result.configured_streams: control_records_count = sum(1 for _ in read_control_execution_result.get_records_per_stream(stream_name)) target_records_count = sum(1 for _ in read_target_execution_result.get_records_per_stream(stream_name)) @@ -136,8 +134,6 @@ async def _check_all_records_are_the_same( self, request: SubRequest, record_property: Callable, - configured_streams: Iterable[str], - primary_keys_per_stream: dict[str, Optional[list[str]]], read_control_execution_result: ExecutionResult, read_target_execution_result: ExecutionResult, ) -> None: @@ -151,14 +147,14 @@ async def _check_all_records_are_the_same( read_target_execution_result (ExecutionResult): The target version execution result. """ streams_with_diff = set() - for stream in configured_streams: + for stream in read_control_execution_result.configured_streams: control_records = list(read_control_execution_result.get_records_per_stream(stream)) target_records = list(read_target_execution_result.get_records_per_stream(stream)) if control_records and not target_records: pytest.fail(f"Stream {stream} is missing in the target version.") - if primary_key := primary_keys_per_stream.get(stream): + if primary_key := read_control_execution_result.primary_keys_per_stream.get(stream): diffs = self._get_diff_on_stream_with_pk( request, record_property, @@ -241,7 +237,6 @@ def _check_record_schema_match( async def test_record_count_with_state( self, record_property: Callable, - configured_streams: Iterable[str], read_with_state_control_execution_result: ExecutionResult, read_with_state_target_execution_result: ExecutionResult, ) -> None: @@ -263,7 +258,6 @@ async def test_record_count_with_state( ) await self._check_record_counts( record_property, - configured_streams, read_with_state_control_execution_result, read_with_state_target_execution_result, ) @@ -272,7 +266,6 @@ async def test_record_count_with_state( async def test_record_count_without_state( self, record_property: Callable, - configured_streams: Iterable[str], read_control_execution_result: ExecutionResult, read_target_execution_result: ExecutionResult, ) -> None: @@ -294,7 +287,6 @@ async def test_record_count_without_state( ) await self._check_record_counts( record_property, - configured_streams, read_control_execution_result, read_target_execution_result, ) @@ -304,8 +296,6 @@ async def test_all_pks_are_produced_in_target_version_with_state( self, request: SubRequest, record_property: Callable, - configured_streams: Iterable[str], - primary_keys_per_stream: dict[str, Optional[list[str]]], read_with_state_control_execution_result: ExecutionResult, read_with_state_target_execution_result: ExecutionResult, ) -> None: @@ -323,8 +313,6 @@ async def test_all_pks_are_produced_in_target_version_with_state( await self._check_all_pks_are_produced_in_target_version( request, record_property, - configured_streams, - primary_keys_per_stream, read_with_state_control_execution_result, read_with_state_target_execution_result, ) @@ -334,8 +322,6 @@ async def test_all_pks_are_produced_in_target_version_without_state( self, request: SubRequest, record_property: Callable, - configured_streams: Iterable[str], - primary_keys_per_stream: dict[str, Optional[list[str]]], read_control_execution_result: ExecutionResult, read_target_execution_result: ExecutionResult, ) -> None: @@ -353,8 +339,6 @@ async def test_all_pks_are_produced_in_target_version_without_state( await self._check_all_pks_are_produced_in_target_version( request, record_property, - configured_streams, - primary_keys_per_stream, read_control_execution_result, read_target_execution_result, ) @@ -405,8 +389,6 @@ async def test_all_records_are_the_same_with_state( self, request: SubRequest, record_property: Callable, - configured_streams: Iterable[str], - primary_keys_per_stream: dict[str, Optional[list[str]]], read_with_state_control_execution_result: ExecutionResult, read_with_state_target_execution_result: ExecutionResult, ) -> None: @@ -425,8 +407,6 @@ async def test_all_records_are_the_same_with_state( await self._check_all_records_are_the_same( request, record_property, - configured_streams, - primary_keys_per_stream, read_with_state_control_execution_result, read_with_state_target_execution_result, ) @@ -437,8 +417,6 @@ async def test_all_records_are_the_same_without_state( self, request: SubRequest, record_property: Callable, - configured_streams: Iterable[str], - primary_keys_per_stream: dict[str, Optional[list[str]]], read_control_execution_result: ExecutionResult, read_target_execution_result: ExecutionResult, ) -> None: @@ -457,8 +435,6 @@ async def test_all_records_are_the_same_without_state( await self._check_all_records_are_the_same( request, record_property, - configured_streams, - primary_keys_per_stream, read_control_execution_result, read_target_execution_result, ) diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/regression_tests/test_spec.py b/airbyte-ci/connectors/live-tests/src/live_tests/regression_tests/test_spec.py index 967698f7462a..7a1985fd3e40 100644 --- a/airbyte-ci/connectors/live-tests/src/live_tests/regression_tests/test_spec.py +++ b/airbyte-ci/connectors/live-tests/src/live_tests/regression_tests/test_spec.py @@ -5,6 +5,7 @@ import pytest from airbyte_protocol.models import Type # type: ignore + from live_tests.commons.models import ExecutionResult from live_tests.utils import fail_test_on_failing_execution_results diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/report.py b/airbyte-ci/connectors/live-tests/src/live_tests/report.py index bc4d6e31f25e..78bb06720c72 100644 --- a/airbyte-ci/connectors/live-tests/src/live_tests/report.py +++ b/airbyte-ci/connectors/live-tests/src/live_tests/report.py @@ -3,6 +3,7 @@ import datetime import json +from abc import ABC, abstractmethod from collections import defaultdict from collections.abc import Iterable, MutableMapping from copy import deepcopy @@ -14,14 +15,19 @@ import requests import yaml from jinja2 import Environment, PackageLoader, select_autoescape + from live_tests import stash_keys +from live_tests.commons.models import Command, ConnectionObjects from live_tests.consts import MAX_LINES_IN_REPORT if TYPE_CHECKING: + from typing import List + import pytest from _pytest.config import Config - from airbyte_protocol.models import SyncMode, Type # type: ignore - from live_tests.commons.models import Command, ExecutionResult + from airbyte_protocol.models import AirbyteStream, ConfiguredAirbyteStream, SyncMode, Type # type: ignore + + from live_tests.commons.models import ExecutionResult class ReportState(Enum): @@ -30,41 +36,140 @@ class ReportState(Enum): FINISHED = "finished" -class Report: - TEMPLATE_NAME = "report.html.j2" - - SPEC_SECRET_MASK_URL = "https://connectors.airbyte.com/files/registries/v0/specs_secrets_mask.yaml" +class BaseReport(ABC): + TEMPLATE_NAME: str def __init__(self, path: Path, pytest_config: Config) -> None: self.path = path self.pytest_config = pytest_config - self.connection_objects = pytest_config.stash[stash_keys.CONNECTION_OBJECTS] - self.secret_properties = self.get_secret_properties() self.created_at = datetime.datetime.utcnow() self.updated_at = self.created_at - self.control_execution_results_per_command: dict[Command, ExecutionResult] = {} - self.target_execution_results_per_command: dict[Command, ExecutionResult] = {} - self.test_results: list[dict[str, Any]] = [] + + self.control_execution_results_per_command: dict[Command, List[ExecutionResult]] = {command: [] for command in Command} + self.target_execution_results_per_command: dict[Command, List[ExecutionResult]] = {command: [] for command in Command} self.update(ReportState.INITIALIZING) - def get_secret_properties(self) -> list: - response = requests.get(self.SPEC_SECRET_MASK_URL) - response.raise_for_status() - return yaml.safe_load(response.text)["properties"] + @abstractmethod + def render(self) -> None: + pass - def update(self, state: ReportState = ReportState.RUNNING) -> None: - self._state = state - self.updated_at = datetime.datetime.utcnow() - self.render() + @property + def all_connection_objects(self) -> List[ConnectionObjects]: + return self.pytest_config.stash[stash_keys.ALL_CONNECTION_OBJECTS] def add_control_execution_result(self, control_execution_result: ExecutionResult) -> None: - self.control_execution_results_per_command[control_execution_result.command] = control_execution_result + self.control_execution_results_per_command[control_execution_result.command].append(control_execution_result) self.update() def add_target_execution_result(self, target_execution_result: ExecutionResult) -> None: - self.target_execution_results_per_command[target_execution_result.command] = target_execution_result + self.target_execution_results_per_command[target_execution_result.command].append(target_execution_result) self.update() + def update(self, state: ReportState = ReportState.RUNNING) -> None: + self._state = state + self.updated_at = datetime.datetime.utcnow() + self.render() + + +class PrivateDetailsReport(BaseReport): + TEMPLATE_NAME = "private_details.html.j2" + SPEC_SECRET_MASK_URL = "https://connectors.airbyte.com/files/registries/v0/specs_secrets_mask.yaml" + + def __init__(self, path: Path, pytest_config: Config) -> None: + self.secret_properties = self.get_secret_properties() + super().__init__(path, pytest_config) + + def get_secret_properties(self) -> list: + response = requests.get(self.SPEC_SECRET_MASK_URL) + response.raise_for_status() + return yaml.safe_load(response.text)["properties"] + + def scrub_secrets_from_config(self, to_scrub: MutableMapping) -> MutableMapping: + if isinstance(to_scrub, dict): + for key, value in to_scrub.items(): + if key in self.secret_properties: + to_scrub[key] = "********" + elif isinstance(value, dict): + to_scrub[key] = self.scrub_secrets_from_config(value) + return to_scrub + + @property + def renderable_connection_objects(self) -> list[dict[str, Any]]: + return [ + { + "workspace_id": connection_objects.workspace_id, + "connection_id": connection_objects.connection_id, + "hashed_connection_id": connection_objects.hashed_connection_id, + "source_config": json.dumps( + self.scrub_secrets_from_config( + deepcopy(connection_objects.source_config.data) if connection_objects.source_config else {} + ), + indent=2, + ), + "url": connection_objects.url, + } + for connection_objects in self.all_connection_objects + ] + + def render(self) -> None: + jinja_env = Environment( + loader=PackageLoader(__package__, "templates"), + autoescape=select_autoescape(), + trim_blocks=False, + lstrip_blocks=True, + ) + template = jinja_env.get_template(self.TEMPLATE_NAME) + rendered = template.render( + user=self.pytest_config.stash[stash_keys.USER], + test_date=self.created_at, + all_connection_objects=self.renderable_connection_objects, + connector_image=self.pytest_config.stash[stash_keys.CONNECTOR_IMAGE], + control_version=self.pytest_config.stash[stash_keys.CONTROL_VERSION], + target_version=self.pytest_config.stash[stash_keys.TARGET_VERSION], + requested_urls_per_command=self.get_requested_urls_per_command(), + fully_generated=self._state is ReportState.FINISHED, + ) + self.path.write_text(rendered) + + def get_requested_urls_per_command( + self, + ) -> dict[Command, list[tuple[int, str, str]]]: + requested_urls_per_command = {} + all_commands = sorted( + list(set(self.control_execution_results_per_command.keys()).union(set(self.target_execution_results_per_command.keys()))), + key=lambda command: command.value, + ) + for command in all_commands: + if command in self.control_execution_results_per_command: + control_flows = [ + flow for exec_result in self.control_execution_results_per_command[command] for flow in exec_result.http_flows + ] + else: + control_flows = [] + if command in self.target_execution_results_per_command: + target_flows = [ + flow for exec_result in self.target_execution_results_per_command[command] for flow in exec_result.http_flows + ] + else: + target_flows = [] + all_flows = [] + max_flows = max(len(control_flows), len(target_flows)) + for i in range(max_flows): + control_url = control_flows[i].request.url if i < len(control_flows) else "" + target_url = target_flows[i].request.url if i < len(target_flows) else "" + all_flows.append((i, control_url, target_url)) + requested_urls_per_command[command] = all_flows + return requested_urls_per_command + + +class TestReport(BaseReport): + TEMPLATE_NAME = "report.html.j2" + + def __init__(self, path: Path, pytest_config: Config, private_details_url: Optional[str] = None) -> None: + self.private_details_url = private_details_url + self.test_results: list[dict[str, Any]] = [] + super().__init__(path, pytest_config) + def add_test_result(self, test_report: pytest.TestReport, test_documentation: Optional[str] = None) -> None: cut_properties: list[tuple[str, str]] = [] for property_name, property_value in test_report.user_properties: @@ -98,82 +203,67 @@ def render(self) -> None: fully_generated=self._state is ReportState.FINISHED, user=self.pytest_config.stash[stash_keys.USER], test_date=self.updated_at, - connection_url=self.pytest_config.stash[stash_keys.CONNECTION_URL], - workspace_id=self.pytest_config.stash[stash_keys.CONNECTION_OBJECTS].workspace_id, - connection_id=self.pytest_config.stash[stash_keys.CONNECTION_ID], connector_image=self.pytest_config.stash[stash_keys.CONNECTOR_IMAGE], control_version=self.pytest_config.stash[stash_keys.CONTROL_VERSION], target_version=self.pytest_config.stash[stash_keys.TARGET_VERSION], - source_config=json.dumps( - self.scrub_secrets_from_config( - deepcopy(self.connection_objects.source_config.data) if self.connection_objects.source_config else {} - ), - indent=2, - ), - state=json.dumps( - self.connection_objects.state if self.connection_objects.state else {}, - indent=2, - ), - configured_catalog=self.connection_objects.configured_catalog.json(indent=2) - if self.connection_objects.configured_catalog - else {}, - catalog=self.connection_objects.catalog.json(indent=2) if self.connection_objects.catalog else {}, + all_connection_objects=self.renderable_connection_objects, message_count_per_type=self.get_message_count_per_type(), stream_coverage_metrics=self.get_stream_coverage_metrics(), untested_streams=self.get_untested_streams(), - selected_streams=self.get_selected_streams(), + selected_streams=self.get_configured_streams(), sync_mode_coverage=self.get_sync_mode_coverage(), - requested_urls_per_command=self.get_requested_urls_per_command(), http_metrics_per_command=self.get_http_metrics_per_command(), record_count_per_command_and_stream=self.get_record_count_per_stream(), test_results=self.test_results, max_lines=MAX_LINES_IN_REPORT, + private_details_url=self.private_details_url, ) self.path.write_text(rendered) - def scrub_secrets_from_config(self, to_scrub: MutableMapping) -> MutableMapping: - if isinstance(to_scrub, dict): - for key, value in to_scrub.items(): - if key in self.secret_properties: - to_scrub[key] = "********" - elif isinstance(value, dict): - to_scrub[key] = self.scrub_secrets_from_config(value) - return to_scrub + @property + def renderable_connection_objects(self) -> list[dict[str, Any]]: + return [ + { + "hashed_connection_id": connection_objects.hashed_connection_id, + "catalog": connection_objects.catalog.json(indent=2) if connection_objects.catalog else {}, + "configured_catalog": connection_objects.configured_catalog.json(indent=2), + "state": json.dumps(connection_objects.state if connection_objects.state else {}, indent=2), + } + for connection_objects in self.all_connection_objects + ] - ### REPORT CONTENT HELPERS ### def get_stream_coverage_metrics(self) -> dict[str, str]: - configured_catalog_stream_count = ( - len(self.connection_objects.configured_catalog.streams) if self.connection_objects.configured_catalog else 0 - ) - catalog_stream_count = len(self.connection_objects.catalog.streams) if self.connection_objects.catalog else 0 + configured_catalog_stream_count = len(self.get_configured_streams()) + catalog_stream_count = len(self.all_streams) + coverage = configured_catalog_stream_count / catalog_stream_count if catalog_stream_count > 0 else 0 return { "Available in catalog": str(catalog_stream_count), "In use (in configured catalog)": str(configured_catalog_stream_count), - "Coverage": f"{(configured_catalog_stream_count / catalog_stream_count) * 100:.2f}%", + "Coverage": f"{coverage * 100:.2f}%", } def get_record_count_per_stream( self, ) -> dict[Command, dict[str, dict[str, int] | int]]: record_count_per_command_and_stream: dict[Command, dict[str, dict[str, int] | int]] = {} - - for control_result, target_result in zip( + for control_results, target_results in zip( self.control_execution_results_per_command.values(), self.target_execution_results_per_command.values(), strict=False, ): per_stream_count = defaultdict(lambda: {"control": 0, "target": 0}) # type: ignore - for result, source in [ - (control_result, "control"), - (target_result, "target"), + for results, source in [ + (control_results, "control"), + (target_results, "target"), ]: - stream_schemas: Iterable = result.stream_schemas or [] + stream_schemas: Iterable = [stream_schema for result in results for stream_schema in result.stream_schemas] for stream in stream_schemas: - per_stream_count[stream][source] = self._get_record_count_for_stream(result, stream) + per_stream_count[stream][source] = sum([self._get_record_count_for_stream(result, stream) for result in results]) for stream in per_stream_count: per_stream_count[stream]["difference"] = per_stream_count[stream]["target"] - per_stream_count[stream]["control"] - record_count_per_command_and_stream[control_result.command] = per_stream_count # type: ignore + if control_results: + record_count_per_command_and_stream[control_results[0].command] = per_stream_count # type: ignore return record_count_per_command_and_stream @@ -186,11 +276,28 @@ def get_untested_streams(self) -> list[str]: for stream_count in self.get_record_count_per_stream().values(): streams_with_data.update(stream_count.keys()) - catalog_streams = self.connection_objects.catalog.streams if self.connection_objects.catalog else [] - - return [stream.name for stream in catalog_streams if stream.name not in streams_with_data] - - def get_selected_streams(self) -> dict[str, dict[str, SyncMode | bool]]: + return [stream.name for stream in self.all_streams if stream.name not in streams_with_data] + + @property + def all_streams(self) -> List[AirbyteStream]: + # A set would be better but AirbyteStream is not hashable + all_streams = dict() + for connection_objects in self.all_connection_objects: + if connection_objects.catalog: + for stream in connection_objects.catalog.streams: + all_streams[stream.name] = stream + return list(all_streams.values()) + + @property + def all_configured_streams(self) -> List[ConfiguredAirbyteStream]: + all_configured_streams = dict() + for connection_objects in self.all_connection_objects: + if connection_objects.configured_catalog: + for configured_airbyte_stream in connection_objects.configured_catalog.streams: + all_configured_streams[configured_airbyte_stream.stream.name] = configured_airbyte_stream + return list(all_configured_streams.values()) + + def get_configured_streams(self) -> dict[str, dict[str, SyncMode | bool]]: untested_streams = self.get_untested_streams() return ( { @@ -199,17 +306,17 @@ def get_selected_streams(self) -> dict[str, dict[str, SyncMode | bool]]: "has_data": configured_stream.stream.name not in untested_streams, } for configured_stream in sorted( - self.connection_objects.configured_catalog.streams, + self.all_configured_streams, key=lambda x: x.stream.name, ) } - if self.connection_objects.configured_catalog + if self.all_configured_streams else {} ) def get_sync_mode_coverage(self) -> dict[SyncMode, int]: count_per_sync_mode: dict[SyncMode, int] = defaultdict(int) - for s in self.get_selected_streams().values(): + for s in self.get_configured_streams().values(): count_per_sync_mode[s["sync_mode"]] += 1 return count_per_sync_mode @@ -224,10 +331,11 @@ def get_message_count_per_type( self.control_execution_results_per_command, self.target_execution_results_per_command, ]: - for command, execution_result in execution_results_per_command.items(): + for command, execution_results in execution_results_per_command.items(): all_commands.add(command) - for message_type in execution_result.get_message_count_per_type().keys(): - all_message_types.add(message_type) + for execution_result in execution_results: + for message_type in execution_result.get_message_count_per_type().keys(): + all_message_types.add(message_type) all_commands_sorted = sorted(all_commands, key=lambda command: command.value) all_message_types_sorted = sorted(all_message_types, key=lambda message_type: message_type.value) @@ -241,13 +349,16 @@ def get_message_count_per_type( "target": 0, } if command in self.control_execution_results_per_command: - message_count_per_type_and_command[message_type][command]["control"] = ( - self.control_execution_results_per_command[command].get_message_count_per_type().get(message_type, 0) - ) + for control_result in self.control_execution_results_per_command[command]: + message_count_per_type_and_command[message_type][command]["control"] += ( + control_result.get_message_count_per_type().get(message_type, 0) + ) if command in self.target_execution_results_per_command: - message_count_per_type_and_command[message_type][command]["target"] = ( - self.target_execution_results_per_command[command].get_message_count_per_type().get(message_type, 0) - ) + for target_result in self.target_execution_results_per_command[command]: + message_count_per_type_and_command[message_type][command]["target"] += ( + target_result.get_message_count_per_type().get(message_type, 0) + ) + message_count_per_type_and_command[message_type][command]["difference"] = ( message_count_per_type_and_command[message_type][command]["target"] - message_count_per_type_and_command[message_type][command]["control"] @@ -259,65 +370,42 @@ def get_http_metrics_per_command( ) -> dict[Command, dict[str, dict[str, int | str] | int]]: metrics_per_command: dict[Command, dict[str, dict[str, int | str] | int]] = {} - for control_result, target_result in zip( + for control_results, target_results in zip( self.control_execution_results_per_command.values(), self.target_execution_results_per_command.values(), strict=False, ): - control_flow_count = len(control_result.http_flows) - control_all_urls = [f.request.url for f in control_result.http_flows] + # TODO + # Duplicate flow counts may be wrong when we gather results from multiple connections + control_flow_count = sum([len(control_result.http_flows) for control_result in control_results]) + control_all_urls = [f.request.url for control_result in control_results for f in control_result.http_flows] control_duplicate_flow_count = len(control_all_urls) - len(set(control_all_urls)) - control_cache_hits_count = sum(1 for f in control_result.http_flows if f.is_replay) + control_cache_hits_count = sum(1 for control_result in control_results for f in control_result.http_flows if f.is_replay) control_cache_hit_ratio = f"{(control_cache_hits_count / control_flow_count) * 100:.2f}%" if control_flow_count != 0 else "N/A" - target_flow_count = len(target_result.http_flows) - target_all_urls = [f.request.url for f in target_result.http_flows] + target_flow_count = sum([len(target_result.http_flows) for target_result in target_results]) + target_all_urls = [f.request.url for target_result in target_results for f in target_result.http_flows] target_duplicate_flow_count = len(target_all_urls) - len(set(target_all_urls)) - target_cache_hits_count = sum(1 for f in target_result.http_flows if f.is_replay) + + target_cache_hits_count = sum(1 for target_result in target_results for f in target_result.http_flows if f.is_replay) target_cache_hit_ratio = f"{(target_cache_hits_count / target_flow_count) * 100:.2f}%" if target_flow_count != 0 else "N/A" flow_count_difference = target_flow_count - control_flow_count - - metrics_per_command[control_result.command] = { - "control": { - "flow_count": control_flow_count, - "duplicate_flow_count": control_duplicate_flow_count, - "cache_hits_count": control_cache_hits_count, - "cache_hit_ratio": control_cache_hit_ratio, - }, - "target": { - "flow_count": target_flow_count, - "duplicate_flow_count": target_duplicate_flow_count, - "cache_hits_count": target_cache_hits_count, - "cache_hit_ratio": target_cache_hit_ratio, - }, - "difference": flow_count_difference, - } + if control_results: + metrics_per_command[control_results[0].command] = { + "control": { + "flow_count": control_flow_count, + "duplicate_flow_count": control_duplicate_flow_count, + "cache_hits_count": control_cache_hits_count, + "cache_hit_ratio": control_cache_hit_ratio, + }, + "target": { + "flow_count": target_flow_count, + "duplicate_flow_count": target_duplicate_flow_count, + "cache_hits_count": target_cache_hits_count, + "cache_hit_ratio": target_cache_hit_ratio, + }, + "difference": flow_count_difference, + } return metrics_per_command - - def get_requested_urls_per_command( - self, - ) -> dict[Command, list[tuple[int, str, str]]]: - requested_urls_per_command = {} - all_commands = sorted( - list(set(self.control_execution_results_per_command.keys()).union(set(self.target_execution_results_per_command.keys()))), - key=lambda command: command.value, - ) - for command in all_commands: - if command in self.control_execution_results_per_command: - control_flows = self.control_execution_results_per_command[command].http_flows - else: - control_flows = [] - if command in self.target_execution_results_per_command: - target_flows = self.target_execution_results_per_command[command].http_flows - else: - target_flows = [] - all_flows = [] - max_flows = max(len(control_flows), len(target_flows)) - for i in range(max_flows): - control_url = control_flows[i].request.url if i < len(control_flows) else "" - target_url = target_flows[i].request.url if i < len(target_flows) else "" - all_flows.append((i, control_url, target_url)) - requested_urls_per_command[command] = all_flows - return requested_urls_per_command diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/stash_keys.py b/airbyte-ci/connectors/live-tests/src/live_tests/stash_keys.py index 493182e264d0..cb558164a67d 100644 --- a/airbyte-ci/connectors/live-tests/src/live_tests/stash_keys.py +++ b/airbyte-ci/connectors/live-tests/src/live_tests/stash_keys.py @@ -2,16 +2,17 @@ from __future__ import annotations from pathlib import Path +from typing import List import pytest + from live_tests.commons.evaluation_modes import TestEvaluationMode from live_tests.commons.models import ConnectionObjects, ConnectionSubset -from live_tests.report import Report +from live_tests.report import PrivateDetailsReport, TestReport AIRBYTE_API_KEY = pytest.StashKey[str]() AUTO_SELECT_CONNECTION = pytest.StashKey[bool]() -CONNECTION_ID = pytest.StashKey[str]() -CONNECTION_OBJECTS = pytest.StashKey[ConnectionObjects]() +ALL_CONNECTION_OBJECTS = pytest.StashKey[List[ConnectionObjects]]() CONNECTION_URL = pytest.StashKey[str | None]() CONNECTOR_IMAGE = pytest.StashKey[str]() CONTROL_VERSION = pytest.StashKey[str]() @@ -23,7 +24,8 @@ IS_PRODUCTION_CI = pytest.StashKey[bool]() # Running in airbyte-ci in GhA IS_PERMITTED_BOOL = pytest.StashKey[bool]() PR_URL = pytest.StashKey[str]() -REPORT = pytest.StashKey[Report]() +TEST_REPORT = pytest.StashKey[TestReport]() +PRIVATE_DETAILS_REPORT = pytest.StashKey[PrivateDetailsReport]() RETRIEVAL_REASONS = pytest.StashKey[str]() SELECTED_STREAMS = pytest.StashKey[set[str]]() SESSION_RUN_ID = pytest.StashKey[str]() @@ -33,3 +35,4 @@ USER = pytest.StashKey[str]() WORKSPACE_ID = pytest.StashKey[str]() TEST_EVALUATION_MODE = pytest.StashKey[TestEvaluationMode] +MAX_CONNECTIONS = pytest.StashKey[int | None]() diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/templates/private_details.html.j2 b/airbyte-ci/connectors/live-tests/src/live_tests/templates/private_details.html.j2 new file mode 100644 index 000000000000..2505bb3d3cea --- /dev/null +++ b/airbyte-ci/connectors/live-tests/src/live_tests/templates/private_details.html.j2 @@ -0,0 +1,305 @@ + + + + + + Test Report + + + + + + + +
+

Live test private details

+
+

Context

+
+
    +
  • Tester: {{ user }}
  • +
  • Test date: {{ test_date }}
  • +
  • Connector image: {{ connector_image }}
  • +
  • Control version: {{ control_version }}
  • +
  • Target version: {{ target_version }}
  • +
+
+
+
+

Connections used for testing

+ {% for connection_objects in all_connection_objects %} +
+

Details for {{ connection_objects['hashed_connection_id'] }}

+
    +
  • Connection in Airbyte Cloud
  • +
  • Workpace ID: {{ connection_objects['workspace_id'] }}
  • +
  • Connection ID: {{ connection_objects['connection_id']}}
  • +
+

Source configuration

+

The configuration object taken from the given connection that was passed to each version of the connector during the test.

+
{{ connection_objects['source_config'] }}
+
+ {% endfor %} +
+
+ {% if not fully_generated %} +

Requested URLs

+ {% else%} +

Requested URLs

+ {% endif %} +
+ {% for command, flows in requested_urls_per_command.items() %} +

{{ command.value.upper() }}

+ {% if flows %} +
+ + + + + + + + + + {% for index, control_url, target_url in flows %} + + + + + + {% endfor %} + +
Control URLTarget URL
{{ index }}{{ control_url }}{{ target_url }}
+
+ {% else %} +

No URLs requested

+ {% endif %} + {% endfor%} +
+
+
+ + diff --git a/airbyte-ci/connectors/live-tests/src/live_tests/templates/report.html.j2 b/airbyte-ci/connectors/live-tests/src/live_tests/templates/report.html.j2 index cffb9387d3e2..4ec1519a305a 100644 --- a/airbyte-ci/connectors/live-tests/src/live_tests/templates/report.html.j2 +++ b/airbyte-ci/connectors/live-tests/src/live_tests/templates/report.html.j2 @@ -20,7 +20,16 @@ console.log("Report is fully generated"); {% endif %} } - + function toggleContent(element) { + const contentDiv = element.querySelector('.section_content'); + if (contentDiv.style.display === "none") { + contentDiv.style.display = "block"; + element.classList.add('active'); + } else { + contentDiv.style.display = "none"; + element.classList.remove('active'); + } + } setInterval(refreshPage, 10000); + + + diff --git a/airbyte-integrations/connectors/source-agilecrm/manifest.yaml b/airbyte-integrations/connectors/source-agilecrm/manifest.yaml new file mode 100644 index 000000000000..b70ea704c1ca --- /dev/null +++ b/airbyte-integrations/connectors/source-agilecrm/manifest.yaml @@ -0,0 +1,2548 @@ +version: 6.4.0 + +type: DeclarativeSource + +check: + type: CheckStream + stream_names: + - contacts + +definitions: + streams: + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /dev/api/contacts + http_method: GET + request_headers: + Accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: page_size + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['cursor'] }}" + stop_condition: "{{ not last_record.get('cursor') }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + companies: + type: DeclarativeStream + name: companies + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /dev/api/contacts/companies/list + http_method: POST + request_headers: + Accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_data + field_name: cursor + page_size_option: + type: RequestOption + inject_into: body_data + field_name: page_size + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['cursor'] }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/companies" + deals: + type: DeclarativeStream + name: deals + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /dev/api/opportunity + http_method: GET + request_headers: + Accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['cursor'] }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/deals" + notes: + type: DeclarativeStream + name: notes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /dev/api/contacts/{{ stream_partition.contact_id }}/notes + http_method: GET + request_headers: + Accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: contact_id + stream: + $ref: "#/definitions/streams/contacts" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/notes" + tasks: + type: DeclarativeStream + name: tasks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /dev/api/tasks + http_method: GET + request_headers: + Accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tasks" + events: + type: DeclarativeStream + name: events + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /dev/api/events + http_method: GET + request_headers: + Accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/events" + milestone: + type: DeclarativeStream + name: milestone + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /dev/api/milestone/pipelines + http_method: GET + request_headers: + Accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/milestone" + campaigns: + type: DeclarativeStream + name: campaigns + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /dev/api/workflows + http_method: GET + request_headers: + Accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['cursor'] }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/campaigns" + documents: + type: DeclarativeStream + name: documents + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /dev/api/documents/contact/{{ stream_partition.contact_id }}/docs + http_method: GET + request_headers: + Accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: contact_id + stream: + $ref: "#/definitions/streams/contacts" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/documents" + ticket_filters: + type: DeclarativeStream + name: ticket_filters + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /dev/api/tickets/filters + http_method: GET + request_headers: + Accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/ticket_filters" + tickets: + type: DeclarativeStream + name: tickets + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /dev/api/tickets/filter + http_method: GET + request_parameters: + filter_id: "{{ stream_partition.filter_id }}" + request_headers: + Accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: filter_id + stream: + $ref: "#/definitions/streams/ticket_filters" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tickets" + base_requester: + type: HttpRequester + url_base: https://{{ config['domain'] }}.agilecrm.com + authenticator: + type: BasicHttpAuthenticator + password: "{{ config[\"api_key\"] }}" + username: "{{ config[\"email\"] }}" + +streams: + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/companies" + - $ref: "#/definitions/streams/deals" + - $ref: "#/definitions/streams/notes" + - $ref: "#/definitions/streams/tasks" + - $ref: "#/definitions/streams/events" + - $ref: "#/definitions/streams/milestone" + - $ref: "#/definitions/streams/campaigns" + - $ref: "#/definitions/streams/documents" + - $ref: "#/definitions/streams/ticket_filters" + - $ref: "#/definitions/streams/tickets" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - email + - domain + - api_key + properties: + email: + type: string + description: >- + Your Agile CRM account email address. This is used as the username for + authentication. + name: email + order: 0 + title: Email Address + domain: + type: string + description: The specific subdomain for your Agile CRM account + name: domain + order: 1 + title: Domain + api_key: + type: string + description: >- + API key to use. Find it at Admin Settings -> API & Analytics -> API + Key in your Agile CRM account. + name: api_key + order: 2 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + contacts: true + companies: true + deals: true + notes: true + tasks: true + events: true + milestone: true + campaigns: true + documents: true + ticket_filters: true + tickets: true + testedStreams: + contacts: + streamHash: 1b0201da1c78918956c2ce3d94852928c7dad00e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + companies: + streamHash: 44d430ecfefd3ca8505da802ceb5eda816037442 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + deals: + streamHash: 4b0106a1b6900cbb2d3d23691dbfd020c44fe780 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + notes: + streamHash: d9091a532e9546cefc842868f9c3f56b8c6709b2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tasks: + streamHash: 3541439e84df3b0c998ea7b29de33a05f755df08 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + events: + streamHash: 1bfa15882b66169b19a8e9865b24f0e53869a0f7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: false + primaryKeysArePresent: true + primaryKeysAreUnique: true + milestone: + hasRecords: true + streamHash: c1f2e139ffe24486a32b8d10f39602d8ace0e462 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + campaigns: + hasRecords: true + streamHash: 56c9e0ece277e19d7cc83c2038e6e5abd4da30e7 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + documents: + hasRecords: true + streamHash: 4e6e164f20733a5bc21033827c2292c6bb3c4432 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + ticket_filters: + hasRecords: true + streamHash: b3cf9d32eac1b5c12fcae54d00617c3b0f8bade9 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + tickets: + hasRecords: true + streamHash: 44bfa7a5e1c85017b13f4c02d535458b0760216d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://github.com/agilecrm/rest-api + +schemas: + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + browserId: + type: + - array + - "null" + campaignStatus: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + campaign_id: + type: + - string + - "null" + campaign_name: + type: + - string + - "null" + end_time: + type: + - number + - "null" + start_time: + type: + - number + - "null" + status: + type: + - string + - "null" + concurrent_save_allowed: + type: + - boolean + - "null" + contact_company_id: + type: + - string + - "null" + created_time: + type: + - number + - "null" + emailBounceStatus: + type: + - array + - "null" + entity_type: + type: + - string + - "null" + formId: + type: + - number + - "null" + id: + type: number + is_client_import: + type: + - boolean + - "null" + is_duplicate_existed: + type: + - boolean + - "null" + is_duplicate_verification_failed: + type: + - boolean + - "null" + is_lead_converted: + type: + - boolean + - "null" + klout_score: + type: + - string + - "null" + last_called: + type: + - number + - "null" + last_campaign_emaild: + type: + - number + - "null" + last_contacted: + type: + - number + - "null" + last_emailed: + type: + - number + - "null" + lead_converted_time: + type: + - number + - "null" + lead_score: + type: + - number + - "null" + lead_source_id: + type: + - number + - "null" + lead_status_id: + type: + - number + - "null" + owner: + type: + - object + - "null" + properties: + calendarURL: + type: + - string + - "null" + calendar_url: + type: + - string + - "null" + domain: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + pic: + type: + - string + - "null" + schedule_id: + type: + - string + - "null" + properties: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + name: + type: + - string + - "null" + subtype: + type: + - string + - "null" + value: + type: + - string + - "null" + restored_time: + type: + - number + - "null" + source: + type: + - string + - "null" + star_value: + type: + - number + - "null" + tags: + type: + - array + - "null" + items: + type: + - string + - "null" + tagsWithTime: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + availableCount: + type: + - number + - "null" + createdTime: + type: + - number + - "null" + entity_type: + type: + - string + - "null" + tag: + type: + - string + - "null" + trashed_time: + type: + - number + - "null" + unsubscribeStatus: + type: + - array + - "null" + updated_time: + type: + - number + - "null" + viewed: + type: + - object + - "null" + properties: + viewed_time: + type: + - number + - "null" + viewer_id: + type: + - number + - "null" + viewed_time: + type: + - number + - "null" + required: + - id + companies: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + browserId: + type: + - array + - "null" + campaignStatus: + type: + - array + - "null" + concurrent_save_allowed: + type: + - boolean + - "null" + created_time: + type: + - number + - "null" + emailBounceStatus: + type: + - array + - "null" + entity_type: + type: + - string + - "null" + formId: + type: + - number + - "null" + id: + type: number + is_client_import: + type: + - boolean + - "null" + is_duplicate_existed: + type: + - boolean + - "null" + is_duplicate_verification_failed: + type: + - boolean + - "null" + is_lead_converted: + type: + - boolean + - "null" + klout_score: + type: + - string + - "null" + last_called: + type: + - number + - "null" + last_campaign_emaild: + type: + - number + - "null" + last_contacted: + type: + - number + - "null" + last_emailed: + type: + - number + - "null" + lead_converted_time: + type: + - number + - "null" + lead_score: + type: + - number + - "null" + lead_source_id: + type: + - number + - "null" + lead_status_id: + type: + - number + - "null" + owner: + type: + - object + - "null" + properties: + calendarURL: + type: + - string + - "null" + calendar_url: + type: + - string + - "null" + domain: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + pic: + type: + - string + - "null" + schedule_id: + type: + - string + - "null" + properties: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + name: + type: + - string + - "null" + subtype: + type: + - string + - "null" + value: + type: + - string + - "null" + restored_time: + type: + - number + - "null" + star_value: + type: + - number + - "null" + tags: + type: + - array + - "null" + items: + type: + - string + - "null" + tagsWithTime: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + availableCount: + type: + - number + - "null" + createdTime: + type: + - number + - "null" + entity_type: + type: + - string + - "null" + tag: + type: + - string + - "null" + trashed_time: + type: + - number + - "null" + unsubscribeStatus: + type: + - array + - "null" + updated_time: + type: + - number + - "null" + viewed: + type: + - object + - "null" + properties: + viewed_time: + type: + - number + - "null" + viewer_id: + type: + - number + - "null" + viewed_time: + type: + - number + - "null" + required: + - id + deals: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + apply_discount: + type: + - boolean + - "null" + archived: + type: + - boolean + - "null" + close_date: + type: + - number + - "null" + colorName: + type: + - string + - "null" + contact_ids: + type: + - array + - "null" + items: + type: + - string + - "null" + contacts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + properties: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + name: + type: + - string + - "null" + value: + type: + - string + - "null" + created_time: + type: + - number + - "null" + currency_conversion_value: + type: + - number + - "null" + custom_data: + type: + - array + - "null" + deal_source_id: + type: + - number + - "null" + discount_amt: + type: + - number + - "null" + discount_type: + type: + - string + - "null" + discount_value: + type: + - number + - "null" + entity_type: + type: + - string + - "null" + expected_value: + type: + - number + - "null" + id: + type: number + isCurrencyUpdateRequired: + type: + - boolean + - "null" + lost_reason_id: + type: + - number + - "null" + milestone: + type: + - string + - "null" + milestone_changed_time: + type: + - number + - "null" + name: + type: + - string + - "null" + note_created_time: + type: + - number + - "null" + note_ids: + type: + - array + - "null" + items: + type: + - string + - "null" + notes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + contact_ids: + type: + - array + - "null" + contacts: + type: + - array + - "null" + created_time: + type: + - number + - "null" + deal_ids: + type: + - array + - "null" + domainOwner: + type: + - object + - "null" + properties: + calendarURL: + type: + - string + - "null" + calendar_url: + type: + - string + - "null" + domain: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + pic: + type: + - string + - "null" + schedule_id: + type: + - string + - "null" + entity_type: + type: + - string + - "null" + id: + type: + - number + - "null" + subject: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + calendarURL: + type: + - string + - "null" + calendar_url: + type: + - string + - "null" + domain: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + pic: + type: + - string + - "null" + schedule_id: + type: + - string + - "null" + pipeline_id: + type: + - number + - "null" + probability: + type: + - number + - "null" + products: + type: + - array + - "null" + tags: + type: + - array + - "null" + tagsWithTime: + type: + - array + - "null" + total_deal_value: + type: + - number + - "null" + updated_time: + type: + - number + - "null" + won_date: + type: + - number + - "null" + required: + - id + notes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + contact_ids: + type: + - array + - "null" + items: + type: + - string + - "null" + contacts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + properties: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + name: + type: + - string + - "null" + value: + type: + - string + - "null" + count: + type: + - number + - "null" + created_time: + type: + - number + - "null" + deal_ids: + type: + - array + - "null" + domainOwner: + type: + - object + - "null" + properties: + calendarURL: + type: + - string + - "null" + calendar_url: + type: + - string + - "null" + domain: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + pic: + type: + - string + - "null" + schedule_id: + type: + - string + - "null" + entity_type: + type: + - string + - "null" + id: + type: number + subject: + type: + - string + - "null" + required: + - id + tasks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + contacts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + properties: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + name: + type: + - string + - "null" + value: + type: + - string + - "null" + created_time: + type: + - number + - "null" + deal_ids: + type: + - array + - "null" + items: + type: + - string + - "null" + deals: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + due: + type: + - number + - "null" + entity_type: + type: + - string + - "null" + id: + type: number + is_complete: + type: + - boolean + - "null" + note_ids: + type: + - array + - "null" + notes: + type: + - array + - "null" + priority_type: + type: + - string + - "null" + progress: + type: + - number + - "null" + status: + type: + - string + - "null" + subject: + type: + - string + - "null" + taskDescription: + type: + - string + - "null" + taskOwner: + type: + - object + - "null" + properties: + calendarURL: + type: + - string + - "null" + calendar_url: + type: + - string + - "null" + domain: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + pic: + type: + - string + - "null" + schedule_id: + type: + - string + - "null" + task_completed_time: + type: + - number + - "null" + task_start_time: + type: + - number + - "null" + required: + - id + events: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} + milestone: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + deals_exist: + type: + - boolean + - "null" + id: + type: number + isDefault: + type: + - boolean + - "null" + lost_milestone: + type: + - string + - "null" + milestones: + type: + - string + - "null" + name: + type: + - string + - "null" + won_milestone: + type: + - string + - "null" + required: + - id + campaigns: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + access_level: + type: + - number + - "null" + backupExists: + type: + - boolean + - "null" + category: + type: + - number + - "null" + count: + type: + - number + - "null" + created_time: + type: + - number + - "null" + creatorName: + type: + - string + - "null" + domainUserId: + type: + - number + - "null" + id: + type: number + is_disabled: + type: + - boolean + - "null" + name: + type: + - string + - "null" + rules: + type: + - string + - "null" + trigger: + type: + - object + - "null" + properties: + campaign: + type: + - string + - "null" + contactFilter: + type: + - string + - "null" + email_tracking_type: + type: + - string + - "null" + event_owner_id: + type: + - string + - "null" + event_type: + type: + - string + - "null" + is_disabled: + type: + - boolean + - "null" + new_email_trigger_run_on_new_contacts: + type: + - boolean + - "null" + trigger_run_on_new_contacts: + type: + - boolean + - "null" + unsubscribe: + type: + - object + - "null" + properties: + action: + type: + - string + - "null" + is_unsubscribe_email_disabled: + type: + - boolean + - "null" + tag: + type: + - string + - "null" + unsubscribe_email: + type: + - string + - "null" + unsubscribe_name: + type: + - string + - "null" + unsubscribe_subject: + type: + - string + - "null" + updated_time: + type: + - number + - "null" + updated_time_update: + type: + - boolean + - "null" + required: + - id + documents: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + case_ids: + type: + - array + - "null" + contact_ids: + type: + - array + - "null" + items: + type: + - string + - "null" + contacts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + properties: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + name: + type: + - string + - "null" + value: + type: + - string + - "null" + deal_ids: + type: + - array + - "null" + items: + type: + - string + - "null" + deals: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + doc_type: + type: + - string + - "null" + dummy_name: + type: + - string + - "null" + entity_type: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + network_type: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + calendarURL: + type: + - string + - "null" + calendar_url: + type: + - string + - "null" + domain: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + pic: + type: + - string + - "null" + schedule_id: + type: + - string + - "null" + relatedContacts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + browserId: + type: + - array + - "null" + campaignStatus: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + campaign_id: + type: + - string + - "null" + campaign_name: + type: + - string + - "null" + end_time: + type: + - number + - "null" + start_time: + type: + - number + - "null" + status: + type: + - string + - "null" + concurrent_save_allowed: + type: + - boolean + - "null" + created_time: + type: + - number + - "null" + emailBounceStatus: + type: + - array + - "null" + entity_type: + type: + - string + - "null" + formId: + type: + - number + - "null" + id: + type: + - number + - "null" + is_client_import: + type: + - boolean + - "null" + is_duplicate_existed: + type: + - boolean + - "null" + is_duplicate_verification_failed: + type: + - boolean + - "null" + is_lead_converted: + type: + - boolean + - "null" + klout_score: + type: + - string + - "null" + last_called: + type: + - number + - "null" + last_campaign_emaild: + type: + - number + - "null" + last_contacted: + type: + - number + - "null" + last_emailed: + type: + - number + - "null" + lead_converted_time: + type: + - number + - "null" + lead_score: + type: + - number + - "null" + lead_source_id: + type: + - number + - "null" + lead_status_id: + type: + - number + - "null" + owner: + type: + - object + - "null" + properties: + calendarURL: + type: + - string + - "null" + calendar_url: + type: + - string + - "null" + domain: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + pic: + type: + - string + - "null" + schedule_id: + type: + - string + - "null" + properties: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + name: + type: + - string + - "null" + subtype: + type: + - string + - "null" + value: + type: + - string + - "null" + restored_time: + type: + - number + - "null" + star_value: + type: + - number + - "null" + tags: + type: + - array + - "null" + items: + type: + - string + - "null" + tagsWithTime: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + availableCount: + type: + - number + - "null" + createdTime: + type: + - number + - "null" + entity_type: + type: + - string + - "null" + tag: + type: + - string + - "null" + trashed_time: + type: + - number + - "null" + unsubscribeStatus: + type: + - array + - "null" + updated_time: + type: + - number + - "null" + viewed: + type: + - object + - "null" + properties: + viewed_time: + type: + - number + - "null" + viewer_id: + type: + - number + - "null" + viewed_time: + type: + - number + - "null" + size: + type: + - number + - "null" + template_type: + type: + - string + - "null" + text: + type: + - string + - "null" + update: + type: + - number + - "null" + uploaded_time: + type: + - number + - "null" + url: + type: + - string + - "null" + required: + - id + ticket_filters: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + conditions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + CONDITION: + type: + - string + - "null" + LHS: + type: + - string + - "null" + RHS: + type: + - string + - "null" + id: + type: number + is_default_filter: + type: + - boolean + - "null" + name: + type: + - string + - "null" + owner_id: + type: + - number + - "null" + ticketGroups: + type: + - array + - "null" + updated_time: + type: + - number + - "null" + required: + - id + tickets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + assigned_time: + type: + - number + - "null" + assigned_to_group: + type: + - boolean + - "null" + assignee: + type: + - object + - "null" + properties: + calendarURL: + type: + - string + - "null" + calendar_url: + type: + - string + - "null" + domain: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + pic: + type: + - string + - "null" + schedule_id: + type: + - string + - "null" + assigneeID: + type: + - number + - "null" + attachments_exists: + type: + - boolean + - "null" + attachments_existsString: + type: + - string + - "null" + attachments_list: + type: + - array + - "null" + cc_emails: + type: + - array + - "null" + items: + type: + - string + - "null" + closedOn: + type: + - string + - "null" + contact: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + properties: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + name: + type: + - string + - "null" + value: + type: + - string + - "null" + contactID: + type: + - number + - "null" + contact_ids: + type: + - array + - "null" + createdOn: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_time: + type: + - number + - "null" + dueOn: + type: + - string + - "null" + entity_type: + type: + - string + - "null" + first_notes_text: + type: + - string + - "null" + first_replied_time: + type: + - number + - "null" + group: + type: + - object + - "null" + properties: + group_email: + type: + - string + - "null" + group_name: + type: + - string + - "null" + id: + type: + - number + - "null" + groupID: + type: + - number + - "null" + html_text: + type: + - string + - "null" + id: + type: + - number + - "null" + isPrivate: + type: + - boolean + - "null" + is_compressed: + type: + - boolean + - "null" + is_favorite: + type: + - boolean + - "null" + is_favoriteString: + type: + - string + - "null" + is_spam: + type: + - boolean + - "null" + labels: + type: + - array + - "null" + lastUpdatedOn: + type: + - string + - "null" + last_agent_replied_time: + type: + - number + - "null" + last_customer_replied_time: + type: + - number + - "null" + last_reply_text: + type: + - string + - "null" + last_requester_name: + type: + - string + - "null" + last_ticket_notes: + type: + - object + - "null" + properties: + created_time: + type: + - number + - "null" + id: + type: + - number + - "null" + plain_text: + type: + - string + - "null" + ticket_notes_assinee: + type: + - object + - "null" + properties: + calendarURL: + type: + - string + - "null" + calendar_url: + type: + - string + - "null" + domain: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + pic: + type: + - string + - "null" + schedule_id: + type: + - string + - "null" + last_updated_by: + type: + - string + - "null" + last_updated_time: + type: + - number + - "null" + no_of_reopens: + type: + - number + - "null" + priority: + type: + - string + - "null" + priorityName: + type: + - string + - "null" + requester_email: + type: + - string + - "null" + requester_ip_address: + type: + - string + - "null" + requester_name: + type: + - string + - "null" + source: + type: + - string + - "null" + sourceFrom: + type: + - string + - "null" + status: + type: + - string + - "null" + statusName: + type: + - string + - "null" + stringTicketID: + type: + - string + - "null" + subject: + type: + - string + - "null" + user_replies_count: + type: + - number + - "null" diff --git a/airbyte-integrations/connectors/source-agilecrm/metadata.yaml b/airbyte-integrations/connectors/source-agilecrm/metadata.yaml new file mode 100644 index 000000000000..bccf861dcb7a --- /dev/null +++ b/airbyte-integrations/connectors/source-agilecrm/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "https://*.agilecrm.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-agilecrm + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 7bdf5aaa-3dad-4ed0-9cec-4858454f3e18 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-agilecrm + githubIssueLabel: source-agilecrm + icon: icon.svg + license: MIT + name: AgileCRM + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/agilecrm + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-aha/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-aha/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-aha/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-aha/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-aha/metadata.yaml b/airbyte-integrations/connectors/source-aha/metadata.yaml index 6cd0f081d672..ac63eb414570 100644 --- a/airbyte-integrations/connectors/source-aha/metadata.yaml +++ b/airbyte-integrations/connectors/source-aha/metadata.yaml @@ -15,11 +15,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 81ca39dc-4534-4dd2-b848-b0cfd2c11fce - dockerImageTag: 0.4.3 + dockerImageTag: 0.4.8 dockerRepository: airbyte/source-aha documentationUrl: https://docs.airbyte.com/integrations/sources/aha githubIssueLabel: source-aha diff --git a/airbyte-integrations/connectors/source-aircall/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-aircall/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-aircall/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-aircall/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-airtable/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-airtable/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-airtable/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-airtable/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-airtable/main.py b/airbyte-integrations/connectors/source-airtable/main.py index 170d6caf75b1..61d016c6e10f 100644 --- a/airbyte-integrations/connectors/source-airtable/main.py +++ b/airbyte-integrations/connectors/source-airtable/main.py @@ -4,5 +4,6 @@ from source_airtable.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-airtable/source_airtable/airtable_backoff_strategy.py b/airbyte-integrations/connectors/source-airtable/source_airtable/airtable_backoff_strategy.py index 3cf295b20562..a4283a121240 100644 --- a/airbyte-integrations/connectors/source-airtable/source_airtable/airtable_backoff_strategy.py +++ b/airbyte-integrations/connectors/source-airtable/source_airtable/airtable_backoff_strategy.py @@ -4,6 +4,7 @@ from typing import Any, Optional, Union import requests + from airbyte_cdk.sources.streams.http.error_handlers import BackoffStrategy diff --git a/airbyte-integrations/connectors/source-airtable/source_airtable/airtable_error_handler.py b/airbyte-integrations/connectors/source-airtable/source_airtable/airtable_error_handler.py index 7cde021f9552..336e8be7b7eb 100644 --- a/airbyte-integrations/connectors/source-airtable/source_airtable/airtable_error_handler.py +++ b/airbyte-integrations/connectors/source-airtable/source_airtable/airtable_error_handler.py @@ -7,6 +7,7 @@ from typing import Mapping, Optional, Union import requests + from airbyte_cdk.sources.streams.http.error_handlers import HttpStatusErrorHandler from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, FailureType, ResponseAction from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator diff --git a/airbyte-integrations/connectors/source-airtable/source_airtable/airtable_error_mapping.py b/airbyte-integrations/connectors/source-airtable/source_airtable/airtable_error_mapping.py index 7ae780d39d15..0a29d79dfcdd 100644 --- a/airbyte-integrations/connectors/source-airtable/source_airtable/airtable_error_mapping.py +++ b/airbyte-integrations/connectors/source-airtable/source_airtable/airtable_error_mapping.py @@ -6,6 +6,7 @@ from airbyte_cdk.sources.streams.http.error_handlers.default_error_mapping import DEFAULT_ERROR_MAPPING from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, ResponseAction + AIRTABLE_ERROR_MAPPING = DEFAULT_ERROR_MAPPING | { 403: ErrorResolution( response_action=ResponseAction.FAIL, diff --git a/airbyte-integrations/connectors/source-airtable/source_airtable/auth.py b/airbyte-integrations/connectors/source-airtable/source_airtable/auth.py index 692e09ecae40..f1517a456785 100644 --- a/airbyte-integrations/connectors/source-airtable/source_airtable/auth.py +++ b/airbyte-integrations/connectors/source-airtable/source_airtable/auth.py @@ -5,6 +5,7 @@ from typing import Any, Mapping, Union import requests + from airbyte_cdk.models import FailureType from airbyte_cdk.sources.streams.http.requests_native_auth import ( BasicHttpAuthenticator, diff --git a/airbyte-integrations/connectors/source-airtable/source_airtable/schema_helpers.py b/airbyte-integrations/connectors/source-airtable/source_airtable/schema_helpers.py index 5ec6f022df9f..f70fbacb499e 100644 --- a/airbyte-integrations/connectors/source-airtable/source_airtable/schema_helpers.py +++ b/airbyte-integrations/connectors/source-airtable/source_airtable/schema_helpers.py @@ -9,11 +9,11 @@ from airbyte_cdk.models import AirbyteStream from airbyte_cdk.models.airbyte_protocol import DestinationSyncMode, SyncMode + logger: logging.Logger = logging.getLogger("airbyte") class SchemaTypes: - string: Dict = {"type": ["null", "string"]} number: Dict = {"type": ["null", "number"]} diff --git a/airbyte-integrations/connectors/source-airtable/source_airtable/source.py b/airbyte-integrations/connectors/source-airtable/source_airtable/source.py index 655959c751c0..8d841efd64f9 100644 --- a/airbyte-integrations/connectors/source-airtable/source_airtable/source.py +++ b/airbyte-integrations/connectors/source-airtable/source_airtable/source.py @@ -18,7 +18,6 @@ class SourceAirtable(AbstractSource): - logger: logging.Logger = logging.getLogger("airbyte") streams_catalog: Iterable[Mapping[str, Any]] = [] _auth: AirtableAuth = None diff --git a/airbyte-integrations/connectors/source-airtable/source_airtable/streams.py b/airbyte-integrations/connectors/source-airtable/source_airtable/streams.py index 39e985b948fa..5a1ddeb60845 100644 --- a/airbyte-integrations/connectors/source-airtable/source_airtable/streams.py +++ b/airbyte-integrations/connectors/source-airtable/source_airtable/streams.py @@ -7,6 +7,7 @@ from typing import Any, Iterable, Mapping, MutableMapping, Optional import requests + from airbyte_cdk.sources.streams.http import HttpClient, HttpStream from airbyte_cdk.sources.streams.http.error_handlers import HttpStatusErrorHandler from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator @@ -15,6 +16,7 @@ from source_airtable.airtable_error_handler import AirtableErrorHandler from source_airtable.schema_helpers import SchemaHelpers + URL_BASE: str = "https://api.airtable.com/v0/" @@ -97,7 +99,6 @@ def path(self, **kwargs) -> str: class AirtableStream(HttpStream, ABC): def __init__(self, stream_path: str, stream_name: str, stream_schema, table_name: str, **kwargs): - self.stream_name = stream_name self.stream_path = stream_path self.stream_schema = stream_schema diff --git a/airbyte-integrations/connectors/source-airtable/unit_tests/conftest.py b/airbyte-integrations/connectors/source-airtable/unit_tests/conftest.py index f2a42ae96efb..161a0529852b 100644 --- a/airbyte-integrations/connectors/source-airtable/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-airtable/unit_tests/conftest.py @@ -4,10 +4,11 @@ import pytest +from source_airtable.streams import AirtableStream + from airbyte_cdk.models import AirbyteStream, ConfiguredAirbyteCatalog from airbyte_cdk.models.airbyte_protocol import DestinationSyncMode, SyncMode from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator -from source_airtable.streams import AirtableStream @pytest.fixture diff --git a/airbyte-integrations/connectors/source-airtable/unit_tests/test_airtable_backoff_strategy.py b/airbyte-integrations/connectors/source-airtable/unit_tests/test_airtable_backoff_strategy.py index e9ee73055239..3e0ae06c53b8 100644 --- a/airbyte-integrations/connectors/source-airtable/unit_tests/test_airtable_backoff_strategy.py +++ b/airbyte-integrations/connectors/source-airtable/unit_tests/test_airtable_backoff_strategy.py @@ -10,13 +10,7 @@ from source_airtable.airtable_backoff_strategy import AirtableBackoffStrategy -@pytest.mark.parametrize( - "response_code, expected_backoff_time", - [ - (429, 30), - (404, None) - ] -) +@pytest.mark.parametrize("response_code, expected_backoff_time", [(429, 30), (404, None)]) def test_backoff_time(response_code, expected_backoff_time): mocked_logger = MagicMock(spec=logging.Logger) backoff = AirtableBackoffStrategy(logger=mocked_logger) diff --git a/airbyte-integrations/connectors/source-airtable/unit_tests/test_airtable_error_handler.py b/airbyte-integrations/connectors/source-airtable/unit_tests/test_airtable_error_handler.py index 67daf8eb3129..f10fe1cfe951 100644 --- a/airbyte-integrations/connectors/source-airtable/unit_tests/test_airtable_error_handler.py +++ b/airbyte-integrations/connectors/source-airtable/unit_tests/test_airtable_error_handler.py @@ -6,21 +6,30 @@ from unittest.mock import MagicMock import pytest -from airbyte_cdk.sources.streams.http.error_handlers.response_models import FailureType, ResponseAction -from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator from requests import Response from source_airtable.airtable_error_handler import AirtableErrorHandler from source_airtable.airtable_error_mapping import AIRTABLE_ERROR_MAPPING from source_airtable.auth import AirtableOAuth +from airbyte_cdk.sources.streams.http.error_handlers.response_models import FailureType, ResponseAction +from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator + @pytest.mark.parametrize( "auth, json_response, error_message", [ - (TokenAuthenticator, {"error": {"type": "INVALID_PERMISSIONS_OR_MODEL_NOT_FOUND"}}, "Personal Access Token does not have required permissions, please add all required permissions to existed one or create new PAT, see docs for more info: https://docs.airbyte.com/integrations/sources/airtable#step-1-set-up-airtable"), - (AirtableOAuth, {"error": {"type": "INVALID_PERMISSIONS_OR_MODEL_NOT_FOUND"}}, "Access Token does not have required permissions, please reauthenticate."), - (TokenAuthenticator, {"error": {"type": "Test 403"}}, "Permission denied or entity is unprocessable.") - ] + ( + TokenAuthenticator, + {"error": {"type": "INVALID_PERMISSIONS_OR_MODEL_NOT_FOUND"}}, + "Personal Access Token does not have required permissions, please add all required permissions to existed one or create new PAT, see docs for more info: https://docs.airbyte.com/integrations/sources/airtable#step-1-set-up-airtable", + ), + ( + AirtableOAuth, + {"error": {"type": "INVALID_PERMISSIONS_OR_MODEL_NOT_FOUND"}}, + "Access Token does not have required permissions, please reauthenticate.", + ), + (TokenAuthenticator, {"error": {"type": "Test 403"}}, "Permission denied or entity is unprocessable."), + ], ) def test_interpret_response_handles_403_error(auth, json_response, error_message): mocked_authenticator = MagicMock(spec=auth) @@ -35,6 +44,7 @@ def test_interpret_response_handles_403_error(auth, json_response, error_message assert error_resolution.failure_type == FailureType.config_error assert error_resolution.error_message == error_message + def test_interpret_response_defers_to_airtable_error_mapping_for_other_errors(): mocked_logger = MagicMock(spec=logging.Logger) mocked_response = MagicMock(spec=Response) diff --git a/airbyte-integrations/connectors/source-airtable/unit_tests/test_authenticator.py b/airbyte-integrations/connectors/source-airtable/unit_tests/test_authenticator.py index fbc0c6e9e49f..766779eeddab 100644 --- a/airbyte-integrations/connectors/source-airtable/unit_tests/test_authenticator.py +++ b/airbyte-integrations/connectors/source-airtable/unit_tests/test_authenticator.py @@ -4,9 +4,11 @@ import pytest +from source_airtable.auth import AirtableAuth, AirtableOAuth + from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator from airbyte_cdk.utils import AirbyteTracedException -from source_airtable.auth import AirtableAuth, AirtableOAuth + CONFIG_OAUTH = {"credentials": {"auth_method": "oauth2.0", "client_id": "sample_client_id", "client_secret": "sample_client_secret"}} diff --git a/airbyte-integrations/connectors/source-airtable/unit_tests/test_source.py b/airbyte-integrations/connectors/source-airtable/unit_tests/test_source.py index d1591ab7fbb0..eab9bed768a2 100644 --- a/airbyte-integrations/connectors/source-airtable/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-airtable/unit_tests/test_source.py @@ -7,9 +7,10 @@ from unittest.mock import MagicMock import pytest -from airbyte_cdk.models import AirbyteCatalog from source_airtable.source import SourceAirtable +from airbyte_cdk.models import AirbyteCatalog + @pytest.mark.parametrize( "status, check_passed", diff --git a/airbyte-integrations/connectors/source-airtable/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-airtable/unit_tests/test_streams.py index e9a8d96dd37a..c31d0982e866 100644 --- a/airbyte-integrations/connectors/source-airtable/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-airtable/unit_tests/test_streams.py @@ -11,7 +11,6 @@ class TestBases: - bases_instance = AirtableBases(authenticator=MagicMock()) def test_url_base(self): @@ -50,7 +49,6 @@ def test_parse_response(self, fake_bases_response, expected_bases_response, requ class TestTables: - tables_instance = AirtableTables(base_id="test_base_id", authenticator=MagicMock()) def test_path(self): diff --git a/airbyte-integrations/connectors/source-akeneo/README.md b/airbyte-integrations/connectors/source-akeneo/README.md new file mode 100644 index 000000000000..6ab13cdaf20d --- /dev/null +++ b/airbyte-integrations/connectors/source-akeneo/README.md @@ -0,0 +1,33 @@ +# Akeneo +This directory contains the manifest-only connector for `source-akeneo`. + +The Akeneo Airbyte connector enables seamless data synchronization between Akeneo PIM (Product Information Management) and other platforms. It allows you to easily extract, transform, and load product information from Akeneo to a desired data destination, facilitating efficient management and integration of product catalogs across systems. This connector supports bidirectional data flows, helping businesses maintain accurate and up-to-date product information for various sales channels. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-akeneo:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-akeneo build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-akeneo test +``` + diff --git a/airbyte-integrations/connectors/source-akeneo/acceptance-test-config.yml b/airbyte-integrations/connectors/source-akeneo/acceptance-test-config.yml new file mode 100644 index 000000000000..90baa0a8534a --- /dev/null +++ b/airbyte-integrations/connectors/source-akeneo/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-akeneo:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-akeneo/icon.svg b/airbyte-integrations/connectors/source-akeneo/icon.svg new file mode 100644 index 000000000000..2356eeec644f --- /dev/null +++ b/airbyte-integrations/connectors/source-akeneo/icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/airbyte-integrations/connectors/source-akeneo/manifest.yaml b/airbyte-integrations/connectors/source-akeneo/manifest.yaml new file mode 100644 index 000000000000..b794af62acde --- /dev/null +++ b/airbyte-integrations/connectors/source-akeneo/manifest.yaml @@ -0,0 +1,6691 @@ +version: 5.16.0 + +type: DeclarativeSource + +description: >- + The Akeneo Airbyte connector enables seamless data synchronization between + Akeneo PIM (Product Information Management) and other platforms. It allows you + to easily extract, transform, and load product information from Akeneo to a + desired data destination, facilitating efficient management and integration of + product catalogs across systems. This connector supports bidirectional data + flows, helping businesses maintain accurate and up-to-date product information + for various sales channels. + +check: + type: CheckStream + stream_names: + - products + +definitions: + streams: + products: + type: DeclarativeStream + name: products + primary_key: + - uuid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /products-uuid + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + "categories ": + type: DeclarativeStream + name: "categories " + primary_key: + - code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /categories + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/categories " + families: + type: DeclarativeStream + name: families + primary_key: + - code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /families + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/families" + family_variants: + type: DeclarativeStream + name: family_variants + primary_key: + - code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /families/{{ stream_partition.family_code }}/variants + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: code + partition_field: family_code + stream: + $ref: "#/definitions/streams/families" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/family_variants" + attributes: + type: DeclarativeStream + name: attributes + primary_key: + - code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /attributes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/attributes" + attribute_groups: + type: DeclarativeStream + name: attribute_groups + primary_key: + - code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /attribute-groups + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/attribute_groups" + association_types: + type: DeclarativeStream + name: association_types + primary_key: + - code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /association-types + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/association_types" + channels: + type: DeclarativeStream + name: channels + primary_key: + - code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /channels + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/channels" + locales: + type: DeclarativeStream + name: locales + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /locales + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/locales" + currencies: + type: DeclarativeStream + name: currencies + primary_key: + - code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /currencies + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/currencies" + measure_families: + type: DeclarativeStream + name: measure_families + primary_key: + - code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /measure-families + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/measure_families" + base_requester: + type: HttpRequester + url_base: "{{ config[\"host\"] }}/api/rest/v1" + authenticator: + type: SessionTokenAuthenticator + login_requester: + type: HttpRequester + url_base: "{{ config[\"host\"] }}/api/oauth/v1" + path: token + authenticator: + type: BasicHttpAuthenticator + password: "{{ config[\"secret\"] }}" + username: "{{ config[\"client_id\"] }}" + http_method: POST + request_parameters: {} + request_headers: {} + request_body_json: + password: "{{ config['password'] }}" + username: "{{ config['api_username'] }}" + grant_type: password + session_token_path: + - access_token + expiration_duration: PT1H + request_authentication: + type: Bearer + +streams: + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/categories " + - $ref: "#/definitions/streams/families" + - $ref: "#/definitions/streams/family_variants" + - $ref: "#/definitions/streams/attributes" + - $ref: "#/definitions/streams/attribute_groups" + - $ref: "#/definitions/streams/association_types" + - $ref: "#/definitions/streams/channels" + - $ref: "#/definitions/streams/locales" + - $ref: "#/definitions/streams/currencies" + - $ref: "#/definitions/streams/measure_families" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - host + - api_username + - password + - client_id + properties: + host: + type: string + description: https://cb8715249e.trial.akeneo.cloud + order: 0 + title: Host + api_username: + type: string + order: 1 + title: API Username + password: + type: string + order: 2 + title: Password + airbyte_secret: true + client_id: + type: string + order: 3 + title: Client ID + secret: + type: string + order: 4 + title: Secret + always_show: true + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + products: true + "categories ": true + families: true + family_variants: true + attributes: true + attribute_groups: true + association_types: true + channels: true + locales: true + currencies: true + measure_families: true + testedStreams: + products: + streamHash: d8f7bdfec50fe02408812c2c01f8555de9c21cc9 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + "categories ": + streamHash: 0a6a99847156f87fe4ebf0d71cb8f5c9bd83977b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + families: + streamHash: 452cd2f922d7607f777254ee34b449386cb98943 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + family_variants: + streamHash: e4029a5e91f267a5eb2199653dd28eef9fe372c2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + attributes: + streamHash: 8ad57ccffc7bdf3f92cee698c0d48ab90b9c5886 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + attribute_groups: + streamHash: ca3773e295515bdc0a0d8d48fddddc4bd442629b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + association_types: + streamHash: 984fa922d3728e1a55a026aecdb165f800af1d6a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + channels: + streamHash: 03f3f97fbf23ccbef66b414c0bf2ac3972423538 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + locales: + streamHash: fa6e0c3364ac475d91e4a8479ed21fef68062831 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + currencies: + streamHash: 5216fc38b15fcfbf35153bafd306f0d05ac29e00 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + measure_families: + hasRecords: true + streamHash: d3c6dc38392923b83ea70d6fc791ac46d53f08af + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://api.akeneo.com/api-reference.html + openapiSpecUrl: >- + https://storage.googleapis.com/akecld-prd-sdk-aep-prd-api-assets/openapi_specification.yml + +schemas: + products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + metadata: + type: + - object + - "null" + properties: + workflow_status: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + associations: + type: + - object + - "null" + properties: + PACK: + type: + - object + - "null" + properties: + groups: + type: + - array + - "null" + product_models: + type: + - array + - "null" + products: + type: + - array + - "null" + SUBSTITUTION: + type: + - object + - "null" + properties: + groups: + type: + - array + - "null" + product_models: + type: + - array + - "null" + items: + type: + - string + - "null" + products: + type: + - array + - "null" + items: + type: + - string + - "null" + UPSELL: + type: + - object + - "null" + properties: + groups: + type: + - array + - "null" + product_models: + type: + - array + - "null" + products: + type: + - array + - "null" + X_SELL: + type: + - object + - "null" + properties: + groups: + type: + - array + - "null" + product_models: + type: + - array + - "null" + items: + type: + - string + - "null" + products: + type: + - array + - "null" + items: + type: + - string + - "null" + categories: + type: + - array + - "null" + items: + type: + - string + - "null" + created: + type: + - string + - "null" + enabled: + type: + - boolean + - "null" + family: + type: + - string + - "null" + groups: + type: + - array + - "null" + parent: + type: + - string + - "null" + quantified_associations: + type: + - object + - "null" + updated: + type: + - string + - "null" + uuid: + type: string + values: + type: + - object + - "null" + properties: + description: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + scope: + type: + - string + - "null" + 3d_technology: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + adjustable_stand_width: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - number + - "null" + unit: + type: + - string + - "null" + amp_hours: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - number + - "null" + unit: + type: + - string + - "null" + app_aesthetics: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + app_awards: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + app_base_material: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + app_body_material: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + app_edition_text: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + app_finishing: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + app_slices: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + app_top_material: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + app_voltage: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + app_wattage: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - number + - "null" + unit: + type: + - string + - "null" + aspect_ratio_tires: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + atmosphere: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + download: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + atmosphere_2: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + download: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + authorized_countries: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + auto_exposure: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + auto_focus_assist_beam: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + auto_focus_lock: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + automatic_document_feeder: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + automatic_reduction_enlargement: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + automatic_two_sided_printing: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + backlight_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + bags_all_hardware_colors: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + bags_closure_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + bags_inner_description: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + bags_strap_description: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + bags_typespecific_details: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + battery_included: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + battery_power_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + bluetooth_enabled: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + bluetooth_version: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + brand: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + brief_product: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + download: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + built_in_speakers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + bw_print_speed: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + cable_s_included: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + camera_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + category_code_description: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + certification_logo_1: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + download: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + certification_logo_2: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + download: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + certification_logo_3: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + download: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + certifications: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + chuck_size: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + chuck_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + clothing_care_instructions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + clothing_material: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + clothing_material_text: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + clothing_size: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + color: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + color_category: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + color_name: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + color_pattern: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + color_print_speed: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + color_scanning: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + connector_type_1: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + connector_type_2: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + cord_length_ft: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + cornering_stability: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + cosmetic_allergenes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + cosmetic_aromatic_components: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + cosmetic_authorized_claim: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + cosmetic_benefits: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + cosmetic_clinical_evaluation: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + cosmetic_cvolume: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + cosmetic_format: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + cosmetic_web_fp_picto1: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + cosmetics_text_bapplication: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + cosmetics_text_benefit: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + cosmetics_text_formula: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + curved_screen: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + customs_description: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + customs_material: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + depth: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + designer: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + designer_color_name: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + designer_id: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + display_color: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + display_diagonal: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - number + - "null" + unit: + type: + - string + - "null" + display_screen: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + display_srgb: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + display_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + drill_bit_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + driving_comfort: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + dry_traction: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + durability_treadwear: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + duty_cycle: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + ean: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + energy_star_certified: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + epeat_qualified: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + erp_name: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + estimated_annual_electricity_use: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + estimated_annual_operating_cost_usd: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + ethernet_port_s: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + exclusive: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + featured_streaming_services: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + features: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + food_allergens: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + food_coeliac: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + food_energy_kcal: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + food_energy_kj: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + food_fat_g: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + food_halal: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + food_ingredients: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + food_kosher: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + food_lactose: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + food_protein_g: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + food_vegan: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + food_vegetarian: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + forme_galenique: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + furniture_fabric_composition: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + furniture_packaging_dimensions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + furniture_yarn_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + gender_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + go_live_date: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + green_tire_technology: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + handling: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + hdmi_audio_return_channel_arc: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + height: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + high_dynamic_range_format: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + high_dynamic_range_hdr: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + hydroplaning_resistance: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + ice_traction: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + image_1: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + download: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + image_2: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + download: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + image_3: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + download: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + image_4: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + download: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + image_5: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + download: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + image_dimension: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + download: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + image_instagram_1: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + download: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + image_material_detail: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + download: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + includes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + integrated_fax: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + language_s_displayed: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + led_panel_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + leg_height: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - number + - "null" + unit: + type: + - string + - "null" + length: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + load_index: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + load_range: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + long_description: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + made_in: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + main_market: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + material: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + maximum_frame_rate: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + maximum_print_size: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + maximum_speed_rpm: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + maximum_video_resolution: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + measuring_rim_width: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + meta_description: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + meta_keywords: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + meta_title: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + mobile_device_printing: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + model_name: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + model_number: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + model_year: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + motion_enhancement_technology: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + motor_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + multifunctional_functions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + name: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + network_compatibility: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + noise_level: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + non_textile_part: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + number_of_black_cartridges_included: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + number_of_color_cartridges_included: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + number_of_component_video_inputs: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + number_of_composite_video_inputs: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + number_of_digital_optical_audio_outputs: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + number_of_dvi_inputs: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + number_of_hdmi_hdcp: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + number_of_hdmi_inputs: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + number_of_ink_bottles_tanks_included: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + number_of_ink_bottles_tanks_required: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + number_of_pieces: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + number_of_usb_2_0_ports: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + number_of_usb_port_s_total: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + optical_zoom: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + original_equipment: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + overall_diameter: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + overall_summer_all_seasons: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + overall_winter: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + peremption: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + pharmaceutical_form: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + picture_quality_enhancement_technology: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + power_requirements: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + power_tool_features: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + power_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + price: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + currency: + type: + - string + - "null" + printer_connectivity: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + printer_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + product_data_pdf: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + download: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + product_depth_with_stand: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + product_depth_without_stand: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + product_heading: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + product_height_with_stand: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + product_height_without_stand: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + product_weight_with_stand: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + product_weight_without_stand: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + product_width: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + rechargeable: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + rechargeable_battery_remote_control: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + recommended_cure_days: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + recycled_material: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + refresh_rate: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - number + - "null" + unit: + type: + - string + - "null" + reinforced_tire: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + remote_control_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + resolution: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + response_time: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + rf_antenna_input: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + rim_width_approved: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + runflat_tire_technology: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + runway: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + runway_image: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + download: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + scanner_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + screen_mirroring: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + screen_mirroring_technology: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + screen_size: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + sensor_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + series: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + shank_style: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + short_description: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + sidewall_lettering: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + sidewall_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + sku: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + smart_capable: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + smart_platform: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + snow_traction: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + speaker_output: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - number + - "null" + unit: + type: + - string + - "null" + specific_manufacturer_technologies: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + speed_rating: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + stand_depth: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + stand_included: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + stand_width: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + studdable_tire: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + style_family_code: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + style_name: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + tire_qualities: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + tire_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + tmall_categories: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + tmall_descripton: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + tmall_title: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + total_megapixels: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + touch_screen: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + tray_capacity: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - number + - "null" + tread_depth: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + tread_width: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + tv_tuner: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + uniform_tire_quality_grading_utqg: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + upc: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + usage: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + usage_indicaion: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + locale: + type: + - string + - "null" + uses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + v_chip: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + variant_name: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + vendor_item_number: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + vesa_wall_mount_standard: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + voltage: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - number + - "null" + unit: + type: + - string + - "null" + weight: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + wet_traction: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - string + - "null" + wheel_diameter: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + wheel_width: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + wide_format_printing: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + wide_format_scanning: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + width: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + unit: + type: + - string + - "null" + winter_designed_tire: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - boolean + - "null" + works_with: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute_type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - string + - "null" + required: + - uuid + "categories ": + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + code: + type: string + labels: + type: + - object + - "null" + properties: + en_US: + type: + - string + - "null" + es_ES: + type: + - string + - "null" + zh_CN: + type: + - string + - "null" + parent: + type: + - string + - "null" + updated: + type: + - string + - "null" + required: + - code + families: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attribute_as_image: + type: + - string + - "null" + attribute_as_label: + type: + - string + - "null" + attribute_requirements: + type: + - object + - "null" + properties: + ecommerce: + type: + - array + - "null" + items: + type: + - string + - "null" + marketplaces: + type: + - array + - "null" + items: + type: + - string + - "null" + pos: + type: + - array + - "null" + items: + type: + - string + - "null" + attributes: + type: + - array + - "null" + items: + type: + - string + - "null" + code: + type: string + labels: + type: + - object + - "null" + properties: + en_US: + type: + - string + - "null" + es_ES: + type: + - string + - "null" + zh_CN: + type: + - string + - "null" + required: + - code + family_variants: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + code: + type: string + labels: + type: + - object + - "null" + properties: + en_US: + type: + - string + - "null" + variant_attribute_sets: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attributes: + type: + - array + - "null" + items: + type: + - string + - "null" + axes: + type: + - array + - "null" + items: + type: + - string + - "null" + level: + type: + - number + - "null" + required: + - code + attributes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + allowed_extensions: + type: + - array + - "null" + items: + type: + - string + - "null" + auto_option_sorting: + type: + - boolean + - "null" + available_locales: + type: + - array + - "null" + code: + type: string + date_min: + type: + - string + - "null" + decimals_allowed: + type: + - boolean + - "null" + default_metric_unit: + type: + - string + - "null" + group: + type: + - string + - "null" + group_labels: + type: + - object + - "null" + properties: + en_US: + type: + - string + - "null" + es_ES: + type: + - string + - "null" + zh_CN: + type: + - string + - "null" + guidelines: + type: + - object + - "null" + properties: + en_US: + type: + - string + - "null" + is_main_identifier: + type: + - boolean + - "null" + labels: + type: + - object + - "null" + properties: + en_US: + type: + - string + - "null" + es_ES: + type: + - string + - "null" + zh_CN: + type: + - string + - "null" + localizable: + type: + - boolean + - "null" + metric_family: + type: + - string + - "null" + minimum_input_length: + type: + - number + - "null" + negative_allowed: + type: + - boolean + - "null" + number_min: + type: + - string + - "null" + scopable: + type: + - boolean + - "null" + sort_order: + type: + - number + - "null" + unique: + type: + - boolean + - "null" + useable_as_grid_filter: + type: + - boolean + - "null" + validation_regexp: + type: + - string + - "null" + validation_rule: + type: + - string + - "null" + wysiwyg_enabled: + type: + - boolean + - "null" + required: + - code + attribute_groups: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + attributes: + type: + - array + - "null" + items: + type: + - string + - "null" + code: + type: string + labels: + type: + - object + - "null" + properties: + en_US: + type: + - string + - "null" + es_ES: + type: + - string + - "null" + zh_CN: + type: + - string + - "null" + sort_order: + type: + - number + - "null" + required: + - code + association_types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + code: + type: string + is_quantified: + type: + - boolean + - "null" + is_two_way: + type: + - boolean + - "null" + labels: + type: + - object + - "null" + properties: + en_US: + type: + - string + - "null" + es_ES: + type: + - string + - "null" + zh_CN: + type: + - string + - "null" + required: + - code + channels: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + category_tree: + type: + - string + - "null" + code: + type: string + conversion_units: + type: + - object + - "null" + currencies: + type: + - array + - "null" + items: + type: + - string + - "null" + labels: + type: + - object + - "null" + properties: + en_US: + type: + - string + - "null" + es_ES: + type: + - string + - "null" + zh_CN: + type: + - string + - "null" + locales: + type: + - array + - "null" + items: + type: + - string + - "null" + required: + - code + locales: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + code: + type: + - string + - "null" + enabled: + type: + - boolean + - "null" + currencies: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + code: + type: string + enabled: + type: + - boolean + - "null" + label: + type: + - string + - "null" + required: + - code + measure_families: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + code: + type: string + standard: + type: + - string + - "null" + units: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + code: + type: + - string + - "null" + convert: + type: + - object + - "null" + properties: + add: + type: + - string + - "null" + div: + type: + - string + - "null" + mul: + type: + - string + - "null" + sub: + type: + - string + - "null" + symbol: + type: + - string + - "null" + required: + - code diff --git a/airbyte-integrations/connectors/source-akeneo/metadata.yaml b/airbyte-integrations/connectors/source-akeneo/metadata.yaml new file mode 100644 index 000000000000..bdce1504c13d --- /dev/null +++ b/airbyte-integrations/connectors/source-akeneo/metadata.yaml @@ -0,0 +1,34 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-akeneo + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: d6754ed7-dd8a-4a0a-a07e-e768fbac420c + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-akeneo + githubIssueLabel: source-akeneo + icon: icon.svg + license: MIT + name: Akeneo + releaseDate: 2024-10-28 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/akeneo + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-algolia/metadata.yaml b/airbyte-integrations/connectors/source-algolia/metadata.yaml index 40adb570a99d..38ed27109ef9 100644 --- a/airbyte-integrations/connectors/source-algolia/metadata.yaml +++ b/airbyte-integrations/connectors/source-algolia/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-algolia connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: a20aa64a-bb59-4782-97bf-afd6a241c737 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-algolia githubIssueLabel: source-algolia icon: icon.svg diff --git a/airbyte-integrations/connectors/source-alpha-vantage/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-alpha-vantage/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-alpha-vantage/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-alpha-vantage/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-alpha-vantage/main.py b/airbyte-integrations/connectors/source-alpha-vantage/main.py index dcccfe7a535c..48d5bd87d7f3 100644 --- a/airbyte-integrations/connectors/source-alpha-vantage/main.py +++ b/airbyte-integrations/connectors/source-alpha-vantage/main.py @@ -4,5 +4,6 @@ from source_alpha_vantage.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-alpha-vantage/metadata.yaml b/airbyte-integrations/connectors/source-alpha-vantage/metadata.yaml index cfd5e3446a6d..74dea10b3346 100644 --- a/airbyte-integrations/connectors/source-alpha-vantage/metadata.yaml +++ b/airbyte-integrations/connectors/source-alpha-vantage/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: db385323-9333-4fec-bec3-9e0ca9326c90 - dockerImageTag: 0.1.22 + dockerImageTag: 0.1.26 dockerRepository: airbyte/source-alpha-vantage githubIssueLabel: source-alpha-vantage icon: alpha-vantage.svg @@ -39,5 +39,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-alpha-vantage/poetry.lock b/airbyte-integrations/connectors/source-alpha-vantage/poetry.lock index 2d9b72370c15..e563263b1bd0 100644 --- a/airbyte-integrations/connectors/source-alpha-vantage/poetry.lock +++ b/airbyte-integrations/connectors/source-alpha-vantage/poetry.lock @@ -42,13 +42,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] @@ -56,24 +56,24 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.0" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.0-py3-none-any.whl", hash = "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a"}, - {file = "anyio-4.6.0.tar.gz", hash = "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -88,19 +88,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -166,13 +166,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -256,116 +256,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -435,20 +422,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -498,13 +485,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -519,13 +506,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -533,7 +520,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -583,13 +569,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -679,156 +665,177 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.134" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.134-py3-none-any.whl", hash = "sha256:ada98ad80ef38807725f32441a472da3dd28394010877751f48f458d3289da04"}, - {file = "langsmith-0.1.134.tar.gz", hash = "sha256:23abee3b508875a0e63c602afafffc02442a19cfd88f9daae05b3e9054fd6b61"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" -version = "3.0.1" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" files = [ - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win32.whl", hash = "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win32.whl", hash = "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win32.whl", hash = "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win32.whl", hash = "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win32.whl", hash = "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b"}, - {file = "markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] name = "orjson" -version = "3.10.7" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:74f4544f5a6405b90da8ea724d15ac9c36da4d72a738c64685003337401f5c12"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34a566f22c28222b08875b18b0dfbf8a947e69df21a9ed5c51a6bf91cfb944ac"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf6ba8ebc8ef5792e2337fb0419f8009729335bb400ece005606336b7fd7bab7"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac7cf6222b29fbda9e3a472b41e6a5538b48f2c8f99261eecd60aafbdb60690c"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de817e2f5fc75a9e7dd350c4b0f54617b280e26d1631811a43e7e968fa71e3e9"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:348bdd16b32556cf8d7257b17cf2bdb7ab7976af4af41ebe79f9796c218f7e91"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:479fd0844ddc3ca77e0fd99644c7fe2de8e8be1efcd57705b5c92e5186e8a250"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fdf5197a21dd660cf19dfd2a3ce79574588f8f5e2dbf21bda9ee2d2b46924d84"}, - {file = "orjson-3.10.7-cp310-none-win32.whl", hash = "sha256:d374d36726746c81a49f3ff8daa2898dccab6596864ebe43d50733275c629175"}, - {file = "orjson-3.10.7-cp310-none-win_amd64.whl", hash = "sha256:cb61938aec8b0ffb6eef484d480188a1777e67b05d58e41b435c74b9d84e0b9c"}, - {file = "orjson-3.10.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0"}, - {file = "orjson-3.10.7-cp311-none-win32.whl", hash = "sha256:82763b46053727a7168d29c772ed5c870fdae2f61aa8a25994c7984a19b1021f"}, - {file = "orjson-3.10.7-cp311-none-win_amd64.whl", hash = "sha256:eb8d384a24778abf29afb8e41d68fdd9a156cf6e5390c04cc07bbc24b89e98b5"}, - {file = "orjson-3.10.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44a96f2d4c3af51bfac6bc4ef7b182aa33f2f054fd7f34cc0ee9a320d051d41f"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ac14cd57df0572453543f8f2575e2d01ae9e790c21f57627803f5e79b0d3c3"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bdbb61dcc365dd9be94e8f7df91975edc9364d6a78c8f7adb69c1cdff318ec93"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b48b3db6bb6e0a08fa8c83b47bc169623f801e5cc4f24442ab2b6617da3b5313"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23820a1563a1d386414fef15c249040042b8e5d07b40ab3fe3efbfbbcbcb8864"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0c6a008e91d10a2564edbb6ee5069a9e66df3fbe11c9a005cb411f441fd2c09"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d352ee8ac1926d6193f602cbe36b1643bbd1bbcb25e3c1a657a4390f3000c9a5"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b"}, - {file = "orjson-3.10.7-cp312-none-win32.whl", hash = "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb"}, - {file = "orjson-3.10.7-cp312-none-win_amd64.whl", hash = "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1"}, - {file = "orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149"}, - {file = "orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad"}, - {file = "orjson-3.10.7-cp313-none-win32.whl", hash = "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2"}, - {file = "orjson-3.10.7-cp313-none-win_amd64.whl", hash = "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024"}, - {file = "orjson-3.10.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6ea2b2258eff652c82652d5e0f02bd5e0463a6a52abb78e49ac288827aaa1469"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:430ee4d85841e1483d487e7b81401785a5dfd69db5de01314538f31f8fbf7ee1"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b6146e439af4c2472c56f8540d799a67a81226e11992008cb47e1267a9b3225"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:084e537806b458911137f76097e53ce7bf5806dda33ddf6aaa66a028f8d43a23"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829cf2195838e3f93b70fd3b4292156fc5e097aac3739859ac0dcc722b27ac0"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1193b2416cbad1a769f868b1749535d5da47626ac29445803dae7cc64b3f5c98"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4e6c3da13e5a57e4b3dca2de059f243ebec705857522f188f0180ae88badd354"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c31008598424dfbe52ce8c5b47e0752dca918a4fdc4a2a32004efd9fab41d866"}, - {file = "orjson-3.10.7-cp38-none-win32.whl", hash = "sha256:7122a99831f9e7fe977dc45784d3b2edc821c172d545e6420c375e5a935f5a1c"}, - {file = "orjson-3.10.7-cp38-none-win_amd64.whl", hash = "sha256:a763bc0e58504cc803739e7df040685816145a6f3c8a589787084b54ebc9f16e"}, - {file = "orjson-3.10.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e76be12658a6fa376fcd331b1ea4e58f5a06fd0220653450f0d415b8fd0fbe20"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed350d6978d28b92939bfeb1a0570c523f6170efc3f0a0ef1f1df287cd4f4960"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144888c76f8520e39bfa121b31fd637e18d4cc2f115727865fdf9fa325b10412"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09b2d92fd95ad2402188cf51573acde57eb269eddabaa60f69ea0d733e789fe9"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b24a579123fa884f3a3caadaed7b75eb5715ee2b17ab5c66ac97d29b18fe57f"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591bcfe7512353bd609875ab38050efe3d55e18934e2f18950c108334b4ff"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f4db56635b58cd1a200b0a23744ff44206ee6aa428185e2b6c4a65b3197abdcd"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0fa5886854673222618638c6df7718ea7fe2f3f2384c452c9ccedc70b4a510a5"}, - {file = "orjson-3.10.7-cp39-none-win32.whl", hash = "sha256:8272527d08450ab16eb405f47e0f4ef0e5ff5981c3d82afe0efd25dcbef2bcd2"}, - {file = "orjson-3.10.7-cp39-none-win_amd64.whl", hash = "sha256:974683d4618c0c7dbf4f69c95a979734bf183d0658611760017f6e70a145af58"}, - {file = "orjson-3.10.7.tar.gz", hash = "sha256:75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -931,54 +938,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -990,13 +997,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1284,33 +1291,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.1.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"}, - {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1377,13 +1384,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1408,81 +1415,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-alpha-vantage/pyproject.toml b/airbyte-integrations/connectors/source-alpha-vantage/pyproject.toml index a7402df7f1a5..0b346666e253 100644 --- a/airbyte-integrations/connectors/source-alpha-vantage/pyproject.toml +++ b/airbyte-integrations/connectors/source-alpha-vantage/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.22" +version = "0.1.26" name = "source-alpha-vantage" description = "Source implementation for Alpha Vantage." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-alpha-vantage/source_alpha_vantage/object_dpath_extractor.py b/airbyte-integrations/connectors/source-alpha-vantage/source_alpha_vantage/object_dpath_extractor.py index fa00fb61a53d..91d0018826b2 100644 --- a/airbyte-integrations/connectors/source-alpha-vantage/source_alpha_vantage/object_dpath_extractor.py +++ b/airbyte-integrations/connectors/source-alpha-vantage/source_alpha_vantage/object_dpath_extractor.py @@ -7,6 +7,7 @@ import dpath.util import requests + from airbyte_cdk.sources.declarative.extractors.dpath_extractor import DpathExtractor from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString from airbyte_cdk.sources.declarative.types import Record diff --git a/airbyte-integrations/connectors/source-alpha-vantage/source_alpha_vantage/run.py b/airbyte-integrations/connectors/source-alpha-vantage/source_alpha_vantage/run.py index fe5a71ac01fb..e865183827a2 100644 --- a/airbyte-integrations/connectors/source-alpha-vantage/source_alpha_vantage/run.py +++ b/airbyte-integrations/connectors/source-alpha-vantage/source_alpha_vantage/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_alpha_vantage import SourceAlphaVantage +from airbyte_cdk.entrypoint import launch + def run(): source = SourceAlphaVantage() diff --git a/airbyte-integrations/connectors/source-alpha-vantage/source_alpha_vantage/source.py b/airbyte-integrations/connectors/source-alpha-vantage/source_alpha_vantage/source.py index e8cede80087d..7cec796ec207 100644 --- a/airbyte-integrations/connectors/source-alpha-vantage/source_alpha_vantage/source.py +++ b/airbyte-integrations/connectors/source-alpha-vantage/source_alpha_vantage/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-amazon-ads/.coveragerc b/airbyte-integrations/connectors/source-amazon-ads/.coveragerc new file mode 100644 index 000000000000..fefbd49b0c85 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/.coveragerc @@ -0,0 +1,3 @@ +[run] +omit = + source_amazon_ads/run.py \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-amazon-ads/acceptance-test-config.yml b/airbyte-integrations/connectors/source-amazon-ads/acceptance-test-config.yml index 2fda08b5232d..145492740f21 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-amazon-ads/acceptance-test-config.yml @@ -1,4 +1,22 @@ +connector_image: airbyte/source-amazon-ads:dev +test_strictness_level: high acceptance_tests: + spec: + tests: + - spec_path: integration_tests/spec.json + backward_compatibility_tests_config: + disable_for_version: 5.0.0 + connection: + tests: + - config_path: secrets/config.json + status: succeed + - config_path: integration_tests/invalid_config.json + status: exception + discovery: + tests: + - config_path: secrets/config.json + backward_compatibility_tests_config: + disable_for_version: 3.4.3 basic_read: tests: - config_path: secrets/config.json @@ -19,12 +37,8 @@ acceptance_tests: bypass_reason: "can't populate stream because it requires real ad campaign" - name: sponsored_display_report_stream bypass_reason: "can't populate stream because it requires real ad campaign" - - name: sponsored_brands_report_stream - bypass_reason: "can't populate stream because it requires real ad campaign" - name: sponsored_brands_v3_report_stream bypass_reason: "can't populate stream because it requires real ad campaign" - - name: sponsored_brands_video_report_stream - bypass_reason: "can't populate stream because it requires real ad campaign" - name: sponsored_products_report_stream bypass_reason: "can't populate stream because it requires real ad campaign" - name: sponsored_display_creatives @@ -34,17 +48,6 @@ acceptance_tests: timeout_seconds: 2400 expect_records: path: integration_tests/expected_records.jsonl - connection: - tests: - - config_path: secrets/config.json - status: succeed - - config_path: integration_tests/invalid_config.json - status: exception - discovery: - tests: - - config_path: secrets/config.json - backward_compatibility_tests_config: - disable_for_version: 3.4.3 full_refresh: tests: - config_path: secrets/config.json @@ -52,10 +55,3 @@ acceptance_tests: timeout_seconds: 3600 incremental: bypass_reason: "can't populate stream because it requires real ad campaign" - spec: - tests: - - spec_path: integration_tests/spec.json - backward_compatibility_tests_config: - disable_for_version: 5.0.0 -connector_image: airbyte/source-amazon-ads:dev -test_strictness_level: high diff --git a/airbyte-integrations/connectors/source-amazon-ads/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-amazon-ads/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-amazon-ads/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-amazon-ads/integration_tests/spec.json b/airbyte-integrations/connectors/source-amazon-ads/integration_tests/spec.json index 9e5131c4148d..f131594106f3 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/integration_tests/spec.json +++ b/airbyte-integrations/connectors/source-amazon-ads/integration_tests/spec.json @@ -1,11 +1,11 @@ { - "documentationUrl": "https://docs.airbyte.com/integrations/sources/amazon-ads", "connectionSpecification": { - "title": "Amazon Ads Spec", + "title": "Source Amazon Ads", "type": "object", "properties": { "auth_type": { "title": "Auth Type", + "default": "oauth2.0", "const": "oauth2.0", "order": 0, "type": "string" @@ -34,18 +34,18 @@ "region": { "title": "Region", "description": "Region to pull data from (EU/NA/FE). See docs for more details.", - "enum": ["NA", "EU", "FE"], - "type": "string", "default": "NA", - "order": 4 + "enum": ["NA", "EU", "FE"], + "order": 4, + "type": "string" }, "start_date": { "title": "Start Date", "description": "The Start date for collecting reports, should not be more than 60 days in the past. In YYYY-MM-DD format", "examples": ["2022-10-10", "2022-10-22"], + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$", "order": 5, "type": "string", - "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$", "format": "date" }, "profiles": { @@ -69,13 +69,16 @@ "state_filter": { "title": "State Filter", "description": "Reflects the state of the Display, Product, and Brand Campaign streams as enabled, paused, or archived. If you do not populate this field, it will be ignored completely.", + "default": [], + "order": 8, + "type": "array", "items": { - "type": "string", - "enum": ["enabled", "paused", "archived"] + "title": "StateFilterEnum", + "description": "An enumeration.", + "enum": ["enabled", "paused", "archived"], + "type": "string" }, - "type": "array", - "uniqueItems": true, - "order": 8 + "uniqueItems": true }, "look_back_window": { "title": "Look Back Window", @@ -88,8 +91,12 @@ "report_record_types": { "title": "Report Record Types", "description": "Optional configuration which accepts an array of string of record types. Leave blank for default behaviour to pull all report types. Use this config option only if you want to pull specific report type(s). See docs for more details", + "default": [], + "order": 10, + "type": "array", "items": { - "type": "string", + "title": "ReportRecordTypeEnum", + "description": "An enumeration.", "enum": [ "adGroups", "asins", @@ -99,16 +106,17 @@ "keywords", "productAds", "targets" - ] + ], + "type": "string" }, - "type": "array", - "uniqueItems": true, - "order": 10 + "uniqueItems": true } }, - "required": ["client_id", "client_secret", "refresh_token"], - "additionalProperties": true + "required": ["client_id", "client_secret", "refresh_token"] }, + "documentationUrl": "https://docs.airbyte.com/integrations/sources/amazon-ads", + "supportsNormalization": false, + "supportsDBT": false, "advanced_auth": { "auth_flow_type": "oauth2.0", "predicate_key": ["auth_type"], diff --git a/airbyte-integrations/connectors/source-amazon-ads/main.py b/airbyte-integrations/connectors/source-amazon-ads/main.py index 30a0b6957860..c85eb27fa106 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/main.py +++ b/airbyte-integrations/connectors/source-amazon-ads/main.py @@ -4,5 +4,6 @@ from source_amazon_ads.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-amazon-ads/metadata.yaml b/airbyte-integrations/connectors/source-amazon-ads/metadata.yaml index be3c1c29ceb3..ae52183c1f2f 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/metadata.yaml +++ b/airbyte-integrations/connectors/source-amazon-ads/metadata.yaml @@ -9,17 +9,19 @@ data: - advertising-api-eu.amazon.com - advertising-api-fe.amazon.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: c6b0a29e-1da9-4512-9002-7bfd0cba2246 - dockerImageTag: 5.0.20 + dockerImageTag: 6.2.4 dockerRepository: airbyte/source-amazon-ads documentationUrl: https://docs.airbyte.com/integrations/sources/amazon-ads githubIssueLabel: source-amazon-ads icon: amazonads.svg license: MIT - maxSecondsBetweenMessages: 5400 + # Based on https://advertising.amazon.com/API/docs/en-us/guides/reporting/v3/get-started#checking-report-status, report generation can take up to 3 hours + # We've added one minute on top of the three hours because of the waiting time before we poll the report status + maxSecondsBetweenMessages: 10860 name: Amazon Ads remoteRegistries: pypi: @@ -33,6 +35,18 @@ data: releaseStage: generally_available releases: breakingChanges: + 6.0.0: + message: + "The Report API V2 is being deprecated in favor of V3. Given this change, fields available through the sponsoredDisplayReportStream stream will change, + and streams `SponsoredBrandsReportStream` `SponsoredBrandsVideoReportStream` will become unavailable. We recommend using `SponsoredBrandsV3ReportStream` as an alternative stream with the same dataset." + upgradeDeadline: "2024-11-01" + deadlineAction: "auto_upgrade" + scopedImpact: + - scopeType: stream + impactedScopes: + - "sponsored_display_report_stream" + - "sponsored_brands_report_stream" + - "sponsored_brands_video_report_stream" 5.0.0: message: "`SponsoredBrandCampaigns`, `SponsoredBrandsAdGroups`, `SponsoredProductCampaigns`, and `SponsoredProductAdGroupBidRecommendations` streams have updated schemas and must be reset." upgradeDeadline: "2024-03-27" diff --git a/airbyte-integrations/connectors/source-amazon-ads/poetry.lock b/airbyte-integrations/connectors/source-amazon-ads/poetry.lock index d543f3a347cc..6b09e51b6bde 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/poetry.lock +++ b/airbyte-integrations/connectors/source-amazon-ads/poetry.lock @@ -2,105 +2,124 @@ [[package]] name = "airbyte-cdk" -version = "0.90.0" +version = "6.12.4" description = "A framework for writing Airbyte Connectors." optional = false -python-versions = "<4.0,>=3.9" +python-versions = "<3.13,>=3.10" files = [ - {file = "airbyte_cdk-0.90.0-py3-none-any.whl", hash = "sha256:bd0aa5843cdc4901f2e482f0e86695ca4e6db83b65c5017799255dd20535cf56"}, - {file = "airbyte_cdk-0.90.0.tar.gz", hash = "sha256:25cefc010718bada5cce3f87e7ae93068630732c0d34ce5145f8ddf7457d4d3c"}, + {file = "airbyte_cdk-6.12.4-py3-none-any.whl", hash = "sha256:903f2c2d3be4d6595bc6c50a4625e2551308d2ca90e021bf489e0a82cf0f965d"}, + {file = "airbyte_cdk-6.12.4.tar.gz", hash = "sha256:f9f39746dec5e01a9d37255cfb45a753953227b7aafebf8f5603a6e9f943b182"}, ] [package.dependencies] -airbyte-protocol-models = ">=0.9.0,<1.0" +airbyte-protocol-models-dataclasses = ">=0.14,<0.15" backoff = "*" cachetools = "*" -cryptography = ">=42.0.5,<43.0.0" -Deprecated = ">=1.2,<1.3" -dpath = ">=2.0.1,<2.1.0" -genson = "1.2.2" +cryptography = ">=42.0.5,<44.0.0" +dpath = ">=2.1.6,<3.0.0" +dunamai = ">=1.22.0,<2.0.0" +genson = "1.3.0" isodate = ">=0.6.1,<0.7.0" Jinja2 = ">=3.1.2,<3.2.0" jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" +jsonschema = ">=4.17.3,<4.18.0" langchain_core = "0.1.42" +nltk = "3.9.1" +numpy = "<2" +orjson = ">=3.10.7,<4.0.0" +pandas = "2.2.2" pendulum = "<3.0.0" -pydantic = ">=1.10.8,<2.0.0" +psutil = "6.1.0" +pydantic = ">=2.7,<3.0" pyjwt = ">=2.8.0,<3.0.0" pyrate-limiter = ">=3.1.0,<3.2.0" python-dateutil = "*" -pytz = "2024.1" +python-ulid = ">=3.0.0,<4.0.0" +pytz = "2024.2" PyYAML = ">=6.0.1,<7.0.0" +rapidfuzz = ">=3.10.1,<4.0.0" requests = "*" requests_cache = "*" -wcmatch = "8.4" +serpyco-rs = ">=1.10.2,<2.0.0" +Unidecode = ">=1.3,<2.0" +wcmatch = "10.0" +xmltodict = ">=0.13.0,<0.14.0" [package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] +file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "python-snappy (==0.7.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] +sql = ["sqlalchemy (>=2.0,!=2.0.36,<3.0)"] +vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.8.0)"] [[package]] -name = "airbyte-protocol-models" -version = "0.13.0" -description = "Declares the Airbyte Protocol." +name = "airbyte-protocol-models-dataclasses" +version = "0.14.1" +description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models_dataclasses-0.14.1-py3-none-any.whl", hash = "sha256:dfe10b32ee09e6ba9b4f17bd309e841b61cbd61ec8f80b1937ff104efd6209a9"}, + {file = "airbyte_protocol_models_dataclasses-0.14.1.tar.gz", hash = "sha256:f62a46556b82ea0d55de144983141639e8049d836dd4e0a9d7234c5b2e103c08"}, ] -[package.dependencies] -pydantic = ">=1.9.2,<2.0.0" +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." +name = "attributes-doc" +version = "0.4.0" +description = "PEP 224 implementation" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.8" files = [ - {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, + {file = "attributes-doc-0.4.0.tar.gz", hash = "sha256:b1576c94a714e9fc2c65c47cf10d0c8e1a5f7c4f5ae7f69006be108d95cbfbfb"}, + {file = "attributes_doc-0.4.0-py2.py3-none-any.whl", hash = "sha256:4c3007d9e58f3a6cb4b9c614c4d4ce2d92161581f28e594ddd8241cc3a113bdd"}, ] [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -166,13 +185,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -256,118 +275,119 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, +] + +[[package]] +name = "click" +version = "8.1.8" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + [[package]] name = "colorama" version = "0.4.6" @@ -381,43 +401,38 @@ files = [ [[package]] name = "cryptography" -version = "42.0.8" +version = "43.0.3" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, + {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, + {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, + {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, + {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, + {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, + {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, + {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, ] [package.dependencies] @@ -430,37 +445,34 @@ nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] [[package]] -name = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." +name = "dpath" +version = "2.2.0" +description = "Filesystem-like pathing and searching for dictionaries" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "dpath-2.2.0-py3-none-any.whl", hash = "sha256:b330a375ded0a0d2ed404440f6c6a715deae5313af40bbb01c8a41d891900576"}, + {file = "dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e"}, ] -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - [[package]] -name = "dpath" -version = "2.0.8" -description = "Filesystem-like pathing and searching for dictionaries" +name = "dunamai" +version = "1.23.0" +description = "Dynamic version generation" optional = false -python-versions = ">=3.7" +python-versions = ">=3.5" files = [ - {file = "dpath-2.0.8-py3-none-any.whl", hash = "sha256:f92f595214dd93a00558d75d4b858beee519f4cffca87f02616ad6cd013f3436"}, - {file = "dpath-2.0.8.tar.gz", hash = "sha256:a3440157ebe80d0a3ad794f1b61c571bef125214800ffdb9afc9424e8250fe9b"}, + {file = "dunamai-1.23.0-py3-none-any.whl", hash = "sha256:a0906d876e92441793c6a423e16a4802752e723e9c9a5aabdc5535df02dbe041"}, + {file = "dunamai-1.23.0.tar.gz", hash = "sha256:a163746de7ea5acb6dacdab3a6ad621ebc612ed1e528aaa8beedb8887fccd2c4"}, ] +[package.dependencies] +packaging = ">=20.9" + [[package]] name = "exceptiongroup" version = "1.2.2" @@ -491,12 +503,13 @@ python-dateutil = ">=2.7" [[package]] name = "genson" -version = "1.2.2" +version = "1.3.0" description = "GenSON is a powerful, user-friendly JSON Schema generator." optional = false python-versions = "*" files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, + {file = "genson-1.3.0-py3-none-any.whl", hash = "sha256:468feccd00274cc7e4c09e84b08704270ba8d95232aa280f65b986139cec67f7"}, + {file = "genson-1.3.0.tar.gz", hash = "sha256:e02db9ac2e3fd29e65b5286f7135762e2cd8a986537c075b06fc5f1517308e37"}, ] [[package]] @@ -512,13 +525,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -533,13 +546,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -547,7 +560,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -597,13 +609,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -612,6 +624,17 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "joblib" +version = "1.4.2" +description = "Lightweight pipelining with Python functions" +optional = false +python-versions = ">=3.8" +files = [ + {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, + {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, +] + [[package]] name = "jsonpatch" version = "1.33" @@ -650,24 +673,22 @@ files = [ [[package]] name = "jsonschema" -version = "3.2.0" +version = "4.17.3" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, ] [package.dependencies] attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" [package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] [[package]] name = "langchain-core" @@ -693,22 +714,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -780,86 +804,157 @@ files = [ ] [[package]] -name = "oauthlib" -version = "3.2.2" -description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" +name = "nltk" +version = "3.9.1" +description = "Natural Language Toolkit" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, - {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, + {file = "nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1"}, + {file = "nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868"}, ] +[package.dependencies] +click = "*" +joblib = "*" +regex = ">=2021.8.3" +tqdm = "*" + [package.extras] -rsa = ["cryptography (>=3.0.0)"] -signals = ["blinker (>=1.4.0)"] -signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] +all = ["matplotlib", "numpy", "pyparsing", "python-crfsuite", "requests", "scikit-learn", "scipy", "twython"] +corenlp = ["requests"] +machine-learning = ["numpy", "python-crfsuite", "scikit-learn", "scipy"] +plot = ["matplotlib"] +tgrep = ["pyparsing"] +twitter = ["twython"] + +[[package]] +name = "numpy" +version = "1.26.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, +] [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -873,6 +968,78 @@ files = [ {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] +[[package]] +name = "pandas" +version = "2.2.2" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + [[package]] name = "pendulum" version = "2.1.2" @@ -939,16 +1106,35 @@ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] [[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" +name = "psutil" +version = "6.1.0" +description = "Cross-platform lib for process and system monitoring in Python." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, ] +[package.extras] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + [[package]] name = "pycparser" version = "2.22" @@ -962,72 +1148,145 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" -description = "Data validation and settings management using python type hints" +version = "2.10.4" +description = "Data validation using Python type hints" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] -typing-extensions = ">=4.2.0" +annotated-types = ">=0.6.0" +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] +email = ["email-validator (>=2.0.0)"] +timezone = ["tzdata"] + +[[package]] +name = "pydantic-core" +version = "2.27.2" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1094,27 +1353,25 @@ files = [ [[package]] name = "pytest" -version = "6.2.5" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" +pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-mock" @@ -1147,15 +1404,29 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "python-ulid" +version = "3.0.0" +description = "Universally unique lexicographically sortable identifier" +optional = false +python-versions = ">=3.9" +files = [ + {file = "python_ulid-3.0.0-py3-none-any.whl", hash = "sha256:e4c4942ff50dbd79167ad01ac725ec58f924b4018025ce22c858bfcff99a5e31"}, + {file = "python_ulid-3.0.0.tar.gz", hash = "sha256:e50296a47dc8209d28629a22fc81ca26c00982c78934bd7766377ba37ea49a9f"}, +] + +[package.extras] +pydantic = ["pydantic (>=2.0)"] + [[package]] name = "pytz" -version = "2024.1" +version = "2024.2" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, + {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, + {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, ] [[package]] @@ -1231,6 +1502,209 @@ files = [ {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] +[[package]] +name = "rapidfuzz" +version = "3.11.0" +description = "rapid fuzzy string matching" +optional = false +python-versions = ">=3.9" +files = [ + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eb8a54543d16ab1b69e2c5ed96cabbff16db044a50eddfc028000138ca9ddf33"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:231c8b2efbd7f8d2ecd1ae900363ba168b8870644bb8f2b5aa96e4a7573bde19"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54e7f442fb9cca81e9df32333fb075ef729052bcabe05b0afc0441f462299114"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:906f1f2a1b91c06599b3dd1be207449c5d4fc7bd1e1fa2f6aef161ea6223f165"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed59044aea9eb6c663112170f2399b040d5d7b162828b141f2673e822093fa8"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cb1965a28b0fa64abdee130c788a0bc0bb3cf9ef7e3a70bf055c086c14a3d7e"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b488b244931d0291412917e6e46ee9f6a14376625e150056fe7c4426ef28225"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f0ba13557fec9d5ffc0a22826754a7457cc77f1b25145be10b7bb1d143ce84c6"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3871fa7dfcef00bad3c7e8ae8d8fd58089bad6fb21f608d2bf42832267ca9663"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b2669eafee38c5884a6e7cc9769d25c19428549dcdf57de8541cf9e82822e7db"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ffa1bb0e26297b0f22881b219ffc82a33a3c84ce6174a9d69406239b14575bd5"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:45b15b8a118856ac9caac6877f70f38b8a0d310475d50bc814698659eabc1cdb"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win32.whl", hash = "sha256:22033677982b9c4c49676f215b794b0404073f8974f98739cb7234e4a9ade9ad"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:be15496e7244361ff0efcd86e52559bacda9cd975eccf19426a0025f9547c792"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_arm64.whl", hash = "sha256:714a7ba31ba46b64d30fccfe95f8013ea41a2e6237ba11a805a27cdd3bce2573"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8724a978f8af7059c5323d523870bf272a097478e1471295511cf58b2642ff83"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b63cb1f2eb371ef20fb155e95efd96e060147bdd4ab9fc400c97325dfee9fe1"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82497f244aac10b20710448645f347d862364cc4f7d8b9ba14bd66b5ce4dec18"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:339607394941801e6e3f6c1ecd413a36e18454e7136ed1161388de674f47f9d9"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84819390a36d6166cec706b9d8f0941f115f700b7faecab5a7e22fc367408bc3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eea8d9e20632d68f653455265b18c35f90965e26f30d4d92f831899d6682149b"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b659e1e2ea2784a9a397075a7fc395bfa4fe66424042161c4bcaf6e4f637b38"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1315cd2a351144572e31fe3df68340d4b83ddec0af8b2e207cd32930c6acd037"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a7743cca45b4684c54407e8638f6d07b910d8d811347b9d42ff21262c7c23245"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:5bb636b0150daa6d3331b738f7c0f8b25eadc47f04a40e5c23c4bfb4c4e20ae3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:42f4dd264ada7a9aa0805ea0da776dc063533917773cf2df5217f14eb4429eae"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:51f24cb39e64256221e6952f22545b8ce21cacd59c0d3e367225da8fc4b868d8"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win32.whl", hash = "sha256:aaf391fb6715866bc14681c76dc0308f46877f7c06f61d62cc993b79fc3c4a2a"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:ebadd5b8624d8ad503e505a99b8eb26fe3ea9f8e9c2234e805a27b269e585842"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:d895998fec712544c13cfe833890e0226585cf0391dd3948412441d5d68a2b8c"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f382fec4a7891d66fb7163c90754454030bb9200a13f82ee7860b6359f3f2fa8"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dfaefe08af2a928e72344c800dcbaf6508e86a4ed481e28355e8d4b6a6a5230e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92ebb7c12f682b5906ed98429f48a3dd80dd0f9721de30c97a01473d1a346576"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a1b3ebc62d4bcdfdeba110944a25ab40916d5383c5e57e7c4a8dc0b6c17211a"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c6d7fea39cb33e71de86397d38bf7ff1a6273e40367f31d05761662ffda49e4"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99aebef8268f2bc0b445b5640fd3312e080bd17efd3fbae4486b20ac00466308"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4469307f464ae3089acf3210b8fc279110d26d10f79e576f385a98f4429f7d97"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:eb97c53112b593f89a90b4f6218635a9d1eea1d7f9521a3b7d24864228bbc0aa"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef8937dae823b889c0273dfa0f0f6c46a3658ac0d851349c464d1b00e7ff4252"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d95f9e9f3777b96241d8a00d6377cc9c716981d828b5091082d0fe3a2924b43e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:b1d67d67f89e4e013a5295e7523bc34a7a96f2dba5dd812c7c8cb65d113cbf28"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d994cf27e2f874069884d9bddf0864f9b90ad201fcc9cb2f5b82bacc17c8d5f2"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win32.whl", hash = "sha256:ba26d87fe7fcb56c4a53b549a9e0e9143f6b0df56d35fe6ad800c902447acd5b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:b1f7efdd7b7adb32102c2fa481ad6f11923e2deb191f651274be559d56fc913b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:ed78c8e94f57b44292c1a0350f580e18d3a3c5c0800e253f1583580c1b417ad2"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e60814edd0c9b511b5f377d48b9782b88cfe8be07a98f99973669299c8bb318a"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f28952da055dbfe75828891cd3c9abf0984edc8640573c18b48c14c68ca5e06"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e8f93bc736020351a6f8e71666e1f486bb8bd5ce8112c443a30c77bfde0eb68"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76a4a11ba8f678c9e5876a7d465ab86def047a4fcc043617578368755d63a1bc"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc0e0d41ad8a056a9886bac91ff9d9978e54a244deb61c2972cc76b66752de9c"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e8ea35f2419c7d56b3e75fbde2698766daedb374f20eea28ac9b1f668ef4f74"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd340bbd025302276b5aa221dccfe43040c7babfc32f107c36ad783f2ffd8775"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:494eef2c68305ab75139034ea25328a04a548d297712d9cf887bf27c158c388b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5a167344c1d6db06915fb0225592afdc24d8bafaaf02de07d4788ddd37f4bc2f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8c7af25bda96ac799378ac8aba54a8ece732835c7b74cfc201b688a87ed11152"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d2a0f7e17f33e7890257367a1662b05fecaf56625f7dbb6446227aaa2b86448b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4d0d26c7172bdb64f86ee0765c5b26ea1dc45c52389175888ec073b9b28f4305"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win32.whl", hash = "sha256:6ad02bab756751c90fa27f3069d7b12146613061341459abf55f8190d899649f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:b1472986fd9c5d318399a01a0881f4a0bf4950264131bb8e2deba9df6d8c362b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:c408f09649cbff8da76f8d3ad878b64ba7f7abdad1471efb293d2c075e80c822"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1bac4873f6186f5233b0084b266bfb459e997f4c21fc9f029918f44a9eccd304"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f9f12c2d0aa52b86206d2059916153876a9b1cf9dfb3cf2f344913167f1c3d4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd501de6f7a8f83557d20613b58734d1cb5f0be78d794cde64fe43cfc63f5f2"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4416ca69af933d4a8ad30910149d3db6d084781d5c5fdedb713205389f535385"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f0821b9bdf18c5b7d51722b906b233a39b17f602501a966cfbd9b285f8ab83cd"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0edecc3f90c2653298d380f6ea73b536944b767520c2179ec5d40b9145e47aa"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4513dd01cee11e354c31b75f652d4d466c9440b6859f84e600bdebfccb17735a"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d9727b85511b912571a76ce53c7640ba2c44c364e71cef6d7359b5412739c570"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ab9eab33ee3213f7751dc07a1a61b8d9a3d748ca4458fffddd9defa6f0493c16"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:6b01c1ddbb054283797967ddc5433d5c108d680e8fa2684cf368be05407b07e4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:3857e335f97058c4b46fa39ca831290b70de554a5c5af0323d2f163b19c5f2a6"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d98a46cf07c0c875d27e8a7ed50f304d83063e49b9ab63f21c19c154b4c0d08d"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win32.whl", hash = "sha256:c36539ed2c0173b053dafb221458812e178cfa3224ade0960599bec194637048"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:ec8d7d8567e14af34a7911c98f5ac74a3d4a743cd848643341fc92b12b3784ff"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_arm64.whl", hash = "sha256:62171b270ecc4071be1c1f99960317db261d4c8c83c169e7f8ad119211fe7397"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f06e3c4c0a8badfc4910b9fd15beb1ad8f3b8fafa8ea82c023e5e607b66a78e4"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fe7aaf5a54821d340d21412f7f6e6272a9b17a0cbafc1d68f77f2fc11009dcd5"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25398d9ac7294e99876a3027ffc52c6bebeb2d702b1895af6ae9c541ee676702"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a52eea839e4bdc72c5e60a444d26004da00bb5bc6301e99b3dde18212e41465"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c87319b0ab9d269ab84f6453601fd49b35d9e4a601bbaef43743f26fabf496c"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3048c6ed29d693fba7d2a7caf165f5e0bb2b9743a0989012a98a47b975355cca"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b04f29735bad9f06bb731c214f27253bd8bedb248ef9b8a1b4c5bde65b838454"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7864e80a0d4e23eb6194254a81ee1216abdc53f9dc85b7f4d56668eced022eb8"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3794df87313dfb56fafd679b962e0613c88a293fd9bd5dd5c2793d66bf06a101"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d71da0012face6f45432a11bc59af19e62fac5a41f8ce489e80c0add8153c3d1"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff38378346b7018f42cbc1f6d1d3778e36e16d8595f79a312b31e7c25c50bd08"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6668321f90aa02a5a789d4e16058f2e4f2692c5230252425c3532a8a62bc3424"}, + {file = "rapidfuzz-3.11.0.tar.gz", hash = "sha256:a53ca4d3f52f00b393fab9b5913c5bafb9afc27d030c8a1db1283da6917a860f"}, +] + +[package.extras] +all = ["numpy"] + +[[package]] +name = "regex" +version = "2024.11.6" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.8" +files = [ + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, +] + [[package]] name = "requests" version = "2.32.3" @@ -1299,24 +1773,6 @@ requests = ">=2.22,<3" [package.extras] fixture = ["fixtures"] -[[package]] -name = "requests-oauthlib" -version = "1.3.1" -description = "OAuthlib authentication support for Requests." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, - {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"}, -] - -[package.dependencies] -oauthlib = ">=3.0.0" -requests = ">=2.0.0" - -[package.extras] -rsa = ["oauthlib[signedtoken] (>=3.0.0)"] - [[package]] name = "requests-toolbelt" version = "1.0.0" @@ -1333,53 +1789,86 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "responses" -version = "0.23.3" +version = "0.25.3" description = "A utility library for mocking out the `requests` Python library." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "responses-0.23.3-py3-none-any.whl", hash = "sha256:e6fbcf5d82172fecc0aa1860fd91e58cbfd96cee5e96da5b63fa6eb3caa10dd3"}, - {file = "responses-0.23.3.tar.gz", hash = "sha256:205029e1cb334c21cb4ec64fc7599be48b859a0fd381a42443cdd600bfe8b16a"}, + {file = "responses-0.25.3-py3-none-any.whl", hash = "sha256:521efcbc82081ab8daa588e08f7e8a64ce79b91c39f6e62199b19159bea7dbcb"}, + {file = "responses-0.25.3.tar.gz", hash = "sha256:617b9247abd9ae28313d57a75880422d55ec63c29d33d629697590a034358dba"}, ] [package.dependencies] pyyaml = "*" requests = ">=2.30.0,<3.0" -types-PyYAML = "*" urllib3 = ">=1.25.10,<3.0" [package.extras] -tests = ["coverage (>=6.0.0)", "flake8", "mypy", "pytest (>=7.0.0)", "pytest-asyncio", "pytest-cov", "pytest-httpserver", "tomli", "tomli-w", "types-requests"] +tests = ["coverage (>=6.0.0)", "flake8", "mypy", "pytest (>=7.0.0)", "pytest-asyncio", "pytest-cov", "pytest-httpserver", "tomli", "tomli-w", "types-PyYAML", "types-requests"] [[package]] -name = "setuptools" -version = "75.3.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" +name = "serpyco-rs" +version = "1.11.0" +description = "" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4b2bd933539bd8c84315e2fb5ae52ef7a58ace5a6dfe3f8b73f74dc71216779e"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:627f957889ff73c4d2269fc7b6bba93212381befe03633e7cb5495de66ba9a33"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b0933620abc01434023e0e3e22255b7e4ab9b427b5a9a5ee00834656d792377a"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9ce46683d92e34abb20304817fc5ac6cb141a06fc7468dedb1d8865a8a9682f6"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bda437d86e8859bf91c189c1f4650899822f6d6d7b02b48f5729da904eb7bb7d"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a72bfbd282af17ebe76d122639013e802c09902543fdbbd828fb2159ec9755e"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d4808df5384e3e8581e31a90ba7a1fa501c0837b1f174284bb8a4555b6864ea"}, + {file = "serpyco_rs-1.11.0-cp310-none-win_amd64.whl", hash = "sha256:c7b60aef4c16d68efb0d6241f05d0a434d873d98449cbb4366b0d385f0a7172b"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d47ee577cf4d69b53917615cb031ad8708eb2f59fe78194b1968c13130fc2f7"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6090d9a1487237cdd4e9362a823eede23249602019b917e7bd57846179286e79"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7192eb3df576386fefd595ea31ae25c62522841ffec7e7aeb37a80b55bdc3213"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b52ef8affb7e71b9b98a7d5216d6a7ad03b04e990acb147cd9211c8b931c5487"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3480e09e473560c60e74aaa789e6b4d079637371aae0a98235440111464bbba7"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c92e36b0ab6fe866601c2331f7e99c809a126d21963c03d8a5c29331526deed"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84f497361952d4566bc1f77e9e15a84a2614f593cc671fbf0a0fa80046f9c3d7"}, + {file = "serpyco_rs-1.11.0-cp311-none-win_amd64.whl", hash = "sha256:37fc1cf192bef9784fbf1f4e03cec21750b9e704bef55cc0442f71a715eee920"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3ea93d485f03dc8b0cfb0d477f0ad2e86e78f0461b53010656ab5b4db1b41fb0"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7772410d15694b03f9c5500a2c47d62eed76e191bea4087ad042250346b1a38e"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42118463c1679846cffd2f06f47744c9b9eb33c5d0448afd88ea19e1a81a8ddd"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:79481a455b76cc56021dc55bb6d5bdda1b2b32bcb6a1ee711b597140d112e9b1"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8fd79051f9af9591fc03cf7d3033ff180416301f6a4fd3d1e3d92ebd2d68697"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d29c8f9aeed734a3b51f7349d04ec9063516ffa4e10b632d75e9b1309e4930e4"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15609158b0d9591ffa118302cd9d0039970cb3faf91dce32975f7d276e7411d5"}, + {file = "serpyco_rs-1.11.0-cp312-none-win_amd64.whl", hash = "sha256:00081eae77fbf4c5d88371c5586317ab02ccb293a330b460869a283edf2b7b69"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3028893366a1985adcedb13fa8f6f98c087c185efc427f94c2ccdafa40f45832"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c18bf511316f3abf648a68ee62ef88617bec57d3fcde69466b4361102715ae5"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7dde9ef09cdfaf7c62378186b9e29f54ec76114be4c347be6a06dd559c5681e"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:18500ebc5e75285841e35585a238629a990b709e14f68933233640d15ca17d5f"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47c23132d4e03982703a7630aa09877b41e499722142f76b6153f6619b612f3"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5f8e6ba499f6a0825bee0d8f8764569d367af871b563fc6512c171474e8e5383"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15438a076047c34cff6601a977df54948e8d39d1a86f89d05c48bc60f4c12a61"}, + {file = "serpyco_rs-1.11.0-cp313-none-win_amd64.whl", hash = "sha256:84ee2c109415bd81904fc9abb9aec86a5dd13166808c21142cf23ec639f683bd"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5c97c16c865261577fac4effeccc7ef5e0a1e8e35e7a3ee6c90c77c3a4cd7ff9"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47825e70f86fd6ef7c4a835dea3d6e8eef4fee354ed7b39ced99f31aba74a86e"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24d220220365110edba2f778f41ab3cf396883da0f26e1361a3ada9bd0227f73"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3a46f334af5a9d77acc6e1e58f355ae497900a2798929371f0545e274f6e6166"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d72b748acce4b4e3c7c9724e1eb33d033a1c26b08a698b393e0288060e0901"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2b8b6f205e8cc038d4d30dd0e70eece7bbecc816eb2f3787c330dc2218e232d"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:038d748bfff31f150f0c3edab2766b8843edb952cb1bd3bf547886beb0912dae"}, + {file = "serpyco_rs-1.11.0-cp39-none-win_amd64.whl", hash = "sha256:0fee1c89ec2cb013dc232e4ebef88e2844357ce8631063b56639dbfb83762f20"}, + {file = "serpyco_rs-1.11.0.tar.gz", hash = "sha256:70a844615ffb229e6e89c204b3ab7404aacaf2838911814c7d847969b8da2e3a"}, ] -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +[package.dependencies] +attributes-doc = "*" +typing-extensions = "*" [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1409,27 +1898,67 @@ doc = ["reno", "sphinx"] test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" +name = "tomli" +version = "2.2.1" +description = "A lil' TOML parser" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = ">=3.8" files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] - -[[package]] -name = "types-pyyaml" -version = "6.0.12.20240917" -description = "Typing stubs for PyYAML" + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, +] + +[[package]] +name = "tqdm" +version = "4.67.1" +description = "Fast, Extensible Progress Meter" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "types-PyYAML-6.0.12.20240917.tar.gz", hash = "sha256:d1405a86f9576682234ef83bcb4e6fff7c9305c8b1fbad5e0bcd4f7dbdc9c587"}, - {file = "types_PyYAML-6.0.12.20240917-py3-none-any.whl", hash = "sha256:392b267f1c0fe6022952462bf5d6523f31e37f6cea49b14cee7ad634b6301570"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + [[package]] name = "typing-extensions" version = "4.12.2" @@ -1441,6 +1970,28 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] +[[package]] +name = "tzdata" +version = "2024.2" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, + {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, +] + +[[package]] +name = "unidecode" +version = "1.3.8" +description = "ASCII transliterations of Unicode text" +optional = false +python-versions = ">=3.5" +files = [ + {file = "Unidecode-1.3.8-py3-none-any.whl", hash = "sha256:d130a61ce6696f8148a3bd8fe779c99adeb4b870584eeb9526584e9aa091fd39"}, + {file = "Unidecode-1.3.8.tar.gz", hash = "sha256:cfdb349d46ed3873ece4586b96aa75258726e2fa8ec21d6f00a591d98806c2f4"}, +] + [[package]] name = "url-normalize" version = "1.4.3" @@ -1457,13 +2008,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1474,98 +2025,30 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "wcmatch" -version = "8.4" +version = "10.0" description = "Wildcard/glob file name matcher." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, + {file = "wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a"}, + {file = "wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a"}, ] [package.dependencies] bracex = ">=2.1.1" [[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." +name = "xmltodict" +version = "0.13.0" +description = "Makes working with XML feel like you are working with JSON" optional = false -python-versions = ">=3.6" +python-versions = ">=3.4" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "xmltodict-0.13.0-py2.py3-none-any.whl", hash = "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"}, + {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"}, ] [metadata] lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "c1d7d10e74c03b6519d821cb3006edf3dacb1540e35960f1fdbbef10d2c5334e" +python-versions = "^3.10,<3.12" +content-hash = "1483a2a0463fcf5b5880b9e0ac76d387e082dc41302e63c7207c7e0385d02157" diff --git a/airbyte-integrations/connectors/source-amazon-ads/pyproject.toml b/airbyte-integrations/connectors/source-amazon-ads/pyproject.toml index 848e63533431..88f991092fb4 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/pyproject.toml +++ b/airbyte-integrations/connectors/source-amazon-ads/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "5.0.20" +version = "6.2.4" name = "source-amazon-ads" description = "Source implementation for Amazon Ads." authors = [ "Airbyte ",] @@ -16,17 +16,14 @@ repository = "https://github.com/airbytehq/airbyte" include = "source_amazon_ads" [tool.poetry.dependencies] -python = "^3.9,<3.12" -requests-oauthlib = "==1.3.1" -airbyte-cdk = "0.90.0" -pendulum = "==2.1.2" +python = "^3.10,<3.12" +airbyte-cdk = "^6" [tool.poetry.scripts] source-amazon-ads = "source_amazon_ads.run:run" [tool.poetry.group.dev.dependencies] -responses = "^0.23.1" -freezegun = "^1.2.0" -requests-mock = "^1.9.3" -pytest-mock = "^3.7.0" -pytest = "^6.1" +responses = "^0.25" +freezegun = "*" +requests-mock = "*" +pytest-mock = "*" diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/config_migrations.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/config_migrations.py index dda920775164..e5bebdddd0ba 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/config_migrations.py +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/config_migrations.py @@ -6,11 +6,12 @@ import logging from typing import Any, List, Mapping -from airbyte_cdk.config_observation import create_connector_config_control_message +from airbyte_cdk.config_observation import emit_configuration_as_airbyte_control_message from airbyte_cdk.entrypoint import AirbyteEntrypoint from airbyte_cdk.sources import Source from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository + logger = logging.getLogger("airbyte_logger") @@ -72,18 +73,6 @@ def modify_and_save(cls, config_path: str, source: Source, config: Mapping[str, source.write_config(migrated_config, config_path) return migrated_config - @classmethod - def emit_control_message(cls, migrated_config: Mapping[str, Any]) -> None: - """ - Emits the control messages related to configuration migration. - - Args: - - migrated_config (Mapping[str, Any]): The migrated configuration. - """ - cls.message_repository.emit_message(create_connector_config_control_message(migrated_config)) - for message in cls.message_repository._message_queue: - print(message.json(exclude_unset=True)) - @classmethod def migrate(cls, args: List[str], source: Source) -> None: """ @@ -101,4 +90,4 @@ def migrate(cls, args: List[str], source: Source) -> None: if config_path: config = source.read_config(config_path) if cls.should_migrate(config): - cls.emit_control_message(cls.modify_and_save(config_path, source, config)) + emit_configuration_as_airbyte_control_message(cls.modify_and_save(config_path, source, config)) diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/declarative_source_adapter.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/declarative_source_adapter.py deleted file mode 100644 index 6b46127b0b6b..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/declarative_source_adapter.py +++ /dev/null @@ -1,48 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - - -from logging import Logger -from typing import Any, List, Mapping - -from airbyte_cdk.models import AirbyteConnectionStatus -from airbyte_cdk.sources import AbstractSource -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource -from airbyte_cdk.sources.streams import Stream -from airbyte_protocol.models import ConnectorSpecification - - -class DeclarativeSourceAdapter(YamlDeclarativeSource): - def __init__(self, source: AbstractSource) -> None: - self._source = source - super().__init__(path_to_yaml="manifest.yaml") - self._set_adapted_methods() - - @property - def name(self) -> str: - return self._source.name - - def spec(self, logger: Logger) -> ConnectorSpecification: - return self._source.spec(logger) - - def check(self, logger: Logger, config: Mapping[str, Any]) -> AirbyteConnectionStatus: - return self._source.check(logger, config) - - def streams(self, config: Mapping[str, Any]) -> List[Stream]: - return self._source.streams(config) - - def _validate_source(self) -> None: - """Skipping manifest validation as it can be incomplete when use adapter""" - return - - def _set_adapted_methods(self) -> None: - """ - Since the adapter is intended to smoothly migrate the connector, - this method determines whether each of methods `spec`, `check`, and `streams` was declared in the manifest file - and if yes, makes the source use it, otherwise the method defined in the source will be used - """ - adapted_methods = ("spec", "check", "streams") - for method in adapted_methods: - if method in self.resolved_manifest: - self._source.__setattr__(method, getattr(super(), method)) diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/manifest.yaml b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/manifest.yaml index 5bfd063c9346..721374bf3144 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/manifest.yaml +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/manifest.yaml @@ -1,168 +1,1204 @@ -version: 0.60.1 -type: source_amazon_ads.SourceAmazonAds -spec: - type: Spec - documentation_url: https://docs.airbyte.com/integrations/sources/amazon-ads - connection_specification: - title: Amazon Ads Spec - type: object - properties: - auth_type: - title: Auth Type - const: oauth2.0 - order: 0 - type: string - client_id: - title: Client ID - description: - The client ID of your Amazon Ads developer application. See the - docs - for more information. - order: 1 - type: string - airbyte_secret: true - client_secret: - title: Client Secret - description: - The client secret of your Amazon Ads developer application. See - the docs - for more information. - airbyte_secret: true - order: 2 - type: string - refresh_token: - title: Refresh Token - description: - Amazon Ads refresh token. See the docs - for more information on how to obtain this token. - airbyte_secret: true - order: 3 - type: string - region: - title: Region - description: - Region to pull data from (EU/NA/FE). See docs - for more details. - enum: - - NA - - EU - - FE - type: string - default: NA - order: 4 - start_date: - title: Start Date - description: - The Start date for collecting reports, should not be more than - 60 days in the past. In YYYY-MM-DD format - pattern: "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" - format: date - examples: - - "2022-10-10" - - "2022-10-22" - order: 5 - type: string - profiles: - title: Profile IDs - description: 'Profile IDs you want to fetch data for. The Amazon Ads source connector supports only profiles with seller and vendor type, profiles with agency type will be ignored. See docs for more details. Note: If Marketplace IDs are also selected, profiles will be selected if they match the Profile ID OR the Marketplace ID.' - order: 6 - type: array - items: - type: integer - marketplace_ids: - title: Marketplace IDs - description: "Marketplace IDs you want to fetch data for. Note: If Profile IDs are also selected, profiles will be selected if they match the Profile ID OR the Marketplace ID." - order: 7 - type: array - items: - type: string - state_filter: - title: State Filter - description: Reflects the state of the Display, Product, and Brand Campaign streams as enabled, paused, or archived. If you do not populate this field, it will be ignored completely. - items: - type: string - enum: - - enabled - - paused - - archived - type: array - uniqueItems: true - order: 8 - look_back_window: - title: "Look Back Window" - description: "The amount of days to go back in time to get the updated data from Amazon Ads" - examples: - - 3 - - 10 - type: "integer" - default: 3 - order: 9 - report_record_types: - title: Report Record Types - description: - Optional configuration which accepts an array of string of record types. - Leave blank for default behaviour to pull all report types. - Use this config option only if you want to pull specific report type(s). - See docs - for more details - items: - type: string - enum: - - adGroups - - asins - - asins_keywords - - asins_targets - - campaigns - - keywords - - productAds - - targets - type: array - uniqueItems: true - order: 10 - required: - - client_id - - client_secret - - refresh_token - additionalProperties: true - advanced_auth: - auth_flow_type: oauth2.0 - predicate_key: - - auth_type - predicate_value: oauth2.0 - oauth_config_specification: - oauth_user_input_from_connector_config_specification: - type: object - additionalProperties: false - properties: - region: - type: string - path_in_connector_config: - - region - complete_oauth_output_specification: - type: object - additionalProperties: true - properties: - refresh_token: - type: string - path_in_connector_config: - - refresh_token - complete_oauth_server_input_specification: - type: object - additionalProperties: true - properties: - client_id: - type: string - client_secret: - type: string - complete_oauth_server_output_specification: - type: object - additionalProperties: true - properties: - client_id: - type: string - path_in_connector_config: - - client_id - client_secret: - type: string - path_in_connector_config: - - client_secret +version: 6.1.0 + +type: DeclarativeSource + +check: + type: CheckStream + stream_names: + - streams + +definitions: + sponsored_product_ad_group_error_handler: + type: DefaultErrorHandler + # max_retries: 5 + response_filters: + - http_codes: [400] + action: IGNORE + error_message: "Skip current AdGroup because it does not support request {response.request.url} for current profile" + - http_codes: [422] + action: IGNORE + error_message: "Skip current AdGroup because the ad group {json.loads(response.request.body)['adGroupId']} does not have any asins" + - http_codes: [404] + action: IGNORE + error_message: "Skip current AdGroup because the specified ad group has no associated bid" + + basic_error_handler: + type: DefaultErrorHandler + response_filters: + - predicate: "{{ 'message' in response }}" + action: FAIL + error_message: "{{ response.message }}" + - predicate: "{{ 'code' in response and 'details' in response }}" + action: IGNORE + error_message: "{{ response.code }}; {{ response.details }}" + + oauth_authenticator: + type: OAuthAuthenticator + refresh_request_body: {} + token_refresh_endpoint: "https://api.amazon.com/auth/o2/token" + grant_type: refresh_token + client_id: '{{ config["client_id"] }}' + client_secret: '{{ config["client_secret"] }}' + refresh_token: '{{ config["refresh_token"] }}' + base_requester: + type: HttpRequester + url_base: >- + {%- set URL_MAPPING = { + "NA": "https://advertising-api.amazon.com/", + "EU": "https://advertising-api-eu.amazon.com/", + "FE": "https://advertising-api-fe.amazon.com/" + } -%} + {{ URL_MAPPING[config["region"]] }} + authenticator: "#/definitions/oauth_authenticator" + request_headers: + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + offset_paginator: + type: "DefaultPaginator" + pagination_strategy: + type: OffsetIncrement + page_size: 100 + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: count + page_token_option: + type: RequestOption + field_name: startIndex + inject_into: request_parameter + streams: + profiles: + type: DeclarativeStream + name: profiles + primary_key: + - profileId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/profiles?profileTypeFilter=seller,vendor + http_method: GET + use_cache: true + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: NoPagination + + profiles_filtered: + type: DeclarativeStream + name: profiles + primary_key: + - profileId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/profiles?profileTypeFilter=seller,vendor + http_method: GET + use_cache: true + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + record_filter: + condition: >- + {%- set requested_profiles = config.get("profiles", []) -%} + {%- set requested_marketplace_ids = config.get("marketplace_ids", []) -%} + {{ record["profileId"] in requested_profiles or record["accountInfo"]["marketplaceStringId"] in requested_marketplace_ids if requested_profiles or requested_marketplace_ids else False }} + paginator: + type: NoPagination + portfolios: + type: DeclarativeStream + name: portfolios + primary_key: + - portfolioId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/portfolios/extended + http_method: GET + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: NoPagination + + sponsored_display_campaigns: + type: DeclarativeStream + name: sponsored_display_campaigns + primary_key: + - campaignId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + error_handler: + $ref: "#/definitions/basic_error_handler" + path: sd/campaigns + http_method: GET + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + request_params: + stateFilter: "{{ ','.join(config['state_filter']) }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + $ref: "#/definitions/offset_paginator" + sponsored_display_ad_groups: + type: DeclarativeStream + name: sponsored_display_ad_groups + primary_key: + - adGroupId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sd/adGroups + http_method: GET + error_handler: + $ref: "#/definitions/basic_error_handler" + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + $ref: "#/definitions/offset_paginator" + sponsored_display_product_ads: + type: DeclarativeStream + name: sponsored_display_product_ads + primary_key: + - adId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sd/productAds + http_method: GET + error_handler: + $ref: "#/definitions/basic_error_handler" + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + $ref: "#/definitions/offset_paginator" + sponsored_display_targetings: + type: DeclarativeStream + name: sponsored_display_targetings + primary_key: + - targetId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sd/targets + http_method: GET + error_handler: + $ref: "#/definitions/basic_error_handler" + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + $ref: "#/definitions/offset_paginator" + sponsored_display_creatives: + type: DeclarativeStream + name: sponsored_display_creatives + primary_key: + - creativeId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sd/creatives + http_method: GET + error_handler: + $ref: "#/definitions/basic_error_handler" + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + $ref: "#/definitions/offset_paginator" + sponsored_display_budget_rules: + type: DeclarativeStream + name: sponsored_display_budget_rules + primary_key: + - ruleId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + # Important: API docs contains incorrect endpoint path: + # sd/budgetRules - endpoint from API docs which always returns empty results + # sp/budgetRules - working endpoint + path: sp/budgetRules # TODO: check/rename stream during next breaking changes + http_method: GET + error_handler: + $ref: "#/definitions/basic_error_handler" + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: ["budgetRulesForAdvertiserResponse"] + paginator: + type: "DefaultPaginator" + pagination_strategy: + type: OffsetIncrement + page_size: 30 + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + page_token_option: + type: RequestOption + field_name: startIndex + inject_into: request_parameter + + sponsored_brands_keywords: + type: DeclarativeStream + name: sponsored_brands_keywords + primary_key: + - adGroupId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sb/keywords + error_handler: + $ref: "#/definitions/basic_error_handler" + http_method: GET + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + $ref: "#/definitions/offset_paginator" + sponsored_brands_campaigns: + type: DeclarativeStream + name: sponsored_brands_campaigns + primary_key: + - campaignId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sb/v4/campaigns/list + error_handler: + $ref: "#/definitions/basic_error_handler" + http_method: POST + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + Accept: application/vnd.sbcampaignresource.v4+json + Content-Type: application/vnd.sbcampaignresource.v4+json + request_body_json: + stateFilter: " {{ {'include': ','.join(config['state_filter'])} if config['state_filter'] else None }} " + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: ["campaigns"] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: nextToken + page_size_option: + type: RequestOption + inject_into: body_json + field_name: maxResults + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.nextToken }}" + sponsored_brands_ad_groups: + type: DeclarativeStream + name: sponsored_brands_ad_groups + primary_key: + - adGroupId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + error_handler: + $ref: "#/definitions/basic_error_handler" + path: sb/v4/adGroups/list + http_method: POST + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + Accept: application/vnd.sbadgroupresource.v4+json + Content-Type: application/vnd.sbadgroupresource.v4+json + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: ["adGroups"] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: nextToken + page_size_option: + type: RequestOption + inject_into: body_json + field_name: maxResults + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.nextToken }}" + + sponsored_product_campaigns: + type: DeclarativeStream + name: sponsored_product_campaigns + primary_key: + - campaignId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sp/campaigns/list + http_method: POST + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + Accept: application/vnd.spCampaign.v3+json + Content-Type: application/vnd.spCampaign.v3+json + request_body_json: + stateFilter: " {{ {'include': ','.join(config['state_filter'])} if config['state_filter'] else None }} " + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: ["campaigns"] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: nextToken + page_size_option: + type: RequestOption + inject_into: body_json + field_name: maxResults + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.nextToken }}" + sponsored_product_ad_groups: + type: DeclarativeStream + name: sponsored_product_ad_groups + primary_key: + - adGroupId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /sp/adGroups/list + http_method: POST + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + Accept: application/vnd.spAdGroup.v3+json + Content-Type: application/vnd.spAdGroup.v3+json + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: ["adGroups"] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: nextToken + page_size_option: + type: RequestOption + inject_into: body_json + field_name: maxResults + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.nextToken }}" + sponsored_product_keywords: + type: DeclarativeStream + name: sponsored_product_keywords + primary_key: + - keywordId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sp/keywords/list + http_method: POST + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + Accept: application/vnd.spKeyword.v3+json + Content-Type: application/vnd.spKeyword.v3+json + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: ["keywords"] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: nextToken + page_size_option: + type: RequestOption + inject_into: body_json + field_name: maxResults + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.nextToken }}" + sponsored_product_negative_keywords: + type: DeclarativeStream + name: sponsored_product_negative_keywords + primary_key: + - keywordId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sp/negativeKeywords/list + http_method: POST + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + Accept: application/vnd.spNegativeKeyword.v3+json + Content-Type: application/vnd.spNegativeKeyword.v3+json + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: ["negativeKeywords"] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: nextToken + page_size_option: + type: RequestOption + inject_into: body_json + field_name: maxResults + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.nextToken }}" + sponsored_product_campaign_negative_keywords: + type: DeclarativeStream + name: sponsored_product_campaign_negative_keywords + primary_key: + - keywordId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sp/campaignNegativeKeywords/list + http_method: POST + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + Accept: application/vnd.spCampaignNegativeKeyword.v3+json + Content-Type: application/vnd.spCampaignNegativeKeyword.v3+json + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: ["campaignNegativeKeywords"] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: nextToken + page_size_option: + type: RequestOption + inject_into: body_json + field_name: maxResults + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.nextToken }}" + sponsored_product_ads: + type: DeclarativeStream + name: sponsored_product_ads + primary_key: + - adId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sp/productAds/list + http_method: POST + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + Accept: application/vnd.spProductAd.v3+json + Content-Type: application/vnd.spProductAd.v3+json + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: ["productAds"] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: nextToken + page_size_option: + type: RequestOption + inject_into: body_json + field_name: maxResults + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.nextToken }}" + sponsored_product_targetings: + type: DeclarativeStream + name: sponsored_product_targetings + primary_key: + - targetId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sp/targets/list + http_method: POST + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + Accept: application/vnd.spTargetingClause.v3+json + Content-Type: application/vnd.spTargetingClause.v3+json + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: ["targetingClauses"] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: nextToken + page_size_option: + type: RequestOption + inject_into: body_json + field_name: maxResults + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.nextToken }}" + + sponsored_product_ad_group_bid_recommendations: + type: DeclarativeStream + name: sponsored_product_ad_group_bid_recommendations + primary_key: [] + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + error_handler: "#/definitions/sponsored_product_ad_group_error_handler" + path: /sp/targets/bid/recommendations + http_method: POST + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice.parent_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + Accept: application/vnd.spthemebasedbidrecommendation.v4+json + Content-Type: application/vnd.spthemebasedbidrecommendation.v4+json + request_body_json: + targetingExpressions: + - type: CLOSE_MATCH + - type: LOOSE_MATCH + - type: SUBSTITUTES + - type: COMPLEMENTS + adGroupId: '{{ stream_slice["adGroupId"] }}' + campaignId: '{{ stream_slice.extra_fields["campaignId"] }}' + recommendationType: BIDS_FOR_EXISTING_AD_GROUP + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "adGroupId" + stream: "#/definitions/streams/sponsored_product_ad_groups" + partition_field: "adGroupId" + extra_fields: + - ["campaignId"] + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: nextToken + page_size_option: + type: RequestOption + inject_into: body_json + field_name: maxResults + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.nextToken }}" + transformations: + - type: AddFields + fields: + - path: ["adGroupId"] + value: '{{ stream_slice["adGroupId"] }}' + value_type: string + - path: ["campaignId"] + value: '{{ stream_slice.extra_fields["campaignId"] }}' + value_type: string + + sponsored_product_ad_group_suggested_keywords: + type: DeclarativeStream + name: sponsored_product_ad_group_suggested_keywords + primary_key: [] + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + error_handler: "#/definitions/sponsored_product_ad_group_error_handler" + path: "v2/sp/adGroups/{{ stream_slice['adGroupId'] }}/suggested/keywords" + http_method: GET + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice.parent_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + request_params: + maxNumSuggestions: 100 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "adGroupId" + stream: "#/definitions/streams/sponsored_product_ad_groups" + partition_field: "adGroupId" + extra_fields: + - ["campaignId"] + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: NoPagination + + attribution_report_products: + type: DeclarativeStream + name: attribution_report_products + primary_key: [] + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + error_handler: + type: DefaultErrorHandler + response_filters: + - predicate: '{{ response.message == "This profileID is not authorized to use Amazon Attribution" }}' + action: IGNORE + error_message: "{{ response }}" + - predicate: "{{ 'message' in response }}" + action: FAIL + error_message: "{{ response.message }}" + - predicate: "{{ 'code' in response and 'details' in response }}" + action: IGNORE + error_message: "{{ response.code }}; {{ response.details }}" + path: /attribution/report + http_method: POST + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + request_body_json: + reportType: "PRODUCTS" + metrics: | + {{ + ','.join([ + 'attributedDetailPageViewsClicks14d', + 'attributedAddToCartClicks14d', + 'attributedPurchases14d', + 'unitsSold14d', + 'attributedSales14d', + 'brandHaloDetailPageViewsClicks14d', + 'brandHaloAttributedAddToCartClicks14d', + 'brandHaloAttributedPurchases14d', + 'brandHaloUnitsSold14d', + 'brandHaloAttributedSales14d', + 'attributedNewToBrandPurchases14d', + 'attributedNewToBrandUnitsSold14d', + 'attributedNewToBrandSales14d', + 'brandHaloNewToBrandPurchases14d', + 'brandHaloNewToBrandUnitsSold14d', + 'brandHaloNewToBrandSales14d', + ]) + }} + startDate: >- + {%- set _start_date = config.get("start_date") -%} + {%- set start_date = today_with_timezone(stream_slice.extra_fields["timezone"]) -%} + {%- set end_date = today_with_timezone(stream_slice.extra_fields["timezone"]) -%} + "{{ start_date.strftime("%Y%m%d") if not config.get("start_date") else max(format_datetime(config['start_date'], "%Y%m%d"), (end_date - duration("P90D")).strftime("%Y%m%d")) | string }}" + endDate: >- + "{{ format_datetime(today_with_timezone(stream_slice.extra_fields['timezone']).strftime('%Y%m%d'), '%Y%m%d', '%Y%m%d') }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + extra_fields: + - ["timezone"] + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: ["reports"] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: cursorId + page_size_option: + type: RequestOption + inject_into: body_json + field_name: count + pagination_strategy: + type: CursorPagination + page_size: 300 + cursor_value: "{{ response.cursorId }}" + + attribution_report_performance_adgroup: + type: DeclarativeStream + name: attribution_report_performance_adgroup + primary_key: [] + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + error_handler: + type: DefaultErrorHandler + response_filters: + - http_codes: [400] + action: IGNORE + error_message: "{{ response }}" + - predicate: "{{ 'message' in response }}" + action: FAIL + error_message: "{{ response.message }}" + path: /attribution/report + http_method: POST + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + request_body_json: + reportType: "PERFORMANCE" + groupBy: "ADGROUP" + metrics: | + {{ + ','.join([ + 'Click-throughs', + 'attributedDetailPageViewsClicks14d', + 'attributedAddToCartClicks14d', + 'attributedPurchases14d', + 'unitsSold14d', + 'attributedSales14d', + 'attributedTotalDetailPageViewsClicks14d', + 'attributedTotalAddToCartClicks14d', + 'attributedTotalPurchases14d', + 'totalUnitsSold14d', + 'totalAttributedSales14d', + 'brb_bonus_amount' + ]) + }} + startDate: >- + {%- set _start_date = config.get("start_date") -%} + {%- set start_date = today_with_timezone(stream_slice.extra_fields["timezone"]) -%} + {%- set end_date = today_with_timezone(stream_slice.extra_fields["timezone"]) -%} + "{{ start_date.strftime("%Y%m%d") if not config.get("start_date") else max(format_datetime(config['start_date'], "%Y%m%d"), (end_date - duration("P90D")).strftime("%Y%m%d")) | string }}" + endDate: >- + "{{ format_datetime(today_with_timezone(stream_slice.extra_fields['timezone']).strftime('%Y%m%d'), '%Y%m%d', '%Y%m%d') }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + extra_fields: + - ["timezone"] + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: ["reports"] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: cursorId + page_size_option: + type: RequestOption + inject_into: body_json + field_name: count + pagination_strategy: + type: CursorPagination + page_size: 300 + cursor_value: "{{ response.cursorId }}" + + attribution_report_performance_campaign: + type: DeclarativeStream + name: attribution_report_performance_campaign + primary_key: [] + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + error_handler: + type: DefaultErrorHandler + response_filters: + - http_codes: [400] + action: IGNORE + error_message: "{{ response }}" + - predicate: "{{ 'message' in response }}" + action: FAIL + error_message: "{{ response.message }}" + path: /attribution/report + http_method: POST + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + request_body_json: + reportType: "PERFORMANCE" + groupBy: "CAMPAIGN" + metrics: | + {{ + ','.join([ + 'Click-throughs', + 'attributedDetailPageViewsClicks14d', + 'attributedAddToCartClicks14d', + 'attributedPurchases14d', + 'unitsSold14d', + 'attributedSales14d', + 'attributedTotalDetailPageViewsClicks14d', + 'attributedTotalAddToCartClicks14d', + 'attributedTotalPurchases14d', + 'totalUnitsSold14d', + 'totalAttributedSales14d', + 'brb_bonus_amount' + ]) + }} + startDate: >- + {%- set _start_date = config.get("start_date") -%} + {%- set start_date = today_with_timezone(stream_slice.extra_fields["timezone"]) -%} + {%- set end_date = today_with_timezone(stream_slice.extra_fields["timezone"]) -%} + "{{ start_date.strftime("%Y%m%d") if not config.get("start_date") else max(format_datetime(config['start_date'], "%Y%m%d"), (end_date - duration("P90D")).strftime("%Y%m%d")) | string }}" + endDate: >- + "{{ format_datetime(today_with_timezone(stream_slice.extra_fields['timezone']).strftime('%Y%m%d'), '%Y%m%d', '%Y%m%d') }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + extra_fields: + - ["timezone"] + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: ["reports"] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: cursorId + page_size_option: + type: RequestOption + inject_into: body_json + field_name: count + pagination_strategy: + type: CursorPagination + page_size: 300 + cursor_value: "{{ response.cursorId }}" + + attribution_report_performance_creative: + type: DeclarativeStream + name: attribution_report_performance_creative + primary_key: [] + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + error_handler: + type: DefaultErrorHandler + response_filters: + - http_codes: [400] + action: IGNORE + error_message: "{{ response }}" + - predicate: "{{ 'message' in response }}" + action: FAIL + error_message: "{{ response.message }}" + path: /attribution/report + http_method: POST + request_headers: + Amazon-Advertising-API-Scope: "{{ stream_slice['profileId'] }}" + Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}' + request_body_json: + reportType: "PERFORMANCE" + groupBy: "CREATIVE" + metrics: | + {{ + ','.join([ + 'Click-throughs', + 'attributedDetailPageViewsClicks14d', + 'attributedAddToCartClicks14d', + 'attributedPurchases14d', + 'unitsSold14d', + 'attributedSales14d', + 'attributedTotalDetailPageViewsClicks14d', + 'attributedTotalAddToCartClicks14d', + 'attributedTotalPurchases14d', + 'totalUnitsSold14d', + 'totalAttributedSales14d', + ]) + }} + startDate: >- + {%- set _start_date = config.get("start_date") -%} + {%- set start_date = today_with_timezone(stream_slice.extra_fields["timezone"]) -%} + {%- set end_date = today_with_timezone(stream_slice.extra_fields["timezone"]) -%} + "{{ start_date.strftime("%Y%m%d") if not config.get("start_date") else max(format_datetime(config['start_date'], "%Y%m%d"), (end_date - duration("P90D")).strftime("%Y%m%d")) | string }}" + endDate: >- + "{{ format_datetime(today_with_timezone(stream_slice.extra_fields['timezone']).strftime('%Y%m%d'), '%Y%m%d', '%Y%m%d') }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: "profileId" + stream: "#/definitions/streams/profiles_filtered" + partition_field: "profileId" + extra_fields: + - ["timezone"] + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: ["reports"] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: cursorId + page_size_option: + type: RequestOption + inject_into: body_json + field_name: count + pagination_strategy: + type: CursorPagination + page_size: 300 + cursor_value: "{{ response.cursorId }}" + +streams: + - $ref: "#/definitions/streams/profiles" + - $ref: "#/definitions/streams/portfolios" + + - $ref: "#/definitions/streams/sponsored_display_campaigns" + - $ref: "#/definitions/streams/sponsored_display_ad_groups" + - $ref: "#/definitions/streams/sponsored_display_product_ads" + - $ref: "#/definitions/streams/sponsored_display_targetings" + - $ref: "#/definitions/streams/sponsored_display_creatives" + - $ref: "#/definitions/streams/sponsored_display_budget_rules" + + - $ref: "#/definitions/streams/sponsored_brands_keywords" + - $ref: "#/definitions/streams/sponsored_brands_campaigns" + - $ref: "#/definitions/streams/sponsored_brands_ad_groups" + + - $ref: "#/definitions/streams/sponsored_product_campaigns" + - $ref: "#/definitions/streams/sponsored_product_ad_groups" + - $ref: "#/definitions/streams/sponsored_product_keywords" + - $ref: "#/definitions/streams/sponsored_product_negative_keywords" + - $ref: "#/definitions/streams/sponsored_product_campaign_negative_keywords" + - $ref: "#/definitions/streams/sponsored_product_ads" + - $ref: "#/definitions/streams/sponsored_product_targetings" + + - $ref: "#/definitions/streams/sponsored_product_ad_group_bid_recommendations" + - $ref: "#/definitions/streams/sponsored_product_ad_group_suggested_keywords" + + - $ref: "#/definitions/streams/attribution_report_products" + - $ref: "#/definitions/streams/attribution_report_performance_adgroup" + - $ref: "#/definitions/streams/attribution_report_performance_campaign" + - $ref: "#/definitions/streams/attribution_report_performance_creative" + +concurrency_level: + type: ConcurrencyLevel + default_concurrency: 10 + max_concurrency: 10 diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/run.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/run.py index 0436d379599e..6782766e81c6 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/run.py +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/run.py @@ -4,14 +4,54 @@ import sys +import time +import traceback +from typing import List -from airbyte_cdk.entrypoint import launch +from orjson import orjson + +from airbyte_cdk.entrypoint import AirbyteEntrypoint, launch, logger +from airbyte_cdk.exception_handler import init_uncaught_exception_handler +from airbyte_cdk.models import AirbyteErrorTraceMessage, AirbyteMessage, AirbyteMessageSerializer, AirbyteTraceMessage, TraceType, Type from source_amazon_ads import SourceAmazonAds from source_amazon_ads.config_migrations import MigrateStartDate -from source_amazon_ads.declarative_source_adapter import DeclarativeSourceAdapter + + +def _get_source(args: List[str]): + catalog_path = AirbyteEntrypoint.extract_catalog(args) + config_path = AirbyteEntrypoint.extract_config(args) + state_path = AirbyteEntrypoint.extract_state(args) + try: + return SourceAmazonAds( + SourceAmazonAds.read_catalog(catalog_path) if catalog_path else None, + SourceAmazonAds.read_config(config_path) if config_path else None, + SourceAmazonAds.read_state(state_path) if state_path else None, + ) + except Exception as error: + print( + orjson.dumps( + AirbyteMessageSerializer.dump( + AirbyteMessage( + type=Type.TRACE, + trace=AirbyteTraceMessage( + type=TraceType.ERROR, + emitted_at=time.time_ns() // 1_000_000, + error=AirbyteErrorTraceMessage( + message=f"Error starting the sync. This could be due to an invalid configuration or catalog. Please contact Support for assistance. Error: {error}", + stack_trace=traceback.format_exc(), + ), + ), + ) + ) + ).decode() + ) + return None def run(): - source = DeclarativeSourceAdapter(source=SourceAmazonAds()) - MigrateStartDate.migrate(sys.argv[1:], source) - launch(source, sys.argv[1:]) + init_uncaught_exception_handler(logger) + _args = sys.argv[1:] + source = _get_source(_args) + if source: + MigrateStartDate.migrate(sys.argv[1:], source) + launch(source, _args) diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/__init__.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/__init__.py deleted file mode 100644 index 053c733ac2ff..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/__init__.py +++ /dev/null @@ -1,56 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -from .attribution_report import AttributionReportModel -from .common import ( - CatalogModel, - Keywords, - MetricsReport, - NegativeKeywords, - Portfolio -) -from .profile import Profile -from .sponsored_brands import ( - BrandsAdGroup, - BrandsCampaign, -) -from .sponsored_display import DisplayAdGroup, DisplayBudgetRules, DisplayCampaign, DisplayCreatives, DisplayProductAds, DisplayTargeting -from .sponsored_products import ( - ProductAd, - ProductAdGroupBidRecommendations, - ProductAdGroups, - ProductAdGroupSuggestedKeywords, - ProductCampaign, - ProductTargeting, - SponsoredProductCampaignNegativeKeywordsModel, - SponsoredProductKeywordsModel, - SponsoredProductNegativeKeywordsModel -) - -__all__ = [ - "BrandsAdGroup", - "BrandsCampaign", - "CatalogModel", - "DisplayAdGroup", - "DisplayCampaign", - "DisplayProductAds", - "DisplayTargeting", - "DisplayBudgetRules", - "Keywords", - "DisplayCreatives", - "MetricsReport", - "NegativeKeywords", - "CampaignNegativeKeywords", - "Portfolio", - "ProductAd", - "ProductAdGroups", - "ProductAdGroupBidRecommendations", - "ProductAdGroupSuggestedKeywords", - "ProductCampaign", - "ProductTargeting", - "Profile", - "AttributionReportModel", - "SponsoredProductCampaignNegativeKeywordsModel", - "SponsoredProductKeywordsModel", - "SponsoredProductNegativeKeywordsModel" -] diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/attribution_report.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/attribution_report.py deleted file mode 100644 index b7b3e89c5a79..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/attribution_report.py +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Optional - -from .common import CatalogModel - - -class AttributionReportModel(CatalogModel): - date: str - brandName: str - marketplace: str - campaignId: Optional[str] - productAsin: str - productConversionType: str - advertiserName: str - adGroupId: Optional[str] - creativeId: Optional[str] - productName: str - productCategory: str - productSubcategory: str - productGroup: str - publisher: Optional[str] diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/attribution_report_performance_adgroup.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/attribution_report_performance_adgroup.json new file mode 100644 index 000000000000..80422aa45cf3 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/attribution_report_performance_adgroup.json @@ -0,0 +1,118 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "date": { + "type": ["null", "string"] + }, + "brandName": { + "type": ["null", "string"] + }, + "marketplace": { + "type": ["null", "string"] + }, + "campaignId": { + "type": ["null", "string"] + }, + "productAsin": { + "type": ["null", "string"] + }, + "productConversionType": { + "type": ["null", "string"] + }, + "advertiserName": { + "type": ["null", "string"] + }, + "adGroupId": { + "type": ["null", "string"] + }, + "creativeId": { + "type": ["null", "string"] + }, + "productName": { + "type": ["null", "string"] + }, + "productCategory": { + "type": ["null", "string"] + }, + "productSubcategory": { + "type": ["null", "string"] + }, + "productGroup": { + "type": ["null", "string"] + }, + "publisher": { + "type": ["null", "string"] + }, + "Click-throughs": { + "type": ["null", "string"] + }, + "attributedDetailPageViewsClicks14d": { + "type": ["null", "string"] + }, + "attributedAddToCartClicks14d": { + "type": ["null", "string"] + }, + "attributedPurchases14d": { + "type": ["null", "string"] + }, + "unitsSold14d": { + "type": ["null", "string"] + }, + "attributedSales14d": { + "type": ["null", "string"] + }, + "attributedTotalDetailPageViewsClicks14d": { + "type": ["null", "string"] + }, + "attributedTotalAddToCartClicks14d": { + "type": ["null", "string"] + }, + "attributedTotalPurchases14d": { + "type": ["null", "string"] + }, + "totalUnitsSold14d": { + "type": ["null", "string"] + }, + "totalAttributedSales14d": { + "type": ["null", "string"] + }, + "brb_bonus_amount": { + "type": ["null", "string"] + }, + "brandHaloDetailPageViewsClicks14d": { + "type": ["null", "string"] + }, + "brandHaloAttributedAddToCartClicks14d": { + "type": ["null", "string"] + }, + "brandHaloAttributedPurchases14d": { + "type": ["null", "string"] + }, + "brandHaloUnitsSold14d": { + "type": ["null", "string"] + }, + "brandHaloAttributedSales14d": { + "type": ["null", "string"] + }, + "attributedNewToBrandPurchases14d": { + "type": ["null", "string"] + }, + "attributedNewToBrandUnitsSold14d": { + "type": ["null", "string"] + }, + "attributedNewToBrandSales14d": { + "type": ["null", "string"] + }, + "brandHaloNewToBrandPurchases14d": { + "type": ["null", "string"] + }, + "brandHaloNewToBrandUnitsSold14d": { + "type": ["null", "string"] + }, + "brandHaloNewToBrandSales14d": { + "type": ["null", "string"] + } + }, + "title": "attribution_report_performance_adgroup", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/attribution_report_performance_campaign.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/attribution_report_performance_campaign.json new file mode 100644 index 000000000000..2dc5c6ef17a3 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/attribution_report_performance_campaign.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "date": { "type": ["null", "string"] }, + "brandName": { "type": ["null", "string"] }, + "marketplace": { "type": ["null", "string"] }, + "campaignId": { "type": ["null", "string"] }, + "productAsin": { "type": ["null", "string"] }, + "productConversionType": { "type": ["null", "string"] }, + "advertiserName": { "type": ["null", "string"] }, + "adGroupId": { "type": ["null", "string"] }, + "creativeId": { "type": ["null", "string"] }, + "productName": { "type": ["null", "string"] }, + "productCategory": { "type": ["null", "string"] }, + "productSubcategory": { "type": ["null", "string"] }, + "productGroup": { "type": ["null", "string"] }, + "publisher": { "type": ["null", "string"] }, + "Click-throughs": { "type": ["null", "string"] }, + "attributedDetailPageViewsClicks14d": { "type": ["null", "string"] }, + "attributedAddToCartClicks14d": { "type": ["null", "string"] }, + "attributedPurchases14d": { "type": ["null", "string"] }, + "unitsSold14d": { "type": ["null", "string"] }, + "attributedSales14d": { "type": ["null", "string"] }, + "attributedTotalDetailPageViewsClicks14d": { "type": ["null", "string"] }, + "attributedTotalAddToCartClicks14d": { "type": ["null", "string"] }, + "attributedTotalPurchases14d": { "type": ["null", "string"] }, + "totalUnitsSold14d": { "type": ["null", "string"] }, + "totalAttributedSales14d": { "type": ["null", "string"] }, + "brb_bonus_amount": { "type": ["null", "string"] }, + "brandHaloDetailPageViewsClicks14d": { "type": ["null", "string"] }, + "brandHaloAttributedAddToCartClicks14d": { "type": ["null", "string"] }, + "brandHaloAttributedPurchases14d": { "type": ["null", "string"] }, + "brandHaloUnitsSold14d": { "type": ["null", "string"] }, + "brandHaloAttributedSales14d": { "type": ["null", "string"] }, + "attributedNewToBrandPurchases14d": { "type": ["null", "string"] }, + "attributedNewToBrandUnitsSold14d": { "type": ["null", "string"] }, + "attributedNewToBrandSales14d": { "type": ["null", "string"] }, + "brandHaloNewToBrandPurchases14d": { "type": ["null", "string"] }, + "brandHaloNewToBrandUnitsSold14d": { "type": ["null", "string"] }, + "brandHaloNewToBrandSales14d": { "type": ["null", "string"] } + }, + "title": "attribution_report_performance_campaign", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/attribution_report_performance_creative.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/attribution_report_performance_creative.json new file mode 100644 index 000000000000..752537d60c06 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/attribution_report_performance_creative.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "date": { "type": ["null", "string"] }, + "brandName": { "type": ["null", "string"] }, + "marketplace": { "type": ["null", "string"] }, + "campaignId": { "type": ["null", "string"] }, + "productAsin": { "type": ["null", "string"] }, + "productConversionType": { "type": ["null", "string"] }, + "advertiserName": { "type": ["null", "string"] }, + "adGroupId": { "type": ["null", "string"] }, + "creativeId": { "type": ["null", "string"] }, + "productName": { "type": ["null", "string"] }, + "productCategory": { "type": ["null", "string"] }, + "productSubcategory": { "type": ["null", "string"] }, + "productGroup": { "type": ["null", "string"] }, + "publisher": { "type": ["null", "string"] }, + "Click-throughs": { "type": ["null", "string"] }, + "attributedDetailPageViewsClicks14d": { "type": ["null", "string"] }, + "attributedAddToCartClicks14d": { "type": ["null", "string"] }, + "attributedPurchases14d": { "type": ["null", "string"] }, + "unitsSold14d": { "type": ["null", "string"] }, + "attributedSales14d": { "type": ["null", "string"] }, + "attributedTotalDetailPageViewsClicks14d": { "type": ["null", "string"] }, + "attributedTotalAddToCartClicks14d": { "type": ["null", "string"] }, + "attributedTotalPurchases14d": { "type": ["null", "string"] }, + "totalUnitsSold14d": { "type": ["null", "string"] }, + "totalAttributedSales14d": { "type": ["null", "string"] }, + "brb_bonus_amount": { "type": ["null", "string"] }, + "brandHaloDetailPageViewsClicks14d": { "type": ["null", "string"] }, + "brandHaloAttributedAddToCartClicks14d": { "type": ["null", "string"] }, + "brandHaloAttributedPurchases14d": { "type": ["null", "string"] }, + "brandHaloUnitsSold14d": { "type": ["null", "string"] }, + "brandHaloAttributedSales14d": { "type": ["null", "string"] }, + "attributedNewToBrandPurchases14d": { "type": ["null", "string"] }, + "attributedNewToBrandUnitsSold14d": { "type": ["null", "string"] }, + "attributedNewToBrandSales14d": { "type": ["null", "string"] }, + "brandHaloNewToBrandPurchases14d": { "type": ["null", "string"] }, + "brandHaloNewToBrandUnitsSold14d": { "type": ["null", "string"] }, + "brandHaloNewToBrandSales14d": { "type": ["null", "string"] } + }, + "title": "attribution_report_performance_creative", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/attribution_report_products.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/attribution_report_products.json new file mode 100644 index 000000000000..9d367b04ac7b --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/attribution_report_products.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "date": { "type": ["null", "string"] }, + "brandName": { "type": ["null", "string"] }, + "marketplace": { "type": ["null", "string"] }, + "campaignId": { "type": ["null", "string"] }, + "productAsin": { "type": ["null", "string"] }, + "productConversionType": { "type": ["null", "string"] }, + "advertiserName": { "type": ["null", "string"] }, + "adGroupId": { "type": ["null", "string"] }, + "creativeId": { "type": ["null", "string"] }, + "productName": { "type": ["null", "string"] }, + "productCategory": { "type": ["null", "string"] }, + "productSubcategory": { "type": ["null", "string"] }, + "productGroup": { "type": ["null", "string"] }, + "publisher": { "type": ["null", "string"] }, + "Click-throughs": { "type": ["null", "string"] }, + "attributedDetailPageViewsClicks14d": { "type": ["null", "string"] }, + "attributedAddToCartClicks14d": { "type": ["null", "string"] }, + "attributedPurchases14d": { "type": ["null", "string"] }, + "unitsSold14d": { "type": ["null", "string"] }, + "attributedSales14d": { "type": ["null", "string"] }, + "attributedTotalDetailPageViewsClicks14d": { "type": ["null", "string"] }, + "attributedTotalAddToCartClicks14d": { "type": ["null", "string"] }, + "attributedTotalPurchases14d": { "type": ["null", "string"] }, + "totalUnitsSold14d": { "type": ["null", "string"] }, + "totalAttributedSales14d": { "type": ["null", "string"] }, + "brb_bonus_amount": { "type": ["null", "string"] }, + "brandHaloDetailPageViewsClicks14d": { "type": ["null", "string"] }, + "brandHaloAttributedAddToCartClicks14d": { "type": ["null", "string"] }, + "brandHaloAttributedPurchases14d": { "type": ["null", "string"] }, + "brandHaloUnitsSold14d": { "type": ["null", "string"] }, + "brandHaloAttributedSales14d": { "type": ["null", "string"] }, + "attributedNewToBrandPurchases14d": { "type": ["null", "string"] }, + "attributedNewToBrandUnitsSold14d": { "type": ["null", "string"] }, + "attributedNewToBrandSales14d": { "type": ["null", "string"] }, + "brandHaloNewToBrandPurchases14d": { "type": ["null", "string"] }, + "brandHaloNewToBrandUnitsSold14d": { "type": ["null", "string"] }, + "brandHaloNewToBrandSales14d": { "type": ["null", "string"] } + }, + "title": "attribution_report_products", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/common.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/common.py deleted file mode 100644 index 89485a7a8d72..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/common.py +++ /dev/null @@ -1,102 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from decimal import Decimal -from typing import Any, Dict, Iterable, Type - -from pydantic import BaseModel, create_model - - -class CatalogModel(BaseModel): - class Config: - arbitrary_types_allowed = True - - @classmethod - def schema_extra(cls, schema: Dict[str, Any], model: Type["BaseModel"]) -> None: - # Modify pydantic generated jsonschema. - # Remove "title" and "description" fields to reduce size. - schema.pop("title", None) - schema.pop("description", None) - # Remove required section so any missing attribute from API wont break object validation. - schema.pop("required", None) - # According to https://github.com/airbytehq/airbyte/issues/14196 set additionalProperties to True - if schema.pop("additionalProperties", None): - schema["additionalProperties"] = True - for name, prop in schema.get("properties", {}).items(): - prop.pop("title", None) - prop.pop("description", None) - if prop.pop("additionalProperties", None): - prop["additionalProperties"] = True - allow_none = model.__fields__[name].allow_none - # Pydantic doesnt treat Union[None, Any] type correctly when - # generation jsonschema so we cant set field as nullable (i.e. - # field that can have either null and non-null values), - # generate this jsonschema value manually. - if "type" in prop: - if allow_none: - prop["type"] = ["null", prop["type"]] - if prop["type"] == "array" and prop["items"]: - if prop["items"].pop("additionalProperties", None): - prop["items"]["additionalProperties"] = True - if schema["type"] == "object": - schema["type"] = ["object", "null"] - - -class MetricsReport(CatalogModel): - profileId: int - recordType: str - reportDate: str - recordId: str - # This property will be overwritten with autogenerated model based on metrics list - metric: None - - @classmethod - def generate_metric_model(cls, metric_list: Iterable[str]) -> CatalogModel: - metrics_obj_model = create_model("MetricObjModel", **{f: (str, None) for f in metric_list}, __base__=CatalogModel) - return create_model("MetricsModel", metric=(metrics_obj_model, None), __base__=cls) - - -class Targeting(CatalogModel): - targetId: Decimal - adGroupId: Decimal - state: str - expressionType: str - bid: Decimal - - -class KeywordsBase(CatalogModel): - keywordId: Decimal - campaignId: Decimal - adGroupId: Decimal - state: str - keywordText: str - - -class Keywords(KeywordsBase): - nativeLanguageKeyword: str - matchType: str - bid: Decimal - - -class NegativeKeywords(KeywordsBase): - matchType: str - - -class Budget(CatalogModel): - amount: Decimal = None - currencyCode: str = None - policy: str = None - startDate: str = None - endDate: str = None - - -class Portfolio(CatalogModel): - portfolioId: int - name: str = None - budget: Budget = None - inBudget: bool = None - state: str = None - creationDate: int = None - lastUpdatedDate: int = None - servingStatus: str = None diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/portfolios.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/portfolios.json new file mode 100644 index 000000000000..cf7539e2c60e --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/portfolios.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "portfolioId": { "type": ["null", "integer"] }, + "name": { "type": ["null", "string"] }, + "budget": { + "type": ["object", "null"], + "properties": { + "amount": { "type": ["null", "number"] }, + "currencyCode": { "type": ["null", "string"] }, + "policy": { "type": ["null", "string"] }, + "startDate": { "type": ["null", "string"] }, + "endDate": { "type": ["null", "string"] } + } + }, + "inBudget": { "type": ["null", "boolean"] }, + "state": { "type": ["null", "string"] }, + "creationDate": { "type": ["null", "integer"] }, + "lastUpdatedDate": { "type": ["null", "integer"] }, + "servingStatus": { "type": ["null", "string"] } + }, + "title": "portfolios", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/profile.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/profile.py deleted file mode 100644 index 0bc6c509334f..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/profile.py +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from decimal import Decimal - -from .common import CatalogModel - - -class AccountInfo(CatalogModel): - marketplaceStringId: str - id: str - type: str - name: str = None - subType: str = None - validPaymentMethod: bool = None - - -class Profile(CatalogModel): - profileId: int - countryCode: str = None - currencyCode: str = None - dailyBudget: Decimal = None - timezone: str - accountInfo: AccountInfo diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/profiles.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/profiles.json new file mode 100644 index 000000000000..53ba437b6a4b --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/profiles.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "profileId": { "type": ["null", "integer"] }, + "countryCode": { "type": ["null", "string"] }, + "currencyCode": { "type": ["null", "string"] }, + "dailyBudget": { "type": ["null", "number"] }, + "timezone": { "type": ["null", "string"] }, + "accountInfo": { + "type": ["object", "null"], + "properties": { + "marketplaceStringId": { "type": ["null", "string"] }, + "id": { "type": ["null", "string"] }, + "type": { "type": ["null", "string"] }, + "name": { "type": ["null", "string"] }, + "subType": { "type": ["null", "string"] }, + "validPaymentMethod": { "type": ["null", "boolean"] } + } + } + }, + "title": "profiles", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_brands.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_brands.py deleted file mode 100644 index 51d8f091e81c..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_brands.py +++ /dev/null @@ -1,53 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from decimal import Decimal -from typing import Any, Dict, List, Optional - -from .common import CatalogModel - - -class LandingPage(CatalogModel): - pageType: str - url: str - - -class BidAdjustment(CatalogModel): - bidAdjustmentPredicate: str - bidAdjustmentPercent: int - - -class Creative(CatalogModel): - brandName: str - brandLogoAssetID: str - brandLogoUrl: str - asins: List[str] - shouldOptimizeAsins: bool - - -class BrandsCampaign(CatalogModel): - campaignId: str - name: str - tags: Dict[str, str] - budget: Decimal - budgetType: str - startDate: str - endDate: str - state: str - brandEntityId: str - portfolioId: str - ruleBasedBudget: Optional[Dict[str, Any]] - bidding: Optional[Dict[str, Any]] - productLocation: Optional[str] - costType: Optional[str] - smartDefault: Optional[List[str]] - extendedData: Optional[Dict[str, Any]] - - -class BrandsAdGroup(CatalogModel): - campaignId: str - adGroupId: str - name: str - state: str - extendedData: Dict[str, Any] diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_brands_ad_groups.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_brands_ad_groups.json new file mode 100644 index 000000000000..7b1232ba8518 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_brands_ad_groups.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "campaignId": { "type": ["null", "string"] }, + "adGroupId": { "type": ["null", "string"] }, + "name": { "type": ["null", "string"] }, + "state": { "type": ["null", "string"] }, + "extendedData": { "type": ["null", "object"] } + }, + "title": "sponsored_brands_ad_groups", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_brands_campaigns.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_brands_campaigns.json new file mode 100644 index 000000000000..1c528e9c6535 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_brands_campaigns.json @@ -0,0 +1,26 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "campaignId": { "type": ["null", "string"] }, + "name": { "type": ["null", "string"] }, + "tags": { "type": ["null", "object"], "additionalProperties": true }, + "budget": { "type": ["null", "number"] }, + "budgetType": { "type": ["null", "string"] }, + "startDate": { "type": ["null", "string"] }, + "endDate": { "type": ["null", "string"] }, + "state": { "type": ["null", "string"] }, + "brandEntityId": { "type": ["null", "string"] }, + "portfolioId": { "type": ["null", "string"] }, + "ruleBasedBudget": { "type": ["null", "object"] }, + "bidding": { "type": ["null", "object"] }, + "productLocation": { "type": ["null", "string"] }, + "costType": { "type": ["null", "string"] }, + "smartDefault": { + "type": ["null", "array"], + "items": { "type": ["null", "string"] } + }, + "extendedData": { "type": ["null", "object"] } + }, + "title": "sponsored_brands_campaigns", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_brands_keywords.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_brands_keywords.json new file mode 100644 index 000000000000..6a179f71d387 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_brands_keywords.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "campaignId": { "type": ["null", "string"] }, + "adGroupId": { "type": ["null", "string"] }, + "name": { "type": ["null", "string"] }, + "state": { "type": ["null", "string"] }, + "extendedData": { "type": ["null", "object"] } + }, + "title": "sponsored_brands_keywords", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_brands_v3_report_stream.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_brands_v3_report_stream.json new file mode 100644 index 000000000000..e83fcc7d2ce0 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_brands_v3_report_stream.json @@ -0,0 +1,32 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "profileId": { "type": ["null", "integer"] }, + "recordType": { "type": ["null", "string"] }, + "reportDate": { "type": ["null", "string"] }, + "recordId": { "type": ["null", "string"] }, + "metric": { + "type": ["object", "null"], + "properties": { + "attributionType": { "type": ["null", "string"] }, + "campaignName": { "type": ["null", "string"] }, + "newToBrandSales14d": { "type": ["null", "string"] }, + "orders14d": { "type": ["null", "string"] }, + "productName": { "type": ["null", "string"] }, + "sales14d": { "type": ["null", "string"] }, + "newToBrandPurchasesPercentage14d": { "type": ["null", "string"] }, + "purchasedAsin": { "type": ["null", "string"] }, + "newToBrandSalesPercentage14d": { "type": ["null", "string"] }, + "productCategory": { "type": ["null", "string"] }, + "newToBrandPurchases14d": { "type": ["null", "string"] }, + "newToBrandUnitsSoldPercentage14d": { "type": ["null", "string"] }, + "unitsSold14d": { "type": ["null", "string"] }, + "adGroupName": { "type": ["null", "string"] }, + "newToBrandUnitsSold14d": { "type": ["null", "string"] }, + "campaignBudgetCurrencyCode": { "type": ["null", "string"] } + } + } + }, + "title": "sponsored_brands_v3_report_stream", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display.py deleted file mode 100644 index 83e845fb36ed..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display.py +++ /dev/null @@ -1,115 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from decimal import Decimal -from typing import Any, Dict, List, Optional - -from .common import CatalogModel, Targeting - - -class DisplayCampaign(CatalogModel): - campaignId: Decimal - name: str - budgetType: str - budget: Decimal - startDate: str - endDate: str = None - costType: str - state: str - portfolioId: int = None - tactic: str - deliveryProfile: str - - -class DisplayAdGroup(CatalogModel): - name: str - campaignId: Decimal - adGroupId: Decimal - defaultBid: Decimal - bidOptimization: str - state: str - tactic: str - creativeType: str - - -class DisplayProductAds(CatalogModel): - state: str - adId: Decimal - campaignId: Decimal - adGroupId: Decimal - asin: str - sku: str - - -class DisplayTargeting(Targeting): - campaignId: Decimal - expression: List[Dict[str, str]] - resolvedExpression: List[Dict[str, str]] - - -class DisplayCreatives(CatalogModel): - adGroupId: Decimal - creativeId: Decimal - creativeType: str - properties: Dict[str, Any] - moderationStatus: str - - -class DisplayBudgetRuleDetailsPerformanceMeasureCondition(CatalogModel): - metricName: str - comparisonOperator: str - threshold: Decimal - - -class DisplayBudgetRuleDetailsRecurrenceIntraDaySchedule(CatalogModel): - startTime: str - endTime: str - - -class DisplayBudgetRuleDetailsRecurrence(CatalogModel): - type: str - daysOfWeek: List[str] = None - intraDaySchedule: List[DisplayBudgetRuleDetailsRecurrenceIntraDaySchedule] = None - threshold: Decimal - - -class DisplayBudgetRuleDetailsBudgetIncreaseBy(CatalogModel): - type: str - value: Decimal - - -class DisplayBudgetRuleDetailsDurationEventTypeRuleDuration(CatalogModel): - eventId: str - endDate: str - eventName: str - startDate: str - - -class DisplayBudgetRuleDetailsDurationDateRangeTypeRuleDuration(CatalogModel): - endDate: Optional[str] - startDate: str - - -class DisplayBudgetRuleDetailsDuration(CatalogModel): - eventTypeRuleDuration: Optional[DisplayBudgetRuleDetailsDurationEventTypeRuleDuration] = None - dateRangeTypeRuleDuration: Optional[DisplayBudgetRuleDetailsDurationDateRangeTypeRuleDuration] = None - - -class DisplayBudgetRuleDetails(CatalogModel): - name: str - ruleType: str = None - duration: Optional[DisplayBudgetRuleDetailsDuration] = None - budgetIncreaseBy: Optional[DisplayBudgetRuleDetailsBudgetIncreaseBy] = None - recurrence: Optional[DisplayBudgetRuleDetailsRecurrence] = None - performanceMeasureCondition: Optional[DisplayBudgetRuleDetailsPerformanceMeasureCondition] = None - - -class DisplayBudgetRules(CatalogModel): - ruleId: str - ruleStatus: str - ruleState: str - lastUpdatedDate: Optional[Decimal] - createdDate: Decimal - ruleDetails: DisplayBudgetRuleDetails = None - ruleStatusDetails: Dict[str, str] = None diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_ad_groups.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_ad_groups.json new file mode 100644 index 000000000000..504e5e24c5fc --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_ad_groups.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "name": { "type": ["null", "string"] }, + "campaignId": { "type": ["null", "number"] }, + "adGroupId": { "type": ["null", "number"] }, + "defaultBid": { "type": ["null", "number"] }, + "bidOptimization": { "type": ["null", "string"] }, + "state": { "type": ["null", "string"] }, + "tactic": { "type": ["null", "string"] }, + "creativeType": { "type": ["null", "string"] } + }, + "title": "sponsored_display_ad_groups", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_budget_rules.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_budget_rules.json new file mode 100644 index 000000000000..e52d1d6ff896 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_budget_rules.json @@ -0,0 +1,80 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "ruleId": { "type": ["null", "string"] }, + "ruleStatus": { "type": ["null", "string"] }, + "ruleState": { "type": ["null", "string"] }, + "lastUpdatedDate": { "type": ["null", "number"] }, + "createdDate": { "type": ["null", "number"] }, + "ruleDetails": { + "type": ["object", "null"], + "properties": { + "name": { "type": ["null", "string"] }, + "ruleType": { "type": ["null", "string"] }, + "duration": { + "type": ["object", "null"], + "properties": { + "eventTypeRuleDuration": { + "type": ["object", "null"], + "properties": { + "eventId": { "type": ["null", "string"] }, + "endDate": { "type": ["null", "string"] }, + "eventName": { "type": ["null", "string"] }, + "startDate": { "type": ["null", "string"] } + } + }, + "dateRangeTypeRuleDuration": { + "type": ["object", "null"], + "properties": { + "endDate": { "type": ["null", "string"] }, + "startDate": { "type": ["null", "string"] } + } + } + } + }, + "budgetIncreaseBy": { + "type": ["object", "null"], + "properties": { + "type": { "type": ["null", "string"] }, + "value": { "type": ["null", "number"] } + } + }, + "recurrence": { + "type": ["object", "null"], + "properties": { + "type": { "type": ["null", "string"] }, + "daysOfWeek": { + "type": ["null", "array"], + "items": { "type": ["null", "string"] } + }, + "intraDaySchedule": { + "type": ["null", "array"], + "items": { + "type": ["object", "null"], + "properties": { + "startTime": { "type": ["null", "string"] }, + "endTime": { "type": ["null", "string"] } + } + } + }, + "threshold": { "type": ["null", "number"] } + } + }, + "performanceMeasureCondition": { + "type": ["object", "null"], + "properties": { + "metricName": { "type": ["null", "string"] }, + "comparisonOperator": { "type": ["null", "string"] }, + "threshold": { "type": ["null", "number"] } + } + } + } + }, + "ruleStatusDetails": { + "type": ["null", "object"], + "additionalProperties": true + } + }, + "title": "sponsored_display_budget_rules", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_campaigns.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_campaigns.json new file mode 100644 index 000000000000..f243730a264b --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_campaigns.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "campaignId": { "type": ["null", "number"] }, + "name": { "type": ["null", "string"] }, + "budgetType": { "type": ["null", "string"] }, + "budget": { "type": ["null", "number"] }, + "startDate": { "type": ["null", "string"] }, + "endDate": { "type": ["null", "string"] }, + "costType": { "type": ["null", "string"] }, + "state": { "type": ["null", "string"] }, + "portfolioId": { "type": ["null", "integer"] }, + "tactic": { "type": ["null", "string"] }, + "deliveryProfile": { "type": ["null", "string"] } + }, + "title": "sponsored_display_campaigns", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_creatives.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_creatives.json new file mode 100644 index 000000000000..e9e88d46bcc0 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_creatives.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "adGroupId": { "type": ["null", "number"] }, + "creativeId": { "type": ["null", "number"] }, + "creativeType": { "type": ["null", "string"] }, + "properties": { "type": ["null", "object"] }, + "moderationStatus": { "type": ["null", "string"] } + }, + "title": "sponsored_display_creatives", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_product_ads.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_product_ads.json new file mode 100644 index 000000000000..3381bd7b65b3 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_product_ads.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "state": { "type": ["null", "string"] }, + "adId": { "type": ["null", "number"] }, + "campaignId": { "type": ["null", "number"] }, + "adGroupId": { "type": ["null", "number"] }, + "asin": { "type": ["null", "string"] }, + "sku": { "type": ["null", "string"] } + }, + "title": "sponsored_display_product_ads", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_report_stream.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_report_stream.json new file mode 100644 index 000000000000..9bbacd40ff50 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_report_stream.json @@ -0,0 +1,96 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "profileId": { "type": ["null", "integer"] }, + "recordType": { "type": ["null", "string"] }, + "reportDate": { "type": ["null", "string"] }, + "recordId": { "type": ["null", "string"] }, + "metric": { + "type": ["object", "null"], + "properties": { + "videoUnmutes": { "type": ["null", "string"] }, + "royaltyQualifiedBorrowsFromClicks": { "type": ["null", "string"] }, + "newToBrandDetailPageViewClicks": { "type": ["null", "string"] }, + "videoCompleteViews": { "type": ["null", "string"] }, + "unitsSold": { "type": ["null", "string"] }, + "newToBrandPurchases": { "type": ["null", "string"] }, + "addToListFromClicks": { "type": ["null", "string"] }, + "videoMidpointViews": { "type": ["null", "string"] }, + "adGroupId": { "type": ["null", "string"] }, + "campaignStatus": { "type": ["null", "string"] }, + "brandedSearches": { "type": ["null", "string"] }, + "eCPAddToCart": { "type": ["null", "string"] }, + "qualifiedBorrowsFromClicks": { "type": ["null", "string"] }, + "detailPageViews": { "type": ["null", "string"] }, + "sales": { "type": ["null", "string"] }, + "viewabilityRate": { "type": ["null", "string"] }, + "newToBrandECPDetailPageView": { "type": ["null", "string"] }, + "purchases": { "type": ["null", "string"] }, + "newToBrandUnitsSold": { "type": ["null", "string"] }, + "campaignName": { "type": ["null", "string"] }, + "clicks": { "type": ["null", "string"] }, + "addToList": { "type": ["null", "string"] }, + "campaignBudgetAmount": { "type": ["null", "string"] }, + "royaltyQualifiedBorrowsFromViews": { "type": ["null", "string"] }, + "unitsSoldClicks": { "type": ["null", "string"] }, + "brandedSearchesClicks": { "type": ["null", "string"] }, + "addToCartRate": { "type": ["null", "string"] }, + "newToBrandDetailPageViewRate": { "type": ["null", "string"] }, + "endDate": { "type": ["null", "string"] }, + "targetingText": { "type": ["null", "string"] }, + "unitsSoldBrandHalo": { "type": ["null", "string"] }, + "videoFirstQuartileViews": { "type": ["null", "string"] }, + "adId": { "type": ["null", "string"] }, + "costType": { "type": ["null", "string"] }, + "newToBrandUnitsSoldClicks": { "type": ["null", "string"] }, + "brandedSearchesViews": { "type": ["null", "string"] }, + "leads": { "type": ["null", "string"] }, + "startDate": { "type": ["null", "string"] }, + "linkOuts": { "type": ["null", "string"] }, + "qualifiedBorrowsFromViews": { "type": ["null", "string"] }, + "addToListFromViews": { "type": ["null", "string"] }, + "addToCart": { "type": ["null", "string"] }, + "campaignId": { "type": ["null", "string"] }, + "newToBrandSalesClicks": { "type": ["null", "string"] }, + "detailPageViewsClicks": { "type": ["null", "string"] }, + "promotedSku": { "type": ["null", "string"] }, + "newToBrandPurchasesClicks": { "type": ["null", "string"] }, + "salesBrandHaloClicks": { "type": ["null", "string"] }, + "salesPromotedClicks": { "type": ["null", "string"] }, + "newToBrandDetailPageViews": { "type": ["null", "string"] }, + "conversionsBrandHaloClicks": { "type": ["null", "string"] }, + "addToCartClicks": { "type": ["null", "string"] }, + "unitsSoldBrandHaloClicks": { "type": ["null", "string"] }, + "eCPBrandSearch": { "type": ["null", "string"] }, + "conversionsBrandHalo": { "type": ["null", "string"] }, + "promotedAsin": { "type": ["null", "string"] }, + "addToCartViews": { "type": ["null", "string"] }, + "qualifiedBorrows": { "type": ["null", "string"] }, + "impressionsViews": { "type": ["null", "string"] }, + "leadFormOpens": { "type": ["null", "string"] }, + "newToBrandSales": { "type": ["null", "string"] }, + "newToBrandDetailPageViewViews": { "type": ["null", "string"] }, + "purchasesPromotedClicks": { "type": ["null", "string"] }, + "salesClicks": { "type": ["null", "string"] }, + "salesBrandHalo": { "type": ["null", "string"] }, + "targetingId": { "type": ["null", "string"] }, + "purchasesClicks": { "type": ["null", "string"] }, + "impressions": { "type": ["null", "string"] }, + "cost": { "type": ["null", "string"] }, + "royaltyQualifiedBorrows": { "type": ["null", "string"] }, + "targetingExpression": { "type": ["null", "string"] }, + "brandedSearchRate": { "type": ["null", "string"] }, + "impressionsFrequencyAverage": { "type": ["null", "string"] }, + "bidOptimization": { "type": ["null", "string"] }, + "videoThirdQuartileViews": { "type": ["null", "string"] }, + "cumulativeReach": { "type": ["null", "string"] }, + "asinBrandHalo": { "type": ["null", "string"] }, + "adGroupName": { "type": ["null", "string"] }, + "campaignBudgetCurrencyCode": { "type": ["null", "string"] }, + "viewClickThroughRate": { "type": ["null", "string"] } + } + } + }, + "title": "sponsored_display_report_stream", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_targetings.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_targetings.json new file mode 100644 index 000000000000..86a1ddf5f5a6 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_display_targetings.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "targetId": { "type": ["null", "number"] }, + "adGroupId": { "type": ["null", "number"] }, + "state": { "type": ["null", "string"] }, + "expressionType": { "type": ["null", "string"] }, + "bid": { "type": ["null", "number"] }, + "campaignId": { "type": ["null", "number"] }, + "expression": { + "type": "array", + "items": { "type": ["null", "object"], "additionalProperties": true } + }, + "resolvedExpression": { + "type": "array", + "items": { "type": ["null", "object"], "additionalProperties": true } + } + }, + "title": "sponsored_display_targetings", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_ad_group_bid_recommendations.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_ad_group_bid_recommendations.json new file mode 100644 index 000000000000..cb895d6c08e2 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_ad_group_bid_recommendations.json @@ -0,0 +1,29 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "adGroupId": { "type": ["null", "string"] }, + "campaignId": { "type": ["null", "string"] }, + "theme": { "type": ["null", "string"] }, + "bidRecommendationsForTargetingExpressions": { + "type": "array", + "items": { + "type": ["object", "null"], + "properties": { + "bidValues": { + "type": "array", + "items": { + "type": ["null", "object"], + "additionalProperties": true + } + }, + "targetingExpression": { + "type": ["null", "object"], + "additionalProperties": true + } + } + } + } + }, + "title": "sponsored_product_ad_group_bid_recommendations", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_ad_group_suggested_keywords.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_ad_group_suggested_keywords.json new file mode 100644 index 000000000000..6a5afdb755de --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_ad_group_suggested_keywords.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "adGroupId": { "type": ["null", "integer"] }, + "suggestedKeywords": { + "type": ["null", "array"], + "items": { + "type": ["object", "null"], + "properties": { + "keywordText": { "type": ["null", "string"] }, + "matchType": { "type": ["null", "string"] } + } + } + } + }, + "title": "sponsored_product_ad_group_suggested_keywords", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_ad_groups.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_ad_groups.json new file mode 100644 index 000000000000..902592a5567f --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_ad_groups.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "adGroupId": { "type": ["null", "string"] }, + "name": { "type": ["null", "string"] }, + "campaignId": { "type": ["null", "string"] }, + "defaultBid": { "type": ["null", "number"] }, + "state": { "type": ["null", "string"] }, + "extendedData": { "type": ["null", "object"] } + }, + "title": "sponsored_product_ad_groups", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_ads.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_ads.json new file mode 100644 index 000000000000..8719813651c2 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_ads.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "adId": { "type": ["null", "string"] }, + "campaignId": { "type": ["null", "string"] }, + "customText": { "type": ["null", "string"] }, + "asin": { "type": ["null", "string"] }, + "state": { "type": ["null", "string"] }, + "sku": { "type": ["null", "string"] }, + "adGroupId": { "type": ["null", "string"] }, + "extendedData": { "type": ["null", "object"] } + }, + "title": "sponsored_product_ads", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_campaign_negative_keywords.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_campaign_negative_keywords.json new file mode 100644 index 000000000000..f8a439d82ec7 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_campaign_negative_keywords.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "keywordId": { "type": ["null", "string"] }, + "campaignId": { "type": ["null", "string"] }, + "adGroupId": { "type": ["null", "number"] }, + "state": { "type": ["null", "string"] }, + "keywordText": { "type": ["null", "string"] }, + "extendedData": { "type": ["null", "object"] } + }, + "title": "sponsored_product_campaign_negative_keywords", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_campaigns.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_campaigns.json new file mode 100644 index 000000000000..a5864bfb9c11 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_campaigns.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "portfolioId": { "type": ["null", "string"] }, + "campaignId": { "type": ["null", "string"] }, + "name": { "type": ["null", "string"] }, + "tags": { "type": ["null", "object"], "additionalProperties": true }, + "targetingType": { "type": ["null", "string"] }, + "state": { "type": ["null", "string"] }, + "dynamicBidding": { "type": ["null", "object"] }, + "startDate": { "type": ["null", "string"] }, + "endDate": { "type": ["null", "string"] }, + "budget": { "type": ["null", "object"] }, + "extendedData": { "type": ["null", "object"] } + }, + "title": "sponsored_product_campaigns", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_keywords.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_keywords.json new file mode 100644 index 000000000000..9c1e8b755145 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_keywords.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "keywordId": { "type": ["null", "string"] }, + "campaignId": { "type": ["null", "string"] }, + "adGroupId": { "type": ["null", "string"] }, + "state": { "type": ["null", "string"] }, + "keywordText": { "type": ["null", "string"] }, + "nativeLanguageLocale": { "type": ["null", "string"] }, + "extendedData": { "type": ["null", "object"] } + }, + "title": "sponsored_product_keywords", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_negative_keywords.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_negative_keywords.json new file mode 100644 index 000000000000..c1b847949b24 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_negative_keywords.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "keywordId": { "type": ["null", "string"] }, + "campaignId": { "type": ["null", "string"] }, + "adGroupId": { "type": ["null", "string"] }, + "state": { "type": ["null", "string"] }, + "keywordText": { "type": ["null", "string"] }, + "nativeLanguageLocale": { "type": ["null", "string"] }, + "extendedData": { "type": ["null", "object"] } + }, + "title": "sponsored_product_negative_keywords", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_targetings.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_targetings.json new file mode 100644 index 000000000000..bb206b1fba35 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_product_targetings.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "expression": { + "type": ["null", "array"], + "items": { "type": ["null", "object"], "additionalProperties": true } + }, + "targetId": { "type": ["null", "string"] }, + "resolvedExpression": { + "type": "array", + "items": { "type": ["null", "object"], "additionalProperties": true } + }, + "campaignId": { "type": ["null", "string"] }, + "expressionType": { "type": ["null", "string"] }, + "state": { "type": ["null", "string"] }, + "bid": { "type": ["null", "number"] }, + "adGroupId": { "type": ["null", "string"] }, + "extendedData": { "type": ["null", "object"] } + }, + "title": "sponsored_product_targetings", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_products.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_products.py deleted file mode 100644 index 6ef9a7b5ff1d..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_products.py +++ /dev/null @@ -1,114 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from decimal import Decimal -from typing import Any, Dict, List, Optional - -from .common import CatalogModel, KeywordsBase - - -class Adjustments(CatalogModel): - predicate: str - percentage: Decimal - - -class Bidding(CatalogModel): - strategy: str - adjustments: List[Adjustments] - - -class ProductCampaign(CatalogModel): - portfolioId: str - campaignId: str - name: str - tags: Dict[str, str] - targetingType: str - state: str - dynamicBidding: Dict[str, Any] - startDate: str - endDate: str - budget: Dict[str, Any] - extendedData: Optional[Dict[str, Any]] - - -class ProductAdGroups(CatalogModel): - adGroupId: str - name: str - campaignId: str - defaultBid: Decimal - state: str - extendedData: dict - - -class BidRecommendations(CatalogModel): - bidValues: List[Dict[str, str]] - targetingExpression: Dict[str, str] - - -class ProductAdGroupBidRecommendations(CatalogModel): - adGroupId: str - campaignId: str - theme: str - bidRecommendationsForTargetingExpressions: List[BidRecommendations] - - -class SuggestedKeyword(CatalogModel): - keywordText: str - matchType: str - - -class ProductAdGroupSuggestedKeywords(CatalogModel): - adGroupId: int - suggestedKeywords: List[SuggestedKeyword] = None - - -class ProductAd(CatalogModel): - adId: str - campaignId: str - customText: str - asin: str - state: str - sku: str - adGroupId: str - extendedData: Optional[Dict[str, Any]] - - -class ProductTargeting(CatalogModel): - expression: List[Dict[str, str]] - targetId: str - resolvedExpression: List[Dict[str, str]] - campaignId: str - expressionType: str - state: str - bid: float - adGroupId: str - extendedData: Optional[Dict[str, Any]] - - -class SponsoredProductCampaignNegativeKeywordsModel(KeywordsBase): - keywordId: str - campaignId: str - state: str - keywordText: str - extendedData: Optional[Dict[str, Any]] - - -class SponsoredProductKeywordsModel(KeywordsBase): - keywordId: str - nativeLanguageLocale: str - campaignId: str - state: str - adGroupId: str - keywordText: str - extendedData: Optional[Dict[str, Any]] - - -class SponsoredProductNegativeKeywordsModel(KeywordsBase): - keywordId: str - nativeLanguageLocale: str - campaignId: str - state: str - adGroupId: str - keywordText: str - extendedData: Optional[Dict[str, Any]] diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_products_report_stream.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_products_report_stream.json new file mode 100644 index 000000000000..0c2a7ce9c560 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/schemas/sponsored_products_report_stream.json @@ -0,0 +1,70 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "profileId": { "type": ["null", "integer"] }, + "recordType": { "type": ["null", "string"] }, + "reportDate": { "type": ["null", "string"] }, + "recordId": { "type": ["null", "string"] }, + "metric": { + "type": ["object", "null"], + "properties": { + "advertisedAsin": { "type": ["null", "string"] }, + "unitsSoldSameSku1d": { "type": ["null", "string"] }, + "unitsSoldSameSku30d": { "type": ["null", "string"] }, + "campaignApplicableBudgetRuleId": { "type": ["null", "string"] }, + "matchType": { "type": ["null", "string"] }, + "purchasesSameSku1d": { "type": ["null", "string"] }, + "unitsSoldClicks7d": { "type": ["null", "string"] }, + "adGroupId": { "type": ["null", "string"] }, + "campaignStatus": { "type": ["null", "string"] }, + "advertisedSku": { "type": ["null", "string"] }, + "campaignRuleBasedBudgetAmount": { "type": ["null", "string"] }, + "unitsSoldSameSku7d": { "type": ["null", "string"] }, + "keywordId": { "type": ["null", "string"] }, + "campaignApplicableBudgetRuleName": { "type": ["null", "string"] }, + "keyword": { "type": ["null", "string"] }, + "sales30d": { "type": ["null", "string"] }, + "campaignName": { "type": ["null", "string"] }, + "clicks": { "type": ["null", "string"] }, + "purchasesSameSku7d": { "type": ["null", "string"] }, + "salesOtherSku14d": { "type": ["null", "string"] }, + "attributedSalesSameSku30d": { "type": ["null", "string"] }, + "salesOtherSku30d": { "type": ["null", "string"] }, + "campaignBudgetAmount": { "type": ["null", "string"] }, + "purchasesSameSku14d": { "type": ["null", "string"] }, + "sales14d": { "type": ["null", "string"] }, + "purchasedAsin": { "type": ["null", "string"] }, + "sales7d": { "type": ["null", "string"] }, + "attributedSalesSameSku14d": { "type": ["null", "string"] }, + "unitsSoldOtherSku30d": { "type": ["null", "string"] }, + "targeting": { "type": ["null", "string"] }, + "salesOtherSku7d": { "type": ["null", "string"] }, + "attributedSalesSameSku7d": { "type": ["null", "string"] }, + "salesOtherSku1d": { "type": ["null", "string"] }, + "purchases14d": { "type": ["null", "string"] }, + "purchases1d": { "type": ["null", "string"] }, + "campaignId": { "type": ["null", "string"] }, + "unitsSoldClicks30d": { "type": ["null", "string"] }, + "unitsSoldClicks14d": { "type": ["null", "string"] }, + "sales1d": { "type": ["null", "string"] }, + "unitsSoldOtherSku1d": { "type": ["null", "string"] }, + "purchases7d": { "type": ["null", "string"] }, + "keywordType": { "type": ["null", "string"] }, + "unitsSoldClicks1d": { "type": ["null", "string"] }, + "purchases30d": { "type": ["null", "string"] }, + "purchasesSameSku30d": { "type": ["null", "string"] }, + "unitsSoldOtherSku7d": { "type": ["null", "string"] }, + "impressions": { "type": ["null", "string"] }, + "attributedSalesSameSku1d": { "type": ["null", "string"] }, + "cost": { "type": ["null", "string"] }, + "unitsSoldOtherSku14d": { "type": ["null", "string"] }, + "unitsSoldSameSku14d": { "type": ["null", "string"] }, + "adId": { "type": ["null", "string"] }, + "adGroupName": { "type": ["null", "string"] }, + "campaignBudgetCurrencyCode": { "type": ["null", "string"] } + } + } + }, + "title": "sponsored_products_report_stream", + "type": ["null", "object"] +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/source.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/source.py index d65a949e48d5..8d41e57a5eea 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/source.py +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/source.py @@ -7,55 +7,26 @@ from typing import Any, List, Mapping, Optional, Tuple import pendulum -from airbyte_cdk.sources import AbstractSource + +from airbyte_cdk import TState +from airbyte_cdk.models import AdvancedAuth, AuthFlowType, ConfiguredAirbyteCatalog, ConnectorSpecification, OAuthConfigSpecification +from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http.requests_native_auth import Oauth2Authenticator -from .schemas import Profile -from .streams import ( - AttributionReportPerformanceAdgroup, - AttributionReportPerformanceCampaign, - AttributionReportPerformanceCreative, - AttributionReportProducts, - Portfolios, - Profiles, - SponsoredBrandsAdGroups, - SponsoredBrandsCampaigns, - SponsoredBrandsKeywords, - SponsoredBrandsReportStream, - SponsoredBrandsV3ReportStream, - SponsoredBrandsVideoReportStream, - SponsoredDisplayAdGroups, - SponsoredDisplayBudgetRules, - SponsoredDisplayCampaigns, - SponsoredDisplayCreatives, - SponsoredDisplayProductAds, - SponsoredDisplayReportStream, - SponsoredDisplayTargetings, - SponsoredProductAdGroupBidRecommendations, - SponsoredProductAdGroups, - SponsoredProductAdGroupSuggestedKeywords, - SponsoredProductAds, - SponsoredProductCampaignNegativeKeywords, - SponsoredProductCampaigns, - SponsoredProductKeywords, - SponsoredProductNegativeKeywords, - SponsoredProductsReportStream, - SponsoredProductTargetings, -) +from .spec import SourceAmazonAdsSpec +from .streams import Profiles, SponsoredBrandsV3ReportStream, SponsoredDisplayReportStream, SponsoredProductsReportStream + # Oauth 2.0 authentication URL for amazon TOKEN_URL = "https://api.amazon.com/auth/o2/token" -CONFIG_DATE_FORMAT = "YYYY-MM-DD" -class SourceAmazonAds(AbstractSource): +class SourceAmazonAds(YamlDeclarativeSource): + def __init__(self, catalog: Optional[ConfiguredAirbyteCatalog], config: Optional[Mapping[str, Any]], state: TState, **kwargs): + super().__init__(catalog=catalog, config=config, state=state, **{"path_to_yaml": "manifest.yaml"}) + def _validate_and_transform(self, config: Mapping[str, Any]) -> Mapping[str, Any]: - start_date = config.get("start_date") - if start_date: - config["start_date"] = pendulum.from_format(start_date, CONFIG_DATE_FORMAT).date() - else: - config["start_date"] = None if not config.get("region"): source_spec = self.spec(logging.getLogger("airbyte")) config["region"] = source_spec.connectionSpecification["properties"]["region"]["default"] @@ -107,36 +78,13 @@ def streams(self, config: Mapping[str, Any]) -> List[Stream]: profiles_list = profiles_stream.get_all_profiles() stream_args["profiles"] = self._choose_profiles(config, profiles_list) non_profile_stream_classes = [ - SponsoredDisplayCampaigns, - SponsoredDisplayAdGroups, - SponsoredDisplayCreatives, - SponsoredDisplayProductAds, - SponsoredDisplayTargetings, SponsoredDisplayReportStream, - SponsoredDisplayBudgetRules, - SponsoredProductCampaigns, - SponsoredProductAdGroups, - SponsoredProductAdGroupBidRecommendations, - SponsoredProductAdGroupSuggestedKeywords, - SponsoredProductKeywords, - SponsoredProductNegativeKeywords, - SponsoredProductCampaignNegativeKeywords, - SponsoredProductAds, - SponsoredProductTargetings, - SponsoredProductsReportStream, - SponsoredBrandsCampaigns, - SponsoredBrandsAdGroups, - SponsoredBrandsKeywords, - SponsoredBrandsReportStream, SponsoredBrandsV3ReportStream, - SponsoredBrandsVideoReportStream, - AttributionReportPerformanceAdgroup, - AttributionReportPerformanceCampaign, - AttributionReportPerformanceCreative, - AttributionReportProducts, + SponsoredProductsReportStream, + ] + return super().streams(config=config) + [ + *[stream_class(**stream_args) for stream_class in non_profile_stream_classes], ] - portfolios_stream = Portfolios(**stream_args) - return [profiles_stream, portfolios_stream, *[stream_class(**stream_args) for stream_class in non_profile_stream_classes]] @staticmethod def _make_authenticator(config: Mapping[str, Any]): @@ -148,13 +96,50 @@ def _make_authenticator(config: Mapping[str, Any]): ) @staticmethod - def _choose_profiles(config: Mapping[str, Any], available_profiles: List[Profile]): + def _choose_profiles(config: Mapping[str, Any], available_profiles: List[dict[str, Any]]): requested_profiles = config.get("profiles", []) requested_marketplace_ids = config.get("marketplace_ids", []) if requested_profiles or requested_marketplace_ids: return [ profile for profile in available_profiles - if profile.profileId in requested_profiles or profile.accountInfo.marketplaceStringId in requested_marketplace_ids + if profile["profileId"] in requested_profiles or profile["accountInfo"]["marketplaceStringId"] in requested_marketplace_ids ] return available_profiles + + def spec(self, logger: logging.Logger) -> ConnectorSpecification: + return ConnectorSpecification( + documentationUrl="https://docs.airbyte.com/integrations/sources/amazon-ads", + connectionSpecification=SourceAmazonAdsSpec.schema(), + supportsDBT=False, + advanced_auth=AdvancedAuth( + auth_flow_type=AuthFlowType.oauth2_0, + predicate_key=["auth_type"], + predicate_value="oauth2.0", + oauth_config_specification=OAuthConfigSpecification( + oauth_user_input_from_connector_config_specification={ + "type": "object", + "additionalProperties": False, + "properties": {"region": {"type": "string", "path_in_connector_config": ["region"]}}, + }, + complete_oauth_output_specification={ + "type": "object", + "additionalProperties": True, + "properties": {"refresh_token": {"type": "string", "path_in_connector_config": ["refresh_token"]}}, + }, + complete_oauth_server_input_specification={ + "type": "object", + "additionalProperties": True, + "properties": {"client_id": {"type": "string"}, "client_secret": {"type": "string"}}, + }, + complete_oauth_server_output_specification={ + "type": "object", + "additionalProperties": True, + "properties": { + "client_id": {"type": "string", "path_in_connector_config": ["client_id"]}, + "client_secret": {"type": "string", "path_in_connector_config": ["client_secret"]}, + }, + }, + ), + ), + ) diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/spec.json b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/spec.json new file mode 100644 index 000000000000..f131594106f3 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/spec.json @@ -0,0 +1,173 @@ +{ + "connectionSpecification": { + "title": "Source Amazon Ads", + "type": "object", + "properties": { + "auth_type": { + "title": "Auth Type", + "default": "oauth2.0", + "const": "oauth2.0", + "order": 0, + "type": "string" + }, + "client_id": { + "title": "Client ID", + "description": "The client ID of your Amazon Ads developer application. See the docs for more information.", + "airbyte_secret": true, + "order": 1, + "type": "string" + }, + "client_secret": { + "title": "Client Secret", + "description": "The client secret of your Amazon Ads developer application. See the docs for more information.", + "airbyte_secret": true, + "order": 2, + "type": "string" + }, + "refresh_token": { + "title": "Refresh Token", + "description": "Amazon Ads refresh token. See the docs for more information on how to obtain this token.", + "airbyte_secret": true, + "order": 3, + "type": "string" + }, + "region": { + "title": "Region", + "description": "Region to pull data from (EU/NA/FE). See docs for more details.", + "default": "NA", + "enum": ["NA", "EU", "FE"], + "order": 4, + "type": "string" + }, + "start_date": { + "title": "Start Date", + "description": "The Start date for collecting reports, should not be more than 60 days in the past. In YYYY-MM-DD format", + "examples": ["2022-10-10", "2022-10-22"], + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$", + "order": 5, + "type": "string", + "format": "date" + }, + "profiles": { + "title": "Profile IDs", + "description": "Profile IDs you want to fetch data for. The Amazon Ads source connector supports only profiles with seller and vendor type, profiles with agency type will be ignored. See docs for more details. Note: If Marketplace IDs are also selected, profiles will be selected if they match the Profile ID OR the Marketplace ID.", + "order": 6, + "type": "array", + "items": { + "type": "integer" + } + }, + "marketplace_ids": { + "title": "Marketplace IDs", + "description": "Marketplace IDs you want to fetch data for. Note: If Profile IDs are also selected, profiles will be selected if they match the Profile ID OR the Marketplace ID.", + "order": 7, + "type": "array", + "items": { + "type": "string" + } + }, + "state_filter": { + "title": "State Filter", + "description": "Reflects the state of the Display, Product, and Brand Campaign streams as enabled, paused, or archived. If you do not populate this field, it will be ignored completely.", + "default": [], + "order": 8, + "type": "array", + "items": { + "title": "StateFilterEnum", + "description": "An enumeration.", + "enum": ["enabled", "paused", "archived"], + "type": "string" + }, + "uniqueItems": true + }, + "look_back_window": { + "title": "Look Back Window", + "description": "The amount of days to go back in time to get the updated data from Amazon Ads", + "default": 3, + "examples": [3, 10], + "order": 9, + "type": "integer" + }, + "report_record_types": { + "title": "Report Record Types", + "description": "Optional configuration which accepts an array of string of record types. Leave blank for default behaviour to pull all report types. Use this config option only if you want to pull specific report type(s). See docs for more details", + "default": [], + "order": 10, + "type": "array", + "items": { + "title": "ReportRecordTypeEnum", + "description": "An enumeration.", + "enum": [ + "adGroups", + "asins", + "asins_keywords", + "asins_targets", + "campaigns", + "keywords", + "productAds", + "targets" + ], + "type": "string" + }, + "uniqueItems": true + } + }, + "required": ["client_id", "client_secret", "refresh_token"] + }, + "documentationUrl": "https://docs.airbyte.com/integrations/sources/amazon-ads", + "supportsNormalization": false, + "supportsDBT": false, + "advanced_auth": { + "auth_flow_type": "oauth2.0", + "predicate_key": ["auth_type"], + "predicate_value": "oauth2.0", + "oauth_config_specification": { + "oauth_user_input_from_connector_config_specification": { + "type": "object", + "additionalProperties": false, + "properties": { + "region": { + "type": "string", + "path_in_connector_config": ["region"] + } + } + }, + "complete_oauth_output_specification": { + "type": "object", + "additionalProperties": true, + "properties": { + "refresh_token": { + "type": "string", + "path_in_connector_config": ["refresh_token"] + } + } + }, + "complete_oauth_server_input_specification": { + "type": "object", + "additionalProperties": true, + "properties": { + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + } + } + }, + "complete_oauth_server_output_specification": { + "type": "object", + "additionalProperties": true, + "properties": { + "client_id": { + "type": "string", + "path_in_connector_config": ["client_id"] + }, + "client_secret": { + "type": "string", + "path_in_connector_config": ["client_secret"] + } + } + } + } + } +} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/spec.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/spec.py new file mode 100644 index 000000000000..555e17e9c584 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/spec.py @@ -0,0 +1,104 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + + +from datetime import date +from enum import Enum +from typing import List, Optional + +from pydantic.v1 import Field + +from airbyte_cdk.sources.config import BaseConfig + + +class StateFilterEnum(str, Enum): + enabled = "enabled" + paused = "paused" + archived = "archived" + + +class ReportRecordTypeEnum(str, Enum): + adGroups = "adGroups" + asins = "asins" + asins_keywords = "asins_keywords" + asins_targets = "asins_targets" + campaigns = "campaigns" + keywords = "keywords" + productAds = "productAds" + targets = "targets" + + +class SourceAmazonAdsSpec(BaseConfig): + class Config: + title = "Source Amazon Ads" + use_enum_values = True + + auth_type: str = Field("oauth2.0", const=True, title="Auth Type", order=0) + client_id: str = Field( + ..., + description='The client ID of your Amazon Ads developer application. See the docs for more information.', + title="Client ID", + airbyte_secret=True, + order=1, + ) + client_secret: str = Field( + ..., + description='The client secret of your Amazon Ads developer application. See the docs for more information.', + title="Client Secret", + airbyte_secret=True, + order=2, + ) + refresh_token: str = Field( + ..., + description='Amazon Ads refresh token. See the docs for more information on how to obtain this token.', + title="Refresh Token", + airbyte_secret=True, + order=3, + ) + region: Optional[str] = Field( + "NA", + description='Region to pull data from (EU/NA/FE). See docs for more details.', + title="Region", + enum=["NA", "EU", "FE"], + order=4, + ) + start_date: Optional[date] = Field( + None, + description="The Start date for collecting reports, should not be more than 60 days in the past. In YYYY-MM-DD format", + examples=["2022-10-10", "2022-10-22"], + pattern="^[0-9]{4}-[0-9]{2}-[0-9]{2}$", + title="Start Date", + order=5, + ) + profiles: Optional[List[int]] = Field( + None, + description='Profile IDs you want to fetch data for. The Amazon Ads source connector supports only profiles with seller and vendor type, profiles with agency type will be ignored. See docs for more details. Note: If Marketplace IDs are also selected, profiles will be selected if they match the Profile ID OR the Marketplace ID.', + title="Profile IDs", + order=6, + ) + marketplace_ids: Optional[List[str]] = Field( + None, + description="Marketplace IDs you want to fetch data for. Note: If Profile IDs are also selected, profiles will be selected if they match the Profile ID OR the Marketplace ID.", + title="Marketplace IDs", + order=7, + ) + state_filter: Optional[List[StateFilterEnum]] = Field( + default=[], + description="Reflects the state of the Display, Product, and Brand Campaign streams as enabled, paused, or archived. If you do not populate this field, it will be ignored completely.", + title="State Filter", + unique_items=True, + order=8, + ) + look_back_window: Optional[int] = Field( + 3, + description="The amount of days to go back in time to get the updated data from Amazon Ads", + examples=[3, 10], + title="Look Back Window", + order=9, + ) + report_record_types: Optional[List[ReportRecordTypeEnum]] = Field( + [], + description='Optional configuration which accepts an array of string of record types. Leave blank for default behaviour to pull all report types. Use this config option only if you want to pull specific report type(s). See docs for more details', + title="Report Record Types", + unique_items=True, + order=10, + ) diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/__init__.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/__init__.py index caa39bccfc91..ac9f78d7503c 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/__init__.py +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/__init__.py @@ -1,74 +1,16 @@ # # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # -from .attribution_report import ( - AttributionReportPerformanceAdgroup, - AttributionReportPerformanceCampaign, - AttributionReportPerformanceCreative, - AttributionReportProducts, -) -from .portfolios import Portfolios from .profiles import Profiles from .report_streams import ( - SponsoredBrandsReportStream, SponsoredBrandsV3ReportStream, - SponsoredBrandsVideoReportStream, SponsoredDisplayReportStream, SponsoredProductsReportStream, ) -from .sponsored_brands import ( - SponsoredBrandsAdGroups, - SponsoredBrandsCampaigns, - SponsoredBrandsKeywords -) -from .sponsored_display import ( - SponsoredDisplayAdGroups, - SponsoredDisplayBudgetRules, - SponsoredDisplayCampaigns, - SponsoredDisplayCreatives, - SponsoredDisplayProductAds, - SponsoredDisplayTargetings, -) -from .sponsored_products import ( - SponsoredProductAdGroupBidRecommendations, - SponsoredProductAdGroups, - SponsoredProductAdGroupSuggestedKeywords, - SponsoredProductAds, - SponsoredProductCampaignNegativeKeywords, - SponsoredProductCampaigns, - SponsoredProductKeywords, - SponsoredProductNegativeKeywords, - SponsoredProductTargetings, -) __all__ = [ - "Portfolios", "Profiles", - "SponsoredDisplayAdGroups", - "SponsoredDisplayCampaigns", - "SponsoredDisplayProductAds", - "SponsoredDisplayTargetings", - "SponsoredDisplayBudgetRules", - "SponsoredProductAdGroups", - "SponsoredDisplayCreatives", - "SponsoredProductAdGroupBidRecommendations", - "SponsoredProductAdGroupSuggestedKeywords", - "SponsoredProductAds", - "SponsoredProductCampaigns", - "SponsoredProductKeywords", - "SponsoredProductNegativeKeywords", - "SponsoredProductCampaignNegativeKeywords", - "SponsoredProductTargetings", - "SponsoredBrandsCampaigns", - "SponsoredBrandsAdGroups", - "SponsoredBrandsKeywords", "SponsoredDisplayReportStream", "SponsoredProductsReportStream", - "SponsoredBrandsReportStream", "SponsoredBrandsV3ReportStream", - "SponsoredBrandsVideoReportStream", - "AttributionReportPerformanceAdgroup", - "AttributionReportPerformanceCampaign", - "AttributionReportPerformanceCreative", - "AttributionReportProducts", ] diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/attribution_report.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/attribution_report.py deleted file mode 100644 index 4c683846e6d2..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/attribution_report.py +++ /dev/null @@ -1,182 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Iterable, List, Mapping, Optional - -import pendulum -import requests -from airbyte_cdk.models import SyncMode -from requests.exceptions import HTTPError -from source_amazon_ads.schemas import AttributionReportModel -from source_amazon_ads.streams.common import AmazonAdsStream - -BRAND_REFERRAL_BONUS = "brb_bonus_amount" - -METRICS_MAP = { - "PERFORMANCE": [ - "Click-throughs", - "attributedDetailPageViewsClicks14d", - "attributedAddToCartClicks14d", - "attributedPurchases14d", - "unitsSold14d", - "attributedSales14d", - "attributedTotalDetailPageViewsClicks14d", - "attributedTotalAddToCartClicks14d", - "attributedTotalPurchases14d", - "totalUnitsSold14d", - "totalAttributedSales14d", - ], - "PRODUCTS": [ - "attributedDetailPageViewsClicks14d", - "attributedAddToCartClicks14d", - "attributedPurchases14d", - "unitsSold14d", - "attributedSales14d", - "brandHaloDetailPageViewsClicks14d", - "brandHaloAttributedAddToCartClicks14d", - "brandHaloAttributedPurchases14d", - "brandHaloUnitsSold14d", - "brandHaloAttributedSales14d", - "attributedNewToBrandPurchases14d", - "attributedNewToBrandUnitsSold14d", - "attributedNewToBrandSales14d", - "brandHaloNewToBrandPurchases14d", - "brandHaloNewToBrandUnitsSold14d", - "brandHaloNewToBrandSales14d", - ], -} - - -class AttributionReport(AmazonAdsStream): - """ - This stream corresponds to Amazon Advertising API - Attribution Reports - https://advertising.amazon.com/API/docs/en-us/amazon-attribution-prod-3p/#/ - """ - - model = AttributionReportModel - primary_key = None - data_field = "reports" - page_size = 300 - - report_type = "" - custom_metrics = [] - group_by = "" - - _next_page_token_field = "cursorId" - _current_profile_id = "" - - REPORT_DATE_FORMAT = "YYYYMMDD" - CONFIG_DATE_FORMAT = "YYYY-MM-DD" - REPORTING_PERIOD = 90 - - def __init__(self, config: Mapping[str, Any], *args, **kwargs): - self._start_date = config.get("start_date") - super().__init__(config, *args, **kwargs) - - @property - def metrics(self): - return METRICS_MAP[self.report_type] + self.custom_metrics - - @property - def http_method(self) -> str: - return "POST" - - def path(self, **kwargs) -> str: - return "/attribution/report" - - def get_json_schema(self): - schema = super().get_json_schema() - metrics_type_map = {metric: {"type": ["null", "string"]} for metric in self.metrics} - schema["properties"].update(metrics_type_map) - return schema - - def stream_slices( - self, sync_mode: SyncMode, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None - ) -> Iterable[Optional[Mapping[str, Any]]]: - for profile in self._profiles: - start_date = pendulum.now(tz=profile.timezone).subtract(days=1).date() - end_date = pendulum.now(tz=profile.timezone).date() - if self._start_date: - start_date = max(self._start_date, end_date.subtract(days=self.REPORTING_PERIOD)) - - yield { - "profileId": profile.profileId, - "startDate": start_date.format(self.REPORT_DATE_FORMAT), - "endDate": end_date.format(self.REPORT_DATE_FORMAT), - } - - def read_records( - self, - sync_mode: SyncMode, - cursor_field: List[str] = None, - stream_slice: Mapping[str, Any] = None, - stream_state: Mapping[str, Any] = None, - ) -> Iterable[Mapping[str, Any]]: - try: - yield from super().read_records(sync_mode, cursor_field, stream_slice, stream_state) - except HTTPError as e: - if e.response.status_code == 400: - if e.response.json()["message"] == "This profileID is not authorized to use Amazon Attribution": - self.logger.warning(f"This profileID {stream_slice['profileId']} is not authorized to use Amazon Attribution") - return - raise e - - def request_headers( - self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None - ) -> Mapping[str, Any]: - headers = super().request_headers(stream_state, stream_slice, next_page_token) - headers["Amazon-Advertising-API-Scope"] = str(stream_slice["profileId"]) - return headers - - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - stream_data = response.json() - next_page_token = stream_data.get(self._next_page_token_field) - if next_page_token: - return {self._next_page_token_field: next_page_token} - - def request_body_json( - self, - stream_state: Mapping[str, Any], - stream_slice: Mapping[str, Any] = None, - next_page_token: Mapping[str, Any] = None, - ) -> Optional[Mapping]: - - body = { - "reportType": self.report_type, - "count": self.page_size, - "metrics": ",".join(self.metrics), - "startDate": stream_slice["startDate"], - "endDate": stream_slice["endDate"], - self._next_page_token_field: "", - } - - if self.group_by: - body["groupBy"] = self.group_by - - if next_page_token: - body[self._next_page_token_field] = next_page_token[self._next_page_token_field] - - return body - - -class AttributionReportProducts(AttributionReport): - report_type = "PRODUCTS" - group_by = "" - - -class AttributionReportPerformanceCreative(AttributionReport): - report_type = "PERFORMANCE" - group_by = "CREATIVE" - - -class AttributionReportPerformanceAdgroup(AttributionReport): - report_type = "PERFORMANCE" - custom_metrics = [BRAND_REFERRAL_BONUS] - group_by = "ADGROUP" - - -class AttributionReportPerformanceCampaign(AttributionReport): - report_type = "PERFORMANCE" - custom_metrics = [BRAND_REFERRAL_BONUS] - group_by = "CAMPAIGN" diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/common.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/common.py index 9ad9bb481f94..3ed493d99d67 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/common.py +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/common.py @@ -1,19 +1,20 @@ # # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # - -from abc import ABC, abstractmethod +import logging +from abc import ABC from http import HTTPStatus -from typing import Any, Iterable, List, Mapping, MutableMapping, Optional +from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Union import requests +from pydantic.v1 import BaseModel, ValidationError + +from airbyte_cdk.models import FailureType from airbyte_cdk.sources.streams.core import Stream from airbyte_cdk.sources.streams.http import HttpStream -from airbyte_cdk.sources.utils.schema_helpers import expand_refs -from pydantic import BaseModel, ValidationError +from airbyte_cdk.sources.streams.http.error_handlers import ErrorHandler, ErrorResolution, HttpStatusErrorHandler, ResponseAction from source_amazon_ads.constants import URL_MAPPING -from source_amazon_ads.schemas import CatalogModel -from source_amazon_ads.schemas.profile import Profile + """ This class hierarchy may seem overcomplicated so here is a visualization of @@ -25,24 +26,7 @@ class to provide explanation why it had been done in this way. │ └── AmazonAdsStream │ ├── Profiles │ ├── Portfolios - │ └── SubProfilesStream - │ ├── SponsoredDisplayAdGroups - │ ├── SponsoredDisplayCampaigns - │ ├── SponsoredDisplayProductAds - │ ├── SponsoredDisplayTargetings - │ ├── SponsoredProductsV3 - │ | ├── SponsoredProductAdGroups - │ | ├── SponsoredProductAds - │ | ├── SponsoredProductCampaigns - │ | ├── SponsoredProductKeywords - │ | ├── SponsoredProductNegativeKeywords - │ | └── SponsoredProductTargetings - │ ├── SponsoredBrandsV4 - │ | ├── SponsoredBrandsCampaigns - │ | └── SponsoredBrandsAdGroups - │ └── SponsoredBrandsKeywords └── ReportStream - ├── SponsoredBrandsReportStream ├── SponsoredBrandsV3ReportStream ├── SponsoredDisplayReportStream └── SponsoredProductsReportStream @@ -65,6 +49,8 @@ class to provide explanation why it had been done in this way. """ +LOGGER = logging.getLogger("airbyte") + class ErrorResponse(BaseModel): code: str @@ -72,28 +58,38 @@ class ErrorResponse(BaseModel): requestId: Optional[str] +class AmazonAdsErrorHandler(HttpStatusErrorHandler): + def interpret_response(self, response_or_exception: Optional[Union[requests.Response, Exception]] = None) -> ErrorResolution: + if response_or_exception.status_code == HTTPStatus.OK: + return ErrorResolution(ResponseAction.SUCCESS) + + try: + resp = ErrorResponse.parse_raw(response_or_exception.text) + except ValidationError: + return ErrorResolution( + response_action=ResponseAction.FAIL, + failure_type=FailureType.system_error, + error_message=f"Response status code: {response_or_exception.status_code}. Unexpected error. {response_or_exception.text=}", + ) + + LOGGER.warning( + f"Unexpected error {resp.code} when processing request {response_or_exception.request.url} for " + f"{response_or_exception.request.headers['Amazon-Advertising-API-Scope']} profile: {resp.details}" + ) + + return ErrorResolution(ResponseAction.SUCCESS) + + class BasicAmazonAdsStream(Stream, ABC): """ Base class for all Amazon Ads streams. """ - def __init__(self, config: Mapping[str, Any], profiles: List[Profile] = None): + def __init__(self, config: Mapping[str, Any], profiles: List[dict[str, Any]] = None): self._profiles = profiles or [] self._client_id = config["client_id"] self._url = URL_MAPPING[config["region"]] - @property - @abstractmethod - def model(self) -> CatalogModel: - """ - Pydantic model to represent json schema - """ - - def get_json_schema(self): - schema = self.model.schema() - expand_refs(schema) - return schema - # Basic full refresh stream class AmazonAdsStream(HttpStream, BasicAmazonAdsStream): @@ -103,7 +99,7 @@ class AmazonAdsStream(HttpStream, BasicAmazonAdsStream): data_field = "" - def __init__(self, config: Mapping[str, Any], *args, profiles: List[Profile] = None, **kwargs): + def __init__(self, config: Mapping[str, Any], *args, profiles: List[dict[str, Any]] = None, **kwargs): # Each AmazonAdsStream instance are dependant on list of profiles. BasicAmazonAdsStream.__init__(self, config, profiles=profiles) HttpStream.__init__(self, *args, **kwargs) @@ -112,10 +108,6 @@ def __init__(self, config: Mapping[str, Any], *args, profiles: List[Profile] = N def url_base(self): return self._url - @property - def raise_on_http_errors(self): - return False - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: return None @@ -165,51 +157,5 @@ def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapp f"{response.request.headers['Amazon-Advertising-API-Scope']} profile: {resp.details}" ) - -class SubProfilesStream(AmazonAdsStream): - """ - Stream for getting resources with pagination support and getting resources based on list of profiles set by source. - """ - - page_size = 100 - - def __init__(self, *args, **kwargs): - self._current_offset = 0 - super().__init__(*args, **kwargs) - - def next_page_token(self, response: requests.Response) -> Optional[int]: - if not response: - return 0 - responses = response.json() - if len(responses) < self.page_size: - # This is last page, reset current offset - self._current_offset = 0 - return 0 - else: - next_offset = self._current_offset + self.page_size - self._current_offset = next_offset - return next_offset - - def request_params( - self, - stream_state: Mapping[str, Any], - stream_slice: Mapping[str, Any] = None, - next_page_token: int = None, - ) -> MutableMapping[str, Any]: - return { - "startIndex": next_page_token, - "count": self.page_size, - } - - def read_records(self, *args, **kwargs) -> Iterable[Mapping[str, Any]]: - """ - Iterate through self._profiles list and send read all records for each profile. - """ - for profile in self._profiles: - self._current_profile_id = profile.profileId - yield from super().read_records(*args, **kwargs) - - def request_headers(self, *args, **kwargs) -> MutableMapping[str, Any]: - headers = super().request_headers(*args, **kwargs) - headers["Amazon-Advertising-API-Scope"] = str(self._current_profile_id) - return headers + def get_error_handler(self) -> ErrorHandler: + return AmazonAdsErrorHandler(logger=LOGGER) diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/portfolios.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/portfolios.py deleted file mode 100644 index 1d253fda57e6..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/portfolios.py +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Iterable, Mapping, MutableMapping - -from source_amazon_ads.schemas import Portfolio -from source_amazon_ads.streams.common import AmazonAdsStream - - -class Portfolios(AmazonAdsStream): - """ - This stream corresponds to Amazon Advertising API - Portfolios - https://advertising.amazon.com/API/docs/en-us/reference/2/portfolios - """ - - primary_key = "portfolioId" - model = Portfolio - - def path(self, **kwargs) -> str: - return "v2/portfolios/extended" - - def read_records(self, *args, **kwargs) -> Iterable[Mapping[str, Any]]: - """ - Iterate through self._profiles list and send read all records for each profile. - """ - for profile in self._profiles: - self._current_profile_id = profile.profileId - yield from super().read_records(*args, **kwargs) - - def request_headers(self, *args, **kwargs) -> MutableMapping[str, Any]: - headers = super().request_headers(*args, **kwargs) - headers["Amazon-Advertising-API-Scope"] = str(self._current_profile_id) - return headers diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/profiles.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/profiles.py index c6491c052acf..a8917baf8c12 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/profiles.py +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/profiles.py @@ -5,8 +5,8 @@ from typing import Any, Iterable, List, Mapping import requests + from airbyte_cdk.models import SyncMode -from source_amazon_ads.schemas import Profile from source_amazon_ads.streams.common import AmazonAdsStream @@ -16,33 +16,32 @@ class Profiles(AmazonAdsStream): https://advertising.amazon.com/API/docs/en-us/reference/2/profiles#/Profiles """ + is_resumable = False primary_key = "profileId" - model = Profile def path(self, **kwargs) -> str: return "v2/profiles?profileTypeFilter=seller,vendor" def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapping]: for record in super().parse_response(response, **kwargs): - profile_id_obj = self.model.parse_obj(record) # Populate self._profiles list with profiles objects to not make # unnecessary API calls. - self._profiles.append(profile_id_obj) + self._profiles.append(record) yield record def read_records(self, *args, **kwargs) -> Iterable[Mapping[str, Any]]: if self._profiles: # In case if we have _profiles populated we can use it instead of making API call. - yield from [profile.dict(exclude_unset=True) for profile in self._profiles] + yield from [profile for profile in self._profiles] else: # Make API call by the means of basic HttpStream class. yield from super().read_records(*args, **kwargs) - def get_all_profiles(self) -> List[Profile]: + def get_all_profiles(self) -> List[dict[str, Any]]: """ Fetch all profiles and return it as list. We need this to set dependecies for other streams since all of the Amazon Ads API calls require profile id to be passed. :return List of profile object """ - return [self.model.parse_obj(profile) for profile in self.read_records(SyncMode.full_refresh)] + return [profile for profile in self.read_records(SyncMode.full_refresh)] diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/__init__.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/__init__.py index 314d3770336b..130750e8ecc1 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/__init__.py +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/__init__.py @@ -1,15 +1,12 @@ # # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # -from .brands_report import SponsoredBrandsReportStream, SponsoredBrandsV3ReportStream -from .brands_video_report import SponsoredBrandsVideoReportStream +from .brands_report import SponsoredBrandsV3ReportStream from .display_report import SponsoredDisplayReportStream from .products_report import SponsoredProductsReportStream __all__ = [ "SponsoredDisplayReportStream", "SponsoredProductsReportStream", - "SponsoredBrandsReportStream", "SponsoredBrandsV3ReportStream", - "SponsoredBrandsVideoReportStream", ] diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/brands_report.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/brands_report.py index fbe14a4bc118..8887c3ccaf6f 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/brands_report.py +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/brands_report.py @@ -5,127 +5,6 @@ from http import HTTPStatus from .products_report import SponsoredProductsReportStream -from .report_streams import ReportStream - -METRICS_MAP = { - "keywords": [ - "campaignName", - "campaignId", - "campaignStatus", - "campaignBudget", - "campaignBudgetType", - "campaignRuleBasedBudget", - "applicableBudgetRuleId", - "applicableBudgetRuleName", - "adGroupName", - "adGroupId", - "keywordText", - "keywordBid", - "keywordStatus", - "searchTermImpressionRank", - "matchType", - "impressions", - "clicks", - "cost", - "attributedDetailPageViewsClicks14d", - "attributedSales14d", - "attributedSales14dSameSKU", - "attributedConversions14d", - "attributedConversions14dSameSKU", - "attributedOrdersNewToBrand14d", - "attributedOrdersNewToBrandPercentage14d", - "attributedOrderRateNewToBrand14d", - "attributedSalesNewToBrand14d", - "attributedSalesNewToBrandPercentage14d", - "attributedUnitsOrderedNewToBrand14d", - "attributedUnitsOrderedNewToBrandPercentage14d", - "unitsSold14d", - "dpv14d", - "attributedBrandedSearches14d", - "keywordId", - "searchTermImpressionShare", - ], - "adGroups": [ - "campaignName", - "campaignId", - "campaignStatus", - "campaignBudget", - "campaignBudgetType", - "adGroupName", - "adGroupId", - "impressions", - "clicks", - "cost", - "attributedDetailPageViewsClicks14d", - "attributedSales14d", - "attributedSales14dSameSKU", - "attributedConversions14d", - "attributedConversions14dSameSKU", - "attributedOrdersNewToBrand14d", - "attributedOrdersNewToBrandPercentage14d", - "attributedOrderRateNewToBrand14d", - "attributedSalesNewToBrand14d", - "attributedSalesNewToBrandPercentage14d", - "attributedUnitsOrderedNewToBrand14d", - "attributedUnitsOrderedNewToBrandPercentage14d", - "unitsSold14d", - "dpv14d", - "attributedBrandedSearches14d", - ], - "campaigns": [ - "campaignName", - "campaignId", - "campaignStatus", - "campaignBudget", - "campaignBudgetType", - "campaignRuleBasedBudget", - "applicableBudgetRuleId", - "applicableBudgetRuleName", - "impressions", - "clicks", - "cost", - "attributedDetailPageViewsClicks14d", - "attributedSales14d", - "attributedSales14dSameSKU", - "attributedConversions14d", - "attributedConversions14dSameSKU", - "attributedOrdersNewToBrand14d", - "attributedOrdersNewToBrandPercentage14d", - "attributedOrderRateNewToBrand14d", - "attributedSalesNewToBrand14d", - "attributedSalesNewToBrandPercentage14d", - "attributedUnitsOrderedNewToBrand14d", - "attributedUnitsOrderedNewToBrandPercentage14d", - "unitsSold14d", - "dpv14d", - "attributedBrandedSearches14d", - ], -} - -METRICS_TYPE_TO_ID_MAP = { - "keywords": "keywordBid", - "adGroups": "adGroupId", - "campaigns": "campaignId", -} - - -class SponsoredBrandsReportStream(ReportStream): - """ - https://advertising.amazon.com/API/docs/en-us/reference/sponsored-brands/2/reports - """ - - def report_init_endpoint(self, record_type: str) -> str: - return f"/v2/hsa/{record_type}/report" - - metrics_map = METRICS_MAP - metrics_type_to_id_map = METRICS_TYPE_TO_ID_MAP - - def _get_init_report_body(self, report_date: str, record_type: str, profile): - metrics_list = self.metrics_map[record_type] - body = { - "reportDate": report_date, - } - yield {**body, "metrics": ",".join(metrics_list)} METRICS_MAP_V3 = { diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/brands_video_report.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/brands_video_report.py deleted file mode 100644 index b5da376396cd..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/brands_video_report.py +++ /dev/null @@ -1,146 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from .report_streams import ReportStream - -METRICS_MAP = { - "keywords": [ - "campaignName", - "campaignId", - "campaignStatus", - "campaignBudget", - "campaignBudgetType", - "adGroupName", - "adGroupId", - "keywordText", - "keywordBid", - "keywordStatus", - "matchType", - "impressions", - "clicks", - "cost", - "attributedSales14d", - "attributedSales14dSameSKU", - "attributedConversions14d", - "attributedConversions14dSameSKU", - "attributedBrandedSearches14d", - "attributedDetailPageViewsClicks14d", - "attributedOrderRateNewToBrand14d", - "attributedOrdersNewToBrand14d", - "attributedOrdersNewToBrandPercentage14d", - "attributedSalesNewToBrand14d", - "attributedSalesNewToBrandPercentage14d", - "attributedUnitsOrderedNewToBrand14d", - "attributedUnitsOrderedNewToBrandPercentage14d", - "dpv14d", - "keywordId", - "vctr", - "video5SecondViewRate", - "video5SecondViews", - "videoCompleteViews", - "videoFirstQuartileViews", - "videoMidpointViews", - "videoThirdQuartileViews", - "videoUnmutes", - "viewableImpressions", - "vtr", - ], - "adGroups": [ - "campaignName", - "campaignId", - "campaignStatus", - "campaignBudget", - "campaignBudgetType", - "adGroupName", - "adGroupId", - "impressions", - "clicks", - "cost", - "attributedSales14d", - "attributedSales14dSameSKU", - "attributedConversions14d", - "attributedConversions14dSameSKU", - "vctr", - "video5SecondViewRate", - "video5SecondViews", - "videoCompleteViews", - "videoFirstQuartileViews", - "videoMidpointViews", - "videoThirdQuartileViews", - "videoUnmutes", - "viewableImpressions", - "vtr", - "dpv14d", - "attributedDetailPageViewsClicks14d", - "attributedOrderRateNewToBrand14d", - "attributedOrdersNewToBrand14d", - "attributedOrdersNewToBrandPercentage14d", - "attributedSalesNewToBrand14d", - "attributedSalesNewToBrandPercentage14d", - "attributedUnitsOrderedNewToBrand14d", - "attributedUnitsOrderedNewToBrandPercentage14d", - "attributedBrandedSearches14d", - ], - "campaigns": [ - "campaignName", - "campaignId", - "campaignStatus", - "campaignBudget", - "campaignBudgetType", - "impressions", - "clicks", - "cost", - "attributedSales14d", - "attributedSales14dSameSKU", - "attributedConversions14d", - "attributedConversions14dSameSKU", - "attributedSalesNewToBrand14d", - "attributedSalesNewToBrandPercentage14d", - "attributedUnitsOrderedNewToBrand14d", - "attributedUnitsOrderedNewToBrandPercentage14d", - "attributedBrandedSearches14d", - "attributedDetailPageViewsClicks14d", - "attributedOrderRateNewToBrand14d", - "attributedOrdersNewToBrand14d", - "attributedOrdersNewToBrandPercentage14d", - "dpv14d", - "vctr", - "video5SecondViewRate", - "video5SecondViews", - "videoCompleteViews", - "videoFirstQuartileViews", - "videoMidpointViews", - "videoThirdQuartileViews", - "videoUnmutes", - "viewableImpressions", - "vtr", - ], -} - - -METRICS_TYPE_TO_ID_MAP = { - "keywords": "keywordBid", - "adGroups": "adGroupId", - "campaigns": "campaignId", -} - - -class SponsoredBrandsVideoReportStream(ReportStream): - """ - https://advertising.amazon.com/API/docs/en-us/reference/sponsored-brands/2/reports - """ - - def report_init_endpoint(self, record_type: str) -> str: - return f"/v2/hsa/{record_type}/report" - - metrics_map = METRICS_MAP - metrics_type_to_id_map = METRICS_TYPE_TO_ID_MAP - - def _get_init_report_body(self, report_date: str, record_type: str, profile): - metrics_list = self.metrics_map[record_type] - body = { - "reportDate": report_date, - "creativeType": "video", - } - yield {**body, "metrics": ",".join(metrics_list)} diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/display_report.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/display_report.py index de158949addc..428958c58a3d 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/display_report.py +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/display_report.py @@ -2,241 +2,382 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # +from http import HTTPStatus +from typing import Any, List, Mapping -from .report_streams import RecordType, ReportStream +import requests -METRICS_MAP = { +from airbyte_cdk.sources.streams.http.requests_native_auth import Oauth2Authenticator +from source_amazon_ads.streams.report_streams.report_stream_models import ReportInfo +from source_amazon_ads.streams.report_streams.report_streams import ReportStream + + +METRICS_MAP_V3 = { "campaigns": [ - "campaignName", + "addToCart", + "addToCartClicks", + "addToCartRate", + "addToCartViews", + "addToList", + "addToListFromClicks", + "addToListFromViews", + "qualifiedBorrows", + "qualifiedBorrowsFromClicks", + "qualifiedBorrowsFromViews", + "royaltyQualifiedBorrows", + "royaltyQualifiedBorrowsFromClicks", + "royaltyQualifiedBorrowsFromViews", + "brandedSearches", + "brandedSearchesClicks", + "brandedSearchesViews", + "brandedSearchRate", + "campaignBudgetCurrencyCode", "campaignId", - "impressions", + "campaignName", "clicks", "cost", - "currency", - "attributedConversions1d", - "attributedConversions7d", - "attributedConversions14d", - "attributedConversions30d", - "attributedConversions1dSameSKU", - "attributedConversions7dSameSKU", - "attributedConversions14dSameSKU", - "attributedConversions30dSameSKU", - "attributedUnitsOrdered1d", - "attributedUnitsOrdered7d", - "attributedUnitsOrdered14d", - "attributedUnitsOrdered30d", - "attributedSales1d", - "attributedSales7d", - "attributedSales14d", - "attributedSales30d", - "attributedSales1dSameSKU", - "attributedSales7dSameSKU", - "attributedSales14dSameSKU", - "attributedSales30dSameSKU", - "attributedOrdersNewToBrand14d", - "attributedSalesNewToBrand14d", - "attributedUnitsOrderedNewToBrand14d", - "costType", - "campaignBudget", + "detailPageViews", + "detailPageViewsClicks", + "eCPAddToCart", + "eCPBrandSearch", + "endDate", + "impressions", + "impressionsViews", + "leadFormOpens", + "leads", + "linkOuts", + "newToBrandPurchases", + "newToBrandPurchasesClicks", + "newToBrandSalesClicks", + "newToBrandUnitsSold", + "newToBrandUnitsSoldClicks", + "purchases", + "purchasesClicks", + "purchasesPromotedClicks", + "sales", + "salesClicks", + "salesPromotedClicks", + "startDate", + "unitsSold", + "unitsSoldClicks", + "videoCompleteViews", + "videoFirstQuartileViews", + "videoMidpointViews", + "videoThirdQuartileViews", + "videoUnmutes", + "viewabilityRate", + "viewClickThroughRate", + ] + + [ # Group-by metrics + "campaignBudgetAmount", "campaignStatus", - "attributedBrandedSearches14d", - "attributedDetailPageView14d", - "viewAttributedBrandedSearches14d", - "viewAttributedConversions14d", - "viewAttributedDetailPageView14d", - "viewAttributedOrdersNewToBrand14d", - "viewAttributedSales14d", - "viewAttributedSalesNewToBrand14d", - "viewAttributedUnitsOrdered14d", - "viewAttributedUnitsOrderedNewToBrand14d", - "viewImpressions", - ], + "costType", + "cumulativeReach", + "impressionsFrequencyAverage", + "newToBrandDetailPageViewClicks", + "newToBrandDetailPageViewRate", + "newToBrandDetailPageViews", + "newToBrandDetailPageViewViews", + "newToBrandECPDetailPageView", + "newToBrandSales", + ], # 'date', "adGroups": [ - "campaignName", - "campaignId", - "adGroupName", + "addToCart", + "addToCartClicks", + "addToCartRate", + "addToCartViews", "adGroupId", - "impressions", + "adGroupName", + "addToList", + "addToListFromClicks", + "addToListFromViews", + "qualifiedBorrows", + "qualifiedBorrowsFromClicks", + "qualifiedBorrowsFromViews", + "royaltyQualifiedBorrows", + "royaltyQualifiedBorrowsFromClicks", + "royaltyQualifiedBorrowsFromViews", + "bidOptimization", + "brandedSearches", + "brandedSearchesClicks", + "brandedSearchesViews", + "brandedSearchRate", + "campaignBudgetCurrencyCode", + "campaignId", + "campaignName", "clicks", "cost", - "currency", - "attributedConversions1d", - "attributedConversions7d", - "attributedConversions14d", - "attributedConversions30d", - "attributedConversions1dSameSKU", - "attributedConversions7dSameSKU", - "attributedConversions14dSameSKU", - "attributedConversions30dSameSKU", - "attributedUnitsOrdered1d", - "attributedUnitsOrdered7d", - "attributedUnitsOrdered14d", - "attributedUnitsOrdered30d", - "attributedSales1d", - "attributedSales7d", - "attributedSales14d", - "attributedSales30d", - "attributedSales1dSameSKU", - "attributedSales7dSameSKU", - "attributedSales14dSameSKU", - "attributedSales30dSameSKU", - "attributedOrdersNewToBrand14d", - "attributedUnitsOrderedNewToBrand14d", - "attributedBrandedSearches14d", - "attributedDetailPageView14d", - "bidOptimization", - "viewAttributedBrandedSearches14d", - "viewAttributedConversions14d", - "viewAttributedDetailPageView14d", - "viewAttributedOrdersNewToBrand14d", - "viewAttributedSales14d", - "viewAttributedSalesNewToBrand14d", - "viewAttributedUnitsOrdered14d", - "viewAttributedUnitsOrderedNewToBrand14d", - "viewImpressions", - ], + "detailPageViews", + "detailPageViewsClicks", + "eCPAddToCart", + "eCPBrandSearch", + "endDate", + "impressions", + "impressionsViews", + "leadFormOpens", + "leads", + "linkOuts", + "newToBrandPurchases", + "newToBrandPurchasesClicks", + "newToBrandSales", + "newToBrandSalesClicks", + "newToBrandUnitsSold", + "newToBrandUnitsSoldClicks", + "purchases", + "purchasesClicks", + "purchasesPromotedClicks", + "sales", + "salesClicks", + "salesPromotedClicks", + "startDate", + "unitsSold", + "unitsSoldClicks", + "videoCompleteViews", + "videoFirstQuartileViews", + "videoMidpointViews", + "videoThirdQuartileViews", + "videoUnmutes", + "viewabilityRate", + "viewClickThroughRate", + ] + + [ # Group-by metrics + "cumulativeReach", + "impressionsFrequencyAverage", + "newToBrandDetailPageViewClicks", + "newToBrandDetailPageViewRate", + "newToBrandDetailPageViews", + "newToBrandDetailPageViewViews", + "newToBrandECPDetailPageView", + ], # 'date', "productAds": [ - "campaignName", - "campaignId", - "adGroupName", + "addToCart", + "addToCartRate", + "addToCartViews", + "addToCartClicks", "adGroupId", - "asin", - "sku", # Available for seller accounts only. + "adGroupName", "adId", - "impressions", + "addToList", + "addToListFromClicks", + "qualifiedBorrows", + "royaltyQualifiedBorrows", + "addToListFromViews", + "qualifiedBorrowsFromClicks", + "qualifiedBorrowsFromViews", + "royaltyQualifiedBorrowsFromClicks", + "royaltyQualifiedBorrowsFromViews", + "bidOptimization", + "brandedSearches", + "brandedSearchesClicks", + "brandedSearchesViews", + "brandedSearchRate", + "campaignBudgetCurrencyCode", + "campaignId", + "campaignName", "clicks", "cost", - "currency", - "attributedConversions1d", - "attributedConversions7d", - "attributedConversions14d", - "attributedConversions30d", - "attributedConversions1dSameSKU", - "attributedConversions7dSameSKU", - "attributedConversions14dSameSKU", - "attributedConversions30dSameSKU", - "attributedUnitsOrdered1d", - "attributedUnitsOrdered7d", - "attributedUnitsOrdered14d", - "attributedUnitsOrdered30d", - "attributedSales1d", - "attributedSales7d", - "attributedSales14d", - "attributedSales30d", - "attributedSales1dSameSKU", - "attributedSales7dSameSKU", - "attributedSales14dSameSKU", - "attributedSales30dSameSKU", - "attributedOrdersNewToBrand14d", - "attributedSalesNewToBrand14d", - "attributedUnitsOrderedNewToBrand14d", - "attributedBrandedSearches14d", - "attributedDetailPageView14d", - "viewAttributedBrandedSearches14d", - "viewAttributedConversions14d", - "viewAttributedDetailPageView14d", - "viewAttributedOrdersNewToBrand14d", - "viewAttributedSales14d", - "viewAttributedSalesNewToBrand14d", - "viewAttributedUnitsOrdered14d", - "viewAttributedUnitsOrderedNewToBrand14d", - "viewImpressions", - ], + "cumulativeReach", + "detailPageViews", + "detailPageViewsClicks", + "eCPAddToCart", + "eCPBrandSearch", + "endDate", + "impressions", + "impressionsFrequencyAverage", + "impressionsViews", + "leadFormOpens", + "leads", + "linkOuts", + "newToBrandDetailPageViewClicks", + "newToBrandDetailPageViewRate", + "newToBrandDetailPageViews", + "newToBrandDetailPageViewViews", + "newToBrandECPDetailPageView", + "newToBrandPurchases", + "newToBrandPurchasesClicks", + "newToBrandSales", + "newToBrandSalesClicks", + "newToBrandUnitsSold", + "newToBrandUnitsSoldClicks", + "promotedAsin", + "promotedSku", + "purchases", + "purchasesClicks", + "purchasesPromotedClicks", + "sales", + "salesClicks", + "salesPromotedClicks", + "startDate", + "unitsSold", + "unitsSoldClicks", + "videoCompleteViews", + "videoFirstQuartileViews", + "videoMidpointViews", + "videoThirdQuartileViews", + "videoUnmutes", + "viewabilityRate", + "viewClickThroughRate", + ], # 'date', "targets": [ - "campaignName", - "campaignId", - "adGroupName", + "addToCart", + "addToCartClicks", + "addToCartRate", + "addToCartViews", "adGroupId", - "targetId", - "targetingExpression", - "targetingText", - "targetingType", - "impressions", + "adGroupName", + "addToList", + "addToListFromClicks", + "addToListFromViews", + "qualifiedBorrows", + "qualifiedBorrowsFromClicks", + "qualifiedBorrowsFromViews", + "royaltyQualifiedBorrows", + "royaltyQualifiedBorrowsFromClicks", + "royaltyQualifiedBorrowsFromViews", + "brandedSearches", + "brandedSearchesClicks", + "brandedSearchesViews", + "brandedSearchRate", + "campaignBudgetCurrencyCode", + "campaignId", + "campaignName", "clicks", "cost", - "currency", - "attributedConversions1d", - "attributedConversions7d", - "attributedConversions14d", - "attributedConversions30d", - "attributedConversions1dSameSKU", - "attributedConversions7dSameSKU", - "attributedConversions14dSameSKU", - "attributedConversions30dSameSKU", - "attributedUnitsOrdered1d", - "attributedUnitsOrdered7d", - "attributedUnitsOrdered14d", - "attributedUnitsOrdered30d", - "attributedSales1d", - "attributedSales7d", - "attributedSales14d", - "attributedSales30d", - "attributedSales1dSameSKU", - "attributedSales7dSameSKU", - "attributedSales14dSameSKU", - "attributedSales30dSameSKU", - "attributedOrdersNewToBrand14d", - "attributedSalesNewToBrand14d", - "attributedUnitsOrderedNewToBrand14d", - "attributedBrandedSearches14d", - "attributedDetailPageView14d", - "viewAttributedBrandedSearches14d", - "viewAttributedConversions14d", - "viewAttributedDetailPageView14d", - "viewAttributedOrdersNewToBrand14d", - "viewAttributedSales14d", - "viewAttributedSalesNewToBrand14d", - "viewAttributedUnitsOrdered14d", - "viewAttributedUnitsOrderedNewToBrand14d", - "viewImpressions", - ], + "detailPageViews", + "detailPageViewsClicks", + "eCPAddToCart", + "eCPBrandSearch", + "endDate", + "impressions", + "impressionsViews", + "leadFormOpens", + "leads", + "linkOuts", + "newToBrandPurchases", + "newToBrandPurchasesClicks", + "newToBrandSales", + "newToBrandSalesClicks", + "newToBrandUnitsSold", + "newToBrandUnitsSoldClicks", + "purchases", + "purchasesClicks", + "purchasesPromotedClicks", + "sales", + "salesClicks", + "salesPromotedClicks", + "startDate", + "targetingExpression", + "targetingId", + "targetingText", + "unitsSold", + "unitsSoldClicks", + "videoCompleteViews", + "videoFirstQuartileViews", + "videoMidpointViews", + "videoThirdQuartileViews", + "videoUnmutes", + "viewabilityRate", + "viewClickThroughRate", + ], # 'date', "asins": [ - "campaignName", - "campaignId", - "adGroupName", "adGroupId", - "asin", - "otherAsin", - "sku", # Available for seller accounts only. - "currency", - "attributedUnitsOrdered1dOtherSKU", - "attributedUnitsOrdered7dOtherSKU", - "attributedUnitsOrdered14dOtherSKU", - "attributedUnitsOrdered30dOtherSKU", - "attributedSales1dOtherSKU", - "attributedSales7dOtherSKU", - "attributedSales14dOtherSKU", - "attributedSales30dOtherSKU", + "adGroupName", + "asinBrandHalo", + "addToList", + "addToListFromClicks", + "qualifiedBorrowsFromClicks", + "royaltyQualifiedBorrowsFromClicks", + "addToListFromViews", + "qualifiedBorrows", + "qualifiedBorrowsFromViews", + "royaltyQualifiedBorrows", + "royaltyQualifiedBorrowsFromViews", + "campaignBudgetCurrencyCode", + "campaignId", + "campaignName", + "conversionsBrandHalo", + "conversionsBrandHaloClicks", + "endDate", + "promotedAsin", + "promotedSku", + "salesBrandHalo", + "salesBrandHaloClicks", + "startDate", + "unitsSoldBrandHalo", + "unitsSoldBrandHaloClicks", ], } METRICS_TYPE_TO_ID_MAP = {"campaigns": "campaignId", "adGroups": "adGroupId", "productAds": "adId", "targets": "targetId", "asins": "asin"} -TACTICS = ["T00020", "T00030"] - class SponsoredDisplayReportStream(ReportStream): """ https://advertising.amazon.com/API/docs/en-us/sponsored-display/3-0/openapi#/Reports """ + API_VERSION = "reporting" # v3 + REPORT_DATE_FORMAT = "YYYY-MM-DD" + ad_product = "SPONSORED_DISPLAY" + report_is_created = HTTPStatus.OK + metrics_map = METRICS_MAP_V3 + metrics_type_to_id_map = METRICS_TYPE_TO_ID_MAP + + def __init__(self, config: Mapping[str, Any], profiles: List[dict[str, Any]], authenticator: Oauth2Authenticator): + super().__init__(config, profiles, authenticator) + # using session without auth as API returns 400 bad request if Authorization header presents in request + # X-Amz-Algorithm and X-Amz-Signature query params already present in the url, that is enough to make proper request + self._report_download_session = requests.Session() + def report_init_endpoint(self, record_type: str) -> str: - return f"/sd/{record_type}/report" + return f"/{self.API_VERSION}/reports" - metrics_map = METRICS_MAP - metrics_type_to_id_map = METRICS_TYPE_TO_ID_MAP + def _download_report(self, report_info: ReportInfo, url: str) -> List[dict]: + """ + Download and parse report result + """ + return super()._download_report(None, url) def _get_init_report_body(self, report_date: str, record_type: str, profile): - for tactic in TACTICS: - metrics_list = self.metrics_map[record_type] - if record_type == RecordType.ASINS and profile.accountInfo.type == "vendor": - return None - elif record_type == RecordType.PRODUCTADS and profile.accountInfo.type != "seller": - # Remove SKU from metrics since it is only available for seller accounts in Product Ad report - metrics_list = [m for m in metrics_list if m != "sku"] - yield { - "reportDate": report_date, - "tactic": tactic, - "metrics": ",".join(metrics_list), - } + metrics_list = self.metrics_map[record_type] + + reportTypeId = "sdCampaigns" # SponsoredDisplayCampaigns + group_by = ["campaign"] + filters = [] + + if record_type == "adGroups": + reportTypeId = "sdAdGroup" + group_by = ["adGroup"] + + elif record_type == "productAds": + reportTypeId = "sdAdvertisedProduct" + group_by = ["advertiser"] + + elif record_type == "asins": + reportTypeId = "sdPurchasedProduct" + group_by = ["asin"] + + elif record_type == "keywords" or record_type == "targets": + group_by = ["targeting"] + reportTypeId = "sdTargeting" + + if record_type == "keywords": + filters = [{"field": "keywordType", "values": ["BROAD", "PHRASE", "EXACT"]}] + + body = { + "name": f"{record_type} report {report_date}", + "startDate": report_date, + "endDate": report_date, + "configuration": { + "adProduct": self.ad_product, + "groupBy": group_by, + "columns": metrics_list, + "reportTypeId": reportTypeId, + "filters": filters, + "timeUnit": "SUMMARY", + "format": "GZIP_JSON", + }, + } + + yield body diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/products_report.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/products_report.py index c39d18b7490c..c8a532c0d0fa 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/products_report.py +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/products_report.py @@ -6,12 +6,12 @@ from http import HTTPStatus from typing import Any, List, Mapping -import backoff import requests + from airbyte_cdk.sources.streams.http.requests_native_auth import Oauth2Authenticator -from source_amazon_ads.schemas import Profile -from .report_streams import ReportInfo, ReportStream, TooManyRequests +from .report_streams import ReportInfo, ReportStream + METRICS_MAP = { "campaigns": [ @@ -271,7 +271,7 @@ class SponsoredProductsReportStream(ReportStream): metrics_map = METRICS_MAP metrics_type_to_id_map = METRICS_TYPE_TO_ID_MAP - def __init__(self, config: Mapping[str, Any], profiles: List[Profile], authenticator: Oauth2Authenticator): + def __init__(self, config: Mapping[str, Any], profiles: List[dict[str, Any]], authenticator: Oauth2Authenticator): super().__init__(config, profiles, authenticator) # using session without auth as API returns 400 bad request if Authorization header presents in request # X-Amz-Algorithm and X-Amz-Signature query params already present in the url, that is enough to make proper request diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/report_stream_models.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/report_stream_models.py new file mode 100644 index 000000000000..6b3e3a4b8113 --- /dev/null +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/report_stream_models.py @@ -0,0 +1,42 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + +from dataclasses import dataclass +from enum import Enum +from typing import List, Optional + +from pydantic.v1 import BaseModel + + +class RecordType(str, Enum): + CAMPAIGNS = "campaigns" + ADGROUPS = "adGroups" + PRODUCTADS = "productAds" + TARGETS = "targets" + ASINS = "asins" + + +class Status(str, Enum): + IN_PROGRESS = "IN_PROGRESS" + SUCCESS = "SUCCESS" + COMPLETED = "COMPLETED" + FAILURE = "FAILURE" + + +class ReportInitResponse(BaseModel): + reportId: str + status: str + + +class ReportStatus(BaseModel): + status: str + location: Optional[str] = None + url: Optional[str] + + +@dataclass +class ReportInfo: + report_id: str + profile_id: int + record_type: Optional[str] + status: Status + metric_objects: List[dict] diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/report_streams.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/report_streams.py index f8e65950f58f..1f87d37ffb8a 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/report_streams.py +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/report_streams.py @@ -7,8 +7,6 @@ import uuid from abc import ABC, abstractmethod from copy import deepcopy -from dataclasses import dataclass -from enum import Enum from gzip import decompress from http import HTTPStatus from typing import Any, Dict, Iterable, List, Mapping, Optional, Tuple @@ -17,49 +15,16 @@ import backoff import pendulum import requests -from airbyte_cdk.models import SyncMode +from pendulum import Date + +from airbyte_cdk import AirbyteTracedException +from airbyte_cdk.models import FailureType, SyncMode from airbyte_cdk.sources.streams.availability_strategy import AvailabilityStrategy from airbyte_cdk.sources.streams.http.requests_native_auth import Oauth2Authenticator -from pendulum import Date -from pydantic import BaseModel -from source_amazon_ads.schemas import CatalogModel, MetricsReport, Profile from source_amazon_ads.streams.common import BasicAmazonAdsStream from source_amazon_ads.utils import get_typed_env, iterate_one_by_one - -class RecordType(str, Enum): - CAMPAIGNS = "campaigns" - ADGROUPS = "adGroups" - PRODUCTADS = "productAds" - TARGETS = "targets" - ASINS = "asins" - - -class Status(str, Enum): - IN_PROGRESS = "IN_PROGRESS" - SUCCESS = "SUCCESS" - COMPLETED = "COMPLETED" - FAILURE = "FAILURE" - - -class ReportInitResponse(BaseModel): - reportId: str - status: str - - -class ReportStatus(BaseModel): - status: str - location: Optional[str] - url: Optional[str] - - -@dataclass -class ReportInfo: - report_id: str - profile_id: int - record_type: str - status: Status - metric_objects: List[dict] +from .report_stream_models import ReportInfo, ReportInitResponse, ReportStatus, Status class RetryableException(Exception): @@ -88,6 +53,9 @@ class TooManyRequests(Exception): """ +CONFIG_DATE_FORMAT = "YYYY-MM-DD" + + class ReportStream(BasicAmazonAdsStream, ABC): """ Common base class for report streams @@ -116,14 +84,15 @@ class ReportStream(BasicAmazonAdsStream, ABC): (406, re.compile(r"^Report date is too far in the past\.")), ] - def __init__(self, config: Mapping[str, Any], profiles: List[Profile], authenticator: Oauth2Authenticator): + def __init__(self, config: Mapping[str, Any], profiles: List[dict[str, Any]], authenticator: Oauth2Authenticator): super().__init__(config, profiles) self._state = {} self._session = requests.Session() self._session.auth = authenticator self._report_download_session = self._session - self._model = self._generate_model() - self._start_date: Optional[Date] = config.get("start_date") + self._start_date: Optional[str] = ( + pendulum.from_format(config["start_date"], CONFIG_DATE_FORMAT).date() if config.get("start_date") else None + ) self._look_back_window: int = config["look_back_window"] # Timeout duration in minutes for Reports. Default is 180 minutes. self.report_wait_timeout: int = get_typed_env("REPORT_WAIT_TIMEOUT", 180) @@ -131,10 +100,6 @@ def __init__(self, config: Mapping[str, Any], profiles: List[Profile], authentic self.report_generation_maximum_retries: int = get_typed_env("REPORT_GENERATION_MAX_RETRIES", 5) self._report_record_types = config.get("report_record_types") - @property - def model(self) -> CatalogModel: - return self._model - @property def availability_strategy(self) -> Optional["AvailabilityStrategy"]: return None @@ -164,18 +129,25 @@ def read_records( return profile = stream_slice["profile"] report_date = stream_slice[self.cursor_field] - report_info_list = self._init_and_try_read_records(profile, report_date) + try: + report_info_list = self._init_and_try_read_records(profile, report_date) + except TooManyRequests as e: + raise AirbyteTracedException( + failure_type=FailureType.transient_error, + message=f"Too many requests on resource {e}. Please retry later", + internal_message=f"Errors received from the API were: {e}", + ) self._update_state(profile, report_date) for report_info in report_info_list: for metric_object in report_info.metric_objects: - yield self._model( - profileId=report_info.profile_id, - recordType=report_info.record_type, - reportDate=report_date, - recordId=self.get_record_id(metric_object, report_info.record_type), - metric=metric_object, - ).dict() + yield { + "profileId": report_info.profile_id, + "recordType": report_info.record_type, + "reportDate": report_date, + "recordId": self.get_record_id(metric_object, report_info.record_type), + "metric": metric_object, + } def get_record_id(self, metric_object: dict, record_type: str) -> str: return metric_object.get(self.metrics_type_to_id_map[record_type]) or str(uuid.uuid4()) @@ -197,7 +169,7 @@ def wrapped(self, *args, **kwargs): return wrapped @backoff_max_tries - def _init_and_try_read_records(self, profile: Profile, report_date): + def _init_and_try_read_records(self, profile: dict[str, Any], report_date: str): report_info_list = self._init_reports(profile, report_date) self.logger.info(f"Waiting for {len(report_info_list)} report(s) to be generated") self._try_read_records(report_info_list) @@ -228,17 +200,6 @@ def _try_read_records(self, report_info_list): def _incomplete_report_info(self, report_info_list): return [r for r in report_info_list if r.status != Status.SUCCESS and r.status != Status.COMPLETED] - def _generate_model(self): - """ - Generate pydantic model based on combined list of all the metrics - attributes for particular stream. This model later will be used for - discover schema generation. - """ - metrics = set() - for metric_list in self.metrics_map.values(): - metrics.update(set(metric_list)) - return MetricsReport.generate_metric_model(metrics) - def _get_auth_headers(self, profile_id: int): return ( { @@ -303,7 +264,7 @@ def _send_http_request(self, url: str, profile_id: int, json: dict = None, is_do session = self._report_download_session if is_download_report else self._session response = session.get(url, headers=headers) if response.status_code == HTTPStatus.TOO_MANY_REQUESTS: - raise TooManyRequests() + raise TooManyRequests("429: Too many requests during report creation. Please try again later...") return response def get_date_range(self, start_date: Date, timezone: str) -> Iterable[str]: @@ -313,26 +274,25 @@ def get_date_range(self, start_date: Date, timezone: str) -> Iterable[str]: yield start_date.format(self.REPORT_DATE_FORMAT) start_date = start_date.add(days=1) - def get_start_date(self, profile: Profile, stream_state: Mapping[str, Any]) -> Date: - today = pendulum.today(tz=profile.timezone).date() - start_date = stream_state.get(str(profile.profileId), {}).get(self.cursor_field) + def get_start_date(self, profile: dict[str, Any], stream_state: Mapping[str, Any]) -> Date: + today = pendulum.today(tz=profile["timezone"]).date() + start_date = stream_state.get(str(profile["profileId"]), {}).get(self.cursor_field) if start_date: - start_date = pendulum.from_format(start_date, self.REPORT_DATE_FORMAT).date() + start_date = pendulum.parse(start_date).date() # Taking date from state if it's not older than 60 days return max(start_date, today.subtract(days=self.REPORTING_PERIOD)) if self._start_date: return max(self._start_date, today.subtract(days=self.REPORTING_PERIOD)) return today - def stream_profile_slices(self, profile: Profile, stream_state: Mapping[str, Any]) -> Iterable[Mapping[str, Any]]: + def stream_profile_slices(self, profile: dict[str, Any], stream_state: Mapping[str, Any]) -> Iterable[Mapping[str, Any]]: start_date = self.get_start_date(profile, stream_state) - for report_date in self.get_date_range(start_date, profile.timezone): + for report_date in self.get_date_range(start_date, profile["timezone"]): yield {"profile": profile, self.cursor_field: report_date} def stream_slices( self, sync_mode: SyncMode, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - stream_state = stream_state or {} no_data = True @@ -352,19 +312,16 @@ def state(self): def state(self, value): self._state = deepcopy(value) - def get_updated_state(self, current_stream_state: Dict[str, Any], latest_data: Mapping[str, Any]) -> Mapping[str, Any]: - return self._state - - def _update_state(self, profile: Profile, report_date: str): + def _update_state(self, profile: dict[str, Any], report_date: str): report_date = pendulum.from_format(report_date, self.REPORT_DATE_FORMAT).date() - look_back_date = pendulum.today(tz=profile.timezone).date().subtract(days=self._look_back_window - 1) + look_back_date = pendulum.today(tz=profile["timezone"]).date().subtract(days=self._look_back_window - 1) start_date = self.get_start_date(profile, self._state) updated_state = max(min(report_date, look_back_date), start_date).format(self.REPORT_DATE_FORMAT) - stream_state_value = self._state.get(str(profile.profileId), {}).get(self.cursor_field) + stream_state_value = self._state.get(str(profile["profileId"]), {}).get(self.cursor_field) if stream_state_value: updated_state = max(updated_state, stream_state_value) - self._state.setdefault(str(profile.profileId), {})[self.cursor_field] = updated_state + self._state.setdefault(str(profile["profileId"]), {})[self.cursor_field] = updated_state @abstractmethod def _get_init_report_body(self, report_date: str, record_type: str, profile) -> Dict[str, Any]: @@ -377,7 +334,7 @@ def _get_init_report_body(self, report_date: str, record_type: str, profile) -> ReportInitFailure, max_tries=5, ) - def _init_reports(self, profile: Profile, report_date: str) -> List[ReportInfo]: + def _init_reports(self, profile: dict[str, Any], report_date: str) -> List[ReportInfo]: """ Send report generation requests for all profiles and for all record types for specific day. :report_date - date for generating metric report. @@ -398,15 +355,15 @@ def _init_reports(self, profile: Profile, report_date: str) -> List[ReportInfo]: # different metric list for each record. request_record_type = record_type.split("_")[0] self.logger.info( - f"Initiating report generation for {profile.profileId} profile with {record_type} type for {report_date} date" + f"Initiating report generation for {profile['profileId']} profile with {record_type} type for {report_date} date" ) response = self._send_http_request( urljoin(self._url, self.report_init_endpoint(request_record_type)), - profile.profileId, + profile["profileId"], report_init_body, ) if response.status_code != self.report_is_created: - error_msg = f"Unexpected HTTP status code {response.status_code} when registering {record_type}, {type(self).__name__} for {profile.profileId} profile: {response.text}" + error_msg = f"Unexpected HTTP status code {response.status_code} when registering {record_type}, {type(self).__name__} for {profile['profileId']} profile: {response.text}" if self._skip_known_errors(response): self.logger.warning(error_msg) break @@ -417,7 +374,7 @@ def _init_reports(self, profile: Profile, report_date: str) -> List[ReportInfo]: ReportInfo( report_id=response.reportId, record_type=record_type, - profile_id=profile.profileId, + profile_id=profile["profileId"], status=Status.IN_PROGRESS, metric_objects=[], ) diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/sponsored_brands.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/sponsored_brands.py deleted file mode 100644 index 030ae17f94e0..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/sponsored_brands.py +++ /dev/null @@ -1,103 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# -from typing import Any, Mapping, MutableMapping - -from requests import Response -from source_amazon_ads.schemas import BrandsAdGroup, BrandsCampaign -from source_amazon_ads.streams.common import SubProfilesStream - - -class SponsoredBrandsV4(SubProfilesStream): - """ - This Stream supports the Sponsored Brands V4 API, which requires POST methods - https://advertising.amazon.com/API/docs/en-us/sponsored-brands/3-0/openapi/prod - """ - - @property - def http_method(self, **kwargs) -> str: - return "POST" - - def request_headers(self, profile_id: str = None, *args, **kwargs) -> MutableMapping[str, Any]: - headers = super().request_headers(*args, **kwargs) - headers["Accept"] = self.content_type - headers["Content-Type"] = self.content_type - return headers - - def request_body_json( - self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None - ) -> Mapping[str, Any]: - request_body = {} - request_body["maxResults"] = self.page_size - if next_page_token: - request_body["nextToken"] = next_page_token - return request_body - - def next_page_token(self, response: Response) -> str: - if not response: - return None - return response.json().get("nextToken", None) - - def request_params( - self, - stream_state: Mapping[str, Any], - stream_slice: Mapping[str, Any] = None, - next_page_token: int = None, - ) -> MutableMapping[str, Any]: - return {} - - -class SponsoredBrandsCampaigns(SponsoredBrandsV4): - """ - This stream corresponds to Amazon Ads API - Sponsored Brands Campaigns v4 - https://advertising.amazon.com/API/docs/en-us/sponsored-brands/3-0/openapi/prod#tag/Campaigns/operation/ListSponsoredBrandsCampaigns - """ - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.state_filter = kwargs.get("config", {}).get("state_filter") - - primary_key = "campaignId" - data_field = "campaigns" - state_filter = None - content_type = "application/vnd.sbcampaignresource.v4+json" - model = BrandsCampaign - - def path(self, **kwargs) -> str: - return "sb/v4/campaigns/list" - - def request_body_json( - self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None - ) -> Mapping[str, Any]: - request_body = super().request_body_json(stream_state, stream_slice, next_page_token) - if self.state_filter: - request_body["stateFilter"] = {"include": self.state_filter} - return request_body - - -class SponsoredBrandsAdGroups(SponsoredBrandsV4): - """ - This stream corresponds to Amazon Ads API - Sponsored Brands Ad Groups v4 - https://advertising.amazon.com/API/docs/en-us/sponsored-brands/3-0/openapi/prod#tag/Ad-groups/operation/ListSponsoredBrandsAdGroups - """ - - primary_key = "adGroupId" - data_field = "adGroups" - model = BrandsAdGroup - content_type = "application/vnd.sbadgroupresource.v4+json" - - def path(self, **kwargs) -> str: - return "sb/v4/adGroups/list" - - -class SponsoredBrandsKeywords(SubProfilesStream): - """ - This stream corresponds to Amazon Advertising API - Sponsored Brands Keywords - https://advertising.amazon.com/API/docs/en-us/sponsored-brands/3-0/openapi#/Keywords - """ - - primary_key = "adGroupId" - model = BrandsAdGroup - - def path(self, **kwargs) -> str: - return "sb/keywords" diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/sponsored_display.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/sponsored_display.py deleted file mode 100644 index 9c2b0f24fb85..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/sponsored_display.py +++ /dev/null @@ -1,115 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Mapping - -from source_amazon_ads.schemas import ( - DisplayAdGroup, - DisplayBudgetRules, - DisplayCampaign, - DisplayCreatives, - DisplayProductAds, - DisplayTargeting, -) -from source_amazon_ads.streams.common import SubProfilesStream - - -class SponsoredDisplayCampaigns(SubProfilesStream): - """ - This stream corresponds to Amazon Advertising API - Sponsored Displays Campaigns - https://advertising.amazon.com/API/docs/en-us/sponsored-display/3-0/openapi#/Campaigns - """ - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.state_filter = kwargs.get("config", {}).get("state_filter") - - primary_key = "campaignId" - state_filter = None - model = DisplayCampaign - - def path(self, **kwargs) -> str: - return "sd/campaigns" - - def request_params(self, *args, **kwargs): - params = super().request_params(*args, **kwargs) - if self.state_filter: - params["stateFilter"] = ",".join(self.state_filter) - return params - - -class SponsoredDisplayAdGroups(SubProfilesStream): - """ - This stream corresponds to Amazon Advertising API - Sponsored Displays Ad groups - https://advertising.amazon.com/API/docs/en-us/sponsored-display/3-0/openapi#/Ad%20groups - """ - - primary_key = "adGroupId" - model = DisplayAdGroup - - def path(self, **kwargs) -> str: - return "sd/adGroups" - - -class SponsoredDisplayProductAds(SubProfilesStream): - """ - This stream corresponds to Amazon Advertising API - Sponsored Displays Product Ads - https://advertising.amazon.com/API/docs/en-us/sponsored-display/3-0/openapi#/Product%20ads - """ - - primary_key = "adId" - model = DisplayProductAds - - def path(self, **kwargs) -> str: - return "sd/productAds" - - -class SponsoredDisplayTargetings(SubProfilesStream): - """ - This stream corresponds to Amazon Advertising API - Sponsored Displays Targetings - https://advertising.amazon.com/API/docs/en-us/sponsored-display/3-0/openapi#/Targeting - """ - - primary_key = "targetId" - model = DisplayTargeting - - def path(self, **kwargs) -> str: - return "sd/targets" - - -class SponsoredDisplayCreatives(SubProfilesStream): - """ - This stream corresponds to Amazon Advertising API - Sponsored Displays Creatives - https://advertising.amazon.com/API/docs/en-us/sponsored-display/3-0/openapi#/Creatives/listCreatives - """ - - primary_key = "creativeId" - model = DisplayCreatives - - def path(self, **kwargs) -> str: - return "/sd/creatives" - - -class SponsoredDisplayBudgetRules(SubProfilesStream): - """ - This stream corresponds to Amazon Advertising API - Sponsored Displays BudgetRules - https://advertising.amazon.com/API/docs/en-us/sponsored-display/3-0/openapi/prod#/BudgetRules/GetSDBudgetRulesForAdvertiser - - Important: API docs contains incorrect endpoint path: - sd/budgetRules - endpoint from API docs which always returns empty results - sp/budgetRules - working endpoint - """ - - primary_key = "ruleId" - model = DisplayBudgetRules - data_field = "budgetRulesForAdvertiserResponse" - page_size = 30 - - def path(self, **kwargs) -> str: - return "sp/budgetRules" - - def request_params(self, stream_slice: Mapping[str, Any] = None, **kwargs): - params = super().request_params(stream_slice=stream_slice, **kwargs) - params["pageSize"] = params.pop("count") - return params diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/sponsored_products.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/sponsored_products.py deleted file mode 100644 index 3b465e9ce2b6..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/sponsored_products.py +++ /dev/null @@ -1,303 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -from abc import ABC -from http import HTTPStatus -from typing import Any, Iterable, List, Mapping, MutableMapping, Optional - -from airbyte_protocol.models import SyncMode -from requests import Response -from source_amazon_ads.schemas import ( - ProductAd, - ProductAdGroupBidRecommendations, - ProductAdGroups, - ProductAdGroupSuggestedKeywords, - ProductCampaign, - ProductTargeting, - SponsoredProductCampaignNegativeKeywordsModel, - SponsoredProductKeywordsModel, - SponsoredProductNegativeKeywordsModel, -) -from source_amazon_ads.streams.common import SubProfilesStream - - -class SponsoredProductsV3(SubProfilesStream): - """ - This Stream supports the Sponsored Products v3 API, which requires POST methods - https://advertising.amazon.com/API/docs/en-us/sponsored-products/3-0/openapi/prod - """ - - @property - def http_method(self, **kwargs) -> str: - return "POST" - - def request_headers(self, profile_id: str = None, *args, **kwargs) -> MutableMapping[str, Any]: - headers = super().request_headers(*args, **kwargs) - headers["Accept"] = self.content_type - headers["Content-Type"] = self.content_type - return headers - - def next_page_token(self, response: Response) -> str: - if not response: - return None - return response.json().get("nextToken", None) - - def request_body_json( - self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None - ) -> Mapping[str, Any]: - request_body = {} - request_body["maxResults"] = self.page_size - if next_page_token: - request_body["nextToken"] = next_page_token - return request_body - - def request_params( - self, - stream_state: Mapping[str, Any], - stream_slice: Mapping[str, Any] = None, - next_page_token: int = None, - ) -> MutableMapping[str, Any]: - return {} - - -class SponsoredProductCampaigns(SponsoredProductsV3): - """ - This stream corresponds to Amazon Ads API - Sponsored Products (v3) Campaigns - https://advertising.amazon.com/API/docs/en-us/sponsored-products/3-0/openapi/prod#tag/Campaigns/operation/ListSponsoredProductsCampaigns - """ - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.state_filter = kwargs.get("config", {}).get("state_filter") - - primary_key = "campaignId" - data_field = "campaigns" - state_filter = None - model = ProductCampaign - content_type = "application/vnd.spCampaign.v3+json" - - def path(self, **kwargs) -> str: - return "sp/campaigns/list" - - def request_body_json( - self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None - ) -> Mapping[str, Any]: - request_body = super().request_body_json(stream_state, stream_slice, next_page_token) - if self.state_filter: - request_body["stateFilter"] = {"include": self.state_filter} - return request_body - - -class SponsoredProductAdGroups(SponsoredProductsV3): - """ - This stream corresponds to Amazon Ads API - Sponsored Products (v3) Ad groups - https://advertising.amazon.com/API/docs/en-us/sponsored-products/3-0/openapi/prod#tag/Ad-groups/operation/ListSponsoredProductsAdGroups - """ - - primary_key = "adGroupId" - data_field = "adGroups" - content_type = "application/vnd.spAdGroup.v3+json" - model = ProductAdGroups - - def path(self, **kwargs) -> str: - return "/sp/adGroups/list" - - -class SponsoredProductAdGroupWithSlicesABC(SponsoredProductsV3, ABC): - """ABC Class for extraction of additional information for each known sp ad group""" - - primary_key = "adGroupId" - - def __init__(self, *args, **kwargs): - self.__args = args - self.__kwargs = kwargs - super().__init__(*args, **kwargs) - - def stream_slices( - self, *, sync_mode: SyncMode, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None - ) -> Iterable[Optional[Mapping[str, Any]]]: - yield from SponsoredProductAdGroups(*self.__args, **self.__kwargs).read_records( - sync_mode=sync_mode, cursor_field=cursor_field, stream_slice=None, stream_state=stream_state - ) - - def parse_response(self, response: Response, **kwargs) -> Iterable[Mapping]: - - resp = response.json() - if response.status_code == HTTPStatus.OK: - yield resp - - if response.status_code == HTTPStatus.BAD_REQUEST: - # 400 error message for bids recommendation: - # Bid recommendation for AD group in Manual Targeted Campaign is not supported. - # 400 error message for keywords recommendation: - # Getting keyword recommendations for AD Group in Auto Targeted Campaign is not supported - self.logger.warning( - f"Skip current AdGroup because it does not support request {response.request.url} for " - f"{response.request.headers['Amazon-Advertising-API-Scope']} profile: {response.text}" - ) - elif response.status_code == HTTPStatus.UNPROCESSABLE_ENTITY: - # 422 error message for bids recommendation: - # No recommendations can be provided as the input ad group does not have any asins. - self.logger.warning( - f"Skip current AdGroup because the ad group {json.loads(response.request.body)['adGroupId']} does not have any asins {response.request.url}" - ) - elif response.status_code == HTTPStatus.NOT_FOUND: - # 404 Either the specified ad group identifier was not found, - # or the specified ad group was found but no associated bid was found. - self.logger.warning( - f"Skip current AdGroup because the specified ad group has no associated bid {response.request.url} for " - f"{response.request.headers['Amazon-Advertising-API-Scope']} profile: {response.text}" - ) - - else: - response.raise_for_status() - - -class SponsoredProductAdGroupBidRecommendations(SponsoredProductAdGroupWithSlicesABC): - """ - This stream corresponds to Amazon Ads API - Sponsored Products (v3) Ad group bid recommendations, now referred to as "Target Bid Recommendations" by Amazon Ads - https://advertising.amazon.com/API/docs/en-us/sponsored-display/3-0/openapi#tag/Bid-Recommendations/operation/getTargetBidRecommendations - """ - - primary_key = None - data_field = "bidRecommendations" - content_type = "application/vnd.spthemebasedbidrecommendation.v4+json" - model = ProductAdGroupBidRecommendations - - def path(self, stream_slice: Mapping[str, Any] = None, **kwargs) -> str: - return "/sp/targets/bid/recommendations" - - def request_body_json( - self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None - ) -> Mapping[str, Any]: - self.current_ad_group_id = stream_slice["adGroupId"] - self.current_campaign_id = stream_slice["campaignId"] - - request_body = {} - request_body["targetingExpressions"] = [ - {"type": "CLOSE_MATCH"}, - {"type": "LOOSE_MATCH"}, - {"type": "SUBSTITUTES"}, - {"type": "COMPLEMENTS"}, - ] - request_body["adGroupId"] = stream_slice["adGroupId"] - request_body["campaignId"] = stream_slice["campaignId"] - request_body["recommendationType"] = "BIDS_FOR_EXISTING_AD_GROUP" - return request_body - - def parse_response(self, response: Response, **kwargs) -> Iterable[Mapping]: - for record in super().parse_response(response, **kwargs): - record["adGroupId"] = self.current_ad_group_id - record["campaignId"] = self.current_campaign_id - yield record - - -class SponsoredProductAdGroupSuggestedKeywords(SponsoredProductAdGroupWithSlicesABC): - """Docs: - V2 API: - https://advertising.amazon.com/API/docs/en-us/sponsored-products/2-0/openapi#/Suggested%20keywords - GET /v2/sp/adGroups/{{adGroupId}}>/suggested/keywords - """ - - primary_key = None - data_field = "" - model = ProductAdGroupSuggestedKeywords - - @property - def http_method(self, **kwargs) -> str: - return "GET" - - def path(self, stream_slice: Mapping[str, Any] = None, **kwargs) -> str: - return f"v2/sp/adGroups/{stream_slice['adGroupId']}/suggested/keywords" - - def request_params( - self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, Any] = None, next_page_token: int = None - ) -> MutableMapping[str, Any]: - return {"maxNumSuggestions": 100} - - def request_headers(self, profile_id: str = None, *args, **kwargs) -> MutableMapping[str, Any]: - headers = {} - headers["Amazon-Advertising-API-Scope"] = str(self._current_profile_id) - headers["Amazon-Advertising-API-ClientId"] = self._client_id - return headers - - def request_body_json( - self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None - ) -> Mapping[str, Any]: - return {} - - -class SponsoredProductKeywords(SponsoredProductsV3): - """ - This stream corresponds to Amazon Ads Sponsored Products v3 API - Sponsored Products Keywords - https://advertising.amazon.com/API/docs/en-us/sponsored-products/3-0/openapi/prod#tag/Keywords/operation/ListSponsoredProductsKeywords - """ - - primary_key = "keywordId" - data_field = "keywords" - content_type = "application/vnd.spKeyword.v3+json" - model = SponsoredProductKeywordsModel - - def path(self, **kwargs) -> str: - return "sp/keywords/list" - - -class SponsoredProductNegativeKeywords(SponsoredProductsV3): - """ - This stream corresponds to Amazon Ads Sponsored Products v3 API - Sponsored Products Negative Keywords - https://advertising.amazon.com/API/docs/en-us/sponsored-products/3-0/openapi/prod#tag/Negative-keywords/operation/ListSponsoredProductsNegativeKeywords - """ - - primary_key = "keywordId" - data_field = "negativeKeywords" - content_type = "application/vnd.spNegativeKeyword.v3+json" - model = SponsoredProductNegativeKeywordsModel - - def path(self, **kwargs) -> str: - return "sp/negativeKeywords/list" - - -class SponsoredProductCampaignNegativeKeywords(SponsoredProductsV3): - """ - This stream corresponds to Amazon Ads Sponsored Products v3 API - Sponsored Products Negative Keywords - https://advertising.amazon.com/API/docs/en-us/sponsored-products/3-0/openapi/prod#tag/Campaign-negative-keywords/operation/ListSponsoredProductsCampaignNegativeKeywords - """ - - primary_key = "keywordId" - data_field = "campaignNegativeKeywords" - content_type = "application/vnd.spCampaignNegativeKeyword.v3+json" - model = SponsoredProductCampaignNegativeKeywordsModel - - def path(self, **kwargs) -> str: - return "sp/campaignNegativeKeywords/list" - - -class SponsoredProductAds(SponsoredProductsV3): - """ - This stream corresponds to Amazon Ads v3 API - Sponsored Products Ads - https://advertising.amazon.com/API/docs/en-us/sponsored-products/3-0/openapi/prod#tag/Product-ads/operation/ListSponsoredProductsProductAds - """ - - primary_key = "adId" - data_field = "productAds" - content_type = "application/vnd.spProductAd.v3+json" - model = ProductAd - - def path(self, **kwargs) -> str: - return "sp/productAds/list" - - -class SponsoredProductTargetings(SponsoredProductsV3): - """ - This stream corresponds to Amazon Ads Sponsored Products v3 API - Sponsored Products Targeting Clauses - """ - - primary_key = "targetId" - data_field = "targetingClauses" - content_type = "application/vnd.spTargetingClause.v3+json" - model = ProductTargeting - - def path(self, **kwargs) -> str: - return "sp/targets/list" diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/utils.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/utils.py index 62444e6984e0..5cde2adfd521 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/utils.py +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/utils.py @@ -6,6 +6,7 @@ import os from typing import Union + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/__init__.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/__init__.py index aabf455a3389..405206b533aa 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/__init__.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/__init__.py @@ -6,6 +6,4 @@ from .report_check_status_request_builer import ReportCheckStatusRequestBuilder from .report_download_request_builder import ReportDownloadRequestBuilder from .sponsored_products_report_request_builder import SponsoredProductsReportRequestBuilder -from .sponsored_brands_video_report_request_builder import SponsoredBrandsVideoReportRequestBuilder -from .sponsored_brands_report_request_builder import SponsoredBrandsReportRequestBuilder from .sponsored_brands_report_v3_request_builder import SponsoredBrandsV3ReportRequestBuilder diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/attribution_report_request_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/attribution_report_request_builder.py index c0c0572b42b4..d448a1ad9681 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/attribution_report_request_builder.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/attribution_report_request_builder.py @@ -5,7 +5,42 @@ from collections import OrderedDict from typing import Any, Dict, List, Optional -from source_amazon_ads.streams.attribution_report import BRAND_REFERRAL_BONUS, METRICS_MAP + +BRAND_REFERRAL_BONUS = "brb_bonus_amount" + +METRICS_MAP = { + "PERFORMANCE": [ + "Click-throughs", + "attributedDetailPageViewsClicks14d", + "attributedAddToCartClicks14d", + "attributedPurchases14d", + "unitsSold14d", + "attributedSales14d", + "attributedTotalDetailPageViewsClicks14d", + "attributedTotalAddToCartClicks14d", + "attributedTotalPurchases14d", + "totalUnitsSold14d", + "totalAttributedSales14d", + ], + "PRODUCTS": [ + "attributedDetailPageViewsClicks14d", + "attributedAddToCartClicks14d", + "attributedPurchases14d", + "unitsSold14d", + "attributedSales14d", + "brandHaloDetailPageViewsClicks14d", + "brandHaloAttributedAddToCartClicks14d", + "brandHaloAttributedPurchases14d", + "brandHaloUnitsSold14d", + "brandHaloAttributedSales14d", + "attributedNewToBrandPurchases14d", + "attributedNewToBrandUnitsSold14d", + "attributedNewToBrandSales14d", + "brandHaloNewToBrandPurchases14d", + "brandHaloNewToBrandUnitsSold14d", + "brandHaloNewToBrandSales14d", + ], +} from .base_request_builder import AmazonAdsBaseRequestBuilder @@ -15,64 +50,72 @@ class AttributionReportRequestBuilder(AmazonAdsBaseRequestBuilder): def products_endpoint( cls, client_id: str, client_access_token: str, profile_id: str, start_date: datetime.date, end_date: datetime.date, limit: int = 300 ) -> "AttributionReportRequestBuilder": - return cls("attribution/report") \ - .with_client_id(client_id) \ - .with_client_access_token(client_access_token) \ - .with_profile_id(profile_id) \ - .with_report_type("PRODUCTS") \ - .with_metrics(METRICS_MAP["PRODUCTS"]) \ - .with_limit(limit) \ - .with_start_date(start_date) \ + return ( + cls("attribution/report") + .with_client_id(client_id) + .with_client_access_token(client_access_token) + .with_profile_id(profile_id) + .with_report_type("PRODUCTS") + .with_metrics(METRICS_MAP["PRODUCTS"]) + .with_limit(limit) + .with_start_date(start_date) .with_end_date(end_date) + ) @classmethod def performance_adgroup_endpoint( cls, client_id: str, client_access_token: str, profile_id: str, start_date: datetime.date, end_date: datetime.date, limit: int = 300 ) -> "AttributionReportRequestBuilder": - return cls("attribution/report") \ - .with_client_id(client_id) \ - .with_client_access_token(client_access_token) \ - .with_profile_id(profile_id) \ - .with_report_type("PERFORMANCE") \ - .with_metrics(METRICS_MAP["PERFORMANCE"] + [BRAND_REFERRAL_BONUS]) \ - .with_limit(limit) \ - .with_start_date(start_date) \ - .with_end_date(end_date) \ + return ( + cls("attribution/report") + .with_client_id(client_id) + .with_client_access_token(client_access_token) + .with_profile_id(profile_id) + .with_report_type("PERFORMANCE") + .with_metrics(METRICS_MAP["PERFORMANCE"] + [BRAND_REFERRAL_BONUS]) + .with_limit(limit) + .with_start_date(start_date) + .with_end_date(end_date) .with_grouping("ADGROUP") + ) @classmethod def performance_campaign_endpoint( cls, client_id: str, client_access_token: str, profile_id: str, start_date: datetime.date, end_date: datetime.date, limit: int = 300 ) -> "AttributionReportRequestBuilder": - return cls("attribution/report") \ - .with_client_id(client_id) \ - .with_client_access_token(client_access_token) \ - .with_profile_id(profile_id) \ - .with_report_type("PERFORMANCE") \ - .with_metrics(METRICS_MAP["PERFORMANCE"] + [BRAND_REFERRAL_BONUS]) \ - .with_limit(limit) \ - .with_start_date(start_date) \ - .with_end_date(end_date) \ + return ( + cls("attribution/report") + .with_client_id(client_id) + .with_client_access_token(client_access_token) + .with_profile_id(profile_id) + .with_report_type("PERFORMANCE") + .with_metrics(METRICS_MAP["PERFORMANCE"] + [BRAND_REFERRAL_BONUS]) + .with_limit(limit) + .with_start_date(start_date) + .with_end_date(end_date) .with_grouping("CAMPAIGN") + ) @classmethod def performance_creative_endpoint( cls, client_id: str, client_access_token: str, profile_id: str, start_date: datetime.date, end_date: datetime.date, limit: int = 300 ) -> "AttributionReportRequestBuilder": - return cls("attribution/report") \ - .with_client_id(client_id) \ - .with_client_access_token(client_access_token) \ - .with_profile_id(profile_id) \ - .with_report_type("PERFORMANCE") \ - .with_metrics(METRICS_MAP["PERFORMANCE"]) \ - .with_limit(limit) \ - .with_start_date(start_date) \ - .with_end_date(end_date) \ + return ( + cls("attribution/report") + .with_client_id(client_id) + .with_client_access_token(client_access_token) + .with_profile_id(profile_id) + .with_report_type("PERFORMANCE") + .with_metrics(METRICS_MAP["PERFORMANCE"]) + .with_limit(limit) + .with_start_date(start_date) + .with_end_date(end_date) .with_grouping("CREATIVE") + ) def __init__(self, resource: str) -> None: super().__init__(resource) - self._cursor_field: Optional[int] = "" + self._cursor_field: Optional[int] = None self._end_date: Optional[str] = None self._grouping: Optional[str] = None self._limit: Optional[int] = None @@ -85,12 +128,12 @@ def query_params(self) -> Dict[str, Any]: return None @property - def request_body(self) ->Optional[str]: + def request_body(self) -> Optional[str]: body: dict = OrderedDict() if self._report_type: body["reportType"] = self._report_type - if self._limit: - body["count"] = self._limit + if self._grouping: + body["groupBy"] = self._grouping if self._metrics: body["metrics"] = ",".join(self._metrics) if self._start_date: @@ -98,10 +141,10 @@ def request_body(self) ->Optional[str]: if self._end_date: body["endDate"] = self._end_date - body["cursorId"] = self._cursor_field - - if self._grouping: - body["groupBy"] = self._grouping + if self._cursor_field: + body["cursorId"] = self._cursor_field + if self._limit: + body["count"] = self._limit return json.dumps(body) @@ -112,7 +155,7 @@ def with_cursor_field(self, cursor_field: str) -> "AttributionReportRequestBuild def with_end_date(self, end_date: datetime.date) -> "AttributionReportRequestBuilder": self._end_date: str = end_date.isoformat().replace("-", "") return self - + def with_grouping(self, grouping: str) -> "AttributionReportRequestBuilder": self._grouping: str = grouping return self @@ -124,7 +167,7 @@ def with_limit(self, limit: int) -> "AttributionReportRequestBuilder": def with_metrics(self, metrics: List[str]) -> "AttributionReportRequestBuilder": self._metrics: str = metrics return self - + def with_report_type(self, report_type: str) -> "AttributionReportRequestBuilder": self._report_type: str = report_type return self diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/base_request_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/base_request_builder.py index e0b58efab6e1..97b076e17ec1 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/base_request_builder.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/base_request_builder.py @@ -30,12 +30,7 @@ def request_body(self) -> Optional[str]: """""" def build(self) -> HttpRequest: - return HttpRequest( - url=self.url, - query_params=self.query_params, - headers=self.headers, - body=self.request_body - ) + return HttpRequest(url=self.url, query_params=self.query_params, headers=self.headers, body=self.request_body) class AmazonAdsBaseRequestBuilder(AmazonAdsRequestBuilder): diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/constants.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/constants.py index 217e4a8dbb39..f6e8e8211a2d 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/constants.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/constants.py @@ -1,4 +1,4 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. BASE_URL = "https://advertising-api.amazon.com" -BASE_OAUTH_URL = "https://api.amazon.com" \ No newline at end of file +BASE_OAUTH_URL = "https://api.amazon.com" diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/oauth_request_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/oauth_request_builder.py index 9038bced8d06..927f4a84cf61 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/oauth_request_builder.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/oauth_request_builder.py @@ -9,10 +9,7 @@ class OAuthRequestBuilder(AmazonAdsRequestBuilder): @classmethod def oauth_endpoint(cls, client_id: str, client_secred: str, refresh_token: str) -> "OAuthRequestBuilder": - return cls("auth/o2/token") \ - .with_client_id(client_id) \ - .with_client_secret(client_secred) \ - .with_refresh_token(refresh_token) + return cls("auth/o2/token").with_client_id(client_id).with_client_secret(client_secred).with_refresh_token(refresh_token) def __init__(self, resource: str) -> None: self._resource: str = resource @@ -34,7 +31,9 @@ def headers(self) -> Dict[str, Any]: @property def request_body(self) -> Optional[str]: - return f"grant_type=refresh_token&client_id={self._client_id}&client_secret={self._client_secret}&refresh_token={self._refresh_token}" + return ( + f"grant_type=refresh_token&client_id={self._client_id}&client_secret={self._client_secret}&refresh_token={self._refresh_token}" + ) def with_client_id(self, client_id: str) -> "OAuthRequestBuilder": self._client_id: str = client_id diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/profiles_request_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/profiles_request_builder.py index 5c5fb98fef7a..b907446da468 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/profiles_request_builder.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/profiles_request_builder.py @@ -9,10 +9,12 @@ class ProfilesRequestBuilder(AmazonAdsRequestBuilder): @classmethod def profiles_endpoint(cls, client_id: str, client_access_token: str) -> "ProfilesRequestBuilder": - return cls("v2/profiles") \ - .with_client_id(client_id) \ - .with_client_access_token(client_access_token) \ + return ( + cls("v2/profiles") + .with_client_id(client_id) + .with_client_access_token(client_access_token) .with_profile_type_filter(["seller", "vendor"]) + ) def __init__(self, resource: str) -> None: self._resource: str = resource @@ -24,7 +26,7 @@ def __init__(self, resource: str) -> None: def url(self) -> str: url = f"{BASE_URL}/{self._resource}" if self._profile_type_filter: - url = f"{url}?profileTypeFilter={','.join(self._profile_type_filter)}" + url = f"{url}?profileTypeFilter={','.join(self._profile_type_filter)}" return url @property diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/report_check_status_request_builer.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/report_check_status_request_builer.py index fcbd1ed257fc..acaf2039ec75 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/report_check_status_request_builer.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/report_check_status_request_builer.py @@ -6,42 +6,33 @@ class ReportCheckStatusRequestBuilder(AmazonAdsBaseRequestBuilder): - @classmethod def check_v2_report_status_endpoint( cls, client_id: str, client_access_token: str, profile_id: str, report_id: str ) -> "ReportCheckStatusRequestBuilder": - return cls(f"v2/reports/{report_id}") \ - .with_client_id(client_id) \ - .with_client_access_token(client_access_token) \ + return ( + cls(f"v2/reports/{report_id}") + .with_client_id(client_id) + .with_client_access_token(client_access_token) .with_profile_id(profile_id) + ) @classmethod def check_v3_report_status_endpoint( cls, client_id: str, client_access_token: str, profile_id: str, report_id: str ) -> "ReportCheckStatusRequestBuilder": - return cls(f"reporting/reports/{report_id}") \ - .with_client_id(client_id) \ - .with_client_access_token(client_access_token) \ + return ( + cls(f"reporting/reports/{report_id}") + .with_client_id(client_id) + .with_client_access_token(client_access_token) .with_profile_id(profile_id) + ) @classmethod def check_sponsored_display_report_status_endpoint( cls, client_id: str, client_access_token: str, profile_id: str, report_id: str ) -> "ReportCheckStatusRequestBuilder": - return cls.check_v2_report_status_endpoint(client_id, client_access_token, profile_id, report_id) - - @classmethod - def check_sponsored_brands_video_report_status_endpoint( - cls, client_id: str, client_access_token: str, profile_id: str, report_id: str - ) -> "ReportCheckStatusRequestBuilder": - return cls.check_v2_report_status_endpoint(client_id, client_access_token, profile_id, report_id) - - @classmethod - def check_sponsored_brands_report_status_endpoint( - cls, client_id: str, client_access_token: str, profile_id: str, report_id: str - ) -> "ReportCheckStatusRequestBuilder": - return cls.check_v2_report_status_endpoint(client_id, client_access_token, profile_id, report_id) + return cls.check_v3_report_status_endpoint(client_id, client_access_token, profile_id, report_id) @classmethod def check_sponsored_products_report_status_endpoint( @@ -63,5 +54,5 @@ def query_params(self) -> Dict[str, Any]: return None @property - def request_body(self) ->Optional[str]: + def request_body(self) -> Optional[str]: return None diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/report_download_request_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/report_download_request_builder.py index 3e234bc587a4..d9697630c6be 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/report_download_request_builder.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/report_download_request_builder.py @@ -13,10 +13,7 @@ def __init__(self, report_id: str) -> None: @property def url(self): - return ( - f"https://offline-report-storage-us-east-1-prod.s3.amazonaws.com" - f"/{self._report_id}/{self._report_id}.json" - ) + return f"https://offline-report-storage-us-east-1-prod.s3.amazonaws.com" f"/{self._report_id}/{self._report_id}.json" @property def headers(self): diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_brands_report_request_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_brands_report_request_builder.py deleted file mode 100644 index c81423442747..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_brands_report_request_builder.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -import json -from collections import OrderedDict -from typing import Any, Dict, List, Optional - -import pendulum - -from .base_request_builder import AmazonAdsBaseRequestBuilder - - -class SponsoredBrandsReportRequestBuilder(AmazonAdsBaseRequestBuilder): - @classmethod - def _init_report_endpoint( - cls, client_id: str, client_access_token: str, profile_id: str, report_type: str, metrics: List[str], report_date: Optional[str] = None - ) -> "SponsoredBrandsReportRequestBuilder": - return cls(f"v2/hsa/{report_type}/report") \ - .with_client_id(client_id) \ - .with_client_access_token(client_access_token) \ - .with_profile_id(profile_id) \ - .with_metrics(metrics) \ - .with_report_date(report_date) - - @classmethod - def init_campaigns_report_endpoint( - cls, client_id: str, client_access_token: str, profile_id: str, metrics: List[str], report_date: Optional[str] - ) -> "SponsoredBrandsReportRequestBuilder": - return cls._init_report_endpoint(client_id, client_access_token, profile_id, "campaigns", report_date, metrics) - - @classmethod - def init_ad_groups_report_endpoint( - cls, client_id: str, client_access_token: str, profile_id: str, metrics: List[str], report_date: Optional[str] - ) -> "SponsoredBrandsReportRequestBuilder": - return cls._init_report_endpoint(client_id, client_access_token, profile_id, "adGroups", report_date, metrics) - - @classmethod - def init_keywords_report_endpoint( - cls, client_id: str, client_access_token: str, profile_id: str, metrics: List[str], report_date: Optional[str] - ) -> "SponsoredBrandsReportRequestBuilder": - return cls._init_report_endpoint(client_id, client_access_token, profile_id, "keywords", report_date, metrics) - - def __init__(self, resource: str) -> None: - super().__init__(resource) - self._metrics: List[str] = None - self._report_date: str = None - - @property - def query_params(self) -> Dict[str, Any]: - return None - - @property - def request_body(self) ->Optional[str]: - body: dict = OrderedDict() - if self._report_date: - body["reportDate"] = self._report_date - if self._metrics: - body["metrics"] = self._metrics - return json.dumps(body) - - def with_report_date(self, report_date: pendulum.date) -> "SponsoredBrandsReportRequestBuilder": - self._report_date = report_date.format("YYYYMMDD") - return self - - def with_metrics(self, metrics: List[str]) -> "SponsoredBrandsReportRequestBuilder": - self._metrics = ",".join(metrics) - return self diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_brands_report_v3_request_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_brands_report_v3_request_builder.py index f8ddae54d5e6..0987e20379b8 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_brands_report_v3_request_builder.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_brands_report_v3_request_builder.py @@ -12,15 +12,23 @@ class SponsoredBrandsV3ReportRequestBuilder(AmazonAdsBaseRequestBuilder): @classmethod def _init_report_endpoint( - cls, client_id: str, client_access_token: str, profile_id: str, report_type: str, metrics: List[str], report_date: Optional[str] = None + cls, + client_id: str, + client_access_token: str, + profile_id: str, + report_type: str, + metrics: List[str], + report_date: Optional[str] = None, ) -> "SponsoredBrandsV3ReportRequestBuilder": - return cls(f"reporting/reports") \ - .with_client_id(client_id) \ - .with_client_access_token(client_access_token) \ - .with_profile_id(profile_id) \ - .with_metrics(metrics) \ - .with_report_date(report_date) \ + return ( + cls(f"reporting/reports") + .with_client_id(client_id) + .with_client_access_token(client_access_token) + .with_profile_id(profile_id) + .with_metrics(metrics) + .with_report_date(report_date) .with_report_type(report_type) + ) @classmethod def init_purchased_asin_report_endpoint( @@ -57,7 +65,7 @@ def query_params(self) -> Dict[str, Any]: return None @property - def request_body(self) ->Optional[str]: + def request_body(self) -> Optional[str]: body: dict = OrderedDict() if self._report_type and self._report_date: body["name"] = f"{self._report_type} report {self._report_date}" @@ -67,10 +75,7 @@ def request_body(self) ->Optional[str]: body["endDate"] = self._report_date if self._report_type: - body["configuration"] = { - "adProduct": "SPONSORED_BRANDS", - "groupBy": self._report_config_group_by - } + body["configuration"] = {"adProduct": "SPONSORED_BRANDS", "groupBy": self._report_config_group_by} if self._metrics: body["configuration"]["columns"] = self._metrics diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_brands_request_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_brands_request_builder.py index 65b947483c66..a1b99683a259 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_brands_request_builder.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_brands_request_builder.py @@ -7,33 +7,29 @@ class SponsoredBrandsRequestBuilder(AmazonAdsBaseRequestBuilder): @classmethod - def ad_groups_endpoint( - cls, client_id: str, client_access_token: str, profile_id: str - ) -> "SponsoredBrandsRequestBuilder": - return cls("sb/v4/adGroups/list") \ - .with_client_id(client_id) \ - .with_client_access_token(client_access_token) \ - .with_profile_id(profile_id) + def ad_groups_endpoint(cls, client_id: str, client_access_token: str, profile_id: str) -> "SponsoredBrandsRequestBuilder": + return ( + cls("sb/v4/adGroups/list").with_client_id(client_id).with_client_access_token(client_access_token).with_profile_id(profile_id) + ) @classmethod def keywords_endpoint( cls, client_id: str, client_access_token: str, profile_id: str, limit: Optional[int] = 100, start_index: Optional[int] = 0 ) -> "SponsoredBrandsRequestBuilder": - return cls("sb/keywords") \ - .with_client_id(client_id) \ - .with_client_access_token(client_access_token) \ - .with_profile_id(profile_id) \ - .with_limit(limit) \ + return ( + cls("sb/keywords") + .with_client_id(client_id) + .with_client_access_token(client_access_token) + .with_profile_id(profile_id) + .with_limit(limit) .with_start_index(start_index) + ) @classmethod - def campaigns_endpoint( - cls, client_id: str, client_access_token: str, profile_id: str - ) -> "SponsoredBrandsRequestBuilder": - return cls("sb/v4/campaigns/list") \ - .with_client_id(client_id) \ - .with_client_access_token(client_access_token) \ - .with_profile_id(profile_id) + def campaigns_endpoint(cls, client_id: str, client_access_token: str, profile_id: str) -> "SponsoredBrandsRequestBuilder": + return ( + cls("sb/v4/campaigns/list").with_client_id(client_id).with_client_access_token(client_access_token).with_profile_id(profile_id) + ) def __init__(self, resource: str) -> None: super().__init__(resource) @@ -51,7 +47,7 @@ def query_params(self) -> Dict[str, Any]: return query_params @property - def request_body(self) ->Optional[str]: + def request_body(self) -> Optional[str]: return self._body def with_limit(self, limit: int) -> "SponsoredBrandsRequestBuilder": diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_brands_video_report_request_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_brands_video_report_request_builder.py deleted file mode 100644 index 21a9d59a828d..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_brands_video_report_request_builder.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -import json -from collections import OrderedDict -from typing import Any, Dict, List, Optional - -import pendulum - -from .base_request_builder import AmazonAdsBaseRequestBuilder - - -class SponsoredBrandsVideoReportRequestBuilder(AmazonAdsBaseRequestBuilder): - @classmethod - def _init_report_endpoint( - cls, client_id: str, client_access_token: str, profile_id: str, report_type: str, metrics: List[str], report_date: Optional[str] = None - ) -> "SponsoredBrandsVideoReportRequestBuilder": - return cls(f"v2/hsa/{report_type}/report") \ - .with_client_id(client_id) \ - .with_client_access_token(client_access_token) \ - .with_profile_id(profile_id) \ - .with_metrics(metrics) \ - .with_report_date(report_date) - - @classmethod - def init_campaigns_report_endpoint( - cls, client_id: str, client_access_token: str, profile_id: str, metrics: List[str], report_date: Optional[str] - ) -> "SponsoredBrandsVideoReportRequestBuilder": - return cls.init_report_endpoint(client_id, client_access_token, profile_id, "campaigns", report_date, metrics) - - @classmethod - def init_ad_groups_report_endpoint( - cls, client_id: str, client_access_token: str, profile_id: str, metrics: List[str], report_date: Optional[str] - ) -> "SponsoredBrandsVideoReportRequestBuilder": - return cls.init_report_endpoint(client_id, client_access_token, profile_id, "adGroups", report_date, metrics) - - @classmethod - def init_keywords_report_endpoint( - cls, client_id: str, client_access_token: str, profile_id: str, metrics: List[str], report_date: Optional[str] - ) -> "SponsoredBrandsVideoReportRequestBuilder": - return cls.init_report_endpoint(client_id, client_access_token, profile_id, "keywords", report_date, metrics) - - def __init__(self, resource: str) -> None: - super().__init__(resource) - self._metrics: List[str] = None - self._report_date: str = None - - @property - def query_params(self) -> Dict[str, Any]: - return None - - @property - def request_body(self) ->Optional[str]: - body: dict = OrderedDict() - if self._report_date: - body["reportDate"] = self._report_date - body["creativeType"] = "video" - if self._metrics: - body["metrics"] = self._metrics - return json.dumps(body) - - def with_report_date(self, report_date: pendulum.date) -> "SponsoredBrandsVideoReportRequestBuilder": - self._report_date = report_date.format("YYYYMMDD") - return self - - def with_metrics(self, metrics: List[str]) -> "SponsoredBrandsVideoReportRequestBuilder": - self._metrics = ",".join(metrics) - return self diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_display_report_request_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_display_report_request_builder.py index cfa25f28aa3b..93a52c8e80bf 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_display_report_request_builder.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_display_report_request_builder.py @@ -12,21 +12,29 @@ class SponsoredDisplayReportRequestBuilder(AmazonAdsBaseRequestBuilder): @classmethod def _init_report_endpoint( - cls, client_id: str, client_access_token: str, profile_id: str, report_type: str, tactics: str, metrics: List[str], report_date: Optional[str] = None + cls, + client_id: str, + client_access_token: str, + profile_id: str, + report_type: str, + metrics: List[str], + report_date: Optional[str] = None, ) -> "SponsoredDisplayReportRequestBuilder": - return cls(f"sd/{report_type}/report") \ - .with_client_id(client_id) \ - .with_client_access_token(client_access_token) \ - .with_profile_id(profile_id) \ - .with_tactics(tactics) \ - .with_metrics(metrics) \ + return ( + cls(f"reporting/reports") + .with_client_id(client_id) + .with_client_access_token(client_access_token) + .with_profile_id(profile_id) + .with_metrics(metrics) .with_report_date(report_date) + .with_report_type(report_type) + ) @classmethod def init_campaigns_report_endpoint( - cls, client_id: str, client_access_token: str, profile_id: str, tactics: str, metrics: List[str], report_date: Optional[str] + cls, client_id: str, client_access_token: str, profile_id: str, metrics: List[str], report_date: Optional[str] ) -> "SponsoredDisplayReportRequestBuilder": - return cls._init_report_endpoint(client_id, client_access_token, profile_id, "campaigns", report_date, tactics, metrics) + return cls._init_report_endpoint(client_id, client_access_token, profile_id, "campaigns", report_date, metrics) @classmethod def init_ad_groups_report_endpoint( @@ -56,30 +64,84 @@ def __init__(self, resource: str) -> None: super().__init__(resource) self._metrics: List[str] = None self._report_date: str = None + self._report_type: str = None + + @property + def _report_config_group_by(self) -> List[str]: + return { + "campaigns": ["campaign"], + "adGroups": ["adGroup"], + "keywords": ["targeting"], + "targets": ["targeting"], + "productAds": ["advertiser"], + "asins_keywords": ["asin"], + "asins_targets": ["asin"], + "asins": ["asin"], + }[self._report_type] + + @property + def _report_config_report_type_id(self) -> str: + return { + "campaigns": "sdCampaigns", + "adGroups": "sdAdGroup", + "keywords": "sdTargeting", + "targets": "sdTargeting", + "productAds": "sdAdvertisedProduct", + "asins_keywords": "sdPurchasedProduct", + "asins_targets": "sdPurchasedProduct", + "asins": "sdPurchasedProduct", + }[self._report_type] + + @property + def _report_config_filters(self) -> List[str]: + return { + "campaigns": [], + "adGroups": [], + "keywords": [{"field": "keywordType", "values": ["BROAD", "PHRASE", "EXACT"]}], + "targets": [], + "productAds": [], + "asins_keywords": [], + "asins_targets": [], + "asins": [], + }[self._report_type] @property def query_params(self) -> Dict[str, Any]: return None @property - def request_body(self) ->Optional[str]: + def request_body(self) -> Optional[str]: body: dict = OrderedDict() + if self._report_type and self._report_date: + body["name"] = f"{self._report_type} report {self._report_date}" + if self._report_date: - body["reportDate"] = self._report_date - if self._tactics: - body["tactic"] = self._tactics + body["startDate"] = self._report_date + body["endDate"] = self._report_date + + if self._report_type: + body["configuration"] = {"adProduct": "SPONSORED_DISPLAY", "groupBy": self._report_config_group_by} + if self._metrics: - body["metrics"] = self._metrics + body["configuration"]["columns"] = self._metrics + + if self._report_type: + body["configuration"]["reportTypeId"] = self._report_config_report_type_id + body["configuration"]["filters"] = self._report_config_filters + + body["configuration"]["timeUnit"] = "SUMMARY" + body["configuration"]["format"] = "GZIP_JSON" + return json.dumps(body) def with_report_date(self, report_date: pendulum.date) -> "SponsoredDisplayReportRequestBuilder": - self._report_date = report_date.format("YYYYMMDD") + self._report_date = report_date.format("YYYY-MM-DD") return self - def with_tactics(self, tactics: str) -> "SponsoredDisplayReportRequestBuilder": - self._tactics = tactics + def with_metrics(self, metrics: List[str]) -> "SponsoredDisplayReportRequestBuilder": + self._metrics = metrics return self - def with_metrics(self, metrics: List[str]) -> "SponsoredDisplayReportRequestBuilder": - self._metrics = ",".join(metrics) + def with_report_type(self, report_type: str) -> "SponsoredDisplayReportRequestBuilder": + self._report_type = report_type return self diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_products_report_request_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_products_report_request_builder.py index b5bba3e2aded..ce5c4dd52b06 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_products_report_request_builder.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_requests/sponsored_products_report_request_builder.py @@ -12,15 +12,23 @@ class SponsoredProductsReportRequestBuilder(AmazonAdsBaseRequestBuilder): @classmethod def _init_report_endpoint( - cls, client_id: str, client_access_token: str, profile_id: str, report_type: str, metrics: List[str], report_date: Optional[str] = None + cls, + client_id: str, + client_access_token: str, + profile_id: str, + report_type: str, + metrics: List[str], + report_date: Optional[str] = None, ) -> "SponsoredProductsReportRequestBuilder": - return cls(f"reporting/reports") \ - .with_client_id(client_id) \ - .with_client_access_token(client_access_token) \ - .with_profile_id(profile_id) \ - .with_metrics(metrics) \ - .with_report_date(report_date) \ + return ( + cls(f"reporting/reports") + .with_client_id(client_id) + .with_client_access_token(client_access_token) + .with_profile_id(profile_id) + .with_metrics(metrics) + .with_report_date(report_date) .with_report_type(report_type) + ) @classmethod def init_campaigns_report_endpoint( @@ -111,7 +119,7 @@ def query_params(self) -> Dict[str, Any]: return None @property - def request_body(self) ->Optional[str]: + def request_body(self) -> Optional[str]: body: dict = OrderedDict() if self._report_type and self._report_date: body["name"] = f"{self._report_type} report {self._report_date}" @@ -121,10 +129,7 @@ def request_body(self) ->Optional[str]: body["endDate"] = self._report_date if self._report_type: - body["configuration"] = { - "adProduct": "SPONSORED_PRODUCTS", - "groupBy": self._report_config_group_by - } + body["configuration"] = {"adProduct": "SPONSORED_PRODUCTS", "groupBy": self._report_config_group_by} if self._metrics: body["configuration"]["columns"] = self._metrics diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/error_response_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/error_response_builder.py index c23611559074..fd211041c409 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/error_response_builder.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/error_response_builder.py @@ -17,7 +17,9 @@ class ErrorResponseBuilder(HttpResponseBuilder): - def __init__(self, template: Dict[str, Any], records_path: Union[FieldPath, NestedPath], pagination_strategy: Union[PaginationStrategy, None]): + def __init__( + self, template: Dict[str, Any], records_path: Union[FieldPath, NestedPath], pagination_strategy: Union[PaginationStrategy, None] + ): super().__init__(template, records_path, pagination_strategy) self._records: Dict[str, Any] = {} diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/records/error_record_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/records/error_record_builder.py index 2028d58e7159..d4d79895458b 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/records/error_record_builder.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/records/error_record_builder.py @@ -11,7 +11,7 @@ def __init__( template: Dict[str, Any], id_path: Optional[Path] = None, cursor_path: Optional[Union[FieldPath, NestedPath]] = None, - error_message_path: Optional[Path] = None + error_message_path: Optional[Path] = None, ): super().__init__(template, id_path, cursor_path) self._error_message_path = error_message_path diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/records/report_check_status_record_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/records/report_check_status_record_builder.py index 8681c0eb3b09..f0f57d01d57f 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/records/report_check_status_record_builder.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/records/report_check_status_record_builder.py @@ -9,10 +9,7 @@ class ReportCheckStatusRecordBuilder(RecordBuilder): @classmethod def status_record(cls) -> "ReportCheckStatusRecordBuilder": return cls( - find_template("report_status_response", __file__), - id_path=None, - status_path=FieldPath("status"), - url_path=FieldPath("url") + find_template("report_status_response", __file__), id_path=None, status_path=FieldPath("status"), url_path=FieldPath("url") ) def __init__( @@ -21,7 +18,7 @@ def __init__( id_path: Optional[Path] = None, status_path: Optional[Path] = None, url_path: Optional[Path] = None, - cursor_path: Optional[Union[FieldPath, NestedPath]] = None + cursor_path: Optional[Union[FieldPath, NestedPath]] = None, ): super().__init__(template, id_path, cursor_path) self._status_path = status_path diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/records/report_init_response_record_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/records/report_init_response_record_builder.py index eec142972d1c..f534252fafb2 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/records/report_init_response_record_builder.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/records/report_init_response_record_builder.py @@ -12,7 +12,7 @@ def init_response_record(cls) -> "ReportInitResponseRecordBuilder": find_template("report_init_response", __file__), id_path=FieldPath("reportId"), status_path=FieldPath("status"), - cursor_path=None + cursor_path=None, ) def __init__( @@ -20,7 +20,7 @@ def __init__( template: Dict[str, Any], id_path: Optional[Path] = None, status_path: Optional[Path] = None, - cursor_path: Optional[Union[FieldPath, NestedPath]] = None + cursor_path: Optional[Union[FieldPath, NestedPath]] = None, ): super().__init__(template, id_path, cursor_path) self._status_path = status_path diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/report_check_status_response_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/report_check_status_response_builder.py index 8ba0dfc26aed..202a00006d17 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/report_check_status_response_builder.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/report_check_status_response_builder.py @@ -12,11 +12,11 @@ class ReportCheckStatusResponseBuilder(HttpResponseBuilder): @classmethod def check_status_response(cls) -> "ReportCheckStatusResponseBuilder": return cls(find_template("report_status_response", __file__), DictTemplatePath(), None) - + def with_record(self, record: RecordBuilder) -> HttpResponseBuilder: self._records = record return self - + def build(self) -> HttpResponse: self._records_path.update(self._response, self._records.build()) return HttpResponse(json.dumps(self._response), self._status_code) diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/report_init_response_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/report_init_response_builder.py index 470b7f72a527..b39471ed1dac 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/report_init_response_builder.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/report_init_response_builder.py @@ -12,11 +12,11 @@ class ReportInitResponseBuilder(HttpResponseBuilder): @classmethod def report_init_response(cls) -> "ReportInitResponseBuilder": return cls(find_template("report_init_response", __file__), DictTemplatePath(), None) - + def with_record(self, record: RecordBuilder) -> HttpResponseBuilder: self._records = record return self - + def build(self) -> HttpResponse: self._records_path.update(self._response, self._records.build()) return HttpResponse(json.dumps(self._response), self._status_code) diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/sponsored_brands_response_builder.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/sponsored_brands_response_builder.py index 2b07547fa989..ec75641b8063 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/sponsored_brands_response_builder.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/ad_responses/sponsored_brands_response_builder.py @@ -13,7 +13,9 @@ def ad_groups_response(cls, pagination_strategy: Optional[PaginationStrategy] = return cls(find_template("sponsored_brands_ad_groups", __file__), ListTemplatePath(), pagination_strategy) @classmethod - def ad_groups_non_breaking_error_response(cls, pagination_strategy: Optional[PaginationStrategy] = None) -> "SponsoredBrandsResponseBuilder": + def ad_groups_non_breaking_error_response( + cls, pagination_strategy: Optional[PaginationStrategy] = None + ) -> "SponsoredBrandsResponseBuilder": return cls(find_template("non_breaking_error", __file__), ListTemplatePath(), pagination_strategy) @classmethod diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/config.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/config.py index a9a989b8d8c7..2acee74d842c 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/config.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/config.py @@ -5,6 +5,7 @@ from airbyte_cdk.test.mock_http.response_builder import find_template + CLIENT_ID = "amzn.app-oa2-client.test" CLIENT_SECRET = "test-secret" REGION = "NA" diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/test_attribution_report_streams.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/test_attribution_report_streams.py index 6548c3a39c9f..4bee406a893a 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/test_attribution_report_streams.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/test_attribution_report_streams.py @@ -6,9 +6,10 @@ from zoneinfo import ZoneInfo import freezegun + +from airbyte_cdk.models import Level as LogLevel +from airbyte_cdk.models import SyncMode from airbyte_cdk.test.mock_http import HttpMocker -from airbyte_protocol.models import Level as LogLevel -from airbyte_protocol.models import SyncMode from .ad_requests import AttributionReportRequestBuilder, OAuthRequestBuilder, ProfilesRequestBuilder from .ad_responses import AttributionReportResponseBuilder, ErrorResponseBuilder, OAuthResponseBuilder, ProfilesResponseBuilder @@ -17,6 +18,7 @@ from .config import ConfigBuilder from .utils import get_log_messages_by_log_level, read_stream + REPORTING_PERIOD = 90 _NOW = datetime.now(timezone.utc) _A_START_DATE = _NOW - timedelta(days=REPORTING_PERIOD) @@ -31,12 +33,14 @@ def _config(self): def _given_oauth_and_profiles(self, http_mocker: HttpMocker, config: dict) -> None: http_mocker.post( - OAuthRequestBuilder.oauth_endpoint(client_id=config["client_id"], client_secred=config["client_secret"], refresh_token=config["refresh_token"]).build(), - OAuthResponseBuilder.token_response().build() + OAuthRequestBuilder.oauth_endpoint( + client_id=config["client_id"], client_secred=config["client_secret"], refresh_token=config["refresh_token"] + ).build(), + OAuthResponseBuilder.token_response().build(), ) http_mocker.get( ProfilesRequestBuilder.profiles_endpoint(client_id=config["client_id"], client_access_token=config["access_token"]).build(), - ProfilesResponseBuilder.profiles_response().with_record(ProfilesRecordBuilder.profiles_record()).build() + ProfilesResponseBuilder.profiles_response().with_record(ProfilesRecordBuilder.profiles_record()).build(), ) @HttpMocker() @@ -56,17 +60,17 @@ def test_given_non_breaking_error_when_read_products_then_stream_is_ignored(self self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), ).build(), - ErrorResponseBuilder.non_breaking_error_response().with_record(non_breaking_error).with_status_code(400).build() + ErrorResponseBuilder.non_breaking_error_response().with_record(non_breaking_error).with_status_code(400).build(), ) output = read_stream("attribution_report_products", SyncMode.full_refresh, self._config) assert len(output.records) == 0 - warning_logs = get_log_messages_by_log_level(output.logs, LogLevel.WARN) - assert any([non_breaking_error.build().get("details") in worning for worning in warning_logs]) - + info_logs = get_log_messages_by_log_level(output.logs, LogLevel.INFO) + assert any([non_breaking_error.build().get("details") in info for info in info_logs]) + @HttpMocker() def test_given_breaking_error_when_read_products_then_stream_is_ignored(self, http_mocker): """ @@ -83,12 +87,12 @@ def test_given_breaking_error_when_read_products_then_stream_is_ignored(self, ht self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), ).build(), - ErrorResponseBuilder.breaking_error_response().with_record(breaking_error).with_status_code(500).build() + ErrorResponseBuilder.breaking_error_response().with_record(breaking_error).with_status_code(500).build(), ) - with patch('time.sleep', return_value=None): + with patch("time.sleep", return_value=None): output = read_stream("attribution_report_products", SyncMode.full_refresh, self._config) assert len(output.records) == 0 @@ -110,9 +114,9 @@ def test_given_one_page_when_read_products_then_return_records(self, http_mocker self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), ).build(), - AttributionReportResponseBuilder.products_response().with_record(AttributionReportRecordBuilder.products_record()).build() + AttributionReportResponseBuilder.products_response().with_record(AttributionReportRecordBuilder.products_record()).build(), ) output = read_stream("attribution_report_products", SyncMode.full_refresh, self._config) @@ -133,12 +137,12 @@ def test_given_many_pages_when_read_products_then_return_records(self, http_mock self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), ).build(), - AttributionReportResponseBuilder.products_response(CursorBasedPaginationStrategy()) \ - .with_record(AttributionReportRecordBuilder.products_record()) \ - .with_pagination() \ - .build() + AttributionReportResponseBuilder.products_response(CursorBasedPaginationStrategy()) + .with_record(AttributionReportRecordBuilder.products_record()) + .with_pagination() + .build(), ) http_mocker.post( AttributionReportRequestBuilder.products_endpoint( @@ -146,9 +150,11 @@ def test_given_many_pages_when_read_products_then_return_records(self, http_mock self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() - ).with_cursor_field("next-page-token").build(), - AttributionReportResponseBuilder.products_response().with_record(AttributionReportRecordBuilder.products_record()).build() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), + ) + .with_cursor_field("next-page-token") + .build(), + AttributionReportResponseBuilder.products_response().with_record(AttributionReportRecordBuilder.products_record()).build(), ) output = read_stream("attribution_report_products", SyncMode.full_refresh, self._config) @@ -171,17 +177,17 @@ def test_given_non_breaking_error_when_read_performance_adgroup_then_stream_is_i self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), ).build(), - ErrorResponseBuilder.non_breaking_error_response().with_record(non_breaking_error).with_status_code(400).build() + ErrorResponseBuilder.non_breaking_error_response().with_record(non_breaking_error).with_status_code(400).build(), ) output = read_stream("attribution_report_performance_adgroup", SyncMode.full_refresh, self._config) assert len(output.records) == 0 - warning_logs = get_log_messages_by_log_level(output.logs, LogLevel.WARN) - assert any([non_breaking_error.build().get("details") in worning for worning in warning_logs]) - + info_logs = get_log_messages_by_log_level(output.logs, LogLevel.INFO) + assert any([non_breaking_error.build().get("details") in info for info in info_logs]) + @HttpMocker() def test_given_breaking_error_when_read_performance_adgroup_then_stream_is_ignored(self, http_mocker): """ @@ -198,12 +204,12 @@ def test_given_breaking_error_when_read_performance_adgroup_then_stream_is_ignor self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), ).build(), - ErrorResponseBuilder.breaking_error_response().with_record(breaking_error).with_status_code(500).build() + ErrorResponseBuilder.breaking_error_response().with_record(breaking_error).with_status_code(500).build(), ) - with patch('time.sleep', return_value=None): + with patch("time.sleep", return_value=None): output = read_stream("attribution_report_performance_adgroup", SyncMode.full_refresh, self._config) assert len(output.records) == 0 @@ -225,14 +231,16 @@ def test_given_one_page_when_read_performance_adgroup_then_return_records(self, self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), ).build(), - AttributionReportResponseBuilder.performance_adgroup_response().with_record(AttributionReportRecordBuilder.performance_adgroup_record()).build() + AttributionReportResponseBuilder.performance_adgroup_response() + .with_record(AttributionReportRecordBuilder.performance_adgroup_record()) + .build(), ) output = read_stream("attribution_report_performance_adgroup", SyncMode.full_refresh, self._config) assert len(output.records) == 1 - + @HttpMocker() def test_given_many_pages_when_read_performance_adgroup_then_return_records(self, http_mocker): """ @@ -248,12 +256,12 @@ def test_given_many_pages_when_read_performance_adgroup_then_return_records(self self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), ).build(), - AttributionReportResponseBuilder.performance_adgroup_response(CursorBasedPaginationStrategy()) \ - .with_record(AttributionReportRecordBuilder.performance_adgroup_record()) \ - .with_pagination() \ - .build() + AttributionReportResponseBuilder.performance_adgroup_response(CursorBasedPaginationStrategy()) + .with_record(AttributionReportRecordBuilder.performance_adgroup_record()) + .with_pagination() + .build(), ) http_mocker.post( AttributionReportRequestBuilder.performance_adgroup_endpoint( @@ -261,14 +269,18 @@ def test_given_many_pages_when_read_performance_adgroup_then_return_records(self self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() - ).with_cursor_field("next-page-token").build(), - AttributionReportResponseBuilder.performance_adgroup_response().with_record(AttributionReportRecordBuilder.performance_adgroup_record()).build() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), + ) + .with_cursor_field("next-page-token") + .build(), + AttributionReportResponseBuilder.performance_adgroup_response() + .with_record(AttributionReportRecordBuilder.performance_adgroup_record()) + .build(), ) output = read_stream("attribution_report_performance_adgroup", SyncMode.full_refresh, self._config) assert len(output.records) == 2 - + @HttpMocker() def test_given_non_breaking_error_when_read_performance_campaign_then_stream_is_ignored(self, http_mocker): """ @@ -286,17 +298,17 @@ def test_given_non_breaking_error_when_read_performance_campaign_then_stream_is_ self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), ).build(), - ErrorResponseBuilder.non_breaking_error_response().with_record(non_breaking_error).with_status_code(400).build() + ErrorResponseBuilder.non_breaking_error_response().with_record(non_breaking_error).with_status_code(400).build(), ) output = read_stream("attribution_report_performance_campaign", SyncMode.full_refresh, self._config) assert len(output.records) == 0 - warning_logs = get_log_messages_by_log_level(output.logs, LogLevel.WARN) - assert any([non_breaking_error.build().get("details") in worning for worning in warning_logs]) - + info_logs = get_log_messages_by_log_level(output.logs, LogLevel.INFO) + assert any([non_breaking_error.build().get("details") in info for info in info_logs]) + @HttpMocker() def test_given_breaking_error_when_read_performance_campaign_then_stream_is_ignored(self, http_mocker): """ @@ -313,12 +325,12 @@ def test_given_breaking_error_when_read_performance_campaign_then_stream_is_igno self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), ).build(), - ErrorResponseBuilder.breaking_error_response().with_record(breaking_error).with_status_code(500).build() + ErrorResponseBuilder.breaking_error_response().with_record(breaking_error).with_status_code(500).build(), ) - with patch('time.sleep', return_value=None): + with patch("time.sleep", return_value=None): output = read_stream("attribution_report_performance_campaign", SyncMode.full_refresh, self._config) assert len(output.records) == 0 @@ -340,14 +352,16 @@ def test_given_one_page_when_read_performance_campaign_then_return_records(self, self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), ).build(), - AttributionReportResponseBuilder.performance_campaign_response().with_record(AttributionReportRecordBuilder.performance_campaign_record()).build() + AttributionReportResponseBuilder.performance_campaign_response() + .with_record(AttributionReportRecordBuilder.performance_campaign_record()) + .build(), ) output = read_stream("attribution_report_performance_campaign", SyncMode.full_refresh, self._config) assert len(output.records) == 1 - + @HttpMocker() def test_given_many_pages_when_read_performance_campaign_then_return_records(self, http_mocker): """ @@ -363,12 +377,12 @@ def test_given_many_pages_when_read_performance_campaign_then_return_records(sel self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), ).build(), - AttributionReportResponseBuilder.performance_campaign_response(CursorBasedPaginationStrategy()) \ - .with_record(AttributionReportRecordBuilder.performance_campaign_record()) \ - .with_pagination() \ - .build() + AttributionReportResponseBuilder.performance_campaign_response(CursorBasedPaginationStrategy()) + .with_record(AttributionReportRecordBuilder.performance_campaign_record()) + .with_pagination() + .build(), ) http_mocker.post( AttributionReportRequestBuilder.performance_campaign_endpoint( @@ -376,9 +390,13 @@ def test_given_many_pages_when_read_performance_campaign_then_return_records(sel self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() - ).with_cursor_field("next-page-token").build(), - AttributionReportResponseBuilder.performance_campaign_response().with_record(AttributionReportRecordBuilder.performance_campaign_record()).build() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), + ) + .with_cursor_field("next-page-token") + .build(), + AttributionReportResponseBuilder.performance_campaign_response() + .with_record(AttributionReportRecordBuilder.performance_campaign_record()) + .build(), ) output = read_stream("attribution_report_performance_campaign", SyncMode.full_refresh, self._config) @@ -401,17 +419,17 @@ def test_given_non_breaking_error_when_read_performance_creative_then_stream_is_ self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), ).build(), - ErrorResponseBuilder.non_breaking_error_response().with_record(non_breaking_error).with_status_code(400).build() + ErrorResponseBuilder.non_breaking_error_response().with_record(non_breaking_error).with_status_code(400).build(), ) output = read_stream("attribution_report_performance_creative", SyncMode.full_refresh, self._config) assert len(output.records) == 0 - warning_logs = get_log_messages_by_log_level(output.logs, LogLevel.WARN) - assert any([non_breaking_error.build().get("details") in worning for worning in warning_logs]) - + info_logs = get_log_messages_by_log_level(output.logs, LogLevel.INFO) + assert any([non_breaking_error.build().get("details") in info for info in info_logs]) + @HttpMocker() def test_given_breaking_error_when_read_performance_creative_then_stream_is_ignored(self, http_mocker): """ @@ -428,12 +446,12 @@ def test_given_breaking_error_when_read_performance_creative_then_stream_is_igno self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), ).build(), - ErrorResponseBuilder.breaking_error_response().with_record(breaking_error).with_status_code(500).build() + ErrorResponseBuilder.breaking_error_response().with_record(breaking_error).with_status_code(500).build(), ) - with patch('time.sleep', return_value=None): + with patch("time.sleep", return_value=None): output = read_stream("attribution_report_performance_creative", SyncMode.full_refresh, self._config) assert len(output.records) == 0 @@ -455,9 +473,11 @@ def test_given_one_page_when_read_performance_creative_then_return_records(self, self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), ).build(), - AttributionReportResponseBuilder.performance_creative_response().with_record(AttributionReportRecordBuilder.performance_creative_record()).build() + AttributionReportResponseBuilder.performance_creative_response() + .with_record(AttributionReportRecordBuilder.performance_creative_record()) + .build(), ) output = read_stream("attribution_report_performance_creative", SyncMode.full_refresh, self._config) @@ -478,12 +498,12 @@ def test_given_many_pages_when_read_performance_creative_then_return_records(sel self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), ).build(), - AttributionReportResponseBuilder.performance_creative_response(CursorBasedPaginationStrategy()) \ - .with_record(AttributionReportRecordBuilder.performance_creative_record()) \ - .with_pagination() \ - .build() + AttributionReportResponseBuilder.performance_creative_response(CursorBasedPaginationStrategy()) + .with_record(AttributionReportRecordBuilder.performance_creative_record()) + .with_pagination() + .build(), ) http_mocker.post( AttributionReportRequestBuilder.performance_creative_endpoint( @@ -491,9 +511,13 @@ def test_given_many_pages_when_read_performance_creative_then_return_records(sel self._config["access_token"], self._config["profiles"][0], start_date=_A_START_DATE.astimezone(ZoneInfo(profile_timezone)).date(), - end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date() - ).with_cursor_field("next-page-token").build(), - AttributionReportResponseBuilder.performance_creative_response().with_record(AttributionReportRecordBuilder.performance_creative_record()).build() + end_date=_NOW.astimezone(ZoneInfo(profile_timezone)).date(), + ) + .with_cursor_field("next-page-token") + .build(), + AttributionReportResponseBuilder.performance_creative_response() + .with_record(AttributionReportRecordBuilder.performance_creative_record()) + .build(), ) output = read_stream("attribution_report_performance_creative", SyncMode.full_refresh, self._config) diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/test_report_streams.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/test_report_streams.py index 2d377a047928..fe0d429ada68 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/test_report_streams.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/test_report_streams.py @@ -6,19 +6,18 @@ import pendulum import requests_mock +from source_amazon_ads.streams.report_streams import brands_report, display_report, products_report + +from airbyte_cdk.models import AirbyteStateBlob, SyncMode +from airbyte_cdk.models import Level as LogLevel from airbyte_cdk.test.mock_http import HttpMocker, HttpRequestMatcher -from airbyte_protocol.models import Level as LogLevel -from airbyte_protocol.models import SyncMode -from source_amazon_ads.streams.report_streams import brands_report, brands_video_report, display_report, products_report from .ad_requests import ( OAuthRequestBuilder, ProfilesRequestBuilder, ReportCheckStatusRequestBuilder, ReportDownloadRequestBuilder, - SponsoredBrandsReportRequestBuilder, SponsoredBrandsV3ReportRequestBuilder, - SponsoredBrandsVideoReportRequestBuilder, SponsoredDisplayReportRequestBuilder, SponsoredProductsReportRequestBuilder, ) @@ -51,12 +50,14 @@ def _given_oauth_and_profiles(self, http_mocker: HttpMocker, config: dict) -> No Authenticate and get profiles """ http_mocker.post( - OAuthRequestBuilder.oauth_endpoint(client_id=config["client_id"], client_secred=config["client_secret"], refresh_token=config["refresh_token"]).build(), - OAuthResponseBuilder.token_response().build() + OAuthRequestBuilder.oauth_endpoint( + client_id=config["client_id"], client_secred=config["client_secret"], refresh_token=config["refresh_token"] + ).build(), + OAuthResponseBuilder.token_response().build(), ) http_mocker.get( ProfilesRequestBuilder.profiles_endpoint(client_id=config["client_id"], client_access_token=config["access_token"]).build(), - ProfilesResponseBuilder.profiles_response().with_record(ProfilesRecordBuilder.profiles_record()).build() + ProfilesResponseBuilder.profiles_response().with_record(ProfilesRecordBuilder.profiles_record()).build(), ) @HttpMocker() @@ -74,133 +75,31 @@ def test_given_file_when_read_display_report_then_return_records(self, http_mock profile_timezone = ProfilesRecordBuilder.profiles_record().build().get("timezone") start_date = pendulum.today(tz=profile_timezone).date() - for report_type, metrics in display_report.METRICS_MAP.items(): - for tactic in display_report.TACTICS: - report_id = str(uuid.uuid4()) - http_mocker.post( - SponsoredDisplayReportRequestBuilder._init_report_endpoint( - self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_type, tactic, metrics, start_date - ).build(), - ReportInitResponseBuilder.report_init_response().with_record( - ReportInitResponseRecordBuilder.init_response_record().with_status("PENDING").with_id(report_id) - ).with_status_code(202).build() - ) - download_request_builder = ReportDownloadRequestBuilder.download_endpoint(report_id) - http_mocker.get( - ReportCheckStatusRequestBuilder.check_sponsored_display_report_status_endpoint( - self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_id - ).build(), - ReportCheckStatusResponseBuilder.check_status_response().with_record( - ReportCheckStatusRecordBuilder.status_record().with_status("COMPLETED").with_url(download_request_builder.url) - ).build() - ) - - # a workaround to pass compressed document to the mocked response - gzip_file_report_response = ReportDownloadResponseBuilder.download_report().with_record(ReportFileRecordBuilder.report_file_record()).build() - request_matcher = HttpRequestMatcher(download_request_builder.build(), minimum_number_of_expected_match=1) - http_mocker._matchers.append(request_matcher) - - http_mocker._mocker.get( - requests_mock.ANY, - additional_matcher=http_mocker._matches_wrapper(request_matcher), - response_list=[{"content": gzip_file_report_response.body, "status_code": gzip_file_report_response.status_code}], - ) - - output = read_stream("sponsored_display_report_stream", SyncMode.full_refresh, self._config) - assert len(output.records) == 10 - - @HttpMocker() - def test_given_file_when_read_products_report_then_return_records(self, http_mocker): - """ - Check products report stream: normal stream read flow. - In this test we prepare http mocker to handle all report types based on metrics defined for the report stream - as well as workaround to handle gzipped file content. - Request structure: - 1. Request report for start processing - 2. Check status and get a download link - 3. Download report file using the link - """ - self._given_oauth_and_profiles(http_mocker, self._config) - - profile_timezone = ProfilesRecordBuilder.profiles_record().build().get("timezone") - start_date = pendulum.today(tz=profile_timezone).date() - - for report_type, metrics in products_report.METRICS_MAP.items(): + for report_type, metrics in display_report.METRICS_MAP_V3.items(): report_id = str(uuid.uuid4()) http_mocker.post( - SponsoredProductsReportRequestBuilder._init_report_endpoint( + SponsoredDisplayReportRequestBuilder._init_report_endpoint( self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_type, metrics, start_date ).build(), - ReportInitResponseBuilder.report_init_response().with_record( - ReportInitResponseRecordBuilder.init_response_record().with_status("PENDING").with_id(report_id) - ).with_status_code(200).build() + ReportInitResponseBuilder.report_init_response() + .with_record(ReportInitResponseRecordBuilder.init_response_record().with_status("PENDING").with_id(report_id)) + .with_status_code(200) + .build(), ) download_request_builder = ReportDownloadRequestBuilder.download_endpoint(report_id) http_mocker.get( - ReportCheckStatusRequestBuilder.check_sponsored_products_report_status_endpoint( + ReportCheckStatusRequestBuilder.check_sponsored_display_report_status_endpoint( self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_id ).build(), - ReportCheckStatusResponseBuilder.check_status_response().with_record( - ReportCheckStatusRecordBuilder.status_record().with_status("COMPLETED").with_url(download_request_builder.url) - ).build() + ReportCheckStatusResponseBuilder.check_status_response() + .with_record(ReportCheckStatusRecordBuilder.status_record().with_status("COMPLETED").with_url(download_request_builder.url)) + .build(), ) # a workaround to pass compressed document to the mocked response - gzip_file_report_response = ReportDownloadResponseBuilder.download_report().with_record( - ReportFileRecordBuilder.report_file_record() - ).build() - request_matcher = HttpRequestMatcher(download_request_builder.build(), minimum_number_of_expected_match=1) - http_mocker._matchers.append(request_matcher) - - http_mocker._mocker.get( - requests_mock.ANY, - additional_matcher=http_mocker._matches_wrapper(request_matcher), - response_list=[{"content": gzip_file_report_response.body, "status_code": gzip_file_report_response.status_code}], - ) - - output = read_stream("sponsored_products_report_stream", SyncMode.full_refresh, self._config) - assert len(output.records) == 7 - - @HttpMocker() - def test_given_file_when_read_brands_video_report_then_return_records(self, http_mocker): - """ - Check brands video report stream: normal stream read flow. - In this test we prepare http mocker to handle all report types based on metrics defined for the report stream - as well as workaround to handle gzipped file content - Request structure: - 1. Request report for start processing - 2. Check status and get a download link - 3. Download report file using the link - """ - self._given_oauth_and_profiles(http_mocker, self._config) - - profile_timezone = ProfilesRecordBuilder.profiles_record().build().get("timezone") - start_date = pendulum.today(tz=profile_timezone).date() - - for report_type, metrics in brands_video_report.METRICS_MAP.items(): - report_id = str(uuid.uuid4()) - http_mocker.post( - SponsoredBrandsVideoReportRequestBuilder._init_report_endpoint( - self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_type, metrics, start_date - ).build(), - ReportInitResponseBuilder.report_init_response().with_record( - ReportInitResponseRecordBuilder.init_response_record().with_status("PENDING").with_id(report_id) - ).with_status_code(202).build() - ) - download_request_builder = ReportDownloadRequestBuilder.download_endpoint(report_id) - http_mocker.get( - ReportCheckStatusRequestBuilder.check_sponsored_brands_video_report_status_endpoint( - self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_id - ).build(), - ReportCheckStatusResponseBuilder.check_status_response().with_record( - ReportCheckStatusRecordBuilder.status_record().with_status("COMPLETED").with_url(download_request_builder.url) - ).build() + gzip_file_report_response = ( + ReportDownloadResponseBuilder.download_report().with_record(ReportFileRecordBuilder.report_file_record()).build() ) - - # a workaround to pass compressed document to the mocked response - gzip_file_report_response = ReportDownloadResponseBuilder.download_report().with_record( - ReportFileRecordBuilder.report_file_record() - ).build() request_matcher = HttpRequestMatcher(download_request_builder.build(), minimum_number_of_expected_match=1) http_mocker._matchers.append(request_matcher) @@ -210,13 +109,13 @@ def test_given_file_when_read_brands_video_report_then_return_records(self, http response_list=[{"content": gzip_file_report_response.body, "status_code": gzip_file_report_response.status_code}], ) - output = read_stream("sponsored_brands_video_report_stream", SyncMode.full_refresh, self._config) - assert len(output.records) == 3 + output = read_stream("sponsored_display_report_stream", SyncMode.full_refresh, self._config) + assert len(output.records) == 5 @HttpMocker() - def test_given_file_when_read_brands_report_then_return_records(self, http_mocker): + def test_given_file_when_read_products_report_then_return_records(self, http_mocker): """ - Check brands report stream: normal stream read flow. + Check products report stream: normal stream read flow. In this test we prepare http mocker to handle all report types based on metrics defined for the report stream as well as workaround to handle gzipped file content. Request structure: @@ -229,30 +128,31 @@ def test_given_file_when_read_brands_report_then_return_records(self, http_mocke profile_timezone = ProfilesRecordBuilder.profiles_record().build().get("timezone") start_date = pendulum.today(tz=profile_timezone).date() - for report_type, metrics in brands_report.METRICS_MAP.items(): + for report_type, metrics in products_report.METRICS_MAP.items(): report_id = str(uuid.uuid4()) http_mocker.post( - SponsoredBrandsReportRequestBuilder._init_report_endpoint( + SponsoredProductsReportRequestBuilder._init_report_endpoint( self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_type, metrics, start_date ).build(), - ReportInitResponseBuilder.report_init_response().with_record( - ReportInitResponseRecordBuilder.init_response_record().with_status("PENDING").with_id(report_id) - ).with_status_code(202).build() + ReportInitResponseBuilder.report_init_response() + .with_record(ReportInitResponseRecordBuilder.init_response_record().with_status("PENDING").with_id(report_id)) + .with_status_code(200) + .build(), ) download_request_builder = ReportDownloadRequestBuilder.download_endpoint(report_id) http_mocker.get( - ReportCheckStatusRequestBuilder.check_sponsored_brands_report_status_endpoint( + ReportCheckStatusRequestBuilder.check_sponsored_products_report_status_endpoint( self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_id ).build(), - ReportCheckStatusResponseBuilder.check_status_response().with_record( - ReportCheckStatusRecordBuilder.status_record().with_status("COMPLETED").with_url(download_request_builder.url) - ).build() + ReportCheckStatusResponseBuilder.check_status_response() + .with_record(ReportCheckStatusRecordBuilder.status_record().with_status("COMPLETED").with_url(download_request_builder.url)) + .build(), ) # a workaround to pass compressed document to the mocked response - gzip_file_report_response = ReportDownloadResponseBuilder.download_report().with_record( - ReportFileRecordBuilder.report_file_record() - ).build() + gzip_file_report_response = ( + ReportDownloadResponseBuilder.download_report().with_record(ReportFileRecordBuilder.report_file_record()).build() + ) request_matcher = HttpRequestMatcher(download_request_builder.build(), minimum_number_of_expected_match=1) http_mocker._matchers.append(request_matcher) @@ -262,8 +162,8 @@ def test_given_file_when_read_brands_report_then_return_records(self, http_mocke response_list=[{"content": gzip_file_report_response.body, "status_code": gzip_file_report_response.status_code}], ) - output = read_stream("sponsored_brands_report_stream", SyncMode.full_refresh, self._config) - assert len(output.records) == 3 + output = read_stream("sponsored_products_report_stream", SyncMode.full_refresh, self._config) + assert len(output.records) == 7 @HttpMocker() def test_given_file_when_read_brands_v3_report_then_return_records(self, http_mocker): @@ -287,24 +187,25 @@ def test_given_file_when_read_brands_v3_report_then_return_records(self, http_mo SponsoredBrandsV3ReportRequestBuilder._init_report_endpoint( self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_type, metrics, start_date ).build(), - ReportInitResponseBuilder.report_init_response().with_record( - ReportInitResponseRecordBuilder.init_response_record().with_status("PENDING").with_id(report_id) - ).with_status_code(200).build() + ReportInitResponseBuilder.report_init_response() + .with_record(ReportInitResponseRecordBuilder.init_response_record().with_status("PENDING").with_id(report_id)) + .with_status_code(200) + .build(), ) download_request_builder = ReportDownloadRequestBuilder.download_endpoint(report_id) http_mocker.get( ReportCheckStatusRequestBuilder.check_sponsored_brands_v3_report_status_endpoint( self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_id ).build(), - ReportCheckStatusResponseBuilder.check_status_response().with_record( - ReportCheckStatusRecordBuilder.status_record().with_status("COMPLETED").with_url(download_request_builder.url) - ).build() + ReportCheckStatusResponseBuilder.check_status_response() + .with_record(ReportCheckStatusRecordBuilder.status_record().with_status("COMPLETED").with_url(download_request_builder.url)) + .build(), ) # a workaround to pass compressed document to the mocked response - gzip_file_report_response = ReportDownloadResponseBuilder.download_report().with_record( - ReportFileRecordBuilder.report_file_record() - ).build() + gzip_file_report_response = ( + ReportDownloadResponseBuilder.download_report().with_record(ReportFileRecordBuilder.report_file_record()).build() + ) request_matcher = HttpRequestMatcher(download_request_builder.build(), minimum_number_of_expected_match=1) http_mocker._matchers.append(request_matcher) @@ -315,6 +216,7 @@ def test_given_file_when_read_brands_v3_report_then_return_records(self, http_mo ) output = read_stream("sponsored_brands_v3_report_stream", SyncMode.full_refresh, self._config) + assert output.most_recent_state.stream_state == AirbyteStateBlob({"1": {"reportDate": start_date.format("YYYY-MM-DD")}}) assert len(output.records) == 1 @HttpMocker() @@ -324,7 +226,6 @@ def test_given_known_error_when_read_brands_v3_report_then_skip_report(self, htt When error of this kind happen, we warn and then keep syncing another reports if possible. In this test all report init requests are failed with known error and skipped """ - self._given_oauth_and_profiles(http_mocker, self._config) ERRORS = [ (400, "KDP authors do not have access to Sponsored Brands functionality"), @@ -333,6 +234,7 @@ def test_given_known_error_when_read_brands_v3_report_then_skip_report(self, htt ] for status_code, msg in ERRORS: + self._given_oauth_and_profiles(http_mocker, self._config) profile_timezone = ProfilesRecordBuilder.profiles_record().build().get("timezone") start_date = pendulum.today(tz=profile_timezone).date() non_breaking_error = ErrorRecordBuilder.non_breaking_error().with_error_message(msg) @@ -340,9 +242,17 @@ def test_given_known_error_when_read_brands_v3_report_then_skip_report(self, htt for report_type, metrics in brands_report.METRICS_MAP_V3.items(): http_mocker.post( SponsoredBrandsV3ReportRequestBuilder._init_report_endpoint( - self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_type, metrics, start_date + self._config["client_id"], + self._config["access_token"], + self._config["profiles"][0], + report_type, + metrics, + start_date, ).build(), - ErrorResponseBuilder.non_breaking_error_response().with_record(non_breaking_error).with_status_code(status_code).build(), + ErrorResponseBuilder.non_breaking_error_response() + .with_record(non_breaking_error) + .with_status_code(status_code) + .build(), ) output = read_stream("sponsored_brands_v3_report_stream", SyncMode.full_refresh, self._config) @@ -354,79 +264,53 @@ def test_given_known_error_when_read_brands_v3_report_then_skip_report(self, htt f"SponsoredBrandsV3ReportStream for 1 profile: {json.dumps(non_breaking_error.build())}" ) assert any([expected_warning_log in warn for warn in warning_logs]) + http_mocker.clear_all_matchers() @HttpMocker() def test_given_known_error_when_read_display_report_then_partially_skip_records(self, http_mocker): """ - Check brands v3 stream: non-breaking errors are ignored. + Check display v3 stream: non-breaking errors are ignored. When error of this kind happen, we warn and then keep syncing another reports if possible. In this test half of report init requests are failed with known error and skipped while another half of reports successfully processed """ self._given_oauth_and_profiles(http_mocker, self._config) - ERRORS = [ - (400, "Tactic T00030 is not supported for report API in marketplace ABC00030."), - ] - - for status_code, msg in ERRORS: - profile_timezone = ProfilesRecordBuilder.profiles_record().build().get("timezone") - start_date = pendulum.today(tz=profile_timezone).date() - non_breaking_error = ErrorRecordBuilder.non_breaking_error().with_error_message(msg) - - for report_type, metrics in display_report.METRICS_MAP.items(): - report_id = str(uuid.uuid4()) - tactic = display_report.TACTICS[0] - http_mocker.post( - SponsoredDisplayReportRequestBuilder._init_report_endpoint( - self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_type, tactic, metrics, start_date - ).build(), - ReportInitResponseBuilder.report_init_response().with_record( - ReportInitResponseRecordBuilder.init_response_record().with_status("PENDING").with_id(report_id) - ).with_status_code(202).build() - ) - download_request_builder = ReportDownloadRequestBuilder.download_endpoint(report_id) - http_mocker.get( - ReportCheckStatusRequestBuilder.check_sponsored_display_report_status_endpoint( - self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_id - ).build(), - ReportCheckStatusResponseBuilder.check_status_response().with_record( - ReportCheckStatusRecordBuilder.status_record().with_status("COMPLETED").with_url(download_request_builder.url) - ).build() - ) + profile_timezone = ProfilesRecordBuilder.profiles_record().build().get("timezone") + start_date = pendulum.today(tz=profile_timezone).date() - # a workaround to pass compressed document to the mocked response - gzip_file_report_response = ReportDownloadResponseBuilder.download_report().with_record(ReportFileRecordBuilder.report_file_record()).build() - request_matcher = HttpRequestMatcher(download_request_builder.build(), minimum_number_of_expected_match=1) - http_mocker._matchers.append(request_matcher) + for report_type, metrics in display_report.METRICS_MAP_V3.items(): + report_id = str(uuid.uuid4()) + http_mocker.post( + SponsoredDisplayReportRequestBuilder._init_report_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_type, metrics, start_date + ).build(), + ReportInitResponseBuilder.report_init_response() + .with_record(ReportInitResponseRecordBuilder.init_response_record().with_status("PENDING").with_id(report_id)) + .with_status_code(200) + .build(), + ) + download_request_builder = ReportDownloadRequestBuilder.download_endpoint(report_id) + http_mocker.get( + ReportCheckStatusRequestBuilder.check_sponsored_display_report_status_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_id + ).build(), + ReportCheckStatusResponseBuilder.check_status_response() + .with_record(ReportCheckStatusRecordBuilder.status_record().with_status("COMPLETED").with_url(download_request_builder.url)) + .build(), + ) - http_mocker._mocker.get( - requests_mock.ANY, - additional_matcher=http_mocker._matches_wrapper(request_matcher), - response_list=[{"content": gzip_file_report_response.body, "status_code": gzip_file_report_response.status_code}], - ) + # a workaround to pass compressed document to the mocked response + gzip_file_report_response = ( + ReportDownloadResponseBuilder.download_report().with_record(ReportFileRecordBuilder.report_file_record()).build() + ) + request_matcher = HttpRequestMatcher(download_request_builder.build(), minimum_number_of_expected_match=1) + http_mocker._matchers.append(request_matcher) - for report_type, metrics in display_report.METRICS_MAP.items(): - tactic = display_report.TACTICS[1] - http_mocker.post( - SponsoredDisplayReportRequestBuilder._init_report_endpoint( - self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_type, tactic, metrics, start_date - ).build(), - ErrorResponseBuilder.non_breaking_error_response().with_record(non_breaking_error).with_status_code(status_code).build(), - ) + http_mocker._mocker.get( + requests_mock.ANY, + additional_matcher=http_mocker._matches_wrapper(request_matcher), + response_list=[{"content": gzip_file_report_response.body, "status_code": gzip_file_report_response.status_code}], + ) - output = read_stream("sponsored_display_report_stream", SyncMode.full_refresh, self._config) - assert len(output.records) == 5 - - expected_warning_logs = [ - ( - f"Unexpected HTTP status code {status_code} when registering {report_type}, " - f"SponsoredDisplayReportStream for 1 profile: {json.dumps(non_breaking_error.build())}" - ) for report_type in display_report.METRICS_MAP.keys() - ] - for expected_warning_log in expected_warning_logs: - assert any( - [ - expected_warning_log in warn - for warn in get_log_messages_by_log_level(output.logs, LogLevel.WARN) - ] - ) + output = read_stream("sponsored_display_report_stream", SyncMode.full_refresh, self._config) + assert len(output.records) == 5 diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/test_sponsored_streams.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/test_sponsored_streams.py index e5096bcb1351..96874e60649b 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/test_sponsored_streams.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/test_sponsored_streams.py @@ -4,6 +4,8 @@ from unittest import TestCase from unittest.mock import patch +from airbyte_cdk.models import Level as LogLevel +from airbyte_cdk.models import SyncMode from airbyte_cdk.test.mock_http import HttpMocker from airbyte_cdk.test.mock_http.response_builder import ( FieldPath, @@ -15,8 +17,6 @@ create_response_builder, find_template, ) -from airbyte_protocol.models import Level as LogLevel -from airbyte_protocol.models import SyncMode from .ad_requests import OAuthRequestBuilder, ProfilesRequestBuilder, SponsoredBrandsRequestBuilder from .ad_responses import ErrorResponseBuilder, OAuthResponseBuilder, ProfilesResponseBuilder, SponsoredBrandsResponseBuilder @@ -25,24 +25,19 @@ from .config import ConfigBuilder from .utils import get_log_messages_by_log_level, read_stream -_DEFAULT_REQUEST_BODY = json.dumps({ - "maxResults": 100 -}) + +_DEFAULT_REQUEST_BODY = json.dumps({"maxResults": 100}) + def _a_record(stream_name: str, data_field: str, record_id_path: str) -> RecordBuilder: return create_record_builder( - find_template(stream_name, __file__), - FieldPath(data_field), - record_id_path=FieldPath(record_id_path), - record_cursor_path=None + find_template(stream_name, __file__), FieldPath(data_field), record_id_path=FieldPath(record_id_path), record_cursor_path=None ) + def _a_response(stream_name: str, data_field: str, pagination_strategy: PaginationStrategy = None) -> HttpResponseBuilder: - return create_response_builder( - find_template(stream_name, __file__), - FieldPath(data_field), - pagination_strategy=pagination_strategy - ) + return create_response_builder(find_template(stream_name, __file__), FieldPath(data_field), pagination_strategy=pagination_strategy) + class TestSponsoredBrandsStreamsFullRefresh(TestCase): @property @@ -54,12 +49,14 @@ def _given_oauth_and_profiles(self, http_mocker: HttpMocker, config: dict) -> No Authenticate and get profiles """ http_mocker.post( - OAuthRequestBuilder.oauth_endpoint(client_id=config["client_id"], client_secred=config["client_secret"], refresh_token=config["refresh_token"]).build(), - OAuthResponseBuilder.token_response().build() + OAuthRequestBuilder.oauth_endpoint( + client_id=config["client_id"], client_secred=config["client_secret"], refresh_token=config["refresh_token"] + ).build(), + OAuthResponseBuilder.token_response().build(), ) http_mocker.get( ProfilesRequestBuilder.profiles_endpoint(client_id=config["client_id"], client_access_token=config["access_token"]).build(), - ProfilesResponseBuilder.profiles_response().with_record(ProfilesRecordBuilder.profiles_record()).build() + ProfilesResponseBuilder.profiles_response().with_record(ProfilesRecordBuilder.profiles_record()).build(), ) @HttpMocker() @@ -72,14 +69,18 @@ def test_given_non_breaking_error_when_read_ad_groups_then_stream_is_ignored(sel non_breaking_error = ErrorRecordBuilder.non_breaking_error() http_mocker.post( - SponsoredBrandsRequestBuilder.ad_groups_endpoint(self._config["client_id"], self._config["access_token"], self._config["profiles"][0]).with_request_body(_DEFAULT_REQUEST_BODY).build(), - ErrorResponseBuilder.non_breaking_error_response().with_record(non_breaking_error).with_status_code(400).build() + SponsoredBrandsRequestBuilder.ad_groups_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0] + ) + .with_request_body(_DEFAULT_REQUEST_BODY) + .build(), + ErrorResponseBuilder.non_breaking_error_response().with_record(non_breaking_error).with_status_code(400).build(), ) output = read_stream("sponsored_brands_ad_groups", SyncMode.full_refresh, self._config) assert len(output.records) == 0 - warning_logs = get_log_messages_by_log_level(output.logs, LogLevel.WARN) - assert any([non_breaking_error.build().get("details") in worning for worning in warning_logs]) + info_logs = get_log_messages_by_log_level(output.logs, LogLevel.INFO) + assert any([non_breaking_error.build().get("details") in info for info in info_logs]) @HttpMocker() def test_given_breaking_error_when_read_ad_groups_then_stream_stop_syncing(self, http_mocker: HttpMocker): @@ -90,10 +91,14 @@ def test_given_breaking_error_when_read_ad_groups_then_stream_stop_syncing(self, breaking_error = ErrorRecordBuilder.breaking_error() http_mocker.post( - SponsoredBrandsRequestBuilder.ad_groups_endpoint(self._config["client_id"], self._config["access_token"], self._config["profiles"][0]).with_request_body(_DEFAULT_REQUEST_BODY).build(), - ErrorResponseBuilder.breaking_error_response().with_record(breaking_error).with_status_code(500).build() + SponsoredBrandsRequestBuilder.ad_groups_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0] + ) + .with_request_body(_DEFAULT_REQUEST_BODY) + .build(), + ErrorResponseBuilder.breaking_error_response().with_record(breaking_error).with_status_code(500).build(), ) - with patch('time.sleep', return_value=None): + with patch("time.sleep", return_value=None): output = read_stream("sponsored_brands_ad_groups", SyncMode.full_refresh, self._config) assert len(output.records) == 0 @@ -112,8 +117,12 @@ def test_given_one_page_when_read_ad_groups_then_return_records(self, http_mocke self._given_oauth_and_profiles(http_mocker, self._config) http_mocker.post( - SponsoredBrandsRequestBuilder.ad_groups_endpoint(self._config["client_id"], self._config["access_token"], self._config["profiles"][0]).with_request_body(_DEFAULT_REQUEST_BODY).build(), - _a_response(stream_name, data_field, None).with_record(_a_record(stream_name, data_field, record_id_path)).build() + SponsoredBrandsRequestBuilder.ad_groups_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0] + ) + .with_request_body(_DEFAULT_REQUEST_BODY) + .build(), + _a_response(stream_name, data_field, None).with_record(_a_record(stream_name, data_field, record_id_path)).build(), ) output = read_stream("sponsored_brands_ad_groups", SyncMode.full_refresh, self._config) @@ -131,20 +140,30 @@ def test_given_many_pages_when_read_ad_groups_then_return_records(self, http_moc record_id_path = "adGroupId" pagination_strategy = SponsoredCursorBasedPaginationStrategy() - paginated_request_body = json.dumps({ - "maxResults": 100, - "nextToken": "next-page-token" - }) + paginated_request_body = json.dumps({"nextToken": "next-page-token", "maxResults": 100}) self._given_oauth_and_profiles(http_mocker, self._config) http_mocker.post( - SponsoredBrandsRequestBuilder.ad_groups_endpoint(self._config["client_id"], self._config["access_token"], self._config["profiles"][0]).with_request_body(_DEFAULT_REQUEST_BODY).build(), - _a_response(stream_name, data_field, pagination_strategy).with_record(_a_record(stream_name, data_field, record_id_path)).with_pagination().build() + SponsoredBrandsRequestBuilder.ad_groups_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0] + ) + .with_request_body(_DEFAULT_REQUEST_BODY) + .build(), + _a_response(stream_name, data_field, pagination_strategy) + .with_record(_a_record(stream_name, data_field, record_id_path)) + .with_pagination() + .build(), ) http_mocker.post( - SponsoredBrandsRequestBuilder.ad_groups_endpoint(self._config["client_id"], self._config["access_token"], self._config["profiles"][0]).with_request_body(paginated_request_body).build(), - _a_response(stream_name, data_field, pagination_strategy).with_record(_a_record(stream_name, data_field, record_id_path)).build() + SponsoredBrandsRequestBuilder.ad_groups_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0] + ) + .with_request_body(paginated_request_body) + .build(), + _a_response(stream_name, data_field, pagination_strategy) + .with_record(_a_record(stream_name, data_field, record_id_path)) + .build(), ) output = read_stream("sponsored_brands_ad_groups", SyncMode.full_refresh, self._config) @@ -160,14 +179,18 @@ def test_given_non_breaking_error_when_read_campaigns_then_stream_is_ignored(sel non_breaking_error = ErrorRecordBuilder.non_breaking_error() http_mocker.post( - SponsoredBrandsRequestBuilder.campaigns_endpoint(self._config["client_id"], self._config["access_token"], self._config["profiles"][0]).with_request_body(_DEFAULT_REQUEST_BODY).build(), - ErrorResponseBuilder.non_breaking_error_response().with_record(non_breaking_error).with_status_code(400).build() + SponsoredBrandsRequestBuilder.campaigns_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0] + ) + .with_request_body(_DEFAULT_REQUEST_BODY) + .build(), + ErrorResponseBuilder.non_breaking_error_response().with_record(non_breaking_error).with_status_code(400).build(), ) output = read_stream("sponsored_brands_campaigns", SyncMode.full_refresh, self._config) assert len(output.records) == 0 - warning_logs = get_log_messages_by_log_level(output.logs, LogLevel.WARN) - assert any([non_breaking_error.build().get("details") in worning for worning in warning_logs]) + info_logs = get_log_messages_by_log_level(output.logs, LogLevel.INFO) + assert any([non_breaking_error.build().get("details") in info for info in info_logs]) @HttpMocker() def test_given_breaking_error_when_read_campaigns_then_stream_stop_syncing(self, http_mocker: HttpMocker): @@ -178,10 +201,14 @@ def test_given_breaking_error_when_read_campaigns_then_stream_stop_syncing(self, breaking_error = ErrorRecordBuilder.breaking_error() http_mocker.post( - SponsoredBrandsRequestBuilder.campaigns_endpoint(self._config["client_id"], self._config["access_token"], self._config["profiles"][0]).with_request_body(_DEFAULT_REQUEST_BODY).build(), - ErrorResponseBuilder.breaking_error_response().with_record(breaking_error).with_status_code(500).build() + SponsoredBrandsRequestBuilder.campaigns_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0] + ) + .with_request_body(_DEFAULT_REQUEST_BODY) + .build(), + ErrorResponseBuilder.breaking_error_response().with_record(breaking_error).with_status_code(500).build(), ) - with patch('time.sleep', return_value=None): + with patch("time.sleep", return_value=None): output = read_stream("sponsored_brands_campaigns", SyncMode.full_refresh, self._config) assert len(output.records) == 0 @@ -200,8 +227,12 @@ def test_given_one_page_when_read_campaigns_then_return_records(self, http_mocke record_id_path = "campaignId" http_mocker.post( - SponsoredBrandsRequestBuilder.campaigns_endpoint(self._config["client_id"], self._config["access_token"], self._config["profiles"][0]).with_request_body(_DEFAULT_REQUEST_BODY).build(), - _a_response(stream_name, data_field, None).with_record(_a_record(stream_name, data_field, record_id_path)).build() + SponsoredBrandsRequestBuilder.campaigns_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0] + ) + .with_request_body(_DEFAULT_REQUEST_BODY) + .build(), + _a_response(stream_name, data_field, None).with_record(_a_record(stream_name, data_field, record_id_path)).build(), ) output = read_stream("sponsored_brands_campaigns", SyncMode.full_refresh, self._config) @@ -218,20 +249,30 @@ def test_given_many_pages_when_read_campaigns_then_return_records(self, http_moc record_id_path = "campaignId" pagination_strategy = SponsoredCursorBasedPaginationStrategy() - paginated_request_body = json.dumps({ - "maxResults": 100, - "nextToken": "next-page-token" - }) + paginated_request_body = json.dumps({"nextToken": "next-page-token", "maxResults": 100}) self._given_oauth_and_profiles(http_mocker, self._config) http_mocker.post( - SponsoredBrandsRequestBuilder.campaigns_endpoint(self._config["client_id"], self._config["access_token"], self._config["profiles"][0]).with_request_body(_DEFAULT_REQUEST_BODY).build(), - _a_response(stream_name, data_field, pagination_strategy).with_record(_a_record(stream_name, data_field, record_id_path)).with_pagination().build() + SponsoredBrandsRequestBuilder.campaigns_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0] + ) + .with_request_body(_DEFAULT_REQUEST_BODY) + .build(), + _a_response(stream_name, data_field, pagination_strategy) + .with_record(_a_record(stream_name, data_field, record_id_path)) + .with_pagination() + .build(), ) http_mocker.post( - SponsoredBrandsRequestBuilder.campaigns_endpoint(self._config["client_id"], self._config["access_token"], self._config["profiles"][0]).with_request_body(paginated_request_body).build(), - _a_response(stream_name, data_field, pagination_strategy).with_record(_a_record(stream_name, data_field, record_id_path)).build() + SponsoredBrandsRequestBuilder.campaigns_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0] + ) + .with_request_body(paginated_request_body) + .build(), + _a_response(stream_name, data_field, pagination_strategy) + .with_record(_a_record(stream_name, data_field, record_id_path)) + .build(), ) output = read_stream("sponsored_brands_campaigns", SyncMode.full_refresh, self._config) @@ -247,14 +288,16 @@ def test_given_non_breaking_error_when_read_keywords_then_stream_is_ignored(self non_breaking_error = ErrorRecordBuilder.non_breaking_error() http_mocker.get( - SponsoredBrandsRequestBuilder.keywords_endpoint(self._config["client_id"], self._config["access_token"], self._config["profiles"][0], limit=100).build(), - ErrorResponseBuilder.non_breaking_error_response().with_record(non_breaking_error).with_status_code(400).build() + SponsoredBrandsRequestBuilder.keywords_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0], limit=100 + ).build(), + ErrorResponseBuilder.non_breaking_error_response().with_record(non_breaking_error).with_status_code(400).build(), ) output = read_stream("sponsored_brands_keywords", SyncMode.full_refresh, self._config) assert len(output.records) == 0 - warning_logs = get_log_messages_by_log_level(output.logs, LogLevel.WARN) - assert any([non_breaking_error.build().get("details") in worning for worning in warning_logs]) + info_logs = get_log_messages_by_log_level(output.logs, LogLevel.INFO) + assert any([non_breaking_error.build().get("details") in info for info in info_logs]) @HttpMocker() def test_given_breaking_error_when_read_keywords_then_stream_stop_syncing(self, http_mocker: HttpMocker): @@ -265,10 +308,12 @@ def test_given_breaking_error_when_read_keywords_then_stream_stop_syncing(self, breaking_error = ErrorRecordBuilder.breaking_error() http_mocker.get( - SponsoredBrandsRequestBuilder.keywords_endpoint(self._config["client_id"], self._config["access_token"], self._config["profiles"][0], limit=100).build(), - ErrorResponseBuilder.breaking_error_response().with_record(breaking_error).with_status_code(500).build() + SponsoredBrandsRequestBuilder.keywords_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0], limit=100 + ).build(), + ErrorResponseBuilder.breaking_error_response().with_record(breaking_error).with_status_code(500).build(), ) - with patch('time.sleep', return_value=None): + with patch("time.sleep", return_value=None): output = read_stream("sponsored_brands_keywords", SyncMode.full_refresh, self._config) assert len(output.records) == 0 @@ -283,8 +328,10 @@ def test_given_one_page_when_read_keywords_then_return_records(self, http_mocker self._given_oauth_and_profiles(http_mocker, self._config) http_mocker.get( - SponsoredBrandsRequestBuilder.keywords_endpoint(self._config["client_id"], self._config["access_token"], self._config["profiles"][0], limit=100).build(), - SponsoredBrandsResponseBuilder.keywords_response().with_record(SponsoredBrandsRecordBuilder.keywords_record()).build() + SponsoredBrandsRequestBuilder.keywords_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0], limit=100 + ).build(), + SponsoredBrandsResponseBuilder.keywords_response().with_record(SponsoredBrandsRecordBuilder.keywords_record()).build(), ) output = read_stream("sponsored_brands_keywords", SyncMode.full_refresh, self._config) @@ -298,16 +345,28 @@ def test_given_many_pages_when_read_keywords_then_return_records(self, http_mock self._given_oauth_and_profiles(http_mocker, self._config) http_mocker.get( - SponsoredBrandsRequestBuilder.keywords_endpoint(self._config["client_id"], self._config["access_token"], self._config["profiles"][0], limit=100).build(), - SponsoredBrandsResponseBuilder.keywords_response(CountBasedPaginationStrategy()).with_record(SponsoredBrandsRecordBuilder.keywords_record()).with_pagination().build() + SponsoredBrandsRequestBuilder.keywords_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0], limit=100 + ).build(), + SponsoredBrandsResponseBuilder.keywords_response(CountBasedPaginationStrategy()) + .with_record(SponsoredBrandsRecordBuilder.keywords_record()) + .with_pagination() + .build(), ) http_mocker.get( - SponsoredBrandsRequestBuilder.keywords_endpoint(self._config["client_id"], self._config["access_token"], self._config["profiles"][0], limit=100, start_index=100).build(), - SponsoredBrandsResponseBuilder.keywords_response(CountBasedPaginationStrategy()).with_record(SponsoredBrandsRecordBuilder.keywords_record()).with_pagination().build() + SponsoredBrandsRequestBuilder.keywords_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0], limit=100, start_index=100 + ).build(), + SponsoredBrandsResponseBuilder.keywords_response(CountBasedPaginationStrategy()) + .with_record(SponsoredBrandsRecordBuilder.keywords_record()) + .with_pagination() + .build(), ) http_mocker.get( - SponsoredBrandsRequestBuilder.keywords_endpoint(self._config["client_id"], self._config["access_token"], self._config["profiles"][0], limit=100, start_index=200).build(), - SponsoredBrandsResponseBuilder.keywords_response().with_record(SponsoredBrandsRecordBuilder.keywords_record()).build() + SponsoredBrandsRequestBuilder.keywords_endpoint( + self._config["client_id"], self._config["access_token"], self._config["profiles"][0], limit=100, start_index=200 + ).build(), + SponsoredBrandsResponseBuilder.keywords_response().with_record(SponsoredBrandsRecordBuilder.keywords_record()).build(), ) output = read_stream("sponsored_brands_keywords", SyncMode.full_refresh, self._config) diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/utils.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/utils.py index fafd5b37f785..3e91740f9f3f 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/utils.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/integrations/utils.py @@ -3,24 +3,19 @@ import operator from typing import Any, Dict, List, Optional -from airbyte_cdk.models import AirbyteMessage +from source_amazon_ads import SourceAmazonAds + +from airbyte_cdk.models import AirbyteMessage, SyncMode from airbyte_cdk.models import Level as LogLevel from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read -from airbyte_protocol.models import SyncMode -from source_amazon_ads import SourceAmazonAds -from source_amazon_ads.declarative_source_adapter import DeclarativeSourceAdapter def read_stream( - stream_name: str, - sync_mode: SyncMode, - config: Dict[str, Any], - state: Optional[Dict[str, Any]] = None, - expecting_exception: bool = False + stream_name: str, sync_mode: SyncMode, config: Dict[str, Any], state: Optional[Dict[str, Any]] = None, expecting_exception: bool = False ) -> EntrypointOutput: catalog = CatalogBuilder().with_stream(stream_name, sync_mode).build() - return read(DeclarativeSourceAdapter(source=SourceAmazonAds()), config, catalog, state, expecting_exception) + return read(SourceAmazonAds(catalog=catalog, config=config, state=state), config, catalog, state, expecting_exception) def get_log_messages_by_log_level(logs: List[AirbyteMessage], log_level: LogLevel) -> List[str]: diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_attribution_report.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_attribution_report.py deleted file mode 100644 index 32203166e150..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_attribution_report.py +++ /dev/null @@ -1,159 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json - -import pendulum -import pytest -import requests -import responses -from airbyte_cdk.models import SyncMode -from freezegun import freeze_time -from jsonschema import validate -from source_amazon_ads import SourceAmazonAds -from source_amazon_ads.schemas.profile import AccountInfo, Profile -from source_amazon_ads.streams import AttributionReportProducts - -from .utils import read_full_refresh - - -def setup_responses( - profiles_response=None, - attribution_report_response=None, -): - responses.add( - responses.POST, - "https://api.amazon.com/auth/o2/token", - json={"access_token": "access_token", "expires_in": 10}, - ) - if profiles_response: - responses.add( - responses.GET, - "https://advertising-api.amazon.com/v2/profiles", - body=profiles_response, - ) - if attribution_report_response: - responses.add( - responses.POST, - "https://advertising-api.amazon.com/attribution/report", - body=attribution_report_response, - ) - - -def get_stream_by_name(streams, stream_name): - for stream in streams: - if stream.name == stream_name: - return stream - raise Exception(f"Expected stream {stream_name} not found") - - -@pytest.mark.parametrize( - ("stream_name", "report_type"), - [ - ("attribution_report_products", "PRODUCTS"), - ("attribution_report_performance_adgroup", "PERFORMANCE_ADGROUP"), - ("attribution_report_performance_campaign", "PERFORMANCE_CAMPAIGN"), - ("attribution_report_performance_creative", "PERFORMANCE_CREATIVE"), - ], -) -@responses.activate -def test_attribution_report_schema(config, profiles_response, attribution_report_response, stream_name, report_type): - # custom start date - config["start_date"] = "2022-09-03" - - setup_responses(profiles_response=profiles_response, attribution_report_response=attribution_report_response(report_type)) - - source = SourceAmazonAds() - streams = source.streams(config) - - profile_stream = get_stream_by_name(streams, "profiles") - attribution_report_stream = get_stream_by_name(streams, stream_name) - schema = attribution_report_stream.get_json_schema() - schema["additionalProperties"] = False - - profile_records = list(read_full_refresh(profile_stream)) - attribution_records = list(read_full_refresh(attribution_report_stream)) - assert len(attribution_records) == len(profile_records) * len(json.loads(attribution_report_response(report_type)).get("reports")) - - for record in attribution_records: - validate(schema=schema, instance=record) - - -@pytest.mark.parametrize( - ("stream_name", "report_type"), - [ - ("attribution_report_products", "PRODUCTS"), - ("attribution_report_performance_adgroup", "PERFORMANCE_ADGROUP"), - ("attribution_report_performance_campaign", "PERFORMANCE_CAMPAIGN"), - ("attribution_report_performance_creative", "PERFORMANCE_CREATIVE"), - ], -) -@responses.activate -def test_attribution_report_with_pagination(mocker, config, profiles_response, attribution_report_response, stream_name, report_type): - profiles = json.loads(profiles_response) - # use only single profile - profiles_response = json.dumps([profiles[0]]) - - setup_responses(profiles_response=profiles_response) - - source = SourceAmazonAds() - streams = source.streams(config) - - attribution_report_stream = get_stream_by_name(streams, stream_name) - attribution_data = json.loads(attribution_report_response(report_type)) - - def _callback(request: requests.PreparedRequest): - attribution_data["cursorId"] = None - request_data = json.loads(request.body) - - if request_data["count"] > 0: - mocker.patch("source_amazon_ads.streams.attribution_report.AttributionReport.page_size", 0) - attribution_data["cursorId"] = "next_page_token" - - return 200, {}, json.dumps(attribution_data) - - responses.add_callback( - responses.POST, - "https://advertising-api.amazon.com/attribution/report", - content_type="application/json", - callback=_callback, - ) - - attribution_records = list(read_full_refresh(attribution_report_stream)) - - # request should be called 2 times for a single profile - assert len(attribution_records) == 2 * len(attribution_data.get("reports")) - - -@freeze_time("2022-05-15 12:00:00") -def test_attribution_report_slices(config): - - profiles = [ - Profile(profileId=1, timezone="America/Los_Angeles", accountInfo=AccountInfo(id="1", type="seller", marketplaceStringId="")), - Profile(profileId=2, timezone="America/Los_Angeles", accountInfo=AccountInfo(id="1", type="seller", marketplaceStringId="")), - ] - - stream = AttributionReportProducts(config, profiles=profiles) - slices = list(stream.stream_slices(sync_mode=SyncMode.full_refresh)) - - assert slices == [ - {"profileId": 1, "startDate": "20220514", "endDate": "20220515"}, - {"profileId": 2, "startDate": "20220514", "endDate": "20220515"}, - ] - - config["start_date"] = pendulum.from_format("2022-05-01", "YYYY-MM-DD").date() - stream = AttributionReportProducts(config, profiles=profiles) - slices = list(stream.stream_slices(sync_mode=SyncMode.full_refresh)) - assert slices == [ - {"profileId": 1, "startDate": "20220501", "endDate": "20220515"}, - {"profileId": 2, "startDate": "20220501", "endDate": "20220515"}, - ] - - config["start_date"] = pendulum.from_format("2022-01-01", "YYYY-MM-DD").date() - stream = AttributionReportProducts(config, profiles=profiles) - slices = list(stream.stream_slices(sync_mode=SyncMode.full_refresh)) - assert slices == [ - {"profileId": 1, "startDate": "20220214", "endDate": "20220515"}, - {"profileId": 2, "startDate": "20220214", "endDate": "20220515"}, - ] diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_report_streams.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_report_streams.py index cf319c09a83f..831e3e53303b 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_report_streams.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_report_streams.py @@ -13,33 +13,20 @@ import pytest import requests_mock import responses -from airbyte_cdk.models import SyncMode from freezegun import freeze_time from pendulum import Date from pytest import raises from requests.exceptions import ConnectionError -from source_amazon_ads.schemas.profile import AccountInfo, Profile -from source_amazon_ads.source import CONFIG_DATE_FORMAT -from source_amazon_ads.streams import ( - SponsoredBrandsCampaigns, - SponsoredBrandsReportStream, - SponsoredBrandsV3ReportStream, - SponsoredBrandsVideoReportStream, - SponsoredDisplayCampaigns, - SponsoredDisplayReportStream, - SponsoredProductCampaigns, - SponsoredProductsReportStream, -) -from source_amazon_ads.streams.report_streams.display_report import TACTICS -from source_amazon_ads.streams.report_streams.report_streams import ( - RecordType, - ReportGenerationFailure, - ReportGenerationInProgress, - TooManyRequests, -) +from source_amazon_ads.streams import SponsoredBrandsV3ReportStream, SponsoredDisplayReportStream, SponsoredProductsReportStream +from source_amazon_ads.streams.report_streams.report_stream_models import RecordType +from source_amazon_ads.streams.report_streams.report_streams import ReportGenerationFailure, ReportGenerationInProgress, TooManyRequests + +from airbyte_cdk import AirbyteTracedException +from airbyte_cdk.models import SyncMode from .utils import read_incremental + """ METRIC_RESPONSE is gzip compressed binary representing this string: [ @@ -177,10 +164,10 @@ def setup_responses(init_response=None, init_response_products=None, init_respon def make_profiles(profile_type="seller"): return [ - Profile( + dict( profileId=1, timezone="America/Los_Angeles", - accountInfo=AccountInfo(marketplaceStringId="", id="", type=profile_type), + accountInfo=dict(marketplaceStringId="", id="", type=profile_type), ) ] @@ -188,7 +175,7 @@ def make_profiles(profile_type="seller"): @responses.activate def test_display_report_stream(config): setup_responses( - init_response=REPORT_INIT_RESPONSE, + init_response_products=REPORT_INIT_RESPONSE, status_response=REPORT_STATUS_RESPONSE, metric_response=METRIC_RESPONSE, ) @@ -196,16 +183,16 @@ def test_display_report_stream(config): profiles = make_profiles() stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) - stream_slice = {"profile": profiles[0], "reportDate": "20210725"} + stream_slice = {"profile": profiles[0], "reportDate": "2021-07-25"} metrics = [m for m in stream.read_records(SyncMode.incremental, stream_slice=stream_slice)] - assert len(metrics) == METRICS_COUNT * len(stream.metrics_map) * len(TACTICS) + assert len(metrics) == METRICS_COUNT * len(stream.metrics_map) profiles = make_profiles(profile_type="vendor") stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) stream_slice["profile"] = profiles[0] metrics = [m for m in stream.read_records(SyncMode.incremental, stream_slice=stream_slice)] # Skip asins record for vendor profiles - assert len(metrics) == METRICS_COUNT * (len(stream.metrics_map) - 1) * len(TACTICS) + assert len(metrics) == METRICS_COUNT * (len(stream.metrics_map)) @pytest.mark.parametrize( @@ -235,7 +222,7 @@ def test_stream_report_body_metrics(config, profiles, stream_class, url_pattern, ) stream = stream_class(config, profiles, authenticator=mock.MagicMock()) - stream_slice = {"profile": profiles[0], "reportDate": "20210725"} + stream_slice = {"profile": profiles[0], "reportDate": "2021-07-25"} list(stream.read_records(SyncMode.incremental, stream_slice=stream_slice)) for call in responses.calls: create_report_pattern = re.compile(url_pattern) @@ -282,22 +269,6 @@ def test_products_report_stream_without_pk(config): assert len(metrics) == len(stream.metrics_map) -@responses.activate -def test_brands_report_stream(config): - setup_responses( - init_response_brands=REPORT_INIT_RESPONSE, - status_response=REPORT_STATUS_RESPONSE, - metric_response=METRIC_RESPONSE, - ) - - profiles = make_profiles() - - stream = SponsoredBrandsReportStream(config, profiles, authenticator=mock.MagicMock()) - stream_slice = {"profile": profiles[0], "reportDate": "20210725"} - metrics = [m for m in stream.read_records(SyncMode.incremental, stream_slice=stream_slice)] - assert len(metrics) == METRICS_COUNT * len(stream.metrics_map) - - @responses.activate def test_brands_v3_report_stream(config): setup_responses( @@ -314,29 +285,13 @@ def test_brands_v3_report_stream(config): assert len(metrics) == METRICS_COUNT * len(stream.metrics_map) -@responses.activate -def test_brands_video_report_stream(config): - setup_responses( - init_response_brands=REPORT_INIT_RESPONSE, - status_response=REPORT_STATUS_RESPONSE, - metric_response=METRIC_RESPONSE, - ) - - profiles = make_profiles() - - stream = SponsoredBrandsVideoReportStream(config, profiles, authenticator=mock.MagicMock()) - stream_slice = {"profile": profiles[0], "reportDate": "20210725"} - metrics = [m for m in stream.read_records(SyncMode.incremental, stream_slice=stream_slice)] - assert len(metrics) == METRICS_COUNT * len(stream.metrics_map) - - @responses.activate def test_display_report_stream_init_failure(mocker, config): profiles = make_profiles() stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) - stream_slice = {"profile": profiles[0], "reportDate": "20210725"} + stream_slice = {"profile": profiles[0], "reportDate": "2021-07-25"} responses.add( - responses.POST, re.compile(r"https://advertising-api.amazon.com/sd/[a-zA-Z]+/report"), json={"error": "some error"}, status=400 + responses.POST, re.compile(r"https://advertising-api.amazon.com/reporting/reports"), json={"error": "some error"}, status=400 ) sleep_mock = mocker.patch("time.sleep") @@ -352,8 +307,8 @@ def test_display_report_stream_init_http_exception(mocker, config): mocker.patch("time.sleep", lambda x: None) profiles = make_profiles() stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) - stream_slice = {"profile": profiles[0], "reportDate": "20210725"} - responses.add(responses.POST, re.compile(r"https://advertising-api.amazon.com/sd/[a-zA-Z]+/report"), body=ConnectionError()) + stream_slice = {"profile": profiles[0], "reportDate": "2021-07-25"} + responses.add(responses.POST, re.compile(r"https://advertising-api.amazon.com/reporting/reports"), body=ConnectionError()) with raises(ConnectionError): _ = [m for m in stream.read_records(SyncMode.incremental, stream_slice=stream_slice)] @@ -365,10 +320,10 @@ def test_display_report_stream_init_too_many_requests(mocker, config): mocker.patch("time.sleep", lambda x: None) profiles = make_profiles() stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) - stream_slice = {"profile": profiles[0], "reportDate": "20210725"} - responses.add(responses.POST, re.compile(r"https://advertising-api.amazon.com/sd/[a-zA-Z]+/report"), json={}, status=429) + stream_slice = {"profile": profiles[0], "reportDate": "2021-07-25"} + responses.add(responses.POST, "https://advertising-api.amazon.com/reporting/reports", json={}, status=429) - with raises(TooManyRequests): + with raises(AirbyteTracedException): _ = [m for m in stream.read_records(SyncMode.incremental, stream_slice=stream_slice)] assert len(responses.calls) == 10 @@ -380,13 +335,13 @@ def test_display_report_stream_init_too_many_requests(mocker, config): [ (lambda x: x <= 10, "SUCCESS", None), ], - 10, + 5, ), ( [ (lambda x: x > 10, "SUCCESS", None), ], - 20, + 15, ), ( [ @@ -400,7 +355,7 @@ def test_display_report_stream_init_too_many_requests(mocker, config): (lambda x: x >= 6 and x <= 10, None, "2021-01-02 03:23:05"), (lambda x: x >= 11, "SUCCESS", "2021-01-02 03:24:06"), ], - 20, + 15, ), ( [ @@ -418,7 +373,7 @@ def test_display_report_stream_init_too_many_requests(mocker, config): @responses.activate def test_display_report_stream_backoff(mocker, config, modifiers, expected): mocker.patch("time.sleep") - setup_responses(init_response=REPORT_INIT_RESPONSE, metric_response=METRIC_RESPONSE) + setup_responses(init_response_products=REPORT_INIT_RESPONSE, metric_response=METRIC_RESPONSE) with freeze_time("2021-01-02 03:04:05") as frozen_time: @@ -438,10 +393,10 @@ def __call__(self, request): return (200, {}, response) callback = StatusCallback() - responses.add_callback(responses.GET, re.compile(r"https://advertising-api.amazon.com/v2/reports/[^/]+$"), callback=callback) + responses.add_callback(responses.GET, re.compile(r"https://advertising-api.amazon.com/reporting/reports/[^/]+$"), callback=callback) profiles = make_profiles() stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) - stream_slice = {"profile": profiles[0], "reportDate": "20210725"} + stream_slice = {"profile": profiles[0], "reportDate": "2021-07-25"} if isinstance(expected, int): list(stream.read_records(SyncMode.incremental, stream_slice=stream_slice)) @@ -457,7 +412,7 @@ def test_display_report_stream_slices_full_refresh(config): profiles = make_profiles() stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) slices = list(stream.stream_slices(SyncMode.full_refresh, cursor_field=stream.cursor_field)) - assert slices == [{"profile": profiles[0], "reportDate": "20210729"}] + assert slices == [{"profile": profiles[0], "reportDate": "2021-07-29"}] @freeze_time("2021-07-30 04:26:08") @@ -465,39 +420,39 @@ def test_display_report_stream_slices_full_refresh(config): def test_display_report_stream_slices_incremental(config): profiles = make_profiles() stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) - stream_state = {str(profiles[0].profileId): {"reportDate": "20210725"}} + stream_state = {str(profiles[0]["profileId"]): {"reportDate": "2021-07-25"}} slices = list(stream.stream_slices(SyncMode.incremental, cursor_field=stream.cursor_field, stream_state=stream_state)) assert slices == [ - {"profile": profiles[0], "reportDate": "20210725"}, - {"profile": profiles[0], "reportDate": "20210726"}, - {"profile": profiles[0], "reportDate": "20210727"}, - {"profile": profiles[0], "reportDate": "20210728"}, - {"profile": profiles[0], "reportDate": "20210729"}, + {"profile": profiles[0], "reportDate": "2021-07-25"}, + {"profile": profiles[0], "reportDate": "2021-07-26"}, + {"profile": profiles[0], "reportDate": "2021-07-27"}, + {"profile": profiles[0], "reportDate": "2021-07-28"}, + {"profile": profiles[0], "reportDate": "2021-07-29"}, ] - stream_state = {str(profiles[0].profileId): {"reportDate": "20210730"}} + stream_state = {str(profiles[0]["profileId"]): {"reportDate": "2021-07-30"}} slices = list(stream.stream_slices(SyncMode.incremental, cursor_field=stream.cursor_field, stream_state=stream_state)) assert slices == [None] slices = list(stream.stream_slices(SyncMode.incremental, cursor_field=stream.cursor_field, stream_state={})) - assert slices == [{"profile": profiles[0], "reportDate": "20210729"}] + assert slices == [{"profile": profiles[0], "reportDate": "2021-07-29"}] slices = list(stream.stream_slices(SyncMode.incremental, cursor_field=None, stream_state={})) - assert slices == [{"profile": profiles[0], "reportDate": "20210729"}] + assert slices == [{"profile": profiles[0], "reportDate": "2021-07-29"}] @freeze_time("2021-08-01 04:00:00") def test_get_start_date(config): profiles = make_profiles() - config["start_date"] = pendulum.from_format("2021-07-10", CONFIG_DATE_FORMAT).date() + config["start_date"] = "2021-07-10" stream = SponsoredProductsReportStream(config, profiles, authenticator=mock.MagicMock()) assert stream.get_start_date(profiles[0], {}) == Date(2021, 7, 10) - config["start_date"] = pendulum.from_format("2021-05-10", CONFIG_DATE_FORMAT).date() + config["start_date"] = "2021-05-10" stream = SponsoredProductsReportStream(config, profiles, authenticator=mock.MagicMock()) assert stream.get_start_date(profiles[0], {}) == Date(2021, 6, 1) - profile_id = str(profiles[0].profileId) + profile_id = str(profiles[0]["profileId"]) stream = SponsoredProductsReportStream(config, profiles, authenticator=mock.MagicMock()) assert stream.get_start_date(profiles[0], {profile_id: {"reportDate": "2021-08-10"}}) == Date(2021, 8, 10) stream = SponsoredProductsReportStream(config, profiles, authenticator=mock.MagicMock()) @@ -510,8 +465,8 @@ def test_get_start_date(config): @freeze_time("2021-08-01 04:00:00") def test_stream_slices_different_timezones(config): - profile1 = Profile(profileId=1, timezone="America/Los_Angeles", accountInfo=AccountInfo(marketplaceStringId="", id="", type="seller")) - profile2 = Profile(profileId=2, timezone="UTC", accountInfo=AccountInfo(marketplaceStringId="", id="", type="seller")) + profile1 = dict(profileId=1, timezone="America/Los_Angeles", accountInfo=dict(marketplaceStringId="", id="", type="seller")) + profile2 = dict(profileId=2, timezone="UTC", accountInfo=dict(marketplaceStringId="", id="", type="seller")) stream = SponsoredProductsReportStream(config, [profile1, profile2], authenticator=mock.MagicMock()) slices = list(stream.stream_slices(SyncMode.incremental, cursor_field=stream.cursor_field, stream_state={})) assert slices == [{"profile": profile1, "reportDate": "2021-07-31"}, {"profile": profile2, "reportDate": "2021-08-01"}] @@ -519,9 +474,9 @@ def test_stream_slices_different_timezones(config): def test_stream_slices_lazy_evaluation(config): with freeze_time("2022-06-01T23:50:00+00:00") as frozen_datetime: - config["start_date"] = pendulum.from_format("2021-05-10", CONFIG_DATE_FORMAT).date() - profile1 = Profile(profileId=1, timezone="UTC", accountInfo=AccountInfo(marketplaceStringId="", id="", type="seller")) - profile2 = Profile(profileId=2, timezone="UTC", accountInfo=AccountInfo(marketplaceStringId="", id="", type="seller")) + config["start_date"] = "2021-05-10" + profile1 = dict(profileId=1, timezone="UTC", accountInfo=dict(marketplaceStringId="", id="", type="seller")) + profile2 = dict(profileId=2, timezone="UTC", accountInfo=dict(marketplaceStringId="", id="", type="seller")) stream = SponsoredProductsReportStream(config, [profile1, profile2], authenticator=mock.MagicMock()) stream.REPORTING_PERIOD = 5 @@ -571,7 +526,7 @@ def test_get_date_range_lazy_evaluation(): @responses.activate def test_read_incremental_without_records(config): setup_responses( - init_response=REPORT_INIT_RESPONSE, + init_response_products=REPORT_INIT_RESPONSE, status_response=REPORT_STATUS_RESPONSE, metric_response=b64decode("H4sIAAAAAAAAAIuOBQApu0wNAgAAAA=="), ) @@ -581,7 +536,7 @@ def test_read_incremental_without_records(config): with freeze_time("2021-01-02 12:00:00") as frozen_datetime: state = {} - reportDates = ["20210102", "20210102", "20210102", "20210103", "20210104", "20210105"] + reportDates = ["2021-01-02", "2021-01-02", "2021-01-02", "2021-01-03", "2021-01-04", "2021-01-05"] for reportDate in reportDates: records = list(read_incremental(stream, state)) assert state == {"1": {"reportDate": reportDate}} @@ -592,7 +547,7 @@ def test_read_incremental_without_records(config): @responses.activate def test_read_incremental_with_records(config): setup_responses( - init_response=REPORT_INIT_RESPONSE, + init_response_products=REPORT_INIT_RESPONSE, status_response=REPORT_STATUS_RESPONSE, metric_response=METRIC_RESPONSE, ) @@ -603,50 +558,50 @@ def test_read_incremental_with_records(config): with freeze_time("2021-01-02 12:00:00") as frozen_datetime: state = {} records = list(read_incremental(stream, state)) - assert state == {"1": {"reportDate": "20210102"}} - assert {r["reportDate"] for r in records} == {"20210102"} + assert state == {"1": {"reportDate": "2021-01-02"}} + assert {r["reportDate"] for r in records} == {"2021-01-02"} frozen_datetime.tick(delta=timedelta(days=1)) records = list(read_incremental(stream, state)) - assert state == {"1": {"reportDate": "20210102"}} - assert {r["reportDate"] for r in records} == {"20210102", "20210103"} + assert state == {"1": {"reportDate": "2021-01-02"}} + assert {r["reportDate"] for r in records} == {"2021-01-02", "2021-01-03"} frozen_datetime.tick(delta=timedelta(days=1)) records = list(read_incremental(stream, state)) - assert state == {"1": {"reportDate": "20210102"}} - assert {r["reportDate"] for r in records} == {"20210102", "20210103", "20210104"} + assert state == {"1": {"reportDate": "2021-01-02"}} + assert {r["reportDate"] for r in records} == {"2021-01-02", "2021-01-03", "2021-01-04"} frozen_datetime.tick(delta=timedelta(days=1)) records = list(read_incremental(stream, state)) - assert state == {"1": {"reportDate": "20210103"}} - assert {r["reportDate"] for r in records} == {"20210102", "20210103", "20210104", "20210105"} + assert state == {"1": {"reportDate": "2021-01-03"}} + assert {r["reportDate"] for r in records} == {"2021-01-02", "2021-01-03", "2021-01-04", "2021-01-05"} frozen_datetime.tick(delta=timedelta(days=1)) records = list(read_incremental(stream, state)) - assert state == {"1": {"reportDate": "20210104"}} - assert {r["reportDate"] for r in records} == {"20210103", "20210104", "20210105", "20210106"} + assert state == {"1": {"reportDate": "2021-01-04"}} + assert {r["reportDate"] for r in records} == {"2021-01-03", "2021-01-04", "2021-01-05", "2021-01-06"} frozen_datetime.tick(delta=timedelta(days=1)) records = list(read_incremental(stream, state)) - assert state == {"1": {"reportDate": "20210105"}} - assert {r["reportDate"] for r in records} == {"20210104", "20210105", "20210106", "20210107"} + assert state == {"1": {"reportDate": "2021-01-05"}} + assert {r["reportDate"] for r in records} == {"2021-01-04", "2021-01-05", "2021-01-06", "2021-01-07"} @responses.activate def test_read_incremental_without_records_start_date(config): setup_responses( - init_response=REPORT_INIT_RESPONSE, + init_response_products=REPORT_INIT_RESPONSE, status_response=REPORT_STATUS_RESPONSE, metric_response=b64decode("H4sIAAAAAAAAAIuOBQApu0wNAgAAAA=="), ) profiles = make_profiles() - config["start_date"] = pendulum.from_format("2020-12-25", CONFIG_DATE_FORMAT).date() + config["start_date"] = "2020-12-25" stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) with freeze_time("2021-01-02 12:00:00") as frozen_datetime: state = {} - reportDates = ["20201231", "20210101", "20210102", "20210103", "20210104"] + reportDates = ["2020-12-31", "2021-01-01", "2021-01-02", "2021-01-03", "2021-01-04"] for reportDate in reportDates: records = list(read_incremental(stream, state)) assert state == {"1": {"reportDate": reportDate}} @@ -657,120 +612,51 @@ def test_read_incremental_without_records_start_date(config): @responses.activate def test_read_incremental_with_records_start_date(config): setup_responses( - init_response=REPORT_INIT_RESPONSE, + init_response_products=REPORT_INIT_RESPONSE, status_response=REPORT_STATUS_RESPONSE, metric_response=METRIC_RESPONSE, ) profiles = make_profiles() - config["start_date"] = pendulum.from_format("2020-12-25", CONFIG_DATE_FORMAT).date() + config["start_date"] = "2020-12-25" stream = SponsoredDisplayReportStream(config, profiles, authenticator=mock.MagicMock()) with freeze_time("2021-01-02 12:00:00") as frozen_datetime: state = {} records = list(read_incremental(stream, state)) - assert state == {"1": {"reportDate": "20201231"}} + assert state == {"1": {"reportDate": "2020-12-31"}} assert {r["reportDate"] for r in records} == { - "20201225", - "20201226", - "20201227", - "20201228", - "20201229", - "20201230", - "20201231", - "20210101", - "20210102", + "2020-12-25", + "2020-12-26", + "2020-12-27", + "2020-12-28", + "2020-12-29", + "2020-12-30", + "2020-12-31", + "2021-01-01", + "2021-01-02", } frozen_datetime.tick(delta=timedelta(days=1)) records = list(read_incremental(stream, state)) - assert state == {"1": {"reportDate": "20210101"}} - assert {r["reportDate"] for r in records} == {"20201231", "20210101", "20210102", "20210103"} + assert state == {"1": {"reportDate": "2021-01-01"}} + assert {r["reportDate"] for r in records} == {"2020-12-31", "2021-01-01", "2021-01-02", "2021-01-03"} frozen_datetime.tick(delta=timedelta(days=1)) records = list(read_incremental(stream, state)) - assert state == {"1": {"reportDate": "20210102"}} - assert {r["reportDate"] for r in records} == {"20210101", "20210102", "20210103", "20210104"} + assert state == {"1": {"reportDate": "2021-01-02"}} + assert {r["reportDate"] for r in records} == {"2021-01-01", "2021-01-02", "2021-01-03", "2021-01-04"} frozen_datetime.tick(delta=timedelta(days=1)) records = list(read_incremental(stream, state)) - assert state == {"1": {"reportDate": "20210103"}} - assert {r["reportDate"] for r in records} == {"20210102", "20210103", "20210104", "20210105"} + assert state == {"1": {"reportDate": "2021-01-03"}} + assert {r["reportDate"] for r in records} == {"2021-01-02", "2021-01-03", "2021-01-04", "2021-01-05"} frozen_datetime.tick(delta=timedelta(days=1)) records = list(read_incremental(stream, state)) - assert state == {"1": {"reportDate": "20210104"}} - assert {r["reportDate"] for r in records} == {"20210103", "20210104", "20210105", "20210106"} - - -@pytest.mark.parametrize( - "state_filter, stream_class", - [ - ( - ["enabled", "archived", "paused"], - SponsoredDisplayCampaigns, - ), - ( - ["enabled"], - SponsoredDisplayCampaigns, - ), - ( - None, - SponsoredDisplayCampaigns, - ), - ], -) -def test_streams_state_filter(mocker, config, state_filter, stream_class): - profiles = make_profiles() - mocker.patch.object(stream_class, "state_filter", new_callable=mocker.PropertyMock, return_value=state_filter) - - stream = stream_class(config, profiles) - params = stream.request_params(stream_state=None, stream_slice=None, next_page_token=None) - if "stateFilter" in params: - assert params["stateFilter"] == ",".join(state_filter) - else: - assert state_filter is None - -@pytest.mark.parametrize( - "state_filter, stream_class", - [ - ( - ["enabled", "archived", "paused"], - SponsoredBrandsCampaigns, - ), - ( - ["enabled"], - SponsoredBrandsCampaigns, - ), - ( - None, - SponsoredBrandsCampaigns, - ), - ( - ["enabled", "archived", "paused"], - SponsoredProductCampaigns, - ), - ( - ["enabled"], - SponsoredProductCampaigns, - ), - ( - None, - SponsoredProductCampaigns, - ), - ], -) -def test_sponsored_brand_and_products_streams_state_filter(mocker, config, state_filter, stream_class): - profiles = make_profiles() - mocker.patch.object(stream_class, "state_filter", new_callable=mocker.PropertyMock, return_value=state_filter) - - stream = stream_class(config, profiles) - request_body = stream.request_body_json(stream_state=None, stream_slice=None, next_page_token=None) - if "stateFilter" in request_body: - assert request_body["stateFilter"]["include"] == state_filter - else: - assert state_filter is None + assert state == {"1": {"reportDate": "2021-01-04"}} + assert {r["reportDate"] for r in records} == {"2021-01-03", "2021-01-04", "2021-01-05", "2021-01-06"} @responses.activate @@ -780,7 +666,7 @@ def test_sponsored_brand_and_products_streams_state_filter(mocker, config, state ) def test_display_report_stream_with_custom_record_types(config_gen, custom_record_types, flag_match_error): setup_responses( - init_response=REPORT_INIT_RESPONSE, + init_response_products=REPORT_INIT_RESPONSE, status_response=REPORT_STATUS_RESPONSE, metric_response=METRIC_RESPONSE, ) @@ -788,7 +674,7 @@ def test_display_report_stream_with_custom_record_types(config_gen, custom_recor profiles = make_profiles() stream = SponsoredDisplayReportStream(config_gen(report_record_types=custom_record_types), profiles, authenticator=mock.MagicMock()) - stream_slice = {"profile": profiles[0], "reportDate": "20210725"} + stream_slice = {"profile": profiles[0], "reportDate": "2021-07-25"} records = list(stream.read_records(SyncMode.incremental, stream_slice=stream_slice)) for record in records: if record["recordType"] not in custom_record_types: @@ -827,36 +713,6 @@ def test_products_report_stream_with_custom_record_types(config_gen, custom_reco assert False -@responses.activate -@pytest.mark.parametrize( - "custom_record_types, expected_record_types, flag_match_error", - [ - (["campaigns"], ["campaigns"], True), - (["asins"], ["asins"], True), - (["campaigns", "adGroups"], ["campaigns", "adGroups"], True), - ([], [], False), - (["invalid_record_type"], [], True), - ], -) -def test_brands_video_report_with_custom_record_types(config_gen, custom_record_types, expected_record_types, flag_match_error): - setup_responses( - init_response_brands=REPORT_INIT_RESPONSE, - status_response=REPORT_STATUS_RESPONSE, - metric_response=METRIC_RESPONSE, - ) - - profiles = make_profiles() - - stream = SponsoredBrandsVideoReportStream(config_gen(report_record_types=custom_record_types), profiles, authenticator=mock.MagicMock()) - stream_slice = {"profile": profiles[0], "reportDate": "20210725"} - records = list(stream.read_records(SyncMode.incremental, stream_slice=stream_slice)) - for record in records: - print(record) - if record["recordType"] not in expected_record_types: - if flag_match_error: - assert False - - @pytest.mark.parametrize( "metric_object, record_type", [ @@ -881,7 +737,7 @@ def test_get_record_id_by_report_type(config, metric_object, record_type): def test_sponsored_products_report_stream_send_http_request_on_download_not_use_headers(config): profiles = make_profiles(profile_type="vendor") - stream = SponsoredProductsReportStream(config,profiles, authenticator=mock.MagicMock()) + stream = SponsoredProductsReportStream(config, profiles, authenticator=mock.MagicMock()) download_url = "https://download/url" with requests_mock.Mocker() as m: @@ -890,4 +746,3 @@ def test_sponsored_products_report_stream_send_http_request_on_download_not_use_ assert request_mock.called is True assert "Authorization" not in request_mock.request_history[0].matcher.last_request._request.headers.keys() - diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_source.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_source.py deleted file mode 100644 index 4ecc75099554..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_source.py +++ /dev/null @@ -1,162 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import responses -from airbyte_cdk.models import AirbyteConnectionStatus, AirbyteMessage, ConnectorSpecification, Status, Type -from jsonschema import Draft4Validator -from source_amazon_ads import SourceAmazonAds -from source_amazon_ads.declarative_source_adapter import DeclarativeSourceAdapter -from source_amazon_ads.schemas import Profile - -from .utils import command_check, url_strip_query - - -def setup_responses(): - responses.add( - responses.POST, - "https://api.amazon.com/auth/o2/token", - json={"access_token": "alala", "expires_in": 10}, - ) - responses.add( - responses.GET, - "https://advertising-api.amazon.com/v2/profiles", - json=[{"profileId": 111, "timezone": "gtm", "accountInfo": {"marketplaceStringId": "mkt_id_1", "id": "111", "type": "vendor"}}], - ) - - -def ensure_additional_property_is_boolean(root): - for name, prop in root.get("properties", {}).items(): - if prop["type"] == "array" and "items" in prop: - ensure_additional_property_is_boolean(prop["items"]) - if prop["type"] == "object" and "properties" in prop: - ensure_additional_property_is_boolean(prop) - if "additionalProperties" in root: - assert type(root["additionalProperties"]) == bool, ( - f"`additionalProperties` expected to be of 'bool' type. " f"Got: {type(root['additionalProperties']).__name__}" - ) - - -@responses.activate -def test_discover(config): - setup_responses() - source = DeclarativeSourceAdapter(source=SourceAmazonAds()) - catalog = source.discover(None, config) - catalog = AirbyteMessage(type=Type.CATALOG, catalog=catalog).dict(exclude_unset=True) - schemas = [stream["json_schema"] for stream in catalog["catalog"]["streams"]] - for schema in schemas: - Draft4Validator.check_schema(schema) - ensure_additional_property_is_boolean(schema) - - -def test_spec(): - source = DeclarativeSourceAdapter(source=SourceAmazonAds()) - spec = source.spec(None) - assert isinstance(spec, ConnectorSpecification) - - -@responses.activate -def test_check(config_gen): - setup_responses() - source = DeclarativeSourceAdapter(source=SourceAmazonAds()) - - assert command_check(source, config_gen(start_date=...)) == AirbyteConnectionStatus(status=Status.SUCCEEDED) - assert len(responses.calls) == 2 - - assert command_check(source, config_gen(start_date="")) == AirbyteConnectionStatus(status=Status.SUCCEEDED) - assert len(responses.calls) == 4 - - assert source.check(None, config_gen(start_date="2022-02-20")) == AirbyteConnectionStatus(status=Status.SUCCEEDED) - assert len(responses.calls) == 6 - - assert command_check(source, config_gen(start_date="2022-20-02")) == AirbyteConnectionStatus( - status=Status.FAILED, message="'month must be in 1..12'" - ) - assert len(responses.calls) == 6 - - assert command_check(source, config_gen(start_date="no date")) == AirbyteConnectionStatus( - status=Status.FAILED, message="'String does not match format YYYY-MM-DD'" - ) - assert len(responses.calls) == 6 - - assert command_check(source, config_gen(region=...)) == AirbyteConnectionStatus(status=Status.SUCCEEDED) - assert len(responses.calls) == 8 - assert url_strip_query(responses.calls[7].request.url) == "https://advertising-api.amazon.com/v2/profiles" - - assert command_check(source, config_gen(look_back_window=...)) == AirbyteConnectionStatus(status=Status.SUCCEEDED) - - -@responses.activate -def test_source_streams(config): - setup_responses() - source = DeclarativeSourceAdapter(source=SourceAmazonAds()) - streams = source.streams(config) - assert len(streams) == 29 - actual_stream_names = {stream.name for stream in streams} - expected_stream_names = { - "profiles", - "portfolios", - "sponsored_display_campaigns", - "sponsored_product_campaigns", - "sponsored_product_ad_groups", - "sponsored_product_ad_group_suggested_keywords", - "sponsored_product_ad_group_bid_recommendations", - "sponsored_product_keywords", - "sponsored_product_negative_keywords", - "sponsored_product_campaign_negative_keywords", - "sponsored_product_ads", - "sponsored_product_targetings", - "sponsored_products_report_stream", - "sponsored_brands_campaigns", - "sponsored_brands_ad_groups", - "sponsored_brands_keywords", - "sponsored_brands_report_stream", - "attribution_report_performance_adgroup", - "attribution_report_performance_campaign", - "attribution_report_performance_creative", - "attribution_report_products", - "sponsored_display_budget_rules", - } - assert not expected_stream_names - actual_stream_names - - -def test_filter_profiles_exist(): - source = SourceAmazonAds() - mock_objs = [ - {"profileId": 111, "timezone": "gtm", "accountInfo": {"marketplaceStringId": "mkt_id_1", "id": "111", "type": "vendor"}}, - {"profileId": 222, "timezone": "gtm", "accountInfo": {"marketplaceStringId": "mkt_id_2", "id": "222", "type": "vendor"}}, - {"profileId": 333, "timezone": "gtm", "accountInfo": {"marketplaceStringId": "mkt_id_3", "id": "333", "type": "vendor"}}, - ] - - mock_profiles = [Profile.parse_obj(profile) for profile in mock_objs] - - filtered_profiles = source._choose_profiles({}, mock_profiles) - assert len(filtered_profiles) == 3 - - filtered_profiles = source._choose_profiles({"profiles": [111]}, mock_profiles) - assert len(filtered_profiles) == 1 - assert filtered_profiles[0].profileId == 111 - - filtered_profiles = source._choose_profiles({"profiles": [111, 333]}, mock_profiles) - assert len(filtered_profiles) == 2 - - filtered_profiles = source._choose_profiles({"profiles": [444]}, mock_profiles) - assert len(filtered_profiles) == 0 - - filtered_profiles = source._choose_profiles({"marketplace_ids": ["mkt_id_4"]}, mock_profiles) - assert len(filtered_profiles) == 0 - - filtered_profiles = source._choose_profiles({"marketplace_ids": ["mkt_id_1"]}, mock_profiles) - assert len(filtered_profiles) == 1 - assert filtered_profiles[0].accountInfo.marketplaceStringId == "mkt_id_1" - - filtered_profiles = source._choose_profiles({"marketplace_ids": ["mkt_id_1", "mkt_id_3"]}, mock_profiles) - assert len(filtered_profiles) == 2 - - filtered_profiles = source._choose_profiles({"profiles": [111], "marketplace_ids": ["mkt_id_2"]}, mock_profiles) - assert len(filtered_profiles) == 2 - - filtered_profiles = source._choose_profiles({"profiles": [111], "marketplace_ids": ["mkt_id_1"]}, mock_profiles) - assert len(filtered_profiles) == 1 - assert filtered_profiles[0].profileId == 111 diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_streams.py deleted file mode 100644 index 31264c021008..000000000000 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_streams.py +++ /dev/null @@ -1,308 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -from http import HTTPStatus -from urllib.parse import parse_qs, urlparse - -import pytest -import requests -import responses -from airbyte_cdk.models import SyncMode -from jsonschema import validate -from source_amazon_ads import SourceAmazonAds - - -def setup_responses( - profiles_response=None, - portfolios_response=None, - campaigns_response=None, - adgroups_response=None, - targeting_response=None, - product_ads_response=None, - generic_response=None, - creatives_response=None, - post_response=None, -): - responses.add( - responses.POST, - "https://api.amazon.com/auth/o2/token", - json={"access_token": "alala", "expires_in": 10}, - ) - if profiles_response: - responses.add( - responses.GET, - "https://advertising-api.amazon.com/v2/profiles", - body=profiles_response, - ) - if portfolios_response: - responses.add( - responses.GET, - "https://advertising-api.amazon.com/v2/portfolios/extended", - body=portfolios_response, - ) - if campaigns_response: - responses.add( - responses.GET, - "https://advertising-api.amazon.com/sd/campaigns", - body=campaigns_response, - ) - if adgroups_response: - responses.add( - responses.GET, - "https://advertising-api.amazon.com/sd/adGroups", - body=adgroups_response, - ) - if targeting_response: - responses.add( - responses.GET, - "https://advertising-api.amazon.com/sd/targets", - body=targeting_response, - ) - if product_ads_response: - responses.add( - responses.GET, - "https://advertising-api.amazon.com/sd/productAds", - body=product_ads_response, - ) - if creatives_response: - responses.add( - responses.GET, - "https://advertising-api.amazon.com/sd/creatives", - body=creatives_response, - ) - if generic_response: - responses.add( - responses.GET, - f"https://advertising-api.amazon.com/{generic_response}", - json=[], - ) - if post_response: - responses.add( - responses.POST, - f"https://advertising-api.amazon.com/{post_response}", - json={}, - ) - - -def get_all_stream_records(stream, stream_slice=None): - records = stream.read_records(SyncMode.full_refresh, stream_slice=stream_slice) - return [r for r in records] - - -def get_stream_by_name(streams, stream_name): - for stream in streams: - if stream.name == stream_name: - return stream - raise Exception(f"Expected stream {stream_name} not found") - - -@responses.activate -def test_streams_profile(config, profiles_response): - setup_responses(profiles_response=profiles_response) - - source = SourceAmazonAds() - streams = source.streams(config) - - profile_stream = get_stream_by_name(streams, "profiles") - schema = profile_stream.get_json_schema() - records = get_all_stream_records(profile_stream) - assert len(responses.calls) == 2 - assert len(profile_stream._profiles) == 4 - assert len(records) == 4 - expected_records = json.loads(profiles_response) - for record, expected_record in zip(records, expected_records): - validate(schema=schema, instance=record) - assert record == expected_record - - -@responses.activate -def test_streams_portfolios(config, profiles_response, portfolios_response): - setup_responses(profiles_response=profiles_response, portfolios_response=portfolios_response) - - source = SourceAmazonAds() - streams = source.streams(config) - - portfolio_stream = get_stream_by_name(streams, "portfolios") - schema = portfolio_stream.get_json_schema() - records = get_all_stream_records(portfolio_stream) - assert len(responses.calls) == 6 - assert len(records) == 8 - expected_records = json.loads(portfolios_response) - for record, expected_record in zip(records, expected_records): - validate(schema=schema, instance=record) - assert record == expected_record - - -@responses.activate -def test_streams_campaigns_4_vendors(config, profiles_response, campaigns_response): - profiles_response = json.loads(profiles_response) - for profile in profiles_response: - profile["accountInfo"]["type"] = "vendor" - profiles_response = json.dumps(profiles_response) - setup_responses(profiles_response=profiles_response, campaigns_response=campaigns_response) - - source = SourceAmazonAds() - streams = source.streams(config) - profile_stream = get_stream_by_name(streams, "profiles") - campaigns_stream = get_stream_by_name(streams, "sponsored_display_campaigns") - profile_records = get_all_stream_records(profile_stream) - campaigns_records = get_all_stream_records(campaigns_stream) - assert len(campaigns_records) == len(profile_records) * len(json.loads(campaigns_response)) - - -@pytest.mark.parametrize( - ("page_size"), - [1, 2, 5, 1000000], -) -@responses.activate -def test_streams_campaigns_pagination(mocker, config, profiles_response, campaigns_response, page_size): - mocker.patch("source_amazon_ads.streams.common.SubProfilesStream.page_size", page_size) - profiles_response = json.loads(profiles_response) - for profile in profiles_response: - profile["accountInfo"]["type"] = "vendor" - profiles_response = json.dumps(profiles_response) - setup_responses(profiles_response=profiles_response) - - source = SourceAmazonAds() - streams = source.streams(config) - profile_stream = get_stream_by_name(streams, "profiles") - campaigns_stream = get_stream_by_name(streams, "sponsored_display_campaigns") - campaigns = json.loads(campaigns_response) - - def campaigns_paginated_response_cb(request): - query = urlparse(request.url).query - query = parse_qs(query) - start_index, count = (int(query.get(f, [0])[0]) for f in ["startIndex", "count"]) - response_body = campaigns[start_index : start_index + count] - return (200, {}, json.dumps(response_body)) - - responses.add_callback( - responses.GET, - "https://advertising-api.amazon.com/sd/campaigns", - content_type="application/json", - callback=campaigns_paginated_response_cb, - ) - profile_records = get_all_stream_records(profile_stream) - - campaigns_records = get_all_stream_records(campaigns_stream) - assert len(campaigns_records) == len(profile_records) * len(json.loads(campaigns_response)) - - -@pytest.mark.parametrize(("status_code"), [HTTPStatus.FORBIDDEN, HTTPStatus.UNAUTHORIZED]) -@responses.activate -def test_streams_campaigns_pagination_403_error(mocker, status_code, config, profiles_response, campaigns_response): - setup_responses(profiles_response=profiles_response) - responses.add( - responses.GET, - "https://advertising-api.amazon.com/sd/campaigns", - json={"message": "msg"}, - status=status_code, - ) - source = SourceAmazonAds() - streams = source.streams(config) - campaigns_stream = get_stream_by_name(streams, "sponsored_display_campaigns") - - with pytest.raises(requests.exceptions.HTTPError): - get_all_stream_records(campaigns_stream) - - -@responses.activate -def test_streams_campaigns_pagination_403_error_expected(mocker, config, profiles_response, campaigns_response): - setup_responses(profiles_response=profiles_response) - responses.add( - responses.GET, - "https://advertising-api.amazon.com/sd/campaigns", - json={"code": "403", "details": "details", "requestId": "xxx"}, - status=403, - ) - source = SourceAmazonAds() - streams = source.streams(config) - campaigns_stream = get_stream_by_name(streams, "sponsored_display_campaigns") - - campaigns_records = get_all_stream_records(campaigns_stream) - assert campaigns_records == [] - - -@pytest.mark.parametrize( - ("stream_name", "endpoint"), - [ - ("sponsored_display_ad_groups", "sd/adGroups"), - ("sponsored_display_product_ads", "sd/productAds"), - ("sponsored_display_targetings", "sd/targets"), - ("sponsored_display_creatives", "sd/creatives"), - ], -) -@responses.activate -def test_streams_displays( - config, stream_name, endpoint, profiles_response, adgroups_response, targeting_response, product_ads_response, creatives_response -): - setup_responses( - profiles_response=profiles_response, - adgroups_response=adgroups_response, - targeting_response=targeting_response, - product_ads_response=product_ads_response, - creatives_response=creatives_response, - ) - - source = SourceAmazonAds() - streams = source.streams(config) - test_stream = get_stream_by_name(streams, stream_name) - - records = get_all_stream_records(test_stream) - assert len(records) == 4 - schema = test_stream.get_json_schema() - for r in records: - validate(schema=schema, instance=r) - assert any([endpoint in call.request.url for call in responses.calls]) - - -@pytest.mark.parametrize( - ("stream_name", "endpoint"), - [ - ("sponsored_brands_campaigns", "sb/v4/campaigns/list"), - ("sponsored_brands_ad_groups", "sb/v4/adGroups/list"), - ("sponsored_brands_keywords", "sb/keywords"), - ("sponsored_product_campaigns", "sp/campaigns/list"), - ("sponsored_product_ad_groups", "sp/adGroups/list"), - ("sponsored_product_keywords", "sp/keywords/list"), - ("sponsored_product_negative_keywords", "sp/negativeKeywords/list"), - ("sponsored_product_ads", "sp/productAds/list"), - ("sponsored_product_targetings", "sp/targets/list"), - ], -) -@responses.activate -def test_streams_brands_and_products(config, stream_name, endpoint, profiles_response): - if endpoint != "sb/keywords": - setup_responses(profiles_response=profiles_response, post_response=endpoint) - else: - setup_responses(profiles_response=profiles_response, generic_response=endpoint) - - source = SourceAmazonAds() - streams = source.streams(config) - test_stream = get_stream_by_name(streams, stream_name) - - records = get_all_stream_records(test_stream) - assert records == [] - assert any([endpoint in call.request.url for call in responses.calls]) - - -@responses.activate -def test_sponsored_product_ad_group_bid_recommendations_404_error(caplog, config, profiles_response): - setup_responses(profiles_response=profiles_response) - responses.add( - responses.POST, - "https://advertising-api.amazon.com/sp/targets/bid/recommendations", - json={ - "code": "404", - "details": "404 Either the specified ad group identifier was not found or the specified ad group was found but no associated bid was found.", - }, - status=404, - ) - source = SourceAmazonAds() - streams = source.streams(config) - test_stream = get_stream_by_name(streams, "sponsored_product_ad_group_bid_recommendations") - records = get_all_stream_records(test_stream, stream_slice={"campaignId": "1231", "adGroupId": "xxx"}) - assert records == [] - assert "Skip current AdGroup because the specified ad group has no associated bid" in caplog.text diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/utils.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/utils.py index eb6cbb4dd93f..a993909cc455 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/utils.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/utils.py @@ -6,12 +6,13 @@ from unittest import mock from urllib.parse import urlparse, urlunparse +from source_amazon_ads.config_migrations import MigrateStartDate + from airbyte_cdk.models import SyncMode from airbyte_cdk.models.airbyte_protocol import ConnectorSpecification from airbyte_cdk.sources import Source from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.utils.schema_helpers import check_config_against_spec_or_exit, split_config -from source_amazon_ads.config_migrations import MigrateStartDate def read_incremental(stream_instance: Stream, stream_state: MutableMapping[str, Any]) -> Iterator[dict]: diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/acceptance-test-config.yml b/airbyte-integrations/connectors/source-amazon-seller-partner/acceptance-test-config.yml index 74cb5b27390a..a2bb6f0da2d5 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/acceptance-test-config.yml @@ -107,11 +107,11 @@ acceptance_tests: tests: - config_path: "secrets/config.json" configured_catalog_path: "integration_tests/configured_catalog_incremental.json" - timeout_seconds: 3600 + timeout_seconds: 7200 future_state: future_state_path: "integration_tests/future_state.json" full_refresh: tests: - config_path: "secrets/config.json" configured_catalog_path: "integration_tests/configured_catalog.json" - timeout_seconds: 3600 + timeout_seconds: 7200 diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-amazon-seller-partner/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/main.py b/airbyte-integrations/connectors/source-amazon-seller-partner/main.py index ee7f33aa3ce5..e9aadc718c43 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/main.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/main.py @@ -4,5 +4,6 @@ from source_amazon_seller_partner.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/metadata.yaml b/airbyte-integrations/connectors/source-amazon-seller-partner/metadata.yaml index 523fa91399e2..9e9094d8e5df 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/metadata.yaml +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/metadata.yaml @@ -11,11 +11,11 @@ data: ql: 400 sl: 300 connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: e55879a8-0ef8-4557-abcf-ab34c53ec460 - dockerImageTag: 4.4.4 + dockerImageTag: 4.4.7 dockerRepository: airbyte/source-amazon-seller-partner documentationUrl: https://docs.airbyte.com/integrations/sources/amazon-seller-partner erdUrl: https://dbdocs.io/airbyteio/source-amazon-seller-partner?view=relationships diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/poetry.lock b/airbyte-integrations/connectors/source-amazon-seller-partner/poetry.lock index f065a2c8d355..5664a283d6d0 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/poetry.lock +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/poetry.lock @@ -42,13 +42,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.0" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.0-py3-none-any.whl", hash = "sha256:c499373822566642203dcc5d5c4e987a3e95f50c639d88573fdb8870a5d94bb3"}, + {file = "airbyte_protocol_models-0.14.0.tar.gz", hash = "sha256:05a6769e51491fb733e6b63426f3daafadbf38b9d23038b64ba35979862bef15"}, ] [package.dependencies] @@ -56,13 +56,13 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.0" +version = "4.6.2.post1" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.0-py3-none-any.whl", hash = "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a"}, - {file = "anyio-4.6.0.tar.gz", hash = "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb"}, + {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, + {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, ] [package.dependencies] @@ -73,7 +73,7 @@ typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} [package.extras] doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.21.0b1)"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -457,20 +457,20 @@ langdetect = ["langdetect"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -534,13 +534,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -715,156 +715,174 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.134" +version = "0.1.145" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.134-py3-none-any.whl", hash = "sha256:ada98ad80ef38807725f32441a472da3dd28394010877751f48f458d3289da04"}, - {file = "langsmith-0.1.134.tar.gz", hash = "sha256:23abee3b508875a0e63c602afafffc02442a19cfd88f9daae05b3e9054fd6b61"}, + {file = "langsmith-0.1.145-py3-none-any.whl", hash = "sha256:bd3001fc6738ad9061a2709d60f62a6bdf4892a17e63c7751f73a6f32a100729"}, + {file = "langsmith-0.1.145.tar.gz", hash = "sha256:b6e53f7b1624846f03769a1fce673baf2a0a262b4f4129b1f6bd127a1f44f8fd"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" [[package]] name = "markupsafe" -version = "3.0.1" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" files = [ - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win32.whl", hash = "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win32.whl", hash = "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win32.whl", hash = "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win32.whl", hash = "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win32.whl", hash = "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b"}, - {file = "markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] name = "orjson" -version = "3.10.7" +version = "3.10.12" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:74f4544f5a6405b90da8ea724d15ac9c36da4d72a738c64685003337401f5c12"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34a566f22c28222b08875b18b0dfbf8a947e69df21a9ed5c51a6bf91cfb944ac"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf6ba8ebc8ef5792e2337fb0419f8009729335bb400ece005606336b7fd7bab7"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac7cf6222b29fbda9e3a472b41e6a5538b48f2c8f99261eecd60aafbdb60690c"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de817e2f5fc75a9e7dd350c4b0f54617b280e26d1631811a43e7e968fa71e3e9"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:348bdd16b32556cf8d7257b17cf2bdb7ab7976af4af41ebe79f9796c218f7e91"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:479fd0844ddc3ca77e0fd99644c7fe2de8e8be1efcd57705b5c92e5186e8a250"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fdf5197a21dd660cf19dfd2a3ce79574588f8f5e2dbf21bda9ee2d2b46924d84"}, - {file = "orjson-3.10.7-cp310-none-win32.whl", hash = "sha256:d374d36726746c81a49f3ff8daa2898dccab6596864ebe43d50733275c629175"}, - {file = "orjson-3.10.7-cp310-none-win_amd64.whl", hash = "sha256:cb61938aec8b0ffb6eef484d480188a1777e67b05d58e41b435c74b9d84e0b9c"}, - {file = "orjson-3.10.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0"}, - {file = "orjson-3.10.7-cp311-none-win32.whl", hash = "sha256:82763b46053727a7168d29c772ed5c870fdae2f61aa8a25994c7984a19b1021f"}, - {file = "orjson-3.10.7-cp311-none-win_amd64.whl", hash = "sha256:eb8d384a24778abf29afb8e41d68fdd9a156cf6e5390c04cc07bbc24b89e98b5"}, - {file = "orjson-3.10.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44a96f2d4c3af51bfac6bc4ef7b182aa33f2f054fd7f34cc0ee9a320d051d41f"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ac14cd57df0572453543f8f2575e2d01ae9e790c21f57627803f5e79b0d3c3"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bdbb61dcc365dd9be94e8f7df91975edc9364d6a78c8f7adb69c1cdff318ec93"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b48b3db6bb6e0a08fa8c83b47bc169623f801e5cc4f24442ab2b6617da3b5313"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23820a1563a1d386414fef15c249040042b8e5d07b40ab3fe3efbfbbcbcb8864"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0c6a008e91d10a2564edbb6ee5069a9e66df3fbe11c9a005cb411f441fd2c09"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d352ee8ac1926d6193f602cbe36b1643bbd1bbcb25e3c1a657a4390f3000c9a5"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b"}, - {file = "orjson-3.10.7-cp312-none-win32.whl", hash = "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb"}, - {file = "orjson-3.10.7-cp312-none-win_amd64.whl", hash = "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1"}, - {file = "orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149"}, - {file = "orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad"}, - {file = "orjson-3.10.7-cp313-none-win32.whl", hash = "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2"}, - {file = "orjson-3.10.7-cp313-none-win_amd64.whl", hash = "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024"}, - {file = "orjson-3.10.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6ea2b2258eff652c82652d5e0f02bd5e0463a6a52abb78e49ac288827aaa1469"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:430ee4d85841e1483d487e7b81401785a5dfd69db5de01314538f31f8fbf7ee1"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b6146e439af4c2472c56f8540d799a67a81226e11992008cb47e1267a9b3225"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:084e537806b458911137f76097e53ce7bf5806dda33ddf6aaa66a028f8d43a23"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829cf2195838e3f93b70fd3b4292156fc5e097aac3739859ac0dcc722b27ac0"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1193b2416cbad1a769f868b1749535d5da47626ac29445803dae7cc64b3f5c98"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4e6c3da13e5a57e4b3dca2de059f243ebec705857522f188f0180ae88badd354"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c31008598424dfbe52ce8c5b47e0752dca918a4fdc4a2a32004efd9fab41d866"}, - {file = "orjson-3.10.7-cp38-none-win32.whl", hash = "sha256:7122a99831f9e7fe977dc45784d3b2edc821c172d545e6420c375e5a935f5a1c"}, - {file = "orjson-3.10.7-cp38-none-win_amd64.whl", hash = "sha256:a763bc0e58504cc803739e7df040685816145a6f3c8a589787084b54ebc9f16e"}, - {file = "orjson-3.10.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e76be12658a6fa376fcd331b1ea4e58f5a06fd0220653450f0d415b8fd0fbe20"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed350d6978d28b92939bfeb1a0570c523f6170efc3f0a0ef1f1df287cd4f4960"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144888c76f8520e39bfa121b31fd637e18d4cc2f115727865fdf9fa325b10412"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09b2d92fd95ad2402188cf51573acde57eb269eddabaa60f69ea0d733e789fe9"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b24a579123fa884f3a3caadaed7b75eb5715ee2b17ab5c66ac97d29b18fe57f"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591bcfe7512353bd609875ab38050efe3d55e18934e2f18950c108334b4ff"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f4db56635b58cd1a200b0a23744ff44206ee6aa428185e2b6c4a65b3197abdcd"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0fa5886854673222618638c6df7718ea7fe2f3f2384c452c9ccedc70b4a510a5"}, - {file = "orjson-3.10.7-cp39-none-win32.whl", hash = "sha256:8272527d08450ab16eb405f47e0f4ef0e5ff5981c3d82afe0efd25dcbef2bcd2"}, - {file = "orjson-3.10.7-cp39-none-win_amd64.whl", hash = "sha256:974683d4618c0c7dbf4f69c95a979734bf183d0658611760017f6e70a145af58"}, - {file = "orjson-3.10.7.tar.gz", hash = "sha256:75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3"}, + {file = "orjson-3.10.12-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ece01a7ec71d9940cc654c482907a6b65df27251255097629d0dea781f255c6d"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c34ec9aebc04f11f4b978dd6caf697a2df2dd9b47d35aa4cc606cabcb9df69d7"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd6ec8658da3480939c79b9e9e27e0db31dffcd4ba69c334e98c9976ac29140e"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f17e6baf4cf01534c9de8a16c0c611f3d94925d1701bf5f4aff17003677d8ced"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6402ebb74a14ef96f94a868569f5dccf70d791de49feb73180eb3c6fda2ade56"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0000758ae7c7853e0a4a6063f534c61656ebff644391e1f81698c1b2d2fc8cd2"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:888442dcee99fd1e5bd37a4abb94930915ca6af4db50e23e746cdf4d1e63db13"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c1f7a3ce79246aa0e92f5458d86c54f257fb5dfdc14a192651ba7ec2c00f8a05"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:802a3935f45605c66fb4a586488a38af63cb37aaad1c1d94c982c40dcc452e85"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1da1ef0113a2be19bb6c557fb0ec2d79c92ebd2fed4cfb1b26bab93f021fb885"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a3273e99f367f137d5b3fecb5e9f45bcdbfac2a8b2f32fbc72129bbd48789c2"}, + {file = "orjson-3.10.12-cp310-none-win32.whl", hash = "sha256:475661bf249fd7907d9b0a2a2421b4e684355a77ceef85b8352439a9163418c3"}, + {file = "orjson-3.10.12-cp310-none-win_amd64.whl", hash = "sha256:87251dc1fb2b9e5ab91ce65d8f4caf21910d99ba8fb24b49fd0c118b2362d509"}, + {file = "orjson-3.10.12-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a734c62efa42e7df94926d70fe7d37621c783dea9f707a98cdea796964d4cf74"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:750f8b27259d3409eda8350c2919a58b0cfcd2054ddc1bd317a643afc646ef23"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb52c22bfffe2857e7aa13b4622afd0dd9d16ea7cc65fd2bf318d3223b1b6252"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:440d9a337ac8c199ff8251e100c62e9488924c92852362cd27af0e67308c16ef"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9e15c06491c69997dfa067369baab3bf094ecb74be9912bdc4339972323f252"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:362d204ad4b0b8724cf370d0cd917bb2dc913c394030da748a3bb632445ce7c4"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2b57cbb4031153db37b41622eac67329c7810e5f480fda4cfd30542186f006ae"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:165c89b53ef03ce0d7c59ca5c82fa65fe13ddf52eeb22e859e58c237d4e33b9b"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5dee91b8dfd54557c1a1596eb90bcd47dbcd26b0baaed919e6861f076583e9da"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77a4e1cfb72de6f905bdff061172adfb3caf7a4578ebf481d8f0530879476c07"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:038d42c7bc0606443459b8fe2d1f121db474c49067d8d14c6a075bbea8bf14dd"}, + {file = "orjson-3.10.12-cp311-none-win32.whl", hash = "sha256:03b553c02ab39bed249bedd4abe37b2118324d1674e639b33fab3d1dafdf4d79"}, + {file = "orjson-3.10.12-cp311-none-win_amd64.whl", hash = "sha256:8b8713b9e46a45b2af6b96f559bfb13b1e02006f4242c156cbadef27800a55a8"}, + {file = "orjson-3.10.12-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:53206d72eb656ca5ac7d3a7141e83c5bbd3ac30d5eccfe019409177a57634b0d"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac8010afc2150d417ebda810e8df08dd3f544e0dd2acab5370cfa6bcc0662f8f"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed459b46012ae950dd2e17150e838ab08215421487371fa79d0eced8d1461d70"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dcb9673f108a93c1b52bfc51b0af422c2d08d4fc710ce9c839faad25020bb69"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22a51ae77680c5c4652ebc63a83d5255ac7d65582891d9424b566fb3b5375ee9"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910fdf2ac0637b9a77d1aad65f803bac414f0b06f720073438a7bd8906298192"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:24ce85f7100160936bc2116c09d1a8492639418633119a2224114f67f63a4559"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a76ba5fc8dd9c913640292df27bff80a685bed3a3c990d59aa6ce24c352f8fc"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ff70ef093895fd53f4055ca75f93f047e088d1430888ca1229393a7c0521100f"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f4244b7018b5753ecd10a6d324ec1f347da130c953a9c88432c7fbc8875d13be"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:16135ccca03445f37921fa4b585cff9a58aa8d81ebcb27622e69bfadd220b32c"}, + {file = "orjson-3.10.12-cp312-none-win32.whl", hash = "sha256:2d879c81172d583e34153d524fcba5d4adafbab8349a7b9f16ae511c2cee8708"}, + {file = "orjson-3.10.12-cp312-none-win_amd64.whl", hash = "sha256:fc23f691fa0f5c140576b8c365bc942d577d861a9ee1142e4db468e4e17094fb"}, + {file = "orjson-3.10.12-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:47962841b2a8aa9a258b377f5188db31ba49af47d4003a32f55d6f8b19006543"}, + {file = "orjson-3.10.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6334730e2532e77b6054e87ca84f3072bee308a45a452ea0bffbbbc40a67e296"}, + {file = "orjson-3.10.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:accfe93f42713c899fdac2747e8d0d5c659592df2792888c6c5f829472e4f85e"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a7974c490c014c48810d1dede6c754c3cc46598da758c25ca3b4001ac45b703f"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3f250ce7727b0b2682f834a3facff88e310f52f07a5dcfd852d99637d386e79e"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f31422ff9486ae484f10ffc51b5ab2a60359e92d0716fcce1b3593d7bb8a9af6"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5f29c5d282bb2d577c2a6bbde88d8fdcc4919c593f806aac50133f01b733846e"}, + {file = "orjson-3.10.12-cp313-none-win32.whl", hash = "sha256:f45653775f38f63dc0e6cd4f14323984c3149c05d6007b58cb154dd080ddc0dc"}, + {file = "orjson-3.10.12-cp313-none-win_amd64.whl", hash = "sha256:229994d0c376d5bdc91d92b3c9e6be2f1fbabd4cc1b59daae1443a46ee5e9825"}, + {file = "orjson-3.10.12-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7d69af5b54617a5fac5c8e5ed0859eb798e2ce8913262eb522590239db6c6763"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ed119ea7d2953365724a7059231a44830eb6bbb0cfead33fcbc562f5fd8f935"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9c5fc1238ef197e7cad5c91415f524aaa51e004be5a9b35a1b8a84ade196f73f"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43509843990439b05f848539d6f6198d4ac86ff01dd024b2f9a795c0daeeab60"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f72e27a62041cfb37a3de512247ece9f240a561e6c8662276beaf4d53d406db4"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a904f9572092bb6742ab7c16c623f0cdccbad9eeb2d14d4aa06284867bddd31"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:855c0833999ed5dc62f64552db26f9be767434917d8348d77bacaab84f787d7b"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:897830244e2320f6184699f598df7fb9db9f5087d6f3f03666ae89d607e4f8ed"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0b32652eaa4a7539f6f04abc6243619c56f8530c53bf9b023e1269df5f7816dd"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:36b4aa31e0f6a1aeeb6f8377769ca5d125db000f05c20e54163aef1d3fe8e833"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5535163054d6cbf2796f93e4f0dbc800f61914c0e3c4ed8499cf6ece22b4a3da"}, + {file = "orjson-3.10.12-cp38-none-win32.whl", hash = "sha256:90a5551f6f5a5fa07010bf3d0b4ca2de21adafbbc0af6cb700b63cd767266cb9"}, + {file = "orjson-3.10.12-cp38-none-win_amd64.whl", hash = "sha256:703a2fb35a06cdd45adf5d733cf613cbc0cb3ae57643472b16bc22d325b5fb6c"}, + {file = "orjson-3.10.12-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f29de3ef71a42a5822765def1febfb36e0859d33abf5c2ad240acad5c6a1b78d"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de365a42acc65d74953f05e4772c974dad6c51cfc13c3240899f534d611be967"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:91a5a0158648a67ff0004cb0df5df7dcc55bfc9ca154d9c01597a23ad54c8d0c"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c47ce6b8d90fe9646a25b6fb52284a14ff215c9595914af63a5933a49972ce36"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0eee4c2c5bfb5c1b47a5db80d2ac7aaa7e938956ae88089f098aff2c0f35d5d8"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35d3081bbe8b86587eb5c98a73b97f13d8f9fea685cf91a579beddacc0d10566"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73c23a6e90383884068bc2dba83d5222c9fcc3b99a0ed2411d38150734236755"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5472be7dc3269b4b52acba1433dac239215366f89dc1d8d0e64029abac4e714e"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:7319cda750fca96ae5973efb31b17d97a5c5225ae0bc79bf5bf84df9e1ec2ab6"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:74d5ca5a255bf20b8def6a2b96b1e18ad37b4a122d59b154c458ee9494377f80"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ff31d22ecc5fb85ef62c7d4afe8301d10c558d00dd24274d4bbe464380d3cd69"}, + {file = "orjson-3.10.12-cp39-none-win32.whl", hash = "sha256:c22c3ea6fba91d84fcb4cda30e64aff548fcf0c44c876e681f47d61d24b12e6b"}, + {file = "orjson-3.10.12-cp39-none-win_amd64.whl", hash = "sha256:be604f60d45ace6b0b33dd990a66b4526f1a7a186ac411c942674625456ca548"}, + {file = "orjson-3.10.12.tar.gz", hash = "sha256:0a78bbda3aea0f9f079057ee1ee8a1ecf790d4f1af88dd67493c6b8ee52506ff"}, ] [[package]] @@ -967,54 +985,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -1026,13 +1044,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.0" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.0-py3-none-any.whl", hash = "sha256:543b77207db656de204372350926bed5a86201c4cbff159f623f79c7bb487a15"}, + {file = "pyjwt-2.10.0.tar.gz", hash = "sha256:7628a7eb7938959ac1b26e819a1df0fd3259505627b575e4bad6d08f76db695c"}, ] [package.extras] @@ -1238,105 +1256,105 @@ files = [ [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -1425,23 +1443,23 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.1.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"}, - {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" @@ -1577,92 +1595,87 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [[package]] name = "xmltodict" -version = "0.14.1" +version = "0.14.2" description = "Makes working with XML feel like you are working with JSON" optional = false python-versions = ">=3.6" files = [ - {file = "xmltodict-0.14.1-py2.py3-none-any.whl", hash = "sha256:3ef4a7b71c08f19047fcbea572e1d7f4207ab269da1565b5d40e9823d3894e63"}, - {file = "xmltodict-0.14.1.tar.gz", hash = "sha256:338c8431e4fc554517651972d62f06958718f6262b04316917008e8fd677a6b0"}, + {file = "xmltodict-0.14.2-py2.py3-none-any.whl", hash = "sha256:20cc7d723ed729276e808f26fb6b3599f786cbc37e06c65e192ba77c40f20aac"}, + {file = "xmltodict-0.14.2.tar.gz", hash = "sha256:201e7c28bb210e374999d1dde6382923ab0ed1a8a5faeece48ab525b7810a553"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/pyproject.toml b/airbyte-integrations/connectors/source-amazon-seller-partner/pyproject.toml index b20d29cbf643..542236d1dfa5 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/pyproject.toml +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/pyproject.toml @@ -3,7 +3,7 @@ requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "4.4.4" +version = "4.4.7" name = "source-amazon-seller-partner" description = "Source implementation for Amazon Seller Partner." authors = ["Airbyte "] diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/auth.py b/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/auth.py index 4bdaab19df35..d062e1d85046 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/auth.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/auth.py @@ -6,6 +6,7 @@ from typing import Any, Mapping import pendulum + from airbyte_cdk.sources.streams.http.auth import Oauth2Authenticator diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/config_migrations.py b/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/config_migrations.py index 39a7055af1b7..b98903bd9863 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/config_migrations.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/config_migrations.py @@ -12,6 +12,7 @@ from .source import SourceAmazonSellerPartner + logger = logging.getLogger("airbyte_logger") diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/constants.py b/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/constants.py index 4b0e1e99bbe5..618a808ba0c3 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/constants.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/constants.py @@ -31,6 +31,7 @@ Australia A39IBJ37TRP1C6 AU Japan A1VC38T7YXB528 JP """ + from enum import Enum from typing import Dict, Tuple diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/source.py b/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/source.py index f24974868a78..623e103127c7 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/source.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/source.py @@ -7,12 +7,13 @@ from typing import Any, List, Mapping, Optional, Tuple import pendulum +from requests import HTTPError + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.utils import AirbyteTracedException, is_cloud_environment from airbyte_protocol.models import ConnectorSpecification -from requests import HTTPError from source_amazon_seller_partner.auth import AWSAuthenticator from source_amazon_seller_partner.constants import get_marketplaces from source_amazon_seller_partner.streams import ( @@ -73,6 +74,7 @@ ) from source_amazon_seller_partner.utils import AmazonConfigException + # given the retention period: 730 DEFAULT_RETENTION_PERIOD_IN_DAYS = 730 @@ -107,7 +109,7 @@ def _get_stream_kwargs(config: Mapping[str, Any]) -> Mapping[str, Any]: "authenticator": auth, "replication_start_date": start_date, "marketplace_id": marketplace_id, - "period_in_days": config.get("period_in_days", 30), + "period_in_days": config.get("period_in_days", 365), "replication_end_date": end_date, } return stream_kwargs diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/streams.py b/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/streams.py index 1715c5b2ccba..a414590399a0 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/streams.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/streams.py @@ -17,11 +17,11 @@ import pendulum import requests import xmltodict + from airbyte_cdk.entrypoint import logger from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.streams.core import CheckpointMixin, package_name_from_class from airbyte_cdk.sources.streams.http import HttpStream -from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException from airbyte_cdk.sources.streams.http.rate_limiting import default_backoff_handler from airbyte_cdk.sources.utils.schema_helpers import ResourceSchemaLoader from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer @@ -29,6 +29,7 @@ from airbyte_protocol.models import FailureType from source_amazon_seller_partner.utils import STREAM_THRESHOLD_PERIOD, threshold_period_decorator + REPORTS_API_VERSION = "2021-06-30" ORDERS_API_VERSION = "v0" VENDORS_API_VERSION = "v1" @@ -232,7 +233,7 @@ def __init__( self._replication_start_date = replication_start_date self._replication_end_date = replication_end_date self.marketplace_id = marketplace_id - self.period_in_days = max(period_in_days, self.replication_start_date_limit_in_days) # ensure old configs work + self.period_in_days = min(period_in_days, self.replication_start_date_limit_in_days) # ensure old configs work self._report_options = report_options self._http_method = "GET" self._stream_name = stream_name @@ -575,6 +576,7 @@ class FlatFileOrdersReports(IncrementalReportsAmazonSPStream): report_name = "GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL" primary_key = "amazon-order-id" cursor_field = "last-updated-date" + replication_start_date_limit_in_days = 30 class FbaStorageFeesReports(IncrementalReportsAmazonSPStream): diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/utils.py b/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/utils.py index 6c340ecfe566..7696b235dae6 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/utils.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/utils.py @@ -7,6 +7,7 @@ from airbyte_cdk.utils import AirbyteTracedException from airbyte_protocol.models import FailureType + LOG_LEVEL = logging.getLevelName("INFO") LOGGER = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/conftest.py b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/conftest.py index 12579417383d..6165eea8d437 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/conftest.py @@ -8,6 +8,7 @@ import pytest + os.environ["DEPLOYMENT_MODE"] = "testing" @@ -25,10 +26,7 @@ def init_kwargs() -> Dict[str, Any]: @pytest.fixture def report_init_kwargs(init_kwargs) -> Dict[str, Any]: - return { - "stream_name": "GET_TEST_REPORT", - **init_kwargs - } + return {"stream_name": "GET_TEST_REPORT", **init_kwargs} @pytest.fixture diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/config.py b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/config.py index 75cccd73e380..05c8b5c47d34 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/config.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/config.py @@ -10,6 +10,7 @@ import pendulum + ACCESS_TOKEN = "test_access_token" LWA_APP_ID = "amazon_app_id" LWA_CLIENT_SECRET = "amazon_client_secret" diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/pagination.py b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/pagination.py index 79b1528ed038..7d7a549dcc53 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/pagination.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/pagination.py @@ -7,6 +7,7 @@ from airbyte_cdk.test.mock_http.response_builder import PaginationStrategy + NEXT_TOKEN_STRING = "MDAwMDAwMDAwMQ==" diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/test_report_based_streams.py b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/test_report_based_streams.py index 1225aa30b181..1a23c7c99549 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/test_report_based_streams.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/test_report_based_streams.py @@ -11,17 +11,19 @@ import freezegun import pytest import requests_mock +from source_amazon_seller_partner.streams import ReportProcessingStatus + from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput from airbyte_cdk.test.mock_http import HttpMocker, HttpResponse from airbyte_cdk.test.mock_http.matcher import HttpRequestMatcher from airbyte_protocol.models import AirbyteStateMessage, FailureType, SyncMode -from source_amazon_seller_partner.streams import ReportProcessingStatus from .config import CONFIG_END_DATE, CONFIG_START_DATE, MARKETPLACE_ID, NOW, VENDOR_TRAFFIC_REPORT_CONFIG_END_DATE, ConfigBuilder from .request_builder import RequestBuilder from .response_builder import build_response, response_with_status from .utils import assert_message_in_log_output, config, find_template, get_stream_by_name, mock_auth, read_output + _DOCUMENT_DOWNLOAD_URL = "https://test.com/download" _REPORT_ID = "6789087632" _REPORT_DOCUMENT_ID = "report_document_id" @@ -447,14 +449,16 @@ def test_given_http_error_500_on_create_report_when_read_then_no_records_and_err @pytest.mark.parametrize(("stream_name", "data_format"), STREAMS) @HttpMocker() def test_given_http_error_not_support_account_id_of_type_vendor_when_read_then_no_records_and_error_logged( - self, stream_name: str, data_format: str, http_mocker: HttpMocker + self, stream_name: str, data_format: str, http_mocker: HttpMocker ): mock_auth(http_mocker) response_body = { "errors": [ - {"code": "InvalidInput", - "message": "Report type 301 does not support account ID of type class com.amazon.partner.account.id.VendorGroupId.", - "details": ""} + { + "code": "InvalidInput", + "message": "Report type 301 does not support account ID of type class com.amazon.partner.account.id.VendorGroupId.", + "details": "", + } ] } http_mocker.post( diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/test_vendor_direct_fulfillment_shipping.py b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/test_vendor_direct_fulfillment_shipping.py index f3eccb1b2615..35f2a10b7ec8 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/test_vendor_direct_fulfillment_shipping.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/test_vendor_direct_fulfillment_shipping.py @@ -8,6 +8,7 @@ import freezegun import pendulum + from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput from airbyte_cdk.test.mock_http import HttpMocker from airbyte_cdk.test.mock_http.response_builder import ( @@ -28,6 +29,7 @@ from .response_builder import response_with_status from .utils import config, mock_auth, read_output + _START_DATE = pendulum.datetime(year=2023, month=1, day=1) _END_DATE = pendulum.datetime(year=2023, month=1, day=5) _REPLICATION_START_FIELD = "createdAfter" diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/test_vendor_orders.py b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/test_vendor_orders.py index a1416a505328..3937e7fc0873 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/test_vendor_orders.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/test_vendor_orders.py @@ -8,6 +8,7 @@ import freezegun import pendulum + from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput from airbyte_cdk.test.mock_http import HttpMocker from airbyte_cdk.test.mock_http.response_builder import ( @@ -28,6 +29,7 @@ from .response_builder import response_with_status from .utils import config, mock_auth, read_output + _START_DATE = pendulum.datetime(year=2023, month=1, day=1) _END_DATE = pendulum.datetime(year=2023, month=1, day=5) _REPLICATION_START_FIELD = "changedAfter" diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/utils.py b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/utils.py index 099f99f42f39..91b7f7c511d2 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/utils.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/integration/utils.py @@ -7,13 +7,14 @@ from http import HTTPStatus from typing import Any, List, Mapping, Optional +from source_amazon_seller_partner import SourceAmazonSellerPartner + from airbyte_cdk.sources.streams import Stream from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read from airbyte_cdk.test.mock_http import HttpMocker from airbyte_cdk.test.mock_http.response_builder import _get_unit_test_folder from airbyte_protocol.models import AirbyteStateMessage, ConfiguredAirbyteCatalog, Level, SyncMode -from source_amazon_seller_partner import SourceAmazonSellerPartner from .config import ACCESS_TOKEN, ConfigBuilder from .request_builder import RequestBuilder diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_analytics_streams.py b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_analytics_streams.py index 1006cbc9080d..16b924b9c800 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_analytics_streams.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_analytics_streams.py @@ -7,9 +7,10 @@ import pendulum import pytest -from airbyte_cdk.models import SyncMode from source_amazon_seller_partner.streams import AnalyticsStream, IncrementalAnalyticsStream +from airbyte_cdk.models import SyncMode + class SomeAnalyticsStream(AnalyticsStream): report_name = "GET_ANALYTICS_STREAM" @@ -141,6 +142,7 @@ def test_get_updated_state(self, report_init_kwargs, current_stream_state, lates def test_stream_slices(self, report_init_kwargs, start_date, end_date, stream_state, fixed_period_in_days, expected_slices): report_init_kwargs["replication_start_date"] = start_date report_init_kwargs["replication_end_date"] = end_date + report_init_kwargs["period_in_days"] = 365 stream = SomeIncrementalAnalyticsStream(**report_init_kwargs) stream.fixed_period_in_days = fixed_period_in_days with patch("pendulum.now", return_value=pendulum.parse("2023-09-09T00:00:00Z")): diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_finance_streams.py b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_finance_streams.py index 385699cc5844..46360c3737d6 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_finance_streams.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_finance_streams.py @@ -8,10 +8,12 @@ import pendulum import pytest import requests +from source_amazon_seller_partner.streams import ListFinancialEventGroups, ListFinancialEvents, RestockInventoryReports + from airbyte_cdk.models import SyncMode from airbyte_cdk.utils import AirbyteTracedException from airbyte_protocol.models import FailureType -from source_amazon_seller_partner.streams import ListFinancialEventGroups, ListFinancialEvents, RestockInventoryReports + list_financial_event_groups_data = { "payload": { @@ -211,15 +213,7 @@ def test_reports_read_records_raise_on_backoff(mocker, requests_mock, caplog): requests_mock.post( "https://test.url/reports/2021-06-30/reports", status_code=429, - json={ - "errors": [ - { - "code": "QuotaExceeded", - "message": "You exceeded your quota for the requested resource.", - "details": "" - } - ] - }, + json={"errors": [{"code": "QuotaExceeded", "message": "You exceeded your quota for the requested resource.", "details": ""}]}, ) stream = RestockInventoryReports( diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_migrations.py b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_migrations.py index 058dfc514d77..533c96df2e5d 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_migrations.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_migrations.py @@ -7,11 +7,13 @@ from typing import Any, Mapping import pytest -from airbyte_cdk.models import OrchestratorType, Type -from airbyte_cdk.sources import Source from source_amazon_seller_partner.config_migrations import MigrateAccountType, MigrateReportOptions, MigrateStreamNameOption from source_amazon_seller_partner.source import SourceAmazonSellerPartner +from airbyte_cdk.models import OrchestratorType, Type +from airbyte_cdk.sources import Source + + CMD = "check" SOURCE: Source = SourceAmazonSellerPartner() diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_reports_streams_settlement_report.py b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_reports_streams_settlement_report.py index 2d50e3adcb9f..afd6f6e3c1eb 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_reports_streams_settlement_report.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_reports_streams_settlement_report.py @@ -4,9 +4,11 @@ import pytest -from airbyte_cdk.models import SyncMode from source_amazon_seller_partner.streams import FlatFileSettlementV2Reports +from airbyte_cdk.models import SyncMode + + START_DATE_1 = "2022-05-25T00:00:00Z" END_DATE_1 = "2022-05-26T00:00:00Z" diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_source.py b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_source.py index a77cf2bd0b07..1bc7f5dab48f 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_source.py @@ -7,11 +7,13 @@ from unittest.mock import patch import pytest -from airbyte_cdk.sources.streams import Stream from source_amazon_seller_partner import SourceAmazonSellerPartner from source_amazon_seller_partner.streams import VendorOrders from source_amazon_seller_partner.utils import AmazonConfigException +from airbyte_cdk.sources.streams import Stream + + logger = logging.getLogger("airbyte") @@ -124,19 +126,23 @@ def test_check_connection_with_orders(requests_mock, connector_config_with_repor ( "GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA", [ - ("GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA", + ( + "GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA", [ {"option_name": "some_name_1", "option_value": "some_value_1"}, {"option_name": "some_name_2", "option_value": "some_value_2"}, ], - ), - ] + ), + ], ), ("SOME_OTHER_STREAM", []), ), ) def test_get_stream_report_options_list(connector_config_with_report_options, report_name, stream_name_w_options): - assert list(SourceAmazonSellerPartner().get_stream_report_kwargs(report_name, connector_config_with_report_options)) == stream_name_w_options + assert ( + list(SourceAmazonSellerPartner().get_stream_report_kwargs(report_name, connector_config_with_report_options)) + == stream_name_w_options + ) def test_config_report_options_validation_error_duplicated_streams(connector_config_with_report_options): @@ -199,7 +205,9 @@ def test_spec(deployment_mode, common_streams_count, monkeypatch): "GET_VENDOR_NET_PURE_PRODUCT_MARGIN_REPORT", "GET_VENDOR_TRAFFIC_REPORT", } - streams_with_report_options = SourceAmazonSellerPartner().spec( - logger - ).connectionSpecification["properties"]["report_options_list"]["items"]["properties"]["report_name"]["enum"] + streams_with_report_options = ( + SourceAmazonSellerPartner() + .spec(logger) + .connectionSpecification["properties"]["report_options_list"]["items"]["properties"]["report_name"]["enum"] + ) assert len(set(streams_with_report_options).intersection(oss_only_streams)) == common_streams_count diff --git a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_streams.py index 54c8bc037277..8d5857ec491e 100644 --- a/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_streams.py @@ -8,9 +8,6 @@ import pendulum import pytest import requests -from airbyte_cdk.models import SyncMode -from airbyte_cdk.utils import AirbyteTracedException -from airbyte_protocol.models import FailureType from source_amazon_seller_partner.streams import ( IncrementalReportsAmazonSPStream, ReportProcessingStatus, @@ -18,6 +15,10 @@ VendorDirectFulfillmentShipping, ) +from airbyte_cdk.models import SyncMode +from airbyte_cdk.utils import AirbyteTracedException +from airbyte_protocol.models import FailureType + class SomeReportStream(ReportsAmazonSPStream): report_name = "GET_TEST_REPORT" @@ -85,6 +86,7 @@ def test_report_data(self, report_init_kwargs): def test_stream_slices(self, report_init_kwargs, start_date, end_date, expected_slices): report_init_kwargs["replication_start_date"] = start_date report_init_kwargs["replication_end_date"] = end_date + report_init_kwargs["period_in_days"] = 365 stream = SomeReportStream(**report_init_kwargs) with patch("pendulum.now", return_value=pendulum.parse("2023-01-01T00:00:00Z")): @@ -245,15 +247,7 @@ def test_given_429_when_read_records_then_raise_transient_error(self, report_ini "POST", "https://test.url/reports/2021-06-30/reports", status_code=429, - json={ - "errors": [ - { - "code": "QuotaExceeded", - "message": "You exceeded your quota for the requested resource.", - "details": "" - } - ] - }, + json={"errors": [{"code": "QuotaExceeded", "message": "You exceeded your quota for the requested resource.", "details": ""}]}, reason="Forbidden", ) @@ -301,6 +295,7 @@ class TestVendorFulfillment: def test_stream_slices(self, init_kwargs, start_date, end_date, stream_state, expected_slices): init_kwargs["replication_start_date"] = start_date init_kwargs["replication_end_date"] = end_date + init_kwargs["period_in_days"] = 365 stream = VendorDirectFulfillmentShipping(**init_kwargs) with patch("pendulum.now", return_value=pendulum.parse("2022-09-05T00:00:00Z")): diff --git a/airbyte-integrations/connectors/source-amazon-sqs/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-amazon-sqs/integration_tests/acceptance.py index 43ce950d77ca..72132012aaed 100644 --- a/airbyte-integrations/connectors/source-amazon-sqs/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-amazon-sqs/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-amazon-sqs/main.py b/airbyte-integrations/connectors/source-amazon-sqs/main.py index 3e218a144f8f..3d9850f97f6d 100644 --- a/airbyte-integrations/connectors/source-amazon-sqs/main.py +++ b/airbyte-integrations/connectors/source-amazon-sqs/main.py @@ -4,5 +4,6 @@ from source_amazon_sqs.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-amazon-sqs/setup.py b/airbyte-integrations/connectors/source-amazon-sqs/setup.py index e39e0d894b21..3ba1991d471a 100644 --- a/airbyte-integrations/connectors/source-amazon-sqs/setup.py +++ b/airbyte-integrations/connectors/source-amazon-sqs/setup.py @@ -5,6 +5,7 @@ from setuptools import find_packages, setup + MAIN_REQUIREMENTS = ["airbyte-cdk", "boto3"] TEST_REQUIREMENTS = ["requests-mock~=1.9.3", "pytest-mock~=3.6.1", "pytest~=6.1", "moto[sqs, iam]"] diff --git a/airbyte-integrations/connectors/source-amazon-sqs/source_amazon_sqs/source.py b/airbyte-integrations/connectors/source-amazon-sqs/source_amazon_sqs/source.py index 6472649a9b9e..4aedc4e71d9c 100644 --- a/airbyte-integrations/connectors/source-amazon-sqs/source_amazon_sqs/source.py +++ b/airbyte-integrations/connectors/source-amazon-sqs/source_amazon_sqs/source.py @@ -8,6 +8,8 @@ from typing import Dict, Generator import boto3 +from botocore.exceptions import ClientError + from airbyte_cdk.logger import AirbyteLogger from airbyte_cdk.models import ( AirbyteCatalog, @@ -20,7 +22,6 @@ Type, ) from airbyte_cdk.sources.source import Source -from botocore.exceptions import ClientError class SourceAmazonSqs(Source): diff --git a/airbyte-integrations/connectors/source-amazon-sqs/unit_tests/unit_test.py b/airbyte-integrations/connectors/source-amazon-sqs/unit_tests/unit_test.py index 28ead98ff99c..511b2081c087 100644 --- a/airbyte-integrations/connectors/source-amazon-sqs/unit_tests/unit_test.py +++ b/airbyte-integrations/connectors/source-amazon-sqs/unit_tests/unit_test.py @@ -6,14 +6,15 @@ from typing import Any, Dict, Mapping import boto3 -from airbyte_cdk.logger import AirbyteLogger -from airbyte_cdk.models import ConfiguredAirbyteCatalog, Status # from airbyte_cdk.sources.source import Source from moto import mock_iam, mock_sqs from moto.core import set_initial_no_auth_action_count from source_amazon_sqs import SourceAmazonSqs +from airbyte_cdk.logger import AirbyteLogger +from airbyte_cdk.models import ConfiguredAirbyteCatalog, Status + @mock_iam def create_user_with_all_permissions(): diff --git a/airbyte-integrations/connectors/source-amplitude/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-amplitude/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-amplitude/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-amplitude/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-amplitude/integration_tests/integration_test.py b/airbyte-integrations/connectors/source-amplitude/integration_tests/integration_test.py index cb2230f94ead..c0b6f7e64019 100755 --- a/airbyte-integrations/connectors/source-amplitude/integration_tests/integration_test.py +++ b/airbyte-integrations/connectors/source-amplitude/integration_tests/integration_test.py @@ -7,9 +7,10 @@ from pathlib import Path import pytest +from source_amplitude.source import SourceAmplitude + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.declarative.types import StreamSlice -from source_amplitude.source import SourceAmplitude @pytest.fixture(scope="module") diff --git a/airbyte-integrations/connectors/source-amplitude/main.py b/airbyte-integrations/connectors/source-amplitude/main.py index 14500e9c73e6..66dbbbcd80bf 100644 --- a/airbyte-integrations/connectors/source-amplitude/main.py +++ b/airbyte-integrations/connectors/source-amplitude/main.py @@ -4,5 +4,6 @@ from source_amplitude.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-amplitude/metadata.yaml b/airbyte-integrations/connectors/source-amplitude/metadata.yaml index fb6e248d81ab..7a0e79432c33 100644 --- a/airbyte-integrations/connectors/source-amplitude/metadata.yaml +++ b/airbyte-integrations/connectors/source-amplitude/metadata.yaml @@ -7,11 +7,11 @@ data: - amplitude.com - analytics.eu.amplitude.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: fa9f58c6-2d03-4237-aaa4-07d75e0c1396 - dockerImageTag: 0.6.13 + dockerImageTag: 0.6.17 dockerRepository: airbyte/source-amplitude documentationUrl: https://docs.airbyte.com/integrations/sources/amplitude githubIssueLabel: source-amplitude diff --git a/airbyte-integrations/connectors/source-amplitude/poetry.lock b/airbyte-integrations/connectors/source-amplitude/poetry.lock index 8556f6cae6fd..093830708669 100644 --- a/airbyte-integrations/connectors/source-amplitude/poetry.lock +++ b/airbyte-integrations/connectors/source-amplitude/poetry.lock @@ -69,24 +69,24 @@ files = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -101,19 +101,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -179,13 +179,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -269,127 +269,114 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -462,20 +449,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -525,13 +512,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -546,13 +533,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -560,7 +547,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -610,13 +596,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -717,22 +703,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -830,69 +819,86 @@ twitter = ["twython"] [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -995,19 +1001,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1015,100 +1021,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -1116,13 +1133,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1328,105 +1345,105 @@ files = [ [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -1513,33 +1530,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1581,20 +1598,21 @@ files = [ [[package]] name = "tqdm" -version = "4.66.6" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63"}, - {file = "tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -1626,13 +1644,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1657,81 +1675,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-amplitude/pyproject.toml b/airbyte-integrations/connectors/source-amplitude/pyproject.toml index 0010e5c43126..49b09e587112 100644 --- a/airbyte-integrations/connectors/source-amplitude/pyproject.toml +++ b/airbyte-integrations/connectors/source-amplitude/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.6.13" +version = "0.6.17" name = "source-amplitude" description = "Source implementation for Amplitude." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-amplitude/source_amplitude/components.py b/airbyte-integrations/connectors/source-amplitude/source_amplitude/components.py index 5fa407664b6e..562a5e957bb2 100644 --- a/airbyte-integrations/connectors/source-amplitude/source_amplitude/components.py +++ b/airbyte-integrations/connectors/source-amplitude/source_amplitude/components.py @@ -12,10 +12,12 @@ import pendulum import requests + from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor from airbyte_cdk.sources.declarative.schema.json_file_schema_loader import JsonFileSchemaLoader from airbyte_cdk.sources.declarative.types import Config, Record + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-amplitude/source_amplitude/run.py b/airbyte-integrations/connectors/source-amplitude/source_amplitude/run.py index 3649e5d9b311..12b0d3fe1614 100644 --- a/airbyte-integrations/connectors/source-amplitude/source_amplitude/run.py +++ b/airbyte-integrations/connectors/source-amplitude/source_amplitude/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_amplitude import SourceAmplitude +from airbyte_cdk.entrypoint import launch + def run(): source = SourceAmplitude() diff --git a/airbyte-integrations/connectors/source-amplitude/source_amplitude/source.py b/airbyte-integrations/connectors/source-amplitude/source_amplitude/source.py index 6ff2160da69c..cc98c73367b5 100644 --- a/airbyte-integrations/connectors/source-amplitude/source_amplitude/source.py +++ b/airbyte-integrations/connectors/source-amplitude/source_amplitude/source.py @@ -5,10 +5,12 @@ from base64 import b64encode from typing import Any, List, Mapping +from source_amplitude.streams import Events + from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator -from source_amplitude.streams import Events + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into diff --git a/airbyte-integrations/connectors/source-amplitude/source_amplitude/streams.py b/airbyte-integrations/connectors/source-amplitude/source_amplitude/streams.py index d6f22fa668d2..40112fa5e0ff 100644 --- a/airbyte-integrations/connectors/source-amplitude/source_amplitude/streams.py +++ b/airbyte-integrations/connectors/source-amplitude/source_amplitude/streams.py @@ -12,6 +12,7 @@ import pendulum import requests + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.streams.core import CheckpointMixin from airbyte_cdk.sources.streams.http import HttpStream @@ -19,6 +20,7 @@ from airbyte_cdk.sources.streams.http.error_handlers.default_error_mapping import DEFAULT_ERROR_MAPPING from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, FailureType, ResponseAction + LOGGER = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-amplitude/unit_tests/test_custom_extractors.py b/airbyte-integrations/connectors/source-amplitude/unit_tests/test_custom_extractors.py index 7d78a625301a..560b7248eabe 100644 --- a/airbyte-integrations/connectors/source-amplitude/unit_tests/test_custom_extractors.py +++ b/airbyte-integrations/connectors/source-amplitude/unit_tests/test_custom_extractors.py @@ -11,11 +11,12 @@ import pendulum import pytest import requests -from airbyte_cdk.models import SyncMode -from airbyte_cdk.utils import AirbyteTracedException from source_amplitude.components import ActiveUsersRecordExtractor, AverageSessionLengthRecordExtractor, EventsExtractor from source_amplitude.streams import Events +from airbyte_cdk.models import SyncMode +from airbyte_cdk.utils import AirbyteTracedException + @pytest.mark.parametrize( "custom_extractor, data, expected", @@ -141,9 +142,9 @@ def test_event_read(self, requests_mock): "error_code, expectation", [ (400, pytest.raises(AirbyteTracedException)), - (404, does_not_raise()), # does not raise because response action is IGNORE + (404, does_not_raise()), # does not raise because response action is IGNORE (504, pytest.raises(AirbyteTracedException)), - (500, does_not_raise()), # does not raise because repsonse action is RETRY + (500, does_not_raise()), # does not raise because repsonse action is RETRY ], ) def test_event_errors_read(self, mocker, requests_mock, error_code, expectation): @@ -195,7 +196,6 @@ def test_events_parse_response(self, file_name, content_is_valid, records_count) assert len(parsed_response) == records_count if content_is_valid: - # RFC3339 pattern pattern = r"^((?:(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2}(?:\.\d+)?))(Z|[\+-]\d{2}:\d{2})?)$" diff --git a/airbyte-integrations/connectors/source-apify-dataset/components.py b/airbyte-integrations/connectors/source-apify-dataset/components.py index 0fea713e975a..2b1710ddd800 100644 --- a/airbyte-integrations/connectors/source-apify-dataset/components.py +++ b/airbyte-integrations/connectors/source-apify-dataset/components.py @@ -5,6 +5,7 @@ from dataclasses import dataclass import requests + from airbyte_cdk.sources.declarative.extractors.dpath_extractor import DpathExtractor from airbyte_cdk.sources.declarative.types import Record diff --git a/airbyte-integrations/connectors/source-apify-dataset/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-apify-dataset/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-apify-dataset/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-apify-dataset/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-apify-dataset/metadata.yaml b/airbyte-integrations/connectors/source-apify-dataset/metadata.yaml index 6899b27a6c4b..e5ba814c44c0 100644 --- a/airbyte-integrations/connectors/source-apify-dataset/metadata.yaml +++ b/airbyte-integrations/connectors/source-apify-dataset/metadata.yaml @@ -3,11 +3,11 @@ data: hosts: - api.apify.com connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.15.0@sha256:09a84e0622f36393077332faf11cc239e77083fae5fa500592c049dca25888a7 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 47f17145-fe20-4ef5-a548-e29b048adf84 - dockerImageTag: 2.2.0 + dockerImageTag: 2.2.4 dockerRepository: airbyte/source-apify-dataset documentationUrl: https://docs.airbyte.com/integrations/sources/apify-dataset githubIssueLabel: source-apify-dataset diff --git a/airbyte-integrations/connectors/source-appcues/metadata.yaml b/airbyte-integrations/connectors/source-appcues/metadata.yaml index ffc816002634..14684ef28af6 100644 --- a/airbyte-integrations/connectors/source-appcues/metadata.yaml +++ b/airbyte-integrations/connectors/source-appcues/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-appcues connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 3bab735a-e108-4c94-ab3f-414e3447b409 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-appcues githubIssueLabel: source-appcues icon: icon.svg diff --git a/airbyte-integrations/connectors/source-appfigures/metadata.yaml b/airbyte-integrations/connectors/source-appfigures/metadata.yaml index 41e877f37103..629084b48d60 100644 --- a/airbyte-integrations/connectors/source-appfigures/metadata.yaml +++ b/airbyte-integrations/connectors/source-appfigures/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-appfigures connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: e2fcf0a0-3f99-4938-ba34-3a6dd51fd4a4 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-appfigures githubIssueLabel: source-appfigures icon: icon.svg diff --git a/airbyte-integrations/connectors/source-appfollow/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-appfollow/integration_tests/acceptance.py index d49b55882333..a9256a533972 100644 --- a/airbyte-integrations/connectors/source-appfollow/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-appfollow/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-appfollow/metadata.yaml b/airbyte-integrations/connectors/source-appfollow/metadata.yaml index 7093d68351b0..5e22f0709925 100644 --- a/airbyte-integrations/connectors/source-appfollow/metadata.yaml +++ b/airbyte-integrations/connectors/source-appfollow/metadata.yaml @@ -14,7 +14,7 @@ data: connectorSubtype: api connectorType: source definitionId: b4375641-e270-41d3-9c20-4f9cecad87a8 - dockerImageTag: 1.1.0 + dockerImageTag: 1.1.4 dockerRepository: airbyte/source-appfollow githubIssueLabel: source-appfollow icon: appfollow.svg @@ -48,5 +48,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.5.4@sha256:b07a521add11f987c63c0db68c1b57e90bec0c985f1cb6f3c5a1940cde628a70 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-apple-search-ads/acceptance-test-config.yml b/airbyte-integrations/connectors/source-apple-search-ads/acceptance-test-config.yml index e6f863199d55..08dba5ca8202 100644 --- a/airbyte-integrations/connectors/source-apple-search-ads/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-apple-search-ads/acceptance-test-config.yml @@ -8,43 +8,43 @@ acceptance_tests: connection: tests: - config_path: "secrets/config.json" - status: "succeed" - - config_path: "integration_tests/invalid_config.json" status: "failed" - discovery: - tests: - - config_path: "secrets/config.json" - basic_read: - tests: - - config_path: "secrets/config.json" - configured_catalog_path: "integration_tests/configured_catalog.json" - empty_streams: [] - timeout_seconds: 3600 - incremental: - tests: - - config_path: "secrets/config.json" - configured_catalog_path: "integration_tests/configured_catalog.json" - future_state: - future_state_path: "integration_tests/abnormal_state.json" - timeout_seconds: 3600 - full_refresh: - tests: - - config_path: "secrets/config.json" - configured_catalog_path: "integration_tests/configured_catalog.json" - ignored_fields: - adgroups_report_daily: - - name: granularity - bypass_reason: "Can't be idempotent by nature" - - name: metadata - bypass_reason: "Can't be idempotent by nature" - campaigns_report_daily: - - name: granularity - bypass_reason: "Can't be idempotent by nature" - - name: metadata - bypass_reason: "Can't be idempotent by nature" - keywords_report_daily: - - name: granularity - bypass_reason: "Can't be idempotent by nature" - - name: metadata - bypass_reason: "Can't be idempotent by nature" - timeout_seconds: 3600 + + ## Uncomment the following tests and mark above connection test status as "succeeded" when we have a usable sandbox environment + # discovery: + # tests: + # - config_path: "secrets/config.json" + # basic_read: + # tests: + # - config_path: "secrets/config.json" + # configured_catalog_path: "integration_tests/configured_catalog.json" + # empty_streams: [] + # timeout_seconds: 3600 + # incremental: + # tests: + # - config_path: "secrets/config.json" + # configured_catalog_path: "integration_tests/configured_catalog.json" + # future_state: + # future_state_path: "integration_tests/abnormal_state.json" + # timeout_seconds: 3600 + # full_refresh: + # tests: + # - config_path: "secrets/config.json" + # configured_catalog_path: "integration_tests/configured_catalog.json" + # ignored_fields: + # adgroups_report_daily: + # - name: granularity + # bypass_reason: "Can't be idempotent by nature" + # - name: metadata + # bypass_reason: "Can't be idempotent by nature" + # campaigns_report_daily: + # - name: granularity + # bypass_reason: "Can't be idempotent by nature" + # - name: metadata + # bypass_reason: "Can't be idempotent by nature" + # keywords_report_daily: + # - name: granularity + # bypass_reason: "Can't be idempotent by nature" + # - name: metadata + # bypass_reason: "Can't be idempotent by nature" + # timeout_seconds: 3600 diff --git a/airbyte-integrations/connectors/source-apple-search-ads/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-apple-search-ads/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-apple-search-ads/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-apple-search-ads/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-apple-search-ads/manifest.yaml b/airbyte-integrations/connectors/source-apple-search-ads/manifest.yaml index 286cf3f79f24..5492dcf2663d 100644 --- a/airbyte-integrations/connectors/source-apple-search-ads/manifest.yaml +++ b/airbyte-integrations/connectors/source-apple-search-ads/manifest.yaml @@ -452,6 +452,7 @@ definitions: type: OAuthAuthenticator client_id: "{{ config.client_id }}" client_secret: "{{ config.client_secret }}" + grant_type: client_credentials token_refresh_endpoint: >- https://appleid.apple.com/auth/oauth2/token?grant_type=client_credentials&scope=searchadsorg diff --git a/airbyte-integrations/connectors/source-apple-search-ads/metadata.yaml b/airbyte-integrations/connectors/source-apple-search-ads/metadata.yaml index 590c6c63b2e0..801921762cee 100644 --- a/airbyte-integrations/connectors/source-apple-search-ads/metadata.yaml +++ b/airbyte-integrations/connectors/source-apple-search-ads/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: e59c8416-c2fa-4bd3-9e95-52677ea281c1 - dockerImageTag: 0.2.0 + dockerImageTag: 0.2.5 dockerRepository: airbyte/source-apple-search-ads githubIssueLabel: source-apple-search-ads icon: apple.svg @@ -25,7 +25,15 @@ data: ab_internal: sl: 100 ql: 100 + connectorTestSuitesOptions: + - suite: acceptanceTests + testSecrets: + - name: SECRET_SOURCE-APPLE-SEARCH-ADS__CREDS + fileName: config.json + secretStore: + type: GSM + alias: airbyte-connector-testing-secret-store supportLevel: community connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.7.5@sha256:4832cc13b262b4cae4ba72b07da544e6ee2f5d216b7147483480d5ebc5d0d7ca + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-appsflyer/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-appsflyer/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-appsflyer/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-appsflyer/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-appsflyer/main.py b/airbyte-integrations/connectors/source-appsflyer/main.py index ebf2655b2ec4..ba1145064175 100644 --- a/airbyte-integrations/connectors/source-appsflyer/main.py +++ b/airbyte-integrations/connectors/source-appsflyer/main.py @@ -4,5 +4,6 @@ from source_appsflyer.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-appsflyer/metadata.yaml b/airbyte-integrations/connectors/source-appsflyer/metadata.yaml index 920cb198bd93..06772f60e83f 100644 --- a/airbyte-integrations/connectors/source-appsflyer/metadata.yaml +++ b/airbyte-integrations/connectors/source-appsflyer/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 16447954-e6a8-4593-b140-43dea13bc457 - dockerImageTag: 0.2.21 + dockerImageTag: 0.2.25 dockerRepository: airbyte/source-appsflyer githubIssueLabel: source-appsflyer icon: appsflyer.svg @@ -43,5 +43,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-appsflyer/poetry.lock b/airbyte-integrations/connectors/source-appsflyer/poetry.lock index 562dd35a6358..222f96e3d94e 100644 --- a/airbyte-integrations/connectors/source-appsflyer/poetry.lock +++ b/airbyte-integrations/connectors/source-appsflyer/poetry.lock @@ -62,19 +62,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -140,127 +140,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -276,20 +263,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -367,13 +354,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -486,13 +473,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -573,54 +560,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -884,33 +871,33 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -951,13 +938,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -982,81 +969,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-appsflyer/pyproject.toml b/airbyte-integrations/connectors/source-appsflyer/pyproject.toml index 7d6aa3bf0b27..e37b1e0fe15e 100644 --- a/airbyte-integrations/connectors/source-appsflyer/pyproject.toml +++ b/airbyte-integrations/connectors/source-appsflyer/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.2.21" +version = "0.2.25" name = "source-appsflyer" description = "Source implementation for Appsflyer." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-appsflyer/source_appsflyer/source.py b/airbyte-integrations/connectors/source-appsflyer/source_appsflyer/source.py index 8e77d5b78019..90cf565ac9c5 100644 --- a/airbyte-integrations/connectors/source-appsflyer/source_appsflyer/source.py +++ b/airbyte-integrations/connectors/source-appsflyer/source_appsflyer/source.py @@ -12,12 +12,13 @@ import pendulum import requests +from pendulum.tz.timezone import Timezone + from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http import HttpStream from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer -from pendulum.tz.timezone import Timezone from .fields import * diff --git a/airbyte-integrations/connectors/source-appsflyer/unit_tests/test_incremental_streams.py b/airbyte-integrations/connectors/source-appsflyer/unit_tests/test_incremental_streams.py index cc6dae86af52..6251fd0352f6 100644 --- a/airbyte-integrations/connectors/source-appsflyer/unit_tests/test_incremental_streams.py +++ b/airbyte-integrations/connectors/source-appsflyer/unit_tests/test_incremental_streams.py @@ -4,7 +4,6 @@ import pendulum import pytest -from airbyte_cdk.models import SyncMode from pytest import fixture, raises from source_appsflyer.fields import * from source_appsflyer.source import ( @@ -22,6 +21,8 @@ UninstallEvents, ) +from airbyte_cdk.models import SyncMode + @fixture def patch_incremental_base_class(mocker): diff --git a/airbyte-integrations/connectors/source-apptivo/README.md b/airbyte-integrations/connectors/source-apptivo/README.md new file mode 100644 index 000000000000..8e95fb0d23c3 --- /dev/null +++ b/airbyte-integrations/connectors/source-apptivo/README.md @@ -0,0 +1,33 @@ +# Apptivo +This directory contains the manifest-only connector for `source-apptivo`. + +Apptivo connector seamless data integration between Apptivo and various data warehouses or databases, automating data transfer for analytics, reporting, and insights. This connector allows businesses to synchronize Apptivo CRM data, such as contacts, deals, and activities, with other systems to streamline workflows and improve data accessibility across platforms. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-apptivo:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-apptivo build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-apptivo test +``` + diff --git a/airbyte-integrations/connectors/source-apptivo/acceptance-test-config.yml b/airbyte-integrations/connectors/source-apptivo/acceptance-test-config.yml new file mode 100644 index 000000000000..b99b79a53f74 --- /dev/null +++ b/airbyte-integrations/connectors/source-apptivo/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-apptivo:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-apptivo/icon.svg b/airbyte-integrations/connectors/source-apptivo/icon.svg new file mode 100644 index 000000000000..3ee8adec16a7 --- /dev/null +++ b/airbyte-integrations/connectors/source-apptivo/icon.svg @@ -0,0 +1,425 @@ + + + + diff --git a/airbyte-integrations/connectors/source-apptivo/manifest.yaml b/airbyte-integrations/connectors/source-apptivo/manifest.yaml new file mode 100644 index 000000000000..e9b037ff4b54 --- /dev/null +++ b/airbyte-integrations/connectors/source-apptivo/manifest.yaml @@ -0,0 +1,2580 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Apptivo connector seamless data integration between Apptivo and various data + warehouses or databases, automating data transfer for analytics, reporting, + and insights. This connector allows businesses to synchronize Apptivo CRM + data, such as contacts, deals, and activities, with other systems to + streamline workflows and improve data accessibility across platforms. + +check: + type: CheckStream + stream_names: + - customers + +definitions: + streams: + customers: + type: DeclarativeStream + name: customers + primary_key: + - customerId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /app/dao/v6/customers + http_method: GET + request_parameters: + a: getAll + accessKey: "{{ config['access_key'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startIndex + page_size_option: + type: RequestOption + field_name: numRecords + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: false + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - contactId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /app/dao/v6/contacts + http_method: GET + request_parameters: + a: getAll + accessKey: "{{ config[\"access_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startIndex + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: numRecords + pagination_strategy: + type: OffsetIncrement + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + cases: + type: DeclarativeStream + name: cases + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /app/dao/v6/cases + http_method: GET + request_parameters: + a: getConfigData + accessKey: "{{ config[\"access_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/cases" + leads: + type: DeclarativeStream + name: leads + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /app/dao/v6/leads + http_method: GET + request_parameters: + a: getAll + accessKey: "{{ config[\"access_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startIndex + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: numRecords + pagination_strategy: + type: OffsetIncrement + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/leads" + opportunities: + type: DeclarativeStream + name: opportunities + primary_key: + - opportunityId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /app/dao/v6/opportunities + http_method: GET + request_parameters: + a: getAll + accessKey: "{{ config[\"access_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startIndex + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: numRecords + pagination_strategy: + type: OffsetIncrement + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/opportunities" + base_requester: + type: HttpRequester + url_base: https://app.apptivo.com + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: apiKey + inject_into: request_parameter + +streams: + - $ref: "#/definitions/streams/customers" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/cases" + - $ref: "#/definitions/streams/leads" + - $ref: "#/definitions/streams/opportunities" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - access_key + properties: + api_key: + type: string + description: >- + API key to use. Find it in your Apptivo account under Business + Settings -> API Access. + name: api_key + order: 0 + title: API Key + airbyte_secret: true + access_key: + type: string + order: 1 + title: Access Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + customers: true + contacts: true + cases: true + leads: true + opportunities: true + testedStreams: + customers: + streamHash: fd3012cf32a546a143d4db55a6936e5cd2695ff7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contacts: + streamHash: 60a5d3b5a5140f0077da15685ede08fba1a3aa6e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + cases: + hasRecords: true + streamHash: f06a577d96be781ad8edf87c672e9d56dd233520 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + leads: + streamHash: bfcf2924569717b33757ead4ff677ea44f5f4f81 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + opportunities: + streamHash: 4e76f40c2c7803ec2abf0f5593e5651efe32afd1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://www.apptivo.com/developer-api/ + +schemas: + customers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + description: + type: + - string + - "null" + accounts: + type: + - array + - "null" + addresses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + accountAddressId: + type: + - number + - "null" + addressAttributeId: + type: + - string + - "null" + addressGroupName: + type: + - string + - "null" + addressId: + type: + - number + - "null" + addressLine1: + type: + - string + - "null" + addressLine2: + type: + - string + - "null" + addressType: + type: + - string + - "null" + addressTypeCode: + type: + - string + - "null" + city: + type: + - string + - "null" + countryCode: + type: + - string + - "null" + countryId: + type: + - number + - "null" + countryName: + type: + - string + - "null" + id: + type: + - string + - "null" + state: + type: + - string + - "null" + stateCode: + type: + - string + - "null" + zipCode: + type: + - string + - "null" + annualRevenueCurrencyCode: + type: + - string + - "null" + assigneeObjectId: + type: + - number + - "null" + assigneeObjectRefId: + type: + - number + - "null" + assigneeObjectRefName: + type: + - string + - "null" + campaignName: + type: + - string + - "null" + createdBy: + type: + - number + - "null" + createdByName: + type: + - string + - "null" + creationDate: + type: + - string + - "null" + creditRating: + type: + - string + - "null" + currencyCode: + type: + - string + - "null" + customAttributes: + type: + - array + - "null" + customerCategory: + type: + - string + - "null" + customerId: + type: number + customerName: + type: + - string + - "null" + customerNameNotAnalysed: + type: + - string + - "null" + customerNumber: + type: + - string + - "null" + deActivateRendered: + type: + - boolean + - "null" + defaultBillingCurrency: + type: + - string + - "null" + emailAddresses: + type: + - array + - "null" + employeeRange: + type: + - string + - "null" + faceBookURL: + type: + - string + - "null" + firmId: + type: + - number + - "null" + id: + type: + - string + - "null" + industryName: + type: + - string + - "null" + isActive: + type: + - string + - "null" + isAffiliate: + type: + - string + - "null" + isApproveRendered: + type: + - boolean + - "null" + isBounced: + type: + - string + - "null" + isExistingCustomer: + type: + - string + - "null" + isResponded: + type: + - string + - "null" + isUnsubscribed: + type: + - string + - "null" + labels: + type: + - array + - "null" + lastContactedDate: + type: + - string + - "null" + lastUpdateDate: + type: + - string + - "null" + lastUpdatedByName: + type: + - string + - "null" + linkedInURL: + type: + - string + - "null" + marketName: + type: + - string + - "null" + notes: + type: + - array + - "null" + objectId: + type: + - number + - "null" + objectStatus: + type: + - string + - "null" + ownership: + type: + - string + - "null" + parentCustomerName: + type: + - string + - "null" + paymentTerm: + type: + - string + - "null" + paymentTermId: + type: + - number + - "null" + phoneNumber: + type: + - string + - "null" + phoneNumbers: + type: + - array + - "null" + reInstateRendered: + type: + - boolean + - "null" + removeEmailAddresses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + emailType: + type: + - string + - "null" + emailTypeCode: + type: + - string + - "null" + id: + type: + - string + - "null" + removePhoneNumbers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + phoneType: + type: + - string + - "null" + phoneTypeCode: + type: + - string + - "null" + segmentName: + type: + - string + - "null" + skypeName: + type: + - string + - "null" + slaName: + type: + - string + - "null" + sortNumber: + type: + - string + - "null" + statusId: + type: + - number + - "null" + statusName: + type: + - string + - "null" + supportPlanName: + type: + - string + - "null" + syncToGoogle: + type: + - string + - "null" + territories: + type: + - array + - "null" + tickerSymbol: + type: + - string + - "null" + toObjectIds: + type: + - array + - "null" + items: + type: + - number + - "null" + twitterURL: + type: + - string + - "null" + updatedBy: + type: + - number + - "null" + website: + type: + - string + - "null" + required: + - customerId + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + description: + type: + - string + - "null" + accountId: + type: + - number + - "null" + accountName: + type: + - string + - "null" + accounts: + type: + - array + - "null" + addresses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + addressAttributeId: + type: + - string + - "null" + addressGroupName: + type: + - string + - "null" + addressId: + type: + - number + - "null" + addressLine1: + type: + - string + - "null" + addressLine2: + type: + - string + - "null" + addressType: + type: + - string + - "null" + addressTypeCode: + type: + - string + - "null" + city: + type: + - string + - "null" + countryCode: + type: + - string + - "null" + countryId: + type: + - number + - "null" + countryName: + type: + - string + - "null" + state: + type: + - string + - "null" + stateCode: + type: + - string + - "null" + zipCode: + type: + - string + - "null" + assigneeObjectId: + type: + - number + - "null" + assigneeObjectRefId: + type: + - number + - "null" + assigneeObjectRefName: + type: + - string + - "null" + bestWayToContactId: + type: + - number + - "null" + bestWayToContactName: + type: + - string + - "null" + categories: + type: + - array + - "null" + contactAttributes: + type: + - array + - "null" + contactId: + type: number + contactStatusId: + type: + - number + - "null" + contactStatusName: + type: + - string + - "null" + contactTypeName: + type: + - string + - "null" + createdBy: + type: + - number + - "null" + createdByName: + type: + - string + - "null" + creationDate: + type: + - string + - "null" + customAttributes: + type: + - array + - "null" + customerNumber: + type: + - string + - "null" + emailAddresses: + type: + - array + - "null" + externalRefId: + type: + - string + - "null" + faceBookURL: + type: + - string + - "null" + firmId: + type: + - number + - "null" + firstName: + type: + - string + - "null" + foods: + type: + - string + - "null" + fullName: + type: + - string + - "null" + hobbies: + type: + - string + - "null" + id: + type: + - string + - "null" + industryName: + type: + - string + - "null" + isActive: + type: + - string + - "null" + isBounced: + type: + - string + - "null" + isPrimary: + type: + - string + - "null" + isResponded: + type: + - string + - "null" + isUnsubscribed: + type: + - string + - "null" + jobTitle: + type: + - string + - "null" + labels: + type: + - array + - "null" + lastContactedDate: + type: + - string + - "null" + lastName: + type: + - string + - "null" + lastUpdateDate: + type: + - string + - "null" + lastUpdatedBy: + type: + - number + - "null" + lastUpdatedByName: + type: + - string + - "null" + linkedInURL: + type: + - string + - "null" + marketName: + type: + - string + - "null" + nickName: + type: + - string + - "null" + notes: + type: + - array + - "null" + objectStatus: + type: + - string + - "null" + phoneNumbers: + type: + - array + - "null" + phoneticName: + type: + - string + - "null" + segmentName: + type: + - string + - "null" + skypeName: + type: + - string + - "null" + supplierName: + type: + - string + - "null" + syncToGoogle: + type: + - string + - "null" + syncToO365: + type: + - string + - "null" + territories: + type: + - array + - "null" + twitterURL: + type: + - string + - "null" + website: + type: + - string + - "null" + required: + - contactId + cases: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accessLevel: + type: + - string + - "null" + addressTypes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + code: + type: + - string + - "null" + id: + type: + - number + - "null" + isEnabled: + type: + - string + - "null" + isSmsEnabled: + type: + - string + - "null" + name: + type: + - string + - "null" + app360Objects: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + isLandscape: + type: + - boolean + - "null" + objectChecked: + type: + - boolean + - "null" + objectId: + type: + - number + - "null" + objectName: + type: + - string + - "null" + appName: + type: + - string + - "null" + assigneeObjectId: + type: + - number + - "null" + assigneeObjectRefId: + type: + - number + - "null" + assigneeObjectRefName: + type: + - string + - "null" + assigneeType: + type: + - string + - "null" + assignees: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + isLandscape: + type: + - boolean + - "null" + objectChecked: + type: + - boolean + - "null" + objectId: + type: + - number + - "null" + objectRefId: + type: + - number + - "null" + objectRefName: + type: + - string + - "null" + assignmentLevels: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + code: + type: + - string + - "null" + isEnabled: + type: + - string + - "null" + name: + type: + - string + - "null" + caseSources: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + caseSourceId: + type: + - number + - "null" + caseSourceName: + type: + - string + - "null" + isEnabled: + type: + - string + - "null" + casesPortalTabName: + type: + - string + - "null" + collaborationSettings: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + activityActionSettings: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + code: + type: + - string + - "null" + isEnabled: + type: + - string + - "null" + isShareWithAssignee: + type: + - string + - "null" + isShareWithCustomers: + type: + - string + - "null" + isShareWithOthers: + type: + - string + - "null" + name: + type: + - string + - "null" + privilegeCode: + type: + - string + - "null" + privilegeName: + type: + - string + - "null" + code: + type: + - string + - "null" + isEnabled: + type: + - string + - "null" + name: + type: + - string + - "null" + privilegeCode: + type: + - string + - "null" + privilegeName: + type: + - string + - "null" + configVersionNumber: + type: + - number + - "null" + conversions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + code: + type: + - string + - "null" + name: + type: + - string + - "null" + countOfAllCases: + type: + - number + - "null" + countOfCases: + type: + - number + - "null" + countOfMyEmployeeFollowupCases: + type: + - number + - "null" + countOfMyEmployeeNotRespondedQueueCases: + type: + - number + - "null" + countOfMyEmployeeQueueCases: + type: + - number + - "null" + countOfMyQueueCases: + type: + - number + - "null" + countOfMyfollowupCases: + type: + - number + - "null" + countOfNotRespondedQueueCases: + type: + - number + - "null" + countOfUnrespondedCases: + type: + - number + - "null" + countOfUnrespondedEmployeesCases: + type: + - number + - "null" + countOfUnrespondedTeamsCases: + type: + - number + - "null" + createdBy: + type: + - number + - "null" + currencies: + type: + - array + - "null" + items: + type: + - string + - "null" + currencyCode: + type: + - string + - "null" + currencySymbolType: + type: + - string + - "null" + dateFormat: + type: + - string + - "null" + default360ObjectId: + type: + - string + - "null" + defaultHomePage: + type: + - string + - "null" + defaultViewType: + type: + - string + - "null" + eSignatureOption: + type: + - string + - "null" + editAccessLevel: + type: + - string + - "null" + emailTemplates: + type: + - array + - "null" + emailTypes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + code: + type: + - string + - "null" + id: + type: + - number + - "null" + isEnabled: + type: + - string + - "null" + isSmsEnabled: + type: + - string + - "null" + name: + type: + - string + - "null" + employees: + type: + - array + - "null" + firmId: + type: + - number + - "null" + followupTeams: + type: + - array + - "null" + id: + type: + - string + - "null" + isATagEnabled: + type: + - string + - "null" + isCasesPortalEnabled: + type: + - string + - "null" + isCustomerNotificaitonEnabled: + type: + - string + - "null" + isDashboardViewEnabled: + type: + - string + - "null" + isDefaultAssigneeEnabled: + type: + - string + - "null" + isDuplicationRulesEnabled: + type: + - boolean + - "null" + isEnterpriseDuplicateRuleEnabled: + type: + - boolean + - "null" + isGenerateEnabled: + type: + - string + - "null" + isKbPortalEnabled: + type: + - string + - "null" + isListViewEnabled: + type: + - string + - "null" + isMultiCurrency: + type: + - string + - "null" + isSWPTagEnabled: + type: + - string + - "null" + isTimeTrackingEnabled: + type: + - string + - "null" + kbPortalTabName: + type: + - string + - "null" + labels: + type: + - array + - "null" + lastUpdateDate: + type: + - string + - "null" + lastUpdatedBy: + type: + - number + - "null" + listLayouts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + data: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + width: + type: + - number + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + mobileViews: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + isEnabled: + type: + - string + - "null" + name: + type: + - string + - "null" + webLayout: + type: + - string + - "null" + notRespondedTeams: + type: + - array + - "null" + numRecords: + type: + - number + - "null" + numberGenerator: + type: + - object + - "null" + properties: + isAutoGenerate: + type: + - string + - "null" + startsWith: + type: + - number + - "null" + objectId: + type: + - number + - "null" + parentObjectId: + type: + - number + - "null" + pdfDefaultTemplateId: + type: + - string + - "null" + pdfTemplates: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + content: + type: + - string + - "null" + enabled: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isBarCodeEnabled: + type: + - boolean + - "null" + isEsignEnabled: + type: + - boolean + - "null" + isQRCodeEnabled: + type: + - boolean + - "null" + name: + type: + - string + - "null" + prefix: + type: + - string + - "null" + phoneTypes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + code: + type: + - string + - "null" + id: + type: + - number + - "null" + isEnabled: + type: + - string + - "null" + isSmsEnabled: + type: + - string + - "null" + name: + type: + - string + - "null" + portalEditAccessLevel: + type: + - string + - "null" + portalIsParentCustomerVisibility: + type: + - string + - "null" + portalViewAccessLevel: + type: + - string + - "null" + priorities: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + casesCount: + type: + - number + - "null" + code: + type: + - string + - "null" + id: + type: + - number + - "null" + isEnabled: + type: + - string + - "null" + name: + type: + - string + - "null" + privilegeSettings: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + actionCode: + type: + - string + - "null" + actionName: + type: + - string + - "null" + isEnabled: + type: + - string + - "null" + privilegeCode: + type: + - string + - "null" + privilegeName: + type: + - string + - "null" + privileges: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + version: + type: + - number + - "null" + description: + type: + - string + - "null" + createdBy: + type: + - number + - "null" + creationDate: + type: + - string + - "null" + displayName: + type: + - string + - "null" + id: + type: + - string + - "null" + isFromDAP: + type: + - boolean + - "null" + lastUpdateDate: + type: + - string + - "null" + lastUpdatedBy: + type: + - number + - "null" + name: + type: + - string + - "null" + objectId: + type: + - number + - "null" + parentPrivilegeId: + type: + - string + - "null" + privilegeAutoGrants: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + autograntPrivilegeId: + type: + - number + - "null" + quickLinks: + type: + - array + - "null" + referenceFields: + type: + - array + - "null" + reportGroups: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + version: + type: + - number + - "null" + description: + type: + - string + - "null" + reportGroupName: + type: + - string + - "null" + reports: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + version: + type: + - number + - "null" + description: + type: + - string + - "null" + addresses: + type: + - array + - "null" + associatedEntities: + type: + - array + - "null" + customAttributes: + type: + - array + - "null" + emailAddresses: + type: + - array + - "null" + isPaidReport: + type: + - string + - "null" + labels: + type: + - array + - "null" + metaAttributeMap: + type: + - object + - "null" + metaObjectMap: + type: + - object + - "null" + phoneNumbers: + type: + - array + - "null" + privilegeCode: + type: + - string + - "null" + removeAddresses: + type: + - array + - "null" + removeEmailAddresses: + type: + - array + - "null" + removeLabels: + type: + - array + - "null" + removePhoneNumbers: + type: + - array + - "null" + reportCode: + type: + - string + - "null" + reportId: + type: + - number + - "null" + reportName: + type: + - string + - "null" + toObjectIds: + type: + - array + - "null" + savedViews: + type: + - array + - "null" + slas: + type: + - array + - "null" + snapShots: + type: + - array + - "null" + statuses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + casesCount: + type: + - number + - "null" + isActive: + type: + - string + - "null" + isEnabled: + type: + - string + - "null" + statusCode: + type: + - string + - "null" + statusId: + type: + - number + - "null" + statusName: + type: + - string + - "null" + sysMessages: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + code: + type: + - string + - "null" + message: + type: + - string + - "null" + teams: + type: + - array + - "null" + timeTrackingType: + type: + - string + - "null" + types: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + casesCount: + type: + - number + - "null" + isActive: + type: + - string + - "null" + isEnabled: + type: + - string + - "null" + typeCode: + type: + - string + - "null" + typeId: + type: + - number + - "null" + typeName: + type: + - string + - "null" + userConfig: + type: + - object + - "null" + properties: + myViews: + type: + - array + - "null" + sharedViews: + type: + - array + - "null" + versionNumber: + type: + - number + - "null" + viewSettings: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + bulkActions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + code: + type: + - string + - "null" + isEnabled: + type: + - string + - "null" + name: + type: + - string + - "null" + code: + type: + - string + - "null" + isEnabled: + type: + - string + - "null" + listLayoutId: + type: + - string + - "null" + mobileViewId: + type: + - string + - "null" + mobileViewName: + type: + - string + - "null" + name: + type: + - string + - "null" + privilegeCode: + type: + - string + - "null" + privilegeName: + type: + - string + - "null" + webLayout: + type: + - string + - "null" + leads: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + description: + type: + - string + - "null" + accountId: + type: + - number + - "null" + accountName: + type: + - string + - "null" + accounts: + type: + - array + - "null" + actualAmount: + type: + - number + - "null" + addresses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + addressAttributeId: + type: + - string + - "null" + addressGroupName: + type: + - string + - "null" + addressId: + type: + - number + - "null" + addressLine1: + type: + - string + - "null" + addressLine2: + type: + - string + - "null" + addressType: + type: + - string + - "null" + addressTypeCode: + type: + - string + - "null" + city: + type: + - string + - "null" + countryCode: + type: + - string + - "null" + countryId: + type: + - number + - "null" + countryName: + type: + - string + - "null" + county: + type: + - string + - "null" + state: + type: + - string + - "null" + stateCode: + type: + - string + - "null" + zipCode: + type: + - string + - "null" + annualRevenueCurrencyCode: + type: + - string + - "null" + assigneeObjectId: + type: + - number + - "null" + assigneeObjectRefId: + type: + - number + - "null" + assigneeObjectRefName: + type: + - string + - "null" + companyName: + type: + - string + - "null" + createdBy: + type: + - number + - "null" + createdByName: + type: + - string + - "null" + createdByObjectId: + type: + - number + - "null" + createdByObjectRefId: + type: + - number + - "null" + creationDate: + type: + - string + - "null" + currencyCode: + type: + - string + - "null" + customAttributes: + type: + - array + - "null" + emailAddresses: + type: + - array + - "null" + employeeRange: + type: + - string + - "null" + firmId: + type: + - number + - "null" + firstName: + type: + - string + - "null" + fromObjectId: + type: + - number + - "null" + fromObjectRefId: + type: + - number + - "null" + fullName: + type: + - string + - "null" + id: + type: string + industryName: + type: + - string + - "null" + isBounced: + type: + - string + - "null" + isUnsubscribed: + type: + - string + - "null" + jobTitle: + type: + - string + - "null" + labels: + type: + - array + - "null" + lastContactedDate: + type: + - string + - "null" + lastName: + type: + - string + - "null" + lastUpdateDate: + type: + - string + - "null" + lastUpdatedBy: + type: + - number + - "null" + lastUpdatedByName: + type: + - string + - "null" + leadId: + type: + - number + - "null" + notes: + type: + - array + - "null" + objectId: + type: + - number + - "null" + objectStatus: + type: + - string + - "null" + ownership: + type: + - string + - "null" + phoneNumbers: + type: + - array + - "null" + potentialAmount: + type: + - number + - "null" + potentialAmountCurrencyCode: + type: + - string + - "null" + referredById: + type: + - number + - "null" + referredByName: + type: + - string + - "null" + territories: + type: + - array + - "null" + website: + type: + - string + - "null" + required: + - id + opportunities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + accounts: + type: + - array + - "null" + actualAmount: + type: + - number + - "null" + addresses: + type: + - array + - "null" + amount: + type: + - number + - "null" + assignedToObjectId: + type: + - number + - "null" + assignedToObjectRefId: + type: + - number + - "null" + assignedToObjectRefName: + type: + - string + - "null" + assigneeManagers: + type: + - array + - "null" + campaignName: + type: + - string + - "null" + closeDate: + type: + - string + - "null" + createdBy: + type: + - number + - "null" + createdByName: + type: + - string + - "null" + creationDate: + type: + - string + - "null" + currencyCode: + type: + - string + - "null" + customAttributes: + type: + - array + - "null" + emailAddresses: + type: + - array + - "null" + firmId: + type: + - number + - "null" + histories: + type: + - array + - "null" + id: + type: + - string + - "null" + inquiryTypes: + type: + - array + - "null" + isActive: + type: + - string + - "null" + isLocked: + type: + - string + - "null" + isMultiCurrency: + type: + - string + - "null" + itemList: + type: + - array + - "null" + items: + type: + - array + - "null" + labels: + type: + - array + - "null" + lastContactedDate: + type: + - string + - "null" + lastUpdateDate: + type: + - string + - "null" + lastUpdatedBy: + type: + - number + - "null" + lastUpdatedByName: + type: + - string + - "null" + leadSourceTypeId: + type: + - number + - "null" + leadSourceTypeName: + type: + - string + - "null" + notes: + type: + - array + - "null" + objectStatus: + type: + - string + - "null" + opportunityCustomer: + type: + - string + - "null" + opportunityCustomerId: + type: + - number + - "null" + opportunityHistory: + type: + - string + - "null" + opportunityId: + type: number + opportunityName: + type: + - string + - "null" + opportunityNameNotAnalysed: + type: + - string + - "null" + pdfTemplateId: + type: + - number + - "null" + pdfTemplateName: + type: + - string + - "null" + phoneNumbers: + type: + - array + - "null" + probability: + type: + - number + - "null" + propertyList: + type: + - array + - "null" + removeLabels: + type: + - array + - "null" + salesStageHistory: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + version: + type: + - number + - "null" + amount: + type: + - number + - "null" + closeDate: + type: + - string + - "null" + createdBy: + type: + - number + - "null" + createdByName: + type: + - string + - "null" + creationDate: + type: + - string + - "null" + currencyCode: + type: + - string + - "null" + firmId: + type: + - number + - "null" + id: + type: + - number + - "null" + lastUpdateDate: + type: + - string + - "null" + lastUpdatedBy: + type: + - number + - "null" + lastUpdatedByName: + type: + - string + - "null" + opportunityId: + type: + - number + - "null" + probability: + type: + - number + - "null" + stageId: + type: + - number + - "null" + stageName: + type: + - string + - "null" + salesStageId: + type: + - number + - "null" + salesStageName: + type: + - string + - "null" + territories: + type: + - array + - "null" + required: + - opportunityId diff --git a/airbyte-integrations/connectors/source-apptivo/metadata.yaml b/airbyte-integrations/connectors/source-apptivo/metadata.yaml new file mode 100644 index 000000000000..78621ca1550d --- /dev/null +++ b/airbyte-integrations/connectors/source-apptivo/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "app.apptivo.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-apptivo + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: eb41169b-b293-4690-b690-a1046cca0e3b + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-apptivo + githubIssueLabel: source-apptivo + icon: icon.svg + license: MIT + name: Apptivo + releaseDate: 2024-11-09 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/apptivo + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-asana/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-asana/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-asana/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-asana/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-asana/main.py b/airbyte-integrations/connectors/source-asana/main.py index 5fde4e3c72d6..ade635df308f 100644 --- a/airbyte-integrations/connectors/source-asana/main.py +++ b/airbyte-integrations/connectors/source-asana/main.py @@ -4,5 +4,6 @@ from source_asana.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-asana/metadata.yaml b/airbyte-integrations/connectors/source-asana/metadata.yaml index 8e19094d7a74..9b76f92c4bf7 100644 --- a/airbyte-integrations/connectors/source-asana/metadata.yaml +++ b/airbyte-integrations/connectors/source-asana/metadata.yaml @@ -24,11 +24,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: d0243522-dccf-4978-8ba0-37ed47a0bdbf - dockerImageTag: 1.2.13 + dockerImageTag: 1.3.4 dockerRepository: airbyte/source-asana githubIssueLabel: source-asana icon: asana.svg diff --git a/airbyte-integrations/connectors/source-asana/poetry.lock b/airbyte-integrations/connectors/source-asana/poetry.lock index 02302faf1ed9..93b15329fa06 100644 --- a/airbyte-integrations/connectors/source-asana/poetry.lock +++ b/airbyte-integrations/connectors/source-asana/poetry.lock @@ -2,95 +2,124 @@ [[package]] name = "airbyte-cdk" -version = "1.8.0" +version = "6.12.4" description = "A framework for writing Airbyte Connectors." optional = false -python-versions = "<4.0,>=3.9" +python-versions = "<3.13,>=3.10" files = [ - {file = "airbyte_cdk-1.8.0-py3-none-any.whl", hash = "sha256:ca23d7877005fe87ffc4a3a3de29ee55eed625d874eb59b49664b156f9ae9ee2"}, - {file = "airbyte_cdk-1.8.0.tar.gz", hash = "sha256:ac82fbfd6b650b7ed015900748e30fdd2a4c574caa54d1bcc03cb584a17f1533"}, + {file = "airbyte_cdk-6.12.4-py3-none-any.whl", hash = "sha256:903f2c2d3be4d6595bc6c50a4625e2551308d2ca90e021bf489e0a82cf0f965d"}, + {file = "airbyte_cdk-6.12.4.tar.gz", hash = "sha256:f9f39746dec5e01a9d37255cfb45a753953227b7aafebf8f5603a6e9f943b182"}, ] [package.dependencies] -airbyte-protocol-models = ">=0.9.0,<1.0" +airbyte-protocol-models-dataclasses = ">=0.14,<0.15" backoff = "*" cachetools = "*" -cryptography = ">=42.0.5,<43.0.0" -Deprecated = ">=1.2,<1.3" +cryptography = ">=42.0.5,<44.0.0" dpath = ">=2.1.6,<3.0.0" -genson = "1.2.2" +dunamai = ">=1.22.0,<2.0.0" +genson = "1.3.0" isodate = ">=0.6.1,<0.7.0" Jinja2 = ">=3.1.2,<3.2.0" jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" +jsonschema = ">=4.17.3,<4.18.0" langchain_core = "0.1.42" +nltk = "3.9.1" +numpy = "<2" +orjson = ">=3.10.7,<4.0.0" +pandas = "2.2.2" pendulum = "<3.0.0" -pydantic = ">=1.10.8,<2.0.0" +psutil = "6.1.0" +pydantic = ">=2.7,<3.0" pyjwt = ">=2.8.0,<3.0.0" pyrate-limiter = ">=3.1.0,<3.2.0" python-dateutil = "*" -pytz = "2024.1" +python-ulid = ">=3.0.0,<4.0.0" +pytz = "2024.2" PyYAML = ">=6.0.1,<7.0.0" +rapidfuzz = ">=3.10.1,<4.0.0" requests = "*" requests_cache = "*" -wcmatch = "8.4" +serpyco-rs = ">=1.10.2,<2.0.0" +Unidecode = ">=1.3,<2.0" +wcmatch = "10.0" +xmltodict = ">=0.13.0,<0.14.0" [package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] +file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "python-snappy (==0.7.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] +sql = ["sqlalchemy (>=2.0,!=2.0.36,<3.0)"] +vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.8.0)"] [[package]] -name = "airbyte-protocol-models" -version = "0.13.0" -description = "Declares the Airbyte Protocol." +name = "airbyte-protocol-models-dataclasses" +version = "0.14.1" +description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models_dataclasses-0.14.1-py3-none-any.whl", hash = "sha256:dfe10b32ee09e6ba9b4f17bd309e841b61cbd61ec8f80b1937ff104efd6209a9"}, + {file = "airbyte_protocol_models_dataclasses-0.14.1.tar.gz", hash = "sha256:f62a46556b82ea0d55de144983141639e8049d836dd4e0a9d7234c5b2e103c08"}, ] -[package.dependencies] -pydantic = ">=1.9.2,<2.0.0" +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] +[[package]] +name = "attributes-doc" +version = "0.4.0" +description = "PEP 224 implementation" +optional = false +python-versions = ">=3.8" +files = [ + {file = "attributes-doc-0.4.0.tar.gz", hash = "sha256:b1576c94a714e9fc2c65c47cf10d0c8e1a5f7c4f5ae7f69006be108d95cbfbfb"}, + {file = "attributes_doc-0.4.0-py2.py3-none-any.whl", hash = "sha256:4c3007d9e58f3a6cb4b9c614c4d4ce2d92161581f28e594ddd8241cc3a113bdd"}, +] + [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -156,13 +185,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -246,118 +275,119 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] +[[package]] +name = "click" +version = "8.1.8" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + [[package]] name = "colorama" version = "0.4.6" @@ -371,43 +401,38 @@ files = [ [[package]] name = "cryptography" -version = "42.0.8" +version = "43.0.3" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, + {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, + {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, + {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, + {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, + {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, + {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, + {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, ] [package.dependencies] @@ -420,26 +445,9 @@ nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] -[[package]] -name = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - [[package]] name = "dpath" version = "2.2.0" @@ -451,6 +459,20 @@ files = [ {file = "dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e"}, ] +[[package]] +name = "dunamai" +version = "1.23.0" +description = "Dynamic version generation" +optional = false +python-versions = ">=3.5" +files = [ + {file = "dunamai-1.23.0-py3-none-any.whl", hash = "sha256:a0906d876e92441793c6a423e16a4802752e723e9c9a5aabdc5535df02dbe041"}, + {file = "dunamai-1.23.0.tar.gz", hash = "sha256:a163746de7ea5acb6dacdab3a6ad621ebc612ed1e528aaa8beedb8887fccd2c4"}, +] + +[package.dependencies] +packaging = ">=20.9" + [[package]] name = "exceptiongroup" version = "1.2.2" @@ -467,12 +489,13 @@ test = ["pytest (>=6)"] [[package]] name = "genson" -version = "1.2.2" +version = "1.3.0" description = "GenSON is a powerful, user-friendly JSON Schema generator." optional = false python-versions = "*" files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, + {file = "genson-1.3.0-py3-none-any.whl", hash = "sha256:468feccd00274cc7e4c09e84b08704270ba8d95232aa280f65b986139cec67f7"}, + {file = "genson-1.3.0.tar.gz", hash = "sha256:e02db9ac2e3fd29e65b5286f7135762e2cd8a986537c075b06fc5f1517308e37"}, ] [[package]] @@ -488,13 +511,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -509,13 +532,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -523,7 +546,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -573,13 +595,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -588,6 +610,17 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "joblib" +version = "1.4.2" +description = "Lightweight pipelining with Python functions" +optional = false +python-versions = ">=3.8" +files = [ + {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, + {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, +] + [[package]] name = "jsonpatch" version = "1.33" @@ -626,24 +659,22 @@ files = [ [[package]] name = "jsonschema" -version = "3.2.0" +version = "4.17.3" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, ] [package.dependencies] attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" [package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] [[package]] name = "langchain-core" @@ -669,22 +700,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -755,71 +789,158 @@ files = [ {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] +[[package]] +name = "nltk" +version = "3.9.1" +description = "Natural Language Toolkit" +optional = false +python-versions = ">=3.8" +files = [ + {file = "nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1"}, + {file = "nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868"}, +] + +[package.dependencies] +click = "*" +joblib = "*" +regex = ">=2021.8.3" +tqdm = "*" + +[package.extras] +all = ["matplotlib", "numpy", "pyparsing", "python-crfsuite", "requests", "scikit-learn", "scipy", "twython"] +corenlp = ["requests"] +machine-learning = ["numpy", "python-crfsuite", "scikit-learn", "scipy"] +plot = ["matplotlib"] +tgrep = ["pyparsing"] +twitter = ["twython"] + +[[package]] +name = "numpy" +version = "1.26.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, +] + [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -833,6 +954,78 @@ files = [ {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] +[[package]] +name = "pandas" +version = "2.2.2" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + [[package]] name = "pendulum" version = "2.1.2" @@ -898,6 +1091,36 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "psutil" +version = "6.1.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, +] + +[package.extras] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + [[package]] name = "pycparser" version = "2.22" @@ -911,72 +1134,145 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" -description = "Data validation and settings management using python type hints" +version = "2.10.4" +description = "Data validation using Python type hints" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] -typing-extensions = ">=4.2.0" +annotated-types = ">=0.6.0" +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] +email = ["email-validator (>=2.0.0)"] +timezone = ["tzdata"] + +[[package]] +name = "pydantic-core" +version = "2.27.2" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1043,13 +1339,13 @@ files = [ [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] @@ -1094,15 +1390,29 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "python-ulid" +version = "3.0.0" +description = "Universally unique lexicographically sortable identifier" +optional = false +python-versions = ">=3.9" +files = [ + {file = "python_ulid-3.0.0-py3-none-any.whl", hash = "sha256:e4c4942ff50dbd79167ad01ac725ec58f924b4018025ce22c858bfcff99a5e31"}, + {file = "python_ulid-3.0.0.tar.gz", hash = "sha256:e50296a47dc8209d28629a22fc81ca26c00982c78934bd7766377ba37ea49a9f"}, +] + +[package.extras] +pydantic = ["pydantic (>=2.0)"] + [[package]] name = "pytz" -version = "2024.1" +version = "2024.2" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, + {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, + {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, ] [[package]] @@ -1178,6 +1488,209 @@ files = [ {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] +[[package]] +name = "rapidfuzz" +version = "3.11.0" +description = "rapid fuzzy string matching" +optional = false +python-versions = ">=3.9" +files = [ + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eb8a54543d16ab1b69e2c5ed96cabbff16db044a50eddfc028000138ca9ddf33"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:231c8b2efbd7f8d2ecd1ae900363ba168b8870644bb8f2b5aa96e4a7573bde19"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54e7f442fb9cca81e9df32333fb075ef729052bcabe05b0afc0441f462299114"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:906f1f2a1b91c06599b3dd1be207449c5d4fc7bd1e1fa2f6aef161ea6223f165"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed59044aea9eb6c663112170f2399b040d5d7b162828b141f2673e822093fa8"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cb1965a28b0fa64abdee130c788a0bc0bb3cf9ef7e3a70bf055c086c14a3d7e"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b488b244931d0291412917e6e46ee9f6a14376625e150056fe7c4426ef28225"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f0ba13557fec9d5ffc0a22826754a7457cc77f1b25145be10b7bb1d143ce84c6"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3871fa7dfcef00bad3c7e8ae8d8fd58089bad6fb21f608d2bf42832267ca9663"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b2669eafee38c5884a6e7cc9769d25c19428549dcdf57de8541cf9e82822e7db"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ffa1bb0e26297b0f22881b219ffc82a33a3c84ce6174a9d69406239b14575bd5"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:45b15b8a118856ac9caac6877f70f38b8a0d310475d50bc814698659eabc1cdb"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win32.whl", hash = "sha256:22033677982b9c4c49676f215b794b0404073f8974f98739cb7234e4a9ade9ad"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:be15496e7244361ff0efcd86e52559bacda9cd975eccf19426a0025f9547c792"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_arm64.whl", hash = "sha256:714a7ba31ba46b64d30fccfe95f8013ea41a2e6237ba11a805a27cdd3bce2573"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8724a978f8af7059c5323d523870bf272a097478e1471295511cf58b2642ff83"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b63cb1f2eb371ef20fb155e95efd96e060147bdd4ab9fc400c97325dfee9fe1"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82497f244aac10b20710448645f347d862364cc4f7d8b9ba14bd66b5ce4dec18"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:339607394941801e6e3f6c1ecd413a36e18454e7136ed1161388de674f47f9d9"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84819390a36d6166cec706b9d8f0941f115f700b7faecab5a7e22fc367408bc3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eea8d9e20632d68f653455265b18c35f90965e26f30d4d92f831899d6682149b"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b659e1e2ea2784a9a397075a7fc395bfa4fe66424042161c4bcaf6e4f637b38"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1315cd2a351144572e31fe3df68340d4b83ddec0af8b2e207cd32930c6acd037"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a7743cca45b4684c54407e8638f6d07b910d8d811347b9d42ff21262c7c23245"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:5bb636b0150daa6d3331b738f7c0f8b25eadc47f04a40e5c23c4bfb4c4e20ae3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:42f4dd264ada7a9aa0805ea0da776dc063533917773cf2df5217f14eb4429eae"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:51f24cb39e64256221e6952f22545b8ce21cacd59c0d3e367225da8fc4b868d8"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win32.whl", hash = "sha256:aaf391fb6715866bc14681c76dc0308f46877f7c06f61d62cc993b79fc3c4a2a"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:ebadd5b8624d8ad503e505a99b8eb26fe3ea9f8e9c2234e805a27b269e585842"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:d895998fec712544c13cfe833890e0226585cf0391dd3948412441d5d68a2b8c"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f382fec4a7891d66fb7163c90754454030bb9200a13f82ee7860b6359f3f2fa8"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dfaefe08af2a928e72344c800dcbaf6508e86a4ed481e28355e8d4b6a6a5230e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92ebb7c12f682b5906ed98429f48a3dd80dd0f9721de30c97a01473d1a346576"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a1b3ebc62d4bcdfdeba110944a25ab40916d5383c5e57e7c4a8dc0b6c17211a"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c6d7fea39cb33e71de86397d38bf7ff1a6273e40367f31d05761662ffda49e4"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99aebef8268f2bc0b445b5640fd3312e080bd17efd3fbae4486b20ac00466308"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4469307f464ae3089acf3210b8fc279110d26d10f79e576f385a98f4429f7d97"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:eb97c53112b593f89a90b4f6218635a9d1eea1d7f9521a3b7d24864228bbc0aa"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef8937dae823b889c0273dfa0f0f6c46a3658ac0d851349c464d1b00e7ff4252"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d95f9e9f3777b96241d8a00d6377cc9c716981d828b5091082d0fe3a2924b43e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:b1d67d67f89e4e013a5295e7523bc34a7a96f2dba5dd812c7c8cb65d113cbf28"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d994cf27e2f874069884d9bddf0864f9b90ad201fcc9cb2f5b82bacc17c8d5f2"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win32.whl", hash = "sha256:ba26d87fe7fcb56c4a53b549a9e0e9143f6b0df56d35fe6ad800c902447acd5b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:b1f7efdd7b7adb32102c2fa481ad6f11923e2deb191f651274be559d56fc913b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:ed78c8e94f57b44292c1a0350f580e18d3a3c5c0800e253f1583580c1b417ad2"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e60814edd0c9b511b5f377d48b9782b88cfe8be07a98f99973669299c8bb318a"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f28952da055dbfe75828891cd3c9abf0984edc8640573c18b48c14c68ca5e06"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e8f93bc736020351a6f8e71666e1f486bb8bd5ce8112c443a30c77bfde0eb68"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76a4a11ba8f678c9e5876a7d465ab86def047a4fcc043617578368755d63a1bc"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc0e0d41ad8a056a9886bac91ff9d9978e54a244deb61c2972cc76b66752de9c"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e8ea35f2419c7d56b3e75fbde2698766daedb374f20eea28ac9b1f668ef4f74"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd340bbd025302276b5aa221dccfe43040c7babfc32f107c36ad783f2ffd8775"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:494eef2c68305ab75139034ea25328a04a548d297712d9cf887bf27c158c388b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5a167344c1d6db06915fb0225592afdc24d8bafaaf02de07d4788ddd37f4bc2f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8c7af25bda96ac799378ac8aba54a8ece732835c7b74cfc201b688a87ed11152"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d2a0f7e17f33e7890257367a1662b05fecaf56625f7dbb6446227aaa2b86448b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4d0d26c7172bdb64f86ee0765c5b26ea1dc45c52389175888ec073b9b28f4305"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win32.whl", hash = "sha256:6ad02bab756751c90fa27f3069d7b12146613061341459abf55f8190d899649f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:b1472986fd9c5d318399a01a0881f4a0bf4950264131bb8e2deba9df6d8c362b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:c408f09649cbff8da76f8d3ad878b64ba7f7abdad1471efb293d2c075e80c822"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1bac4873f6186f5233b0084b266bfb459e997f4c21fc9f029918f44a9eccd304"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f9f12c2d0aa52b86206d2059916153876a9b1cf9dfb3cf2f344913167f1c3d4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd501de6f7a8f83557d20613b58734d1cb5f0be78d794cde64fe43cfc63f5f2"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4416ca69af933d4a8ad30910149d3db6d084781d5c5fdedb713205389f535385"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f0821b9bdf18c5b7d51722b906b233a39b17f602501a966cfbd9b285f8ab83cd"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0edecc3f90c2653298d380f6ea73b536944b767520c2179ec5d40b9145e47aa"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4513dd01cee11e354c31b75f652d4d466c9440b6859f84e600bdebfccb17735a"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d9727b85511b912571a76ce53c7640ba2c44c364e71cef6d7359b5412739c570"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ab9eab33ee3213f7751dc07a1a61b8d9a3d748ca4458fffddd9defa6f0493c16"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:6b01c1ddbb054283797967ddc5433d5c108d680e8fa2684cf368be05407b07e4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:3857e335f97058c4b46fa39ca831290b70de554a5c5af0323d2f163b19c5f2a6"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d98a46cf07c0c875d27e8a7ed50f304d83063e49b9ab63f21c19c154b4c0d08d"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win32.whl", hash = "sha256:c36539ed2c0173b053dafb221458812e178cfa3224ade0960599bec194637048"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:ec8d7d8567e14af34a7911c98f5ac74a3d4a743cd848643341fc92b12b3784ff"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_arm64.whl", hash = "sha256:62171b270ecc4071be1c1f99960317db261d4c8c83c169e7f8ad119211fe7397"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f06e3c4c0a8badfc4910b9fd15beb1ad8f3b8fafa8ea82c023e5e607b66a78e4"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fe7aaf5a54821d340d21412f7f6e6272a9b17a0cbafc1d68f77f2fc11009dcd5"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25398d9ac7294e99876a3027ffc52c6bebeb2d702b1895af6ae9c541ee676702"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a52eea839e4bdc72c5e60a444d26004da00bb5bc6301e99b3dde18212e41465"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c87319b0ab9d269ab84f6453601fd49b35d9e4a601bbaef43743f26fabf496c"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3048c6ed29d693fba7d2a7caf165f5e0bb2b9743a0989012a98a47b975355cca"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b04f29735bad9f06bb731c214f27253bd8bedb248ef9b8a1b4c5bde65b838454"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7864e80a0d4e23eb6194254a81ee1216abdc53f9dc85b7f4d56668eced022eb8"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3794df87313dfb56fafd679b962e0613c88a293fd9bd5dd5c2793d66bf06a101"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d71da0012face6f45432a11bc59af19e62fac5a41f8ce489e80c0add8153c3d1"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff38378346b7018f42cbc1f6d1d3778e36e16d8595f79a312b31e7c25c50bd08"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6668321f90aa02a5a789d4e16058f2e4f2692c5230252425c3532a8a62bc3424"}, + {file = "rapidfuzz-3.11.0.tar.gz", hash = "sha256:a53ca4d3f52f00b393fab9b5913c5bafb9afc27d030c8a1db1283da6917a860f"}, +] + +[package.extras] +all = ["numpy"] + +[[package]] +name = "regex" +version = "2024.11.6" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.8" +files = [ + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, +] + [[package]] name = "requests" version = "2.32.3" @@ -1261,34 +1774,68 @@ files = [ requests = ">=2.0.1,<3.0.0" [[package]] -name = "setuptools" -version = "75.2.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" +name = "serpyco-rs" +version = "1.11.0" +description = "" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4b2bd933539bd8c84315e2fb5ae52ef7a58ace5a6dfe3f8b73f74dc71216779e"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:627f957889ff73c4d2269fc7b6bba93212381befe03633e7cb5495de66ba9a33"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b0933620abc01434023e0e3e22255b7e4ab9b427b5a9a5ee00834656d792377a"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9ce46683d92e34abb20304817fc5ac6cb141a06fc7468dedb1d8865a8a9682f6"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bda437d86e8859bf91c189c1f4650899822f6d6d7b02b48f5729da904eb7bb7d"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a72bfbd282af17ebe76d122639013e802c09902543fdbbd828fb2159ec9755e"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d4808df5384e3e8581e31a90ba7a1fa501c0837b1f174284bb8a4555b6864ea"}, + {file = "serpyco_rs-1.11.0-cp310-none-win_amd64.whl", hash = "sha256:c7b60aef4c16d68efb0d6241f05d0a434d873d98449cbb4366b0d385f0a7172b"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d47ee577cf4d69b53917615cb031ad8708eb2f59fe78194b1968c13130fc2f7"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6090d9a1487237cdd4e9362a823eede23249602019b917e7bd57846179286e79"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7192eb3df576386fefd595ea31ae25c62522841ffec7e7aeb37a80b55bdc3213"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b52ef8affb7e71b9b98a7d5216d6a7ad03b04e990acb147cd9211c8b931c5487"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3480e09e473560c60e74aaa789e6b4d079637371aae0a98235440111464bbba7"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c92e36b0ab6fe866601c2331f7e99c809a126d21963c03d8a5c29331526deed"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84f497361952d4566bc1f77e9e15a84a2614f593cc671fbf0a0fa80046f9c3d7"}, + {file = "serpyco_rs-1.11.0-cp311-none-win_amd64.whl", hash = "sha256:37fc1cf192bef9784fbf1f4e03cec21750b9e704bef55cc0442f71a715eee920"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3ea93d485f03dc8b0cfb0d477f0ad2e86e78f0461b53010656ab5b4db1b41fb0"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7772410d15694b03f9c5500a2c47d62eed76e191bea4087ad042250346b1a38e"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42118463c1679846cffd2f06f47744c9b9eb33c5d0448afd88ea19e1a81a8ddd"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:79481a455b76cc56021dc55bb6d5bdda1b2b32bcb6a1ee711b597140d112e9b1"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8fd79051f9af9591fc03cf7d3033ff180416301f6a4fd3d1e3d92ebd2d68697"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d29c8f9aeed734a3b51f7349d04ec9063516ffa4e10b632d75e9b1309e4930e4"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15609158b0d9591ffa118302cd9d0039970cb3faf91dce32975f7d276e7411d5"}, + {file = "serpyco_rs-1.11.0-cp312-none-win_amd64.whl", hash = "sha256:00081eae77fbf4c5d88371c5586317ab02ccb293a330b460869a283edf2b7b69"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3028893366a1985adcedb13fa8f6f98c087c185efc427f94c2ccdafa40f45832"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c18bf511316f3abf648a68ee62ef88617bec57d3fcde69466b4361102715ae5"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7dde9ef09cdfaf7c62378186b9e29f54ec76114be4c347be6a06dd559c5681e"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:18500ebc5e75285841e35585a238629a990b709e14f68933233640d15ca17d5f"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47c23132d4e03982703a7630aa09877b41e499722142f76b6153f6619b612f3"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5f8e6ba499f6a0825bee0d8f8764569d367af871b563fc6512c171474e8e5383"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15438a076047c34cff6601a977df54948e8d39d1a86f89d05c48bc60f4c12a61"}, + {file = "serpyco_rs-1.11.0-cp313-none-win_amd64.whl", hash = "sha256:84ee2c109415bd81904fc9abb9aec86a5dd13166808c21142cf23ec639f683bd"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5c97c16c865261577fac4effeccc7ef5e0a1e8e35e7a3ee6c90c77c3a4cd7ff9"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47825e70f86fd6ef7c4a835dea3d6e8eef4fee354ed7b39ced99f31aba74a86e"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24d220220365110edba2f778f41ab3cf396883da0f26e1361a3ada9bd0227f73"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3a46f334af5a9d77acc6e1e58f355ae497900a2798929371f0545e274f6e6166"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d72b748acce4b4e3c7c9724e1eb33d033a1c26b08a698b393e0288060e0901"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2b8b6f205e8cc038d4d30dd0e70eece7bbecc816eb2f3787c330dc2218e232d"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:038d748bfff31f150f0c3edab2766b8843edb952cb1bd3bf547886beb0912dae"}, + {file = "serpyco_rs-1.11.0-cp39-none-win_amd64.whl", hash = "sha256:0fee1c89ec2cb013dc232e4ebef88e2844357ce8631063b56639dbfb83762f20"}, + {file = "serpyco_rs-1.11.0.tar.gz", hash = "sha256:70a844615ffb229e6e89c204b3ab7404aacaf2838911814c7d847969b8da2e3a"}, ] -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +[package.dependencies] +attributes-doc = "*" +typing-extensions = "*" [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1319,15 +1866,66 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "tomli" -version = "2.0.2" +version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] +[[package]] +name = "tqdm" +version = "4.67.1" +description = "Fast, Extensible Progress Meter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + [[package]] name = "typing-extensions" version = "4.12.2" @@ -1339,6 +1937,28 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] +[[package]] +name = "tzdata" +version = "2024.2" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, + {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, +] + +[[package]] +name = "unidecode" +version = "1.3.8" +description = "ASCII transliterations of Unicode text" +optional = false +python-versions = ">=3.5" +files = [ + {file = "Unidecode-1.3.8-py3-none-any.whl", hash = "sha256:d130a61ce6696f8148a3bd8fe779c99adeb4b870584eeb9526584e9aa091fd39"}, + {file = "Unidecode-1.3.8.tar.gz", hash = "sha256:cfdb349d46ed3873ece4586b96aa75258726e2fa8ec21d6f00a591d98806c2f4"}, +] + [[package]] name = "url-normalize" version = "1.4.3" @@ -1355,13 +1975,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1372,98 +1992,30 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "wcmatch" -version = "8.4" +version = "10.0" description = "Wildcard/glob file name matcher." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, + {file = "wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a"}, + {file = "wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a"}, ] [package.dependencies] bracex = ">=2.1.1" [[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." +name = "xmltodict" +version = "0.13.0" +description = "Makes working with XML feel like you are working with JSON" optional = false -python-versions = ">=3.6" +python-versions = ">=3.4" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "xmltodict-0.13.0-py2.py3-none-any.whl", hash = "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"}, + {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"}, ] [metadata] lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "5b0cd125a4941563e47d35d2a1603eb16db2c74dd30a0ea65043dfabe1a82cd9" +python-versions = "^3.10,<3.12" +content-hash = "f574598eb867859296c6c6457f8c3d8aafc6ec4e04f9dd84004ccf7e11960b38" diff --git a/airbyte-integrations/connectors/source-asana/pyproject.toml b/airbyte-integrations/connectors/source-asana/pyproject.toml index f13fbdc682fc..9908568695d1 100644 --- a/airbyte-integrations/connectors/source-asana/pyproject.toml +++ b/airbyte-integrations/connectors/source-asana/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "1.2.13" +version = "1.3.4" name = "source-asana" description = "Source implementation for asana." authors = [ "Airbyte ",] @@ -15,8 +15,8 @@ repository = "https://github.com/airbytehq/airbyte" packages = [ { include = "source_asana" }, {include = "main.py" } ] [tool.poetry.dependencies] -python = "^3.9,<3.12" -airbyte-cdk = "^1" +python = "^3.10,<3.12" +airbyte-cdk = "^6" [tool.poetry.scripts] source-asana = "source_asana.run:run" diff --git a/airbyte-integrations/connectors/source-asana/source_asana/components.py b/airbyte-integrations/connectors/source-asana/source_asana/components.py index 41595bc273bd..528d372c222b 100644 --- a/airbyte-integrations/connectors/source-asana/source_asana/components.py +++ b/airbyte-integrations/connectors/source-asana/source_asana/components.py @@ -7,10 +7,11 @@ from pkgutil import get_data from typing import Any, Mapping, MutableMapping, Optional, Union +from yaml import safe_load + from airbyte_cdk.sources.declarative.requesters.http_requester import HttpRequester from airbyte_cdk.sources.declarative.requesters.request_options.interpolated_request_input_provider import InterpolatedRequestInputProvider from airbyte_cdk.sources.declarative.types import StreamSlice, StreamState -from yaml import safe_load @dataclass diff --git a/airbyte-integrations/connectors/source-asana/source_asana/config_migration.py b/airbyte-integrations/connectors/source-asana/source_asana/config_migration.py index 64c2ff3945eb..60ae8c42cb5a 100644 --- a/airbyte-integrations/connectors/source-asana/source_asana/config_migration.py +++ b/airbyte-integrations/connectors/source-asana/source_asana/config_migration.py @@ -11,6 +11,7 @@ from airbyte_cdk.sources import Source from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-asana/source_asana/manifest.yaml b/airbyte-integrations/connectors/source-asana/source_asana/manifest.yaml index a9ccb7add2db..f7f1ce148ff5 100644 --- a/airbyte-integrations/connectors/source-asana/source_asana/manifest.yaml +++ b/airbyte-integrations/connectors/source-asana/source_asana/manifest.yaml @@ -2599,6 +2599,17 @@ spec: title: Organization Export IDs description: Globally unique identifiers for the organization exports type: array + num_workers: + type: integer + title: Number of concurrent workers + minimum: 1 + maximum: 25 + default: 10 + examples: [1, 2, 3] + description: >- + The number of worker threads to use for the sync. + The performance upper boundary is based on the limit of your Asana pricing plan. + More info about the rate limit tiers can be found on Asana's API docs. advanced_auth: auth_flow_type: oauth2.0 predicate_key: @@ -2654,3 +2665,19 @@ metadata: custom_fields: false organization_exports: false events: false + +# Asana rate limiting has two tiers: +# - Free: 2.5 req/s, 150 req/min +# - Paid: 25 req/s, 1500 req/min +# +# In addition, Asana has a cap on the maximum number of requests in progress concurrently depending +# on the endpoint HTTP method: +# - GET: 50 concurrent requests (We're already capping at 25 req/sec, but 50 should be the absolute ceiling) +# - POST/PUT/PATCH/DELETE: 5 concurrent requests (We don't have any streams using these methods) +# +# Lastly, a few specific endpoints have stricter limitation although neither are used at the moment: +# - /search: 60 req/min +concurrency_level: + type: ConcurrencyLevel + default_concurrency: "{{ config.get('num_workers', 3) }}" + max_concurrency: 25 diff --git a/airbyte-integrations/connectors/source-asana/source_asana/run.py b/airbyte-integrations/connectors/source-asana/source_asana/run.py index ad0ba7858788..221a9a071af1 100644 --- a/airbyte-integrations/connectors/source-asana/source_asana/run.py +++ b/airbyte-integrations/connectors/source-asana/source_asana/run.py @@ -1,17 +1,57 @@ # -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. # import sys +import traceback +from datetime import datetime +from typing import List -from airbyte_cdk.entrypoint import launch +from orjson import orjson from source_asana import SourceAsana +from airbyte_cdk.entrypoint import AirbyteEntrypoint, launch +from airbyte_cdk.models import AirbyteErrorTraceMessage, AirbyteMessage, AirbyteMessageSerializer, AirbyteTraceMessage, TraceType, Type + from .config_migration import AsanaConfigMigration +def _get_source(args: List[str]): + catalog_path = AirbyteEntrypoint.extract_catalog(args) + config_path = AirbyteEntrypoint.extract_config(args) + state_path = AirbyteEntrypoint.extract_state(args) + try: + return SourceAsana( + SourceAsana.read_catalog(catalog_path) if catalog_path else None, + SourceAsana.read_config(config_path) if config_path else None, + SourceAsana.read_state(state_path) if state_path else None, + ) + except Exception as error: + print( + orjson.dumps( + AirbyteMessageSerializer.dump( + AirbyteMessage( + type=Type.TRACE, + trace=AirbyteTraceMessage( + type=TraceType.ERROR, + emitted_at=int(datetime.now().timestamp() * 1000), + error=AirbyteErrorTraceMessage( + message=f"Error starting the sync. This could be due to an invalid configuration or catalog. Please contact Support for assistance. Error: {error}", + stack_trace=traceback.format_exc(), + ), + ), + ) + ) + ).decode() + ) + return None + + def run(): - source = SourceAsana() + _args = sys.argv[1:] + source = _get_source(_args) + # need to verify that we can run this migration script after instantiating the source AsanaConfigMigration.migrate(sys.argv[1:], source) - launch(source, sys.argv[1:]) + if source: + launch(source, _args) diff --git a/airbyte-integrations/connectors/source-asana/source_asana/source.py b/airbyte-integrations/connectors/source-asana/source_asana/source.py index aca18cda68cf..4e4efe46b638 100644 --- a/airbyte-integrations/connectors/source-asana/source_asana/source.py +++ b/airbyte-integrations/connectors/source-asana/source_asana/source.py @@ -2,7 +2,12 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # +from typing import Any, Mapping, Optional + +from airbyte_cdk.models import ConfiguredAirbyteCatalog from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource +from airbyte_cdk.sources.source import TState + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into @@ -14,5 +19,5 @@ # Declarative Source class SourceAsana(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) + def __init__(self, catalog: Optional[ConfiguredAirbyteCatalog], config: Optional[Mapping[str, Any]], state: TState, **kwargs): + super().__init__(catalog=catalog, config=config, state=state, **{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-asana/unit_tests/test_config_migrations.py b/airbyte-integrations/connectors/source-asana/unit_tests/test_config_migrations.py index fd7701e95033..4bb360ca2e2a 100644 --- a/airbyte-integrations/connectors/source-asana/unit_tests/test_config_migrations.py +++ b/airbyte-integrations/connectors/source-asana/unit_tests/test_config_migrations.py @@ -5,19 +5,27 @@ from source_asana.config_migration import AsanaConfigMigration from source_asana.source import SourceAsana + TEST_CONFIG_PATH = f"{os.path.dirname(__file__)}/test_config.json" def test_should_migrate(): assert AsanaConfigMigration.should_migrate({"access_token": "asdfcxz"}) is True - assert AsanaConfigMigration.should_migrate({"credentials": { "option_title": "PAT Credentials", "personal_access_token": "1206938133417909" }} -) is False + assert ( + AsanaConfigMigration.should_migrate( + {"credentials": {"option_title": "PAT Credentials", "personal_access_token": "1206938133417909"}} + ) + is False + ) def test__modify_and_save(): - source = SourceAsana() user_config = {"access_token": "asdfcxz"} - expected = {"credentials": { "option_title": "PAT Credentials", "personal_access_token": "asdfcxz" }} + expected = {"credentials": {"option_title": "PAT Credentials", "personal_access_token": "asdfcxz"}} + + # todo: need to make the migrate a classmethod instead of staticmethod since the missing config field will fail validation + source = SourceAsana(config=user_config, catalog=None, state=None) + modified_config = AsanaConfigMigration.modify_and_save(config_path=TEST_CONFIG_PATH, source=source, config=user_config) assert modified_config["credentials"]["personal_access_token"] == user_config["access_token"] assert modified_config["credentials"]["personal_access_token"] == expected["credentials"]["personal_access_token"] diff --git a/airbyte-integrations/connectors/source-ashby/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-ashby/integration_tests/acceptance.py index efc25f08ce82..78b220cebb18 100644 --- a/airbyte-integrations/connectors/source-ashby/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-ashby/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-ashby/metadata.yaml b/airbyte-integrations/connectors/source-ashby/metadata.yaml index 705f8ce529ed..f3a637f73e83 100644 --- a/airbyte-integrations/connectors/source-ashby/metadata.yaml +++ b/airbyte-integrations/connectors/source-ashby/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 4e8c9fa0-3634-499b-b948-11581b5c3efa - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-ashby githubIssueLabel: source-ashby icon: ashby.svg @@ -29,5 +29,5 @@ data: connectorTestSuitesOptions: - suite: unitTests connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-auth0/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-auth0/integration_tests/acceptance.py index d49b55882333..a9256a533972 100644 --- a/airbyte-integrations/connectors/source-auth0/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-auth0/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-avni/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-avni/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-avni/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-avni/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-avni/main.py b/airbyte-integrations/connectors/source-avni/main.py index 5ab8e86addc5..7ff1ad92a8b0 100644 --- a/airbyte-integrations/connectors/source-avni/main.py +++ b/airbyte-integrations/connectors/source-avni/main.py @@ -5,9 +5,11 @@ import sys -from airbyte_cdk.entrypoint import launch from source_avni import SourceAvni +from airbyte_cdk.entrypoint import launch + + if __name__ == "__main__": source = SourceAvni() launch(source, sys.argv[1:]) diff --git a/airbyte-integrations/connectors/source-avni/source_avni/components.py b/airbyte-integrations/connectors/source-avni/source_avni/components.py index d47cbf7654f6..782f0f2100ef 100644 --- a/airbyte-integrations/connectors/source-avni/source_avni/components.py +++ b/airbyte-integrations/connectors/source-avni/source_avni/components.py @@ -4,6 +4,7 @@ import boto3 import requests + from airbyte_cdk.sources.declarative.auth.token import BasicHttpAuthenticator @@ -11,7 +12,6 @@ class CustomAuthenticator(BasicHttpAuthenticator): @property def token(self) -> str: - username = self._username.eval(self.config) password = self._password.eval(self.config) @@ -29,7 +29,6 @@ def auth_header(self) -> str: return "auth-token" def get_client_id(self): - url_client = "https://app.avniproject.org/idp-details" response = requests.get(url_client) response.raise_for_status() diff --git a/airbyte-integrations/connectors/source-avni/source_avni/run.py b/airbyte-integrations/connectors/source-avni/source_avni/run.py index 636ce2134b8d..4b1154b784ae 100644 --- a/airbyte-integrations/connectors/source-avni/source_avni/run.py +++ b/airbyte-integrations/connectors/source-avni/source_avni/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_avni import SourceAvni +from airbyte_cdk.entrypoint import launch + def run(): source = SourceAvni() diff --git a/airbyte-integrations/connectors/source-avni/source_avni/source.py b/airbyte-integrations/connectors/source-avni/source_avni/source.py index e6c65ceadb7d..23d6f53b3e51 100644 --- a/airbyte-integrations/connectors/source-avni/source_avni/source.py +++ b/airbyte-integrations/connectors/source-avni/source_avni/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-avni/unit_tests/test_components.py b/airbyte-integrations/connectors/source-avni/unit_tests/test_components.py index 49f77bed58ec..2ac44c6aaf65 100644 --- a/airbyte-integrations/connectors/source-avni/unit_tests/test_components.py +++ b/airbyte-integrations/connectors/source-avni/unit_tests/test_components.py @@ -7,14 +7,13 @@ from source_avni.components import CustomAuthenticator -@patch('boto3.client') +@patch("boto3.client") def test_token_property(mock_boto3_client): - mock_cognito_client = Mock() mock_boto3_client.return_value = mock_cognito_client - config= { "username": "example@gmail.com", "api_key": "api_key" } - source = CustomAuthenticator(config=config,username="example@gmail.com",password="api_key",parameters="") + config = {"username": "example@gmail.com", "api_key": "api_key"} + source = CustomAuthenticator(config=config, username="example@gmail.com", password="api_key", parameters="") source._username = Mock() source._username.eval.return_value = "test_username" source._password = Mock() @@ -22,24 +21,18 @@ def test_token_property(mock_boto3_client): source.get_client_id = Mock() source.get_client_id.return_value = "test_client_id" - mock_cognito_client.initiate_auth.return_value = { - "AuthenticationResult": { - "IdToken": "test_id_token" - } - } + mock_cognito_client.initiate_auth.return_value = {"AuthenticationResult": {"IdToken": "test_id_token"}} token = source.token mock_boto3_client.assert_called_once_with("cognito-idp", region_name="ap-south-1") mock_cognito_client.initiate_auth.assert_called_once_with( - ClientId="test_client_id", - AuthFlow="USER_PASSWORD_AUTH", - AuthParameters={"USERNAME": "test_username", "PASSWORD": "test_password"} + ClientId="test_client_id", AuthFlow="USER_PASSWORD_AUTH", AuthParameters={"USERNAME": "test_username", "PASSWORD": "test_password"} ) assert token == "test_id_token" + def test_get_client_id(mocker): - - config= { "username": "example@gmail.com", "api_key": "api_key" } - source = CustomAuthenticator(config=config,username="example@gmail.com",password="api_key",parameters="") + config = {"username": "example@gmail.com", "api_key": "api_key"} + source = CustomAuthenticator(config=config, username="example@gmail.com", password="api_key", parameters="") client_id = source.get_client_id() expected_length = 26 - assert len(client_id) == expected_length \ No newline at end of file + assert len(client_id) == expected_length diff --git a/airbyte-integrations/connectors/source-aws-cloudtrail/README.md b/airbyte-integrations/connectors/source-aws-cloudtrail/README.md index 495ea1871042..9af9b3a6753b 100644 --- a/airbyte-integrations/connectors/source-aws-cloudtrail/README.md +++ b/airbyte-integrations/connectors/source-aws-cloudtrail/README.md @@ -1,111 +1,65 @@ -# Aws-Cloudtrail source connector +# AWS Cloudtrail source connector +This directory contains the manifest-only connector for `source-aws-cloudtrail`. +This _manifest-only_ connector is not a Python package on its own, as it runs inside of the base `source-declarative-manifest` image. -This is the repository for the Aws Cloudtrail configuration based source connector. -For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.com/integrations/sources/aws-cloudtrail). +For information about how to configure and use this connector within Airbyte, see [the connector's full documentation](https://docs.airbyte.com/integrations/sources/aws-cloudtrail). ## Local development -### Prerequisites +We recommend using the Connector Builder to edit this connector. +Using either Airbyte Cloud or your local Airbyte OSS instance, navigate to the **Builder** tab and select **Import a YAML**. +Then select the connector's `manifest.yaml` file to load the connector into the Builder. You're now ready to make changes to the connector! -* Python (`^3.9`) -* Poetry (`^1.7`) - installation instructions [here](https://python-poetry.org/docs/#installation) +If you prefer to develop locally, you can follow the instructions below. +### Building the docker image +You can build any manifest-only connector with `airbyte-ci`: -### Installing the connector +1. Install [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md) +2. Run the following command to build the docker image: -From this connector directory, run: ```bash -poetry install --with dev +airbyte-ci connectors --name=source-aws-cloudtrail build ``` +An image will be available on your host with the tag `airbyte/source-aws-cloudtrail:dev`. -### Create credentials +### Creating credentials **If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/aws-cloudtrail) -to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `spec` inside `manifest.yaml` file. +to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `spec` object in the connector's `manifest.yaml` file. Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. -See `integration_tests/sample_config.json` for a sample config file. - - -### Locally running the connector - - -``` -poetry run source-aws-cloudtrail spec -poetry run source-aws-cloudtrail check --config secrets/config.json -poetry run source-aws-cloudtrail discover --config secrets/config.json -poetry run source-aws-cloudtrail read --config secrets/config.json --catalog integration_tests/configured_catalog.json -``` -### Running tests +### Running as a docker container -To run tests locally, from the connector directory run: +Then run any of the standard source connector commands: -``` -poetry run pytest tests -``` - -### Building the docker image - -1. Install [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md) -2. Run the following command to build the docker image: ```bash -airbyte-ci connectors --name source-aws-cloudtrail build -``` - -An image will be available on your host with the tag `airbyte/source-aws-cloudtrail:dev`. - - -### Running as a docker container - -### Running as a docker container -Then run any of the connector commands as follows: -``` docker run --rm airbyte/source-aws-cloudtrail:dev spec docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-aws-cloudtrail:dev check --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-aws-cloudtrail:dev discover --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-aws-cloudtrail:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json ``` -### Running our CI test suite +### Running the CI test suite You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): -```bash -airbyte-ci connectors --name=source-aws-cloudtrail test -``` - -### Customizing acceptance Tests - -Customize `acceptance-test-config.yml` file to configure acceptance tests. See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) for more information. -If your connector requires to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py. - -### Dependency Management -All of your dependencies should be managed via Poetry. -To add a new dependency, run: ```bash -poetry add +airbyte-ci connectors --name=source-aws-cloudtrail test ``` -Please commit the changes to `pyproject.toml` and `poetry.lock` files. - ## Publishing a new version of the connector -You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what? -1. Make sure your changes are passing our test suite: `airbyte-ci connectors --name=source-aws-cloudtrail test` -2. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): +If you want to contribute changes to `source-aws-cloudtrail`, here's how you can do that: +1. Make your changes locally, or load the connector's manifest into Connector Builder and make changes there. +2. Make sure your changes are passing our test suite with `airbyte-ci connectors --name=source-aws-cloudtrail test` +3. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): - bump the `dockerImageTag` value in in `metadata.yaml` - - bump the `version` value in `pyproject.toml` -2. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): - - bump the `dockerImageTag` value in in `metadata.yaml` - - bump the `version` value in `pyproject.toml` -3. Make sure the `metadata.yaml` content is up to date. -4. Make sure the connector documentation and its changelog is up to date (`docs/integrations/sources/aws-cloudtrail.md`). 4. Make sure the connector documentation and its changelog is up to date (`docs/integrations/sources/aws-cloudtrail.md`). 5. Create a Pull Request: use [our PR naming conventions](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#pull-request-title-convention). 6. Pat yourself on the back for being an awesome contributor. 7. Someone from Airbyte will take a look at your PR and iterate with you to merge it into master. 8. Once your PR is merged, the new version of the connector will be automatically published to Docker Hub and our connector registry. -8. Once your PR is merged, the new version of the connector will be automatically published to Docker Hub and our connector registry. \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-aws-cloudtrail/__init__.py b/airbyte-integrations/connectors/source-aws-cloudtrail/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-integrations/connectors/source-aws-cloudtrail/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-integrations/connectors/source-aws-cloudtrail/acceptance-test-config.yml b/airbyte-integrations/connectors/source-aws-cloudtrail/acceptance-test-config.yml index 8618350c4f35..a576348ee455 100644 --- a/airbyte-integrations/connectors/source-aws-cloudtrail/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-aws-cloudtrail/acceptance-test-config.yml @@ -4,7 +4,7 @@ connector_image: airbyte/source-aws-cloudtrail:dev acceptance_tests: spec: tests: - - spec_path: "source_aws_cloudtrail/spec.yaml" + - spec_path: "manifest.yaml" backward_compatibility_tests_config: disable_for_version: 0.1.11 # The spec has additional filtering property connection: diff --git a/airbyte-integrations/connectors/source-aws-cloudtrail/components.py b/airbyte-integrations/connectors/source-aws-cloudtrail/components.py new file mode 100644 index 000000000000..b99a2a62f301 --- /dev/null +++ b/airbyte-integrations/connectors/source-aws-cloudtrail/components.py @@ -0,0 +1,114 @@ +# +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. +# + +import datetime +import hashlib +import hmac +import json +from dataclasses import InitVar, dataclass +from typing import Any, Mapping, Union + +import requests + +from airbyte_cdk.sources.declarative.auth.declarative_authenticator import NoAuth +from airbyte_cdk.sources.declarative.interpolation import InterpolatedString +from airbyte_cdk.sources.declarative.types import Config + + +@dataclass +class CustomAuthenticator(NoAuth): + config: Config + aws_key_id: Union[InterpolatedString, str] + aws_secret_key: Union[InterpolatedString, str] + aws_region_name: Union[InterpolatedString, str] + + def __post_init__(self, parameters: Mapping[str, Any]): + self._aws_key_id = InterpolatedString.create(self.aws_key_id, parameters=parameters).eval(self.config) + self._aws_secret_key = InterpolatedString.create(self.aws_secret_key, parameters=parameters).eval(self.config) + self._aws_region_name = InterpolatedString.create(self.aws_region_name, parameters=parameters).eval(self.config) + self.path = "/" + self.service = "cloudtrail" + + def __call__(self, request: requests.PreparedRequest) -> requests.PreparedRequest: + """Attach the HTTP headers required to authenticate on the HTTP request""" + self.headers = { + "Content-Type": "application/x-amz-json-1.1", + "Accept": "application/json", + "Host": f"cloudtrail.{self._aws_region_name}.amazonaws.com", + } + # StartTime and EndTime should be Unix timestamps with integer type + request_body_json = json.loads(request.body.decode("utf-8")) + if self.config.get("lookup_attributes_filter"): + lookup_attributes_filter = self.config.get("lookup_attributes_filter", {}) + attribute_key = lookup_attributes_filter.get("attribute_key", "") + attribute_value = lookup_attributes_filter.get("attribute_value", "") + + request_body_json["LookupAttributes"] = [{"AttributeKey": attribute_key, "AttributeValue": attribute_value}] + request_body_json["StartTime"] = int(float(request_body_json["StartTime"])) + request_body_json["EndTime"] = int(float(request_body_json["EndTime"])) + request.body = json.dumps(request_body_json).encode("utf-8") + # Sign the AWS Request and update headers with timestamp + authorization_header, amz_date = self.sign_aws_request( + self.service, + self._aws_region_name, + request.method, + self.path, + self.headers, + request_body_json, + self._aws_key_id, + self._aws_secret_key, + ) + self.headers["X-Amz-Date"] = amz_date + self.headers["Authorization"] = authorization_header + request.headers.update(self.headers) + return request + + @property + def auth_header(self) -> str: + return None + + @property + def token(self): + return None + + # AWS Cloudtrail Requires custom sign process with request, Referred from botocore client - https://github.com/boto/botocore/issues/786 + def sign_aws_request(self, service, region, method, path, headers, payload, aws_access_key, aws_secret_key): + # Define required parameters for signing + service = service + region = region + method = method + path = path + headers = headers + string_payload = json.dumps(payload) + payload_hash = hashlib.sha256(string_payload.encode()).hexdigest() + + # Generate timestamp and date for the request + amz_date = datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%SZ") + date_stamp = datetime.datetime.utcnow().strftime("%Y%m%d") + + # Generate canonical request + canonical_headers = "".join([f"{key.lower()}:{value.strip()}\n" for key, value in sorted(headers.items())]) + signed_headers = ";".join(sorted(key.lower() for key in headers)) + canonical_request = f"{method}\n{path}\n\n{canonical_headers}\n{signed_headers}\n{payload_hash}" + + # Generate string to sign + algorithm = "AWS4-HMAC-SHA256" + credential_scope = f"{date_stamp}/{region}/{service}/aws4_request" + string_to_sign = f"{algorithm}\n{amz_date}\n{credential_scope}\n" + hashlib.sha256(canonical_request.encode()).hexdigest() + + # Generate signing key + secret = ("AWS4" + aws_secret_key).encode() + k_date = hmac.new(secret, date_stamp.encode(), hashlib.sha256).digest() + k_region = hmac.new(k_date, region.encode(), hashlib.sha256).digest() + k_service = hmac.new(k_region, service.encode(), hashlib.sha256).digest() + k_signing = hmac.new(k_service, b"aws4_request", hashlib.sha256).digest() + + # Generate signature + signature = hmac.new(k_signing, string_to_sign.encode(), hashlib.sha256).hexdigest() + + # Generate authorization header + authorization_header = ( + f"{algorithm} Credential={aws_access_key}/{credential_scope}, " f"SignedHeaders={signed_headers}, Signature={signature}" + ) + return authorization_header, amz_date diff --git a/airbyte-integrations/connectors/source-aws-cloudtrail/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-aws-cloudtrail/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-aws-cloudtrail/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-aws-cloudtrail/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-aws-cloudtrail/main.py b/airbyte-integrations/connectors/source-aws-cloudtrail/main.py deleted file mode 100644 index f2324dfe8812..000000000000 --- a/airbyte-integrations/connectors/source-aws-cloudtrail/main.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from source_aws_cloudtrail.run import run - -if __name__ == "__main__": - run() diff --git a/airbyte-integrations/connectors/source-aws-cloudtrail/manifest.yaml b/airbyte-integrations/connectors/source-aws-cloudtrail/manifest.yaml new file mode 100644 index 000000000000..86146b1c23ed --- /dev/null +++ b/airbyte-integrations/connectors/source-aws-cloudtrail/manifest.yaml @@ -0,0 +1,422 @@ +version: "4.3.2" +definitions: + selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - "{{ parameters.extractor_path }}" + requester: + type: HttpRequester + url_base: "https://cloudtrail.{{ config['aws_region_name'] }}.amazonaws.com" + http_method: "POST" + authenticator: + type: CustomAuthenticator + class_name: source_declarative_manifest.components.CustomAuthenticator + aws_key_id: "{{config['aws_key_id']}}" + aws_secret_key: "{{config['aws_secret_key']}}" + aws_region_name: "{{config['aws_region_name']}}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: ExponentialBackoffStrategy + response_filters: + - type: HttpResponseFilter + action: RETRY + http_codes: + - 400 + incremental_sync_base: + type: DatetimeBasedCursor + datetime_format: "%s" + cursor_field: "EventTime" + start_time_option: + inject_into: body_json + field_name: StartTime + type: RequestOption + end_time_option: + inject_into: body_json + field_name: EndTime + type: RequestOption + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] or now_utc().strftime('%Y-%m-%d') }}" + datetime_format: "%Y-%m-%d" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%s') }}" + datetime_format: "%s" + paginator_base: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: "NextToken" + pagination_strategy: + type: CursorPagination + cursor_value: '{{ response.get("NextToken", {}) }}' + stop_condition: '{{ not response.get("NextToken", {}) }}' + management_events_stream: + type: DeclarativeStream + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + AccessKeyId: + type: + - "null" + - string + CloudTrailEvent: + type: + - "null" + - string + EventId: + type: + - "null" + - string + EventName: + type: + - "null" + - string + EventSource: + type: + - "null" + - string + EventTime: + type: + - "null" + - number + ReadOnly: + type: + - "null" + - string + Resources: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + ResourceName: + type: + - "null" + - string + ResourceType: + type: + - "null" + - string + Username: + type: + - "null" + - string + retriever: + type: SimpleRetriever + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - "{{ parameters.extractor_path }}" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: "NextToken" + pagination_strategy: + type: CursorPagination + cursor_value: '{{ response.get("NextToken", {}) }}' + stop_condition: '{{ not response.get("NextToken", {}) }}' + requester: + type: HttpRequester + url_base: "https://cloudtrail.{{ config['aws_region_name'] }}.amazonaws.com" + http_method: "POST" + authenticator: + type: CustomAuthenticator + class_name: source_declarative_manifest.components.CustomAuthenticator + aws_key_id: "{{config['aws_key_id']}}" + aws_secret_key: "{{config['aws_secret_key']}}" + aws_region_name: "{{config['aws_region_name']}}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: ExponentialBackoffStrategy + response_filters: + - type: HttpResponseFilter + action: RETRY + http_codes: + - 400 + request_headers: + x-amz-target: "com.amazonaws.cloudtrail.v20131101.CloudTrail_20131101.LookupEvents" + request_body_json: + MaxResults: 50 + incremental_sync: + type: DatetimeBasedCursor + datetime_format: "%s" + cursor_field: "EventTime" + start_time_option: + inject_into: body_json + field_name: StartTime + type: RequestOption + end_time_option: + inject_into: body_json + field_name: EndTime + type: RequestOption + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] or now_utc().strftime('%Y-%m-%d') }}" + datetime_format: "%Y-%m-%d" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%s') }}" + datetime_format: "%s" + management_events_schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + AccessKeyId: + type: + - "null" + - string + CloudTrailEvent: + type: + - "null" + - string + EventId: + type: + - "null" + - string + EventName: + type: + - "null" + - string + EventSource: + type: + - "null" + - string + EventTime: + type: + - "null" + - number + ReadOnly: + type: + - "null" + - string + Resources: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + ResourceName: + type: + - "null" + - string + ResourceType: + type: + - "null" + - string + Username: + type: + - "null" + - string +streams: +- type: DeclarativeStream + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + AccessKeyId: + type: + - "null" + - string + CloudTrailEvent: + type: + - "null" + - string + EventId: + type: + - "null" + - string + EventName: + type: + - "null" + - string + EventSource: + type: + - "null" + - string + EventTime: + type: + - "null" + - number + ReadOnly: + type: + - "null" + - string + Resources: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + ResourceName: + type: + - "null" + - string + ResourceType: + type: + - "null" + - string + Username: + type: + - "null" + - string + retriever: + type: SimpleRetriever + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - "{{ parameters.extractor_path }}" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: "NextToken" + pagination_strategy: + type: CursorPagination + cursor_value: '{{ response.get("NextToken", {}) }}' + stop_condition: '{{ not response.get("NextToken", {}) }}' + requester: + type: HttpRequester + url_base: "https://cloudtrail.{{ config['aws_region_name'] }}.amazonaws.com" + http_method: "POST" + authenticator: + type: CustomAuthenticator + class_name: source_declarative_manifest.components.CustomAuthenticator + aws_key_id: "{{config['aws_key_id']}}" + aws_secret_key: "{{config['aws_secret_key']}}" + aws_region_name: "{{config['aws_region_name']}}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: ExponentialBackoffStrategy + response_filters: + - type: HttpResponseFilter + action: RETRY + http_codes: + - 400 + request_headers: + x-amz-target: "com.amazonaws.cloudtrail.v20131101.CloudTrail_20131101.LookupEvents" + request_body_json: + MaxResults: 50 + path: "/" + incremental_sync: + type: DatetimeBasedCursor + datetime_format: "%s" + cursor_field: "EventTime" + start_time_option: + inject_into: body_json + field_name: StartTime + type: RequestOption + end_time_option: + inject_into: body_json + field_name: EndTime + type: RequestOption + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] or now_utc().strftime('%Y-%m-%d') }}" + datetime_format: "%Y-%m-%d" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%s') }}" + datetime_format: "%s" + name: "management_events" + primary_key: "EventId" +check: + type: CheckStream + stream_names: + - "management_events" +spec: + type: Spec + documentation_url: https://docs.airbyte.com/integrations/sources/aws-cloudtrail + connection_specification: + $schema: http://json-schema.org/draft-07/schema# + title: Aws CloudTrail Spec + type: object + required: + - aws_key_id + - aws_secret_key + - aws_region_name + additionalProperties: true + properties: + aws_key_id: + type: string + title: Key ID + description: AWS CloudTrail Access Key ID. See the docs + for more information on how to obtain this key. + airbyte_secret: true + aws_secret_key: + type: string + title: Secret Key + description: AWS CloudTrail Access Key ID. See the docs + for more information on how to obtain this key. + airbyte_secret: true + aws_region_name: + type: string + title: Region Name + description: The default AWS Region to use, for example, us-west-1 or us-west-2. + When specifying a Region inline during client initialization, this property + is named region_name. + default: "us-east-1" + start_date: + type: string + title: Start Date + description: "The date you would like to replicate data. Data in AWS CloudTrail + is available for last 90 days only. Format: YYYY-MM-DD." + examples: + - "2021-01-01" + pattern: "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" + format: date + lookup_attributes_filter: + title: Filter applied while fetching records based on AttributeKey and AttributeValue + which will be appended on the request body + type: object + required: + - attribute_key + - attribute_value + properties: + attribute_key: + type: string + title: Attribute Key from the response to filter + examples: + - "EventName" + default: "EventName" + attribute_value: + type: string + title: Corresponding value to the given attribute key + examples: + - "ListInstanceAssociations" + - "ConsoleLogin" + default: "ListInstanceAssociations" +type: DeclarativeSource diff --git a/airbyte-integrations/connectors/source-aws-cloudtrail/metadata.yaml b/airbyte-integrations/connectors/source-aws-cloudtrail/metadata.yaml index 4b1370ce4d1c..4a05990c5824 100644 --- a/airbyte-integrations/connectors/source-aws-cloudtrail/metadata.yaml +++ b/airbyte-integrations/connectors/source-aws-cloudtrail/metadata.yaml @@ -12,19 +12,21 @@ data: 1.0.0: upgradeDeadline: "2024-07-30" message: - "The verison migrates the Aws CloudTrail connector to the low-code framework for greater maintainability. - !! Important: The management_events stream changed it's EventTime field from integer to float. - The `start_date` parameter is now optional and the connector now takes current date as default start date " + "The verison migrates the Aws CloudTrail connector to the low-code + framework for greater maintainability. !! Important: The management_events + stream changed it's EventTime field from integer to float. The `start_date` + parameter is now optional and the connector now takes current date as default + start date " remoteRegistries: pypi: - enabled: true + enabled: false packageName: airbyte-source-aws-cloudtrail connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/source-declarative-manifest:5.15.0@sha256:09a84e0622f36393077332faf11cc239e77083fae5fa500592c049dca25888a7 connectorSubtype: api connectorType: source definitionId: 6ff047c0-f5d5-4ce5-8c81-204a830fa7e1 - dockerImageTag: 1.0.20 + dockerImageTag: 1.1.0 dockerRepository: airbyte/source-aws-cloudtrail githubIssueLabel: source-aws-cloudtrail icon: aws-cloudtrail.svg @@ -35,8 +37,8 @@ data: supportLevel: community documentationUrl: https://docs.airbyte.com/integrations/sources/aws-cloudtrail tags: - - language:python - cdk:low-code + - language:manifest-only connectorTestSuitesOptions: - suite: liveTests testConnections: diff --git a/airbyte-integrations/connectors/source-aws-cloudtrail/poetry.lock b/airbyte-integrations/connectors/source-aws-cloudtrail/poetry.lock deleted file mode 100644 index 4f716568ca0c..000000000000 --- a/airbyte-integrations/connectors/source-aws-cloudtrail/poetry.lock +++ /dev/null @@ -1,1469 +0,0 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. - -[[package]] -name = "airbyte-cdk" -version = "0.90.0" -description = "A framework for writing Airbyte Connectors." -optional = false -python-versions = "<4.0,>=3.9" -files = [ - {file = "airbyte_cdk-0.90.0-py3-none-any.whl", hash = "sha256:bd0aa5843cdc4901f2e482f0e86695ca4e6db83b65c5017799255dd20535cf56"}, - {file = "airbyte_cdk-0.90.0.tar.gz", hash = "sha256:25cefc010718bada5cce3f87e7ae93068630732c0d34ce5145f8ddf7457d4d3c"}, -] - -[package.dependencies] -airbyte-protocol-models = ">=0.9.0,<1.0" -backoff = "*" -cachetools = "*" -cryptography = ">=42.0.5,<43.0.0" -Deprecated = ">=1.2,<1.3" -dpath = ">=2.0.1,<2.1.0" -genson = "1.2.2" -isodate = ">=0.6.1,<0.7.0" -Jinja2 = ">=3.1.2,<3.2.0" -jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" -langchain_core = "0.1.42" -pendulum = "<3.0.0" -pydantic = ">=1.10.8,<2.0.0" -pyjwt = ">=2.8.0,<3.0.0" -pyrate-limiter = ">=3.1.0,<3.2.0" -python-dateutil = "*" -pytz = "2024.1" -PyYAML = ">=6.0.1,<7.0.0" -requests = "*" -requests_cache = "*" -wcmatch = "8.4" - -[package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] - -[[package]] -name = "airbyte-protocol-models" -version = "0.13.0" -description = "Declares the Airbyte Protocol." -optional = false -python-versions = ">=3.8" -files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, -] - -[package.dependencies] -pydantic = ">=1.9.2,<2.0.0" - -[[package]] -name = "anyio" -version = "4.6.2.post1" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.9" -files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, -] - -[package.dependencies] -exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} - -[package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] -trio = ["trio (>=0.26.1)"] - -[[package]] -name = "attrs" -version = "24.2.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" -files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, -] - -[package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] - -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "bracex" -version = "2.5.post1" -description = "Bash style brace expander." -optional = false -python-versions = ">=3.8" -files = [ - {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, - {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, -] - -[[package]] -name = "cachetools" -version = "5.5.0" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, - {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, -] - -[[package]] -name = "cattrs" -version = "24.1.2" -description = "Composable complex class support for attrs and dataclasses." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, - {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, -] - -[package.dependencies] -attrs = ">=23.1.0" -exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} - -[package.extras] -bson = ["pymongo (>=4.4.0)"] -cbor2 = ["cbor2 (>=5.4.6)"] -msgpack = ["msgpack (>=1.0.5)"] -msgspec = ["msgspec (>=0.18.5)"] -orjson = ["orjson (>=3.9.2)"] -pyyaml = ["pyyaml (>=6.0)"] -tomlkit = ["tomlkit (>=0.11.8)"] -ujson = ["ujson (>=5.7.0)"] - -[[package]] -name = "certifi" -version = "2024.8.30" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, -] - -[[package]] -name = "cffi" -version = "1.17.1" -description = "Foreign Function Interface for Python calling C code." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, - {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, - {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, - {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, - {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, - {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, - {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, - {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, - {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, - {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, - {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, - {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, - {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, - {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, - {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, - {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, -] - -[package.dependencies] -pycparser = "*" - -[[package]] -name = "charset-normalizer" -version = "3.4.0" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -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 = "cryptography" -version = "42.0.8" -description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -optional = false -python-versions = ">=3.7" -files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, -] - -[package.dependencies] -cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} - -[package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] -docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] -nox = ["nox"] -pep8test = ["check-sdist", "click", "mypy", "ruff"] -sdist = ["build"] -ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] -test-randomorder = ["pytest-randomly"] - -[[package]] -name = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - -[[package]] -name = "dpath" -version = "2.0.8" -description = "Filesystem-like pathing and searching for dictionaries" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dpath-2.0.8-py3-none-any.whl", hash = "sha256:f92f595214dd93a00558d75d4b858beee519f4cffca87f02616ad6cd013f3436"}, - {file = "dpath-2.0.8.tar.gz", hash = "sha256:a3440157ebe80d0a3ad794f1b61c571bef125214800ffdb9afc9424e8250fe9b"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "genson" -version = "1.2.2" -description = "GenSON is a powerful, user-friendly JSON Schema generator." -optional = false -python-versions = "*" -files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, -] - -[[package]] -name = "h11" -version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.7" -files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, -] - -[[package]] -name = "httpcore" -version = "1.0.6" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.13,<0.15" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<1.0)"] - -[[package]] -name = "httpx" -version = "0.27.2" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isodate" -version = "0.6.1" -description = "An ISO 8601 date/time/duration parser and formatter" -optional = false -python-versions = "*" -files = [ - {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, - {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "jinja2" -version = "3.1.4" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "jsonpatch" -version = "1.33" -description = "Apply JSON-Patches (RFC 6902)" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" -files = [ - {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, - {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, -] - -[package.dependencies] -jsonpointer = ">=1.9" - -[[package]] -name = "jsonpointer" -version = "3.0.0" -description = "Identify specific nodes in a JSON document (RFC 6901)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, - {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, -] - -[[package]] -name = "jsonref" -version = "0.2" -description = "An implementation of JSON Reference for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonref-0.2-py3-none-any.whl", hash = "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f"}, - {file = "jsonref-0.2.tar.gz", hash = "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697"}, -] - -[[package]] -name = "jsonschema" -version = "3.2.0" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, -] - -[package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" - -[package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] - -[[package]] -name = "langchain-core" -version = "0.1.42" -description = "Building applications with LLMs through composability" -optional = false -python-versions = "<4.0,>=3.8.1" -files = [ - {file = "langchain_core-0.1.42-py3-none-any.whl", hash = "sha256:c5653ffa08a44f740295c157a24c0def4a753333f6a2c41f76bf431cd00be8b5"}, - {file = "langchain_core-0.1.42.tar.gz", hash = "sha256:40751bf60ea5d8e2b2efe65290db434717ee3834870c002e40e2811f09d814e6"}, -] - -[package.dependencies] -jsonpatch = ">=1.33,<2.0" -langsmith = ">=0.1.0,<0.2.0" -packaging = ">=23.2,<24.0" -pydantic = ">=1,<3" -PyYAML = ">=5.3" -tenacity = ">=8.1.0,<9.0.0" - -[package.extras] -extended-testing = ["jinja2 (>=3,<4)"] - -[[package]] -name = "langsmith" -version = "0.1.137" -description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." -optional = false -python-versions = "<4.0,>=3.8.1" -files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, -] - -[package.dependencies] -httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" -pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} -requests = ">=2,<3" -requests-toolbelt = ">=1.0.0,<2.0.0" - -[[package]] -name = "markupsafe" -version = "3.0.2" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -files = [ - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, - {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, -] - -[[package]] -name = "orjson" -version = "3.10.10" -description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" -optional = false -python-versions = ">=3.8" -files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, -] - -[[package]] -name = "packaging" -version = "23.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, -] - -[[package]] -name = "pendulum" -version = "2.1.2" -description = "Python datetimes made easy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, - {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, - {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, - {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, - {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, - {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, - {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, - {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, - {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, - {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, - {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, -] - -[package.dependencies] -python-dateutil = ">=2.6,<3.0" -pytzdata = ">=2020.1" - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pycparser" -version = "2.22" -description = "C parser in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, - {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, -] - -[[package]] -name = "pydantic" -version = "1.10.18" -description = "Data validation and settings management using python type hints" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, -] - -[package.dependencies] -typing-extensions = ">=4.2.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] - -[[package]] -name = "pyjwt" -version = "2.9.0" -description = "JSON Web Token implementation in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, -] - -[package.extras] -crypto = ["cryptography (>=3.4.0)"] -dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] -docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] -tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] - -[[package]] -name = "pyrate-limiter" -version = "3.1.1" -description = "Python Rate-Limiter using Leaky-Bucket Algorithm" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, - {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, -] - -[package.extras] -all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] -docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] - -[[package]] -name = "pyrsistent" -version = "0.20.0" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7"}, - {file = "pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee"}, - {file = "pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d"}, - {file = "pyrsistent-0.20.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win32.whl", hash = "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d"}, - {file = "pyrsistent-0.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win32.whl", hash = "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf"}, - {file = "pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b"}, - {file = "pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4"}, -] - -[[package]] -name = "pytest" -version = "8.3.3" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=1.5,<2" -tomli = {version = ">=1", markers = "python_version < \"3.11\""} - -[package.extras] -dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-mock" -version = "3.14.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, -] - -[package.dependencies] -pytest = ">=6.2.5" - -[package.extras] -dev = ["pre-commit", "pytest-asyncio", "tox"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytz" -version = "2024.1" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, -] - -[[package]] -name = "pytzdata" -version = "2020.1" -description = "The Olson timezone database for Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, - {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-cache" -version = "1.2.1" -description = "A persistent cache for python requests" -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, - {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, -] - -[package.dependencies] -attrs = ">=21.2" -cattrs = ">=22.2" -platformdirs = ">=2.5" -requests = ">=2.22" -url-normalize = ">=1.4" -urllib3 = ">=1.25.5" - -[package.extras] -all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] -bson = ["bson (>=0.5)"] -docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] -dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] -json = ["ujson (>=5.4)"] -mongodb = ["pymongo (>=3)"] -redis = ["redis (>=3)"] -security = ["itsdangerous (>=2.0)"] -yaml = ["pyyaml (>=6.0.1)"] - -[[package]] -name = "requests-mock" -version = "1.12.1" -description = "Mock out responses from the requests package" -optional = false -python-versions = ">=3.5" -files = [ - {file = "requests-mock-1.12.1.tar.gz", hash = "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401"}, - {file = "requests_mock-1.12.1-py2.py3-none-any.whl", hash = "sha256:b1e37054004cdd5e56c84454cc7df12b25f90f382159087f4b6915aaeef39563"}, -] - -[package.dependencies] -requests = ">=2.22,<3" - -[package.extras] -fixture = ["fixtures"] - -[[package]] -name = "requests-toolbelt" -version = "1.0.0" -description = "A utility belt for advanced users of python-requests" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, - {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, -] - -[package.dependencies] -requests = ">=2.0.1,<3.0.0" - -[[package]] -name = "setuptools" -version = "75.3.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - -[[package]] -name = "tenacity" -version = "8.5.0" -description = "Retry code until it succeeds" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, - {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, -] - -[package.extras] -doc = ["reno", "sphinx"] -test = ["pytest", "tornado (>=4.5)", "typeguard"] - -[[package]] -name = "tomli" -version = "2.0.2" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "url-normalize" -version = "1.4.3" -description = "URL normalization for Python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, - {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "urllib3" -version = "2.2.3" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "wcmatch" -version = "8.4" -description = "Wildcard/glob file name matcher." -optional = false -python-versions = ">=3.7" -files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, -] - -[package.dependencies] -bracex = ">=2.1.1" - -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "acd5908c82765b55ec5859799db1bcbb616d044db689a3ba94346d8b1d2f9b5c" diff --git a/airbyte-integrations/connectors/source-aws-cloudtrail/pyproject.toml b/airbyte-integrations/connectors/source-aws-cloudtrail/pyproject.toml deleted file mode 100644 index 5594a26293ab..000000000000 --- a/airbyte-integrations/connectors/source-aws-cloudtrail/pyproject.toml +++ /dev/null @@ -1,27 +0,0 @@ -[build-system] -requires = [ "poetry-core>=1.0.0",] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -version = "1.0.20" -name = "source-aws-cloudtrail" -description = "Source implementation for aws-cloudtrail." -authors = [ "Airbyte ",] -license = "MIT" -readme = "README.md" -documentation = "https://docs.airbyte.com/integrations/sources/aws-cloudtrail" -homepage = "https://airbyte.com" -repository = "https://github.com/airbytehq/airbyte" -packages = [ { include = "source_aws_cloudtrail" }, {include = "main.py" } ] - -[tool.poetry.dependencies] -python = "^3.9,<3.12" -airbyte-cdk = "^0" - -[tool.poetry.scripts] -source-aws-cloudtrail = "source_aws_cloudtrail.run:run" - -[tool.poetry.group.dev.dependencies] -requests-mock = "*" -pytest-mock = "*" -pytest = "*" diff --git a/airbyte-integrations/connectors/source-aws-cloudtrail/source_aws_cloudtrail/__init__.py b/airbyte-integrations/connectors/source-aws-cloudtrail/source_aws_cloudtrail/__init__.py deleted file mode 100644 index 96885851ecf4..000000000000 --- a/airbyte-integrations/connectors/source-aws-cloudtrail/source_aws_cloudtrail/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from .source import SourceAwsCloudtrail - -__all__ = ["SourceAwsCloudtrail"] diff --git a/airbyte-integrations/connectors/source-aws-cloudtrail/source_aws_cloudtrail/components.py b/airbyte-integrations/connectors/source-aws-cloudtrail/source_aws_cloudtrail/components.py deleted file mode 100644 index c2cf082ef31f..000000000000 --- a/airbyte-integrations/connectors/source-aws-cloudtrail/source_aws_cloudtrail/components.py +++ /dev/null @@ -1,113 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -import datetime -import hashlib -import hmac -import json -from dataclasses import InitVar, dataclass -from typing import Any, Mapping, Union - -import requests -from airbyte_cdk.sources.declarative.auth.declarative_authenticator import NoAuth -from airbyte_cdk.sources.declarative.interpolation import InterpolatedString -from airbyte_cdk.sources.declarative.types import Config - - -@dataclass -class CustomAuthenticator(NoAuth): - config: Config - aws_key_id: Union[InterpolatedString, str] - aws_secret_key: Union[InterpolatedString, str] - aws_region_name: Union[InterpolatedString, str] - - def __post_init__(self, parameters: Mapping[str, Any]): - self._aws_key_id = InterpolatedString.create(self.aws_key_id, parameters=parameters).eval(self.config) - self._aws_secret_key = InterpolatedString.create(self.aws_secret_key, parameters=parameters).eval(self.config) - self._aws_region_name = InterpolatedString.create(self.aws_region_name, parameters=parameters).eval(self.config) - self.path = "/" - self.service = "cloudtrail" - - def __call__(self, request: requests.PreparedRequest) -> requests.PreparedRequest: - """Attach the HTTP headers required to authenticate on the HTTP request""" - self.headers = { - "Content-Type": "application/x-amz-json-1.1", - "Accept": "application/json", - "Host": f"cloudtrail.{self._aws_region_name}.amazonaws.com", - } - # StartTime and EndTime should be Unix timestamps with integer type - request_body_json = json.loads(request.body.decode("utf-8")) - if self.config.get("lookup_attributes_filter"): - lookup_attributes_filter = self.config.get("lookup_attributes_filter", {}) - attribute_key = lookup_attributes_filter.get("attribute_key", "") - attribute_value = lookup_attributes_filter.get("attribute_value", "") - - request_body_json["LookupAttributes"] = [{"AttributeKey": attribute_key, "AttributeValue": attribute_value}] - request_body_json["StartTime"] = int(float(request_body_json["StartTime"])) - request_body_json["EndTime"] = int(float(request_body_json["EndTime"])) - request.body = json.dumps(request_body_json).encode("utf-8") - # Sign the AWS Request and update headers with timestamp - authorization_header, amz_date = self.sign_aws_request( - self.service, - self._aws_region_name, - request.method, - self.path, - self.headers, - request_body_json, - self._aws_key_id, - self._aws_secret_key, - ) - self.headers["X-Amz-Date"] = amz_date - self.headers["Authorization"] = authorization_header - request.headers.update(self.headers) - return request - - @property - def auth_header(self) -> str: - return None - - @property - def token(self): - return None - - # AWS Cloudtrail Requires custom sign process with request, Referred from botocore client - https://github.com/boto/botocore/issues/786 - def sign_aws_request(self, service, region, method, path, headers, payload, aws_access_key, aws_secret_key): - # Define required parameters for signing - service = service - region = region - method = method - path = path - headers = headers - string_payload = json.dumps(payload) - payload_hash = hashlib.sha256(string_payload.encode()).hexdigest() - - # Generate timestamp and date for the request - amz_date = datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%SZ") - date_stamp = datetime.datetime.utcnow().strftime("%Y%m%d") - - # Generate canonical request - canonical_headers = "".join([f"{key.lower()}:{value.strip()}\n" for key, value in sorted(headers.items())]) - signed_headers = ";".join(sorted(key.lower() for key in headers)) - canonical_request = f"{method}\n{path}\n\n{canonical_headers}\n{signed_headers}\n{payload_hash}" - - # Generate string to sign - algorithm = "AWS4-HMAC-SHA256" - credential_scope = f"{date_stamp}/{region}/{service}/aws4_request" - string_to_sign = f"{algorithm}\n{amz_date}\n{credential_scope}\n" + hashlib.sha256(canonical_request.encode()).hexdigest() - - # Generate signing key - secret = ("AWS4" + aws_secret_key).encode() - k_date = hmac.new(secret, date_stamp.encode(), hashlib.sha256).digest() - k_region = hmac.new(k_date, region.encode(), hashlib.sha256).digest() - k_service = hmac.new(k_region, service.encode(), hashlib.sha256).digest() - k_signing = hmac.new(k_service, b"aws4_request", hashlib.sha256).digest() - - # Generate signature - signature = hmac.new(k_signing, string_to_sign.encode(), hashlib.sha256).hexdigest() - - # Generate authorization header - authorization_header = ( - f"{algorithm} Credential={aws_access_key}/{credential_scope}, " f"SignedHeaders={signed_headers}, Signature={signature}" - ) - return authorization_header, amz_date diff --git a/airbyte-integrations/connectors/source-aws-cloudtrail/source_aws_cloudtrail/manifest.yaml b/airbyte-integrations/connectors/source-aws-cloudtrail/source_aws_cloudtrail/manifest.yaml deleted file mode 100644 index 2ca8fa07d4c9..000000000000 --- a/airbyte-integrations/connectors/source-aws-cloudtrail/source_aws_cloudtrail/manifest.yaml +++ /dev/null @@ -1,218 +0,0 @@ -version: "0.71.0" - -definitions: - selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: ["{{ parameters.extractor_path }}"] - - requester: - type: HttpRequester - url_base: "https://cloudtrail.{{ config['aws_region_name'] }}.amazonaws.com" - http_method: "POST" - authenticator: - type: CustomAuthenticator - class_name: source_aws_cloudtrail.components.CustomAuthenticator - aws_key_id: "{{config['aws_key_id']}}" - aws_secret_key: "{{config['aws_secret_key']}}" - aws_region_name: "{{config['aws_region_name']}}" - error_handler: - type: CompositeErrorHandler - error_handlers: - - type: DefaultErrorHandler - backoff_strategies: - - type: ExponentialBackoffStrategy - response_filters: - - type: HttpResponseFilter - action: RETRY - http_codes: - - 400 - - incremental_sync_base: - type: DatetimeBasedCursor - datetime_format: "%s" - cursor_field: "EventTime" - start_time_option: - inject_into: body_json - field_name: StartTime - type: RequestOption - end_time_option: - inject_into: body_json - field_name: EndTime - type: RequestOption - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] or now_utc().strftime('%Y-%m-%d') }}" - datetime_format: "%Y-%m-%d" - end_datetime: - type: MinMaxDatetime - datetime: "{{ now_utc().strftime('%s') }}" - datetime_format: "%s" - - paginator_base: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: body_json - field_name: "NextToken" - pagination_strategy: - type: CursorPagination - cursor_value: '{{ response.get("NextToken", {}) }}' - stop_condition: '{{ not response.get("NextToken", {}) }}' - - management_events_stream: - type: DeclarativeStream - $parameters: - name: "management_events" - primary_key: "EventId" - path: "/" - extractor_path: "Events" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/definitions/management_events_schema" - retriever: - type: SimpleRetriever - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator_base" - requester: - $ref: "#/definitions/requester" - authenticator: - $ref: "#/definitions/requester/authenticator" - request_headers: - x-amz-target: "com.amazonaws.cloudtrail.v20131101.CloudTrail_20131101.LookupEvents" - request_body_json: - MaxResults: 50 - incremental_sync: - $ref: "#/definitions/incremental_sync_base" - - management_events_schema: - $schema: http://json-schema.org/draft-07/schema# - type: object - properties: - AccessKeyId: - type: - - "null" - - string - CloudTrailEvent: - type: - - "null" - - string - EventId: - type: - - "null" - - string - EventName: - type: - - "null" - - string - EventSource: - type: - - "null" - - string - EventTime: - type: - - "null" - - number - ReadOnly: - type: - - "null" - - string - Resources: - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - ResourceName: - type: - - "null" - - string - ResourceType: - type: - - "null" - - string - Username: - type: - - "null" - - string - -streams: - - "#/definitions/management_events_stream" #Ref: https://docs.aws.amazon.com/awscloudtrail/latest/APIReference/API_LookupEvents.html - -check: - type: CheckStream - stream_names: - - "management_events" - -spec: - type: Spec - documentation_url: https://docs.airbyte.com/integrations/sources/aws-cloudtrail - connection_specification: - $schema: http://json-schema.org/draft-07/schema# - title: Aws CloudTrail Spec - type: object - required: - - aws_key_id - - aws_secret_key - - aws_region_name - additionalProperties: true - properties: - aws_key_id: - type: string - title: Key ID - description: - AWS CloudTrail Access Key ID. See the docs - for more information on how to obtain this key. - airbyte_secret: true - aws_secret_key: - type: string - title: Secret Key - description: - AWS CloudTrail Access Key ID. See the docs - for more information on how to obtain this key. - airbyte_secret: true - aws_region_name: - type: string - title: Region Name - description: - The default AWS Region to use, for example, us-west-1 or us-west-2. - When specifying a Region inline during client initialization, this property - is named region_name. - default: "us-east-1" - start_date: - type: string - title: Start Date - description: - "The date you would like to replicate data. Data in AWS CloudTrail - is available for last 90 days only. Format: YYYY-MM-DD." - examples: - - "2021-01-01" - pattern: "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" - format: date - lookup_attributes_filter: - title: Filter applied while fetching records based on AttributeKey and AttributeValue which will be appended on the request body - type: object - required: - - attribute_key - - attribute_value - properties: - attribute_key: - type: string - title: Attribute Key from the response to filter - examples: - - "EventName" - default: "EventName" - attribute_value: - type: string - title: Corresponding value to the given attribute key - examples: - - "ListInstanceAssociations" - - "ConsoleLogin" - default: "ListInstanceAssociations" diff --git a/airbyte-integrations/connectors/source-aws-cloudtrail/source_aws_cloudtrail/run.py b/airbyte-integrations/connectors/source-aws-cloudtrail/source_aws_cloudtrail/run.py deleted file mode 100644 index 2a7629d84eab..000000000000 --- a/airbyte-integrations/connectors/source-aws-cloudtrail/source_aws_cloudtrail/run.py +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import sys - -from airbyte_cdk.entrypoint import launch - -from .source import SourceAwsCloudtrail - - -def run(): - source = SourceAwsCloudtrail() - launch(source, sys.argv[1:]) diff --git a/airbyte-integrations/connectors/source-aws-cloudtrail/source_aws_cloudtrail/source.py b/airbyte-integrations/connectors/source-aws-cloudtrail/source_aws_cloudtrail/source.py deleted file mode 100644 index bcbfb5dd0a3e..000000000000 --- a/airbyte-integrations/connectors/source-aws-cloudtrail/source_aws_cloudtrail/source.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource - -""" -This file provides the necessary constructs to interpret a provided declarative YAML configuration file into -source connector. - -WARNING: Do not modify this file. -""" - - -# Declarative Source -class SourceAwsCloudtrail(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-azure-blob-storage/build_customization.py b/airbyte-integrations/connectors/source-azure-blob-storage/build_customization.py index 6f490c8b1b11..bb54e8147922 100644 --- a/airbyte-integrations/connectors/source-azure-blob-storage/build_customization.py +++ b/airbyte-integrations/connectors/source-azure-blob-storage/build_customization.py @@ -5,6 +5,7 @@ from typing import TYPE_CHECKING + if TYPE_CHECKING: from dagger import Container diff --git a/airbyte-integrations/connectors/source-azure-blob-storage/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-azure-blob-storage/integration_tests/acceptance.py index 43ce950d77ca..72132012aaed 100644 --- a/airbyte-integrations/connectors/source-azure-blob-storage/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-azure-blob-storage/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-azure-blob-storage/integration_tests/conftest.py b/airbyte-integrations/connectors/source-azure-blob-storage/integration_tests/conftest.py index 62b485cc5303..2f6bd0adfe41 100644 --- a/airbyte-integrations/connectors/source-azure-blob-storage/integration_tests/conftest.py +++ b/airbyte-integrations/connectors/source-azure-blob-storage/integration_tests/conftest.py @@ -11,15 +11,17 @@ import azure import docker import pytest -from airbyte_protocol.models import ConfiguredAirbyteCatalog from azure.storage.blob import BlobServiceClient, ContainerClient from azure.storage.blob._shared.authentication import SharedKeyCredentialPolicy from fastavro import parse_schema, writer from pandas import read_csv from source_azure_blob_storage import SourceAzureBlobStorage +from airbyte_protocol.models import ConfiguredAirbyteCatalog + from .utils import get_docker_ip, load_config + logger = logging.getLogger("airbyte") JSON_TO_AVRO_TYPES = {"string": "string", "integer": "long", "number": "float", "object": "record"} diff --git a/airbyte-integrations/connectors/source-azure-blob-storage/integration_tests/integration_test.py b/airbyte-integrations/connectors/source-azure-blob-storage/integration_tests/integration_test.py index 29c9ffd1ef1a..7c4b5b24f679 100644 --- a/airbyte-integrations/connectors/source-azure-blob-storage/integration_tests/integration_test.py +++ b/airbyte-integrations/connectors/source-azure-blob-storage/integration_tests/integration_test.py @@ -4,10 +4,11 @@ from typing import Any, Mapping import pytest +from source_azure_blob_storage import SourceAzureBlobStorage, SourceAzureBlobStorageSpec, SourceAzureBlobStorageStreamReader + from airbyte_cdk.sources.file_based.stream.cursor import DefaultFileBasedCursor from airbyte_cdk.test.entrypoint_wrapper import read from airbyte_protocol.models import ConfiguredAirbyteCatalog -from source_azure_blob_storage import SourceAzureBlobStorage, SourceAzureBlobStorageSpec, SourceAzureBlobStorageStreamReader @pytest.mark.parametrize( diff --git a/airbyte-integrations/connectors/source-azure-blob-storage/integration_tests/spec.json b/airbyte-integrations/connectors/source-azure-blob-storage/integration_tests/spec.json index 6d18352e7754..cf2e9e44688b 100644 --- a/airbyte-integrations/connectors/source-azure-blob-storage/integration_tests/spec.json +++ b/airbyte-integrations/connectors/source-azure-blob-storage/integration_tests/spec.json @@ -35,9 +35,7 @@ "default": ["**"], "order": 1, "type": "array", - "items": { - "type": "string" - } + "items": { "type": "string" } }, "legacy_prefix": { "title": "Legacy Prefix", @@ -136,9 +134,7 @@ "description": "A set of case-sensitive strings that should be interpreted as null values. For example, if the value 'NA' should be interpreted as null, enter 'NA' in this field.", "default": [], "type": "array", - "items": { - "type": "string" - }, + "items": { "type": "string" }, "uniqueItems": true }, "strings_can_be_null": { @@ -162,9 +158,7 @@ "header_definition": { "title": "CSV Header Definition", "description": "How headers will be defined. `User Provided` assumes the CSV does not have a header row and uses the headers provided and `Autogenerated` assumes the CSV does not have a header row and the CDK will generate headers using for `f{i}` where `i` is the index starting from 0. Else, the default behavior is to use the header from the CSV file. If a user wants to autogenerate or provide column names for a CSV having headers, they can skip rows.", - "default": { - "header_definition_type": "From CSV" - }, + "default": { "header_definition_type": "From CSV" }, "oneOf": [ { "title": "From CSV", @@ -206,9 +200,7 @@ "title": "Column Names", "description": "The column names that will be used while emitting the CSV records", "type": "array", - "items": { - "type": "string" - } + "items": { "type": "string" } } }, "required": ["column_names", "header_definition_type"] @@ -221,9 +213,7 @@ "description": "A set of case-sensitive strings that should be interpreted as true values.", "default": ["y", "yes", "t", "true", "on", "1"], "type": "array", - "items": { - "type": "string" - }, + "items": { "type": "string" }, "uniqueItems": true }, "false_values": { @@ -231,9 +221,7 @@ "description": "A set of case-sensitive strings that should be interpreted as false values.", "default": ["n", "no", "f", "false", "off", "0"], "type": "array", - "items": { - "type": "string" - }, + "items": { "type": "string" }, "uniqueItems": true }, "inference_type": { @@ -313,9 +301,7 @@ "processing": { "title": "Processing", "description": "Processing configuration", - "default": { - "mode": "local" - }, + "default": { "mode": "local" }, "type": "object", "oneOf": [ { @@ -401,6 +387,43 @@ "auth_type" ] }, + { + "title": "Authenticate via Client Credentials", + "type": "object", + "properties": { + "auth_type": { + "title": "Auth Type", + "default": "client_credentials", + "const": "client_credentials", + "enum": ["client_credentials"], + "type": "string" + }, + "app_tenant_id": { + "title": "Tenant ID", + "description": "Tenant ID of the Microsoft Azure Application", + "airbyte_secret": true, + "type": "string" + }, + "app_client_id": { + "title": "Client ID", + "description": "Client ID of your Microsoft developer application", + "airbyte_secret": true, + "type": "string" + }, + "app_client_secret": { + "title": "Client Secret", + "description": "Client Secret of your Microsoft developer application", + "airbyte_secret": true, + "type": "string" + } + }, + "required": [ + "app_tenant_id", + "app_client_id", + "app_client_secret", + "auth_type" + ] + }, { "title": "Authenticate via Storage Account Key", "type": "object", @@ -485,12 +508,8 @@ "type": "object", "additionalProperties": false, "properties": { - "client_id": { - "type": "string" - }, - "client_secret": { - "type": "string" - } + "client_id": { "type": "string" }, + "client_secret": { "type": "string" } } }, "complete_oauth_server_output_specification": { diff --git a/airbyte-integrations/connectors/source-azure-blob-storage/main.py b/airbyte-integrations/connectors/source-azure-blob-storage/main.py index 5d60acbf692a..37897c63affe 100644 --- a/airbyte-integrations/connectors/source-azure-blob-storage/main.py +++ b/airbyte-integrations/connectors/source-azure-blob-storage/main.py @@ -5,5 +5,6 @@ from source_azure_blob_storage.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-azure-blob-storage/metadata.yaml b/airbyte-integrations/connectors/source-azure-blob-storage/metadata.yaml index 414b161dc19a..8ab59ad83768 100644 --- a/airbyte-integrations/connectors/source-azure-blob-storage/metadata.yaml +++ b/airbyte-integrations/connectors/source-azure-blob-storage/metadata.yaml @@ -12,7 +12,7 @@ data: connectorSubtype: file connectorType: source definitionId: fdaaba68-4875-4ed9-8fcd-4ae1e0a25093 - dockerImageTag: 0.4.4 + dockerImageTag: 0.5.0 dockerRepository: airbyte/source-azure-blob-storage documentationUrl: https://docs.airbyte.com/integrations/sources/azure-blob-storage githubIssueLabel: source-azure-blob-storage diff --git a/airbyte-integrations/connectors/source-azure-blob-storage/pyproject.toml b/airbyte-integrations/connectors/source-azure-blob-storage/pyproject.toml index 8fbfa597d162..5dfb28755435 100644 --- a/airbyte-integrations/connectors/source-azure-blob-storage/pyproject.toml +++ b/airbyte-integrations/connectors/source-azure-blob-storage/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.4.4" +version = "0.5.0" name = "source-azure-blob-storage" description = "Source implementation for Azure Blob Storage." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-azure-blob-storage/source_azure_blob_storage/config_migrations.py b/airbyte-integrations/connectors/source-azure-blob-storage/source_azure_blob_storage/config_migrations.py index d66169a9d7ae..dd9430d7ee75 100644 --- a/airbyte-integrations/connectors/source-azure-blob-storage/source_azure_blob_storage/config_migrations.py +++ b/airbyte-integrations/connectors/source-azure-blob-storage/source_azure_blob_storage/config_migrations.py @@ -9,19 +9,18 @@ from airbyte_cdk import AirbyteEntrypoint, Source, create_connector_config_control_message + logger = logging.getLogger("airbyte_logger") class MigrateConfig(ABC): @classmethod @abstractmethod - def should_migrate(cls, config: Mapping[str, Any]) -> bool: - ... + def should_migrate(cls, config: Mapping[str, Any]) -> bool: ... @classmethod @abstractmethod - def migrate_config(cls, config: Mapping[str, Any]) -> Mapping[str, Any]: - ... + def migrate_config(cls, config: Mapping[str, Any]) -> Mapping[str, Any]: ... @classmethod def modify_and_save(cls, config_path: str, source: Source, config: Mapping[str, Any]) -> Mapping[str, Any]: diff --git a/airbyte-integrations/connectors/source-azure-blob-storage/source_azure_blob_storage/spec.py b/airbyte-integrations/connectors/source-azure-blob-storage/source_azure_blob_storage/spec.py index ed331a9c4a2b..c92a71d73175 100644 --- a/airbyte-integrations/connectors/source-azure-blob-storage/source_azure_blob_storage/spec.py +++ b/airbyte-integrations/connectors/source-azure-blob-storage/source_azure_blob_storage/spec.py @@ -6,9 +6,10 @@ from typing import Any, Dict, Literal, Optional, Union import dpath.util +from pydantic import AnyUrl, BaseModel, Field + from airbyte_cdk import OneOfOptionConfig from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec -from pydantic import AnyUrl, BaseModel, Field class Oauth2(BaseModel): @@ -35,6 +36,25 @@ class Config(OneOfOptionConfig): ) +class ClientCredentials(BaseModel): + class Config(OneOfOptionConfig): + title = "Authenticate via Client Credentials" + discriminator = "auth_type" + + auth_type: Literal["client_credentials"] = Field("client_credentials", const=True) + app_tenant_id: str = Field(title="Tenant ID", description="Tenant ID of the Microsoft Azure Application", airbyte_secret=True) + app_client_id: str = Field( + title="Client ID", + description="Client ID of your Microsoft developer application", + airbyte_secret=True, + ) + app_client_secret: str = Field( + title="Client Secret", + description="Client Secret of your Microsoft developer application", + airbyte_secret=True, + ) + + class StorageAccountKey(BaseModel): class Config(OneOfOptionConfig): title = "Authenticate via Storage Account Key" @@ -60,7 +80,7 @@ class SourceAzureBlobStorageSpec(AbstractFileBasedSpec): def documentation_url(cls) -> AnyUrl: return AnyUrl("https://docs.airbyte.com/integrations/sources/azure-blob-storage", scheme="https") - credentials: Union[Oauth2, StorageAccountKey] = Field( + credentials: Union[Oauth2, ClientCredentials, StorageAccountKey] = Field( title="Authentication", description="Credentials for connecting to the Azure Blob Storage", discriminator="auth_type", diff --git a/airbyte-integrations/connectors/source-azure-blob-storage/source_azure_blob_storage/stream_reader.py b/airbyte-integrations/connectors/source-azure-blob-storage/source_azure_blob_storage/stream_reader.py index a394b0adf581..be5febe283f0 100644 --- a/airbyte-integrations/connectors/source-azure-blob-storage/source_azure_blob_storage/stream_reader.py +++ b/airbyte-integrations/connectors/source-azure-blob-storage/source_azure_blob_storage/stream_reader.py @@ -3,22 +3,62 @@ import logging from io import IOBase -from typing import Iterable, List, Optional, Union +from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Union import pytz +from azure.core.credentials import AccessToken, TokenCredential +from azure.core.exceptions import ResourceNotFoundError +from azure.storage.blob import BlobServiceClient, ContainerClient +from smart_open import open + from airbyte_cdk import AirbyteTracedException, FailureType from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode from airbyte_cdk.sources.file_based.remote_file import RemoteFile from airbyte_cdk.sources.streams.http.requests_native_auth import Oauth2Authenticator -from azure.core.credentials import AccessToken -from azure.core.exceptions import ResourceNotFoundError -from azure.storage.blob import BlobServiceClient, ContainerClient -from smart_open import open from .spec import SourceAzureBlobStorageSpec -class AzureOauth2Authenticator(Oauth2Authenticator): +class AzureClientCredentialsAuthenticator(Oauth2Authenticator, TokenCredential): + def __init__(self, tenant_id: str, client_id: str, client_secret: str, **kwargs): + super().__init__( + token_refresh_endpoint=f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token", + client_id=client_id, + client_secret=client_secret, + grant_type="client_credentials", + scopes=["https://storage.azure.com/.default"], + refresh_token=None, + ) + + def build_refresh_request_body(self) -> Mapping[str, Any]: + """ + Returns the request body to set on the refresh request + + Override to define additional parameters + """ + payload: MutableMapping[str, Any] = { + "grant_type": self.get_grant_type(), + "client_id": self.get_client_id(), + "client_secret": self.get_client_secret(), + } + + if self.get_scopes(): + payload["scope"] = " ".join(self.get_scopes()) + + if self.get_refresh_request_body(): + for key, val in self.get_refresh_request_body().items(): + # We defer to existing oauth constructs over custom configured fields + if key not in payload: + payload[key] = val + + return payload + + def get_token(self, *args, **kwargs) -> AccessToken: + """Parent class handles Oauth Refresh token logic.""" + return AccessToken(token=self.get_access_token(), expires_on=int(self.get_token_expiry_date().timestamp())) + + +class AzureOauth2Authenticator(Oauth2Authenticator, TokenCredential): """ Authenticator for Azure Blob Storage SDK to align with azure.core.credentials.TokenCredential protocol """ @@ -62,17 +102,24 @@ def azure_blob_service_client(self): return BlobServiceClient(self.account_url, credential=self._credentials) @property - def azure_credentials(self) -> Union[str, AzureOauth2Authenticator]: + def azure_credentials(self) -> Union[str, AzureOauth2Authenticator, AzureClientCredentialsAuthenticator]: if not self._credentials: if self.config.credentials.auth_type == "storage_account_key": self._credentials = self.config.credentials.azure_blob_storage_account_key - else: + elif self.config.credentials.auth_type == "oauth2": self._credentials = AzureOauth2Authenticator( token_refresh_endpoint=f"https://login.microsoftonline.com/{self.config.credentials.tenant_id}/oauth2/v2.0/token", client_id=self.config.credentials.client_id, client_secret=self.config.credentials.client_secret, refresh_token=self.config.credentials.refresh_token, ) + elif self.config.credentials.auth_type == "client_credentials": + self._credentials = AzureClientCredentialsAuthenticator( + tenant_id=self.config.credentials.app_tenant_id, + client_id=self.config.credentials.app_client_id, + client_secret=self.config.credentials.app_client_secret, + ) + return self._credentials def get_matching_files( diff --git a/airbyte-integrations/connectors/source-azure-blob-storage/unit_tests/test_authenticator.py b/airbyte-integrations/connectors/source-azure-blob-storage/unit_tests/test_authenticator.py index dbe30bfeb7fe..0fa869fd1739 100644 --- a/airbyte-integrations/connectors/source-azure-blob-storage/unit_tests/test_authenticator.py +++ b/airbyte-integrations/connectors/source-azure-blob-storage/unit_tests/test_authenticator.py @@ -2,26 +2,45 @@ from azure.core.credentials import AccessToken -from source_azure_blob_storage.stream_reader import AzureOauth2Authenticator +from source_azure_blob_storage.stream_reader import AzureClientCredentialsAuthenticator, AzureOauth2Authenticator def test_custom_authenticator(requests_mock): - authenticator = AzureOauth2Authenticator( - token_refresh_endpoint="https://login.microsoftonline.com/tenant_id/oauth2/v2.0/token", - client_id="client_id", - client_secret="client_secret", - refresh_token="refresh_token", - ) + token_refresh_endpoint="https://login.microsoftonline.com/tenant_id/oauth2/v2.0/token", + client_id="client_id", + client_secret="client_secret", + refresh_token="refresh_token", + ) token_refresh_response = { "token_type": "Bearer", "scope": "https://storage.azure.com/user_impersonation https://storage.azure.com/.default", "expires_in": 5144, "ext_expires_in": 5144, "access_token": "access_token", - "refresh_token": "refresh_token" + "refresh_token": "refresh_token", } requests_mock.post("https://login.microsoftonline.com/tenant_id/oauth2/v2.0/token", json=token_refresh_response) new_token = authenticator.get_token() assert isinstance(new_token, AccessToken) assert new_token.token == "access_token" + + +def test_client_authenticator(requests_mock): + authenticator = AzureClientCredentialsAuthenticator( + token_refresh_endpoint="https://login.microsoftonline.com/tenant_id/oauth2/v2.0/token", + tenant_id="tenant_id", + client_id="client_id", + client_secret="client_secret", + ) + token_response = { + "token_type": "Bearer", + "scope": "https://storage.azure.com/.default", + "expires_in": 3600, + "ext_expires_in": 3600, + "access_token": "access_token_123", + } + requests_mock.post("https://login.microsoftonline.com/tenant_id/oauth2/v2.0/token", json=token_response) + new_token = authenticator.get_token() + assert isinstance(new_token, AccessToken) + assert new_token.token == "access_token_123" diff --git a/airbyte-integrations/connectors/source-azure-blob-storage/unit_tests/test_config_migration.py b/airbyte-integrations/connectors/source-azure-blob-storage/unit_tests/test_config_migration.py index b41630da48bd..b71ee1372fef 100644 --- a/airbyte-integrations/connectors/source-azure-blob-storage/unit_tests/test_config_migration.py +++ b/airbyte-integrations/connectors/source-azure-blob-storage/unit_tests/test_config_migration.py @@ -3,12 +3,26 @@ import json import os +from pathlib import Path +from shutil import copytree +from tempfile import TemporaryDirectory from typing import Any, Mapping -from airbyte_cdk.sources.file_based.stream.cursor import DefaultFileBasedCursor +from pytest import fixture from source_azure_blob_storage import SourceAzureBlobStorage, SourceAzureBlobStorageSpec, SourceAzureBlobStorageStreamReader from source_azure_blob_storage.config_migrations import MigrateCredentials, MigrateLegacyConfig +from airbyte_cdk.sources.file_based.stream.cursor import DefaultFileBasedCursor + + +@fixture +def temp_configs(): + config_path = f"{os.path.dirname(__file__)}/test_configs/" + with TemporaryDirectory() as _tempdir: + configs_dir = Path(_tempdir) / "test_configs" + copytree(config_path, configs_dir) + yield configs_dir + # HELPERS def load_config(config_path: str) -> Mapping[str, Any]: @@ -16,8 +30,8 @@ def load_config(config_path: str) -> Mapping[str, Any]: return json.load(config) -def test_legacy_config_migration(): - config_path = f"{os.path.dirname(__file__)}/test_configs/test_legacy_config.json" +def test_legacy_config_migration(temp_configs): + config_path = str((Path(temp_configs) / "test_legacy_config.json").resolve()) migration_instance = MigrateLegacyConfig source = SourceAzureBlobStorage( SourceAzureBlobStorageStreamReader(), @@ -46,9 +60,11 @@ def test_legacy_config_migration(): assert test_migrated_config == expected_config -def test_credentials_config_migration(): - config_path = f"{os.path.dirname(__file__)}/test_configs/test_config_without_credentials.json" +def test_credentials_config_migration(temp_configs): + config_path = str((Path(temp_configs) / "test_config_without_credentials.json").resolve()) initial_config = load_config(config_path) + expected = initial_config["azure_blob_storage_account_key"] + migration_instance = MigrateCredentials source = SourceAzureBlobStorage( SourceAzureBlobStorageStreamReader(), @@ -60,4 +76,4 @@ def test_credentials_config_migration(): ) migration_instance.migrate(["check", "--config", config_path], source) test_migrated_config = load_config(config_path) - assert test_migrated_config["credentials"]["azure_blob_storage_account_key"] == initial_config["azure_blob_storage_account_key"] + assert test_migrated_config["credentials"]["azure_blob_storage_account_key"] == expected diff --git a/airbyte-integrations/connectors/source-azure-blob-storage/unit_tests/test_stream_reader.py b/airbyte-integrations/connectors/source-azure-blob-storage/unit_tests/test_stream_reader.py index 3cec8f051aa2..26f3296a6f53 100644 --- a/airbyte-integrations/connectors/source-azure-blob-storage/unit_tests/test_stream_reader.py +++ b/airbyte-integrations/connectors/source-azure-blob-storage/unit_tests/test_stream_reader.py @@ -12,24 +12,26 @@ from source_azure_blob_storage.spec import SourceAzureBlobStorageSpec from source_azure_blob_storage.stream_reader import AzureOauth2Authenticator, SourceAzureBlobStorageStreamReader + logger = logging.Logger("") @pytest.mark.parametrize( "credentials, expected_credentials_type", [ - ({"auth_type": "oauth2", - "tenant_id": "tenant_id", - "client_id": "client_id", - "client_secret": "client_secret", - "refresh_token": "refresh_token" - }, AzureOauth2Authenticator), - ({ - "auth_type": "storage_account_key", - "azure_blob_storage_account_key": "key1" - }, str), + ( + { + "auth_type": "oauth2", + "tenant_id": "tenant_id", + "client_id": "client_id", + "client_secret": "client_secret", + "refresh_token": "refresh_token", + }, + AzureOauth2Authenticator, + ), + ({"auth_type": "storage_account_key", "azure_blob_storage_account_key": "key1"}, str), ], - ids=["oauth2", "storage_account_key"] + ids=["oauth2", "storage_account_key"], ) def test_stream_reader_credentials(credentials: Dict, expected_credentials_type: Union[str, AzureOauth2Authenticator]): reader = SourceAzureBlobStorageStreamReader() @@ -59,9 +61,9 @@ def test_stream_reader_files_read_and_filter_by_date(): reader.config = config with patch.object(ContainerClient, "list_blobs") as blobs: blobs.return_value = [ - BlobProperties(name='sample_file_1.csv', **{"Last-Modified": datetime.datetime(2023, 1, 1, 1, 1, 0)}), - BlobProperties(name='sample_file_2.csv', **{"Last-Modified": datetime.datetime(2024, 1, 1, 1, 1, 0)}), - BlobProperties(name='sample_file_3.csv', **{"Last-Modified": datetime.datetime(2024, 1, 5, 1, 1, 0)}) + BlobProperties(name="sample_file_1.csv", **{"Last-Modified": datetime.datetime(2023, 1, 1, 1, 1, 0)}), + BlobProperties(name="sample_file_2.csv", **{"Last-Modified": datetime.datetime(2024, 1, 1, 1, 1, 0)}), + BlobProperties(name="sample_file_3.csv", **{"Last-Modified": datetime.datetime(2024, 1, 5, 1, 1, 0)}), ] files = list(reader.get_matching_files(globs=["**"], prefix=None, logger=logger)) assert len(files) == 2 diff --git a/airbyte-integrations/connectors/source-azure-table/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-azure-table/integration_tests/acceptance.py index 43ce950d77ca..72132012aaed 100644 --- a/airbyte-integrations/connectors/source-azure-table/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-azure-table/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-azure-table/main.py b/airbyte-integrations/connectors/source-azure-table/main.py index 0831f8065766..0ccc48e59be2 100644 --- a/airbyte-integrations/connectors/source-azure-table/main.py +++ b/airbyte-integrations/connectors/source-azure-table/main.py @@ -4,5 +4,6 @@ from source_azure_table.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-azure-table/metadata.yaml b/airbyte-integrations/connectors/source-azure-table/metadata.yaml index e22a92d2c33e..3ce332627c6d 100644 --- a/airbyte-integrations/connectors/source-azure-table/metadata.yaml +++ b/airbyte-integrations/connectors/source-azure-table/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: database connectorType: source definitionId: 798ae795-5189-42b6-b64e-3cb91db93338 - dockerImageTag: 0.1.28 + dockerImageTag: 0.1.32 dockerRepository: airbyte/source-azure-table githubIssueLabel: source-azure-table icon: azureblobstorage.svg @@ -40,5 +40,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-azure-table/poetry.lock b/airbyte-integrations/connectors/source-azure-table/poetry.lock index d76bc685fbd1..b36b3f075a28 100644 --- a/airbyte-integrations/connectors/source-azure-table/poetry.lock +++ b/airbyte-integrations/connectors/source-azure-table/poetry.lock @@ -62,32 +62,32 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "azure-core" -version = "1.31.0" +version = "1.32.0" description = "Microsoft Azure Core Library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "azure_core-1.31.0-py3-none-any.whl", hash = "sha256:22954de3777e0250029360ef31d80448ef1be13b80a459bff80ba7073379e2cd"}, - {file = "azure_core-1.31.0.tar.gz", hash = "sha256:656a0dd61e1869b1506b7c6a3b31d62f15984b1a573d6326f6aa2f3e4123284b"}, + {file = "azure_core-1.32.0-py3-none-any.whl", hash = "sha256:eac191a0efb23bfa83fddf321b27b122b4ec847befa3091fa736a5c32c50d7b4"}, + {file = "azure_core-1.32.0.tar.gz", hash = "sha256:22b3c35d6b2dae14990f6c1be2912bf23ffe50b220e708a28ab1bb92b1c730e5"}, ] [package.dependencies] @@ -100,20 +100,20 @@ aio = ["aiohttp (>=3.0)"] [[package]] name = "azure-data-tables" -version = "12.5.0" +version = "12.6.0" description = "Microsoft Azure Azure Data Tables Client Library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "azure-data-tables-12.5.0.tar.gz", hash = "sha256:eea393a6380c42eb03e807825c037832003d09c823294831da15e81155a0b4e6"}, - {file = "azure_data_tables-12.5.0-py3-none-any.whl", hash = "sha256:fa45330f45c0d7a45db353c196cb4265bdf03fb1de9e1e726c30b8dd5ea55e5d"}, + {file = "azure_data_tables-12.6.0-py3-none-any.whl", hash = "sha256:9869620765142d7caec7a6adca733f617ddcd006a810876f0cf95eea4f5b9692"}, + {file = "azure_data_tables-12.6.0.tar.gz", hash = "sha256:e0d5598113855f9114fd7671623d35509f83772970cfdc597901b35f42dc3134"}, ] [package.dependencies] -azure-core = ">=1.29.4,<2.0.0" -isodate = ">=0.6.1,<1.0.0" +azure-core = ">=1.29.4" +isodate = ">=0.6.1" typing-extensions = ">=4.3.0" -yarl = ">=1.0,<2.0" +yarl = ">=1.0" [[package]] name = "backoff" @@ -176,127 +176,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -312,20 +299,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -403,13 +390,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -626,13 +613,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""} [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -702,109 +689,93 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "propcache" -version = "0.2.0" +version = "0.2.1" description = "Accelerated property cache" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"}, - {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"}, - {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"}, - {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"}, - {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, - {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, - {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544"}, - {file = "propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032"}, - {file = "propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed"}, - {file = "propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d"}, - {file = "propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798"}, - {file = "propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9"}, - {file = "propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df"}, - {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, - {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6445804cf4ec763dc70de65a3b0d9954e868609e83850a47ca4f0cb64bd79fea"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9479aa06a793c5aeba49ce5c5692ffb51fcd9a7016e017d555d5e2b0045d212"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9631c5e8b5b3a0fda99cb0d29c18133bca1e18aea9effe55adb3da1adef80d3"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3156628250f46a0895f1f36e1d4fbe062a1af8718ec3ebeb746f1d23f0c5dc4d"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b6fb63ae352e13748289f04f37868099e69dba4c2b3e271c46061e82c745634"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:887d9b0a65404929641a9fabb6452b07fe4572b269d901d622d8a34a4e9043b2"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a96dc1fa45bd8c407a0af03b2d5218392729e1822b0c32e62c5bf7eeb5fb3958"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a7e65eb5c003a303b94aa2c3852ef130230ec79e349632d030e9571b87c4698c"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:999779addc413181912e984b942fbcc951be1f5b3663cd80b2687758f434c583"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:19a0f89a7bb9d8048d9c4370c9c543c396e894c76be5525f5e1ad287f1750ddf"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1ac2f5fe02fa75f56e1ad473f1175e11f475606ec9bd0be2e78e4734ad575034"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:574faa3b79e8ebac7cb1d7930f51184ba1ccf69adfdec53a12f319a06030a68b"}, + {file = "propcache-0.2.1-cp310-cp310-win32.whl", hash = "sha256:03ff9d3f665769b2a85e6157ac8b439644f2d7fd17615a82fa55739bc97863f4"}, + {file = "propcache-0.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:2d3af2e79991102678f53e0dbf4c35de99b6b8b58f29a27ca0325816364caaba"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e"}, + {file = "propcache-0.2.1-cp311-cp311-win32.whl", hash = "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034"}, + {file = "propcache-0.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518"}, + {file = "propcache-0.2.1-cp312-cp312-win32.whl", hash = "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246"}, + {file = "propcache-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30"}, + {file = "propcache-0.2.1-cp313-cp313-win32.whl", hash = "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6"}, + {file = "propcache-0.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6a9a8c34fb7bb609419a211e59da8887eeca40d300b5ea8e56af98f6fbbb1541"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae1aa1cd222c6d205853b3013c69cd04515f9d6ab6de4b0603e2e1c33221303e"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:accb6150ce61c9c4b7738d45550806aa2b71c7668c6942f17b0ac182b6142fd4"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5eee736daafa7af6d0a2dc15cc75e05c64f37fc37bafef2e00d77c14171c2097"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7a31fc1e1bd362874863fdeed71aed92d348f5336fd84f2197ba40c59f061bd"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba4cfa1052819d16699e1d55d18c92b6e094d4517c41dd231a8b9f87b6fa681"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f089118d584e859c62b3da0892b88a83d611c2033ac410e929cb6754eec0ed16"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:781e65134efaf88feb447e8c97a51772aa75e48b794352f94cb7ea717dedda0d"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31f5af773530fd3c658b32b6bdc2d0838543de70eb9a2156c03e410f7b0d3aae"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:a7a078f5d37bee6690959c813977da5291b24286e7b962e62a94cec31aa5188b"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:cea7daf9fc7ae6687cf1e2c049752f19f146fdc37c2cc376e7d0032cf4f25347"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:8b3489ff1ed1e8315674d0775dc7d2195fb13ca17b3808721b54dbe9fd020faf"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9403db39be1393618dd80c746cb22ccda168efce239c73af13c3763ef56ffc04"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5d97151bc92d2b2578ff7ce779cdb9174337390a535953cbb9452fb65164c587"}, + {file = "propcache-0.2.1-cp39-cp39-win32.whl", hash = "sha256:9caac6b54914bdf41bcc91e7eb9147d331d29235a7c967c150ef5df6464fd1bb"}, + {file = "propcache-0.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:92fc4500fcb33899b05ba73276dfb684a20d31caa567b7cb5252d48f896a91b1"}, + {file = "propcache-0.2.1-py3-none-any.whl", hash = "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54"}, + {file = "propcache-0.2.1.tar.gz", hash = "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64"}, ] [[package]] @@ -820,54 +791,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -1131,33 +1102,33 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1198,13 +1169,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1229,172 +1200,167 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [[package]] name = "yarl" -version = "1.17.0" +version = "1.18.3" description = "Yet another URL library" optional = false python-versions = ">=3.9" files = [ - {file = "yarl-1.17.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2d8715edfe12eee6f27f32a3655f38d6c7410deb482158c0b7d4b7fad5d07628"}, - {file = "yarl-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1803bf2a7a782e02db746d8bd18f2384801bc1d108723840b25e065b116ad726"}, - {file = "yarl-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e66589110e20c2951221a938fa200c7aa134a8bdf4e4dc97e6b21539ff026d4"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7069d411cfccf868e812497e0ec4acb7c7bf8d684e93caa6c872f1e6f5d1664d"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cbf70ba16118db3e4b0da69dcde9d4d4095d383c32a15530564c283fa38a7c52"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0bc53cc349675b32ead83339a8de79eaf13b88f2669c09d4962322bb0f064cbc"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6aa18a402d1c80193ce97c8729871f17fd3e822037fbd7d9b719864018df746"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d89c5bc701861cfab357aa0cd039bc905fe919997b8c312b4b0c358619c38d4d"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b728bdf38ca58f2da1d583e4af4ba7d4cd1a58b31a363a3137a8159395e7ecc7"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:5542e57dc15d5473da5a39fbde14684b0cc4301412ee53cbab677925e8497c11"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e564b57e5009fb150cb513804d7e9e9912fee2e48835638f4f47977f88b4a39c"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:eb3c4cff524b4c1c1dba3a6da905edb1dfd2baf6f55f18a58914bbb2d26b59e1"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:05e13f389038842da930d439fbed63bdce3f7644902714cb68cf527c971af804"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:153c38ee2b4abba136385af4467459c62d50f2a3f4bde38c7b99d43a20c143ef"}, - {file = "yarl-1.17.0-cp310-cp310-win32.whl", hash = "sha256:4065b4259d1ae6f70fd9708ffd61e1c9c27516f5b4fae273c41028afcbe3a094"}, - {file = "yarl-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:abf366391a02a8335c5c26163b5fe6f514cc1d79e74d8bf3ffab13572282368e"}, - {file = "yarl-1.17.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:19a4fe0279626c6295c5b0c8c2bb7228319d2e985883621a6e87b344062d8135"}, - {file = "yarl-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cadd0113f4db3c6b56868d6a19ca6286f5ccfa7bc08c27982cf92e5ed31b489a"}, - {file = "yarl-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:60d6693eef43215b1ccfb1df3f6eae8db30a9ff1e7989fb6b2a6f0b468930ee8"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb8bf3843e1fa8cf3fe77813c512818e57368afab7ebe9ef02446fe1a10b492"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d2a5b35fd1d8d90443e061d0c8669ac7600eec5c14c4a51f619e9e105b136715"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5bf17b32f392df20ab5c3a69d37b26d10efaa018b4f4e5643c7520d8eee7ac7"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48f51b529b958cd06e78158ff297a8bf57b4021243c179ee03695b5dbf9cb6e1"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fcaa06bf788e19f913d315d9c99a69e196a40277dc2c23741a1d08c93f4d430"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:32f3ee19ff0f18a7a522d44e869e1ebc8218ad3ae4ebb7020445f59b4bbe5897"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:a4fb69a81ae2ec2b609574ae35420cf5647d227e4d0475c16aa861dd24e840b0"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7bacc8b77670322132a1b2522c50a1f62991e2f95591977455fd9a398b4e678d"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:437bf6eb47a2d20baaf7f6739895cb049e56896a5ffdea61a4b25da781966e8b"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:30534a03c87484092080e3b6e789140bd277e40f453358900ad1f0f2e61fc8ec"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b30df4ff98703649915144be6f0df3b16fd4870ac38a09c56d5d9e54ff2d5f96"}, - {file = "yarl-1.17.0-cp311-cp311-win32.whl", hash = "sha256:263b487246858e874ab53e148e2a9a0de8465341b607678106829a81d81418c6"}, - {file = "yarl-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:07055a9e8b647a362e7d4810fe99d8f98421575e7d2eede32e008c89a65a17bd"}, - {file = "yarl-1.17.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:84095ab25ba69a8fa3fb4936e14df631b8a71193fe18bd38be7ecbe34d0f5512"}, - {file = "yarl-1.17.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:02608fb3f6df87039212fc746017455ccc2a5fc96555ee247c45d1e9f21f1d7b"}, - {file = "yarl-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13468d291fe8c12162b7cf2cdb406fe85881c53c9e03053ecb8c5d3523822cd9"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8da3f8f368fb7e2f052fded06d5672260c50b5472c956a5f1bd7bf474ae504ab"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ec0507ab6523980bed050137007c76883d941b519aca0e26d4c1ec1f297dd646"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08fc76df7fd8360e9ff30e6ccc3ee85b8dbd6ed5d3a295e6ec62bcae7601b932"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d522f390686acb6bab2b917dd9ca06740c5080cd2eaa5aef8827b97e967319d"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:147c527a80bb45b3dcd6e63401af8ac574125d8d120e6afe9901049286ff64ef"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:24cf43bcd17a0a1f72284e47774f9c60e0bf0d2484d5851f4ddf24ded49f33c6"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:c28a44b9e0fba49c3857360e7ad1473fc18bc7f6659ca08ed4f4f2b9a52c75fa"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:350cacb2d589bc07d230eb995d88fcc646caad50a71ed2d86df533a465a4e6e1"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:fd1ab1373274dea1c6448aee420d7b38af163b5c4732057cd7ee9f5454efc8b1"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4934e0f96dadc567edc76d9c08181633c89c908ab5a3b8f698560124167d9488"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8d0a278170d75c88e435a1ce76557af6758bfebc338435b2eba959df2552163e"}, - {file = "yarl-1.17.0-cp312-cp312-win32.whl", hash = "sha256:61584f33196575a08785bb56db6b453682c88f009cd9c6f338a10f6737ce419f"}, - {file = "yarl-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:9987a439ad33a7712bd5bbd073f09ad10d38640425fa498ecc99d8aa064f8fc4"}, - {file = "yarl-1.17.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8deda7b8eb15a52db94c2014acdc7bdd14cb59ec4b82ac65d2ad16dc234a109e"}, - {file = "yarl-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56294218b348dcbd3d7fce0ffd79dd0b6c356cb2a813a1181af730b7c40de9e7"}, - {file = "yarl-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1fab91292f51c884b290ebec0b309a64a5318860ccda0c4940e740425a67b6b7"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cf93fa61ff4d9c7d40482ce1a2c9916ca435e34a1b8451e17f295781ccc034f"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:261be774a0d71908c8830c33bacc89eef15c198433a8cc73767c10eeeb35a7d0"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deec9693b67f6af856a733b8a3e465553ef09e5e8ead792f52c25b699b8f9e6e"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c804b07622ba50a765ca7fb8145512836ab65956de01307541def869e4a456c9"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d013a7c9574e98c14831a8f22d27277688ec3b2741d0188ac01a910b009987a"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e2cfcba719bd494c7413dcf0caafb51772dec168c7c946e094f710d6aa70494e"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:c068aba9fc5b94dfae8ea1cedcbf3041cd4c64644021362ffb750f79837e881f"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3616df510ffac0df3c9fa851a40b76087c6c89cbcea2de33a835fc80f9faac24"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:755d6176b442fba9928a4df787591a6a3d62d4969f05c406cad83d296c5d4e05"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c18f6e708d1cf9ff5b1af026e697ac73bea9cb70ee26a2b045b112548579bed2"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5b937c216b6dee8b858c6afea958de03c5ff28406257d22b55c24962a2baf6fd"}, - {file = "yarl-1.17.0-cp313-cp313-win32.whl", hash = "sha256:d0131b14cb545c1a7bd98f4565a3e9bdf25a1bd65c83fc156ee5d8a8499ec4a3"}, - {file = "yarl-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:01c96efa4313c01329e88b7e9e9e1b2fc671580270ddefdd41129fa8d0db7696"}, - {file = "yarl-1.17.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0d44f67e193f0a7acdf552ecb4d1956a3a276c68e7952471add9f93093d1c30d"}, - {file = "yarl-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:16ea0aa5f890cdcb7ae700dffa0397ed6c280840f637cd07bffcbe4b8d68b985"}, - {file = "yarl-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cf5469dc7dcfa65edf5cc3a6add9f84c5529c6b556729b098e81a09a92e60e51"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e662bf2f6e90b73cf2095f844e2bc1fda39826472a2aa1959258c3f2a8500a2f"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8260e88f1446904ba20b558fa8ce5d0ab9102747238e82343e46d056d7304d7e"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dc16477a4a2c71e64c5d3d15d7ae3d3a6bb1e8b955288a9f73c60d2a391282f"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46027e326cecd55e5950184ec9d86c803f4f6fe4ba6af9944a0e537d643cdbe0"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc95e46c92a2b6f22e70afe07e34dbc03a4acd07d820204a6938798b16f4014f"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:16ca76c7ac9515320cd09d6cc083d8d13d1803f6ebe212b06ea2505fd66ecff8"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:eb1a5b97388f2613f9305d78a3473cdf8d80c7034e554d8199d96dcf80c62ac4"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:41fd5498975418cdc34944060b8fbeec0d48b2741068077222564bea68daf5a6"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:146ca582ed04a5664ad04b0e0603934281eaab5c0115a5a46cce0b3c061a56a1"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:6abb8c06107dbec97481b2392dafc41aac091a5d162edf6ed7d624fe7da0587a"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4d14be4613dd4f96c25feb4bd8c0d8ce0f529ab0ae555a17df5789e69d8ec0c5"}, - {file = "yarl-1.17.0-cp39-cp39-win32.whl", hash = "sha256:174d6a6cad1068f7850702aad0c7b1bca03bcac199ca6026f84531335dfc2646"}, - {file = "yarl-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:6af417ca2c7349b101d3fd557ad96b4cd439fdb6ab0d288e3f64a068eea394d0"}, - {file = "yarl-1.17.0-py3-none-any.whl", hash = "sha256:62dd42bb0e49423f4dd58836a04fcf09c80237836796025211bbe913f1524993"}, - {file = "yarl-1.17.0.tar.gz", hash = "sha256:d3f13583f378930377e02002b4085a3d025b00402d5a80911726d43a67911cd9"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:602d98f2c2d929f8e697ed274fbadc09902c4025c5a9963bf4e9edfc3ab6f7ed"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c654d5207c78e0bd6d749f6dae1dcbbfde3403ad3a4b11f3c5544d9906969dde"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5094d9206c64181d0f6e76ebd8fb2f8fe274950a63890ee9e0ebfd58bf9d787b"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35098b24e0327fc4ebdc8ffe336cee0a87a700c24ffed13161af80124b7dc8e5"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3236da9272872443f81fedc389bace88408f64f89f75d1bdb2256069a8730ccc"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c08cc9b16f4f4bc522771d96734c7901e7ebef70c6c5c35dd0f10845270bcd"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80316a8bd5109320d38eef8833ccf5f89608c9107d02d2a7f985f98ed6876990"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1e1cc06da1491e6734f0ea1e6294ce00792193c463350626571c287c9a704db"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fea09ca13323376a2fdfb353a5fa2e59f90cd18d7ca4eaa1fd31f0a8b4f91e62"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e3b9fd71836999aad54084906f8663dffcd2a7fb5cdafd6c37713b2e72be1760"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:757e81cae69244257d125ff31663249b3013b5dc0a8520d73694aed497fb195b"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b1771de9944d875f1b98a745bc547e684b863abf8f8287da8466cf470ef52690"}, + {file = "yarl-1.18.3-cp310-cp310-win32.whl", hash = "sha256:8874027a53e3aea659a6d62751800cf6e63314c160fd607489ba5c2edd753cf6"}, + {file = "yarl-1.18.3-cp310-cp310-win_amd64.whl", hash = "sha256:93b2e109287f93db79210f86deb6b9bbb81ac32fc97236b16f7433db7fc437d8"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8503ad47387b8ebd39cbbbdf0bf113e17330ffd339ba1144074da24c545f0069"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02ddb6756f8f4517a2d5e99d8b2f272488e18dd0bfbc802f31c16c6c20f22193"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67a283dd2882ac98cc6318384f565bffc751ab564605959df4752d42483ad889"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d980e0325b6eddc81331d3f4551e2a333999fb176fd153e075c6d1c2530aa8a8"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b643562c12680b01e17239be267bc306bbc6aac1f34f6444d1bded0c5ce438ca"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c017a3b6df3a1bd45b9fa49a0f54005e53fbcad16633870104b66fa1a30a29d8"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75674776d96d7b851b6498f17824ba17849d790a44d282929c42dbb77d4f17ae"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccaa3a4b521b780a7e771cc336a2dba389a0861592bbce09a476190bb0c8b4b3"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d06d3005e668744e11ed80812e61efd77d70bb7f03e33c1598c301eea20efbb"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:9d41beda9dc97ca9ab0b9888cb71f7539124bc05df02c0cff6e5acc5a19dcc6e"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ba23302c0c61a9999784e73809427c9dbedd79f66a13d84ad1b1943802eaaf59"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6748dbf9bfa5ba1afcc7556b71cda0d7ce5f24768043a02a58846e4a443d808d"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0b0cad37311123211dc91eadcb322ef4d4a66008d3e1bdc404808992260e1a0e"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0fb2171a4486bb075316ee754c6d8382ea6eb8b399d4ec62fde2b591f879778a"}, + {file = "yarl-1.18.3-cp311-cp311-win32.whl", hash = "sha256:61b1a825a13bef4a5f10b1885245377d3cd0bf87cba068e1d9a88c2ae36880e1"}, + {file = "yarl-1.18.3-cp311-cp311-win_amd64.whl", hash = "sha256:b9d60031cf568c627d028239693fd718025719c02c9f55df0a53e587aab951b5"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285"}, + {file = "yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2"}, + {file = "yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:90adb47ad432332d4f0bc28f83a5963f426ce9a1a8809f5e584e704b82685dcb"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:913829534200eb0f789d45349e55203a091f45c37a2674678744ae52fae23efa"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ef9f7768395923c3039055c14334ba4d926f3baf7b776c923c93d80195624782"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a19f62ff30117e706ebc9090b8ecc79aeb77d0b1f5ec10d2d27a12bc9f66d0"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e17c9361d46a4d5addf777c6dd5eab0715a7684c2f11b88c67ac37edfba6c482"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a74a13a4c857a84a845505fd2d68e54826a2cd01935a96efb1e9d86c728e186"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41f7ce59d6ee7741af71d82020346af364949314ed3d87553763a2df1829cc58"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f52a265001d830bc425f82ca9eabda94a64a4d753b07d623a9f2863fde532b53"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:82123d0c954dc58db301f5021a01854a85bf1f3bb7d12ae0c01afc414a882ca2"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2ec9bbba33b2d00999af4631a3397d1fd78290c48e2a3e52d8dd72db3a067ac8"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbd6748e8ab9b41171bb95c6142faf068f5ef1511935a0aa07025438dd9a9bc1"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:877d209b6aebeb5b16c42cbb377f5f94d9e556626b1bfff66d7b0d115be88d0a"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b464c4ab4bfcb41e3bfd3f1c26600d038376c2de3297760dfe064d2cb7ea8e10"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8d39d351e7faf01483cc7ff7c0213c412e38e5a340238826be7e0e4da450fdc8"}, + {file = "yarl-1.18.3-cp313-cp313-win32.whl", hash = "sha256:61ee62ead9b68b9123ec24bc866cbef297dd266175d53296e2db5e7f797f902d"}, + {file = "yarl-1.18.3-cp313-cp313-win_amd64.whl", hash = "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:61e5e68cb65ac8f547f6b5ef933f510134a6bf31bb178be428994b0cb46c2a04"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe57328fbc1bfd0bd0514470ac692630f3901c0ee39052ae47acd1d90a436719"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a440a2a624683108a1b454705ecd7afc1c3438a08e890a1513d468671d90a04e"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09c7907c8548bcd6ab860e5f513e727c53b4a714f459b084f6580b49fa1b9cee"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4f6450109834af88cb4cc5ecddfc5380ebb9c228695afc11915a0bf82116789"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9ca04806f3be0ac6d558fffc2fdf8fcef767e0489d2684a21912cc4ed0cd1b8"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77a6e85b90a7641d2e07184df5557132a337f136250caafc9ccaa4a2a998ca2c"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6333c5a377c8e2f5fae35e7b8f145c617b02c939d04110c76f29ee3676b5f9a5"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0b3c92fa08759dbf12b3a59579a4096ba9af8dd344d9a813fc7f5070d86bbab1"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4ac515b860c36becb81bb84b667466885096b5fc85596948548b667da3bf9f24"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:045b8482ce9483ada4f3f23b3774f4e1bf4f23a2d5c912ed5170f68efb053318"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:a4bb030cf46a434ec0225bddbebd4b89e6471814ca851abb8696170adb163985"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:54d6921f07555713b9300bee9c50fb46e57e2e639027089b1d795ecd9f7fa910"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1d407181cfa6e70077df3377938c08012d18893f9f20e92f7d2f314a437c30b1"}, + {file = "yarl-1.18.3-cp39-cp39-win32.whl", hash = "sha256:ac36703a585e0929b032fbaab0707b75dc12703766d0b53486eabd5139ebadd5"}, + {file = "yarl-1.18.3-cp39-cp39-win_amd64.whl", hash = "sha256:ba87babd629f8af77f557b61e49e7c7cac36f22f871156b91e10a6e9d4f829e9"}, + {file = "yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b"}, + {file = "yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1"}, ] [package.dependencies] diff --git a/airbyte-integrations/connectors/source-azure-table/pyproject.toml b/airbyte-integrations/connectors/source-azure-table/pyproject.toml index 1d567f2a4abd..c86a03fc257a 100644 --- a/airbyte-integrations/connectors/source-azure-table/pyproject.toml +++ b/airbyte-integrations/connectors/source-azure-table/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.28" +version = "0.1.32" name = "source-azure-table" description = "Source implementation for Azure Table." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-azure-table/unit_tests/test_azure_table.py b/airbyte-integrations/connectors/source-azure-table/unit_tests/test_azure_table.py index 752e8472480c..aa1b2aaceb78 100644 --- a/airbyte-integrations/connectors/source-azure-table/unit_tests/test_azure_table.py +++ b/airbyte-integrations/connectors/source-azure-table/unit_tests/test_azure_table.py @@ -23,14 +23,11 @@ def test_get_table_service_client_handles_exception(mocker, reader): """ Test that get_table_service_client method handles exceptions correctly. """ - mocker.patch( - "source_azure_table.azure_table.TableServiceClient.from_connection_string", - side_effect=Exception("Connection error") - ) + mocker.patch("source_azure_table.azure_table.TableServiceClient.from_connection_string", side_effect=Exception("Connection error")) with pytest.raises(Exception) as exc_info: reader.get_table_service_client() - + assert "Connection error" in str(exc_info.value) @@ -58,10 +55,7 @@ def test_get_table_client_handles_exception(mocker, reader): reader.get_table_client("") assert "table name is not valid." in str(exc_info.value) - mocker.patch( - "source_azure_table.azure_table.TableClient.from_connection_string", - side_effect=Exception("Connection error") - ) + mocker.patch("source_azure_table.azure_table.TableClient.from_connection_string", side_effect=Exception("Connection error")) with pytest.raises(Exception) as exc_info: reader.get_table_client("valid_table_name") @@ -74,10 +68,7 @@ def test_get_tables_return(mocker, reader, tables): """ mock_client = mocker.MagicMock() mock_client.list_tables.return_value = tables.__iter__() - mocker.patch( - "azure.data.tables.TableServiceClient.from_connection_string", - return_value=mock_client - ) + mocker.patch("azure.data.tables.TableServiceClient.from_connection_string", return_value=mock_client) result = reader.get_tables() result_table_names = [table.name for table in result] @@ -92,10 +83,7 @@ def test_get_tables_handles_exception(mocker, reader): """ mock_client = mocker.MagicMock() mock_client.list_tables.side_effect = Exception("Failed to list tables") - mocker.patch( - "azure.data.tables.TableServiceClient.from_connection_string", - return_value=mock_client - ) + mocker.patch("azure.data.tables.TableServiceClient.from_connection_string", return_value=mock_client) with pytest.raises(Exception) as exc_info: reader.get_tables() diff --git a/airbyte-integrations/connectors/source-azure-table/unit_tests/test_source.py b/airbyte-integrations/connectors/source-azure-table/unit_tests/test_source.py index 956375acda0b..d9a455c7def7 100644 --- a/airbyte-integrations/connectors/source-azure-table/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-azure-table/unit_tests/test_source.py @@ -2,9 +2,10 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # -from airbyte_cdk.models import AirbyteCatalog, SyncMode from source_azure_table.streams import AzureTableStream +from airbyte_cdk.models import AirbyteCatalog, SyncMode + # Tests def test_discover(mocker, config, tables, source, logger): diff --git a/airbyte-integrations/connectors/source-babelforce/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-babelforce/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-babelforce/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-babelforce/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-babelforce/metadata.yaml b/airbyte-integrations/connectors/source-babelforce/metadata.yaml index 092c69a4e8fb..92180120c1ca 100644 --- a/airbyte-integrations/connectors/source-babelforce/metadata.yaml +++ b/airbyte-integrations/connectors/source-babelforce/metadata.yaml @@ -14,7 +14,7 @@ data: connectorSubtype: api connectorType: source definitionId: 971c3e1e-78a5-411e-ad56-c4052b50876b - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.7 dockerRepository: airbyte/source-babelforce githubIssueLabel: source-babelforce icon: babelforce.svg @@ -31,5 +31,5 @@ data: ql: 100 supportLevel: community connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-bamboo-hr/components.py b/airbyte-integrations/connectors/source-bamboo-hr/components.py index 8035c61dc25d..0f925f3bee74 100644 --- a/airbyte-integrations/connectors/source-bamboo-hr/components.py +++ b/airbyte-integrations/connectors/source-bamboo-hr/components.py @@ -11,7 +11,6 @@ @dataclass class CustomReportsSchemaLoader(JsonFileSchemaLoader): - config: Mapping[str, Any] parameters: InitVar[Mapping[str, Any]] = {"name": "custom_reports_stream"} diff --git a/airbyte-integrations/connectors/source-bamboo-hr/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-bamboo-hr/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-bamboo-hr/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-bamboo-hr/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-bamboo-hr/metadata.yaml b/airbyte-integrations/connectors/source-bamboo-hr/metadata.yaml index d5fbfa1814ed..e128a61b3bb7 100644 --- a/airbyte-integrations/connectors/source-bamboo-hr/metadata.yaml +++ b/airbyte-integrations/connectors/source-bamboo-hr/metadata.yaml @@ -6,11 +6,11 @@ data: ql: 200 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.14.0@sha256:accdf6c1bbcabd45b40f836692e4f3b1a1e1f0b28267973802ee212cd9c2c16a + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 90916976-a132-4ce9-8bce-82a03dd58788 - dockerImageTag: 0.5.0 + dockerImageTag: 0.5.4 dockerRepository: airbyte/source-bamboo-hr documentationUrl: https://docs.airbyte.com/integrations/sources/bamboo-hr githubIssueLabel: source-bamboo-hr diff --git a/airbyte-integrations/connectors/source-beamer/metadata.yaml b/airbyte-integrations/connectors/source-beamer/metadata.yaml index e2356bca6ed3..9af418850225 100644 --- a/airbyte-integrations/connectors/source-beamer/metadata.yaml +++ b/airbyte-integrations/connectors/source-beamer/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-beamer connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.6.2@sha256:f5fcd3d4703b7590b6166a7853c5ed1686731607cd30a159a8c24e2fe2c1ee98 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: b928158d-4d2a-4ea6-a9c6-efa90f5c1e5d - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-beamer githubIssueLabel: source-beamer icon: icon.svg diff --git a/airbyte-integrations/connectors/source-bigcommerce/README.md b/airbyte-integrations/connectors/source-bigcommerce/README.md index 68db043c87ec..d12d54253347 100644 --- a/airbyte-integrations/connectors/source-bigcommerce/README.md +++ b/airbyte-integrations/connectors/source-bigcommerce/README.md @@ -1,89 +1,63 @@ # Bigcommerce source connector +This directory contains the manifest-only connector for `source-bigcommerce`. +This _manifest-only_ connector is not a Python package on its own, as it runs inside of the base `source-declarative-manifest` image. -This is the repository for the Bigcommerce source connector, written in Python. -For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.com/integrations/sources/bigcommerce). +For information about how to configure and use this connector within Airbyte, see [the connector's full documentation](https://docs.airbyte.com/integrations/sources/bigcommerce). ## Local development -### Prerequisites -* Python (~=3.9) -* Poetry (~=1.7) - installation instructions [here](https://python-poetry.org/docs/#installation) +We recommend using the Connector Builder to edit this connector. +Using either Airbyte Cloud or your local Airbyte OSS instance, navigate to the **Builder** tab and select **Import a YAML**. +Then select the connector's `manifest.yaml` file to load the connector into the Builder. You're now ready to make changes to the connector! +If you prefer to develop locally, you can follow the instructions below. -### Installing the connector -From this connector directory, run: -```bash -poetry install --with dev -``` - - -### Create credentials -**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/bigcommerce) -to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_bigcommerce/spec.yaml` file. -Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. -See `sample_files/sample_config.json` for a sample config file. - - -### Locally running the connector -``` -poetry run source-bigcommerce spec -poetry run source-bigcommerce check --config secrets/config.json -poetry run source-bigcommerce discover --config secrets/config.json -poetry run source-bigcommerce read --config secrets/config.json --catalog sample_files/configured_catalog.json -``` +### Building the docker image -### Running unit tests -To run unit tests locally, from the connector directory run: -``` -poetry run pytest unit_tests -``` +You can build any manifest-only connector with `airbyte-ci`: -### Building the docker image 1. Install [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md) 2. Run the following command to build the docker image: + ```bash airbyte-ci connectors --name=source-bigcommerce build ``` An image will be available on your host with the tag `airbyte/source-bigcommerce:dev`. +### Creating credentials + +**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/bigcommerce) +to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `spec` object in the connector's `manifest.yaml` file. +Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. ### Running as a docker container -Then run any of the connector commands as follows: -``` + +Then run any of the standard source connector commands: + +```bash docker run --rm airbyte/source-bigcommerce:dev spec docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-bigcommerce:dev check --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-bigcommerce:dev discover --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-bigcommerce:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json ``` -### Running our CI test suite -You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): -```bash -airbyte-ci connectors --name=source-bigcommerce test -``` +### Running the CI test suite -### Customizing acceptance Tests -Customize `acceptance-test-config.yml` file to configure acceptance tests. See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) for more information. -If your connector requires to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py. +You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): -### Dependency Management -All of your dependencies should be managed via Poetry. -To add a new dependency, run: ```bash -poetry add +airbyte-ci connectors --name=source-bigcommerce test ``` -Please commit the changes to `pyproject.toml` and `poetry.lock` files. - ## Publishing a new version of the connector -You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what? -1. Make sure your changes are passing our test suite: `airbyte-ci connectors --name=source-bigcommerce test` -2. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): + +If you want to contribute changes to `source-bigcommerce`, here's how you can do that: +1. Make your changes locally, or load the connector's manifest into Connector Builder and make changes there. +2. Make sure your changes are passing our test suite with `airbyte-ci connectors --name=source-bigcommerce test` +3. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): - bump the `dockerImageTag` value in in `metadata.yaml` - - bump the `version` value in `pyproject.toml` -3. Make sure the `metadata.yaml` content is up to date. 4. Make sure the connector documentation and its changelog is up to date (`docs/integrations/sources/bigcommerce.md`). 5. Create a Pull Request: use [our PR naming conventions](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#pull-request-title-convention). 6. Pat yourself on the back for being an awesome contributor. diff --git a/airbyte-integrations/connectors/source-bigcommerce/__init__.py b/airbyte-integrations/connectors/source-bigcommerce/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-integrations/connectors/source-bigcommerce/acceptance-test-config.yml b/airbyte-integrations/connectors/source-bigcommerce/acceptance-test-config.yml index 564a05cfa774..9659545f0b7e 100644 --- a/airbyte-integrations/connectors/source-bigcommerce/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-bigcommerce/acceptance-test-config.yml @@ -4,7 +4,7 @@ connector_image: airbyte/source-bigcommerce:dev acceptance_tests: spec: tests: - - spec_path: "source_bigcommerce/spec.yaml" + - spec_path: "manifest.yaml" connection: tests: - config_path: "secrets/config.json" diff --git a/airbyte-integrations/connectors/source-bigcommerce/components.py b/airbyte-integrations/connectors/source-bigcommerce/components.py new file mode 100644 index 000000000000..5a823f6da031 --- /dev/null +++ b/airbyte-integrations/connectors/source-bigcommerce/components.py @@ -0,0 +1,29 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +from dataclasses import dataclass +from typing import Optional + +import dpath.util +import pendulum + +from airbyte_cdk.sources.declarative.transformations.add_fields import AddFields +from airbyte_cdk.sources.declarative.types import Config, Record, StreamSlice, StreamState + + +@dataclass +class DateTimeTransformer(AddFields): + def transform( + self, + record: Record, + config: Optional[Config] = None, + stream_state: Optional[StreamState] = None, + stream_slice: Optional[StreamSlice] = None, + ) -> Record: + kwargs = {"record": record, "stream_state": stream_state, "stream_slice": stream_slice} + for parsed_field in self._parsed_fields: + date_time = parsed_field.value.eval(config, **kwargs) + new_date_time = str(pendulum.from_format(date_time, "ddd, D MMM YYYY HH:mm:ss ZZ")) + dpath.util.new(record, parsed_field.path, new_date_time) + return record diff --git a/airbyte-integrations/connectors/source-bigcommerce/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-bigcommerce/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-bigcommerce/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-bigcommerce/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-bigcommerce/main.py b/airbyte-integrations/connectors/source-bigcommerce/main.py deleted file mode 100644 index 7830bf519a65..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/main.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from source_bigcommerce.run import run - -if __name__ == "__main__": - run() diff --git a/airbyte-integrations/connectors/source-bigcommerce/manifest.yaml b/airbyte-integrations/connectors/source-bigcommerce/manifest.yaml new file mode 100644 index 000000000000..134c62e6506d --- /dev/null +++ b/airbyte-integrations/connectors/source-bigcommerce/manifest.yaml @@ -0,0 +1,3158 @@ +version: 5.15.0 + +type: DeclarativeSource + +check: + type: CheckStream + stream_names: + - customers + +definitions: + streams: + customers: + type: DeclarativeStream + name: customers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v3/customers + http_method: GET + request_parameters: + sort: date_modified:asc + request_headers: + Accept: application/json + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 250 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: date_modified + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%dT%H:%M:%S+00:00" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%d" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: date_modified:min + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers" + orders: + type: DeclarativeStream + name: orders + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/orders + http_method: GET + request_parameters: + sort: date_modified:asc + request_headers: + Accept: application/json + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 250 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: date_modified + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%dT%H:%M:%S+00:00" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%d" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: min_date_modified + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + transformations: + - type: CustomTransformation + class_name: source_declarative_manifest.components.DateTimeTransformer + fields: + - path: + - date_modified + value: "{{ record.date_modified }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/orders" + transactions: + type: DeclarativeStream + name: transactions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/orders/{{ stream_partition.order_id }}/transactions + http_method: GET + request_headers: + Accept: application/json + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 250 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: order_id + stream: + $ref: "#/definitions/streams/orders" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: id + cursor_datetime_formats: + - "%s" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%d" + start_time_option: + type: RequestOption + field_name: date_modified:min + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/transactions" + pages: + type: DeclarativeStream + name: pages + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v3/content/pages + http_method: GET + request_parameters: + sort: date_modified:asc + request_headers: + Accept: application/json + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 250 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: id + cursor_datetime_formats: + - "%s" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%d" + start_time_option: + type: RequestOption + field_name: date_modified:min + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/pages" + products: + type: DeclarativeStream + name: products + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v3/catalog/products + http_method: GET + request_parameters: + sort: date_modified + request_headers: + Accept: application/json + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 250 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: date_modified + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%dT%H:%M:%S+00:00" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%d" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: date_modified:min + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + channels: + type: DeclarativeStream + name: channels + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v3/channels + http_method: GET + request_parameters: + sort: date_modified + request_headers: + Accept: application/json + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 250 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: date_modified + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%dT%H:%M:%S+00:00" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%d" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: date_modified:min + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/channels" + store: + type: DeclarativeStream + name: store + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/store + http_method: GET + request_parameters: + sort: date_modified:asc + request_headers: + Accept: application/json + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 250 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/store" + order_products: + type: DeclarativeStream + name: order_products + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/orders/{{ stream_partition.order_id }}/products + http_method: GET + request_parameters: + sort: date_modified:asc + request_headers: + Accept: application/json + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 250 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: order_id + stream: + $ref: "#/definitions/streams/orders" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: id + cursor_datetime_formats: + - "%s" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%d" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/order_products" + brands: + type: DeclarativeStream + name: brands + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v3/catalog/brands + http_method: GET + request_parameters: + sort: id + request_headers: + Accept: application/json + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 250 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: id + cursor_datetime_formats: + - "%s" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%d" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/brands" + categories: + type: DeclarativeStream + name: categories + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v3/catalog/categories + http_method: GET + request_parameters: + sort: id + request_headers: + Accept: application/json + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 250 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: id + cursor_datetime_formats: + - "%s" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%d" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/categories" + base_requester: + type: HttpRequester + url_base: https://api.bigcommerce.com/stores/{{ config["store_hash"] }}/ + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"access_token\"] }}" + inject_into: + type: RequestOption + inject_into: header + field_name: X-Auth-Token + +streams: + - $ref: "#/definitions/streams/customers" + - $ref: "#/definitions/streams/orders" + - $ref: "#/definitions/streams/transactions" + - $ref: "#/definitions/streams/pages" + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/channels" + - $ref: "#/definitions/streams/store" + - $ref: "#/definitions/streams/order_products" + - $ref: "#/definitions/streams/brands" + - $ref: "#/definitions/streams/categories" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - start_date + - access_token + - store_hash + properties: + start_date: + type: string + description: "The date you would like to replicate data. Format: YYYY-MM-DD." + title: Start date + examples: + - "2021-01-01" + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ + order: 0 + access_token: + type: string + description: Access Token for making authenticated requests. + title: Access Token + airbyte_secret: true + order: 1 + store_hash: + type: string + description: >- + The hash code of the store. For + https://api.bigcommerce.com/stores/HASH_CODE/v3/, The store's hash + code is 'HASH_CODE'. + title: Store Hash + order: 2 + additionalProperties: true + +metadata: + autoImportSchema: + customers: false + orders: false + transactions: false + pages: false + products: false + channels: false + store: false + order_products: false + brands: false + categories: false + yamlComponents: + streams: + orders: + - transformations + testedStreams: {} + assist: {} + +schemas: + customers: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + address_count: + type: + - "null" + - integer + addresses: + type: + - "null" + - array + items: + type: + - "null" + - object + additionalProperties: true + properties: + accepts_product_review_abandoned_cart_emails: + type: + - "null" + - boolean + address1: + type: + - "null" + - string + address2: + type: + - "null" + - string + address_type: + type: + - "null" + - string + channel_ids: + type: + - "null" + - array + city: + type: + - "null" + - string + company: + type: + - "null" + - string + country: + type: + - "null" + - string + country_code: + type: + - "null" + - string + customer_id: + type: + - "null" + - integer + first_name: + type: + - "null" + - string + form_fields: + type: + - "null" + - array + oneOf: + - type: + - "null" + - object + properties: + customer_id: + type: + - "null" + - integer + name: + type: + - "null" + - string + value: + oneOf: + - type: + - "null" + - string + - type: + - "null" + - integer + - type: + - "null" + - array + - type: + - "null" + - object + properties: + address_id: + type: + - "null" + - integer + name: + type: + - "null" + - string + value: + oneOf: + - type: + - "null" + - string + - type: + - "null" + - integer + - type: + - "null" + - array + id: + type: + - "null" + - integer + last_name: + type: + - "null" + - string + origin_channel_id: + type: + - "null" + - integer + phone: + type: + - "null" + - string + postal_code: + type: + - "null" + - string + state_or_province: + type: + - "null" + - string + store_credit_amounts: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + amount: + type: + - "null" + - integer + attribute_count: + type: + - "null" + - integer + authentication: + type: + - "null" + - object + properties: + force_password_reset: + type: + - "null" + - boolean + company: + type: + - "null" + - string + customer_group_id: + type: + - "null" + - integer + date_created: + type: + - "null" + - string + format: date-time + date_modified: + type: + - "null" + - string + format: date-time + email: + type: + - "null" + - string + first_name: + type: + - "null" + - string + id: + type: + - "null" + - integer + last_name: + type: + - "null" + - string + notes: + type: + - "null" + - string + phone: + type: + - "null" + - string + registration_ip_address: + type: + - "null" + - string + tax_exempt_category: + type: + - "null" + - string + orders: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + base_handling_cost: + type: + - "null" + - string + base_shipping_cost: + type: + - "null" + - string + base_wrapping_cost: + oneOf: + - type: + - "null" + - integer + - type: + - "null" + - string + billing_address: + type: + - "null" + - object + properties: + city: + type: + - "null" + - string + company: + type: + - "null" + - string + country: + type: + - "null" + - string + country_iso2: + type: + - "null" + - string + email: + type: + - "null" + - string + first_name: + type: + - "null" + - string + form_fields: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + name: + type: + - "null" + - string + value: + type: + - "null" + - string + last_name: + type: + - "null" + - string + phone: + type: + - "null" + - string + state: + type: + - "null" + - string + street_1: + type: + - "null" + - string + street_2: + type: + - "null" + - string + zip: + type: + - "null" + - string + cart_id: + type: + - "null" + - string + channel_id: + type: + - "null" + - integer + coupon_discount: + type: + - "null" + - string + coupons: + type: + - "null" + - object + properties: + resource: + type: + - "null" + - string + url: + type: + - "null" + - string + currency_code: + type: + - "null" + - string + currency_exchange_rate: + type: + - "null" + - string + currency_id: + type: + - "null" + - integer + customer_id: + type: + - "null" + - integer + customer_locale: + type: + - "null" + - string + customer_message: + type: + - "null" + - string + date_created: + type: + - "null" + - string + format: date-time + date_modified: + type: + - "null" + - string + format: date-time + date_shipped: + type: + - "null" + - string + format: date-time + default_currency_code: + type: + - "null" + - string + default_currency_id: + type: + - "null" + - integer + discount_amount: + type: + - "null" + - string + ebay_order_id: + type: + - "null" + - string + external_id: + type: + - "null" + - string + external_source: + type: + - "null" + - string + geoip_country: + type: + - "null" + - string + geoip_country_iso2: + type: + - "null" + - string + gift_certificate_amount: + type: + - "null" + - string + handling_cost_ex_tax: + type: + - "null" + - string + handling_cost_inc_tax: + type: + - "null" + - string + handling_cost_tax: + type: + - "null" + - string + handling_cost_tax_class_id: + type: + - "null" + - integer + id: + type: + - "null" + - integer + ip_address: + type: + - "null" + - string + is_deleted: + type: + - "null" + - boolean + is_email_opt_in: + type: + - "null" + - boolean + items_shipped: + type: + - "null" + - integer + items_total: + type: + - "null" + - integer + order_is_digital: + type: + - "null" + - boolean + order_source: + type: + - "null" + - string + payment_method: + type: + - "null" + - string + payment_status: + type: + - "null" + - string + products: + type: + - "null" + - object + properties: + resource: + type: + - "null" + - string + url: + type: + - "null" + - string + refunded_amount: + type: + - "null" + - string + shipping_address_count: + type: + - "null" + - integer + shipping_addresses: + type: + - "null" + - object + properties: + resource: + type: + - "null" + - string + url: + type: + - "null" + - string + shipping_cost_ex_tax: + type: + - "null" + - string + shipping_cost_inc_tax: + type: + - "null" + - string + shipping_cost_tax: + type: + - "null" + - string + shipping_cost_tax_class_id: + type: + - "null" + - integer + staff_notes: + type: + - "null" + - string + status: + type: + - "null" + - string + status_id: + type: + - "null" + - integer + store_credit_amount: + type: + - "null" + - string + subtotal_ex_tax: + type: + - "null" + - string + subtotal_inc_tax: + type: + - "null" + - string + subtotal_tax: + type: + - "null" + - string + tax_provider_id: + type: + - "null" + - string + total_ex_tax: + type: + - "null" + - string + total_inc_tax: + type: + - "null" + - string + wrapping_cost_ex_tax: + type: + - "null" + - string + wrapping_cost_inc_tax: + type: + - "null" + - string + wrapping_cost_tax: + type: + - "null" + - string + wrapping_cost_tax_class_id: + type: + - "null" + - integer + transactions: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + amount: + type: + - "null" + - number + avs_result: + type: + - "null" + - object + properties: + code: + type: + - "null" + - string + message: + type: + - "null" + - string + postal_match: + type: + - "null" + - string + street_match: + type: + - "null" + - string + credit_card: + type: + - "null" + - object + properties: + card_expiry_month: + type: + - "null" + - integer + card_expiry_year: + type: + - "null" + - integer + card_iin: + type: + - "null" + - string + card_last4: + type: + - "null" + - string + card_type: + type: + - "null" + - string + currency: + type: + - "null" + - string + custom: + type: + - "null" + - object + properties: + payment_method: + type: + - "null" + - string + cvv_result: + type: + - "null" + - object + properties: + code: + type: + - "null" + - string + message: + type: + - "null" + - string + date_created: + type: + - "null" + - string + event: + type: + - "null" + - string + fraud_review: + type: + - "null" + - boolean + gateway: + type: + - "null" + - string + gateway_transaction_id: + type: + - "null" + - string + gift_certificate: + type: + - "null" + - object + properties: + code: + type: + - "null" + - string + original_balance: + type: + - "null" + - integer + remaining_balance: + type: + - "null" + - integer + starting_balance: + type: + - "null" + - integer + status: + type: + - "null" + - string + id: + type: + - "null" + - integer + method: + type: + - "null" + - string + offline: + type: + - "null" + - object + properties: + display_name: + type: + - "null" + - string + order_id: + type: + - "null" + - string + payment_instrument_token: + type: + - "null" + - string + payment_method_id: + type: + - "null" + - string + reference_transaction_id: + type: + - "null" + - integer + status: + type: + - "null" + - string + store_credit: + type: + - "null" + - object + properties: + remaining_balance: + type: + - "null" + - integer + test: + type: + - "null" + - boolean + pages: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + type: + type: + - "null" + - string + body: + type: + - "null" + - string + channel_id: + type: + - "null" + - integer + contact_fields: + type: + - "null" + - string + email: + type: + - "null" + - string + feed: + type: + - "null" + - string + id: + type: + - "null" + - integer + is_customers_only: + type: + - "null" + - boolean + is_homepage: + type: + - "null" + - boolean + is_visible: + type: + - "null" + - boolean + link: + type: + - "null" + - string + meta_description: + type: + - "null" + - string + meta_keywords: + type: + - "null" + - string + meta_title: + type: + - "null" + - string + name: + type: + - "null" + - string + parent_id: + type: + - "null" + - integer + search_keywords: + type: + - "null" + - string + sort_order: + type: + - "null" + - integer + url: + type: + - "null" + - string + products: + type: object + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: + type: + - "null" + - string + availability: + type: + - "null" + - string + availability_description: + type: + - "null" + - string + base_variant_id: + type: + - "null" + - integer + bin_picking_number: + type: + - "null" + - string + brand_id: + type: + - "null" + - integer + brand_name or brand_id: + type: + - "null" + - string + bulk_pricing_rules: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + amount: + type: + - "null" + - integer + id: + type: + - "null" + - integer + quantity_max: + type: + - "null" + - integer + quantity_min: + type: + - "null" + - integer + required: + - quantity_min + - quantity_max + - type + - amount + title: bulkPricingRule_Full + calculated_price: + type: + - "null" + - number + format: float + categories: + type: + - "null" + - array + items: + type: + - "null" + - integer + condition: + type: + - "null" + - string + cost_price: + type: + - "null" + - number + format: float + custom_fields: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + id: + type: + - "null" + - integer + name: + type: + - "null" + - string + value: + type: + - "null" + - string + required: + - name + - value + title: productCustomField_Put + custom_url: + type: + - "null" + - object + properties: + is_customized: + type: + - "null" + - boolean + url: + type: + - "null" + - string + title: customUrl_Full + date_created: + type: + - "null" + - string + format: date-time + date_modified: + type: + - "null" + - string + format: date-time + depth: + type: + - "null" + - number + format: float + fixed_cost_shipping_price: + type: + - "null" + - number + format: float + gift_wrapping_options_list: + type: + - "null" + - array + items: + type: + - "null" + - integer + gift_wrapping_options_type: + type: + - "null" + - string + gtin: + type: + - "null" + - string + height: + type: + - "null" + - number + format: float + id: + type: + - "null" + - integer + images: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + description: + type: + - "null" + - string + date_modified: + type: + - "null" + - string + format: date-time + id: + type: + - "null" + - integer + image_file: + type: + - "null" + - string + image_url: + type: + - "null" + - string + is_thumbnail: + type: + - "null" + - boolean + product_id: + type: + - "null" + - integer + sort_order: + type: + - "null" + - integer + url_standard: + type: + - "null" + - string + url_thumbnail: + type: + - "null" + - string + url_tiny: + type: + - "null" + - string + url_zoom: + type: + - "null" + - string + title: productImage_Full + inventory_level: + type: + - "null" + - integer + inventory_tracking: + type: + - "null" + - string + inventory_warning_level: + type: + - "null" + - integer + is_condition_shown: + type: + - "null" + - boolean + is_featured: + type: + - "null" + - boolean + is_free_shipping: + type: + - "null" + - boolean + is_preorder_only: + type: + - "null" + - boolean + is_price_hidden: + type: + - "null" + - boolean + is_visible: + type: + - "null" + - boolean + layout_file: + type: + - "null" + - string + map_price: + type: + - "null" + - number + meta_description: + type: + - "null" + - string + meta_keywords: + type: + - "null" + - array + items: + type: + - "null" + - string + modifiers: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + config: + type: + - "null" + - object + properties: + checkbox_label: + type: + - "null" + - string + checked_by_default: + type: + - "null" + - boolean + date_earliest_value: + type: + - "null" + - string + format: date + date_latest_value: + type: + - "null" + - string + format: date + date_limit_mode: + type: + - "null" + - string + date_limited: + type: + - "null" + - boolean + default_value: + type: + - "null" + - string + file_max_size: + type: + - "null" + - integer + file_types_mode: + type: + - "null" + - string + file_types_other: + type: + - "null" + - array + items: + type: + - "null" + - string + file_types_supported: + type: + - "null" + - array + items: + type: + - "null" + - string + number_highest_value: + type: + - "null" + - number + number_integers_only: + type: + - "null" + - boolean + number_limit_mode: + type: + - "null" + - string + number_limited: + type: + - "null" + - boolean + number_lowest_value: + type: + - "null" + - number + product_list_adjusts_inventory: + type: + - "null" + - boolean + product_list_adjusts_pricing: + type: + - "null" + - boolean + product_list_shipping_calc: + type: + - "null" + - string + text_characters_limited: + type: + - "null" + - boolean + text_lines_limited: + type: + - "null" + - boolean + text_max_length: + type: + - "null" + - integer + text_max_lines: + type: + - "null" + - integer + text_min_length: + type: + - "null" + - integer + title: config_Full + display_name: + type: + - "null" + - string + id: + type: + - "null" + - integer + name: + type: + - "null" + - string + option_values: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + adjusters: + type: + - "null" + - object + properties: + image_url: + type: + - "null" + - string + price: + type: + - "null" + - object + properties: + adjuster: + type: + - "null" + - string + adjuster_value: + type: + - "null" + - number + title: adjuster_Full + purchasing_disabled: + type: + - "null" + - object + properties: + message: + type: + - "null" + - string + status: + type: + - "null" + - boolean + weight: + type: + - "null" + - object + properties: + adjuster: + type: + - "null" + - string + adjuster_value: + type: + - "null" + - number + title: adjuster_Full + title: adjusters_Full + id: + type: + - "null" + - integer + is_default: + type: + - "null" + - boolean + label: + type: + - "null" + - string + option_id: + type: + - "null" + - integer + sort_order: + type: + - "null" + - integer + value_data: + type: + - object + - "null" + required: + - label + - sort_order + title: productModifierOptionValue_Full + product_id: + type: + - "null" + - integer + required: + type: + - "null" + - boolean + sort_order: + type: + - "null" + - integer + required: + - type + - required + title: productModifier_Full + mpn: + type: + - "null" + - string + name: + type: + - "null" + - string + open_graph_description: + type: + - "null" + - string + open_graph_title: + type: + - "null" + - string + open_graph_type: + type: + - "null" + - string + open_graph_use_image: + type: + - "null" + - boolean + open_graph_use_meta_description: + type: + - "null" + - boolean + open_graph_use_product_name: + type: + - "null" + - boolean + option_set_display: + type: + - "null" + - string + option_set_id: + type: + - "null" + - integer + options: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + config: + type: + - "null" + - object + properties: + checkbox_label: + type: + - "null" + - string + checked_by_default: + type: + - "null" + - boolean + date_earliest_value: + type: + - "null" + - string + format: date + date_latest_value: + type: + - "null" + - string + format: date + date_limit_mode: + type: + - "null" + - string + date_limited: + type: + - "null" + - boolean + default_value: + type: + - "null" + - string + file_max_size: + type: + - "null" + - integer + file_types_mode: + type: + - "null" + - string + file_types_other: + type: + - "null" + - array + items: + type: + - "null" + - string + file_types_supported: + type: + - "null" + - array + items: + type: + - "null" + - string + number_highest_value: + type: + - "null" + - number + number_integers_only: + type: + - "null" + - boolean + number_limit_mode: + type: + - "null" + - string + number_limited: + type: + - "null" + - boolean + number_lowest_value: + type: + - "null" + - number + product_list_adjusts_inventory: + type: + - "null" + - boolean + product_list_adjusts_pricing: + type: + - "null" + - boolean + product_list_shipping_calc: + type: + - "null" + - string + text_characters_limited: + type: + - "null" + - boolean + text_lines_limited: + type: + - "null" + - boolean + text_max_length: + type: + - "null" + - integer + text_max_lines: + type: + - "null" + - integer + text_min_length: + type: + - "null" + - integer + title: productOptionConfig_Full + display_name: + type: + - "null" + - string + id: + type: + - "null" + - integer + option_values: + type: + - "null" + - object + properties: + id: + type: + - "null" + - integer + is_default: + type: + - "null" + - boolean + label: + type: + - "null" + - string + sort_order: + type: + - "null" + - integer + value_data: + type: + - object + - "null" + required: + - label + - sort_order + title: productOptionOptionValue_Full + product_id: + type: + - "null" + - integer + sort_order: + type: + - "null" + - integer + title: productOption_Base + order_quantity_maximum: + type: + - "null" + - integer + order_quantity_minimum: + type: + - "null" + - integer + page_title: + type: + - "null" + - string + preorder_message: + type: + - "null" + - string + preorder_release_date: + type: + - "null" + - string + format: date-time + price: + type: + - "null" + - number + format: float + price_hidden_label: + type: + - "null" + - string + product_tax_code: + type: + - "null" + - string + related_products: + type: + - "null" + - array + items: + type: + - "null" + - integer + retail_price: + type: + - "null" + - number + format: float + reviews_count: + type: + - "null" + - integer + reviews_rating_sum: + type: + - "null" + - integer + sale_price: + type: + - "null" + - number + format: float + search_keywords: + type: + - "null" + - string + sku: + type: + - "null" + - string + sort_order: + type: + - "null" + - integer + tax_class_id: + type: + - "null" + - integer + total_sold: + type: + - "null" + - integer + upc: + type: + - "null" + - string + variants: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + bin_picking_number: + type: + - "null" + - string + calculated_price: + type: + - "null" + - number + format: double + calculated_weight: + type: number + cost_price: + type: + - "null" + - number + format: double + depth: + type: + - "null" + - number + format: double + fixed_cost_shipping_price: + type: + - "null" + - number + format: double + height: + type: + - "null" + - number + format: double + id: + type: + - "null" + - integer + inventory_level: + type: + - "null" + - integer + inventory_warning_level: + type: + - "null" + - integer + is_free_shipping: + type: + - "null" + - boolean + mpn: + type: + - "null" + - string + option_values: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + id: + type: + - "null" + - integer + label: + type: + - "null" + - string + option_display_name: + type: + - "null" + - string + option_id: + type: + - "null" + - integer + title: productVariantOptionValue_Full + price: + type: + - "null" + - number + format: double + product_id: + type: + - "null" + - integer + purchasing_disabled: + type: + - "null" + - boolean + purchasing_disabled_message: + type: + - "null" + - string + retail_price: + type: + - "null" + - number + format: double + sale_price: + type: + - "null" + - number + format: double + sku: + type: + - "null" + - string + sku_id: + type: + - "null" + - integer + upc: + type: + - "null" + - string + weight: + type: + - "null" + - number + format: double + width: + type: + - "null" + - number + format: double + title: productVariant_Full + videos: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + description: + type: + - "null" + - string + id: + type: + - "null" + - integer + length: + type: + - "null" + - string + product_id: + type: + - "null" + - integer + sort_order: + type: + - "null" + - integer + title: + type: + - "null" + - string + video_id: + type: + - "null" + - string + title: productVideo_Full + view_count: + type: + - "null" + - integer + warranty: + type: + - "null" + - string + weight: + type: + - "null" + - number + format: float + width: + type: + - "null" + - number + format: float + title: Product Response + channels: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + type: + type: + - "null" + - string + date_created: + type: + - "null" + - string + format: date-time + date_modified: + type: + - "null" + - string + format: date-time + external_id: + type: + - "null" + - string + icon_url: + type: + - "null" + - string + id: + type: + - "null" + - integer + is_enabled: + type: + - "null" + - boolean + is_listable_from_ui: + type: + - "null" + - boolean + is_visible: + type: + - "null" + - boolean + name: + type: + - "null" + - string + platform: + type: + - "null" + - string + status: + type: + - "null" + - string + store: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + account_uuid: + type: + - "null" + - string + active_comparison_modules: + type: + - "null" + - array + address: + type: + - "null" + - string + admin_email: + type: + - "null" + - string + control_panel_base_url: + type: + - "null" + - string + country: + type: + - "null" + - string + country_code: + type: + - "null" + - string + currency: + type: + - "null" + - string + currency_symbol: + type: + - "null" + - string + currency_symbol_location: + type: + - "null" + - string + decimal_places: + type: + - "null" + - integer + decimal_separator: + type: + - "null" + - string + default_channel_id: + type: + - "null" + - integer + default_site_id: + type: + - "null" + - integer + dimension_decimal_places: + type: + - "null" + - integer + dimension_decimal_token: + type: + - "null" + - string + dimension_thousands_token: + type: + - "null" + - string + dimension_units: + type: + - "null" + - string + domain: + type: + - "null" + - string + favicon_url: + type: + - "null" + - string + features: + type: + - "null" + - object + properties: + checkout_type: + type: + - "null" + - string + facebook_catalog_id: + type: + - "null" + - string + graphql_storefront_api_enabled: + type: + - "null" + - boolean + multi_storefront_enabled: + type: + - "null" + - boolean + shopper_consent_tracking_enabled: + type: + - "null" + - boolean + sitewidehttps_enabled: + type: + - "null" + - boolean + stencil_enabled: + type: + - "null" + - boolean + wishlists_enabled: + type: + - "null" + - boolean + first_name: + type: + - "null" + - string + id: + type: + - "null" + - string + industry: + type: + - "null" + - string + is_price_entered_with_tax: + type: + - "null" + - boolean + language: + type: + - "null" + - string + last_name: + type: + - "null" + - string + logo: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + url: + type: + - "null" + - string + name: + type: + - "null" + - string + order_email: + type: + - "null" + - string + phone: + type: + - "null" + - string + plan_is_trial: + type: + - "null" + - boolean + plan_level: + type: + - "null" + - string + plan_name: + type: + - "null" + - string + secure_url: + type: + - "null" + - string + status: + type: + - "null" + - string + store_id: + type: + - "null" + - integer + thousands_separator: + type: + - "null" + - string + timezone: + type: + - "null" + - object + properties: + date_format: + type: + - "null" + - object + properties: + display: + type: + - "null" + - string + export: + type: + - "null" + - string + extended_display: + type: + - "null" + - string + dst_offset: + type: + - "null" + - integer + name: + type: + - "null" + - string + raw_offset: + type: + - "null" + - integer + weight_units: + type: + - "null" + - string + order_products: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + type: + type: + - "null" + - string + applied_discounts: + type: + - "null" + - array + base_cost_price: + type: + - "null" + - string + base_price: + type: + - "null" + - string + base_total: + type: + - "null" + - string + base_wrapping_cost: + type: + - "null" + - string + bin_picking_number: + type: + - "null" + - string + brand: + type: + - "null" + - string + configurable_fields: + type: + - "null" + - array + cost_price_ex_tax: + type: + - "null" + - string + cost_price_inc_tax: + type: + - "null" + - string + cost_price_tax: + type: + - "null" + - string + depth: + type: + - "null" + - string + ebay_item_id: + type: + - "null" + - string + ebay_transaction_id: + type: + - "null" + - string + event_date: + type: + - "null" + - string + event_name: + type: + - "null" + - string + external_id: + type: + - "null" + - string + fixed_shipping_cost: + type: + - "null" + - string + fulfillment_source: + type: + - "null" + - string + gift_certificate_id: + type: + - "null" + - integer + height: + type: + - "null" + - string + id: + type: + - "null" + - integer + is_bundled_product: + type: + - "null" + - boolean + is_refunded: + type: + - "null" + - boolean + name: + type: + - "null" + - string + name_customer: + type: + - "null" + - string + name_merchant: + type: + - "null" + - string + option_set_id: + type: + - "null" + - integer + order_address_id: + type: + - "null" + - integer + order_id: + type: + - "null" + - integer + parent_order_product_id: + type: + - "null" + - integer + price_ex_tax: + type: + - "null" + - string + price_inc_tax: + type: + - "null" + - string + price_tax: + type: + - "null" + - string + product_id: + type: + - "null" + - integer + product_options: + type: + - "null" + - array + quantity: + type: + - "null" + - number + quantity_refunded: + type: + - "null" + - number + quantity_shipped: + type: + - "null" + - number + refund_amount: + type: + - "null" + - string + return_id: + type: + - "null" + - number + sku: + type: + - "null" + - string + total_ex_tax: + type: + - "null" + - string + total_inc_tax: + type: + - "null" + - string + total_tax: + type: + - "null" + - string + upc: + type: + - "null" + - string + variant_id: + type: + - "null" + - integer + weight: + type: + - "null" + - string + width: + type: + - "null" + - string + wrapping_cost_ex_tax: + type: + - "null" + - string + wrapping_cost_inc_tax: + type: + - "null" + - string + wrapping_cost_tax: + type: + - "null" + - string + wrapping_id: + type: + - "null" + - string + wrapping_message: + type: + - "null" + - string + wrapping_name: + type: + - "null" + - string + brands: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + custom_url: + type: + - "null" + - object + properties: + is_customized: + type: + - "null" + - boolean + url: + type: + - "null" + - string + id: + type: + - "null" + - integer + image_url: + type: + - "null" + - string + meta_description: + type: + - "null" + - string + meta_keywords: + type: + - "null" + - array + items: + type: + - "null" + - string + name: + type: + - "null" + - string + page_title: + type: + - "null" + - string + search_keywords: + type: + - "null" + - string + categories: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + description: + type: + - "null" + - string + custom_url: + type: + - "null" + - object + properties: + is_customized: + type: + - "null" + - boolean + path: + type: + - "null" + - string + default_product_sort: + type: + - "null" + - string + id: + type: + - "null" + - integer + image_url: + type: + - "null" + - string + is_visible: + type: + - "null" + - boolean + layout_file: + type: + - "null" + - string + meta_description: + type: + - "null" + - string + meta_keywords: + type: + - "null" + - array + items: + type: + - "null" + - string + name: + type: + - "null" + - string + page_title: + type: + - "null" + - string + parent_id: + type: + - "null" + - integer + search_keywords: + type: + - "null" + - string + sort_order: + type: + - "null" + - integer + views: + type: + - "null" + - integer diff --git a/airbyte-integrations/connectors/source-bigcommerce/metadata.yaml b/airbyte-integrations/connectors/source-bigcommerce/metadata.yaml index 570e2a7f0898..179f609496d1 100644 --- a/airbyte-integrations/connectors/source-bigcommerce/metadata.yaml +++ b/airbyte-integrations/connectors/source-bigcommerce/metadata.yaml @@ -4,7 +4,7 @@ data: - api.bigcommerce.com remoteRegistries: pypi: - enabled: true + enabled: false packageName: airbyte-source-bigcommerce registryOverrides: oss: @@ -14,7 +14,7 @@ data: connectorSubtype: api connectorType: source definitionId: 59c5501b-9f95-411e-9269-7143c939adbd - dockerImageTag: 0.2.22 + dockerImageTag: 0.3.6 dockerRepository: airbyte/source-bigcommerce documentationUrl: https://docs.airbyte.com/integrations/sources/bigcommerce githubIssueLabel: source-bigcommerce @@ -23,9 +23,9 @@ data: name: Bigcommerce releaseDate: 2021-08-19 releaseStage: alpha - supportLevel: community + supportLevel: archived tags: - - language:python + - language:manifest-only - cdk:low-code ab_internal: sl: 100 @@ -47,5 +47,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-bigcommerce/poetry.lock b/airbyte-integrations/connectors/source-bigcommerce/poetry.lock deleted file mode 100644 index 711efc8fb7ce..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/poetry.lock +++ /dev/null @@ -1,1492 +0,0 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. - -[[package]] -name = "airbyte-cdk" -version = "1.0.0" -description = "A framework for writing Airbyte Connectors." -optional = false -python-versions = "<4.0,>=3.9" -files = [ - {file = "airbyte_cdk-1.0.0-py3-none-any.whl", hash = "sha256:74cd8d4f9790b9a164731c42236cb015166b5ab2b0754b6a1fd730f223eb4e7f"}, - {file = "airbyte_cdk-1.0.0.tar.gz", hash = "sha256:102b75ce589460be4f75dabd3402ac7aa633c90758558c81d140fd436b76371f"}, -] - -[package.dependencies] -airbyte-protocol-models = ">=0.9.0,<1.0" -backoff = "*" -cachetools = "*" -cryptography = ">=42.0.5,<43.0.0" -Deprecated = ">=1.2,<1.3" -dpath = ">=2.0.1,<2.1.0" -genson = "1.2.2" -isodate = ">=0.6.1,<0.7.0" -Jinja2 = ">=3.1.2,<3.2.0" -jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" -langchain_core = "0.1.42" -pendulum = "<3.0.0" -pydantic = ">=1.10.8,<2.0.0" -pyjwt = ">=2.8.0,<3.0.0" -pyrate-limiter = ">=3.1.0,<3.2.0" -python-dateutil = "*" -pytz = "2024.1" -PyYAML = ">=6.0.1,<7.0.0" -requests = "*" -requests_cache = "*" -wcmatch = "8.4" - -[package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] - -[[package]] -name = "airbyte-protocol-models" -version = "0.13.0" -description = "Declares the Airbyte Protocol." -optional = false -python-versions = ">=3.8" -files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, -] - -[package.dependencies] -pydantic = ">=1.9.2,<2.0.0" - -[[package]] -name = "anyio" -version = "4.6.2.post1" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.9" -files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, -] - -[package.dependencies] -exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} - -[package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] -trio = ["trio (>=0.26.1)"] - -[[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, -] - -[[package]] -name = "attrs" -version = "24.2.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" -files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, -] - -[package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] - -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "bracex" -version = "2.5.post1" -description = "Bash style brace expander." -optional = false -python-versions = ">=3.8" -files = [ - {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, - {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, -] - -[[package]] -name = "cachetools" -version = "5.5.0" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, - {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, -] - -[[package]] -name = "cattrs" -version = "24.1.2" -description = "Composable complex class support for attrs and dataclasses." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, - {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, -] - -[package.dependencies] -attrs = ">=23.1.0" -exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} - -[package.extras] -bson = ["pymongo (>=4.4.0)"] -cbor2 = ["cbor2 (>=5.4.6)"] -msgpack = ["msgpack (>=1.0.5)"] -msgspec = ["msgspec (>=0.18.5)"] -orjson = ["orjson (>=3.9.2)"] -pyyaml = ["pyyaml (>=6.0)"] -tomlkit = ["tomlkit (>=0.11.8)"] -ujson = ["ujson (>=5.7.0)"] - -[[package]] -name = "certifi" -version = "2024.8.30" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, -] - -[[package]] -name = "cffi" -version = "1.17.1" -description = "Foreign Function Interface for Python calling C code." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, - {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, - {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, - {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, - {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, - {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, - {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, - {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, - {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, - {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, - {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, - {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, - {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, - {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, - {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, - {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, -] - -[package.dependencies] -pycparser = "*" - -[[package]] -name = "charset-normalizer" -version = "3.4.0" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -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 = "cryptography" -version = "42.0.8" -description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -optional = false -python-versions = ">=3.7" -files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, -] - -[package.dependencies] -cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} - -[package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] -docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] -nox = ["nox"] -pep8test = ["check-sdist", "click", "mypy", "ruff"] -sdist = ["build"] -ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] -test-randomorder = ["pytest-randomly"] - -[[package]] -name = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - -[[package]] -name = "dpath" -version = "2.0.8" -description = "Filesystem-like pathing and searching for dictionaries" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dpath-2.0.8-py3-none-any.whl", hash = "sha256:f92f595214dd93a00558d75d4b858beee519f4cffca87f02616ad6cd013f3436"}, - {file = "dpath-2.0.8.tar.gz", hash = "sha256:a3440157ebe80d0a3ad794f1b61c571bef125214800ffdb9afc9424e8250fe9b"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "genson" -version = "1.2.2" -description = "GenSON is a powerful, user-friendly JSON Schema generator." -optional = false -python-versions = "*" -files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, -] - -[[package]] -name = "h11" -version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.7" -files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, -] - -[[package]] -name = "httpcore" -version = "1.0.6" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.13,<0.15" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<1.0)"] - -[[package]] -name = "httpx" -version = "0.27.2" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isodate" -version = "0.6.1" -description = "An ISO 8601 date/time/duration parser and formatter" -optional = false -python-versions = "*" -files = [ - {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, - {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "jinja2" -version = "3.1.4" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "jsonpatch" -version = "1.33" -description = "Apply JSON-Patches (RFC 6902)" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" -files = [ - {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, - {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, -] - -[package.dependencies] -jsonpointer = ">=1.9" - -[[package]] -name = "jsonpointer" -version = "3.0.0" -description = "Identify specific nodes in a JSON document (RFC 6901)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, - {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, -] - -[[package]] -name = "jsonref" -version = "0.2" -description = "An implementation of JSON Reference for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonref-0.2-py3-none-any.whl", hash = "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f"}, - {file = "jsonref-0.2.tar.gz", hash = "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697"}, -] - -[[package]] -name = "jsonschema" -version = "3.2.0" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, -] - -[package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" - -[package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] - -[[package]] -name = "langchain-core" -version = "0.1.42" -description = "Building applications with LLMs through composability" -optional = false -python-versions = "<4.0,>=3.8.1" -files = [ - {file = "langchain_core-0.1.42-py3-none-any.whl", hash = "sha256:c5653ffa08a44f740295c157a24c0def4a753333f6a2c41f76bf431cd00be8b5"}, - {file = "langchain_core-0.1.42.tar.gz", hash = "sha256:40751bf60ea5d8e2b2efe65290db434717ee3834870c002e40e2811f09d814e6"}, -] - -[package.dependencies] -jsonpatch = ">=1.33,<2.0" -langsmith = ">=0.1.0,<0.2.0" -packaging = ">=23.2,<24.0" -pydantic = ">=1,<3" -PyYAML = ">=5.3" -tenacity = ">=8.1.0,<9.0.0" - -[package.extras] -extended-testing = ["jinja2 (>=3,<4)"] - -[[package]] -name = "langsmith" -version = "0.1.137" -description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." -optional = false -python-versions = "<4.0,>=3.8.1" -files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, -] - -[package.dependencies] -httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" -pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} -requests = ">=2,<3" -requests-toolbelt = ">=1.0.0,<2.0.0" - -[[package]] -name = "markupsafe" -version = "3.0.2" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -files = [ - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, - {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, -] - -[[package]] -name = "orjson" -version = "3.10.10" -description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" -optional = false -python-versions = ">=3.8" -files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, -] - -[[package]] -name = "packaging" -version = "23.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, -] - -[[package]] -name = "pendulum" -version = "2.1.2" -description = "Python datetimes made easy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, - {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, - {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, - {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, - {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, - {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, - {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, - {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, - {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, - {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, - {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, -] - -[package.dependencies] -python-dateutil = ">=2.6,<3.0" -pytzdata = ">=2020.1" - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] - -[[package]] -name = "pycparser" -version = "2.22" -description = "C parser in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, - {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, -] - -[[package]] -name = "pydantic" -version = "1.10.18" -description = "Data validation and settings management using python type hints" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, -] - -[package.dependencies] -typing-extensions = ">=4.2.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] - -[[package]] -name = "pyjwt" -version = "2.9.0" -description = "JSON Web Token implementation in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, -] - -[package.extras] -crypto = ["cryptography (>=3.4.0)"] -dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] -docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] -tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] - -[[package]] -name = "pyrate-limiter" -version = "3.1.1" -description = "Python Rate-Limiter using Leaky-Bucket Algorithm" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, - {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, -] - -[package.extras] -all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] -docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] - -[[package]] -name = "pyrsistent" -version = "0.20.0" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7"}, - {file = "pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee"}, - {file = "pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d"}, - {file = "pyrsistent-0.20.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win32.whl", hash = "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d"}, - {file = "pyrsistent-0.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win32.whl", hash = "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf"}, - {file = "pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b"}, - {file = "pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4"}, -] - -[[package]] -name = "pytest" -version = "6.2.5" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, -] - -[package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] - -[[package]] -name = "pytest-mock" -version = "3.14.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, -] - -[package.dependencies] -pytest = ">=6.2.5" - -[package.extras] -dev = ["pre-commit", "pytest-asyncio", "tox"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytz" -version = "2024.1" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, -] - -[[package]] -name = "pytzdata" -version = "2020.1" -description = "The Olson timezone database for Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, - {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-cache" -version = "1.2.1" -description = "A persistent cache for python requests" -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, - {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, -] - -[package.dependencies] -attrs = ">=21.2" -cattrs = ">=22.2" -platformdirs = ">=2.5" -requests = ">=2.22" -url-normalize = ">=1.4" -urllib3 = ">=1.25.5" - -[package.extras] -all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] -bson = ["bson (>=0.5)"] -docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] -dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] -json = ["ujson (>=5.4)"] -mongodb = ["pymongo (>=3)"] -redis = ["redis (>=3)"] -security = ["itsdangerous (>=2.0)"] -yaml = ["pyyaml (>=6.0.1)"] - -[[package]] -name = "requests-mock" -version = "1.12.1" -description = "Mock out responses from the requests package" -optional = false -python-versions = ">=3.5" -files = [ - {file = "requests-mock-1.12.1.tar.gz", hash = "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401"}, - {file = "requests_mock-1.12.1-py2.py3-none-any.whl", hash = "sha256:b1e37054004cdd5e56c84454cc7df12b25f90f382159087f4b6915aaeef39563"}, -] - -[package.dependencies] -requests = ">=2.22,<3" - -[package.extras] -fixture = ["fixtures"] - -[[package]] -name = "requests-toolbelt" -version = "1.0.0" -description = "A utility belt for advanced users of python-requests" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, - {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, -] - -[package.dependencies] -requests = ">=2.0.1,<3.0.0" - -[[package]] -name = "setuptools" -version = "75.2.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - -[[package]] -name = "tenacity" -version = "8.5.0" -description = "Retry code until it succeeds" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, - {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, -] - -[package.extras] -doc = ["reno", "sphinx"] -test = ["pytest", "tornado (>=4.5)", "typeguard"] - -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "url-normalize" -version = "1.4.3" -description = "URL normalization for Python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, - {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "urllib3" -version = "2.2.3" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "wcmatch" -version = "8.4" -description = "Wildcard/glob file name matcher." -optional = false -python-versions = ">=3.7" -files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, -] - -[package.dependencies] -bracex = ">=2.1.1" - -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "7837a8e446313e068be6245532d7ddb3a63f70da7bc4c6613d26c3a1443db8e7" diff --git a/airbyte-integrations/connectors/source-bigcommerce/pyproject.toml b/airbyte-integrations/connectors/source-bigcommerce/pyproject.toml deleted file mode 100644 index 1f216916ad60..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/pyproject.toml +++ /dev/null @@ -1,28 +0,0 @@ -[build-system] -requires = [ "poetry-core>=1.0.0",] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -version = "0.2.22" -name = "source-bigcommerce" -description = "Source implementation for Bigcommerce." -authors = [ "Airbyte ",] -license = "MIT" -readme = "README.md" -documentation = "https://docs.airbyte.com/integrations/sources/bigcommerce" -homepage = "https://airbyte.com" -repository = "https://github.com/airbytehq/airbyte" -[[tool.poetry.packages]] -include = "source_bigcommerce" - -[tool.poetry.dependencies] -python = "^3.9,<3.12" -airbyte-cdk = "1.0.0" - -[tool.poetry.scripts] -source-bigcommerce = "source_bigcommerce.run:run" - -[tool.poetry.group.dev.dependencies] -requests-mock = "^1.9.3" -pytest = "^6.2" -pytest-mock = "^3.6.1" diff --git a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/__init__.py b/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/__init__.py deleted file mode 100644 index 2a85736c808d..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from .source import SourceBigcommerce - -__all__ = ["SourceBigcommerce"] diff --git a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/components.py b/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/components.py deleted file mode 100644 index d9cdab67a57d..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/components.py +++ /dev/null @@ -1,29 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import dataclass -from typing import Optional - -import dpath.util -import pendulum -from airbyte_cdk.sources.declarative.transformations.add_fields import AddFields -from airbyte_cdk.sources.declarative.types import Config, Record, StreamSlice, StreamState - - -@dataclass -class DateTimeTransformer(AddFields): - def transform( - self, - record: Record, - config: Optional[Config] = None, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - ) -> Record: - - kwargs = {"record": record, "stream_state": stream_state, "stream_slice": stream_slice} - for parsed_field in self._parsed_fields: - date_time = parsed_field.value.eval(config, **kwargs) - new_date_time = str(pendulum.from_format(date_time, "ddd, D MMM YYYY HH:mm:ss ZZ")) - dpath.util.new(record, parsed_field.path, new_date_time) - return record diff --git a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/manifest.yaml b/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/manifest.yaml deleted file mode 100644 index 4b06dd2f882f..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/manifest.yaml +++ /dev/null @@ -1,338 +0,0 @@ -version: 0.50.2 -type: DeclarativeSource - -check: - type: CheckStream - stream_names: - - customers - -definitions: - selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - inject_into: request_parameter - field_name: limit - type: RequestOption - pagination_strategy: - type: PageIncrement - start_from_page: 1 - page_size: 250 - date_modified_incremental_sync: - type: DatetimeBasedCursor - cursor_field: date_modified - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%SZ" - - "%Y-%m-%dT%H:%M:%S+00:00" - datetime_format: "%Y-%m-%d" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%d" - start_time_option: - inject_into: request_parameter - field_name: date_modified:min - type: RequestOption - end_datetime: - type: MinMaxDatetime - datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - base_id_incremental_sync: - type: DatetimeBasedCursor - cursor_field: id - cursor_datetime_formats: - - "%s" - datetime_format: "%Y-%m-%d" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%d" - end_datetime: - type: MinMaxDatetime - datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - id_incremental_sync: - $ref: "#/definitions/base_id_incremental_sync" - start_time_option: - type: RequestOption - field_name: date_modified:min - inject_into: request_parameter - order_id_partition_router: - - type: SubstreamPartitionRouter - parent_stream_configs: - - type: ParentStreamConfig - parent_key: id - partition_field: order_id - stream: - $ref: "#/definitions/orders_stream" - requester: - type: HttpRequester - url_base: https://api.bigcommerce.com/stores/{{ config["store_hash"] }}/ - http_method: GET - request_headers: - Accept: application/json - Content-Type: application/json - authenticator: - type: ApiKeyAuthenticator - api_token: '{{ config["access_token"] }}' - inject_into: - type: RequestOption - inject_into: header - field_name: X-Auth-Token - request_body_json: {} - customers_stream: - type: DeclarativeStream - name: customers - primary_key: "id" - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: v3/customers - request_parameters: - sort: date_modified:asc - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator" - incremental_sync: - $ref: "#/definitions/date_modified_incremental_sync" - orders_stream: - type: DeclarativeStream - name: orders - primary_key: "id" - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: v2/orders - request_parameters: - sort: date_modified:asc - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: [] - paginator: - $ref: "#/definitions/paginator" - incremental_sync: - type: DatetimeBasedCursor - cursor_field: date_modified - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%SZ" - - "%Y-%m-%dT%H:%M:%S+00:00" - datetime_format: "%Y-%m-%d" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%d" - start_time_option: - inject_into: request_parameter - field_name: min_date_modified - type: RequestOption - end_datetime: - type: MinMaxDatetime - datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - transformations: - - type: CustomTransformation - class_name: source_bigcommerce.components.DateTimeTransformer - fields: - - path: - - date_modified - value: "{{ record.date_modified }}" - transactions_stream: - type: DeclarativeStream - name: transactions - primary_key: "id" - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: v2/orders/{{ stream_partition.order_id }}/transactions - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator" - partition_router: - $ref: "#/definitions/order_id_partition_router" - incremental_sync: - $ref: "#/definitions/id_incremental_sync" - pages_stream: - type: DeclarativeStream - name: pages - primary_key: "id" - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: v3/content/pages - request_parameters: - sort: date_modified:asc - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator" - incremental_sync: - $ref: "#/definitions/id_incremental_sync" - products_stream: - type: DeclarativeStream - name: products - primary_key: "id" - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: v3/catalog/products - request_parameters: - sort: date_modified - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator" - incremental_sync: - $ref: "#/definitions/date_modified_incremental_sync" - channels_stream: - type: DeclarativeStream - name: channels - primary_key: "id" - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: /v3/channels - request_parameters: - sort: date_modified - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator" - incremental_sync: - $ref: "#/definitions/date_modified_incremental_sync" - store_stream: - type: DeclarativeStream - name: store - primary_key: "id" - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: v2/store - request_parameters: - sort: date_modified:asc - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: [] - paginator: - $ref: "#/definitions/paginator" - order_products_stream: - type: DeclarativeStream - name: order_products - primary_key: "id" - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: v2/orders/{{ stream_partition.order_id }}/products - request_parameters: - sort: date_modified:asc - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: [] - paginator: - $ref: "#/definitions/paginator" - partition_router: - $ref: "#/definitions/order_id_partition_router" - incremental_sync: - $ref: "#/definitions/base_id_incremental_sync" - brands_stream: - type: DeclarativeStream - name: brands - primary_key: "id" - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: v3/catalog/brands - request_parameters: - sort: id - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator" - incremental_sync: - $ref: "#/definitions/base_id_incremental_sync" - categories_stream: - type: DeclarativeStream - name: categories - primary_key: "id" - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: v3/catalog/categories - request_parameters: - sort: id - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator" - incremental_sync: - $ref: "#/definitions/base_id_incremental_sync" - -streams: - - "#/definitions/customers_stream" - - "#/definitions/orders_stream" - - "#/definitions/transactions_stream" - - "#/definitions/pages_stream" - - "#/definitions/products_stream" - - "#/definitions/channels_stream" - - "#/definitions/store_stream" - - "#/definitions/order_products_stream" - - "#/definitions/brands_stream" - - "#/definitions/categories_stream" - -spec: - documentation_url: https://docs.airbyte.com/integrations/sources/bigcommerce - type: Spec - connection_specification: - additionalProperties: true - $schema: http://json-schema.org/draft-07/schema# - type: object - required: - - start_date - - access_token - - store_hash - properties: - start_date: - type: string - title: Start date - description: "The date you would like to replicate data. Format: YYYY-MM-DD." - examples: ["2021-01-01"] - pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ - order: 0 - access_token: - type: string - title: Access Token - description: "Access Token for making authenticated requests." - airbyte_secret: true - order: 1 - store_hash: - title: Store Hash - description: >- - The hash code of the store. For https://api.bigcommerce.com/stores/HASH_CODE/v3/, The store's hash code is 'HASH_CODE'. - type: string - order: 2 diff --git a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/run.py b/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/run.py deleted file mode 100644 index 7e5234a1b2b1..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/run.py +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import sys - -from airbyte_cdk.entrypoint import launch -from source_bigcommerce import SourceBigcommerce - - -def run(): - source = SourceBigcommerce() - launch(source, sys.argv[1:]) diff --git a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/brands.json b/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/brands.json deleted file mode 100644 index 38170334d2b8..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/brands.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "id": { - "type": ["null", "integer"] - }, - "name": { - "type": ["null", "string"] - }, - "page_title": { - "type": ["null", "string"] - }, - "meta_keywords": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "meta_description": { - "type": ["null", "string"] - }, - "search_keywords": { - "type": ["null", "string"] - }, - "image_url": { - "type": ["null", "string"] - }, - "custom_url": { - "type": ["null", "object"], - "properties": { - "url": { - "type": ["null", "string"] - }, - "is_customized": { - "type": ["null", "boolean"] - } - } - } - } -} diff --git a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/categories.json b/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/categories.json deleted file mode 100644 index 6b26ee372e55..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/categories.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "additionalProperties": true, - "properties": { - "id": { - "type": ["null", "integer"] - }, - "parent_id": { - "type": ["null", "integer"] - }, - "name": { - "type": ["null", "string"] - }, - "description": { - "type": ["null", "string"] - }, - "views": { - "type": ["null", "integer"] - }, - "sort_order": { - "type": ["null", "integer"] - }, - "page_title": { - "type": ["null", "string"] - }, - "meta_keywords": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "meta_description": { - "type": ["null", "string"] - }, - "layout_file": { - "type": ["null", "string"] - }, - "image_url": { - "type": ["null", "string"] - }, - "is_visible": { - "type": ["null", "boolean"] - }, - "search_keywords": { - "type": ["null", "string"] - }, - "default_product_sort": { - "type": ["null", "string"] - }, - "custom_url": { - "type": ["null", "object"], - "properties": { - "path": { - "type": ["null", "string"] - }, - "is_customized": { - "type": ["null", "boolean"] - } - } - } - } -} diff --git a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/channels.json b/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/channels.json deleted file mode 100644 index 78e6edc8221e..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/channels.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "id": { - "type": ["null", "integer"] - }, - "external_id": { - "type": ["null", "string"] - }, - "is_listable_from_ui": { - "type": ["null", "boolean"] - }, - "is_visible": { - "type": ["null", "boolean"] - }, - "status": { - "type": ["null", "string"] - }, - "name": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "string"] - }, - "platform": { - "type": ["null", "string"] - }, - "date_created": { - "type": ["null", "string"], - "format": "date-time" - }, - "date_modified": { - "type": ["null", "string"], - "format": "date-time" - }, - "icon_url": { - "type": ["null", "string"] - }, - "is_enabled": { - "type": ["null", "boolean"] - } - } -} diff --git a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/customers.json b/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/customers.json deleted file mode 100644 index e00906cff851..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/customers.json +++ /dev/null @@ -1,171 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "additionalProperties": true, - "properties": { - "email": { - "type": ["null", "string"] - }, - "first_name": { - "type": ["null", "string"] - }, - "last_name": { - "type": ["null", "string"] - }, - "company": { - "type": ["null", "string"] - }, - "phone": { - "type": ["null", "string"] - }, - "registration_ip_address": { - "type": ["null", "string"] - }, - "notes": { - "type": ["null", "string"] - }, - "tax_exempt_category": { - "type": ["null", "string"] - }, - "customer_group_id": { - "type": ["null", "integer"] - }, - "id": { - "type": ["null", "integer"] - }, - "date_modified": { - "type": ["null", "string"], - "format": "date-time" - }, - "date_created": { - "type": ["null", "string"], - "format": "date-time" - }, - "address_count": { - "type": ["null", "integer"] - }, - "attribute_count": { - "type": ["null", "integer"] - }, - "authentication": { - "type": ["null", "object"], - "properties": { - "force_password_reset": { - "type": ["null", "boolean"] - } - } - }, - "addresses": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "additionalProperties": true, - "properties": { - "first_name": { - "type": ["null", "string"] - }, - "last_name": { - "type": ["null", "string"] - }, - "company": { - "type": ["null", "string"] - }, - "address1": { - "type": ["null", "string"] - }, - "address2": { - "type": ["null", "string"] - }, - "city": { - "type": ["null", "string"] - }, - "state_or_province": { - "type": ["null", "string"] - }, - "postal_code": { - "type": ["null", "string"] - }, - "country_code": { - "type": ["null", "string"] - }, - "phone": { - "type": ["null", "string"] - }, - "address_type": { - "type": ["null", "string"] - }, - "customer_id": { - "type": ["null", "integer"] - }, - "id": { - "type": ["null", "integer"] - }, - "country": { - "type": ["null", "string"] - }, - "form_fields": { - "type": ["null", "array"], - "oneOf": [ - { - "type": ["null", "object"], - "properties": { - "name": { - "type": ["null", "string"] - }, - "value": { - "oneOf": [ - { "type": ["null", "string"] }, - { "type": ["null", "integer"] }, - { "type": ["null", "array"] } - ] - }, - "customer_id": { - "type": ["null", "integer"] - } - } - }, - { - "type": ["null", "object"], - "properties": { - "name": { - "type": ["null", "string"] - }, - "value": { - "oneOf": [ - { "type": ["null", "string"] }, - { "type": ["null", "integer"] }, - { "type": ["null", "array"] } - ] - }, - "address_id": { - "type": ["null", "integer"] - } - } - } - ] - }, - "store_credit_amounts": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "amount": { - "type": ["null", "integer"] - } - } - } - }, - "accepts_product_review_abandoned_cart_emails": { - "type": ["null", "boolean"] - }, - "channel_ids": { - "type": ["null", "array"] - }, - "origin_channel_id": { - "type": ["null", "integer"] - } - } - } - } - } -} diff --git a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/order_products.json b/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/order_products.json deleted file mode 100644 index f2927892c12c..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/order_products.json +++ /dev/null @@ -1,177 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "id": { - "type": ["null", "integer"] - }, - "order_id": { - "type": ["null", "integer"] - }, - "product_id": { - "type": ["null", "integer"] - }, - "variant_id": { - "type": ["null", "integer"] - }, - "order_address_id": { - "type": ["null", "integer"] - }, - "name": { - "type": ["null", "string"] - }, - "name_customer": { - "type": ["null", "string"] - }, - "name_merchant": { - "type": ["null", "string"] - }, - "sku": { - "type": ["null", "string"] - }, - "upc": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "string"] - }, - "base_price": { - "type": ["null", "string"] - }, - "price_ex_tax": { - "type": ["null", "string"] - }, - "price_inc_tax": { - "type": ["null", "string"] - }, - "price_tax": { - "type": ["null", "string"] - }, - "base_total": { - "type": ["null", "string"] - }, - "total_ex_tax": { - "type": ["null", "string"] - }, - "total_inc_tax": { - "type": ["null", "string"] - }, - "total_tax": { - "type": ["null", "string"] - }, - "weight": { - "type": ["null", "string"] - }, - "width": { - "type": ["null", "string"] - }, - "height": { - "type": ["null", "string"] - }, - "depth": { - "type": ["null", "string"] - }, - "quantity": { - "type": ["null", "number"] - }, - "base_cost_price": { - "type": ["null", "string"] - }, - "cost_price_inc_tax": { - "type": ["null", "string"] - }, - "cost_price_ex_tax": { - "type": ["null", "string"] - }, - "cost_price_tax": { - "type": ["null", "string"] - }, - "is_refunded": { - "type": ["null", "boolean"] - }, - "quantity_refunded": { - "type": ["null", "number"] - }, - "refund_amount": { - "type": ["null", "string"] - }, - "return_id": { - "type": ["null", "number"] - }, - "wrapping_id": { - "type": ["null", "string"] - }, - "wrapping_name": { - "type": ["null", "string"] - }, - "base_wrapping_cost": { - "type": ["null", "string"] - }, - "wrapping_cost_ex_tax": { - "type": ["null", "string"] - }, - "wrapping_cost_inc_tax": { - "type": ["null", "string"] - }, - "wrapping_cost_tax": { - "type": ["null", "string"] - }, - "wrapping_message": { - "type": ["null", "string"] - }, - "quantity_shipped": { - "type": ["null", "number"] - }, - "event_name": { - "type": ["null", "string"] - }, - "event_date": { - "type": ["null", "string"] - }, - "fixed_shipping_cost": { - "type": ["null", "string"] - }, - "ebay_item_id": { - "type": ["null", "string"] - }, - "ebay_transaction_id": { - "type": ["null", "string"] - }, - "option_set_id": { - "type": ["null", "integer"] - }, - "parent_order_product_id": { - "type": ["null", "integer"] - }, - "is_bundled_product": { - "type": ["null", "boolean"] - }, - "bin_picking_number": { - "type": ["null", "string"] - }, - "external_id": { - "type": ["null", "string"] - }, - "fulfillment_source": { - "type": ["null", "string"] - }, - "brand": { - "type": ["null", "string"] - }, - "gift_certificate_id": { - "type": ["null", "integer"] - }, - "applied_discounts": { - "type": ["null", "array"] - }, - "applied_discounts": { - "type": ["null", "array"] - }, - "product_options": { - "type": ["null", "array"] - }, - "configurable_fields": { - "type": ["null", "array"] - } - } -} diff --git a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/orders.json b/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/orders.json deleted file mode 100644 index c3743441ffd3..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/orders.json +++ /dev/null @@ -1,271 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "id": { - "type": ["null", "integer"] - }, - "date_modified": { - "type": ["null", "string"], - "format": "date-time" - }, - "date_shipped": { - "type": ["null", "string"], - "format": "date-time" - }, - "cart_id": { - "type": ["null", "string"] - }, - "status": { - "type": ["null", "string"] - }, - "subtotal_tax": { - "type": ["null", "string"] - }, - "shipping_cost_tax": { - "type": ["null", "string"] - }, - "shipping_cost_tax_class_id": { - "type": ["null", "integer"] - }, - "handling_cost_tax": { - "type": ["null", "string"] - }, - "handling_cost_tax_class_id": { - "type": ["null", "integer"] - }, - "wrapping_cost_tax": { - "type": ["null", "string"] - }, - "wrapping_cost_tax_class_id": { - "type": ["null", "integer"] - }, - "payment_status": { - "type": ["null", "string"] - }, - "store_credit_amount": { - "type": ["null", "string"] - }, - "gift_certificate_amount": { - "type": ["null", "string"] - }, - "currency_id": { - "type": ["null", "integer"] - }, - "currency_code": { - "type": ["null", "string"] - }, - "currency_exchange_rate": { - "type": ["null", "string"] - }, - "default_currency_id": { - "type": ["null", "integer"] - }, - "coupon_discount": { - "type": ["null", "string"] - }, - "shipping_address_count": { - "type": ["null", "integer"] - }, - "is_email_opt_in": { - "type": ["null", "boolean"] - }, - "order_source": { - "type": ["null", "string"] - }, - "products": { - "type": ["null", "object"], - "properties": { - "url": { - "type": ["null", "string"] - }, - "resource": { - "type": ["null", "string"] - } - } - }, - "shipping_addresses": { - "type": ["null", "object"], - "properties": { - "url": { - "type": ["null", "string"] - }, - "resource": { - "type": ["null", "string"] - } - } - }, - "coupons": { - "type": ["null", "object"], - "properties": { - "url": { - "type": ["null", "string"] - }, - "resource": { - "type": ["null", "string"] - } - } - }, - "status_id": { - "type": ["null", "integer"] - }, - "base_handling_cost": { - "type": ["null", "string"] - }, - "base_shipping_cost": { - "type": ["null", "string"] - }, - "base_wrapping_cost": { - "oneOf": [{ "type": ["null", "integer"] }, { "type": ["null", "string"] }] - }, - "billing_address": { - "type": ["null", "object"], - "properties": { - "first_name": { - "type": ["null", "string"] - }, - "last_name": { - "type": ["null", "string"] - }, - "company": { - "type": ["null", "string"] - }, - "street_1": { - "type": ["null", "string"] - }, - "street_2": { - "type": ["null", "string"] - }, - "city": { - "type": ["null", "string"] - }, - "state": { - "type": ["null", "string"] - }, - "zip": { - "type": ["null", "string"] - }, - "country": { - "type": ["null", "string"] - }, - "country_iso2": { - "type": ["null", "string"] - }, - "phone": { - "type": ["null", "string"] - }, - "email": { - "type": ["null", "string"] - }, - "form_fields": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "name": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - } - } - } - } - }, - "channel_id": { - "type": ["null", "integer"] - }, - "customer_id": { - "type": ["null", "integer"] - }, - "customer_message": { - "type": ["null", "string"] - }, - "date_created": { - "type": ["null", "string"], - "format": "date-time" - }, - "default_currency_code": { - "type": ["null", "string"] - }, - "discount_amount": { - "type": ["null", "string"] - }, - "ebay_order_id": { - "type": ["null", "string"] - }, - "external_id": { - "type": ["null", "string"] - }, - "external_source": { - "type": ["null", "string"] - }, - "geoip_country": { - "type": ["null", "string"] - }, - "geoip_country_iso2": { - "type": ["null", "string"] - }, - "handling_cost_ex_tax": { - "type": ["null", "string"] - }, - "handling_cost_inc_tax": { - "type": ["null", "string"] - }, - "ip_address": { - "type": ["null", "string"] - }, - "is_deleted": { - "type": ["null", "boolean"] - }, - "items_shipped": { - "type": ["null", "integer"] - }, - "items_total": { - "type": ["null", "integer"] - }, - "order_is_digital": { - "type": ["null", "boolean"] - }, - "payment_method": { - "type": ["null", "string"] - }, - "refunded_amount": { - "type": ["null", "string"] - }, - "shipping_cost_ex_tax": { - "type": ["null", "string"] - }, - "shipping_cost_inc_tax": { - "type": ["null", "string"] - }, - "staff_notes": { - "type": ["null", "string"] - }, - "subtotal_ex_tax": { - "type": ["null", "string"] - }, - "subtotal_inc_tax": { - "type": ["null", "string"] - }, - "tax_provider_id": { - "type": ["null", "string"] - }, - "customer_locale": { - "type": ["null", "string"] - }, - "total_ex_tax": { - "type": ["null", "string"] - }, - "total_inc_tax": { - "type": ["null", "string"] - }, - "wrapping_cost_ex_tax": { - "type": ["null", "string"] - }, - "wrapping_cost_inc_tax": { - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/pages.json b/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/pages.json deleted file mode 100644 index 003984b52eea..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/pages.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "email": { - "type": ["null", "string"] - }, - "meta_title": { - "type": ["null", "string"] - }, - "body": { - "type": ["null", "string"] - }, - "feed": { - "type": ["null", "string"] - }, - "link": { - "type": ["null", "string"] - }, - "contact_fields": { - "type": ["null", "string"] - }, - "meta_keywords": { - "type": ["null", "string"] - }, - "meta_description": { - "type": ["null", "string"] - }, - "search_keywords": { - "type": ["null", "string"] - }, - "url": { - "type": ["null", "string"] - }, - "channel_id": { - "type": ["null", "integer"] - }, - "name": { - "type": ["null", "string"] - }, - "is_visible": { - "type": ["null", "boolean"] - }, - "parent_id": { - "type": ["null", "integer"] - }, - "sort_order": { - "type": ["null", "integer"] - }, - "type": { - "type": ["null", "string"] - }, - "is_homepage": { - "type": ["null", "boolean"] - }, - "is_customers_only": { - "type": ["null", "boolean"] - }, - "id": { - "type": ["null", "integer"] - } - } -} diff --git a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/products.json b/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/products.json deleted file mode 100644 index af01020e9a35..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/products.json +++ /dev/null @@ -1,797 +0,0 @@ -{ - "type": "object", - "title": "Product Response", - "properties": { - "name": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "string"] - }, - "sku": { - "type": ["null", "string"] - }, - "description": { - "type": ["null", "string"] - }, - "weight": { - "type": ["null", "number"], - "format": "float" - }, - "width": { - "type": ["null", "number"], - "format": "float" - }, - "depth": { - "type": ["null", "number"], - "format": "float" - }, - "height": { - "type": ["null", "number"], - "format": "float" - }, - "price": { - "type": ["null", "number"], - "format": "float" - }, - "cost_price": { - "type": ["null", "number"], - "format": "float" - }, - "retail_price": { - "type": ["null", "number"], - "format": "float" - }, - "sale_price": { - "type": ["null", "number"], - "format": "float" - }, - "map_price": { - "type": ["null", "number"] - }, - "tax_class_id": { - "type": ["null", "integer"] - }, - "product_tax_code": { - "type": ["null", "string"] - }, - "categories": { - "type": ["null", "array"], - "items": { - "type": ["null", "integer"] - } - }, - "brand_id": { - "type": ["null", "integer"] - }, - "inventory_level": { - "type": ["null", "integer"] - }, - "inventory_warning_level": { - "type": ["null", "integer"] - }, - "inventory_tracking": { - "type": ["null", "string"] - }, - "fixed_cost_shipping_price": { - "type": ["null", "number"], - "format": "float" - }, - "is_free_shipping": { - "type": ["null", "boolean"] - }, - "is_visible": { - "type": ["null", "boolean"] - }, - "is_featured": { - "type": ["null", "boolean"] - }, - "related_products": { - "type": ["null", "array"], - "items": { - "type": ["null", "integer"] - } - }, - "warranty": { - "type": ["null", "string"] - }, - "bin_picking_number": { - "type": ["null", "string"] - }, - "layout_file": { - "type": ["null", "string"] - }, - "upc": { - "type": ["null", "string"] - }, - "search_keywords": { - "type": ["null", "string"] - }, - "availability": { - "type": ["null", "string"] - }, - "availability_description": { - "type": ["null", "string"] - }, - "gift_wrapping_options_type": { - "type": ["null", "string"] - }, - "gift_wrapping_options_list": { - "type": ["null", "array"], - "items": { - "type": ["null", "integer"] - } - }, - "sort_order": { - "type": ["null", "integer"] - }, - "condition": { - "type": ["null", "string"] - }, - "is_condition_shown": { - "type": ["null", "boolean"] - }, - "order_quantity_minimum": { - "type": ["null", "integer"] - }, - "order_quantity_maximum": { - "type": ["null", "integer"] - }, - "page_title": { - "type": ["null", "string"] - }, - "meta_keywords": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "meta_description": { - "type": ["null", "string"] - }, - "view_count": { - "type": ["null", "integer"] - }, - "preorder_release_date": { - "type": ["null", "string"], - "format": "date-time" - }, - "preorder_message": { - "type": ["null", "string"] - }, - "is_preorder_only": { - "type": ["null", "boolean"] - }, - "is_price_hidden": { - "type": ["null", "boolean"] - }, - "price_hidden_label": { - "type": ["null", "string"] - }, - "custom_url": { - "type": ["null", "object"], - "title": "customUrl_Full", - "properties": { - "url": { - "type": ["null", "string"] - }, - "is_customized": { - "type": ["null", "boolean"] - } - } - }, - "open_graph_type": { - "type": ["null", "string"] - }, - "open_graph_title": { - "type": ["null", "string"] - }, - "open_graph_description": { - "type": ["null", "string"] - }, - "open_graph_use_meta_description": { - "type": ["null", "boolean"] - }, - "open_graph_use_product_name": { - "type": ["null", "boolean"] - }, - "open_graph_use_image": { - "type": ["null", "boolean"] - }, - "brand_name or brand_id": { - "type": ["null", "string"] - }, - "gtin": { - "type": ["null", "string"] - }, - "mpn": { - "type": ["null", "string"] - }, - "reviews_rating_sum": { - "type": ["null", "integer"] - }, - "reviews_count": { - "type": ["null", "integer"] - }, - "total_sold": { - "type": ["null", "integer"] - }, - "custom_fields": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "title": "productCustomField_Put", - "required": ["name", "value"], - "properties": { - "id": { - "type": ["null", "integer"] - }, - "name": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - } - } - }, - "bulk_pricing_rules": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "title": "bulkPricingRule_Full", - "required": ["quantity_min", "quantity_max", "type", "amount"], - "properties": { - "id": { - "type": ["null", "integer"] - }, - "quantity_min": { - "type": ["null", "integer"] - }, - "quantity_max": { - "type": ["null", "integer"] - }, - "type": { - "type": ["null", "string"] - }, - "amount": { - "type": ["null", "integer"] - } - } - } - }, - "images": { - "type": ["null", "array"], - "items": { - "title": "productImage_Full", - "type": ["null", "object"], - "properties": { - "image_file": { - "type": ["null", "string"] - }, - "is_thumbnail": { - "type": ["null", "boolean"] - }, - "sort_order": { - "type": ["null", "integer"] - }, - "description": { - "type": ["null", "string"] - }, - "image_url": { - "type": ["null", "string"] - }, - "id": { - "type": ["null", "integer"] - }, - "product_id": { - "type": ["null", "integer"] - }, - "url_zoom": { - "type": ["null", "string"] - }, - "url_standard": { - "type": ["null", "string"] - }, - "url_thumbnail": { - "type": ["null", "string"] - }, - "url_tiny": { - "type": ["null", "string"] - }, - "date_modified": { - "format": "date-time", - "type": ["null", "string"] - } - } - } - }, - "videos": { - "type": ["null", "array"], - "items": { - "title": "productVideo_Full", - "type": ["null", "object"], - "properties": { - "title": { - "type": ["null", "string"] - }, - "description": { - "type": ["null", "string"] - }, - "sort_order": { - "type": ["null", "integer"] - }, - "type": { - "type": ["null", "string"] - }, - "video_id": { - "type": ["null", "string"] - }, - "id": { - "type": ["null", "integer"] - }, - "product_id": { - "type": ["null", "integer"] - }, - "length": { - "type": ["null", "string"] - } - } - } - }, - "date_created": { - "type": ["null", "string"], - "format": "date-time" - }, - "date_modified": { - "type": ["null", "string"], - "format": "date-time" - }, - "id": { - "type": ["null", "integer"] - }, - "base_variant_id": { - "type": ["null", "integer"] - }, - "calculated_price": { - "type": ["null", "number"], - "format": "float" - }, - "options": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "title": "productOption_Base", - "properties": { - "id": { - "type": ["null", "integer"] - }, - "product_id": { - "type": ["null", "integer"] - }, - "display_name": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "string"] - }, - "config": { - "type": ["null", "object"], - "title": "productOptionConfig_Full", - "properties": { - "default_value": { - "type": ["null", "string"] - }, - "checked_by_default": { - "type": ["null", "boolean"] - }, - "checkbox_label": { - "type": ["null", "string"] - }, - "date_limited": { - "type": ["null", "boolean"] - }, - "date_limit_mode": { - "type": ["null", "string"] - }, - "date_earliest_value": { - "type": ["null", "string"], - "format": "date" - }, - "date_latest_value": { - "type": ["null", "string"], - "format": "date" - }, - "file_types_mode": { - "type": ["null", "string"] - }, - "file_types_supported": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "file_types_other": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "file_max_size": { - "type": ["null", "integer"] - }, - "text_characters_limited": { - "type": ["null", "boolean"] - }, - "text_min_length": { - "type": ["null", "integer"] - }, - "text_max_length": { - "type": ["null", "integer"] - }, - "text_lines_limited": { - "type": ["null", "boolean"] - }, - "text_max_lines": { - "type": ["null", "integer"] - }, - "number_limited": { - "type": ["null", "boolean"] - }, - "number_limit_mode": { - "type": ["null", "string"] - }, - "number_lowest_value": { - "type": ["null", "number"] - }, - "number_highest_value": { - "type": ["null", "number"] - }, - "number_integers_only": { - "type": ["null", "boolean"] - }, - "product_list_adjusts_inventory": { - "type": ["null", "boolean"] - }, - "product_list_adjusts_pricing": { - "type": ["null", "boolean"] - }, - "product_list_shipping_calc": { - "type": ["null", "string"] - } - } - }, - "sort_order": { - "type": ["null", "integer"] - }, - "option_values": { - "title": "productOptionOptionValue_Full", - "type": ["null", "object"], - "required": ["label", "sort_order"], - "properties": { - "is_default": { - "type": ["null", "boolean"] - }, - "label": { - "type": ["null", "string"] - }, - "sort_order": { - "type": ["null", "integer"] - }, - "value_data": { - "type": ["object", "null"] - }, - "id": { - "type": ["null", "integer"] - } - } - } - } - } - }, - "modifiers": { - "type": ["null", "array"], - "items": { - "title": "productModifier_Full", - "type": ["null", "object"], - "required": ["type", "required"], - "properties": { - "type": { - "type": ["null", "string"] - }, - "required": { - "type": ["null", "boolean"] - }, - "sort_order": { - "type": ["null", "integer"] - }, - "config": { - "type": ["null", "object"], - "title": "config_Full", - "properties": { - "default_value": { - "type": ["null", "string"] - }, - "checked_by_default": { - "type": ["null", "boolean"] - }, - "checkbox_label": { - "type": ["null", "string"] - }, - "date_limited": { - "type": ["null", "boolean"] - }, - "date_limit_mode": { - "type": ["null", "string"] - }, - "date_earliest_value": { - "type": ["null", "string"], - "format": "date" - }, - "date_latest_value": { - "type": ["null", "string"], - "format": "date" - }, - "file_types_mode": { - "type": ["null", "string"] - }, - "file_types_supported": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "file_types_other": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "file_max_size": { - "type": ["null", "integer"] - }, - "text_characters_limited": { - "type": ["null", "boolean"] - }, - "text_min_length": { - "type": ["null", "integer"] - }, - "text_max_length": { - "type": ["null", "integer"] - }, - "text_lines_limited": { - "type": ["null", "boolean"] - }, - "text_max_lines": { - "type": ["null", "integer"] - }, - "number_limited": { - "type": ["null", "boolean"] - }, - "number_limit_mode": { - "type": ["null", "string"] - }, - "number_lowest_value": { - "type": ["null", "number"] - }, - "number_highest_value": { - "type": ["null", "number"] - }, - "number_integers_only": { - "type": ["null", "boolean"] - }, - "product_list_adjusts_inventory": { - "type": ["null", "boolean"] - }, - "product_list_adjusts_pricing": { - "type": ["null", "boolean"] - }, - "product_list_shipping_calc": { - "type": ["null", "string"] - } - } - }, - "display_name": { - "type": ["null", "string"] - }, - "id": { - "type": ["null", "integer"] - }, - "product_id": { - "type": ["null", "integer"] - }, - "name": { - "type": ["null", "string"] - }, - "option_values": { - "type": ["null", "array"], - "items": { - "title": "productModifierOptionValue_Full", - "type": ["null", "object"], - "required": ["label", "sort_order"], - "properties": { - "is_default": { - "type": ["null", "boolean"] - }, - "label": { - "type": ["null", "string"] - }, - "sort_order": { - "type": ["null", "integer"] - }, - "value_data": { - "type": ["object", "null"] - }, - "adjusters": { - "type": ["null", "object"], - "title": "adjusters_Full", - "properties": { - "price": { - "type": ["null", "object"], - "title": "adjuster_Full", - "properties": { - "adjuster": { - "type": ["null", "string"] - }, - "adjuster_value": { - "type": ["null", "number"] - } - } - }, - "weight": { - "type": ["null", "object"], - "title": "adjuster_Full", - "properties": { - "adjuster": { - "type": ["null", "string"] - }, - "adjuster_value": { - "type": ["null", "number"] - } - } - }, - "image_url": { - "type": ["null", "string"] - }, - "purchasing_disabled": { - "type": ["null", "object"], - "properties": { - "status": { - "type": ["null", "boolean"] - }, - "message": { - "type": ["null", "string"] - } - } - } - } - }, - "id": { - "type": ["null", "integer"] - }, - "option_id": { - "type": ["null", "integer"] - } - } - } - } - } - } - }, - "option_set_id": { - "type": ["null", "integer"] - }, - "option_set_display": { - "type": ["null", "string"] - }, - "variants": { - "type": ["null", "array"], - "items": { - "title": "productVariant_Full", - "type": ["null", "object"], - "properties": { - "cost_price": { - "type": ["null", "number"], - "format": "double" - }, - "price": { - "type": ["null", "number"], - "format": "double" - }, - "sale_price": { - "type": ["null", "number"], - "format": "double" - }, - "retail_price": { - "type": ["null", "number"], - "format": "double" - }, - "weight": { - "type": ["null", "number"], - "format": "double" - }, - "width": { - "type": ["null", "number"], - "format": "double" - }, - "height": { - "type": ["null", "number"], - "format": "double" - }, - "depth": { - "type": ["null", "number"], - "format": "double" - }, - "is_free_shipping": { - "type": ["null", "boolean"] - }, - "fixed_cost_shipping_price": { - "type": ["null", "number"], - "format": "double" - }, - "purchasing_disabled": { - "type": ["null", "boolean"] - }, - "purchasing_disabled_message": { - "type": ["null", "string"] - }, - "upc": { - "type": ["null", "string"] - }, - "inventory_level": { - "type": ["null", "integer"] - }, - "inventory_warning_level": { - "type": ["null", "integer"] - }, - "bin_picking_number": { - "type": ["null", "string"] - }, - "mpn": { - "type": ["null", "string"] - }, - "id": { - "type": ["null", "integer"] - }, - "product_id": { - "type": ["null", "integer"] - }, - "sku": { - "type": ["null", "string"] - }, - "sku_id": { - "type": ["null", "integer"] - }, - "option_values": { - "type": ["null", "array"], - "items": { - "title": "productVariantOptionValue_Full", - "type": ["null", "object"], - "properties": { - "option_display_name": { - "type": ["null", "string"] - }, - "label": { - "type": ["null", "string"] - }, - "id": { - "type": ["null", "integer"] - }, - "option_id": { - "type": ["null", "integer"] - } - } - } - }, - "calculated_price": { - "type": ["null", "number"], - "format": "double" - }, - "calculated_weight": { - "type": "number" - } - } - } - } - } -} diff --git a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/shared/meta.json b/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/shared/meta.json deleted file mode 100644 index 0622da2f41f4..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/shared/meta.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "pagination": { - "type": ["null", "object"], - "properties": { - "total": { - "type": ["null", "integer"] - }, - "count": { - "type": ["null", "integer"] - }, - "per_page": { - "type": ["null", "integer"] - }, - "current_page": { - "type": ["null", "integer"] - }, - "total_pages": { - "type": ["null", "integer"] - }, - "links": { - "type": ["null", "object"], - "properties": { - "previous": { - "type": ["null", "string"] - }, - "current": { - "type": ["null", "string"] - }, - "next": { - "type": ["null", "string"] - } - } - } - } - } -} diff --git a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/store.json b/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/store.json deleted file mode 100644 index 22a6188fa281..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/store.json +++ /dev/null @@ -1,185 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "id": { - "type": ["null", "string"] - }, - "account_uuid": { - "type": ["null", "string"] - }, - "domain": { - "type": ["null", "string"] - }, - "secure_url": { - "type": ["null", "string"] - }, - "control_panel_base_url": { - "type": ["null", "string"] - }, - "status": { - "type": ["null", "string"] - }, - "name": { - "type": ["null", "string"] - }, - "first_name": { - "type": ["null", "string"] - }, - "last_name": { - "type": ["null", "string"] - }, - "address": { - "type": ["null", "string"] - }, - "country": { - "type": ["null", "string"] - }, - "country_code": { - "type": ["null", "string"] - }, - "phone": { - "type": ["null", "string"] - }, - "admin_email": { - "type": ["null", "string"] - }, - "order_email": { - "type": ["null", "string"] - }, - "favicon_url": { - "type": ["null", "string"] - }, - "timezone": { - "type": ["null", "object"], - "properties": { - "name": { - "type": ["null", "string"] - }, - "raw_offset": { - "type": ["null", "integer"] - }, - "dst_offset": { - "type": ["null", "integer"] - }, - "date_format": { - "type": ["null", "object"], - "properties": { - "display": { - "type": ["null", "string"] - }, - "export": { - "type": ["null", "string"] - }, - "extended_display": { - "type": ["null", "string"] - } - } - } - } - }, - "language": { - "type": ["null", "string"] - }, - "currency": { - "type": ["null", "string"] - }, - "currency_symbol": { - "type": ["null", "string"] - }, - "decimal_separator": { - "type": ["null", "string"] - }, - "thousands_separator": { - "type": ["null", "string"] - }, - "decimal_places": { - "type": ["null", "integer"] - }, - "currency_symbol_location": { - "type": ["null", "string"] - }, - "weight_units": { - "type": ["null", "string"] - }, - "dimension_units": { - "type": ["null", "string"] - }, - "dimension_decimal_places": { - "type": ["null", "integer"] - }, - "dimension_decimal_token": { - "type": ["null", "string"] - }, - "dimension_thousands_token": { - "type": ["null", "string"] - }, - "plan_name": { - "type": ["null", "string"] - }, - "plan_level": { - "type": ["null", "string"] - }, - "plan_is_trial": { - "type": ["null", "boolean"] - }, - "industry": { - "type": ["null", "string"] - }, - "logo": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "url": { - "type": ["null", "string"] - } - } - } - }, - "is_price_entered_with_tax": { - "type": ["null", "boolean"] - }, - "store_id": { - "type": ["null", "integer"] - }, - "default_site_id": { - "type": ["null", "integer"] - }, - "default_channel_id": { - "type": ["null", "integer"] - }, - "active_comparison_modules": { - "type": ["null", "array"] - }, - "features": { - "type": ["null", "object"], - "properties": { - "stencil_enabled": { - "type": ["null", "boolean"] - }, - "sitewidehttps_enabled": { - "type": ["null", "boolean"] - }, - "facebook_catalog_id": { - "type": ["null", "string"] - }, - "checkout_type": { - "type": ["null", "string"] - }, - "wishlists_enabled": { - "type": ["null", "boolean"] - }, - "graphql_storefront_api_enabled": { - "type": ["null", "boolean"] - }, - "shopper_consent_tracking_enabled": { - "type": ["null", "boolean"] - }, - "multi_storefront_enabled": { - "type": ["null", "boolean"] - } - } - } - } -} diff --git a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/transactions.json b/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/transactions.json deleted file mode 100644 index c2731c2cc44d..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/schemas/transactions.json +++ /dev/null @@ -1,143 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "event": { - "type": ["null", "string"] - }, - "method": { - "type": ["null", "string"] - }, - "amount": { - "type": ["null", "number"] - }, - "currency": { - "type": ["null", "string"] - }, - "gateway": { - "type": ["null", "string"] - }, - "gateway_transaction_id": { - "type": ["null", "string"] - }, - "date_created": { - "type": ["null", "string"] - }, - "test": { - "type": ["null", "boolean"] - }, - "status": { - "type": ["null", "string"] - }, - "fraud_review": { - "type": ["null", "boolean"] - }, - "reference_transaction_id": { - "type": ["null", "integer"] - }, - "offline": { - "type": ["null", "object"], - "properties": { - "display_name": { - "type": ["null", "string"] - } - } - }, - "custom": { - "type": ["null", "object"], - "properties": { - "payment_method": { - "type": ["null", "string"] - } - } - }, - "payment_method_id": { - "type": ["null", "string"] - }, - "id": { - "type": ["null", "integer"] - }, - "order_id": { - "type": ["null", "string"] - }, - "payment_instrument_token": { - "type": ["null", "string"] - }, - "avs_result": { - "type": ["null", "object"], - "properties": { - "code": { - "type": ["null", "string"] - }, - "message": { - "type": ["null", "string"] - }, - "street_match": { - "type": ["null", "string"] - }, - "postal_match": { - "type": ["null", "string"] - } - } - }, - "cvv_result": { - "type": ["null", "object"], - "properties": { - "code": { - "type": ["null", "string"] - }, - "message": { - "type": ["null", "string"] - } - } - }, - "credit_card": { - "type": ["null", "object"], - "properties": { - "card_type": { - "type": ["null", "string"] - }, - "card_iin": { - "type": ["null", "string"] - }, - "card_last4": { - "type": ["null", "string"] - }, - "card_expiry_month": { - "type": ["null", "integer"] - }, - "card_expiry_year": { - "type": ["null", "integer"] - } - } - }, - "gift_certificate": { - "type": ["null", "object"], - "properties": { - "code": { - "type": ["null", "string"] - }, - "original_balance": { - "type": ["null", "integer"] - }, - "starting_balance": { - "type": ["null", "integer"] - }, - "remaining_balance": { - "type": ["null", "integer"] - }, - "status": { - "type": ["null", "string"] - } - } - }, - "store_credit": { - "type": ["null", "object"], - "properties": { - "remaining_balance": { - "type": ["null", "integer"] - } - } - } - } -} diff --git a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/source.py b/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/source.py deleted file mode 100644 index 997d0eb20418..000000000000 --- a/airbyte-integrations/connectors/source-bigcommerce/source_bigcommerce/source.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource - -""" -This file provides the necessary constructs to interpret a provided declarative YAML configuration file into -source connector. - -WARNING: Do not modify this file. -""" - - -# Declarative Source -class SourceBigcommerce(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-bigmailer/README.md b/airbyte-integrations/connectors/source-bigmailer/README.md new file mode 100644 index 000000000000..0541756002c8 --- /dev/null +++ b/airbyte-integrations/connectors/source-bigmailer/README.md @@ -0,0 +1,33 @@ +# BigMailer +This directory contains the manifest-only connector for `source-bigmailer`. + +An Airbyte connector for [BigMailer](https://bigmailer.com) would facilitate seamless data syncing between BigMailer and other platforms. This connector would allow users to pull data from BigMailer, such as *brands*, *contacts*, *lists*, *fields*, *message types*, *segments*, *bulk campaigns*, *transactional campaigns*, *suppression lists*, and *users*, into various data destinations for further analysis, reporting, or automation tasks. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-bigmailer:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-bigmailer build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-bigmailer test +``` + diff --git a/airbyte-integrations/connectors/source-bigmailer/acceptance-test-config.yml b/airbyte-integrations/connectors/source-bigmailer/acceptance-test-config.yml new file mode 100644 index 000000000000..502f2a992b12 --- /dev/null +++ b/airbyte-integrations/connectors/source-bigmailer/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-bigmailer:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-bigmailer/icon.svg b/airbyte-integrations/connectors/source-bigmailer/icon.svg new file mode 100644 index 000000000000..ecbedd081963 --- /dev/null +++ b/airbyte-integrations/connectors/source-bigmailer/icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/airbyte-integrations/connectors/source-bigmailer/manifest.yaml b/airbyte-integrations/connectors/source-bigmailer/manifest.yaml new file mode 100644 index 000000000000..61e5ccd1282b --- /dev/null +++ b/airbyte-integrations/connectors/source-bigmailer/manifest.yaml @@ -0,0 +1,977 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + An Airbyte connector for [BigMailer](https://bigmailer.com) would facilitate + seamless data syncing between BigMailer and other platforms. This connector + would allow users to pull data from BigMailer, such as *brands*, *contacts*, + *lists*, *fields*, *message types*, *segments*, *bulk campaigns*, + *transactional campaigns*, *suppression lists*, and *users*, into various data + destinations for further analysis, reporting, or automation tasks. + +check: + type: CheckStream + stream_names: + - brands + +definitions: + streams: + brands: + type: DeclarativeStream + name: brands + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /brands + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('cursor', '') }}" + stop_condition: "{{ not response.get('has_more', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/brands" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /brands/{{ stream_partition.brand_id }}/contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('cursor', '') }}" + stop_condition: "{{ not response.get('has_more', False) }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: brand_id + stream: + $ref: "#/definitions/streams/brands" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + lists: + type: DeclarativeStream + name: lists + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /brands/{{ stream_partition.brand_id }}/lists + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('cursor', '') }}" + stop_condition: "{{ not response.get('has_more', False) }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: brand_id + stream: + $ref: "#/definitions/streams/brands" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/lists" + fields: + type: DeclarativeStream + name: fields + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /brands/{{ stream_partition.brand_id }}/fields + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('cursor', '') }}" + stop_condition: "{{ not response.get('has_more', False) }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: brand_id + stream: + $ref: "#/definitions/streams/brands" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/fields" + message-types: + type: DeclarativeStream + name: message-types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /brands/{{ stream_partition.brand_id }}/message-types + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('cursor', '') }}" + stop_condition: "{{ not response.get('has_more', False) }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: brand_id + stream: + $ref: "#/definitions/streams/brands" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/message-types" + segments: + type: DeclarativeStream + name: segments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /brands/{{ stream_partition.brand_id }}/segments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('cursor', '') }}" + stop_condition: "{{ not response.get('has_more', False) }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: brand_id + stream: + $ref: "#/definitions/streams/brands" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/segments" + bulk_campaigns: + type: DeclarativeStream + name: bulk_campaigns + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /brands/{{ stream_partition.brand_id }}/bulk-campaigns + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('cursor', '') }}" + stop_condition: "{{ not response.get('has_more', False) }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: brand_id + stream: + $ref: "#/definitions/streams/brands" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/bulk_campaigns" + transactional_campaigns: + type: DeclarativeStream + name: transactional_campaigns + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /brands/{{ stream_partition.brand_id }}/transactional-campaigns + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('cursor', '') }}" + stop_condition: "{{ not response.get('has_more', False) }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: brand_id + stream: + $ref: "#/definitions/streams/brands" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/transactional_campaigns" + suppression_lists: + type: DeclarativeStream + name: suppression_lists + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /brands/{{ stream_partition.brand_id }}/suppression-lists + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('cursor', '') }}" + stop_condition: "{{ not response.get('has_more', False) }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: brand_id + stream: + $ref: "#/definitions/streams/brands" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/suppression_lists" + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('cursor', '') }}" + stop_condition: "{{ not response.get('has_more', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + base_requester: + type: HttpRequester + url_base: https://api.bigmailer.io/v1 + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: X-API-Key + inject_into: header + +streams: + - $ref: "#/definitions/streams/brands" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/lists" + - $ref: "#/definitions/streams/fields" + - $ref: "#/definitions/streams/message-types" + - $ref: "#/definitions/streams/segments" + - $ref: "#/definitions/streams/bulk_campaigns" + - $ref: "#/definitions/streams/transactional_campaigns" + - $ref: "#/definitions/streams/suppression_lists" + - $ref: "#/definitions/streams/users" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + description: >- + API key to use. You can create and find it on the API key management + page in your BigMailer account. + name: api_key + order: 0 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + brands: true + contacts: true + lists: true + fields: true + message-types: true + segments: true + bulk_campaigns: true + transactional_campaigns: true + suppression_lists: true + users: true + testedStreams: + brands: + streamHash: 55c29f943e68dc5dff935fe26623f131fb4f4eb6 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contacts: + streamHash: a6822ab2e7c5a5da030ad2d1aa45907a7d2072bb + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + lists: + streamHash: b896f46fb8da0aa924e9b14e63d78e0b16ede7c0 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + fields: + streamHash: d8ee861c6ca035d717e3b809957174336876c5fa + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + message-types: + hasRecords: true + streamHash: e83fee5a4acef42f947ae6b5959e7c87b025bcb2 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + segments: + hasRecords: true + streamHash: a5bfb006da5f17e9d66ed11846f380d8ba54e16e + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + bulk_campaigns: + hasRecords: true + streamHash: e6b6776d2575c2c3bb6438e2c6af2c23c092fad1 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + transactional_campaigns: + hasRecords: true + streamHash: 0eeefd74a73a84f929d9c06696eda5b8c5c9f26a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + suppression_lists: + hasRecords: true + streamHash: db2854f007e416bd229cf0ed400d912bdfd5fb80 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + users: + hasRecords: true + streamHash: 43d2365a28f857145e25f2af5c7e2e6d6ea39a32 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://docs.bigmailer.io/reference + +schemas: + brands: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + bounce_danger_percent: + type: + - number + - "null" + created: + type: + - number + - "null" + filter_soft_bounces: + type: + - boolean + - "null" + from_email: + type: + - string + - "null" + from_name: + type: + - string + - "null" + id: + type: string + max_soft_bounces: + type: + - number + - "null" + name: + type: + - string + - "null" + required: + - id + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + brand_id: + type: + - string + - "null" + created: + type: + - number + - "null" + email: + type: + - string + - "null" + field_values: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + string: + type: + - string + - "null" + id: + type: string + list_ids: + type: + - array + - "null" + items: + type: + - string + - "null" + num_complaints: + type: + - number + - "null" + num_hard_bounces: + type: + - number + - "null" + num_soft_bounces: + type: + - number + - "null" + unsubscribe_all: + type: + - boolean + - "null" + unsubscribe_ids: + type: + - array + - "null" + required: + - id + lists: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + all: + type: + - boolean + - "null" + created: + type: + - number + - "null" + id: + type: string + name: + type: + - string + - "null" + required: + - id + fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + created: + type: + - number + - "null" + id: + type: string + merge_tag_name: + type: + - string + - "null" + name: + type: + - string + - "null" + required: + - id + message-types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + created: + type: + - number + - "null" + id: + type: string + name: + type: + - string + - "null" + required: + - id + segments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created: + type: + - number + - "null" + id: + type: string + name: + type: + - string + - "null" + required: + - id + bulk_campaigns: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created: + type: + - number + - "null" + id: + type: string + message_type_id: + type: + - string + - "null" + name: + type: + - string + - "null" + num_clicks: + type: + - number + - "null" + num_complaints: + type: + - number + - "null" + num_hard_bounces: + type: + - number + - "null" + num_opens: + type: + - number + - "null" + num_rejected: + type: + - number + - "null" + num_sent: + type: + - number + - "null" + num_soft_bounces: + type: + - number + - "null" + num_total_clicks: + type: + - number + - "null" + num_total_opens: + type: + - number + - "null" + num_unsubscribes: + type: + - number + - "null" + preview: + type: + - string + - "null" + status: + type: + - string + - "null" + subject: + type: + - string + - "null" + throttling_type: + type: + - string + - "null" + track_clicks: + type: + - boolean + - "null" + track_opens: + type: + - boolean + - "null" + track_text_clicks: + type: + - boolean + - "null" + required: + - id + transactional_campaigns: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created: + type: + - number + - "null" + id: + type: string + list_id: + type: + - string + - "null" + message_type_id: + type: + - string + - "null" + name: + type: + - string + - "null" + num_clicks: + type: + - number + - "null" + num_complaints: + type: + - number + - "null" + num_hard_bounces: + type: + - number + - "null" + num_opens: + type: + - number + - "null" + num_rejected: + type: + - number + - "null" + num_sent: + type: + - number + - "null" + num_soft_bounces: + type: + - number + - "null" + num_total_clicks: + type: + - number + - "null" + num_total_opens: + type: + - number + - "null" + num_unsubscribes: + type: + - number + - "null" + status: + type: + - string + - "null" + track_clicks: + type: + - boolean + - "null" + track_opens: + type: + - boolean + - "null" + track_text_clicks: + type: + - boolean + - "null" + required: + - id + suppression_lists: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created: + type: + - number + - "null" + file_name: + type: + - string + - "null" + file_size: + type: + - number + - "null" + id: + type: + - string + - "null" + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created: + type: + - number + - "null" + email: + type: + - string + - "null" + id: + type: string + is_activated: + type: + - boolean + - "null" + is_owner: + type: + - boolean + - "null" + role: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-bigmailer/metadata.yaml b/airbyte-integrations/connectors/source-bigmailer/metadata.yaml new file mode 100644 index 000000000000..e8e603f813f6 --- /dev/null +++ b/airbyte-integrations/connectors/source-bigmailer/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.bigmailer.io" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-bigmailer + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: c448df04-e5ce-43e0-85cb-a4cfff936c3d + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-bigmailer + githubIssueLabel: source-bigmailer + icon: icon.svg + license: MIT + name: BigMailer + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/bigmailer + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-bigquery/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-bigquery/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-bigquery/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-bigquery/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-bigquery/metadata.yaml b/airbyte-integrations/connectors/source-bigquery/metadata.yaml index cf094810d241..ba58493d9388 100644 --- a/airbyte-integrations/connectors/source-bigquery/metadata.yaml +++ b/airbyte-integrations/connectors/source-bigquery/metadata.yaml @@ -2,10 +2,26 @@ data: ab_internal: ql: 200 sl: 100 + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a connectorSubtype: database + connectorTestSuitesOptions: + - suite: unitTests + - suite: integrationTests + testSecrets: + - fileName: credentials.json + name: SECRET_SOURCE-BIGQUERY_CREDENTIALS__CREDS + secretStore: + alias: airbyte-connector-testing-secret-store + type: GSM + - fileName: sat-config.json + name: SECRET_SOURCE-BIGQUERY_SAT__CREDS + secretStore: + alias: airbyte-connector-testing-secret-store + type: GSM connectorType: source definitionId: bfd1ddf8-ae8a-4620-b1d7-55597d2ba08c - dockerImageTag: 0.4.2 + dockerImageTag: 0.4.3 dockerRepository: airbyte/source-bigquery documentationUrl: https://docs.airbyte.com/integrations/sources/bigquery githubIssueLabel: source-bigquery @@ -21,18 +37,4 @@ data: supportLevel: community tags: - language:java - connectorTestSuitesOptions: - - suite: unitTests - - suite: integrationTests - testSecrets: - - name: SECRET_SOURCE-BIGQUERY_CREDENTIALS__CREDS - fileName: credentials.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store - - name: SECRET_SOURCE-BIGQUERY_SAT__CREDS - fileName: sat-config.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-bing-ads/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-bing-ads/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-bing-ads/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-bing-ads/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-bing-ads/main.py b/airbyte-integrations/connectors/source-bing-ads/main.py index c05297b01ad8..dfb7775f3071 100644 --- a/airbyte-integrations/connectors/source-bing-ads/main.py +++ b/airbyte-integrations/connectors/source-bing-ads/main.py @@ -4,5 +4,6 @@ from source_bing_ads.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-bing-ads/metadata.yaml b/airbyte-integrations/connectors/source-bing-ads/metadata.yaml index c9593fe72124..14aaacfabc15 100644 --- a/airbyte-integrations/connectors/source-bing-ads/metadata.yaml +++ b/airbyte-integrations/connectors/source-bing-ads/metadata.yaml @@ -12,11 +12,11 @@ data: - api.ads.microsoft.com - clientcenter.api.bingads.microsoft.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 47f25999-dd5e-4636-8c39-e7cea2453331 - dockerImageTag: 2.8.2 + dockerImageTag: 2.8.8 dockerRepository: airbyte/source-bing-ads documentationUrl: https://docs.airbyte.com/integrations/sources/bing-ads erdUrl: https://dbdocs.io/airbyteio/source-bing-ads?view=relationships diff --git a/airbyte-integrations/connectors/source-bing-ads/poetry.lock b/airbyte-integrations/connectors/source-bing-ads/poetry.lock index 031cb250f54c..3a0927014299 100644 --- a/airbyte-integrations/connectors/source-bing-ads/poetry.lock +++ b/airbyte-integrations/connectors/source-bing-ads/poetry.lock @@ -48,13 +48,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models-dataclasses" -version = "0.13.0" +version = "0.13.1" description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models_dataclasses-0.13.0-py3-none-any.whl", hash = "sha256:0aedb99ffc4f9aab0ce91bba2c292fa17cd8fd4b42eeba196d6a16c20bbbd7a5"}, - {file = "airbyte_protocol_models_dataclasses-0.13.0.tar.gz", hash = "sha256:72e67850d661e2808406aec5839b3158ebb94d3553b798dbdae1b4a278548d2f"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1-py3-none-any.whl", hash = "sha256:20a734b7b1c3479a643777830db6a2e0a34428f33d16abcfd320552576fabe5a"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1.tar.gz", hash = "sha256:ec6a0fb6b16267bde910f52279445d06c8e1a3e4ed82ac2937b405ab280449d5"}, ] [[package]] @@ -70,24 +70,24 @@ files = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -113,19 +113,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -216,13 +216,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -306,127 +306,114 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -499,20 +486,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -576,13 +563,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -597,13 +584,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -611,7 +598,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -661,13 +647,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -768,22 +754,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -881,131 +870,150 @@ twitter = ["twython"] [[package]] name = "numpy" -version = "2.1.2" +version = "2.2.1" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.10" files = [ - {file = "numpy-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466"}, - {file = "numpy-2.1.2-cp310-cp310-win32.whl", hash = "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb"}, - {file = "numpy-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146"}, - {file = "numpy-2.1.2-cp311-cp311-win32.whl", hash = "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c"}, - {file = "numpy-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142"}, - {file = "numpy-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550"}, - {file = "numpy-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe"}, - {file = "numpy-2.1.2-cp313-cp313-win32.whl", hash = "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a"}, - {file = "numpy-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e"}, - {file = "numpy-2.1.2.tar.gz", hash = "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c"}, + {file = "numpy-2.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5edb4e4caf751c1518e6a26a83501fda79bff41cc59dac48d70e6d65d4ec4440"}, + {file = "numpy-2.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aa3017c40d513ccac9621a2364f939d39e550c542eb2a894b4c8da92b38896ab"}, + {file = "numpy-2.2.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:61048b4a49b1c93fe13426e04e04fdf5a03f456616f6e98c7576144677598675"}, + {file = "numpy-2.2.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:7671dc19c7019103ca44e8d94917eba8534c76133523ca8406822efdd19c9308"}, + {file = "numpy-2.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4250888bcb96617e00bfa28ac24850a83c9f3a16db471eca2ee1f1714df0f957"}, + {file = "numpy-2.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7746f235c47abc72b102d3bce9977714c2444bdfaea7888d241b4c4bb6a78bf"}, + {file = "numpy-2.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:059e6a747ae84fce488c3ee397cee7e5f905fd1bda5fb18c66bc41807ff119b2"}, + {file = "numpy-2.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f62aa6ee4eb43b024b0e5a01cf65a0bb078ef8c395e8713c6e8a12a697144528"}, + {file = "numpy-2.2.1-cp310-cp310-win32.whl", hash = "sha256:48fd472630715e1c1c89bf1feab55c29098cb403cc184b4859f9c86d4fcb6a95"}, + {file = "numpy-2.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:b541032178a718c165a49638d28272b771053f628382d5e9d1c93df23ff58dbf"}, + {file = "numpy-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:40f9e544c1c56ba8f1cf7686a8c9b5bb249e665d40d626a23899ba6d5d9e1484"}, + {file = "numpy-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9b57eaa3b0cd8db52049ed0330747b0364e899e8a606a624813452b8203d5f7"}, + {file = "numpy-2.2.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:bc8a37ad5b22c08e2dbd27df2b3ef7e5c0864235805b1e718a235bcb200cf1cb"}, + {file = "numpy-2.2.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:9036d6365d13b6cbe8f27a0eaf73ddcc070cae584e5ff94bb45e3e9d729feab5"}, + {file = "numpy-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51faf345324db860b515d3f364eaa93d0e0551a88d6218a7d61286554d190d73"}, + {file = "numpy-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38efc1e56b73cc9b182fe55e56e63b044dd26a72128fd2fbd502f75555d92591"}, + {file = "numpy-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:31b89fa67a8042e96715c68e071a1200c4e172f93b0fbe01a14c0ff3ff820fc8"}, + {file = "numpy-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4c86e2a209199ead7ee0af65e1d9992d1dce7e1f63c4b9a616500f93820658d0"}, + {file = "numpy-2.2.1-cp311-cp311-win32.whl", hash = "sha256:b34d87e8a3090ea626003f87f9392b3929a7bbf4104a05b6667348b6bd4bf1cd"}, + {file = "numpy-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:360137f8fb1b753c5cde3ac388597ad680eccbbbb3865ab65efea062c4a1fd16"}, + {file = "numpy-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:694f9e921a0c8f252980e85bce61ebbd07ed2b7d4fa72d0e4246f2f8aa6642ab"}, + {file = "numpy-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3683a8d166f2692664262fd4900f207791d005fb088d7fdb973cc8d663626faa"}, + {file = "numpy-2.2.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:780077d95eafc2ccc3ced969db22377b3864e5b9a0ea5eb347cc93b3ea900315"}, + {file = "numpy-2.2.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:55ba24ebe208344aa7a00e4482f65742969a039c2acfcb910bc6fcd776eb4355"}, + {file = "numpy-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b1d07b53b78bf84a96898c1bc139ad7f10fda7423f5fd158fd0f47ec5e01ac7"}, + {file = "numpy-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5062dc1a4e32a10dc2b8b13cedd58988261416e811c1dc4dbdea4f57eea61b0d"}, + {file = "numpy-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:fce4f615f8ca31b2e61aa0eb5865a21e14f5629515c9151850aa936c02a1ee51"}, + {file = "numpy-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:67d4cda6fa6ffa073b08c8372aa5fa767ceb10c9a0587c707505a6d426f4e046"}, + {file = "numpy-2.2.1-cp312-cp312-win32.whl", hash = "sha256:32cb94448be47c500d2c7a95f93e2f21a01f1fd05dd2beea1ccd049bb6001cd2"}, + {file = "numpy-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:ba5511d8f31c033a5fcbda22dd5c813630af98c70b2661f2d2c654ae3cdfcfc8"}, + {file = "numpy-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f1d09e520217618e76396377c81fba6f290d5f926f50c35f3a5f72b01a0da780"}, + {file = "numpy-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3ecc47cd7f6ea0336042be87d9e7da378e5c7e9b3c8ad0f7c966f714fc10d821"}, + {file = "numpy-2.2.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f419290bc8968a46c4933158c91a0012b7a99bb2e465d5ef5293879742f8797e"}, + {file = "numpy-2.2.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5b6c390bfaef8c45a260554888966618328d30e72173697e5cabe6b285fb2348"}, + {file = "numpy-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:526fc406ab991a340744aad7e25251dd47a6720a685fa3331e5c59fef5282a59"}, + {file = "numpy-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f74e6fdeb9a265624ec3a3918430205dff1df7e95a230779746a6af78bc615af"}, + {file = "numpy-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:53c09385ff0b72ba79d8715683c1168c12e0b6e84fb0372e97553d1ea91efe51"}, + {file = "numpy-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f3eac17d9ec51be534685ba877b6ab5edc3ab7ec95c8f163e5d7b39859524716"}, + {file = "numpy-2.2.1-cp313-cp313-win32.whl", hash = "sha256:9ad014faa93dbb52c80d8f4d3dcf855865c876c9660cb9bd7553843dd03a4b1e"}, + {file = "numpy-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:164a829b6aacf79ca47ba4814b130c4020b202522a93d7bff2202bfb33b61c60"}, + {file = "numpy-2.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4dfda918a13cc4f81e9118dea249e192ab167a0bb1966272d5503e39234d694e"}, + {file = "numpy-2.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:733585f9f4b62e9b3528dd1070ec4f52b8acf64215b60a845fa13ebd73cd0712"}, + {file = "numpy-2.2.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:89b16a18e7bba224ce5114db863e7029803c179979e1af6ad6a6b11f70545008"}, + {file = "numpy-2.2.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:676f4eebf6b2d430300f1f4f4c2461685f8269f94c89698d832cdf9277f30b84"}, + {file = "numpy-2.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27f5cdf9f493b35f7e41e8368e7d7b4bbafaf9660cba53fb21d2cd174ec09631"}, + {file = "numpy-2.2.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1ad395cf254c4fbb5b2132fee391f361a6e8c1adbd28f2cd8e79308a615fe9d"}, + {file = "numpy-2.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:08ef779aed40dbc52729d6ffe7dd51df85796a702afbf68a4f4e41fafdc8bda5"}, + {file = "numpy-2.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:26c9c4382b19fcfbbed3238a14abf7ff223890ea1936b8890f058e7ba35e8d71"}, + {file = "numpy-2.2.1-cp313-cp313t-win32.whl", hash = "sha256:93cf4e045bae74c90ca833cba583c14b62cb4ba2cba0abd2b141ab52548247e2"}, + {file = "numpy-2.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:bff7d8ec20f5f42607599f9994770fa65d76edca264a87b5e4ea5629bce12268"}, + {file = "numpy-2.2.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7ba9cc93a91d86365a5d270dee221fdc04fb68d7478e6bf6af650de78a8339e3"}, + {file = "numpy-2.2.1-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:3d03883435a19794e41f147612a77a8f56d4e52822337844fff3d4040a142964"}, + {file = "numpy-2.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4511d9e6071452b944207c8ce46ad2f897307910b402ea5fa975da32e0102800"}, + {file = "numpy-2.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5c5cc0cbabe9452038ed984d05ac87910f89370b9242371bd9079cb4af61811e"}, + {file = "numpy-2.2.1.tar.gz", hash = "sha256:45681fd7128c8ad1c379f0ca0776a8b0c6583d2f69889ddac01559dfe4390918"}, ] [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -1180,19 +1188,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1200,100 +1208,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -1301,13 +1320,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1513,105 +1532,105 @@ files = [ [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -1752,33 +1771,33 @@ typing-extensions = "*" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1831,20 +1850,21 @@ files = [ [[package]] name = "tqdm" -version = "4.66.6" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63"}, - {file = "tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -1917,81 +1937,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [[package]] diff --git a/airbyte-integrations/connectors/source-bing-ads/pyproject.toml b/airbyte-integrations/connectors/source-bing-ads/pyproject.toml index 50147b7d2deb..919f3efcfa99 100644 --- a/airbyte-integrations/connectors/source-bing-ads/pyproject.toml +++ b/airbyte-integrations/connectors/source-bing-ads/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "2.8.2" +version = "2.8.8" name = "source-bing-ads" description = "Source implementation for Bing Ads." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/base_streams.py b/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/base_streams.py index abeb59c2f003..4aed49b85a71 100644 --- a/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/base_streams.py +++ b/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/base_streams.py @@ -7,13 +7,14 @@ from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Union from urllib.error import URLError -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.streams import Stream from bingads.service_client import ServiceClient from bingads.v13.reporting.reporting_service_manager import ReportingServiceManager -from source_bing_ads.client import Client from suds import sudsobject +from airbyte_cdk.models import SyncMode +from airbyte_cdk.sources.streams import Stream +from source_bing_ads.client import Client + class BingAdsBaseStream(Stream, ABC): primary_key: Optional[Union[str, List[str], List[List[str]]]] = None diff --git a/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/bulk_streams.py b/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/bulk_streams.py index 159aba01bf79..85e01f86d693 100644 --- a/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/bulk_streams.py +++ b/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/bulk_streams.py @@ -8,16 +8,16 @@ import pandas as pd import pendulum +from numpy import nan + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.streams import IncrementalMixin from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer -from numpy import nan from source_bing_ads.base_streams import Accounts, BingAdsBaseStream from source_bing_ads.utils import transform_bulk_datetime_format_to_rfc_3339 class BingAdsBulkStream(BingAdsBaseStream, IncrementalMixin, ABC): - transformer: TypeTransformer = TypeTransformer(TransformConfig.DefaultSchemaNormalization | TransformConfig.CustomSchemaNormalization) cursor_field = "Modified Time" primary_key = "Id" diff --git a/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/client.py b/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/client.py index 06c1c801917c..223882405783 100644 --- a/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/client.py +++ b/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/client.py @@ -14,8 +14,6 @@ import backoff import pendulum -from airbyte_cdk.models import FailureType -from airbyte_cdk.utils import AirbyteTracedException from bingads.authorization import AuthorizationData, OAuthTokens, OAuthWebAuthCodeGrant from bingads.exceptions import OAuthTokenRequestException from bingads.service_client import ServiceClient @@ -25,6 +23,10 @@ from bingads.v13.reporting.reporting_service_manager import ReportingServiceManager from suds import WebFault, sudsobject +from airbyte_cdk.models import FailureType +from airbyte_cdk.utils import AirbyteTracedException + + FILE_TYPE = "Csv" TIMEOUT_IN_MILLISECONDS = 3_600_000 diff --git a/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/report_streams.py b/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/report_streams.py index dc49ab462cb4..5640921c89da 100644 --- a/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/report_streams.py +++ b/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/report_streams.py @@ -2,6 +2,7 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # +import _csv import re import xml.etree.ElementTree as ET from abc import ABC, abstractmethod @@ -9,20 +10,20 @@ from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Set, Tuple, Union from urllib.parse import urlparse -import _csv import pendulum -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.streams.core import package_name_from_class -from airbyte_cdk.sources.utils.schema_helpers import ResourceSchemaLoader -from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer from bingads import ServiceClient from bingads.v13.internal.reporting.row_report import _RowReport from bingads.v13.internal.reporting.row_report_iterator import _RowReportRecord from bingads.v13.reporting import ReportingDownloadParameters from cached_property import cached_property +from suds import WebFault, sudsobject + +from airbyte_cdk.models import SyncMode +from airbyte_cdk.sources.streams.core import package_name_from_class +from airbyte_cdk.sources.utils.schema_helpers import ResourceSchemaLoader +from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer from source_bing_ads.base_streams import Accounts, BingAdsStream from source_bing_ads.utils import transform_date_format_to_rfc_3339, transform_report_hourly_datetime_format_to_rfc_3339 -from suds import WebFault, sudsobject class HourlyReportTransformerMixin: diff --git a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/base_test.py b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/base_test.py index 153de0086423..219e4628f8f0 100644 --- a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/base_test.py +++ b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/base_test.py @@ -5,11 +5,6 @@ from unittest import TestCase from unittest.mock import MagicMock, patch -from airbyte_cdk.models import AirbyteStateMessage, SyncMode -from airbyte_cdk.test.catalog_builder import CatalogBuilder -from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read -from airbyte_cdk.test.mock_http import HttpMocker -from airbyte_cdk.test.state_builder import StateBuilder from bingads.v13.bulk import BulkServiceManager from bingads.v13.reporting.reporting_service_manager import ReportingServiceManager from client_builder import build_request, response_with_status @@ -18,6 +13,12 @@ from suds.transport.https import HttpAuthenticated from suds_response_mock import mock_http_authenticated_send +from airbyte_cdk.models import AirbyteStateMessage, SyncMode +from airbyte_cdk.test.catalog_builder import CatalogBuilder +from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read +from airbyte_cdk.test.mock_http import HttpMocker +from airbyte_cdk.test.state_builder import StateBuilder + class BaseTest(TestCase): @property diff --git a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/config_builder.py b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/config_builder.py index 1606921d8bd0..3e16e05a03c6 100644 --- a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/config_builder.py +++ b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/config_builder.py @@ -4,6 +4,7 @@ from airbyte_cdk.test.mock_http.response_builder import find_template + TENNANT_ID = "common" DEVELOPER_TOKEN = "test-token" REFRESH_TOKEN = "test-refresh-token" diff --git a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/suds_response_mock.py b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/suds_response_mock.py index 59b3bea844ea..ed8a64e1842e 100644 --- a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/suds_response_mock.py +++ b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/suds_response_mock.py @@ -3,6 +3,7 @@ from suds.transport import Reply, Request from suds.transport.https import HttpAuthenticated + SEARCH_ACCOUNTS_RESPONSE = b""" 6f0a329e-4cb4-4c79-9c08-2dfe601ba05a diff --git a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_accounts_stream.py b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_accounts_stream.py index d97762fc0bf5..01530c1fad97 100644 --- a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_accounts_stream.py +++ b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_accounts_stream.py @@ -2,15 +2,16 @@ from typing import Any, Dict, Optional, Tuple from unittest.mock import MagicMock, patch -from airbyte_cdk.models import SyncMode -from airbyte_cdk.test.catalog_builder import CatalogBuilder -from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read -from airbyte_cdk.test.mock_http import HttpMocker from base_test import BaseTest from source_bing_ads.source import SourceBingAds from suds.transport.https import HttpAuthenticated from suds_response_mock import mock_http_authenticated_send +from airbyte_cdk.models import SyncMode +from airbyte_cdk.test.catalog_builder import CatalogBuilder +from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read +from airbyte_cdk.test.mock_http import HttpMocker + class TestAccountsStream(BaseTest): stream_name = "accounts" diff --git a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_app_install_ad_labels_stream.py b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_app_install_ad_labels_stream.py index 1dd16c11461f..534dcb61a5bd 100644 --- a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_app_install_ad_labels_stream.py +++ b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_app_install_ad_labels_stream.py @@ -1,10 +1,11 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. import pendulum -from airbyte_cdk.models import SyncMode -from airbyte_cdk.test.mock_http import HttpMocker from freezegun import freeze_time from test_bulk_stream import TestBulkStream +from airbyte_cdk.models import SyncMode +from airbyte_cdk.test.mock_http import HttpMocker + class TestAppInstallAdLabelsStream(TestBulkStream): stream_name = "app_install_ad_labels" @@ -38,7 +39,9 @@ def test_incremental_read_cursor_value_matches_value_from_most_recent_record(sel self.auth_client(http_mocker) output, _ = self.read_stream(self.stream_name, SyncMode.incremental, self._config, "app_install_ad_labels_with_cursor_value") assert len(output.records) == 4 - assert output.most_recent_state.stream_state.__dict__.get(self.account_id, {}) == {self.cursor_field: "2024-01-04T12:12:12.028+00:00"} + assert output.most_recent_state.stream_state.__dict__.get(self.account_id, {}) == { + self.cursor_field: "2024-01-04T12:12:12.028+00:00" + } @HttpMocker() @freeze_time("2024-02-26") # mock current time as stream data available for 30 days only @@ -46,14 +49,14 @@ def test_incremental_read_with_state(self, http_mocker: HttpMocker): state = self._state("app_install_ad_labels_state", self.stream_name) self.auth_client(http_mocker) output, service_call_mock = self.read_stream( - self.stream_name, - SyncMode.incremental, - self._config, - "app_install_ad_labels_with_state", - state + self.stream_name, SyncMode.incremental, self._config, "app_install_ad_labels_with_state", state ) - assert output.most_recent_state.stream_state.__dict__.get(self.account_id, {}) == {self.cursor_field: "2024-01-29T12:55:12.028+00:00"} + assert output.most_recent_state.stream_state.__dict__.get(self.account_id, {}) == { + self.cursor_field: "2024-01-29T12:55:12.028+00:00" + } previous_state = state[0].stream.stream_state.__dict__ # gets DownloadParams object - assert service_call_mock.call_args.args[0].last_sync_time_in_utc == pendulum.parse(previous_state[self.account_id][self.cursor_field]) + assert service_call_mock.call_args.args[0].last_sync_time_in_utc == pendulum.parse( + previous_state[self.account_id][self.cursor_field] + ) diff --git a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_app_install_ads_stream.py b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_app_install_ads_stream.py index 7524b3241110..913bf6105f00 100644 --- a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_app_install_ads_stream.py +++ b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_app_install_ads_stream.py @@ -1,10 +1,11 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. import pendulum -from airbyte_cdk.models import SyncMode -from airbyte_cdk.test.mock_http import HttpMocker from freezegun import freeze_time from test_bulk_stream import TestBulkStream +from airbyte_cdk.models import SyncMode +from airbyte_cdk.test.mock_http import HttpMocker + class TestAppInstallAdsStream(TestBulkStream): stream_name = "app_install_ads" @@ -38,16 +39,24 @@ def test_incremental_read_cursor_value_matches_value_from_most_recent_record(sel self.auth_client(http_mocker) output, _ = self.read_stream(self.stream_name, SyncMode.incremental, self._config, "app_install_ads_with_cursor_value") assert len(output.records) == 4 - assert output.most_recent_state.stream_state.__dict__.get(self.account_id, {}) == {self.cursor_field: "2024-03-01T12:49:12.028+00:00"} + assert output.most_recent_state.stream_state.__dict__.get(self.account_id, {}) == { + self.cursor_field: "2024-03-01T12:49:12.028+00:00" + } @HttpMocker() @freeze_time("2023-12-29") # mock current time as stream data available for 30 days only def test_incremental_read_with_state(self, http_mocker: HttpMocker): state = self._state("app_install_ads_state", self.stream_name) self.auth_client(http_mocker) - output, service_call_mock = self.read_stream(self.stream_name, SyncMode.incremental, self._config, "app_install_ads_with_state", state) - assert output.most_recent_state.stream_state.__dict__.get(self.account_id, {}) == {self.cursor_field: "2024-01-01T10:55:12.028+00:00"} + output, service_call_mock = self.read_stream( + self.stream_name, SyncMode.incremental, self._config, "app_install_ads_with_state", state + ) + assert output.most_recent_state.stream_state.__dict__.get(self.account_id, {}) == { + self.cursor_field: "2024-01-01T10:55:12.028+00:00" + } previous_state = state[0].stream.stream_state.__dict__ # gets DownloadParams object - assert service_call_mock.call_args.args[0].last_sync_time_in_utc == pendulum.parse(previous_state[self.account_id][self.cursor_field]) + assert service_call_mock.call_args.args[0].last_sync_time_in_utc == pendulum.parse( + previous_state[self.account_id][self.cursor_field] + ) diff --git a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_budget_stream.py b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_budget_stream.py index 8c375d58bdc2..6ac874274e0f 100644 --- a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_budget_stream.py +++ b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_budget_stream.py @@ -1,10 +1,11 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. import pendulum -from airbyte_cdk.models import SyncMode -from airbyte_cdk.test.mock_http import HttpMocker from freezegun import freeze_time from test_bulk_stream import TestBulkStream +from airbyte_cdk.models import SyncMode +from airbyte_cdk.test.mock_http import HttpMocker + class TestBudgetStream(TestBulkStream): stream_name = "budget" diff --git a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_hourly_reports.py b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_hourly_reports.py index ce40374eed82..fc3bc2c44b8d 100644 --- a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_hourly_reports.py +++ b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_hourly_reports.py @@ -2,6 +2,7 @@ from test_report_stream import TestSuiteReportStream + FIRST_STATE = {"180535609": {"TimePeriod": "2023-11-12T00:00:00+00:00"}} SECOND_STATE = {"180535609": {"TimePeriod": "2023-11-13T00:00:00+00:00"}} diff --git a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_report_stream.py b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_report_stream.py index ae222db7dbd0..7829df1614d2 100644 --- a/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_report_stream.py +++ b/airbyte-integrations/connectors/source-bing-ads/unit_tests/integrations/test_report_stream.py @@ -4,12 +4,13 @@ from typing import Any, Optional import pendulum -from airbyte_cdk.models import SyncMode -from airbyte_cdk.test.mock_http import HttpMocker from base_test import BaseTest from bingads.v13.reporting.reporting_service_manager import ReportingServiceManager from config_builder import ConfigBuilder +from airbyte_cdk.models import SyncMode +from airbyte_cdk.test.mock_http import HttpMocker + class TestReportStream(BaseTest): start_date = "2024-01-01" diff --git a/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_bulk_streams.py b/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_bulk_streams.py index 9a96becee8c6..7fc12f901ef1 100644 --- a/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_bulk_streams.py +++ b/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_bulk_streams.py @@ -88,18 +88,18 @@ def test_bulk_stream_read_with_chunks_app_install_ad_labels(mocked_client, confi app_install_ads = AppInstallAdLabels(mocked_client, config) result = app_install_ads.read_with_chunks(path=path_to_file) assert next(result) == { - 'Ad Group': None, - 'Campaign': None, - 'Client Id': 'ClientIdGoesHere', - 'Color': None, - 'Description': None, - 'Id': '-22', - 'Label': None, - 'Modified Time': None, - 'Name': None, - 'Parent Id': '-11112', - 'Status': None, - 'Type': 'App Install Ad Label' + "Ad Group": None, + "Campaign": None, + "Client Id": "ClientIdGoesHere", + "Color": None, + "Description": None, + "Id": "-22", + "Label": None, + "Modified Time": None, + "Name": None, + "Parent Id": "-11112", + "Status": None, + "Type": "App Install Ad Label", } @@ -116,17 +116,21 @@ def test_bulk_stream_read_with_chunks_ioe_error(mocked_client, config, caplog): @pytest.mark.parametrize( "stream_state, config_start_date, expected_start_date", [ - ({"some_account_id": {"Modified Time": "2023-10-15T12:00:00.000+00:00"}}, "2020-01-01", DateTime(2023, 10, 15, 12, 0, 0, tzinfo=UTC)), + ( + {"some_account_id": {"Modified Time": "2023-10-15T12:00:00.000+00:00"}}, + "2020-01-01", + DateTime(2023, 10, 15, 12, 0, 0, tzinfo=UTC), + ), ({"another_account_id": {"Modified Time": "2023-10-15T12:00:00.000+00:00"}}, "2020-01-01", None), ({}, "2020-01-01", None), ({}, "2023-10-21", DateTime(2023, 10, 21, 0, 0, 0, tzinfo=UTC)), ], - ids=["state_within_30_days", "state_within_30_days_another_account_id", "empty_state", "empty_state_start_date_within_30"] + ids=["state_within_30_days", "state_within_30_days_another_account_id", "empty_state", "empty_state_start_date_within_30"], ) def test_bulk_stream_start_date(mocked_client, config, stream_state, config_start_date, expected_start_date): mocked_client.reports_start_date = pendulum.parse(config_start_date) if config_start_date else None stream = AppInstallAds(mocked_client, config) - assert expected_start_date == stream.get_start_date(stream_state, 'some_account_id') + assert expected_start_date == stream.get_start_date(stream_state, "some_account_id") @patch.object(source_bing_ads.source, "Client") @@ -140,18 +144,10 @@ def test_bulk_stream_stream_state(mocked_client, config): assert stream.state == {"some_account_id": {"Modified Time": "2023-05-27T18:00:14.970+00:00"}} # stream state saved to connection state stream.state = { - "120342748234": { - "Modified Time": "2022-11-05T12:07:29.360+00:00" - }, - "27364572345": { - "Modified Time": "2022-11-05T12:07:29.360+00:00" - }, - "732645723": { - "Modified Time": "2022-11-05T12:07:29.360+00:00" - }, - "837563864": { - "Modified Time": "2022-11-05T12:07:29.360+00:00" - } + "120342748234": {"Modified Time": "2022-11-05T12:07:29.360+00:00"}, + "27364572345": {"Modified Time": "2022-11-05T12:07:29.360+00:00"}, + "732645723": {"Modified Time": "2022-11-05T12:07:29.360+00:00"}, + "837563864": {"Modified Time": "2022-11-05T12:07:29.360+00:00"}, } assert stream.state == { "120342748234": {"Modified Time": "2022-11-05T12:07:29.360+00:00"}, @@ -165,4 +161,6 @@ def test_bulk_stream_stream_state(mocked_client, config): @patch.object(source_bing_ads.source, "Client") def test_bulk_stream_custom_transform_date_rfc3339(mocked_client, config): stream = AppInstallAds(mocked_client, config) - assert "2023-04-27T18:00:14.970+00:00" == stream.custom_transform_date_rfc3339("04/27/2023 18:00:14.970", stream.get_json_schema()["properties"][stream.cursor_field]) + assert "2023-04-27T18:00:14.970+00:00" == stream.custom_transform_date_rfc3339( + "04/27/2023 18:00:14.970", stream.get_json_schema()["properties"][stream.cursor_field] + ) diff --git a/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_client.py b/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_client.py index 96b2d5777f57..597c3477f13f 100644 --- a/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_client.py +++ b/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_client.py @@ -10,12 +10,13 @@ import pytest import source_bing_ads.client -from airbyte_cdk.utils import AirbyteTracedException from bingads.authorization import AuthorizationData, OAuthTokens from bingads.v13.bulk import BulkServiceManager from bingads.v13.reporting.exceptions import ReportingDownloadException from suds import sudsobject +from airbyte_cdk.utils import AirbyteTracedException + def test_sudsobject_todict_primitive_types(): test_arr = ["1", "test", 1, [0, 0]] diff --git a/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_reports.py b/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_reports.py index f68acb43a302..aad542afec40 100644 --- a/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_reports.py +++ b/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_reports.py @@ -2,6 +2,7 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # +import _csv import copy import json import xml.etree.ElementTree as ET @@ -9,11 +10,9 @@ from unittest.mock import MagicMock, Mock, patch from urllib.parse import urlparse -import _csv import pendulum import pytest import source_bing_ads -from airbyte_cdk.models import SyncMode from bingads.service_info import SERVICE_INFO_DICT_V13 from bingads.v13.internal.reporting.row_report import _RowReport from bingads.v13.internal.reporting.row_report_iterator import _RowReportRecord, _RowValues @@ -53,6 +52,9 @@ from source_bing_ads.source import SourceBingAds from suds import WebFault +from airbyte_cdk.models import SyncMode + + TEST_CONFIG = { "developer_token": "developer_token", "client_id": "client_id", @@ -259,7 +261,10 @@ def test_report_parse_response_csv_error(caplog): fake_response = MagicMock() fake_response.report_records.__iter__ = MagicMock(side_effect=_csv.Error) list(stream_report.parse_response(fake_response)) - assert "CSV report file for stream `account_performance_report_hourly` is broken or cannot be read correctly: , skipping ..." in caplog.messages + assert ( + "CSV report file for stream `account_performance_report_hourly` is broken or cannot be read correctly: , skipping ..." + in caplog.messages + ) @patch.object(source_bing_ads.source, "Client") @@ -404,10 +409,10 @@ def test_account_performance_report_monthly_stream_slices(mocked_client, config_ with patch.object(Accounts, "read_records", return_value=accounts_read_records): stream_slice = list(account_performance_report_monthly.stream_slices(sync_mode=SyncMode.full_refresh)) assert stream_slice == [ - {'account_id': 180519267, 'customer_id': 100, 'time_period': 'LastYear'}, - {'account_id': 180519267, 'customer_id': 100, 'time_period': 'ThisYear'}, - {'account_id': 180278106, 'customer_id': 200, 'time_period': 'LastYear'}, - {'account_id': 180278106, 'customer_id': 200, 'time_period': 'ThisYear'} + {"account_id": 180519267, "customer_id": 100, "time_period": "LastYear"}, + {"account_id": 180519267, "customer_id": 100, "time_period": "ThisYear"}, + {"account_id": 180278106, "customer_id": 200, "time_period": "LastYear"}, + {"account_id": 180278106, "customer_id": 200, "time_period": "ThisYear"}, ] @@ -417,10 +422,7 @@ def test_account_performance_report_monthly_stream_slices_no_time_period(mocked_ accounts_read_records = iter([{"Id": 180519267, "ParentCustomerId": 100}, {"Id": 180278106, "ParentCustomerId": 200}]) with patch.object(Accounts, "read_records", return_value=accounts_read_records): stream_slice = list(account_performance_report_monthly.stream_slices(sync_mode=SyncMode.full_refresh)) - assert stream_slice == [ - {'account_id': 180519267, 'customer_id': 100}, - {'account_id': 180278106, 'customer_id': 200} - ] + assert stream_slice == [{"account_id": 180519267, "customer_id": 100}, {"account_id": 180278106, "customer_id": 200}] @pytest.mark.parametrize( @@ -451,14 +453,38 @@ def test_custom_performance_report_no_last_year_stream_slices(mocked_client, con (AccountPerformanceReportHourly, "hourly_reports/account_performance.csv", "hourly_reports/account_performance_records.json"), (AdGroupPerformanceReportHourly, "hourly_reports/ad_group_performance.csv", "hourly_reports/ad_group_performance_records.json"), (AdPerformanceReportHourly, "hourly_reports/ad_performance.csv", "hourly_reports/ad_performance_records.json"), - (CampaignImpressionPerformanceReportHourly, "hourly_reports/campaign_impression_performance.csv", "hourly_reports/campaign_impression_performance_records.json"), + ( + CampaignImpressionPerformanceReportHourly, + "hourly_reports/campaign_impression_performance.csv", + "hourly_reports/campaign_impression_performance_records.json", + ), (KeywordPerformanceReportHourly, "hourly_reports/keyword_performance.csv", "hourly_reports/keyword_performance_records.json"), - (GeographicPerformanceReportHourly, "hourly_reports/geographic_performance.csv", "hourly_reports/geographic_performance_records.json"), + ( + GeographicPerformanceReportHourly, + "hourly_reports/geographic_performance.csv", + "hourly_reports/geographic_performance_records.json", + ), (AgeGenderAudienceReportHourly, "hourly_reports/age_gender_audience.csv", "hourly_reports/age_gender_audience_records.json"), - (SearchQueryPerformanceReportHourly, "hourly_reports/search_query_performance.csv", "hourly_reports/search_query_performance_records.json"), - (UserLocationPerformanceReportHourly, "hourly_reports/user_location_performance.csv", "hourly_reports/user_location_performance_records.json"), - (AccountImpressionPerformanceReportHourly, "hourly_reports/account_impression_performance.csv", "hourly_reports/account_impression_performance_records.json"), - (AdGroupImpressionPerformanceReportHourly, "hourly_reports/ad_group_impression_performance.csv", "hourly_reports/ad_group_impression_performance_records.json"), + ( + SearchQueryPerformanceReportHourly, + "hourly_reports/search_query_performance.csv", + "hourly_reports/search_query_performance_records.json", + ), + ( + UserLocationPerformanceReportHourly, + "hourly_reports/user_location_performance.csv", + "hourly_reports/user_location_performance_records.json", + ), + ( + AccountImpressionPerformanceReportHourly, + "hourly_reports/account_impression_performance.csv", + "hourly_reports/account_impression_performance_records.json", + ), + ( + AdGroupImpressionPerformanceReportHourly, + "hourly_reports/ad_group_impression_performance.csv", + "hourly_reports/ad_group_impression_performance_records.json", + ), ], ) @patch.object(source_bing_ads.source, "Client") diff --git a/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_source.py b/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_source.py index a938300eedf0..f53cac5a1080 100644 --- a/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_source.py @@ -6,12 +6,13 @@ import pytest import source_bing_ads -from airbyte_cdk.models import SyncMode -from airbyte_cdk.utils import AirbyteTracedException from bingads.service_info import SERVICE_INFO_DICT_V13 from source_bing_ads.base_streams import Accounts, AdGroups, Ads, Campaigns from source_bing_ads.source import SourceBingAds +from airbyte_cdk.models import SyncMode +from airbyte_cdk.utils import AirbyteTracedException + @patch.object(source_bing_ads.source, "Client") def test_streams_config_based(mocked_client, config): @@ -97,7 +98,6 @@ def test_clear_reporting_object_name(): @patch.object(source_bing_ads.source, "Client") def test_campaigns_request_params(mocked_client, config): - campaigns = Campaigns(mocked_client, config) request_params = campaigns.request_params(stream_slice={"account_id": "account_id"}) @@ -110,7 +110,6 @@ def test_campaigns_request_params(mocked_client, config): @patch.object(source_bing_ads.source, "Client") def test_campaigns_stream_slices(mocked_client, config): - campaigns = Campaigns(mocked_client, config) accounts_read_records = iter([{"Id": 180519267, "ParentCustomerId": 100}, {"Id": 180278106, "ParentCustomerId": 200}]) with patch.object(Accounts, "read_records", return_value=accounts_read_records): @@ -123,7 +122,6 @@ def test_campaigns_stream_slices(mocked_client, config): @patch.object(source_bing_ads.source, "Client") def test_adgroups_stream_slices(mocked_client, config): - adgroups = AdGroups(mocked_client, config) accounts_read_records = iter([{"Id": 180519267, "ParentCustomerId": 100}, {"Id": 180278106, "ParentCustomerId": 200}]) campaigns_read_records = [iter([{"Id": 11}, {"Id": 22}]), iter([{"Id": 55}, {"Id": 66}])] @@ -140,7 +138,6 @@ def test_adgroups_stream_slices(mocked_client, config): @patch.object(source_bing_ads.source, "Client") def test_ads_request_params(mocked_client, config): - ads = Ads(mocked_client, config) request_params = ads.request_params(stream_slice={"ad_group_id": "ad_group_id"}) @@ -155,7 +152,6 @@ def test_ads_request_params(mocked_client, config): @patch.object(source_bing_ads.source, "Client") def test_ads_stream_slices(mocked_client, config): - ads = Ads(mocked_client, config) with patch.object( diff --git a/airbyte-integrations/connectors/source-bitly/metadata.yaml b/airbyte-integrations/connectors/source-bitly/metadata.yaml index b8db33dcd4f6..f961ce57f9d9 100644 --- a/airbyte-integrations/connectors/source-bitly/metadata.yaml +++ b/airbyte-integrations/connectors/source-bitly/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-bitly connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 3631f862-646b-4abf-abde-dc37acf3847c - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-bitly githubIssueLabel: source-bitly icon: icon.svg diff --git a/airbyte-integrations/connectors/source-blogger/README.md b/airbyte-integrations/connectors/source-blogger/README.md new file mode 100644 index 000000000000..df9b795e8e3e --- /dev/null +++ b/airbyte-integrations/connectors/source-blogger/README.md @@ -0,0 +1,33 @@ +# Blogger +This directory contains the manifest-only connector for `source-blogger`. + +Google Blogger is a free blogging platform by Google that allows users to create and manage their own blogs with ease. It offers customizable templates, user-friendly tools, and integration with other Google services, making it simple to publish content and reach a wide audience. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-blogger:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-blogger build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-blogger test +``` + diff --git a/airbyte-integrations/connectors/source-blogger/acceptance-test-config.yml b/airbyte-integrations/connectors/source-blogger/acceptance-test-config.yml new file mode 100644 index 000000000000..e541bff1f6e2 --- /dev/null +++ b/airbyte-integrations/connectors/source-blogger/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-blogger:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-blogger/icon.svg b/airbyte-integrations/connectors/source-blogger/icon.svg new file mode 100644 index 000000000000..ffd4019ae678 --- /dev/null +++ b/airbyte-integrations/connectors/source-blogger/icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-blogger/manifest.yaml b/airbyte-integrations/connectors/source-blogger/manifest.yaml new file mode 100644 index 000000000000..37bb80b8a69a --- /dev/null +++ b/airbyte-integrations/connectors/source-blogger/manifest.yaml @@ -0,0 +1,726 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Google Blogger is a free blogging platform by Google that allows users to + create and manage their own blogs with ease. It offers customizable templates, + user-friendly tools, and integration with other Google services, making it + simple to publish content and reach a wide audience. + +check: + type: CheckStream + stream_names: + - users + +definitions: + streams: + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /blogger/v3/users/self/blogs + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: nextPageToken + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('nextPageToken', '') }}" + stop_condition: "{{ response.get('nextPageToken') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + blogs: + type: DeclarativeStream + name: blogs + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /blogger/v3/blogs/{{ stream_partition.blog_id }}/posts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: nextPageToken + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('nextPageToken', '') }}" + stop_condition: "{{ response.get('nextPageToken') is none }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: blog_id + stream: + $ref: "#/definitions/streams/users" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/blogs" + posts: + type: DeclarativeStream + name: posts + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /blogger/v3/blogs/{{ stream_partition.blog_id + }}/posts/{{stream_partition.post_id}} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: nextPageToken + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('nextPageToken', '') }}" + stop_condition: "{{ response.get('nextPageToken') is none }}" + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: blog_id + stream: + $ref: "#/definitions/streams/users" + incremental_dependency: true + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: post_id + stream: + $ref: "#/definitions/streams/blogs" + incremental_dependency: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/posts" + pages: + type: DeclarativeStream + name: pages + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /blogger/v3/blogs/{{ stream_partition.blog_id }}/pages + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: nextPageToken + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('nextPageToken', '') }}" + stop_condition: "{{ response.get('nextPageToken') is none }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: blog_id + stream: + $ref: "#/definitions/streams/users" + incremental_dependency: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/pages" + comments: + type: DeclarativeStream + name: comments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /blogger/v3/blogs/{{ stream_partition.blog_id + }}/posts/{{stream_partition.post_id}}/comments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: nextPageToken + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('nextPageToken', '') }}" + stop_condition: "{{ response.get('nextPageToken') is none }}" + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: blog_id + stream: + $ref: "#/definitions/streams/users" + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: post_id + stream: + $ref: "#/definitions/streams/posts" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/comments" + base_requester: + type: HttpRequester + url_base: https://www.googleapis.com + authenticator: + type: OAuthAuthenticator + client_id: "{{ config[\"client_id\"] }}" + grant_type: refresh_token + client_secret: "{{ config[\"client_secret\"] }}" + refresh_token: "{{ config[\"client_refresh_token\"] }}" + refresh_request_body: {} + token_refresh_endpoint: https://oauth2.googleapis.com/token + +streams: + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/blogs" + - $ref: "#/definitions/streams/posts" + - $ref: "#/definitions/streams/pages" + - $ref: "#/definitions/streams/comments" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - client_id + - client_secret + - client_refresh_token + properties: + client_id: + type: string + order: 0 + title: Client ID + airbyte_secret: true + client_secret: + type: string + order: 1 + title: Client secret + airbyte_secret: true + client_refresh_token: + type: string + order: 2 + title: Refresh token + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + users: true + blogs: true + posts: true + pages: true + comments: false + testedStreams: + users: + streamHash: 15cb44e17561fd4b25260ebe00aad383411149f3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + blogs: + streamHash: 4ba8428f9ddcfd4ade1172ff2853a75adda47812 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + posts: + streamHash: 376828a8fecbce3ba7db12fdb33c3b05baed7481 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + pages: + streamHash: b061c8d16a2a61985797a20ed0bc503cf1fa2449 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + comments: + streamHash: 378e96f990cd6f073b99d89f3ae3ead328f8588f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://developers.google.com/blogger/docs/3.0/using + +schemas: + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + id: + type: string + kind: + type: + - string + - "null" + locale: + type: + - object + - "null" + properties: + country: + type: + - string + - "null" + language: + type: + - string + - "null" + variant: + type: + - string + - "null" + name: + type: + - string + - "null" + pages: + type: + - object + - "null" + properties: + selfLink: + type: + - string + - "null" + totalItems: + type: + - number + - "null" + posts: + type: + - object + - "null" + properties: + selfLink: + type: + - string + - "null" + totalItems: + type: + - number + - "null" + published: + type: + - string + - "null" + selfLink: + type: + - string + - "null" + status: + type: + - string + - "null" + updated: + type: + - string + - "null" + url: + type: + - string + - "null" + required: + - id + blogs: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + author: + type: + - object + - "null" + properties: + displayName: + type: + - string + - "null" + id: + type: + - string + - "null" + image: + type: + - object + - "null" + properties: + url: + type: + - string + - "null" + url: + type: + - string + - "null" + blog: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + content: + type: + - string + - "null" + etag: + type: + - string + - "null" + id: + type: string + kind: + type: + - string + - "null" + published: + type: + - string + - "null" + replies: + type: + - object + - "null" + properties: + selfLink: + type: + - string + - "null" + totalItems: + type: + - string + - "null" + selfLink: + type: + - string + - "null" + title: + type: + - string + - "null" + updated: + type: + - string + - "null" + url: + type: + - string + - "null" + required: + - id + posts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + author: + type: + - object + - "null" + properties: + displayName: + type: + - string + - "null" + id: + type: + - string + - "null" + image: + type: + - object + - "null" + properties: + url: + type: + - string + - "null" + url: + type: + - string + - "null" + blog: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + content: + type: + - string + - "null" + etag: + type: + - string + - "null" + id: + type: + - string + - "null" + kind: + type: + - string + - "null" + published: + type: + - string + - "null" + replies: + type: + - object + - "null" + properties: + selfLink: + type: + - string + - "null" + totalItems: + type: + - string + - "null" + selfLink: + type: + - string + - "null" + title: + type: + - string + - "null" + updated: + type: + - string + - "null" + url: + type: + - string + - "null" + pages: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + author: + type: + - object + - "null" + properties: + displayName: + type: + - string + - "null" + id: + type: + - string + - "null" + image: + type: + - object + - "null" + properties: + url: + type: + - string + - "null" + url: + type: + - string + - "null" + blog: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + content: + type: + - string + - "null" + etag: + type: + - string + - "null" + id: + type: string + kind: + type: + - string + - "null" + published: + type: + - string + - "null" + selfLink: + type: + - string + - "null" + title: + type: + - string + - "null" + updated: + type: + - string + - "null" + url: + type: + - string + - "null" + required: + - id + comments: + type: object + $schema: http://json-schema.org/schema# + properties: + author: + type: + - object + - "null" + properties: + displayName: + type: + - string + - "null" + id: + type: + - string + - "null" + image: + type: + - object + - "null" + properties: + url: + type: + - string + - "null" + url: + type: + - string + - "null" + blog: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + content: + type: + - string + - "null" + id: + type: string + kind: + type: + - string + - "null" + post: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + published: + type: + - string + - "null" + selfLink: + type: + - string + - "null" + updated: + type: + - string + - "null" + required: + - id + additionalProperties: true diff --git a/airbyte-integrations/connectors/source-blogger/metadata.yaml b/airbyte-integrations/connectors/source-blogger/metadata.yaml new file mode 100644 index 000000000000..46e95bd52a2d --- /dev/null +++ b/airbyte-integrations/connectors/source-blogger/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "googleapis.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-blogger + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: c6c4d8ae-60e9-49b4-9b48-e3a5857455fe + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-blogger + githubIssueLabel: source-blogger + icon: icon.svg + license: MIT + name: Blogger + releaseDate: 2024-11-09 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/blogger + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-box/README.md b/airbyte-integrations/connectors/source-box/README.md new file mode 100644 index 000000000000..802f6d72f5f5 --- /dev/null +++ b/airbyte-integrations/connectors/source-box/README.md @@ -0,0 +1,33 @@ +# Box +This directory contains the manifest-only connector for `source-box`. + +The Box Connector enables seamless data extraction from Box, allowing users to list, access, and synchronize files or folders from their Box cloud storage. This connector helps automate workflows by integrating Box data with other tools, ensuring efficient file management and analysis + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-box:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-box build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-box test +``` + diff --git a/airbyte-integrations/connectors/source-box/acceptance-test-config.yml b/airbyte-integrations/connectors/source-box/acceptance-test-config.yml new file mode 100644 index 000000000000..169db29c4727 --- /dev/null +++ b/airbyte-integrations/connectors/source-box/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-box:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-box/icon.svg b/airbyte-integrations/connectors/source-box/icon.svg new file mode 100644 index 000000000000..8a81fd5c1463 --- /dev/null +++ b/airbyte-integrations/connectors/source-box/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-box/manifest.yaml b/airbyte-integrations/connectors/source-box/manifest.yaml new file mode 100644 index 000000000000..8bbe0d1ea74c --- /dev/null +++ b/airbyte-integrations/connectors/source-box/manifest.yaml @@ -0,0 +1,2720 @@ +version: 5.16.0 + +type: DeclarativeSource + +description: >- + The Box Connector enables seamless data extraction from Box, allowing users to + list, access, and synchronize files or folders from their Box cloud storage. + This connector helps automate workflows by integrating Box data with other + tools, ensuring efficient file management and analysis + +check: + type: CheckStream + stream_names: + - events + +definitions: + streams: + events: + type: DeclarativeStream + name: events + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /2.0/events + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - entries + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: stream_position + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('next_stream_position') }}" + stop_condition: "{{ response.chunk_size == 0 }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/events" + sign_templates: + type: DeclarativeStream + name: sign_templates + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /2.0/sign_templates + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - entries + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: marker + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"next_marker\") }}" + stop_condition: "{{ response.get(\"next_marker\") is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sign_templates" + collections: + type: DeclarativeStream + name: collections + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /2.0/collections + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - entries + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/collections" + collection_items: + type: DeclarativeStream + name: collection_items + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /2.0/collections/{{ stream_partition.collection }}/items + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - entries + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + pagination_strategy: + type: OffsetIncrement + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: collection + stream: + $ref: "#/definitions/streams/collections" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/collection_items" + sign_request: + type: DeclarativeStream + name: sign_request + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /2.0/sign_requests + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - entries + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: marker + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('next_marker') }}" + stop_condition: "{{ response.get('next_marker') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sign_request" + admin_logs: + type: DeclarativeStream + name: admin_logs + primary_key: + - event_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /2.0/events?stream_type=admin_logs + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - entries + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: stream_position + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('next_stream_position', '') }}" + stop_condition: "{{ response.chunk_size == 0 }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/admin_logs" + files: + type: DeclarativeStream + name: files + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /2.0/folders/0/items + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - entries + record_filter: + type: RecordFilter + condition: "{{ record['type'] == \"file\"}}" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/files" + file_collaborations: + type: DeclarativeStream + name: file_collaborations + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /2.0/files/{{ stream_slice['file_id'] }}/collaborations + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - entries + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: marker + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('next_marker') }}" + stop_condition: "{{ response.get('next_marker') is none }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: file_id + stream: + $ref: "#/definitions/streams/files" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/file_collaborations" + folder_collaborations: + type: DeclarativeStream + name: folder_collaborations + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /2.0/folders/{{ stream_slice['folder_id'] }}/collaborations + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - entries + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: marker + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('next_marker') }}" + stop_condition: "{{ response.get('next_marker') is none }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: folder_id + stream: + $ref: "#/definitions/streams/folders" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/folder_collaborations" + file_comments: + type: DeclarativeStream + name: file_comments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /2.0/files/{{ stream_slice['file_id'] }}/comments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - entries + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: file_id + stream: + $ref: "#/definitions/streams/files" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/file_comments" + recent_items: + type: DeclarativeStream + name: recent_items + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /2.0/recent_items + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - entries + - "*" + - item + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: marker + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('next_marker') }}" + stop_condition: "{{ response.get('next_marker') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/recent_items" + file_tasks: + type: DeclarativeStream + name: file_tasks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /2.0/files/{{ stream_slice['file_id'] }}/tasks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - entries + - "*" + - task_assignment_collection + - entries + - "*" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: file_id + stream: + $ref: "#/definitions/streams/files" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/file_tasks" + trashed_items: + type: DeclarativeStream + name: trashed_items + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /2.0/folders/trash/items + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - entries + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + pagination_strategy: + type: OffsetIncrement + page_size: 1000 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/trashed_items" + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /2.0/users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - entries + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + pagination_strategy: + type: OffsetIncrement + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + folders: + type: DeclarativeStream + name: folders + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /2.0/folders/0/items + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - entries + record_filter: + type: RecordFilter + condition: "{{ record['type'] == \"folder\"}}" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/folders" + base_requester: + type: HttpRequester + url_base: https://api.box.com + authenticator: + type: OAuthAuthenticator + client_id: "{{ config[\"client_id\"] }}" + grant_type: client_credentials + client_secret: "{{ config[\"client_secret\"] }}" + expires_in_name: expires_in + access_token_name: access_token + refresh_request_body: + box_subject_id: "{{ config['user'] }}" + box_subject_type: user + token_refresh_endpoint: https://api.box.com/oauth2/token + +streams: + - $ref: "#/definitions/streams/events" + - $ref: "#/definitions/streams/sign_templates" + - $ref: "#/definitions/streams/collections" + - $ref: "#/definitions/streams/collection_items" + - $ref: "#/definitions/streams/sign_request" + - $ref: "#/definitions/streams/admin_logs" + - $ref: "#/definitions/streams/files" + - $ref: "#/definitions/streams/file_collaborations" + - $ref: "#/definitions/streams/folder_collaborations" + - $ref: "#/definitions/streams/file_comments" + - $ref: "#/definitions/streams/recent_items" + - $ref: "#/definitions/streams/file_tasks" + - $ref: "#/definitions/streams/trashed_items" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/folders" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - client_id + - client_secret + - user + properties: + client_id: + type: string + name: client_id + order: 0 + title: OAuth Client ID + airbyte_secret: true + client_secret: + type: string + name: client_secret + order: 1 + title: OAuth Client Secret + airbyte_secret: true + user: + type: number + order: 2 + title: User + additionalProperties: true + +metadata: + autoImportSchema: + events: true + sign_templates: true + collections: true + collection_items: true + sign_request: true + admin_logs: true + files: true + file_collaborations: true + folder_collaborations: true + file_comments: true + recent_items: true + file_tasks: true + trashed_items: true + users: true + folders: true + testedStreams: + events: + streamHash: 5f6a527cfa95216243803a32516a01f06260bb01 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + sign_templates: + streamHash: 4ab2165704ff19049bf1ecc510154302f122e5ba + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + collections: + streamHash: 99a1e98e0e5e1f0e34c55e3c067158efc139614d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + collection_items: + streamHash: 166e60e6b8bccc1e6854a88f7ad29fe76f08a83a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + sign_request: + streamHash: a75dbf901501cd636c8087c31ea771b4aba77d65 + hasResponse: true + responsesAreSuccessful: true + hasRecords: false + primaryKeysArePresent: true + primaryKeysAreUnique: true + admin_logs: + streamHash: d29f65619562bd57f0ab2ffde25f45fe85094fed + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + files: + streamHash: f2bddba5e78d73843ff573adddc0f5b664d98deb + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + file_collaborations: + streamHash: b57e258db538c594ace1cba278854f0702bbe926 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + folder_collaborations: + streamHash: 9154707962f8ebc5736593f901aa484ba6aa3d34 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + file_comments: + streamHash: 2711d975ffe518367db630ef6dc0c2598b5cb86d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + recent_items: + streamHash: a220c9ba1787d7da58f2d496a76a176600c800ff + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + file_tasks: + streamHash: b7cdc6e9b385a24c4f491d8b820a6924bd52070f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + trashed_items: + hasRecords: true + streamHash: 220c9d1eb25065d60d7347c9219ae6882b3bfdb4 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + users: + streamHash: 0e26a32514f04fae7185887ae41861452eb580f7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + folders: + streamHash: e8aee8caba4e6a759ead1aa1b2b20f27f6d690de + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://developer.box.com/reference/ + +schemas: + events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + additional_details: + type: + - object + - "null" + properties: + original_item_id: + type: + - string + - "null" + original_item_name: + type: + - string + - "null" + original_item_type: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + login: + type: + - string + - "null" + name: + type: + - string + - "null" + event_id: + type: + - string + - "null" + event_type: + type: + - string + - "null" + recorded_at: + type: + - string + - "null" + session_id: + type: + - string + - "null" + source: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + assigned_at: + type: + - string + - "null" + assigned_by: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + login: + type: + - string + - "null" + name: + type: + - string + - "null" + assigned_to: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + login: + type: + - string + - "null" + name: + type: + - string + - "null" + content_created_at: + type: + - string + - "null" + content_modified_at: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + login: + type: + - string + - "null" + name: + type: + - string + - "null" + etag: + type: + - string + - "null" + file_version: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + id: + type: + - string + - "null" + invite_email: + type: + - string + - "null" + is_reply_comment: + type: + - boolean + - "null" + item: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + etag: + type: + - string + - "null" + file_version: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + item_status: + type: + - string + - "null" + message: + type: + - string + - "null" + modified_at: + type: + - string + - "null" + modified_by: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + login: + type: + - string + - "null" + name: + type: + - string + - "null" + name: + type: + - string + - "null" + owned_by: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + login: + type: + - string + - "null" + name: + type: + - string + - "null" + parent: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + etag: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + path_collection: + type: + - object + - "null" + properties: + entries: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + etag: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + total_count: + type: + - number + - "null" + purged_at: + type: + - string + - "null" + resolution_state: + type: + - string + - "null" + role: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + size: + type: + - number + - "null" + status: + type: + - string + - "null" + synced: + type: + - boolean + - "null" + trashed_at: + type: + - string + - "null" + sign_templates: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + additional_info: + type: + - object + - "null" + properties: + non_editable: + type: + - array + - "null" + required: + type: + - object + - "null" + properties: + signers: + type: + - array + - "null" + items: + type: + - array + - "null" + items: + type: + - string + - "null" + are_email_settings_locked: + type: + - boolean + - "null" + are_fields_locked: + type: + - boolean + - "null" + are_files_locked: + type: + - boolean + - "null" + are_options_locked: + type: + - boolean + - "null" + are_recipients_locked: + type: + - boolean + - "null" + days_valid: + type: + - number + - "null" + email_message: + type: + - string + - "null" + email_subject: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + parent_folder: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + etag: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + signers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + inputs: + type: + - array + - "null" + is_in_person: + type: + - boolean + - "null" + label: + type: + - string + - "null" + order: + type: + - number + - "null" + public_id: + type: + - string + - "null" + role: + type: + - string + - "null" + source_files: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + etag: + type: + - string + - "null" + file_version: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + required: + - id + collections: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + collection_type: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + required: + - id + collection_items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + etag: + type: + - string + - "null" + file_version: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + required: + - id + sign_request: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + are_reminders_enabled: + type: + - boolean + - "null" + are_text_signatures_enabled: + type: + - boolean + - "null" + id: + type: string + is_document_preparation_needed: + type: + - boolean + - "null" + is_phone_verification_required_to_view: + type: + - boolean + - "null" + name: + type: + - string + - "null" + parent_folder: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + etag: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + prefill_tags: + type: + - array + - "null" + sign_files: + type: + - object + - "null" + properties: + files: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + etag: + type: + - string + - "null" + file_version: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + is_ready_for_download: + type: + - boolean + - "null" + signers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + has_viewed_document: + type: + - boolean + - "null" + inputs: + type: + - array + - "null" + is_in_person: + type: + - boolean + - "null" + login_required: + type: + - boolean + - "null" + order: + type: + - number + - "null" + role: + type: + - string + - "null" + suppress_notifications: + type: + - boolean + - "null" + verification_phone_number: + type: + - string + - "null" + source_files: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + etag: + type: + - string + - "null" + file_version: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + status: + type: + - string + - "null" + required: + - id + admin_logs: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + accessible_by: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + login: + type: + - string + - "null" + name: + type: + - string + - "null" + additional_details: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + metadata: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + operationParams: + type: + - string + - "null" + access_token_identifier: + type: + - string + - "null" + collab_id: + type: + - string + - "null" + collection: + type: + - object + - "null" + properties: + collection_id: + type: + - number + - "null" + collection_name: + type: + - string + - "null" + user: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + collection_item: + type: + - object + - "null" + properties: + collection_id: + type: + - number + - "null" + collection_name: + type: + - string + - "null" + item: + type: + - object + - "null" + properties: + file: + type: + - number + - "null" + user: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + comment_id: + type: + - number + - "null" + ekm_id: + type: + - string + - "null" + invitation_message: + type: + - string + - "null" + is_performed_by_admin: + type: + - boolean + - "null" + message: + type: + - string + - "null" + original_item_id: + type: + - string + - "null" + original_item_name: + type: + - string + - "null" + original_item_type: + type: + - string + - "null" + role: + type: + - string + - "null" + service_id: + type: + - string + - "null" + service_name: + type: + - string + - "null" + sharedLinkSettings: + type: + - object + - "null" + properties: + newCanDownload: + type: + - boolean + - "null" + newCanEdit: + type: + - boolean + - "null" + newCanPreview: + type: + - boolean + - "null" + newIsExpirationDateSet: + type: + - boolean + - "null" + newIsPasswordProtected: + type: + - boolean + - "null" + newVisibilityStatus: + type: + - string + - "null" + shared_link_id: + type: + - string + - "null" + sign_request: + type: + - object + - "null" + properties: + files: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + parent: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + ready_sign_link: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + redirection: + type: + - object + - "null" + properties: + declined_redirect_url: + type: + - string + - "null" + redirect_url: + type: + - string + - "null" + requestor: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + login: + type: + - string + - "null" + name: + type: + - string + - "null" + requestor_ip_address: + type: + - string + - "null" + sender_message: + type: + - object + - "null" + properties: + message: + type: + - string + - "null" + subject: + type: + - string + - "null" + sign_request_id: + type: + - string + - "null" + sign_request_short_id: + type: + - string + - "null" + signer: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + login: + type: + - string + - "null" + name: + type: + - string + - "null" + signer_ip_address: + type: + - string + - "null" + status: + type: + - string + - "null" + size: + type: + - number + - "null" + task: + type: + - object + - "null" + properties: + created_by: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + login: + type: + - string + - "null" + due_at: + type: + - string + - "null" + id: + type: + - number + - "null" + message: + type: + - string + - "null" + task_assignment: + type: + - object + - "null" + properties: + assigned_to: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + login: + type: + - string + - "null" + message: + type: + - string + - "null" + status: + type: + - string + - "null" + version_id: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + login: + type: + - string + - "null" + name: + type: + - string + - "null" + event_id: + type: string + event_type: + type: + - string + - "null" + ip_address: + type: + - string + - "null" + source: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + file_id: + type: + - string + - "null" + file_name: + type: + - string + - "null" + folder_id: + type: + - string + - "null" + folder_name: + type: + - string + - "null" + id: + type: + - string + - "null" + item_id: + type: + - string + - "null" + item_name: + type: + - string + - "null" + item_type: + type: + - string + - "null" + login: + type: + - string + - "null" + name: + type: + - string + - "null" + owned_by: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + login: + type: + - string + - "null" + name: + type: + - string + - "null" + parent: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + user_email: + type: + - string + - "null" + required: + - event_id + files: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + etag: + type: + - string + - "null" + file_version: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + required: + - id + file_collaborations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + login: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: string + invite_email: + type: + - string + - "null" + is_access_only: + type: + - boolean + - "null" + item: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + etag: + type: + - string + - "null" + file_version: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + modified_at: + type: + - string + - "null" + role: + type: + - string + - "null" + status: + type: + - string + - "null" + required: + - id + folder_collaborations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + login: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: string + invite_email: + type: + - string + - "null" + is_access_only: + type: + - boolean + - "null" + item: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + etag: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + modified_at: + type: + - string + - "null" + role: + type: + - string + - "null" + status: + type: + - string + - "null" + required: + - id + file_comments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + login: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: string + is_reply_comment: + type: + - boolean + - "null" + message: + type: + - string + - "null" + required: + - id + recent_items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + etag: + type: + - string + - "null" + file_version: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + required: + - id + file_tasks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + assigned_at: + type: + - string + - "null" + assigned_to: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + login: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: string + item: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + etag: + type: + - string + - "null" + file_version: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + message: + type: + - string + - "null" + resolution_state: + type: + - string + - "null" + status: + type: + - string + - "null" + required: + - id + trashed_items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + etag: + type: + - string + - "null" + file_version: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + sha1: + type: + - string + - "null" + required: + - id + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + address: + type: + - string + - "null" + avatar_url: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: string + job_title: + type: + - string + - "null" + language: + type: + - string + - "null" + login: + type: + - string + - "null" + max_upload_size: + type: + - number + - "null" + modified_at: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + space_amount: + type: + - number + - "null" + space_used: + type: + - number + - "null" + status: + type: + - string + - "null" + timezone: + type: + - string + - "null" + required: + - id + folders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + etag: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-box/metadata.yaml b/airbyte-integrations/connectors/source-box/metadata.yaml new file mode 100644 index 000000000000..77ae8aadeb96 --- /dev/null +++ b/airbyte-integrations/connectors/source-box/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.box.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-box + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 3eab5d94-2e12-4bca-ab0c-3af869b2dcd8 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-box + githubIssueLabel: source-box + icon: icon.svg + license: MIT + name: Box + releaseDate: 2024-10-24 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/box + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-braintree/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-braintree/integration_tests/acceptance.py index 43ce950d77ca..72132012aaed 100644 --- a/airbyte-integrations/connectors/source-braintree/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-braintree/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-braintree/main.py b/airbyte-integrations/connectors/source-braintree/main.py index d4ae7bec5223..2b5b482a3bcd 100644 --- a/airbyte-integrations/connectors/source-braintree/main.py +++ b/airbyte-integrations/connectors/source-braintree/main.py @@ -4,5 +4,6 @@ from source_braintree.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-braintree/metadata.yaml b/airbyte-integrations/connectors/source-braintree/metadata.yaml index b5d07fa241a5..7ce66087cdd8 100644 --- a/airbyte-integrations/connectors/source-braintree/metadata.yaml +++ b/airbyte-integrations/connectors/source-braintree/metadata.yaml @@ -5,7 +5,7 @@ data: connectorSubtype: api connectorType: source definitionId: 63cea06f-1c75-458d-88fe-ad48c7cb27fd - dockerImageTag: 0.3.20 + dockerImageTag: 0.3.25 dockerRepository: airbyte/source-braintree documentationUrl: https://docs.airbyte.com/integrations/sources/braintree githubIssueLabel: source-braintree @@ -25,7 +25,7 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 releaseStage: alpha supportLevel: community tags: diff --git a/airbyte-integrations/connectors/source-braintree/poetry.lock b/airbyte-integrations/connectors/source-braintree/poetry.lock index 8d1cf6f51f83..a1b7a5c38a00 100644 --- a/airbyte-integrations/connectors/source-braintree/poetry.lock +++ b/airbyte-integrations/connectors/source-braintree/poetry.lock @@ -61,19 +61,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -102,13 +102,13 @@ files = [ [[package]] name = "braintree" -version = "4.30.0" +version = "4.31.0" description = "Braintree Python Library" optional = false python-versions = "*" files = [ - {file = "braintree-4.30.0-py2.py3-none-any.whl", hash = "sha256:a0a754439155c820e14db9e637d648a3c848be895c00c941bc1e0f9521bce3d3"}, - {file = "braintree-4.30.0.tar.gz", hash = "sha256:3b7fa20d1eb76737da4dd170c09df39d6b6eeb3625ed68a6520bbbe5aa66c0fb"}, + {file = "braintree-4.31.0-py2.py3-none-any.whl", hash = "sha256:426011f92418703809007f387c3ce13b03535ad6f67244171ff2b417369e3693"}, + {file = "braintree-4.31.0.tar.gz", hash = "sha256:de383469ae0f824efba7e2d726c13927090d6a9305e1c49de1cb258b2868d43d"}, ] [package.dependencies] @@ -153,127 +153,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -289,20 +276,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -380,13 +367,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -499,13 +486,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -651,54 +638,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -919,33 +906,33 @@ yaml = ["pyyaml (>=6.0.1)"] [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -997,13 +984,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1028,81 +1015,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-braintree/pyproject.toml b/airbyte-integrations/connectors/source-braintree/pyproject.toml index 35c60e1503e9..d10761c4401e 100644 --- a/airbyte-integrations/connectors/source-braintree/pyproject.toml +++ b/airbyte-integrations/connectors/source-braintree/pyproject.toml @@ -3,7 +3,7 @@ requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.3.20" +version = "0.3.25" name = "source-braintree" description = "Source implementation for Braintree." authors = ["Airbyte "] diff --git a/airbyte-integrations/connectors/source-braintree/source_braintree/schemas/common.py b/airbyte-integrations/connectors/source-braintree/source_braintree/schemas/common.py index 7ca4cc60abfd..6e8e40f64845 100644 --- a/airbyte-integrations/connectors/source-braintree/source_braintree/schemas/common.py +++ b/airbyte-integrations/connectors/source-braintree/source_braintree/schemas/common.py @@ -6,10 +6,11 @@ from typing import Any, Dict, Optional, Type import pydantic -from airbyte_cdk.sources.utils.schema_helpers import expand_refs from pydantic import BaseModel from pydantic.typing import resolve_annotations +from airbyte_cdk.sources.utils.schema_helpers import expand_refs + class AllOptional(pydantic.main.ModelMetaclass): """ diff --git a/airbyte-integrations/connectors/source-braintree/source_braintree/source.py b/airbyte-integrations/connectors/source-braintree/source_braintree/source.py index 29d30182144c..15d9235267c9 100644 --- a/airbyte-integrations/connectors/source-braintree/source_braintree/source.py +++ b/airbyte-integrations/connectors/source-braintree/source_braintree/source.py @@ -6,9 +6,6 @@ from typing import List, Union import requests -from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor -from airbyte_cdk.sources.declarative.types import Record -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource from braintree.attribute_getter import AttributeGetter from braintree.customer import Customer as BCustomer from braintree.discount import Discount as BDiscount @@ -18,8 +15,13 @@ from braintree.subscription import Subscription as BSubscription from braintree.transaction import Transaction as BTransaction from braintree.util.xml_util import XmlUtil + +from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor +from airbyte_cdk.sources.declarative.types import Record +from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource from source_braintree.schemas import Customer, Discount, Dispute, MerchantAccount, Plan, Subscription, Transaction + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-braze/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-braze/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-braze/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-braze/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-braze/main.py b/airbyte-integrations/connectors/source-braze/main.py index 723116b28098..28735b4616de 100644 --- a/airbyte-integrations/connectors/source-braze/main.py +++ b/airbyte-integrations/connectors/source-braze/main.py @@ -4,5 +4,6 @@ from source_braze.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-braze/setup.py b/airbyte-integrations/connectors/source-braze/setup.py index 43f778382f75..eab5b4e0fd40 100644 --- a/airbyte-integrations/connectors/source-braze/setup.py +++ b/airbyte-integrations/connectors/source-braze/setup.py @@ -5,6 +5,7 @@ from setuptools import find_packages, setup + MAIN_REQUIREMENTS = [ "airbyte-cdk", ] diff --git a/airbyte-integrations/connectors/source-braze/source_braze/components.py b/airbyte-integrations/connectors/source-braze/source_braze/components.py index 06e003ec51d8..0771877d7c63 100644 --- a/airbyte-integrations/connectors/source-braze/source_braze/components.py +++ b/airbyte-integrations/connectors/source-braze/source_braze/components.py @@ -5,6 +5,7 @@ from dataclasses import dataclass import requests + from airbyte_cdk.sources.declarative.extractors.dpath_extractor import DpathExtractor from airbyte_cdk.sources.declarative.types import Record diff --git a/airbyte-integrations/connectors/source-braze/source_braze/run.py b/airbyte-integrations/connectors/source-braze/source_braze/run.py index 645b7a31df24..c2b1033fb4df 100644 --- a/airbyte-integrations/connectors/source-braze/source_braze/run.py +++ b/airbyte-integrations/connectors/source-braze/source_braze/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_braze import SourceBraze +from airbyte_cdk.entrypoint import launch + def run(): source = SourceBraze() diff --git a/airbyte-integrations/connectors/source-braze/source_braze/source.py b/airbyte-integrations/connectors/source-braze/source_braze/source.py index df957f37fb67..44e98d1eb706 100644 --- a/airbyte-integrations/connectors/source-braze/source_braze/source.py +++ b/airbyte-integrations/connectors/source-braze/source_braze/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-braze/source_braze/transformations.py b/airbyte-integrations/connectors/source-braze/source_braze/transformations.py index 60a13384e269..bd95bdf646a5 100644 --- a/airbyte-integrations/connectors/source-braze/source_braze/transformations.py +++ b/airbyte-integrations/connectors/source-braze/source_braze/transformations.py @@ -6,6 +6,7 @@ from typing import Optional import dpath + from airbyte_cdk.sources.declarative.transformations import AddFields from airbyte_cdk.sources.declarative.types import Config, Record, StreamSlice, StreamState diff --git a/airbyte-integrations/connectors/source-braze/unit_tests/test_datetime_incremental_sync.py b/airbyte-integrations/connectors/source-braze/unit_tests/test_datetime_incremental_sync.py index d478ac686adc..76ff085244e8 100644 --- a/airbyte-integrations/connectors/source-braze/unit_tests/test_datetime_incremental_sync.py +++ b/airbyte-integrations/connectors/source-braze/unit_tests/test_datetime_incremental_sync.py @@ -2,9 +2,10 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # +from source_braze import DatetimeIncrementalSyncComponent + from airbyte_cdk.sources.declarative.requesters import RequestOption from airbyte_cdk.sources.declarative.requesters.request_option import RequestOptionType -from source_braze import DatetimeIncrementalSyncComponent def test_datetime_slicer(): diff --git a/airbyte-integrations/connectors/source-braze/unit_tests/test_transformations.py b/airbyte-integrations/connectors/source-braze/unit_tests/test_transformations.py index 2ed02ec26eaa..00314360102a 100644 --- a/airbyte-integrations/connectors/source-braze/unit_tests/test_transformations.py +++ b/airbyte-integrations/connectors/source-braze/unit_tests/test_transformations.py @@ -2,9 +2,10 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # -from airbyte_cdk.sources.declarative.transformations.add_fields import AddedFieldDefinition from source_braze import TransformToRecordComponent +from airbyte_cdk.sources.declarative.transformations.add_fields import AddedFieldDefinition + def test_string_to_dict_transformation(): """ diff --git a/airbyte-integrations/connectors/source-breezometer/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-breezometer/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-breezometer/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-breezometer/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-breezometer/metadata.yaml b/airbyte-integrations/connectors/source-breezometer/metadata.yaml index 591b12beddc9..f9d3972c520a 100644 --- a/airbyte-integrations/connectors/source-breezometer/metadata.yaml +++ b/airbyte-integrations/connectors/source-breezometer/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 7c37685e-8512-4901-addf-9afbef6c0de9 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.8 dockerRepository: airbyte/source-breezometer githubIssueLabel: source-breezometer icon: breezometer.svg @@ -38,5 +38,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-breezy-hr/metadata.yaml b/airbyte-integrations/connectors/source-breezy-hr/metadata.yaml index 94b66434448c..9ffb4c9ec5e3 100644 --- a/airbyte-integrations/connectors/source-breezy-hr/metadata.yaml +++ b/airbyte-integrations/connectors/source-breezy-hr/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-breezy-hr connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: bc2c2e4f-41a1-40e3-9e82-eea19cf958ff - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-breezy-hr githubIssueLabel: source-breezy-hr icon: icon.svg diff --git a/airbyte-integrations/connectors/source-brex/README.md b/airbyte-integrations/connectors/source-brex/README.md new file mode 100644 index 000000000000..d6fa23bf4c87 --- /dev/null +++ b/airbyte-integrations/connectors/source-brex/README.md @@ -0,0 +1,33 @@ +# Brex +This directory contains the manifest-only connector for `source-brex`. + +Fetches data on users, expenses, transactions, vendors, and budgets from Brex API. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-brex:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-brex build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-brex test +``` + diff --git a/airbyte-integrations/connectors/source-brex/acceptance-test-config.yml b/airbyte-integrations/connectors/source-brex/acceptance-test-config.yml new file mode 100644 index 000000000000..352887b11a2e --- /dev/null +++ b/airbyte-integrations/connectors/source-brex/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-brex:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-brex/icon.svg b/airbyte-integrations/connectors/source-brex/icon.svg new file mode 100644 index 000000000000..244b5e327edf --- /dev/null +++ b/airbyte-integrations/connectors/source-brex/icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/airbyte-integrations/connectors/source-brex/manifest.yaml b/airbyte-integrations/connectors/source-brex/manifest.yaml new file mode 100644 index 000000000000..3a6c6869bfd1 --- /dev/null +++ b/airbyte-integrations/connectors/source-brex/manifest.yaml @@ -0,0 +1,419 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + Fetches data on users, expenses, transactions, vendors, and budgets from Brex + API. + +check: + type: CheckStream + stream_names: + - transactions + +definitions: + streams: + transactions: + type: DeclarativeStream + name: transactions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/transactions/card/primary + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('next_cursor') }}" + stop_condition: "{{ response.get('next_cursor') is none }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: posted_at_date + lookback_window: P1D + cursor_datetime_formats: + - "%Y-%m-%d" + datetime_format: "%Y-%m-%dT%H:%M:%S" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: posted_at_start + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/transactions" + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('next_cursor') }}" + stop_condition: "{{ response.get('next_cursor') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + departments: + type: DeclarativeStream + name: departments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/departments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('next_cursor') }}" + stop_condition: "{{ response.get('next_cursor') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/departments" + vendors: + type: DeclarativeStream + name: vendors + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v1/vendors + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('next_cursor') }}" + stop_condition: "{{ response.get('next_cursor') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/vendors" + expenses: + type: DeclarativeStream + name: expenses + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v1/expenses/card + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('next_cursor') }}" + stop_condition: "{{ response.get('next_cursor') is none }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: purchased_at + lookback_window: P1M + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%dT%H:%M:%S.%fZ" + datetime_format: "%Y-%m-%dT%H:%M:%S" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: purchased_at_start + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: purchased_at_end + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/expenses" + budgets: + type: DeclarativeStream + name: budgets + primary_key: + - budget_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/budgets + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('next_cursor') }}" + stop_condition: "{{ response.get('next_cursor') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/budgets" + base_requester: + type: HttpRequester + url_base: https://platform.brexapis.com + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"user_token\"] }}" + +streams: + - $ref: "#/definitions/streams/transactions" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/departments" + - $ref: "#/definitions/streams/vendors" + - $ref: "#/definitions/streams/expenses" + - $ref: "#/definitions/streams/budgets" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - user_token + - start_date + properties: + user_token: + type: string + description: >- + User token to authenticate API requests. Generate it from your Brex + dashboard under Developer > Settings. + name: user_token + title: User Token + airbyte_secret: true + order: 0 + start_date: + type: string + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + order: 1 + additionalProperties: true + +metadata: + autoImportSchema: + transactions: true + users: false + departments: false + vendors: false + expenses: false + budgets: false + testedStreams: + transactions: + streamHash: 9095688de0c91a5eafb2969f27859182d0eb1329 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + users: + streamHash: 22fb9114f7bec24f5b753c0eed981138105cd5e6 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + departments: + streamHash: 3a7de8adfde28e720a9f9254c63103d34bfc3966 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + vendors: + streamHash: 678154fbac1bda4601d2a9ce17e8e4283df96e22 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + expenses: + streamHash: 83d3aa00696a8b74df332824a39fbcf75bdebd7d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + budgets: + streamHash: 9bfb438f0d1d68b61814339b4153e4904088baaa + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://developer.brex.com/openapi/transactions_api/ + +schemas: + transactions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + amount: + type: + - object + - "null" + properties: + amount: + type: + - number + - "null" + currency: + type: + - string + - "null" + card_id: + type: + - string + - "null" + id: + type: string + initiated_at_date: + type: + - string + - "null" + merchant: + type: + - object + - "null" + properties: + country: + type: + - string + - "null" + mcc: + type: + - string + - "null" + raw_descriptor: + type: + - string + - "null" + posted_at_date: + type: string + required: + - id + - posted_at_date + users: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} + departments: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} + vendors: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} + expenses: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} + budgets: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} diff --git a/airbyte-integrations/connectors/source-brex/metadata.yaml b/airbyte-integrations/connectors/source-brex/metadata.yaml new file mode 100644 index 000000000000..6e17c084847d --- /dev/null +++ b/airbyte-integrations/connectors/source-brex/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "platform.brexapis.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-brex + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 7d605ca7-f2b8-41c4-96a7-3d5637e58d6d + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-brex + githubIssueLabel: source-brex + icon: icon.svg + license: MIT + name: Brex + releaseDate: 2024-10-30 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/brex + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-bugsnag/metadata.yaml b/airbyte-integrations/connectors/source-bugsnag/metadata.yaml index 5b6f37ac44ca..bf4a9e525085 100644 --- a/airbyte-integrations/connectors/source-bugsnag/metadata.yaml +++ b/airbyte-integrations/connectors/source-bugsnag/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-bugsnag connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.13.0@sha256:ffc5977f59e1f38bf3f5dd70b6fa0520c2450ebf85153c5a8df315b8c918d5c3 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: fa6c7629-0556-4b29-9f2c-7f6f4e54e997 - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.5 dockerRepository: airbyte/source-bugsnag githubIssueLabel: source-bugsnag icon: icon.svg diff --git a/airbyte-integrations/connectors/source-buildkite/metadata.yaml b/airbyte-integrations/connectors/source-buildkite/metadata.yaml index ec08ef637f74..08f6038a81d1 100644 --- a/airbyte-integrations/connectors/source-buildkite/metadata.yaml +++ b/airbyte-integrations/connectors/source-buildkite/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-buildkite connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 9b0d6e72-5c85-40a3-af88-3a8f7c65746f - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-buildkite githubIssueLabel: source-buildkite icon: icon.svg diff --git a/airbyte-integrations/connectors/source-bunny-inc/README.md b/airbyte-integrations/connectors/source-bunny-inc/README.md new file mode 100644 index 000000000000..6d8d5d4568b1 --- /dev/null +++ b/airbyte-integrations/connectors/source-bunny-inc/README.md @@ -0,0 +1,33 @@ +# Bunny, Inc. +This directory contains the manifest-only connector for `source-bunny-inc`. + +Synchronizes Bunny data + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-bunny-inc:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-bunny-inc build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-bunny-inc test +``` + diff --git a/airbyte-integrations/connectors/source-bunny-inc/acceptance-test-config.yml b/airbyte-integrations/connectors/source-bunny-inc/acceptance-test-config.yml new file mode 100644 index 000000000000..46a114fcedf0 --- /dev/null +++ b/airbyte-integrations/connectors/source-bunny-inc/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-bunny-inc:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-bunny-inc/icon.svg b/airbyte-integrations/connectors/source-bunny-inc/icon.svg new file mode 100644 index 000000000000..a395862217ae --- /dev/null +++ b/airbyte-integrations/connectors/source-bunny-inc/icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/airbyte-integrations/connectors/source-bunny-inc/manifest.yaml b/airbyte-integrations/connectors/source-bunny-inc/manifest.yaml new file mode 100644 index 000000000000..4fb66f1e0040 --- /dev/null +++ b/airbyte-integrations/connectors/source-bunny-inc/manifest.yaml @@ -0,0 +1,2110 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: Synchronizes Bunny data + +check: + type: CheckStream + stream_names: + - accounts + - accountBalances + - contacts + - entities + - invoices + - invoiceItems + - payments + - products + - plans + - quotes + - quote_charges + - subscriptions + - subscriptionCharges + - transactions + - tenants + +definitions: + streams: + plans: + type: DeclarativeStream + name: plans + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: variables + inject_into: body_json + pagination_strategy: + type: CursorPagination + cursor_value: >- + {{ '{"after": "' + response.data.plans.pageInfo.endCursor + '"}' + if response.data.plans.pageInfo.endCursor else "" }} + stop_condition: "{{ response.data.plans.pageInfo.hasNextPage is false }}" + requester: + $ref: "#/definitions/base_requester" + path: /graphql + http_method: POST + request_body_json: + query: >- + query($after: String) { plans(first: 10, after: $after) { nodes { + id addon basePrice code contactUsLabel contactUsUrl + createdAt description id internalNotes isVisible name position + pricingDescription productId productPlanName selfServiceBuy + selfServiceCancel selfServiceRenew updatedAt } pageInfo { + startCursor endCursor hasNextPage hasPreviousPage } } } + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - plans + - nodes + - "*" + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/plans" + quotes: + type: DeclarativeStream + name: quotes + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: variables + inject_into: body_json + pagination_strategy: + type: CursorPagination + cursor_value: >- + {{ '{"after": "' + response.data.quotes.pageInfo.endCursor + '"}' + if response.data.quotes.pageInfo.endCursor else "" }} + stop_condition: "{{ response.data.quotes.pageInfo.hasNextPage is false }}" + requester: + $ref: "#/definitions/base_requester" + path: /graphql + http_method: POST + request_body_json: + query: >- + query($after: String) { quotes(first: 10, after: $after) { nodes { + id acceptedByName acceptedByTitle accountId amount + amountDue applicationDate backdatedPeriods backdatedQuote + billingDay contactId createdAt credits currencyId dealId discount + discountValue evergreen id message name netPaymentDays notes + number ownerId payableId periodAmount poNumber smallUnitAmountDue + splitInvoice subtotal taxAmount taxCode updatedAt uuid } pageInfo + { startCursor endCursor hasNextPage hasPreviousPage } } } + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - quotes + - nodes + - "*" + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/quotes" + tenants: + type: DeclarativeStream + name: tenants + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: variables + inject_into: body_json + pagination_strategy: + type: CursorPagination + cursor_value: >- + {{ '{"after": "' + response.data.tenants.pageInfo.endCursor + '"}' + if response.data.tenants.pageInfo.endCursor else "" }} + stop_condition: "{{ response.data.tenants.pageInfo.hasNextPage is false }}" + requester: + $ref: "#/definitions/base_requester" + path: /graphql + http_method: POST + request_body_json: + query: >- + query($after: String) { tenants(first: 10, after: $after) { nodes + { id accountId code createdAt id lastLogin + latestProvisioningChangeId name platformId provisioningRequired + provisioningState subdomain updatedAt userCount utilizationMetrics + } pageInfo { startCursor endCursor hasNextPage hasPreviousPage } } + } + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - tenants + - nodes + - "*" + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tenants" + accounts: + type: DeclarativeStream + name: accounts + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: variables + inject_into: body_json + pagination_strategy: + type: CursorPagination + cursor_value: >- + {{ '{"after": "' + response.data.accounts.pageInfo.endCursor + + '"}' if response.data.accounts.pageInfo.endCursor else "" }} + stop_condition: "{{ response.data.accounts.pageInfo.hasNextPage is false }}" + requester: + $ref: "#/definitions/base_requester" + path: /graphql + http_method: POST + request_body_json: + query: >- + query($after: String) { accounts(first: 10, after: $after) { nodes + { id accountTypeId annualRevenue billingCity + billingContactId billingCountry billingDay billingState + billingStreet billingZip code createdAt currencyId description + duns employees entityId entityUseCode fax groupId id industryId + invoiceTemplateId linkedinUrl name netPaymentDays ownerUserId + payingStatus phone shippingCity shippingCountry shippingState + shippingStreet shippingZip taxNumber taxNumberValidated timezone + updatedAt website } pageInfo { startCursor endCursor hasNextPage + hasPreviousPage } } } + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - accounts + - nodes + - "*" + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounts" + contacts: + type: DeclarativeStream + name: contacts + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: variables + inject_into: body_json + pagination_strategy: + type: CursorPagination + cursor_value: >- + {{ '{"after": "' + response.data.contacts.pageInfo.endCursor + + '"}' if response.data.contacts.pageInfo.endCursor else "" }} + stop_condition: "{{ response.data.contacts.pageInfo.hasNextPage is false }}" + requester: + $ref: "#/definitions/base_requester" + path: /graphql + http_method: POST + request_body_json: + query: >- + query($after: String) { contacts(first: 10, after: $after) { nodes + { id accountId code createdAt description email + entityId firstName fullName id lastName linkedinUrl mailingCity + mailingCountry mailingState mailingStreet mailingZip mobile phone + portalAccess salutation title updatedAt } pageInfo { startCursor + endCursor hasNextPage hasPreviousPage } } } + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - contacts + - nodes + - "*" + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + entities: + type: DeclarativeStream + name: entities + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: variables + inject_into: body_json + pagination_strategy: + type: CursorPagination + cursor_value: >- + {{ '{"after": "' + response.data.entities.pageInfo.endCursor + + '"}' if response.data.entities.pageInfo.endCursor else "" }} + stop_condition: "{{ response.data.entities.pageInfo.hasNextPage is false }}" + requester: + $ref: "#/definitions/base_requester" + path: /graphql + http_method: POST + request_body_json: + query: >- + query($after: String) { entities(first: 10, after: $after) { nodes + { id abbreviation accentColor baseCurrencyId + billingCity billingCountry billingState billingStreet billingZip + brandColor createdAt customerServiceEmail + defaultAccountsReceivableAccountId defaultBankingFeesAccountId + defaultConversionGainAccountId defaultConversionLossAccountId + defaultCpcaAccountId defaultDeferredRevenueAccountId + defaultPaymentAccountId defaultRecognizedRevenueAccountId + defaultTaxPayableAccountId emailSenderName emailTemplate fax + fiscalYearStartMonth id invoiceNumberPrefix invoiceNumberSeq + invoicesImageUrl isDefault name phone privacyUrl quoteNumberPrefix + quoteNumberSeq quotesImageUrl refundPolicyUrl taxId taxType + termsUrl timezone topNavImageUrl updatedAt website } pageInfo { + startCursor endCursor hasNextPage hasPreviousPage } } } + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - entities + - nodes + - "*" + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/entities" + invoices: + type: DeclarativeStream + name: invoices + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: variables + inject_into: body_json + pagination_strategy: + type: CursorPagination + cursor_value: >- + {{ '{"after": "' + response.data.invoices.pageInfo.endCursor + + '"}' if response.data.invoices.pageInfo.endCursor else "" }} + stop_condition: "{{ response.data.invoices.pageInfo.hasNextPage is false }}" + requester: + $ref: "#/definitions/base_requester" + path: /graphql + http_method: POST + request_body_json: + query: >- + query($after: String) { invoices(first: 10, after: $after) { nodes + { id accountId amount amountDue amountPaid createdAt + credits currencyId description dueAt id netPaymentDays number + paidAt payableId poNumber portalUrl quoteId smallUnitAmountDue + subtotal taxAmount updatedAt url uuid } pageInfo { startCursor + endCursor hasNextPage hasPreviousPage } } } + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - invoices + - nodes + - "*" + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/invoices" + payments: + type: DeclarativeStream + name: payments + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: variables + inject_into: body_json + pagination_strategy: + type: CursorPagination + cursor_value: >- + {{ '{"after": "' + response.data.payments.pageInfo.endCursor + + '"}' if response.data.payments.pageInfo.endCursor else "" }} + stop_condition: "{{ response.data.payments.pageInfo.hasNextPage is false }}" + requester: + $ref: "#/definitions/base_requester" + path: /graphql + http_method: POST + request_body_json: + query: >- + query($after: String) { payments(first: 10, after: $after) { nodes + { id accountId amount amountUnapplied + baseCurrencyCash baseCurrencyId createdAt currencyId description + id isLegacy memo receivedAt updatedAt } pageInfo { startCursor + endCursor hasNextPage hasPreviousPage } } } + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - payments + - nodes + - "*" + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/payments" + products: + type: DeclarativeStream + name: products + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: variables + inject_into: body_json + pagination_strategy: + type: CursorPagination + cursor_value: >- + {{ '{"after": "' + response.data.products.pageInfo.endCursor + + '"}' if response.data.products.pageInfo.endCursor else "" }} + stop_condition: "{{ response.data.products.pageInfo.hasNextPage is false }}" + requester: + $ref: "#/definitions/base_requester" + path: /graphql + http_method: POST + request_body_json: + query: >- + query($after: String) { products(first: 10, after: $after) { nodes + { id code description everythingInPlus id + internalNotes name platformId productCategoryId + showProductNameOnLineItem } pageInfo { startCursor endCursor + hasNextPage hasPreviousPage } } } + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - products + - nodes + - "*" + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + invoiceItems: + type: DeclarativeStream + name: invoiceItems + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: variables + inject_into: body_json + pagination_strategy: + type: CursorPagination + cursor_value: >- + {{ '{"after": "' + response.data.invoiceItems.pageInfo.endCursor + + '"}' if response.data.invoiceItems.pageInfo.endCursor else "" }} + stop_condition: "{{ response.data.invoiceItems.pageInfo.hasNextPage is false }}" + requester: + $ref: "#/definitions/base_requester" + path: /graphql + http_method: POST + request_body_json: + query: >- + query($after: String) { invoiceItems(first: 10, after: $after) { + nodes { id amount chargeType couponId currencyId + discount id invoiceId lineText position price priceDecimals + priceListId pricingModel prorationRate quantity subtotal taxAmount + taxCode unitOfMeasure vatCode } pageInfo { startCursor endCursor + hasNextPage hasPreviousPage } } } + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - invoiceItems + - nodes + - "*" + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/invoiceItems" + transactions: + type: DeclarativeStream + name: transactions + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: variables + inject_into: body_json + pagination_strategy: + type: CursorPagination + cursor_value: >- + {{ '{"after": "' + response.data.transactions.pageInfo.endCursor + + '"}' if response.data.transactions.pageInfo.endCursor else "" }} + stop_condition: "{{ response.data.transactions.pageInfo.hasNextPage is false }}" + requester: + $ref: "#/definitions/base_requester" + path: /graphql + http_method: POST + request_body_json: + query: >- + query($after: String) { transactions(first: 10, after: $after) { + nodes { id accountId amount createdAt currencyId + description dueAt id state transactionableId } pageInfo { + startCursor endCursor hasNextPage hasPreviousPage } } } + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - transactions + - nodes + - "*" + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/transactions" + quote_charges: + type: DeclarativeStream + name: quote_charges + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: variables + inject_into: body_json + pagination_strategy: + type: CursorPagination + cursor_value: >- + {{ '{"after": "' + response.data.quote_charges.pageInfo.endCursor + + '"}' if response.data.quote_charges.pageInfo.endCursor else "" + }} + stop_condition: "{{ response.data.quote_charges.pageInfo.hasNextPage is false }}" + requester: + $ref: "#/definitions/base_requester" + path: /graphql + http_method: POST + request_body_json: + query: >- + query($after: String) { quote_charges(first: 10, after: $after) { + nodes { id amount billingPeriod chargeType couponId + createdAt currencyId currentQuantity discount id invoiceLineText + kind name price priceDecimals priceListChargeId pricingModel + prorationRate quantity quantityMax quantityMin quoteChangeId + subtotal taxAmount taxCode tieredAveragePrice updatedAt vatCode } + pageInfo { startCursor endCursor hasNextPage hasPreviousPage } } + } + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - quote_charges + - nodes + - "*" + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/quote_charges" + subscriptions: + type: DeclarativeStream + name: subscriptions + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: variables + inject_into: body_json + pagination_strategy: + type: CursorPagination + cursor_value: >- + {{ '{"after": "' + response.data.subscriptions.pageInfo.endCursor + + '"}' if response.data.subscriptions.pageInfo.endCursor else "" + }} + stop_condition: "{{ response.data.subscriptions.pageInfo.hasNextPage is false }}" + requester: + $ref: "#/definitions/base_requester" + path: /graphql + http_method: POST + request_body_json: + query: >- + query($after: String) { subscriptions(first: 10, after: $after) { + nodes { id accountId cancelationDate createdAt + currencyId endDate id name period priceListId rampIntervalMonths + startDate trialEndDate trialPeriod trialStartDate updatedAt } + pageInfo { startCursor endCursor hasNextPage hasPreviousPage } } + } + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - subscriptions + - nodes + - "*" + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/subscriptions" + accountBalances: + type: DeclarativeStream + name: accountBalances + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: variables + inject_into: body_json + pagination_strategy: + type: CursorPagination + cursor_value: >- + {{ '{"after": "' + + response.data.accountBalances.pageInfo.endCursor + '"}' if + response.data.accountBalances.pageInfo.endCursor else "" }} + stop_condition: "{{ response.data.accountBalances.pageInfo.hasNextPage is false }}" + requester: + $ref: "#/definitions/base_requester" + path: /graphql + http_method: POST + request_body_json: + query: >- + query($after: String) { accountBalances(first: 10, after: $after) + { nodes { id accountId balance currencyId id } + pageInfo { startCursor endCursor hasNextPage hasPreviousPage } } + } + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - accountBalances + - nodes + - "*" + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accountBalances" + subscriptionCharges: + type: DeclarativeStream + name: subscriptionCharges + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: variables + inject_into: body_json + pagination_strategy: + type: CursorPagination + cursor_value: >- + {{ '{"after": "' + + response.data.subscriptionCharges.pageInfo.endCursor + '"}' if + response.data.subscriptionCharges.pageInfo.endCursor else "" }} + stop_condition: >- + {{ response.data.subscriptionCharges.pageInfo.hasNextPage is false + }} + requester: + $ref: "#/definitions/base_requester" + path: /graphql + http_method: POST + request_body_json: + query: >- + query($after: String) { subscriptionCharges(first: 10, after: + $after) { nodes { id amount billingPeriod chargeType + createdAt discount discountedPrice id invoiceLineText kind name + periodPrice price priceDecimals priceListChargeId priceListId + pricingModel prorationRate quantity quantityMax quantityMin + selfServiceQuantity subscriptionId tieredAveragePrice updatedAt } + pageInfo { startCursor endCursor hasNextPage hasPreviousPage } } + } + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - subscriptionCharges + - nodes + - "*" + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/subscriptionCharges" + base_requester: + type: HttpRequester + url_base: https://{{ config['subdomain'] }}.bunny.com + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"apikey\"] }}" + +streams: + - $ref: "#/definitions/streams/accounts" + - $ref: "#/definitions/streams/accountBalances" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/entities" + - $ref: "#/definitions/streams/invoices" + - $ref: "#/definitions/streams/invoiceItems" + - $ref: "#/definitions/streams/payments" + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/plans" + - $ref: "#/definitions/streams/quotes" + - $ref: "#/definitions/streams/quote_charges" + - $ref: "#/definitions/streams/subscriptions" + - $ref: "#/definitions/streams/subscriptionCharges" + - $ref: "#/definitions/streams/transactions" + - $ref: "#/definitions/streams/tenants" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - subdomain + - apikey + properties: + apikey: + type: string + order: 1 + title: API Key + airbyte_secret: true + subdomain: + type: string + description: The subdomain specific to your Bunny account or service. + name: subdomain + order: 0 + title: Subdomain + start_date: + type: string + order: 2 + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + additionalProperties: true + +metadata: + assist: + docsUrl: https://docs.bunny.com/developer/api-reference/queries + testedStreams: + accounts: + hasRecords: true + streamHash: 879d5b5d7dce71369a5533ed96b390b77ad3564c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + accountBalances: + hasRecords: true + streamHash: 7966c01aabd07cbc905c0279ad44b14f477f299c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + contacts: + streamHash: 5c4db7b94dae251a1def94ae790d146b1cbda8dd + entities: + streamHash: 65ba5f31944b56368fe9d693a03ac6cab8cec1a8 + invoices: + streamHash: 9feae4d0141466f2d326a05d2188dbfa9164b183 + invoiceItems: + streamHash: a57d20dc73fd2c3a236145e89f3c77d9c061628d + payments: + streamHash: 9fe5abc62e8cecac5d14d5e058c3d246892c5f99 + products: + streamHash: eb4c9da4f993e9b1171199b47692253adb532726 + plans: + streamHash: cea5bead8031602423eb8df3ba577195d17572c8 + quotes: + streamHash: 36c6f963d53d145a8e9445f6278e156097883364 + quote_charges: + streamHash: ee6bfaba5669eac8de245ecf39c78af156089584 + subscriptions: + streamHash: ad990d631848383d26d20f3789de9ebce593c10d + subscriptionCharges: + streamHash: 123de539ae97a449a628d09b51e62183f0a2e522 + transactions: + streamHash: cfa646f3076e35847315e08f20dcd1857b2609fe + tenants: + streamHash: e0b625be017779be93b76740a2a5d9b9c2cd6374 + autoImportSchema: + plans: false + quotes: false + tenants: false + accounts: true + contacts: false + entities: false + invoices: false + payments: false + products: false + invoiceItems: false + transactions: false + quote_charges: false + subscriptions: false + accountBalances: false + subscriptionCharges: false + +schemas: + plans: + type: object + $schema: http://json-schema.org/schema + properties: + description: + type: + - string + - "null" + id: + type: + - string + - "null" + code: + type: + - string + - "null" + name: + type: + - string + - "null" + addon: + type: + - boolean + - "null" + position: + type: + - int + - "null" + basePrice: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + isVisible: + type: + - boolean + - "null" + productId: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + contactUsUrl: + type: + - string + - "null" + internalNotes: + type: + - string + - "null" + contactUsLabel: + type: + - string + - "null" + selfServiceBuy: + type: + - boolean + - "null" + productPlanName: + type: + - string + - "null" + selfServiceRenew: + type: + - boolean + - "null" + selfServiceCancel: + type: + - boolean + - "null" + pricingDescription: + type: + - string + - "null" + additionalProperties: true + quotes: + type: object + $schema: http://json-schema.org/schema + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + uuid: + type: + - string + - "null" + notes: + type: + - string + - "null" + amount: + type: + - string + - "null" + dealId: + type: + - string + - "null" + number: + type: + - string + - "null" + credits: + type: + - number + - "null" + message: + type: + - string + - "null" + ownerId: + type: + - string + - "null" + taxCode: + type: + - string + - "null" + discount: + type: + - number + - "null" + poNumber: + type: + - string + - "null" + subtotal: + type: + - string + - "null" + accountId: + type: + - string + - "null" + amountDue: + type: + - number + - "null" + contactId: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + evergreen: + type: + - boolean + - "null" + payableId: + type: + - string + - "null" + taxAmount: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + billingDay: + type: + - int + - "null" + currencyId: + type: + - string + - "null" + periodAmount: + type: + - number + - "null" + splitInvoice: + type: + - boolean + - "null" + discountValue: + type: + - string + - "null" + acceptedByName: + type: + - string + - "null" + backdatedQuote: + type: + - boolean + - "null" + netPaymentDays: + type: + - int + - "null" + acceptedByTitle: + type: + - string + - "null" + applicationDate: + type: + - date + - "null" + backdatedPeriods: + type: + - boolean + - "null" + smallUnitAmountDue: + type: + - int + - "null" + additionalProperties: true + tenants: + type: object + $schema: http://json-schema.org/schema + properties: + id: + type: + - string + - "null" + code: + type: + - string + - "null" + name: + type: + - string + - "null" + accountId: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + lastLogin: + type: + - timestamp_without_timezone + - "null" + subdomain: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + userCount: + type: + - int + - "null" + platformId: + type: + - string + - "null" + provisioningState: + type: + - string + - "null" + utilizationMetrics: + type: + - string + - "null" + provisioningRequired: + type: + - boolean + - "null" + latestProvisioningChangeId: + type: + - string + - "null" + additionalProperties: true + accounts: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + description: + type: + - string + - "null" + id: + type: string + code: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + groupId: + type: + - string + - "null" + website: + type: + - string + - "null" + entityId: + type: + - string + - "null" + timezone: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + billingDay: + type: + - number + - "null" + billingZip: + type: + - string + - "null" + currencyId: + type: + - string + - "null" + industryId: + type: + - string + - "null" + billingCity: + type: + - string + - "null" + linkedinUrl: + type: + - string + - "null" + ownerUserId: + type: + - string + - "null" + billingState: + type: + - string + - "null" + payingStatus: + type: + - string + - "null" + accountTypeId: + type: + - string + - "null" + billingStreet: + type: + - string + - "null" + billingCountry: + type: + - string + - "null" + netPaymentDays: + type: + - number + - "null" + shippingCountry: + type: + - string + - "null" + billingContactId: + type: + - string + - "null" + invoiceTemplateId: + type: + - string + - "null" + taxNumberValidated: + type: + - boolean + - "null" + additionalProperties: true + contacts: + type: object + $schema: http://json-schema.org/schema + properties: + description: + type: + - string + - "null" + id: + type: + - string + - "null" + code: + type: + - string + - "null" + email: + type: + - string + - "null" + phone: + type: + - string + - "null" + title: + type: + - string + - "null" + mobile: + type: + - string + - "null" + entityId: + type: + - string + - "null" + fullName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + accountId: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + firstName: + type: + - string + - "null" + updatedAt: + type: + - timestamp_without_timezone + - "null" + mailingZip: + type: + - string + - "null" + salutation: + type: + - string + - "null" + linkedinUrl: + type: + - string + - "null" + mailingCity: + type: + - string + - "null" + mailingState: + type: + - string + - "null" + portalAccess: + type: + - boolean + - "null" + mailingStreet: + type: + - string + - "null" + mailingCountry: + type: + - string + - "null" + additionalProperties: true + entities: + type: object + $schema: http://json-schema.org/schema + properties: + id: + type: + - string + - "null" + fax: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + taxId: + type: + - string + - "null" + taxType: + type: + - string + - "null" + website: + type: + - string + - "null" + termsUrl: + type: + - string + - "null" + timezone: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + isDefault: + type: + - boolean + - "null" + updatedAt: + type: + - string + - "null" + billingZip: + type: + - string + - "null" + brandColor: + type: + - string + - "null" + privacyUrl: + type: + - string + - "null" + accentColor: + type: + - string + - "null" + billingCity: + type: + - string + - "null" + abbreviation: + type: + - string + - "null" + billingState: + type: + - string + - "null" + billingStreet: + type: + - string + - "null" + emailTemplate: + type: + - string + - "null" + baseCurrencyId: + type: + - string + - "null" + billingCountry: + type: + - string + - "null" + quoteNumberSeq: + type: + - int + - "null" + quotesImageUrl: + type: + - string + - "null" + topNavImageUrl: + type: + - string + - "null" + emailSenderName: + type: + - string + - "null" + refundPolicyUrl: + type: + - string + - "null" + invoiceNumberSeq: + type: + - int + - "null" + invoicesImageUrl: + type: + - string + - "null" + quoteNumberPrefix: + type: + - string + - "null" + invoiceNumberPrefix: + type: + - string + - "null" + customerServiceEmail: + type: + - string + - "null" + defaultCpcaAccountId: + type: + - string + - "null" + fiscalYearStartMonth: + type: + - int + - "null" + defaultPaymentAccountId: + type: + - string + - "null" + defaultTaxPayableAccountId: + type: + - string + - "null" + defaultBankingFeesAccountId: + type: + - string + - "null" + defaultConversionGainAccountId: + type: + - string + - "null" + defaultConversionLossAccountId: + type: + - string + - "null" + defaultDeferredRevenueAccountId: + type: + - string + - "null" + defaultRecognizedRevenueAccountId: + type: + - string + - "null" + defaultAccountsReceivableAccountId: + type: + - string + - "null" + additionalProperties: true + invoices: + type: object + $schema: http://json-schema.org/schema + properties: + description: + type: + - string + - "null" + id: + type: + - string + - "null" + url: + type: + - string + - "null" + uuid: + type: + - string + - "null" + dueAt: + type: + - date + - "null" + amount: + type: + - string + - "null" + number: + type: + - string + - "null" + paidAt: + type: + - timestamp_without_timezone + - "null" + credits: + type: + - number + - "null" + quoteId: + type: + - string + - "null" + poNumber: + type: + - string + - "null" + subtotal: + type: + - string + - "null" + accountId: + type: + - string + - "null" + amountDue: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + payableId: + type: + - string + - "null" + portalUrl: + type: + - string + - "null" + taxAmount: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + amountPaid: + type: + - number + - "null" + currencyId: + type: + - string + - "null" + netPaymentDays: + type: + - string + - "null" + smallUnitAmountDue: + type: + - int + - "null" + additionalProperties: true + payments: + type: object + $schema: http://json-schema.org/schema + properties: + description: + type: + - string + - "null" + id: + type: + - string + - "null" + memo: + type: + - string + - "null" + amount: + type: + - string + - "null" + isLegacy: + type: + - boolean + - "null" + accountId: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + currencyId: + type: + - string + - "null" + receivedAt: + type: + - string + - "null" + baseCurrencyId: + type: + - string + - "null" + amountUnapplied: + type: + - number + - "null" + baseCurrencyCash: + type: + - number + - "null" + additionalProperties: true + products: + type: object + $schema: http://json-schema.org/schema + properties: + description: + type: + - string + - "null" + id: + type: + - string + - "null" + code: + type: + - string + - "null" + name: + type: + - string + - "null" + platformId: + type: + - string + - "null" + internalNotes: + type: + - string + - "null" + everythingInPlus: + type: + - boolean + - "null" + productCategoryId: + type: + - string + - "null" + showProductNameOnLineItem: + type: + - boolean + - "null" + additionalProperties: true + invoiceItems: + type: object + $schema: http://json-schema.org/schema + properties: + id: + type: + - string + - "null" + price: + type: + - string + - "null" + amount: + type: + - string + - "null" + taxCode: + type: + - string + - "null" + vatCode: + type: + - string + - "null" + couponId: + type: + - string + - "null" + discount: + type: + - number + - "null" + lineText: + type: + - string + - "null" + position: + type: + - int + - "null" + quantity: + type: + - int + - "null" + subtotal: + type: + - string + - "null" + invoiceId: + type: + - string + - "null" + taxAmount: + type: + - number + - "null" + chargeType: + type: + - string + - "null" + currencyId: + type: + - string + - "null" + priceListId: + type: + - string + - "null" + pricingModel: + type: + - string + - "null" + priceDecimals: + type: + - string + - "null" + prorationRate: + type: + - number + - "null" + unitOfMeasure: + type: + - string + - "null" + additionalProperties: true + transactions: + type: object + $schema: http://json-schema.org/schema + properties: + description: + type: + - string + - "null" + id: + type: + - string + - "null" + dueAt: + type: + - string + - "null" + state: + type: + - string + - "null" + amount: + type: + - string + - "null" + accountId: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + currencyId: + type: + - string + - "null" + transactionableId: + type: + - string + - "null" + additionalProperties: true + quote_charges: + type: object + $schema: http://json-schema.org/schema + properties: + id: + type: + - string + - "null" + kind: + type: + - string + - "null" + name: + type: + - string + - "null" + price: + type: + - number + - "null" + amount: + type: + - number + - "null" + taxCode: + type: + - string + - "null" + vatCode: + type: + - string + - "null" + couponId: + type: + - string + - "null" + discount: + type: + - number + - "null" + quantity: + type: + - int + - "null" + subtotal: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + taxAmount: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + chargeType: + type: + - string + - "null" + currencyId: + type: + - string + - "null" + quantityMax: + type: + - int + - "null" + quantityMin: + type: + - int + - "null" + pricingModel: + type: + - string + - "null" + billingPeriod: + type: + - string + - "null" + priceDecimals: + type: + - int + - "null" + prorationRate: + type: + - number + - "null" + quoteChangeId: + type: + - string + - "null" + currentQuantity: + type: + - int + - "null" + invoiceLineText: + type: + - string + - "null" + priceListChargeId: + type: + - string + - "null" + tieredAveragePrice: + type: + - number + - "null" + additionalProperties: true + subscriptions: + type: object + $schema: http://json-schema.org/schema + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + period: + type: + - string + - "null" + endDate: + type: + - date + - "null" + accountId: + type: + - string + - "null" + createdAt: + type: + - timestamp_without_timezone + - "null" + startDate: + type: + - date + - "null" + updatedAt: + type: + - timestamp_without_timezone + - "null" + currencyId: + type: + - string + - "null" + priceListId: + type: + - string + - "null" + trialPeriod: + type: + - string + - "null" + trialEndDate: + type: + - date + - "null" + trialStartDate: + type: + - date + - "null" + cancelationDate: + type: + - date + - "null" + rampIntervalMonths: + type: + - int + - "null" + additionalProperties: true + accountBalances: + type: object + $schema: http://json-schema.org/schema + properties: + id: + type: + - string + - "null" + balance: + type: + - string + - "null" + accountId: + type: + - string + - "null" + currencyId: + type: + - string + - "null" + additionalProperties: true + subscriptionCharges: + type: object + $schema: http://json-schema.org/schema + properties: + id: + type: + - string + - "null" + kind: + type: + - string + - "null" + name: + type: + - string + - "null" + price: + type: + - string + - "null" + amount: + type: + - number + - "null" + discount: + type: + - number + - "null" + quantity: + type: + - int + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + chargeType: + type: + - string + - "null" + periodPrice: + type: + - number + - "null" + priceListId: + type: + - string + - "null" + quantityMax: + type: + - int + - "null" + quantityMin: + type: + - int + - "null" + pricingModel: + type: + - string + - "null" + billingPeriod: + type: + - string + - "null" + priceDecimals: + type: + - int + - "null" + prorationRate: + type: + - number + - "null" + subscriptionId: + type: + - string + - "null" + discountedPrice: + type: + - string + - "null" + invoiceLineText: + type: + - string + - "null" + priceListChargeId: + type: + - string + - "null" + tieredAveragePrice: + type: + - number + - "null" + selfServiceQuantity: + type: + - boolean + - "null" + additionalProperties: true diff --git a/airbyte-integrations/connectors/source-bunny-inc/metadata.yaml b/airbyte-integrations/connectors/source-bunny-inc/metadata.yaml new file mode 100644 index 000000000000..11ead1a7d3a6 --- /dev/null +++ b/airbyte-integrations/connectors/source-bunny-inc/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "https://*.bunny.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-bunny-inc + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 6aa362e3-6107-4fdc-9209-130a60e8725c + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-bunny-inc + githubIssueLabel: source-bunny-inc + icon: icon.svg + license: MIT + name: Bunny, Inc. + releaseDate: 2024-10-29 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/bunny-inc + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-buzzsprout/metadata.yaml b/airbyte-integrations/connectors/source-buzzsprout/metadata.yaml index 3be8be923a9f..02a5648bef05 100644 --- a/airbyte-integrations/connectors/source-buzzsprout/metadata.yaml +++ b/airbyte-integrations/connectors/source-buzzsprout/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-buzzsprout connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 6ad23bfc-cb11-4faa-a243-f9ccdb0145cc - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.9 dockerRepository: airbyte/source-buzzsprout githubIssueLabel: source-buzzsprout icon: icon.svg diff --git a/airbyte-integrations/connectors/source-cal-com/README.md b/airbyte-integrations/connectors/source-cal-com/README.md new file mode 100644 index 000000000000..ee66e9012ac0 --- /dev/null +++ b/airbyte-integrations/connectors/source-cal-com/README.md @@ -0,0 +1,33 @@ +# Cal.com +This directory contains the manifest-only connector for `source-cal-com`. + +The Cal.com connector enables seamless data synchronization between Cal.com’s scheduling platform and various destinations. It helps extract events, attendees, and booking details from Cal.com, making it easy to analyze scheduling data or integrate it into downstream systems like data warehouses or CRMs. This connector streamlines automated reporting and insights for time management and booking analytics + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-cal-com:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-cal-com build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-cal-com test +``` + diff --git a/airbyte-integrations/connectors/source-cal-com/acceptance-test-config.yml b/airbyte-integrations/connectors/source-cal-com/acceptance-test-config.yml new file mode 100644 index 000000000000..2ad597b9fd11 --- /dev/null +++ b/airbyte-integrations/connectors/source-cal-com/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-cal-com:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-cal-com/icon.svg b/airbyte-integrations/connectors/source-cal-com/icon.svg new file mode 100644 index 000000000000..354d7c9616a5 --- /dev/null +++ b/airbyte-integrations/connectors/source-cal-com/icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-cal-com/manifest.yaml b/airbyte-integrations/connectors/source-cal-com/manifest.yaml new file mode 100644 index 000000000000..1c9602fd5270 --- /dev/null +++ b/airbyte-integrations/connectors/source-cal-com/manifest.yaml @@ -0,0 +1,880 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + The Cal.com connector enables seamless data synchronization between Cal.com’s + scheduling platform and various destinations. It helps extract events, + attendees, and booking details from Cal.com, making it easy to analyze + scheduling data or integrate it into downstream systems like data warehouses + or CRMs. This connector streamlines automated reporting and insights for time + management and booking analytics + +check: + type: CheckStream + stream_names: + - event_types + +definitions: + streams: + event_types: + type: DeclarativeStream + name: event_types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/event-types + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - eventTypeGroups + - "*" + - eventTypes + - "*" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: take + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/event_types" + my_profile: + type: DeclarativeStream + name: my_profile + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/me + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/my_profile" + schedules: + type: DeclarativeStream + name: schedules + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/schedules + http_method: GET + request_headers: + cal-api-version: "2024-06-11" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: take + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/schedules" + calendars: + type: DeclarativeStream + name: calendars + primary_key: + - externalId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/calendars + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - connectedCalendars + - "*" + - calendars + - "*" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/calendars" + bookings: + type: DeclarativeStream + name: bookings + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/bookings + http_method: GET + request_headers: + cal-api-version: "2024-08-13" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - "*" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + page_size_option: + type: RequestOption + field_name: take + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/bookings" + conferencing: + type: DeclarativeStream + name: conferencing + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/conferencing + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/conferencing" + base_requester: + type: HttpRequester + url_base: https://api.cal.com + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/event_types" + - $ref: "#/definitions/streams/my_profile" + - $ref: "#/definitions/streams/schedules" + - $ref: "#/definitions/streams/calendars" + - $ref: "#/definitions/streams/bookings" + - $ref: "#/definitions/streams/conferencing" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - orgId + - api_key + properties: + orgId: + type: string + name: Organization ID + order: 0 + title: orgId + api_key: + type: string + description: API key to use. Find it at https://cal.com/account + name: api_key + order: 1 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + event_types: true + my_profile: true + schedules: true + calendars: true + bookings: true + conferencing: true + testedStreams: + event_types: + streamHash: 5997ca432cb58db58d2d2b5730e65aeebb917cf0 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + my_profile: + hasRecords: true + streamHash: f36b2ec021e76f2cce1d826a00fdb1cacb9ab4ea + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + schedules: + streamHash: 32f5be46fba85df1ddf3a67196729c9f3b152d98 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + calendars: + hasRecords: true + streamHash: 9cb1b9161f0deaf9644c05460bf8988a06f2d1ea + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + bookings: + streamHash: 306e91dd4a043f11aaedb6da8a5acfe837128dd5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + conferencing: + streamHash: 3bf649057d4e6b8ea7e003ac70ec896ea49ef5c7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://cal.com/docs/api-reference/v2/introduction + +schemas: + event_types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + metadata: + type: + - object + - "null" + properties: + apps: + type: + - object + - "null" + properties: + giphy: + type: + - object + - "null" + properties: + enabled: + type: + - boolean + - "null" + thankYouPage: + type: + - string + - "null" + multipleDuration: + type: + - array + - "null" + items: + type: + - number + - "null" + afterEventBuffer: + type: + - number + - "null" + assignAllTeamMembers: + type: + - boolean + - "null" + beforeEventBuffer: + type: + - number + - "null" + bookingFields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + defaultLabel: + type: + - string + - "null" + defaultPlaceholder: + type: + - string + - "null" + editable: + type: + - string + - "null" + name: + type: + - string + - "null" + required: + type: + - boolean + - "null" + sources: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + label: + type: + - string + - "null" + variant: + type: + - string + - "null" + variantsConfig: + type: + - object + - "null" + properties: + variants: + type: + - object + - "null" + properties: + fullName: + type: + - object + - "null" + properties: + fields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + name: + type: + - string + - "null" + required: + type: + - boolean + - "null" + views: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + label: + type: + - string + - "null" + children: + type: + - array + - "null" + currency: + type: + - string + - "null" + disableGuests: + type: + - boolean + - "null" + hashedLink: + type: + - array + - "null" + hidden: + type: + - boolean + - "null" + hideCalendarNotes: + type: + - boolean + - "null" + hosts: + type: + - array + - "null" + id: + type: number + isInstantEvent: + type: + - boolean + - "null" + length: + type: + - number + - "null" + locations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + lockTimeZoneToggleOnBookingPage: + type: + - boolean + - "null" + minimumBookingNotice: + type: + - number + - "null" + offsetStart: + type: + - number + - "null" + onlyShowFirstAvailableSlot: + type: + - boolean + - "null" + periodType: + type: + - string + - "null" + position: + type: + - number + - "null" + price: + type: + - number + - "null" + requiresBookerEmailVerification: + type: + - boolean + - "null" + requiresConfirmation: + type: + - boolean + - "null" + seatsShowAttendees: + type: + - boolean + - "null" + seatsShowAvailabilityCount: + type: + - boolean + - "null" + slug: + type: + - string + - "null" + title: + type: + - string + - "null" + useEventTypeDestinationCalendarEmail: + type: + - boolean + - "null" + userId: + type: + - number + - "null" + userIds: + type: + - array + - "null" + items: + type: + - number + - "null" + required: + - id + my_profile: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + defaultScheduleId: + type: + - number + - "null" + email: + type: + - string + - "null" + id: + type: number + timeFormat: + type: + - number + - "null" + timeZone: + type: + - string + - "null" + username: + type: + - string + - "null" + weekStart: + type: + - string + - "null" + required: + - id + schedules: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + availability: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + days: + type: + - array + - "null" + items: + type: + - string + - "null" + endTime: + type: + - string + - "null" + startTime: + type: + - string + - "null" + id: + type: number + isDefault: + type: + - boolean + - "null" + name: + type: + - string + - "null" + overrides: + type: + - array + - "null" + ownerId: + type: + - number + - "null" + timeZone: + type: + - string + - "null" + required: + - id + calendars: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + credentialId: + type: + - number + - "null" + email: + type: + - string + - "null" + externalId: + type: string + integration: + type: + - string + - "null" + isSelected: + type: + - boolean + - "null" + name: + type: + - string + - "null" + primary: + type: + - boolean + - "null" + readOnly: + type: + - boolean + - "null" + required: + - externalId + bookings: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + absentHost: + type: + - boolean + - "null" + attendees: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + absent: + type: + - boolean + - "null" + language: + type: + - string + - "null" + name: + type: + - string + - "null" + timeZone: + type: + - string + - "null" + bookingFieldsResponses: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + guests: + type: + - array + - "null" + location: + type: + - object + - "null" + properties: + optionValue: + type: + - string + - "null" + value: + type: + - string + - "null" + name: + type: + - string + - "null" + duration: + type: + - number + - "null" + end: + type: + - string + - "null" + eventType: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + slug: + type: + - string + - "null" + eventTypeId: + type: + - number + - "null" + guests: + type: + - array + - "null" + hosts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + timeZone: + type: + - string + - "null" + id: + type: number + location: + type: + - string + - "null" + meetingUrl: + type: + - string + - "null" + rescheduledFromUid: + type: + - string + - "null" + start: + type: + - string + - "null" + status: + type: + - string + - "null" + title: + type: + - string + - "null" + uid: + type: + - string + - "null" + required: + - id + conferencing: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + appId: + type: + - string + - "null" + id: + type: number + invalid: + type: + - boolean + - "null" + key: + type: + - object + - "null" + userId: + type: + - number + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-cal-com/metadata.yaml b/airbyte-integrations/connectors/source-cal-com/metadata.yaml new file mode 100644 index 000000000000..f1cd1bd887f1 --- /dev/null +++ b/airbyte-integrations/connectors/source-cal-com/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.cal.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-cal-com + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 3db8a652-88f7-41ee-91a3-2f745322d9ae + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-cal-com + githubIssueLabel: source-cal-com + icon: icon.svg + license: MIT + name: Cal.com + releaseDate: 2024-11-11 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/cal-com + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-calendly/metadata.yaml b/airbyte-integrations/connectors/source-calendly/metadata.yaml index ae3f2287ba5a..b9c5d51dad09 100644 --- a/airbyte-integrations/connectors/source-calendly/metadata.yaml +++ b/airbyte-integrations/connectors/source-calendly/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-calendly connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: b8f2cbee-b073-4dd8-9b80-97d7bae967a4 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-calendly githubIssueLabel: source-calendly icon: icon.svg diff --git a/airbyte-integrations/connectors/source-callrail/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-callrail/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-callrail/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-callrail/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-campaign-monitor/metadata.yaml b/airbyte-integrations/connectors/source-campaign-monitor/metadata.yaml index 94ba17d4a0db..526923c15545 100644 --- a/airbyte-integrations/connectors/source-campaign-monitor/metadata.yaml +++ b/airbyte-integrations/connectors/source-campaign-monitor/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-campaign-monitor connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 9d350ec7-2860-4106-a331-7d9403dd9a02 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-campaign-monitor githubIssueLabel: source-campaign-monitor icon: icon.svg diff --git a/airbyte-integrations/connectors/source-campayn/README.md b/airbyte-integrations/connectors/source-campayn/README.md new file mode 100644 index 000000000000..23d7f0447e86 --- /dev/null +++ b/airbyte-integrations/connectors/source-campayn/README.md @@ -0,0 +1,33 @@ +# Campayn +This directory contains the manifest-only connector for `source-campayn`. + +The Airbyte connector for [Campayn](https://campayn.com/) enables seamless data integration between the Campayn email marketing platform and your data warehouse or analytics system. This connector automates the extraction of subscriber lists, email campaigns, performance metrics, and engagement data from Campayn, allowing businesses to centralize marketing insights, optimize email strategies, and drive data-driven decisions efficiently. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-campayn:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-campayn build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-campayn test +``` + diff --git a/airbyte-integrations/connectors/source-campayn/acceptance-test-config.yml b/airbyte-integrations/connectors/source-campayn/acceptance-test-config.yml new file mode 100644 index 000000000000..d223abc0fddb --- /dev/null +++ b/airbyte-integrations/connectors/source-campayn/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-campayn:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-campayn/icon.svg b/airbyte-integrations/connectors/source-campayn/icon.svg new file mode 100644 index 000000000000..4e9512c3e027 --- /dev/null +++ b/airbyte-integrations/connectors/source-campayn/icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/airbyte-integrations/connectors/source-campayn/manifest.yaml b/airbyte-integrations/connectors/source-campayn/manifest.yaml new file mode 100644 index 000000000000..6e1c25025bbe --- /dev/null +++ b/airbyte-integrations/connectors/source-campayn/manifest.yaml @@ -0,0 +1,381 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + The Airbyte connector for [Campayn](https://campayn.com/) enables seamless + data integration between the Campayn email marketing platform and your data + warehouse or analytics system. This connector automates the extraction of + subscriber lists, email campaigns, performance metrics, and engagement data + from Campayn, allowing businesses to centralize marketing insights, optimize + email strategies, and drive data-driven decisions efficiently. + +check: + type: CheckStream + stream_names: + - lists + +definitions: + streams: + lists: + type: DeclarativeStream + name: lists + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /lists.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/lists" + forms: + type: DeclarativeStream + name: forms + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /lists/{{ stream_partition.list_id }}/forms.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: list_id + stream: + $ref: "#/definitions/streams/lists" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/forms" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /lists/{{ stream_partition.list_id }}/contacts.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: list_id + stream: + $ref: "#/definitions/streams/lists" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + emails: + type: DeclarativeStream + name: emails + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /emails.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/emails" + reports: + type: DeclarativeStream + name: reports + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /reports/calendar.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/reports" + base_requester: + type: HttpRequester + url_base: https://{{ config['sub_domain'] }}.campayn.com/api/v1/ + authenticator: + type: ApiKeyAuthenticator + api_token: TRUEREST apikey={{ config["api_key"] }} + inject_into: + type: RequestOption + field_name: Authorization + inject_into: header + +streams: + - $ref: "#/definitions/streams/lists" + - $ref: "#/definitions/streams/forms" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/emails" + - $ref: "#/definitions/streams/reports" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - sub_domain + - api_key + properties: + sub_domain: + type: string + name: domain + title: Sub Domain + order: 0 + api_key: + type: string + description: >- + API key to use. Find it in your Campayn account settings. Keep it + secure as it grants access to your Campayn data. + name: api_key + title: API Key + airbyte_secret: true + order: 1 + additionalProperties: true + +metadata: + autoImportSchema: + lists: true + forms: true + contacts: true + emails: true + reports: true + yamlComponents: + global: + - authenticator + testedStreams: + lists: + streamHash: 616482821ae602657529ce5b28d5bda32e35406f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + forms: + streamHash: e191ad7b67f69fb64758f4d2c018db77997ca403 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contacts: + streamHash: c666da93e7c5c59b9179a3f12114f86ef9067def + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + emails: + streamHash: 7d9acd173fa4ab94ea22b8e7c43b82bfc64fd140 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + reports: + streamHash: 5dcf5bba9a8dd94090b5d719112d2b15bfb50075 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://github.com/nebojsac/Campayn-API + +schemas: + lists: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + contact_count: + type: + - number + - "null" + id: + type: string + list_name: + type: + - string + - "null" + tags: + type: + - string + - "null" + required: + - id + forms: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + contact_list_id: + type: + - string + - "null" + form_html: + type: + - string + - "null" + form_title: + type: + - string + - "null" + form_type: + type: + - string + - "null" + id: + type: string + signup_count: + type: + - string + - "null" + required: + - id + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + confirmed: + type: + - string + - "null" + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + id: + type: string + image_url: + type: + - string + - "null" + last_name: + type: + - string + - "null" + required: + - id + emails: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: string + name: + type: + - string + - "null" + percent_responses: + type: + - number + - "null" + percent_views: + type: + - number + - "null" + preview_thumb: + type: + - string + - "null" + preview_url: + type: + - string + - "null" + send_count: + type: + - string + - "null" + send_now: + type: + - boolean + - "null" + status: + type: + - string + - "null" + unique_responses: + type: + - number + - "null" + unique_views: + type: + - number + - "null" + required: + - id + reports: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: string + name: + type: + - string + - "null" + preview_url: + type: + - string + - "null" + scheduled_date: + type: + - string + - "null" + status: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-campayn/metadata.yaml b/airbyte-integrations/connectors/source-campayn/metadata.yaml new file mode 100644 index 000000000000..0278361cfc01 --- /dev/null +++ b/airbyte-integrations/connectors/source-campayn/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "https:" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-campayn + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 5674ae5a-511e-4093-9da9-086bf5f0b568 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-campayn + githubIssueLabel: source-campayn + icon: icon.svg + license: MIT + name: Campayn + releaseDate: 2024-10-31 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/campayn + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-canny/metadata.yaml b/airbyte-integrations/connectors/source-canny/metadata.yaml index 1420f844848e..6d219c977c87 100644 --- a/airbyte-integrations/connectors/source-canny/metadata.yaml +++ b/airbyte-integrations/connectors/source-canny/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-canny connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: ec1ffa33-bfd9-428a-a645-ece66a1a9f44 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-canny githubIssueLabel: source-canny icon: icon.svg diff --git a/airbyte-integrations/connectors/source-capsule-crm/README.md b/airbyte-integrations/connectors/source-capsule-crm/README.md new file mode 100644 index 000000000000..62de977bff2e --- /dev/null +++ b/airbyte-integrations/connectors/source-capsule-crm/README.md @@ -0,0 +1,33 @@ +# Capsule CRM +This directory contains the manifest-only connector for `source-capsule-crm`. + +Capsule CRM connector enables seamless data syncing from Capsule CRM to various data warehouses, helping businesses centralize and analyze customer data efficiently. It supports real-time data extraction of contacts, opportunities, and custom fields, making it ideal for comprehensive CRM analytics and reporting. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-capsule-crm:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-capsule-crm build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-capsule-crm test +``` + diff --git a/airbyte-integrations/connectors/source-capsule-crm/acceptance-test-config.yml b/airbyte-integrations/connectors/source-capsule-crm/acceptance-test-config.yml new file mode 100644 index 000000000000..01a91574f62b --- /dev/null +++ b/airbyte-integrations/connectors/source-capsule-crm/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-capsule-crm:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-capsule-crm/icon.svg b/airbyte-integrations/connectors/source-capsule-crm/icon.svg new file mode 100644 index 000000000000..3a8b8813bf6b --- /dev/null +++ b/airbyte-integrations/connectors/source-capsule-crm/icon.svg @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-capsule-crm/manifest.yaml b/airbyte-integrations/connectors/source-capsule-crm/manifest.yaml new file mode 100644 index 000000000000..13702b4690b0 --- /dev/null +++ b/airbyte-integrations/connectors/source-capsule-crm/manifest.yaml @@ -0,0 +1,1660 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Capsule CRM connector enables seamless data syncing from Capsule CRM to + various data warehouses, helping businesses centralize and analyze customer + data efficiently. It supports real-time data extraction of contacts, + opportunities, and custom fields, making it ideal for comprehensive CRM + analytics and reporting. + +check: + type: CheckStream + stream_names: + - users + +definitions: + streams: + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - users + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: perPage + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ headers.get('link', {}).get('next', {}).get('url') }}" + stop_condition: "{{ headers.get('link', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + parties: + type: DeclarativeStream + name: parties + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/parties + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - parties + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: perPage + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ headers.get('link', {}).get('next', {}).get('url') }}" + stop_condition: "{{ headers.get('link', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/parties" + tasks: + type: DeclarativeStream + name: tasks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/tasks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - tasks + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: perPage + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ headers.get('link', {}).get('next', {}).get('url') }}" + stop_condition: "{{ headers.get('link', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tasks" + employees: + type: DeclarativeStream + name: employees + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/parties/{{ stream_partition.party }}/people + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - parties + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: perPage + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ headers.get('link', {}).get('next', {}).get('url') }}" + stop_condition: "{{ headers.get('link', {}).get('next') is none }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: party + stream: + $ref: "#/definitions/streams/parties" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/employees" + projects: + type: DeclarativeStream + name: projects + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/kases + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - kases + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: perPage + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ headers.get('link', {}).get('next', {}).get('url') }}" + stop_condition: "{{ headers.get('link', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/projects" + opportunities: + type: DeclarativeStream + name: opportunities + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/opportunities + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - opportunities + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: perPage + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ headers.get('link', {}).get('next', {}).get('url') }}" + stop_condition: "{{ headers.get('link', {}).get('next') is none }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: since + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/opportunities" + pipelines: + type: DeclarativeStream + name: pipelines + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/pipelines + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - pipelines + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: perPage + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ headers.get('link', {}).get('next', {}).get('url') }}" + stop_condition: "{{ headers.get('link', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/pipelines" + milestones: + type: DeclarativeStream + name: milestones + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/milestones + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - milestones + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: perPage + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ headers.get('link', {}).get('next', {}).get('url') }}" + stop_condition: "{{ headers.get('link', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/milestones" + site: + type: DeclarativeStream + name: site + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/site + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - site + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: perPage + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ headers.get('link', {}).get('next', {}).get('url') }}" + stop_condition: "{{ headers.get('link', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/site" + tags: + type: DeclarativeStream + name: tags + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/{{ config['entity'] }}/tags + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - tags + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: perPage + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ headers.get('link', {}).get('next', {}).get('url') }}" + stop_condition: "{{ headers.get('link', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tags" + custom_fields: + type: DeclarativeStream + name: custom_fields + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/{{ config['entity'] }}/fields/definitions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - definitions + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: perPage + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ headers.get('link', {}).get('next', {}).get('url') }}" + stop_condition: "{{ headers.get('link', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/custom_fields" + lost_reasons: + type: DeclarativeStream + name: lost_reasons + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/lostreasons + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - lostReasons + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: perPage + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ headers.get('link', {}).get('next', {}).get('url') }}" + stop_condition: "{{ headers.get('link', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/lost_reasons" + board: + type: DeclarativeStream + name: board + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/boards + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - boards + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: perPage + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ headers.get('link', {}).get('next', {}).get('url') }}" + stop_condition: "{{ headers.get('link', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/board" + categories: + type: DeclarativeStream + name: categories + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/categories + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - categories + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ headers.get('link', {}).get('next', {}).get('url') }}" + stop_condition: "{{ headers.get('link', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/categories" + activity_types: + type: DeclarativeStream + name: activity_types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/activitytypes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - activityTypes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: perPage + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ headers.get('link', {}).get('next', {}).get('url') }}" + stop_condition: "{{ headers.get('link', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/activity_types" + stages: + type: DeclarativeStream + name: stages + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/stages + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - stages + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: perPage + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ headers.get('link', {}).get('next', {}).get('url') }}" + stop_condition: "{{ headers.get('link', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stages" + base_requester: + type: HttpRequester + url_base: https://api.capsulecrm.com + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"bearer_token\"] }}" + +streams: + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/parties" + - $ref: "#/definitions/streams/tasks" + - $ref: "#/definitions/streams/employees" + - $ref: "#/definitions/streams/projects" + - $ref: "#/definitions/streams/opportunities" + - $ref: "#/definitions/streams/pipelines" + - $ref: "#/definitions/streams/milestones" + - $ref: "#/definitions/streams/site" + - $ref: "#/definitions/streams/tags" + - $ref: "#/definitions/streams/custom_fields" + - $ref: "#/definitions/streams/lost_reasons" + - $ref: "#/definitions/streams/board" + - $ref: "#/definitions/streams/categories" + - $ref: "#/definitions/streams/activity_types" + - $ref: "#/definitions/streams/stages" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - bearer_token + - start_date + - entity + properties: + bearer_token: + type: string + description: >- + Bearer token to authenticate API requests. Generate it from the 'My + Preferences' > 'API Authentication Tokens' page in your Capsule + account. + name: bearer_token + order: 0 + title: Bearer Token + airbyte_secret: true + start_date: + type: string + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + order: 1 + entity: + type: string + title: Entity + enum: + - parties + - opportunities + - kases + order: 2 + additionalProperties: true + +metadata: + autoImportSchema: + users: true + parties: true + tasks: true + employees: true + projects: true + opportunities: true + pipelines: true + milestones: true + site: true + tags: true + custom_fields: true + lost_reasons: true + board: true + categories: true + activity_types: true + stages: true + testedStreams: + users: + streamHash: 1df7dd662cff0427b74427d335bae274ac526658 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + parties: + streamHash: 7472efff929fe223b3fd60bcc1fb4f171c26bfb4 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tasks: + streamHash: 127af0f770965149c9c86d2f89e35a39735a1b40 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + employees: + streamHash: 74bc35579e14f68ecae546fb1580200ad7136579 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + projects: + streamHash: a5eb36cc8204d1f37d33d64aae2273102d1e59a5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + opportunities: + streamHash: e7c448d4f554df553f86ad8fd0ef3a73d8234a09 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + pipelines: + streamHash: 960f49c70af6d95e908914e372108cab3fb483c5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + milestones: + streamHash: 7cde1e3cd3e578a77a3a1b1b3f8bb995d832f9e0 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + site: + streamHash: 44c92a9afa7ece8d625eca19e657e358bd1e550f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tags: + streamHash: 69b50c615b4fc5156884913543c122eac9cb61b1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + custom_fields: + streamHash: 10b46602c7261ba4f3bbdeb227cc1f10c0de1a57 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + lost_reasons: + streamHash: bf8dec5d032eb3cdae7894af0ce4c156c03bb773 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + board: + streamHash: 85008610bc07d3a5833a39bc45d5da2b7f3caebe + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + categories: + streamHash: e77e7e691dacabf690890eb1da6d2ee43c4b9238 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + activity_types: + streamHash: 1709073a75e496a6662794e1c2e0a8f6f1a1b980 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + stages: + streamHash: b8070adccf36161f5638e1a047731b03e12b567c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://developer.capsulecrm.com/v2/overview/getting-started + +schemas: + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + currency: + type: + - string + - "null" + deleted: + type: + - boolean + - "null" + id: + type: number + lastLoginAt: + type: + - string + - "null" + locale: + type: + - string + - "null" + loggedIn: + type: + - boolean + - "null" + name: + type: + - string + - "null" + party: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: + - number + - "null" + lastName: + type: + - string + - "null" + pictureURL: + type: + - string + - "null" + pictureURL: + type: + - string + - "null" + status: + type: + - string + - "null" + taskReminder: + type: + - boolean + - "null" + timezone: + type: + - string + - "null" + username: + type: + - string + - "null" + required: + - id + parties: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + addresses: + type: + - array + - "null" + createdAt: + type: + - string + - "null" + emailAddresses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + id: + type: + - number + - "null" + firstName: + type: + - string + - "null" + id: + type: number + jobTitle: + type: + - string + - "null" + lastName: + type: + - string + - "null" + name: + type: + - string + - "null" + organisation: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + pictureURL: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + deleted: + type: + - boolean + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + pictureURL: + type: + - string + - "null" + username: + type: + - string + - "null" + phoneNumbers: + type: + - array + - "null" + pictureURL: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + websites: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + id: + type: + - number + - "null" + service: + type: + - string + - "null" + url: + type: + - string + - "null" + required: + - id + tasks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + active: + type: + - boolean + - "null" + category: + type: + - object + - "null" + properties: + colour: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + detail: + type: + - string + - "null" + dueOn: + type: + - string + - "null" + hasTrack: + type: + - boolean + - "null" + id: + type: number + owner: + type: + - object + - "null" + properties: + deleted: + type: + - boolean + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + pictureURL: + type: + - string + - "null" + username: + type: + - string + - "null" + party: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + pictureURL: + type: + - string + - "null" + status: + type: + - string + - "null" + taskDayDelayRule: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + required: + - id + employees: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + addresses: + type: + - array + - "null" + createdAt: + type: + - string + - "null" + emailAddresses: + type: + - array + - "null" + firstName: + type: + - string + - "null" + id: + type: number + lastName: + type: + - string + - "null" + organisation: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + pictureURL: + type: + - string + - "null" + phoneNumbers: + type: + - array + - "null" + pictureURL: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + websites: + type: + - array + - "null" + required: + - id + projects: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + deleted: + type: + - boolean + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + pictureURL: + type: + - string + - "null" + username: + type: + - string + - "null" + party: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: + - number + - "null" + lastName: + type: + - string + - "null" + pictureURL: + type: + - string + - "null" + stage: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + status: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + required: + - id + opportunities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + durationBasis: + type: + - string + - "null" + id: + type: number + lastOpenMilestone: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + lastStageChangedAt: + type: + - string + - "null" + milestone: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + name: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + deleted: + type: + - boolean + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + pictureURL: + type: + - string + - "null" + username: + type: + - string + - "null" + party: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: + - number + - "null" + lastName: + type: + - string + - "null" + pictureURL: + type: + - string + - "null" + probability: + type: + - number + - "null" + updatedAt: + type: string + value: + type: + - object + - "null" + properties: + currency: + type: + - string + - "null" + required: + - id + - updatedAt + pipelines: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + required: + - id + milestones: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + complete: + type: + - boolean + - "null" + createdAt: + type: + - string + - "null" + daysUntilStale: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + pipeline: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + probability: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + required: + - id + site: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + name: + type: + - string + - "null" + subdomain: + type: + - string + - "null" + url: + type: + - string + - "null" + tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + dataTag: + type: + - boolean + - "null" + id: + type: number + name: + type: + - string + - "null" + required: + - id + custom_fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + displayOrder: + type: + - number + - "null" + id: + type: number + important: + type: + - boolean + - "null" + name: + type: + - string + - "null" + options: + type: + - array + - "null" + required: + - id + lost_reasons: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + id: + type: number + includedForConversion: + type: + - boolean + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + required: + - id + board: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + required: + - id + categories: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + colour: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + required: + - id + activity_types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + icon: + type: + - object + - "null" + properties: + displayName: + type: + - string + - "null" + iconName: + type: + - string + - "null" + id: + type: + - string + - "null" + isSystem: + type: + - boolean + - "null" + order: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + updateLastContacted: + type: + - boolean + - "null" + required: + - id + stages: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + board: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + displayOrder: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-capsule-crm/metadata.yaml b/airbyte-integrations/connectors/source-capsule-crm/metadata.yaml new file mode 100644 index 000000000000..aab60d684f14 --- /dev/null +++ b/airbyte-integrations/connectors/source-capsule-crm/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.capsulecrm.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-capsule-crm + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 4f1b8b9c-fa2c-4fc2-b041-e3bde27a0cb1 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-capsule-crm + githubIssueLabel: source-capsule-crm + icon: icon.svg + license: MIT + name: Capsule CRM + releaseDate: 2024-11-09 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/capsule-crm + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-captain-data/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-captain-data/integration_tests/acceptance.py index efc25f08ce82..78b220cebb18 100644 --- a/airbyte-integrations/connectors/source-captain-data/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-captain-data/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-captain-data/metadata.yaml b/airbyte-integrations/connectors/source-captain-data/metadata.yaml index 6feb52aee37d..d01c72b168a4 100644 --- a/airbyte-integrations/connectors/source-captain-data/metadata.yaml +++ b/airbyte-integrations/connectors/source-captain-data/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: fa290790-1dca-43e7-8ced-6a40b2a66099 - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-captain-data githubIssueLabel: source-captain-data icon: captain-data.svg @@ -27,5 +27,5 @@ data: ql: 100 supportLevel: community connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-care-quality-commission/metadata.yaml b/airbyte-integrations/connectors/source-care-quality-commission/metadata.yaml index d8c7d689cf67..adfc345c768f 100644 --- a/airbyte-integrations/connectors/source-care-quality-commission/metadata.yaml +++ b/airbyte-integrations/connectors/source-care-quality-commission/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-care-quality-commission connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 2366b7bf-b83e-471c-b4a0-1405887fdf6e - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.9 dockerRepository: airbyte/source-care-quality-commission githubIssueLabel: source-care-quality-commission icon: icon.svg diff --git a/airbyte-integrations/connectors/source-cart/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-cart/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-cart/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-cart/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-cart/main.py b/airbyte-integrations/connectors/source-cart/main.py index c7f69c914848..53fc51e036f4 100644 --- a/airbyte-integrations/connectors/source-cart/main.py +++ b/airbyte-integrations/connectors/source-cart/main.py @@ -4,5 +4,6 @@ from source_cart.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-cart/metadata.yaml b/airbyte-integrations/connectors/source-cart/metadata.yaml index bed846a4729e..9d6aec03e584 100644 --- a/airbyte-integrations/connectors/source-cart/metadata.yaml +++ b/airbyte-integrations/connectors/source-cart/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:1.2.2@sha256:57703de3b4c4204bd68a7b13c9300f8e03c0189bffddaffc796f1da25d2dbea0 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: bb1a6d31-6879-4819-a2bd-3eed299ea8e2 - dockerImageTag: 0.3.6 + dockerImageTag: 0.3.11 dockerRepository: airbyte/source-cart documentationUrl: https://docs.airbyte.com/integrations/sources/cart githubIssueLabel: source-cart diff --git a/airbyte-integrations/connectors/source-cart/poetry.lock b/airbyte-integrations/connectors/source-cart/poetry.lock index 7f50cbe7a597..1077e5f93884 100644 --- a/airbyte-integrations/connectors/source-cart/poetry.lock +++ b/airbyte-integrations/connectors/source-cart/poetry.lock @@ -62,22 +62,22 @@ files = [ [[package]] name = "attrs" -version = "23.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, - {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] -tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "backoff" @@ -92,35 +92,35 @@ files = [ [[package]] name = "bracex" -version = "2.4" +version = "2.5.post1" description = "Bash style brace expander." optional = false python-versions = ">=3.8" files = [ - {file = "bracex-2.4-py3-none-any.whl", hash = "sha256:efdc71eff95eaff5e0f8cfebe7d01adf2c8637c8c92edaf63ef348c241a82418"}, - {file = "bracex-2.4.tar.gz", hash = "sha256:a27eaf1df42cf561fed58b7a8f3fdf129d1ea16a81e1fadd1d17989bc6384beb"}, + {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, + {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, ] [[package]] name = "cachetools" -version = "5.3.3" +version = "5.5.0" description = "Extensible memoizing collections and decorators" optional = false python-versions = ">=3.7" files = [ - {file = "cachetools-5.3.3-py3-none-any.whl", hash = "sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945"}, - {file = "cachetools-5.3.3.tar.gz", hash = "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"}, + {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, + {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, ] [[package]] name = "cattrs" -version = "23.2.3" +version = "24.1.2" description = "Composable complex class support for attrs and dataclasses." optional = false python-versions = ">=3.8" files = [ - {file = "cattrs-23.2.3-py3-none-any.whl", hash = "sha256:0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108"}, - {file = "cattrs-23.2.3.tar.gz", hash = "sha256:a934090d95abaa9e911dac357e3a8699e0b4b14f8529bcc7d2b1ad9d51672b9f"}, + {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, + {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, ] [package.dependencies] @@ -132,6 +132,7 @@ typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_ver bson = ["pymongo (>=4.4.0)"] cbor2 = ["cbor2 (>=5.4.6)"] msgpack = ["msgpack (>=1.0.5)"] +msgspec = ["msgspec (>=0.18.5)"] orjson = ["orjson (>=3.9.2)"] pyyaml = ["pyyaml (>=6.0)"] tomlkit = ["tomlkit (>=0.11.8)"] @@ -139,112 +140,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.6.2" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, - {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.3.2" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -260,20 +263,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -288,13 +291,13 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.2.1" +version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, - {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, ] [package.extras] @@ -312,15 +315,18 @@ files = [ [[package]] name = "idna" -version = "3.7" +version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, ] +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -348,13 +354,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -397,82 +403,83 @@ format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-va [[package]] name = "markupsafe" -version = "2.1.5" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -511,19 +518,19 @@ pytzdata = ">=2020.1" [[package]] name = "platformdirs" -version = "4.2.2" +version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, - {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "pluggy" @@ -553,54 +560,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.17" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.17-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fa51175313cc30097660b10eec8ca55ed08bfa07acbfe02f7a42f6c242e9a4b"}, - {file = "pydantic-1.10.17-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7e8988bb16988890c985bd2093df9dd731bfb9d5e0860db054c23034fab8f7a"}, - {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:371dcf1831f87c9e217e2b6a0c66842879a14873114ebb9d0861ab22e3b5bb1e"}, - {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4866a1579c0c3ca2c40575398a24d805d4db6cb353ee74df75ddeee3c657f9a7"}, - {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:543da3c6914795b37785703ffc74ba4d660418620cc273490d42c53949eeeca6"}, - {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7623b59876f49e61c2e283551cc3647616d2fbdc0b4d36d3d638aae8547ea681"}, - {file = "pydantic-1.10.17-cp310-cp310-win_amd64.whl", hash = "sha256:409b2b36d7d7d19cd8310b97a4ce6b1755ef8bd45b9a2ec5ec2b124db0a0d8f3"}, - {file = "pydantic-1.10.17-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fa43f362b46741df8f201bf3e7dff3569fa92069bcc7b4a740dea3602e27ab7a"}, - {file = "pydantic-1.10.17-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2a72d2a5ff86a3075ed81ca031eac86923d44bc5d42e719d585a8eb547bf0c9b"}, - {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4ad32aed3bf5eea5ca5decc3d1bbc3d0ec5d4fbcd72a03cdad849458decbc63"}, - {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb4e741782e236ee7dc1fb11ad94dc56aabaf02d21df0e79e0c21fe07c95741"}, - {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d2f89a719411cb234105735a520b7c077158a81e0fe1cb05a79c01fc5eb59d3c"}, - {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db3b48d9283d80a314f7a682f7acae8422386de659fffaba454b77a083c3937d"}, - {file = "pydantic-1.10.17-cp311-cp311-win_amd64.whl", hash = "sha256:9c803a5113cfab7bbb912f75faa4fc1e4acff43e452c82560349fff64f852e1b"}, - {file = "pydantic-1.10.17-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:820ae12a390c9cbb26bb44913c87fa2ff431a029a785642c1ff11fed0a095fcb"}, - {file = "pydantic-1.10.17-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c1e51d1af306641b7d1574d6d3307eaa10a4991542ca324f0feb134fee259815"}, - {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e53fb834aae96e7b0dadd6e92c66e7dd9cdf08965340ed04c16813102a47fab"}, - {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e2495309b1266e81d259a570dd199916ff34f7f51f1b549a0d37a6d9b17b4dc"}, - {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:098ad8de840c92ea586bf8efd9e2e90c6339d33ab5c1cfbb85be66e4ecf8213f"}, - {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:525bbef620dac93c430d5d6bdbc91bdb5521698d434adf4434a7ef6ffd5c4b7f"}, - {file = "pydantic-1.10.17-cp312-cp312-win_amd64.whl", hash = "sha256:6654028d1144df451e1da69a670083c27117d493f16cf83da81e1e50edce72ad"}, - {file = "pydantic-1.10.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c87cedb4680d1614f1d59d13fea353faf3afd41ba5c906a266f3f2e8c245d655"}, - {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11289fa895bcbc8f18704efa1d8020bb9a86314da435348f59745473eb042e6b"}, - {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94833612d6fd18b57c359a127cbfd932d9150c1b72fea7c86ab58c2a77edd7c7"}, - {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d4ecb515fa7cb0e46e163ecd9d52f9147ba57bc3633dca0e586cdb7a232db9e3"}, - {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7017971ffa7fd7808146880aa41b266e06c1e6e12261768a28b8b41ba55c8076"}, - {file = "pydantic-1.10.17-cp37-cp37m-win_amd64.whl", hash = "sha256:e840e6b2026920fc3f250ea8ebfdedf6ea7a25b77bf04c6576178e681942ae0f"}, - {file = "pydantic-1.10.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bfbb18b616abc4df70591b8c1ff1b3eabd234ddcddb86b7cac82657ab9017e33"}, - {file = "pydantic-1.10.17-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebb249096d873593e014535ab07145498957091aa6ae92759a32d40cb9998e2e"}, - {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8c209af63ccd7b22fba94b9024e8b7fd07feffee0001efae50dd99316b27768"}, - {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b40c9e13a0b61583e5599e7950490c700297b4a375b55b2b592774332798b7"}, - {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c31d281c7485223caf6474fc2b7cf21456289dbaa31401844069b77160cab9c7"}, - {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae5184e99a060a5c80010a2d53c99aee76a3b0ad683d493e5f0620b5d86eeb75"}, - {file = "pydantic-1.10.17-cp38-cp38-win_amd64.whl", hash = "sha256:ad1e33dc6b9787a6f0f3fd132859aa75626528b49cc1f9e429cdacb2608ad5f0"}, - {file = "pydantic-1.10.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7e17c0ee7192e54a10943f245dc79e36d9fe282418ea05b886e1c666063a7b54"}, - {file = "pydantic-1.10.17-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cafb9c938f61d1b182dfc7d44a7021326547b7b9cf695db5b68ec7b590214773"}, - {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95ef534e3c22e5abbdbdd6f66b6ea9dac3ca3e34c5c632894f8625d13d084cbe"}, - {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d96b8799ae3d782df7ec9615cb59fc32c32e1ed6afa1b231b0595f6516e8ab"}, - {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ab2f976336808fd5d539fdc26eb51f9aafc1f4b638e212ef6b6f05e753c8011d"}, - {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8ad363330557beac73159acfbeed220d5f1bfcd6b930302a987a375e02f74fd"}, - {file = "pydantic-1.10.17-cp39-cp39-win_amd64.whl", hash = "sha256:48db882e48575ce4b39659558b2f9f37c25b8d348e37a2b4e32971dd5a7d6227"}, - {file = "pydantic-1.10.17-py3-none-any.whl", hash = "sha256:e41b5b973e5c64f674b3b4720286ded184dcc26a691dd55f34391c62c6934688"}, - {file = "pydantic-1.10.17.tar.gz", hash = "sha256:f434160fb14b353caf634149baaf847206406471ba70e64657c1e8330277a991"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -734,62 +741,64 @@ files = [ [[package]] name = "pyyaml" -version = "6.0.1" +version = "6.0.2" description = "YAML parser and emitter for Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] [[package]] @@ -862,28 +871,33 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "70.1.1" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-70.1.1-py3-none-any.whl", hash = "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95"}, - {file = "setuptools-70.1.1.tar.gz", hash = "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -924,13 +938,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.2" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, - {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -955,81 +969,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-cart/pyproject.toml b/airbyte-integrations/connectors/source-cart/pyproject.toml index 3c6b8c8b4795..2315806a8179 100644 --- a/airbyte-integrations/connectors/source-cart/pyproject.toml +++ b/airbyte-integrations/connectors/source-cart/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.3.6" +version = "0.3.11" name = "source-cart" description = "Source implementation for Cart." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-cart/source_cart/source.py b/airbyte-integrations/connectors/source-cart/source_cart/source.py index 15903dd2210c..1bf2c0c918d6 100644 --- a/airbyte-integrations/connectors/source-cart/source_cart/source.py +++ b/airbyte-integrations/connectors/source-cart/source_cart/source.py @@ -13,12 +13,13 @@ import pendulum import requests +from pendulum.parsing.exceptions import ParserError + from airbyte_cdk import AirbyteLogger from airbyte_cdk.models import SyncMode from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http.auth import HttpAuthenticator -from pendulum.parsing.exceptions import ParserError from .streams import Addresses, CustomersCart, OrderItems, OrderPayments, Orders, OrderStatuses, Products diff --git a/airbyte-integrations/connectors/source-cart/source_cart/streams.py b/airbyte-integrations/connectors/source-cart/source_cart/streams.py index f6e31507f38a..1d5d8a95aafa 100644 --- a/airbyte-integrations/connectors/source-cart/source_cart/streams.py +++ b/airbyte-integrations/connectors/source-cart/source_cart/streams.py @@ -9,6 +9,7 @@ from typing import Any, Iterable, Mapping, MutableMapping, Optional, Union import requests + from airbyte_cdk.sources.streams.http import HttpStream from airbyte_cdk.sources.streams.http.auth.core import HttpAuthenticator @@ -93,7 +94,6 @@ def request_params( class IncrementalCartStream(CartStream, ABC): - state_checkpoint_interval = 1000 cursor_field = "updated_at" diff --git a/airbyte-integrations/connectors/source-castor-edc/metadata.yaml b/airbyte-integrations/connectors/source-castor-edc/metadata.yaml index dd43883893fc..f0573f0a07c3 100644 --- a/airbyte-integrations/connectors/source-castor-edc/metadata.yaml +++ b/airbyte-integrations/connectors/source-castor-edc/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-castor-edc connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 2cb45514-7c10-439c-a198-aeb1ddab02cb - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.9 dockerRepository: airbyte/source-castor-edc githubIssueLabel: source-castor-edc icon: icon.svg diff --git a/airbyte-integrations/connectors/source-chameleon/metadata.yaml b/airbyte-integrations/connectors/source-chameleon/metadata.yaml index bd1ee3cb3d99..be0b479f6db1 100644 --- a/airbyte-integrations/connectors/source-chameleon/metadata.yaml +++ b/airbyte-integrations/connectors/source-chameleon/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-chameleon connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 64a0240a-81a4-4e40-8002-e063b17cfbbe - dockerImageTag: 0.1.1 + dockerImageTag: 0.1.6 dockerRepository: airbyte/source-chameleon githubIssueLabel: source-chameleon icon: icon.svg diff --git a/airbyte-integrations/connectors/source-chargebee/acceptance-test-config.yml b/airbyte-integrations/connectors/source-chargebee/acceptance-test-config.yml index 72be3187bb2d..a932817faca9 100644 --- a/airbyte-integrations/connectors/source-chargebee/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-chargebee/acceptance-test-config.yml @@ -32,6 +32,8 @@ acceptance_tests: bypass_reason: "Unstable data. Test data is not persistent. Tested with mocker server tests." - name: "site_migration_detail" bypass_reason: "Cannnot populate with test data." + - name: "contact" + bypass_reason: "Relies on customer as a parent stream and there is a bug where the parent stream is emitting stream statuses on rate limit which leads to CATs failing. See https://github.com/airbytehq/airbyte-internal-issues/issues/10808 for more information." - name: "customer" bypass_reason: "Tested with mocker server tests." - name: "subscription" @@ -45,7 +47,7 @@ acceptance_tests: expect_records: path: "integration_tests/expected_records.jsonl" exact_order: no - validate_state_messages: False + validate_state_messages: false fail_on_extra_columns: true incremental: tests: @@ -53,16 +55,7 @@ acceptance_tests: timeout_seconds: 2400 configured_catalog_path: "integration_tests/configured_catalog.json" future_state: - future_state_path: "integration_tests/future_state.json" - missing_streams: - - name: contact - bypass_reason: "This stream is Full-Refresh only" - - name: quote_line_group - bypass_reason: "This stream is Full-Refresh only" - - name: attached_item - bypass_reason: "This stream is Full-Refresh only" - - name: subscription_with_scheduled_changes - bypass_reason: "This stream is Full-Refresh only" + bypass_reason: "This test does not make sense using Concurrent CDK" full_refresh: tests: - config_path: "secrets/config.json" diff --git a/airbyte-integrations/connectors/source-chargebee/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-chargebee/integration_tests/acceptance.py index 43ce950d77ca..72132012aaed 100644 --- a/airbyte-integrations/connectors/source-chargebee/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-chargebee/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-chargebee/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-chargebee/integration_tests/expected_records.jsonl index 738efeb22afa..4e7aaa5597ac 100644 --- a/airbyte-integrations/connectors/source-chargebee/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-chargebee/integration_tests/expected_records.jsonl @@ -1,6 +1,3 @@ -{"stream": "contact", "data": {"id": "0000002", "first_name": "User2", "last_name": "Sample", "email": "user2.sample.airbyte@gmail.com", "phone": "+13335556789", "label": "Tag2", "enabled": true, "send_account_email": true, "send_billing_email": true, "object": "contact", "customer_id": "Azz5jBTTJ96UqlvE", "custom_fields": []}, "emitted_at": 1706028645460} -{"stream": "contact", "data": {"id": "Test 1", "first_name": "Sample Name 1", "last_name": "Sample Lastname 1", "email": "name1@example.com", "enabled": true, "send_account_email": false, "send_billing_email": false, "object": "contact", "customer_id": "cbdemo_richard", "custom_fields": []}, "emitted_at": 1706028645946} -{"stream": "contact", "data": {"id": "Test Contact 2", "first_name": "Sample Name Two", "last_name": "Sample Lastname 2", "email": "name2@example.com", "phone": "+13888433888", "enabled": true, "send_account_email": false, "send_billing_email": false, "object": "contact", "customer_id": "Test-Custome-1", "custom_fields": []}, "emitted_at": 1706028645251} {"stream": "order", "data": {"id": "1", "document_number": "lol1", "invoice_id": "24", "subscription_id": "6olOsTTHieWUY9", "customer_id": "cbdemo_tyler", "status": "queued", "payment_status": "paid", "order_type": "system_generated", "price_type": "tax_exclusive", "order_date": 1674036524, "shipping_date": 1674036524, "created_by": "Auto generated by system", "tax": 0, "amount_paid": 1000, "amount_adjusted": 0, "refundable_credits_issued": 0, "refundable_credits": 1000, "rounding_adjustement": 0, "paid_on": 1674036524, "exchange_rate": 1.0, "created_at": 1674036525, "updated_at": 1674036525, "is_resent": false, "resource_version": 1674036525755, "deleted": false, "object": "order", "discount": 0, "sub_total": 1000, "order_line_items": [{"id": "o_li169lB6TTHiez02Fb4", "invoice_id": "24", "invoice_line_item_id": "li_6olOsTTHieX6YB", "unit_price": 1000, "amount": 1000, "fulfillment_quantity": 1, "fulfillment_amount": 1000, "tax_amount": 0, "amount_paid": 1000, "amount_adjusted": 0, "refundable_credits_issued": 0, "refundable_credits": 1000, "is_shippable": true, "status": "queued", "object": "order_line_item", "entity_id": "Test-Plan-1-USD-Daily", "discount_amount": 0, "item_level_discount_amount": 0, "description": "Test Plan 1", "entity_type": "plan_item_price"}], "total": 1000, "currency_code": "USD", "base_currency_code": "USD", "is_gifted": false, "billing_address": {"first_name": "Tyler", "last_name": "Durden", "company": "Iselectrics", "validation_status": "not_validated", "object": "billing_address"}, "linked_credit_notes": [], "resent_orders": [], "custom_fields": []}, "emitted_at": 1703026216053} {"stream": "order", "data": {"id": "2", "document_number": "lol2", "invoice_id": "25", "subscription_id": "AzZTZgTTHixMHV3", "customer_id": "cbdemo_richard", "status": "queued", "payment_status": "paid", "order_type": "system_generated", "price_type": "tax_exclusive", "order_date": 1674036596, "shipping_date": 1674036596, "created_by": "Auto generated by system", "tax": 0, "amount_paid": 1000, "amount_adjusted": 0, "refundable_credits_issued": 0, "refundable_credits": 1000, "rounding_adjustement": 0, "paid_on": 1674036596, "exchange_rate": 1.0, "created_at": 1674036599, "updated_at": 1674036684, "is_resent": false, "resource_version": 1674036684213, "deleted": false, "object": "order", "discount": 0, "sub_total": 1000, "order_line_items": [{"id": "o_li16CQyCTTHiy9912Tu", "invoice_id": "25", "invoice_line_item_id": "li_AzZTZgTTHixMhV5", "unit_price": 1000, "amount": 1000, "fulfillment_quantity": 1, "fulfillment_amount": 1000, "tax_amount": 0, "amount_paid": 1000, "amount_adjusted": 0, "refundable_credits_issued": 0, "refundable_credits": 1000, "is_shippable": true, "status": "queued", "object": "order_line_item", "entity_id": "Test-Plan-1-USD-Daily", "discount_amount": 0, "item_level_discount_amount": 0, "description": "Test Plan 1", "entity_type": "plan_item_price"}], "total": 1000, "currency_code": "USD", "base_currency_code": "USD", "is_gifted": false, "shipping_address": {"first_name": "Sample Name 1", "last_name": "Sample Lastname 1", "email": "name1@example.com", "company": "Semiconductors", "phone": "+1 382 846 3883", "line1": "Ms Ninette Franck", "line2": "4381", "city": "San Francisco", "state_code": "CA", "state": "California", "country": "US", "zip": "94114", "validation_status": "not_validated", "object": "shipping_address"}, "billing_address": {"first_name": "Richard", "last_name": "Hendricks", "company": "Zencorporation", "validation_status": "not_validated", "object": "billing_address"}, "linked_credit_notes": [], "resent_orders": [], "custom_fields": []}, "emitted_at": 1703026216060} {"stream": "order", "data": {"id": "3", "document_number": "lol3", "invoice_id": "26", "subscription_id": "AzZTZgTTHmX8Gc1", "customer_id": "cbdemo_simon", "status": "queued", "payment_status": "paid", "order_type": "system_generated", "price_type": "tax_exclusive", "order_date": 1674037448, "shipping_date": 1674037448, "created_by": "Auto generated by system", "tax": 0, "amount_paid": 700, "amount_adjusted": 0, "refundable_credits_issued": 0, "refundable_credits": 700, "rounding_adjustement": 0, "paid_on": 1674037448, "exchange_rate": 1.0, "created_at": 1674037452, "updated_at": 1674037452, "is_resent": false, "resource_version": 1674037452271, "deleted": false, "object": "order", "discount": 300, "sub_total": 700, "order_line_items": [{"id": "o_liAzZZMnTTHmY0s1O7g", "invoice_id": "26", "invoice_line_item_id": "li_AzZTZgTTHmX93c3", "unit_price": 1000, "amount": 1000, "fulfillment_quantity": 1, "fulfillment_amount": 700, "tax_amount": 0, "amount_paid": 700, "amount_adjusted": 0, "refundable_credits_issued": 0, "refundable_credits": 700, "is_shippable": true, "status": "queued", "object": "order_line_item", "entity_id": "Test-Plan-1-USD-Daily", "discount_amount": 300, "item_level_discount_amount": 300, "description": "Test Plan 1", "entity_type": "plan_item_price"}], "line_item_discounts": [{"object": "line_item_discount", "line_item_id": "li_AzZTZgTTHmX93c3", "discount_type": "item_level_coupon", "discount_amount": 300, "coupon_id": "cbdemo_launchoffer", "entity_id": "cbdemo_launchoffer"}], "total": 700, "currency_code": "USD", "base_currency_code": "USD", "is_gifted": false, "billing_address": {"first_name": "Simon", "last_name": "Masrani", "company": "Openlane Ltd", "validation_status": "not_validated", "object": "billing_address"}, "linked_credit_notes": [], "resent_orders": [], "custom_fields": []}, "emitted_at": 1703026216066} diff --git a/airbyte-integrations/connectors/source-chargebee/integration_tests/future_state.json b/airbyte-integrations/connectors/source-chargebee/integration_tests/future_state.json index 56be52da0818..7d611939e0f8 100644 --- a/airbyte-integrations/connectors/source-chargebee/integration_tests/future_state.json +++ b/airbyte-integrations/connectors/source-chargebee/integration_tests/future_state.json @@ -2,7 +2,7 @@ { "type": "STREAM", "stream": { - "stream_state": { "updated_at": 2147483647 }, + "stream_state": { "updated_at": "2147483647" }, "stream_descriptor": { "name": "subscription" } } }, @@ -16,42 +16,42 @@ { "type": "STREAM", "stream": { - "stream_state": { "updated_at": 2147483647 }, + "stream_state": { "updated_at": "2147483647" }, "stream_descriptor": { "name": "coupon" } } }, { "type": "STREAM", "stream": { - "stream_state": { "updated_at": 2147483647 }, + "stream_state": { "updated_at": "2147483647" }, "stream_descriptor": { "name": "customer" } } }, { "type": "STREAM", "stream": { - "stream_state": { "updated_at": 2147483647 }, + "stream_state": { "updated_at": "2147483647" }, "stream_descriptor": { "name": "invoice" } } }, { "type": "STREAM", "stream": { - "stream_state": { "updated_at": 2147483647 }, + "stream_state": { "updated_at": "2147483647" }, "stream_descriptor": { "name": "credit_note" } } }, { "type": "STREAM", "stream": { - "stream_state": { "updated_at": 2147483647 }, + "stream_state": { "updated_at": "2147483647" }, "stream_descriptor": { "name": "order" } } }, { "type": "STREAM", "stream": { - "stream_state": { "updated_at": 2147483647 }, + "stream_state": { "updated_at": "2147483647" }, "stream_descriptor": { "name": "item" } } }, @@ -65,91 +65,91 @@ { "type": "STREAM", "stream": { - "stream_state": { "updated_at": 2147483647 }, + "stream_state": { "updated_at": "2147483647" }, "stream_descriptor": { "name": "hosted_page" } } }, { "type": "STREAM", "stream": { - "stream_state": { "updated_at": 2147483647 }, + "stream_state": { "updated_at": "2147483647" }, "stream_descriptor": { "name": "item_price" } } }, { "type": "STREAM", "stream": { - "stream_state": { "updated_at": 2147483647 }, + "stream_state": { "updated_at": "2147483647" }, "stream_descriptor": { "name": "payment_source" } } }, { "type": "STREAM", "stream": { - "stream_state": { "created_at": 2147483647 }, + "stream_state": { "created_at": "2147483647" }, "stream_descriptor": { "name": "promotional_credit" } } }, { "type": "STREAM", "stream": { - "stream_state": { "updated_at": 2147483647 }, + "stream_state": { "updated_at": "2147483647" }, "stream_descriptor": { "name": "gift" } } }, { "type": "STREAM", "stream": { - "stream_state": { "updated_at": 2147483647 }, + "stream_state": { "updated_at": "2147483647" }, "stream_descriptor": { "name": "unbilled_charge" } } }, { "type": "STREAM", "stream": { - "stream_state": { "updated_at": 2147483647 }, + "stream_state": { "updated_at": "2147483647" }, "stream_descriptor": { "name": "quote" } } }, { "type": "STREAM", "stream": { - "stream_state": { "updated_at": 2147483647 }, + "stream_state": { "updated_at": "2147483647" }, "stream_descriptor": { "name": "transaction" } } }, { "type": "STREAM", "stream": { - "stream_state": { "created_at": 2147483647 }, + "stream_state": { "created_at": "2147483647" }, "stream_descriptor": { "name": "comment" } } }, { "type": "STREAM", "stream": { - "stream_state": { "updated_at": 2147483647 }, + "stream_state": { "updated_at": "2147483647" }, "stream_descriptor": { "name": "item_family" } } }, { "type": "STREAM", "stream": { - "stream_state": { "updated_at": 2147483647 }, + "stream_state": { "updated_at": "2147483647" }, "stream_descriptor": { "name": "differential_price" } } }, { "type": "STREAM", "stream": { - "stream_state": { "migrated_at": 2147483647 }, + "stream_state": { "migrated_at": "2147483647" }, "stream_descriptor": { "name": "site_migration_detail" } } }, { "type": "STREAM", "stream": { - "stream_state": { "occurred_at": 2147483647 }, + "stream_state": { "occurred_at": "2147483647" }, "stream_descriptor": { "name": "event" } } } diff --git a/airbyte-integrations/connectors/source-chargebee/main.py b/airbyte-integrations/connectors/source-chargebee/main.py index 351ea1590b35..00e55c1473d3 100644 --- a/airbyte-integrations/connectors/source-chargebee/main.py +++ b/airbyte-integrations/connectors/source-chargebee/main.py @@ -4,5 +4,6 @@ from source_chargebee.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-chargebee/metadata.yaml b/airbyte-integrations/connectors/source-chargebee/metadata.yaml index 32042e791341..427a4515c135 100644 --- a/airbyte-integrations/connectors/source-chargebee/metadata.yaml +++ b/airbyte-integrations/connectors/source-chargebee/metadata.yaml @@ -10,7 +10,7 @@ data: connectorSubtype: api connectorType: source definitionId: 686473f1-76d9-4994-9cc7-9b13da46147c - dockerImageTag: 0.6.17 + dockerImageTag: 0.7.2 dockerRepository: airbyte/source-chargebee documentationUrl: https://docs.airbyte.com/integrations/sources/chargebee githubIssueLabel: source-chargebee diff --git a/airbyte-integrations/connectors/source-chargebee/poetry.lock b/airbyte-integrations/connectors/source-chargebee/poetry.lock index 26e63325f7dd..d3e2003d8caa 100644 --- a/airbyte-integrations/connectors/source-chargebee/poetry.lock +++ b/airbyte-integrations/connectors/source-chargebee/poetry.lock @@ -1,60 +1,64 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "airbyte-cdk" -version = "5.16.0" +version = "6.6.1" description = "A framework for writing Airbyte Connectors." optional = false python-versions = "<4.0,>=3.10" files = [ - {file = "airbyte_cdk-5.16.0-py3-none-any.whl", hash = "sha256:71f909ffc489e3c20ee2ee8a307fe30035bc3f62b221951ede1f2063b76b49a9"}, - {file = "airbyte_cdk-5.16.0.tar.gz", hash = "sha256:1f214a93c3ec20c047d13c4612de0cdaf76fb87e8f312fd7a8ea1e216ad1794a"}, + {file = "airbyte_cdk-6.6.1-py3-none-any.whl", hash = "sha256:b3f06f859fdf51bfcfe96cc91a7149e21cd172e55964be283052c655bd3d1eae"}, + {file = "airbyte_cdk-6.6.1.tar.gz", hash = "sha256:3c89222deb9ae3684bfcee1d015c6b248db07e0e4ab708e283ecc2be8e1d0792"}, ] [package.dependencies] airbyte-protocol-models-dataclasses = ">=0.13,<0.14" backoff = "*" cachetools = "*" -cryptography = ">=42.0.5,<43.0.0" +cryptography = ">=42.0.5,<44.0.0" Deprecated = ">=1.2,<1.3" dpath = ">=2.1.6,<3.0.0" -genson = "1.2.2" +dunamai = ">=1.22.0,<2.0.0" +genson = "1.3.0" isodate = ">=0.6.1,<0.7.0" Jinja2 = ">=3.1.2,<3.2.0" jsonref = ">=0.2,<0.3" jsonschema = ">=3.2.0,<3.3.0" langchain_core = "0.1.42" nltk = "3.8.1" +numpy = "<2" orjson = ">=3.10.7,<4.0.0" pandas = "2.2.2" pendulum = "<3.0.0" +psutil = "6.1.0" pydantic = ">=2.7,<3.0" pyjwt = ">=2.8.0,<3.0.0" pyrate-limiter = ">=3.1.0,<3.2.0" python-dateutil = "*" +python-ulid = ">=3.0.0,<4.0.0" pytz = "2024.1" PyYAML = ">=6.0.1,<7.0.0" requests = "*" requests_cache = "*" serpyco-rs = ">=1.10.2,<2.0.0" -wcmatch = "8.4" +wcmatch = "10.0" xmltodict = ">=0.13.0,<0.14.0" [package.extras] file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "python-snappy (==0.7.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] sql = ["sqlalchemy (>=2.0,!=2.0.36,<3.0)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] +vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.8.0)"] [[package]] name = "airbyte-protocol-models-dataclasses" -version = "0.13.0" +version = "0.13.1" description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models_dataclasses-0.13.0-py3-none-any.whl", hash = "sha256:0aedb99ffc4f9aab0ce91bba2c292fa17cd8fd4b42eeba196d6a16c20bbbd7a5"}, - {file = "airbyte_protocol_models_dataclasses-0.13.0.tar.gz", hash = "sha256:72e67850d661e2808406aec5839b3158ebb94d3553b798dbdae1b4a278548d2f"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1-py3-none-any.whl", hash = "sha256:20a734b7b1c3479a643777830db6a2e0a34428f33d16abcfd320552576fabe5a"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1.tar.gz", hash = "sha256:ec6a0fb6b16267bde910f52279445d06c8e1a3e4ed82ac2937b405ab280449d5"}, ] [[package]] @@ -420,43 +424,38 @@ files = [ [[package]] name = "cryptography" -version = "42.0.8" +version = "43.0.3" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, + {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, + {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, + {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, + {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, + {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, + {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, + {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, ] [package.dependencies] @@ -469,7 +468,7 @@ nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] [[package]] @@ -500,6 +499,20 @@ files = [ {file = "dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e"}, ] +[[package]] +name = "dunamai" +version = "1.22.0" +description = "Dynamic version generation" +optional = false +python-versions = ">=3.5" +files = [ + {file = "dunamai-1.22.0-py3-none-any.whl", hash = "sha256:eab3894b31e145bd028a74b13491c57db01986a7510482c9b5fff3b4e53d77b7"}, + {file = "dunamai-1.22.0.tar.gz", hash = "sha256:375a0b21309336f0d8b6bbaea3e038c36f462318c68795166e31f9873fdad676"}, +] + +[package.dependencies] +packaging = ">=20.9" + [[package]] name = "exceptiongroup" version = "1.2.2" @@ -530,12 +543,13 @@ python-dateutil = ">=2.7" [[package]] name = "genson" -version = "1.2.2" +version = "1.3.0" description = "GenSON is a powerful, user-friendly JSON Schema generator." optional = false python-versions = "*" files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, + {file = "genson-1.3.0-py3-none-any.whl", hash = "sha256:468feccd00274cc7e4c09e84b08704270ba8d95232aa280f65b986139cec67f7"}, + {file = "genson-1.3.0.tar.gz", hash = "sha256:e02db9ac2e3fd29e65b5286f7135762e2cd8a986537c075b06fc5f1517308e37"}, ] [[package]] @@ -551,13 +565,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -743,13 +757,13 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.143" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.143-py3-none-any.whl", hash = "sha256:ba0d827269e9b03a90fababe41fa3e4e3f833300b95add10184f7e67167dde6f"}, + {file = "langsmith-0.1.143.tar.gz", hash = "sha256:4c5159e5cd84b3f8499433009e72d2076dd2daf6c044ac8a3611b30d0d0161c5"}, ] [package.dependencies] @@ -856,131 +870,114 @@ twitter = ["twython"] [[package]] name = "numpy" -version = "2.1.2" +version = "1.26.4" description = "Fundamental package for array computing in Python" optional = false -python-versions = ">=3.10" -files = [ - {file = "numpy-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466"}, - {file = "numpy-2.1.2-cp310-cp310-win32.whl", hash = "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb"}, - {file = "numpy-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146"}, - {file = "numpy-2.1.2-cp311-cp311-win32.whl", hash = "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c"}, - {file = "numpy-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142"}, - {file = "numpy-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550"}, - {file = "numpy-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe"}, - {file = "numpy-2.1.2-cp313-cp313-win32.whl", hash = "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a"}, - {file = "numpy-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e"}, - {file = "numpy-2.1.2.tar.gz", hash = "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c"}, +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, ] [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.11" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.11-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6dade64687f2bd7c090281652fe18f1151292d567a9302b34c2dbb92a3872f1f"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82f07c550a6ccd2b9290849b22316a609023ed851a87ea888c0456485a7d196a"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd9a187742d3ead9df2e49240234d728c67c356516cf4db018833a86f20ec18c"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77b0fed6f209d76c1c39f032a70df2d7acf24b1812ca3e6078fd04e8972685a3"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63fc9d5fe1d4e8868f6aae547a7b8ba0a2e592929245fff61d633f4caccdcdd6"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65cd3e3bb4fbb4eddc3c1e8dce10dc0b73e808fcb875f9fab40c81903dd9323e"}, + {file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6f67c570602300c4befbda12d153113b8974a3340fdcf3d6de095ede86c06d92"}, + {file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1f39728c7f7d766f1f5a769ce4d54b5aaa4c3f92d5b84817053cc9995b977acc"}, + {file = "orjson-3.10.11-cp310-none-win32.whl", hash = "sha256:1789d9db7968d805f3d94aae2c25d04014aae3a2fa65b1443117cd462c6da647"}, + {file = "orjson-3.10.11-cp310-none-win_amd64.whl", hash = "sha256:5576b1e5a53a5ba8f8df81872bb0878a112b3ebb1d392155f00f54dd86c83ff6"}, + {file = "orjson-3.10.11-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1444f9cb7c14055d595de1036f74ecd6ce15f04a715e73f33bb6326c9cef01b6"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdec57fe3b4bdebcc08a946db3365630332dbe575125ff3d80a3272ebd0ddafe"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4eed32f33a0ea6ef36ccc1d37f8d17f28a1d6e8eefae5928f76aff8f1df85e67"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80df27dd8697242b904f4ea54820e2d98d3f51f91e97e358fc13359721233e4b"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:705f03cee0cb797256d54de6695ef219e5bc8c8120b6654dd460848d57a9af3d"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03246774131701de8e7059b2e382597da43144a9a7400f178b2a32feafc54bd5"}, + {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8b5759063a6c940a69c728ea70d7c33583991c6982915a839c8da5f957e0103a"}, + {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:677f23e32491520eebb19c99bb34675daf5410c449c13416f7f0d93e2cf5f981"}, + {file = "orjson-3.10.11-cp311-none-win32.whl", hash = "sha256:a11225d7b30468dcb099498296ffac36b4673a8398ca30fdaec1e6c20df6aa55"}, + {file = "orjson-3.10.11-cp311-none-win_amd64.whl", hash = "sha256:df8c677df2f9f385fcc85ab859704045fa88d4668bc9991a527c86e710392bec"}, + {file = "orjson-3.10.11-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:360a4e2c0943da7c21505e47cf6bd725588962ff1d739b99b14e2f7f3545ba51"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:496e2cb45de21c369079ef2d662670a4892c81573bcc143c4205cae98282ba97"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7dfa8db55c9792d53c5952900c6a919cfa377b4f4534c7a786484a6a4a350c19"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:51f3382415747e0dbda9dade6f1e1a01a9d37f630d8c9049a8ed0e385b7a90c0"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f35a1b9f50a219f470e0e497ca30b285c9f34948d3c8160d5ad3a755d9299433"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f3b7c5803138e67028dde33450e054c87e0703afbe730c105f1fcd873496d5"}, + {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f91d9eb554310472bd09f5347950b24442600594c2edc1421403d7610a0998fd"}, + {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dfbb2d460a855c9744bbc8e36f9c3a997c4b27d842f3d5559ed54326e6911f9b"}, + {file = "orjson-3.10.11-cp312-none-win32.whl", hash = "sha256:d4a62c49c506d4d73f59514986cadebb7e8d186ad510c518f439176cf8d5359d"}, + {file = "orjson-3.10.11-cp312-none-win_amd64.whl", hash = "sha256:f1eec3421a558ff7a9b010a6c7effcfa0ade65327a71bb9b02a1c3b77a247284"}, + {file = "orjson-3.10.11-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c46294faa4e4d0eb73ab68f1a794d2cbf7bab33b1dda2ac2959ffb7c61591899"}, + {file = "orjson-3.10.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52e5834d7d6e58a36846e059d00559cb9ed20410664f3ad156cd2cc239a11230"}, + {file = "orjson-3.10.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2fc947e5350fdce548bfc94f434e8760d5cafa97fb9c495d2fef6757aa02ec0"}, + {file = "orjson-3.10.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0efabbf839388a1dab5b72b5d3baedbd6039ac83f3b55736eb9934ea5494d258"}, + {file = "orjson-3.10.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3f29634260708c200c4fe148e42b4aae97d7b9fee417fbdd74f8cfc265f15b0"}, + {file = "orjson-3.10.11-cp313-none-win32.whl", hash = "sha256:1a1222ffcee8a09476bbdd5d4f6f33d06d0d6642df2a3d78b7a195ca880d669b"}, + {file = "orjson-3.10.11-cp313-none-win_amd64.whl", hash = "sha256:bc274ac261cc69260913b2d1610760e55d3c0801bb3457ba7b9004420b6b4270"}, + {file = "orjson-3.10.11-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:19b3763e8bbf8ad797df6b6b5e0fc7c843ec2e2fc0621398534e0c6400098f87"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1be83a13312e5e58d633580c5eb8d0495ae61f180da2722f20562974188af205"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:afacfd1ab81f46dedd7f6001b6d4e8de23396e4884cd3c3436bd05defb1a6446"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb4d0bea56bba596723d73f074c420aec3b2e5d7d30698bc56e6048066bd560c"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96ed1de70fcb15d5fed529a656df29f768187628727ee2788344e8a51e1c1350"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bfb30c891b530f3f80e801e3ad82ef150b964e5c38e1fb8482441c69c35c61c"}, + {file = "orjson-3.10.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d496c74fc2b61341e3cefda7eec21b7854c5f672ee350bc55d9a4997a8a95204"}, + {file = "orjson-3.10.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:655a493bac606655db9a47fe94d3d84fc7f3ad766d894197c94ccf0c5408e7d3"}, + {file = "orjson-3.10.11-cp38-none-win32.whl", hash = "sha256:b9546b278c9fb5d45380f4809e11b4dd9844ca7aaf1134024503e134ed226161"}, + {file = "orjson-3.10.11-cp38-none-win_amd64.whl", hash = "sha256:b592597fe551d518f42c5a2eb07422eb475aa8cfdc8c51e6da7054b836b26782"}, + {file = "orjson-3.10.11-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c95f2ecafe709b4e5c733b5e2768ac569bed308623c85806c395d9cca00e08af"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80c00d4acded0c51c98754fe8218cb49cb854f0f7eb39ea4641b7f71732d2cb7"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:461311b693d3d0a060439aa669c74f3603264d4e7a08faa68c47ae5a863f352d"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52ca832f17d86a78cbab86cdc25f8c13756ebe182b6fc1a97d534051c18a08de"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c57ea78a753812f528178aa2f1c57da633754c91d2124cb28991dab4c79a54"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7fcfc6f7ca046383fb954ba528587e0f9336828b568282b27579c49f8e16aad"}, + {file = "orjson-3.10.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:86b9dd983857970c29e4c71bb3e95ff085c07d3e83e7c46ebe959bac07ebd80b"}, + {file = "orjson-3.10.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4d83f87582d223e54efb2242a79547611ba4ebae3af8bae1e80fa9a0af83bb7f"}, + {file = "orjson-3.10.11-cp39-none-win32.whl", hash = "sha256:9fd0ad1c129bc9beb1154c2655f177620b5beaf9a11e0d10bac63ef3fce96950"}, + {file = "orjson-3.10.11-cp39-none-win_amd64.whl", hash = "sha256:10f416b2a017c8bd17f325fb9dee1fb5cdd7a54e814284896b7c3f2763faa017"}, + {file = "orjson-3.10.11.tar.gz", hash = "sha256:e35b6d730de6384d5b2dab5fd23f0d76fae8bbc8c353c2f78210aa5fa4beb3ef"}, ] [[package]] @@ -1131,6 +1128,36 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "psutil" +version = "6.1.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, +] + +[package.extras] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + [[package]] name = "py" version = "1.11.0" @@ -1402,6 +1429,20 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "python-ulid" +version = "3.0.0" +description = "Universally unique lexicographically sortable identifier" +optional = false +python-versions = ">=3.9" +files = [ + {file = "python_ulid-3.0.0-py3-none-any.whl", hash = "sha256:e4c4942ff50dbd79167ad01ac725ec58f924b4018025ce22c858bfcff99a5e31"}, + {file = "python_ulid-3.0.0.tar.gz", hash = "sha256:e50296a47dc8209d28629a22fc81ca26c00982c78934bd7766377ba37ea49a9f"}, +] + +[package.extras] +pydantic = ["pydantic (>=2.0)"] + [[package]] name = "pytz" version = "2024.1" @@ -1488,105 +1529,105 @@ files = [ [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -1727,23 +1768,23 @@ typing-extensions = "*" [[package]] name = "setuptools" -version = "75.2.0" +version = "75.5.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.5.0-py3-none-any.whl", hash = "sha256:87cb777c3b96d638ca02031192d40390e0ad97737e27b6b4fa831bea86f2f829"}, + {file = "setuptools-75.5.0.tar.gz", hash = "sha256:5c4ccb41111392671f02bb5f8436dfc5a9a7185e80500531b133f5775c4163ef"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib-metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" @@ -1795,13 +1836,13 @@ files = [ [[package]] name = "tqdm" -version = "4.66.5" +version = "4.67.0" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd"}, - {file = "tqdm-4.66.5.tar.gz", hash = "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad"}, + {file = "tqdm-4.67.0-py3-none-any.whl", hash = "sha256:0cd8af9d56911acab92182e88d763100d4788bdf421d251616040cc4d44863be"}, + {file = "tqdm-4.67.0.tar.gz", hash = "sha256:fe5a6f95e6fe0b9755e9469b77b9c3cf850048224ecaa8293d7d2d31f97d869a"}, ] [package.dependencies] @@ -1809,6 +1850,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -1868,13 +1910,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "wcmatch" -version = "8.4" +version = "10.0" description = "Wildcard/glob file name matcher." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, + {file = "wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a"}, + {file = "wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a"}, ] [package.dependencies] @@ -1973,4 +2015,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.10,<3.12" -content-hash = "2c6d4faf7e1836ea62aa4c9ac879d18b0b9f29f2d5f0efa2e233170ee6b18b73" +content-hash = "e4e7dd9ffced02e4363b0f1e8dde3125b2d440a472164d010dd1962c6f8731ee" diff --git a/airbyte-integrations/connectors/source-chargebee/pyproject.toml b/airbyte-integrations/connectors/source-chargebee/pyproject.toml index ccee2fe59ffa..bcc032415d09 100644 --- a/airbyte-integrations/connectors/source-chargebee/pyproject.toml +++ b/airbyte-integrations/connectors/source-chargebee/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.6.17" +version = "0.7.2" name = "source-chargebee" description = "Source implementation for Chargebee." authors = [ "Airbyte ",] @@ -17,7 +17,7 @@ include = "source_chargebee" [tool.poetry.dependencies] python = "^3.10,<3.12" -airbyte-cdk = "^5" +airbyte-cdk = "^6" [tool.poetry.scripts] source-chargebee = "source_chargebee.run:run" diff --git a/airbyte-integrations/connectors/source-chargebee/source_chargebee/components.py b/airbyte-integrations/connectors/source-chargebee/source_chargebee/components.py index 0f05242ec89e..5df32652c8c5 100644 --- a/airbyte-integrations/connectors/source-chargebee/source_chargebee/components.py +++ b/airbyte-integrations/connectors/source-chargebee/source_chargebee/components.py @@ -155,7 +155,6 @@ def set(self) -> None: @dataclass class IncrementalSingleSliceCursor(DeclarativeCursor): - cursor_field: Union[InterpolatedString, str] config: Config parameters: InitVar[Mapping[str, Any]] diff --git a/airbyte-integrations/connectors/source-chargebee/source_chargebee/manifest.yaml b/airbyte-integrations/connectors/source-chargebee/source_chargebee/manifest.yaml index e4ff9489892c..27c2d5e12ee8 100644 --- a/airbyte-integrations/connectors/source-chargebee/source_chargebee/manifest.yaml +++ b/airbyte-integrations/connectors/source-chargebee/source_chargebee/manifest.yaml @@ -21,10 +21,11 @@ definitions: error_handlers: - type: DefaultErrorHandler response_filters: - - error_message_contains: "This API operation is not enabled for this site" + - predicate: "{{ 'api_error_code' in response and response['api_error_code'] == 'configuration_incompatible' }}" action: IGNORE error_message: "Stream is available only for Product Catalog 1.0" - type: DefaultErrorHandler + max_retries: 10 backoff_strategies: - type: WaitTimeFromHeader header: "Retry-After" @@ -34,8 +35,8 @@ definitions: datetime: "{{ format_datetime(config['start_date'], '%s') }}" datetime_format: "%s" end_datetime: - datetime: "{{ now_utc().strftime('%s') }}" - datetime_format: "%s" + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" datetime_format: "%s" cursor_granularity: PT1S step: P1M @@ -311,9 +312,14 @@ definitions: transformations: - type: CustomTransformation class_name: source_chargebee.components.CustomFieldTransformation + - type: AddFields + fields: + - path: ["subscription_id"] + value_type: string + value: "{{ stream_slice.subscription_id }}" $parameters: name: "subscription_with_scheduled_changes" - primary_key: "id" + primary_key: "subscription_id" path: "/subscriptions/{{ stream_slice.subscription_id }}/retrieve_with_scheduled_changes" transaction_stream: $ref: "#/definitions/base_incremental_stream" @@ -464,3 +470,15 @@ streams: check: stream_names: - "event" + +# Chargebee offers three tiers of rate limits: +# - Starter: 150 req/min (2.5 req/sec) +# - Performance: 1000 req/min (16 req/sec) +# - Enterprise: 3500 req/min (58 req/sec) +# +# We use defer to a level of 3 because we assume by default that customers are on the Starter tier, but +# customers can specify a higher concurrency level as needed up to the theoretical max rate limit. +concurrency_level: + type: ConcurrencyLevel + default_concurrency: "{{ config.get('num_workers', 3) }}" + max_concurrency: 50 diff --git a/airbyte-integrations/connectors/source-chargebee/source_chargebee/run.py b/airbyte-integrations/connectors/source-chargebee/source_chargebee/run.py index 5c0b427da197..d410d2cc2590 100644 --- a/airbyte-integrations/connectors/source-chargebee/source_chargebee/run.py +++ b/airbyte-integrations/connectors/source-chargebee/source_chargebee/run.py @@ -4,11 +4,50 @@ import sys +import traceback +from datetime import datetime +from typing import List -from airbyte_cdk.entrypoint import launch +from orjson import orjson from source_chargebee import SourceChargebee +from airbyte_cdk.entrypoint import AirbyteEntrypoint, launch +from airbyte_cdk.models import AirbyteErrorTraceMessage, AirbyteMessage, AirbyteMessageSerializer, AirbyteTraceMessage, TraceType, Type + + +def _get_source(args: List[str]): + catalog_path = AirbyteEntrypoint.extract_catalog(args) + config_path = AirbyteEntrypoint.extract_config(args) + state_path = AirbyteEntrypoint.extract_state(args) + try: + return SourceChargebee( + SourceChargebee.read_catalog(catalog_path) if catalog_path else None, + SourceChargebee.read_config(config_path) if config_path else None, + SourceChargebee.read_state(state_path) if state_path else None, + ) + except Exception as error: + print( + orjson.dumps( + AirbyteMessageSerializer.dump( + AirbyteMessage( + type=Type.TRACE, + trace=AirbyteTraceMessage( + type=TraceType.ERROR, + emitted_at=int(datetime.now().timestamp() * 1000), + error=AirbyteErrorTraceMessage( + message=f"Error starting the sync. This could be due to an invalid configuration or catalog. Please contact Support for assistance. Error: {error}", + stack_trace=traceback.format_exc(), + ), + ), + ) + ) + ).decode() + ) + return None + def run(): - source = SourceChargebee() - launch(source, sys.argv[1:]) + _args = sys.argv[1:] + source = _get_source(_args) + if source: + launch(source, _args) diff --git a/airbyte-integrations/connectors/source-chargebee/source_chargebee/schemas/subscription_with_scheduled_changes.json b/airbyte-integrations/connectors/source-chargebee/source_chargebee/schemas/subscription_with_scheduled_changes.json index 5bf8160b1990..4be2a11aa9b7 100644 --- a/airbyte-integrations/connectors/source-chargebee/source_chargebee/schemas/subscription_with_scheduled_changes.json +++ b/airbyte-integrations/connectors/source-chargebee/source_chargebee/schemas/subscription_with_scheduled_changes.json @@ -3,7 +3,7 @@ "name": "Subscription", "type": "object", "properties": { - "id": { + "subscription_id": { "description": "The unique ID of the subscription.", "type": ["string", "null"] }, diff --git a/airbyte-integrations/connectors/source-chargebee/source_chargebee/source.py b/airbyte-integrations/connectors/source-chargebee/source_chargebee/source.py index 23186cfaa5cd..1f6e516955b3 100644 --- a/airbyte-integrations/connectors/source-chargebee/source_chargebee/source.py +++ b/airbyte-integrations/connectors/source-chargebee/source_chargebee/source.py @@ -2,7 +2,12 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # +from typing import Any, Mapping, Optional + +from airbyte_cdk.models import ConfiguredAirbyteCatalog from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource +from airbyte_cdk.sources.source import TState + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into @@ -14,5 +19,5 @@ # Declarative Source class SourceChargebee(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) + def __init__(self, catalog: Optional[ConfiguredAirbyteCatalog], config: Optional[Mapping[str, Any]], state: TState, **kwargs): + super().__init__(catalog=catalog, config=config, state=state, **{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-chargebee/source_chargebee/spec.yaml b/airbyte-integrations/connectors/source-chargebee/source_chargebee/spec.yaml index 34e151cf6c6c..b71480802d0a 100644 --- a/airbyte-integrations/connectors/source-chargebee/source_chargebee/spec.yaml +++ b/airbyte-integrations/connectors/source-chargebee/source_chargebee/spec.yaml @@ -38,3 +38,15 @@ connectionSpecification: enum: ["1.0", "2.0"] default: "2.0" order: 3 + num_workers: + type: integer + title: Number of concurrent workers + minimum: 1 + maximum: 50 + default: 3 + examples: [1, 2, 3] + description: >- + The number of worker threads to use for the sync. + The performance upper boundary is based on the limit of your Chargebee plan. + More info about the rate limit plan tiers can be found on Chargebee's API docs. + order: 4 diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/config.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/config.py index 85f0de928865..65fdee149555 100644 --- a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/config.py +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/config.py @@ -10,7 +10,7 @@ def __init__(self) -> None: "site": "ConfigBuilder default site", "site_api_key": "ConfigBuilder default site api key", "start_date": "2023-01-01T06:57:44Z", - "product_catalog": "2.0" + "product_catalog": "2.0", } def with_site(self, site: str) -> "ConfigBuilder": @@ -30,4 +30,4 @@ def with_product_catalog(self, product_catalog: str) -> "ConfigBuilder": return self def build(self) -> Dict[str, Any]: - return self._config \ No newline at end of file + return self._config diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/pagination.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/pagination.py index 0cf9d9d5a5bc..f5cd872ef7c0 100644 --- a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/pagination.py +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/pagination.py @@ -8,4 +8,4 @@ class ChargebeePaginationStrategy(PaginationStrategy): @staticmethod def update(response: Dict[str, Any]) -> None: - response["next_offset"] = "[1707076198000,57873868]" \ No newline at end of file + response["next_offset"] = "[1707076198000,57873868]" diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/request_builder.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/request_builder.py index 1b97d9e4d6fb..2429e0af5855 100644 --- a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/request_builder.py +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/request_builder.py @@ -9,7 +9,6 @@ class ChargebeeRequestBuilder: - @classmethod def addon_endpoint(cls, site: str, site_api_key: str) -> "ChargebeeRequestBuilder": return cls("addons", site, site_api_key) @@ -69,7 +68,7 @@ def with_include_deleted(self, include_deleted: bool) -> "ChargebeeRequestBuilde return self def with_created_at_btw(self, created_at_btw: List[int]) -> "ChargebeeRequestBuilder": - self._created_at_btw = f'{created_at_btw}' + self._created_at_btw = f"{created_at_btw}" return self def with_updated_at_btw(self, updated_at_btw: List[int]) -> "ChargebeeRequestBuilder": @@ -97,7 +96,7 @@ def with_limit(self, limit: int) -> "ChargebeeRequestBuilder": return self def build(self) -> HttpRequest: - query_params= {} + query_params = {} if self._sort_by_asc: query_params["sort_by[asc]"] = self._sort_by_asc if self._sort_by_desc: @@ -117,7 +116,9 @@ def build(self) -> HttpRequest: if self._any_query_params: if query_params: - raise ValueError(f"Both `any_query_params` and {list(query_params.keys())} were configured. Provide only one of none but not both.") + raise ValueError( + f"Both `any_query_params` and {list(query_params.keys())} were configured. Provide only one of none but not both." + ) query_params = ANY_QUERY_PARAMS return HttpRequest( @@ -126,8 +127,8 @@ def build(self) -> HttpRequest: headers={"Authorization": f"Basic {base64.b64encode((str(self._site_api_key) + ':').encode('utf-8')).decode('utf-8')}"}, ) -class ChargebeeSubstreamRequestBuilder(ChargebeeRequestBuilder): +class ChargebeeSubstreamRequestBuilder(ChargebeeRequestBuilder): @classmethod def subscription_with_scheduled_changes_endpoint(cls, site: str, site_api_key: str) -> "ChargebeeRequestBuilder": return cls("subscriptions", site, site_api_key) @@ -141,7 +142,7 @@ def with_endpoint_path(self, endpoint_path: str) -> "ChargebeeSubstreamRequestBu return self def build(self) -> HttpRequest: - query_params= {} + query_params = {} if self._sort_by_asc: query_params["sort_by[asc]"] = self._sort_by_asc if self._sort_by_desc: @@ -161,7 +162,9 @@ def build(self) -> HttpRequest: if self._any_query_params: if query_params: - raise ValueError(f"Both `any_query_params` and {list(query_params.keys())} were configured. Provide only one of none but not both.") + raise ValueError( + f"Both `any_query_params` and {list(query_params.keys())} were configured. Provide only one of none but not both." + ) query_params = ANY_QUERY_PARAMS return HttpRequest( diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/response_builder.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/response_builder.py index f9163b6be3a8..838fb8d82dc7 100644 --- a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/response_builder.py +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/response_builder.py @@ -10,5 +10,6 @@ def a_response_with_status(status_code: int) -> HttpResponse: return HttpResponse(json.dumps(find_template(str(status_code), __file__)), status_code) + def a_response_with_status_and_header(status_code: int, header: Mapping[str, str]) -> HttpResponse: - return HttpResponse(json.dumps(find_template(str(status_code), __file__)), status_code, header) \ No newline at end of file + return HttpResponse(json.dumps(find_template(str(status_code), __file__)), status_code, header) diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_addon.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_addon.py index 877c571b3bc1..cf14caaf96ac 100644 --- a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_addon.py +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_addon.py @@ -5,6 +5,8 @@ from unittest import TestCase import freezegun +from source_chargebee import SourceChargebee + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read @@ -19,13 +21,13 @@ find_template, ) from airbyte_cdk.test.state_builder import StateBuilder -from source_chargebee import SourceChargebee from .config import ConfigBuilder from .pagination import ChargebeePaginationStrategy from .request_builder import ChargebeeRequestBuilder from .response_builder import a_response_with_status, a_response_with_status_and_header + _STREAM_NAME = "addon" _SITE = "test-site" _SITE_API_KEY = "test-api-key" @@ -35,46 +37,49 @@ _NO_STATE = {} _NOW = datetime.now(timezone.utc) + def _a_request() -> ChargebeeRequestBuilder: return ChargebeeRequestBuilder.addon_endpoint(_SITE, _SITE_API_KEY) + def _config() -> ConfigBuilder: return ConfigBuilder().with_site(_SITE).with_site_api_key(_SITE_API_KEY).with_product_catalog(_PRODUCT_CATALOG) + def _catalog(sync_mode: SyncMode) -> ConfiguredAirbyteCatalog: return CatalogBuilder().with_stream(_STREAM_NAME, sync_mode).build() -def _source() -> SourceChargebee: - return SourceChargebee() + +def _source(catalog: ConfiguredAirbyteCatalog, config: Dict[str, Any], state: Optional[Dict[str, Any]]) -> SourceChargebee: + return SourceChargebee(catalog=catalog, config=config, state=state) + def _a_record() -> RecordBuilder: return create_record_builder( find_template(_STREAM_NAME, __file__), FieldPath("list"), record_id_path=NestedPath([_STREAM_NAME, _PRIMARY_KEY]), - record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]) + record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]), ) + def _a_response() -> HttpResponseBuilder: return create_response_builder( - find_template(_STREAM_NAME, __file__), - FieldPath("list"), - pagination_strategy=ChargebeePaginationStrategy() + find_template(_STREAM_NAME, __file__), FieldPath("list"), pagination_strategy=ChargebeePaginationStrategy() ) + def _read( - config_builder: ConfigBuilder, - sync_mode: SyncMode, - state: Optional[Dict[str, Any]] = None, - expecting_exception: bool = False + config_builder: ConfigBuilder, sync_mode: SyncMode, state: Optional[Dict[str, Any]] = None, expecting_exception: bool = False ) -> EntrypointOutput: catalog = _catalog(sync_mode) config = config_builder.build() - return read(_source(), config, catalog, state, expecting_exception) + source = _source(catalog=catalog, config=config, state=state) + return read(source, config, catalog, state, expecting_exception) + @freezegun.freeze_time(_NOW.isoformat()) class FullRefreshTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -89,8 +94,7 @@ def _read(config: ConfigBuilder, expecting_exception: bool = False) -> Entrypoin def test_given_valid_response_records_are_extracted_and_returned(self, http_mocker: HttpMocker) -> None: # Tests simple read and record extraction http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record()).with_record(_a_record()).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record()).with_record(_a_record()).build() ) output = self._read(_config().with_start_date(self._start_date)) assert len(output.records) == 2 @@ -99,12 +103,21 @@ def test_given_valid_response_records_are_extracted_and_returned(self, http_mock def test_given_multiple_pages_of_records_read_and_returned(self, http_mocker: HttpMocker) -> None: # Tests pagination http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]).build(), - _a_response().with_record(_a_record()).with_pagination().build() + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]) + .build(), + _a_response().with_record(_a_record()).with_pagination().build(), ) http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]).with_offset("[1707076198000,57873868]").build(), - _a_response().with_record(_a_record()).build() + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]) + .with_offset("[1707076198000,57873868]") + .build(), + _a_response().with_record(_a_record()).build(), ) self._read(_config().with_start_date(self._start_date)) @@ -113,14 +126,10 @@ def test_given_multiple_pages_of_records_read_and_returned(self, http_mocker: Ht @HttpMocker() def test_given_http_status_400_when_read_then_stream_is_ignored(self, http_mocker: HttpMocker) -> None: # Tests 400 status error handling - http_mocker.get( - _a_request().with_any_query_params().build(), - a_response_with_status(400) - ) + http_mocker.get(_a_request().with_any_query_params().build(), a_response_with_status(400)) output = self._read(_config().with_start_date(self._start_date), expecting_exception=True) assert len(output.get_stream_statuses(f"{_STREAM_NAME}s")) == 0 - @HttpMocker() def test_given_http_status_401_when_the_stream_is_incomplete(self, http_mocker: HttpMocker) -> None: # Test 401 status error handling @@ -164,9 +173,9 @@ def test_given_http_status_500_after_max_retries_raises_config_error(self, http_ output = self._read(_config(), expecting_exception=True) assert output.errors[-1].trace.error.failure_type == FailureType.config_error + @freezegun.freeze_time(_NOW.isoformat()) class IncrementalTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -182,25 +191,28 @@ def test_given_no_initial_state_when_read_then_return_state_based_on_most_recent # Tests setting state when no initial state is provided cursor_value = self._start_date_in_seconds + 1 http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record().with_cursor(cursor_value)).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record().with_cursor(cursor_value)).build() ) output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8)), _NO_STATE) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=cursor_value) + assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=str(cursor_value)) @HttpMocker() def test_given_initial_state_use_state_for_query_params(self, http_mocker: HttpMocker) -> None: # Tests updating query param with state state_cursor_value = int((self._now - timedelta(days=5)).timestamp()) record_cursor_value = self._now_in_seconds - 1 - state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() + state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([state_cursor_value, self._now_in_seconds]).build(), + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([state_cursor_value, self._now_in_seconds]) + .build(), _a_response().with_record(_a_record().with_cursor(record_cursor_value)).build(), ) output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8)), state) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=record_cursor_value) \ No newline at end of file + assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=str(record_cursor_value)) diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_coupon.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_coupon.py index 32f3a7c5cb80..854e4a45a7c9 100644 --- a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_coupon.py +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_coupon.py @@ -5,6 +5,8 @@ from unittest import TestCase import freezegun +from source_chargebee import SourceChargebee + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read @@ -19,13 +21,13 @@ find_template, ) from airbyte_cdk.test.state_builder import StateBuilder -from source_chargebee import SourceChargebee from .config import ConfigBuilder from .pagination import ChargebeePaginationStrategy from .request_builder import ChargebeeRequestBuilder from .response_builder import a_response_with_status, a_response_with_status_and_header + _STREAM_NAME = "coupon" _SITE = "test-site" _SITE_API_KEY = "test-api-key" @@ -35,46 +37,49 @@ _NO_STATE = {} _NOW = datetime.now(timezone.utc) + def _a_request() -> ChargebeeRequestBuilder: return ChargebeeRequestBuilder.coupon_endpoint(_SITE, _SITE_API_KEY) + def _config() -> ConfigBuilder: return ConfigBuilder().with_site(_SITE).with_site_api_key(_SITE_API_KEY).with_product_catalog(_PRODUCT_CATALOG) + def _catalog(sync_mode: SyncMode) -> ConfiguredAirbyteCatalog: return CatalogBuilder().with_stream(_STREAM_NAME, sync_mode).build() -def _source() -> SourceChargebee: - return SourceChargebee() + +def _source(catalog: ConfiguredAirbyteCatalog, config: Dict[str, Any], state: Optional[Dict[str, Any]]) -> SourceChargebee: + return SourceChargebee(catalog=catalog, config=config, state=state) + def _a_record() -> RecordBuilder: return create_record_builder( find_template(_STREAM_NAME, __file__), FieldPath("list"), record_id_path=NestedPath([_STREAM_NAME, _PRIMARY_KEY]), - record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]) + record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]), ) + def _a_response() -> HttpResponseBuilder: return create_response_builder( - find_template(_STREAM_NAME, __file__), - FieldPath("list"), - pagination_strategy=ChargebeePaginationStrategy() + find_template(_STREAM_NAME, __file__), FieldPath("list"), pagination_strategy=ChargebeePaginationStrategy() ) + def _read( - config_builder: ConfigBuilder, - sync_mode: SyncMode, - state: Optional[Dict[str, Any]] = None, - expecting_exception: bool = False + config_builder: ConfigBuilder, sync_mode: SyncMode, state: Optional[Dict[str, Any]] = None, expecting_exception: bool = False ) -> EntrypointOutput: catalog = _catalog(sync_mode) config = config_builder.build() - return read(_source(), config, catalog, state, expecting_exception) + source = _source(catalog=catalog, config=config, state=state) + return read(source, config, catalog, state, expecting_exception) + @freezegun.freeze_time(_NOW.isoformat()) class FullRefreshTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -89,8 +94,7 @@ def _read(config: ConfigBuilder, expecting_exception: bool = False) -> Entrypoin def test_given_valid_response_records_are_extracted_and_returned(self, http_mocker: HttpMocker) -> None: # Tests simple read and record extraction http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record()).with_record(_a_record()).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record()).with_record(_a_record()).build() ) output = self._read(_config().with_start_date(self._start_date)) assert len(output.records) == 2 @@ -100,11 +104,14 @@ def test_given_multiple_pages_of_records_read_and_returned(self, http_mocker: Ht # Tests pagination http_mocker.get( _a_request().with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]).build(), - _a_response().with_record(_a_record()).with_pagination().build() + _a_response().with_record(_a_record()).with_pagination().build(), ) http_mocker.get( - _a_request().with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]).with_offset("[1707076198000,57873868]").build(), - _a_response().with_record(_a_record()).build() + _a_request() + .with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]) + .with_offset("[1707076198000,57873868]") + .build(), + _a_response().with_record(_a_record()).build(), ) self._read(_config().with_start_date(self._start_date)) @@ -115,7 +122,7 @@ def test_given_records_returned_with_custom_field_transformation(self, http_mock # Tests custom field transformation http_mocker.get( _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record().with_field(NestedPath([_STREAM_NAME, "cf_my_custom_field"]), "my_custom_value")).build() + _a_response().with_record(_a_record().with_field(NestedPath([_STREAM_NAME, "cf_my_custom_field"]), "my_custom_value")).build(), ) output = self._read(_config().with_start_date(self._start_date)) assert output.records[0].record.data["custom_fields"][0]["name"] == "cf_my_custom_field" @@ -124,10 +131,7 @@ def test_given_records_returned_with_custom_field_transformation(self, http_mock @HttpMocker() def test_given_http_status_400_when_read_then_stream_is_ignored(self, http_mocker: HttpMocker) -> None: # Tests 400 status error handling - http_mocker.get( - _a_request().with_any_query_params().build(), - a_response_with_status(400) - ) + http_mocker.get(_a_request().with_any_query_params().build(), a_response_with_status(400)) output = self._read(_config().with_start_date(self._start_date), expecting_exception=True) assert len(output.get_stream_statuses(f"{_STREAM_NAME}s")) == 0 @@ -177,7 +181,6 @@ def test_given_http_status_500_after_max_retries_raises_config_error(self, http_ @freezegun.freeze_time(_NOW.isoformat()) class IncrementalTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -193,20 +196,19 @@ def test_given_no_initial_state_when_read_then_return_state_based_on_most_recent # Tests setting state when no initial state is provided cursor_value = self._start_date_in_seconds + 1 http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record().with_cursor(cursor_value)).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record().with_cursor(cursor_value)).build() ) output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8)), _NO_STATE) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=cursor_value) + assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=str(cursor_value)) @HttpMocker() def test_given_initial_state_use_state_for_query_params(self, http_mocker: HttpMocker) -> None: # Tests updating query param with state state_cursor_value = int((self._now - timedelta(days=5)).timestamp()) record_cursor_value = self._now_in_seconds - 1 - state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() + state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() http_mocker.get( _a_request().with_updated_at_btw([state_cursor_value, self._now_in_seconds]).build(), _a_response().with_record(_a_record().with_cursor(record_cursor_value)).build(), @@ -214,4 +216,4 @@ def test_given_initial_state_use_state_for_query_params(self, http_mocker: HttpM output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8)), state) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=record_cursor_value) + assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=str(record_cursor_value)) diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_customer.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_customer.py index 4c7d0441ca37..ffd36b12a924 100644 --- a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_customer.py +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_customer.py @@ -5,6 +5,8 @@ from unittest import TestCase import freezegun +from source_chargebee import SourceChargebee + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read @@ -19,13 +21,13 @@ find_template, ) from airbyte_cdk.test.state_builder import StateBuilder -from source_chargebee import SourceChargebee from .config import ConfigBuilder from .pagination import ChargebeePaginationStrategy from .request_builder import ChargebeeRequestBuilder from .response_builder import a_response_with_status, a_response_with_status_and_header + _STREAM_NAME = "customer" _SITE = "test-site" _SITE_API_KEY = "test-api-key" @@ -35,46 +37,49 @@ _NO_STATE = {} _NOW = datetime.now(timezone.utc) + def _a_request() -> ChargebeeRequestBuilder: return ChargebeeRequestBuilder.customer_endpoint(_SITE, _SITE_API_KEY) + def _config() -> ConfigBuilder: return ConfigBuilder().with_site(_SITE).with_site_api_key(_SITE_API_KEY).with_product_catalog(_PRODUCT_CATALOG) + def _catalog(sync_mode: SyncMode) -> ConfiguredAirbyteCatalog: return CatalogBuilder().with_stream(_STREAM_NAME, sync_mode).build() -def _source() -> SourceChargebee: - return SourceChargebee() + +def _source(catalog: ConfiguredAirbyteCatalog, config: Dict[str, Any], state: Optional[Dict[str, Any]]) -> SourceChargebee: + return SourceChargebee(catalog=catalog, config=config, state=state) + def _a_record() -> RecordBuilder: return create_record_builder( find_template(_STREAM_NAME, __file__), FieldPath("list"), record_id_path=NestedPath([_STREAM_NAME, _PRIMARY_KEY]), - record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]) + record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]), ) + def _a_response() -> HttpResponseBuilder: return create_response_builder( - find_template(_STREAM_NAME, __file__), - FieldPath("list"), - pagination_strategy=ChargebeePaginationStrategy() + find_template(_STREAM_NAME, __file__), FieldPath("list"), pagination_strategy=ChargebeePaginationStrategy() ) + def _read( - config_builder: ConfigBuilder, - sync_mode: SyncMode, - state: Optional[Dict[str, Any]] = None, - expecting_exception: bool = False + config_builder: ConfigBuilder, sync_mode: SyncMode, state: Optional[Dict[str, Any]] = None, expecting_exception: bool = False ) -> EntrypointOutput: catalog = _catalog(sync_mode) config = config_builder.build() - return read(_source(), config, catalog, state, expecting_exception) + source = _source(catalog=catalog, config=config, state=state) + return read(source, config, catalog, state, expecting_exception) + @freezegun.freeze_time(_NOW.isoformat()) class FullRefreshTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -89,8 +94,7 @@ def _read(config: ConfigBuilder, expecting_exception: bool = False) -> Entrypoin def test_given_valid_response_records_are_extracted_and_returned(self, http_mocker: HttpMocker) -> None: # Tests simple read and record extraction http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record()).with_record(_a_record()).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record()).with_record(_a_record()).build() ) output = self._read(_config().with_start_date(self._start_date)) assert len(output.records) == 2 @@ -99,12 +103,21 @@ def test_given_valid_response_records_are_extracted_and_returned(self, http_mock def test_given_multiple_pages_of_records_read_and_returned(self, http_mocker: HttpMocker) -> None: # Tests pagination http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]).build(), - _a_response().with_record(_a_record()).with_pagination().build() + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]) + .build(), + _a_response().with_record(_a_record()).with_pagination().build(), ) http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]).with_offset("[1707076198000,57873868]").build(), - _a_response().with_record(_a_record()).build() + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]) + .with_offset("[1707076198000,57873868]") + .build(), + _a_response().with_record(_a_record()).build(), ) self._read(_config().with_start_date(self._start_date)) @@ -115,7 +128,7 @@ def test_given_records_returned_with_custom_field_transformation(self, http_mock # Tests custom field transformation http_mocker.get( _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record().with_field(NestedPath([_STREAM_NAME, "cf_my_custom_field"]), "my_custom_value")).build() + _a_response().with_record(_a_record().with_field(NestedPath([_STREAM_NAME, "cf_my_custom_field"]), "my_custom_value")).build(), ) output = self._read(_config().with_start_date(self._start_date)) assert output.records[0].record.data["custom_fields"][0]["name"] == "cf_my_custom_field" @@ -124,10 +137,7 @@ def test_given_records_returned_with_custom_field_transformation(self, http_mock @HttpMocker() def test_given_http_status_400_when_read_then_stream_is_ignored(self, http_mocker: HttpMocker) -> None: # Tests 400 status error handling - http_mocker.get( - _a_request().with_any_query_params().build(), - a_response_with_status(400) - ) + http_mocker.get(_a_request().with_any_query_params().build(), a_response_with_status(400)) output = self._read(_config().with_start_date(self._start_date), expecting_exception=True) assert len(output.get_stream_statuses(f"{_STREAM_NAME}s")) == 0 @@ -174,9 +184,9 @@ def test_given_http_status_500_after_max_retries_raises_config_error(self, http_ output = self._read(_config(), expecting_exception=True) assert output.errors[-1].trace.error.failure_type == FailureType.config_error + @freezegun.freeze_time(_NOW.isoformat()) class IncrementalTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -192,25 +202,28 @@ def test_given_no_initial_state_when_read_then_return_state_based_on_most_recent # Tests setting state when no initial state is provided cursor_value = self._start_date_in_seconds + 1 http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record().with_cursor(cursor_value)).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record().with_cursor(cursor_value)).build() ) output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8)), _NO_STATE) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=cursor_value) + assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=str(cursor_value)) @HttpMocker() def test_given_initial_state_use_state_for_query_params(self, http_mocker: HttpMocker) -> None: # Tests updating query param with state state_cursor_value = int((self._now - timedelta(days=5)).timestamp()) record_cursor_value = self._now_in_seconds - 1 - state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() + state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([state_cursor_value, self._now_in_seconds]).build(), + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([state_cursor_value, self._now_in_seconds]) + .build(), _a_response().with_record(_a_record().with_cursor(record_cursor_value)).build(), ) output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8)), state) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=record_cursor_value) + assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=str(record_cursor_value)) diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_event.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_event.py index c472c62f56e5..3aace07fdf28 100644 --- a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_event.py +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_event.py @@ -5,6 +5,8 @@ from unittest import TestCase import freezegun +from source_chargebee import SourceChargebee + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read @@ -19,13 +21,13 @@ find_template, ) from airbyte_cdk.test.state_builder import StateBuilder -from source_chargebee import SourceChargebee from .config import ConfigBuilder from .pagination import ChargebeePaginationStrategy from .request_builder import ChargebeeRequestBuilder from .response_builder import a_response_with_status, a_response_with_status_and_header + _STREAM_NAME = "event" _SITE = "test-site" _SITE_API_KEY = "test-api-key" @@ -35,46 +37,49 @@ _NO_STATE = {} _NOW = datetime.now(timezone.utc) + def _a_request() -> ChargebeeRequestBuilder: return ChargebeeRequestBuilder.event_endpoint(_SITE, _SITE_API_KEY) + def _config() -> ConfigBuilder: return ConfigBuilder().with_site(_SITE).with_site_api_key(_SITE_API_KEY).with_product_catalog(_PRODUCT_CATALOG) + def _catalog(sync_mode: SyncMode) -> ConfiguredAirbyteCatalog: return CatalogBuilder().with_stream(_STREAM_NAME, sync_mode).build() -def _source() -> SourceChargebee: - return SourceChargebee() + +def _source(catalog: ConfiguredAirbyteCatalog, config: Dict[str, Any], state: Optional[Dict[str, Any]]) -> SourceChargebee: + return SourceChargebee(catalog=catalog, config=config, state=state) + def _a_record() -> RecordBuilder: return create_record_builder( find_template(_STREAM_NAME, __file__), FieldPath("list"), record_id_path=NestedPath([_STREAM_NAME, _PRIMARY_KEY]), - record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]) + record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]), ) + def _a_response() -> HttpResponseBuilder: return create_response_builder( - find_template(_STREAM_NAME, __file__), - FieldPath("list"), - pagination_strategy=ChargebeePaginationStrategy() + find_template(_STREAM_NAME, __file__), FieldPath("list"), pagination_strategy=ChargebeePaginationStrategy() ) + def _read( - config_builder: ConfigBuilder, - sync_mode: SyncMode, - state: Optional[Dict[str, Any]] = None, - expecting_exception: bool = False + config_builder: ConfigBuilder, sync_mode: SyncMode, state: Optional[Dict[str, Any]] = None, expecting_exception: bool = False ) -> EntrypointOutput: catalog = _catalog(sync_mode) config = config_builder.build() - return read(_source(), config, catalog, state, expecting_exception) + source = _source(catalog=catalog, config=config, state=state) + return read(source, config, catalog, state, expecting_exception) + @freezegun.freeze_time(_NOW.isoformat()) class FullRefreshTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -89,8 +94,7 @@ def _read(config: ConfigBuilder, expecting_exception: bool = False) -> Entrypoin def test_given_valid_response_records_are_extracted_and_returned(self, http_mocker: HttpMocker) -> None: # Tests simple read and record extraction http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record()).with_record(_a_record()).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record()).with_record(_a_record()).build() ) output = self._read(_config().with_start_date(self._start_date)) assert len(output.records) == 2 @@ -100,11 +104,15 @@ def test_given_multiple_pages_of_records_read_and_returned(self, http_mocker: Ht # Tests pagination http_mocker.get( _a_request().with_sort_by_asc(_CURSOR_FIELD).with_occurred_at_btw([self._start_date_in_seconds, self._now_in_seconds]).build(), - _a_response().with_record(_a_record()).with_pagination().build() + _a_response().with_record(_a_record()).with_pagination().build(), ) http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_occurred_at_btw([self._start_date_in_seconds, self._now_in_seconds]).with_offset("[1707076198000,57873868]").build(), - _a_response().with_record(_a_record()).build() + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_occurred_at_btw([self._start_date_in_seconds, self._now_in_seconds]) + .with_offset("[1707076198000,57873868]") + .build(), + _a_response().with_record(_a_record()).build(), ) self._read(_config().with_start_date(self._start_date)) @@ -162,7 +170,6 @@ def test_given_http_status_500_after_max_retries_raises_config_error(self, http_ @freezegun.freeze_time(_NOW.isoformat()) class IncrementalTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -178,20 +185,19 @@ def test_given_no_initial_state_when_read_then_return_state_based_on_most_recent # Tests setting state when no initial state is provided cursor_value = self._start_date_in_seconds + 1 http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record().with_cursor(cursor_value)).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record().with_cursor(cursor_value)).build() ) output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8)), _NO_STATE) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(occurred_at=cursor_value) + assert most_recent_state.stream_state == AirbyteStateBlob(occurred_at=str(cursor_value)) @HttpMocker() def test_given_initial_state_use_state_for_query_params(self, http_mocker: HttpMocker) -> None: # Tests updating query param with state state_cursor_value = int((self._now - timedelta(days=5)).timestamp()) record_cursor_value = self._now_in_seconds - 1 - state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() + state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() http_mocker.get( _a_request().with_sort_by_asc(_CURSOR_FIELD).with_occurred_at_btw([state_cursor_value, self._now_in_seconds]).build(), _a_response().with_record(_a_record().with_cursor(record_cursor_value)).build(), @@ -199,4 +205,4 @@ def test_given_initial_state_use_state_for_query_params(self, http_mocker: HttpM output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8)), state) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(occurred_at=record_cursor_value) + assert most_recent_state.stream_state == AirbyteStateBlob(occurred_at=str(record_cursor_value)) diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_hosted_page.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_hosted_page.py index 10a00ae6cf29..48756d17096f 100644 --- a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_hosted_page.py +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_hosted_page.py @@ -5,6 +5,8 @@ from unittest import TestCase import freezegun +from source_chargebee import SourceChargebee + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read @@ -19,13 +21,13 @@ find_template, ) from airbyte_cdk.test.state_builder import StateBuilder -from source_chargebee import SourceChargebee from .config import ConfigBuilder from .pagination import ChargebeePaginationStrategy from .request_builder import ChargebeeRequestBuilder from .response_builder import a_response_with_status, a_response_with_status_and_header + _STREAM_NAME = "hosted_page" _SITE = "test-site" _SITE_API_KEY = "test-api-key" @@ -35,46 +37,49 @@ _NO_STATE = {} _NOW = datetime.now(timezone.utc) + def _a_request() -> ChargebeeRequestBuilder: return ChargebeeRequestBuilder.hosted_page_endpoint(_SITE, _SITE_API_KEY) + def _config() -> ConfigBuilder: return ConfigBuilder().with_site(_SITE).with_site_api_key(_SITE_API_KEY).with_product_catalog(_PRODUCT_CATALOG) + def _catalog(sync_mode: SyncMode) -> ConfiguredAirbyteCatalog: return CatalogBuilder().with_stream(_STREAM_NAME, sync_mode).build() -def _source() -> SourceChargebee: - return SourceChargebee() + +def _source(catalog: ConfiguredAirbyteCatalog, config: Dict[str, Any], state: Optional[Dict[str, Any]]) -> SourceChargebee: + return SourceChargebee(catalog=catalog, config=config, state=state) + def _a_record() -> RecordBuilder: return create_record_builder( find_template(_STREAM_NAME, __file__), FieldPath("list"), record_id_path=NestedPath([_STREAM_NAME, _PRIMARY_KEY]), - record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]) + record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]), ) + def _a_response() -> HttpResponseBuilder: return create_response_builder( - find_template(_STREAM_NAME, __file__), - FieldPath("list"), - pagination_strategy=ChargebeePaginationStrategy() + find_template(_STREAM_NAME, __file__), FieldPath("list"), pagination_strategy=ChargebeePaginationStrategy() ) + def _read( - config_builder: ConfigBuilder, - sync_mode: SyncMode, - state: Optional[Dict[str, Any]] = None, - expecting_exception: bool = False + config_builder: ConfigBuilder, sync_mode: SyncMode, state: Optional[Dict[str, Any]] = None, expecting_exception: bool = False ) -> EntrypointOutput: catalog = _catalog(sync_mode) config = config_builder.build() - return read(_source(), config, catalog, state, expecting_exception) + source = _source(catalog=catalog, config=config, state=state) + return read(source, config, catalog, state, expecting_exception) + @freezegun.freeze_time(_NOW.isoformat()) class FullRefreshTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -89,8 +94,7 @@ def _read(config: ConfigBuilder, expecting_exception: bool = False) -> Entrypoin def test_given_valid_response_records_are_extracted_and_returned(self, http_mocker: HttpMocker) -> None: # Tests simple read and record extraction http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record()).with_record(_a_record()).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record()).with_record(_a_record()).build() ) output = self._read(_config().with_start_date(self._start_date)) assert len(output.records) == 2 @@ -99,12 +103,21 @@ def test_given_valid_response_records_are_extracted_and_returned(self, http_mock def test_given_multiple_pages_of_records_read_and_returned(self, http_mocker: HttpMocker) -> None: # Tests pagination http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]).build(), - _a_response().with_record(_a_record()).with_pagination().build() + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]) + .build(), + _a_response().with_record(_a_record()).with_pagination().build(), ) http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]).with_offset("[1707076198000,57873868]").build(), - _a_response().with_record(_a_record()).build() + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]) + .with_offset("[1707076198000,57873868]") + .build(), + _a_response().with_record(_a_record()).build(), ) self._read(_config().with_start_date(self._start_date)) @@ -159,9 +172,9 @@ def test_given_http_status_500_after_max_retries_raises_config_error(self, http_ output = self._read(_config(), expecting_exception=True) assert output.errors[-1].trace.error.failure_type == FailureType.config_error + @freezegun.freeze_time(_NOW.isoformat()) class IncrementalTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -177,25 +190,28 @@ def test_given_no_initial_state_when_read_then_return_state_based_on_most_recent # Tests setting state when no initial state is provided cursor_value = self._start_date_in_seconds + 1 http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record().with_cursor(cursor_value)).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record().with_cursor(cursor_value)).build() ) output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8)), _NO_STATE) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=cursor_value) + assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=str(cursor_value)) @HttpMocker() def test_given_initial_state_use_state_for_query_params(self, http_mocker: HttpMocker) -> None: # Tests updating query param with state state_cursor_value = int((self._now - timedelta(days=5)).timestamp()) record_cursor_value = self._now_in_seconds - 1 - state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() + state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([state_cursor_value, self._now_in_seconds]).build(), + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([state_cursor_value, self._now_in_seconds]) + .build(), _a_response().with_record(_a_record().with_cursor(record_cursor_value)).build(), ) output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8)), state) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=record_cursor_value) + assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=str(record_cursor_value)) diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_plan.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_plan.py index c7d651edf35b..a441f7711d1b 100644 --- a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_plan.py +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_plan.py @@ -5,6 +5,8 @@ from unittest import TestCase import freezegun +from source_chargebee import SourceChargebee + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read @@ -19,13 +21,13 @@ find_template, ) from airbyte_cdk.test.state_builder import StateBuilder -from source_chargebee import SourceChargebee from .config import ConfigBuilder from .pagination import ChargebeePaginationStrategy from .request_builder import ChargebeeRequestBuilder from .response_builder import a_response_with_status, a_response_with_status_and_header + _STREAM_NAME = "plan" _SITE = "test-site" _SITE_API_KEY = "test-api-key" @@ -35,46 +37,49 @@ _NO_STATE = {} _NOW = datetime.now(timezone.utc) + def _a_request() -> ChargebeeRequestBuilder: return ChargebeeRequestBuilder.plan_endpoint(_SITE, _SITE_API_KEY) + def _config() -> ConfigBuilder: return ConfigBuilder().with_site(_SITE).with_site_api_key(_SITE_API_KEY).with_product_catalog(_PRODUCT_CATALOG) + def _catalog(sync_mode: SyncMode) -> ConfiguredAirbyteCatalog: return CatalogBuilder().with_stream(_STREAM_NAME, sync_mode).build() -def _source() -> SourceChargebee: - return SourceChargebee() + +def _source(catalog: ConfiguredAirbyteCatalog, config: Dict[str, Any], state: Optional[Dict[str, Any]]) -> SourceChargebee: + return SourceChargebee(catalog=catalog, config=config, state=state) + def _a_record() -> RecordBuilder: return create_record_builder( find_template(_STREAM_NAME, __file__), FieldPath("list"), record_id_path=NestedPath([_STREAM_NAME, _PRIMARY_KEY]), - record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]) + record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]), ) + def _a_response() -> HttpResponseBuilder: return create_response_builder( - find_template(_STREAM_NAME, __file__), - FieldPath("list"), - pagination_strategy=ChargebeePaginationStrategy() + find_template(_STREAM_NAME, __file__), FieldPath("list"), pagination_strategy=ChargebeePaginationStrategy() ) + def _read( - config_builder: ConfigBuilder, - sync_mode: SyncMode, - state: Optional[Dict[str, Any]] = None, - expecting_exception: bool = False + config_builder: ConfigBuilder, sync_mode: SyncMode, state: Optional[Dict[str, Any]] = None, expecting_exception: bool = False ) -> EntrypointOutput: catalog = _catalog(sync_mode) config = config_builder.build() - return read(_source(), config, catalog, state, expecting_exception) + source = _source(catalog=catalog, config=config, state=state) + return read(source, config, catalog, state, expecting_exception) + @freezegun.freeze_time(_NOW.isoformat()) class FullRefreshTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -89,8 +94,7 @@ def _read(config: ConfigBuilder, expecting_exception: bool = False) -> Entrypoin def test_given_valid_response_records_are_extracted_and_returned(self, http_mocker: HttpMocker) -> None: # Tests simple read and record extraction http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record()).with_record(_a_record()).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record()).with_record(_a_record()).build() ) output = self._read(_config().with_start_date(self._start_date)) assert len(output.records) == 2 @@ -99,12 +103,21 @@ def test_given_valid_response_records_are_extracted_and_returned(self, http_mock def test_given_multiple_pages_of_records_read_and_returned(self, http_mocker: HttpMocker) -> None: # Tests pagination http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]).build(), - _a_response().with_record(_a_record()).with_pagination().build() + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]) + .build(), + _a_response().with_record(_a_record()).with_pagination().build(), ) http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]).with_offset("[1707076198000,57873868]").build(), - _a_response().with_record(_a_record()).build() + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]) + .with_offset("[1707076198000,57873868]") + .build(), + _a_response().with_record(_a_record()).build(), ) self._read(_config().with_start_date(self._start_date)) @@ -113,10 +126,7 @@ def test_given_multiple_pages_of_records_read_and_returned(self, http_mocker: Ht @HttpMocker() def test_given_http_status_400_when_read_then_stream_is_ignored(self, http_mocker: HttpMocker) -> None: # Tests 400 status error handling - http_mocker.get( - _a_request().with_any_query_params().build(), - a_response_with_status(400) - ) + http_mocker.get(_a_request().with_any_query_params().build(), a_response_with_status(400)) output = self._read(_config().with_start_date(self._start_date), expecting_exception=True) assert len(output.get_stream_statuses(f"{_STREAM_NAME}s")) == 0 @@ -166,7 +176,6 @@ def test_given_http_status_500_after_max_retries_raises_config_error(self, http_ @freezegun.freeze_time(_NOW.isoformat()) class IncrementalTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -182,25 +191,28 @@ def test_given_no_initial_state_when_read_then_return_state_based_on_most_recent # Tests setting state when no initial state is provided cursor_value = self._start_date_in_seconds + 1 http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record().with_cursor(cursor_value)).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record().with_cursor(cursor_value)).build() ) output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8)), _NO_STATE) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=cursor_value) + assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=str(cursor_value)) @HttpMocker() def test_given_initial_state_use_state_for_query_params(self, http_mocker: HttpMocker) -> None: # Tests updating query param with state state_cursor_value = int((self._now - timedelta(days=5)).timestamp()) record_cursor_value = self._now_in_seconds - 1 - state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() + state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([state_cursor_value, self._now_in_seconds]).build(), + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([state_cursor_value, self._now_in_seconds]) + .build(), _a_response().with_record(_a_record().with_cursor(record_cursor_value)).build(), ) output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8)), state) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=record_cursor_value) + assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=str(record_cursor_value)) diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_site_migration_detail.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_site_migration_detail.py index 40972289716a..d92ec52fedda 100644 --- a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_site_migration_detail.py +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_site_migration_detail.py @@ -5,6 +5,8 @@ from unittest import TestCase import freezegun +from source_chargebee import SourceChargebee + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read @@ -19,13 +21,13 @@ find_template, ) from airbyte_cdk.test.state_builder import StateBuilder -from source_chargebee import SourceChargebee from .config import ConfigBuilder from .pagination import ChargebeePaginationStrategy from .request_builder import ChargebeeRequestBuilder from .response_builder import a_response_with_status, a_response_with_status_and_header + _STREAM_NAME = "site_migration_detail" _SITE = "test-site" _SITE_API_KEY = "test-api-key" @@ -35,51 +37,53 @@ _NO_STATE = {} _NOW = datetime.now(timezone.utc) -''' +""" Note that this is a semi-incremental stream and tests will need to be adapated accordingly -''' +""" def _a_request() -> ChargebeeRequestBuilder: return ChargebeeRequestBuilder.site_migration_detail_endpoint(_SITE, _SITE_API_KEY) + def _config() -> ConfigBuilder: return ConfigBuilder().with_site(_SITE).with_site_api_key(_SITE_API_KEY).with_product_catalog(_PRODUCT_CATALOG) + def _catalog(sync_mode: SyncMode) -> ConfiguredAirbyteCatalog: return CatalogBuilder().with_stream(_STREAM_NAME, sync_mode).build() -def _source() -> SourceChargebee: - return SourceChargebee() + +def _source(catalog: ConfiguredAirbyteCatalog, config: Dict[str, Any], state: Optional[Dict[str, Any]]) -> SourceChargebee: + return SourceChargebee(catalog=catalog, config=config, state=state) + def _a_record() -> RecordBuilder: return create_record_builder( find_template(_STREAM_NAME, __file__), FieldPath("list"), record_id_path=NestedPath([_STREAM_NAME, _PRIMARY_KEY]), - record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]) + record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]), ) + def _a_response() -> HttpResponseBuilder: return create_response_builder( - find_template(_STREAM_NAME, __file__), - FieldPath("list"), - pagination_strategy=ChargebeePaginationStrategy() + find_template(_STREAM_NAME, __file__), FieldPath("list"), pagination_strategy=ChargebeePaginationStrategy() ) + def _read( - config_builder: ConfigBuilder, - sync_mode: SyncMode, - state: Optional[Dict[str, Any]] = None, - expecting_exception: bool = False + config_builder: ConfigBuilder, sync_mode: SyncMode, state: Optional[Dict[str, Any]] = None, expecting_exception: bool = False ) -> EntrypointOutput: catalog = _catalog(sync_mode) config = config_builder.build() - return read(_source(), config, catalog, state, expecting_exception) + source = _source(catalog=catalog, config=config, state=state) + return read(source, config, catalog, state, expecting_exception) + @freezegun.freeze_time(_NOW.isoformat()) class FullRefreshTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -94,8 +98,7 @@ def _read(config: ConfigBuilder, expecting_exception: bool = False) -> Entrypoin def test_given_valid_response_records_are_extracted_and_returned(self, http_mocker: HttpMocker) -> None: # Tests simple read and record extraction http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record()).with_record(_a_record()).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record()).with_record(_a_record()).build() ) output = self._read(_config().with_start_date(self._start_date)) assert len(output.records) == 2 @@ -103,26 +106,16 @@ def test_given_valid_response_records_are_extracted_and_returned(self, http_mock @HttpMocker() def test_given_multiple_pages_of_records_read_and_returned(self, http_mocker: HttpMocker) -> None: # Tests pagination - http_mocker.get( - _a_request().build(), - _a_response().with_record(_a_record()).with_pagination().build() - ) - http_mocker.get( - _a_request().with_offset("[1707076198000,57873868]").build(), - _a_response().with_record(_a_record()).build() - ) + http_mocker.get(_a_request().build(), _a_response().with_record(_a_record()).with_pagination().build()) + http_mocker.get(_a_request().with_offset("[1707076198000,57873868]").build(), _a_response().with_record(_a_record()).build()) self._read(_config().with_start_date(self._start_date)) # HTTPMocker ensures call are performed - @HttpMocker() def test_given_http_status_400_when_read_then_stream_is_ignored(self, http_mocker: HttpMocker) -> None: # Tests 400 status error handling - http_mocker.get( - _a_request().with_any_query_params().build(), - a_response_with_status(400) - ) + http_mocker.get(_a_request().with_any_query_params().build(), a_response_with_status(400)) output = self._read(_config().with_start_date(self._start_date), expecting_exception=True) assert len(output.get_stream_statuses(f"{_STREAM_NAME}s")) == 0 @@ -172,7 +165,6 @@ def test_given_http_status_500_after_max_retries_raises_config_error(self, http_ @freezegun.freeze_time(_NOW.isoformat()) class IncrementalTest(TestCase): - # Site Migration Detail stream is a semi-incremental stream and therefore state acts differently than typical declarative incremental implementation -- state is updated to most recent cursor value read def setUp(self) -> None: @@ -190,8 +182,7 @@ def test_given_no_initial_state_when_read_then_return_state_based_on_cursor_fiel # Tests setting state when no initial state is provided cursor_value = self._start_date_in_seconds + 1 http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record().with_cursor(cursor_value)).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record().with_cursor(cursor_value)).build() ) output = self._read(_config().with_start_date(self._start_date), _NO_STATE) most_recent_state = output.most_recent_state @@ -202,7 +193,7 @@ def test_given_no_initial_state_when_read_then_return_state_based_on_cursor_fiel def test_given_initial_state_value_when_read_then_state_is_updated_to_most_recent_cursor_value(self, http_mocker: HttpMocker) -> None: state_cursor_value = self._start_date_in_seconds + 1 record_cursor_value = state_cursor_value + 1 - state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() + state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() http_mocker.get( _a_request().with_any_query_params().build(), @@ -212,13 +203,17 @@ def test_given_initial_state_value_when_read_then_state_is_updated_to_most_recen output = self._read(_config().with_start_date(self._start_date), state) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(migrated_at=record_cursor_value, prior_state={_CURSOR_FIELD: state_cursor_value}) + assert most_recent_state.stream_state == AirbyteStateBlob( + migrated_at=record_cursor_value, prior_state={_CURSOR_FIELD: state_cursor_value} + ) @HttpMocker() - def test_given_record_returned_with_cursor_value_before_state_record_is_not_read_and_state_not_updated(self, http_mocker: HttpMocker) -> None: + def test_given_record_returned_with_cursor_value_before_state_record_is_not_read_and_state_not_updated( + self, http_mocker: HttpMocker + ) -> None: state_cursor_value = self._start_date_in_seconds record_cursor_value = self._start_date_in_seconds - 1 - state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() + state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() http_mocker.get( _a_request().with_any_query_params().build(), @@ -228,5 +223,7 @@ def test_given_record_returned_with_cursor_value_before_state_record_is_not_read output = self._read(_config().with_start_date(self._start_date), state) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(migrated_at=state_cursor_value, prior_state={_CURSOR_FIELD: state_cursor_value}) + assert most_recent_state.stream_state == AirbyteStateBlob( + migrated_at=state_cursor_value, prior_state={_CURSOR_FIELD: state_cursor_value} + ) assert len(output.records) == 0 diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_subscription.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_subscription.py index 86b5f34d3203..fb2ff1776ff7 100644 --- a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_subscription.py +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_subscription.py @@ -5,6 +5,8 @@ from unittest import TestCase import freezegun +from source_chargebee import SourceChargebee + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read @@ -19,13 +21,13 @@ find_template, ) from airbyte_cdk.test.state_builder import StateBuilder -from source_chargebee import SourceChargebee from .config import ConfigBuilder from .pagination import ChargebeePaginationStrategy from .request_builder import ChargebeeRequestBuilder from .response_builder import a_response_with_status, a_response_with_status_and_header + _STREAM_NAME = "subscription" _SITE = "test-site" _SITE_API_KEY = "test-api-key" @@ -35,46 +37,49 @@ _NO_STATE = {} _NOW = datetime.now(timezone.utc) + def _a_request() -> ChargebeeRequestBuilder: return ChargebeeRequestBuilder.subscription_endpoint(_SITE, _SITE_API_KEY) + def _config() -> ConfigBuilder: return ConfigBuilder().with_site(_SITE).with_site_api_key(_SITE_API_KEY).with_product_catalog(_PRODUCT_CATALOG) + def _catalog(sync_mode: SyncMode) -> ConfiguredAirbyteCatalog: return CatalogBuilder().with_stream(_STREAM_NAME, sync_mode).build() -def _source() -> SourceChargebee: - return SourceChargebee() + +def _source(catalog: ConfiguredAirbyteCatalog, config: Dict[str, Any], state: Optional[Dict[str, Any]]) -> SourceChargebee: + return SourceChargebee(catalog=catalog, config=config, state=state) + def _a_record() -> RecordBuilder: return create_record_builder( find_template(_STREAM_NAME, __file__), FieldPath("list"), record_id_path=NestedPath([_STREAM_NAME, _PRIMARY_KEY]), - record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]) + record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]), ) + def _a_response() -> HttpResponseBuilder: return create_response_builder( - find_template(_STREAM_NAME, __file__), - FieldPath("list"), - pagination_strategy=ChargebeePaginationStrategy() + find_template(_STREAM_NAME, __file__), FieldPath("list"), pagination_strategy=ChargebeePaginationStrategy() ) + def _read( - config_builder: ConfigBuilder, - sync_mode: SyncMode, - state: Optional[Dict[str, Any]] = None, - expecting_exception: bool = False + config_builder: ConfigBuilder, sync_mode: SyncMode, state: Optional[Dict[str, Any]] = None, expecting_exception: bool = False ) -> EntrypointOutput: catalog = _catalog(sync_mode) config = config_builder.build() - return read(_source(), config, catalog, state, expecting_exception) + source = _source(catalog=catalog, config=config, state=state) + return read(source, config, catalog, state, expecting_exception) + @freezegun.freeze_time(_NOW.isoformat()) class FullRefreshTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -89,8 +94,7 @@ def _read(config: ConfigBuilder, expecting_exception: bool = False) -> Entrypoin def test_given_valid_response_records_are_extracted_and_returned(self, http_mocker: HttpMocker) -> None: # Tests simple read and record extraction http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record()).with_record(_a_record()).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record()).with_record(_a_record()).build() ) output = self._read(_config().with_start_date(self._start_date)) assert len(output.records) == 2 @@ -99,12 +103,21 @@ def test_given_valid_response_records_are_extracted_and_returned(self, http_mock def test_given_multiple_pages_of_records_read_and_returned(self, http_mocker: HttpMocker) -> None: # Tests pagination http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]).build(), - _a_response().with_record(_a_record()).with_pagination().build() + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]) + .build(), + _a_response().with_record(_a_record()).with_pagination().build(), ) http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]).with_offset("[1707076198000,57873868]").build(), - _a_response().with_record(_a_record()).build() + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]) + .with_offset("[1707076198000,57873868]") + .build(), + _a_response().with_record(_a_record()).build(), ) self._read(_config().with_start_date(self._start_date)) @@ -115,7 +128,7 @@ def test_given_records_returned_with_custom_field_transformation(self, http_mock # Tests custom field transformation http_mocker.get( _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record().with_field(NestedPath([_STREAM_NAME, "cf_my_custom_field"]), "my_custom_value")).build() + _a_response().with_record(_a_record().with_field(NestedPath([_STREAM_NAME, "cf_my_custom_field"]), "my_custom_value")).build(), ) output = self._read(_config().with_start_date(self._start_date)) assert output.records[0].record.data["custom_fields"][0]["name"] == "cf_my_custom_field" @@ -124,10 +137,7 @@ def test_given_records_returned_with_custom_field_transformation(self, http_mock @HttpMocker() def test_given_http_status_400_when_read_then_stream_is_ignored(self, http_mocker: HttpMocker) -> None: # Tests 400 status error handling - http_mocker.get( - _a_request().with_any_query_params().build(), - a_response_with_status(400) - ) + http_mocker.get(_a_request().with_any_query_params().build(), a_response_with_status(400)) output = self._read(_config().with_start_date(self._start_date), expecting_exception=True) assert len(output.get_stream_statuses(f"{_STREAM_NAME}s")) == 0 @@ -177,7 +187,6 @@ def test_given_http_status_500_after_max_retries_raises_config_error(self, http_ @freezegun.freeze_time(_NOW.isoformat()) class IncrementalTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -193,25 +202,28 @@ def test_given_no_initial_state_when_read_then_return_state_based_on_most_recent # Tests setting state when no initial state is provided cursor_value = self._start_date_in_seconds + 1 http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record().with_cursor(cursor_value)).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record().with_cursor(cursor_value)).build() ) output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8)), _NO_STATE) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=cursor_value) + assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=str(cursor_value)) @HttpMocker() def test_given_initial_state_use_state_for_query_params(self, http_mocker: HttpMocker) -> None: # Tests updating query param with state state_cursor_value = int((self._now - timedelta(days=5)).timestamp()) record_cursor_value = self._now_in_seconds - 1 - state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() + state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([state_cursor_value, self._now_in_seconds]).build(), + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([state_cursor_value, self._now_in_seconds]) + .build(), _a_response().with_record(_a_record().with_cursor(record_cursor_value)).build(), ) output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8)), state) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=record_cursor_value) + assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=str(record_cursor_value)) diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_subscription_with_scheduled_changes.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_subscription_with_scheduled_changes.py index 0eff336263df..cb6d46f8124c 100644 --- a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_subscription_with_scheduled_changes.py +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_subscription_with_scheduled_changes.py @@ -5,6 +5,8 @@ from unittest import TestCase import freezegun +from source_chargebee import SourceChargebee + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read @@ -20,13 +22,13 @@ find_template, ) from airbyte_cdk.test.state_builder import StateBuilder -from source_chargebee import SourceChargebee from .config import ConfigBuilder from .pagination import ChargebeePaginationStrategy from .request_builder import ChargebeeRequestBuilder, ChargebeeSubstreamRequestBuilder from .response_builder import a_response_with_status, a_response_with_status_and_header + _STREAM_NAME = "subscription_with_scheduled_changes" _SITE = "test-site" _SITE_API_KEY = "test-api-key" @@ -36,65 +38,68 @@ _NO_STATE = {} _NOW = datetime.now(timezone.utc) + def _a_parent_request() -> ChargebeeRequestBuilder: return ChargebeeRequestBuilder.subscription_endpoint(_SITE, _SITE_API_KEY) + def _a_child_request() -> ChargebeeSubstreamRequestBuilder: return ChargebeeSubstreamRequestBuilder.subscription_with_scheduled_changes_endpoint(_SITE, _SITE_API_KEY) + def _config() -> ConfigBuilder: return ConfigBuilder().with_site(_SITE).with_site_api_key(_SITE_API_KEY).with_product_catalog(_PRODUCT_CATALOG) + def _catalog(sync_mode: SyncMode) -> ConfiguredAirbyteCatalog: - return CatalogBuilder().with_stream(_STREAM_NAME, sync_mode).with_stream("subscription", sync_mode).build() + return CatalogBuilder().with_stream(_STREAM_NAME, sync_mode).build() + + +def _source(catalog: ConfiguredAirbyteCatalog, config: Dict[str, Any], state: Optional[Dict[str, Any]]) -> SourceChargebee: + return SourceChargebee(catalog=catalog, config=config, state=state) -def _source() -> SourceChargebee: - return SourceChargebee() def _a_parent_record() -> RecordBuilder: return create_record_builder( find_template("subscription", __file__), FieldPath("list"), record_id_path=NestedPath(["subscription", _PRIMARY_KEY]), - record_cursor_path=NestedPath(["subscription", _CURSOR_FIELD]) + record_cursor_path=NestedPath(["subscription", _CURSOR_FIELD]), ) + def _a_child_record() -> RecordBuilder: return create_record_builder( find_template("subscription_with_scheduled_changes", __file__), FieldPath("list"), record_id_path=NestedPath(["subscription", _PRIMARY_KEY]), - record_cursor_path=NestedPath(["subscription", _CURSOR_FIELD]) + record_cursor_path=NestedPath(["subscription", _CURSOR_FIELD]), ) + def _a_parent_response() -> HttpResponseBuilder: return create_response_builder( - find_template("subscription", __file__), - FieldPath("list"), - pagination_strategy=ChargebeePaginationStrategy() + find_template("subscription", __file__), FieldPath("list"), pagination_strategy=ChargebeePaginationStrategy() ) -def _a_child_response() -> HttpResponseBuilder: +def _a_child_response() -> HttpResponseBuilder: return create_response_builder( - find_template("subscription_with_scheduled_changes", __file__), - FieldPath("list"), - pagination_strategy=ChargebeePaginationStrategy() + find_template("subscription_with_scheduled_changes", __file__), FieldPath("list"), pagination_strategy=ChargebeePaginationStrategy() ) + def _read( - config_builder: ConfigBuilder, - sync_mode: SyncMode, - state: Optional[Dict[str, Any]] = None, - expecting_exception: bool = False + config_builder: ConfigBuilder, sync_mode: SyncMode, state: Optional[Dict[str, Any]] = None, expecting_exception: bool = False ) -> EntrypointOutput: catalog = _catalog(sync_mode) config = config_builder.build() - return read(_source(), config, catalog, state, expecting_exception) + source = _source(catalog=catalog, config=config, state=state) + return read(source, config, catalog, state, expecting_exception) + @freezegun.freeze_time(_NOW.isoformat()) class FullRefreshTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -106,33 +111,92 @@ def _read(config: ConfigBuilder, expecting_exception: bool = False) -> Entrypoin return _read(config, SyncMode.full_refresh, expecting_exception=expecting_exception) @HttpMocker() - def test_given_valid_response_records_are_extracted_and_returned(self, http_mocker: HttpMocker) -> None: - + def test_when_read_then_records_are_extracted(self, http_mocker: HttpMocker) -> None: parent_id = "subscription_test" http_mocker.get( _a_parent_request().with_any_query_params().build(), - _a_parent_response().with_record(_a_parent_record().with_id(parent_id)).build() + _a_parent_response().with_record(_a_parent_record().with_id(parent_id)).build(), + ) + http_mocker.get( + _a_child_request() + .with_parent_id(parent_id) + .with_endpoint_path("retrieve_with_scheduled_changes") + .with_any_query_params() + .build(), + _a_child_response().with_record(_a_child_record()).build(), + ) + + output = self._read(_config().with_start_date(self._start_date)) + assert len(output.records) == 1 + + @HttpMocker() + def test_given_multiple_parents_when_read_then_fetch_for_each_parent(self, http_mocker: HttpMocker) -> None: + a_parent_id = "a_subscription_test" + another_parent_id = "another_subscription_test" + + http_mocker.get( + _a_parent_request().with_any_query_params().build(), + _a_parent_response() + .with_record(_a_parent_record().with_id(a_parent_id)) + .with_record(_a_parent_record().with_id(another_parent_id)) + .build(), + ) + + http_mocker.get( + _a_child_request() + .with_parent_id(a_parent_id) + .with_endpoint_path("retrieve_with_scheduled_changes") + .with_any_query_params() + .build(), + _a_child_response().with_record(_a_child_record()).build(), ) http_mocker.get( - _a_child_request().with_parent_id(parent_id).with_endpoint_path("retrieve_with_scheduled_changes").with_any_query_params().build(), - _a_child_response().with_record(_a_child_record().with_id(parent_id)).build() + _a_child_request() + .with_parent_id(another_parent_id) + .with_endpoint_path("retrieve_with_scheduled_changes") + .with_any_query_params() + .build(), + _a_child_response().with_record(_a_child_record()).build(), ) output = self._read(_config().with_start_date(self._start_date)) assert len(output.records) == 2 @HttpMocker() - def test_given_http_status_400_when_read_then_stream_is_ignored(self, http_mocker: HttpMocker) -> None: + def test_when_read_then_primary_key_is_set(self, http_mocker: HttpMocker) -> None: + parent_id = "subscription_test" + + http_mocker.get( + _a_parent_request().with_any_query_params().build(), + _a_parent_response().with_record(_a_parent_record().with_id(parent_id)).build(), + ) + http_mocker.get( + _a_child_request() + .with_parent_id(parent_id) + .with_endpoint_path("retrieve_with_scheduled_changes") + .with_any_query_params() + .build(), + _a_child_response().with_record(_a_child_record()).build(), + ) + + output = self._read(_config().with_start_date(self._start_date)) + assert "subscription_id" in output.records[0].record.data + @HttpMocker() + def test_given_http_status_400_when_read_then_stream_is_ignored(self, http_mocker: HttpMocker) -> None: parent_id = "subscription_test" http_mocker.get( _a_parent_request().with_any_query_params().build(), - _a_parent_response().with_record(_a_parent_record().with_id(parent_id)).build() + _a_parent_response().with_record(_a_parent_record().with_id(parent_id)).build(), ) http_mocker.get( - _a_child_request().with_parent_id(parent_id).with_endpoint_path("retrieve_with_scheduled_changes").with_any_query_params().build(), + _a_child_request() + .with_parent_id(parent_id) + .with_endpoint_path("retrieve_with_scheduled_changes") + .with_any_query_params() + .build(), a_response_with_status(400), ) @@ -140,15 +204,18 @@ def test_given_http_status_400_when_read_then_stream_is_ignored(self, http_mocke @HttpMocker() def test_given_http_status_404_when_read_then_stream_is_ignored(self, http_mocker: HttpMocker) -> None: - parent_id = "subscription_test" http_mocker.get( _a_parent_request().with_any_query_params().build(), - _a_parent_response().with_record(_a_parent_record().with_id(parent_id)).build() + _a_parent_response().with_record(_a_parent_record().with_id(parent_id)).build(), ) http_mocker.get( - _a_child_request().with_parent_id(parent_id).with_endpoint_path("retrieve_with_scheduled_changes").with_any_query_params().build(), + _a_child_request() + .with_parent_id(parent_id) + .with_endpoint_path("retrieve_with_scheduled_changes") + .with_any_query_params() + .build(), a_response_with_status(404), ) diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_virtual_bank_account.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_virtual_bank_account.py index 0f986eb87b6f..24527edf0f0c 100644 --- a/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_virtual_bank_account.py +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/integration/test_virtual_bank_account.py @@ -5,6 +5,8 @@ from unittest import TestCase import freezegun +from source_chargebee import SourceChargebee + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read @@ -19,13 +21,13 @@ find_template, ) from airbyte_cdk.test.state_builder import StateBuilder -from source_chargebee import SourceChargebee from .config import ConfigBuilder from .pagination import ChargebeePaginationStrategy from .request_builder import ChargebeeRequestBuilder from .response_builder import a_response_with_status, a_response_with_status_and_header + _STREAM_NAME = "virtual_bank_account" _SITE = "test-site" _SITE_API_KEY = "test-api-key" @@ -35,46 +37,49 @@ _NO_STATE = {} _NOW = datetime.now(timezone.utc) + def _a_request() -> ChargebeeRequestBuilder: return ChargebeeRequestBuilder.virtual_bank_account_endpoint(_SITE, _SITE_API_KEY) + def _config() -> ConfigBuilder: return ConfigBuilder().with_site(_SITE).with_site_api_key(_SITE_API_KEY).with_product_catalog(_PRODUCT_CATALOG) + def _catalog(sync_mode: SyncMode) -> ConfiguredAirbyteCatalog: return CatalogBuilder().with_stream(_STREAM_NAME, sync_mode).build() -def _source() -> SourceChargebee: - return SourceChargebee() + +def _source(catalog: ConfiguredAirbyteCatalog, config: Dict[str, Any], state: Optional[Dict[str, Any]]) -> SourceChargebee: + return SourceChargebee(catalog=catalog, config=config, state=state) + def _a_record() -> RecordBuilder: return create_record_builder( find_template(_STREAM_NAME, __file__), FieldPath("list"), record_id_path=NestedPath([_STREAM_NAME, _PRIMARY_KEY]), - record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]) + record_cursor_path=NestedPath([_STREAM_NAME, _CURSOR_FIELD]), ) + def _a_response() -> HttpResponseBuilder: return create_response_builder( - find_template(_STREAM_NAME, __file__), - FieldPath("list"), - pagination_strategy=ChargebeePaginationStrategy() + find_template(_STREAM_NAME, __file__), FieldPath("list"), pagination_strategy=ChargebeePaginationStrategy() ) + def _read( - config_builder: ConfigBuilder, - sync_mode: SyncMode, - state: Optional[Dict[str, Any]] = None, - expecting_exception: bool = False + config_builder: ConfigBuilder, sync_mode: SyncMode, state: Optional[Dict[str, Any]] = None, expecting_exception: bool = False ) -> EntrypointOutput: catalog = _catalog(sync_mode) config = config_builder.build() - return read(_source(), config, catalog, state, expecting_exception) + source = _source(catalog=catalog, config=config, state=state) + return read(source, config, catalog, state, expecting_exception) + @freezegun.freeze_time(_NOW.isoformat()) class FullRefreshTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -89,8 +94,7 @@ def _read(config: ConfigBuilder, expecting_exception: bool = False) -> Entrypoin def test_given_valid_response_records_are_extracted_and_returned(self, http_mocker: HttpMocker) -> None: # Tests simple read and record extraction http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record()).with_record(_a_record()).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record()).with_record(_a_record()).build() ) output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8))) assert len(output.records) == 2 @@ -99,12 +103,21 @@ def test_given_valid_response_records_are_extracted_and_returned(self, http_mock def test_given_multiple_pages_of_records_read_and_returned(self, http_mocker: HttpMocker) -> None: # Tests pagination http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]).build(), - _a_response().with_record(_a_record()).with_pagination().build() + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]) + .build(), + _a_response().with_record(_a_record()).with_pagination().build(), ) http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]).with_offset("[1707076198000,57873868]").build(), - _a_response().with_record(_a_record()).build() + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([self._start_date_in_seconds, self._now_in_seconds]) + .with_offset("[1707076198000,57873868]") + .build(), + _a_response().with_record(_a_record()).build(), ) self._read(_config().with_start_date(self._start_date)) @@ -113,14 +126,10 @@ def test_given_multiple_pages_of_records_read_and_returned(self, http_mocker: Ht @HttpMocker() def test_given_http_status_400_when_read_then_stream_is_ignored(self, http_mocker: HttpMocker) -> None: # Tests 400 status error handling - http_mocker.get( - _a_request().with_any_query_params().build(), - a_response_with_status(400) - ) + http_mocker.get(_a_request().with_any_query_params().build(), a_response_with_status(400)) output = self._read(_config().with_start_date(self._start_date), expecting_exception=True) assert len(output.get_stream_statuses(f"{_STREAM_NAME}s")) == 0 - @HttpMocker() def test_given_http_status_401_when_the_stream_is_incomplete(self, http_mocker: HttpMocker) -> None: # Test 401 status error handling @@ -164,9 +173,9 @@ def test_given_http_status_500_after_max_retries_raises_config_error(self, http_ output = self._read(_config(), expecting_exception=True) assert output.errors[-1].trace.error.failure_type == FailureType.config_error + @freezegun.freeze_time(_NOW.isoformat()) class IncrementalTest(TestCase): - def setUp(self) -> None: self._now = _NOW self._now_in_seconds = int(self._now.timestamp()) @@ -182,25 +191,28 @@ def test_given_no_initial_state_when_read_then_return_state_based_on_most_recent # Tests setting state when no initial state is provided cursor_value = self._start_date_in_seconds + 1 http_mocker.get( - _a_request().with_any_query_params().build(), - _a_response().with_record(_a_record().with_cursor(cursor_value)).build() + _a_request().with_any_query_params().build(), _a_response().with_record(_a_record().with_cursor(cursor_value)).build() ) output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8)), _NO_STATE) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=cursor_value) + assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=str(cursor_value)) @HttpMocker() def test_given_initial_state_use_state_for_query_params(self, http_mocker: HttpMocker) -> None: # Tests updating query param with state state_cursor_value = int((self._now - timedelta(days=5)).timestamp()) record_cursor_value = self._now_in_seconds - 1 - state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() + state = StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: state_cursor_value}).build() http_mocker.get( - _a_request().with_sort_by_asc(_CURSOR_FIELD).with_include_deleted(True).with_updated_at_btw([state_cursor_value, self._now_in_seconds]).build(), + _a_request() + .with_sort_by_asc(_CURSOR_FIELD) + .with_include_deleted(True) + .with_updated_at_btw([state_cursor_value, self._now_in_seconds]) + .build(), _a_response().with_record(_a_record().with_cursor(record_cursor_value)).build(), ) output = self._read(_config().with_start_date(self._start_date - timedelta(hours=8)), state) most_recent_state = output.most_recent_state assert most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) - assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=record_cursor_value) + assert most_recent_state.stream_state == AirbyteStateBlob(updated_at=str(record_cursor_value)) diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/resource/config/config.json b/airbyte-integrations/connectors/source-chargebee/unit_tests/resource/config/config.json new file mode 100644 index 000000000000..e17d5c774af4 --- /dev/null +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/resource/config/config.json @@ -0,0 +1,6 @@ +{ + "site": "test", + "site_api_key": "fake-key", + "start_date": "2023-01-01T06:57:44Z", + "product_catalog": "2.0" +} diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/test_component.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/test_component.py index 54709f56fed0..4dd6cf059289 100644 --- a/airbyte-integrations/connectors/source-chargebee/unit_tests/test_component.py +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/test_component.py @@ -2,9 +2,10 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # import pytest -from airbyte_cdk.sources.types import Record, StreamSlice from source_chargebee.components import CustomFieldTransformation, IncrementalSingleSliceCursor +from airbyte_cdk.sources.types import Record, StreamSlice + @pytest.mark.parametrize( "record, expected_record", @@ -26,11 +27,12 @@ def test_field_transformation(record, expected_record): transformed_record = transformer.transform(record) assert transformed_record == expected_record + @pytest.mark.parametrize( "record_data, expected", [ ({"pk": 1, "name": "example", "updated_at": 1662459011}, True), - ] + ], ) def test_slicer(record_data, expected): date_time_dict = {"updated_at": 1662459010} @@ -50,24 +52,17 @@ def test_slicer(record_data, expected): @pytest.mark.parametrize( "first_record, second_record, expected", [ - ({"pk": 1, "name": "example", "updated_at": 1662459010}, - {"pk": 2, "name": "example2", "updated_at": 1662460000}, - True), - ({"pk": 1, "name": "example", "updated_at": 1662459010}, - {"pk": 2, "name": "example2", "updated_at": 1662440000}, - False), - ({"pk": 1, "name": "example", "updated_at": 1662459010}, - {"pk": 2, "name": "example2"}, - False), - ({"pk": 1, "name": "example"}, - {"pk": 2, "name": "example2", "updated_at": 1662459010}, - True), - ] + ({"pk": 1, "name": "example", "updated_at": 1662459010}, {"pk": 2, "name": "example2", "updated_at": 1662460000}, True), + ({"pk": 1, "name": "example", "updated_at": 1662459010}, {"pk": 2, "name": "example2", "updated_at": 1662440000}, False), + ({"pk": 1, "name": "example", "updated_at": 1662459010}, {"pk": 2, "name": "example2"}, False), + ({"pk": 1, "name": "example"}, {"pk": 2, "name": "example2", "updated_at": 1662459010}, True), + ], ) def test_is_greater_than_or_equal(first_record, second_record, expected): slicer = IncrementalSingleSliceCursor(config={}, parameters={}, cursor_field="updated_at") assert slicer.is_greater_than_or_equal(second_record, first_record) == expected + def test_set_initial_state(): cursor_field = "updated_at" cursor_value = 999999999 @@ -75,18 +70,19 @@ def test_set_initial_state(): slicer.set_initial_state(stream_state={cursor_field: cursor_value}) assert slicer._state[cursor_field] == cursor_value + @pytest.mark.parametrize( "record, expected", [ - ({"pk": 1, "name": "example", "updated_at": 1662459010}, - True), - ] + ({"pk": 1, "name": "example", "updated_at": 1662459010}, True), + ], ) def test_should_be_synced(record, expected): cursor_field = "updated_at" slicer = IncrementalSingleSliceCursor(config={}, parameters={}, cursor_field=cursor_field) assert slicer.should_be_synced(record) == expected + def test_stream_slices(): slicer = IncrementalSingleSliceCursor(config={}, parameters={}, cursor_field="updated_at") stream_slices_instance = slicer.stream_slices() diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/test_run.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/test_run.py new file mode 100644 index 000000000000..b2991eda1ac1 --- /dev/null +++ b/airbyte-integrations/connectors/source-chargebee/unit_tests/test_run.py @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + +from unittest.mock import patch + +from source_chargebee.run import run + + +def test_run_with_non_existing_config(): + with patch("sys.argv", ["", "check", "--config", "resource/config/config.json"]): + # A check failed message is expected because the test config doesn't have a valid API key. But this + # still validates that we could instantiate the concurrent source correctly with the incoming args + assert run() is None diff --git a/airbyte-integrations/connectors/source-chargebee/unit_tests/test_source.py b/airbyte-integrations/connectors/source-chargebee/unit_tests/test_source.py deleted file mode 100644 index 62feab67ad1d..000000000000 --- a/airbyte-integrations/connectors/source-chargebee/unit_tests/test_source.py +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from source_chargebee import SourceChargebee - - -def test_source(): - assert SourceChargebee() \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-chargedesk/metadata.yaml b/airbyte-integrations/connectors/source-chargedesk/metadata.yaml index eab427a58169..a83314aa9462 100644 --- a/airbyte-integrations/connectors/source-chargedesk/metadata.yaml +++ b/airbyte-integrations/connectors/source-chargedesk/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-chargedesk connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: cd803254-3d2c-4613-a870-20d205ee6267 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.9 dockerRepository: airbyte/source-chargedesk githubIssueLabel: source-chargedesk icon: icon.svg diff --git a/airbyte-integrations/connectors/source-chargify/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-chargify/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-chargify/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-chargify/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-chargify/metadata.yaml b/airbyte-integrations/connectors/source-chargify/metadata.yaml index 5dd38159e7e7..da731e112c64 100644 --- a/airbyte-integrations/connectors/source-chargify/metadata.yaml +++ b/airbyte-integrations/connectors/source-chargify/metadata.yaml @@ -14,7 +14,7 @@ data: connectorSubtype: api connectorType: source definitionId: 9b2d3607-7222-4709-9fa2-c2abdebbdd88 - dockerImageTag: 0.5.0 + dockerImageTag: 0.5.5 dockerRepository: airbyte/source-chargify githubIssueLabel: source-chargify icon: chargify.svg @@ -42,5 +42,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.5.4@sha256:b07a521add11f987c63c0db68c1b57e90bec0c985f1cb6f3c5a1940cde628a70 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-chartmogul/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-chartmogul/integration_tests/acceptance.py index efc25f08ce82..78b220cebb18 100644 --- a/airbyte-integrations/connectors/source-chartmogul/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-chartmogul/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-chartmogul/metadata.yaml b/airbyte-integrations/connectors/source-chartmogul/metadata.yaml index 1d9cbb219c17..4664c472f512 100644 --- a/airbyte-integrations/connectors/source-chartmogul/metadata.yaml +++ b/airbyte-integrations/connectors/source-chartmogul/metadata.yaml @@ -18,11 +18,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: b6604cbd-1b12-4c08-8767-e140d0fb0877 - dockerImageTag: 1.1.1 + dockerImageTag: 1.1.5 dockerRepository: airbyte/source-chartmogul githubIssueLabel: source-chartmogul icon: chartmogul.svg diff --git a/airbyte-integrations/connectors/source-cimis/metadata.yaml b/airbyte-integrations/connectors/source-cimis/metadata.yaml index 7c50fb1a9259..830bded3d082 100644 --- a/airbyte-integrations/connectors/source-cimis/metadata.yaml +++ b/airbyte-integrations/connectors/source-cimis/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-cimis connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: d169ef9b-6741-4af6-b4c8-7ec4410d7f0e - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-cimis githubIssueLabel: source-cimis icon: icon.svg diff --git a/airbyte-integrations/connectors/source-cin7/README.md b/airbyte-integrations/connectors/source-cin7/README.md new file mode 100644 index 000000000000..5ff8416e5839 --- /dev/null +++ b/airbyte-integrations/connectors/source-cin7/README.md @@ -0,0 +1,39 @@ +# Cin7 +This directory contains the manifest-only connector for `source-cin7`. + +This is the Cin7 source that ingests data from the Cin7 API. + +Cin7 (Connector Inventory Performance), If you’re a business that wants to grow, you need an inventory solution you can count on - both now and in the future. With Cin7 you get a real-time picture of your products across systems, channels, marketplaces and regions, plus NEW ForesightAI advanced inventory forecasting that empowers you to see around corners and stay three steps ahead of demand! https://www.cin7.com/ + +To use this source, you must first create an account. Once logged in, head to Integrations -> API -> Cin7 Core API. +Create an application and note down the Account Id and the API key, you will need to enter these in the input fields. You can find more information about the API here https://dearinventory.docs.apiary.io/#reference + + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-cin7:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-cin7 build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-cin7 test +``` + diff --git a/airbyte-integrations/connectors/source-cin7/acceptance-test-config.yml b/airbyte-integrations/connectors/source-cin7/acceptance-test-config.yml new file mode 100644 index 000000000000..5872089b3130 --- /dev/null +++ b/airbyte-integrations/connectors/source-cin7/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-cin7:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-cin7/icon.svg b/airbyte-integrations/connectors/source-cin7/icon.svg new file mode 100644 index 000000000000..74df1bc30a79 --- /dev/null +++ b/airbyte-integrations/connectors/source-cin7/icon.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-cin7/manifest.yaml b/airbyte-integrations/connectors/source-cin7/manifest.yaml new file mode 100644 index 000000000000..62a77d3b5f07 --- /dev/null +++ b/airbyte-integrations/connectors/source-cin7/manifest.yaml @@ -0,0 +1,2288 @@ +version: 5.17.0 + +type: DeclarativeSource + +description: > + This is the Cin7 source that ingests data from the Cin7 API. + + + Cin7 (Connector Inventory Performance), If you’re a business that wants to + grow, you need an inventory solution you can count on - both now and in the + future. With Cin7 you get a real-time picture of your products across systems, + channels, marketplaces and regions, plus NEW ForesightAI advanced inventory + forecasting that empowers you to see around corners and stay three steps ahead + of demand! https://www.cin7.com/ + + + To use this source, you must first create an account. Once logged in, head to + Integrations -> API -> Cin7 Core API. + + Create an application and note down the Account Id and the API key, you will + need to enter these in the input fields. You can find more information about + the API here https://dearinventory.docs.apiary.io/#reference + +check: + type: CheckStream + stream_names: + - bank_accounts + +definitions: + streams: + bank_accounts: + type: DeclarativeStream + name: bank_accounts + primary_key: + - AccountID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/ref/accountBank + http_method: GET + request_headers: + api-auth-accountid: "{{ config[\"accountid\"] }}" + api-auth-applicationkey: "{{ config[\"api_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - BankAccountsList + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/bank_accounts" + attribute_sets: + type: DeclarativeStream + name: attribute_sets + primary_key: + - ID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/ref/attributeset + http_method: GET + request_headers: + api-auth-accountid: "{{ config[\"accountid\"] }}" + api-auth-applicationkey: "{{ config[\"api_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - AttributeSetList + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/attribute_sets" + accounts: + type: DeclarativeStream + name: accounts + primary_key: + - Code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/ref/account + http_method: GET + request_headers: + api-auth-accountid: "{{ config[\"accountid\"] }}" + api-auth-applicationkey: "{{ config[\"api_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - AccountsList + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounts" + brands: + type: DeclarativeStream + name: brands + primary_key: + - ID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/ref/brand + http_method: GET + request_headers: + api-auth-accountid: "{{ config[\"accountid\"] }}" + api-auth-applicationkey: "{{ config[\"api_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - BrandList + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/brands" + carriers: + type: DeclarativeStream + name: carriers + primary_key: + - CarrierID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/ref/carrier + http_method: GET + request_headers: + api-auth-accountid: "{{ config[\"accountid\"] }}" + api-auth-applicationkey: "{{ config[\"api_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - CarrierList + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/carriers" + customers: + type: DeclarativeStream + name: customers + primary_key: + - ID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/customer + http_method: GET + request_headers: + api-auth-accountid: "{{ config[\"accountid\"] }}" + api-auth-applicationkey: "{{ config[\"api_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - CustomerList + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers" + deals: + type: DeclarativeStream + name: deals + primary_key: + - ID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/reference/deals + http_method: GET + request_headers: + api-auth-accountid: "{{ config[\"accountid\"] }}" + api-auth-applicationkey: "{{ config[\"api_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Deals + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/deals" + locations: + type: DeclarativeStream + name: locations + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/ref/location + http_method: GET + request_headers: + api-auth-accountid: "{{ config[\"accountid\"] }}" + api-auth-applicationkey: "{{ config[\"api_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/locations" + products: + type: DeclarativeStream + name: products + primary_key: + - ID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /products + http_method: GET + request_headers: + api-auth-accountid: "{{ config[\"accountid\"] }}" + api-auth-applicationkey: "{{ config[\"api_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Products + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + purchases: + type: DeclarativeStream + name: purchases + primary_key: + - ID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: purchaselist + http_method: GET + request_headers: + api-auth-accountid: "{{ config[\"accountid\"] }}" + api-auth-applicationkey: "{{ config[\"api_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - PurchaseList + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/purchases" + suppliers: + type: DeclarativeStream + name: suppliers + primary_key: + - ID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: suppliers + http_method: GET + request_headers: + api-auth-accountid: "{{ config[\"accountid\"] }}" + api-auth-applicationkey: "{{ config[\"api_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Suppliers + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/suppliers" + sales: + type: DeclarativeStream + name: sales + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/crm/opportunity + http_method: GET + request_headers: + api-auth-accountid: "{{ config[\"accountid\"] }}" + api-auth-applicationkey: "{{ config[\"api_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - opportunityList + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sales" + sale_list: + type: DeclarativeStream + name: sale_list + primary_key: + - SaleID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/saleList + http_method: GET + request_headers: + api-auth-accountid: "{{ config[\"accountid\"] }}" + api-auth-applicationkey: "{{ config[\"api_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - SaleList + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sale_list" + taxes: + type: DeclarativeStream + name: taxes + primary_key: + - ID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/ref/tax + http_method: GET + request_headers: + api-auth-accountid: "{{ config[\"accountid\"] }}" + api-auth-applicationkey: "{{ config[\"api_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - TaxRuleList + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/taxes" + product_categories: + type: DeclarativeStream + name: product_categories + primary_key: + - ID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/ref/category + http_method: GET + request_headers: + api-auth-accountid: "{{ config[\"accountid\"] }}" + api-auth-applicationkey: "{{ config[\"api_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - CategoryList + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/product_categories" + product_family: + type: DeclarativeStream + name: product_family + primary_key: + - ID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/productFamily + http_method: GET + request_headers: + api-auth-accountid: "{{ config[\"accountid\"] }}" + api-auth-applicationkey: "{{ config[\"api_key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - ProductFamilies + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/product_family" + base_requester: + type: HttpRequester + url_base: https://inventory.dearsystems.com/externalapi/ + +streams: + - $ref: "#/definitions/streams/bank_accounts" + - $ref: "#/definitions/streams/attribute_sets" + - $ref: "#/definitions/streams/accounts" + - $ref: "#/definitions/streams/brands" + - $ref: "#/definitions/streams/carriers" + - $ref: "#/definitions/streams/customers" + - $ref: "#/definitions/streams/deals" + - $ref: "#/definitions/streams/locations" + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/purchases" + - $ref: "#/definitions/streams/suppliers" + - $ref: "#/definitions/streams/sales" + - $ref: "#/definitions/streams/sale_list" + - $ref: "#/definitions/streams/taxes" + - $ref: "#/definitions/streams/product_categories" + - $ref: "#/definitions/streams/product_family" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - accountid + - api_key + properties: + accountid: + type: string + description: The ID associated with your account. + order: 0 + title: Account ID + api_key: + type: string + description: The API key associated with your account. + order: 1 + title: API Key + additionalProperties: true + +metadata: + autoImportSchema: + bank_accounts: true + attribute_sets: true + accounts: true + brands: true + carriers: true + customers: true + deals: true + locations: true + products: true + purchases: true + suppliers: true + sales: true + sale_list: true + taxes: true + product_categories: true + product_family: true + testedStreams: + bank_accounts: + hasRecords: true + streamHash: f7dd65eb1f8a795e710813293bccdf70380226ff + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + attribute_sets: + hasRecords: true + streamHash: a477de0eca518a4c300f0581fabe1d00ae87cb1d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + accounts: + hasRecords: true + streamHash: f544371a8538ec73c072dbfd3241c64aba21124f + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + brands: + hasRecords: true + streamHash: 73573fb44c4417e98dbe0650e1782df7c57ae6d7 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + carriers: + hasRecords: true + streamHash: 4d049420bb231781198df96e94f555db8922970e + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + customers: + hasRecords: true + streamHash: 8ebcdd2288269655b2b926a08b3ff13de4830701 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + deals: + streamHash: 3091c0f345e8e31f88ed309fbc5d000ec7eca4b3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + locations: + hasRecords: true + streamHash: e49c3d38646053ba45575de9669e6f163187fbbb + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + products: + hasRecords: true + streamHash: c5379cda41ba035523eaa33f17107d772e25f1d3 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + purchases: + hasRecords: true + streamHash: 751de6d6cfbfcfb538a62a15db61f2ea8dcc6f63 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + suppliers: + streamHash: 58f238049ce5031d00fee8b5b562c6110541afd8 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + sales: + streamHash: d09addf97ad0ae0453e42ff9f3e8f66bb71616aa + hasResponse: true + responsesAreSuccessful: true + hasRecords: false + primaryKeysArePresent: true + primaryKeysAreUnique: true + sale_list: + hasRecords: true + streamHash: 63f057d9b8a830772b5e0ae35c44c189821a21c5 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + taxes: + hasRecords: true + streamHash: 67b527295ad75865bbf0f651f8faf1d461839e85 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + product_categories: + streamHash: 60ce930da7366da26fdc07296bcc6b7f9601882d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + product_family: + streamHash: 7e9a93bb48fe322bac0d4db56acc9e46c63534b0 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + bank_accounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + AccountCode: + type: + - string + - "null" + AccountID: + type: string + AccountName: + type: + - string + - "null" + AccountNumber: + type: + - string + - "null" + Bank: + type: + - string + - "null" + Currency: + type: + - string + - "null" + InitialBalance: + type: + - number + - "null" + StatementBalance: + type: + - number + - "null" + required: + - AccountID + attribute_sets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Attribute10Name: + type: + - string + - "null" + Attribute10Type: + type: + - string + - "null" + Attribute1Name: + type: + - string + - "null" + Attribute1Type: + type: + - string + - "null" + Attribute2Name: + type: + - string + - "null" + Attribute2Type: + type: + - string + - "null" + Attribute2Values: + type: + - string + - "null" + Attribute3Name: + type: + - string + - "null" + Attribute3Type: + type: + - string + - "null" + Attribute4Name: + type: + - string + - "null" + Attribute4Type: + type: + - string + - "null" + Attribute5Name: + type: + - string + - "null" + Attribute5Type: + type: + - string + - "null" + Attribute6Name: + type: + - string + - "null" + Attribute6Type: + type: + - string + - "null" + Attribute7Name: + type: + - string + - "null" + Attribute7Type: + type: + - string + - "null" + Attribute8Name: + type: + - string + - "null" + Attribute8Type: + type: + - string + - "null" + Attribute9Name: + type: + - string + - "null" + Attribute9Type: + type: + - string + - "null" + Attributes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + Name: + type: + - string + - "null" + Type: + type: + - string + - "null" + Values: + type: + - string + - "null" + ID: + type: string + Name: + type: + - string + - "null" + required: + - ID + accounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + BankAccountId: + type: + - string + - "null" + BankAccountNumber: + type: + - string + - "null" + Class: + type: + - string + - "null" + Code: + type: string + Description: + type: + - string + - "null" + DisplayName: + type: + - string + - "null" + ForPayments: + type: + - boolean + - "null" + Name: + type: + - string + - "null" + Status: + type: + - string + - "null" + SystemAccount: + type: + - string + - "null" + SystemAccountCode: + type: + - string + - "null" + Type: + type: + - string + - "null" + required: + - Code + brands: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + ID: + type: string + Name: + type: + - string + - "null" + required: + - ID + carriers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + CarrierID: + type: string + Description: + type: + - string + - "null" + required: + - CarrierID + customers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + AccountReceivable: + type: + - string + - "null" + Addresses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + City: + type: + - string + - "null" + DefaultForType: + type: + - boolean + - "null" + ID: + type: + - string + - "null" + Line1: + type: + - string + - "null" + Line2: + type: + - string + - "null" + Postcode: + type: + - string + - "null" + State: + type: + - string + - "null" + Type: + type: + - string + - "null" + Carrier: + type: + - string + - "null" + Contacts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + Comment: + type: + - string + - "null" + Default: + type: + - boolean + - "null" + Email: + type: + - string + - "null" + Fax: + type: + - string + - "null" + ID: + type: + - string + - "null" + IncludeInEmail: + type: + - boolean + - "null" + JobTitle: + type: + - string + - "null" + MarketingConsent: + type: + - number + - "null" + MobilePhone: + type: + - string + - "null" + Name: + type: + - string + - "null" + Phone: + type: + - string + - "null" + Website: + type: + - string + - "null" + CreditLimit: + type: + - number + - "null" + Currency: + type: + - string + - "null" + Discount: + type: + - number + - "null" + ID: + type: string + IsOnCreditHold: + type: + - boolean + - "null" + LastModifiedOn: + type: + - string + - "null" + Location: + type: + - string + - "null" + Name: + type: + - string + - "null" + PaymentTerm: + type: + - string + - "null" + PriceTier: + type: + - string + - "null" + ProductPrices: + type: + - array + - "null" + RevenueAccount: + type: + - string + - "null" + Status: + type: + - string + - "null" + TaxRule: + type: + - string + - "null" + required: + - ID + deals: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + AllowCoupons: + type: + - boolean + - "null" + CouponCodes: + type: + - string + - "null" + CustomersGroup: + type: + - string + - "null" + DateFrom: + type: + - string + - "null" + DateTo: + type: + - string + - "null" + DealCustomerTags: + type: + - array + - "null" + DealCustomers: + type: + - array + - "null" + DealDiscounts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + BuyMore: + type: + - boolean + - "null" + DealDiscountBrands: + type: + - array + - "null" + DealDiscountCategories: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + CategoryID: + type: + - string + - "null" + CategoryName: + type: + - string + - "null" + ID: + type: + - string + - "null" + DealDiscountProducts: + type: + - array + - "null" + DealDiscountTags: + type: + - array + - "null" + DiscountID: + type: + - string + - "null" + DiscountName: + type: + - string + - "null" + DiscountType: + type: + - string + - "null" + ID: + type: + - string + - "null" + IsOrderLevel: + type: + - boolean + - "null" + Sequence: + type: + - number + - "null" + ID: + type: string + IsActive: + type: + - boolean + - "null" + Name: + type: + - string + - "null" + SingleCouponCodeUsage: + type: + - boolean + - "null" + required: + - ID + locations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + LocationList: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + Bins: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + ID: + type: + - string + - "null" + IsDeprecated: + type: + - boolean + - "null" + IsStaging: + type: + - boolean + - "null" + Name: + type: + - string + - "null" + FixedAssetsLocation: + type: + - boolean + - "null" + ID: + type: + - string + - "null" + IsCoMan: + type: + - boolean + - "null" + IsDefault: + type: + - boolean + - "null" + IsDeprecated: + type: + - boolean + - "null" + IsShopFloor: + type: + - boolean + - "null" + IsStaging: + type: + - boolean + - "null" + Name: + type: + - string + - "null" + ParentID: + type: + - string + - "null" + Page: + type: + - number + - "null" + Total: + type: + - number + - "null" + products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + AdditionalAttribute1: + type: + - string + - "null" + AdditionalAttribute10: + type: + - string + - "null" + AdditionalAttribute2: + type: + - string + - "null" + AdditionalAttribute3: + type: + - string + - "null" + AdditionalAttribute4: + type: + - string + - "null" + AdditionalAttribute5: + type: + - string + - "null" + AdditionalAttribute6: + type: + - string + - "null" + AdditionalAttribute7: + type: + - string + - "null" + AdditionalAttribute8: + type: + - string + - "null" + AdditionalAttribute9: + type: + - string + - "null" + AttributeSet: + type: + - string + - "null" + AverageCost: + type: + - number + - "null" + Barcode: + type: + - string + - "null" + Brand: + type: + - string + - "null" + Category: + type: + - string + - "null" + CostingMethod: + type: + - string + - "null" + DefaultLocation: + type: + - string + - "null" + Description: + type: + - string + - "null" + DropShipMode: + type: + - string + - "null" + ExpenseAccount: + type: + - string + - "null" + Height: + type: + - number + - "null" + ID: + type: string + InventoryAccount: + type: + - string + - "null" + LastModifiedOn: + type: + - string + - "null" + Length: + type: + - number + - "null" + MinimumBeforeReorder: + type: + - number + - "null" + Name: + type: + - string + - "null" + PickZones: + type: + - string + - "null" + PriceTier1: + type: + - number + - "null" + PriceTier10: + type: + - number + - "null" + PriceTier2: + type: + - number + - "null" + PriceTier3: + type: + - number + - "null" + PriceTier4: + type: + - number + - "null" + PriceTier5: + type: + - number + - "null" + PriceTier6: + type: + - number + - "null" + PriceTier7: + type: + - number + - "null" + PriceTier8: + type: + - number + - "null" + PriceTier9: + type: + - number + - "null" + PriceTiers: + type: + - object + - "null" + properties: + Tier 1: + type: + - number + - "null" + Tier 10: + type: + - number + - "null" + Tier 2: + type: + - number + - "null" + Tier 3: + type: + - number + - "null" + Tier 4: + type: + - number + - "null" + Tier 5: + type: + - number + - "null" + Tier 6: + type: + - number + - "null" + Tier 7: + type: + - number + - "null" + Tier 8: + type: + - number + - "null" + Tier 9: + type: + - number + - "null" + PurchaseTaxRule: + type: + - string + - "null" + ReorderQuantity: + type: + - number + - "null" + RevenueAccount: + type: + - string + - "null" + SKU: + type: + - string + - "null" + SaleTaxRule: + type: + - string + - "null" + Sellable: + type: + - boolean + - "null" + Status: + type: + - string + - "null" + StockLocator: + type: + - string + - "null" + Tags: + type: + - string + - "null" + Type: + type: + - string + - "null" + UOM: + type: + - string + - "null" + Weight: + type: + - number + - "null" + Width: + type: + - number + - "null" + required: + - ID + purchases: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + BaseCurrency: + type: + - string + - "null" + BlindReceipt: + type: + - boolean + - "null" + CreditNoteNumber: + type: + - string + - "null" + CreditNoteStatus: + type: + - string + - "null" + ID: + type: string + InvoiceAmount: + type: + - number + - "null" + InvoiceDate: + type: + - string + - "null" + InvoiceDueDate: + type: + - string + - "null" + InvoiceNumber: + type: + - string + - "null" + InvoiceStatus: + type: + - string + - "null" + LastUpdatedDate: + type: + - string + - "null" + OrderDate: + type: + - string + - "null" + OrderNumber: + type: + - string + - "null" + OrderStatus: + type: + - string + - "null" + PaidAmount: + type: + - number + - "null" + RequiredBy: + type: + - string + - "null" + Status: + type: + - string + - "null" + StockReceivedStatus: + type: + - string + - "null" + Supplier: + type: + - string + - "null" + SupplierCurrency: + type: + - string + - "null" + SupplierID: + type: + - string + - "null" + UnstockStatus: + type: + - string + - "null" + required: + - ID + suppliers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + AccountPayable: + type: + - string + - "null" + Addresses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + City: + type: + - string + - "null" + Country: + type: + - string + - "null" + DefaultForType: + type: + - boolean + - "null" + Line1: + type: + - string + - "null" + Line2: + type: + - string + - "null" + Postcode: + type: + - string + - "null" + State: + type: + - string + - "null" + Type: + type: + - string + - "null" + Contacts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + Default: + type: + - boolean + - "null" + Email: + type: + - string + - "null" + Fax: + type: + - string + - "null" + IncludeInEmail: + type: + - boolean + - "null" + MobilePhone: + type: + - string + - "null" + Name: + type: + - string + - "null" + Phone: + type: + - string + - "null" + Currency: + type: + - string + - "null" + Discount: + type: + - number + - "null" + ID: + type: string + LastModifiedOn: + type: + - string + - "null" + Name: + type: + - string + - "null" + PaymentTerm: + type: + - string + - "null" + Status: + type: + - string + - "null" + TaxRule: + type: + - string + - "null" + required: + - ID + sales: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Page: + type: + - number + - "null" + Total: + type: + - number + - "null" + opportunityList: + type: + - array + - "null" + sale_list: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + BaseCurrency: + type: + - string + - "null" + CombinedInvoiceStatus: + type: + - string + - "null" + CombinedPackingStatus: + type: + - string + - "null" + CombinedPaymentStatus: + type: + - string + - "null" + CombinedPickingStatus: + type: + - string + - "null" + CombinedShippingStatus: + type: + - string + - "null" + CombinedTrackingNumbers: + type: + - string + - "null" + CreditNoteStatus: + type: + - string + - "null" + Customer: + type: + - string + - "null" + CustomerCurrency: + type: + - string + - "null" + CustomerID: + type: + - string + - "null" + CustomerReference: + type: + - string + - "null" + ExternalID: + type: + - string + - "null" + FulFilmentStatus: + type: + - string + - "null" + InvoiceAmount: + type: + - number + - "null" + InvoiceDate: + type: + - string + - "null" + InvoiceDueDate: + type: + - string + - "null" + InvoiceNumber: + type: + - string + - "null" + OrderDate: + type: + - string + - "null" + OrderLocationID: + type: + - string + - "null" + OrderNumber: + type: + - string + - "null" + OrderStatus: + type: + - string + - "null" + PaidAmount: + type: + - number + - "null" + QuoteStatus: + type: + - string + - "null" + RestockStatus: + type: + - string + - "null" + SaleID: + type: string + ShipBy: + type: + - string + - "null" + Status: + type: + - string + - "null" + Type: + type: + - string + - "null" + Updated: + type: + - string + - "null" + required: + - SaleID + taxes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Account: + type: + - string + - "null" + Components: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + ComponentOrder: + type: + - number + - "null" + Compound: + type: + - boolean + - "null" + Name: + type: + - string + - "null" + ID: + type: string + IsActive: + type: + - boolean + - "null" + IsTaxForPurchase: + type: + - boolean + - "null" + IsTaxForSale: + type: + - boolean + - "null" + Name: + type: + - string + - "null" + TaxInclusive: + type: + - boolean + - "null" + TaxPercent: + type: + - number + - "null" + required: + - ID + product_categories: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + ID: + type: string + Name: + type: + - string + - "null" + required: + - ID + product_family: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Attachments: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + ContentType: + type: + - string + - "null" + DownloadUrl: + type: + - string + - "null" + FileName: + type: + - string + - "null" + ID: + type: + - string + - "null" + IsDefault: + type: + - boolean + - "null" + AttributeSet: + type: + - string + - "null" + Brand: + type: + - string + - "null" + Category: + type: + - string + - "null" + CostingMethod: + type: + - string + - "null" + DefaultLocation: + type: + - string + - "null" + Description: + type: + - string + - "null" + DropShipMode: + type: + - string + - "null" + ID: + type: string + LastModifiedOn: + type: + - string + - "null" + MinimumBeforeReorder: + type: + - number + - "null" + Name: + type: + - string + - "null" + Option1Name: + type: + - string + - "null" + Option1Values: + type: + - string + - "null" + Option2Name: + type: + - string + - "null" + Option2Values: + type: + - string + - "null" + Option3Name: + type: + - string + - "null" + Option3Values: + type: + - string + - "null" + PriceTier1: + type: + - number + - "null" + PriceTier10: + type: + - number + - "null" + PriceTier2: + type: + - number + - "null" + PriceTier3: + type: + - number + - "null" + PriceTier4: + type: + - number + - "null" + PriceTier5: + type: + - number + - "null" + PriceTier6: + type: + - number + - "null" + PriceTier7: + type: + - number + - "null" + PriceTier8: + type: + - number + - "null" + PriceTier9: + type: + - number + - "null" + Products: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + ID: + type: + - string + - "null" + Name: + type: + - string + - "null" + Option1: + type: + - string + - "null" + Option2: + type: + - string + - "null" + Option3: + type: + - string + - "null" + SKU: + type: + - string + - "null" + ReorderQuantity: + type: + - number + - "null" + SKU: + type: + - string + - "null" + ShortDescription: + type: + - string + - "null" + Tags: + type: + - string + - "null" + UOM: + type: + - string + - "null" + required: + - ID diff --git a/airbyte-integrations/connectors/source-cin7/metadata.yaml b/airbyte-integrations/connectors/source-cin7/metadata.yaml new file mode 100644 index 000000000000..a1606fb159d6 --- /dev/null +++ b/airbyte-integrations/connectors/source-cin7/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "inventory.dearsystems.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-cin7 + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: ff48bf15-f917-4fff-ba28-cbab56ef892f + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-cin7 + githubIssueLabel: source-cin7 + icon: icon.svg + license: MIT + name: Cin7 + releaseDate: 2024-10-30 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/cin7 + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-circa/README.md b/airbyte-integrations/connectors/source-circa/README.md new file mode 100644 index 000000000000..fc4404b28c9e --- /dev/null +++ b/airbyte-integrations/connectors/source-circa/README.md @@ -0,0 +1,33 @@ +# Circa +This directory contains the manifest-only connector for `source-circa`. + +Airbyte connector for Circa.com would enable seamless data extraction from Circa's platform, facilitating automated data integration into your data warehouse or analytics systems. This connector would pull key metrics, user engagement data, and content performance insights, offering streamlined reporting and analysis workflows. Ideal for organizations looking to consolidate Circa’s data with other sources for comprehensive business intelligence. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-circa:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-circa build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-circa test +``` + diff --git a/airbyte-integrations/connectors/source-circa/acceptance-test-config.yml b/airbyte-integrations/connectors/source-circa/acceptance-test-config.yml new file mode 100644 index 000000000000..1d6bf38a00e6 --- /dev/null +++ b/airbyte-integrations/connectors/source-circa/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-circa:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-circa/icon.svg b/airbyte-integrations/connectors/source-circa/icon.svg new file mode 100644 index 000000000000..93d3f5a9ea7c --- /dev/null +++ b/airbyte-integrations/connectors/source-circa/icon.svg @@ -0,0 +1,12 @@ + + + + diff --git a/airbyte-integrations/connectors/source-circa/manifest.yaml b/airbyte-integrations/connectors/source-circa/manifest.yaml new file mode 100644 index 000000000000..94251e480473 --- /dev/null +++ b/airbyte-integrations/connectors/source-circa/manifest.yaml @@ -0,0 +1,1065 @@ +version: 5.14.0 + +type: DeclarativeSource + +description: >- + Airbyte connector for Circa.com would enable seamless data extraction from + Circa's platform, facilitating automated data integration into your data + warehouse or analytics systems. This connector would pull key metrics, user + engagement data, and content performance insights, offering streamlined + reporting and analysis workflows. Ideal for organizations looking to + consolidate Circa’s data with other sources for comprehensive business + intelligence. + +check: + type: CheckStream + stream_names: + - events + +definitions: + streams: + teams: + type: DeclarativeStream + name: teams + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: page + inject_into: body_json + pagination_strategy: + type: PageIncrement + page_size: 25 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /teams + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/teams" + events: + type: DeclarativeStream + name: events + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: page + inject_into: body_json + pagination_strategy: + type: PageIncrement + page_size: 25 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /events + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/events" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: updated_at[max] + inject_into: request_parameter + start_time_option: + type: RequestOption + field_name: updated_at[min] + inject_into: request_parameter + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + contacts: + type: DeclarativeStream + name: contacts + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: page + inject_into: body_json + pagination_strategy: + type: PageIncrement + page_size: 25 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: updated_at[max] + inject_into: request_parameter + start_time_option: + type: RequestOption + field_name: updated_at[min] + inject_into: request_parameter + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + companies: + type: DeclarativeStream + name: companies + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: page + inject_into: body_json + pagination_strategy: + type: PageIncrement + page_size: 25 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /companies + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/companies" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: updated_at[max] + inject_into: request_parameter + start_time_option: + type: RequestOption + field_name: updated_at[min] + inject_into: request_parameter + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + event_fields: + type: DeclarativeStream + name: event_fields + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /fields + http_method: GET + request_parameters: + fields_for: Event + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/event_fields" + company_fields: + type: DeclarativeStream + name: company_fields + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /fields + http_method: GET + request_parameters: + fields_for: Company + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/company_fields" + contact_fields: + type: DeclarativeStream + name: contact_fields + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /fields + http_method: GET + request_parameters: + fields_for: Contact + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contact_fields" + event_contacts: + type: DeclarativeStream + name: event_contacts + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: page + inject_into: body_json + pagination_strategy: + type: PageIncrement + page_size: 25 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /events/{{ stream_partition.event_id }}/contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: + $ref: "#/definitions/streams/events" + parent_key: id + partition_field: event_id + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/event_contacts" + company_contacts: + type: DeclarativeStream + name: company_contacts + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + field_name: page + inject_into: body_json + pagination_strategy: + type: PageIncrement + page_size: 25 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: companies/{{ stream_partition.company_id }}/contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: + $ref: "#/definitions/streams/companies" + parent_key: id + partition_field: company_id + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/company_contacts" + base_requester: + type: HttpRequester + url_base: https://app.circa.co/api/v1 + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/events" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/teams" + - $ref: "#/definitions/streams/companies" + - $ref: "#/definitions/streams/company_contacts" + - $ref: "#/definitions/streams/event_fields" + - $ref: "#/definitions/streams/contact_fields" + - $ref: "#/definitions/streams/company_fields" + - $ref: "#/definitions/streams/event_contacts" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - start_date + properties: + api_key: + type: string + description: >- + API key to use. Find it at + https://app.circa.co/settings/integrations/api + name: api_key + order: 0 + title: API Key + airbyte_secret: true + start_date: + type: string + order: 1 + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + additionalProperties: true + +metadata: + assist: + docsUrl: https://docs.circa.co/ + testedStreams: + teams: + hasRecords: true + streamHash: 3a333dca6eb202b626d5807858c9cb70c580636c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + events: + hasRecords: true + streamHash: e819947a5a8c1bc9759c82397024bd83cfb469b1 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + contacts: + hasRecords: true + streamHash: 497d37a0e403270401c202685588af80ed0e9f11 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + companies: + hasRecords: true + streamHash: 216768eb9e27c528ff4d46f339eaef671b7f1e5a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + event_fields: + hasRecords: true + streamHash: 6d9b721f9f31fbdb46af0f0b90e5fb7a796ae16f + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + company_fields: + hasRecords: true + streamHash: 40d227270ec88a6e2fdd397292a6e55c843a215b + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + contact_fields: + hasRecords: true + streamHash: a00fdf4f6fbfe317353c876fc88e5ff49de42241 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + event_contacts: + hasRecords: true + streamHash: 6d9d71beb8ff08a57680d4ebf85abe59bbc1114c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + company_contacts: + hasRecords: true + streamHash: 18ddfafe76ae6aa6b4538b8703e88293e3f8c6c2 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + autoImportSchema: + teams: true + events: true + contacts: false + companies: true + event_fields: true + company_fields: true + contact_fields: true + event_contacts: true + company_contacts: true + +schemas: + teams: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + name: + type: + - string + - "null" + additionalProperties: true + events: + type: object + $schema: http://json-schema.org/schema# + required: + - id + - updated_at + properties: + id: + type: string + name: + type: + - string + - "null" + team: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + roles: + type: + - array + - "null" + types: + type: + - array + - "null" + status: + type: + - string + - "null" + website: + type: + - string + - "null" + brief_url: + type: + - string + - "null" + time_zone: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + email: + type: + - string + - "null" + last_name: + type: + - string + - "null" + first_name: + type: + - string + - "null" + paid_total: + type: + - number + - "null" + updated_at: + type: string + updated_by: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + email: + type: + - string + - "null" + last_name: + type: + - string + - "null" + first_name: + type: + - string + - "null" + actual_total: + type: + - number + - "null" + planned_total: + type: + - number + - "null" + additionalProperties: true + contacts: + type: object + $schema: http://json-schema.org/schema# + required: + - id + - updated_at + properties: + id: + type: string + email: + type: + - string + - "null" + company: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + hot_lead: + type: + - boolean + - "null" + last_name: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + email: + type: + - string + - "null" + last_name: + type: + - string + - "null" + first_name: + type: + - string + - "null" + first_name: + type: + - string + - "null" + updated_at: + type: string + updated_by: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + email: + type: + - string + - "null" + last_name: + type: + - string + - "null" + first_name: + type: + - string + - "null" + sync_status: + type: + - object + - "null" + properties: + status: + type: + - string + - "null" + email_opt_in: + type: + - boolean + - "null" + created_method: + type: + - string + - "null" + updated_method: + type: + - string + - "null" + additionalProperties: true + companies: + type: object + $schema: http://json-schema.org/schema# + required: + - updated_at + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + created_at: + type: + - string + - "null" + updated_at: + type: string + additionalProperties: true + event_fields: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + label: + type: + - string + - "null" + order: + type: + - number + - "null" + options: + type: + - array + - "null" + items: + type: + - string + - "null" + section: + type: + - string + - "null" + required: + type: + - boolean + - "null" + field_for: + type: + - string + - "null" + field_name: + type: + - string + - "null" + field_type: + type: + - string + - "null" + additionalProperties: true + company_fields: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + label: + type: + - string + - "null" + order: + type: + - number + - "null" + required: + type: + - boolean + - "null" + field_for: + type: + - string + - "null" + field_name: + type: + - string + - "null" + field_type: + type: + - string + - "null" + additionalProperties: true + contact_fields: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + label: + type: + - string + - "null" + order: + type: + - number + - "null" + options: + type: + - array + - "null" + items: + type: + - string + - "null" + required: + type: + - boolean + - "null" + field_for: + type: + - string + - "null" + field_name: + type: + - string + - "null" + field_type: + type: + - string + - "null" + additionalProperties: true + event_contacts: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + email: + type: + - string + - "null" + company: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + hot_lead: + type: + - boolean + - "null" + last_name: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + email: + type: + - string + - "null" + last_name: + type: + - string + - "null" + first_name: + type: + - string + - "null" + first_name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + email: + type: + - string + - "null" + last_name: + type: + - string + - "null" + first_name: + type: + - string + - "null" + sync_status: + type: + - object + - "null" + properties: + status: + type: + - string + - "null" + email_opt_in: + type: + - boolean + - "null" + created_method: + type: + - string + - "null" + updated_method: + type: + - string + - "null" + additionalProperties: true + company_contacts: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + email: + type: + - string + - "null" + company: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + hot_lead: + type: + - boolean + - "null" + last_name: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + email: + type: + - string + - "null" + last_name: + type: + - string + - "null" + first_name: + type: + - string + - "null" + first_name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + email: + type: + - string + - "null" + last_name: + type: + - string + - "null" + first_name: + type: + - string + - "null" + email_opt_in: + type: + - boolean + - "null" + created_method: + type: + - string + - "null" + updated_method: + type: + - string + - "null" + additionalProperties: true diff --git a/airbyte-integrations/connectors/source-circa/metadata.yaml b/airbyte-integrations/connectors/source-circa/metadata.yaml new file mode 100644 index 000000000000..1d61ff79a1d3 --- /dev/null +++ b/airbyte-integrations/connectors/source-circa/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "app.circa.co" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-circa + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 751184ec-3b11-4084-b1b7-8064dde1e76e + dockerImageTag: 0.0.7 + dockerRepository: airbyte/source-circa + githubIssueLabel: source-circa + icon: icon.svg + license: MIT + name: Circa + releaseDate: 2024-10-21 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/circa + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-clarif-ai/metadata.yaml b/airbyte-integrations/connectors/source-clarif-ai/metadata.yaml index 9f3a713be047..540d16172647 100644 --- a/airbyte-integrations/connectors/source-clarif-ai/metadata.yaml +++ b/airbyte-integrations/connectors/source-clarif-ai/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-clarif-ai connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.14.0@sha256:accdf6c1bbcabd45b40f836692e4f3b1a1e1f0b28267973802ee212cd9c2c16a + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 7fbeaeea-2d0d-4f13-8200-fa228494d91c - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-clarif-ai githubIssueLabel: source-clarif-ai icon: icon.svg diff --git a/airbyte-integrations/connectors/source-clazar/icon.svg b/airbyte-integrations/connectors/source-clazar/icon.svg index e7c2546fccd4..7f8043898a3e 100644 --- a/airbyte-integrations/connectors/source-clazar/icon.svg +++ b/airbyte-integrations/connectors/source-clazar/icon.svg @@ -1,3 +1,11 @@ - - + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-clazar/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-clazar/integration_tests/acceptance.py index efc25f08ce82..78b220cebb18 100644 --- a/airbyte-integrations/connectors/source-clazar/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-clazar/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-clazar/metadata.yaml b/airbyte-integrations/connectors/source-clazar/metadata.yaml index feaeedca6651..755dcd8d7cd8 100644 --- a/airbyte-integrations/connectors/source-clazar/metadata.yaml +++ b/airbyte-integrations/connectors/source-clazar/metadata.yaml @@ -12,11 +12,11 @@ data: enabled: false packageName: airbyte-source-clazar connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: d7df7b64-6266-45b5-ad83-e1515578f371 - dockerImageTag: 0.4.2 + dockerImageTag: 0.4.8 dockerRepository: airbyte/source-clazar githubIssueLabel: source-clazar icon: clazar.svg diff --git a/airbyte-integrations/connectors/source-clickhouse-strict-encrypt/metadata.yaml b/airbyte-integrations/connectors/source-clickhouse-strict-encrypt/metadata.yaml index 915c7ded54dc..ba1a1bc5437d 100644 --- a/airbyte-integrations/connectors/source-clickhouse-strict-encrypt/metadata.yaml +++ b/airbyte-integrations/connectors/source-clickhouse-strict-encrypt/metadata.yaml @@ -3,24 +3,26 @@ data: hosts: - ${host} - ${tunnel_method.tunnel_host} - registryOverrides: - cloud: - enabled: false # strict encrypt connectors are deployed to Cloud by their non strict encrypt sibling. - oss: - enabled: false # strict encrypt connectors are not used on OSS. + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a connectorSubtype: database + connectorTestSuitesOptions: + - suite: integrationTests connectorType: source definitionId: bad83517-5e54-4a3d-9b53-63e85fbd4d7c - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.3 dockerRepository: airbyte/source-clickhouse-strict-encrypt + documentationUrl: https://docs.airbyte.com/integrations/sources/clickhouse githubIssueLabel: source-clickhouse icon: clickhouse.svg license: MIT name: ClickHouse + registryOverrides: + cloud: + enabled: false + oss: + enabled: false releaseStage: alpha - documentationUrl: https://docs.airbyte.com/integrations/sources/clickhouse tags: - language:java - connectorTestSuitesOptions: - - suite: integrationTests metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-clickhouse/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-clickhouse/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-clickhouse/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-clickhouse/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-clickhouse/metadata.yaml b/airbyte-integrations/connectors/source-clickhouse/metadata.yaml index 4e81c5069720..3151b3880d5b 100644 --- a/airbyte-integrations/connectors/source-clickhouse/metadata.yaml +++ b/airbyte-integrations/connectors/source-clickhouse/metadata.yaml @@ -6,10 +6,14 @@ data: hosts: - ${host} - ${tunnel_method.tunnel_host} + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a connectorSubtype: database + connectorTestSuitesOptions: + - suite: integrationTests connectorType: source definitionId: bad83517-5e54-4a3d-9b53-63e85fbd4d7c - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.3 dockerRepository: airbyte/source-clickhouse documentationUrl: https://docs.airbyte.com/integrations/sources/clickhouse githubIssueLabel: source-clickhouse @@ -18,7 +22,7 @@ data: name: ClickHouse registryOverrides: cloud: - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.3 dockerRepository: airbyte/source-clickhouse-strict-encrypt enabled: true oss: @@ -27,6 +31,4 @@ data: supportLevel: community tags: - language:java - connectorTestSuitesOptions: - - suite: integrationTests metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-clickup-api/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-clickup-api/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-clickup-api/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-clickup-api/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-clickup-api/metadata.yaml b/airbyte-integrations/connectors/source-clickup-api/metadata.yaml index 8b6e94625f4e..4ab2851c929f 100644 --- a/airbyte-integrations/connectors/source-clickup-api/metadata.yaml +++ b/airbyte-integrations/connectors/source-clickup-api/metadata.yaml @@ -5,7 +5,7 @@ data: connectorSubtype: api connectorType: source definitionId: 311a7a27-3fb5-4f7e-8265-5e4afe258b66 - dockerImageTag: 0.3.1 + dockerImageTag: 0.3.5 dockerRepository: airbyte/source-clickup-api githubIssueLabel: source-clickup-api icon: clickup.svg @@ -43,5 +43,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-clockify/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-clockify/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-clockify/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-clockify/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-clockify/metadata.yaml b/airbyte-integrations/connectors/source-clockify/metadata.yaml index 55adb9a0be54..c9b5cdc22455 100644 --- a/airbyte-integrations/connectors/source-clockify/metadata.yaml +++ b/airbyte-integrations/connectors/source-clockify/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - api.clockify.me connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.4.3@sha256:8937b693c7e01087f6e86e683826ac20f160f7952b8f0a13cbf4f9bfdd7af570 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: e71aae8a-5143-11ed-bdc3-0242ac120002 - dockerImageTag: 0.4.1 + dockerImageTag: 0.4.5 dockerRepository: airbyte/source-clockify documentationUrl: https://docs.airbyte.com/integrations/sources/clockify githubIssueLabel: source-clockify diff --git a/airbyte-integrations/connectors/source-clockodo/README.md b/airbyte-integrations/connectors/source-clockodo/README.md new file mode 100644 index 000000000000..362136a37cab --- /dev/null +++ b/airbyte-integrations/connectors/source-clockodo/README.md @@ -0,0 +1,33 @@ +# Clockodo +This directory contains the manifest-only connector for `source-clockodo`. + +The Airbyte connector for Clockodo enables seamless data integration between Clockodo and your preferred data warehouse or destination. This connector allows you to efficiently extract time tracking, project management, and reporting data from Clockodo, providing accurate insights and facilitating informed business decisions. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-clockodo:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-clockodo build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-clockodo test +``` + diff --git a/airbyte-integrations/connectors/source-clockodo/acceptance-test-config.yml b/airbyte-integrations/connectors/source-clockodo/acceptance-test-config.yml new file mode 100644 index 000000000000..f65fe516be4b --- /dev/null +++ b/airbyte-integrations/connectors/source-clockodo/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-clockodo:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-clockodo/icon.svg b/airbyte-integrations/connectors/source-clockodo/icon.svg new file mode 100644 index 000000000000..347315df1151 --- /dev/null +++ b/airbyte-integrations/connectors/source-clockodo/icon.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-clockodo/manifest.yaml b/airbyte-integrations/connectors/source-clockodo/manifest.yaml new file mode 100644 index 000000000000..3e5543a0cb1a --- /dev/null +++ b/airbyte-integrations/connectors/source-clockodo/manifest.yaml @@ -0,0 +1,1588 @@ +version: 5.14.0 + +type: DeclarativeSource + +description: >- + The Airbyte connector for Clockodo enables seamless data integration between + Clockodo and your preferred data warehouse or destination. This connector + allows you to efficiently extract time tracking, project management, and + reporting data from Clockodo, providing accurate insights and facilitating + informed business decisions. + +check: + type: CheckStream + stream_names: + - projects + +definitions: + streams: + projects: + type: DeclarativeStream + name: projects + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/projects + http_method: GET + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - projects + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: items_per_page + pagination_strategy: + type: CursorPagination + page_size: 1000 + cursor_value: "{{ response.paging.current_page | int + 1 }}" + stop_condition: "{{ response.paging.count_pages == response.paging.current_page}}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/projects" + absences: + type: DeclarativeStream + name: absences + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/absences + http_method: GET + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - absences + partition_router: + type: ListPartitionRouter + values: "{{ config['years'] }}" + cursor_field: year + request_option: + type: RequestOption + inject_into: request_parameter + field_name: year + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/absences" + customers: + type: DeclarativeStream + name: customers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/customers + http_method: GET + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - customers + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: items_per_page + pagination_strategy: + type: CursorPagination + page_size: 1000 + cursor_value: "{{ response.paging.current_page | int + 1 }}" + stop_condition: "{{ response.paging.count_pages == response.paging.current_page}}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers" + entries: + type: DeclarativeStream + name: entries + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/entries + http_method: GET + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - entries + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.paging.current_page | int + 1 }}" + stop_condition: "{{ response.paging.count_pages == response.paging.current_page}}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: time_last_change + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: time_since + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: time_until + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/entries" + holidays_carry: + type: DeclarativeStream + name: holidays_carry + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /holidayscarry + http_method: GET + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - holidayscarry + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/holidays_carry" + holidays_quota: + type: DeclarativeStream + name: holidays_quota + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /holidaysquota + http_method: GET + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - holidaysquota + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/holidays_quota" + lumpsum_services: + type: DeclarativeStream + name: lumpsum_services + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/lumpsumservices + http_method: GET + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - lumpSumServices + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/lumpsum_services" + non_business_days: + type: DeclarativeStream + name: non_business_days + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /nonbusinessdays + http_method: GET + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - nonbusinessdays + partition_router: + type: ListPartitionRouter + values: "{{ config.years }}" + cursor_field: year + request_option: + type: RequestOption + inject_into: request_parameter + field_name: year + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/non_business_days" + overtime_carry: + type: DeclarativeStream + name: overtime_carry + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /overtimecarry + http_method: GET + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - overtimecarry + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/overtime_carry" + services: + type: DeclarativeStream + name: services + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/services + http_method: GET + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - services + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: items_per_page + pagination_strategy: + type: CursorPagination + page_size: 1000 + cursor_value: "{{ response.paging.current_page | int + 1 }}" + stop_condition: "{{ response.paging.count_pages == response.paging.current_page}}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/services" + surcharges: + type: DeclarativeStream + name: surcharges + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/surcharges + http_method: GET + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - surcharges + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/surcharges" + target_hours: + type: DeclarativeStream + name: target_hours + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /targethours + http_method: GET + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - targethours + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/target_hours" + teams: + type: DeclarativeStream + name: teams + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/teams + http_method: GET + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - teams + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/teams" + user_reports: + type: DeclarativeStream + name: user_reports + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /userreports + http_method: GET + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - userreports + partition_router: + type: ListPartitionRouter + values: "{{ config.years }}" + cursor_field: year + request_option: + type: RequestOption + inject_into: request_parameter + field_name: year + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/user_reports" + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/users + http_method: GET + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - users + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + customers_projects: + type: DeclarativeStream + name: customers_projects + primary_key: + - user_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/users/{{ stream_partition.user_id }}/access/customers-projects + http_method: GET + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: user_id + stream: + $ref: "#/definitions/streams/users" + transformations: + - type: AddFields + fields: + - path: + - user_id + value: "{{ stream_partition.user_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers_projects" + work_times: + type: DeclarativeStream + name: work_times + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/workTimes + http_method: GET + request_parameters: + users_id: "{{ stream_partition.user_id }}" + date_since: "{{ format_datetime(config['start_time'], '%Y-%m-%d') }}" + date_until: "{{ format_datetime(config[\"end_time\"], '%Y-%m-%d') }}" + request_headers: + X-Clockodo-External-Application: "{{ config[\"external_application\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - work_time_days + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.paging.current_page | int + 1 }}" + stop_condition: "{{ response.paging.count_pages == response.paging.current_page}}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: user_id + stream: + $ref: "#/definitions/streams/users" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/work_times" + base_requester: + type: HttpRequester + url_base: https://my.clockodo.com/api + authenticator: + type: BasicHttpAuthenticator + password: "{{ config[\"api_key\"] }}" + username: "{{ config[\"email_address\"] }}" + +streams: + - $ref: "#/definitions/streams/projects" + - $ref: "#/definitions/streams/absences" + - $ref: "#/definitions/streams/customers" + - $ref: "#/definitions/streams/entries" + - $ref: "#/definitions/streams/holidays_carry" + - $ref: "#/definitions/streams/holidays_quota" + - $ref: "#/definitions/streams/lumpsum_services" + - $ref: "#/definitions/streams/non_business_days" + - $ref: "#/definitions/streams/overtime_carry" + - $ref: "#/definitions/streams/services" + - $ref: "#/definitions/streams/surcharges" + - $ref: "#/definitions/streams/target_hours" + - $ref: "#/definitions/streams/teams" + - $ref: "#/definitions/streams/user_reports" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/customers_projects" + - $ref: "#/definitions/streams/work_times" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - email_address + - external_application + - years + - start_date + properties: + api_key: + type: string + description: >- + API key to use. Find it in the 'Personal data' section of your + Clockodo account. + name: api_key + order: 0 + title: API Key + airbyte_secret: true + email_address: + type: string + description: >- + Your Clockodo account email address. Find it in your Clockodo account + settings. + name: email_address + order: 1 + title: Email Address + external_application: + type: string + description: >- + Identification of the calling application, including the email address + of a technical contact person. Format: [name of application or + company];[email address]. + name: external_application + order: 2 + title: External Application Header + default: Airbyte + years: + type: array + description: 2024, 2025 + title: Years + order: 3 + start_date: + type: string + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + order: 4 + additionalProperties: true + +metadata: + autoImportSchema: + projects: true + absences: true + customers: true + entries: true + holidays_carry: true + holidays_quota: true + lumpsum_services: true + non_business_days: true + overtime_carry: true + services: true + surcharges: true + target_hours: true + teams: true + user_reports: true + users: true + customers_projects: true + work_times: true + testedStreams: + projects: + streamHash: 5118bb02f9bab96765d8d050e22412bdd5d51e35 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + absences: + streamHash: f26eb7e9a1605b995726ed13f6197e765acc385e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + customers: + streamHash: 08ca930fb7cfb6c36a63fe1a37542795cbc05984 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + entries: + streamHash: b4177032cf2a20851d3d07deb6c9a71fe3499645 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + holidays_carry: + streamHash: e48839eff131e148fe0fc088d169982751c78e81 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + holidays_quota: + streamHash: b9c95ec43672adfb723739044bb58a56dac3c908 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + lumpsum_services: + streamHash: 4a184ac9dbd17e470dfe6e1ad2f5de90756df6dc + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + non_business_days: + streamHash: a6fd505564d95facf53816c0cfba75f8f13c2ac9 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + overtime_carry: + streamHash: b2d2f23a96f7597fb258c8bf39582870782437d5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + services: + streamHash: 0657be7ab387318a21947cb7388dceb662387251 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + surcharges: + streamHash: 4d54a3384127ccd4e306d3622476667b53906fe7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + target_hours: + streamHash: d43471c2a05f4fdb9de873ed7c8665c752b16159 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + teams: + streamHash: 799dd4476020338c6f755be19a044b1216a72426 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + user_reports: + streamHash: 78993ea668dfeeab72f98a4a24d6875496825b84 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + users: + streamHash: bce80801cf75761b9491c55a9f3eb211e6f92e1e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + customers_projects: + streamHash: 564b5039ce98dfcc33f4ec0c145ce940ca3aa9d8 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + work_times: + streamHash: b25e0d40c153790d8cb4ecc3ddfd707edcf3eb81 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://www.clockodo.com/en/api/ + +schemas: + projects: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active: + type: + - boolean + - "null" + billable_default: + type: + - boolean + - "null" + billed_completely: + type: + - boolean + - "null" + budget_is_hours: + type: + - boolean + - "null" + budget_is_not_strict: + type: + - boolean + - "null" + budget_money: + type: + - number + - "null" + completed: + type: + - boolean + - "null" + customers_id: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + revenue_factor: + type: + - number + - "null" + test_data: + type: + - boolean + - "null" + required: + - id + absences: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + approved_by: + type: + - number + - "null" + count_days: + type: + - number + - "null" + date_approved: + type: + - string + - "null" + date_since: + type: + - string + - "null" + date_until: + type: + - string + - "null" + id: + type: number + status: + type: + - number + - "null" + users_id: + type: + - number + - "null" + required: + - id + customers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active: + type: + - boolean + - "null" + billable_default: + type: + - boolean + - "null" + color: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + test_data: + type: + - boolean + - "null" + required: + - id + entries: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + billable: + type: + - number + - "null" + clocked: + type: + - boolean + - "null" + clocked_offline: + type: + - boolean + - "null" + customers_id: + type: + - number + - "null" + duration: + type: + - number + - "null" + hourly_rate: + type: + - number + - "null" + id: + type: number + lumpsum: + type: + - number + - "null" + lumpsum_services_amount: + type: + - number + - "null" + lumpsum_services_id: + type: + - number + - "null" + projects_id: + type: + - number + - "null" + services_id: + type: + - number + - "null" + test_data: + type: + - boolean + - "null" + text: + type: + - string + - "null" + texts_id: + type: + - number + - "null" + time_clocked_since: + type: + - string + - "null" + time_insert: + type: + - string + - "null" + time_last_change: + type: string + time_last_change_work_time: + type: + - string + - "null" + time_since: + type: + - string + - "null" + time_until: + type: + - string + - "null" + users_id: + type: + - number + - "null" + required: + - id + - time_last_change + holidays_carry: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + count: + type: + - number + - "null" + id: + type: number + note: + type: + - string + - "null" + users_id: + type: + - number + - "null" + year: + type: + - number + - "null" + required: + - id + holidays_quota: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + count: + type: + - number + - "null" + id: + type: number + note: + type: + - string + - "null" + users_id: + type: + - number + - "null" + year_since: + type: + - number + - "null" + year_until: + type: + - number + - "null" + required: + - id + lumpsum_services: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active: + type: + - boolean + - "null" + id: + type: number + name: + type: + - string + - "null" + price: + type: + - number + - "null" + unit: + type: + - string + - "null" + required: + - id + non_business_days: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + date: + type: + - string + - "null" + half_day: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + nonbusinessgroups_id: + type: + - number + - "null" + required: + - id + overtime_carry: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + hours: + type: + - number + - "null" + id: + type: number + note: + type: + - string + - "null" + users_id: + type: + - number + - "null" + year: + type: + - number + - "null" + required: + - id + services: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active: + type: + - boolean + - "null" + id: + type: number + name: + type: + - string + - "null" + required: + - id + surcharges: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accumulation: + type: + - boolean + - "null" + id: + type: number + name: + type: + - string + - "null" + nonbusiness: + type: + - object + - "null" + properties: + percent: + type: + - number + - "null" + time_since: + type: + - string + - "null" + time_since_is_previous_day: + type: + - boolean + - "null" + time_until: + type: + - string + - "null" + time_until_is_next_day: + type: + - boolean + - "null" + nonbusiness_special: + type: + - object + - "null" + properties: + percent: + type: + - number + - "null" + time_since: + type: + - string + - "null" + time_since_is_previous_day: + type: + - boolean + - "null" + time_until: + type: + - string + - "null" + time_until_is_next_day: + type: + - boolean + - "null" + sunday: + type: + - object + - "null" + properties: + percent: + type: + - number + - "null" + time_since: + type: + - string + - "null" + time_since_is_previous_day: + type: + - boolean + - "null" + time_until: + type: + - string + - "null" + time_until_is_next_day: + type: + - boolean + - "null" + required: + - id + target_hours: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + compensation_daily: + type: + - number + - "null" + compensation_monthly: + type: + - number + - "null" + date_since: + type: + - string + - "null" + date_until: + type: + - string + - "null" + friday: + type: + - number + - "null" + id: + type: number + monday: + type: + - number + - "null" + saturday: + type: + - number + - "null" + sunday: + type: + - number + - "null" + test_data: + type: + - boolean + - "null" + thursday: + type: + - number + - "null" + tuesday: + type: + - number + - "null" + users_id: + type: + - number + - "null" + wednesday: + type: + - number + - "null" + required: + - id + teams: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: number + leader: + type: + - number + - "null" + name: + type: + - string + - "null" + required: + - id + user_reports: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + diff: + type: + - number + - "null" + holidays_carry: + type: + - number + - "null" + holidays_quota: + type: + - number + - "null" + overtime_carryover: + type: + - number + - "null" + overtime_reduced: + type: + - number + - "null" + sum_absence: + type: + - object + - "null" + properties: + home_office: + type: + - number + - "null" + maternity_protection: + type: + - number + - "null" + military_service: + type: + - number + - "null" + out_of_office: + type: + - number + - "null" + quarantine: + type: + - number + - "null" + regular_holidays: + type: + - number + - "null" + school: + type: + - number + - "null" + sick_child: + type: + - number + - "null" + sick_self: + type: + - number + - "null" + special_leaves: + type: + - number + - "null" + sum_hours: + type: + - number + - "null" + sum_reduction_planned: + type: + - number + - "null" + sum_reduction_used: + type: + - number + - "null" + sum_target: + type: + - number + - "null" + surcharges: + type: + - object + - "null" + properties: + night: + type: + - number + - "null" + night_increased: + type: + - number + - "null" + nonbusiness: + type: + - number + - "null" + nonbusiness_special: + type: + - number + - "null" + saturday: + type: + - number + - "null" + sunday: + type: + - number + - "null" + users_email: + type: + - string + - "null" + users_id: + type: + - number + - "null" + users_name: + type: + - string + - "null" + workdays: + type: + - number + - "null" + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + absence_managers_id: + type: + - array + - "null" + items: + type: + - number + - "null" + active: + type: + - boolean + - "null" + can_add_customers: + type: + - boolean + - "null" + can_generally_manage_absences: + type: + - boolean + - "null" + can_generally_see_absences: + type: + - boolean + - "null" + creator: + type: + - number + - "null" + default_holidays_count: + type: + - boolean + - "null" + default_target_hours: + type: + - boolean + - "null" + edit_lock_sync: + type: + - boolean + - "null" + email: + type: + - string + - "null" + id: + type: number + initials: + type: + - string + - "null" + language: + type: + - string + - "null" + name: + type: + - string + - "null" + role: + type: + - string + - "null" + support_pin: + type: + - string + - "null" + timeformat_12h: + type: + - boolean + - "null" + timezone: + type: + - string + - "null" + weekend_friday: + type: + - boolean + - "null" + weekstart_monday: + type: + - boolean + - "null" + work_time_edit_lock_days: + type: + - number + - "null" + worktime_regulation_id: + type: + - number + - "null" + required: + - id + customers_projects: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + add: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + report: + anyOf: + - type: boolean + - type: object + properties: + "3797976": + type: boolean + user_id: + type: number + required: + - user_id + work_times: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + date: + type: + - string + - "null" + intervals: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + time_since: + type: + - string + - "null" + time_until: + type: + - string + - "null" + offset: + type: + - number + - "null" + users_id: + type: + - number + - "null" diff --git a/airbyte-integrations/connectors/source-clockodo/metadata.yaml b/airbyte-integrations/connectors/source-clockodo/metadata.yaml new file mode 100644 index 000000000000..fe1227ca4315 --- /dev/null +++ b/airbyte-integrations/connectors/source-clockodo/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "my.clockodo.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-clockodo + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 9cddb136-acda-4755-9200-9014944650fc + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-clockodo + githubIssueLabel: source-clockodo + icon: icon.svg + license: MIT + name: Clockodo + releaseDate: 2024-10-28 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/clockodo + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-close-com/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-close-com/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-close-com/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-close-com/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-close-com/main.py b/airbyte-integrations/connectors/source-close-com/main.py index f80e76315939..cbd57dadfa8a 100644 --- a/airbyte-integrations/connectors/source-close-com/main.py +++ b/airbyte-integrations/connectors/source-close-com/main.py @@ -4,5 +4,6 @@ from source_close_com.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-close-com/metadata.yaml b/airbyte-integrations/connectors/source-close-com/metadata.yaml index ffdfbb2aef7a..a5ea851a455e 100644 --- a/airbyte-integrations/connectors/source-close-com/metadata.yaml +++ b/airbyte-integrations/connectors/source-close-com/metadata.yaml @@ -8,7 +8,7 @@ data: connectorSubtype: api connectorType: source definitionId: dfffecb7-9a13-43e9-acdc-b92af7997ca9 - dockerImageTag: 0.5.24 + dockerImageTag: 0.5.29 dockerRepository: airbyte/source-close-com documentationUrl: https://docs.airbyte.com/integrations/sources/close-com githubIssueLabel: source-close-com @@ -39,5 +39,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-close-com/poetry.lock b/airbyte-integrations/connectors/source-close-com/poetry.lock index ad049cdbb1a4..1c3b0a9a1f94 100644 --- a/airbyte-integrations/connectors/source-close-com/poetry.lock +++ b/airbyte-integrations/connectors/source-close-com/poetry.lock @@ -42,13 +42,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] @@ -56,24 +56,24 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -88,19 +88,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -166,13 +166,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -256,116 +256,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -435,20 +422,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -498,13 +485,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -519,13 +506,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -533,7 +520,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -583,13 +569,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -679,22 +665,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.136" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.136-py3-none-any.whl", hash = "sha256:cad2215eb7a754ee259878e19c558f4f8d3795aa1b699f087d4500e640f80d0a"}, - {file = "langsmith-0.1.136.tar.gz", hash = "sha256:5c0de01a313db70dd9a85845c0f416a69b5b653b3e98ba413d7d41e8851315b1"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -767,68 +756,86 @@ files = [ [[package]] name = "orjson" -version = "3.10.9" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.9-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a377186a11b48c55969e34f0aa414c2826a234f212d6f2b312ba512e3cdb2c6f"}, - {file = "orjson-3.10.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bf37bf0ca538065c34efe1803378b2dadd7e05b06610a086c2857f15ee59e12"}, - {file = "orjson-3.10.9-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7d9d83a91168aa48309acba804e393b7d9216b66f15e38f339b9fbb00db8986d"}, - {file = "orjson-3.10.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0014038a17a1fe273da0a5489787677ef5a64566ab383ad6d929e44ed5683f4"}, - {file = "orjson-3.10.9-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d6ae1b1733e4528e45675ed09a732b6ac37d716bce2facaf467f84ce774adecd"}, - {file = "orjson-3.10.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe91c2259c4a859356b6db1c6e649b40577492f66d483da8b8af6da0f87c00e3"}, - {file = "orjson-3.10.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a04f912c32463386ba117591c99a3d9e40b3b69bed9c5123d89dff06f0f5a4b0"}, - {file = "orjson-3.10.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ae82ca347829ca47431767b079f96bb977f592189250ccdede676339a80c8982"}, - {file = "orjson-3.10.9-cp310-none-win32.whl", hash = "sha256:fd5083906825d7f5d23089425ce5424d783d6294020bcabb8518a3e1f97833e5"}, - {file = "orjson-3.10.9-cp310-none-win_amd64.whl", hash = "sha256:e9ff9521b5be0340c8e686bcfe2619777fd7583f71e7b494601cc91ad3919d2e"}, - {file = "orjson-3.10.9-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f3bd9df47385b8fabb3b2ee1e83f9960b8accc1905be971a1c257f16c32b491e"}, - {file = "orjson-3.10.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4948961b6bce1e2086b2cf0b56cc454cdab589d40c7f85be71fb5a5556c51d3"}, - {file = "orjson-3.10.9-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a9fc7a6cf2b229ddc323e136df13b3fb4466c50d84ed600cd0898223dd2fea3"}, - {file = "orjson-3.10.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2314846e1029a2d2b899140f350eaaf3a73281df43ba84ac44d94ca861b5b269"}, - {file = "orjson-3.10.9-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f52d993504827503411df2d60e60acf52885561458d6273f99ecd172f31c4352"}, - {file = "orjson-3.10.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e29bbf08d907756c145a3a3a1f7ce2f11f15e3edbd3342842589d6030981b76f"}, - {file = "orjson-3.10.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7ae82992c00b480c3cc7dac6739324554be8c5d8e858a90044928506a3333ef4"}, - {file = "orjson-3.10.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6fdf8d32b6d94019dc15163542d345e9ce4c4661f56b318608aa3088a1a3a23b"}, - {file = "orjson-3.10.9-cp311-none-win32.whl", hash = "sha256:01f5fef452b4d7615f2e94153479370a4b59e0c964efb32dd902978f807a45cd"}, - {file = "orjson-3.10.9-cp311-none-win_amd64.whl", hash = "sha256:95361c4197c7ce9afdf56255de6f4e2474c39d16a277cce31d1b99a2520486d8"}, - {file = "orjson-3.10.9-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:43ad5560db54331c007dc38be5ba7706cb72974a29ae8227019d89305d750a6f"}, - {file = "orjson-3.10.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1471c3274b1a4a9b8f4b9ed6effaea9ad885796373797515c44b365b375c256d"}, - {file = "orjson-3.10.9-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:41d8cac575acd15918903d74cfaabb5dbe57b357b93341332f647d1013928dcc"}, - {file = "orjson-3.10.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2920c8754f1aedc98bd357ec172af18ce48f5f1017a92244c85fe41d16d3c6e0"}, - {file = "orjson-3.10.9-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c7fa3ff6a0d9d15a0d0d2254cca16cd919156a18423654ce5574591392fe9914"}, - {file = "orjson-3.10.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1e91b90c0c26bd79593967c1adef421bcff88c9e723d49c93bb7ad8af80bc6b"}, - {file = "orjson-3.10.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f11949024f785ace1a516db32fa6255f6227226b2c988abf66f5aee61d43d8f7"}, - {file = "orjson-3.10.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:060e020d85d0ec145bc1b536b1fd9c10a0519c91991ead9724d6f759ebe26b9a"}, - {file = "orjson-3.10.9-cp312-none-win32.whl", hash = "sha256:71f73439999fe662843da3607cdf6e75b1551c330f487e5801d463d969091c63"}, - {file = "orjson-3.10.9-cp312-none-win_amd64.whl", hash = "sha256:12e2efe81356b8448f1cd130f8d75d3718de583112d71f2e2f8baa81bd835bb9"}, - {file = "orjson-3.10.9-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:0ab6e3ad10e964392f0e838751bcce2ef9c8fa8be7deddffff83088e5791566d"}, - {file = "orjson-3.10.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68ef65223baab00f469c8698f771ab3e6ccf6af2a987e77de5b566b4ec651150"}, - {file = "orjson-3.10.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6f130848205fea90a2cb9fa2b11cafff9a9f31f4efad225800bc8b9e4a702f24"}, - {file = "orjson-3.10.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2ea7a98f3295ed8adb6730a5788cc78dafea28300d19932a1d2143457f7db802"}, - {file = "orjson-3.10.9-cp313-none-win32.whl", hash = "sha256:bdce39f96149a74fddeb2674c54f1da5e57724d32952eb6df2ac719b66d453cc"}, - {file = "orjson-3.10.9-cp313-none-win_amd64.whl", hash = "sha256:d11383701d4b58e795039b662ada46987744293d57bfa2719e7379b8d67bc796"}, - {file = "orjson-3.10.9-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1c3a1e845916a3739ab4162bb48dee66e0e727a19faf397176a7db0d9826cc3c"}, - {file = "orjson-3.10.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:063ca59d93d93d1387f0c4bb766c6d4f5b0e423fe7c366d0bd4401a56d1669d1"}, - {file = "orjson-3.10.9-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:938b7fcd79cf06fe348fb24b6163fbaa2fdc9fbed8b1f06318f24467f1487e63"}, - {file = "orjson-3.10.9-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cc32a9e43c7693011ccde6f8eff8cba75ca0d2a55de11092faa4a716101e67f5"}, - {file = "orjson-3.10.9-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1b3069b7e2f57f3eef2282029b9c2ba21f08a55f1018e483663a3356f046af4c"}, - {file = "orjson-3.10.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4289b5d1f88fd05dcafdd7a1f3b17bb722e77712b7618f98e86bdda560e0a1a"}, - {file = "orjson-3.10.9-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:74f5a7a7f282d326be71b722b0c350da7af6f5f15b9378da177e0e4a09bd91a3"}, - {file = "orjson-3.10.9-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:80e0c013e50cf7198319d8137931684eb9f32daa067e8276d9dbdd4010bb4add"}, - {file = "orjson-3.10.9-cp38-none-win32.whl", hash = "sha256:9d989152df8f60a76867354e0e08d896292ab9fb96a7ef89a5b3838de174522c"}, - {file = "orjson-3.10.9-cp38-none-win_amd64.whl", hash = "sha256:485358fe9892d6bfd88e5885b66bf88496e1842c8f35f61682ff9928b12a6cf0"}, - {file = "orjson-3.10.9-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ca54e6f320e33c8a6e471c424ee16576361d905c15d69e134c2906d3fcb31795"}, - {file = "orjson-3.10.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9a9eb03a29c9b30b6c8bb35e5fa20d96589a76e0042005be59b7c3af10a7e43"}, - {file = "orjson-3.10.9-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:731e8859fc99b398c286320726906404091141e9223dd5e9e6917f7e32e1cc68"}, - {file = "orjson-3.10.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:75b061c11f5aab979a95927a76394b4a85e3e4d63d0a2a16b56a4f7c6503afab"}, - {file = "orjson-3.10.9-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b61b08f6397f004570fd6a840f4a58946b63b4c7029408cdedb45fe85c7d17f7"}, - {file = "orjson-3.10.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c4f5e0360b7f0aba91dafe12469108109a0e8973956d4a9865ca262a6881406"}, - {file = "orjson-3.10.9-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e403429e2947a059545e305d97e4b0eb90d3bb44b396d6f327d7ae2018391e13"}, - {file = "orjson-3.10.9-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0e492b93e122264c2dc78700859122631a4715bda88fabf57d9226954cfe7ec5"}, - {file = "orjson-3.10.9-cp39-none-win32.whl", hash = "sha256:bfba9605e85bfd19b83a21c2c25c2bed2000d5f097f3fa3ad5b5f8a7263a3148"}, - {file = "orjson-3.10.9-cp39-none-win_amd64.whl", hash = "sha256:77d277fa138d4bf145e8b24042004891c188c52ac8492724a183f42b0031cf0c"}, - {file = "orjson-3.10.9.tar.gz", hash = "sha256:c378074e0c46035dc66e57006993233ec66bf8487d501bab41649b4b7289ed4d"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -931,54 +938,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -990,13 +997,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1284,33 +1291,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1377,13 +1384,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1408,81 +1415,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-close-com/pyproject.toml b/airbyte-integrations/connectors/source-close-com/pyproject.toml index 56865f5c1803..69e058f52235 100644 --- a/airbyte-integrations/connectors/source-close-com/pyproject.toml +++ b/airbyte-integrations/connectors/source-close-com/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.5.24" +version = "0.5.29" name = "source-close-com" description = "Source implementation for Close.com." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-close-com/source_close_com/datetime_incremental_sync.py b/airbyte-integrations/connectors/source-close-com/source_close_com/datetime_incremental_sync.py index 6ce18802ab7e..71ac5b4189ce 100644 --- a/airbyte-integrations/connectors/source-close-com/source_close_com/datetime_incremental_sync.py +++ b/airbyte-integrations/connectors/source-close-com/source_close_com/datetime_incremental_sync.py @@ -6,6 +6,7 @@ from dataclasses import dataclass import pendulum + from airbyte_cdk.sources.declarative.incremental import DatetimeBasedCursor diff --git a/airbyte-integrations/connectors/source-close-com/source_close_com/source.py b/airbyte-integrations/connectors/source-close-com/source_close_com/source.py index 2b524cb260e6..24f4a6b5f80a 100644 --- a/airbyte-integrations/connectors/source-close-com/source_close_com/source.py +++ b/airbyte-integrations/connectors/source-close-com/source_close_com/source.py @@ -10,6 +10,7 @@ from urllib.parse import parse_qsl, urlparse import requests + from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http import HttpStream diff --git a/airbyte-integrations/connectors/source-close-com/source_close_com/source_lc.py b/airbyte-integrations/connectors/source-close-com/source_close_com/source_lc.py index 4dc1b251dd97..4f45b8c93d6f 100644 --- a/airbyte-integrations/connectors/source-close-com/source_close_com/source_lc.py +++ b/airbyte-integrations/connectors/source-close-com/source_close_com/source_lc.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-cloudbeds/README.md b/airbyte-integrations/connectors/source-cloudbeds/README.md new file mode 100644 index 000000000000..95850dce43f8 --- /dev/null +++ b/airbyte-integrations/connectors/source-cloudbeds/README.md @@ -0,0 +1,39 @@ +# Cloudbeds +This directory contains the manifest-only connector for `source-cloudbeds`. + +This is Cloudbeds source that ingests data from the Cloudbeds API. + +Cloudbeds is an unified hospitality platform https://cloudbeds.com + +In order to use this source, you must first create a cloudbeds account. Once logged in, navigate to the API credentials page for your property by clicking Account > Apps & Marketplace in the upper right corner. Use the menu on the top to navigate to the API Credentials Page. Click the New Credentials button, fill in the details and click on Create. This will create an application, then click on the API Key and provide all the required scopes as needed. + +You can learn more about the API here https://hotels.cloudbeds.com/api/v1.2/docs/ + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-cloudbeds:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-cloudbeds build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-cloudbeds test +``` + diff --git a/airbyte-integrations/connectors/source-cloudbeds/acceptance-test-config.yml b/airbyte-integrations/connectors/source-cloudbeds/acceptance-test-config.yml new file mode 100644 index 000000000000..5a07e461b1e8 --- /dev/null +++ b/airbyte-integrations/connectors/source-cloudbeds/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-cloudbeds:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-cloudbeds/icon.svg b/airbyte-integrations/connectors/source-cloudbeds/icon.svg new file mode 100644 index 000000000000..f35ae0ef7cdb --- /dev/null +++ b/airbyte-integrations/connectors/source-cloudbeds/icon.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-cloudbeds/manifest.yaml b/airbyte-integrations/connectors/source-cloudbeds/manifest.yaml new file mode 100644 index 000000000000..e92303143a2c --- /dev/null +++ b/airbyte-integrations/connectors/source-cloudbeds/manifest.yaml @@ -0,0 +1,703 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + This is Cloudbeds source that ingests data from the Cloudbeds API. + + + Cloudbeds is an unified hospitality platform https://cloudbeds.com + + + In order to use this source, you must first create a cloudbeds account. Once + logged in, navigate to the API credentials page for your property by clicking + Account > Apps & Marketplace in the upper right corner. Use the menu on the + top to navigate to the API Credentials Page. Click the New Credentials button, + fill in the details and click on Create. This will create an application, then + click on the API Key and provide all the required scopes as needed. + + + You can learn more about the API here + https://hotels.cloudbeds.com/api/v1.2/docs/ + +check: + type: CheckStream + stream_names: + - guests + +definitions: + streams: + guests: + type: DeclarativeStream + name: guests + primary_key: + - guestID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: getGuestList + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageNumber + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/guests" + hotels: + type: DeclarativeStream + name: hotels + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: getHotels + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageNumber + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/hotels" + rooms: + type: DeclarativeStream + name: rooms + primary_key: + - propertyID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: getRoomBlocks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageNumber + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/rooms" + reservations: + type: DeclarativeStream + name: reservations + primary_key: + - reservationID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: getReservations + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageNumber + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/reservations" + transactions: + type: DeclarativeStream + name: transactions + primary_key: + - transactionID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: getTransactions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageNumber + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/transactions" + packages: + type: DeclarativeStream + name: packages + primary_key: + - itemID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: getItems + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageNumber + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/packages" + base_requester: + type: HttpRequester + url_base: https://api.cloudbeds.com/api/v1.2/ + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/guests" + - $ref: "#/definitions/streams/hotels" + - $ref: "#/definitions/streams/rooms" + - $ref: "#/definitions/streams/reservations" + - $ref: "#/definitions/streams/transactions" + - $ref: "#/definitions/streams/packages" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + title: API Key + airbyte_secret: true + order: 0 + additionalProperties: true + +metadata: + autoImportSchema: + guests: true + hotels: true + rooms: true + reservations: true + transactions: true + packages: true + testedStreams: + guests: + streamHash: 8c3f802465858a6249b0a34501d4cc04c681e1b5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + hotels: + streamHash: 6e6352cd896d02b30f29b21c2a21ef6d14c27dab + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + rooms: + streamHash: d1b2ac08b13a5b601839be16f3f343e4c84239c1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + reservations: + streamHash: c318b9390d7f2ac48fc3bf923e6d350ff572000d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + transactions: + streamHash: c8f35dae787999ae71131884c4fffa6dc51759fe + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + packages: + streamHash: 743c759bcb3abca3ad9c48675da1e955673d5642 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://hotels.cloudbeds.com/api/v1.2/docs/ + openapiSpecUrl: https://hotels.cloudbeds.com/api/v1.2/docs/cb-v1.2-openapi-3.0.1.yaml + +schemas: + guests: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + dateCreated: + type: + - string + - "null" + dateModified: + type: + - string + - "null" + guestEmail: + type: + - string + - "null" + guestID: + type: string + guestName: + type: + - string + - "null" + isAnonymized: + type: + - boolean + - "null" + isMainGuest: + type: + - boolean + - "null" + isMerged: + type: + - boolean + - "null" + newGuestID: + type: + - string + - "null" + propertyID: + type: + - string + - "null" + reservationID: + type: + - string + - "null" + required: + - guestID + hotels: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + organizationID: + type: + - string + - "null" + propertyCurrency: + type: + - object + - "null" + properties: + currencyCode: + type: + - string + - "null" + currencyPosition: + type: + - string + - "null" + currencySymbol: + type: + - string + - "null" + propertyDescription: + type: + - string + - "null" + propertyID: + type: + - string + - "null" + propertyImage: + type: + - string + - "null" + propertyName: + type: + - string + - "null" + propertyTimezone: + type: + - string + - "null" + rooms: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + propertyID: + type: string + roomBlocks: + type: + - array + - "null" + required: + - propertyID + reservations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + adults: + type: + - string + - "null" + balance: + type: + - number + - "null" + children: + type: + - string + - "null" + dateCreated: + type: + - string + - "null" + dateModified: + type: + - string + - "null" + endDate: + type: + - string + - "null" + guestID: + type: + - string + - "null" + guestName: + type: + - string + - "null" + origin: + type: + - string + - "null" + profileID: + type: + - string + - "null" + propertyID: + type: + - string + - "null" + reservationID: + type: string + sourceID: + type: + - string + - "null" + sourceName: + type: + - string + - "null" + startDate: + type: + - string + - "null" + status: + type: + - string + - "null" + required: + - reservationID + transactions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + amount: + type: + - number + - "null" + cardType: + type: + - string + - "null" + category: + type: + - string + - "null" + currency: + type: + - string + - "null" + guestCheckIn: + type: + - string + - "null" + guestCheckOut: + type: + - string + - "null" + guestID: + type: + - string + - "null" + guestName: + type: + - string + - "null" + isDeleted: + type: + - boolean + - "null" + itemCategoryName: + type: + - string + - "null" + notes: + type: + - string + - "null" + parentTransactionID: + type: + - string + - "null" + propertyID: + type: + - string + - "null" + propertyName: + type: + - string + - "null" + quantity: + type: + - string + - "null" + reservationID: + type: + - string + - "null" + roomName: + type: + - string + - "null" + roomTypeID: + type: + - string + - "null" + roomTypeName: + type: + - string + - "null" + subReservationID: + type: + - string + - "null" + transactionCategory: + type: + - string + - "null" + transactionCode: + type: + - string + - "null" + transactionDateTime: + type: + - string + - "null" + transactionDateTimeUTC: + type: + - string + - "null" + transactionID: + type: string + transactionModifiedDateTime: + type: + - string + - "null" + transactionModifiedDateTimeUTC: + type: + - string + - "null" + transactionType: + type: + - string + - "null" + userName: + type: + - string + - "null" + required: + - transactionID + packages: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + categoryName: + type: + - string + - "null" + fees: + type: + - array + - "null" + grandTotal: + type: + - number + - "null" + itemCode: + type: + - string + - "null" + itemID: + type: string + itemType: + type: + - string + - "null" + name: + type: + - string + - "null" + price: + type: + - number + - "null" + priceWithoutFeesAndTaxes: + type: + - number + - "null" + sku: + type: + - string + - "null" + stockInventory: + type: + - boolean + - "null" + taxes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + taxName: + type: + - string + - "null" + taxValue: + type: + - number + - "null" + totalFees: + type: + - number + - "null" + totalTaxes: + type: + - number + - "null" + required: + - itemID diff --git a/airbyte-integrations/connectors/source-cloudbeds/metadata.yaml b/airbyte-integrations/connectors/source-cloudbeds/metadata.yaml new file mode 100644 index 000000000000..69930adc6dc1 --- /dev/null +++ b/airbyte-integrations/connectors/source-cloudbeds/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.cloudbeds.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-cloudbeds + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 021d2bd7-40de-43b8-8a93-21e8b731eceb + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-cloudbeds + githubIssueLabel: source-cloudbeds + icon: icon.svg + license: MIT + name: Cloudbeds + releaseDate: 2024-10-31 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/cloudbeds + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-coassemble/metadata.yaml b/airbyte-integrations/connectors/source-coassemble/metadata.yaml index 9fb55b2b49c7..0cd01c59bf10 100644 --- a/airbyte-integrations/connectors/source-coassemble/metadata.yaml +++ b/airbyte-integrations/connectors/source-coassemble/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-coassemble connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 85999b05-fae0-4312-a3ae-f4987f50d434 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-coassemble githubIssueLabel: source-coassemble icon: icon.svg diff --git a/airbyte-integrations/connectors/source-cockroachdb/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-cockroachdb/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-cockroachdb/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-cockroachdb/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-cockroachdb/metadata.yaml b/airbyte-integrations/connectors/source-cockroachdb/metadata.yaml index cbdf081112aa..edd75eb5e56e 100644 --- a/airbyte-integrations/connectors/source-cockroachdb/metadata.yaml +++ b/airbyte-integrations/connectors/source-cockroachdb/metadata.yaml @@ -1,30 +1,32 @@ data: + ab_internal: + ql: 100 + sl: 100 allowedHosts: hosts: - ${host} + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a connectorSubtype: database + connectorTestSuitesOptions: + - suite: unitTests + - suite: integrationTests connectorType: source definitionId: 9fa5862c-da7c-11eb-8d19-0242ac130003 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.3 dockerRepository: airbyte/source-cockroachdb + documentationUrl: https://docs.airbyte.com/integrations/sources/cockroachdb githubIssueLabel: source-cockroachdb icon: cockroachdb.svg license: MIT name: Cockroachdb registryOverrides: cloud: - enabled: false # Can not be in cloud until security is handled via DEPLOYMENT_MODE=cloud. + enabled: false oss: enabled: true releaseStage: alpha - documentationUrl: https://docs.airbyte.com/integrations/sources/cockroachdb + supportLevel: community tags: - language:java - ab_internal: - sl: 100 - ql: 100 - supportLevel: community - connectorTestSuitesOptions: - - suite: unitTests - - suite: integrationTests metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-coda/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-coda/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-coda/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-coda/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-coda/metadata.yaml b/airbyte-integrations/connectors/source-coda/metadata.yaml index 35608b9c04f8..d46fbcf0ce73 100644 --- a/airbyte-integrations/connectors/source-coda/metadata.yaml +++ b/airbyte-integrations/connectors/source-coda/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - https://coda.io/ connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 27f910fd-f832-4b2e-bcfd-6ab342e434d8 - dockerImageTag: 1.3.3 + dockerImageTag: 1.3.8 dockerRepository: airbyte/source-coda documentationUrl: https://docs.airbyte.com/integrations/sources/coda githubIssueLabel: source-coda diff --git a/airbyte-integrations/connectors/source-codefresh/metadata.yaml b/airbyte-integrations/connectors/source-codefresh/metadata.yaml index b01c2731b675..6708158de00f 100644 --- a/airbyte-integrations/connectors/source-codefresh/metadata.yaml +++ b/airbyte-integrations/connectors/source-codefresh/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-codefresh connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: cd8313fe-05cb-4439-aed5-26a2adc4856c - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-codefresh githubIssueLabel: source-codefresh icon: icon.svg diff --git a/airbyte-integrations/connectors/source-coin-api/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-coin-api/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-coin-api/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-coin-api/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-coin-api/metadata.yaml b/airbyte-integrations/connectors/source-coin-api/metadata.yaml index ae243954e6e9..630da6e12802 100644 --- a/airbyte-integrations/connectors/source-coin-api/metadata.yaml +++ b/airbyte-integrations/connectors/source-coin-api/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 919984ef-53a2-479b-8ffe-9c1ddb9fc3f3 - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.5 dockerRepository: airbyte/source-coin-api documentationUrl: https://docs.airbyte.com/integrations/sources/coin-api githubIssueLabel: source-coin-api diff --git a/airbyte-integrations/connectors/source-coingecko-coins/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-coingecko-coins/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-coingecko-coins/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-coingecko-coins/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-coingecko-coins/metadata.yaml b/airbyte-integrations/connectors/source-coingecko-coins/metadata.yaml index f05504629963..e92bf8237324 100644 --- a/airbyte-integrations/connectors/source-coingecko-coins/metadata.yaml +++ b/airbyte-integrations/connectors/source-coingecko-coins/metadata.yaml @@ -2,14 +2,14 @@ data: connectorSubtype: api connectorType: source definitionId: 9cdd4183-d0ba-40c3-aad3-6f46d4103974 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.9 dockerRepository: airbyte/source-coingecko-coins githubIssueLabel: source-coingecko-coins icon: coingeckocoins.svg license: MIT name: CoinGecko Coins connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc remoteRegistries: pypi: enabled: false diff --git a/airbyte-integrations/connectors/source-coinmarketcap/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-coinmarketcap/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-coinmarketcap/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-coinmarketcap/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-commcare/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-commcare/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-commcare/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-commcare/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-commcare/main.py b/airbyte-integrations/connectors/source-commcare/main.py index edd438bde5be..fe2d48f84604 100644 --- a/airbyte-integrations/connectors/source-commcare/main.py +++ b/airbyte-integrations/connectors/source-commcare/main.py @@ -4,5 +4,6 @@ from source_commcare.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-commcare/metadata.yaml b/airbyte-integrations/connectors/source-commcare/metadata.yaml index d44c29cc4ba6..9987be1ee68c 100644 --- a/airbyte-integrations/connectors/source-commcare/metadata.yaml +++ b/airbyte-integrations/connectors/source-commcare/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: f39208dc-7e1c-48b8-919b-5006360cc27f - dockerImageTag: 0.1.22 + dockerImageTag: 0.1.26 dockerRepository: airbyte/source-commcare githubIssueLabel: source-commcare icon: commcare.svg @@ -29,5 +29,5 @@ data: connectorTestSuitesOptions: - suite: unitTests connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-commcare/poetry.lock b/airbyte-integrations/connectors/source-commcare/poetry.lock index 562b252c3b5f..21e9d2171695 100644 --- a/airbyte-integrations/connectors/source-commcare/poetry.lock +++ b/airbyte-integrations/connectors/source-commcare/poetry.lock @@ -62,19 +62,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -150,127 +150,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -286,20 +273,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -328,13 +315,13 @@ test = ["pytest (>=6)"] [[package]] name = "fastjsonschema" -version = "2.20.0" +version = "2.21.1" description = "Fastest Python implementation of JSON schema" optional = false python-versions = "*" files = [ - {file = "fastjsonschema-2.20.0-py3-none-any.whl", hash = "sha256:5875f0b0fa7a0043a91e93a9b8f793bcbbba9691e7fd83dca95c28ba26d21f0a"}, - {file = "fastjsonschema-2.20.0.tar.gz", hash = "sha256:3d48fc5300ee96f5d116f10fe6f28d938e6008f59a6a025c2649475b87f76a23"}, + {file = "fastjsonschema-2.21.1-py3-none-any.whl", hash = "sha256:c9e5b7e908310918cf494a434eeb31384dd84a98b57a30bcb1f535015b554667"}, + {file = "fastjsonschema-2.21.1.tar.gz", hash = "sha256:794d4f0a58f848961ba16af7b9c85a3e88cd360df008c59aac6fc5ae9323b5d4"}, ] [package.extras] @@ -381,13 +368,13 @@ files = [ [[package]] name = "google-api-core" -version = "2.22.0" +version = "2.24.0" description = "Google API client core library" optional = false python-versions = ">=3.7" files = [ - {file = "google_api_core-2.22.0-py3-none-any.whl", hash = "sha256:a6652b6bd51303902494998626653671703c420f6f4c88cfd3f50ed723e9d021"}, - {file = "google_api_core-2.22.0.tar.gz", hash = "sha256:26f8d76b96477db42b55fd02a33aae4a42ec8b86b98b94969b7333a2c828bf35"}, + {file = "google_api_core-2.24.0-py3-none-any.whl", hash = "sha256:10d82ac0fca69c82a25b3efdeefccf6f28e02ebb97925a8cce8edbfe379929d9"}, + {file = "google_api_core-2.24.0.tar.gz", hash = "sha256:e255640547a597a4da010876d333208ddac417d60add22b6851a0c66a831fcaf"}, ] [package.dependencies] @@ -413,13 +400,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] [[package]] name = "google-auth" -version = "2.35.0" +version = "2.37.0" description = "Google Authentication Library" optional = false python-versions = ">=3.7" files = [ - {file = "google_auth-2.35.0-py2.py3-none-any.whl", hash = "sha256:25df55f327ef021de8be50bad0dfd4a916ad0de96da86cd05661c9297723ad3f"}, - {file = "google_auth-2.35.0.tar.gz", hash = "sha256:f4c64ed4e01e8e8b646ef34c018f8bf3338df0c8e37d8b3bba40e7f574a3278a"}, + {file = "google_auth-2.37.0-py2.py3-none-any.whl", hash = "sha256:42664f18290a6be591be5329a96fe30184be1a1badb7292a7f686a9659de9ca0"}, + {file = "google_auth-2.37.0.tar.gz", hash = "sha256:0054623abf1f9c83492c63d3f47e77f0a544caa3d40b2d98e099a611c2dd5d00"}, ] [package.dependencies] @@ -430,19 +417,20 @@ rsa = ">=3.1.4,<5" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0.dev0)", "requests (>=2.20.0,<3.0.0.dev0)"] enterprise-cert = ["cryptography", "pyopenssl"] +pyjwt = ["cryptography (>=38.0.3)", "pyjwt (>=2.0)"] pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0.dev0)"] [[package]] name = "google-cloud-bigquery" -version = "3.26.0" +version = "3.27.0" description = "Google BigQuery API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google_cloud_bigquery-3.26.0-py2.py3-none-any.whl", hash = "sha256:e0e9ad28afa67a18696e624cbccab284bf2c0a3f6eeb9eeb0426c69b943793a8"}, - {file = "google_cloud_bigquery-3.26.0.tar.gz", hash = "sha256:edbdc788beea659e04c0af7fe4dcd6d9155344b98951a0d5055bd2f15da4ba23"}, + {file = "google_cloud_bigquery-3.27.0-py2.py3-none-any.whl", hash = "sha256:b53b0431e5ba362976a4cd8acce72194b4116cdf8115030c7b339b884603fcc3"}, + {file = "google_cloud_bigquery-3.27.0.tar.gz", hash = "sha256:379c524054d7b090fa56d0c22662cc6e6458a6229b6754c0e7177e3a73421d2c"}, ] [package.dependencies] @@ -542,13 +530,13 @@ requests = ["requests (>=2.18.0,<3.0.0dev)"] [[package]] name = "googleapis-common-protos" -version = "1.65.0" +version = "1.66.0" description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" files = [ - {file = "googleapis_common_protos-1.65.0-py2.py3-none-any.whl", hash = "sha256:2972e6c496f435b92590fd54045060867f3fe9be2c82ab148fc8885035479a63"}, - {file = "googleapis_common_protos-1.65.0.tar.gz", hash = "sha256:334a29d07cddc3aa01dee4988f9afd9b2916ee2ff49d6b757155dc0d197852c0"}, + {file = "googleapis_common_protos-1.66.0-py2.py3-none-any.whl", hash = "sha256:d7abcd75fabb2e0ec9f74466401f6c119a0b498e27370e9be4c94cb7e382b8ed"}, + {file = "googleapis_common_protos-1.66.0.tar.gz", hash = "sha256:c3e7b33d15fdca5374cc0a7346dd92ffa847425cc4ea941d970f13680052ec8c"}, ] [package.dependencies] @@ -559,85 +547,85 @@ grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] [[package]] name = "grpcio" -version = "1.67.1" +version = "1.68.1" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.8" files = [ - {file = "grpcio-1.67.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:8b0341d66a57f8a3119b77ab32207072be60c9bf79760fa609c5609f2deb1f3f"}, - {file = "grpcio-1.67.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:f5a27dddefe0e2357d3e617b9079b4bfdc91341a91565111a21ed6ebbc51b22d"}, - {file = "grpcio-1.67.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:43112046864317498a33bdc4797ae6a268c36345a910de9b9c17159d8346602f"}, - {file = "grpcio-1.67.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9b929f13677b10f63124c1a410994a401cdd85214ad83ab67cc077fc7e480f0"}, - {file = "grpcio-1.67.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7d1797a8a3845437d327145959a2c0c47c05947c9eef5ff1a4c80e499dcc6fa"}, - {file = "grpcio-1.67.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0489063974d1452436139501bf6b180f63d4977223ee87488fe36858c5725292"}, - {file = "grpcio-1.67.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9fd042de4a82e3e7aca44008ee2fb5da01b3e5adb316348c21980f7f58adc311"}, - {file = "grpcio-1.67.1-cp310-cp310-win32.whl", hash = "sha256:638354e698fd0c6c76b04540a850bf1db27b4d2515a19fcd5cf645c48d3eb1ed"}, - {file = "grpcio-1.67.1-cp310-cp310-win_amd64.whl", hash = "sha256:608d87d1bdabf9e2868b12338cd38a79969eaf920c89d698ead08f48de9c0f9e"}, - {file = "grpcio-1.67.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:7818c0454027ae3384235a65210bbf5464bd715450e30a3d40385453a85a70cb"}, - {file = "grpcio-1.67.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ea33986b70f83844cd00814cee4451055cd8cab36f00ac64a31f5bb09b31919e"}, - {file = "grpcio-1.67.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:c7a01337407dd89005527623a4a72c5c8e2894d22bead0895306b23c6695698f"}, - {file = "grpcio-1.67.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80b866f73224b0634f4312a4674c1be21b2b4afa73cb20953cbbb73a6b36c3cc"}, - {file = "grpcio-1.67.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9fff78ba10d4250bfc07a01bd6254a6d87dc67f9627adece85c0b2ed754fa96"}, - {file = "grpcio-1.67.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8a23cbcc5bb11ea7dc6163078be36c065db68d915c24f5faa4f872c573bb400f"}, - {file = "grpcio-1.67.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1a65b503d008f066e994f34f456e0647e5ceb34cfcec5ad180b1b44020ad4970"}, - {file = "grpcio-1.67.1-cp311-cp311-win32.whl", hash = "sha256:e29ca27bec8e163dca0c98084040edec3bc49afd10f18b412f483cc68c712744"}, - {file = "grpcio-1.67.1-cp311-cp311-win_amd64.whl", hash = "sha256:786a5b18544622bfb1e25cc08402bd44ea83edfb04b93798d85dca4d1a0b5be5"}, - {file = "grpcio-1.67.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:267d1745894200e4c604958da5f856da6293f063327cb049a51fe67348e4f953"}, - {file = "grpcio-1.67.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:85f69fdc1d28ce7cff8de3f9c67db2b0ca9ba4449644488c1e0303c146135ddb"}, - {file = "grpcio-1.67.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:f26b0b547eb8d00e195274cdfc63ce64c8fc2d3e2d00b12bf468ece41a0423a0"}, - {file = "grpcio-1.67.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4422581cdc628f77302270ff839a44f4c24fdc57887dc2a45b7e53d8fc2376af"}, - {file = "grpcio-1.67.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d7616d2ded471231c701489190379e0c311ee0a6c756f3c03e6a62b95a7146e"}, - {file = "grpcio-1.67.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8a00efecde9d6fcc3ab00c13f816313c040a28450e5e25739c24f432fc6d3c75"}, - {file = "grpcio-1.67.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:699e964923b70f3101393710793289e42845791ea07565654ada0969522d0a38"}, - {file = "grpcio-1.67.1-cp312-cp312-win32.whl", hash = "sha256:4e7b904484a634a0fff132958dabdb10d63e0927398273917da3ee103e8d1f78"}, - {file = "grpcio-1.67.1-cp312-cp312-win_amd64.whl", hash = "sha256:5721e66a594a6c4204458004852719b38f3d5522082be9061d6510b455c90afc"}, - {file = "grpcio-1.67.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:aa0162e56fd10a5547fac8774c4899fc3e18c1aa4a4759d0ce2cd00d3696ea6b"}, - {file = "grpcio-1.67.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:beee96c8c0b1a75d556fe57b92b58b4347c77a65781ee2ac749d550f2a365dc1"}, - {file = "grpcio-1.67.1-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:a93deda571a1bf94ec1f6fcda2872dad3ae538700d94dc283c672a3b508ba3af"}, - {file = "grpcio-1.67.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e6f255980afef598a9e64a24efce87b625e3e3c80a45162d111a461a9f92955"}, - {file = "grpcio-1.67.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e838cad2176ebd5d4a8bb03955138d6589ce9e2ce5d51c3ada34396dbd2dba8"}, - {file = "grpcio-1.67.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:a6703916c43b1d468d0756c8077b12017a9fcb6a1ef13faf49e67d20d7ebda62"}, - {file = "grpcio-1.67.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:917e8d8994eed1d86b907ba2a61b9f0aef27a2155bca6cbb322430fc7135b7bb"}, - {file = "grpcio-1.67.1-cp313-cp313-win32.whl", hash = "sha256:e279330bef1744040db8fc432becc8a727b84f456ab62b744d3fdb83f327e121"}, - {file = "grpcio-1.67.1-cp313-cp313-win_amd64.whl", hash = "sha256:fa0c739ad8b1996bd24823950e3cb5152ae91fca1c09cc791190bf1627ffefba"}, - {file = "grpcio-1.67.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:178f5db771c4f9a9facb2ab37a434c46cb9be1a75e820f187ee3d1e7805c4f65"}, - {file = "grpcio-1.67.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0f3e49c738396e93b7ba9016e153eb09e0778e776df6090c1b8c91877cc1c426"}, - {file = "grpcio-1.67.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:24e8a26dbfc5274d7474c27759b54486b8de23c709d76695237515bc8b5baeab"}, - {file = "grpcio-1.67.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b6c16489326d79ead41689c4b84bc40d522c9a7617219f4ad94bc7f448c5085"}, - {file = "grpcio-1.67.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60e6a4dcf5af7bbc36fd9f81c9f372e8ae580870a9e4b6eafe948cd334b81cf3"}, - {file = "grpcio-1.67.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:95b5f2b857856ed78d72da93cd7d09b6db8ef30102e5e7fe0961fe4d9f7d48e8"}, - {file = "grpcio-1.67.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b49359977c6ec9f5d0573ea4e0071ad278ef905aa74e420acc73fd28ce39e9ce"}, - {file = "grpcio-1.67.1-cp38-cp38-win32.whl", hash = "sha256:f5b76ff64aaac53fede0cc93abf57894ab2a7362986ba22243d06218b93efe46"}, - {file = "grpcio-1.67.1-cp38-cp38-win_amd64.whl", hash = "sha256:804c6457c3cd3ec04fe6006c739579b8d35c86ae3298ffca8de57b493524b771"}, - {file = "grpcio-1.67.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:a25bdea92b13ff4d7790962190bf6bf5c4639876e01c0f3dda70fc2769616335"}, - {file = "grpcio-1.67.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cdc491ae35a13535fd9196acb5afe1af37c8237df2e54427be3eecda3653127e"}, - {file = "grpcio-1.67.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:85f862069b86a305497e74d0dc43c02de3d1d184fc2c180993aa8aa86fbd19b8"}, - {file = "grpcio-1.67.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec74ef02010186185de82cc594058a3ccd8d86821842bbac9873fd4a2cf8be8d"}, - {file = "grpcio-1.67.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01f616a964e540638af5130469451cf580ba8c7329f45ca998ab66e0c7dcdb04"}, - {file = "grpcio-1.67.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:299b3d8c4f790c6bcca485f9963b4846dd92cf6f1b65d3697145d005c80f9fe8"}, - {file = "grpcio-1.67.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:60336bff760fbb47d7e86165408126f1dded184448e9a4c892189eb7c9d3f90f"}, - {file = "grpcio-1.67.1-cp39-cp39-win32.whl", hash = "sha256:5ed601c4c6008429e3d247ddb367fe8c7259c355757448d7c1ef7bd4a6739e8e"}, - {file = "grpcio-1.67.1-cp39-cp39-win_amd64.whl", hash = "sha256:5db70d32d6703b89912af16d6d45d78406374a8b8ef0d28140351dd0ec610e98"}, - {file = "grpcio-1.67.1.tar.gz", hash = "sha256:3dc2ed4cabea4dc14d5e708c2b426205956077cc5de419b4d4079315017e9732"}, + {file = "grpcio-1.68.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:d35740e3f45f60f3c37b1e6f2f4702c23867b9ce21c6410254c9c682237da68d"}, + {file = "grpcio-1.68.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:d99abcd61760ebb34bdff37e5a3ba333c5cc09feda8c1ad42547bea0416ada78"}, + {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:f8261fa2a5f679abeb2a0a93ad056d765cdca1c47745eda3f2d87f874ff4b8c9"}, + {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0feb02205a27caca128627bd1df4ee7212db051019a9afa76f4bb6a1a80ca95e"}, + {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:919d7f18f63bcad3a0f81146188e90274fde800a94e35d42ffe9eadf6a9a6330"}, + {file = "grpcio-1.68.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:963cc8d7d79b12c56008aabd8b457f400952dbea8997dd185f155e2f228db079"}, + {file = "grpcio-1.68.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ccf2ebd2de2d6661e2520dae293298a3803a98ebfc099275f113ce1f6c2a80f1"}, + {file = "grpcio-1.68.1-cp310-cp310-win32.whl", hash = "sha256:2cc1fd04af8399971bcd4f43bd98c22d01029ea2e56e69c34daf2bf8470e47f5"}, + {file = "grpcio-1.68.1-cp310-cp310-win_amd64.whl", hash = "sha256:ee2e743e51cb964b4975de572aa8fb95b633f496f9fcb5e257893df3be854746"}, + {file = "grpcio-1.68.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:55857c71641064f01ff0541a1776bfe04a59db5558e82897d35a7793e525774c"}, + {file = "grpcio-1.68.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4b177f5547f1b995826ef529d2eef89cca2f830dd8b2c99ffd5fde4da734ba73"}, + {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:3522c77d7e6606d6665ec8d50e867f13f946a4e00c7df46768f1c85089eae515"}, + {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d1fae6bbf0816415b81db1e82fb3bf56f7857273c84dcbe68cbe046e58e1ccd"}, + {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:298ee7f80e26f9483f0b6f94cc0a046caf54400a11b644713bb5b3d8eb387600"}, + {file = "grpcio-1.68.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cbb5780e2e740b6b4f2d208e90453591036ff80c02cc605fea1af8e6fc6b1bbe"}, + {file = "grpcio-1.68.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ddda1aa22495d8acd9dfbafff2866438d12faec4d024ebc2e656784d96328ad0"}, + {file = "grpcio-1.68.1-cp311-cp311-win32.whl", hash = "sha256:b33bd114fa5a83f03ec6b7b262ef9f5cac549d4126f1dc702078767b10c46ed9"}, + {file = "grpcio-1.68.1-cp311-cp311-win_amd64.whl", hash = "sha256:7f20ebec257af55694d8f993e162ddf0d36bd82d4e57f74b31c67b3c6d63d8b2"}, + {file = "grpcio-1.68.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:8829924fffb25386995a31998ccbbeaa7367223e647e0122043dfc485a87c666"}, + {file = "grpcio-1.68.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3aed6544e4d523cd6b3119b0916cef3d15ef2da51e088211e4d1eb91a6c7f4f1"}, + {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:4efac5481c696d5cb124ff1c119a78bddbfdd13fc499e3bc0ca81e95fc573684"}, + {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ab2d912ca39c51f46baf2a0d92aa265aa96b2443266fc50d234fa88bf877d8e"}, + {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c87ce2a97434dffe7327a4071839ab8e8bffd0054cc74cbe971fba98aedd60"}, + {file = "grpcio-1.68.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e4842e4872ae4ae0f5497bf60a0498fa778c192cc7a9e87877abd2814aca9475"}, + {file = "grpcio-1.68.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:255b1635b0ed81e9f91da4fcc8d43b7ea5520090b9a9ad9340d147066d1d3613"}, + {file = "grpcio-1.68.1-cp312-cp312-win32.whl", hash = "sha256:7dfc914cc31c906297b30463dde0b9be48e36939575eaf2a0a22a8096e69afe5"}, + {file = "grpcio-1.68.1-cp312-cp312-win_amd64.whl", hash = "sha256:a0c8ddabef9c8f41617f213e527254c41e8b96ea9d387c632af878d05db9229c"}, + {file = "grpcio-1.68.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:a47faedc9ea2e7a3b6569795c040aae5895a19dde0c728a48d3c5d7995fda385"}, + {file = "grpcio-1.68.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:390eee4225a661c5cd133c09f5da1ee3c84498dc265fd292a6912b65c421c78c"}, + {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:66a24f3d45c33550703f0abb8b656515b0ab777970fa275693a2f6dc8e35f1c1"}, + {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c08079b4934b0bf0a8847f42c197b1d12cba6495a3d43febd7e99ecd1cdc8d54"}, + {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8720c25cd9ac25dd04ee02b69256d0ce35bf8a0f29e20577427355272230965a"}, + {file = "grpcio-1.68.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:04cfd68bf4f38f5bb959ee2361a7546916bd9a50f78617a346b3aeb2b42e2161"}, + {file = "grpcio-1.68.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c28848761a6520c5c6071d2904a18d339a796ebe6b800adc8b3f474c5ce3c3ad"}, + {file = "grpcio-1.68.1-cp313-cp313-win32.whl", hash = "sha256:77d65165fc35cff6e954e7fd4229e05ec76102d4406d4576528d3a3635fc6172"}, + {file = "grpcio-1.68.1-cp313-cp313-win_amd64.whl", hash = "sha256:a8040f85dcb9830d8bbb033ae66d272614cec6faceee88d37a88a9bd1a7a704e"}, + {file = "grpcio-1.68.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:eeb38ff04ab6e5756a2aef6ad8d94e89bb4a51ef96e20f45c44ba190fa0bcaad"}, + {file = "grpcio-1.68.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8a3869a6661ec8f81d93f4597da50336718bde9eb13267a699ac7e0a1d6d0bea"}, + {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:2c4cec6177bf325eb6faa6bd834d2ff6aa8bb3b29012cceb4937b86f8b74323c"}, + {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12941d533f3cd45d46f202e3667be8ebf6bcb3573629c7ec12c3e211d99cfccf"}, + {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80af6f1e69c5e68a2be529990684abdd31ed6622e988bf18850075c81bb1ad6e"}, + {file = "grpcio-1.68.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e8dbe3e00771bfe3d04feed8210fc6617006d06d9a2679b74605b9fed3e8362c"}, + {file = "grpcio-1.68.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:83bbf5807dc3ee94ce1de2dfe8a356e1d74101e4b9d7aa8c720cc4818a34aded"}, + {file = "grpcio-1.68.1-cp38-cp38-win32.whl", hash = "sha256:8cb620037a2fd9eeee97b4531880e439ebfcd6d7d78f2e7dcc3726428ab5ef63"}, + {file = "grpcio-1.68.1-cp38-cp38-win_amd64.whl", hash = "sha256:52fbf85aa71263380d330f4fce9f013c0798242e31ede05fcee7fbe40ccfc20d"}, + {file = "grpcio-1.68.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:cb400138e73969eb5e0535d1d06cae6a6f7a15f2cc74add320e2130b8179211a"}, + {file = "grpcio-1.68.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a1b988b40f2fd9de5c820f3a701a43339d8dcf2cb2f1ca137e2c02671cc83ac1"}, + {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:96f473cdacfdd506008a5d7579c9f6a7ff245a9ade92c3c0265eb76cc591914f"}, + {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:37ea3be171f3cf3e7b7e412a98b77685eba9d4fd67421f4a34686a63a65d99f9"}, + {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ceb56c4285754e33bb3c2fa777d055e96e6932351a3082ce3559be47f8024f0"}, + {file = "grpcio-1.68.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:dffd29a2961f3263a16d73945b57cd44a8fd0b235740cb14056f0612329b345e"}, + {file = "grpcio-1.68.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:025f790c056815b3bf53da850dd70ebb849fd755a4b1ac822cb65cd631e37d43"}, + {file = "grpcio-1.68.1-cp39-cp39-win32.whl", hash = "sha256:1098f03dedc3b9810810568060dea4ac0822b4062f537b0f53aa015269be0a76"}, + {file = "grpcio-1.68.1-cp39-cp39-win_amd64.whl", hash = "sha256:334ab917792904245a028f10e803fcd5b6f36a7b2173a820c0b5b076555825e1"}, + {file = "grpcio-1.68.1.tar.gz", hash = "sha256:44a8502dd5de653ae6a73e2de50a401d84184f0331d0ac3daeb044e66d5c5054"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.67.1)"] +protobuf = ["grpcio-tools (>=1.68.1)"] [[package]] name = "grpcio-status" -version = "1.67.1" +version = "1.68.1" description = "Status proto mapping for gRPC" optional = false python-versions = ">=3.8" files = [ - {file = "grpcio_status-1.67.1-py3-none-any.whl", hash = "sha256:16e6c085950bdacac97c779e6a502ea671232385e6e37f258884d6883392c2bd"}, - {file = "grpcio_status-1.67.1.tar.gz", hash = "sha256:2bf38395e028ceeecfd8866b081f61628114b384da7d51ae064ddc8d766a5d11"}, + {file = "grpcio_status-1.68.1-py3-none-any.whl", hash = "sha256:66f3d8847f665acfd56221333d66f7ad8927903d87242a482996bdb45e8d28fd"}, + {file = "grpcio_status-1.68.1.tar.gz", hash = "sha256:e1378d036c81a1610d7b4c7a146cd663dd13fcc915cf4d7d053929dba5bbb6e1"}, ] [package.dependencies] googleapis-common-protos = ">=1.5.5" -grpcio = ">=1.67.1" +grpcio = ">=1.68.1" protobuf = ">=5.26.1,<6.0dev" [[package]] @@ -681,13 +669,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -800,13 +788,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -893,22 +881,22 @@ testing = ["google-api-core (>=1.31.5)"] [[package]] name = "protobuf" -version = "5.28.3" +version = "5.29.2" description = "" optional = false python-versions = ">=3.8" files = [ - {file = "protobuf-5.28.3-cp310-abi3-win32.whl", hash = "sha256:0c4eec6f987338617072592b97943fdbe30d019c56126493111cf24344c1cc24"}, - {file = "protobuf-5.28.3-cp310-abi3-win_amd64.whl", hash = "sha256:91fba8f445723fcf400fdbe9ca796b19d3b1242cd873907979b9ed71e4afe868"}, - {file = "protobuf-5.28.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a3f6857551e53ce35e60b403b8a27b0295f7d6eb63d10484f12bc6879c715687"}, - {file = "protobuf-5.28.3-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:3fa2de6b8b29d12c61911505d893afe7320ce7ccba4df913e2971461fa36d584"}, - {file = "protobuf-5.28.3-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:712319fbdddb46f21abb66cd33cb9e491a5763b2febd8f228251add221981135"}, - {file = "protobuf-5.28.3-cp38-cp38-win32.whl", hash = "sha256:3e6101d095dfd119513cde7259aa703d16c6bbdfae2554dfe5cfdbe94e32d548"}, - {file = "protobuf-5.28.3-cp38-cp38-win_amd64.whl", hash = "sha256:27b246b3723692bf1068d5734ddaf2fccc2cdd6e0c9b47fe099244d80200593b"}, - {file = "protobuf-5.28.3-cp39-cp39-win32.whl", hash = "sha256:135658402f71bbd49500322c0f736145731b16fc79dc8f367ab544a17eab4535"}, - {file = "protobuf-5.28.3-cp39-cp39-win_amd64.whl", hash = "sha256:70585a70fc2dd4818c51287ceef5bdba6387f88a578c86d47bb34669b5552c36"}, - {file = "protobuf-5.28.3-py3-none-any.whl", hash = "sha256:cee1757663fa32a1ee673434fcf3bf24dd54763c79690201208bafec62f19eed"}, - {file = "protobuf-5.28.3.tar.gz", hash = "sha256:64badbc49180a5e401f373f9ce7ab1d18b63f7dd4a9cdc43c92b9f0b481cef7b"}, + {file = "protobuf-5.29.2-cp310-abi3-win32.whl", hash = "sha256:c12ba8249f5624300cf51c3d0bfe5be71a60c63e4dcf51ffe9a68771d958c851"}, + {file = "protobuf-5.29.2-cp310-abi3-win_amd64.whl", hash = "sha256:842de6d9241134a973aab719ab42b008a18a90f9f07f06ba480df268f86432f9"}, + {file = "protobuf-5.29.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a0c53d78383c851bfa97eb42e3703aefdc96d2036a41482ffd55dc5f529466eb"}, + {file = "protobuf-5.29.2-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:494229ecd8c9009dd71eda5fd57528395d1eacdf307dbece6c12ad0dd09e912e"}, + {file = "protobuf-5.29.2-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:b6b0d416bbbb9d4fbf9d0561dbfc4e324fd522f61f7af0fe0f282ab67b22477e"}, + {file = "protobuf-5.29.2-cp38-cp38-win32.whl", hash = "sha256:e621a98c0201a7c8afe89d9646859859be97cb22b8bf1d8eacfd90d5bda2eb19"}, + {file = "protobuf-5.29.2-cp38-cp38-win_amd64.whl", hash = "sha256:13d6d617a2a9e0e82a88113d7191a1baa1e42c2cc6f5f1398d3b054c8e7e714a"}, + {file = "protobuf-5.29.2-cp39-cp39-win32.whl", hash = "sha256:36000f97ea1e76e8398a3f02936aac2a5d2b111aae9920ec1b769fc4a222c4d9"}, + {file = "protobuf-5.29.2-cp39-cp39-win_amd64.whl", hash = "sha256:2d2e674c58a06311c8e99e74be43e7f3a8d1e2b2fdf845eaa347fbd866f23355"}, + {file = "protobuf-5.29.2-py3-none-any.whl", hash = "sha256:fde4554c0e578a5a0bcc9a276339594848d1e89f9ea47b4427c80e5d72f90181"}, + {file = "protobuf-5.29.2.tar.gz", hash = "sha256:b2cc8e8bb7c9326996f0e160137b0861f1a82162502658df2951209d0cb0309e"}, ] [[package]] @@ -949,54 +937,54 @@ pyasn1 = ">=0.4.6,<0.7.0" [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -1274,33 +1262,33 @@ pyasn1 = ">=0.1.3" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1341,13 +1329,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1372,81 +1360,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-commcare/pyproject.toml b/airbyte-integrations/connectors/source-commcare/pyproject.toml index 2a865cbf2ad9..68229e72b691 100644 --- a/airbyte-integrations/connectors/source-commcare/pyproject.toml +++ b/airbyte-integrations/connectors/source-commcare/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.22" +version = "0.1.26" name = "source-commcare" description = "Source implementation for Commcare." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-commcare/source_commcare/source.py b/airbyte-integrations/connectors/source-commcare/source_commcare/source.py index a6f3a7bc3a6f..6ee0e04d4463 100644 --- a/airbyte-integrations/connectors/source-commcare/source_commcare/source.py +++ b/airbyte-integrations/connectors/source-commcare/source_commcare/source.py @@ -9,12 +9,13 @@ from urllib.parse import parse_qs import requests +from flatten_json import flatten + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import IncrementalMixin, Stream from airbyte_cdk.sources.streams.http import HttpStream from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator -from flatten_json import flatten # Basic full refresh stream @@ -56,7 +57,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def request_params( self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, any] = None, next_page_token: Mapping[str, Any] = None ) -> MutableMapping[str, Any]: - params = {"format": "json"} return params @@ -79,7 +79,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def request_params( self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, any] = None, next_page_token: Mapping[str, Any] = None ) -> MutableMapping[str, Any]: - params = {"format": "json", "extras": "true"} return params @@ -123,7 +122,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def request_params( self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, any] = None, next_page_token: Mapping[str, Any] = None ) -> MutableMapping[str, Any]: - params = {"format": "json"} if next_page_token: params.update(next_page_token) @@ -136,7 +134,6 @@ def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapp class Case(IncrementalStream): - """ docs: https://www.commcarehq.org/a/[domain]/api/[version]/case/ """ @@ -167,7 +164,6 @@ def path( def request_params( self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, any] = None, next_page_token: Mapping[str, Any] = None ) -> MutableMapping[str, Any]: - # start date is what we saved for forms # if self.cursor_field in self.state else (CommcareStream.last_form_date or self.initial_date) ix = self.state[self.cursor_field] @@ -234,7 +230,6 @@ def path( def request_params( self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, any] = None, next_page_token: Mapping[str, Any] = None ) -> MutableMapping[str, Any]: - # if self.cursor_field in self.state else self.initial_date ix = self.state[self.cursor_field] params = { diff --git a/airbyte-integrations/connectors/source-commercetools/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-commercetools/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-commercetools/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-commercetools/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-commercetools/main.py b/airbyte-integrations/connectors/source-commercetools/main.py index 44dd2fb8f952..5d986dfc5e60 100644 --- a/airbyte-integrations/connectors/source-commercetools/main.py +++ b/airbyte-integrations/connectors/source-commercetools/main.py @@ -4,5 +4,6 @@ from source_commercetools.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-commercetools/metadata.yaml b/airbyte-integrations/connectors/source-commercetools/metadata.yaml index 6a547e186f70..664392a674e4 100644 --- a/airbyte-integrations/connectors/source-commercetools/metadata.yaml +++ b/airbyte-integrations/connectors/source-commercetools/metadata.yaml @@ -15,7 +15,7 @@ data: connectorSubtype: api connectorType: source definitionId: 008b2e26-11a3-11ec-82a8-0242ac130003 - dockerImageTag: 0.2.22 + dockerImageTag: 0.2.27 dockerRepository: airbyte/source-commercetools githubIssueLabel: source-commercetools icon: commercetools.svg @@ -42,5 +42,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-commercetools/poetry.lock b/airbyte-integrations/connectors/source-commercetools/poetry.lock index c2268c5899fb..67d96c050603 100644 --- a/airbyte-integrations/connectors/source-commercetools/poetry.lock +++ b/airbyte-integrations/connectors/source-commercetools/poetry.lock @@ -42,13 +42,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] @@ -56,24 +56,24 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -88,19 +88,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -166,13 +166,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -256,116 +256,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -435,20 +422,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -498,13 +485,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -519,13 +506,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -533,7 +520,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -583,13 +569,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -679,22 +665,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -767,69 +756,86 @@ files = [ [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -932,54 +938,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -991,13 +997,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1285,33 +1291,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1378,13 +1384,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1409,81 +1415,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-commercetools/pyproject.toml b/airbyte-integrations/connectors/source-commercetools/pyproject.toml index 51279f3a853d..fd064e413a2c 100644 --- a/airbyte-integrations/connectors/source-commercetools/pyproject.toml +++ b/airbyte-integrations/connectors/source-commercetools/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.2.22" +version = "0.2.27" name = "source-commercetools" description = "Source implementation for Commercetools." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-commercetools/source_commercetools/components.py b/airbyte-integrations/connectors/source-commercetools/source_commercetools/components.py index f39ab7dd6f28..403963f6d594 100644 --- a/airbyte-integrations/connectors/source-commercetools/source_commercetools/components.py +++ b/airbyte-integrations/connectors/source-commercetools/source_commercetools/components.py @@ -7,9 +7,11 @@ import backoff import requests + from airbyte_cdk.sources.declarative.auth import DeclarativeOauth2Authenticator from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-commercetools/source_commercetools/run.py b/airbyte-integrations/connectors/source-commercetools/source_commercetools/run.py index 0d264787f978..0b5f63721a93 100644 --- a/airbyte-integrations/connectors/source-commercetools/source_commercetools/run.py +++ b/airbyte-integrations/connectors/source-commercetools/source_commercetools/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_commercetools import SourceCommercetools +from airbyte_cdk.entrypoint import launch + def run(): source = SourceCommercetools() diff --git a/airbyte-integrations/connectors/source-commercetools/source_commercetools/source.py b/airbyte-integrations/connectors/source-commercetools/source_commercetools/source.py index cdcca15f5522..b36bc81e6d50 100644 --- a/airbyte-integrations/connectors/source-commercetools/source_commercetools/source.py +++ b/airbyte-integrations/connectors/source-commercetools/source_commercetools/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-concord/metadata.yaml b/airbyte-integrations/connectors/source-concord/metadata.yaml index 2f1ba9ddb465..131c93145c4d 100644 --- a/airbyte-integrations/connectors/source-concord/metadata.yaml +++ b/airbyte-integrations/connectors/source-concord/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-concord connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: dc50b4e6-862e-4b49-8ed7-3c988f4b1db0 - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-concord githubIssueLabel: source-concord icon: icon.svg diff --git a/airbyte-integrations/connectors/source-configcat/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-configcat/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-configcat/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-configcat/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-configcat/metadata.yaml b/airbyte-integrations/connectors/source-configcat/metadata.yaml index 93930bceff0f..81f61f0ea367 100644 --- a/airbyte-integrations/connectors/source-configcat/metadata.yaml +++ b/airbyte-integrations/connectors/source-configcat/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 4fd7565c-8b99-439b-80d0-2d965e1d958c - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-configcat githubIssueLabel: source-configcat icon: configcat.svg @@ -39,5 +39,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-confluence/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-confluence/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-confluence/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-confluence/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-confluence/metadata.yaml b/airbyte-integrations/connectors/source-confluence/metadata.yaml index 26064d2f10a5..b4cbad5fe032 100644 --- a/airbyte-integrations/connectors/source-confluence/metadata.yaml +++ b/airbyte-integrations/connectors/source-confluence/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - ${subdomain}.atlassian.net connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: cf40a7f8-71f8-45ce-a7fa-fca053e4028c - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.5 dockerRepository: airbyte/source-confluence documentationUrl: https://docs.airbyte.com/integrations/sources/confluence githubIssueLabel: source-confluence diff --git a/airbyte-integrations/connectors/source-convertkit/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-convertkit/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-convertkit/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-convertkit/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-convertkit/metadata.yaml b/airbyte-integrations/connectors/source-convertkit/metadata.yaml index d04a39bbd6e3..27dde77500f8 100644 --- a/airbyte-integrations/connectors/source-convertkit/metadata.yaml +++ b/airbyte-integrations/connectors/source-convertkit/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: be9ee02f-6efe-4970-979b-95f797a37188 - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.8 dockerRepository: airbyte/source-convertkit githubIssueLabel: source-convertkit icon: convertkit.svg @@ -39,5 +39,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-convex/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-convex/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-convex/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-convex/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-convex/main.py b/airbyte-integrations/connectors/source-convex/main.py index 751ae667fae2..c407ac73f395 100644 --- a/airbyte-integrations/connectors/source-convex/main.py +++ b/airbyte-integrations/connectors/source-convex/main.py @@ -4,5 +4,6 @@ from source_convex.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-convex/metadata.yaml b/airbyte-integrations/connectors/source-convex/metadata.yaml index cb75f9cfdf04..3f0231d02a6c 100644 --- a/airbyte-integrations/connectors/source-convex/metadata.yaml +++ b/airbyte-integrations/connectors/source-convex/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: c332628c-f55c-4017-8222-378cfafda9b2 - dockerImageTag: 0.4.21 + dockerImageTag: 0.4.25 dockerRepository: airbyte/source-convex githubIssueLabel: source-convex icon: convex.svg @@ -40,5 +40,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-convex/poetry.lock b/airbyte-integrations/connectors/source-convex/poetry.lock index ea20f620623c..1925a3969e0f 100644 --- a/airbyte-integrations/connectors/source-convex/poetry.lock +++ b/airbyte-integrations/connectors/source-convex/poetry.lock @@ -62,19 +62,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -140,127 +140,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -276,20 +263,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -367,13 +354,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -486,13 +473,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -573,54 +560,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -903,33 +890,33 @@ tests = ["coverage (>=3.7.1,<6.0.0)", "flake8", "mypy", "pytest (>=4.6)", "pytes [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -970,13 +957,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1001,81 +988,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-convex/pyproject.toml b/airbyte-integrations/connectors/source-convex/pyproject.toml index e3ca61ec4c6a..510ecb1d0459 100644 --- a/airbyte-integrations/connectors/source-convex/pyproject.toml +++ b/airbyte-integrations/connectors/source-convex/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.4.21" +version = "0.4.25" name = "source-convex" description = "Source implementation for Convex." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-convex/source_convex/source.py b/airbyte-integrations/connectors/source-convex/source_convex/source.py index 664f5bf3ca16..3b12ca62656f 100644 --- a/airbyte-integrations/connectors/source-convex/source_convex/source.py +++ b/airbyte-integrations/connectors/source-convex/source_convex/source.py @@ -8,12 +8,14 @@ from typing import Any, Dict, Iterable, Iterator, List, Mapping, MutableMapping, Optional, Tuple, TypedDict, cast import requests + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import IncrementalMixin, Stream from airbyte_cdk.sources.streams.http import HttpStream from airbyte_cdk.sources.streams.http.requests_native_auth.token import TokenAuthenticator + ConvexConfig = TypedDict( "ConvexConfig", { diff --git a/airbyte-integrations/connectors/source-convex/unit_tests/test_incremental_streams.py b/airbyte-integrations/connectors/source-convex/unit_tests/test_incremental_streams.py index c1006b9f6167..a8416bcaca7e 100644 --- a/airbyte-integrations/connectors/source-convex/unit_tests/test_incremental_streams.py +++ b/airbyte-integrations/connectors/source-convex/unit_tests/test_incremental_streams.py @@ -5,10 +5,11 @@ from unittest.mock import MagicMock -from airbyte_cdk.models import SyncMode from pytest import fixture from source_convex.source import ConvexStream +from airbyte_cdk.models import SyncMode + @fixture def patch_incremental_base_class(mocker): diff --git a/airbyte-integrations/connectors/source-convex/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-convex/unit_tests/test_streams.py index 17512d01cf07..7fc5a7a0158f 100644 --- a/airbyte-integrations/connectors/source-convex/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-convex/unit_tests/test_streams.py @@ -8,9 +8,10 @@ import pytest import requests import responses -from airbyte_cdk.models import SyncMode from source_convex.source import ConvexStream +from airbyte_cdk.models import SyncMode + @pytest.fixture def patch_base_class(mocker): diff --git a/airbyte-integrations/connectors/source-copper/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-copper/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-copper/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-copper/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-copper/metadata.yaml b/airbyte-integrations/connectors/source-copper/metadata.yaml index ee6f899aab3d..95c752393355 100644 --- a/airbyte-integrations/connectors/source-copper/metadata.yaml +++ b/airbyte-integrations/connectors/source-copper/metadata.yaml @@ -3,11 +3,11 @@ data: hosts: - https://api.copper.com/ connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.1.0@sha256:3ac88000d74db5f9d8dcb004299b917a5dff5cbbc19ebccd49288266095547ca connectorSubtype: api connectorType: source definitionId: 44f3002f-2df9-4f6d-b21c-02cd3b47d0dc - dockerImageTag: 0.4.2 + dockerImageTag: 0.4.3 dockerRepository: airbyte/source-copper documentationUrl: https://docs.airbyte.com/integrations/sources/copper githubIssueLabel: source-copper diff --git a/airbyte-integrations/connectors/source-countercyclical/metadata.yaml b/airbyte-integrations/connectors/source-countercyclical/metadata.yaml index 9807c68fa5aa..94ab307cf726 100644 --- a/airbyte-integrations/connectors/source-countercyclical/metadata.yaml +++ b/airbyte-integrations/connectors/source-countercyclical/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-countercyclical connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: cd671e85-accc-4f85-8f79-b55294e95a11 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-countercyclical githubIssueLabel: source-countercyclical icon: icon.svg diff --git a/airbyte-integrations/connectors/source-customer-io/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-customer-io/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-customer-io/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-customer-io/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-customer-io/metadata.yaml b/airbyte-integrations/connectors/source-customer-io/metadata.yaml index 2a91487f4bd3..2f05883ee833 100644 --- a/airbyte-integrations/connectors/source-customer-io/metadata.yaml +++ b/airbyte-integrations/connectors/source-customer-io/metadata.yaml @@ -15,11 +15,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 34f697bc-b989-4eda-b06f-d0f39b88825b - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.7 dockerRepository: airbyte/source-customer-io githubIssueLabel: source-customer-io icon: customer-io.svg diff --git a/airbyte-integrations/connectors/source-datadog/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-datadog/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-datadog/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-datadog/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-datadog/manifest.yaml b/airbyte-integrations/connectors/source-datadog/manifest.yaml index 4696f4908128..38f7dc81fb5b 100644 --- a/airbyte-integrations/connectors/source-datadog/manifest.yaml +++ b/airbyte-integrations/connectors/source-datadog/manifest.yaml @@ -1,7 +1,9 @@ -version: 5.7.5 +version: 5.16.0 type: DeclarativeSource +description: removed `is_read_only` attribute from dashboards stream schema + check: type: CheckStream stream_names: @@ -682,14 +684,6 @@ schemas: - "null" description: Dashboard identifier. readOnly: true - is_read_only: - type: - - boolean - - "null" - description: >- - Whether this dashboard is read-only. If True, only the author and - admins can make changes to it. - readOnly: true layout_type: type: - string diff --git a/airbyte-integrations/connectors/source-datadog/metadata.yaml b/airbyte-integrations/connectors/source-datadog/metadata.yaml index bb4c02099324..67055eca50bf 100644 --- a/airbyte-integrations/connectors/source-datadog/metadata.yaml +++ b/airbyte-integrations/connectors/source-datadog/metadata.yaml @@ -20,10 +20,13 @@ data: 1.0.0: message: "Spec and schema are inline now, and default start and end date is setup for incremental sync." upgradeDeadline: "2024-09-18" + 2.0.0: + message: "`is_read_only` has been removed from the `dashboards` stream schema. This attribute is deprecated as per API upgrade. See more [here](https://docs.datadoghq.com/dashboards/guide/is-read-only-deprecation/)" + upgradeDeadline: "2024-12-13" connectorSubtype: api connectorType: source definitionId: 1cfc30c7-82db-43f4-9fd7-ac1b42312cda - dockerImageTag: 1.1.1 + dockerImageTag: 2.0.4 dockerRepository: airbyte/source-datadog githubIssueLabel: source-datadog icon: datadog.svg @@ -52,5 +55,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-datascope/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-datascope/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-datascope/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-datascope/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-datascope/metadata.yaml b/airbyte-integrations/connectors/source-datascope/metadata.yaml index 0841313113e1..7d7280bfc638 100644 --- a/airbyte-integrations/connectors/source-datascope/metadata.yaml +++ b/airbyte-integrations/connectors/source-datascope/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 8e1ae2d2-4790-44d3-9d83-75b3fc3940ff - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.8 dockerRepository: airbyte/source-datascope githubIssueLabel: source-datascope icon: datascope.svg @@ -42,5 +42,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-db2/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-db2/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-db2/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-db2/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-db2/metadata.yaml b/airbyte-integrations/connectors/source-db2/metadata.yaml index edb0ba684142..10e943d20c21 100644 --- a/airbyte-integrations/connectors/source-db2/metadata.yaml +++ b/airbyte-integrations/connectors/source-db2/metadata.yaml @@ -1,30 +1,32 @@ data: + ab_internal: + ql: 100 + sl: 100 allowedHosts: hosts: - ${host} + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a connectorSubtype: database + connectorTestSuitesOptions: + - suite: unitTests + - suite: integrationTests connectorType: source definitionId: 447e0381-3780-4b46-bb62-00a4e3c8b8e2 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.3 dockerRepository: airbyte/source-db2 + documentationUrl: https://docs.airbyte.com/integrations/sources/db2 githubIssueLabel: source-db2 icon: db2.svg license: MIT name: IBM Db2 registryOverrides: cloud: - enabled: false # Would require DEPLOYMENT_MODE=cloud handling to release to cloud again + enabled: false oss: enabled: true releaseStage: alpha - documentationUrl: https://docs.airbyte.com/integrations/sources/db2 + supportLevel: community tags: - language:java - ab_internal: - sl: 100 - ql: 100 - supportLevel: community - connectorTestSuitesOptions: - - suite: unitTests - - suite: integrationTests metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-dbt/metadata.yaml b/airbyte-integrations/connectors/source-dbt/metadata.yaml index 01e7241b74dc..d5c97dd47b83 100644 --- a/airbyte-integrations/connectors/source-dbt/metadata.yaml +++ b/airbyte-integrations/connectors/source-dbt/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-dbt connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 6eaa4fc5-cf11-413d-a0d6-0023402f71f6 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-dbt githubIssueLabel: source-dbt icon: icon.svg diff --git a/airbyte-integrations/connectors/source-declarative-manifest/main.py b/airbyte-integrations/connectors/source-declarative-manifest/main.py index fb1e853213d7..a4c78be28f71 100644 --- a/airbyte-integrations/connectors/source-declarative-manifest/main.py +++ b/airbyte-integrations/connectors/source-declarative-manifest/main.py @@ -4,5 +4,6 @@ from source_declarative_manifest.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-declarative-manifest/metadata.yaml b/airbyte-integrations/connectors/source-declarative-manifest/metadata.yaml index 8d5634b416ac..47db36376a4a 100644 --- a/airbyte-integrations/connectors/source-declarative-manifest/metadata.yaml +++ b/airbyte-integrations/connectors/source-declarative-manifest/metadata.yaml @@ -8,7 +8,7 @@ data: connectorType: source definitionId: 64a2f99c-542f-4af8-9a6f-355f1217b436 # This version should not be updated manually - it is updated by the CDK release workflow. - dockerImageTag: 5.17.0 + dockerImageTag: 6.5.2 dockerRepository: airbyte/source-declarative-manifest # This page is hidden from the docs for now, since the connector is not in any Airbyte registries. documentationUrl: https://docs.airbyte.com/integrations/sources/low-code diff --git a/airbyte-integrations/connectors/source-declarative-manifest/poetry.lock b/airbyte-integrations/connectors/source-declarative-manifest/poetry.lock index 061d388c6034..3516c6df58bd 100644 --- a/airbyte-integrations/connectors/source-declarative-manifest/poetry.lock +++ b/airbyte-integrations/connectors/source-declarative-manifest/poetry.lock @@ -2,13 +2,13 @@ [[package]] name = "airbyte-cdk" -version = "5.17.0" +version = "6.5.2" description = "A framework for writing Airbyte Connectors." optional = false python-versions = "<4.0,>=3.10" files = [ - {file = "airbyte_cdk-5.17.0-py3-none-any.whl", hash = "sha256:135a8fc43b00a92169dfcdc43c1d7c629aba871a0b471f950ca5d76d3741fc92"}, - {file = "airbyte_cdk-5.17.0.tar.gz", hash = "sha256:5db70cbacec80ba3beabe4253480ab9a3947a450e8d0e39af4a91638b317b32a"}, + {file = "airbyte_cdk-6.5.2-py3-none-any.whl", hash = "sha256:ea33322da43cb5cef4f51ea759b7769e59a074249710b14e28d93bfb72cd825b"}, + {file = "airbyte_cdk-6.5.2.tar.gz", hash = "sha256:9cb026230c2649d4578574fd031f32a64f0d3f934f01ccfd3f5daf4f41bd1384"}, ] [package.dependencies] @@ -25,9 +25,11 @@ jsonref = ">=0.2,<0.3" jsonschema = ">=3.2.0,<3.3.0" langchain_core = "0.1.42" nltk = "3.8.1" +numpy = "<2" orjson = ">=3.10.7,<4.0.0" pandas = "2.2.2" pendulum = "<3.0.0" +psutil = "6.1.0" pydantic = ">=2.7,<3.0" pyjwt = ">=2.8.0,<3.0.0" pyrate-limiter = ">=3.1.0,<3.2.0" @@ -973,6 +975,36 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "psutil" +version = "6.1.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, +] + +[package.extras] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + [[package]] name = "pycparser" version = "2.22" @@ -1747,4 +1779,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.10,<3.12" -content-hash = "70df7684faebd836c644dce4dca63ec92b77c85cc443ae5a1e52034c1285e086" +content-hash = "d7f98f87c4363ca27bb2001a90f1af4e757bf40ce1a22025bdf2c787297eca92" diff --git a/airbyte-integrations/connectors/source-declarative-manifest/pyproject.toml b/airbyte-integrations/connectors/source-declarative-manifest/pyproject.toml index 40398f12f6ef..80c528edb0da 100644 --- a/airbyte-integrations/connectors/source-declarative-manifest/pyproject.toml +++ b/airbyte-integrations/connectors/source-declarative-manifest/pyproject.toml @@ -3,7 +3,7 @@ requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "5.17.0" +version = "6.5.2" name = "source-declarative-manifest" description = "Base source implementation for low-code sources." authors = ["Airbyte "] @@ -17,7 +17,7 @@ include = "source_declarative_manifest" [tool.poetry.dependencies] python = "^3.10,<3.12" -airbyte-cdk = "5.17.0" +airbyte-cdk = "6.5.2" [tool.poetry.scripts] source-declarative-manifest = "source_declarative_manifest.run:run" diff --git a/airbyte-integrations/connectors/source-declarative-manifest/source_declarative_manifest/run.py b/airbyte-integrations/connectors/source-declarative-manifest/source_declarative_manifest/run.py index 4ef4c1908425..811567aa78fa 100644 --- a/airbyte-integrations/connectors/source-declarative-manifest/source_declarative_manifest/run.py +++ b/airbyte-integrations/connectors/source-declarative-manifest/source_declarative_manifest/run.py @@ -1,19 +1,34 @@ # # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # + from __future__ import annotations import json import pkgutil import sys +import traceback +from datetime import datetime from pathlib import Path -from typing import List +from typing import Any, List, Mapping, Optional + +from orjson import orjson -from airbyte_cdk.connector import BaseConnector from airbyte_cdk.entrypoint import AirbyteEntrypoint, launch -from airbyte_cdk.models import AirbyteMessage, ConnectorSpecificationSerializer, Type -from airbyte_cdk.sources.declarative.manifest_declarative_source import ManifestDeclarativeSource +from airbyte_cdk.models import ( + AirbyteErrorTraceMessage, + AirbyteMessage, + AirbyteMessageSerializer, + AirbyteStateMessage, + AirbyteTraceMessage, + ConfiguredAirbyteCatalog, + ConnectorSpecificationSerializer, + TraceType, + Type, +) +from airbyte_cdk.sources.declarative.concurrent_declarative_source import ConcurrentDeclarativeSource from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource +from airbyte_cdk.sources.source import TState class SourceLocalYaml(YamlDeclarativeSource): @@ -21,7 +36,7 @@ class SourceLocalYaml(YamlDeclarativeSource): Declarative source defined by a yaml file in the local filesystem """ - def __init__(self): + def __init__(self, catalog: Optional[ConfiguredAirbyteCatalog], config: Optional[Mapping[str, Any]], state: TState, **kwargs): """ HACK! Problem: YamlDeclarativeSource relies on the calling module name/path to find the yaml file. @@ -33,7 +48,7 @@ def __init__(self): When all manifest connectors are updated to use the new airbyte-cdk. When all manifest connectors are updated to use the source-declarative-manifest as the base image. """ - super().__init__(**{"path_to_yaml": "manifest.yaml"}) + super().__init__(catalog=catalog, config=config, state=state, **{"path_to_yaml": "manifest.yaml"}) def _is_local_manifest_command(args: List[str]) -> bool: @@ -48,8 +63,33 @@ def handle_command(args: List[str]) -> None: handle_remote_manifest_command(args) +def _get_local_yaml_source(args: List[str]) -> SourceLocalYaml: + try: + config, catalog, state = _parse_inputs_into_config_catalog_state(args) + return SourceLocalYaml(config=config, catalog=catalog, state=state) + except Exception as error: + print( + orjson.dumps( + AirbyteMessageSerializer.dump( + AirbyteMessage( + type=Type.TRACE, + trace=AirbyteTraceMessage( + type=TraceType.ERROR, + emitted_at=int(datetime.now().timestamp() * 1000), + error=AirbyteErrorTraceMessage( + message=f"Error starting the sync. This could be due to an invalid configuration or catalog. Please contact Support for assistance. Error: {error}", + stack_trace=traceback.format_exc(), + ), + ), + ) + ) + ).decode() + ) + raise error + + def handle_local_manifest_command(args: List[str]) -> None: - source = SourceLocalYaml() + source = _get_local_yaml_source(args) launch(source, args) @@ -68,24 +108,56 @@ def handle_remote_manifest_command(args: List[str]) -> None: message = AirbyteMessage(type=Type.SPEC, spec=spec) print(AirbyteEntrypoint.airbyte_message_to_string(message)) else: - source = create_manifest(args) + source = create_declarative_source(args) launch(source, args) -def create_manifest(args: List[str]) -> ManifestDeclarativeSource: +def create_declarative_source(args: List[str]) -> ConcurrentDeclarativeSource: """Creates the source with the injected config. This essentially does what other low-code sources do at build time, but at runtime, with a user-provided manifest in the config. This better reflects what happens in the connector builder. """ - parsed_args = AirbyteEntrypoint.parse_args(args) - config = BaseConnector.read_config(parsed_args.config) - if "__injected_declarative_manifest" not in config: - raise ValueError( - f"Invalid config: `__injected_declarative_manifest` should be provided at the root of the config but config only has keys {list(config.keys())}" + try: + config, catalog, state = _parse_inputs_into_config_catalog_state(args) + if "__injected_declarative_manifest" not in config: + raise ValueError( + f"Invalid config: `__injected_declarative_manifest` should be provided at the root of the config but config only has keys {list(config.keys())}" + ) + return ConcurrentDeclarativeSource( + config=config, catalog=catalog, state=state, source_config=config.get("__injected_declarative_manifest") ) - return ManifestDeclarativeSource(config.get("__injected_declarative_manifest")) + except Exception as error: + print( + orjson.dumps( + AirbyteMessageSerializer.dump( + AirbyteMessage( + type=Type.TRACE, + trace=AirbyteTraceMessage( + type=TraceType.ERROR, + emitted_at=int(datetime.now().timestamp() * 1000), + error=AirbyteErrorTraceMessage( + message=f"Error starting the sync. This could be due to an invalid configuration or catalog. Please contact Support for assistance. Error: {error}", + stack_trace=traceback.format_exc(), + ), + ), + ) + ) + ).decode() + ) + raise error + + +def _parse_inputs_into_config_catalog_state( + args: List[str], +) -> (Optional[Mapping[str, Any]], Optional[ConfiguredAirbyteCatalog], List[AirbyteStateMessage]): + parsed_args = AirbyteEntrypoint.parse_args(args) + config = ConcurrentDeclarativeSource.read_config(parsed_args.config) if hasattr(parsed_args, "config") else None + catalog = ConcurrentDeclarativeSource.read_catalog(parsed_args.catalog) if hasattr(parsed_args, "catalog") else None + state = ConcurrentDeclarativeSource.read_state(parsed_args.state) if hasattr(parsed_args, "state") else [] + + return config, catalog, state def run(): diff --git a/airbyte-integrations/connectors/source-declarative-manifest/unit_tests/test_source_declarative_local_manifest.py b/airbyte-integrations/connectors/source-declarative-manifest/unit_tests/test_source_declarative_local_manifest.py index dddd710bdbee..41e6254d51f1 100644 --- a/airbyte-integrations/connectors/source-declarative-manifest/unit_tests/test_source_declarative_local_manifest.py +++ b/airbyte-integrations/connectors/source-declarative-manifest/unit_tests/test_source_declarative_local_manifest.py @@ -2,36 +2,47 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # +import json from unittest.mock import patch import pytest from jsonschema import ValidationError from source_declarative_manifest import run + POKEAPI_JSON_SPEC_SUBSTRING = '"required":["pokemon_name"]' SUCCESS_CHECK_SUBSTRING = '"connectionStatus":{"status":"SUCCEEDED"}' +FAILED_CHECK_SUBSTRING = '"connectionStatus":{"status":"FAILED"}' + @pytest.fixture(autouse=True) def setup(valid_local_manifest_yaml): - with patch('source_declarative_manifest.run._is_local_manifest_command', return_value=True): - with patch('source_declarative_manifest.run.YamlDeclarativeSource._read_and_parse_yaml_file', return_value=valid_local_manifest_yaml): + with patch("source_declarative_manifest.run._is_local_manifest_command", return_value=True): + with patch( + "source_declarative_manifest.run.YamlDeclarativeSource._read_and_parse_yaml_file", return_value=valid_local_manifest_yaml + ): yield + def test_spec_is_poke_api(capsys): run.handle_command(["spec"]) stdout = capsys.readouterr() assert POKEAPI_JSON_SPEC_SUBSTRING in stdout.out + def test_invalid_yaml_throws(capsys, invalid_local_manifest_yaml): - with patch('source_declarative_manifest.run.YamlDeclarativeSource._read_and_parse_yaml_file', return_value=invalid_local_manifest_yaml): - with pytest.raises(ValidationError): - run.handle_command(["spec"]) + with patch("source_declarative_manifest.run.YamlDeclarativeSource._read_and_parse_yaml_file", return_value=invalid_local_manifest_yaml): + with pytest.raises(ValidationError): + run.handle_command(["spec"]) + + +def test_given_invalid_config_then_unsuccessful_check(capsys, invalid_local_config_file): + run.handle_command(["check", "--config", str(invalid_local_config_file)]) + stdout = capsys.readouterr() + assert json.loads(stdout.out).get("connectionStatus").get("status") == "FAILED" -def test_given_invalid_config_then_raise_value_error(invalid_local_config_file): - with pytest.raises(ValueError): - run.create_manifest(["check", "--config", str(invalid_local_config_file)]) -def test_given_invalid_config_then_raise_value_error(capsys, valid_local_config_file): +def test_given_valid_config_with_successful_check(capsys, valid_local_config_file): run.handle_command(["check", "--config", str(valid_local_config_file)]) stdout = capsys.readouterr() assert SUCCESS_CHECK_SUBSTRING in stdout.out diff --git a/airbyte-integrations/connectors/source-declarative-manifest/unit_tests/test_source_declarative_remote_manifest.py b/airbyte-integrations/connectors/source-declarative-manifest/unit_tests/test_source_declarative_remote_manifest.py index 35091ac0785b..d96beb954d50 100644 --- a/airbyte-integrations/connectors/source-declarative-manifest/unit_tests/test_source_declarative_remote_manifest.py +++ b/airbyte-integrations/connectors/source-declarative-manifest/unit_tests/test_source_declarative_remote_manifest.py @@ -3,8 +3,10 @@ # import pytest +from source_declarative_manifest.run import create_declarative_source, handle_command + from airbyte_cdk.sources.declarative.manifest_declarative_source import ManifestDeclarativeSource -from source_declarative_manifest.run import create_manifest, handle_command + REMOTE_MANIFEST_SPEC_SUBSTRING = '"required":["__injected_declarative_manifest"]' @@ -17,9 +19,9 @@ def test_spec_does_not_raise_value_error(capsys): def test_given_no_injected_declarative_manifest_then_raise_value_error(invalid_remote_config): with pytest.raises(ValueError): - create_manifest(["check", "--config", str(invalid_remote_config)]) + create_declarative_source(["check", "--config", str(invalid_remote_config)]) def test_given_injected_declarative_manifest_then_return_declarative_manifest(valid_remote_config): - source = create_manifest(["check", "--config", str(valid_remote_config)]) + source = create_declarative_source(["check", "--config", str(valid_remote_config)]) assert isinstance(source, ManifestDeclarativeSource) diff --git a/airbyte-integrations/connectors/source-delighted/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-delighted/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-delighted/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-delighted/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-delighted/metadata.yaml b/airbyte-integrations/connectors/source-delighted/metadata.yaml index 7b951b37019c..f56a1808378f 100644 --- a/airbyte-integrations/connectors/source-delighted/metadata.yaml +++ b/airbyte-integrations/connectors/source-delighted/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - api.delighted.com connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.4.3@sha256:8937b693c7e01087f6e86e683826ac20f160f7952b8f0a13cbf4f9bfdd7af570 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: cc88c43f-6f53-4e8a-8c4d-b284baaf9635 - dockerImageTag: 0.4.0 + dockerImageTag: 0.4.4 dockerRepository: airbyte/source-delighted documentationUrl: https://docs.airbyte.com/integrations/sources/delighted githubIssueLabel: source-delighted diff --git a/airbyte-integrations/connectors/source-deputy/README.md b/airbyte-integrations/connectors/source-deputy/README.md new file mode 100644 index 000000000000..b78b1e8d59a8 --- /dev/null +++ b/airbyte-integrations/connectors/source-deputy/README.md @@ -0,0 +1,43 @@ +# Deputy +This directory contains the manifest-only connector for `source-deputy`. + +This is the Deputy source that ingests data from the Deputy API. + +Deputy is a software that simplifies employee scheduling, timesheets and HR in one place https://www.deputy.com/ + +In order to use this source you must first create an account on Deputy. +Once logged in, your Deputy install will have a specific URL in the structure of https://{installname}.{geo}.deputy.com - This is the same URL that will be the base API url . + +To obtain your bearer token to use the API, follow the steps shown here https://developer.deputy.com/deputy-docs/docs/the-hello-world-of-deputy +This will have you create an oauth application and create an access token. Enter the access token in the input field. + +You can learn more about the API here https://developer.deputy.com/deputy-docs/reference/getlocations + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-deputy:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-deputy build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-deputy test +``` + diff --git a/airbyte-integrations/connectors/source-deputy/acceptance-test-config.yml b/airbyte-integrations/connectors/source-deputy/acceptance-test-config.yml new file mode 100644 index 000000000000..fd75d7d3b523 --- /dev/null +++ b/airbyte-integrations/connectors/source-deputy/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-deputy:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-deputy/icon.svg b/airbyte-integrations/connectors/source-deputy/icon.svg new file mode 100644 index 000000000000..9e34b4241668 --- /dev/null +++ b/airbyte-integrations/connectors/source-deputy/icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/airbyte-integrations/connectors/source-deputy/manifest.yaml b/airbyte-integrations/connectors/source-deputy/manifest.yaml new file mode 100644 index 000000000000..690e571211f3 --- /dev/null +++ b/airbyte-integrations/connectors/source-deputy/manifest.yaml @@ -0,0 +1,2715 @@ +version: 5.16.0 + +type: DeclarativeSource + +description: >- + This is the Deputy source that ingests data from the Deputy API. + + + Deputy is a software that simplifies employee scheduling, timesheets and HR in + one place https://www.deputy.com/ + + + In order to use this source you must first create an account on Deputy. + + Once logged in, your Deputy install will have a specific URL in the structure + of https://{installname}.{geo}.deputy.com - This is the same URL that will be + the base API url . + + + To obtain your bearer token to use the API, follow the steps shown here + https://developer.deputy.com/deputy-docs/docs/the-hello-world-of-deputy + + This will have you create an oauth application and create an access token. + Enter the access token in the input field. + + + You can learn more about the API here + https://developer.deputy.com/deputy-docs/reference/getlocations + +check: + type: CheckStream + stream_names: + - locations + +definitions: + streams: + locations: + type: DeclarativeStream + name: locations + primary_key: + - Id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/resource/Company + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/locations" + employees: + type: DeclarativeStream + name: employees + primary_key: + - Id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/supervise/employee + http_method: GET + request_body_json: + max: 1 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/employees" + award_lists: + type: DeclarativeStream + name: award_lists + primary_key: + - AwardCode + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/payroll/listAwardsLibrary + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/award_lists" + departments: + type: DeclarativeStream + name: departments + primary_key: + - Id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/resource/OperationalUnit + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/departments" + timesheets: + type: DeclarativeStream + name: timesheets + primary_key: + - Id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/my/timesheets + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/timesheets" + tasks: + type: DeclarativeStream + name: tasks + primary_key: + - Id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/my/tasks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tasks" + news_feed: + type: DeclarativeStream + name: news_feed + primary_key: + - Id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/my/memo + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/news_feed" + addresses: + type: DeclarativeStream + name: addresses + primary_key: + - Id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/resource/Address + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/addresses" + categories: + type: DeclarativeStream + name: categories + primary_key: + - Id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/resource/Category + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/categories" + comments: + type: DeclarativeStream + name: comments + primary_key: + - Id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/resource/Comment + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/comments" + company_periods: + type: DeclarativeStream + name: company_periods + primary_key: + - Id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/resource/CompanyPeriod + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/company_periods" + employee_agreements: + type: DeclarativeStream + name: employee_agreements + primary_key: + - Id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/resource/EmployeeAgreement + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/employee_agreements" + employee: + type: DeclarativeStream + name: employee + primary_key: + - Id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/resource/Employee + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/employee" + base_requester: + type: HttpRequester + url_base: "{{ config[\"base_url\"] }}" + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/locations" + - $ref: "#/definitions/streams/employees" + - $ref: "#/definitions/streams/award_lists" + - $ref: "#/definitions/streams/departments" + - $ref: "#/definitions/streams/timesheets" + - $ref: "#/definitions/streams/tasks" + - $ref: "#/definitions/streams/news_feed" + - $ref: "#/definitions/streams/addresses" + - $ref: "#/definitions/streams/categories" + - $ref: "#/definitions/streams/comments" + - $ref: "#/definitions/streams/company_periods" + - $ref: "#/definitions/streams/employee_agreements" + - $ref: "#/definitions/streams/employee" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - base_url + - api_key + properties: + base_url: + type: string + description: The base url for your deputy account to make API requests + order: 0 + title: Base URL + api_key: + type: string + order: 1 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + locations: true + employees: true + award_lists: true + departments: true + timesheets: true + tasks: true + news_feed: true + addresses: true + categories: true + comments: true + company_periods: true + employee_agreements: true + employee: true + testedStreams: + locations: + hasRecords: true + streamHash: b36f59510c29852826ce956d16d2f72d4bd3bd2e + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + employees: + streamHash: 7a7c2909cbbd0443d5465c2575bac45cbd6e669a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + award_lists: + hasRecords: true + streamHash: 227bf7d420b60c1c7c77ba995a36504548658c4e + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + departments: + hasRecords: true + streamHash: e8de6171bb9b6eca67b847b6e0c75c6ba5d4a680 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + timesheets: + hasRecords: true + streamHash: 9fb385d3bd75b9e488326143df36cde35822fd47 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + tasks: + hasRecords: true + streamHash: 1a07fa7312a790952e191b42d6536f50bbcbc83d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + news_feed: + hasRecords: true + streamHash: 8c36fe3f13fcbbe0e4a29d847bf2240722e0de70 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + addresses: + streamHash: 649a48479802de0ec534864451ff11133a342f6e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + categories: + hasRecords: true + streamHash: 8868489ef8e3fe57a9fa39c246b6bd5039665919 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + comments: + hasRecords: true + streamHash: 9d23f04869592fd2677fbc0831ba4e9459a00e4e + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + company_periods: + hasRecords: true + streamHash: 3a77170b7f6f6874d5a9a5c0e3b3b58f6d549a0a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + employee_agreements: + hasRecords: true + streamHash: 0b0f62833706ce6891347513c900b9e9830556d4 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + employee: + streamHash: c7b8e61416e2bac7ee41e43a918d945081e92356 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + locations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Active: + type: + - boolean + - "null" + Address: + type: + - number + - "null" + BusinessNumber: + type: + - string + - "null" + Code: + type: + - string + - "null" + CompanyName: + type: + - string + - "null" + Contact: + type: + - number + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + Id: + type: number + IsPayrollEntity: + type: + - boolean + - "null" + IsWorkplace: + type: + - boolean + - "null" + Modified: + type: + - string + - "null" + ParentCompany: + type: + - number + - "null" + PayrollExportCode: + type: + - string + - "null" + TradingName: + type: + - string + - "null" + _DPMetaData: + type: + - object + - "null" + properties: + AddressObject: + type: + - object + - "null" + properties: + Country: + type: + - number + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + Id: + type: + - number + - "null" + Modified: + type: + - string + - "null" + Print: + type: + - string + - "null" + State: + type: + - string + - "null" + Street1: + type: + - string + - "null" + CreatorInfo: + type: + - object + - "null" + properties: + DisplayName: + type: + - string + - "null" + Employee: + type: + - number + - "null" + EmployeeProfile: + type: + - number + - "null" + Id: + type: + - number + - "null" + Photo: + type: + - string + - "null" + Pronouns: + type: + - number + - "null" + CustomData: + type: + - object + - "null" + properties: {} + Geo: + type: + - object + - "null" + properties: + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + Id: + type: + - number + - "null" + Latitude: + type: + - number + - "null" + Longitude: + type: + - number + - "null" + Modified: + type: + - string + - "null" + Orm: + type: + - string + - "null" + RecId: + type: + - number + - "null" + System: + type: + - string + - "null" + required: + - Id + employees: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Active: + type: + - boolean + - "null" + AllowAppraisal: + type: + - boolean + - "null" + AllowLogin: + type: + - boolean + - "null" + AnalyticsID: + type: + - string + - "null" + CanAskToShowPin: + type: + - boolean + - "null" + Company: + type: + - number + - "null" + Contact: + type: + - number + - "null" + Contract: + anyOf: + - type: string + - type: object + properties: + Award: + type: "null" + AwardStartDate: + type: "null" + BasePayRule: + type: number + Code: + type: "null" + CountryId: + type: "null" + Created: + type: string + Creator: + type: number + Description: + type: "null" + EmploymentBasis: + type: number + EmploymentCategory: + type: number + EmploymentCondition: + type: "null" + EmploymentStatus: + type: number + EmploymentSubType: + type: "null" + EndDate: + type: "null" + File: + type: "null" + Id: + type: number + LeaveRuleArray: + type: array + items: + type: object + properties: + BasePayRule: + type: number + ContractId: + type: number + Created: + type: string + Creator: + type: number + Id: + type: number + LeaveRuleId: + type: number + LoadingPayRule1: + type: "null" + LoadingPayRule2: + type: "null" + LoadingPayRule3: + type: "null" + Modified: + type: string + _DPMetaData: + type: object + properties: + CreatorInfo: + type: object + properties: + DisplayName: + type: string + Id: + type: number + Photo: + type: string + System: + type: string + MigrateTo: + type: "null" + Modified: + type: string + Name: + type: string + PayRuleArray: + type: array + items: + type: object + properties: + AdvancedCalculation: + type: "null" + AnnualSalary: + type: "null" + Comment: + type: "null" + Config: + type: "null" + CrId: + type: "null" + Created: + type: string + Creator: + type: number + CtId: + type: "null" + DexmlScript: + type: "null" + DexmlScriptParam: + type: "null" + HourlyRate: + type: number + Id: + type: number + IsExported: + type: boolean + IsMultiplier: + type: boolean + MaximumShiftLength: + type: "null" + MaximumType: + type: number + MaximumValue: + type: "null" + MinimumShiftLength: + type: "null" + MinimumType: + type: number + MinimumValue: + type: "null" + Modified: + type: string + MultiplierBaseRate: + type: "null" + MultiplierValue: + type: "null" + PayPortionRule: + type: number + PayTitle: + type: string + PayrollCategory: + type: string + PeriodType: + type: "null" + RateTag: + type: "null" + RateType: + type: "null" + RecommendWith: + type: number + RemunerationBy: + type: number + RemunerationType: + type: number + Schedule: + type: number + UnitValue: + type: "null" + _DPMetaData: + type: object + properties: + CreatorInfo: + type: object + System: + type: string + PeriodType: + type: number + PpId: + type: "null" + StartDate: + type: "null" + StressProfile: + type: "null" + StrictLeaveApproval: + type: "null" + ThirdPartySync: + type: string + _DPMetaData: + type: object + properties: + CreatorInfo: + type: object + System: + type: string + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + DisplayName: + type: + - string + - "null" + Email: + type: + - string + - "null" + EmployeeHourlyRate: + type: + - number + - "null" + FirstName: + type: + - string + - "null" + HasAndroidToken: + type: + - boolean + - "null" + HasEnabled2FA: + type: + - boolean + - "null" + HasIPhoneToken: + type: + - boolean + - "null" + HistoryId: + type: + - number + - "null" + Id: + type: number + Img: + type: + - string + - "null" + IsSubordinate: + type: + - boolean + - "null" + LastName: + type: + - string + - "null" + LeaveAccrualArray: + type: + - array + - "null" + Mobile: + type: + - string + - "null" + Modified: + type: + - string + - "null" + PayrollId: + type: + - string + - "null" + Photo: + type: + - number + - "null" + PhotoLinkId: + type: + - string + - "null" + Pronouns: + type: + - number + - "null" + Role: + type: + - number + - "null" + StartDate: + type: + - string + - "null" + Status: + type: + - number + - "null" + StressProfile: + type: + - number + - "null" + TrainingArray: + type: + - string + - "null" + TrainingFileArray: + type: + - array + - "null" + UserId: + type: + - number + - "null" + UserName: + type: + - string + - "null" + WorkplaceArray: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + Agreement1: + type: + - number + - "null" + Agreement2: + type: + - number + - "null" + Agreement3: + type: + - number + - "null" + Company: + type: + - number + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + EmployeeId: + type: + - number + - "null" + Id: + type: + - number + - "null" + Modified: + type: + - string + - "null" + SortOrder: + type: + - number + - "null" + _DPMetaData: + type: + - object + - "null" + properties: + CreatorInfo: + type: + - object + - "null" + System: + type: + - string + - "null" + _DPMetaData: + type: + - object + - "null" + properties: + CreatorInfo: + type: + - object + - "null" + System: + type: + - string + - "null" + required: + - Id + award_lists: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + AwardCode: + type: string + CountryCode: + type: + - string + - "null" + employmentTerm: + type: + - number + - "null" + name: + type: + - string + - "null" + required: + - AwardCode + departments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Active: + type: + - boolean + - "null" + Address: + type: + - number + - "null" + AddressObject: + anyOf: + - type: array + - type: object + properties: + City: + type: string + ContactName: + type: "null" + Country: + type: number + Created: + type: string + Creator: + type: number + Format: + type: "null" + Id: + type: number + Modified: + type: string + Notes: + type: "null" + Phone: + type: "null" + PoBox: + type: "null" + Postcode: + type: string + Print: + type: string + Saved: + type: "null" + State: + type: string + Street1: + type: string + Street2: + type: "null" + StreetNo: + type: "null" + SuiteNo: + type: "null" + UnitNo: + type: "null" + Verified: + type: "null" + Colour: + type: + - string + - "null" + Company: + type: + - number + - "null" + CompanyAddress: + type: + - number + - "null" + CompanyCode: + type: + - string + - "null" + CompanyName: + type: + - string + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + Id: + type: number + Modified: + type: + - string + - "null" + OperationalUnitName: + type: + - string + - "null" + ParentOperationalUnit: + type: + - number + - "null" + PayrollExportName: + type: + - string + - "null" + RosterSortOrder: + type: + - number + - "null" + ShowOnRoster: + type: + - boolean + - "null" + _DPMetaData: + type: + - object + - "null" + properties: + AddressObject: + type: + - object + - "null" + properties: + City: + type: + - string + - "null" + Country: + type: + - number + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + Id: + type: + - number + - "null" + Modified: + type: + - string + - "null" + Postcode: + type: + - string + - "null" + Print: + type: + - string + - "null" + State: + type: + - string + - "null" + Street1: + type: + - string + - "null" + CreatorInfo: + type: + - object + - "null" + properties: + DisplayName: + type: + - string + - "null" + Employee: + type: + - number + - "null" + EmployeeProfile: + type: + - number + - "null" + Id: + type: + - number + - "null" + Photo: + type: + - string + - "null" + Pronouns: + type: + - number + - "null" + System: + type: + - string + - "null" + required: + - Id + timesheets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + AutoPayRuleApproved: + type: + - boolean + - "null" + AutoProcessed: + type: + - boolean + - "null" + AutoRounded: + type: + - boolean + - "null" + AutoTimeApproved: + type: + - boolean + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + Date: + type: + - string + - "null" + Disputed: + type: + - boolean + - "null" + Employee: + type: + - number + - "null" + EmployeeAgreement: + type: + - number + - "null" + EmployeeHistory: + type: + - number + - "null" + EndTime: + type: + - number + - "null" + EndTimeLocalized: + type: + - string + - "null" + Id: + type: number + Invoiced: + type: + - boolean + - "null" + IsInProgress: + type: + - boolean + - "null" + IsLeave: + type: + - boolean + - "null" + MarkedPaidUnpaidAt: + type: + - string + - "null" + Mealbreak: + type: + - string + - "null" + MealbreakSlots: + type: + - string + - "null" + Metadata: + type: + - string + - "null" + Modified: + type: + - string + - "null" + OnCost: + type: + - number + - "null" + OperationalUnit: + type: + - number + - "null" + OperationalUnitObject: + type: + - object + - "null" + properties: + Active: + type: + - boolean + - "null" + Address: + type: + - number + - "null" + AddressObject: + type: + - object + - "null" + properties: + City: + type: + - string + - "null" + Country: + type: + - number + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + Id: + type: + - number + - "null" + Modified: + type: + - string + - "null" + Postcode: + type: + - string + - "null" + Print: + type: + - string + - "null" + State: + type: + - string + - "null" + Street1: + type: + - string + - "null" + Colour: + type: + - string + - "null" + Company: + type: + - number + - "null" + CompanyAddress: + type: + - number + - "null" + CompanyCode: + type: + - string + - "null" + CompanyName: + type: + - string + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + Id: + type: + - number + - "null" + Modified: + type: + - string + - "null" + OperationalUnitName: + type: + - string + - "null" + ParentOperationalUnit: + type: + - number + - "null" + PayrollExportName: + type: + - string + - "null" + RosterSortOrder: + type: + - number + - "null" + ShowOnRoster: + type: + - boolean + - "null" + PayRuleApproved: + type: + - boolean + - "null" + PayStaged: + type: + - boolean + - "null" + PaycycleId: + type: + - number + - "null" + RealTime: + type: + - boolean + - "null" + ReviewState: + type: + - number + - "null" + Slots: + type: + - array + - "null" + StartTime: + type: + - number + - "null" + StartTimeLocalized: + type: + - string + - "null" + TimeApproved: + type: + - boolean + - "null" + TotalTime: + type: + - number + - "null" + TotalTimeInv: + type: + - number + - "null" + ValidationFlag: + type: + - number + - "null" + _DPMetaData: + type: + - object + - "null" + properties: + CreatorInfo: + type: + - object + - "null" + properties: + DisplayName: + type: + - string + - "null" + Employee: + type: + - number + - "null" + EmployeeProfile: + type: + - number + - "null" + Id: + type: + - number + - "null" + Photo: + type: + - string + - "null" + Pronouns: + type: + - number + - "null" + EmployeeInfo: + type: + - object + - "null" + properties: + DisplayName: + type: + - string + - "null" + Employee: + type: + - number + - "null" + EmployeeProfile: + type: + - number + - "null" + Id: + type: + - number + - "null" + Photo: + type: + - string + - "null" + Pronouns: + type: + - number + - "null" + OperationalUnitInfo: + type: + - object + - "null" + properties: + Company: + type: + - number + - "null" + CompanyName: + type: + - string + - "null" + Id: + type: + - number + - "null" + LabelWithCompany: + type: + - string + - "null" + OperationalUnitName: + type: + - string + - "null" + System: + type: + - string + - "null" + required: + - Id + tasks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Answer: + type: + - string + - "null" + Comment: + type: + - string + - "null" + Created: + type: + - string + - "null" + Date: + type: + - string + - "null" + DayTimestamp: + type: + - number + - "null" + GroupId: + type: + - number + - "null" + Id: + type: number + Modified: + type: + - string + - "null" + OpUnitId: + type: + - number + - "null" + Question: + type: + - string + - "null" + SortOrder: + type: + - number + - "null" + TaskSetupId: + type: + - number + - "null" + Type: + type: + - number + - "null" + UserEntry: + type: + - number + - "null" + UserResponsible: + type: + - number + - "null" + _DPMetaData: + type: + - object + - "null" + properties: + System: + type: + - string + - "null" + UserEntryInfo: + type: + - object + - "null" + properties: + DisplayName: + type: + - string + - "null" + Employee: + type: + - number + - "null" + Id: + type: + - number + - "null" + Photo: + type: + - string + - "null" + UserResponsibleInfo: + type: + - object + - "null" + properties: + DisplayName: + type: + - string + - "null" + Employee: + type: + - number + - "null" + Id: + type: + - number + - "null" + Photo: + type: + - string + - "null" + required: + - Id + news_feed: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Active: + type: + - boolean + - "null" + ConfirmText: + type: + - string + - "null" + Content: + type: + - string + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + DisableComment: + type: + - boolean + - "null" + Id: + type: number + Keyword: + type: + - string + - "null" + Modified: + type: + - string + - "null" + ShowFrom: + type: + - string + - "null" + Type: + type: + - number + - "null" + _DPMetaData: + type: + - object + - "null" + properties: + AssignedUsers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + DisplayName: + type: + - string + - "null" + Employee: + type: + - number + - "null" + EmployeeProfile: + type: + - number + - "null" + Id: + type: + - number + - "null" + Photo: + type: + - string + - "null" + Pronouns: + type: + - number + - "null" + CanDelete: + type: + - boolean + - "null" + Comments: + type: + - array + - "null" + Companies: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + Active: + type: + - boolean + - "null" + Address: + type: + - number + - "null" + BusinessNumber: + type: + - string + - "null" + Code: + type: + - string + - "null" + CompanyName: + type: + - string + - "null" + Contact: + type: + - number + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + Id: + type: + - number + - "null" + IsPayrollEntity: + type: + - boolean + - "null" + IsWorkplace: + type: + - boolean + - "null" + Modified: + type: + - string + - "null" + ParentCompany: + type: + - number + - "null" + PayrollExportCode: + type: + - string + - "null" + TradingName: + type: + - string + - "null" + _DPMetaData: + type: + - object + - "null" + properties: + AddressObject: + type: + - object + - "null" + properties: + Country: + type: + - number + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + Id: + type: + - number + - "null" + Modified: + type: + - string + - "null" + Print: + type: + - string + - "null" + State: + type: + - string + - "null" + Street1: + type: + - string + - "null" + CreatorInfo: + type: + - object + - "null" + properties: + DisplayName: + type: + - string + - "null" + Employee: + type: + - number + - "null" + EmployeeProfile: + type: + - number + - "null" + Id: + type: + - number + - "null" + Photo: + type: + - string + - "null" + Pronouns: + type: + - number + - "null" + CustomData: + type: + - object + - "null" + properties: {} + Geo: + type: + - object + - "null" + properties: + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + Id: + type: + - number + - "null" + Latitude: + type: + - number + - "null" + Longitude: + type: + - number + - "null" + Modified: + type: + - string + - "null" + Orm: + type: + - string + - "null" + RecId: + type: + - number + - "null" + System: + type: + - string + - "null" + CreatorInfo: + type: + - object + - "null" + properties: + DisplayName: + type: + - string + - "null" + Employee: + type: + - number + - "null" + EmployeeProfile: + type: + - number + - "null" + Id: + type: + - number + - "null" + Photo: + type: + - string + - "null" + Pronouns: + type: + - number + - "null" + Files: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + DownloadLink: + type: + - string + - "null" + DynamicLink: + type: + - string + - "null" + Height: + type: + - number + - "null" + Id: + type: + - number + - "null" + Linkid: + type: + - string + - "null" + Modified: + type: + - string + - "null" + Name: + type: + - string + - "null" + P5050Link: + type: + - string + - "null" + PreviewLink: + type: + - string + - "null" + Session: + type: + - number + - "null" + Size: + type: + - number + - "null" + Tempid: + type: + - string + - "null" + Type: + type: + - string + - "null" + Width: + type: + - number + - "null" + MemoLogs: + type: + - array + - "null" + Reactions: + type: + - object + - "null" + properties: + "1": + type: + - number + - "null" + "2": + type: + - number + - "null" + "3": + type: + - number + - "null" + "4": + type: + - number + - "null" + "5": + type: + - number + - "null" + "6": + type: + - number + - "null" + RequireConfirmation: + type: + - boolean + - "null" + RequireMyConfirm: + type: + - boolean + - "null" + System: + type: + - string + - "null" + Teams: + type: + - array + - "null" + UserReaction: + type: + - array + - "null" + required: + - Id + addresses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + City: + type: + - string + - "null" + Country: + type: + - number + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + Id: + type: number + Modified: + type: + - string + - "null" + Postcode: + type: + - string + - "null" + Print: + type: + - string + - "null" + State: + type: + - string + - "null" + Street1: + type: + - string + - "null" + _DPMetaData: + type: + - object + - "null" + properties: + CreatorInfo: + type: + - object + - "null" + properties: + DisplayName: + type: + - string + - "null" + Employee: + type: + - number + - "null" + EmployeeProfile: + type: + - number + - "null" + Id: + type: + - number + - "null" + Photo: + type: + - string + - "null" + Pronouns: + type: + - number + - "null" + System: + type: + - string + - "null" + required: + - Id + categories: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Category: + type: + - string + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + Group: + type: + - string + - "null" + Id: + type: number + Modified: + type: + - string + - "null" + SortOrder: + type: + - number + - "null" + Stafflog: + type: + - boolean + - "null" + System: + type: + - boolean + - "null" + _DPMetaData: + type: + - object + - "null" + properties: + CreatorInfo: + type: + - object + - "null" + properties: + DisplayName: + type: + - string + - "null" + Employee: + type: + - number + - "null" + EmployeeProfile: + type: + - number + - "null" + Id: + type: + - number + - "null" + Photo: + type: + - string + - "null" + Pronouns: + type: + - number + - "null" + System: + type: + - string + - "null" + required: + - Id + comments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Comment: + type: + - string + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + Id: + type: number + IgnorePermission: + type: + - boolean + - "null" + InFeed: + type: + - boolean + - "null" + Modified: + type: + - string + - "null" + Orm: + type: + - string + - "null" + RecId: + type: + - number + - "null" + _DPMetaData: + type: + - object + - "null" + properties: + CreatorInfo: + type: + - object + - "null" + properties: + DisplayName: + type: + - string + - "null" + Employee: + type: + - number + - "null" + EmployeeProfile: + type: + - number + - "null" + Id: + type: + - number + - "null" + Photo: + type: + - string + - "null" + Pronouns: + type: + - number + - "null" + System: + type: + - string + - "null" + required: + - Id + company_periods: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Company: + type: + - number + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + DateEnd: + type: + - string + - "null" + DateStart: + type: + - string + - "null" + End: + type: + - number + - "null" + Id: + type: number + Modified: + type: + - string + - "null" + PayPeriod: + type: + - number + - "null" + Start: + type: + - number + - "null" + _DPMetaData: + type: + - object + - "null" + properties: + CreatorInfo: + type: + - object + - "null" + properties: + DisplayName: + type: + - string + - "null" + Employee: + type: + - number + - "null" + EmployeeProfile: + type: + - number + - "null" + Id: + type: + - number + - "null" + Photo: + type: + - string + - "null" + Pronouns: + type: + - number + - "null" + System: + type: + - string + - "null" + required: + - Id + employee_agreements: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Active: + type: + - boolean + - "null" + CompanyName: + type: + - string + - "null" + Config: + type: + - string + - "null" + Contract: + type: + - number + - "null" + ContractFile: + type: + - number + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + EmpType: + type: + - number + - "null" + EmployeeId: + type: + - number + - "null" + HistoryId: + type: + - number + - "null" + Id: + type: number + Modified: + type: + - string + - "null" + PayPeriod: + type: + - number + - "null" + PayPoint: + type: + - number + - "null" + PayrollId: + type: + - string + - "null" + SalaryPayRule: + type: + - number + - "null" + StartDate: + type: + - string + - "null" + _DPMetaData: + type: + - object + - "null" + properties: + CreatorInfo: + type: + - object + - "null" + properties: + DisplayName: + type: + - string + - "null" + Employee: + type: + - number + - "null" + EmployeeProfile: + type: + - number + - "null" + Id: + type: + - number + - "null" + Photo: + type: + - string + - "null" + Pronouns: + type: + - number + - "null" + System: + type: + - string + - "null" + required: + - Id + employee: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Active: + type: + - boolean + - "null" + AllowAppraisal: + type: + - boolean + - "null" + Company: + type: + - number + - "null" + Contact: + type: + - number + - "null" + Created: + type: + - string + - "null" + Creator: + type: + - number + - "null" + DisplayName: + type: + - string + - "null" + FirstName: + type: + - string + - "null" + HistoryId: + type: + - number + - "null" + Id: + type: number + LastName: + type: + - string + - "null" + Modified: + type: + - string + - "null" + Photo: + type: + - number + - "null" + Pronouns: + type: + - number + - "null" + Role: + type: + - number + - "null" + StartDate: + type: + - string + - "null" + StressProfile: + type: + - number + - "null" + UserId: + type: + - number + - "null" + _DPMetaData: + type: + - object + - "null" + properties: + CreatorInfo: + type: + - object + - "null" + properties: + DisplayName: + type: + - string + - "null" + Employee: + type: + - number + - "null" + EmployeeProfile: + type: + - number + - "null" + Id: + type: + - number + - "null" + Photo: + type: + - string + - "null" + Pronouns: + type: + - number + - "null" + System: + type: + - string + - "null" + required: + - Id diff --git a/airbyte-integrations/connectors/source-deputy/metadata.yaml b/airbyte-integrations/connectors/source-deputy/metadata.yaml new file mode 100644 index 000000000000..5137cd8c8f0a --- /dev/null +++ b/airbyte-integrations/connectors/source-deputy/metadata.yaml @@ -0,0 +1,34 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-deputy + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 0b8bfdb4-ee91-43a8-9f91-536c816724a6 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-deputy + githubIssueLabel: source-deputy + icon: icon.svg + license: MIT + name: Deputy + releaseDate: 2024-10-27 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/deputy + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-dixa/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-dixa/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-dixa/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-dixa/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-dixa/metadata.yaml b/airbyte-integrations/connectors/source-dixa/metadata.yaml index e23e07eff472..60d6c99cce74 100644 --- a/airbyte-integrations/connectors/source-dixa/metadata.yaml +++ b/airbyte-integrations/connectors/source-dixa/metadata.yaml @@ -14,7 +14,7 @@ data: connectorSubtype: api connectorType: source definitionId: 0b5c867e-1b12-4d02-ab74-97b2184ff6d7 - dockerImageTag: 0.4.0 + dockerImageTag: 0.4.4 dockerRepository: airbyte/source-dixa githubIssueLabel: source-dixa icon: dixa.svg @@ -39,5 +39,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.5.4@sha256:b07a521add11f987c63c0db68c1b57e90bec0c985f1cb6f3c5a1940cde628a70 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-dockerhub/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-dockerhub/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-dockerhub/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-dockerhub/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-dockerhub/metadata.yaml b/airbyte-integrations/connectors/source-dockerhub/metadata.yaml index 621a02d7b158..614b68e74465 100644 --- a/airbyte-integrations/connectors/source-dockerhub/metadata.yaml +++ b/airbyte-integrations/connectors/source-dockerhub/metadata.yaml @@ -7,11 +7,11 @@ data: - hub.docker.com - auth.docker.io connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 72d405a3-56d8-499f-a571-667c03406e43 - dockerImageTag: 0.3.3 + dockerImageTag: 0.3.8 dockerRepository: airbyte/source-dockerhub documentationUrl: https://docs.airbyte.com/integrations/sources/dockerhub githubIssueLabel: source-dockerhub diff --git a/airbyte-integrations/connectors/source-dremio/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-dremio/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-dremio/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-dremio/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-dremio/metadata.yaml b/airbyte-integrations/connectors/source-dremio/metadata.yaml index 8cd5cd161993..96347c5efd70 100644 --- a/airbyte-integrations/connectors/source-dremio/metadata.yaml +++ b/airbyte-integrations/connectors/source-dremio/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: d99e9ace-8621-46c2-9144-76ae4751d64b - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-dremio githubIssueLabel: source-dremio icon: dremio.svg @@ -39,5 +39,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-drift/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-drift/integration_tests/acceptance.py index d49b55882333..a9256a533972 100644 --- a/airbyte-integrations/connectors/source-drift/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-drift/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-drift/metadata.yaml b/airbyte-integrations/connectors/source-drift/metadata.yaml index e950b8da6e2f..a6a4bdba9791 100644 --- a/airbyte-integrations/connectors/source-drift/metadata.yaml +++ b/airbyte-integrations/connectors/source-drift/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - https://driftapi.com/ connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.4.3@sha256:8937b693c7e01087f6e86e683826ac20f160f7952b8f0a13cbf4f9bfdd7af570 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 445831eb-78db-4b1f-8f1f-0d96ad8739e2 - dockerImageTag: 0.4.1 + dockerImageTag: 0.4.6 dockerRepository: airbyte/source-drift documentationUrl: https://docs.airbyte.com/integrations/sources/drift githubIssueLabel: source-drift diff --git a/airbyte-integrations/connectors/source-drip/metadata.yaml b/airbyte-integrations/connectors/source-drip/metadata.yaml index ce0fdcfc05ae..8622c4f88272 100644 --- a/airbyte-integrations/connectors/source-drip/metadata.yaml +++ b/airbyte-integrations/connectors/source-drip/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-drip connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 4221175d-1bb9-436d-8cc7-ca0d8605b2b6 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-drip githubIssueLabel: source-drip icon: icon.svg diff --git a/airbyte-integrations/connectors/source-dropbox-sign/metadata.yaml b/airbyte-integrations/connectors/source-dropbox-sign/metadata.yaml index bb6a5839a7d1..51814ceabd18 100644 --- a/airbyte-integrations/connectors/source-dropbox-sign/metadata.yaml +++ b/airbyte-integrations/connectors/source-dropbox-sign/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-dropbox-sign connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: da9cccd2-7319-44ea-b6cf-ddc08f13e959 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-dropbox-sign githubIssueLabel: source-dropbox-sign icon: icon.svg diff --git a/airbyte-integrations/connectors/source-dynamodb/metadata.yaml b/airbyte-integrations/connectors/source-dynamodb/metadata.yaml index 93e6faeb1e29..5b27881b37d0 100644 --- a/airbyte-integrations/connectors/source-dynamodb/metadata.yaml +++ b/airbyte-integrations/connectors/source-dynamodb/metadata.yaml @@ -2,10 +2,22 @@ data: ab_internal: ql: 200 sl: 100 + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a connectorSubtype: api + connectorTestSuitesOptions: + - suite: unitTests + - suite: acceptanceTests + - suite: integrationTests + testSecrets: + - fileName: config.json + name: SECRET_SOURCE-DYNAMODB__CREDS + secretStore: + alias: airbyte-connector-testing-secret-store + type: GSM connectorType: source definitionId: 50401137-8871-4c5a-abb7-1f5fda35545a - dockerImageTag: 0.3.6 + dockerImageTag: 0.3.7 dockerRepository: airbyte/source-dynamodb documentationUrl: https://docs.airbyte.com/integrations/sources/dynamodb githubIssueLabel: source-dynamodb @@ -21,14 +33,4 @@ data: supportLevel: community tags: - language:java - connectorTestSuitesOptions: - - suite: unitTests - - suite: acceptanceTests - - suite: integrationTests - testSecrets: - - name: SECRET_SOURCE-DYNAMODB__CREDS - fileName: config.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-e-conomic/README.md b/airbyte-integrations/connectors/source-e-conomic/README.md new file mode 100644 index 000000000000..d7c24953a7d6 --- /dev/null +++ b/airbyte-integrations/connectors/source-e-conomic/README.md @@ -0,0 +1,33 @@ +# e-conomic +This directory contains the manifest-only connector for `source-e-conomic`. + +The Airbyte connector for e-conomic enables seamless integration with the e-conomic accounting platform. It allows users to efficiently extract financial data such as invoices, accounts, customers, and transactions from e-conomic and sync it to your preferred data warehouse or analytics tool. This connector simplifies data flow management, facilitating automated data extraction for comprehensive financial reporting and analysis. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-e-conomic:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-e-conomic build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-e-conomic test +``` + diff --git a/airbyte-integrations/connectors/source-e-conomic/acceptance-test-config.yml b/airbyte-integrations/connectors/source-e-conomic/acceptance-test-config.yml new file mode 100644 index 000000000000..b3d6fda887c7 --- /dev/null +++ b/airbyte-integrations/connectors/source-e-conomic/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-e-conomic:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-e-conomic/icon.svg b/airbyte-integrations/connectors/source-e-conomic/icon.svg new file mode 100644 index 000000000000..7ae093456c55 --- /dev/null +++ b/airbyte-integrations/connectors/source-e-conomic/icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/airbyte-integrations/connectors/source-e-conomic/manifest.yaml b/airbyte-integrations/connectors/source-e-conomic/manifest.yaml new file mode 100644 index 000000000000..4cf9f2320160 --- /dev/null +++ b/airbyte-integrations/connectors/source-e-conomic/manifest.yaml @@ -0,0 +1,7032 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + The Airbyte connector for e-conomic enables seamless integration with the + e-conomic accounting platform. It allows users to efficiently extract + financial data such as invoices, accounts, customers, and transactions from + e-conomic and sync it to your preferred data warehouse or analytics tool. This + connector simplifies data flow management, facilitating automated data + extraction for comprehensive financial reporting and analysis. + +check: + type: CheckStream + stream_names: + - accounts + +definitions: + streams: + accounts: + type: DeclarativeStream + name: accounts + primary_key: + - accountNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounts + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + pagination_strategy: + type: PageIncrement + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounts" + accounting_years: + type: DeclarativeStream + name: accounting_years + primary_key: + - year + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounting-years + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounting_years" + app_roles: + type: DeclarativeStream + name: app_roles + primary_key: + - roleNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /app-roles + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 0 + page_size: 1000 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/app_roles" + currencies: + type: DeclarativeStream + name: currencies + primary_key: + - code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /currencies + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + pagination_strategy: + type: PageIncrement + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/currencies" + customer_groups: + type: DeclarativeStream + name: customer_groups + primary_key: + - customerGroupNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /customer-groups + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customer_groups" + customers: + type: DeclarativeStream + name: customers + primary_key: + - customerNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /customers + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + pagination_strategy: + type: PageIncrement + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers" + departmental_distributions: + type: DeclarativeStream + name: departmental_distributions + primary_key: + - departmentalDistributionNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /departmental-distributions + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/departmental_distributions" + departments: + type: DeclarativeStream + name: departments + primary_key: + - departmentNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /departments + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/departments" + employees: + type: DeclarativeStream + name: employees + primary_key: + - employeeNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /employees + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + pagination_strategy: + type: PageIncrement + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/employees" + journals: + type: DeclarativeStream + name: journals + primary_key: + - journalNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /journals + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/journals" + payment_terms: + type: DeclarativeStream + name: payment_terms + primary_key: + - paymentTermsNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /payment-terms + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/payment_terms" + payment_types: + type: DeclarativeStream + name: payment_types + primary_key: + - paymentTypeNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /payment-types + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/payment_types" + product_groups: + type: DeclarativeStream + name: product_groups + primary_key: + - productGroupNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /product-groups + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/product_groups" + products: + type: DeclarativeStream + name: products + primary_key: + - productNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /products + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + draft_quotes: + type: DeclarativeStream + name: draft_quotes + primary_key: + - quoteNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /quotes/drafts + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/draft_quotes" + suppliers: + type: DeclarativeStream + name: suppliers + primary_key: + - supplierNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /suppliers + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/suppliers" + units: + type: DeclarativeStream + name: units + primary_key: + - unitNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /units + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/units" + vat_accounts: + type: DeclarativeStream + name: vat_accounts + primary_key: + - vatCode + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /vat-accounts + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/vat_accounts" + vat_types: + type: DeclarativeStream + name: vat_types + primary_key: + - vatTypeNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /vat-types + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/vat_types" + vat_zones: + type: DeclarativeStream + name: vat_zones + primary_key: + - vatZoneNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /vat-zones + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/vat_zones" + sent_quotes: + type: DeclarativeStream + name: sent_quotes + primary_key: + - quoteNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /quotes/sent + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sent_quotes" + archived_quotes: + type: DeclarativeStream + name: archived_quotes + primary_key: + - quoteNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /quotes/archived + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/archived_quotes" + draft_invoices: + type: DeclarativeStream + name: draft_invoices + primary_key: + - draftInvoiceNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /invoices/drafts + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/draft_invoices" + booked_invoices: + type: DeclarativeStream + name: booked_invoices + primary_key: + - bookedInvoiceNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /invoices/booked + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/booked_invoices" + paid_invoices: + type: DeclarativeStream + name: paid_invoices + primary_key: + - bookedInvoiceNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /invoices/paid + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/paid_invoices" + overdue_invoices: + type: DeclarativeStream + name: overdue_invoices + primary_key: + - bookedInvoiceNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /invoices/overdue + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/overdue_invoices" + unpaid_invoices: + type: DeclarativeStream + name: unpaid_invoices + primary_key: + - bookedInvoiceNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /invoices/unpaid + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/unpaid_invoices" + not_due_invoices: + type: DeclarativeStream + name: not_due_invoices + primary_key: + - bookedInvoiceNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /invoices/not-due + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/not_due_invoices" + total_invoices: + type: DeclarativeStream + name: total_invoices + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /invoices/totals + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/total_invoices" + sent_invoices: + type: DeclarativeStream + name: sent_invoices + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /invoices/sent + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sent_invoices" + draft_orders: + type: DeclarativeStream + name: draft_orders + primary_key: + - orderNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /orders/drafts + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/draft_orders" + sent_orders: + type: DeclarativeStream + name: sent_orders + primary_key: + - orderNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /orders/sent + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sent_orders" + archived_orders: + type: DeclarativeStream + name: archived_orders + primary_key: + - orderNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /orders/archived + http_method: GET + request_headers: + X-AgreementGrantToken: "{{ config[\"agreement_grant_token\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collection + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skippages + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/archived_orders" + base_requester: + type: HttpRequester + url_base: https://restapi.e-conomic.com + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"app_secret_token\"] }}" + inject_into: + type: RequestOption + field_name: X-AppSecretToken + inject_into: header + +streams: + - $ref: "#/definitions/streams/accounts" + - $ref: "#/definitions/streams/accounting_years" + - $ref: "#/definitions/streams/app_roles" + - $ref: "#/definitions/streams/currencies" + - $ref: "#/definitions/streams/customer_groups" + - $ref: "#/definitions/streams/customers" + - $ref: "#/definitions/streams/departmental_distributions" + - $ref: "#/definitions/streams/departments" + - $ref: "#/definitions/streams/employees" + - $ref: "#/definitions/streams/journals" + - $ref: "#/definitions/streams/payment_terms" + - $ref: "#/definitions/streams/payment_types" + - $ref: "#/definitions/streams/product_groups" + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/draft_quotes" + - $ref: "#/definitions/streams/suppliers" + - $ref: "#/definitions/streams/units" + - $ref: "#/definitions/streams/vat_accounts" + - $ref: "#/definitions/streams/vat_types" + - $ref: "#/definitions/streams/vat_zones" + - $ref: "#/definitions/streams/sent_quotes" + - $ref: "#/definitions/streams/archived_quotes" + - $ref: "#/definitions/streams/draft_invoices" + - $ref: "#/definitions/streams/booked_invoices" + - $ref: "#/definitions/streams/paid_invoices" + - $ref: "#/definitions/streams/overdue_invoices" + - $ref: "#/definitions/streams/unpaid_invoices" + - $ref: "#/definitions/streams/not_due_invoices" + - $ref: "#/definitions/streams/total_invoices" + - $ref: "#/definitions/streams/sent_invoices" + - $ref: "#/definitions/streams/draft_orders" + - $ref: "#/definitions/streams/sent_orders" + - $ref: "#/definitions/streams/archived_orders" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - app_secret_token + - agreement_grant_token + properties: + app_secret_token: + type: string + description: >- + Your private token that identifies your app. Find it in your e-conomic + account settings. + name: app_secret_token + order: 0 + title: App Secret Token + airbyte_secret: true + agreement_grant_token: + type: string + description: >- + Token that identifies the grant issued by an agreement, allowing your + app to access data. Obtain it from your e-conomic account settings. + name: agreement_grant_token + order: 1 + title: Agreement Grant Token + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + accounts: true + accounting_years: true + app_roles: true + currencies: true + customer_groups: true + customers: true + departmental_distributions: true + departments: true + employees: true + journals: true + payment_terms: true + payment_types: true + product_groups: true + products: true + draft_quotes: true + suppliers: true + units: true + vat_accounts: true + vat_types: true + vat_zones: true + sent_quotes: true + archived_quotes: true + draft_invoices: true + booked_invoices: true + paid_invoices: true + overdue_invoices: true + unpaid_invoices: true + not_due_invoices: true + total_invoices: true + sent_invoices: true + draft_orders: true + sent_orders: true + archived_orders: true + testedStreams: + accounts: + streamHash: 6a371091607a986dca813986d16550c09796b415 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + accounting_years: + streamHash: e35ac7344fe85423f7234037f3ed7749ac9a2fe4 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + app_roles: + streamHash: faa17330b5271e80f45fbc2e0a332e9a9bf9edf1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + currencies: + streamHash: e443e91efc903cf7710924c1735986d7440a6d39 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + customer_groups: + streamHash: 1b6df748b66eee85b8d393a464c9c1a691fd67a3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + customers: + streamHash: 83b089497ee6a436e14b36c49fba56e943f9ebf8 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + departmental_distributions: + streamHash: 0f2cb5c746e7893b09e879960cbf771260ea02e4 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + departments: + streamHash: 2eb947e493f69fdd2b782f7086b7e00452ff7d4b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + employees: + streamHash: 8ab6eb85a94cb55800699aee9bc1cdb4423a0aac + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + journals: + hasRecords: true + streamHash: 17082ac31ac7ae4042e435352ea51f67df66811b + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + payment_terms: + hasRecords: true + streamHash: 80678e3509f1b7807160bbed2eb46a36a96dcfec + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + payment_types: + hasRecords: true + streamHash: 647ace19e558c93db93df03a718ce0bbd86c68bd + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + product_groups: + hasRecords: true + streamHash: ffba46fa0aaeb9c4b524d03144c35525bd5d3a66 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + products: + hasRecords: true + streamHash: 1c22486b1ecc86dc4d93eb3d07a3df120a0ee2b0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + draft_quotes: + hasRecords: true + streamHash: 661b079c0d711e505664ac00305c558dfe3f85da + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + suppliers: + hasRecords: true + streamHash: 9b870e076ec25245410e1b8c41e5360cd314c767 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + units: + hasRecords: true + streamHash: 927ee6a8e8b4c495fbb1d3a0f875024927b8bc3e + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + vat_accounts: + hasRecords: true + streamHash: d648c65212720ae7566dcaf6490aa8c77819e727 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + vat_types: + streamHash: da01a6fe5788c9691bff4162a84d8e1e582cae71 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + vat_zones: + hasRecords: true + streamHash: 0fa9e2e89ec6c86e0b25ad8b9d0119cd783845b4 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + sent_quotes: + hasRecords: true + streamHash: e699b8627cfebb701e67e0a0ab7224cc14409c08 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + archived_quotes: + hasRecords: true + streamHash: 34390dc5c1a7930c2f853b6f5a5368a975064587 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + draft_invoices: + hasRecords: true + streamHash: 81fdb385e3ec7784cc651f02538d73f663ac8a12 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + booked_invoices: + hasRecords: true + streamHash: 3dbe9119db1773a399c68ab03a3a7e46451271c5 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + paid_invoices: + hasRecords: true + streamHash: c2def7996a523fdd39d61321ee95fda20aef5fa2 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + overdue_invoices: + hasRecords: true + streamHash: d28ffc6647c9573fc9674463a27f53a2fece5644 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + unpaid_invoices: + hasRecords: true + streamHash: 7f130cdbb35c2979359ccf682b34048a7a7c076d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + not_due_invoices: + hasRecords: true + streamHash: e95ee49bc140964d503705fa50a061f6729efa6c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + total_invoices: + hasRecords: true + streamHash: 4a4609ed6304e3bb96bc939414e4de1674db58b1 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + sent_invoices: + hasRecords: true + streamHash: 1aa39528ce530e5c8457cc2b86a069d46aa65752 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + draft_orders: + hasRecords: true + streamHash: 02a8e3b65f4fa0c2dd3b7c24ebc02e68983522ad + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + sent_orders: + hasRecords: true + streamHash: 5f5d474a1f2867069de0ff0e7b537813ddcde6c2 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + archived_orders: + hasRecords: true + streamHash: e855cf3c70f39c24492ebac8549babf73f781603 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://restdocs.e-conomic.com/ + +schemas: + accounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accountNumber: + type: number + accountType: + type: + - string + - "null" + accountingYears: + type: + - string + - "null" + balance: + type: + - number + - "null" + blockDirectEntries: + type: + - boolean + - "null" + debitCredit: + type: + - string + - "null" + department: + type: + - object + - "null" + properties: + departmentNumber: + type: + - number + - "null" + name: + type: + - string + - "null" + self: + type: + - string + - "null" + departmentalDistribution: + type: + - object + - "null" + properties: + departmentalDistributionNumber: + type: + - number + - "null" + distributionType: + type: + - string + - "null" + self: + type: + - string + - "null" + name: + type: + - string + - "null" + self: + type: + - string + - "null" + totalFromAccount: + type: + - object + - "null" + properties: + accountNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + vatAccount: + type: + - object + - "null" + properties: + self: + type: + - string + - "null" + vatCode: + type: + - string + - "null" + required: + - accountNumber + accounting_years: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + entries: + type: + - string + - "null" + fromDate: + type: + - string + - "null" + periods: + type: + - string + - "null" + self: + type: + - string + - "null" + toDate: + type: + - string + - "null" + totals: + type: + - string + - "null" + vouchers: + type: + - string + - "null" + year: + type: string + required: + - year + app_roles: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + name: + type: + - string + - "null" + requiredModules: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + moduleNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + roleNumber: + type: number + required: + - roleNumber + currencies: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + code: + type: string + isoNumber: + type: + - string + - "null" + name: + type: + - string + - "null" + self: + type: + - string + - "null" + required: + - code + customer_groups: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account: + type: + - object + - "null" + properties: + accountNumber: + type: + - number + - "null" + accountType: + type: + - string + - "null" + accountingYears: + type: + - string + - "null" + balance: + type: + - number + - "null" + blockDirectEntries: + type: + - boolean + - "null" + debitCredit: + type: + - string + - "null" + name: + type: + - string + - "null" + openingAccount: + type: + - object + - "null" + properties: + accountNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + self: + type: + - string + - "null" + customerGroupNumber: + type: number + customers: + type: + - string + - "null" + name: + type: + - string + - "null" + self: + type: + - string + - "null" + required: + - customerGroupNumber + customers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address: + type: + - string + - "null" + attention: + type: + - object + - "null" + properties: + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + balance: + type: + - number + - "null" + barred: + type: + - boolean + - "null" + city: + type: + - string + - "null" + contacts: + type: + - string + - "null" + corporateIdentificationNumber: + type: + - string + - "null" + country: + type: + - string + - "null" + currency: + type: + - string + - "null" + customerContact: + type: + - object + - "null" + properties: + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + customerGroup: + type: + - object + - "null" + properties: + customerGroupNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + customerNumber: + type: number + defaultDeliveryLocation: + type: + - object + - "null" + properties: + deliveryLocationNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + deliveryLocations: + type: + - string + - "null" + dueAmount: + type: + - number + - "null" + eInvoicingDisabledByDefault: + type: + - boolean + - "null" + ean: + type: + - string + - "null" + email: + type: + - string + - "null" + invoices: + type: + - object + - "null" + properties: + booked: + type: + - string + - "null" + drafts: + type: + - string + - "null" + self: + type: + - string + - "null" + lastUpdated: + type: + - string + - "null" + mobilePhone: + type: + - string + - "null" + name: + type: + - string + - "null" + paymentTerms: + type: + - object + - "null" + properties: + paymentTermsNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + salesPerson: + type: + - object + - "null" + properties: + employeeNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + self: + type: + - string + - "null" + telephoneAndFaxNumber: + type: + - string + - "null" + templates: + type: + - object + - "null" + properties: + invoice: + type: + - string + - "null" + invoiceLine: + type: + - string + - "null" + self: + type: + - string + - "null" + totals: + type: + - object + - "null" + properties: + booked: + type: + - string + - "null" + drafts: + type: + - string + - "null" + self: + type: + - string + - "null" + vatZone: + type: + - object + - "null" + properties: + self: + type: + - string + - "null" + vatZoneNumber: + type: + - number + - "null" + zip: + type: + - string + - "null" + required: + - customerNumber + departmental_distributions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + barred: + type: + - boolean + - "null" + departmentalDistributionNumber: + type: number + distributionType: + type: + - string + - "null" + distributions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + department: + type: + - object + - "null" + properties: + departmentNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + percentage: + type: + - number + - "null" + name: + type: + - string + - "null" + self: + type: + - string + - "null" + required: + - departmentalDistributionNumber + departments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + barred: + type: + - boolean + - "null" + departmentNumber: + type: number + name: + type: + - string + - "null" + self: + type: + - string + - "null" + required: + - departmentNumber + employees: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + barred: + type: + - boolean + - "null" + bookedInvoices: + type: + - string + - "null" + customers: + type: + - string + - "null" + draftInvoices: + type: + - string + - "null" + email: + type: + - string + - "null" + employeeGroup: + type: + - object + - "null" + properties: + employeeGroupNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + employeeNumber: + type: number + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + self: + type: + - string + - "null" + required: + - employeeNumber + journals: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + entries: + type: + - string + - "null" + journalNumber: + type: number + name: + type: + - string + - "null" + self: + type: + - string + - "null" + settings: + type: + - object + - "null" + properties: + contraAccounts: + type: + - object + - "null" + properties: + customerPayments: + type: + - object + - "null" + properties: + accountNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + entryTypeRestrictedTo: + type: + - string + - "null" + voucherNumbers: + type: + - object + - "null" + properties: + minimumVoucherNumber: + type: + - number + - "null" + templates: + type: + - object + - "null" + properties: + financeVoucher: + type: + - string + - "null" + manualCustomerInvoice: + type: + - string + - "null" + self: + type: + - string + - "null" + vouchers: + type: + - string + - "null" + required: + - journalNumber + payment_terms: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + contraAccountForPrepaidAmount: + type: + - object + - "null" + properties: + accountNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + creditCardCompany: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + daysOfCredit: + type: + - number + - "null" + name: + type: + - string + - "null" + paymentTermsNumber: + type: number + paymentTermsType: + type: + - string + - "null" + self: + type: + - string + - "null" + required: + - paymentTermsNumber + payment_types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + name: + type: + - string + - "null" + paymentTypeNumber: + type: number + self: + type: + - string + - "null" + required: + - paymentTypeNumber + product_groups: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accrual: + type: + - object + - "null" + properties: + accountNumber: + type: + - number + - "null" + accountType: + type: + - string + - "null" + accountingYears: + type: + - string + - "null" + balance: + type: + - number + - "null" + blockDirectEntries: + type: + - boolean + - "null" + debitCredit: + type: + - string + - "null" + name: + type: + - string + - "null" + self: + type: + - string + - "null" + vatAccount: + type: + - object + - "null" + properties: + self: + type: + - string + - "null" + vatCode: + type: + - string + - "null" + name: + type: + - string + - "null" + productGroupNumber: + type: number + products: + type: + - string + - "null" + salesAccounts: + type: + - string + - "null" + self: + type: + - string + - "null" + required: + - productGroupNumber + products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + barCode: + type: + - string + - "null" + barred: + type: + - boolean + - "null" + costPrice: + type: + - number + - "null" + invoices: + type: + - object + - "null" + properties: + booked: + type: + - string + - "null" + drafts: + type: + - string + - "null" + self: + type: + - string + - "null" + lastUpdated: + type: + - string + - "null" + minimumStock: + type: + - number + - "null" + name: + type: + - string + - "null" + pricing: + type: + - object + - "null" + properties: + currencySpecificSalesPrices: + type: + - string + - "null" + productGroup: + type: + - object + - "null" + properties: + accrual: + type: + - object + - "null" + properties: + accountNumber: + type: + - number + - "null" + accountType: + type: + - string + - "null" + accountingYears: + type: + - string + - "null" + balance: + type: + - number + - "null" + blockDirectEntries: + type: + - boolean + - "null" + debitCredit: + type: + - string + - "null" + name: + type: + - string + - "null" + self: + type: + - string + - "null" + vatAccount: + type: + - object + - "null" + properties: + self: + type: + - string + - "null" + vatCode: + type: + - string + - "null" + name: + type: + - string + - "null" + productGroupNumber: + type: + - number + - "null" + products: + type: + - string + - "null" + salesAccounts: + type: + - string + - "null" + self: + type: + - string + - "null" + productNumber: + type: string + recommendedPrice: + type: + - number + - "null" + salesPrice: + type: + - number + - "null" + self: + type: + - string + - "null" + unit: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + products: + type: + - string + - "null" + self: + type: + - string + - "null" + unitNumber: + type: + - number + - "null" + required: + - productNumber + draft_quotes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attachment: + type: + - string + - "null" + costPriceInBaseCurrency: + type: + - number + - "null" + currency: + type: + - string + - "null" + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + date: + type: + - string + - "null" + delivery: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + zip: + type: + - string + - "null" + deliveryLocation: + type: + - object + - "null" + properties: + deliveryLocationNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + exchangeRate: + type: + - number + - "null" + grossAmount: + type: + - number + - "null" + grossAmountInBaseCurrency: + type: + - number + - "null" + lastUpdated: + type: + - string + - "null" + layout: + type: + - object + - "null" + properties: + layoutNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + lines: + type: + - array + - "null" + marginInBaseCurrency: + type: + - number + - "null" + marginPercentage: + type: + - number + - "null" + netAmount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + orderNumberDb: + type: + - number + - "null" + paymentTerms: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + daysOfCredit: + type: + - number + - "null" + name: + type: + - string + - "null" + paymentTermsNumber: + type: + - number + - "null" + paymentTermsType: + type: + - string + - "null" + self: + type: + - string + - "null" + pdf: + type: + - object + - "null" + properties: + download: + type: + - string + - "null" + quoteNumber: + type: number + recipient: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + attention: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + cvr: + type: + - string + - "null" + ean: + type: + - string + - "null" + mobilePhone: + type: + - string + - "null" + name: + type: + - string + - "null" + nemHandelType: + type: + - string + - "null" + vatZone: + type: + - object + - "null" + properties: + self: + type: + - string + - "null" + vatZoneNumber: + type: + - number + - "null" + zip: + type: + - string + - "null" + references: + type: + - object + - "null" + properties: + customerContact: + type: + - object + - "null" + properties: + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + salesPerson: + type: + - object + - "null" + properties: + employeeNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + roundingAmount: + type: + - number + - "null" + salesDocumentType: + type: + - string + - "null" + self: + type: + - string + - "null" + soap: + type: + - object + - "null" + properties: + quoteHandle: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + templates: + type: + - object + - "null" + properties: + draftInvoiceUpgradeInstructions: + type: + - string + - "null" + orderUpgradeInstructions: + type: + - string + - "null" + self: + type: + - string + - "null" + vatAmount: + type: + - number + - "null" + required: + - quoteNumber + suppliers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address: + type: + - string + - "null" + attention: + type: + - object + - "null" + properties: + number: + type: + - number + - "null" + self: + type: + - string + - "null" + bankAccount: + type: + - string + - "null" + city: + type: + - string + - "null" + contacts: + type: + - string + - "null" + costAccount: + type: + - object + - "null" + properties: + accountNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + country: + type: + - string + - "null" + currency: + type: + - string + - "null" + defaultInvoiceText: + type: + - string + - "null" + email: + type: + - string + - "null" + layout: + type: + - object + - "null" + properties: + layoutNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + metaData: + type: + - object + - "null" + properties: + delete: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + href: + type: + - string + - "null" + httpMethod: + type: + - string + - "null" + name: + type: + - string + - "null" + paymentTerms: + type: + - object + - "null" + properties: + paymentTermsNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + phone: + type: + - string + - "null" + remittanceAdvice: + type: + - object + - "null" + properties: + creditorId: + type: + - string + - "null" + paymentType: + type: + - object + - "null" + properties: + paymentTypeNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + salesPerson: + type: + - object + - "null" + properties: + employeeNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + self: + type: + - string + - "null" + supplierContact: + type: + - object + - "null" + properties: + number: + type: + - number + - "null" + self: + type: + - string + - "null" + supplierGroup: + type: + - object + - "null" + properties: + self: + type: + - string + - "null" + supplierGroupNumber: + type: + - number + - "null" + supplierNumber: + type: number + vatZone: + type: + - object + - "null" + properties: + self: + type: + - string + - "null" + vatZoneNumber: + type: + - number + - "null" + zip: + type: + - string + - "null" + required: + - supplierNumber + units: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + name: + type: + - string + - "null" + products: + type: + - string + - "null" + self: + type: + - string + - "null" + unitNumber: + type: number + required: + - unitNumber + vat_accounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account: + type: + - object + - "null" + properties: + accountNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + contraAccount: + type: + - object + - "null" + properties: + accountNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + name: + type: + - string + - "null" + ratePercentage: + type: + - number + - "null" + self: + type: + - string + - "null" + vatCode: + type: string + vatType: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + self: + type: + - string + - "null" + vatTypeNumber: + type: + - number + - "null" + required: + - vatCode + vat_types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + name: + type: + - string + - "null" + self: + type: + - string + - "null" + vatTypeNumber: + type: number + required: + - vatTypeNumber + vat_zones: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + enabledForCustomer: + type: + - boolean + - "null" + enabledForSupplier: + type: + - boolean + - "null" + name: + type: + - string + - "null" + self: + type: + - string + - "null" + vatZoneNumber: + type: number + required: + - vatZoneNumber + sent_quotes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attachment: + type: + - string + - "null" + costPriceInBaseCurrency: + type: + - number + - "null" + currency: + type: + - string + - "null" + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + date: + type: + - string + - "null" + delivery: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + zip: + type: + - string + - "null" + deliveryLocation: + type: + - object + - "null" + properties: + deliveryLocationNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + exchangeRate: + type: + - number + - "null" + grossAmount: + type: + - number + - "null" + grossAmountInBaseCurrency: + type: + - number + - "null" + lastUpdated: + type: + - string + - "null" + layout: + type: + - object + - "null" + properties: + layoutNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + lines: + type: + - array + - "null" + marginInBaseCurrency: + type: + - number + - "null" + marginPercentage: + type: + - number + - "null" + netAmount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + orderNumberDb: + type: + - number + - "null" + paymentTerms: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + daysOfCredit: + type: + - number + - "null" + name: + type: + - string + - "null" + paymentTermsNumber: + type: + - number + - "null" + paymentTermsType: + type: + - string + - "null" + self: + type: + - string + - "null" + pdf: + type: + - object + - "null" + properties: + download: + type: + - string + - "null" + quoteNumber: + type: number + recipient: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + attention: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + cvr: + type: + - string + - "null" + ean: + type: + - string + - "null" + mobilePhone: + type: + - string + - "null" + name: + type: + - string + - "null" + nemHandelType: + type: + - string + - "null" + vatZone: + type: + - object + - "null" + properties: + self: + type: + - string + - "null" + vatZoneNumber: + type: + - number + - "null" + zip: + type: + - string + - "null" + references: + type: + - object + - "null" + properties: + customerContact: + type: + - object + - "null" + properties: + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + salesPerson: + type: + - object + - "null" + properties: + employeeNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + roundingAmount: + type: + - number + - "null" + salesDocumentType: + type: + - string + - "null" + self: + type: + - string + - "null" + soap: + type: + - object + - "null" + properties: + quoteHandle: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + templates: + type: + - object + - "null" + properties: + draftInvoiceUpgradeInstructions: + type: + - string + - "null" + orderUpgradeInstructions: + type: + - string + - "null" + self: + type: + - string + - "null" + vatAmount: + type: + - number + - "null" + required: + - quoteNumber + archived_quotes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attachment: + type: + - string + - "null" + costPriceInBaseCurrency: + type: + - number + - "null" + currency: + type: + - string + - "null" + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + date: + type: + - string + - "null" + delivery: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + zip: + type: + - string + - "null" + deliveryLocation: + type: + - object + - "null" + properties: + deliveryLocationNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + exchangeRate: + type: + - number + - "null" + grossAmount: + type: + - number + - "null" + grossAmountInBaseCurrency: + type: + - number + - "null" + lastUpdated: + type: + - string + - "null" + layout: + type: + - object + - "null" + properties: + layoutNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + lines: + type: + - array + - "null" + marginInBaseCurrency: + type: + - number + - "null" + marginPercentage: + type: + - number + - "null" + netAmount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + orderNumberDb: + type: + - number + - "null" + paymentTerms: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + daysOfCredit: + type: + - number + - "null" + name: + type: + - string + - "null" + paymentTermsNumber: + type: + - number + - "null" + paymentTermsType: + type: + - string + - "null" + self: + type: + - string + - "null" + pdf: + type: + - object + - "null" + properties: + download: + type: + - string + - "null" + quoteNumber: + type: number + recipient: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + attention: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + cvr: + type: + - string + - "null" + ean: + type: + - string + - "null" + mobilePhone: + type: + - string + - "null" + name: + type: + - string + - "null" + nemHandelType: + type: + - string + - "null" + vatZone: + type: + - object + - "null" + properties: + self: + type: + - string + - "null" + vatZoneNumber: + type: + - number + - "null" + zip: + type: + - string + - "null" + references: + type: + - object + - "null" + properties: + customerContact: + type: + - object + - "null" + properties: + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + salesPerson: + type: + - object + - "null" + properties: + employeeNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + roundingAmount: + type: + - number + - "null" + salesDocumentType: + type: + - string + - "null" + self: + type: + - string + - "null" + soap: + type: + - object + - "null" + properties: + quoteHandle: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + templates: + type: + - object + - "null" + properties: + draftInvoiceUpgradeInstructions: + type: + - string + - "null" + orderUpgradeInstructions: + type: + - string + - "null" + self: + type: + - string + - "null" + vatAmount: + type: + - number + - "null" + required: + - quoteNumber + draft_invoices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attachment: + type: + - string + - "null" + costPriceInBaseCurrency: + type: + - number + - "null" + currency: + type: + - string + - "null" + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + date: + type: + - string + - "null" + delivery: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + zip: + type: + - string + - "null" + deliveryLocation: + type: + - object + - "null" + properties: + deliveryLocationNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + draftInvoiceNumber: + type: number + dueDate: + type: + - string + - "null" + exchangeRate: + type: + - number + - "null" + grossAmount: + type: + - number + - "null" + grossAmountInBaseCurrency: + type: + - number + - "null" + lastUpdated: + type: + - string + - "null" + layout: + type: + - object + - "null" + properties: + layoutNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + marginInBaseCurrency: + type: + - number + - "null" + marginPercentage: + type: + - number + - "null" + netAmount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + notes: + type: + - object + - "null" + properties: + heading: + type: + - string + - "null" + textLine1: + type: + - string + - "null" + textLine2: + type: + - string + - "null" + orderNumberDb: + type: + - number + - "null" + paymentTerms: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + daysOfCredit: + type: + - number + - "null" + name: + type: + - string + - "null" + paymentTermsNumber: + type: + - number + - "null" + paymentTermsType: + type: + - string + - "null" + self: + type: + - string + - "null" + pdf: + type: + - object + - "null" + properties: + download: + type: + - string + - "null" + project: + type: + - object + - "null" + properties: + projectNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + recipient: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + attention: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + cvr: + type: + - string + - "null" + ean: + type: + - string + - "null" + mobilePhone: + type: + - string + - "null" + name: + type: + - string + - "null" + nemHandelType: + type: + - string + - "null" + vatZone: + type: + - object + - "null" + properties: + enabledForCustomer: + type: + - boolean + - "null" + enabledForSupplier: + type: + - boolean + - "null" + name: + type: + - string + - "null" + self: + type: + - string + - "null" + vatZoneNumber: + type: + - number + - "null" + zip: + type: + - string + - "null" + references: + type: + - object + - "null" + properties: + customerContact: + type: + - object + - "null" + properties: + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + other: + type: + - string + - "null" + salesPerson: + type: + - object + - "null" + properties: + employeeNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + vendorReference: + type: + - object + - "null" + properties: + employeeNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + roundingAmount: + type: + - number + - "null" + self: + type: + - string + - "null" + soap: + type: + - object + - "null" + properties: + currentInvoiceHandle: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + templates: + type: + - object + - "null" + properties: + bookingInstructions: + type: + - string + - "null" + self: + type: + - string + - "null" + vatAmount: + type: + - number + - "null" + required: + - draftInvoiceNumber + booked_invoices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + bookedInvoiceNumber: + type: number + currency: + type: + - string + - "null" + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + date: + type: + - string + - "null" + delivery: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + zip: + type: + - string + - "null" + deliveryLocation: + type: + - object + - "null" + properties: + deliveryLocationNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + exchangeRate: + type: + - number + - "null" + grossAmount: + type: + - number + - "null" + grossAmountInBaseCurrency: + type: + - number + - "null" + layout: + type: + - object + - "null" + properties: + layoutNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + netAmount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + notes: + type: + - object + - "null" + properties: + heading: + type: + - string + - "null" + textLine1: + type: + - string + - "null" + textLine2: + type: + - string + - "null" + orderNumber: + type: + - number + - "null" + paymentTerms: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + daysOfCredit: + type: + - number + - "null" + name: + type: + - string + - "null" + paymentTermsNumber: + type: + - number + - "null" + paymentTermsType: + type: + - string + - "null" + self: + type: + - string + - "null" + pdf: + type: + - object + - "null" + properties: + download: + type: + - string + - "null" + project: + type: + - object + - "null" + properties: + projectNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + recipient: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + attention: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + ean: + type: + - string + - "null" + name: + type: + - string + - "null" + vatZone: + type: + - object + - "null" + properties: + enabledForCustomer: + type: + - boolean + - "null" + enabledForSupplier: + type: + - boolean + - "null" + name: + type: + - string + - "null" + self: + type: + - string + - "null" + vatZoneNumber: + type: + - number + - "null" + zip: + type: + - string + - "null" + references: + type: + - object + - "null" + properties: + customerContact: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + salesPerson: + type: + - object + - "null" + properties: + employeeNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + remainder: + type: + - number + - "null" + remainderInBaseCurrency: + type: + - number + - "null" + roundingAmount: + type: + - number + - "null" + self: + type: + - string + - "null" + sent: + type: + - string + - "null" + vatAmount: + type: + - number + - "null" + required: + - bookedInvoiceNumber + paid_invoices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + bookedInvoiceNumber: + type: number + currency: + type: + - string + - "null" + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + date: + type: + - string + - "null" + delivery: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + zip: + type: + - string + - "null" + deliveryLocation: + type: + - object + - "null" + properties: + deliveryLocationNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + exchangeRate: + type: + - number + - "null" + grossAmount: + type: + - number + - "null" + grossAmountInBaseCurrency: + type: + - number + - "null" + layout: + type: + - object + - "null" + properties: + layoutNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + netAmount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + notes: + type: + - object + - "null" + properties: + heading: + type: + - string + - "null" + orderNumber: + type: + - number + - "null" + paymentTerms: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + daysOfCredit: + type: + - number + - "null" + name: + type: + - string + - "null" + paymentTermsNumber: + type: + - number + - "null" + paymentTermsType: + type: + - string + - "null" + self: + type: + - string + - "null" + pdf: + type: + - object + - "null" + properties: + download: + type: + - string + - "null" + project: + type: + - object + - "null" + properties: + projectNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + recipient: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + attention: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + ean: + type: + - string + - "null" + name: + type: + - string + - "null" + vatZone: + type: + - object + - "null" + properties: + enabledForCustomer: + type: + - boolean + - "null" + enabledForSupplier: + type: + - boolean + - "null" + name: + type: + - string + - "null" + self: + type: + - string + - "null" + vatZoneNumber: + type: + - number + - "null" + zip: + type: + - string + - "null" + references: + type: + - object + - "null" + properties: + customerContact: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + salesPerson: + type: + - object + - "null" + properties: + employeeNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + remainder: + type: + - number + - "null" + remainderInBaseCurrency: + type: + - number + - "null" + roundingAmount: + type: + - number + - "null" + self: + type: + - string + - "null" + sent: + type: + - string + - "null" + vatAmount: + type: + - number + - "null" + required: + - bookedInvoiceNumber + overdue_invoices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + bookedInvoiceNumber: + type: number + currency: + type: + - string + - "null" + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + date: + type: + - string + - "null" + delivery: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + zip: + type: + - string + - "null" + deliveryLocation: + type: + - object + - "null" + properties: + deliveryLocationNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + exchangeRate: + type: + - number + - "null" + grossAmount: + type: + - number + - "null" + grossAmountInBaseCurrency: + type: + - number + - "null" + layout: + type: + - object + - "null" + properties: + layoutNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + netAmount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + notes: + type: + - object + - "null" + properties: + heading: + type: + - string + - "null" + textLine1: + type: + - string + - "null" + textLine2: + type: + - string + - "null" + orderNumber: + type: + - number + - "null" + paymentTerms: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + daysOfCredit: + type: + - number + - "null" + name: + type: + - string + - "null" + paymentTermsNumber: + type: + - number + - "null" + paymentTermsType: + type: + - string + - "null" + self: + type: + - string + - "null" + pdf: + type: + - object + - "null" + properties: + download: + type: + - string + - "null" + project: + type: + - object + - "null" + properties: + projectNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + recipient: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + attention: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + ean: + type: + - string + - "null" + name: + type: + - string + - "null" + vatZone: + type: + - object + - "null" + properties: + enabledForCustomer: + type: + - boolean + - "null" + enabledForSupplier: + type: + - boolean + - "null" + name: + type: + - string + - "null" + self: + type: + - string + - "null" + vatZoneNumber: + type: + - number + - "null" + zip: + type: + - string + - "null" + references: + type: + - object + - "null" + properties: + customerContact: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + salesPerson: + type: + - object + - "null" + properties: + employeeNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + remainder: + type: + - number + - "null" + remainderInBaseCurrency: + type: + - number + - "null" + roundingAmount: + type: + - number + - "null" + self: + type: + - string + - "null" + sent: + type: + - string + - "null" + vatAmount: + type: + - number + - "null" + required: + - bookedInvoiceNumber + unpaid_invoices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + bookedInvoiceNumber: + type: number + currency: + type: + - string + - "null" + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + date: + type: + - string + - "null" + delivery: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + zip: + type: + - string + - "null" + deliveryLocation: + type: + - object + - "null" + properties: + deliveryLocationNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + exchangeRate: + type: + - number + - "null" + grossAmount: + type: + - number + - "null" + grossAmountInBaseCurrency: + type: + - number + - "null" + layout: + type: + - object + - "null" + properties: + layoutNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + netAmount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + notes: + type: + - object + - "null" + properties: + heading: + type: + - string + - "null" + textLine1: + type: + - string + - "null" + textLine2: + type: + - string + - "null" + orderNumber: + type: + - number + - "null" + paymentTerms: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + daysOfCredit: + type: + - number + - "null" + name: + type: + - string + - "null" + paymentTermsNumber: + type: + - number + - "null" + paymentTermsType: + type: + - string + - "null" + self: + type: + - string + - "null" + pdf: + type: + - object + - "null" + properties: + download: + type: + - string + - "null" + project: + type: + - object + - "null" + properties: + projectNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + recipient: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + attention: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + ean: + type: + - string + - "null" + name: + type: + - string + - "null" + vatZone: + type: + - object + - "null" + properties: + enabledForCustomer: + type: + - boolean + - "null" + enabledForSupplier: + type: + - boolean + - "null" + name: + type: + - string + - "null" + self: + type: + - string + - "null" + vatZoneNumber: + type: + - number + - "null" + zip: + type: + - string + - "null" + references: + type: + - object + - "null" + properties: + customerContact: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + salesPerson: + type: + - object + - "null" + properties: + employeeNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + remainder: + type: + - number + - "null" + remainderInBaseCurrency: + type: + - number + - "null" + roundingAmount: + type: + - number + - "null" + self: + type: + - string + - "null" + sent: + type: + - string + - "null" + vatAmount: + type: + - number + - "null" + required: + - bookedInvoiceNumber + not_due_invoices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + bookedInvoiceNumber: + type: number + currency: + type: + - string + - "null" + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + date: + type: + - string + - "null" + delivery: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + zip: + type: + - string + - "null" + deliveryLocation: + type: + - object + - "null" + properties: + deliveryLocationNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + exchangeRate: + type: + - number + - "null" + grossAmount: + type: + - number + - "null" + grossAmountInBaseCurrency: + type: + - number + - "null" + layout: + type: + - object + - "null" + properties: + layoutNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + netAmount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + notes: + type: + - object + - "null" + properties: + heading: + type: + - string + - "null" + textLine1: + type: + - string + - "null" + textLine2: + type: + - string + - "null" + orderNumber: + type: + - number + - "null" + paymentTerms: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + daysOfCredit: + type: + - number + - "null" + name: + type: + - string + - "null" + paymentTermsNumber: + type: + - number + - "null" + paymentTermsType: + type: + - string + - "null" + self: + type: + - string + - "null" + pdf: + type: + - object + - "null" + properties: + download: + type: + - string + - "null" + project: + type: + - object + - "null" + properties: + projectNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + recipient: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + attention: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + ean: + type: + - string + - "null" + name: + type: + - string + - "null" + vatZone: + type: + - object + - "null" + properties: + enabledForCustomer: + type: + - boolean + - "null" + enabledForSupplier: + type: + - boolean + - "null" + name: + type: + - string + - "null" + self: + type: + - string + - "null" + vatZoneNumber: + type: + - number + - "null" + zip: + type: + - string + - "null" + references: + type: + - object + - "null" + properties: + customerContact: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + salesPerson: + type: + - object + - "null" + properties: + employeeNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + remainder: + type: + - number + - "null" + remainderInBaseCurrency: + type: + - number + - "null" + roundingAmount: + type: + - number + - "null" + self: + type: + - string + - "null" + sent: + type: + - string + - "null" + vatAmount: + type: + - number + - "null" + required: + - bookedInvoiceNumber + total_invoices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + booked: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + invoiceCount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + paid: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + grossRemainderInBaseCurrency: + type: + - number + - "null" + invoiceCount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + self: + type: + - string + - "null" + self: + type: + - string + - "null" + unpaid: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + grossRemainderInBaseCurrency: + type: + - number + - "null" + invoiceCount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + notOverdue: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + invoiceCount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + self: + type: + - string + - "null" + overdue: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + grossRemainderInBaseCurrency: + type: + - number + - "null" + invoiceCount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + self: + type: + - string + - "null" + self: + type: + - string + - "null" + drafts: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + invoiceCount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + self: + type: + - string + - "null" + predefinedPeriodFilters: + type: + - object + - "null" + properties: + lastFifteenDays: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + self: + type: + - string + - "null" + lastMonth: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + self: + type: + - string + - "null" + lastSevenDays: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + self: + type: + - string + - "null" + lastThirtyDays: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + self: + type: + - string + - "null" + lastWeek: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + self: + type: + - string + - "null" + lastYear: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + self: + type: + - string + - "null" + thisMonth: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + self: + type: + - string + - "null" + thisWeek: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + self: + type: + - string + - "null" + thisYear: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + self: + type: + - string + - "null" + self: + type: + - string + - "null" + sent_invoices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdBy: + type: + - string + - "null" + creationDate: + type: + - string + - "null" + id: + type: number + invoice: + type: + - object + - "null" + properties: + bookedInvoiceNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + recipient: + type: + - object + - "null" + properties: + ean: + type: + - string + - "null" + self: + type: + - string + - "null" + sentBy: + type: + - string + - "null" + status: + type: + - string + - "null" + required: + - id + draft_orders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attachment: + type: + - string + - "null" + costPriceInBaseCurrency: + type: + - number + - "null" + currency: + type: + - string + - "null" + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + date: + type: + - string + - "null" + delivery: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + zip: + type: + - string + - "null" + deliveryLocation: + type: + - object + - "null" + properties: + deliveryLocationNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + exchangeRate: + type: + - number + - "null" + grossAmount: + type: + - number + - "null" + grossAmountInBaseCurrency: + type: + - number + - "null" + lastUpdated: + type: + - string + - "null" + layout: + type: + - object + - "null" + properties: + layoutNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + lines: + type: + - array + - "null" + marginInBaseCurrency: + type: + - number + - "null" + marginPercentage: + type: + - number + - "null" + netAmount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + orderNumber: + type: number + orderNumberDb: + type: + - number + - "null" + paymentTerms: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + daysOfCredit: + type: + - number + - "null" + name: + type: + - string + - "null" + paymentTermsNumber: + type: + - number + - "null" + paymentTermsType: + type: + - string + - "null" + self: + type: + - string + - "null" + pdf: + type: + - object + - "null" + properties: + download: + type: + - string + - "null" + recipient: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + attention: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + mobilePhone: + type: + - string + - "null" + name: + type: + - string + - "null" + nemHandelType: + type: + - string + - "null" + vatZone: + type: + - object + - "null" + properties: + self: + type: + - string + - "null" + vatZoneNumber: + type: + - number + - "null" + zip: + type: + - string + - "null" + references: + type: + - object + - "null" + properties: + customerContact: + type: + - object + - "null" + properties: + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + salesPerson: + type: + - object + - "null" + properties: + employeeNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + roundingAmount: + type: + - number + - "null" + salesDocumentType: + type: + - string + - "null" + self: + type: + - string + - "null" + soap: + type: + - object + - "null" + properties: + orderHandle: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + templates: + type: + - object + - "null" + properties: + self: + type: + - string + - "null" + upgradeInstructions: + type: + - string + - "null" + vatAmount: + type: + - number + - "null" + required: + - orderNumber + sent_orders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attachment: + type: + - string + - "null" + costPriceInBaseCurrency: + type: + - number + - "null" + currency: + type: + - string + - "null" + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + date: + type: + - string + - "null" + delivery: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + zip: + type: + - string + - "null" + deliveryLocation: + type: + - object + - "null" + properties: + deliveryLocationNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + exchangeRate: + type: + - number + - "null" + grossAmount: + type: + - number + - "null" + grossAmountInBaseCurrency: + type: + - number + - "null" + lastUpdated: + type: + - string + - "null" + layout: + type: + - object + - "null" + properties: + layoutNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + lines: + type: + - array + - "null" + marginInBaseCurrency: + type: + - number + - "null" + marginPercentage: + type: + - number + - "null" + netAmount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + orderNumber: + type: number + orderNumberDb: + type: + - number + - "null" + paymentTerms: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + daysOfCredit: + type: + - number + - "null" + name: + type: + - string + - "null" + paymentTermsNumber: + type: + - number + - "null" + paymentTermsType: + type: + - string + - "null" + self: + type: + - string + - "null" + pdf: + type: + - object + - "null" + properties: + download: + type: + - string + - "null" + recipient: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + attention: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + mobilePhone: + type: + - string + - "null" + name: + type: + - string + - "null" + nemHandelType: + type: + - string + - "null" + vatZone: + type: + - object + - "null" + properties: + self: + type: + - string + - "null" + vatZoneNumber: + type: + - number + - "null" + zip: + type: + - string + - "null" + references: + type: + - object + - "null" + properties: + customerContact: + type: + - object + - "null" + properties: + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + salesPerson: + type: + - object + - "null" + properties: + employeeNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + roundingAmount: + type: + - number + - "null" + salesDocumentType: + type: + - string + - "null" + self: + type: + - string + - "null" + soap: + type: + - object + - "null" + properties: + orderHandle: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + templates: + type: + - object + - "null" + properties: + self: + type: + - string + - "null" + upgradeInstructions: + type: + - string + - "null" + vatAmount: + type: + - number + - "null" + required: + - orderNumber + archived_orders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attachment: + type: + - string + - "null" + costPriceInBaseCurrency: + type: + - number + - "null" + currency: + type: + - string + - "null" + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + date: + type: + - string + - "null" + delivery: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + zip: + type: + - string + - "null" + deliveryLocation: + type: + - object + - "null" + properties: + deliveryLocationNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + exchangeRate: + type: + - number + - "null" + grossAmount: + type: + - number + - "null" + grossAmountInBaseCurrency: + type: + - number + - "null" + lastUpdated: + type: + - string + - "null" + layout: + type: + - object + - "null" + properties: + layoutNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + lines: + type: + - array + - "null" + marginInBaseCurrency: + type: + - number + - "null" + marginPercentage: + type: + - number + - "null" + netAmount: + type: + - number + - "null" + netAmountInBaseCurrency: + type: + - number + - "null" + orderNumber: + type: number + orderNumberDb: + type: + - number + - "null" + paymentTerms: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + daysOfCredit: + type: + - number + - "null" + name: + type: + - string + - "null" + paymentTermsNumber: + type: + - number + - "null" + paymentTermsType: + type: + - string + - "null" + self: + type: + - string + - "null" + pdf: + type: + - object + - "null" + properties: + download: + type: + - string + - "null" + recipient: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + attention: + type: + - object + - "null" + properties: + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + mobilePhone: + type: + - string + - "null" + name: + type: + - string + - "null" + nemHandelType: + type: + - string + - "null" + vatZone: + type: + - object + - "null" + properties: + self: + type: + - string + - "null" + vatZoneNumber: + type: + - number + - "null" + zip: + type: + - string + - "null" + references: + type: + - object + - "null" + properties: + customerContact: + type: + - object + - "null" + properties: + customer: + type: + - object + - "null" + properties: + customerNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + customerContactNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + salesPerson: + type: + - object + - "null" + properties: + employeeNumber: + type: + - number + - "null" + self: + type: + - string + - "null" + roundingAmount: + type: + - number + - "null" + salesDocumentType: + type: + - string + - "null" + self: + type: + - string + - "null" + soap: + type: + - object + - "null" + properties: + orderHandle: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + templates: + type: + - object + - "null" + properties: + self: + type: + - string + - "null" + upgradeInstructions: + type: + - string + - "null" + vatAmount: + type: + - number + - "null" + required: + - orderNumber diff --git a/airbyte-integrations/connectors/source-e-conomic/metadata.yaml b/airbyte-integrations/connectors/source-e-conomic/metadata.yaml new file mode 100644 index 000000000000..fca33287b8ab --- /dev/null +++ b/airbyte-integrations/connectors/source-e-conomic/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "restapi.e-conomic.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-e-conomic + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 2724ccae-2503-4348-9f1c-b5645b54a985 + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-e-conomic + githubIssueLabel: source-e-conomic + icon: icon.svg + license: MIT + name: e-conomic + releaseDate: 2024-10-28 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/e-conomic + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-easypost/metadata.yaml b/airbyte-integrations/connectors/source-easypost/metadata.yaml index 63ba626ecebe..b6f09a737412 100644 --- a/airbyte-integrations/connectors/source-easypost/metadata.yaml +++ b/airbyte-integrations/connectors/source-easypost/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-easypost connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.8.0@sha256:568b4cf0261ea6909db3ae00a0da6bc21ff2b271529a03683be0125dc27a86a2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: b74b0cfc-dd2c-4fdd-9bb0-ffc9efe04c36 - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-easypost githubIssueLabel: source-easypost icon: icon.svg diff --git a/airbyte-integrations/connectors/source-easypromos/README.md b/airbyte-integrations/connectors/source-easypromos/README.md new file mode 100644 index 000000000000..403f4876b023 --- /dev/null +++ b/airbyte-integrations/connectors/source-easypromos/README.md @@ -0,0 +1,33 @@ +# Easypromos +This directory contains the manifest-only connector for `source-easypromos`. + +Airbyte connector for Easypromos enables seamless data extraction from Easypromos, an online platform for running contests, giveaways, and promotions. It facilitates automatic syncing of participant information, promotion performance, and engagement metrics into data warehouses, streamlining analytics and reporting. This integration helps businesses easily analyze campaign data and optimize marketing strategies + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-easypromos:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-easypromos build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-easypromos test +``` + diff --git a/airbyte-integrations/connectors/source-easypromos/acceptance-test-config.yml b/airbyte-integrations/connectors/source-easypromos/acceptance-test-config.yml new file mode 100644 index 000000000000..513a41ef34df --- /dev/null +++ b/airbyte-integrations/connectors/source-easypromos/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-easypromos:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-easypromos/icon.svg b/airbyte-integrations/connectors/source-easypromos/icon.svg new file mode 100644 index 000000000000..54366c5c3039 --- /dev/null +++ b/airbyte-integrations/connectors/source-easypromos/icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/airbyte-integrations/connectors/source-easypromos/manifest.yaml b/airbyte-integrations/connectors/source-easypromos/manifest.yaml new file mode 100644 index 000000000000..e631179c9071 --- /dev/null +++ b/airbyte-integrations/connectors/source-easypromos/manifest.yaml @@ -0,0 +1,764 @@ +version: 5.14.0 + +type: DeclarativeSource + +description: >- + Airbyte connector for Easypromos enables seamless data extraction from + Easypromos, an online platform for running contests, giveaways, and + promotions. It facilitates automatic syncing of participant information, + promotion performance, and engagement metrics into data warehouses, + streamlining analytics and reporting. This integration helps businesses easily + analyze campaign data and optimize marketing strategies + +check: + type: CheckStream + stream_names: + - promotions + +definitions: + streams: + promotions: + type: DeclarativeStream + name: promotions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /promotions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: next_cursor + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('paging', {}).get('next_cursor') }}" + stop_condition: "{{ response.get('paging', {}).get('next_cursor') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/promotions" + organizing_brands: + type: DeclarativeStream + name: organizing_brands + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /organizing_brands + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: next_cursor + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('paging', {}).get('next_cursor') }}" + stop_condition: "{{ response.get('paging', {}).get('next_cursor') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/organizing_brands" + stages: + type: DeclarativeStream + name: stages + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /stages/{{ stream_partition.promotion_id }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: next_cursor + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('paging', {}).get('next_cursor') }}" + stop_condition: "{{ response.get('paging', {}).get('next_cursor') is none }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: promotion_id + stream: + $ref: "#/definitions/streams/promotions" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stages" + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /users/{{ stream_partition.promotion_id }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: next_cursor + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('paging', {}).get('next_cursor') }}" + stop_condition: "{{ response.get('paging', {}).get('next_cursor') is none }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: promotion_id + stream: + $ref: "#/definitions/streams/promotions" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + participations: + type: DeclarativeStream + name: participations + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /participations/{{ stream_partition.promotion_id }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: next_cursor + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('paging', {}).get('next_cursor') }}" + stop_condition: "{{ response.get('paging', {}).get('next_cursor') is none }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: promotion_id + stream: + $ref: "#/definitions/streams/promotions" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/participations" + prizes: + type: DeclarativeStream + name: prizes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /prizes/{{ stream_partition.promotion_id }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: next_cursor + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('paging', {}).get('next_cursor') }}" + stop_condition: "{{ response.get('paging', {}).get('next_cursor') is none }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: promotion_id + stream: + $ref: "#/definitions/streams/promotions" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/prizes" + rankings: + type: DeclarativeStream + name: rankings + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /ranking/{{ stream_partition.promotion_id }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: next_cursor + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('paging', {}).get('next_cursor') }}" + stop_condition: "{{ response.get('paging', {}).get('next_cursor') is none }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: promotion_id + stream: + $ref: "#/definitions/streams/promotions" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/rankings" + base_requester: + type: HttpRequester + url_base: https://api.easypromosapp.com/v2 + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"bearer_token\"] }}" + +streams: + - $ref: "#/definitions/streams/promotions" + - $ref: "#/definitions/streams/organizing_brands" + - $ref: "#/definitions/streams/stages" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/participations" + - $ref: "#/definitions/streams/prizes" + - $ref: "#/definitions/streams/rankings" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - bearer_token + properties: + bearer_token: + type: string + name: jwt_token + order: 0 + title: Bearer Token + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + promotions: true + organizing_brands: false + stages: false + users: false + participations: false + prizes: false + rankings: false + testedStreams: + promotions: + hasRecords: true + streamHash: aa30738aecf05a5ad59b1d4b5360a2cac3c1a431 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + organizing_brands: + hasRecords: true + streamHash: 6caeef094bc7203463c34ca952f2d7c164a9003a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + stages: + hasRecords: true + streamHash: bf15f2fc055a0e9d4440359f2e71e4abd102cfa5 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + users: + hasRecords: true + streamHash: 999f9a05b409a39ef39c4fda263259826643513a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + participations: + hasRecords: true + streamHash: f2c2f9574b5ba92e535bd7da808b06cd52239d8d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + prizes: + hasRecords: true + streamHash: 85b403e53fb415e280f92ef873ed3ce465c95a59 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + rankings: + hasRecords: true + streamHash: c852ad512d4adb549fbfc253161e99c1c3bb6b56 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://easypromos-apiref.redoc.ly/ + +schemas: + promotions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created: + type: + - string + - "null" + default_language: + type: + - string + - "null" + end_date: + type: + - string + - "null" + id: + type: string + organizing_brand: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + promotion_type: + type: + - string + - "null" + start_date: + type: + - string + - "null" + status: + type: + - string + - "null" + timezone: + type: + - string + - "null" + title: + type: + - string + - "null" + url: + type: + - string + - "null" + required: + - id + organizing_brands: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: string + name: + type: + - string + - "null" + required: + - id + stages: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + end_date: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + start_date: + type: + - string + - "null" + visible: + type: + - boolean + - "null" + required: + - id + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + country: + type: + - string + - "null" + created: + type: + - string + - "null" + custom_properties: + type: + - array + - "null" + email: + type: + - string + - "null" + external_id: + type: + - string + - "null" + first_name: + type: + - string + - "null" + id: + type: string + language: + type: + - string + - "null" + last_name: + type: + - string + - "null" + login_type: + type: + - string + - "null" + meta_data: + type: + - object + - "null" + properties: + ip: + type: + - string + - "null" + legals: + type: + - object + - "null" + properties: + privacy_url: + type: + - string + - "null" + terms_url: + type: + - string + - "null" + referral_url: + type: + - string + - "null" + user_agent: + type: + - string + - "null" + utm_campaign: + type: + - string + - "null" + utm_medium: + type: + - string + - "null" + utm_source: + type: + - string + - "null" + nickname: + type: + - string + - "null" + promotion_id: + type: + - string + - "null" + status: + type: + - string + - "null" + required: + - id + participations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created: + type: + - string + - "null" + data: + type: + - array + - "null" + id: + type: string + ip: + type: + - string + - "null" + promotion_id: + type: + - string + - "null" + stage_id: + type: + - string + - "null" + user_agent: + type: + - string + - "null" + user_id: + type: + - string + - "null" + required: + - id + prizes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + code: + type: + - string + - "null" + created: + type: + - string + - "null" + download_url: + type: + - string + - "null" + id: + type: string + participation_id: + type: + - string + - "null" + prize_type: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + assignation_type: + type: + - string + - "null" + id: + type: + - string + - "null" + image: + type: + - string + - "null" + instructions: + type: + - string + - "null" + name: + type: + - string + - "null" + qty: + type: + - string + - "null" + ref: + type: + - string + - "null" + redeem_url: + type: + - string + - "null" + stage_id: + type: + - string + - "null" + user: + type: + - object + - "null" + properties: + country: + type: + - string + - "null" + created: + type: + - string + - "null" + custom_properties: + type: + - array + - "null" + external_id: + type: + - string + - "null" + first_name: + type: + - string + - "null" + id: + type: + - string + - "null" + language: + type: + - string + - "null" + last_name: + type: + - string + - "null" + meta_data: + type: + - object + - "null" + properties: + ip: + type: + - string + - "null" + legals: + type: + - object + - "null" + properties: {} + user_agent: + type: + - string + - "null" + utm_medium: + type: + - string + - "null" + nickname: + type: + - string + - "null" + promotion_id: + type: + - string + - "null" + social_id: + type: + - string + - "null" + status: + type: + - string + - "null" + user_id: + type: + - string + - "null" + required: + - id + rankings: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} diff --git a/airbyte-integrations/connectors/source-easypromos/metadata.yaml b/airbyte-integrations/connectors/source-easypromos/metadata.yaml new file mode 100644 index 000000000000..66c77be6a734 --- /dev/null +++ b/airbyte-integrations/connectors/source-easypromos/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.easypromosapp.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-easypromos + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 8b418a25-7042-430f-96d8-72853a337a26 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-easypromos + githubIssueLabel: source-easypromos + icon: icon.svg + license: MIT + name: Easypromos + releaseDate: 2024-10-21 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/easypromos + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-elasticemail/README.md b/airbyte-integrations/connectors/source-elasticemail/README.md new file mode 100644 index 000000000000..c5cab263e6f0 --- /dev/null +++ b/airbyte-integrations/connectors/source-elasticemail/README.md @@ -0,0 +1,35 @@ +# Elasticemail +This directory contains the manifest-only connector for `source-elasticemail`. + +Elasticemail is an email delivery and marketing platform. +Using this connector we extract data from streams such as campaigns , contacts , lists and statistics! +Docs : https://elasticemail.com/developers/api-documentation/rest-api + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-elasticemail:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-elasticemail build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-elasticemail test +``` + diff --git a/airbyte-integrations/connectors/source-elasticemail/acceptance-test-config.yml b/airbyte-integrations/connectors/source-elasticemail/acceptance-test-config.yml new file mode 100644 index 000000000000..18725a041216 --- /dev/null +++ b/airbyte-integrations/connectors/source-elasticemail/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-elasticemail:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-elasticemail/icon.svg b/airbyte-integrations/connectors/source-elasticemail/icon.svg new file mode 100644 index 000000000000..650ad92bda02 --- /dev/null +++ b/airbyte-integrations/connectors/source-elasticemail/icon.svg @@ -0,0 +1,17 @@ + + + diff --git a/airbyte-integrations/connectors/source-elasticemail/manifest.yaml b/airbyte-integrations/connectors/source-elasticemail/manifest.yaml new file mode 100644 index 000000000000..d61657802fe4 --- /dev/null +++ b/airbyte-integrations/connectors/source-elasticemail/manifest.yaml @@ -0,0 +1,901 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Elasticemail is an email delivery and marketing platform. + + Using this connector we extract data from streams such as campaigns , contacts + , lists and statistics! + + Docs : https://elasticemail.com/developers/api-documentation/rest-api + +check: + type: CheckStream + stream_names: + - campaigns + +definitions: + streams: + campaigns: + type: DeclarativeStream + name: campaigns + primary_key: + - Name + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: campaigns + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/campaigns" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - Email + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + events: + type: DeclarativeStream + name: events + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: events + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + incremental_sync: + type: DatetimeBasedCursor + cursor_field: EventDate + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: from + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: to + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/events" + files: + type: DeclarativeStream + name: files + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: files + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/files" + inboundroute: + type: DeclarativeStream + name: inboundroute + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: inboundroute + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/inboundroute" + lists: + type: DeclarativeStream + name: lists + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: lists + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/lists" + segments: + type: DeclarativeStream + name: segments + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: segments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/segments" + statistics: + type: DeclarativeStream + name: statistics + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: statistics + http_method: GET + request_parameters: + from: "{{ config['from'] }}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: FAIL + http_codes: + - 400 + error_message: Please enter " FROM " + error_message_contains: Missing required parameter - from + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/statistics" + templates: + type: DeclarativeStream + name: templates + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: templates + http_method: GET + request_parameters: + scopeType: "{{ config['scope_type'] }}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: FAIL + http_codes: + - 400 + error_message: Please enter scope type + error_message_contains: Missing required parameter - scopeType + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/templates" + base_requester: + type: HttpRequester + url_base: https://api.elasticemail.com/v4/ + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: X-ElasticEmail-ApiKey + inject_into: header + +streams: + - $ref: "#/definitions/streams/campaigns" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/events" + - $ref: "#/definitions/streams/files" + - $ref: "#/definitions/streams/inboundroute" + - $ref: "#/definitions/streams/lists" + - $ref: "#/definitions/streams/segments" + - $ref: "#/definitions/streams/statistics" + - $ref: "#/definitions/streams/templates" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - start_date + properties: + api_key: + type: string + order: 0 + title: API Key + airbyte_secret: true + scope_type: + type: string + enum: + - Personal + - Global + order: 1 + title: scope type + from: + type: string + order: 2 + title: From + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + start_date: + type: string + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + order: 3 + additionalProperties: true + +metadata: + autoImportSchema: + campaigns: true + contacts: true + events: true + files: true + inboundroute: true + lists: true + segments: true + statistics: true + templates: true + testedStreams: + campaigns: + streamHash: 710dfed26ba909aa8a827eb0f01f0d7637b91654 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contacts: + hasRecords: true + streamHash: 1f12a61f26afd232c3f30930ab2e4d0f03c3c2ff + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + events: + streamHash: 31b475a5f62ca0631118a6abcace8b2ff4df5fc4 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + files: + hasRecords: true + streamHash: 8f885dddf20aee665691852cb3cb3c1a2d1d9bde + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + inboundroute: + hasRecords: true + streamHash: 7b2c797f57d0ee3ea1d0b517768535ea3cbbdbfa + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + lists: + hasRecords: true + streamHash: 3380bc055963d77b500814a2918a339bfffaddc1 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + segments: + hasRecords: true + streamHash: 7b70d5ab087b477ec5ae5fc14debb32a91443084 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + statistics: + hasRecords: true + streamHash: 582a9673808200009b054803e616e352da909451 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + templates: + hasRecords: true + streamHash: f6aa0b75ced8878e0c39f13696d93a1ec5d77083 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: {} + +schemas: + campaigns: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Content: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + From: + type: + - string + - "null" + Poolname: + type: + - string + - "null" + ReplyTo: + type: + - string + - "null" + Subject: + type: + - string + - "null" + TemplateName: + type: + - string + - "null" + Utm: + type: + - object + - "null" + properties: {} + Name: + type: string + Options: + type: + - object + - "null" + properties: + DeliveryOptimization: + type: + - string + - "null" + ScheduleFor: + type: + - string + - "null" + SplitOptions: + type: + - object + - "null" + properties: + OptimizeFor: + type: + - string + - "null" + OptimizePeriodMinutes: + type: + - number + - "null" + TriggerCount: + type: + - number + - "null" + TriggerFrequency: + type: + - number + - "null" + Recipients: + type: + - object + - "null" + properties: + ListNames: + type: + - array + - "null" + items: + type: + - string + - "null" + Status: + type: + - string + - "null" + required: + - Name + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Activity: + type: + - object + - "null" + properties: + FriendlyErrorMessage: + type: + - string + - "null" + LastIP: + type: + - string + - "null" + LastSent: + type: + - string + - "null" + TotalClicked: + type: + - number + - "null" + TotalFailed: + type: + - number + - "null" + TotalOpened: + type: + - number + - "null" + TotalSent: + type: + - number + - "null" + Consent: + type: + - object + - "null" + properties: + ConsentDate: + type: + - string + - "null" + ConsentIP: + type: + - string + - "null" + ConsentTracking: + type: + - string + - "null" + CustomFields: + type: + - object + - "null" + DateAdded: + type: + - string + - "null" + DateUpdated: + type: + - string + - "null" + Email: + type: string + FirstName: + type: + - string + - "null" + LastName: + type: + - string + - "null" + Source: + type: + - number + - string + - "null" + Status: + type: + - string + - "null" + StatusChangeDate: + type: + - string + - "null" + required: + - Email + events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + ChannelName: + type: + - string + - "null" + EventDate: + type: string + EventType: + type: + - string + - "null" + FromEmail: + type: + - string + - "null" + IPAddress: + type: + - string + - "null" + Message: + type: + - string + - "null" + MessageCategory: + type: + - string + - "null" + MsgID: + type: + - string + - "null" + PoolName: + type: + - string + - "null" + Subject: + type: + - string + - "null" + To: + type: + - string + - "null" + TransactionID: + type: + - string + - "null" + required: + - EventDate + files: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + ContentType: + type: + - string + - "null" + DateAdded: + type: + - string + - "null" + ExpirationDate: + type: + - string + - "null" + FileID: + type: + - number + - "null" + FileName: + type: + - string + - "null" + Size: + type: + - number + - "null" + inboundroute: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + ActionParameter: + type: + - string + - "null" + ActionType: + type: + - string + - "null" + Filter: + type: + - string + - "null" + FilterType: + type: + - string + - "null" + Name: + type: + - string + - "null" + PublicId: + type: + - string + - "null" + SortOrder: + type: + - number + - "null" + lists: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + AllowUnsubscribe: + type: + - boolean + - "null" + DateAdded: + type: + - string + - "null" + ListName: + type: + - string + - "null" + PublicListID: + type: + - string + - "null" + segments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Name: + type: + - string + - "null" + Rule: + type: + - string + - "null" + statistics: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Bounced: + type: + - number + - "null" + Clicked: + type: + - number + - "null" + Complaints: + type: + - number + - "null" + Delivered: + type: + - number + - "null" + EmailTotal: + type: + - number + - "null" + InProgress: + type: + - number + - "null" + Inbound: + type: + - number + - "null" + ManualCancel: + type: + - number + - "null" + NotDelivered: + type: + - number + - "null" + Opened: + type: + - number + - "null" + Recipients: + type: + - number + - "null" + SmsTotal: + type: + - number + - "null" + Unsubscribed: + type: + - number + - "null" + templates: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Body: + type: + - array + - "null" + DateAdded: + type: + - string + - "null" + Name: + type: + - string + - "null" + Subject: + type: + - string + - "null" + TemplateScope: + type: + - string + - "null" + TemplateType: + type: + - string + - "null" diff --git a/airbyte-integrations/connectors/source-elasticemail/metadata.yaml b/airbyte-integrations/connectors/source-elasticemail/metadata.yaml new file mode 100644 index 000000000000..c20a3155623d --- /dev/null +++ b/airbyte-integrations/connectors/source-elasticemail/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.elasticemail.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-elasticemail + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: ed2c12aa-375c-4d18-9d3b-7e1f8a23245d + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-elasticemail + githubIssueLabel: source-elasticemail + icon: icon.svg + license: MIT + name: Elasticemail + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/elasticemail + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-elasticsearch/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-elasticsearch/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-elasticsearch/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-elasticsearch/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-elasticsearch/metadata.yaml b/airbyte-integrations/connectors/source-elasticsearch/metadata.yaml index 60f99e6bb504..bcdd08ffe87b 100644 --- a/airbyte-integrations/connectors/source-elasticsearch/metadata.yaml +++ b/airbyte-integrations/connectors/source-elasticsearch/metadata.yaml @@ -1,9 +1,18 @@ data: + ab_internal: + ql: 100 + sl: 100 + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a connectorSubtype: api + connectorTestSuitesOptions: + - suite: unitTests + - suite: integrationTests connectorType: source definitionId: 7cf88806-25f5-4e1a-b422-b2fa9e1b0090 - dockerImageTag: 0.1.2 + dockerImageTag: 0.1.3 dockerRepository: airbyte/source-elasticsearch + documentationUrl: https://docs.airbyte.com/integrations/sources/elasticsearch githubIssueLabel: source-elasticsearch icon: elasticsearch.svg license: MIT @@ -14,14 +23,7 @@ data: oss: enabled: true releaseStage: alpha - documentationUrl: https://docs.airbyte.com/integrations/sources/elasticsearch + supportLevel: community tags: - language:java - ab_internal: - sl: 100 - ql: 100 - supportLevel: community - connectorTestSuitesOptions: - - suite: unitTests - - suite: integrationTests metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-emailoctopus/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-emailoctopus/integration_tests/acceptance.py index 3a0f562732fb..6e0d32803f45 100644 --- a/airbyte-integrations/connectors/source-emailoctopus/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-emailoctopus/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-emailoctopus/metadata.yaml b/airbyte-integrations/connectors/source-emailoctopus/metadata.yaml index 3ecba0373a30..d6596f6e78d0 100644 --- a/airbyte-integrations/connectors/source-emailoctopus/metadata.yaml +++ b/airbyte-integrations/connectors/source-emailoctopus/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 46b25e70-c980-4590-a811-8deaf50ee09f - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-emailoctopus documentationUrl: https://docs.airbyte.com/integrations/sources/emailoctopus githubIssueLabel: source-emailoctopus diff --git a/airbyte-integrations/connectors/source-employment-hero/metadata.yaml b/airbyte-integrations/connectors/source-employment-hero/metadata.yaml index 12e11ead7d47..41b94a6cf283 100644 --- a/airbyte-integrations/connectors/source-employment-hero/metadata.yaml +++ b/airbyte-integrations/connectors/source-employment-hero/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-employment-hero connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: e2db518e-ef68-40bb-a2b6-b9f9aabbadb3 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-employment-hero githubIssueLabel: source-employment-hero icon: icon.svg diff --git a/airbyte-integrations/connectors/source-encharge/README.md b/airbyte-integrations/connectors/source-encharge/README.md new file mode 100644 index 000000000000..81014c697095 --- /dev/null +++ b/airbyte-integrations/connectors/source-encharge/README.md @@ -0,0 +1,33 @@ +# Encharge +This directory contains the manifest-only connector for `source-encharge`. + +Airbyte connector for [Encharge](https://encharge.io/) enables seamless data integration between Encharge and your data warehouse or other destinations. With this connector, you can easily sync marketing automation data from Encharge. This allows for improved data-driven decision-making and enhanced marketing insights across platforms. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-encharge:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-encharge build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-encharge test +``` + diff --git a/airbyte-integrations/connectors/source-encharge/acceptance-test-config.yml b/airbyte-integrations/connectors/source-encharge/acceptance-test-config.yml new file mode 100644 index 000000000000..7d3b6c94b188 --- /dev/null +++ b/airbyte-integrations/connectors/source-encharge/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-encharge:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-encharge/icon.svg b/airbyte-integrations/connectors/source-encharge/icon.svg new file mode 100644 index 000000000000..94bf7accc9e1 --- /dev/null +++ b/airbyte-integrations/connectors/source-encharge/icon.svg @@ -0,0 +1,7 @@ + + + + Layer 1 + + + diff --git a/airbyte-integrations/connectors/source-encharge/manifest.yaml b/airbyte-integrations/connectors/source-encharge/manifest.yaml new file mode 100644 index 000000000000..767ab24fc07c --- /dev/null +++ b/airbyte-integrations/connectors/source-encharge/manifest.yaml @@ -0,0 +1,855 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Airbyte connector for [Encharge](https://encharge.io/) enables seamless data + integration between Encharge and your data warehouse or other destinations. + With this connector, you can easily sync marketing automation data from + Encharge. This allows for improved data-driven decision-making and enhanced + marketing insights across platforms. + +check: + type: CheckStream + stream_names: + - peoples + +definitions: + streams: + schemas: + type: DeclarativeStream + name: schemas + primary_key: + - name + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /schemas + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - objects + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/schemas" + peoples: + type: DeclarativeStream + name: peoples + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /people/all + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - people + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/peoples" + accounts: + type: DeclarativeStream + name: accounts + primary_key: + - accountId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounts" + account_tags: + type: DeclarativeStream + name: account_tags + primary_key: + - tag + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /tags-management + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - tags + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/account_tags" + segments: + type: DeclarativeStream + name: segments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /segments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - segments + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/segments" + fields: + type: DeclarativeStream + name: fields + primary_key: + - name + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /fields + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/fields" + segment_people: + type: DeclarativeStream + name: segment_people + primary_key: + - segment_id + - email + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /segments/{{stream_slice.segment_id}}/people + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - people + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: segment_id + stream: + $ref: "#/definitions/streams/segments" + transformations: + - type: AddFields + fields: + - path: + - segment_id + value: "{{ stream_slice.segment_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/segment_people" + base_requester: + type: HttpRequester + url_base: https://api.encharge.io/v1 + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: X-Encharge-Token + inject_into: header + +streams: + - $ref: "#/definitions/streams/peoples" + - $ref: "#/definitions/streams/accounts" + - $ref: "#/definitions/streams/account_tags" + - $ref: "#/definitions/streams/segments" + - $ref: "#/definitions/streams/fields" + - $ref: "#/definitions/streams/schemas" + - $ref: "#/definitions/streams/segment_people" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + description: The API key to use for authentication + name: api_key + order: 0 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + schemas: false + peoples: true + accounts: false + account_tags: false + segments: false + fields: false + segment_people: false + testedStreams: + schemas: + hasRecords: true + streamHash: 2074d3133d41c0aa4162fd878f2409a7bb37010b + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + peoples: + streamHash: f5365e1e91ec221739d2de544e1f8c84dd95bfa6 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + accounts: + streamHash: cf3f394bd38e4640fff11e118da37623a42e80ca + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + account_tags: + streamHash: 3290e0bc8f1a8b6d2b7e30d5206e462f7d94a2e2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + segments: + streamHash: 2302fba784ef1e1fdb5fc043f10fc48bb1668661 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + fields: + hasRecords: true + streamHash: 931e9e1ae101d51b53ac8a8884ca0330b25d2731 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + segment_people: + streamHash: 8bce993bbb51c880b2ed1c99d3023a1c9081e8f3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://app-encharge-resources.s3.amazonaws.com/redoc.html + +schemas: + schemas: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + associations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + fromObject: + type: + - string + - "null" + id: + type: + - number + - "null" + toObject: + type: + - string + - "null" + displayNamePlural: + type: + - string + - "null" + displayNameSingular: + type: + - string + - "null" + fields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + array: + type: + - boolean + - "null" + canMapFrom: + type: + - boolean + - "null" + createdBy: + type: + - string + - "null" + enum: + type: + - array + - "null" + items: + type: + - string + - "null" + enumNames: + type: + - array + - "null" + items: + type: + - string + - "null" + firstClassField: + type: + - boolean + - "null" + format: + type: + - string + - "null" + icon: + type: + - string + - "null" + name: + type: + - string + - "null" + readOnly: + type: + - boolean + - "null" + title: + type: + - string + - "null" + tooltip: + type: + - string + - "null" + name: + type: string + primaryField: + type: + - string + - "null" + searchableFields: + type: + - array + - "null" + items: + type: + - string + - "null" + required: + - name + peoples: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + CommunicationCategories: + type: + - object + - "null" + properties: {} + createdAt: + type: + - string + - "null" + email: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: string + isEmailDisposable: + type: + - boolean + - "null" + isEmailRole: + type: + - boolean + - "null" + lastActivity: + type: + - string + - "null" + lastName: + type: + - string + - "null" + leadScore: + type: + - number + - "null" + name: + type: + - string + - "null" + tags: + type: + - string + - "null" + title: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + validationConfidence: + type: + - number + - "null" + validationResult: + type: + - string + - "null" + required: + - id + accounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + accountId: + type: number + activeServices: + type: + - array + - "null" + items: + type: + - string + - "null" + apiKeys: + type: + - array + - "null" + items: + type: + - string + - "null" + approved: + type: + - boolean + - "null" + blocked: + type: + - boolean + - "null" + companyInfo: + type: + - object + - "null" + properties: + isSaaS: + type: + - boolean + - "null" + summary: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + fields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + array: + type: + - boolean + - "null" + canMapFrom: + type: + - boolean + - "null" + createdBy: + type: + - string + - "null" + enum: + type: + - array + - "null" + items: + type: + - string + - "null" + enumNames: + type: + - array + - "null" + items: + type: + - string + - "null" + firstClassField: + type: + - boolean + - "null" + format: + type: + - string + - "null" + icon: + type: + - string + - "null" + name: + type: + - string + - "null" + readOnly: + type: + - boolean + - "null" + title: + type: + - string + - "null" + tooltip: + type: + - string + - "null" + flags: + type: + - object + - "null" + properties: + aiFlowsGenerated: + type: + - boolean + - "null" + isFreeEmail: + type: + - boolean + - "null" + providedSiteAndName: + type: + - boolean + - "null" + registrationFinished: + type: + - boolean + - "null" + hasStripeAPIKey: + type: + - boolean + - "null" + industry: + type: + - string + - "null" + name: + type: + - string + - "null" + onboarding: + type: + - object + - "null" + properties: + import: + type: + - boolean + - "null" + outputFieldMappings: + type: + - object + - "null" + peopleCount: + type: + - number + - "null" + phone: + type: + - string + - "null" + site: + type: + - string + - "null" + status: + type: + - string + - "null" + testAccount: + type: + - boolean + - "null" + timezone: + type: + - string + - "null" + webhookSeed: + type: + - string + - "null" + writeKey: + type: + - string + - "null" + required: + - accountId + account_tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + tag: + type: string + required: + - tag + segments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + accountId: + type: + - number + - "null" + autoSegment: + type: + - boolean + - "null" + conditions: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + conditions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + condition: + type: + - string + - "null" + field: + type: + - string + - "null" + value: + type: + - boolean + - number + - "null" + operator: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + objectName: + type: + - string + - "null" + readOnly: + type: + - boolean + - "null" + required: + - id + fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + array: + type: + - boolean + - "null" + canMapFrom: + type: + - boolean + - "null" + createdBy: + type: + - string + - "null" + enum: + type: + - array + - "null" + items: + type: + - string + - "null" + enumNames: + type: + - array + - "null" + items: + type: + - string + - "null" + firstClassField: + type: + - boolean + - "null" + format: + type: + - string + - "null" + icon: + type: + - string + - "null" + name: + type: string + readOnly: + type: + - boolean + - "null" + title: + type: + - string + - "null" + tooltip: + type: + - string + - "null" + required: + - name + segment_people: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} diff --git a/airbyte-integrations/connectors/source-encharge/metadata.yaml b/airbyte-integrations/connectors/source-encharge/metadata.yaml new file mode 100644 index 000000000000..ced939cb6802 --- /dev/null +++ b/airbyte-integrations/connectors/source-encharge/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.encharge.io" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-encharge + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 44a57f92-595c-4512-9983-1563b8764b63 + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-encharge + githubIssueLabel: source-encharge + icon: icon.svg + license: MIT + name: Encharge + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/encharge + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-eventbrite/metadata.yaml b/airbyte-integrations/connectors/source-eventbrite/metadata.yaml index e633e1291203..49795e1e0444 100644 --- a/airbyte-integrations/connectors/source-eventbrite/metadata.yaml +++ b/airbyte-integrations/connectors/source-eventbrite/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-eventbrite connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 6748b22d-3d27-4907-b8c0-04f6c8ef71b8 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-eventbrite githubIssueLabel: source-eventbrite icon: icon.svg diff --git a/airbyte-integrations/connectors/source-eventee/README.md b/airbyte-integrations/connectors/source-eventee/README.md new file mode 100644 index 000000000000..dd4db49111d9 --- /dev/null +++ b/airbyte-integrations/connectors/source-eventee/README.md @@ -0,0 +1,33 @@ +# Eventee +This directory contains the manifest-only connector for `source-eventee`. + +The Airbyte connector for Eventee enables seamless integration and automated data synchronization between Eventee, a leading event management platform, and your data destinations. It extracts and transfers event-related information such as attendee details, lectures, tracks, and more. This connector ensures real-time or scheduled data flow, helping you centralize and analyze Eventee's data effortlessly for improved event insights and reporting. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-eventee:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-eventee build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-eventee test +``` + diff --git a/airbyte-integrations/connectors/source-eventee/acceptance-test-config.yml b/airbyte-integrations/connectors/source-eventee/acceptance-test-config.yml new file mode 100644 index 000000000000..a3c6567297e9 --- /dev/null +++ b/airbyte-integrations/connectors/source-eventee/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-eventee:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-eventee/icon.svg b/airbyte-integrations/connectors/source-eventee/icon.svg new file mode 100644 index 000000000000..64539a46ed84 --- /dev/null +++ b/airbyte-integrations/connectors/source-eventee/icon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-eventee/manifest.yaml b/airbyte-integrations/connectors/source-eventee/manifest.yaml new file mode 100644 index 000000000000..0305f8976596 --- /dev/null +++ b/airbyte-integrations/connectors/source-eventee/manifest.yaml @@ -0,0 +1,1035 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + The Airbyte connector for Eventee enables seamless integration and automated + data synchronization between Eventee, a leading event management platform, and + your data destinations. It extracts and transfers event-related information + such as attendee details, lectures, tracks, and more. This connector ensures + real-time or scheduled data flow, helping you centralize and analyze Eventee's + data effortlessly for improved event insights and reporting. + +check: + type: CheckStream + stream_names: + - halls + +definitions: + streams: + halls: + type: DeclarativeStream + name: halls + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /content + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - halls + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/halls" + days: + type: DeclarativeStream + name: days + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /content + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - days + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/days" + lectures: + type: DeclarativeStream + name: lectures + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /content + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - lectures + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/lectures" + speakers: + type: DeclarativeStream + name: speakers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /content + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - speakers + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/speakers" + workshops: + type: DeclarativeStream + name: workshops + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /content + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - workshops + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/workshops" + pauses: + type: DeclarativeStream + name: pauses + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /content + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - pauses + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/pauses" + tracks: + type: DeclarativeStream + name: tracks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /content + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - tracks + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tracks" + partners: + type: DeclarativeStream + name: partners + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /partners + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/partners" + participants: + type: DeclarativeStream + name: participants + primary_key: + - email + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /participants + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/participants" + base_requester: + type: HttpRequester + url_base: https://api.eventee.co/public/v1 + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"api_token\"] }}" + +streams: + - $ref: "#/definitions/streams/halls" + - $ref: "#/definitions/streams/days" + - $ref: "#/definitions/streams/lectures" + - $ref: "#/definitions/streams/speakers" + - $ref: "#/definitions/streams/workshops" + - $ref: "#/definitions/streams/pauses" + - $ref: "#/definitions/streams/tracks" + - $ref: "#/definitions/streams/partners" + - $ref: "#/definitions/streams/participants" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_token + properties: + api_token: + type: string + description: >- + API token to use. Generate it at https://admin.eventee.co/ in + 'Settings -> Features'. + name: api_token + order: 0 + title: API Token + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + halls: true + days: true + lectures: true + speakers: true + workshops: true + pauses: true + tracks: true + partners: false + participants: false + testedStreams: + halls: + hasRecords: true + streamHash: e14467f04497713244238dd3d1dcf4698c47349a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + days: + streamHash: 2cdccce2f95e890913399fd07ad7bdea48460b1e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + lectures: + hasRecords: true + streamHash: e5b518d8ab07258cb9b8703e8ccccfcc722e99b0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + speakers: + streamHash: 6f03a172b1fa1bc70e5a2b6237a9dc0e70139246 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + workshops: + streamHash: f512a236b799a2ae88bb52c7613086e305c289d7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + pauses: + streamHash: e9f7eb51fab59c7bd0e79c9317a7d2d2f2b966ac + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tracks: + streamHash: 0750e28cba1c73599df78ecfb7edf0aaebb90693 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + partners: + streamHash: 2af8d537faba2c32e9e34223881948350b08a063 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + participants: + streamHash: 4fe776b5dfcacd254ebfdb2363705671a2be6f5d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://publiceventeeapi.docs.apiary.io/ + +schemas: + halls: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + event_id: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + order: + type: + - number + - "null" + stream: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + available: + type: + - boolean + - "null" + code: + type: + - string + - "null" + created_at: + type: + - string + - "null" + is_live: + type: + - boolean + - "null" + streamable_id: + type: + - number + - "null" + streamable_type: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + url: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + days: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + content_url: + type: + - string + - "null" + date: + type: + - string + - "null" + event_id: + type: + - number + - "null" + id: + type: number + required: + - id + lectures: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + description: + type: + - string + - "null" + available: + type: + - number + - "null" + booked: + type: + - boolean + - "null" + booking_info: + type: + - array + - "null" + capacity: + type: + - number + - "null" + code: + type: + - string + - "null" + created_at: + type: + - string + - "null" + discussion: + type: + - number + - "null" + end: + type: + - string + - "null" + event_day_id: + type: + - number + - "null" + event_id: + type: + - number + - "null" + files: + type: + - array + - "null" + hall_id: + type: + - number + - "null" + id: + type: number + laravel_through_key: + type: + - number + - "null" + mentoring: + type: + - boolean + - "null" + moderating: + type: + - boolean + - "null" + name: + type: + - string + - "null" + overlapping: + type: + - boolean + - "null" + panel_discussion: + type: + - number + - "null" + polling: + type: + - boolean + - "null" + qr_code_url: + type: + - string + - "null" + speakers: + type: + - array + - "null" + items: + type: + - number + - "null" + start: + type: + - string + - "null" + tracks: + type: + - array + - "null" + updated_at: + type: + - string + - "null" + required: + - id + speakers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + bio: + type: + - string + - "null" + bio_html: + type: + - string + - "null" + company: + type: + - string + - "null" + country: + type: + - string + - "null" + email: + type: + - string + - "null" + event_id: + type: + - number + - "null" + facebook: + type: + - string + - "null" + id: + type: number + instagram: + type: + - string + - "null" + language: + type: + - string + - "null" + linkedIn: + type: + - string + - "null" + name: + type: + - string + - "null" + order: + type: + - number + - "null" + phone: + type: + - string + - "null" + position: + type: + - string + - "null" + twitter: + type: + - string + - "null" + web: + type: + - string + - "null" + required: + - id + workshops: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + description: + type: + - string + - "null" + available: + type: + - number + - "null" + booked: + type: + - boolean + - "null" + booking_info: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + available: + type: + - number + - "null" + booked: + type: + - boolean + - "null" + booked_attendees: + type: + - array + - "null" + capacity: + type: + - number + - "null" + id: + type: + - number + - "null" + lecture_id: + type: + - number + - "null" + capacity: + type: + - number + - "null" + code: + type: + - string + - "null" + created_at: + type: + - string + - "null" + discussion: + type: + - number + - "null" + end: + type: + - string + - "null" + event_day_id: + type: + - number + - "null" + event_id: + type: + - number + - "null" + files: + type: + - array + - "null" + hall_id: + type: + - number + - "null" + id: + type: number + laravel_through_key: + type: + - number + - "null" + mentoring: + type: + - boolean + - "null" + moderating: + type: + - boolean + - "null" + name: + type: + - string + - "null" + overlapping: + type: + - boolean + - "null" + panel_discussion: + type: + - number + - "null" + polling: + type: + - boolean + - "null" + qr_code_url: + type: + - string + - "null" + speakers: + type: + - array + - "null" + start: + type: + - string + - "null" + tracks: + type: + - array + - "null" + updated_at: + type: + - string + - "null" + required: + - id + pauses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + end: + type: + - string + - "null" + event_day_id: + type: + - number + - "null" + event_id: + type: + - number + - "null" + id: + type: number + laravel_through_key: + type: + - number + - "null" + name: + type: + - string + - "null" + start: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + tracks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + color: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + order: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + required: + - id + partners: + type: object + $schema: http://json-schema.org/schema# + properties: + description: + type: + - string + - "null" + address: + type: + - string + - "null" + code: + type: + - string + - "null" + company: + type: + - string + - "null" + created_at: + type: + - string + - "null" + email: + type: + - string + - "null" + exhibitor: + type: + - boolean + - "null" + exhibitor_info: + type: + - object + - "null" + properties: + booth_number: + type: + - string + - "null" + order: + type: + - number + - "null" + photo: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + height: + type: + - number + - "null" + id: + type: + - number + - "null" + thumbnail: + type: + - string + - "null" + url: + type: + - string + - "null" + width: + type: + - number + - "null" + id: + type: number + logo: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + height: + type: + - number + - "null" + id: + type: + - number + - "null" + thumbnail: + type: + - string + - "null" + url: + type: + - string + - "null" + width: + type: + - number + - "null" + phone: + type: + - string + - "null" + photo: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + height: + type: + - number + - "null" + id: + type: + - number + - "null" + thumbnail: + type: + - string + - "null" + url: + type: + - string + - "null" + width: + type: + - number + - "null" + qr_code_url: + type: + - string + - "null" + sections: + type: + - array + - "null" + sponsor: + type: + - boolean + - "null" + sponsor_info: + type: + - object + - "null" + properties: + order: + type: + - number + - "null" + photo: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + height: + type: + - number + - "null" + id: + type: + - number + - "null" + thumbnail: + type: + - string + - "null" + url: + type: + - string + - "null" + width: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + web: + type: + - string + - "null" + required: + - id + additionalProperties: true + participants: + type: object + $schema: http://json-schema.org/schema# + properties: + email: + type: string + name: + type: + - string + - "null" + role: + type: + - string + - "null" + required: + - email + additionalProperties: true diff --git a/airbyte-integrations/connectors/source-eventee/metadata.yaml b/airbyte-integrations/connectors/source-eventee/metadata.yaml new file mode 100644 index 000000000000..ee538343d70f --- /dev/null +++ b/airbyte-integrations/connectors/source-eventee/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.eventee.co" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-eventee + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 8be64312-22e6-4c6d-8738-2294bd565139 + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-eventee + githubIssueLabel: source-eventee + icon: icon.svg + license: MIT + name: Eventee + releaseDate: 2024-10-28 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/eventee + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-eventzilla/README.md b/airbyte-integrations/connectors/source-eventzilla/README.md new file mode 100644 index 000000000000..0ed55a327014 --- /dev/null +++ b/airbyte-integrations/connectors/source-eventzilla/README.md @@ -0,0 +1,33 @@ +# Eventzilla +This directory contains the manifest-only connector for `source-eventzilla`. + +The Airbyte connector for Eventzilla enables seamless integration between Eventzilla and various data destinations. It automates the extraction of event management data, such as attendee details, ticket sales, and event performance metrics, and syncs it with your preferred data warehouses or analytics tools. This connector helps organizations centralize and analyze their Eventzilla data for reporting, monitoring, and strategic insights. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-eventzilla:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-eventzilla build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-eventzilla test +``` + diff --git a/airbyte-integrations/connectors/source-eventzilla/acceptance-test-config.yml b/airbyte-integrations/connectors/source-eventzilla/acceptance-test-config.yml new file mode 100644 index 000000000000..3bd9cc1242ca --- /dev/null +++ b/airbyte-integrations/connectors/source-eventzilla/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-eventzilla:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-eventzilla/icon.svg b/airbyte-integrations/connectors/source-eventzilla/icon.svg new file mode 100644 index 000000000000..863c5ba893f0 --- /dev/null +++ b/airbyte-integrations/connectors/source-eventzilla/icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/airbyte-integrations/connectors/source-eventzilla/manifest.yaml b/airbyte-integrations/connectors/source-eventzilla/manifest.yaml new file mode 100644 index 000000000000..256396b5093e --- /dev/null +++ b/airbyte-integrations/connectors/source-eventzilla/manifest.yaml @@ -0,0 +1,794 @@ +version: 5.14.0 + +type: DeclarativeSource + +description: >- + The Airbyte connector for Eventzilla enables seamless integration between + Eventzilla and various data destinations. It automates the extraction of event + management data, such as attendee details, ticket sales, and event performance + metrics, and syncs it with your preferred data warehouses or analytics tools. + This connector helps organizations centralize and analyze their Eventzilla + data for reporting, monitoring, and strategic insights. + +check: + type: CheckStream + stream_names: + - tickets + +definitions: + streams: + events: + type: DeclarativeStream + name: events + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /events + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - events + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/events" + attendees: + type: DeclarativeStream + name: attendees + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /events/{{ stream_partition.event_id }}/attendees + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - attendees + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: event_id + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/attendees" + categories: + type: DeclarativeStream + name: categories + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /categories + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - categories + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/categories" + tickets: + type: DeclarativeStream + name: tickets + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /events/{{ stream_partition.event_id }}/tickets + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - tickets + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: event_id + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tickets" + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - users + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + transactions: + type: DeclarativeStream + name: transactions + primary_key: + - refno + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /events/{{ stream_partition.event_id }}/transactions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - transactions + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: event_id + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/transactions" + base_requester: + type: HttpRequester + url_base: https://www.eventzillaapi.net/api/v2 + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"x-api-key\"] }}" + inject_into: + type: RequestOption + field_name: x-api-key + inject_into: header + +streams: + - $ref: "#/definitions/streams/events" + - $ref: "#/definitions/streams/attendees" + - $ref: "#/definitions/streams/categories" + - $ref: "#/definitions/streams/tickets" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/transactions" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - x-api-key + properties: + x-api-key: + type: string + description: >- + API key to use. Generate it by creating a new application within your + Eventzilla account settings under Settings > App Management. + name: x-api-key + order: 0 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + events: true + attendees: false + categories: false + tickets: false + users: false + transactions: false + testedStreams: + events: + streamHash: f9fe484687d4e31ce37624e7eca6056fffe086ba + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + attendees: + streamHash: b6fc0aa7a306b8d42beab9cb83f46f6dfdb8d615 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + categories: + streamHash: 12edf4da2b31d4f53713f6562e12403f4b94a5e3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tickets: + streamHash: be36a1402a27c4d6bc69ffe88f9c6dfd8acb451e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + users: + streamHash: 136f69bf38a643670c0de65d045697a971d74459 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + transactions: + streamHash: 6e1d3a52da1e821680358c6bc8735bd39e9308c5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://developer.eventzilla.net/docs/ + +schemas: + events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + bgimage_url: + type: + - string + - "null" + categories: + type: + - string + - "null" + currency: + type: + - string + - "null" + dateid: + type: + - number + - "null" + description_html: + type: + - string + - "null" + end_date: + type: + - string + - "null" + end_time: + type: + - string + - "null" + id: + type: number + invite_code: + type: + - string + - "null" + language: + type: + - string + - "null" + logo_url: + type: + - string + - "null" + show_remaining: + type: + - boolean + - "null" + start_date: + type: + - string + - "null" + start_time: + type: + - string + - "null" + status: + type: + - string + - "null" + tickets_sold: + type: + - number + - "null" + tickets_total: + type: + - number + - "null" + time_zone: + type: + - string + - "null" + timezone_code: + type: + - string + - "null" + title: + type: + - string + - "null" + twitter_hashtag: + type: + - string + - "null" + url: + type: + - string + - "null" + utc_offset: + type: + - string + - "null" + venue: + type: + - string + - "null" + required: + - id + attendees: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + bar_code: + type: + - string + - "null" + buyer_first_name: + type: + - string + - "null" + buyer_last_name: + type: + - string + - "null" + email: + type: + - string + - "null" + event_date: + type: + - string + - "null" + event_id: + type: + - number + - "null" + first_name: + type: + - string + - "null" + id: + type: number + is_attended: + type: + - string + - "null" + last_name: + type: + - string + - "null" + payment_type: + type: + - string + - "null" + questions: + type: + - array + - "null" + refno: + type: + - string + - "null" + ticket_type: + type: + - string + - "null" + transaction_amount: + type: + - number + - "null" + transaction_date: + type: + - string + - "null" + transaction_status: + type: + - string + - "null" + required: + - id + categories: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + category: + type: string + required: + - category + tickets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + additional_instructions: + type: + - string + - "null" + allow_partial_payment: + type: + - boolean + - "null" + boxoffice_only: + type: + - boolean + - "null" + group_discount: + type: + - number + - "null" + group_percentage: + type: + - number + - "null" + group_price: + type: + - number + - "null" + id: + type: number + is_visible: + type: + - boolean + - "null" + limit_maximum: + type: + - number + - "null" + limit_minimum: + type: + - number + - "null" + partial_payment_amount: + type: + - number + - "null" + partial_payment_frequency: + type: + - string + - "null" + partial_payment_installments: + type: + - number + - "null" + price: + type: + - number + - "null" + quantity_total: + type: + - number + - "null" + sales_end_date: + type: + - string + - "null" + sales_end_time: + type: + - string + - "null" + sales_start_date: + type: + - string + - "null" + sales_start_time: + type: + - string + - "null" + ticket_type: + type: + - string + - "null" + title: + type: + - string + - "null" + unlock_code: + type: + - string + - "null" + required: + - id + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address_country: + type: + - string + - "null" + address_line1: + type: + - string + - "null" + address_line2: + type: + - string + - "null" + address_locality: + type: + - string + - "null" + address_region: + type: + - string + - "null" + avatar_url: + type: + - string + - "null" + company: + type: + - string + - "null" + email: + type: + - string + - "null" + facebook_id: + type: + - string + - "null" + first_name: + type: + - string + - "null" + id: + type: number + last_name: + type: + - string + - "null" + last_seen: + type: + - string + - "null" + phone_primary: + type: + - string + - "null" + timezone: + type: + - string + - "null" + twitter_id: + type: + - string + - "null" + user_type: + type: + - string + - "null" + username: + type: + - string + - "null" + website: + type: + - string + - "null" + zip_code: + type: + - string + - "null" + required: + - id + transactions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + buyer_first_name: + type: + - string + - "null" + buyer_last_name: + type: + - string + - "null" + checkout_id: + type: + - number + - "null" + comments: + type: + - string + - "null" + email: + type: + - string + - "null" + event_date: + type: + - string + - "null" + event_id: + type: + - number + - "null" + eventzilla_fee: + type: + - number + - "null" + payment_type: + type: + - string + - "null" + promo_code: + type: + - string + - "null" + refno: + type: string + tickets_in_transaction: + type: + - number + - "null" + title: + type: + - string + - "null" + transaction_amount: + type: + - number + - "null" + transaction_date: + type: + - string + - "null" + transaction_discount: + type: + - number + - "null" + transaction_status: + type: + - string + - "null" + transaction_tax: + type: + - number + - "null" + user_id: + type: + - number + - "null" + required: + - refno diff --git a/airbyte-integrations/connectors/source-eventzilla/metadata.yaml b/airbyte-integrations/connectors/source-eventzilla/metadata.yaml new file mode 100644 index 000000000000..cf02e30fd971 --- /dev/null +++ b/airbyte-integrations/connectors/source-eventzilla/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "eventzillaapi.net" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-eventzilla + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: ba6ddcf2-00c7-44f2-9cee-2d295bd0c854 + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-eventzilla + githubIssueLabel: source-eventzilla + icon: icon.svg + license: MIT + name: Eventzilla + releaseDate: 2024-10-23 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/eventzilla + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-everhour/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-everhour/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-everhour/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-everhour/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-everhour/metadata.yaml b/airbyte-integrations/connectors/source-everhour/metadata.yaml index bbcd3b2325ce..6ad09fc5780e 100644 --- a/airbyte-integrations/connectors/source-everhour/metadata.yaml +++ b/airbyte-integrations/connectors/source-everhour/metadata.yaml @@ -18,11 +18,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 6babfc42-c734-4ef6-a817-6eca15f0f9b7 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-everhour githubIssueLabel: source-everhour icon: everhour.svg diff --git a/airbyte-integrations/connectors/source-exchange-rates/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-exchange-rates/integration_tests/acceptance.py index efc25f08ce82..78b220cebb18 100644 --- a/airbyte-integrations/connectors/source-exchange-rates/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-exchange-rates/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-exchange-rates/metadata.yaml b/airbyte-integrations/connectors/source-exchange-rates/metadata.yaml index c27e90c6d766..164d2ebdb8f2 100644 --- a/airbyte-integrations/connectors/source-exchange-rates/metadata.yaml +++ b/airbyte-integrations/connectors/source-exchange-rates/metadata.yaml @@ -16,11 +16,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: e2b40e36-aa0e-4bed-b41b-bcea6fa348b1 - dockerImageTag: 1.4.3 + dockerImageTag: 1.4.6 dockerRepository: airbyte/source-exchange-rates githubIssueLabel: source-exchange-rates icon: exchangeratesapi.svg diff --git a/airbyte-integrations/connectors/source-ezofficeinventory/metadata.yaml b/airbyte-integrations/connectors/source-ezofficeinventory/metadata.yaml index 691456e30b98..a21c5b450738 100644 --- a/airbyte-integrations/connectors/source-ezofficeinventory/metadata.yaml +++ b/airbyte-integrations/connectors/source-ezofficeinventory/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-ezofficeinventory connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 7b6be0f6-4139-42f8-a89e-2ca25560979a - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.9 dockerRepository: airbyte/source-ezofficeinventory githubIssueLabel: source-ezofficeinventory icon: icon.svg diff --git a/airbyte-integrations/connectors/source-facebook-marketing/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-facebook-marketing/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-facebook-marketing/main.py b/airbyte-integrations/connectors/source-facebook-marketing/main.py index fc25c7149e93..b0d0f19d8d9f 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/main.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/main.py @@ -5,5 +5,6 @@ from source_facebook_marketing.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-facebook-marketing/metadata.yaml b/airbyte-integrations/connectors/source-facebook-marketing/metadata.yaml index c675cda30b89..8a8665d4d52b 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/metadata.yaml +++ b/airbyte-integrations/connectors/source-facebook-marketing/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - graph.facebook.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: e7778cfc-e97c-4458-9ecb-b4f2bba8946c - dockerImageTag: 3.3.18 + dockerImageTag: 3.3.24 dockerRepository: airbyte/source-facebook-marketing documentationUrl: https://docs.airbyte.com/integrations/sources/facebook-marketing githubIssueLabel: source-facebook-marketing diff --git a/airbyte-integrations/connectors/source-facebook-marketing/poetry.lock b/airbyte-integrations/connectors/source-facebook-marketing/poetry.lock index bb52418e1d79..d805104325c4 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/poetry.lock +++ b/airbyte-integrations/connectors/source-facebook-marketing/poetry.lock @@ -2,136 +2,122 @@ [[package]] name = "aiohappyeyeballs" -version = "2.4.3" +version = "2.4.4" description = "Happy Eyeballs for asyncio" optional = false python-versions = ">=3.8" files = [ - {file = "aiohappyeyeballs-2.4.3-py3-none-any.whl", hash = "sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572"}, - {file = "aiohappyeyeballs-2.4.3.tar.gz", hash = "sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586"}, + {file = "aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8"}, + {file = "aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745"}, ] [[package]] name = "aiohttp" -version = "3.10.10" +version = "3.11.11" description = "Async http client/server framework (asyncio)" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "aiohttp-3.10.10-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:be7443669ae9c016b71f402e43208e13ddf00912f47f623ee5994e12fc7d4b3f"}, - {file = "aiohttp-3.10.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7b06b7843929e41a94ea09eb1ce3927865387e3e23ebe108e0d0d09b08d25be9"}, - {file = "aiohttp-3.10.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:333cf6cf8e65f6a1e06e9eb3e643a0c515bb850d470902274239fea02033e9a8"}, - {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:274cfa632350225ce3fdeb318c23b4a10ec25c0e2c880eff951a3842cf358ac1"}, - {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9e5e4a85bdb56d224f412d9c98ae4cbd032cc4f3161818f692cd81766eee65a"}, - {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b606353da03edcc71130b52388d25f9a30a126e04caef1fd637e31683033abd"}, - {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab5a5a0c7a7991d90446a198689c0535be89bbd6b410a1f9a66688f0880ec026"}, - {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:578a4b875af3e0daaf1ac6fa983d93e0bbfec3ead753b6d6f33d467100cdc67b"}, - {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8105fd8a890df77b76dd3054cddf01a879fc13e8af576805d667e0fa0224c35d"}, - {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3bcd391d083f636c06a68715e69467963d1f9600f85ef556ea82e9ef25f043f7"}, - {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fbc6264158392bad9df19537e872d476f7c57adf718944cc1e4495cbabf38e2a"}, - {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e48d5021a84d341bcaf95c8460b152cfbad770d28e5fe14a768988c461b821bc"}, - {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2609e9ab08474702cc67b7702dbb8a80e392c54613ebe80db7e8dbdb79837c68"}, - {file = "aiohttp-3.10.10-cp310-cp310-win32.whl", hash = "sha256:84afcdea18eda514c25bc68b9af2a2b1adea7c08899175a51fe7c4fb6d551257"}, - {file = "aiohttp-3.10.10-cp310-cp310-win_amd64.whl", hash = "sha256:9c72109213eb9d3874f7ac8c0c5fa90e072d678e117d9061c06e30c85b4cf0e6"}, - {file = "aiohttp-3.10.10-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c30a0eafc89d28e7f959281b58198a9fa5e99405f716c0289b7892ca345fe45f"}, - {file = "aiohttp-3.10.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:258c5dd01afc10015866114e210fb7365f0d02d9d059c3c3415382ab633fcbcb"}, - {file = "aiohttp-3.10.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:15ecd889a709b0080f02721255b3f80bb261c2293d3c748151274dfea93ac871"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3935f82f6f4a3820270842e90456ebad3af15810cf65932bd24da4463bc0a4c"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:413251f6fcf552a33c981c4709a6bba37b12710982fec8e558ae944bfb2abd38"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1720b4f14c78a3089562b8875b53e36b51c97c51adc53325a69b79b4b48ebcb"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:679abe5d3858b33c2cf74faec299fda60ea9de62916e8b67e625d65bf069a3b7"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79019094f87c9fb44f8d769e41dbb664d6e8fcfd62f665ccce36762deaa0e911"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe2fb38c2ed905a2582948e2de560675e9dfbee94c6d5ccdb1301c6d0a5bf092"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a3f00003de6eba42d6e94fabb4125600d6e484846dbf90ea8e48a800430cc142"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1bbb122c557a16fafc10354b9d99ebf2f2808a660d78202f10ba9d50786384b9"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:30ca7c3b94708a9d7ae76ff281b2f47d8eaf2579cd05971b5dc681db8caac6e1"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:df9270660711670e68803107d55c2b5949c2e0f2e4896da176e1ecfc068b974a"}, - {file = "aiohttp-3.10.10-cp311-cp311-win32.whl", hash = "sha256:aafc8ee9b742ce75044ae9a4d3e60e3d918d15a4c2e08a6c3c3e38fa59b92d94"}, - {file = "aiohttp-3.10.10-cp311-cp311-win_amd64.whl", hash = "sha256:362f641f9071e5f3ee6f8e7d37d5ed0d95aae656adf4ef578313ee585b585959"}, - {file = "aiohttp-3.10.10-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9294bbb581f92770e6ed5c19559e1e99255e4ca604a22c5c6397b2f9dd3ee42c"}, - {file = "aiohttp-3.10.10-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a8fa23fe62c436ccf23ff930149c047f060c7126eae3ccea005f0483f27b2e28"}, - {file = "aiohttp-3.10.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5c6a5b8c7926ba5d8545c7dd22961a107526562da31a7a32fa2456baf040939f"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:007ec22fbc573e5eb2fb7dec4198ef8f6bf2fe4ce20020798b2eb5d0abda6138"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9627cc1a10c8c409b5822a92d57a77f383b554463d1884008e051c32ab1b3742"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:50edbcad60d8f0e3eccc68da67f37268b5144ecc34d59f27a02f9611c1d4eec7"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a45d85cf20b5e0d0aa5a8dca27cce8eddef3292bc29d72dcad1641f4ed50aa16"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b00807e2605f16e1e198f33a53ce3c4523114059b0c09c337209ae55e3823a8"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f2d4324a98062be0525d16f768a03e0bbb3b9fe301ceee99611dc9a7953124e6"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:438cd072f75bb6612f2aca29f8bd7cdf6e35e8f160bc312e49fbecab77c99e3a"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:baa42524a82f75303f714108fea528ccacf0386af429b69fff141ffef1c534f9"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a7d8d14fe962153fc681f6366bdec33d4356f98a3e3567782aac1b6e0e40109a"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c1277cd707c465cd09572a774559a3cc7c7a28802eb3a2a9472588f062097205"}, - {file = "aiohttp-3.10.10-cp312-cp312-win32.whl", hash = "sha256:59bb3c54aa420521dc4ce3cc2c3fe2ad82adf7b09403fa1f48ae45c0cbde6628"}, - {file = "aiohttp-3.10.10-cp312-cp312-win_amd64.whl", hash = "sha256:0e1b370d8007c4ae31ee6db7f9a2fe801a42b146cec80a86766e7ad5c4a259cf"}, - {file = "aiohttp-3.10.10-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ad7593bb24b2ab09e65e8a1d385606f0f47c65b5a2ae6c551db67d6653e78c28"}, - {file = "aiohttp-3.10.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1eb89d3d29adaf533588f209768a9c02e44e4baf832b08118749c5fad191781d"}, - {file = "aiohttp-3.10.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3fe407bf93533a6fa82dece0e74dbcaaf5d684e5a51862887f9eaebe6372cd79"}, - {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50aed5155f819873d23520919e16703fc8925e509abbb1a1491b0087d1cd969e"}, - {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f05e9727ce409358baa615dbeb9b969db94324a79b5a5cea45d39bdb01d82e6"}, - {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dffb610a30d643983aeb185ce134f97f290f8935f0abccdd32c77bed9388b42"}, - {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa6658732517ddabe22c9036479eabce6036655ba87a0224c612e1ae6af2087e"}, - {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:741a46d58677d8c733175d7e5aa618d277cd9d880301a380fd296975a9cdd7bc"}, - {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e00e3505cd80440f6c98c6d69269dcc2a119f86ad0a9fd70bccc59504bebd68a"}, - {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ffe595f10566f8276b76dc3a11ae4bb7eba1aac8ddd75811736a15b0d5311414"}, - {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdfcf6443637c148c4e1a20c48c566aa694fa5e288d34b20fcdc58507882fed3"}, - {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d183cf9c797a5291e8301790ed6d053480ed94070637bfaad914dd38b0981f67"}, - {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:77abf6665ae54000b98b3c742bc6ea1d1fb31c394bcabf8b5d2c1ac3ebfe7f3b"}, - {file = "aiohttp-3.10.10-cp313-cp313-win32.whl", hash = "sha256:4470c73c12cd9109db8277287d11f9dd98f77fc54155fc71a7738a83ffcc8ea8"}, - {file = "aiohttp-3.10.10-cp313-cp313-win_amd64.whl", hash = "sha256:486f7aabfa292719a2753c016cc3a8f8172965cabb3ea2e7f7436c7f5a22a151"}, - {file = "aiohttp-3.10.10-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:1b66ccafef7336a1e1f0e389901f60c1d920102315a56df85e49552308fc0486"}, - {file = "aiohttp-3.10.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:acd48d5b80ee80f9432a165c0ac8cbf9253eaddb6113269a5e18699b33958dbb"}, - {file = "aiohttp-3.10.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3455522392fb15ff549d92fbf4b73b559d5e43dc522588f7eb3e54c3f38beee7"}, - {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45c3b868724137f713a38376fef8120c166d1eadd50da1855c112fe97954aed8"}, - {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:da1dee8948d2137bb51fbb8a53cce6b1bcc86003c6b42565f008438b806cccd8"}, - {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5ce2ce7c997e1971b7184ee37deb6ea9922ef5163c6ee5aa3c274b05f9e12fa"}, - {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28529e08fde6f12eba8677f5a8608500ed33c086f974de68cc65ab218713a59d"}, - {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f7db54c7914cc99d901d93a34704833568d86c20925b2762f9fa779f9cd2e70f"}, - {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:03a42ac7895406220124c88911ebee31ba8b2d24c98507f4a8bf826b2937c7f2"}, - {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:7e338c0523d024fad378b376a79faff37fafb3c001872a618cde1d322400a572"}, - {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:038f514fe39e235e9fef6717fbf944057bfa24f9b3db9ee551a7ecf584b5b480"}, - {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:64f6c17757251e2b8d885d728b6433d9d970573586a78b78ba8929b0f41d045a"}, - {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:93429602396f3383a797a2a70e5f1de5df8e35535d7806c9f91df06f297e109b"}, - {file = "aiohttp-3.10.10-cp38-cp38-win32.whl", hash = "sha256:c823bc3971c44ab93e611ab1a46b1eafeae474c0c844aff4b7474287b75fe49c"}, - {file = "aiohttp-3.10.10-cp38-cp38-win_amd64.whl", hash = "sha256:54ca74df1be3c7ca1cf7f4c971c79c2daf48d9aa65dea1a662ae18926f5bc8ce"}, - {file = "aiohttp-3.10.10-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:01948b1d570f83ee7bbf5a60ea2375a89dfb09fd419170e7f5af029510033d24"}, - {file = "aiohttp-3.10.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9fc1500fd2a952c5c8e3b29aaf7e3cc6e27e9cfc0a8819b3bce48cc1b849e4cc"}, - {file = "aiohttp-3.10.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f614ab0c76397661b90b6851a030004dac502e48260ea10f2441abd2207fbcc7"}, - {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00819de9e45d42584bed046314c40ea7e9aea95411b38971082cad449392b08c"}, - {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05646ebe6b94cc93407b3bf34b9eb26c20722384d068eb7339de802154d61bc5"}, - {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:998f3bd3cfc95e9424a6acd7840cbdd39e45bc09ef87533c006f94ac47296090"}, - {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9010c31cd6fa59438da4e58a7f19e4753f7f264300cd152e7f90d4602449762"}, - {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ea7ffc6d6d6f8a11e6f40091a1040995cdff02cfc9ba4c2f30a516cb2633554"}, - {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ef9c33cc5cbca35808f6c74be11eb7f5f6b14d2311be84a15b594bd3e58b5527"}, - {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ce0cdc074d540265bfeb31336e678b4e37316849d13b308607efa527e981f5c2"}, - {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:597a079284b7ee65ee102bc3a6ea226a37d2b96d0418cc9047490f231dc09fe8"}, - {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:7789050d9e5d0c309c706953e5e8876e38662d57d45f936902e176d19f1c58ab"}, - {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e7f8b04d83483577fd9200461b057c9f14ced334dcb053090cea1da9c8321a91"}, - {file = "aiohttp-3.10.10-cp39-cp39-win32.whl", hash = "sha256:c02a30b904282777d872266b87b20ed8cc0d1501855e27f831320f471d54d983"}, - {file = "aiohttp-3.10.10-cp39-cp39-win_amd64.whl", hash = "sha256:edfe3341033a6b53a5c522c802deb2079eee5cbfbb0af032a55064bd65c73a23"}, - {file = "aiohttp-3.10.10.tar.gz", hash = "sha256:0631dd7c9f0822cc61c88586ca76d5b5ada26538097d0f1df510b082bad3411a"}, + {file = "aiohttp-3.11.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a60804bff28662cbcf340a4d61598891f12eea3a66af48ecfdc975ceec21e3c8"}, + {file = "aiohttp-3.11.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b4fa1cb5f270fb3eab079536b764ad740bb749ce69a94d4ec30ceee1b5940d5"}, + {file = "aiohttp-3.11.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:731468f555656767cda219ab42e033355fe48c85fbe3ba83a349631541715ba2"}, + {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb23d8bb86282b342481cad4370ea0853a39e4a32a0042bb52ca6bdde132df43"}, + {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f047569d655f81cb70ea5be942ee5d4421b6219c3f05d131f64088c73bb0917f"}, + {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd7659baae9ccf94ae5fe8bfaa2c7bc2e94d24611528395ce88d009107e00c6d"}, + {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af01e42ad87ae24932138f154105e88da13ce7d202a6de93fafdafb2883a00ef"}, + {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5854be2f3e5a729800bac57a8d76af464e160f19676ab6aea74bde18ad19d438"}, + {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6526e5fb4e14f4bbf30411216780c9967c20c5a55f2f51d3abd6de68320cc2f3"}, + {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:85992ee30a31835fc482468637b3e5bd085fa8fe9392ba0bdcbdc1ef5e9e3c55"}, + {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:88a12ad8ccf325a8a5ed80e6d7c3bdc247d66175afedbe104ee2aaca72960d8e"}, + {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0a6d3fbf2232e3a08c41eca81ae4f1dff3d8f1a30bae415ebe0af2d2458b8a33"}, + {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84a585799c58b795573c7fa9b84c455adf3e1d72f19a2bf498b54a95ae0d194c"}, + {file = "aiohttp-3.11.11-cp310-cp310-win32.whl", hash = "sha256:bfde76a8f430cf5c5584553adf9926534352251d379dcb266ad2b93c54a29745"}, + {file = "aiohttp-3.11.11-cp310-cp310-win_amd64.whl", hash = "sha256:0fd82b8e9c383af11d2b26f27a478640b6b83d669440c0a71481f7c865a51da9"}, + {file = "aiohttp-3.11.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ba74ec819177af1ef7f59063c6d35a214a8fde6f987f7661f4f0eecc468a8f76"}, + {file = "aiohttp-3.11.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4af57160800b7a815f3fe0eba9b46bf28aafc195555f1824555fa2cfab6c1538"}, + {file = "aiohttp-3.11.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ffa336210cf9cd8ed117011085817d00abe4c08f99968deef0013ea283547204"}, + {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81b8fe282183e4a3c7a1b72f5ade1094ed1c6345a8f153506d114af5bf8accd9"}, + {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3af41686ccec6a0f2bdc66686dc0f403c41ac2089f80e2214a0f82d001052c03"}, + {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70d1f9dde0e5dd9e292a6d4d00058737052b01f3532f69c0c65818dac26dc287"}, + {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:249cc6912405917344192b9f9ea5cd5b139d49e0d2f5c7f70bdfaf6b4dbf3a2e"}, + {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0eb98d90b6690827dcc84c246811feeb4e1eea683c0eac6caed7549be9c84665"}, + {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec82bf1fda6cecce7f7b915f9196601a1bd1a3079796b76d16ae4cce6d0ef89b"}, + {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9fd46ce0845cfe28f108888b3ab17abff84ff695e01e73657eec3f96d72eef34"}, + {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:bd176afcf8f5d2aed50c3647d4925d0db0579d96f75a31e77cbaf67d8a87742d"}, + {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ec2aa89305006fba9ffb98970db6c8221541be7bee4c1d027421d6f6df7d1ce2"}, + {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:92cde43018a2e17d48bb09c79e4d4cb0e236de5063ce897a5e40ac7cb4878773"}, + {file = "aiohttp-3.11.11-cp311-cp311-win32.whl", hash = "sha256:aba807f9569455cba566882c8938f1a549f205ee43c27b126e5450dc9f83cc62"}, + {file = "aiohttp-3.11.11-cp311-cp311-win_amd64.whl", hash = "sha256:ae545f31489548c87b0cced5755cfe5a5308d00407000e72c4fa30b19c3220ac"}, + {file = "aiohttp-3.11.11-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e595c591a48bbc295ebf47cb91aebf9bd32f3ff76749ecf282ea7f9f6bb73886"}, + {file = "aiohttp-3.11.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3ea1b59dc06396b0b424740a10a0a63974c725b1c64736ff788a3689d36c02d2"}, + {file = "aiohttp-3.11.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8811f3f098a78ffa16e0ea36dffd577eb031aea797cbdba81be039a4169e242c"}, + {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7227b87a355ce1f4bf83bfae4399b1f5bb42e0259cb9405824bd03d2f4336a"}, + {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d40f9da8cabbf295d3a9dae1295c69975b86d941bc20f0a087f0477fa0a66231"}, + {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffb3dc385f6bb1568aa974fe65da84723210e5d9707e360e9ecb51f59406cd2e"}, + {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8f5f7515f3552d899c61202d99dcb17d6e3b0de777900405611cd747cecd1b8"}, + {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3499c7ffbfd9c6a3d8d6a2b01c26639da7e43d47c7b4f788016226b1e711caa8"}, + {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8e2bf8029dbf0810c7bfbc3e594b51c4cc9101fbffb583a3923aea184724203c"}, + {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b6212a60e5c482ef90f2d788835387070a88d52cf6241d3916733c9176d39eab"}, + {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d119fafe7b634dbfa25a8c597718e69a930e4847f0b88e172744be24515140da"}, + {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:6fba278063559acc730abf49845d0e9a9e1ba74f85f0ee6efd5803f08b285853"}, + {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:92fc484e34b733704ad77210c7957679c5c3877bd1e6b6d74b185e9320cc716e"}, + {file = "aiohttp-3.11.11-cp312-cp312-win32.whl", hash = "sha256:9f5b3c1ed63c8fa937a920b6c1bec78b74ee09593b3f5b979ab2ae5ef60d7600"}, + {file = "aiohttp-3.11.11-cp312-cp312-win_amd64.whl", hash = "sha256:1e69966ea6ef0c14ee53ef7a3d68b564cc408121ea56c0caa2dc918c1b2f553d"}, + {file = "aiohttp-3.11.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:541d823548ab69d13d23730a06f97460f4238ad2e5ed966aaf850d7c369782d9"}, + {file = "aiohttp-3.11.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:929f3ed33743a49ab127c58c3e0a827de0664bfcda566108989a14068f820194"}, + {file = "aiohttp-3.11.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0882c2820fd0132240edbb4a51eb8ceb6eef8181db9ad5291ab3332e0d71df5f"}, + {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b63de12e44935d5aca7ed7ed98a255a11e5cb47f83a9fded7a5e41c40277d104"}, + {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa54f8ef31d23c506910c21163f22b124facb573bff73930735cf9fe38bf7dff"}, + {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a344d5dc18074e3872777b62f5f7d584ae4344cd6006c17ba12103759d407af3"}, + {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7fb429ab1aafa1f48578eb315ca45bd46e9c37de11fe45c7f5f4138091e2f1"}, + {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c341c7d868750e31961d6d8e60ff040fb9d3d3a46d77fd85e1ab8e76c3e9a5c4"}, + {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed9ee95614a71e87f1a70bc81603f6c6760128b140bc4030abe6abaa988f1c3d"}, + {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:de8d38f1c2810fa2a4f1d995a2e9c70bb8737b18da04ac2afbf3971f65781d87"}, + {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a9b7371665d4f00deb8f32208c7c5e652059b0fda41cf6dbcac6114a041f1cc2"}, + {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:620598717fce1b3bd14dd09947ea53e1ad510317c85dda2c9c65b622edc96b12"}, + {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf8d9bfee991d8acc72d060d53860f356e07a50f0e0d09a8dfedea1c554dd0d5"}, + {file = "aiohttp-3.11.11-cp313-cp313-win32.whl", hash = "sha256:9d73ee3725b7a737ad86c2eac5c57a4a97793d9f442599bea5ec67ac9f4bdc3d"}, + {file = "aiohttp-3.11.11-cp313-cp313-win_amd64.whl", hash = "sha256:c7a06301c2fb096bdb0bd25fe2011531c1453b9f2c163c8031600ec73af1cc99"}, + {file = "aiohttp-3.11.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3e23419d832d969f659c208557de4a123e30a10d26e1e14b73431d3c13444c2e"}, + {file = "aiohttp-3.11.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:21fef42317cf02e05d3b09c028712e1d73a9606f02467fd803f7c1f39cc59add"}, + {file = "aiohttp-3.11.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1f21bb8d0235fc10c09ce1d11ffbd40fc50d3f08a89e4cf3a0c503dc2562247a"}, + {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1642eceeaa5ab6c9b6dfeaaa626ae314d808188ab23ae196a34c9d97efb68350"}, + {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2170816e34e10f2fd120f603e951630f8a112e1be3b60963a1f159f5699059a6"}, + {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8be8508d110d93061197fd2d6a74f7401f73b6d12f8822bbcd6d74f2b55d71b1"}, + {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4eed954b161e6b9b65f6be446ed448ed3921763cc432053ceb606f89d793927e"}, + {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6c9af134da4bc9b3bd3e6a70072509f295d10ee60c697826225b60b9959acdd"}, + {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:44167fc6a763d534a6908bdb2592269b4bf30a03239bcb1654781adf5e49caf1"}, + {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:479b8c6ebd12aedfe64563b85920525d05d394b85f166b7873c8bde6da612f9c"}, + {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:10b4ff0ad793d98605958089fabfa350e8e62bd5d40aa65cdc69d6785859f94e"}, + {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:b540bd67cfb54e6f0865ceccd9979687210d7ed1a1cc8c01f8e67e2f1e883d28"}, + {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dac54e8ce2ed83b1f6b1a54005c87dfed139cf3f777fdc8afc76e7841101226"}, + {file = "aiohttp-3.11.11-cp39-cp39-win32.whl", hash = "sha256:568c1236b2fde93b7720f95a890741854c1200fba4a3471ff48b2934d2d93fd3"}, + {file = "aiohttp-3.11.11-cp39-cp39-win_amd64.whl", hash = "sha256:943a8b052e54dfd6439fd7989f67fc6a7f2138d0a2cf0a7de5f18aa4fe7eb3b1"}, + {file = "aiohttp-3.11.11.tar.gz", hash = "sha256:bb49c7f1e6ebf3821a42d81d494f538107610c3a705987f53068546b0e90303e"}, ] [package.dependencies] aiohappyeyeballs = ">=2.3.0" aiosignal = ">=1.1.2" -async-timeout = {version = ">=4.0,<5.0", markers = "python_version < \"3.11\""} +async-timeout = {version = ">=4.0,<6.0", markers = "python_version < \"3.11\""} attrs = ">=17.3.0" frozenlist = ">=1.1.1" multidict = ">=4.5,<7.0" -yarl = ">=1.12.0,<2.0" +propcache = ">=0.2.0" +yarl = ">=1.17.0,<2.0" [package.extras] speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] [[package]] name = "aiosignal" -version = "1.3.1" +version = "1.3.2" description = "aiosignal: a list of registered asynchronous callbacks" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, - {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, + {file = "aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5"}, + {file = "aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54"}, ] [package.dependencies] @@ -185,13 +171,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models-dataclasses" -version = "0.13.0" +version = "0.13.1" description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models_dataclasses-0.13.0-py3-none-any.whl", hash = "sha256:0aedb99ffc4f9aab0ce91bba2c292fa17cd8fd4b42eeba196d6a16c20bbbd7a5"}, - {file = "airbyte_protocol_models_dataclasses-0.13.0.tar.gz", hash = "sha256:72e67850d661e2808406aec5839b3158ebb94d3553b798dbdae1b4a278548d2f"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1-py3-none-any.whl", hash = "sha256:20a734b7b1c3479a643777830db6a2e0a34428f33d16abcfd320552576fabe5a"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1.tar.gz", hash = "sha256:ec6a0fb6b16267bde910f52279445d06c8e1a3e4ed82ac2937b405ab280449d5"}, ] [[package]] @@ -207,35 +193,35 @@ files = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] name = "async-timeout" -version = "4.0.3" +version = "5.0.1" description = "Timeout context manager for asyncio programs" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, - {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, + {file = "async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c"}, + {file = "async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3"}, ] [[package]] @@ -251,19 +237,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -340,13 +326,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -430,127 +416,114 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -636,20 +609,20 @@ requests = "*" [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -845,13 +818,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -866,13 +839,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -880,7 +853,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -930,13 +902,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -1037,22 +1009,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -1254,131 +1229,150 @@ twitter = ["twython"] [[package]] name = "numpy" -version = "2.1.2" +version = "2.2.1" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.10" files = [ - {file = "numpy-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466"}, - {file = "numpy-2.1.2-cp310-cp310-win32.whl", hash = "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb"}, - {file = "numpy-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146"}, - {file = "numpy-2.1.2-cp311-cp311-win32.whl", hash = "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c"}, - {file = "numpy-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142"}, - {file = "numpy-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550"}, - {file = "numpy-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe"}, - {file = "numpy-2.1.2-cp313-cp313-win32.whl", hash = "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a"}, - {file = "numpy-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e"}, - {file = "numpy-2.1.2.tar.gz", hash = "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c"}, + {file = "numpy-2.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5edb4e4caf751c1518e6a26a83501fda79bff41cc59dac48d70e6d65d4ec4440"}, + {file = "numpy-2.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aa3017c40d513ccac9621a2364f939d39e550c542eb2a894b4c8da92b38896ab"}, + {file = "numpy-2.2.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:61048b4a49b1c93fe13426e04e04fdf5a03f456616f6e98c7576144677598675"}, + {file = "numpy-2.2.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:7671dc19c7019103ca44e8d94917eba8534c76133523ca8406822efdd19c9308"}, + {file = "numpy-2.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4250888bcb96617e00bfa28ac24850a83c9f3a16db471eca2ee1f1714df0f957"}, + {file = "numpy-2.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7746f235c47abc72b102d3bce9977714c2444bdfaea7888d241b4c4bb6a78bf"}, + {file = "numpy-2.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:059e6a747ae84fce488c3ee397cee7e5f905fd1bda5fb18c66bc41807ff119b2"}, + {file = "numpy-2.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f62aa6ee4eb43b024b0e5a01cf65a0bb078ef8c395e8713c6e8a12a697144528"}, + {file = "numpy-2.2.1-cp310-cp310-win32.whl", hash = "sha256:48fd472630715e1c1c89bf1feab55c29098cb403cc184b4859f9c86d4fcb6a95"}, + {file = "numpy-2.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:b541032178a718c165a49638d28272b771053f628382d5e9d1c93df23ff58dbf"}, + {file = "numpy-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:40f9e544c1c56ba8f1cf7686a8c9b5bb249e665d40d626a23899ba6d5d9e1484"}, + {file = "numpy-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9b57eaa3b0cd8db52049ed0330747b0364e899e8a606a624813452b8203d5f7"}, + {file = "numpy-2.2.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:bc8a37ad5b22c08e2dbd27df2b3ef7e5c0864235805b1e718a235bcb200cf1cb"}, + {file = "numpy-2.2.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:9036d6365d13b6cbe8f27a0eaf73ddcc070cae584e5ff94bb45e3e9d729feab5"}, + {file = "numpy-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51faf345324db860b515d3f364eaa93d0e0551a88d6218a7d61286554d190d73"}, + {file = "numpy-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38efc1e56b73cc9b182fe55e56e63b044dd26a72128fd2fbd502f75555d92591"}, + {file = "numpy-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:31b89fa67a8042e96715c68e071a1200c4e172f93b0fbe01a14c0ff3ff820fc8"}, + {file = "numpy-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4c86e2a209199ead7ee0af65e1d9992d1dce7e1f63c4b9a616500f93820658d0"}, + {file = "numpy-2.2.1-cp311-cp311-win32.whl", hash = "sha256:b34d87e8a3090ea626003f87f9392b3929a7bbf4104a05b6667348b6bd4bf1cd"}, + {file = "numpy-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:360137f8fb1b753c5cde3ac388597ad680eccbbbb3865ab65efea062c4a1fd16"}, + {file = "numpy-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:694f9e921a0c8f252980e85bce61ebbd07ed2b7d4fa72d0e4246f2f8aa6642ab"}, + {file = "numpy-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3683a8d166f2692664262fd4900f207791d005fb088d7fdb973cc8d663626faa"}, + {file = "numpy-2.2.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:780077d95eafc2ccc3ced969db22377b3864e5b9a0ea5eb347cc93b3ea900315"}, + {file = "numpy-2.2.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:55ba24ebe208344aa7a00e4482f65742969a039c2acfcb910bc6fcd776eb4355"}, + {file = "numpy-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b1d07b53b78bf84a96898c1bc139ad7f10fda7423f5fd158fd0f47ec5e01ac7"}, + {file = "numpy-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5062dc1a4e32a10dc2b8b13cedd58988261416e811c1dc4dbdea4f57eea61b0d"}, + {file = "numpy-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:fce4f615f8ca31b2e61aa0eb5865a21e14f5629515c9151850aa936c02a1ee51"}, + {file = "numpy-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:67d4cda6fa6ffa073b08c8372aa5fa767ceb10c9a0587c707505a6d426f4e046"}, + {file = "numpy-2.2.1-cp312-cp312-win32.whl", hash = "sha256:32cb94448be47c500d2c7a95f93e2f21a01f1fd05dd2beea1ccd049bb6001cd2"}, + {file = "numpy-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:ba5511d8f31c033a5fcbda22dd5c813630af98c70b2661f2d2c654ae3cdfcfc8"}, + {file = "numpy-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f1d09e520217618e76396377c81fba6f290d5f926f50c35f3a5f72b01a0da780"}, + {file = "numpy-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3ecc47cd7f6ea0336042be87d9e7da378e5c7e9b3c8ad0f7c966f714fc10d821"}, + {file = "numpy-2.2.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f419290bc8968a46c4933158c91a0012b7a99bb2e465d5ef5293879742f8797e"}, + {file = "numpy-2.2.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5b6c390bfaef8c45a260554888966618328d30e72173697e5cabe6b285fb2348"}, + {file = "numpy-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:526fc406ab991a340744aad7e25251dd47a6720a685fa3331e5c59fef5282a59"}, + {file = "numpy-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f74e6fdeb9a265624ec3a3918430205dff1df7e95a230779746a6af78bc615af"}, + {file = "numpy-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:53c09385ff0b72ba79d8715683c1168c12e0b6e84fb0372e97553d1ea91efe51"}, + {file = "numpy-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f3eac17d9ec51be534685ba877b6ab5edc3ab7ec95c8f163e5d7b39859524716"}, + {file = "numpy-2.2.1-cp313-cp313-win32.whl", hash = "sha256:9ad014faa93dbb52c80d8f4d3dcf855865c876c9660cb9bd7553843dd03a4b1e"}, + {file = "numpy-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:164a829b6aacf79ca47ba4814b130c4020b202522a93d7bff2202bfb33b61c60"}, + {file = "numpy-2.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4dfda918a13cc4f81e9118dea249e192ab167a0bb1966272d5503e39234d694e"}, + {file = "numpy-2.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:733585f9f4b62e9b3528dd1070ec4f52b8acf64215b60a845fa13ebd73cd0712"}, + {file = "numpy-2.2.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:89b16a18e7bba224ce5114db863e7029803c179979e1af6ad6a6b11f70545008"}, + {file = "numpy-2.2.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:676f4eebf6b2d430300f1f4f4c2461685f8269f94c89698d832cdf9277f30b84"}, + {file = "numpy-2.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27f5cdf9f493b35f7e41e8368e7d7b4bbafaf9660cba53fb21d2cd174ec09631"}, + {file = "numpy-2.2.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1ad395cf254c4fbb5b2132fee391f361a6e8c1adbd28f2cd8e79308a615fe9d"}, + {file = "numpy-2.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:08ef779aed40dbc52729d6ffe7dd51df85796a702afbf68a4f4e41fafdc8bda5"}, + {file = "numpy-2.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:26c9c4382b19fcfbbed3238a14abf7ff223890ea1936b8890f058e7ba35e8d71"}, + {file = "numpy-2.2.1-cp313-cp313t-win32.whl", hash = "sha256:93cf4e045bae74c90ca833cba583c14b62cb4ba2cba0abd2b141ab52548247e2"}, + {file = "numpy-2.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:bff7d8ec20f5f42607599f9994770fa65d76edca264a87b5e4ea5629bce12268"}, + {file = "numpy-2.2.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7ba9cc93a91d86365a5d270dee221fdc04fb68d7478e6bf6af650de78a8339e3"}, + {file = "numpy-2.2.1-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:3d03883435a19794e41f147612a77a8f56d4e52822337844fff3d4040a142964"}, + {file = "numpy-2.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4511d9e6071452b944207c8ce46ad2f897307910b402ea5fa975da32e0102800"}, + {file = "numpy-2.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5c5cc0cbabe9452038ed984d05ac87910f89370b9242371bd9079cb4af61811e"}, + {file = "numpy-2.2.1.tar.gz", hash = "sha256:45681fd7128c8ad1c379f0ca0776a8b0c6583d2f69889ddac01559dfe4390918"}, ] [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -1531,109 +1525,93 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "propcache" -version = "0.2.0" +version = "0.2.1" description = "Accelerated property cache" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"}, - {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"}, - {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"}, - {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"}, - {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, - {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, - {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544"}, - {file = "propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032"}, - {file = "propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed"}, - {file = "propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d"}, - {file = "propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798"}, - {file = "propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9"}, - {file = "propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df"}, - {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, - {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6445804cf4ec763dc70de65a3b0d9954e868609e83850a47ca4f0cb64bd79fea"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9479aa06a793c5aeba49ce5c5692ffb51fcd9a7016e017d555d5e2b0045d212"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9631c5e8b5b3a0fda99cb0d29c18133bca1e18aea9effe55adb3da1adef80d3"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3156628250f46a0895f1f36e1d4fbe062a1af8718ec3ebeb746f1d23f0c5dc4d"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b6fb63ae352e13748289f04f37868099e69dba4c2b3e271c46061e82c745634"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:887d9b0a65404929641a9fabb6452b07fe4572b269d901d622d8a34a4e9043b2"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a96dc1fa45bd8c407a0af03b2d5218392729e1822b0c32e62c5bf7eeb5fb3958"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a7e65eb5c003a303b94aa2c3852ef130230ec79e349632d030e9571b87c4698c"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:999779addc413181912e984b942fbcc951be1f5b3663cd80b2687758f434c583"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:19a0f89a7bb9d8048d9c4370c9c543c396e894c76be5525f5e1ad287f1750ddf"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1ac2f5fe02fa75f56e1ad473f1175e11f475606ec9bd0be2e78e4734ad575034"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:574faa3b79e8ebac7cb1d7930f51184ba1ccf69adfdec53a12f319a06030a68b"}, + {file = "propcache-0.2.1-cp310-cp310-win32.whl", hash = "sha256:03ff9d3f665769b2a85e6157ac8b439644f2d7fd17615a82fa55739bc97863f4"}, + {file = "propcache-0.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:2d3af2e79991102678f53e0dbf4c35de99b6b8b58f29a27ca0325816364caaba"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e"}, + {file = "propcache-0.2.1-cp311-cp311-win32.whl", hash = "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034"}, + {file = "propcache-0.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518"}, + {file = "propcache-0.2.1-cp312-cp312-win32.whl", hash = "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246"}, + {file = "propcache-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30"}, + {file = "propcache-0.2.1-cp313-cp313-win32.whl", hash = "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6"}, + {file = "propcache-0.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6a9a8c34fb7bb609419a211e59da8887eeca40d300b5ea8e56af98f6fbbb1541"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae1aa1cd222c6d205853b3013c69cd04515f9d6ab6de4b0603e2e1c33221303e"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:accb6150ce61c9c4b7738d45550806aa2b71c7668c6942f17b0ac182b6142fd4"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5eee736daafa7af6d0a2dc15cc75e05c64f37fc37bafef2e00d77c14171c2097"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7a31fc1e1bd362874863fdeed71aed92d348f5336fd84f2197ba40c59f061bd"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba4cfa1052819d16699e1d55d18c92b6e094d4517c41dd231a8b9f87b6fa681"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f089118d584e859c62b3da0892b88a83d611c2033ac410e929cb6754eec0ed16"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:781e65134efaf88feb447e8c97a51772aa75e48b794352f94cb7ea717dedda0d"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31f5af773530fd3c658b32b6bdc2d0838543de70eb9a2156c03e410f7b0d3aae"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:a7a078f5d37bee6690959c813977da5291b24286e7b962e62a94cec31aa5188b"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:cea7daf9fc7ae6687cf1e2c049752f19f146fdc37c2cc376e7d0032cf4f25347"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:8b3489ff1ed1e8315674d0775dc7d2195fb13ca17b3808721b54dbe9fd020faf"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9403db39be1393618dd80c746cb22ccda168efce239c73af13c3763ef56ffc04"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5d97151bc92d2b2578ff7ce779cdb9174337390a535953cbb9452fb65164c587"}, + {file = "propcache-0.2.1-cp39-cp39-win32.whl", hash = "sha256:9caac6b54914bdf41bcc91e7eb9147d331d29235a7c967c150ef5df6464fd1bb"}, + {file = "propcache-0.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:92fc4500fcb33899b05ba73276dfb684a20d31caa567b7cb5252d48f896a91b1"}, + {file = "propcache-0.2.1-py3-none-any.whl", hash = "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54"}, + {file = "propcache-0.2.1.tar.gz", hash = "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64"}, ] [[package]] @@ -1660,19 +1638,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1680,100 +1658,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -1781,13 +1770,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1991,105 +1980,105 @@ files = [ [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -2230,33 +2219,33 @@ typing-extensions = "*" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -2287,31 +2276,62 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "tomli" -version = "2.0.2" +version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] [[package]] name = "tqdm" -version = "4.66.6" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63"}, - {file = "tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -2354,13 +2374,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -2385,81 +2405,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [[package]] @@ -2475,93 +2490,93 @@ files = [ [[package]] name = "yarl" -version = "1.17.0" +version = "1.18.3" description = "Yet another URL library" optional = false python-versions = ">=3.9" files = [ - {file = "yarl-1.17.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2d8715edfe12eee6f27f32a3655f38d6c7410deb482158c0b7d4b7fad5d07628"}, - {file = "yarl-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1803bf2a7a782e02db746d8bd18f2384801bc1d108723840b25e065b116ad726"}, - {file = "yarl-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e66589110e20c2951221a938fa200c7aa134a8bdf4e4dc97e6b21539ff026d4"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7069d411cfccf868e812497e0ec4acb7c7bf8d684e93caa6c872f1e6f5d1664d"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cbf70ba16118db3e4b0da69dcde9d4d4095d383c32a15530564c283fa38a7c52"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0bc53cc349675b32ead83339a8de79eaf13b88f2669c09d4962322bb0f064cbc"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6aa18a402d1c80193ce97c8729871f17fd3e822037fbd7d9b719864018df746"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d89c5bc701861cfab357aa0cd039bc905fe919997b8c312b4b0c358619c38d4d"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b728bdf38ca58f2da1d583e4af4ba7d4cd1a58b31a363a3137a8159395e7ecc7"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:5542e57dc15d5473da5a39fbde14684b0cc4301412ee53cbab677925e8497c11"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e564b57e5009fb150cb513804d7e9e9912fee2e48835638f4f47977f88b4a39c"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:eb3c4cff524b4c1c1dba3a6da905edb1dfd2baf6f55f18a58914bbb2d26b59e1"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:05e13f389038842da930d439fbed63bdce3f7644902714cb68cf527c971af804"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:153c38ee2b4abba136385af4467459c62d50f2a3f4bde38c7b99d43a20c143ef"}, - {file = "yarl-1.17.0-cp310-cp310-win32.whl", hash = "sha256:4065b4259d1ae6f70fd9708ffd61e1c9c27516f5b4fae273c41028afcbe3a094"}, - {file = "yarl-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:abf366391a02a8335c5c26163b5fe6f514cc1d79e74d8bf3ffab13572282368e"}, - {file = "yarl-1.17.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:19a4fe0279626c6295c5b0c8c2bb7228319d2e985883621a6e87b344062d8135"}, - {file = "yarl-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cadd0113f4db3c6b56868d6a19ca6286f5ccfa7bc08c27982cf92e5ed31b489a"}, - {file = "yarl-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:60d6693eef43215b1ccfb1df3f6eae8db30a9ff1e7989fb6b2a6f0b468930ee8"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb8bf3843e1fa8cf3fe77813c512818e57368afab7ebe9ef02446fe1a10b492"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d2a5b35fd1d8d90443e061d0c8669ac7600eec5c14c4a51f619e9e105b136715"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5bf17b32f392df20ab5c3a69d37b26d10efaa018b4f4e5643c7520d8eee7ac7"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48f51b529b958cd06e78158ff297a8bf57b4021243c179ee03695b5dbf9cb6e1"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fcaa06bf788e19f913d315d9c99a69e196a40277dc2c23741a1d08c93f4d430"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:32f3ee19ff0f18a7a522d44e869e1ebc8218ad3ae4ebb7020445f59b4bbe5897"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:a4fb69a81ae2ec2b609574ae35420cf5647d227e4d0475c16aa861dd24e840b0"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7bacc8b77670322132a1b2522c50a1f62991e2f95591977455fd9a398b4e678d"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:437bf6eb47a2d20baaf7f6739895cb049e56896a5ffdea61a4b25da781966e8b"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:30534a03c87484092080e3b6e789140bd277e40f453358900ad1f0f2e61fc8ec"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b30df4ff98703649915144be6f0df3b16fd4870ac38a09c56d5d9e54ff2d5f96"}, - {file = "yarl-1.17.0-cp311-cp311-win32.whl", hash = "sha256:263b487246858e874ab53e148e2a9a0de8465341b607678106829a81d81418c6"}, - {file = "yarl-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:07055a9e8b647a362e7d4810fe99d8f98421575e7d2eede32e008c89a65a17bd"}, - {file = "yarl-1.17.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:84095ab25ba69a8fa3fb4936e14df631b8a71193fe18bd38be7ecbe34d0f5512"}, - {file = "yarl-1.17.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:02608fb3f6df87039212fc746017455ccc2a5fc96555ee247c45d1e9f21f1d7b"}, - {file = "yarl-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13468d291fe8c12162b7cf2cdb406fe85881c53c9e03053ecb8c5d3523822cd9"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8da3f8f368fb7e2f052fded06d5672260c50b5472c956a5f1bd7bf474ae504ab"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ec0507ab6523980bed050137007c76883d941b519aca0e26d4c1ec1f297dd646"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08fc76df7fd8360e9ff30e6ccc3ee85b8dbd6ed5d3a295e6ec62bcae7601b932"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d522f390686acb6bab2b917dd9ca06740c5080cd2eaa5aef8827b97e967319d"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:147c527a80bb45b3dcd6e63401af8ac574125d8d120e6afe9901049286ff64ef"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:24cf43bcd17a0a1f72284e47774f9c60e0bf0d2484d5851f4ddf24ded49f33c6"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:c28a44b9e0fba49c3857360e7ad1473fc18bc7f6659ca08ed4f4f2b9a52c75fa"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:350cacb2d589bc07d230eb995d88fcc646caad50a71ed2d86df533a465a4e6e1"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:fd1ab1373274dea1c6448aee420d7b38af163b5c4732057cd7ee9f5454efc8b1"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4934e0f96dadc567edc76d9c08181633c89c908ab5a3b8f698560124167d9488"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8d0a278170d75c88e435a1ce76557af6758bfebc338435b2eba959df2552163e"}, - {file = "yarl-1.17.0-cp312-cp312-win32.whl", hash = "sha256:61584f33196575a08785bb56db6b453682c88f009cd9c6f338a10f6737ce419f"}, - {file = "yarl-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:9987a439ad33a7712bd5bbd073f09ad10d38640425fa498ecc99d8aa064f8fc4"}, - {file = "yarl-1.17.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8deda7b8eb15a52db94c2014acdc7bdd14cb59ec4b82ac65d2ad16dc234a109e"}, - {file = "yarl-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56294218b348dcbd3d7fce0ffd79dd0b6c356cb2a813a1181af730b7c40de9e7"}, - {file = "yarl-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1fab91292f51c884b290ebec0b309a64a5318860ccda0c4940e740425a67b6b7"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cf93fa61ff4d9c7d40482ce1a2c9916ca435e34a1b8451e17f295781ccc034f"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:261be774a0d71908c8830c33bacc89eef15c198433a8cc73767c10eeeb35a7d0"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deec9693b67f6af856a733b8a3e465553ef09e5e8ead792f52c25b699b8f9e6e"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c804b07622ba50a765ca7fb8145512836ab65956de01307541def869e4a456c9"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d013a7c9574e98c14831a8f22d27277688ec3b2741d0188ac01a910b009987a"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e2cfcba719bd494c7413dcf0caafb51772dec168c7c946e094f710d6aa70494e"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:c068aba9fc5b94dfae8ea1cedcbf3041cd4c64644021362ffb750f79837e881f"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3616df510ffac0df3c9fa851a40b76087c6c89cbcea2de33a835fc80f9faac24"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:755d6176b442fba9928a4df787591a6a3d62d4969f05c406cad83d296c5d4e05"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c18f6e708d1cf9ff5b1af026e697ac73bea9cb70ee26a2b045b112548579bed2"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5b937c216b6dee8b858c6afea958de03c5ff28406257d22b55c24962a2baf6fd"}, - {file = "yarl-1.17.0-cp313-cp313-win32.whl", hash = "sha256:d0131b14cb545c1a7bd98f4565a3e9bdf25a1bd65c83fc156ee5d8a8499ec4a3"}, - {file = "yarl-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:01c96efa4313c01329e88b7e9e9e1b2fc671580270ddefdd41129fa8d0db7696"}, - {file = "yarl-1.17.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0d44f67e193f0a7acdf552ecb4d1956a3a276c68e7952471add9f93093d1c30d"}, - {file = "yarl-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:16ea0aa5f890cdcb7ae700dffa0397ed6c280840f637cd07bffcbe4b8d68b985"}, - {file = "yarl-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cf5469dc7dcfa65edf5cc3a6add9f84c5529c6b556729b098e81a09a92e60e51"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e662bf2f6e90b73cf2095f844e2bc1fda39826472a2aa1959258c3f2a8500a2f"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8260e88f1446904ba20b558fa8ce5d0ab9102747238e82343e46d056d7304d7e"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dc16477a4a2c71e64c5d3d15d7ae3d3a6bb1e8b955288a9f73c60d2a391282f"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46027e326cecd55e5950184ec9d86c803f4f6fe4ba6af9944a0e537d643cdbe0"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc95e46c92a2b6f22e70afe07e34dbc03a4acd07d820204a6938798b16f4014f"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:16ca76c7ac9515320cd09d6cc083d8d13d1803f6ebe212b06ea2505fd66ecff8"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:eb1a5b97388f2613f9305d78a3473cdf8d80c7034e554d8199d96dcf80c62ac4"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:41fd5498975418cdc34944060b8fbeec0d48b2741068077222564bea68daf5a6"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:146ca582ed04a5664ad04b0e0603934281eaab5c0115a5a46cce0b3c061a56a1"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:6abb8c06107dbec97481b2392dafc41aac091a5d162edf6ed7d624fe7da0587a"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4d14be4613dd4f96c25feb4bd8c0d8ce0f529ab0ae555a17df5789e69d8ec0c5"}, - {file = "yarl-1.17.0-cp39-cp39-win32.whl", hash = "sha256:174d6a6cad1068f7850702aad0c7b1bca03bcac199ca6026f84531335dfc2646"}, - {file = "yarl-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:6af417ca2c7349b101d3fd557ad96b4cd439fdb6ab0d288e3f64a068eea394d0"}, - {file = "yarl-1.17.0-py3-none-any.whl", hash = "sha256:62dd42bb0e49423f4dd58836a04fcf09c80237836796025211bbe913f1524993"}, - {file = "yarl-1.17.0.tar.gz", hash = "sha256:d3f13583f378930377e02002b4085a3d025b00402d5a80911726d43a67911cd9"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:602d98f2c2d929f8e697ed274fbadc09902c4025c5a9963bf4e9edfc3ab6f7ed"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c654d5207c78e0bd6d749f6dae1dcbbfde3403ad3a4b11f3c5544d9906969dde"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5094d9206c64181d0f6e76ebd8fb2f8fe274950a63890ee9e0ebfd58bf9d787b"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35098b24e0327fc4ebdc8ffe336cee0a87a700c24ffed13161af80124b7dc8e5"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3236da9272872443f81fedc389bace88408f64f89f75d1bdb2256069a8730ccc"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c08cc9b16f4f4bc522771d96734c7901e7ebef70c6c5c35dd0f10845270bcd"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80316a8bd5109320d38eef8833ccf5f89608c9107d02d2a7f985f98ed6876990"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1e1cc06da1491e6734f0ea1e6294ce00792193c463350626571c287c9a704db"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fea09ca13323376a2fdfb353a5fa2e59f90cd18d7ca4eaa1fd31f0a8b4f91e62"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e3b9fd71836999aad54084906f8663dffcd2a7fb5cdafd6c37713b2e72be1760"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:757e81cae69244257d125ff31663249b3013b5dc0a8520d73694aed497fb195b"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b1771de9944d875f1b98a745bc547e684b863abf8f8287da8466cf470ef52690"}, + {file = "yarl-1.18.3-cp310-cp310-win32.whl", hash = "sha256:8874027a53e3aea659a6d62751800cf6e63314c160fd607489ba5c2edd753cf6"}, + {file = "yarl-1.18.3-cp310-cp310-win_amd64.whl", hash = "sha256:93b2e109287f93db79210f86deb6b9bbb81ac32fc97236b16f7433db7fc437d8"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8503ad47387b8ebd39cbbbdf0bf113e17330ffd339ba1144074da24c545f0069"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02ddb6756f8f4517a2d5e99d8b2f272488e18dd0bfbc802f31c16c6c20f22193"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67a283dd2882ac98cc6318384f565bffc751ab564605959df4752d42483ad889"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d980e0325b6eddc81331d3f4551e2a333999fb176fd153e075c6d1c2530aa8a8"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b643562c12680b01e17239be267bc306bbc6aac1f34f6444d1bded0c5ce438ca"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c017a3b6df3a1bd45b9fa49a0f54005e53fbcad16633870104b66fa1a30a29d8"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75674776d96d7b851b6498f17824ba17849d790a44d282929c42dbb77d4f17ae"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccaa3a4b521b780a7e771cc336a2dba389a0861592bbce09a476190bb0c8b4b3"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d06d3005e668744e11ed80812e61efd77d70bb7f03e33c1598c301eea20efbb"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:9d41beda9dc97ca9ab0b9888cb71f7539124bc05df02c0cff6e5acc5a19dcc6e"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ba23302c0c61a9999784e73809427c9dbedd79f66a13d84ad1b1943802eaaf59"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6748dbf9bfa5ba1afcc7556b71cda0d7ce5f24768043a02a58846e4a443d808d"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0b0cad37311123211dc91eadcb322ef4d4a66008d3e1bdc404808992260e1a0e"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0fb2171a4486bb075316ee754c6d8382ea6eb8b399d4ec62fde2b591f879778a"}, + {file = "yarl-1.18.3-cp311-cp311-win32.whl", hash = "sha256:61b1a825a13bef4a5f10b1885245377d3cd0bf87cba068e1d9a88c2ae36880e1"}, + {file = "yarl-1.18.3-cp311-cp311-win_amd64.whl", hash = "sha256:b9d60031cf568c627d028239693fd718025719c02c9f55df0a53e587aab951b5"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285"}, + {file = "yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2"}, + {file = "yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:90adb47ad432332d4f0bc28f83a5963f426ce9a1a8809f5e584e704b82685dcb"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:913829534200eb0f789d45349e55203a091f45c37a2674678744ae52fae23efa"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ef9f7768395923c3039055c14334ba4d926f3baf7b776c923c93d80195624782"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a19f62ff30117e706ebc9090b8ecc79aeb77d0b1f5ec10d2d27a12bc9f66d0"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e17c9361d46a4d5addf777c6dd5eab0715a7684c2f11b88c67ac37edfba6c482"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a74a13a4c857a84a845505fd2d68e54826a2cd01935a96efb1e9d86c728e186"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41f7ce59d6ee7741af71d82020346af364949314ed3d87553763a2df1829cc58"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f52a265001d830bc425f82ca9eabda94a64a4d753b07d623a9f2863fde532b53"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:82123d0c954dc58db301f5021a01854a85bf1f3bb7d12ae0c01afc414a882ca2"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2ec9bbba33b2d00999af4631a3397d1fd78290c48e2a3e52d8dd72db3a067ac8"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbd6748e8ab9b41171bb95c6142faf068f5ef1511935a0aa07025438dd9a9bc1"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:877d209b6aebeb5b16c42cbb377f5f94d9e556626b1bfff66d7b0d115be88d0a"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b464c4ab4bfcb41e3bfd3f1c26600d038376c2de3297760dfe064d2cb7ea8e10"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8d39d351e7faf01483cc7ff7c0213c412e38e5a340238826be7e0e4da450fdc8"}, + {file = "yarl-1.18.3-cp313-cp313-win32.whl", hash = "sha256:61ee62ead9b68b9123ec24bc866cbef297dd266175d53296e2db5e7f797f902d"}, + {file = "yarl-1.18.3-cp313-cp313-win_amd64.whl", hash = "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:61e5e68cb65ac8f547f6b5ef933f510134a6bf31bb178be428994b0cb46c2a04"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe57328fbc1bfd0bd0514470ac692630f3901c0ee39052ae47acd1d90a436719"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a440a2a624683108a1b454705ecd7afc1c3438a08e890a1513d468671d90a04e"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09c7907c8548bcd6ab860e5f513e727c53b4a714f459b084f6580b49fa1b9cee"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4f6450109834af88cb4cc5ecddfc5380ebb9c228695afc11915a0bf82116789"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9ca04806f3be0ac6d558fffc2fdf8fcef767e0489d2684a21912cc4ed0cd1b8"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77a6e85b90a7641d2e07184df5557132a337f136250caafc9ccaa4a2a998ca2c"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6333c5a377c8e2f5fae35e7b8f145c617b02c939d04110c76f29ee3676b5f9a5"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0b3c92fa08759dbf12b3a59579a4096ba9af8dd344d9a813fc7f5070d86bbab1"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4ac515b860c36becb81bb84b667466885096b5fc85596948548b667da3bf9f24"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:045b8482ce9483ada4f3f23b3774f4e1bf4f23a2d5c912ed5170f68efb053318"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:a4bb030cf46a434ec0225bddbebd4b89e6471814ca851abb8696170adb163985"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:54d6921f07555713b9300bee9c50fb46e57e2e639027089b1d795ecd9f7fa910"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1d407181cfa6e70077df3377938c08012d18893f9f20e92f7d2f314a437c30b1"}, + {file = "yarl-1.18.3-cp39-cp39-win32.whl", hash = "sha256:ac36703a585e0929b032fbaab0707b75dc12703766d0b53486eabd5139ebadd5"}, + {file = "yarl-1.18.3-cp39-cp39-win_amd64.whl", hash = "sha256:ba87babd629f8af77f557b61e49e7c7cac36f22f871156b91e10a6e9d4f829e9"}, + {file = "yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b"}, + {file = "yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1"}, ] [package.dependencies] diff --git a/airbyte-integrations/connectors/source-facebook-marketing/pyproject.toml b/airbyte-integrations/connectors/source-facebook-marketing/pyproject.toml index e81362dd6c3c..bb6b2b15fccd 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/pyproject.toml +++ b/airbyte-integrations/connectors/source-facebook-marketing/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "3.3.18" +version = "3.3.24" name = "source-facebook-marketing" description = "Source implementation for Facebook Marketing." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/api.py b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/api.py index 31bf4644013d..7b7615ea92b2 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/api.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/api.py @@ -13,8 +13,10 @@ from facebook_business.adobjects.adaccount import AdAccount from facebook_business.api import FacebookResponse from facebook_business.exceptions import FacebookRequestError + from source_facebook_marketing.streams.common import retry_pattern + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/config_migrations.py b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/config_migrations.py index da5b8dc1c285..a4b28821bce2 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/config_migrations.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/config_migrations.py @@ -12,6 +12,7 @@ from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository from source_facebook_marketing.spec import ValidAdSetStatuses, ValidAdStatuses, ValidCampaignStatuses + logger = logging.getLogger("airbyte_logger") diff --git a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/source.py b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/source.py index b6eb3cb30c1e..776bdcbe2d67 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/source.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/source.py @@ -7,6 +7,7 @@ import facebook_business import pendulum + from airbyte_cdk.models import ( AdvancedAuth, AuthFlowType, @@ -55,6 +56,7 @@ from .utils import validate_end_date, validate_start_date + logger = logging.getLogger("airbyte") UNSUPPORTED_FIELDS = {"unique_conversions", "unique_ctr", "unique_clicks"} diff --git a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/spec.py b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/spec.py index 79c82c2210ad..6ccf6edbf8b8 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/spec.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/spec.py @@ -6,14 +6,16 @@ from enum import Enum from typing import List, Literal, Optional, Set, Union -from airbyte_cdk.sources.config import BaseConfig -from airbyte_cdk.utils.oneof_option_config import OneOfOptionConfig from facebook_business.adobjects.ad import Ad from facebook_business.adobjects.adset import AdSet from facebook_business.adobjects.adsinsights import AdsInsights from facebook_business.adobjects.campaign import Campaign from pydantic.v1 import BaseModel, Field, PositiveInt, constr +from airbyte_cdk.sources.config import BaseConfig +from airbyte_cdk.utils.oneof_option_config import OneOfOptionConfig + + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/async_job.py b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/async_job.py index e8f1038c2bb9..c6da3d872767 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/async_job.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/async_job.py @@ -18,10 +18,12 @@ from facebook_business.adobjects.objectparser import ObjectParser from facebook_business.api import FacebookAdsApi, FacebookAdsApiBatch, FacebookBadObjectError, FacebookResponse from pendulum.duration import Duration + from source_facebook_marketing.streams.common import retry_pattern from ..utils import validate_start_date + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/async_job_manager.py b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/async_job_manager.py index dc01cd228412..4fcaddcfdfcc 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/async_job_manager.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/async_job_manager.py @@ -10,6 +10,7 @@ from .async_job import AsyncJob, ParentAsyncJob, update_in_batch + if TYPE_CHECKING: # pragma: no cover from source_facebook_marketing.api import API diff --git a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/base_insight_streams.py b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/base_insight_streams.py index b33b9278eeb7..8b85af62a4a3 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/base_insight_streams.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/base_insight_streams.py @@ -6,19 +6,21 @@ from functools import cache, cached_property from typing import Any, Iterable, Iterator, List, Mapping, MutableMapping, Optional, Union -import airbyte_cdk.sources.utils.casing as casing import pendulum +from facebook_business.exceptions import FacebookBadObjectError, FacebookRequestError + +import airbyte_cdk.sources.utils.casing as casing from airbyte_cdk.models import FailureType, SyncMode from airbyte_cdk.sources.streams.core import package_name_from_class from airbyte_cdk.sources.utils.schema_helpers import ResourceSchemaLoader from airbyte_cdk.utils import AirbyteTracedException -from facebook_business.exceptions import FacebookBadObjectError, FacebookRequestError from source_facebook_marketing.streams.async_job import AsyncJob, InsightAsyncJob from source_facebook_marketing.streams.async_job_manager import InsightAsyncJobManager from source_facebook_marketing.streams.common import traced_exception from .base_streams import FBMarketingIncrementalStream + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/base_streams.py b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/base_streams.py index ed4bc29aef34..5e7562d644e9 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/base_streams.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/base_streams.py @@ -9,16 +9,18 @@ from typing import TYPE_CHECKING, Any, Iterable, List, Mapping, MutableMapping, Optional import pendulum +from facebook_business.adobjects.abstractobject import AbstractObject +from facebook_business.exceptions import FacebookRequestError + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.availability_strategy import AvailabilityStrategy from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer -from facebook_business.adobjects.abstractobject import AbstractObject -from facebook_business.exceptions import FacebookRequestError from source_facebook_marketing.streams.common import traced_exception from .common import deep_merge + if TYPE_CHECKING: # pragma: no cover from source_facebook_marketing.api import API diff --git a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/common.py b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/common.py index c3446cdfea01..46f150e766f7 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/common.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/common.py @@ -10,9 +10,11 @@ import backoff import pendulum +from facebook_business.exceptions import FacebookRequestError + from airbyte_cdk.models import FailureType from airbyte_cdk.utils import AirbyteTracedException -from facebook_business.exceptions import FacebookRequestError + # The Facebook API error codes indicating rate-limiting are listed at # https://developers.facebook.com/docs/graph-api/overview/rate-limiting/ diff --git a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/streams.py b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/streams.py index d33e202a637b..0dd3b4177a18 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/streams.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/streams.py @@ -8,16 +8,18 @@ import pendulum import requests -from airbyte_cdk.models import SyncMode from facebook_business.adobjects.adaccount import AdAccount as FBAdAccount from facebook_business.adobjects.adimage import AdImage from facebook_business.adobjects.user import User from facebook_business.exceptions import FacebookRequestError + +from airbyte_cdk.models import SyncMode from source_facebook_marketing.spec import ValidAdSetStatuses, ValidAdStatuses, ValidCampaignStatuses from .base_insight_streams import AdsInsights from .base_streams import FBMarketingIncrementalStream, FBMarketingReversedIncrementalStream, FBMarketingStream + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/utils.py b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/utils.py index e81c6bfd14c5..71e35ddac007 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/utils.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/utils.py @@ -8,6 +8,7 @@ import pendulum from pendulum import Date, DateTime + logger = logging.getLogger("airbyte") # Facebook store metrics maximum of 37 months old. Any time range that diff --git a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/conftest.py b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/conftest.py index 7a7cbaa39b9e..1ea8602ce656 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/conftest.py @@ -7,6 +7,7 @@ from pytest import fixture from source_facebook_marketing.api import API + FB_API_VERSION = FacebookAdsApi.API_VERSION diff --git a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/config.py b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/config.py index 1e76b6403a50..51772039a52e 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/config.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/config.py @@ -10,6 +10,7 @@ import pendulum + ACCESS_TOKEN = "test_access_token" ACCOUNT_ID = "111111111111111" CLIENT_ID = "test_client_id" diff --git a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/pagination.py b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/pagination.py index 69b284d6d308..16846f6d78d4 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/pagination.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/pagination.py @@ -9,6 +9,7 @@ from airbyte_cdk.test.mock_http.request import HttpRequest from airbyte_cdk.test.mock_http.response_builder import PaginationStrategy + NEXT_PAGE_TOKEN = "QVFIUlhOX3Rnbm5Y" diff --git a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/test_ads_insights_action_product_id.py b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/test_ads_insights_action_product_id.py index 2a290cd48cbc..8bdbe9ddd9cc 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/test_ads_insights_action_product_id.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/test_ads_insights_action_product_id.py @@ -11,6 +11,8 @@ import freezegun import pendulum +from source_facebook_marketing.streams.async_job import Status + from airbyte_cdk.models import AirbyteStateMessage, AirbyteStreamStateSerializer, StreamDescriptor, SyncMode from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput from airbyte_cdk.test.mock_http import HttpMocker @@ -23,7 +25,6 @@ create_response_builder, find_template, ) -from source_facebook_marketing.streams.async_job import Status from .config import ACCESS_TOKEN, ACCOUNT_ID, DATE_FORMAT, END_DATE, NOW, START_DATE, ConfigBuilder from .pagination import NEXT_PAGE_TOKEN, FacebookMarketingPaginationStrategy @@ -31,113 +32,114 @@ from .response_builder import build_response, error_reduce_amount_of_data_response, get_account_response from .utils import config, encode_request_body, read_output + _STREAM_NAME = "ads_insights_action_product_id" _CURSOR_FIELD = "date_start" _REPORT_RUN_ID = "1571860060019548" _JOB_ID = "1049937379601625" _JOB_START_FIELDS = [ - "account_currency", - "account_id", - "account_name", - "action_values", - "actions", - "ad_click_actions", - "ad_id", - "ad_impression_actions", - "ad_name", - "adset_id", - "adset_name", - "attribution_setting", - "auction_bid", - "auction_competitiveness", - "auction_max_competitor_bid", - "buying_type", - "campaign_id", - "campaign_name", - "canvas_avg_view_percent", - "canvas_avg_view_time", - "catalog_segment_actions", - "catalog_segment_value", - "catalog_segment_value_mobile_purchase_roas", - "catalog_segment_value_omni_purchase_roas", - "catalog_segment_value_website_purchase_roas", - "clicks", - "conversion_rate_ranking", - "conversion_values", - "conversions", - "converted_product_quantity", - "converted_product_value", - "cost_per_15_sec_video_view", - "cost_per_2_sec_continuous_video_view", - "cost_per_action_type", - "cost_per_ad_click", - "cost_per_conversion", - "cost_per_estimated_ad_recallers", - "cost_per_inline_link_click", - "cost_per_inline_post_engagement", - "cost_per_outbound_click", - "cost_per_thruplay", - "cost_per_unique_action_type", - "cost_per_unique_click", - "cost_per_unique_inline_link_click", - "cost_per_unique_outbound_click", - "cpc", - "cpm", - "cpp", - "created_time", - "ctr", - "date_start", - "date_stop", - "engagement_rate_ranking", - "estimated_ad_recallers", - "frequency", - "full_view_impressions", - "full_view_reach", - "impressions", - "inline_link_click_ctr", - "inline_link_clicks", - "inline_post_engagement", - "instant_experience_clicks_to_open", - "instant_experience_clicks_to_start", - "instant_experience_outbound_clicks", - "mobile_app_purchase_roas", - "objective", - "optimization_goal", - "outbound_clicks", - "outbound_clicks_ctr", - "purchase_roas", - "qualifying_question_qualify_answer_rate", - "quality_ranking", - "reach", - "social_spend", - "spend", - "unique_actions", - "unique_clicks", - "unique_ctr", - "unique_inline_link_click_ctr", - "unique_inline_link_clicks", - "unique_link_clicks_ctr", - "unique_outbound_clicks", - "unique_outbound_clicks_ctr", - "updated_time", - "video_15_sec_watched_actions", - "video_30_sec_watched_actions", - "video_avg_time_watched_actions", - "video_continuous_2_sec_watched_actions", - "video_p100_watched_actions", - "video_p25_watched_actions", - "video_p50_watched_actions", - "video_p75_watched_actions", - "video_p95_watched_actions", - "video_play_actions", - "video_play_curve_actions", - "video_play_retention_0_to_15s_actions", - "video_play_retention_20_to_60s_actions", - "video_play_retention_graph_actions", - "video_time_watched_actions", - "website_ctr", - "website_purchase_roas", - ] + "account_currency", + "account_id", + "account_name", + "action_values", + "actions", + "ad_click_actions", + "ad_id", + "ad_impression_actions", + "ad_name", + "adset_id", + "adset_name", + "attribution_setting", + "auction_bid", + "auction_competitiveness", + "auction_max_competitor_bid", + "buying_type", + "campaign_id", + "campaign_name", + "canvas_avg_view_percent", + "canvas_avg_view_time", + "catalog_segment_actions", + "catalog_segment_value", + "catalog_segment_value_mobile_purchase_roas", + "catalog_segment_value_omni_purchase_roas", + "catalog_segment_value_website_purchase_roas", + "clicks", + "conversion_rate_ranking", + "conversion_values", + "conversions", + "converted_product_quantity", + "converted_product_value", + "cost_per_15_sec_video_view", + "cost_per_2_sec_continuous_video_view", + "cost_per_action_type", + "cost_per_ad_click", + "cost_per_conversion", + "cost_per_estimated_ad_recallers", + "cost_per_inline_link_click", + "cost_per_inline_post_engagement", + "cost_per_outbound_click", + "cost_per_thruplay", + "cost_per_unique_action_type", + "cost_per_unique_click", + "cost_per_unique_inline_link_click", + "cost_per_unique_outbound_click", + "cpc", + "cpm", + "cpp", + "created_time", + "ctr", + "date_start", + "date_stop", + "engagement_rate_ranking", + "estimated_ad_recallers", + "frequency", + "full_view_impressions", + "full_view_reach", + "impressions", + "inline_link_click_ctr", + "inline_link_clicks", + "inline_post_engagement", + "instant_experience_clicks_to_open", + "instant_experience_clicks_to_start", + "instant_experience_outbound_clicks", + "mobile_app_purchase_roas", + "objective", + "optimization_goal", + "outbound_clicks", + "outbound_clicks_ctr", + "purchase_roas", + "qualifying_question_qualify_answer_rate", + "quality_ranking", + "reach", + "social_spend", + "spend", + "unique_actions", + "unique_clicks", + "unique_ctr", + "unique_inline_link_click_ctr", + "unique_inline_link_clicks", + "unique_link_clicks_ctr", + "unique_outbound_clicks", + "unique_outbound_clicks_ctr", + "updated_time", + "video_15_sec_watched_actions", + "video_30_sec_watched_actions", + "video_avg_time_watched_actions", + "video_continuous_2_sec_watched_actions", + "video_p100_watched_actions", + "video_p25_watched_actions", + "video_p50_watched_actions", + "video_p75_watched_actions", + "video_p95_watched_actions", + "video_play_actions", + "video_play_curve_actions", + "video_play_retention_0_to_15s_actions", + "video_play_retention_20_to_60s_actions", + "video_play_retention_graph_actions", + "video_time_watched_actions", + "website_ctr", + "website_purchase_roas", +] def _update_api_throttle_limit_request(account_id: Optional[str] = ACCOUNT_ID) -> RequestBuilder: @@ -145,7 +147,10 @@ def _update_api_throttle_limit_request(account_id: Optional[str] = ACCOUNT_ID) - def _job_start_request( - account_id: Optional[str] = ACCOUNT_ID, since: Optional[datetime] = None, until: Optional[datetime] = None, fields: Optional[List[str]] = None + account_id: Optional[str] = ACCOUNT_ID, + since: Optional[datetime] = None, + until: Optional[datetime] = None, + fields: Optional[List[str]] = None, ) -> RequestBuilder: since = since.strftime(DATE_FORMAT) if since else START_DATE[:10] until = until.strftime(DATE_FORMAT) if until else END_DATE[:10] @@ -174,7 +179,7 @@ def _job_start_request( "PENDING_BILLING_INFO", "PENDING_REVIEW", "PREAPPROVED", - "WITH_ISSUES" + "WITH_ISSUES", ], }, ], @@ -250,7 +255,7 @@ def _read(config_: ConfigBuilder, expecting_exception: bool = False, json_schema stream_name=_STREAM_NAME, sync_mode=SyncMode.full_refresh, expecting_exception=expecting_exception, - json_schema=json_schema + json_schema=json_schema, ) @HttpMocker() @@ -434,7 +439,10 @@ def test_given_status_500_reduce_amount_of_data_when_read_then_limit_reduced(sel class TestIncremental(TestCase): @staticmethod def _read( - config_: ConfigBuilder, state: Optional[List[AirbyteStateMessage]] = None, expecting_exception: bool = False, json_schema: Optional[Dict[str, any]] = None + config_: ConfigBuilder, + state: Optional[List[AirbyteStateMessage]] = None, + expecting_exception: bool = False, + json_schema: Optional[Dict[str, any]] = None, ) -> EntrypointOutput: return read_output( config_builder=config_, @@ -442,7 +450,7 @@ def _read( sync_mode=SyncMode.incremental, state=state, expecting_exception=expecting_exception, - json_schema=json_schema + json_schema=json_schema, ) @HttpMocker() @@ -467,7 +475,9 @@ def test_when_read_then_state_message_produced_and_state_match_start_interval(se ) output = self._read(config().with_account_ids([account_id]).with_start_date(start_date).with_end_date(end_date)) - cursor_value_from_state_message = AirbyteStreamStateSerializer.dump(output.most_recent_state).get("stream_state").get(account_id, {}).get(_CURSOR_FIELD) + cursor_value_from_state_message = ( + AirbyteStreamStateSerializer.dump(output.most_recent_state).get("stream_state").get(account_id, {}).get(_CURSOR_FIELD) + ) assert output.most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) assert cursor_value_from_state_message == start_date.strftime(DATE_FORMAT) @@ -511,8 +521,12 @@ def test_given_multiple_account_ids_when_read_then_state_produced_by_account_id_ ) output = self._read(config().with_account_ids([account_id_1, account_id_2]).with_start_date(start_date).with_end_date(end_date)) - cursor_value_from_state_account_1 = AirbyteStreamStateSerializer.dump(output.most_recent_state).get("stream_state").get(account_id_1, {}).get(_CURSOR_FIELD) - cursor_value_from_state_account_2 = AirbyteStreamStateSerializer.dump(output.most_recent_state).get("stream_state").get(account_id_2, {}).get(_CURSOR_FIELD) + cursor_value_from_state_account_1 = ( + AirbyteStreamStateSerializer.dump(output.most_recent_state).get("stream_state").get(account_id_1, {}).get(_CURSOR_FIELD) + ) + cursor_value_from_state_account_2 = ( + AirbyteStreamStateSerializer.dump(output.most_recent_state).get("stream_state").get(account_id_2, {}).get(_CURSOR_FIELD) + ) expected_cursor_value = start_date.strftime(DATE_FORMAT) assert output.most_recent_state.stream_descriptor == StreamDescriptor(name=_STREAM_NAME) assert cursor_value_from_state_account_1 == expected_cursor_value diff --git a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/test_videos.py b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/test_videos.py index d437566f1d48..90c13e2a6941 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/test_videos.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/test_videos.py @@ -7,6 +7,7 @@ from unittest import TestCase import freezegun + from airbyte_cdk.models import AirbyteStateMessage, AirbyteStreamStateSerializer, SyncMode from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput from airbyte_cdk.test.mock_http import HttpMocker @@ -26,6 +27,7 @@ from .response_builder import error_reduce_amount_of_data_response, get_account_response from .utils import config, read_output + _STREAM_NAME = "videos" _CURSOR_FIELD = "updated_time" _FIELDS = [ @@ -96,7 +98,7 @@ def _read(config_: ConfigBuilder, expecting_exception: bool = False, json_schema stream_name=_STREAM_NAME, sync_mode=SyncMode.full_refresh, expecting_exception=expecting_exception, - json_schema=json_schema + json_schema=json_schema, ) @HttpMocker() @@ -244,7 +246,9 @@ def test_when_read_then_state_message_produced_and_state_match_latest_record(sel ) output = self._read(config().with_account_ids([account_id])) - cursor_value_from_state_message = AirbyteStreamStateSerializer.dump(output.most_recent_state).get("stream_state").get(account_id, {}).get(_CURSOR_FIELD) + cursor_value_from_state_message = ( + AirbyteStreamStateSerializer.dump(output.most_recent_state).get("stream_state").get(account_id, {}).get(_CURSOR_FIELD) + ) assert cursor_value_from_state_message == max_cursor_value @HttpMocker() @@ -276,8 +280,12 @@ def test_given_multiple_account_ids_when_read_then_state_produced_by_account_id_ ) output = self._read(config().with_account_ids([account_id_1, account_id_2])) - cursor_value_from_state_account_1 = AirbyteStreamStateSerializer.dump(output.most_recent_state).get("stream_state").get(account_id_1, {}).get(_CURSOR_FIELD) - cursor_value_from_state_account_2 = AirbyteStreamStateSerializer.dump(output.most_recent_state).get("stream_state").get(account_id_2, {}).get(_CURSOR_FIELD) + cursor_value_from_state_account_1 = ( + AirbyteStreamStateSerializer.dump(output.most_recent_state).get("stream_state").get(account_id_1, {}).get(_CURSOR_FIELD) + ) + cursor_value_from_state_account_2 = ( + AirbyteStreamStateSerializer.dump(output.most_recent_state).get("stream_state").get(account_id_2, {}).get(_CURSOR_FIELD) + ) assert cursor_value_from_state_account_1 == max_cursor_value_account_id_1 assert cursor_value_from_state_account_2 == max_cursor_value_account_id_2 diff --git a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/utils.py b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/utils.py index 2686186e1840..eb45b856b124 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/utils.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/integration/utils.py @@ -6,11 +6,12 @@ from typing import Any, Dict, List, Optional from urllib.parse import urlencode +from facebook_business.api import _top_level_param_json_encode +from source_facebook_marketing import SourceFacebookMarketing + from airbyte_cdk.models import AirbyteStateMessage, ConfiguredAirbyteCatalog, SyncMode from airbyte_cdk.test.catalog_builder import ConfiguredAirbyteStreamBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read -from facebook_business.api import _top_level_param_json_encode -from source_facebook_marketing import SourceFacebookMarketing from .config import ConfigBuilder @@ -34,7 +35,7 @@ def read_output( sync_mode: SyncMode, state: Optional[List[AirbyteStateMessage]] = None, expecting_exception: Optional[bool] = False, - json_schema: Optional[Dict[str, any]] = None + json_schema: Optional[Dict[str, any]] = None, ) -> EntrypointOutput: _catalog = catalog(stream_name, sync_mode, json_schema) _config = config_builder.build() diff --git a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_api.py b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_api.py index c09279ca1d8d..0bd249e56bc4 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_api.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_api.py @@ -8,6 +8,7 @@ from facebook_business import FacebookAdsApi, FacebookSession from facebook_business.adobjects.adaccount import AdAccount + FB_API_VERSION = FacebookAdsApi.API_VERSION diff --git a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_base_insight_streams.py b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_base_insight_streams.py index 9b9a0e2a1f9f..86a58ffadcfa 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_base_insight_streams.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_base_insight_streams.py @@ -6,12 +6,13 @@ import pendulum import pytest -from airbyte_cdk.models import SyncMode from freezegun import freeze_time from pendulum import duration from source_facebook_marketing.streams import AdsInsights from source_facebook_marketing.streams.async_job import AsyncJob, InsightAsyncJob +from airbyte_cdk.models import SyncMode + @pytest.fixture(name="api") def api_fixture(mocker): @@ -99,14 +100,10 @@ def test_init_statuses(self, api, some_config): end_date=datetime(2011, 1, 1), insights_lookback_window=28, fields=["account_id", "account_currency"], - filter_statuses=["ACTIVE", "ARCHIVED"] + filter_statuses=["ACTIVE", "ARCHIVED"], ) - assert stream.request_params()["filtering"] == [ - {'field': 'ad.effective_status', - 'operator': 'IN', - 'value': ['ACTIVE', 'ARCHIVED']} - ] + assert stream.request_params()["filtering"] == [{"field": "ad.effective_status", "operator": "IN", "value": ["ACTIVE", "ARCHIVED"]}] def test_read_records_all(self, mocker, api, some_config): """1. yield all from mock @@ -464,7 +461,9 @@ def test_stream_slices_with_state_and_slices(self, api, async_manager_mock, star async_manager_mock.assert_called_once() args, kwargs = async_manager_mock.call_args generated_jobs = list(kwargs["jobs"]) - assert len(generated_jobs) == (end_date.date() - (cursor_value.date() - stream.insights_lookback_period)).days + 1, "should be 37 slices because we ignore slices which are within insights_lookback_period" + assert ( + len(generated_jobs) == (end_date.date() - (cursor_value.date() - stream.insights_lookback_period)).days + 1 + ), "should be 37 slices because we ignore slices which are within insights_lookback_period" assert generated_jobs[0].interval.start == cursor_value.date() - stream.insights_lookback_period assert generated_jobs[1].interval.start == cursor_value.date() - stream.insights_lookback_period + duration(days=1) @@ -602,61 +601,78 @@ def test_start_date_with_lookback_window( @pytest.mark.parametrize( "breakdowns, record, expected_record", ( - ( - ["body_asset", ], - {"body_asset": {"id": "871246182", "text": "Some text"}}, - {"body_asset": {"id": "871246182", "text": "Some text"}, "body_asset_id": "871246182"} - ), - ( - ["call_to_action_asset",], - {"call_to_action_asset": {"id": "871246182", "name": "Some name"}}, - {"call_to_action_asset": {"id": "871246182", "name": "Some name"}, "call_to_action_asset_id": "871246182"} - ), - ( - ["description_asset", ], - {"description_asset": {"id": "871246182", "text": "Some text"}}, - {"description_asset": {"id": "871246182", "text": "Some text"}, "description_asset_id": "871246182"} - ), - ( - ["image_asset", ], - {"image_asset": {"id": "871246182", "hash": "hash", "url": "url"}}, - {"image_asset": {"id": "871246182", "hash": "hash", "url": "url"}, "image_asset_id": "871246182"} - ), - ( - ["link_url_asset", ], - {"link_url_asset": {"id": "871246182", "website_url": "website_url"}}, - {"link_url_asset": {"id": "871246182", "website_url": "website_url"}, "link_url_asset_id": "871246182"} - ), - ( - ["title_asset", ], - {"title_asset": {"id": "871246182", "text": "Some text"}}, - {"title_asset": {"id": "871246182", "text": "Some text"}, "title_asset_id": "871246182"} - ), - ( - ["video_asset", ], - { - "video_asset": { - "id": "871246182", "video_id": "video_id", "url": "url", - "thumbnail_url": "thumbnail_url", "video_name": "video_name" - } - }, - { - "video_asset": { - "id": "871246182", "video_id": "video_id", "url": "url", - "thumbnail_url": "thumbnail_url", "video_name": "video_name" - }, - "video_asset_id": "871246182" - } - ), - ( - ["body_asset", "country"], - {"body_asset": {"id": "871246182", "text": "Some text"}, "country": "country", "dma": "dma"}, - { - "body_asset": {"id": "871246182", "text": "Some text"}, - "country": "country", "dma": "dma", "body_asset_id": "871246182" - } - ), - ) + ( + [ + "body_asset", + ], + {"body_asset": {"id": "871246182", "text": "Some text"}}, + {"body_asset": {"id": "871246182", "text": "Some text"}, "body_asset_id": "871246182"}, + ), + ( + [ + "call_to_action_asset", + ], + {"call_to_action_asset": {"id": "871246182", "name": "Some name"}}, + {"call_to_action_asset": {"id": "871246182", "name": "Some name"}, "call_to_action_asset_id": "871246182"}, + ), + ( + [ + "description_asset", + ], + {"description_asset": {"id": "871246182", "text": "Some text"}}, + {"description_asset": {"id": "871246182", "text": "Some text"}, "description_asset_id": "871246182"}, + ), + ( + [ + "image_asset", + ], + {"image_asset": {"id": "871246182", "hash": "hash", "url": "url"}}, + {"image_asset": {"id": "871246182", "hash": "hash", "url": "url"}, "image_asset_id": "871246182"}, + ), + ( + [ + "link_url_asset", + ], + {"link_url_asset": {"id": "871246182", "website_url": "website_url"}}, + {"link_url_asset": {"id": "871246182", "website_url": "website_url"}, "link_url_asset_id": "871246182"}, + ), + ( + [ + "title_asset", + ], + {"title_asset": {"id": "871246182", "text": "Some text"}}, + {"title_asset": {"id": "871246182", "text": "Some text"}, "title_asset_id": "871246182"}, + ), + ( + [ + "video_asset", + ], + { + "video_asset": { + "id": "871246182", + "video_id": "video_id", + "url": "url", + "thumbnail_url": "thumbnail_url", + "video_name": "video_name", + } + }, + { + "video_asset": { + "id": "871246182", + "video_id": "video_id", + "url": "url", + "thumbnail_url": "thumbnail_url", + "video_name": "video_name", + }, + "video_asset_id": "871246182", + }, + ), + ( + ["body_asset", "country"], + {"body_asset": {"id": "871246182", "text": "Some text"}, "country": "country", "dma": "dma"}, + {"body_asset": {"id": "871246182", "text": "Some text"}, "country": "country", "dma": "dma", "body_asset_id": "871246182"}, + ), + ), ) def test_transform_breakdowns(self, api, some_config, breakdowns, record, expected_record): start_date = pendulum.parse("2024-01-01") @@ -674,36 +690,19 @@ def test_transform_breakdowns(self, api, some_config, breakdowns, record, expect @pytest.mark.parametrize( "breakdowns, expect_pks", ( - ( - ["body_asset"], ["date_start", "account_id", "ad_id", "body_asset_id"] - ), - ( - ["call_to_action_asset"], ["date_start", "account_id", "ad_id", "call_to_action_asset_id"] - ), - ( - ["description_asset"], ["date_start", "account_id", "ad_id", "description_asset_id"] - ), - ( - ["image_asset"], ["date_start", "account_id", "ad_id", "image_asset_id"] - ), - ( - ["link_url_asset"], ["date_start", "account_id", "ad_id", "link_url_asset_id"] - ), - ( - ["title_asset"], ["date_start", "account_id", "ad_id", "title_asset_id"] - ), - ( - ["video_asset"], ["date_start", "account_id", "ad_id", "video_asset_id"] - ), - ( - ["video_asset", "skan_conversion_id", "place_page_id"], - ["date_start", "account_id", "ad_id", "video_asset_id", "skan_conversion_id", "place_page_id"] - ), - ( - None, - ["date_start", "account_id", "ad_id"] - ), - ) + (["body_asset"], ["date_start", "account_id", "ad_id", "body_asset_id"]), + (["call_to_action_asset"], ["date_start", "account_id", "ad_id", "call_to_action_asset_id"]), + (["description_asset"], ["date_start", "account_id", "ad_id", "description_asset_id"]), + (["image_asset"], ["date_start", "account_id", "ad_id", "image_asset_id"]), + (["link_url_asset"], ["date_start", "account_id", "ad_id", "link_url_asset_id"]), + (["title_asset"], ["date_start", "account_id", "ad_id", "title_asset_id"]), + (["video_asset"], ["date_start", "account_id", "ad_id", "video_asset_id"]), + ( + ["video_asset", "skan_conversion_id", "place_page_id"], + ["date_start", "account_id", "ad_id", "video_asset_id", "skan_conversion_id", "place_page_id"], + ), + (None, ["date_start", "account_id", "ad_id"]), + ), ) def test_primary_keys(self, api, some_config, breakdowns, expect_pks): start_date = pendulum.parse("2024-01-01") @@ -714,43 +713,38 @@ def test_primary_keys(self, api, some_config, breakdowns, expect_pks): start_date=start_date, end_date=end_date, insights_lookback_window=1, - breakdowns=breakdowns + breakdowns=breakdowns, ) assert stream.primary_key == expect_pks @pytest.mark.parametrize( "breakdowns, expect_pks", ( - ( - ["body_asset"], ["date_start", "account_id", "ad_id", "body_asset_id"] - ), - ( - ["call_to_action_asset"], ["date_start", "account_id", "ad_id", "call_to_action_asset_id"] - ), - ( - ["description_asset"], ["date_start", "account_id", "ad_id", "description_asset_id"] - ), - ( - ["image_asset"], ["date_start", "account_id", "ad_id", "image_asset_id"] - ), - ( - ["link_url_asset"], ["date_start", "account_id", "ad_id", "link_url_asset_id"] - ), - ( - ["title_asset"], ["date_start", "account_id", "ad_id", "title_asset_id"] - ), - ( - ["video_asset"], ["date_start", "account_id", "ad_id", "video_asset_id"] - ), - ( - ["video_asset", "skan_conversion_id", "place_page_id"], - ["date_start", "account_id", "ad_id", "video_asset_id", "skan_conversion_id", "place_page_id"] - ), - ( - ["video_asset", "link_url_asset", "skan_conversion_id", "place_page_id", "gender"], - ["date_start", "account_id", "ad_id", "video_asset_id", "link_url_asset_id", "skan_conversion_id", "place_page_id", "gender"] - ), - ) + (["body_asset"], ["date_start", "account_id", "ad_id", "body_asset_id"]), + (["call_to_action_asset"], ["date_start", "account_id", "ad_id", "call_to_action_asset_id"]), + (["description_asset"], ["date_start", "account_id", "ad_id", "description_asset_id"]), + (["image_asset"], ["date_start", "account_id", "ad_id", "image_asset_id"]), + (["link_url_asset"], ["date_start", "account_id", "ad_id", "link_url_asset_id"]), + (["title_asset"], ["date_start", "account_id", "ad_id", "title_asset_id"]), + (["video_asset"], ["date_start", "account_id", "ad_id", "video_asset_id"]), + ( + ["video_asset", "skan_conversion_id", "place_page_id"], + ["date_start", "account_id", "ad_id", "video_asset_id", "skan_conversion_id", "place_page_id"], + ), + ( + ["video_asset", "link_url_asset", "skan_conversion_id", "place_page_id", "gender"], + [ + "date_start", + "account_id", + "ad_id", + "video_asset_id", + "link_url_asset_id", + "skan_conversion_id", + "place_page_id", + "gender", + ], + ), + ), ) def test_object_pk_added_to_schema(self, api, some_config, breakdowns, expect_pks): start_date = pendulum.parse("2024-01-01") @@ -761,7 +755,7 @@ def test_object_pk_added_to_schema(self, api, some_config, breakdowns, expect_pk start_date=start_date, end_date=end_date, insights_lookback_window=1, - breakdowns=breakdowns + breakdowns=breakdowns, ) schema = stream.get_json_schema() assert schema diff --git a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_client.py b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_client.py index 885560c92d3a..65b53d21eb11 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_client.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_client.py @@ -6,12 +6,14 @@ import pendulum import pytest -from airbyte_cdk.models import FailureType, SyncMode -from airbyte_cdk.utils import AirbyteTracedException from facebook_business import FacebookAdsApi, FacebookSession from facebook_business.exceptions import FacebookRequestError from source_facebook_marketing.streams import Activities, AdAccount, AdCreatives, Campaigns, Videos +from airbyte_cdk.models import FailureType, SyncMode +from airbyte_cdk.utils import AirbyteTracedException + + FB_API_VERSION = FacebookAdsApi.API_VERSION @@ -105,7 +107,9 @@ def test_limit_reached(self, mocker, requests_mock, api, fb_call_rate_response, except FacebookRequestError: pytest.fail("Call rate error has not being handled") - def test_given_rate_limit_reached_when_read_then_raise_transient_traced_exception(self, requests_mock, api, fb_call_rate_response, account_id, some_config): + def test_given_rate_limit_reached_when_read_then_raise_transient_traced_exception( + self, requests_mock, api, fb_call_rate_response, account_id, some_config + ): requests_mock.register_uri( "GET", FacebookSession.GRAPH + f"/{FB_API_VERSION}/act_{account_id}/campaigns", diff --git a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_config_migrations.py b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_config_migrations.py index 68229d5923a1..91a1a9b1a174 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_config_migrations.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_config_migrations.py @@ -8,8 +8,6 @@ from typing import Any, Mapping import pytest -from airbyte_cdk.models import OrchestratorType, Type -from airbyte_cdk.sources import Source from source_facebook_marketing.config_migrations import ( MigrateAccountIdToArray, MigrateIncludeDeletedToStatusFilters, @@ -17,6 +15,10 @@ ) from source_facebook_marketing.source import SourceFacebookMarketing +from airbyte_cdk.models import OrchestratorType, Type +from airbyte_cdk.sources import Source + + # BASE ARGS CMD = "check" SOURCE: Source = SourceFacebookMarketing() @@ -168,6 +170,7 @@ def test_should_not_migrate_upgraded_config(self): migration_instance = MigrateIncludeDeletedToStatusFilters() assert not migration_instance.should_migrate(new_config) + class TestMigrateSecretsPathInConnector: OLD_TEST_CONFIG_PATH_ACCESS_TOKEN = _config_path(f"{_SECRETS_TO_CREDENTIALS_CONFIGS_PATH}/test_old_access_token_config.json") NEW_TEST_CONFIG_PATH_ACCESS_TOKEN = _config_path(f"{_SECRETS_TO_CREDENTIALS_CONFIGS_PATH}/test_new_access_token_config.json") @@ -178,7 +181,7 @@ class TestMigrateSecretsPathInConnector: def revert_migration(config_path: str) -> None: with open(config_path, "r") as test_config: config = json.load(test_config) - credentials = config.pop("credentials",{}) + credentials = config.pop("credentials", {}) credentials.pop("auth_type", None) with open(config_path, "w") as updated_config: config = json.dumps({**config, **credentials}) @@ -202,7 +205,7 @@ def test_migrate_access_token_config(self): assert original_config["access_token"] == credentials["access_token"] # revert the test_config to the starting point self.revert_migration(self.OLD_TEST_CONFIG_PATH_ACCESS_TOKEN) - + def test_migrate_client_config(self): migration_instance = MigrateSecretsPathInConnector() original_config = load_config(self.OLD_TEST_CONFIG_PATH_CLIENT) @@ -228,7 +231,7 @@ def test_should_not_migrate_new_client_config(self): new_config = load_config(self.NEW_TEST_CONFIG_PATH_CLIENT) migration_instance = MigrateSecretsPathInConnector() assert not migration_instance._should_migrate(new_config) - + def test_should_not_migrate_new_access_token_config(self): new_config = load_config(self.NEW_TEST_CONFIG_PATH_ACCESS_TOKEN) migration_instance = MigrateSecretsPathInConnector() diff --git a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_errors.py b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_errors.py index b593e7e1b1f3..258c32425638 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_errors.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_errors.py @@ -7,14 +7,16 @@ from unittest.mock import MagicMock import pytest -from airbyte_cdk.models import FailureType, SyncMode -from airbyte_cdk.utils.traced_exception import AirbyteTracedException from facebook_business import FacebookAdsApi, FacebookSession from facebook_business.exceptions import FacebookRequestError from source_facebook_marketing.api import API from source_facebook_marketing.streams import AdAccount, AdCreatives, AdsInsights from source_facebook_marketing.streams.common import traced_exception +from airbyte_cdk.models import FailureType, SyncMode +from airbyte_cdk.utils.traced_exception import AirbyteTracedException + + FB_API_VERSION = FacebookAdsApi.API_VERSION account_id = "unknown_account" @@ -113,7 +115,7 @@ "code": 100, } }, - } + }, # Error randomly happens for different connections. # Can be reproduced on https://developers.facebook.com/tools/explorer/?method=GET&path=act_&version=v17.0 # 1st reason: incorrect ad account id is used @@ -183,7 +185,7 @@ "error_user_msg": "profile should always be linked to delegate page", } }, - } + }, # Error happens on Video stream: https://graph.facebook.com/v17.0/act_XXXXXXXXXXXXXXXX/advideos # Recommendations says that the problem can be fixed by switching to Business Ad Account Id ), @@ -215,8 +217,8 @@ "message": "(#3018) The start date of the time range cannot be beyond 37 months from the current date", "type": "OAuthException", "code": 3018, - "fbtrace_id": "Ag-P22y80OSEXM4qsGk2T9P" - } + "fbtrace_id": "Ag-P22y80OSEXM4qsGk2T9P", + } }, }, ), @@ -252,27 +254,28 @@ SERVICE_TEMPORARILY_UNAVAILABLE_TEST_NAME = "error_400_service_temporarily_unavailable" SERVICE_TEMPORARILY_UNAVAILABLE_RESPONSE = { - "status_code": 503, - "json": { - "error": { - "message": "(#2) Service temporarily unavailable", - "type": "OAuthException", - "is_transient": True, - "code": 2, - "fbtrace_id": "AnUyGZoFqN2m50GHVpOQEqr", - } - }, - } + "status_code": 503, + "json": { + "error": { + "message": "(#2) Service temporarily unavailable", + "type": "OAuthException", + "is_transient": True, + "code": 2, + "fbtrace_id": "AnUyGZoFqN2m50GHVpOQEqr", + } + }, +} REDUCE_FIELDS_ERROR_TEST_NAME = "error_500_reduce_the_amount_of_data" REDUCE_FIELDS_ERROR_RESPONSE = { - "status_code": 500, - "json": { - "error": { - "message": "Please reduce the amount of data you're asking for, then retry your request", - "code": 1, - } - }, - } + "status_code": 500, + "json": { + "error": { + "message": "Please reduce the amount of data you're asking for, then retry your request", + "code": 1, + } + }, +} + class TestRealErrors: @pytest.mark.parametrize( @@ -406,23 +409,24 @@ def test_config_error_during_actual_nodes_read(self, requests_mock, name, friend assert error.failure_type == FailureType.config_error assert friendly_msg in error.message - @pytest.mark.parametrize("name, friendly_msg, config_error_response, failure_type", - [ - ( - REDUCE_FIELDS_ERROR_TEST_NAME, - "Please reduce the number of fields requested. Go to the schema tab, " - "select your source, and unselect the fields you do not need.", - REDUCE_FIELDS_ERROR_RESPONSE, - FailureType.config_error - ), - ( - SERVICE_TEMPORARILY_UNAVAILABLE_TEST_NAME, - "The Facebook API service is temporarily unavailable. This issue should resolve itself, and does not require further action.", - SERVICE_TEMPORARILY_UNAVAILABLE_RESPONSE, - FailureType.transient_error - ) - ] - ) + @pytest.mark.parametrize( + "name, friendly_msg, config_error_response, failure_type", + [ + ( + REDUCE_FIELDS_ERROR_TEST_NAME, + "Please reduce the number of fields requested. Go to the schema tab, " + "select your source, and unselect the fields you do not need.", + REDUCE_FIELDS_ERROR_RESPONSE, + FailureType.config_error, + ), + ( + SERVICE_TEMPORARILY_UNAVAILABLE_TEST_NAME, + "The Facebook API service is temporarily unavailable. This issue should resolve itself, and does not require further action.", + SERVICE_TEMPORARILY_UNAVAILABLE_RESPONSE, + FailureType.transient_error, + ), + ], + ) def test_config_error_that_was_retried_when_reading_nodes(self, requests_mock, name, friendly_msg, config_error_response, failure_type): """This test covers errors that have been resolved in the past with a retry strategy, but it could also can fail after retries, then, we need to provide the user with a humanized error explaining what just happened""" @@ -498,7 +502,7 @@ def test_config_error_insights_during_actual_nodes_read(self, requests_mock, nam assert friendly_msg in error.message def test_retry_for_cannot_include_error(self, requests_mock): - """Error raised randomly for insights stream. Oncall: https://github.com/airbytehq/oncall/issues/4868 """ + """Error raised randomly for insights stream. Oncall: https://github.com/airbytehq/oncall/issues/4868""" api = API(access_token=some_config["access_token"], page_size=100) stream = AdsInsights( @@ -516,7 +520,7 @@ def test_retry_for_cannot_include_error(self, requests_mock): "error": { "message": "(#100) Cannot include video_avg_time_watched_actions, video_continuous_2_sec_watched_actions in summary param because they weren't there while creating the report run.", "type": "OAuthException", - "code": 100 + "code": 100, } }, } @@ -594,24 +598,22 @@ def test_traced_exception_with_api_error(): request_context={}, http_status=400, http_headers={}, - body='{"error": {"message": "Error validating access token", "code": 190}}' + body='{"error": {"message": "Error validating access token", "code": 190}}', ) error.api_error_message = MagicMock(return_value="Error validating access token") - + result = traced_exception(error) - + assert isinstance(result, AirbyteTracedException) - assert result.message == "Invalid access token. Re-authenticate if FB oauth is used or refresh access token with all required permissions" + assert ( + result.message == "Invalid access token. Re-authenticate if FB oauth is used or refresh access token with all required permissions" + ) assert result.failure_type == FailureType.config_error def test_traced_exception_without_api_error(): error = FacebookRequestError( - message="Call was unsuccessful. The Facebook API has imploded", - request_context={}, - http_status=408, - http_headers={}, - body='{}' + message="Call was unsuccessful. The Facebook API has imploded", request_context={}, http_status=408, http_headers={}, body="{}" ) error.api_error_message = MagicMock(return_value=None) diff --git a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_source.py b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_source.py index 774f83c1c9e5..c5a654daa7c9 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_source.py @@ -7,6 +7,10 @@ from unittest.mock import call import pytest +from facebook_business import FacebookAdsApi, FacebookSession +from source_facebook_marketing import SourceFacebookMarketing +from source_facebook_marketing.spec import ConnectorConfig + from airbyte_cdk import AirbyteTracedException from airbyte_cdk.models import ( AirbyteConnectionStatus, @@ -18,9 +22,6 @@ Status, SyncMode, ) -from facebook_business import FacebookAdsApi, FacebookSession -from source_facebook_marketing import SourceFacebookMarketing -from source_facebook_marketing.spec import ConnectorConfig from .utils import command_check diff --git a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_utils.py b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_utils.py index 3a0ac0691c2c..209870c38ccd 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_utils.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_utils.py @@ -7,6 +7,7 @@ import pytest from source_facebook_marketing.utils import DATA_RETENTION_PERIOD, validate_end_date, validate_start_date + TODAY = pendulum.datetime(2023, 3, 31) diff --git a/airbyte-integrations/connectors/source-facebook-pages/components.py b/airbyte-integrations/connectors/source-facebook-pages/components.py index d730dc2ba169..07df178e89d5 100644 --- a/airbyte-integrations/connectors/source-facebook-pages/components.py +++ b/airbyte-integrations/connectors/source-facebook-pages/components.py @@ -9,12 +9,13 @@ import dpath.util import pendulum import requests +from requests import HTTPError + from airbyte_cdk.sources.declarative.auth.declarative_authenticator import NoAuth from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString from airbyte_cdk.sources.declarative.schema import JsonFileSchemaLoader from airbyte_cdk.sources.declarative.transformations import RecordTransformation from airbyte_cdk.sources.declarative.types import Config, Record, StreamSlice, StreamState -from requests import HTTPError @dataclass diff --git a/airbyte-integrations/connectors/source-facebook-pages/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-facebook-pages/integration_tests/acceptance.py index 43ce950d77ca..72132012aaed 100644 --- a/airbyte-integrations/connectors/source-facebook-pages/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-facebook-pages/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-facebook-pages/unit_tests/test_custom_field_transformation.py b/airbyte-integrations/connectors/source-facebook-pages/unit_tests/test_custom_field_transformation.py new file mode 100644 index 000000000000..8f553d3d745c --- /dev/null +++ b/airbyte-integrations/connectors/source-facebook-pages/unit_tests/test_custom_field_transformation.py @@ -0,0 +1,19 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import json +import os + +from source_facebook_pages.components import CustomFieldTransformation + + +def test_field_transformation(): + with ( + open(f"{os.path.dirname(__file__)}/initial_record.json", "r") as initial_record, + open(f"{os.path.dirname(__file__)}/transformed_record.json", "r") as transformed_record, + ): + initial_record = json.loads(initial_record.read()) + transformed_record = json.loads(transformed_record.read()) + record_transformation = CustomFieldTransformation(config={}, parameters={"name": "page"}) + assert transformed_record == record_transformation.transform(initial_record) diff --git a/airbyte-integrations/connectors/source-factorial/metadata.yaml b/airbyte-integrations/connectors/source-factorial/metadata.yaml index cb6bf148206e..f5f7cf7dcf01 100644 --- a/airbyte-integrations/connectors/source-factorial/metadata.yaml +++ b/airbyte-integrations/connectors/source-factorial/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-factorial connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 02e8708f-3270-4f13-8b67-257b8ef439f0 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-factorial githubIssueLabel: source-factorial icon: icon.svg diff --git a/airbyte-integrations/connectors/source-faker/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-faker/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-faker/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-faker/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-faker/main.py b/airbyte-integrations/connectors/source-faker/main.py index 9df2974ae7bd..27ee46fc769b 100644 --- a/airbyte-integrations/connectors/source-faker/main.py +++ b/airbyte-integrations/connectors/source-faker/main.py @@ -5,5 +5,6 @@ from source_faker.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-faker/metadata.yaml b/airbyte-integrations/connectors/source-faker/metadata.yaml index 456dd85753ef..0bfb42e697fe 100644 --- a/airbyte-integrations/connectors/source-faker/metadata.yaml +++ b/airbyte-integrations/connectors/source-faker/metadata.yaml @@ -9,7 +9,7 @@ data: connectorSubtype: api connectorType: source definitionId: dfd88b22-b603-4c3d-aad7-3701784586b1 - dockerImageTag: 6.2.20-rc.1 + dockerImageTag: 6.2.21-rc.1 dockerRepository: airbyte/source-faker documentationUrl: https://docs.airbyte.com/integrations/sources/faker githubIssueLabel: source-faker diff --git a/airbyte-integrations/connectors/source-faker/pyproject.toml b/airbyte-integrations/connectors/source-faker/pyproject.toml index 3ce1d14fb33c..5ad85cb26c03 100644 --- a/airbyte-integrations/connectors/source-faker/pyproject.toml +++ b/airbyte-integrations/connectors/source-faker/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "6.2.20-rc.1" +version = "6.2.21-rc.1" name = "source-faker" description = "Source implementation for fake but realistic looking data." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-faker/source_faker/purchase_generator.py b/airbyte-integrations/connectors/source-faker/source_faker/purchase_generator.py index 70f166a8a4fb..6be3cd5510c5 100644 --- a/airbyte-integrations/connectors/source-faker/source_faker/purchase_generator.py +++ b/airbyte-integrations/connectors/source-faker/source_faker/purchase_generator.py @@ -6,9 +6,10 @@ from multiprocessing import current_process from typing import Dict, List -from airbyte_cdk.models import AirbyteRecordMessage, Type from mimesis import Datetime, Numeric +from airbyte_cdk.models import AirbyteRecordMessage, Type + from .airbyte_message_with_cached_json import AirbyteMessageWithCachedJSON from .utils import format_airbyte_time, now_millis diff --git a/airbyte-integrations/connectors/source-faker/source_faker/source.py b/airbyte-integrations/connectors/source-faker/source_faker/source.py index 15423b7fcb81..965d2b71b68a 100644 --- a/airbyte-integrations/connectors/source-faker/source_faker/source.py +++ b/airbyte-integrations/connectors/source-faker/source_faker/source.py @@ -10,6 +10,7 @@ from .streams import Products, Purchases, Users + DEFAULT_COUNT = 1_000 diff --git a/airbyte-integrations/connectors/source-faker/source_faker/user_generator.py b/airbyte-integrations/connectors/source-faker/source_faker/user_generator.py index 2e8a0b7b2192..4251b42ac01b 100644 --- a/airbyte-integrations/connectors/source-faker/source_faker/user_generator.py +++ b/airbyte-integrations/connectors/source-faker/source_faker/user_generator.py @@ -5,10 +5,11 @@ import datetime from multiprocessing import current_process -from airbyte_cdk.models import AirbyteRecordMessage, Type from mimesis import Address, Datetime, Person from mimesis.locales import Locale +from airbyte_cdk.models import AirbyteRecordMessage, Type + from .airbyte_message_with_cached_json import AirbyteMessageWithCachedJSON from .utils import format_airbyte_time, now_millis diff --git a/airbyte-integrations/connectors/source-faker/unit_tests/unit_test.py b/airbyte-integrations/connectors/source-faker/unit_tests/unit_test.py index e4fbef60201b..395a0181e47b 100644 --- a/airbyte-integrations/connectors/source-faker/unit_tests/unit_test.py +++ b/airbyte-integrations/connectors/source-faker/unit_tests/unit_test.py @@ -4,9 +4,10 @@ import jsonschema import pytest -from airbyte_cdk.models import AirbyteMessage, ConfiguredAirbyteCatalog, Type from source_faker import SourceFaker +from airbyte_cdk.models import AirbyteMessage, ConfiguredAirbyteCatalog, Type + class MockLogger: def debug(a, b, **kwargs): diff --git a/airbyte-integrations/connectors/source-fastbill/README.md b/airbyte-integrations/connectors/source-fastbill/README.md index 3b40ddf780b1..3bca407f747e 100644 --- a/airbyte-integrations/connectors/source-fastbill/README.md +++ b/airbyte-integrations/connectors/source-fastbill/README.md @@ -1,49 +1,22 @@ # Fastbill source connector -This is the repository for the Fastbill source connector, written in Python. -For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.com/integrations/sources/fastbill). +This directory contains the manifest-only connector for `source-fastbill`. +This _manifest-only_ connector is not a Python package on its own, as it runs inside of the base `source-declarative-manifest` image. -## Local development - -### Prerequisites - -- Python (~=3.9) -- Poetry (~=1.7) - installation instructions [here](https://python-poetry.org/docs/#installation) - -### Installing the connector - -From this connector directory, run: - -```bash -poetry install --with dev -``` - -### Create credentials +For information about how to configure and use this connector within Airbyte, see [the connector's full documentation](https://docs.airbyte.com/integrations/sources/fastbill). -**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/fastbill) -to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_fastbill/spec.yaml` file. -Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. -See `sample_files/sample_config.json` for a sample config file. - -### Locally running the connector - -``` -poetry run source-fastbill spec -poetry run source-fastbill check --config secrets/config.json -poetry run source-fastbill discover --config secrets/config.json -poetry run source-fastbill read --config secrets/config.json --catalog sample_files/configured_catalog.json -``` +## Local development -### Running unit tests +We recommend using the Connector Builder to edit this connector. +Using either Airbyte Cloud or your local Airbyte OSS instance, navigate to the **Builder** tab and select **Import a YAML**. +Then select the connector's `manifest.yaml` file to load the connector into the Builder. You're now ready to make changes to the connector! -To run unit tests locally, from the connector directory run: - -``` -poetry run pytest unit_tests -``` +If you prefer to develop locally, you can follow the instructions below. ### Building the docker image +You can build any manifest-only connector with `airbyte-ci`: + 1. Install [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md) 2. Run the following command to build the docker image: @@ -53,18 +26,24 @@ airbyte-ci connectors --name=source-fastbill build An image will be available on your host with the tag `airbyte/source-fastbill:dev`. +### Creating credentials + +**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/fastbill) +to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `spec` object in the connector's `manifest.yaml` file. +Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. + ### Running as a docker container -Then run any of the connector commands as follows: +Then run any of the standard source connector commands: -``` +```bash docker run --rm airbyte/source-fastbill:dev spec docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-fastbill:dev check --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-fastbill:dev discover --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-fastbill:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json ``` -### Running our CI test suite +### Running the CI test suite You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): @@ -72,31 +51,13 @@ You can run our full test suite locally using [`airbyte-ci`](https://github.com/ airbyte-ci connectors --name=source-fastbill test ``` -### Customizing acceptance Tests - -Customize `acceptance-test-config.yml` file to configure acceptance tests. See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) for more information. -If your connector requires to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py. - -### Dependency Management - -All of your dependencies should be managed via Poetry. -To add a new dependency, run: - -```bash -poetry add -``` - -Please commit the changes to `pyproject.toml` and `poetry.lock` files. - ## Publishing a new version of the connector -You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what? - -1. Make sure your changes are passing our test suite: `airbyte-ci connectors --name=source-fastbill test` -2. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): - - bump the `dockerImageTag` value in in `metadata.yaml` - - bump the `version` value in `pyproject.toml` -3. Make sure the `metadata.yaml` content is up to date. +If you want to contribute changes to `source-fastbill`, here's how you can do that: +1. Make your changes locally, or load the connector's manifest into Connector Builder and make changes there. +2. Make sure your changes are passing our test suite with `airbyte-ci connectors --name=source-fastbill test` +3. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): + - bump the `dockerImageTag` value in in `metadata.yaml` 4. Make sure the connector documentation and its changelog is up to date (`docs/integrations/sources/fastbill.md`). 5. Create a Pull Request: use [our PR naming conventions](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#pull-request-title-convention). 6. Pat yourself on the back for being an awesome contributor. diff --git a/airbyte-integrations/connectors/source-fastbill/__init__.py b/airbyte-integrations/connectors/source-fastbill/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-integrations/connectors/source-fastbill/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-integrations/connectors/source-fastbill/acceptance-test-config.yml b/airbyte-integrations/connectors/source-fastbill/acceptance-test-config.yml index 1081a3bd8c19..4cc5f90fea25 100644 --- a/airbyte-integrations/connectors/source-fastbill/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-fastbill/acceptance-test-config.yml @@ -3,29 +3,29 @@ # Airbyte doesn't have a Fastbill test account to run tests connector_image: airbyte/source-fastbill:dev acceptance_tests: - # spec: - # tests: - # - spec_path: "source_fastbill/spec.yaml" + spec: + tests: + - spec_path: "manifest.yaml" connection: tests: - # - config_path: "secrets/config.json" - # status: "succeed" + - config_path: "secrets/config.json" + status: "succeed" - config_path: "integration_tests/invalid_config.json" status: "failed" - # discovery: - # tests: - # - config_path: "secrets/config.json" - # basic_read: - # tests: - # - config_path: "secrets/config.json" - # configured_catalog_path: "integration_tests/configured_catalog.json" - # empty_streams: - # - name: products - # - name: recurring_invoices - # - name: revenues - # incremental: - # bypass_reason: "This connector does not implement incremental sync" - # full_refresh: - # tests: - # - config_path: "secrets/config.json" - # configured_catalog_path: "integration_tests/configured_catalog.json" + discovery: + tests: + - config_path: "secrets/config.json" + basic_read: + tests: + - config_path: "secrets/config.json" + configured_catalog_path: "integration_tests/configured_catalog.json" + empty_streams: + - name: products + - name: recurring_invoices + - name: revenues + incremental: + bypass_reason: "This connector does not implement incremental sync" + full_refresh: + tests: + - config_path: "secrets/config.json" + configured_catalog_path: "integration_tests/configured_catalog.json" diff --git a/airbyte-integrations/connectors/source-fastbill/components.py b/airbyte-integrations/connectors/source-fastbill/components.py new file mode 100644 index 000000000000..2d3160cd6992 --- /dev/null +++ b/airbyte-integrations/connectors/source-fastbill/components.py @@ -0,0 +1,19 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import base64 +from dataclasses import dataclass + +from airbyte_cdk.sources.declarative.auth.token import BasicHttpAuthenticator + + +@dataclass +class CustomAuthenticator(BasicHttpAuthenticator): + @property + def token(self): + username = self._username.eval(self.config).encode("latin1") + password = self._password.eval(self.config).encode("latin1") + encoded_credentials = base64.b64encode(b":".join((username, password))).strip() + token = "Basic " + encoded_credentials.decode("utf-8") + return token diff --git a/airbyte-integrations/connectors/source-fastbill/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-fastbill/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-fastbill/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-fastbill/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-fastbill/main.py b/airbyte-integrations/connectors/source-fastbill/main.py deleted file mode 100644 index acf657a8214d..000000000000 --- a/airbyte-integrations/connectors/source-fastbill/main.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from source_fastbill.run import run - -if __name__ == "__main__": - run() diff --git a/airbyte-integrations/connectors/source-fastbill/manifest.yaml b/airbyte-integrations/connectors/source-fastbill/manifest.yaml new file mode 100644 index 000000000000..ef46f17853cd --- /dev/null +++ b/airbyte-integrations/connectors/source-fastbill/manifest.yaml @@ -0,0 +1,1401 @@ +version: 5.15.0 + +type: DeclarativeSource + +check: + type: CheckStream + stream_names: + - invoices + +definitions: + streams: + invoices: + type: DeclarativeStream + name: invoices + primary_key: + - INVOICE_ID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api.php + http_method: POST + request_body_json: + LIMIT: 100 + SERVICE: invoice.get + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - RESPONSE + - INVOICES + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: OFFSET + pagination_strategy: + type: OffsetIncrement + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/invoices" + recurring_invoices: + type: DeclarativeStream + name: recurring_invoices + primary_key: + - INVOICE_ID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api.php + http_method: POST + request_body_json: + LIMIT: 100 + SERVICE: recurring.get + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - RESPONSE + - INVOICES + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: OFFSET + pagination_strategy: + type: OffsetIncrement + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/recurring_invoices" + products: + type: DeclarativeStream + name: products + primary_key: + - ARTICLE_ID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api.php + http_method: POST + request_body_json: + LIMIT: 100 + SERVICE: article.get + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - RESPONSE + - ARTICLES + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: OFFSET + pagination_strategy: + type: OffsetIncrement + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + revenues: + type: DeclarativeStream + name: revenues + primary_key: + - INVOICE_ID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api.php + http_method: POST + request_body_json: + LIMIT: 100 + SERVICE: revenue.get + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - RESPONSE + - REVENUES + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: OFFSET + pagination_strategy: + type: OffsetIncrement + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/revenues" + customers: + type: DeclarativeStream + name: customers + primary_key: + - CUSTOMER_ID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api.php + http_method: POST + request_body_json: + LIMIT: 100 + SERVICE: customer.get + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - RESPONSE + - CUSTOMERS + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: OFFSET + pagination_strategy: + type: OffsetIncrement + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers" + base_requester: + type: HttpRequester + url_base: https://my.fastbill.com/api/1.0 + authenticator: + class_name: source_declarative_manifest.components.CustomAuthenticator + password: "{{ config[\"api_key\"] }}" + username: "{{ config[\"username\"] }}" + +streams: + - $ref: "#/definitions/streams/invoices" + - $ref: "#/definitions/streams/recurring_invoices" + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/revenues" + - $ref: "#/definitions/streams/customers" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - username + - api_key + properties: + username: + type: string + description: Username for Fastbill account + order: 0 + title: Username + api_key: + type: string + description: Fastbill API key + order: 1 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + invoices: false + recurring_invoices: false + products: false + revenues: false + customers: false + yamlComponents: + global: + - authenticator + testedStreams: + invoices: + streamHash: 20857ec38cdfc474738705385285d6859e74866e + recurring_invoices: + streamHash: 9f9b69113f6ac08925352b114b516d219d6e93a1 + products: + streamHash: 7e92ddc1f8374019dc37c33f961beebe45c44af5 + revenues: + streamHash: d161fe2af92a08a53bd6937db97adcc1bcf8c64f + customers: + streamHash: 4707ba52e52e71f51211199a0dad1427be27c13b + assist: {} + +schemas: + invoices: + type: object + $schema: http://json-schema.org/draft-04/schema# + additionalProperties: true + properties: + ADDRESS: + type: string + description: Customer address + empty: true + ADDRESS_2: + type: string + description: Additional address information + empty: true + BANK_ACCOUNT_NUMBER: + type: string + description: Customer's bank account number + empty: true + BANK_ACCOUNT_OWNER: + type: string + description: Name of the bank account owner + empty: true + BANK_BIC: + type: string + description: Bank Identifier Code + empty: true + BANK_CODE: + type: string + description: Bank code + empty: true + BANK_IBAN: + type: string + description: International Bank Account Number + empty: true + BANK_NAME: + type: string + description: Name of the bank + empty: true + CASH_DISCOUNT_DAYS: + type: string + description: Number of days to avail cash discount + CASH_DISCOUNT_PERCENT: + type: string + description: Percentage of cash discount offered + CITY: + type: string + description: Customer's city + empty: true + CONTACT_ID: + type: string + description: Contact ID + COUNTRY_CODE: + type: string + description: Customer's country code + CURRENCY_CODE: + type: string + description: Currency code + CUSTOMER_COSTCENTER_ID: + type: string + description: Customer's cost center ID + CUSTOMER_ID: + type: string + description: Customer ID + CUSTOMER_NUMBER: + type: string + description: Customer number + DELIVERY_DATE: + type: string + description: Date of delivery + DOCUMENT_URL: + type: string + description: URL to access the document + DUE_DATE: + type: string + description: Due date for payment + FIRST_NAME: + type: string + description: Customer's first name + empty: true + INTROTEXT: + type: string + description: Introductory text + empty: true + INVOICE_DATE: + type: string + description: Date of the invoice + INVOICE_ID: + type: string + description: Invoice ID + INVOICE_NUMBER: + type: string + description: Invoice number + INVOICE_TITLE: + type: string + description: Title of the invoice + empty: true + IS_CANCELED: + type: string + description: Flag indicating if the invoice is canceled + ITEMS: + type: + - "null" + - array + description: Items included in the invoice + items: + type: object + properties: + ARTICLE_NUMBER: + type: string + description: Article number + CATEGORY: + type: + - "null" + - array + description: Category of the item + items: {} + CATEGORY_ID: + type: + - "null" + - array + description: Category ID + items: {} + COMPLETE_GROSS: + type: number + description: Total gross amount for the item + COMPLETE_NET: + type: number + description: Total net amount for the item + DESCRIPTION: + type: string + description: Description of the item + empty: true + INVOICE_ITEM_ID: + type: integer + description: Invoice item ID + QUANTITY: + type: integer + description: Quantity of the item + SORT_ORDER: + type: integer + description: Order in which the item appears + UNIT_PRICE: + type: number + description: Unit price of the item + VAT_PERCENT: + type: integer + description: VAT percentage for the item + VAT_VALUE: + type: number + description: VAT value for the item + LASTUPDATE: + type: string + description: Last update date + LAST_NAME: + type: string + description: Customer's last name + empty: true + NOTE: + type: string + description: Additional note + empty: true + ORGANIZATION: + type: string + description: Customer's organization + empty: true + PAID_DATE: + type: string + description: Date when the invoice was paid + PAYMENTS: + type: + - "null" + - array + description: Payment details + items: + description: Individual payment details + PAYMENT_INFO: + type: string + description: Payment information + PAYMENT_TYPE: + type: string + description: Type of payment + empty: true + PROJECT_ID: + type: string + description: Project ID + SALUTATION: + type: string + description: Salutation for the customer + empty: true + SERVICE_PERIOD_END: + type: string + description: End date of the service period + SERVICE_PERIOD_START: + type: string + description: Start date of the service period + SUB_TOTAL: + type: number + description: Subtotal amount + TEMPLATE_ID: + type: string + description: Template ID + empty: true + TOTAL: + type: number + description: Total amount + TYPE: + type: string + description: Type of the invoice + VAT_CASE: + type: string + description: VAT case + VAT_ID: + type: string + description: VAT ID + VAT_ITEMS: + type: + - "null" + - array + description: VAT details for items + items: + type: object + properties: + COMPLETE_NET: + type: number + description: Total net amount for VAT + VAT_PERCENT: + type: integer + description: VAT percentage + VAT_VALUE: + type: number + description: VAT value + VAT_TOTAL: + type: number + description: Total VAT amount + ZIPCODE: + type: string + description: Customer's ZIP code + empty: true + recurring_invoices: + type: + - object + $schema: http://json-schema.org/draft-04/schema# + additionalProperties: true + properties: + ADDRESS: + type: + - "null" + - string + description: Customer's street address + empty: true + ADDRESS_2: + type: + - "null" + - string + description: Additional address information + empty: true + BANK_ACCOUNT_NUMBER: + type: + - "null" + - string + description: Customer's bank account number + empty: true + BANK_ACCOUNT_OWNER: + type: + - "null" + - string + description: Owner's name of the bank account + empty: true + BANK_BIC: + type: + - "null" + - string + description: Bank Identifier Code + empty: true + BANK_CODE: + type: + - "null" + - string + description: Bank code or routing number + empty: true + BANK_IBAN: + type: + - "null" + - string + description: International Bank Account Number + empty: true + BANK_NAME: + type: + - "null" + - string + description: Name of the customer's bank + empty: true + CASH_DISCOUNT_DAYS: + type: + - "null" + - string + description: Number of days for cash discount + CASH_DISCOUNT_PERCENT: + type: + - "null" + - string + description: Percentage of cash discount + CITY: + type: + - "null" + - string + description: Customer's city + empty: true + CONTACT_ID: + type: + - "null" + - string + description: Contact ID of the customer + CURRENCY_CODE: + type: + - "null" + - string + description: Currency code used for the invoice + CUSTOMER_COSTCENTER_ID: + type: + - "null" + - string + description: Customer's cost center ID + CUSTOMER_ID: + type: + - "null" + - string + description: Unique ID of the customer + CUSTOMER_NUMBER: + type: + - "null" + - string + description: Customer's unique identification number + DELIVERY_DATE: + type: + - "null" + - string + description: Date of delivery + EMAIL_NOTIFY: + type: + - "null" + - string + description: Flag to indicate if customer was notified via email + FIRST_NAME: + type: + - "null" + - string + description: Customer's first name + empty: true + FREQUENCY: + type: + - "null" + - string + description: Frequency of the recurring invoice + INTROTEXT: + type: + - "null" + - string + description: Introduction text for the invoice + empty: true + INVOICE_ID: + type: + - string + description: Unique ID of the invoice + INVOICE_TITLE: + type: + - "null" + - string + description: Title of the invoice + ITEMS: + type: + - "null" + - array + description: List of items in the invoice + items: + type: + - "null" + - object + properties: + ARTICLE_NUMBER: + type: + - "null" + - string + description: Article number of the item + CATEGORY: + type: + - "null" + - string + - array + description: Category of the item + empty: true + items: {} + CATEGORY_ID: + type: + - "null" + - integer + - array + description: Unique ID of the category + items: {} + COMPLETE_GROSS: + type: + - "null" + - number + description: Total gross amount of the item + COMPLETE_NET: + type: + - "null" + - number + description: Total net amount of the item + DESCRIPTION: + type: + - "null" + - string + description: Description of the item + INVOICE_ITEM_ID: + type: + - "null" + - number + description: Unique ID of the invoice item + QUANTITY: + type: + - "null" + - number + description: Quantity of the item + SORT_ORDER: + type: + - "null" + - number + description: Order in which the item appears + UNIT_PRICE: + type: + - "null" + - number + description: Price per unit of the item + VAT_PERCENT: + type: + - "null" + - number + description: VAT percentage applied to the item + VAT_VALUE: + type: + - "null" + - number + description: VAT value of the item + LAST_NAME: + type: + - "null" + - string + description: Customer's last name + empty: true + NOTE: + type: + - "null" + - string + description: Additional notes or comments + empty: true + OCCURENCES: + type: + - "null" + - string + description: Number of occurrences for the recurring invoice + ORGANIZATION: + type: + - "null" + - string + description: Customer's organization + empty: true + OUTPUT_TYPE: + type: + - "null" + - string + description: Output format type + PAYMENT_TYPE: + type: + - "null" + - string + description: Payment method type + PROJECT_ID: + type: + - "null" + - string + description: ID of the associated project + SALUTATION: + type: + - "null" + - string + description: Customer's salutation + empty: true + SERVICE_PERIOD_END: + type: + - "null" + - string + description: End date of the service period + SERVICE_PERIOD_START: + type: + - "null" + - string + description: Start date of the service period + START_DATE: + type: + - "null" + - string + description: Start date of the recurring invoice + SUB_TOTAL: + type: + - "null" + - number + description: Total amount before tax + TEMPLATE_ID: + type: + - "null" + - string + description: Unique ID of the template used for the invoice + empty: true + TOTAL: + type: + - "null" + - number + description: Total amount including tax + TYPE: + type: + - "null" + - string + description: Type of the recurring invoice + VAT_CASE: + type: + - "null" + - string + description: VAT case type + VAT_ITEMS: + type: + - "null" + - array + description: List of VAT items in the invoice + items: + type: + - "null" + - object + properties: + COMPLETE_NET: + type: + - "null" + - number + description: Total net amount of the VAT item + VAT_PERCENT: + type: + - "null" + - number + description: VAT percentage for the VAT item + VAT_VALUE: + type: + - "null" + - number + description: VAT value of the VAT item + VAT_TOTAL: + type: + - "null" + - number + description: Total VAT amount + ZIPCODE: + type: + - "null" + - string + description: Customer's ZIP code + empty: true + products: + type: object + $schema: http://json-schema.org/draft-04/schema# + additionalProperties: true + properties: + ARTICLE_ID: + type: string + description: Unique identifier for the product article. + ARTICLE_NUMBER: + type: string + description: Identification number for the product article. + CURRENCY_CODE: + type: string + description: The currency code used for the price of the product article. + DESCRIPTION: + type: string + description: Detailed description of the product article. + empty: true + IS_GROSS: + type: number + description: Indicates whether the price is gross or net (inclusive of tax). + TAGS: + type: + - string + - "null" + description: Tags associated with the product article. + empty: true + TITLE: + type: string + description: Title or name of the product article. + UNIT: + type: string + description: Unit of measurement for the product article (e.g., piece, kg). + UNIT_PRICE: + type: string + description: Price per unit of the product article. + VAT_PERCENT: + type: string + description: >- + The percentage of Value Added Tax applied to the product article + price. + revenues: + type: object + $schema: http://json-schema.org/draft-04/schema# + additionalProperties: true + properties: + ADDRESS: + type: + - "null" + - string + description: Customer's street address + empty: true + ADDRESS_2: + type: + - "null" + - string + description: Additional address information (e.g., apartment number) + empty: true + BANK_ACCOUNT_NUMBER: + type: + - "null" + - string + description: Customer's bank account number + empty: true + BANK_ACCOUNT_OWNER: + type: + - "null" + - string + description: The name of the bank account owner + empty: true + BANK_BIC: + type: + - "null" + - string + description: Bank Identifier Code for the customer's bank + empty: true + BANK_CODE: + type: + - "null" + - string + description: Bank code for the customer's bank + empty: true + BANK_IBAN: + type: + - "null" + - string + description: International Bank Account Number (IBAN) + empty: true + BANK_NAME: + type: + - "null" + - string + description: Name of the customer's bank + empty: true + CASH_DISCOUNT_DAYS: + type: + - "null" + - string + description: Number of days within which cash discount can be availed + CASH_DISCOUNT_PERCENT: + type: + - "null" + - string + description: Percentage of cash discount available on the invoice + CITY: + type: + - "null" + - string + description: City where the customer is located + empty: true + CONTACT_ID: + type: + - "null" + - string + description: ID of the contact associated with the invoice + COUNTRY_CODE: + type: + - "null" + - string + description: Country code of the customer's location + CURRENCY_CODE: + type: + - "null" + - string + description: Currency code used for the invoice + CUSTOMER_COSTCENTER_ID: + type: + - "null" + - string + description: ID of the cost center associated with the customer + CUSTOMER_ID: + type: + - "null" + - string + description: Unique ID of the customer + CUSTOMER_NUMBER: + type: + - "null" + - string + description: Customer's identification number + DELIVERY_DATE: + type: + - "null" + - string + description: Date when the invoice delivery is scheduled + DOCUMENT_URL: + type: + - "null" + - string + description: URL link to access the invoice document + DUE_DATE: + type: + - "null" + - string + description: Due date for payment of the invoice + FIRST_NAME: + type: + - "null" + - string + description: Customer's first name + empty: true + INTROTEXT: + type: + - "null" + - string + description: Introduction text for the invoice + empty: true + INVOICE_DATE: + type: + - "null" + - string + description: Date when the invoice was issued + INVOICE_ID: + type: + - string + description: Unique ID of the invoice + INVOICE_NUMBER: + type: + - "null" + - string + description: Unique number assigned to the invoice + INVOICE_TITLE: + type: + - "null" + - string + description: Title or subject of the invoice + empty: true + IS_CANCELED: + type: + - "null" + - string + description: Indicates if the invoice is canceled + ITEMS: + type: + - array + - "null" + description: Contains information about the items related to the revenues data. + items: + type: object + properties: + ARTICLE_NUMBER: + type: + - "null" + - string + description: Unique number assigned to the item + CATEGORY: + type: + - "null" + - array + - string + description: Category to which the item belongs + empty: true + CATEGORY_ID: + type: + - "null" + - array + - integer + description: ID of the category to which the item belongs + COMPLETE_GROSS: + type: + - "null" + - number + description: Total gross amount for the item + COMPLETE_NET: + type: + - "null" + - integer + description: Total net amount for the item + DESCRIPTION: + type: + - "null" + - string + description: Description of the item + INVOICE_ITEM_ID: + type: + - "null" + - integer + description: Unique ID of the invoice item + QUANTITY: + type: + - "null" + - integer + description: Quantity of the item + SORT_ORDER: + type: + - "null" + - integer + description: Order in which the item appears in the invoice + UNIT_PRICE: + type: + - "null" + - integer + description: Price per unit of the item + VAT_PERCENT: + type: + - "null" + - integer + description: VAT percentage applicable to the item + VAT_VALUE: + type: + - "null" + - number + description: VAT amount for the item + LASTUPDATE: + type: + - "null" + - string + description: Date of the last update made to the invoice + LAST_NAME: + type: + - "null" + - string + description: Customer's last name + empty: true + NOTE: + type: + - "null" + - string + description: Additional notes or comments related to the invoice + empty: true + ORGANIZATION: + type: + - "null" + - string + description: Name of the customer's organization + empty: true + PAID_DATE: + type: + - "null" + - string + description: Date when the invoice was paid + PAYMENTS: + type: + - "null" + - array + description: >- + Contains details of the payments made corresponding to the revenues + data. + items: + AMOUNT: + type: + - string + - "null" + description: Amount of the payment + CURRENCY_CODE: + type: + - string + - "null" + description: Currency code of the payment + DATE: + type: + - string + - "null" + description: Date when the payment was made + NOTE: + type: + - string + - "null" + description: Any additional notes related to the payment + empty: true + PAYMENT_ID: + type: + - string + - "null" + description: Unique ID of the payment + TYPE: + type: + - string + - "null" + description: Type of payment (e.g., credit card, bank transfer) + PAYMENT_INFO: + type: + - "null" + - string + description: Information related to the payment + PAYMENT_TYPE: + type: + - "null" + - string + description: Type of payment (e.g., partial, full) + empty: true + PROJECT_ID: + type: + - "null" + - string + description: ID of the project associated with the invoice + SALUTATION: + type: + - "null" + - string + description: Salutation used for addressing the customer (Mr., Ms.) + empty: true + SERVICE_PERIOD_END: + type: + - "null" + - string + description: End date of the service period covered by the invoice + empty: true + SERVICE_PERIOD_START: + type: + - "null" + - string + description: Start date of the service period covered by the invoice + empty: true + SUB_TOTAL: + type: + - "null" + - integer + description: Subtotal amount before applying taxes or discounts + TEMPLATE_ID: + type: + - "null" + - string + description: ID of the template used for generating the invoice + empty: true + TOTAL: + type: + - number + - "null" + description: Total amount including all taxes and discounts + TYPE: + type: + - "null" + - string + description: Type of the invoice (e.g., sales, service) + VAT_CASE: + type: + - "null" + - string + description: VAT case type (e.g., domestic, intra-community) + VAT_ID: + type: + - "null" + - string + description: VAT identification number + VAT_ITEMS: + type: + - array + - "null" + description: >- + Includes VAT (Value Added Tax) related items associated with the + revenues data. + items: + type: object + properties: + COMPLETE_NET: + type: + - "null" + - integer + description: Total net amount for the VAT item + VAT_PERCENT: + type: + - "null" + - integer + description: VAT percentage for the VAT item + VAT_VALUE: + type: + - "null" + - number + description: VAT value for the VAT item + VAT_TOTAL: + type: + - "null" + - number + description: Total VAT amount for the invoice + ZIPCODE: + type: + - "null" + - string + description: Zip code of the customer's location + empty: true + customers: + type: object + $schema: http://json-schema.org/draft-04/schema# + additionalProperties: true + properties: + ACADEMIC_DEGREE: + type: string + description: Academic degree of the customer + empty: true + ADDRESS: + type: string + description: Primary address of the customer + empty: true + ADDRESS_2: + type: string + description: Secondary address of the customer + empty: true + BANK_ACCOUNT_MANDATE_REFERENCE: + type: string + description: Reference for the bank account mandate + empty: true + BANK_ACCOUNT_NUMBER: + type: string + description: Bank account number + empty: true + BANK_ACCOUNT_OWNER: + type: string + description: Owner of the bank account + empty: true + BANK_BIC: + type: string + description: Bank Identification Code + empty: true + BANK_CODE: + type: string + description: Bank code associated with the bank account + empty: true + BANK_IBAN: + type: string + description: International Bank Account Number + empty: true + BANK_NAME: + type: string + description: Name of the bank + empty: true + CITY: + type: string + description: City of the customer + empty: true + COUNTRY_CODE: + type: string + description: Country code of the customer + CREATED: + type: string + description: Date and time when the customer record was created + format: date-time + CURRENCY_CODE: + type: string + description: Currency code used for transactions + CUSTOMER_ACCOUNT: + type: string + description: Customer account details + empty: true + CUSTOMER_ID: + type: string + description: Unique identifier for the customer + CUSTOMER_NUMBER: + type: string + description: Customer number for identification + CUSTOMER_TYPE: + type: string + description: Type of customer + empty: true + DAYS_FOR_PAYMENT: + type: string + description: Number of days allowed for payment + empty: true + DOCUMENT_HISTORY_URL: + type: string + description: URL for customer's document history + empty: true + EMAIL: + type: string + description: Email address of the customer + empty: true + FAX: + type: string + description: Fax number of the customer + empty: true + FIRST_NAME: + type: string + description: First name of the customer + empty: true + LASTUPDATE: + type: string + description: Last update timestamp for the customer record + LAST_NAME: + type: string + description: Last name of the customer + empty: true + MOBILE: + type: string + description: Mobile phone number of the customer + empty: true + NEWSLETTER_OPTIN: + type: string + description: Opt-in status for receiving newsletters + empty: true + ORGANIZATION: + type: string + description: Organization or company name + empty: true + PAYMENT_TYPE: + type: string + description: Payment type preferred by the customer + empty: true + PHONE: + type: string + description: Primary phone number of the customer + empty: true + PHONE_2: + type: string + description: Secondary phone number of the customer + empty: true + POSITION: + type: string + description: Position or job title of the customer + empty: true + SALUTATION: + type: string + description: Salutation used when addressing the customer + empty: true + SECONDARY_ADDRESS: + type: string + description: Secondary address details + empty: true + SHOW_PAYMENT_NOTICE: + type: string + description: Flag indicating whether payment notice should be displayed + empty: true + TAGS: + type: string + description: Tags or labels associated with the customer + empty: true + TOP: + type: string + description: Top level customer identifier + empty: true + VAT_ID: + type: string + description: Value Added Tax (VAT) identification number + WEBSITE: + type: string + description: Website URL of the customer + empty: true + ZIPCODE: + type: string + description: ZIP or postal code of the customer + empty: true diff --git a/airbyte-integrations/connectors/source-fastbill/metadata.yaml b/airbyte-integrations/connectors/source-fastbill/metadata.yaml index 133a48df87e0..27c433b5f2d0 100644 --- a/airbyte-integrations/connectors/source-fastbill/metadata.yaml +++ b/airbyte-integrations/connectors/source-fastbill/metadata.yaml @@ -3,11 +3,11 @@ data: hosts: - "*" connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: eb3e9c1c-0467-4eb7-a172-5265e04ccd0a - dockerImageTag: 0.2.24 + dockerImageTag: 0.3.5 dockerRepository: airbyte/source-fastbill documentationUrl: https://docs.airbyte.com/integrations/sources/fastbill githubIssueLabel: source-fastbill @@ -23,11 +23,14 @@ data: releaseStage: alpha remoteRegistries: pypi: - enabled: true + enabled: false packageName: airbyte-source-fastbill + ab_internal: + ql: 100 + sl: 100 supportLevel: community tags: - - language:python + - language:manifest-only - cdk:low-code connectorTestSuitesOptions: - suite: unitTests diff --git a/airbyte-integrations/connectors/source-fastbill/poetry.lock b/airbyte-integrations/connectors/source-fastbill/poetry.lock deleted file mode 100644 index 92915b0e1ad3..000000000000 --- a/airbyte-integrations/connectors/source-fastbill/poetry.lock +++ /dev/null @@ -1,1048 +0,0 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. - -[[package]] -name = "airbyte-cdk" -version = "0.80.0" -description = "A framework for writing Airbyte Connectors." -optional = false -python-versions = "<4.0,>=3.9" -files = [ - {file = "airbyte_cdk-0.80.0-py3-none-any.whl", hash = "sha256:060e92323a73674fa4e9e2e4a1eb312b9b9d072c9bbe5fa28f54ef21cb4974f3"}, - {file = "airbyte_cdk-0.80.0.tar.gz", hash = "sha256:1383512a83917fecca5b24cea4c72aa5c561cf96dd464485fbcefda48fe574c5"}, -] - -[package.dependencies] -airbyte-protocol-models = "0.5.1" -backoff = "*" -cachetools = "*" -Deprecated = ">=1.2,<1.3" -dpath = ">=2.0.1,<2.1.0" -genson = "1.2.2" -isodate = ">=0.6.1,<0.7.0" -Jinja2 = ">=3.1.2,<3.2.0" -jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" -pendulum = "<3.0.0" -pydantic = ">=1.10.8,<2.0.0" -pyrate-limiter = ">=3.1.0,<3.2.0" -python-dateutil = "*" -PyYAML = ">=6.0.1,<7.0.0" -requests = "*" -requests_cache = "*" -wcmatch = "8.4" - -[package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.0.271)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] - -[[package]] -name = "airbyte-protocol-models" -version = "0.5.1" -description = "Declares the Airbyte Protocol." -optional = false -python-versions = ">=3.8" -files = [ - {file = "airbyte_protocol_models-0.5.1-py3-none-any.whl", hash = "sha256:dfe84e130e51ce2ae81a06d5aa36f6c5ce3152b9e36e6f0195fad6c3dab0927e"}, - {file = "airbyte_protocol_models-0.5.1.tar.gz", hash = "sha256:7c8b16c7c1c7956b1996052e40585a3a93b1e44cb509c4e97c1ee4fe507ea086"}, -] - -[package.dependencies] -pydantic = ">=1.9.2,<2.0.0" - -[[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, -] - -[[package]] -name = "attrs" -version = "24.2.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" -files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, -] - -[package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] - -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "bracex" -version = "2.5.post1" -description = "Bash style brace expander." -optional = false -python-versions = ">=3.8" -files = [ - {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, - {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, -] - -[[package]] -name = "cachetools" -version = "5.5.0" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, - {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, -] - -[[package]] -name = "cattrs" -version = "24.1.2" -description = "Composable complex class support for attrs and dataclasses." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, - {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, -] - -[package.dependencies] -attrs = ">=23.1.0" -exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} - -[package.extras] -bson = ["pymongo (>=4.4.0)"] -cbor2 = ["cbor2 (>=5.4.6)"] -msgpack = ["msgpack (>=1.0.5)"] -msgspec = ["msgspec (>=0.18.5)"] -orjson = ["orjson (>=3.9.2)"] -pyyaml = ["pyyaml (>=6.0)"] -tomlkit = ["tomlkit (>=0.11.8)"] -ujson = ["ujson (>=5.7.0)"] - -[[package]] -name = "certifi" -version = "2024.8.30" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.0" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -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 = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - -[[package]] -name = "dpath" -version = "2.0.8" -description = "Filesystem-like pathing and searching for dictionaries" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dpath-2.0.8-py3-none-any.whl", hash = "sha256:f92f595214dd93a00558d75d4b858beee519f4cffca87f02616ad6cd013f3436"}, - {file = "dpath-2.0.8.tar.gz", hash = "sha256:a3440157ebe80d0a3ad794f1b61c571bef125214800ffdb9afc9424e8250fe9b"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "genson" -version = "1.2.2" -description = "GenSON is a powerful, user-friendly JSON Schema generator." -optional = false -python-versions = "*" -files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, -] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isodate" -version = "0.6.1" -description = "An ISO 8601 date/time/duration parser and formatter" -optional = false -python-versions = "*" -files = [ - {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, - {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "jinja2" -version = "3.1.4" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "jsonref" -version = "0.2" -description = "An implementation of JSON Reference for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonref-0.2-py3-none-any.whl", hash = "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f"}, - {file = "jsonref-0.2.tar.gz", hash = "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697"}, -] - -[[package]] -name = "jsonschema" -version = "3.2.0" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, -] - -[package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" - -[package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] - -[[package]] -name = "markupsafe" -version = "3.0.1" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -files = [ - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win32.whl", hash = "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win32.whl", hash = "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win32.whl", hash = "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win32.whl", hash = "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win32.whl", hash = "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b"}, - {file = "markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344"}, -] - -[[package]] -name = "packaging" -version = "24.1" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, -] - -[[package]] -name = "pendulum" -version = "2.1.2" -description = "Python datetimes made easy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, - {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, - {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, - {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, - {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, - {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, - {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, - {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, - {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, - {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, - {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, -] - -[package.dependencies] -python-dateutil = ">=2.6,<3.0" -pytzdata = ">=2020.1" - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] - -[[package]] -name = "pydantic" -version = "1.10.18" -description = "Data validation and settings management using python type hints" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, -] - -[package.dependencies] -typing-extensions = ">=4.2.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] - -[[package]] -name = "pyrate-limiter" -version = "3.1.1" -description = "Python Rate-Limiter using Leaky-Bucket Algorithm" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, - {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, -] - -[package.extras] -all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] -docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] - -[[package]] -name = "pyrsistent" -version = "0.20.0" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7"}, - {file = "pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee"}, - {file = "pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d"}, - {file = "pyrsistent-0.20.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win32.whl", hash = "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d"}, - {file = "pyrsistent-0.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win32.whl", hash = "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf"}, - {file = "pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b"}, - {file = "pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4"}, -] - -[[package]] -name = "pytest" -version = "6.2.5" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, -] - -[package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] - -[[package]] -name = "pytest-mock" -version = "3.14.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, -] - -[package.dependencies] -pytest = ">=6.2.5" - -[package.extras] -dev = ["pre-commit", "pytest-asyncio", "tox"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytzdata" -version = "2020.1" -description = "The Olson timezone database for Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, - {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-cache" -version = "1.2.1" -description = "A persistent cache for python requests" -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, - {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, -] - -[package.dependencies] -attrs = ">=21.2" -cattrs = ">=22.2" -platformdirs = ">=2.5" -requests = ">=2.22" -url-normalize = ">=1.4" -urllib3 = ">=1.25.5" - -[package.extras] -all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] -bson = ["bson (>=0.5)"] -docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] -dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] -json = ["ujson (>=5.4)"] -mongodb = ["pymongo (>=3)"] -redis = ["redis (>=3)"] -security = ["itsdangerous (>=2.0)"] -yaml = ["pyyaml (>=6.0.1)"] - -[[package]] -name = "setuptools" -version = "75.1.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"}, - {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "url-normalize" -version = "1.4.3" -description = "URL normalization for Python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, - {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "urllib3" -version = "2.2.3" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "wcmatch" -version = "8.4" -description = "Wildcard/glob file name matcher." -optional = false -python-versions = ">=3.7" -files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, -] - -[package.dependencies] -bracex = ">=2.1.1" - -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "41355a5bbc184920577634c7e63ed44c5ad8778fec503f57375dc15ad92ae487" diff --git a/airbyte-integrations/connectors/source-fastbill/pyproject.toml b/airbyte-integrations/connectors/source-fastbill/pyproject.toml deleted file mode 100644 index f24a4e5d06ea..000000000000 --- a/airbyte-integrations/connectors/source-fastbill/pyproject.toml +++ /dev/null @@ -1,27 +0,0 @@ -[build-system] -requires = [ "poetry-core>=1.0.0",] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -version = "0.2.24" -name = "source-fastbill" -description = "Source implementation for Fastbill." -authors = [ "Airbyte ",] -license = "MIT" -readme = "README.md" -documentation = "https://docs.airbyte.com/integrations/sources/fastbill" -homepage = "https://airbyte.com" -repository = "https://github.com/airbytehq/airbyte" -[[tool.poetry.packages]] -include = "source_fastbill" - -[tool.poetry.dependencies] -python = "^3.9,<3.12" -airbyte-cdk = "0.80.0" - -[tool.poetry.scripts] -source-fastbill = "source_fastbill.run:run" - -[tool.poetry.group.dev.dependencies] -pytest = "^6.2" -pytest-mock = "^3.6.1" diff --git a/airbyte-integrations/connectors/source-fastbill/source_fastbill/__init__.py b/airbyte-integrations/connectors/source-fastbill/source_fastbill/__init__.py deleted file mode 100644 index 4fb157c56bff..000000000000 --- a/airbyte-integrations/connectors/source-fastbill/source_fastbill/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from .source import SourceFastbill - -__all__ = ["SourceFastbill"] diff --git a/airbyte-integrations/connectors/source-fastbill/source_fastbill/components.py b/airbyte-integrations/connectors/source-fastbill/source_fastbill/components.py deleted file mode 100644 index 002f96dd713c..000000000000 --- a/airbyte-integrations/connectors/source-fastbill/source_fastbill/components.py +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import base64 -from dataclasses import dataclass - -from airbyte_cdk.sources.declarative.auth.token import BasicHttpAuthenticator - - -@dataclass -class CustomAuthenticator(BasicHttpAuthenticator): - @property - def token(self): - - username = self._username.eval(self.config).encode("latin1") - password = self._password.eval(self.config).encode("latin1") - encoded_credentials = base64.b64encode(b":".join((username, password))).strip() - token = "Basic " + encoded_credentials.decode("utf-8") - return token diff --git a/airbyte-integrations/connectors/source-fastbill/source_fastbill/manifest.yaml b/airbyte-integrations/connectors/source-fastbill/source_fastbill/manifest.yaml deleted file mode 100644 index 00ab59efceb8..000000000000 --- a/airbyte-integrations/connectors/source-fastbill/source_fastbill/manifest.yaml +++ /dev/null @@ -1,1282 +0,0 @@ -version: "0.29.0" - -definitions: - selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: ["RESPONSE", "{{ parameters.record_extractor }}"] - requester: - type: HttpRequester - url_base: "https://my.fastbill.com/api/1.0" - http_method: "POST" - authenticator: - class_name: source_fastbill.components.CustomAuthenticator - username: "{{config['username']}}" - password: "{{config['api_key']}}" - request_body_json: - SERVICE: "{{ parameters.endpoint }}.get" - LIMIT: 100 - Content-Type: "application/json" - retriever: - type: SimpleRetriever - record_selector: - $ref: "#/definitions/selector" - paginator: - type: "DefaultPaginator" - pagination_strategy: - type: "OffsetIncrement" - page_size: 100 - page_token_option: - type: "RequestOption" - field_name: "OFFSET" - inject_into: "body_json" - requester: - $ref: "#/definitions/requester" - base_stream: - type: DeclarativeStream - retriever: - $ref: "#/definitions/retriever" - - invoices_stream: - $ref: "#/definitions/base_stream" - name: "invoices" - primary_key: "INVOICE_ID" - $parameters: - path: "/api.php" - endpoint: "invoice" - record_extractor: "INVOICES" - - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-04/schema# - type: object - properties: - INVOICE_ID: - description: Invoice ID - type: string - TYPE: - description: Type of the invoice - type: string - CUSTOMER_ID: - description: Customer ID - type: string - CUSTOMER_NUMBER: - description: Customer number - type: string - CUSTOMER_COSTCENTER_ID: - description: Customer's cost center ID - type: string - CONTACT_ID: - description: Contact ID - type: string - PROJECT_ID: - description: Project ID - type: string - CURRENCY_CODE: - description: Currency code - type: string - DELIVERY_DATE: - description: Date of delivery - type: string - INVOICE_TITLE: - description: Title of the invoice - type: string - empty: true - CASH_DISCOUNT_PERCENT: - description: Percentage of cash discount offered - type: string - CASH_DISCOUNT_DAYS: - description: Number of days to avail cash discount - type: string - SUB_TOTAL: - description: Subtotal amount - type: number - VAT_TOTAL: - description: Total VAT amount - type: number - VAT_CASE: - description: VAT case - type: string - VAT_ITEMS: - description: VAT details for items - type: - - "null" - - array - items: - type: object - properties: - VAT_PERCENT: - description: VAT percentage - type: integer - COMPLETE_NET: - description: Total net amount for VAT - type: number - VAT_VALUE: - description: VAT value - type: number - ITEMS: - description: Items included in the invoice - type: - - "null" - - array - items: - type: object - properties: - INVOICE_ITEM_ID: - description: Invoice item ID - type: integer - ARTICLE_NUMBER: - description: Article number - type: string - DESCRIPTION: - description: Description of the item - type: string - empty: true - QUANTITY: - description: Quantity of the item - type: integer - UNIT_PRICE: - description: Unit price of the item - type: number - VAT_PERCENT: - description: VAT percentage for the item - type: integer - VAT_VALUE: - description: VAT value for the item - type: number - COMPLETE_NET: - description: Total net amount for the item - type: number - COMPLETE_GROSS: - description: Total gross amount for the item - type: number - CATEGORY: - description: Category of the item - type: - - "null" - - array - items: {} - CATEGORY_ID: - description: Category ID - type: - - "null" - - array - items: {} - SORT_ORDER: - description: Order in which the item appears - type: integer - TOTAL: - description: Total amount - type: number - ORGANIZATION: - description: Customer's organization - type: string - empty: true - NOTE: - description: Additional note - type: string - empty: true - SALUTATION: - description: Salutation for the customer - type: string - empty: true - FIRST_NAME: - description: Customer's first name - type: string - empty: true - LAST_NAME: - description: Customer's last name - type: string - empty: true - ADDRESS: - description: Customer address - type: string - empty: true - ADDRESS_2: - description: Additional address information - type: string - empty: true - ZIPCODE: - description: Customer's ZIP code - type: string - empty: true - CITY: - description: Customer's city - type: string - empty: true - SERVICE_PERIOD_START: - description: Start date of the service period - type: string - SERVICE_PERIOD_END: - description: End date of the service period - type: string - PAYMENT_TYPE: - description: Type of payment - type: string - empty: true - BANK_NAME: - description: Name of the bank - type: string - empty: true - BANK_ACCOUNT_NUMBER: - description: Customer's bank account number - type: string - empty: true - BANK_CODE: - description: Bank code - type: string - empty: true - BANK_ACCOUNT_OWNER: - description: Name of the bank account owner - type: string - empty: true - BANK_IBAN: - description: International Bank Account Number - type: string - empty: true - BANK_BIC: - description: Bank Identifier Code - type: string - empty: true - COUNTRY_CODE: - description: Customer's country code - type: string - VAT_ID: - description: VAT ID - type: string - TEMPLATE_ID: - description: Template ID - type: string - empty: true - INVOICE_NUMBER: - description: Invoice number - type: string - INTROTEXT: - description: Introductory text - type: string - empty: true - PAID_DATE: - description: Date when the invoice was paid - type: string - IS_CANCELED: - description: Flag indicating if the invoice is canceled - type: string - INVOICE_DATE: - description: Date of the invoice - type: string - DUE_DATE: - description: Due date for payment - type: string - PAYMENT_INFO: - description: Payment information - type: string - PAYMENTS: - description: Payment details - type: - - "null" - - array - items: - description: Individual payment details - LASTUPDATE: - description: Last update date - type: string - DOCUMENT_URL: - description: URL to access the document - type: string - recurring_invoices_stream: - $ref: "#/definitions/base_stream" - name: "recurring_invoices" - primary_key: "INVOICE_ID" - $parameters: - path: "/api.php" - endpoint: "recurring" - record_extractor: "INVOICES" - - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-04/schema# - type: - - object - properties: - INVOICE_ID: - description: Unique ID of the invoice - type: - - string - TYPE: - description: Type of the recurring invoice - type: - - "null" - - string - CUSTOMER_ID: - description: Unique ID of the customer - type: - - "null" - - string - CUSTOMER_NUMBER: - description: Customer's unique identification number - type: - - "null" - - string - CUSTOMER_COSTCENTER_ID: - description: Customer's cost center ID - type: - - "null" - - string - CONTACT_ID: - description: Contact ID of the customer - type: - - "null" - - string - PROJECT_ID: - description: ID of the associated project - type: - - "null" - - string - CURRENCY_CODE: - description: Currency code used for the invoice - type: - - "null" - - string - DELIVERY_DATE: - description: Date of delivery - type: - - "null" - - string - INVOICE_TITLE: - description: Title of the invoice - type: - - "null" - - string - CASH_DISCOUNT_PERCENT: - description: Percentage of cash discount - type: - - "null" - - string - CASH_DISCOUNT_DAYS: - description: Number of days for cash discount - type: - - "null" - - string - SUB_TOTAL: - description: Total amount before tax - type: - - "null" - - number - VAT_TOTAL: - description: Total VAT amount - type: - - "null" - - number - VAT_CASE: - description: VAT case type - type: - - "null" - - string - VAT_ITEMS: - description: List of VAT items in the invoice - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - VAT_PERCENT: - description: VAT percentage for the VAT item - type: - - "null" - - number - COMPLETE_NET: - description: Total net amount of the VAT item - type: - - "null" - - number - VAT_VALUE: - description: VAT value of the VAT item - type: - - "null" - - number - ITEMS: - description: List of items in the invoice - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - INVOICE_ITEM_ID: - description: Unique ID of the invoice item - type: - - "null" - - number - ARTICLE_NUMBER: - description: Article number of the item - type: - - "null" - - string - DESCRIPTION: - description: Description of the item - type: - - "null" - - string - QUANTITY: - description: Quantity of the item - type: - - "null" - - number - UNIT_PRICE: - description: Price per unit of the item - type: - - "null" - - number - VAT_PERCENT: - description: VAT percentage applied to the item - type: - - "null" - - number - VAT_VALUE: - description: VAT value of the item - type: - - "null" - - number - COMPLETE_NET: - description: Total net amount of the item - type: - - "null" - - number - COMPLETE_GROSS: - description: Total gross amount of the item - type: - - "null" - - number - CATEGORY: - description: Category of the item - type: - - "null" - - string - - array - empty: true - items: {} - CATEGORY_ID: - description: Unique ID of the category - type: - - "null" - - integer - - array - items: {} - SORT_ORDER: - description: Order in which the item appears - type: - - "null" - - number - TOTAL: - description: Total amount including tax - type: - - "null" - - number - ORGANIZATION: - description: Customer's organization - type: - - "null" - - string - empty: true - NOTE: - description: Additional notes or comments - type: - - "null" - - string - empty: true - SALUTATION: - description: Customer's salutation - type: - - "null" - - string - empty: true - FIRST_NAME: - description: Customer's first name - type: - - "null" - - string - empty: true - LAST_NAME: - description: Customer's last name - type: - - "null" - - string - empty: true - ADDRESS: - description: Customer's street address - type: - - "null" - - string - empty: true - ADDRESS_2: - description: Additional address information - type: - - "null" - - string - empty: true - ZIPCODE: - description: Customer's ZIP code - type: - - "null" - - string - empty: true - CITY: - description: Customer's city - type: - - "null" - - string - empty: true - SERVICE_PERIOD_START: - description: Start date of the service period - type: - - "null" - - string - SERVICE_PERIOD_END: - description: End date of the service period - type: - - "null" - - string - PAYMENT_TYPE: - description: Payment method type - type: - - "null" - - string - BANK_NAME: - description: Name of the customer's bank - type: - - "null" - - string - empty: true - BANK_ACCOUNT_NUMBER: - description: Customer's bank account number - type: - - "null" - - string - empty: true - BANK_CODE: - description: Bank code or routing number - type: - - "null" - - string - empty: true - BANK_ACCOUNT_OWNER: - description: Owner's name of the bank account - type: - - "null" - - string - empty: true - BANK_IBAN: - description: International Bank Account Number - type: - - "null" - - string - empty: true - BANK_BIC: - description: Bank Identifier Code - type: - - "null" - - string - empty: true - TEMPLATE_ID: - description: Unique ID of the template used for the invoice - type: - - "null" - - string - empty: true - OCCURENCES: - description: Number of occurrences for the recurring invoice - type: - - "null" - - string - FREQUENCY: - description: Frequency of the recurring invoice - type: - - "null" - - string - START_DATE: - description: Start date of the recurring invoice - type: - - "null" - - string - EMAIL_NOTIFY: - description: Flag to indicate if customer was notified via email - type: - - "null" - - string - OUTPUT_TYPE: - description: Output format type - type: - - "null" - - string - INTROTEXT: - description: Introduction text for the invoice - type: - - "null" - - string - empty: true - products_stream: - $ref: "#/definitions/base_stream" - name: "products" - primary_key: "ARTICLE_ID" - $parameters: - path: "/api.php" - endpoint: "article" - record_extractor: "ARTICLES" - - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-04/schema# - type: object - properties: - ARTICLE_ID: - description: Unique identifier for the product article. - type: string - ARTICLE_NUMBER: - description: Identification number for the product article. - type: string - TITLE: - description: Title or name of the product article. - type: string - DESCRIPTION: - description: Detailed description of the product article. - type: string - empty: true - UNIT: - description: - Unit of measurement for the product article (e.g., piece, - kg). - type: string - UNIT_PRICE: - description: Price per unit of the product article. - type: string - CURRENCY_CODE: - description: The currency code used for the price of the product article. - type: string - VAT_PERCENT: - description: - The percentage of Value Added Tax applied to the product - article price. - type: string - IS_GROSS: - description: - Indicates whether the price is gross or net (inclusive of - tax). - type: number - TAGS: - description: Tags associated with the product article. - type: - - string - - "null" - empty: true - revenues_stream: - $ref: "#/definitions/base_stream" - name: "revenues" - primary_key: "INVOICE_ID" - $parameters: - path: "/api.php" - endpoint: "revenue" - record_extractor: "REVENUES" - - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-04/schema# - type: object - properties: - INVOICE_ID: - description: Unique ID of the invoice - type: - - string - TYPE: - description: Type of the invoice (e.g., sales, service) - type: - - "null" - - string - CUSTOMER_ID: - description: Unique ID of the customer - type: - - "null" - - string - CUSTOMER_NUMBER: - description: Customer's identification number - type: - - "null" - - string - CUSTOMER_COSTCENTER_ID: - description: ID of the cost center associated with the customer - type: - - "null" - - string - CONTACT_ID: - description: ID of the contact associated with the invoice - type: - - "null" - - string - PROJECT_ID: - description: ID of the project associated with the invoice - type: - - "null" - - string - CURRENCY_CODE: - description: Currency code used for the invoice - type: - - "null" - - string - DELIVERY_DATE: - description: Date when the invoice delivery is scheduled - type: - - "null" - - string - INVOICE_TITLE: - description: Title or subject of the invoice - type: - - "null" - - string - empty: true - CASH_DISCOUNT_PERCENT: - description: Percentage of cash discount available on the invoice - type: - - "null" - - string - CASH_DISCOUNT_DAYS: - description: Number of days within which cash discount can be availed - type: - - "null" - - string - SUB_TOTAL: - description: Subtotal amount before applying taxes or discounts - type: - - "null" - - integer - VAT_TOTAL: - description: Total VAT amount for the invoice - type: - - "null" - - number - VAT_CASE: - description: VAT case type (e.g., domestic, intra-community) - type: - - "null" - - string - VAT_ITEMS: - description: - Includes VAT (Value Added Tax) related items associated with - the revenues data. - type: - - array - - "null" - items: - type: object - properties: - VAT_PERCENT: - description: VAT percentage for the VAT item - type: - - "null" - - integer - COMPLETE_NET: - description: Total net amount for the VAT item - type: - - "null" - - integer - VAT_VALUE: - description: VAT value for the VAT item - type: - - "null" - - number - ITEMS: - description: - Contains information about the items related to the revenues - data. - type: - - array - - "null" - items: - type: object - properties: - INVOICE_ITEM_ID: - description: Unique ID of the invoice item - type: - - "null" - - integer - ARTICLE_NUMBER: - description: Unique number assigned to the item - type: - - "null" - - string - DESCRIPTION: - description: Description of the item - type: - - "null" - - string - QUANTITY: - description: Quantity of the item - type: - - "null" - - integer - UNIT_PRICE: - description: Price per unit of the item - type: - - "null" - - integer - VAT_PERCENT: - description: VAT percentage applicable to the item - type: - - "null" - - integer - VAT_VALUE: - description: VAT amount for the item - type: - - "null" - - number - COMPLETE_NET: - description: Total net amount for the item - type: - - "null" - - integer - COMPLETE_GROSS: - description: Total gross amount for the item - type: - - "null" - - number - CATEGORY: - description: Category to which the item belongs - type: - - "null" - - array - - string - empty: true - CATEGORY_ID: - description: ID of the category to which the item belongs - type: - - "null" - - array - - integer - SORT_ORDER: - description: Order in which the item appears in the invoice - type: - - "null" - - integer - TOTAL: - description: Total amount including all taxes and discounts - type: - - number - - "null" - ORGANIZATION: - description: Name of the customer's organization - type: - - "null" - - string - empty: true - NOTE: - description: Additional notes or comments related to the invoice - type: - - "null" - - string - empty: true - SALUTATION: - description: Salutation used for addressing the customer (Mr., Ms.) - type: - - "null" - - string - empty: true - FIRST_NAME: - description: Customer's first name - type: - - "null" - - string - empty: true - LAST_NAME: - description: Customer's last name - type: - - "null" - - string - empty: true - ADDRESS: - description: Customer's street address - type: - - "null" - - string - empty: true - ADDRESS_2: - description: Additional address information (e.g., apartment number) - type: - - "null" - - string - empty: true - ZIPCODE: - description: Zip code of the customer's location - type: - - "null" - - string - empty: true - CITY: - description: City where the customer is located - type: - - "null" - - string - empty: true - SERVICE_PERIOD_START: - description: Start date of the service period covered by the invoice - type: - - "null" - - string - empty: true - SERVICE_PERIOD_END: - description: End date of the service period covered by the invoice - type: - - "null" - - string - empty: true - PAYMENT_TYPE: - description: Type of payment (e.g., partial, full) - type: - - "null" - - string - empty: true - BANK_NAME: - description: Name of the customer's bank - type: - - "null" - - string - empty: true - BANK_ACCOUNT_NUMBER: - description: Customer's bank account number - type: - - "null" - - string - empty: true - BANK_CODE: - description: Bank code for the customer's bank - type: - - "null" - - string - empty: true - BANK_ACCOUNT_OWNER: - description: The name of the bank account owner - type: - - "null" - - string - empty: true - BANK_IBAN: - description: International Bank Account Number (IBAN) - type: - - "null" - - string - empty: true - BANK_BIC: - description: Bank Identifier Code for the customer's bank - type: - - "null" - - string - empty: true - COUNTRY_CODE: - description: Country code of the customer's location - type: - - "null" - - string - VAT_ID: - description: VAT identification number - type: - - "null" - - string - TEMPLATE_ID: - description: ID of the template used for generating the invoice - type: - - "null" - - string - empty: true - INVOICE_NUMBER: - description: Unique number assigned to the invoice - type: - - "null" - - string - INTROTEXT: - description: Introduction text for the invoice - type: - - "null" - - string - empty: true - PAID_DATE: - description: Date when the invoice was paid - type: - - "null" - - string - IS_CANCELED: - description: Indicates if the invoice is canceled - type: - - "null" - - string - INVOICE_DATE: - description: Date when the invoice was issued - type: - - "null" - - string - DUE_DATE: - description: Due date for payment of the invoice - type: - - "null" - - string - PAYMENT_INFO: - description: Information related to the payment - type: - - "null" - - string - PAYMENTS: - description: - Contains details of the payments made corresponding to the - revenues data. - type: - - "null" - - array - items: - PAYMENT_ID: - description: Unique ID of the payment - type: - - string - - "null" - DATE: - description: Date when the payment was made - type: - - string - - "null" - AMOUNT: - description: Amount of the payment - type: - - string - - "null" - CURRENCY_CODE: - description: Currency code of the payment - type: - - string - - "null" - NOTE: - description: Any additional notes related to the payment - type: - - string - - "null" - empty: true - TYPE: - description: Type of payment (e.g., credit card, bank transfer) - type: - - string - - "null" - LASTUPDATE: - description: Date of the last update made to the invoice - type: - - "null" - - string - DOCUMENT_URL: - description: URL link to access the invoice document - type: - - "null" - - string - customers_stream: - $ref: "#/definitions/base_stream" - name: "customers" - primary_key: "CUSTOMER_ID" - $parameters: - path: "/api.php" - endpoint: "customer" - record_extractor: "CUSTOMERS" - - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-04/schema# - type: object - properties: - CUSTOMER_ID: - description: Unique identifier for the customer - type: string - CUSTOMER_NUMBER: - description: Customer number for identification - type: string - DAYS_FOR_PAYMENT: - description: Number of days allowed for payment - type: string - empty: true - CREATED: - description: Date and time when the customer record was created - type: string - format: date-time - PAYMENT_TYPE: - description: Payment type preferred by the customer - type: string - empty: true - BANK_NAME: - description: Name of the bank - type: string - empty: true - BANK_ACCOUNT_NUMBER: - description: Bank account number - type: string - empty: true - BANK_CODE: - description: Bank code associated with the bank account - type: string - empty: true - BANK_ACCOUNT_OWNER: - description: Owner of the bank account - type: string - empty: true - BANK_IBAN: - description: International Bank Account Number - type: string - empty: true - BANK_BIC: - description: Bank Identification Code - type: string - empty: true - BANK_ACCOUNT_MANDATE_REFERENCE: - description: Reference for the bank account mandate - type: string - empty: true - SHOW_PAYMENT_NOTICE: - description: Flag indicating whether payment notice should be displayed - type: string - empty: true - CUSTOMER_ACCOUNT: - description: Customer account details - type: string - empty: true - CUSTOMER_TYPE: - description: Type of customer - type: string - empty: true - TOP: - description: Top level customer identifier - type: string - empty: true - NEWSLETTER_OPTIN: - description: Opt-in status for receiving newsletters - type: string - empty: true - ORGANIZATION: - description: Organization or company name - type: string - empty: true - POSITION: - description: Position or job title of the customer - type: string - empty: true - ACADEMIC_DEGREE: - description: Academic degree of the customer - type: string - empty: true - SALUTATION: - description: Salutation used when addressing the customer - type: string - empty: true - FIRST_NAME: - description: First name of the customer - type: string - empty: true - LAST_NAME: - description: Last name of the customer - type: string - empty: true - ADDRESS: - description: Primary address of the customer - type: string - empty: true - ADDRESS_2: - description: Secondary address of the customer - type: string - empty: true - ZIPCODE: - description: ZIP or postal code of the customer - type: string - empty: true - CITY: - description: City of the customer - type: string - empty: true - COUNTRY_CODE: - description: Country code of the customer - type: string - SECONDARY_ADDRESS: - description: Secondary address details - type: string - empty: true - PHONE: - description: Primary phone number of the customer - type: string - empty: true - PHONE_2: - description: Secondary phone number of the customer - type: string - empty: true - FAX: - description: Fax number of the customer - type: string - empty: true - MOBILE: - description: Mobile phone number of the customer - type: string - empty: true - EMAIL: - description: Email address of the customer - type: string - empty: true - WEBSITE: - description: Website URL of the customer - type: string - empty: true - VAT_ID: - description: Value Added Tax (VAT) identification number - type: string - CURRENCY_CODE: - description: Currency code used for transactions - type: string - LASTUPDATE: - description: Last update timestamp for the customer record - type: string - TAGS: - description: Tags or labels associated with the customer - type: string - empty: true - DOCUMENT_HISTORY_URL: - description: URL for customer's document history - type: string - empty: true -streams: - - "#/definitions/invoices_stream" - - "#/definitions/recurring_invoices_stream" - - "#/definitions/products_stream" - - "#/definitions/revenues_stream" - - "#/definitions/customers_stream" - -check: - type: CheckStream - stream_names: - - "invoices" - -spec: - type: Spec - documentationUrl: "https://docs.airbyte.com/integrations/sources/fastbill" - connection_specification: - $schema: http://json-schema.org/draft-07/schema# - title: Fastbill Spec - type: object - required: - - username - - api_key - properties: - username: - title: Username - type: string - description: Username for Fastbill account - api_key: - title: API Key - type: string - description: Fastbill API key - airbyte_secret: true diff --git a/airbyte-integrations/connectors/source-fastbill/source_fastbill/run.py b/airbyte-integrations/connectors/source-fastbill/source_fastbill/run.py deleted file mode 100644 index eee32cd7dd6c..000000000000 --- a/airbyte-integrations/connectors/source-fastbill/source_fastbill/run.py +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import sys - -from airbyte_cdk.entrypoint import launch -from source_fastbill import SourceFastbill - - -def run(): - source = SourceFastbill() - launch(source, sys.argv[1:]) diff --git a/airbyte-integrations/connectors/source-fastbill/source_fastbill/source.py b/airbyte-integrations/connectors/source-fastbill/source_fastbill/source.py deleted file mode 100644 index 4c88c647489f..000000000000 --- a/airbyte-integrations/connectors/source-fastbill/source_fastbill/source.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource - -""" -This file provides the necessary constructs to interpret a provided declarative YAML configuration file into -source connector. - -WARNING: Do not modify this file. -""" - - -# Declarative Source -class SourceFastbill(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-fastbill/unit_tests/test_components.py b/airbyte-integrations/connectors/source-fastbill/unit_tests/test_components.py deleted file mode 100644 index 7e202dec15f0..000000000000 --- a/airbyte-integrations/connectors/source-fastbill/unit_tests/test_components.py +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from source_fastbill.components import CustomAuthenticator - - -def test_token_generation(): - - config = {"username": "example@gmail.com", "api_key": "api_key"} - authenticator = CustomAuthenticator(config=config, username="example@gmail.com", password="api_key", parameters=None) - token = authenticator.token - expected_token = "Basic ZXhhbXBsZUBnbWFpbC5jb206YXBpX2tleQ==" - assert expected_token == token diff --git a/airbyte-integrations/connectors/source-fauna/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-fauna/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-fauna/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-fauna/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-fauna/main.py b/airbyte-integrations/connectors/source-fauna/main.py index 9e4bc25307ed..85e9d886d239 100644 --- a/airbyte-integrations/connectors/source-fauna/main.py +++ b/airbyte-integrations/connectors/source-fauna/main.py @@ -4,5 +4,6 @@ from source_fauna.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-fauna/setup.py b/airbyte-integrations/connectors/source-fauna/setup.py index 25c4e60b8647..83c3a7c2ea4d 100644 --- a/airbyte-integrations/connectors/source-fauna/setup.py +++ b/airbyte-integrations/connectors/source-fauna/setup.py @@ -5,6 +5,7 @@ from setuptools import find_packages, setup + MAIN_REQUIREMENTS = [ "airbyte-cdk~=0.1", "faunadb~=4.2", diff --git a/airbyte-integrations/connectors/source-fauna/source_fauna/source.py b/airbyte-integrations/connectors/source-fauna/source_fauna/source.py index 8cc685a1586c..eb1d5cdbc9f2 100644 --- a/airbyte-integrations/connectors/source-fauna/source_fauna/source.py +++ b/airbyte-integrations/connectors/source-fauna/source_fauna/source.py @@ -8,6 +8,12 @@ from datetime import datetime from typing import Dict, Generator, Optional +from faunadb import _json +from faunadb import query as q +from faunadb.client import FaunaClient +from faunadb.errors import FaunaError, Unauthorized +from faunadb.objects import Ref + from airbyte_cdk.logger import AirbyteLogger from airbyte_cdk.models import ( AirbyteCatalog, @@ -23,11 +29,6 @@ Type, ) from airbyte_cdk.sources import Source -from faunadb import _json -from faunadb import query as q -from faunadb.client import FaunaClient -from faunadb.errors import FaunaError, Unauthorized -from faunadb.objects import Ref from source_fauna.serialize import fauna_doc_to_airbyte diff --git a/airbyte-integrations/connectors/source-fauna/unit_tests/check_test.py b/airbyte-integrations/connectors/source-fauna/unit_tests/check_test.py index c6c8263cc852..5c6453b7748d 100644 --- a/airbyte-integrations/connectors/source-fauna/unit_tests/check_test.py +++ b/airbyte-integrations/connectors/source-fauna/unit_tests/check_test.py @@ -4,13 +4,14 @@ from unittest.mock import MagicMock, Mock -from airbyte_cdk.models import Status from faunadb import query as q from faunadb.errors import Unauthorized from faunadb.objects import Ref from source_fauna import SourceFauna from test_util import config, mock_logger +from airbyte_cdk.models import Status + def query_hardcoded(expr): print(expr) diff --git a/airbyte-integrations/connectors/source-fauna/unit_tests/database_test.py b/airbyte-integrations/connectors/source-fauna/unit_tests/database_test.py index 5137d192adaf..1629a6bc530f 100644 --- a/airbyte-integrations/connectors/source-fauna/unit_tests/database_test.py +++ b/airbyte-integrations/connectors/source-fauna/unit_tests/database_test.py @@ -11,6 +11,10 @@ from datetime import datetime import docker +from faunadb import query as q +from source_fauna import SourceFauna +from test_util import CollectionConfig, DeletionsConfig, FullConfig, config, mock_logger, ref + from airbyte_cdk.models import ( AirbyteConnectionStatus, AirbyteStream, @@ -21,9 +25,6 @@ SyncMode, Type, ) -from faunadb import query as q -from source_fauna import SourceFauna -from test_util import CollectionConfig, DeletionsConfig, FullConfig, config, mock_logger, ref def setup_database(source: SourceFauna): diff --git a/airbyte-integrations/connectors/source-fauna/unit_tests/discover_test.py b/airbyte-integrations/connectors/source-fauna/unit_tests/discover_test.py index 82ac8183af34..7def4507c2ff 100644 --- a/airbyte-integrations/connectors/source-fauna/unit_tests/discover_test.py +++ b/airbyte-integrations/connectors/source-fauna/unit_tests/discover_test.py @@ -4,12 +4,13 @@ from unittest.mock import MagicMock, Mock -from airbyte_cdk.models import AirbyteStream from faunadb import query as q from faunadb.objects import Ref from source_fauna import SourceFauna from test_util import config, mock_logger +from airbyte_cdk.models import AirbyteStream + def mock_source() -> SourceFauna: source = SourceFauna() diff --git a/airbyte-integrations/connectors/source-fauna/unit_tests/incremental_test.py b/airbyte-integrations/connectors/source-fauna/unit_tests/incremental_test.py index 9a955244a5d4..a95880aad353 100644 --- a/airbyte-integrations/connectors/source-fauna/unit_tests/incremental_test.py +++ b/airbyte-integrations/connectors/source-fauna/unit_tests/incremental_test.py @@ -6,6 +6,11 @@ from typing import Dict, Generator from unittest.mock import MagicMock, Mock +from faunadb import _json +from faunadb import query as q +from source_fauna import SourceFauna +from test_util import CollectionConfig, config, expand_columns_query, mock_logger, ref + from airbyte_cdk.models import ( AirbyteMessage, AirbyteRecordMessage, @@ -17,10 +22,7 @@ SyncMode, Type, ) -from faunadb import _json -from faunadb import query as q -from source_fauna import SourceFauna -from test_util import CollectionConfig, config, expand_columns_query, mock_logger, ref + NOW = 1234512987 diff --git a/airbyte-integrations/connectors/source-file/build_customization.py b/airbyte-integrations/connectors/source-file/build_customization.py index 1c585de9caac..83411796d153 100644 --- a/airbyte-integrations/connectors/source-file/build_customization.py +++ b/airbyte-integrations/connectors/source-file/build_customization.py @@ -5,6 +5,7 @@ from typing import TYPE_CHECKING + if TYPE_CHECKING: from dagger import Container diff --git a/airbyte-integrations/connectors/source-file/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-file/integration_tests/acceptance.py index 43ce950d77ca..72132012aaed 100644 --- a/airbyte-integrations/connectors/source-file/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-file/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-file/integration_tests/client_storage_providers_test.py b/airbyte-integrations/connectors/source-file/integration_tests/client_storage_providers_test.py index 758c1118eae6..38adaeb45a1f 100644 --- a/airbyte-integrations/connectors/source-file/integration_tests/client_storage_providers_test.py +++ b/airbyte-integrations/connectors/source-file/integration_tests/client_storage_providers_test.py @@ -9,6 +9,7 @@ import pytest from source_file.client import Client + HERE = Path(__file__).parent.absolute() diff --git a/airbyte-integrations/connectors/source-file/integration_tests/conftest.py b/airbyte-integrations/connectors/source-file/integration_tests/conftest.py index cb8041a4f396..465dcb84e2bf 100644 --- a/airbyte-integrations/connectors/source-file/integration_tests/conftest.py +++ b/airbyte-integrations/connectors/source-file/integration_tests/conftest.py @@ -24,6 +24,7 @@ from paramiko.client import AutoAddPolicy, SSHClient from paramiko.ssh_exception import SSHException + HERE = Path(__file__).parent.absolute() diff --git a/airbyte-integrations/connectors/source-file/integration_tests/file_formats_test.py b/airbyte-integrations/connectors/source-file/integration_tests/file_formats_test.py index 3f9980d1c0bf..69379aa6586b 100644 --- a/airbyte-integrations/connectors/source-file/integration_tests/file_formats_test.py +++ b/airbyte-integrations/connectors/source-file/integration_tests/file_formats_test.py @@ -7,10 +7,12 @@ from pathlib import Path import pytest -from airbyte_cdk.utils import AirbyteTracedException from source_file import SourceFile from source_file.client import Client +from airbyte_cdk.utils import AirbyteTracedException + + SAMPLE_DIRECTORY = Path(__file__).resolve().parent.joinpath("sample_files/formats") diff --git a/airbyte-integrations/connectors/source-file/main.py b/airbyte-integrations/connectors/source-file/main.py index 3e7e82fd61d8..98e8e365ff72 100644 --- a/airbyte-integrations/connectors/source-file/main.py +++ b/airbyte-integrations/connectors/source-file/main.py @@ -4,5 +4,6 @@ from source_file.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-file/metadata.yaml b/airbyte-integrations/connectors/source-file/metadata.yaml index af8bbfc91636..9e1cc8536994 100644 --- a/airbyte-integrations/connectors/source-file/metadata.yaml +++ b/airbyte-integrations/connectors/source-file/metadata.yaml @@ -10,7 +10,7 @@ data: connectorSubtype: file connectorType: source definitionId: 778daa7c-feaf-4db6-96f3-70fd645acc77 - dockerImageTag: 0.5.14 + dockerImageTag: 0.5.16 dockerRepository: airbyte/source-file documentationUrl: https://docs.airbyte.com/integrations/sources/file githubIssueLabel: source-file diff --git a/airbyte-integrations/connectors/source-file/poetry.lock b/airbyte-integrations/connectors/source-file/poetry.lock index 9e011bdd0877..e61a3e38a600 100644 --- a/airbyte-integrations/connectors/source-file/poetry.lock +++ b/airbyte-integrations/connectors/source-file/poetry.lock @@ -305,13 +305,13 @@ files = [ [[package]] name = "azure-core" -version = "1.31.0" +version = "1.32.0" description = "Microsoft Azure Core Library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "azure_core-1.31.0-py3-none-any.whl", hash = "sha256:22954de3777e0250029360ef31d80448ef1be13b80a459bff80ba7073379e2cd"}, - {file = "azure_core-1.31.0.tar.gz", hash = "sha256:656a0dd61e1869b1506b7c6a3b31d62f15984b1a573d6326f6aa2f3e4123284b"}, + {file = "azure_core-1.32.0-py3-none-any.whl", hash = "sha256:eac191a0efb23bfa83fddf321b27b122b4ec847befa3091fa736a5c32c50d7b4"}, + {file = "azure_core-1.32.0.tar.gz", hash = "sha256:22b3c35d6b2dae14990f6c1be2912bf23ffe50b220e708a28ab1bb92b1c730e5"}, ] [package.dependencies] @@ -1557,13 +1557,13 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.139" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.139-py3-none-any.whl", hash = "sha256:2a4a541bfbd0a9727255df28a60048c85bc8c4c6a276975923785c3fd82dc879"}, + {file = "langsmith-0.1.139.tar.gz", hash = "sha256:2f9e4d32fef3ad7ef42c8506448cce3a31ad6b78bb4f3310db04ddaa1e9d744d"}, ] [package.dependencies] @@ -1909,69 +1909,69 @@ et-xmlfile = "*" [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.11" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.11-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6dade64687f2bd7c090281652fe18f1151292d567a9302b34c2dbb92a3872f1f"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82f07c550a6ccd2b9290849b22316a609023ed851a87ea888c0456485a7d196a"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd9a187742d3ead9df2e49240234d728c67c356516cf4db018833a86f20ec18c"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77b0fed6f209d76c1c39f032a70df2d7acf24b1812ca3e6078fd04e8972685a3"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63fc9d5fe1d4e8868f6aae547a7b8ba0a2e592929245fff61d633f4caccdcdd6"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65cd3e3bb4fbb4eddc3c1e8dce10dc0b73e808fcb875f9fab40c81903dd9323e"}, + {file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6f67c570602300c4befbda12d153113b8974a3340fdcf3d6de095ede86c06d92"}, + {file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1f39728c7f7d766f1f5a769ce4d54b5aaa4c3f92d5b84817053cc9995b977acc"}, + {file = "orjson-3.10.11-cp310-none-win32.whl", hash = "sha256:1789d9db7968d805f3d94aae2c25d04014aae3a2fa65b1443117cd462c6da647"}, + {file = "orjson-3.10.11-cp310-none-win_amd64.whl", hash = "sha256:5576b1e5a53a5ba8f8df81872bb0878a112b3ebb1d392155f00f54dd86c83ff6"}, + {file = "orjson-3.10.11-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1444f9cb7c14055d595de1036f74ecd6ce15f04a715e73f33bb6326c9cef01b6"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdec57fe3b4bdebcc08a946db3365630332dbe575125ff3d80a3272ebd0ddafe"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4eed32f33a0ea6ef36ccc1d37f8d17f28a1d6e8eefae5928f76aff8f1df85e67"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80df27dd8697242b904f4ea54820e2d98d3f51f91e97e358fc13359721233e4b"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:705f03cee0cb797256d54de6695ef219e5bc8c8120b6654dd460848d57a9af3d"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03246774131701de8e7059b2e382597da43144a9a7400f178b2a32feafc54bd5"}, + {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8b5759063a6c940a69c728ea70d7c33583991c6982915a839c8da5f957e0103a"}, + {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:677f23e32491520eebb19c99bb34675daf5410c449c13416f7f0d93e2cf5f981"}, + {file = "orjson-3.10.11-cp311-none-win32.whl", hash = "sha256:a11225d7b30468dcb099498296ffac36b4673a8398ca30fdaec1e6c20df6aa55"}, + {file = "orjson-3.10.11-cp311-none-win_amd64.whl", hash = "sha256:df8c677df2f9f385fcc85ab859704045fa88d4668bc9991a527c86e710392bec"}, + {file = "orjson-3.10.11-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:360a4e2c0943da7c21505e47cf6bd725588962ff1d739b99b14e2f7f3545ba51"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:496e2cb45de21c369079ef2d662670a4892c81573bcc143c4205cae98282ba97"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7dfa8db55c9792d53c5952900c6a919cfa377b4f4534c7a786484a6a4a350c19"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:51f3382415747e0dbda9dade6f1e1a01a9d37f630d8c9049a8ed0e385b7a90c0"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f35a1b9f50a219f470e0e497ca30b285c9f34948d3c8160d5ad3a755d9299433"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f3b7c5803138e67028dde33450e054c87e0703afbe730c105f1fcd873496d5"}, + {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f91d9eb554310472bd09f5347950b24442600594c2edc1421403d7610a0998fd"}, + {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dfbb2d460a855c9744bbc8e36f9c3a997c4b27d842f3d5559ed54326e6911f9b"}, + {file = "orjson-3.10.11-cp312-none-win32.whl", hash = "sha256:d4a62c49c506d4d73f59514986cadebb7e8d186ad510c518f439176cf8d5359d"}, + {file = "orjson-3.10.11-cp312-none-win_amd64.whl", hash = "sha256:f1eec3421a558ff7a9b010a6c7effcfa0ade65327a71bb9b02a1c3b77a247284"}, + {file = "orjson-3.10.11-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c46294faa4e4d0eb73ab68f1a794d2cbf7bab33b1dda2ac2959ffb7c61591899"}, + {file = "orjson-3.10.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52e5834d7d6e58a36846e059d00559cb9ed20410664f3ad156cd2cc239a11230"}, + {file = "orjson-3.10.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2fc947e5350fdce548bfc94f434e8760d5cafa97fb9c495d2fef6757aa02ec0"}, + {file = "orjson-3.10.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0efabbf839388a1dab5b72b5d3baedbd6039ac83f3b55736eb9934ea5494d258"}, + {file = "orjson-3.10.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3f29634260708c200c4fe148e42b4aae97d7b9fee417fbdd74f8cfc265f15b0"}, + {file = "orjson-3.10.11-cp313-none-win32.whl", hash = "sha256:1a1222ffcee8a09476bbdd5d4f6f33d06d0d6642df2a3d78b7a195ca880d669b"}, + {file = "orjson-3.10.11-cp313-none-win_amd64.whl", hash = "sha256:bc274ac261cc69260913b2d1610760e55d3c0801bb3457ba7b9004420b6b4270"}, + {file = "orjson-3.10.11-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:19b3763e8bbf8ad797df6b6b5e0fc7c843ec2e2fc0621398534e0c6400098f87"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1be83a13312e5e58d633580c5eb8d0495ae61f180da2722f20562974188af205"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:afacfd1ab81f46dedd7f6001b6d4e8de23396e4884cd3c3436bd05defb1a6446"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb4d0bea56bba596723d73f074c420aec3b2e5d7d30698bc56e6048066bd560c"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96ed1de70fcb15d5fed529a656df29f768187628727ee2788344e8a51e1c1350"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bfb30c891b530f3f80e801e3ad82ef150b964e5c38e1fb8482441c69c35c61c"}, + {file = "orjson-3.10.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d496c74fc2b61341e3cefda7eec21b7854c5f672ee350bc55d9a4997a8a95204"}, + {file = "orjson-3.10.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:655a493bac606655db9a47fe94d3d84fc7f3ad766d894197c94ccf0c5408e7d3"}, + {file = "orjson-3.10.11-cp38-none-win32.whl", hash = "sha256:b9546b278c9fb5d45380f4809e11b4dd9844ca7aaf1134024503e134ed226161"}, + {file = "orjson-3.10.11-cp38-none-win_amd64.whl", hash = "sha256:b592597fe551d518f42c5a2eb07422eb475aa8cfdc8c51e6da7054b836b26782"}, + {file = "orjson-3.10.11-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c95f2ecafe709b4e5c733b5e2768ac569bed308623c85806c395d9cca00e08af"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80c00d4acded0c51c98754fe8218cb49cb854f0f7eb39ea4641b7f71732d2cb7"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:461311b693d3d0a060439aa669c74f3603264d4e7a08faa68c47ae5a863f352d"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52ca832f17d86a78cbab86cdc25f8c13756ebe182b6fc1a97d534051c18a08de"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c57ea78a753812f528178aa2f1c57da633754c91d2124cb28991dab4c79a54"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7fcfc6f7ca046383fb954ba528587e0f9336828b568282b27579c49f8e16aad"}, + {file = "orjson-3.10.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:86b9dd983857970c29e4c71bb3e95ff085c07d3e83e7c46ebe959bac07ebd80b"}, + {file = "orjson-3.10.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4d83f87582d223e54efb2242a79547611ba4ebae3af8bae1e80fa9a0af83bb7f"}, + {file = "orjson-3.10.11-cp39-none-win32.whl", hash = "sha256:9fd0ad1c129bc9beb1154c2655f177620b5beaf9a11e0d10bac63ef3fce96950"}, + {file = "orjson-3.10.11-cp39-none-win_amd64.whl", hash = "sha256:10f416b2a017c8bd17f325fb9dee1fb5cdd7a54e814284896b7c3f2763faa017"}, + {file = "orjson-3.10.11.tar.gz", hash = "sha256:e35b6d730de6384d5b2dab5fd23f0d76fae8bbc8c353c2f78210aa5fa4beb3ef"}, ] [[package]] @@ -3143,93 +3143,93 @@ test = ["pytest", "pytest-cov"] [[package]] name = "yarl" -version = "1.17.0" +version = "1.17.1" description = "Yet another URL library" optional = false python-versions = ">=3.9" files = [ - {file = "yarl-1.17.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2d8715edfe12eee6f27f32a3655f38d6c7410deb482158c0b7d4b7fad5d07628"}, - {file = "yarl-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1803bf2a7a782e02db746d8bd18f2384801bc1d108723840b25e065b116ad726"}, - {file = "yarl-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e66589110e20c2951221a938fa200c7aa134a8bdf4e4dc97e6b21539ff026d4"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7069d411cfccf868e812497e0ec4acb7c7bf8d684e93caa6c872f1e6f5d1664d"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cbf70ba16118db3e4b0da69dcde9d4d4095d383c32a15530564c283fa38a7c52"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0bc53cc349675b32ead83339a8de79eaf13b88f2669c09d4962322bb0f064cbc"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6aa18a402d1c80193ce97c8729871f17fd3e822037fbd7d9b719864018df746"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d89c5bc701861cfab357aa0cd039bc905fe919997b8c312b4b0c358619c38d4d"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b728bdf38ca58f2da1d583e4af4ba7d4cd1a58b31a363a3137a8159395e7ecc7"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:5542e57dc15d5473da5a39fbde14684b0cc4301412ee53cbab677925e8497c11"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e564b57e5009fb150cb513804d7e9e9912fee2e48835638f4f47977f88b4a39c"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:eb3c4cff524b4c1c1dba3a6da905edb1dfd2baf6f55f18a58914bbb2d26b59e1"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:05e13f389038842da930d439fbed63bdce3f7644902714cb68cf527c971af804"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:153c38ee2b4abba136385af4467459c62d50f2a3f4bde38c7b99d43a20c143ef"}, - {file = "yarl-1.17.0-cp310-cp310-win32.whl", hash = "sha256:4065b4259d1ae6f70fd9708ffd61e1c9c27516f5b4fae273c41028afcbe3a094"}, - {file = "yarl-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:abf366391a02a8335c5c26163b5fe6f514cc1d79e74d8bf3ffab13572282368e"}, - {file = "yarl-1.17.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:19a4fe0279626c6295c5b0c8c2bb7228319d2e985883621a6e87b344062d8135"}, - {file = "yarl-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cadd0113f4db3c6b56868d6a19ca6286f5ccfa7bc08c27982cf92e5ed31b489a"}, - {file = "yarl-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:60d6693eef43215b1ccfb1df3f6eae8db30a9ff1e7989fb6b2a6f0b468930ee8"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb8bf3843e1fa8cf3fe77813c512818e57368afab7ebe9ef02446fe1a10b492"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d2a5b35fd1d8d90443e061d0c8669ac7600eec5c14c4a51f619e9e105b136715"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5bf17b32f392df20ab5c3a69d37b26d10efaa018b4f4e5643c7520d8eee7ac7"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48f51b529b958cd06e78158ff297a8bf57b4021243c179ee03695b5dbf9cb6e1"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fcaa06bf788e19f913d315d9c99a69e196a40277dc2c23741a1d08c93f4d430"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:32f3ee19ff0f18a7a522d44e869e1ebc8218ad3ae4ebb7020445f59b4bbe5897"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:a4fb69a81ae2ec2b609574ae35420cf5647d227e4d0475c16aa861dd24e840b0"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7bacc8b77670322132a1b2522c50a1f62991e2f95591977455fd9a398b4e678d"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:437bf6eb47a2d20baaf7f6739895cb049e56896a5ffdea61a4b25da781966e8b"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:30534a03c87484092080e3b6e789140bd277e40f453358900ad1f0f2e61fc8ec"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b30df4ff98703649915144be6f0df3b16fd4870ac38a09c56d5d9e54ff2d5f96"}, - {file = "yarl-1.17.0-cp311-cp311-win32.whl", hash = "sha256:263b487246858e874ab53e148e2a9a0de8465341b607678106829a81d81418c6"}, - {file = "yarl-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:07055a9e8b647a362e7d4810fe99d8f98421575e7d2eede32e008c89a65a17bd"}, - {file = "yarl-1.17.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:84095ab25ba69a8fa3fb4936e14df631b8a71193fe18bd38be7ecbe34d0f5512"}, - {file = "yarl-1.17.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:02608fb3f6df87039212fc746017455ccc2a5fc96555ee247c45d1e9f21f1d7b"}, - {file = "yarl-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13468d291fe8c12162b7cf2cdb406fe85881c53c9e03053ecb8c5d3523822cd9"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8da3f8f368fb7e2f052fded06d5672260c50b5472c956a5f1bd7bf474ae504ab"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ec0507ab6523980bed050137007c76883d941b519aca0e26d4c1ec1f297dd646"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08fc76df7fd8360e9ff30e6ccc3ee85b8dbd6ed5d3a295e6ec62bcae7601b932"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d522f390686acb6bab2b917dd9ca06740c5080cd2eaa5aef8827b97e967319d"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:147c527a80bb45b3dcd6e63401af8ac574125d8d120e6afe9901049286ff64ef"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:24cf43bcd17a0a1f72284e47774f9c60e0bf0d2484d5851f4ddf24ded49f33c6"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:c28a44b9e0fba49c3857360e7ad1473fc18bc7f6659ca08ed4f4f2b9a52c75fa"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:350cacb2d589bc07d230eb995d88fcc646caad50a71ed2d86df533a465a4e6e1"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:fd1ab1373274dea1c6448aee420d7b38af163b5c4732057cd7ee9f5454efc8b1"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4934e0f96dadc567edc76d9c08181633c89c908ab5a3b8f698560124167d9488"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8d0a278170d75c88e435a1ce76557af6758bfebc338435b2eba959df2552163e"}, - {file = "yarl-1.17.0-cp312-cp312-win32.whl", hash = "sha256:61584f33196575a08785bb56db6b453682c88f009cd9c6f338a10f6737ce419f"}, - {file = "yarl-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:9987a439ad33a7712bd5bbd073f09ad10d38640425fa498ecc99d8aa064f8fc4"}, - {file = "yarl-1.17.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8deda7b8eb15a52db94c2014acdc7bdd14cb59ec4b82ac65d2ad16dc234a109e"}, - {file = "yarl-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56294218b348dcbd3d7fce0ffd79dd0b6c356cb2a813a1181af730b7c40de9e7"}, - {file = "yarl-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1fab91292f51c884b290ebec0b309a64a5318860ccda0c4940e740425a67b6b7"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cf93fa61ff4d9c7d40482ce1a2c9916ca435e34a1b8451e17f295781ccc034f"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:261be774a0d71908c8830c33bacc89eef15c198433a8cc73767c10eeeb35a7d0"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deec9693b67f6af856a733b8a3e465553ef09e5e8ead792f52c25b699b8f9e6e"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c804b07622ba50a765ca7fb8145512836ab65956de01307541def869e4a456c9"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d013a7c9574e98c14831a8f22d27277688ec3b2741d0188ac01a910b009987a"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e2cfcba719bd494c7413dcf0caafb51772dec168c7c946e094f710d6aa70494e"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:c068aba9fc5b94dfae8ea1cedcbf3041cd4c64644021362ffb750f79837e881f"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3616df510ffac0df3c9fa851a40b76087c6c89cbcea2de33a835fc80f9faac24"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:755d6176b442fba9928a4df787591a6a3d62d4969f05c406cad83d296c5d4e05"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c18f6e708d1cf9ff5b1af026e697ac73bea9cb70ee26a2b045b112548579bed2"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5b937c216b6dee8b858c6afea958de03c5ff28406257d22b55c24962a2baf6fd"}, - {file = "yarl-1.17.0-cp313-cp313-win32.whl", hash = "sha256:d0131b14cb545c1a7bd98f4565a3e9bdf25a1bd65c83fc156ee5d8a8499ec4a3"}, - {file = "yarl-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:01c96efa4313c01329e88b7e9e9e1b2fc671580270ddefdd41129fa8d0db7696"}, - {file = "yarl-1.17.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0d44f67e193f0a7acdf552ecb4d1956a3a276c68e7952471add9f93093d1c30d"}, - {file = "yarl-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:16ea0aa5f890cdcb7ae700dffa0397ed6c280840f637cd07bffcbe4b8d68b985"}, - {file = "yarl-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cf5469dc7dcfa65edf5cc3a6add9f84c5529c6b556729b098e81a09a92e60e51"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e662bf2f6e90b73cf2095f844e2bc1fda39826472a2aa1959258c3f2a8500a2f"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8260e88f1446904ba20b558fa8ce5d0ab9102747238e82343e46d056d7304d7e"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dc16477a4a2c71e64c5d3d15d7ae3d3a6bb1e8b955288a9f73c60d2a391282f"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46027e326cecd55e5950184ec9d86c803f4f6fe4ba6af9944a0e537d643cdbe0"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc95e46c92a2b6f22e70afe07e34dbc03a4acd07d820204a6938798b16f4014f"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:16ca76c7ac9515320cd09d6cc083d8d13d1803f6ebe212b06ea2505fd66ecff8"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:eb1a5b97388f2613f9305d78a3473cdf8d80c7034e554d8199d96dcf80c62ac4"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:41fd5498975418cdc34944060b8fbeec0d48b2741068077222564bea68daf5a6"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:146ca582ed04a5664ad04b0e0603934281eaab5c0115a5a46cce0b3c061a56a1"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:6abb8c06107dbec97481b2392dafc41aac091a5d162edf6ed7d624fe7da0587a"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4d14be4613dd4f96c25feb4bd8c0d8ce0f529ab0ae555a17df5789e69d8ec0c5"}, - {file = "yarl-1.17.0-cp39-cp39-win32.whl", hash = "sha256:174d6a6cad1068f7850702aad0c7b1bca03bcac199ca6026f84531335dfc2646"}, - {file = "yarl-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:6af417ca2c7349b101d3fd557ad96b4cd439fdb6ab0d288e3f64a068eea394d0"}, - {file = "yarl-1.17.0-py3-none-any.whl", hash = "sha256:62dd42bb0e49423f4dd58836a04fcf09c80237836796025211bbe913f1524993"}, - {file = "yarl-1.17.0.tar.gz", hash = "sha256:d3f13583f378930377e02002b4085a3d025b00402d5a80911726d43a67911cd9"}, + {file = "yarl-1.17.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1794853124e2f663f0ea54efb0340b457f08d40a1cef78edfa086576179c91"}, + {file = "yarl-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fbea1751729afe607d84acfd01efd95e3b31db148a181a441984ce9b3d3469da"}, + {file = "yarl-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ee427208c675f1b6e344a1f89376a9613fc30b52646a04ac0c1f6587c7e46ec"}, + {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b74ff4767d3ef47ffe0cd1d89379dc4d828d4873e5528976ced3b44fe5b0a21"}, + {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:62a91aefff3d11bf60e5956d340eb507a983a7ec802b19072bb989ce120cd948"}, + {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:846dd2e1243407133d3195d2d7e4ceefcaa5f5bf7278f0a9bda00967e6326b04"}, + {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e844be8d536afa129366d9af76ed7cb8dfefec99f5f1c9e4f8ae542279a6dc3"}, + {file = "yarl-1.17.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc7c92c1baa629cb03ecb0c3d12564f172218fb1739f54bf5f3881844daadc6d"}, + {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ae3476e934b9d714aa8000d2e4c01eb2590eee10b9d8cd03e7983ad65dfbfcba"}, + {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c7e177c619342e407415d4f35dec63d2d134d951e24b5166afcdfd1362828e17"}, + {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64cc6e97f14cf8a275d79c5002281f3040c12e2e4220623b5759ea7f9868d6a5"}, + {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:84c063af19ef5130084db70ada40ce63a84f6c1ef4d3dbc34e5e8c4febb20822"}, + {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:482c122b72e3c5ec98f11457aeb436ae4aecca75de19b3d1de7cf88bc40db82f"}, + {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:380e6c38ef692b8fd5a0f6d1fa8774d81ebc08cfbd624b1bca62a4d4af2f9931"}, + {file = "yarl-1.17.1-cp310-cp310-win32.whl", hash = "sha256:16bca6678a83657dd48df84b51bd56a6c6bd401853aef6d09dc2506a78484c7b"}, + {file = "yarl-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:561c87fea99545ef7d692403c110b2f99dced6dff93056d6e04384ad3bc46243"}, + {file = "yarl-1.17.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cbad927ea8ed814622305d842c93412cb47bd39a496ed0f96bfd42b922b4a217"}, + {file = "yarl-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fca4b4307ebe9c3ec77a084da3a9d1999d164693d16492ca2b64594340999988"}, + {file = "yarl-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff5c6771c7e3511a06555afa317879b7db8d640137ba55d6ab0d0c50425cab75"}, + {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b29beab10211a746f9846baa39275e80034e065460d99eb51e45c9a9495bcca"}, + {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a52a1ffdd824fb1835272e125385c32fd8b17fbdefeedcb4d543cc23b332d74"}, + {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:58c8e9620eb82a189c6c40cb6b59b4e35b2ee68b1f2afa6597732a2b467d7e8f"}, + {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d216e5d9b8749563c7f2c6f7a0831057ec844c68b4c11cb10fc62d4fd373c26d"}, + {file = "yarl-1.17.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:881764d610e3269964fc4bb3c19bb6fce55422828e152b885609ec176b41cf11"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8c79e9d7e3d8a32d4824250a9c6401194fb4c2ad9a0cec8f6a96e09a582c2cc0"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:299f11b44d8d3a588234adbe01112126010bd96d9139c3ba7b3badd9829261c3"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:cc7d768260f4ba4ea01741c1b5fe3d3a6c70eb91c87f4c8761bbcce5181beafe"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:de599af166970d6a61accde358ec9ded821234cbbc8c6413acfec06056b8e860"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2b24ec55fad43e476905eceaf14f41f6478780b870eda5d08b4d6de9a60b65b4"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9fb815155aac6bfa8d86184079652c9715c812d506b22cfa369196ef4e99d1b4"}, + {file = "yarl-1.17.1-cp311-cp311-win32.whl", hash = "sha256:7615058aabad54416ddac99ade09a5510cf77039a3b903e94e8922f25ed203d7"}, + {file = "yarl-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:14bc88baa44e1f84164a392827b5defb4fa8e56b93fecac3d15315e7c8e5d8b3"}, + {file = "yarl-1.17.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:327828786da2006085a4d1feb2594de6f6d26f8af48b81eb1ae950c788d97f61"}, + {file = "yarl-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cc353841428d56b683a123a813e6a686e07026d6b1c5757970a877195f880c2d"}, + {file = "yarl-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c73df5b6e8fabe2ddb74876fb82d9dd44cbace0ca12e8861ce9155ad3c886139"}, + {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bdff5e0995522706c53078f531fb586f56de9c4c81c243865dd5c66c132c3b5"}, + {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:06157fb3c58f2736a5e47c8fcbe1afc8b5de6fb28b14d25574af9e62150fcaac"}, + {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1654ec814b18be1af2c857aa9000de7a601400bd4c9ca24629b18486c2e35463"}, + {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f6595c852ca544aaeeb32d357e62c9c780eac69dcd34e40cae7b55bc4fb1147"}, + {file = "yarl-1.17.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:459e81c2fb920b5f5df744262d1498ec2c8081acdcfe18181da44c50f51312f7"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e48cdb8226644e2fbd0bdb0a0f87906a3db07087f4de77a1b1b1ccfd9e93685"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d9b6b28a57feb51605d6ae5e61a9044a31742db557a3b851a74c13bc61de5172"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e594b22688d5747b06e957f1ef822060cb5cb35b493066e33ceac0cf882188b7"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5f236cb5999ccd23a0ab1bd219cfe0ee3e1c1b65aaf6dd3320e972f7ec3a39da"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a2a64e62c7a0edd07c1c917b0586655f3362d2c2d37d474db1a509efb96fea1c"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d0eea830b591dbc68e030c86a9569826145df485b2b4554874b07fea1275a199"}, + {file = "yarl-1.17.1-cp312-cp312-win32.whl", hash = "sha256:46ddf6e0b975cd680eb83318aa1d321cb2bf8d288d50f1754526230fcf59ba96"}, + {file = "yarl-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:117ed8b3732528a1e41af3aa6d4e08483c2f0f2e3d3d7dca7cf538b3516d93df"}, + {file = "yarl-1.17.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5d1d42556b063d579cae59e37a38c61f4402b47d70c29f0ef15cee1acaa64488"}, + {file = "yarl-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0167540094838ee9093ef6cc2c69d0074bbf84a432b4995835e8e5a0d984374"}, + {file = "yarl-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2f0a6423295a0d282d00e8701fe763eeefba8037e984ad5de44aa349002562ac"}, + {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5b078134f48552c4d9527db2f7da0b5359abd49393cdf9794017baec7506170"}, + {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d401f07261dc5aa36c2e4efc308548f6ae943bfff20fcadb0a07517a26b196d8"}, + {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5f1ac7359e17efe0b6e5fec21de34145caef22b260e978336f325d5c84e6938"}, + {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f63d176a81555984e91f2c84c2a574a61cab7111cc907e176f0f01538e9ff6e"}, + {file = "yarl-1.17.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e275792097c9f7e80741c36de3b61917aebecc08a67ae62899b074566ff8556"}, + {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:81713b70bea5c1386dc2f32a8f0dab4148a2928c7495c808c541ee0aae614d67"}, + {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:aa46dce75078fceaf7cecac5817422febb4355fbdda440db55206e3bd288cfb8"}, + {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1ce36ded585f45b1e9bb36d0ae94765c6608b43bd2e7f5f88079f7a85c61a4d3"}, + {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:2d374d70fdc36f5863b84e54775452f68639bc862918602d028f89310a034ab0"}, + {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:2d9f0606baaec5dd54cb99667fcf85183a7477f3766fbddbe3f385e7fc253299"}, + {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b0341e6d9a0c0e3cdc65857ef518bb05b410dbd70d749a0d33ac0f39e81a4258"}, + {file = "yarl-1.17.1-cp313-cp313-win32.whl", hash = "sha256:2e7ba4c9377e48fb7b20dedbd473cbcbc13e72e1826917c185157a137dac9df2"}, + {file = "yarl-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:949681f68e0e3c25377462be4b658500e85ca24323d9619fdc41f68d46a1ffda"}, + {file = "yarl-1.17.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8994b29c462de9a8fce2d591028b986dbbe1b32f3ad600b2d3e1c482c93abad6"}, + {file = "yarl-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f9cbfbc5faca235fbdf531b93aa0f9f005ec7d267d9d738761a4d42b744ea159"}, + {file = "yarl-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b40d1bf6e6f74f7c0a567a9e5e778bbd4699d1d3d2c0fe46f4b717eef9e96b95"}, + {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5efe0661b9fcd6246f27957f6ae1c0eb29bc60552820f01e970b4996e016004"}, + {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b5c4804e4039f487e942c13381e6c27b4b4e66066d94ef1fae3f6ba8b953f383"}, + {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5d6a6c9602fd4598fa07e0389e19fe199ae96449008d8304bf5d47cb745462e"}, + {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4c9156c4d1eb490fe374fb294deeb7bc7eaccda50e23775b2354b6a6739934"}, + {file = "yarl-1.17.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6324274b4e0e2fa1b3eccb25997b1c9ed134ff61d296448ab8269f5ac068c4c"}, + {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d8a8b74d843c2638f3864a17d97a4acda58e40d3e44b6303b8cc3d3c44ae2d29"}, + {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:7fac95714b09da9278a0b52e492466f773cfe37651cf467a83a1b659be24bf71"}, + {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c180ac742a083e109c1a18151f4dd8675f32679985a1c750d2ff806796165b55"}, + {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:578d00c9b7fccfa1745a44f4eddfdc99d723d157dad26764538fbdda37209857"}, + {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:1a3b91c44efa29e6c8ef8a9a2b583347998e2ba52c5d8280dbd5919c02dfc3b5"}, + {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a7ac5b4984c468ce4f4a553df281450df0a34aefae02e58d77a0847be8d1e11f"}, + {file = "yarl-1.17.1-cp39-cp39-win32.whl", hash = "sha256:7294e38f9aa2e9f05f765b28ffdc5d81378508ce6dadbe93f6d464a8c9594473"}, + {file = "yarl-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:eb6dce402734575e1a8cc0bb1509afca508a400a57ce13d306ea2c663bad1138"}, + {file = "yarl-1.17.1-py3-none-any.whl", hash = "sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06"}, + {file = "yarl-1.17.1.tar.gz", hash = "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47"}, ] [package.dependencies] diff --git a/airbyte-integrations/connectors/source-file/pyproject.toml b/airbyte-integrations/connectors/source-file/pyproject.toml index 05a034726be0..96b3038f6f29 100644 --- a/airbyte-integrations/connectors/source-file/pyproject.toml +++ b/airbyte-integrations/connectors/source-file/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.5.14" +version = "0.5.16" name = "source-file" description = "Source implementation for File" authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-file/source_file/client.py b/airbyte-integrations/connectors/source-file/source_file/client.py index 7fcb478e9155..ca197b53d3d0 100644 --- a/airbyte-integrations/connectors/source-file/source_file/client.py +++ b/airbyte-integrations/connectors/source-file/source_file/client.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. # @@ -24,9 +24,6 @@ import pandas as pd import smart_open import smart_open.ssh -from airbyte_cdk.entrypoint import logger -from airbyte_cdk.models import AirbyteStream, FailureType, SyncMode -from airbyte_cdk.utils import AirbyteTracedException, is_cloud_environment from azure.storage.blob import BlobServiceClient from genson import SchemaBuilder from google.cloud.storage import Client as GCSClient @@ -38,8 +35,13 @@ from urllib3.exceptions import ProtocolError from yaml import safe_load +from airbyte_cdk.entrypoint import logger +from airbyte_cdk.models import AirbyteStream, FailureType, SyncMode +from airbyte_cdk.utils import AirbyteTracedException, is_cloud_environment + from .utils import LOCAL_STORAGE_NAME, backoff_handler + SSH_TIMEOUT = 60 # Force the log level of the smart-open logger to ERROR - https://github.com/airbytehq/airbyte/pull/27157 @@ -366,11 +368,11 @@ def load_dataframes(self, fp, skip_data=False, read_sample_chunk: bool = False) reader_options["engine"] = "fastparquet" yield reader(fp, **reader_options) elif self._reader_format == "excel": - # Use openpyxl to read new-style Excel (xlsx) file; return to pandas for others try: - yield from self.openpyxl_chunk_reader(fp, **reader_options) + for df_chunk in self.openpyxl_chunk_reader(fp, **reader_options): + yield df_chunk except (InvalidFileException, BadZipFile): - yield reader(fp, **reader_options) + yield pd.read_excel(fp, **reader_options) else: yield reader(fp, **reader_options) except ParserError as err: @@ -505,27 +507,74 @@ def streams(self, empty_schema: bool = False) -> Iterable: yield AirbyteStream(name=self.stream_name, json_schema=json_schema, supported_sync_modes=[SyncMode.full_refresh]) def openpyxl_chunk_reader(self, file, **kwargs): - """Use openpyxl lazy loading feature to read excel files (xlsx only) in chunks of 500 lines at a time""" - work_book = load_workbook(filename=file) + """ + Use openpyxl's lazy loading feature to read Excel files (xlsx only) in chunks of 500 lines at a time. + """ + # Retrieve reader options + header = kwargs.get("header", 0) + skiprows = kwargs.get("skiprows", 0) user_provided_column_names = kwargs.get("names") + chunk_size = 500 + + # Load workbook with data-only to avoid loading formulas + work_book = load_workbook(filename=file, data_only=True, read_only=True) + for sheetname in work_book.sheetnames: work_sheet = work_book[sheetname] - data = work_sheet.values - end = work_sheet.max_row - if end == 1 and not user_provided_column_names: - message = "Please provide column names for table in reader options field" - logger.error(message) + data = list(work_sheet.iter_rows(values_only=True)) + + # Skip rows as specified + data = data[skiprows:] + + if len(data) == 0: raise AirbyteTracedException( - message="Config validation error: " + message, - internal_message=message, + message="File does not contain enough rows to process.", + internal_message=f"Sheet {sheetname} contains no data after applying header and skiprows.", failure_type=FailureType.config_error, ) - cols, start = (next(data), 1) if not user_provided_column_names else (user_provided_column_names, 0) - step = 500 - while start <= end: - df = pd.DataFrame(data=(next(data) for _ in range(start, min(start + step, end))), columns=cols) - yield df - start += step + + # Determine column names + if user_provided_column_names: + column_names = user_provided_column_names + elif header is not None: + if len(data) <= header: + raise AirbyteTracedException( + message="File does not contain enough rows to extract headers.", + internal_message=f"Sheet {sheetname} does not have enough rows for the specified header {header}.", + failure_type=FailureType.config_error, + ) + column_names = data[header] # Extract the header row + data = data[header + 1 :] # Remove the header row and rows above it + else: + raise AirbyteTracedException( + message="Unable to determine column names. Please provide valid reader options.", + internal_message="No header or column names specified.", + failure_type=FailureType.config_error, + ) + + if column_names is None or len(column_names) == 0: + raise AirbyteTracedException( + message="Column names could not be determined.", + internal_message="Column names are empty or invalid.", + failure_type=FailureType.config_error, + ) + + if len(data) == 0: + raise AirbyteTracedException( + message="File does not contain any data rows.", + internal_message=f"Sheet {sheetname} contains no data rows after applying header and skiprows.", + failure_type=FailureType.config_error, + ) + + chunk = [] + for row in data: + chunk.append(dict(zip(column_names, row))) + if len(chunk) == chunk_size: + yield pd.DataFrame(chunk) + chunk = [] + + if chunk: + yield pd.DataFrame(chunk) class URLFileSecure(URLFile): diff --git a/airbyte-integrations/connectors/source-file/source_file/utils.py b/airbyte-integrations/connectors/source-file/source_file/utils.py index ef8c258b9179..248ee36e9f6e 100644 --- a/airbyte-integrations/connectors/source-file/source_file/utils.py +++ b/airbyte-integrations/connectors/source-file/source_file/utils.py @@ -5,6 +5,7 @@ import logging from urllib.parse import parse_qs, urlencode, urlparse + # default logger logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-file/unit_tests/test_client.py b/airbyte-integrations/connectors/source-file/unit_tests/test_client.py index 71d745c1ef74..326f6475326e 100644 --- a/airbyte-integrations/connectors/source-file/unit_tests/test_client.py +++ b/airbyte-integrations/connectors/source-file/unit_tests/test_client.py @@ -1,18 +1,21 @@ # -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. # +from tempfile import NamedTemporaryFile from unittest.mock import patch, sentinel +import pandas as pd import pytest -from airbyte_cdk.utils import AirbyteTracedException from pandas import read_csv, read_excel, testing from paramiko import SSHException from source_file.client import Client, URLFile from source_file.utils import backoff_handler from urllib3.exceptions import ProtocolError +from airbyte_cdk.utils import AirbyteTracedException + @pytest.fixture def wrong_format_client(): @@ -79,6 +82,7 @@ def test_load_dataframes_xlsb(config, absolute_path, test_files): f = f"{absolute_path}/{test_files}/test.xlsb" read_file = next(client.load_dataframes(fp=f)) expected = read_excel(f, engine="pyxlsb") + assert read_file.equals(expected) @@ -96,8 +100,7 @@ def test_load_dataframes_xlsx(config, absolute_path, test_files, file_name, shou assert read_file.equals(expected) -@pytest.mark.parametrize("file_format, file_path", [("json", "formats/json/demo.json"), - ("jsonl", "formats/jsonl/jsonl_nested.jsonl")]) +@pytest.mark.parametrize("file_format, file_path", [("json", "formats/json/demo.json"), ("jsonl", "formats/jsonl/jsonl_nested.jsonl")]) def test_load_nested_json(client, config, absolute_path, test_files, file_format, file_path): if file_format == "jsonl": config["format"] = file_format @@ -128,7 +131,8 @@ def test_cache_stream(client, absolute_path, test_files): f = f"{absolute_path}/{test_files}/test.csv" with open(f, mode="rb") as file: assert client._cache_stream(file) - + + def test_unzip_stream(client, absolute_path, test_files): f = f"{absolute_path}/{test_files}/test.csv.zip" with open(f, mode="rb") as file: @@ -220,6 +224,75 @@ def patched_open(self): def test_backoff_handler(caplog): details = {"tries": 1, "wait": 1} backoff_handler(details) - expected = [('airbyte', 20, 'Caught retryable error after 1 tries. Waiting 1 seconds then retrying...')] + expected = [("airbyte", 20, "Caught retryable error after 1 tries. Waiting 1 seconds then retrying...")] assert caplog.record_tuples == expected + + +def generate_excel_file(data): + """ + Helper function to generate an Excel file with the given data. + """ + tmp_file = NamedTemporaryFile(suffix=".xlsx", delete=False) + df = pd.DataFrame(data) + df.to_excel(tmp_file.name, index=False, header=False) + tmp_file.seek(0) + return tmp_file + + +def test_excel_reader_option_names(config): + """ + Test the 'names' option for the Excel reader. + """ + config["format"] = "excel" + config["reader_options"] = {"names": ["CustomCol1", "CustomCol2"]} + client = Client(**config) + + data = [["Value1", "Value2"], ["Value3", "Value4"]] + expected_data = [ + {"CustomCol1": "Value1", "CustomCol2": "Value2"}, + {"CustomCol1": "Value3", "CustomCol2": "Value4"}, + ] + + with generate_excel_file(data) as tmp: + read_file = next(client.load_dataframes(fp=tmp.name)) + assert isinstance(read_file, pd.DataFrame) + assert read_file.to_dict(orient="records") == expected_data + + +def test_excel_reader_option_skiprows(config): + """ + Test the 'skiprows' option for the Excel reader. + """ + config["format"] = "excel" + config["reader_options"] = {"skiprows": 1} + client = Client(**config) + + data = [["SkipRow1", "SkipRow2"], ["Header1", "Header2"], ["Value1", "Value2"]] + expected_data = [ + {"Header1": "Value1", "Header2": "Value2"}, + ] + + with generate_excel_file(data) as tmp: + read_file = next(client.load_dataframes(fp=tmp.name)) + assert isinstance(read_file, pd.DataFrame) + assert read_file.to_dict(orient="records") == expected_data + + +def test_excel_reader_option_header(config): + """ + Test the 'header' option for the Excel reader. + """ + config["format"] = "excel" + config["reader_options"] = {"header": 1} + client = Client(**config) + + data = [["UnusedRow1", "UnusedRow2"], ["Header1", "Header2"], ["Value1", "Value2"]] + expected_data = [ + {"Header1": "Value1", "Header2": "Value2"}, + ] + + with generate_excel_file(data) as tmp: + read_file = next(client.load_dataframes(fp=tmp.name)) + assert isinstance(read_file, pd.DataFrame) + assert read_file.to_dict(orient="records") == expected_data diff --git a/airbyte-integrations/connectors/source-file/unit_tests/test_nested_json_schema.py b/airbyte-integrations/connectors/source-file/unit_tests/test_nested_json_schema.py index 14bd37a419aa..8466ad5c82f2 100644 --- a/airbyte-integrations/connectors/source-file/unit_tests/test_nested_json_schema.py +++ b/airbyte-integrations/connectors/source-file/unit_tests/test_nested_json_schema.py @@ -10,6 +10,7 @@ import pytest from source_file.source import SourceFile + json_obj = { "id": "0001", "type": "donut", diff --git a/airbyte-integrations/connectors/source-file/unit_tests/test_source.py b/airbyte-integrations/connectors/source-file/unit_tests/test_source.py index 0a0c0ca798ad..26446e5db6d1 100644 --- a/airbyte-integrations/connectors/source-file/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-file/unit_tests/test_source.py @@ -8,6 +8,8 @@ import jsonschema import pytest +from source_file.source import SourceFile + from airbyte_cdk.models import ( AirbyteConnectionStatus, AirbyteMessage, @@ -22,7 +24,7 @@ ) from airbyte_cdk.utils import AirbyteTracedException from airbyte_protocol.models.airbyte_protocol import Type as MessageType -from source_file.source import SourceFile + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-fillout/README.md b/airbyte-integrations/connectors/source-fillout/README.md new file mode 100644 index 000000000000..b2a460e06d26 --- /dev/null +++ b/airbyte-integrations/connectors/source-fillout/README.md @@ -0,0 +1,33 @@ +# Fillout +This directory contains the manifest-only connector for `source-fillout`. + +The Airbyte connector for Fillout.com enables seamless data synchronization between Fillout forms and various target destinations. This connector allows you to extract form submissions and related data from Fillout and transfer it to your chosen data warehouse, analytics platform, or other destinations. With this integration, you can automate workflows, perform data analysis, and centralize data management for improved insights and reporting. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-fillout:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-fillout build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-fillout test +``` + diff --git a/airbyte-integrations/connectors/source-fillout/acceptance-test-config.yml b/airbyte-integrations/connectors/source-fillout/acceptance-test-config.yml new file mode 100644 index 000000000000..4352de9cdee6 --- /dev/null +++ b/airbyte-integrations/connectors/source-fillout/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-fillout:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-fillout/icon.svg b/airbyte-integrations/connectors/source-fillout/icon.svg new file mode 100644 index 000000000000..0fcf8d7624a2 --- /dev/null +++ b/airbyte-integrations/connectors/source-fillout/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-fillout/manifest.yaml b/airbyte-integrations/connectors/source-fillout/manifest.yaml new file mode 100644 index 000000000000..72847ed07627 --- /dev/null +++ b/airbyte-integrations/connectors/source-fillout/manifest.yaml @@ -0,0 +1,381 @@ +version: 6.1.0 + +type: DeclarativeSource + +description: >- + The Airbyte connector for Fillout.com enables seamless data synchronization + between Fillout forms and various target destinations. This connector allows + you to extract form submissions and related data from Fillout and transfer it + to your chosen data warehouse, analytics platform, or other destinations. With + this integration, you can automate workflows, perform data analysis, and + centralize data management for improved insights and reporting. + +check: + type: CheckStream + stream_names: + - forms + +definitions: + streams: + forms: + type: DeclarativeStream + name: forms + primary_key: + - formId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /forms + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/forms" + form_metadata: + type: DeclarativeStream + name: form_metadata + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /forms/{{ stream_partition.form_id }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: formId + partition_field: form_id + stream: + $ref: "#/definitions/streams/forms" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/form_metadata" + submissions: + type: DeclarativeStream + name: submissions + primary_key: + - submissionId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /forms/{{ stream_partition.form_id }}/submissions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - responses + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 150 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: formId + partition_field: form_id + stream: + $ref: "#/definitions/streams/forms" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: submissionTime + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%fZ" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: afterDate + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: "beforeDate " + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + transformations: + - type: AddFields + fields: + - path: + - formId + value: "{{ stream_partition.form_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/submissions" + base_requester: + type: HttpRequester + url_base: https://api.fillout.com/v1/api + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/forms" + - $ref: "#/definitions/streams/form_metadata" + - $ref: "#/definitions/streams/submissions" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - start_date + properties: + api_key: + type: string + description: >- + API key to use. Find it in the Developer settings tab of your Fillout + account. + name: api_key + order: 0 + title: API Key + airbyte_secret: true + start_date: + type: string + order: 1 + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + additionalProperties: true + +metadata: + autoImportSchema: + forms: true + form_metadata: true + submissions: true + testedStreams: + forms: + hasRecords: true + streamHash: ed5a5bcc98a75c0ee799db522a659dc89c16344e + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + form_metadata: + hasRecords: true + streamHash: 9701fd2020429ea05b4611e4185d634aa669712a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + submissions: + streamHash: 618af7b9b7be9ff9b37106ce75863fe568048443 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://www.fillout.com/help/fillout-rest-api + +schemas: + forms: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + formId: + type: string + id: + type: + - number + - "null" + name: + type: + - string + - "null" + required: + - formId + form_metadata: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + calculations: + type: + - array + - "null" + documents: + type: + - array + - "null" + id: + type: string + name: + type: + - string + - "null" + payments: + type: + - array + - "null" + questions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + options: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + label: + type: + - string + - "null" + value: + type: + - string + - "null" + scheduling: + type: + - array + - "null" + urlParameters: + type: + - array + - "null" + required: + - id + submissions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + calculations: + type: + - array + - "null" + documents: + type: + - array + - "null" + lastUpdatedAt: + type: + - string + - "null" + payments: + type: + - array + - "null" + questions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + value: + anyOf: + - type: + - "null" + - number + - string + - type: object + properties: + address: + type: string + city: + type: string + country: + type: string + state: + type: string + zipCode: + type: string + quiz: + type: + - object + - "null" + scheduling: + type: + - array + - "null" + submissionId: + type: string + formId: + type: string + submissionTime: + type: string + urlParameters: + type: + - array + - "null" + required: + - formId + - submissionId + - submissionTime diff --git a/airbyte-integrations/connectors/source-fillout/metadata.yaml b/airbyte-integrations/connectors/source-fillout/metadata.yaml new file mode 100644 index 000000000000..60064d9c9400 --- /dev/null +++ b/airbyte-integrations/connectors/source-fillout/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.fillout.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-fillout + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: fae4092b-fcb4-4dba-8ad4-f8bf9a32d25e + dockerImageTag: 0.2.4 + dockerRepository: airbyte/source-fillout + githubIssueLabel: source-fillout + icon: icon.svg + license: MIT + name: Fillout + releaseDate: 2024-11-14 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/fillout + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-finage/README.md b/airbyte-integrations/connectors/source-finage/README.md new file mode 100644 index 000000000000..008cd2f037ee --- /dev/null +++ b/airbyte-integrations/connectors/source-finage/README.md @@ -0,0 +1,34 @@ +# Finage +This directory contains the manifest-only connector for `source-finage`. + +Real-Time Market Data Solutions for Stocks, Forex, and Crypto +This connector can be used to extract data from various APIs such as symbol-list,Aggregates,Snapshot and Technical Indicators + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-finage:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-finage build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-finage test +``` + diff --git a/airbyte-integrations/connectors/source-finage/acceptance-test-config.yml b/airbyte-integrations/connectors/source-finage/acceptance-test-config.yml new file mode 100644 index 000000000000..e234a9ff9dfe --- /dev/null +++ b/airbyte-integrations/connectors/source-finage/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-finage:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-finage/icon.svg b/airbyte-integrations/connectors/source-finage/icon.svg new file mode 100644 index 000000000000..628584dc81e7 --- /dev/null +++ b/airbyte-integrations/connectors/source-finage/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-finage/manifest.yaml b/airbyte-integrations/connectors/source-finage/manifest.yaml new file mode 100644 index 000000000000..ea1fae755e01 --- /dev/null +++ b/airbyte-integrations/connectors/source-finage/manifest.yaml @@ -0,0 +1,1632 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Real-Time Market Data Solutions for Stocks, Forex, and Crypto + + This connector can be used to extract data from various APIs such as + symbol-list,Aggregates,Snapshot and Technical Indicators + +check: + type: CheckStream + stream_names: + - market_news + +definitions: + streams: + market_news: + type: DeclarativeStream + name: market_news + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /news/market/{{ stream_partition.symbol }} + http_method: GET + request_parameters: + limit: "30" + request_headers: + Accept-Encoding: Gzip + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - news + partition_router: + type: ListPartitionRouter + values: "{{ config[\"symbols\"] }}" + cursor_field: symbol + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/market_news" + most_active_us_stocks: + type: DeclarativeStream + name: most_active_us_stocks + primary_key: + - symbol + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /fnd/market-information/us/most-actives + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + transformations: + - type: AddFields + fields: + - path: + - Datetime + value: "{{ now_utc() }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/most_active_us_stocks" + technical_indicators: + type: DeclarativeStream + name: technical_indicators + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + fnd/technical-indicator/{{ config['tech_indicator_type'] }}/{{ + config['time'] }}/{{ stream_partition.symbol }} + http_method: GET + request_parameters: + period: "{{ config['period'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: ListPartitionRouter + values: "{{ config[\"symbols\"] }}" + cursor_field: symbol + transformations: + - type: AddFields + fields: + - path: + - symbol + value: "{{ stream_partition.symbol }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/technical_indicators" + economic_calendar: + type: DeclarativeStream + name: economic_calendar + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: fnd/economic-calendar + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + incremental_sync: + type: DatetimeBasedCursor + cursor_field: date + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: from + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: to + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/economic_calendar" + earning_calendar: + type: DeclarativeStream + name: earning_calendar + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /fnd/earning-calendar + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/earning_calendar" + delisted_companies: + type: DeclarativeStream + name: delisted_companies + primary_key: + - symbol + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /fnd/delisted-companies/ + http_method: GET + request_parameters: + limit: "1000" + period: annual + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/delisted_companies" + ipo_calendar: + type: DeclarativeStream + name: ipo_calendar + primary_key: + - symbol + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: fnd/ipo-calendar + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + incremental_sync: + type: DatetimeBasedCursor + cursor_field: date + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: from + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: to + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/ipo_calendar" + "historical_stock_split ": + type: DeclarativeStream + name: "historical_stock_split " + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: fnd/historical-stock-splits/{{ stream_partition.symbol }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: ListPartitionRouter + values: "{{ config[\"symbols\"] }}" + cursor_field: symbol + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/historical_stock_split " + historical_dividends_calendar: + type: DeclarativeStream + name: historical_dividends_calendar + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: fnd/historical-dividends/{{ stream_partition.symbol }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: ListPartitionRouter + values: "{{ config[\"symbols\"] }}" + cursor_field: symbol + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/historical_dividends_calendar" + cash_flow_statements: + type: DeclarativeStream + name: cash_flow_statements + primary_key: + - date + - symbol + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: fnd/cash-flow-statement/{{ stream_partition.symbol }} + http_method: GET + request_parameters: + period: "{{ config['time_period'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: ListPartitionRouter + values: "{{ config[\"symbols\"] }}" + cursor_field: symbol + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/cash_flow_statements" + balance_sheet_statements: + type: DeclarativeStream + name: balance_sheet_statements + primary_key: + - date + - symbol + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: fnd/balance-sheet-statements/{{ stream_partition.symbol }} + http_method: GET + request_parameters: + period: "{{ config['time_period'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: ListPartitionRouter + values: "{{ config[\"symbols\"] }}" + cursor_field: symbol + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/balance_sheet_statements" + income_statement: + type: DeclarativeStream + name: income_statement + primary_key: + - date + - symbol + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: fnd/income-statement/{{ stream_partition.symbol }} + http_method: GET + request_parameters: + period: "{{ config['time_period'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: ListPartitionRouter + values: "{{ config[\"symbols\"] }}" + cursor_field: symbol + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/income_statement" + institutional_holders: + type: DeclarativeStream + name: institutional_holders + primary_key: + - holder + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: fnd/funds/institutional-holder/{{ stream_partition.symbol }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: ListPartitionRouter + values: "{{ config[\"symbols\"] }}" + cursor_field: symbol + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/institutional_holders" + mutual_fund_holder: + type: DeclarativeStream + name: mutual_fund_holder + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: fnd/funds/mutual-fund-holder/{{ stream_partition.symbol }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: ListPartitionRouter + values: "{{ config[\"symbols\"] }}" + cursor_field: symbol + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/mutual_fund_holder" + most_gainers: + type: DeclarativeStream + name: most_gainers + primary_key: + - symbol + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: fnd/market-information/us/most-gainers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/most_gainers" + most_losers: + type: DeclarativeStream + name: most_losers + primary_key: + - symbol + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: fnd/market-information/us/most-losers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/most_losers" + sector_performance: + type: DeclarativeStream + name: sector_performance + primary_key: + - sector + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: fnd/market-information/us/sector-performance + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sector_performance" + shares_float: + type: DeclarativeStream + name: shares_float + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: fnd/shares-float/{{ stream_partition.symbol }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: ListPartitionRouter + values: "{{ config[\"symbols\"] }}" + cursor_field: symbol + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/shares_float" + base_requester: + type: HttpRequester + url_base: https://api.finage.co.uk/ + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: apikey + inject_into: request_parameter + +streams: + - $ref: "#/definitions/streams/market_news" + - $ref: "#/definitions/streams/most_active_us_stocks" + - $ref: "#/definitions/streams/technical_indicators" + - $ref: "#/definitions/streams/economic_calendar" + - $ref: "#/definitions/streams/earning_calendar" + - $ref: "#/definitions/streams/delisted_companies" + - $ref: "#/definitions/streams/ipo_calendar" + - $ref: "#/definitions/streams/historical_stock_split " + - $ref: "#/definitions/streams/historical_dividends_calendar" + - $ref: "#/definitions/streams/cash_flow_statements" + - $ref: "#/definitions/streams/balance_sheet_statements" + - $ref: "#/definitions/streams/income_statement" + - $ref: "#/definitions/streams/institutional_holders" + - $ref: "#/definitions/streams/mutual_fund_holder" + - $ref: "#/definitions/streams/most_gainers" + - $ref: "#/definitions/streams/most_losers" + - $ref: "#/definitions/streams/sector_performance" + - $ref: "#/definitions/streams/shares_float" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - symbols + - start_date + properties: + api_key: + type: string + order: 0 + title: API Key + airbyte_secret: true + symbols: + type: array + description: "List of symbols " + order: 1 + title: Symbols + tech_indicator_type: + type: string + description: "One of DEMA, EMA, SMA, WMA, RSI, TEMA, Williams, ADX " + enum: + - DEMA + - EMA + - SMA + - WMA + - RSI + - TEMA + - Williams + - ADX + order: 2 + title: Technical Indicator Type + default: SMA + time: + type: string + enum: + - daily + - 1min + - 5min + - 15min + - 30min + - 1hour + - 4hour + order: 3 + title: Time Interval + default: daily + period: + type: string + description: Time period. Default is 10 + order: 4 + title: Period + time_aggregates: + type: string + description: Size of the time + enum: + - minute + - hour + - day + - week + - month + - quarter + - year + order: 5 + title: Time aggregates + default: day + time_period: + type: string + description: Time Period for cash flow stmts + enum: + - annual + - quarter + order: 6 + title: Time Period + start_date: + type: string + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + order: 7 + additionalProperties: true + +metadata: + autoImportSchema: + market_news: true + most_active_us_stocks: true + technical_indicators: true + economic_calendar: true + earning_calendar: true + delisted_companies: true + ipo_calendar: true + "historical_stock_split ": true + historical_dividends_calendar: true + cash_flow_statements: true + balance_sheet_statements: true + income_statement: true + institutional_holders: true + mutual_fund_holder: true + most_gainers: true + most_losers: true + sector_performance: true + shares_float: true + testedStreams: + market_news: + streamHash: b9df19e00609045ae619227beaec3d97e618abda + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + most_active_us_stocks: + streamHash: 253c2a15c310fad7cde7a88e1b671727cfebd4eb + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + technical_indicators: + streamHash: 22317d22acc5f76d6ed9449e3b92e87b8998ffbc + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + economic_calendar: + streamHash: 3fc796767238a27e9f297da1d40db3d209a4df76 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + earning_calendar: + streamHash: 78b4604379752654184349eb4b2c2c30ceead9a0 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + delisted_companies: + streamHash: 772290fcafdeadecbcbcb48928e1aec7a43afbcb + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + ipo_calendar: + streamHash: 62238b9dd37f0b8b4bc6d709b666ca9d085b8eb7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + "historical_stock_split ": + streamHash: 6fe8da58cfec43c7a641b63d5b560c1e872f3c8e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + historical_dividends_calendar: + hasRecords: true + streamHash: 4f0cc4391de713ccb1c4c86ce9867da216ee74d4 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + cash_flow_statements: + streamHash: 385c49dd6bf317922c439f2f1a668842f1d80ea4 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + balance_sheet_statements: + streamHash: 8df9996cca665fb3192d26bc911346698da61180 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + income_statement: + streamHash: 1a4e198146a571747d18f9748ae0415ddab3bc18 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + institutional_holders: + streamHash: 3ac75f617932a8567f483910f344b9d407d937ba + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + mutual_fund_holder: + streamHash: 21ec06e8a926a92e4887f674d3f7000968bf020c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + most_gainers: + streamHash: b8466e76f06b4e5f974ecc99059e16a13f927fc4 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + most_losers: + hasRecords: true + streamHash: 6080fd432659e5ce8034a9ba27ccb3606768023f + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + sector_performance: + hasRecords: true + streamHash: 4c0c6e98044910ffc67b4cb4b098fd2c2b9f8ca1 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + shares_float: + hasRecords: true + streamHash: 4696d9314ea9a7809521519a1deae6c30a57c21a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: {} + +schemas: + market_news: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + date: + type: + - string + - "null" + source: + type: + - string + - "null" + title: + type: + - string + - "null" + url: + type: + - string + - "null" + most_active_us_stocks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Datetime: + type: + - string + - "null" + change: + type: + - number + - "null" + change_percentage: + type: + - string + - "null" + company_name: + type: + - string + - "null" + price: + type: + - string + - "null" + symbol: + type: string + required: + - symbol + technical_indicators: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + close: + type: + - string + - "null" + date: + type: + - string + - "null" + high: + type: + - string + - "null" + low: + type: + - string + - "null" + open: + type: + - string + - "null" + symbol: + type: + - string + - "null" + value: + type: + - string + - "null" + volume: + type: + - string + - "null" + economic_calendar: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + actual: + type: + - number + - "null" + change: + type: + - number + - "null" + changePercentage: + type: + - number + - "null" + country: + type: + - string + - "null" + countryFlag: + type: + - string + - "null" + date: + type: string + estimate: + type: + - number + - "null" + event: + type: + - string + - "null" + previous: + type: + - number + - "null" + required: + - date + earning_calendar: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + date: + type: + - string + - "null" + eps: + type: + - number + - "null" + estimated_eps: + type: + - number + - "null" + estimated_revenue: + type: + - number + - "null" + revenue: + type: + - number + - "null" + symbol: + type: + - string + - "null" + time: + type: + - string + - "null" + delisted_companies: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + company_name: + type: + - string + - "null" + delisted_date: + type: + - string + - "null" + exchange: + type: + - string + - "null" + ipo_date: + type: + - string + - "null" + symbol: + type: string + required: + - symbol + ipo_calendar: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + company: + type: + - string + - "null" + date: + type: string + exchange: + type: + - string + - "null" + market_cap: + type: + - number + - "null" + price_range: + type: + - string + - "null" + shares: + type: + - number + - "null" + status: + type: + - string + - "null" + symbol: + type: string + required: + - symbol + - date + "historical_stock_split ": + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + date: + type: + - string + - "null" + denominator_factor: + type: + - number + - "null" + label: + type: + - string + - "null" + numerator_factor: + type: + - number + - "null" + historical_dividends_calendar: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + adj_dividend: + type: + - number + - "null" + date: + type: + - string + - "null" + declaration_date: + type: + - string + - "null" + dividend: + type: + - number + - "null" + label: + type: + - string + - "null" + payment_date: + type: + - string + - "null" + record_date: + type: + - string + - "null" + cash_flow_statements: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + acceptedDate: + type: + - string + - "null" + accountsPayables: + type: + - number + - "null" + accountsReceivables: + type: + - number + - "null" + acquisitionsNet: + type: + - number + - "null" + capitalExpenditure: + type: + - number + - "null" + cashAtBeginningOfPeriod: + type: + - number + - "null" + cashAtEndOfPeriod: + type: + - number + - "null" + changeInWorkingCapital: + type: + - number + - "null" + commonStockIssued: + type: + - number + - "null" + commonStockRepurchased: + type: + - number + - "null" + date: + type: string + debtRepayment: + type: + - number + - "null" + deferredIncomeTax: + type: + - number + - "null" + depreciationAndAmortization: + type: + - number + - "null" + dividendsPaid: + type: + - number + - "null" + effectOfForexChangesOnCash: + type: + - number + - "null" + fillingDate: + type: + - string + - "null" + finalLink: + type: + - string + - "null" + freeCashFlow: + type: + - number + - "null" + inventory: + type: + - number + - "null" + investmentsInPropertyPlantAndEquipment: + type: + - number + - "null" + link: + type: + - string + - "null" + netCashProvidedByOperatingActivities: + type: + - number + - "null" + netCashUsedForInvestingActivites: + type: + - number + - "null" + netCashUsedProvidedByFinancingActivities: + type: + - number + - "null" + netChangeInCash: + type: + - number + - "null" + netIncome: + type: + - number + - "null" + operatingCashFlow: + type: + - number + - "null" + otherFinancingActivites: + type: + - number + - "null" + otherInvestingActivites: + type: + - number + - "null" + otherNonCashItems: + type: + - number + - "null" + otherWorkingCapital: + type: + - number + - "null" + period: + type: + - string + - "null" + purchasesOfInvestments: + type: + - number + - "null" + salesMaturitiesOfInvestments: + type: + - number + - "null" + stockBasedCompensation: + type: + - number + - "null" + symbol: + type: string + required: + - date + - symbol + balance_sheet_statements: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + acceptedDate: + type: + - string + - "null" + accountPayables: + type: + - number + - "null" + accumulatedOtherComprehensiveIncomeLoss: + type: + - number + - "null" + cashAndCashEquivalents: + type: + - number + - "null" + cashAndShortTermInvestments: + type: + - number + - "null" + commonStock: + type: + - number + - "null" + date: + type: string + deferredRevenue: + type: + - number + - "null" + deferredRevenueNonCurrent: + type: + - number + - "null" + deferredTaxLiabilitiesNonCurrent: + type: + - number + - "null" + fillingDate: + type: + - string + - "null" + finalLink: + type: + - string + - "null" + goodwill: + type: + - number + - "null" + goodwillAndIntangibleAssets: + type: + - number + - "null" + intangibleAssets: + type: + - number + - "null" + inventory: + type: + - number + - "null" + link: + type: + - string + - "null" + longTermDebt: + type: + - number + - "null" + longTermInvestments: + type: + - number + - "null" + netDebt: + type: + - number + - "null" + netReceivables: + type: + - number + - "null" + otherAssets: + type: + - number + - "null" + otherCurrentAssets: + type: + - number + - "null" + otherCurrentLiabilities: + type: + - number + - "null" + otherNonCurrentAssets: + type: + - number + - "null" + otherNonCurrentLiabilities: + type: + - number + - "null" + othertotalStockholdersEquity: + type: + - number + - "null" + period: + type: + - string + - "null" + propertyPlantEquipmentNet: + type: + - number + - "null" + retainedEarnings: + type: + - number + - "null" + shortTermDebt: + type: + - number + - "null" + shortTermInvestments: + type: + - number + - "null" + symbol: + type: string + taxAssets: + type: + - number + - "null" + taxPayables: + type: + - number + - "null" + totalAssets: + type: + - number + - "null" + totalCurrentAssets: + type: + - number + - "null" + totalCurrentLiabilities: + type: + - number + - "null" + totalDebt: + type: + - number + - "null" + totalInvestments: + type: + - number + - "null" + totalLiabilities: + type: + - number + - "null" + totalLiabilitiesAndStockholdersEquity: + type: + - number + - "null" + totalNonCurrentAssets: + type: + - number + - "null" + totalNonCurrentLiabilities: + type: + - number + - "null" + totalStockholdersEquity: + type: + - number + - "null" + required: + - date + - symbol + income_statement: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + acceptedDate: + type: + - string + - "null" + costAndExpenses: + type: + - number + - "null" + costOfRevenue: + type: + - number + - "null" + date: + type: string + depreciationAndAmortization: + type: + - number + - "null" + ebitda: + type: + - number + - "null" + ebitdaRatio: + type: + - number + - "null" + eps: + type: + - number + - "null" + epsDiluted: + type: + - number + - "null" + fillingDate: + type: + - string + - "null" + finalLink: + type: + - string + - "null" + generalAndAdministrativeExpenses: + type: + - number + - "null" + grossProfit: + type: + - number + - "null" + grossProfitRatio: + type: + - number + - "null" + incomeBeforeTax: + type: + - number + - "null" + incomeBeforeTaxRatio: + type: + - number + - "null" + incomeTaxExpense: + type: + - number + - "null" + interestExpense: + type: + - number + - "null" + link: + type: + - string + - "null" + netIncome: + type: + - number + - "null" + netIncomeRatio: + type: + - number + - "null" + operatingExpenses: + type: + - number + - "null" + operatingIncome: + type: + - number + - "null" + operatingIncomeRatio: + type: + - number + - "null" + otherExpenses: + type: + - number + - "null" + period: + type: + - string + - "null" + researchAndDevelopmentExpenses: + type: + - number + - "null" + revenue: + type: + - number + - "null" + sellingAndMarketingExpenses: + type: + - number + - "null" + symbol: + type: string + totalOtherIncomeExpensesNet: + type: + - number + - "null" + weightedAverageShsOut: + type: + - number + - "null" + weightedAverageShsOutDil: + type: + - number + - "null" + required: + - date + - symbol + institutional_holders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + change: + type: + - number + - "null" + holder: + type: string + report_date: + type: + - string + - "null" + shares: + type: + - number + - "null" + required: + - holder + mutual_fund_holder: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + change: + type: + - number + - "null" + holder: + type: + - string + - "null" + report_date: + type: + - string + - "null" + shares: + type: + - number + - "null" + weight_percentage: + type: + - string + - "null" + most_gainers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + change: + type: + - string + - "null" + change_percentage: + type: + - string + - "null" + company_name: + type: + - string + - "null" + price: + type: + - string + - "null" + symbol: + type: string + required: + - symbol + most_losers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + change: + type: + - string + - "null" + change_percentage: + type: + - string + - "null" + company_name: + type: + - string + - "null" + price: + type: + - string + - "null" + symbol: + type: string + required: + - symbol + sector_performance: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + change_percentage: + type: + - string + - "null" + sector: + type: string + required: + - sector + shares_float: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + date: + type: + - string + - "null" + outstanding_shares: + type: + - number + - "null" + public_float: + type: + - number + - "null" + stock_float: + type: + - number + - "null" + symbol: + type: + - string + - "null" diff --git a/airbyte-integrations/connectors/source-finage/metadata.yaml b/airbyte-integrations/connectors/source-finage/metadata.yaml new file mode 100644 index 000000000000..665e194c10bf --- /dev/null +++ b/airbyte-integrations/connectors/source-finage/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.finage.co.uk" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-finage + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 5220663f-d87b-498e-8aed-1f2d59371a61 + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-finage + githubIssueLabel: source-finage + icon: icon.svg + license: MIT + name: Finage + releaseDate: 2024-11-09 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/finage + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-financial-modelling/README.md b/airbyte-integrations/connectors/source-financial-modelling/README.md new file mode 100644 index 000000000000..8fc4d04a4152 --- /dev/null +++ b/airbyte-integrations/connectors/source-financial-modelling/README.md @@ -0,0 +1,35 @@ +# Financial Modelling +This directory contains the manifest-only connector for `source-financial-modelling`. + +FMP provides financial data. +Using this connector we can extract data from various endpoints like Stocks list, ETFs list , Exchange Symbols and Historical MarketCap etc +Docs : https://site.financialmodelingprep.com/developer/docs + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-financial-modelling:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-financial-modelling build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-financial-modelling test +``` + diff --git a/airbyte-integrations/connectors/source-financial-modelling/acceptance-test-config.yml b/airbyte-integrations/connectors/source-financial-modelling/acceptance-test-config.yml new file mode 100644 index 000000000000..8d11a787ae22 --- /dev/null +++ b/airbyte-integrations/connectors/source-financial-modelling/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-financial-modelling:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-financial-modelling/icon.svg b/airbyte-integrations/connectors/source-financial-modelling/icon.svg new file mode 100644 index 000000000000..d2a2d8a9caa8 --- /dev/null +++ b/airbyte-integrations/connectors/source-financial-modelling/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-financial-modelling/manifest.yaml b/airbyte-integrations/connectors/source-financial-modelling/manifest.yaml new file mode 100644 index 000000000000..a47f08df6f1a --- /dev/null +++ b/airbyte-integrations/connectors/source-financial-modelling/manifest.yaml @@ -0,0 +1,1358 @@ +version: 5.14.0 + +type: DeclarativeSource + +description: >- + FMP provides financial data. + + Using this connector we can extract data from various endpoints like Stocks + list, ETFs list , Exchange Symbols and Historical MarketCap etc + + Docs : https://site.financialmodelingprep.com/developer/docs + +check: + type: CheckStream + stream_names: + - stocks + +definitions: + streams: + stocks: + type: DeclarativeStream + name: stocks + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: stock/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stocks" + etfs: + type: DeclarativeStream + name: etfs + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: etf/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/etfs" + stock_available_traded: + type: DeclarativeStream + name: stock_available_traded + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: available-traded/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stock_available_traded" + stock_cik_list: + type: DeclarativeStream + name: stock_cik_list + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: cik_list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stock_cik_list" + stock_euronext_symbols: + type: DeclarativeStream + name: stock_euronext_symbols + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: symbol/available-euronext + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stock_euronext_symbols" + stock_exchange_symbols: + type: DeclarativeStream + name: stock_exchange_symbols + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: symbol/{{ config['exchange'] }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stock_exchange_symbols" + stock_available_indexes: + type: DeclarativeStream + name: stock_available_indexes + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: symbol/available-indexes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stock_available_indexes" + company_profile: + type: DeclarativeStream + name: company_profile + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: profile/{{ stream_partition.symbol}} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: symbol + partition_field: symbol + stream: + $ref: "#/definitions/streams/stock_exchange_symbols" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/company_profile" + stock_screener: + type: DeclarativeStream + name: stock_screener + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: stock-screener + http_method: GET + request_parameters: + marketCapMoreThan: "{{ config['marketcapmorethan'] }}" + marketCapLowerThan: "{{ config['marketcaplowerthan'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stock_screener" + historical_market_cap: + type: DeclarativeStream + name: historical_market_cap + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: historical-market-capitalization/{{ stream_partition.symbol}} + http_method: GET + request_parameters: + limit: "500" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: symbol + partition_field: symbol + stream: + $ref: "#/definitions/streams/stock_exchange_symbols" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: date + cursor_datetime_formats: + - "%Y-%m-%d" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: from + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: to + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/historical_market_cap" + delisted_companies: + type: DeclarativeStream + name: delisted_companies + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: delisted-companies + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/delisted_companies" + exchange_prices: + type: DeclarativeStream + name: exchange_prices + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: stock-price-change/{{ stream_partition.symbol}} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: symbol + partition_field: symbol + stream: + $ref: "#/definitions/streams/stock_exchange_symbols" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/exchange_prices" + all_realtime_stock_prices: + type: DeclarativeStream + name: all_realtime_stock_prices + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: stock/full/real-time-price + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/all_realtime_stock_prices" + all_fx_prices: + type: DeclarativeStream + name: all_fx_prices + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: fx + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/all_fx_prices" + stock_historical_price: + type: DeclarativeStream + name: stock_historical_price + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + historical-chart/{{ config['time_frame'] }}/{{ + stream_partition.symbol}} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: symbol + partition_field: symbol + stream: + $ref: "#/definitions/streams/stock_exchange_symbols" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: date + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%d %H:%M:%S" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: from + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: to + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stock_historical_price" + forex_list: + type: DeclarativeStream + name: forex_list + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: symbol/available-forex-currency-pairs + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/forex_list" + cryptocurrencies_list: + type: DeclarativeStream + name: cryptocurrencies_list + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: symbol/available-cryptocurrencies + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/cryptocurrencies_list" + base_requester: + type: HttpRequester + url_base: https://financialmodelingprep.com/api/v3/ + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: apikey + inject_into: request_parameter + +streams: + - $ref: "#/definitions/streams/stocks" + - $ref: "#/definitions/streams/etfs" + - $ref: "#/definitions/streams/stock_available_traded" + - $ref: "#/definitions/streams/stock_cik_list" + - $ref: "#/definitions/streams/stock_euronext_symbols" + - $ref: "#/definitions/streams/stock_exchange_symbols" + - $ref: "#/definitions/streams/stock_available_indexes" + - $ref: "#/definitions/streams/company_profile" + - $ref: "#/definitions/streams/stock_screener" + - $ref: "#/definitions/streams/historical_market_cap" + - $ref: "#/definitions/streams/delisted_companies" + - $ref: "#/definitions/streams/exchange_prices" + - $ref: "#/definitions/streams/all_realtime_stock_prices" + - $ref: "#/definitions/streams/all_fx_prices" + - $ref: "#/definitions/streams/stock_historical_price" + - $ref: "#/definitions/streams/forex_list" + - $ref: "#/definitions/streams/cryptocurrencies_list" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - start_date + properties: + api_key: + type: string + order: 0 + title: API Key + airbyte_secret: true + exchange: + type: string + description: >- + The stock exchange : AMEX, AMS, AQS, ASX, ATH, BER, BME, BRU, BSE, + BUD, BUE, BVC, CAI, CBOE, CNQ, CPH, DFM, DOH, DUS, DXE, EGX, EURONEXT, + HAM, HEL, HKSE, ICE, IOB, IST, JKT, JNB, JPX, KLS, KOE, KSC, KUW, LSE, + MCX, MEX, MIL, MUN, NASDAQ, NEO, NSE, NYSE, NZE, OEM, OQX, OSL, OTC, + PNK, PRA, RIS, SAO, SAU, SES, SET, SGO, SHH, SHZ, SIX, STO, STU, TAI, + TLV, TSX, TSXV, TWO, VIE, VSE, WSE, XETRA + order: 1 + title: Exchange + default: NASDAQ + marketcapmorethan: + type: string + description: >- + Used in screener to filter out stocks with a market cap more than the + give marketcap + order: 2 + title: Market Cap More Than + marketcaplowerthan: + type: string + description: >- + Used in screener to filter out stocks with a market cap lower than the + give marketcap + order: 3 + title: Market Cap Lower Than + time_frame: + type: string + description: For example 1min, 5min, 15min, 30min, 1hour, 4hour + order: 4 + title: Time Frame + default: 4hour + enum: + - 1min + - 5min + - 15min + - 30min + - 1hour + - 4hour + start_date: + type: string + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + order: 5 + additionalProperties: true + +metadata: + autoImportSchema: + stocks: true + etfs: true + stock_available_traded: true + stock_cik_list: true + stock_euronext_symbols: true + stock_exchange_symbols: true + stock_available_indexes: true + company_profile: true + stock_screener: true + historical_market_cap: true + delisted_companies: true + exchange_prices: true + all_realtime_stock_prices: true + all_fx_prices: true + stock_historical_price: true + forex_list: true + cryptocurrencies_list: true + testedStreams: + stocks: + streamHash: 3cd737fdc10d93f8ad402f1781e4eb2a950bc448 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + etfs: + streamHash: 673db891b91ef5e11d7654988deca5b9a84126c1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + stock_available_traded: + streamHash: b7a0c8bf3655b170d6abd23b084c892e530a1eda + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + stock_cik_list: + streamHash: b96ddd9895c89cd2c2172b4e0c6edd3451d8cee2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + stock_euronext_symbols: + streamHash: 97ecd8911004c1f18f5f27a725cb82966bfadc08 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + stock_exchange_symbols: + streamHash: 530a5008ec34b27f4ed2369bd12d008a0a8f072b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + stock_available_indexes: + streamHash: 1b924b9c1aca45e1f5549477e35ab46c97119d25 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + company_profile: + streamHash: ca5f0a46e2125e9c19bf1b4864708dfef2410159 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + stock_screener: + streamHash: 195eabf9d812e08642831553194a031a68afea78 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + historical_market_cap: + streamHash: 3ae2520b60408749857f78c32660dc58365bcf99 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + delisted_companies: + streamHash: 04a19a5fe538f784395c7cae746e1e3b8e9abaad + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + exchange_prices: + streamHash: 5fb72a0ee2b701570641f692e8949861867f77f5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + all_realtime_stock_prices: + streamHash: 4bcca1e1e7d9d89eb4c0e9176b0e63088434cd0a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + all_fx_prices: + streamHash: c44a516cc4eabd4a8a53ae88903f6c9b66e6a41a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + stock_historical_price: + streamHash: 56225db87b1856894c6ef2001bcab9caf4dac374 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + forex_list: + hasRecords: true + streamHash: f50787ec42b2f4cdec2297da114c99b830a5115a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + cryptocurrencies_list: + hasRecords: true + streamHash: 1db6a40be5714e012f2cd25bb59eea41fa1cd361 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: {} + +schemas: + stocks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + exchange: + type: + - string + - "null" + exchangeShortName: + type: + - string + - "null" + name: + type: + - string + - "null" + price: + type: + - number + - "null" + symbol: + type: + - string + - "null" + etfs: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + exchange: + type: + - string + - "null" + exchangeShortName: + type: + - string + - "null" + name: + type: + - string + - "null" + price: + type: + - number + - "null" + symbol: + type: + - string + - "null" + stock_available_traded: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + exchange: + type: + - string + - "null" + exchangeShortName: + type: + - string + - "null" + name: + type: + - string + - "null" + price: + type: + - number + - "null" + symbol: + type: + - string + - "null" + stock_cik_list: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + cik: + type: + - string + - "null" + name: + type: + - string + - "null" + stock_euronext_symbols: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + currency: + type: + - string + - "null" + exchangeShortName: + type: + - string + - "null" + name: + type: + - string + - "null" + stockExchange: + type: + - string + - "null" + symbol: + type: + - string + - "null" + stock_exchange_symbols: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + avgVolume: + type: + - number + - "null" + change: + type: + - number + - "null" + changesPercentage: + type: + - number + - "null" + dayHigh: + type: + - number + - "null" + dayLow: + type: + - number + - "null" + earningsAnnouncement: + type: + - string + - "null" + eps: + type: + - number + - "null" + exchange: + type: + - string + - "null" + marketCap: + type: + - number + - "null" + name: + type: + - string + - "null" + open: + type: + - number + - "null" + pe: + type: + - number + - "null" + previousClose: + type: + - number + - "null" + price: + type: + - number + - "null" + priceAvg200: + type: + - number + - "null" + priceAvg50: + type: + - number + - "null" + sharesOutstanding: + type: + - number + - "null" + symbol: + type: + - string + - "null" + timestamp: + type: + - number + - "null" + volume: + type: + - number + - "null" + yearHigh: + type: + - number + - "null" + yearLow: + type: + - number + - "null" + stock_available_indexes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + currency: + type: + - string + - "null" + exchangeShortName: + type: + - string + - "null" + name: + type: + - string + - "null" + stockExchange: + type: + - string + - "null" + symbol: + type: + - string + - "null" + company_profile: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + address: + type: + - string + - "null" + beta: + type: + - number + - "null" + ceo: + type: + - string + - "null" + changes: + type: + - number + - "null" + cik: + type: + - string + - "null" + city: + type: + - string + - "null" + companyName: + type: + - string + - "null" + country: + type: + - string + - "null" + currency: + type: + - string + - "null" + cusip: + type: + - string + - "null" + dcf: + type: + - number + - "null" + dcfDiff: + type: + - number + - "null" + defaultImage: + type: + - boolean + - "null" + exchange: + type: + - string + - "null" + exchangeShortName: + type: + - string + - "null" + fullTimeEmployees: + type: + - string + - "null" + image: + type: + - string + - "null" + industry: + type: + - string + - "null" + ipoDate: + type: + - string + - "null" + isActivelyTrading: + type: + - boolean + - "null" + isAdr: + type: + - boolean + - "null" + isEtf: + type: + - boolean + - "null" + isFund: + type: + - boolean + - "null" + isin: + type: + - string + - "null" + lastDiv: + type: + - number + - "null" + mktCap: + type: + - number + - "null" + phone: + type: + - string + - "null" + price: + type: + - number + - "null" + range: + type: + - string + - "null" + sector: + type: + - string + - "null" + state: + type: + - string + - "null" + symbol: + type: + - string + - "null" + volAvg: + type: + - number + - "null" + website: + type: + - string + - "null" + zip: + type: + - string + - "null" + stock_screener: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + beta: + type: + - number + - "null" + companyName: + type: + - string + - "null" + country: + type: + - string + - "null" + exchange: + type: + - string + - "null" + exchangeShortName: + type: + - string + - "null" + industry: + type: + - string + - "null" + isActivelyTrading: + type: + - boolean + - "null" + isEtf: + type: + - boolean + - "null" + isFund: + type: + - boolean + - "null" + lastAnnualDividend: + type: + - number + - "null" + marketCap: + type: + - number + - "null" + price: + type: + - number + - "null" + sector: + type: + - string + - "null" + symbol: + type: + - string + - "null" + volume: + type: + - number + - "null" + historical_market_cap: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + date: + type: string + marketCap: + type: + - number + - "null" + symbol: + type: + - string + - "null" + required: + - date + delisted_companies: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + companyName: + type: + - string + - "null" + delistedDate: + type: + - string + - "null" + exchange: + type: + - string + - "null" + ipoDate: + type: + - string + - "null" + symbol: + type: + - string + - "null" + exchange_prices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + 10Y: + type: + - number + - "null" + 1D: + type: + - number + - "null" + 1M: + type: + - number + - "null" + 1Y: + type: + - number + - "null" + 3M: + type: + - number + - "null" + 3Y: + type: + - number + - "null" + 5D: + type: + - number + - "null" + 5Y: + type: + - number + - "null" + 6M: + type: + - number + - "null" + max: + type: + - number + - "null" + symbol: + type: + - string + - "null" + ytd: + type: + - number + - "null" + all_realtime_stock_prices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + askPrice: + type: + - number + - "null" + askSize: + type: + - number + - "null" + bidPrice: + type: + - number + - "null" + bidSize: + type: + - number + - "null" + fmpLast: + type: + - number + - "null" + lastSalePrice: + type: + - number + - "null" + lastSaleSize: + type: + - number + - "null" + lastSaleTime: + type: + - number + - "null" + lastUpdated: + type: + - number + - "null" + symbol: + type: + - string + - "null" + volume: + type: + - number + - "null" + all_fx_prices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + ask: + type: + - string + - "null" + bid: + type: + - string + - "null" + changes: + type: + - number + - "null" + date: + type: + - string + - "null" + high: + type: + - string + - "null" + low: + type: + - string + - "null" + open: + type: + - string + - "null" + ticker: + type: + - string + - "null" + stock_historical_price: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + close: + type: + - number + - "null" + date: + type: string + high: + type: + - number + - "null" + low: + type: + - number + - "null" + open: + type: + - number + - "null" + volume: + type: + - number + - "null" + required: + - date + forex_list: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + currency: + type: + - string + - "null" + exchangeShortName: + type: + - string + - "null" + name: + type: + - string + - "null" + stockExchange: + type: + - string + - "null" + symbol: + type: + - string + - "null" + cryptocurrencies_list: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + currency: + type: + - string + - "null" + exchangeShortName: + type: + - string + - "null" + name: + type: + - string + - "null" + stockExchange: + type: + - string + - "null" + symbol: + type: + - string + - "null" diff --git a/airbyte-integrations/connectors/source-financial-modelling/metadata.yaml b/airbyte-integrations/connectors/source-financial-modelling/metadata.yaml new file mode 100644 index 000000000000..6f21ce6885e7 --- /dev/null +++ b/airbyte-integrations/connectors/source-financial-modelling/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "financialmodelingprep.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-financial-modelling + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 4c3d6bdd-dc0e-4a66-b48a-2e7956195eec + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-financial-modelling + githubIssueLabel: source-financial-modelling + icon: icon.svg + license: MIT + name: Financial Modelling + releaseDate: 2024-10-22 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/financial-modelling + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-finnhub/README.md b/airbyte-integrations/connectors/source-finnhub/README.md new file mode 100644 index 000000000000..bb95fee010c1 --- /dev/null +++ b/airbyte-integrations/connectors/source-finnhub/README.md @@ -0,0 +1,33 @@ +# Finnhub +This directory contains the manifest-only connector for `source-finnhub`. + +Finnhub is a financial data platform that provides real-time stock market, forex, and cryptocurrency data, along with extensive fundamental data, economic indicators, and alternative data for global markets. With its powerful API, Finnhub delivers actionable insights, enabling developers, financial institutions, and traders to integrate market intelligence into their applications, build trading algorithms, and track investment performance. It supports a wide range of financial metrics, including earnings reports, company profiles, and news, making it a comprehensive solution for financial analysis and market research + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-finnhub:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-finnhub build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-finnhub test +``` + diff --git a/airbyte-integrations/connectors/source-finnhub/acceptance-test-config.yml b/airbyte-integrations/connectors/source-finnhub/acceptance-test-config.yml new file mode 100644 index 000000000000..cab576f482a1 --- /dev/null +++ b/airbyte-integrations/connectors/source-finnhub/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-finnhub:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-finnhub/icon.svg b/airbyte-integrations/connectors/source-finnhub/icon.svg new file mode 100644 index 000000000000..1201a237d741 --- /dev/null +++ b/airbyte-integrations/connectors/source-finnhub/icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/airbyte-integrations/connectors/source-finnhub/manifest.yaml b/airbyte-integrations/connectors/source-finnhub/manifest.yaml new file mode 100644 index 000000000000..fd5ce52390d8 --- /dev/null +++ b/airbyte-integrations/connectors/source-finnhub/manifest.yaml @@ -0,0 +1,992 @@ +version: 5.16.0 + +type: DeclarativeSource + +description: >- + Finnhub is a financial data platform that provides real-time stock market, + forex, and cryptocurrency data, along with extensive fundamental data, + economic indicators, and alternative data for global markets. With its + powerful API, Finnhub delivers actionable insights, enabling developers, + financial institutions, and traders to integrate market intelligence into + their applications, build trading algorithms, and track investment + performance. It supports a wide range of financial metrics, including earnings + reports, company profiles, and news, making it a comprehensive solution for + financial analysis and market research +check: + type: CheckStream + stream_names: + - marketnews + +definitions: + streams: + marketnews: + type: DeclarativeStream + name: marketnews + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /news?category={{config['market_new_category']}} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/marketnews" + stock_symbols: + type: DeclarativeStream + name: stock_symbols + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /stock/symbol?exchange={{ config['exchange'] }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stock_symbols" + basic_financial_report: + type: DeclarativeStream + name: basic_financial_report + primary_key: + - accessNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /stock/financials-reported + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: ListPartitionRouter + values: "{{ config.symbols }}" + cursor_field: symbol + request_option: + type: RequestOption + inject_into: request_parameter + field_name: symbol + incremental_sync: + type: DatetimeBasedCursor + cursor_field: startDate + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%d %H:%M:%S" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date_2\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: from + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: to + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/basic_financial_report" + company_profile: + type: DeclarativeStream + name: company_profile + primary_key: + - ticker + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /stock/profile2 + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: ListPartitionRouter + values: "{{ config.symbols }}" + cursor_field: symbol + request_option: + type: RequestOption + inject_into: request_parameter + field_name: symbol + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/company_profile" + sec_filings: + type: DeclarativeStream + name: sec_filings + primary_key: + - accessNumber + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /stock/filings + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: ListPartitionRouter + values: "{{ config.symbols }}" + cursor_field: symbol + request_option: + type: RequestOption + inject_into: request_parameter + field_name: symbol + incremental_sync: + type: DatetimeBasedCursor + cursor_field: filedDate + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%d %H:%M:%S" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date_2\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: from + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: to + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sec_filings" + insider_transactions: + type: DeclarativeStream + name: insider_transactions + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /stock/insider-transactions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: ListPartitionRouter + values: "{{ config.symbols }}" + cursor_field: symbol + request_option: + type: RequestOption + inject_into: request_parameter + field_name: symbol + incremental_sync: + type: DatetimeBasedCursor + cursor_field: transactionDate + cursor_datetime_formats: + - "%Y-%m-%d" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date_2\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: from + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: to + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/insider_transactions" + insider_sentiment: + type: DeclarativeStream + name: insider_sentiment + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /stock/insider-sentiment + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: ListPartitionRouter + values: "{{ config.symbols }}" + cursor_field: symbol + request_option: + type: RequestOption + inject_into: request_parameter + field_name: symbol + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/insider_sentiment" + company_news: + type: DeclarativeStream + name: company_news + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /company-news + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: ListPartitionRouter + values: "{{ config.symbols }}" + cursor_field: symbol + request_option: + type: RequestOption + inject_into: request_parameter + field_name: symbol + incremental_sync: + type: DatetimeBasedCursor + cursor_field: datetime + cursor_datetime_formats: + - "%s" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date_2\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: from + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: to + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/company_news" + stock_recommendations: + type: DeclarativeStream + name: stock_recommendations + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /stock/recommendation + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: ListPartitionRouter + values: "{{ config.symbols }}" + cursor_field: symbol + request_option: + type: RequestOption + inject_into: request_parameter + field_name: symbol + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stock_recommendations" + earnings_surprises: + type: DeclarativeStream + name: earnings_surprises + primary_key: + - symbol + - period + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /stock/earnings + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: ListPartitionRouter + values: "{{ config.symbols }}" + cursor_field: symbol + request_option: + type: RequestOption + inject_into: request_parameter + field_name: symbol + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/earnings_surprises" + stock_quote: + type: DeclarativeStream + name: stock_quote + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /quote + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: ListPartitionRouter + values: "{{ config.symbols }}" + cursor_field: symbol + request_option: + type: RequestOption + inject_into: request_parameter + field_name: symbol + transformations: + - type: AddFields + fields: + - path: + - symbol + value: "{{ stream_partition.symbol }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stock_quote" + base_requester: + type: HttpRequester + url_base: https://finnhub.io/api/v1 + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: token + inject_into: request_parameter + +streams: + - $ref: "#/definitions/streams/marketnews" + - $ref: "#/definitions/streams/stock_symbols" + - $ref: "#/definitions/streams/basic_financial_report" + - $ref: "#/definitions/streams/company_profile" + - $ref: "#/definitions/streams/sec_filings" + - $ref: "#/definitions/streams/insider_transactions" + - $ref: "#/definitions/streams/insider_sentiment" + - $ref: "#/definitions/streams/company_news" + - $ref: "#/definitions/streams/stock_recommendations" + - $ref: "#/definitions/streams/earnings_surprises" + - $ref: "#/definitions/streams/stock_quote" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - symbols + - market_news_category + - exchange + - start_date_2 + properties: + api_key: + type: string + description: The API key to use for authentication + name: api_key + order: 0 + title: API Key + airbyte_secret: true + symbols: + type: array + name: company_symbol + order: 1 + title: Companies + market_news_category: + type: string + description: >- + This parameter can be 1 of the following values general, forex, + crypto, merger. + title: Market News Category + default: general + enum: + - general + - forex + - crypto + - merger + order: 2 + exchange: + type: string + description: "More info: https://finnhub.io/docs/api/stock-symbols" + title: Exchange + default: US + order: 3 + start_date_2: + type: string + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + order: 4 + additionalProperties: true + +metadata: + autoImportSchema: + marketnews: true + stock_symbols: true + basic_financial_report: false + company_profile: true + sec_filings: true + insider_transactions: false + insider_sentiment: false + company_news: true + stock_recommendations: false + earnings_surprises: false + stock_quote: true + testedStreams: + marketnews: + streamHash: f1c6821d2ad17da19c15be9a29b964c95fc72b3d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + stock_symbols: + streamHash: a481b061b2ebb223a5e94e71275cf121b53ae457 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + basic_financial_report: + streamHash: 7fb2565f8171add436ff06128d2bddc65f39948f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + company_profile: + streamHash: 093d488e2794fae4274cc8beed808b021cdd30b7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + sec_filings: + streamHash: 5ccfc67778f56038004767e0c879fe9699ba8909 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + insider_transactions: + streamHash: d3e80f2b01eb399e15aaa95c0a645aa795eb4737 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + insider_sentiment: + streamHash: 68f53090b913d3c23afe895d102f2009a19d45a5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + company_news: + streamHash: 28d15b6953fe6b944ec6bef610f6c69a6aac2c84 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + stock_recommendations: + streamHash: 190cf9650126e66328ec0ebac0f9a324c91fd346 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + earnings_surprises: + streamHash: b89237a3ccb7a1991700822a1cb3c784e6b525bf + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + stock_quote: + streamHash: 59936a915d2fdab55efa6613756c64504578ccf1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://finnhub.io/docs/api/ + +schemas: + marketnews: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + category: + type: + - string + - "null" + datetime: + type: + - number + - "null" + headline: + type: + - string + - "null" + id: + type: number + image: + type: + - string + - "null" + related: + type: + - string + - "null" + source: + type: + - string + - "null" + summary: + type: + - string + - "null" + url: + type: + - string + - "null" + required: + - id + stock_symbols: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + currency: + type: + - string + - "null" + displaySymbol: + type: + - string + - "null" + figi: + type: + - string + - "null" + mic: + type: + - string + - "null" + shareClassFIGI: + type: + - string + - "null" + symbol: + type: + - string + - "null" + symbol2: + type: + - string + - "null" + basic_financial_report: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} + company_profile: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + country: + type: + - string + - "null" + currency: + type: + - string + - "null" + estimateCurrency: + type: + - string + - "null" + exchange: + type: + - string + - "null" + finnhubIndustry: + type: + - string + - "null" + ipo: + type: + - string + - "null" + logo: + type: + - string + - "null" + marketCapitalization: + type: + - number + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + shareOutstanding: + type: + - number + - "null" + ticker: + type: string + weburl: + type: + - string + - "null" + required: + - ticker + sec_filings: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + acceptedDate: + type: + - string + - "null" + accessNumber: + type: string + cik: + type: + - string + - "null" + filedDate: + type: string + filingUrl: + type: + - string + - "null" + form: + type: + - string + - "null" + reportUrl: + type: + - string + - "null" + symbol: + type: + - string + - "null" + required: + - accessNumber + - filedDate + insider_transactions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + change: + type: + - number + - "null" + currency: + type: + - string + - "null" + filingDate: + type: + - string + - "null" + id: + type: string + isDerivative: + type: + - boolean + - "null" + name: + type: + - string + - "null" + share: + type: + - number + - "null" + source: + type: + - string + - "null" + symbol: + type: + - string + - "null" + transactionCode: + type: + - string + - "null" + transactionDate: + type: + - string + - "null" + transactionPrice: + type: + - number + - "null" + required: + - id + insider_sentiment: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + data: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + change: + type: + - number + - "null" + month: + type: + - number + - "null" + mspr: + type: + - number + - "null" + symbol: + type: + - string + - "null" + year: + type: + - number + - "null" + symbol: + type: + - string + - "null" + company_news: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + category: + type: + - string + - "null" + datetime: + type: number + headline: + type: + - string + - "null" + id: + type: + - number + - "null" + image: + type: + - string + - "null" + related: + type: + - string + - "null" + source: + type: + - string + - "null" + summary: + type: + - string + - "null" + url: + type: + - string + - "null" + required: + - datetime + stock_recommendations: + type: object + $schema: http://json-schema.org/schema# + properties: + buy: + type: + - number + - "null" + hold: + type: + - number + - "null" + period: + type: + - string + - "null" + sell: + type: + - number + - "null" + strongBuy: + type: + - number + - "null" + strongSell: + type: + - number + - "null" + symbol: + type: + - string + - "null" + additionalProperties: true + earnings_surprises: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + actual: + type: + - number + - "null" + estimate: + type: + - number + - "null" + period: + type: + - string + - "null" + quarter: + type: + - number + - "null" + surprise: + type: + - number + - "null" + surprisePercent: + type: + - number + - "null" + symbol: + type: + - string + - "null" + year: + type: + - number + - "null" + stock_quote: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + c: + type: + - number + - "null" + d: + type: + - number + - "null" + dp: + type: + - number + - "null" + h: + type: + - number + - "null" + l: + type: + - number + - "null" + o: + type: + - number + - "null" + pc: + type: + - number + - "null" + symbol: + type: + - string + - "null" + t: + type: + - number + - "null" diff --git a/airbyte-integrations/connectors/source-finnhub/metadata.yaml b/airbyte-integrations/connectors/source-finnhub/metadata.yaml new file mode 100644 index 000000000000..cc9faface762 --- /dev/null +++ b/airbyte-integrations/connectors/source-finnhub/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "finnhub.io" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-finnhub + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: ec96d68b-e32c-4f0a-ba28-0b01f176a3bb + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-finnhub + githubIssueLabel: source-finnhub + icon: icon.svg + license: MIT + name: Finnhub + releaseDate: 2024-10-24 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/finnhub + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-finnworlds/README.md b/airbyte-integrations/connectors/source-finnworlds/README.md new file mode 100644 index 000000000000..4bac958eb83a --- /dev/null +++ b/airbyte-integrations/connectors/source-finnworlds/README.md @@ -0,0 +1,35 @@ +# Finnworlds +This directory contains the manifest-only connector for `source-finnworlds`. + +Finnworlds provides data related to finance for globally traded instruments. +With this connector we can easily fetch data from various streams such as Dividends , Stock Splits , Candle Sticks etc +Docs : https://finnworlds.com/ + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-finnworlds:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-finnworlds build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-finnworlds test +``` + diff --git a/airbyte-integrations/connectors/source-finnworlds/acceptance-test-config.yml b/airbyte-integrations/connectors/source-finnworlds/acceptance-test-config.yml new file mode 100644 index 000000000000..35d5cc97045a --- /dev/null +++ b/airbyte-integrations/connectors/source-finnworlds/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-finnworlds:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-finnworlds/icon.svg b/airbyte-integrations/connectors/source-finnworlds/icon.svg new file mode 100644 index 000000000000..ba3d14f1aa51 --- /dev/null +++ b/airbyte-integrations/connectors/source-finnworlds/icon.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-finnworlds/manifest.yaml b/airbyte-integrations/connectors/source-finnworlds/manifest.yaml new file mode 100644 index 000000000000..95ad14d7881d --- /dev/null +++ b/airbyte-integrations/connectors/source-finnworlds/manifest.yaml @@ -0,0 +1,750 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + Finnworlds provides data related to finance for globally traded instruments. + + With this connector we can easily fetch data from various streams such as + Dividends , Stock Splits , Candle Sticks etc + + Docs : https://finnworlds.com/ + +check: + type: CheckStream + stream_names: + - bonds + +definitions: + streams: + bonds: + type: DeclarativeStream + name: bonds + primary_key: + - country + - datetime + - type + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: bonds + http_method: GET + request_parameters: + key: "{{ config[\"key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - result + - output + partition_router: + - type: ListPartitionRouter + values: "{{ config.countries }}" + cursor_field: country + request_option: + type: RequestOption + field_name: country + inject_into: request_parameter + - type: ListPartitionRouter + values: "{{ config.bond_type }}" + cursor_field: bond_type + request_option: + type: RequestOption + field_name: type + inject_into: request_parameter + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/bonds" + dividends: + type: DeclarativeStream + name: dividends + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: dividends + http_method: GET + request_parameters: + key: "{{ config[\"key\"] }}" + date_to: "{{ today_utc() }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - result + - output + - dividends + partition_router: + type: ListPartitionRouter + values: "{{ config.tickers }}" + cursor_field: ticket + request_option: + type: RequestOption + field_name: ticker + inject_into: request_parameter + transformations: + - type: AddFields + fields: + - path: + - ticker + value: "{{ stream_slice.ticker }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/dividends" + stock_splits: + type: DeclarativeStream + name: stock_splits + primary_key: + - ticker + - date + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: stocksplits + http_method: GET + request_parameters: + key: "{{ config[\"key\"] }}" + date_to: "{{ today_utc() }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - result + - output + - stocksplits + partition_router: + type: ListPartitionRouter + values: "{{ config.tickers }}" + cursor_field: ticker + request_option: + type: RequestOption + field_name: ticker + inject_into: request_parameter + transformations: + - type: AddFields + fields: + - path: + - ticker + value: "{{ stream_partition.ticker }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stock_splits" + historical_candlestick: + type: DeclarativeStream + name: historical_candlestick + primary_key: + - ticker + - date + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: historicalcandlestick + http_method: GET + request_parameters: + key: "{{ config[\"key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - result + - output + - daily_stock_data + partition_router: + type: ListPartitionRouter + values: "{{ config.tickers }}" + cursor_field: ticker + request_option: + type: RequestOption + field_name: ticker + inject_into: request_parameter + incremental_sync: + type: DatetimeBasedCursor + cursor_field: date + cursor_datetime_formats: + - "%Y-%m-%d" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: date_from + inject_into: request_parameter + transformations: + - type: AddFields + fields: + - path: + - ticker + value: "{{ stream_partition.ticker }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/historical_candlestick" + macro_calendar: + type: DeclarativeStream + name: macro_calendar + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: macrocalendar + http_method: GET + request_parameters: + key: "{{ config[\"key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - result + - output + partition_router: + type: ListPartitionRouter + values: "{{ config.countries }}" + cursor_field: country + request_option: + type: RequestOption + field_name: country + inject_into: request_parameter + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/macro_calendar" + macro_indicator: + type: DeclarativeStream + name: macro_indicator + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: macroindicator + http_method: GET + request_parameters: + key: "{{ config[\"key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - result + - output + partition_router: + type: ListPartitionRouter + values: "{{ config.countries }}" + cursor_field: country + request_option: + type: RequestOption + field_name: country + inject_into: request_parameter + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/macro_indicator" + commodities: + type: DeclarativeStream + name: commodities + primary_key: + - commodity_name + - datetime + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: commodities + http_method: GET + request_parameters: + key: "{{ config[\"key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - result + - output + partition_router: + type: ListPartitionRouter + values: "{{ config.commodities }}" + cursor_field: commodity + request_option: + type: RequestOption + inject_into: request_parameter + field_name: commodity_name + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/commodities" + benchmark: + type: DeclarativeStream + name: benchmark + primary_key: + - datetime + - country + - benchmark + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: benchmark + http_method: GET + request_parameters: + key: "{{ config[\"key\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - result + - output + partition_router: + type: ListPartitionRouter + values: "{{ config.countries }}" + cursor_field: country + request_option: + type: RequestOption + inject_into: request_parameter + field_name: country + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/benchmark" + base_requester: + type: HttpRequester + url_base: https://api.finnworlds.com/api/v1/ + +streams: + - $ref: "#/definitions/streams/bonds" + - $ref: "#/definitions/streams/dividends" + - $ref: "#/definitions/streams/stock_splits" + - $ref: "#/definitions/streams/historical_candlestick" + - $ref: "#/definitions/streams/macro_calendar" + - $ref: "#/definitions/streams/macro_indicator" + - $ref: "#/definitions/streams/commodities" + - $ref: "#/definitions/streams/benchmark" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - key + - start_date + properties: + list: + type: string + description: Choose isin, ticker, reg_lei or cik + order: 0 + title: List + default: ticker + list_countries_for_bonds: + type: string + order: 1 + title: List Countries for Bonds + default: country + key: + type: string + order: 2 + title: API Key + airbyte_secret: true + bond_type: + type: array + description: For example 10y, 5y, 2y... + order: 3 + title: Bond Type + countries: + type: array + description: brazil, united states, italia, japan + order: 4 + title: Countries + tickers: + type: array + description: AAPL, T, MU, GOOG + order: 5 + title: Tickers + start_date: + type: string + order: 6 + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + commodities: + type: array + description: "Options Available: beef, cheese, oil, ..." + order: 7 + title: Commodities + additionalProperties: true + +metadata: + autoImportSchema: + bonds: true + dividends: true + stock_splits: true + historical_candlestick: true + macro_calendar: true + macro_indicator: true + commodities: true + benchmark: true + testedStreams: + bonds: + hasRecords: true + streamHash: 357fb7f57462d774ece7c5085554061f1bc6e85b + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + dividends: + hasRecords: true + streamHash: 63c321ce2ead5cff97454e92149a19eefe6c7b22 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + stock_splits: + hasRecords: true + streamHash: 9c28d289b17af092b5aa56759d9adfea41053062 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + historical_candlestick: + hasRecords: true + streamHash: 567dbe7aa3bc15925ee48637b04598e48b1e1a8b + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + macro_calendar: + hasRecords: true + streamHash: de60019c0a1af68baa501b2908385b6ff0869177 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + macro_indicator: + hasRecords: true + streamHash: 95831425814dd02b44730007faf85c625f61cc0b + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + commodities: + streamHash: 95fbe6ac1ba1337b323c02b6e43cc9d3982b4ee2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + benchmark: + streamHash: a990d23f5f72c745c9f1ba74c358e91e397ef1fb + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + bonds: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: string + country: + type: string + datetime: + type: string + percentage_month: + type: + - string + - "null" + percentage_week: + type: + - string + - "null" + percentage_year: + type: + - string + - "null" + price_change_day: + type: + - string + - "null" + region: + type: + - string + - "null" + yield: + type: + - string + - "null" + required: + - country + - datetime + - type + dividends: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + date: + type: + - string + - "null" + dividend_rate: + type: + - string + - "null" + ticker: + type: + - string + - "null" + stock_splits: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + date: + type: string + stock_split: + type: + - string + - "null" + ticker: + type: string + required: + - ticker + - date + historical_candlestick: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + adjusted_close: + type: + - string + - "null" + close: + type: + - string + - "null" + closetime: + type: + - number + - "null" + date: + type: string + dividend_rate: + type: + - string + - "null" + high: + type: + - string + - "null" + low: + type: + - string + - "null" + open: + type: + - string + - "null" + opentime: + type: + - number + - "null" + stock_split: + type: + - string + - "null" + ticker: + type: string + trade_volume: + type: + - string + - "null" + required: + - ticker + - date + macro_calendar: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + actual: + type: + - string + - "null" + consensus: + type: + - string + - "null" + country: + type: + - string + - "null" + datetime: + type: + - string + - "null" + impact: + type: + - string + - "null" + iso_country_code: + type: + - string + - "null" + previous: + type: + - string + - "null" + report_date: + type: + - string + - "null" + report_name: + type: + - string + - "null" + unit: + type: + - string + - "null" + macro_indicator: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + actual: + type: + - string + - "null" + previous: + type: + - string + - "null" + report_date: + type: + - string + - "null" + report_name: + type: + - string + - "null" + unit: + type: + - string + - "null" + commodities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + commodity_name: + type: string + commodity_price: + type: + - string + - "null" + commodity_unit: + type: + - string + - "null" + datetime: + type: string + percentage_day: + type: + - string + - "null" + percentage_month: + type: + - string + - "null" + percentage_week: + type: + - string + - "null" + percentage_year: + type: + - string + - "null" + price_change_day: + type: + - string + - "null" + quarter1_25: + type: + - string + - "null" + quarter2_25: + type: + - string + - "null" + quarter3_25: + type: + - string + - "null" + quarter4_24: + type: + - string + - "null" + required: + - commodity_name + - datetime + benchmark: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + benchmark: + type: string + country: + type: string + datetime: + type: string + percentage_day: + type: + - string + - "null" + percentage_month: + type: + - string + - "null" + percentage_week: + type: + - string + - "null" + percentage_year: + type: + - string + - "null" + price: + type: + - string + - "null" + price_change_day: + type: + - string + - "null" + region: + type: + - string + - "null" + required: + - datetime + - country + - benchmark diff --git a/airbyte-integrations/connectors/source-finnworlds/metadata.yaml b/airbyte-integrations/connectors/source-finnworlds/metadata.yaml new file mode 100644 index 000000000000..91087b1f73a4 --- /dev/null +++ b/airbyte-integrations/connectors/source-finnworlds/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.finnworlds.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-finnworlds + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: b8a9a60f-7178-468a-a333-23b431e355b7 + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-finnworlds + githubIssueLabel: source-finnworlds + icon: icon.svg + license: MIT + name: Finnworlds + releaseDate: 2024-10-25 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/finnworlds + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-firebase-realtime-database/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-firebase-realtime-database/integration_tests/acceptance.py index 50bba3cdce94..b7498c7869f7 100644 --- a/airbyte-integrations/connectors/source-firebase-realtime-database/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-firebase-realtime-database/integration_tests/acceptance.py @@ -10,6 +10,7 @@ import docker import pytest + pytest_plugins = ("source_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-firebase-realtime-database/main.py b/airbyte-integrations/connectors/source-firebase-realtime-database/main.py index 708648fa8c15..58586ddc6928 100644 --- a/airbyte-integrations/connectors/source-firebase-realtime-database/main.py +++ b/airbyte-integrations/connectors/source-firebase-realtime-database/main.py @@ -4,5 +4,6 @@ from source_firebase_realtime_database.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-firebase-realtime-database/metadata.yaml b/airbyte-integrations/connectors/source-firebase-realtime-database/metadata.yaml index 2b993a4b4588..d79670bcf73e 100644 --- a/airbyte-integrations/connectors/source-firebase-realtime-database/metadata.yaml +++ b/airbyte-integrations/connectors/source-firebase-realtime-database/metadata.yaml @@ -5,7 +5,7 @@ data: connectorSubtype: database connectorType: source definitionId: acb5f973-a565-441e-992f-4946f3e65662 - dockerImageTag: 0.1.25 + dockerImageTag: 0.1.31 dockerRepository: airbyte/source-firebase-realtime-database githubIssueLabel: source-firebase-realtime-database license: MIT @@ -31,5 +31,5 @@ data: connectorTestSuitesOptions: - suite: unitTests connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-firebase-realtime-database/poetry.lock b/airbyte-integrations/connectors/source-firebase-realtime-database/poetry.lock index 7840074e4a0a..362b2436769f 100644 --- a/airbyte-integrations/connectors/source-firebase-realtime-database/poetry.lock +++ b/airbyte-integrations/connectors/source-firebase-realtime-database/poetry.lock @@ -42,13 +42,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] @@ -56,24 +56,24 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.0" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.0-py3-none-any.whl", hash = "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a"}, - {file = "anyio-4.6.0.tar.gz", hash = "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -88,19 +88,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -129,13 +129,13 @@ files = [ [[package]] name = "cachecontrol" -version = "0.14.0" +version = "0.14.1" description = "httplib2 caching for requests" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "cachecontrol-0.14.0-py3-none-any.whl", hash = "sha256:f5bf3f0620c38db2e5122c0726bdebb0d16869de966ea6a2befe92470b740ea0"}, - {file = "cachecontrol-0.14.0.tar.gz", hash = "sha256:7db1195b41c81f8274a7bbd97c956f44e8348265a1bc7641c37dfebc39f0c938"}, + {file = "cachecontrol-0.14.1-py3-none-any.whl", hash = "sha256:65e3abd62b06382ce3894df60dde9e0deb92aeb734724f68fa4f3b91e97206b9"}, + {file = "cachecontrol-0.14.1.tar.gz", hash = "sha256:06ef916a1e4eb7dba9948cdfc9c76e749db2e02104a9a1277e8b642591a0f717"}, ] [package.dependencies] @@ -143,7 +143,7 @@ msgpack = ">=0.5.2,<2.0.0" requests = ">=2.16.0" [package.extras] -dev = ["CacheControl[filecache,redis]", "black", "build", "cherrypy", "furo", "mypy", "pytest", "pytest-cov", "sphinx", "sphinx-copybutton", "tox", "types-redis", "types-requests"] +dev = ["CacheControl[filecache,redis]", "build", "cherrypy", "codespell[tomli]", "furo", "mypy", "pytest", "pytest-cov", "ruff", "sphinx", "sphinx-copybutton", "tox", "types-redis", "types-requests"] filecache = ["filelock (>=3.8.0)"] redis = ["redis (>=2.10.5)"] @@ -186,13 +186,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -276,116 +276,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -455,20 +442,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -526,13 +513,13 @@ files = [ [[package]] name = "google-api-core" -version = "2.21.0" +version = "2.24.0" description = "Google API client core library" optional = false python-versions = ">=3.7" files = [ - {file = "google_api_core-2.21.0-py3-none-any.whl", hash = "sha256:6869eacb2a37720380ba5898312af79a4d30b8bca1548fb4093e0697dc4bdf5d"}, - {file = "google_api_core-2.21.0.tar.gz", hash = "sha256:4a152fd11a9f774ea606388d423b68aa7e6d6a0ffe4c8266f74979613ec09f81"}, + {file = "google_api_core-2.24.0-py3-none-any.whl", hash = "sha256:10d82ac0fca69c82a25b3efdeefccf6f28e02ebb97925a8cce8edbfe379929d9"}, + {file = "google_api_core-2.24.0.tar.gz", hash = "sha256:e255640547a597a4da010876d333208ddac417d60add22b6851a0c66a831fcaf"}, ] [package.dependencies] @@ -558,13 +545,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] [[package]] name = "google-api-python-client" -version = "2.149.0" +version = "2.157.0" description = "Google API Client Library for Python" optional = false python-versions = ">=3.7" files = [ - {file = "google_api_python_client-2.149.0-py2.py3-none-any.whl", hash = "sha256:1a5232e9cfed8c201799d9327e4d44dc7ea7daa3c6e1627fca41aa201539c0da"}, - {file = "google_api_python_client-2.149.0.tar.gz", hash = "sha256:b9d68c6b14ec72580d66001bd33c5816b78e2134b93ccc5cf8f624516b561750"}, + {file = "google_api_python_client-2.157.0-py2.py3-none-any.whl", hash = "sha256:0b0231db106324c659bf8b85f390391c00da57a60ebc4271e33def7aac198c75"}, + {file = "google_api_python_client-2.157.0.tar.gz", hash = "sha256:2ee342d0967ad1cedec43ccd7699671d94bff151e1f06833ea81303f9a6d86fd"}, ] [package.dependencies] @@ -576,13 +563,13 @@ uritemplate = ">=3.0.1,<5" [[package]] name = "google-auth" -version = "2.35.0" +version = "2.37.0" description = "Google Authentication Library" optional = false python-versions = ">=3.7" files = [ - {file = "google_auth-2.35.0-py2.py3-none-any.whl", hash = "sha256:25df55f327ef021de8be50bad0dfd4a916ad0de96da86cd05661c9297723ad3f"}, - {file = "google_auth-2.35.0.tar.gz", hash = "sha256:f4c64ed4e01e8e8b646ef34c018f8bf3338df0c8e37d8b3bba40e7f574a3278a"}, + {file = "google_auth-2.37.0-py2.py3-none-any.whl", hash = "sha256:42664f18290a6be591be5329a96fe30184be1a1badb7292a7f686a9659de9ca0"}, + {file = "google_auth-2.37.0.tar.gz", hash = "sha256:0054623abf1f9c83492c63d3f47e77f0a544caa3d40b2d98e099a611c2dd5d00"}, ] [package.dependencies] @@ -593,6 +580,7 @@ rsa = ">=3.1.4,<5" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0.dev0)", "requests (>=2.20.0,<3.0.0.dev0)"] enterprise-cert = ["cryptography", "pyopenssl"] +pyjwt = ["cryptography (>=38.0.3)", "pyjwt (>=2.0)"] pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0.dev0)"] @@ -653,13 +641,13 @@ protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4 [[package]] name = "google-cloud-storage" -version = "2.18.2" +version = "2.19.0" description = "Google Cloud Storage API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google_cloud_storage-2.18.2-py2.py3-none-any.whl", hash = "sha256:97a4d45c368b7d401ed48c4fdfe86e1e1cb96401c9e199e419d289e2c0370166"}, - {file = "google_cloud_storage-2.18.2.tar.gz", hash = "sha256:aaf7acd70cdad9f274d29332673fcab98708d0e1f4dceb5a5356aaef06af4d99"}, + {file = "google_cloud_storage-2.19.0-py2.py3-none-any.whl", hash = "sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba"}, + {file = "google_cloud_storage-2.19.0.tar.gz", hash = "sha256:cd05e9e7191ba6cb68934d8eb76054d9be4562aa89dbc4236feee4d7d51342b2"}, ] [package.dependencies] @@ -733,13 +721,13 @@ requests = ["requests (>=2.18.0,<3.0.0dev)"] [[package]] name = "googleapis-common-protos" -version = "1.65.0" +version = "1.66.0" description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" files = [ - {file = "googleapis_common_protos-1.65.0-py2.py3-none-any.whl", hash = "sha256:2972e6c496f435b92590fd54045060867f3fe9be2c82ab148fc8885035479a63"}, - {file = "googleapis_common_protos-1.65.0.tar.gz", hash = "sha256:334a29d07cddc3aa01dee4988f9afd9b2916ee2ff49d6b757155dc0d197852c0"}, + {file = "googleapis_common_protos-1.66.0-py2.py3-none-any.whl", hash = "sha256:d7abcd75fabb2e0ec9f74466401f6c119a0b498e27370e9be4c94cb7e382b8ed"}, + {file = "googleapis_common_protos-1.66.0.tar.gz", hash = "sha256:c3e7b33d15fdca5374cc0a7346dd92ffa847425cc4ea941d970f13680052ec8c"}, ] [package.dependencies] @@ -750,85 +738,85 @@ grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] [[package]] name = "grpcio" -version = "1.66.2" +version = "1.68.1" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.8" files = [ - {file = "grpcio-1.66.2-cp310-cp310-linux_armv7l.whl", hash = "sha256:fe96281713168a3270878255983d2cb1a97e034325c8c2c25169a69289d3ecfa"}, - {file = "grpcio-1.66.2-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:73fc8f8b9b5c4a03e802b3cd0c18b2b06b410d3c1dcbef989fdeb943bd44aff7"}, - {file = "grpcio-1.66.2-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:03b0b307ba26fae695e067b94cbb014e27390f8bc5ac7a3a39b7723fed085604"}, - {file = "grpcio-1.66.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d69ce1f324dc2d71e40c9261d3fdbe7d4c9d60f332069ff9b2a4d8a257c7b2b"}, - {file = "grpcio-1.66.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05bc2ceadc2529ab0b227b1310d249d95d9001cd106aa4d31e8871ad3c428d73"}, - {file = "grpcio-1.66.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8ac475e8da31484efa25abb774674d837b343afb78bb3bcdef10f81a93e3d6bf"}, - {file = "grpcio-1.66.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0be4e0490c28da5377283861bed2941d1d20ec017ca397a5df4394d1c31a9b50"}, - {file = "grpcio-1.66.2-cp310-cp310-win32.whl", hash = "sha256:4e504572433f4e72b12394977679161d495c4c9581ba34a88d843eaf0f2fbd39"}, - {file = "grpcio-1.66.2-cp310-cp310-win_amd64.whl", hash = "sha256:2018b053aa15782db2541ca01a7edb56a0bf18c77efed975392583725974b249"}, - {file = "grpcio-1.66.2-cp311-cp311-linux_armv7l.whl", hash = "sha256:2335c58560a9e92ac58ff2bc5649952f9b37d0735608242973c7a8b94a6437d8"}, - {file = "grpcio-1.66.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:45a3d462826f4868b442a6b8fdbe8b87b45eb4f5b5308168c156b21eca43f61c"}, - {file = "grpcio-1.66.2-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:a9539f01cb04950fd4b5ab458e64a15f84c2acc273670072abe49a3f29bbad54"}, - {file = "grpcio-1.66.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce89f5876662f146d4c1f695dda29d4433a5d01c8681fbd2539afff535da14d4"}, - {file = "grpcio-1.66.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d25a14af966438cddf498b2e338f88d1c9706f3493b1d73b93f695c99c5f0e2a"}, - {file = "grpcio-1.66.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6001e575b8bbd89eee11960bb640b6da6ae110cf08113a075f1e2051cc596cae"}, - {file = "grpcio-1.66.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4ea1d062c9230278793820146c95d038dc0f468cbdd172eec3363e42ff1c7d01"}, - {file = "grpcio-1.66.2-cp311-cp311-win32.whl", hash = "sha256:38b68498ff579a3b1ee8f93a05eb48dc2595795f2f62716e797dc24774c1aaa8"}, - {file = "grpcio-1.66.2-cp311-cp311-win_amd64.whl", hash = "sha256:6851de821249340bdb100df5eacfecfc4e6075fa85c6df7ee0eb213170ec8e5d"}, - {file = "grpcio-1.66.2-cp312-cp312-linux_armv7l.whl", hash = "sha256:802d84fd3d50614170649853d121baaaa305de7b65b3e01759247e768d691ddf"}, - {file = "grpcio-1.66.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:80fd702ba7e432994df208f27514280b4b5c6843e12a48759c9255679ad38db8"}, - {file = "grpcio-1.66.2-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:12fda97ffae55e6526825daf25ad0fa37483685952b5d0f910d6405c87e3adb6"}, - {file = "grpcio-1.66.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:950da58d7d80abd0ea68757769c9db0a95b31163e53e5bb60438d263f4bed7b7"}, - {file = "grpcio-1.66.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e636ce23273683b00410f1971d209bf3689238cf5538d960adc3cdfe80dd0dbd"}, - {file = "grpcio-1.66.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a917d26e0fe980b0ac7bfcc1a3c4ad6a9a4612c911d33efb55ed7833c749b0ee"}, - {file = "grpcio-1.66.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:49f0ca7ae850f59f828a723a9064cadbed90f1ece179d375966546499b8a2c9c"}, - {file = "grpcio-1.66.2-cp312-cp312-win32.whl", hash = "sha256:31fd163105464797a72d901a06472860845ac157389e10f12631025b3e4d0453"}, - {file = "grpcio-1.66.2-cp312-cp312-win_amd64.whl", hash = "sha256:ff1f7882e56c40b0d33c4922c15dfa30612f05fb785074a012f7cda74d1c3679"}, - {file = "grpcio-1.66.2-cp313-cp313-linux_armv7l.whl", hash = "sha256:3b00efc473b20d8bf83e0e1ae661b98951ca56111feb9b9611df8efc4fe5d55d"}, - {file = "grpcio-1.66.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1caa38fb22a8578ab8393da99d4b8641e3a80abc8fd52646f1ecc92bcb8dee34"}, - {file = "grpcio-1.66.2-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:c408f5ef75cfffa113cacd8b0c0e3611cbfd47701ca3cdc090594109b9fcbaed"}, - {file = "grpcio-1.66.2-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c806852deaedee9ce8280fe98955c9103f62912a5b2d5ee7e3eaa284a6d8d8e7"}, - {file = "grpcio-1.66.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f145cc21836c332c67baa6fc81099d1d27e266401565bf481948010d6ea32d46"}, - {file = "grpcio-1.66.2-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:73e3b425c1e155730273f73e419de3074aa5c5e936771ee0e4af0814631fb30a"}, - {file = "grpcio-1.66.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:9c509a4f78114cbc5f0740eb3d7a74985fd2eff022971bc9bc31f8bc93e66a3b"}, - {file = "grpcio-1.66.2-cp313-cp313-win32.whl", hash = "sha256:20657d6b8cfed7db5e11b62ff7dfe2e12064ea78e93f1434d61888834bc86d75"}, - {file = "grpcio-1.66.2-cp313-cp313-win_amd64.whl", hash = "sha256:fb70487c95786e345af5e854ffec8cb8cc781bcc5df7930c4fbb7feaa72e1cdf"}, - {file = "grpcio-1.66.2-cp38-cp38-linux_armv7l.whl", hash = "sha256:a18e20d8321c6400185b4263e27982488cb5cdd62da69147087a76a24ef4e7e3"}, - {file = "grpcio-1.66.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:02697eb4a5cbe5a9639f57323b4c37bcb3ab2d48cec5da3dc2f13334d72790dd"}, - {file = "grpcio-1.66.2-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:99a641995a6bc4287a6315989ee591ff58507aa1cbe4c2e70d88411c4dcc0839"}, - {file = "grpcio-1.66.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ed71e81782966ffead60268bbda31ea3f725ebf8aa73634d5dda44f2cf3fb9c"}, - {file = "grpcio-1.66.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbd27c24a4cc5e195a7f56cfd9312e366d5d61b86e36d46bbe538457ea6eb8dd"}, - {file = "grpcio-1.66.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d9a9724a156c8ec6a379869b23ba3323b7ea3600851c91489b871e375f710bc8"}, - {file = "grpcio-1.66.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d8d4732cc5052e92cea2f78b233c2e2a52998ac40cd651f40e398893ad0d06ec"}, - {file = "grpcio-1.66.2-cp38-cp38-win32.whl", hash = "sha256:7b2c86457145ce14c38e5bf6bdc19ef88e66c5fee2c3d83285c5aef026ba93b3"}, - {file = "grpcio-1.66.2-cp38-cp38-win_amd64.whl", hash = "sha256:e88264caad6d8d00e7913996030bac8ad5f26b7411495848cc218bd3a9040b6c"}, - {file = "grpcio-1.66.2-cp39-cp39-linux_armv7l.whl", hash = "sha256:c400ba5675b67025c8a9f48aa846f12a39cf0c44df5cd060e23fda5b30e9359d"}, - {file = "grpcio-1.66.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:66a0cd8ba6512b401d7ed46bb03f4ee455839957f28b8d61e7708056a806ba6a"}, - {file = "grpcio-1.66.2-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:06de8ec0bd71be123eec15b0e0d457474931c2c407869b6c349bd9bed4adbac3"}, - {file = "grpcio-1.66.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb57870449dfcfac428afbb5a877829fcb0d6db9d9baa1148705739e9083880e"}, - {file = "grpcio-1.66.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b672abf90a964bfde2d0ecbce30f2329a47498ba75ce6f4da35a2f4532b7acbc"}, - {file = "grpcio-1.66.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ad2efdbe90c73b0434cbe64ed372e12414ad03c06262279b104a029d1889d13e"}, - {file = "grpcio-1.66.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9c3a99c519f4638e700e9e3f83952e27e2ea10873eecd7935823dab0c1c9250e"}, - {file = "grpcio-1.66.2-cp39-cp39-win32.whl", hash = "sha256:78fa51ebc2d9242c0fc5db0feecc57a9943303b46664ad89921f5079e2e4ada7"}, - {file = "grpcio-1.66.2-cp39-cp39-win_amd64.whl", hash = "sha256:728bdf36a186e7f51da73be7f8d09457a03061be848718d0edf000e709418987"}, - {file = "grpcio-1.66.2.tar.gz", hash = "sha256:563588c587b75c34b928bc428548e5b00ea38c46972181a4d8b75ba7e3f24231"}, + {file = "grpcio-1.68.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:d35740e3f45f60f3c37b1e6f2f4702c23867b9ce21c6410254c9c682237da68d"}, + {file = "grpcio-1.68.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:d99abcd61760ebb34bdff37e5a3ba333c5cc09feda8c1ad42547bea0416ada78"}, + {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:f8261fa2a5f679abeb2a0a93ad056d765cdca1c47745eda3f2d87f874ff4b8c9"}, + {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0feb02205a27caca128627bd1df4ee7212db051019a9afa76f4bb6a1a80ca95e"}, + {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:919d7f18f63bcad3a0f81146188e90274fde800a94e35d42ffe9eadf6a9a6330"}, + {file = "grpcio-1.68.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:963cc8d7d79b12c56008aabd8b457f400952dbea8997dd185f155e2f228db079"}, + {file = "grpcio-1.68.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ccf2ebd2de2d6661e2520dae293298a3803a98ebfc099275f113ce1f6c2a80f1"}, + {file = "grpcio-1.68.1-cp310-cp310-win32.whl", hash = "sha256:2cc1fd04af8399971bcd4f43bd98c22d01029ea2e56e69c34daf2bf8470e47f5"}, + {file = "grpcio-1.68.1-cp310-cp310-win_amd64.whl", hash = "sha256:ee2e743e51cb964b4975de572aa8fb95b633f496f9fcb5e257893df3be854746"}, + {file = "grpcio-1.68.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:55857c71641064f01ff0541a1776bfe04a59db5558e82897d35a7793e525774c"}, + {file = "grpcio-1.68.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4b177f5547f1b995826ef529d2eef89cca2f830dd8b2c99ffd5fde4da734ba73"}, + {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:3522c77d7e6606d6665ec8d50e867f13f946a4e00c7df46768f1c85089eae515"}, + {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d1fae6bbf0816415b81db1e82fb3bf56f7857273c84dcbe68cbe046e58e1ccd"}, + {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:298ee7f80e26f9483f0b6f94cc0a046caf54400a11b644713bb5b3d8eb387600"}, + {file = "grpcio-1.68.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cbb5780e2e740b6b4f2d208e90453591036ff80c02cc605fea1af8e6fc6b1bbe"}, + {file = "grpcio-1.68.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ddda1aa22495d8acd9dfbafff2866438d12faec4d024ebc2e656784d96328ad0"}, + {file = "grpcio-1.68.1-cp311-cp311-win32.whl", hash = "sha256:b33bd114fa5a83f03ec6b7b262ef9f5cac549d4126f1dc702078767b10c46ed9"}, + {file = "grpcio-1.68.1-cp311-cp311-win_amd64.whl", hash = "sha256:7f20ebec257af55694d8f993e162ddf0d36bd82d4e57f74b31c67b3c6d63d8b2"}, + {file = "grpcio-1.68.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:8829924fffb25386995a31998ccbbeaa7367223e647e0122043dfc485a87c666"}, + {file = "grpcio-1.68.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3aed6544e4d523cd6b3119b0916cef3d15ef2da51e088211e4d1eb91a6c7f4f1"}, + {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:4efac5481c696d5cb124ff1c119a78bddbfdd13fc499e3bc0ca81e95fc573684"}, + {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ab2d912ca39c51f46baf2a0d92aa265aa96b2443266fc50d234fa88bf877d8e"}, + {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c87ce2a97434dffe7327a4071839ab8e8bffd0054cc74cbe971fba98aedd60"}, + {file = "grpcio-1.68.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e4842e4872ae4ae0f5497bf60a0498fa778c192cc7a9e87877abd2814aca9475"}, + {file = "grpcio-1.68.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:255b1635b0ed81e9f91da4fcc8d43b7ea5520090b9a9ad9340d147066d1d3613"}, + {file = "grpcio-1.68.1-cp312-cp312-win32.whl", hash = "sha256:7dfc914cc31c906297b30463dde0b9be48e36939575eaf2a0a22a8096e69afe5"}, + {file = "grpcio-1.68.1-cp312-cp312-win_amd64.whl", hash = "sha256:a0c8ddabef9c8f41617f213e527254c41e8b96ea9d387c632af878d05db9229c"}, + {file = "grpcio-1.68.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:a47faedc9ea2e7a3b6569795c040aae5895a19dde0c728a48d3c5d7995fda385"}, + {file = "grpcio-1.68.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:390eee4225a661c5cd133c09f5da1ee3c84498dc265fd292a6912b65c421c78c"}, + {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:66a24f3d45c33550703f0abb8b656515b0ab777970fa275693a2f6dc8e35f1c1"}, + {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c08079b4934b0bf0a8847f42c197b1d12cba6495a3d43febd7e99ecd1cdc8d54"}, + {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8720c25cd9ac25dd04ee02b69256d0ce35bf8a0f29e20577427355272230965a"}, + {file = "grpcio-1.68.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:04cfd68bf4f38f5bb959ee2361a7546916bd9a50f78617a346b3aeb2b42e2161"}, + {file = "grpcio-1.68.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c28848761a6520c5c6071d2904a18d339a796ebe6b800adc8b3f474c5ce3c3ad"}, + {file = "grpcio-1.68.1-cp313-cp313-win32.whl", hash = "sha256:77d65165fc35cff6e954e7fd4229e05ec76102d4406d4576528d3a3635fc6172"}, + {file = "grpcio-1.68.1-cp313-cp313-win_amd64.whl", hash = "sha256:a8040f85dcb9830d8bbb033ae66d272614cec6faceee88d37a88a9bd1a7a704e"}, + {file = "grpcio-1.68.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:eeb38ff04ab6e5756a2aef6ad8d94e89bb4a51ef96e20f45c44ba190fa0bcaad"}, + {file = "grpcio-1.68.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8a3869a6661ec8f81d93f4597da50336718bde9eb13267a699ac7e0a1d6d0bea"}, + {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:2c4cec6177bf325eb6faa6bd834d2ff6aa8bb3b29012cceb4937b86f8b74323c"}, + {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12941d533f3cd45d46f202e3667be8ebf6bcb3573629c7ec12c3e211d99cfccf"}, + {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80af6f1e69c5e68a2be529990684abdd31ed6622e988bf18850075c81bb1ad6e"}, + {file = "grpcio-1.68.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e8dbe3e00771bfe3d04feed8210fc6617006d06d9a2679b74605b9fed3e8362c"}, + {file = "grpcio-1.68.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:83bbf5807dc3ee94ce1de2dfe8a356e1d74101e4b9d7aa8c720cc4818a34aded"}, + {file = "grpcio-1.68.1-cp38-cp38-win32.whl", hash = "sha256:8cb620037a2fd9eeee97b4531880e439ebfcd6d7d78f2e7dcc3726428ab5ef63"}, + {file = "grpcio-1.68.1-cp38-cp38-win_amd64.whl", hash = "sha256:52fbf85aa71263380d330f4fce9f013c0798242e31ede05fcee7fbe40ccfc20d"}, + {file = "grpcio-1.68.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:cb400138e73969eb5e0535d1d06cae6a6f7a15f2cc74add320e2130b8179211a"}, + {file = "grpcio-1.68.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a1b988b40f2fd9de5c820f3a701a43339d8dcf2cb2f1ca137e2c02671cc83ac1"}, + {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:96f473cdacfdd506008a5d7579c9f6a7ff245a9ade92c3c0265eb76cc591914f"}, + {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:37ea3be171f3cf3e7b7e412a98b77685eba9d4fd67421f4a34686a63a65d99f9"}, + {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ceb56c4285754e33bb3c2fa777d055e96e6932351a3082ce3559be47f8024f0"}, + {file = "grpcio-1.68.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:dffd29a2961f3263a16d73945b57cd44a8fd0b235740cb14056f0612329b345e"}, + {file = "grpcio-1.68.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:025f790c056815b3bf53da850dd70ebb849fd755a4b1ac822cb65cd631e37d43"}, + {file = "grpcio-1.68.1-cp39-cp39-win32.whl", hash = "sha256:1098f03dedc3b9810810568060dea4ac0822b4062f537b0f53aa015269be0a76"}, + {file = "grpcio-1.68.1-cp39-cp39-win_amd64.whl", hash = "sha256:334ab917792904245a028f10e803fcd5b6f36a7b2173a820c0b5b076555825e1"}, + {file = "grpcio-1.68.1.tar.gz", hash = "sha256:44a8502dd5de653ae6a73e2de50a401d84184f0331d0ac3daeb044e66d5c5054"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.66.2)"] +protobuf = ["grpcio-tools (>=1.68.1)"] [[package]] name = "grpcio-status" -version = "1.66.2" +version = "1.68.1" description = "Status proto mapping for gRPC" optional = false python-versions = ">=3.8" files = [ - {file = "grpcio_status-1.66.2-py3-none-any.whl", hash = "sha256:e5fe189f6897d12aa9cd74408a17ca41e44fad30871cf84f5cbd17bd713d2455"}, - {file = "grpcio_status-1.66.2.tar.gz", hash = "sha256:fb55cbb5c2e67062f7a4d5c99e489d074fb57e98678d5c3c6692a2d74d89e9ae"}, + {file = "grpcio_status-1.68.1-py3-none-any.whl", hash = "sha256:66f3d8847f665acfd56221333d66f7ad8927903d87242a482996bdb45e8d28fd"}, + {file = "grpcio_status-1.68.1.tar.gz", hash = "sha256:e1378d036c81a1610d7b4c7a146cd663dd13fcc915cf4d7d053929dba5bbb6e1"}, ] [package.dependencies] googleapis-common-protos = ">=1.5.5" -grpcio = ">=1.66.2" +grpcio = ">=1.68.1" protobuf = ">=5.26.1,<6.0dev" [[package]] @@ -844,13 +832,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -879,13 +867,13 @@ pyparsing = {version = ">=2.4.2,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.0.2 || >3.0 [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -893,7 +881,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -943,13 +930,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -1039,90 +1026,93 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.134" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.134-py3-none-any.whl", hash = "sha256:ada98ad80ef38807725f32441a472da3dd28394010877751f48f458d3289da04"}, - {file = "langsmith-0.1.134.tar.gz", hash = "sha256:23abee3b508875a0e63c602afafffc02442a19cfd88f9daae05b3e9054fd6b61"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" -version = "3.0.1" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" files = [ - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win32.whl", hash = "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win32.whl", hash = "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win32.whl", hash = "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win32.whl", hash = "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win32.whl", hash = "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b"}, - {file = "markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] @@ -1200,68 +1190,86 @@ files = [ [[package]] name = "orjson" -version = "3.10.7" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:74f4544f5a6405b90da8ea724d15ac9c36da4d72a738c64685003337401f5c12"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34a566f22c28222b08875b18b0dfbf8a947e69df21a9ed5c51a6bf91cfb944ac"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf6ba8ebc8ef5792e2337fb0419f8009729335bb400ece005606336b7fd7bab7"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac7cf6222b29fbda9e3a472b41e6a5538b48f2c8f99261eecd60aafbdb60690c"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de817e2f5fc75a9e7dd350c4b0f54617b280e26d1631811a43e7e968fa71e3e9"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:348bdd16b32556cf8d7257b17cf2bdb7ab7976af4af41ebe79f9796c218f7e91"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:479fd0844ddc3ca77e0fd99644c7fe2de8e8be1efcd57705b5c92e5186e8a250"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fdf5197a21dd660cf19dfd2a3ce79574588f8f5e2dbf21bda9ee2d2b46924d84"}, - {file = "orjson-3.10.7-cp310-none-win32.whl", hash = "sha256:d374d36726746c81a49f3ff8daa2898dccab6596864ebe43d50733275c629175"}, - {file = "orjson-3.10.7-cp310-none-win_amd64.whl", hash = "sha256:cb61938aec8b0ffb6eef484d480188a1777e67b05d58e41b435c74b9d84e0b9c"}, - {file = "orjson-3.10.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0"}, - {file = "orjson-3.10.7-cp311-none-win32.whl", hash = "sha256:82763b46053727a7168d29c772ed5c870fdae2f61aa8a25994c7984a19b1021f"}, - {file = "orjson-3.10.7-cp311-none-win_amd64.whl", hash = "sha256:eb8d384a24778abf29afb8e41d68fdd9a156cf6e5390c04cc07bbc24b89e98b5"}, - {file = "orjson-3.10.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44a96f2d4c3af51bfac6bc4ef7b182aa33f2f054fd7f34cc0ee9a320d051d41f"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ac14cd57df0572453543f8f2575e2d01ae9e790c21f57627803f5e79b0d3c3"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bdbb61dcc365dd9be94e8f7df91975edc9364d6a78c8f7adb69c1cdff318ec93"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b48b3db6bb6e0a08fa8c83b47bc169623f801e5cc4f24442ab2b6617da3b5313"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23820a1563a1d386414fef15c249040042b8e5d07b40ab3fe3efbfbbcbcb8864"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0c6a008e91d10a2564edbb6ee5069a9e66df3fbe11c9a005cb411f441fd2c09"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d352ee8ac1926d6193f602cbe36b1643bbd1bbcb25e3c1a657a4390f3000c9a5"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b"}, - {file = "orjson-3.10.7-cp312-none-win32.whl", hash = "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb"}, - {file = "orjson-3.10.7-cp312-none-win_amd64.whl", hash = "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1"}, - {file = "orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149"}, - {file = "orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad"}, - {file = "orjson-3.10.7-cp313-none-win32.whl", hash = "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2"}, - {file = "orjson-3.10.7-cp313-none-win_amd64.whl", hash = "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024"}, - {file = "orjson-3.10.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6ea2b2258eff652c82652d5e0f02bd5e0463a6a52abb78e49ac288827aaa1469"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:430ee4d85841e1483d487e7b81401785a5dfd69db5de01314538f31f8fbf7ee1"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b6146e439af4c2472c56f8540d799a67a81226e11992008cb47e1267a9b3225"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:084e537806b458911137f76097e53ce7bf5806dda33ddf6aaa66a028f8d43a23"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829cf2195838e3f93b70fd3b4292156fc5e097aac3739859ac0dcc722b27ac0"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1193b2416cbad1a769f868b1749535d5da47626ac29445803dae7cc64b3f5c98"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4e6c3da13e5a57e4b3dca2de059f243ebec705857522f188f0180ae88badd354"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c31008598424dfbe52ce8c5b47e0752dca918a4fdc4a2a32004efd9fab41d866"}, - {file = "orjson-3.10.7-cp38-none-win32.whl", hash = "sha256:7122a99831f9e7fe977dc45784d3b2edc821c172d545e6420c375e5a935f5a1c"}, - {file = "orjson-3.10.7-cp38-none-win_amd64.whl", hash = "sha256:a763bc0e58504cc803739e7df040685816145a6f3c8a589787084b54ebc9f16e"}, - {file = "orjson-3.10.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e76be12658a6fa376fcd331b1ea4e58f5a06fd0220653450f0d415b8fd0fbe20"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed350d6978d28b92939bfeb1a0570c523f6170efc3f0a0ef1f1df287cd4f4960"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144888c76f8520e39bfa121b31fd637e18d4cc2f115727865fdf9fa325b10412"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09b2d92fd95ad2402188cf51573acde57eb269eddabaa60f69ea0d733e789fe9"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b24a579123fa884f3a3caadaed7b75eb5715ee2b17ab5c66ac97d29b18fe57f"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591bcfe7512353bd609875ab38050efe3d55e18934e2f18950c108334b4ff"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f4db56635b58cd1a200b0a23744ff44206ee6aa428185e2b6c4a65b3197abdcd"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0fa5886854673222618638c6df7718ea7fe2f3f2384c452c9ccedc70b4a510a5"}, - {file = "orjson-3.10.7-cp39-none-win32.whl", hash = "sha256:8272527d08450ab16eb405f47e0f4ef0e5ff5981c3d82afe0efd25dcbef2bcd2"}, - {file = "orjson-3.10.7-cp39-none-win_amd64.whl", hash = "sha256:974683d4618c0c7dbf4f69c95a979734bf183d0658611760017f6e70a145af58"}, - {file = "orjson-3.10.7.tar.gz", hash = "sha256:75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -1342,13 +1350,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "proto-plus" -version = "1.24.0" +version = "1.25.0" description = "Beautiful, Pythonic protocol buffers." optional = false python-versions = ">=3.7" files = [ - {file = "proto-plus-1.24.0.tar.gz", hash = "sha256:30b72a5ecafe4406b0d339db35b56c4059064e69227b8c3bda7462397f966445"}, - {file = "proto_plus-1.24.0-py3-none-any.whl", hash = "sha256:402576830425e5f6ce4c2a6702400ac79897dab0b4343821aa5188b0fab81a12"}, + {file = "proto_plus-1.25.0-py3-none-any.whl", hash = "sha256:c91fc4a65074ade8e458e95ef8bac34d4008daa7cce4a12d6707066fca648961"}, + {file = "proto_plus-1.25.0.tar.gz", hash = "sha256:fbb17f57f7bd05a68b7707e745e26528b0b3c34e378db91eef93912c54982d91"}, ] [package.dependencies] @@ -1359,22 +1367,22 @@ testing = ["google-api-core (>=1.31.5)"] [[package]] name = "protobuf" -version = "5.28.2" +version = "5.29.2" description = "" optional = false python-versions = ">=3.8" files = [ - {file = "protobuf-5.28.2-cp310-abi3-win32.whl", hash = "sha256:eeea10f3dc0ac7e6b4933d32db20662902b4ab81bf28df12218aa389e9c2102d"}, - {file = "protobuf-5.28.2-cp310-abi3-win_amd64.whl", hash = "sha256:2c69461a7fcc8e24be697624c09a839976d82ae75062b11a0972e41fd2cd9132"}, - {file = "protobuf-5.28.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a8b9403fc70764b08d2f593ce44f1d2920c5077bf7d311fefec999f8c40f78b7"}, - {file = "protobuf-5.28.2-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:35cfcb15f213449af7ff6198d6eb5f739c37d7e4f1c09b5d0641babf2cc0c68f"}, - {file = "protobuf-5.28.2-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:5e8a95246d581eef20471b5d5ba010d55f66740942b95ba9b872d918c459452f"}, - {file = "protobuf-5.28.2-cp38-cp38-win32.whl", hash = "sha256:87317e9bcda04a32f2ee82089a204d3a2f0d3c8aeed16568c7daf4756e4f1fe0"}, - {file = "protobuf-5.28.2-cp38-cp38-win_amd64.whl", hash = "sha256:c0ea0123dac3399a2eeb1a1443d82b7afc9ff40241433296769f7da42d142ec3"}, - {file = "protobuf-5.28.2-cp39-cp39-win32.whl", hash = "sha256:ca53faf29896c526863366a52a8f4d88e69cd04ec9571ed6082fa117fac3ab36"}, - {file = "protobuf-5.28.2-cp39-cp39-win_amd64.whl", hash = "sha256:8ddc60bf374785fb7cb12510b267f59067fa10087325b8e1855b898a0d81d276"}, - {file = "protobuf-5.28.2-py3-none-any.whl", hash = "sha256:52235802093bd8a2811abbe8bf0ab9c5f54cca0a751fdd3f6ac2a21438bffece"}, - {file = "protobuf-5.28.2.tar.gz", hash = "sha256:59379674ff119717404f7454647913787034f03fe7049cbef1d74a97bb4593f0"}, + {file = "protobuf-5.29.2-cp310-abi3-win32.whl", hash = "sha256:c12ba8249f5624300cf51c3d0bfe5be71a60c63e4dcf51ffe9a68771d958c851"}, + {file = "protobuf-5.29.2-cp310-abi3-win_amd64.whl", hash = "sha256:842de6d9241134a973aab719ab42b008a18a90f9f07f06ba480df268f86432f9"}, + {file = "protobuf-5.29.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a0c53d78383c851bfa97eb42e3703aefdc96d2036a41482ffd55dc5f529466eb"}, + {file = "protobuf-5.29.2-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:494229ecd8c9009dd71eda5fd57528395d1eacdf307dbece6c12ad0dd09e912e"}, + {file = "protobuf-5.29.2-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:b6b0d416bbbb9d4fbf9d0561dbfc4e324fd522f61f7af0fe0f282ab67b22477e"}, + {file = "protobuf-5.29.2-cp38-cp38-win32.whl", hash = "sha256:e621a98c0201a7c8afe89d9646859859be97cb22b8bf1d8eacfd90d5bda2eb19"}, + {file = "protobuf-5.29.2-cp38-cp38-win_amd64.whl", hash = "sha256:13d6d617a2a9e0e82a88113d7191a1baa1e42c2cc6f5f1398d3b054c8e7e714a"}, + {file = "protobuf-5.29.2-cp39-cp39-win32.whl", hash = "sha256:36000f97ea1e76e8398a3f02936aac2a5d2b111aae9920ec1b769fc4a222c4d9"}, + {file = "protobuf-5.29.2-cp39-cp39-win_amd64.whl", hash = "sha256:2d2e674c58a06311c8e99e74be43e7f3a8d1e2b2fdf845eaa347fbd866f23355"}, + {file = "protobuf-5.29.2-py3-none-any.whl", hash = "sha256:fde4554c0e578a5a0bcc9a276339594848d1e89f9ea47b4427c80e5d72f90181"}, + {file = "protobuf-5.29.2.tar.gz", hash = "sha256:b2cc8e8bb7c9326996f0e160137b0861f1a82162502658df2951209d0cb0309e"}, ] [[package]] @@ -1426,54 +1434,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -1485,13 +1493,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.dependencies] @@ -1505,13 +1513,13 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] [[package]] name = "pyparsing" -version = "3.1.4" +version = "3.2.1" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false -python-versions = ">=3.6.8" +python-versions = ">=3.9" files = [ - {file = "pyparsing-3.1.4-py3-none-any.whl", hash = "sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c"}, - {file = "pyparsing-3.1.4.tar.gz", hash = "sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032"}, + {file = "pyparsing-3.2.1-py3-none-any.whl", hash = "sha256:506ff4f4386c4cec0590ec19e6302d3aedb992fdc02c761e90416f158dacf8e1"}, + {file = "pyparsing-3.2.1.tar.gz", hash = "sha256:61980854fd66de3a90028d679a954d5f2623e83144b5afe5ee86f43d762e5f0a"}, ] [package.extras] @@ -1810,33 +1818,33 @@ pyasn1 = ">=0.1.3" [[package]] name = "setuptools" -version = "75.1.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"}, - {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1914,13 +1922,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1945,81 +1953,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-firebase-realtime-database/pyproject.toml b/airbyte-integrations/connectors/source-firebase-realtime-database/pyproject.toml index 05a3bb9c5b03..6d395cb89fb2 100644 --- a/airbyte-integrations/connectors/source-firebase-realtime-database/pyproject.toml +++ b/airbyte-integrations/connectors/source-firebase-realtime-database/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.25" +version = "0.1.31" name = "source-firebase-realtime-database" description = "Source implementation for Firebase Realtime Database." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-firebase-realtime-database/unit_tests/unit_test.py b/airbyte-integrations/connectors/source-firebase-realtime-database/unit_tests/unit_test.py index a1370a44d289..4de83ba31dda 100644 --- a/airbyte-integrations/connectors/source-firebase-realtime-database/unit_tests/unit_test.py +++ b/airbyte-integrations/connectors/source-firebase-realtime-database/unit_tests/unit_test.py @@ -35,7 +35,6 @@ ], ) def test_stream_name_from(config, stream_name): - actual = SourceFirebaseRealtimeDatabase.stream_name_from(config) expected = stream_name diff --git a/airbyte-integrations/connectors/source-firebolt/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-firebolt/integration_tests/acceptance.py index 43ce950d77ca..72132012aaed 100644 --- a/airbyte-integrations/connectors/source-firebolt/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-firebolt/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-firebolt/integration_tests/integration_test.py b/airbyte-integrations/connectors/source-firebolt/integration_tests/integration_test.py index c66074e0551b..d6c185fd5de8 100644 --- a/airbyte-integrations/connectors/source-firebolt/integration_tests/integration_test.py +++ b/airbyte-integrations/connectors/source-firebolt/integration_tests/integration_test.py @@ -8,6 +8,10 @@ from typing import Dict, Generator from unittest.mock import MagicMock +from firebolt.db import Connection +from pytest import fixture +from source_firebolt.source import SourceFirebolt, establish_connection + from airbyte_cdk.models import Status from airbyte_cdk.models.airbyte_protocol import ( AirbyteStream, @@ -16,9 +20,6 @@ DestinationSyncMode, SyncMode, ) -from firebolt.db import Connection -from pytest import fixture -from source_firebolt.source import SourceFirebolt, establish_connection @fixture(scope="module") diff --git a/airbyte-integrations/connectors/source-firebolt/main.py b/airbyte-integrations/connectors/source-firebolt/main.py index a901e9c4ae29..3aa31e6e1953 100644 --- a/airbyte-integrations/connectors/source-firebolt/main.py +++ b/airbyte-integrations/connectors/source-firebolt/main.py @@ -4,5 +4,6 @@ from source_firebolt.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-firebolt/metadata.yaml b/airbyte-integrations/connectors/source-firebolt/metadata.yaml index ce7ede0d5d37..0880f19e849b 100644 --- a/airbyte-integrations/connectors/source-firebolt/metadata.yaml +++ b/airbyte-integrations/connectors/source-firebolt/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: database connectorType: source definitionId: 6f2ac653-8623-43c4-8950-19218c7caf3d - dockerImageTag: 2.0.23 + dockerImageTag: 2.0.24 dockerRepository: airbyte/source-firebolt githubIssueLabel: source-firebolt connectorBuildOptions: diff --git a/airbyte-integrations/connectors/source-firebolt/poetry.lock b/airbyte-integrations/connectors/source-firebolt/poetry.lock index e7ea02037e02..9402f9c24d87 100644 --- a/airbyte-integrations/connectors/source-firebolt/poetry.lock +++ b/airbyte-integrations/connectors/source-firebolt/poetry.lock @@ -807,13 +807,13 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.139" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.139-py3-none-any.whl", hash = "sha256:2a4a541bfbd0a9727255df28a60048c85bc8c4c6a276975923785c3fd82dc879"}, + {file = "langsmith-0.1.139.tar.gz", hash = "sha256:2f9e4d32fef3ad7ef42c8506448cce3a31ad6b78bb4f3310db04ddaa1e9d744d"}, ] [package.dependencies] @@ -895,69 +895,69 @@ files = [ [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.11" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.11-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6dade64687f2bd7c090281652fe18f1151292d567a9302b34c2dbb92a3872f1f"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82f07c550a6ccd2b9290849b22316a609023ed851a87ea888c0456485a7d196a"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd9a187742d3ead9df2e49240234d728c67c356516cf4db018833a86f20ec18c"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77b0fed6f209d76c1c39f032a70df2d7acf24b1812ca3e6078fd04e8972685a3"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63fc9d5fe1d4e8868f6aae547a7b8ba0a2e592929245fff61d633f4caccdcdd6"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65cd3e3bb4fbb4eddc3c1e8dce10dc0b73e808fcb875f9fab40c81903dd9323e"}, + {file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6f67c570602300c4befbda12d153113b8974a3340fdcf3d6de095ede86c06d92"}, + {file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1f39728c7f7d766f1f5a769ce4d54b5aaa4c3f92d5b84817053cc9995b977acc"}, + {file = "orjson-3.10.11-cp310-none-win32.whl", hash = "sha256:1789d9db7968d805f3d94aae2c25d04014aae3a2fa65b1443117cd462c6da647"}, + {file = "orjson-3.10.11-cp310-none-win_amd64.whl", hash = "sha256:5576b1e5a53a5ba8f8df81872bb0878a112b3ebb1d392155f00f54dd86c83ff6"}, + {file = "orjson-3.10.11-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1444f9cb7c14055d595de1036f74ecd6ce15f04a715e73f33bb6326c9cef01b6"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdec57fe3b4bdebcc08a946db3365630332dbe575125ff3d80a3272ebd0ddafe"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4eed32f33a0ea6ef36ccc1d37f8d17f28a1d6e8eefae5928f76aff8f1df85e67"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80df27dd8697242b904f4ea54820e2d98d3f51f91e97e358fc13359721233e4b"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:705f03cee0cb797256d54de6695ef219e5bc8c8120b6654dd460848d57a9af3d"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03246774131701de8e7059b2e382597da43144a9a7400f178b2a32feafc54bd5"}, + {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8b5759063a6c940a69c728ea70d7c33583991c6982915a839c8da5f957e0103a"}, + {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:677f23e32491520eebb19c99bb34675daf5410c449c13416f7f0d93e2cf5f981"}, + {file = "orjson-3.10.11-cp311-none-win32.whl", hash = "sha256:a11225d7b30468dcb099498296ffac36b4673a8398ca30fdaec1e6c20df6aa55"}, + {file = "orjson-3.10.11-cp311-none-win_amd64.whl", hash = "sha256:df8c677df2f9f385fcc85ab859704045fa88d4668bc9991a527c86e710392bec"}, + {file = "orjson-3.10.11-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:360a4e2c0943da7c21505e47cf6bd725588962ff1d739b99b14e2f7f3545ba51"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:496e2cb45de21c369079ef2d662670a4892c81573bcc143c4205cae98282ba97"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7dfa8db55c9792d53c5952900c6a919cfa377b4f4534c7a786484a6a4a350c19"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:51f3382415747e0dbda9dade6f1e1a01a9d37f630d8c9049a8ed0e385b7a90c0"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f35a1b9f50a219f470e0e497ca30b285c9f34948d3c8160d5ad3a755d9299433"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f3b7c5803138e67028dde33450e054c87e0703afbe730c105f1fcd873496d5"}, + {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f91d9eb554310472bd09f5347950b24442600594c2edc1421403d7610a0998fd"}, + {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dfbb2d460a855c9744bbc8e36f9c3a997c4b27d842f3d5559ed54326e6911f9b"}, + {file = "orjson-3.10.11-cp312-none-win32.whl", hash = "sha256:d4a62c49c506d4d73f59514986cadebb7e8d186ad510c518f439176cf8d5359d"}, + {file = "orjson-3.10.11-cp312-none-win_amd64.whl", hash = "sha256:f1eec3421a558ff7a9b010a6c7effcfa0ade65327a71bb9b02a1c3b77a247284"}, + {file = "orjson-3.10.11-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c46294faa4e4d0eb73ab68f1a794d2cbf7bab33b1dda2ac2959ffb7c61591899"}, + {file = "orjson-3.10.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52e5834d7d6e58a36846e059d00559cb9ed20410664f3ad156cd2cc239a11230"}, + {file = "orjson-3.10.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2fc947e5350fdce548bfc94f434e8760d5cafa97fb9c495d2fef6757aa02ec0"}, + {file = "orjson-3.10.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0efabbf839388a1dab5b72b5d3baedbd6039ac83f3b55736eb9934ea5494d258"}, + {file = "orjson-3.10.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3f29634260708c200c4fe148e42b4aae97d7b9fee417fbdd74f8cfc265f15b0"}, + {file = "orjson-3.10.11-cp313-none-win32.whl", hash = "sha256:1a1222ffcee8a09476bbdd5d4f6f33d06d0d6642df2a3d78b7a195ca880d669b"}, + {file = "orjson-3.10.11-cp313-none-win_amd64.whl", hash = "sha256:bc274ac261cc69260913b2d1610760e55d3c0801bb3457ba7b9004420b6b4270"}, + {file = "orjson-3.10.11-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:19b3763e8bbf8ad797df6b6b5e0fc7c843ec2e2fc0621398534e0c6400098f87"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1be83a13312e5e58d633580c5eb8d0495ae61f180da2722f20562974188af205"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:afacfd1ab81f46dedd7f6001b6d4e8de23396e4884cd3c3436bd05defb1a6446"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb4d0bea56bba596723d73f074c420aec3b2e5d7d30698bc56e6048066bd560c"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96ed1de70fcb15d5fed529a656df29f768187628727ee2788344e8a51e1c1350"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bfb30c891b530f3f80e801e3ad82ef150b964e5c38e1fb8482441c69c35c61c"}, + {file = "orjson-3.10.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d496c74fc2b61341e3cefda7eec21b7854c5f672ee350bc55d9a4997a8a95204"}, + {file = "orjson-3.10.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:655a493bac606655db9a47fe94d3d84fc7f3ad766d894197c94ccf0c5408e7d3"}, + {file = "orjson-3.10.11-cp38-none-win32.whl", hash = "sha256:b9546b278c9fb5d45380f4809e11b4dd9844ca7aaf1134024503e134ed226161"}, + {file = "orjson-3.10.11-cp38-none-win_amd64.whl", hash = "sha256:b592597fe551d518f42c5a2eb07422eb475aa8cfdc8c51e6da7054b836b26782"}, + {file = "orjson-3.10.11-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c95f2ecafe709b4e5c733b5e2768ac569bed308623c85806c395d9cca00e08af"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80c00d4acded0c51c98754fe8218cb49cb854f0f7eb39ea4641b7f71732d2cb7"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:461311b693d3d0a060439aa669c74f3603264d4e7a08faa68c47ae5a863f352d"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52ca832f17d86a78cbab86cdc25f8c13756ebe182b6fc1a97d534051c18a08de"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c57ea78a753812f528178aa2f1c57da633754c91d2124cb28991dab4c79a54"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7fcfc6f7ca046383fb954ba528587e0f9336828b568282b27579c49f8e16aad"}, + {file = "orjson-3.10.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:86b9dd983857970c29e4c71bb3e95ff085c07d3e83e7c46ebe959bac07ebd80b"}, + {file = "orjson-3.10.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4d83f87582d223e54efb2242a79547611ba4ebae3af8bae1e80fa9a0af83bb7f"}, + {file = "orjson-3.10.11-cp39-none-win32.whl", hash = "sha256:9fd0ad1c129bc9beb1154c2655f177620b5beaf9a11e0d10bac63ef3fce96950"}, + {file = "orjson-3.10.11-cp39-none-win_amd64.whl", hash = "sha256:10f416b2a017c8bd17f325fb9dee1fb5cdd7a54e814284896b7c3f2763faa017"}, + {file = "orjson-3.10.11.tar.gz", hash = "sha256:e35b6d730de6384d5b2dab5fd23f0d76fae8bbc8c353c2f78210aa5fa4beb3ef"}, ] [[package]] @@ -1474,23 +1474,23 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.2.0" +version = "75.3.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, + {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, ] [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] [[package]] name = "six" diff --git a/airbyte-integrations/connectors/source-firebolt/pyproject.toml b/airbyte-integrations/connectors/source-firebolt/pyproject.toml index 612e6c807f0d..08ce69a2ec74 100644 --- a/airbyte-integrations/connectors/source-firebolt/pyproject.toml +++ b/airbyte-integrations/connectors/source-firebolt/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "2.0.23" +version = "2.0.24" name = "source-firebolt" description = "Source implementation for Firebolt." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-firebolt/source_firebolt/source.py b/airbyte-integrations/connectors/source-firebolt/source_firebolt/source.py index 2d53f9c90663..aaf4e8112643 100644 --- a/airbyte-integrations/connectors/source-firebolt/source_firebolt/source.py +++ b/airbyte-integrations/connectors/source-firebolt/source_firebolt/source.py @@ -20,6 +20,7 @@ from .database import establish_connection, get_table_structure from .utils import airbyte_message_from_data, convert_type + SUPPORTED_SYNC_MODES = [SyncMode.full_refresh] diff --git a/airbyte-integrations/connectors/source-firebolt/unit_tests/test_firebolt_source.py b/airbyte-integrations/connectors/source-firebolt/unit_tests/test_firebolt_source.py index 2e273232b323..01ab8d494202 100644 --- a/airbyte-integrations/connectors/source-firebolt/unit_tests/test_firebolt_source.py +++ b/airbyte-integrations/connectors/source-firebolt/unit_tests/test_firebolt_source.py @@ -6,6 +6,11 @@ from decimal import Decimal from unittest.mock import MagicMock, patch +from pytest import fixture, mark +from source_firebolt.database import get_table_structure, parse_config +from source_firebolt.source import SUPPORTED_SYNC_MODES, SourceFirebolt, convert_type, establish_connection +from source_firebolt.utils import airbyte_message_from_data, format_fetch_result + from airbyte_cdk.models import ( AirbyteMessage, AirbyteRecordMessage, @@ -17,10 +22,6 @@ SyncMode, Type, ) -from pytest import fixture, mark -from source_firebolt.database import get_table_structure, parse_config -from source_firebolt.source import SUPPORTED_SYNC_MODES, SourceFirebolt, convert_type, establish_connection -from source_firebolt.utils import airbyte_message_from_data, format_fetch_result @fixture(params=["my_engine", "my_engine.api.firebolt.io"]) @@ -33,6 +34,7 @@ def config(request): } return args + @fixture() def legacy_config(request): args = { @@ -44,6 +46,7 @@ def legacy_config(request): } return args + @fixture() def config_no_engine(): args = { @@ -109,12 +112,14 @@ def test_parse_config(config, logger): result = parse_config(config, logger) assert result["engine_url"] == "override_engine.api.firebolt.io" + def test_parse_legacy_config(legacy_config, logger): result = parse_config(legacy_config, logger) assert result["database"] == "my_database" assert result["auth"].username == "my@username" assert result["auth"].password == "my_password" + @patch("source_firebolt.database.connect") def test_connection(mock_connection, config, config_no_engine, logger): establish_connection(config, logger) diff --git a/airbyte-integrations/connectors/source-firehydrant/README.md b/airbyte-integrations/connectors/source-firehydrant/README.md new file mode 100644 index 000000000000..ed3bbfe9f0fa --- /dev/null +++ b/airbyte-integrations/connectors/source-firehydrant/README.md @@ -0,0 +1,33 @@ +# FireHydrant +This directory contains the manifest-only connector for `source-firehydrant`. + +The Airbyte connector for FireHydrant enables seamless data integration between FireHydrant and your data ecosystem. It allows you to efficiently extract incident management and reliability data from FireHydrant, empowering teams with valuable insights for post-incident analysis, reliability reporting, and proactive system monitoring. With this connector, users can automate the data flow and gain deeper visibility into incidents and response metrics, improving reliability and operational efficiency. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-firehydrant:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-firehydrant build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-firehydrant test +``` + diff --git a/airbyte-integrations/connectors/source-firehydrant/acceptance-test-config.yml b/airbyte-integrations/connectors/source-firehydrant/acceptance-test-config.yml new file mode 100644 index 000000000000..13e44fa73b3a --- /dev/null +++ b/airbyte-integrations/connectors/source-firehydrant/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-firehydrant:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-firehydrant/icon.svg b/airbyte-integrations/connectors/source-firehydrant/icon.svg new file mode 100644 index 000000000000..e4b9af7ad99e --- /dev/null +++ b/airbyte-integrations/connectors/source-firehydrant/icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/airbyte-integrations/connectors/source-firehydrant/manifest.yaml b/airbyte-integrations/connectors/source-firehydrant/manifest.yaml new file mode 100644 index 000000000000..5f59aa3cd03b --- /dev/null +++ b/airbyte-integrations/connectors/source-firehydrant/manifest.yaml @@ -0,0 +1,6889 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + The Airbyte connector for FireHydrant enables seamless data integration + between FireHydrant and your data ecosystem. It allows you to efficiently + extract incident management and reliability data from FireHydrant, empowering + teams with valuable insights for post-incident analysis, reliability + reporting, and proactive system monitoring. With this connector, users can + automate the data flow and gain deeper visibility into incidents and response + metrics, improving reliability and operational efficiency. + +check: + type: CheckStream + stream_names: + - enviroments + +definitions: + streams: + enviroments: + type: DeclarativeStream + name: enviroments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /environments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/enviroments" + services: + type: DeclarativeStream + name: services + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /services + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/services" + functionalities: + type: DeclarativeStream + name: functionalities + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /functionalities + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/functionalities" + teams: + type: DeclarativeStream + name: teams + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /teams + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/teams" + webhooks: + type: DeclarativeStream + name: webhooks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /webhooks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/webhooks" + signals_on_call: + type: DeclarativeStream + name: signals_on_call + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /signals_on_call + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/signals_on_call" + changes_events: + type: DeclarativeStream + name: changes_events + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /changes/events + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/changes_events" + changes: + type: DeclarativeStream + name: changes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /changes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/changes" + entitlements: + type: DeclarativeStream + name: entitlements + primary_key: + - slug + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /entitlements + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/entitlements" + incidents: + type: DeclarativeStream + name: incidents + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /incidents + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/incidents" + incident_roles: + type: DeclarativeStream + name: incident_roles + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /incident_roles + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/incident_roles" + incident_tags: + type: DeclarativeStream + name: incident_tags + primary_key: + - name + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /incident_tags + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/incident_tags" + incident_types: + type: DeclarativeStream + name: incident_types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /incident_types + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/incident_types" + integrations: + type: DeclarativeStream + name: integrations + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /integrations + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/integrations" + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + reports: + type: DeclarativeStream + name: reports + primary_key: + - bucket + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /reports/mean_time + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/reports" + runbook_actions: + type: DeclarativeStream + name: runbook_actions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /runbooks/actions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/runbook_actions" + runbook_executions: + type: DeclarativeStream + name: runbook_executions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /runbooks/executions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/runbook_executions" + runbooks: + type: DeclarativeStream + name: runbooks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /runbooks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/runbooks" + runbook_audits: + type: DeclarativeStream + name: runbook_audits + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /runbook_audits + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/runbook_audits" + nunc_connections: + type: DeclarativeStream + name: nunc_connections + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /nunc_connections + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/nunc_connections" + measurement_definitions: + type: DeclarativeStream + name: measurement_definitions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /lifecycles/measurement_definitions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/measurement_definitions" + phases: + type: DeclarativeStream + name: phases + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /lifecycles/phases + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/phases" + priorities: + type: DeclarativeStream + name: priorities + primary_key: + - slug + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /priorities + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/priorities" + severities: + type: DeclarativeStream + name: severities + primary_key: + - slug + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /severities + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/severities" + severity_matrix_conditions: + type: DeclarativeStream + name: severity_matrix_conditions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /severity_matrix/conditions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/severity_matrix_conditions" + severity_matrix_impacts: + type: DeclarativeStream + name: severity_matrix_impacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /severity_matrix/impacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/severity_matrix_impacts" + scheduled_maintenances: + type: DeclarativeStream + name: scheduled_maintenances + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /scheduled_maintenances + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/scheduled_maintenances" + infrastructures: + type: DeclarativeStream + name: infrastructures + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /infrastructures + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + transformations: + - type: AddFields + fields: + - path: + - id + value: "{{ record['infrastructure']['id'] }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/infrastructures" + custom_fields_definitions: + type: DeclarativeStream + name: custom_fields_definitions + primary_key: + - field_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /custom_fields/definitions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/custom_fields_definitions" + post_mortems_reports: + type: DeclarativeStream + name: post_mortems_reports + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /post_mortems/reports + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/post_mortems_reports" + post_mortems_questions: + type: DeclarativeStream + name: post_mortems_questions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /post_mortems/questions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/post_mortems_questions" + alerts: + type: DeclarativeStream + name: alerts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /alerts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/alerts" + tickets: + type: DeclarativeStream + name: tickets + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /ticketing/tickets + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tickets" + ticketing_projects: + type: DeclarativeStream + name: ticketing_projects + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /ticketing/projects + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/ticketing_projects" + ticketing_priorities: + type: DeclarativeStream + name: ticketing_priorities + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /ticketing/priorities + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/ticketing_priorities" + ticket_tags: + type: DeclarativeStream + name: ticket_tags + primary_key: + - name + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /ticketing/ticket_tags + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/ticket_tags" + task_lists: + type: DeclarativeStream + name: task_lists + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /task_lists + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/task_lists" + checklist_templates: + type: DeclarativeStream + name: checklist_templates + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /checklist_templates + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get(\"pagination\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"pagination\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/checklist_templates" + base_requester: + type: HttpRequester + url_base: https://api.firehydrant.io/v1 + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"api_token\"] }}" + +streams: + - $ref: "#/definitions/streams/enviroments" + - $ref: "#/definitions/streams/services" + - $ref: "#/definitions/streams/functionalities" + - $ref: "#/definitions/streams/teams" + - $ref: "#/definitions/streams/webhooks" + - $ref: "#/definitions/streams/signals_on_call" + - $ref: "#/definitions/streams/changes_events" + - $ref: "#/definitions/streams/changes" + - $ref: "#/definitions/streams/entitlements" + - $ref: "#/definitions/streams/incidents" + - $ref: "#/definitions/streams/incident_roles" + - $ref: "#/definitions/streams/incident_tags" + - $ref: "#/definitions/streams/incident_types" + - $ref: "#/definitions/streams/integrations" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/reports" + - $ref: "#/definitions/streams/runbook_actions" + - $ref: "#/definitions/streams/runbook_executions" + - $ref: "#/definitions/streams/runbooks" + - $ref: "#/definitions/streams/runbook_audits" + - $ref: "#/definitions/streams/nunc_connections" + - $ref: "#/definitions/streams/measurement_definitions" + - $ref: "#/definitions/streams/phases" + - $ref: "#/definitions/streams/priorities" + - $ref: "#/definitions/streams/severities" + - $ref: "#/definitions/streams/severity_matrix_conditions" + - $ref: "#/definitions/streams/severity_matrix_impacts" + - $ref: "#/definitions/streams/scheduled_maintenances" + - $ref: "#/definitions/streams/infrastructures" + - $ref: "#/definitions/streams/custom_fields_definitions" + - $ref: "#/definitions/streams/post_mortems_reports" + - $ref: "#/definitions/streams/post_mortems_questions" + - $ref: "#/definitions/streams/alerts" + - $ref: "#/definitions/streams/tickets" + - $ref: "#/definitions/streams/ticketing_projects" + - $ref: "#/definitions/streams/ticketing_priorities" + - $ref: "#/definitions/streams/ticket_tags" + - $ref: "#/definitions/streams/task_lists" + - $ref: "#/definitions/streams/checklist_templates" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_token + properties: + api_token: + type: string + description: >- + Bot token to use for authenticating with the FireHydrant API. You can + find or create a bot token by logging into your organization and + visiting the Bot users page at + https://app.firehydrant.io/organizations/bots. + name: api_token + order: 0 + title: API Token + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + enviroments: true + services: true + functionalities: true + teams: true + webhooks: true + signals_on_call: true + changes_events: true + changes: true + entitlements: true + incidents: true + incident_roles: true + incident_tags: true + incident_types: true + integrations: true + users: true + reports: true + runbook_actions: true + runbook_executions: true + runbooks: true + runbook_audits: true + nunc_connections: true + measurement_definitions: true + phases: true + priorities: true + severities: true + severity_matrix_conditions: true + severity_matrix_impacts: true + scheduled_maintenances: true + infrastructures: true + custom_fields_definitions: true + post_mortems_reports: true + post_mortems_questions: true + alerts: true + tickets: true + ticketing_projects: true + ticketing_priorities: true + ticket_tags: true + task_lists: true + checklist_templates: true + testedStreams: + enviroments: + hasRecords: true + streamHash: 71983108f8df8f1a8b9a2ff3995dfe29414d67fe + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + services: + hasRecords: true + streamHash: 2f64b43f7a8b620ce891202df6b94e9501b5a428 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + functionalities: + hasRecords: true + streamHash: 7c41bbb2c1962de172a812603704919911ffd889 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + teams: + hasRecords: true + streamHash: 58c73deeb399b8e6b39d28cdfe24bfdcfb26c071 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + webhooks: + hasRecords: true + streamHash: 3882e21c123275883db1ffc1a234fe9911dd7556 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + signals_on_call: + hasRecords: true + streamHash: d88d170a0d2cc0344845a0fb569a9947a740fcd9 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + changes_events: + hasRecords: true + streamHash: 1e72de329f01ba8e45411b01ea912ef3250565fb + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + changes: + hasRecords: true + streamHash: f2b49a9b58168ddfbb01e97e4b7cc253bb315034 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + entitlements: + hasRecords: true + streamHash: e3dbda8d04c12461d39ad3f2480b0ffa75d7ac3c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + incidents: + hasRecords: true + streamHash: 42d7966e35a4b94108fcfb510b6297f3f8bc4f03 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + incident_roles: + hasRecords: true + streamHash: 971b4d934016e6fccd33a297479c7753bfa1dfef + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + incident_tags: + hasRecords: true + streamHash: bc18571d8105214f3f5463c543e57314a359e4b4 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + incident_types: + hasRecords: true + streamHash: e2b355089e950aa9a7d0c18b7a39af49db1656c6 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + integrations: + hasRecords: true + streamHash: 5f836b33d2d3070e72daa4c2eb30b047ee1318a6 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + users: + hasRecords: true + streamHash: 512f644060cf210bdabe36aef703de21607d1bdf + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + reports: + hasRecords: true + streamHash: d9b38bc9d3e6200cc43ef3036fa563a44b1210c0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + runbook_actions: + hasRecords: true + streamHash: cccc1c26f630fd82cdcc3238fbe6018e772a771b + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + runbook_executions: + hasRecords: true + streamHash: 0cb2e568db0fb9744718bec9d590cce98131d152 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + runbooks: + hasRecords: true + streamHash: a538bbef227d626e73f8600649903a4266db50cf + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + runbook_audits: + hasRecords: true + streamHash: 9e563d84495affb0e47f17381f412b811f0eaa98 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + nunc_connections: + hasRecords: true + streamHash: 3cdf85f3f6ac7ab7ccc7a618360c15a9f0d7667e + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + measurement_definitions: + hasRecords: true + streamHash: d99db659bc2b373ab7c91b5a02e7249d81415a1d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + phases: + hasRecords: true + streamHash: baa1d5104f78b1c15011110b0481dad09e7a652a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + priorities: + hasRecords: true + streamHash: 20a474e11a55d6cb19f38d84d7725c3d32eb402d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + severities: + hasRecords: true + streamHash: 52af71adff9c3625346fda144e389a8fe586b8fa + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + severity_matrix_conditions: + hasRecords: true + streamHash: 00f9e25630ed8e92f7826983916e3c7b1a50202a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + severity_matrix_impacts: + hasRecords: true + streamHash: b273c982f82008bcab876d832d823f90fd2fbdc0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + scheduled_maintenances: + hasRecords: true + streamHash: 70dd65b2f5d1e71876c14507227ec7e72d3d943b + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + infrastructures: + hasRecords: true + streamHash: 6beeecd9f04aaac754a2e24d041f39432de6bdb5 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + custom_fields_definitions: + hasRecords: true + streamHash: 4a16e02dbf2c63df3f2c8df850963e13d89b8406 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + post_mortems_reports: + hasRecords: true + streamHash: 4057a116278a3d45e7d38a80fa702a5530ef5ed0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + post_mortems_questions: + hasRecords: true + streamHash: 95ec2948aa1b42d8393daa0631e10eaefe5f0177 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + alerts: + hasRecords: true + streamHash: 424d96078269c237dca02d43a59152cae75b5ce2 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + tickets: + hasRecords: true + streamHash: b43064e6e6c589d026f8f39d992c9cc10b85ffe5 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + ticketing_projects: + hasRecords: true + streamHash: 339ecfe3e573f72148bdeb54ba286ac62118c52c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + ticketing_priorities: + hasRecords: true + streamHash: bbaa77a0891236d1ea132fe951370f24a75a1b6d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + ticket_tags: + streamHash: 26d058b7451618c9b13c6a3c034443ade678e09f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + task_lists: + hasRecords: true + streamHash: 4a56320dcfb4c9ca479d7589cdfcd75a4a9c5949 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + checklist_templates: + hasRecords: true + streamHash: 74d8d98c1f3e58da49564fa21cfca4828e5679fc + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://developers.firehydrant.com/ + +schemas: + enviroments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + active_incidents: + type: + - array + - "null" + created_at: + type: + - string + - "null" + external_resources: + type: + - array + - "null" + id: + type: string + name: + type: + - string + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + services: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + active_incidents: + type: + - array + - "null" + alert_on_add: + type: + - boolean + - "null" + auto_add_responding_team: + type: + - boolean + - "null" + checklists: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + checks: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + completed_checks: + type: + - number + - "null" + created_at: + type: + - string + - "null" + external_resources: + type: + - array + - "null" + functionalities: + type: + - array + - "null" + id: + type: string + labels: + type: + - object + - "null" + properties: + j: + type: + - string + - "null" + links: + type: + - array + - "null" + name: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + signals_ical_url: + type: + - string + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + service_tier: + type: + - number + - "null" + slug: + type: + - string + - "null" + teams: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + signals_ical_url: + type: + - string + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + required: + - id + functionalities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + active_incidents: + type: + - array + - "null" + alert_on_add: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + external_resources: + type: + - array + - "null" + id: + type: string + labels: + type: + - object + - "null" + links: + type: + - array + - "null" + name: + type: + - string + - "null" + services: + type: + - array + - "null" + slug: + type: + - string + - "null" + teams: + type: + - array + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + required: + - id + teams: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + functionalities: + type: + - array + - "null" + id: + type: string + memberships: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + default_incident_role: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + summary: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + user: + type: + - object + - "null" + properties: + created_at: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + signals_enabled_notification_types: + type: + - array + - "null" + slack_linked?: + type: + - boolean + - "null" + updated_at: + type: + - string + - "null" + name: + type: + - string + - "null" + owned_checklist_templates: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + checks: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + owned_functionalities: + type: + - array + - "null" + owned_runbooks: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + categories: + type: + - array + - "null" + items: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + signals_ical_url: + type: + - string + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + summary: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + owned_services: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + alert_on_add: + type: + - boolean + - "null" + auto_add_responding_team: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + id: + type: + - string + - "null" + labels: + type: + - object + - "null" + properties: + j: + type: + - string + - "null" + name: + type: + - string + - "null" + service_tier: + type: + - number + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + responding_services: + type: + - array + - "null" + services: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + alert_on_add: + type: + - boolean + - "null" + auto_add_responding_team: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + id: + type: + - string + - "null" + labels: + type: + - object + - "null" + properties: + j: + type: + - string + - "null" + name: + type: + - string + - "null" + service_tier: + type: + - number + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + signals_ical_url: + type: + - string + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + webhooks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + id: + type: string + state: + type: + - string + - "null" + subscriptions: + type: + - array + - "null" + items: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + url: + type: + - string + - "null" + required: + - id + signals_on_call: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + current_shift: + type: + - object + - "null" + properties: + color: + type: + - string + - "null" + end_time: + type: + - string + - "null" + id: + type: + - string + - "null" + on_call_schedule: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + start_time: + type: + - string + - "null" + team: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + time_zone: + type: + - string + - "null" + user: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + next_shift: + type: + - object + - "null" + properties: + color: + type: + - string + - "null" + end_time: + type: + - string + - "null" + id: + type: + - string + - "null" + on_call_schedule: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + start_time: + type: + - string + - "null" + team: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + time_zone: + type: + - string + - "null" + user: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + team: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + time_zone: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + changes_events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + authors: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + created_at: + type: + - string + - "null" + duration_iso8601: + type: + - string + - "null" + duration_ms: + type: + - number + - "null" + ends_at: + type: + - string + - "null" + environments: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + active_incidents: + type: + - array + - "null" + created_at: + type: + - string + - "null" + external_resources: + type: + - array + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + id: + type: string + labels: + type: + - object + - "null" + properties: + j: + type: + - string + - "null" + old: + type: + - string + - "null" + services: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + alert_on_add: + type: + - boolean + - "null" + auto_add_responding_team: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + id: + type: + - string + - "null" + labels: + type: + - object + - "null" + properties: + j: + type: + - string + - "null" + name: + type: + - string + - "null" + service_tier: + type: + - number + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + starts_at: + type: + - string + - "null" + summary: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + changes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: string + labels: + type: + - object + - "null" + properties: + property1: + type: + - string + - "null" + property2: + type: + - string + - "null" + summary: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + entitlements: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + available: + type: + - boolean + - "null" + current_count: + type: + - number + - "null" + errors: + type: + - object + - "null" + properties: + access: + type: + - array + - "null" + items: + type: + - string + - "null" + quota: + type: + - array + - "null" + items: + type: + - string + - "null" + exists: + type: + - boolean + - "null" + maximum: + type: + - number + - "null" + name: + type: + - string + - "null" + slug: + type: string + tier: + type: + - string + - "null" + required: + - slug + incidents: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + active: + type: + - boolean + - "null" + conference_bridges: + type: + - array + - "null" + conversations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + channel: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + comments_url: + type: + - string + - "null" + field: + type: + - string + - "null" + id: + type: + - string + - "null" + resource_class: + type: + - string + - "null" + resource_id: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + current_milestone: + type: + - string + - "null" + custom_fields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + display_name: + type: + - string + - "null" + field_id: + type: + - string + - "null" + name: + type: + - string + - "null" + slug: + type: + - string + - "null" + value: + type: + - string + - "null" + value_string: + type: + - string + - "null" + value_type: + type: + - string + - "null" + customer_impact_summary: + type: + - string + - "null" + customers_impacted: + type: + - number + - "null" + environments: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + field_requirements: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + field_id: + type: + - string + - "null" + functionalities: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: string + impacts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + condition: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + position: + type: + - number + - "null" + conversations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + channel: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + comments_url: + type: + - string + - "null" + id: + type: + - string + - "null" + resource_class: + type: + - string + - "null" + resource_id: + type: + - string + - "null" + id: + type: + - string + - "null" + impact: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + incident_channels: + type: + - array + - "null" + incident_tickets: + type: + - array + - "null" + incident_url: + type: + - string + - "null" + labels: + type: + - object + - "null" + last_note: + type: + - object + - "null" + properties: + body: + type: + - string + - "null" + conversations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + channel: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + comments_url: + type: + - string + - "null" + id: + type: + - string + - "null" + resource_class: + type: + - string + - "null" + resource_id: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: + - string + - "null" + status_pages: + type: + - array + - "null" + last_update: + type: + - string + - "null" + lifecycle_measurements: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + calculated_at: + type: + - string + - "null" + ends_at_milestone: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + slug: + type: + - string + - "null" + starts_at_milestone: + type: + - string + - "null" + value: + type: + - string + - "null" + lifecycle_phases: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + id: + type: + - string + - "null" + milestones: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + duration: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + occurred_at: + type: + - string + - "null" + position: + type: + - number + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + name: + type: + - string + - "null" + position: + type: + - number + - "null" + milestones: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + created_at: + type: + - string + - "null" + duration: + type: + - string + - "null" + id: + type: + - string + - "null" + occurred_at: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + name: + type: + - string + - "null" + number: + type: + - number + - "null" + organization: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + organization_id: + type: + - string + - "null" + priority: + type: + - string + - "null" + private_id: + type: + - string + - "null" + private_status_page_url: + type: + - string + - "null" + report_id: + type: + - string + - "null" + restricted: + type: + - boolean + - "null" + retro_exports: + type: + - array + - "null" + role_assignments: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + created_at: + type: + - string + - "null" + id: + type: + - string + - "null" + incident_role: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + summary: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + status: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + user: + type: + - object + - "null" + properties: + created_at: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + signals_enabled_notification_types: + type: + - array + - "null" + slack_linked?: + type: + - boolean + - "null" + updated_at: + type: + - string + - "null" + services: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + severity: + type: + - string + - "null" + severity_color: + type: + - string + - "null" + started_at: + type: + - string + - "null" + status_pages: + type: + - array + - "null" + summary: + type: + - string + - "null" + tag_list: + type: + - array + - "null" + items: + type: + - string + - "null" + team_assignments: + type: + - array + - "null" + required: + - id + incident_roles: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + summary: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + incident_tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + name: + type: string + required: + - name + incident_types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + template: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + impacts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + condition_id: + type: + - string + - "null" + condition_name: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + priority: + type: + - string + - "null" + runbook_ids: + type: + - array + - "null" + severity: + type: + - string + - "null" + tag_list: + type: + - array + - "null" + items: + type: + - string + - "null" + template_values: + type: + - object + - "null" + properties: + environments: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + condition_id: + type: + - string + - "null" + condition_name: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + functionalities: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + condition_id: + type: + - string + - "null" + condition_name: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + runbooks: + type: + - object + - "null" + services: + type: + - array + - "null" + teams: + type: + - object + - "null" + updated_at: + type: + - string + - "null" + required: + - id + integrations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + connections: + type: + - array + - "null" + created_at: + type: + - string + - "null" + deprecated: + type: + - boolean + - "null" + enabled: + type: + - boolean + - "null" + id: + type: string + installed: + type: + - boolean + - "null" + logo: + type: + - object + - "null" + properties: + logo_url: + type: + - string + - "null" + name: + type: + - string + - "null" + nat_ip: + type: + - string + - "null" + setup_url: + type: + - string + - "null" + slug: + type: + - string + - "null" + required: + - id + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + signals_enabled_notification_types: + type: + - array + - "null" + slack_linked?: + type: + - boolean + - "null" + updated_at: + type: + - string + - "null" + required: + - id + reports: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + bucket: + type: string + points: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + key: + type: + - string + - "null" + value: + type: + - number + - "null" + required: + - bucket + runbook_actions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + automatable: + type: + - boolean + - "null" + category: + type: + - string + - "null" + config: + type: + - object + - "null" + properties: + documentation_url: + type: + - string + - "null" + elements: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + dynamic_select: + type: + - object + - "null" + properties: + async_url: + type: + - string + - "null" + clearable: + type: + - boolean + - "null" + default_value: + anyOf: + - type: + - array + - "null" + - type: object + properties: + label: + type: string + value: + type: string + is_multi: + type: + - boolean + - "null" + label: + type: + - string + - "null" + options: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + placeholder: + type: + - string + - "null" + required: + type: + - boolean + - "null" + id: + type: + - string + - "null" + input: + type: + - object + - "null" + properties: + default_value: + type: + - string + - "null" + label: + type: + - string + - "null" + placeholder: + type: + - string + - "null" + required: + type: + - boolean + - "null" + markdown: + type: + - object + - "null" + properties: + text: + type: + - string + - "null" + textarea: + type: + - object + - "null" + properties: + default_value: + type: + - string + - "null" + label: + type: + - string + - "null" + placeholder: + type: + - string + - "null" + created_at: + type: + - string + - "null" + default_logic: + type: + - object + - "null" + properties: + eq: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + var: + type: + - string + - "null" + exists: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + var: + type: + - string + - "null" + default_rule_data: + type: + - object + - "null" + properties: + "1": + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + label: + type: + - string + - "null" + value: + type: + - string + - "null" + id: + type: string + integration: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + connections: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + authorized_by: + type: + - string + - "null" + authorized_by_id: + type: + - string + - "null" + configuration_url: + type: + - string + - "null" + created_at: + type: + - string + - "null" + default_authorized_actor: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + display_name: + type: + - string + - "null" + id: + type: + - string + - "null" + integration_id: + type: + - string + - "null" + integration_slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + created_at: + type: + - string + - "null" + deprecated: + type: + - boolean + - "null" + enabled: + type: + - boolean + - "null" + id: + type: + - string + - "null" + installed: + type: + - boolean + - "null" + logo: + type: + - object + - "null" + properties: + logo_url: + type: + - string + - "null" + name: + type: + - string + - "null" + nat_ip: + type: + - string + - "null" + setup_url: + type: + - string + - "null" + slug: + type: + - string + - "null" + name: + type: + - string + - "null" + prerequisites: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + setup_path: + type: + - string + - "null" + slug: + type: + - string + - "null" + warning: + type: + - string + - "null" + repeatable: + type: + - boolean + - "null" + rerunnable: + type: + - boolean + - "null" + slug: + type: + - string + - "null" + supported_runbook_types: + type: + - array + - "null" + items: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + runbook_executions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + created_by: + type: + - string + - "null" + executed_for: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + has_been_rerun: + type: + - boolean + - "null" + id: + type: string + runbook: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + categories: + type: + - array + - "null" + items: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + summary: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + status: + type: + - string + - "null" + status_reason: + type: + - string + - "null" + status_reason_message: + type: + - string + - "null" + steps: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + action_slug: + type: + - string + - "null" + action_type: + type: + - string + - "null" + automatic: + type: + - boolean + - "null" + config: + type: + - object + - "null" + properties: + role: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + role_for_assignment: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + task_list: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + user: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + executable: + type: + - boolean + - "null" + execution: + type: + - object + - "null" + properties: + data: + type: + - object + - "null" + performed_at: + type: + - string + - "null" + performed_by: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + state: + type: + - string + - "null" + has_been_rerun: + type: + - boolean + - "null" + has_been_retried: + type: + - boolean + - "null" + id: + type: + - string + - "null" + integration_name: + type: + - string + - "null" + integration_slug: + type: + - string + - "null" + name: + type: + - string + - "null" + repeatable: + type: + - boolean + - "null" + repeats: + type: + - boolean + - "null" + step_elements: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + dataKeyName: + type: + - string + - "null" + id: + type: + - string + - "null" + markdown: + type: + - object + - "null" + properties: + text: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + runbooks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + attachment_rule: + type: + - object + - "null" + properties: + logic: + type: + - object + - "null" + properties: + manually: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + var: + type: + - string + - "null" + user_data: + type: + - object + - "null" + categories: + type: + - array + - "null" + items: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + signals_ical_url: + type: + - string + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + summary: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + runbook_audits: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + account_id: + type: + - number + - "null" + action: + type: + - string + - "null" + auditable_id: + type: + - string + - "null" + auditable_type: + type: + - string + - "null" + audited_changes: + type: + - object + - "null" + properties: + account_id: + type: + - number + - "null" + action_id: + type: + - string + - "null" + automatic: + type: + - boolean + - "null" + config: + type: + - object + - "null" + properties: + agenda: + type: + - string + - "null" + body: + type: + - string + - "null" + channel_name_format: + type: + - string + - "null" + channel_visibility: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + channels: + type: + - string + - "null" + communications_channel_enabled: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + email_address: + type: + - string + - "null" + message: + type: + - string + - "null" + record_meeting: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + role: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + role_for_assignment: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + runbook: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + subject: + type: + - string + - "null" + summary: + type: + - string + - "null" + task_list: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + ticket_description: + type: + - string + - "null" + ticket_summary: + type: + - string + - "null" + topic: + type: + - string + - "null" + user: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + delay_duration: + type: + - string + - "null" + name: + type: + - string + - "null" + organization_id: + type: + - string + - "null" + position: + type: + - number + - "null" + repeats: + type: + - boolean + - "null" + repeats_duration: + type: + - string + - "null" + reruns: + type: + - boolean + - "null" + runbook_id: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: number + user_id: + type: + - string + - "null" + user_type: + type: + - string + - "null" + required: + - id + nunc_connections: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + cname: + type: + - string + - "null" + company_name: + type: + - string + - "null" + component_groups: + type: + - array + - "null" + components: + type: + - array + - "null" + conditions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + condition_id: + type: + - string + - "null" + condition_name: + type: + - string + - "null" + nunc_condition: + type: + - string + - "null" + domain: + type: + - string + - "null" + enable_histogram: + type: + - boolean + - "null" + exposed_fields: + type: + - array + - "null" + items: + type: + - string + - "null" + greeting_body: + type: + - string + - "null" + greeting_title: + type: + - string + - "null" + id: + type: string + links: + type: + - array + - "null" + operational_message: + type: + - string + - "null" + title: + type: + - string + - "null" + ui_version: + type: + - number + - "null" + required: + - id + measurement_definitions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + ends_at_milestone: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + slug: + type: + - string + - "null" + healthiness: + type: + - boolean + - "null" + id: + type: string + name: + type: + - string + - "null" + slug: + type: + - string + - "null" + starts_at_milestone: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + phases: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + id: + type: string + milestones: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + position: + type: + - number + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + name: + type: + - string + - "null" + position: + type: + - number + - "null" + required: + - id + priorities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + default: + type: + - boolean + - "null" + position: + type: + - number + - "null" + slug: + type: string + updated_at: + type: + - string + - "null" + required: + - slug + severities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + color: + type: + - string + - "null" + created_at: + type: + - string + - "null" + position: + type: + - number + - "null" + slug: + type: string + system_record: + type: + - boolean + - "null" + updated_at: + type: + - string + - "null" + required: + - slug + severity_matrix_conditions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: string + name: + type: + - string + - "null" + position: + type: + - number + - "null" + required: + - id + severity_matrix_impacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + affects_id: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + position: + type: + - number + - "null" + required: + - id + scheduled_maintenances: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + ends_at: + type: + - string + - "null" + id: + type: string + impacts: + type: + - array + - "null" + labels: + type: + - object + - "null" + name: + type: + - string + - "null" + starts_at: + type: + - string + - "null" + status_pages: + type: + - array + - "null" + summary: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + infrastructures: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + id: + type: string + infrastructure: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + active_incidents: + type: + - array + - "null" + items: + type: + - string + - "null" + alert_on_add: + type: + - boolean + - "null" + auto_add_responding_team: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + external_resources: + type: + - array + - "null" + id: + type: + - string + - "null" + labels: + type: + - object + - "null" + properties: + j: + type: + - string + - "null" + name: + type: + - string + - "null" + service_tier: + type: + - number + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + custom_fields_definitions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + display_name: + type: + - string + - "null" + field_id: + type: string + field_type: + type: + - string + - "null" + permissible_values: + type: + - array + - "null" + items: + type: + - string + - "null" + required: + type: + - boolean + - "null" + slug: + type: + - string + - "null" + required: + - field_id + post_mortems_reports: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + calendar_events: + type: + - array + - "null" + created_at: + type: + - string + - "null" + id: + type: string + incident: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + active: + type: + - boolean + - "null" + conference_bridges: + type: + - array + - "null" + conversations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + channel: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + comments_url: + type: + - string + - "null" + field: + type: + - string + - "null" + id: + type: + - string + - "null" + resource_class: + type: + - string + - "null" + resource_id: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + current_milestone: + type: + - string + - "null" + custom_fields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + display_name: + type: + - string + - "null" + field_id: + type: + - string + - "null" + name: + type: + - string + - "null" + slug: + type: + - string + - "null" + value: + type: + - string + - "null" + value_string: + type: + - string + - "null" + value_type: + type: + - string + - "null" + customer_impact_summary: + type: + - string + - "null" + customers_impacted: + type: + - number + - "null" + environments: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + field_requirements: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + field_id: + type: + - string + - "null" + functionalities: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: + - string + - "null" + impacts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + condition: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + position: + type: + - number + - "null" + conversations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + channel: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + comments_url: + type: + - string + - "null" + id: + type: + - string + - "null" + resource_class: + type: + - string + - "null" + resource_id: + type: + - string + - "null" + id: + type: + - string + - "null" + impact: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + incident_channels: + type: + - array + - "null" + incident_tickets: + type: + - array + - "null" + incident_url: + type: + - string + - "null" + labels: + type: + - object + - "null" + last_note: + type: + - object + - "null" + properties: + body: + type: + - string + - "null" + conversations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + channel: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + comments_url: + type: + - string + - "null" + id: + type: + - string + - "null" + resource_class: + type: + - string + - "null" + resource_id: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: + - string + - "null" + status_pages: + type: + - array + - "null" + last_update: + type: + - string + - "null" + lifecycle_measurements: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + calculated_at: + type: + - string + - "null" + ends_at_milestone: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + slug: + type: + - string + - "null" + starts_at_milestone: + type: + - string + - "null" + value: + type: + - string + - "null" + lifecycle_phases: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + id: + type: + - string + - "null" + milestones: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + duration: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + occurred_at: + type: + - string + - "null" + position: + type: + - number + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + name: + type: + - string + - "null" + position: + type: + - number + - "null" + milestones: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + created_at: + type: + - string + - "null" + duration: + type: + - string + - "null" + id: + type: + - string + - "null" + occurred_at: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + name: + type: + - string + - "null" + number: + type: + - number + - "null" + organization: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + organization_id: + type: + - string + - "null" + priority: + type: + - string + - "null" + private_id: + type: + - string + - "null" + private_status_page_url: + type: + - string + - "null" + report_id: + type: + - string + - "null" + restricted: + type: + - boolean + - "null" + retro_exports: + type: + - array + - "null" + role_assignments: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + created_at: + type: + - string + - "null" + id: + type: + - string + - "null" + incident_role: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + summary: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + status: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + user: + type: + - object + - "null" + properties: + created_at: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + signals_enabled_notification_types: + type: + - array + - "null" + slack_linked?: + type: + - boolean + - "null" + updated_at: + type: + - string + - "null" + services: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + severity: + type: + - string + - "null" + severity_color: + type: + - string + - "null" + started_at: + type: + - string + - "null" + status_pages: + type: + - array + - "null" + summary: + type: + - string + - "null" + tag_list: + type: + - array + - "null" + items: + type: + - string + - "null" + team_assignments: + type: + - array + - "null" + incident_id: + type: + - string + - "null" + name: + type: + - string + - "null" + questions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + conversations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + channel: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + comments_url: + type: + - string + - "null" + id: + type: + - string + - "null" + resource_class: + type: + - string + - "null" + resource_id: + type: + - string + - "null" + id: + type: + - string + - "null" + is_required: + type: + - boolean + - "null" + kind: + type: + - string + - "null" + question_type_id: + type: + - string + - "null" + title: + type: + - string + - "null" + tooltip: + type: + - string + - "null" + summary: + type: + - string + - "null" + tag_list: + type: + - array + - "null" + updated_at: + type: + - string + - "null" + required: + - id + post_mortems_questions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: string + is_required: + type: + - boolean + - "null" + kind: + type: + - string + - "null" + title: + type: + - string + - "null" + tooltip: + type: + - string + - "null" + required: + - id + alerts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + environments: + type: + - array + - "null" + id: + type: string + incidents: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + number: + type: + - number + - "null" + restricted: + type: + - boolean + - "null" + integration_name: + type: + - string + - "null" + is_expired: + type: + - boolean + - "null" + labels: + type: + - object + - "null" + position: + type: + - number + - "null" + remote_id: + type: + - string + - "null" + remote_url: + type: + - string + - "null" + services: + type: + - array + - "null" + signal_id: + type: + - string + - "null" + source_icon: + type: + - string + - "null" + starts_at: + type: + - string + - "null" + status: + type: + - string + - "null" + summary: + type: + - string + - "null" + tags: + type: + - array + - "null" + required: + - id + tickets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + assignees: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + attachments: + type: + - array + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + id: + type: string + incident_id: + type: + - string + - "null" + priority: + type: + - object + - "null" + properties: + created_at: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + position: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + state: + type: + - string + - "null" + summary: + type: + - string + - "null" + tag_list: + type: + - array + - "null" + items: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + ticketing_projects: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: string + name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + ticketing_priorities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + position: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + required: + - id + ticket_tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + name: + type: string + required: + - name + task_lists: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + checklist_templates: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + checks: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + connected_services: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + alert_on_add: + type: + - boolean + - "null" + auto_add_responding_team: + type: + - boolean + - "null" + completed_checks: + type: + - number + - "null" + created_at: + type: + - string + - "null" + id: + type: + - string + - "null" + labels: + type: + - object + - "null" + properties: + j: + type: + - string + - "null" + name: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + signals_ical_url: + type: + - string + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + service_checklist_updated_at: + type: + - string + - "null" + service_tier: + type: + - number + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + signals_ical_url: + type: + - string + - "null" + slug: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-firehydrant/metadata.yaml b/airbyte-integrations/connectors/source-firehydrant/metadata.yaml new file mode 100644 index 000000000000..d9d7a1770b6c --- /dev/null +++ b/airbyte-integrations/connectors/source-firehydrant/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.firehydrant.io" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-firehydrant + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: b58c3536-7900-439c-80a8-fc2b94460781 + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-firehydrant + githubIssueLabel: source-firehydrant + icon: icon.svg + license: MIT + name: FireHydrant + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/firehydrant + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-fleetio/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-fleetio/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-fleetio/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-fleetio/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-fleetio/metadata.yaml b/airbyte-integrations/connectors/source-fleetio/metadata.yaml index f3adf798f88e..5fbb84984a00 100644 --- a/airbyte-integrations/connectors/source-fleetio/metadata.yaml +++ b/airbyte-integrations/connectors/source-fleetio/metadata.yaml @@ -5,11 +5,11 @@ data: oss: enabled: true connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 13a7652d-1d94-4033-931a-613d22d3cbb3 - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-fleetio githubIssueLabel: source-fleetio icon: icon.svg diff --git a/airbyte-integrations/connectors/source-flexmail/README.md b/airbyte-integrations/connectors/source-flexmail/README.md new file mode 100644 index 000000000000..6f1cec28fd0c --- /dev/null +++ b/airbyte-integrations/connectors/source-flexmail/README.md @@ -0,0 +1,33 @@ +# Flexmail +This directory contains the manifest-only connector for `source-flexmail`. + +The Airbyte connector for [Flexmail](https://flexmail.be/) enables seamless data integration from Flexmail, a comprehensive email marketing platform, into various data warehouses and analytics tools. With this connector, users can efficiently synchronize Flexmail data—such as campaign details, subscriber information, and engagement metrics—allowing for unified insights and advanced reporting across platforms. Perfect for businesses aiming to centralize their marketing data for enhanced visibility and decision-making. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-flexmail:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-flexmail build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-flexmail test +``` + diff --git a/airbyte-integrations/connectors/source-flexmail/acceptance-test-config.yml b/airbyte-integrations/connectors/source-flexmail/acceptance-test-config.yml new file mode 100644 index 000000000000..3e07e14a4743 --- /dev/null +++ b/airbyte-integrations/connectors/source-flexmail/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-flexmail:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-flexmail/icon.svg b/airbyte-integrations/connectors/source-flexmail/icon.svg new file mode 100644 index 000000000000..9e95f293d625 --- /dev/null +++ b/airbyte-integrations/connectors/source-flexmail/icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/airbyte-integrations/connectors/source-flexmail/manifest.yaml b/airbyte-integrations/connectors/source-flexmail/manifest.yaml new file mode 100644 index 000000000000..8760c3316106 --- /dev/null +++ b/airbyte-integrations/connectors/source-flexmail/manifest.yaml @@ -0,0 +1,457 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + The Airbyte connector for [Flexmail](https://flexmail.be/) enables seamless + data integration from Flexmail, a comprehensive email marketing platform, into + various data warehouses and analytics tools. With this connector, users can + efficiently synchronize Flexmail data—such as campaign details, subscriber + information, and engagement metrics—allowing for unified insights and advanced + reporting across platforms. Perfect for businesses aiming to centralize their + marketing data for enhanced visibility and decision-making. + +check: + type: CheckStream + stream_names: + - contacts + +definitions: + streams: + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - item + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 500 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + custom_fields: + type: DeclarativeStream + name: custom_fields + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /custom-fields + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - item + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/custom_fields" + interests: + type: DeclarativeStream + name: interests + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /interests + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - item + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/interests" + segments: + type: DeclarativeStream + name: segments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /segments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - item + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/segments" + sources: + type: DeclarativeStream + name: sources + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /sources + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - item + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 500 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sources" + webhook_events: + type: DeclarativeStream + name: webhook_events + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /webhook-events + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/webhook_events" + base_requester: + type: HttpRequester + url_base: https://api.flexmail.eu + authenticator: + type: BasicHttpAuthenticator + password: "{{ config[\"personal_access_token\"] }}" + username: "{{ config[\"account_id\"] }}" + +streams: + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/custom_fields" + - $ref: "#/definitions/streams/interests" + - $ref: "#/definitions/streams/segments" + - $ref: "#/definitions/streams/sources" + - $ref: "#/definitions/streams/webhook_events" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - account_id + - personal_access_token + properties: + account_id: + type: string + description: >- + Your Flexmail account ID. You can find it in your Flexmail account + settings. + name: account_id + order: 0 + title: Account ID + personal_access_token: + type: string + description: >- + A personal access token for API authentication. Manage your tokens in + Flexmail under Settings > API > Personal access tokens. + name: personal_access_token + order: 1 + title: Personal Access Token + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + contacts: true + custom_fields: true + interests: true + segments: true + sources: true + webhook_events: true + testedStreams: + contacts: + streamHash: 9697aafc0c43eacbdf5543a0866bb1711eb7a99c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + custom_fields: + streamHash: 8e9130174f724b68eac023f7754ad4d7750820f3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + interests: + streamHash: c58d821de8774fffbfa15514e93452676449b542 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + segments: + streamHash: 22bb7e1a7abfacb36b8fa22c0c21175f098842a7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + sources: + streamHash: 505704b58a5f5e7a6e532635df6dbb61e9f2b416 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + webhook_events: + streamHash: 5ff0384abc63be781b90d10dd38dc652f7037c4a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://api.flexmail.eu/documentation + +schemas: + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + sources: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + custom_fields: + type: + - object + - "null" + properties: {} + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + id: + type: number + language: + type: + - string + - "null" + name: + type: + - string + - "null" + required: + - id + custom_fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + placeholder: + type: + - string + - "null" + required: + - id + interests: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + id: + type: string + label: + type: + - string + - "null" + name: + type: + - string + - "null" + visibility: + type: + - string + - "null" + required: + - id + segments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: string + name: + type: + - string + - "null" + number_of_contacts: + type: + - number + - "null" + required: + - id + sources: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + required: + - id + webhook_events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + events: + type: + - array + - "null" + items: + type: + - string + - "null" diff --git a/airbyte-integrations/connectors/source-flexmail/metadata.yaml b/airbyte-integrations/connectors/source-flexmail/metadata.yaml new file mode 100644 index 000000000000..ae2a6a94f7e9 --- /dev/null +++ b/airbyte-integrations/connectors/source-flexmail/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.flexmail.eu" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-flexmail + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 82a2d4b1-9fe3-408a-84b4-bd690426fc15 + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-flexmail + githubIssueLabel: source-flexmail + icon: icon.svg + license: MIT + name: Flexmail + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/flexmail + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-flexport/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-flexport/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-flexport/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-flexport/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-flexport/metadata.yaml b/airbyte-integrations/connectors/source-flexport/metadata.yaml index b988f18d5145..648a19694b1e 100644 --- a/airbyte-integrations/connectors/source-flexport/metadata.yaml +++ b/airbyte-integrations/connectors/source-flexport/metadata.yaml @@ -15,7 +15,7 @@ data: connectorSubtype: api connectorType: source definitionId: f95337f1-2ad1-4baf-922f-2ca9152de630 - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.7 dockerRepository: airbyte/source-flexport githubIssueLabel: source-flexport icon: flexport.svg @@ -32,5 +32,5 @@ data: ql: 100 supportLevel: community connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-float/metadata.yaml b/airbyte-integrations/connectors/source-float/metadata.yaml index f2a13ba386c5..047f241342bf 100644 --- a/airbyte-integrations/connectors/source-float/metadata.yaml +++ b/airbyte-integrations/connectors/source-float/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-float connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.15.0@sha256:09a84e0622f36393077332faf11cc239e77083fae5fa500592c049dca25888a7 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 4f755eb9-6e1a-4b0e-bc1e-26b9f5d3ca4c - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.5 dockerRepository: airbyte/source-float githubIssueLabel: source-float icon: icon.svg diff --git a/airbyte-integrations/connectors/source-flowlu/README.md b/airbyte-integrations/connectors/source-flowlu/README.md new file mode 100644 index 000000000000..c15737041694 --- /dev/null +++ b/airbyte-integrations/connectors/source-flowlu/README.md @@ -0,0 +1,33 @@ +# Flowlu +This directory contains the manifest-only connector for `source-flowlu`. + +Flowlu connector enables seamless data integration between Flowlu, a project management and CRM platform, and various destinations supported by Airbyte. With this connector, users can automate the flow of project, finance, and CRM data into their preferred analytics or storage solutions for enhanced data analysis and reporting. This integration streamlines data syncing, reducing manual data transfer efforts and enhancing productivity. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-flowlu:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-flowlu build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-flowlu test +``` + diff --git a/airbyte-integrations/connectors/source-flowlu/acceptance-test-config.yml b/airbyte-integrations/connectors/source-flowlu/acceptance-test-config.yml new file mode 100644 index 000000000000..5a764c6ae379 --- /dev/null +++ b/airbyte-integrations/connectors/source-flowlu/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-flowlu:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-flowlu/icon.svg b/airbyte-integrations/connectors/source-flowlu/icon.svg new file mode 100644 index 000000000000..170ef8473e0f --- /dev/null +++ b/airbyte-integrations/connectors/source-flowlu/icon.svg @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-flowlu/manifest.yaml b/airbyte-integrations/connectors/source-flowlu/manifest.yaml new file mode 100644 index 000000000000..b65e0ef67cfb --- /dev/null +++ b/airbyte-integrations/connectors/source-flowlu/manifest.yaml @@ -0,0 +1,5022 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Flowlu connector enables seamless data integration between Flowlu, a project + management and CRM platform, and various destinations supported by Airbyte. + With this connector, users can automate the flow of project, finance, and CRM + data into their preferred analytics or storage solutions for enhanced data + analysis and reporting. This integration streamlines data syncing, reducing + manual data transfer efforts and enhancing productivity. + +check: + type: CheckStream + stream_names: + - tasks + +definitions: + streams: + tasks: + type: DeclarativeStream + name: tasks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /task/tasks/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tasks" + custom_fields: + type: DeclarativeStream + name: custom_fields + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /customfields/fields/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/custom_fields" + agile_workflows: + type: DeclarativeStream + name: agile_workflows + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /agile/workflows/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/agile_workflows" + st_projects_users: + type: DeclarativeStream + name: st_projects_users + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /st/project_observers/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/st_projects_users" + projects: + type: DeclarativeStream + name: projects + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /st/projects/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/projects" + account: + type: DeclarativeStream + name: account + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /crm/account/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/account" + agile_epics: + type: DeclarativeStream + name: agile_epics + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /agile/epics/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/agile_epics" + loss_reason: + type: DeclarativeStream + name: loss_reason + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /crm/loss_reason/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/loss_reason" + pipeline: + type: DeclarativeStream + name: pipeline + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /crm/pipeline/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/pipeline" + lead: + type: DeclarativeStream + name: lead + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /crm/lead/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/lead" + emails: + type: DeclarativeStream + name: emails + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /crm/emails/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/emails" + invoice: + type: DeclarativeStream + name: invoice + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /fin/invoice/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/invoice" + customer_payment: + type: DeclarativeStream + name: customer_payment + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /fin/customer_payment/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customer_payment" + bank_account: + type: DeclarativeStream + name: bank_account + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /fin/bank_account/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/bank_account" + agile_stages: + type: DeclarativeStream + name: agile_stages + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /agile/stages/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/agile_stages" + agile_sprints: + type: DeclarativeStream + name: agile_sprints + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /agile/sprints/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/agile_sprints" + agile_issues: + type: DeclarativeStream + name: agile_issues + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /agile/issues/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/agile_issues" + task_lists: + type: DeclarativeStream + name: task_lists + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /task/taskslists/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/task_lists" + lists: + type: DeclarativeStream + name: lists + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /task/lists/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/lists" + calendar: + type: DeclarativeStream + name: calendar + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /calendar/calendar/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/calendar" + agile_issue_relation_types: + type: DeclarativeStream + name: agile_issue_relation_types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /agile/issue_relation_types/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/agile_issue_relation_types" + agile_issue_relation_names: + type: DeclarativeStream + name: agile_issue_relation_names + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /agile/issue_relation_names/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/agile_issue_relation_names" + agile_issue_type: + type: DeclarativeStream + name: agile_issue_type + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /agile/issue_type/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/agile_issue_type" + agile_categories: + type: DeclarativeStream + name: agile_categories + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /agile/categories/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/agile_categories" + custom_fields_field_sets: + type: DeclarativeStream + name: custom_fields_field_sets + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /customfields/fieldsets/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/custom_fields_field_sets" + product_list: + type: DeclarativeStream + name: product_list + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /products/product/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/product_list" + product_categories: + type: DeclarativeStream + name: product_categories + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /products/category/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/product_categories" + product_price_list: + type: DeclarativeStream + name: product_price_list + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /products/pricelist/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/product_price_list" + product_manufacturer: + type: DeclarativeStream + name: product_manufacturer + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /products/manufacturer/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/product_manufacturer" + timesheet: + type: DeclarativeStream + name: timesheet + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /timetracker/timesheets/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/timesheet" + estimates: + type: DeclarativeStream + name: estimates + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /fin/estimate/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/estimates" + transactions: + type: DeclarativeStream + name: transactions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /fin/transaction/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/transactions" + invoice_items: + type: DeclarativeStream + name: invoice_items + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /fin/invoice_item/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/invoice_items" + invoice_contacts: + type: DeclarativeStream + name: invoice_contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /fin/invoice_contacts/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/invoice_contacts" + project_observers: + type: DeclarativeStream + name: project_observers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /st/project_observers/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/project_observers" + task_workflows: + type: DeclarativeStream + name: task_workflows + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /task/workflows/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: body_json + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/task_workflows" + base_requester: + type: HttpRequester + url_base: https://{{ config['company'] }}.flowlu.com/api/v1/module + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: api_key + inject_into: request_parameter + +streams: + - $ref: "#/definitions/streams/tasks" + - $ref: "#/definitions/streams/custom_fields" + - $ref: "#/definitions/streams/agile_workflows" + - $ref: "#/definitions/streams/st_projects_users" + - $ref: "#/definitions/streams/projects" + - $ref: "#/definitions/streams/account" + - $ref: "#/definitions/streams/agile_epics" + - $ref: "#/definitions/streams/loss_reason" + - $ref: "#/definitions/streams/pipeline" + - $ref: "#/definitions/streams/lead" + - $ref: "#/definitions/streams/emails" + - $ref: "#/definitions/streams/invoice" + - $ref: "#/definitions/streams/customer_payment" + - $ref: "#/definitions/streams/bank_account" + - $ref: "#/definitions/streams/agile_stages" + - $ref: "#/definitions/streams/agile_sprints" + - $ref: "#/definitions/streams/agile_issues" + - $ref: "#/definitions/streams/task_lists" + - $ref: "#/definitions/streams/lists" + - $ref: "#/definitions/streams/calendar" + - $ref: "#/definitions/streams/agile_issue_relation_types" + - $ref: "#/definitions/streams/agile_issue_relation_names" + - $ref: "#/definitions/streams/agile_issue_type" + - $ref: "#/definitions/streams/agile_categories" + - $ref: "#/definitions/streams/custom_fields_field_sets" + - $ref: "#/definitions/streams/product_list" + - $ref: "#/definitions/streams/product_categories" + - $ref: "#/definitions/streams/product_price_list" + - $ref: "#/definitions/streams/product_manufacturer" + - $ref: "#/definitions/streams/timesheet" + - $ref: "#/definitions/streams/estimates" + - $ref: "#/definitions/streams/transactions" + - $ref: "#/definitions/streams/invoice_items" + - $ref: "#/definitions/streams/invoice_contacts" + - $ref: "#/definitions/streams/project_observers" + - $ref: "#/definitions/streams/task_workflows" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - company + properties: + api_key: + type: string + description: The API key to use for authentication + name: api_key + order: 0 + title: API Key + airbyte_secret: true + company: + type: string + name: company + order: 1 + title: Company + additionalProperties: true + +metadata: + autoImportSchema: + tasks: true + custom_fields: true + agile_workflows: true + st_projects_users: true + projects: true + account: true + agile_epics: true + loss_reason: true + pipeline: true + lead: true + emails: true + invoice: true + customer_payment: true + bank_account: true + agile_stages: true + agile_sprints: true + agile_issues: true + task_lists: true + lists: true + calendar: true + agile_issue_relation_types: true + agile_issue_relation_names: true + agile_issue_type: true + agile_categories: true + custom_fields_field_sets: true + product_list: true + product_categories: true + product_price_list: true + product_manufacturer: true + timesheet: true + estimates: true + transactions: true + invoice_items: true + invoice_contacts: true + project_observers: true + task_workflows: true + testedStreams: + tasks: + hasRecords: true + streamHash: 4d21cf594aa725599fd06c5ef408cb4606cb8eca + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + custom_fields: + hasRecords: true + streamHash: fe7885829ecedc0f8ceb2096fa6320eed0e91954 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + agile_workflows: + hasRecords: true + streamHash: c1457e272b04375034a467ffb744ceff84451ff8 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + st_projects_users: + hasRecords: true + streamHash: b6b4e8948e4f852465fe2b0ae828cf28cafe5b92 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + projects: + hasRecords: true + streamHash: 472f78d65df39c709377d22cb30e56ddcacd36ed + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + account: + hasRecords: true + streamHash: 6e382ff1c416f7f693a19609a309879f1f1afcdd + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + agile_epics: + hasRecords: true + streamHash: dd7c0643e16c5c38f11f1c822ffe046c1b1c070a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + loss_reason: + hasRecords: true + streamHash: a03f2220a1cf400741e68161f802c1a1ec2a8272 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + pipeline: + hasRecords: true + streamHash: 1315a4bea1c162b8bc635d4737ef046003782bb6 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + lead: + streamHash: 7dacf161994621f8e5f25b08925f043890ce9c6e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + emails: + hasRecords: true + streamHash: 599ca6acbe72953d36a3b14a00744ab169d58371 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + invoice: + hasRecords: true + streamHash: 8c26ab3eeb9ded4581b64b111fd6ee9d1250ad5f + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + customer_payment: + streamHash: 8789e193fc5bfed0567747f074ac9e307df9b28d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + bank_account: + hasRecords: true + streamHash: 5d0b80df2701d5547eca79808bd532feb8dfc2d6 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + agile_stages: + streamHash: 6ec71a29729a2e7037597b2a09c830ad8b6c58dd + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + agile_sprints: + streamHash: 84090469153118dbc987a9c37cf2c799a83e6d2d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + agile_issues: + streamHash: 2dfe1c6fb173ccf02521581efa6ee9006fcf24e7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + task_lists: + hasRecords: true + streamHash: f9ee5cf4140c33dfce4fcc5ad4614702add957ac + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + lists: + hasRecords: true + streamHash: d8435b29cba98887f89abbaefff341e6cb1b6ea2 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + calendar: + hasRecords: true + streamHash: 820c3058e9e99635a08c5bed6a636c91ddba6489 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + agile_issue_relation_types: + streamHash: c7c49d323249db80ebd12c25696b3a8aedc15881 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + agile_issue_relation_names: + streamHash: d325d97845d03febf1789a55afd5cb4c4fc034ee + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + agile_issue_type: + streamHash: c5de0b7196345425586cae50a436443ecb7f4533 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + agile_categories: + streamHash: da5fe66d152a993a89e8aecf5c9c845584de3c5c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + custom_fields_field_sets: + hasRecords: true + streamHash: fe0fc46f7b8609aed7ab2f881741f8f9747432dc + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + product_list: + hasRecords: true + streamHash: ae55e6d3b33655d9417f462760e7476847f066f0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + product_categories: + streamHash: 77477ff0efdf5f63d3214bf50fce6b985f91beb1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + product_price_list: + streamHash: 6d0373a7cd9776a359bdf49099bb9588b900b055 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + product_manufacturer: + streamHash: ab864bebecfa95947fa189acef03afb490aa8a22 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + timesheet: + streamHash: 5d940a9256be572fc15ce9976bda373f41ae4cec + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + estimates: + streamHash: ef0ff9b1004e55e8cc666d035043e27423851e6c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + transactions: + streamHash: e2598f4d0f43fc7b0f37ae256ae83a233b271b20 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + invoice_items: + streamHash: 110a211844ace85ae8dc297049dd97709db80b4f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + invoice_contacts: + streamHash: bbe98bae7f8fee36a8edad2553f5b88b55a9bb09 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + project_observers: + streamHash: f8b4261a5e38ed2d294fd4f2704f0ac54b2bd704 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + task_workflows: + streamHash: dffaca6f0d341a9dddc39f204efdeeb28df44794 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://www.flowlu.com/api/#section/Common-structure + +schemas: + tasks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + description: + type: + - string + - "null" + all_day: + type: + - number + - "null" + archive_status: + type: + - number + - "null" + closed_by: + type: + - number + - "null" + closed_date: + type: + - string + - "null" + cost: + type: + - number + - "null" + cost_type: + type: + - string + - "null" + created_date: + type: + - string + - "null" + crm_account_id: + type: + - number + - "null" + deadline: + type: + - string + - "null" + deadline_allowchange: + type: + - number + - "null" + event_access_type: + type: + - number + - "null" + event_busy_status: + type: + - number + - "null" + event_calendar_id: + type: + - number + - "null" + event_color: + type: + - string + - "null" + event_etag: + type: + - string + - "null" + event_location: + type: + - string + - "null" + event_sync_type: + type: + - number + - "null" + event_type: + type: + - number + - "null" + extra_fields: + type: + - string + - "null" + first_closed_date: + type: + - string + - "null" + id: + type: number + is_archive: + type: + - string + - "null" + is_hidden: + type: + - number + - "null" + is_repeat: + type: + - number + - "null" + model: + type: + - string + - "null" + model_id: + type: + - number + - "null" + module: + type: + - string + - "null" + name: + type: + - string + - "null" + ordering: + type: + - number + - "null" + owner_id: + type: + - number + - "null" + parent_id: + type: + - number + - "null" + plan_end_date: + type: + - string + - "null" + plan_start_date: + type: + - string + - "null" + prev_task_id: + type: + - number + - "null" + price: + type: + - number + - "null" + price_type: + type: + - string + - "null" + priority: + type: + - number + - "null" + project_checkitem_id: + type: + - number + - "null" + project_stage_id: + type: + - number + - "null" + public_template: + type: + - number + - "null" + rating: + type: + - number + - "null" + ref: + type: + - string + - "null" + ref_id: + type: + - string + - "null" + report: + type: + - string + - "null" + report_complete: + type: + - string + - "null" + responsible_id: + type: + - number + - "null" + return_count: + type: + - number + - "null" + start_date: + type: + - string + - "null" + status_firstviewdate: + type: + - string + - "null" + status_updated_by: + type: + - number + - "null" + status_updated_date: + type: + - string + - "null" + task_checkbyowner: + type: + - number + - "null" + template_id: + type: + - number + - "null" + time_estimate: + type: + - number + - "null" + time_spent: + type: + - number + - "null" + updated_by: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + uuid: + type: + - string + - "null" + workflow_id: + type: + - number + - "null" + workflow_stage_id: + type: + - number + - "null" + required: + - id + custom_fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + active: + type: + - number + - "null" + alias: + type: + - string + - "null" + api_use_alias: + type: + - number + - "null" + cache_parent_id: + type: + - number + - "null" + cache_value: + type: + - string + - "null" + fieldset_id: + type: + - number + - "null" + formula: + type: + - string + - "null" + group_id: + type: + - number + - "null" + group_label_field_id: + type: + - number + - "null" + hidden_detail: + type: + - number + - "null" + hint: + type: + - string + - "null" + id: + type: number + model: + type: + - string + - "null" + module: + type: + - string + - "null" + name: + type: + - string + - "null" + ordering: + type: + - number + - "null" + parent_id: + type: + - number + - "null" + required: + type: + - number + - "null" + scope_id: + type: + - number + - "null" + show_in_mobile: + type: + - number + - "null" + show_on_detail_page: + type: + - number + - "null" + webhook_use_alias: + type: + - number + - "null" + required: + - id + agile_workflows: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created_date: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + updated_date: + type: + - string + - "null" + required: + - id + st_projects_users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: + - number + - "null" + project_id: + type: + - number + - "null" + role: + type: + - number + - "null" + user_id: + type: + - number + - "null" + projects: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + archive_date: + type: + - string + - "null" + archive_description: + type: + - string + - "null" + bill_taxes: + type: + - number + - "null" + billing_type: + type: + - number + - "null" + briefcase_id: + type: + - number + - "null" + created_by: + type: + - number + - "null" + created_date: + type: + - string + - "null" + crm_lead_id: + type: + - number + - "null" + customer_crm_contact_id: + type: + - number + - "null" + customer_id: + type: + - number + - "null" + default_bill_time_type: + type: + - string + - "null" + default_billing_rate: + type: + - number + - "null" + default_employee_cost_rate: + type: + - number + - "null" + default_invoice_item_format: + type: + - string + - "null" + default_invoice_split_type_in_project: + type: + - number + - "null" + default_only_completed_task: + type: + - string + - "null" + default_time_cost_type: + type: + - string + - "null" + enddate: + type: + - string + - "null" + estimated_expenses: + type: + - number + - "null" + estimated_revenue: + type: + - number + - "null" + extra_fields: + type: + - string + - "null" + id: + type: number + is_archive: + type: + - number + - "null" + manager_id: + type: + - number + - "null" + name: + type: + - string + - "null" + ordering: + type: + - number + - "null" + priority: + type: + - number + - "null" + project_type_id: + type: + - number + - "null" + ref: + type: + - string + - "null" + ref_id: + type: + - string + - "null" + stage_id: + type: + - number + - "null" + startdate: + type: + - string + - "null" + tasks_workflow_id: + type: + - number + - "null" + updated_by: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + use_default_invoice_split_type: + type: + - number + - "null" + uuid: + type: + - string + - "null" + workspace_id: + type: + - number + - "null" + required: + - id + account: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + description: + type: + - string + - "null" + VAT: + type: + - string + - "null" + VAT1: + type: + - string + - "null" + VAT2: + type: + - string + - "null" + account_category_id: + type: + - number + - "null" + active: + type: + - number + - "null" + address: + type: + - string + - "null" + address_legal: + type: + - string + - "null" + bank_details: + type: + - string + - "null" + billing_address_line_1: + type: + - string + - "null" + billing_address_line_2: + type: + - string + - "null" + billing_address_line_3: + type: + - string + - "null" + billing_city: + type: + - string + - "null" + billing_country: + type: + - string + - "null" + billing_state: + type: + - string + - "null" + billing_zip: + type: + - string + - "null" + created_date: + type: + - string + - "null" + email: + type: + - string + - "null" + email_personal: + type: + - string + - "null" + extra_fields: + type: + - string + - "null" + first_name: + type: + - string + - "null" + guid_1c: + type: + - string + - "null" + honorific_title_id: + type: + - number + - "null" + id: + type: number + industry_id: + type: + - number + - "null" + last_activity_id: + type: + - number + - "null" + last_activity_model: + type: + - string + - "null" + last_activity_time: + type: + - string + - "null" + last_name: + type: + - string + - "null" + link_facebook: + type: + - string + - "null" + link_google: + type: + - string + - "null" + link_instagram: + type: + - string + - "null" + link_linkedin: + type: + - string + - "null" + link_vk: + type: + - string + - "null" + merged_to: + type: + - number + - "null" + middle_name: + type: + - string + - "null" + name: + type: + - string + - "null" + name_legal: + type: + - string + - "null" + name_legal_full: + type: + - string + - "null" + organization_employee_count: + type: + - number + - "null" + organization_expenses: + type: + - number + - "null" + organization_registration_date: + type: + - string + - "null" + organization_revenue: + type: + - number + - "null" + owner_id: + type: + - number + - "null" + phone: + type: + - string + - "null" + phone2: + type: + - string + - "null" + phone3: + type: + - string + - "null" + ref: + type: + - string + - "null" + ref_id: + type: + - number + - "null" + shipping_address_line_1: + type: + - string + - "null" + shipping_address_line_2: + type: + - string + - "null" + shipping_address_line_3: + type: + - string + - "null" + shipping_city: + type: + - string + - "null" + shipping_country: + type: + - string + - "null" + shipping_state: + type: + - string + - "null" + shipping_zip: + type: + - string + - "null" + skype: + type: + - string + - "null" + telegram: + type: + - string + - "null" + timezone: + type: + - string + - "null" + updated_date: + type: + - string + - "null" + web: + type: + - string + - "null" + required: + - id + agile_epics: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created_by: + type: + - number + - "null" + created_date: + type: + - string + - "null" + end_date: + type: + - string + - "null" + id: + type: number + is_completed: + type: + - number + - "null" + name: + type: + - string + - "null" + ordering: + type: + - number + - "null" + project_id: + type: + - number + - "null" + start_date: + type: + - string + - "null" + updated_by: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + required: + - id + loss_reason: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + ordering: + type: + - number + - "null" + required: + - id + pipeline: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + ordering: + type: + - number + - "null" + type_access: + type: + - string + - "null" + lead: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + active: + type: + - number + - "null" + adjustment: + type: + - number + - "null" + adjustment_description: + type: + - string + - "null" + assignee_id: + type: + - number + - "null" + auto_calc: + type: + - string + - "null" + budget: + type: + - number + - "null" + cf_1: + type: + - string + - "null" + cf_2: + type: + - string + - "null" + cf_2_value: + type: + - string + - "null" + closing_comment: + type: + - string + - "null" + closing_date: + type: + - string + - "null" + closing_status_id: + type: + - number + - "null" + contact_company: + type: + - string + - "null" + contact_email: + type: + - string + - "null" + contact_id: + type: + - number + - "null" + contact_mobile: + type: + - string + - "null" + contact_name: + type: + - string + - "null" + contact_phone: + type: + - string + - "null" + contact_position: + type: + - string + - "null" + contact_web: + type: + - string + - "null" + created_by: + type: + - number + - "null" + created_date: + type: + - string + - "null" + customer_id: + type: + - number + - "null" + deadline: + type: + - string + - "null" + id: + type: number + last_activity_id: + type: + - number + - "null" + last_activity_model: + type: + - string + - "null" + last_activity_time: + type: + - string + - "null" + merged_to_id: + type: + - number + - "null" + name: + type: + - string + - "null" + ordering: + type: + - number + - "null" + pipeline_id: + type: + - number + - "null" + pipeline_stage_id: + type: + - number + - "null" + pricelist_id: + type: + - number + - "null" + ref: + type: + - string + - "null" + ref_id: + type: + - number + - "null" + shipping_charge: + type: + - number + - "null" + source_id: + type: + - number + - "null" + start_date: + type: + - string + - "null" + updated_date: + type: + - string + - "null" + required: + - id + emails: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + account_id: + type: + - number + - "null" + comment: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: number + required: + - id + invoice: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + adjustment: + type: + - number + - "null" + adjustment_description: + type: + - string + - "null" + assignee_id: + type: + - number + - "null" + bank: + type: + - string + - "null" + bank_id: + type: + - number + - "null" + bcy_paid_total: + type: + - number + - "null" + bill_from_address: + type: + - string + - "null" + bill_from_city: + type: + - string + - "null" + bill_from_country_id: + type: + - number + - "null" + bill_from_state: + type: + - string + - "null" + bill_from_zip: + type: + - string + - "null" + bill_to_address: + type: + - string + - "null" + bill_to_city: + type: + - string + - "null" + bill_to_country_id: + type: + - number + - "null" + bill_to_state: + type: + - string + - "null" + bill_to_zip: + type: + - string + - "null" + category_id: + type: + - number + - "null" + company_phone: + type: + - string + - "null" + company_phone2: + type: + - string + - "null" + company_vat: + type: + - string + - "null" + company_vat2: + type: + - string + - "null" + contact_person: + type: + - string + - "null" + contact_person2: + type: + - string + - "null" + contact_person2_position: + type: + - string + - "null" + contact_person_position: + type: + - string + - "null" + created_by: + type: + - number + - "null" + created_date: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + currency_id: + type: + - number + - "null" + customer_id: + type: + - number + - "null" + customer_legal_name: + type: + - string + - "null" + customer_name: + type: + - string + - "null" + discount: + type: + - number + - "null" + discount_before_tax: + type: + - number + - "null" + due_date: + type: + - string + - "null" + estimate_id: + type: + - number + - "null" + exported_1c: + type: + - number + - "null" + group_id: + type: + - number + - "null" + id: + type: number + invoice_date: + type: + - string + - "null" + invoice_emailed_date: + type: + - string + - "null" + invoice_footer_text: + type: + - string + - "null" + invoice_number: + type: + - number + - "null" + invoice_number_print: + type: + - string + - "null" + invoice_terms_text: + type: + - string + - "null" + is_discount_percent: + type: + - number + - "null" + is_invoice_emailed: + type: + - number + - "null" + is_reminder_sent: + type: + - number + - "null" + is_template: + type: + - number + - "null" + model: + type: + - string + - "null" + model_id: + type: + - number + - "null" + module: + type: + - string + - "null" + note: + type: + - string + - "null" + org_account_id: + type: + - number + - "null" + org_id: + type: + - number + - "null" + org_phone: + type: + - string + - "null" + org_phone2: + type: + - string + - "null" + org_vat: + type: + - string + - "null" + org_vat2: + type: + - string + - "null" + paid_date: + type: + - string + - "null" + payment_options: + type: + - string + - "null" + paymethod_id: + type: + - number + - "null" + plan_money_id: + type: + - number + - "null" + plan_money_total: + type: + - number + - "null" + pm_currency_id: + type: + - number + - "null" + pricelist_id: + type: + - number + - "null" + ps_currency_id: + type: + - number + - "null" + pscy_paid_total: + type: + - number + - "null" + recurring_invoice_id: + type: + - number + - "null" + ref: + type: + - string + - "null" + ref_id: + type: + - string + - "null" + reference: + type: + - string + - "null" + reminders_sent_date: + type: + - string + - "null" + shipping_charge: + type: + - number + - "null" + show_add_sign_string: + type: + - number + - "null" + status_id: + type: + - number + - "null" + sub_total: + type: + - number + - "null" + tax1: + type: + - number + - "null" + tax1_included: + type: + - number + - "null" + tax2: + type: + - number + - "null" + tax2_included: + type: + - number + - "null" + tax_total: + type: + - number + - "null" + template_id: + type: + - number + - "null" + template_name: + type: + - string + - "null" + total: + type: + - number + - "null" + updated_by: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + use_multiple_pm: + type: + - number + - "null" + uuid: + type: + - string + - "null" + required: + - id + customer_payment: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + description: + type: + - string + - "null" + bank_account_id: + type: + - number + - "null" + charge: + type: + - number + - "null" + complete_date: + type: + - string + - "null" + created_by: + type: + - number + - "null" + created_date: + type: + - string + - "null" + crm_company_id: + type: + - number + - "null" + currency_id: + type: + - number + - "null" + date: + type: + - string + - "null" + enddate: + type: + - string + - "null" + id: + type: number + is_complete: + type: + - number + - "null" + is_manual: + type: + - number + - "null" + is_owed: + type: + - number + - "null" + name: + type: + - string + - "null" + need_approve: + type: + - number + - "null" + ordering: + type: + - number + - "null" + org_id: + type: + - number + - "null" + owner_id: + type: + - number + - "null" + project_id: + type: + - number + - "null" + project_stage_id: + type: + - number + - "null" + ref: + type: + - string + - "null" + ref_id: + type: + - string + - "null" + ref_uuid: + type: + - string + - "null" + reference: + type: + - string + - "null" + startdate: + type: + - string + - "null" + status: + type: + - number + - "null" + status_pls: + type: + - number + - "null" + total: + type: + - number + - "null" + updated_by: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + uuid: + type: + - string + - "null" + required: + - id + bank_account: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + account_group_id: + type: + - number + - "null" + active: + type: + - number + - "null" + bcy_balance: + type: + - number + - "null" + closed_at: + type: + - string + - "null" + currency_exchange_rate: + type: + - number + - "null" + currency_id: + type: + - number + - "null" + excluded_balance: + type: + - number + - "null" + fixed_balance: + type: + - number + - "null" + fixed_balance_date: + type: + - string + - "null" + id: + type: number + manager_id: + type: + - number + - "null" + name: + type: + - string + - "null" + ordering: + type: + - number + - "null" + ordering_by_group: + type: + - number + - "null" + org_id: + type: + - number + - "null" + pls_bcy_balance: + type: + - number + - "null" + pls_fixed_balance: + type: + - number + - "null" + pls_fixed_balance_date: + type: + - string + - "null" + ref: + type: + - string + - "null" + ref_id: + type: + - string + - "null" + required: + - id + agile_stages: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + color: + type: + - string + - "null" + created_date: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + ordering: + type: + - number + - "null" + status: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + workflow_id: + type: + - number + - "null" + required: + - id + agile_sprints: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + active: + type: + - number + - "null" + changelog: + type: + - string + - "null" + created_date: + type: + - string + - "null" + deadline: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + project_id: + type: + - number + - "null" + standup_time: + type: + - string + - "null" + start_date: + type: + - string + - "null" + started: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + required: + - id + agile_issues: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + archived_date: + type: + - string + - "null" + assignee_id: + type: + - number + - "null" + category_id: + type: + - number + - "null" + completed_date: + type: + - string + - "null" + created_date: + type: + - string + - "null" + creator_id: + type: + - number + - "null" + effort: + type: + - number + - "null" + epic_id: + type: + - number + - "null" + estimate: + type: + - number + - "null" + id: + type: number + is_archived: + type: + - number + - "null" + name: + type: + - string + - "null" + number: + type: + - number + - "null" + number_label: + type: + - string + - "null" + ordering: + type: + - number + - "null" + parent_issue_id: + type: + - number + - "null" + priority: + type: + - number + - "null" + project_id: + type: + - number + - "null" + ref: + type: + - string + - "null" + ref_id: + type: + - string + - "null" + sprint_id: + type: + - number + - "null" + type_id: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + value: + type: + - string + - "null" + workflow_stage_id: + type: + - number + - "null" + required: + - id + task_lists: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_by: + type: + - number + - "null" + created_date: + type: + - string + - "null" + id: + type: number + list_id: + type: + - number + - "null" + task_id: + type: + - number + - "null" + updated_by: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + required: + - id + lists: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active: + type: + - number + - "null" + color: + type: + - string + - "null" + created_by: + type: + - number + - "null" + created_date: + type: + - string + - "null" + icon: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + ordering: + type: + - number + - "null" + updated_by: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + user_id: + type: + - number + - "null" + required: + - id + calendar: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + description: + type: + - string + - "null" + color: + type: + - string + - "null" + created_by: + type: + - number + - "null" + created_date: + type: + - string + - "null" + etag: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + sync_type: + type: + - number + - "null" + timezone: + type: + - string + - "null" + updated_by: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + uuid: + type: + - string + - "null" + required: + - id + agile_issue_relation_types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + child_relation_name_id: + type: + - number + - "null" + created_date: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + parent_relation_name_id: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + required: + - id + agile_issue_relation_names: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_date: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + tree_type: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + required: + - id + agile_issue_type: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + description: + type: + - string + - "null" + color: + type: + - string + - "null" + created_date: + type: + - string + - "null" + icon: + type: + - string + - "null" + id: + type: number + is_default: + type: + - number + - "null" + name: + type: + - string + - "null" + ordering: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + required: + - id + agile_categories: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + assignee_id: + type: + - number + - "null" + color: + type: + - string + - "null" + created_date: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + ordering: + type: + - number + - "null" + parent_id: + type: + - number + - "null" + project_id: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + required: + - id + custom_fields_field_sets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + group_field: + type: + - string + - "null" + group_id: + type: + - number + - "null" + id: + type: number + model: + type: + - string + - "null" + module: + type: + - string + - "null" + name: + type: + - string + - "null" + required: + - id + product_list: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + description: + type: + - string + - "null" + active: + type: + - number + - "null" + article: + type: + - string + - "null" + category_id: + type: + - number + - "null" + code: + type: + - string + - "null" + code_ean: + type: + - string + - "null" + code_isbn: + type: + - string + - "null" + code_mpn: + type: + - string + - "null" + code_upc: + type: + - string + - "null" + created: + type: + - string + - "null" + created_by: + type: + - number + - "null" + full_description: + type: + - string + - "null" + id: + type: number + manufacturer_id: + type: + - number + - "null" + name: + type: + - string + - "null" + online_payment_subject_type: + type: + - number + - "null" + online_payment_type: + type: + - number + - "null" + online_payment_vat: + type: + - number + - "null" + pricelist_currency_1: + type: + - string + - "null" + pricelist_price_1: + type: + - string + - "null" + ref: + type: + - string + - "null" + ref_id: + type: + - string + - "null" + tax: + type: + - number + - "null" + tax_desc: + type: + - string + - "null" + tax_included: + type: + - number + - "null" + taxable: + type: + - number + - "null" + unit_id: + type: + - number + - "null" + uom_id: + type: + - number + - "null" + updated: + type: + - string + - "null" + updated_by: + type: + - number + - "null" + required: + - id + product_categories: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + active: + type: + - number + - "null" + created: + type: + - string + - "null" + created_by: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + parent_id: + type: + - number + - "null" + ref: + type: + - string + - "null" + ref_id: + type: + - string + - "null" + updated: + type: + - string + - "null" + updated_by: + type: + - number + - "null" + required: + - id + product_price_list: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + description: + type: + - string + - "null" + active: + type: + - number + - "null" + created: + type: + - string + - "null" + created_by: + type: + - number + - "null" + default: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + ordering: + type: + - number + - "null" + ref: + type: + - string + - "null" + ref_id: + type: + - string + - "null" + updated: + type: + - string + - "null" + updated_by: + type: + - number + - "null" + required: + - id + product_manufacturer: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + active: + type: + - number + - "null" + created: + type: + - string + - "null" + created_by: + type: + - number + - "null" + crm_company_id: + type: + - number + - "null" + currency_id: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + ref: + type: + - string + - "null" + ref_id: + type: + - string + - "null" + updated: + type: + - string + - "null" + updated_by: + type: + - number + - "null" + required: + - id + timesheet: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + aggregated_time_estimate: + type: + - number + - "null" + amount_timeestimate: + type: + - number + - "null" + amount_timespent: + type: + - number + - "null" + bill_amount_timeestimate: + type: + - number + - "null" + bill_amount_timespent: + type: + - number + - "null" + bill_cost_timeestimate: + type: + - number + - "null" + bill_cost_timespent: + type: + - number + - "null" + bill_time: + type: + - number + - "null" + bill_time_estimate: + type: + - number + - "null" + bill_time_type: + type: + - string + - "null" + billing_rate: + type: + - number + - "null" + billing_status: + type: + - number + - "null" + cost_time_type: + type: + - string + - "null" + created_by: + type: + - number + - "null" + created_date: + type: + - string + - "null" + currency_id: + type: + - number + - "null" + employee_cost_rate: + type: + - number + - "null" + id: + type: number + invoice_id: + type: + - number + - "null" + is_billable: + type: + - number + - "null" + is_billable_employee: + type: + - number + - "null" + model: + type: + - string + - "null" + model_id: + type: + - number + - "null" + module: + type: + - string + - "null" + parent_sheet_id: + type: + - number + - "null" + rate: + type: + - number + - "null" + time_estimate: + type: + - number + - "null" + time_spent: + type: + - number + - "null" + unbill_time: + type: + - number + - "null" + unbill_time_estimate: + type: + - number + - "null" + updated_by: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + required: + - id + estimates: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + active: + type: + - number + - "null" + adjustment: + type: + - number + - "null" + adjustment_description: + type: + - string + - "null" + assignee_id: + type: + - number + - "null" + bill_from_address: + type: + - string + - "null" + bill_from_city: + type: + - string + - "null" + bill_from_country_id: + type: + - number + - "null" + bill_from_state: + type: + - string + - "null" + bill_from_zip: + type: + - string + - "null" + bill_to_address: + type: + - string + - "null" + bill_to_city: + type: + - string + - "null" + bill_to_country_id: + type: + - number + - "null" + bill_to_state: + type: + - string + - "null" + bill_to_zip: + type: + - string + - "null" + company_phone: + type: + - string + - "null" + company_phone2: + type: + - string + - "null" + company_vat: + type: + - string + - "null" + company_vat2: + type: + - string + - "null" + contact_person: + type: + - string + - "null" + contact_person_position: + type: + - string + - "null" + created_by: + type: + - number + - "null" + currency_code: + type: + - string + - "null" + currency_id: + type: + - number + - "null" + customer_id: + type: + - number + - "null" + customer_legal_name: + type: + - string + - "null" + customer_name: + type: + - string + - "null" + discount: + type: + - number + - "null" + discount_before_tax: + type: + - number + - "null" + estimate_emailed_date: + type: + - string + - "null" + estimate_footer_text: + type: + - string + - "null" + estimate_number: + type: + - number + - "null" + estimate_number_print: + type: + - string + - "null" + estimate_terms_text: + type: + - string + - "null" + exchange_rate: + type: + - number + - "null" + expire_date: + type: + - string + - "null" + group_id: + type: + - number + - "null" + id: + type: number + invoice_date: + type: + - string + - "null" + is_discount_percent: + type: + - number + - "null" + model: + type: + - string + - "null" + model_id: + type: + - number + - "null" + module: + type: + - string + - "null" + org_id: + type: + - number + - "null" + org_phone: + type: + - string + - "null" + org_phone2: + type: + - string + - "null" + org_vat: + type: + - string + - "null" + org_vat2: + type: + - string + - "null" + pricelist_id: + type: + - number + - "null" + ref: + type: + - string + - "null" + ref_id: + type: + - string + - "null" + reference_number: + type: + - string + - "null" + shipping_charge: + type: + - number + - "null" + status_id: + type: + - number + - "null" + sub_total: + type: + - number + - "null" + tax1: + type: + - number + - "null" + tax1_included: + type: + - number + - "null" + tax2: + type: + - number + - "null" + tax2_included: + type: + - number + - "null" + tax_total: + type: + - number + - "null" + template_id: + type: + - number + - "null" + total: + type: + - number + - "null" + updated_by: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + uuid: + type: + - string + - "null" + required: + - id + transactions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + description: + type: + - string + - "null" + bcy_charge: + type: + - number + - "null" + bcy_income: + type: + - number + - "null" + bcy_outcome: + type: + - number + - "null" + business_line_id: + type: + - number + - "null" + category_id: + type: + - number + - "null" + charge: + type: + - number + - "null" + created_by: + type: + - number + - "null" + created_date: + type: + - string + - "null" + crm_account_id: + type: + - number + - "null" + currency_exchange_rate: + type: + - number + - "null" + currency_id: + type: + - number + - "null" + date: + type: + - string + - "null" + id: + type: number + income: + type: + - number + - "null" + invoice_id: + type: + - number + - "null" + is_charge: + type: + - number + - "null" + is_generated: + type: + - number + - "null" + is_storno: + type: + - number + - "null" + manager_id: + type: + - number + - "null" + name: + type: + - string + - "null" + ordering: + type: + - number + - "null" + org_account_id: + type: + - number + - "null" + org_id: + type: + - number + - "null" + outcome: + type: + - number + - "null" + plan_money_id: + type: + - number + - "null" + plan_money_total: + type: + - number + - "null" + pm_currency_id: + type: + - number + - "null" + project_id: + type: + - number + - "null" + ref: + type: + - string + - "null" + ref_id: + type: + - number + - "null" + ref_uuid: + type: + - string + - "null" + reference: + type: + - string + - "null" + reference_id: + type: + - number + - "null" + status: + type: + - number + - "null" + store_doc_currency_id: + type: + - number + - "null" + store_doc_id: + type: + - number + - "null" + store_doc_total: + type: + - number + - "null" + updated_by: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + uuid: + type: + - string + - "null" + required: + - id + invoice_items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + description: + type: + - string + - "null" + bcy_paid_total: + type: + - number + - "null" + discount: + type: + - string + - "null" + discount_amount: + type: + - number + - "null" + discount_is_percent: + type: + - number + - "null" + id: + type: number + invoice_id: + type: + - number + - "null" + item_id: + type: + - number + - "null" + name: + type: + - string + - "null" + online_payment_subject_type: + type: + - number + - "null" + online_payment_type: + type: + - number + - "null" + online_payment_vat: + type: + - number + - "null" + ordering: + type: + - number + - "null" + paid_date: + type: + - string + - "null" + paid_total: + type: + - number + - "null" + plan_money_id: + type: + - number + - "null" + plan_money_total: + type: + - number + - "null" + quantity: + type: + - number + - "null" + ref: + type: + - string + - "null" + ref_id: + type: + - string + - "null" + sub_total: + type: + - number + - "null" + tax1: + type: + - number + - "null" + tax1_amount: + type: + - number + - "null" + tax1_included: + type: + - number + - "null" + tax2: + type: + - number + - "null" + tax2_amount: + type: + - number + - "null" + tax2_included: + type: + - number + - "null" + tax_displayed: + type: + - string + - "null" + tax_total: + type: + - number + - "null" + total: + type: + - number + - "null" + unit_id: + type: + - number + - "null" + unit_price: + type: + - number + - "null" + required: + - id + invoice_contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + contact_id: + type: + - string + - "null" + email_id: + type: + - number + - "null" + id: + type: number + invoice_emailed: + type: + - number + - "null" + invoice_emailed_date: + type: + - string + - "null" + invoice_id: + type: + - number + - "null" + is_primary: + type: + - number + - "null" + reminders_sent: + type: + - number + - "null" + reminders_sent_date: + type: + - string + - "null" + required: + - id + project_observers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: number + project_id: + type: + - number + - "null" + role: + type: + - number + - "null" + user_id: + type: + - number + - "null" + required: + - id + task_workflows: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + active: + type: + - number + - "null" + created_by: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + ordering: + type: + - number + - "null" + updated_by: + type: + - number + - "null" + updated_date: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-flowlu/metadata.yaml b/airbyte-integrations/connectors/source-flowlu/metadata.yaml new file mode 100644 index 000000000000..662efcddef55 --- /dev/null +++ b/airbyte-integrations/connectors/source-flowlu/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "https:" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-flowlu + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: c9db3f2d-054a-43bc-96cc-0d2843bce018 + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-flowlu + githubIssueLabel: source-flowlu + icon: icon.svg + license: MIT + name: Flowlu + releaseDate: 2024-11-11 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/flowlu + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-formbricks/README.md b/airbyte-integrations/connectors/source-formbricks/README.md new file mode 100644 index 000000000000..11214bd4186a --- /dev/null +++ b/airbyte-integrations/connectors/source-formbricks/README.md @@ -0,0 +1,33 @@ +# Formbricks +This directory contains the manifest-only connector for `source-formbricks`. + +The Airbyte connector for [Formbricks](https://www.formbricks.com/) enables seamless data integration by pulling customer feedback and form data from Formbricks directly into your data warehouse. This connector allows you to automate data syncing for enhanced analytics, providing valuable insights into user behavior and satisfaction across platforms. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-formbricks:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-formbricks build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-formbricks test +``` + diff --git a/airbyte-integrations/connectors/source-formbricks/acceptance-test-config.yml b/airbyte-integrations/connectors/source-formbricks/acceptance-test-config.yml new file mode 100644 index 000000000000..2abb8cfb1d06 --- /dev/null +++ b/airbyte-integrations/connectors/source-formbricks/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-formbricks:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-formbricks/icon.svg b/airbyte-integrations/connectors/source-formbricks/icon.svg new file mode 100644 index 000000000000..975a9a0e48c2 --- /dev/null +++ b/airbyte-integrations/connectors/source-formbricks/icon.svg @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-formbricks/manifest.yaml b/airbyte-integrations/connectors/source-formbricks/manifest.yaml new file mode 100644 index 000000000000..6a281a2c019a --- /dev/null +++ b/airbyte-integrations/connectors/source-formbricks/manifest.yaml @@ -0,0 +1,1120 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + The Airbyte connector for [Formbricks](https://www.formbricks.com/) enables + seamless data integration by pulling customer feedback and form data from + Formbricks directly into your data warehouse. This connector allows you to + automate data syncing for enhanced analytics, providing valuable insights into + user behavior and satisfaction across platforms. + +check: + type: CheckStream + stream_names: + - surveys + +definitions: + streams: + surveys: + type: DeclarativeStream + name: surveys + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /management/surveys + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/surveys" + action_classes: + type: DeclarativeStream + name: action_classes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /management/action-classes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/action_classes" + attribute_classes: + type: DeclarativeStream + name: attribute_classes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /management/attribute-classes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/attribute_classes" + identified_peoples: + type: DeclarativeStream + name: identified_peoples + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /management/people + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/identified_peoples" + responses: + type: DeclarativeStream + name: responses + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /management/responses + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + pagination_strategy: + type: OffsetIncrement + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/responses" + webhooks: + type: DeclarativeStream + name: webhooks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /webhooks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/webhooks" + base_requester: + type: HttpRequester + url_base: https://app.formbricks.com/api/v1 + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: X-API-Key + inject_into: header + +streams: + - $ref: "#/definitions/streams/surveys" + - $ref: "#/definitions/streams/action_classes" + - $ref: "#/definitions/streams/attribute_classes" + - $ref: "#/definitions/streams/identified_peoples" + - $ref: "#/definitions/streams/responses" + - $ref: "#/definitions/streams/webhooks" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + description: >- + API key to use. You can generate and find it in your Postman account + settings. + name: api_key + order: 0 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + surveys: true + action_classes: true + attribute_classes: true + identified_peoples: true + responses: true + webhooks: true + testedStreams: + surveys: + hasRecords: true + streamHash: c8230054f86d9610f3dc97aa3b61294a9214c963 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + action_classes: + hasRecords: true + streamHash: 945c9208a75e601702d8547e66d4f82636b7041c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + attribute_classes: + streamHash: 2ee2f0cd95655ff33cd85043937972bd495f87c0 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + identified_peoples: + streamHash: 5bef3a1a5748d5b2f3a06b2dd740c2ab62ae1108 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + responses: + streamHash: b8ed53771a51c18b206cc2ff9b73374f027780ef + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + webhooks: + hasRecords: true + streamHash: 80c98dada4167d2f9c3cb956d6b826878e1713fa + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://documenter.getpostman.com/view/11026000/2sA3Bq5XEh + +schemas: + surveys: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + delay: + type: + - number + - "null" + displayOption: + type: + - string + - "null" + endings: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + buttonLabel: + type: + - object + - "null" + properties: + default: + type: + - string + - "null" + buttonLink: + type: + - string + - "null" + headline: + type: + - object + - "null" + properties: + default: + type: + - string + - "null" + id: + type: + - string + - "null" + subheader: + type: + - object + - "null" + properties: + default: + type: + - string + - "null" + environmentId: + type: + - string + - "null" + hiddenFields: + type: + - object + - "null" + properties: + enabled: + type: + - boolean + - "null" + fieldIds: + type: + - array + - "null" + id: + type: string + isSingleResponsePerEmailEnabled: + type: + - boolean + - "null" + isVerifyEmailEnabled: + type: + - boolean + - "null" + languages: + type: + - array + - "null" + name: + type: + - string + - "null" + questions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + choices: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + label: + type: + - object + - "null" + properties: + default: + type: + - string + - "null" + headline: + type: + - object + - "null" + properties: + default: + type: + - string + - "null" + id: + type: + - string + - "null" + inputType: + type: + - string + - "null" + isColorCodingEnabled: + type: + - boolean + - "null" + logic: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + actions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + objective: + type: + - string + - "null" + target: + type: + - string + - "null" + conditions: + type: + - object + - "null" + properties: + conditions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + leftOperand: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - string + - "null" + operator: + type: + - string + - "null" + rightOperand: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - number + - "null" + connector: + type: + - string + - "null" + id: + type: + - string + - "null" + id: + type: + - string + - "null" + lowerLabel: + type: + - object + - "null" + properties: + default: + type: + - string + - "null" + placeholder: + type: + - object + - "null" + properties: + default: + type: + - string + - "null" + range: + type: + - number + - "null" + required: + type: + - boolean + - "null" + scale: + type: + - string + - "null" + shuffleOption: + type: + - string + - "null" + subheader: + type: + - object + - "null" + properties: + default: + type: + - string + - "null" + upperLabel: + type: + - object + - "null" + properties: + default: + type: + - string + - "null" + segment: + type: + - object + - "null" + properties: + createdAt: + type: + - string + - "null" + environmentId: + type: + - string + - "null" + filters: + type: + - array + - "null" + id: + type: + - string + - "null" + isPrivate: + type: + - boolean + - "null" + surveys: + type: + - array + - "null" + items: + type: + - string + - "null" + title: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + singleUse: + type: + - object + - "null" + properties: + enabled: + type: + - boolean + - "null" + isEncrypted: + type: + - boolean + - "null" + status: + type: + - string + - "null" + styling: + type: + - object + - "null" + properties: + brandColor: + type: + - object + - "null" + properties: + light: + type: + - string + - "null" + cardArrangement: + type: + - object + - "null" + properties: + appSurveys: + type: + - string + - "null" + linkSurveys: + type: + - string + - "null" + cardBackgroundColor: + type: + - object + - "null" + properties: + light: + type: + - string + - "null" + cardBorderColor: + type: + - object + - "null" + properties: + light: + type: + - string + - "null" + cardShadowColor: + type: + - object + - "null" + properties: + light: + type: + - string + - "null" + hideProgressBar: + type: + - boolean + - "null" + inputBorderColor: + type: + - object + - "null" + properties: + light: + type: + - string + - "null" + inputColor: + type: + - object + - "null" + properties: + light: + type: + - string + - "null" + isDarkModeEnabled: + type: + - boolean + - "null" + isLogoHidden: + type: + - boolean + - "null" + questionColor: + type: + - object + - "null" + properties: + light: + type: + - string + - "null" + roundness: + type: + - number + - "null" + triggers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + actionClass: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + environmentId: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + variables: + type: + - array + - "null" + welcomeCard: + type: + - object + - "null" + properties: + enabled: + type: + - boolean + - "null" + headline: + type: + - object + - "null" + properties: + default: + type: + - string + - "null" + html: + type: + - object + - "null" + properties: + default: + type: + - string + - "null" + showResponseCount: + type: + - boolean + - "null" + timeToFinish: + type: + - boolean + - "null" + required: + - id + action_classes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + environmentId: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + noCodeConfig: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + elementSelector: + type: + - object + - "null" + properties: + innerHtml: + type: + - string + - "null" + urlFilters: + type: + - array + - "null" + updatedAt: + type: + - string + - "null" + required: + - id + attribute_classes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + archived: + type: + - boolean + - "null" + createdAt: + type: + - string + - "null" + environmentId: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + required: + - id + identified_peoples: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attributes: + type: + - object + - "null" + properties: + plan: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + environmentId: + type: + - string + - "null" + id: + type: string + updatedAt: + type: + - string + - "null" + userId: + type: + - string + - "null" + required: + - id + responses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + cm3zf81pymlmve85hi7buqzr: + type: + - string + - "null" + pj3o8kqzpkqcz96mx8bma7lm: + type: + - number + - "null" + thjgnj8qycp2chmxe26phcc6: + type: + - string + - "null" + displayId: + type: + - string + - "null" + finished: + type: + - boolean + - "null" + id: + type: string + meta: + type: + - object + - "null" + properties: + action: + type: + - string + - "null" + country: + type: + - string + - "null" + url: + type: + - string + - "null" + userAgent: + type: + - object + - "null" + properties: + browser: + type: + - string + - "null" + device: + type: + - string + - "null" + os: + type: + - string + - "null" + notes: + type: + - array + - "null" + person: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + userId: + type: + - string + - "null" + personAttributes: + type: + - object + - "null" + properties: + plan: + type: + - string + - "null" + surveyId: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + createdAt: + type: + - string + - "null" + environmentId: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + ttc: + type: + - object + - "null" + properties: + _total: + type: + - number + - "null" + cm3zf81pymlmve85hi7buqzr: + type: + - number + - "null" + pj3o8kqzpkqcz96mx8bma7lm: + type: + - number + - "null" + thjgnj8qycp2chmxe26phcc6: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + variables: + type: + - object + - "null" + required: + - id + webhooks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + environmentId: + type: + - string + - "null" + id: + type: string + source: + type: + - string + - "null" + surveyIds: + type: + - array + - "null" + triggers: + type: + - array + - "null" + items: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + url: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-formbricks/metadata.yaml b/airbyte-integrations/connectors/source-formbricks/metadata.yaml new file mode 100644 index 000000000000..73a2a93a37f5 --- /dev/null +++ b/airbyte-integrations/connectors/source-formbricks/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "app.formbricks.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-formbricks + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 6ee4ad96-368f-4c5a-85cf-d92d4b27a4dd + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-formbricks + githubIssueLabel: source-formbricks + icon: icon.svg + license: MIT + name: Formbricks + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/formbricks + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-free-agent-connector/metadata.yaml b/airbyte-integrations/connectors/source-free-agent-connector/metadata.yaml index fd94c1abc5b9..28ad87b58399 100644 --- a/airbyte-integrations/connectors/source-free-agent-connector/metadata.yaml +++ b/airbyte-integrations/connectors/source-free-agent-connector/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-free-agent-connector connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: e3b1e503-2777-460c-80ef-5d6b41367858 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-free-agent-connector githubIssueLabel: source-free-agent-connector icon: icon.svg diff --git a/airbyte-integrations/connectors/source-freightview/README.md b/airbyte-integrations/connectors/source-freightview/README.md new file mode 100644 index 000000000000..a8c2fadec388 --- /dev/null +++ b/airbyte-integrations/connectors/source-freightview/README.md @@ -0,0 +1,33 @@ +# Freightview +This directory contains the manifest-only connector for `source-freightview`. + +An **Airbyte connector for Freightview** enables seamless data integration by extracting and syncing shipping data from Freightview to your target data warehouses or applications. This connector automates the retrieval of essential shipping details, such as quotes, tracking, and shipment reports, allowing businesses to efficiently analyze and manage logistics operations in a centralized system. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-freightview:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-freightview build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-freightview test +``` + diff --git a/airbyte-integrations/connectors/source-freightview/acceptance-test-config.yml b/airbyte-integrations/connectors/source-freightview/acceptance-test-config.yml new file mode 100644 index 000000000000..0f6c879a08bc --- /dev/null +++ b/airbyte-integrations/connectors/source-freightview/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-freightview:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-freightview/icon.svg b/airbyte-integrations/connectors/source-freightview/icon.svg new file mode 100644 index 000000000000..5834cc9c72c7 --- /dev/null +++ b/airbyte-integrations/connectors/source-freightview/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-freightview/manifest.yaml b/airbyte-integrations/connectors/source-freightview/manifest.yaml new file mode 100644 index 000000000000..6ccbca99e37d --- /dev/null +++ b/airbyte-integrations/connectors/source-freightview/manifest.yaml @@ -0,0 +1,723 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + An **Airbyte connector for Freightview** enables seamless data integration by + extracting and syncing shipping data from Freightview to your target data + warehouses or applications. This connector automates the retrieval of + essential shipping details, such as quotes, tracking, and shipment reports, + allowing businesses to efficiently analyze and manage logistics operations in + a centralized system. + +check: + type: CheckStream + stream_names: + - shipments + +definitions: + streams: + quotes: + type: DeclarativeStream + name: quotes + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /shipments/{{ stream_partition.shipmentId }}/quotes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - quotes + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: + $ref: "#/definitions/streams/shipments" + parent_key: shipmentId + partition_field: shipmentId + primary_key: + - quoteId + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/quotes" + tracking: + type: DeclarativeStream + name: tracking + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /shipments/{{ stream_partition.shipmentId }}/tracking + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: + $ref: "#/definitions/streams/shipments" + parent_key: shipmentId + partition_field: shipmentId + primary_key: + - createdDate + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tracking" + shipments: + type: DeclarativeStream + name: shipments + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('continuationToken') }}" + stop_condition: "{{ response.get('continuationToken') is none }}" + requester: + $ref: "#/definitions/base_requester" + path: /shipments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - shipments + primary_key: + - shipmentId + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/shipments" + base_requester: + type: HttpRequester + url_base: https://api.freightview.com/v2.0 + authenticator: + type: SessionTokenAuthenticator + login_requester: + type: HttpRequester + path: token + url_base: https://api.freightview.com/v2.0/auth + http_method: POST + authenticator: + type: NoAuth + request_headers: {} + request_body_json: + client_id: "{{ config['client_id'] }}" + grant_type: client_credentials + client_secret: "{{ config['client_secret'] }}" + request_parameters: {} + session_token_path: + - access_token + expiration_duration: P1D + request_authentication: + type: Bearer + +streams: + - $ref: "#/definitions/streams/shipments" + - $ref: "#/definitions/streams/quotes" + - $ref: "#/definitions/streams/tracking" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - client_id + - client_secret + properties: + client_id: + type: string + order: 0 + title: Client ID + airbyte_secret: true + client_secret: + type: string + order: 1 + title: Client Secret + airbyte_secret: true + additionalProperties: true + +metadata: + assist: + docsUrl: https://developer.freightview.com/v2/ + openapiSpecUrl: https://developer.freightview.com/freightview-v2.0.min.yaml + testedStreams: + quotes: + hasRecords: true + streamHash: 177dc0c27f597f453ca998cdc8395f8ddc69f535 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + tracking: + hasRecords: true + streamHash: b63b82cb7e3735030dcc3eb68f4dd1b7106c3fbd + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + shipments: + hasRecords: true + streamHash: f5b80d551a70730df5c0fdd5c50d138050cf4681 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + autoImportSchema: + quotes: false + tracking: true + shipments: true + +schemas: + quotes: + type: object + $schema: http://json-schema.org/schema# + required: + - quoteId + properties: + mode: + type: + - string + - "null" + amount: + type: + - number + - "null" + method: + type: + - string + - "null" + source: + type: + - string + - "null" + status: + type: + - string + - "null" + quoteId: + type: string + currency: + type: + - string + - "null" + quoteNum: + type: + - string + - "null" + carrierId: + type: + - string + - "null" + serviceId: + type: + - string + - "null" + createdDate: + type: + - string + - "null" + pricingType: + type: + - string + - "null" + paymentTerms: + type: + - string + - "null" + providerCode: + type: + - string + - "null" + providerName: + type: + - string + - "null" + equipmentType: + type: + - string + - "null" + pricingMethod: + type: + - string + - "null" + additionalProperties: true + tracking: + type: object + $schema: http://json-schema.org/schema# + required: + - createdDate + properties: + summary: + type: + - string + - "null" + eventDate: + type: + - string + - "null" + eventTime: + type: + - string + - "null" + eventType: + type: + - string + - "null" + createdDate: + type: string + additionalProperties: true + shipments: + type: object + $schema: http://json-schema.org/schema# + required: + - shipmentId + properties: + bol: + type: + - object + - "null" + properties: + status: + type: + - string + - "null" + bolNumber: + type: + - string + - "null" + items: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + itemId: + type: + - string + - "null" + weight: + type: + - number + - "null" + contains: + type: + - array + - "null" + quantity: + type: + - number + - "null" + stackable: + type: + - boolean + - "null" + weightUOM: + type: + - string + - "null" + nmfcNumber: + type: + - number + - "null" + nonStandard: + type: + - boolean + - "null" + dropLocationSequence: + type: + - number + - "null" + declaredValueCurrency: + type: + - string + - "null" + pickupLocationSequence: + type: + - number + - "null" + billTo: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + state: + type: + - string + - "null" + address: + type: + - string + - "null" + company: + type: + - string + - "null" + country: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + contactName: + type: + - string + - "null" + contactEmail: + type: + - string + - "null" + contactPhone: + type: + - string + - "null" + pickup: + type: + - object + - "null" + properties: + status: + type: + - string + - "null" + requestedDate: + type: + - string + - "null" + status: + type: + - string + - "null" + refNums: + type: + - array + - "null" + bookedBy: + type: + - string + - "null" + quotedBy: + type: + - string + - "null" + tracking: + type: + - object + - "null" + properties: + status: + type: + - string + - "null" + lastUpdatedDate: + type: + - string + - "null" + direction: + type: + - string + - "null" + documents: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + url: + type: + - string + - "null" + source: + type: + - string + - "null" + fileName: + type: + - string + - "null" + mimeType: + type: + - string + - "null" + uploadDate: + type: + - string + - "null" + downloadUrl: + type: + - string + - "null" + equipment: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + mode: + type: + - string + - "null" + weight: + type: + - number + - "null" + weightUOM: + type: + - string + - "null" + isHazardous: + type: + - boolean + - "null" + accessorials: + type: + - array + - "null" + alternateTypes: + type: + - array + - "null" + locations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + lat: + type: + - number + - "null" + lng: + type: + - number + - "null" + city: + type: + - string + - "null" + state: + type: + - string + - "null" + address: + type: + - string + - "null" + company: + type: + - string + - "null" + country: + type: + - string + - "null" + opensAt: + type: + - string + - "null" + refNums: + type: + - array + - "null" + address2: + type: + - string + - "null" + closesAt: + type: + - string + - "null" + sequence: + type: + - number + - "null" + stopDate: + type: + - string + - "null" + stopType: + type: + - string + - "null" + timezone: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + contactName: + type: + - string + - "null" + accessorials: + type: + - array + - "null" + contactEmail: + type: + - string + - "null" + contactPhone: + type: + - string + - "null" + instructions: + type: + - string + - "null" + stopDateType: + type: + - string + - "null" + bookedDate: + type: + - string + - "null" + isArchived: + type: + - boolean + - "null" + isLiveLoad: + type: + - boolean + - "null" + pickupDate: + type: + - string + - "null" + shipmentId: + type: string + createdDate: + type: + - string + - "null" + selectedQuote: + type: + - object + - "null" + properties: + mode: + type: + - string + - "null" + amount: + type: + - number + - "null" + method: + type: + - string + - "null" + source: + type: + - string + - "null" + status: + type: + - string + - "null" + quoteId: + type: + - string + - "null" + currency: + type: + - string + - "null" + quoteNum: + type: + - string + - "null" + carrierId: + type: + - string + - "null" + serviceId: + type: + - string + - "null" + createdDate: + type: + - string + - "null" + pricingType: + type: + - string + - "null" + paymentTerms: + type: + - string + - "null" + providerCode: + type: + - string + - "null" + providerName: + type: + - string + - "null" + equipmentType: + type: + - string + - "null" + pricingMethod: + type: + - string + - "null" + additionalProperties: true diff --git a/airbyte-integrations/connectors/source-freightview/metadata.yaml b/airbyte-integrations/connectors/source-freightview/metadata.yaml new file mode 100644 index 000000000000..3d3baad6b0b4 --- /dev/null +++ b/airbyte-integrations/connectors/source-freightview/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.freightview.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-freightview + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: aaedb415-d131-468f-84ab-5319d72e02ed + dockerImageTag: 0.0.4 + dockerRepository: airbyte/source-freightview + githubIssueLabel: source-freightview + icon: icon.svg + license: MIT + name: Freightview + releaseDate: 2024-10-28 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/freightview + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-freshbooks/README.md b/airbyte-integrations/connectors/source-freshbooks/README.md new file mode 100644 index 000000000000..08b01a383c6e --- /dev/null +++ b/airbyte-integrations/connectors/source-freshbooks/README.md @@ -0,0 +1,33 @@ +# FreshBooks +This directory contains the manifest-only connector for `source-freshbooks`. + +FreshBooks connector seamlessly syncs invoicing, expenses, and client data from FreshBooks into data warehouses or analytics platforms. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-freshbooks:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-freshbooks build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-freshbooks test +``` + diff --git a/airbyte-integrations/connectors/source-freshbooks/acceptance-test-config.yml b/airbyte-integrations/connectors/source-freshbooks/acceptance-test-config.yml new file mode 100644 index 000000000000..e64c1189e300 --- /dev/null +++ b/airbyte-integrations/connectors/source-freshbooks/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-freshbooks:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-freshbooks/icon.svg b/airbyte-integrations/connectors/source-freshbooks/icon.svg new file mode 100644 index 000000000000..9b4ac79421e5 --- /dev/null +++ b/airbyte-integrations/connectors/source-freshbooks/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-freshbooks/manifest.yaml b/airbyte-integrations/connectors/source-freshbooks/manifest.yaml new file mode 100644 index 000000000000..3acf8f940d8b --- /dev/null +++ b/airbyte-integrations/connectors/source-freshbooks/manifest.yaml @@ -0,0 +1,2086 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + FreshBooks connector seamlessly syncs invoicing, expenses, and client data + from FreshBooks into data warehouses or analytics platforms. + +check: + type: CheckStream + stream_names: + - user + +definitions: + streams: + user: + type: DeclarativeStream + name: user + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /auth/api/v1/users/me + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/user" + clients: + type: DeclarativeStream + name: clients + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounting/account/{{ config["account_id"] }}/users/clients + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - result + - clients + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/clients" + invoices: + type: DeclarativeStream + name: invoices + primary_key: + - id + - invoiceid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounting/account/{{ config['account_id'] }}/invoices/invoices + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - result + - invoices + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/invoices" + expenses: + type: DeclarativeStream + name: expenses + primary_key: + - id + - expenseid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounting/account/{{ config['account_id'] }}/expenses/expenses + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - result + - expenses + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/expenses" + expense_summaries: + type: DeclarativeStream + name: expense_summaries + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounting/account/{{ config["account_id"] }}/expenses/summaries + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - result + - summaries + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/expense_summaries" + expense_categories: + type: DeclarativeStream + name: expense_categories + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounting/account/{{ config["account_id"] }}/expenses/categories + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - result + - categories + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/expense_categories" + invoice_details: + type: DeclarativeStream + name: invoice_details + primary_key: + - invoiceid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /accounting/account/{{ config["account_id"] + }}/reports/accounting/invoice_details + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - result + - invoice_details + - clients + - "*" + - invoices + - "*" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/invoice_details" + expense_details: + type: DeclarativeStream + name: expense_details + primary_key: + - expenseid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /accounting/account/{{ config['account_id'] + }}/reports/accounting/expense_details + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - result + - expense_details + - data + - "*" + - expenses + - "*" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/expense_details" + accounts: + type: DeclarativeStream + name: accounts + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /accounting/businesses/{{ config['business_uuid'] + }}/ledger_accounts/accounts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounts" + taxes: + type: DeclarativeStream + name: taxes + primary_key: + - taxid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounting/account/{{ config["account_id"] }}/taxes/taxes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - response + - result + - taxes + - "*" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/taxes" + base_requester: + type: HttpRequester + url_base: https://api.freshbooks.com + authenticator: + type: OAuthAuthenticator + client_id: "{{ config[\"client_id\"] }}" + grant_type: refresh_token + client_secret: "{{ config[\"client_secret\"] }}" + refresh_token: "{{ config[\"client_refresh_token\"] }}" + refresh_request_body: + redirect_uri: "{{ config[\"redirect_uri\"] }}" + refresh_token_updater: + refresh_token_name: refresh_token + access_token_config_path: + - oauth_access_token + token_expiry_date_config_path: + - oauth_token_expiry_date + refresh_token_config_path: + - client_refresh_token + token_refresh_endpoint: https://api.freshbooks.com/auth/oauth/token + +streams: + - $ref: "#/definitions/streams/user" + - $ref: "#/definitions/streams/clients" + - $ref: "#/definitions/streams/invoices" + - $ref: "#/definitions/streams/expenses" + - $ref: "#/definitions/streams/expense_summaries" + - $ref: "#/definitions/streams/expense_categories" + - $ref: "#/definitions/streams/invoice_details" + - $ref: "#/definitions/streams/expense_details" + - $ref: "#/definitions/streams/accounts" + - $ref: "#/definitions/streams/taxes" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - client_id + - client_secret + - redirect_uri + - account_id + - client_refresh_token + - business_uuid + properties: + client_id: + type: string + order: 0 + title: Client ID + airbyte_secret: true + client_secret: + type: string + order: 1 + title: Client secret + airbyte_secret: true + redirect_uri: + type: string + order: 2 + title: Redirect Uri + airbyte_secret: true + account_id: + type: string + order: 3 + title: Account Id + client_refresh_token: + type: string + order: 4 + title: Refresh token + airbyte_secret: true + oauth_access_token: + type: string + description: >- + The current access token. This field might be overridden by the + connector based on the token refresh endpoint response. + order: 5 + title: Access token + airbyte_secret: true + oauth_token_expiry_date: + type: string + description: >- + The date the current access token expires in. This field might be + overridden by the connector based on the token refresh endpoint + response. + order: 6 + title: Token expiry date + format: date-time + business_uuid: + type: string + order: 7 + title: Business uuid + additionalProperties: true + +metadata: + autoImportSchema: + user: true + clients: true + invoices: true + expenses: true + expense_summaries: true + expense_categories: true + invoice_details: true + expense_details: true + accounts: true + taxes: true + testedStreams: + user: + hasRecords: true + streamHash: 084154685fd57ba95fed5b9a5e68c697a9a98fcc + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + clients: + hasRecords: true + streamHash: 35e9f0487bda5713e6b688ebca713409e707eaf5 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + invoices: + hasRecords: true + streamHash: c583e59892652200fda6b7b0672278b0a859550d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + expenses: + hasRecords: true + streamHash: 2b5c12602f5d15f916ccbcb17749332488e7ff45 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + expense_summaries: + hasRecords: true + streamHash: 958e28c6ad13fef3a7ca192cce4d007217744dfa + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + expense_categories: + hasRecords: true + streamHash: 175f129069e1b76a1aa4e4cc09c720b2432e58f0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + invoice_details: + hasRecords: true + streamHash: b2ea5342d54bed63b89a45a85024677a999f5171 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + expense_details: + hasRecords: true + streamHash: 9b667c02b8aab2f4c21c39b4b7a8d7bc6377f78a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + accounts: + hasRecords: true + streamHash: e393f445f6fa6f1161556aca19e5a9a4dd75bbf2 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + taxes: + streamHash: 12b2752c45f9d92bcc1e51161a53bf54fa9962d2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://www.freshbooks.com/api/start + +schemas: + user: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + response: + type: + - object + - "null" + properties: + addresses: + type: + - array + - "null" + items: + type: + - "null" + - "null" + business_memberships: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + business: + type: + - object + - "null" + properties: + account_id: + type: + - string + - "null" + active: + type: + - boolean + - "null" + address: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + country: + type: + - string + - "null" + id: + type: + - number + - "null" + postal_code: + type: + - string + - "null" + province: + type: + - string + - "null" + street: + type: + - string + - "null" + street2: + type: + - string + - "null" + advanced_accounting_enabled: + type: + - boolean + - "null" + business_clients: + type: + - array + - "null" + business_uuid: + type: + - string + - "null" + date_format: + type: + - string + - "null" + first_day_of_week: + type: + - number + - "null" + id: + type: + - number + - "null" + industry: + type: + - string + - "null" + name: + type: + - string + - "null" + phone_number: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + phone_number: + type: + - string + - "null" + status: + type: + - string + - "null" + timezone: + type: + - string + - "null" + fasttrack_token: + type: + - string + - "null" + id: + type: + - number + - "null" + role: + type: + - string + - "null" + unacknowledged_change: + type: + - boolean + - "null" + business_statuses: + type: + - object + - "null" + properties: + YpZK5G: + type: + - string + - "null" + confirmed_at: + type: + - string + - "null" + created_at: + type: + - string + - "null" + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + groups: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + active: + type: + - boolean + - "null" + business_id: + type: + - number + - "null" + group_id: + type: + - number + - "null" + id: + type: + - number + - "null" + identity_id: + type: + - number + - "null" + identity_uuid: + type: + - string + - "null" + role: + type: + - string + - "null" + id: + type: + - number + - "null" + identity_id: + type: + - number + - "null" + identity_origin: + type: + - string + - "null" + identity_uuid: + type: + - string + - "null" + integrations: + type: + - object + - "null" + language: + type: + - string + - "null" + last_name: + type: + - string + - "null" + links: + type: + - object + - "null" + properties: + me: + type: + - string + - "null" + roles: + type: + - string + - "null" + permissions: + type: + - object + - "null" + properties: + YpZK5G: + type: + - object + - "null" + properties: + BankReconciliation.access: + type: + - boolean + - "null" + BetaHeliosAsyncExpenses.access: + type: + - boolean + - "null" + accountant_partner.limit: + type: + - number + - "null" + accounting_reports_v2_general_ledger.access: + type: + - boolean + - "null" + accounts_payable.access: + type: + - boolean + - "null" + accounts_payable_beta.access: + type: + - boolean + - "null" + accounts_payable_reports.access: + type: + - boolean + - "null" + acss_direct_debit.access: + type: + - boolean + - "null" + advanced_accounting.access: + type: + - boolean + - "null" + andromeda_manual_mileage_tracking.access: + type: + - boolean + - "null" + andromeda_mileage_tracker.dev.access: + type: + - boolean + - "null" + attachments.access: + type: + - boolean + - "null" + audit_log.access: + type: + - boolean + - "null" + audit_log_backend.access: + type: + - boolean + - "null" + audit_log_expense.access: + type: + - boolean + - "null" + auto_bank_import.access: + type: + - boolean + - "null" + bacs_direct_debit.access: + type: + - boolean + - "null" + bacs_direct_debit_mandate.access: + type: + - boolean + - "null" + bacs_fee_cap.limit: + type: + - number + - "null" + bank_import_failure_notifications.access: + type: + - boolean + - "null" + bank_rec_smart_match.access: + type: + - boolean + - "null" + beta_mobile_create_expense_subcategory.access: + type: + - boolean + - "null" + bill_payment_reconciliation.access: + type: + - boolean + - "null" + business_accountant.limit: + type: + - number + - "null" + cardapp_new_payment_methods.access: + type: + - boolean + - "null" + client.limit: + type: + - number + - "null" + core_data_from_es.access: + type: + - boolean + - "null" + credit_notes_payment_method.access: + type: + - boolean + - "null" + credit_reconciliation.access: + type: + - boolean + - "null" + customizable_dashboard.access: + type: + - boolean + - "null" + display_credits_plan_summary.access: + type: + - boolean + - "null" + documents_ocr.access: + type: + - boolean + - "null" + documents_ocr_bill.access: + type: + - boolean + - "null" + documents_ocr_bill_complete.access: + type: + - boolean + - "null" + documents_ocr_bill_plan.access: + type: + - boolean + - "null" + documents_ocr_complete_plan.access: + type: + - boolean + - "null" + documents_ocr_match_expenses.access: + type: + - boolean + - "null" + documents_ocr_plan.access: + type: + - boolean + - "null" + email_verification_with_code_page.access: + type: + - boolean + - "null" + emails_page.access: + type: + - boolean + - "null" + embedded_payroll.access: + type: + - boolean + - "null" + embedded_payroll_journal_entries.access: + type: + - boolean + - "null" + enhanced_project_client_typeahead.access: + type: + - boolean + - "null" + es_migrations.access: + type: + - boolean + - "null" + estimate_convert_to_project.access: + type: + - boolean + - "null" + fiscal_year.access: + type: + - boolean + - "null" + flexcoa_advanced_accounting.access: + type: + - boolean + - "null" + flexcoa_beta_rollout.access: + type: + - boolean + - "null" + flexible_chart_of_accounts.access: + type: + - boolean + - "null" + helios_bulk_actions_invoices.beta.access: + type: + - boolean + - "null" + helios_company_taxes.beta.access: + type: + - boolean + - "null" + helios_dashboard.access: + type: + - boolean + - "null" + helios_expense_rebilling.beta.access: + type: + - boolean + - "null" + helios_invoice_archive.beta.access: + type: + - boolean + - "null" + helios_late_fee_reminder.beta.access: + type: + - boolean + - "null" + helios_manual_mileage_tracking.access: + type: + - boolean + - "null" + helios_push_resource_to_use_execute.beta.access: + type: + - boolean + - "null" + helios_pushnotifications.beta.access: + type: + - boolean + - "null" + helios_rebill_time.access: + type: + - boolean + - "null" + helios_remote_search.beta.access: + type: + - boolean + - "null" + helios_stripe_virtual_terminal.beta.access: + type: + - boolean + - "null" + helios_sync_throttle.beta.access: + type: + - boolean + - "null" + helios_virtual_terminal.beta.access: + type: + - boolean + - "null" + helios_virtual_terminal_advertising.beta.access: + type: + - boolean + - "null" + helios_virtual_terminal_tutorial.beta.access: + type: + - boolean + - "null" + historical_payroll_minimum.access: + type: + - boolean + - "null" + improved_bank_transfer_education_for_clients.access: + type: + - boolean + - "null" + invoice_pdf_email.access: + type: + - boolean + - "null" + ios_beta_payment_schedules.access: + type: + - boolean + - "null" + ios_beta_zendesk_widget.access: + type: + - boolean + - "null" + latest_released_api_version.access: + type: + - boolean + - "null" + launchpad_cards_version.access: + type: + - boolean + - "null" + launchpad_cards_version_with_personalization.access: + type: + - boolean + - "null" + limit_add_businesses.access: + type: + - boolean + - "null" + manual_journal_entries_feature.access: + type: + - boolean + - "null" + metapane_payment_methods_improvement.access: + type: + - boolean + - "null" + mobile_receipt_rebilling.access: + type: + - boolean + - "null" + modern_friendbuy.access: + type: + - boolean + - "null" + mtd_enhancements.access: + type: + - boolean + - "null" + new_payments_page: + type: + - boolean + - "null" + new_setup_quiz.access: + type: + - boolean + - "null" + no_seat_employee.access: + type: + - boolean + - "null" + opus_items_services_page.access: + type: + - boolean + - "null" + opus_my_team_page.access: + type: + - boolean + - "null" + outstanding_invoices_summary.access: + type: + - boolean + - "null" + partial_payments.access: + type: + - boolean + - "null" + payment_links.access: + type: + - boolean + - "null" + payments_withdrawal_report.access: + type: + - boolean + - "null" + paypal_gateway.access: + type: + - boolean + - "null" + paypal_tiered_pricing.access: + type: + - boolean + - "null" + payroll_notifications.access: + type: + - boolean + - "null" + payroll_user_invite.access: + type: + - boolean + - "null" + plaid_integration.access: + type: + - boolean + - "null" + premium_contractor_role.access: + type: + - boolean + - "null" + project_line_items.access: + type: + - boolean + - "null" + project_profitability.access: + type: + - boolean + - "null" + project_service_estimates.access: + type: + - boolean + - "null" + project_widget_updates.access: + type: + - boolean + - "null" + proposals_candidate.access: + type: + - boolean + - "null" + recurring_ach.access: + type: + - boolean + - "null" + recurring_paypal.access: + type: + - boolean + - "null" + recurring_revenue_monarch_updates.access: + type: + - boolean + - "null" + refunds.access: + type: + - boolean + - "null" + retained_earnings.access: + type: + - boolean + - "null" + retainers.limit: + type: + - number + - "null" + retainers_feature.access: + type: + - boolean + - "null" + rich_proposals.access: + type: + - boolean + - "null" + rounded_time_tracking.access: + type: + - boolean + - "null" + sales_managed_receipt.access: + type: + - boolean + - "null" + saltedge_integration.access: + type: + - boolean + - "null" + save_emails.access: + type: + - boolean + - "null" + scopes_ui_phase1.access: + type: + - boolean + - "null" + sepa_direct_debit.access: + type: + - boolean + - "null" + sepa_direct_debit_mandate.access: + type: + - boolean + - "null" + sepa_fee_cap.limit: + type: + - number + - "null" + solvvy_support_chat.access: + type: + - boolean + - "null" + staff.limit: + type: + - number + - "null" + stripe_ach.access: + type: + - boolean + - "null" + stripe_advanced_payments.access: + type: + - boolean + - "null" + stripe_payments_intent.access: + type: + - boolean + - "null" + stripe_unified_account.access: + type: + - boolean + - "null" + team_members.access: + type: + - boolean + - "null" + team_utilization_report.access: + type: + - boolean + - "null" + ted_report_refactor.access: + type: + - boolean + - "null" + time_entry_billed_amount.access: + type: + - boolean + - "null" + time_zone_enhancement.access: + type: + - boolean + - "null" + wepay_kyc_redirect.access: + type: + - boolean + - "null" + yodlee_fastlink_upgrade.access: + type: + - boolean + - "null" + phone_numbers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + title: + type: + - string + - "null" + profile: + type: + - object + - "null" + properties: + first_name: + type: + - string + - "null" + has_password: + type: + - boolean + - "null" + is_email_confirmed: + type: + - boolean + - "null" + last_name: + type: + - string + - "null" + professions: + type: + - array + - "null" + setup_complete: + type: + - boolean + - "null" + time_format: + type: + - number + - "null" + timezone: + type: + - string + - "null" + roles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + accountid: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: + - number + - "null" + links: + type: + - object + - "null" + properties: + destroy: + type: + - string + - "null" + role: + type: + - string + - "null" + systemid: + type: + - number + - "null" + userid: + type: + - number + - "null" + setup_complete: + type: + - boolean + - "null" + subscription_statuses: + type: + - object + - "null" + properties: + YpZK5G: + type: + - string + - "null" + timezone: + type: + - string + - "null" + clients: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accounting_systemid: + type: + - string + - "null" + allow_email_include_pdf: + type: + - boolean + - "null" + allow_late_fees: + type: + - boolean + - "null" + allow_late_notifications: + type: + - boolean + - "null" + bus_phone: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + email: + type: + - string + - "null" + exceeds_client_limit: + type: + - number + - "null" + fax: + type: + - string + - "null" + fname: + type: + - string + - "null" + id: + type: + - number + - "null" + language: + type: + - string + - "null" + level: + type: + - number + - "null" + lname: + type: + - string + - "null" + mob_phone: + type: + - string + - "null" + notified: + type: + - boolean + - "null" + num_logins: + type: + - number + - "null" + organization: + type: + - string + - "null" + p_city: + type: + - string + - "null" + p_code: + type: + - string + - "null" + p_country: + type: + - string + - "null" + p_province: + type: + - string + - "null" + p_street: + type: + - string + - "null" + p_street2: + type: + - string + - "null" + pref_email: + type: + - boolean + - "null" + pref_gmail: + type: + - boolean + - "null" + role: + type: + - string + - "null" + s_city: + type: + - string + - "null" + s_code: + type: + - string + - "null" + s_country: + type: + - string + - "null" + s_province: + type: + - string + - "null" + s_street: + type: + - string + - "null" + s_street2: + type: + - string + - "null" + signup_date: + type: + - string + - "null" + updated: + type: + - string + - "null" + userid: + type: + - number + - "null" + username: + type: + - string + - "null" + uuid: + type: + - string + - "null" + vis_state: + type: + - number + - "null" + invoices: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} + expenses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - string + - "null" + account_name: + type: + - string + - "null" + accounting_systemid: + type: + - string + - "null" + amount: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + code: + type: + - string + - "null" + bank_name: + type: + - string + - "null" + bill_matches: + type: + - array + - "null" + billable: + type: + - boolean + - "null" + categoryid: + type: + - number + - "null" + clientid: + type: + - number + - "null" + compounded_tax: + type: + - boolean + - "null" + date: + type: + - string + - "null" + expenseid: + type: number + ext_invoiceid: + type: + - number + - "null" + ext_systemid: + type: + - number + - "null" + from_bulk_import: + type: + - boolean + - "null" + has_receipt: + type: + - boolean + - "null" + id: + type: number + include_receipt: + type: + - boolean + - "null" + is_cogs: + type: + - boolean + - "null" + isduplicate: + type: + - boolean + - "null" + markup_percent: + type: + - string + - "null" + notes: + type: + - string + - "null" + potential_bill_payment: + type: + - boolean + - "null" + projectid: + type: + - number + - "null" + staffid: + type: + - number + - "null" + status: + type: + - number + - "null" + updated: + type: + - string + - "null" + vis_state: + type: + - number + - "null" + required: + - id + - expenseid + expense_summaries: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + amounts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + code: + type: + - string + - "null" + count: + type: + - number + - "null" + counts: + type: + - number + - "null" + id: + type: + - string + - "null" + expense_categories: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + category: + type: + - string + - "null" + categoryid: + type: + - number + - "null" + created_at: + type: + - string + - "null" + id: + type: number + is_cogs: + type: + - boolean + - "null" + is_editable: + type: + - boolean + - "null" + parentid: + type: + - number + - "null" + transaction_posted: + type: + - boolean + - "null" + updated_at: + type: + - string + - "null" + vis_state: + type: + - number + - "null" + required: + - id + invoice_details: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + create_date: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + discount_total: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + code: + type: + - string + - "null" + due_offset_days: + type: + - number + - "null" + invoice_number: + type: + - string + - "null" + invoiceid: + type: number + lines: + type: + - array + - "null" + outstanding: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + code: + type: + - string + - "null" + paid: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + code: + type: + - string + - "null" + subtotal: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + code: + type: + - string + - "null" + tax: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + code: + type: + - string + - "null" + tax_summaries: + type: + - array + - "null" + total: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + code: + type: + - string + - "null" + v3_status: + type: + - string + - "null" + required: + - invoiceid + expense_details: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account_name: + type: + - string + - "null" + amount: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + code: + type: + - string + - "null" + authorid: + type: + - string + - "null" + categoryid: + type: + - string + - "null" + clientid: + type: + - string + - "null" + date: + type: + - string + - "null" + expenseid: + type: number + imported_from_csv: + type: + - boolean + - "null" + is_cogs: + type: + - boolean + - "null" + notes: + type: + - string + - "null" + taxAmount1: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + code: + type: + - string + - "null" + taxAmount2: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + code: + type: + - string + - "null" + vendor: + type: + - string + - "null" + vendorid: + type: + - string + - "null" + required: + - expenseid + accounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + data: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + auto_created: + type: + - boolean + - "null" + name: + type: + - string + - "null" + number: + type: + - string + - "null" + parent_account: + type: + - string + - "null" + state: + type: + - string + - "null" + sub_accounts: + type: + - array + - "null" + items: + type: + - string + - "null" + sub_type: + type: + - string + - "null" + system_account_name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + uuid: + type: + - string + - "null" + taxes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accounting_systemid: + type: + - string + - "null" + amount: + type: + - string + - "null" + compound: + type: + - boolean + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + taxid: + type: number + updated: + type: + - string + - "null" + required: + - taxid diff --git a/airbyte-integrations/connectors/source-freshbooks/metadata.yaml b/airbyte-integrations/connectors/source-freshbooks/metadata.yaml new file mode 100644 index 000000000000..d8d009e04356 --- /dev/null +++ b/airbyte-integrations/connectors/source-freshbooks/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.freshbooks.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-freshbooks + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: e1e86c88-fdd6-41d3-9516-3564021a1902 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-freshbooks + githubIssueLabel: source-freshbooks + icon: icon.svg + license: MIT + name: FreshBooks + releaseDate: 2024-10-27 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/freshbooks + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-freshcaller/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-freshcaller/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-freshcaller/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-freshcaller/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-freshcaller/main.py b/airbyte-integrations/connectors/source-freshcaller/main.py index 7039ceb25a6d..c990d3691ce9 100644 --- a/airbyte-integrations/connectors/source-freshcaller/main.py +++ b/airbyte-integrations/connectors/source-freshcaller/main.py @@ -4,5 +4,6 @@ from source_freshcaller.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-freshcaller/metadata.yaml b/airbyte-integrations/connectors/source-freshcaller/metadata.yaml index f61fb7af45e7..f597fc8135f1 100644 --- a/airbyte-integrations/connectors/source-freshcaller/metadata.yaml +++ b/airbyte-integrations/connectors/source-freshcaller/metadata.yaml @@ -3,7 +3,7 @@ data: ql: 100 sl: 200 connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorTestSuitesOptions: - suite: liveTests @@ -19,7 +19,7 @@ data: type: GSM connectorType: source definitionId: 8a5d48f6-03bb-4038-a942-a8d3f175cca3 - dockerImageTag: 0.4.18 + dockerImageTag: 0.4.21 dockerRepository: airbyte/source-freshcaller documentationUrl: https://docs.airbyte.com/integrations/sources/freshcaller githubIssueLabel: source-freshcaller diff --git a/airbyte-integrations/connectors/source-freshcaller/poetry.lock b/airbyte-integrations/connectors/source-freshcaller/poetry.lock index 5f0917f08200..22729f3b5438 100644 --- a/airbyte-integrations/connectors/source-freshcaller/poetry.lock +++ b/airbyte-integrations/connectors/source-freshcaller/poetry.lock @@ -53,19 +53,19 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -131,127 +131,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -267,20 +254,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -358,13 +345,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -477,13 +464,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -618,54 +605,54 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -733,13 +720,13 @@ files = [ [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] @@ -916,44 +903,74 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] name = "tomli" -version = "2.0.2" +version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] [[package]] @@ -994,13 +1011,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1025,81 +1042,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-freshcaller/pyproject.toml b/airbyte-integrations/connectors/source-freshcaller/pyproject.toml index 6ef3feb44c3f..ec24dfac89d6 100644 --- a/airbyte-integrations/connectors/source-freshcaller/pyproject.toml +++ b/airbyte-integrations/connectors/source-freshcaller/pyproject.toml @@ -3,7 +3,7 @@ requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.4.18" +version = "0.4.21" name = "source-freshcaller" description = "Source implementation for Freshcaller" authors = ["Airbyte "] diff --git a/airbyte-integrations/connectors/source-freshcaller/source_freshcaller/run.py b/airbyte-integrations/connectors/source-freshcaller/source_freshcaller/run.py index b6757d75d1aa..d4c01966794a 100644 --- a/airbyte-integrations/connectors/source-freshcaller/source_freshcaller/run.py +++ b/airbyte-integrations/connectors/source-freshcaller/source_freshcaller/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_freshcaller import SourceFreshcaller +from airbyte_cdk.entrypoint import launch + def run(): source = SourceFreshcaller() diff --git a/airbyte-integrations/connectors/source-freshcaller/source_freshcaller/source.py b/airbyte-integrations/connectors/source-freshcaller/source_freshcaller/source.py index 61eb6c017422..edfa285746a6 100644 --- a/airbyte-integrations/connectors/source-freshcaller/source_freshcaller/source.py +++ b/airbyte-integrations/connectors/source-freshcaller/source_freshcaller/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-freshdesk/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-freshdesk/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-freshdesk/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-freshdesk/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-freshdesk/main.py b/airbyte-integrations/connectors/source-freshdesk/main.py index d32eaa6ca9e5..dc9d287ffe12 100644 --- a/airbyte-integrations/connectors/source-freshdesk/main.py +++ b/airbyte-integrations/connectors/source-freshdesk/main.py @@ -4,5 +4,6 @@ from source_freshdesk.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-freshdesk/source_freshdesk/components.py b/airbyte-integrations/connectors/source-freshdesk/source_freshdesk/components.py index 3c87fa809e6a..62c441218c17 100644 --- a/airbyte-integrations/connectors/source-freshdesk/source_freshdesk/components.py +++ b/airbyte-integrations/connectors/source-freshdesk/source_freshdesk/components.py @@ -4,6 +4,7 @@ from typing import Any, List, Mapping, MutableMapping, Optional import requests + from airbyte_cdk.sources.declarative.incremental import DatetimeBasedCursor from airbyte_cdk.sources.declarative.requesters.http_requester import HttpRequester from airbyte_cdk.sources.declarative.requesters.paginators.strategies.page_increment import PageIncrement @@ -109,7 +110,9 @@ def get_request_params( start_time = stream_slice.get(self._partition_field_start.eval(self.config)) if not self.updated_slice else self.updated_slice options[self.start_time_option.field_name.eval(config=self.config)] = start_time # type: ignore # field_name is always casted to an interpolated string if self.end_time_option and self.end_time_option.inject_into == option_type: - options[self.end_time_option.field_name.eval(config=self.config)] = stream_slice.get(self._partition_field_end.eval(self.config)) # type: ignore # field_name is always casted to an interpolated string + options[self.end_time_option.field_name.eval(config=self.config)] = stream_slice.get( + self._partition_field_end.eval(self.config) + ) # type: ignore # field_name is always casted to an interpolated string return options diff --git a/airbyte-integrations/connectors/source-freshdesk/unit_tests/test_300_page.py b/airbyte-integrations/connectors/source-freshdesk/unit_tests/test_300_page.py index 982a82aa8163..533d78205ce1 100644 --- a/airbyte-integrations/connectors/source-freshdesk/unit_tests/test_300_page.py +++ b/airbyte-integrations/connectors/source-freshdesk/unit_tests/test_300_page.py @@ -3,9 +3,10 @@ # import pytest -from airbyte_cdk.models import SyncMode from conftest import find_stream +from airbyte_cdk.models import SyncMode + @pytest.fixture(name="responses") def responses_fixtures(): diff --git a/airbyte-integrations/connectors/source-freshdesk/unit_tests/test_incremental_sync.py b/airbyte-integrations/connectors/source-freshdesk/unit_tests/test_incremental_sync.py index 619ad510a506..cf598caf2629 100644 --- a/airbyte-integrations/connectors/source-freshdesk/unit_tests/test_incremental_sync.py +++ b/airbyte-integrations/connectors/source-freshdesk/unit_tests/test_incremental_sync.py @@ -2,9 +2,10 @@ import pytest -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOptionType from source_freshdesk.components import FreshdeskTicketsIncrementalSync +from airbyte_cdk.sources.declarative.requesters.request_option import RequestOptionType + class TestFreshdeskTicketsIncrementalSync: @pytest.mark.parametrize( diff --git a/airbyte-integrations/connectors/source-freshdesk/unit_tests/test_pagination_strategy.py b/airbyte-integrations/connectors/source-freshdesk/unit_tests/test_pagination_strategy.py index 4cdcf74fe6c1..e5ac47ab81b5 100644 --- a/airbyte-integrations/connectors/source-freshdesk/unit_tests/test_pagination_strategy.py +++ b/airbyte-integrations/connectors/source-freshdesk/unit_tests/test_pagination_strategy.py @@ -8,7 +8,6 @@ class TestFreshdeskTicketsPaginationStrategy: - # returns None when there are fewer records than the page size @pytest.mark.parametrize( "response, current_page, last_records, expected", diff --git a/airbyte-integrations/connectors/source-freshdesk/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-freshdesk/unit_tests/test_streams.py index 1e5a1444574c..2ca8dc18a996 100644 --- a/airbyte-integrations/connectors/source-freshdesk/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-freshdesk/unit_tests/test_streams.py @@ -6,9 +6,10 @@ from typing import Any, MutableMapping import pytest +from conftest import find_stream + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.streams import Stream -from conftest import find_stream def _read_full_refresh(stream_instance: Stream): diff --git a/airbyte-integrations/connectors/source-freshsales/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-freshsales/integration_tests/acceptance.py index efc25f08ce82..78b220cebb18 100644 --- a/airbyte-integrations/connectors/source-freshsales/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-freshsales/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-freshsales/metadata.yaml b/airbyte-integrations/connectors/source-freshsales/metadata.yaml index a9f7e57a1f3c..0092272e451d 100644 --- a/airbyte-integrations/connectors/source-freshsales/metadata.yaml +++ b/airbyte-integrations/connectors/source-freshsales/metadata.yaml @@ -18,11 +18,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: eca08d79-7b92-4065-b7f3-79c14836ebe7 - dockerImageTag: 1.1.1 + dockerImageTag: 1.1.5 releases: breakingChanges: 1.0.0: diff --git a/airbyte-integrations/connectors/source-freshservice/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-freshservice/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-freshservice/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-freshservice/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-freshservice/metadata.yaml b/airbyte-integrations/connectors/source-freshservice/metadata.yaml index 1aad1017da75..b41e38ba44c7 100644 --- a/airbyte-integrations/connectors/source-freshservice/metadata.yaml +++ b/airbyte-integrations/connectors/source-freshservice/metadata.yaml @@ -3,11 +3,11 @@ data: hosts: - ${domain_name}/api/v2 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 9bb85338-ea95-4c93-b267-6be89125b267 - dockerImageTag: 1.4.3 + dockerImageTag: 1.4.8 dockerRepository: airbyte/source-freshservice documentationUrl: https://docs.airbyte.com/integrations/sources/freshservice githubIssueLabel: source-freshservice diff --git a/airbyte-integrations/connectors/source-front/metadata.yaml b/airbyte-integrations/connectors/source-front/metadata.yaml index ca61d9cb4574..0ac7ccfcc2b2 100644 --- a/airbyte-integrations/connectors/source-front/metadata.yaml +++ b/airbyte-integrations/connectors/source-front/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-front connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.3@sha256:9214270d83304213977c08e91fd9c55a98819543dbbf0df25a4356299af4f3ab connectorSubtype: api connectorType: source definitionId: ae390de9-bdd5-4bfa-9d14-34010b44ca50 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.5 dockerRepository: airbyte/source-front githubIssueLabel: source-front icon: icon.svg diff --git a/airbyte-integrations/connectors/source-fulcrum/README.md b/airbyte-integrations/connectors/source-fulcrum/README.md new file mode 100644 index 000000000000..81b2080b240c --- /dev/null +++ b/airbyte-integrations/connectors/source-fulcrum/README.md @@ -0,0 +1,33 @@ +# Fulcrum +This directory contains the manifest-only connector for `source-fulcrum`. + +Airbyte connector for Fulcrum would enable seamless data extraction from the Fulcrum platform, allowing users to sync survey and field data with their data warehouses or other applications. This connector would facilitate automated, scheduled transfers of structured data, improving analytics, reporting, and decision-making processes by integrating Fulcrum's powerful field data collection capabilities with a broader data ecosystem. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-fulcrum:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-fulcrum build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-fulcrum test +``` + diff --git a/airbyte-integrations/connectors/source-fulcrum/acceptance-test-config.yml b/airbyte-integrations/connectors/source-fulcrum/acceptance-test-config.yml new file mode 100644 index 000000000000..60a47f6dc40b --- /dev/null +++ b/airbyte-integrations/connectors/source-fulcrum/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-fulcrum:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-fulcrum/icon.svg b/airbyte-integrations/connectors/source-fulcrum/icon.svg new file mode 100644 index 000000000000..3454abda99c5 --- /dev/null +++ b/airbyte-integrations/connectors/source-fulcrum/icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/airbyte-integrations/connectors/source-fulcrum/manifest.yaml b/airbyte-integrations/connectors/source-fulcrum/manifest.yaml new file mode 100644 index 000000000000..3e7b5e3154a9 --- /dev/null +++ b/airbyte-integrations/connectors/source-fulcrum/manifest.yaml @@ -0,0 +1,3028 @@ +version: 5.14.0 + +type: DeclarativeSource + +description: >- + Airbyte connector for Fulcrum would enable seamless data extraction from the + Fulcrum platform, allowing users to sync survey and field data with their data + warehouses or other applications. This connector would facilitate automated, + scheduled transfers of structured data, improving analytics, reporting, and + decision-making processes by integrating Fulcrum's powerful field data + collection capabilities with a broader data ecosystem. + +check: + type: CheckStream + stream_names: + - forms + +definitions: + streams: + forms: + type: DeclarativeStream + name: forms + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/forms.json + http_method: GET + request_parameters: + type: all + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - forms + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/forms" + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/users.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - user + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + workflows: + type: DeclarativeStream + name: workflows + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/workflows.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - workflows + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/workflows" + webhooks: + type: DeclarativeStream + name: webhooks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/webhooks.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - webhooks + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/webhooks" + changesets: + type: DeclarativeStream + name: changesets + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/changesets.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - changesets + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/changesets" + records: + type: DeclarativeStream + name: records + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/records.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - records + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/records" + signatures: + type: DeclarativeStream + name: signatures + primary_key: + - record_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/signatures.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - signatures + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/signatures" + projects: + type: DeclarativeStream + name: projects + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/projects.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - projects + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/projects" + layers: + type: DeclarativeStream + name: layers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/layers.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - layers + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/layers" + classification_sets: + type: DeclarativeStream + name: classification_sets + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/classification_sets.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - classification_sets + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/classification_sets" + choice_lists: + type: DeclarativeStream + name: choice_lists + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/choice_lists.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - choice_lists + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/choice_lists" + groups: + type: DeclarativeStream + name: groups + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/groups.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - groups + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/groups" + memberships: + type: DeclarativeStream + name: memberships + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/memberships.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - memberships + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/memberships" + roles: + type: DeclarativeStream + name: roles + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: api/v2/roles.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - roles + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/roles" + authorizations: + type: DeclarativeStream + name: authorizations + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/authorizations.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - authorizations + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/authorizations" + photos: + type: DeclarativeStream + name: photos + primary_key: + - record_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/photos.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - photos + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: current_page + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/photos" + audio: + type: DeclarativeStream + name: audio + primary_key: + - record_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/audio.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - audio + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/audio" + videos: + type: DeclarativeStream + name: videos + primary_key: + - record_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/videos.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - videos + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/videos" + base_requester: + type: HttpRequester + url_base: https://api.fulcrumapp.com + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: X-ApiToken + inject_into: header + +streams: + - $ref: "#/definitions/streams/forms" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/workflows" + - $ref: "#/definitions/streams/webhooks" + - $ref: "#/definitions/streams/changesets" + - $ref: "#/definitions/streams/records" + - $ref: "#/definitions/streams/signatures" + - $ref: "#/definitions/streams/projects" + - $ref: "#/definitions/streams/layers" + - $ref: "#/definitions/streams/classification_sets" + - $ref: "#/definitions/streams/choice_lists" + - $ref: "#/definitions/streams/groups" + - $ref: "#/definitions/streams/memberships" + - $ref: "#/definitions/streams/roles" + - $ref: "#/definitions/streams/authorizations" + - $ref: "#/definitions/streams/photos" + - $ref: "#/definitions/streams/audio" + - $ref: "#/definitions/streams/videos" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + description: API key to use. Find it at https://web.fulcrumapp.com/settings/api + name: api_key + order: 0 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + forms: true + users: false + workflows: false + webhooks: true + changesets: true + records: true + signatures: true + projects: true + layers: true + classification_sets: true + choice_lists: true + groups: true + memberships: true + roles: true + authorizations: true + photos: false + audio: false + videos: false + testedStreams: + forms: + streamHash: d701e2df9f720df416aaa5c9b4e7a6a2a2a56252 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + users: + streamHash: 524af7e9234688de6994edb27292be6ce7d82346 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + workflows: + streamHash: ba12cc2917bf11449cd1af4cab03cfafc904e5ed + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + webhooks: + streamHash: 76b56a17ebf198ae81942372cea3f586b2baf0db + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + changesets: + streamHash: 5fa140e231db93a5b1909ea11ab72381ce666299 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + records: + streamHash: 41331fe4c7953c6849064293d471a229278c1b09 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + signatures: + hasRecords: true + streamHash: fb715c0bebb31f6c7e3147729bd9f78fb5884747 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + projects: + hasRecords: true + streamHash: 07364c25c3cffac0d4f85f59f19fce726db204d3 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + layers: + hasRecords: true + streamHash: e40fcbb288e274b84d840f6ff737310323d0a008 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + classification_sets: + hasRecords: true + streamHash: 277de4082d0d248d93785fb85d55e44fc6e9d350 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + choice_lists: + hasRecords: true + streamHash: 46bd64269bd9e61ee4942ab9d29f68b8bef17cc3 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + groups: + hasRecords: true + streamHash: e65d5d2466ca21ebb78776ff87b202cd581cb2e4 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + memberships: + hasRecords: true + streamHash: 72381538d12e923b39c97b73b418b64aa2e07c74 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + roles: + hasRecords: true + streamHash: 145c72d8a6e501b5ac905db993e5cf16a78eda3c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + authorizations: + hasRecords: true + streamHash: 1771d3b9077668e60e9c1281b0485710aac0bf71 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + photos: + hasRecords: true + streamHash: 49bb8ddaef2bec53a509a967f125f3df9e986a5f + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + audio: + hasRecords: true + streamHash: ed2ecfacee335f637a6e47c275e2f8ce1cb900c1 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + videos: + hasRecords: true + streamHash: 99c4355f6405e291b6de7d639ea017c33cafc1f1 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://docs.fulcrumapp.com/reference/rest-api-intro + +schemas: + forms: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + description: + type: + - string + - "null" + assignment_enabled: + type: + - boolean + - "null" + attachment_ids: + type: + - array + - "null" + auto_assign: + type: + - boolean + - "null" + bounding_box: + type: + - array + - "null" + items: + type: + - number + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_id: + type: + - string + - "null" + elements: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + agreement_text: + type: + - string + - "null" + annotations_enabled: + type: + - boolean + - "null" + audio_enabled: + type: + - boolean + - "null" + data_name: + type: + - string + - "null" + default_previous_value: + type: + - boolean + - "null" + default_value: + type: + - string + - "null" + deidentification_enabled: + type: + - boolean + - "null" + disabled: + type: + - boolean + - "null" + hidden: + type: + - boolean + - "null" + key: + type: + - string + - "null" + label: + type: + - string + - "null" + latlongstamp_enabled: + type: + - boolean + - "null" + negative: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + neutral: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + neutral_enabled: + type: + - boolean + - "null" + numeric: + type: + - boolean + - "null" + positive: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + required: + type: + - boolean + - "null" + timestamp_enabled: + type: + - boolean + - "null" + track_enabled: + type: + - boolean + - "null" + visible_conditions_behavior: + type: + - string + - "null" + fastfill_audio_enabled: + type: + - boolean + - "null" + field_effects: + type: + - object + - "null" + geometry_required: + type: + - boolean + - "null" + geometry_types: + type: + - array + - "null" + items: + type: + - string + - "null" + hidden_on_dashboard: + type: + - boolean + - "null" + id: + type: string + name: + type: + - string + - "null" + projects_enabled: + type: + - boolean + - "null" + record_changed_at: + type: + - string + - "null" + record_count: + type: + - number + - "null" + record_title_key: + type: + - string + - "null" + report_templates: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + status: + type: + - string + - "null" + status_field: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + choices: + type: + - array + - "null" + data_name: + type: + - string + - "null" + default_previous_value: + type: + - boolean + - "null" + default_value: + type: + - string + - "null" + disabled: + type: + - boolean + - "null" + enabled: + type: + - boolean + - "null" + hidden: + type: + - boolean + - "null" + key: + type: + - string + - "null" + label: + type: + - string + - "null" + read_only: + type: + - boolean + - "null" + required: + type: + - boolean + - "null" + title_field_keys: + type: + - array + - "null" + items: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - string + - "null" + updated_by_id: + type: + - string + - "null" + required: + - id + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + access: + type: + - object + - "null" + properties: + allowed: + type: + - boolean + - "null" + completed_onboarding: + type: + - boolean + - "null" + contexts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + api_token: + type: + - string + - "null" + has_ita_system_apps: + type: + - boolean + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + plan: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + activity_feed_enabled: + type: + - boolean + - "null" + api_access_enabled: + type: + - boolean + - "null" + attachments_enabled: + type: + - boolean + - "null" + audio_enabled: + type: + - boolean + - "null" + audit_logs_enabled: + type: + - boolean + - "null" + barcodes_enabled: + type: + - boolean + - "null" + base_price_in_cents: + type: + - number + - "null" + calculations_enabled: + type: + - boolean + - "null" + communities_enabled: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + custom_roles_enabled: + type: + - boolean + - "null" + data_event_inference_enabled: + type: + - boolean + - "null" + data_event_loadfile_enabled: + type: + - boolean + - "null" + data_event_recognizetext_enabled: + type: + - boolean + - "null" + data_pack_cost: + type: + - number + - "null" + data_pack_size: + type: + - number + - "null" + data_shares_enabled: + type: + - boolean + - "null" + data_shares_limit: + type: + - number + - "null" + developer_pack_cost: + type: + - number + - "null" + developer_pack_enabled: + type: + - boolean + - "null" + esri_enterprise_connection_enabled: + type: + - boolean + - "null" + export_changesets_enabled: + type: + - boolean + - "null" + export_formats: + type: + - array + - "null" + items: + type: + - string + - "null" + export_full_history_enabled: + type: + - boolean + - "null" + export_photos: + type: + - boolean + - "null" + export_reports_enabled: + type: + - boolean + - "null" + exports_enabled: + type: + - boolean + - "null" + external_contributions_enabled: + type: + - boolean + - "null" + flags: + type: + - object + - "null" + properties: + advanced_geometry_android: + type: + - boolean + - "null" + advanced_geometry_beta: + type: + - boolean + - "null" + advanced_geometry_enabled: + type: + - boolean + - "null" + advanced_geometry_ios: + type: + - boolean + - "null" + batch_pdf_export_enabled: + type: + - boolean + - "null" + bulk_records_delete_enabled: + type: + - boolean + - "null" + esri_enhanced: + type: + - boolean + - "null" + feature_service_layers_enabled: + type: + - boolean + - "null" + import_limit: + type: + - number + - "null" + map_engine: + type: + - string + - "null" + mobile_layer_picker: + type: + - boolean + - "null" + mobile_layer_picker_ga: + type: + - boolean + - "null" + mobile_offline_feature_services: + type: + - boolean + - "null" + non_blocking_sync_ga: + type: + - boolean + - "null" + offline_basemaps_beta: + type: + - boolean + - "null" + reporting_map_engine: + type: + - string + - "null" + suppress_repeatable_geometry: + type: + - boolean + - "null" + suppress_repeatable_geometry_ga: + type: + - boolean + - "null" + tracking_android_enabled: + type: + - boolean + - "null" + tracking_ios_enabled: + type: + - boolean + - "null" + tracking_ios_enabled_ga: + type: + - boolean + - "null" + web_map_engine: + type: + - string + - "null" + web_sketch_editor: + type: + - boolean + - "null" + form_scripts_enabled: + type: + - boolean + - "null" + id: + type: + - string + - "null" + imports_enabled: + type: + - boolean + - "null" + included_users: + type: + - number + - "null" + layers_enabled: + type: + - boolean + - "null" + maps_data_quota: + type: + - number + - "null" + media_data_quota: + type: + - number + - "null" + media_data_usage_includes_audio: + type: + - boolean + - "null" + media_data_usage_includes_photos: + type: + - boolean + - "null" + media_data_usage_includes_signatures: + type: + - boolean + - "null" + media_data_usage_includes_videos: + type: + - boolean + - "null" + name: + type: + - string + - "null" + photo_annotations_enabled: + type: + - boolean + - "null" + photo_deidentification_enabled: + type: + - boolean + - "null" + photo_recognition_enabled: + type: + - boolean + - "null" + photos_enabled: + type: + - boolean + - "null" + price_in_cents: + type: + - number + - "null" + public_color: + type: + - string + - "null" + public_slug: + type: + - string + - "null" + query_api_enabled: + type: + - boolean + - "null" + record_links_enabled: + type: + - boolean + - "null" + record_merging_enabled: + type: + - boolean + - "null" + reference_files_enabled: + type: + - boolean + - "null" + repeatables_enabled: + type: + - boolean + - "null" + report_watermark_enabled: + type: + - boolean + - "null" + reporting_advanced_enabled: + type: + - boolean + - "null" + reporting_basic_enabled: + type: + - boolean + - "null" + saml_enabled: + type: + - boolean + - "null" + shared_views_enabled: + type: + - boolean + - "null" + signatures_enabled: + type: + - boolean + - "null" + slug: + type: + - string + - "null" + sync_draft_records_enabled: + type: + - boolean + - "null" + updated_at: + type: + - string + - "null" + versioning_enabled: + type: + - boolean + - "null" + videos_enabled: + type: + - boolean + - "null" + view_history_enabled: + type: + - boolean + - "null" + webhooks_enabled: + type: + - boolean + - "null" + workflow_integration_daily_limit: + type: + - number + - "null" + workflows_enabled: + type: + - boolean + - "null" + role: + type: + - object + - "null" + properties: + can_access_issues_and_tasks: + type: + - boolean + - "null" + can_assign_records: + type: + - boolean + - "null" + can_bulk_delete_records: + type: + - boolean + - "null" + can_bulk_update_records: + type: + - boolean + - "null" + can_change_project: + type: + - boolean + - "null" + can_change_status: + type: + - boolean + - "null" + can_configure_issues_and_tasks: + type: + - boolean + - "null" + can_create_records: + type: + - boolean + - "null" + can_delete_records: + type: + - boolean + - "null" + can_export_records: + type: + - boolean + - "null" + can_import_records: + type: + - boolean + - "null" + can_manage_apps: + type: + - boolean + - "null" + can_manage_authorizations: + type: + - boolean + - "null" + can_manage_choice_lists: + type: + - boolean + - "null" + can_manage_classification_sets: + type: + - boolean + - "null" + can_manage_groups: + type: + - boolean + - "null" + can_manage_layers: + type: + - boolean + - "null" + can_manage_members: + type: + - boolean + - "null" + can_manage_projects: + type: + - boolean + - "null" + can_manage_roles: + type: + - boolean + - "null" + can_manage_subscription: + type: + - boolean + - "null" + can_run_reports: + type: + - boolean + - "null" + can_update_organization: + type: + - boolean + - "null" + can_update_records: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_id: + type: + - string + - "null" + id: + type: + - string + - "null" + is_default: + type: + - boolean + - "null" + is_system: + type: + - boolean + - "null" + name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - string + - "null" + updated_by_id: + type: + - string + - "null" + current_organization: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + id: + type: string + image_large: + type: + - string + - "null" + image_small: + type: + - string + - "null" + last_name: + type: + - string + - "null" + managed: + type: + - boolean + - "null" + phone_number: + type: + - string + - "null" + required: + - id + workflows: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_id: + type: + - string + - "null" + event_type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + object_resource_id: + type: + - string + - "null" + object_type: + type: + - string + - "null" + run_for_bulk_actions: + type: + - boolean + - "null" + steps: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + arguments: + type: + - object + - "null" + properties: + auth: + type: + - object + - "null" + properties: + password: + type: + - string + - "null" + username: + type: + - string + - "null" + expression: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + combinator: + type: + - string + - "null" + field: + type: + - string + - "null" + operator: + type: + - string + - "null" + value: + type: + - string + - "null" + headers: + type: + - object + - "null" + properties: + "": + type: + - string + - "null" + method: + type: + - string + - "null" + parameters: + type: + - object + - "null" + properties: + "": + type: + - string + - "null" + payload: + type: + - string + - "null" + url: + type: + - string + - "null" + id: + type: + - string + - "null" + initial: + type: + - boolean + - "null" + next_steps: + type: + - array + - "null" + items: + type: + - string + - "null" + step_type: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - string + - "null" + updated_by_id: + type: + - string + - "null" + webhooks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + run_for_bulk_actions: + type: + - boolean + - "null" + updated_at: + type: + - string + - "null" + url: + type: + - string + - "null" + required: + - id + changesets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + metadata: + type: + - object + - "null" + properties: + application: + type: + - string + - "null" + browser: + type: + - string + - "null" + browser_version: + type: + - string + - "null" + platform: + type: + - string + - "null" + platform_version: + type: + - string + - "null" + user_agent: + type: + - string + - "null" + closed_at: + type: + - string + - "null" + closed_by: + type: + - string + - "null" + closed_by_id: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_id: + type: + - string + - "null" + form_id: + type: + - string + - "null" + gravatar_image_url: + type: + - string + - "null" + id: + type: string + image_large: + type: + - string + - "null" + image_small: + type: + - string + - "null" + max_lat: + type: + - number + - "null" + max_lon: + type: + - number + - "null" + min_lat: + type: + - number + - "null" + min_lon: + type: + - number + - "null" + number_created: + type: + - number + - "null" + number_deleted: + type: + - number + - "null" + number_of_changes: + type: + - number + - "null" + number_updated: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - string + - "null" + updated_by_id: + type: + - string + - "null" + required: + - id + records: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + client_created_at: + type: + - string + - "null" + client_updated_at: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_id: + type: + - string + - "null" + created_duration: + type: + - number + - "null" + edited_duration: + type: + - number + - "null" + form_id: + type: + - string + - "null" + form_values: + type: + - object + - "null" + properties: + "6281": + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + audio_id: + type: + - string + - "null" + "0600": + type: + - string + - "null" + 2f60: + type: + - object + - "null" + properties: + signature_id: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + 2fcc: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + video_id: + type: + - string + - "null" + 5d00: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + photo_id: + type: + - string + - "null" + 6c2f: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attachment_id: + type: + - string + - "null" + name: + type: + - string + - "null" + 7da2: + type: + - string + - "null" + d630: + type: + - string + - "null" + geometry: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + coordinates: + type: + - array + - "null" + items: + type: + - number + - "null" + id: + type: string + latitude: + type: + - number + - "null" + longitude: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - string + - "null" + updated_by_id: + type: + - string + - "null" + updated_duration: + type: + - number + - "null" + required: + - id + signatures: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + access_key: + type: + - string + - "null" + content_type: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_id: + type: + - string + - "null" + file_size: + type: + - number + - "null" + form_id: + type: + - string + - "null" + processed: + type: + - boolean + - "null" + record_id: + type: string + stored: + type: + - boolean + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - string + - "null" + updated_by_id: + type: + - string + - "null" + uploaded: + type: + - boolean + - "null" + url: + type: + - string + - "null" + required: + - record_id + projects: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + customer: + type: + - string + - "null" + external_job_id: + type: + - string + - "null" + form_count: + type: + - number + - "null" + id: + type: string + name: + type: + - string + - "null" + record_count: + type: + - number + - "null" + status: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + layers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + origin: + type: + - string + - "null" + source: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + classification_sets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_id: + type: + - string + - "null" + id: + type: string + items: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - string + - "null" + updated_by_id: + type: + - string + - "null" + required: + - id + choice_lists: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + description: + type: + - string + - "null" + choices: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_id: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - string + - "null" + updated_by_id: + type: + - string + - "null" + required: + - id + groups: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + id: + type: string + is_managed: + type: + - boolean + - "null" + name: + type: + - string + - "null" + required: + - id + memberships: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + gravatar_image_url: + type: + - string + - "null" + id: + type: string + image_large: + type: + - string + - "null" + image_small: + type: + - string + - "null" + last_name: + type: + - string + - "null" + last_sign_in_at: + type: + - string + - "null" + role_id: + type: + - string + - "null" + role_name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + user: + type: + - string + - "null" + user_id: + type: + - string + - "null" + user_type: + type: + - string + - "null" + required: + - id + roles: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + can_access_issues_and_tasks: + type: + - boolean + - "null" + can_assign_records: + type: + - boolean + - "null" + can_bulk_delete_records: + type: + - boolean + - "null" + can_bulk_update_records: + type: + - boolean + - "null" + can_change_project: + type: + - boolean + - "null" + can_change_status: + type: + - boolean + - "null" + can_configure_issues_and_tasks: + type: + - boolean + - "null" + can_create_records: + type: + - boolean + - "null" + can_delete_records: + type: + - boolean + - "null" + can_export_records: + type: + - boolean + - "null" + can_import_records: + type: + - boolean + - "null" + can_manage_apps: + type: + - boolean + - "null" + can_manage_authorizations: + type: + - boolean + - "null" + can_manage_choice_lists: + type: + - boolean + - "null" + can_manage_classification_sets: + type: + - boolean + - "null" + can_manage_groups: + type: + - boolean + - "null" + can_manage_layers: + type: + - boolean + - "null" + can_manage_members: + type: + - boolean + - "null" + can_manage_projects: + type: + - boolean + - "null" + can_manage_roles: + type: + - boolean + - "null" + can_manage_subscription: + type: + - boolean + - "null" + can_run_reports: + type: + - boolean + - "null" + can_update_organization: + type: + - boolean + - "null" + can_update_records: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_id: + type: + - string + - "null" + id: + type: string + is_default: + type: + - boolean + - "null" + is_system: + type: + - boolean + - "null" + name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - string + - "null" + updated_by_id: + type: + - string + - "null" + required: + - id + authorizations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + id: + type: string + last_ip_address: + type: + - string + - "null" + last_used_at: + type: + - string + - "null" + last_user_agent: + type: + - string + - "null" + note: + type: + - string + - "null" + token_last_8: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + user_id: + type: + - string + - "null" + required: + - id + photos: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + access_key: + type: + - string + - "null" + content_type: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_id: + type: + - string + - "null" + file_size: + type: + - number + - "null" + form_id: + type: + - string + - "null" + latitude: + type: + - number + - "null" + longitude: + type: + - number + - "null" + processed: + type: + - boolean + - "null" + record_id: + type: string + stored: + type: + - boolean + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - string + - "null" + updated_by_id: + type: + - string + - "null" + uploaded: + type: + - boolean + - "null" + url: + type: + - string + - "null" + required: + - record_id + audio: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + access_key: + type: + - string + - "null" + content_type: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_id: + type: + - string + - "null" + file_size: + type: + - number + - "null" + form_id: + type: + - string + - "null" + processed: + type: + - boolean + - "null" + record_id: + type: string + status: + type: + - string + - "null" + stored: + type: + - boolean + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - string + - "null" + updated_by_id: + type: + - string + - "null" + uploaded: + type: + - boolean + - "null" + url: + type: + - string + - "null" + required: + - record_id + videos: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + access_key: + type: + - string + - "null" + content_type: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_id: + type: + - string + - "null" + file_size: + type: + - number + - "null" + form_id: + type: + - string + - "null" + processed: + type: + - boolean + - "null" + record_id: + type: string + status: + type: + - string + - "null" + stored: + type: + - boolean + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - string + - "null" + updated_by_id: + type: + - string + - "null" + uploaded: + type: + - boolean + - "null" + url: + type: + - string + - "null" + required: + - record_id diff --git a/airbyte-integrations/connectors/source-fulcrum/metadata.yaml b/airbyte-integrations/connectors/source-fulcrum/metadata.yaml new file mode 100644 index 000000000000..a420f75e88ca --- /dev/null +++ b/airbyte-integrations/connectors/source-fulcrum/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.fulcrumapp.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-fulcrum + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 1028d4dc-005b-484b-9164-5a81e0dbac19 + dockerImageTag: 0.0.7 + dockerRepository: airbyte/source-fulcrum + githubIssueLabel: source-fulcrum + icon: icon.svg + license: MIT + name: Fulcrum + releaseDate: 2024-10-21 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/fulcrum + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-fullstory/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-fullstory/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-fullstory/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-fullstory/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-fullstory/metadata.yaml b/airbyte-integrations/connectors/source-fullstory/metadata.yaml index 144c7a90e18d..dc90d3d60188 100644 --- a/airbyte-integrations/connectors/source-fullstory/metadata.yaml +++ b/airbyte-integrations/connectors/source-fullstory/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 263fd456-02d1-4a26-a35e-52ccaedad778 - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.5 dockerRepository: airbyte/source-fullstory githubIssueLabel: source-fullstory icon: fullstory.svg @@ -37,5 +37,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-gainsight-px/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-gainsight-px/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-gainsight-px/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-gainsight-px/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-gainsight-px/metadata.yaml b/airbyte-integrations/connectors/source-gainsight-px/metadata.yaml index 1b02631bd177..7dafb0cff25a 100644 --- a/airbyte-integrations/connectors/source-gainsight-px/metadata.yaml +++ b/airbyte-integrations/connectors/source-gainsight-px/metadata.yaml @@ -3,7 +3,7 @@ data: hosts: - api.aptrinsic.com/v1 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc remoteRegistries: pypi: enabled: false @@ -16,7 +16,7 @@ data: connectorSubtype: api connectorType: source definitionId: 0da3b186-8879-4e94-8738-55b48762f1e8 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-gainsight-px githubIssueLabel: source-gainsight-px icon: gainsight-px.svg diff --git a/airbyte-integrations/connectors/source-gcs/build_customization.py b/airbyte-integrations/connectors/source-gcs/build_customization.py index 83b1b136bf90..33593a539450 100644 --- a/airbyte-integrations/connectors/source-gcs/build_customization.py +++ b/airbyte-integrations/connectors/source-gcs/build_customization.py @@ -5,6 +5,7 @@ from typing import TYPE_CHECKING + if TYPE_CHECKING: from dagger import Container diff --git a/airbyte-integrations/connectors/source-gcs/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-gcs/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-gcs/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-gcs/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-gcs/integration_tests/conftest.py b/airbyte-integrations/connectors/source-gcs/integration_tests/conftest.py index 1fe90e1f1374..639577406d69 100644 --- a/airbyte-integrations/connectors/source-gcs/integration_tests/conftest.py +++ b/airbyte-integrations/connectors/source-gcs/integration_tests/conftest.py @@ -14,6 +14,7 @@ from .utils import get_docker_ip + LOCAL_GCP_PORT = 4443 from urllib.parse import urlparse, urlunparse @@ -77,4 +78,3 @@ def connector_setup_fixture(docker_client) -> None: container.kill() container.remove() - diff --git a/airbyte-integrations/connectors/source-gcs/integration_tests/integration_test.py b/airbyte-integrations/connectors/source-gcs/integration_tests/integration_test.py index e14dd36501e1..7046c434ca28 100644 --- a/airbyte-integrations/connectors/source-gcs/integration_tests/integration_test.py +++ b/airbyte-integrations/connectors/source-gcs/integration_tests/integration_test.py @@ -2,10 +2,11 @@ import os import pytest +from source_gcs import Config, SourceGCS, SourceGCSStreamReader + from airbyte_cdk.models import ConfiguredAirbyteCatalog from airbyte_cdk.sources.file_based.stream.cursor import DefaultFileBasedCursor from airbyte_cdk.test.entrypoint_wrapper import read -from source_gcs import Config, SourceGCS, SourceGCSStreamReader from .utils import load_config diff --git a/airbyte-integrations/connectors/source-gcs/main.py b/airbyte-integrations/connectors/source-gcs/main.py index 695a41f39be3..3b58be6e85f0 100644 --- a/airbyte-integrations/connectors/source-gcs/main.py +++ b/airbyte-integrations/connectors/source-gcs/main.py @@ -5,5 +5,6 @@ from source_gcs.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-gcs/metadata.yaml b/airbyte-integrations/connectors/source-gcs/metadata.yaml index 8b4ca6194e3d..8f3e18d6e3fc 100644 --- a/airbyte-integrations/connectors/source-gcs/metadata.yaml +++ b/airbyte-integrations/connectors/source-gcs/metadata.yaml @@ -7,11 +7,11 @@ data: - storage.googleapis.com - accounts.google.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: file connectorType: source definitionId: 2a8c41ae-8c23-4be0-a73f-2ab10ca1a820 - dockerImageTag: 0.8.1 + dockerImageTag: 0.8.2 dockerRepository: airbyte/source-gcs documentationUrl: https://docs.airbyte.com/integrations/sources/gcs githubIssueLabel: source-gcs diff --git a/airbyte-integrations/connectors/source-gcs/poetry.lock b/airbyte-integrations/connectors/source-gcs/poetry.lock index c88cafe5eae2..63a07aa1ca44 100644 --- a/airbyte-integrations/connectors/source-gcs/poetry.lock +++ b/airbyte-integrations/connectors/source-gcs/poetry.lock @@ -2,13 +2,13 @@ [[package]] name = "airbyte-cdk" -version = "5.13.0" +version = "5.17.0" description = "A framework for writing Airbyte Connectors." optional = false python-versions = "<4.0,>=3.10" files = [ - {file = "airbyte_cdk-5.13.0-py3-none-any.whl", hash = "sha256:b26c99631e797c0bdb8373a6a05c81bf62b7d7397ca41b6ee05702d1013bd389"}, - {file = "airbyte_cdk-5.13.0.tar.gz", hash = "sha256:ab5799a238366dff61a8cded347b02deb63818513af4e61e2d1a51608a2280df"}, + {file = "airbyte_cdk-5.17.0-py3-none-any.whl", hash = "sha256:135a8fc43b00a92169dfcdc43c1d7c629aba871a0b471f950ca5d76d3741fc92"}, + {file = "airbyte_cdk-5.17.0.tar.gz", hash = "sha256:5db70cbacec80ba3beabe4253480ab9a3947a450e8d0e39af4a91638b317b32a"}, ] [package.dependencies] @@ -54,17 +54,18 @@ xmltodict = ">=0.13.0,<0.14.0" [package.extras] file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "python-snappy (==0.7.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] +sql = ["sqlalchemy (>=2.0,!=2.0.36,<3.0)"] vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] [[package]] name = "airbyte-protocol-models-dataclasses" -version = "0.13.0" +version = "0.13.1" description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models_dataclasses-0.13.0-py3-none-any.whl", hash = "sha256:0aedb99ffc4f9aab0ce91bba2c292fa17cd8fd4b42eeba196d6a16c20bbbd7a5"}, - {file = "airbyte_protocol_models_dataclasses-0.13.0.tar.gz", hash = "sha256:72e67850d661e2808406aec5839b3158ebb94d3553b798dbdae1b4a278548d2f"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1-py3-none-any.whl", hash = "sha256:20a734b7b1c3479a643777830db6a2e0a34428f33d16abcfd320552576fabe5a"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1.tar.gz", hash = "sha256:ec6a0fb6b16267bde910f52279445d06c8e1a3e4ed82ac2937b405ab280449d5"}, ] [[package]] @@ -80,13 +81,13 @@ files = [ [[package]] name = "anyio" -version = "4.6.0" +version = "4.6.2.post1" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.0-py3-none-any.whl", hash = "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a"}, - {file = "anyio-4.6.0.tar.gz", hash = "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb"}, + {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, + {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, ] [package.dependencies] @@ -97,7 +98,7 @@ typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} [package.extras] doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.21.0b1)"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -466,101 +467,101 @@ files = [ [[package]] name = "cramjam" -version = "2.8.4" +version = "2.9.0" description = "Thin Python bindings to de/compression algorithms in Rust" optional = false python-versions = ">=3.8" files = [ - {file = "cramjam-2.8.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:e9e112514363261a896f85948d5d055dccaab2a1fa77d440f55030464118a95a"}, - {file = "cramjam-2.8.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ee2441028e813ecc1d10b90640dd2b9649cdefdfe80af1d838cf00fd935ee5e7"}, - {file = "cramjam-2.8.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:86a3e0f91176eacd23f8d63b01139a63687cb3fa9670996b3bfa7c38eac6cb7e"}, - {file = "cramjam-2.8.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e34aa083a10079c8814091c0fe9080238a82569fa08058cf79d12b3f9710fc5"}, - {file = "cramjam-2.8.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:465ccf470536e065822daa2a083dedf18df8133278e9132b147bd1721211d707"}, - {file = "cramjam-2.8.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30aba9e9c737c986d26a809b9e36628452c075234a5e835b085ab7c2b9574dc"}, - {file = "cramjam-2.8.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:52f710bd7fa9b5a374e2e2281d7d672f9eb89263c531643f95fab93e98200c68"}, - {file = "cramjam-2.8.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6622095ffa6cae77c9e8036a39757fdb1d3cabc3444ad892e5a705882ed06c8d"}, - {file = "cramjam-2.8.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bc618c018594c20696a42faf8a144e1508b8a4312e0d8697f6c64b337e37e5d9"}, - {file = "cramjam-2.8.4-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:30c75259f58583f96ad9cef7202c70cd6604a9dabf9834211df48a27ec85f84a"}, - {file = "cramjam-2.8.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:2b9b4bbe7ef3318b2f2aed2a8a658b401a9ad9314d50372f9bb97cdef093f326"}, - {file = "cramjam-2.8.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d7a7c10fb2602d7c8c4dbe4eeacf352477cc1af939fd3537f4e1cd42526855b8"}, - {file = "cramjam-2.8.4-cp310-none-win32.whl", hash = "sha256:831ee2424b095f51c9719b0479d9b413bc849e47160b904a7a8e4a8dcf41d2f7"}, - {file = "cramjam-2.8.4-cp310-none-win_amd64.whl", hash = "sha256:4f6bf5752a0322cc63f955343c390253034b609d167930584bb392bf4179c444"}, - {file = "cramjam-2.8.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d48fd69224a2f4df187856021f545a65486575cba92bb32a14ccad1ce54584a9"}, - {file = "cramjam-2.8.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c53d8dce609607370f01a5db65c79db75db08e9e89cbb9c2a2212b7a3c0b8af3"}, - {file = "cramjam-2.8.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d08b8ff282545ab3a414db845e430320555ff7a7eb90517b2c9554e24ca0d763"}, - {file = "cramjam-2.8.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac5fb30cf6c03f72397ead8584592dc071f486c76199c46c28e7de619174ba1f"}, - {file = "cramjam-2.8.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0d86cfb2b457a337db4b7c8cf6a9dafc018806750f28b3c27d71b94e2d4379d0"}, - {file = "cramjam-2.8.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59565a16ce0c71993d3947bdf9301e0d69866c15f37d67d2875809eca998d841"}, - {file = "cramjam-2.8.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6741544b372ba3e6c65db1c44b1a75e48743d091b76a09d7d832b1fb0a0ef518"}, - {file = "cramjam-2.8.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5f486bacd46f364137f5b164a879821115118d7f866a838429eb10aee59a14b"}, - {file = "cramjam-2.8.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4e02081bfb9998f5ff816f3e984a62ca91835e3483c578812374aaf5cb6ed921"}, - {file = "cramjam-2.8.4-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:1c63e856727726a1ee2a77a12bfccfcd70ee3e5bbe9e6d07bd00be5a1eb6ec10"}, - {file = "cramjam-2.8.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:74fb59137946b691e8987349e9117e2897f3b0484116ad6e2b1b4de0d082430f"}, - {file = "cramjam-2.8.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c7952e0cd6f37a04983cb027175f91f225d7c30625038b8930b6fd3f00619350"}, - {file = "cramjam-2.8.4-cp311-none-win32.whl", hash = "sha256:2bfd5c442e6031b146a93b1cc37d42c04b6d01bb652c9f123338c482c3943038"}, - {file = "cramjam-2.8.4-cp311-none-win_amd64.whl", hash = "sha256:73c95cae138bc8f5604bbbc97860f158c4f77e046304dd4f9c9838021d64217a"}, - {file = "cramjam-2.8.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:5056f476917d31c69719883bbe12272288b77ab5ea5ee55fbcbb6c0dd10e52da"}, - {file = "cramjam-2.8.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8359d31dca4bd8286e031f1a21f20f62f4e7a4586c407e916fd2de101c719a8b"}, - {file = "cramjam-2.8.4-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a1aee32556b9f7ecc61c6c4675798153ac511b5b72db9f56d2a8c20c1fa6d563"}, - {file = "cramjam-2.8.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:005bfe79ae38ea1df67fd3079089287640c780bf112aab4b6a3a9f12f0bf3c91"}, - {file = "cramjam-2.8.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51662c79c5a2256824f3acca9ccdbeaad3626c90ae46a19ef25f186d70a9ac69"}, - {file = "cramjam-2.8.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c744148e33002cefd4aaa3641800c0008fa177c8c09230c09d30d6e7ab473a4"}, - {file = "cramjam-2.8.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c897d2443cf9f3685a51ecc28c669aad95b6a610de7883647fe450cc742e2ea7"}, - {file = "cramjam-2.8.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:741b0c29d701d470243b9cad09a3e21c2ab83190710df680fd84baea1b262089"}, - {file = "cramjam-2.8.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4cfc6d838afb90a59d2c721fe8d78c2a333edf5c370b3ce8f9823c49bc52e5d0"}, - {file = "cramjam-2.8.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:977e380a567f1bcdb0f1156820fedc57727c6c639769b846b39ad7fc1be5563b"}, - {file = "cramjam-2.8.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3f16dea7f430bb8a5cf2e2a8eece5fa7a6e58bffae3913083f6c20de50ce85bd"}, - {file = "cramjam-2.8.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d25c2ff722e66a55c58b6c325985b2bf342a6592db084557c2956a07d7179d7"}, - {file = "cramjam-2.8.4-cp312-none-win32.whl", hash = "sha256:b63bcf4e5f9c6ee027947a22862d054e8ce0fa189a33ccdb07e66ef09291252c"}, - {file = "cramjam-2.8.4-cp312-none-win_amd64.whl", hash = "sha256:72b9d4c29a51a8656690df2ef6f7823fa27ebc35e051182b6ebef5fef180876f"}, - {file = "cramjam-2.8.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:9b00949104594eb2b6daf9ec72f1a6dfc93968bc0ffbdbfee936c359fc782186"}, - {file = "cramjam-2.8.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:24b29d805e860d22499e6f5d004582477f3c8309e2a899e0c86c1530a94e6092"}, - {file = "cramjam-2.8.4-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f9454207624a701cb518fbef137e2eb6088aaf5606679aa6ab28d2dd06d72702"}, - {file = "cramjam-2.8.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ee580acb4b6af5ae211b80b679aa377ffa9f9ff74a1e9de458c09d19bce4433"}, - {file = "cramjam-2.8.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:157c36731e430670be44ba490b8a0e4fc04ebdd78c3ea19339ba4ac24d73ad25"}, - {file = "cramjam-2.8.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30a12b1437e28b5e72ab10642d214e9b42220e8c5be2948ac6916aca203f69b0"}, - {file = "cramjam-2.8.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:553e2cd4c2614510770ff3a8bf6b72957a86985b1ae2b8fcdc6d04848857313f"}, - {file = "cramjam-2.8.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e40e448d50fa7c2b79c06d99459ad4a77d58d9cfb3f0549a63b91179a5e57c0b"}, - {file = "cramjam-2.8.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:769995dfc7fd042ce123f25e7659977ed4aa4d5d6aad976970b12b9b4019c116"}, - {file = "cramjam-2.8.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:1ba26f563d9e5be588c8e5f5523b4cdb5b63e3ac3fb28857af9611eb5ea51416"}, - {file = "cramjam-2.8.4-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:5cbfd6c44c85216b3535095258b506f6e246c6fbf1438a79f71bcff4d98f7e3f"}, - {file = "cramjam-2.8.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:4bf4e8711b27604b3ca7e7c224a70f5abe94f5bf05a183bd97677e9cffd2be04"}, - {file = "cramjam-2.8.4-cp313-none-win32.whl", hash = "sha256:7c9ca8e6c33c06c08e9945a20fe0f64a2bcd363554e359a2936b3a469883630a"}, - {file = "cramjam-2.8.4-cp313-none-win_amd64.whl", hash = "sha256:ee92df7e66b7cbdb05b18687a42696bc729bacaad0d68f5549e30cbfa1eb0ca8"}, - {file = "cramjam-2.8.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:386eb0fe9567ae3c06e2053205e19e671e4170f3a0deb68dd103e4c651a3ff8b"}, - {file = "cramjam-2.8.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:64e22027874ce429ce04c0c9d19e6bed5bf6425ecc3e68752211b8509915c57c"}, - {file = "cramjam-2.8.4-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b74470fb215a3ac2e6ed968f671286456030882aa25616b969b1a52ebda4f29d"}, - {file = "cramjam-2.8.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c41d4542cc2c7238017caebc161b0866b3fb5e85e59727ab623f95e07abc453"}, - {file = "cramjam-2.8.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:14b6f2f883068873bd2b5c31fbf7c4223c0452b8bff662bec02d7973a095c46b"}, - {file = "cramjam-2.8.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d5921c4521d41fb125d31ce1fe9e5bfba24a2577bc8727289baae9afbebc8409"}, - {file = "cramjam-2.8.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb62855f17be5d1bec0d3cef89d8d54582137529c7ea96480c40ebb4a8c92c4b"}, - {file = "cramjam-2.8.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91cd4b28fc75680616bd22db5a56802ce7ce406052c58e72fd583a16746a1010"}, - {file = "cramjam-2.8.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f03502eaf1a0a95cdcbf4c6ebba5edfaa68d356f487ec8485ae651772c9426f9"}, - {file = "cramjam-2.8.4-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:bb5e23c1f8dc2b4cddc7982da60d2f7a9719920539c26e7b754f2272f510fc0c"}, - {file = "cramjam-2.8.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ef6b0d4c83b173d18398713522bff1db1e4e73ec3b3da6495afc5628767d6c85"}, - {file = "cramjam-2.8.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b2253287a08759cefb75ef46ebaa0f993a2890a31fe9bba94363ca245f42d821"}, - {file = "cramjam-2.8.4-cp38-none-win32.whl", hash = "sha256:8375090e54978ccbb1d90e494d73d09e36477e0d695ddadf2d13627168862950"}, - {file = "cramjam-2.8.4-cp38-none-win_amd64.whl", hash = "sha256:12100dd3ed6969365d1952832e39c017d97c85eeb517ae468092f67aa4d89568"}, - {file = "cramjam-2.8.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:47c1594346dceb0d363d479ddac1e9ff87596c92e5258b389118ae6e30599145"}, - {file = "cramjam-2.8.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5472f9c6db34046c7ab2f0c4be5a4be677dba98bf78cc0eb03f9812e5774f14d"}, - {file = "cramjam-2.8.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9bfa940e016bfeea2b93115abf9e4e455a6325dd85a3fa6af55c6052f070ba25"}, - {file = "cramjam-2.8.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24e738a92ac520b26b952bfc48b1ba6453ea455e20167f08f6ee3df5c7d22cd4"}, - {file = "cramjam-2.8.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:78ded70e85722a6dcd0c436193af58a43083f0ece35c1f74227782a28e517aa0"}, - {file = "cramjam-2.8.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99b024a9912a5fd3b4e6b949b83b291e2828775edc0595ef8b94c491e904287b"}, - {file = "cramjam-2.8.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:673dc6395fed94db59fb75a7657d8b061bd575332d8f15025e7b1a4feaba0a3f"}, - {file = "cramjam-2.8.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4b8f83c5a98fecf44c6d852a9bd30ab1508e51d910dc9c8e636863d131fd5eb"}, - {file = "cramjam-2.8.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:85eada9385a706d8d0f6cb1d51995f5eef16d3cade7e68150d6e441fd26406da"}, - {file = "cramjam-2.8.4-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:2429134bb2ee8fffe28f41e3f5390be9c539ac1e2c453034ea63542d7aacc5cc"}, - {file = "cramjam-2.8.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e90003b2ce00358ee669afa0710bf52dee6827460b80ce4a7a9f906551ab703a"}, - {file = "cramjam-2.8.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d0619af45310cceeab9a2410d4a14445743e494015d85584b974847bfb2a2011"}, - {file = "cramjam-2.8.4-cp39-none-win32.whl", hash = "sha256:a30d68094462076655259feee1187237af846969007e5341a96c79b447c47ab3"}, - {file = "cramjam-2.8.4-cp39-none-win_amd64.whl", hash = "sha256:f24e375dfb31f0953e236f2cc4af1b03b80d40aec2bc558df48d507d8e7c8d96"}, - {file = "cramjam-2.8.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3536362f777d817c4994d6eaa42e00e705092c5660fd3d9984f3b0cc6164d327"}, - {file = "cramjam-2.8.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:0d52eabd20a694636f5b0197daa64db497ea518e057935a7c61ec71e92d3ccd6"}, - {file = "cramjam-2.8.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cf69f19ebd546fc155ec3098603de51f52bf620a23597810cb5b34d6aff116d"}, - {file = "cramjam-2.8.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:364258057d579c772e23e1f666fd7efec4f63ea2e791889bb18263c9e9e6aa91"}, - {file = "cramjam-2.8.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:98a2e2c3132b454ae47b194164bb8860464ed410fbbffc0d1de19452cc7cb402"}, - {file = "cramjam-2.8.4.tar.gz", hash = "sha256:ad8bec85b46283330214f4367805e6f56e04ce25a030a2c6a4b127437d006fcf"}, + {file = "cramjam-2.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:eb16d995e454b0155b166f6e6da7df4ac812d44e0f3b6dc0f344a934609fd5bc"}, + {file = "cramjam-2.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cb1e86bfea656b51f2e75f2cedb17fc08b552d105b814d19b595294ecbe94d8d"}, + {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4bd76b654275736fd4f55521981b73751c34dacf70a1dbce96e454a39d43201f"}, + {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21569f19d5848606b85ac0dde0dc3639319d26fed8522c7103515df875bcb300"}, + {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b8f8b1117b4e697d39950ecab01700ce0aef66541e4478eb4d7b3ade8703347b"}, + {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3464d0042a03e8ef38a2b774ef23163cf3c0cdc41b8dfbf7c4aadf93e40b459"}, + {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0711c776750e243ae347d6609c975f0ff4be9ae65b2764d29e4bbdad8e574c3a"}, + {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00d96f798bc980b29f8e1c3ed7d554050e05d4cde23d1633ffed4cd63110024a"}, + {file = "cramjam-2.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fc49b6575e3cb15da3180c5a3926ec81db33b109e48530708da76614b306904b"}, + {file = "cramjam-2.9.0-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:c4fa6c23e56d48df18f534af921ec936c812743a8972ecdd5e5ff47b464fea00"}, + {file = "cramjam-2.9.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b4b8d8160685c11ffb4e8e6daaab79cb351a1c54ceec41cc18a0a62c89309fe0"}, + {file = "cramjam-2.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0ed6362cb6c964f8d0c6e7f790e8961b9242cd3acd87c56169ca14d642653707"}, + {file = "cramjam-2.9.0-cp310-none-win32.whl", hash = "sha256:fe9af350dfbdc7ed4c93a8016a8ad7b5492fc116e7197cad7cbce99b434d3fe1"}, + {file = "cramjam-2.9.0-cp310-none-win_amd64.whl", hash = "sha256:37054c73704a3183b60869e7fec1614648752c31d89f44de1ffe1f01ad4d20d5"}, + {file = "cramjam-2.9.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:170a50407f9400073621cc1d5f3200ca3ad9de3000831e3e86f5561ca8048a08"}, + {file = "cramjam-2.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:912c94781c8ff318a4d3f3306f8d94d41ae5aa7b9760c4bb0476b01142084845"}, + {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:df089639983a03070be6eabc60317aa1ffbf2c5409023b57a5fc2e4975163bc4"}, + {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ca28a8f6ab5fca35f163fd7d7a970880ce4fc1a0bead1249ecdaa96ec9ac1f4"}, + {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:abd8bf9a94e3866215ac181a7dbcfa1ddbedca4f8048494a79934febe88537df"}, + {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7de19a382bcab93cd4d028d51f6f581920a3b79659a384775188135b7fc64f15"}, + {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a4156fcefa1dfaa65d35ff82c252d1e32be12820f26d04748be6cd3b461cf85f"}, + {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4a3104022129d7463100dfaf12efd398ebfa4b7e4e50832ccc596754f7c26df"}, + {file = "cramjam-2.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6ebee5f5d7e2b9277895ea4fd94646b72075fe9cfc0e8f4770b65c9e72b1fec1"}, + {file = "cramjam-2.9.0-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:8e33ebe4d709b21bc15e7ddf485ac6b30d7fdc7ed7c3c65130654c007f50c183"}, + {file = "cramjam-2.9.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4d5a39118008bb9f2fba36a0ceea6c41fbd0b55d2647b043ba51a868e5f6de92"}, + {file = "cramjam-2.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7f6ef35eba883927af2678b561cc4407e0b3b0d58a251c863bec4b3d8258cc2f"}, + {file = "cramjam-2.9.0-cp311-none-win32.whl", hash = "sha256:b21e55b5cfdaff96eae1f323ae9a0d36e86852cdf62fe23b60a2481d2fed5571"}, + {file = "cramjam-2.9.0-cp311-none-win_amd64.whl", hash = "sha256:9f685fe4e49b2f3e233548e3397b3f9189d71a265718ec631d13eca3d5718ddb"}, + {file = "cramjam-2.9.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:34578e4c1518b10dad5e0ba40c721e529ef13e7742a528843b40e1f20dd6078c"}, + {file = "cramjam-2.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1d5b5512dc61ea78f32e021e88a5fd5b46a821409479e6657d33614fc9e45677"}, + {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0b4f1b5e33915ed591c0c19b8c3bbdd7aa0f6a9bfe2b7246b475d497bda15f18"}, + {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad301801afa0eecdacabf353a2802df5e6770f9bfb0a559d6c069813d83cfd42"}, + {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:399baf80fea574e3870f233e12e6a12f02c53b054e13d792348b272b0614370a"}, + {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3121e2fbec58907fa70636adaeaf30c27614c867e08a7a5bd2887b33786ff790"}, + {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd04205b2a87087ffc2257c3ad33f11daabc053956f64ac1ec7bae299cac3f2f"}, + {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddb9c4db36188a8f08c2303100a83100f26a8572803ae35eadff359bebd3d204"}, + {file = "cramjam-2.9.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ef553d4080368006817c1a935ed619c71987cf10417a32386acc00c5418a2934"}, + {file = "cramjam-2.9.0-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:9862ca8ead80857ecfb9b07f02f577733261e981346f31585fe118975eabb738"}, + {file = "cramjam-2.9.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4714e1ea0c3329368b83fe5ad6e831d5ca11fb794ca7cf491622eb6b2d420d2f"}, + {file = "cramjam-2.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1b4ca30c9f27e3b88bc082d4637e7648f93da5cb69a2dbe0c0300bc51353c820"}, + {file = "cramjam-2.9.0-cp312-none-win32.whl", hash = "sha256:0ed2fef010d1caca9ea63814e9cb5b1d47d907b80302b8cc0b3a1e116ea241e2"}, + {file = "cramjam-2.9.0-cp312-none-win_amd64.whl", hash = "sha256:bd26d71939de5dcf169d479fbc7fcfed21e6675bab33e7f7e9f8405f19711c71"}, + {file = "cramjam-2.9.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:dd70ea5d7b2c5e479e04ac3a00d8bc3deca146d2b5dbfbe3d7b42ed136e19de4"}, + {file = "cramjam-2.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b1410e68c464666473a89cade17483b94bb4639d9161c440ee54ee1e0eca583"}, + {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b0078727fe8c28ef1695e5d04aae5c41ac697eb087cba387c6a02b825f9071c0"}, + {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a63c4e63319bf7dfc3ab46c06afb76d3d9cc1c94369b609dde480e5cc78e4de"}, + {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47d7253b5a10c201cc65aecfb517dfa1c0b5831b2524ac32dd2964fceafc0dc4"}, + {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05970fb640f236767003e62c256a085754536169bac863f4a3502ecb59cbf197"}, + {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0b062d261fa3fac00146cf801896c8cfafe1e41332eb047aa0a36558299daa6"}, + {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:017b7066f18b7b676068f51b1dbdecc02d76d9af10092252b22dcbd03a78ed33"}, + {file = "cramjam-2.9.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:9de33ef3bc006c11fbad1dc8b15341dcc78430df2c5ce1e790dfb729b11ab593"}, + {file = "cramjam-2.9.0-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:b99efaf81be8e381de1cde6574e2c89030ed53994e73b0e75b62d6e232f491c5"}, + {file = "cramjam-2.9.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:36426e3f1920f6aa4c644d007bf9cfad06dd9f1a30cd0a921d72b010492d8447"}, + {file = "cramjam-2.9.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ea9bcaff298f5d35ef67346d474fca388c5cf6d4edab1d06b84868800f88bd36"}, + {file = "cramjam-2.9.0-cp313-none-win32.whl", hash = "sha256:c48da60a5eb481b412e5e462b81ad307fb2203178a2840a743f0a7c5fc1718c9"}, + {file = "cramjam-2.9.0-cp313-none-win_amd64.whl", hash = "sha256:97a6311bd32f301ff1b922bc9de62ace3d9fd845e20efc0f71b4d0239a45b8d2"}, + {file = "cramjam-2.9.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:78e7349f945a83bc48855fb042873092a69b155a088b8c11942eb76418b32705"}, + {file = "cramjam-2.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:65a097ea765dd4ef2fb868b5b0959d7c93a64c250b2c52f462898c823ae4b950"}, + {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:35cad507eb02c775e6c5444312f98b28dd8bf122425677ae199484996e838673"}, + {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8982925d179b940efa860513a31b839bb06343501077cca3e67f7a2f7360d355"}, + {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ba7e2d33e1d092dffd0a3ff4bd1b86177594aa3c2901fd478e78e1fb2aee8ed3"}, + {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:904be92e3bc25e78343ee52aa0fd5fba3a31d11d474e8af4623a9d00baa84bc2"}, + {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9221297c547d702e1431e96705fce26c6a87df34a681a6b97fe63b536d09c1d8"}, + {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e98a18c22a85f321091cc8db6694af1d713a369c2d60ec611c10ccfe24ab103a"}, + {file = "cramjam-2.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e248510f8e2dbc71fa99f86238c9023365dbe1a4520eb40e33d73416527349f2"}, + {file = "cramjam-2.9.0-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:dc07376aa33b6004ea372ac9b0ba0ed3455aa2fc4e18727414142ecb46b176b8"}, + {file = "cramjam-2.9.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e94021c541eb2a199b5a2ffae0ea84fb8b99863dab99a5b154b00bc7a44b5c48"}, + {file = "cramjam-2.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4adbf4366f8dc29b7c5c731c800cf633be76c9911e928daeb606827d6ae7c599"}, + {file = "cramjam-2.9.0-cp38-none-win32.whl", hash = "sha256:ca880f555c8db40942acc8a50722c33e229b6be90e598acc1a201f36487b917d"}, + {file = "cramjam-2.9.0-cp38-none-win_amd64.whl", hash = "sha256:ab17a429a92db90bf40115efb97d10e71b94b0dcacf30cf724552df2794a58fb"}, + {file = "cramjam-2.9.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ed7fd7bc2b86ec3161fe0cc49f5f392e6efa55c91a95397d5047820c38117660"}, + {file = "cramjam-2.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a0f654c739a6bc4a69a2aaf31463328a208757ed780ff886234532f78e06a864"}, + {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cd4d4ab9deb5846af0ac6cf1fa139cfa40291ad14d073efa8b8e20c8d1aa90bd"}, + {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bafc32f01d4ab64f83fdbc29bc5bd25a920b59c751c12e06e6f4b1e379be7600"}, + {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0fb5ea631dbf998f667766a9e485e757817d66ed559916ba553a0ec2f902d788"}, + {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c902e56e60c48f5f15e55257aaa1c2678323df5f18a1b839e8d05cac1107576c"}, + {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:441d3875cdffe5df9294b93ef570058837732dd727cd9d18efa0f089f1c2687a"}, + {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed486e57a79ccc7aebaa2ec12517d891fdc5d2fde16915e3db705b8a47570981"}, + {file = "cramjam-2.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:013cb872205641c6e5269f530ed40aaaa5640d84e0d8f33b89f5a1bf7f655527"}, + {file = "cramjam-2.9.0-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:a41b4b10a381be1d42a1a7dd07b8c3faccd3d12c7e98e973a6ec558fd040a607"}, + {file = "cramjam-2.9.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:598eac1713ddbe69c3b30dcc890d69b206ce08903fc3aed58149aae87c61973a"}, + {file = "cramjam-2.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:72e9ebc27c557706a3c9964c1d1b4522857760dbd60c105a4f5421f3b66e31a2"}, + {file = "cramjam-2.9.0-cp39-none-win32.whl", hash = "sha256:dbbd6fba677e1cbc9d6bd4ebbe3e8b3667d0295f1731489db2a971c95f0ceca0"}, + {file = "cramjam-2.9.0-cp39-none-win_amd64.whl", hash = "sha256:7f33a83969fa94ee8e0c1f0aef8eb303ead3e9142338dc543abeb7e1a28734ab"}, + {file = "cramjam-2.9.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:132db7d3346ea21ba44e7ee23ec73bd6fa9eb1e77133ca6dfe1f7449a69999af"}, + {file = "cramjam-2.9.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2addf801c88bead21256ccd87dc97cffead03758c4a4947fad8e454f4abfda0a"}, + {file = "cramjam-2.9.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24afad3ba62774abbb150dc25aab21b047ab999c4143c7a8d96577848baf7af6"}, + {file = "cramjam-2.9.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:604c16052cf29d0c796927ed7e107f65429d2036c82c9a8009bd453c94e5e4f0"}, + {file = "cramjam-2.9.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:65bded20fd2cef17b22246c336ddd67fac842341ee311042b4a70e65dc745aa7"}, + {file = "cramjam-2.9.0.tar.gz", hash = "sha256:f103e648aa3ebe9b8e2c1a3a92719288d8f3f41007c319ad298cdce2d0c28641"}, ] [package.extras] @@ -637,20 +638,20 @@ typing-inspect = ">=0.4.0,<1" [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "docker" @@ -782,13 +783,13 @@ files = [ [[package]] name = "google-api-core" -version = "2.21.0" +version = "2.23.0" description = "Google API client core library" optional = false python-versions = ">=3.7" files = [ - {file = "google_api_core-2.21.0-py3-none-any.whl", hash = "sha256:6869eacb2a37720380ba5898312af79a4d30b8bca1548fb4093e0697dc4bdf5d"}, - {file = "google_api_core-2.21.0.tar.gz", hash = "sha256:4a152fd11a9f774ea606388d423b68aa7e6d6a0ffe4c8266f74979613ec09f81"}, + {file = "google_api_core-2.23.0-py3-none-any.whl", hash = "sha256:c20100d4c4c41070cf365f1d8ddf5365915291b5eb11b83829fbd1c999b5122f"}, + {file = "google_api_core-2.23.0.tar.gz", hash = "sha256:2ceb087315e6af43f256704b871d99326b1f12a9d6ce99beaedec99ba26a0ace"}, ] [package.dependencies] @@ -806,13 +807,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] [[package]] name = "google-auth" -version = "2.35.0" +version = "2.36.0" description = "Google Authentication Library" optional = false python-versions = ">=3.7" files = [ - {file = "google_auth-2.35.0-py2.py3-none-any.whl", hash = "sha256:25df55f327ef021de8be50bad0dfd4a916ad0de96da86cd05661c9297723ad3f"}, - {file = "google_auth-2.35.0.tar.gz", hash = "sha256:f4c64ed4e01e8e8b646ef34c018f8bf3338df0c8e37d8b3bba40e7f574a3278a"}, + {file = "google_auth-2.36.0-py2.py3-none-any.whl", hash = "sha256:51a15d47028b66fd36e5c64a82d2d57480075bccc7da37cde257fc94177a61fb"}, + {file = "google_auth-2.36.0.tar.gz", hash = "sha256:545e9618f2df0bcbb7dcbc45a546485b1212624716975a1ea5ae8149ce769ab1"}, ] [package.dependencies] @@ -926,13 +927,13 @@ requests = ["requests (>=2.18.0,<3.0.0dev)"] [[package]] name = "googleapis-common-protos" -version = "1.65.0" +version = "1.66.0" description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" files = [ - {file = "googleapis_common_protos-1.65.0-py2.py3-none-any.whl", hash = "sha256:2972e6c496f435b92590fd54045060867f3fe9be2c82ab148fc8885035479a63"}, - {file = "googleapis_common_protos-1.65.0.tar.gz", hash = "sha256:334a29d07cddc3aa01dee4988f9afd9b2916ee2ff49d6b757155dc0d197852c0"}, + {file = "googleapis_common_protos-1.66.0-py2.py3-none-any.whl", hash = "sha256:d7abcd75fabb2e0ec9f74466401f6c119a0b498e27370e9be4c94cb7e382b8ed"}, + {file = "googleapis_common_protos-1.66.0.tar.gz", hash = "sha256:c3e7b33d15fdca5374cc0a7346dd92ffa847425cc4ea941d970f13680052ec8c"}, ] [package.dependencies] @@ -954,13 +955,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -1160,18 +1161,18 @@ six = "*" [[package]] name = "langsmith" -version = "0.1.134" +version = "0.1.145" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.134-py3-none-any.whl", hash = "sha256:ada98ad80ef38807725f32441a472da3dd28394010877751f48f458d3289da04"}, - {file = "langsmith-0.1.134.tar.gz", hash = "sha256:23abee3b508875a0e63c602afafffc02442a19cfd88f9daae05b3e9054fd6b61"}, + {file = "langsmith-0.1.145-py3-none-any.whl", hash = "sha256:bd3001fc6738ad9061a2709d60f62a6bdf4892a17e63c7751f73a6f32a100729"}, + {file = "langsmith-0.1.145.tar.gz", hash = "sha256:b6e53f7b1624846f03769a1fce673baf2a0a262b4f4129b1f6bd127a1f44f8fd"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" @@ -1347,92 +1348,92 @@ testing = ["coverage", "pyyaml"] [[package]] name = "markupsafe" -version = "3.0.1" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" files = [ - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win32.whl", hash = "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win32.whl", hash = "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win32.whl", hash = "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win32.whl", hash = "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win32.whl", hash = "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b"}, - {file = "markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] name = "marshmallow" -version = "3.22.0" +version = "3.23.1" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "marshmallow-3.22.0-py3-none-any.whl", hash = "sha256:71a2dce49ef901c3f97ed296ae5051135fd3febd2bf43afe0ae9a82143a494d9"}, - {file = "marshmallow-3.22.0.tar.gz", hash = "sha256:4972f529104a220bb8637d595aa4c9762afbe7f7a77d82dc58c1615d70c5823e"}, + {file = "marshmallow-3.23.1-py3-none-any.whl", hash = "sha256:fece2eb2c941180ea1b7fcbd4a83c51bfdd50093fdd3ad2585ee5e1df2508491"}, + {file = "marshmallow-3.23.1.tar.gz", hash = "sha256:3a8dfda6edd8dcdbf216c0ede1d1e78d230a6dc9c5a088f58c4083b974a0d468"}, ] [package.dependencies] packaging = ">=17.0" [package.extras] -dev = ["marshmallow[tests]", "pre-commit (>=3.5,<4.0)", "tox"] -docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.13)", "sphinx (==8.0.2)", "sphinx-issues (==4.1.0)", "sphinx-version-warning (==1.1.2)"] -tests = ["pytest", "pytz", "simplejson"] +dev = ["marshmallow[tests]", "pre-commit (>=3.5,<5.0)", "tox"] +docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.14)", "sphinx (==8.1.3)", "sphinx-issues (==5.0.0)", "sphinx-version-warning (==1.1.2)"] +tests = ["pytest", "simplejson"] [[package]] name = "mypy-extensions" @@ -1517,68 +1518,86 @@ files = [ [[package]] name = "orjson" -version = "3.10.7" +version = "3.10.12" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:74f4544f5a6405b90da8ea724d15ac9c36da4d72a738c64685003337401f5c12"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34a566f22c28222b08875b18b0dfbf8a947e69df21a9ed5c51a6bf91cfb944ac"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf6ba8ebc8ef5792e2337fb0419f8009729335bb400ece005606336b7fd7bab7"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac7cf6222b29fbda9e3a472b41e6a5538b48f2c8f99261eecd60aafbdb60690c"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de817e2f5fc75a9e7dd350c4b0f54617b280e26d1631811a43e7e968fa71e3e9"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:348bdd16b32556cf8d7257b17cf2bdb7ab7976af4af41ebe79f9796c218f7e91"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:479fd0844ddc3ca77e0fd99644c7fe2de8e8be1efcd57705b5c92e5186e8a250"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fdf5197a21dd660cf19dfd2a3ce79574588f8f5e2dbf21bda9ee2d2b46924d84"}, - {file = "orjson-3.10.7-cp310-none-win32.whl", hash = "sha256:d374d36726746c81a49f3ff8daa2898dccab6596864ebe43d50733275c629175"}, - {file = "orjson-3.10.7-cp310-none-win_amd64.whl", hash = "sha256:cb61938aec8b0ffb6eef484d480188a1777e67b05d58e41b435c74b9d84e0b9c"}, - {file = "orjson-3.10.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0"}, - {file = "orjson-3.10.7-cp311-none-win32.whl", hash = "sha256:82763b46053727a7168d29c772ed5c870fdae2f61aa8a25994c7984a19b1021f"}, - {file = "orjson-3.10.7-cp311-none-win_amd64.whl", hash = "sha256:eb8d384a24778abf29afb8e41d68fdd9a156cf6e5390c04cc07bbc24b89e98b5"}, - {file = "orjson-3.10.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44a96f2d4c3af51bfac6bc4ef7b182aa33f2f054fd7f34cc0ee9a320d051d41f"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ac14cd57df0572453543f8f2575e2d01ae9e790c21f57627803f5e79b0d3c3"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bdbb61dcc365dd9be94e8f7df91975edc9364d6a78c8f7adb69c1cdff318ec93"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b48b3db6bb6e0a08fa8c83b47bc169623f801e5cc4f24442ab2b6617da3b5313"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23820a1563a1d386414fef15c249040042b8e5d07b40ab3fe3efbfbbcbcb8864"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0c6a008e91d10a2564edbb6ee5069a9e66df3fbe11c9a005cb411f441fd2c09"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d352ee8ac1926d6193f602cbe36b1643bbd1bbcb25e3c1a657a4390f3000c9a5"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b"}, - {file = "orjson-3.10.7-cp312-none-win32.whl", hash = "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb"}, - {file = "orjson-3.10.7-cp312-none-win_amd64.whl", hash = "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1"}, - {file = "orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149"}, - {file = "orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad"}, - {file = "orjson-3.10.7-cp313-none-win32.whl", hash = "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2"}, - {file = "orjson-3.10.7-cp313-none-win_amd64.whl", hash = "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024"}, - {file = "orjson-3.10.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6ea2b2258eff652c82652d5e0f02bd5e0463a6a52abb78e49ac288827aaa1469"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:430ee4d85841e1483d487e7b81401785a5dfd69db5de01314538f31f8fbf7ee1"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b6146e439af4c2472c56f8540d799a67a81226e11992008cb47e1267a9b3225"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:084e537806b458911137f76097e53ce7bf5806dda33ddf6aaa66a028f8d43a23"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829cf2195838e3f93b70fd3b4292156fc5e097aac3739859ac0dcc722b27ac0"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1193b2416cbad1a769f868b1749535d5da47626ac29445803dae7cc64b3f5c98"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4e6c3da13e5a57e4b3dca2de059f243ebec705857522f188f0180ae88badd354"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c31008598424dfbe52ce8c5b47e0752dca918a4fdc4a2a32004efd9fab41d866"}, - {file = "orjson-3.10.7-cp38-none-win32.whl", hash = "sha256:7122a99831f9e7fe977dc45784d3b2edc821c172d545e6420c375e5a935f5a1c"}, - {file = "orjson-3.10.7-cp38-none-win_amd64.whl", hash = "sha256:a763bc0e58504cc803739e7df040685816145a6f3c8a589787084b54ebc9f16e"}, - {file = "orjson-3.10.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e76be12658a6fa376fcd331b1ea4e58f5a06fd0220653450f0d415b8fd0fbe20"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed350d6978d28b92939bfeb1a0570c523f6170efc3f0a0ef1f1df287cd4f4960"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144888c76f8520e39bfa121b31fd637e18d4cc2f115727865fdf9fa325b10412"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09b2d92fd95ad2402188cf51573acde57eb269eddabaa60f69ea0d733e789fe9"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b24a579123fa884f3a3caadaed7b75eb5715ee2b17ab5c66ac97d29b18fe57f"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591bcfe7512353bd609875ab38050efe3d55e18934e2f18950c108334b4ff"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f4db56635b58cd1a200b0a23744ff44206ee6aa428185e2b6c4a65b3197abdcd"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0fa5886854673222618638c6df7718ea7fe2f3f2384c452c9ccedc70b4a510a5"}, - {file = "orjson-3.10.7-cp39-none-win32.whl", hash = "sha256:8272527d08450ab16eb405f47e0f4ef0e5ff5981c3d82afe0efd25dcbef2bcd2"}, - {file = "orjson-3.10.7-cp39-none-win_amd64.whl", hash = "sha256:974683d4618c0c7dbf4f69c95a979734bf183d0658611760017f6e70a145af58"}, - {file = "orjson-3.10.7.tar.gz", hash = "sha256:75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3"}, + {file = "orjson-3.10.12-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ece01a7ec71d9940cc654c482907a6b65df27251255097629d0dea781f255c6d"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c34ec9aebc04f11f4b978dd6caf697a2df2dd9b47d35aa4cc606cabcb9df69d7"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd6ec8658da3480939c79b9e9e27e0db31dffcd4ba69c334e98c9976ac29140e"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f17e6baf4cf01534c9de8a16c0c611f3d94925d1701bf5f4aff17003677d8ced"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6402ebb74a14ef96f94a868569f5dccf70d791de49feb73180eb3c6fda2ade56"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0000758ae7c7853e0a4a6063f534c61656ebff644391e1f81698c1b2d2fc8cd2"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:888442dcee99fd1e5bd37a4abb94930915ca6af4db50e23e746cdf4d1e63db13"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c1f7a3ce79246aa0e92f5458d86c54f257fb5dfdc14a192651ba7ec2c00f8a05"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:802a3935f45605c66fb4a586488a38af63cb37aaad1c1d94c982c40dcc452e85"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1da1ef0113a2be19bb6c557fb0ec2d79c92ebd2fed4cfb1b26bab93f021fb885"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a3273e99f367f137d5b3fecb5e9f45bcdbfac2a8b2f32fbc72129bbd48789c2"}, + {file = "orjson-3.10.12-cp310-none-win32.whl", hash = "sha256:475661bf249fd7907d9b0a2a2421b4e684355a77ceef85b8352439a9163418c3"}, + {file = "orjson-3.10.12-cp310-none-win_amd64.whl", hash = "sha256:87251dc1fb2b9e5ab91ce65d8f4caf21910d99ba8fb24b49fd0c118b2362d509"}, + {file = "orjson-3.10.12-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a734c62efa42e7df94926d70fe7d37621c783dea9f707a98cdea796964d4cf74"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:750f8b27259d3409eda8350c2919a58b0cfcd2054ddc1bd317a643afc646ef23"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb52c22bfffe2857e7aa13b4622afd0dd9d16ea7cc65fd2bf318d3223b1b6252"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:440d9a337ac8c199ff8251e100c62e9488924c92852362cd27af0e67308c16ef"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9e15c06491c69997dfa067369baab3bf094ecb74be9912bdc4339972323f252"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:362d204ad4b0b8724cf370d0cd917bb2dc913c394030da748a3bb632445ce7c4"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2b57cbb4031153db37b41622eac67329c7810e5f480fda4cfd30542186f006ae"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:165c89b53ef03ce0d7c59ca5c82fa65fe13ddf52eeb22e859e58c237d4e33b9b"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5dee91b8dfd54557c1a1596eb90bcd47dbcd26b0baaed919e6861f076583e9da"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77a4e1cfb72de6f905bdff061172adfb3caf7a4578ebf481d8f0530879476c07"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:038d42c7bc0606443459b8fe2d1f121db474c49067d8d14c6a075bbea8bf14dd"}, + {file = "orjson-3.10.12-cp311-none-win32.whl", hash = "sha256:03b553c02ab39bed249bedd4abe37b2118324d1674e639b33fab3d1dafdf4d79"}, + {file = "orjson-3.10.12-cp311-none-win_amd64.whl", hash = "sha256:8b8713b9e46a45b2af6b96f559bfb13b1e02006f4242c156cbadef27800a55a8"}, + {file = "orjson-3.10.12-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:53206d72eb656ca5ac7d3a7141e83c5bbd3ac30d5eccfe019409177a57634b0d"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac8010afc2150d417ebda810e8df08dd3f544e0dd2acab5370cfa6bcc0662f8f"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed459b46012ae950dd2e17150e838ab08215421487371fa79d0eced8d1461d70"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dcb9673f108a93c1b52bfc51b0af422c2d08d4fc710ce9c839faad25020bb69"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22a51ae77680c5c4652ebc63a83d5255ac7d65582891d9424b566fb3b5375ee9"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910fdf2ac0637b9a77d1aad65f803bac414f0b06f720073438a7bd8906298192"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:24ce85f7100160936bc2116c09d1a8492639418633119a2224114f67f63a4559"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a76ba5fc8dd9c913640292df27bff80a685bed3a3c990d59aa6ce24c352f8fc"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ff70ef093895fd53f4055ca75f93f047e088d1430888ca1229393a7c0521100f"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f4244b7018b5753ecd10a6d324ec1f347da130c953a9c88432c7fbc8875d13be"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:16135ccca03445f37921fa4b585cff9a58aa8d81ebcb27622e69bfadd220b32c"}, + {file = "orjson-3.10.12-cp312-none-win32.whl", hash = "sha256:2d879c81172d583e34153d524fcba5d4adafbab8349a7b9f16ae511c2cee8708"}, + {file = "orjson-3.10.12-cp312-none-win_amd64.whl", hash = "sha256:fc23f691fa0f5c140576b8c365bc942d577d861a9ee1142e4db468e4e17094fb"}, + {file = "orjson-3.10.12-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:47962841b2a8aa9a258b377f5188db31ba49af47d4003a32f55d6f8b19006543"}, + {file = "orjson-3.10.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6334730e2532e77b6054e87ca84f3072bee308a45a452ea0bffbbbc40a67e296"}, + {file = "orjson-3.10.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:accfe93f42713c899fdac2747e8d0d5c659592df2792888c6c5f829472e4f85e"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a7974c490c014c48810d1dede6c754c3cc46598da758c25ca3b4001ac45b703f"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3f250ce7727b0b2682f834a3facff88e310f52f07a5dcfd852d99637d386e79e"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f31422ff9486ae484f10ffc51b5ab2a60359e92d0716fcce1b3593d7bb8a9af6"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5f29c5d282bb2d577c2a6bbde88d8fdcc4919c593f806aac50133f01b733846e"}, + {file = "orjson-3.10.12-cp313-none-win32.whl", hash = "sha256:f45653775f38f63dc0e6cd4f14323984c3149c05d6007b58cb154dd080ddc0dc"}, + {file = "orjson-3.10.12-cp313-none-win_amd64.whl", hash = "sha256:229994d0c376d5bdc91d92b3c9e6be2f1fbabd4cc1b59daae1443a46ee5e9825"}, + {file = "orjson-3.10.12-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7d69af5b54617a5fac5c8e5ed0859eb798e2ce8913262eb522590239db6c6763"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ed119ea7d2953365724a7059231a44830eb6bbb0cfead33fcbc562f5fd8f935"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9c5fc1238ef197e7cad5c91415f524aaa51e004be5a9b35a1b8a84ade196f73f"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43509843990439b05f848539d6f6198d4ac86ff01dd024b2f9a795c0daeeab60"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f72e27a62041cfb37a3de512247ece9f240a561e6c8662276beaf4d53d406db4"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a904f9572092bb6742ab7c16c623f0cdccbad9eeb2d14d4aa06284867bddd31"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:855c0833999ed5dc62f64552db26f9be767434917d8348d77bacaab84f787d7b"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:897830244e2320f6184699f598df7fb9db9f5087d6f3f03666ae89d607e4f8ed"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0b32652eaa4a7539f6f04abc6243619c56f8530c53bf9b023e1269df5f7816dd"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:36b4aa31e0f6a1aeeb6f8377769ca5d125db000f05c20e54163aef1d3fe8e833"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5535163054d6cbf2796f93e4f0dbc800f61914c0e3c4ed8499cf6ece22b4a3da"}, + {file = "orjson-3.10.12-cp38-none-win32.whl", hash = "sha256:90a5551f6f5a5fa07010bf3d0b4ca2de21adafbbc0af6cb700b63cd767266cb9"}, + {file = "orjson-3.10.12-cp38-none-win_amd64.whl", hash = "sha256:703a2fb35a06cdd45adf5d733cf613cbc0cb3ae57643472b16bc22d325b5fb6c"}, + {file = "orjson-3.10.12-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f29de3ef71a42a5822765def1febfb36e0859d33abf5c2ad240acad5c6a1b78d"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de365a42acc65d74953f05e4772c974dad6c51cfc13c3240899f534d611be967"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:91a5a0158648a67ff0004cb0df5df7dcc55bfc9ca154d9c01597a23ad54c8d0c"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c47ce6b8d90fe9646a25b6fb52284a14ff215c9595914af63a5933a49972ce36"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0eee4c2c5bfb5c1b47a5db80d2ac7aaa7e938956ae88089f098aff2c0f35d5d8"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35d3081bbe8b86587eb5c98a73b97f13d8f9fea685cf91a579beddacc0d10566"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73c23a6e90383884068bc2dba83d5222c9fcc3b99a0ed2411d38150734236755"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5472be7dc3269b4b52acba1433dac239215366f89dc1d8d0e64029abac4e714e"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:7319cda750fca96ae5973efb31b17d97a5c5225ae0bc79bf5bf84df9e1ec2ab6"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:74d5ca5a255bf20b8def6a2b96b1e18ad37b4a122d59b154c458ee9494377f80"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ff31d22ecc5fb85ef62c7d4afe8301d10c558d00dd24274d4bbe464380d3cd69"}, + {file = "orjson-3.10.12-cp39-none-win32.whl", hash = "sha256:c22c3ea6fba91d84fcb4cda30e64aff548fcf0c44c876e681f47d61d24b12e6b"}, + {file = "orjson-3.10.12-cp39-none-win_amd64.whl", hash = "sha256:be604f60d45ace6b0b33dd990a66b4526f1a7a186ac411c942674625456ca548"}, + {file = "orjson-3.10.12.tar.gz", hash = "sha256:0a78bbda3aea0f9f079057ee1ee8a1ecf790d4f1af88dd67493c6b8ee52506ff"}, ] [[package]] @@ -1734,95 +1753,90 @@ pytzdata = ">=2020.1" [[package]] name = "pillow" -version = "10.4.0" +version = "11.0.0" description = "Python Imaging Library (Fork)" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, - {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, - {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, - {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, - {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, - {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, - {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, - {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, - {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, - {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, - {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, - {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, - {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, - {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, - {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, - {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, - {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, - {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, - {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, - {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, - {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, - {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, - {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, - {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, - {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, - {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, - {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, - {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, - {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, - {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, - {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, - {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, - {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, - {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, - {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, - {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, - {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, - {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, - {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, - {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, - {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, - {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, + {file = "pillow-11.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947"}, + {file = "pillow-11.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f"}, + {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb"}, + {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97"}, + {file = "pillow-11.0.0-cp310-cp310-win32.whl", hash = "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50"}, + {file = "pillow-11.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c"}, + {file = "pillow-11.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1"}, + {file = "pillow-11.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc"}, + {file = "pillow-11.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a"}, + {file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3"}, + {file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5"}, + {file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b"}, + {file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa"}, + {file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306"}, + {file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9"}, + {file = "pillow-11.0.0-cp311-cp311-win32.whl", hash = "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5"}, + {file = "pillow-11.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291"}, + {file = "pillow-11.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9"}, + {file = "pillow-11.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923"}, + {file = "pillow-11.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903"}, + {file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4"}, + {file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f"}, + {file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9"}, + {file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7"}, + {file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6"}, + {file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc"}, + {file = "pillow-11.0.0-cp312-cp312-win32.whl", hash = "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6"}, + {file = "pillow-11.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47"}, + {file = "pillow-11.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25"}, + {file = "pillow-11.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcd1fb5bb7b07f64c15618c89efcc2cfa3e95f0e3bcdbaf4642509de1942a699"}, + {file = "pillow-11.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e038b0745997c7dcaae350d35859c9715c71e92ffb7e0f4a8e8a16732150f38"}, + {file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ae08bd8ffc41aebf578c2af2f9d8749d91f448b3bfd41d7d9ff573d74f2a6b2"}, + {file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d69bfd8ec3219ae71bcde1f942b728903cad25fafe3100ba2258b973bd2bc1b2"}, + {file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:61b887f9ddba63ddf62fd02a3ba7add935d053b6dd7d58998c630e6dbade8527"}, + {file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:c6a660307ca9d4867caa8d9ca2c2658ab685de83792d1876274991adec7b93fa"}, + {file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:73e3a0200cdda995c7e43dd47436c1548f87a30bb27fb871f352a22ab8dcf45f"}, + {file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fba162b8872d30fea8c52b258a542c5dfd7b235fb5cb352240c8d63b414013eb"}, + {file = "pillow-11.0.0-cp313-cp313-win32.whl", hash = "sha256:f1b82c27e89fffc6da125d5eb0ca6e68017faf5efc078128cfaa42cf5cb38798"}, + {file = "pillow-11.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ba470552b48e5835f1d23ecb936bb7f71d206f9dfeee64245f30c3270b994de"}, + {file = "pillow-11.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:846e193e103b41e984ac921b335df59195356ce3f71dcfd155aa79c603873b84"}, + {file = "pillow-11.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4ad70c4214f67d7466bea6a08061eba35c01b1b89eaa098040a35272a8efb22b"}, + {file = "pillow-11.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6ec0d5af64f2e3d64a165f490d96368bb5dea8b8f9ad04487f9ab60dc4bb6003"}, + {file = "pillow-11.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c809a70e43c7977c4a42aefd62f0131823ebf7dd73556fa5d5950f5b354087e2"}, + {file = "pillow-11.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:4b60c9520f7207aaf2e1d94de026682fc227806c6e1f55bba7606d1c94dd623a"}, + {file = "pillow-11.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1e2688958a840c822279fda0086fec1fdab2f95bf2b717b66871c4ad9859d7e8"}, + {file = "pillow-11.0.0-cp313-cp313t-win32.whl", hash = "sha256:607bbe123c74e272e381a8d1957083a9463401f7bd01287f50521ecb05a313f8"}, + {file = "pillow-11.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c39ed17edea3bc69c743a8dd3e9853b7509625c2462532e62baa0732163a904"}, + {file = "pillow-11.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3"}, + {file = "pillow-11.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2e46773dc9f35a1dd28bd6981332fd7f27bec001a918a72a79b4133cf5291dba"}, + {file = "pillow-11.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2679d2258b7f1192b378e2893a8a0a0ca472234d4c2c0e6bdd3380e8dfa21b6a"}, + {file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eda2616eb2313cbb3eebbe51f19362eb434b18e3bb599466a1ffa76a033fb916"}, + {file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ec184af98a121fb2da42642dea8a29ec80fc3efbaefb86d8fdd2606619045d"}, + {file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:8594f42df584e5b4bb9281799698403f7af489fba84c34d53d1c4bfb71b7c4e7"}, + {file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:c12b5ae868897c7338519c03049a806af85b9b8c237b7d675b8c5e089e4a618e"}, + {file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:70fbbdacd1d271b77b7721fe3cdd2d537bbbd75d29e6300c672ec6bb38d9672f"}, + {file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5178952973e588b3f1360868847334e9e3bf49d19e169bbbdfaf8398002419ae"}, + {file = "pillow-11.0.0-cp39-cp39-win32.whl", hash = "sha256:8c676b587da5673d3c75bd67dd2a8cdfeb282ca38a30f37950511766b26858c4"}, + {file = "pillow-11.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:94f3e1780abb45062287b4614a5bc0874519c86a777d4a7ad34978e86428b8dd"}, + {file = "pillow-11.0.0-cp39-cp39-win_arm64.whl", hash = "sha256:290f2cc809f9da7d6d622550bbf4c1e57518212da51b6a30fe8e0a270a5b78bd"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316"}, + {file = "pillow-11.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5bd2d3bdb846d757055910f0a59792d33b555800813c3b39ada1829c372ccb06"}, + {file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:375b8dd15a1f5d2feafff536d47e22f69625c1aa92f12b339ec0b2ca40263273"}, + {file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:daffdf51ee5db69a82dd127eabecce20729e21f7a3680cf7cbb23f0829189790"}, + {file = "pillow-11.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7326a1787e3c7b0429659e0a944725e1b03eeaa10edd945a86dead1913383944"}, + {file = "pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739"}, ] [package.extras] -docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +docs = ["furo", "olefile", "sphinx (>=8.1)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] fpx = ["olefile"] mic = ["olefile"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] @@ -1862,13 +1876,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "proto-plus" -version = "1.24.0" +version = "1.25.0" description = "Beautiful, Pythonic protocol buffers." optional = false python-versions = ">=3.7" files = [ - {file = "proto-plus-1.24.0.tar.gz", hash = "sha256:30b72a5ecafe4406b0d339db35b56c4059064e69227b8c3bda7462397f966445"}, - {file = "proto_plus-1.24.0-py3-none-any.whl", hash = "sha256:402576830425e5f6ce4c2a6702400ac79897dab0b4343821aa5188b0fab81a12"}, + {file = "proto_plus-1.25.0-py3-none-any.whl", hash = "sha256:c91fc4a65074ade8e458e95ef8bac34d4008daa7cce4a12d6707066fca648961"}, + {file = "proto_plus-1.25.0.tar.gz", hash = "sha256:fbb17f57f7bd05a68b7707e745e26528b0b3c34e378db91eef93912c54982d91"}, ] [package.dependencies] @@ -1879,22 +1893,22 @@ testing = ["google-api-core (>=1.31.5)"] [[package]] name = "protobuf" -version = "5.28.2" +version = "5.28.3" description = "" optional = false python-versions = ">=3.8" files = [ - {file = "protobuf-5.28.2-cp310-abi3-win32.whl", hash = "sha256:eeea10f3dc0ac7e6b4933d32db20662902b4ab81bf28df12218aa389e9c2102d"}, - {file = "protobuf-5.28.2-cp310-abi3-win_amd64.whl", hash = "sha256:2c69461a7fcc8e24be697624c09a839976d82ae75062b11a0972e41fd2cd9132"}, - {file = "protobuf-5.28.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a8b9403fc70764b08d2f593ce44f1d2920c5077bf7d311fefec999f8c40f78b7"}, - {file = "protobuf-5.28.2-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:35cfcb15f213449af7ff6198d6eb5f739c37d7e4f1c09b5d0641babf2cc0c68f"}, - {file = "protobuf-5.28.2-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:5e8a95246d581eef20471b5d5ba010d55f66740942b95ba9b872d918c459452f"}, - {file = "protobuf-5.28.2-cp38-cp38-win32.whl", hash = "sha256:87317e9bcda04a32f2ee82089a204d3a2f0d3c8aeed16568c7daf4756e4f1fe0"}, - {file = "protobuf-5.28.2-cp38-cp38-win_amd64.whl", hash = "sha256:c0ea0123dac3399a2eeb1a1443d82b7afc9ff40241433296769f7da42d142ec3"}, - {file = "protobuf-5.28.2-cp39-cp39-win32.whl", hash = "sha256:ca53faf29896c526863366a52a8f4d88e69cd04ec9571ed6082fa117fac3ab36"}, - {file = "protobuf-5.28.2-cp39-cp39-win_amd64.whl", hash = "sha256:8ddc60bf374785fb7cb12510b267f59067fa10087325b8e1855b898a0d81d276"}, - {file = "protobuf-5.28.2-py3-none-any.whl", hash = "sha256:52235802093bd8a2811abbe8bf0ab9c5f54cca0a751fdd3f6ac2a21438bffece"}, - {file = "protobuf-5.28.2.tar.gz", hash = "sha256:59379674ff119717404f7454647913787034f03fe7049cbef1d74a97bb4593f0"}, + {file = "protobuf-5.28.3-cp310-abi3-win32.whl", hash = "sha256:0c4eec6f987338617072592b97943fdbe30d019c56126493111cf24344c1cc24"}, + {file = "protobuf-5.28.3-cp310-abi3-win_amd64.whl", hash = "sha256:91fba8f445723fcf400fdbe9ca796b19d3b1242cd873907979b9ed71e4afe868"}, + {file = "protobuf-5.28.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a3f6857551e53ce35e60b403b8a27b0295f7d6eb63d10484f12bc6879c715687"}, + {file = "protobuf-5.28.3-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:3fa2de6b8b29d12c61911505d893afe7320ce7ccba4df913e2971461fa36d584"}, + {file = "protobuf-5.28.3-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:712319fbdddb46f21abb66cd33cb9e491a5763b2febd8f228251add221981135"}, + {file = "protobuf-5.28.3-cp38-cp38-win32.whl", hash = "sha256:3e6101d095dfd119513cde7259aa703d16c6bbdfae2554dfe5cfdbe94e32d548"}, + {file = "protobuf-5.28.3-cp38-cp38-win_amd64.whl", hash = "sha256:27b246b3723692bf1068d5734ddaf2fccc2cdd6e0c9b47fe099244d80200593b"}, + {file = "protobuf-5.28.3-cp39-cp39-win32.whl", hash = "sha256:135658402f71bbd49500322c0f736145731b16fc79dc8f367ab544a17eab4535"}, + {file = "protobuf-5.28.3-cp39-cp39-win_amd64.whl", hash = "sha256:70585a70fc2dd4818c51287ceef5bdba6387f88a578c86d47bb34669b5552c36"}, + {file = "protobuf-5.28.3-py3-none-any.whl", hash = "sha256:cee1757663fa32a1ee673434fcf3bf24dd54763c79690201208bafec62f19eed"}, + {file = "protobuf-5.28.3.tar.gz", hash = "sha256:64badbc49180a5e401f373f9ce7ab1d18b63f7dd4a9cdc43c92b9f0b481cef7b"}, ] [[package]] @@ -1983,19 +1997,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.1" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.1-py3-none-any.whl", hash = "sha256:a8d20db84de64cf4a7d59e899c2caf0fe9d660c7cfc482528e7020d7dd189a7e"}, + {file = "pydantic-2.10.1.tar.gz", hash = "sha256:a4daca2dc0aa429555e0656d6bf94873a7dc5f54ee42b1f5873d666fb3f35560"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.1" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -2003,100 +2017,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.1" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206"}, + {file = "pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c"}, + {file = "pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc"}, + {file = "pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9"}, + {file = "pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5"}, + {file = "pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae"}, + {file = "pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c"}, + {file = "pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16"}, + {file = "pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23"}, + {file = "pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05"}, + {file = "pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337"}, + {file = "pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:5897bec80a09b4084aee23f9b73a9477a46c3304ad1d2d07acca19723fb1de62"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d0165ab2914379bd56908c02294ed8405c252250668ebcb438a55494c69f44ab"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b9af86e1d8e4cfc82c2022bfaa6f459381a50b94a29e95dcdda8442d6d83864"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f6c8a66741c5f5447e047ab0ba7a1c61d1e95580d64bce852e3df1f895c4067"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a42d6a8156ff78981f8aa56eb6394114e0dedb217cf8b729f438f643608cbcd"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64c65f40b4cd8b0e049a8edde07e38b476da7e3aaebe63287c899d2cff253fa5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdcf339322a3fae5cbd504edcefddd5a50d9ee00d968696846f089b4432cf78"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf99c8404f008750c846cb4ac4667b798a9f7de673ff719d705d9b2d6de49c5f"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f1edcea27918d748c7e5e4d917297b2a0ab80cad10f86631e488b7cddf76a36"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:159cac0a3d096f79ab6a44d77a961917219707e2a130739c64d4dd46281f5c2a"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:029d9757eb621cc6e1848fa0b0310310de7301057f623985698ed7ebb014391b"}, + {file = "pydantic_core-2.27.1-cp38-none-win32.whl", hash = "sha256:a28af0695a45f7060e6f9b7092558a928a28553366519f64083c63a44f70e618"}, + {file = "pydantic_core-2.27.1-cp38-none-win_amd64.whl", hash = "sha256:2d4567c850905d5eaaed2f7a404e61012a51caf288292e016360aa2b96ff38d4"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:e9386266798d64eeb19dd3677051f5705bf873e98e15897ddb7d76f477131967"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4228b5b646caa73f119b1ae756216b59cc6e2267201c27d3912b592c5e323b60"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3dfe500de26c52abe0477dde16192ac39c98f05bf2d80e76102d394bd13854"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aee66be87825cdf72ac64cb03ad4c15ffef4143dbf5c113f64a5ff4f81477bf9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b748c44bb9f53031c8cbc99a8a061bc181c1000c60a30f55393b6e9c45cc5bd"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ca038c7f6a0afd0b2448941b6ef9d5e1949e999f9e5517692eb6da58e9d44be"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e0bd57539da59a3e4671b90a502da9a28c72322a4f17866ba3ac63a82c4498e"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac6c2c45c847bbf8f91930d88716a0fb924b51e0c6dad329b793d670ec5db792"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b94d4ba43739bbe8b0ce4262bcc3b7b9f31459ad120fb595627eaeb7f9b9ca01"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:00e6424f4b26fe82d44577b4c842d7df97c20be6439e8e685d0d715feceb9fb9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:38de0a70160dd97540335b7ad3a74571b24f1dc3ed33f815f0880682e6880131"}, + {file = "pydantic_core-2.27.1-cp39-none-win32.whl", hash = "sha256:7ccebf51efc61634f6c2344da73e366c75e735960b5654b63d7e6f69a5885fa3"}, + {file = "pydantic_core-2.27.1-cp39-none-win_amd64.whl", hash = "sha256:a57847b090d7892f123726202b7daa20df6694cbd583b67a592e856bff603d6c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5fde892e6c697ce3e30c61b239330fc5d569a71fefd4eb6512fc6caec9dd9e2f"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:816f5aa087094099fff7edabb5e01cc370eb21aa1a1d44fe2d2aefdfb5599b31"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c10c309e18e443ddb108f0ef64e8729363adbfd92d6d57beec680f6261556f3"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98476c98b02c8e9b2eec76ac4156fd006628b1b2d0ef27e548ffa978393fd154"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c3027001c28434e7ca5a6e1e527487051136aa81803ac812be51802150d880dd"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7699b1df36a48169cdebda7ab5a2bac265204003f153b4bd17276153d997670a"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1c39b07d90be6b48968ddc8c19e7585052088fd7ec8d568bb31ff64c70ae3c97"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:46ccfe3032b3915586e469d4972973f893c0a2bb65669194a5bdea9bacc088c2"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:62ba45e21cf6571d7f716d903b5b7b6d2617e2d5d67c0923dc47b9d41369f840"}, + {file = "pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235"}, ] [package.dependencies] @@ -2104,13 +2129,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.0" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.0-py3-none-any.whl", hash = "sha256:543b77207db656de204372350926bed5a86201c4cbff159f623f79c7bb487a15"}, + {file = "pyjwt-2.10.0.tar.gz", hash = "sha256:7628a7eb7938959ac1b26e819a1df0fd3259505627b575e4bad6d08f76db695c"}, ] [package.extras] @@ -2369,17 +2394,17 @@ typing-extensions = ">=4.9.0" [[package]] name = "python-iso639" -version = "2024.4.27" +version = "2024.10.22" description = "ISO 639 language codes, names, and other associated information" optional = false python-versions = ">=3.8" files = [ - {file = "python_iso639-2024.4.27-py3-none-any.whl", hash = "sha256:27526a84cebc4c4d53fea9d1ebbc7209c8d279bebaa343e6765a1fc8780565ab"}, - {file = "python_iso639-2024.4.27.tar.gz", hash = "sha256:97e63b5603e085c6a56a12a95740010e75d9134e0aab767e0978b53fd8824f13"}, + {file = "python_iso639-2024.10.22-py3-none-any.whl", hash = "sha256:02d3ce2e01c6896b30b9cbbd3e1c8ee0d7221250b5d63ea9803e0d2a81fd1047"}, + {file = "python_iso639-2024.10.22.tar.gz", hash = "sha256:750f21b6a0bc6baa24253a3d8aae92b582bf93aa40988361cd96852c2c6d9a52"}, ] [package.extras] -dev = ["black (==24.4.2)", "build (==1.2.1)", "flake8 (==7.0.0)", "pytest (==8.1.2)", "requests (==2.31.0)", "twine (==5.0.0)"] +dev = ["black (==24.10.0)", "build (==1.2.1)", "flake8 (==7.1.1)", "pytest (==8.3.3)", "requests (==2.32.3)", "twine (==5.1.1)"] [[package]] name = "python-magic" @@ -2445,29 +2470,29 @@ files = [ [[package]] name = "pywin32" -version = "307" +version = "308" description = "Python for Window Extensions" optional = false python-versions = "*" files = [ - {file = "pywin32-307-cp310-cp310-win32.whl", hash = "sha256:f8f25d893c1e1ce2d685ef6d0a481e87c6f510d0f3f117932781f412e0eba31b"}, - {file = "pywin32-307-cp310-cp310-win_amd64.whl", hash = "sha256:36e650c5e5e6b29b5d317385b02d20803ddbac5d1031e1f88d20d76676dd103d"}, - {file = "pywin32-307-cp310-cp310-win_arm64.whl", hash = "sha256:0c12d61e0274e0c62acee79e3e503c312426ddd0e8d4899c626cddc1cafe0ff4"}, - {file = "pywin32-307-cp311-cp311-win32.whl", hash = "sha256:fec5d27cc893178fab299de911b8e4d12c5954e1baf83e8a664311e56a272b75"}, - {file = "pywin32-307-cp311-cp311-win_amd64.whl", hash = "sha256:987a86971753ed7fdd52a7fb5747aba955b2c7fbbc3d8b76ec850358c1cc28c3"}, - {file = "pywin32-307-cp311-cp311-win_arm64.whl", hash = "sha256:fd436897c186a2e693cd0437386ed79f989f4d13d6f353f8787ecbb0ae719398"}, - {file = "pywin32-307-cp312-cp312-win32.whl", hash = "sha256:07649ec6b01712f36debf39fc94f3d696a46579e852f60157a729ac039df0815"}, - {file = "pywin32-307-cp312-cp312-win_amd64.whl", hash = "sha256:00d047992bb5dcf79f8b9b7c81f72e0130f9fe4b22df613f755ab1cc021d8347"}, - {file = "pywin32-307-cp312-cp312-win_arm64.whl", hash = "sha256:b53658acbfc6a8241d72cc09e9d1d666be4e6c99376bc59e26cdb6223c4554d2"}, - {file = "pywin32-307-cp313-cp313-win32.whl", hash = "sha256:ea4d56e48dc1ab2aa0a5e3c0741ad6e926529510516db7a3b6981a1ae74405e5"}, - {file = "pywin32-307-cp313-cp313-win_amd64.whl", hash = "sha256:576d09813eaf4c8168d0bfd66fb7cb3b15a61041cf41598c2db4a4583bf832d2"}, - {file = "pywin32-307-cp313-cp313-win_arm64.whl", hash = "sha256:b30c9bdbffda6a260beb2919f918daced23d32c79109412c2085cbc513338a0a"}, - {file = "pywin32-307-cp37-cp37m-win32.whl", hash = "sha256:5101472f5180c647d4525a0ed289ec723a26231550dbfd369ec19d5faf60e511"}, - {file = "pywin32-307-cp37-cp37m-win_amd64.whl", hash = "sha256:05de55a7c110478dc4b202230e98af5e0720855360d2b31a44bb4e296d795fba"}, - {file = "pywin32-307-cp38-cp38-win32.whl", hash = "sha256:13d059fb7f10792542082f5731d5d3d9645320fc38814759313e5ee97c3fac01"}, - {file = "pywin32-307-cp38-cp38-win_amd64.whl", hash = "sha256:7e0b2f93769d450a98ac7a31a087e07b126b6d571e8b4386a5762eb85325270b"}, - {file = "pywin32-307-cp39-cp39-win32.whl", hash = "sha256:55ee87f2f8c294e72ad9d4261ca423022310a6e79fb314a8ca76ab3f493854c6"}, - {file = "pywin32-307-cp39-cp39-win_amd64.whl", hash = "sha256:e9d5202922e74985b037c9ef46778335c102b74b95cec70f629453dbe7235d87"}, + {file = "pywin32-308-cp310-cp310-win32.whl", hash = "sha256:796ff4426437896550d2981b9c2ac0ffd75238ad9ea2d3bfa67a1abd546d262e"}, + {file = "pywin32-308-cp310-cp310-win_amd64.whl", hash = "sha256:4fc888c59b3c0bef905ce7eb7e2106a07712015ea1c8234b703a088d46110e8e"}, + {file = "pywin32-308-cp310-cp310-win_arm64.whl", hash = "sha256:a5ab5381813b40f264fa3495b98af850098f814a25a63589a8e9eb12560f450c"}, + {file = "pywin32-308-cp311-cp311-win32.whl", hash = "sha256:5d8c8015b24a7d6855b1550d8e660d8daa09983c80e5daf89a273e5c6fb5095a"}, + {file = "pywin32-308-cp311-cp311-win_amd64.whl", hash = "sha256:575621b90f0dc2695fec346b2d6302faebd4f0f45c05ea29404cefe35d89442b"}, + {file = "pywin32-308-cp311-cp311-win_arm64.whl", hash = "sha256:100a5442b7332070983c4cd03f2e906a5648a5104b8a7f50175f7906efd16bb6"}, + {file = "pywin32-308-cp312-cp312-win32.whl", hash = "sha256:587f3e19696f4bf96fde9d8a57cec74a57021ad5f204c9e627e15c33ff568897"}, + {file = "pywin32-308-cp312-cp312-win_amd64.whl", hash = "sha256:00b3e11ef09ede56c6a43c71f2d31857cf7c54b0ab6e78ac659497abd2834f47"}, + {file = "pywin32-308-cp312-cp312-win_arm64.whl", hash = "sha256:9b4de86c8d909aed15b7011182c8cab38c8850de36e6afb1f0db22b8959e3091"}, + {file = "pywin32-308-cp313-cp313-win32.whl", hash = "sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed"}, + {file = "pywin32-308-cp313-cp313-win_amd64.whl", hash = "sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4"}, + {file = "pywin32-308-cp313-cp313-win_arm64.whl", hash = "sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd"}, + {file = "pywin32-308-cp37-cp37m-win32.whl", hash = "sha256:1f696ab352a2ddd63bd07430080dd598e6369152ea13a25ebcdd2f503a38f1ff"}, + {file = "pywin32-308-cp37-cp37m-win_amd64.whl", hash = "sha256:13dcb914ed4347019fbec6697a01a0aec61019c1046c2b905410d197856326a6"}, + {file = "pywin32-308-cp38-cp38-win32.whl", hash = "sha256:5794e764ebcabf4ff08c555b31bd348c9025929371763b2183172ff4708152f0"}, + {file = "pywin32-308-cp38-cp38-win_amd64.whl", hash = "sha256:3b92622e29d651c6b783e368ba7d6722b1634b8e70bd376fd7610fe1992e19de"}, + {file = "pywin32-308-cp39-cp39-win32.whl", hash = "sha256:7873ca4dc60ab3287919881a7d4f88baee4a6e639aa6962de25a98ba6b193341"}, + {file = "pywin32-308-cp39-cp39-win_amd64.whl", hash = "sha256:71b3322d949b4cc20776436a9c9ba0eeedcbc9c650daa536df63f0ff111bb920"}, ] [[package]] @@ -2534,99 +2559,99 @@ files = [ [[package]] name = "rapidfuzz" -version = "3.10.0" +version = "3.10.1" description = "rapid fuzzy string matching" optional = false python-versions = ">=3.9" files = [ - {file = "rapidfuzz-3.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:884453860de029380dded8f3c1918af2d8eb5adf8010261645c7e5c88c2b5428"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718c9bd369288aca5fa929df6dbf66fdbe9768d90940a940c0b5cdc96ade4309"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a68e3724b7dab761c01816aaa64b0903734d999d5589daf97c14ef5cc0629a8e"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1af60988d47534246d9525f77288fdd9de652608a4842815d9018570b959acc6"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3084161fc3e963056232ef8d937449a2943852e07101f5a136c8f3cfa4119217"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6cd67d3d017296d98ff505529104299f78433e4b8af31b55003d901a62bbebe9"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b11a127ac590fc991e8a02c2d7e1ac86e8141c92f78546f18b5c904064a0552c"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aadce42147fc09dcef1afa892485311e824c050352e1aa6e47f56b9b27af4cf0"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b54853c2371bf0e38d67da379519deb6fbe70055efb32f6607081641af3dc752"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ce19887268e90ee81a3957eef5e46a70ecc000713796639f83828b950343f49e"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f39a2a5ded23b9b9194ec45740dce57177b80f86c6d8eba953d3ff1a25c97766"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0ec338d5f4ad8d9339a88a08db5c23e7f7a52c2b2a10510c48a0cef1fb3f0ddc"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-win32.whl", hash = "sha256:56fd15ea8f4c948864fa5ebd9261c67cf7b89a1c517a0caef4df75446a7af18c"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:43dfc5e733808962a822ff6d9c29f3039a3cfb3620706f5953e17cfe4496724c"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-win_arm64.whl", hash = "sha256:ae7966f205b5a7fde93b44ca8fed37c1c8539328d7f179b1197de34eceaceb5f"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bb0013795b40db5cf361e6f21ee7cda09627cf294977149b50e217d7fe9a2f03"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:69ef5b363afff7150a1fbe788007e307b9802a2eb6ad92ed51ab94e6ad2674c6"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c582c46b1bb0b19f1a5f4c1312f1b640c21d78c371a6615c34025b16ee56369b"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:288f6f6e7410cacb115fb851f3f18bf0e4231eb3f6cb5bd1cec0e7b25c4d039d"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9e29a13d2fd9be3e7d8c26c7ef4ba60b5bc7efbc9dbdf24454c7e9ebba31768"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea2da0459b951ee461bd4e02b8904890bd1c4263999d291c5cd01e6620177ad4"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:457827ba82261aa2ae6ac06a46d0043ab12ba7216b82d87ae1434ec0f29736d6"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5d350864269d56f51ab81ab750c9259ae5cad3152c0680baef143dcec92206a1"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a9b8f51e08c3f983d857c3889930af9ddecc768453822076683664772d87e374"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7f3a6aa6e70fc27e4ff5c479f13cc9fc26a56347610f5f8b50396a0d344c5f55"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:803f255f10d63420979b1909ef976e7d30dec42025c9b067fc1d2040cc365a7e"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2026651761bf83a0f31495cc0f70840d5c0d54388f41316e3f9cb51bd85e49a5"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-win32.whl", hash = "sha256:4df75b3ebbb8cfdb9bf8b213b168620b88fd92d0c16a8bc9f9234630b282db59"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:f9f0bbfb6787b97c51516f3ccf97737d504db5d239ad44527673b81f598b84ab"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-win_arm64.whl", hash = "sha256:10fdad800441b9c97d471a937ba7d42625f1b530db05e572f1cb7d401d95c893"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7dc87073ba3a40dd65591a2100aa71602107443bf10770579ff9c8a3242edb94"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a425a0a868cf8e9c6e93e1cda4b758cdfd314bb9a4fc916c5742c934e3613480"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a86d5d1d75e61df060c1e56596b6b0a4422a929dff19cc3dbfd5eee762c86b61"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34f213d59219a9c3ca14e94a825f585811a68ac56b4118b4dc388b5b14afc108"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96ad46f5f56f70fab2be9e5f3165a21be58d633b90bf6e67fc52a856695e4bcf"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9178277f72d144a6c7704d7ae7fa15b7b86f0f0796f0e1049c7b4ef748a662ef"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76a35e9e19a7c883c422ffa378e9a04bc98cb3b29648c5831596401298ee51e6"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a6405d34c394c65e4f73a1d300c001f304f08e529d2ed6413b46ee3037956eb"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bd393683129f446a75d8634306aed7e377627098a1286ff3af2a4f1736742820"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b0445fa9880ead81f5a7d0efc0b9c977a947d8052c43519aceeaf56eabaf6843"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:c50bc308fa29767ed8f53a8d33b7633a9e14718ced038ed89d41b886e301da32"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e89605afebbd2d4b045bccfdc12a14b16fe8ccbae05f64b4b4c64a97dad1c891"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-win32.whl", hash = "sha256:2db9187f3acf3cd33424ecdbaad75414c298ecd1513470df7bda885dcb68cc15"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:50e3d0c72ea15391ba9531ead7f2068a67c5b18a6a365fef3127583aaadd1725"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-win_arm64.whl", hash = "sha256:9eac95b4278bd53115903d89118a2c908398ee8bdfd977ae844f1bd2b02b917c"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fe5231e8afd069c742ac5b4f96344a0fe4aff52df8e53ef87faebf77f827822c"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:886882367dbc985f5736356105798f2ae6e794e671fc605476cbe2e73838a9bb"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b33e13e537e3afd1627d421a142a12bbbe601543558a391a6fae593356842f6e"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:094c26116d55bf9c53abd840d08422f20da78ec4c4723e5024322321caedca48"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:545fc04f2d592e4350f59deb0818886c1b444ffba3bec535b4fbb97191aaf769"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:916a6abf3632e592b937c3d04c00a6efadd8fd30539cdcd4e6e4d92be7ca5d90"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb6ec40cef63b1922083d33bfef2f91fc0b0bc07b5b09bfee0b0f1717d558292"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c77a7330dd15c7eb5fd3631dc646fc96327f98db8181138766bd14d3e905f0ba"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:949b5e9eeaa4ecb4c7e9c2a4689dddce60929dd1ff9c76a889cdbabe8bbf2171"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b5363932a5aab67010ae1a6205c567d1ef256fb333bc23c27582481606be480c"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5dd6eec15b13329abe66cc241b484002ecb0e17d694491c944a22410a6a9e5e2"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79e7f98525b60b3c14524e0a4e1fedf7654657b6e02eb25f1be897ab097706f3"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-win32.whl", hash = "sha256:d29d1b9857c65f8cb3a29270732e1591b9bacf89de9d13fa764f79f07d8f1fd2"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:fa9720e56663cc3649d62b4b5f3145e94b8f5611e8a8e1b46507777249d46aad"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-win_arm64.whl", hash = "sha256:eda4c661e68dddd56c8fbfe1ca35e40dd2afd973f7ebb1605f4d151edc63dff8"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cffbc50e0767396ed483900900dd58ce4351bc0d40e64bced8694bd41864cc71"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c038b9939da3035afb6cb2f465f18163e8f070aba0482923ecff9443def67178"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca366c2e2a54e2f663f4529b189fdeb6e14d419b1c78b754ec1744f3c01070d4"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c4c82b1689b23b1b5e6a603164ed2be41b6f6de292a698b98ba2381e889eb9d"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98f6ebe28831a482981ecfeedc8237047878424ad0c1add2c7f366ba44a20452"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4bd1a7676ee2a4c8e2f7f2550bece994f9f89e58afb96088964145a83af7408b"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec9139baa3f85b65adc700eafa03ed04995ca8533dd56c924f0e458ffec044ab"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:26de93e6495078b6af4c4d93a42ca067b16cc0e95699526c82ab7d1025b4d3bf"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f3a0bda83c18195c361b5500377d0767749f128564ca95b42c8849fd475bb327"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:63e4c175cbce8c3adc22dca5e6154588ae673f6c55374d156f3dac732c88d7de"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4dd3d8443970eaa02ab5ae45ce584b061f2799cd9f7e875190e2617440c1f9d4"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e5ddb2388610799fc46abe389600625058f2a73867e63e20107c5ad5ffa57c47"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-win32.whl", hash = "sha256:2e9be5d05cd960914024412b5406fb75a82f8562f45912ff86255acbfdbfb78e"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:47aca565a39c9a6067927871973ca827023e8b65ba6c5747f4c228c8d7ddc04f"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-win_arm64.whl", hash = "sha256:b0732343cdc4273b5921268026dd7266f75466eb21873cb7635a200d9d9c3fac"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f744b5eb1469bf92dd143d36570d2bdbbdc88fe5cb0b5405e53dd34f479cbd8a"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b67cc21a14327a0eb0f47bc3d7e59ec08031c7c55220ece672f9476e7a8068d3"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fe5783676f0afba4a522c80b15e99dbf4e393c149ab610308a8ef1f04c6bcc8"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4688862f957c8629d557d084f20b2d803f8738b6c4066802a0b1cc472e088d9"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20bd153aacc244e4c907d772c703fea82754c4db14f8aa64d75ff81b7b8ab92d"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:50484d563f8bfa723c74c944b0bb15b9e054db9c889348c8c307abcbee75ab92"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5897242d455461f2c5b82d7397b29341fd11e85bf3608a522177071044784ee8"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:116c71a81e046ba56551d8ab68067ca7034d94b617545316d460a452c5c3c289"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0a547e4350d1fa32624d3eab51eff8cf329f4cae110b4ea0402486b1da8be40"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:399b9b79ccfcf50ca3bad7692bc098bb8eade88d7d5e15773b7f866c91156d0c"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7947a425d1be3e744707ee58c6cb318b93a56e08f080722dcc0347e0b7a1bb9a"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:94c48b4a2a4b1d22246f48e2b11cae01ec7d23f0c9123f8bb822839ad79d0a88"}, - {file = "rapidfuzz-3.10.0.tar.gz", hash = "sha256:6b62af27e65bb39276a66533655a2fa3c60a487b03935721c45b7809527979be"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f17d9f21bf2f2f785d74f7b0d407805468b4c173fa3e52c86ec94436b338e74a"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b31f358a70efc143909fb3d75ac6cd3c139cd41339aa8f2a3a0ead8315731f2b"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f4f43f2204b56a61448ec2dd061e26fd344c404da99fb19f3458200c5874ba2"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d81bf186a453a2757472133b24915768abc7c3964194406ed93e170e16c21cb"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3611c8f45379a12063d70075c75134f2a8bd2e4e9b8a7995112ddae95ca1c982"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c3b537b97ac30da4b73930fa8a4fe2f79c6d1c10ad535c5c09726612cd6bed9"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:231ef1ec9cf7b59809ce3301006500b9d564ddb324635f4ea8f16b3e2a1780da"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ed4f3adc1294834955b7e74edd3c6bd1aad5831c007f2d91ea839e76461a5879"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:7b6015da2e707bf632a71772a2dbf0703cff6525732c005ad24987fe86e8ec32"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1b35a118d61d6f008e8e3fb3a77674d10806a8972c7b8be433d6598df4d60b01"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:bc308d79a7e877226f36bdf4e149e3ed398d8277c140be5c1fd892ec41739e6d"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f017dbfecc172e2d0c37cf9e3d519179d71a7f16094b57430dffc496a098aa17"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-win32.whl", hash = "sha256:36c0e1483e21f918d0f2f26799fe5ac91c7b0c34220b73007301c4f831a9c4c7"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:10746c1d4c8cd8881c28a87fd7ba0c9c102346dfe7ff1b0d021cdf093e9adbff"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-win_arm64.whl", hash = "sha256:dfa64b89dcb906835e275187569e51aa9d546a444489e97aaf2cc84011565fbe"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:92958ae075c87fef393f835ed02d4fe8d5ee2059a0934c6c447ea3417dfbf0e8"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ba7521e072c53e33c384e78615d0718e645cab3c366ecd3cc8cb732befd94967"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d02cbd75d283c287471b5b3738b3e05c9096150f93f2d2dfa10b3d700f2db9"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:efa1582a397da038e2f2576c9cd49b842f56fde37d84a6b0200ffebc08d82350"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f12912acee1f506f974f58de9fdc2e62eea5667377a7e9156de53241c05fdba8"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666d5d8b17becc3f53447bcb2b6b33ce6c2df78792495d1fa82b2924cd48701a"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26f71582c0d62445067ee338ddad99b655a8f4e4ed517a90dcbfbb7d19310474"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8a2ef08b27167bcff230ffbfeedd4c4fa6353563d6aaa015d725dd3632fc3de7"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:365e4fc1a2b95082c890f5e98489b894e6bf8c338c6ac89bb6523c2ca6e9f086"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1996feb7a61609fa842e6b5e0c549983222ffdedaf29644cc67e479902846dfe"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:cf654702f144beaa093103841a2ea6910d617d0bb3fccb1d1fd63c54dde2cd49"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec108bf25de674781d0a9a935030ba090c78d49def3d60f8724f3fc1e8e75024"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-win32.whl", hash = "sha256:031f8b367e5d92f7a1e27f7322012f3c321c3110137b43cc3bf678505583ef48"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:f98f36c6a1bb9a6c8bbec99ad87c8c0e364f34761739b5ea9adf7b48129ae8cf"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-win_arm64.whl", hash = "sha256:f1da2028cb4e41be55ee797a82d6c1cf589442504244249dfeb32efc608edee7"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1340b56340896bede246f612b6ecf685f661a56aabef3d2512481bfe23ac5835"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2316515169b7b5a453f0ce3adbc46c42aa332cae9f2edb668e24d1fc92b2f2bb"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e06fe6a12241ec1b72c0566c6b28cda714d61965d86569595ad24793d1ab259"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d99c1cd9443b19164ec185a7d752f4b4db19c066c136f028991a480720472e23"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1d9aa156ed52d3446388ba4c2f335e312191d1ca9d1f5762ee983cf23e4ecf6"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:54bcf4efaaee8e015822be0c2c28214815f4f6b4f70d8362cfecbd58a71188ac"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0c955e32afdbfdf6e9ee663d24afb25210152d98c26d22d399712d29a9b976b"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:191633722203f5b7717efcb73a14f76f3b124877d0608c070b827c5226d0b972"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:195baad28057ec9609e40385991004e470af9ef87401e24ebe72c064431524ab"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0fff4a6b87c07366662b62ae994ffbeadc472e72f725923f94b72a3db49f4671"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4ffed25f9fdc0b287f30a98467493d1e1ce5b583f6317f70ec0263b3c97dbba6"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d02cf8e5af89a9ac8f53c438ddff6d773f62c25c6619b29db96f4aae248177c0"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-win32.whl", hash = "sha256:f3bb81d4fe6a5d20650f8c0afcc8f6e1941f6fecdb434f11b874c42467baded0"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:aaf83e9170cb1338922ae42d320699dccbbdca8ffed07faeb0b9257822c26e24"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-win_arm64.whl", hash = "sha256:c5da802a0d085ad81b0f62828fb55557996c497b2d0b551bbdfeafd6d447892f"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fc22d69a1c9cccd560a5c434c0371b2df0f47c309c635a01a913e03bbf183710"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38b0dac2c8e057562b8f0d8ae5b663d2d6a28c5ab624de5b73cef9abb6129a24"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fde3bbb14e92ce8fcb5c2edfff72e474d0080cadda1c97785bf4822f037a309"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9141fb0592e55f98fe9ac0f3ce883199b9c13e262e0bf40c5b18cdf926109d16"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:237bec5dd1bfc9b40bbd786cd27949ef0c0eb5fab5eb491904c6b5df59d39d3c"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18123168cba156ab5794ea6de66db50f21bb3c66ae748d03316e71b27d907b95"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b75fe506c8e02769cc47f5ab21ce3e09b6211d3edaa8f8f27331cb6988779be"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9da82aa4b46973aaf9e03bb4c3d6977004648c8638febfc0f9d237e865761270"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c34c022d5ad564f1a5a57a4a89793bd70d7bad428150fb8ff2760b223407cdcf"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1e96c84d6c2a0ca94e15acb5399118fff669f4306beb98a6d8ec6f5dccab4412"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e8e154b84a311263e1aca86818c962e1fa9eefdd643d1d5d197fcd2738f88cb9"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:335fee93188f8cd585552bb8057228ce0111bd227fa81bfd40b7df6b75def8ab"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-win32.whl", hash = "sha256:6729b856166a9e95c278410f73683957ea6100c8a9d0a8dbe434c49663689255"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-win_amd64.whl", hash = "sha256:0e06d99ad1ad97cb2ef7f51ec6b1fedd74a3a700e4949353871cf331d07b382a"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-win_arm64.whl", hash = "sha256:8d1b7082104d596a3eb012e0549b2634ed15015b569f48879701e9d8db959dbb"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:779027d3307e1a2b1dc0c03c34df87a470a368a1a0840a9d2908baf2d4067956"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:440b5608ab12650d0390128d6858bc839ae77ffe5edf0b33a1551f2fa9860651"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cac41a411e07a6f3dc80dfbd33f6be70ea0abd72e99c59310819d09f07d945"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:958473c9f0bca250590200fd520b75be0dbdbc4a7327dc87a55b6d7dc8d68552"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ef60dfa73749ef91cb6073be1a3e135f4846ec809cc115f3cbfc6fe283a5584"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7fbac18f2c19fc983838a60611e67e3262e36859994c26f2ee85bb268de2355"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a0d519ff39db887cd73f4e297922786d548f5c05d6b51f4e6754f452a7f4296"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bebb7bc6aeb91cc57e4881b222484c26759ca865794187217c9dcea6c33adae6"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fe07f8b9c3bb5c5ad1d2c66884253e03800f4189a60eb6acd6119ebaf3eb9894"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:bfa48a4a2d45a41457f0840c48e579db157a927f4e97acf6e20df8fc521c79de"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2cf44d01bfe8ee605b7eaeecbc2b9ca64fc55765f17b304b40ed8995f69d7716"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e6bbca9246d9eedaa1c84e04a7f555493ba324d52ae4d9f3d9ddd1b740dcd87"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-win32.whl", hash = "sha256:567f88180f2c1423b4fe3f3ad6e6310fc97b85bdba574801548597287fc07028"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:6b2cd7c29d6ecdf0b780deb587198f13213ac01c430ada6913452fd0c40190fc"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-win_arm64.whl", hash = "sha256:9f912d459e46607ce276128f52bea21ebc3e9a5ccf4cccfef30dd5bddcf47be8"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ac4452f182243cfab30ba4668ef2de101effaedc30f9faabb06a095a8c90fd16"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:565c2bd4f7d23c32834652b27b51dd711814ab614b4e12add8476be4e20d1cf5"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:187d9747149321607be4ccd6f9f366730078bed806178ec3eeb31d05545e9e8f"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:616290fb9a8fa87e48cb0326d26f98d4e29f17c3b762c2d586f2b35c1fd2034b"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:073a5b107e17ebd264198b78614c0206fa438cce749692af5bc5f8f484883f50"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:39c4983e2e2ccb9732f3ac7d81617088822f4a12291d416b09b8a1eadebb3e29"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ac7adee6bcf0c6fee495d877edad1540a7e0f5fc208da03ccb64734b43522d7a"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:425f4ac80b22153d391ee3f94bc854668a0c6c129f05cf2eaf5ee74474ddb69e"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65a2fa13e8a219f9b5dcb9e74abe3ced5838a7327e629f426d333dfc8c5a6e66"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75561f3df9a906aaa23787e9992b228b1ab69007932dc42070f747103e177ba8"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:edd062490537e97ca125bc6c7f2b7331c2b73d21dc304615afe61ad1691e15d5"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfcc8feccf63245a22dfdd16e222f1a39771a44b870beb748117a0e09cbb4a62"}, + {file = "rapidfuzz-3.10.1.tar.gz", hash = "sha256:5a15546d847a915b3f42dc79ef9b0c78b998b4e2c53b252e7166284066585979"}, ] [package.extras] @@ -2634,105 +2659,105 @@ all = ["numpy"] [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -2887,23 +2912,23 @@ typing-extensions = "*" [[package]] name = "setuptools" -version = "75.1.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"}, - {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" @@ -2992,31 +3017,32 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "tomli" -version = "2.0.2" +version = "2.1.0" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, + {file = "tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391"}, + {file = "tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8"}, ] [[package]] name = "tqdm" -version = "4.66.5" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd"}, - {file = "tqdm-4.66.5.tar.gz", hash = "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -3200,81 +3226,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [[package]] diff --git a/airbyte-integrations/connectors/source-gcs/pyproject.toml b/airbyte-integrations/connectors/source-gcs/pyproject.toml index 086120fbc32d..ec384fe927ca 100644 --- a/airbyte-integrations/connectors/source-gcs/pyproject.toml +++ b/airbyte-integrations/connectors/source-gcs/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.8.1" +version = "0.8.2" name = "source-gcs" description = "Source implementation for Gcs." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-gcs/source_gcs/config.py b/airbyte-integrations/connectors/source-gcs/source_gcs/config.py index 40c5ec5a5cf8..f2d3d37326f5 100644 --- a/airbyte-integrations/connectors/source-gcs/source_gcs/config.py +++ b/airbyte-integrations/connectors/source-gcs/source_gcs/config.py @@ -5,9 +5,10 @@ from typing import Literal, Union +from pydantic.v1 import AnyUrl, BaseModel, Field + from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec from airbyte_cdk.utils.oneof_option_config import OneOfOptionConfig -from pydantic.v1 import AnyUrl, BaseModel, Field class OAuthCredentials(BaseModel): diff --git a/airbyte-integrations/connectors/source-gcs/source_gcs/helpers.py b/airbyte-integrations/connectors/source-gcs/source_gcs/helpers.py index 7b497a6a9f35..4dfaddb5c4d5 100644 --- a/airbyte-integrations/connectors/source-gcs/source_gcs/helpers.py +++ b/airbyte-integrations/connectors/source-gcs/source_gcs/helpers.py @@ -5,10 +5,11 @@ import json -from airbyte_cdk.sources.file_based.remote_file import RemoteFile from google.cloud import storage from google.oauth2 import credentials, service_account +from airbyte_cdk.sources.file_based.remote_file import RemoteFile + def get_gcs_client(config): if config.credentials.auth_type == "Service": diff --git a/airbyte-integrations/connectors/source-gcs/source_gcs/run.py b/airbyte-integrations/connectors/source-gcs/source_gcs/run.py index 65038c7fa7ef..c0a00bf91939 100644 --- a/airbyte-integrations/connectors/source-gcs/source_gcs/run.py +++ b/airbyte-integrations/connectors/source-gcs/source_gcs/run.py @@ -7,9 +7,10 @@ import time import traceback +from orjson import orjson + from airbyte_cdk import AirbyteEntrypoint, launch from airbyte_cdk.models import AirbyteErrorTraceMessage, AirbyteMessage, AirbyteMessageSerializer, AirbyteTraceMessage, TraceType, Type -from orjson import orjson from source_gcs import Config, Cursor, SourceGCS, SourceGCSStreamReader from source_gcs.config_migrations import MigrateServiceAccount diff --git a/airbyte-integrations/connectors/source-gcs/source_gcs/spec.py b/airbyte-integrations/connectors/source-gcs/source_gcs/spec.py index abc91843a449..b81e60e95a32 100644 --- a/airbyte-integrations/connectors/source-gcs/source_gcs/spec.py +++ b/airbyte-integrations/connectors/source-gcs/source_gcs/spec.py @@ -3,9 +3,10 @@ # from typing import Literal, Union -from airbyte_cdk.utils.oneof_option_config import OneOfOptionConfig from pydantic.v1 import BaseModel, Field +from airbyte_cdk.utils.oneof_option_config import OneOfOptionConfig + class OAuthCredentials(BaseModel): class Config(OneOfOptionConfig): diff --git a/airbyte-integrations/connectors/source-gcs/source_gcs/stream_reader.py b/airbyte-integrations/connectors/source-gcs/source_gcs/stream_reader.py index fdd339c43424..53597e931640 100644 --- a/airbyte-integrations/connectors/source-gcs/source_gcs/stream_reader.py +++ b/airbyte-integrations/connectors/source-gcs/source_gcs/stream_reader.py @@ -11,14 +11,16 @@ import pytz import smart_open -from airbyte_cdk.sources.file_based.exceptions import ErrorListingFiles, FileBasedSourceError -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode from google.cloud import storage from google.oauth2 import credentials, service_account + +from airbyte_cdk.sources.file_based.exceptions import ErrorListingFiles, FileBasedSourceError +from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode from source_gcs.config import Config from source_gcs.helpers import GCSRemoteFile from source_gcs.zip_helper import ZipHelper + # google can raise warnings for end user credentials, wrapping it to Logger logging.captureWarnings(True) @@ -96,7 +98,6 @@ def get_matching_files(self, globs: List[str], prefix: Optional[str], logger: lo last_modified = blob.updated.astimezone(pytz.utc).replace(tzinfo=None) if not start_date or last_modified >= start_date: - if self.config.credentials.auth_type == "Client": uri = f"gs://{blob.bucket.name}/{blob.name}" else: diff --git a/airbyte-integrations/connectors/source-gcs/source_gcs/zip_helper.py b/airbyte-integrations/connectors/source-gcs/source_gcs/zip_helper.py index 43b7c2deeecf..609fc2e013dc 100644 --- a/airbyte-integrations/connectors/source-gcs/source_gcs/zip_helper.py +++ b/airbyte-integrations/connectors/source-gcs/source_gcs/zip_helper.py @@ -7,8 +7,10 @@ from typing import Iterable from google.cloud.storage.blob import Blob + from source_gcs.helpers import GCSRemoteFile + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-gcs/unit_tests/conftest.py b/airbyte-integrations/connectors/source-gcs/unit_tests/conftest.py index 105a55e1ee08..5b72f1604164 100644 --- a/airbyte-integrations/connectors/source-gcs/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-gcs/unit_tests/conftest.py @@ -6,10 +6,11 @@ from unittest.mock import Mock import pytest -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig from source_gcs import Cursor, SourceGCSStreamReader from source_gcs.helpers import GCSRemoteFile +from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig + @pytest.fixture def logger(): @@ -63,9 +64,10 @@ def zip_file(): uri=str(Path(__file__).parent / "resource/files/test.csv.zip"), last_modified=datetime.today(), mime_type=".zip", - displayed_uri="resource/files/test.csv.zip" + displayed_uri="resource/files/test.csv.zip", ) + @pytest.fixture def mocked_blob(): blob = Mock() diff --git a/airbyte-integrations/connectors/source-gcs/unit_tests/test_config.py b/airbyte-integrations/connectors/source-gcs/unit_tests/test_config.py index ea301e8d9e12..eab24e5e8d14 100644 --- a/airbyte-integrations/connectors/source-gcs/unit_tests/test_config.py +++ b/airbyte-integrations/connectors/source-gcs/unit_tests/test_config.py @@ -7,4 +7,3 @@ def test_documentation_url(): assert "https" in Config.documentation_url() - diff --git a/airbyte-integrations/connectors/source-gcs/unit_tests/test_config_migrations.py b/airbyte-integrations/connectors/source-gcs/unit_tests/test_config_migrations.py index 142a7f8939c8..8812a03243ee 100644 --- a/airbyte-integrations/connectors/source-gcs/unit_tests/test_config_migrations.py +++ b/airbyte-integrations/connectors/source-gcs/unit_tests/test_config_migrations.py @@ -6,33 +6,42 @@ from unittest.mock import MagicMock import pytest -from airbyte_cdk import AirbyteEntrypoint from source_gcs import SourceGCS from source_gcs.config_migrations import MigrateServiceAccount +from airbyte_cdk import AirbyteEntrypoint + def load_config(path: str) -> Mapping[str, Any]: with open(path, "r") as f: return json.load(f) + def revert_config(path: str) -> None: migrated_config = load_config(path) del migrated_config["credentials"] with open(path, "w") as f: f.write(json.dumps(migrated_config)) + @pytest.mark.parametrize( "config_file_path, run_revert", [ # Migration is required (str(pathlib.Path(__file__).parent / "resource/config_migrations/service_account_config.json"), True), # New config format - (str(pathlib.Path(__file__).parent / "resource/config_migrations/service_account_with_credentials_config.json"), False) - ] + (str(pathlib.Path(__file__).parent / "resource/config_migrations/service_account_with_credentials_config.json"), False), + ], ) def test_migrate_config(config_file_path, run_revert): args = ["check", "--config", config_file_path] - source = SourceGCS(MagicMock(), MagicMock, None, AirbyteEntrypoint.extract_config(args), None,) + source = SourceGCS( + MagicMock(), + MagicMock, + None, + AirbyteEntrypoint.extract_config(args), + None, + ) MigrateServiceAccount().migrate(args, source) migrated_config = load_config(config_file_path) @@ -43,4 +52,3 @@ def test_migrate_config(config_file_path, run_revert): if run_revert: revert_config(config_file_path) - diff --git a/airbyte-integrations/connectors/source-gcs/unit_tests/test_cursor.py b/airbyte-integrations/connectors/source-gcs/unit_tests/test_cursor.py index 59095eead97d..309f5167a14a 100644 --- a/airbyte-integrations/connectors/source-gcs/unit_tests/test_cursor.py +++ b/airbyte-integrations/connectors/source-gcs/unit_tests/test_cursor.py @@ -1,9 +1,10 @@ # Copyright (c) 2024 Airbyte, Inc., all rights reserved. from datetime import datetime +from source_gcs import Cursor + from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig from airbyte_cdk.sources.file_based.stream.cursor import DefaultFileBasedCursor -from source_gcs import Cursor def test_add_file_successfully(cursor, remote_file, logger): @@ -125,9 +126,6 @@ def test_add_file_zip_files(mocked_reader, zip_file, logger): cursor = Cursor(stream_config=FileBasedStreamConfig(name="test", globs=["**/*.zip"], format={"filetype": "csv"})) cursor.add_file(zip_file) - saved_history_cursor = datetime.strptime( - cursor._file_to_datetime_history[zip_file.displayed_uri], - cursor.DATE_TIME_FORMAT - ) + saved_history_cursor = datetime.strptime(cursor._file_to_datetime_history[zip_file.displayed_uri], cursor.DATE_TIME_FORMAT) assert saved_history_cursor == zip_file.last_modified diff --git a/airbyte-integrations/connectors/source-gcs/unit_tests/test_run.py b/airbyte-integrations/connectors/source-gcs/unit_tests/test_run.py index 87b46cc061aa..a74903a226b3 100644 --- a/airbyte-integrations/connectors/source-gcs/unit_tests/test_run.py +++ b/airbyte-integrations/connectors/source-gcs/unit_tests/test_run.py @@ -3,10 +3,11 @@ from unittest.mock import patch import pytest -from airbyte_cdk.utils.traced_exception import AirbyteTracedException from common import catalog_path, config_path from source_gcs.run import run +from airbyte_cdk.utils.traced_exception import AirbyteTracedException + def test_run_with_non_existing_config(): with patch("sys.argv", ["", "check", "--config", "non_existing.json"]): diff --git a/airbyte-integrations/connectors/source-gcs/unit_tests/test_source.py b/airbyte-integrations/connectors/source-gcs/unit_tests/test_source.py index 03062a560865..76c55728c0af 100644 --- a/airbyte-integrations/connectors/source-gcs/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-gcs/unit_tests/test_source.py @@ -4,11 +4,12 @@ from unittest.mock import Mock import pytest -from airbyte_cdk import AirbyteTracedException -from airbyte_cdk.sources.file_based.availability_strategy import DefaultFileBasedAvailabilityStrategy from common import catalog_path, config_path from source_gcs import Config, Cursor, SourceGCS, SourceGCSStreamReader +from airbyte_cdk import AirbyteTracedException +from airbyte_cdk.sources.file_based.availability_strategy import DefaultFileBasedAvailabilityStrategy + def _source_gcs(catalog, config): return SourceGCS( diff --git a/airbyte-integrations/connectors/source-gcs/unit_tests/test_stream.py b/airbyte-integrations/connectors/source-gcs/unit_tests/test_stream.py index 163aaab29bf1..9ef22105964b 100644 --- a/airbyte-integrations/connectors/source-gcs/unit_tests/test_stream.py +++ b/airbyte-integrations/connectors/source-gcs/unit_tests/test_stream.py @@ -9,8 +9,15 @@ def test_transform_record(zip_file, mocked_reader, logger): stream = GCSStream( - config=Mock(), catalog_schema=Mock(), stream_reader=Mock(), availability_strategy=Mock(), discovery_policy=Mock(),parsers=Mock(), - validation_policy=Mock(), errors_collector=Mock(), cursor=Mock() + config=Mock(), + catalog_schema=Mock(), + stream_reader=Mock(), + availability_strategy=Mock(), + discovery_policy=Mock(), + parsers=Mock(), + validation_policy=Mock(), + errors_collector=Mock(), + cursor=Mock(), ) last_updated = zip_file.last_modified.isoformat() transformed_record = stream.transform_record({"field1": 1}, zip_file, last_updated) @@ -19,11 +26,7 @@ def test_transform_record(zip_file, mocked_reader, logger): assert transformed_record["_ab_source_file_url"] != zip_file.uri last_updated = datetime.today().isoformat() - csv_file = GCSRemoteFile( - uri="https://storage.googleapis.com/test/test", - last_modified=last_updated, - mime_type = "csv" - ) + csv_file = GCSRemoteFile(uri="https://storage.googleapis.com/test/test", last_modified=last_updated, mime_type="csv") transformed_record = stream.transform_record({"field1": 1}, csv_file, last_updated) assert transformed_record["_ab_source_file_url"] == csv_file.uri diff --git a/airbyte-integrations/connectors/source-gcs/unit_tests/test_stream_reader.py b/airbyte-integrations/connectors/source-gcs/unit_tests/test_stream_reader.py index b5d5b501872e..b9508c8f5dde 100644 --- a/airbyte-integrations/connectors/source-gcs/unit_tests/test_stream_reader.py +++ b/airbyte-integrations/connectors/source-gcs/unit_tests/test_stream_reader.py @@ -4,19 +4,17 @@ from unittest.mock import Mock import pytest +from source_gcs import Config, SourceGCSStreamReader +from source_gcs.config import ServiceAccountCredentials + from airbyte_cdk.sources.file_based.exceptions import ErrorListingFiles from airbyte_cdk.sources.file_based.file_based_stream_reader import FileReadMode from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from source_gcs import Config, SourceGCSStreamReader -from source_gcs.config import ServiceAccountCredentials def test_get_matching_files_with_no_prefix(logger, mocked_reader): mocked_reader._config = Config( - credentials=ServiceAccountCredentials( - service_account='{"type": "service_account"}', - auth_type="Service" - ), + credentials=ServiceAccountCredentials(service_account='{"type": "service_account"}', auth_type="Service"), bucket="test_bucket", streams=[], ) diff --git a/airbyte-integrations/connectors/source-gcs/unit_tests/test_zip_helper.py b/airbyte-integrations/connectors/source-gcs/unit_tests/test_zip_helper.py index d4ea6e2fb08f..f2595830b6db 100644 --- a/airbyte-integrations/connectors/source-gcs/unit_tests/test_zip_helper.py +++ b/airbyte-integrations/connectors/source-gcs/unit_tests/test_zip_helper.py @@ -6,7 +6,6 @@ def test_get_gcs_remote_files(mocked_blob, zip_file, caplog): - files = list(ZipHelper(mocked_blob, zip_file,tempfile.TemporaryDirectory()).get_gcs_remote_files()) + files = list(ZipHelper(mocked_blob, zip_file, tempfile.TemporaryDirectory()).get_gcs_remote_files()) assert len(files) == 1 assert "Picking up file test.csv from zip archive" in caplog.text - diff --git a/airbyte-integrations/connectors/source-genesys/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-genesys/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-genesys/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-genesys/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-genesys/main.py b/airbyte-integrations/connectors/source-genesys/main.py index d34643d2aa21..fbd608c13d5a 100644 --- a/airbyte-integrations/connectors/source-genesys/main.py +++ b/airbyte-integrations/connectors/source-genesys/main.py @@ -4,5 +4,6 @@ from source_genesys.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-genesys/metadata.yaml b/airbyte-integrations/connectors/source-genesys/metadata.yaml index 8e7565a34a11..588eb49a45d2 100644 --- a/airbyte-integrations/connectors/source-genesys/metadata.yaml +++ b/airbyte-integrations/connectors/source-genesys/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 5ea4459a-8f1a-452a-830f-a65c38cc438d - dockerImageTag: 0.1.21 + dockerImageTag: 0.1.26 dockerRepository: airbyte/source-genesys githubIssueLabel: source-genesys icon: genesys.svg @@ -29,5 +29,5 @@ data: connectorTestSuitesOptions: - suite: unitTests connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-genesys/poetry.lock b/airbyte-integrations/connectors/source-genesys/poetry.lock index daa4d036e32d..1077e5f93884 100644 --- a/airbyte-integrations/connectors/source-genesys/poetry.lock +++ b/airbyte-integrations/connectors/source-genesys/poetry.lock @@ -62,19 +62,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -140,127 +140,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -276,20 +263,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -367,13 +354,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -486,13 +473,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -573,54 +560,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -884,33 +871,33 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -951,13 +938,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -982,81 +969,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-genesys/pyproject.toml b/airbyte-integrations/connectors/source-genesys/pyproject.toml index 4e6c7feb81e4..0b759b28daa0 100644 --- a/airbyte-integrations/connectors/source-genesys/pyproject.toml +++ b/airbyte-integrations/connectors/source-genesys/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.21" +version = "0.1.26" name = "source-genesys" description = "Source implementation for Genesys." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-genesys/source_genesys/authenicator.py b/airbyte-integrations/connectors/source-genesys/source_genesys/authenicator.py index 4a5adde124bc..67fae1b42130 100644 --- a/airbyte-integrations/connectors/source-genesys/source_genesys/authenicator.py +++ b/airbyte-integrations/connectors/source-genesys/source_genesys/authenicator.py @@ -8,6 +8,7 @@ from airbyte_cdk.sources.streams.http.requests_native_auth import Oauth2Authenticator + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-genesys/source_genesys/source.py b/airbyte-integrations/connectors/source-genesys/source_genesys/source.py index 30d0d1106c43..27f2a07b5273 100644 --- a/airbyte-integrations/connectors/source-genesys/source_genesys/source.py +++ b/airbyte-integrations/connectors/source-genesys/source_genesys/source.py @@ -7,6 +7,7 @@ from typing import Any, Dict, Iterable, List, Mapping, MutableMapping, Optional, Tuple import requests + from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http import HttpStream @@ -244,7 +245,6 @@ def path(self, **kwargs) -> str: class SourceGenesys(AbstractSource): def build_refresh_request_body(self) -> Mapping[str, Any]: - return { "grant_type": "client_credentials", "client_id": self.get_client_id(), @@ -259,7 +259,6 @@ def check_connection(self, logger, config) -> Tuple[bool, any]: return True, None def streams(self, config: Mapping[str, Any]) -> List[Stream]: - GENESYS_REGION_DOMAIN_MAP: Dict[str, str] = { "Americas (US East)": "mypurecloud.com", "Americas (US East 2)": "use2.us-gov-pure.cloud", diff --git a/airbyte-integrations/connectors/source-getgist/README.md b/airbyte-integrations/connectors/source-getgist/README.md new file mode 100644 index 000000000000..7afa4a427525 --- /dev/null +++ b/airbyte-integrations/connectors/source-getgist/README.md @@ -0,0 +1,33 @@ +# GetGist +This directory contains the manifest-only connector for `source-getgist`. + +An Airbyte connector for [Gist](https://getgist.com/) would enable data syncing between Gist and various data platforms or databases. This connector could pull data from key objects like contacts, tags, segments, campaigns, forms, and subscription types, facilitating integration with other tools in a data pipeline. By automating data extraction from Gist, users can analyze customer interactions and engagement more efficiently in their preferred analytics or storage environment. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-getgist:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-getgist build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-getgist test +``` + diff --git a/airbyte-integrations/connectors/source-getgist/acceptance-test-config.yml b/airbyte-integrations/connectors/source-getgist/acceptance-test-config.yml new file mode 100644 index 000000000000..111950e7ed35 --- /dev/null +++ b/airbyte-integrations/connectors/source-getgist/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-getgist:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-getgist/icon.svg b/airbyte-integrations/connectors/source-getgist/icon.svg new file mode 100644 index 000000000000..5d24483740cb --- /dev/null +++ b/airbyte-integrations/connectors/source-getgist/icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/airbyte-integrations/connectors/source-getgist/manifest.yaml b/airbyte-integrations/connectors/source-getgist/manifest.yaml new file mode 100644 index 000000000000..50230fda8309 --- /dev/null +++ b/airbyte-integrations/connectors/source-getgist/manifest.yaml @@ -0,0 +1,940 @@ +version: 6.1.0 + +type: DeclarativeSource + +check: + type: CheckStream + stream_names: + - contacts + +definitions: + streams: + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - contacts + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 60 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + collections: + type: DeclarativeStream + name: collections + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /collections + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - collections + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 60 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/collections" + articles: + type: DeclarativeStream + name: articles + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /articles + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - articles + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 60 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/articles" + events: + type: DeclarativeStream + name: events + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /events + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - events + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 60 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/events" + tags: + type: DeclarativeStream + name: tags + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /tags + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - tags + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 60 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tags" + segments: + type: DeclarativeStream + name: segments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /segments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - segments + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 60 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/segments" + forms: + type: DeclarativeStream + name: forms + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /forms + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - forms + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 60 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/forms" + campaigns: + type: DeclarativeStream + name: campaigns + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /campaigns + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - campaigns + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 60 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/campaigns" + subscription_types: + type: DeclarativeStream + name: subscription_types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /subscription_types + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - subscription_types + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 60 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/subscription_types" + teams: + type: DeclarativeStream + name: teams + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /teams + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - teams + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 60 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/teams" + teammates: + type: DeclarativeStream + name: teammates + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /teammates + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - teammates + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 60 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/teammates" + stores: + type: DeclarativeStream + name: stores + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /ecommerce/stores + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 60 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stores" + base_requester: + type: HttpRequester + url_base: https://api.getgist.com + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/collections" + - $ref: "#/definitions/streams/articles" + - $ref: "#/definitions/streams/events" + - $ref: "#/definitions/streams/tags" + - $ref: "#/definitions/streams/segments" + - $ref: "#/definitions/streams/forms" + - $ref: "#/definitions/streams/campaigns" + - $ref: "#/definitions/streams/subscription_types" + - $ref: "#/definitions/streams/teams" + - $ref: "#/definitions/streams/teammates" + - $ref: "#/definitions/streams/stores" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + description: >- + API key to use. Find it in the Integration Settings on your Gist + dashboard at https://app.getgist.com/projects/_/settings/api-key. + name: api_key + order: 0 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + contacts: true + collections: true + articles: true + events: true + tags: true + segments: true + forms: true + campaigns: true + subscription_types: true + teams: true + teammates: true + stores: true + testedStreams: + contacts: + streamHash: 2e70986deb1d74411b14ad4f0262860580920f03 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + collections: + streamHash: f598396d91ba4e9d0307d37f8e111668138e2637 + hasResponse: true + responsesAreSuccessful: true + hasRecords: false + primaryKeysArePresent: true + primaryKeysAreUnique: true + articles: + streamHash: 780a15f4e999b4b5bd16c5aa00b146c6f796957b + hasResponse: true + responsesAreSuccessful: true + hasRecords: false + primaryKeysArePresent: true + primaryKeysAreUnique: true + events: + streamHash: 1a7306b582f339a9e8c5a33efc99205f79de6fdd + hasResponse: true + responsesAreSuccessful: true + hasRecords: false + primaryKeysArePresent: true + primaryKeysAreUnique: true + tags: + streamHash: 1ef2f44078ba32b4002ab25203fb9caba870fc07 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + segments: + streamHash: 42a15ed4cf923d26f9aa3ae8c5bd45e9a8135cce + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + forms: + streamHash: 94fa67c973a5fe1fb3029fe74b34da90ad870aa2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: false + primaryKeysArePresent: true + primaryKeysAreUnique: true + campaigns: + streamHash: 75bdc1a21039b61d9ee0a0104f4adf6129ba81ae + hasResponse: true + responsesAreSuccessful: true + hasRecords: false + primaryKeysArePresent: true + primaryKeysAreUnique: true + subscription_types: + hasRecords: true + streamHash: 18e3eef2fa47d8b7b2ac87513b20431cf0003230 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + teams: + streamHash: 039b19ff9ccdbb7f0a96c0050fac55d5f4ca51f9 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + teammates: + streamHash: f9c5921021ec6e5d733fd4263552ff8f6634f935 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + stores: + streamHash: be7d949426471ae275d98fc591f92092d0cb9eb0 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://developers.getgist.com/api + +schemas: + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + avatar: + type: + - string + - "null" + created_at: + type: + - number + - "null" + custom_properties: + type: + - object + - "null" + properties: {} + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + full_name: + type: + - string + - "null" + id: + type: number + last_seen_at: + type: + - number + - "null" + location_data: + type: + - object + - "null" + properties: {} + name: + type: + - string + - "null" + segments: + type: + - array + - "null" + signed_up_at: + type: + - number + - "null" + social_profiles: + type: + - array + - "null" + tags: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + unsubscribed_from_emails: + type: + - string + - "null" + updated_at: + type: + - number + - "null" + required: + - id + collections: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - number + - "null" + default_locale: + type: + - string + - "null" + id: + type: number + translations: + type: + - object + - "null" + properties: + en: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + icon: + type: + - string + - "null" + name: + type: + - string + - "null" + url: + type: + - string + - "null" + updated_at: + type: + - number + - "null" + required: + - id + articles: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} + events: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} + tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: number + name: + type: + - string + - "null" + required: + - id + segments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + updated_at: + type: + - number + - "null" + required: + - id + forms: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - number + - "null" + fields: + type: + - array + - "null" + form_type: + type: + - string + - "null" + id: + type: number + status: + type: + - string + - "null" + title: + type: + - string + - "null" + required: + - id + campaigns: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active_subscriber_count: + type: + - number + - "null" + created_at: + type: + - number + - "null" + email_click_rate: + type: + - string + - "null" + email_count: + type: + - number + - "null" + email_open_rate: + type: + - string + - "null" + href: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + status: + type: + - string + - "null" + unsubscribed_subscriber_count: + type: + - number + - "null" + updated_at: + type: + - number + - "null" + required: + - id + subscription_types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + contact_count: + type: + - number + - "null" + display_order: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + status: + type: + - string + - "null" + required: + - id + teams: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - number + - "null" + emoji: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + teammate_ids: + type: + - array + - "null" + items: + type: + - number + - "null" + required: + - id + teammates: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + agent_status: + type: + - string + - "null" + avatar: + type: + - string + - "null" + away_mode_enabled: + type: + - boolean + - "null" + email: + type: + - string + - "null" + has_inbox_seat: + type: + - boolean + - "null" + id: + type: number + last_active_on: + type: + - number + - "null" + name: + type: + - string + - "null" + team_ids: + type: + - array + - "null" + items: + type: + - number + - "null" + required: + - id + stores: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + ecommerce_stores: + type: + - array + - "null" diff --git a/airbyte-integrations/connectors/source-getgist/metadata.yaml b/airbyte-integrations/connectors/source-getgist/metadata.yaml new file mode 100644 index 000000000000..7fd22dae963a --- /dev/null +++ b/airbyte-integrations/connectors/source-getgist/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.getgist.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-getgist + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: bc670226-bee1-470c-a013-df05e5ac8f1a + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-getgist + githubIssueLabel: source-getgist + icon: icon.svg + license: MIT + name: GetGist + releaseDate: 2024-10-31 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/getgist + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-getlago/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-getlago/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-getlago/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-getlago/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-getlago/metadata.yaml b/airbyte-integrations/connectors/source-getlago/metadata.yaml index dd809fc267ad..f51560f393c3 100644 --- a/airbyte-integrations/connectors/source-getlago/metadata.yaml +++ b/airbyte-integrations/connectors/source-getlago/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: e1a3866b-d3b2-43b6-b6d7-8c1ee4d7f53f - dockerImageTag: 0.7.2 + dockerImageTag: 0.7.6 dockerRepository: airbyte/source-getlago githubIssueLabel: source-getlago icon: getlago.svg @@ -39,5 +39,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-gitbook/README.md b/airbyte-integrations/connectors/source-gitbook/README.md new file mode 100644 index 000000000000..6cdc69a23669 --- /dev/null +++ b/airbyte-integrations/connectors/source-gitbook/README.md @@ -0,0 +1,33 @@ +# GitBook +This directory contains the manifest-only connector for `source-gitbook`. + +GitBook connector enables seamless data integration from GitBook into your data pipelines. It efficiently extracts content, such as documentation and pages, allowing teams to sync and analyze information across platforms. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-gitbook:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-gitbook build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-gitbook test +``` + diff --git a/airbyte-integrations/connectors/source-gitbook/acceptance-test-config.yml b/airbyte-integrations/connectors/source-gitbook/acceptance-test-config.yml new file mode 100644 index 000000000000..71b64f5e6c2f --- /dev/null +++ b/airbyte-integrations/connectors/source-gitbook/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-gitbook:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-gitbook/icon.svg b/airbyte-integrations/connectors/source-gitbook/icon.svg new file mode 100644 index 000000000000..c409530a4f28 --- /dev/null +++ b/airbyte-integrations/connectors/source-gitbook/icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/airbyte-integrations/connectors/source-gitbook/manifest.yaml b/airbyte-integrations/connectors/source-gitbook/manifest.yaml new file mode 100644 index 000000000000..9c38c16c05d5 --- /dev/null +++ b/airbyte-integrations/connectors/source-gitbook/manifest.yaml @@ -0,0 +1,630 @@ +version: 5.14.0 + +type: DeclarativeSource + +description: >- + GitBook connector enables seamless data integration from GitBook into your + data pipelines. It efficiently extracts content, such as documentation and + pages, allowing teams to sync and analyze information across platforms. + +check: + type: CheckStream + stream_names: + - users + +definitions: + streams: + users: + type: DeclarativeStream + name: users + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v1/user + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('next', {}).get('page') }}" + stop_condition: "{{ response.get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + organizations: + type: DeclarativeStream + name: organizations + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v1/orgs + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('next', {}).get('page') }}" + stop_condition: "{{ response.get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/organizations" + insights_traffic: + type: DeclarativeStream + name: insights_traffic + primary_key: + - timestamp + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v1/spaces/{{ config["space_id"] }}/insights/traffic + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - views + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('next', {}).get('page') }}" + stop_condition: "{{ response.get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/insights_traffic" + content: + type: DeclarativeStream + name: content + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v1/spaces/{{ config["space_id"] }}/content + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - pages + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('next', {}).get('page') }}" + stop_condition: "{{ response.get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/content" + org_members: + type: DeclarativeStream + name: org_members + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v1/orgs/{{ stream_partition.organization }}/members + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('next', {}).get('page') }}" + stop_condition: "{{ response.get('next') is none }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: organization + stream: + $ref: "#/definitions/streams/organizations" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/org_members" + base_requester: + type: HttpRequester + url_base: https://api.gitbook.com + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"access_token\"] }}" + +streams: + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/organizations" + - $ref: "#/definitions/streams/insights_traffic" + - $ref: "#/definitions/streams/content" + - $ref: "#/definitions/streams/org_members" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - access_token + - space_id + properties: + access_token: + type: string + description: >- + Personal access token for authenticating with the GitBook API. You can + view and manage your access tokens in the Developer settings of your + GitBook user account. + name: access_token + order: 0 + title: Access Token + airbyte_secret: true + space_id: + type: string + order: 1 + title: Space Id + additionalProperties: true + +metadata: + autoImportSchema: + users: true + organizations: true + insights_traffic: true + content: true + org_members: true + testedStreams: + users: + streamHash: 94aeda59e989c4a397bbb153b8e5326f16214f57 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + organizations: + streamHash: 9ab2877e203852d0f3f72d1b43efdebe30b191e8 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + insights_traffic: + streamHash: f592e43057580e07f97dd3533c7570c7ba8ef156 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + content: + hasRecords: true + streamHash: 57e08861335cfd51ba3a9253c80fd292611ca7ce + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + org_members: + hasRecords: true + streamHash: 2ca42bd9987373ad019bf5cb16bdab15213b33e2 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://developer.gitbook.com/gitbook-api/overview + +schemas: + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + displayName: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - string + - "null" + object: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + urls: + type: + - object + - "null" + properties: + location: + type: + - string + - "null" + organizations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + defaultRole: + type: + - string + - "null" + emailDomains: + type: + - array + - "null" + id: + type: string + inviteLinks: + type: + - boolean + - "null" + object: + type: + - string + - "null" + plan: + type: + - string + - "null" + title: + type: + - string + - "null" + urls: + type: + - object + - "null" + properties: + app: + type: + - string + - "null" + location: + type: + - string + - "null" + useCase: + type: + - string + - "null" + required: + - id + insights_traffic: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + count: + type: + - number + - "null" + timestamp: + type: string + required: + - timestamp + content: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + cover: + type: + - object + - "null" + properties: + ref: + type: + - object + - "null" + properties: + kind: + type: + - string + - "null" + url: + type: + - string + - "null" + yPos: + type: + - number + - "null" + documentId: + type: + - string + - "null" + icon: + type: + - string + - "null" + id: + type: string + kind: + type: + - string + - "null" + layout: + type: + - object + - "null" + properties: + description: + type: + - boolean + - "null" + cover: + type: + - boolean + - "null" + coverSize: + type: + - string + - "null" + outline: + type: + - boolean + - "null" + pagination: + type: + - boolean + - "null" + tableOfContents: + type: + - boolean + - "null" + title: + type: + - boolean + - "null" + pages: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + documentId: + type: + - string + - "null" + icon: + type: + - string + - "null" + id: + type: + - string + - "null" + kind: + type: + - string + - "null" + layout: + type: + - object + - "null" + properties: + description: + type: + - boolean + - "null" + cover: + type: + - boolean + - "null" + coverSize: + type: + - string + - "null" + outline: + type: + - boolean + - "null" + pagination: + type: + - boolean + - "null" + tableOfContents: + type: + - boolean + - "null" + title: + type: + - boolean + - "null" + pages: + type: + - array + - "null" + path: + type: + - string + - "null" + slug: + type: + - string + - "null" + title: + type: + - string + - "null" + urls: + type: + - object + - "null" + properties: + app: + type: + - string + - "null" + path: + type: + - string + - "null" + slug: + type: + - string + - "null" + title: + type: + - string + - "null" + urls: + type: + - object + - "null" + properties: + app: + type: + - string + - "null" + required: + - id + org_members: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + disabled: + type: + - boolean + - "null" + id: + type: string + joinedAt: + type: + - string + - "null" + lastSeenAt: + type: + - string + - "null" + object: + type: + - string + - "null" + role: + type: + - string + - "null" + spaces: + type: + - number + - "null" + sso: + type: + - boolean + - "null" + teams: + type: + - number + - "null" + user: + type: + - object + - "null" + properties: + displayName: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - string + - "null" + object: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + urls: + type: + - object + - "null" + properties: + location: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-gitbook/metadata.yaml b/airbyte-integrations/connectors/source-gitbook/metadata.yaml new file mode 100644 index 000000000000..3a8125b52ee6 --- /dev/null +++ b/airbyte-integrations/connectors/source-gitbook/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.gitbook.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-gitbook + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: d1fcdf3a-dcfd-4b2e-a32c-d8a7a2e9790c + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-gitbook + githubIssueLabel: source-gitbook + icon: icon.svg + license: MIT + name: GitBook + releaseDate: 2024-10-30 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/gitbook + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-github/fixtures/github.py b/airbyte-integrations/connectors/source-github/fixtures/github.py index 920b0677f952..ce0eea2a046c 100644 --- a/airbyte-integrations/connectors/source-github/fixtures/github.py +++ b/airbyte-integrations/connectors/source-github/fixtures/github.py @@ -9,6 +9,7 @@ import requests + logging.basicConfig(level=logging.INFO) diff --git a/airbyte-integrations/connectors/source-github/fixtures/main.py b/airbyte-integrations/connectors/source-github/fixtures/main.py index 00468b290d42..47776cb04626 100644 --- a/airbyte-integrations/connectors/source-github/fixtures/main.py +++ b/airbyte-integrations/connectors/source-github/fixtures/main.py @@ -8,6 +8,7 @@ from github import GitHubFiller + if __name__ == "__main__": api_token = sys.argv[1] repository = sys.argv[2] diff --git a/airbyte-integrations/connectors/source-github/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-github/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-github/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-github/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-github/main.py b/airbyte-integrations/connectors/source-github/main.py index 4d37ce6cccf5..bbe2a227e2f8 100644 --- a/airbyte-integrations/connectors/source-github/main.py +++ b/airbyte-integrations/connectors/source-github/main.py @@ -4,5 +4,6 @@ from source_github.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-github/metadata.yaml b/airbyte-integrations/connectors/source-github/metadata.yaml index 152d2130e645..7736899fb250 100644 --- a/airbyte-integrations/connectors/source-github/metadata.yaml +++ b/airbyte-integrations/connectors/source-github/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - ${api_url} connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: ef69ef6e-aa7f-4af1-a01d-ef775033524e - dockerImageTag: 1.8.15 + dockerImageTag: 1.8.20 dockerRepository: airbyte/source-github documentationUrl: https://docs.airbyte.com/integrations/sources/github erdUrl: https://dbdocs.io/airbyteio/source-github?view=relationships diff --git a/airbyte-integrations/connectors/source-github/poetry.lock b/airbyte-integrations/connectors/source-github/poetry.lock index 6f8cd9a9f3ca..577ce5c34581 100644 --- a/airbyte-integrations/connectors/source-github/poetry.lock +++ b/airbyte-integrations/connectors/source-github/poetry.lock @@ -69,24 +69,24 @@ files = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -101,19 +101,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -179,13 +179,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -269,127 +269,114 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -462,20 +449,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -550,13 +537,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -571,13 +558,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -585,7 +572,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -635,13 +621,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -742,22 +728,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -855,69 +844,86 @@ twitter = ["twython"] [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -1020,19 +1026,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1040,100 +1046,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -1141,13 +1158,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1353,105 +1370,105 @@ files = [ [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -1558,23 +1575,23 @@ tests = ["coverage (>=6.0.0)", "flake8", "mypy", "pytest (>=7.0.0)", "pytest-asy [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "sgqlc" @@ -1596,13 +1613,13 @@ websocket = ["websocket-client"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1644,33 +1661,34 @@ files = [ [[package]] name = "tqdm" -version = "4.66.6" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63"}, - {file = "tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] [[package]] name = "types-pyyaml" -version = "6.0.12.20240917" +version = "6.0.12.20241230" description = "Typing stubs for PyYAML" optional = false python-versions = ">=3.8" files = [ - {file = "types-PyYAML-6.0.12.20240917.tar.gz", hash = "sha256:d1405a86f9576682234ef83bcb4e6fff7c9305c8b1fbad5e0bcd4f7dbdc9c587"}, - {file = "types_PyYAML-6.0.12.20240917-py3-none-any.whl", hash = "sha256:392b267f1c0fe6022952462bf5d6523f31e37f6cea49b14cee7ad634b6301570"}, + {file = "types_PyYAML-6.0.12.20241230-py3-none-any.whl", hash = "sha256:fa4d32565219b68e6dee5f67534c722e53c00d1cfc09c435ef04d7353e1e96e6"}, + {file = "types_pyyaml-6.0.12.20241230.tar.gz", hash = "sha256:7f07622dbd34bb9c8b264fe860a17e0efcad00d50b5f27e93984909d9363498c"}, ] [[package]] @@ -1700,13 +1718,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1731,81 +1749,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-github/pyproject.toml b/airbyte-integrations/connectors/source-github/pyproject.toml index b6a51a0a86f0..97ad9b2e485c 100644 --- a/airbyte-integrations/connectors/source-github/pyproject.toml +++ b/airbyte-integrations/connectors/source-github/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "1.8.15" +version = "1.8.20" name = "source-github" description = "Source implementation for GitHub." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-github/source_github/backoff_strategies.py b/airbyte-integrations/connectors/source-github/source_github/backoff_strategies.py index ac887892499c..f407b315b21f 100644 --- a/airbyte-integrations/connectors/source-github/source_github/backoff_strategies.py +++ b/airbyte-integrations/connectors/source-github/source_github/backoff_strategies.py @@ -6,6 +6,7 @@ from typing import Any, Optional, Union import requests + from airbyte_cdk import BackoffStrategy from airbyte_cdk.sources.streams.http import HttpStream diff --git a/airbyte-integrations/connectors/source-github/source_github/config_migrations.py b/airbyte-integrations/connectors/source-github/source_github/config_migrations.py index 79ec73a9cd2f..f644b4c45266 100644 --- a/airbyte-integrations/connectors/source-github/source_github/config_migrations.py +++ b/airbyte-integrations/connectors/source-github/source_github/config_migrations.py @@ -12,6 +12,7 @@ from .source import SourceGithub + logger = logging.getLogger("airbyte_logger") @@ -30,13 +31,11 @@ class MigrateStringToArray(ABC): @property @abc.abstractmethod - def migrate_from_key(self) -> str: - ... + def migrate_from_key(self) -> str: ... @property @abc.abstractmethod - def migrate_to_key(self) -> str: - ... + def migrate_to_key(self) -> str: ... @classmethod def _should_migrate(cls, config: Mapping[str, Any]) -> bool: @@ -95,12 +94,10 @@ def migrate(cls, args: List[str], source: SourceGithub) -> None: class MigrateRepository(MigrateStringToArray): - migrate_from_key: str = "repository" migrate_to_key: str = "repositories" class MigrateBranch(MigrateStringToArray): - migrate_from_key: str = "branch" migrate_to_key: str = "branches" diff --git a/airbyte-integrations/connectors/source-github/source_github/errors_handlers.py b/airbyte-integrations/connectors/source-github/source_github/errors_handlers.py index 26abc891e897..ba36daec8ced 100644 --- a/airbyte-integrations/connectors/source-github/source_github/errors_handlers.py +++ b/airbyte-integrations/connectors/source-github/source_github/errors_handlers.py @@ -5,6 +5,7 @@ from typing import Optional, Union import requests + from airbyte_cdk.sources.streams.http import HttpStream from airbyte_cdk.sources.streams.http.error_handlers import ErrorHandler, ErrorResolution, HttpStatusErrorHandler, ResponseAction from airbyte_cdk.sources.streams.http.error_handlers.default_error_mapping import DEFAULT_ERROR_MAPPING @@ -12,6 +13,7 @@ from . import constants + GITHUB_DEFAULT_ERROR_MAPPING = DEFAULT_ERROR_MAPPING | { 401: ErrorResolution( response_action=ResponseAction.RETRY, diff --git a/airbyte-integrations/connectors/source-github/source_github/github_schema.py b/airbyte-integrations/connectors/source-github/source_github/github_schema.py index ace0d9c69e2d..bfa26d90dd37 100644 --- a/airbyte-integrations/connectors/source-github/source_github/github_schema.py +++ b/airbyte-integrations/connectors/source-github/source_github/github_schema.py @@ -6,6 +6,7 @@ import sgqlc.types.datetime import sgqlc.types.relay + github_schema = sgqlc.types.Schema() diff --git a/airbyte-integrations/connectors/source-github/source_github/graphql.py b/airbyte-integrations/connectors/source-github/source_github/graphql.py index 603e58f0182c..bdeb4655bcd8 100644 --- a/airbyte-integrations/connectors/source-github/source_github/graphql.py +++ b/airbyte-integrations/connectors/source-github/source_github/graphql.py @@ -11,6 +11,7 @@ from . import github_schema + _schema = github_schema _schema_root = _schema.github_schema @@ -165,7 +166,6 @@ def get_query_issue_reactions(owner, name, first, after, number=None): class QueryReactions: - # AVERAGE_REVIEWS - optimal number of reviews to fetch inside every pull request. # If we try to fetch too many (up to 100) we will spend too many scores of query cost. # https://docs.github.com/en/graphql/overview/resource-limitations#calculating-a-rate-limit-score-before-running-the-call diff --git a/airbyte-integrations/connectors/source-github/source_github/source.py b/airbyte-integrations/connectors/source-github/source_github/source.py index 5698b8795833..9e6246e67ff3 100644 --- a/airbyte-integrations/connectors/source-github/source_github/source.py +++ b/airbyte-integrations/connectors/source-github/source_github/source.py @@ -60,7 +60,6 @@ class SourceGithub(AbstractSource): - continue_sync_on_stream_failure = True @staticmethod diff --git a/airbyte-integrations/connectors/source-github/source_github/streams.py b/airbyte-integrations/connectors/source-github/source_github/streams.py index 7e9fcc80cc3e..cc8d8d8ee2b2 100644 --- a/airbyte-integrations/connectors/source-github/source_github/streams.py +++ b/airbyte-integrations/connectors/source-github/source_github/streams.py @@ -9,6 +9,7 @@ import pendulum import requests + from airbyte_cdk import BackoffStrategy, StreamSlice from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, Level, SyncMode from airbyte_cdk.models import Type as MessageType @@ -41,7 +42,6 @@ class GithubStreamABC(HttpStream, ABC): - primary_key = "id" # Detect streams with high API load @@ -80,7 +80,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def request_params( self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None ) -> MutableMapping[str, Any]: - params = {"per_page": self.page_size} if next_page_token: @@ -756,7 +755,6 @@ def path(self, stream_slice: Mapping[str, Any] = None, **kwargs) -> str: class GitHubGraphQLStream(GithubStream, ABC): - http_method = "POST" def path( @@ -976,7 +974,6 @@ def request_body_json( class ReactionStream(GithubStream, CheckpointMixin, ABC): - parent_key = "id" copy_parent_key = "comment_id" cursor_field = "created_at" @@ -1394,9 +1391,9 @@ def _get_updated_state(self, current_stream_state: MutableMapping[str, Any], lat stream_state_value = current_stream_state.get(repository, {}).get(project_id, {}).get(column_id, {}).get(self.cursor_field) if stream_state_value: updated_state = max(updated_state, stream_state_value) - current_stream_state.setdefault(repository, {}).setdefault(project_id, {}).setdefault(column_id, {})[ - self.cursor_field - ] = updated_state + current_stream_state.setdefault(repository, {}).setdefault(project_id, {}).setdefault(column_id, {})[self.cursor_field] = ( + updated_state + ) return current_stream_state def transform(self, record: MutableMapping[str, Any], stream_slice: Mapping[str, Any]) -> MutableMapping[str, Any]: @@ -1621,7 +1618,6 @@ def transform(self, record: MutableMapping[str, Any], stream_slice: Mapping[str, return record def get_error_handler(self) -> Optional[ErrorHandler]: - return ContributorActivityErrorHandler(logger=self.logger, max_retries=5, error_mapping=GITHUB_DEFAULT_ERROR_MAPPING) def get_backoff_strategy(self) -> Optional[Union[BackoffStrategy, List[BackoffStrategy]]]: diff --git a/airbyte-integrations/connectors/source-github/source_github/utils.py b/airbyte-integrations/connectors/source-github/source_github/utils.py index 3479e7c12b43..d9b7ea18d3bc 100644 --- a/airbyte-integrations/connectors/source-github/source_github/utils.py +++ b/airbyte-integrations/connectors/source-github/source_github/utils.py @@ -9,6 +9,7 @@ import pendulum import requests + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator @@ -99,7 +100,6 @@ def update_token(self) -> None: @property def token(self) -> str: - token = self.current_active_token return f"{self._auth_method} {token}" @@ -123,13 +123,15 @@ def _check_token_limits(self, token: str): ) token_info = self._tokens[token] remaining_info_core = rate_limit_info.get("core") - token_info.count_rest, token_info.reset_at_rest = remaining_info_core.get("remaining"), pendulum.from_timestamp( - remaining_info_core.get("reset") + token_info.count_rest, token_info.reset_at_rest = ( + remaining_info_core.get("remaining"), + pendulum.from_timestamp(remaining_info_core.get("reset")), ) remaining_info_graphql = rate_limit_info.get("graphql") - token_info.count_graphql, token_info.reset_at_graphql = remaining_info_graphql.get("remaining"), pendulum.from_timestamp( - remaining_info_graphql.get("reset") + token_info.count_graphql, token_info.reset_at_graphql = ( + remaining_info_graphql.get("remaining"), + pendulum.from_timestamp(remaining_info_graphql.get("reset")), ) def check_all_tokens(self): diff --git a/airbyte-integrations/connectors/source-github/unit_tests/conftest.py b/airbyte-integrations/connectors/source-github/unit_tests/conftest.py index f4e454dfab98..b2f4f27fe7a5 100644 --- a/airbyte-integrations/connectors/source-github/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-github/unit_tests/conftest.py @@ -5,6 +5,7 @@ import pytest import responses + os.environ["REQUEST_CACHE_PATH"] = "REQUEST_CACHE_PATH" diff --git a/airbyte-integrations/connectors/source-github/unit_tests/integration/test_assignees.py b/airbyte-integrations/connectors/source-github/unit_tests/integration/test_assignees.py index bde678baef18..89c9b35fcc88 100644 --- a/airbyte-integrations/connectors/source-github/unit_tests/integration/test_assignees.py +++ b/airbyte-integrations/connectors/source-github/unit_tests/integration/test_assignees.py @@ -3,16 +3,18 @@ import json from unittest import TestCase +from source_github import SourceGithub + from airbyte_cdk.models import SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import read from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse from airbyte_cdk.test.mock_http.response_builder import find_template from airbyte_cdk.test.state_builder import StateBuilder -from source_github import SourceGithub from .config import ConfigBuilder + _CONFIG = ConfigBuilder().with_repositories(["airbytehq/mock-test-0", "airbytehq/mock-test-1", "airbytehq/mock-test-2"]).build() @@ -162,12 +164,19 @@ def test_read_full_refresh_emits_per_partition_state(self): per_partition_state_1 = {"partition": {"repository": "airbytehq/mock-test-1"}, "cursor": {"__ab_full_refresh_sync_complete": True}} per_partition_state_2 = {"partition": {"repository": "airbytehq/mock-test-2"}, "cursor": {"__ab_full_refresh_sync_complete": True}} - incoming_state = StateBuilder().with_stream_state("assignees", { - "states": [ - {"partition": {"repository": "airbytehq/mock-test-0"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - {"partition": {"repository": "airbytehq/mock-test-1"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, - ] - }).build() + incoming_state = ( + StateBuilder() + .with_stream_state( + "assignees", + { + "states": [ + {"partition": {"repository": "airbytehq/mock-test-0"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, + {"partition": {"repository": "airbytehq/mock-test-1"}, "cursor": {"__ab_full_refresh_sync_complete": True}}, + ] + }, + ) + .build() + ) source = SourceGithub() actual_messages = read(source, config=_CONFIG, catalog=_create_catalog(), state=incoming_state) diff --git a/airbyte-integrations/connectors/source-github/unit_tests/integration/test_events.py b/airbyte-integrations/connectors/source-github/unit_tests/integration/test_events.py index 4140e6a1b63d..dfea868aed68 100644 --- a/airbyte-integrations/connectors/source-github/unit_tests/integration/test_events.py +++ b/airbyte-integrations/connectors/source-github/unit_tests/integration/test_events.py @@ -3,6 +3,8 @@ import json from unittest import TestCase, mock +from source_github import SourceGithub + from airbyte_cdk.models import SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import read @@ -10,10 +12,10 @@ from airbyte_cdk.test.mock_http.response_builder import find_template from airbyte_cdk.test.state_builder import StateBuilder from airbyte_protocol.models import AirbyteStreamStatus, Level, TraceType -from source_github import SourceGithub from .config import ConfigBuilder + _CONFIG = ConfigBuilder().with_repositories(["airbytehq/integration-test"]).build() diff --git a/airbyte-integrations/connectors/source-github/unit_tests/test_migrations/test_config_migrations.py b/airbyte-integrations/connectors/source-github/unit_tests/test_migrations/test_config_migrations.py index fdebc3af470b..06ad40cf2756 100644 --- a/airbyte-integrations/connectors/source-github/unit_tests/test_migrations/test_config_migrations.py +++ b/airbyte-integrations/connectors/source-github/unit_tests/test_migrations/test_config_migrations.py @@ -7,11 +7,13 @@ import os from typing import Any, Mapping -from airbyte_cdk.models import OrchestratorType, Type -from airbyte_cdk.sources import Source from source_github.config_migrations import MigrateBranch, MigrateRepository from source_github.source import SourceGithub +from airbyte_cdk.models import OrchestratorType, Type +from airbyte_cdk.sources import Source + + # BASE ARGS CMD = "check" TEST_CONFIG_PATH = f"{os.path.dirname(__file__)}/test_config.json" diff --git a/airbyte-integrations/connectors/source-github/unit_tests/test_multiple_token_authenticator.py b/airbyte-integrations/connectors/source-github/unit_tests/test_multiple_token_authenticator.py index ebe8eb56c4a4..829c6137eb95 100644 --- a/airbyte-integrations/connectors/source-github/unit_tests/test_multiple_token_authenticator.py +++ b/airbyte-integrations/connectors/source-github/unit_tests/test_multiple_token_authenticator.py @@ -8,13 +8,14 @@ import pendulum import pytest import responses -from airbyte_cdk.utils import AirbyteTracedException -from airbyte_protocol.models import FailureType from freezegun import freeze_time from source_github import SourceGithub from source_github.streams import Organizations from source_github.utils import MultipleTokenAuthenticatorWithRateLimiter, read_full_refresh +from airbyte_cdk.utils import AirbyteTracedException +from airbyte_protocol.models import FailureType + @responses.activate def test_multiple_tokens(rate_limit_mock_response): diff --git a/airbyte-integrations/connectors/source-github/unit_tests/test_source.py b/airbyte-integrations/connectors/source-github/unit_tests/test_source.py index 388e726e7dde..8e0d2455d0fc 100644 --- a/airbyte-integrations/connectors/source-github/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-github/unit_tests/test_source.py @@ -8,11 +8,12 @@ import pytest import responses -from airbyte_cdk.models import AirbyteConnectionStatus, Status -from airbyte_cdk.utils.traced_exception import AirbyteTracedException from source_github import constants from source_github.source import SourceGithub +from airbyte_cdk.models import AirbyteConnectionStatus, Status +from airbyte_cdk.utils.traced_exception import AirbyteTracedException + from .utils import command_check diff --git a/airbyte-integrations/connectors/source-github/unit_tests/test_stream.py b/airbyte-integrations/connectors/source-github/unit_tests/test_stream.py index d8944137c766..1ee7c865bbfb 100644 --- a/airbyte-integrations/connectors/source-github/unit_tests/test_stream.py +++ b/airbyte-integrations/connectors/source-github/unit_tests/test_stream.py @@ -10,10 +10,6 @@ import pytest import requests import responses -from airbyte_cdk.models import ConfiguredAirbyteCatalog, SyncMode -from airbyte_cdk.sources.streams.http.error_handlers import ErrorHandler, ErrorResolution, HttpStatusErrorHandler, ResponseAction -from airbyte_cdk.sources.streams.http.exceptions import BaseBackoffException, UserDefinedBackoffException -from airbyte_protocol.models import FailureType from requests import HTTPError from responses import matchers from source_github import SourceGithub, constants @@ -55,8 +51,14 @@ ) from source_github.utils import read_full_refresh +from airbyte_cdk.models import ConfiguredAirbyteCatalog, SyncMode +from airbyte_cdk.sources.streams.http.error_handlers import ErrorHandler, ErrorResolution, HttpStatusErrorHandler, ResponseAction +from airbyte_cdk.sources.streams.http.exceptions import BaseBackoffException, UserDefinedBackoffException +from airbyte_protocol.models import FailureType + from .utils import ProjectsResponsesAPI, read_incremental + DEFAULT_BACKOFF_DELAYS = [1, 2, 4, 8, 16] @@ -102,10 +104,34 @@ def test_backoff_time(time_mock, http_status, response_headers, expected_backoff @pytest.mark.parametrize( ("http_status", "response_headers", "text", "response_action", "error_message"), [ - (HTTPStatus.OK, {"X-RateLimit-Resource": "graphql"}, '{"errors": [{"type": "RATE_LIMITED"}]}', ResponseAction.RATE_LIMITED, f"Response status code: {HTTPStatus.OK}. Retrying..."), - (HTTPStatus.FORBIDDEN, {"X-RateLimit-Remaining": "0"}, "", ResponseAction.RATE_LIMITED, f"Response status code: {HTTPStatus.FORBIDDEN}. Retrying..."), - (HTTPStatus.FORBIDDEN, {"Retry-After": "0"}, "", ResponseAction.RATE_LIMITED, f"Response status code: {HTTPStatus.FORBIDDEN}. Retrying..."), - (HTTPStatus.FORBIDDEN, {"Retry-After": "60"}, "", ResponseAction.RATE_LIMITED, f"Response status code: {HTTPStatus.FORBIDDEN}. Retrying..."), + ( + HTTPStatus.OK, + {"X-RateLimit-Resource": "graphql"}, + '{"errors": [{"type": "RATE_LIMITED"}]}', + ResponseAction.RATE_LIMITED, + f"Response status code: {HTTPStatus.OK}. Retrying...", + ), + ( + HTTPStatus.FORBIDDEN, + {"X-RateLimit-Remaining": "0"}, + "", + ResponseAction.RATE_LIMITED, + f"Response status code: {HTTPStatus.FORBIDDEN}. Retrying...", + ), + ( + HTTPStatus.FORBIDDEN, + {"Retry-After": "0"}, + "", + ResponseAction.RATE_LIMITED, + f"Response status code: {HTTPStatus.FORBIDDEN}. Retrying...", + ), + ( + HTTPStatus.FORBIDDEN, + {"Retry-After": "60"}, + "", + ResponseAction.RATE_LIMITED, + f"Response status code: {HTTPStatus.FORBIDDEN}. Retrying...", + ), (HTTPStatus.INTERNAL_SERVER_ERROR, {}, "", ResponseAction.RETRY, "Internal server error."), (HTTPStatus.BAD_GATEWAY, {}, "", ResponseAction.RETRY, "Bad gateway."), (HTTPStatus.SERVICE_UNAVAILABLE, {}, "", ResponseAction.RETRY, "Service unavailable."), @@ -330,7 +356,6 @@ def test_stream_repositories_read(): @responses.activate @patch("time.sleep") def test_stream_projects_disabled(time_mock): - repository_args_with_start_date = {"start_date": "start_date", "page_size_for_large_streams": 30, "repositories": ["test_repo"]} stream = Projects(**repository_args_with_start_date) @@ -348,7 +373,6 @@ def test_stream_projects_disabled(time_mock): @responses.activate def test_stream_pull_requests_incremental_read(): - page_size = 2 repository_args_with_start_date = { "repositories": ["organization/repository"], @@ -412,7 +436,6 @@ def test_stream_pull_requests_incremental_read(): @responses.activate def test_stream_commits_incremental_read(): - repository_args_with_start_date = { "repositories": ["organization/repository"], "page_size_for_large_streams": 100, @@ -451,18 +474,18 @@ def test_stream_commits_incremental_read(): "name": "branch", "commit": { "sha": "74445338726f0f8e1c27c10dce90ca00c5ae2858", - "url": "https://api.github.com/repos/airbytehq/airbyte/commits/74445338726f0f8e1c27c10dce90ca00c5ae2858" + "url": "https://api.github.com/repos/airbytehq/airbyte/commits/74445338726f0f8e1c27c10dce90ca00c5ae2858", }, - "protected": False + "protected": False, }, { "name": "main", "commit": { "sha": "c27c10dce90ca00c5ae285874445338726f0f8e1", - "url": "https://api.github.com/repos/airbytehq/airbyte/commits/c27c10dce90ca00c5ae285874445338726f0f8e1" + "url": "https://api.github.com/repos/airbytehq/airbyte/commits/c27c10dce90ca00c5ae285874445338726f0f8e1", }, - "protected": False - } + "protected": False, + }, ], status=200, ) @@ -503,7 +526,6 @@ def test_stream_commits_incremental_read(): @responses.activate def test_stream_pull_request_commits(): - repository_args = { "repositories": ["organization/repository"], "page_size_for_large_streams": 100, @@ -545,7 +567,6 @@ def test_stream_pull_request_commits(): @responses.activate def test_stream_project_columns(): - repository_args_with_start_date = { "repositories": ["organization/repository"], "page_size_for_large_streams": 100, @@ -638,7 +659,6 @@ def test_stream_project_columns(): @responses.activate def test_stream_project_cards(): - repository_args_with_start_date = { "repositories": ["organization/repository"], "page_size_for_large_streams": 100, @@ -734,7 +754,6 @@ def test_stream_project_cards(): @responses.activate def test_stream_comments(): - repository_args_with_start_date = { "repositories": ["organization/repository", "airbytehq/airbyte"], "page_size_for_large_streams": 2, @@ -866,7 +885,6 @@ def test_stream_comments(): @responses.activate def test_streams_read_full_refresh(): - repository_args = { "repositories": ["organization/repository"], "page_size_for_large_streams": 100, @@ -927,7 +945,6 @@ def get_records(cursor_field): @responses.activate def test_stream_reviews_incremental_read(): - repository_args_with_start_date = { "start_date": "2000-01-01T00:00:00Z", "page_size_for_large_streams": 30, @@ -1002,7 +1019,6 @@ def test_stream_team_members_full_refresh(time_mock, caplog, rate_limit_mock_res @responses.activate def test_stream_commit_comment_reactions_incremental_read(): - repository_args = {"repositories": ["airbytehq/integration-test"], "page_size_for_large_streams": 100} stream = CommitCommentReactions(**repository_args) stream._parent_stream._http_client._session.cache.clear() @@ -1083,7 +1099,6 @@ def test_stream_commit_comment_reactions_incremental_read(): @responses.activate def test_stream_workflow_runs_read_incremental(monkeypatch): - repository_args_with_start_date = { "repositories": ["org/repos"], "page_size_for_large_streams": 30, @@ -1202,7 +1217,6 @@ def test_stream_workflow_runs_read_incremental(monkeypatch): @responses.activate def test_stream_workflow_jobs_read(): - repository_args = { "repositories": ["org/repo"], "page_size_for_large_streams": 100, @@ -1303,7 +1317,6 @@ def test_stream_workflow_jobs_read(): @responses.activate def test_stream_pull_request_comment_reactions_read(): - repository_args_with_start_date = { "start_date": "2022-01-01T00:00:00Z", "page_size_for_large_streams": 2, @@ -1361,11 +1374,7 @@ def test_stream_projects_v2_graphql_retry(time_mock, rate_limit_mock_response): } stream = ProjectsV2(**repository_args_with_start_date) resp = responses.add( - responses.POST, - "https://api.github.com/graphql", - json={"errors": "not found"}, - status=200, - headers={'Retry-After': '5'} + responses.POST, "https://api.github.com/graphql", json={"errors": "not found"}, status=200, headers={"Retry-After": "5"} ) backoff_strategy = GithubStreamABCBackoffStrategy(stream) diff --git a/airbyte-integrations/connectors/source-github/unit_tests/utils.py b/airbyte-integrations/connectors/source-github/unit_tests/utils.py index 81b32a929bcf..77472173550b 100644 --- a/airbyte-integrations/connectors/source-github/unit_tests/utils.py +++ b/airbyte-integrations/connectors/source-github/unit_tests/utils.py @@ -6,6 +6,7 @@ from unittest import mock import responses + from airbyte_cdk.models import SyncMode from airbyte_cdk.models.airbyte_protocol import ConnectorSpecification from airbyte_cdk.sources import Source diff --git a/airbyte-integrations/connectors/source-gitlab/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-gitlab/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-gitlab/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-gitlab/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-gitlab/main.py b/airbyte-integrations/connectors/source-gitlab/main.py index 1c322c2f2c48..8dcc7a60745f 100644 --- a/airbyte-integrations/connectors/source-gitlab/main.py +++ b/airbyte-integrations/connectors/source-gitlab/main.py @@ -4,5 +4,6 @@ from source_gitlab.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-gitlab/source_gitlab/config_migrations.py b/airbyte-integrations/connectors/source-gitlab/source_gitlab/config_migrations.py index ec47f547f591..1640cc68ad99 100644 --- a/airbyte-integrations/connectors/source-gitlab/source_gitlab/config_migrations.py +++ b/airbyte-integrations/connectors/source-gitlab/source_gitlab/config_migrations.py @@ -12,6 +12,7 @@ from .source import SourceGitlab + logger = logging.getLogger("airbyte_logger") @@ -30,13 +31,11 @@ class MigrateStringToArray(ABC): @property @abc.abstractmethod - def migrate_from_key(self) -> str: - ... + def migrate_from_key(self) -> str: ... @property @abc.abstractmethod - def migrate_to_key(self) -> str: - ... + def migrate_to_key(self) -> str: ... @classmethod def _should_migrate(cls, config: Mapping[str, Any]) -> bool: diff --git a/airbyte-integrations/connectors/source-gitlab/unit_tests/conftest.py b/airbyte-integrations/connectors/source-gitlab/unit_tests/conftest.py index c6f180e38de9..1b4a6d60636d 100644 --- a/airbyte-integrations/connectors/source-gitlab/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-gitlab/unit_tests/conftest.py @@ -6,9 +6,11 @@ from typing import Any, Mapping import pytest -from airbyte_cdk.sources.streams import Stream from source_gitlab.source import SourceGitlab +from airbyte_cdk.sources.streams import Stream + + BASE_CONFIG = { "start_date": "2021-01-01T00:00:00Z", "api_url": "gitlab.com", diff --git a/airbyte-integrations/connectors/source-gitlab/unit_tests/test_config_migrations.py b/airbyte-integrations/connectors/source-gitlab/unit_tests/test_config_migrations.py index b61fb232906d..4293f2ed4695 100644 --- a/airbyte-integrations/connectors/source-gitlab/unit_tests/test_config_migrations.py +++ b/airbyte-integrations/connectors/source-gitlab/unit_tests/test_config_migrations.py @@ -5,6 +5,7 @@ from source_gitlab.config_migrations import MigrateGroups from source_gitlab.source import SourceGitlab + TEST_CONFIG_PATH = f"{os.path.dirname(__file__)}/test_config.json" diff --git a/airbyte-integrations/connectors/source-gitlab/unit_tests/test_partition_routers.py b/airbyte-integrations/connectors/source-gitlab/unit_tests/test_partition_routers.py index 4e7e0b40483f..7222619f32cc 100644 --- a/airbyte-integrations/connectors/source-gitlab/unit_tests/test_partition_routers.py +++ b/airbyte-integrations/connectors/source-gitlab/unit_tests/test_partition_routers.py @@ -3,9 +3,10 @@ # +from conftest import BASE_CONFIG, GROUPS_LIST_URL, get_stream_by_name + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.declarative.types import StreamSlice -from conftest import BASE_CONFIG, GROUPS_LIST_URL, get_stream_by_name class TestGroupStreamsPartitionRouter: @@ -56,9 +57,7 @@ def test_projects_stream_slices_with_group_project_ids(self, requests_mock): url=f"https://gitlab.com/api/v4/groups/{group_id}?per_page=50", json=[{"id": group_id, "projects": [{"id": project_id, "path_with_namespace": project_id}]}], ) - expected_stream_slices.append( - StreamSlice(partition={"id": project_id.replace("/", "%2F")}, cursor_slice={}) - ) + expected_stream_slices.append(StreamSlice(partition={"id": project_id.replace("/", "%2F")}, cursor_slice={})) requests_mock.get(url=GROUPS_LIST_URL, json=groups_list_response) diff --git a/airbyte-integrations/connectors/source-gitlab/unit_tests/test_source.py b/airbyte-integrations/connectors/source-gitlab/unit_tests/test_source.py index b650c9e52b6d..06f55edf7d51 100644 --- a/airbyte-integrations/connectors/source-gitlab/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-gitlab/unit_tests/test_source.py @@ -6,9 +6,10 @@ import logging import pytest -from airbyte_cdk.sources.declarative.declarative_stream import DeclarativeStream from source_gitlab import SourceGitlab +from airbyte_cdk.sources.declarative.declarative_stream import DeclarativeStream + def test_streams(config): source = SourceGitlab() @@ -19,9 +20,7 @@ def test_streams(config): def test_connection_success(config, requests_mock): requests_mock.get(url="/api/v4/groups", json=[{"id": "g1"}]) - requests_mock.get( - url="/api/v4/groups/g1", json=[{"id": "g1", "projects": [{"id": "p1", "path_with_namespace": "p1"}]}] - ) + requests_mock.get(url="/api/v4/groups/g1", json=[{"id": "g1", "projects": [{"id": "p1", "path_with_namespace": "p1"}]}]) requests_mock.get(url="/api/v4/projects/p1", json={"id": "p1"}) source = SourceGitlab() status, msg = source.check_connection(logging.getLogger(), config) @@ -30,9 +29,7 @@ def test_connection_success(config, requests_mock): def test_connection_invalid_projects_and_projects(config_with_project_groups, requests_mock): requests_mock.register_uri("GET", "https://gitlab.com/api/v4/groups/g1?per_page=50", status_code=404) - requests_mock.register_uri( - "GET", "https://gitlab.com/api/v4/groups/g1/descendant_groups?per_page=50", status_code=404 - ) + requests_mock.register_uri("GET", "https://gitlab.com/api/v4/groups/g1/descendant_groups?per_page=50", status_code=404) requests_mock.register_uri("GET", "https://gitlab.com/api/v4/projects/p1?per_page=50&statistics=1", status_code=404) source = SourceGitlab() status, msg = source.check_connection(logging.getLogger(), config_with_project_groups) diff --git a/airbyte-integrations/connectors/source-gitlab/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-gitlab/unit_tests/test_streams.py index 9eef564ef235..820ca47f17b5 100644 --- a/airbyte-integrations/connectors/source-gitlab/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-gitlab/unit_tests/test_streams.py @@ -4,9 +4,11 @@ import pytest -from airbyte_cdk.models import SyncMode from conftest import BASE_CONFIG, GROUPS_LIST_URL, get_stream_by_name +from airbyte_cdk.models import SyncMode + + CONFIG = BASE_CONFIG | {"projects_list": ["p_1"]} @@ -123,7 +125,7 @@ def test_should_retry(requests_mock, stream_name, extra_mocks): "user_full_name": "John", "environment_name": "dev", "project_id": "p_1", - } + }, ), ( "merge_request_commits", @@ -157,11 +159,12 @@ def test_stream_slices_child_stream(requests_mock): url="https://gitlab.com/api/v4/projects/p_1?per_page=50&statistics=1", json=[{"id": 13082000, "description": "", "name": "New CI Test Project"}], ) - stream_state = {"13082000": {""'created_at': "2021-03-10T23:58:1213"}} + stream_state = {"13082000": {"" "created_at": "2021-03-10T23:58:1213"}} slices = list(commits.stream_slices(sync_mode=SyncMode.full_refresh, stream_state=stream_state)) assert slices + def test_request_params(): commits = get_stream_by_name("commits", CONFIG) assert commits.retriever.requester.get_request_params() == {"with_stats": "true"} diff --git a/airbyte-integrations/connectors/source-gitlab/unit_tests/test_utils.py b/airbyte-integrations/connectors/source-gitlab/unit_tests/test_utils.py index 5019d87b7b44..a347efae2f82 100644 --- a/airbyte-integrations/connectors/source-gitlab/unit_tests/test_utils.py +++ b/airbyte-integrations/connectors/source-gitlab/unit_tests/test_utils.py @@ -11,7 +11,7 @@ ("http://example", (True, "http", "example")), ("test://example.com", (False, "", "")), ("https://example.com/test/test2", (False, "", "")), - ) + ), ) def test_parse_url(url, expected): assert parse_url(url) == expected diff --git a/airbyte-integrations/connectors/source-glassfrog/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-glassfrog/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-glassfrog/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-glassfrog/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-glassfrog/metadata.yaml b/airbyte-integrations/connectors/source-glassfrog/metadata.yaml index ba8b487aa7f5..9cdc28adc975 100644 --- a/airbyte-integrations/connectors/source-glassfrog/metadata.yaml +++ b/airbyte-integrations/connectors/source-glassfrog/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - api.glassfrog.com connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: cf8ff320-6272-4faa-89e6-4402dc17e5d5 - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.6 dockerRepository: airbyte/source-glassfrog documentationUrl: https://docs.airbyte.com/integrations/sources/glassfrog githubIssueLabel: source-glassfrog diff --git a/airbyte-integrations/connectors/source-gmail/metadata.yaml b/airbyte-integrations/connectors/source-gmail/metadata.yaml index a4b4190128e1..88cda65a1754 100644 --- a/airbyte-integrations/connectors/source-gmail/metadata.yaml +++ b/airbyte-integrations/connectors/source-gmail/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-gmail connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: f7833dac-fc18-4feb-a2a9-94b22001edc6 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-gmail githubIssueLabel: source-gmail icon: icon.svg diff --git a/airbyte-integrations/connectors/source-gnews/components.py b/airbyte-integrations/connectors/source-gnews/components.py index df2f0a450bda..d93c3d963174 100644 --- a/airbyte-integrations/connectors/source-gnews/components.py +++ b/airbyte-integrations/connectors/source-gnews/components.py @@ -7,6 +7,7 @@ from typing import Any, Mapping, Optional, Union import requests + from airbyte_cdk.sources.declarative.requesters.error_handlers import BackoffStrategy from airbyte_cdk.sources.declarative.types import Config diff --git a/airbyte-integrations/connectors/source-gnews/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-gnews/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-gnews/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-gnews/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-gnews/metadata.yaml b/airbyte-integrations/connectors/source-gnews/metadata.yaml index ae662d0c10b7..54930b851593 100644 --- a/airbyte-integrations/connectors/source-gnews/metadata.yaml +++ b/airbyte-integrations/connectors/source-gnews/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: ce38aec4-5a77-439a-be29-9ca44fd4e811 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-gnews githubIssueLabel: source-gnews icon: gnews.svg @@ -40,5 +40,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-gocardless/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-gocardless/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-gocardless/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-gocardless/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-gocardless/metadata.yaml b/airbyte-integrations/connectors/source-gocardless/metadata.yaml index c57e56750300..dd665aded7d4 100644 --- a/airbyte-integrations/connectors/source-gocardless/metadata.yaml +++ b/airbyte-integrations/connectors/source-gocardless/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: ba15ac82-5c6a-4fb2-bf24-925c23a1180c - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-gocardless githubIssueLabel: source-gocardless icon: gocardless.svg @@ -27,5 +27,5 @@ data: ql: 100 supportLevel: community connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-goldcast/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-goldcast/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-goldcast/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-goldcast/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-goldcast/metadata.yaml b/airbyte-integrations/connectors/source-goldcast/metadata.yaml index eb36d5128a2a..5c2562f10a01 100644 --- a/airbyte-integrations/connectors/source-goldcast/metadata.yaml +++ b/airbyte-integrations/connectors/source-goldcast/metadata.yaml @@ -15,11 +15,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: c2c25d04-9bb1-4171-8a7a-bb7cead8add0 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-goldcast githubIssueLabel: source-goldcast icon: goldcast.svg diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/__init__.py b/airbyte-integrations/connectors/source-gong/__init__.py similarity index 100% rename from airbyte-cdk/python/airbyte_cdk/sources/declarative/async_job/__init__.py rename to airbyte-integrations/connectors/source-gong/__init__.py diff --git a/airbyte-integrations/connectors/source-gong/components.py b/airbyte-integrations/connectors/source-gong/components.py new file mode 100644 index 000000000000..5f4356d8aab2 --- /dev/null +++ b/airbyte-integrations/connectors/source-gong/components.py @@ -0,0 +1,27 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + +from typing import Any, Mapping, MutableMapping, Optional + +from airbyte_cdk.sources.declarative.incremental.datetime_based_cursor import DatetimeBasedCursor +from airbyte_cdk.sources.declarative.requesters.request_option import RequestOptionType +from airbyte_cdk.sources.declarative.types import StreamSlice, StreamState + + +class IncrementalSingleBodyFilterCursor(DatetimeBasedCursor): + def get_request_body_json( + self, + *, + stream_state: Optional[StreamState] = None, + stream_slice: Optional[StreamSlice] = None, + next_page_token: Optional[Mapping[str, Any]] = None, + ) -> Mapping[str, Any]: + return self._get_request_filter_options(RequestOptionType.body_json, stream_slice) + + def _get_request_filter_options(self, option_type: RequestOptionType, stream_slice: Optional[StreamSlice]) -> Mapping[str, Any]: + options: MutableMapping[str, Any] = {} + if not stream_slice: + return options + if self.start_time_option and self.start_time_option.inject_into == option_type: + field_name, sub_field_name = self.start_time_option.field_name.eval(config=self.config).replace(" ", "").split(",") + options[field_name] = {sub_field_name: stream_slice.get(self._partition_field_start.eval(self.config))} + return options diff --git a/airbyte-integrations/connectors/source-gong/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-gong/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-gong/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-gong/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-gong/integration_tests/configured_catalog.json b/airbyte-integrations/connectors/source-gong/integration_tests/configured_catalog.json index 3013e0b0d6f0..6905cf8a4812 100644 --- a/airbyte-integrations/connectors/source-gong/integration_tests/configured_catalog.json +++ b/airbyte-integrations/connectors/source-gong/integration_tests/configured_catalog.json @@ -13,10 +13,10 @@ "stream": { "name": "calls", "json_schema": {}, - "supported_sync_modes": ["full_refresh"] + "supported_sync_modes": ["full_refresh", "incremental"] }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" + "sync_mode": "incremental", + "destination_sync_mode": "append" }, { "stream": { @@ -40,10 +40,10 @@ "stream": { "name": "answeredScorecards", "json_schema": {}, - "supported_sync_modes": ["full_refresh"] + "supported_sync_modes": ["full_refresh", "incremental"] }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" + "sync_mode": "incremental", + "destination_sync_mode": "append" } ] } diff --git a/airbyte-integrations/connectors/source-gong/manifest.yaml b/airbyte-integrations/connectors/source-gong/manifest.yaml index 5c357b1f3dc7..a3db39fff265 100644 --- a/airbyte-integrations/connectors/source-gong/manifest.yaml +++ b/airbyte-integrations/connectors/source-gong/manifest.yaml @@ -58,8 +58,14 @@ definitions: $ref: "#/definitions/base_requester" path: /calls http_method: GET - request_parameters: - fromDateTime: "{{ config['start_date'] }}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + error_message_contains: found corresponding to the provided filters record_selector: type: RecordSelector extractor: @@ -76,6 +82,23 @@ definitions: type: CursorPagination cursor_value: "{{ response.records.cursor }}" stop_condition: "{{ 'records' not in response }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: started + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%dT%H:%M:%S%z" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config.start_date or (now_utc() - + duration('P90DT23H')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: fromDateTime schema_loader: type: InlineSchemaLoader schema: @@ -198,8 +221,6 @@ definitions: http_method: POST request_parameters: fromDateTime: "{{ config['start_date'] }}" - request_body_json: - filter: '{"callFromDate": "{{ config["start_date"] }}"}' record_selector: type: RecordSelector extractor: @@ -221,6 +242,25 @@ definitions: page_size: 100 cursor_value: "{{ response.records.cursor }}" stop_condition: "{{ 'records' not in response }}" + incremental_sync: + type: CustomIncrementalSync + class_name: >- + source_declarative_manifest.components.IncrementalSingleBodyFilterCursor + cursor_field: reviewTime + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%dT%H:%M:%S%z" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config.start_date or (now_utc() - + duration('P90DT23H')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: body_json + field_name: filter, reviewFromDate schema_loader: type: InlineSchemaLoader schema: @@ -230,8 +270,8 @@ definitions: url_base: https://api.gong.io/v2/ authenticator: type: BasicHttpAuthenticator - username: '{{ config["access_key"] }}' - password: '{{ config["access_key_secret"] }}' + username: "{{ config[\"access_key\"] }}" + password: "{{ config[\"access_key_secret\"] }}" streams: - $ref: "#/definitions/streams/users" @@ -282,37 +322,46 @@ metadata: extensiveCalls: false scorecards: false answeredScorecards: false + yamlComponents: + streams: + calls: + - errorHandler + - incrementalSync + extensiveCalls: + - incrementalSync + answeredScorecards: + - incrementalSync testedStreams: - scorecards: - streamHash: b4a5aa11ee2cb96554fa359ffec46d50641b0434 + users: + streamHash: c6b2bab08397024790447b2ea909e5e2056b3778 hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true - users: - streamHash: c6b2bab08397024790447b2ea909e5e2056b3778 + calls: + streamHash: 6f531846afce0222f244df5390aa7b3e1a534d1d hasResponse: true - responsesAreSuccessful: true - hasRecords: true + responsesAreSuccessful: false + hasRecords: false primaryKeysArePresent: true primaryKeysAreUnique: true - answeredScorecards: - streamHash: 42e030943265c512ecbca24e953416c157210edf + extensiveCalls: + streamHash: 99ac4098c8bba3989f73dff4c7b4b85963c90acd hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true - extensiveCalls: - streamHash: 99ac4098c8bba3989f73dff4c7b4b85963c90acd + scorecards: + streamHash: b4a5aa11ee2cb96554fa359ffec46d50641b0434 hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true - calls: - streamHash: 4152ed041830ae0728cd87629fcc46f5ab42a394 + answeredScorecards: + streamHash: 42e030943265c512ecbca24e953416c157210edf hasResponse: true responsesAreSuccessful: true hasRecords: true diff --git a/airbyte-integrations/connectors/source-gong/metadata.yaml b/airbyte-integrations/connectors/source-gong/metadata.yaml index a7e608af3d0d..71b18bd647df 100644 --- a/airbyte-integrations/connectors/source-gong/metadata.yaml +++ b/airbyte-integrations/connectors/source-gong/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 32382e40-3b49-4b99-9c5c-4076501914e7 - dockerImageTag: 0.3.1 + dockerImageTag: 0.3.6 dockerRepository: airbyte/source-gong documentationUrl: https://docs.airbyte.com/integrations/sources/gong githubIssueLabel: source-gong diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/migrations/__init__.py b/airbyte-integrations/connectors/source-gong/unit_tests/__init__.py similarity index 100% rename from airbyte-cdk/python/airbyte_cdk/sources/declarative/migrations/__init__.py rename to airbyte-integrations/connectors/source-gong/unit_tests/__init__.py diff --git a/airbyte-integrations/connectors/source-gong/unit_tests/test_request_with_filter.py b/airbyte-integrations/connectors/source-gong/unit_tests/test_request_with_filter.py new file mode 100644 index 000000000000..de602c599148 --- /dev/null +++ b/airbyte-integrations/connectors/source-gong/unit_tests/test_request_with_filter.py @@ -0,0 +1,47 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + +import unittest +from json import dumps, load +from typing import Dict + +from components import IncrementalSingleBodyFilterCursor + +from airbyte_cdk.sources.declarative.datetime.min_max_datetime import MinMaxDatetime +from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption + + +def config() -> Dict[str, str]: + with open( + "secrets/config.json", + ) as f: + yield load(f) + + +class TestGetRequestFilterOptions(unittest.TestCase): + def setUp(self): + self.instance = IncrementalSingleBodyFilterCursor( + start_datetime=MinMaxDatetime(datetime="2024-03-25", datetime_format="%Y-%m-%dT%H:%M:%SZ", parameters=None), + cursor_field="reviewTime", + datetime_format="%Y-%m-%d", + config=config, + parameters=None, + ) + + def test_get_request_filter_options_no_stream_slice(self): + expected = {} + option_type = "body_json" + result = self.instance._get_request_filter_options(option_type, None) + assert result == expected + + def test_get_request_filter_options_with_start_time_option(self): + expected = {"filter": {"reviewFromDate": "2024-03-25"}} + + self.instance.start_time_option = RequestOption(inject_into="body_json", field_name="filter, reviewFromDate", parameters=None) + self.instance.stream_slice = {"start_time": "2024-03-25", "end_time": "2024-03-29"} + option_type = "body_json" + result = self.instance._get_request_filter_options(option_type, self.instance.stream_slice) + assert result == expected + + +if __name__ == "__main__": + unittest.main() diff --git a/airbyte-integrations/connectors/source-google-ads/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-google-ads/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-google-ads/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-google-ads/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-google-ads/integration_tests/integration_test.py b/airbyte-integrations/connectors/source-google-ads/integration_tests/integration_test.py index c6960355b90c..aa6c453f9018 100644 --- a/airbyte-integrations/connectors/source-google-ads/integration_tests/integration_test.py +++ b/airbyte-integrations/connectors/source-google-ads/integration_tests/integration_test.py @@ -6,10 +6,11 @@ from pathlib import Path import pytest -from airbyte_cdk.models import SyncMode from google.ads.googleads.v17.services.types.google_ads_service import GoogleAdsRow from source_google_ads.source import SourceGoogleAds +from airbyte_cdk.models import SyncMode + @pytest.fixture(scope="module") def config(): diff --git a/airbyte-integrations/connectors/source-google-ads/main.py b/airbyte-integrations/connectors/source-google-ads/main.py index 2824c4955943..7e8e4ddf5226 100644 --- a/airbyte-integrations/connectors/source-google-ads/main.py +++ b/airbyte-integrations/connectors/source-google-ads/main.py @@ -4,5 +4,6 @@ from source_google_ads.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/config_migrations.py b/airbyte-integrations/connectors/source-google-ads/source_google_ads/config_migrations.py index 81bae9ceb5cb..61990be3b7b9 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/config_migrations.py +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/config_migrations.py @@ -14,6 +14,7 @@ from .utils import GAQL + FULL_REFRESH_CUSTOM_TABLE = [ "asset", "asset_group_listing_group_filter", diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/custom_query_stream.py b/airbyte-integrations/connectors/source-google-ads/source_google_ads/custom_query_stream.py index 4a3ac096cfdd..4b2a25a08a32 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/custom_query_stream.py +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/custom_query_stream.py @@ -9,6 +9,7 @@ from .streams import GoogleAdsStream, IncrementalGoogleAdsStream from .utils import GAQL + DATE_TYPES = ("segments.date", "segments.month", "segments.quarter", "segments.week") diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/google_ads.py b/airbyte-integrations/connectors/source-google-ads/source_google_ads/google_ads.py index 3a2128f6182f..982210066766 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/google_ads.py +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/google_ads.py @@ -7,8 +7,6 @@ from typing import Any, Iterable, Iterator, List, Mapping, MutableMapping import backoff -from airbyte_cdk.models import FailureType -from airbyte_cdk.utils import AirbyteTracedException from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.v17.services.types.google_ads_service import GoogleAdsRow, SearchGoogleAdsResponse from google.api_core.exceptions import InternalServerError, ServerError, TooManyRequests @@ -17,8 +15,12 @@ from google.protobuf.message import Message from proto.marshal.collections import Repeated, RepeatedComposite +from airbyte_cdk.models import FailureType +from airbyte_cdk.utils import AirbyteTracedException + from .utils import logger + API_VERSION = "v17" diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py b/airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py index 562dacf6f899..4fa488df17e3 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py @@ -6,11 +6,12 @@ import logging from typing import Any, Iterable, List, Mapping, MutableMapping, Tuple +from pendulum import duration, parse, today + from airbyte_cdk.models import FailureType, SyncMode from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.utils import AirbyteTracedException -from pendulum import duration, parse, today from .custom_query_stream import CustomQuery, IncrementalCustomQuery from .google_ads import GoogleAds diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py b/airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py index 0dc3374548fa..99da0e71f661 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py @@ -8,15 +8,16 @@ import backoff import pendulum -from airbyte_cdk.models import FailureType, SyncMode -from airbyte_cdk.sources.streams import CheckpointMixin, Stream -from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer -from airbyte_cdk.utils import AirbyteTracedException from google.ads.googleads.errors import GoogleAdsException from google.ads.googleads.v17.services.services.google_ads_service.pagers import SearchPager from google.ads.googleads.v17.services.types.google_ads_service import SearchGoogleAdsResponse from google.api_core.exceptions import InternalServerError, ServerError, ServiceUnavailable, TooManyRequests, Unauthenticated +from airbyte_cdk.models import FailureType, SyncMode +from airbyte_cdk.sources.streams import CheckpointMixin, Stream +from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer +from airbyte_cdk.utils import AirbyteTracedException + from .google_ads import GoogleAds, logger from .models import CustomerModel from .utils import ExpiredPageTokenError, chunk_date_range, detached, generator_backoff, get_resource_name, parse_dates, traced_exception diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/utils.py b/airbyte-integrations/connectors/source-google-ads/source_google_ads/utils.py index 824d9c9cb470..5b31eac22e37 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/utils.py +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/utils.py @@ -13,8 +13,6 @@ from typing import Any, Callable, Generator, Iterable, MutableMapping, Optional, Tuple, Type, Union import pendulum -from airbyte_cdk.models import FailureType -from airbyte_cdk.utils import AirbyteTracedException from google.ads.googleads.errors import GoogleAdsException from google.ads.googleads.v17.errors.types.authentication_error import AuthenticationErrorEnum from google.ads.googleads.v17.errors.types.authorization_error import AuthorizationErrorEnum @@ -23,6 +21,10 @@ from google.ads.googleads.v17.errors.types.request_error import RequestErrorEnum from google.api_core.exceptions import Unauthenticated +from airbyte_cdk.models import FailureType +from airbyte_cdk.utils import AirbyteTracedException + + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-google-ads/unit_tests/conftest.py b/airbyte-integrations/connectors/source-google-ads/unit_tests/conftest.py index f409e0f1ac52..21623048feda 100644 --- a/airbyte-integrations/connectors/source-google-ads/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-google-ads/unit_tests/conftest.py @@ -55,6 +55,7 @@ def mock_oauth_call(requests_mock): def customers(config): return [CustomerModel(id=_id, time_zone="local", is_manager_account=False) for _id in config["customer_id"].split(",")] + @pytest.fixture def additional_customers(config, customers): return customers + [CustomerModel(id="789", time_zone="local", is_manager_account=False)] diff --git a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_config_migrations.py b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_config_migrations.py index a65712bf0e9d..c6a7e287ed07 100644 --- a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_config_migrations.py +++ b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_config_migrations.py @@ -6,11 +6,13 @@ import json from typing import Any, Mapping -from airbyte_cdk.models import OrchestratorType, Type -from airbyte_cdk.sources import Source from source_google_ads.config_migrations import MigrateCustomQuery from source_google_ads.source import SourceGoogleAds +from airbyte_cdk.models import OrchestratorType, Type +from airbyte_cdk.sources import Source + + # BASE ARGS CMD = "check" TEST_CONFIG_PATH = "unit_tests/test_migrations/custom_query/test_config.json" diff --git a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_errors.py b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_errors.py index 49679c3be829..bb99b9cc427f 100644 --- a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_errors.py +++ b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_errors.py @@ -8,12 +8,13 @@ from unittest.mock import Mock import pytest -from airbyte_cdk.utils import AirbyteTracedException from source_google_ads.google_ads import GoogleAds from source_google_ads.models import CustomerModel from source_google_ads.source import SourceGoogleAds from source_google_ads.streams import AdGroupLabel, Label, ServiceAccounts +from airbyte_cdk.utils import AirbyteTracedException + from .common import MockGoogleAdsClient, mock_google_ads_request_failure @@ -35,7 +36,10 @@ def mock_get_customers(mocker): "Failed to access the customer '123'. Ensure the customer is linked to your manager account or check your permissions to access this customer account.", ), (["QUERY_ERROR"], "Incorrect custom query. Error in query: unexpected end of query."), - (["UNRECOGNIZED_FIELD"], "The Custom Query: `None` has unrecognized field in the query. Please make sure the field exists or name entered is valid."), + ( + ["UNRECOGNIZED_FIELD"], + "The Custom Query: `None` has unrecognized field in the query. Please make sure the field exists or name entered is valid.", + ), ( ["RESOURCE_EXHAUSTED"], ( diff --git a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_google_ads.py b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_google_ads.py index e3bec07f2976..5c8f93b4e7cf 100644 --- a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_google_ads.py +++ b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_google_ads.py @@ -8,14 +8,16 @@ import pendulum import pytest -from airbyte_cdk.utils import AirbyteTracedException from google.ads.googleads.v17.services.types.google_ads_service import GoogleAdsRow from google.auth import exceptions from source_google_ads.google_ads import GoogleAds from source_google_ads.streams import chunk_date_range +from airbyte_cdk.utils import AirbyteTracedException + from .common import MockGoogleAdsClient, MockGoogleAdsService + SAMPLE_SCHEMA = { "properties": { "segment.date": { @@ -148,11 +150,12 @@ def test_get_field_value(): response = GoogleAds.get_field_value(MockedDateSegment(date), field, {}) assert response == date + def test_get_field_value_object(): expected_response = [ - { "text": "An exciting headline", "policySummaryInfo": { "reviewStatus": "REVIEWED","approvalStatus":"APPROVED" } }, - { "text": "second" }, - ] + {"text": "An exciting headline", "policySummaryInfo": {"reviewStatus": "REVIEWED", "approvalStatus": "APPROVED"}}, + {"text": "second"}, + ] field = "ad_group_ad.ad.responsive_search_ad.headlines" ads_row = GoogleAdsRow( ad_group_ad={ @@ -161,14 +164,9 @@ def test_get_field_value_object(): "headlines": [ { "text": "An exciting headline", - "policy_summary_info": { - "review_status": "REVIEWED", - "approval_status": "APPROVED" - } + "policy_summary_info": {"review_status": "REVIEWED", "approval_status": "APPROVED"}, }, - { - "text": "second" - } + {"text": "second"}, ] } } @@ -176,13 +174,14 @@ def test_get_field_value_object(): ) response = GoogleAds.get_field_value(ads_row, field, {}) - assert [json.loads(i) for i in response] == expected_response + assert [json.loads(i) for i in response] == expected_response + def test_get_field_value_strings(): expected_response = [ - "http://url_one.com", - "https://url_two.com", - ] + "http://url_one.com", + "https://url_two.com", + ] ads_row = GoogleAdsRow( ad_group_ad={ "ad": { @@ -197,6 +196,7 @@ def test_get_field_value_strings(): response = GoogleAds.get_field_value(ads_row, field, {}) assert response == expected_response + def test_parse_single_result(): date = "2001-01-01" response = GoogleAds.parse_single_result(SAMPLE_SCHEMA, MockedDateSegment(date)) diff --git a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_incremental_events_streams.py b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_incremental_events_streams.py index 34b89d1e2e88..50173bce7ff3 100644 --- a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_incremental_events_streams.py +++ b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_incremental_events_streams.py @@ -8,11 +8,12 @@ import pendulum import pytest -from airbyte_cdk.models import SyncMode -from airbyte_cdk.utils import AirbyteTracedException from source_google_ads.google_ads import GoogleAds from source_google_ads.streams import CampaignCriterion, ChangeStatus +from airbyte_cdk.models import SyncMode +from airbyte_cdk.utils import AirbyteTracedException + def mock_response_parent(): yield [ @@ -82,7 +83,7 @@ def test_change_status_stream(config, customers): def test_change_status_stream_slices(config, additional_customers): - """ Change status stream slices should return correct empty slices for the new customers """ + """Change status stream slices should return correct empty slices for the new customers""" google_api = MockGoogleAds(credentials=config["credentials"]) stream = ChangeStatus(api=google_api, customers=additional_customers) @@ -94,12 +95,19 @@ def test_change_status_stream_slices(config, additional_customers): result_slices = list(stream.stream_slices(stream_state=stream_state)) assert len(result_slices) == 2 - assert result_slices == [{'start_date': '2023-11-01 12:36:04.772447', 'end_date': '2023-11-02 00:00:00.000000', 'customer_id': '123', - 'login_customer_id': None}, {'customer_id': '789', 'login_customer_id': None}] + assert result_slices == [ + { + "start_date": "2023-11-01 12:36:04.772447", + "end_date": "2023-11-02 00:00:00.000000", + "customer_id": "123", + "login_customer_id": None, + }, + {"customer_id": "789", "login_customer_id": None}, + ] def test_incremental_events_stream_slices(config, additional_customers): - """ Test if the empty slice will be produced for the new customers """ + """Test if the empty slice will be produced for the new customers""" stream_state = {"change_status": {"123": {"change_status.last_change_date_time": "2023-06-12 13:20:01.003295"}}} google_api = MockGoogleAds(credentials=config["credentials"]) @@ -121,12 +129,21 @@ def test_incremental_events_stream_slices(config, additional_customers): stream_slices = list(stream.stream_slices(stream_state=stream_state)) assert len(stream_slices) == 2 - assert stream_slices == [{'customer_id': '123', 'updated_ids': {'2', '1'}, 'deleted_ids': {'3', '4'}, - 'record_changed_time_map': {'1': '2023-06-13 12:36:01.772447', '2': '2023-06-13 12:36:02.772447', - '3': '2023-06-13 12:36:03.772447', '4': '2023-06-13 12:36:04.772447'}, - 'login_customer_id': None}, - {'customer_id': '789', 'updated_ids': set(), 'deleted_ids': set(), 'record_changed_time_map': {}, - 'login_customer_id': None}] + assert stream_slices == [ + { + "customer_id": "123", + "updated_ids": {"2", "1"}, + "deleted_ids": {"3", "4"}, + "record_changed_time_map": { + "1": "2023-06-13 12:36:01.772447", + "2": "2023-06-13 12:36:02.772447", + "3": "2023-06-13 12:36:03.772447", + "4": "2023-06-13 12:36:04.772447", + }, + "login_customer_id": None, + }, + {"customer_id": "789", "updated_ids": set(), "deleted_ids": set(), "record_changed_time_map": {}, "login_customer_id": None}, + ] def test_child_incremental_events_read(config, customers): diff --git a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_source.py b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_source.py index fd53878536cf..10c384e532c9 100644 --- a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_source.py @@ -10,8 +10,6 @@ import pendulum import pytest -from airbyte_cdk import AirbyteTracedException -from airbyte_cdk.models import AirbyteStream, ConfiguredAirbyteCatalog, ConfiguredAirbyteStream, DestinationSyncMode, FailureType, SyncMode from pendulum import duration, today from source_google_ads.custom_query_stream import IncrementalCustomQuery from source_google_ads.google_ads import GoogleAds @@ -20,6 +18,9 @@ from source_google_ads.streams import AdGroupAdLegacy, chunk_date_range from source_google_ads.utils import GAQL +from airbyte_cdk import AirbyteTracedException +from airbyte_cdk.models import AirbyteStream, ConfiguredAirbyteCatalog, ConfiguredAirbyteStream, DestinationSyncMode, FailureType, SyncMode + from .common import MockGoogleAdsClient diff --git a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_streams.py index d0665bea9ac9..fbf8c8f07f3c 100644 --- a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_streams.py @@ -6,8 +6,6 @@ from unittest.mock import Mock import pytest -from airbyte_cdk.models import FailureType, SyncMode -from airbyte_cdk.utils import AirbyteTracedException from google.ads.googleads.errors import GoogleAdsException from google.ads.googleads.v17.errors.types.errors import ErrorCode, GoogleAdsError, GoogleAdsFailure from google.ads.googleads.v17.errors.types.request_error import RequestErrorEnum @@ -16,6 +14,10 @@ from source_google_ads.google_ads import GoogleAds from source_google_ads.streams import AdGroup, ClickView, Customer, CustomerLabel +from airbyte_cdk.models import FailureType, SyncMode +from airbyte_cdk.utils import AirbyteTracedException + + # EXPIRED_PAGE_TOKEN exception will be raised when page token has expired. exception = GoogleAdsException( error=RpcError(), @@ -251,8 +253,10 @@ def test_retry_500_raises_transient_error(mocker, config, customers): with pytest.raises(AirbyteTracedException) as exception: records = list(stream.read_records(sync_mode=SyncMode.incremental, cursor_field=["segments.date"], stream_slice=stream_slice)) - assert exception.value.internal_message == ("Internal Error encountered Unable to fetch data from Google Ads API due to " - "temporal error on the Google Ads server. Please retry again later. ") + assert exception.value.internal_message == ( + "Internal Error encountered Unable to fetch data from Google Ads API due to " + "temporal error on the Google Ads server. Please retry again later. " + ) assert exception.value.failure_type == FailureType.transient_error assert mocked_search.call_count == 5 assert records == [] diff --git a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_utils.py b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_utils.py index fe162fb993bc..5fbeab771444 100644 --- a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_utils.py +++ b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_utils.py @@ -8,10 +8,11 @@ import backoff import pytest -from airbyte_cdk.utils import AirbyteTracedException from source_google_ads import SourceGoogleAds from source_google_ads.utils import GAQL, generator_backoff +from airbyte_cdk.utils import AirbyteTracedException + def test_parse_GAQL_ok(): sql = GAQL.parse("SELECT field FROM table") diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-google-analytics-data-api/integration_tests/acceptance.py index d49b55882333..a9256a533972 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/main.py b/airbyte-integrations/connectors/source-google-analytics-data-api/main.py index 93839ed0e51a..613303154767 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/main.py +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/main.py @@ -4,5 +4,6 @@ from source_google_analytics_data_api.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/metadata.yaml b/airbyte-integrations/connectors/source-google-analytics-data-api/metadata.yaml index 5adca8bb5352..08956880d91b 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/metadata.yaml +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/metadata.yaml @@ -8,11 +8,11 @@ data: - www.googleapis.com - analyticsdata.googleapis.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 3cc2eafd-84aa-4dca-93af-322d9dfeec1a - dockerImageTag: 2.6.1 + dockerImageTag: 2.6.2 dockerRepository: airbyte/source-google-analytics-data-api documentationUrl: https://docs.airbyte.com/integrations/sources/google-analytics-data-api githubIssueLabel: source-google-analytics-data-api diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/poetry.lock b/airbyte-integrations/connectors/source-google-analytics-data-api/poetry.lock index 517184e314a7..e567557509d2 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/poetry.lock +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/poetry.lock @@ -48,13 +48,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models-dataclasses" -version = "0.13.0" +version = "0.13.1" description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models_dataclasses-0.13.0-py3-none-any.whl", hash = "sha256:0aedb99ffc4f9aab0ce91bba2c292fa17cd8fd4b42eeba196d6a16c20bbbd7a5"}, - {file = "airbyte_protocol_models_dataclasses-0.13.0.tar.gz", hash = "sha256:72e67850d661e2808406aec5839b3158ebb94d3553b798dbdae1b4a278548d2f"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1-py3-none-any.whl", hash = "sha256:20a734b7b1c3479a643777830db6a2e0a34428f33d16abcfd320552576fabe5a"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1.tar.gz", hash = "sha256:ec6a0fb6b16267bde910f52279445d06c8e1a3e4ed82ac2937b405ab280449d5"}, ] [[package]] @@ -70,24 +70,24 @@ files = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -474,20 +474,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -551,13 +551,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -572,13 +572,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -586,7 +586,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -743,22 +742,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -856,131 +858,150 @@ twitter = ["twython"] [[package]] name = "numpy" -version = "2.1.2" +version = "2.2.0" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.10" files = [ - {file = "numpy-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466"}, - {file = "numpy-2.1.2-cp310-cp310-win32.whl", hash = "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb"}, - {file = "numpy-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146"}, - {file = "numpy-2.1.2-cp311-cp311-win32.whl", hash = "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c"}, - {file = "numpy-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142"}, - {file = "numpy-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550"}, - {file = "numpy-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe"}, - {file = "numpy-2.1.2-cp313-cp313-win32.whl", hash = "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a"}, - {file = "numpy-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e"}, - {file = "numpy-2.1.2.tar.gz", hash = "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c"}, + {file = "numpy-2.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1e25507d85da11ff5066269d0bd25d06e0a0f2e908415534f3e603d2a78e4ffa"}, + {file = "numpy-2.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a62eb442011776e4036af5c8b1a00b706c5bc02dc15eb5344b0c750428c94219"}, + {file = "numpy-2.2.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:b606b1aaf802e6468c2608c65ff7ece53eae1a6874b3765f69b8ceb20c5fa78e"}, + {file = "numpy-2.2.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:36b2b43146f646642b425dd2027730f99bac962618ec2052932157e213a040e9"}, + {file = "numpy-2.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fe8f3583e0607ad4e43a954e35c1748b553bfe9fdac8635c02058023277d1b3"}, + {file = "numpy-2.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:122fd2fcfafdefc889c64ad99c228d5a1f9692c3a83f56c292618a59aa60ae83"}, + {file = "numpy-2.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3f2f5cddeaa4424a0a118924b988746db6ffa8565e5829b1841a8a3bd73eb59a"}, + {file = "numpy-2.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7fe4bb0695fe986a9e4deec3b6857003b4cfe5c5e4aac0b95f6a658c14635e31"}, + {file = "numpy-2.2.0-cp310-cp310-win32.whl", hash = "sha256:b30042fe92dbd79f1ba7f6898fada10bdaad1847c44f2dff9a16147e00a93661"}, + {file = "numpy-2.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dc1d6d66f8d37843ed281773c7174f03bf7ad826523f73435deb88ba60d2d4"}, + {file = "numpy-2.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9874bc2ff574c40ab7a5cbb7464bf9b045d617e36754a7bc93f933d52bd9ffc6"}, + {file = "numpy-2.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0da8495970f6b101ddd0c38ace92edea30e7e12b9a926b57f5fabb1ecc25bb90"}, + {file = "numpy-2.2.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0557eebc699c1c34cccdd8c3778c9294e8196df27d713706895edc6f57d29608"}, + {file = "numpy-2.2.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:3579eaeb5e07f3ded59298ce22b65f877a86ba8e9fe701f5576c99bb17c283da"}, + {file = "numpy-2.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40deb10198bbaa531509aad0cd2f9fadb26c8b94070831e2208e7df543562b74"}, + {file = "numpy-2.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2aed8fcf8abc3020d6a9ccb31dbc9e7d7819c56a348cc88fd44be269b37427e"}, + {file = "numpy-2.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a222d764352c773aa5ebde02dd84dba3279c81c6db2e482d62a3fa54e5ece69b"}, + {file = "numpy-2.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4e58666988605e251d42c2818c7d3d8991555381be26399303053b58a5bbf30d"}, + {file = "numpy-2.2.0-cp311-cp311-win32.whl", hash = "sha256:4723a50e1523e1de4fccd1b9a6dcea750c2102461e9a02b2ac55ffeae09a4410"}, + {file = "numpy-2.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:16757cf28621e43e252c560d25b15f18a2f11da94fea344bf26c599b9cf54b73"}, + {file = "numpy-2.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cff210198bb4cae3f3c100444c5eaa573a823f05c253e7188e1362a5555235b3"}, + {file = "numpy-2.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:58b92a5828bd4d9aa0952492b7de803135038de47343b2aa3cc23f3b71a3dc4e"}, + {file = "numpy-2.2.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:ebe5e59545401fbb1b24da76f006ab19734ae71e703cdb4a8b347e84a0cece67"}, + {file = "numpy-2.2.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:e2b8cd48a9942ed3f85b95ca4105c45758438c7ed28fff1e4ce3e57c3b589d8e"}, + {file = "numpy-2.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57fcc997ffc0bef234b8875a54d4058afa92b0b0c4223fc1f62f24b3b5e86038"}, + {file = "numpy-2.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ad7d11b309bd132d74397fcf2920933c9d1dc865487128f5c03d580f2c3d03"}, + {file = "numpy-2.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cb24cca1968b21355cc6f3da1a20cd1cebd8a023e3c5b09b432444617949085a"}, + {file = "numpy-2.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0798b138c291d792f8ea40fe3768610f3c7dd2574389e37c3f26573757c8f7ef"}, + {file = "numpy-2.2.0-cp312-cp312-win32.whl", hash = "sha256:afe8fb968743d40435c3827632fd36c5fbde633b0423da7692e426529b1759b1"}, + {file = "numpy-2.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:3a4199f519e57d517ebd48cb76b36c82da0360781c6a0353e64c0cac30ecaad3"}, + {file = "numpy-2.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f8c8b141ef9699ae777c6278b52c706b653bf15d135d302754f6b2e90eb30367"}, + {file = "numpy-2.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f0986e917aca18f7a567b812ef7ca9391288e2acb7a4308aa9d265bd724bdae"}, + {file = "numpy-2.2.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:1c92113619f7b272838b8d6702a7f8ebe5edea0df48166c47929611d0b4dea69"}, + {file = "numpy-2.2.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5a145e956b374e72ad1dff82779177d4a3c62bc8248f41b80cb5122e68f22d13"}, + {file = "numpy-2.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18142b497d70a34b01642b9feabb70156311b326fdddd875a9981f34a369b671"}, + {file = "numpy-2.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7d41d1612c1a82b64697e894b75db6758d4f21c3ec069d841e60ebe54b5b571"}, + {file = "numpy-2.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a98f6f20465e7618c83252c02041517bd2f7ea29be5378f09667a8f654a5918d"}, + {file = "numpy-2.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e09d40edfdb4e260cb1567d8ae770ccf3b8b7e9f0d9b5c2a9992696b30ce2742"}, + {file = "numpy-2.2.0-cp313-cp313-win32.whl", hash = "sha256:3905a5fffcc23e597ee4d9fb3fcd209bd658c352657548db7316e810ca80458e"}, + {file = "numpy-2.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:a184288538e6ad699cbe6b24859206e38ce5fba28f3bcfa51c90d0502c1582b2"}, + {file = "numpy-2.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7832f9e8eb00be32f15fdfb9a981d6955ea9adc8574c521d48710171b6c55e95"}, + {file = "numpy-2.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f0dd071b95bbca244f4cb7f70b77d2ff3aaaba7fa16dc41f58d14854a6204e6c"}, + {file = "numpy-2.2.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:b0b227dcff8cdc3efbce66d4e50891f04d0a387cce282fe1e66199146a6a8fca"}, + {file = "numpy-2.2.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:6ab153263a7c5ccaf6dfe7e53447b74f77789f28ecb278c3b5d49db7ece10d6d"}, + {file = "numpy-2.2.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e500aba968a48e9019e42c0c199b7ec0696a97fa69037bea163b55398e390529"}, + {file = "numpy-2.2.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:440cfb3db4c5029775803794f8638fbdbf71ec702caf32735f53b008e1eaece3"}, + {file = "numpy-2.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a55dc7a7f0b6198b07ec0cd445fbb98b05234e8b00c5ac4874a63372ba98d4ab"}, + {file = "numpy-2.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4bddbaa30d78c86329b26bd6aaaea06b1e47444da99eddac7bf1e2fab717bd72"}, + {file = "numpy-2.2.0-cp313-cp313t-win32.whl", hash = "sha256:30bf971c12e4365153afb31fc73f441d4da157153f3400b82db32d04de1e4066"}, + {file = "numpy-2.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:d35717333b39d1b6bb8433fa758a55f1081543de527171543a2b710551d40881"}, + {file = "numpy-2.2.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e12c6c1ce84628c52d6367863773f7c8c8241be554e8b79686e91a43f1733773"}, + {file = "numpy-2.2.0-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:b6207dc8fb3c8cb5668e885cef9ec7f70189bec4e276f0ff70d5aa078d32c88e"}, + {file = "numpy-2.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a50aeff71d0f97b6450d33940c7181b08be1441c6c193e678211bff11aa725e7"}, + {file = "numpy-2.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:df12a1f99b99f569a7c2ae59aa2d31724e8d835fc7f33e14f4792e3071d11221"}, + {file = "numpy-2.2.0.tar.gz", hash = "sha256:140dd80ff8981a583a60980be1a655068f8adebf7a45a06a6858c873fcdcd4a0"}, ] [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.12" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.12-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ece01a7ec71d9940cc654c482907a6b65df27251255097629d0dea781f255c6d"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c34ec9aebc04f11f4b978dd6caf697a2df2dd9b47d35aa4cc606cabcb9df69d7"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd6ec8658da3480939c79b9e9e27e0db31dffcd4ba69c334e98c9976ac29140e"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f17e6baf4cf01534c9de8a16c0c611f3d94925d1701bf5f4aff17003677d8ced"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6402ebb74a14ef96f94a868569f5dccf70d791de49feb73180eb3c6fda2ade56"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0000758ae7c7853e0a4a6063f534c61656ebff644391e1f81698c1b2d2fc8cd2"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:888442dcee99fd1e5bd37a4abb94930915ca6af4db50e23e746cdf4d1e63db13"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c1f7a3ce79246aa0e92f5458d86c54f257fb5dfdc14a192651ba7ec2c00f8a05"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:802a3935f45605c66fb4a586488a38af63cb37aaad1c1d94c982c40dcc452e85"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1da1ef0113a2be19bb6c557fb0ec2d79c92ebd2fed4cfb1b26bab93f021fb885"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a3273e99f367f137d5b3fecb5e9f45bcdbfac2a8b2f32fbc72129bbd48789c2"}, + {file = "orjson-3.10.12-cp310-none-win32.whl", hash = "sha256:475661bf249fd7907d9b0a2a2421b4e684355a77ceef85b8352439a9163418c3"}, + {file = "orjson-3.10.12-cp310-none-win_amd64.whl", hash = "sha256:87251dc1fb2b9e5ab91ce65d8f4caf21910d99ba8fb24b49fd0c118b2362d509"}, + {file = "orjson-3.10.12-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a734c62efa42e7df94926d70fe7d37621c783dea9f707a98cdea796964d4cf74"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:750f8b27259d3409eda8350c2919a58b0cfcd2054ddc1bd317a643afc646ef23"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb52c22bfffe2857e7aa13b4622afd0dd9d16ea7cc65fd2bf318d3223b1b6252"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:440d9a337ac8c199ff8251e100c62e9488924c92852362cd27af0e67308c16ef"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9e15c06491c69997dfa067369baab3bf094ecb74be9912bdc4339972323f252"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:362d204ad4b0b8724cf370d0cd917bb2dc913c394030da748a3bb632445ce7c4"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2b57cbb4031153db37b41622eac67329c7810e5f480fda4cfd30542186f006ae"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:165c89b53ef03ce0d7c59ca5c82fa65fe13ddf52eeb22e859e58c237d4e33b9b"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5dee91b8dfd54557c1a1596eb90bcd47dbcd26b0baaed919e6861f076583e9da"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77a4e1cfb72de6f905bdff061172adfb3caf7a4578ebf481d8f0530879476c07"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:038d42c7bc0606443459b8fe2d1f121db474c49067d8d14c6a075bbea8bf14dd"}, + {file = "orjson-3.10.12-cp311-none-win32.whl", hash = "sha256:03b553c02ab39bed249bedd4abe37b2118324d1674e639b33fab3d1dafdf4d79"}, + {file = "orjson-3.10.12-cp311-none-win_amd64.whl", hash = "sha256:8b8713b9e46a45b2af6b96f559bfb13b1e02006f4242c156cbadef27800a55a8"}, + {file = "orjson-3.10.12-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:53206d72eb656ca5ac7d3a7141e83c5bbd3ac30d5eccfe019409177a57634b0d"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac8010afc2150d417ebda810e8df08dd3f544e0dd2acab5370cfa6bcc0662f8f"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed459b46012ae950dd2e17150e838ab08215421487371fa79d0eced8d1461d70"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dcb9673f108a93c1b52bfc51b0af422c2d08d4fc710ce9c839faad25020bb69"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22a51ae77680c5c4652ebc63a83d5255ac7d65582891d9424b566fb3b5375ee9"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910fdf2ac0637b9a77d1aad65f803bac414f0b06f720073438a7bd8906298192"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:24ce85f7100160936bc2116c09d1a8492639418633119a2224114f67f63a4559"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a76ba5fc8dd9c913640292df27bff80a685bed3a3c990d59aa6ce24c352f8fc"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ff70ef093895fd53f4055ca75f93f047e088d1430888ca1229393a7c0521100f"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f4244b7018b5753ecd10a6d324ec1f347da130c953a9c88432c7fbc8875d13be"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:16135ccca03445f37921fa4b585cff9a58aa8d81ebcb27622e69bfadd220b32c"}, + {file = "orjson-3.10.12-cp312-none-win32.whl", hash = "sha256:2d879c81172d583e34153d524fcba5d4adafbab8349a7b9f16ae511c2cee8708"}, + {file = "orjson-3.10.12-cp312-none-win_amd64.whl", hash = "sha256:fc23f691fa0f5c140576b8c365bc942d577d861a9ee1142e4db468e4e17094fb"}, + {file = "orjson-3.10.12-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:47962841b2a8aa9a258b377f5188db31ba49af47d4003a32f55d6f8b19006543"}, + {file = "orjson-3.10.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6334730e2532e77b6054e87ca84f3072bee308a45a452ea0bffbbbc40a67e296"}, + {file = "orjson-3.10.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:accfe93f42713c899fdac2747e8d0d5c659592df2792888c6c5f829472e4f85e"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a7974c490c014c48810d1dede6c754c3cc46598da758c25ca3b4001ac45b703f"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3f250ce7727b0b2682f834a3facff88e310f52f07a5dcfd852d99637d386e79e"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f31422ff9486ae484f10ffc51b5ab2a60359e92d0716fcce1b3593d7bb8a9af6"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5f29c5d282bb2d577c2a6bbde88d8fdcc4919c593f806aac50133f01b733846e"}, + {file = "orjson-3.10.12-cp313-none-win32.whl", hash = "sha256:f45653775f38f63dc0e6cd4f14323984c3149c05d6007b58cb154dd080ddc0dc"}, + {file = "orjson-3.10.12-cp313-none-win_amd64.whl", hash = "sha256:229994d0c376d5bdc91d92b3c9e6be2f1fbabd4cc1b59daae1443a46ee5e9825"}, + {file = "orjson-3.10.12-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7d69af5b54617a5fac5c8e5ed0859eb798e2ce8913262eb522590239db6c6763"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ed119ea7d2953365724a7059231a44830eb6bbb0cfead33fcbc562f5fd8f935"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9c5fc1238ef197e7cad5c91415f524aaa51e004be5a9b35a1b8a84ade196f73f"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43509843990439b05f848539d6f6198d4ac86ff01dd024b2f9a795c0daeeab60"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f72e27a62041cfb37a3de512247ece9f240a561e6c8662276beaf4d53d406db4"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a904f9572092bb6742ab7c16c623f0cdccbad9eeb2d14d4aa06284867bddd31"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:855c0833999ed5dc62f64552db26f9be767434917d8348d77bacaab84f787d7b"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:897830244e2320f6184699f598df7fb9db9f5087d6f3f03666ae89d607e4f8ed"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0b32652eaa4a7539f6f04abc6243619c56f8530c53bf9b023e1269df5f7816dd"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:36b4aa31e0f6a1aeeb6f8377769ca5d125db000f05c20e54163aef1d3fe8e833"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5535163054d6cbf2796f93e4f0dbc800f61914c0e3c4ed8499cf6ece22b4a3da"}, + {file = "orjson-3.10.12-cp38-none-win32.whl", hash = "sha256:90a5551f6f5a5fa07010bf3d0b4ca2de21adafbbc0af6cb700b63cd767266cb9"}, + {file = "orjson-3.10.12-cp38-none-win_amd64.whl", hash = "sha256:703a2fb35a06cdd45adf5d733cf613cbc0cb3ae57643472b16bc22d325b5fb6c"}, + {file = "orjson-3.10.12-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f29de3ef71a42a5822765def1febfb36e0859d33abf5c2ad240acad5c6a1b78d"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de365a42acc65d74953f05e4772c974dad6c51cfc13c3240899f534d611be967"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:91a5a0158648a67ff0004cb0df5df7dcc55bfc9ca154d9c01597a23ad54c8d0c"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c47ce6b8d90fe9646a25b6fb52284a14ff215c9595914af63a5933a49972ce36"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0eee4c2c5bfb5c1b47a5db80d2ac7aaa7e938956ae88089f098aff2c0f35d5d8"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35d3081bbe8b86587eb5c98a73b97f13d8f9fea685cf91a579beddacc0d10566"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73c23a6e90383884068bc2dba83d5222c9fcc3b99a0ed2411d38150734236755"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5472be7dc3269b4b52acba1433dac239215366f89dc1d8d0e64029abac4e714e"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:7319cda750fca96ae5973efb31b17d97a5c5225ae0bc79bf5bf84df9e1ec2ab6"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:74d5ca5a255bf20b8def6a2b96b1e18ad37b4a122d59b154c458ee9494377f80"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ff31d22ecc5fb85ef62c7d4afe8301d10c558d00dd24274d4bbe464380d3cd69"}, + {file = "orjson-3.10.12-cp39-none-win32.whl", hash = "sha256:c22c3ea6fba91d84fcb4cda30e64aff548fcf0c44c876e681f47d61d24b12e6b"}, + {file = "orjson-3.10.12-cp39-none-win_amd64.whl", hash = "sha256:be604f60d45ace6b0b33dd990a66b4526f1a7a186ac411c942674625456ca548"}, + {file = "orjson-3.10.12.tar.gz", hash = "sha256:0a78bbda3aea0f9f079057ee1ee8a1ecf790d4f1af88dd67493c6b8ee52506ff"}, ] [[package]] @@ -1155,19 +1176,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.3" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.3-py3-none-any.whl", hash = "sha256:be04d85bbc7b65651c5f8e6b9976ed9c6f41782a55524cef079a34a0bb82144d"}, + {file = "pydantic-2.10.3.tar.gz", hash = "sha256:cb5ac360ce894ceacd69c403187900a02c4b20b693a9dd1d643e1effab9eadf9"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.1" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1175,100 +1196,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.1" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206"}, + {file = "pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c"}, + {file = "pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc"}, + {file = "pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9"}, + {file = "pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5"}, + {file = "pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae"}, + {file = "pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c"}, + {file = "pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16"}, + {file = "pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23"}, + {file = "pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05"}, + {file = "pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337"}, + {file = "pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:5897bec80a09b4084aee23f9b73a9477a46c3304ad1d2d07acca19723fb1de62"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d0165ab2914379bd56908c02294ed8405c252250668ebcb438a55494c69f44ab"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b9af86e1d8e4cfc82c2022bfaa6f459381a50b94a29e95dcdda8442d6d83864"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f6c8a66741c5f5447e047ab0ba7a1c61d1e95580d64bce852e3df1f895c4067"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a42d6a8156ff78981f8aa56eb6394114e0dedb217cf8b729f438f643608cbcd"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64c65f40b4cd8b0e049a8edde07e38b476da7e3aaebe63287c899d2cff253fa5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdcf339322a3fae5cbd504edcefddd5a50d9ee00d968696846f089b4432cf78"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf99c8404f008750c846cb4ac4667b798a9f7de673ff719d705d9b2d6de49c5f"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f1edcea27918d748c7e5e4d917297b2a0ab80cad10f86631e488b7cddf76a36"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:159cac0a3d096f79ab6a44d77a961917219707e2a130739c64d4dd46281f5c2a"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:029d9757eb621cc6e1848fa0b0310310de7301057f623985698ed7ebb014391b"}, + {file = "pydantic_core-2.27.1-cp38-none-win32.whl", hash = "sha256:a28af0695a45f7060e6f9b7092558a928a28553366519f64083c63a44f70e618"}, + {file = "pydantic_core-2.27.1-cp38-none-win_amd64.whl", hash = "sha256:2d4567c850905d5eaaed2f7a404e61012a51caf288292e016360aa2b96ff38d4"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:e9386266798d64eeb19dd3677051f5705bf873e98e15897ddb7d76f477131967"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4228b5b646caa73f119b1ae756216b59cc6e2267201c27d3912b592c5e323b60"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3dfe500de26c52abe0477dde16192ac39c98f05bf2d80e76102d394bd13854"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aee66be87825cdf72ac64cb03ad4c15ffef4143dbf5c113f64a5ff4f81477bf9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b748c44bb9f53031c8cbc99a8a061bc181c1000c60a30f55393b6e9c45cc5bd"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ca038c7f6a0afd0b2448941b6ef9d5e1949e999f9e5517692eb6da58e9d44be"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e0bd57539da59a3e4671b90a502da9a28c72322a4f17866ba3ac63a82c4498e"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac6c2c45c847bbf8f91930d88716a0fb924b51e0c6dad329b793d670ec5db792"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b94d4ba43739bbe8b0ce4262bcc3b7b9f31459ad120fb595627eaeb7f9b9ca01"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:00e6424f4b26fe82d44577b4c842d7df97c20be6439e8e685d0d715feceb9fb9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:38de0a70160dd97540335b7ad3a74571b24f1dc3ed33f815f0880682e6880131"}, + {file = "pydantic_core-2.27.1-cp39-none-win32.whl", hash = "sha256:7ccebf51efc61634f6c2344da73e366c75e735960b5654b63d7e6f69a5885fa3"}, + {file = "pydantic_core-2.27.1-cp39-none-win_amd64.whl", hash = "sha256:a57847b090d7892f123726202b7daa20df6694cbd583b67a592e856bff603d6c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5fde892e6c697ce3e30c61b239330fc5d569a71fefd4eb6512fc6caec9dd9e2f"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:816f5aa087094099fff7edabb5e01cc370eb21aa1a1d44fe2d2aefdfb5599b31"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c10c309e18e443ddb108f0ef64e8729363adbfd92d6d57beec680f6261556f3"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98476c98b02c8e9b2eec76ac4156fd006628b1b2d0ef27e548ffa978393fd154"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c3027001c28434e7ca5a6e1e527487051136aa81803ac812be51802150d880dd"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7699b1df36a48169cdebda7ab5a2bac265204003f153b4bd17276153d997670a"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1c39b07d90be6b48968ddc8c19e7585052088fd7ec8d568bb31ff64c70ae3c97"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:46ccfe3032b3915586e469d4972973f893c0a2bb65669194a5bdea9bacc088c2"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:62ba45e21cf6571d7f716d903b5b7b6d2617e2d5d67c0923dc47b9d41369f840"}, + {file = "pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235"}, ] [package.dependencies] @@ -1488,105 +1520,105 @@ files = [ [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -1727,33 +1759,33 @@ typing-extensions = "*" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1795,20 +1827,21 @@ files = [ [[package]] name = "tqdm" -version = "4.66.6" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63"}, - {file = "tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -1882,81 +1915,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [[package]] diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/pyproject.toml b/airbyte-integrations/connectors/source-google-analytics-data-api/pyproject.toml index 3f5bedb75b6e..d658b8879b45 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/pyproject.toml +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "2.6.1" +version = "2.6.2" name = "source-google-analytics-data-api" description = "Source implementation for Google Analytics Data Api." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/api_quota.py b/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/api_quota.py index 27591cb3a1a7..2267cd3a19e3 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/api_quota.py +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/api_quota.py @@ -8,9 +8,10 @@ from typing import Any, Iterable, Mapping, Optional import requests -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ResponseAction from requests.exceptions import JSONDecodeError +from airbyte_cdk.sources.streams.http.error_handlers.response_models import ResponseAction + from .utils import API_LIMIT_PER_HOUR diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/authenticator.py b/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/authenticator.py index 4a4bedce6ac3..b290368c983f 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/authenticator.py +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/authenticator.py @@ -6,6 +6,7 @@ import jwt import requests + from source_google_analytics_data_api import utils diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/config_migrations.py b/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/config_migrations.py index c055b6445bc2..e1d1d23ccf82 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/config_migrations.py +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/config_migrations.py @@ -8,6 +8,7 @@ import dpath.util import orjson + from airbyte_cdk.config_observation import create_connector_config_control_message from airbyte_cdk.entrypoint import AirbyteEntrypoint from airbyte_cdk.models import AirbyteMessageSerializer @@ -15,6 +16,7 @@ from .source import SourceGoogleAnalyticsDataApi + logger = logging.getLogger("airbyte_logger") diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/google_analytics_data_api_metadata_error_mapping.py b/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/google_analytics_data_api_metadata_error_mapping.py index ea17f13864ab..f3e4723157c7 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/google_analytics_data_api_metadata_error_mapping.py +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/google_analytics_data_api_metadata_error_mapping.py @@ -7,6 +7,7 @@ from airbyte_cdk.sources.streams.http.error_handlers.default_error_mapping import DEFAULT_ERROR_MAPPING from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, ResponseAction + PROPERTY_ID_DOCS_URL = "https://developers.google.com/analytics/devguides/reporting/data/v1/property-id#what_is_my_property_id" MESSAGE = "Incorrect Property ID: {property_id}. Access was denied to the property ID entered. Check your access to the Property ID or use Google Analytics {property_id_docs_url} to find your Property ID." diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/source.py b/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/source.py index 957805ecde5b..1ed3e035984c 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/source.py +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/source.py @@ -18,6 +18,8 @@ import jsonschema import pendulum import requests +from requests import HTTPError + from airbyte_cdk.models import FailureType, SyncMode from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream @@ -28,7 +30,6 @@ from airbyte_cdk.sources.streams.http.exceptions import BaseBackoffException from airbyte_cdk.sources.streams.http.http_client import MessageRepresentationAirbyteTracedErrors from airbyte_cdk.utils import AirbyteTracedException -from requests import HTTPError from source_google_analytics_data_api import utils from source_google_analytics_data_api.google_analytics_data_api_base_error_mapping import get_google_analytics_data_api_base_error_mapping from source_google_analytics_data_api.google_analytics_data_api_metadata_error_mapping import ( @@ -49,6 +50,7 @@ transform_json, ) + # set the quota handler globally since limitations are the same for all streams # the initial values should be saved once and tracked for each stream, inclusively. GoogleAnalyticsQuotaHandler: GoogleAnalyticsApiQuota = GoogleAnalyticsApiQuota() diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/utils.py b/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/utils.py index d2783f6634ba..f08a5472c0d4 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/utils.py +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/source_google_analytics_data_api/utils.py @@ -12,9 +12,11 @@ import jsonschema import pandas as pd + from airbyte_cdk.sources.streams.http import requests_native_auth as auth from source_google_analytics_data_api.authenticator import GoogleServiceKeyAuthenticator + DATE_FORMAT = "%Y-%m-%d" metrics_data_native_types_map: Dict = { diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/conftest.py b/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/conftest.py index fcd8e1b879be..95b944b3bae7 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/conftest.py @@ -9,6 +9,7 @@ import pytest + # json credentials with fake private key json_credentials = """ { diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_api_quota.py b/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_api_quota.py index bd5af212c081..af86742f72eb 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_api_quota.py +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_api_quota.py @@ -4,9 +4,11 @@ import pytest import requests -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ResponseAction from source_google_analytics_data_api.api_quota import GoogleAnalyticsApiQuota +from airbyte_cdk.sources.streams.http.error_handlers.response_models import ResponseAction + + TEST_QUOTA_INSTANCE: GoogleAnalyticsApiQuota = GoogleAnalyticsApiQuota() @@ -35,7 +37,7 @@ def test_check_initial_quota_is_empty(): "potentiallyThresholdedRequestsPerHour": {"consumed": 1, "remaining": 26}, } }, - False, # partial_quota + False, # partial_quota ResponseAction.RETRY, None, # backoff_time_exp False, # stop_iter_exp diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_migration.py b/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_migration.py index a0df1b3f59d2..aa70ba13cb9d 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_migration.py +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_migration.py @@ -4,10 +4,11 @@ from unittest.mock import patch -from airbyte_cdk.entrypoint import AirbyteEntrypoint from source_google_analytics_data_api import SourceGoogleAnalyticsDataApi from source_google_analytics_data_api.config_migrations import MigratePropertyID +from airbyte_cdk.entrypoint import AirbyteEntrypoint + @patch.object(SourceGoogleAnalyticsDataApi, "read_config") @patch.object(SourceGoogleAnalyticsDataApi, "write_config") diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_migration_cohortspec/test_config_migration_cohortspec.py b/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_migration_cohortspec/test_config_migration_cohortspec.py index 340d6db7660e..aac51ada0dcc 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_migration_cohortspec/test_config_migration_cohortspec.py +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_migration_cohortspec/test_config_migration_cohortspec.py @@ -8,11 +8,13 @@ from typing import Any, Mapping import dpath.util -from airbyte_cdk.models import OrchestratorType, Type -from airbyte_cdk.sources import Source from source_google_analytics_data_api.config_migrations import MigrateCustomReportsCohortSpec from source_google_analytics_data_api.source import SourceGoogleAnalyticsDataApi +from airbyte_cdk.models import OrchestratorType, Type +from airbyte_cdk.sources import Source + + # BASE ARGS CMD = "check" TEST_CONFIG_PATH = f"{os.path.dirname(__file__)}/test_config.json" diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_migrations/test_config_migrations.py b/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_migrations/test_config_migrations.py index 5bee2f8ab6b9..39b569b5f234 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_migrations/test_config_migrations.py +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_migrations/test_config_migrations.py @@ -6,11 +6,13 @@ import json from typing import Any, Mapping -from airbyte_cdk.models import OrchestratorType, Type -from airbyte_cdk.sources import Source from source_google_analytics_data_api.config_migrations import MigrateCustomReports from source_google_analytics_data_api.source import SourceGoogleAnalyticsDataApi +from airbyte_cdk.models import OrchestratorType, Type +from airbyte_cdk.sources import Source + + # BASE ARGS CMD = "check" TEST_CONFIG_PATH = "unit_tests/test_migrations/test_config.json" diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_source.py b/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_source.py index e86201860e8b..d2d801e9bb2d 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_source.py @@ -5,14 +5,15 @@ from unittest.mock import MagicMock, patch import pytest -from airbyte_cdk.models import AirbyteConnectionStatus, FailureType, Status -from airbyte_cdk.sources.streams.http.http import HttpStatusErrorHandler -from airbyte_cdk.utils import AirbyteTracedException from source_google_analytics_data_api import SourceGoogleAnalyticsDataApi from source_google_analytics_data_api.api_quota import GoogleAnalyticsApiQuotaBase from source_google_analytics_data_api.source import GoogleAnalyticsDatApiErrorHandler, MetadataDescriptor from source_google_analytics_data_api.utils import NO_DIMENSIONS, NO_METRICS, NO_NAME, WRONG_CUSTOM_REPORT_CONFIG, WRONG_JSON_SYNTAX +from airbyte_cdk.models import AirbyteConnectionStatus, FailureType, Status +from airbyte_cdk.sources.streams.http.http import HttpStatusErrorHandler +from airbyte_cdk.utils import AirbyteTracedException + @pytest.mark.parametrize( "config_values, is_successful, message", @@ -111,32 +112,42 @@ def test_check_failure_throws_exception(requests_mock, config_gen, error_code): def test_exhausted_quota_recovers_after_two_retries(requests_mock, config_gen): """ - If the account runs out of quota the api will return a message asking us to back off for one hour. - We have set backoff time for this scenario to 30 minutes to check if quota is already recovered, if not - it will backoff again 30 minutes and quote should be reestablished by then. - Now, we don't want wait one hour to test out this retry behavior so we will fix time dividing by 600 the quota - recovery time and also the backoff time. + If the account runs out of quota the api will return a message asking us to back off for one hour. + We have set backoff time for this scenario to 30 minutes to check if quota is already recovered, if not + it will backoff again 30 minutes and quote should be reestablished by then. + Now, we don't want wait one hour to test out this retry behavior so we will fix time dividing by 600 the quota + recovery time and also the backoff time. """ requests_mock.register_uri( "POST", "https://oauth2.googleapis.com/token", json={"access_token": "access_token", "expires_in": 3600, "token_type": "Bearer"} ) - error_response = {"error": {"message":"Exhausted potentially thresholded requests quota. This quota will refresh in under an hour. To learn more, see"}} + error_response = { + "error": { + "message": "Exhausted potentially thresholded requests quota. This quota will refresh in under an hour. To learn more, see" + } + } requests_mock.register_uri( "GET", "https://analyticsdata.googleapis.com/v1beta/properties/UA-11111111/metadata", # first try we get 429 t=~0 - [{"json": error_response, "status_code": 429}, - # first retry we get 429 t=~1800 - {"json": error_response, "status_code": 429}, - # second retry quota is recovered, t=~3600 - {"json": { - "dimensions": [{"apiName": "date"}, {"apiName": "country"}, {"apiName": "language"}, {"apiName": "browser"}], - "metrics": [{"apiName": "totalUsers"}, {"apiName": "screenPageViews"}, {"apiName": "sessions"}], - }, "status_code": 200} - ] + [ + {"json": error_response, "status_code": 429}, + # first retry we get 429 t=~1800 + {"json": error_response, "status_code": 429}, + # second retry quota is recovered, t=~3600 + { + "json": { + "dimensions": [{"apiName": "date"}, {"apiName": "country"}, {"apiName": "language"}, {"apiName": "browser"}], + "metrics": [{"apiName": "totalUsers"}, {"apiName": "screenPageViews"}, {"apiName": "sessions"}], + }, + "status_code": 200, + }, + ], ) + def fix_time(time): - return int(time / 600 ) + return int(time / 600) + source = SourceGoogleAnalyticsDataApi() logger = MagicMock() max_time_fixed = fix_time(GoogleAnalyticsDatApiErrorHandler.QUOTA_RECOVERY_TIME) @@ -146,10 +157,18 @@ def fix_time(time): potentially_thresholded_requests_per_hour_mapping_fixed = { **potentially_thresholded_requests_per_hour_mapping, "backoff": fixed_threshold_backoff_time, - } + } with ( - patch.object(GoogleAnalyticsDatApiErrorHandler, 'QUOTA_RECOVERY_TIME', new=max_time_fixed), - patch.object(GoogleAnalyticsApiQuotaBase, 'quota_mapping', new={**GoogleAnalyticsApiQuotaBase.quota_mapping,"potentiallyThresholdedRequestsPerHour": potentially_thresholded_requests_per_hour_mapping_fixed})): + patch.object(GoogleAnalyticsDatApiErrorHandler, "QUOTA_RECOVERY_TIME", new=max_time_fixed), + patch.object( + GoogleAnalyticsApiQuotaBase, + "quota_mapping", + new={ + **GoogleAnalyticsApiQuotaBase.quota_mapping, + "potentiallyThresholdedRequestsPerHour": potentially_thresholded_requests_per_hour_mapping_fixed, + }, + ), + ): output = source.check(logger, config_gen(property_ids=["UA-11111111"])) assert output == AirbyteConnectionStatus(status=Status.SUCCEEDED, message=None) @@ -164,7 +183,7 @@ def test_check_failure(requests_mock, config_gen, error_code): ) source = SourceGoogleAnalyticsDataApi() logger = MagicMock() - with patch.object(HttpStatusErrorHandler, 'max_retries', new=0): + with patch.object(HttpStatusErrorHandler, "max_retries", new=0): airbyte_status = source.check(logger, config_gen(property_ids=["UA-11111111"])) assert airbyte_status.status == Status.FAILED assert airbyte_status.message == repr("Failed to get metadata, over quota, try later") diff --git a/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_streams.py index 3ab018bbe6d3..97cb79d8b64d 100644 --- a/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-google-analytics-data-api/unit_tests/test_streams.py @@ -10,11 +10,12 @@ from unittest.mock import MagicMock import pytest -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, FailureType, ResponseAction from freezegun import freeze_time from requests.models import Response from source_google_analytics_data_api.source import GoogleAnalyticsDataApiBaseStream, SourceGoogleAnalyticsDataApi +from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, FailureType, ResponseAction + from .utils import read_incremental @@ -85,10 +86,9 @@ def test_request_body_json(patch_base_class): {"name": "browser"}, ], "keepEmptyRows": True, - "dateRanges": [{ - "startDate": request_body_params["stream_slice"]["startDate"], - "endDate": request_body_params["stream_slice"]["endDate"] - }], + "dateRanges": [ + {"startDate": request_body_params["stream_slice"]["startDate"], "endDate": request_body_params["stream_slice"]["endDate"]} + ], "returnPropertyQuota": True, "offset": str(0), "limit": "100000", @@ -269,8 +269,8 @@ def test_should_retry(patch_base_class, http_status, response_action_expected, r if response_body: json_data = response_body response_mock._content = str.encode(json.dumps(json_data)) - response_mock.headers = {'Content-Type': 'application/json'} - response_mock.encoding = 'utf-8' + response_mock.headers = {"Content-Type": "application/json"} + response_mock.encoding = "utf-8" stream = GoogleAnalyticsDataApiBaseStream(authenticator=MagicMock(), config=patch_base_class["config"]) assert stream.get_error_handler().interpret_response(response_mock).response_action == response_action_expected @@ -312,6 +312,7 @@ def test_stream_slices(): {"startDate": "2022-12-30", "endDate": "2023-01-01"}, ] + @freeze_time("2023-01-01 00:00:00") def test_full_refresh(): """ @@ -319,9 +320,7 @@ def test_full_refresh(): """ config = {"date_ranges_start_date": datetime.date(2022, 12, 29), "window_in_days": 1, "dimensions": ["browser", "country", "language"]} stream = GoogleAnalyticsDataApiBaseStream(authenticator=None, config=config) - full_refresh_state = { - "__ab_full_refresh_state_message": True - } + full_refresh_state = {"__ab_full_refresh_state_message": True} slices = list(stream.stream_slices(sync_mode=None, stream_state=full_refresh_state)) assert slices == [ {"startDate": "2022-12-29", "endDate": "2022-12-29"}, @@ -423,47 +422,37 @@ def test_read_incremental(requests_mock): {"property_id": 123, "yearWeek": "202202", "totalUsers": 140, "startDate": "2022-01-10", "endDate": "2022-01-10"}, ] + @pytest.mark.parametrize( "config_dimensions, expected_state", [ pytest.param(["browser", "country", "language", "date"], {"date": "20240320"}, id="test_date_no_cursor_field_dimension"), pytest.param(["browser", "country", "language"], {}, id="test_date_cursor_field_dimension"), - ] + ], ) def test_get_updated_state(config_dimensions, expected_state): config = { - "credentials": { - "auth_type": "Service", - "credentials_json": "{ \"client_email\": \"a@gmail.com\", \"client_id\": \"1234\", \"client_secret\": \"5678\", \"private_key\": \"5678\"}" - }, - "date_ranges_start_date": "2023-04-01", - "window_in_days": 30, - "property_ids": ["123"], - "custom_reports_array": [ - { - "name": "pivot_report", - "dateRanges": [{"startDate": "2020-09-01", "endDate": "2020-09-15"}], - "dimensions": config_dimensions, - "metrics": ["sessions"], - "pivots": [ - { - "fieldNames": ["browser"], - "limit": 5 - }, - { - "fieldNames": ["country"], - "limit": 250 - }, + "credentials": { + "auth_type": "Service", + "credentials_json": '{ "client_email": "a@gmail.com", "client_id": "1234", "client_secret": "5678", "private_key": "5678"}', + }, + "date_ranges_start_date": "2023-04-01", + "window_in_days": 30, + "property_ids": ["123"], + "custom_reports_array": [ { - "fieldNames": ["language"], - "limit": 15 + "name": "pivot_report", + "dateRanges": [{"startDate": "2020-09-01", "endDate": "2020-09-15"}], + "dimensions": config_dimensions, + "metrics": ["sessions"], + "pivots": [ + {"fieldNames": ["browser"], "limit": 5}, + {"fieldNames": ["country"], "limit": 250}, + {"fieldNames": ["language"], "limit": 15}, + ], + "cohortSpec": {"enabled": "false"}, } - ], - "cohortSpec": { - "enabled": "false" - } - } - ] + ], } source = SourceGoogleAnalyticsDataApi() config = source._validate_and_transform(config, report_names=set()) diff --git a/airbyte-integrations/connectors/source-google-analytics-v4-service-account-only/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-google-analytics-v4-service-account-only/integration_tests/acceptance.py index d49b55882333..a9256a533972 100644 --- a/airbyte-integrations/connectors/source-google-analytics-v4-service-account-only/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-google-analytics-v4-service-account-only/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-google-analytics-v4-service-account-only/main.py b/airbyte-integrations/connectors/source-google-analytics-v4-service-account-only/main.py index 4d84f48a074b..d2371e025304 100644 --- a/airbyte-integrations/connectors/source-google-analytics-v4-service-account-only/main.py +++ b/airbyte-integrations/connectors/source-google-analytics-v4-service-account-only/main.py @@ -10,6 +10,7 @@ from airbyte_cdk.models import AirbyteMessage, ConnectorSpecification, FailureType, Type from airbyte_cdk.utils import AirbyteTracedException + if __name__ == "__main__": logger = init_logger("airbyte") init_uncaught_exception_handler(logger) diff --git a/airbyte-integrations/connectors/source-google-analytics-v4-service-account-only/metadata.yaml b/airbyte-integrations/connectors/source-google-analytics-v4-service-account-only/metadata.yaml index 2c28b4884dd6..bba9e96500ea 100644 --- a/airbyte-integrations/connectors/source-google-analytics-v4-service-account-only/metadata.yaml +++ b/airbyte-integrations/connectors/source-google-analytics-v4-service-account-only/metadata.yaml @@ -9,11 +9,11 @@ data: - analyticsdata.googleapis.com - analyticsreporting.googleapis.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 9e28a926-8f3c-4911-982d-a2e1c378b59c - dockerImageTag: 0.1.1 + dockerImageTag: 0.1.2 dockerRepository: airbyte/source-google-analytics-v4-service-account-only documentationUrl: https://docs.airbyte.com/integrations/sources/google-analytics-v4-service-account-only githubIssueLabel: source-google-analytics-v4-service-account-only diff --git a/airbyte-integrations/connectors/source-google-analytics-v4/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-google-analytics-v4/integration_tests/acceptance.py index d49b55882333..a9256a533972 100644 --- a/airbyte-integrations/connectors/source-google-analytics-v4/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-google-analytics-v4/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-google-analytics-v4/main.py b/airbyte-integrations/connectors/source-google-analytics-v4/main.py index 4d84f48a074b..d2371e025304 100644 --- a/airbyte-integrations/connectors/source-google-analytics-v4/main.py +++ b/airbyte-integrations/connectors/source-google-analytics-v4/main.py @@ -10,6 +10,7 @@ from airbyte_cdk.models import AirbyteMessage, ConnectorSpecification, FailureType, Type from airbyte_cdk.utils import AirbyteTracedException + if __name__ == "__main__": logger = init_logger("airbyte") init_uncaught_exception_handler(logger) diff --git a/airbyte-integrations/connectors/source-google-analytics-v4/metadata.yaml b/airbyte-integrations/connectors/source-google-analytics-v4/metadata.yaml index 3c782805bff1..bbe3b2db42d9 100644 --- a/airbyte-integrations/connectors/source-google-analytics-v4/metadata.yaml +++ b/airbyte-integrations/connectors/source-google-analytics-v4/metadata.yaml @@ -9,11 +9,11 @@ data: - analyticsdata.googleapis.com - analyticsreporting.googleapis.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: eff3616a-f9c3-11eb-9a03-0242ac130003 - dockerImageTag: 0.4.1 + dockerImageTag: 0.4.6 dockerRepository: airbyte/source-google-analytics-v4 documentationUrl: https://docs.airbyte.com/integrations/sources/google-analytics-v4 githubIssueLabel: source-google-analytics-v4 diff --git a/airbyte-integrations/connectors/source-google-analytics-v4/poetry.lock b/airbyte-integrations/connectors/source-google-analytics-v4/poetry.lock index 9d8da31a8441..c5ba87113ee4 100644 --- a/airbyte-integrations/connectors/source-google-analytics-v4/poetry.lock +++ b/airbyte-integrations/connectors/source-google-analytics-v4/poetry.lock @@ -39,13 +39,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] @@ -53,24 +53,24 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -85,19 +85,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -163,13 +163,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -253,116 +253,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -423,20 +410,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -500,13 +487,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -521,13 +508,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -535,7 +522,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -585,13 +571,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -681,22 +667,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -769,69 +758,86 @@ files = [ [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -934,54 +940,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -1276,33 +1282,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1369,13 +1375,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1400,81 +1406,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-google-analytics-v4/pyproject.toml b/airbyte-integrations/connectors/source-google-analytics-v4/pyproject.toml index 22ad38fbc137..ca27a856da4d 100644 --- a/airbyte-integrations/connectors/source-google-analytics-v4/pyproject.toml +++ b/airbyte-integrations/connectors/source-google-analytics-v4/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.4.1" +version = "0.4.6" name = "source-google-analytics-v4" description = "Source implementation for Google Analytics V4." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-google-analytics-v4/source_google_analytics_v4/custom_reports_validator.py b/airbyte-integrations/connectors/source-google-analytics-v4/source_google_analytics_v4/custom_reports_validator.py index 9e6d232996e6..6f0b224882f3 100644 --- a/airbyte-integrations/connectors/source-google-analytics-v4/source_google_analytics_v4/custom_reports_validator.py +++ b/airbyte-integrations/connectors/source-google-analytics-v4/source_google_analytics_v4/custom_reports_validator.py @@ -9,6 +9,7 @@ from pydantic import BaseModel, Field, ValidationError, validator from pydantic.class_validators import root_validator + ERROR_MSG_MISSING_SEGMENT_DIMENSION = "errors: `ga:segment` is required" @@ -99,7 +100,6 @@ def explain(self, errors: List[Dict]): @dataclass class CustomReportsValidator: - custom_reports: Union[List[Dict], Dict] = Field(default_factory=list) def __post_init__(self): @@ -108,7 +108,6 @@ def __post_init__(self): self.explainer: Explainer = Explainer() def validate(self): - # local import of airbyte_cdk dependencies from airbyte_cdk.models import FailureType from airbyte_cdk.utils.traced_exception import AirbyteTracedException diff --git a/airbyte-integrations/connectors/source-google-analytics-v4/source_google_analytics_v4/source.py b/airbyte-integrations/connectors/source-google-analytics-v4/source_google_analytics_v4/source.py index a71786d1a3a9..5bfa7b4cf297 100644 --- a/airbyte-integrations/connectors/source-google-analytics-v4/source_google_analytics_v4/source.py +++ b/airbyte-integrations/connectors/source-google-analytics-v4/source_google_analytics_v4/source.py @@ -14,6 +14,7 @@ import jwt import pendulum import requests + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream @@ -23,6 +24,7 @@ from .custom_reports_validator import CustomReportsValidator + DATA_IS_NOT_GOLDEN_MSG = "Google Analytics data is not golden. Future requests may return different data." RESULT_IS_SAMPLED_MSG = ( @@ -179,7 +181,6 @@ def raise_on_http_errors(self) -> bool: def request_body_json( self, stream_slice: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None, **kwargs: Any ) -> Optional[Mapping]: - metrics = [{"expression": metric} for metric in self.metrics] dimensions = [{"name": dimension} for dimension in self.dimensions] segments = [{"segmentId": segment} for segment in self.segments] diff --git a/airbyte-integrations/connectors/source-google-analytics-v4/unit_tests/conftest.py b/airbyte-integrations/connectors/source-google-analytics-v4/unit_tests/conftest.py index 35e9d17716d8..58cb13723d30 100644 --- a/airbyte-integrations/connectors/source-google-analytics-v4/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-google-analytics-v4/unit_tests/conftest.py @@ -9,6 +9,7 @@ import pendulum import pytest + from airbyte_cdk.models import ConfiguredAirbyteCatalog from airbyte_cdk.sources.streams.http.auth import NoAuth diff --git a/airbyte-integrations/connectors/source-google-analytics-v4/unit_tests/test_custom_reports_validator.py b/airbyte-integrations/connectors/source-google-analytics-v4/unit_tests/test_custom_reports_validator.py index 4becd6c2d323..023e077dfd44 100644 --- a/airbyte-integrations/connectors/source-google-analytics-v4/unit_tests/test_custom_reports_validator.py +++ b/airbyte-integrations/connectors/source-google-analytics-v4/unit_tests/test_custom_reports_validator.py @@ -3,9 +3,10 @@ # import pytest -from airbyte_cdk.utils.traced_exception import AirbyteTracedException from source_google_analytics_v4.custom_reports_validator import CustomReportsValidator +from airbyte_cdk.utils.traced_exception import AirbyteTracedException + @pytest.mark.parametrize( "custom_reports, expected", diff --git a/airbyte-integrations/connectors/source-google-analytics-v4/unit_tests/unit_test.py b/airbyte-integrations/connectors/source-google-analytics-v4/unit_tests/unit_test.py index a4a9f276ba14..bd6cdc1ac209 100644 --- a/airbyte-integrations/connectors/source-google-analytics-v4/unit_tests/unit_test.py +++ b/airbyte-integrations/connectors/source-google-analytics-v4/unit_tests/unit_test.py @@ -8,7 +8,6 @@ import pendulum import pytest -from airbyte_cdk.models import SyncMode, Type from freezegun import freeze_time from source_google_analytics_v4.source import ( DATA_IS_NOT_GOLDEN_MSG, @@ -19,6 +18,9 @@ SourceGoogleAnalyticsV4, ) +from airbyte_cdk.models import SyncMode, Type + + expected_metrics_dimensions_type_map = ( {"ga:users": "INTEGER", "ga:newUsers": "INTEGER"}, {"ga:date": "STRING", "ga:country": "STRING"}, diff --git a/airbyte-integrations/connectors/source-google-classroom/README.md b/airbyte-integrations/connectors/source-google-classroom/README.md new file mode 100644 index 000000000000..3396aeab57fd --- /dev/null +++ b/airbyte-integrations/connectors/source-google-classroom/README.md @@ -0,0 +1,33 @@ +# Google Classroom +This directory contains the manifest-only connector for `source-google-classroom`. + +Google Classroom connector enables seamless data integration between Google Classroom and various destinations. This connector facilitates the synchronization of course information, rosters, assignments empowering educators to automate reporting and streamline classroom data management efficiently. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-google-classroom:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-google-classroom build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-google-classroom test +``` + diff --git a/airbyte-integrations/connectors/source-google-classroom/acceptance-test-config.yml b/airbyte-integrations/connectors/source-google-classroom/acceptance-test-config.yml new file mode 100644 index 000000000000..edc7c43965f8 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-classroom/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-google-classroom:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-google-classroom/icon.svg b/airbyte-integrations/connectors/source-google-classroom/icon.svg new file mode 100644 index 000000000000..f185e0bca46c --- /dev/null +++ b/airbyte-integrations/connectors/source-google-classroom/icon.svg @@ -0,0 +1,275 @@ + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-google-classroom/manifest.yaml b/airbyte-integrations/connectors/source-google-classroom/manifest.yaml new file mode 100644 index 000000000000..f5dbd274e37e --- /dev/null +++ b/airbyte-integrations/connectors/source-google-classroom/manifest.yaml @@ -0,0 +1,722 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + Google Classroom connector enables seamless data integration between Google + Classroom and various destinations. This connector facilitates the + synchronization of course information, rosters, assignments empowering + educators to automate reporting and streamline classroom data management + efficiently. + +check: + type: CheckStream + stream_names: + - courses + +definitions: + streams: + courses: + type: DeclarativeStream + name: courses + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v1/courses + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - courses + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('nextPageToken', '') }}" + stop_condition: >- + {{ response.get('nextPageToken') is none or + response.get('nextPageToken') == '' }} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/courses" + teachers: + type: DeclarativeStream + name: teachers + primary_key: + - userId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v1/courses/{{ stream_partition.course }}/teachers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - teachers + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('nextPageToken', '') }}" + stop_condition: >- + {{ response.get('nextPageToken') is none or + response.get('nextPageToken') == '' }} + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: course + stream: + $ref: "#/definitions/streams/courses" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/teachers" + students: + type: DeclarativeStream + name: students + primary_key: + - userId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v1/courses/{{ stream_partition.course }}/students + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - students + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('nextPageToken', '') }}" + stop_condition: >- + {{ response.get('nextPageToken') is none or + response.get('nextPageToken') == '' }} + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: course + stream: + $ref: "#/definitions/streams/courses" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/students" + announcements: + type: DeclarativeStream + name: announcements + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v1/courses/{{ stream_partition.course }}/announcements + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - announcements + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('nextPageToken', '') }}" + stop_condition: >- + {{ response.get('nextPageToken') is not defined or + response.get('nextPageToken') == '' }} + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: course + stream: + $ref: "#/definitions/streams/courses" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/announcements" + coursework: + type: DeclarativeStream + name: coursework + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v1/courses/{{ stream_partition.course }}/courseWork + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - courseWork + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('nextPageToken', '') }}" + stop_condition: >- + {{ response.get('nextPageToken') is none or + response.get('nextPageToken') == '' }} + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: course + stream: + $ref: "#/definitions/streams/courses" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/coursework" + studentsubmissions: + type: DeclarativeStream + name: studentsubmissions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /v1/courses/{{ stream_partition.course }}/courseWork/{{ + stream_partition.coursework }}/studentSubmissions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - studentSubmissions + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('nextPageToken', '') }}" + stop_condition: "{{ response.get('nextPageToken') is none }}" + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: course + stream: + $ref: "#/definitions/streams/courses" + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: coursework + stream: + $ref: "#/definitions/streams/coursework" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/studentsubmissions" + base_requester: + type: HttpRequester + url_base: https://classroom.googleapis.com + authenticator: + type: OAuthAuthenticator + client_id: "{{ config[\"client_id\"] }}" + grant_type: refresh_token + client_secret: "{{ config[\"client_secret\"] }}" + expires_in_name: expires_in + access_token_name: access_token + refresh_request_body: {} + refresh_token: "{{ config[\"client_refresh_token\"] }}" + token_refresh_endpoint: https://oauth2.googleapis.com/token + +streams: + - $ref: "#/definitions/streams/courses" + - $ref: "#/definitions/streams/teachers" + - $ref: "#/definitions/streams/students" + - $ref: "#/definitions/streams/announcements" + - $ref: "#/definitions/streams/coursework" + - $ref: "#/definitions/streams/studentsubmissions" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - client_id + - client_secret + - client_refresh_token + properties: + client_id: + type: string + name: client_id + title: OAuth Client ID + airbyte_secret: true + order: 0 + client_secret: + type: string + name: client_secret + title: OAuth Client Secret + airbyte_secret: true + order: 1 + client_refresh_token: + type: string + title: Refresh token + airbyte_secret: true + order: 2 + additionalProperties: true + +metadata: + autoImportSchema: + courses: true + teachers: true + students: true + announcements: true + coursework: true + studentsubmissions: true + testedStreams: + courses: + streamHash: b35f48d14765b3758d2cb63261ffcd44304ca08a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + teachers: + streamHash: 8d5dd7e1d0f997f5cdb21e4e6595a029404c5af9 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + students: + streamHash: 7521191448dff583fc642559f70cd5279a7b729d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + announcements: + streamHash: f98439e1e3ba08042beb284dd8335f48f8905b7e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + coursework: + streamHash: c951fbca5dec5bb25dfa0cdf9080beefc3ceb361 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + studentsubmissions: + streamHash: 1faa94727cbb66ac7412970a80546beafc3013eb + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://developers.google.com/classroom/reference/rest + +schemas: + courses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + alternateLink: + type: + - string + - "null" + courseGroupEmail: + type: + - string + - "null" + courseState: + type: + - string + - "null" + creationTime: + type: + - string + - "null" + enrollmentCode: + type: + - string + - "null" + gradebookSettings: + type: + - object + - "null" + properties: + calculationType: + type: + - string + - "null" + displaySetting: + type: + - string + - "null" + guardiansEnabled: + type: + - boolean + - "null" + id: + type: string + name: + type: + - string + - "null" + ownerId: + type: + - string + - "null" + teacherFolder: + type: + - object + - "null" + properties: + alternateLink: + type: + - string + - "null" + id: + type: + - string + - "null" + title: + type: + - string + - "null" + teacherGroupEmail: + type: + - string + - "null" + updateTime: + type: + - string + - "null" + required: + - id + teachers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + courseId: + type: + - string + - "null" + profile: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - object + - "null" + properties: + familyName: + type: + - string + - "null" + fullName: + type: + - string + - "null" + givenName: + type: + - string + - "null" + permissions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + permission: + type: + - string + - "null" + userId: + type: string + required: + - userId + students: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + courseId: + type: + - string + - "null" + profile: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - object + - "null" + properties: + familyName: + type: + - string + - "null" + fullName: + type: + - string + - "null" + givenName: + type: + - string + - "null" + permissions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + permission: + type: + - string + - "null" + userId: + type: string + required: + - userId + announcements: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + alternateLink: + type: + - string + - "null" + assigneeMode: + type: + - string + - "null" + courseId: + type: + - string + - "null" + creationTime: + type: + - string + - "null" + creatorUserId: + type: + - string + - "null" + id: + type: string + state: + type: + - string + - "null" + text: + type: + - string + - "null" + updateTime: + type: + - string + - "null" + required: + - id + coursework: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + alternateLink: + type: + - string + - "null" + assigneeMode: + type: + - string + - "null" + courseId: + type: + - string + - "null" + creationTime: + type: + - string + - "null" + creatorUserId: + type: + - string + - "null" + id: + type: string + maxPoints: + type: + - number + - "null" + state: + type: + - string + - "null" + submissionModificationMode: + type: + - string + - "null" + title: + type: + - string + - "null" + updateTime: + type: + - string + - "null" + workType: + type: + - string + - "null" + required: + - id + studentsubmissions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + alternateLink: + type: + - string + - "null" + courseId: + type: + - string + - "null" + courseWorkId: + type: + - string + - "null" + courseWorkType: + type: + - string + - "null" + creationTime: + type: + - string + - "null" + id: + type: string + shortAnswerSubmission: + type: + - object + - "null" + properties: + answer: + type: + - string + - "null" + state: + type: + - string + - "null" + submissionHistory: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + stateHistory: + type: + - object + - "null" + properties: + actorUserId: + type: + - string + - "null" + state: + type: + - string + - "null" + stateTimestamp: + type: + - string + - "null" + updateTime: + type: + - string + - "null" + userId: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-google-classroom/metadata.yaml b/airbyte-integrations/connectors/source-google-classroom/metadata.yaml new file mode 100644 index 000000000000..7926157a3e71 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-classroom/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "classroom.googleapis.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-google-classroom + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 2c3aa088-396d-4ee6-8096-971ecd11598c + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-google-classroom + githubIssueLabel: source-google-classroom + icon: icon.svg + license: MIT + name: Google Classroom + releaseDate: 2024-10-26 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/google-classroom + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-google-directory/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-google-directory/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-google-directory/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-google-directory/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-google-directory/main.py b/airbyte-integrations/connectors/source-google-directory/main.py index fa60e31af90e..62faf30d2f24 100644 --- a/airbyte-integrations/connectors/source-google-directory/main.py +++ b/airbyte-integrations/connectors/source-google-directory/main.py @@ -4,5 +4,6 @@ from source_google_directory.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-google-directory/metadata.yaml b/airbyte-integrations/connectors/source-google-directory/metadata.yaml index 2f32f968db07..08280858f438 100644 --- a/airbyte-integrations/connectors/source-google-directory/metadata.yaml +++ b/airbyte-integrations/connectors/source-google-directory/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: d19ae824-e289-4b14-995a-0632eb46d246 - dockerImageTag: 0.2.23 + dockerImageTag: 0.2.28 dockerRepository: airbyte/source-google-directory githubIssueLabel: source-google-directory icon: googledirectory.svg @@ -14,7 +14,7 @@ data: packageName: airbyte-source-google-directory registryOverrides: cloud: - dockerImageTag: 0.2.23 + dockerImageTag: 0.2.28 enabled: true oss: enabled: true @@ -46,5 +46,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-google-directory/poetry.lock b/airbyte-integrations/connectors/source-google-directory/poetry.lock index 64b4f9c7a1c3..6f1ba20f3198 100644 --- a/airbyte-integrations/connectors/source-google-directory/poetry.lock +++ b/airbyte-integrations/connectors/source-google-directory/poetry.lock @@ -62,19 +62,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -140,127 +140,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -276,20 +263,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -369,13 +356,13 @@ uritemplate = ">=3.0.0,<4dev" [[package]] name = "google-auth" -version = "2.35.0" +version = "2.37.0" description = "Google Authentication Library" optional = false python-versions = ">=3.7" files = [ - {file = "google_auth-2.35.0-py2.py3-none-any.whl", hash = "sha256:25df55f327ef021de8be50bad0dfd4a916ad0de96da86cd05661c9297723ad3f"}, - {file = "google_auth-2.35.0.tar.gz", hash = "sha256:f4c64ed4e01e8e8b646ef34c018f8bf3338df0c8e37d8b3bba40e7f574a3278a"}, + {file = "google_auth-2.37.0-py2.py3-none-any.whl", hash = "sha256:42664f18290a6be591be5329a96fe30184be1a1badb7292a7f686a9659de9ca0"}, + {file = "google_auth-2.37.0.tar.gz", hash = "sha256:0054623abf1f9c83492c63d3f47e77f0a544caa3d40b2d98e099a611c2dd5d00"}, ] [package.dependencies] @@ -386,6 +373,7 @@ rsa = ">=3.1.4,<5" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0.dev0)", "requests (>=2.20.0,<3.0.0.dev0)"] enterprise-cert = ["cryptography", "pyopenssl"] +pyjwt = ["cryptography (>=38.0.3)", "pyjwt (>=2.0)"] pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0.dev0)"] @@ -426,13 +414,13 @@ tool = ["click"] [[package]] name = "googleapis-common-protos" -version = "1.65.0" +version = "1.66.0" description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" files = [ - {file = "googleapis_common_protos-1.65.0-py2.py3-none-any.whl", hash = "sha256:2972e6c496f435b92590fd54045060867f3fe9be2c82ab148fc8885035479a63"}, - {file = "googleapis_common_protos-1.65.0.tar.gz", hash = "sha256:334a29d07cddc3aa01dee4988f9afd9b2916ee2ff49d6b757155dc0d197852c0"}, + {file = "googleapis_common_protos-1.66.0-py2.py3-none-any.whl", hash = "sha256:d7abcd75fabb2e0ec9f74466401f6c119a0b498e27370e9be4c94cb7e382b8ed"}, + {file = "googleapis_common_protos-1.66.0.tar.gz", hash = "sha256:c3e7b33d15fdca5374cc0a7346dd92ffa847425cc4ea941d970f13680052ec8c"}, ] [package.dependencies] @@ -496,13 +484,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -631,13 +619,13 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -774,54 +762,54 @@ pyasn1 = ">=0.4.6,<0.7.0" [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -833,13 +821,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyparsing" -version = "3.2.0" +version = "3.2.1" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false python-versions = ">=3.9" files = [ - {file = "pyparsing-3.2.0-py3-none-any.whl", hash = "sha256:93d9577b88da0bbea8cc8334ee8b918ed014968fd2ec383e868fb8afb1ccef84"}, - {file = "pyparsing-3.2.0.tar.gz", hash = "sha256:cbf74e27246d595d9a74b186b810f6fbb86726dbf3b9532efb343f6d7294fe9c"}, + {file = "pyparsing-3.2.1-py3-none-any.whl", hash = "sha256:506ff4f4386c4cec0590ec19e6302d3aedb992fdc02c761e90416f158dacf8e1"}, + {file = "pyparsing-3.2.1.tar.gz", hash = "sha256:61980854fd66de3a90028d679a954d5f2623e83144b5afe5ee86f43d762e5f0a"}, ] [package.extras] @@ -1131,33 +1119,33 @@ pyasn1 = ">=0.1.3" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1209,13 +1197,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1240,81 +1228,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-google-directory/pyproject.toml b/airbyte-integrations/connectors/source-google-directory/pyproject.toml index cd934463e958..334627b0a700 100644 --- a/airbyte-integrations/connectors/source-google-directory/pyproject.toml +++ b/airbyte-integrations/connectors/source-google-directory/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.2.23" +version = "0.2.28" name = "source-google-directory" description = "Source implementation for Google Directory." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-google-directory/source_google_directory/api.py b/airbyte-integrations/connectors/source-google-directory/source_google_directory/api.py index 6a74d4cd0d75..9151f37a94bc 100644 --- a/airbyte-integrations/connectors/source-google-directory/source_google_directory/api.py +++ b/airbyte-integrations/connectors/source-google-directory/source_google_directory/api.py @@ -17,6 +17,7 @@ from .utils import rate_limit_handling + SCOPES = ["https://www.googleapis.com/auth/admin.directory.user.readonly", "https://www.googleapis.com/auth/admin.directory.group.readonly"] diff --git a/airbyte-integrations/connectors/source-google-drive/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-google-drive/integration_tests/acceptance.py index 6b0c294530cd..abe3d6fde3ed 100644 --- a/airbyte-integrations/connectors/source-google-drive/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-google-drive/integration_tests/acceptance.py @@ -7,6 +7,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-google-drive/main.py b/airbyte-integrations/connectors/source-google-drive/main.py index 606e4f7641e8..53fba38d7846 100644 --- a/airbyte-integrations/connectors/source-google-drive/main.py +++ b/airbyte-integrations/connectors/source-google-drive/main.py @@ -4,5 +4,6 @@ from source_google_drive.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-google-drive/source_google_drive/spec.py b/airbyte-integrations/connectors/source-google-drive/source_google_drive/spec.py index 95c7572471c6..fdecc52aab91 100644 --- a/airbyte-integrations/connectors/source-google-drive/source_google_drive/spec.py +++ b/airbyte-integrations/connectors/source-google-drive/source_google_drive/spec.py @@ -6,9 +6,10 @@ from typing import Any, Dict, Literal, Union import dpath.util +from pydantic import BaseModel, Field + from airbyte_cdk import OneOfOptionConfig from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec -from pydantic import BaseModel, Field class OAuthCredentials(BaseModel): diff --git a/airbyte-integrations/connectors/source-google-drive/source_google_drive/stream_reader.py b/airbyte-integrations/connectors/source-google-drive/source_google_drive/stream_reader.py index ac73c84b5a19..3cf03d175909 100644 --- a/airbyte-integrations/connectors/source-google-drive/source_google_drive/stream_reader.py +++ b/airbyte-integrations/connectors/source-google-drive/source_google_drive/stream_reader.py @@ -10,16 +10,18 @@ from io import IOBase from typing import Iterable, List, Optional, Set -from airbyte_cdk import AirbyteTracedException, FailureType -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode -from airbyte_cdk.sources.file_based.remote_file import RemoteFile from google.oauth2 import credentials, service_account from googleapiclient.discovery import build from googleapiclient.http import MediaIoBaseDownload + +from airbyte_cdk import AirbyteTracedException, FailureType +from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode +from airbyte_cdk.sources.file_based.remote_file import RemoteFile from source_google_drive.utils import get_folder_id from .spec import SourceGoogleDriveSpec + FOLDER_MIME_TYPE = "application/vnd.google-apps.folder" GOOGLE_DOC_MIME_TYPE = "application/vnd.google-apps.document" EXPORTABLE_DOCUMENTS_MIME_TYPES = [ diff --git a/airbyte-integrations/connectors/source-google-drive/unit_tests/test_reader.py b/airbyte-integrations/connectors/source-google-drive/unit_tests/test_reader.py index a98f2436cae4..66fce445ada7 100644 --- a/airbyte-integrations/connectors/source-google-drive/unit_tests/test_reader.py +++ b/airbyte-integrations/connectors/source-google-drive/unit_tests/test_reader.py @@ -7,11 +7,12 @@ from unittest.mock import MagicMock, call, patch import pytest +from source_google_drive.spec import ServiceAccountCredentials, SourceGoogleDriveSpec +from source_google_drive.stream_reader import GoogleDriveRemoteFile, SourceGoogleDriveStreamReader + from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig from airbyte_cdk.sources.file_based.config.jsonl_format import JsonlFormat from airbyte_cdk.sources.file_based.file_based_stream_reader import FileReadMode -from source_google_drive.spec import ServiceAccountCredentials, SourceGoogleDriveSpec -from source_google_drive.stream_reader import GoogleDriveRemoteFile, SourceGoogleDriveStreamReader def create_reader( @@ -19,7 +20,7 @@ def create_reader( folder_url="https://drive.google.com/drive/folders/1Z2Q3", streams=[FileBasedStreamConfig(name="test", format=JsonlFormat())], credentials=ServiceAccountCredentials(auth_type="Service", service_account_info='{"test": "abc"}'), - ) + ), ): reader = SourceGoogleDriveStreamReader() reader.config = config diff --git a/airbyte-integrations/connectors/source-google-drive/unit_tests/test_utils.py b/airbyte-integrations/connectors/source-google-drive/unit_tests/test_utils.py index 8dcb7e52e223..2740a3d88ee5 100644 --- a/airbyte-integrations/connectors/source-google-drive/unit_tests/test_utils.py +++ b/airbyte-integrations/connectors/source-google-drive/unit_tests/test_utils.py @@ -18,11 +18,11 @@ ("https://drive.google.com/drive/my-drive", None, True), ("http://drive.google.com/drive/u/0/folders/1q2w3e4r5t6y7u8i9o0p/", None, True), ("https://drive.google.com/", None, True), - ] + ], ) def test_get_folder_id(input, output, raises): if raises: with pytest.raises(ValueError): get_folder_id(input) else: - assert get_folder_id(input) == output \ No newline at end of file + assert get_folder_id(input) == output diff --git a/airbyte-integrations/connectors/source-google-forms/README.md b/airbyte-integrations/connectors/source-google-forms/README.md new file mode 100644 index 000000000000..2a3e4c37f2e1 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-forms/README.md @@ -0,0 +1,33 @@ +# Google Forms +This directory contains the manifest-only connector for `source-google-forms`. + +Google Forms is a free online tool from Google that allows users to create custom surveys, quizzes, and forms. It enables easy collection and organization of data by automating responses into a connected Google Sheets spreadsheet. With Google Forms, you can design forms with various question types, share them via email or links, and track responses in real-time, making it ideal for feedback collection, event registration, or educational assessments. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-google-forms:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-google-forms build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-google-forms test +``` + diff --git a/airbyte-integrations/connectors/source-google-forms/acceptance-test-config.yml b/airbyte-integrations/connectors/source-google-forms/acceptance-test-config.yml new file mode 100644 index 000000000000..3f758e48aa08 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-forms/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-google-forms:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-google-forms/icon.svg b/airbyte-integrations/connectors/source-google-forms/icon.svg new file mode 100644 index 000000000000..79f2eb208e89 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-forms/icon.svg @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-google-forms/manifest.yaml b/airbyte-integrations/connectors/source-google-forms/manifest.yaml new file mode 100644 index 000000000000..fe48ce94753e --- /dev/null +++ b/airbyte-integrations/connectors/source-google-forms/manifest.yaml @@ -0,0 +1,519 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Google Forms is a free online tool from Google that allows users to create + custom surveys, quizzes, and forms. It enables easy collection and + organization of data by automating responses into a connected Google Sheets + spreadsheet. With Google Forms, you can design forms with various question + types, share them via email or links, and track responses in real-time, making + it ideal for feedback collection, event registration, or educational + assessments. + +check: + type: CheckStream + stream_names: + - forms + +definitions: + streams: + forms: + type: DeclarativeStream + name: forms + primary_key: + - formId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: forms/{{ stream_partition.formid }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: ListPartitionRouter + values: "{{ config['form_id'] }}" + cursor_field: formid + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/forms" + form_responses: + type: DeclarativeStream + name: form_responses + primary_key: + - responseId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: forms/{{ stream_partition.formid }}/responses + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - responses + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('nextPageToken', '') }}" + stop_condition: "{{ response.get('nextPageToken') is none }}" + partition_router: + type: ListPartitionRouter + values: "{{ config['form_id'] }}" + cursor_field: formid + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/form_responses" + base_requester: + type: HttpRequester + url_base: https://forms.googleapis.com/v1/ + authenticator: + type: OAuthAuthenticator + client_id: "{{ config[\"client_id\"] }}" + grant_type: refresh_token + client_secret: "{{ config[\"client_secret\"] }}" + refresh_token: "{{ config[\"client_refresh_token\"] }}" + refresh_request_body: {} + token_refresh_endpoint: https://oauth2.googleapis.com/token + +streams: + - $ref: "#/definitions/streams/forms" + - $ref: "#/definitions/streams/form_responses" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - client_id + - client_secret + - client_refresh_token + - form_id + properties: + client_id: + type: string + order: 0 + title: Client ID + airbyte_secret: true + client_secret: + type: string + order: 1 + title: Client secret + airbyte_secret: true + client_refresh_token: + type: string + order: 2 + title: Refresh token + airbyte_secret: true + form_id: + type: array + order: 3 + title: Form IDs + additionalProperties: true + +metadata: + autoImportSchema: + forms: true + form_responses: false + testedStreams: + forms: + streamHash: 032a8a1fc074ec05e71e72cf999b1e5a914c49a4 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + form_responses: + streamHash: 690303fa58627d1353bbfc4d0f7ad69f7911e5cf + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://developers.google.com/forms/api/reference/rest/?apix=true + +schemas: + forms: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + formId: + type: string + info: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + documentTitle: + type: + - string + - "null" + title: + type: + - string + - "null" + items: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + itemId: + type: + - string + - "null" + questionItem: + type: + - object + - "null" + properties: + question: + type: + - object + - "null" + properties: + choiceQuestion: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + options: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + questionId: + type: + - string + - "null" + required: + type: + - boolean + - "null" + textQuestion: + type: + - object + - "null" + properties: + paragraph: + type: + - boolean + - "null" + title: + type: + - string + - "null" + responderUri: + type: + - string + - "null" + revisionId: + type: + - string + - "null" + settings: + type: + - object + - "null" + required: + - formId + form_responses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + answers: + type: + - object + - "null" + properties: + 0027c4cd: + type: + - object + - "null" + properties: + questionId: + type: + - string + - "null" + textAnswers: + type: + - object + - "null" + properties: + answers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + 137cf025: + type: + - object + - "null" + properties: + questionId: + type: + - string + - "null" + textAnswers: + type: + - object + - "null" + properties: + answers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + 1cef0da8: + type: + - object + - "null" + properties: + questionId: + type: + - string + - "null" + textAnswers: + type: + - object + - "null" + properties: + answers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + 3447475e: + type: + - object + - "null" + properties: + questionId: + type: + - string + - "null" + textAnswers: + type: + - object + - "null" + properties: + answers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + 346c97bf: + type: + - object + - "null" + properties: + questionId: + type: + - string + - "null" + textAnswers: + type: + - object + - "null" + properties: + answers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + 54ea9b24: + type: + - object + - "null" + properties: + questionId: + type: + - string + - "null" + textAnswers: + type: + - object + - "null" + properties: + answers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + 594bba3a: + type: + - object + - "null" + properties: + questionId: + type: + - string + - "null" + textAnswers: + type: + - object + - "null" + properties: + answers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + 5ede6594: + type: + - object + - "null" + properties: + questionId: + type: + - string + - "null" + textAnswers: + type: + - object + - "null" + properties: + answers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + 651957f9: + type: + - object + - "null" + properties: + questionId: + type: + - string + - "null" + textAnswers: + type: + - object + - "null" + properties: + answers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + createTime: + type: + - string + - "null" + lastSubmittedTime: + type: + - string + - "null" + responseId: + type: string + required: + - responseId diff --git a/airbyte-integrations/connectors/source-google-forms/metadata.yaml b/airbyte-integrations/connectors/source-google-forms/metadata.yaml new file mode 100644 index 000000000000..aa97e222262f --- /dev/null +++ b/airbyte-integrations/connectors/source-google-forms/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "forms.googleapis.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-google-forms + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 4100f944-1bef-4a73-a1c6-6042e3137749 + dockerImageTag: 0.0.4 + dockerRepository: airbyte/source-google-forms + githubIssueLabel: source-google-forms + icon: icon.svg + license: MIT + name: Google Forms + releaseDate: 2024-11-09 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/google-forms + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-google-pagespeed-insights/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-google-pagespeed-insights/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-google-pagespeed-insights/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-google-pagespeed-insights/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-google-pagespeed-insights/metadata.yaml b/airbyte-integrations/connectors/source-google-pagespeed-insights/metadata.yaml index 72b3baae4ea6..7cccd47009c4 100644 --- a/airbyte-integrations/connectors/source-google-pagespeed-insights/metadata.yaml +++ b/airbyte-integrations/connectors/source-google-pagespeed-insights/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.4.3@sha256:8937b693c7e01087f6e86e683826ac20f160f7952b8f0a13cbf4f9bfdd7af570 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 1e9086ab-ddac-4c1d-aafd-ba43ff575fe4 - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-google-pagespeed-insights documentationUrl: https://docs.airbyte.com/integrations/sources/google-pagespeed-insights githubIssueLabel: source-google-pagespeed-insights diff --git a/airbyte-integrations/connectors/source-google-search-console/acceptance-test-config.yml b/airbyte-integrations/connectors/source-google-search-console/acceptance-test-config.yml index 4bc8f213b833..d73c05c4f894 100755 --- a/airbyte-integrations/connectors/source-google-search-console/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-google-search-console/acceptance-test-config.yml @@ -14,9 +14,8 @@ acceptance_tests: tests: - config_path: "secrets/config.json" status: "succeed" - # TODO: uncomment testing on service_account_config.json when we update creds - # - config_path: "secrets/service_account_config.json" - # status: "succeed" + - config_path: "secrets/service_account_config.json" + status: "succeed" - config_path: "integration_tests/invalid_config.json" status: "failed" discovery: diff --git a/airbyte-integrations/connectors/source-google-search-console/credentials/get_authentication_url.py b/airbyte-integrations/connectors/source-google-search-console/credentials/get_authentication_url.py index 944377055e87..20d8f3b0132a 100755 --- a/airbyte-integrations/connectors/source-google-search-console/credentials/get_authentication_url.py +++ b/airbyte-integrations/connectors/source-google-search-console/credentials/get_authentication_url.py @@ -4,6 +4,7 @@ import json + # Check https://developers.google.com/webmaster-tools/search-console-api-original/v3/ for all available scopes OAUTH_SCOPE = "https://www.googleapis.com/auth/webmasters.readonly" diff --git a/airbyte-integrations/connectors/source-google-search-console/credentials/get_refresh_token.py b/airbyte-integrations/connectors/source-google-search-console/credentials/get_refresh_token.py index 675661179530..6ceb6ae845a5 100755 --- a/airbyte-integrations/connectors/source-google-search-console/credentials/get_refresh_token.py +++ b/airbyte-integrations/connectors/source-google-search-console/credentials/get_refresh_token.py @@ -8,6 +8,7 @@ import requests + GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token" with open("credentials.json", "r") as f: diff --git a/airbyte-integrations/connectors/source-google-search-console/credentials/setup.py b/airbyte-integrations/connectors/source-google-search-console/credentials/setup.py index 4e39115533b4..906add1a3e0e 100755 --- a/airbyte-integrations/connectors/source-google-search-console/credentials/setup.py +++ b/airbyte-integrations/connectors/source-google-search-console/credentials/setup.py @@ -5,6 +5,7 @@ from setuptools import find_packages, setup + MAIN_REQUIREMENTS = [ "requests", ] diff --git a/airbyte-integrations/connectors/source-google-search-console/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-google-search-console/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100755 --- a/airbyte-integrations/connectors/source-google-search-console/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-google-search-console/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-google-search-console/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-google-search-console/integration_tests/expected_records.jsonl index 24899c787314..d6b276530c0a 100644 --- a/airbyte-integrations/connectors/source-google-search-console/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-google-search-console/integration_tests/expected_records.jsonl @@ -1,29 +1,29 @@ {"stream": "sites", "data": {"siteUrl": "sc-domain:airbyte.io", "permissionLevel": "siteFullUser"}, "emitted_at": 1709913944973} {"stream": "sitemaps", "data": {"path": "https://discuss.airbyte.io/sitemap.xml", "lastSubmitted": "2024-02-10T17:31:13.470Z", "isPending": false, "isSitemapsIndex": true, "lastDownloaded": "2024-03-08T04:51:33.425Z", "warnings": "0", "errors": "0", "contents": [{"type": "web", "submitted": "1778", "indexed": "0"}]}, "emitted_at": 1709913945327} {"stream": "sitemaps", "data": {"path": "https://airbyte.io/sitemap.xml", "lastSubmitted": "2021-09-10T23:02:22.258Z", "isPending": false, "isSitemapsIndex": false, "type": "sitemap", "lastDownloaded": "2024-03-08T02:25:38.869Z", "warnings": "6", "errors": "0", "contents": [{"type": "web", "submitted": "30333", "indexed": "0"}]}, "emitted_at": 1709913945328} -{"stream": "search_analytics_by_date", "data": {"clicks": 120, "impressions": 5267, "ctr": 0.022783368141256883, "position": 35.45490791722043, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-01"}, "emitted_at": 1709913946169} -{"stream": "search_analytics_by_date", "data": {"clicks": 439, "impressions": 10076, "ctr": 0.043568876538308855, "position": 24.655617308455735, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-02"}, "emitted_at": 1709913946170} -{"stream": "search_analytics_by_country", "data": {"clicks": 98, "impressions": 2544, "ctr": 0.03852201257861635, "position": 25.294025157232703, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-03", "country": "usa"}, "emitted_at": 1709913947363} -{"stream": "search_analytics_by_country", "data": {"clicks": 84, "impressions": 2389, "ctr": 0.03516115529510255, "position": 28.137295939723735, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-02", "country": "usa"}, "emitted_at": 1709913947364} -{"stream": "search_analytics_by_device", "data": {"clicks": 453, "impressions": 10313, "ctr": 0.043925143023368564, "position": 22.476873848540677, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-03", "device": "DESKTOP"}, "emitted_at": 1709913947994} -{"stream": "search_analytics_by_device", "data": {"clicks": 415, "impressions": 9270, "ctr": 0.0447680690399137, "position": 23.817044228694716, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-02", "device": "DESKTOP"}, "emitted_at": 1709913947996} -{"stream": "search_analytics_by_page", "data": {"clicks": 14, "impressions": 178, "ctr": 0.07865168539325842, "position": 7.162921348314606, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-02", "page": "https://discuss.airbyte.io/t/nil-pointer-error-when-deploying-helm-chart/601"}, "emitted_at": 1709913949344} -{"stream": "search_analytics_by_page", "data": {"clicks": 14, "impressions": 59, "ctr": 0.23728813559322035, "position": 7.5423728813559325, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-03", "page": "https://discuss.airbyte.io/t/using-a-private-git-repo-for-transformations-the-selection-criterion-does-not-match-any-nodes/4170"}, "emitted_at": 1709913949345} -{"stream": "search_analytics_by_query", "data": {"clicks": 5, "impressions": 6, "ctr": 0.8333333333333334, "position": 1, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-03", "query": "internal server error: cannot invoke \"io.airbyte.api.model.generated.airbytecatalog.getstreams()\" because \"discovered\" is null"}, "emitted_at": 1709913950680} -{"stream": "search_analytics_by_query", "data": {"clicks": 3, "impressions": 4, "ctr": 0.75, "position": 2, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-02", "query": "the selection criterion does not match any nodes"}, "emitted_at": 1709913950680} -{"stream": "search_analytics_all_fields", "data": {"clicks": 2, "impressions": 3, "ctr": 0.6666666666666666, "position": 2, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-02", "country": "gbr", "device": "DESKTOP", "page": "https://discuss.airbyte.io/t/using-a-private-git-repo-for-transformations-the-selection-criterion-does-not-match-any-nodes/4170", "query": "the selection criterion does not match any nodes"}, "emitted_at": 1709913953146} -{"stream": "search_analytics_all_fields", "data": {"clicks": 2, "impressions": 2, "ctr": 1, "position": 2, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-02", "country": "usa", "device": "DESKTOP", "page": "https://discuss.airbyte.io/t/integrating-keycloak-iam-with-airbyte/2826", "query": "airbyte keycloak"}, "emitted_at": 1709913953146} -{"stream": "custom_dimensions", "data": {"clicks": 97, "impressions": 2392, "ctr": 0.040551839464882944, "position": 24.149247491638796, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-03", "country": "usa", "device": "DESKTOP"}, "emitted_at": 1709913970183} -{"stream": "custom_dimensions", "data": {"clicks": 81, "impressions": 2220, "ctr": 0.03648648648648649, "position": 27.025675675675675, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-02", "country": "usa", "device": "DESKTOP"}, "emitted_at": 1709913970184} -{"stream": "search_analytics_keyword_page_report", "data": {"clicks": 1, "impressions": 1, "ctr": 1, "position": 4, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-09-01", "country": "ind", "device": "DESKTOP", "query": "airbyte octavia", "page": "https://discuss.airbyte.io/t/airbyte-connectors-configuration-data-storage-using-octavia/3145"}, "emitted_at": 1725547397864} -{"stream": "search_analytics_keyword_page_report", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 32, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-08-31", "country": "are", "device": "DESKTOP", "query": "database in k8s", "page": "https://discuss.airbyte.io/t/kubernetes-temporal-deployment-failling-to-connect-with-external-azure-postgres-db/2928"}, "emitted_at": 1725547398182} -{"stream": "search_analytics_page_report", "data": {"clicks": 2, "impressions": 4, "ctr": 0.5, "position": 2.5, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-02", "country": "gbr", "device": "DESKTOP", "page": "https://discuss.airbyte.io/t/using-a-private-git-repo-for-transformations-the-selection-criterion-does-not-match-any-nodes/4170"}, "emitted_at": 1709913968085} -{"stream": "search_analytics_page_report", "data": {"clicks": 2, "impressions": 3, "ctr": 0.6666666666666666, "position": 1, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-03", "country": "deu", "device": "DESKTOP", "page": "https://discuss.airbyte.io/t/mixpanel-connector-issue-follow-up-on-previous-case/2814"}, "emitted_at": 1709913968086} -{"stream": "search_analytics_keyword_site_report_by_page", "data": {"clicks": 1, "impressions": 1, "ctr": 1, "position": 6, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-09-12", "country": "aus", "device": "DESKTOP", "query": "nothing to do. try checking your model configs and model specification args"}, "emitted_at": 1726485253585} -{"stream": "search_analytics_keyword_site_report_by_page", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 3, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-09-12", "country": "can", "device": "DESKTOP", "query": "did not find matching node for patch with name"}, "emitted_at": 1726485254092} -{"stream": "search_analytics_keyword_site_report_by_site", "data": {"clicks": 1, "impressions": 1, "ctr": 1, "position": 4, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-09-06", "country": "can", "device": "DESKTOP", "query": "airbyte datadog"}, "emitted_at": 1725874488288} -{"stream": "search_analytics_keyword_site_report_by_site", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 12, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-09-06", "country": "can", "device": "DESKTOP", "query": "error: could not find a version that satisfies the requirement pyyaml (from versions: none)"}, "emitted_at": 1725874488655} -{"stream": "search_analytics_site_report_by_page", "data": {"clicks": 105, "impressions": 2905, "ctr": 0.03614457831325301, "position": 21.6447504302926, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-03", "country": "usa", "device": "DESKTOP"}, "emitted_at": 1709913968684} -{"stream": "search_analytics_site_report_by_page", "data": {"clicks": 87, "impressions": 2598, "ctr": 0.03348729792147806, "position": 24.50269438029253, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-02", "country": "usa", "device": "DESKTOP"}, "emitted_at": 1709913968685} -{"stream": "search_analytics_site_report_by_site", "data": {"clicks": 97, "impressions": 2392, "ctr": 0.040551839464882944, "position": 24.149247491638796, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-03", "country": "usa", "device": "DESKTOP"}, "emitted_at": 1709913969703} -{"stream": "search_analytics_site_report_by_site", "data": {"clicks": 81, "impressions": 2220, "ctr": 0.03648648648648649, "position": 27.025675675675675, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-02", "country": "usa", "device": "DESKTOP"}, "emitted_at": 1709913969704} +{"stream": "search_analytics_by_date", "data": {"clicks": 0, "impressions": 0, "ctr": 0, "site_url": "sc-domain:airbyte.io", "search_type": "googleNews", "date": "2024-11-06"}, "emitted_at": 1731512430633} +{"stream": "search_analytics_by_date", "data": {"clicks": 0, "impressions": 0, "ctr": 0, "site_url": "sc-domain:airbyte.io", "search_type": "googleNews", "date": "2024-11-09"}, "emitted_at": 1731512430759} +{"stream": "search_analytics_by_country", "data": {"clicks": 1, "impressions": 15, "ctr": 0.06666666666666667, "position": 64.46666666666667, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-06", "country": "pak"}, "emitted_at": 1731512591294} +{"stream": "search_analytics_by_country", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 74, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-09", "country": "are"}, "emitted_at": 1731512591491} +{"stream": "search_analytics_by_device", "data": {"clicks": 1, "impressions": 251, "ctr": 0.00398406374501992, "position": 44.669322709163346, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-06", "device": "DESKTOP"}, "emitted_at": 1731512748032} +{"stream": "search_analytics_by_device", "data": {"clicks": 0, "impressions": 88, "ctr": 0, "position": 50.31818181818182, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-09", "device": "DESKTOP"}, "emitted_at": 1731512748153} +{"stream": "search_analytics_by_page", "data": {"clicks": 1, "impressions": 2, "ctr": 0.5, "position": 23.5, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-06", "page": "https://discuss.airbyte.io/t/iterable-fails-on-initial-sync-even-after-greatly-reducing-the-total-count-size-of-streams/2769"}, "emitted_at": 1731512874739} +{"stream": "search_analytics_by_page", "data": {"clicks": 0, "impressions": 4, "ctr": 0, "position": 50.25, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-09", "page": "https://discuss.airbyte.io/t/acceptance-test-failing-no-pytest/1970"}, "emitted_at": 1731512875046} +{"stream": "search_analytics_by_query", "data": {"clicks": 1, "impressions": 1, "ctr": 1, "position": 91, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-07", "query": "parquet file example"}, "emitted_at": 1731512968461} +{"stream": "search_analytics_by_query", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 90, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-09", "query": "\"failed to fetch\""}, "emitted_at": 1731512969250} +{"stream": "search_analytics_all_fields", "data": {"clicks": 1, "impressions": 1, "ctr": 1, "position": 91, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-07", "country": "egy", "device": "DESKTOP", "page": "https://discuss.airbyte.io/t/source-mysql-destination-s3-parquet-support-negative-ids-integers-for-mysql-source-to-aws-s3-destination-in-parquet-file-format/4054", "query": "parquet file example"}, "emitted_at": 1731513049949} +{"stream": "search_analytics_all_fields", "data": {"clicks": 0, "impressions": 2, "ctr": 0, "position": 82, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-09", "country": "arg", "device": "DESKTOP", "page": "https://discuss.airbyte.io/t/mysql-source-connector-type-tinyint-1/2171", "query": "mysql unsigned int"}, "emitted_at": 1731513050147} +{"stream": "custom_dimensions", "data": {"clicks": 1, "impressions": 4, "ctr": 0.25, "position": 44.25, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-06", "country": "pak", "device": "DESKTOP"}, "emitted_at": 1731513357449} +{"stream": "custom_dimensions", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 74, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-09", "country": "are", "device": "DESKTOP"}, "emitted_at": 1731513357654} +{"stream": "search_analytics_keyword_page_report", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 2, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-11-09", "country": "usa", "device": "DESKTOP", "query": "did not find matching node for patch with name", "page": "https://discuss.airbyte.io/t/using-a-private-git-repo-for-transformations-the-selection-criterion-does-not-match-any-nodes/4170"}, "emitted_at": 1731513131863} +{"stream": "search_analytics_keyword_page_report", "data": {"clicks": 3, "impressions": 49, "ctr": 0.061224489795918366, "position": 7.63265306122449, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-11-09", "country": "ind", "device": "MOBILE", "query": "ocean credit loan app", "page": "https://discuss.airbyte.io/t/ocean-credit-loan-app-customer-care-helpline-number-7702650355-8891102031call-nowdfg/8703"}, "emitted_at": 1731513132507} +{"stream": "search_analytics_page_report", "data": {"clicks": 1, "impressions": 1, "ctr": 1, "position": 91, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-07", "country": "egy", "device": "DESKTOP", "page": "https://discuss.airbyte.io/t/source-mysql-destination-s3-parquet-support-negative-ids-integers-for-mysql-source-to-aws-s3-destination-in-parquet-file-format/4054"}, "emitted_at": 1731513215967} +{"stream": "search_analytics_page_report", "data": {"clicks": 0, "impressions": 2, "ctr": 0, "position": 82, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-09", "country": "arg", "device": "DESKTOP", "page": "https://discuss.airbyte.io/t/mysql-source-connector-type-tinyint-1/2171"}, "emitted_at": 1731513216207} +{"stream": "search_analytics_keyword_site_report_by_page", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 2, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-11-09", "country": "usa", "device": "DESKTOP", "query": "did not find matching node for patch with name"}, "emitted_at": 1731513493966} +{"stream": "search_analytics_keyword_site_report_by_page", "data": {"clicks": 3, "impressions": 53, "ctr": 0.05660377358490566, "position": 7.660377358490566, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-11-09", "country": "ind", "device": "MOBILE", "query": "ocean credit loan app"}, "emitted_at": 1731513494305} +{"stream": "search_analytics_keyword_site_report_by_site", "data": {"clicks": 3, "impressions": 53, "ctr": 0.05660377358490566, "position": 7.660377358490566, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-11-09", "country": "ind", "device": "MOBILE", "query": "ocean credit loan app"}, "emitted_at": 1731513570131} +{"stream": "search_analytics_keyword_site_report_by_site", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 2, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-11-09", "country": "usa", "device": "DESKTOP", "query": "did not find matching node for patch with name"}, "emitted_at": 1731513570440} +{"stream": "search_analytics_site_report_by_page", "data": {"clicks": 1, "impressions": 8, "ctr": 0.125, "position": 26.125, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-06", "country": "pak", "device": "DESKTOP"}, "emitted_at": 1731513641044} +{"stream": "search_analytics_site_report_by_page", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 74, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-09", "country": "are", "device": "DESKTOP"}, "emitted_at": 1731513641278} +{"stream": "search_analytics_site_report_by_site", "data": {"clicks": 1, "impressions": 4, "ctr": 0.25, "position": 44.25, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-06", "country": "pak", "device": "DESKTOP"}, "emitted_at": 1731513811469} +{"stream": "search_analytics_site_report_by_site", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 74, "site_url": "sc-domain:airbyte.io", "search_type": "image", "date": "2024-11-09", "country": "are", "device": "DESKTOP"}, "emitted_at": 1731513811933} diff --git a/airbyte-integrations/connectors/source-google-search-console/main.py b/airbyte-integrations/connectors/source-google-search-console/main.py index 845383457bb7..62b40b4e0391 100755 --- a/airbyte-integrations/connectors/source-google-search-console/main.py +++ b/airbyte-integrations/connectors/source-google-search-console/main.py @@ -4,5 +4,6 @@ from source_google_search_console.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-google-search-console/metadata.yaml b/airbyte-integrations/connectors/source-google-search-console/metadata.yaml index cd0670ee9e5b..0cd3ffd7ad07 100644 --- a/airbyte-integrations/connectors/source-google-search-console/metadata.yaml +++ b/airbyte-integrations/connectors/source-google-search-console/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - "*.googleapis.com" connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: eb4c9e00-db83-4d63-a386-39cfa91012a8 - dockerImageTag: 1.5.4 + dockerImageTag: 1.5.9 dockerRepository: airbyte/source-google-search-console documentationUrl: https://docs.airbyte.com/integrations/sources/google-search-console erdUrl: https://dbdocs.io/airbyteio/source-google-search-console?view=relationships diff --git a/airbyte-integrations/connectors/source-google-search-console/poetry.lock b/airbyte-integrations/connectors/source-google-search-console/poetry.lock index 10163376b354..aaadd8c9057c 100644 --- a/airbyte-integrations/connectors/source-google-search-console/poetry.lock +++ b/airbyte-integrations/connectors/source-google-search-console/poetry.lock @@ -42,18 +42,40 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.12.2" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.12.2-py3-none-any.whl", hash = "sha256:1780db5b26285865b858d26502933def8e11919c9436ccf7b8b9cb0170b07c2a"}, - {file = "airbyte_protocol_models-0.12.2.tar.gz", hash = "sha256:b7c4d9a7c32c0691601c2b9416af090a858e126666e2c8c880d7a1798eb519f0"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] pydantic = ">=1.9.2,<2.0.0" +[[package]] +name = "anyio" +version = "4.7.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.9" +files = [ + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, +] + +[package.dependencies] +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} +idna = ">=2.8" +sniffio = ">=1.1" +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} + +[package.extras] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] +trio = ["trio (>=0.26.1)"] + [[package]] name = "atomicwrites" version = "1.4.1" @@ -66,22 +88,22 @@ files = [ [[package]] name = "attrs" -version = "23.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, - {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] -tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "backoff" @@ -96,35 +118,35 @@ files = [ [[package]] name = "bracex" -version = "2.5" +version = "2.5.post1" description = "Bash style brace expander." optional = false python-versions = ">=3.8" files = [ - {file = "bracex-2.5-py3-none-any.whl", hash = "sha256:d2fcf4b606a82ac325471affe1706dd9bbaa3536c91ef86a31f6b766f3dad1d0"}, - {file = "bracex-2.5.tar.gz", hash = "sha256:0725da5045e8d37ea9592ab3614d8b561e22c3c5fde3964699be672e072ab611"}, + {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, + {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, ] [[package]] name = "cachetools" -version = "5.4.0" +version = "5.5.0" description = "Extensible memoizing collections and decorators" optional = false python-versions = ">=3.7" files = [ - {file = "cachetools-5.4.0-py3-none-any.whl", hash = "sha256:3ae3b49a3d5e28a77a0be2b37dbcb89005058959cb2323858c2657c4a8cab474"}, - {file = "cachetools-5.4.0.tar.gz", hash = "sha256:b8adc2e7c07f105ced7bc56dbb6dfbe7c4a00acce20e2227b3f355be89bc6827"}, + {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, + {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, ] [[package]] name = "cattrs" -version = "23.2.3" +version = "24.1.2" description = "Composable complex class support for attrs and dataclasses." optional = false python-versions = ">=3.8" files = [ - {file = "cattrs-23.2.3-py3-none-any.whl", hash = "sha256:0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108"}, - {file = "cattrs-23.2.3.tar.gz", hash = "sha256:a934090d95abaa9e911dac357e3a8699e0b4b14f8529bcc7d2b1ad9d51672b9f"}, + {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, + {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, ] [package.dependencies] @@ -136,6 +158,7 @@ typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_ver bson = ["pymongo (>=4.4.0)"] cbor2 = ["cbor2 (>=5.4.6)"] msgpack = ["msgpack (>=1.0.5)"] +msgspec = ["msgspec (>=0.18.5)"] orjson = ["orjson (>=3.9.2)"] pyyaml = ["pyyaml (>=6.0)"] tomlkit = ["tomlkit (>=0.11.8)"] @@ -143,74 +166,89 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.7.4" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "cffi" -version = "1.16.0" +version = "1.17.1" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" files = [ - {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, - {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, - {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, - {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, - {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, - {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, - {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, - {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, - {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, - {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, - {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, - {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, - {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, - {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, - {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, + {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, + {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, + {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, + {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, ] [package.dependencies] @@ -218,101 +256,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.3.2" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -382,20 +422,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -434,13 +474,13 @@ files = [ [[package]] name = "google-api-core" -version = "2.19.1" +version = "2.24.0" description = "Google API client core library" optional = false python-versions = ">=3.7" files = [ - {file = "google-api-core-2.19.1.tar.gz", hash = "sha256:f4695f1e3650b316a795108a76a1c416e6afb036199d1c1f1f110916df479ffd"}, - {file = "google_api_core-2.19.1-py3-none-any.whl", hash = "sha256:f12a9b8309b5e21d92483bbd47ce2c445861ec7d269ef6784ecc0ea8c1fa6125"}, + {file = "google_api_core-2.24.0-py3-none-any.whl", hash = "sha256:10d82ac0fca69c82a25b3efdeefccf6f28e02ebb97925a8cce8edbfe379929d9"}, + {file = "google_api_core-2.24.0.tar.gz", hash = "sha256:e255640547a597a4da010876d333208ddac417d60add22b6851a0c66a831fcaf"}, ] [package.dependencies] @@ -451,6 +491,7 @@ protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4 requests = ">=2.18.0,<3.0.0.dev0" [package.extras] +async-rest = ["google-auth[aiohttp] (>=2.35.0,<3.0.dev0)"] grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio (>=1.49.1,<2.0dev)", "grpcio-status (>=1.33.2,<2.0.dev0)", "grpcio-status (>=1.49.1,<2.0.dev0)"] grpcgcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] @@ -513,13 +554,13 @@ httplib2 = ">=0.19.0" [[package]] name = "googleapis-common-protos" -version = "1.63.2" +version = "1.66.0" description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" files = [ - {file = "googleapis-common-protos-1.63.2.tar.gz", hash = "sha256:27c5abdffc4911f28101e635de1533fb4cfd2c37fbaa9174587c799fac90aa87"}, - {file = "googleapis_common_protos-1.63.2-py2.py3-none-any.whl", hash = "sha256:27a2499c7e8aff199665b22741997e485eccc8645aa9176c7c988e6fae507945"}, + {file = "googleapis_common_protos-1.66.0-py2.py3-none-any.whl", hash = "sha256:d7abcd75fabb2e0ec9f74466401f6c119a0b498e27370e9be4c94cb7e382b8ed"}, + {file = "googleapis_common_protos-1.66.0.tar.gz", hash = "sha256:c3e7b33d15fdca5374cc0a7346dd92ffa847425cc4ea941d970f13680052ec8c"}, ] [package.dependencies] @@ -528,6 +569,38 @@ protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4 [package.extras] grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.7" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<1.0)"] + [[package]] name = "httplib2" version = "0.22.0" @@ -542,17 +615,44 @@ files = [ [package.dependencies] pyparsing = {version = ">=2.4.2,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.0.2 || >3.0.2,<3.0.3 || >3.0.3,<4", markers = "python_version > \"3.0\""} +[[package]] +name = "httpx" +version = "0.28.1" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +zstd = ["zstandard (>=0.18.0)"] + [[package]] name = "idna" -version = "3.7" +version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, ] +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -580,13 +680,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -676,147 +776,177 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.96" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.96-py3-none-any.whl", hash = "sha256:1e8285c3f84cffebc761ff5624647de20686dbbf659f5d1135918261f85bad13"}, - {file = "langsmith-0.1.96.tar.gz", hash = "sha256:01b7fa7d538b6409ee74bff458cc3dcdc1799fc70d329f79eb26ba54c32991ae"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] -orjson = ">=3.9.14,<4.0.0" +httpx = ">=0.23.0,<1" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" +requests-toolbelt = ">=1.0.0,<2.0.0" + +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] [[package]] name = "markupsafe" -version = "2.1.5" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false -python-versions = ">=3.7" -files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +python-versions = ">=3.9" +files = [ + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] name = "orjson" -version = "3.10.6" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.6-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:fb0ee33124db6eaa517d00890fc1a55c3bfe1cf78ba4a8899d71a06f2d6ff5c7"}, - {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c1c4b53b24a4c06547ce43e5fee6ec4e0d8fe2d597f4647fc033fd205707365"}, - {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eadc8fd310edb4bdbd333374f2c8fec6794bbbae99b592f448d8214a5e4050c0"}, - {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:61272a5aec2b2661f4fa2b37c907ce9701e821b2c1285d5c3ab0207ebd358d38"}, - {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57985ee7e91d6214c837936dc1608f40f330a6b88bb13f5a57ce5257807da143"}, - {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:633a3b31d9d7c9f02d49c4ab4d0a86065c4a6f6adc297d63d272e043472acab5"}, - {file = "orjson-3.10.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1c680b269d33ec444afe2bdc647c9eb73166fa47a16d9a75ee56a374f4a45f43"}, - {file = "orjson-3.10.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f759503a97a6ace19e55461395ab0d618b5a117e8d0fbb20e70cfd68a47327f2"}, - {file = "orjson-3.10.6-cp310-none-win32.whl", hash = "sha256:95a0cce17f969fb5391762e5719575217bd10ac5a189d1979442ee54456393f3"}, - {file = "orjson-3.10.6-cp310-none-win_amd64.whl", hash = "sha256:df25d9271270ba2133cc88ee83c318372bdc0f2cd6f32e7a450809a111efc45c"}, - {file = "orjson-3.10.6-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b1ec490e10d2a77c345def52599311849fc063ae0e67cf4f84528073152bb2ba"}, - {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55d43d3feb8f19d07e9f01e5b9be4f28801cf7c60d0fa0d279951b18fae1932b"}, - {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac3045267e98fe749408eee1593a142e02357c5c99be0802185ef2170086a863"}, - {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c27bc6a28ae95923350ab382c57113abd38f3928af3c80be6f2ba7eb8d8db0b0"}, - {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d27456491ca79532d11e507cadca37fb8c9324a3976294f68fb1eff2dc6ced5a"}, - {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05ac3d3916023745aa3b3b388e91b9166be1ca02b7c7e41045da6d12985685f0"}, - {file = "orjson-3.10.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1335d4ef59ab85cab66fe73fd7a4e881c298ee7f63ede918b7faa1b27cbe5212"}, - {file = "orjson-3.10.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4bbc6d0af24c1575edc79994c20e1b29e6fb3c6a570371306db0993ecf144dc5"}, - {file = "orjson-3.10.6-cp311-none-win32.whl", hash = "sha256:450e39ab1f7694465060a0550b3f6d328d20297bf2e06aa947b97c21e5241fbd"}, - {file = "orjson-3.10.6-cp311-none-win_amd64.whl", hash = "sha256:227df19441372610b20e05bdb906e1742ec2ad7a66ac8350dcfd29a63014a83b"}, - {file = "orjson-3.10.6-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ea2977b21f8d5d9b758bb3f344a75e55ca78e3ff85595d248eee813ae23ecdfb"}, - {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b6f3d167d13a16ed263b52dbfedff52c962bfd3d270b46b7518365bcc2121eed"}, - {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f710f346e4c44a4e8bdf23daa974faede58f83334289df80bc9cd12fe82573c7"}, - {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7275664f84e027dcb1ad5200b8b18373e9c669b2a9ec33d410c40f5ccf4b257e"}, - {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0943e4c701196b23c240b3d10ed8ecd674f03089198cf503105b474a4f77f21f"}, - {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:446dee5a491b5bc7d8f825d80d9637e7af43f86a331207b9c9610e2f93fee22a"}, - {file = "orjson-3.10.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:64c81456d2a050d380786413786b057983892db105516639cb5d3ee3c7fd5148"}, - {file = "orjson-3.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:960db0e31c4e52fa0fc3ecbaea5b2d3b58f379e32a95ae6b0ebeaa25b93dfd34"}, - {file = "orjson-3.10.6-cp312-none-win32.whl", hash = "sha256:a6ea7afb5b30b2317e0bee03c8d34c8181bc5a36f2afd4d0952f378972c4efd5"}, - {file = "orjson-3.10.6-cp312-none-win_amd64.whl", hash = "sha256:874ce88264b7e655dde4aeaacdc8fd772a7962faadfb41abe63e2a4861abc3dc"}, - {file = "orjson-3.10.6-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:66680eae4c4e7fc193d91cfc1353ad6d01b4801ae9b5314f17e11ba55e934183"}, - {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:caff75b425db5ef8e8f23af93c80f072f97b4fb3afd4af44482905c9f588da28"}, - {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3722fddb821b6036fd2a3c814f6bd9b57a89dc6337b9924ecd614ebce3271394"}, - {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2c116072a8533f2fec435fde4d134610f806bdac20188c7bd2081f3e9e0133f"}, - {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6eeb13218c8cf34c61912e9df2de2853f1d009de0e46ea09ccdf3d757896af0a"}, - {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:965a916373382674e323c957d560b953d81d7a8603fbeee26f7b8248638bd48b"}, - {file = "orjson-3.10.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:03c95484d53ed8e479cade8628c9cea00fd9d67f5554764a1110e0d5aa2de96e"}, - {file = "orjson-3.10.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:e060748a04cccf1e0a6f2358dffea9c080b849a4a68c28b1b907f272b5127e9b"}, - {file = "orjson-3.10.6-cp38-none-win32.whl", hash = "sha256:738dbe3ef909c4b019d69afc19caf6b5ed0e2f1c786b5d6215fbb7539246e4c6"}, - {file = "orjson-3.10.6-cp38-none-win_amd64.whl", hash = "sha256:d40f839dddf6a7d77114fe6b8a70218556408c71d4d6e29413bb5f150a692ff7"}, - {file = "orjson-3.10.6-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:697a35a083c4f834807a6232b3e62c8b280f7a44ad0b759fd4dce748951e70db"}, - {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd502f96bf5ea9a61cbc0b2b5900d0dd68aa0da197179042bdd2be67e51a1e4b"}, - {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f215789fb1667cdc874c1b8af6a84dc939fd802bf293a8334fce185c79cd359b"}, - {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2debd8ddce948a8c0938c8c93ade191d2f4ba4649a54302a7da905a81f00b56"}, - {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5410111d7b6681d4b0d65e0f58a13be588d01b473822483f77f513c7f93bd3b2"}, - {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb1f28a137337fdc18384079fa5726810681055b32b92253fa15ae5656e1dddb"}, - {file = "orjson-3.10.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bf2fbbce5fe7cd1aa177ea3eab2b8e6a6bc6e8592e4279ed3db2d62e57c0e1b2"}, - {file = "orjson-3.10.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:79b9b9e33bd4c517445a62b90ca0cc279b0f1f3970655c3df9e608bc3f91741a"}, - {file = "orjson-3.10.6-cp39-none-win32.whl", hash = "sha256:30b0a09a2014e621b1adf66a4f705f0809358350a757508ee80209b2d8dae219"}, - {file = "orjson-3.10.6-cp39-none-win_amd64.whl", hash = "sha256:49e3bc615652617d463069f91b867a4458114c5b104e13b7ae6872e5f79d0844"}, - {file = "orjson-3.10.6.tar.gz", hash = "sha256:e54b63d0a7c6c54a5f5f726bc93a2078111ef060fec4ecbf34c5db800ca3b3a7"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -866,19 +996,19 @@ pytzdata = ">=2020.1" [[package]] name = "platformdirs" -version = "4.2.2" +version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, - {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "pluggy" @@ -897,13 +1027,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "proto-plus" -version = "1.24.0" +version = "1.25.0" description = "Beautiful, Pythonic protocol buffers." optional = false python-versions = ">=3.7" files = [ - {file = "proto-plus-1.24.0.tar.gz", hash = "sha256:30b72a5ecafe4406b0d339db35b56c4059064e69227b8c3bda7462397f966445"}, - {file = "proto_plus-1.24.0-py3-none-any.whl", hash = "sha256:402576830425e5f6ce4c2a6702400ac79897dab0b4343821aa5188b0fab81a12"}, + {file = "proto_plus-1.25.0-py3-none-any.whl", hash = "sha256:c91fc4a65074ade8e458e95ef8bac34d4008daa7cce4a12d6707066fca648961"}, + {file = "proto_plus-1.25.0.tar.gz", hash = "sha256:fbb17f57f7bd05a68b7707e745e26528b0b3c34e378db91eef93912c54982d91"}, ] [package.dependencies] @@ -914,22 +1044,22 @@ testing = ["google-api-core (>=1.31.5)"] [[package]] name = "protobuf" -version = "5.27.3" +version = "5.29.2" description = "" optional = false python-versions = ">=3.8" files = [ - {file = "protobuf-5.27.3-cp310-abi3-win32.whl", hash = "sha256:dcb307cd4ef8fec0cf52cb9105a03d06fbb5275ce6d84a6ae33bc6cf84e0a07b"}, - {file = "protobuf-5.27.3-cp310-abi3-win_amd64.whl", hash = "sha256:16ddf3f8c6c41e1e803da7abea17b1793a97ef079a912e42351eabb19b2cffe7"}, - {file = "protobuf-5.27.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:68248c60d53f6168f565a8c76dc58ba4fa2ade31c2d1ebdae6d80f969cdc2d4f"}, - {file = "protobuf-5.27.3-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:b8a994fb3d1c11156e7d1e427186662b64694a62b55936b2b9348f0a7c6625ce"}, - {file = "protobuf-5.27.3-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:a55c48f2a2092d8e213bd143474df33a6ae751b781dd1d1f4d953c128a415b25"}, - {file = "protobuf-5.27.3-cp38-cp38-win32.whl", hash = "sha256:043853dcb55cc262bf2e116215ad43fa0859caab79bb0b2d31b708f128ece035"}, - {file = "protobuf-5.27.3-cp38-cp38-win_amd64.whl", hash = "sha256:c2a105c24f08b1e53d6c7ffe69cb09d0031512f0b72f812dd4005b8112dbe91e"}, - {file = "protobuf-5.27.3-cp39-cp39-win32.whl", hash = "sha256:c84eee2c71ed83704f1afbf1a85c3171eab0fd1ade3b399b3fad0884cbcca8bf"}, - {file = "protobuf-5.27.3-cp39-cp39-win_amd64.whl", hash = "sha256:af7c0b7cfbbb649ad26132e53faa348580f844d9ca46fd3ec7ca48a1ea5db8a1"}, - {file = "protobuf-5.27.3-py3-none-any.whl", hash = "sha256:8572c6533e544ebf6899c360e91d6bcbbee2549251643d32c52cf8a5de295ba5"}, - {file = "protobuf-5.27.3.tar.gz", hash = "sha256:82460903e640f2b7e34ee81a947fdaad89de796d324bcbc38ff5430bcdead82c"}, + {file = "protobuf-5.29.2-cp310-abi3-win32.whl", hash = "sha256:c12ba8249f5624300cf51c3d0bfe5be71a60c63e4dcf51ffe9a68771d958c851"}, + {file = "protobuf-5.29.2-cp310-abi3-win_amd64.whl", hash = "sha256:842de6d9241134a973aab719ab42b008a18a90f9f07f06ba480df268f86432f9"}, + {file = "protobuf-5.29.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a0c53d78383c851bfa97eb42e3703aefdc96d2036a41482ffd55dc5f529466eb"}, + {file = "protobuf-5.29.2-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:494229ecd8c9009dd71eda5fd57528395d1eacdf307dbece6c12ad0dd09e912e"}, + {file = "protobuf-5.29.2-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:b6b0d416bbbb9d4fbf9d0561dbfc4e324fd522f61f7af0fe0f282ab67b22477e"}, + {file = "protobuf-5.29.2-cp38-cp38-win32.whl", hash = "sha256:e621a98c0201a7c8afe89d9646859859be97cb22b8bf1d8eacfd90d5bda2eb19"}, + {file = "protobuf-5.29.2-cp38-cp38-win_amd64.whl", hash = "sha256:13d6d617a2a9e0e82a88113d7191a1baa1e42c2cc6f5f1398d3b054c8e7e714a"}, + {file = "protobuf-5.29.2-cp39-cp39-win32.whl", hash = "sha256:36000f97ea1e76e8398a3f02936aac2a5d2b111aae9920ec1b769fc4a222c4d9"}, + {file = "protobuf-5.29.2-cp39-cp39-win_amd64.whl", hash = "sha256:2d2e674c58a06311c8e99e74be43e7f3a8d1e2b2fdf845eaa347fbd866f23355"}, + {file = "protobuf-5.29.2-py3-none-any.whl", hash = "sha256:fde4554c0e578a5a0bcc9a276339594848d1e89f9ea47b4427c80e5d72f90181"}, + {file = "protobuf-5.29.2.tar.gz", hash = "sha256:b2cc8e8bb7c9326996f0e160137b0861f1a82162502658df2951209d0cb0309e"}, ] [[package]] @@ -945,24 +1075,24 @@ files = [ [[package]] name = "pyasn1" -version = "0.6.0" +version = "0.6.1" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" optional = false python-versions = ">=3.8" files = [ - {file = "pyasn1-0.6.0-py2.py3-none-any.whl", hash = "sha256:cca4bb0f2df5504f02f6f8a775b6e416ff9b0b3b16f7ee80b5a3153d9b804473"}, - {file = "pyasn1-0.6.0.tar.gz", hash = "sha256:3a35ab2c4b5ef98e17dfdec8ab074046fbda76e281c5a706ccd82328cfc8f64c"}, + {file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"}, + {file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"}, ] [[package]] name = "pyasn1-modules" -version = "0.4.0" +version = "0.4.1" description = "A collection of ASN.1-based protocols modules" optional = false python-versions = ">=3.8" files = [ - {file = "pyasn1_modules-0.4.0-py3-none-any.whl", hash = "sha256:be04f15b66c206eed667e0bb5ab27e2b1855ea54a842e5037738099e8ca4ae0b"}, - {file = "pyasn1_modules-0.4.0.tar.gz", hash = "sha256:831dbcea1b177b28c9baddf4c6d1013c24c3accd14a1873fffaa6a2e905f17b6"}, + {file = "pyasn1_modules-0.4.1-py3-none-any.whl", hash = "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd"}, + {file = "pyasn1_modules-0.4.1.tar.gz", hash = "sha256:c28e2dbf9c06ad61c71a075c7e0f9fd0f1b0bb2d2ad4377f240d33ac2ab60a7c"}, ] [package.dependencies] @@ -981,54 +1111,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.17" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.17-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fa51175313cc30097660b10eec8ca55ed08bfa07acbfe02f7a42f6c242e9a4b"}, - {file = "pydantic-1.10.17-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7e8988bb16988890c985bd2093df9dd731bfb9d5e0860db054c23034fab8f7a"}, - {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:371dcf1831f87c9e217e2b6a0c66842879a14873114ebb9d0861ab22e3b5bb1e"}, - {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4866a1579c0c3ca2c40575398a24d805d4db6cb353ee74df75ddeee3c657f9a7"}, - {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:543da3c6914795b37785703ffc74ba4d660418620cc273490d42c53949eeeca6"}, - {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7623b59876f49e61c2e283551cc3647616d2fbdc0b4d36d3d638aae8547ea681"}, - {file = "pydantic-1.10.17-cp310-cp310-win_amd64.whl", hash = "sha256:409b2b36d7d7d19cd8310b97a4ce6b1755ef8bd45b9a2ec5ec2b124db0a0d8f3"}, - {file = "pydantic-1.10.17-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fa43f362b46741df8f201bf3e7dff3569fa92069bcc7b4a740dea3602e27ab7a"}, - {file = "pydantic-1.10.17-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2a72d2a5ff86a3075ed81ca031eac86923d44bc5d42e719d585a8eb547bf0c9b"}, - {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4ad32aed3bf5eea5ca5decc3d1bbc3d0ec5d4fbcd72a03cdad849458decbc63"}, - {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb4e741782e236ee7dc1fb11ad94dc56aabaf02d21df0e79e0c21fe07c95741"}, - {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d2f89a719411cb234105735a520b7c077158a81e0fe1cb05a79c01fc5eb59d3c"}, - {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db3b48d9283d80a314f7a682f7acae8422386de659fffaba454b77a083c3937d"}, - {file = "pydantic-1.10.17-cp311-cp311-win_amd64.whl", hash = "sha256:9c803a5113cfab7bbb912f75faa4fc1e4acff43e452c82560349fff64f852e1b"}, - {file = "pydantic-1.10.17-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:820ae12a390c9cbb26bb44913c87fa2ff431a029a785642c1ff11fed0a095fcb"}, - {file = "pydantic-1.10.17-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c1e51d1af306641b7d1574d6d3307eaa10a4991542ca324f0feb134fee259815"}, - {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e53fb834aae96e7b0dadd6e92c66e7dd9cdf08965340ed04c16813102a47fab"}, - {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e2495309b1266e81d259a570dd199916ff34f7f51f1b549a0d37a6d9b17b4dc"}, - {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:098ad8de840c92ea586bf8efd9e2e90c6339d33ab5c1cfbb85be66e4ecf8213f"}, - {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:525bbef620dac93c430d5d6bdbc91bdb5521698d434adf4434a7ef6ffd5c4b7f"}, - {file = "pydantic-1.10.17-cp312-cp312-win_amd64.whl", hash = "sha256:6654028d1144df451e1da69a670083c27117d493f16cf83da81e1e50edce72ad"}, - {file = "pydantic-1.10.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c87cedb4680d1614f1d59d13fea353faf3afd41ba5c906a266f3f2e8c245d655"}, - {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11289fa895bcbc8f18704efa1d8020bb9a86314da435348f59745473eb042e6b"}, - {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94833612d6fd18b57c359a127cbfd932d9150c1b72fea7c86ab58c2a77edd7c7"}, - {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d4ecb515fa7cb0e46e163ecd9d52f9147ba57bc3633dca0e586cdb7a232db9e3"}, - {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7017971ffa7fd7808146880aa41b266e06c1e6e12261768a28b8b41ba55c8076"}, - {file = "pydantic-1.10.17-cp37-cp37m-win_amd64.whl", hash = "sha256:e840e6b2026920fc3f250ea8ebfdedf6ea7a25b77bf04c6576178e681942ae0f"}, - {file = "pydantic-1.10.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bfbb18b616abc4df70591b8c1ff1b3eabd234ddcddb86b7cac82657ab9017e33"}, - {file = "pydantic-1.10.17-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebb249096d873593e014535ab07145498957091aa6ae92759a32d40cb9998e2e"}, - {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8c209af63ccd7b22fba94b9024e8b7fd07feffee0001efae50dd99316b27768"}, - {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b40c9e13a0b61583e5599e7950490c700297b4a375b55b2b592774332798b7"}, - {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c31d281c7485223caf6474fc2b7cf21456289dbaa31401844069b77160cab9c7"}, - {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae5184e99a060a5c80010a2d53c99aee76a3b0ad683d493e5f0620b5d86eeb75"}, - {file = "pydantic-1.10.17-cp38-cp38-win_amd64.whl", hash = "sha256:ad1e33dc6b9787a6f0f3fd132859aa75626528b49cc1f9e429cdacb2608ad5f0"}, - {file = "pydantic-1.10.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7e17c0ee7192e54a10943f245dc79e36d9fe282418ea05b886e1c666063a7b54"}, - {file = "pydantic-1.10.17-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cafb9c938f61d1b182dfc7d44a7021326547b7b9cf695db5b68ec7b590214773"}, - {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95ef534e3c22e5abbdbdd6f66b6ea9dac3ca3e34c5c632894f8625d13d084cbe"}, - {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d96b8799ae3d782df7ec9615cb59fc32c32e1ed6afa1b231b0595f6516e8ab"}, - {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ab2f976336808fd5d539fdc26eb51f9aafc1f4b638e212ef6b6f05e753c8011d"}, - {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8ad363330557beac73159acfbeed220d5f1bfcd6b930302a987a375e02f74fd"}, - {file = "pydantic-1.10.17-cp39-cp39-win_amd64.whl", hash = "sha256:48db882e48575ce4b39659558b2f9f37c25b8d348e37a2b4e32971dd5a7d6227"}, - {file = "pydantic-1.10.17-py3-none-any.whl", hash = "sha256:e41b5b973e5c64f674b3b4720286ded184dcc26a691dd55f34391c62c6934688"}, - {file = "pydantic-1.10.17.tar.gz", hash = "sha256:f434160fb14b353caf634149baaf847206406471ba70e64657c1e8330277a991"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -1040,13 +1170,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1057,13 +1187,13 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] [[package]] name = "pyparsing" -version = "3.1.2" +version = "3.2.1" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false -python-versions = ">=3.6.8" +python-versions = ">=3.9" files = [ - {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, - {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, + {file = "pyparsing-3.2.1-py3-none-any.whl", hash = "sha256:506ff4f4386c4cec0590ec19e6302d3aedb992fdc02c761e90416f158dacf8e1"}, + {file = "pyparsing-3.2.1.tar.gz", hash = "sha256:61980854fd66de3a90028d679a954d5f2623e83144b5afe5ee86f43d762e5f0a"}, ] [package.extras] @@ -1218,62 +1348,64 @@ files = [ [[package]] name = "pyyaml" -version = "6.0.1" +version = "6.0.2" description = "YAML parser and emitter for Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] [[package]] @@ -1344,6 +1476,20 @@ requests = ">=2.22,<3" [package.extras] fixture = ["fixtures"] +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +description = "A utility belt for advanced users of python-requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, + {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, +] + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + [[package]] name = "rsa" version = "4.9" @@ -1360,29 +1506,44 @@ pyasn1 = ">=0.1.3" [[package]] name = "setuptools" -version = "72.1.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-72.1.0-py3-none-any.whl", hash = "sha256:5a03e1860cf56bb6ef48ce186b0e557fdba433237481a9a625176c2831be15d1"}, - {file = "setuptools-72.1.0.tar.gz", hash = "sha256:8d243eff56d095e5817f796ede6ae32941278f542e0f941867cc05ae52b162ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, ] [[package]] @@ -1449,13 +1610,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.2" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, - {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1480,81 +1641,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-google-search-console/pyproject.toml b/airbyte-integrations/connectors/source-google-search-console/pyproject.toml index 498d8cc81fc4..a4ba2fb82700 100644 --- a/airbyte-integrations/connectors/source-google-search-console/pyproject.toml +++ b/airbyte-integrations/connectors/source-google-search-console/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "1.5.4" +version = "1.5.9" name = "source-google-search-console" description = "Source implementation for Google Search Console." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-google-search-console/source_google_search_console/config_migrations.py b/airbyte-integrations/connectors/source-google-search-console/source_google_search_console/config_migrations.py index 2774f64703c7..7e0886377db3 100644 --- a/airbyte-integrations/connectors/source-google-search-console/source_google_search_console/config_migrations.py +++ b/airbyte-integrations/connectors/source-google-search-console/source_google_search_console/config_migrations.py @@ -11,6 +11,7 @@ from airbyte_cdk.sources import Source from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository + logger = logging.getLogger("airbyte_logger") diff --git a/airbyte-integrations/connectors/source-google-search-console/source_google_search_console/service_account_authenticator.py b/airbyte-integrations/connectors/source-google-search-console/source_google_search_console/service_account_authenticator.py index 15759c39bec7..0530faa64a01 100755 --- a/airbyte-integrations/connectors/source-google-search-console/source_google_search_console/service_account_authenticator.py +++ b/airbyte-integrations/connectors/source-google-search-console/source_google_search_console/service_account_authenticator.py @@ -6,8 +6,10 @@ from google.auth.transport.requests import Request from google.oauth2.service_account import Credentials from requests.auth import AuthBase + from source_google_search_console.exceptions import UnauthorizedServiceAccountError + DEFAULT_SCOPES = ["https://www.googleapis.com/auth/webmasters.readonly"] diff --git a/airbyte-integrations/connectors/source-google-search-console/source_google_search_console/source.py b/airbyte-integrations/connectors/source-google-search-console/source_google_search_console/source.py index e1481d1dcaab..c8c196c22f4c 100755 --- a/airbyte-integrations/connectors/source-google-search-console/source_google_search_console/source.py +++ b/airbyte-integrations/connectors/source-google-search-console/source_google_search_console/source.py @@ -10,6 +10,7 @@ import jsonschema import pendulum import requests + from airbyte_cdk.models import FailureType, SyncMode from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream @@ -40,6 +41,7 @@ Sites, ) + custom_reports_schema = { "type": "array", "items": { diff --git a/airbyte-integrations/connectors/source-google-search-console/source_google_search_console/streams.py b/airbyte-integrations/connectors/source-google-search-console/source_google_search_console/streams.py index 1474a7591f7a..76d359743d65 100755 --- a/airbyte-integrations/connectors/source-google-search-console/source_google_search_console/streams.py +++ b/airbyte-integrations/connectors/source-google-search-console/source_google_search_console/streams.py @@ -9,10 +9,12 @@ import pendulum import requests +from requests.auth import AuthBase + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.streams import CheckpointMixin from airbyte_cdk.sources.streams.http import HttpStream -from requests.auth import AuthBase + BASE_URL = "https://www.googleapis.com/webmasters/v3/" ROW_LIMIT = 25000 diff --git a/airbyte-integrations/connectors/source-google-search-console/unit_tests/test_migrations/test_config_migrations.py b/airbyte-integrations/connectors/source-google-search-console/unit_tests/test_migrations/test_config_migrations.py index 1a321480fc1f..63498cf5e2f4 100644 --- a/airbyte-integrations/connectors/source-google-search-console/unit_tests/test_migrations/test_config_migrations.py +++ b/airbyte-integrations/connectors/source-google-search-console/unit_tests/test_migrations/test_config_migrations.py @@ -6,11 +6,13 @@ import json from typing import Any, Mapping -from airbyte_cdk.models import OrchestratorType, Type -from airbyte_cdk.sources import Source from source_google_search_console.config_migrations import MigrateCustomReports from source_google_search_console.source import SourceGoogleSearchConsole +from airbyte_cdk.models import OrchestratorType, Type +from airbyte_cdk.sources import Source + + # BASE ARGS CMD = "check" TEST_CONFIG_PATH = "unit_tests/test_migrations/test_config.json" diff --git a/airbyte-integrations/connectors/source-google-search-console/unit_tests/unit_test.py b/airbyte-integrations/connectors/source-google-search-console/unit_tests/unit_test.py index 3c2b6dedfbe5..72acd67241e4 100755 --- a/airbyte-integrations/connectors/source-google-search-console/unit_tests/unit_test.py +++ b/airbyte-integrations/connectors/source-google-search-console/unit_tests/unit_test.py @@ -8,8 +8,6 @@ import pytest import requests -from airbyte_cdk.models import AirbyteConnectionStatus, Status, SyncMode -from airbyte_cdk.utils.traced_exception import AirbyteTracedException from pytest_lazyfixture import lazy_fixture from source_google_search_console.source import SourceGoogleSearchConsole from source_google_search_console.streams import ( @@ -23,6 +21,10 @@ ) from utils import command_check +from airbyte_cdk.models import AirbyteConnectionStatus, Status, SyncMode +from airbyte_cdk.utils.traced_exception import AirbyteTracedException + + logger = logging.getLogger("airbyte") @@ -133,7 +135,9 @@ def test_forbidden_should_retry(requests_mock, forbidden_error_message_json): def test_bad_aggregation_type_should_retry(requests_mock, bad_aggregation_type): stream = SearchAnalyticsKeywordSiteReportBySite(None, ["https://example.com"], "2021-01-01", "2021-01-02") - requests_mock.post(f"{stream.url_base}sites/{stream._site_urls[0]}/searchAnalytics/query", status_code=200, json={"rows": [{"keys": ["TPF_QA"]}]}) + requests_mock.post( + f"{stream.url_base}sites/{stream._site_urls[0]}/searchAnalytics/query", status_code=200, json={"rows": [{"keys": ["TPF_QA"]}]} + ) slice = list(stream.stream_slices(None))[0] url = stream.url_base + stream.path(None, slice) requests_mock.get(url, status_code=400, json=bad_aggregation_type) diff --git a/airbyte-integrations/connectors/source-google-sheets/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-google-sheets/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-google-sheets/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-google-sheets/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-google-sheets/main.py b/airbyte-integrations/connectors/source-google-sheets/main.py index 806ac60fbefe..7ecf2f8cd0e9 100644 --- a/airbyte-integrations/connectors/source-google-sheets/main.py +++ b/airbyte-integrations/connectors/source-google-sheets/main.py @@ -4,5 +4,6 @@ from source_google_sheets.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-google-sheets/metadata.yaml b/airbyte-integrations/connectors/source-google-sheets/metadata.yaml index a5926a4bfcf5..f132cad60d21 100644 --- a/airbyte-integrations/connectors/source-google-sheets/metadata.yaml +++ b/airbyte-integrations/connectors/source-google-sheets/metadata.yaml @@ -10,7 +10,7 @@ data: connectorSubtype: file connectorType: source definitionId: 71607ba1-c0ac-4799-8049-7f4b90dd50f7 - dockerImageTag: 0.7.4 + dockerImageTag: 0.8.4 dockerRepository: airbyte/source-google-sheets documentationUrl: https://docs.airbyte.com/integrations/sources/google-sheets githubIssueLabel: source-google-sheets @@ -35,8 +35,8 @@ data: connectorTestSuitesOptions: - suite: liveTests testConnections: - - name: google-sheets_service_config_dev_null - id: 758d197a-864f-45d3-9d5d-0a52fd9c0a22 + - name: temp-google-sheets_service_config_dev_null + id: 035f390f-591f-4bb5-b6d5-52145627befb - suite: unitTests - suite: acceptanceTests testSecrets: diff --git a/airbyte-integrations/connectors/source-google-sheets/pyproject.toml b/airbyte-integrations/connectors/source-google-sheets/pyproject.toml index 8813ea592b35..af6535ac7df6 100644 --- a/airbyte-integrations/connectors/source-google-sheets/pyproject.toml +++ b/airbyte-integrations/connectors/source-google-sheets/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.7.4" +version = "0.8.4" name = "source-google-sheets" description = "Source implementation for Google Sheets." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-google-sheets/source_google_sheets/client.py b/airbyte-integrations/connectors/source-google-sheets/source_google_sheets/client.py index 6dff3db5a41d..1664da763bd0 100644 --- a/airbyte-integrations/connectors/source-google-sheets/source_google_sheets/client.py +++ b/airbyte-integrations/connectors/source-google-sheets/source_google_sheets/client.py @@ -11,6 +11,7 @@ from .helpers import SCOPES, Helpers + logger = logging.getLogger("airbyte") @@ -33,24 +34,16 @@ def give_up(error): def __init__(self, credentials: Dict[str, str], scopes: List[str] = SCOPES): self.client = Helpers.get_authenticated_sheets_client(credentials, scopes) - def _create_range(self, sheet, row_cursor): - range = f"{sheet}!{row_cursor}:{row_cursor + self.Backoff.row_batch_size}" - return range - @backoff.on_exception(backoff.expo, errors.HttpError, max_time=120, giveup=Backoff.give_up, on_backoff=Backoff.increase_row_batch_size) def get(self, **kwargs): return self.client.get(**kwargs).execute() - @backoff.on_exception(backoff.expo, errors.HttpError, max_time=120, giveup=Backoff.give_up, on_backoff=Backoff.increase_row_batch_size) - def create(self, **kwargs): - return self.client.create(**kwargs).execute() - @backoff.on_exception(backoff.expo, errors.HttpError, max_time=120, giveup=Backoff.give_up, on_backoff=Backoff.increase_row_batch_size) def get_values(self, **kwargs): range = self._create_range(kwargs.pop("sheet"), kwargs.pop("row_cursor")) logger.info(f"Fetching range {range}") return self.client.values().batchGet(ranges=range, **kwargs).execute() - @backoff.on_exception(backoff.expo, errors.HttpError, max_time=120, giveup=Backoff.give_up, on_backoff=Backoff.increase_row_batch_size) - def update_values(self, **kwargs): - return self.client.values().batchUpdate(**kwargs).execute() + def _create_range(self, sheet, row_cursor): + range = f"{sheet}!{row_cursor}:{row_cursor + self.Backoff.row_batch_size}" + return range diff --git a/airbyte-integrations/connectors/source-google-sheets/source_google_sheets/helpers.py b/airbyte-integrations/connectors/source-google-sheets/source_google_sheets/helpers.py index 13b7d6f9b4bc..74da7aef6182 100644 --- a/airbyte-integrations/connectors/source-google-sheets/source_google_sheets/helpers.py +++ b/airbyte-integrations/connectors/source-google-sheets/source_google_sheets/helpers.py @@ -9,14 +9,16 @@ from datetime import datetime from typing import Dict, FrozenSet, Iterable, List, Tuple -from airbyte_cdk.models.airbyte_protocol import AirbyteRecordMessage, AirbyteStream, ConfiguredAirbyteCatalog, SyncMode from google.oauth2 import credentials as client_account from google.oauth2 import service_account from googleapiclient import discovery +from airbyte_cdk.models.airbyte_protocol import AirbyteRecordMessage, AirbyteStream, ConfiguredAirbyteCatalog, SyncMode + from .models.spreadsheet import RowData, Spreadsheet from .utils import safe_name_conversion + SCOPES = ["https://www.googleapis.com/auth/spreadsheets.readonly", "https://www.googleapis.com/auth/drive.readonly"] logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-google-sheets/source_google_sheets/source.py b/airbyte-integrations/connectors/source-google-sheets/source_google_sheets/source.py index eae6e3776123..06ba0e617d12 100644 --- a/airbyte-integrations/connectors/source-google-sheets/source_google_sheets/source.py +++ b/airbyte-integrations/connectors/source-google-sheets/source_google_sheets/source.py @@ -8,6 +8,10 @@ import socket from typing import Any, Generator, List, Mapping, MutableMapping, Optional, Union +from apiclient import errors +from google.auth import exceptions as google_exceptions +from requests.status_codes import codes as status_codes + from airbyte_cdk.models import FailureType from airbyte_cdk.models.airbyte_protocol import ( AirbyteCatalog, @@ -24,9 +28,6 @@ from airbyte_cdk.sources.streams.checkpoint import FullRefreshCheckpointReader from airbyte_cdk.utils import AirbyteTracedException from airbyte_cdk.utils.stream_status_utils import as_airbyte_message -from apiclient import errors -from google.auth import exceptions as google_exceptions -from requests.status_codes import codes as status_codes from .client import GoogleSheetsClient from .helpers import Helpers @@ -34,6 +35,7 @@ from .models.spreadsheet_values import SpreadsheetValues from .utils import exception_description_by_status_code, safe_name_conversion + # override default socket timeout to be 10 mins instead of 60 sec. # on behalf of https://github.com/airbytehq/oncall/issues/242 DEFAULT_SOCKET_TIMEOUT: int = 600 diff --git a/airbyte-integrations/connectors/source-google-sheets/source_google_sheets/utils.py b/airbyte-integrations/connectors/source-google-sheets/source_google_sheets/utils.py index 0e2168c4aff2..bf3f6a8cc302 100644 --- a/airbyte-integrations/connectors/source-google-sheets/source_google_sheets/utils.py +++ b/airbyte-integrations/connectors/source-google-sheets/source_google_sheets/utils.py @@ -8,6 +8,7 @@ import unidecode from requests.status_codes import codes as status_codes + TOKEN_PATTERN = re.compile(r"[A-Z]+[a-z]*|[a-z]+|\d+|(?P[^a-zA-Z\d]+)") DEFAULT_SEPARATOR = "_" diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/conftest.py b/airbyte-integrations/connectors/source-google-sheets/unit_tests/conftest.py index 7f1a4c699a8b..6c8e392764df 100644 --- a/airbyte-integrations/connectors/source-google-sheets/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/conftest.py @@ -3,9 +3,10 @@ # import pytest -from airbyte_cdk.models.airbyte_protocol import AirbyteStream, ConfiguredAirbyteStream, DestinationSyncMode, SyncMode from source_google_sheets.models import CellData, GridData, RowData, Sheet, SheetProperties, Spreadsheet, SpreadsheetValues, ValueRange +from airbyte_cdk.models.airbyte_protocol import AirbyteStream, ConfiguredAirbyteStream, DestinationSyncMode, SyncMode + @pytest.fixture def invalid_config(): @@ -28,10 +29,11 @@ def maker(spreadsheet_id, sheet_name): sheets=[ Sheet( data=[GridData(rowData=[RowData(values=[CellData(formattedValue="ID")])])], - properties=SheetProperties(title=sheet_name, gridProperties={"rowCount": 2}) + properties=SheetProperties(title=sheet_name, gridProperties={"rowCount": 2}), ), ], ) + return maker @@ -39,6 +41,7 @@ def maker(spreadsheet_id, sheet_name): def spreadsheet_values(): def maker(spreadsheet_id): return SpreadsheetValues(spreadsheetId=spreadsheet_id, valueRanges=[ValueRange(values=[["1"]])]) + return maker @@ -51,4 +54,5 @@ def maker(*name_schema_pairs): sync_mode=SyncMode.full_refresh, destination_sync_mode=DestinationSyncMode.overwrite, ) + return maker diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/__init__.py b/airbyte-integrations/connectors/source-google-sheets/unit_tests/integration/__init__.py similarity index 100% rename from airbyte-cdk/python/airbyte_cdk/sources/file_based/config/__init__.py rename to airbyte-integrations/connectors/source-google-sheets/unit_tests/integration/__init__.py diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/integration/custom_http_mocker.py b/airbyte-integrations/connectors/source-google-sheets/unit_tests/integration/custom_http_mocker.py new file mode 100644 index 000000000000..f54e8cffb53a --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/integration/custom_http_mocker.py @@ -0,0 +1,77 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + + +from functools import wraps +from typing import Dict +from unittest.mock import patch +from urllib.parse import parse_qsl, unquote, urlencode, urlunparse + +from httplib2 import Response + +from airbyte_cdk.test.mock_http import HttpResponse +from airbyte_cdk.test.mock_http.request import HttpRequest + + +def parse_and_transform(parse_result_str: str): + """ + Parse the input string representation of a HttpRequest transform it into the URL. + """ + parse_result_part = parse_result_str.split("ParseResult(", 1)[1].split(")", 1)[0] + + # Convert the ParseResult string into a dictionary + components = eval(f"dict({parse_result_part})") + + url = urlunparse( + ( + components["scheme"], + components["netloc"], + components["path"], + components["params"], + components["query"], + components["fragment"], + ) + ) + + return url + + +class CustomHttpMocker: + """ + This is a limited mocker for usage with httplib2.Http.request + It has a similar interface to airbyte HttpMocker such than when we move this connector to low-code only with + a http retriever we will be able to substitute CustomHttpMocker => HttpMocker in out integration testing with minimal changes. + + Note: there is only support for get and post method and url matching ignoring the body but this is enough for the current test set. + """ + + requests_mapper: Dict = {} + + def post(self, request: HttpRequest, response: HttpResponse): + custom_response = (Response({"status": response.status_code}), response.body.encode("utf-8")) + uri = parse_and_transform(str(request)) + decoded_url = unquote(uri) + self.requests_mapper[("POST", decoded_url)] = custom_response + + def get(self, request: HttpRequest, response: HttpResponse): + custom_response = (Response({"status": response.status_code}), response.body.encode("utf-8")) + uri = parse_and_transform(str(request)) + decoded_url = unquote(uri) + self.requests_mapper[("GET", decoded_url)] = custom_response + + def mock_request(self, uri, method="GET", body=None, headers=None, **kwargs): + decoded_url = unquote(uri) + mocked_response = self.requests_mapper.get((method, decoded_url)) + if not mocked_response: + raise Exception(f"Mock response not found {uri} {method}") + return mocked_response + + # trying to type that using callables provides the error `incompatible with return type "_F" in supertype "ContextDecorator"` + def __call__(self, test_func): # type: ignore + @wraps(test_func) + def wrapper(*args, **kwargs): # type: ignore # this is a very generic wrapper that does not need to be typed + kwargs["http_mocker"] = self + + with patch("httplib2.Http.request", side_effect=self.mock_request): + return test_func(*args, **kwargs) + + return wrapper diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/integration/request_builder.py b/airbyte-integrations/connectors/source-google-sheets/unit_tests/integration/request_builder.py new file mode 100644 index 000000000000..9fc77d47a852 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/integration/request_builder.py @@ -0,0 +1,73 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + +from __future__ import annotations + +from airbyte_cdk.test.mock_http.request import HttpRequest + + +# todo: this should be picked from manifest in the future +GOOGLE_SHEETS_BASE_URL = "https://sheets.googleapis.com/v4/spreadsheets" +OAUTH_AUTHORIZATION_ENDPOINT = "https://oauth2.googleapis.com" + + +class RequestBuilder: + @classmethod + def get_account_endpoint(cls) -> RequestBuilder: + return cls(resource="values:batchGet") + + def __init__(self, resource: str = None) -> None: + self._spreadsheet_id = None + self._query_params = {} + self._body = None + self.resource = resource + + def with_include_grid_data(self, include_grid_data: bool) -> RequestBuilder: + self._query_params["includeGridData"] = "true" if include_grid_data else "false" + return self + + def with_alt(self, alt: str) -> RequestBuilder: + self._query_params["alt"] = alt + return self + + def with_ranges(self, ranges: str) -> RequestBuilder: + self._query_params["ranges"] = ranges + return self + + def with_major_dimension(self, dimension: str) -> RequestBuilder: + self._query_params["majorDimension"] = dimension + return self + + def with_spreadsheet_id(self, spreadsheet_id: str) -> RequestBuilder: + self._spreadsheet_id = spreadsheet_id + return self + + def build(self) -> HttpRequest: + endpoint = f"/{self.resource}" if self.resource else "" + return HttpRequest( + url=f"{GOOGLE_SHEETS_BASE_URL}/{self._spreadsheet_id}{endpoint}", + query_params=self._query_params, + body=self._body, + ) + + +class AuthBuilder: + @classmethod + def get_token_endpoint(cls) -> AuthBuilder: + return cls(resource="token") + + def __init__(self, resource): + self._body = "" + self._resource = resource + self._query_params = "" + + def with_body(self, body: str): + self._body = body + return self + + def build(self) -> HttpRequest: + endpoint = f"/{self._resource}" if self._resource else "" + return HttpRequest( + url=f"{OAUTH_AUTHORIZATION_ENDPOINT}{endpoint}", + query_params=self._query_params, + body=self._body, + ) diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/integration/test_credentials.py b/airbyte-integrations/connectors/source-google-sheets/unit_tests/integration/test_credentials.py new file mode 100644 index 000000000000..e4781f4d267d --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/integration/test_credentials.py @@ -0,0 +1,64 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. +import json + + +# this key was generated with rsa library from cryptography +test_private_key = """ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCjM57/r+LuNv9z +Bbe7+sMCJJm6t1MafRfxYVEz9c52/mLa5iEnpJfE+NRFgyp8hE8t493Btt/bJk94 +2bMthZqMh2n9dIJZOUYBzd5MHLOc6vCUHFZT9fzHX/yTrz/bxa31BQs6c1p2HOiY +Kr3r0Dyj5jXsKo0mgt+iVKGgcSZ6NCzMRL8N9M++13k2RUPwaGksuyNqzAqgNhHd +wQcuS42AEFEOT1sfa4xG5mMY6+tPKDP92/ISHNUMD9NpzIA8A+tFX/w/L5VQKR3r +fTfrSTtkG6qF+3ARdeKqpxrW4ZPHuzNH8Y2I1uBuVaDvmZMvi+BLKgwwhWuEGjB1 +j6Tv4TgXAgMBAAECggEAJTXLXlPdg1/hzXlzw3XwyYfLz0EmPwdfkqcUKysz2Hi2 +1F8dFxtViVEMoQ6/fKV0Iivur1DBaIerHgxQ6KOqMblcRrAuWiaPWjD0qtjucOw2 +TybI3hrbeB/gCFIwVq0TNSbhwQF1EjIULEGujNotQVdnWwH2rd2wHKR8N4ck9T6b +SKz8+u21RY2cBprneS6wxh+dvba8+7cpHn4cB+TB6UMeUow01LF4ye+hYVDNx6j9 +VcdWXlH9fCy/GUTF4um+ABunlMCm6D5DAUVeiugd+ChSKzqOlV/H17EK1MF4HAjh +Alo2FJrKd8/ZwX1Xmngi9Y2Dlggmfiw4HzeNZNFFPQKBgQDmeQxDBvZapjdJntOM +DccoQGJyZMznd277xefKTfZLetcWWtgantW7IAxEEbwZOfrQFnBsNIlnreGPoZ7n +DL2jv/oVeEcr29FxlbDR2R1/h8Mp7d41Qi1Sd9RAhGcVtYZhLCCMMxt4DN7/v77M +2lc3B0NhgC3kxOJCC8kN2gqSTQKBgQC1RyENp1UTOSUbFsx1WbAzy2K974CRnL54 +uK7efoLQ7fLh6OsRlBoy60aUpHv2tCb5ac+xdMELoAQu3PQKJMDJITstwgM4p6AP +x32lAHzOYnhG9/3P7kc29OaY8tlkDAn0ckv05DLAGLbKAemcGKW3/u08EITQtdW7 +dEH75Ow98wKBgQDb5tV3QrZeKcgI251XPXIwCrakFV+Y3tErM1qFIbwFqtB8yPL2 ++2RM5jgt3ooNu89/KlncNIiCP1s/k2Mta2+qRStVvuyRgWympsAOic1meGATqp1h +TaI21JTVdj9xbEEqiFMJ0l28PvOrLAXeKdobbDezWPzxEZYclGgiak+55QKBgBVU +6W7R4hEBCHzHkge9Jh7yMAxpwpdf+on6MZm9CWfMmGg9IGxRIUQcq5GSSYQebveq +m+Yl9xGHIvbgyVboPEduwagAzKA+GXfB4ecox4cBz2WKiTOOtpKg/wHAkhRT1lgN +myKWN+KjBd9/mh3kSJv+Q6xtxTNKMnx8kccyiRpBAoGBAJV9AAXj4icaDiPKoQw5 +UERTGuVoEpWbc3yi/PXJ99fQxHZIHQa7a7VyyTHsDplqWu/qfHFHj+IJops8+l1F +U7PQBfXvIpubb55EhNCaID1VaRauGjW2x8PGA/27KQ3mB1uxEZUO8crcDYvPsZJf +jHfASOY3OsGgYW95pkyx5TH7 +-----END PRIVATE KEY----- + +""" + +service_account_info = { + "type": "service_account", + "project_id": "test-project-id", + "private_key_id": "test-private-key-id", + "private_key": test_private_key, + "client_email": "test-service-account@test-project.iam.gserviceaccount.com", + "client_id": "1234567890", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/test-service-account%40test-project.iam.gserviceaccount.com", +} + +service_account_info_encoded = json.dumps(service_account_info).encode("utf-8") + +service_account_credentials = { + "auth_type": "Service", + "service_account_info": service_account_info_encoded, +} + + +oauth_credentials = { + "auth_type": "Client", + "client_id": "43987534895734985.apps.googleusercontent.com", + "client_secret": "2347586435987643598", + "refresh_token": "1//4398574389537495437983457985437", +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/integration/test_source.py b/airbyte-integrations/connectors/source-google-sheets/unit_tests/integration/test_source.py new file mode 100644 index 000000000000..2123a2caec3b --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/integration/test_source.py @@ -0,0 +1,549 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + + +import json +from copy import deepcopy +from typing import Optional +from unittest import TestCase +from unittest.mock import ( + Mock, + patch, # patch("time.sleep") +) + +import pytest +from source_google_sheets import SourceGoogleSheets + +from airbyte_cdk.models import Status +from airbyte_cdk.models.airbyte_protocol import AirbyteStateBlob, AirbyteStreamStatus +from airbyte_cdk.test.catalog_builder import CatalogBuilder, ConfiguredAirbyteStreamBuilder +from airbyte_cdk.test.entrypoint_wrapper import read +from airbyte_cdk.test.mock_http import HttpResponse +from airbyte_cdk.test.mock_http.response_builder import find_template +from airbyte_cdk.utils import AirbyteTracedException + +from .custom_http_mocker import CustomHttpMocker as HttpMocker +from .request_builder import AuthBuilder, RequestBuilder +from .test_credentials import oauth_credentials, service_account_credentials, service_account_info + + +_SPREADSHEET_ID = "a_spreadsheet_id" + +_STREAM_NAME = "a_stream_name" +_B_STREAM_NAME = "b_stream_name" +_C_STREAM_NAME = "c_stream_name" + + +_CONFIG = {"spreadsheet_id": _SPREADSHEET_ID, "credentials": oauth_credentials} + +_SERVICE_CONFIG = {"spreadsheet_id": _SPREADSHEET_ID, "credentials": service_account_credentials} + + +class GoogleSheetSourceTest(TestCase): + def setUp(self) -> None: + self._config = deepcopy(_CONFIG) + self._service_config = deepcopy(_SERVICE_CONFIG) + self._source = SourceGoogleSheets() + + @staticmethod + def authorize(http_mocker: HttpMocker): + # Authorization request with user credentials to "https://oauth2.googleapis.com" to obtain a token + http_mocker.post(AuthBuilder.get_token_endpoint().build(), HttpResponse(json.dumps(find_template("auth_response", __file__)), 200)) + + @staticmethod + def get_streams(http_mocker: HttpMocker, streams_response_file: Optional[str] = None, meta_response_code: Optional[int] = 200): + """ " + Mock request to https://sheets.googleapis.com/v4/spreadsheets/?includeGridData=false&alt=json in order + to obtain sheets (streams) from the spreed_sheet_id provided. + e.g. from response file + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 1, + "columnCount": 1 + } + } + } + ], + """ + GoogleSheetSourceTest.authorize(http_mocker) + if streams_response_file: + http_mocker.get( + RequestBuilder().with_spreadsheet_id(_SPREADSHEET_ID).with_include_grid_data(False).with_alt("json").build(), + HttpResponse(json.dumps(find_template(streams_response_file, __file__)), meta_response_code), + ) + + @staticmethod + def get_schema( + http_mocker: HttpMocker, + headers_response_file: str, + headers_response_code: int = 200, + stream_name: Optional[str] = _STREAM_NAME, + data_initial_range_response_file: Optional[str] = None, + data_initial_response_code: Optional[int] = 200, + ): + """ " + Mock request to 'https://sheets.googleapis.com/v4/spreadsheets/?includeGridData=true&ranges=!1:1&alt=json' + to obtain headers data (keys) used for stream schema from the spreadsheet + sheet provided. + For this we use range of first row in query. + e.g. from response file + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": , + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 4, + "columnCount": 2 + } + }, + "data": [ + { + "rowData": [ + { + "values": [ + { + "userEnteredValue": { + "stringValue": "name" + }, + "effectiveValue": { + "stringValue": "name" + }, + "formattedValue": "name" + }, + { + "userEnteredValue": { + "stringValue": "age" + }, + "effectiveValue": { + "stringValue": "age" + }, + "formattedValue": "age" + } + ]}],}]}] + """ + http_mocker.get( + RequestBuilder() + .with_spreadsheet_id(_SPREADSHEET_ID) + .with_include_grid_data(True) + .with_ranges(f"{stream_name}!1:1") + .with_alt("json") + .build(), + HttpResponse(json.dumps(find_template(headers_response_file, __file__)), headers_response_code), + ) + + @staticmethod + def get_stream_data( + http_mocker: HttpMocker, range_data_response_file: str, range_response_code: int = 200, stream_name: Optional[str] = _STREAM_NAME + ): + """ " + Mock requests to 'https://sheets.googleapis.com/v4/spreadsheets//values:batchGet?ranges=!2:202&majorDimension=ROWS&alt=json' + to obtain value ranges (data) for stream from the spreadsheet + sheet provided. + For this we use range [2:202(2 + range in config which default is 200)]. + We start at 2 as we consider row 1 to contain headers. If we had more data the routine would continue to next ranges. + e.g. from response file + { + "spreadsheetId": "", + "valueRanges": [ + { + "range": "!A2:B4", + "majorDimension": "ROWS", + "values": [ + ["name1", "22"], + ["name2", "24"], + ["name3", "25"] + ] + } + ] + } + """ + batch_request_ranges = f"{stream_name}!2:202" + http_mocker.get( + RequestBuilder.get_account_endpoint() + .with_spreadsheet_id(_SPREADSHEET_ID) + .with_ranges(batch_request_ranges) + .with_major_dimension("ROWS") + .with_alt("json") + .build(), + HttpResponse(json.dumps(find_template(range_data_response_file, __file__)), range_response_code), + ) + + @HttpMocker() + def test_given_spreadsheet_when_check_then_status_is_succeeded(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "check_succeeded_meta") + GoogleSheetSourceTest.get_schema(http_mocker, "check_succeeded_range") + connection_status = self._source.check(Mock(), self._config) + assert connection_status.status == Status.SUCCEEDED + + def test_given_authentication_error_when_check_then_status_is_failed(self) -> None: + del self._config["credentials"]["client_secret"] + connection_status = self._source.check(Mock(), self._config) + assert connection_status.status == Status.FAILED + + def test_given_service_authentication_error_when_check_then_status_is_failed(self) -> None: + wrong_service_account_info = deepcopy(service_account_info) + del wrong_service_account_info["client_email"] + wrong_service_account_info_encoded = json.dumps(service_account_info).encode("utf-8") + wrong_service_account_credentials = { + "auth_type": "Service", + "service_account_info": wrong_service_account_info_encoded, + } + connection_status = self._source.check(Mock(), wrong_service_account_credentials) + assert connection_status.status == Status.FAILED + + @HttpMocker() + def test_invalid_credentials_error_message_when_check(self, http_mocker: HttpMocker) -> None: + http_mocker.post( + AuthBuilder.get_token_endpoint().build(), HttpResponse(json.dumps(find_template("auth_invalid_client", __file__)), 200) + ) + with pytest.raises(AirbyteTracedException) as exc_info: + self._source.check(Mock(), self._config) + + assert str(exc_info.value) == ("Access to the spreadsheet expired or was revoked. Re-authenticate to restore access.") + + @HttpMocker() + def test_invalid_link_error_message_when_check(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "invalid_link", 404) + + with pytest.raises(AirbyteTracedException) as exc_info: + self._source.check(Mock(), self._config) + assert str(exc_info.value) == ( + "Config error: The spreadsheet link is not valid. Enter the URL of the Google spreadsheet you want to sync." + ) + + def test_check_invalid_creds_json_file(self) -> None: + connection_status = self._source.check(Mock(), "") + assert "Please use valid credentials json file" in connection_status.message + assert connection_status.status == Status.FAILED + + @HttpMocker() + def test_check_access_expired(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "invalid_permissions", 403) + with pytest.raises(AirbyteTracedException) as exc_info: + self._source.check(Mock(), self._config) + assert str(exc_info.value) == ("Config error: ") + + @HttpMocker() + def test_check_expected_to_read_data_from_1_sheet(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "check_succeeded_meta", 200) + GoogleSheetSourceTest.get_schema(http_mocker, "check_wrong_range", 200) + + connection_status = self._source.check(Mock(), self._config) + assert connection_status.status == Status.FAILED + assert ( + connection_status.message + == f"Unable to read the schema of sheet a_stream_name. Error: Unexpected return result: Sheet {_STREAM_NAME} was expected to contain data on exactly 1 sheet. " + ) + + @HttpMocker() + def test_check_duplicated_headers(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "check_succeeded_meta", 200) + GoogleSheetSourceTest.get_schema(http_mocker, "check_duplicate_headers", 200) + + connection_status = self._source.check(Mock(), self._config) + assert connection_status.status == Status.FAILED + assert ( + connection_status.message + == f"The following duplicate headers were found in the following sheets. Please fix them to continue: [sheet:{_STREAM_NAME}, headers:['header1']]" + ) + + @HttpMocker() + def test_given_grid_sheet_type_with_at_least_one_row_when_discover_then_return_stream(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "only_headers_meta", 200) + GoogleSheetSourceTest.get_schema(http_mocker, "only_headers_range", 200) + + discovered_catalog = self._source.discover(Mock(), self._config) + assert len(discovered_catalog.streams) == 1 + assert len(discovered_catalog.streams[0].json_schema["properties"]) == 2 + + @HttpMocker() + def test_discover_return_expected_schema(self, http_mocker: HttpMocker) -> None: + # When we move to manifest only is possible that DynamicSchemaLoader will identify fields like age as integers + # and addresses "oneOf": [{"type": ["null", "string"]}, {"type": ["null", "integer"]}] as it has mixed data + expected_schemas_properties = { + _STREAM_NAME: {"age": {"type": "string"}, "name": {"type": "string"}}, + _B_STREAM_NAME: {"email": {"type": "string"}, "name": {"type": "string"}}, + _C_STREAM_NAME: {"address": {"type": "string"}}, + } + GoogleSheetSourceTest.get_streams(http_mocker, "multiple_streams_schemas_meta", 200) + GoogleSheetSourceTest.get_schema(http_mocker, f"multiple_streams_schemas_{_STREAM_NAME}_range", 200) + GoogleSheetSourceTest.get_schema(http_mocker, f"multiple_streams_schemas_{_B_STREAM_NAME}_range", 200, _B_STREAM_NAME) + GoogleSheetSourceTest.get_schema(http_mocker, f"multiple_streams_schemas_{_C_STREAM_NAME}_range", 200, _C_STREAM_NAME) + + discovered_catalog = self._source.discover(Mock(), self._config) + assert len(discovered_catalog.streams) == 3 + for current_stream in discovered_catalog.streams: + assert current_stream.json_schema["properties"] == expected_schemas_properties[current_stream.name] + + @HttpMocker() + def test_discover_with_names_conversion(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "only_headers_meta", 200) + GoogleSheetSourceTest.get_schema(http_mocker, "names_conversion_range", 200) + + self._config["names_conversion"] = True + + discovered_catalog = self._source.discover(Mock(), self._config) + assert len(discovered_catalog.streams) == 1 + assert len(discovered_catalog.streams[0].json_schema["properties"]) == 2 + assert "_1_test" in discovered_catalog.streams[0].json_schema["properties"].keys() + + @HttpMocker() + def test_discover_could_not_run_discover(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "internal_server_error", 500) + + with pytest.raises(Exception) as exc_info, patch("time.sleep"), patch("backoff._sync._maybe_call", side_effect=lambda value: 3): + self._source.discover(Mock(), self._config) + expected_message = ( + "Could not discover the schema of your spreadsheet. There was an issue with the Google Sheets API." + " This is usually a temporary issue from Google's side. Please try again. If this issue persists, contact support. Interval Server error." + ) + assert str(exc_info.value) == expected_message + + @HttpMocker() + def test_discover_invalid_credentials_error_message(self, http_mocker: HttpMocker) -> None: + http_mocker.post( + AuthBuilder.get_token_endpoint().build(), HttpResponse(json.dumps(find_template("auth_invalid_client", __file__)), 200) + ) + + with pytest.raises(Exception) as exc_info: + self._source.discover(Mock(), self._config) + expected_message = "Access to the spreadsheet expired or was revoked. Re-authenticate to restore access." + assert str(exc_info.value) == expected_message + + @HttpMocker() + def test_discover_404_error(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "invalid_link", 404) + + with pytest.raises(AirbyteTracedException) as exc_info: + self._source.discover(Mock(), self._config) + expected_message = ( + f"The requested Google Sheets spreadsheet with id {_SPREADSHEET_ID} does not exist." + " Please ensure the Spreadsheet Link you have set is valid and the spreadsheet exists. If the issue persists, contact support. Requested entity was not found.." + ) + assert str(exc_info.value) == expected_message + + @HttpMocker() + def test_discover_403_error(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "invalid_permissions", 403) + + with pytest.raises(AirbyteTracedException) as exc_info: + self._source.discover(Mock(), self._config) + expected_message = ( + "The authenticated Google Sheets user does not have permissions to view the " + f"spreadsheet with id {_SPREADSHEET_ID}. Please ensure the authenticated user has access" + " to the Spreadsheet and reauthenticate. If the issue persists, contact support. " + "The caller does not have right permissions." + ) + assert str(exc_info.value) == expected_message + + @HttpMocker() + def test_given_grid_sheet_type_without_rows_when_discover_then_ignore_stream(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "no_rows_meta", 200) + GoogleSheetSourceTest.get_schema(http_mocker, "no_rows_range", 200) + + discovered_catalog = self._source.discover(Mock(), self._config) + assert len(discovered_catalog.streams) == 0 + + @HttpMocker() + def test_given_not_grid_sheet_type_when_discover_then_ignore_stream(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "non_grid_sheet_meta", 200) + discovered_catalog = self._source.discover(Mock(), self._config) + assert len(discovered_catalog.streams) == 0 + + @HttpMocker() + def test_when_read_then_return_records(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "read_records_meta") + GoogleSheetSourceTest.get_schema(http_mocker, "read_records_range") + GoogleSheetSourceTest.get_stream_data(http_mocker, "read_records_range_with_dimensions") + + configured_catalog = ( + CatalogBuilder() + .with_stream( + ConfiguredAirbyteStreamBuilder() + .with_name(_STREAM_NAME) + .with_json_schema({"properties": {"header_1": {"type": ["null", "string"]}, "header_2": {"type": ["null", "string"]}}}) + ) + .build() + ) + + output = read(self._source, self._config, configured_catalog) + assert len(output.records) == 2 + + @HttpMocker() + def test_when_read_multiple_streams_return_records(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "multiple_streams_schemas_meta", 200) + + GoogleSheetSourceTest.get_schema(http_mocker, f"multiple_streams_schemas_{_STREAM_NAME}_range", 200) + GoogleSheetSourceTest.get_schema(http_mocker, f"multiple_streams_schemas_{_B_STREAM_NAME}_range", 200, _B_STREAM_NAME) + GoogleSheetSourceTest.get_schema(http_mocker, f"multiple_streams_schemas_{_C_STREAM_NAME}_range", 200, _C_STREAM_NAME) + + GoogleSheetSourceTest.get_stream_data(http_mocker, f"multiple_streams_schemas_{_STREAM_NAME}_range_2") + GoogleSheetSourceTest.get_stream_data(http_mocker, f"multiple_streams_schemas_{_B_STREAM_NAME}_range_2", stream_name=_B_STREAM_NAME) + GoogleSheetSourceTest.get_stream_data(http_mocker, f"multiple_streams_schemas_{_C_STREAM_NAME}_range_2", stream_name=_C_STREAM_NAME) + + configured_catalog = ( + CatalogBuilder() + .with_stream( + ConfiguredAirbyteStreamBuilder() + .with_name(_STREAM_NAME) + .with_json_schema({"properties": {"age": {"type": "string"}, "name": {"type": "string"}}}) + ) + .with_stream( + ConfiguredAirbyteStreamBuilder() + .with_name(_B_STREAM_NAME) + .with_json_schema({"properties": {"email": {"type": "string"}, "name": {"type": "string"}}}) + ) + .with_stream( + ConfiguredAirbyteStreamBuilder().with_name(_C_STREAM_NAME).with_json_schema({"properties": {"address": {"type": "string"}}}) + ) + .build() + ) + + output = read(self._source, self._config, configured_catalog) + assert len(output.records) == 9 + + assert output.state_messages[0].state.stream.stream_descriptor.name == _STREAM_NAME + assert output.state_messages[1].state.stream.stream_descriptor.name == _B_STREAM_NAME + assert output.state_messages[2].state.stream.stream_descriptor.name == _C_STREAM_NAME + + airbyte_stream_statuses = [AirbyteStreamStatus.COMPLETE, AirbyteStreamStatus.RUNNING, AirbyteStreamStatus.STARTED] + for output_id in range(3): + assert output.state_messages[output_id].state.stream.stream_state == AirbyteStateBlob(__ab_no_cursor_state_message=True) + expected_status = airbyte_stream_statuses.pop() + assert output.trace_messages[output_id].trace.stream_status.status == expected_status + assert output.trace_messages[output_id + 3].trace.stream_status.status == expected_status + assert output.trace_messages[output_id + 6].trace.stream_status.status == expected_status + + @HttpMocker() + def test_when_read_then_status_and_state_messages_emitted(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "read_records_meta_2", 200) + GoogleSheetSourceTest.get_schema(http_mocker, "read_records_range_2", 200) + GoogleSheetSourceTest.get_stream_data(http_mocker, "read_records_range_with_dimensions_2") + + configured_catalog = ( + CatalogBuilder() + .with_stream( + ConfiguredAirbyteStreamBuilder() + .with_name(_STREAM_NAME) + .with_json_schema({"properties": {"header_1": {"type": ["null", "string"]}, "header_2": {"type": ["null", "string"]}}}) + ) + .build() + ) + + output = read(self._source, self._config, configured_catalog) + assert len(output.records) == 5 + assert output.state_messages[0].state.stream.stream_state == AirbyteStateBlob(__ab_no_cursor_state_message=True) + assert output.state_messages[0].state.stream.stream_descriptor.name == _STREAM_NAME + + assert output.trace_messages[0].trace.stream_status.status == AirbyteStreamStatus.STARTED + assert output.trace_messages[1].trace.stream_status.status == AirbyteStreamStatus.RUNNING + assert output.trace_messages[2].trace.stream_status.status == AirbyteStreamStatus.COMPLETE + + @HttpMocker() + def test_read_429_error(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "read_records_meta", 200) + GoogleSheetSourceTest.get_schema(http_mocker, "read_records_range", 200) + GoogleSheetSourceTest.get_stream_data(http_mocker, "rate_limit_error", 429) + + configured_catalog = ( + CatalogBuilder() + .with_stream( + ConfiguredAirbyteStreamBuilder() + .with_name(_STREAM_NAME) + .with_json_schema({"properties": {"header_1": {"type": ["null", "string"]}, "header_2": {"type": ["null", "string"]}}}) + ) + .build() + ) + + with patch("time.sleep"), patch("backoff._sync._maybe_call", side_effect=lambda value: 1): + output = read(self._source, self._config, configured_catalog) + + expected_message = "Stopped syncing process due to rate limits. Rate limit has been reached. Please try later or request a higher quota for your account." + assert output.errors[0].trace.error.message == expected_message + + @HttpMocker() + def test_read_403_error(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "read_records_meta", 200) + GoogleSheetSourceTest.get_schema(http_mocker, "read_records_range", 200) + GoogleSheetSourceTest.get_stream_data(http_mocker, "invalid_permissions", 403) + + configured_catalog = ( + CatalogBuilder() + .with_stream( + ConfiguredAirbyteStreamBuilder() + .with_name(_STREAM_NAME) + .with_json_schema({"properties": {"header_1": {"type": ["null", "string"]}, "header_2": {"type": ["null", "string"]}}}) + ) + .build() + ) + + output = read(self._source, self._config, configured_catalog) + + expected_message = f"Stopped syncing process. The authenticated Google Sheets user does not have permissions to view the spreadsheet with id {_SPREADSHEET_ID}. Please ensure the authenticated user has access to the Spreadsheet and reauthenticate. If the issue persists, contact support" + assert output.errors[0].trace.error.message == expected_message + + @HttpMocker() + def test_read_500_error(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "read_records_meta", 200) + GoogleSheetSourceTest.get_schema(http_mocker, "read_records_range", 200) + GoogleSheetSourceTest.get_stream_data(http_mocker, "internal_server_error", 500) + + configured_catalog = ( + CatalogBuilder() + .with_stream( + ConfiguredAirbyteStreamBuilder() + .with_name(_STREAM_NAME) + .with_json_schema({"properties": {"header_1": {"type": ["null", "string"]}, "header_2": {"type": ["null", "string"]}}}) + ) + .build() + ) + + with patch("time.sleep"), patch("backoff._sync._maybe_call", side_effect=lambda value: 1): + output = read(self._source, self._config, configured_catalog) + + expected_message = "Stopped syncing process. There was an issue with the Google Sheets API. This is usually a temporary issue from Google's side. Please try again. If this issue persists, contact support" + assert output.errors[0].trace.error.message == expected_message + + @HttpMocker() + def test_read_empty_sheet(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "read_records_meta", 200) + GoogleSheetSourceTest.get_schema(http_mocker, "read_records_range_empty", 200) + + configured_catalog = ( + CatalogBuilder() + .with_stream( + ConfiguredAirbyteStreamBuilder() + .with_name(_STREAM_NAME) + .with_json_schema({"properties": {"header_1": {"type": ["null", "string"]}, "header_2": {"type": ["null", "string"]}}}) + ) + .build() + ) + + output = read(self._source, self._config, configured_catalog) + expected_message = f"Unexpected return result: Sheet {_STREAM_NAME} was expected to contain data on exactly 1 sheet. " + assert output.errors[0].trace.error.internal_message == expected_message + + @HttpMocker() + def test_read_expected_data_on_1_sheet(self, http_mocker: HttpMocker) -> None: + GoogleSheetSourceTest.get_streams(http_mocker, "read_records_meta", 200) + GoogleSheetSourceTest.get_schema(http_mocker, "read_records_range_with_unexpected_extra_sheet", 200) + + configured_catalog = ( + CatalogBuilder() + .with_stream( + ConfiguredAirbyteStreamBuilder() + .with_name(_STREAM_NAME) + .with_json_schema({"properties": {"header_1": {"type": ["null", "string"]}, "header_2": {"type": ["null", "string"]}}}) + ) + .build() + ) + + output = read(self._source, self._config, configured_catalog) + expected_message = f"Unexpected return result: Sheet {_STREAM_NAME} was expected to contain data on exactly 1 sheet. " + assert output.errors[0].trace.error.internal_message == expected_message diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/auth_invalid_client.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/auth_invalid_client.json new file mode 100644 index 000000000000..a89b0f15cfc6 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/auth_invalid_client.json @@ -0,0 +1,4 @@ +{ + "error": "invalid_client", + "error_description": "Unauthorized" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/auth_response.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/auth_response.json new file mode 100644 index 000000000000..806181194f95 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/auth_response.json @@ -0,0 +1,7 @@ +{ + "access_token": "ya29.32498574648763487543", + "expires_in": 3599, + "scope": "https://www.googleapis.com/auth/drive.readonly https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/spreadsheets openid https://www.googleapis.com/auth/spreadsheets.readonly https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile", + "token_type": "Bearer", + "id_token": "eyfaketoken43857463853746438576" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/check_duplicate_headers.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/check_duplicate_headers.json new file mode 100644 index 000000000000..63fce7c02f71 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/check_duplicate_headers.json @@ -0,0 +1,307 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 1, + "columnCount": 2 + } + }, + "data": [ + { + "rowData": [ + { + "values": [ + { + "userEnteredValue": { + "stringValue": "header1" + }, + "effectiveValue": { + "stringValue": "header1" + }, + "formattedValue": "header1", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + }, + { + "userEnteredValue": { + "stringValue": "header1" + }, + "effectiveValue": { + "stringValue": "header1" + }, + "formattedValue": "header1", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + }, + { + "userEnteredValue": { + "stringValue": "header2" + }, + "effectiveValue": { + "stringValue": "header2" + }, + "formattedValue": "header2", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + } + ] + } + ], + "rowMetadata": [ + { + "pixelSize": 21 + } + ], + "columnMetadata": [ + { + "pixelSize": 100 + }, + { + "pixelSize": 100 + } + ] + } + ] + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/check_succeeded_meta.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/check_succeeded_meta.json new file mode 100644 index 000000000000..0620b50c1692 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/check_succeeded_meta.json @@ -0,0 +1,149 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 1, + "columnCount": 1 + } + } + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/check_succeeded_range.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/check_succeeded_range.json new file mode 100644 index 000000000000..425ef7fe8991 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/check_succeeded_range.json @@ -0,0 +1,163 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 1, + "columnCount": 1 + } + }, + "data": [ + { + "rowMetadata": [ + { + "pixelSize": 21 + } + ], + "columnMetadata": [ + { + "pixelSize": 100 + } + ] + } + ] + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/check_wrong_range.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/check_wrong_range.json new file mode 100644 index 000000000000..770d4217b157 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/check_wrong_range.json @@ -0,0 +1,189 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 1, + "columnCount": 1 + } + }, + "data": [ + { + "rowMetadata": [ + { + "pixelSize": 21 + } + ], + "columnMetadata": [ + { + "pixelSize": 100 + } + ] + } + ] + }, + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 1, + "columnCount": 1 + } + }, + "data": [ + { + "rowMetadata": [ + { + "pixelSize": 21 + } + ], + "columnMetadata": [ + { + "pixelSize": 100 + } + ] + } + ] + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/internal_server_error.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/internal_server_error.json new file mode 100644 index 000000000000..a8b857aaae2b --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/internal_server_error.json @@ -0,0 +1,7 @@ +{ + "error": { + "code": 500, + "message": "Interval Server error", + "status": "INTERNAL_SERVER_ERROR" + } +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/invalid_link.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/invalid_link.json new file mode 100644 index 000000000000..5418c5798488 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/invalid_link.json @@ -0,0 +1,7 @@ +{ + "error": { + "code": 404, + "message": "Requested entity was not found.", + "status": "NOT_FOUND" + } +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/invalid_permissions.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/invalid_permissions.json new file mode 100644 index 000000000000..25e5cf638811 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/invalid_permissions.json @@ -0,0 +1,7 @@ +{ + "error": { + "code": 403, + "message": "The caller does not have right permissions", + "status": "NOT_PERMISSIONS" + } +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_a_stream_name_range.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_a_stream_name_range.json new file mode 100644 index 000000000000..50ea0676590b --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_a_stream_name_range.json @@ -0,0 +1,262 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 4, + "columnCount": 2 + } + }, + "data": [ + { + "rowData": [ + { + "values": [ + { + "userEnteredValue": { + "stringValue": "name" + }, + "effectiveValue": { + "stringValue": "name" + }, + "formattedValue": "name", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + }, + { + "userEnteredValue": { + "stringValue": "age" + }, + "effectiveValue": { + "stringValue": "age" + }, + "formattedValue": "age", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + } + ] + } + ], + "rowMetadata": [ + { + "pixelSize": 21 + } + ], + "columnMetadata": [ + { + "pixelSize": 100 + }, + { + "pixelSize": 100 + } + ] + } + ] + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_a_stream_name_range_2.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_a_stream_name_range_2.json new file mode 100644 index 000000000000..8dd6f2bbae1c --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_a_stream_name_range_2.json @@ -0,0 +1,14 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "valueRanges": [ + { + "range": "a_stream_name!A2:B4", + "majorDimension": "ROWS", + "values": [ + ["name1", "22"], + ["name2", "24"], + ["name3", "25"] + ] + } + ] +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_b_stream_name_range.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_b_stream_name_range.json new file mode 100644 index 000000000000..f2cdc9e0f92e --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_b_stream_name_range.json @@ -0,0 +1,262 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 1855086503, + "title": "b_stream_name", + "index": 1, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 3, + "columnCount": 2 + } + }, + "data": [ + { + "rowData": [ + { + "values": [ + { + "userEnteredValue": { + "stringValue": "name" + }, + "effectiveValue": { + "stringValue": "name" + }, + "formattedValue": "name", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + }, + { + "userEnteredValue": { + "stringValue": "email" + }, + "effectiveValue": { + "stringValue": "email" + }, + "formattedValue": "email", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + } + ] + } + ], + "rowMetadata": [ + { + "pixelSize": 21 + } + ], + "columnMetadata": [ + { + "pixelSize": 100 + }, + { + "pixelSize": 129 + } + ] + } + ] + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_b_stream_name_range_2.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_b_stream_name_range_2.json new file mode 100644 index 000000000000..f565de883a42 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_b_stream_name_range_2.json @@ -0,0 +1,13 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "valueRanges": [ + { + "range": "b_stream_name!A2:B3", + "majorDimension": "ROWS", + "values": [ + ["name1", "name1@fake.com"], + ["name2", "name2@fake.com"] + ] + } + ] +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_c_stream_name_range.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_c_stream_name_range.json new file mode 100644 index 000000000000..053acc1bb66b --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_c_stream_name_range.json @@ -0,0 +1,214 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 1295940323, + "title": "c_stream_name", + "index": 2, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 5, + "columnCount": 1 + } + }, + "data": [ + { + "rowData": [ + { + "values": [ + { + "userEnteredValue": { + "stringValue": "address" + }, + "effectiveValue": { + "stringValue": "address" + }, + "formattedValue": "address", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + } + ] + } + ], + "rowMetadata": [ + { + "pixelSize": 21 + } + ], + "columnMetadata": [ + { + "pixelSize": 100 + } + ] + } + ] + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_c_stream_name_range_2.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_c_stream_name_range_2.json new file mode 100644 index 000000000000..4e03570e3c57 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_c_stream_name_range_2.json @@ -0,0 +1,10 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "valueRanges": [ + { + "range": "c_stream_name!A2:A5", + "majorDimension": "ROWS", + "values": [["969 m street"], ["969"], ["78"], ["89 washington st"]] + } + ] +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_meta.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_meta.json new file mode 100644 index 000000000000..76483160e209 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/multiple_streams_schemas_meta.json @@ -0,0 +1,173 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 4, + "columnCount": 2 + } + } + }, + { + "properties": { + "sheetId": 1855086503, + "title": "b_stream_name", + "index": 1, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 3, + "columnCount": 2 + } + } + }, + { + "properties": { + "sheetId": 1295940323, + "title": "c_stream_name", + "index": 2, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 5, + "columnCount": 1 + } + } + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/names_conversion_range.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/names_conversion_range.json new file mode 100644 index 000000000000..3fd4fad8d83b --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/names_conversion_range.json @@ -0,0 +1,262 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 1, + "columnCount": 2 + } + }, + "data": [ + { + "rowData": [ + { + "values": [ + { + "userEnteredValue": { + "stringValue": "1 тест" + }, + "effectiveValue": { + "stringValue": "1 тест" + }, + "formattedValue": "1 тест", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + }, + { + "userEnteredValue": { + "stringValue": "header2" + }, + "effectiveValue": { + "stringValue": "header2" + }, + "formattedValue": "header2", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + } + ] + } + ], + "rowMetadata": [ + { + "pixelSize": 21 + } + ], + "columnMetadata": [ + { + "pixelSize": 100 + }, + { + "pixelSize": 100 + } + ] + } + ] + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/no_rows_meta.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/no_rows_meta.json new file mode 100644 index 000000000000..bf29bb4d5f4a --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/no_rows_meta.json @@ -0,0 +1,149 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 0, + "columnCount": 0 + } + } + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/no_rows_range.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/no_rows_range.json new file mode 100644 index 000000000000..db957b475846 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/no_rows_range.json @@ -0,0 +1,150 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 0, + "columnCount": 0 + } + }, + "data": [] + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/non_grid_sheet_meta.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/non_grid_sheet_meta.json new file mode 100644 index 000000000000..7a9a60587952 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/non_grid_sheet_meta.json @@ -0,0 +1,149 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "potato", + "gridProperties": { + "rowCount": 1, + "columnCount": 2 + } + } + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/only_headers_meta.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/only_headers_meta.json new file mode 100644 index 000000000000..93475bd7e601 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/only_headers_meta.json @@ -0,0 +1,149 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 1, + "columnCount": 2 + } + } + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/only_headers_range.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/only_headers_range.json new file mode 100644 index 000000000000..02dc2c4d2e67 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/only_headers_range.json @@ -0,0 +1,262 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 1, + "columnCount": 2 + } + }, + "data": [ + { + "rowData": [ + { + "values": [ + { + "userEnteredValue": { + "stringValue": "header1" + }, + "effectiveValue": { + "stringValue": "header1" + }, + "formattedValue": "header1", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + }, + { + "userEnteredValue": { + "stringValue": "header2" + }, + "effectiveValue": { + "stringValue": "header2" + }, + "formattedValue": "header2", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + } + ] + } + ], + "rowMetadata": [ + { + "pixelSize": 21 + } + ], + "columnMetadata": [ + { + "pixelSize": 100 + }, + { + "pixelSize": 100 + } + ] + } + ] + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/rate_limit_error.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/rate_limit_error.json new file mode 100644 index 000000000000..d12ee7027fe3 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/rate_limit_error.json @@ -0,0 +1,7 @@ +{ + "error": { + "code": 429, + "message": "Request a higher quota limit", + "status": "RATE_LIMIT" + } +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_meta.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_meta.json new file mode 100644 index 000000000000..da8089aa5b72 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_meta.json @@ -0,0 +1,149 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 3, + "columnCount": 2 + } + } + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_meta_2.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_meta_2.json new file mode 100644 index 000000000000..542d396dbeb1 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_meta_2.json @@ -0,0 +1,149 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 6, + "columnCount": 2 + } + } + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range.json new file mode 100644 index 000000000000..826a3a8dc7a8 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range.json @@ -0,0 +1,262 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 3, + "columnCount": 2 + } + }, + "data": [ + { + "rowData": [ + { + "values": [ + { + "userEnteredValue": { + "stringValue": "header_1" + }, + "effectiveValue": { + "stringValue": "header_1" + }, + "formattedValue": "header_1", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + }, + { + "userEnteredValue": { + "stringValue": "header_2" + }, + "effectiveValue": { + "stringValue": "header_2" + }, + "formattedValue": "header_2", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + } + ] + } + ], + "rowMetadata": [ + { + "pixelSize": 21 + } + ], + "columnMetadata": [ + { + "pixelSize": 100 + }, + { + "pixelSize": 100 + } + ] + } + ] + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range_2.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range_2.json new file mode 100644 index 000000000000..a37bb3de73b2 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range_2.json @@ -0,0 +1,262 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 6, + "columnCount": 2 + } + }, + "data": [ + { + "rowData": [ + { + "values": [ + { + "userEnteredValue": { + "stringValue": "header_1" + }, + "effectiveValue": { + "stringValue": "header_1" + }, + "formattedValue": "header_1", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + }, + { + "userEnteredValue": { + "stringValue": "header_2" + }, + "effectiveValue": { + "stringValue": "header_2" + }, + "formattedValue": "header_2", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + } + ] + } + ], + "rowMetadata": [ + { + "pixelSize": 21 + } + ], + "columnMetadata": [ + { + "pixelSize": 100 + }, + { + "pixelSize": 100 + } + ] + } + ] + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range_empty.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range_empty.json new file mode 100644 index 000000000000..a3b144e23ae1 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range_empty.json @@ -0,0 +1,136 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range_with_dimensions.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range_with_dimensions.json new file mode 100644 index 000000000000..3849091d19fb --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range_with_dimensions.json @@ -0,0 +1,13 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "valueRanges": [ + { + "range": "a_stream_name!A2:B3", + "majorDimension": "ROWS", + "values": [ + ["value_11", "value_12"], + ["value_21", "value_22"] + ] + } + ] +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range_with_dimensions_2.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range_with_dimensions_2.json new file mode 100644 index 000000000000..97f4c72d481f --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range_with_dimensions_2.json @@ -0,0 +1,16 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "valueRanges": [ + { + "range": "a_stream_name!A2:B6", + "majorDimension": "ROWS", + "values": [ + ["value_11", "value_12"], + ["value_21", "value_22"], + ["value_31", "value_32"], + ["value_41", "value_42"], + ["value_51", "value_52"] + ] + } + ] +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range_with_unexpected_extra_sheet.json b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range_with_unexpected_extra_sheet.json new file mode 100644 index 000000000000..9d1599f43837 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/resource/http/response/read_records_range_with_unexpected_extra_sheet.json @@ -0,0 +1,387 @@ +{ + "spreadsheetId": "19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw", + "properties": { + "title": "a_spreadsheet_id", + "locale": "en_US", + "autoRecalc": "ON_CHANGE", + "timeZone": "America/Mexico_City", + "defaultFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "arial,sans,sans-serif", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + "spreadsheetTheme": { + "primaryFontFamily": "Arial", + "themeColors": [ + { + "colorType": "TEXT", + "color": { + "rgbColor": {} + } + }, + { + "colorType": "BACKGROUND", + "color": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + }, + { + "colorType": "ACCENT1", + "color": { + "rgbColor": { + "red": 0.25882354, + "green": 0.52156866, + "blue": 0.95686275 + } + } + }, + { + "colorType": "ACCENT2", + "color": { + "rgbColor": { + "red": 0.91764706, + "green": 0.2627451, + "blue": 0.20784314 + } + } + }, + { + "colorType": "ACCENT3", + "color": { + "rgbColor": { + "red": 0.9843137, + "green": 0.7372549, + "blue": 0.015686275 + } + } + }, + { + "colorType": "ACCENT4", + "color": { + "rgbColor": { + "red": 0.20392157, + "green": 0.65882355, + "blue": 0.3254902 + } + } + }, + { + "colorType": "ACCENT5", + "color": { + "rgbColor": { + "red": 1, + "green": 0.42745098, + "blue": 0.003921569 + } + } + }, + { + "colorType": "ACCENT6", + "color": { + "rgbColor": { + "red": 0.27450982, + "green": 0.7411765, + "blue": 0.7764706 + } + } + }, + { + "colorType": "LINK", + "color": { + "rgbColor": { + "red": 0.06666667, + "green": 0.33333334, + "blue": 0.8 + } + } + } + ] + } + }, + "sheets": [ + { + "properties": { + "sheetId": 0, + "title": "a_stream_name", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 3, + "columnCount": 2 + } + }, + "data": [ + { + "rowData": [ + { + "values": [ + { + "userEnteredValue": { + "stringValue": "header_1" + }, + "effectiveValue": { + "stringValue": "header_1" + }, + "formattedValue": "header_1", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + }, + { + "userEnteredValue": { + "stringValue": "header_2" + }, + "effectiveValue": { + "stringValue": "header_2" + }, + "formattedValue": "header_2", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + } + ] + } + ], + "rowMetadata": [ + { + "pixelSize": 21 + } + ], + "columnMetadata": [ + { + "pixelSize": 100 + }, + { + "pixelSize": 100 + } + ] + } + ] + }, + { + "properties": { + "sheetId": 0, + "title": "a_stream_name_other", + "index": 0, + "sheetType": "GRID", + "gridProperties": { + "rowCount": 3, + "columnCount": 2 + } + }, + "data": [ + { + "rowData": [ + { + "values": [ + { + "userEnteredValue": { + "stringValue": "header_1" + }, + "effectiveValue": { + "stringValue": "header_1" + }, + "formattedValue": "header_1", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + }, + { + "userEnteredValue": { + "stringValue": "header_2" + }, + "effectiveValue": { + "stringValue": "header_2" + }, + "formattedValue": "header_2", + "effectiveFormat": { + "backgroundColor": { + "red": 1, + "green": 1, + "blue": 1 + }, + "padding": { + "top": 2, + "right": 3, + "bottom": 2, + "left": 3 + }, + "horizontalAlignment": "LEFT", + "verticalAlignment": "BOTTOM", + "wrapStrategy": "OVERFLOW_CELL", + "textFormat": { + "foregroundColor": {}, + "fontFamily": "Arial", + "fontSize": 10, + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "foregroundColorStyle": { + "rgbColor": {} + } + }, + "hyperlinkDisplayType": "PLAIN_TEXT", + "backgroundColorStyle": { + "rgbColor": { + "red": 1, + "green": 1, + "blue": 1 + } + } + } + } + ] + } + ], + "rowMetadata": [ + { + "pixelSize": 21 + } + ], + "columnMetadata": [ + { + "pixelSize": 100 + }, + { + "pixelSize": 100 + } + ] + } + ] + } + ], + "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/19gOzIckDX7AB8E7Ikts6KAxNrk3ZGSjLbnkYxxM_HLw/edit?ouid=106175843115957165976" +} diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/test_helpers.py b/airbyte-integrations/connectors/source-google-sheets/unit_tests/test_helpers.py index 5a1408faa0c1..a57d024c6d0c 100644 --- a/airbyte-integrations/connectors/source-google-sheets/unit_tests/test_helpers.py +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/test_helpers.py @@ -7,6 +7,10 @@ import unittest from unittest.mock import Mock, patch +from source_google_sheets.client import GoogleSheetsClient +from source_google_sheets.helpers import Helpers +from source_google_sheets.models import CellData, GridData, RowData, Sheet, SheetProperties, Spreadsheet + from airbyte_cdk.models.airbyte_protocol import ( AirbyteRecordMessage, AirbyteStream, @@ -15,9 +19,7 @@ DestinationSyncMode, SyncMode, ) -from source_google_sheets.client import GoogleSheetsClient -from source_google_sheets.helpers import Helpers -from source_google_sheets.models import CellData, GridData, RowData, Sheet, SheetProperties, Spreadsheet + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-google-sheets/unit_tests/test_stream.py b/airbyte-integrations/connectors/source-google-sheets/unit_tests/test_stream.py index b939910d57f7..54a2e054d91e 100644 --- a/airbyte-integrations/connectors/source-google-sheets/unit_tests/test_stream.py +++ b/airbyte-integrations/connectors/source-google-sheets/unit_tests/test_stream.py @@ -6,14 +6,15 @@ import pytest import requests -from airbyte_cdk.models.airbyte_protocol import AirbyteStateBlob, AirbyteStreamStatus, ConfiguredAirbyteCatalog -from airbyte_cdk.utils import AirbyteTracedException from apiclient import errors from source_google_sheets import SourceGoogleSheets from source_google_sheets.client import GoogleSheetsClient from source_google_sheets.helpers import SCOPES, Helpers from source_google_sheets.models import CellData, GridData, RowData, Sheet, SheetProperties, Spreadsheet +from airbyte_cdk.models.airbyte_protocol import AirbyteStateBlob, AirbyteStreamStatus, ConfiguredAirbyteCatalog +from airbyte_cdk.utils import AirbyteTracedException + def set_http_error_for_google_sheets_client(mocker, resp): mocker.patch.object(GoogleSheetsClient, "__init__", lambda s, credentials, scopes=SCOPES: None) @@ -191,7 +192,7 @@ def test_discover_invalid_credentials_error_message(mocker, invalid_config): source = SourceGoogleSheets() with pytest.raises(AirbyteTracedException) as e: source.discover(logger=mocker.MagicMock(), config=invalid_config) - assert e.value.args[0] == 'Access to the spreadsheet expired or was revoked. Re-authenticate to restore access.' + assert e.value.args[0] == "Access to the spreadsheet expired or was revoked. Re-authenticate to restore access." def test_get_credentials(invalid_config): @@ -223,12 +224,14 @@ def test_read_429_error(mocker, invalid_config, catalog, caplog): sheet1 = "soccer_team" sheet1_columns = frozenset(["arsenal", "chelsea", "manutd", "liverpool"]) sheet1_schema = {"properties": {c: {"type": "string"} for c in sheet1_columns}} - catalog = ConfiguredAirbyteCatalog(streams=catalog((sheet1, sheet1_schema),)) + catalog = ConfiguredAirbyteCatalog( + streams=catalog( + (sheet1, sheet1_schema), + ) + ) with pytest.raises(AirbyteTracedException) as e: next(source.read(logger=logging.getLogger("airbyte"), config=invalid_config, catalog=catalog)) - expected_message = ( - "Rate limit has been reached. Please try later or request a higher quota for your account." - ) + expected_message = "Rate limit has been reached. Please try later or request a higher quota for your account." assert e.value.args[0] == expected_message @@ -243,7 +246,11 @@ def test_read_403_error(mocker, invalid_config, catalog, caplog): sheet1 = "soccer_team" sheet1_columns = frozenset(["arsenal", "chelsea", "manutd", "liverpool"]) sheet1_schema = {"properties": {c: {"type": "string"} for c in sheet1_columns}} - catalog = ConfiguredAirbyteCatalog(streams=catalog((sheet1, sheet1_schema),)) + catalog = ConfiguredAirbyteCatalog( + streams=catalog( + (sheet1, sheet1_schema), + ) + ) with pytest.raises(AirbyteTracedException) as e: next(source.read(logger=logging.getLogger("airbyte"), config=invalid_config, catalog=catalog)) assert ( @@ -265,7 +272,11 @@ def test_read_500_error(mocker, invalid_config, catalog, caplog): sheet1 = "soccer_team" sheet1_columns = frozenset(["arsenal", "chelsea", "manutd", "liverpool"]) sheet1_schema = {"properties": {c: {"type": "string"} for c in sheet1_columns}} - catalog = ConfiguredAirbyteCatalog(streams=catalog((sheet1, sheet1_schema),)) + catalog = ConfiguredAirbyteCatalog( + streams=catalog( + (sheet1, sheet1_schema), + ) + ) with pytest.raises(AirbyteTracedException) as e: next(source.read(logger=logging.getLogger("airbyte"), config=invalid_config, catalog=catalog)) expected_message = ( @@ -303,8 +314,13 @@ def test_read_empty_sheet(invalid_config, mocker, catalog, caplog): sheet1 = "soccer_team" sheet2 = "soccer_team2" sheets = [ - Sheet(properties=SheetProperties(title=t), data=[{"test1": "12", "test2": "123"},]) - for t in [sheet1] + Sheet( + properties=SheetProperties(title=t), + data=[ + {"test1": "12", "test2": "123"}, + ], + ) + for t in [sheet1] ] mocker.patch.object( GoogleSheetsClient, @@ -328,7 +344,11 @@ def test_when_read_then_status_messages_emitted(mocker, spreadsheet, spreadsheet mocker.patch.object(GoogleSheetsClient, "get_values", return_value=spreadsheet_values(spreadsheet_id)) sheet_schema = {"properties": {"ID": {"type": "string"}}} - catalog = ConfiguredAirbyteCatalog(streams=catalog((sheet_name, sheet_schema),)) + catalog = ConfiguredAirbyteCatalog( + streams=catalog( + (sheet_name, sheet_schema), + ) + ) records = list(source.read(logger=logging.getLogger("airbyte"), config=invalid_config, catalog=catalog)) # stream started, stream running, 1 record, stream state, stream completed @@ -346,7 +366,11 @@ def test_when_read_then_state_message_emitted(mocker, spreadsheet, spreadsheet_v mocker.patch.object(GoogleSheetsClient, "get_values", return_value=spreadsheet_values(spreadsheet_id)) sheet_schema = {"properties": {"ID": {"type": "string"}}} - catalog = ConfiguredAirbyteCatalog(streams=catalog((sheet_name, sheet_schema),)) + catalog = ConfiguredAirbyteCatalog( + streams=catalog( + (sheet_name, sheet_schema), + ) + ) records = list(source.read(logger=logging.getLogger("airbyte"), config=invalid_config, catalog=catalog)) # stream started, stream running, 1 record, stream state, stream completed diff --git a/airbyte-integrations/connectors/source-google-tasks/metadata.yaml b/airbyte-integrations/connectors/source-google-tasks/metadata.yaml index f8fe26e98ff5..6489dc9fe119 100644 --- a/airbyte-integrations/connectors/source-google-tasks/metadata.yaml +++ b/airbyte-integrations/connectors/source-google-tasks/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-google-tasks connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 751c2519-1446-416e-9736-9b98585f8125 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.9 dockerRepository: airbyte/source-google-tasks githubIssueLabel: source-google-tasks icon: icon.svg diff --git a/airbyte-integrations/connectors/source-google-webfonts/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-google-webfonts/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-google-webfonts/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-google-webfonts/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-google-webfonts/metadata.yaml b/airbyte-integrations/connectors/source-google-webfonts/metadata.yaml index 81c2cfb27d4d..b16f8e880140 100644 --- a/airbyte-integrations/connectors/source-google-webfonts/metadata.yaml +++ b/airbyte-integrations/connectors/source-google-webfonts/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: a68fbcde-b465-4ab3-b2a6-b0590a875835 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-google-webfonts documentationUrl: https://docs.airbyte.com/integrations/sources/google-webfonts githubIssueLabel: source-google-webfonts diff --git a/airbyte-integrations/connectors/source-gorgias/manifest.yaml b/airbyte-integrations/connectors/source-gorgias/manifest.yaml index be154ceb9b9f..4d8ed27bd736 100644 --- a/airbyte-integrations/connectors/source-gorgias/manifest.yaml +++ b/airbyte-integrations/connectors/source-gorgias/manifest.yaml @@ -50,6 +50,8 @@ definitions: cursor_field: created_datetime cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%d %H:%M:%S+00:00" datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" start_datetime: type: MinMaxDatetime @@ -114,6 +116,8 @@ definitions: cursor_field: updated_datetime cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%d %H:%M:%S+00:00" datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" start_datetime: type: MinMaxDatetime @@ -180,6 +184,8 @@ definitions: cursor_field: updated_datetime cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%d %H:%M:%S+00:00" datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" start_datetime: type: MinMaxDatetime @@ -244,6 +250,8 @@ definitions: cursor_field: created_datetime cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%d %H:%M:%S+00:00" datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" start_datetime: type: MinMaxDatetime @@ -308,6 +316,8 @@ definitions: cursor_field: updated_datetime cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%d %H:%M:%S+00:00" datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" start_datetime: type: MinMaxDatetime @@ -372,6 +382,8 @@ definitions: cursor_field: created_datetime cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%d %H:%M:%S+00:00" datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" start_datetime: type: MinMaxDatetime @@ -436,6 +448,8 @@ definitions: cursor_field: created_datetime cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%d %H:%M:%S+00:00" datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" start_datetime: type: MinMaxDatetime @@ -500,6 +514,8 @@ definitions: cursor_field: created_datetime cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%d %H:%M:%S+00:00" datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" start_datetime: type: MinMaxDatetime @@ -564,6 +580,8 @@ definitions: cursor_field: created_datetime cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%d %H:%M:%S+00:00" datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" start_datetime: type: MinMaxDatetime @@ -628,6 +646,8 @@ definitions: cursor_field: created_datetime cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%d %H:%M:%S+00:00" datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" start_datetime: type: MinMaxDatetime @@ -692,6 +712,8 @@ definitions: cursor_field: created_datetime cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%d %H:%M:%S+00:00" datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" start_datetime: type: MinMaxDatetime @@ -756,6 +778,8 @@ definitions: cursor_field: created_datetime cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%d %H:%M:%S+00:00" datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" start_datetime: type: MinMaxDatetime @@ -820,6 +844,8 @@ definitions: cursor_field: created_datetime cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%d %H:%M:%S+00:00" datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" start_datetime: type: MinMaxDatetime @@ -884,6 +910,8 @@ definitions: cursor_field: created_datetime cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%d %H:%M:%S+00:00" datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" start_datetime: type: MinMaxDatetime @@ -948,6 +976,8 @@ definitions: cursor_field: created_datetime cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%d %H:%M:%S+00:00" datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" start_datetime: type: MinMaxDatetime @@ -1020,6 +1050,8 @@ definitions: cursor_field: created_datetime cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%d %H:%M:%S+00:00" datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" start_datetime: type: MinMaxDatetime @@ -1112,114 +1144,148 @@ metadata: messages: true users: true views_items: true + yamlComponents: + streams: + account: + - incrementalSync + customers: + - incrementalSync + custom-fields: + - incrementalSync + events: + - incrementalSync + integrations: + - incrementalSync + jobs: + - incrementalSync + macros: + - incrementalSync + views: + - incrementalSync + rules: + - incrementalSync + satisfaction-surveys: + - incrementalSync + tags: + - incrementalSync + teams: + - incrementalSync + tickets: + - incrementalSync + messages: + - incrementalSync + users: + - incrementalSync + views_items: + - incrementalSync testedStreams: account: - streamHash: 35c0cadba84dbdeff763b400c40d63332063f0ca + streamHash: d744624c7484b6696d00b448a4873d44577fe6d4 hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true customers: - streamHash: f4fa57dc21e535ec9b5b8b772ca89d3c7587e2e9 + streamHash: ca559007a6bf263aeaf11dbb9b96295e64555c2f hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true custom-fields: - hasRecords: true - streamHash: c19cf92c5bde4806aba375c664479a9d36a61896 + streamHash: 158d74d4ec15ddb393fcd93410df78b504b07144 hasResponse: true - primaryKeysAreUnique: true - primaryKeysArePresent: true responsesAreSuccessful: true - events: hasRecords: true - streamHash: 49ac78abe633a9c4fce0778e183d9bba24473308 - hasResponse: true - primaryKeysAreUnique: true primaryKeysArePresent: true + primaryKeysAreUnique: true + events: + streamHash: 180fd5e4dcc2a7c6c78011249aa2a8bdc8910c4f + hasResponse: true responsesAreSuccessful: true - integrations: hasRecords: true - streamHash: d160fd9e3e9e1a62d7d8c789126191c998476934 - hasResponse: true - primaryKeysAreUnique: true primaryKeysArePresent: true + primaryKeysAreUnique: true + integrations: + streamHash: d7d971ef58a4eab715c2a3609213d5d65e8fefca + hasResponse: true responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true jobs: - streamHash: e705479af8c394a6a042d19943fde3c7c574df91 + streamHash: ed6c3e3ed40bb137f8ef8748435bd2c83b9e3d74 hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true macros: - hasRecords: true - streamHash: bebe6bd207f5507cc2b92614e82608fe5488acd7 + streamHash: 955fe8be382283bd12e9b461f8c6dea96d521480 hasResponse: true - primaryKeysAreUnique: true - primaryKeysArePresent: true responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true views: - streamHash: fd8ae05b480c0312b7780da2d0ecc1831779db78 + streamHash: f6f2fec4decd9c5657d47007cf7ca50c74798f5d hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true rules: - streamHash: 5df2be309fb2e0d9ddc5903d1f1177e8ddb0e551 + streamHash: 1bbb2ded40d6ec6ac514a7a4d031824fb72c8671 hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true satisfaction-surveys: - streamHash: 83a105ff8474fa6f58bb39fa09006938444f10ce + streamHash: 78392e54d6a852c07c6b68f1268167a523a1fed8 hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true tags: - streamHash: 3715b9466b20abc4f5bdc222cd4dde77d65b0344 + streamHash: d08f102f1d1d60817d0dc073daebc13c9589d2fc hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true teams: - streamHash: 4c753176b11815ff3da55d6806ee16839b9c0c7d + streamHash: 0ef08ffb72fa8e5404c7ceb3d350be90cf39cbcb hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true tickets: - streamHash: 5086078a027afddc63a8a323be7c7208b47b109c + streamHash: b735a8354cf6d5ad5034612614d137a60a0420d8 hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true messages: - streamHash: d57f0f0ff7940081368628d20293453fd5807e0a + streamHash: 5fb8111396993c073be7704df24dac5c8bdb3446 hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true users: - streamHash: 4c462adb8d9112b0f7d54e967939cdb8627ba15f + streamHash: 5c44f43aba3bdbdddb0bce2483d1a2baf7591307 hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true views_items: - streamHash: 95d5e0af74d9233ab6a07c00834b2d3b993b4496 + streamHash: 3fb81032865e8878b9d3d811f070b8e09c2d82cf hasResponse: true responsesAreSuccessful: true hasRecords: true @@ -1420,6 +1486,19 @@ schemas: - object - "null" properties: + notification: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + message: + type: + - string + - "null" status: type: - string @@ -1440,6 +1519,10 @@ schemas: type: - string - "null" + custom_fields: + type: + - object + - "null" email: type: - string @@ -1693,12 +1776,103 @@ schemas: - "null" created_datetime: type: string + ended_datetime: + type: + - string + - "null" id: type: number info: type: - object - "null" + properties: + _composed_files: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + absolute_path: + type: + - string + - "null" + content_type: + type: + - string + - "null" + name: + type: + - string + - "null" + size: + type: + - number + - "null" + url: + type: + - string + - "null" + _tickets_files: + type: + - array + - "null" + archive: + type: + - object + - "null" + properties: + absolute_path: + type: + - string + - "null" + content_type: + type: + - string + - "null" + name: + type: + - string + - "null" + size: + type: + - number + - "null" + url: + type: + - string + - "null" + custom_fields_mapping: + type: + - object + - "null" + custom_fields_order: + type: + - array + - "null" + items: + type: + - string + - "null" + iteration_over: + type: + - boolean + - "null" + progress_count: + type: + - number + - "null" + progress_cursor: + type: + - number + - "null" + timezone: + type: + - string + - "null" params: type: - object @@ -2053,6 +2227,10 @@ schemas: type: - string - "null" + started_datetime: + type: + - string + - "null" status: type: - string @@ -7371,6 +7549,10 @@ schemas: - "null" created_datetime: type: string + custom_fields: + type: + - object + - "null" email: type: - string diff --git a/airbyte-integrations/connectors/source-gorgias/metadata.yaml b/airbyte-integrations/connectors/source-gorgias/metadata.yaml index dd2adedb848c..19e16a9055a9 100644 --- a/airbyte-integrations/connectors/source-gorgias/metadata.yaml +++ b/airbyte-integrations/connectors/source-gorgias/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-gorgias connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.3@sha256:9214270d83304213977c08e91fd9c55a98819543dbbf0df25a4356299af4f3ab connectorSubtype: api connectorType: source definitionId: 9fdc3733-c51a-4129-9be5-7e9ad6eab6ac - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-gorgias githubIssueLabel: source-gorgias icon: icon.svg diff --git a/airbyte-integrations/connectors/source-greenhouse/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-greenhouse/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-greenhouse/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-greenhouse/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-greenhouse/main.py b/airbyte-integrations/connectors/source-greenhouse/main.py index e08a14b429fd..378686d959b4 100644 --- a/airbyte-integrations/connectors/source-greenhouse/main.py +++ b/airbyte-integrations/connectors/source-greenhouse/main.py @@ -4,5 +4,6 @@ from source_greenhouse.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-greenhouse/metadata.yaml b/airbyte-integrations/connectors/source-greenhouse/metadata.yaml index 4caffdf6826f..04643042e7ad 100644 --- a/airbyte-integrations/connectors/source-greenhouse/metadata.yaml +++ b/airbyte-integrations/connectors/source-greenhouse/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - harvest.greenhouse.io connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 59f1e50a-331f-4f09-b3e8-2e8d4d355f44 - dockerImageTag: 0.5.25 + dockerImageTag: 0.5.29 dockerRepository: airbyte/source-greenhouse documentationUrl: https://docs.airbyte.com/integrations/sources/greenhouse githubIssueLabel: source-greenhouse diff --git a/airbyte-integrations/connectors/source-greenhouse/poetry.lock b/airbyte-integrations/connectors/source-greenhouse/poetry.lock index 220902354c49..13337dec58a1 100644 --- a/airbyte-integrations/connectors/source-greenhouse/poetry.lock +++ b/airbyte-integrations/connectors/source-greenhouse/poetry.lock @@ -62,19 +62,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -140,127 +140,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -295,20 +282,20 @@ fast-validation = ["fastjsonschema"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -386,13 +373,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -505,13 +492,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -592,54 +579,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -903,33 +890,33 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -970,13 +957,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1001,81 +988,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-greenhouse/pyproject.toml b/airbyte-integrations/connectors/source-greenhouse/pyproject.toml index 15818c9e418a..356cdea01058 100644 --- a/airbyte-integrations/connectors/source-greenhouse/pyproject.toml +++ b/airbyte-integrations/connectors/source-greenhouse/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.5.25" +version = "0.5.29" name = "source-greenhouse" description = "Source implementation for Greenhouse." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-greenhouse/source_greenhouse/source.py b/airbyte-integrations/connectors/source-greenhouse/source_greenhouse/source.py index dabad443b366..2be3db68fbff 100644 --- a/airbyte-integrations/connectors/source-greenhouse/source_greenhouse/source.py +++ b/airbyte-integrations/connectors/source-greenhouse/source_greenhouse/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-greenhouse/unit_tests/conftest.py b/airbyte-integrations/connectors/source-greenhouse/unit_tests/conftest.py index 605c45c1ea2f..463a456b4aaa 100644 --- a/airbyte-integrations/connectors/source-greenhouse/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-greenhouse/unit_tests/conftest.py @@ -5,9 +5,10 @@ from unittest.mock import MagicMock, Mock import pytest -from airbyte_cdk.sources.streams import Stream from source_greenhouse.components import GreenHouseSlicer, GreenHouseSubstreamSlicer +from airbyte_cdk.sources.streams import Stream + @pytest.fixture def greenhouse_slicer(): @@ -18,4 +19,11 @@ def greenhouse_slicer(): @pytest.fixture def greenhouse_substream_slicer(): parent_stream = MagicMock(spec=Stream) - return GreenHouseSubstreamSlicer(cursor_field='cursor_field', stream_slice_field='slice_field', parent_stream=parent_stream, parent_key='parent_key', parameters={}, request_cursor_field=None) + return GreenHouseSubstreamSlicer( + cursor_field="cursor_field", + stream_slice_field="slice_field", + parent_stream=parent_stream, + parent_key="parent_key", + parameters={}, + request_cursor_field=None, + ) diff --git a/airbyte-integrations/connectors/source-greenhouse/unit_tests/test_components.py b/airbyte-integrations/connectors/source-greenhouse/unit_tests/test_components.py index 48db265f477f..27bab35ef71e 100644 --- a/airbyte-integrations/connectors/source-greenhouse/unit_tests/test_components.py +++ b/airbyte-integrations/connectors/source-greenhouse/unit_tests/test_components.py @@ -6,9 +6,10 @@ from unittest.mock import MagicMock, Mock import pytest -from airbyte_cdk.sources.streams import Stream from source_greenhouse.components import GreenHouseSlicer, GreenHouseSubstreamSlicer +from airbyte_cdk.sources.streams import Stream + def test_slicer(greenhouse_slicer): date_time = "2022-09-05T10:10:10.000000Z" @@ -53,17 +54,12 @@ def test_sub_slicer(last_record, expected, records): @pytest.mark.parametrize( "stream_state, cursor_field, expected_state", [ - ({'cursor_field_1': '2022-09-05T10:10:10.000Z'}, 'cursor_field_1', {'cursor_field_1': '2022-09-05T10:10:10.000Z'}), - ({'cursor_field_2': '2022-09-05T10:10:100000Z'}, 'cursor_field_3', {}), - ({'cursor_field_4': None}, 'cursor_field_4', {}), - ({'cursor_field_5': ''}, 'cursor_field_5', {}), + ({"cursor_field_1": "2022-09-05T10:10:10.000Z"}, "cursor_field_1", {"cursor_field_1": "2022-09-05T10:10:10.000Z"}), + ({"cursor_field_2": "2022-09-05T10:10:100000Z"}, "cursor_field_3", {}), + ({"cursor_field_4": None}, "cursor_field_4", {}), + ({"cursor_field_5": ""}, "cursor_field_5", {}), ], - ids=[ - "cursor_value_present", - "cursor_value_not_present", - "cursor_value_is_None", - "cursor_value_is_empty_string" - ] + ids=["cursor_value_present", "cursor_value_not_present", "cursor_value_is_None", "cursor_value_is_empty_string"], ) def test_slicer_set_initial_state(stream_state, cursor_field, expected_state): slicer = GreenHouseSlicer(cursor_field=cursor_field, parameters={}, request_cursor_field=None) @@ -71,36 +67,30 @@ def test_slicer_set_initial_state(stream_state, cursor_field, expected_state): slicer.set_initial_state(stream_state) assert slicer.get_stream_state() == expected_state + @pytest.mark.parametrize( "stream_state, initial_state, expected_state", [ ( - {'id1': {'cursor_field': '2023-01-01T10:00:00.000Z'}}, - {'id2': {'cursor_field': '2023-01-02T11:00:00.000Z'}}, - { - 'id1': {'cursor_field': '2023-01-01T10:00:00.000Z'}, - 'id2': {'cursor_field': '2023-01-02T11:00:00.000Z'} - } + {"id1": {"cursor_field": "2023-01-01T10:00:00.000Z"}}, + {"id2": {"cursor_field": "2023-01-02T11:00:00.000Z"}}, + {"id1": {"cursor_field": "2023-01-01T10:00:00.000Z"}, "id2": {"cursor_field": "2023-01-02T11:00:00.000Z"}}, ), ( - {'id1': {'cursor_field': '2023-01-01T10:00:00.000Z'}}, - {'id1': {'cursor_field': '2023-01-01T09:00:00.000Z'}}, - {'id1': {'cursor_field': '2023-01-01T10:00:00.000Z'}} - ), - ( - {}, - {}, - {} + {"id1": {"cursor_field": "2023-01-01T10:00:00.000Z"}}, + {"id1": {"cursor_field": "2023-01-01T09:00:00.000Z"}}, + {"id1": {"cursor_field": "2023-01-01T10:00:00.000Z"}}, ), + ({}, {}, {}), ], ids=[ "stream_state and initial_state have different keys", "stream_state and initial_state have overlapping keys with different values", - "stream_state and initial_state are empty" - ] + "stream_state and initial_state are empty", + ], ) def test_substream_set_initial_state(greenhouse_substream_slicer, stream_state, initial_state, expected_state): - slicer = greenhouse_substream_slicer + slicer = greenhouse_substream_slicer # Set initial state slicer._state = initial_state slicer.set_initial_state(stream_state) @@ -110,27 +100,11 @@ def test_substream_set_initial_state(greenhouse_substream_slicer, stream_state, @pytest.mark.parametrize( "first_record, second_record, expected_result", [ - ( - {'cursor_field': '2023-01-01T00:00:00.000Z'}, - {'cursor_field': '2023-01-02T00:00:00.000Z'}, - False - ), - ( - {'cursor_field': '2023-02-01T00:00:00.000Z'}, - {'cursor_field': '2023-01-01T00:00:00.000Z'}, - True - ), - ( - {'cursor_field': '2023-01-02T00:00:00.000Z'}, - {'cursor_field': ''}, - True - ), - ( - {'cursor_field': ''}, - {'cursor_field': '2023-01-02T00:00:00.000Z'}, - False - ), - ] + ({"cursor_field": "2023-01-01T00:00:00.000Z"}, {"cursor_field": "2023-01-02T00:00:00.000Z"}, False), + ({"cursor_field": "2023-02-01T00:00:00.000Z"}, {"cursor_field": "2023-01-01T00:00:00.000Z"}, True), + ({"cursor_field": "2023-01-02T00:00:00.000Z"}, {"cursor_field": ""}, True), + ({"cursor_field": ""}, {"cursor_field": "2023-01-02T00:00:00.000Z"}, False), + ], ) def test_is_greater_than_or_equal(greenhouse_substream_slicer, first_record, second_record, expected_result): slicer = greenhouse_substream_slicer diff --git a/airbyte-integrations/connectors/source-greythr/README.md b/airbyte-integrations/connectors/source-greythr/README.md new file mode 100644 index 000000000000..65b91a0c0f40 --- /dev/null +++ b/airbyte-integrations/connectors/source-greythr/README.md @@ -0,0 +1,33 @@ +# GreytHr +This directory contains the manifest-only connector for `source-greythr`. + +The GreytHR Connector for Airbyte allows seamless integration with the GreytHR platform, enabling users to automate the extraction and synchronization of employee management and payroll data into their preferred destinations for reporting, analytics, or further processing. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-greythr:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-greythr build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-greythr test +``` + diff --git a/airbyte-integrations/connectors/source-greythr/acceptance-test-config.yml b/airbyte-integrations/connectors/source-greythr/acceptance-test-config.yml new file mode 100644 index 000000000000..b71ee7378964 --- /dev/null +++ b/airbyte-integrations/connectors/source-greythr/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-greythr:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-greythr/icon.svg b/airbyte-integrations/connectors/source-greythr/icon.svg new file mode 100644 index 000000000000..f840636b361c --- /dev/null +++ b/airbyte-integrations/connectors/source-greythr/icon.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-greythr/manifest.yaml b/airbyte-integrations/connectors/source-greythr/manifest.yaml new file mode 100644 index 000000000000..9d553363715a --- /dev/null +++ b/airbyte-integrations/connectors/source-greythr/manifest.yaml @@ -0,0 +1,1047 @@ +version: 6.1.0 + +type: DeclarativeSource + +description: >- + The GreytHR Connector for Airbyte allows seamless integration with the GreytHR + platform, enabling users to automate the extraction and synchronization of + employee management and payroll data into their preferred destinations for + reporting, analytics, or further processing. + +check: + type: CheckStream + stream_names: + - Employees + +definitions: + streams: + Employees: + type: DeclarativeStream + name: Employees + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + requester: + $ref: "#/definitions/base_requester" + path: /employee/v2/employees + http_method: GET + request_headers: + x-greythr-domain: "{{ config[\"domain\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - employeeId + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/Employees" + Users List: + type: DeclarativeStream + name: Users List + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + requester: + $ref: "#/definitions/base_requester" + path: /user/v2/users + http_method: GET + request_headers: + x-greythr-domain: "{{ config[\"domain\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/Users List" + Employees Profile: + type: DeclarativeStream + name: Employees Profile + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /employee/v2/employees/profile + http_method: GET + request_headers: + x-greythr-domain: "{{ config[\"domain\"] }}" + request_parameters: + descRequired: "true" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - employeeId + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/Employees Profile" + Employees Categories: + type: DeclarativeStream + name: Employees Categories + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /employee/v2/employees/categories + http_method: GET + request_headers: + x-greythr-domain: "{{ config[\"domain\"] }}" + request_parameters: + descRequired: "true" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - employeeId + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/Employees Categories" + Employee Bank Details: + type: DeclarativeStream + name: Employee Bank Details + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + requester: + $ref: "#/definitions/base_requester" + path: /employee/v2/employees/bank + http_method: GET + request_headers: + x-greythr-domain: "{{ config[\"domain\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - employeeId + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/Employee Bank Details" + Employees Work Details: + type: DeclarativeStream + name: Employees Work Details + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + requester: + $ref: "#/definitions/base_requester" + path: /employee/v2/employees/work + http_method: GET + request_headers: + x-greythr-domain: "{{ config[\"domain\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - employeeId + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/Employees Work Details" + Employee PF & ESI details: + type: DeclarativeStream + name: Employee PF & ESI details + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + requester: + $ref: "#/definitions/base_requester" + path: /employee/v2/employees/pf + http_method: GET + request_headers: + x-greythr-domain: "{{ config[\"domain\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - employeeId + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/Employee PF & ESI details" + Employee Statutory Details: + type: DeclarativeStream + name: Employee Statutory Details + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + requester: + $ref: "#/definitions/base_requester" + path: /employee/v2/employees/statutory/india + http_method: GET + request_headers: + x-greythr-domain: "{{ config[\"domain\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - employeeId + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/Employee Statutory Details" + Employees Personal Details: + type: DeclarativeStream + name: Employees Personal Details + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + requester: + $ref: "#/definitions/base_requester" + path: /employee/v2/employees/personal + http_method: GET + request_headers: + x-greythr-domain: "{{ config[\"domain\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - employeeId + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/Employees Personal Details" + Employee Separation Details: + type: DeclarativeStream + name: Employee Separation Details + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + requester: + $ref: "#/definitions/base_requester" + path: /employee/v2/employees/separation + http_method: GET + request_headers: + x-greythr-domain: "{{ config[\"domain\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - employeeId + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/Employee Separation Details" + Employee Qualifications Details: + type: DeclarativeStream + name: Employee Qualifications Details + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + requester: + $ref: "#/definitions/base_requester" + path: /employee/v2/employees/qualifications + http_method: GET + request_headers: + x-greythr-domain: "{{ config[\"domain\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/Employee Qualifications Details" + base_requester: + type: HttpRequester + url_base: "{{ config['base_url'] }}" + authenticator: + type: SessionTokenAuthenticator + login_requester: + type: HttpRequester + path: client-token + url_base: https://{{ config['domain'] }}/uas/v1/oauth2 + http_method: POST + authenticator: + type: BasicHttpAuthenticator + password: "{{ config[\"password\"] }}" + username: "{{ config[\"username\"] }}" + request_headers: {} + request_parameters: {} + session_token_path: + - access_token + expiration_duration: P1W + request_authentication: + type: ApiKey + inject_into: + type: RequestOption + field_name: ACCESS-TOKEN + inject_into: header + +streams: + - $ref: "#/definitions/streams/Employees" + - $ref: "#/definitions/streams/Employees Categories" + - $ref: "#/definitions/streams/Employees Profile" + - $ref: "#/definitions/streams/Employees Personal Details" + - $ref: "#/definitions/streams/Employees Work Details" + - $ref: "#/definitions/streams/Employee Separation Details" + - $ref: "#/definitions/streams/Employee Statutory Details" + - $ref: "#/definitions/streams/Employee Bank Details" + - $ref: "#/definitions/streams/Employee PF & ESI details" + - $ref: "#/definitions/streams/Employee Qualifications Details" + - $ref: "#/definitions/streams/Users List" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - base_url + - domain + - username + properties: + domain: + type: string + description: Your GreytHR Host URL + order: 1 + title: Host URL + base_url: + type: string + description: https://api.greythr.com + order: 0 + title: Base URL + password: + type: string + order: 3 + title: Password + always_show: true + airbyte_secret: true + username: + type: string + order: 2 + title: Username + additionalProperties: true + +metadata: + assist: + docsUrl: https://www.getknit.dev/blog/greythr-api-guide + testedStreams: + Employees: + hasRecords: true + streamHash: 28c83fcf7656de194f5722e530d230f8aa5d597d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + Users List: + hasRecords: true + streamHash: 9fabe296a9f240936fe30eac8a9803da1aedd608 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + Employees Profile: + hasRecords: true + streamHash: 4394c8a538b68ec6bd5b5c91ef02d40491a7720f + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + Employees Categories: + hasRecords: true + streamHash: d94a5856f8c3c4d3685bc1ebd8fd92debf751557 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + Employee Bank Details: + hasRecords: true + streamHash: c1abcaabd836f3c73ab660f2e52df64740a2f143 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + Employees Work Details: + hasRecords: true + streamHash: d79f7042c185f1481dd9abb739577f8fecc6574d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + Employee PF & ESI details: + hasRecords: true + streamHash: 0c4d5128674762c7579273943ab279d4c38f6709 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + Employee Statutory Details: + hasRecords: true + streamHash: b0a8289160af4538fca2edf0cec84a15a92ddf14 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + Employees Personal Details: + hasRecords: true + streamHash: 32388a874fce59805a00dab12df7efa9183f3219 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + Employee Separation Details: + hasRecords: true + streamHash: a66bfba7e6973d7c81f705d79e209ca39b272d8b + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + Employee Qualifications Details: + hasRecords: true + streamHash: f9bb303f71084bbd7a04fc072ceb786e7518e722 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + autoImportSchema: + Employees: true + Users List: true + Employees Profile: true + Employees Categories: true + Employee Bank Details: true + Employees Work Details: true + Employee PF & ESI details: true + Employee Statutory Details: true + Employees Personal Details: true + Employee Separation Details: true + Employee Qualifications Details: true + +schemas: + Employees: + type: object + $schema: http://json-schema.org/schema# + required: + - employeeId + properties: + name: + type: + - string + - "null" + email: + type: + - string + - "null" + title: + type: + - string + - "null" + gender: + type: + - string + - "null" + mobile: + type: + - string + - "null" + status: + type: + - number + - "null" + leftorg: + type: + - boolean + - "null" + lastName: + type: + - string + - "null" + firstName: + type: + - string + - "null" + dateOfJoin: + type: + - string + - "null" + employeeId: + type: number + employeeNo: + type: + - string + - "null" + middleName: + type: + - string + - "null" + yearsInJob: + type: + - number + - "null" + dateOfBirth: + type: + - string + - "null" + leavingDate: + type: + - string + - "null" + lastModified: + type: + - string + - "null" + personalEmail: + type: + - string + - "null" + personalEmail2: + type: + - string + - "null" + personalEmail3: + type: + - string + - "null" + prevExperience: + type: + - number + - "null" + yearsInService: + type: + - number + - "null" + probationPeriod: + type: + - number + - "null" + relevantExperience: + type: + - number + - "null" + additionalProperties: true + Users List: + type: object + $schema: http://json-schema.org/schema# + properties: + type: + type: + - number + - "null" + id: + type: + - number + - "null" + admin: + type: + - boolean + - "null" + email: + type: + - string + - "null" + deleted: + type: + - boolean + - "null" + userName: + type: + - string + - "null" + systemPassword: + type: + - boolean + - "null" + additionalProperties: true + Employees Profile: + type: object + $schema: http://json-schema.org/schema# + required: + - employeeId + properties: + twitter: + type: + - string + - "null" + wishDOB: + type: + - string + - "null" + facebook: + type: + - string + - "null" + linkedIn: + type: + - string + - "null" + nickname: + type: + - string + - "null" + biography: + type: + - string + - "null" + employeeId: + type: number + additionalProperties: true + Employees Categories: + type: object + $schema: http://json-schema.org/schema# + required: + - employeeId + properties: + employeeId: + type: number + categoryList: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + value: + type: + - number + - "null" + category: + type: + - number + - "null" + valueDesc: + type: + - string + - "null" + effectiveTo: + type: + - string + - "null" + categoryDesc: + type: + - string + - "null" + effectiveFrom: + type: + - string + - "null" + additionalProperties: true + Employee Bank Details: + type: object + $schema: http://json-schema.org/schema# + required: + - employeeId + properties: + bankName: + type: + - number + - "null" + bankBranch: + type: + - number + - "null" + branchCode: + type: + - string + - "null" + employeeId: + type: number + bankAccountNumber: + type: + - string + - "null" + salaryPaymentMode: + type: + - number + - "null" + additionalProperties: true + Employees Work Details: + type: object + $schema: http://json-schema.org/schema# + required: + - employeeId + properties: + employeeId: + type: number + confirmDate: + type: + - string + - "null" + noticePeriod: + type: + - number + - "null" + onboardingStatus: + type: + - string + - "null" + extendedProbationDays: + type: + - number + - "null" + additionalProperties: true + Employee PF & ESI details: + type: object + $schema: http://json-schema.org/schema# + required: + - employeeId + properties: + uan: + type: + - string + - "null" + pfNumber: + type: + - string + - "null" + employeeId: + type: number + pfEligible: + type: + - boolean + - "null" + esiEligible: + type: + - boolean + - "null" + pfKycLinkedOn: + type: + - string + - "null" + pfExistingMember: + type: + - boolean + - "null" + excessEPFContribution: + type: + - boolean + - "null" + excessEPSContribution: + type: + - boolean + - "null" + additionalProperties: true + Employee Statutory Details: + type: object + $schema: http://json-schema.org/schema# + required: + - employeeId + properties: + disabled: + type: + - boolean + - "null" + birthplace: + type: + - string + - "null" + employeeId: + type: number + expatriate: + type: + - boolean + - "null" + fatherName: + type: + - string + - "null" + isDirector: + type: + - boolean + - "null" + nationality: + type: + - number + - "null" + countryOfOrigin: + type: + - number + - "null" + residentialStatus: + type: + - number + - "null" + additionalProperties: true + Employees Personal Details: + type: object + $schema: http://json-schema.org/schema# + required: + - employeeId + properties: + bloodGroup: + type: + - number + - "null" + employeeId: + type: number + spouseName: + type: + - string + - "null" + maritalStatus: + type: + - number + - "null" + additionalProperties: true + Employee Separation Details: + type: object + $schema: http://json-schema.org/schema# + required: + - employeeId + properties: + leftOrg: + type: + - boolean + - "null" + employeeId: + type: number + leavingDate: + type: + - string + - "null" + leavingReason: + type: + - number + - "null" + fitToBeRehired: + type: + - boolean + - "null" + submissionDate: + type: + - string + - "null" + exitInterviewDate: + type: + - string + - "null" + finalSettlementDate: + type: + - string + - "null" + submittedResignation: + type: + - boolean + - "null" + tentativeLeavingDate: + type: + - string + - "null" + additionalProperties: true + Employee Qualifications Details: + type: object + $schema: http://json-schema.org/schema# + properties: + id: + type: + - number + - "null" + duration: + type: + - string + - "null" + employee: + type: + - number + - "null" + qualArea: + type: + - number + - "null" + qualYear: + type: + - number + - "null" + institute: + type: + - string + - "null" + qualLevel: + type: + - number + - "null" + qualDescription: + type: + - number + - "null" + qualCompletionYear: + type: + - number + - "null" + additionalProperties: true diff --git a/airbyte-integrations/connectors/source-greythr/metadata.yaml b/airbyte-integrations/connectors/source-greythr/metadata.yaml new file mode 100644 index 000000000000..937ff0dc5e81 --- /dev/null +++ b/airbyte-integrations/connectors/source-greythr/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "*" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-greythr + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 1a807325-5a1c-4e0f-a574-841034b1765d + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-greythr + githubIssueLabel: source-greythr + icon: icon.svg + license: MIT + name: GreytHr + releaseDate: 2024-11-29 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/greythr + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-gridly/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-gridly/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-gridly/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-gridly/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-gridly/main.py b/airbyte-integrations/connectors/source-gridly/main.py index 307be6500faf..48b578302a7b 100644 --- a/airbyte-integrations/connectors/source-gridly/main.py +++ b/airbyte-integrations/connectors/source-gridly/main.py @@ -4,5 +4,6 @@ from source_gridly.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-gridly/metadata.yaml b/airbyte-integrations/connectors/source-gridly/metadata.yaml index 2dfd3281384c..abc4401360e0 100644 --- a/airbyte-integrations/connectors/source-gridly/metadata.yaml +++ b/airbyte-integrations/connectors/source-gridly/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 6cbea164-3237-433b-9abb-36d384ee4cbf - dockerImageTag: 0.1.22 + dockerImageTag: 0.1.26 dockerRepository: airbyte/source-gridly githubIssueLabel: source-gridly icon: gridly.svg @@ -40,5 +40,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-gridly/poetry.lock b/airbyte-integrations/connectors/source-gridly/poetry.lock index daa4d036e32d..1077e5f93884 100644 --- a/airbyte-integrations/connectors/source-gridly/poetry.lock +++ b/airbyte-integrations/connectors/source-gridly/poetry.lock @@ -62,19 +62,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -140,127 +140,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -276,20 +263,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -367,13 +354,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -486,13 +473,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -573,54 +560,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -884,33 +871,33 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -951,13 +938,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -982,81 +969,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-gridly/pyproject.toml b/airbyte-integrations/connectors/source-gridly/pyproject.toml index 79a9ba828e0b..a553656cdb31 100644 --- a/airbyte-integrations/connectors/source-gridly/pyproject.toml +++ b/airbyte-integrations/connectors/source-gridly/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.22" +version = "0.1.26" name = "source-gridly" description = "Source implementation for Gridly." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-gridly/source_gridly/helpers.py b/airbyte-integrations/connectors/source-gridly/source_gridly/helpers.py index 05f9d4843cc5..b896e6102f94 100644 --- a/airbyte-integrations/connectors/source-gridly/source_gridly/helpers.py +++ b/airbyte-integrations/connectors/source-gridly/source_gridly/helpers.py @@ -5,6 +5,7 @@ from typing import Any, Dict import requests + from airbyte_cdk.models import AirbyteStream from airbyte_cdk.models.airbyte_protocol import DestinationSyncMode, SyncMode from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator diff --git a/airbyte-integrations/connectors/source-gridly/source_gridly/source.py b/airbyte-integrations/connectors/source-gridly/source_gridly/source.py index 10a400672cfb..d1c2ed8a5483 100644 --- a/airbyte-integrations/connectors/source-gridly/source_gridly/source.py +++ b/airbyte-integrations/connectors/source-gridly/source_gridly/source.py @@ -9,6 +9,7 @@ from typing import Any, Dict, Iterable, List, Mapping, MutableMapping, Optional, Tuple import requests + from airbyte_cdk.models import AirbyteCatalog from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream diff --git a/airbyte-integrations/connectors/source-gridly/unit_tests/test_source.py b/airbyte-integrations/connectors/source-gridly/unit_tests/test_source.py index 2aa8d22ce2d9..4d3ea285f4f4 100644 --- a/airbyte-integrations/connectors/source-gridly/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-gridly/unit_tests/test_source.py @@ -6,6 +6,7 @@ from source_gridly.source import SourceGridly + CONFIG = {"api_key": "IbuIBdkFjrJps6", "grid_id": "4539o52kmdjmzwp"} diff --git a/airbyte-integrations/connectors/source-guru/metadata.yaml b/airbyte-integrations/connectors/source-guru/metadata.yaml index 4a9ae3e31ac2..ece6214fb74d 100644 --- a/airbyte-integrations/connectors/source-guru/metadata.yaml +++ b/airbyte-integrations/connectors/source-guru/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-guru connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 30e2d5f2-63c1-4993-8079-c8abf24e747d - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.9 dockerRepository: airbyte/source-guru githubIssueLabel: source-guru icon: icon.svg diff --git a/airbyte-integrations/connectors/source-gutendex/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-gutendex/integration_tests/acceptance.py index efc25f08ce82..78b220cebb18 100644 --- a/airbyte-integrations/connectors/source-gutendex/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-gutendex/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-hardcoded-records/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-hardcoded-records/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-hardcoded-records/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-hardcoded-records/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-hardcoded-records/main.py b/airbyte-integrations/connectors/source-hardcoded-records/main.py index ead17772f9c3..e697227784c1 100644 --- a/airbyte-integrations/connectors/source-hardcoded-records/main.py +++ b/airbyte-integrations/connectors/source-hardcoded-records/main.py @@ -5,5 +5,6 @@ from source_hardcoded_records.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-hardcoded-records/metadata.yaml b/airbyte-integrations/connectors/source-hardcoded-records/metadata.yaml index 0e1b796fb7a9..54439cb3a97a 100644 --- a/airbyte-integrations/connectors/source-hardcoded-records/metadata.yaml +++ b/airbyte-integrations/connectors/source-hardcoded-records/metadata.yaml @@ -5,11 +5,11 @@ data: allowedHosts: hosts: [] connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 084124ab-22db-4019-b36d-630418541bf7 - dockerImageTag: 0.0.17 + dockerImageTag: 0.0.23 dockerRepository: airbyte/source-hardcoded-records documentationUrl: https://docs.airbyte.com/integrations/sources/hardcoded-records githubIssueLabel: source-hardcoded-records diff --git a/airbyte-integrations/connectors/source-hardcoded-records/poetry.lock b/airbyte-integrations/connectors/source-hardcoded-records/poetry.lock index 70a534060ec7..e9c2c967b1f9 100644 --- a/airbyte-integrations/connectors/source-hardcoded-records/poetry.lock +++ b/airbyte-integrations/connectors/source-hardcoded-records/poetry.lock @@ -2,59 +2,63 @@ [[package]] name = "airbyte-cdk" -version = "5.17.0" +version = "6.6.1" description = "A framework for writing Airbyte Connectors." optional = false python-versions = "<4.0,>=3.10" files = [ - {file = "airbyte_cdk-5.17.0-py3-none-any.whl", hash = "sha256:135a8fc43b00a92169dfcdc43c1d7c629aba871a0b471f950ca5d76d3741fc92"}, - {file = "airbyte_cdk-5.17.0.tar.gz", hash = "sha256:5db70cbacec80ba3beabe4253480ab9a3947a450e8d0e39af4a91638b317b32a"}, + {file = "airbyte_cdk-6.6.1-py3-none-any.whl", hash = "sha256:b3f06f859fdf51bfcfe96cc91a7149e21cd172e55964be283052c655bd3d1eae"}, + {file = "airbyte_cdk-6.6.1.tar.gz", hash = "sha256:3c89222deb9ae3684bfcee1d015c6b248db07e0e4ab708e283ecc2be8e1d0792"}, ] [package.dependencies] airbyte-protocol-models-dataclasses = ">=0.13,<0.14" backoff = "*" cachetools = "*" -cryptography = ">=42.0.5,<43.0.0" +cryptography = ">=42.0.5,<44.0.0" Deprecated = ">=1.2,<1.3" dpath = ">=2.1.6,<3.0.0" -genson = "1.2.2" +dunamai = ">=1.22.0,<2.0.0" +genson = "1.3.0" isodate = ">=0.6.1,<0.7.0" Jinja2 = ">=3.1.2,<3.2.0" jsonref = ">=0.2,<0.3" jsonschema = ">=3.2.0,<3.3.0" langchain_core = "0.1.42" nltk = "3.8.1" +numpy = "<2" orjson = ">=3.10.7,<4.0.0" pandas = "2.2.2" pendulum = "<3.0.0" +psutil = "6.1.0" pydantic = ">=2.7,<3.0" pyjwt = ">=2.8.0,<3.0.0" pyrate-limiter = ">=3.1.0,<3.2.0" python-dateutil = "*" +python-ulid = ">=3.0.0,<4.0.0" pytz = "2024.1" PyYAML = ">=6.0.1,<7.0.0" requests = "*" requests_cache = "*" serpyco-rs = ">=1.10.2,<2.0.0" -wcmatch = "8.4" +wcmatch = "10.0" xmltodict = ">=0.13.0,<0.14.0" [package.extras] file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "python-snappy (==0.7.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] sql = ["sqlalchemy (>=2.0,!=2.0.36,<3.0)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] +vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.8.0)"] [[package]] name = "airbyte-protocol-models-dataclasses" -version = "0.13.0" +version = "0.13.1" description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models_dataclasses-0.13.0-py3-none-any.whl", hash = "sha256:0aedb99ffc4f9aab0ce91bba2c292fa17cd8fd4b42eeba196d6a16c20bbbd7a5"}, - {file = "airbyte_protocol_models_dataclasses-0.13.0.tar.gz", hash = "sha256:72e67850d661e2808406aec5839b3158ebb94d3553b798dbdae1b4a278548d2f"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1-py3-none-any.whl", hash = "sha256:20a734b7b1c3479a643777830db6a2e0a34428f33d16abcfd320552576fabe5a"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1.tar.gz", hash = "sha256:ec6a0fb6b16267bde910f52279445d06c8e1a3e4ed82ac2937b405ab280449d5"}, ] [[package]] @@ -70,24 +74,24 @@ files = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -113,19 +117,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -191,13 +195,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -281,127 +285,114 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -420,43 +411,38 @@ files = [ [[package]] name = "cryptography" -version = "42.0.8" +version = "43.0.3" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, + {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, + {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, + {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, + {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, + {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, + {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, + {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, ] [package.dependencies] @@ -469,25 +455,25 @@ nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -500,6 +486,20 @@ files = [ {file = "dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e"}, ] +[[package]] +name = "dunamai" +version = "1.23.0" +description = "Dynamic version generation" +optional = false +python-versions = ">=3.5" +files = [ + {file = "dunamai-1.23.0-py3-none-any.whl", hash = "sha256:a0906d876e92441793c6a423e16a4802752e723e9c9a5aabdc5535df02dbe041"}, + {file = "dunamai-1.23.0.tar.gz", hash = "sha256:a163746de7ea5acb6dacdab3a6ad621ebc612ed1e528aaa8beedb8887fccd2c4"}, +] + +[package.dependencies] +packaging = ">=20.9" + [[package]] name = "exceptiongroup" version = "1.2.2" @@ -516,12 +516,13 @@ test = ["pytest (>=6)"] [[package]] name = "genson" -version = "1.2.2" +version = "1.3.0" description = "GenSON is a powerful, user-friendly JSON Schema generator." optional = false python-versions = "*" files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, + {file = "genson-1.3.0-py3-none-any.whl", hash = "sha256:468feccd00274cc7e4c09e84b08704270ba8d95232aa280f65b986139cec67f7"}, + {file = "genson-1.3.0.tar.gz", hash = "sha256:e02db9ac2e3fd29e65b5286f7135762e2cd8a986537c075b06fc5f1517308e37"}, ] [[package]] @@ -537,13 +538,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -558,13 +559,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -572,7 +573,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -622,13 +622,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -729,18 +729,18 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = [ {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""}, {version = ">=2.7.4,<3.0.0", markers = "python_full_version >= \"3.12.4\""}, @@ -748,6 +748,9 @@ pydantic = [ requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -845,131 +848,131 @@ twitter = ["twython"] [[package]] name = "numpy" -version = "2.1.2" +version = "1.26.4" description = "Fundamental package for array computing in Python" optional = false -python-versions = ">=3.10" -files = [ - {file = "numpy-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466"}, - {file = "numpy-2.1.2-cp310-cp310-win32.whl", hash = "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb"}, - {file = "numpy-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146"}, - {file = "numpy-2.1.2-cp311-cp311-win32.whl", hash = "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c"}, - {file = "numpy-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142"}, - {file = "numpy-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550"}, - {file = "numpy-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe"}, - {file = "numpy-2.1.2-cp313-cp313-win32.whl", hash = "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a"}, - {file = "numpy-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e"}, - {file = "numpy-2.1.2.tar.gz", hash = "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c"}, +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, ] [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -1121,6 +1124,36 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "psutil" +version = "6.1.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, +] + +[package.extras] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + [[package]] name = "py" version = "1.11.0" @@ -1145,22 +1178,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = [ - {version = ">=4.6.1", markers = "python_version < \"3.13\""}, - {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, -] +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1168,100 +1198,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -1269,13 +1310,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1395,6 +1436,20 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "python-ulid" +version = "3.0.0" +description = "Universally unique lexicographically sortable identifier" +optional = false +python-versions = ">=3.9" +files = [ + {file = "python_ulid-3.0.0-py3-none-any.whl", hash = "sha256:e4c4942ff50dbd79167ad01ac725ec58f924b4018025ce22c858bfcff99a5e31"}, + {file = "python_ulid-3.0.0.tar.gz", hash = "sha256:e50296a47dc8209d28629a22fc81ca26c00982c78934bd7766377ba37ea49a9f"}, +] + +[package.extras] +pydantic = ["pydantic (>=2.0)"] + [[package]] name = "pytz" version = "2024.1" @@ -1481,105 +1536,105 @@ files = [ [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -1703,33 +1758,33 @@ typing-extensions = "*" [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1771,20 +1826,21 @@ files = [ [[package]] name = "tqdm" -version = "4.66.6" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63"}, - {file = "tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -1827,13 +1883,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1844,13 +1900,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "wcmatch" -version = "8.4" +version = "10.0" description = "Wildcard/glob file name matcher." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, + {file = "wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a"}, + {file = "wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a"}, ] [package.dependencies] @@ -1858,81 +1914,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [[package]] diff --git a/airbyte-integrations/connectors/source-hardcoded-records/pyproject.toml b/airbyte-integrations/connectors/source-hardcoded-records/pyproject.toml index ad50fb034a6f..262e144468d9 100644 --- a/airbyte-integrations/connectors/source-hardcoded-records/pyproject.toml +++ b/airbyte-integrations/connectors/source-hardcoded-records/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.0.17" +version = "0.0.23" name = "source-hardcoded-records" description = "Source implementation for hardcoded recprds." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-hardcoded-records/source_hardcoded_records/source.py b/airbyte-integrations/connectors/source-hardcoded-records/source_hardcoded_records/source.py index 862ac9470e96..73b2369c5792 100644 --- a/airbyte-integrations/connectors/source-hardcoded-records/source_hardcoded_records/source.py +++ b/airbyte-integrations/connectors/source-hardcoded-records/source_hardcoded_records/source.py @@ -9,6 +9,7 @@ from .streams import Customers, DummyFields, Products + DEFAULT_COUNT = 1_000 diff --git a/airbyte-integrations/connectors/source-harness/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-harness/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-harness/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-harness/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-harness/main.py b/airbyte-integrations/connectors/source-harness/main.py index a33c09315382..237fb7b71ce1 100644 --- a/airbyte-integrations/connectors/source-harness/main.py +++ b/airbyte-integrations/connectors/source-harness/main.py @@ -4,5 +4,6 @@ from source_harness.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-harness/source_harness/run.py b/airbyte-integrations/connectors/source-harness/source_harness/run.py index 544daa9407a1..6a0dc730fd62 100644 --- a/airbyte-integrations/connectors/source-harness/source_harness/run.py +++ b/airbyte-integrations/connectors/source-harness/source_harness/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_harness import SourceHarness +from airbyte_cdk.entrypoint import launch + def run(): source = SourceHarness() diff --git a/airbyte-integrations/connectors/source-harness/source_harness/source.py b/airbyte-integrations/connectors/source-harness/source_harness/source.py index a52f4c06db86..b12559ebc98a 100644 --- a/airbyte-integrations/connectors/source-harness/source_harness/source.py +++ b/airbyte-integrations/connectors/source-harness/source_harness/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-harvest/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-harvest/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-harvest/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-harvest/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-harvest/metadata.yaml b/airbyte-integrations/connectors/source-harvest/metadata.yaml index 6ffdc98583ef..04d1de22cf56 100644 --- a/airbyte-integrations/connectors/source-harvest/metadata.yaml +++ b/airbyte-integrations/connectors/source-harvest/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - api.harvestapp.com connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: fe2b4084-3386-4d3b-9ad6-308f61a6f1e6 - dockerImageTag: 1.1.2 + dockerImageTag: 1.1.7 dockerRepository: airbyte/source-harvest documentationUrl: https://docs.airbyte.com/integrations/sources/harvest githubIssueLabel: source-harvest diff --git a/airbyte-integrations/connectors/source-height/metadata.yaml b/airbyte-integrations/connectors/source-height/metadata.yaml index 1c427d116201..9b6f1c8e83d5 100644 --- a/airbyte-integrations/connectors/source-height/metadata.yaml +++ b/airbyte-integrations/connectors/source-height/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-height connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 8f4b2d64-970a-4a6f-b316-3d1144c67be8 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.9 dockerRepository: airbyte/source-height githubIssueLabel: source-height icon: icon.svg diff --git a/airbyte-integrations/connectors/source-hellobaton/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-hellobaton/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-hellobaton/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-hellobaton/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-hellobaton/metadata.yaml b/airbyte-integrations/connectors/source-hellobaton/metadata.yaml index c29d6a4f58a3..9134596a5b56 100644 --- a/airbyte-integrations/connectors/source-hellobaton/metadata.yaml +++ b/airbyte-integrations/connectors/source-hellobaton/metadata.yaml @@ -14,7 +14,7 @@ data: connectorSubtype: api connectorType: source definitionId: 492b56d1-937c-462e-8076-21ad2031e784 - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.9 dockerRepository: airbyte/source-hellobaton githubIssueLabel: source-hellobaton icon: hellobaton.svg @@ -43,5 +43,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.14.0@sha256:accdf6c1bbcabd45b40f836692e4f3b1a1e1f0b28267973802ee212cd9c2c16a + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-hibob/metadata.yaml b/airbyte-integrations/connectors/source-hibob/metadata.yaml index 8ebd594bcec4..0187bee41070 100644 --- a/airbyte-integrations/connectors/source-hibob/metadata.yaml +++ b/airbyte-integrations/connectors/source-hibob/metadata.yaml @@ -16,11 +16,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 4dc991ed-3dcc-4c40-ac28-9402836709f1 - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-hibob githubIssueLabel: source-hibob icon: icon.svg diff --git a/airbyte-integrations/connectors/source-high-level/metadata.yaml b/airbyte-integrations/connectors/source-high-level/metadata.yaml index 078ed20a65b0..3e6689339e04 100644 --- a/airbyte-integrations/connectors/source-high-level/metadata.yaml +++ b/airbyte-integrations/connectors/source-high-level/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-high-level connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 2028e68a-8c97-45c4-b196-e61bad7b6f40 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-high-level githubIssueLabel: source-high-level icon: icon.svg diff --git a/airbyte-integrations/connectors/source-hoorayhr/README.md b/airbyte-integrations/connectors/source-hoorayhr/README.md new file mode 100644 index 000000000000..95b2dcb571fe --- /dev/null +++ b/airbyte-integrations/connectors/source-hoorayhr/README.md @@ -0,0 +1,33 @@ +# HoorayHR +This directory contains the manifest-only connector for `source-hoorayhr`. + +Source connector for HoorayHR (https://hoorayhr.io). The connector uses https://api.hoorayhr.io + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-hoorayhr:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-hoorayhr build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-hoorayhr test +``` + diff --git a/airbyte-integrations/connectors/source-hoorayhr/acceptance-test-config.yml b/airbyte-integrations/connectors/source-hoorayhr/acceptance-test-config.yml new file mode 100644 index 000000000000..68a236e2cd9f --- /dev/null +++ b/airbyte-integrations/connectors/source-hoorayhr/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-hoorayhr:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-hoorayhr/icon.svg b/airbyte-integrations/connectors/source-hoorayhr/icon.svg new file mode 100644 index 000000000000..3904611c98a1 --- /dev/null +++ b/airbyte-integrations/connectors/source-hoorayhr/icon.svg @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-hoorayhr/manifest.yaml b/airbyte-integrations/connectors/source-hoorayhr/manifest.yaml new file mode 100644 index 000000000000..c3b932d1a4df --- /dev/null +++ b/airbyte-integrations/connectors/source-hoorayhr/manifest.yaml @@ -0,0 +1,803 @@ +version: 6.1.0 + +type: DeclarativeSource + +description: >- + Source connector for HoorayHR (https://hoorayhr.io). The connector uses + https://api.hoorayhr.io + +check: + type: CheckStream + stream_names: + - sick-leaves + +definitions: + streams: + users: + type: DeclarativeStream + name: users + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + time-off: + type: DeclarativeStream + name: time-off + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /time-off + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/time-off" + leave-types: + type: DeclarativeStream + name: leave-types + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /leave-types + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/leave-types" + sick-leaves: + type: DeclarativeStream + name: sick-leaves + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /sick-leave + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sick-leaves" + base_requester: + type: HttpRequester + url_base: https://api.hooray.nl + authenticator: + type: SessionTokenAuthenticator + login_requester: + type: HttpRequester + path: authentication + url_base: https://api.hooray.nl + http_method: POST + authenticator: + type: NoAuth + request_headers: {} + request_body_json: + email: "{{ config[\"hoorayhrusername\"] }}" + password: "{{ config[\"hoorayhrpassword\"] }}" + strategy: local + request_parameters: {} + session_token_path: + - accessToken + request_authentication: + type: ApiKey + inject_into: + type: RequestOption + field_name: Authorization + inject_into: header + +streams: + - $ref: "#/definitions/streams/sick-leaves" + - $ref: "#/definitions/streams/time-off" + - $ref: "#/definitions/streams/leave-types" + - $ref: "#/definitions/streams/users" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - hoorayhrusername + - hoorayhrpassword + properties: + hoorayhrpassword: + type: string + order: 1 + title: HoorayHR Password + airbyte_secret: true + hoorayhrusername: + type: string + order: 0 + title: HoorayHR Username + additionalProperties: true + +metadata: + assist: {} + testedStreams: + users: + hasRecords: true + streamHash: 33982ec24949870d1dd15b7191b46c03296fd15d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + time-off: + hasRecords: true + streamHash: 768ac0388c513fc36cf2af868244f3e0e13997a2 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + leave-types: + hasRecords: true + streamHash: aca371fa790b98baa7a814d47ca7e66d0b17c399 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + sick-leaves: + hasRecords: true + streamHash: 2bb47034ff795f366f0bafa8258077020af607c0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + autoImportSchema: + users: true + time-off: true + leave-types: true + sick-leaves: true + +schemas: + users: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: number + city: + type: + - string + - "null" + email: + type: + - string + - "null" + phone: + type: + - string + - "null" + teams: + type: + - string + - "null" + avatar: + type: + - string + - "null" + gender: + type: + - string + - "null" + locale: + type: + - string + - "null" + status: + type: + - number + - "null" + country: + type: + - string + - "null" + isAdmin: + type: + - number + - "null" + zipcode: + type: + - string + - "null" + initials: + type: + - string + - "null" + jobTitle: + type: + - string + - "null" + lastName: + type: + - string + - "null" + nickName: + type: + - string + - "null" + timezone: + type: + - string + - "null" + abilities: + type: + - array + - "null" + biography: + type: + - string + - "null" + birthdate: + type: + - string + - "null" + companyId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + firstName: + type: + - string + - "null" + insertion: + type: + - string + - "null" + invitedAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + birthPlace: + type: + - string + - "null" + civilStatus: + type: + - string + - "null" + costCenters: + type: + - array + - "null" + nationality: + type: + - string + - "null" + onBoardedAt: + type: + - string + - "null" + birthCountry: + type: + - string + - "null" + emailPrivate: + type: + - string + - "null" + integrations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + enabled: + type: + - string + - "null" + addressNumber: + type: + - string + - "null" + addressStreet: + type: + - string + - "null" + emergencyName: + type: + - string + - "null" + holidayPolicy: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + lastNameUsage: + type: + - string + - "null" + companyEndDate: + type: + - string + - "null" + employeeNumber: + type: + - string + - "null" + addressAddition: + type: + - string + - "null" + holidayPolicyId: + type: + - number + - "null" + invitedByUserId: + type: + - number + - "null" + travelAllowance: + type: + - number + - "null" + companyEndReason: + type: + - string + - "null" + companyStartDate: + type: + - string + - "null" + inviteAcceptedAt: + type: + - string + - "null" + inviteRemindedAt: + type: + - string + - "null" + bankAccountNumber: + type: + - string + - "null" + emergencyRelation: + type: + - string + - "null" + emergencyWorkPhone: + type: + - string + - "null" + citizenServiceNumber: + type: + - string + - "null" + emergencyPersonalPhone: + type: + - string + - "null" + twoFactorAuthentication: + type: + - number + - "null" + bankAccountNumberOnBehalfOf: + type: + - string + - "null" + additionalProperties: true + time-off: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: number + end: + type: + - string + - "null" + notes: + type: + - string + - "null" + pause: + type: + - number + - "null" + reply: + type: + - string + - "null" + start: + type: + - string + - "null" + labels: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - object + - "null" + properties: + de: + type: + - string + - "null" + en: + type: + - string + - "null" + nl: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + archivedAt: + type: + - string + - "null" + status: + type: + - number + - "null" + userId: + type: + - number + - "null" + timezone: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + holidayId: + type: + - number + - "null" + isPrivate: + type: + - number + - "null" + leaveUnit: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + budgetTotal: + type: + - number + - "null" + leaveTypeId: + type: + - number + - "null" + timeOffType: + type: + - string + - "null" + userIdApproved: + type: + - number + - "null" + baseTimeOffType: + type: + - string + - "null" + isNotCalculated: + type: + - number + - "null" + leaveTypeRuleId: + type: + - number + - "null" + budgetAdjustment: + type: + - number + - "null" + budgetCalculated: + type: + - number + - "null" + additionalProperties: true + leave-types: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: number + icon: + type: + - string + - "null" + name: + type: + - string + - "null" + color: + type: + - string + - "null" + budget: + type: + - number + - "null" + default: + type: + - number + - "null" + isLegacy: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - number + - "null" + leaveInDays: + type: + - number + - "null" + unpaidLeave: + type: + - number + - "null" + periodOffset: + type: + - number + - "null" + leaveTypeRules: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + order: + type: + - number + - "null" + budget: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + leaveTypeId: + type: + - number + - "null" + transferTerm: + type: + - number + - "null" + transferPeriod: + type: + - string + - "null" + expirationMoment: + type: + - string + - "null" + ruleSystemCategory: + type: + - string + - "null" + autoApproveLimit: + type: + - number + - "null" + subtractHolidays: + type: + - number + - "null" + calculationMethod: + type: + - string + - "null" + budgetReleaseTiming: + type: + - string + - "null" + invisibleInCalendar: + type: + - number + - "null" + budgetReleaseRecurrence: + type: + - string + - "null" + leaveTypeSystemCategory: + type: + - string + - "null" + accumulateBudgetWhenAbsent: + type: + - number + - "null" + additionalProperties: true + sick-leaves: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: number + notes: + type: + - string + - "null" + status: + type: + - number + - "null" + userId: + type: + - number + - "null" + timezone: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + percentage: + type: + - number + - "null" + actualStart: + type: + - string + - "null" + actualTotal: + type: + - number + - "null" + actualReturn: + type: + - string + - "null" + expectedTotal: + type: + - number + - "null" + reportedStart: + type: + - string + - "null" + actualStartEnd: + type: + - string + - "null" + expectedReturn: + type: + - string + - "null" + reportedReturn: + type: + - string + - "null" + userIdReported: + type: + - number + - "null" + actualReturnEnd: + type: + - string + - "null" + userIdConfirmed: + type: + - number + - "null" + additionalProperties: true diff --git a/airbyte-integrations/connectors/source-hoorayhr/metadata.yaml b/airbyte-integrations/connectors/source-hoorayhr/metadata.yaml new file mode 100644 index 000000000000..f7e660b39ab2 --- /dev/null +++ b/airbyte-integrations/connectors/source-hoorayhr/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.hooray.nl" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-hoorayhr + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: a2e34f7c-7de1-422c-b909-ce12f3e051af + dockerImageTag: 0.1.2 + dockerRepository: airbyte/source-hoorayhr + githubIssueLabel: source-hoorayhr + icon: icon.svg + license: MIT + name: HoorayHR + releaseDate: 2024-12-17 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/hoorayhr + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-hubplanner/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-hubplanner/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-hubplanner/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-hubplanner/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-hubplanner/metadata.yaml b/airbyte-integrations/connectors/source-hubplanner/metadata.yaml index 02ab82cabae0..f8cea84b5b46 100644 --- a/airbyte-integrations/connectors/source-hubplanner/metadata.yaml +++ b/airbyte-integrations/connectors/source-hubplanner/metadata.yaml @@ -14,7 +14,7 @@ data: connectorSubtype: api connectorType: source definitionId: 8097ceb9-383f-42f6-9f92-d3fd4bcc7689 - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.6 dockerRepository: airbyte/source-hubplanner githubIssueLabel: source-hubplanner icon: hubplanner.svg @@ -43,5 +43,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-hubspot/acceptance-test-config.yml b/airbyte-integrations/connectors/source-hubspot/acceptance-test-config.yml index 603dc2c0501b..139d772a957d 100644 --- a/airbyte-integrations/connectors/source-hubspot/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-hubspot/acceptance-test-config.yml @@ -93,6 +93,11 @@ acceptance_tests: bypass_reason: Hubspot time depend on current time - name: properties/hs_time_* bypass_reason: Hubspot time depend on current time + leads: + - name: properties_hs_time_* + bypass_reason: Hubspot time depend on current time + - name: properties/hs_time_* + bypass_reason: Hubspot time depend on current time tickets: - name: properties_hs_time_* bypass_reason: Hubspot time depend on current time @@ -127,6 +132,11 @@ acceptance_tests: bypass_reason: Hubspot time depend on current time - name: properties/hs_time_* bypass_reason: Hubspot time depend on current time + leads: + - name: properties_hs_time_* + bypass_reason: Hubspot time depend on current time + - name: properties/hs_time_* + bypass_reason: Hubspot time depend on current time tickets: - name: properties_hs_time_* bypass_reason: Hubspot time depend on current time diff --git a/airbyte-integrations/connectors/source-hubspot/integration_tests/abnormal_state.json b/airbyte-integrations/connectors/source-hubspot/integration_tests/abnormal_state.json index 6143f9e9f6e8..7df2f83d6938 100644 --- a/airbyte-integrations/connectors/source-hubspot/integration_tests/abnormal_state.json +++ b/airbyte-integrations/connectors/source-hubspot/integration_tests/abnormal_state.json @@ -150,6 +150,17 @@ "stream_state": { "updatedAt": "2200-01-01T00:00:00.000000Z" } } }, + { + "type": "STREAM", + "stream": { + "stream_descriptor": { + "name": "leads" + }, + "stream_state": { + "updatedAt": "2200-01-01T00:00:00.000000Z" + } + } + }, { "type": "STREAM", "stream": { diff --git a/airbyte-integrations/connectors/source-hubspot/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-hubspot/integration_tests/acceptance.py index 43ce950d77ca..72132012aaed 100644 --- a/airbyte-integrations/connectors/source-hubspot/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-hubspot/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-hubspot/integration_tests/basic_read_catalog.json b/airbyte-integrations/connectors/source-hubspot/integration_tests/basic_read_catalog.json index bf7dcf90e416..6538fa521593 100644 --- a/airbyte-integrations/connectors/source-hubspot/integration_tests/basic_read_catalog.json +++ b/airbyte-integrations/connectors/source-hubspot/integration_tests/basic_read_catalog.json @@ -201,6 +201,18 @@ "cursor_field": ["updatedAt"], "destination_sync_mode": "append" }, + { + "stream": { + "name": "leads", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updatedAt"] + }, + "sync_mode": "full_refresh", + "cursor_field": ["updatedAt"], + "destination_sync_mode": "append" + }, { "stream": { "name": "line_items", diff --git a/airbyte-integrations/connectors/source-hubspot/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-hubspot/integration_tests/expected_records.jsonl index 73bba3b2bb50..8e2b3fa6b968 100644 --- a/airbyte-integrations/connectors/source-hubspot/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-hubspot/integration_tests/expected_records.jsonl @@ -75,9 +75,11 @@ {"stream": "form_submissions", "data": {"submittedAt": 1707094502866, "values": [{"name": "email", "value": "integration-test+hubspot_form_100@airbyte.io", "objectTypeId": "0-1"}], "pageUrl": "https://share.hsforms.com/17X1n1tQkRLOOmod8jZV67A571yo", "updatedAt": 1707094502866, "formId": "ed7d67d6-d424-44b3-8e9a-877c8d957aec"}, "emitted_at": 1707094528032} {"stream": "contacts_form_submissions", "data": {"canonical-vid": 3001, "conversion-id": "2ec044dd-5ba6-4bbf-b64d-2b3a561d8434", "timestamp": 1707094108543, "form-id": "49773438-eebc-4622-a70b-f2102839d416", "portal-id": 8727216, "page-url": "https://meetings.hubspot.com/team-1-airbyte", "title": "Meetings Link: team-1-airbyte", "form-type": "MEETING", "contact-associated-by": ["EMAIL"], "meta-data": []}, "emitted_at": 1707094509475} {"stream": "contacts_form_submissions", "data": {"canonical-vid": 3101, "conversion-id": "aed975ea-68dd-456a-aef1-c80ef08001e8", "timestamp": 1707094502866, "form-id": "ed7d67d6-d424-44b3-8e9a-877c8d957aec", "portal-id": 8727216, "page-url": "https://share.hsforms.com/17X1n1tQkRLOOmod8jZV67A571yo", "canonical-url": "https://share.hsforms.com/17X1n1tQkRLOOmod8jZV67A571yo", "page-title": "Form", "title": "New form 100", "form-type": "HUBSPOT", "meta-data": []}, "emitted_at": 1707094509476} -{"stream": "deals_archived", "data": {"id": "21535649821","properties": {"amount":1000,"amount_in_home_currency":1000,"closed_lost_reason":null,"closed_won_reason":null,"closedate":"2024-08-16T02:20:24.142000+00:00","createdate":"2024-08-17T02:17:47.632000+00:00","days_to_close":0,"dealname":"Test deal BBBB","dealstage":"closedlost","dealtype":null,"description":null,"engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"hs_acv":null,"hs_all_accessible_team_ids":null,"hs_all_collaborator_owner_ids":null,"hs_all_deal_split_owner_ids":null,"hs_all_owner_ids":"52550153","hs_all_team_ids":null,"hs_analytics_latest_source":null,"hs_analytics_latest_source_company":null,"hs_analytics_latest_source_contact":null,"hs_analytics_latest_source_data_1":null,"hs_analytics_latest_source_data_1_company":null,"hs_analytics_latest_source_data_1_contact":null,"hs_analytics_latest_source_data_2":null,"hs_analytics_latest_source_data_2_company":null,"hs_analytics_latest_source_data_2_contact":null,"hs_analytics_latest_source_timestamp":null,"hs_analytics_latest_source_timestamp_company":null,"hs_analytics_latest_source_timestamp_contact":null,"hs_analytics_source":null,"hs_analytics_source_data_1":null,"hs_analytics_source_data_2":null,"hs_arr":null,"hs_campaign":null,"hs_closed_amount":0,"hs_closed_amount_in_home_currency":0,"hs_closed_deal_close_date":0,"hs_closed_deal_create_date":0,"hs_closed_won_count":0,"hs_closed_won_date":null,"hs_created_by_user_id":12282590,"hs_createdate":"2024-08-17T02:17:47.632000+00:00","hs_date_entered_66894120":null,"hs_date_entered_9567448":null,"hs_date_entered_9567449":null,"hs_date_entered_appointmentscheduled":"2024-08-17T02:17:47.632000+00:00","hs_date_entered_closedlost":"2024-08-17T02:19:06.611000+00:00","hs_date_entered_closedwon":null,"hs_date_entered_contractsent":null,"hs_date_entered_customclosedwonstage":null,"hs_date_entered_decisionmakerboughtin":null,"hs_date_entered_presentationscheduled":null,"hs_date_entered_qualifiedtobuy":null,"hs_date_exited_66894120":null,"hs_date_exited_9567448":null,"hs_date_exited_9567449":null,"hs_date_exited_appointmentscheduled":"2024-08-17T02:19:06.611000+00:00","hs_date_exited_closedlost":null,"hs_date_exited_closedwon":null,"hs_date_exited_contractsent":null,"hs_date_exited_customclosedwonstage":null,"hs_date_exited_decisionmakerboughtin":null,"hs_date_exited_presentationscheduled":null,"hs_date_exited_qualifiedtobuy":null,"hs_days_to_close_raw":0,"hs_deal_amount_calculation_preference":null,"hs_deal_score":null,"hs_deal_stage_probability":0,"hs_deal_stage_probability_shadow":0,"hs_exchange_rate":null,"hs_forecast_amount":1000,"hs_forecast_probability":null,"hs_has_empty_conditional_stage_properties":null,"hs_is_closed":true,"hs_is_closed_count":1,"hs_is_closed_won":false,"hs_is_deal_split":false,"hs_is_in_first_deal_stage":false,"hs_is_open_count":0,"hs_lastmodifieddate":"2024-08-17T02:20:24.300000+00:00","hs_latest_approval_status":null,"hs_latest_approval_status_approval_id":null,"hs_latest_meeting_activity":null,"hs_likelihood_to_close":null,"hs_line_item_global_term_hs_discount_percentage":null,"hs_line_item_global_term_hs_discount_percentage_enabled":null,"hs_line_item_global_term_hs_recurring_billing_period":null,"hs_line_item_global_term_hs_recurring_billing_period_enabled":null,"hs_line_item_global_term_hs_recurring_billing_start_date":null,"hs_line_item_global_term_hs_recurring_billing_start_date_enabled":null,"hs_line_item_global_term_recurringbillingfrequency":null,"hs_line_item_global_term_recurringbillingfrequency_enabled":null,"hs_manual_forecast_category":null,"hs_merged_object_ids":null,"hs_mrr":null,"hs_next_step":null,"hs_next_step_updated_at":null,"hs_notes_next_activity_type":null,"hs_num_associated_deal_splits":0,"hs_num_of_associated_line_items":0,"hs_num_target_accounts":0,"hs_object_id":21535649821,"hs_object_source":"CRM_UI","hs_object_source_detail_1":null,"hs_object_source_detail_2":null,"hs_object_source_detail_3":null,"hs_object_source_id":"userId:12282590","hs_object_source_label":"CRM_UI","hs_object_source_user_id":12282590,"hs_open_deal_create_date":0,"hs_pinned_engagement_id":null,"hs_predicted_amount":null,"hs_predicted_amount_in_home_currency":null,"hs_priority":null,"hs_projected_amount":0,"hs_projected_amount_in_home_currency":0,"hs_read_only":null,"hs_sales_email_last_replied":null,"hs_tag_ids":null,"hs_tcv":null,"hs_time_in_66894120":null,"hs_time_in_9567448":null,"hs_time_in_9567449":null,"hs_time_in_appointmentscheduled":78979,"hs_time_in_closedlost":551398,"hs_time_in_closedwon":null,"hs_time_in_contractsent":null,"hs_time_in_customclosedwonstage":null,"hs_time_in_decisionmakerboughtin":null,"hs_time_in_presentationscheduled":null,"hs_time_in_qualifiedtobuy":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"12282590","hs_v2_cumulative_time_in_66894120":null,"hs_v2_cumulative_time_in_9567448":null,"hs_v2_cumulative_time_in_9567449":null,"hs_v2_cumulative_time_in_appointmentscheduled":78979,"hs_v2_cumulative_time_in_closedlost":null,"hs_v2_cumulative_time_in_closedwon":null,"hs_v2_cumulative_time_in_contractsent":null,"hs_v2_cumulative_time_in_customclosedwonstage":null,"hs_v2_cumulative_time_in_decisionmakerboughtin":null,"hs_v2_cumulative_time_in_presentationscheduled":null,"hs_v2_cumulative_time_in_qualifiedtobuy":null,"hs_v2_date_entered_66894120":null,"hs_v2_date_entered_9567448":null,"hs_v2_date_entered_9567449":null,"hs_v2_date_entered_appointmentscheduled":"2024-08-17T02:17:47.632000+00:00","hs_v2_date_entered_closedlost":"2024-08-17T02:19:06.611000+00:00","hs_v2_date_entered_closedwon":null,"hs_v2_date_entered_contractsent":null,"hs_v2_date_entered_customclosedwonstage":null,"hs_v2_date_entered_decisionmakerboughtin":null,"hs_v2_date_entered_presentationscheduled":null,"hs_v2_date_entered_qualifiedtobuy":null,"hs_v2_date_exited_66894120":null,"hs_v2_date_exited_9567448":null,"hs_v2_date_exited_9567449":null,"hs_v2_date_exited_appointmentscheduled":"2024-08-17T02:19:06.611000+00:00","hs_v2_date_exited_closedlost":null,"hs_v2_date_exited_closedwon":null,"hs_v2_date_exited_contractsent":null,"hs_v2_date_exited_customclosedwonstage":null,"hs_v2_date_exited_decisionmakerboughtin":null,"hs_v2_date_exited_presentationscheduled":null,"hs_v2_date_exited_qualifiedtobuy":null,"hs_v2_latest_time_in_66894120":null,"hs_v2_latest_time_in_9567448":null,"hs_v2_latest_time_in_9567449":null,"hs_v2_latest_time_in_appointmentscheduled":78979,"hs_v2_latest_time_in_closedlost":null,"hs_v2_latest_time_in_closedwon":null,"hs_v2_latest_time_in_contractsent":null,"hs_v2_latest_time_in_customclosedwonstage":null,"hs_v2_latest_time_in_decisionmakerboughtin":null,"hs_v2_latest_time_in_presentationscheduled":null,"hs_v2_latest_time_in_qualifiedtobuy":null,"hs_was_imported":null,"hubspot_owner_assigneddate":"2024-08-17T02:17:47.632000+00:00","hubspot_owner_id":"52550153","hubspot_team_id":null,"notes_last_contacted":null,"notes_last_updated":"2024-08-17T02:18:02.066000+00:00","notes_next_activity_date":null,"num_associated_contacts":0,"num_contacted_notes":0,"num_notes":1,"pipeline":"default"},"createdAt":"2024-08-17T02:17:47.632Z","updatedAt":"2024-08-17T02:20:24.300Z","archived":true,"archivedAt":"2024-08-17T02:25:40.353Z","properties_amount":1000,"properties_amount_in_home_currency":1000,"properties_closed_lost_reason":null,"properties_closed_won_reason":null,"properties_closedate":"2024-08-16T02:20:24.142000+00:00","properties_createdate":"2024-08-17T02:17:47.632000+00:00","properties_days_to_close":0,"properties_dealname":"Test deal BBBB","properties_dealstage":"closedlost","properties_dealtype":null,"properties_description":null,"properties_engagements_last_meeting_booked":null,"properties_engagements_last_meeting_booked_campaign":null,"properties_engagements_last_meeting_booked_medium":null,"properties_engagements_last_meeting_booked_source":null,"properties_hs_acv":null,"properties_hs_all_accessible_team_ids":null,"properties_hs_all_collaborator_owner_ids":null,"properties_hs_all_deal_split_owner_ids":null,"properties_hs_all_owner_ids":"52550153","properties_hs_all_team_ids":null,"properties_hs_analytics_latest_source":null,"properties_hs_analytics_latest_source_company":null,"properties_hs_analytics_latest_source_contact":null,"properties_hs_analytics_latest_source_data_1":null,"properties_hs_analytics_latest_source_data_1_company":null,"properties_hs_analytics_latest_source_data_1_contact":null,"properties_hs_analytics_latest_source_data_2":null,"properties_hs_analytics_latest_source_data_2_company":null,"properties_hs_analytics_latest_source_data_2_contact":null,"properties_hs_analytics_latest_source_timestamp":null,"properties_hs_analytics_latest_source_timestamp_company":null,"properties_hs_analytics_latest_source_timestamp_contact":null,"properties_hs_analytics_source":null,"properties_hs_analytics_source_data_1":null,"properties_hs_analytics_source_data_2":null,"properties_hs_arr":null,"properties_hs_campaign":null,"properties_hs_closed_amount":0,"properties_hs_closed_amount_in_home_currency":0,"properties_hs_closed_deal_close_date":0,"properties_hs_closed_deal_create_date":0,"properties_hs_closed_won_count":0,"properties_hs_closed_won_date":null,"properties_hs_created_by_user_id":12282590,"properties_hs_createdate":"2024-08-17T02:17:47.632000+00:00","properties_hs_date_entered_66894120":null,"properties_hs_date_entered_9567448":null,"properties_hs_date_entered_9567449":null,"properties_hs_date_entered_appointmentscheduled":"2024-08-17T02:17:47.632000+00:00","properties_hs_date_entered_closedlost":"2024-08-17T02:19:06.611000+00:00","properties_hs_date_entered_closedwon":null,"properties_hs_date_entered_contractsent":null,"properties_hs_date_entered_customclosedwonstage":null,"properties_hs_date_entered_decisionmakerboughtin":null,"properties_hs_date_entered_presentationscheduled":null,"properties_hs_date_entered_qualifiedtobuy":null,"properties_hs_date_exited_66894120":null,"properties_hs_date_exited_9567448":null,"properties_hs_date_exited_9567449":null,"properties_hs_date_exited_appointmentscheduled":"2024-08-17T02:19:06.611000+00:00","properties_hs_date_exited_closedlost":null,"properties_hs_date_exited_closedwon":null,"properties_hs_date_exited_contractsent":null,"properties_hs_date_exited_customclosedwonstage":null,"properties_hs_date_exited_decisionmakerboughtin":null,"properties_hs_date_exited_presentationscheduled":null,"properties_hs_date_exited_qualifiedtobuy":null,"properties_hs_days_to_close_raw":0,"properties_hs_deal_amount_calculation_preference":null,"properties_hs_deal_score":null,"properties_hs_deal_stage_probability":0,"properties_hs_deal_stage_probability_shadow":0,"properties_hs_exchange_rate":null,"properties_hs_forecast_amount":1000,"properties_hs_forecast_probability":null,"properties_hs_has_empty_conditional_stage_properties":null,"properties_hs_is_closed":true,"properties_hs_is_closed_count":1,"properties_hs_is_closed_won":false,"properties_hs_is_deal_split":false,"properties_hs_is_in_first_deal_stage":false,"properties_hs_is_open_count":0,"properties_hs_lastmodifieddate":"2024-08-17T02:20:24.300000+00:00","properties_hs_latest_approval_status":null,"properties_hs_latest_approval_status_approval_id":null,"properties_hs_latest_meeting_activity":null,"properties_hs_likelihood_to_close":null,"properties_hs_line_item_global_term_hs_discount_percentage":null,"properties_hs_line_item_global_term_hs_discount_percentage_enabled":null,"properties_hs_line_item_global_term_hs_recurring_billing_period":null,"properties_hs_line_item_global_term_hs_recurring_billing_period_enabled":null,"properties_hs_line_item_global_term_hs_recurring_billing_start_date":null,"properties_hs_line_item_global_term_hs_recurring_billing_start_date_enabled":null,"properties_hs_line_item_global_term_recurringbillingfrequency":null,"properties_hs_line_item_global_term_recurringbillingfrequency_enabled":null,"properties_hs_manual_forecast_category":null,"properties_hs_merged_object_ids":null,"properties_hs_mrr":null,"properties_hs_next_step":null,"properties_hs_next_step_updated_at":null,"properties_hs_notes_next_activity_type":null,"properties_hs_num_associated_deal_splits":0,"properties_hs_num_of_associated_line_items":0,"properties_hs_num_target_accounts":0,"properties_hs_object_id":21535649821,"properties_hs_object_source":"CRM_UI","properties_hs_object_source_detail_1":null,"properties_hs_object_source_detail_2":null,"properties_hs_object_source_detail_3":null,"properties_hs_object_source_id":"userId:12282590","properties_hs_object_source_label":"CRM_UI","properties_hs_object_source_user_id":12282590,"properties_hs_open_deal_create_date":0,"properties_hs_pinned_engagement_id":null,"properties_hs_predicted_amount":null,"properties_hs_predicted_amount_in_home_currency":null,"properties_hs_priority":null,"properties_hs_projected_amount":0,"properties_hs_projected_amount_in_home_currency":0,"properties_hs_read_only":null,"properties_hs_sales_email_last_replied":null,"properties_hs_tag_ids":null,"properties_hs_tcv":null,"properties_hs_time_in_66894120":null,"properties_hs_time_in_9567448":null,"properties_hs_time_in_9567449":null,"properties_hs_time_in_appointmentscheduled":78979,"properties_hs_time_in_closedlost":551398,"properties_hs_time_in_closedwon":null,"properties_hs_time_in_contractsent":null,"properties_hs_time_in_customclosedwonstage":null,"properties_hs_time_in_decisionmakerboughtin":null,"properties_hs_time_in_presentationscheduled":null,"properties_hs_time_in_qualifiedtobuy":null,"properties_hs_unique_creation_key":null,"properties_hs_updated_by_user_id":12282590,"properties_hs_user_ids_of_all_notification_followers":null,"properties_hs_user_ids_of_all_notification_unfollowers":null,"properties_hs_user_ids_of_all_owners":"12282590","properties_hs_v2_cumulative_time_in_66894120":null,"properties_hs_v2_cumulative_time_in_9567448":null,"properties_hs_v2_cumulative_time_in_9567449":null,"properties_hs_v2_cumulative_time_in_appointmentscheduled":78979,"properties_hs_v2_cumulative_time_in_closedlost":null,"properties_hs_v2_cumulative_time_in_closedwon":null,"properties_hs_v2_cumulative_time_in_contractsent":null,"properties_hs_v2_cumulative_time_in_customclosedwonstage":null,"properties_hs_v2_cumulative_time_in_decisionmakerboughtin":null,"properties_hs_v2_cumulative_time_in_presentationscheduled":null,"properties_hs_v2_cumulative_time_in_qualifiedtobuy":null,"properties_hs_v2_date_entered_66894120":null,"properties_hs_v2_date_entered_9567448":null,"properties_hs_v2_date_entered_9567449":null,"properties_hs_v2_date_entered_appointmentscheduled":"2024-08-17T02:17:47.632000+00:00","properties_hs_v2_date_entered_closedlost":"2024-08-17T02:19:06.611000+00:00","properties_hs_v2_date_entered_closedwon":null,"properties_hs_v2_date_entered_contractsent":null,"properties_hs_v2_date_entered_customclosedwonstage":null,"properties_hs_v2_date_entered_decisionmakerboughtin":null,"properties_hs_v2_date_entered_presentationscheduled":null,"properties_hs_v2_date_entered_qualifiedtobuy":null,"properties_hs_v2_date_exited_66894120":null,"properties_hs_v2_date_exited_9567448":null,"properties_hs_v2_date_exited_9567449":null,"properties_hs_v2_date_exited_appointmentscheduled":"2024-08-17T02:19:06.611000+00:00","properties_hs_v2_date_exited_closedlost":null,"properties_hs_v2_date_exited_closedwon":null,"properties_hs_v2_date_exited_contractsent":null,"properties_hs_v2_date_exited_customclosedwonstage":null,"properties_hs_v2_date_exited_decisionmakerboughtin":null,"properties_hs_v2_date_exited_presentationscheduled":null,"properties_hs_v2_date_exited_qualifiedtobuy":null,"properties_hs_v2_latest_time_in_66894120":null,"properties_hs_v2_latest_time_in_9567448":null,"properties_hs_v2_latest_time_in_9567449":null,"properties_hs_v2_latest_time_in_appointmentscheduled":78979,"properties_hs_v2_latest_time_in_closedlost":null,"properties_hs_v2_latest_time_in_closedwon":null,"properties_hs_v2_latest_time_in_contractsent":null,"properties_hs_v2_latest_time_in_customclosedwonstage":null,"properties_hs_v2_latest_time_in_decisionmakerboughtin":null,"properties_hs_v2_latest_time_in_presentationscheduled":null,"properties_hs_v2_latest_time_in_qualifiedtobuy":null,"properties_hs_was_imported":null,"properties_hubspot_owner_assigneddate":"2024-08-17T02:17:47.632000+00:00","properties_hubspot_owner_id":"52550153","properties_hubspot_team_id":null,"properties_notes_last_contacted":null,"properties_notes_last_updated":"2024-08-17T02:18:02.066000+00:00","properties_notes_next_activity_date":null,"properties_num_associated_contacts":0,"properties_num_contacted_notes":0,"properties_num_notes":1,"properties_pipeline":"default"},"emitted_at":1723861698009} +{"stream": "deals_archived", "data": {"id":"29140168524","properties":{ "amount":1, "amount_in_home_currency":1,"closed_lost_reason":null,"closed_won_reason":null,"closedate":"2024-11-15T15:05:30.176000+00:00","createdate":"2024-11-15T15:06:09.508000+00:00","days_to_close":0,"dealname":"Deal_archived_11_5_2024","dealstage":"appointmentscheduled","dealtype":"newbusiness","description":null,"engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"hs_acv":1.0,"hs_all_accessible_team_ids":null,"hs_all_collaborator_owner_ids":null,"hs_all_deal_split_owner_ids":"52550153","hs_all_owner_ids":"52550153","hs_all_team_ids":null,"hs_analytics_latest_source":"DIRECT_TRAFFIC","hs_analytics_latest_source_company":null,"hs_analytics_latest_source_contact":"DIRECT_TRAFFIC","hs_analytics_latest_source_data_1":"e3875d32-ab81-48f1-9e78-493eae864f12","hs_analytics_latest_source_data_1_company":null,"hs_analytics_latest_source_data_1_contact":"e3875d32-ab81-48f1-9e78-493eae864f12","hs_analytics_latest_source_data_2":null,"hs_analytics_latest_source_data_2_company":null,"hs_analytics_latest_source_data_2_contact":null,"hs_analytics_latest_source_timestamp":"2024-06-26T23:58:13.518000+00:00","hs_analytics_latest_source_timestamp_company":null,"hs_analytics_latest_source_timestamp_contact":"2024-06-26T23:58:13.518000+00:00","hs_analytics_source":"OFFLINE","hs_analytics_source_data_1":"INTEGRATION","hs_analytics_source_data_2":"1566903","hs_arr":0.0,"hs_campaign":null,"hs_closed_amount":0,"hs_closed_amount_in_home_currency":0,"hs_closed_deal_close_date":0,"hs_closed_deal_create_date":0,"hs_closed_won_count":0,"hs_closed_won_date":null,"hs_created_by_user_id":12282590,"hs_createdate":"2024-11-15T15:06:09.508000+00:00","hs_date_entered_66894120":null,"hs_date_entered_9567448":null,"hs_date_entered_9567449":null,"hs_date_entered_appointmentscheduled":"2024-11-15T15:06:09.508000+00:00","hs_date_entered_closedlost":null,"hs_date_entered_closedwon":null,"hs_date_entered_contractsent":null,"hs_date_entered_customclosedwonstage":null,"hs_date_entered_decisionmakerboughtin":null,"hs_date_entered_presentationscheduled":null,"hs_date_entered_qualifiedtobuy":null,"hs_date_exited_66894120":null,"hs_date_exited_9567448":null,"hs_date_exited_9567449":null,"hs_date_exited_appointmentscheduled":null,"hs_date_exited_closedlost":null,"hs_date_exited_closedwon":null,"hs_date_exited_contractsent":null,"hs_date_exited_customclosedwonstage":null,"hs_date_exited_decisionmakerboughtin":null,"hs_date_exited_presentationscheduled":null,"hs_date_exited_qualifiedtobuy":null,"hs_days_to_close_raw":0,"hs_deal_amount_calculation_preference":null,"hs_deal_score":null,"hs_deal_stage_probability":0.2,"hs_deal_stage_probability_shadow":0.2,"hs_exchange_rate":null,"hs_forecast_amount":1,"hs_forecast_probability":null,"hs_has_empty_conditional_stage_properties":null,"hs_is_closed":false,"hs_is_closed_count":0,"hs_is_closed_lost":false,"hs_is_closed_won":false,"hs_is_deal_split":false,"hs_is_in_first_deal_stage":true,"hs_is_open_count":1,"hs_lastmodifieddate":"2024-11-15T15:06:54.762000+00:00","hs_latest_approval_status":null,"hs_latest_approval_status_approval_id":null,"hs_latest_meeting_activity":null,"hs_likelihood_to_close":null,"hs_line_item_global_term_hs_discount_percentage":null,"hs_line_item_global_term_hs_discount_percentage_enabled":null,"hs_line_item_global_term_hs_recurring_billing_period":null,"hs_line_item_global_term_hs_recurring_billing_period_enabled":null,"hs_line_item_global_term_hs_recurring_billing_start_date":null,"hs_line_item_global_term_hs_recurring_billing_start_date_enabled":null,"hs_line_item_global_term_recurringbillingfrequency":null,"hs_line_item_global_term_recurringbillingfrequency_enabled":null,"hs_manual_forecast_category":null,"hs_merged_object_ids":null,"hs_mrr":0.0,"hs_next_step":null,"hs_next_step_updated_at":null,"hs_notes_next_activity_type":null,"hs_num_associated_deal_splits":1,"hs_num_of_associated_line_items":1,"hs_num_target_accounts":0,"hs_object_id":29140168524,"hs_object_source":"CRM_UI","hs_object_source_detail_1":null,"hs_object_source_detail_2":null,"hs_object_source_detail_3":null,"hs_object_source_id":"userId:12282590","hs_object_source_label":"CRM_UI","hs_object_source_user_id":12282590,"hs_open_deal_create_date":1731683169508,"hs_pinned_engagement_id":null,"hs_predicted_amount":null,"hs_predicted_amount_in_home_currency":null,"hs_priority":"high","hs_projected_amount":0.2,"hs_projected_amount_in_home_currency":0.2,"hs_read_only":null,"hs_sales_email_last_replied":null,"hs_shared_team_ids":null,"hs_shared_user_ids":null,"hs_tag_ids":null,"hs_tcv":1.0,"hs_time_in_66894120":null,"hs_time_in_9567448":null,"hs_time_in_9567449":null,"hs_time_in_appointmentscheduled":3118539,"hs_time_in_closedlost":null,"hs_time_in_closedwon":null,"hs_time_in_contractsent":null,"hs_time_in_customclosedwonstage":null,"hs_time_in_decisionmakerboughtin":null,"hs_time_in_presentationscheduled":null,"hs_time_in_qualifiedtobuy":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"12282590","hs_v2_cumulative_time_in_66894120":null,"hs_v2_cumulative_time_in_9567448":null,"hs_v2_cumulative_time_in_9567449":null,"hs_v2_cumulative_time_in_appointmentscheduled":null,"hs_v2_cumulative_time_in_closedlost":null,"hs_v2_cumulative_time_in_closedwon":null,"hs_v2_cumulative_time_in_contractsent":null,"hs_v2_cumulative_time_in_customclosedwonstage":null,"hs_v2_cumulative_time_in_decisionmakerboughtin":null,"hs_v2_cumulative_time_in_presentationscheduled":null,"hs_v2_cumulative_time_in_qualifiedtobuy":null,"hs_v2_date_entered_66894120":null,"hs_v2_date_entered_9567448":null,"hs_v2_date_entered_9567449":null,"hs_v2_date_entered_appointmentscheduled":"2024-11-15T15:06:09.508000+00:00","hs_v2_date_entered_closedlost":null,"hs_v2_date_entered_closedwon":null,"hs_v2_date_entered_contractsent":null,"hs_v2_date_entered_customclosedwonstage":null,"hs_v2_date_entered_decisionmakerboughtin":null,"hs_v2_date_entered_presentationscheduled":null,"hs_v2_date_entered_qualifiedtobuy":null,"hs_v2_date_exited_66894120":null,"hs_v2_date_exited_9567448":null,"hs_v2_date_exited_9567449":null,"hs_v2_date_exited_appointmentscheduled":null,"hs_v2_date_exited_closedlost":null,"hs_v2_date_exited_closedwon":null,"hs_v2_date_exited_contractsent":null,"hs_v2_date_exited_customclosedwonstage":null,"hs_v2_date_exited_decisionmakerboughtin":null,"hs_v2_date_exited_presentationscheduled":null,"hs_v2_date_exited_qualifiedtobuy":null,"hs_v2_latest_time_in_66894120":null,"hs_v2_latest_time_in_9567448":null,"hs_v2_latest_time_in_9567449":null,"hs_v2_latest_time_in_appointmentscheduled":null,"hs_v2_latest_time_in_closedlost":null,"hs_v2_latest_time_in_closedwon":null,"hs_v2_latest_time_in_contractsent":null,"hs_v2_latest_time_in_customclosedwonstage":null,"hs_v2_latest_time_in_decisionmakerboughtin":null,"hs_v2_latest_time_in_presentationscheduled":null,"hs_v2_latest_time_in_qualifiedtobuy":null,"hs_was_imported":null,"hubspot_owner_assigneddate":"2024-11-15T15:06:09.508000+00:00","hubspot_owner_id":"52550153","hubspot_team_id":null,"notes_last_contacted":null,"notes_last_updated":"2024-11-15T15:06:27.514000+00:00","notes_next_activity_date":null,"num_associated_contacts":1,"num_contacted_notes":0,"num_notes":1,"pipeline":"default"},"createdAt":"2024-11-15T15:06:09.508Z","updatedAt":"2024-11-15T15:06:54.762Z","archived":true,"archivedAt":"2024-11-15T15:07:51.246Z","properties_amount":1,"properties_amount_in_home_currency":1,"properties_closed_lost_reason":null,"properties_closed_won_reason":null,"properties_closedate":"2024-11-15T15:05:30.176000+00:00","properties_createdate":"2024-11-15T15:06:09.508000+00:00","properties_days_to_close":0,"properties_dealname":"Deal_archived_11_5_2024","properties_dealstage":"appointmentscheduled","properties_dealtype":"newbusiness","properties_description":null,"properties_engagements_last_meeting_booked":null,"properties_engagements_last_meeting_booked_campaign":null,"properties_engagements_last_meeting_booked_medium":null,"properties_engagements_last_meeting_booked_source":null,"properties_hs_acv":1.0,"properties_hs_all_accessible_team_ids":null,"properties_hs_all_collaborator_owner_ids":null,"properties_hs_all_deal_split_owner_ids":"52550153","properties_hs_all_owner_ids":"52550153","properties_hs_all_team_ids":null,"properties_hs_analytics_latest_source":"DIRECT_TRAFFIC","properties_hs_analytics_latest_source_company":null,"properties_hs_analytics_latest_source_contact":"DIRECT_TRAFFIC","properties_hs_analytics_latest_source_data_1":"e3875d32-ab81-48f1-9e78-493eae864f12","properties_hs_analytics_latest_source_data_1_company":null,"properties_hs_analytics_latest_source_data_1_contact":"e3875d32-ab81-48f1-9e78-493eae864f12","properties_hs_analytics_latest_source_data_2":null,"properties_hs_analytics_latest_source_data_2_company":null,"properties_hs_analytics_latest_source_data_2_contact":null,"properties_hs_analytics_latest_source_timestamp":"2024-06-26T23:58:13.518000+00:00","properties_hs_analytics_latest_source_timestamp_company":null,"properties_hs_analytics_latest_source_timestamp_contact":"2024-06-26T23:58:13.518000+00:00","properties_hs_analytics_source":"OFFLINE","properties_hs_analytics_source_data_1":"INTEGRATION","properties_hs_analytics_source_data_2":"1566903","properties_hs_arr":0.0,"properties_hs_campaign":null,"properties_hs_closed_amount":0,"properties_hs_closed_amount_in_home_currency":0,"properties_hs_closed_deal_close_date":0,"properties_hs_closed_deal_create_date":0,"properties_hs_closed_won_count":0,"properties_hs_closed_won_date":null,"properties_hs_created_by_user_id":12282590,"properties_hs_createdate":"2024-11-15T15:06:09.508000+00:00","properties_hs_date_entered_66894120":null,"properties_hs_date_entered_9567448":null,"properties_hs_date_entered_9567449":null,"properties_hs_date_entered_appointmentscheduled":"2024-11-15T15:06:09.508000+00:00","properties_hs_date_entered_closedlost":null,"properties_hs_date_entered_closedwon":null,"properties_hs_date_entered_contractsent":null,"properties_hs_date_entered_customclosedwonstage":null,"properties_hs_date_entered_decisionmakerboughtin":null,"properties_hs_date_entered_presentationscheduled":null,"properties_hs_date_entered_qualifiedtobuy":null,"properties_hs_date_exited_66894120":null,"properties_hs_date_exited_9567448":null,"properties_hs_date_exited_9567449":null,"properties_hs_date_exited_appointmentscheduled":null,"properties_hs_date_exited_closedlost":null,"properties_hs_date_exited_closedwon":null,"properties_hs_date_exited_contractsent":null,"properties_hs_date_exited_customclosedwonstage":null,"properties_hs_date_exited_decisionmakerboughtin":null,"properties_hs_date_exited_presentationscheduled":null,"properties_hs_date_exited_qualifiedtobuy":null,"properties_hs_days_to_close_raw":0,"properties_hs_deal_amount_calculation_preference":null,"properties_hs_deal_score":null,"properties_hs_deal_stage_probability":0.2,"properties_hs_deal_stage_probability_shadow":0.2,"properties_hs_exchange_rate":null,"properties_hs_forecast_amount":1,"properties_hs_forecast_probability":null,"properties_hs_has_empty_conditional_stage_properties":null,"properties_hs_is_closed":false,"properties_hs_is_closed_count":0,"properties_hs_is_closed_lost":false,"properties_hs_is_closed_won":false,"properties_hs_is_deal_split":false,"properties_hs_is_in_first_deal_stage":true,"properties_hs_is_open_count":1,"properties_hs_lastmodifieddate":"2024-11-15T15:06:54.762000+00:00","properties_hs_latest_approval_status":null,"properties_hs_latest_approval_status_approval_id":null,"properties_hs_latest_meeting_activity":null,"properties_hs_likelihood_to_close":null,"properties_hs_line_item_global_term_hs_discount_percentage":null,"properties_hs_line_item_global_term_hs_discount_percentage_enabled":null,"properties_hs_line_item_global_term_hs_recurring_billing_period":null,"properties_hs_line_item_global_term_hs_recurring_billing_period_enabled":null,"properties_hs_line_item_global_term_hs_recurring_billing_start_date":null,"properties_hs_line_item_global_term_hs_recurring_billing_start_date_enabled":null,"properties_hs_line_item_global_term_recurringbillingfrequency":null,"properties_hs_line_item_global_term_recurringbillingfrequency_enabled":null,"properties_hs_manual_forecast_category":null,"properties_hs_merged_object_ids":null,"properties_hs_mrr":0.0,"properties_hs_next_step":null,"properties_hs_next_step_updated_at":null,"properties_hs_notes_next_activity_type":null,"properties_hs_num_associated_deal_splits":1,"properties_hs_num_of_associated_line_items":1,"properties_hs_num_target_accounts":0,"properties_hs_object_id":29140168524,"properties_hs_object_source":"CRM_UI","properties_hs_object_source_detail_1":null,"properties_hs_object_source_detail_2":null,"properties_hs_object_source_detail_3":null,"properties_hs_object_source_id":"userId:12282590","properties_hs_object_source_label":"CRM_UI","properties_hs_object_source_user_id":12282590,"properties_hs_open_deal_create_date":1731683169508,"properties_hs_pinned_engagement_id":null,"properties_hs_predicted_amount":null,"properties_hs_predicted_amount_in_home_currency":null,"properties_hs_priority":"high","properties_hs_projected_amount":0.2,"properties_hs_projected_amount_in_home_currency":0.2,"properties_hs_read_only":null,"properties_hs_sales_email_last_replied":null,"properties_hs_shared_team_ids":null,"properties_hs_shared_user_ids":null,"properties_hs_tag_ids":null,"properties_hs_tcv":1.0,"properties_hs_time_in_66894120":null,"properties_hs_time_in_9567448":null,"properties_hs_time_in_9567449":null,"properties_hs_time_in_appointmentscheduled":3118539,"properties_hs_time_in_closedlost":null,"properties_hs_time_in_closedwon":null,"properties_hs_time_in_contractsent":null,"properties_hs_time_in_customclosedwonstage":null,"properties_hs_time_in_decisionmakerboughtin":null,"properties_hs_time_in_presentationscheduled":null,"properties_hs_time_in_qualifiedtobuy":null,"properties_hs_unique_creation_key":null,"properties_hs_updated_by_user_id":12282590,"properties_hs_user_ids_of_all_notification_followers":null,"properties_hs_user_ids_of_all_notification_unfollowers":null,"properties_hs_user_ids_of_all_owners":"12282590","properties_hs_v2_cumulative_time_in_66894120":null,"properties_hs_v2_cumulative_time_in_9567448":null,"properties_hs_v2_cumulative_time_in_9567449":null,"properties_hs_v2_cumulative_time_in_appointmentscheduled":null,"properties_hs_v2_cumulative_time_in_closedlost":null,"properties_hs_v2_cumulative_time_in_closedwon":null,"properties_hs_v2_cumulative_time_in_contractsent":null,"properties_hs_v2_cumulative_time_in_customclosedwonstage":null,"properties_hs_v2_cumulative_time_in_decisionmakerboughtin":null,"properties_hs_v2_cumulative_time_in_presentationscheduled":null,"properties_hs_v2_cumulative_time_in_qualifiedtobuy":null,"properties_hs_v2_date_entered_66894120":null,"properties_hs_v2_date_entered_9567448":null,"properties_hs_v2_date_entered_9567449":null,"properties_hs_v2_date_entered_appointmentscheduled":"2024-11-15T15:06:09.508000+00:00","properties_hs_v2_date_entered_closedlost":null,"properties_hs_v2_date_entered_closedwon":null,"properties_hs_v2_date_entered_contractsent":null,"properties_hs_v2_date_entered_customclosedwonstage":null,"properties_hs_v2_date_entered_decisionmakerboughtin":null,"properties_hs_v2_date_entered_presentationscheduled":null,"properties_hs_v2_date_entered_qualifiedtobuy":null,"properties_hs_v2_date_exited_66894120":null,"properties_hs_v2_date_exited_9567448":null,"properties_hs_v2_date_exited_9567449":null,"properties_hs_v2_date_exited_appointmentscheduled":null,"properties_hs_v2_date_exited_closedlost":null,"properties_hs_v2_date_exited_closedwon":null,"properties_hs_v2_date_exited_contractsent":null,"properties_hs_v2_date_exited_customclosedwonstage":null,"properties_hs_v2_date_exited_decisionmakerboughtin":null,"properties_hs_v2_date_exited_presentationscheduled":null,"properties_hs_v2_date_exited_qualifiedtobuy":null,"properties_hs_v2_latest_time_in_66894120":null,"properties_hs_v2_latest_time_in_9567448":null,"properties_hs_v2_latest_time_in_9567449":null,"properties_hs_v2_latest_time_in_appointmentscheduled":null,"properties_hs_v2_latest_time_in_closedlost":null,"properties_hs_v2_latest_time_in_closedwon":null,"properties_hs_v2_latest_time_in_contractsent":null,"properties_hs_v2_latest_time_in_customclosedwonstage":null,"properties_hs_v2_latest_time_in_decisionmakerboughtin":null,"properties_hs_v2_latest_time_in_presentationscheduled":null,"properties_hs_v2_latest_time_in_qualifiedtobuy":null,"properties_hs_was_imported":null,"properties_hubspot_owner_assigneddate":"2024-11-15T15:06:09.508000+00:00","properties_hubspot_owner_id":"52550153","properties_hubspot_team_id":null,"properties_notes_last_contacted":null,"properties_notes_last_updated":"2024-11-15T15:06:27.514000+00:00","properties_notes_next_activity_date":null,"properties_num_associated_contacts":1,"properties_num_contacted_notes":0,"properties_num_notes":1,"properties_pipeline":"default"},"emitted_at":1731686287959} {"stream": "ticket_pipelines", "data": {"label": "Test_ticket_pipeline", "displayOrder": 1, "id": "80068448", "stages": [{"label": "New", "displayOrder": 0, "metadata": {"ticketState": "OPEN", "isClosed": "false"}, "id": "151692305", "createdAt": "2024-02-05T01:01:42.937Z", "updatedAt": "2024-02-05T01:01:42.937Z", "archived": false, "writePermissions": "CRM_PERMISSIONS_ENFORCEMENT"}, {"label": "Waiting on contact", "displayOrder": 1, "metadata": {"ticketState": "OPEN", "isClosed": "false"}, "id": "151692306", "createdAt": "2024-02-05T01:01:42.937Z", "updatedAt": "2024-02-05T01:01:42.937Z", "archived": false, "writePermissions": "CRM_PERMISSIONS_ENFORCEMENT"}, {"label": "Waiting on us", "displayOrder": 2, "metadata": {"ticketState": "OPEN", "isClosed": "false"}, "id": "151692307", "createdAt": "2024-02-05T01:01:42.937Z", "updatedAt": "2024-02-05T01:01:42.937Z", "archived": false, "writePermissions": "CRM_PERMISSIONS_ENFORCEMENT"}, {"label": "Closed", "displayOrder": 3, "metadata": {"ticketState": "CLOSED", "isClosed": "true"}, "id": "151692308", "createdAt": "2024-02-05T01:01:42.937Z", "updatedAt": "2024-02-05T01:01:42.937Z", "archived": false, "writePermissions": "CRM_PERMISSIONS_ENFORCEMENT"}], "createdAt": "2024-02-05T01:01:42.937Z", "updatedAt": "2024-02-05T01:01:42.937Z", "archived": false}, "emitted_at": 1707258209328} {"stream": "engagements_emails", "data": {"id": "46838275228", "properties": {"hs_all_accessible_team_ids": null, "hs_all_assigned_business_unit_ids": null, "hs_all_owner_ids": "52550153", "hs_all_team_ids": null, "hs_at_mentioned_owner_ids": null, "hs_attachment_ids": null, "hs_body_preview": "test body -- Prefer fewer emails from me? Click here", "hs_body_preview_html": "\n \n \n
\n test body \n
\n
\n -- \n
\n Prefer fewer emails from me? Click here \n
\n
\n \n", "hs_body_preview_is_truncated": false, "hs_created_by": "12282590", "hs_created_by_user_id": 12282590, "hs_createdate": "2024-02-05T01:13:21.505000+00:00", "hs_direction_and_unique_id": "EMAIL:432a7d905bf8fc42ba938819a9e6e291", "hs_email_attached_video_id": null, "hs_email_attached_video_name": null, "hs_email_attached_video_opened": false, "hs_email_attached_video_watched": false, "hs_email_bcc_email": null, "hs_email_bcc_firstname": null, "hs_email_bcc_lastname": null, "hs_email_bcc_raw": null, "hs_email_bounce_error_detail_message": null, "hs_email_bounce_error_detail_status_code": null, "hs_email_cc_email": null, "hs_email_cc_firstname": null, "hs_email_cc_lastname": null, "hs_email_cc_raw": null, "hs_email_click_count": null, "hs_email_direction": "EMAIL", "hs_email_encoded_email_associations_request": null, "hs_email_error_message": null, "hs_email_facsimile_send_id": "6b0d1024453e0b541501565ae69498c7", "hs_email_from_email": "integration-test-user@airbyte.io", "hs_email_from_firstname": "Team-1", "hs_email_from_lastname": "Airbyte", "hs_email_from_raw": null, "hs_email_has_inline_images_stripped": null, "hs_email_headers": "{\"from\":{\"email\":\"integration-test-user@airbyte.io\",\"firstName\":\"Team-1\",\"lastName\":\"Airbyte\"},\"to\":[{\"raw\":\"gl_serhii.lazebnyi@airbyte.io\",\"email\":\"gl_serhii.lazebnyi@airbyte.io\"}],\"cc\":[],\"bcc\":[],\"sender\":{\"email\":\"integration-test-user@airbyte.io\"}}", "hs_email_html": "
test body
--
Prefer fewer emails from me? Click here

", "hs_email_logged_from": "CRM", "hs_email_media_processing_status": "SKIPPED", "hs_email_member_of_forwarded_subthread": null, "hs_email_message_id": "CAK4c3Gyf4xNPCtrON3BFLN9WOWUpfe+sfb+7wh5qYuCD-K71AA@mail.gmail.com", "hs_email_migrated_via_portal_data_migration": null, "hs_email_ms_teams_payload": null, "hs_email_open_count": null, "hs_email_pending_inline_image_ids": null, "hs_email_post_send_status": "SENT", "hs_email_recipient_drop_reasons": null, "hs_email_reply_count": null, "hs_email_send_event_id": null, "hs_email_send_event_id_created": null, "hs_email_sender_email": "integration-test-user@airbyte.io", "hs_email_sender_firstname": null, "hs_email_sender_lastname": null, "hs_email_sender_raw": null, "hs_email_sent_count": 1.0, "hs_email_sent_via": "GMAIL", "hs_email_status": "SENT", "hs_email_stripped_attachment_count": null, "hs_email_subject": "test deal ", "hs_email_text": "test body\n-- \nPrefer fewer emails from me? Click here: https://d11qV604.na1.hs-salescrm-sub.com/preferences/en/manage?data=W2nXS-N30h-MkW3DX4xr38lXTKW2KXbZn3H3ZTKW4kt7Y_3XR2G0W30sn1g2zt_2NW47kvvy23ncKnW47Vmcy4pxy7cW41tzTm1X87X1W364bL-36tRLFW30J_Vy36F403W45FGpL3XHz-RW4ftDwZ4msYq_W24-jyc2HCSCvW3VGBr52TLG1vW2nFrmM3P2tStW43Skr81VxgJXW3z26wT4pc1KRW1Vpb_f3d3w7qW36dtk_4rCSHJW3F507n1_6v4MW2CWCvk49rVZpW23jtn51St_bDW2RKdYG2RNzKSW47znqq1_dHnNW4mGNp33Y1JRBW25m60s1Nk9WFW2MMKcf2F-zTNW4kddlH1NFHhxW25nrXX2KQX5rW3GJy1x2Yh7XsW2Pnx-93f_bXGW47SgSp1XqcMJW2FTQ1Z2KPBb6W32kvXr2KnzH9W3HcvHw3LRJmmW2MLX-W3LBLBJW3Q-74Q2KYV0CW1_9nCQ2r36_S0", "hs_email_thread_id": "3b2bf39b9ed8cfc53310ee557627d073", "hs_email_thread_summary": null, "hs_email_to_email": "gl_serhii.lazebnyi@airbyte.io", "hs_email_to_firstname": null, "hs_email_to_lastname": null, "hs_email_to_raw": "gl_serhii.lazebnyi@airbyte.io", "hs_email_tracker_key": "87989bf6-7771-4486-b3d7-73a31af32b2c", "hs_email_validation_skipped": null, "hs_engagement_source": "EMAIL_INTEGRATION", "hs_engagement_source_id": null, "hs_follow_up_action": null, "hs_gdpr_deleted": null, "hs_lastmodifieddate": "2024-02-05T01:13:26.539000+00:00", "hs_merged_object_ids": null, "hs_modified_by": "12282590", "hs_object_id": 46838275228, "hs_object_source": "CRM_UI", "hs_object_source_detail_1": null, "hs_object_source_detail_2": null, "hs_object_source_detail_3": null, "hs_object_source_id": null, "hs_object_source_label": "CRM_UI", "hs_object_source_user_id": 12282590, "hs_owner_ids_bcc": null, "hs_owner_ids_cc": null, "hs_owner_ids_from": "52550153", "hs_owner_ids_to": null, "hs_product_name": null, "hs_queue_membership_ids": null, "hs_read_only": null, "hs_scs_association_status": null, "hs_scs_audit_id": null, "hs_timestamp": "2024-02-05T01:13:21.109000+00:00", "hs_unique_creation_key": null, "hs_unique_id": "432a7d905bf8fc42ba938819a9e6e291", "hs_updated_by_user_id": 12282590, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": "12282590", "hs_was_imported": null, "hubspot_owner_assigneddate": "2024-02-05T01:13:21.505000+00:00", "hubspot_owner_id": "52550153", "hubspot_team_id": null}, "createdAt": "2024-02-05T01:13:21.505Z", "updatedAt": "2024-02-05T01:13:26.539Z", "archived": false, "companies": ["5000526215"], "deals": ["5388306989"], "contacts": ["3251"], "properties_hs_all_accessible_team_ids": null, "properties_hs_all_assigned_business_unit_ids": null, "properties_hs_all_owner_ids": "52550153", "properties_hs_all_team_ids": null, "properties_hs_at_mentioned_owner_ids": null, "properties_hs_attachment_ids": null, "properties_hs_body_preview": "test body -- Prefer fewer emails from me? Click here", "properties_hs_body_preview_html": "\n \n \n
\n test body \n
\n
\n -- \n
\n Prefer fewer emails from me? Click here \n
\n
\n \n", "properties_hs_body_preview_is_truncated": false, "properties_hs_created_by": "12282590", "properties_hs_created_by_user_id": 12282590, "properties_hs_createdate": "2024-02-05T01:13:21.505000+00:00", "properties_hs_direction_and_unique_id": "EMAIL:432a7d905bf8fc42ba938819a9e6e291", "properties_hs_email_attached_video_id": null, "properties_hs_email_attached_video_name": null, "properties_hs_email_attached_video_opened": false, "properties_hs_email_attached_video_watched": false, "properties_hs_email_bcc_email": null, "properties_hs_email_bcc_firstname": null, "properties_hs_email_bcc_lastname": null, "properties_hs_email_bcc_raw": null, "properties_hs_email_bounce_error_detail_message": null, "properties_hs_email_bounce_error_detail_status_code": null, "properties_hs_email_cc_email": null, "properties_hs_email_cc_firstname": null, "properties_hs_email_cc_lastname": null, "properties_hs_email_cc_raw": null, "properties_hs_email_click_count": null, "properties_hs_email_direction": "EMAIL", "properties_hs_email_encoded_email_associations_request": null, "properties_hs_email_error_message": null, "properties_hs_email_facsimile_send_id": "6b0d1024453e0b541501565ae69498c7", "properties_hs_email_from_email": "integration-test-user@airbyte.io", "properties_hs_email_from_firstname": "Team-1", "properties_hs_email_from_lastname": "Airbyte", "properties_hs_email_from_raw": null, "properties_hs_email_has_inline_images_stripped": null, "properties_hs_email_headers": "{\"from\":{\"email\":\"integration-test-user@airbyte.io\",\"firstName\":\"Team-1\",\"lastName\":\"Airbyte\"},\"to\":[{\"raw\":\"gl_serhii.lazebnyi@airbyte.io\",\"email\":\"gl_serhii.lazebnyi@airbyte.io\"}],\"cc\":[],\"bcc\":[],\"sender\":{\"email\":\"integration-test-user@airbyte.io\"}}", "properties_hs_email_html": "
test body
--
Prefer fewer emails from me? Click here

", "properties_hs_email_logged_from": "CRM", "properties_hs_email_media_processing_status": "SKIPPED", "properties_hs_email_member_of_forwarded_subthread": null, "properties_hs_email_message_id": "CAK4c3Gyf4xNPCtrON3BFLN9WOWUpfe+sfb+7wh5qYuCD-K71AA@mail.gmail.com", "properties_hs_email_migrated_via_portal_data_migration": null, "properties_hs_email_ms_teams_payload": null, "properties_hs_email_open_count": null, "properties_hs_email_pending_inline_image_ids": null, "properties_hs_email_post_send_status": "SENT", "properties_hs_email_recipient_drop_reasons": null, "properties_hs_email_reply_count": null, "properties_hs_email_send_event_id": null, "properties_hs_email_send_event_id_created": null, "properties_hs_email_sender_email": "integration-test-user@airbyte.io", "properties_hs_email_sender_firstname": null, "properties_hs_email_sender_lastname": null, "properties_hs_email_sender_raw": null, "properties_hs_email_sent_count": 1.0, "properties_hs_email_sent_via": "GMAIL", "properties_hs_email_status": "SENT", "properties_hs_email_stripped_attachment_count": null, "properties_hs_email_subject": "test deal ", "properties_hs_email_text": "test body\n-- \nPrefer fewer emails from me? Click here: https://d11qV604.na1.hs-salescrm-sub.com/preferences/en/manage?data=W2nXS-N30h-MkW3DX4xr38lXTKW2KXbZn3H3ZTKW4kt7Y_3XR2G0W30sn1g2zt_2NW47kvvy23ncKnW47Vmcy4pxy7cW41tzTm1X87X1W364bL-36tRLFW30J_Vy36F403W45FGpL3XHz-RW4ftDwZ4msYq_W24-jyc2HCSCvW3VGBr52TLG1vW2nFrmM3P2tStW43Skr81VxgJXW3z26wT4pc1KRW1Vpb_f3d3w7qW36dtk_4rCSHJW3F507n1_6v4MW2CWCvk49rVZpW23jtn51St_bDW2RKdYG2RNzKSW47znqq1_dHnNW4mGNp33Y1JRBW25m60s1Nk9WFW2MMKcf2F-zTNW4kddlH1NFHhxW25nrXX2KQX5rW3GJy1x2Yh7XsW2Pnx-93f_bXGW47SgSp1XqcMJW2FTQ1Z2KPBb6W32kvXr2KnzH9W3HcvHw3LRJmmW2MLX-W3LBLBJW3Q-74Q2KYV0CW1_9nCQ2r36_S0", "properties_hs_email_thread_id": "3b2bf39b9ed8cfc53310ee557627d073", "properties_hs_email_thread_summary": null, "properties_hs_email_to_email": "gl_serhii.lazebnyi@airbyte.io", "properties_hs_email_to_firstname": null, "properties_hs_email_to_lastname": null, "properties_hs_email_to_raw": "gl_serhii.lazebnyi@airbyte.io", "properties_hs_email_tracker_key": "87989bf6-7771-4486-b3d7-73a31af32b2c", "properties_hs_email_validation_skipped": null, "properties_hs_engagement_source": "EMAIL_INTEGRATION", "properties_hs_engagement_source_id": null, "properties_hs_follow_up_action": null, "properties_hs_gdpr_deleted": null, "properties_hs_lastmodifieddate": "2024-02-05T01:13:26.539000+00:00", "properties_hs_merged_object_ids": null, "properties_hs_modified_by": "12282590", "properties_hs_object_id": 46838275228, "properties_hs_object_source": "CRM_UI", "properties_hs_object_source_detail_1": null, "properties_hs_object_source_detail_2": null, "properties_hs_object_source_detail_3": null, "properties_hs_object_source_id": null, "properties_hs_object_source_label": "CRM_UI", "properties_hs_object_source_user_id": 12282590, "properties_hs_owner_ids_bcc": null, "properties_hs_owner_ids_cc": null, "properties_hs_owner_ids_from": "52550153", "properties_hs_owner_ids_to": null, "properties_hs_product_name": null, "properties_hs_queue_membership_ids": null, "properties_hs_read_only": null, "properties_hs_scs_association_status": null, "properties_hs_scs_audit_id": null, "properties_hs_timestamp": "2024-02-05T01:13:21.109000+00:00", "properties_hs_unique_creation_key": null, "properties_hs_unique_id": "432a7d905bf8fc42ba938819a9e6e291", "properties_hs_updated_by_user_id": 12282590, "properties_hs_user_ids_of_all_notification_followers": null, "properties_hs_user_ids_of_all_notification_unfollowers": null, "properties_hs_user_ids_of_all_owners": "12282590", "properties_hs_was_imported": null, "properties_hubspot_owner_assigneddate": "2024-02-05T01:13:21.505000+00:00", "properties_hubspot_owner_id": "52550153", "properties_hubspot_team_id": null}, "emitted_at": 1708015555151} {"stream": "engagements_meetings", "data": {"id": "46837884323", "properties": {"hs_activity_type": null, "hs_all_accessible_team_ids": null, "hs_all_assigned_business_unit_ids": null, "hs_all_owner_ids": "52550153", "hs_all_team_ids": null, "hs_at_mentioned_owner_ids": null, "hs_attachment_ids": null, "hs_attendee_owner_ids": null, "hs_body_preview": null, "hs_body_preview_html": null, "hs_body_preview_is_truncated": false, "hs_contact_first_outreach_date": null, "hs_created_by": 12282590, "hs_created_by_user_id": 12282590, "hs_createdate": "2024-02-05T01:08:01.995000+00:00", "hs_engagement_source": "MEETINGS", "hs_engagement_source_id": null, "hs_follow_up_action": null, "hs_gdpr_deleted": null, "hs_guest_emails": null, "hs_i_cal_uid": "imqqv2eda8h5rh74gabnagl60o@google.com", "hs_include_description_in_reminder": null, "hs_internal_meeting_notes": null, "hs_lastmodifieddate": "2024-02-05T01:40:30.343000+00:00", "hs_meeting_body": null, "hs_meeting_calendar_event_hash": "7e8970ad5f400444979d9c979d5369b4", "hs_meeting_change_id": "7231dcd51227b02a05d158f5e7a602f3", "hs_meeting_created_from_link_id": "6678679", "hs_meeting_end_time": "2024-02-05T14:15:00+00:00", "hs_meeting_external_url": "https://www.google.com/calendar/event?eid=aW1xcXYyZWRhOGg1cmg3NGdhYm5hZ2w2MG8gaW50ZWdyYXRpb24tdGVzdC11c2VyQGFpcmJ5dGUuaW8", "hs_meeting_location": null, "hs_meeting_location_type": null, "hs_meeting_ms_teams_payload": null, "hs_meeting_outcome": "SCHEDULED", "hs_meeting_payments_session_id": null, "hs_meeting_pre_meeting_prospect_reminders": null, "hs_meeting_source": "MEETINGS_PUBLIC", "hs_meeting_source_id": "imqqv2eda8h5rh74gabnagl60o", "hs_meeting_start_time": "2024-02-05T14:00:00+00:00", "hs_meeting_title": "Test User and Team-1 Airbyte", "hs_meeting_web_conference_meeting_id": null, "hs_merged_object_ids": null, "hs_modified_by": 12282590, "hs_object_id": 46837884323, "hs_object_source": "MEETINGS", "hs_object_source_detail_1": null, "hs_object_source_detail_2": null, "hs_object_source_detail_3": null, "hs_object_source_id": null, "hs_object_source_label": "MEETINGS", "hs_object_source_user_id": 12282590, "hs_outcome_canceled_count": 0, "hs_outcome_completed_count": 0, "hs_outcome_no_show_count": 0, "hs_outcome_rescheduled_count": 0, "hs_outcome_scheduled_count": 1, "hs_product_name": null, "hs_queue_membership_ids": null, "hs_read_only": null, "hs_roster_object_coordinates": null, "hs_scheduled_tasks": "{\"scheduledTasks\":[{\"engagementId\":46837884323,\"portalId\":8727216,\"engagementType\":\"MEETING\",\"taskType\":\"PRE_MEETING_NOTIFICATION\",\"timestamp\":1707139800000,\"uuid\":\"MEETING:7a71d47b-0a87-40c4-8e1a-a140184a29d0\"}]}", "hs_time_to_book_meeting_from_first_contact": 0, "hs_timestamp": "2024-02-05T14:00:00+00:00", "hs_timezone": "Europe/Warsaw", "hs_unique_creation_key": null, "hs_unique_id": "imqqv2eda8h5rh74gabnagl60o", "hs_updated_by_user_id": 12282590, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": "12282590", "hs_was_imported": null, "hubspot_owner_assigneddate": "2024-02-05T01:08:10.888000+00:00", "hubspot_owner_id": "52550153", "hubspot_team_id": null}, "createdAt": "2024-02-05T01:08:01.995Z", "updatedAt": "2024-02-05T01:40:30.343Z", "archived": false, "properties_hs_activity_type": null, "properties_hs_all_accessible_team_ids": null, "properties_hs_all_assigned_business_unit_ids": null, "properties_hs_all_owner_ids": "52550153", "properties_hs_all_team_ids": null, "properties_hs_at_mentioned_owner_ids": null, "properties_hs_attachment_ids": null, "properties_hs_attendee_owner_ids": null, "properties_hs_body_preview": null, "properties_hs_body_preview_html": null, "properties_hs_body_preview_is_truncated": false, "properties_hs_contact_first_outreach_date": null, "properties_hs_created_by": 12282590, "properties_hs_created_by_user_id": 12282590, "properties_hs_createdate": "2024-02-05T01:08:01.995000+00:00", "properties_hs_engagement_source": "MEETINGS", "properties_hs_engagement_source_id": null, "properties_hs_follow_up_action": null, "properties_hs_gdpr_deleted": null, "properties_hs_guest_emails": null, "properties_hs_i_cal_uid": "imqqv2eda8h5rh74gabnagl60o@google.com", "properties_hs_include_description_in_reminder": null, "properties_hs_internal_meeting_notes": null, "properties_hs_lastmodifieddate": "2024-02-05T01:40:30.343000+00:00", "properties_hs_meeting_body": null, "properties_hs_meeting_calendar_event_hash": "7e8970ad5f400444979d9c979d5369b4", "properties_hs_meeting_change_id": "7231dcd51227b02a05d158f5e7a602f3", "properties_hs_meeting_created_from_link_id": "6678679", "properties_hs_meeting_end_time": "2024-02-05T14:15:00+00:00", "properties_hs_meeting_external_url": "https://www.google.com/calendar/event?eid=aW1xcXYyZWRhOGg1cmg3NGdhYm5hZ2w2MG8gaW50ZWdyYXRpb24tdGVzdC11c2VyQGFpcmJ5dGUuaW8", "properties_hs_meeting_location": null, "properties_hs_meeting_location_type": null, "properties_hs_meeting_ms_teams_payload": null, "properties_hs_meeting_outcome": "SCHEDULED", "properties_hs_meeting_payments_session_id": null, "properties_hs_meeting_pre_meeting_prospect_reminders": null, "properties_hs_meeting_source": "MEETINGS_PUBLIC", "properties_hs_meeting_source_id": "imqqv2eda8h5rh74gabnagl60o", "properties_hs_meeting_start_time": "2024-02-05T14:00:00+00:00", "properties_hs_meeting_title": "Test User and Team-1 Airbyte", "properties_hs_meeting_web_conference_meeting_id": null, "properties_hs_merged_object_ids": null, "properties_hs_modified_by": 12282590, "properties_hs_object_id": 46837884323, "properties_hs_object_source": "MEETINGS", "properties_hs_object_source_detail_1": null, "properties_hs_object_source_detail_2": null, "properties_hs_object_source_detail_3": null, "properties_hs_object_source_id": null, "properties_hs_object_source_label": "MEETINGS", "properties_hs_object_source_user_id": 12282590, "properties_hs_outcome_canceled_count": 0, "properties_hs_outcome_completed_count": 0, "properties_hs_outcome_no_show_count": 0, "properties_hs_outcome_rescheduled_count": 0, "properties_hs_outcome_scheduled_count": 1, "properties_hs_product_name": null, "properties_hs_queue_membership_ids": null, "properties_hs_read_only": null, "properties_hs_roster_object_coordinates": null, "properties_hs_scheduled_tasks": "{\"scheduledTasks\":[{\"engagementId\":46837884323,\"portalId\":8727216,\"engagementType\":\"MEETING\",\"taskType\":\"PRE_MEETING_NOTIFICATION\",\"timestamp\":1707139800000,\"uuid\":\"MEETING:7a71d47b-0a87-40c4-8e1a-a140184a29d0\"}]}", "properties_hs_time_to_book_meeting_from_first_contact": 0, "properties_hs_timestamp": "2024-02-05T14:00:00+00:00", "properties_hs_timezone": "Europe/Warsaw", "properties_hs_unique_creation_key": null, "properties_hs_unique_id": "imqqv2eda8h5rh74gabnagl60o", "properties_hs_updated_by_user_id": 12282590, "properties_hs_user_ids_of_all_notification_followers": null, "properties_hs_user_ids_of_all_notification_unfollowers": null, "properties_hs_user_ids_of_all_owners": "12282590", "properties_hs_was_imported": null, "properties_hubspot_owner_assigneddate": "2024-02-05T01:08:10.888000+00:00", "properties_hubspot_owner_id": "52550153", "properties_hubspot_team_id": null}, "emitted_at": 1708015722269} {"stream": "engagements_meetings", "data": {"id": "46838182245", "properties": {"hs_activity_type": null, "hs_all_accessible_team_ids": null, "hs_all_assigned_business_unit_ids": null, "hs_all_owner_ids": "52550153", "hs_all_team_ids": null, "hs_at_mentioned_owner_ids": null, "hs_attachment_ids": null, "hs_attendee_owner_ids": null, "hs_body_preview": null, "hs_body_preview_html": null, "hs_body_preview_is_truncated": false, "hs_contact_first_outreach_date": "2024-02-05T15:15:00+00:00", "hs_created_by": 12282590, "hs_created_by_user_id": 12282590, "hs_createdate": "2024-02-05T01:08:32.416000+00:00", "hs_engagement_source": "MEETINGS", "hs_engagement_source_id": null, "hs_follow_up_action": null, "hs_gdpr_deleted": null, "hs_guest_emails": null, "hs_i_cal_uid": null, "hs_include_description_in_reminder": null, "hs_internal_meeting_notes": null, "hs_lastmodifieddate": "2024-02-05T01:08:37.402000+00:00", "hs_meeting_body": null, "hs_meeting_calendar_event_hash": "0b24520e196b77a0db079ab0357565e8", "hs_meeting_change_id": "9cc62faac2139a8ae373f992facb9504", "hs_meeting_created_from_link_id": "6678679", "hs_meeting_end_time": "2024-02-05T15:30:00+00:00", "hs_meeting_external_url": "https://www.google.com/calendar/event?eid=amg5N3RhcWppbjEzaGg4NDI0aXZoc3I0M2MgaW50ZWdyYXRpb24tdGVzdC11c2VyQGFpcmJ5dGUuaW8", "hs_meeting_location": null, "hs_meeting_location_type": null, "hs_meeting_ms_teams_payload": null, "hs_meeting_outcome": "SCHEDULED", "hs_meeting_payments_session_id": null, "hs_meeting_pre_meeting_prospect_reminders": null, "hs_meeting_source": "MEETINGS_PUBLIC", "hs_meeting_source_id": "jh97taqjin13hh8424ivhsr43c", "hs_meeting_start_time": "2024-02-05T15:15:00+00:00", "hs_meeting_title": "Test User and Team-1 Airbyte", "hs_meeting_web_conference_meeting_id": null, "hs_merged_object_ids": null, "hs_modified_by": 12282590, "hs_object_id": 46838182245, "hs_object_source": "MEETINGS", "hs_object_source_detail_1": null, "hs_object_source_detail_2": null, "hs_object_source_detail_3": null, "hs_object_source_id": null, "hs_object_source_label": "MEETINGS", "hs_object_source_user_id": 12282590, "hs_outcome_canceled_count": 0, "hs_outcome_completed_count": 0, "hs_outcome_no_show_count": 0, "hs_outcome_rescheduled_count": 0, "hs_outcome_scheduled_count": 1, "hs_product_name": null, "hs_queue_membership_ids": null, "hs_read_only": null, "hs_roster_object_coordinates": null, "hs_scheduled_tasks": "{\"scheduledTasks\":[{\"engagementId\":46838182245,\"portalId\":8727216,\"engagementType\":\"MEETING\",\"taskType\":\"PRE_MEETING_NOTIFICATION\",\"timestamp\":1707144300000,\"uuid\":\"MEETING:dc82686f-39ac-416f-ad15-4f2d706047c9\"}]}", "hs_time_to_book_meeting_from_first_contact": 0, "hs_timestamp": "2024-02-05T15:15:00+00:00", "hs_timezone": "Europe/Warsaw", "hs_unique_creation_key": null, "hs_unique_id": "jh97taqjin13hh8424ivhsr43c", "hs_updated_by_user_id": 12282590, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": "12282590", "hs_was_imported": null, "hubspot_owner_assigneddate": "2024-02-05T01:08:33.582000+00:00", "hubspot_owner_id": "52550153", "hubspot_team_id": null}, "createdAt": "2024-02-05T01:08:32.416Z", "updatedAt": "2024-02-05T01:08:37.402Z", "archived": false, "contacts": ["3201"], "properties_hs_activity_type": null, "properties_hs_all_accessible_team_ids": null, "properties_hs_all_assigned_business_unit_ids": null, "properties_hs_all_owner_ids": "52550153", "properties_hs_all_team_ids": null, "properties_hs_at_mentioned_owner_ids": null, "properties_hs_attachment_ids": null, "properties_hs_attendee_owner_ids": null, "properties_hs_body_preview": null, "properties_hs_body_preview_html": null, "properties_hs_body_preview_is_truncated": false, "properties_hs_contact_first_outreach_date": "2024-02-05T15:15:00+00:00", "properties_hs_created_by": 12282590, "properties_hs_created_by_user_id": 12282590, "properties_hs_createdate": "2024-02-05T01:08:32.416000+00:00", "properties_hs_engagement_source": "MEETINGS", "properties_hs_engagement_source_id": null, "properties_hs_follow_up_action": null, "properties_hs_gdpr_deleted": null, "properties_hs_guest_emails": null, "properties_hs_i_cal_uid": null, "properties_hs_include_description_in_reminder": null, "properties_hs_internal_meeting_notes": null, "properties_hs_lastmodifieddate": "2024-02-05T01:08:37.402000+00:00", "properties_hs_meeting_body": null, "properties_hs_meeting_calendar_event_hash": "0b24520e196b77a0db079ab0357565e8", "properties_hs_meeting_change_id": "9cc62faac2139a8ae373f992facb9504", "properties_hs_meeting_created_from_link_id": "6678679", "properties_hs_meeting_end_time": "2024-02-05T15:30:00+00:00", "properties_hs_meeting_external_url": "https://www.google.com/calendar/event?eid=amg5N3RhcWppbjEzaGg4NDI0aXZoc3I0M2MgaW50ZWdyYXRpb24tdGVzdC11c2VyQGFpcmJ5dGUuaW8", "properties_hs_meeting_location": null, "properties_hs_meeting_location_type": null, "properties_hs_meeting_ms_teams_payload": null, "properties_hs_meeting_outcome": "SCHEDULED", "properties_hs_meeting_payments_session_id": null, "properties_hs_meeting_pre_meeting_prospect_reminders": null, "properties_hs_meeting_source": "MEETINGS_PUBLIC", "properties_hs_meeting_source_id": "jh97taqjin13hh8424ivhsr43c", "properties_hs_meeting_start_time": "2024-02-05T15:15:00+00:00", "properties_hs_meeting_title": "Test User and Team-1 Airbyte", "properties_hs_meeting_web_conference_meeting_id": null, "properties_hs_merged_object_ids": null, "properties_hs_modified_by": 12282590, "properties_hs_object_id": 46838182245, "properties_hs_object_source": "MEETINGS", "properties_hs_object_source_detail_1": null, "properties_hs_object_source_detail_2": null, "properties_hs_object_source_detail_3": null, "properties_hs_object_source_id": null, "properties_hs_object_source_label": "MEETINGS", "properties_hs_object_source_user_id": 12282590, "properties_hs_outcome_canceled_count": 0, "properties_hs_outcome_completed_count": 0, "properties_hs_outcome_no_show_count": 0, "properties_hs_outcome_rescheduled_count": 0, "properties_hs_outcome_scheduled_count": 1, "properties_hs_product_name": null, "properties_hs_queue_membership_ids": null, "properties_hs_read_only": null, "properties_hs_roster_object_coordinates": null, "properties_hs_scheduled_tasks": "{\"scheduledTasks\":[{\"engagementId\":46838182245,\"portalId\":8727216,\"engagementType\":\"MEETING\",\"taskType\":\"PRE_MEETING_NOTIFICATION\",\"timestamp\":1707144300000,\"uuid\":\"MEETING:dc82686f-39ac-416f-ad15-4f2d706047c9\"}]}", "properties_hs_time_to_book_meeting_from_first_contact": 0, "properties_hs_timestamp": "2024-02-05T15:15:00+00:00", "properties_hs_timezone": "Europe/Warsaw", "properties_hs_unique_creation_key": null, "properties_hs_unique_id": "jh97taqjin13hh8424ivhsr43c", "properties_hs_updated_by_user_id": 12282590, "properties_hs_user_ids_of_all_notification_followers": null, "properties_hs_user_ids_of_all_notification_unfollowers": null, "properties_hs_user_ids_of_all_owners": "12282590", "properties_hs_was_imported": null, "properties_hubspot_owner_assigneddate": "2024-02-05T01:08:33.582000+00:00", "properties_hubspot_owner_id": "52550153", "properties_hubspot_team_id": null}, "emitted_at": 1708015722270} {"stream": "engagements_meetings", "data": {"id": "46838579861", "properties": {"hs_activity_type": null, "hs_all_accessible_team_ids": null, "hs_all_assigned_business_unit_ids": null, "hs_all_owner_ids": "52550153", "hs_all_team_ids": null, "hs_at_mentioned_owner_ids": null, "hs_attachment_ids": null, "hs_attendee_owner_ids": null, "hs_body_preview": "attendee description", "hs_body_preview_html": "\n \n \n

attendee description

\n \n", "hs_body_preview_is_truncated": false, "hs_contact_first_outreach_date": null, "hs_created_by": 12282590, "hs_created_by_user_id": 12282590, "hs_createdate": "2024-02-05T01:15:53.269000+00:00", "hs_engagement_source": "CRM_UI", "hs_engagement_source_id": "12282590", "hs_follow_up_action": null, "hs_gdpr_deleted": null, "hs_guest_emails": null, "hs_i_cal_uid": "c4rjadpo68o3cbb3cpj34b9kcgs62bb2ckrm8b9n68q38d336thm6c1h6g@google.com", "hs_include_description_in_reminder": true, "hs_internal_meeting_notes": "

test note

", "hs_lastmodifieddate": "2024-02-05T01:15:53.749000+00:00", "hs_meeting_body": "

attendee description

", "hs_meeting_calendar_event_hash": null, "hs_meeting_change_id": null, "hs_meeting_created_from_link_id": null, "hs_meeting_end_time": "2024-02-06T10:45:00+00:00", "hs_meeting_external_url": "https://www.google.com/calendar/event?eid=YzRyamFkcG82OG8zY2JiM2NwajM0YjlrY2dzNjJiYjJja3JtOGI5bjY4cTM4ZDMzNnRobTZjMWg2ZyBpbnRlZ3JhdGlvbi10ZXN0LXVzZXJAYWlyYnl0ZS5pbw", "hs_meeting_location": "test address location", "hs_meeting_location_type": "ADDRESS", "hs_meeting_ms_teams_payload": null, "hs_meeting_outcome": "SCHEDULED", "hs_meeting_payments_session_id": null, "hs_meeting_pre_meeting_prospect_reminders": null, "hs_meeting_source": "BIDIRECTIONAL_API", "hs_meeting_source_id": "c4rjadpo68o3cbb3cpj34b9kcgs62bb2ckrm8b9n68q38d336thm6c1h6g", "hs_meeting_start_time": "2024-02-06T10:15:00+00:00", "hs_meeting_title": "test hubspot deal meeting ", "hs_meeting_web_conference_meeting_id": null, "hs_merged_object_ids": null, "hs_modified_by": 12282590, "hs_object_id": 46838579861, "hs_object_source": "CRM_UI", "hs_object_source_detail_1": null, "hs_object_source_detail_2": null, "hs_object_source_detail_3": null, "hs_object_source_id": "userId:12282590", "hs_object_source_label": "CRM_UI", "hs_object_source_user_id": 12282590, "hs_outcome_canceled_count": 0, "hs_outcome_completed_count": 0, "hs_outcome_no_show_count": 0, "hs_outcome_rescheduled_count": 0, "hs_outcome_scheduled_count": 1, "hs_product_name": null, "hs_queue_membership_ids": null, "hs_read_only": null, "hs_roster_object_coordinates": null, "hs_scheduled_tasks": "{\"scheduledTasks\":[{\"engagementId\":46838579861,\"portalId\":8727216,\"engagementType\":\"MEETING\",\"taskType\":\"PRE_MEETING_NOTIFICATION\",\"timestamp\":1707212700000,\"uuid\":\"MEETING:cfda6fc6-d8ae-4e46-971a-4c483a6aec5c\"}]}", "hs_time_to_book_meeting_from_first_contact": 0, "hs_timestamp": "2024-02-06T10:15:00+00:00", "hs_timezone": "Europe/Warsaw", "hs_unique_creation_key": null, "hs_unique_id": "c4rjadpo68o3cbb3cpj34b9kcgs62bb2ckrm8b9n68q38d336thm6c1h6g", "hs_updated_by_user_id": 12282590, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": "12282590", "hs_was_imported": null, "hubspot_owner_assigneddate": "2024-02-05T01:15:53.269000+00:00", "hubspot_owner_id": "52550153", "hubspot_team_id": null}, "createdAt": "2024-02-05T01:15:53.269Z", "updatedAt": "2024-02-05T01:15:53.749Z", "archived": false, "companies": ["5000526215"], "deals": ["5388306989"], "properties_hs_activity_type": null, "properties_hs_all_accessible_team_ids": null, "properties_hs_all_assigned_business_unit_ids": null, "properties_hs_all_owner_ids": "52550153", "properties_hs_all_team_ids": null, "properties_hs_at_mentioned_owner_ids": null, "properties_hs_attachment_ids": null, "properties_hs_attendee_owner_ids": null, "properties_hs_body_preview": "attendee description", "properties_hs_body_preview_html": "\n \n \n

attendee description

\n \n", "properties_hs_body_preview_is_truncated": false, "properties_hs_contact_first_outreach_date": null, "properties_hs_created_by": 12282590, "properties_hs_created_by_user_id": 12282590, "properties_hs_createdate": "2024-02-05T01:15:53.269000+00:00", "properties_hs_engagement_source": "CRM_UI", "properties_hs_engagement_source_id": "12282590", "properties_hs_follow_up_action": null, "properties_hs_gdpr_deleted": null, "properties_hs_guest_emails": null, "properties_hs_i_cal_uid": "c4rjadpo68o3cbb3cpj34b9kcgs62bb2ckrm8b9n68q38d336thm6c1h6g@google.com", "properties_hs_include_description_in_reminder": true, "properties_hs_internal_meeting_notes": "

test note

", "properties_hs_lastmodifieddate": "2024-02-05T01:15:53.749000+00:00", "properties_hs_meeting_body": "

attendee description

", "properties_hs_meeting_calendar_event_hash": null, "properties_hs_meeting_change_id": null, "properties_hs_meeting_created_from_link_id": null, "properties_hs_meeting_end_time": "2024-02-06T10:45:00+00:00", "properties_hs_meeting_external_url": "https://www.google.com/calendar/event?eid=YzRyamFkcG82OG8zY2JiM2NwajM0YjlrY2dzNjJiYjJja3JtOGI5bjY4cTM4ZDMzNnRobTZjMWg2ZyBpbnRlZ3JhdGlvbi10ZXN0LXVzZXJAYWlyYnl0ZS5pbw", "properties_hs_meeting_location": "test address location", "properties_hs_meeting_location_type": "ADDRESS", "properties_hs_meeting_ms_teams_payload": null, "properties_hs_meeting_outcome": "SCHEDULED", "properties_hs_meeting_payments_session_id": null, "properties_hs_meeting_pre_meeting_prospect_reminders": null, "properties_hs_meeting_source": "BIDIRECTIONAL_API", "properties_hs_meeting_source_id": "c4rjadpo68o3cbb3cpj34b9kcgs62bb2ckrm8b9n68q38d336thm6c1h6g", "properties_hs_meeting_start_time": "2024-02-06T10:15:00+00:00", "properties_hs_meeting_title": "test hubspot deal meeting ", "properties_hs_meeting_web_conference_meeting_id": null, "properties_hs_merged_object_ids": null, "properties_hs_modified_by": 12282590, "properties_hs_object_id": 46838579861, "properties_hs_object_source": "CRM_UI", "properties_hs_object_source_detail_1": null, "properties_hs_object_source_detail_2": null, "properties_hs_object_source_detail_3": null, "properties_hs_object_source_id": "userId:12282590", "properties_hs_object_source_label": "CRM_UI", "properties_hs_object_source_user_id": 12282590, "properties_hs_outcome_canceled_count": 0, "properties_hs_outcome_completed_count": 0, "properties_hs_outcome_no_show_count": 0, "properties_hs_outcome_rescheduled_count": 0, "properties_hs_outcome_scheduled_count": 1, "properties_hs_product_name": null, "properties_hs_queue_membership_ids": null, "properties_hs_read_only": null, "properties_hs_roster_object_coordinates": null, "properties_hs_scheduled_tasks": "{\"scheduledTasks\":[{\"engagementId\":46838579861,\"portalId\":8727216,\"engagementType\":\"MEETING\",\"taskType\":\"PRE_MEETING_NOTIFICATION\",\"timestamp\":1707212700000,\"uuid\":\"MEETING:cfda6fc6-d8ae-4e46-971a-4c483a6aec5c\"}]}", "properties_hs_time_to_book_meeting_from_first_contact": 0, "properties_hs_timestamp": "2024-02-06T10:15:00+00:00", "properties_hs_timezone": "Europe/Warsaw", "properties_hs_unique_creation_key": null, "properties_hs_unique_id": "c4rjadpo68o3cbb3cpj34b9kcgs62bb2ckrm8b9n68q38d336thm6c1h6g", "properties_hs_updated_by_user_id": 12282590, "properties_hs_user_ids_of_all_notification_followers": null, "properties_hs_user_ids_of_all_notification_unfollowers": null, "properties_hs_user_ids_of_all_owners": "12282590", "properties_hs_was_imported": null, "properties_hubspot_owner_assigneddate": "2024-02-05T01:15:53.269000+00:00", "properties_hubspot_owner_id": "52550153", "properties_hubspot_team_id": null}, "emitted_at": 1708015722271} +{"stream": "leads", "data": {"id": "360315895939", "properties": {"hs_all_accessible_team_ids": null, "hs_all_assigned_business_unit_ids": null, "hs_all_owner_ids": "52550153", "hs_all_team_ids": null, "hs_associated_company_domain": "test.test", "hs_associated_company_name": "Test", "hs_associated_contact_email": null, "hs_associated_contact_firstname": null, "hs_associated_contact_lastname": null, "hs_calls_attempted_count": 0.0, "hs_calls_connected_count": 0.0, "hs_company_analytics_source": "DIRECT_TRAFFIC", "hs_company_analytics_source_data_1": "e3875d32-ab81-48f1-9e78-493eae864f12", "hs_company_analytics_source_data_2": null, "hs_company_is_target_account": null, "hs_company_last_activity_date": "2023-02-03T07:00:00+00:00", "hs_company_last_engagement_timestamp": null, "hs_company_last_engagement_type": null, "hs_company_last_webpage_visit_timestamp": "2024-03-21T20:00:45.296000+00:00", "hs_company_next_activity_date": null, "hs_company_next_activity_type": null, "hs_company_num_webpage_views": 0.0, "hs_company_timezone": "3", "hs_contact_analytics_source": null, "hs_contact_analytics_source_data_1": null, "hs_contact_analytics_source_data_2": null, "hs_contact_buying_role": null, "hs_contact_job_title": null, "hs_contact_last_activity_date": null, "hs_contact_last_engagement_timestamp": null, "hs_contact_last_engagement_type": null, "hs_contact_last_webpage_visit_timestamp": null, "hs_contact_next_activity_date": null, "hs_contact_next_activity_type": null, "hs_contact_num_webpage_views": null, "hs_contact_timezone": null, "hs_created_by_user_id": 12282590.0, "hs_createdate": "2024-08-30T15:09:05.573000+00:00", "hs_date_entered_attempting_stage_id_745667965": null, "hs_date_entered_connected_stage_id_2058487257": null, "hs_date_entered_new_stage_id_1318266061": "2024-08-30T15:09:05.573000+00:00", "hs_date_entered_qualified_stage_id_233247981": null, "hs_date_entered_unqualified_stage_id_1675714327": null, "hs_date_exited_attempting_stage_id_745667965": null, "hs_date_exited_connected_stage_id_2058487257": null, "hs_date_exited_new_stage_id_1318266061": null, "hs_date_exited_qualified_stage_id_233247981": null, "hs_date_exited_unqualified_stage_id_1675714327": null, "hs_emails_connected_count": 0.0, "hs_emails_connected_count_v2": 0.0, "hs_last_activity_date": "2023-02-03T07:00:00+00:00", "hs_last_engagement_timestamp": null, "hs_last_engagement_type": null, "hs_last_webpage_visit_timestamp": "2024-03-21T20:00:45.296000+00:00", "hs_lastmodifieddate": "2024-08-30T15:13:48.940000+00:00", "hs_lead_associated_deal_pipeline_stage": null, "hs_lead_associated_deals_count": 0.0, "hs_lead_call_count": 0.0, "hs_lead_closed_won_deals_amount": null, "hs_lead_communication_count": 0.0, "hs_lead_currency_code": null, "hs_lead_disqualification_note": null, "hs_lead_disqualification_reason": null, "hs_lead_email_count": 0.0, "hs_lead_first_outreach_date": null, "hs_lead_flow_id": null, "hs_lead_import_unique_key": null, "hs_lead_inferred_pseudostage": "NEW_STAGE", "hs_lead_is_disqualified": 0.0, "hs_lead_is_in_progress": 0.0, "hs_lead_is_new": 1.0, "hs_lead_is_open": 1.0, "hs_lead_is_qualified": 0.0, "hs_lead_label": "COLD", "hs_lead_meeting_count": 0.0, "hs_lead_name": "Test Lead", "hs_lead_name_calculated": "Test 2024-08", "hs_lead_outreach_activity_count": 0.0, "hs_lead_pipeline_value": null, "hs_lead_primary_company_owner": "52550153", "hs_lead_primary_contact_owner": null, "hs_lead_source": "DIRECT_TRAFFIC", "hs_lead_source_company_lifecycle_stage": "customer", "hs_lead_source_contact_lifecycle_stage": null, "hs_lead_source_drill_down_1": "e3875d32-ab81-48f1-9e78-493eae864f12", "hs_lead_source_drill_down_2": null, "hs_lead_source_lifecycle_stage": "customer", "hs_lead_time_to_first_outreach": null, "hs_lead_title": null, "hs_lead_type": "NEW_BUSINESS", "hs_meetings_connected_count": 0.0, "hs_merged_object_ids": null, "hs_next_activity_date": null, "hs_next_activity_type": null, "hs_num_webpage_views": 0.0, "hs_object_id": 360315895939.0, "hs_object_source": "CRM_UI", "hs_object_source_detail_1": null, "hs_object_source_detail_2": null, "hs_object_source_detail_3": null, "hs_object_source_id": "userId:12282590", "hs_object_source_label": "CRM_UI", "hs_object_source_user_id": 12282590.0, "hs_owner_id_calculated": "52550153", "hs_pipeline": "lead-pipeline-id", "hs_pipeline_stage": "new-stage-id", "hs_pipeline_stage_category": "NEW", "hs_pipeline_stage_category_last_updated_at": "2024-08-30T15:13:48.940000+00:00", "hs_pipeline_stage_category_v2": "NEW", "hs_primary_associated_object_name": "Test", "hs_primary_company_id": 11481383026.0, "hs_primary_contact_enrolled_in_sequence": false, "hs_primary_contact_id": null, "hs_read_only": null, "hs_shared_team_ids": null, "hs_shared_user_ids": null, "hs_tag_ids": null, "hs_time_in_attempting_stage_id_745667965": null, "hs_time_in_connected_stage_id_2058487257": null, "hs_time_in_new_stage_id_1318266061": 6660657718.0, "hs_time_in_qualified_stage_id_233247981": null, "hs_time_in_unqualified_stage_id_1675714327": null, "hs_unique_creation_key": null, "hs_updated_by_user_id": 12282590.0, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": "12282590", "hs_v2_cumulative_time_in_attempting_stage_id_745667965": null, "hs_v2_cumulative_time_in_connected_stage_id_2058487257": null, "hs_v2_cumulative_time_in_new_stage_id_1318266061": null, "hs_v2_cumulative_time_in_qualified_stage_id_233247981": null, "hs_v2_cumulative_time_in_unqualified_stage_id_1675714327": null, "hs_v2_date_entered_attempting_stage_id_745667965": null, "hs_v2_date_entered_connected_stage_id_2058487257": null, "hs_v2_date_entered_new_stage_id_1318266061": "2024-08-30T15:09:05.573000+00:00", "hs_v2_date_entered_qualified_stage_id_233247981": null, "hs_v2_date_entered_unqualified_stage_id_1675714327": null, "hs_v2_date_exited_attempting_stage_id_745667965": null, "hs_v2_date_exited_connected_stage_id_2058487257": null, "hs_v2_date_exited_new_stage_id_1318266061": null, "hs_v2_date_exited_qualified_stage_id_233247981": null, "hs_v2_date_exited_unqualified_stage_id_1675714327": null, "hs_v2_latest_time_in_attempting_stage_id_745667965": null, "hs_v2_latest_time_in_connected_stage_id_2058487257": null, "hs_v2_latest_time_in_new_stage_id_1318266061": null, "hs_v2_latest_time_in_qualified_stage_id_233247981": null, "hs_v2_latest_time_in_unqualified_stage_id_1675714327": null, "hs_was_imported": null, "hs_workflow_updated_lifecycle_stage_of_company": null, "hs_workflow_updated_lifecycle_stage_of_contact": null, "hubspot_owner_assigneddate": "2024-08-30T15:09:05.573000+00:00", "hubspot_owner_id": "52550153", "hubspot_team_id": null}, "createdAt": "2024-08-30T15:09:05.573Z", "updatedAt": "2024-08-30T15:13:48.940Z", "archived": false, "companies": ["11481383026", "11481383026"], "properties_hs_all_accessible_team_ids": null, "properties_hs_all_assigned_business_unit_ids": null, "properties_hs_all_owner_ids": "52550153", "properties_hs_all_team_ids": null, "properties_hs_associated_company_domain": "test.test", "properties_hs_associated_company_name": "Test", "properties_hs_associated_contact_email": null, "properties_hs_associated_contact_firstname": null, "properties_hs_associated_contact_lastname": null, "properties_hs_calls_attempted_count": 0.0, "properties_hs_calls_connected_count": 0.0, "properties_hs_company_analytics_source": "DIRECT_TRAFFIC", "properties_hs_company_analytics_source_data_1": "e3875d32-ab81-48f1-9e78-493eae864f12", "properties_hs_company_analytics_source_data_2": null, "properties_hs_company_is_target_account": null, "properties_hs_company_last_activity_date": "2023-02-03T07:00:00+00:00", "properties_hs_company_last_engagement_timestamp": null, "properties_hs_company_last_engagement_type": null, "properties_hs_company_last_webpage_visit_timestamp": "2024-03-21T20:00:45.296000+00:00", "properties_hs_company_next_activity_date": null, "properties_hs_company_next_activity_type": null, "properties_hs_company_num_webpage_views": 0.0, "properties_hs_company_timezone": "3", "properties_hs_contact_analytics_source": null, "properties_hs_contact_analytics_source_data_1": null, "properties_hs_contact_analytics_source_data_2": null, "properties_hs_contact_buying_role": null, "properties_hs_contact_job_title": null, "properties_hs_contact_last_activity_date": null, "properties_hs_contact_last_engagement_timestamp": null, "properties_hs_contact_last_engagement_type": null, "properties_hs_contact_last_webpage_visit_timestamp": null, "properties_hs_contact_next_activity_date": null, "properties_hs_contact_next_activity_type": null, "properties_hs_contact_num_webpage_views": null, "properties_hs_contact_timezone": null, "properties_hs_created_by_user_id": 12282590.0, "properties_hs_createdate": "2024-08-30T15:09:05.573000+00:00", "properties_hs_date_entered_attempting_stage_id_745667965": null, "properties_hs_date_entered_connected_stage_id_2058487257": null, "properties_hs_date_entered_new_stage_id_1318266061": "2024-08-30T15:09:05.573000+00:00", "properties_hs_date_entered_qualified_stage_id_233247981": null, "properties_hs_date_entered_unqualified_stage_id_1675714327": null, "properties_hs_date_exited_attempting_stage_id_745667965": null, "properties_hs_date_exited_connected_stage_id_2058487257": null, "properties_hs_date_exited_new_stage_id_1318266061": null, "properties_hs_date_exited_qualified_stage_id_233247981": null, "properties_hs_date_exited_unqualified_stage_id_1675714327": null, "properties_hs_emails_connected_count": 0.0, "properties_hs_emails_connected_count_v2": 0.0, "properties_hs_last_activity_date": "2023-02-03T07:00:00+00:00", "properties_hs_last_engagement_timestamp": null, "properties_hs_last_engagement_type": null, "properties_hs_last_webpage_visit_timestamp": "2024-03-21T20:00:45.296000+00:00", "properties_hs_lastmodifieddate": "2024-08-30T15:13:48.940000+00:00", "properties_hs_lead_associated_deal_pipeline_stage": null, "properties_hs_lead_associated_deals_count": 0.0, "properties_hs_lead_call_count": 0.0, "properties_hs_lead_closed_won_deals_amount": null, "properties_hs_lead_communication_count": 0.0, "properties_hs_lead_currency_code": null, "properties_hs_lead_disqualification_note": null, "properties_hs_lead_disqualification_reason": null, "properties_hs_lead_email_count": 0.0, "properties_hs_lead_first_outreach_date": null, "properties_hs_lead_flow_id": null, "properties_hs_lead_import_unique_key": null, "properties_hs_lead_inferred_pseudostage": "NEW_STAGE", "properties_hs_lead_is_disqualified": 0.0, "properties_hs_lead_is_in_progress": 0.0, "properties_hs_lead_is_new": 1.0, "properties_hs_lead_is_open": 1.0, "properties_hs_lead_is_qualified": 0.0, "properties_hs_lead_label": "COLD", "properties_hs_lead_meeting_count": 0.0, "properties_hs_lead_name": "Test Lead", "properties_hs_lead_name_calculated": "Test 2024-08", "properties_hs_lead_outreach_activity_count": 0.0, "properties_hs_lead_pipeline_value": null, "properties_hs_lead_primary_company_owner": "52550153", "properties_hs_lead_primary_contact_owner": null, "properties_hs_lead_source": "DIRECT_TRAFFIC", "properties_hs_lead_source_company_lifecycle_stage": "customer", "properties_hs_lead_source_contact_lifecycle_stage": null, "properties_hs_lead_source_drill_down_1": "e3875d32-ab81-48f1-9e78-493eae864f12", "properties_hs_lead_source_drill_down_2": null, "properties_hs_lead_source_lifecycle_stage": "customer", "properties_hs_lead_time_to_first_outreach": null, "properties_hs_lead_title": null, "properties_hs_lead_type": "NEW_BUSINESS", "properties_hs_meetings_connected_count": 0.0, "properties_hs_merged_object_ids": null, "properties_hs_next_activity_date": null, "properties_hs_next_activity_type": null, "properties_hs_num_webpage_views": 0.0, "properties_hs_object_id": 360315895939.0, "properties_hs_object_source": "CRM_UI", "properties_hs_object_source_detail_1": null, "properties_hs_object_source_detail_2": null, "properties_hs_object_source_detail_3": null, "properties_hs_object_source_id": "userId:12282590", "properties_hs_object_source_label": "CRM_UI", "properties_hs_object_source_user_id": 12282590.0, "properties_hs_owner_id_calculated": "52550153", "properties_hs_pipeline": "lead-pipeline-id", "properties_hs_pipeline_stage": "new-stage-id", "properties_hs_pipeline_stage_category": "NEW", "properties_hs_pipeline_stage_category_last_updated_at": "2024-08-30T15:13:48.940000+00:00", "properties_hs_pipeline_stage_category_v2": "NEW", "properties_hs_primary_associated_object_name": "Test", "properties_hs_primary_company_id": 11481383026.0, "properties_hs_primary_contact_enrolled_in_sequence": false, "properties_hs_primary_contact_id": null, "properties_hs_read_only": null, "properties_hs_shared_team_ids": null, "properties_hs_shared_user_ids": null, "properties_hs_tag_ids": null, "properties_hs_time_in_attempting_stage_id_745667965": null, "properties_hs_time_in_connected_stage_id_2058487257": null, "properties_hs_time_in_new_stage_id_1318266061": 6660657718.0, "properties_hs_time_in_qualified_stage_id_233247981": null, "properties_hs_time_in_unqualified_stage_id_1675714327": null, "properties_hs_unique_creation_key": null, "properties_hs_updated_by_user_id": 12282590.0, "properties_hs_user_ids_of_all_notification_followers": null, "properties_hs_user_ids_of_all_notification_unfollowers": null, "properties_hs_user_ids_of_all_owners": "12282590", "properties_hs_v2_cumulative_time_in_attempting_stage_id_745667965": null, "properties_hs_v2_cumulative_time_in_connected_stage_id_2058487257": null, "properties_hs_v2_cumulative_time_in_new_stage_id_1318266061": null, "properties_hs_v2_cumulative_time_in_qualified_stage_id_233247981": null, "properties_hs_v2_cumulative_time_in_unqualified_stage_id_1675714327": null, "properties_hs_v2_date_entered_attempting_stage_id_745667965": null, "properties_hs_v2_date_entered_connected_stage_id_2058487257": null, "properties_hs_v2_date_entered_new_stage_id_1318266061": "2024-08-30T15:09:05.573000+00:00", "properties_hs_v2_date_entered_qualified_stage_id_233247981": null, "properties_hs_v2_date_entered_unqualified_stage_id_1675714327": null, "properties_hs_v2_date_exited_attempting_stage_id_745667965": null, "properties_hs_v2_date_exited_connected_stage_id_2058487257": null, "properties_hs_v2_date_exited_new_stage_id_1318266061": null, "properties_hs_v2_date_exited_qualified_stage_id_233247981": null, "properties_hs_v2_date_exited_unqualified_stage_id_1675714327": null, "properties_hs_v2_latest_time_in_attempting_stage_id_745667965": null, "properties_hs_v2_latest_time_in_connected_stage_id_2058487257": null, "properties_hs_v2_latest_time_in_new_stage_id_1318266061": null, "properties_hs_v2_latest_time_in_qualified_stage_id_233247981": null, "properties_hs_v2_latest_time_in_unqualified_stage_id_1675714327": null, "properties_hs_was_imported": null, "properties_hs_workflow_updated_lifecycle_stage_of_company": null, "properties_hs_workflow_updated_lifecycle_stage_of_contact": null, "properties_hubspot_owner_assigneddate": "2024-08-30T15:09:05.573000+00:00", "properties_hubspot_owner_id": "52550153", "properties_hubspot_team_id": null}, "emitted_at": 1731691365786} +{"stream": "leads", "data": {"id": "360315896441", "properties": {"hs_all_accessible_team_ids": null, "hs_all_assigned_business_unit_ids": null, "hs_all_owner_ids": "65568800", "hs_all_team_ids": null, "hs_associated_company_domain": "test.domain.net", "hs_associated_company_name": "test company 81", "hs_associated_contact_email": null, "hs_associated_contact_firstname": null, "hs_associated_contact_lastname": null, "hs_calls_attempted_count": 0.0, "hs_calls_connected_count": 0.0, "hs_company_analytics_source": null, "hs_company_analytics_source_data_1": null, "hs_company_analytics_source_data_2": null, "hs_company_is_target_account": null, "hs_company_last_activity_date": null, "hs_company_last_engagement_timestamp": null, "hs_company_last_engagement_type": null, "hs_company_last_webpage_visit_timestamp": null, "hs_company_next_activity_date": null, "hs_company_next_activity_type": null, "hs_company_num_webpage_views": null, "hs_company_timezone": "Asia/Dhaka", "hs_contact_analytics_source": null, "hs_contact_analytics_source_data_1": null, "hs_contact_analytics_source_data_2": null, "hs_contact_buying_role": null, "hs_contact_job_title": null, "hs_contact_last_activity_date": null, "hs_contact_last_engagement_timestamp": null, "hs_contact_last_engagement_type": null, "hs_contact_last_webpage_visit_timestamp": null, "hs_contact_next_activity_date": null, "hs_contact_next_activity_type": null, "hs_contact_num_webpage_views": null, "hs_contact_timezone": null, "hs_created_by_user_id": 12282590.0, "hs_createdate": "2024-08-30T15:09:30.342000+00:00", "hs_date_entered_attempting_stage_id_745667965": null, "hs_date_entered_connected_stage_id_2058487257": null, "hs_date_entered_new_stage_id_1318266061": "2024-08-30T15:09:30.342000+00:00", "hs_date_entered_qualified_stage_id_233247981": null, "hs_date_entered_unqualified_stage_id_1675714327": null, "hs_date_exited_attempting_stage_id_745667965": null, "hs_date_exited_connected_stage_id_2058487257": null, "hs_date_exited_new_stage_id_1318266061": null, "hs_date_exited_qualified_stage_id_233247981": null, "hs_date_exited_unqualified_stage_id_1675714327": null, "hs_emails_connected_count": 0.0, "hs_emails_connected_count_v2": 0.0, "hs_last_activity_date": null, "hs_last_engagement_timestamp": null, "hs_last_engagement_type": null, "hs_last_webpage_visit_timestamp": null, "hs_lastmodifieddate": "2024-08-30T15:13:08.423000+00:00", "hs_lead_associated_deal_pipeline_stage": null, "hs_lead_associated_deals_count": 0.0, "hs_lead_call_count": 0.0, "hs_lead_closed_won_deals_amount": null, "hs_lead_communication_count": 0.0, "hs_lead_currency_code": null, "hs_lead_disqualification_note": null, "hs_lead_disqualification_reason": null, "hs_lead_email_count": 0.0, "hs_lead_first_outreach_date": null, "hs_lead_flow_id": null, "hs_lead_import_unique_key": null, "hs_lead_inferred_pseudostage": "NEW_STAGE", "hs_lead_is_disqualified": 0.0, "hs_lead_is_in_progress": 0.0, "hs_lead_is_new": 1.0, "hs_lead_is_open": 1.0, "hs_lead_is_qualified": 0.0, "hs_lead_label": null, "hs_lead_meeting_count": 0.0, "hs_lead_name": "test company 81", "hs_lead_name_calculated": "test company 81 2024-08", "hs_lead_outreach_activity_count": 0.0, "hs_lead_pipeline_value": null, "hs_lead_primary_company_owner": "65568800", "hs_lead_primary_contact_owner": null, "hs_lead_source": null, "hs_lead_source_company_lifecycle_stage": "salesqualifiedlead", "hs_lead_source_contact_lifecycle_stage": null, "hs_lead_source_drill_down_1": null, "hs_lead_source_drill_down_2": null, "hs_lead_source_lifecycle_stage": "salesqualifiedlead", "hs_lead_time_to_first_outreach": null, "hs_lead_title": null, "hs_lead_type": "NEW_BUSINESS", "hs_meetings_connected_count": 0.0, "hs_merged_object_ids": null, "hs_next_activity_date": null, "hs_next_activity_type": null, "hs_num_webpage_views": null, "hs_object_id": 360315896441.0, "hs_object_source": "CRM_UI", "hs_object_source_detail_1": null, "hs_object_source_detail_2": null, "hs_object_source_detail_3": null, "hs_object_source_id": "userId:12282590", "hs_object_source_label": "CRM_UI", "hs_object_source_user_id": 12282590.0, "hs_owner_id_calculated": "65568800", "hs_pipeline": "lead-pipeline-id", "hs_pipeline_stage": "new-stage-id", "hs_pipeline_stage_category": "NEW", "hs_pipeline_stage_category_last_updated_at": "2024-08-30T15:13:08.423000+00:00", "hs_pipeline_stage_category_v2": "NEW", "hs_primary_associated_object_name": "test company 81", "hs_primary_company_id": 7097805655.0, "hs_primary_contact_enrolled_in_sequence": false, "hs_primary_contact_id": null, "hs_read_only": null, "hs_shared_team_ids": null, "hs_shared_user_ids": null, "hs_tag_ids": null, "hs_time_in_attempting_stage_id_745667965": null, "hs_time_in_connected_stage_id_2058487257": null, "hs_time_in_new_stage_id_1318266061": 6660632949.0, "hs_time_in_qualified_stage_id_233247981": null, "hs_time_in_unqualified_stage_id_1675714327": null, "hs_unique_creation_key": null, "hs_updated_by_user_id": 12282590.0, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": "23660229", "hs_v2_cumulative_time_in_attempting_stage_id_745667965": null, "hs_v2_cumulative_time_in_connected_stage_id_2058487257": null, "hs_v2_cumulative_time_in_new_stage_id_1318266061": null, "hs_v2_cumulative_time_in_qualified_stage_id_233247981": null, "hs_v2_cumulative_time_in_unqualified_stage_id_1675714327": null, "hs_v2_date_entered_attempting_stage_id_745667965": null, "hs_v2_date_entered_connected_stage_id_2058487257": null, "hs_v2_date_entered_new_stage_id_1318266061": "2024-08-30T15:09:30.342000+00:00", "hs_v2_date_entered_qualified_stage_id_233247981": null, "hs_v2_date_entered_unqualified_stage_id_1675714327": null, "hs_v2_date_exited_attempting_stage_id_745667965": null, "hs_v2_date_exited_connected_stage_id_2058487257": null, "hs_v2_date_exited_new_stage_id_1318266061": null, "hs_v2_date_exited_qualified_stage_id_233247981": null, "hs_v2_date_exited_unqualified_stage_id_1675714327": null, "hs_v2_latest_time_in_attempting_stage_id_745667965": null, "hs_v2_latest_time_in_connected_stage_id_2058487257": null, "hs_v2_latest_time_in_new_stage_id_1318266061": null, "hs_v2_latest_time_in_qualified_stage_id_233247981": null, "hs_v2_latest_time_in_unqualified_stage_id_1675714327": null, "hs_was_imported": null, "hs_workflow_updated_lifecycle_stage_of_company": null, "hs_workflow_updated_lifecycle_stage_of_contact": null, "hubspot_owner_assigneddate": "2024-08-30T15:09:34.777000+00:00", "hubspot_owner_id": "65568800", "hubspot_team_id": null}, "createdAt": "2024-08-30T15:09:30.342Z", "updatedAt": "2024-08-30T15:13:08.423Z", "archived": false, "companies": ["7097805655", "7097805655"], "properties_hs_all_accessible_team_ids": null, "properties_hs_all_assigned_business_unit_ids": null, "properties_hs_all_owner_ids": "65568800", "properties_hs_all_team_ids": null, "properties_hs_associated_company_domain": "test.domain.net", "properties_hs_associated_company_name": "test company 81", "properties_hs_associated_contact_email": null, "properties_hs_associated_contact_firstname": null, "properties_hs_associated_contact_lastname": null, "properties_hs_calls_attempted_count": 0.0, "properties_hs_calls_connected_count": 0.0, "properties_hs_company_analytics_source": null, "properties_hs_company_analytics_source_data_1": null, "properties_hs_company_analytics_source_data_2": null, "properties_hs_company_is_target_account": null, "properties_hs_company_last_activity_date": null, "properties_hs_company_last_engagement_timestamp": null, "properties_hs_company_last_engagement_type": null, "properties_hs_company_last_webpage_visit_timestamp": null, "properties_hs_company_next_activity_date": null, "properties_hs_company_next_activity_type": null, "properties_hs_company_num_webpage_views": null, "properties_hs_company_timezone": "Asia/Dhaka", "properties_hs_contact_analytics_source": null, "properties_hs_contact_analytics_source_data_1": null, "properties_hs_contact_analytics_source_data_2": null, "properties_hs_contact_buying_role": null, "properties_hs_contact_job_title": null, "properties_hs_contact_last_activity_date": null, "properties_hs_contact_last_engagement_timestamp": null, "properties_hs_contact_last_engagement_type": null, "properties_hs_contact_last_webpage_visit_timestamp": null, "properties_hs_contact_next_activity_date": null, "properties_hs_contact_next_activity_type": null, "properties_hs_contact_num_webpage_views": null, "properties_hs_contact_timezone": null, "properties_hs_created_by_user_id": 12282590.0, "properties_hs_createdate": "2024-08-30T15:09:30.342000+00:00", "properties_hs_date_entered_attempting_stage_id_745667965": null, "properties_hs_date_entered_connected_stage_id_2058487257": null, "properties_hs_date_entered_new_stage_id_1318266061": "2024-08-30T15:09:30.342000+00:00", "properties_hs_date_entered_qualified_stage_id_233247981": null, "properties_hs_date_entered_unqualified_stage_id_1675714327": null, "properties_hs_date_exited_attempting_stage_id_745667965": null, "properties_hs_date_exited_connected_stage_id_2058487257": null, "properties_hs_date_exited_new_stage_id_1318266061": null, "properties_hs_date_exited_qualified_stage_id_233247981": null, "properties_hs_date_exited_unqualified_stage_id_1675714327": null, "properties_hs_emails_connected_count": 0.0, "properties_hs_emails_connected_count_v2": 0.0, "properties_hs_last_activity_date": null, "properties_hs_last_engagement_timestamp": null, "properties_hs_last_engagement_type": null, "properties_hs_last_webpage_visit_timestamp": null, "properties_hs_lastmodifieddate": "2024-08-30T15:13:08.423000+00:00", "properties_hs_lead_associated_deal_pipeline_stage": null, "properties_hs_lead_associated_deals_count": 0.0, "properties_hs_lead_call_count": 0.0, "properties_hs_lead_closed_won_deals_amount": null, "properties_hs_lead_communication_count": 0.0, "properties_hs_lead_currency_code": null, "properties_hs_lead_disqualification_note": null, "properties_hs_lead_disqualification_reason": null, "properties_hs_lead_email_count": 0.0, "properties_hs_lead_first_outreach_date": null, "properties_hs_lead_flow_id": null, "properties_hs_lead_import_unique_key": null, "properties_hs_lead_inferred_pseudostage": "NEW_STAGE", "properties_hs_lead_is_disqualified": 0.0, "properties_hs_lead_is_in_progress": 0.0, "properties_hs_lead_is_new": 1.0, "properties_hs_lead_is_open": 1.0, "properties_hs_lead_is_qualified": 0.0, "properties_hs_lead_label": null, "properties_hs_lead_meeting_count": 0.0, "properties_hs_lead_name": "test company 81", "properties_hs_lead_name_calculated": "test company 81 2024-08", "properties_hs_lead_outreach_activity_count": 0.0, "properties_hs_lead_pipeline_value": null, "properties_hs_lead_primary_company_owner": "65568800", "properties_hs_lead_primary_contact_owner": null, "properties_hs_lead_source": null, "properties_hs_lead_source_company_lifecycle_stage": "salesqualifiedlead", "properties_hs_lead_source_contact_lifecycle_stage": null, "properties_hs_lead_source_drill_down_1": null, "properties_hs_lead_source_drill_down_2": null, "properties_hs_lead_source_lifecycle_stage": "salesqualifiedlead", "properties_hs_lead_time_to_first_outreach": null, "properties_hs_lead_title": null, "properties_hs_lead_type": "NEW_BUSINESS", "properties_hs_meetings_connected_count": 0.0, "properties_hs_merged_object_ids": null, "properties_hs_next_activity_date": null, "properties_hs_next_activity_type": null, "properties_hs_num_webpage_views": null, "properties_hs_object_id": 360315896441.0, "properties_hs_object_source": "CRM_UI", "properties_hs_object_source_detail_1": null, "properties_hs_object_source_detail_2": null, "properties_hs_object_source_detail_3": null, "properties_hs_object_source_id": "userId:12282590", "properties_hs_object_source_label": "CRM_UI", "properties_hs_object_source_user_id": 12282590.0, "properties_hs_owner_id_calculated": "65568800", "properties_hs_pipeline": "lead-pipeline-id", "properties_hs_pipeline_stage": "new-stage-id", "properties_hs_pipeline_stage_category": "NEW", "properties_hs_pipeline_stage_category_last_updated_at": "2024-08-30T15:13:08.423000+00:00", "properties_hs_pipeline_stage_category_v2": "NEW", "properties_hs_primary_associated_object_name": "test company 81", "properties_hs_primary_company_id": 7097805655.0, "properties_hs_primary_contact_enrolled_in_sequence": false, "properties_hs_primary_contact_id": null, "properties_hs_read_only": null, "properties_hs_shared_team_ids": null, "properties_hs_shared_user_ids": null, "properties_hs_tag_ids": null, "properties_hs_time_in_attempting_stage_id_745667965": null, "properties_hs_time_in_connected_stage_id_2058487257": null, "properties_hs_time_in_new_stage_id_1318266061": 6660632949.0, "properties_hs_time_in_qualified_stage_id_233247981": null, "properties_hs_time_in_unqualified_stage_id_1675714327": null, "properties_hs_unique_creation_key": null, "properties_hs_updated_by_user_id": 12282590.0, "properties_hs_user_ids_of_all_notification_followers": null, "properties_hs_user_ids_of_all_notification_unfollowers": null, "properties_hs_user_ids_of_all_owners": "23660229", "properties_hs_v2_cumulative_time_in_attempting_stage_id_745667965": null, "properties_hs_v2_cumulative_time_in_connected_stage_id_2058487257": null, "properties_hs_v2_cumulative_time_in_new_stage_id_1318266061": null, "properties_hs_v2_cumulative_time_in_qualified_stage_id_233247981": null, "properties_hs_v2_cumulative_time_in_unqualified_stage_id_1675714327": null, "properties_hs_v2_date_entered_attempting_stage_id_745667965": null, "properties_hs_v2_date_entered_connected_stage_id_2058487257": null, "properties_hs_v2_date_entered_new_stage_id_1318266061": "2024-08-30T15:09:30.342000+00:00", "properties_hs_v2_date_entered_qualified_stage_id_233247981": null, "properties_hs_v2_date_entered_unqualified_stage_id_1675714327": null, "properties_hs_v2_date_exited_attempting_stage_id_745667965": null, "properties_hs_v2_date_exited_connected_stage_id_2058487257": null, "properties_hs_v2_date_exited_new_stage_id_1318266061": null, "properties_hs_v2_date_exited_qualified_stage_id_233247981": null, "properties_hs_v2_date_exited_unqualified_stage_id_1675714327": null, "properties_hs_v2_latest_time_in_attempting_stage_id_745667965": null, "properties_hs_v2_latest_time_in_connected_stage_id_2058487257": null, "properties_hs_v2_latest_time_in_new_stage_id_1318266061": null, "properties_hs_v2_latest_time_in_qualified_stage_id_233247981": null, "properties_hs_v2_latest_time_in_unqualified_stage_id_1675714327": null, "properties_hs_was_imported": null, "properties_hs_workflow_updated_lifecycle_stage_of_company": null, "properties_hs_workflow_updated_lifecycle_stage_of_contact": null, "properties_hubspot_owner_assigneddate": "2024-08-30T15:09:34.777000+00:00", "properties_hubspot_owner_id": "65568800", "properties_hubspot_team_id": null}, "emitted_at": 1731691365788} \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-hubspot/integration_tests/full_refresh_oauth_catalog.json b/airbyte-integrations/connectors/source-hubspot/integration_tests/full_refresh_oauth_catalog.json index 1ad8473ae64f..08fafa813976 100644 --- a/airbyte-integrations/connectors/source-hubspot/integration_tests/full_refresh_oauth_catalog.json +++ b/airbyte-integrations/connectors/source-hubspot/integration_tests/full_refresh_oauth_catalog.json @@ -138,6 +138,15 @@ "sync_mode": "full_refresh", "destination_sync_mode": "overwrite" }, + { + "stream": { + "name": "leads", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, { "stream": { "name": "line_items", diff --git a/airbyte-integrations/connectors/source-hubspot/integration_tests/incremental_catalog.json b/airbyte-integrations/connectors/source-hubspot/integration_tests/incremental_catalog.json index ccab47f3a4f0..9175ed2b72aa 100644 --- a/airbyte-integrations/connectors/source-hubspot/integration_tests/incremental_catalog.json +++ b/airbyte-integrations/connectors/source-hubspot/integration_tests/incremental_catalog.json @@ -204,6 +204,18 @@ "cursor_field": ["updatedAt"], "destination_sync_mode": "append" }, + { + "stream": { + "name": "leads", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updatedAt"] + }, + "sync_mode": "incremental", + "cursor_field": ["updatedAt"], + "destination_sync_mode": "append" + }, { "stream": { "name": "line_items", diff --git a/airbyte-integrations/connectors/source-hubspot/integration_tests/test_associations.py b/airbyte-integrations/connectors/source-hubspot/integration_tests/test_associations.py index 9e7e8054a273..05c6d7814809 100644 --- a/airbyte-integrations/connectors/source-hubspot/integration_tests/test_associations.py +++ b/airbyte-integrations/connectors/source-hubspot/integration_tests/test_associations.py @@ -5,9 +5,10 @@ import logging import pytest -from airbyte_cdk.models import ConfiguredAirbyteCatalog, Type from source_hubspot.source import SourceHubspot +from airbyte_cdk.models import ConfiguredAirbyteCatalog, Type + @pytest.fixture def source(): diff --git a/airbyte-integrations/connectors/source-hubspot/main.py b/airbyte-integrations/connectors/source-hubspot/main.py index dc073ca21ed6..8aa42945418c 100644 --- a/airbyte-integrations/connectors/source-hubspot/main.py +++ b/airbyte-integrations/connectors/source-hubspot/main.py @@ -4,5 +4,6 @@ from source_hubspot.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-hubspot/metadata.yaml b/airbyte-integrations/connectors/source-hubspot/metadata.yaml index e82812a6ce59..b99caaee559a 100644 --- a/airbyte-integrations/connectors/source-hubspot/metadata.yaml +++ b/airbyte-integrations/connectors/source-hubspot/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - api.hubapi.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 36c891d9-4bd9-43ac-bad2-10e12756272c - dockerImageTag: 4.2.25 + dockerImageTag: 4.4.6 dockerRepository: airbyte/source-hubspot documentationUrl: https://docs.airbyte.com/integrations/sources/hubspot erdUrl: https://dbdocs.io/airbyteio/source-hubspot?view=relationships @@ -30,6 +30,8 @@ data: enabled: true releaseStage: generally_available releases: + rolloutConfiguration: + enableProgressiveRollout: false breakingChanges: 4.0.0: message: >- diff --git a/airbyte-integrations/connectors/source-hubspot/poetry.lock b/airbyte-integrations/connectors/source-hubspot/poetry.lock index 848eb250eb78..261bc8722b11 100644 --- a/airbyte-integrations/connectors/source-hubspot/poetry.lock +++ b/airbyte-integrations/connectors/source-hubspot/poetry.lock @@ -67,24 +67,24 @@ files = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -99,19 +99,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -177,13 +177,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -267,116 +267,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -446,20 +433,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -524,13 +511,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -545,13 +532,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -559,7 +546,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -609,13 +595,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -705,22 +691,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -809,69 +798,86 @@ test = ["pytest", "pytest-cov"] [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -974,19 +980,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -994,100 +1000,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -1095,13 +1112,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1389,33 +1406,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1482,13 +1499,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1513,81 +1530,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-hubspot/pyproject.toml b/airbyte-integrations/connectors/source-hubspot/pyproject.toml index 76073d22a5ce..b67e7c684d70 100644 --- a/airbyte-integrations/connectors/source-hubspot/pyproject.toml +++ b/airbyte-integrations/connectors/source-hubspot/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "4.2.25" +version = "4.4.6" name = "source-hubspot" description = "Source implementation for HubSpot." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-hubspot/sample_files/sample_state.json b/airbyte-integrations/connectors/source-hubspot/sample_files/sample_state.json index d9a123b99c7a..f8a589373903 100644 --- a/airbyte-integrations/connectors/source-hubspot/sample_files/sample_state.json +++ b/airbyte-integrations/connectors/source-hubspot/sample_files/sample_state.json @@ -48,6 +48,13 @@ "stream_descriptor": { "name": "goals" } } }, + { + "type": "STREAM", + "stream": { + "stream_state": { "updatedAt": "2050-05-01" }, + "stream_descriptor": { "name": "leads" } + } + }, { "type": "STREAM", "stream": { diff --git a/airbyte-integrations/connectors/source-hubspot/source_hubspot/components.py b/airbyte-integrations/connectors/source-hubspot/source_hubspot/components.py new file mode 100644 index 000000000000..7501e1d898b8 --- /dev/null +++ b/airbyte-integrations/connectors/source-hubspot/source_hubspot/components.py @@ -0,0 +1,51 @@ +# +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. +# + +from typing import Any, Dict, Optional + +from airbyte_cdk.sources.declarative.transformations import RecordTransformation +from airbyte_cdk.sources.types import Config, StreamSlice, StreamState + + +class NewtoLegacyFieldTransformation(RecordTransformation): + """ + Implements a custom transformation which adds the legacy field equivalent of v2 fields for streams which contain Deals and Contacts entities. + + This custom implmentation was developed in lieu of the AddFields component due to the dynamic-nature of the record properties for the HubSpot source. Each + + For example: + hs_v2_date_exited_{stage_id} -> hs_date_exited_{stage_id} where {stage_id} is a user-generated value + """ + + def __init__(self, field_mapping: Dict[str, str]) -> None: + self._field_mapping = field_mapping + + def transform( + self, + record_or_schema: Dict[str, Any], + config: Optional[Config] = None, + stream_state: Optional[StreamState] = None, + stream_slice: Optional[StreamSlice] = None, + ) -> None: + """ + Transform a record in place by adding fields directly to the record by manipulating the injected fields into a legacy field to avoid breaking syncs. + + :param record_or_schema: The input record or schema to be transformed. + """ + is_record = record_or_schema.get("properties") is not None + + for field, value in list(record_or_schema.get("properties", record_or_schema).items()): + for legacy_field, new_field in self._field_mapping.items(): + if new_field in field: + transformed_field = field.replace(new_field, legacy_field) + + if legacy_field == "hs_lifecyclestage_" and not transformed_field.endswith("_date"): + transformed_field += "_date" + + if is_record: + if record_or_schema["properties"].get(transformed_field) is None: + record_or_schema["properties"][transformed_field] = value + else: + if record_or_schema.get(transformed_field) is None: + record_or_schema[transformed_field] = value diff --git a/airbyte-integrations/connectors/source-hubspot/source_hubspot/errors.py b/airbyte-integrations/connectors/source-hubspot/source_hubspot/errors.py index e73313f80e3f..925f2c84f06f 100644 --- a/airbyte-integrations/connectors/source-hubspot/source_hubspot/errors.py +++ b/airbyte-integrations/connectors/source-hubspot/source_hubspot/errors.py @@ -6,9 +6,10 @@ from typing import Any import requests +from requests import HTTPError + from airbyte_cdk.models import FailureType from airbyte_cdk.utils import AirbyteTracedException -from requests import HTTPError class HubspotError(AirbyteTracedException): diff --git a/airbyte-integrations/connectors/source-hubspot/source_hubspot/schemas/leads.json b/airbyte-integrations/connectors/source-hubspot/source_hubspot/schemas/leads.json new file mode 100644 index 000000000000..27aae0248cec --- /dev/null +++ b/airbyte-integrations/connectors/source-hubspot/source_hubspot/schemas/leads.json @@ -0,0 +1,32 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": ["null", "object"], + "properties": { + "id": { + "description": "Unique identifier for the lead", + "type": ["null", "string"] + }, + "createdAt": { + "description": "Date and time when the lead was created", + "type": ["null", "string"], + "format": "date-time" + }, + "updatedAt": { + "description": "Date and time when the lead was last updated", + "type": ["null", "string"], + "format": "date-time" + }, + "archived": { + "description": "Indicates whether the lead is archived or active", + "type": ["null", "boolean"] + }, + "contacts": { + "description": "List of contacts associated with the lead", + "type": ["null", "array"], + "items": { + "description": "Details of individual contacts", + "type": "string" + } + } + } +} diff --git a/airbyte-integrations/connectors/source-hubspot/source_hubspot/source.py b/airbyte-integrations/connectors/source-hubspot/source_hubspot/source.py index 2de34fd18639..195ac0335d21 100644 --- a/airbyte-integrations/connectors/source-hubspot/source_hubspot/source.py +++ b/airbyte-integrations/connectors/source-hubspot/source_hubspot/source.py @@ -8,12 +8,13 @@ from itertools import chain from typing import Any, Generator, List, Mapping, Optional, Tuple, Union +from requests import HTTPError + from airbyte_cdk.models import FailureType from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http import HttpClient from airbyte_cdk.sources.streams.http.error_handlers import ErrorResolution, HttpStatusErrorHandler, ResponseAction -from requests import HTTPError from source_hubspot.errors import HubspotInvalidAuth from source_hubspot.streams import ( API, @@ -52,6 +53,7 @@ FormSubmissions, Goals, GoalsWebAnalytics, + Leads, LineItems, LineItemsWebAnalytics, MarketingEmails, @@ -67,6 +69,7 @@ Workflows, ) + """ https://github.com/airbytehq/oncall/issues/3800 we use start date 2006-01-01 as date of creation of Hubspot to retrieve all data if start date was not provided @@ -157,6 +160,7 @@ def streams(self, config: Mapping[str, Any]) -> List[Stream]: Forms(**common_params), FormSubmissions(**common_params), Goals(**common_params), + Leads(**common_params), LineItems(**common_params), MarketingEmails(**common_params), Owners(**common_params), diff --git a/airbyte-integrations/connectors/source-hubspot/source_hubspot/streams.py b/airbyte-integrations/connectors/source-hubspot/source_hubspot/streams.py index 73b519359108..4daedbd18fcb 100644 --- a/airbyte-integrations/connectors/source-hubspot/source_hubspot/streams.py +++ b/airbyte-integrations/connectors/source-hubspot/source_hubspot/streams.py @@ -15,9 +15,12 @@ import backoff import pendulum as pendulum import requests +from requests import HTTPError, codes + from airbyte_cdk.entrypoint import logger from airbyte_cdk.models import FailureType, SyncMode from airbyte_cdk.sources import Source +from airbyte_cdk.sources.declarative.transformations import RecordTransformation from airbyte_cdk.sources.streams import CheckpointMixin, Stream from airbyte_cdk.sources.streams.availability_strategy import AvailabilityStrategy from airbyte_cdk.sources.streams.core import StreamData @@ -28,7 +31,7 @@ from airbyte_cdk.sources.utils.schema_helpers import ResourceSchemaLoader from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer from airbyte_cdk.utils import AirbyteTracedException -from requests import HTTPError, codes +from source_hubspot.components import NewtoLegacyFieldTransformation from source_hubspot.constants import OAUTH_CREDENTIALS, PRIVATE_APP_CREDENTIALS from source_hubspot.errors import HubspotAccessDenied, HubspotInvalidAuth, HubspotRateLimited, HubspotTimeout, InvalidStartDateConfigError from source_hubspot.helpers import ( @@ -42,6 +45,7 @@ StoreAsIs, ) + # we got this when provided API Token has incorrect format CLOUDFLARE_ORIGIN_DNS_ERROR = 530 @@ -73,6 +77,18 @@ CUSTOM_FIELD_VALUE_TO_TYPE = {v: k for k, v in CUSTOM_FIELD_TYPE_TO_VALUE.items()} +CONTACTS_NEW_TO_LEGACY_FIELDS_MAPPING = { + "hs_lifecyclestage_": "hs_v2_date_entered_", + "hs_date_exited_": "hs_v2_date_exited_", + "hs_time_in_": "hs_v2_latest_time_in_", +} + +DEALS_NEW_TO_LEGACY_FIELDS_MAPPING = { + "hs_date_entered_": "hs_v2_date_entered_", + "hs_date_exited_": "hs_v2_date_exited_", + "hs_time_in_": "hs_v2_latest_time_in_", +} + def retry_token_expired_handler(**kwargs): """Retry helper when token expired""" @@ -336,6 +352,7 @@ class Stream(HttpStream, ABC): properties_scopes: Set = None unnest_fields: Optional[List[str]] = None checkpoint_by_page = False + _transformations: Optional[List[RecordTransformation]] = None @cached_property def record_unnester(self): @@ -688,6 +705,9 @@ def _transform(self, records: Iterable) -> Iterable: record = self._cast_record_fields_if_needed(record) if self.created_at_field and self.updated_at_field and record.get(self.updated_at_field) is None: record[self.updated_at_field] = record[self.created_at_field] + if self._transformations: + for transformation in self._transformations: + transformation.transform(record_or_schema=record) yield record @staticmethod @@ -794,7 +814,7 @@ def _get_field_props(field_type: str) -> Mapping[str, List[str]]: if not converted_type: converted_type = "string" - logger.warn(f"Unsupported type {field_type} found") + logger.warning(f"Unsupported type {field_type} found") field_props = { "type": ["null", converted_type or field_type], @@ -822,6 +842,10 @@ def properties(self) -> Mapping[str, Any]: for row in data: props[row["name"]] = self._get_field_props(row["type"]) + if self._transformations: + for transformation in self._transformations: + transformation.transform(record_or_schema=props) + return props def properties_scope_is_granted(self): @@ -1493,14 +1517,12 @@ def cursor_field_datetime_format(self) -> str: class ContactsFormSubmissions(ContactsAllBase, ResumableFullRefreshMixin, ABC): - records_field = "form-submissions" filter_field = "formSubmissionMode" filter_value = "all" class ContactsMergedAudit(ContactsAllBase, ResumableFullRefreshMixin, ABC): - records_field = "merge-audits" unnest_fields = ["merged_from_email", "merged_to_email"] @@ -1513,6 +1535,7 @@ class Deals(CRMSearchStream): associations = ["contacts", "companies", "line_items"] primary_key = "id" scopes = {"contacts", "crm.objects.deals.read"} + _transformations = [NewtoLegacyFieldTransformation(field_mapping=DEALS_NEW_TO_LEGACY_FIELDS_MAPPING)] class DealsArchived(ClientSideIncrementalStream): @@ -1526,6 +1549,7 @@ class DealsArchived(ClientSideIncrementalStream): cursor_field_datetime_format = "YYYY-MM-DDTHH:mm:ss.SSSSSSZ" primary_key = "id" scopes = {"contacts", "crm.objects.deals.read"} + _transformations = [NewtoLegacyFieldTransformation(field_mapping=DEALS_NEW_TO_LEGACY_FIELDS_MAPPING)] def request_params( self, @@ -2113,7 +2137,6 @@ def _transform(self, records: Iterable) -> Iterable: class CompaniesPropertyHistory(PropertyHistoryV3): - scopes = {"crm.objects.companies.read"} properties_scopes = {"crm.schemas.companies.read"} entity = "companies" @@ -2198,6 +2221,7 @@ class Contacts(CRMSearchStream): associations = ["contacts", "companies"] primary_key = "id" scopes = {"crm.objects.contacts.read"} + _transformations = [NewtoLegacyFieldTransformation(field_mapping=CONTACTS_NEW_TO_LEGACY_FIELDS_MAPPING)] class EngagementsCalls(CRMSearchStream): @@ -2255,10 +2279,18 @@ class Goals(CRMObjectIncrementalStream): scopes = {"crm.objects.goals.read"} +class Leads(CRMSearchStream): + entity = "leads" + last_modified_field = "hs_lastmodifieddate" + associations = ["contacts", "companies"] + primary_key = "id" + scopes = {"crm.objects.contacts.read", "crm.objects.companies.read", "crm.objects.leads.read"} + + class LineItems(CRMObjectIncrementalStream): entity = "line_item" primary_key = "id" - scopes = {"e-commerce"} + scopes = {"e-commerce", "crm.objects.line_items.read"} class Products(CRMObjectIncrementalStream): @@ -2386,7 +2418,6 @@ def stream_slices( ) -> Iterable[Optional[Mapping[str, Any]]]: now = pendulum.now(tz="UTC") for parent_slice in super().stream_slices(sync_mode, cursor_field, stream_state): - object_id = parent_slice["parent"][self.object_id_field] # We require this workaround to shorten the duration of the acceptance test run. diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/conftest.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/conftest.py index c64d689bde9e..8d10c01fde86 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/conftest.py @@ -6,6 +6,7 @@ from source_hubspot.source import SourceHubspot from source_hubspot.streams import API + NUMBER_OF_PROPERTIES = 2000 @@ -82,6 +83,16 @@ def fake_properties_list(): return [f"property_number_{i}" for i in range(NUMBER_OF_PROPERTIES)] +@pytest.fixture(name="migrated_properties_list") +def migrated_properties_list(): + return [ + "hs_v2_date_entered_prospect", + "hs_v2_date_exited_prospect", + "hs_v2_cumulative_time_in_prsopect", + "hs_v2_some_other_property_in_prospect", + ] + + @pytest.fixture(name="api") def api(some_credentials): return API(some_credentials) diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/config_builder.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/config_builder.py index 048142759ca2..1927b02a1705 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/config_builder.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/config_builder.py @@ -5,9 +5,7 @@ class ConfigBuilder: def __init__(self): - self._config = { - "enable_experimental_streams": True - } + self._config = {"enable_experimental_streams": True} def with_start_date(self, start_date: str): self._config["start_date"] = start_date diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/request_builders/api.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/request_builders/api.py index 17ba71bebf3c..e9695115f5a3 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/request_builders/api.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/request_builders/api.py @@ -26,8 +26,7 @@ def with_refresh_token(self, refresh_token: str): def build(self) -> HttpRequest: client_id, client_secret, refresh_token = self._params["client_id"], self._params["client_secret"], self._params["refresh_token"] return HttpRequest( - url=self.URL, - body=f"grant_type=refresh_token&client_id={client_id}&client_secret={client_secret}&refresh_token={refresh_token}" + url=self.URL, body=f"grant_type=refresh_token&client_id={client_id}&client_secret={client_secret}&refresh_token={refresh_token}" ) diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/request_builders/streams.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/request_builders/streams.py index d0258a26500a..614c51e8ece6 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/request_builders/streams.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/request_builders/streams.py @@ -29,12 +29,7 @@ def with_query(self, qp): return self def build(self) -> HttpRequest: - return HttpRequest( - url=self.URL, - query_params=self._query_params, - headers=self.headers, - body=self._request_body - ) + return HttpRequest(url=self.URL, query_params=self._query_params, headers=self.headers, body=self._request_body) class CRMStreamRequestBuilder(AbstractRequestBuilder): @@ -78,14 +73,7 @@ def _archived(self): @property def _query_params(self): - return [ - self._archived, - self._associations, - self._limit, - self._after, - self._dt_range, - self._properties - ] + return [self._archived, self._associations, self._limit, self._after, self._dt_range, self._properties] def build(self): q = "&".join(filter(None, self._query_params)) @@ -96,14 +84,7 @@ def build(self): class IncrementalCRMStreamRequestBuilder(CRMStreamRequestBuilder): @property def _query_params(self): - return [ - self._limit, - self._after, - self._dt_range, - self._archived, - self._associations, - self._properties - ] + return [self._limit, self._after, self._dt_range, self._archived, self._associations, self._properties] class OwnersArchivedStreamRequestBuilder(AbstractRequestBuilder): @@ -122,11 +103,14 @@ def _archived(self): @property def _query_params(self): - return filter(None, [ - self._limit, - self._after, - self._archived, - ]) + return filter( + None, + [ + self._limit, + self._after, + self._archived, + ], + ) def with_page_token(self, next_page_token: Dict): self._after = "&".join([f"{str(key)}={str(val)}" for key, val in next_page_token.items()]) diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/response_builder/contact_response_builder.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/response_builder/contact_response_builder.py index 87ba98af2b5a..b5c2cc79e61b 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/response_builder/contact_response_builder.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/response_builder/contact_response_builder.py @@ -7,13 +7,13 @@ from airbyte_cdk.test.mock_http import HttpResponse from airbyte_cdk.test.mock_http.response_builder import find_template + _CONTACTS_FIELD = "contacts" _FORM_SUBMISSIONS_FIELD = "form-submissions" _LIST_MEMBERSHIPS_FIELD = "list-memberships" _MERGE_AUDITS_FIELD = "merge-audits" - def _get_template() -> Dict[str, Any]: return find_template("all_contacts", __file__) diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/response_builder/helpers.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/response_builder/helpers.py index 595a02232d43..f5bb912822f7 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/response_builder/helpers.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/response_builder/helpers.py @@ -12,7 +12,7 @@ def __init__( self, template: List[Any], records_path: Optional[Union[FieldPath, NestedPath]] = None, - pagination_strategy: Optional[PaginationStrategy] = None + pagination_strategy: Optional[PaginationStrategy] = None, ): self._response = template self._records: List[RecordBuilder] = [] diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/response_builder/pagination.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/response_builder/pagination.py index ded25153204f..7f594d984fdf 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/response_builder/pagination.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/response_builder/pagination.py @@ -9,13 +9,4 @@ class HubspotPaginationStrategy(PaginationStrategy): NEXT_PAGE_TOKEN = {"after": "256"} def update(self, response: Dict[str, Any]) -> None: - response["paging"] = { - "next": { - "link": "link_to_the_next_page", - **self.NEXT_PAGE_TOKEN - }, - "prev": { - "before": None, - "link": None - } - } + response["paging"] = {"next": {"link": "link_to_the_next_page", **self.NEXT_PAGE_TOKEN}, "prev": {"before": None, "link": None}} diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/response_builder/streams.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/response_builder/streams.py index f5d4795c3775..6b02d952e14c 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/response_builder/streams.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/response_builder/streams.py @@ -13,7 +13,7 @@ class HubspotStreamResponseBuilder(HttpResponseBuilder): @property def pagination_strategy(self): return self._pagination_strategy - + @classmethod def for_stream(cls, stream: str): return cls(find_template(stream, __file__), FieldPath("results"), HubspotPaginationStrategy()) diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_contacts_form_submissions.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_contacts_form_submissions.py index 7bcddfe5e179..fdf05847617c 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_contacts_form_submissions.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_contacts_form_submissions.py @@ -3,6 +3,7 @@ from unittest import TestCase import freezegun + from airbyte_cdk.test.mock_http import HttpMocker from airbyte_protocol.models import AirbyteStateBlob, AirbyteStateMessage, AirbyteStateType, AirbyteStreamState, StreamDescriptor, SyncMode @@ -10,6 +11,7 @@ from .request_builders.streams import ContactsStreamRequestBuilder from .response_builder.contact_response_builder import AllContactsResponseBuilder, ContactBuilder, ContactsFormSubmissionsBuilder + _START_TIME_BEFORE_ANY_RECORD = "1970-01-01T00:00:00Z" _VID_OFFSET = 5331889818 @@ -32,43 +34,60 @@ def tearDown(self) -> None: def test_read_multiple_contact_pages(self) -> None: first_page_request = ContactsStreamRequestBuilder().with_filter("formSubmissionMode", "all").build() - second_page_request = ContactsStreamRequestBuilder().with_filter("formSubmissionMode", "all").with_vid_offset(str(_VID_OFFSET)).build() + second_page_request = ( + ContactsStreamRequestBuilder().with_filter("formSubmissionMode", "all").with_vid_offset(str(_VID_OFFSET)).build() + ) self.mock_response( self._http_mocker, first_page_request, - AllContactsResponseBuilder().with_pagination(vid_offset=_VID_OFFSET).with_contacts([ - ContactBuilder().with_form_submissions([ - ContactsFormSubmissionsBuilder(), - ]), - ContactBuilder().with_form_submissions([ - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - ]), - ]).build(), + AllContactsResponseBuilder() + .with_pagination(vid_offset=_VID_OFFSET) + .with_contacts( + [ + ContactBuilder().with_form_submissions( + [ + ContactsFormSubmissionsBuilder(), + ] + ), + ContactBuilder().with_form_submissions( + [ + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ] + ), + ] + ) + .build(), ) self.mock_response( self._http_mocker, second_page_request, - AllContactsResponseBuilder().with_contacts([ - ContactBuilder().with_form_submissions([ - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - ]), - ContactBuilder().with_form_submissions([ - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - ]), - ]).build(), + AllContactsResponseBuilder() + .with_contacts( + [ + ContactBuilder().with_form_submissions( + [ + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ] + ), + ContactBuilder().with_form_submissions( + [ + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ] + ), + ] + ) + .build(), ) output = self.read_from_stream( - cfg=self.oauth_config(start_date=_START_TIME_BEFORE_ANY_RECORD), - stream=self.STREAM_NAME, - sync_mode=SyncMode.full_refresh + cfg=self.oauth_config(start_date=_START_TIME_BEFORE_ANY_RECORD), stream=self.STREAM_NAME, sync_mode=SyncMode.full_refresh ) self._http_mocker.assert_number_of_calls(first_page_request, 2) @@ -87,56 +106,73 @@ def test_read_from_incoming_state(self) -> None: AirbyteStateMessage( type=AirbyteStateType.STREAM, stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name=self.STREAM_NAME), - stream_state=AirbyteStateBlob(**{"vidOffset": "5331889818"}) - ) + stream_descriptor=StreamDescriptor(name=self.STREAM_NAME), stream_state=AirbyteStateBlob(**{"vidOffset": "5331889818"}) + ), ) ] # Even though we only care about the request with a vidOffset parameter, we mock this in order to pass the availability check first_page_request = ContactsStreamRequestBuilder().with_filter("formSubmissionMode", "all").build() - second_page_request = ContactsStreamRequestBuilder().with_filter("formSubmissionMode", "all").with_vid_offset(str(_VID_OFFSET)).build() + second_page_request = ( + ContactsStreamRequestBuilder().with_filter("formSubmissionMode", "all").with_vid_offset(str(_VID_OFFSET)).build() + ) self.mock_response( self._http_mocker, first_page_request, - AllContactsResponseBuilder().with_pagination(vid_offset=_VID_OFFSET).with_contacts([ - ContactBuilder().with_form_submissions([ - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - - ]), - ContactBuilder().with_form_submissions([ - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - ]), - ]).build(), + AllContactsResponseBuilder() + .with_pagination(vid_offset=_VID_OFFSET) + .with_contacts( + [ + ContactBuilder().with_form_submissions( + [ + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ] + ), + ContactBuilder().with_form_submissions( + [ + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ] + ), + ] + ) + .build(), ) self.mock_response( self._http_mocker, second_page_request, - AllContactsResponseBuilder().with_contacts([ - ContactBuilder().with_form_submissions([ - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - ]), - ContactBuilder().with_form_submissions([ - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - ContactsFormSubmissionsBuilder(), - ]), - ]).build(), + AllContactsResponseBuilder() + .with_contacts( + [ + ContactBuilder().with_form_submissions( + [ + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ] + ), + ContactBuilder().with_form_submissions( + [ + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ContactsFormSubmissionsBuilder(), + ] + ), + ] + ) + .build(), ) output = self.read_from_stream( cfg=self.oauth_config(start_date=_START_TIME_BEFORE_ANY_RECORD), stream=self.STREAM_NAME, sync_mode=SyncMode.full_refresh, - state=state + state=state, ) # We call the first page during check availability. And the sync actually starts with a request to the second page diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_contacts_list_memberships.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_contacts_list_memberships.py index 8fb6e598a395..3c21d185a650 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_contacts_list_memberships.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_contacts_list_memberships.py @@ -4,6 +4,7 @@ from unittest import TestCase import freezegun + from airbyte_cdk.test.mock_http import HttpMocker from airbyte_cdk.test.state_builder import StateBuilder from airbyte_protocol.models import SyncMode @@ -12,6 +13,7 @@ from .request_builders.streams import ContactsStreamRequestBuilder from .response_builder.contact_response_builder import AllContactsResponseBuilder, ContactBuilder, ContactsListMembershipBuilder + _START_TIME_BEFORE_ANY_RECORD = "1970-01-01T00:00:00Z" _NOW = datetime.now(timezone.utc) @@ -37,25 +39,40 @@ def test_given_pagination_when_read_then_extract_records_from_both_pages(self) - self.mock_response( self._http_mocker, ContactsStreamRequestBuilder().with_filter("showListMemberships", True).build(), - AllContactsResponseBuilder().with_pagination(vid_offset=_VID_OFFSET).with_contacts([ - ContactBuilder().with_list_memberships([ - ContactsListMembershipBuilder(), - ContactsListMembershipBuilder(), - ]), - ]).build(), + AllContactsResponseBuilder() + .with_pagination(vid_offset=_VID_OFFSET) + .with_contacts( + [ + ContactBuilder().with_list_memberships( + [ + ContactsListMembershipBuilder(), + ContactsListMembershipBuilder(), + ] + ), + ] + ) + .build(), ) self.mock_response( self._http_mocker, ContactsStreamRequestBuilder().with_filter("showListMemberships", True).with_vid_offset(str(_VID_OFFSET)).build(), - AllContactsResponseBuilder().with_contacts([ - ContactBuilder().with_list_memberships([ - ContactsListMembershipBuilder(), - ]), - ContactBuilder().with_list_memberships([ - ContactsListMembershipBuilder(), - ContactsListMembershipBuilder(), - ]), - ]).build(), + AllContactsResponseBuilder() + .with_contacts( + [ + ContactBuilder().with_list_memberships( + [ + ContactsListMembershipBuilder(), + ] + ), + ContactBuilder().with_list_memberships( + [ + ContactsListMembershipBuilder(), + ContactsListMembershipBuilder(), + ] + ), + ] + ) + .build(), ) output = self.read_from_stream(self.oauth_config(start_date=_START_TIME_BEFORE_ANY_RECORD), self.STREAM_NAME, SyncMode.full_refresh) @@ -67,14 +84,22 @@ def test_given_timestamp_before_start_date_when_read_then_filter_out(self) -> No self.mock_response( self._http_mocker, ContactsStreamRequestBuilder().with_filter("showListMemberships", True).build(), - AllContactsResponseBuilder().with_contacts([ - ContactBuilder().with_list_memberships([ - ContactsListMembershipBuilder().with_timestamp(start_date + timedelta(days=10)), - ContactsListMembershipBuilder().with_timestamp(start_date - timedelta(days=10)), - ]), - ]).build(), + AllContactsResponseBuilder() + .with_contacts( + [ + ContactBuilder().with_list_memberships( + [ + ContactsListMembershipBuilder().with_timestamp(start_date + timedelta(days=10)), + ContactsListMembershipBuilder().with_timestamp(start_date - timedelta(days=10)), + ] + ), + ] + ) + .build(), + ) + output = self.read_from_stream( + self.oauth_config(start_date=start_date.isoformat().replace("+00:00", "Z")), self.STREAM_NAME, SyncMode.full_refresh ) - output = self.read_from_stream(self.oauth_config(start_date=start_date.isoformat().replace("+00:00", "Z")), self.STREAM_NAME, SyncMode.full_refresh) assert len(output.records) == 1 @@ -83,12 +108,18 @@ def test_given_state_when_read_then_filter_out(self) -> None: self.mock_response( self._http_mocker, ContactsStreamRequestBuilder().with_filter("showListMemberships", True).build(), - AllContactsResponseBuilder().with_contacts([ - ContactBuilder().with_list_memberships([ - ContactsListMembershipBuilder().with_timestamp(state_value + timedelta(days=10)), - ContactsListMembershipBuilder().with_timestamp(state_value - timedelta(days=10)), - ]), - ]).build(), + AllContactsResponseBuilder() + .with_contacts( + [ + ContactBuilder().with_list_memberships( + [ + ContactsListMembershipBuilder().with_timestamp(state_value + timedelta(days=10)), + ContactsListMembershipBuilder().with_timestamp(state_value - timedelta(days=10)), + ] + ), + ] + ) + .build(), ) output = self.read_from_stream( self.oauth_config(start_date=_START_TIME_BEFORE_ANY_RECORD), diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_contacts_merged_audit.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_contacts_merged_audit.py index 18c67317aebf..8b76e13cc6c4 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_contacts_merged_audit.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_contacts_merged_audit.py @@ -3,6 +3,7 @@ from unittest import TestCase import freezegun + from airbyte_cdk.test.mock_http import HttpMocker from airbyte_protocol.models import AirbyteStateBlob, AirbyteStateMessage, AirbyteStateType, AirbyteStreamState, StreamDescriptor, SyncMode @@ -10,6 +11,7 @@ from .request_builders.streams import ContactsStreamRequestBuilder from .response_builder.contact_response_builder import AllContactsResponseBuilder, ContactBuilder, ContactsMergeAuditsBuilder + _START_TIME_BEFORE_ANY_RECORD = "1970-01-01T00:00:00Z" _VID_OFFSET = 5331889818 @@ -36,32 +38,49 @@ def test_read_multiple_contact_pages(self) -> None: self.mock_response( self._http_mocker, first_page_request, - AllContactsResponseBuilder().with_pagination(vid_offset=_VID_OFFSET).with_contacts([ - ContactBuilder().with_merge_audits([ - ContactsMergeAuditsBuilder(), - ContactsMergeAuditsBuilder(), - ContactsMergeAuditsBuilder(), - ContactsMergeAuditsBuilder(), - ]), - ContactBuilder().with_merge_audits([ - ContactsMergeAuditsBuilder(), - ContactsMergeAuditsBuilder(), - ContactsMergeAuditsBuilder(), - ]), - ]).build(), + AllContactsResponseBuilder() + .with_pagination(vid_offset=_VID_OFFSET) + .with_contacts( + [ + ContactBuilder().with_merge_audits( + [ + ContactsMergeAuditsBuilder(), + ContactsMergeAuditsBuilder(), + ContactsMergeAuditsBuilder(), + ContactsMergeAuditsBuilder(), + ] + ), + ContactBuilder().with_merge_audits( + [ + ContactsMergeAuditsBuilder(), + ContactsMergeAuditsBuilder(), + ContactsMergeAuditsBuilder(), + ] + ), + ] + ) + .build(), ) self.mock_response( self._http_mocker, second_page_request, - AllContactsResponseBuilder().with_contacts([ - ContactBuilder().with_merge_audits([ - ContactsMergeAuditsBuilder(), - ]), - ContactBuilder().with_merge_audits([ - ContactsMergeAuditsBuilder(), - ContactsMergeAuditsBuilder(), - ]), - ]).build(), + AllContactsResponseBuilder() + .with_contacts( + [ + ContactBuilder().with_merge_audits( + [ + ContactsMergeAuditsBuilder(), + ] + ), + ContactBuilder().with_merge_audits( + [ + ContactsMergeAuditsBuilder(), + ContactsMergeAuditsBuilder(), + ] + ), + ] + ) + .build(), ) output = self.read_from_stream(self.oauth_config(start_date=_START_TIME_BEFORE_ANY_RECORD), self.STREAM_NAME, SyncMode.full_refresh) @@ -82,9 +101,8 @@ def test_read_from_incoming_state(self) -> None: AirbyteStateMessage( type=AirbyteStateType.STREAM, stream=AirbyteStreamState( - stream_descriptor=StreamDescriptor(name=self.STREAM_NAME), - stream_state=AirbyteStateBlob(**{"vidOffset": "5331889818"}) - ) + stream_descriptor=StreamDescriptor(name=self.STREAM_NAME), stream_state=AirbyteStateBlob(**{"vidOffset": "5331889818"}) + ), ) ] @@ -94,39 +112,56 @@ def test_read_from_incoming_state(self) -> None: self.mock_response( self._http_mocker, first_page_request, - AllContactsResponseBuilder().with_pagination(vid_offset=_VID_OFFSET).with_contacts([ - ContactBuilder().with_merge_audits([ - ContactsMergeAuditsBuilder(), - ContactsMergeAuditsBuilder(), - ContactsMergeAuditsBuilder(), - ContactsMergeAuditsBuilder(), - ]), - ContactBuilder().with_merge_audits([ - ContactsMergeAuditsBuilder(), - ContactsMergeAuditsBuilder(), - ContactsMergeAuditsBuilder(), - ]), - ]).build(), + AllContactsResponseBuilder() + .with_pagination(vid_offset=_VID_OFFSET) + .with_contacts( + [ + ContactBuilder().with_merge_audits( + [ + ContactsMergeAuditsBuilder(), + ContactsMergeAuditsBuilder(), + ContactsMergeAuditsBuilder(), + ContactsMergeAuditsBuilder(), + ] + ), + ContactBuilder().with_merge_audits( + [ + ContactsMergeAuditsBuilder(), + ContactsMergeAuditsBuilder(), + ContactsMergeAuditsBuilder(), + ] + ), + ] + ) + .build(), ) self.mock_response( self._http_mocker, second_page_request, - AllContactsResponseBuilder().with_contacts([ - ContactBuilder().with_merge_audits([ - ContactsMergeAuditsBuilder(), - ]), - ContactBuilder().with_merge_audits([ - ContactsMergeAuditsBuilder(), - ContactsMergeAuditsBuilder(), - ]), - ]).build(), + AllContactsResponseBuilder() + .with_contacts( + [ + ContactBuilder().with_merge_audits( + [ + ContactsMergeAuditsBuilder(), + ] + ), + ContactBuilder().with_merge_audits( + [ + ContactsMergeAuditsBuilder(), + ContactsMergeAuditsBuilder(), + ] + ), + ] + ) + .build(), ) output = self.read_from_stream( cfg=self.oauth_config(start_date=_START_TIME_BEFORE_ANY_RECORD), stream=self.STREAM_NAME, sync_mode=SyncMode.full_refresh, - state=state + state=state, ) # We call the first page during check availability. And the sync actually starts with a request to the second page diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_engagements_calls.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_engagements_calls.py index d37005531ecf..936f68a4fa2a 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_engagements_calls.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_engagements_calls.py @@ -5,6 +5,7 @@ import freezegun import mock + from airbyte_cdk.test.mock_http import HttpMocker, HttpResponse from airbyte_cdk.test.mock_http.response_builder import FieldPath from airbyte_protocol.models import SyncMode @@ -27,22 +28,21 @@ def response_builder(self): return HubspotStreamResponseBuilder.for_stream(self.STREAM_NAME) def request(self, page_token: Optional[Dict[str, str]] = None): - request_builder = CRMStreamRequestBuilder().for_entity( - self.OBJECT_TYPE - ).with_associations( - self.ASSOCIATIONS - ).with_properties( - list(self.PROPERTIES.keys()) + request_builder = ( + CRMStreamRequestBuilder() + .for_entity(self.OBJECT_TYPE) + .with_associations(self.ASSOCIATIONS) + .with_properties(list(self.PROPERTIES.keys())) ) if page_token: request_builder = request_builder.with_page_token(page_token) return request_builder.build() def response(self, with_pagination: bool = False): - record = self.record_builder(self.STREAM_NAME, FieldPath(self.CURSOR_FIELD)).with_field( - FieldPath(self.CURSOR_FIELD), self.dt_str(self.updated_at()) - ).with_field( - FieldPath("id"), self.OBJECT_ID + record = ( + self.record_builder(self.STREAM_NAME, FieldPath(self.CURSOR_FIELD)) + .with_field(FieldPath(self.CURSOR_FIELD), self.dt_str(self.updated_at())) + .with_field(FieldPath("id"), self.OBJECT_ID) ) response = self.response_builder.with_record(record) if with_pagination: @@ -82,11 +82,7 @@ def test_given_one_page_when_read_stream_private_token_then_return_records(self, def test_given_two_pages_when_read_then_return_records(self, http_mocker: HttpMocker): self._set_up_requests(http_mocker) self.mock_response(http_mocker, self.request(), self.response(with_pagination=True)) - self.mock_response( - http_mocker, - self.request(page_token=self.response_builder.pagination_strategy.NEXT_PAGE_TOKEN), - self.response() - ) + self.mock_response(http_mocker, self.request(page_token=self.response_builder.pagination_strategy.NEXT_PAGE_TOKEN), self.response()) output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), self.STREAM_NAME, SyncMode.full_refresh) assert len(output.records) == 2 @@ -103,14 +99,7 @@ def test_given_error_response_when_read_analytics_then_get_trace_message(self, h @HttpMocker() def test_given_500_then_200_when_read_then_return_records(self, http_mocker: HttpMocker): self._set_up_requests(http_mocker) - self.mock_response( - http_mocker, - self.request(), - [ - HttpResponse(status_code=500, body="{}"), - self.response() - ] - ) + self.mock_response(http_mocker, self.request(), [HttpResponse(status_code=500, body="{}"), self.response()]) with mock.patch("time.sleep"): output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), self.STREAM_NAME, SyncMode.full_refresh) assert len(output.records) == 1 @@ -147,8 +136,5 @@ def test_given_one_page_when_read_then_get_records_with_flattened_properties(sel def test_given_incremental_sync_when_read_then_state_message_produced_and_state_match_latest_record(self, http_mocker: HttpMocker): self._set_up_requests(http_mocker) self.mock_response(http_mocker, self.request(), self.response()) - output = self.read_from_stream( - self.private_token_config(self.ACCESS_TOKEN), self.STREAM_NAME, SyncMode.incremental - ) + output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), self.STREAM_NAME, SyncMode.incremental) assert len(output.state_messages) == 1 - diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_leads.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_leads.py new file mode 100644 index 000000000000..5f46b8982ae8 --- /dev/null +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_leads.py @@ -0,0 +1,140 @@ +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. + +import http +from typing import Dict, Optional + +import freezegun +import mock + +from airbyte_cdk.test.mock_http import HttpMocker, HttpResponse +from airbyte_cdk.test.mock_http.response_builder import FieldPath +from airbyte_protocol.models import SyncMode + +from . import HubspotTestCase +from .request_builders.streams import CRMStreamRequestBuilder +from .response_builder.streams import HubspotStreamResponseBuilder + + +@freezegun.freeze_time("2024-03-03T14:42:00Z") +class TestLeadsStream(HubspotTestCase): + SCOPES = ["crm.objects.leads.read"] + CURSOR_FIELD = "updatedAt" + STREAM_NAME = "leads" + OBJECT_TYPE = "leads" + ASSOCIATIONS = ["contacts", "companies"] + + @property + def response_builder(self): + return HubspotStreamResponseBuilder.for_stream(self.STREAM_NAME) + + def request(self, page_token: Optional[Dict[str, str]] = None): + request_builder = ( + CRMStreamRequestBuilder() + .for_entity(self.OBJECT_TYPE) + .with_associations(self.ASSOCIATIONS) + .with_properties(list(self.PROPERTIES.keys())) + ) + if page_token: + request_builder = request_builder.with_page_token(page_token) + return request_builder.build() + + def response(self, with_pagination: bool = False): + record = ( + self.record_builder(self.STREAM_NAME, FieldPath(self.CURSOR_FIELD)) + .with_field(FieldPath(self.CURSOR_FIELD), self.dt_str(self.updated_at())) + .with_field(FieldPath("id"), self.OBJECT_ID) + ) + response = self.response_builder.with_record(record) + if with_pagination: + response = response.with_pagination() + return response.build() + + def _set_up_oauth(self, http_mocker: HttpMocker): + self.mock_oauth(http_mocker, self.ACCESS_TOKEN) + self.mock_scopes(http_mocker, self.ACCESS_TOKEN, self.SCOPES) + + def _set_up_requests(self, http_mocker: HttpMocker, with_oauth: bool = False): + if with_oauth: + self._set_up_oauth(http_mocker) + self.mock_custom_objects(http_mocker) + self.mock_properties(http_mocker, self.OBJECT_TYPE, self.PROPERTIES) + + @HttpMocker() + def test_given_oauth_authentication_when_read_then_perform_authenticated_queries(self, http_mocker: HttpMocker): + self._set_up_requests(http_mocker, with_oauth=True) + self.read_from_stream(self.oauth_config(), self.STREAM_NAME, SyncMode.full_refresh) + + @HttpMocker() + def test_given_records_when_read_extract_desired_records(self, http_mocker: HttpMocker): + self._set_up_requests(http_mocker, with_oauth=True) + self.mock_response(http_mocker, self.request(), self.response()) + output = self.read_from_stream(self.oauth_config(), self.STREAM_NAME, SyncMode.full_refresh) + assert len(output.records) == 1 + + @HttpMocker() + def test_given_one_page_when_read_stream_private_token_then_return_records(self, http_mocker: HttpMocker): + self._set_up_requests(http_mocker) + self.mock_response(http_mocker, self.request(), self.response()) + output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), self.STREAM_NAME, SyncMode.full_refresh) + assert len(output.records) == 1 + + @HttpMocker() + def test_given_two_pages_when_read_then_return_records(self, http_mocker: HttpMocker): + self._set_up_requests(http_mocker) + self.mock_response(http_mocker, self.request(), self.response(with_pagination=True)) + self.mock_response(http_mocker, self.request(page_token=self.response_builder.pagination_strategy.NEXT_PAGE_TOKEN), self.response()) + output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), self.STREAM_NAME, SyncMode.full_refresh) + assert len(output.records) == 2 + + @HttpMocker() + def test_given_error_response_when_read_analytics_then_get_trace_message(self, http_mocker: HttpMocker): + self._set_up_requests(http_mocker) + self.mock_response(http_mocker, self.request(), HttpResponse(status_code=500, body="{}")) + with mock.patch("time.sleep"): + output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), self.STREAM_NAME, SyncMode.full_refresh) + assert len(output.records) == 0 + assert len(output.trace_messages) > 0 + assert len(output.errors) > 0 + + @HttpMocker() + def test_given_500_then_200_when_read_then_return_records(self, http_mocker: HttpMocker): + self._set_up_requests(http_mocker) + self.mock_response(http_mocker, self.request(), [HttpResponse(status_code=500, body="{}"), self.response()]) + with mock.patch("time.sleep"): + output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), self.STREAM_NAME, SyncMode.full_refresh) + assert len(output.records) == 1 + assert len(output.trace_messages) > 0 + assert len(output.errors) == 0 + + @HttpMocker() + def test_given_missing_scopes_error_when_read_then_stop_sync(self, http_mocker: HttpMocker): + self.mock_oauth(http_mocker, self.ACCESS_TOKEN) + self.mock_scopes(http_mocker, self.ACCESS_TOKEN, []) + self.read_from_stream(self.oauth_config(), self.STREAM_NAME, SyncMode.full_refresh, expecting_exception=True) + + @HttpMocker() + def test_given_unauthorized_error_when_read_then_stop_sync(self, http_mocker: HttpMocker): + self._set_up_requests(http_mocker) + self.mock_response(http_mocker, self.request(), HttpResponse(status_code=http.HTTPStatus.UNAUTHORIZED, body="{}")) + with mock.patch("time.sleep"): + output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), self.STREAM_NAME, SyncMode.full_refresh) + assert len(output.records) == 0 + assert len(output.trace_messages) > 0 + assert len(output.errors) > 0 + + @HttpMocker() + def test_given_one_page_when_read_then_get_records_with_flattened_properties(self, http_mocker: HttpMocker): + self._set_up_requests(http_mocker) + self.mock_response(http_mocker, self.request(), self.response()) + output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), self.STREAM_NAME, SyncMode.full_refresh) + record = output.records[0].record.data + assert "properties" in record # legacy struct remains to not introduce breaking changes + prop_fields = len([f for f in record if f.startswith("properties_")]) + assert prop_fields > 0 + + @HttpMocker() + def test_given_incremental_sync_when_read_then_state_message_produced_and_state_match_latest_record(self, http_mocker: HttpMocker): + self._set_up_requests(http_mocker) + self.mock_response(http_mocker, self.request(), self.response()) + output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), self.STREAM_NAME, SyncMode.incremental) + assert len(output.state_messages) == 1 diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_owners_archived.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_owners_archived.py index d54a94ca6a9d..eef01cbc0fc5 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_owners_archived.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_owners_archived.py @@ -1,6 +1,7 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. import freezegun + from airbyte_cdk.test.mock_http import HttpMocker from airbyte_cdk.test.mock_http.response_builder import FieldPath from airbyte_protocol.models import SyncMode @@ -16,6 +17,7 @@ class TestOwnersArchivedStream(HubspotTestCase): The test case contains a single test - this is just a sanity check, as the tested stream is identical to the `Owners` stream (which is covered by acceptance tests), except for a single url param. """ + SCOPES = ["crm.objects.owners.read"] CURSOR_FIELD = "updatedAt" STREAM_NAME = "owners_archived" @@ -28,10 +30,10 @@ def response_builder(self): return HubspotStreamResponseBuilder.for_stream(self.STREAM_NAME) def response(self, with_pagination: bool = False): - record = self.record_builder(self.STREAM_NAME, FieldPath(self.CURSOR_FIELD)).with_field( - FieldPath(self.CURSOR_FIELD), self.dt_str(self.updated_at()) - ).with_field( - FieldPath("id"), self.OBJECT_ID + record = ( + self.record_builder(self.STREAM_NAME, FieldPath(self.CURSOR_FIELD)) + .with_field(FieldPath(self.CURSOR_FIELD), self.dt_str(self.updated_at())) + .with_field(FieldPath("id"), self.OBJECT_ID) ) response = self.response_builder.with_record(record) if with_pagination: @@ -54,7 +56,7 @@ def test_given_two_pages_when_read_stream_private_token_then_return_records(self self.mock_response( http_mocker, self.request().with_page_token(self.response_builder.pagination_strategy.NEXT_PAGE_TOKEN).build(), - self.response().build() + self.response().build(), ) output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), self.STREAM_NAME, SyncMode.full_refresh) assert len(output.records) == 2 diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_web_analytics_streams.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_web_analytics_streams.py index 7e3889a69ee3..bd22328de3ec 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_web_analytics_streams.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/integrations/test_web_analytics_streams.py @@ -8,6 +8,7 @@ import mock import pytest import pytz + from airbyte_cdk.test.mock_http import HttpMocker, HttpResponse from airbyte_cdk.test.mock_http.response_builder import FieldPath from airbyte_protocol.models import AirbyteStateBlob, AirbyteStateMessage, AirbyteStateType, AirbyteStreamState, StreamDescriptor, SyncMode @@ -16,6 +17,7 @@ from .request_builders.streams import CRMStreamRequestBuilder, IncrementalCRMStreamRequestBuilder, WebAnalyticsRequestBuilder from .response_builder.streams import HubspotStreamResponseBuilder + CRM_STREAMS = ( ("tickets_web_analytics", "tickets", "ticket", ["contacts", "deals", "companies"]), ("deals_web_analytics", "deals", "deal", ["contacts", "companies", "line_items"]), @@ -51,17 +53,11 @@ def web_analytics_request( object_type: str, start_date: Optional[str] = None, end_date: Optional[str] = None, - first_page: bool = True + first_page: bool = True, ): start_date = start_date or cls.dt_str(cls.start_date()) end_date = end_date or cls.dt_str(cls.now()) - query = { - "limit": 100, - "occurredAfter": start_date, - "occurredBefore": end_date, - "objectId": object_id, - "objectType": object_type - } + query = {"limit": 100, "occurredAfter": start_date, "occurredBefore": end_date, "objectId": object_id, "objectType": object_type} if not first_page: query.update(cls.response_builder(stream).pagination_strategy.NEXT_PAGE_TOKEN) @@ -95,10 +91,10 @@ def mock_parent_object( ): response_builder = cls.response_builder(stream_name) for object_id in object_ids: - record = cls.record_builder(stream_name, FieldPath(cls.PARENT_CURSOR_FIELD)).with_field( - FieldPath(cls.PARENT_CURSOR_FIELD), cls.dt_str(cls.updated_at()) - ).with_field( - FieldPath("id"), object_id + record = ( + cls.record_builder(stream_name, FieldPath(cls.PARENT_CURSOR_FIELD)) + .with_field(FieldPath(cls.PARENT_CURSOR_FIELD), cls.dt_str(cls.updated_at())) + .with_field(FieldPath("id"), object_id) ) response_builder = response_builder.with_record(record) if with_pagination: @@ -136,7 +132,7 @@ def test_given_one_page_when_read_stream_oauth_then_return_records( self.mock_response( http_mocker, self.web_analytics_request(stream_name, self.ACCESS_TOKEN, self.OBJECT_ID, object_type), - self.web_analytics_response(stream_name) + self.web_analytics_response(stream_name), ) output = self.read_from_stream(self.oauth_config(), stream_name, SyncMode.full_refresh) assert len(output.records) == 1 @@ -154,7 +150,7 @@ def test_given_one_page_when_read_stream_private_token_then_return_records( self.mock_response( http_mocker, self.web_analytics_request(stream_name, self.ACCESS_TOKEN, self.OBJECT_ID, object_type), - self.web_analytics_response(stream_name) + self.web_analytics_response(stream_name), ) output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), stream_name, SyncMode.full_refresh) assert len(output.records) == 1 @@ -172,12 +168,12 @@ def test_given_two_pages_when_read_then_return_records( self.mock_response( http_mocker, self.web_analytics_request(stream_name, self.ACCESS_TOKEN, self.OBJECT_ID, object_type), - self.web_analytics_response(stream_name, with_pagination=True) + self.web_analytics_response(stream_name, with_pagination=True), ) self.mock_response( http_mocker, self.web_analytics_request(stream_name, self.ACCESS_TOKEN, self.OBJECT_ID, object_type, first_page=False), - self.web_analytics_response(stream_name) + self.web_analytics_response(stream_name), ) output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), stream_name, SyncMode.full_refresh) assert len(output.records) == 2 @@ -196,7 +192,7 @@ def test_given_two_parent_pages_when_read_then_return_records( parent_stream_name, parent_stream_associations, with_pagination=True, - properties=list(self.PROPERTIES.keys()) + properties=list(self.PROPERTIES.keys()), ) self.mock_parent_object( http_mocker, @@ -205,17 +201,17 @@ def test_given_two_parent_pages_when_read_then_return_records( parent_stream_name, parent_stream_associations, first_page=False, - properties=list(self.PROPERTIES.keys()) + properties=list(self.PROPERTIES.keys()), ) self.mock_response( http_mocker, self.web_analytics_request(stream_name, self.ACCESS_TOKEN, self.OBJECT_ID, object_type), - self.web_analytics_response(stream_name) + self.web_analytics_response(stream_name), ) self.mock_response( http_mocker, self.web_analytics_request(stream_name, self.ACCESS_TOKEN, "another_object_id", object_type), - self.web_analytics_response(stream_name) + self.web_analytics_response(stream_name), ) output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), stream_name, SyncMode.full_refresh) assert len(output.records) == 2 @@ -236,7 +232,7 @@ def test_given_wide_date_range_and_multiple_parent_records_when_read_then_return parent_stream_name, parent_stream_associations, list(self.PROPERTIES.keys()), - date_range=start_to_end + date_range=start_to_end, ) for dt_range in date_ranges: for _id in (self.OBJECT_ID, "another_object_id"): @@ -245,7 +241,7 @@ def test_given_wide_date_range_and_multiple_parent_records_when_read_then_return self.mock_response( http_mocker, self.web_analytics_request(stream_name, self.ACCESS_TOKEN, _id, object_type, start, end), - web_analytics_response + web_analytics_response, ) config_start_dt = date_ranges[0][0] output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN, config_start_dt), stream_name, SyncMode.full_refresh) @@ -264,7 +260,7 @@ def test_given_error_response_when_read_analytics_then_get_trace_message( self.mock_response( http_mocker, self.web_analytics_request(stream_name, self.ACCESS_TOKEN, self.OBJECT_ID, object_type), - HttpResponse(status_code=500, body="{}") + HttpResponse(status_code=500, body="{}"), ) with mock.patch("time.sleep"): output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), stream_name, SyncMode.full_refresh) @@ -285,10 +281,7 @@ def test_given_500_then_200_when_read_then_return_records( self.mock_response( http_mocker, self.web_analytics_request(stream_name, self.ACCESS_TOKEN, self.OBJECT_ID, object_type), - [ - HttpResponse(status_code=500, body="{}"), - self.web_analytics_response(stream_name) - ] + [HttpResponse(status_code=500, body="{}"), self.web_analytics_response(stream_name)], ) with mock.patch("time.sleep"): output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), stream_name, SyncMode.full_refresh) @@ -299,12 +292,7 @@ def test_given_500_then_200_when_read_then_return_records( @pytest.mark.parametrize(("stream_name", "parent_stream_name", "object_type", "parent_stream_associations"), CRM_STREAMS) @HttpMocker() def test_given_missing_scopes_error_when_read_then_hault( - self, - stream_name, - parent_stream_name, - object_type, - parent_stream_associations, - http_mocker: HttpMocker + self, stream_name, parent_stream_name, object_type, parent_stream_associations, http_mocker: HttpMocker ): self.mock_oauth(http_mocker, self.ACCESS_TOKEN) self.mock_scopes(http_mocker, self.ACCESS_TOKEN, []) @@ -313,12 +301,7 @@ def test_given_missing_scopes_error_when_read_then_hault( @pytest.mark.parametrize(("stream_name", "parent_stream_name", "object_type", "parent_stream_associations"), CRM_STREAMS) @HttpMocker() def test_given_unauthorized_error_when_read_then_hault( - self, - stream_name, - parent_stream_name, - object_type, - parent_stream_associations, - http_mocker: HttpMocker + self, stream_name, parent_stream_name, object_type, parent_stream_associations, http_mocker: HttpMocker ): self.mock_custom_objects(http_mocker) self.mock_properties(http_mocker, object_type, self.PROPERTIES) @@ -328,7 +311,7 @@ def test_given_unauthorized_error_when_read_then_hault( self.mock_response( http_mocker, self.web_analytics_request(stream_name, self.ACCESS_TOKEN, self.OBJECT_ID, object_type), - HttpResponse(status_code=http.HTTPStatus.UNAUTHORIZED, body="{}") + HttpResponse(status_code=http.HTTPStatus.UNAUTHORIZED, body="{}"), ) with mock.patch("time.sleep"): output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), stream_name, SyncMode.full_refresh) @@ -339,12 +322,7 @@ def test_given_unauthorized_error_when_read_then_hault( @pytest.mark.parametrize(("stream_name", "parent_stream_name", "object_type", "parent_stream_associations"), CRM_STREAMS) @HttpMocker() def test_given_one_page_when_read_then_get_transformed_records( - self, - stream_name, - parent_stream_name, - object_type, - parent_stream_associations, - http_mocker: HttpMocker + self, stream_name, parent_stream_name, object_type, parent_stream_associations, http_mocker: HttpMocker ): self.mock_custom_objects(http_mocker) self.mock_properties(http_mocker, object_type, self.PROPERTIES) @@ -354,7 +332,7 @@ def test_given_one_page_when_read_then_get_transformed_records( self.mock_response( http_mocker, self.web_analytics_request(stream_name, self.ACCESS_TOKEN, self.OBJECT_ID, object_type), - self.web_analytics_response(stream_name) + self.web_analytics_response(stream_name), ) output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), stream_name, SyncMode.full_refresh) record = output.records[0].record.data @@ -365,12 +343,7 @@ def test_given_one_page_when_read_then_get_transformed_records( @pytest.mark.parametrize(("stream_name", "parent_stream_name", "object_type", "parent_stream_associations"), CRM_STREAMS) @HttpMocker() def test_given_one_page_when_read_then_get_no_records_filtered( - self, - stream_name, - parent_stream_name, - object_type, - parent_stream_associations, - http_mocker: HttpMocker + self, stream_name, parent_stream_name, object_type, parent_stream_associations, http_mocker: HttpMocker ): # validate that no filter is applied on the record set received from the API response self.mock_custom_objects(http_mocker) @@ -381,7 +354,7 @@ def test_given_one_page_when_read_then_get_no_records_filtered( self.mock_response( http_mocker, self.web_analytics_request(stream_name, self.ACCESS_TOKEN, self.OBJECT_ID, object_type), - self.web_analytics_response(stream_name, updated_on=self.dt_str(self.now() - timedelta(days=365))) + self.web_analytics_response(stream_name, updated_on=self.dt_str(self.now() - timedelta(days=365))), ) output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), stream_name, SyncMode.full_refresh) assert len(output.records) == 1 @@ -399,11 +372,9 @@ def test_given_incremental_sync_when_read_then_state_message_produced_and_state_ self.mock_response( http_mocker, self.web_analytics_request(stream_name, self.ACCESS_TOKEN, self.OBJECT_ID, object_type), - self.web_analytics_response(stream_name, id=self.OBJECT_ID) - ) - output = self.read_from_stream( - self.private_token_config(self.ACCESS_TOKEN), stream_name, SyncMode.incremental + self.web_analytics_response(stream_name, id=self.OBJECT_ID), ) + output = self.read_from_stream(self.private_token_config(self.ACCESS_TOKEN), stream_name, SyncMode.incremental) assert len(output.state_messages) == 1 cursor_value_from_state_message = output.most_recent_state.stream_state.dict().get(self.OBJECT_ID, {}).get(self.CURSOR_FIELD) @@ -423,15 +394,15 @@ def test_given_state_with_no_current_slice_when_read_then_current_slice_in_state self.mock_response( http_mocker, self.web_analytics_request(stream_name, self.ACCESS_TOKEN, self.OBJECT_ID, object_type), - self.web_analytics_response(stream_name, id=self.OBJECT_ID) + self.web_analytics_response(stream_name, id=self.OBJECT_ID), ) another_object_id = "another_object_id" current_state = AirbyteStateMessage( type=AirbyteStateType.STREAM, stream=AirbyteStreamState( stream_descriptor=StreamDescriptor(name=stream_name), - stream_state=AirbyteStateBlob(**{another_object_id: {self.CURSOR_FIELD: self.dt_str(self.now())}}) - ) + stream_state=AirbyteStateBlob(**{another_object_id: {self.CURSOR_FIELD: self.dt_str(self.now())}}), + ), ) output = self.read_from_stream( self.private_token_config(self.ACCESS_TOKEN), stream_name, SyncMode.incremental, state=[current_state] @@ -453,14 +424,14 @@ def test_given_state_with_current_slice_when_read_then_state_is_updated( self.mock_response( http_mocker, self.web_analytics_request(stream_name, self.ACCESS_TOKEN, self.OBJECT_ID, object_type), - self.web_analytics_response(stream_name, id=self.OBJECT_ID) + self.web_analytics_response(stream_name, id=self.OBJECT_ID), ) current_state = AirbyteStateMessage( type=AirbyteStateType.STREAM, stream=AirbyteStreamState( stream_descriptor=StreamDescriptor(name=stream_name), - stream_state=AirbyteStateBlob(**{self.OBJECT_ID: {self.CURSOR_FIELD: self.dt_str(self.start_date() - timedelta(days=30))}}) - ) + stream_state=AirbyteStateBlob(**{self.OBJECT_ID: {self.CURSOR_FIELD: self.dt_str(self.start_date() - timedelta(days=30))}}), + ), ) output = self.read_from_stream( self.private_token_config(self.ACCESS_TOKEN), stream_name, SyncMode.incremental, state=[current_state] @@ -493,24 +464,23 @@ def mock_parent_object( date_range = date_range or (cls.dt_str(cls.start_date()), cls.dt_str(cls.now())) response_builder = cls.response_builder(stream_name) for object_id in object_ids: - record = cls.record_builder(stream_name, FieldPath(cls.PARENT_CURSOR_FIELD)).with_field( - FieldPath(cls.PARENT_CURSOR_FIELD), cls.dt_str(cls.updated_at()) - ).with_field( - FieldPath("id"), object_id + record = ( + cls.record_builder(stream_name, FieldPath(cls.PARENT_CURSOR_FIELD)) + .with_field(FieldPath(cls.PARENT_CURSOR_FIELD), cls.dt_str(cls.updated_at())) + .with_field(FieldPath("id"), object_id) ) response_builder = response_builder.with_record(record) if with_pagination: response_builder = response_builder.with_pagination() start, end = date_range - request_builder = IncrementalCRMStreamRequestBuilder().for_entity( - object_type - ).with_associations( - associations - ).with_dt_range( - ("startTimestamp", cls.dt_conversion(start)), - ("endTimestamp", cls.dt_conversion(end)) - ).with_properties(properties) + request_builder = ( + IncrementalCRMStreamRequestBuilder() + .for_entity(object_type) + .with_associations(associations) + .with_dt_range(("startTimestamp", cls.dt_conversion(start)), ("endTimestamp", cls.dt_conversion(end))) + .with_properties(properties) + ) if not first_page: request_builder = request_builder.with_page_token(response_builder.pagination_strategy.NEXT_PAGE_TOKEN) @@ -533,12 +503,8 @@ def test_given_one_page_when_read_stream_private_token_then_return_records( ) @pytest.mark.parametrize(("stream_name", "parent_stream_name", "object_type", "parent_stream_associations"), CRM_INCREMENTAL_STREAMS) - def test_given_two_pages_when_read_then_return_records( - self, stream_name, parent_stream_name, object_type, parent_stream_associations - ): - super().test_given_two_pages_when_read_then_return_records( - stream_name, parent_stream_name, object_type, parent_stream_associations - ) + def test_given_two_pages_when_read_then_return_records(self, stream_name, parent_stream_name, object_type, parent_stream_associations): + super().test_given_two_pages_when_read_then_return_records(stream_name, parent_stream_name, object_type, parent_stream_associations) @pytest.mark.parametrize(("stream_name", "parent_stream_name", "object_type", "parent_stream_associations"), CRM_INCREMENTAL_STREAMS) def test_given_wide_date_range_and_multiple_parent_records_when_read_then_return_records( @@ -573,12 +539,8 @@ def test_given_missing_scopes_error_when_read_then_hault( ) @pytest.mark.parametrize(("stream_name", "parent_stream_name", "object_type", "parent_stream_associations"), CRM_INCREMENTAL_STREAMS) - def test_given_unauthorized_error_when_read_then_hault( - self, stream_name, parent_stream_name, object_type, parent_stream_associations - ): - super().test_given_unauthorized_error_when_read_then_hault( - stream_name, parent_stream_name, object_type, parent_stream_associations - ) + def test_given_unauthorized_error_when_read_then_hault(self, stream_name, parent_stream_name, object_type, parent_stream_associations): + super().test_given_unauthorized_error_when_read_then_hault(stream_name, parent_stream_name, object_type, parent_stream_associations) @pytest.mark.parametrize(("stream_name", "parent_stream_name", "object_type", "parent_stream_associations"), CRM_INCREMENTAL_STREAMS) def test_given_one_page_when_read_then_get_transformed_records( diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/resource/http/response/leads.json b/airbyte-integrations/connectors/source-hubspot/unit_tests/resource/http/response/leads.json new file mode 100644 index 000000000000..ce8e668c12e4 --- /dev/null +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/resource/http/response/leads.json @@ -0,0 +1,319 @@ +{ + "results": [ + { + "id": "784566996485", + "properties": { + "hs_all_accessible_team_ids": null, + "hs_all_assigned_business_unit_ids": null, + "hs_all_owner_ids": "36562474", + "hs_all_team_ids": null, + "hs_associated_company_domain": null, + "hs_associated_company_name": null, + "hs_associated_contact_email": "test.test@test.test", + "hs_associated_contact_firstname": "Test", + "hs_associated_contact_lastname": "Test", + "hs_calls_connected_count": 0.0, + "hs_company_analytics_source": null, + "hs_company_analytics_source_data_1": null, + "hs_company_analytics_source_data_2": null, + "hs_company_avatar_filemanager_key": null, + "hs_company_is_target_account": null, + "hs_company_last_activity_date": null, + "hs_company_last_engagement_timestamp": null, + "hs_company_last_engagement_type": null, + "hs_company_last_webpage_visit_timestamp": null, + "hs_company_next_activity_date": null, + "hs_company_next_activity_type": null, + "hs_company_num_webpage_views": null, + "hs_company_timezone": null, + "hs_contact_analytics_source": "DIRECT_TRAFFIC", + "hs_contact_analytics_source_data_1": "ag54u3yu-tuy5-54ji-9e78-493eae864f12", + "hs_contact_analytics_source_data_2": null, + "hs_contact_avatar_filemanager_key": null, + "hs_contact_buying_role": null, + "hs_contact_job_title": null, + "hs_contact_last_activity_date": null, + "hs_contact_last_engagement_timestamp": null, + "hs_contact_last_engagement_type": null, + "hs_contact_last_webpage_visit_timestamp": "2024-06-26T23:59:35.905000+00:00", + "hs_contact_next_activity_date": null, + "hs_contact_next_activity_type": null, + "hs_contact_num_webpage_views": 0.0, + "hs_contact_timezone": "america_slash_los_angeles", + "hs_created_by_user_id": 34625766.0, + "hs_createdate": "2024-08-30T15:08:29.575000+00:00", + "hs_date_entered_attempting_stage_id_745667965": "2024-08-30T15:08:29.575000+00:00", + "hs_date_entered_connected_stage_id_2058487257": "2024-08-30T15:08:29.575000+00:00", + "hs_date_entered_new_stage_id_1318266061": "2024-08-30T15:08:29.575000+00:00", + "hs_date_entered_qualified_stage_id_233247981": "2024-08-30T15:08:29.575000+00:00", + "hs_date_entered_unqualified_stage_id_1675714327": null, + "hs_date_exited_attempting_stage_id_745667965": "2024-08-30T15:08:29.575000+00:00", + "hs_date_exited_connected_stage_id_2058487257": "2024-08-30T15:08:29.575000+00:00", + "hs_date_exited_new_stage_id_1318266061": "2024-08-30T15:08:29.575000+00:00", + "hs_date_exited_qualified_stage_id_233247981": null, + "hs_date_exited_unqualified_stage_id_1675714327": null, + "hs_emails_connected_count": 0.0, + "hs_initial_assign_notification_state": null, + "hs_last_activity_date": null, + "hs_last_engagement_timestamp": null, + "hs_last_engagement_type": null, + "hs_last_webpage_visit_timestamp": "2024-06-26T23:59:35.905000+00:00", + "hs_lastmodifieddate": "2024-08-30T15:12:58.323000+00:00", + "hs_lead_associated_deal_pipeline_stage": null, + "hs_lead_associated_deals_count": 0.0, + "hs_lead_call_count": 0.0, + "hs_lead_closed_won_deals_amount": null, + "hs_lead_communication_count": 0.0, + "hs_lead_currency_code": null, + "hs_lead_disqualification_note": null, + "hs_lead_disqualification_reason": null, + "hs_lead_email_count": 0.0, + "hs_lead_first_outreach_date": null, + "hs_lead_flow_id": null, + "hs_lead_import_unique_key": null, + "hs_lead_inferred_pseudostage": "NEW_STAGE", + "hs_lead_is_disqualified": 0.0, + "hs_lead_is_in_progress": 0.0, + "hs_lead_is_new": 0.0, + "hs_lead_is_open": 0.0, + "hs_lead_is_qualified": 1.0, + "hs_lead_label": "WARM", + "hs_lead_meeting_count": 0.0, + "hs_lead_name": "Test Test", + "hs_lead_name_calculated": "Test Test 2024-08", + "hs_lead_outreach_activity_count": 0.0, + "hs_lead_pipeline_value": null, + "hs_lead_primary_company_owner": null, + "hs_lead_primary_contact_owner": "36562474", + "hs_lead_source": "DIRECT_TRAFFIC", + "hs_lead_source_company_lifecycle_stage": null, + "hs_lead_source_contact_lifecycle_stage": "salesqualifiedlead", + "hs_lead_source_drill_down_1": "ag54u3yu-tuy5-54ji-9e78-493eae864f12", + "hs_lead_source_drill_down_2": null, + "hs_lead_source_lifecycle_stage": "salesqualifiedlead", + "hs_lead_time_to_first_outreach": null, + "hs_lead_title": null, + "hs_lead_type": "NEW_BUSINESS", + "hs_meetings_connected_count": 0.0, + "hs_merged_object_ids": null, + "hs_next_activity_date": null, + "hs_next_activity_type": null, + "hs_num_webpage_views": 0.0, + "hs_object_id": 784566996485.0, + "hs_object_source": "CRM_UI", + "hs_object_source_detail_1": null, + "hs_object_source_detail_2": null, + "hs_object_source_detail_3": null, + "hs_object_source_id": "userId:34625766", + "hs_object_source_label": "CRM_UI", + "hs_object_source_user_id": 34625766.0, + "hs_owner_id_calculated": "36562474", + "hs_pipeline": "lead-pipeline-id", + "hs_pipeline_stage": "qualified-stage-id", + "hs_pipeline_stage_category": "QUALIFIED", + "hs_pipeline_stage_category_last_updated_at": "2024-08-30T15:12:58.323000+00:00", + "hs_primary_associated_object_name": "Test Test", + "hs_primary_company_id": null, + "hs_primary_contact_enrolled_in_sequence": false, + "hs_primary_contact_id": 57582587682.0, + "hs_read_only": null, + "hs_shared_team_ids": null, + "hs_shared_user_ids": null, + "hs_tag_ids": null, + "hs_time_in_attempting_stage_id_745667965": 0.0, + "hs_time_in_connected_stage_id_2058487257": 0.0, + "hs_time_in_new_stage_id_1318266061": 0.0, + "hs_time_in_qualified_stage_id_233247981": 805781762.0, + "hs_time_in_unqualified_stage_id_1675714327": null, + "hs_unique_creation_key": null, + "hs_updated_by_user_id": 34625766.0, + "hs_user_ids_of_all_notification_followers": null, + "hs_user_ids_of_all_notification_unfollowers": null, + "hs_user_ids_of_all_owners": "23660227", + "hs_v2_cumulative_time_in_attempting_stage_id_745667965": null, + "hs_v2_cumulative_time_in_connected_stage_id_2058487257": null, + "hs_v2_cumulative_time_in_new_stage_id_1318266061": null, + "hs_v2_cumulative_time_in_qualified_stage_id_233247981": null, + "hs_v2_cumulative_time_in_unqualified_stage_id_1675714327": null, + "hs_v2_date_entered_attempting_stage_id_745667965": null, + "hs_v2_date_entered_connected_stage_id_2058487257": null, + "hs_v2_date_entered_new_stage_id_1318266061": null, + "hs_v2_date_entered_qualified_stage_id_233247981": "2024-08-30T15:08:29.575000+00:00", + "hs_v2_date_entered_unqualified_stage_id_1675714327": null, + "hs_v2_date_exited_attempting_stage_id_745667965": null, + "hs_v2_date_exited_connected_stage_id_2058487257": null, + "hs_v2_date_exited_new_stage_id_1318266061": null, + "hs_v2_date_exited_qualified_stage_id_233247981": null, + "hs_v2_date_exited_unqualified_stage_id_1675714327": null, + "hs_v2_latest_time_in_attempting_stage_id_745667965": null, + "hs_v2_latest_time_in_connected_stage_id_2058487257": null, + "hs_v2_latest_time_in_new_stage_id_1318266061": null, + "hs_v2_latest_time_in_qualified_stage_id_233247981": null, + "hs_v2_latest_time_in_unqualified_stage_id_1675714327": null, + "hs_was_imported": null, + "hs_workflow_updated_lifecycle_stage_of_company": null, + "hs_workflow_updated_lifecycle_stage_of_contact": null, + "hubspot_owner_assigneddate": "2024-08-30T15:08:32.982000+00:00", + "hubspot_owner_id": "36562474", + "hubspot_team_id": null + }, + "createdAt": "2024-08-30T15:08:29.575Z", + "updatedAt": "2024-08-30T15:12:58.323Z", + "archived": false, + "contacts": ["57582587682", "57582587682"], + "properties_hs_all_accessible_team_ids": null, + "properties_hs_all_assigned_business_unit_ids": null, + "properties_hs_all_owner_ids": "36562474", + "properties_hs_all_team_ids": null, + "properties_hs_associated_company_domain": null, + "properties_hs_associated_company_name": null, + "properties_hs_associated_contact_email": "test.test@test.test", + "properties_hs_associated_contact_firstname": "Test", + "properties_hs_associated_contact_lastname": "Test", + "properties_hs_calls_connected_count": 0.0, + "properties_hs_company_analytics_source": null, + "properties_hs_company_analytics_source_data_1": null, + "properties_hs_company_analytics_source_data_2": null, + "properties_hs_company_avatar_filemanager_key": null, + "properties_hs_company_is_target_account": null, + "properties_hs_company_last_activity_date": null, + "properties_hs_company_last_engagement_timestamp": null, + "properties_hs_company_last_engagement_type": null, + "properties_hs_company_last_webpage_visit_timestamp": null, + "properties_hs_company_next_activity_date": null, + "properties_hs_company_next_activity_type": null, + "properties_hs_company_num_webpage_views": null, + "properties_hs_company_timezone": null, + "properties_hs_contact_analytics_source": "DIRECT_TRAFFIC", + "properties_hs_contact_analytics_source_data_1": "ag54u3yu-tuy5-54ji-9e78-493eae864f12", + "properties_hs_contact_analytics_source_data_2": null, + "properties_hs_contact_avatar_filemanager_key": null, + "properties_hs_contact_buying_role": null, + "properties_hs_contact_job_title": null, + "properties_hs_contact_last_activity_date": null, + "properties_hs_contact_last_engagement_timestamp": null, + "properties_hs_contact_last_engagement_type": null, + "properties_hs_contact_last_webpage_visit_timestamp": "2024-06-26T23:59:35.905000+00:00", + "properties_hs_contact_next_activity_date": null, + "properties_hs_contact_next_activity_type": null, + "properties_hs_contact_num_webpage_views": 0.0, + "properties_hs_contact_timezone": "america_slash_los_angeles", + "properties_hs_created_by_user_id": 34625766.0, + "properties_hs_createdate": "2024-08-30T15:08:29.575000+00:00", + "properties_hs_date_entered_attempting_stage_id_745667965": "2024-08-30T15:08:29.575000+00:00", + "properties_hs_date_entered_connected_stage_id_2058487257": "2024-08-30T15:08:29.575000+00:00", + "properties_hs_date_entered_new_stage_id_1318266061": "2024-08-30T15:08:29.575000+00:00", + "properties_hs_date_entered_qualified_stage_id_233247981": "2024-08-30T15:08:29.575000+00:00", + "properties_hs_date_entered_unqualified_stage_id_1675714327": null, + "properties_hs_date_exited_attempting_stage_id_745667965": "2024-08-30T15:08:29.575000+00:00", + "properties_hs_date_exited_connected_stage_id_2058487257": "2024-08-30T15:08:29.575000+00:00", + "properties_hs_date_exited_new_stage_id_1318266061": "2024-08-30T15:08:29.575000+00:00", + "properties_hs_date_exited_qualified_stage_id_233247981": null, + "properties_hs_date_exited_unqualified_stage_id_1675714327": null, + "properties_hs_emails_connected_count": 0.0, + "properties_hs_initial_assign_notification_state": null, + "properties_hs_last_activity_date": null, + "properties_hs_last_engagement_timestamp": null, + "properties_hs_last_engagement_type": null, + "properties_hs_last_webpage_visit_timestamp": "2024-06-26T23:59:35.905000+00:00", + "properties_hs_lastmodifieddate": "2024-08-30T15:12:58.323000+00:00", + "properties_hs_lead_associated_deal_pipeline_stage": null, + "properties_hs_lead_associated_deals_count": 0.0, + "properties_hs_lead_call_count": 0.0, + "properties_hs_lead_closed_won_deals_amount": null, + "properties_hs_lead_communication_count": 0.0, + "properties_hs_lead_currency_code": null, + "properties_hs_lead_disqualification_note": null, + "properties_hs_lead_disqualification_reason": null, + "properties_hs_lead_email_count": 0.0, + "properties_hs_lead_first_outreach_date": null, + "properties_hs_lead_flow_id": null, + "properties_hs_lead_import_unique_key": null, + "properties_hs_lead_inferred_pseudostage": "NEW_STAGE", + "properties_hs_lead_is_disqualified": 0.0, + "properties_hs_lead_is_in_progress": 0.0, + "properties_hs_lead_is_new": 0.0, + "properties_hs_lead_is_open": 0.0, + "properties_hs_lead_is_qualified": 1.0, + "properties_hs_lead_label": "WARM", + "properties_hs_lead_meeting_count": 0.0, + "properties_hs_lead_name": "Test Test", + "properties_hs_lead_name_calculated": "Test Test 2024-08", + "properties_hs_lead_outreach_activity_count": 0.0, + "properties_hs_lead_pipeline_value": null, + "properties_hs_lead_primary_company_owner": null, + "properties_hs_lead_primary_contact_owner": "36562474", + "properties_hs_lead_source": "DIRECT_TRAFFIC", + "properties_hs_lead_source_company_lifecycle_stage": null, + "properties_hs_lead_source_contact_lifecycle_stage": "salesqualifiedlead", + "properties_hs_lead_source_drill_down_1": "ag54u3yu-tuy5-54ji-9e78-493eae864f12", + "properties_hs_lead_source_drill_down_2": null, + "properties_hs_lead_source_lifecycle_stage": "salesqualifiedlead", + "properties_hs_lead_time_to_first_outreach": null, + "properties_hs_lead_title": null, + "properties_hs_lead_type": "NEW_BUSINESS", + "properties_hs_meetings_connected_count": 0.0, + "properties_hs_merged_object_ids": null, + "properties_hs_next_activity_date": null, + "properties_hs_next_activity_type": null, + "properties_hs_num_webpage_views": 0.0, + "properties_hs_object_id": 784566996485.0, + "properties_hs_object_source": "CRM_UI", + "properties_hs_object_source_detail_1": null, + "properties_hs_object_source_detail_2": null, + "properties_hs_object_source_detail_3": null, + "properties_hs_object_source_id": "userId:34625766", + "properties_hs_object_source_label": "CRM_UI", + "properties_hs_object_source_user_id": 34625766.0, + "properties_hs_owner_id_calculated": "36562474", + "properties_hs_pipeline": "lead-pipeline-id", + "properties_hs_pipeline_stage": "qualified-stage-id", + "properties_hs_pipeline_stage_category": "QUALIFIED", + "properties_hs_pipeline_stage_category_last_updated_at": "2024-08-30T15:12:58.323000+00:00", + "properties_hs_primary_associated_object_name": "Test Test", + "properties_hs_primary_company_id": null, + "properties_hs_primary_contact_enrolled_in_sequence": false, + "properties_hs_primary_contact_id": 57582587682.0, + "properties_hs_read_only": null, + "properties_hs_shared_team_ids": null, + "properties_hs_shared_user_ids": null, + "properties_hs_tag_ids": null, + "properties_hs_time_in_attempting_stage_id_745667965": 0.0, + "properties_hs_time_in_connected_stage_id_2058487257": 0.0, + "properties_hs_time_in_new_stage_id_1318266061": 0.0, + "properties_hs_time_in_qualified_stage_id_233247981": 805781762.0, + "properties_hs_time_in_unqualified_stage_id_1675714327": null, + "properties_hs_unique_creation_key": null, + "properties_hs_updated_by_user_id": 34625766.0, + "properties_hs_user_ids_of_all_notification_followers": null, + "properties_hs_user_ids_of_all_notification_unfollowers": null, + "properties_hs_user_ids_of_all_owners": "23660227", + "properties_hs_v2_cumulative_time_in_attempting_stage_id_745667965": null, + "properties_hs_v2_cumulative_time_in_connected_stage_id_2058487257": null, + "properties_hs_v2_cumulative_time_in_new_stage_id_1318266061": null, + "properties_hs_v2_cumulative_time_in_qualified_stage_id_233247981": null, + "properties_hs_v2_cumulative_time_in_unqualified_stage_id_1675714327": null, + "properties_hs_v2_date_entered_attempting_stage_id_745667965": null, + "properties_hs_v2_date_entered_connected_stage_id_2058487257": null, + "properties_hs_v2_date_entered_new_stage_id_1318266061": null, + "properties_hs_v2_date_entered_qualified_stage_id_233247981": "2024-08-30T15:08:29.575000+00:00", + "properties_hs_v2_date_entered_unqualified_stage_id_1675714327": null, + "properties_hs_v2_date_exited_attempting_stage_id_745667965": null, + "properties_hs_v2_date_exited_connected_stage_id_2058487257": null, + "properties_hs_v2_date_exited_new_stage_id_1318266061": null, + "properties_hs_v2_date_exited_qualified_stage_id_233247981": null, + "properties_hs_v2_date_exited_unqualified_stage_id_1675714327": null, + "properties_hs_v2_latest_time_in_attempting_stage_id_745667965": null, + "properties_hs_v2_latest_time_in_connected_stage_id_2058487257": null, + "properties_hs_v2_latest_time_in_new_stage_id_1318266061": null, + "properties_hs_v2_latest_time_in_qualified_stage_id_233247981": null, + "properties_hs_v2_latest_time_in_unqualified_stage_id_1675714327": null, + "properties_hs_was_imported": null, + "properties_hs_workflow_updated_lifecycle_stage_of_company": null, + "properties_hs_workflow_updated_lifecycle_stage_of_contact": null, + "properties_hubspot_owner_assigneddate": "2024-08-30T15:08:32.982000+00:00", + "properties_hubspot_owner_id": "36562474", + "properties_hubspot_team_id": null + } + ] +} diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/test_components.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/test_components.py new file mode 100644 index 000000000000..e83609da66b8 --- /dev/null +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/test_components.py @@ -0,0 +1,84 @@ +# +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. +# +import pytest +from source_hubspot.components import NewtoLegacyFieldTransformation +from source_hubspot.streams import DEALS_NEW_TO_LEGACY_FIELDS_MAPPING + + +@pytest.mark.parametrize( + "input, expected", + [ + ( + { + "name": {"type": ["null", "string"]}, + "hs_v2_cumulative_time_in_prospect": {"type": ["null", "string"]}, + "hs_v2_date_entered_prospect": {"type": ["null", "string"]}, + "hs_v2_date_exited_prospect": {"type": ["null", "string"]}, + "hs_v2_some_other_field": {"type": ["null", "string"]}, + }, + { + "name": {"type": ["null", "string"]}, + "hs_v2_cumulative_time_in_prospect": {"type": ["null", "string"]}, + "hs_v2_date_entered_prospect": {"type": ["null", "string"]}, + "hs_date_entered_prospect": {"type": ["null", "string"]}, + "hs_v2_date_exited_prospect": {"type": ["null", "string"]}, + "hs_date_exited_prospect": {"type": ["null", "string"]}, + "hs_v2_some_other_field": {"type": ["null", "string"]}, + }, + ), + ( + {"name": "Edgar Allen Poe", "age": 215, "birthplace": "Boston", "hs_v2_date_entered_poetry": 1827}, + { + "name": "Edgar Allen Poe", + "age": 215, + "birthplace": "Boston", + "hs_v2_date_entered_poetry": 1827, + "hs_date_entered_poetry": 1827, + }, + ), + ( + {"name": "Edgar Allen Poe", "age": 215, "birthplace": "Boston", "properties": {"hs_v2_date_entered_poetry": 1827}}, + { + "name": "Edgar Allen Poe", + "age": 215, + "birthplace": "Boston", + "properties": { + "hs_v2_date_entered_poetry": 1827, + "hs_date_entered_poetry": 1827, + }, + }, + ), + ( + { + "name": "Edgar Allen Poe", + "age": 215, + "birthplace": "Boston", + }, + { + "name": "Edgar Allen Poe", + "age": 215, + "birthplace": "Boston", + }, + ), + ( + {"name": "Edgar Allen Poe", "hs_v2_date_entered_poetry": 1827, "hs_date_entered_poetry": 9999}, + { + "name": "Edgar Allen Poe", + "hs_v2_date_entered_poetry": 1827, + "hs_date_entered_poetry": 9999, + }, + ), + ], + ids=[ + "Transforms stream schema/properties dictionary", + "Transforms record w/ flat properties", + "Transform record w/ nested properties", + "Does not transform record w/o need to transformation", + "Does not overwrite value for legacy field if legacy field exists", + ], +) +def test_new_to_legacy_field_transformation(input, expected): + transformer = NewtoLegacyFieldTransformation(DEALS_NEW_TO_LEGACY_FIELDS_MAPPING) + transformer.transform(input) + assert input == expected diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/test_field_type_converting.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/test_field_type_converting.py index a5793b49b957..454791f22202 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/test_field_type_converting.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/test_field_type_converting.py @@ -37,7 +37,6 @@ def test_field_type_format_converting(field_type, expected): ], ) def test_bad_field_type_converting(field_type, expected, caplog, capsys): - assert Stream._get_field_props(field_type=field_type) == expected logs = caplog.records diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/test_source.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/test_source.py index d383065a1cf8..2033d84ab433 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/test_source.py @@ -12,14 +12,16 @@ import mock import pendulum import pytest -from airbyte_cdk.models import ConfiguredAirbyteCatalog, SyncMode, Type from source_hubspot.errors import HubspotRateLimited, InvalidStartDateConfigError from source_hubspot.helpers import APIv3Property from source_hubspot.source import SourceHubspot from source_hubspot.streams import API, Companies, Deals, Engagements, MarketingEmails, Products, Stream +from airbyte_cdk.models import ConfiguredAirbyteCatalog, SyncMode, Type + from .utils import read_full_refresh, read_incremental + NUMBER_OF_PROPERTIES = 2000 logger = logging.getLogger("test_client") @@ -83,18 +85,16 @@ def test_check_connection_invalid_start_date_exception(config_invalid_date): @mock.patch("source_hubspot.source.SourceHubspot.get_custom_object_streams") def test_streams(requests_mock, config): - streams = SourceHubspot().streams(config) - assert len(streams) == 34 + assert len(streams) == 35 @mock.patch("source_hubspot.source.SourceHubspot.get_custom_object_streams") def test_streams_incremental(requests_mock, config_experimental): - streams = SourceHubspot().streams(config_experimental) - assert len(streams) == 46 + assert len(streams) == 47 def test_custom_streams(config_experimental): @@ -141,7 +141,7 @@ def test_cast_datetime(common_params, caplog): # if you find some diff locally try using "Ex: argument of type 'DateTime' is not iterable in the message". There could be a # difference in local environment when pendulum.parsing.__init__.py importing parse_iso8601. Anyway below is working fine # in container for now and I am not sure if this diff was just a problem with my setup. - "message": f"Couldn't parse date/datetime string in {field_name}, trying to parse timestamp... Field value: {field_value}. Ex: expected string or bytes-like object" + "message": f"Couldn't parse date/datetime string in {field_name}, trying to parse timestamp... Field value: {field_value}. Ex: expected string or bytes-like object", }, } assert expected_warning_message["log"]["message"] in caplog.text @@ -488,6 +488,7 @@ def test_search_based_stream_should_not_attempt_to_get_more_than_10k_records(req assert len(records) == 11000 assert test_stream.state["updatedAt"] == test_stream._init_sync.to_iso8601_string() + def test_search_based_incremental_stream_should_sort_by_id(requests_mock, common_params, fake_properties_list): """ If there are more than 10,000 records that would be returned by the Hubspot search endpoint, @@ -500,7 +501,7 @@ def test_search_based_incremental_stream_should_sort_by_id(requests_mock, common test_stream.associations = [] def random_date(start, end): - return pendulum.from_timestamp(random.randint(start, end)/1000).to_iso8601_string() + return pendulum.from_timestamp(random.randint(start, end) / 1000).to_iso8601_string() after = 0 @@ -518,17 +519,13 @@ def custom_callback(request, context): id = int(filters[2].get("value", 0)) next = int(after) + 100 results = [ - { - "id": f"{y + id}", - "updatedAt": random_date(min_time, max_time), - "after": after - } for y in range(int(after) + 1, next + 1) + {"id": f"{y + id}", "updatedAt": random_date(min_time, max_time), "after": after} for y in range(int(after) + 1, next + 1) ] context.status_code = 200 - if ((id + next) < 11000): + if (id + next) < 11000: return {"results": results, "paging": {"next": {"after": f"{next}"}}} else: - return {"results": results, "paging": {}} # Last page + return {"results": results, "paging": {}} # Last page properties_response = [ { @@ -787,6 +784,7 @@ def test_get_granted_scopes(requests_mock, mocker): assert expected_scopes == actual_scopes + def test_get_granted_scopes_retry(requests_mock, mocker): authenticator = mocker.Mock() expected_token = "the-token" diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/test_split_properties.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/test_split_properties.py index 86534f61540d..632ed4cf3554 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/test_split_properties.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/test_split_properties.py @@ -5,6 +5,7 @@ import pytest from source_hubspot.helpers import APIv1Property, APIv3Property + lorem_ipsum = """Lorem ipsum dolor sit amet, consectetur adipiscing elit""" lorem_ipsum = lorem_ipsum.lower().replace(",", "") diff --git a/airbyte-integrations/connectors/source-hubspot/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-hubspot/unit_tests/test_streams.py index 1052bae51c6d..064f98512101 100644 --- a/airbyte-integrations/connectors/source-hubspot/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-hubspot/unit_tests/test_streams.py @@ -7,7 +7,6 @@ import pendulum import pytest -from airbyte_cdk.models import SyncMode from source_hubspot.streams import ( Campaigns, Companies, @@ -32,6 +31,7 @@ Forms, FormSubmissions, Goals, + Leads, LineItems, MarketingEmails, Owners, @@ -43,6 +43,8 @@ Workflows, ) +from airbyte_cdk.models import SyncMode + from .utils import read_full_refresh, read_incremental @@ -109,6 +111,7 @@ def test_updated_at_field_non_exist_handler(requests_mock, common_params, fake_p (Forms, "form", {"updatedAt": "2022-02-25T16:43:11Z"}), (FormSubmissions, "form", {"updatedAt": "2022-02-25T16:43:11Z"}), (Goals, "goal_targets", {"updatedAt": "2022-02-25T16:43:11Z"}), + (Leads, "leads", {"updatedAt": "2022-02-25T16:43:11Z"}), (LineItems, "line_item", {"updatedAt": "2022-02-25T16:43:11Z"}), (MarketingEmails, "", {"updatedAt": "2022-02-25T16:43:11Z"}), (Owners, "", {"updatedAt": "2022-02-25T16:43:11Z"}), @@ -167,9 +170,7 @@ def test_streams_read(stream, endpoint, cursor_value, requests_mock, common_para contact_lists_v1_response = [ { "json": { - "contacts": [ - {"vid": "test_id", "merge-audits": [{"canonical-vid": 2, "vid-to-merge": 5608, "timestamp": 1653322839932}]} - ] + "contacts": [{"vid": "test_id", "merge-audits": [{"canonical-vid": 2, "vid-to-merge": 5608, "timestamp": 1653322839932}]}] }, "status_code": 200, } @@ -191,15 +192,96 @@ def test_streams_read(stream, endpoint, cursor_value, requests_mock, common_para records = read_full_refresh(stream) assert records + +@pytest.mark.parametrize( + "stream, endpoint, cursor_value", + [ + (Contacts, "contact", {"updatedAt": "2022-02-25T16:43:11Z"}), + (Deals, "deal", {"updatedAt": "2022-02-25T16:43:11Z"}), + (DealsArchived, "deal", {"archivedAt": "2022-02-25T16:43:11Z"}), + ], + ids=[ + "Contacts stream with v2 field transformations", + "Deals stream with v2 field transformations", + "DealsArchived stream with v2 field transformations", + ], +) +def test_stream_read_with_legacy_field_transformation( + stream, endpoint, cursor_value, requests_mock, common_params, fake_properties_list, migrated_properties_list +): + stream = stream(**common_params) + responses = [ + { + "json": { + stream.data_field: [ + { + "id": "test_id", + "created": "2022-02-25T16:43:11Z", + "properties": { + "hs_v2_latest_time_in_prospect": "1 month", + "hs_v2_date_entered_prospect": "2024-01-01T00:00:00Z", + "hs_v2_date_exited_prospect": "2024-02-01T00:00:00Z", + "hs_v2_cumulative_time_in_prsopect": "1 month", + "hs_v2_some_other_property_in_prospect": "Great property", + }, + } + | cursor_value + ], + } + } + ] + fake_properties_list.extend(migrated_properties_list) + properties_response = [ + { + "json": [ + {"name": property_name, "type": "string", "updatedAt": 1571085954360, "createdAt": 1565059306048} + for property_name in fake_properties_list + ], + "status_code": 200, + } + ] + stream._sync_mode = SyncMode.full_refresh + + requests_mock.register_uri("GET", stream.url, responses) + requests_mock.register_uri("GET", f"/properties/v2/{endpoint}/properties", properties_response) + + records = read_full_refresh(stream) + assert records + expected_record = { + "id": "test_id", + "created": "2022-02-25T16:43:11Z", + "properties": { + "hs_v2_date_entered_prospect": "2024-01-01T00:00:00Z", + "hs_v2_date_exited_prospect": "2024-02-01T00:00:00Z", + "hs_v2_latest_time_in_prospect": "1 month", + "hs_v2_cumulative_time_in_prsopect": "1 month", + "hs_v2_some_other_property_in_prospect": "Great property", + "hs_time_in_prospect": "1 month", + "hs_date_exited_prospect": "2024-02-01T00:00:00Z", + }, + "properties_hs_v2_date_entered_prospect": "2024-01-01T00:00:00Z", + "properties_hs_v2_date_exited_prospect": "2024-02-01T00:00:00Z", + "properties_hs_v2_latest_time_in_prospect": "1 month", + "properties_hs_v2_cumulative_time_in_prsopect": "1 month", + "properties_hs_v2_some_other_property_in_prospect": "Great property", + "properties_hs_time_in_prospect": "1 month", + "properties_hs_date_exited_prospect": "2024-02-01T00:00:00Z", + } | cursor_value + if isinstance(stream, Contacts): + expected_record = expected_record | {"properties_hs_lifecyclestage_prospect_date": "2024-01-01T00:00:00Z"} + expected_record["properties"] = expected_record["properties"] | {"hs_lifecyclestage_prospect_date": "2024-01-01T00:00:00Z"} + else: + expected_record = expected_record | {"properties_hs_date_entered_prospect": "2024-01-01T00:00:00Z"} + expected_record["properties"] = expected_record["properties"] | {"hs_date_entered_prospect": "2024-01-01T00:00:00Z"} + assert records[0] == expected_record + + @pytest.mark.parametrize("sync_mode", [SyncMode.full_refresh, SyncMode.incremental]) -def test_crm_search_streams_with_no_associations(sync_mode, common_params, requests_mock, fake_properties_list): +def test_crm_search_streams_with_no_associations(sync_mode, common_params, requests_mock, fake_properties_list): stream = DealSplits(**common_params) stream_state = { "type": "STREAM", - "stream": { - "stream_descriptor": { "name": "deal_splits" }, - "stream_state": { "updatedAt": "2021-01-01T00:00:00.000000Z" } - } + "stream": {"stream_descriptor": {"name": "deal_splits"}, "stream_state": {"updatedAt": "2021-01-01T00:00:00.000000Z"}}, } cursor_value = {"updatedAt": "2022-02-25T16:43:11Z"} responses = [ @@ -499,7 +581,7 @@ def test_contacts_merged_audit_stream_doesnt_call_hubspot_to_get_json_schema(req def test_get_custom_objects_metadata_success(requests_mock, custom_object_schema, expected_custom_object_json_schema, api): requests_mock.register_uri("GET", "/crm/v3/schemas", json={"results": [custom_object_schema]}) - for (entity, fully_qualified_name, schema, custom_properties) in api.get_custom_objects_metadata(): + for entity, fully_qualified_name, schema, custom_properties in api.get_custom_objects_metadata(): assert entity == "animals" assert fully_qualified_name == "p19936848_Animal" assert schema == expected_custom_object_json_schema diff --git a/airbyte-integrations/connectors/source-hugging-face-datasets/README.md b/airbyte-integrations/connectors/source-hugging-face-datasets/README.md new file mode 100644 index 000000000000..da3468d8ebf5 --- /dev/null +++ b/airbyte-integrations/connectors/source-hugging-face-datasets/README.md @@ -0,0 +1,33 @@ +# Hugging Face - Datasets +This directory contains the manifest-only connector for `source-hugging-face-datasets`. + +Imports any datasets from Hugging Face ([https://huggingface.co/datasets](https://huggingface.co/datasets)) + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-hugging-face-datasets:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-hugging-face-datasets build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-hugging-face-datasets test +``` + diff --git a/airbyte-integrations/connectors/source-hugging-face-datasets/acceptance-test-config.yml b/airbyte-integrations/connectors/source-hugging-face-datasets/acceptance-test-config.yml new file mode 100644 index 000000000000..694d6e3df436 --- /dev/null +++ b/airbyte-integrations/connectors/source-hugging-face-datasets/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-hugging-face-datasets:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-hugging-face-datasets/icon.svg b/airbyte-integrations/connectors/source-hugging-face-datasets/icon.svg new file mode 100644 index 000000000000..43c5d3c0c97a --- /dev/null +++ b/airbyte-integrations/connectors/source-hugging-face-datasets/icon.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-hugging-face-datasets/manifest.yaml b/airbyte-integrations/connectors/source-hugging-face-datasets/manifest.yaml new file mode 100644 index 000000000000..e03c0c9afa16 --- /dev/null +++ b/airbyte-integrations/connectors/source-hugging-face-datasets/manifest.yaml @@ -0,0 +1,223 @@ +version: 6.5.2 + +type: DeclarativeSource + +description: >- + Allows importing any datasets from Hugging Face + ([https://huggingface.co/datasets](https://huggingface.co/datasets)) + +check: + type: CheckStream + stream_names: + - rows + +definitions: + streams: + rows: + type: DeclarativeStream + name: rows + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /rows?dataset={{ config["dataset_name"] }}&config={{ + stream_partition.key.split("::")[1] }}&split={{ + stream_partition.key.split("::")[2] }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - rows + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: length + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: key + partition_field: key + stream: + $ref: "#/definitions/streams/splits" + transformations: + - type: AddFields + fields: + - path: + - config + value: "{{ stream_partition.key }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/rows" + splits: + type: DeclarativeStream + name: splits + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /splits?dataset={{ config["dataset_name"] }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - splits + record_filter: + type: RecordFilter + condition: >- + {{ (not config["dataset_splits"] or record.split in + config["dataset_splits"]) and (not config["dataset_subsets"] or + record.config in config["dataset_subsets"]) }} + transformations: + - type: AddFields + fields: + - path: + - key + value: >- + {{ "::".join([record["dataset"], record["config"], + record["split"]]) }} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/splits" + base_requester: + type: HttpRequester + url_base: https://datasets-server.huggingface.co + +streams: + - $ref: "#/definitions/streams/rows" + - $ref: "#/definitions/streams/splits" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - dataset_name + properties: + dataset_name: + type: string + order: 0 + title: Dataset Name + dataset_subsets: + type: array + description: >- + Dataset Subsets to import. Will import all of them if nothing is + provided (see + https://huggingface.co/docs/dataset-viewer/en/configs_and_splits for + more details) + order: 1 + title: Dataset Subsets + dataset_splits: + type: array + description: >- + Splits to import. Will import all of them if nothing is provided (see + https://huggingface.co/docs/dataset-viewer/en/configs_and_splits for + more details) + order: 2 + title: Dataset Splits + additionalProperties: true + +metadata: + autoImportSchema: + rows: true + splits: true + testedStreams: + rows: + streamHash: 7dbbacc410a5b2e190f31a4699420ede8232f1ac + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + splits: + streamHash: 6f7caee478d97fb11794d8e47e1f4a276ebd934a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + rows: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + config: + type: + - string + - "null" + row: + type: + - object + - "null" + properties: + messages: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + content: + type: + - string + - "null" + role: + type: + - string + - "null" + tokens: + type: + - number + - "null" + row_idx: + type: + - number + - "null" + truncated_cells: + type: + - array + - "null" + splits: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + config: + type: + - string + - "null" + dataset: + type: + - string + - "null" + key: + type: + - string + - "null" + split: + type: + - string + - "null" diff --git a/airbyte-integrations/connectors/source-hugging-face-datasets/metadata.yaml b/airbyte-integrations/connectors/source-hugging-face-datasets/metadata.yaml new file mode 100644 index 000000000000..378a96d54790 --- /dev/null +++ b/airbyte-integrations/connectors/source-hugging-face-datasets/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "datasets-server.huggingface.co" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-hugging-face-datasets + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 38438040-03d9-406d-b10b-af83beadd3ef + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-hugging-face-datasets + githubIssueLabel: source-hugging-face-datasets + icon: icon.svg + license: MIT + name: Hugging Face - Datasets + releaseDate: 2024-11-28 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/hugging-face-datasets + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-humanitix/README.md b/airbyte-integrations/connectors/source-humanitix/README.md new file mode 100644 index 000000000000..10b2e1ad8eaf --- /dev/null +++ b/airbyte-integrations/connectors/source-humanitix/README.md @@ -0,0 +1,35 @@ +# Humanitix +This directory contains the manifest-only connector for `source-humanitix`. + +Humanitix is a ticketing platform. +Using this connector we can extract data from streams such as events , orders and tickets. +Docs : https://humanitix.stoplight.io/docs/humanitix-public-api/e508a657c1467-humanitix-public-api + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-humanitix:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-humanitix build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-humanitix test +``` + diff --git a/airbyte-integrations/connectors/source-humanitix/acceptance-test-config.yml b/airbyte-integrations/connectors/source-humanitix/acceptance-test-config.yml new file mode 100644 index 000000000000..f7c4099b2c70 --- /dev/null +++ b/airbyte-integrations/connectors/source-humanitix/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-humanitix:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-humanitix/icon.svg b/airbyte-integrations/connectors/source-humanitix/icon.svg new file mode 100644 index 000000000000..e05ba892b904 --- /dev/null +++ b/airbyte-integrations/connectors/source-humanitix/icon.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-humanitix/manifest.yaml b/airbyte-integrations/connectors/source-humanitix/manifest.yaml new file mode 100644 index 000000000000..e205383fbfde --- /dev/null +++ b/airbyte-integrations/connectors/source-humanitix/manifest.yaml @@ -0,0 +1,2669 @@ +version: 6.1.0 + +type: DeclarativeSource + +description: >- + Humanitix is a ticketing platform. + + Using this connector we can extract data from streams such as events , orders + and tickets. + + Docs : + https://humanitix.stoplight.io/docs/humanitix-public-api/e508a657c1467-humanitix-public-api + +check: + type: CheckStream + stream_names: + - events + +definitions: + streams: + events: + type: DeclarativeStream + name: events + primary_key: + - _id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: events + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - events + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/events" + orders: + type: DeclarativeStream + name: orders + primary_key: + - _id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: events/{{ stream_partition.eventid }}/orders + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - orders + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: _id + partition_field: eventid + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/orders" + tickets: + type: DeclarativeStream + name: tickets + primary_key: + - _id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: events/{{ stream_partition.eventid }}/tickets + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - tickets + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: _id + partition_field: eventid + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tickets" + tags: + type: DeclarativeStream + name: tags + primary_key: + - _id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: tags + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - tags + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tags" + base_requester: + type: HttpRequester + url_base: https://api.humanitix.com/v1/ + authenticator: + type: ApiKeyAuthenticator + inject_into: + type: RequestOption + inject_into: header + field_name: x-api-key + api_token: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/events" + - $ref: "#/definitions/streams/orders" + - $ref: "#/definitions/streams/tickets" + - $ref: "#/definitions/streams/tags" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + title: API Key + airbyte_secret: true + order: 0 + additionalProperties: true + +metadata: + autoImportSchema: + events: true + orders: true + tickets: true + tags: true + testedStreams: + events: + streamHash: a1d5b4c687510acfc1951af15a76553d7d188a5d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + orders: + streamHash: 77338023ccd0f14cfa5b79b82f83d9e272fbd30a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tickets: + streamHash: ed2c44661beeb21eb611f3baa30539179029490a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tags: + streamHash: c33cfcd3e74132e21ca24b7b8517cde9a1a207ed + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + _id: + type: string + additionalQuestions: + type: + - array + - "null" + affiliateCodes: + type: + - array + - "null" + artists: + type: + - array + - "null" + bannerImage: + type: + - object + - "null" + properties: + url: + type: + - string + - "null" + classification: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + category: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + currency: + type: + - string + - "null" + dates: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _id: + type: + - string + - "null" + deleted: + type: + - boolean + - "null" + disabled: + type: + - boolean + - "null" + endDate: + type: + - string + - "null" + startDate: + type: + - string + - "null" + endDate: + type: + - string + - "null" + eventLocation: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + address: + type: + - string + - "null" + addressComponents: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _id: + type: + - string + - "null" + long_name: + type: + - string + - "null" + short_name: + type: + - string + - "null" + types: + type: + - array + - "null" + items: + type: + - string + - "null" + latLng: + type: + - array + - "null" + items: + type: + - number + - "null" + mapUrl: + type: + - string + - "null" + placeId: + type: + - string + - "null" + venueName: + type: + - string + - "null" + keywords: + type: + - array + - "null" + location: + type: + - string + - "null" + markedAsSoldOut: + type: + - boolean + - "null" + name: + type: + - string + - "null" + organiserId: + type: + - string + - "null" + packagedTickets: + type: + - array + - "null" + paymentOptions: + type: + - object + - "null" + properties: + refundSettings: + type: + - object + - "null" + properties: + refundPolicy: + type: + - string + - "null" + pricing: + type: + - object + - "null" + properties: + maximumPrice: + type: + - number + - "null" + minimumPrice: + type: + - number + - "null" + public: + type: + - boolean + - "null" + published: + type: + - boolean + - "null" + slug: + type: + - string + - "null" + startDate: + type: + - string + - "null" + suspendSales: + type: + - boolean + - "null" + tagIds: + type: + - array + - "null" + ticketTypes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _id: + type: + - string + - "null" + deleted: + type: + - boolean + - "null" + disabled: + type: + - boolean + - "null" + isDonation: + type: + - boolean + - "null" + name: + type: + - string + - "null" + price: + type: + - number + - "null" + quantity: + type: + - number + - "null" + timezone: + type: + - string + - "null" + totalCapacity: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + userId: + type: + - string + - "null" + required: + - _id + orders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _id: + type: string + additionalFields: + type: + - array + - "null" + businessPurpose: + type: + - boolean + - "null" + clientDonation: + type: + - number + - "null" + completedAt: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + currency: + type: + - string + - "null" + email: + type: + - string + - "null" + eventDateId: + type: + - string + - "null" + eventId: + type: + - string + - "null" + financialStatus: + type: + - string + - "null" + firstName: + type: + - string + - "null" + incompleteAt: + type: + - string + - "null" + lastName: + type: + - string + - "null" + location: + type: + - string + - "null" + manualOrder: + type: + - boolean + - "null" + mobile: + type: + - string + - "null" + notes: + type: + - string + - "null" + orderName: + type: + - string + - "null" + organiserMailListOptIn: + type: + - boolean + - "null" + paymentGateway: + type: + - string + - "null" + paymentType: + type: + - string + - "null" + purchaseTotals: + type: + - object + - "null" + properties: + absorbedFee: + type: + - number + - "null" + amexFee: + type: + - number + - "null" + bookingFee: + type: + - number + - "null" + bookingTaxes: + type: + - number + - "null" + clientDonation: + type: + - number + - "null" + credit: + type: + - number + - "null" + dgrDonation: + type: + - number + - "null" + discounts: + type: + - number + - "null" + donation: + type: + - number + - "null" + feesIncluded: + type: + - boolean + - "null" + giftCardCredit: + type: + - number + - "null" + grossSales: + type: + - number + - "null" + humanitixFee: + type: + - number + - "null" + netClientDonation: + type: + - number + - "null" + netSales: + type: + - number + - "null" + passedOnFee: + type: + - number + - "null" + passedOnTaxes: + type: + - number + - "null" + rebates: + type: + - number + - "null" + refunds: + type: + - number + - "null" + subtotal: + type: + - number + - "null" + taxes: + type: + - number + - "null" + total: + type: + - number + - "null" + totalTaxes: + type: + - number + - "null" + zipFee: + type: + - number + - "null" + salesChannel: + type: + - string + - "null" + status: + type: + - string + - "null" + tipFees: + type: + - boolean + - "null" + totals: + type: + - object + - "null" + properties: + absorbedFee: + type: + - number + - "null" + amexFee: + type: + - number + - "null" + bookingFee: + type: + - number + - "null" + bookingTaxes: + type: + - number + - "null" + clientDonation: + type: + - number + - "null" + credit: + type: + - number + - "null" + dgrDonation: + type: + - number + - "null" + discounts: + type: + - number + - "null" + donation: + type: + - number + - "null" + feesIncluded: + type: + - boolean + - "null" + giftCardCredit: + type: + - number + - "null" + grossSales: + type: + - number + - "null" + humanitixFee: + type: + - number + - "null" + netClientDonation: + type: + - number + - "null" + netSales: + type: + - number + - "null" + passedOnFee: + type: + - number + - "null" + passedOnTaxes: + type: + - number + - "null" + rebates: + type: + - number + - "null" + refunds: + type: + - number + - "null" + subtotal: + type: + - number + - "null" + taxes: + type: + - number + - "null" + total: + type: + - number + - "null" + totalTaxes: + type: + - number + - "null" + zipFee: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + required: + - _id + tickets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _id: + type: string + absorbedFee: + type: + - number + - "null" + additionalFields: + type: + - array + - "null" + checkInHistory: + type: + - array + - "null" + createdAt: + type: + - string + - "null" + currency: + type: + - string + - "null" + dgrDonation: + type: + - number + - "null" + discount: + type: + - number + - "null" + eventDateId: + type: + - string + - "null" + eventId: + type: + - string + - "null" + fee: + type: + - number + - "null" + firstName: + type: + - string + - "null" + isDonation: + type: + - boolean + - "null" + lastName: + type: + - string + - "null" + location: + type: + - string + - "null" + netPrice: + type: + - number + - "null" + number: + type: + - number + - "null" + orderId: + type: + - string + - "null" + orderName: + type: + - string + - "null" + passedOnFee: + type: + - number + - "null" + price: + type: + - number + - "null" + qrCodeData: + type: + - object + - "null" + properties: + _id: + type: + - string + - "null" + eventId: + type: + - string + - "null" + salesChannel: + type: + - string + - "null" + status: + type: + - string + - "null" + taxes: + type: + - number + - "null" + ticketTypeId: + type: + - string + - "null" + ticketTypeName: + type: + - string + - "null" + total: + type: + - number + - "null" + totalsV2: + type: + - object + - "null" + properties: + credit: + type: + - object + - "null" + properties: + giftCard: + type: + - number + - "null" + store: + type: + - number + - "null" + voucher: + type: + - number + - "null" + customSalesTax: + type: + - object + - "null" + properties: + absorb: + type: + - number + - "null" + passOn: + type: + - number + - "null" + total: + type: + - number + - "null" + dgrDonation: + type: + - number + - "null" + discount: + type: + - number + - "null" + earnings: + type: + - number + - "null" + fees: + type: + - object + - "null" + properties: + additionalFee: + type: + - object + - "null" + properties: + afterpayFee: + type: + - object + - "null" + properties: + fixedFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + percentFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + totalFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + amexFee: + type: + - object + - "null" + properties: + fixedFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + percentFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + totalFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + zipFee: + type: + - object + - "null" + properties: + fixedFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + percentFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + totalFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + humanitixFee: + type: + - object + - "null" + properties: + fixedFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + percentFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + totalFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + paymentFee: + type: + - object + - "null" + properties: + fixedFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + percentFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + totalFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + rebate: + type: + - object + - "null" + properties: + fixedFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + percentFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + totalFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + totalFeeRevenue: + type: + - object + - "null" + properties: + fixedFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + percentFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + totalFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + totalFees: + type: + - object + - "null" + properties: + fixedFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + percentFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + totalFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + uncappedHumanitixFee: + type: + - object + - "null" + properties: + fixedFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + percentFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + totalFee: + type: + - object + - "null" + properties: + absorb: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + passOn: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + grossSales: + type: + - number + - "null" + itemTaxes: + type: + - number + - "null" + netSales: + type: + - number + - "null" + payout: + type: + - number + - "null" + referral: + type: + - number + - "null" + refunds: + type: + - number + - "null" + subTotal: + type: + - object + - "null" + properties: + afterTax: + type: + - number + - "null" + beforeTax: + type: + - number + - "null" + tax: + type: + - number + - "null" + total: + type: + - number + - "null" + totalOrganiserTaxes: + type: + - number + - "null" + totalTaxes: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + required: + - _id + tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _id: + type: string + createdAt: + type: + - string + - "null" + location: + type: + - string + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + userId: + type: + - string + - "null" + required: + - _id diff --git a/airbyte-integrations/connectors/source-humanitix/metadata.yaml b/airbyte-integrations/connectors/source-humanitix/metadata.yaml new file mode 100644 index 000000000000..2054307fde83 --- /dev/null +++ b/airbyte-integrations/connectors/source-humanitix/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.humanitix.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-humanitix + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 89f37cda-8b7d-4179-ad8a-91cf5045b5fd + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-humanitix + githubIssueLabel: source-humanitix + icon: icon.svg + license: MIT + name: Humanitix + releaseDate: 2024-10-31 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/humanitix + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-illumina-basespace/metadata.yaml b/airbyte-integrations/connectors/source-illumina-basespace/metadata.yaml index d0547b2a64c7..e58d52e7fe73 100644 --- a/airbyte-integrations/connectors/source-illumina-basespace/metadata.yaml +++ b/airbyte-integrations/connectors/source-illumina-basespace/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-illumina-basespace connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 62e9c4f2-a768-48f7-a8bf-d54bf1d96425 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-illumina-basespace githubIssueLabel: source-illumina-basespace icon: icon.svg diff --git a/airbyte-integrations/connectors/source-incident-io/metadata.yaml b/airbyte-integrations/connectors/source-incident-io/metadata.yaml index 9c9ecafa8452..cfc616d10067 100644 --- a/airbyte-integrations/connectors/source-incident-io/metadata.yaml +++ b/airbyte-integrations/connectors/source-incident-io/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-incident-io connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.10.2@sha256:81db4f78a92d199f33c38c17f5b63fc87c56739f14dc10276ddec86c7b707b7a + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 7926da90-399e-4f9f-9833-52d8dc3fcb29 - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-incident-io githubIssueLabel: source-incident-io icon: icon.svg diff --git a/airbyte-integrations/connectors/source-inflowinventory/README.md b/airbyte-integrations/connectors/source-inflowinventory/README.md new file mode 100644 index 000000000000..b4a917e52765 --- /dev/null +++ b/airbyte-integrations/connectors/source-inflowinventory/README.md @@ -0,0 +1,35 @@ +# Inflowinventory +This directory contains the manifest-only connector for `source-inflowinventory`. + +As the name suggests , Inflowinventory is an inventory management software. +Using this connector we can extract data from various streams such as customers , productts and sales orders. +Docs : https://cloudapi.inflowinventory.com/docs/index.html#section/Overview + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-inflowinventory:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-inflowinventory build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-inflowinventory test +``` + diff --git a/airbyte-integrations/connectors/source-inflowinventory/acceptance-test-config.yml b/airbyte-integrations/connectors/source-inflowinventory/acceptance-test-config.yml new file mode 100644 index 000000000000..f6f07283595a --- /dev/null +++ b/airbyte-integrations/connectors/source-inflowinventory/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-inflowinventory:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-inflowinventory/icon.svg b/airbyte-integrations/connectors/source-inflowinventory/icon.svg new file mode 100644 index 000000000000..bf315d9b5dce --- /dev/null +++ b/airbyte-integrations/connectors/source-inflowinventory/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-inflowinventory/manifest.yaml b/airbyte-integrations/connectors/source-inflowinventory/manifest.yaml new file mode 100644 index 000000000000..4d43ad1a52e2 --- /dev/null +++ b/airbyte-integrations/connectors/source-inflowinventory/manifest.yaml @@ -0,0 +1,2933 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + As the name suggests , Inflowinventory is an inventory management software. + + Using this connector we can extract data from various streams such as + customers , productts and sales orders. + + Docs https://cloudapi.inflowinventory.com/docs/index.html#section/Overview + +check: + type: CheckStream + stream_names: + - adjustment reasons + +definitions: + streams: + adjustment reasons: + type: DeclarativeStream + name: adjustment reasons + primary_key: + - adjustmentReasonId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/adjustment-reasons" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/adjustment reasons" + categories: + type: DeclarativeStream + name: categories + primary_key: + - categoryId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/categories" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/categories" + currencies: + type: DeclarativeStream + name: currencies + primary_key: + - currencyId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/currencies" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/currencies" + custom_fields: + type: DeclarativeStream + name: custom_fields + primary_key: + - customFieldsId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/custom-fields" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/custom_fields" + locations: + type: DeclarativeStream + name: locations + primary_key: + - locationId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/locations" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/locations" + operation types: + type: DeclarativeStream + name: operation types + primary_key: + - operationTypeId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/operation-types" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/operation types" + payment terms: + type: DeclarativeStream + name: payment terms + primary_key: + - paymentTermsId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/payment-terms" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/payment terms" + pricing schemes: + type: DeclarativeStream + name: pricing schemes + primary_key: + - pricingSchemeId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/pricing-schemes" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/pricing schemes" + products: + type: DeclarativeStream + name: products + primary_key: + - productId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/products" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + product cost adjustments: + type: DeclarativeStream + name: product cost adjustments + primary_key: + - productCostAdjustmentId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/product-cost-adjustments" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/product cost adjustments" + purchase orders: + type: DeclarativeStream + name: purchase orders + primary_key: + - purchaseOrderId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/purchase-orders" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/purchase orders" + sales orders: + type: DeclarativeStream + name: sales orders + primary_key: + - salesOrderId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/sales-orders" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sales orders" + stock adjustments: + type: DeclarativeStream + name: stock adjustments + primary_key: + - stockAdjustmentId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/stock-adjustments" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stock adjustments" + stock counts: + type: DeclarativeStream + name: stock counts + primary_key: + - stockCountId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/stock-counts" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stock counts" + stock transfers: + type: DeclarativeStream + name: stock transfers + primary_key: + - stockTransferId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/stock-transfers" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stock transfers" + tax codes: + type: DeclarativeStream + name: tax codes + primary_key: + - taxCodeId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/tax-codes" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tax codes" + taxing schemes: + type: DeclarativeStream + name: taxing schemes + primary_key: + - taxingSchemeId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/taxing-schemes" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/taxing schemes" + team members: + type: DeclarativeStream + name: team members + primary_key: + - teamMemberId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/team-members" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/team members" + vendors: + type: DeclarativeStream + name: vendors + primary_key: + - vendorId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/vendors" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/vendors" + customers: + type: DeclarativeStream + name: customers + primary_key: + - customerId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: "{{ config['companyid'] }}/customers" + http_method: GET + request_headers: + Accept: application/json;version=2024-03-12 + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers" + base_requester: + type: HttpRequester + url_base: https://cloudapi.inflowinventory.com/ + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: Authorization + inject_into: header + +streams: + - $ref: "#/definitions/streams/adjustment reasons" + - $ref: "#/definitions/streams/categories" + - $ref: "#/definitions/streams/currencies" + - $ref: "#/definitions/streams/custom_fields" + - $ref: "#/definitions/streams/locations" + - $ref: "#/definitions/streams/operation types" + - $ref: "#/definitions/streams/payment terms" + - $ref: "#/definitions/streams/pricing schemes" + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/product cost adjustments" + - $ref: "#/definitions/streams/purchase orders" + - $ref: "#/definitions/streams/sales orders" + - $ref: "#/definitions/streams/stock adjustments" + - $ref: "#/definitions/streams/stock counts" + - $ref: "#/definitions/streams/stock transfers" + - $ref: "#/definitions/streams/tax codes" + - $ref: "#/definitions/streams/taxing schemes" + - $ref: "#/definitions/streams/team members" + - $ref: "#/definitions/streams/vendors" + - $ref: "#/definitions/streams/customers" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - companyid + properties: + api_key: + type: string + order: 0 + title: API Key + airbyte_secret: true + companyid: + type: string + order: 1 + title: CompanyID + additionalProperties: true + +metadata: + autoImportSchema: + adjustment reasons: true + categories: true + currencies: true + custom_fields: true + locations: true + operation types: true + payment terms: true + pricing schemes: true + products: true + product cost adjustments: true + purchase orders: true + sales orders: true + stock adjustments: true + stock counts: true + stock transfers: true + tax codes: true + taxing schemes: true + team members: true + vendors: true + customers: true + testedStreams: + adjustment reasons: + streamHash: 5f42a4f25f44127491b975e740d3799621b51613 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + categories: + streamHash: 680c3b978da6de4e8be556ed106a68f8fa5e36a7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + currencies: + hasRecords: true + streamHash: ca7350df8fafa5ea9018a489bbeca3c64358e892 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + custom_fields: + streamHash: 5fbbc2de197a866111a95ae4a737ddd6faaef161 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + locations: + hasRecords: true + streamHash: 8fe429a7058c796f8f2451df0339eae0a05d0188 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + operation types: + hasRecords: true + streamHash: 4cb9a7422c132579866c0ce91f6d74d7b0c9721d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + payment terms: + hasRecords: true + streamHash: 037f57800bd3634990b8efbb48d0806206794412 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + pricing schemes: + hasRecords: true + streamHash: 36a0e041e86b0a16da122df09f230193030cca52 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + products: + hasRecords: true + streamHash: b422665de15c476e9731b41751da187489741ebb + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + product cost adjustments: + hasRecords: true + streamHash: aa641487eaf0626fc0e0098a5dc0947248bf2ef6 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + purchase orders: + hasRecords: true + streamHash: a9977bcf60635ca1cdf5d6dbdf52def0722e9e09 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + sales orders: + hasRecords: true + streamHash: f0978a9901201e8bb4cf8f880f408789117db250 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + stock adjustments: + hasRecords: true + streamHash: 26ac5620b509f9779b8ae7e5a9029d3429000e4d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + stock counts: + hasRecords: true + streamHash: 00b208c84b542c34734e5f59590a3a59f1d820a2 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + stock transfers: + hasRecords: true + streamHash: f2f09842c9f658d52269f5b4a44144be2cfb9408 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + tax codes: + hasRecords: true + streamHash: e8303c421ea3755fff34ec5164698b2c1b2e635d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + taxing schemes: + hasRecords: true + streamHash: c7e20e7d8b9ac24f3068d76844155f2b5896ed8c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + team members: + hasRecords: true + streamHash: 54a7197b624878df2c39ab55b97e59c69bf81954 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + vendors: + hasRecords: true + streamHash: d140e7743b16868e30022f782322f692ded89265 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + customers: + streamHash: c141bbd7b1361c0461e35d62cf84f9eccb3694f3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + adjustment reasons: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + adjustmentReasonId: + type: string + isActive: + type: + - boolean + - "null" + isInternal: + type: + - boolean + - "null" + name: + type: + - string + - "null" + required: + - adjustmentReasonId + categories: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + categoryId: + type: string + isDefault: + type: + - boolean + - "null" + name: + type: + - string + - "null" + parentCategoryId: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + required: + - categoryId + currencies: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + currencyId: + type: string + decimalPlaces: + type: + - number + - "null" + decimalSeparator: + type: + - string + - "null" + isSymbolFirst: + type: + - boolean + - "null" + isoCode: + type: + - string + - "null" + name: + type: + - string + - "null" + negativeType: + type: + - string + - "null" + symbol: + type: + - string + - "null" + thousandsSeparator: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + required: + - currencyId + custom_fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + customFieldsId: + type: string + customerCustomFieldLabels: + type: + - object + - "null" + properties: + custom1: + type: + - string + - "null" + custom10: + type: + - string + - "null" + custom2: + type: + - string + - "null" + custom3: + type: + - string + - "null" + custom4: + type: + - string + - "null" + custom5: + type: + - string + - "null" + custom6: + type: + - string + - "null" + custom7: + type: + - string + - "null" + custom8: + type: + - string + - "null" + custom9: + type: + - string + - "null" + productCustomFieldLabels: + type: + - object + - "null" + properties: + custom1: + type: + - string + - "null" + custom10: + type: + - string + - "null" + custom2: + type: + - string + - "null" + custom3: + type: + - string + - "null" + custom4: + type: + - string + - "null" + custom5: + type: + - string + - "null" + custom6: + type: + - string + - "null" + custom7: + type: + - string + - "null" + custom8: + type: + - string + - "null" + custom9: + type: + - string + - "null" + purchaseOrderCustomFieldLabels: + type: + - object + - "null" + properties: + custom1: + type: + - string + - "null" + custom10: + type: + - string + - "null" + custom2: + type: + - string + - "null" + custom3: + type: + - string + - "null" + custom4: + type: + - string + - "null" + custom5: + type: + - string + - "null" + custom6: + type: + - string + - "null" + custom7: + type: + - string + - "null" + custom8: + type: + - string + - "null" + custom9: + type: + - string + - "null" + purchaseOrderCustomFieldPrintLabels: + type: + - object + - "null" + properties: + custom1Print: + type: + - boolean + - "null" + custom2Print: + type: + - boolean + - "null" + custom3Print: + type: + - boolean + - "null" + salesOrderCustomFieldLabels: + type: + - object + - "null" + properties: + custom1: + type: + - string + - "null" + custom10: + type: + - string + - "null" + custom2: + type: + - string + - "null" + custom3: + type: + - string + - "null" + custom4: + type: + - string + - "null" + custom5: + type: + - string + - "null" + custom6: + type: + - string + - "null" + custom7: + type: + - string + - "null" + custom8: + type: + - string + - "null" + custom9: + type: + - string + - "null" + salesOrderCustomFieldPrintLabels: + type: + - object + - "null" + properties: + custom1Print: + type: + - boolean + - "null" + custom2Print: + type: + - boolean + - "null" + custom3Print: + type: + - boolean + - "null" + stockAdjustmentCustomFieldLabels: + type: + - object + - "null" + properties: + custom1: + type: + - string + - "null" + custom10: + type: + - string + - "null" + custom2: + type: + - string + - "null" + custom3: + type: + - string + - "null" + custom4: + type: + - string + - "null" + custom5: + type: + - string + - "null" + custom6: + type: + - string + - "null" + custom7: + type: + - string + - "null" + custom8: + type: + - string + - "null" + custom9: + type: + - string + - "null" + stockAdjustmentCustomFieldPrintLabels: + type: + - object + - "null" + properties: + custom1Print: + type: + - boolean + - "null" + custom2Print: + type: + - boolean + - "null" + custom3Print: + type: + - boolean + - "null" + stockTransferCustomFieldLabels: + type: + - object + - "null" + properties: + custom1: + type: + - string + - "null" + custom10: + type: + - string + - "null" + custom2: + type: + - string + - "null" + custom3: + type: + - string + - "null" + custom4: + type: + - string + - "null" + custom5: + type: + - string + - "null" + custom6: + type: + - string + - "null" + custom7: + type: + - string + - "null" + custom8: + type: + - string + - "null" + custom9: + type: + - string + - "null" + stockTransferCustomFieldPrintLabels: + type: + - object + - "null" + properties: + custom1Print: + type: + - boolean + - "null" + custom2Print: + type: + - boolean + - "null" + custom3Print: + type: + - boolean + - "null" + vendorCustomFieldLabels: + type: + - object + - "null" + properties: + custom1: + type: + - string + - "null" + custom10: + type: + - string + - "null" + custom2: + type: + - string + - "null" + custom3: + type: + - string + - "null" + custom4: + type: + - string + - "null" + custom5: + type: + - string + - "null" + custom6: + type: + - string + - "null" + custom7: + type: + - string + - "null" + custom8: + type: + - string + - "null" + custom9: + type: + - string + - "null" + workOrderCustomFieldLabels: + type: + - object + - "null" + properties: + custom1: + type: + - string + - "null" + custom10: + type: + - string + - "null" + custom2: + type: + - string + - "null" + custom3: + type: + - string + - "null" + custom4: + type: + - string + - "null" + custom5: + type: + - string + - "null" + custom6: + type: + - string + - "null" + custom7: + type: + - string + - "null" + custom8: + type: + - string + - "null" + custom9: + type: + - string + - "null" + workOrderCustomFieldPrintLabels: + type: + - object + - "null" + properties: + custom1Print: + type: + - boolean + - "null" + custom2Print: + type: + - boolean + - "null" + custom3Print: + type: + - boolean + - "null" + required: + - customFieldsId + locations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address: + type: + - object + - "null" + properties: + address1: + type: + - string + - "null" + address2: + type: + - string + - "null" + addressType: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + remarks: + type: + - string + - "null" + state: + type: + - string + - "null" + isActive: + type: + - boolean + - "null" + isDefault: + type: + - boolean + - "null" + locationId: + type: string + name: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + required: + - locationId + operation types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + isActive: + type: + - boolean + - "null" + isDefault: + type: + - boolean + - "null" + name: + type: + - string + - "null" + operationTypeId: + type: string + timestamp: + type: + - string + - "null" + required: + - operationTypeId + payment terms: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + daysDue: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + paymentTermsId: + type: string + timestamp: + type: + - string + - "null" + required: + - paymentTermsId + pricing schemes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + currencyId: + type: + - string + - "null" + isActive: + type: + - boolean + - "null" + isDefault: + type: + - boolean + - "null" + isTaxInclusive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + pricingSchemeId: + type: string + timestamp: + type: + - string + - "null" + required: + - pricingSchemeId + products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + autoAssemble: + type: + - boolean + - "null" + categoryId: + type: + - string + - "null" + customFields: + type: + - object + - "null" + properties: + custom1: + type: + - string + - "null" + custom10: + type: + - string + - "null" + custom2: + type: + - string + - "null" + custom3: + type: + - string + - "null" + custom4: + type: + - string + - "null" + custom5: + type: + - string + - "null" + custom6: + type: + - string + - "null" + custom7: + type: + - string + - "null" + custom8: + type: + - string + - "null" + custom9: + type: + - string + - "null" + height: + type: + - string + - "null" + hsTariffNumber: + type: + - string + - "null" + includeQuantityBuildable: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isManufacturable: + type: + - boolean + - "null" + itemType: + type: + - string + - "null" + lastModifiedById: + type: + - string + - "null" + lastModifiedDateTime: + type: + - string + - "null" + lastVendorId: + type: + - string + - "null" + length: + type: + - string + - "null" + name: + type: + - string + - "null" + originCountry: + type: + - string + - "null" + productId: + type: string + purchasingUom: + type: + - object + - "null" + properties: + conversionRatio: + type: + - object + - "null" + properties: + standardQuantity: + type: + - string + - "null" + uomQuantity: + type: + - string + - "null" + name: + type: + - string + - "null" + remarks: + type: + - string + - "null" + salesUom: + type: + - object + - "null" + properties: + conversionRatio: + type: + - object + - "null" + properties: + standardQuantity: + type: + - string + - "null" + uomQuantity: + type: + - string + - "null" + name: + type: + - string + - "null" + sku: + type: + - string + - "null" + standardUomName: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + trackSerials: + type: + - boolean + - "null" + weight: + type: + - string + - "null" + width: + type: + - string + - "null" + required: + - productId + product cost adjustments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + dateTime: + type: + - string + - "null" + lastModifiedById: + type: + - string + - "null" + productCostAdjustmentId: + type: string + productId: + type: + - string + - "null" + serial: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + unitCost: + type: + - string + - "null" + required: + - productCostAdjustmentId + purchase orders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + amountPaid: + type: + - string + - "null" + balance: + type: + - string + - "null" + calculateTax2OnTax1: + type: + - boolean + - "null" + carrier: + type: + - string + - "null" + contactName: + type: + - string + - "null" + currencyId: + type: + - string + - "null" + customFields: + type: + - object + - "null" + properties: + custom1: + type: + - string + - "null" + custom10: + type: + - string + - "null" + custom2: + type: + - string + - "null" + custom3: + type: + - string + - "null" + custom4: + type: + - string + - "null" + custom5: + type: + - string + - "null" + custom6: + type: + - string + - "null" + custom7: + type: + - string + - "null" + custom8: + type: + - string + - "null" + custom9: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + email: + type: + - string + - "null" + exchangeRate: + type: + - string + - "null" + exchangeRateAutoPulled: + type: + - string + - "null" + freight: + type: + - string + - "null" + inventoryStatus: + type: + - string + - "null" + isCancelled: + type: + - boolean + - "null" + isCompleted: + type: + - boolean + - "null" + isQuote: + type: + - boolean + - "null" + isTaxInclusive: + type: + - boolean + - "null" + lastModifiedById: + type: + - string + - "null" + locationId: + type: + - string + - "null" + nonVendorCosts: + type: + - object + - "null" + properties: + isPercent: + type: + - boolean + - "null" + value: + type: + - string + - "null" + orderDate: + type: + - string + - "null" + orderNumber: + type: + - string + - "null" + orderRemarks: + type: + - string + - "null" + paidDate: + type: + - string + - "null" + paymentStatus: + type: + - string + - "null" + paymentTermsId: + type: + - string + - "null" + phone: + type: + - string + - "null" + purchaseOrderId: + type: string + receiveRemarks: + type: + - string + - "null" + requestShipDate: + type: + - string + - "null" + returnExtra: + type: + - string + - "null" + returnFee: + type: + - string + - "null" + returnRemarks: + type: + - string + - "null" + shipToAddress: + type: + - object + - "null" + properties: + address1: + type: + - string + - "null" + address2: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + remarks: + type: + - string + - "null" + state: + type: + - string + - "null" + shipToCompanyName: + type: + - string + - "null" + showShipping: + type: + - boolean + - "null" + subTotal: + type: + - string + - "null" + tax1: + type: + - string + - "null" + tax1Name: + type: + - string + - "null" + tax1OnShipping: + type: + - boolean + - "null" + tax1Rate: + type: + - string + - "null" + tax2: + type: + - string + - "null" + tax2Name: + type: + - string + - "null" + tax2OnShipping: + type: + - boolean + - "null" + tax2Rate: + type: + - string + - "null" + taxingSchemeId: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + total: + type: + - string + - "null" + unstockRemarks: + type: + - string + - "null" + vendorAddress: + type: + - object + - "null" + properties: + address1: + type: + - string + - "null" + address2: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + remarks: + type: + - string + - "null" + state: + type: + - string + - "null" + vendorId: + type: + - string + - "null" + vendorOrderNumber: + type: + - string + - "null" + required: + - purchaseOrderId + sales orders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + amountPaid: + type: + - string + - "null" + balance: + type: + - string + - "null" + billingAddress: + type: + - object + - "null" + properties: + address1: + type: + - string + - "null" + address2: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + remarks: + type: + - string + - "null" + state: + type: + - string + - "null" + calculateTax2OnTax1: + type: + - boolean + - "null" + contactName: + type: + - string + - "null" + currencyId: + type: + - string + - "null" + customFields: + type: + - object + - "null" + properties: + custom1: + type: + - string + - "null" + custom10: + type: + - string + - "null" + custom2: + type: + - string + - "null" + custom3: + type: + - string + - "null" + custom4: + type: + - string + - "null" + custom5: + type: + - string + - "null" + custom6: + type: + - string + - "null" + custom7: + type: + - string + - "null" + custom8: + type: + - string + - "null" + custom9: + type: + - string + - "null" + customerId: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + email: + type: + - string + - "null" + exchangeRate: + type: + - string + - "null" + exchangeRateAutoPulled: + type: + - string + - "null" + externalId: + type: + - string + - "null" + inventoryStatus: + type: + - string + - "null" + invoicedDate: + type: + - string + - "null" + isCancelled: + type: + - boolean + - "null" + isCompleted: + type: + - boolean + - "null" + isInvoiced: + type: + - boolean + - "null" + isPrioritized: + type: + - boolean + - "null" + isQuote: + type: + - boolean + - "null" + isTaxInclusive: + type: + - boolean + - "null" + lastModifiedById: + type: + - string + - "null" + locationId: + type: + - string + - "null" + needsConfirmation: + type: + - boolean + - "null" + nonCustomerCost: + type: + - object + - "null" + properties: + isPercent: + type: + - boolean + - "null" + value: + type: + - string + - "null" + orderDate: + type: + - string + - "null" + orderFreight: + type: + - string + - "null" + orderNumber: + type: + - string + - "null" + orderRemarks: + type: + - string + - "null" + packRemarks: + type: + - string + - "null" + paidDate: + type: + - string + - "null" + paymentStatus: + type: + - string + - "null" + paymentTermsId: + type: + - string + - "null" + phone: + type: + - string + - "null" + pickRemarks: + type: + - string + - "null" + poNumber: + type: + - string + - "null" + pricingSchemeId: + type: + - string + - "null" + requestedShipDate: + type: + - string + - "null" + restockRemarks: + type: + - string + - "null" + returnFee: + type: + - string + - "null" + returnFreight: + type: + - string + - "null" + returnRemarks: + type: + - string + - "null" + salesOrderId: + type: string + salesRep: + type: + - string + - "null" + sameBillingAndShipping: + type: + - boolean + - "null" + shipRemarks: + type: + - string + - "null" + shipToCompanyName: + type: + - string + - "null" + shippedDate: + type: + - string + - "null" + shippingAddress: + type: + - object + - "null" + properties: + address1: + type: + - string + - "null" + address2: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + remarks: + type: + - string + - "null" + state: + type: + - string + - "null" + showShipping: + type: + - boolean + - "null" + source: + type: + - string + - "null" + subTotal: + type: + - string + - "null" + tax1: + type: + - string + - "null" + tax1Name: + type: + - string + - "null" + tax1OnShipping: + type: + - boolean + - "null" + tax1Rate: + type: + - string + - "null" + tax2: + type: + - string + - "null" + tax2Name: + type: + - string + - "null" + tax2OnShipping: + type: + - boolean + - "null" + tax2Rate: + type: + - string + - "null" + taxingSchemeId: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + total: + type: + - string + - "null" + required: + - salesOrderId + stock adjustments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + adjustmentNumber: + type: + - string + - "null" + adjustmentReasonId: + type: + - string + - "null" + customFields: + type: + - object + - "null" + properties: + custom1: + type: + - string + - "null" + custom10: + type: + - string + - "null" + custom2: + type: + - string + - "null" + custom3: + type: + - string + - "null" + custom4: + type: + - string + - "null" + custom5: + type: + - string + - "null" + custom6: + type: + - string + - "null" + custom7: + type: + - string + - "null" + custom8: + type: + - string + - "null" + custom9: + type: + - string + - "null" + date: + type: + - string + - "null" + isCancelled: + type: + - boolean + - "null" + lastModifiedById: + type: + - string + - "null" + locationId: + type: + - string + - "null" + remarks: + type: + - string + - "null" + stockAdjustmentId: + type: string + timestamp: + type: + - string + - "null" + required: + - stockAdjustmentId + stock counts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + completedDate: + type: + - string + - "null" + isCancelled: + type: + - boolean + - "null" + isCompleted: + type: + - boolean + - "null" + isPrepared: + type: + - boolean + - "null" + isReviewed: + type: + - boolean + - "null" + isStarted: + type: + - boolean + - "null" + lastModifiedById: + type: + - string + - "null" + locationId: + type: + - string + - "null" + remarks: + type: + - string + - "null" + startedDate: + type: + - string + - "null" + status: + type: + - string + - "null" + stockCountId: + type: string + stockCountNumber: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + required: + - stockCountId + stock transfers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + assignedToTeamMemberId: + type: + - string + - "null" + customFields: + type: + - object + - "null" + properties: + custom1: + type: + - string + - "null" + custom10: + type: + - string + - "null" + custom2: + type: + - string + - "null" + custom3: + type: + - string + - "null" + custom4: + type: + - string + - "null" + custom5: + type: + - string + - "null" + custom6: + type: + - string + - "null" + custom7: + type: + - string + - "null" + custom8: + type: + - string + - "null" + custom9: + type: + - string + - "null" + fromLocationId: + type: + - string + - "null" + isCancelled: + type: + - boolean + - "null" + lastModifiedById: + type: + - string + - "null" + receivedDate: + type: + - string + - "null" + remarks: + type: + - string + - "null" + sentDate: + type: + - string + - "null" + status: + type: + - string + - "null" + stockTransferId: + type: string + timestamp: + type: + - string + - "null" + toLocationId: + type: + - string + - "null" + transferDate: + type: + - string + - "null" + transferNumber: + type: + - string + - "null" + required: + - stockTransferId + tax codes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + tax1Rate: + type: + - string + - "null" + tax2Rate: + type: + - string + - "null" + taxCodeId: + type: string + taxingSchemeId: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + required: + - taxCodeId + taxing schemes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + calculateTax2OnTax1: + type: + - boolean + - "null" + defaultTaxCodeId: + type: + - string + - "null" + isActive: + type: + - boolean + - "null" + isDefault: + type: + - boolean + - "null" + name: + type: + - string + - "null" + tax1Name: + type: + - string + - "null" + tax1OnShipping: + type: + - boolean + - "null" + tax2Name: + type: + - string + - "null" + tax2OnShipping: + type: + - boolean + - "null" + taxingSchemeId: + type: string + timestamp: + type: + - string + - "null" + required: + - taxingSchemeId + team members: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accessAllLocations: + type: + - boolean + - "null" + accessLocationIds: + type: + - array + - "null" + accessRights: + type: + - array + - "null" + items: + type: + - string + - "null" + canBeSalesRep: + type: + - boolean + - "null" + email: + type: + - string + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + teamMemberId: + type: string + required: + - teamMemberId + vendors: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + contactName: + type: + - string + - "null" + currencyId: + type: + - string + - "null" + customFields: + type: + - object + - "null" + properties: + custom1: + type: + - string + - "null" + custom10: + type: + - string + - "null" + custom2: + type: + - string + - "null" + custom3: + type: + - string + - "null" + custom4: + type: + - string + - "null" + custom5: + type: + - string + - "null" + custom6: + type: + - string + - "null" + custom7: + type: + - string + - "null" + custom8: + type: + - string + - "null" + custom9: + type: + - string + - "null" + defaultAddressId: + type: + - string + - "null" + defaultCarrier: + type: + - string + - "null" + defaultPaymentMethod: + type: + - string + - "null" + defaultPaymentTermsId: + type: + - string + - "null" + discount: + type: + - string + - "null" + email: + type: + - string + - "null" + fax: + type: + - string + - "null" + isActive: + type: + - boolean + - "null" + isTaxInclusivePricing: + type: + - boolean + - "null" + lastModifiedById: + type: + - string + - "null" + leadTimeDays: + type: + - number + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + remarks: + type: + - string + - "null" + taxingSchemeId: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + vendorId: + type: string + website: + type: + - string + - "null" + required: + - vendorId + customers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + contactName: + type: + - string + - "null" + customFields: + type: + - object + - "null" + properties: + custom1: + type: + - string + - "null" + custom10: + type: + - string + - "null" + custom2: + type: + - string + - "null" + custom3: + type: + - string + - "null" + custom4: + type: + - string + - "null" + custom5: + type: + - string + - "null" + custom6: + type: + - string + - "null" + custom7: + type: + - string + - "null" + custom8: + type: + - string + - "null" + custom9: + type: + - string + - "null" + customerId: + type: string + defaultBillingAddressId: + type: + - string + - "null" + defaultCarrier: + type: + - string + - "null" + defaultLocationId: + type: + - string + - "null" + defaultPaymentMethod: + type: + - string + - "null" + defaultPaymentTermsId: + type: + - string + - "null" + defaultSalesRep: + type: + - string + - "null" + defaultShippingAddressId: + type: + - string + - "null" + discount: + type: + - string + - "null" + email: + type: + - string + - "null" + fax: + type: + - string + - "null" + isActive: + type: + - boolean + - "null" + lastModifiedById: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + pricingSchemeId: + type: + - string + - "null" + remarks: + type: + - string + - "null" + taxExemptNumber: + type: + - string + - "null" + taxingSchemeId: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + website: + type: + - string + - "null" + required: + - customerId diff --git a/airbyte-integrations/connectors/source-inflowinventory/metadata.yaml b/airbyte-integrations/connectors/source-inflowinventory/metadata.yaml new file mode 100644 index 000000000000..dad5d248804c --- /dev/null +++ b/airbyte-integrations/connectors/source-inflowinventory/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "cloudapi.inflowinventory.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-inflowinventory + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 139e24a8-6439-4606-8b1b-32bf6817b07d + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-inflowinventory + githubIssueLabel: source-inflowinventory + icon: icon.svg + license: MIT + name: Inflowinventory + releaseDate: 2024-10-29 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/inflowinventory + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-insightly/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-insightly/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-insightly/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-insightly/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-insightly/metadata.yaml b/airbyte-integrations/connectors/source-insightly/metadata.yaml index e82fda0789fa..85af9281be3e 100644 --- a/airbyte-integrations/connectors/source-insightly/metadata.yaml +++ b/airbyte-integrations/connectors/source-insightly/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - api.na1.insightly.com connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 38f84314-fe6a-4257-97be-a8dcd942d693 - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.7 dockerRepository: airbyte/source-insightly documentationUrl: https://docs.airbyte.com/integrations/sources/insightly githubIssueLabel: source-insightly diff --git a/airbyte-integrations/connectors/source-instagram/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-instagram/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-instagram/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-instagram/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-instagram/integration_tests/conftest.py b/airbyte-integrations/connectors/source-instagram/integration_tests/conftest.py index 9bff520cf87e..942f0428b3f5 100644 --- a/airbyte-integrations/connectors/source-instagram/integration_tests/conftest.py +++ b/airbyte-integrations/connectors/source-instagram/integration_tests/conftest.py @@ -6,6 +6,7 @@ import json import pytest + from airbyte_cdk.models import ConfiguredAirbyteCatalog diff --git a/airbyte-integrations/connectors/source-instagram/integration_tests/test_streams.py b/airbyte-integrations/connectors/source-instagram/integration_tests/test_streams.py index 6687d9e16f0c..1703f485ba35 100644 --- a/airbyte-integrations/connectors/source-instagram/integration_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-instagram/integration_tests/test_streams.py @@ -7,9 +7,10 @@ import pendulum import pytest -from airbyte_cdk.models import AirbyteMessage, AirbyteStateBlob, ConfiguredAirbyteCatalog, Type from source_instagram.source import SourceInstagram +from airbyte_cdk.models import AirbyteMessage, AirbyteStateBlob, ConfiguredAirbyteCatalog, Type + @pytest.fixture(name="state") def state_fixture() -> MutableMapping[str, Any]: @@ -35,12 +36,16 @@ def test_incremental_streams(self, configured_catalog, config, state): assert states, "insights should produce states" for state_msg in states: - stream_name, stream_state, state_keys_count = (state_msg.state.stream.stream_descriptor.name, - state_msg.state.stream.stream_state, - len(state_msg.state.stream.stream_state.dict())) + stream_name, stream_state, state_keys_count = ( + state_msg.state.stream.stream_descriptor.name, + state_msg.state.stream.stream_state, + len(state_msg.state.stream.stream_state.dict()), + ) assert stream_name == "user_insights", f"each state message should reference 'user_insights' stream, got {stream_name} instead" - assert isinstance(stream_state, AirbyteStateBlob), f"Stream state should be type AirbyteStateBlob, got {type(stream_state)} instead" + assert isinstance( + stream_state, AirbyteStateBlob + ), f"Stream state should be type AirbyteStateBlob, got {type(stream_state)} instead" assert state_keys_count == 2, f"Stream state should contain 2 partition keys, got {state_keys_count} instead" @staticmethod diff --git a/airbyte-integrations/connectors/source-instagram/main.py b/airbyte-integrations/connectors/source-instagram/main.py index 0a871930a015..7baf96d19171 100644 --- a/airbyte-integrations/connectors/source-instagram/main.py +++ b/airbyte-integrations/connectors/source-instagram/main.py @@ -4,5 +4,6 @@ from source_instagram.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-instagram/source_instagram/api.py b/airbyte-integrations/connectors/source-instagram/source_instagram/api.py index 16426efc1f9a..f9da2aa0df7d 100644 --- a/airbyte-integrations/connectors/source-instagram/source_instagram/api.py +++ b/airbyte-integrations/connectors/source-instagram/source_instagram/api.py @@ -8,15 +8,17 @@ import backoff import pendulum -from airbyte_cdk.entrypoint import logger from cached_property import cached_property from facebook_business import FacebookAdsApi from facebook_business.adobjects import user as fb_user from facebook_business.adobjects.iguser import IGUser from facebook_business.adobjects.page import Page from facebook_business.exceptions import FacebookRequestError + +from airbyte_cdk.entrypoint import logger from source_instagram.common import InstagramAPIException, retry_pattern + backoff_policy = retry_pattern(backoff.expo, FacebookRequestError, max_tries=5, factor=5, max_time=600) diff --git a/airbyte-integrations/connectors/source-instagram/source_instagram/common.py b/airbyte-integrations/connectors/source-instagram/source_instagram/common.py index 98efba83b47b..aad54c0e1311 100644 --- a/airbyte-integrations/connectors/source-instagram/source_instagram/common.py +++ b/airbyte-integrations/connectors/source-instagram/source_instagram/common.py @@ -11,6 +11,7 @@ from facebook_business.exceptions import FacebookRequestError from requests.status_codes import codes as status_codes + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-instagram/source_instagram/components.py b/airbyte-integrations/connectors/source-instagram/source_instagram/components.py index 74ee90ff8cf8..98feb5e58125 100644 --- a/airbyte-integrations/connectors/source-instagram/source_instagram/components.py +++ b/airbyte-integrations/connectors/source-instagram/source_instagram/components.py @@ -5,6 +5,7 @@ from typing import Any, Dict, MutableMapping, Optional import requests + from airbyte_cdk.connector_builder.connector_builder_handler import resolve_manifest from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies.exponential_backoff_strategy import ( ExponentialBackoffStrategy, @@ -17,6 +18,7 @@ from .common import remove_params_from_url + GRAPH_URL = resolve_manifest(source=SourceInstagram()).record.data["manifest"]["definitions"]["base_requester"]["url_base"] diff --git a/airbyte-integrations/connectors/source-instagram/source_instagram/source.py b/airbyte-integrations/connectors/source-instagram/source_instagram/source.py index fe4a35309b95..33f9bcdb6d7b 100644 --- a/airbyte-integrations/connectors/source-instagram/source_instagram/source.py +++ b/airbyte-integrations/connectors/source-instagram/source_instagram/source.py @@ -4,11 +4,13 @@ from typing import Any, List, Mapping, Tuple import pendulum + from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource from airbyte_cdk.sources.streams.core import Stream from source_instagram.api import InstagramAPI from source_instagram.streams import UserInsights + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-instagram/source_instagram/streams.py b/airbyte-integrations/connectors/source-instagram/source_instagram/streams.py index a01fa00b8056..397436a31bf0 100644 --- a/airbyte-integrations/connectors/source-instagram/source_instagram/streams.py +++ b/airbyte-integrations/connectors/source-instagram/source_instagram/streams.py @@ -9,10 +9,11 @@ from typing import Any, Iterable, List, Mapping, MutableMapping, Optional import pendulum +from cached_property import cached_property + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.streams import IncrementalMixin, Stream from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer -from cached_property import cached_property from source_instagram.api import InstagramAPI from .common import remove_params_from_url diff --git a/airbyte-integrations/connectors/source-instagram/unit_tests/conftest.py b/airbyte-integrations/connectors/source-instagram/unit_tests/conftest.py index 92257eaab9e1..b290127f0de5 100644 --- a/airbyte-integrations/connectors/source-instagram/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-instagram/unit_tests/conftest.py @@ -8,6 +8,7 @@ from pytest import fixture from source_instagram.api import InstagramAPI as API + FB_API_VERSION = FacebookAdsApi.API_VERSION @@ -57,12 +58,11 @@ def fb_account_response_fixture(account_id, some_config, requests_mock): "access_token": "access_token", "category": "Software company", "id": f"act_{account_id}", - "paging": {"cursors": { - "before": "cursor", - "after": "cursor"}}, + "paging": {"cursors": {"before": "cursor", "after": "cursor"}}, "summary": {"total_count": 1}, - "status_code": 200 - }] + "status_code": 200, + } + ] } } diff --git a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/config.py b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/config.py index b26f69f8a237..ef3ea86c51db 100644 --- a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/config.py +++ b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/config.py @@ -7,6 +7,7 @@ from typing import Any, List, MutableMapping + ACCESS_TOKEN = "test_access_token" ACCOUNT_ID = "111111111111111" diff --git a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/pagination.py b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/pagination.py index 670d3c4c777e..f77b436893b4 100644 --- a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/pagination.py +++ b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/pagination.py @@ -6,6 +6,7 @@ from airbyte_cdk.test.mock_http.request import HttpRequest from airbyte_cdk.test.mock_http.response_builder import PaginationStrategy + NEXT_PAGE_TOKEN = "QVFIUlhOX3Rnbm5Y" diff --git a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/request_builder.py b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/request_builder.py index 7ac44159c282..d10e4840f9bb 100644 --- a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/request_builder.py +++ b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/request_builder.py @@ -5,12 +5,14 @@ from typing import List, Optional, Union +from source_instagram.source import SourceInstagram + from airbyte_cdk.connector_builder.connector_builder_handler import resolve_manifest from airbyte_cdk.test.mock_http.request import HttpRequest -from source_instagram.source import SourceInstagram from .config import ACCOUNTS_FIELDS + GRAPH_URL = resolve_manifest(source=SourceInstagram()).record.data["manifest"]["definitions"]["base_requester"]["url_base"] @@ -94,4 +96,3 @@ def build(self) -> HttpRequest: def _item_path(self) -> str: path_for_resource = "/" if self._item_id_is_sub_path else "" return f"{self._item_id}{path_for_resource}" if self._item_id else "" - diff --git a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/response_builder.py b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/response_builder.py index 4a1746e422aa..67d14cad0a99 100644 --- a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/response_builder.py +++ b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/response_builder.py @@ -23,20 +23,7 @@ def build_response( def get_account_response() -> HttpResponse: response = { - "data": [ - { - "id": PAGE_ID, - "name": "AccountName", - "instagram_business_account": { - "id": BUSINESS_ACCOUNT_ID - } - } - ], - "paging": { - "cursors": { - "before": "before_token", - "after": "after_token" - } - } - } + "data": [{"id": PAGE_ID, "name": "AccountName", "instagram_business_account": {"id": BUSINESS_ACCOUNT_ID}}], + "paging": {"cursors": {"before": "before_token", "after": "after_token"}}, + } return build_response(body=response, status_code=HTTPStatus.OK) diff --git a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_api.py b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_api.py index 850356c62f49..218692c282f4 100644 --- a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_api.py +++ b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_api.py @@ -21,10 +21,8 @@ from .response_builder import get_account_response from .utils import config, read_output -_FIELDS = [ - "id", - "instagram_business_account" -] + +_FIELDS = ["id", "instagram_business_account"] _STREAM_NAME = "Api" @@ -46,7 +44,6 @@ def _record() -> RecordBuilder: class TestFullRefresh(TestCase): - @staticmethod def _read(config_: ConfigBuilder, expecting_exception: bool = False) -> EntrypointOutput: return read_output( @@ -70,10 +67,7 @@ def test_given_one_page_when_read_then_return_records(self, http_mocker: HttpMoc def test_accounts_with_no_instagram_business_account_field(self, http_mocker: HttpMocker) -> None: test = "not_instagram_business_account" mocked_response = json.dumps(find_template(f"api_for_{test}", __file__)) - http_mocker.get( - get_account_request().build(), - HttpResponse(mocked_response, 200) - ) + http_mocker.get(get_account_request().build(), HttpResponse(mocked_response, 200)) original_records = json.loads(mocked_response) output = self._read(config_=config()) diff --git a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_media.py b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_media.py index 429b75faa425..9319563fb463 100644 --- a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_media.py +++ b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_media.py @@ -23,13 +23,15 @@ from .response_builder import get_account_response from .utils import config, read_output + _FIELDS = [ "caption", "comments_count", "id", "ig_id", "is_comment_enabled", - "like_count","media_type", + "like_count", + "media_type", "media_product_type", "media_url", "owner", @@ -38,44 +40,21 @@ "thumbnail_url", "timestamp", "username", - "children" + "children", ] -_CHILDREN_FIELDS = [ - "id", - "ig_id", - "media_type", - "media_url", - "owner", - "permalink", - "shortcode", - "thumbnail_url", - "timestamp", - "username" - ] - -_CHILDREN_IDS = [ - "07608776690540123", - "52896800415362123", - "39559889460059123", - "17359925580923123" - ] +_CHILDREN_FIELDS = ["id", "ig_id", "media_type", "media_url", "owner", "permalink", "shortcode", "thumbnail_url", "timestamp", "username"] + +_CHILDREN_IDS = ["07608776690540123", "52896800415362123", "39559889460059123", "17359925580923123"] _STREAM_NAME = "media" def _get_request() -> RequestBuilder: - return ( - RequestBuilder.get_media_endpoint(item_id=BUSINESS_ACCOUNT_ID) - .with_limit(100) - .with_fields(_FIELDS) - ) + return RequestBuilder.get_media_endpoint(item_id=BUSINESS_ACCOUNT_ID).with_limit(100).with_fields(_FIELDS) -def _get_children_request(media_id:str) -> RequestBuilder: - return( - RequestBuilder.get_media_children_endpoint(item_id=media_id) - .with_fields(_CHILDREN_FIELDS) - ) +def _get_children_request(media_id: str) -> RequestBuilder: + return RequestBuilder.get_media_children_endpoint(item_id=media_id).with_fields(_CHILDREN_FIELDS) def _get_response() -> HttpResponseBuilder: @@ -93,8 +72,8 @@ def _record() -> RecordBuilder: record_id_path=FieldPath("id"), ) -class TestFullRefresh(TestCase): +class TestFullRefresh(TestCase): @staticmethod def _read(config_: ConfigBuilder, expecting_exception: bool = False) -> EntrypointOutput: return read_output( @@ -162,15 +141,12 @@ def test_given_one_page_has_children_field(self, http_mocker: HttpMocker) -> Non get_account_request().build(), get_account_response(), ) - http_mocker.get( - _get_request().build(), - HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 200) - ) + http_mocker.get(_get_request().build(), HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 200)) for children_id in _CHILDREN_IDS: http_mocker.get( _get_children_request(children_id).build(), - HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_children_for_{test}", __file__)), 200) + HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_children_for_{test}", __file__)), 200), ) output = self._read(config_=config()) diff --git a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_media_insights.py b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_media_insights.py index 11902699b40b..bc95b4cbc934 100644 --- a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_media_insights.py +++ b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_media_insights.py @@ -6,6 +6,7 @@ from unittest import TestCase import pytest + from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput from airbyte_cdk.test.mock_http import HttpMocker, HttpResponse from airbyte_cdk.test.mock_http.response_builder import ( @@ -24,13 +25,15 @@ from .response_builder import get_account_response from .utils import config, read_output + PARENT_FIELDS = [ "caption", "comments_count", "id", "ig_id", "is_comment_enabled", - "like_count","media_type", + "like_count", + "media_type", "media_product_type", "media_url", "owner", @@ -39,9 +42,9 @@ "thumbnail_url", "timestamp", "username", - "children" + "children", ] -_PARENT_STREAM_NAME = 'media' +_PARENT_STREAM_NAME = "media" _STREAM_NAME = "media_insights" @@ -54,28 +57,38 @@ MEDIA_ID_ERROR_WITH_WRONG_PERMISSIONS = "35076616084176125" MEDIA_ID_ERROR_WITH_WRONG_PERMISSIONS_CODE_10 = "35076616084176126" -REELS = 'reels' -VIDEO_FEED = 'video_feed' -VIDEO = 'video' -CAROUSEL_ALBUM = 'carousel_album' -GENERAL_MEDIA = 'general_media' -ERROR_POSTED_BEFORE_BUSINESS = 'error_posted_before_business' -ERROR_WITH_WRONG_PERMISSIONS = 'error_with_wrong_permissions' -ERROR_WITH_WRONG_PERMISSIONS_CODE_10 = 'error_with_wrong_permissions_code_10' +REELS = "reels" +VIDEO_FEED = "video_feed" +VIDEO = "video" +CAROUSEL_ALBUM = "carousel_album" +GENERAL_MEDIA = "general_media" +ERROR_POSTED_BEFORE_BUSINESS = "error_posted_before_business" +ERROR_WITH_WRONG_PERMISSIONS = "error_with_wrong_permissions" +ERROR_WITH_WRONG_PERMISSIONS_CODE_10 = "error_with_wrong_permissions_code_10" _MEDIA_IDS = { REELS: MEDIA_ID_REELS, VIDEO_FEED: MEDIA_ID_VIDEO_FEED, VIDEO: MEDIA_ID_VIDEO, CAROUSEL_ALBUM: MEDIA_ID_CAROUSEL_ALBUM, - GENERAL_MEDIA: MEDIA_ID_GENERAL_MEDIA + GENERAL_MEDIA: MEDIA_ID_GENERAL_MEDIA, } METRICS_GENERAL_MEDIA = ["impressions", "reach", "saved", "video_views", "likes", "comments", "shares", "follows", "profile_visits"] _METRICS = { - MEDIA_ID_REELS: ["comments", "ig_reels_avg_watch_time", "ig_reels_video_view_total_time", "likes", "plays", "reach", "saved", "shares", - "ig_reels_aggregated_all_plays_count", "clips_replays_count"], + MEDIA_ID_REELS: [ + "comments", + "ig_reels_avg_watch_time", + "ig_reels_video_view_total_time", + "likes", + "plays", + "reach", + "saved", + "shares", + "ig_reels_aggregated_all_plays_count", + "clips_replays_count", + ], MEDIA_ID_VIDEO_FEED: ["impressions", "reach", "saved", "video_views"], MEDIA_ID_VIDEO: ["impressions", "reach", "saved", "video_views", "likes", "comments", "shares", "follows", "profile_visits"], MEDIA_ID_CAROUSEL_ALBUM: ["impressions", "reach", "saved", "video_views", "shares", "follows", "profile_visits"], @@ -83,29 +96,22 @@ # Reusing general media metrics for error scenarios MEDIA_ID_ERROR_POSTED_BEFORE_BUSINESS: METRICS_GENERAL_MEDIA, MEDIA_ID_ERROR_WITH_WRONG_PERMISSIONS: METRICS_GENERAL_MEDIA, - MEDIA_ID_ERROR_WITH_WRONG_PERMISSIONS_CODE_10: METRICS_GENERAL_MEDIA + MEDIA_ID_ERROR_WITH_WRONG_PERMISSIONS_CODE_10: METRICS_GENERAL_MEDIA, } def _get_parent_request() -> RequestBuilder: - return ( - RequestBuilder.get_media_endpoint(item_id=BUSINESS_ACCOUNT_ID) - .with_limit(100) - .with_fields(PARENT_FIELDS) - ) + return RequestBuilder.get_media_endpoint(item_id=BUSINESS_ACCOUNT_ID).with_limit(100).with_fields(PARENT_FIELDS) def _get_child_request(media_id, metric) -> RequestBuilder: - return ( - RequestBuilder.get_media_insights_endpoint(item_id=media_id) - .with_custom_param("metric", metric, with_format=True) - ) + return RequestBuilder.get_media_insights_endpoint(item_id=media_id).with_custom_param("metric", metric, with_format=True) def _get_response(stream_name: str, test: str = None, with_pagination_strategy: bool = True) -> HttpResponseBuilder: - scenario = '' + scenario = "" if test: - scenario = f'_for_{test}' + scenario = f"_for_{test}" kwargs = { "response_template": find_template(f"{stream_name}{scenario}", __file__), "records_path": FieldPath("data"), @@ -114,15 +120,13 @@ def _get_response(stream_name: str, test: str = None, with_pagination_strategy: if with_pagination_strategy: kwargs["pagination_strategy"] = InstagramPaginationStrategy(request=_get_parent_request().build(), next_page_token=NEXT_PAGE_TOKEN) - return create_response_builder( - **kwargs - ) + return create_response_builder(**kwargs) def _record(stream_name: str, test: str = None) -> RecordBuilder: - scenario = '' + scenario = "" if test: - scenario = f'_for_{test}' + scenario = f"_for_{test}" return create_record_builder( response_template=find_template(f"{stream_name}{scenario}", __file__), records_path=FieldPath("data"), @@ -131,7 +135,6 @@ def _record(stream_name: str, test: str = None) -> RecordBuilder: class TestFullRefresh(TestCase): - @staticmethod def _read(config_: ConfigBuilder, expecting_exception: bool = False) -> EntrypointOutput: return read_output( @@ -150,12 +153,14 @@ def test_instagram_insights_for_reels(self, http_mocker: HttpMocker) -> None: ) http_mocker.get( _get_parent_request().build(), - _get_response(stream_name=_PARENT_STREAM_NAME, test=test).with_record(_record(stream_name=_PARENT_STREAM_NAME, test=test)).build(), + _get_response(stream_name=_PARENT_STREAM_NAME, test=test) + .with_record(_record(stream_name=_PARENT_STREAM_NAME, test=test)) + .build(), ) http_mocker.get( _get_child_request(media_id=MEDIA_ID_REELS, metric=_METRICS[MEDIA_ID_REELS]).build(), - HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 200) + HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 200), ) output = self._read(config_=config()) @@ -175,12 +180,14 @@ def test_instagram_insights_for_video_feed(self, http_mocker: HttpMocker) -> Non ) http_mocker.get( _get_parent_request().build(), - _get_response(stream_name=_PARENT_STREAM_NAME, test=test).with_record(_record(stream_name=_PARENT_STREAM_NAME, test=test)).build(), + _get_response(stream_name=_PARENT_STREAM_NAME, test=test) + .with_record(_record(stream_name=_PARENT_STREAM_NAME, test=test)) + .build(), ) http_mocker.get( _get_child_request(media_id=MEDIA_ID_VIDEO_FEED, metric=_METRICS[MEDIA_ID_VIDEO_FEED]).build(), - HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 200) + HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 200), ) output = self._read(config_=config()) @@ -200,12 +207,14 @@ def test_instagram_insights_for_video(self, http_mocker: HttpMocker) -> None: ) http_mocker.get( _get_parent_request().build(), - _get_response(stream_name=_PARENT_STREAM_NAME, test=test).with_record(_record(stream_name=_PARENT_STREAM_NAME, test=test)).build(), + _get_response(stream_name=_PARENT_STREAM_NAME, test=test) + .with_record(_record(stream_name=_PARENT_STREAM_NAME, test=test)) + .build(), ) http_mocker.get( _get_child_request(media_id=MEDIA_ID_VIDEO, metric=_METRICS[MEDIA_ID_VIDEO]).build(), - HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 200) + HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 200), ) output = self._read(config_=config()) @@ -225,12 +234,14 @@ def test_instagram_insights_carousel_album(self, http_mocker: HttpMocker) -> Non ) http_mocker.get( _get_parent_request().build(), - _get_response(stream_name=_PARENT_STREAM_NAME, test=test).with_record(_record(stream_name=_PARENT_STREAM_NAME, test=test)).build(), + _get_response(stream_name=_PARENT_STREAM_NAME, test=test) + .with_record(_record(stream_name=_PARENT_STREAM_NAME, test=test)) + .build(), ) http_mocker.get( _get_child_request(media_id=MEDIA_ID_CAROUSEL_ALBUM, metric=_METRICS[MEDIA_ID_CAROUSEL_ALBUM]).build(), - HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 200) + HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 200), ) output = self._read(config_=config()) @@ -250,12 +261,14 @@ def test_instagram_insights_general_media(self, http_mocker: HttpMocker) -> None ) http_mocker.get( _get_parent_request().build(), - _get_response(stream_name=_PARENT_STREAM_NAME, test=test).with_record(_record(stream_name=_PARENT_STREAM_NAME, test=test)).build(), + _get_response(stream_name=_PARENT_STREAM_NAME, test=test) + .with_record(_record(stream_name=_PARENT_STREAM_NAME, test=test)) + .build(), ) http_mocker.get( _get_child_request(media_id=MEDIA_ID_GENERAL_MEDIA, metric=_METRICS[MEDIA_ID_GENERAL_MEDIA]).build(), - HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 200) + HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 200), ) output = self._read(config_=config()) @@ -266,7 +279,6 @@ def test_instagram_insights_general_media(self, http_mocker: HttpMocker) -> None for metric in _METRICS[MEDIA_ID_GENERAL_MEDIA]: assert metric in output.records[0].record.data - @HttpMocker() def test_instagram_insights_error_posted_before_business(self, http_mocker: HttpMocker) -> None: test = ERROR_POSTED_BEFORE_BUSINESS @@ -275,18 +287,19 @@ def test_instagram_insights_error_posted_before_business(self, http_mocker: Http get_account_response(), ) http_mocker.get( - _get_parent_request().build(), - HttpResponse(json.dumps(find_template(f"{_PARENT_STREAM_NAME}_for_{test}", __file__)), 200) + _get_parent_request().build(), HttpResponse(json.dumps(find_template(f"{_PARENT_STREAM_NAME}_for_{test}", __file__)), 200) ) http_mocker.get( _get_child_request(media_id=MEDIA_ID_GENERAL_MEDIA, metric=_METRICS[MEDIA_ID_GENERAL_MEDIA]).build(), - HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{GENERAL_MEDIA}", __file__)), 200) + HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{GENERAL_MEDIA}", __file__)), 200), ) http_mocker.get( - _get_child_request(media_id=MEDIA_ID_ERROR_POSTED_BEFORE_BUSINESS, metric=_METRICS[MEDIA_ID_ERROR_POSTED_BEFORE_BUSINESS]).build(), - HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 400) + _get_child_request( + media_id=MEDIA_ID_ERROR_POSTED_BEFORE_BUSINESS, metric=_METRICS[MEDIA_ID_ERROR_POSTED_BEFORE_BUSINESS] + ).build(), + HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 400), ) output = self._read(config_=config()) @@ -305,18 +318,19 @@ def test_instagram_insights_error_with_wrong_permissions(self, http_mocker: Http get_account_response(), ) http_mocker.get( - _get_parent_request().build(), - HttpResponse(json.dumps(find_template(f"{_PARENT_STREAM_NAME}_for_{test}", __file__)), 200) + _get_parent_request().build(), HttpResponse(json.dumps(find_template(f"{_PARENT_STREAM_NAME}_for_{test}", __file__)), 200) ) http_mocker.get( _get_child_request(media_id=MEDIA_ID_GENERAL_MEDIA, metric=_METRICS[MEDIA_ID_GENERAL_MEDIA]).build(), - HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{GENERAL_MEDIA}", __file__)), 200) + HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{GENERAL_MEDIA}", __file__)), 200), ) http_mocker.get( - _get_child_request(media_id=MEDIA_ID_ERROR_WITH_WRONG_PERMISSIONS, metric=_METRICS[MEDIA_ID_ERROR_WITH_WRONG_PERMISSIONS]).build(), - HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 400) + _get_child_request( + media_id=MEDIA_ID_ERROR_WITH_WRONG_PERMISSIONS, metric=_METRICS[MEDIA_ID_ERROR_WITH_WRONG_PERMISSIONS] + ).build(), + HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 400), ) output = self._read(config_=config()) @@ -336,18 +350,19 @@ def test_instagram_insights_error_with_wrong_permissions_code_10(self, http_mock get_account_response(), ) http_mocker.get( - _get_parent_request().build(), - HttpResponse(json.dumps(find_template(f"{_PARENT_STREAM_NAME}_for_{test}", __file__)), 200) + _get_parent_request().build(), HttpResponse(json.dumps(find_template(f"{_PARENT_STREAM_NAME}_for_{test}", __file__)), 200) ) http_mocker.get( _get_child_request(media_id=MEDIA_ID_GENERAL_MEDIA, metric=_METRICS[MEDIA_ID_GENERAL_MEDIA]).build(), - HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{GENERAL_MEDIA}", __file__)), 200) + HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{GENERAL_MEDIA}", __file__)), 200), ) http_mocker.get( - _get_child_request(media_id=MEDIA_ID_ERROR_WITH_WRONG_PERMISSIONS_CODE_10, metric=_METRICS[MEDIA_ID_ERROR_WITH_WRONG_PERMISSIONS_CODE_10]).build(), - HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 400) + _get_child_request( + media_id=MEDIA_ID_ERROR_WITH_WRONG_PERMISSIONS_CODE_10, metric=_METRICS[MEDIA_ID_ERROR_WITH_WRONG_PERMISSIONS_CODE_10] + ).build(), + HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 400), ) output = self._read(config_=config()) diff --git a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_stories.py b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_stories.py index abc137b78c71..ac8ec96a3e1c 100644 --- a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_stories.py +++ b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_stories.py @@ -22,6 +22,7 @@ from .response_builder import get_account_response from .utils import config, read_output + FIELDS = [ "caption", "id", @@ -35,18 +36,14 @@ "shortcode", "thumbnail_url", "timestamp", - "username" + "username", ] _STREAM_NAME = "stories" def _get_request() -> RequestBuilder: - return ( - RequestBuilder.get_stories_endpoint(item_id=BUSINESS_ACCOUNT_ID) - .with_limit(100) - .with_fields(FIELDS) - ) + return RequestBuilder.get_stories_endpoint(item_id=BUSINESS_ACCOUNT_ID).with_limit(100).with_fields(FIELDS) def _get_response() -> HttpResponseBuilder: @@ -66,7 +63,6 @@ def _record() -> RecordBuilder: class TestFullRefresh(TestCase): - @staticmethod def _read(config_: ConfigBuilder, expecting_exception: bool = False) -> EntrypointOutput: return read_output( diff --git a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_story_insights.py b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_story_insights.py index 1e9e3f0f47aa..5e71182a2349 100644 --- a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_story_insights.py +++ b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_story_insights.py @@ -6,6 +6,7 @@ from unittest import TestCase import pytest + from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput from airbyte_cdk.test.mock_http import HttpMocker, HttpResponse from airbyte_cdk.test.mock_http.response_builder import ( @@ -24,6 +25,7 @@ from .response_builder import get_account_response from .utils import config, read_output + PARENT_FIELDS = [ "caption", "id", @@ -37,40 +39,32 @@ "shortcode", "thumbnail_url", "timestamp", - "username" + "username", ] -_PARENT_STREAM_NAME = 'stories' +_PARENT_STREAM_NAME = "stories" _STREAM_NAME = "story_insights" STORIES_ID = "3874523487643" STORIES_ID_ERROR_CODE_10 = "3874523487644" -HAPPY_PATH = 'story_insights_happy_path' -ERROR_10 = 'story_insights_error_code_10' +HAPPY_PATH = "story_insights_happy_path" +ERROR_10 = "story_insights_error_code_10" _METRICS = ["impressions", "reach", "replies", "follows", "profile_visits", "shares", "total_interactions"] - def _get_parent_request() -> RequestBuilder: - return ( - RequestBuilder.get_stories_endpoint(item_id=BUSINESS_ACCOUNT_ID) - .with_limit(100) - .with_fields(PARENT_FIELDS) - ) + return RequestBuilder.get_stories_endpoint(item_id=BUSINESS_ACCOUNT_ID).with_limit(100).with_fields(PARENT_FIELDS) def _get_child_request(media_id, metric) -> RequestBuilder: - return ( - RequestBuilder.get_media_insights_endpoint(item_id=media_id) - .with_custom_param("metric", metric, with_format=True) - ) + return RequestBuilder.get_media_insights_endpoint(item_id=media_id).with_custom_param("metric", metric, with_format=True) def _get_response(stream_name: str, test: str = None, with_pagination_strategy: bool = True) -> HttpResponseBuilder: - scenario = '' + scenario = "" if test: - scenario = f'_for_{test}' + scenario = f"_for_{test}" kwargs = { "response_template": find_template(f"{stream_name}{scenario}", __file__), "records_path": FieldPath("data"), @@ -79,15 +73,13 @@ def _get_response(stream_name: str, test: str = None, with_pagination_strategy: if with_pagination_strategy: kwargs["pagination_strategy"] = InstagramPaginationStrategy(request=_get_parent_request().build(), next_page_token=NEXT_PAGE_TOKEN) - return create_response_builder( - **kwargs - ) + return create_response_builder(**kwargs) def _record(stream_name: str, test: str = None) -> RecordBuilder: - scenario = '' + scenario = "" if test: - scenario = f'_for_{test}' + scenario = f"_for_{test}" return create_record_builder( response_template=find_template(f"{stream_name}{scenario}", __file__), records_path=FieldPath("data"), @@ -96,7 +88,6 @@ def _record(stream_name: str, test: str = None) -> RecordBuilder: class TestFullRefresh(TestCase): - @staticmethod def _read(config_: ConfigBuilder, expecting_exception: bool = False) -> EntrypointOutput: return read_output( @@ -117,12 +108,14 @@ def test_instagram_story_insights(self, http_mocker: HttpMocker) -> None: # Mocking parent stream http_mocker.get( _get_parent_request().build(), - _get_response(stream_name=_PARENT_STREAM_NAME, test=test).with_record(_record(stream_name=_PARENT_STREAM_NAME, test=test)).build(), + _get_response(stream_name=_PARENT_STREAM_NAME, test=test) + .with_record(_record(stream_name=_PARENT_STREAM_NAME, test=test)) + .build(), ) http_mocker.get( _get_child_request(media_id=STORIES_ID, metric=_METRICS).build(), - HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 200) + HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 200), ) output = self._read(config_=config()) @@ -133,7 +126,6 @@ def test_instagram_story_insights(self, http_mocker: HttpMocker) -> None: for metric in _METRICS: assert metric in output.records[0].record.data - @HttpMocker() def test_instagram_story_insights_for_error_code_30(self, http_mocker: HttpMocker) -> None: test = ERROR_10 @@ -143,18 +135,17 @@ def test_instagram_story_insights_for_error_code_30(self, http_mocker: HttpMocke ) # Mocking parent stream http_mocker.get( - _get_parent_request().build(), - HttpResponse(json.dumps(find_template(f"{_PARENT_STREAM_NAME}_for_{test}", __file__)), 200) + _get_parent_request().build(), HttpResponse(json.dumps(find_template(f"{_PARENT_STREAM_NAME}_for_{test}", __file__)), 200) ) # Good response http_mocker.get( _get_child_request(media_id=STORIES_ID, metric=_METRICS).build(), - HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{HAPPY_PATH}", __file__)), 200) + HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{HAPPY_PATH}", __file__)), 200), ) # error 10 http_mocker.get( _get_child_request(media_id=STORIES_ID_ERROR_CODE_10, metric=_METRICS).build(), - HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 400) + HttpResponse(json.dumps(find_template(f"{_STREAM_NAME}_for_{test}", __file__)), 400), ) output = self._read(config_=config()) diff --git a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_user_lifetime_insights.py b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_user_lifetime_insights.py index a9a5d717fc0f..48dc09b91d6b 100644 --- a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_user_lifetime_insights.py +++ b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_user_lifetime_insights.py @@ -21,6 +21,7 @@ from .response_builder import get_account_response from .utils import config, read_output + _CURSOR_FIELD = "id" _STREAM_NAME = "user_lifetime_insights" @@ -29,28 +30,30 @@ def _get_request() -> RequestBuilder: return ( RequestBuilder.get_user_lifetime_insights_endpoint(item_id=BUSINESS_ACCOUNT_ID) - .with_custom_param("metric", "follower_demographics").with_custom_param("period", "lifetime").with_custom_param("metric_type", "total_value").with_limit(100) + .with_custom_param("metric", "follower_demographics") + .with_custom_param("period", "lifetime") + .with_custom_param("metric_type", "total_value") + .with_limit(100) ) def _get_response() -> HttpResponseBuilder: return create_response_builder( response_template=find_template(_STREAM_NAME, __file__), - records_path=FieldPath('data'), + records_path=FieldPath("data"), ) def _record() -> RecordBuilder: return create_record_builder( response_template=find_template(_STREAM_NAME, __file__), - records_path=FieldPath('data'), + records_path=FieldPath("data"), record_id_path=FieldPath("id"), record_cursor_path=FieldPath(_CURSOR_FIELD), ) class TestFullRefresh(TestCase): - @staticmethod def _read(config_: ConfigBuilder, expecting_exception: bool = False) -> EntrypointOutput: return read_output( @@ -76,4 +79,3 @@ def test_read_records(self, http_mocker: HttpMocker) -> None: output = self._read(config_=config()) # each breakdown should produce a record assert len(output.records) == 3 - diff --git a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_users.py b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_users.py index 2e50aae606f2..97c3519006fa 100644 --- a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_users.py +++ b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/test_users.py @@ -21,6 +21,7 @@ from .response_builder import get_account_response from .utils import config, read_output + _FIELDS = [ "id", "biography", @@ -31,36 +32,32 @@ "name", "profile_picture_url", "username", - "website" + "website", ] _STREAM_NAME = "users" def _get_request() -> RequestBuilder: - return ( - RequestBuilder.get_users_endpoint(item_id=BUSINESS_ACCOUNT_ID) - .with_fields(_FIELDS) - ) + return RequestBuilder.get_users_endpoint(item_id=BUSINESS_ACCOUNT_ID).with_fields(_FIELDS) def _get_response() -> HttpResponseBuilder: return create_response_builder( response_template=find_template(_STREAM_NAME, __file__), - records_path=FieldPath('data'), + records_path=FieldPath("data"), ) def _record() -> RecordBuilder: return create_record_builder( response_template=find_template(_STREAM_NAME, __file__), - records_path=FieldPath('data'), + records_path=FieldPath("data"), record_id_path=FieldPath("id"), ) class TestFullRefresh(TestCase): - @staticmethod def _read(config_: ConfigBuilder, expecting_exception: bool = False) -> EntrypointOutput: return read_output( @@ -83,4 +80,3 @@ def test_read_records(self, http_mocker: HttpMocker) -> None: output = self._read(config_=config()) assert len(output.records) == 1 - diff --git a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/utils.py b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/utils.py index 5be5aef5c8bb..dd58fde5f31d 100644 --- a/airbyte-integrations/connectors/source-instagram/unit_tests/integration/utils.py +++ b/airbyte-integrations/connectors/source-instagram/unit_tests/integration/utils.py @@ -5,10 +5,11 @@ from typing import List, Optional +from source_instagram import SourceInstagram + from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read from airbyte_protocol.models import AirbyteStateMessage, ConfiguredAirbyteCatalog, SyncMode -from source_instagram import SourceInstagram from .config import ConfigBuilder diff --git a/airbyte-integrations/connectors/source-instagram/unit_tests/records.py b/airbyte-integrations/connectors/source-instagram/unit_tests/records.py index ecf06f7b64e5..4ccb16aade93 100644 --- a/airbyte-integrations/connectors/source-instagram/unit_tests/records.py +++ b/airbyte-integrations/connectors/source-instagram/unit_tests/records.py @@ -1,77 +1,53 @@ # Copyright (c) 2024 Airbyte, Inc., all rights reserved. children_record = { - "children": { - "data": [ - { - "id": "7608776690540" - }, - { - "id": "2896800415362" - }, - { - "id": "9559889460059" - }, - { - "id": "7359925580923" - } - ] - } + "children": {"data": [{"id": "7608776690540"}, {"id": "2896800415362"}, {"id": "9559889460059"}, {"id": "7359925580923"}]} } expected_children_transformed = { - "children": - [ - { + "children": [ + { "id": "7608776690540", "ig_id": "2521545917836833225", "media_type": "IMAGE", "media_url": "https://fake_url?_nc_cat=108&ccb=1-7&_nc_sid=18de74&_nc_ohc=tTUSyCXbN40Q7kNvgF-k3H6&_nc_ht=fakecontent&edm=AEQ6tj4EAAAA&oh=00_AYAe4PKmuen4Dryt4sMEbfvrW2_eANbY1AEdl7gHG0a3mw&oe=66701C8F", - "owner": { - "id": "id" - }, + "owner": {"id": "id"}, "shortcode": "shortcode", "timestamp": "2021-03-03T22:48:39+00:00", - "username": "username" - }, - { + "username": "username", + }, + { "id": "2896800415362", "ig_id": "2521545917736276706", "media_type": "IMAGE", "media_url": "https://fake_url?_nc_cat=100&ccb=1-7&_nc_sid=18de74&_nc_ohc=9qJ5-fOc9lcQ7kNvgFirW6U&_nc_ht=fakecontent&edm=AEQ6tj4EAAAA&oh=00_AYBSuGRqMEzjxHri30L5NDs0irt7_7h-arKTYS8inrL56g&oe=66702E9A", - "owner": { - "id": "id" - }, + "owner": {"id": "id"}, "shortcode": "shortcode", "timestamp": "2021-03-03T22:48:39+00:00", - "username": "username" - }, - { + "username": "username", + }, + { "id": "9559889460059", "ig_id": "2521545917845406325", "media_type": "IMAGE", "media_url": "https://fake_url?_nc_cat=110&ccb=1-7&_nc_sid=18de74&_nc_ohc=QOtZzdxFjusQ7kNvgEqsuc2&_nc_ht=fakecontent&edm=AEQ6tj4EAAAA&oh=00_AYBPBGVS3NYW-h8oLwam_rWub-mE-9MLGc1EDVHtLJ2DBQ&oe=66702DE1", - "owner": { - "id": "id" - }, + "owner": {"id": "id"}, "shortcode": "shortcode", "timestamp": "2021-03-03T22:48:39+00:00", - "username": "username" - }, - { + "username": "username", + }, + { "id": "7359925580923", "ig_id": "2521545555591565193", "media_type": "VIDEO", "media_url": "https://fake_url?efg=eyJ2ZW5jb2RlX3RhZyI6InZ0c192b2RfdXJsZ2VuLmNhcm91c2VsX2l0ZW0udW5rbm93bi1DMy40ODAuZGFzaF9iYXNlbGluZV8xX3YxIn0&_nc_ht=fakecontent&_nc_cat=108&vs=863753484982045_2117350142", - "owner": { - "id": "id" - }, + "owner": {"id": "id"}, "shortcode": "shortcode", "thumbnail_url": "https://fake_url?_nc_cat=108&ccb=1-7&_nc_sid=18de74&_nc_ohc=pJkRskDC80UQ7kNvgFn3i4H&_nc_ht=fakecontent&edm=AEQ6tj4EAAAA&oh=00_AYBKK27CU9dvjiqPi9a4JKUIICp26HZ074-vgz0OVKFkbw&oe=66702104", "timestamp": "2021-03-03T22:48:39+00:00", - "username": "username" - } - ] + "username": "username", + }, + ] } clear_url_record = { @@ -85,293 +61,66 @@ } breakdowns_record = { - "name": "follower_demographics", - "period": "lifetime", - "title": "Follower demographics", - "description": "The demographic characteristics of followers, including countries, cities and gender distribution.", - "total_value": { - "breakdowns": [ + "name": "follower_demographics", + "period": "lifetime", + "title": "Follower demographics", + "description": "The demographic characteristics of followers, including countries, cities and gender distribution.", + "total_value": { + "breakdowns": [ { - "dimension_keys": [ - "city" - ], - "results": [ - { - "dimension_values": [ - "London, England" - ], - "value": 263 - }, - { - "dimension_values": [ - "Sydney, New South Wales" - ], - "value": 467 - }, - { - "dimension_values": [ - "Algiers, Algiers Province" - ], - "value": 58 - }, - { - "dimension_values": [ - "Casablanca, Grand Casablanca" - ], - "value": 71 - }, - { - "dimension_values": [ - "São Paulo, São Paulo (state)" - ], - "value": 139 - }, - { - "dimension_values": [ - "Rio de Janeiro, Rio de Janeiro (state)" - ], - "value": 44 - }, - { - "dimension_values": [ - "Perth, Western Australia" - ], - "value": 180 - }, - { - "dimension_values": [ - "Berlin, Berlin" - ], - "value": 47 - }, - { - "dimension_values": [ - "Kolkata, West Bengal" - ], - "value": 85 - }, - { - "dimension_values": [ - "Phoenix, Arizona" - ], - "value": 39 - }, - { - "dimension_values": [ - "Lagos, Lagos State" - ], - "value": 40 - }, - { - "dimension_values": [ - "Dublin, Dublin" - ], - "value": 65 - }, - { - "dimension_values": [ - "Pune, Maharashtra" - ], - "value": 72 - }, - { - "dimension_values": [ - "Wollongong, New South Wales" - ], - "value": 43 - }, - { - "dimension_values": [ - "Christchurch, Canterbury" - ], - "value": 42 - }, - { - "dimension_values": [ - "Jakarta, Jakarta" - ], - "value": 46 - }, - { - "dimension_values": [ - "Pretoria, Gauteng" - ], - "value": 54 - }, - { - "dimension_values": [ - "Buenos Aires, Ciudad Autónoma de Buenos Aires" - ], - "value": 41 - }, - { - "dimension_values": [ - "Gold Coast, Queensland" - ], - "value": 98 - }, - { - "dimension_values": [ - "Sunshine Coast, Queensland" - ], - "value": 37 - }, - { - "dimension_values": [ - "Melbourne, Victoria" - ], - "value": 338 - }, - { - "dimension_values": [ - "Gurugram, Haryana" - ], - "value": 52 - }, - { - "dimension_values": [ - "Delhi, Delhi" - ], - "value": 194 - }, - { - "dimension_values": [ - "Los Angeles, California" - ], - "value": 66 - }, - { - "dimension_values": [ - "Madrid, Comunidad de Madrid" - ], - "value": 65 - }, - { - "dimension_values": [ - "Lahore, Punjab" - ], - "value": 41 - }, - { - "dimension_values": [ - "Brisbane, Queensland" - ], - "value": 160 - }, - { - "dimension_values": [ - "Adelaide, South Australia" - ], - "value": 93 - }, - { - "dimension_values": [ - "Canberra, Australian Capital Territory" - ], - "value": 45 - }, - { - "dimension_values": [ - "Lima, Lima Region" - ], - "value": 43 - }, - { - "dimension_values": [ - "Istanbul, Istanbul Province" - ], - "value": 57 - }, - { - "dimension_values": [ - "Toronto, Ontario" - ], - "value": 40 - }, - { - "dimension_values": [ - "Chennai, Tamil Nadu" - ], - "value": 82 - }, - { - "dimension_values": [ - "Mexico City, Distrito Federal" - ], - "value": 66 - }, - { - "dimension_values": [ - "Auckland, Auckland Region" - ], - "value": 98 - }, - { - "dimension_values": [ - "Cape Town, Western Cape" - ], - "value": 172 - }, - { - "dimension_values": [ - "New York, New York" - ], - "value": 139 - }, - { - "dimension_values": [ - "Cairo, Cairo Governorate" - ], - "value": 45 - }, - { - "dimension_values": [ - "Dubai, Dubai" - ], - "value": 57 - }, - { - "dimension_values": [ - "Santiago, Santiago Metropolitan Region" - ], - "value": 73 - }, - { - "dimension_values": [ - "Mumbai, Maharashtra" - ], - "value": 195 - }, - { - "dimension_values": [ - "Bangalore, Karnataka" - ], - "value": 195 - }, - { - "dimension_values": [ - "Nairobi, Nairobi" - ], - "value": 50 - }, - { - "dimension_values": [ - "Johannesburg, Gauteng" - ], - "value": 50 - }, - { - "dimension_values": [ - "Hyderabad, Telangana" - ], - "value": 49 - } - ] + "dimension_keys": ["city"], + "results": [ + {"dimension_values": ["London, England"], "value": 263}, + {"dimension_values": ["Sydney, New South Wales"], "value": 467}, + {"dimension_values": ["Algiers, Algiers Province"], "value": 58}, + {"dimension_values": ["Casablanca, Grand Casablanca"], "value": 71}, + {"dimension_values": ["São Paulo, São Paulo (state)"], "value": 139}, + {"dimension_values": ["Rio de Janeiro, Rio de Janeiro (state)"], "value": 44}, + {"dimension_values": ["Perth, Western Australia"], "value": 180}, + {"dimension_values": ["Berlin, Berlin"], "value": 47}, + {"dimension_values": ["Kolkata, West Bengal"], "value": 85}, + {"dimension_values": ["Phoenix, Arizona"], "value": 39}, + {"dimension_values": ["Lagos, Lagos State"], "value": 40}, + {"dimension_values": ["Dublin, Dublin"], "value": 65}, + {"dimension_values": ["Pune, Maharashtra"], "value": 72}, + {"dimension_values": ["Wollongong, New South Wales"], "value": 43}, + {"dimension_values": ["Christchurch, Canterbury"], "value": 42}, + {"dimension_values": ["Jakarta, Jakarta"], "value": 46}, + {"dimension_values": ["Pretoria, Gauteng"], "value": 54}, + {"dimension_values": ["Buenos Aires, Ciudad Autónoma de Buenos Aires"], "value": 41}, + {"dimension_values": ["Gold Coast, Queensland"], "value": 98}, + {"dimension_values": ["Sunshine Coast, Queensland"], "value": 37}, + {"dimension_values": ["Melbourne, Victoria"], "value": 338}, + {"dimension_values": ["Gurugram, Haryana"], "value": 52}, + {"dimension_values": ["Delhi, Delhi"], "value": 194}, + {"dimension_values": ["Los Angeles, California"], "value": 66}, + {"dimension_values": ["Madrid, Comunidad de Madrid"], "value": 65}, + {"dimension_values": ["Lahore, Punjab"], "value": 41}, + {"dimension_values": ["Brisbane, Queensland"], "value": 160}, + {"dimension_values": ["Adelaide, South Australia"], "value": 93}, + {"dimension_values": ["Canberra, Australian Capital Territory"], "value": 45}, + {"dimension_values": ["Lima, Lima Region"], "value": 43}, + {"dimension_values": ["Istanbul, Istanbul Province"], "value": 57}, + {"dimension_values": ["Toronto, Ontario"], "value": 40}, + {"dimension_values": ["Chennai, Tamil Nadu"], "value": 82}, + {"dimension_values": ["Mexico City, Distrito Federal"], "value": 66}, + {"dimension_values": ["Auckland, Auckland Region"], "value": 98}, + {"dimension_values": ["Cape Town, Western Cape"], "value": 172}, + {"dimension_values": ["New York, New York"], "value": 139}, + {"dimension_values": ["Cairo, Cairo Governorate"], "value": 45}, + {"dimension_values": ["Dubai, Dubai"], "value": 57}, + {"dimension_values": ["Santiago, Santiago Metropolitan Region"], "value": 73}, + {"dimension_values": ["Mumbai, Maharashtra"], "value": 195}, + {"dimension_values": ["Bangalore, Karnataka"], "value": 195}, + {"dimension_values": ["Nairobi, Nairobi"], "value": 50}, + {"dimension_values": ["Johannesburg, Gauteng"], "value": 50}, + {"dimension_values": ["Hyderabad, Telangana"], "value": 49}, + ], } - ] - }, - "id": "17841457631192237/insights/follower_demographics/lifetime" - } + ] + }, + "id": "17841457631192237/insights/follower_demographics/lifetime", +} expected_breakdown_record_transformed = { "name": "follower_demographics", @@ -379,153 +128,121 @@ "title": "Follower demographics", "description": "The demographic characteristics of followers, including countries, cities and gender distribution.", "value": { - "London, England": 263, - "Sydney, New South Wales": 467, - "Algiers, Algiers Province": 58, - "Casablanca, Grand Casablanca": 71, - "São Paulo, São Paulo (state)": 139, - "Rio de Janeiro, Rio de Janeiro (state)": 44, - "Perth, Western Australia": 180, - "Berlin, Berlin": 47, - "Kolkata, West Bengal": 85, - "Phoenix, Arizona": 39, - "Lagos, Lagos State": 40, - "Dublin, Dublin": 65, - "Pune, Maharashtra": 72, - "Wollongong, New South Wales": 43, - "Christchurch, Canterbury": 42, - "Jakarta, Jakarta": 46, - "Pretoria, Gauteng": 54, - "Buenos Aires, Ciudad Autónoma de Buenos Aires": 41, - "Gold Coast, Queensland": 98, - "Sunshine Coast, Queensland": 37, - "Melbourne, Victoria": 338, - "Gurugram, Haryana": 52, - "Delhi, Delhi": 194, - "Los Angeles, California": 66, - "Madrid, Comunidad de Madrid": 65, - "Lahore, Punjab": 41, - "Brisbane, Queensland": 160, - "Adelaide, South Australia": 93, - "Canberra, Australian Capital Territory": 45, - "Lima, Lima Region": 43, - "Istanbul, Istanbul Province": 57, - "Toronto, Ontario": 40, - "Chennai, Tamil Nadu": 82, - "Mexico City, Distrito Federal": 66, - "Auckland, Auckland Region": 98, - "Cape Town, Western Cape": 172, - "New York, New York": 139, - "Cairo, Cairo Governorate": 45, - "Dubai, Dubai": 57, - "Santiago, Santiago Metropolitan Region": 73, - "Mumbai, Maharashtra": 195, - "Bangalore, Karnataka": 195, - "Nairobi, Nairobi": 50, - "Johannesburg, Gauteng": 50, - "Hyderabad, Telangana": 49 + "London, England": 263, + "Sydney, New South Wales": 467, + "Algiers, Algiers Province": 58, + "Casablanca, Grand Casablanca": 71, + "São Paulo, São Paulo (state)": 139, + "Rio de Janeiro, Rio de Janeiro (state)": 44, + "Perth, Western Australia": 180, + "Berlin, Berlin": 47, + "Kolkata, West Bengal": 85, + "Phoenix, Arizona": 39, + "Lagos, Lagos State": 40, + "Dublin, Dublin": 65, + "Pune, Maharashtra": 72, + "Wollongong, New South Wales": 43, + "Christchurch, Canterbury": 42, + "Jakarta, Jakarta": 46, + "Pretoria, Gauteng": 54, + "Buenos Aires, Ciudad Autónoma de Buenos Aires": 41, + "Gold Coast, Queensland": 98, + "Sunshine Coast, Queensland": 37, + "Melbourne, Victoria": 338, + "Gurugram, Haryana": 52, + "Delhi, Delhi": 194, + "Los Angeles, California": 66, + "Madrid, Comunidad de Madrid": 65, + "Lahore, Punjab": 41, + "Brisbane, Queensland": 160, + "Adelaide, South Australia": 93, + "Canberra, Australian Capital Territory": 45, + "Lima, Lima Region": 43, + "Istanbul, Istanbul Province": 57, + "Toronto, Ontario": 40, + "Chennai, Tamil Nadu": 82, + "Mexico City, Distrito Federal": 66, + "Auckland, Auckland Region": 98, + "Cape Town, Western Cape": 172, + "New York, New York": 139, + "Cairo, Cairo Governorate": 45, + "Dubai, Dubai": 57, + "Santiago, Santiago Metropolitan Region": 73, + "Mumbai, Maharashtra": 195, + "Bangalore, Karnataka": 195, + "Nairobi, Nairobi": 50, + "Johannesburg, Gauteng": 50, + "Hyderabad, Telangana": 49, }, - "id": "17841457631192237/insights/follower_demographics/lifetime" - } + "id": "17841457631192237/insights/follower_demographics/lifetime", +} insights_record = { "data": [ - { - "name": "comments", - "period": "lifetime", - "values": [ - { - "value": 7 - } - ], - "title": "title1", - "description": "Description1.", - "id": "insta_id/insights/comments/lifetime" - }, - { - "name": "ig_reels_avg_watch_time", - "period": "lifetime", - "values": [ - { - "value": 11900 - } - ], - "title": "2", - "description": "Description2.", - "id": "insta_id/insights/ig_reels_avg_watch_time/lifetime" - }, - { - "name": "ig_reels_video_view_total_time", - "period": "lifetime", - "values": [ - { - "value": 25979677 - } - ], - "title": "title3", - "description": "Description3.", - "id": "insta_id/insights/ig_reels_video_view_total_time/lifetime" - }, - { - "name": "likes", - "period": "lifetime", - "values": [ - { - "value": 102 - } - ], - "title": "title4", - "description": "Description4.", - "id": "insta_id/insights/likes/lifetime" - }, - { - "name": "plays", - "period": "lifetime", - "values": [ - { - "value": 2176 - } - ], - "title": "title5", - "description": "Description5.", - "id": "insta_id/insights/plays/lifetime" - }, - { - "name": "reach", - "period": "lifetime", - "values": [ - { - "value": 1842 - } - ], - "title": "title6", - "description": "Description6.", - "id": "insta_id/insights/reach/lifetime" - }, - { - "name": "saved", - "period": "lifetime", - "values": [ - { - "value": 7 - } - ], - "title": "title7", - "description": "Description7.", - "id": "insta_id/insights/saved/lifetime" - }, - { - "name": "shares", - "period": "lifetime", - "values": [ - { - "value": 1 - } - ], - "title": "title8", - "description": "Description8.", - "id": "insta_id/insights/shares/lifetime" - } + { + "name": "comments", + "period": "lifetime", + "values": [{"value": 7}], + "title": "title1", + "description": "Description1.", + "id": "insta_id/insights/comments/lifetime", + }, + { + "name": "ig_reels_avg_watch_time", + "period": "lifetime", + "values": [{"value": 11900}], + "title": "2", + "description": "Description2.", + "id": "insta_id/insights/ig_reels_avg_watch_time/lifetime", + }, + { + "name": "ig_reels_video_view_total_time", + "period": "lifetime", + "values": [{"value": 25979677}], + "title": "title3", + "description": "Description3.", + "id": "insta_id/insights/ig_reels_video_view_total_time/lifetime", + }, + { + "name": "likes", + "period": "lifetime", + "values": [{"value": 102}], + "title": "title4", + "description": "Description4.", + "id": "insta_id/insights/likes/lifetime", + }, + { + "name": "plays", + "period": "lifetime", + "values": [{"value": 2176}], + "title": "title5", + "description": "Description5.", + "id": "insta_id/insights/plays/lifetime", + }, + { + "name": "reach", + "period": "lifetime", + "values": [{"value": 1842}], + "title": "title6", + "description": "Description6.", + "id": "insta_id/insights/reach/lifetime", + }, + { + "name": "saved", + "period": "lifetime", + "values": [{"value": 7}], + "title": "title7", + "description": "Description7.", + "id": "insta_id/insights/saved/lifetime", + }, + { + "name": "shares", + "period": "lifetime", + "values": [{"value": 1}], + "title": "title8", + "description": "Description8.", + "id": "insta_id/insights/shares/lifetime", + }, ] } diff --git a/airbyte-integrations/connectors/source-instagram/unit_tests/test_source.py b/airbyte-integrations/connectors/source-instagram/unit_tests/test_source.py index 4f371e0fc9cf..e1bcacfc5dc7 100644 --- a/airbyte-integrations/connectors/source-instagram/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-instagram/unit_tests/test_source.py @@ -5,6 +5,8 @@ import logging +from source_instagram.source import SourceInstagram + from airbyte_cdk.connector_builder.connector_builder_handler import resolve_manifest from airbyte_cdk.models import ( AirbyteStream, @@ -14,7 +16,7 @@ DestinationSyncMode, SyncMode, ) -from source_instagram.source import SourceInstagram + logger = logging.getLogger("airbyte") @@ -24,23 +26,11 @@ account_url_response = { - "data": [ - { - "id": "page_id", - "name": "Airbyte", - "instagram_business_account": { - "id": "instagram_business_account_id" - } - } - ], - "paging": { - "cursors": { - "before": "before", - "after": "after" - } - } + "data": [{"id": "page_id", "name": "Airbyte", "instagram_business_account": {"id": "instagram_business_account_id"}}], + "paging": {"cursors": {"before": "before", "after": "after"}}, } + def test_check_connection_ok(api, requests_mock, some_config): requests_mock.register_uri("GET", account_url, [{"json": account_url_response}]) ok, error_msg = SourceInstagram().check_connection(logger, config=some_config) diff --git a/airbyte-integrations/connectors/source-instagram/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-instagram/unit_tests/test_streams.py index 58fe97e5002f..74fc74357524 100644 --- a/airbyte-integrations/connectors/source-instagram/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-instagram/unit_tests/test_streams.py @@ -6,11 +6,13 @@ from unittest.mock import MagicMock import pytest -from airbyte_cdk.models import SyncMode from facebook_business import FacebookAdsApi, FacebookSession from source_instagram.streams import DatetimeTransformerMixin, InstagramStream, UserInsights from utils import read_full_refresh, read_incremental +from airbyte_cdk.models import SyncMode + + FB_API_VERSION = FacebookAdsApi.API_VERSION @@ -30,7 +32,6 @@ def test_state_is_not_outdated(api, config): assert not UserInsights(api=api, start_date=config["start_date"])._state_has_legacy_format({"state": {}}) - def test_user_insights_read(api, config, user_insight_data, requests_mock): test_id = "test_id" @@ -42,7 +43,6 @@ def test_user_insights_read(api, config, user_insight_data, requests_mock): assert records - @pytest.mark.parametrize( "values,slice_dates,expected", [ diff --git a/airbyte-integrations/connectors/source-instatus/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-instatus/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-instatus/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-instatus/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-instatus/main.py b/airbyte-integrations/connectors/source-instatus/main.py index 0e0c5af556b5..e2352fc98eb1 100644 --- a/airbyte-integrations/connectors/source-instatus/main.py +++ b/airbyte-integrations/connectors/source-instatus/main.py @@ -4,5 +4,6 @@ from source_instatus.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-instatus/metadata.yaml b/airbyte-integrations/connectors/source-instatus/metadata.yaml index 59608bdc8b43..4467e8e68a4c 100644 --- a/airbyte-integrations/connectors/source-instatus/metadata.yaml +++ b/airbyte-integrations/connectors/source-instatus/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 1901024c-0249-45d0-bcac-31a954652927 - dockerImageTag: 0.1.23 + dockerImageTag: 0.1.28 dockerRepository: airbyte/source-instatus githubIssueLabel: source-instatus icon: instatus.svg @@ -42,5 +42,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-instatus/poetry.lock b/airbyte-integrations/connectors/source-instatus/poetry.lock index 711efc8fb7ce..67d96c050603 100644 --- a/airbyte-integrations/connectors/source-instatus/poetry.lock +++ b/airbyte-integrations/connectors/source-instatus/poetry.lock @@ -42,13 +42,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] @@ -56,24 +56,24 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -88,19 +88,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -166,13 +166,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -256,116 +256,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -435,20 +422,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -498,13 +485,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -519,13 +506,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -533,7 +520,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -583,13 +569,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -679,22 +665,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -767,69 +756,86 @@ files = [ [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -932,54 +938,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -991,13 +997,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1285,33 +1291,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1378,13 +1384,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1409,81 +1415,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-instatus/pyproject.toml b/airbyte-integrations/connectors/source-instatus/pyproject.toml index a9411d6f8839..6a2a201b0ce4 100644 --- a/airbyte-integrations/connectors/source-instatus/pyproject.toml +++ b/airbyte-integrations/connectors/source-instatus/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.23" +version = "0.1.28" name = "source-instatus" description = "Source implementation for Instatus." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-instatus/source_instatus/components.py b/airbyte-integrations/connectors/source-instatus/source_instatus/components.py index 62c6561c19cb..e589d1f07bb4 100644 --- a/airbyte-integrations/connectors/source-instatus/source_instatus/components.py +++ b/airbyte-integrations/connectors/source-instatus/source_instatus/components.py @@ -6,6 +6,7 @@ from typing import Any, Iterable, List, Mapping, Optional import dpath.util + from airbyte_cdk.models import AirbyteMessage, SyncMode, Type from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig, SubstreamPartitionRouter from airbyte_cdk.sources.declarative.transformations import AddFields diff --git a/airbyte-integrations/connectors/source-instatus/source_instatus/run.py b/airbyte-integrations/connectors/source-instatus/source_instatus/run.py index ade50f0a9cdd..ccf55560c448 100644 --- a/airbyte-integrations/connectors/source-instatus/source_instatus/run.py +++ b/airbyte-integrations/connectors/source-instatus/source_instatus/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_instatus import SourceInstatus +from airbyte_cdk.entrypoint import launch + def run(): source = SourceInstatus() diff --git a/airbyte-integrations/connectors/source-instatus/source_instatus/source.py b/airbyte-integrations/connectors/source-instatus/source_instatus/source.py index dda77f207308..2f076f8e1f26 100644 --- a/airbyte-integrations/connectors/source-instatus/source_instatus/source.py +++ b/airbyte-integrations/connectors/source-instatus/source_instatus/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-instatus/unit_tests/test_components.py b/airbyte-integrations/connectors/source-instatus/unit_tests/test_components.py index f09c7ff5e83e..7f6d4b9ceb85 100644 --- a/airbyte-integrations/connectors/source-instatus/unit_tests/test_components.py +++ b/airbyte-integrations/connectors/source-instatus/unit_tests/test_components.py @@ -5,10 +5,11 @@ from unittest.mock import MagicMock import pytest +from source_instatus.components import ListAddFields, UpdatesSubstreamPartitionRouter + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString from airbyte_cdk.sources.declarative.transformations.add_fields import AddedFieldDefinition -from source_instatus.components import ListAddFields, UpdatesSubstreamPartitionRouter @pytest.mark.parametrize( diff --git a/airbyte-integrations/connectors/source-intercom/README.md b/airbyte-integrations/connectors/source-intercom/README.md index 258f2dd41d78..da0194c9aab1 100644 --- a/airbyte-integrations/connectors/source-intercom/README.md +++ b/airbyte-integrations/connectors/source-intercom/README.md @@ -1,49 +1,22 @@ # Intercom source connector -This is the repository for the Intercom source connector, written in Python. -For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.com/integrations/sources/intercom). +This directory contains the manifest-only connector for `source-intercom`. +This _manifest-only_ connector is not a Python package on its own, as it runs inside of the base `source-declarative-manifest` image. -## Local development - -### Prerequisites - -- Python (~=3.9) -- Poetry (~=1.7) - installation instructions [here](https://python-poetry.org/docs/#installation) - -### Installing the connector - -From this connector directory, run: - -```bash -poetry install --with dev -``` - -### Create credentials +For information about how to configure and use this connector within Airbyte, see [the connector's full documentation](https://docs.airbyte.com/integrations/sources/intercom). -**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/intercom) -to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_intercom/spec.yaml` file. -Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. -See `sample_files/sample_config.json` for a sample config file. - -### Locally running the connector - -``` -poetry run source-intercom spec -poetry run source-intercom check --config secrets/config.json -poetry run source-intercom discover --config secrets/config.json -poetry run source-intercom read --config secrets/config.json --catalog integration_tests/configured_catalog.json -``` +## Local development -### Running unit tests +We recommend using the Connector Builder to edit this connector. +Using either Airbyte Cloud or your local Airbyte OSS instance, navigate to the **Builder** tab and select **Import a YAML**. +Then select the connector's `manifest.yaml` file to load the connector into the Builder. You're now ready to make changes to the connector! -To run unit tests locally, from the connector directory run: - -``` -poetry run pytest unit_tests -``` +If you prefer to develop locally, you can follow the instructions below. ### Building the docker image +You can build any manifest-only connector with `airbyte-ci`: + 1. Install [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md) 2. Run the following command to build the docker image: @@ -53,18 +26,24 @@ airbyte-ci connectors --name=source-intercom build An image will be available on your host with the tag `airbyte/source-intercom:dev`. +### Creating credentials + +**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/intercom) +to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `spec` object in the connector's `manifest.yaml` file. +Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. + ### Running as a docker container -Then run any of the connector commands as follows: +Then run any of the standard source connector commands: -``` +```bash docker run --rm airbyte/source-intercom:dev spec docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-intercom:dev check --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-intercom:dev discover --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-intercom:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json ``` -### Running our CI test suite +### Running the CI test suite You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): @@ -72,33 +51,15 @@ You can run our full test suite locally using [`airbyte-ci`](https://github.com/ airbyte-ci connectors --name=source-intercom test ``` -### Customizing acceptance Tests - -Customize `acceptance-test-config.yml` file to configure acceptance tests. See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) for more information. -If your connector requires to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py. - -### Dependency Management - -All of your dependencies should be managed via Poetry. -To add a new dependency, run: - -```bash -poetry add -``` - -Please commit the changes to `pyproject.toml` and `poetry.lock` files. - ## Publishing a new version of the connector -You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what? - -1. Make sure your changes are passing our test suite: `airbyte-ci connectors --name=source-intercom test` -2. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): - - bump the `dockerImageTag` value in in `metadata.yaml` - - bump the `version` value in `pyproject.toml` -3. Make sure the `metadata.yaml` content is up to date. +If you want to contribute changes to `source-intercom`, here's how you can do that: +1. Make your changes locally, or load the connector's manifest into Connector Builder and make changes there. +2. Make sure your changes are passing our test suite with `airbyte-ci connectors --name=source-intercom test` +3. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): + - bump the `dockerImageTag` value in in `metadata.yaml` 4. Make sure the connector documentation and its changelog is up to date (`docs/integrations/sources/intercom.md`). 5. Create a Pull Request: use [our PR naming conventions](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#pull-request-title-convention). 6. Pat yourself on the back for being an awesome contributor. 7. Someone from Airbyte will take a look at your PR and iterate with you to merge it into master. -8. Once your PR is merged, the new version of the connector will be automatically published to Docker Hub and our connector registry. +8. Once your PR is merged, the new version of the connector will be automatically published to Docker Hub and our connector registry. \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-intercom/acceptance-test-config.yml b/airbyte-integrations/connectors/source-intercom/acceptance-test-config.yml index 37dd822467c7..bbcd393ac644 100644 --- a/airbyte-integrations/connectors/source-intercom/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-intercom/acceptance-test-config.yml @@ -5,7 +5,7 @@ test_strictness_level: high acceptance_tests: spec: tests: - - spec_path: "source_intercom/spec.json" + - spec_path: "manifest.yaml" connection: tests: - config_path: "secrets/config.json" @@ -20,6 +20,9 @@ acceptance_tests: - config_path: "secrets/config.json" expect_records: path: "integration_tests/expected_records.jsonl" + empty_streams: + - name: conversation_parts + bypass_reason: Deeply nested response which could not be seeded with sandbox incremental: tests: - config_path: "secrets/config.json" diff --git a/airbyte-integrations/connectors/source-intercom/components.py b/airbyte-integrations/connectors/source-intercom/components.py new file mode 100644 index 000000000000..76de447344c9 --- /dev/null +++ b/airbyte-integrations/connectors/source-intercom/components.py @@ -0,0 +1,376 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +from dataclasses import InitVar, dataclass, field +from functools import wraps +from time import sleep +from typing import Any, Iterable, List, Mapping, Optional, Union + +import requests + +from airbyte_cdk.models import SyncMode +from airbyte_cdk.sources.declarative.incremental import DeclarativeCursor +from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString +from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig +from airbyte_cdk.sources.declarative.requesters.error_handlers import DefaultErrorHandler +from airbyte_cdk.sources.declarative.requesters.request_option import RequestOptionType +from airbyte_cdk.sources.declarative.types import Config, Record, StreamSlice, StreamState +from airbyte_cdk.sources.streams.core import Stream +from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution + + +RequestInput = Union[str, Mapping[str, str]] + + +@dataclass +class IncrementalSingleSliceCursor(DeclarativeCursor): + cursor_field: Union[InterpolatedString, str] + config: Config + parameters: InitVar[Mapping[str, Any]] + + def __post_init__(self, parameters: Mapping[str, Any]): + self._state = {} + self._cursor = None + self.cursor_field = InterpolatedString.create(self.cursor_field, parameters=parameters) + + def get_request_params( + self, + stream_state: Optional[StreamState] = None, + stream_slice: Optional[StreamSlice] = None, + next_page_token: Optional[Mapping[str, Any]] = None, + ) -> Mapping[str, Any]: + # Current implementation does not provide any options to update request params. + # Returns empty dict + return self._get_request_option(RequestOptionType.request_parameter, stream_slice) + + def get_request_headers( + self, + stream_state: Optional[StreamState] = None, + stream_slice: Optional[StreamSlice] = None, + next_page_token: Optional[Mapping[str, Any]] = None, + ) -> Mapping[str, Any]: + # Current implementation does not provide any options to update request headers. + # Returns empty dict + return self._get_request_option(RequestOptionType.header, stream_slice) + + def get_request_body_data( + self, + stream_state: Optional[StreamState] = None, + stream_slice: Optional[StreamSlice] = None, + next_page_token: Optional[Mapping[str, Any]] = None, + ) -> Mapping[str, Any]: + # Current implementation does not provide any options to update body data. + # Returns empty dict + return self._get_request_option(RequestOptionType.body_data, stream_slice) + + def get_request_body_json( + self, + stream_state: Optional[StreamState] = None, + stream_slice: Optional[StreamSlice] = None, + next_page_token: Optional[Mapping[str, Any]] = None, + ) -> Optional[Mapping]: + # Current implementation does not provide any options to update body json. + # Returns empty dict + return self._get_request_option(RequestOptionType.body_json, stream_slice) + + def _get_request_option(self, option_type: RequestOptionType, stream_slice: StreamSlice): + return {} + + def get_stream_state(self) -> StreamState: + return self._state + + def select_state(self, stream_slice: Optional[StreamSlice] = None) -> Optional[StreamState]: + return self.get_stream_state() + + def set_initial_state(self, stream_state: StreamState): + cursor_field = self.cursor_field.eval(self.config) + cursor_value = stream_state.get(cursor_field) + if cursor_value: + self._state[cursor_field] = cursor_value + self._state["prior_state"] = self._state.copy() + self._cursor = cursor_value + + def observe(self, stream_slice: StreamSlice, record: Record) -> None: + """ + Register a record with the cursor; the cursor instance can then use it to manage the state of the in-progress stream read. + + :param stream_slice: The current slice, which may or may not contain the most recently observed record + :param record: the most recently-read record, which the cursor can use to update the stream state. Outwardly-visible changes to the + stream state may need to be deferred depending on whether the source reliably orders records by the cursor field. + """ + record_cursor_value = record.get(self.cursor_field.eval(self.config)) + if not record_cursor_value: + return + + if self.is_greater_than_or_equal(record, self._state): + self._cursor = record_cursor_value + + def close_slice(self, stream_slice: StreamSlice, *args: Any) -> None: + cursor_field = self.cursor_field.eval(self.config) + self._state[cursor_field] = self._cursor + + def stream_slices(self) -> Iterable[Mapping[str, Any]]: + yield StreamSlice(partition={}, cursor_slice={}) + + def should_be_synced(self, record: Record) -> bool: + """ + Evaluating if a record should be synced allows for filtering and stop condition on pagination + """ + record_cursor_value = record.get(self.cursor_field.eval(self.config)) + return bool(record_cursor_value) + + def is_greater_than_or_equal(self, first: Record, second: Record) -> bool: + """ + Evaluating which record is greater in terms of cursor. This is used to avoid having to capture all the records to close a slice + """ + cursor_field = self.cursor_field.eval(self.config) + first_cursor_value = first.get(cursor_field) if first else None + second_cursor_value = second.get(cursor_field) if second else None + if first_cursor_value and second_cursor_value: + return first_cursor_value > second_cursor_value + elif first_cursor_value: + return True + else: + return False + + +@dataclass +class IncrementalSubstreamSlicerCursor(IncrementalSingleSliceCursor): + parent_stream_configs: List[ParentStreamConfig] + parent_complete_fetch: bool = field(default=False) + + def __post_init__(self, parameters: Mapping[str, Any]): + super().__post_init__(parameters) + + if not self.parent_stream_configs: + raise ValueError("IncrementalSubstreamSlicer needs at least 1 parent stream") + + # parent stream parts + self.parent_config: ParentStreamConfig = self.parent_stream_configs[0] + self.parent_stream: Stream = self.parent_config.stream + self.parent_stream_name: str = self.parent_stream.name + self.parent_cursor_field: str = self.parent_stream.cursor_field + self.parent_sync_mode: SyncMode = SyncMode.incremental if self.parent_stream.supports_incremental is True else SyncMode.full_refresh + self.substream_slice_field: str = self.parent_stream_configs[0].partition_field.eval(self.config) + self.parent_field: str = self.parent_stream_configs[0].parent_key.eval(self.config) + self._parent_cursor: Optional[str] = None + + def set_initial_state(self, stream_state: StreamState): + super().set_initial_state(stream_state=stream_state) + if self.parent_stream_name in stream_state and stream_state.get(self.parent_stream_name, {}).get(self.parent_cursor_field): + parent_stream_state = { + self.parent_cursor_field: stream_state[self.parent_stream_name][self.parent_cursor_field], + } + self._state[self.parent_stream_name] = parent_stream_state + if "prior_state" in self._state: + self._state["prior_state"][self.parent_stream_name] = parent_stream_state + + def observe(self, stream_slice: StreamSlice, record: Record) -> None: + """ + Extended the default method to be able to track the parent STATE. + """ + + # save parent cursor value (STATE) from slice + parent_cursor = stream_slice.get(self.parent_stream_name) + if parent_cursor: + self._parent_cursor = parent_cursor.get(self.parent_cursor_field) + + # observe the substream + super().observe(stream_slice, record) + + def close_slice(self, stream_slice: StreamSlice, *args: Any) -> None: + super().close_slice(stream_slice, *args) + + def stream_slices(self) -> Iterable[Mapping[str, Any]]: + parent_state = (self._state or {}).get(self.parent_stream_name, {}) + slices_generator: Iterable[StreamSlice] = self.read_parent_stream(self.parent_sync_mode, self.parent_cursor_field, parent_state) + yield from [slice for slice in slices_generator] if self.parent_complete_fetch else slices_generator + + def track_parent_cursor(self, parent_record: dict) -> None: + """ + Tracks the Parent Stream Cursor, using `parent_cursor_field`. + """ + self._parent_cursor = parent_record.get(self.parent_cursor_field) + if self._parent_cursor: + self._state[self.parent_stream_name] = {self.parent_cursor_field: self._parent_cursor} + + def read_parent_stream( + self, + sync_mode: SyncMode, + cursor_field: Optional[str], + stream_state: Mapping[str, Any], + ) -> Iterable[Mapping[str, Any]]: + self.parent_stream.state = stream_state + + parent_stream_slices_gen = self.parent_stream.stream_slices( + sync_mode=sync_mode, + cursor_field=cursor_field, + stream_state=stream_state, + ) + + for parent_slice in parent_stream_slices_gen: + parent_records_gen = self.parent_stream.read_records( + sync_mode=sync_mode, + cursor_field=cursor_field, + stream_slice=parent_slice, + stream_state=stream_state, + ) + + for parent_record in parent_records_gen: + # update parent cursor + self.track_parent_cursor(parent_record) + substream_slice_value = parent_record.get(self.parent_field) + if substream_slice_value: + cursor_field = self.cursor_field.eval(self.config) + substream_cursor_value = self._state.get(cursor_field) + parent_cursor_value = self._state.get(self.parent_stream_name, {}).get(self.parent_cursor_field) + yield StreamSlice( + partition={ + self.substream_slice_field: substream_slice_value, + }, + cursor_slice={ + cursor_field: substream_cursor_value, + self.parent_stream_name: { + self.parent_cursor_field: parent_cursor_value, + }, + }, + ) + + +@dataclass +class IntercomRateLimiter: + """ + Define timings for RateLimits. Adjust timings if needed. + :: on_unknown_load = 1.0 sec - Intercom recommended time to hold between each API call. + :: on_low_load = 0.01 sec (10 miliseconds) - ideal ratio between hold time and api call, also the standard hold time between each API call. + :: on_mid_load = 1.5 sec - great timing to retrieve another 15% of request capacity while having mid_load. + :: on_high_load = 8.0 sec - ideally we should wait 5.0 sec while having high_load, but we hold 8 sec to retrieve up to 80% of request capacity. + """ + + threshold: float = 0.1 + on_unknown_load: float = 1.0 + on_low_load: float = 0.01 + on_mid_load: float = 1.5 + on_high_load: float = 8.0 # max time + + @staticmethod + def backoff_time(backoff_time: float): + return sleep(backoff_time) + + @staticmethod + def _define_values_from_headers( + current_rate_header_value: Optional[float], + total_rate_header_value: Optional[float], + threshold: float = threshold, + ) -> tuple[float, Union[float, str]]: + # define current load and cutoff from rate_limits + if current_rate_header_value and total_rate_header_value: + cutoff: float = (total_rate_header_value / 2) / total_rate_header_value + load: float = current_rate_header_value / total_rate_header_value + else: + # to guarantee cutoff value to be exactly 1 sec, based on threshold, if headers are not available + cutoff: float = threshold * (1 / threshold) + load = None + return cutoff, load + + @staticmethod + def _convert_load_to_backoff_time( + cutoff: float, + load: Optional[float] = None, + threshold: float = threshold, + ) -> float: + # define backoff_time based on load conditions + if not load: + backoff_time = IntercomRateLimiter.on_unknown_load + elif load <= threshold: + backoff_time = IntercomRateLimiter.on_high_load + elif load <= cutoff: + backoff_time = IntercomRateLimiter.on_mid_load + elif load > cutoff: + backoff_time = IntercomRateLimiter.on_low_load + return backoff_time + + @staticmethod + def get_backoff_time( + *args, + threshold: float = threshold, + rate_limit_header: str = "X-RateLimit-Limit", + rate_limit_remain_header: str = "X-RateLimit-Remaining", + ): + """ + To avoid reaching Intercom API Rate Limits, use the 'X-RateLimit-Limit','X-RateLimit-Remaining' header values, + to determine the current rate limits and load and handle backoff_time based on load %. + Recomended backoff_time between each request is 1 sec, we would handle this dynamicaly. + :: threshold - is the % cutoff for the rate_limits % load, if this cutoff is crossed, + the connector waits `sleep_on_high_load` amount of time, default value = 0.1 (10% left from max capacity) + :: backoff_time - time between each request = 200 miliseconds + :: rate_limit_header - responce header item, contains information with max rate_limits available (max) + :: rate_limit_remain_header - responce header item, contains information with how many requests are still available (current) + Header example: + { + X-RateLimit-Limit: 100 + X-RateLimit-Remaining: 51 + X-RateLimit-Reset: 1487332510 + }, + where: 51 - requests remains and goes down, 100 - max requests capacity. + More information: https://developers.intercom.com/intercom-api-reference/reference/rate-limiting + """ + + # find the requests.Response inside args list + for arg in args: + if isinstance(arg, requests.models.Response): + headers = arg.headers or {} + + # Get the rate_limits from response + total_rate = int(headers.get(rate_limit_header, 0)) if headers else None + current_rate = int(headers.get(rate_limit_remain_header, 0)) if headers else None + cutoff, load = IntercomRateLimiter._define_values_from_headers( + current_rate_header_value=current_rate, + total_rate_header_value=total_rate, + threshold=threshold, + ) + + backoff_time = IntercomRateLimiter._convert_load_to_backoff_time(cutoff=cutoff, load=load, threshold=threshold) + return backoff_time + + @staticmethod + def balance_rate_limit( + threshold: float = threshold, + rate_limit_header: str = "X-RateLimit-Limit", + rate_limit_remain_header: str = "X-RateLimit-Remaining", + ): + """ + The decorator function. + Adjust `threshold`,`rate_limit_header`,`rate_limit_remain_header` if needed. + """ + + def decorator(func): + @wraps(func) + def wrapper_balance_rate_limit(*args, **kwargs): + IntercomRateLimiter.backoff_time( + IntercomRateLimiter.get_backoff_time( + *args, threshold=threshold, rate_limit_header=rate_limit_header, rate_limit_remain_header=rate_limit_remain_header + ) + ) + return func(*args, **kwargs) + + return wrapper_balance_rate_limit + + return decorator + + +class ErrorHandlerWithRateLimiter(DefaultErrorHandler): + """ + The difference between the built-in `DefaultErrorHandler` and this one is the custom decorator, + applied on top of `interpret_response` to preserve the api calls for a defined amount of time, + calculated using the rate limit headers and not use the custom backoff strategy, + since we deal with Response.status_code == 200, + the default requester's logic doesn't allow to handle the status of 200 with `should_retry()`. + """ + + # The RateLimiter is applied to balance the api requests. + @IntercomRateLimiter.balance_rate_limit() + def interpret_response(self, response_or_exception: Optional[Union[requests.Response, Exception]]) -> ErrorResolution: + # Check for response.headers to define the backoff time before the next api call + return super().interpret_response(response_or_exception) diff --git a/airbyte-integrations/connectors/source-intercom/integration_tests/abnormal_state.json b/airbyte-integrations/connectors/source-intercom/integration_tests/abnormal_state.json index e874bc451c67..477d722433d6 100755 --- a/airbyte-integrations/connectors/source-intercom/integration_tests/abnormal_state.json +++ b/airbyte-integrations/connectors/source-intercom/integration_tests/abnormal_state.json @@ -28,10 +28,7 @@ "name": "company_segments" }, "stream_state": { - "updated_at": 7626086649, - "companies": { - "updated_at": 7626086649 - } + "updated_at": 7626086649 } } }, @@ -42,10 +39,7 @@ "name": "conversations" }, "stream_state": { - "updated_at": 7626086649, - "conversations": { - "updated_at": 7626086649 - } + "updated_at": 7626086649 } } }, @@ -56,10 +50,7 @@ "name": "conversation_parts" }, "stream_state": { - "updated_at": 7626086649, - "conversations": { - "updated_at": 7626086649 - } + "updated_at": 7626086649 } } }, diff --git a/airbyte-integrations/connectors/source-intercom/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-intercom/integration_tests/acceptance.py index d49b55882333..a9256a533972 100644 --- a/airbyte-integrations/connectors/source-intercom/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-intercom/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-intercom/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-intercom/integration_tests/expected_records.jsonl index d06ce90f22b7..26538cf32231 100644 --- a/airbyte-integrations/connectors/source-intercom/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-intercom/integration_tests/expected_records.jsonl @@ -28,9 +28,6 @@ {"stream": "conversations", "data": {"type": "conversation", "id": "1", "created_at": 1607553243, "updated_at": 1626346673, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "701718739", "delivered_as": "customer_initiated", "subject": "", "body": "

hey there

", "author": {"type": "lead", "id": "5fd150d50697b6d0bbc4a2c2", "name": null, "email": ""}, "attachments": [], "url": "http://localhost:63342/airbyte-python/airbyte-integrations/bases/base-java/build/tmp/expandedArchives/org.jacoco.agent-0.8.5.jar_6a2df60c47de373ea127d14406367999/about.html?_ijt=uosck1k6vmp2dnl4oqib2g3u9d"}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "5fd150d50697b6d0bbc4a2c2"}]}, "first_contact_reply": {"created_at": 1607553243, "type": "conversation", "url": "http://localhost:63342/airbyte-python/airbyte-integrations/bases/base-java/build/tmp/expandedArchives/org.jacoco.agent-0.8.5.jar_6a2df60c47de373ea127d14406367999/about.html?_ijt=uosck1k6vmp2dnl4oqib2g3u9d"}, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": 4317957, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": 4317954, "first_contact_reply_at": 1607553243, "first_assignment_at": null, "first_admin_reply_at": 1625654131, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": 1607553246, "last_admin_reply_at": 1625656000, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 7}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "assignee": null}, "emitted_at": 1707747714058} {"stream": "conversations", "data": {"type": "conversation", "id": "60", "created_at": 1676461133, "updated_at": 1676461134, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51952871", "delivered_as": "automated", "subject": "", "body": "

Test 3

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea41a0eddb9b625fb712c9"}]}, "first_contact_reply": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "assignee": {"type": "admin", "id": "4423433"}}, "emitted_at": 1707747714064} {"stream": "conversations", "data": {"type": "conversation", "id": "61", "created_at": 1676461196, "updated_at": 1676461197, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51952963", "delivered_as": "automated", "subject": "", "body": "

Test 4

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea41a1b0e17c53248c7956"}]}, "first_contact_reply": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "assignee": {"type": "admin", "id": "4423433"}}, "emitted_at": 1707747714069} -{"stream": "conversation_parts", "data": {"type": "conversation_part", "id": "7288120839", "part_type": "comment", "body": "

is this showing up

", "created_at": 1607553246, "updated_at": 1607553246, "notified_at": 1607553246, "assigned_to": null, "author": {"id": "5fd150d50697b6d0bbc4a2c2", "type": "user", "name": null, "email": ""}, "attachments": [], "external_id": null, "conversation_id": "1"}, "emitted_at": 1707747716219} -{"stream": "conversation_parts", "data": {"type": "conversation_part", "id": "7288121348", "part_type": "comment", "body": "

Airbyte [DEV] will reply as soon as they can.

", "created_at": 1607553249, "updated_at": 1607553249, "notified_at": 1607553249, "assigned_to": null, "author": {"id": "4423434", "type": "bot", "name": "Operator", "email": "operator+wjw5eps7@intercom.io"}, "attachments": [], "external_id": null, "conversation_id": "1"}, "emitted_at": 1707747716222} -{"stream": "conversation_parts", "data": {"type": "conversation_part", "id": "7288121392", "part_type": "comment", "body": "

Give the team a way to reach you:

", "created_at": 1607553250, "updated_at": 1607553250, "notified_at": 1607553250, "assigned_to": null, "author": {"id": "4423434", "type": "bot", "name": "Operator", "email": "operator+wjw5eps7@intercom.io"}, "attachments": [], "external_id": null, "conversation_id": "1"}, "emitted_at": 1707747716225} {"stream": "company_segments", "data": {"type": "segment", "id": "63ea1a19d248071b8d297b39", "name": "Companies less then 100 people", "created_at": 1676286489, "updated_at": 1676461957, "person_type": "user"}, "emitted_at": 1707747722461} {"stream": "company_segments", "data": {"type": "segment", "id": "63eb62f228758099dbc7fabe", "name": "Companies not IT", "created_at": 1676370674, "updated_at": 1676461960, "person_type": "user"}, "emitted_at": 1707747722463} {"stream": "company_segments", "data": {"type": "segment", "id": "63eb63c3046264426ef4bfd6", "name": "Companies tag not 3", "created_at": 1676370883, "updated_at": 1676461915, "person_type": "user"}, "emitted_at": 1707747722465} diff --git a/airbyte-integrations/connectors/source-intercom/main.py b/airbyte-integrations/connectors/source-intercom/main.py deleted file mode 100644 index 410860c90fd8..000000000000 --- a/airbyte-integrations/connectors/source-intercom/main.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from source_intercom.run import run - -if __name__ == "__main__": - run() diff --git a/airbyte-integrations/connectors/source-intercom/manifest.yaml b/airbyte-integrations/connectors/source-intercom/manifest.yaml new file mode 100644 index 000000000000..87b11e536025 --- /dev/null +++ b/airbyte-integrations/connectors/source-intercom/manifest.yaml @@ -0,0 +1,2966 @@ +version: 5.7.0 + +type: DeclarativeSource + +check: + type: CheckStream + stream_names: + - tags + +definitions: + streams: + activity_logs: + type: DeclarativeStream + name: activity_logs + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: admins/activity_logs + http_method: GET + request_headers: + Accept: application/json + Intercom-Version: "2.11" + error_handler: + type: CustomErrorHandler + class_name: source_declarative_manifest.components.ErrorHandlerWithRateLimiter + response_filters: + - type: HttpResponseFilter + action: FAIL + failure_type: config_error + error_message: >- + Failed to perform request. Error: Active subscription needed. + Please, validate your current Intercom plan to continue using + API. + error_message_contains: Active subscription needed + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - activity_logs + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('pages', {}).get('next') }}" + stop_condition: "{{ 'next' not in response.get('pages', {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + lookback_window: P{{ config.get('lookback_window', 0) }}D + cursor_datetime_formats: + - "%s" + datetime_format: "%s" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_at_after + inject_into: request_parameter + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/activity_logs" + admins: + type: DeclarativeStream + description: >- + https://developers.intercom.com/intercom-api-reference/reference#list-admins + name: admins + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: admins + http_method: GET + request_headers: + Accept: application/json + Intercom-Version: "2.11" + error_handler: + type: CustomErrorHandler + class_name: source_declarative_manifest.components.ErrorHandlerWithRateLimiter + response_filters: + - type: HttpResponseFilter + action: FAIL + failure_type: config_error + error_message: >- + Failed to perform request. Error: Active subscription needed. + Please, validate your current Intercom plan to continue using + API. + error_message_contains: Active subscription needed + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - admins + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 150 + cursor_value: "{{ response.get('pages', {}).get('next') }}" + stop_condition: "{{ 'next' not in response.get('pages', {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/admins" + tags: + type: DeclarativeStream + description: >- + https://developers.intercom.com/intercom-api-reference/reference#list-tags-for-an-app + name: tags + primary_key: + - name + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: tags + http_method: GET + request_headers: + Accept: application/json + Intercom-Version: "2.11" + error_handler: + type: CustomErrorHandler + class_name: source_declarative_manifest.components.ErrorHandlerWithRateLimiter + response_filters: + - type: HttpResponseFilter + action: FAIL + failure_type: config_error + error_message: >- + Failed to perform request. Error: Active subscription needed. + Please, validate your current Intercom plan to continue using + API. + error_message_contains: Active subscription needed + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 150 + cursor_value: "{{ response.get('pages', {}).get('next') }}" + stop_condition: "{{ 'next' not in response.get('pages', {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tags" + teams: + type: DeclarativeStream + description: >- + https://developers.intercom.com/intercom-api-reference/reference#list-teams + name: teams + primary_key: + - name + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: teams + http_method: GET + request_headers: + Accept: application/json + Intercom-Version: "2.11" + error_handler: + type: CustomErrorHandler + class_name: source_declarative_manifest.components.ErrorHandlerWithRateLimiter + response_filters: + - type: HttpResponseFilter + action: FAIL + failure_type: config_error + error_message: >- + Failed to perform request. Error: Active subscription needed. + Please, validate your current Intercom plan to continue using + API. + error_message_contains: Active subscription needed + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - teams + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 150 + cursor_value: "{{ response.get('pages', {}).get('next') }}" + stop_condition: "{{ 'next' not in response.get('pages', {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/teams" + segments: + type: DeclarativeStream + description: >- + https://developers.intercom.com/intercom-api-reference/reference#list-segments + name: segments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: segments + http_method: GET + request_headers: + Accept: application/json + Intercom-Version: "2.11" + error_handler: + type: CustomErrorHandler + class_name: source_declarative_manifest.components.ErrorHandlerWithRateLimiter + response_filters: + - type: HttpResponseFilter + action: FAIL + failure_type: config_error + error_message: >- + Failed to perform request. Error: Active subscription needed. + Please, validate your current Intercom plan to continue using + API. + error_message_contains: Active subscription needed + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - segments + record_filter: + type: RecordFilter + condition: >- + {{ record['updated_at'] >= ( stream_state.get('prior_state', + {}).get('updated_at', 0) - (config.get('lookback_window', 0) * + 86400) if stream_state else stream_slice.get('prior_state', + {}).get('updated_at', 0) ) - (config.get('lookback_window', 0) * + 86400) }} + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 150 + cursor_value: "{{ response.get('pages', {}).get('next') }}" + stop_condition: "{{ 'next' not in response.get('pages', {}) }}" + incremental_sync: + type: CustomIncrementalSync + class_name: source_declarative_manifest.components.IncrementalSingleSliceCursor + cursor_field: updated_at + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/segments" + companies: + type: DeclarativeStream + description: >- + https://developers.intercom.com/intercom-api-reference/reference/scroll-over-all-companies + name: companies + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: companies/scroll + http_method: GET + request_headers: + Accept: application/json + Intercom-Version: "2.11" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: RETRY + http_codes: + - 400 + error_message: >- + A scroll (export) job is already in progress for this + Intercom account, causing the request to fail. Only one + active scroll per Intercom account is allowed; + ensure no overlap by limiting active connections or + scheduling jobs appropriately. + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 404 + - type: DefaultErrorHandler + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 60 + response_filters: + - type: HttpResponseFilter + action: RETRY + http_codes: + - 500 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + record_filter: + type: RecordFilter + condition: >- + {{ record['updated_at'] >= ( stream_state.get('prior_state', + {}).get('updated_at', 0) - (config.get('lookback_window', 0) * + 86400) if stream_state else stream_slice.get('prior_state', + {}).get('updated_at', 0) ) - (config.get('lookback_window', 0) * + 86400) }} + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: scroll_param + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 150 + cursor_value: "{{ response.get('scroll_param') }}" + stop_condition: "{{ not response.get('data') }}" + incremental_sync: + type: CustomIncrementalSync + class_name: source_declarative_manifest.components.IncrementalSingleSliceCursor + cursor_field: updated_at + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/companies" + company_attributes: + type: DeclarativeStream + description: >- + https://developers.intercom.com/intercom-api-reference/reference#list-data-attributes + name: company_attributes + primary_key: + - name + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: data_attributes + http_method: GET + request_parameters: + model: company + request_headers: + Accept: application/json + Intercom-Version: "2.11" + error_handler: + type: CustomErrorHandler + class_name: source_declarative_manifest.components.ErrorHandlerWithRateLimiter + response_filters: + - type: HttpResponseFilter + action: FAIL + failure_type: config_error + error_message: >- + Failed to perform request. Error: Active subscription needed. + Please, validate your current Intercom plan to continue using + API. + error_message_contains: Active subscription needed + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 150 + cursor_value: "{{ response.get('pages', {}).get('next') }}" + stop_condition: "{{ 'next' not in response.get('pages', {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/company_attributes" + contact_attributes: + type: DeclarativeStream + description: >- + https://developers.intercom.com/intercom-api-reference/reference#list-data-attributes + name: contact_attributes + primary_key: + - name + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: data_attributes + http_method: GET + request_parameters: + model: contact + request_headers: + Accept: application/json + Intercom-Version: "2.11" + error_handler: + type: CustomErrorHandler + class_name: source_declarative_manifest.components.ErrorHandlerWithRateLimiter + response_filters: + - type: HttpResponseFilter + action: FAIL + failure_type: config_error + error_message: >- + Failed to perform request. Error: Active subscription needed. + Please, validate your current Intercom plan to continue using + API. + error_message_contains: Active subscription needed + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 150 + cursor_value: "{{ response.get('pages', {}).get('next') }}" + stop_condition: "{{ 'next' not in response.get('pages', {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contact_attributes" + contacts: + type: DeclarativeStream + description: >- + https://developers.intercom.com/intercom-api-reference/reference/pagination-sorting-search + name: contacts + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: contacts/search + http_method: POST + request_headers: + Accept: application/json + Intercom-Version: "2.11" + request_body_json: + sort: "{'field': 'updated_at', 'order': 'ascending'}" + query: >- + { 'operator': 'OR', 'value': [ { 'field': 'updated_at', + 'operator': '>', 'value': {{ stream_slice.get('prior_state', + stream_state.get('prior_state', {})).get('updated_at') or + format_datetime(config['start_date'], '%s') }} }, { 'field': + 'updated_at', 'operator': '=', 'value': {{ + stream_slice.get('prior_state', stream_state.get('prior_state', + {})).get('updated_at') or format_datetime(config['start_date'], + '%s') }} }, ], } + pagination: >- + { 'per_page': {{ parameters.get('page_size') }}, 'page': {{ + next_page_token.get('next_page_token').get('page') }}, + 'starting_after': '{{ + next_page_token.get('next_page_token').get('starting_after') }}' } + error_handler: + type: CustomErrorHandler + class_name: source_declarative_manifest.components.ErrorHandlerWithRateLimiter + response_filters: + - type: HttpResponseFilter + action: FAIL + failure_type: config_error + error_message: >- + Failed to perform request. Error: Active subscription needed. + Please, validate your current Intercom plan to continue using + API. + error_message_contains: Active subscription needed + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + record_filter: + type: RecordFilter + condition: >- + {{ record['updated_at'] >= ( stream_state.get('prior_state', + {}).get('updated_at', 0) - (config.get('lookback_window', 0) * + 86400) if stream_state else stream_slice.get('prior_state', + {}).get('updated_at', 0) ) - (config.get('lookback_window', 0) * + 86400)}} + paginator: + type: DefaultPaginator + pagination_strategy: + type: CursorPagination + page_size: 150 + cursor_value: "{{ response.get('pages', {}).get('next') }}" + stop_condition: "{{ 'next' not in response.get('pages', {}) }}" + incremental_sync: + type: CustomIncrementalSync + class_name: source_declarative_manifest.components.IncrementalSingleSliceCursor + cursor_field: updated_at + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + conversations: + type: DeclarativeStream + description: >- + https://developers.intercom.com/intercom-api-reference/reference/pagination-sorting-search + name: conversations + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: conversations/search + http_method: POST + request_headers: + Accept: application/json + Intercom-Version: "2.11" + request_body_json: + sort: "{'field': 'updated_at', 'order': 'ascending'}" + query: >- + { 'operator': 'OR', 'value': [ { 'field': 'updated_at', + 'operator': '>', 'value': {{ stream_slice.get('prior_state', + stream_state.get('prior_state', {})).get('updated_at') or + format_datetime(config['start_date'], '%s') }} }, { 'field': + 'updated_at', 'operator': '=', 'value': {{ + stream_slice.get('prior_state', stream_state.get('prior_state', + {})).get('updated_at') or format_datetime(config['start_date'], + '%s') }} }, ], } + pagination: >- + { 'per_page': {{ parameters.get('page_size') }}, 'page': {{ + next_page_token.get('next_page_token').get('page') }}, + 'starting_after': '{{ + next_page_token.get('next_page_token').get('starting_after') }}' } + error_handler: + type: CustomErrorHandler + class_name: source_declarative_manifest.components.ErrorHandlerWithRateLimiter + response_filters: + - type: HttpResponseFilter + action: FAIL + failure_type: config_error + error_message: >- + Failed to perform request. Error: Active subscription needed. + Please, validate your current Intercom plan to continue using + API. + error_message_contains: Active subscription needed + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - conversations + record_filter: + type: RecordFilter + condition: >- + {{ record['updated_at'] >= ( stream_state.get('prior_state', + {}).get('updated_at', 0) - (config.get('lookback_window', 0) * + 86400) if stream_state else stream_slice.get('prior_state', + {}).get('updated_at', 0) ) - (config.get('lookback_window', 0) * + 86400)}} + paginator: + type: DefaultPaginator + pagination_strategy: + type: CursorPagination + page_size: 150 + cursor_value: "{{ response.get('pages', {}).get('next') }}" + stop_condition: "{{ 'next' not in response.get('pages', {}) }}" + incremental_sync: + type: CustomIncrementalSync + class_name: source_declarative_manifest.components.IncrementalSingleSliceCursor + cursor_field: updated_at + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/conversations" + conversation_parts: + type: DeclarativeStream + name: conversation_parts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /conversations/{{ stream_slice.id }} + http_method: GET + request_headers: + Accept: application/json + Intercom-Version: "2.11" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 404 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - conversation_parts + - conversation_parts + record_filter: + type: RecordFilter + condition: >- + {{ record['updated_at'] >= stream_state.get('prior_state', + {}).get('updated_at', 0) - (config.get('lookback_window', 0) * + 86400)}} + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: id + stream: + $ref: "#/definitions/streams/conversations" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%s" + - "%ms" + datetime_format: "%s" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + transformations: + - type: AddFields + fields: + - path: + - conversation_id + value: "{{ stream_slice.id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/conversation_parts" + company_segments: + type: DeclarativeStream + name: company_segments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /companies/{{ stream_slice.id }}/segments + http_method: GET + request_headers: + Accept: application/json + Intercom-Version: "2.11" + error_handler: + type: CustomErrorHandler + class_name: source_declarative_manifest.components.ErrorHandlerWithRateLimiter + response_filters: + - type: HttpResponseFilter + action: FAIL + failure_type: config_error + error_message: >- + Failed to perform request. Error: Active subscription needed. + Please, validate your current Intercom plan to continue using + API. + error_message_contains: Active subscription needed + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + record_filter: + type: RecordFilter + condition: >- + {{ record['updated_at'] >= stream_state.get('prior_state', + {}).get('updated_at', 0) - (config.get('lookback_window', 0) * + 86400)}} + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: id + stream: + $ref: "#/definitions/streams/companies" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%s" + - "%ms" + datetime_format: "%s" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/company_segments" + base_requester: + type: HttpRequester + url_base: https://api.intercom.io/ + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"access_token\"] }}" + +streams: + - $ref: "#/definitions/streams/activity_logs" + - $ref: "#/definitions/streams/admins" + - $ref: "#/definitions/streams/tags" + - $ref: "#/definitions/streams/teams" + - $ref: "#/definitions/streams/segments" + - $ref: "#/definitions/streams/companies" + - $ref: "#/definitions/streams/company_attributes" + - $ref: "#/definitions/streams/contact_attributes" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/conversations" + - $ref: "#/definitions/streams/conversation_parts" + - $ref: "#/definitions/streams/company_segments" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - access_token + - start_date + properties: + access_token: + type: string + description: >- + Access token for making authenticated requests. See the Intercom + docs for more information. + order: 0 + title: Access token + airbyte_secret: true + client_id: + type: string + description: Client Id for your Intercom application. + order: 1 + title: Client Id + airbyte_secret: true + client_secret: + type: string + description: Client Secret for your Intercom application. + order: 2 + title: Client Secret + airbyte_secret: true + activity_logs_time_step: + type: integer + description: >- + Set lower value in case of failing long running sync of Activity Logs + stream. + order: 3 + title: Activity logs stream slice step size (in days) + default: 30 + maximum: 91 + minimum: 1 + examples: + - 30 + - 10 + - 5 + lookback_window: + type: integer + description: The number of days to shift the state value backward for record sync + order: 4 + title: Lookback window + default: 0 + minimum: 0 + examples: + - 60 + start_date: + type: string + description: >- + UTC date and time in the format 2017-01-25T00:00:00Z. Any data before + this date will not be replicated. + order: 5 + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + examples: + - "2020-11-16T00:00:00Z" + additionalProperties: true + +metadata: + autoImportSchema: + activity_logs: false + admins: false + tags: false + teams: false + segments: false + companies: false + company_attributes: false + contact_attributes: false + contacts: false + conversations: false + conversation_parts: false + company_segments: false + yamlComponents: + streams: + activity_logs: + - errorHandler + admins: + - errorHandler + tags: + - errorHandler + teams: + - errorHandler + segments: + - errorHandler + - incrementalSync + companies: + - incrementalSync + company_attributes: + - errorHandler + contact_attributes: + - errorHandler + contacts: + - errorHandler + - incrementalSync + conversations: + - errorHandler + - incrementalSync + company_segments: + - errorHandler + testedStreams: + activity_logs: + hasRecords: true + streamHash: dae54ab01efc8a7c580121de6902d67a82a87775 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + admins: + hasRecords: true + streamHash: 62fdd12c98bec28f09edd3a34cd16bc5c1afedb6 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + tags: + hasRecords: true + streamHash: 53f9b051b3d5c8747598b848c006c80f3ffc5957 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + teams: + hasRecords: true + streamHash: d27cc586e29ddf6347d6356ea4970af99b7980c1 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + segments: + hasRecords: true + streamHash: 96ba554609834b986e20813cedf03a96183196fd + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + companies: + hasRecords: true + streamHash: 801c62e3a0a4028608efc4bf5f1ad5119b986973 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + company_attributes: + hasRecords: true + streamHash: e59558fb65b2c762d2b3f6b67e9071db2773cf13 + hasResponse: true + primaryKeysAreUnique: false + primaryKeysArePresent: true + responsesAreSuccessful: true + contact_attributes: + hasRecords: true + streamHash: 70d4afa7c3ad63877ab1fd9c185bd58c27ce06bc + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + contacts: + hasRecords: false + streamHash: e796494e6a861bce39d40f66e78e19b9ec633e29 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + conversations: + hasRecords: false + streamHash: 5838b59eba7d58cae3fe42eca72062bc9d29e1c4 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + conversation_parts: + streamHash: 67469544cde547846d7636a110f775313d6e04fc + company_segments: + hasRecords: true + streamHash: 41220115640c54deccc0e5a421991a60aa808d3c + hasResponse: true + primaryKeysAreUnique: false + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: {} + +schemas: + activity_logs: + type: object + additionalProperties: true + properties: + metadata: + type: + - "null" + - object + description: Additional data or information related to the activity + activity_description: + type: + - "null" + - string + description: A description of the activity that took place + activity_type: + type: + - "null" + - string + description: The type or category of the activity + created_at: + type: + - "null" + - integer + description: The timestamp when the activity occurred + id: + type: + - "null" + - string + description: Unique identifier for the activity log entry + performed_by: + type: + - "null" + - object + description: The user who performed the activity + properties: + type: + type: + - "null" + - string + description: Type of the user who performed the activity (e.g., admin, user) + email: + type: + - "null" + - string + description: Email of the user who performed the activity + id: + type: + - "null" + - string + description: Unique identifier of the user who performed the activity + ip: + type: + - "null" + - string + description: IP address from where the activity was performed + admins: + type: object + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: Type of the admin (e.g., full-time, part-time) + admin_ids: + description: Array of unique identifiers for admins + anyOf: + - type: array + items: + type: integer + - type: "null" + avatar: + type: + - "null" + - object + description: Admin avatar details + properties: + image_url: + type: + - "null" + - string + description: URL of the admin's avatar image + away_mode_enabled: + type: + - "null" + - boolean + description: Flag indicating if away mode is enabled for the admin + away_mode_reassign: + type: + - "null" + - boolean + description: Flag indicating if away mode reassignment is enabled for the admin + email: + type: + - "null" + - string + description: Email address of the admin + has_inbox_seat: + type: + - "null" + - boolean + description: Flag indicating if the admin has a seat in the inbox + id: + type: + - "null" + - string + description: Unique identifier for the admin + job_title: + type: + - "null" + - string + description: Job title of the admin + name: + type: + - "null" + - string + description: Name of the admin + team_ids: + description: Array of team identifiers the admin belongs to + anyOf: + - type: array + items: + type: integer + - type: "null" + team_priority_level: + type: + - "null" + - object + description: Detailed team priority level information for the admin + properties: + primary_team_ids: + type: + - "null" + - array + description: Array of primary team identifiers for the admin + items: + type: + - "null" + - integer + secondary_team_ids: + type: + - "null" + - array + description: Array of secondary team identifiers for the admin + items: + type: + - "null" + - integer + tags: + type: object + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: Type of the tag indicating its purpose or category. + id: + type: + - "null" + - string + description: Unique identifier for the tag. + name: + type: + - "null" + - string + description: Name of the tag used for identification. + teams: + type: object + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: Type of team (e.g., 'internal', 'external'). + admin_ids: + description: Array of user IDs representing the admins of the team. + anyOf: + - type: array + items: + type: integer + - type: "null" + id: + type: + - "null" + - string + description: Unique identifier for the team. + name: + type: + - "null" + - string + description: Name of the team. + segments: + type: object + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: The type or category of the segment + count: + type: + - "null" + - integer + description: The number of items in the segment + created_at: + type: + - "null" + - integer + description: The date and time when the segment was created + id: + type: + - "null" + - string + description: Unique identifier for the segment + name: + type: + - "null" + - string + description: The name or title of the segment + person_type: + type: + - "null" + - string + description: Type of persons included in the segment + updated_at: + type: + - "null" + - integer + description: The date and time when the segment was last updated + companies: + type: object + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: The type of the company + app_id: + type: + - "null" + - string + description: The ID of the application associated with the company + company_id: + type: + - "null" + - string + description: The unique identifier of the company + created_at: + type: + - "null" + - integer + description: The date and time when the company was created + custom_attributes: + type: + - "null" + - object + description: Custom attributes specific to the company + additionalProperties: true + id: + type: + - "null" + - string + description: The ID of the company + industry: + type: + - "null" + - string + description: The industry in which the company operates + monthly_spend: + type: + - "null" + - number + description: The monthly spend of the company + multipleOf: 1.e-8 + name: + type: + - "null" + - string + description: The name of the company + plan: + type: + - "null" + - object + description: Details of the company's subscription plan + properties: + type: + type: + - "null" + - string + description: The type of the subscription plan + id: + type: + - "null" + - string + description: The ID of the subscription plan + name: + type: + - "null" + - string + description: The name of the subscription plan + remote_created_at: + type: + - "null" + - integer + description: The remote date and time when the company was created + segments: + type: object + description: Segments associated with the company + properties: + type: + type: string + description: The type of segments associated with the company + segments: + type: array + description: List of segments + items: + type: + - "null" + - object + properties: + type: + type: string + description: The type of the segment + id: + type: string + description: The ID of the segment + session_count: + type: + - "null" + - integer + description: The number of sessions related to the company + size: + type: + - "null" + - integer + description: The size of the company + tags: + type: object + description: Tags associated with the company + properties: + type: + type: string + description: The type of tags associated with the company + tags: + type: array + description: List of tags + items: + type: + - "null" + - object + properties: + type: + type: string + description: The type of the tag + id: + description: The ID of the tag + oneOf: + - type: + - "null" + - string + - type: + - "null" + - integer + name: + type: string + description: The name of the tag + updated_at: + type: + - "null" + - integer + description: The date and time when the company was last updated + user_count: + type: + - "null" + - integer + description: The number of users associated with the company + website: + type: + - "null" + - string + description: The website of the company + company_attributes: + type: object + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: Type of data structure for the company attribute. + description: + type: + - "null" + - string + description: Description or details about the company attribute. + admin_id: + type: + - "null" + - string + description: The ID of the admin user associated with the company. + api_writable: + type: + - "null" + - boolean + description: Indicates whether the field is writable through the API. + archived: + type: + - "null" + - boolean + description: Flag to indicate if the company data is archived. + created_at: + type: + - "null" + - integer + description: Timestamp when the company data was created. + custom: + type: + - "null" + - boolean + description: Custom attribute specific to the company. + data_type: + type: + - "null" + - string + description: Type of data stored in the attribute field. + full_name: + type: + - "null" + - string + description: Full name associated with the company. + id: + type: + - "null" + - integer + description: Unique ID assigned to the company attribute. + label: + type: + - "null" + - string + description: Label or display name for the company attribute. + messenger_writable: + type: + - "null" + - boolean + description: Indicates whether the field is writable through the messenger. + model: + type: + - "null" + - string + description: Model or schema used for storing the company attribute. + name: + type: + - "null" + - string + description: Name of the company attribute. + options: + description: Available options or values for the company attribute. + anyOf: + - type: array + items: + type: string + - type: "null" + ui_writable: + type: + - "null" + - boolean + description: Indicates whether the field is writable through the UI. + updated_at: + type: + - "null" + - integer + description: Timestamp when the company data was last updated. + contact_attributes: + type: object + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: The type of contact attribute (e.g., text, number, boolean). + description: + type: + - "null" + - string + description: Description of the contact attribute for better understanding. + admin_id: + type: + - "null" + - string + description: Unique identifier for the admin associated with the contact attribute. + api_writable: + type: + - "null" + - boolean + description: Indicates whether the attribute is writable via API. + archived: + type: + - "null" + - boolean + description: Flag to signify if the contact attribute is archived. + created_at: + type: + - "null" + - integer + description: Timestamp of when the contact attribute was created. + custom: + type: + - "null" + - boolean + description: Indicates if the attribute is a custom user-defined field. + data_type: + type: + - "null" + - string + description: The data type of the contact attribute value. + full_name: + type: + - "null" + - string + description: The full name associated with the contact attribute. + id: + type: + - "null" + - integer + description: Unique identifier for the contact attribute. + label: + type: + - "null" + - string + description: Label representing the attribute in user interfaces. + messenger_writable: + type: + - "null" + - boolean + description: Indicates whether the attribute is writable via messenger. + model: + type: + - "null" + - string + description: Model to which the contact attribute is associated. + name: + type: + - "null" + - string + description: The name of the contact attribute. + options: + type: + - "null" + - array + description: List of available options for the attribute. + items: + type: + - "null" + - string + ui_writable: + type: + - "null" + - boolean + description: Indicates whether the attribute is writable via user interface. + updated_at: + type: + - "null" + - integer + description: Timestamp of when the contact attribute was last updated. + contacts: + type: object + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: Type of contact. + android_app_name: + type: + - "null" + - string + description: The name of the Android app associated with the contact. + android_app_version: + type: + - "null" + - string + description: The version of the Android app associated with the contact. + android_device: + type: + - "null" + - string + description: The device used by the contact for Android. + android_last_seen_at: + type: + - "null" + - string + description: The date and time when the contact was last seen on Android. + format: date-time + android_os_version: + type: + - "null" + - string + description: The operating system version of the Android device. + android_sdk_version: + type: + - "null" + - string + description: The SDK version of the Android device. + avatar: + type: + - "null" + - string + description: URL pointing to the contact's avatar image. + browser: + type: + - "null" + - string + description: The browser used by the contact. + browser_language: + type: + - "null" + - string + description: The language preference set in the contact's browser. + browser_version: + type: + - "null" + - string + description: The version of the browser used by the contact. + companies: + type: + - "null" + - object + description: Companies associated with the contact. + properties: + type: + type: + - "null" + - string + description: Type of connection with the companies. + data: + type: + - "null" + - array + description: Array of company data associated with the contact. + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + description: Type of company. + id: + type: + - "null" + - string + description: The unique identifier of the company. + url: + type: + - "null" + - string + description: URL of the company. + has_more: + type: + - "null" + - boolean + description: Flag indicating if there are more companies to load. + total_count: + type: + - "null" + - integer + description: Total count of companies associated with the contact. + url: + type: + - "null" + - string + description: URL to access more company information. + created_at: + type: + - "null" + - integer + description: The date and time when the contact was created. + custom_attributes: + type: + - "null" + - object + description: Custom attributes defined for the contact. + additionalProperties: true + properties: {} + email: + type: + - "null" + - string + description: The email address of the contact. + external_id: + type: + - "null" + - string + description: External identifier for the contact. + has_hard_bounced: + type: + - "null" + - boolean + description: Flag indicating if the contact has hard bounced. + id: + type: + - "null" + - string + description: The unique identifier of the contact. + ios_app_name: + type: + - "null" + - string + description: The name of the iOS app associated with the contact. + ios_app_version: + type: + - "null" + - string + description: The version of the iOS app associated with the contact. + ios_device: + type: + - "null" + - string + description: The device used by the contact for iOS. + ios_last_seen_at: + type: + - "null" + - integer + description: The date and time when the contact was last seen on iOS. + ios_os_version: + type: + - "null" + - string + description: The operating system version of the iOS device. + ios_sdk_version: + type: + - "null" + - string + description: The SDK version of the iOS device. + language_override: + type: + - "null" + - string + description: Language override set for the contact. + last_contacted_at: + type: + - "null" + - integer + description: The date and time when the contact was last contacted. + last_email_clicked_at: + type: + - "null" + - integer + description: The date and time when the contact last clicked an email. + last_email_opened_at: + type: + - "null" + - integer + description: The date and time when the contact last opened an email. + last_replied_at: + type: + - "null" + - integer + description: The date and time when the contact last replied. + last_seen_at: + type: + - "null" + - integer + description: The date and time when the contact was last seen overall. + location: + type: + - "null" + - object + description: Location details of the contact. + properties: + type: + type: + - "null" + - string + description: Type of location. + city: + type: + - "null" + - string + description: City of the contact's location. + continent_code: + type: + - "null" + - string + description: Continent code of the contact's location. + country: + type: + - "null" + - string + description: Country of the contact's location. + country_code: + type: + - "null" + - string + description: Country code of the contact's location. + region: + type: + - "null" + - string + description: Region of the contact's location. + marked_email_as_spam: + type: + - "null" + - boolean + description: Flag indicating if the contact's email was marked as spam. + name: + type: + - "null" + - string + description: The name of the contact. + notes: + type: + - "null" + - object + description: Notes associated with the contact. + properties: + type: + type: + - "null" + - string + description: Type of connection with the notes. + data: + type: + - "null" + - array + description: Array of note data associated with the contact. + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + description: Type of note. + id: + type: + - "null" + - string + description: The unique identifier of the note. + url: + type: + - "null" + - string + description: URL of the note. + has_more: + type: + - "null" + - boolean + description: Flag indicating if there are more notes to load. + total_count: + type: + - "null" + - integer + description: Total count of notes associated with the contact. + url: + type: + - "null" + - string + description: URL to access more note information. + opted_in_subscription_types: + type: + - "null" + - object + description: Subscription types the contact opted into. + properties: + type: + type: + - "null" + - string + description: Type of connection with the subscription types. + data: + type: + - "null" + - array + description: Array of subscription type data opted into by the contact. + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + description: Type of subscription. + id: + type: + - "null" + - string + description: The unique identifier of the subscription type. + url: + type: + - "null" + - string + description: URL of the subscription type. + has_more: + type: + - "null" + - boolean + description: Flag indicating if there are more subscription types to load. + total_count: + type: + - "null" + - integer + description: Total count of subscription types the contact opted into. + url: + type: + - "null" + - string + description: URL to access more subscription type information. + opted_out_subscription_types: + type: + - "null" + - object + description: Subscription types the contact opted out from. + properties: + type: + type: + - "null" + - string + description: Type of connection with the subscription types. + data: + type: + - "null" + - array + description: Array of subscription type data opted out from by the contact. + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + description: Type of subscription. + id: + type: + - "null" + - string + description: The unique identifier of the subscription type. + url: + type: + - "null" + - string + description: URL of the subscription type. + has_more: + type: + - "null" + - boolean + description: Flag indicating if there are more subscription types to load. + total_count: + type: + - "null" + - integer + description: Total count of subscription types the contact opted out from. + url: + type: + - "null" + - string + description: URL to access more subscription type information. + os: + type: + - "null" + - string + description: Operating system of the contact's device. + owner_id: + type: + - "null" + - integer + description: The unique identifier of the contact's owner. + phone: + type: + - "null" + - string + description: The phone number of the contact. + referrer: + type: + - "null" + - string + description: Referrer information related to the contact. + role: + type: + - "null" + - string + description: Role or position of the contact. + signed_up_at: + type: + - "null" + - integer + description: The date and time when the contact signed up. + sms_consent: + type: + - "null" + - boolean + description: Consent status for SMS communication. + social_profiles: + type: + - "null" + - object + description: Social profiles associated with the contact. + properties: + type: + type: + - "null" + - string + description: Type of social profile connection. + data: + type: + - "null" + - array + description: Array of social profile data associated with the contact. + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + description: Type of social profile. + name: + type: + - "null" + - string + description: Name of the social profile. + url: + type: + - "null" + - string + description: URL of the social profile. + tags: + type: + - "null" + - object + description: Tags associated with the contact. + properties: + type: + type: + - "null" + - string + description: Type of connection with the tags. + data: + type: + - "null" + - array + description: Array of tag data associated with the contact. + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + description: Type of tag. + id: + type: + - "null" + - string + description: The unique identifier of the tag. + url: + type: + - "null" + - string + description: URL of the tag. + has_more: + type: + - "null" + - boolean + description: Flag indicating if there are more tags to load. + total_count: + type: + - "null" + - integer + description: Total count of tags associated with the contact. + url: + type: + - "null" + - string + description: URL to access more tag information. + unsubscribed_from_emails: + type: + - "null" + - boolean + description: Flag indicating if the contact unsubscribed from emails. + unsubscribed_from_sms: + type: + - "null" + - boolean + description: Flag indicating if the contact unsubscribed from SMS. + updated_at: + type: + - "null" + - integer + description: The date and time when the contact was last updated. + utm_campaign: + type: + - "null" + - string + description: Campaign data from UTM parameters. + utm_content: + type: + - "null" + - string + description: Content data from UTM parameters. + utm_medium: + type: + - "null" + - string + description: Medium data from UTM parameters. + utm_source: + type: + - "null" + - string + description: Source data from UTM parameters. + utm_term: + type: + - "null" + - string + description: Term data from UTM parameters. + workspace_id: + type: + - "null" + - string + description: The unique identifier of the workspace associated with the contact. + conversations: + type: object + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: The type of the conversation + admin_assignee_id: + type: + - "null" + - integer + description: The ID of the administrator assigned to the conversation + assignee: + type: + - "null" + - object + description: The assigned user responsible for the conversation. + properties: + type: + type: + - "null" + - string + description: The type of the assignee (e.g., admin, agent) + email: + type: + - "null" + - string + description: The email of the assignee + id: + type: + - "null" + - string + description: The ID of the assignee + name: + type: + - "null" + - string + description: The name of the assignee + contacts: + type: + - "null" + - object + description: List of contacts involved in the conversation. + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + description: The type of the contact + id: + type: + - "null" + - string + description: The ID of the contact + conversation_message: + type: + - "null" + - object + description: The main message content of the conversation. + properties: + type: + type: + - "null" + - string + description: The type of the conversation message + attachments: + description: Attachments in the conversation message + anyOf: + - type: array + items: + type: object + properties: + type: + type: + - "null" + - string + content_type: + type: + - "null" + - string + filesize: + type: + - "null" + - integer + height: + type: + - "null" + - integer + name: + type: + - "null" + - string + url: + type: + - "null" + - string + width: + type: + - "null" + - integer + - type: "null" + author: + type: + - "null" + - object + description: The author of the conversation message. + properties: + type: + type: + - "null" + - string + description: The type of the author (e.g., admin, customer) + email: + type: + - "null" + - string + description: The email of the author of the message + id: + type: + - "null" + - string + description: The ID of the author of the message + name: + type: + - "null" + - string + description: The name of the author of the message + body: + type: + - "null" + - string + description: The body/content of the conversation message + delivered_as: + type: + - "null" + - string + description: The delivery status of the message + id: + type: + - "null" + - string + description: The ID of the conversation message + subject: + type: + - "null" + - string + description: The subject of the conversation message + url: + type: + - "null" + - string + description: The URL of the conversation message + conversation_rating: + type: + - "null" + - object + description: Ratings given to the conversation by the customer and teammate. + properties: + created_at: + type: + - "null" + - integer + description: The timestamp when the rating was created + customer: + type: + - "null" + - object + description: Rating given by the customer. + properties: + type: + type: + - "null" + - string + description: The type of the customer providing the rating + id: + type: + - "null" + - string + description: The ID of the customer who provided the rating + rating: + type: + - "null" + - integer + description: The rating given to the conversation + remark: + type: + - "null" + - string + description: Any remarks provided with the rating + teammate: + type: + - "null" + - object + description: Rating given by the teammate. + properties: + type: + type: + - "null" + - string + description: The type of the teammate being rated + id: + type: + - "null" + - integer + description: The ID of the teammate being rated + created_at: + type: + - "null" + - integer + description: The timestamp when the conversation was created + custom_attributes: + type: + - "null" + - object + description: Custom attributes associated with the conversation + customer_first_reply: + type: + - "null" + - object + description: Timestamp indicating when the customer first replied. + properties: + type: + type: + - "null" + - string + description: The type of the first customer reply + created_at: + type: + - "null" + - integer + description: The timestamp of the customer's first reply + url: + type: + - "null" + - string + description: The URL of the first customer reply + customers: + description: List of customers involved in the conversation + anyOf: + - type: array + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + id: + type: + - "null" + - string + - type: "null" + first_contact_reply: + type: + - "null" + - object + description: Timestamp indicating when the first contact replied. + properties: + type: + type: + - "null" + - string + description: The type of the first contact reply + created_at: + type: + - "null" + - integer + description: The timestamp of the first contact's reply + url: + type: + - "null" + - string + description: The URL of the first contact reply + id: + type: + - "null" + - string + description: The unique ID of the conversation + open: + type: + - "null" + - boolean + description: Indicates if the conversation is open or closed + priority: + type: + - "null" + - string + description: The priority level of the conversation + read: + type: + - "null" + - boolean + description: Indicates if the conversation has been read + redacted: + type: + - "null" + - boolean + description: Indicates if the conversation is redacted + sent_at: + type: + - "null" + - integer + description: The timestamp when the conversation was sent + sla_applied: + type: + - "null" + - object + description: Service Level Agreement details applied to the conversation. + properties: + sla_name: + type: + - "null" + - string + description: The name of the SLA applied + sla_status: + type: + - "null" + - string + description: The status of the SLA applied + snoozed_until: + type: + - "null" + - integer + description: Timestamp until the conversation is snoozed + source: + type: + - "null" + - object + description: Source details of the conversation. + properties: + type: + type: + - "null" + - string + description: The type of the source + attachments: + type: + - "null" + - array + description: Attachments related to the conversation. + items: + type: + - "null" + - object + additionalProperties: true + properties: {} + author: + type: + - "null" + - object + description: Author of the source. + properties: + type: + type: + - "null" + - string + description: The type of the source author (e.g., admin, customer) + email: + type: + - "null" + - string + description: The email of the source author + id: + type: + - "null" + - string + description: The ID of the source author + name: + type: + - "null" + - string + description: The name of the source author + body: + type: + - "null" + - string + description: The body/content of the source + delivered_as: + type: + - "null" + - string + description: The delivery status of the source + id: + type: + - "null" + - string + description: The ID of the source + redacted: + type: + - "null" + - boolean + description: Indicates if the source is redacted + subject: + type: + - "null" + - string + description: The subject of the source + url: + type: + - "null" + - string + description: The URL of the source + state: + type: + - "null" + - string + description: The state of the conversation (e.g., new, in progress) + statistics: + type: + - "null" + - object + description: Statistics related to the conversation. + properties: + type: + type: + - "null" + - string + description: The type of conversation statistics + count_assignments: + type: + - "null" + - integer + description: The total count of assignments for the conversation + count_conversation_parts: + type: + - "null" + - integer + description: The total count of conversation parts + count_reopens: + type: + - "null" + - integer + description: The total count of conversation reopens + first_admin_reply_at: + type: + - "null" + - integer + description: Timestamp of the first admin reply + first_assignment_at: + type: + - "null" + - integer + description: Timestamp of the first assignment + first_close_at: + type: + - "null" + - integer + description: Timestamp of the first conversation close + first_contact_reply_at: + type: + - "null" + - integer + description: Timestamp of the first contact reply + last_admin_reply_at: + type: + - "null" + - integer + description: Timestamp of the last admin reply + last_assignment_admin_reply_at: + type: + - "null" + - integer + description: Timestamp of the last assignment admin reply + last_assignment_at: + type: + - "null" + - integer + description: Timestamp of the last assignment + last_close_at: + type: + - "null" + - integer + description: Timestamp of the last conversation close + last_closed_by_id: + type: + - "null" + - integer + description: The ID of the last user who closed the conversation + last_contact_reply_at: + type: + - "null" + - integer + description: Timestamp of the last contact reply + median_time_to_reply: + type: + - "null" + - integer + description: The median time taken to reply to the conversation + time_to_admin_reply: + type: + - "null" + - integer + description: Time taken to reply by admin + time_to_assignment: + type: + - "null" + - integer + description: Time taken for assignment + time_to_first_close: + type: + - "null" + - integer + description: Time taken to first close the conversation + time_to_last_close: + type: + - "null" + - integer + description: Time taken to last close the conversation + tags: + type: + - "null" + - object + description: Tags applied to the conversation. + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + description: The type of the tag + applied_at: + type: + - "null" + - integer + description: Timestamp when the tag was applied + applied_by: + type: + - "null" + - object + description: User who applied the tag. + properties: + type: + type: + - "null" + - string + description: The type of the user who applied the tag + id: + type: + - "null" + - string + description: The ID of the user who applied the tag + id: + type: + - "null" + - string + description: The ID of the tag + name: + type: + - "null" + - string + description: The name of the tag + team_assignee_id: + type: + - "null" + - integer + description: The ID of the team assigned to the conversation + teammates: + type: + - "null" + - object + description: List of teammates involved in the conversation. + properties: + type: + type: + - "null" + - string + description: The type of teammates + admins: + type: + - "null" + - array + description: Admin teammates involved in the conversation. + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + description: The type of the teammate (admin) + id: + type: + - "null" + - string + description: The ID of the teammate admin + title: + type: + - "null" + - string + description: The title of the conversation + topics: + type: + - "null" + - object + description: Topics associated with the conversation. + properties: + type: + type: + - "null" + - string + description: The type of topics + topics: + type: + - "null" + - array + description: List of topics related to the conversation. + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + description: The type of the topic + id: + type: + - "null" + - integer + description: The ID of the topic + name: + type: + - "null" + - string + description: The name of the topic + total_count: + type: + - "null" + - integer + description: The total count of topics + updated_at: + type: + - "null" + - integer + description: The timestamp when the conversation was last updated + user: + type: + - "null" + - object + description: The user related to the conversation. + properties: + type: + type: + - "null" + - string + description: The type of the user + id: + type: + - "null" + - string + description: The ID of the user associated with the conversation + waiting_since: + type: + - "null" + - integer + description: Timestamp since waiting for a response + conversation_parts: + type: object + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: The type of conversation part, such as message or note. + assigned_to: + description: >- + The user or team member who is assigned to handle this conversation + part. + oneOf: + - type: object + properties: + type: + type: + - "null" + - string + id: + type: + - "null" + - string + - type: string + - type: "null" + attachments: + type: + - "null" + - array + description: Represents the attachments associated with the conversation part. + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + description: The type or category of the attachment. + content_type: + type: + - "null" + - string + description: The MIME type of the attachment content. + filesize: + type: + - "null" + - integer + description: The size of the attachment file in bytes. + height: + type: + - "null" + - integer + description: The height dimension of the attachment in pixels. + name: + type: + - "null" + - string + description: The filename or name of the attachment. + url: + type: + - "null" + - string + description: The URL or location where the attachment can be accessed. + width: + type: + - "null" + - integer + description: The width dimension of the attachment in pixels. + author: + type: + - "null" + - object + description: Represents the author of the conversation part. + properties: + type: + type: + - "null" + - string + description: The type of author, such as customer or agent. + email: + type: + - "null" + - string + description: The email address of the conversation author. + id: + type: + - "null" + - string + description: The unique identifier of the conversation author. + name: + type: + - "null" + - string + description: The name of the conversation author. + body: + type: + - "null" + - string + description: The main content or message body of the conversation part. + conversation_created_at: + type: + - "null" + - integer + description: The date and time when the conversation was created. + conversation_id: + type: + - "null" + - string + description: The unique identifier of the conversation. + conversation_total_parts: + type: + - "null" + - integer + description: The total number of parts in the conversation. + conversation_updated_at: + type: + - "null" + - integer + description: The date and time when the conversation was last updated. + created_at: + type: + - "null" + - integer + description: The date and time when the conversation part was created. + external_id: + type: + - "null" + - string + description: An external identifier associated with the conversation part. + id: + type: + - "null" + - string + description: The unique identifier of the conversation part. + notified_at: + type: + - "null" + - integer + description: The date and time when the conversation part was last notified. + part_type: + type: + - "null" + - string + description: The type or category of the conversation part. + redacted: + type: + - "null" + - boolean + description: Indicates if the conversation part has been redacted or censored. + updated_at: + type: + - "null" + - integer + description: The date and time when the conversation part was last updated. + company_segments: + type: object + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: The category or type of the company segment. + count: + type: + - "null" + - integer + description: The count of company segments returned in the response. + created_at: + type: + - "null" + - integer + description: The timestamp when the company segment was created. + id: + type: + - "null" + - string + description: The unique identifier associated with the company segment. + name: + type: + - "null" + - string + description: The name of the company segment. + person_type: + type: + - "null" + - string + description: The type of person associated with the company segment. + updated_at: + type: + - "null" + - integer + description: The timestamp when the company segment was last updated. diff --git a/airbyte-integrations/connectors/source-intercom/metadata.yaml b/airbyte-integrations/connectors/source-intercom/metadata.yaml index c48d38a3021a..b6fe2e9b6f85 100644 --- a/airbyte-integrations/connectors/source-intercom/metadata.yaml +++ b/airbyte-integrations/connectors/source-intercom/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - api.intercom.io connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/source-declarative-manifest:5.14.0@sha256:accdf6c1bbcabd45b40f836692e4f3b1a1e1f0b28267973802ee212cd9c2c16a connectorSubtype: api connectorType: source definitionId: d8313939-3782-41b0-be29-b3ca20d8dd3a - dockerImageTag: 0.8.2 + dockerImageTag: 0.9.0-rc.1 dockerRepository: airbyte/source-intercom documentationUrl: https://docs.airbyte.com/integrations/sources/intercom githubIssueLabel: source-intercom @@ -18,9 +18,12 @@ data: license: MIT maxSecondsBetweenMessages: 60 name: Intercom + releases: + rolloutConfiguration: + enableProgressiveRollout: false remoteRegistries: pypi: - enabled: true + enabled: false packageName: airbyte-source-intercom registryOverrides: cloud: @@ -37,14 +40,16 @@ data: - companies supportLevel: certified tags: - - language:python - cdk:low-code + - language:manifest-only connectorTestSuitesOptions: - suite: liveTests testConnections: - name: intercom_config_dev_null id: 09ebd6bb-2756-4cd3-8ad5-7120088cc553 - - suite: unitTests + # We should enable unit tests once the connector has been updated to CDK version >= 6.10.0 + # Until then, the test suites won't be able to run successfully in CI as the fixtures are not present in earlier versions + # - suite: unitTests - suite: integrationTests testSecrets: - name: SECRET_SOURCE-INTERCOM_APIKEY__CREDS diff --git a/airbyte-integrations/connectors/source-intercom/poetry.lock b/airbyte-integrations/connectors/source-intercom/poetry.lock deleted file mode 100644 index cd6e4347052c..000000000000 --- a/airbyte-integrations/connectors/source-intercom/poetry.lock +++ /dev/null @@ -1,1717 +0,0 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. - -[[package]] -name = "airbyte-cdk" -version = "4.6.2" -description = "A framework for writing Airbyte Connectors." -optional = false -python-versions = "<4.0,>=3.10" -files = [ - {file = "airbyte_cdk-4.6.2-py3-none-any.whl", hash = "sha256:3a37bd96c4b4f874b15fc18839b1e163eb30d1e4ef80d7dde2854e6a48efe934"}, - {file = "airbyte_cdk-4.6.2.tar.gz", hash = "sha256:c034f11ba6abe73dd7346ce2bc7017ff71ef0db1fd1ae86fb86beaeae35d8baf"}, -] - -[package.dependencies] -airbyte-protocol-models-pdv2 = ">=0.12.2,<0.13.0" -backoff = "*" -cachetools = "*" -cryptography = ">=42.0.5,<43.0.0" -Deprecated = ">=1.2,<1.3" -dpath = ">=2.1.6,<3.0.0" -genson = "1.2.2" -isodate = ">=0.6.1,<0.7.0" -Jinja2 = ">=3.1.2,<3.2.0" -jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" -langchain_core = "0.1.42" -nltk = "3.8.1" -orjson = ">=3.10.7,<4.0.0" -pendulum = "<3.0.0" -pydantic = ">=2.7,<3.0" -pyjwt = ">=2.8.0,<3.0.0" -pyrate-limiter = ">=3.1.0,<3.2.0" -python-dateutil = "*" -pytz = "2024.1" -PyYAML = ">=6.0.1,<7.0.0" -requests = "*" -requests_cache = "*" -wcmatch = "8.4" - -[package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pandas (==2.2.0)", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] - -[[package]] -name = "airbyte-protocol-models-pdv2" -version = "0.12.2" -description = "Declares the Airbyte Protocol." -optional = false -python-versions = ">=3.8" -files = [ - {file = "airbyte_protocol_models_pdv2-0.12.2-py3-none-any.whl", hash = "sha256:8b3f9d0388928547cdf2e9134c0d589e4bcaa6f63bf71a21299f6824bfb7ad0e"}, - {file = "airbyte_protocol_models_pdv2-0.12.2.tar.gz", hash = "sha256:130c9ab289f3f53749ce63ff1abbfb67a44b7e5bd2794865315a2976138b672b"}, -] - -[package.dependencies] -pydantic = ">=2.7.2,<3.0.0" - -[[package]] -name = "annotated-types" -version = "0.7.0" -description = "Reusable constraint types to use with typing.Annotated" -optional = false -python-versions = ">=3.8" -files = [ - {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, - {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, -] - -[[package]] -name = "anyio" -version = "4.6.2.post1" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.9" -files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, -] - -[package.dependencies] -exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} - -[package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] -trio = ["trio (>=0.26.1)"] - -[[package]] -name = "attrs" -version = "24.2.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" -files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, -] - -[package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] - -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "bracex" -version = "2.5.post1" -description = "Bash style brace expander." -optional = false -python-versions = ">=3.8" -files = [ - {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, - {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, -] - -[[package]] -name = "cachetools" -version = "5.5.0" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, - {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, -] - -[[package]] -name = "cattrs" -version = "24.1.2" -description = "Composable complex class support for attrs and dataclasses." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, - {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, -] - -[package.dependencies] -attrs = ">=23.1.0" -exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} - -[package.extras] -bson = ["pymongo (>=4.4.0)"] -cbor2 = ["cbor2 (>=5.4.6)"] -msgpack = ["msgpack (>=1.0.5)"] -msgspec = ["msgspec (>=0.18.5)"] -orjson = ["orjson (>=3.9.2)"] -pyyaml = ["pyyaml (>=6.0)"] -tomlkit = ["tomlkit (>=0.11.8)"] -ujson = ["ujson (>=5.7.0)"] - -[[package]] -name = "certifi" -version = "2024.8.30" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, -] - -[[package]] -name = "cffi" -version = "1.17.1" -description = "Foreign Function Interface for Python calling C code." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, - {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, - {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, - {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, - {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, - {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, - {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, - {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, - {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, - {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, - {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, - {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, - {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, - {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, - {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, - {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, -] - -[package.dependencies] -pycparser = "*" - -[[package]] -name = "charset-normalizer" -version = "3.4.0" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, -] - -[[package]] -name = "click" -version = "8.1.7" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -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 = "cryptography" -version = "42.0.8" -description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -optional = false -python-versions = ">=3.7" -files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, -] - -[package.dependencies] -cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} - -[package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] -docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] -nox = ["nox"] -pep8test = ["check-sdist", "click", "mypy", "ruff"] -sdist = ["build"] -ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] -test-randomorder = ["pytest-randomly"] - -[[package]] -name = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - -[[package]] -name = "dpath" -version = "2.2.0" -description = "Filesystem-like pathing and searching for dictionaries" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dpath-2.2.0-py3-none-any.whl", hash = "sha256:b330a375ded0a0d2ed404440f6c6a715deae5313af40bbb01c8a41d891900576"}, - {file = "dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "genson" -version = "1.2.2" -description = "GenSON is a powerful, user-friendly JSON Schema generator." -optional = false -python-versions = "*" -files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, -] - -[[package]] -name = "h11" -version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.7" -files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, -] - -[[package]] -name = "httpcore" -version = "1.0.6" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.13,<0.15" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<1.0)"] - -[[package]] -name = "httpx" -version = "0.27.2" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isodate" -version = "0.6.1" -description = "An ISO 8601 date/time/duration parser and formatter" -optional = false -python-versions = "*" -files = [ - {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, - {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "jinja2" -version = "3.1.4" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "joblib" -version = "1.4.2" -description = "Lightweight pipelining with Python functions" -optional = false -python-versions = ">=3.8" -files = [ - {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, - {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, -] - -[[package]] -name = "jsonpatch" -version = "1.33" -description = "Apply JSON-Patches (RFC 6902)" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" -files = [ - {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, - {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, -] - -[package.dependencies] -jsonpointer = ">=1.9" - -[[package]] -name = "jsonpointer" -version = "3.0.0" -description = "Identify specific nodes in a JSON document (RFC 6901)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, - {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, -] - -[[package]] -name = "jsonref" -version = "0.2" -description = "An implementation of JSON Reference for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonref-0.2-py3-none-any.whl", hash = "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f"}, - {file = "jsonref-0.2.tar.gz", hash = "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697"}, -] - -[[package]] -name = "jsonschema" -version = "3.2.0" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, -] - -[package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" - -[package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] - -[[package]] -name = "langchain-core" -version = "0.1.42" -description = "Building applications with LLMs through composability" -optional = false -python-versions = "<4.0,>=3.8.1" -files = [ - {file = "langchain_core-0.1.42-py3-none-any.whl", hash = "sha256:c5653ffa08a44f740295c157a24c0def4a753333f6a2c41f76bf431cd00be8b5"}, - {file = "langchain_core-0.1.42.tar.gz", hash = "sha256:40751bf60ea5d8e2b2efe65290db434717ee3834870c002e40e2811f09d814e6"}, -] - -[package.dependencies] -jsonpatch = ">=1.33,<2.0" -langsmith = ">=0.1.0,<0.2.0" -packaging = ">=23.2,<24.0" -pydantic = ">=1,<3" -PyYAML = ">=5.3" -tenacity = ">=8.1.0,<9.0.0" - -[package.extras] -extended-testing = ["jinja2 (>=3,<4)"] - -[[package]] -name = "langsmith" -version = "0.1.137" -description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." -optional = false -python-versions = "<4.0,>=3.8.1" -files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, -] - -[package.dependencies] -httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" -pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} -requests = ">=2,<3" -requests-toolbelt = ">=1.0.0,<2.0.0" - -[[package]] -name = "markupsafe" -version = "3.0.2" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -files = [ - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, - {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, -] - -[[package]] -name = "nltk" -version = "3.8.1" -description = "Natural Language Toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "nltk-3.8.1-py3-none-any.whl", hash = "sha256:fd5c9109f976fa86bcadba8f91e47f5e9293bd034474752e92a520f81c93dda5"}, - {file = "nltk-3.8.1.zip", hash = "sha256:1834da3d0682cba4f2cede2f9aad6b0fafb6461ba451db0efb6f9c39798d64d3"}, -] - -[package.dependencies] -click = "*" -joblib = "*" -regex = ">=2021.8.3" -tqdm = "*" - -[package.extras] -all = ["matplotlib", "numpy", "pyparsing", "python-crfsuite", "requests", "scikit-learn", "scipy", "twython"] -corenlp = ["requests"] -machine-learning = ["numpy", "python-crfsuite", "scikit-learn", "scipy"] -plot = ["matplotlib"] -tgrep = ["pyparsing"] -twitter = ["twython"] - -[[package]] -name = "orjson" -version = "3.10.10" -description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" -optional = false -python-versions = ">=3.8" -files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, -] - -[[package]] -name = "packaging" -version = "23.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, -] - -[[package]] -name = "pendulum" -version = "2.1.2" -description = "Python datetimes made easy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, - {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, - {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, - {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, - {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, - {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, - {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, - {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, - {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, - {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, - {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, -] - -[package.dependencies] -python-dateutil = ">=2.6,<3.0" -pytzdata = ">=2020.1" - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pycparser" -version = "2.22" -description = "C parser in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, - {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, -] - -[[package]] -name = "pydantic" -version = "2.9.2" -description = "Data validation using Python type hints" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, -] - -[package.dependencies] -annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} - -[package.extras] -email = ["email-validator (>=2.0.0)"] -timezone = ["tzdata"] - -[[package]] -name = "pydantic-core" -version = "2.23.4" -description = "Core functionality for Pydantic validation and serialization" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, -] - -[package.dependencies] -typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" - -[[package]] -name = "pyjwt" -version = "2.9.0" -description = "JSON Web Token implementation in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, -] - -[package.extras] -crypto = ["cryptography (>=3.4.0)"] -dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] -docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] -tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] - -[[package]] -name = "pyrate-limiter" -version = "3.1.1" -description = "Python Rate-Limiter using Leaky-Bucket Algorithm" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, - {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, -] - -[package.extras] -all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] -docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] - -[[package]] -name = "pyrsistent" -version = "0.20.0" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7"}, - {file = "pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee"}, - {file = "pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d"}, - {file = "pyrsistent-0.20.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win32.whl", hash = "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d"}, - {file = "pyrsistent-0.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win32.whl", hash = "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf"}, - {file = "pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b"}, - {file = "pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4"}, -] - -[[package]] -name = "pytest" -version = "8.3.3" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=1.5,<2" -tomli = {version = ">=1", markers = "python_version < \"3.11\""} - -[package.extras] -dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-mock" -version = "3.14.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, -] - -[package.dependencies] -pytest = ">=6.2.5" - -[package.extras] -dev = ["pre-commit", "pytest-asyncio", "tox"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytz" -version = "2024.1" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, -] - -[[package]] -name = "pytzdata" -version = "2020.1" -description = "The Olson timezone database for Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, - {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "regex" -version = "2024.9.11" -description = "Alternative regular expression module, to replace re." -optional = false -python-versions = ">=3.8" -files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-cache" -version = "1.2.1" -description = "A persistent cache for python requests" -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, - {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, -] - -[package.dependencies] -attrs = ">=21.2" -cattrs = ">=22.2" -platformdirs = ">=2.5" -requests = ">=2.22" -url-normalize = ">=1.4" -urllib3 = ">=1.25.5" - -[package.extras] -all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] -bson = ["bson (>=0.5)"] -docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] -dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] -json = ["ujson (>=5.4)"] -mongodb = ["pymongo (>=3)"] -redis = ["redis (>=3)"] -security = ["itsdangerous (>=2.0)"] -yaml = ["pyyaml (>=6.0.1)"] - -[[package]] -name = "requests-mock" -version = "1.12.1" -description = "Mock out responses from the requests package" -optional = false -python-versions = ">=3.5" -files = [ - {file = "requests-mock-1.12.1.tar.gz", hash = "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401"}, - {file = "requests_mock-1.12.1-py2.py3-none-any.whl", hash = "sha256:b1e37054004cdd5e56c84454cc7df12b25f90f382159087f4b6915aaeef39563"}, -] - -[package.dependencies] -requests = ">=2.22,<3" - -[package.extras] -fixture = ["fixtures"] - -[[package]] -name = "requests-toolbelt" -version = "1.0.0" -description = "A utility belt for advanced users of python-requests" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, - {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, -] - -[package.dependencies] -requests = ">=2.0.1,<3.0.0" - -[[package]] -name = "setuptools" -version = "75.3.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - -[[package]] -name = "tenacity" -version = "8.5.0" -description = "Retry code until it succeeds" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, - {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, -] - -[package.extras] -doc = ["reno", "sphinx"] -test = ["pytest", "tornado (>=4.5)", "typeguard"] - -[[package]] -name = "tomli" -version = "2.0.2" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, -] - -[[package]] -name = "tqdm" -version = "4.66.6" -description = "Fast, Extensible Progress Meter" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63"}, - {file = "tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] -notebook = ["ipywidgets (>=6)"] -slack = ["slack-sdk"] -telegram = ["requests"] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "url-normalize" -version = "1.4.3" -description = "URL normalization for Python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, - {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "urllib3" -version = "2.2.3" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "wcmatch" -version = "8.4" -description = "Wildcard/glob file name matcher." -optional = false -python-versions = ">=3.7" -files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, -] - -[package.dependencies] -bracex = ">=2.1.1" - -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.10,<3.12" -content-hash = "e75fecfda21bb185122d6218ee0e5cc1318b240bef1db615ed5052597e23ba11" diff --git a/airbyte-integrations/connectors/source-intercom/pyproject.toml b/airbyte-integrations/connectors/source-intercom/pyproject.toml deleted file mode 100644 index 8b35413efe2e..000000000000 --- a/airbyte-integrations/connectors/source-intercom/pyproject.toml +++ /dev/null @@ -1,28 +0,0 @@ -[build-system] -requires = [ "poetry-core>=1.0.0",] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -version = "0.8.2" -name = "source-intercom" -description = "Source implementation for Intercom Yaml." -authors = [ "Airbyte ",] -license = "MIT" -readme = "README.md" -documentation = "https://docs.airbyte.com/integrations/sources/intercom" -homepage = "https://airbyte.com" -repository = "https://github.com/airbytehq/airbyte" -[[tool.poetry.packages]] -include = "source_intercom" - -[tool.poetry.dependencies] -python = "^3.10,<3.12" -airbyte-cdk = "^4.5.4" - -[tool.poetry.scripts] -source-intercom = "source_intercom.run:run" - -[tool.poetry.group.dev.dependencies] -requests-mock = "^1.9.3" -pytest-mock = "^3.12.0" -pytest = "^8.0.0" diff --git a/airbyte-integrations/connectors/source-intercom/source_intercom/__init__.py b/airbyte-integrations/connectors/source-intercom/source_intercom/__init__.py deleted file mode 100644 index de88c85697a0..000000000000 --- a/airbyte-integrations/connectors/source-intercom/source_intercom/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2022 Airbyte, Inc., all rights reserved. -# - - -from .source import SourceIntercom - -__all__ = ["SourceIntercom"] diff --git a/airbyte-integrations/connectors/source-intercom/source_intercom/components.py b/airbyte-integrations/connectors/source-intercom/source_intercom/components.py deleted file mode 100644 index 4d3670c9490d..000000000000 --- a/airbyte-integrations/connectors/source-intercom/source_intercom/components.py +++ /dev/null @@ -1,375 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from dataclasses import InitVar, dataclass, field -from functools import wraps -from time import sleep -from typing import Any, Iterable, List, Mapping, Optional, Union - -import requests -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.declarative.incremental import DeclarativeCursor -from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString -from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig -from airbyte_cdk.sources.declarative.requesters.error_handlers import DefaultErrorHandler -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOptionType -from airbyte_cdk.sources.declarative.types import Config, Record, StreamSlice, StreamState -from airbyte_cdk.sources.streams.core import Stream -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution - -RequestInput = Union[str, Mapping[str, str]] - - -@dataclass -class IncrementalSingleSliceCursor(DeclarativeCursor): - cursor_field: Union[InterpolatedString, str] - config: Config - parameters: InitVar[Mapping[str, Any]] - - def __post_init__(self, parameters: Mapping[str, Any]): - self._state = {} - self._cursor = None - self.cursor_field = InterpolatedString.create(self.cursor_field, parameters=parameters) - - def get_request_params( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - # Current implementation does not provide any options to update request params. - # Returns empty dict - return self._get_request_option(RequestOptionType.request_parameter, stream_slice) - - def get_request_headers( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - # Current implementation does not provide any options to update request headers. - # Returns empty dict - return self._get_request_option(RequestOptionType.header, stream_slice) - - def get_request_body_data( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - # Current implementation does not provide any options to update body data. - # Returns empty dict - return self._get_request_option(RequestOptionType.body_data, stream_slice) - - def get_request_body_json( - self, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Optional[Mapping]: - # Current implementation does not provide any options to update body json. - # Returns empty dict - return self._get_request_option(RequestOptionType.body_json, stream_slice) - - def _get_request_option(self, option_type: RequestOptionType, stream_slice: StreamSlice): - return {} - - def get_stream_state(self) -> StreamState: - return self._state - - def select_state(self, stream_slice: Optional[StreamSlice] = None) -> Optional[StreamState]: - return self.get_stream_state() - - def set_initial_state(self, stream_state: StreamState): - cursor_field = self.cursor_field.eval(self.config) - cursor_value = stream_state.get(cursor_field) - if cursor_value: - self._state[cursor_field] = cursor_value - self._state["prior_state"] = self._state.copy() - self._cursor = cursor_value - - def observe(self, stream_slice: StreamSlice, record: Record) -> None: - """ - Register a record with the cursor; the cursor instance can then use it to manage the state of the in-progress stream read. - - :param stream_slice: The current slice, which may or may not contain the most recently observed record - :param record: the most recently-read record, which the cursor can use to update the stream state. Outwardly-visible changes to the - stream state may need to be deferred depending on whether the source reliably orders records by the cursor field. - """ - record_cursor_value = record.get(self.cursor_field.eval(self.config)) - if not record_cursor_value: - return - - if self.is_greater_than_or_equal(record, self._state): - self._cursor = record_cursor_value - - def close_slice(self, stream_slice: StreamSlice, *args: Any) -> None: - cursor_field = self.cursor_field.eval(self.config) - self._state[cursor_field] = self._cursor - - def stream_slices(self) -> Iterable[Mapping[str, Any]]: - yield StreamSlice(partition={}, cursor_slice={}) - - def should_be_synced(self, record: Record) -> bool: - """ - Evaluating if a record should be synced allows for filtering and stop condition on pagination - """ - record_cursor_value = record.get(self.cursor_field.eval(self.config)) - return bool(record_cursor_value) - - def is_greater_than_or_equal(self, first: Record, second: Record) -> bool: - """ - Evaluating which record is greater in terms of cursor. This is used to avoid having to capture all the records to close a slice - """ - cursor_field = self.cursor_field.eval(self.config) - first_cursor_value = first.get(cursor_field) if first else None - second_cursor_value = second.get(cursor_field) if second else None - if first_cursor_value and second_cursor_value: - return first_cursor_value > second_cursor_value - elif first_cursor_value: - return True - else: - return False - - -@dataclass -class IncrementalSubstreamSlicerCursor(IncrementalSingleSliceCursor): - parent_stream_configs: List[ParentStreamConfig] - parent_complete_fetch: bool = field(default=False) - - def __post_init__(self, parameters: Mapping[str, Any]): - super().__post_init__(parameters) - - if not self.parent_stream_configs: - raise ValueError("IncrementalSubstreamSlicer needs at least 1 parent stream") - - # parent stream parts - self.parent_config: ParentStreamConfig = self.parent_stream_configs[0] - self.parent_stream: Stream = self.parent_config.stream - self.parent_stream_name: str = self.parent_stream.name - self.parent_cursor_field: str = self.parent_stream.cursor_field - self.parent_sync_mode: SyncMode = SyncMode.incremental if self.parent_stream.supports_incremental is True else SyncMode.full_refresh - self.substream_slice_field: str = self.parent_stream_configs[0].partition_field.eval(self.config) - self.parent_field: str = self.parent_stream_configs[0].parent_key.eval(self.config) - self._parent_cursor: Optional[str] = None - - def set_initial_state(self, stream_state: StreamState): - super().set_initial_state(stream_state=stream_state) - if self.parent_stream_name in stream_state and stream_state.get(self.parent_stream_name, {}).get(self.parent_cursor_field): - parent_stream_state = { - self.parent_cursor_field: stream_state[self.parent_stream_name][self.parent_cursor_field], - } - self._state[self.parent_stream_name] = parent_stream_state - if "prior_state" in self._state: - self._state["prior_state"][self.parent_stream_name] = parent_stream_state - - def observe(self, stream_slice: StreamSlice, record: Record) -> None: - """ - Extended the default method to be able to track the parent STATE. - """ - - # save parent cursor value (STATE) from slice - parent_cursor = stream_slice.get(self.parent_stream_name) - if parent_cursor: - self._parent_cursor = parent_cursor.get(self.parent_cursor_field) - - # observe the substream - super().observe(stream_slice, record) - - def close_slice(self, stream_slice: StreamSlice, *args: Any) -> None: - super().close_slice(stream_slice, *args) - - def stream_slices(self) -> Iterable[Mapping[str, Any]]: - parent_state = (self._state or {}).get(self.parent_stream_name, {}) - slices_generator: Iterable[StreamSlice] = self.read_parent_stream(self.parent_sync_mode, self.parent_cursor_field, parent_state) - yield from [slice for slice in slices_generator] if self.parent_complete_fetch else slices_generator - - def track_parent_cursor(self, parent_record: dict) -> None: - """ - Tracks the Parent Stream Cursor, using `parent_cursor_field`. - """ - self._parent_cursor = parent_record.get(self.parent_cursor_field) - if self._parent_cursor: - self._state[self.parent_stream_name] = {self.parent_cursor_field: self._parent_cursor} - - def read_parent_stream( - self, - sync_mode: SyncMode, - cursor_field: Optional[str], - stream_state: Mapping[str, Any], - ) -> Iterable[Mapping[str, Any]]: - - self.parent_stream.state = stream_state - - parent_stream_slices_gen = self.parent_stream.stream_slices( - sync_mode=sync_mode, - cursor_field=cursor_field, - stream_state=stream_state, - ) - - for parent_slice in parent_stream_slices_gen: - parent_records_gen = self.parent_stream.read_records( - sync_mode=sync_mode, - cursor_field=cursor_field, - stream_slice=parent_slice, - stream_state=stream_state, - ) - - for parent_record in parent_records_gen: - # update parent cursor - self.track_parent_cursor(parent_record) - substream_slice_value = parent_record.get(self.parent_field) - if substream_slice_value: - cursor_field = self.cursor_field.eval(self.config) - substream_cursor_value = self._state.get(cursor_field) - parent_cursor_value = self._state.get(self.parent_stream_name, {}).get(self.parent_cursor_field) - yield StreamSlice( - partition={ - self.substream_slice_field: substream_slice_value, - }, - cursor_slice={ - cursor_field: substream_cursor_value, - self.parent_stream_name: { - self.parent_cursor_field: parent_cursor_value, - }, - }, - ) - - -@dataclass -class IntercomRateLimiter: - """ - Define timings for RateLimits. Adjust timings if needed. - :: on_unknown_load = 1.0 sec - Intercom recommended time to hold between each API call. - :: on_low_load = 0.01 sec (10 miliseconds) - ideal ratio between hold time and api call, also the standard hold time between each API call. - :: on_mid_load = 1.5 sec - great timing to retrieve another 15% of request capacity while having mid_load. - :: on_high_load = 8.0 sec - ideally we should wait 5.0 sec while having high_load, but we hold 8 sec to retrieve up to 80% of request capacity. - """ - - threshold: float = 0.1 - on_unknown_load: float = 1.0 - on_low_load: float = 0.01 - on_mid_load: float = 1.5 - on_high_load: float = 8.0 # max time - - @staticmethod - def backoff_time(backoff_time: float): - return sleep(backoff_time) - - @staticmethod - def _define_values_from_headers( - current_rate_header_value: Optional[float], - total_rate_header_value: Optional[float], - threshold: float = threshold, - ) -> tuple[float, Union[float, str]]: - # define current load and cutoff from rate_limits - if current_rate_header_value and total_rate_header_value: - cutoff: float = (total_rate_header_value / 2) / total_rate_header_value - load: float = current_rate_header_value / total_rate_header_value - else: - # to guarantee cutoff value to be exactly 1 sec, based on threshold, if headers are not available - cutoff: float = threshold * (1 / threshold) - load = None - return cutoff, load - - @staticmethod - def _convert_load_to_backoff_time( - cutoff: float, - load: Optional[float] = None, - threshold: float = threshold, - ) -> float: - # define backoff_time based on load conditions - if not load: - backoff_time = IntercomRateLimiter.on_unknown_load - elif load <= threshold: - backoff_time = IntercomRateLimiter.on_high_load - elif load <= cutoff: - backoff_time = IntercomRateLimiter.on_mid_load - elif load > cutoff: - backoff_time = IntercomRateLimiter.on_low_load - return backoff_time - - @staticmethod - def get_backoff_time( - *args, - threshold: float = threshold, - rate_limit_header: str = "X-RateLimit-Limit", - rate_limit_remain_header: str = "X-RateLimit-Remaining", - ): - """ - To avoid reaching Intercom API Rate Limits, use the 'X-RateLimit-Limit','X-RateLimit-Remaining' header values, - to determine the current rate limits and load and handle backoff_time based on load %. - Recomended backoff_time between each request is 1 sec, we would handle this dynamicaly. - :: threshold - is the % cutoff for the rate_limits % load, if this cutoff is crossed, - the connector waits `sleep_on_high_load` amount of time, default value = 0.1 (10% left from max capacity) - :: backoff_time - time between each request = 200 miliseconds - :: rate_limit_header - responce header item, contains information with max rate_limits available (max) - :: rate_limit_remain_header - responce header item, contains information with how many requests are still available (current) - Header example: - { - X-RateLimit-Limit: 100 - X-RateLimit-Remaining: 51 - X-RateLimit-Reset: 1487332510 - }, - where: 51 - requests remains and goes down, 100 - max requests capacity. - More information: https://developers.intercom.com/intercom-api-reference/reference/rate-limiting - """ - - # find the requests.Response inside args list - for arg in args: - if isinstance(arg, requests.models.Response): - headers = arg.headers or {} - - # Get the rate_limits from response - total_rate = int(headers.get(rate_limit_header, 0)) if headers else None - current_rate = int(headers.get(rate_limit_remain_header, 0)) if headers else None - cutoff, load = IntercomRateLimiter._define_values_from_headers( - current_rate_header_value=current_rate, - total_rate_header_value=total_rate, - threshold=threshold, - ) - - backoff_time = IntercomRateLimiter._convert_load_to_backoff_time(cutoff=cutoff, load=load, threshold=threshold) - return backoff_time - - @staticmethod - def balance_rate_limit( - threshold: float = threshold, - rate_limit_header: str = "X-RateLimit-Limit", - rate_limit_remain_header: str = "X-RateLimit-Remaining", - ): - """ - The decorator function. - Adjust `threshold`,`rate_limit_header`,`rate_limit_remain_header` if needed. - """ - - def decorator(func): - @wraps(func) - def wrapper_balance_rate_limit(*args, **kwargs): - IntercomRateLimiter.backoff_time( - IntercomRateLimiter.get_backoff_time( - *args, threshold=threshold, rate_limit_header=rate_limit_header, rate_limit_remain_header=rate_limit_remain_header - ) - ) - return func(*args, **kwargs) - - return wrapper_balance_rate_limit - - return decorator - - -class ErrorHandlerWithRateLimiter(DefaultErrorHandler): - """ - The difference between the built-in `DefaultErrorHandler` and this one is the custom decorator, - applied on top of `interpret_response` to preserve the api calls for a defined amount of time, - calculated using the rate limit headers and not use the custom backoff strategy, - since we deal with Response.status_code == 200, - the default requester's logic doesn't allow to handle the status of 200 with `should_retry()`. - """ - - # The RateLimiter is applied to balance the api requests. - @IntercomRateLimiter.balance_rate_limit() - def interpret_response(self, response_or_exception: Optional[Union[requests.Response, Exception]]) -> ErrorResolution: - # Check for response.headers to define the backoff time before the next api call - return super().interpret_response(response_or_exception) diff --git a/airbyte-integrations/connectors/source-intercom/source_intercom/manifest.yaml b/airbyte-integrations/connectors/source-intercom/source_intercom/manifest.yaml deleted file mode 100644 index feb1122b22e1..000000000000 --- a/airbyte-integrations/connectors/source-intercom/source_intercom/manifest.yaml +++ /dev/null @@ -1,2408 +0,0 @@ -version: 0.72.1 - -definitions: - ## bases - selector: - description: "Base records selector for Full Refresh streams" - extractor: - type: DpathExtractor - field_path: ["{{ parameters.get('data_field', 'data')}}"] - requester: - description: "Base Requester for Full Refresh streams" - type: HttpRequester - url_base: "https://api.intercom.io/" - http_method: "GET" - authenticator: - type: BearerAuthenticator - api_token: "{{ config['access_token'] }}" - request_headers: - # There is a bug in interpolation, causing the `2.10` string to be evaluated to `2.1`, cutting off the `0`. - # the workaround is to put the `string` inside the `string`, then it's evaluated properly to `2.10` - Intercom-Version: "'2.10'" - Accept: "application/json" - error_handler: - type: CustomErrorHandler - class_name: source_intercom.components.ErrorHandlerWithRateLimiter - response_filters: - - type: HttpResponseFilter - error_message_contains: "Active subscription needed" - action: FAIL - failure_type: config_error - error_message: "Failed to perform request. Error: Active subscription needed. Please, validate your current Intercom plan to continue using API." - retriever: - description: "Base Retriever for Full Refresh streams" - record_selector: - $ref: "#/definitions/selector" - requester: - $ref: "#/definitions/requester" - paginator: - type: "DefaultPaginator" - url_base: "#/definitions/requester/url_base" - pagination_strategy: - type: "CursorPagination" - cursor_value: "{{ response.get('pages', {}).get('next') }}" - stop_condition: "{{ 'next' not in response.get('pages', {}) }}" - page_size: 150 - page_size_option: - inject_into: request_parameter - field_name: per_page - page_token_option: - type: RequestPath - requester_incremental_search: - $ref: "#/definitions/requester" - http_method: "POST" - request_body_json: - query: - "{ 'operator': 'OR', 'value': [ { 'field': 'updated_at', 'operator': - '>', 'value': {{ stream_slice.get('prior_state', stream_state.get('prior_state', - {})).get('updated_at') or format_datetime(config['start_date'], '%s') }} }, - { 'field': 'updated_at', 'operator': '=', 'value': {{ stream_slice.get('prior_state', - stream_state.get('prior_state', {})).get('updated_at') or format_datetime(config['start_date'], - '%s') }} }, ], }" - sort: "{'field': 'updated_at', 'order': 'ascending'}" - pagination: - "{ 'per_page': {{ parameters.get('page_size') }}, 'page': {{ next_page_token.get('next_page_token').get('page') - }}, 'starting_after': '{{ next_page_token.get('next_page_token').get('starting_after') - }}' }" - - ## streams - # full-refresh - stream_full_refresh: - retriever: - $ref: "#/definitions/retriever" - admins: - description: "https://developers.intercom.com/intercom-api-reference/reference#list-admins" - $ref: "#/definitions/stream_full_refresh" - $parameters: - name: "admins" - primary_key: "id" - path: "admins" - data_field: "admins" - schema_loader: - type: InlineSchemaLoader - schema: - type: object - properties: - admin_ids: - description: Array of unique identifiers for admins - anyOf: - - type: array - items: - type: integer - - type: "null" - avatar: - description: Admin avatar details - type: - - "null" - - object - properties: - image_url: - description: URL of the admin's avatar image - type: - - "null" - - string - away_mode_enabled: - description: Flag indicating if away mode is enabled for the admin - type: - - "null" - - boolean - away_mode_reassign: - description: - Flag indicating if away mode reassignment is enabled for - the admin - type: - - "null" - - boolean - email: - description: Email address of the admin - type: - - "null" - - string - has_inbox_seat: - description: Flag indicating if the admin has a seat in the inbox - type: - - "null" - - boolean - id: - description: Unique identifier for the admin - type: - - "null" - - string - job_title: - description: Job title of the admin - type: - - "null" - - string - name: - description: Name of the admin - type: - - "null" - - string - team_ids: - description: Array of team identifiers the admin belongs to - anyOf: - - type: array - items: - type: integer - - type: "null" - type: - description: Type of the admin (e.g., full-time, part-time) - type: - - "null" - - string - team_priority_level: - description: Detailed team priority level information for the admin - type: - - "null" - - object - properties: - primary_team_ids: - description: Array of primary team identifiers for the admin - type: - - "null" - - array - items: - type: - - "null" - - integer - secondary_team_ids: - description: Array of secondary team identifiers for the admin - type: - - "null" - - array - items: - type: - - "null" - - integer - tags: - description: "https://developers.intercom.com/intercom-api-reference/reference#list-tags-for-an-app" - $ref: "#/definitions/stream_full_refresh" - $parameters: - name: "tags" - primary_key: "name" - path: "tags" - schema_loader: - type: InlineSchemaLoader - schema: - type: object - properties: - id: - description: Unique identifier for the tag. - type: - - "null" - - string - name: - description: Name of the tag used for identification. - type: - - "null" - - string - type: - description: Type of the tag indicating its purpose or category. - type: - - "null" - - string - teams: - description: "https://developers.intercom.com/intercom-api-reference/reference#list-teams" - $ref: "#/definitions/stream_full_refresh" - $parameters: - name: "teams" - primary_key: "name" - path: "teams" - data_field: "teams" - - schema_loader: - type: InlineSchemaLoader - schema: - type: object - properties: - admin_ids: - description: Array of user IDs representing the admins of the team. - anyOf: - - type: array - items: - type: integer - - type: "null" - id: - description: Unique identifier for the team. - type: - - "null" - - string - name: - description: Name of the team. - type: - - "null" - - string - type: - description: Type of team (e.g., 'internal', 'external'). - type: - - "null" - - string - stream_data_attributes: - description: "https://developers.intercom.com/intercom-api-reference/reference#list-data-attributes" - $ref: "#/definitions/stream_full_refresh" - retriever: - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - request_parameters: - model: "{{ parameters.get('model') }}" - company_attributes: - description: "https://developers.intercom.com/intercom-api-reference/reference#list-data-attributes" - $ref: "#/definitions/stream_data_attributes" - $parameters: - name: "company_attributes" - primary_key: "name" - path: "data_attributes" - model: "company" - schema_loader: - type: InlineSchemaLoader - schema: - type: object - properties: - id: - description: Unique ID assigned to the company attribute. - type: - - "null" - - integer - admin_id: - description: The ID of the admin user associated with the company. - type: - - "null" - - string - api_writable: - description: Indicates whether the field is writable through the API. - type: - - "null" - - boolean - archived: - description: Flag to indicate if the company data is archived. - type: - - "null" - - boolean - created_at: - description: Timestamp when the company data was created. - type: - - "null" - - integer - custom: - description: Custom attribute specific to the company. - type: - - "null" - - boolean - data_type: - description: Type of data stored in the attribute field. - type: - - "null" - - string - description: - description: Description or details about the company attribute. - type: - - "null" - - string - full_name: - description: Full name associated with the company. - type: - - "null" - - string - label: - description: Label or display name for the company attribute. - type: - - "null" - - string - model: - description: Model or schema used for storing the company attribute. - type: - - "null" - - string - name: - description: Name of the company attribute. - type: - - "null" - - string - options: - description: Available options or values for the company attribute. - anyOf: - - type: array - items: - type: string - - type: "null" - type: - description: Type of data structure for the company attribute. - type: - - "null" - - string - ui_writable: - description: Indicates whether the field is writable through the UI. - type: - - "null" - - boolean - updated_at: - description: Timestamp when the company data was last updated. - type: - - "null" - - integer - messenger_writable: - description: Indicates whether the field is writable through the messenger. - type: - - "null" - - boolean - contact_attributes: - description: "https://developers.intercom.com/intercom-api-reference/reference#list-data-attributes" - $ref: "#/definitions/stream_data_attributes" - $parameters: - name: "contact_attributes" - primary_key: "name" - path: "data_attributes" - model: "contact" - - # semi-incremental - # (full-refresh and emit records >= *prior state) - # (prior state - frozen state from previous sync, it automatically updates with next sync) - schema_loader: - type: InlineSchemaLoader - schema: - type: object - properties: - id: - description: Unique identifier for the contact attribute. - type: - - "null" - - integer - type: - description: The type of contact attribute (e.g., text, number, boolean). - type: - - "null" - - string - model: - description: Model to which the contact attribute is associated. - type: - - "null" - - string - name: - description: The name of the contact attribute. - type: - - "null" - - string - full_name: - description: The full name associated with the contact attribute. - type: - - "null" - - string - label: - description: Label representing the attribute in user interfaces. - type: - - "null" - - string - description: - description: Description of the contact attribute for better understanding. - type: - - "null" - - string - data_type: - description: The data type of the contact attribute value. - type: - - "null" - - string - options: - description: List of available options for the attribute. - type: - - "null" - - array - items: - type: - - "null" - - string - api_writable: - description: Indicates whether the attribute is writable via API. - type: - - "null" - - boolean - ui_writable: - description: Indicates whether the attribute is writable via user interface. - type: - - "null" - - boolean - custom: - description: Indicates if the attribute is a custom user-defined field. - type: - - "null" - - boolean - archived: - description: Flag to signify if the contact attribute is archived. - type: - - "null" - - boolean - admin_id: - description: - Unique identifier for the admin associated with the contact - attribute. - type: - - "null" - - string - created_at: - description: Timestamp of when the contact attribute was created. - type: - - "null" - - integer - updated_at: - description: Timestamp of when the contact attribute was last updated. - type: - - "null" - - integer - messenger_writable: - description: Indicates whether the attribute is writable via messenger. - type: - - "null" - - boolean - stream_semi_incremental: - $ref: "#/definitions/stream_full_refresh" - incremental_sync: - type: CustomIncrementalSync - class_name: source_intercom.components.IncrementalSingleSliceCursor - cursor_field: "updated_at" - retriever: - $ref: "#/definitions/stream_full_refresh/retriever" - record_selector: - $ref: "#/definitions/selector" - record_filter: - condition: - "{{ record['updated_at'] >= ( stream_state.get('prior_state', - {}).get('updated_at', 0) - (config.get('lookback_window', 0) * 86400) if stream_state else stream_slice.get('prior_state', - {}).get('updated_at', 0) ) - (config.get('lookback_window', 0) * 86400) }}" - segments: - description: "https://developers.intercom.com/intercom-api-reference/reference#list-segments" - $ref: "#/definitions/stream_semi_incremental" - $parameters: - name: "segments" - primary_key: "id" - path: "segments" - data_field: "segments" - schema_loader: - type: InlineSchemaLoader - schema: - type: object - properties: - created_at: - description: The date and time when the segment was created - type: - - "null" - - integer - count: - description: The number of items in the segment - type: - - "null" - - integer - id: - description: Unique identifier for the segment - type: - - "null" - - string - name: - description: The name or title of the segment - type: - - "null" - - string - type: - description: The type or category of the segment - type: - - "null" - - string - person_type: - description: Type of persons included in the segment - type: - - "null" - - string - updated_at: - description: The date and time when the segment was last updated - type: - - "null" - - integer - companies: - description: "https://developers.intercom.com/intercom-api-reference/reference/scroll-over-all-companies" - $ref: "#/definitions/stream_semi_incremental" - $parameters: - name: "companies" - primary_key: "id" - path: "companies/scroll" - retriever: - $ref: "#/definitions/stream_semi_incremental/retriever" - paginator: - type: "DefaultPaginator" - url_base: "#/definitions/requester/url_base" - pagination_strategy: - type: "CursorPagination" - cursor_value: "{{ response.get('scroll_param') }}" - stop_condition: "{{ not response.get('data') }}" - page_size: 150 - page_size_option: - inject_into: request_parameter - field_name: per_page - page_token_option: - type: RequestOption - field_name: scroll_param - inject_into: request_parameter - requester: - $ref: "#/definitions/requester" - error_handler: - type: CompositeErrorHandler - error_handlers: - - type: DefaultErrorHandler - description: - " 400 - existing scroll_param, need to wait at least 60 sec - to continue and retry 500 - server-side error, should retry after 60 - sec. " - response_filters: - - http_codes: [400] - action: RETRY - failure_type: transient_error - error_message: "A scroll (export) job is already in progress for this Intercom account, causing the request to fail. Only one active scroll per Intercom account is allowed; ensure no overlap by limiting active connections or scheduling jobs appropriately." - - http_codes: [500] - action: RETRY - failure_type: transient_error - backoff_strategies: - - type: ConstantBackoffStrategy - backoff_time_in_seconds: 60 - - type: DefaultErrorHandler - description: - "404 - scroll_param is expired or not found while requesting, - ignore" - response_filters: - - http_codes: [404] - action: IGNORE - - # semi-incremental substreams - schema_loader: - type: InlineSchemaLoader - schema: - type: object - properties: - type: - description: The type of the company - type: - - "null" - - string - company_id: - description: The unique identifier of the company - type: - - "null" - - string - id: - description: The ID of the company - type: - - "null" - - string - app_id: - description: The ID of the application associated with the company - type: - - "null" - - string - name: - description: The name of the company - type: - - "null" - - string - created_at: - description: The date and time when the company was created - type: - - "null" - - integer - updated_at: - description: The date and time when the company was last updated - type: - - "null" - - integer - monthly_spend: - description: The monthly spend of the company - type: - - "null" - - number - multipleOf: 0.00000001 - session_count: - description: The number of sessions related to the company - type: - - "null" - - integer - user_count: - description: The number of users associated with the company - type: - - "null" - - integer - size: - description: The size of the company - type: - - "null" - - integer - tags: - description: Tags associated with the company - type: object - properties: - type: - description: The type of tags associated with the company - type: string - tags: - description: List of tags - type: array - items: - type: - - "null" - - object - properties: - type: - description: The type of the tag - type: string - name: - description: The name of the tag - type: string - id: - description: The ID of the tag - oneOf: - - type: - - "null" - - string - - type: - - "null" - - integer - segments: - description: Segments associated with the company - type: object - properties: - type: - description: The type of segments associated with the company - type: string - segments: - description: List of segments - type: array - items: - type: - - "null" - - object - properties: - type: - description: The type of the segment - type: string - id: - description: The ID of the segment - type: string - plan: - description: Details of the company's subscription plan - type: - - "null" - - object - properties: - id: - description: The ID of the subscription plan - type: - - "null" - - string - name: - description: The name of the subscription plan - type: - - "null" - - string - type: - description: The type of the subscription plan - type: - - "null" - - string - custom_attributes: - description: Custom attributes specific to the company - type: - - "null" - - object - additionalProperties: true - industry: - description: The industry in which the company operates - type: - - "null" - - string - remote_created_at: - description: The remote date and time when the company was created - type: - - "null" - - integer - website: - description: The website of the company - type: - - "null" - - string - substream_semi_incremental: - $ref: "#/definitions/stream_full_refresh" - incremental_sync: - type: CustomIncrementalSync - class_name: source_intercom.components.IncrementalSubstreamSlicerCursor - cursor_field: "updated_at" - retriever: - $ref: "#/definitions/stream_full_refresh/retriever" - paginator: - type: "NoPagination" - record_selector: - $ref: "#/definitions/selector" - record_filter: - condition: - "{{ record['updated_at'] >= stream_state.get('prior_state', {}).get('updated_at', - 0) - (config.get('lookback_window', 0) * 86400)}}" - conversation_parts: - $ref: "#/definitions/substream_semi_incremental" - incremental_sync: - $ref: "#/definitions/substream_semi_incremental/incremental_sync" - parent_stream_configs: - - type: ParentStreamConfig - stream: "#/definitions/conversations" - parent_key: "id" - partition_field: "id" - $parameters: - name: "conversation_parts" - primary_key: "id" - path: "/conversations/{{ stream_slice.id }}" - transformations: - - type: AddFields - fields: - - path: ["conversation_id"] - value: "'{{ stream_slice.id }}'" - retriever: - $ref: "#/definitions/substream_semi_incremental/retriever" - record_selector: - $ref: "#/definitions/substream_semi_incremental/retriever/record_selector" - extractor: - field_path: ["conversation_parts", "conversation_parts"] - requester: - $ref: "#/definitions/requester" - error_handler: - type: DefaultErrorHandler - description: "404 - conversation is not found while requesting, ignore" - response_filters: - - http_codes: [404] - action: IGNORE - schema_loader: - type: InlineSchemaLoader - schema: - type: object - properties: - assigned_to: - description: - The user or team member who is assigned to handle this conversation - part. - oneOf: - - type: object - properties: - type: - type: - - "null" - - string - id: - type: - - "null" - - string - - type: string - - type: "null" - attachments: - description: - Represents the attachments associated with the conversation - part. - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - type: - description: The type or category of the attachment. - type: - - "null" - - string - name: - description: The filename or name of the attachment. - type: - - "null" - - string - url: - description: The URL or location where the attachment can be accessed. - type: - - "null" - - string - content_type: - description: The MIME type of the attachment content. - type: - - "null" - - string - filesize: - description: The size of the attachment file in bytes. - type: - - "null" - - integer - height: - description: The height dimension of the attachment in pixels. - type: - - "null" - - integer - width: - description: The width dimension of the attachment in pixels. - type: - - "null" - - integer - author: - description: Represents the author of the conversation part. - type: - - "null" - - object - properties: - id: - description: The unique identifier of the conversation author. - type: - - "null" - - string - type: - description: The type of author, such as customer or agent. - type: - - "null" - - string - name: - description: The name of the conversation author. - type: - - "null" - - string - email: - description: The email address of the conversation author. - type: - - "null" - - string - body: - description: The main content or message body of the conversation part. - type: - - "null" - - string - conversation_id: - description: The unique identifier of the conversation. - type: - - "null" - - string - conversation_created_at: - description: The date and time when the conversation was created. - type: - - "null" - - integer - conversation_updated_at: - description: The date and time when the conversation was last updated. - type: - - "null" - - integer - conversation_total_parts: - description: The total number of parts in the conversation. - type: - - "null" - - integer - created_at: - description: The date and time when the conversation part was created. - type: - - "null" - - integer - external_id: - description: An external identifier associated with the conversation part. - type: - - "null" - - string - id: - description: The unique identifier of the conversation part. - type: - - "null" - - string - notified_at: - description: The date and time when the conversation part was last notified. - type: - - "null" - - integer - part_type: - description: The type or category of the conversation part. - type: - - "null" - - string - type: - description: The type of conversation part, such as message or note. - type: - - "null" - - string - updated_at: - description: The date and time when the conversation part was last updated. - type: - - "null" - - integer - redacted: - description: Indicates if the conversation part has been redacted or censored. - type: - - "null" - - boolean - company_segments: - $ref: "#/definitions/substream_semi_incremental" - $parameters: - name: "company_segments" - primary_key: "id" - path: "/companies/{{ stream_slice.id }}/segments" - incremental_sync: - $ref: "#/definitions/substream_semi_incremental/incremental_sync" - parent_complete_fetch: true - parent_stream_configs: - - type: ParentStreamConfig - stream: "#/definitions/companies" - parent_key: "id" - partition_field: "id" - retriever: - $ref: "#/definitions/substream_semi_incremental/retriever" - - # incremental search - schema_loader: - type: InlineSchemaLoader - schema: - type: object - properties: - created_at: - description: The timestamp when the company segment was created. - type: - - "null" - - integer - count: - description: The count of company segments returned in the response. - type: - - "null" - - integer - id: - description: The unique identifier associated with the company segment. - type: - - "null" - - string - name: - description: The name of the company segment. - type: - - "null" - - string - type: - description: The category or type of the company segment. - type: - - "null" - - string - person_type: - description: The type of person associated with the company segment. - type: - - "null" - - string - updated_at: - description: The timestamp when the company segment was last updated. - type: - - "null" - - integer - stream_incremental_search: - description: "https://developers.intercom.com/intercom-api-reference/reference/pagination-sorting-search" - $ref: "#/definitions/stream_full_refresh" - incremental_sync: - type: CustomIncrementalSync - class_name: source_intercom.components.IncrementalSingleSliceCursor - cursor_field: "updated_at" - retriever: - $ref: "#/definitions/stream_full_refresh/retriever" - requester: - $ref: "#/definitions/requester_incremental_search" - record_selector: - $ref: "#/definitions/selector" - record_filter: - description: "https://developers.intercom.com/intercom-api-reference/reference/pagination-sorting-search#pagination" - condition: - "{{ record['updated_at'] >= ( stream_state.get('prior_state', - {}).get('updated_at', 0) - (config.get('lookback_window', 0) * 86400) if stream_state else stream_slice.get('prior_state', - {}).get('updated_at', 0) ) - (config.get('lookback_window', 0) * 86400)}}" - paginator: - type: "DefaultPaginator" - url_base: "#/definitions/requester/url_base" - pagination_strategy: - type: "CursorPagination" - cursor_value: "{{ response.get('pages', {}).get('next') }}" - stop_condition: "{{ 'next' not in response.get('pages', {}) }}" - contacts: - $ref: "#/definitions/stream_incremental_search" - $parameters: - name: "contacts" - path: "contacts/search" - page_size: 150 - schema_loader: - type: InlineSchemaLoader - schema: - type: object - properties: - type: - description: Type of contact. - type: - - "null" - - string - id: - description: The unique identifier of the contact. - type: - - "null" - - string - workspace_id: - description: - The unique identifier of the workspace associated with the - contact. - type: - - "null" - - string - external_id: - description: External identifier for the contact. - type: - - "null" - - string - role: - description: Role or position of the contact. - type: - - "null" - - string - email: - description: The email address of the contact. - type: - - "null" - - string - phone: - description: The phone number of the contact. - type: - - "null" - - string - name: - description: The name of the contact. - type: - - "null" - - string - avatar: - description: URL pointing to the contact's avatar image. - type: - - "null" - - string - owner_id: - description: The unique identifier of the contact's owner. - type: - - "null" - - integer - social_profiles: - description: Social profiles associated with the contact. - type: - - "null" - - object - properties: - type: - description: Type of social profile connection. - type: - - "null" - - string - data: - description: Array of social profile data associated with the contact. - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - type: - description: Type of social profile. - type: - - "null" - - string - name: - description: Name of the social profile. - type: - - "null" - - string - url: - description: URL of the social profile. - type: - - "null" - - string - has_hard_bounced: - description: Flag indicating if the contact has hard bounced. - type: - - "null" - - boolean - marked_email_as_spam: - description: Flag indicating if the contact's email was marked as spam. - type: - - "null" - - boolean - unsubscribed_from_emails: - description: Flag indicating if the contact unsubscribed from emails. - type: - - "null" - - boolean - unsubscribed_from_sms: - description: Flag indicating if the contact unsubscribed from SMS. - type: - - "null" - - boolean - created_at: - description: The date and time when the contact was created. - type: - - "null" - - integer - updated_at: - description: The date and time when the contact was last updated. - type: - - "null" - - integer - signed_up_at: - description: The date and time when the contact signed up. - type: - - "null" - - integer - sms_consent: - description: Consent status for SMS communication. - type: - - "null" - - boolean - last_seen_at: - description: The date and time when the contact was last seen overall. - type: - - "null" - - integer - last_replied_at: - description: The date and time when the contact last replied. - type: - - "null" - - integer - last_contacted_at: - description: The date and time when the contact was last contacted. - type: - - "null" - - integer - last_email_opened_at: - description: The date and time when the contact last opened an email. - type: - - "null" - - integer - last_email_clicked_at: - description: The date and time when the contact last clicked an email. - type: - - "null" - - integer - language_override: - description: Language override set for the contact. - type: - - "null" - - string - browser: - description: The browser used by the contact. - type: - - "null" - - string - browser_version: - description: The version of the browser used by the contact. - type: - - "null" - - string - browser_language: - description: The language preference set in the contact's browser. - type: - - "null" - - string - os: - description: Operating system of the contact's device. - type: - - "null" - - string - location: - description: Location details of the contact. - type: - - "null" - - object - properties: - type: - description: Type of location. - type: - - "null" - - string - country: - description: Country of the contact's location. - type: - - "null" - - string - region: - description: Region of the contact's location. - type: - - "null" - - string - city: - description: City of the contact's location. - type: - - "null" - - string - continent_code: - description: Continent code of the contact's location. - type: - - "null" - - string - country_code: - description: Country code of the contact's location. - type: - - "null" - - string - android_app_name: - description: The name of the Android app associated with the contact. - type: - - "null" - - string - android_app_version: - description: The version of the Android app associated with the contact. - type: - - "null" - - string - android_device: - description: The device used by the contact for Android. - type: - - "null" - - string - android_os_version: - description: The operating system version of the Android device. - type: - - "null" - - string - android_sdk_version: - description: The SDK version of the Android device. - type: - - "null" - - string - android_last_seen_at: - description: The date and time when the contact was last seen on Android. - type: - - "null" - - string - format: date-time - ios_app_name: - description: The name of the iOS app associated with the contact. - type: - - "null" - - string - ios_app_version: - description: The version of the iOS app associated with the contact. - type: - - "null" - - string - ios_device: - description: The device used by the contact for iOS. - type: - - "null" - - string - ios_os_version: - description: The operating system version of the iOS device. - type: - - "null" - - string - ios_sdk_version: - description: The SDK version of the iOS device. - type: - - "null" - - string - ios_last_seen_at: - description: The date and time when the contact was last seen on iOS. - type: - - "null" - - integer - custom_attributes: - description: Custom attributes defined for the contact. - type: - - "null" - - object - additionalProperties: true - properties: {} - tags: - description: Tags associated with the contact. - type: - - "null" - - object - properties: - type: - description: Type of connection with the tags. - type: - - "null" - - string - data: - description: Array of tag data associated with the contact. - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - type: - description: Type of tag. - type: - - "null" - - string - id: - description: The unique identifier of the tag. - type: - - "null" - - string - url: - description: URL of the tag. - type: - - "null" - - string - url: - description: URL to access more tag information. - type: - - "null" - - string - total_count: - description: Total count of tags associated with the contact. - type: - - "null" - - integer - has_more: - description: Flag indicating if there are more tags to load. - type: - - "null" - - boolean - notes: - description: Notes associated with the contact. - type: - - "null" - - object - properties: - type: - description: Type of connection with the notes. - type: - - "null" - - string - data: - description: Array of note data associated with the contact. - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - type: - description: Type of note. - type: - - "null" - - string - id: - description: The unique identifier of the note. - type: - - "null" - - string - url: - description: URL of the note. - type: - - "null" - - string - url: - description: URL to access more note information. - type: - - "null" - - string - total_count: - description: Total count of notes associated with the contact. - type: - - "null" - - integer - has_more: - description: Flag indicating if there are more notes to load. - type: - - "null" - - boolean - companies: - description: Companies associated with the contact. - type: - - "null" - - object - properties: - type: - description: Type of connection with the companies. - type: - - "null" - - string - data: - description: Array of company data associated with the contact. - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - type: - description: Type of company. - type: - - "null" - - string - id: - description: The unique identifier of the company. - type: - - "null" - - string - url: - description: URL of the company. - type: - - "null" - - string - url: - description: URL to access more company information. - type: - - "null" - - string - total_count: - description: Total count of companies associated with the contact. - type: - - "null" - - integer - has_more: - description: Flag indicating if there are more companies to load. - type: - - "null" - - boolean - opted_out_subscription_types: - description: Subscription types the contact opted out from. - type: - - "null" - - object - properties: - type: - description: Type of connection with the subscription types. - type: - - "null" - - string - data: - description: - Array of subscription type data opted out from by the - contact. - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - type: - description: Type of subscription. - type: - - "null" - - string - id: - description: The unique identifier of the subscription type. - type: - - "null" - - string - url: - description: URL of the subscription type. - type: - - "null" - - string - url: - description: URL to access more subscription type information. - type: - - "null" - - string - total_count: - description: - Total count of subscription types the contact opted out - from. - type: - - "null" - - integer - has_more: - description: - Flag indicating if there are more subscription types - to load. - type: - - "null" - - boolean - opted_in_subscription_types: - description: Subscription types the contact opted into. - type: - - "null" - - object - properties: - type: - description: Type of connection with the subscription types. - type: - - "null" - - string - data: - description: Array of subscription type data opted into by the contact. - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - type: - description: Type of subscription. - type: - - "null" - - string - id: - description: The unique identifier of the subscription type. - type: - - "null" - - string - url: - description: URL of the subscription type. - type: - - "null" - - string - url: - description: URL to access more subscription type information. - type: - - "null" - - string - total_count: - description: Total count of subscription types the contact opted into. - type: - - "null" - - integer - has_more: - description: - Flag indicating if there are more subscription types - to load. - type: - - "null" - - boolean - utm_content: - description: Content data from UTM parameters. - type: - - "null" - - string - utm_campaign: - description: Campaign data from UTM parameters. - type: - - "null" - - string - utm_source: - description: Source data from UTM parameters. - type: - - "null" - - string - referrer: - description: Referrer information related to the contact. - type: - - "null" - - string - utm_term: - description: Term data from UTM parameters. - type: - - "null" - - string - utm_medium: - description: Medium data from UTM parameters. - type: - - "null" - - string - conversations: - $ref: "#/definitions/stream_incremental_search" - retriever: - $ref: "#/definitions/stream_incremental_search/retriever" - requester: - $ref: "#/definitions/requester_incremental_search" - request_headers: - # API version header - # There are 404 - User Not Found issue, when `2.10` is used, for certain users: - # https://github.com/airbytehq/oncall/issues/4514 - Intercom-Version: "2.9" - Accept: "application/json" - $parameters: - name: "conversations" - path: "conversations/search" - data_field: "conversations" - page_size: 150 - - # activity logs stream is incremental based on created_at field - schema_loader: - type: InlineSchemaLoader - schema: - type: object - properties: - assignee: - description: The assigned user responsible for the conversation. - type: - - "null" - - object - properties: - id: - description: The ID of the assignee - type: - - "null" - - string - type: - description: The type of the assignee (e.g., admin, agent) - type: - - "null" - - string - name: - description: The name of the assignee - type: - - "null" - - string - email: - description: The email of the assignee - type: - - "null" - - string - source: - description: Source details of the conversation. - type: - - "null" - - object - properties: - type: - description: The type of the source - type: - - "null" - - string - id: - description: The ID of the source - type: - - "null" - - string - redacted: - description: Indicates if the source is redacted - type: - - "null" - - boolean - delivered_as: - description: The delivery status of the source - type: - - "null" - - string - subject: - description: The subject of the source - type: - - "null" - - string - body: - description: The body/content of the source - type: - - "null" - - string - author: - description: Author of the source. - type: - - "null" - - object - properties: - id: - description: The ID of the source author - type: - - "null" - - string - type: - description: The type of the source author (e.g., admin, customer) - type: - - "null" - - string - name: - description: The name of the source author - type: - - "null" - - string - email: - description: The email of the source author - type: - - "null" - - string - attachments: - description: Attachments related to the conversation. - type: - - "null" - - array - items: - type: - - "null" - - object - additionalProperties: true - properties: {} - url: - description: The URL of the source - type: - - "null" - - string - contacts: - description: List of contacts involved in the conversation. - type: - - "null" - - object - items: - type: - - "null" - - object - properties: - type: - description: The type of the contact - type: - - "null" - - string - id: - description: The ID of the contact - type: - - "null" - - string - teammates: - description: List of teammates involved in the conversation. - type: - - "null" - - object - properties: - admins: - description: Admin teammates involved in the conversation. - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - id: - description: The ID of the teammate admin - type: - - "null" - - string - type: - description: The type of the teammate (admin) - type: - - "null" - - string - type: - description: The type of teammates - type: - - "null" - - string - first_contact_reply: - description: Timestamp indicating when the first contact replied. - type: - - "null" - - object - properties: - type: - description: The type of the first contact reply - type: - - "null" - - string - url: - description: The URL of the first contact reply - type: - - "null" - - string - created_at: - description: The timestamp of the first contact's reply - type: - - "null" - - integer - custom_attributes: - description: Custom attributes associated with the conversation - type: - - "null" - - object - priority: - description: The priority level of the conversation - type: - - "null" - - string - conversation_message: - description: The main message content of the conversation. - type: - - "null" - - object - properties: - attachments: - description: Attachments in the conversation message - anyOf: - - type: array - items: - type: object - properties: - type: - type: - - "null" - - string - name: - type: - - "null" - - string - url: - type: - - "null" - - string - content_type: - type: - - "null" - - string - filesize: - type: - - "null" - - integer - height: - type: - - "null" - - integer - width: - type: - - "null" - - integer - - type: "null" - author: - description: The author of the conversation message. - type: - - "null" - - object - properties: - id: - description: The ID of the author of the message - type: - - "null" - - string - type: - description: The type of the author (e.g., admin, customer) - type: - - "null" - - string - name: - description: The name of the author of the message - type: - - "null" - - string - email: - description: The email of the author of the message - type: - - "null" - - string - body: - description: The body/content of the conversation message - type: - - "null" - - string - delivered_as: - description: The delivery status of the message - type: - - "null" - - string - id: - description: The ID of the conversation message - type: - - "null" - - string - subject: - description: The subject of the conversation message - type: - - "null" - - string - type: - description: The type of the conversation message - type: - - "null" - - string - url: - description: The URL of the conversation message - type: - - "null" - - string - conversation_rating: - description: Ratings given to the conversation by the customer and teammate. - type: - - "null" - - object - properties: - created_at: - description: The timestamp when the rating was created - type: - - "null" - - integer - customer: - description: Rating given by the customer. - type: - - "null" - - object - properties: - id: - description: The ID of the customer who provided the rating - type: - - "null" - - string - type: - description: The type of the customer providing the rating - type: - - "null" - - string - rating: - description: The rating given to the conversation - type: - - "null" - - integer - remark: - description: Any remarks provided with the rating - type: - - "null" - - string - teammate: - description: Rating given by the teammate. - type: - - "null" - - object - properties: - id: - description: The ID of the teammate being rated - type: - - "null" - - integer - type: - description: The type of the teammate being rated - type: - - "null" - - string - created_at: - description: The timestamp when the conversation was created - type: - - "null" - - integer - customer_first_reply: - description: Timestamp indicating when the customer first replied. - type: - - "null" - - object - properties: - created_at: - description: The timestamp of the customer's first reply - type: - - "null" - - integer - type: - description: The type of the first customer reply - type: - - "null" - - string - url: - description: The URL of the first customer reply - type: - - "null" - - string - customers: - description: List of customers involved in the conversation - anyOf: - - type: array - items: - type: - - "null" - - object - properties: - id: - type: - - "null" - - string - type: - type: - - "null" - - string - - type: "null" - id: - description: The unique ID of the conversation - type: - - "null" - - string - open: - description: Indicates if the conversation is open or closed - type: - - "null" - - boolean - read: - description: Indicates if the conversation has been read - type: - - "null" - - boolean - sent_at: - description: The timestamp when the conversation was sent - type: - - "null" - - integer - snoozed_until: - description: Timestamp until the conversation is snoozed - type: - - "null" - - integer - sla_applied: - description: Service Level Agreement details applied to the conversation. - type: - - "null" - - object - properties: - sla_name: - description: The name of the SLA applied - type: - - "null" - - string - sla_status: - description: The status of the SLA applied - type: - - "null" - - string - state: - description: The state of the conversation (e.g., new, in progress) - type: - - "null" - - string - statistics: - description: Statistics related to the conversation. - type: - - "null" - - object - properties: - type: - description: The type of conversation statistics - type: - - "null" - - string - time_to_assignment: - description: Time taken for assignment - type: - - "null" - - integer - time_to_admin_reply: - description: Time taken to reply by admin - type: - - "null" - - integer - time_to_first_close: - description: Time taken to first close the conversation - type: - - "null" - - integer - time_to_last_close: - description: Time taken to last close the conversation - type: - - "null" - - integer - median_time_to_reply: - description: The median time taken to reply to the conversation - type: - - "null" - - integer - first_contact_reply_at: - description: Timestamp of the first contact reply - type: - - "null" - - integer - first_assignment_at: - description: Timestamp of the first assignment - type: - - "null" - - integer - first_admin_reply_at: - description: Timestamp of the first admin reply - type: - - "null" - - integer - first_close_at: - description: Timestamp of the first conversation close - type: - - "null" - - integer - last_assignment_at: - description: Timestamp of the last assignment - type: - - "null" - - integer - last_assignment_admin_reply_at: - description: Timestamp of the last assignment admin reply - type: - - "null" - - integer - last_contact_reply_at: - description: Timestamp of the last contact reply - type: - - "null" - - integer - last_admin_reply_at: - description: Timestamp of the last admin reply - type: - - "null" - - integer - last_close_at: - description: Timestamp of the last conversation close - type: - - "null" - - integer - last_closed_by_id: - description: The ID of the last user who closed the conversation - type: - - "null" - - integer - count_reopens: - description: The total count of conversation reopens - type: - - "null" - - integer - count_assignments: - description: The total count of assignments for the conversation - type: - - "null" - - integer - count_conversation_parts: - description: The total count of conversation parts - type: - - "null" - - integer - tags: - description: Tags applied to the conversation. - type: - - "null" - - object - items: - type: - - "null" - - object - properties: - applied_at: - description: Timestamp when the tag was applied - type: - - "null" - - integer - applied_by: - description: User who applied the tag. - type: - - "null" - - object - properties: - id: - description: The ID of the user who applied the tag - type: - - "null" - - string - type: - description: The type of the user who applied the tag - type: - - "null" - - string - id: - description: The ID of the tag - type: - - "null" - - string - name: - description: The name of the tag - type: - - "null" - - string - type: - description: The type of the tag - type: - - "null" - - string - type: - description: The type of the conversation - type: - - "null" - - string - updated_at: - description: The timestamp when the conversation was last updated - type: - - "null" - - integer - user: - description: The user related to the conversation. - type: - - "null" - - object - properties: - id: - description: The ID of the user associated with the conversation - type: - - "null" - - string - type: - description: The type of the user - type: - - "null" - - string - waiting_since: - description: Timestamp since waiting for a response - type: - - "null" - - integer - admin_assignee_id: - description: The ID of the administrator assigned to the conversation - type: - - "null" - - integer - title: - description: The title of the conversation - type: - - "null" - - string - team_assignee_id: - description: The ID of the team assigned to the conversation - type: - - "null" - - integer - redacted: - description: Indicates if the conversation is redacted - type: - - "null" - - boolean - topics: - description: Topics associated with the conversation. - type: - - "null" - - object - properties: - type: - description: The type of topics - type: - - "null" - - string - topics: - description: List of topics related to the conversation. - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - type: - description: The type of the topic - type: - - "null" - - string - id: - description: The ID of the topic - type: - - "null" - - integer - name: - description: The name of the topic - type: - - "null" - - string - total_count: - description: The total count of topics - type: - - "null" - - integer - activity_logs: - $ref: "#/definitions/stream_full_refresh" - primary_key: id - $parameters: - name: "activity_logs" - path: "admins/activity_logs" - data_field: "activity_logs" - retriever: - $ref: "#/definitions/retriever" - description: "The Retriever without passing page size option" - paginator: - type: "DefaultPaginator" - url_base: "#/definitions/requester/url_base" - pagination_strategy: - type: "CursorPagination" - cursor_value: "{{ response.get('pages', {}).get('next') }}" - stop_condition: "{{ 'next' not in response.get('pages', {}) }}" - page_token_option: - type: RequestPath - incremental_sync: - type: DatetimeBasedCursor - cursor_field: created_at - cursor_datetime_formats: - - "%s" - datetime_format: "%s" - lookback_window: "P{{ config.get('lookback_window', 0) }}D" - cursor_granularity: "PT1S" - step: "P{{ config.get('activity_logs_time_step', 30) }}D" - start_datetime: - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - end_time_option: - field_name: "created_at_before" - inject_into: "request_parameter" - start_time_option: - field_name: "created_at_after" - inject_into: "request_parameter" - - schema_loader: - type: InlineSchemaLoader - schema: - type: object - properties: - performed_by: - description: The user who performed the activity - type: - - "null" - - object - properties: - id: - description: Unique identifier of the user who performed the activity - type: - - "null" - - string - type: - description: - Type of the user who performed the activity (e.g., admin, - user) - type: - - "null" - - string - ip: - description: IP address from where the activity was performed - type: - - "null" - - string - email: - description: Email of the user who performed the activity - type: - - "null" - - string - id: - description: Unique identifier for the activity log entry - type: - - "null" - - string - metadata: - description: Additional data or information related to the activity - type: - - "null" - - object - activity_type: - description: The type or category of the activity - type: - - "null" - - string - activity_description: - description: A description of the activity that took place - type: - - "null" - - string - created_at: - description: The timestamp when the activity occurred - type: - - "null" - - integer -streams: - - "#/definitions/activity_logs" - - "#/definitions/admins" - - "#/definitions/tags" - - "#/definitions/teams" - - "#/definitions/segments" - - "#/definitions/companies" - - "#/definitions/company_attributes" - - "#/definitions/contact_attributes" - - "#/definitions/contacts" - - "#/definitions/conversations" - - "#/definitions/conversation_parts" - - "#/definitions/company_segments" - -check: - stream_names: - - "tags" diff --git a/airbyte-integrations/connectors/source-intercom/source_intercom/run.py b/airbyte-integrations/connectors/source-intercom/source_intercom/run.py deleted file mode 100644 index 434766998b6e..000000000000 --- a/airbyte-integrations/connectors/source-intercom/source_intercom/run.py +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import sys - -from airbyte_cdk.entrypoint import launch -from source_intercom import SourceIntercom - - -def run(): - source = SourceIntercom() - launch(source, sys.argv[1:]) diff --git a/airbyte-integrations/connectors/source-intercom/source_intercom/source.py b/airbyte-integrations/connectors/source-intercom/source_intercom/source.py deleted file mode 100644 index bd527bbced67..000000000000 --- a/airbyte-integrations/connectors/source-intercom/source_intercom/source.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource - -""" -This file provides the necessary constructs to interpret a provided declarative YAML configuration file into -source connector. - -WARNING: Do not modify this file. -""" - - -# Declarative Source -class SourceIntercom(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-intercom/source_intercom/spec.json b/airbyte-integrations/connectors/source-intercom/source_intercom/spec.json deleted file mode 100644 index b544fd8b43bd..000000000000 --- a/airbyte-integrations/connectors/source-intercom/source_intercom/spec.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "documentationUrl": "https://docs.airbyte.com/integrations/sources/intercom", - "connectionSpecification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Source Intercom Spec", - "type": "object", - "required": ["start_date", "access_token"], - "additionalProperties": true, - "properties": { - "start_date": { - "type": "string", - "title": "Start date", - "description": "UTC date and time in the format 2017-01-25T00:00:00Z. Any data before this date will not be replicated.", - "examples": ["2020-11-16T00:00:00Z"], - "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$", - "format": "date-time" - }, - "access_token": { - "title": "Access token", - "type": "string", - "description": "Access token for making authenticated requests. See the Intercom docs for more information.", - "airbyte_secret": true, - "order": 0 - }, - "client_id": { - "title": "Client Id", - "type": "string", - "description": "Client Id for your Intercom application.", - "airbyte_secret": true, - "order": 1 - }, - "client_secret": { - "title": "Client Secret", - "type": "string", - "description": "Client Secret for your Intercom application.", - "airbyte_secret": true, - "order": 2 - }, - "activity_logs_time_step": { - "type": "integer", - "default": 30, - "minimum": 1, - "maximum": 91, - "title": "Activity logs stream slice step size (in days)", - "description": "Set lower value in case of failing long running sync of Activity Logs stream.", - "examples": [30, 10, 5], - "order": 3 - }, - "lookback_window": { - "title": "Lookback window", - "description": "The number of days to shift the state value backward for record sync", - "examples": [60], - "default": 0, - "minimum": 0, - "type": "integer", - "order": 4 - } - } - }, - "advanced_auth": { - "auth_flow_type": "oauth2.0", - "oauth_config_specification": { - "complete_oauth_output_specification": { - "type": "object", - "properties": { - "access_token": { - "type": "string", - "path_in_connector_config": ["access_token"] - } - } - }, - "complete_oauth_server_input_specification": { - "type": "object", - "properties": { - "client_id": { - "type": "string" - }, - "client_secret": { - "type": "string" - } - } - }, - "complete_oauth_server_output_specification": { - "type": "object", - "properties": { - "client_id": { - "type": "string", - "path_in_connector_config": ["client_id"] - }, - "client_secret": { - "type": "string", - "path_in_connector_config": ["client_secret"] - } - } - } - } - } -} diff --git a/airbyte-integrations/connectors/source-intercom/unit_tests/conftest.py b/airbyte-integrations/connectors/source-intercom/unit_tests/conftest.py new file mode 100644 index 000000000000..d3826f66680c --- /dev/null +++ b/airbyte-integrations/connectors/source-intercom/unit_tests/conftest.py @@ -0,0 +1,3 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + +pytest_plugins = ["airbyte_cdk.test.utils.manifest_only_fixtures"] diff --git a/airbyte-integrations/connectors/source-intercom/unit_tests/poetry.lock b/airbyte-integrations/connectors/source-intercom/unit_tests/poetry.lock new file mode 100644 index 000000000000..847fa693b143 --- /dev/null +++ b/airbyte-integrations/connectors/source-intercom/unit_tests/poetry.lock @@ -0,0 +1,1992 @@ +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. + +[[package]] +name = "airbyte-cdk" +version = "6.10.0" +description = "A framework for writing Airbyte Connectors." +optional = false +python-versions = "<3.13,>=3.10" +files = [ + {file = "airbyte_cdk-6.10.0-py3-none-any.whl", hash = "sha256:0f953711332dae67f294751044bc4abfcd988c40a176a32e2d02d2a679377acf"}, + {file = "airbyte_cdk-6.10.0.tar.gz", hash = "sha256:90aeb0a87e89e9fc43f27ebccabb64ac96966ce2f398805c93a52cd4580a4641"}, +] + +[package.dependencies] +airbyte-protocol-models-dataclasses = ">=0.14,<0.15" +backoff = "*" +cachetools = "*" +cryptography = ">=42.0.5,<44.0.0" +dpath = ">=2.1.6,<3.0.0" +dunamai = ">=1.22.0,<2.0.0" +genson = "1.3.0" +isodate = ">=0.6.1,<0.7.0" +Jinja2 = ">=3.1.2,<3.2.0" +jsonref = ">=0.2,<0.3" +jsonschema = ">=4.17.3,<4.18.0" +langchain_core = "0.1.42" +nltk = "3.9.1" +numpy = "<2" +orjson = ">=3.10.7,<4.0.0" +pandas = "2.2.2" +pendulum = "<3.0.0" +psutil = "6.1.0" +pydantic = ">=2.7,<3.0" +pyjwt = ">=2.8.0,<3.0.0" +pyrate-limiter = ">=3.1.0,<3.2.0" +python-dateutil = "*" +python-ulid = ">=3.0.0,<4.0.0" +pytz = "2024.1" +PyYAML = ">=6.0.1,<7.0.0" +rapidfuzz = ">=3.10.1,<4.0.0" +requests = "*" +requests_cache = "*" +serpyco-rs = ">=1.10.2,<2.0.0" +wcmatch = "10.0" +xmltodict = ">=0.13.0,<0.14.0" + +[package.extras] +file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "python-snappy (==0.7.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] +sql = ["sqlalchemy (>=2.0,!=2.0.36,<3.0)"] +vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.8.0)"] + +[[package]] +name = "airbyte-protocol-models-dataclasses" +version = "0.14.1" +description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" +optional = false +python-versions = ">=3.8" +files = [ + {file = "airbyte_protocol_models_dataclasses-0.14.1-py3-none-any.whl", hash = "sha256:dfe10b32ee09e6ba9b4f17bd309e841b61cbd61ec8f80b1937ff104efd6209a9"}, + {file = "airbyte_protocol_models_dataclasses-0.14.1.tar.gz", hash = "sha256:f62a46556b82ea0d55de144983141639e8049d836dd4e0a9d7234c5b2e103c08"}, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + +[[package]] +name = "anyio" +version = "4.7.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.9" +files = [ + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, +] + +[package.dependencies] +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} +idna = ">=2.8" +sniffio = ">=1.1" +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} + +[package.extras] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] +trio = ["trio (>=0.26.1)"] + +[[package]] +name = "attributes-doc" +version = "0.4.0" +description = "PEP 224 implementation" +optional = false +python-versions = ">=3.8" +files = [ + {file = "attributes-doc-0.4.0.tar.gz", hash = "sha256:b1576c94a714e9fc2c65c47cf10d0c8e1a5f7c4f5ae7f69006be108d95cbfbfb"}, + {file = "attributes_doc-0.4.0-py2.py3-none-any.whl", hash = "sha256:4c3007d9e58f3a6cb4b9c614c4d4ce2d92161581f28e594ddd8241cc3a113bdd"}, +] + +[[package]] +name = "attrs" +version = "24.3.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.8" +files = [ + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, +] + +[package.extras] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] + +[[package]] +name = "backoff" +version = "2.2.1" +description = "Function decoration for backoff and retry" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, + {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, +] + +[[package]] +name = "bracex" +version = "2.5.post1" +description = "Bash style brace expander." +optional = false +python-versions = ">=3.8" +files = [ + {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, + {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, +] + +[[package]] +name = "cachetools" +version = "5.5.0" +description = "Extensible memoizing collections and decorators" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, + {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, +] + +[[package]] +name = "cattrs" +version = "24.1.2" +description = "Composable complex class support for attrs and dataclasses." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, + {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, +] + +[package.dependencies] +attrs = ">=23.1.0" +exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} + +[package.extras] +bson = ["pymongo (>=4.4.0)"] +cbor2 = ["cbor2 (>=5.4.6)"] +msgpack = ["msgpack (>=1.0.5)"] +msgspec = ["msgspec (>=0.18.5)"] +orjson = ["orjson (>=3.9.2)"] +pyyaml = ["pyyaml (>=6.0)"] +tomlkit = ["tomlkit (>=0.11.8)"] +ujson = ["ujson (>=5.7.0)"] + +[[package]] +name = "certifi" +version = "2024.12.14" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, +] + +[[package]] +name = "cffi" +version = "1.17.1" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, + {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, + {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, + {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, + {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, +] + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "charset-normalizer" +version = "3.4.0" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, + {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, + {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +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 = "cryptography" +version = "43.0.3" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = ">=3.7" +files = [ + {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, + {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, + {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, + {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, + {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, + {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, + {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, +] + +[package.dependencies] +cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] +nox = ["nox"] +pep8test = ["check-sdist", "click", "mypy", "ruff"] +sdist = ["build"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] + +[[package]] +name = "dpath" +version = "2.2.0" +description = "Filesystem-like pathing and searching for dictionaries" +optional = false +python-versions = ">=3.7" +files = [ + {file = "dpath-2.2.0-py3-none-any.whl", hash = "sha256:b330a375ded0a0d2ed404440f6c6a715deae5313af40bbb01c8a41d891900576"}, + {file = "dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e"}, +] + +[[package]] +name = "dunamai" +version = "1.23.0" +description = "Dynamic version generation" +optional = false +python-versions = ">=3.5" +files = [ + {file = "dunamai-1.23.0-py3-none-any.whl", hash = "sha256:a0906d876e92441793c6a423e16a4802752e723e9c9a5aabdc5535df02dbe041"}, + {file = "dunamai-1.23.0.tar.gz", hash = "sha256:a163746de7ea5acb6dacdab3a6ad621ebc612ed1e528aaa8beedb8887fccd2c4"}, +] + +[package.dependencies] +packaging = ">=20.9" + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "genson" +version = "1.3.0" +description = "GenSON is a powerful, user-friendly JSON Schema generator." +optional = false +python-versions = "*" +files = [ + {file = "genson-1.3.0-py3-none-any.whl", hash = "sha256:468feccd00274cc7e4c09e84b08704270ba8d95232aa280f65b986139cec67f7"}, + {file = "genson-1.3.0.tar.gz", hash = "sha256:e02db9ac2e3fd29e65b5286f7135762e2cd8a986537c075b06fc5f1517308e37"}, +] + +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.7" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<1.0)"] + +[[package]] +name = "httpx" +version = "0.28.1" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "idna" +version = "3.10" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.6" +files = [ + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "isodate" +version = "0.6.1" +description = "An ISO 8601 date/time/duration parser and formatter" +optional = false +python-versions = "*" +files = [ + {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, + {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "jinja2" +version = "3.1.4" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "joblib" +version = "1.4.2" +description = "Lightweight pipelining with Python functions" +optional = false +python-versions = ">=3.8" +files = [ + {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, + {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, +] + +[[package]] +name = "jsonpatch" +version = "1.33" +description = "Apply JSON-Patches (RFC 6902)" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +files = [ + {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, + {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, +] + +[package.dependencies] +jsonpointer = ">=1.9" + +[[package]] +name = "jsonpointer" +version = "3.0.0" +description = "Identify specific nodes in a JSON document (RFC 6901)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, + {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, +] + +[[package]] +name = "jsonref" +version = "0.2" +description = "An implementation of JSON Reference for Python" +optional = false +python-versions = "*" +files = [ + {file = "jsonref-0.2-py3-none-any.whl", hash = "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f"}, + {file = "jsonref-0.2.tar.gz", hash = "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697"}, +] + +[[package]] +name = "jsonschema" +version = "4.17.3" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, +] + +[package.dependencies] +attrs = ">=17.4.0" +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] + +[[package]] +name = "langchain-core" +version = "0.1.42" +description = "Building applications with LLMs through composability" +optional = false +python-versions = "<4.0,>=3.8.1" +files = [ + {file = "langchain_core-0.1.42-py3-none-any.whl", hash = "sha256:c5653ffa08a44f740295c157a24c0def4a753333f6a2c41f76bf431cd00be8b5"}, + {file = "langchain_core-0.1.42.tar.gz", hash = "sha256:40751bf60ea5d8e2b2efe65290db434717ee3834870c002e40e2811f09d814e6"}, +] + +[package.dependencies] +jsonpatch = ">=1.33,<2.0" +langsmith = ">=0.1.0,<0.2.0" +packaging = ">=23.2,<24.0" +pydantic = ">=1,<3" +PyYAML = ">=5.3" +tenacity = ">=8.1.0,<9.0.0" + +[package.extras] +extended-testing = ["jinja2 (>=3,<4)"] + +[[package]] +name = "langsmith" +version = "0.1.147" +description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." +optional = false +python-versions = "<4.0,>=3.8.1" +files = [ + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, +] + +[package.dependencies] +httpx = ">=0.23.0,<1" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} +pydantic = [ + {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""}, + {version = ">=2.7.4,<3.0.0", markers = "python_full_version >= \"3.12.4\""}, +] +requests = ">=2,<3" +requests-toolbelt = ">=1.0.0,<2.0.0" + +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + +[[package]] +name = "markupsafe" +version = "3.0.2" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.9" +files = [ + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, +] + +[[package]] +name = "nltk" +version = "3.9.1" +description = "Natural Language Toolkit" +optional = false +python-versions = ">=3.8" +files = [ + {file = "nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1"}, + {file = "nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868"}, +] + +[package.dependencies] +click = "*" +joblib = "*" +regex = ">=2021.8.3" +tqdm = "*" + +[package.extras] +all = ["matplotlib", "numpy", "pyparsing", "python-crfsuite", "requests", "scikit-learn", "scipy", "twython"] +corenlp = ["requests"] +machine-learning = ["numpy", "python-crfsuite", "scikit-learn", "scipy"] +plot = ["matplotlib"] +tgrep = ["pyparsing"] +twitter = ["twython"] + +[[package]] +name = "numpy" +version = "1.26.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, +] + +[[package]] +name = "orjson" +version = "3.10.12" +description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" +optional = false +python-versions = ">=3.8" +files = [ + {file = "orjson-3.10.12-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ece01a7ec71d9940cc654c482907a6b65df27251255097629d0dea781f255c6d"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c34ec9aebc04f11f4b978dd6caf697a2df2dd9b47d35aa4cc606cabcb9df69d7"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd6ec8658da3480939c79b9e9e27e0db31dffcd4ba69c334e98c9976ac29140e"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f17e6baf4cf01534c9de8a16c0c611f3d94925d1701bf5f4aff17003677d8ced"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6402ebb74a14ef96f94a868569f5dccf70d791de49feb73180eb3c6fda2ade56"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0000758ae7c7853e0a4a6063f534c61656ebff644391e1f81698c1b2d2fc8cd2"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:888442dcee99fd1e5bd37a4abb94930915ca6af4db50e23e746cdf4d1e63db13"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c1f7a3ce79246aa0e92f5458d86c54f257fb5dfdc14a192651ba7ec2c00f8a05"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:802a3935f45605c66fb4a586488a38af63cb37aaad1c1d94c982c40dcc452e85"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1da1ef0113a2be19bb6c557fb0ec2d79c92ebd2fed4cfb1b26bab93f021fb885"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a3273e99f367f137d5b3fecb5e9f45bcdbfac2a8b2f32fbc72129bbd48789c2"}, + {file = "orjson-3.10.12-cp310-none-win32.whl", hash = "sha256:475661bf249fd7907d9b0a2a2421b4e684355a77ceef85b8352439a9163418c3"}, + {file = "orjson-3.10.12-cp310-none-win_amd64.whl", hash = "sha256:87251dc1fb2b9e5ab91ce65d8f4caf21910d99ba8fb24b49fd0c118b2362d509"}, + {file = "orjson-3.10.12-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a734c62efa42e7df94926d70fe7d37621c783dea9f707a98cdea796964d4cf74"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:750f8b27259d3409eda8350c2919a58b0cfcd2054ddc1bd317a643afc646ef23"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb52c22bfffe2857e7aa13b4622afd0dd9d16ea7cc65fd2bf318d3223b1b6252"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:440d9a337ac8c199ff8251e100c62e9488924c92852362cd27af0e67308c16ef"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9e15c06491c69997dfa067369baab3bf094ecb74be9912bdc4339972323f252"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:362d204ad4b0b8724cf370d0cd917bb2dc913c394030da748a3bb632445ce7c4"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2b57cbb4031153db37b41622eac67329c7810e5f480fda4cfd30542186f006ae"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:165c89b53ef03ce0d7c59ca5c82fa65fe13ddf52eeb22e859e58c237d4e33b9b"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5dee91b8dfd54557c1a1596eb90bcd47dbcd26b0baaed919e6861f076583e9da"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77a4e1cfb72de6f905bdff061172adfb3caf7a4578ebf481d8f0530879476c07"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:038d42c7bc0606443459b8fe2d1f121db474c49067d8d14c6a075bbea8bf14dd"}, + {file = "orjson-3.10.12-cp311-none-win32.whl", hash = "sha256:03b553c02ab39bed249bedd4abe37b2118324d1674e639b33fab3d1dafdf4d79"}, + {file = "orjson-3.10.12-cp311-none-win_amd64.whl", hash = "sha256:8b8713b9e46a45b2af6b96f559bfb13b1e02006f4242c156cbadef27800a55a8"}, + {file = "orjson-3.10.12-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:53206d72eb656ca5ac7d3a7141e83c5bbd3ac30d5eccfe019409177a57634b0d"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac8010afc2150d417ebda810e8df08dd3f544e0dd2acab5370cfa6bcc0662f8f"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed459b46012ae950dd2e17150e838ab08215421487371fa79d0eced8d1461d70"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dcb9673f108a93c1b52bfc51b0af422c2d08d4fc710ce9c839faad25020bb69"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22a51ae77680c5c4652ebc63a83d5255ac7d65582891d9424b566fb3b5375ee9"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910fdf2ac0637b9a77d1aad65f803bac414f0b06f720073438a7bd8906298192"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:24ce85f7100160936bc2116c09d1a8492639418633119a2224114f67f63a4559"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a76ba5fc8dd9c913640292df27bff80a685bed3a3c990d59aa6ce24c352f8fc"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ff70ef093895fd53f4055ca75f93f047e088d1430888ca1229393a7c0521100f"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f4244b7018b5753ecd10a6d324ec1f347da130c953a9c88432c7fbc8875d13be"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:16135ccca03445f37921fa4b585cff9a58aa8d81ebcb27622e69bfadd220b32c"}, + {file = "orjson-3.10.12-cp312-none-win32.whl", hash = "sha256:2d879c81172d583e34153d524fcba5d4adafbab8349a7b9f16ae511c2cee8708"}, + {file = "orjson-3.10.12-cp312-none-win_amd64.whl", hash = "sha256:fc23f691fa0f5c140576b8c365bc942d577d861a9ee1142e4db468e4e17094fb"}, + {file = "orjson-3.10.12-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:47962841b2a8aa9a258b377f5188db31ba49af47d4003a32f55d6f8b19006543"}, + {file = "orjson-3.10.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6334730e2532e77b6054e87ca84f3072bee308a45a452ea0bffbbbc40a67e296"}, + {file = "orjson-3.10.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:accfe93f42713c899fdac2747e8d0d5c659592df2792888c6c5f829472e4f85e"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a7974c490c014c48810d1dede6c754c3cc46598da758c25ca3b4001ac45b703f"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3f250ce7727b0b2682f834a3facff88e310f52f07a5dcfd852d99637d386e79e"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f31422ff9486ae484f10ffc51b5ab2a60359e92d0716fcce1b3593d7bb8a9af6"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5f29c5d282bb2d577c2a6bbde88d8fdcc4919c593f806aac50133f01b733846e"}, + {file = "orjson-3.10.12-cp313-none-win32.whl", hash = "sha256:f45653775f38f63dc0e6cd4f14323984c3149c05d6007b58cb154dd080ddc0dc"}, + {file = "orjson-3.10.12-cp313-none-win_amd64.whl", hash = "sha256:229994d0c376d5bdc91d92b3c9e6be2f1fbabd4cc1b59daae1443a46ee5e9825"}, + {file = "orjson-3.10.12-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7d69af5b54617a5fac5c8e5ed0859eb798e2ce8913262eb522590239db6c6763"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ed119ea7d2953365724a7059231a44830eb6bbb0cfead33fcbc562f5fd8f935"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9c5fc1238ef197e7cad5c91415f524aaa51e004be5a9b35a1b8a84ade196f73f"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43509843990439b05f848539d6f6198d4ac86ff01dd024b2f9a795c0daeeab60"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f72e27a62041cfb37a3de512247ece9f240a561e6c8662276beaf4d53d406db4"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a904f9572092bb6742ab7c16c623f0cdccbad9eeb2d14d4aa06284867bddd31"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:855c0833999ed5dc62f64552db26f9be767434917d8348d77bacaab84f787d7b"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:897830244e2320f6184699f598df7fb9db9f5087d6f3f03666ae89d607e4f8ed"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0b32652eaa4a7539f6f04abc6243619c56f8530c53bf9b023e1269df5f7816dd"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:36b4aa31e0f6a1aeeb6f8377769ca5d125db000f05c20e54163aef1d3fe8e833"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5535163054d6cbf2796f93e4f0dbc800f61914c0e3c4ed8499cf6ece22b4a3da"}, + {file = "orjson-3.10.12-cp38-none-win32.whl", hash = "sha256:90a5551f6f5a5fa07010bf3d0b4ca2de21adafbbc0af6cb700b63cd767266cb9"}, + {file = "orjson-3.10.12-cp38-none-win_amd64.whl", hash = "sha256:703a2fb35a06cdd45adf5d733cf613cbc0cb3ae57643472b16bc22d325b5fb6c"}, + {file = "orjson-3.10.12-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f29de3ef71a42a5822765def1febfb36e0859d33abf5c2ad240acad5c6a1b78d"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de365a42acc65d74953f05e4772c974dad6c51cfc13c3240899f534d611be967"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:91a5a0158648a67ff0004cb0df5df7dcc55bfc9ca154d9c01597a23ad54c8d0c"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c47ce6b8d90fe9646a25b6fb52284a14ff215c9595914af63a5933a49972ce36"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0eee4c2c5bfb5c1b47a5db80d2ac7aaa7e938956ae88089f098aff2c0f35d5d8"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35d3081bbe8b86587eb5c98a73b97f13d8f9fea685cf91a579beddacc0d10566"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73c23a6e90383884068bc2dba83d5222c9fcc3b99a0ed2411d38150734236755"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5472be7dc3269b4b52acba1433dac239215366f89dc1d8d0e64029abac4e714e"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:7319cda750fca96ae5973efb31b17d97a5c5225ae0bc79bf5bf84df9e1ec2ab6"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:74d5ca5a255bf20b8def6a2b96b1e18ad37b4a122d59b154c458ee9494377f80"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ff31d22ecc5fb85ef62c7d4afe8301d10c558d00dd24274d4bbe464380d3cd69"}, + {file = "orjson-3.10.12-cp39-none-win32.whl", hash = "sha256:c22c3ea6fba91d84fcb4cda30e64aff548fcf0c44c876e681f47d61d24b12e6b"}, + {file = "orjson-3.10.12-cp39-none-win_amd64.whl", hash = "sha256:be604f60d45ace6b0b33dd990a66b4526f1a7a186ac411c942674625456ca548"}, + {file = "orjson-3.10.12.tar.gz", hash = "sha256:0a78bbda3aea0f9f079057ee1ee8a1ecf790d4f1af88dd67493c6b8ee52506ff"}, +] + +[[package]] +name = "packaging" +version = "23.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] + +[[package]] +name = "pandas" +version = "2.2.2" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + +[[package]] +name = "pendulum" +version = "2.1.2" +description = "Python datetimes made easy" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, + {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, + {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, + {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, + {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, + {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, + {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, + {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, + {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, + {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, + {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, + {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, + {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, + {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, + {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, + {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, + {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, + {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, + {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, + {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, + {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, +] + +[package.dependencies] +python-dateutil = ">=2.6,<3.0" +pytzdata = ">=2020.1" + +[[package]] +name = "platformdirs" +version = "4.3.6" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, +] + +[package.extras] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] + +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "psutil" +version = "6.1.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, +] + +[package.extras] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + +[[package]] +name = "pycparser" +version = "2.22" +description = "C parser in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + +[[package]] +name = "pydantic" +version = "2.10.3" +description = "Data validation using Python type hints" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic-2.10.3-py3-none-any.whl", hash = "sha256:be04d85bbc7b65651c5f8e6b9976ed9c6f41782a55524cef079a34a0bb82144d"}, + {file = "pydantic-2.10.3.tar.gz", hash = "sha256:cb5ac360ce894ceacd69c403187900a02c4b20b693a9dd1d643e1effab9eadf9"}, +] + +[package.dependencies] +annotated-types = ">=0.6.0" +pydantic-core = "2.27.1" +typing-extensions = ">=4.12.2" + +[package.extras] +email = ["email-validator (>=2.0.0)"] +timezone = ["tzdata"] + +[[package]] +name = "pydantic-core" +version = "2.27.1" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206"}, + {file = "pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c"}, + {file = "pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc"}, + {file = "pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9"}, + {file = "pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5"}, + {file = "pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae"}, + {file = "pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c"}, + {file = "pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16"}, + {file = "pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23"}, + {file = "pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05"}, + {file = "pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337"}, + {file = "pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:5897bec80a09b4084aee23f9b73a9477a46c3304ad1d2d07acca19723fb1de62"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d0165ab2914379bd56908c02294ed8405c252250668ebcb438a55494c69f44ab"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b9af86e1d8e4cfc82c2022bfaa6f459381a50b94a29e95dcdda8442d6d83864"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f6c8a66741c5f5447e047ab0ba7a1c61d1e95580d64bce852e3df1f895c4067"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a42d6a8156ff78981f8aa56eb6394114e0dedb217cf8b729f438f643608cbcd"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64c65f40b4cd8b0e049a8edde07e38b476da7e3aaebe63287c899d2cff253fa5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdcf339322a3fae5cbd504edcefddd5a50d9ee00d968696846f089b4432cf78"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf99c8404f008750c846cb4ac4667b798a9f7de673ff719d705d9b2d6de49c5f"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f1edcea27918d748c7e5e4d917297b2a0ab80cad10f86631e488b7cddf76a36"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:159cac0a3d096f79ab6a44d77a961917219707e2a130739c64d4dd46281f5c2a"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:029d9757eb621cc6e1848fa0b0310310de7301057f623985698ed7ebb014391b"}, + {file = "pydantic_core-2.27.1-cp38-none-win32.whl", hash = "sha256:a28af0695a45f7060e6f9b7092558a928a28553366519f64083c63a44f70e618"}, + {file = "pydantic_core-2.27.1-cp38-none-win_amd64.whl", hash = "sha256:2d4567c850905d5eaaed2f7a404e61012a51caf288292e016360aa2b96ff38d4"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:e9386266798d64eeb19dd3677051f5705bf873e98e15897ddb7d76f477131967"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4228b5b646caa73f119b1ae756216b59cc6e2267201c27d3912b592c5e323b60"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3dfe500de26c52abe0477dde16192ac39c98f05bf2d80e76102d394bd13854"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aee66be87825cdf72ac64cb03ad4c15ffef4143dbf5c113f64a5ff4f81477bf9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b748c44bb9f53031c8cbc99a8a061bc181c1000c60a30f55393b6e9c45cc5bd"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ca038c7f6a0afd0b2448941b6ef9d5e1949e999f9e5517692eb6da58e9d44be"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e0bd57539da59a3e4671b90a502da9a28c72322a4f17866ba3ac63a82c4498e"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac6c2c45c847bbf8f91930d88716a0fb924b51e0c6dad329b793d670ec5db792"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b94d4ba43739bbe8b0ce4262bcc3b7b9f31459ad120fb595627eaeb7f9b9ca01"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:00e6424f4b26fe82d44577b4c842d7df97c20be6439e8e685d0d715feceb9fb9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:38de0a70160dd97540335b7ad3a74571b24f1dc3ed33f815f0880682e6880131"}, + {file = "pydantic_core-2.27.1-cp39-none-win32.whl", hash = "sha256:7ccebf51efc61634f6c2344da73e366c75e735960b5654b63d7e6f69a5885fa3"}, + {file = "pydantic_core-2.27.1-cp39-none-win_amd64.whl", hash = "sha256:a57847b090d7892f123726202b7daa20df6694cbd583b67a592e856bff603d6c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5fde892e6c697ce3e30c61b239330fc5d569a71fefd4eb6512fc6caec9dd9e2f"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:816f5aa087094099fff7edabb5e01cc370eb21aa1a1d44fe2d2aefdfb5599b31"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c10c309e18e443ddb108f0ef64e8729363adbfd92d6d57beec680f6261556f3"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98476c98b02c8e9b2eec76ac4156fd006628b1b2d0ef27e548ffa978393fd154"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c3027001c28434e7ca5a6e1e527487051136aa81803ac812be51802150d880dd"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7699b1df36a48169cdebda7ab5a2bac265204003f153b4bd17276153d997670a"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1c39b07d90be6b48968ddc8c19e7585052088fd7ec8d568bb31ff64c70ae3c97"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:46ccfe3032b3915586e469d4972973f893c0a2bb65669194a5bdea9bacc088c2"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:62ba45e21cf6571d7f716d903b5b7b6d2617e2d5d67c0923dc47b9d41369f840"}, + {file = "pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" + +[[package]] +name = "pyjwt" +version = "2.10.1" +description = "JSON Web Token implementation in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, +] + +[package.extras] +crypto = ["cryptography (>=3.4.0)"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] +docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] + +[[package]] +name = "pyrate-limiter" +version = "3.1.1" +description = "Python Rate-Limiter using Leaky-Bucket Algorithm" +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, + {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, +] + +[package.extras] +all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] +docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] + +[[package]] +name = "pyrsistent" +version = "0.20.0" +description = "Persistent/Functional/Immutable data structures" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, + {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, + {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34"}, + {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b"}, + {file = "pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f"}, + {file = "pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7"}, + {file = "pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958"}, + {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8"}, + {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a"}, + {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224"}, + {file = "pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656"}, + {file = "pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee"}, + {file = "pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e"}, + {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e"}, + {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3"}, + {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d"}, + {file = "pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174"}, + {file = "pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d"}, + {file = "pyrsistent-0.20.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054"}, + {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98"}, + {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714"}, + {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86"}, + {file = "pyrsistent-0.20.0-cp38-cp38-win32.whl", hash = "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423"}, + {file = "pyrsistent-0.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d"}, + {file = "pyrsistent-0.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce"}, + {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0"}, + {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022"}, + {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca"}, + {file = "pyrsistent-0.20.0-cp39-cp39-win32.whl", hash = "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f"}, + {file = "pyrsistent-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf"}, + {file = "pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b"}, + {file = "pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4"}, +] + +[[package]] +name = "pytest" +version = "8.3.4" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-ulid" +version = "3.0.0" +description = "Universally unique lexicographically sortable identifier" +optional = false +python-versions = ">=3.9" +files = [ + {file = "python_ulid-3.0.0-py3-none-any.whl", hash = "sha256:e4c4942ff50dbd79167ad01ac725ec58f924b4018025ce22c858bfcff99a5e31"}, + {file = "python_ulid-3.0.0.tar.gz", hash = "sha256:e50296a47dc8209d28629a22fc81ca26c00982c78934bd7766377ba37ea49a9f"}, +] + +[package.extras] +pydantic = ["pydantic (>=2.0)"] + +[[package]] +name = "pytz" +version = "2024.1" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, +] + +[[package]] +name = "pytzdata" +version = "2020.1" +description = "The Olson timezone database for Python." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, + {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, +] + +[[package]] +name = "rapidfuzz" +version = "3.10.1" +description = "rapid fuzzy string matching" +optional = false +python-versions = ">=3.9" +files = [ + {file = "rapidfuzz-3.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f17d9f21bf2f2f785d74f7b0d407805468b4c173fa3e52c86ec94436b338e74a"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b31f358a70efc143909fb3d75ac6cd3c139cd41339aa8f2a3a0ead8315731f2b"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f4f43f2204b56a61448ec2dd061e26fd344c404da99fb19f3458200c5874ba2"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d81bf186a453a2757472133b24915768abc7c3964194406ed93e170e16c21cb"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3611c8f45379a12063d70075c75134f2a8bd2e4e9b8a7995112ddae95ca1c982"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c3b537b97ac30da4b73930fa8a4fe2f79c6d1c10ad535c5c09726612cd6bed9"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:231ef1ec9cf7b59809ce3301006500b9d564ddb324635f4ea8f16b3e2a1780da"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ed4f3adc1294834955b7e74edd3c6bd1aad5831c007f2d91ea839e76461a5879"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:7b6015da2e707bf632a71772a2dbf0703cff6525732c005ad24987fe86e8ec32"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1b35a118d61d6f008e8e3fb3a77674d10806a8972c7b8be433d6598df4d60b01"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:bc308d79a7e877226f36bdf4e149e3ed398d8277c140be5c1fd892ec41739e6d"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f017dbfecc172e2d0c37cf9e3d519179d71a7f16094b57430dffc496a098aa17"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-win32.whl", hash = "sha256:36c0e1483e21f918d0f2f26799fe5ac91c7b0c34220b73007301c4f831a9c4c7"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:10746c1d4c8cd8881c28a87fd7ba0c9c102346dfe7ff1b0d021cdf093e9adbff"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-win_arm64.whl", hash = "sha256:dfa64b89dcb906835e275187569e51aa9d546a444489e97aaf2cc84011565fbe"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:92958ae075c87fef393f835ed02d4fe8d5ee2059a0934c6c447ea3417dfbf0e8"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ba7521e072c53e33c384e78615d0718e645cab3c366ecd3cc8cb732befd94967"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d02cbd75d283c287471b5b3738b3e05c9096150f93f2d2dfa10b3d700f2db9"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:efa1582a397da038e2f2576c9cd49b842f56fde37d84a6b0200ffebc08d82350"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f12912acee1f506f974f58de9fdc2e62eea5667377a7e9156de53241c05fdba8"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666d5d8b17becc3f53447bcb2b6b33ce6c2df78792495d1fa82b2924cd48701a"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26f71582c0d62445067ee338ddad99b655a8f4e4ed517a90dcbfbb7d19310474"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8a2ef08b27167bcff230ffbfeedd4c4fa6353563d6aaa015d725dd3632fc3de7"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:365e4fc1a2b95082c890f5e98489b894e6bf8c338c6ac89bb6523c2ca6e9f086"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1996feb7a61609fa842e6b5e0c549983222ffdedaf29644cc67e479902846dfe"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:cf654702f144beaa093103841a2ea6910d617d0bb3fccb1d1fd63c54dde2cd49"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec108bf25de674781d0a9a935030ba090c78d49def3d60f8724f3fc1e8e75024"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-win32.whl", hash = "sha256:031f8b367e5d92f7a1e27f7322012f3c321c3110137b43cc3bf678505583ef48"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:f98f36c6a1bb9a6c8bbec99ad87c8c0e364f34761739b5ea9adf7b48129ae8cf"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-win_arm64.whl", hash = "sha256:f1da2028cb4e41be55ee797a82d6c1cf589442504244249dfeb32efc608edee7"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1340b56340896bede246f612b6ecf685f661a56aabef3d2512481bfe23ac5835"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2316515169b7b5a453f0ce3adbc46c42aa332cae9f2edb668e24d1fc92b2f2bb"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e06fe6a12241ec1b72c0566c6b28cda714d61965d86569595ad24793d1ab259"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d99c1cd9443b19164ec185a7d752f4b4db19c066c136f028991a480720472e23"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1d9aa156ed52d3446388ba4c2f335e312191d1ca9d1f5762ee983cf23e4ecf6"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:54bcf4efaaee8e015822be0c2c28214815f4f6b4f70d8362cfecbd58a71188ac"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0c955e32afdbfdf6e9ee663d24afb25210152d98c26d22d399712d29a9b976b"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:191633722203f5b7717efcb73a14f76f3b124877d0608c070b827c5226d0b972"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:195baad28057ec9609e40385991004e470af9ef87401e24ebe72c064431524ab"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0fff4a6b87c07366662b62ae994ffbeadc472e72f725923f94b72a3db49f4671"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4ffed25f9fdc0b287f30a98467493d1e1ce5b583f6317f70ec0263b3c97dbba6"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d02cf8e5af89a9ac8f53c438ddff6d773f62c25c6619b29db96f4aae248177c0"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-win32.whl", hash = "sha256:f3bb81d4fe6a5d20650f8c0afcc8f6e1941f6fecdb434f11b874c42467baded0"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:aaf83e9170cb1338922ae42d320699dccbbdca8ffed07faeb0b9257822c26e24"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-win_arm64.whl", hash = "sha256:c5da802a0d085ad81b0f62828fb55557996c497b2d0b551bbdfeafd6d447892f"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fc22d69a1c9cccd560a5c434c0371b2df0f47c309c635a01a913e03bbf183710"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38b0dac2c8e057562b8f0d8ae5b663d2d6a28c5ab624de5b73cef9abb6129a24"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fde3bbb14e92ce8fcb5c2edfff72e474d0080cadda1c97785bf4822f037a309"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9141fb0592e55f98fe9ac0f3ce883199b9c13e262e0bf40c5b18cdf926109d16"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:237bec5dd1bfc9b40bbd786cd27949ef0c0eb5fab5eb491904c6b5df59d39d3c"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18123168cba156ab5794ea6de66db50f21bb3c66ae748d03316e71b27d907b95"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b75fe506c8e02769cc47f5ab21ce3e09b6211d3edaa8f8f27331cb6988779be"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9da82aa4b46973aaf9e03bb4c3d6977004648c8638febfc0f9d237e865761270"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c34c022d5ad564f1a5a57a4a89793bd70d7bad428150fb8ff2760b223407cdcf"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1e96c84d6c2a0ca94e15acb5399118fff669f4306beb98a6d8ec6f5dccab4412"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e8e154b84a311263e1aca86818c962e1fa9eefdd643d1d5d197fcd2738f88cb9"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:335fee93188f8cd585552bb8057228ce0111bd227fa81bfd40b7df6b75def8ab"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-win32.whl", hash = "sha256:6729b856166a9e95c278410f73683957ea6100c8a9d0a8dbe434c49663689255"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-win_amd64.whl", hash = "sha256:0e06d99ad1ad97cb2ef7f51ec6b1fedd74a3a700e4949353871cf331d07b382a"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-win_arm64.whl", hash = "sha256:8d1b7082104d596a3eb012e0549b2634ed15015b569f48879701e9d8db959dbb"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:779027d3307e1a2b1dc0c03c34df87a470a368a1a0840a9d2908baf2d4067956"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:440b5608ab12650d0390128d6858bc839ae77ffe5edf0b33a1551f2fa9860651"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cac41a411e07a6f3dc80dfbd33f6be70ea0abd72e99c59310819d09f07d945"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:958473c9f0bca250590200fd520b75be0dbdbc4a7327dc87a55b6d7dc8d68552"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ef60dfa73749ef91cb6073be1a3e135f4846ec809cc115f3cbfc6fe283a5584"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7fbac18f2c19fc983838a60611e67e3262e36859994c26f2ee85bb268de2355"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a0d519ff39db887cd73f4e297922786d548f5c05d6b51f4e6754f452a7f4296"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bebb7bc6aeb91cc57e4881b222484c26759ca865794187217c9dcea6c33adae6"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fe07f8b9c3bb5c5ad1d2c66884253e03800f4189a60eb6acd6119ebaf3eb9894"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:bfa48a4a2d45a41457f0840c48e579db157a927f4e97acf6e20df8fc521c79de"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2cf44d01bfe8ee605b7eaeecbc2b9ca64fc55765f17b304b40ed8995f69d7716"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e6bbca9246d9eedaa1c84e04a7f555493ba324d52ae4d9f3d9ddd1b740dcd87"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-win32.whl", hash = "sha256:567f88180f2c1423b4fe3f3ad6e6310fc97b85bdba574801548597287fc07028"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:6b2cd7c29d6ecdf0b780deb587198f13213ac01c430ada6913452fd0c40190fc"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-win_arm64.whl", hash = "sha256:9f912d459e46607ce276128f52bea21ebc3e9a5ccf4cccfef30dd5bddcf47be8"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ac4452f182243cfab30ba4668ef2de101effaedc30f9faabb06a095a8c90fd16"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:565c2bd4f7d23c32834652b27b51dd711814ab614b4e12add8476be4e20d1cf5"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:187d9747149321607be4ccd6f9f366730078bed806178ec3eeb31d05545e9e8f"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:616290fb9a8fa87e48cb0326d26f98d4e29f17c3b762c2d586f2b35c1fd2034b"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:073a5b107e17ebd264198b78614c0206fa438cce749692af5bc5f8f484883f50"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:39c4983e2e2ccb9732f3ac7d81617088822f4a12291d416b09b8a1eadebb3e29"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ac7adee6bcf0c6fee495d877edad1540a7e0f5fc208da03ccb64734b43522d7a"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:425f4ac80b22153d391ee3f94bc854668a0c6c129f05cf2eaf5ee74474ddb69e"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65a2fa13e8a219f9b5dcb9e74abe3ced5838a7327e629f426d333dfc8c5a6e66"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75561f3df9a906aaa23787e9992b228b1ab69007932dc42070f747103e177ba8"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:edd062490537e97ca125bc6c7f2b7331c2b73d21dc304615afe61ad1691e15d5"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfcc8feccf63245a22dfdd16e222f1a39771a44b870beb748117a0e09cbb4a62"}, + {file = "rapidfuzz-3.10.1.tar.gz", hash = "sha256:5a15546d847a915b3f42dc79ef9b0c78b998b4e2c53b252e7166284066585979"}, +] + +[package.extras] +all = ["numpy"] + +[[package]] +name = "regex" +version = "2024.11.6" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.8" +files = [ + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, +] + +[[package]] +name = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-cache" +version = "1.2.1" +description = "A persistent cache for python requests" +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, + {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, +] + +[package.dependencies] +attrs = ">=21.2" +cattrs = ">=22.2" +platformdirs = ">=2.5" +requests = ">=2.22" +url-normalize = ">=1.4" +urllib3 = ">=1.25.5" + +[package.extras] +all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] +bson = ["bson (>=0.5)"] +docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] +dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] +json = ["ujson (>=5.4)"] +mongodb = ["pymongo (>=3)"] +redis = ["redis (>=3)"] +security = ["itsdangerous (>=2.0)"] +yaml = ["pyyaml (>=6.0.1)"] + +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +description = "A utility belt for advanced users of python-requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, + {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, +] + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + +[[package]] +name = "serpyco-rs" +version = "1.11.0" +description = "" +optional = false +python-versions = ">=3.9" +files = [ + {file = "serpyco_rs-1.11.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4b2bd933539bd8c84315e2fb5ae52ef7a58ace5a6dfe3f8b73f74dc71216779e"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:627f957889ff73c4d2269fc7b6bba93212381befe03633e7cb5495de66ba9a33"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b0933620abc01434023e0e3e22255b7e4ab9b427b5a9a5ee00834656d792377a"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9ce46683d92e34abb20304817fc5ac6cb141a06fc7468dedb1d8865a8a9682f6"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bda437d86e8859bf91c189c1f4650899822f6d6d7b02b48f5729da904eb7bb7d"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a72bfbd282af17ebe76d122639013e802c09902543fdbbd828fb2159ec9755e"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d4808df5384e3e8581e31a90ba7a1fa501c0837b1f174284bb8a4555b6864ea"}, + {file = "serpyco_rs-1.11.0-cp310-none-win_amd64.whl", hash = "sha256:c7b60aef4c16d68efb0d6241f05d0a434d873d98449cbb4366b0d385f0a7172b"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d47ee577cf4d69b53917615cb031ad8708eb2f59fe78194b1968c13130fc2f7"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6090d9a1487237cdd4e9362a823eede23249602019b917e7bd57846179286e79"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7192eb3df576386fefd595ea31ae25c62522841ffec7e7aeb37a80b55bdc3213"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b52ef8affb7e71b9b98a7d5216d6a7ad03b04e990acb147cd9211c8b931c5487"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3480e09e473560c60e74aaa789e6b4d079637371aae0a98235440111464bbba7"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c92e36b0ab6fe866601c2331f7e99c809a126d21963c03d8a5c29331526deed"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84f497361952d4566bc1f77e9e15a84a2614f593cc671fbf0a0fa80046f9c3d7"}, + {file = "serpyco_rs-1.11.0-cp311-none-win_amd64.whl", hash = "sha256:37fc1cf192bef9784fbf1f4e03cec21750b9e704bef55cc0442f71a715eee920"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3ea93d485f03dc8b0cfb0d477f0ad2e86e78f0461b53010656ab5b4db1b41fb0"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7772410d15694b03f9c5500a2c47d62eed76e191bea4087ad042250346b1a38e"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42118463c1679846cffd2f06f47744c9b9eb33c5d0448afd88ea19e1a81a8ddd"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:79481a455b76cc56021dc55bb6d5bdda1b2b32bcb6a1ee711b597140d112e9b1"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8fd79051f9af9591fc03cf7d3033ff180416301f6a4fd3d1e3d92ebd2d68697"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d29c8f9aeed734a3b51f7349d04ec9063516ffa4e10b632d75e9b1309e4930e4"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15609158b0d9591ffa118302cd9d0039970cb3faf91dce32975f7d276e7411d5"}, + {file = "serpyco_rs-1.11.0-cp312-none-win_amd64.whl", hash = "sha256:00081eae77fbf4c5d88371c5586317ab02ccb293a330b460869a283edf2b7b69"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3028893366a1985adcedb13fa8f6f98c087c185efc427f94c2ccdafa40f45832"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c18bf511316f3abf648a68ee62ef88617bec57d3fcde69466b4361102715ae5"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7dde9ef09cdfaf7c62378186b9e29f54ec76114be4c347be6a06dd559c5681e"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:18500ebc5e75285841e35585a238629a990b709e14f68933233640d15ca17d5f"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47c23132d4e03982703a7630aa09877b41e499722142f76b6153f6619b612f3"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5f8e6ba499f6a0825bee0d8f8764569d367af871b563fc6512c171474e8e5383"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15438a076047c34cff6601a977df54948e8d39d1a86f89d05c48bc60f4c12a61"}, + {file = "serpyco_rs-1.11.0-cp313-none-win_amd64.whl", hash = "sha256:84ee2c109415bd81904fc9abb9aec86a5dd13166808c21142cf23ec639f683bd"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5c97c16c865261577fac4effeccc7ef5e0a1e8e35e7a3ee6c90c77c3a4cd7ff9"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47825e70f86fd6ef7c4a835dea3d6e8eef4fee354ed7b39ced99f31aba74a86e"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24d220220365110edba2f778f41ab3cf396883da0f26e1361a3ada9bd0227f73"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3a46f334af5a9d77acc6e1e58f355ae497900a2798929371f0545e274f6e6166"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d72b748acce4b4e3c7c9724e1eb33d033a1c26b08a698b393e0288060e0901"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2b8b6f205e8cc038d4d30dd0e70eece7bbecc816eb2f3787c330dc2218e232d"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:038d748bfff31f150f0c3edab2766b8843edb952cb1bd3bf547886beb0912dae"}, + {file = "serpyco_rs-1.11.0-cp39-none-win_amd64.whl", hash = "sha256:0fee1c89ec2cb013dc232e4ebef88e2844357ce8631063b56639dbfb83762f20"}, + {file = "serpyco_rs-1.11.0.tar.gz", hash = "sha256:70a844615ffb229e6e89c204b3ab7404aacaf2838911814c7d847969b8da2e3a"}, +] + +[package.dependencies] +attributes-doc = "*" +typing-extensions = "*" + +[[package]] +name = "six" +version = "1.17.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, +] + +[[package]] +name = "tenacity" +version = "8.5.0" +description = "Retry code until it succeeds" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, + {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, +] + +[package.extras] +doc = ["reno", "sphinx"] +test = ["pytest", "tornado (>=4.5)", "typeguard"] + +[[package]] +name = "tomli" +version = "2.2.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, +] + +[[package]] +name = "tqdm" +version = "4.67.1" +description = "Fast, Extensible Progress Meter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + +[[package]] +name = "tzdata" +version = "2024.2" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, + {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, +] + +[[package]] +name = "url-normalize" +version = "1.4.3" +description = "URL normalization for Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, + {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "urllib3" +version = "2.2.3" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, + {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "wcmatch" +version = "10.0" +description = "Wildcard/glob file name matcher." +optional = false +python-versions = ">=3.8" +files = [ + {file = "wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a"}, + {file = "wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a"}, +] + +[package.dependencies] +bracex = ">=2.1.1" + +[[package]] +name = "xmltodict" +version = "0.13.0" +description = "Makes working with XML feel like you are working with JSON" +optional = false +python-versions = ">=3.4" +files = [ + {file = "xmltodict-0.13.0-py2.py3-none-any.whl", hash = "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"}, + {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.10,<3.13" +content-hash = "5e8366b535518df8f014fbbecff6bfaf17a0fdf43bd99b1405d4896f6a9cfd00" diff --git a/airbyte-integrations/connectors/source-intercom/unit_tests/pyproject.toml b/airbyte-integrations/connectors/source-intercom/unit_tests/pyproject.toml new file mode 100644 index 000000000000..8363acb21e57 --- /dev/null +++ b/airbyte-integrations/connectors/source-intercom/unit_tests/pyproject.toml @@ -0,0 +1,16 @@ +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" +[tool.poetry] +name = "source-intercom-tests" +version = "0.0.0" +description = "Unit tests for source-intercom" +authors = ["Airbyte "] +[tool.poetry.dependencies] +python = "^3.10,<3.13" +airbyte-cdk = "6.10.0" +pytest = "^8" +[tool.pytest.ini_options] +filterwarnings = [ + "ignore:This class is experimental*" +] diff --git a/airbyte-integrations/connectors/source-intercom/unit_tests/test_components.py b/airbyte-integrations/connectors/source-intercom/unit_tests/test_components.py index cb3ca58063dd..92dcc44da94e 100644 --- a/airbyte-integrations/connectors/source-intercom/unit_tests/test_components.py +++ b/airbyte-integrations/connectors/source-intercom/unit_tests/test_components.py @@ -6,13 +6,14 @@ import pytest import requests + from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig from airbyte_cdk.sources.streams import Stream -from source_intercom.components import IncrementalSingleSliceCursor, IncrementalSubstreamSlicerCursor, IntercomRateLimiter -def test_slicer(): +def test_slicer(components_module): date_time_dict = {"updated_at": 1662459010} + IncrementalSingleSliceCursor = components_module.IncrementalSingleSliceCursor slicer = IncrementalSingleSliceCursor(config={}, parameters={}, cursor_field="updated_at") slicer.observe(date_time_dict, date_time_dict) slicer.close_slice(date_time_dict) @@ -36,7 +37,7 @@ def test_slicer(): ) ], ) -def test_sub_slicer(last_record, expected, records): +def test_sub_slicer(components_module, last_record, expected, records): parent_stream = Mock(spec=Stream) parent_stream.name = "parent_stream_name" parent_stream.cursor_field = "parent_cursor_field" @@ -52,6 +53,8 @@ def test_sub_slicer(last_record, expected, records): config={}, ) + IncrementalSubstreamSlicerCursor = components_module.IncrementalSubstreamSlicerCursor + slicer = IncrementalSubstreamSlicerCursor( config={}, parameters={}, cursor_field="first_stream_cursor", parent_stream_configs=[parent_config], parent_complete_fetch=True ) @@ -72,7 +75,9 @@ def test_sub_slicer(last_record, expected, records): ({}, 1.0), ], ) -def test_rate_limiter(rate_limit_header, backoff_time): +def test_rate_limiter(components_module, rate_limit_header, backoff_time): + IntercomRateLimiter = components_module.IntercomRateLimiter + def check_backoff_time(t): """A replacer for original `IntercomRateLimiter.backoff_time`""" assert backoff_time == t, f"Expected {backoff_time}, got {t}" diff --git a/airbyte-integrations/connectors/source-intercom/unit_tests/test_source.py b/airbyte-integrations/connectors/source-intercom/unit_tests/test_source.py deleted file mode 100644 index fe7a765a2ee0..000000000000 --- a/airbyte-integrations/connectors/source-intercom/unit_tests/test_source.py +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from source_intercom import SourceIntercom - - -def test_source(): - assert SourceIntercom() diff --git a/airbyte-integrations/connectors/source-intruder/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-intruder/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-intruder/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-intruder/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-intruder/metadata.yaml b/airbyte-integrations/connectors/source-intruder/metadata.yaml index 0ec31804e039..23430f88da52 100644 --- a/airbyte-integrations/connectors/source-intruder/metadata.yaml +++ b/airbyte-integrations/connectors/source-intruder/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 3d15163b-11d8-412f-b808-795c9b2c3a3a - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.8 dockerRepository: airbyte/source-intruder githubIssueLabel: source-intruder icon: intruder.svg @@ -39,5 +39,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-invoiced/metadata.yaml b/airbyte-integrations/connectors/source-invoiced/metadata.yaml index 577616a267b6..971fe89771fe 100644 --- a/airbyte-integrations/connectors/source-invoiced/metadata.yaml +++ b/airbyte-integrations/connectors/source-invoiced/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-invoiced connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 5f43588b-998b-4398-bb15-fb6eb4fc015e - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-invoiced githubIssueLabel: source-invoiced icon: icon.svg diff --git a/airbyte-integrations/connectors/source-invoiceninja/README.md b/airbyte-integrations/connectors/source-invoiceninja/README.md new file mode 100644 index 000000000000..3ce221b8f055 --- /dev/null +++ b/airbyte-integrations/connectors/source-invoiceninja/README.md @@ -0,0 +1,35 @@ +# Invoiceninja +This directory contains the manifest-only connector for `source-invoiceninja`. + +Invoice Ninja is an invoicing, billing, and payment management software. +With this connector we can extract data from various streams such asproducts , invoice , payments and quotes. +Docs : https://api-docs.invoicing.co/#overview--introduction + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-invoiceninja:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-invoiceninja build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-invoiceninja test +``` + diff --git a/airbyte-integrations/connectors/source-invoiceninja/acceptance-test-config.yml b/airbyte-integrations/connectors/source-invoiceninja/acceptance-test-config.yml new file mode 100644 index 000000000000..8683f6601958 --- /dev/null +++ b/airbyte-integrations/connectors/source-invoiceninja/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-invoiceninja:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-invoiceninja/icon.svg b/airbyte-integrations/connectors/source-invoiceninja/icon.svg new file mode 100644 index 000000000000..40b3f80fcd3b --- /dev/null +++ b/airbyte-integrations/connectors/source-invoiceninja/icon.svg @@ -0,0 +1,2 @@ + +Invoice Ninja icon diff --git a/airbyte-integrations/connectors/source-invoiceninja/manifest.yaml b/airbyte-integrations/connectors/source-invoiceninja/manifest.yaml new file mode 100644 index 000000000000..fdccf0d7678e --- /dev/null +++ b/airbyte-integrations/connectors/source-invoiceninja/manifest.yaml @@ -0,0 +1,4132 @@ +version: 6.1.0 + +type: DeclarativeSource + +description: >- + Invoice Ninja is an invoicing, billing, and payment management software. + + With this connector we can extract data from various streams such asproducts , + invoice , payments and quotes. + + Docs : https://api-docs.invoicing.co/#overview--introduction + +check: + type: CheckStream + stream_names: + - clients + +definitions: + streams: + clients: + type: DeclarativeStream + name: clients + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: clients + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/clients" + products: + type: DeclarativeStream + name: products + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: products + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + invoices: + type: DeclarativeStream + name: invoices + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: invoices + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/invoices" + recurring invoices: + type: DeclarativeStream + name: recurring invoices + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: recurring_invoices + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/recurring invoices" + payments: + type: DeclarativeStream + name: payments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: payments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/payments" + quotes: + type: DeclarativeStream + name: quotes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: quotes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/quotes" + credits: + type: DeclarativeStream + name: credits + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: credits + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/credits" + projects: + type: DeclarativeStream + name: projects + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: projects + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/projects" + tasks: + type: DeclarativeStream + name: tasks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: tasks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tasks" + vendors: + type: DeclarativeStream + name: vendors + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: vendors + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/vendors" + purchase_orders: + type: DeclarativeStream + name: purchase_orders + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: purchase_orders + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/purchase_orders" + expenses: + type: DeclarativeStream + name: expenses + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: expenses + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/expenses" + recurring expenses: + type: DeclarativeStream + name: recurring expenses + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: recurring_expenses + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/recurring expenses" + bank transactions: + type: DeclarativeStream + name: bank transactions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: bank_transactions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/bank transactions" + base_requester: + type: HttpRequester + url_base: https://invoicing.co/api/v1/ + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: X-API-TOKEN + inject_into: header + +streams: + - $ref: "#/definitions/streams/clients" + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/invoices" + - $ref: "#/definitions/streams/recurring invoices" + - $ref: "#/definitions/streams/payments" + - $ref: "#/definitions/streams/quotes" + - $ref: "#/definitions/streams/credits" + - $ref: "#/definitions/streams/projects" + - $ref: "#/definitions/streams/tasks" + - $ref: "#/definitions/streams/vendors" + - $ref: "#/definitions/streams/purchase_orders" + - $ref: "#/definitions/streams/expenses" + - $ref: "#/definitions/streams/recurring expenses" + - $ref: "#/definitions/streams/bank transactions" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + order: 0 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + clients: true + products: true + invoices: true + recurring invoices: true + payments: true + quotes: true + credits: true + projects: true + tasks: true + vendors: true + purchase_orders: true + expenses: true + recurring expenses: true + bank transactions: true + testedStreams: + clients: + streamHash: 8310efaa5fe0141735b3087522f2ee0d3ac11cac + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + products: + streamHash: 5c569191df2d068ebd1ac6ac9749709c35f3d83e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + invoices: + streamHash: a92a32994c972113dd0838fed578ae47e8917e49 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + recurring invoices: + streamHash: cf41fe8cff4f1ad34219c77be898355a20d71501 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + payments: + streamHash: 1f0a2a67e3ac4a3ea1090845d39d48b1350802dd + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + quotes: + streamHash: 782f358cadd7c143fbf444a08e597c38fe23361a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + credits: + streamHash: dcaff60b0805a53023559885a5561ccd584c68f9 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + projects: + streamHash: 40dc252f04f72814150237a3bc2bd6694ea7f814 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tasks: + streamHash: fe63810ff5089997cea55d84d10a9d335b3c80a5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + vendors: + streamHash: 20ccca439b51faba7ec5633066511dbcd123e7f5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + purchase_orders: + streamHash: d4310cd8a33cc89f922e96b51a7871f67d297d60 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + expenses: + streamHash: 425a31d5ad1869db6dc1282046360b7ec2a1d29e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + recurring expenses: + streamHash: c3dc2d7b586d09cd396bc0b5585f19ca853f297a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + bank transactions: + hasRecords: true + streamHash: 345dbd0e7bfdc8c943391d0572c539670b261006 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: {} + +schemas: + clients: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address1: + type: + - string + - "null" + address2: + type: + - string + - "null" + archived_at: + type: + - number + - "null" + assigned_user_id: + type: + - string + - "null" + balance: + type: + - number + - "null" + city: + type: + - string + - "null" + classification: + type: + - string + - "null" + client_hash: + type: + - string + - "null" + contacts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + archived_at: + type: + - number + - "null" + contact_key: + type: + - string + - "null" + created_at: + type: + - number + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + id: + type: + - string + - "null" + is_locked: + type: + - boolean + - "null" + is_primary: + type: + - boolean + - "null" + last_login: + type: + - number + - "null" + last_name: + type: + - string + - "null" + link: + type: + - string + - "null" + password: + type: + - string + - "null" + phone: + type: + - string + - "null" + send_email: + type: + - boolean + - "null" + updated_at: + type: + - number + - "null" + country_id: + type: + - string + - "null" + created_at: + type: + - number + - "null" + credit_balance: + type: + - number + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + display_name: + type: + - string + - "null" + documents: + type: + - array + - "null" + e_invoice: + type: + - object + - "null" + gateway_tokens: + type: + - array + - "null" + group_settings_id: + type: + - string + - "null" + has_valid_vat_number: + type: + - boolean + - "null" + id: + type: string + id_number: + type: + - string + - "null" + industry_id: + type: + - string + - "null" + is_deleted: + type: + - boolean + - "null" + is_tax_exempt: + type: + - boolean + - "null" + last_login: + type: + - number + - "null" + name: + type: + - string + - "null" + number: + type: + - string + - "null" + paid_to_date: + type: + - number + - "null" + payment_balance: + type: + - number + - "null" + phone: + type: + - string + - "null" + postal_code: + type: + - string + - "null" + private_notes: + type: + - string + - "null" + public_notes: + type: + - string + - "null" + routing_id: + type: + - string + - "null" + settings: + type: + - object + - "null" + properties: + currency_id: + type: + - string + - "null" + default_task_rate: + type: + - number + - "null" + entity: + type: + - string + - "null" + industry_id: + type: + - string + - "null" + language_id: + type: + - string + - "null" + payment_terms: + type: + - string + - "null" + send_reminders: + type: + - boolean + - "null" + size_id: + type: + - string + - "null" + valid_until: + type: + - string + - "null" + shipping_address1: + type: + - string + - "null" + shipping_address2: + type: + - string + - "null" + shipping_city: + type: + - string + - "null" + shipping_country_id: + type: + - string + - "null" + shipping_postal_code: + type: + - string + - "null" + shipping_state: + type: + - string + - "null" + size_id: + type: + - string + - "null" + state: + type: + - string + - "null" + tax_info: + type: + - object + - "null" + updated_at: + type: + - number + - "null" + user_id: + type: + - string + - "null" + vat_number: + type: + - string + - "null" + website: + type: + - string + - "null" + required: + - id + products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + archived_at: + type: + - number + - "null" + assigned_user_id: + type: + - string + - "null" + cost: + type: + - number + - "null" + created_at: + type: + - number + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + documents: + type: + - array + - "null" + id: + type: string + in_stock_quantity: + type: + - number + - "null" + is_deleted: + type: + - boolean + - "null" + max_quantity: + type: + - number + - "null" + notes: + type: + - string + - "null" + price: + type: + - number + - "null" + product_image: + type: + - string + - "null" + product_key: + type: + - string + - "null" + quantity: + type: + - number + - "null" + stock_notification: + type: + - boolean + - "null" + stock_notification_threshold: + type: + - number + - "null" + tax_id: + type: + - string + - "null" + tax_name1: + type: + - string + - "null" + tax_name2: + type: + - string + - "null" + tax_name3: + type: + - string + - "null" + tax_rate1: + type: + - number + - "null" + tax_rate2: + type: + - number + - "null" + tax_rate3: + type: + - number + - "null" + updated_at: + type: + - number + - "null" + user_id: + type: + - string + - "null" + required: + - id + invoices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + amount: + type: + - number + - "null" + archived_at: + type: + - number + - "null" + assigned_user_id: + type: + - string + - "null" + auto_bill_enabled: + type: + - boolean + - "null" + balance: + type: + - number + - "null" + client_id: + type: + - string + - "null" + created_at: + type: + - number + - "null" + custom_surcharge1: + type: + - number + - "null" + custom_surcharge2: + type: + - number + - "null" + custom_surcharge3: + type: + - number + - "null" + custom_surcharge4: + type: + - number + - "null" + custom_surcharge_tax1: + type: + - boolean + - "null" + custom_surcharge_tax2: + type: + - boolean + - "null" + custom_surcharge_tax3: + type: + - boolean + - "null" + custom_surcharge_tax4: + type: + - boolean + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + date: + type: + - string + - "null" + design_id: + type: + - string + - "null" + discount: + type: + - number + - "null" + documents: + type: + - array + - "null" + due_date: + type: + - string + - "null" + e_invoice: + type: + - object + - "null" + entity_type: + type: + - string + - "null" + exchange_rate: + type: + - number + - "null" + footer: + type: + - string + - "null" + has_expenses: + type: + - boolean + - "null" + has_tasks: + type: + - boolean + - "null" + id: + type: string + invitations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + archived_at: + type: + - number + - "null" + client_contact_id: + type: + - string + - "null" + created_at: + type: + - number + - "null" + email_error: + type: + - string + - "null" + email_status: + type: + - string + - "null" + id: + type: + - string + - "null" + key: + type: + - string + - "null" + link: + type: + - string + - "null" + message_id: + type: + - string + - "null" + opened_date: + type: + - string + - "null" + sent_date: + type: + - string + - "null" + updated_at: + type: + - number + - "null" + viewed_date: + type: + - string + - "null" + is_amount_discount: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + last_sent_date: + type: + - string + - "null" + line_items: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _id: + type: + - string + - "null" + cost: + type: + - number + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + date: + type: + - string + - "null" + discount: + type: + - number + - "null" + expense_id: + type: + - string + - "null" + gross_line_total: + type: + - number + - "null" + is_amount_discount: + type: + - boolean + - "null" + line_total: + type: + - number + - "null" + notes: + type: + - string + - "null" + product_cost: + type: + - number + - "null" + product_key: + type: + - string + - "null" + quantity: + type: + - number + - "null" + sort_id: + type: + - string + - "null" + task_id: + type: + - string + - "null" + tax_amount: + type: + - number + - "null" + tax_id: + type: + - string + - "null" + tax_name1: + type: + - string + - "null" + tax_name2: + type: + - string + - "null" + tax_name3: + type: + - string + - "null" + tax_rate1: + type: + - number + - "null" + tax_rate2: + type: + - number + - "null" + tax_rate3: + type: + - number + - "null" + type_id: + type: + - string + - "null" + unit_code: + type: + - string + - "null" + next_send_date: + type: + - string + - "null" + number: + type: + - string + - "null" + paid_to_date: + type: + - number + - "null" + partial: + type: + - number + - "null" + partial_due_date: + type: + - string + - "null" + po_number: + type: + - string + - "null" + private_notes: + type: + - string + - "null" + project_id: + type: + - string + - "null" + public_notes: + type: + - string + - "null" + recurring_id: + type: + - string + - "null" + reminder1_sent: + type: + - string + - "null" + reminder2_sent: + type: + - string + - "null" + reminder3_sent: + type: + - string + - "null" + reminder_last_sent: + type: + - string + - "null" + status_id: + type: + - string + - "null" + subscription_id: + type: + - string + - "null" + tax_info: + type: + - object + - "null" + tax_name1: + type: + - string + - "null" + tax_name2: + type: + - string + - "null" + tax_name3: + type: + - string + - "null" + tax_rate1: + type: + - number + - "null" + tax_rate2: + type: + - number + - "null" + tax_rate3: + type: + - number + - "null" + terms: + type: + - string + - "null" + total_taxes: + type: + - number + - "null" + updated_at: + type: + - number + - "null" + user_id: + type: + - string + - "null" + uses_inclusive_taxes: + type: + - boolean + - "null" + vendor_id: + type: + - string + - "null" + required: + - id + recurring invoices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + amount: + type: + - number + - "null" + archived_at: + type: + - number + - "null" + assigned_user_id: + type: + - string + - "null" + auto_bill: + type: + - string + - "null" + auto_bill_enabled: + type: + - boolean + - "null" + balance: + type: + - number + - "null" + client_id: + type: + - string + - "null" + created_at: + type: + - number + - "null" + custom_surcharge1: + type: + - number + - "null" + custom_surcharge2: + type: + - number + - "null" + custom_surcharge3: + type: + - number + - "null" + custom_surcharge4: + type: + - number + - "null" + custom_surcharge_tax1: + type: + - boolean + - "null" + custom_surcharge_tax2: + type: + - boolean + - "null" + custom_surcharge_tax3: + type: + - boolean + - "null" + custom_surcharge_tax4: + type: + - boolean + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + date: + type: + - string + - "null" + design_id: + type: + - string + - "null" + discount: + type: + - number + - "null" + documents: + type: + - array + - "null" + due_date: + type: + - string + - "null" + due_date_days: + type: + - string + - "null" + entity_type: + type: + - string + - "null" + exchange_rate: + type: + - number + - "null" + footer: + type: + - string + - "null" + frequency_id: + type: + - string + - "null" + has_expenses: + type: + - boolean + - "null" + has_tasks: + type: + - boolean + - "null" + id: + type: string + invitations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + archived_at: + type: + - number + - "null" + client_contact_id: + type: + - string + - "null" + created_at: + type: + - number + - "null" + email_error: + type: + - string + - "null" + email_status: + type: + - string + - "null" + id: + type: + - string + - "null" + key: + type: + - string + - "null" + link: + type: + - string + - "null" + message_id: + type: + - string + - "null" + opened_date: + type: + - string + - "null" + sent_date: + type: + - string + - "null" + updated_at: + type: + - number + - "null" + viewed_date: + type: + - string + - "null" + is_amount_discount: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + last_sent_date: + type: + - string + - "null" + line_items: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _id: + type: + - string + - "null" + cost: + type: + - number + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + date: + type: + - string + - "null" + discount: + type: + - number + - "null" + expense_id: + type: + - string + - "null" + gross_line_total: + type: + - number + - "null" + is_amount_discount: + type: + - boolean + - "null" + line_total: + type: + - number + - "null" + notes: + type: + - string + - "null" + product_cost: + type: + - number + - "null" + product_key: + type: + - string + - "null" + quantity: + type: + - number + - "null" + sort_id: + type: + - string + - "null" + task_id: + type: + - string + - "null" + tax_amount: + type: + - number + - "null" + tax_id: + type: + - string + - "null" + tax_name1: + type: + - string + - "null" + tax_name2: + type: + - string + - "null" + tax_name3: + type: + - string + - "null" + tax_rate1: + type: + - number + - "null" + tax_rate2: + type: + - number + - "null" + tax_rate3: + type: + - number + - "null" + type_id: + type: + - string + - "null" + unit_code: + type: + - string + - "null" + next_send_date: + type: + - string + - "null" + next_send_datetime: + type: + - string + - "null" + number: + type: + - string + - "null" + paid_to_date: + type: + - number + - "null" + partial: + type: + - number + - "null" + partial_due_date: + type: + - string + - "null" + po_number: + type: + - string + - "null" + private_notes: + type: + - string + - "null" + project_id: + type: + - string + - "null" + public_notes: + type: + - string + - "null" + recurring_dates: + type: + - array + - "null" + remaining_cycles: + type: + - number + - "null" + status_id: + type: + - string + - "null" + subscription_id: + type: + - string + - "null" + tax_name1: + type: + - string + - "null" + tax_name2: + type: + - string + - "null" + tax_name3: + type: + - string + - "null" + tax_rate1: + type: + - number + - "null" + tax_rate2: + type: + - number + - "null" + tax_rate3: + type: + - number + - "null" + terms: + type: + - string + - "null" + total_taxes: + type: + - number + - "null" + updated_at: + type: + - number + - "null" + user_id: + type: + - string + - "null" + uses_inclusive_taxes: + type: + - boolean + - "null" + vendor_id: + type: + - string + - "null" + required: + - id + payments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + amount: + type: + - number + - "null" + applied: + type: + - number + - "null" + archived_at: + type: + - number + - "null" + assigned_user_id: + type: + - string + - "null" + client_contact_id: + type: + - string + - "null" + client_id: + type: + - string + - "null" + company_gateway_id: + type: + - string + - "null" + created_at: + type: + - number + - "null" + currency_id: + type: + - string + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + date: + type: + - string + - "null" + documents: + type: + - array + - "null" + exchange_currency_id: + type: + - string + - "null" + exchange_rate: + type: + - number + - "null" + gateway_type_id: + type: + - string + - "null" + id: + type: string + invitation_id: + type: + - string + - "null" + is_deleted: + type: + - boolean + - "null" + is_manual: + type: + - boolean + - "null" + number: + type: + - string + - "null" + paymentables: + type: + - array + - "null" + private_notes: + type: + - string + - "null" + project_id: + type: + - string + - "null" + refunded: + type: + - number + - "null" + status_id: + type: + - string + - "null" + transaction_id: + type: + - string + - "null" + transaction_reference: + type: + - string + - "null" + type_id: + type: + - string + - "null" + updated_at: + type: + - number + - "null" + user_id: + type: + - string + - "null" + vendor_id: + type: + - string + - "null" + required: + - id + quotes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + amount: + type: + - number + - "null" + archived_at: + type: + - number + - "null" + assigned_user_id: + type: + - string + - "null" + balance: + type: + - number + - "null" + client_id: + type: + - string + - "null" + created_at: + type: + - number + - "null" + custom_surcharge1: + type: + - number + - "null" + custom_surcharge2: + type: + - number + - "null" + custom_surcharge3: + type: + - number + - "null" + custom_surcharge4: + type: + - number + - "null" + custom_surcharge_tax1: + type: + - boolean + - "null" + custom_surcharge_tax2: + type: + - boolean + - "null" + custom_surcharge_tax3: + type: + - boolean + - "null" + custom_surcharge_tax4: + type: + - boolean + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + date: + type: + - string + - "null" + design_id: + type: + - string + - "null" + discount: + type: + - number + - "null" + documents: + type: + - array + - "null" + due_date: + type: + - string + - "null" + e_invoice: + type: + - object + - "null" + entity_type: + type: + - string + - "null" + exchange_rate: + type: + - number + - "null" + footer: + type: + - string + - "null" + has_expenses: + type: + - boolean + - "null" + has_tasks: + type: + - boolean + - "null" + id: + type: string + invitations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + archived_at: + type: + - number + - "null" + client_contact_id: + type: + - string + - "null" + created_at: + type: + - number + - "null" + email_error: + type: + - string + - "null" + email_status: + type: + - string + - "null" + id: + type: + - string + - "null" + key: + type: + - string + - "null" + link: + type: + - string + - "null" + message_id: + type: + - string + - "null" + opened_date: + type: + - string + - "null" + sent_date: + type: + - string + - "null" + updated_at: + type: + - number + - "null" + viewed_date: + type: + - string + - "null" + invoice_id: + type: + - string + - "null" + is_amount_discount: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + last_sent_date: + type: + - string + - "null" + line_items: + type: + - array + - "null" + next_send_date: + type: + - string + - "null" + number: + type: + - string + - "null" + paid_to_date: + type: + - number + - "null" + partial: + type: + - number + - "null" + partial_due_date: + type: + - string + - "null" + po_number: + type: + - string + - "null" + private_notes: + type: + - string + - "null" + project_id: + type: + - string + - "null" + public_notes: + type: + - string + - "null" + reminder1_sent: + type: + - string + - "null" + reminder2_sent: + type: + - string + - "null" + reminder3_sent: + type: + - string + - "null" + reminder_last_sent: + type: + - string + - "null" + status_id: + type: + - string + - "null" + subscription_id: + type: + - string + - "null" + tax_info: + type: + - object + - "null" + tax_name1: + type: + - string + - "null" + tax_name2: + type: + - string + - "null" + tax_name3: + type: + - string + - "null" + tax_rate1: + type: + - number + - "null" + tax_rate2: + type: + - number + - "null" + tax_rate3: + type: + - number + - "null" + terms: + type: + - string + - "null" + total_taxes: + type: + - number + - "null" + updated_at: + type: + - number + - "null" + user_id: + type: + - string + - "null" + uses_inclusive_taxes: + type: + - boolean + - "null" + vendor_id: + type: + - string + - "null" + required: + - id + credits: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + amount: + type: + - number + - "null" + archived_at: + type: + - number + - "null" + assigned_user_id: + type: + - string + - "null" + balance: + type: + - number + - "null" + client_id: + type: + - string + - "null" + created_at: + type: + - number + - "null" + custom_surcharge1: + type: + - number + - "null" + custom_surcharge2: + type: + - number + - "null" + custom_surcharge3: + type: + - number + - "null" + custom_surcharge4: + type: + - number + - "null" + custom_surcharge_tax1: + type: + - boolean + - "null" + custom_surcharge_tax2: + type: + - boolean + - "null" + custom_surcharge_tax3: + type: + - boolean + - "null" + custom_surcharge_tax4: + type: + - boolean + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + date: + type: + - string + - "null" + design_id: + type: + - string + - "null" + discount: + type: + - number + - "null" + documents: + type: + - array + - "null" + due_date: + type: + - string + - "null" + e_invoice: + type: + - object + - "null" + entity_type: + type: + - string + - "null" + exchange_rate: + type: + - number + - "null" + footer: + type: + - string + - "null" + has_expenses: + type: + - boolean + - "null" + has_tasks: + type: + - boolean + - "null" + id: + type: string + invitations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + archived_at: + type: + - number + - "null" + client_contact_id: + type: + - string + - "null" + created_at: + type: + - number + - "null" + email_error: + type: + - string + - "null" + email_status: + type: + - string + - "null" + id: + type: + - string + - "null" + key: + type: + - string + - "null" + link: + type: + - string + - "null" + message_id: + type: + - string + - "null" + opened_date: + type: + - string + - "null" + sent_date: + type: + - string + - "null" + updated_at: + type: + - number + - "null" + viewed_date: + type: + - string + - "null" + invoice_id: + type: + - string + - "null" + is_amount_discount: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + last_sent_date: + type: + - string + - "null" + line_items: + type: + - array + - "null" + next_send_date: + type: + - string + - "null" + number: + type: + - string + - "null" + paid_to_date: + type: + - number + - "null" + partial: + type: + - number + - "null" + partial_due_date: + type: + - string + - "null" + po_number: + type: + - string + - "null" + private_notes: + type: + - string + - "null" + project_id: + type: + - string + - "null" + public_notes: + type: + - string + - "null" + reminder1_sent: + type: + - string + - "null" + reminder2_sent: + type: + - string + - "null" + reminder3_sent: + type: + - string + - "null" + reminder_last_sent: + type: + - string + - "null" + status_id: + type: + - string + - "null" + subscription_id: + type: + - string + - "null" + tax_info: + type: + - object + - "null" + tax_name1: + type: + - string + - "null" + tax_name2: + type: + - string + - "null" + tax_name3: + type: + - string + - "null" + tax_rate1: + type: + - number + - "null" + tax_rate2: + type: + - number + - "null" + tax_rate3: + type: + - number + - "null" + terms: + type: + - string + - "null" + total_taxes: + type: + - number + - "null" + updated_at: + type: + - number + - "null" + user_id: + type: + - string + - "null" + uses_inclusive_taxes: + type: + - boolean + - "null" + vendor_id: + type: + - string + - "null" + required: + - id + projects: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + archived_at: + type: + - number + - "null" + assigned_user_id: + type: + - string + - "null" + budgeted_hours: + type: + - number + - "null" + client_id: + type: + - string + - "null" + color: + type: + - string + - "null" + created_at: + type: + - number + - "null" + current_hours: + type: + - number + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + documents: + type: + - array + - "null" + due_date: + type: + - string + - "null" + id: + type: string + is_deleted: + type: + - boolean + - "null" + name: + type: + - string + - "null" + number: + type: + - string + - "null" + private_notes: + type: + - string + - "null" + public_notes: + type: + - string + - "null" + task_rate: + type: + - number + - "null" + updated_at: + type: + - number + - "null" + user_id: + type: + - string + - "null" + required: + - id + tasks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + archived_at: + type: + - number + - "null" + assigned_user_id: + type: + - string + - "null" + client_id: + type: + - string + - "null" + created_at: + type: + - number + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + date: + type: + - string + - "null" + documents: + type: + - array + - "null" + duration: + type: + - number + - "null" + id: + type: string + invoice_id: + type: + - string + - "null" + is_date_based: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + is_running: + type: + - boolean + - "null" + number: + type: + - string + - "null" + project: + type: + - object + - "null" + properties: + archived_at: + type: + - number + - "null" + assigned_user_id: + type: + - string + - "null" + budgeted_hours: + type: + - number + - "null" + client_id: + type: + - string + - "null" + color: + type: + - string + - "null" + created_at: + type: + - number + - "null" + current_hours: + type: + - number + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + documents: + type: + - array + - "null" + due_date: + type: + - string + - "null" + id: + type: + - string + - "null" + is_deleted: + type: + - boolean + - "null" + name: + type: + - string + - "null" + number: + type: + - string + - "null" + private_notes: + type: + - string + - "null" + public_notes: + type: + - string + - "null" + task_rate: + type: + - number + - "null" + updated_at: + type: + - number + - "null" + user_id: + type: + - string + - "null" + project_id: + type: + - string + - "null" + rate: + type: + - number + - "null" + status_id: + type: + - string + - "null" + status_sort_order: + type: + - number + - "null" + time_log: + type: + - string + - "null" + updated_at: + type: + - number + - "null" + user_id: + type: + - string + - "null" + required: + - id + vendors: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address1: + type: + - string + - "null" + address2: + type: + - string + - "null" + archived_at: + type: + - number + - "null" + assigned_user_id: + type: + - string + - "null" + city: + type: + - string + - "null" + classification: + type: + - string + - "null" + contacts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + archived_at: + type: + - number + - "null" + created_at: + type: + - number + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + id: + type: + - string + - "null" + is_primary: + type: + - boolean + - "null" + last_login: + type: + - number + - "null" + last_name: + type: + - string + - "null" + link: + type: + - string + - "null" + password: + type: + - string + - "null" + phone: + type: + - string + - "null" + send_email: + type: + - boolean + - "null" + updated_at: + type: + - number + - "null" + country_id: + type: + - string + - "null" + created_at: + type: + - number + - "null" + currency_id: + type: + - string + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + display_name: + type: + - string + - "null" + documents: + type: + - array + - "null" + id: + type: string + id_number: + type: + - string + - "null" + is_deleted: + type: + - boolean + - "null" + is_tax_exempt: + type: + - boolean + - "null" + language_id: + type: + - string + - "null" + last_login: + type: + - number + - "null" + name: + type: + - string + - "null" + number: + type: + - string + - "null" + phone: + type: + - string + - "null" + postal_code: + type: + - string + - "null" + private_notes: + type: + - string + - "null" + public_notes: + type: + - string + - "null" + routing_id: + type: + - string + - "null" + state: + type: + - string + - "null" + updated_at: + type: + - number + - "null" + user_id: + type: + - string + - "null" + vat_number: + type: + - string + - "null" + website: + type: + - string + - "null" + required: + - id + purchase_orders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + amount: + type: + - number + - "null" + archived_at: + type: + - number + - "null" + assigned_user_id: + type: + - string + - "null" + balance: + type: + - number + - "null" + client_id: + type: + - string + - "null" + created_at: + type: + - number + - "null" + currency_id: + type: + - string + - "null" + custom_surcharge1: + type: + - number + - "null" + custom_surcharge2: + type: + - number + - "null" + custom_surcharge3: + type: + - number + - "null" + custom_surcharge4: + type: + - number + - "null" + custom_surcharge_tax1: + type: + - boolean + - "null" + custom_surcharge_tax2: + type: + - boolean + - "null" + custom_surcharge_tax3: + type: + - boolean + - "null" + custom_surcharge_tax4: + type: + - boolean + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + date: + type: + - string + - "null" + design_id: + type: + - string + - "null" + discount: + type: + - number + - "null" + documents: + type: + - array + - "null" + due_date: + type: + - string + - "null" + e_invoice: + type: + - object + - "null" + entity_type: + type: + - string + - "null" + exchange_rate: + type: + - number + - "null" + expense_id: + type: + - string + - "null" + footer: + type: + - string + - "null" + has_expenses: + type: + - boolean + - "null" + has_tasks: + type: + - boolean + - "null" + id: + type: string + invitations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + archived_at: + type: + - number + - "null" + created_at: + type: + - number + - "null" + email_error: + type: + - string + - "null" + email_status: + type: + - string + - "null" + id: + type: + - string + - "null" + key: + type: + - string + - "null" + link: + type: + - string + - "null" + message_id: + type: + - string + - "null" + opened_date: + type: + - string + - "null" + sent_date: + type: + - string + - "null" + updated_at: + type: + - number + - "null" + vendor_contact_id: + type: + - string + - "null" + viewed_date: + type: + - string + - "null" + is_amount_discount: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + last_sent_date: + type: + - string + - "null" + line_items: + type: + - array + - "null" + next_send_date: + type: + - string + - "null" + number: + type: + - string + - "null" + paid_to_date: + type: + - number + - "null" + partial: + type: + - number + - "null" + partial_due_date: + type: + - string + - "null" + po_number: + type: + - string + - "null" + private_notes: + type: + - string + - "null" + project_id: + type: + - string + - "null" + public_notes: + type: + - string + - "null" + reminder1_sent: + type: + - string + - "null" + reminder2_sent: + type: + - string + - "null" + reminder3_sent: + type: + - string + - "null" + reminder_last_sent: + type: + - string + - "null" + status_id: + type: + - string + - "null" + subscription_id: + type: + - string + - "null" + tax_info: + type: + - object + - "null" + tax_name1: + type: + - string + - "null" + tax_name2: + type: + - string + - "null" + tax_name3: + type: + - string + - "null" + tax_rate1: + type: + - number + - "null" + tax_rate2: + type: + - number + - "null" + tax_rate3: + type: + - number + - "null" + terms: + type: + - string + - "null" + total_taxes: + type: + - number + - "null" + updated_at: + type: + - number + - "null" + user_id: + type: + - string + - "null" + uses_inclusive_taxes: + type: + - boolean + - "null" + vendor_id: + type: + - string + - "null" + required: + - id + expenses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + amount: + type: + - number + - "null" + archived_at: + type: + - number + - "null" + assigned_user_id: + type: + - string + - "null" + bank_id: + type: + - string + - "null" + calculate_tax_by_amount: + type: + - boolean + - "null" + category_id: + type: + - string + - "null" + client_id: + type: + - string + - "null" + created_at: + type: + - number + - "null" + currency_id: + type: + - string + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + date: + type: + - string + - "null" + documents: + type: + - array + - "null" + e_invoice: + type: + - object + - "null" + entity_type: + type: + - string + - "null" + exchange_rate: + type: + - number + - "null" + expense_currency_id: + type: + - string + - "null" + foreign_amount: + type: + - number + - "null" + id: + type: string + invoice_currency_id: + type: + - string + - "null" + invoice_documents: + type: + - boolean + - "null" + invoice_id: + type: + - string + - "null" + is_deleted: + type: + - boolean + - "null" + number: + type: + - string + - "null" + payment_date: + type: + - string + - "null" + payment_type_id: + type: + - string + - "null" + private_notes: + type: + - string + - "null" + project_id: + type: + - string + - "null" + public_notes: + type: + - string + - "null" + recurring_expense_id: + type: + - string + - "null" + should_be_invoiced: + type: + - boolean + - "null" + tax_amount1: + type: + - number + - "null" + tax_amount2: + type: + - number + - "null" + tax_amount3: + type: + - number + - "null" + tax_name1: + type: + - string + - "null" + tax_name2: + type: + - string + - "null" + tax_name3: + type: + - string + - "null" + tax_rate1: + type: + - number + - "null" + tax_rate2: + type: + - number + - "null" + tax_rate3: + type: + - number + - "null" + transaction_id: + type: + - string + - "null" + transaction_reference: + type: + - string + - "null" + updated_at: + type: + - number + - "null" + user_id: + type: + - string + - "null" + uses_inclusive_taxes: + type: + - boolean + - "null" + vendor_id: + type: + - string + - "null" + required: + - id + recurring expenses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + amount: + type: + - number + - "null" + archived_at: + type: + - number + - "null" + assigned_user_id: + type: + - string + - "null" + bank_id: + type: + - string + - "null" + calculate_tax_by_amount: + type: + - boolean + - "null" + category_id: + type: + - string + - "null" + client_id: + type: + - string + - "null" + created_at: + type: + - number + - "null" + currency_id: + type: + - string + - "null" + custom_value1: + type: + - string + - "null" + custom_value2: + type: + - string + - "null" + custom_value3: + type: + - string + - "null" + custom_value4: + type: + - string + - "null" + date: + type: + - string + - "null" + documents: + type: + - array + - "null" + entity_type: + type: + - string + - "null" + exchange_rate: + type: + - number + - "null" + foreign_amount: + type: + - number + - "null" + frequency_id: + type: + - string + - "null" + id: + type: string + invoice_currency_id: + type: + - string + - "null" + invoice_documents: + type: + - boolean + - "null" + invoice_id: + type: + - string + - "null" + is_deleted: + type: + - boolean + - "null" + last_sent_date: + type: + - string + - "null" + next_send_date: + type: + - string + - "null" + number: + type: + - string + - "null" + payment_date: + type: + - string + - "null" + payment_type_id: + type: + - string + - "null" + private_notes: + type: + - string + - "null" + project_id: + type: + - string + - "null" + public_notes: + type: + - string + - "null" + recurring_dates: + type: + - array + - "null" + recurring_expense_currency_id: + type: + - string + - "null" + remaining_cycles: + type: + - number + - "null" + should_be_invoiced: + type: + - boolean + - "null" + status_id: + type: + - string + - "null" + tax_amount1: + type: + - number + - "null" + tax_amount2: + type: + - number + - "null" + tax_amount3: + type: + - number + - "null" + tax_name1: + type: + - string + - "null" + tax_name2: + type: + - string + - "null" + tax_name3: + type: + - string + - "null" + tax_rate1: + type: + - number + - "null" + tax_rate2: + type: + - number + - "null" + tax_rate3: + type: + - number + - "null" + transaction_id: + type: + - string + - "null" + transaction_reference: + type: + - string + - "null" + updated_at: + type: + - number + - "null" + user_id: + type: + - string + - "null" + uses_inclusive_taxes: + type: + - boolean + - "null" + vendor_id: + type: + - string + - "null" + required: + - id + bank transactions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + account_type: + type: + - string + - "null" + amount: + type: + - number + - "null" + archived_at: + type: + - number + - "null" + bank_account_id: + type: + - number + - "null" + bank_integration_id: + type: + - string + - "null" + bank_transaction_rule_id: + type: + - string + - "null" + base_type: + type: + - string + - "null" + category_id: + type: + - number + - "null" + category_type: + type: + - string + - "null" + created_at: + type: + - number + - "null" + currency_id: + type: + - string + - "null" + date: + type: + - string + - "null" + expense_id: + type: + - string + - "null" + id: + type: string + invoice_ids: + type: + - string + - "null" + is_deleted: + type: + - boolean + - "null" + ninja_category_id: + type: + - string + - "null" + nordigen_transaction_id: + type: + - string + - "null" + participant: + type: + - string + - "null" + participant_name: + type: + - string + - "null" + payment_id: + type: + - string + - "null" + status_id: + type: + - string + - "null" + transaction_id: + type: + - number + - "null" + updated_at: + type: + - number + - "null" + user_id: + type: + - string + - "null" + vendor_id: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-invoiceninja/metadata.yaml b/airbyte-integrations/connectors/source-invoiceninja/metadata.yaml new file mode 100644 index 000000000000..5c1eb2489ea2 --- /dev/null +++ b/airbyte-integrations/connectors/source-invoiceninja/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "invoicing.co" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-invoiceninja + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 7aa7e05d-6bba-463e-b635-cd3b96d40101 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-invoiceninja + githubIssueLabel: source-invoiceninja + icon: icon.svg + license: MIT + name: Invoiceninja + releaseDate: 2024-11-07 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/invoiceninja + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-ip2whois/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-ip2whois/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-ip2whois/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-ip2whois/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-ip2whois/metadata.yaml b/airbyte-integrations/connectors/source-ip2whois/metadata.yaml index e6ce35b2bbf4..2fe85b543090 100644 --- a/airbyte-integrations/connectors/source-ip2whois/metadata.yaml +++ b/airbyte-integrations/connectors/source-ip2whois/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: f23b7b7c-d705-49a3-9042-09add3b104a5 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-ip2whois documentationUrl: https://docs.airbyte.com/integrations/sources/ip2whois githubIssueLabel: source-ip2whois diff --git a/airbyte-integrations/connectors/source-iterable/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-iterable/integration_tests/acceptance.py index 51f9b12de27d..e023a7a92b30 100644 --- a/airbyte-integrations/connectors/source-iterable/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-iterable/integration_tests/acceptance.py @@ -4,6 +4,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-iterable/main.py b/airbyte-integrations/connectors/source-iterable/main.py index eef7d894cbc4..5b07bc8070e3 100644 --- a/airbyte-integrations/connectors/source-iterable/main.py +++ b/airbyte-integrations/connectors/source-iterable/main.py @@ -4,5 +4,6 @@ from source_iterable.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-iterable/metadata.yaml b/airbyte-integrations/connectors/source-iterable/metadata.yaml index 5ee3cd4149fb..c26816fe91b2 100644 --- a/airbyte-integrations/connectors/source-iterable/metadata.yaml +++ b/airbyte-integrations/connectors/source-iterable/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - api.iterable.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 2e875208-0c0b-4ee4-9e92-1cb3156ea799 - dockerImageTag: 0.6.17 + dockerImageTag: 0.6.23 dockerRepository: airbyte/source-iterable documentationUrl: https://docs.airbyte.com/integrations/sources/iterable githubIssueLabel: source-iterable diff --git a/airbyte-integrations/connectors/source-iterable/poetry.lock b/airbyte-integrations/connectors/source-iterable/poetry.lock index 7b8e55fff8f5..17b6b7ec2e06 100644 --- a/airbyte-integrations/connectors/source-iterable/poetry.lock +++ b/airbyte-integrations/connectors/source-iterable/poetry.lock @@ -67,41 +67,41 @@ files = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -167,13 +167,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -257,116 +257,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -436,20 +423,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -513,13 +500,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -534,13 +521,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -548,7 +535,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -598,13 +584,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -694,22 +680,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "linkify-it-py" version = "2.0.3" @@ -858,54 +847,54 @@ files = [ [[package]] name = "memray" -version = "1.14.0" +version = "1.15.0" description = "A memory profiler for Python applications" optional = false python-versions = ">=3.7.0" files = [ - {file = "memray-1.14.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:745d9014cb662065501441a7b534c29914fe2b68398b37385aba9f4a1c51c723"}, - {file = "memray-1.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f62a402ca1a7126f749544c3d6493672d6330ffd37d59ba230bc73e5143b3bc2"}, - {file = "memray-1.14.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:36840f39277b1871ecb5a9592dd1aa517a17b9f855f4e3ff08aa328a9d305e69"}, - {file = "memray-1.14.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3c7933ca70c0d59d0ce9b1064a6eda86231248759b46ed6dabedf489039d1aa1"}, - {file = "memray-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75a5907345ff845652e709ddce3171a9ba2d65c62e8bd49a99131066e2a7ce3b"}, - {file = "memray-1.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:88c89c3797834eec177a89ad528699c75b94e2ed08c00754141eae69c520b894"}, - {file = "memray-1.14.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:d6087f291fd68acdf0a833efb57bc0f192c98ae89b4377c690c28313e78d029c"}, - {file = "memray-1.14.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e6ba7bff9dfa37bf3b80a5b83b50eadf20afb1f0e8de4a0139019154086d6bed"}, - {file = "memray-1.14.0-cp311-cp311-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9bb0cfe1b755a860435cd52047b2e3f4f7b0c3887e0c1bf98da7127948284a91"}, - {file = "memray-1.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:638ba74e1735a40b6595fee7f37b426b9a95d244091a1f5df3dc5d98df1cbd4b"}, - {file = "memray-1.14.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7227ebf024cb0688a68ed91ed3e05c61a13751a9e875807195076b827bfde464"}, - {file = "memray-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:248dea8cfb5a615345e28b7e25c94377a8d198da3b6957ee443afa6f4ff1b733"}, - {file = "memray-1.14.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7d03f6be66aa259df7fa50082876fbe6461108d77d46c1f720c46067d60685d4"}, - {file = "memray-1.14.0-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:9af9d30b1e484fd8591c9a7f322fd50b9192a2bce660be92385a01555af9968b"}, - {file = "memray-1.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c4088b391c04796c888ac751b5d387f6e8212b3515d4c53ba540c65a6efe4bda"}, - {file = "memray-1.14.0-cp312-cp312-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:af8aee7e8e5cac1e4130f1184b3e03b6bb08264e4ba1696551791ed3f8fb824e"}, - {file = "memray-1.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4352f9e85957f2cbe45a9e1c87dfc19d2df77e93dcd8a558794a683eeee57b7b"}, - {file = "memray-1.14.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5953f0d2aa31b23d4cce20236a03d90b7c71903709a57b456d6494bfe6f470b7"}, - {file = "memray-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e4ccaca04365efcda51036fe2add980030e33cfc4f3a194a01f530a5c923c65"}, - {file = "memray-1.14.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f85a27eb8a65c810161bb992116a66d328546f78a4a4c7c1868949651b917c08"}, - {file = "memray-1.14.0-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:958d57f7149b8fa4831785394f2a7ace93dbc2be6c49a1c07987a8972986474a"}, - {file = "memray-1.14.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287a01953bc44dd0a32549a23bdacb5f9734e345ca289fa3923867c637715056"}, - {file = "memray-1.14.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfc17cba35d98e3d2ca20ab995f17eec3edba7138b062cbc1aa36d53d9d2d955"}, - {file = "memray-1.14.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c82342cead930ca50235f59740ca238808f9c33ef31d994712972966beb6226e"}, - {file = "memray-1.14.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a22a826b4047e839310514f4889c24e45a66ea222fca19ac0ae7b2f89bbb0281"}, - {file = "memray-1.14.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:344f3c73b97ffc8f1666b404deafbc31a19e6b2881341b706aa7ec20afb0e8b1"}, - {file = "memray-1.14.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a43455233d534e9c0e8dabe827d451124874a6455b2afcbcd60b823241ea5843"}, - {file = "memray-1.14.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e05a3b6bc82ef01821beaee98e86bd8de2ada06cb8781add9c40a3ae4a040383"}, - {file = "memray-1.14.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3bc27e5483c70236c9379b99277b4ea8fa4b3f73a99e37af81190649bd877881"}, - {file = "memray-1.14.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a7e5604448b2a78e329addfb099384515d3f973a03711c4e2a7b6c9f7f34f53"}, - {file = "memray-1.14.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:443885a96ab9f67d46288240e2593b5c3ecb2c507ddb4e3b10695e104403d001"}, - {file = "memray-1.14.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:52a45d96ed717d8efb645e99646a92dd21a2ca38bdb823fe22e38c429cba9513"}, - {file = "memray-1.14.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:72febec7b287667e8ea9ee3e879a4da19a4318bc47e211da815be74acd961994"}, - {file = "memray-1.14.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e07bdc3a4979b335c2b6b93a81b807d5aacd8dbbea56c41c6899a8bc0d2beb3"}, - {file = "memray-1.14.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b5e729d03caf426dc45a258270537a603794ecc067ccfd92f9c67ba9332e788"}, - {file = "memray-1.14.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:1d0a1397b5387b75dc9d9759beb022cb360948584840e850474d7d39ad267f85"}, - {file = "memray-1.14.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:c119b600e7c665e0713f09e25f9ee09733a98035688ecc1ec8fd168fa37a77f6"}, - {file = "memray-1.14.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:29a2e7d84d1652ef4664bcceb155630979b4797180b70da35525d963a4ca707f"}, - {file = "memray-1.14.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b3b8d46b6447cdecba3ba100d47c62e78cdad58b00b2d6ba004d6bad318c8668"}, - {file = "memray-1.14.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:57f9bf3f1c648f1ea877a84c21c449fdafd8cc105763ada6023e36bae9b45eb8"}, - {file = "memray-1.14.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b7a59346d242fc39041d87a71cb6cf45baf492ffbb69da9690de49346be64a8"}, - {file = "memray-1.14.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:11fb00105572b70f2aca8b787ce9748b0c94672fbb6334f1604f7f813ca3dca6"}, - {file = "memray-1.14.0.tar.gz", hash = "sha256:b5d8874b7b215551f0ae9fa8aef3f2f52321a6460dc0141aaf9374709e6b0eb7"}, + {file = "memray-1.15.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:9b623c0c651d611dd068236566a8a202250e3d59307c3a3f241acc47835e73eb"}, + {file = "memray-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74765f92887b7eed152e3b9f14c147c43bf0247417b18c7ea0dec173cd01633c"}, + {file = "memray-1.15.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a5c6be5f9c2280b5ba077cbfec4706f209f9c0c2cd3a53d949ab9f4ee1f6a255"}, + {file = "memray-1.15.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:68bdad519b644539440914e1f6a04995631d0e31311ebe0977d949f2125bb579"}, + {file = "memray-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4964c6bd555a0f1755dfdb97a8d9864e646054594449c66757441f7d7682405"}, + {file = "memray-1.15.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:92212b85c7d843126e4d343c8ca024f4a57537017b9ac7611864963b322aafae"}, + {file = "memray-1.15.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:cb8997e113378b9ac8bbd9b17f4f867fc5c1eea1980d873be3ebe4c2f1176784"}, + {file = "memray-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8ee45d919d81bfeb33677357dd5d248f3cad1d56be2ebd1853d4615a9f965b11"}, + {file = "memray-1.15.0-cp311-cp311-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a6b740aad69e7e5f82ffff53a8edef1313ff0b5e9b7253912da16e905dcb1dcb"}, + {file = "memray-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0045611f2da496e35d37a5ddfa2b6a74bbc82e47087924c07b3f520448297b26"}, + {file = "memray-1.15.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca5688e33a833de604d0e2de01b5bf11a4ac1d768998f8831a375a343dc7acaf"}, + {file = "memray-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bbad938c3fdcebe0cf3c568fb8f8633ab37ab08ad4db167e0991e214d6f595b"}, + {file = "memray-1.15.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4eb50295bd87a091a85ec71f0ee612c5d709df490fea8a3adc4410f5da4f695"}, + {file = "memray-1.15.0-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:d13554a25129593872b5fbcd55ac34453239e51d9b6ace258329596ccce22bb3"}, + {file = "memray-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8cfe15962a9002ede8b1f8b4f045d95855100a8a60a9bf0d9f2b92950f914189"}, + {file = "memray-1.15.0-cp312-cp312-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e84b39adca05e720bdbf950cc92ef4bafefa2d6160111e5fc427cf59c6c16d1a"}, + {file = "memray-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7745d2c58dfc33ef77f8827053cb957131420051b67e2d5642b605d0e65a586"}, + {file = "memray-1.15.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:412225d85db0ec22142a82646d85ecc1e8680d33adbfd15789c7eaa356ad4107"}, + {file = "memray-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d25ab7a7e32fedab46219121dfb6ec3e42c66984b217572fdd4cddc37359c521"}, + {file = "memray-1.15.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fb885f92833279d34addc607831352e91267b8e547ea861ad561a3dba64f6757"}, + {file = "memray-1.15.0-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:c1308e6a5fc5bc4e183bc0fdf5e241ddd9fb374338f32d77a4d5e74ccf611ef1"}, + {file = "memray-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0794227dfa4b86a56137211fd5b8ec131e0bc4a5dc41c2f5a318ca56a22c9331"}, + {file = "memray-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f184e82debd4f0c8ecf8e6034efddccdd9fac22909553a7f094eabf0902cd53f"}, + {file = "memray-1.15.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3493c5ac1ae1353fd0d24481bc9f30da8960ef703bf4af966cefff9dd1234d38"}, + {file = "memray-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:145a3062d8bf631aa8dc4b0928585e201282634afc369799dae1a0b9ece59fd4"}, + {file = "memray-1.15.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:59a4ade09cfe46e85cdb3a1976e9768e4674a6e448533c415dbe84e5a834f7c3"}, + {file = "memray-1.15.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:bb9870f41fe0c4cd4612fded51174f5b837f3bc6364c57b4a60e65016ccc1f7a"}, + {file = "memray-1.15.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:26cb3cac3810bbe9e701d40463c185cf9e7faac3965a0e2b309df1a9fc18cd9a"}, + {file = "memray-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:317287025cabd541f9fdec615b3c7ff394798113feea0edb92d31bc9f06eafd0"}, + {file = "memray-1.15.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:850eba1e3063d97172b0990a14f61782682baeb48f6ae039c0bb86b2f4d19b75"}, + {file = "memray-1.15.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:aa5150e3b58ba6184fac2a97426ee66f996dffe0571bbf09bffe23836318772e"}, + {file = "memray-1.15.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:753632eed43161131bb632799dc53b7ccb7e6341b8ca8ef4ad68ff8da81e766a"}, + {file = "memray-1.15.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:727190a81516e1955932c307ac6a55a3aedb5799bc2edf6a8fbf49852e851f0c"}, + {file = "memray-1.15.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:413b145445110900a99fb78b1fb6932c2e3ffadd35df5b258f8ac0a25e0aaf90"}, + {file = "memray-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2518a298ffa6c5a2ddfa6a36d196aa4aef5bb33c5d95a26565aac6a7f5fcb0c0"}, + {file = "memray-1.15.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae46cb726c4c06121614995b877365680f196fa4549698aa5026c494a40e1a24"}, + {file = "memray-1.15.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:ce28c6a4d89349c43d76ad35ff1c21057230086cfcf18c6f4c2305df108bf0cd"}, + {file = "memray-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:671c2fd8c835caad80c2023baf6cdc4326c0f6dd4ae8bf1d7dbf6ad700c13625"}, + {file = "memray-1.15.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8404f3969e071e35364fd99d238da8ef245cf7ee2c790f3d46cd5b41cbac0541"}, + {file = "memray-1.15.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a3e4c940deae29ea64d8dd4ffaee804f541a413c3c3c061a469837ed35d486b7"}, + {file = "memray-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36720d9ee97dee6cd51b230cbd2556cc3e0215c5a569b97c1faebc927ac3c505"}, + {file = "memray-1.15.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cba7727bfdee596f71323195af0262508ed0aec7ebbf67d98de0b959d9b8cf02"}, + {file = "memray-1.15.0.tar.gz", hash = "sha256:1beffa2bcba3dbe0f095d547927286eca46e272798b83026dd1b5db58e16ed56"}, ] [package.dependencies] @@ -915,76 +904,93 @@ textual = ">=0.41.0" [package.extras] benchmark = ["asv"] -dev = ["Cython", "asv", "black", "bump2version", "check-manifest", "flake8", "furo", "greenlet", "ipython", "isort", "mypy", "packaging", "pytest", "pytest-cov", "pytest-textual-snapshot", "setuptools", "sphinx", "sphinx-argparse", "textual (>=0.43,!=0.65.2,!=0.66)", "towncrier"] +dev = ["Cython", "IPython", "asv", "black", "bump2version", "check-manifest", "flake8", "furo", "greenlet", "ipython", "isort", "mypy", "packaging", "pytest", "pytest-cov", "pytest-textual-snapshot", "setuptools", "sphinx", "sphinx-argparse", "textual (>=0.43,!=0.65.2,!=0.66)", "towncrier"] docs = ["IPython", "bump2version", "furo", "sphinx", "sphinx-argparse", "towncrier"] lint = ["black", "check-manifest", "flake8", "isort", "mypy"] test = ["Cython", "greenlet", "ipython", "packaging", "pytest", "pytest-cov", "pytest-textual-snapshot", "setuptools", "textual (>=0.43,!=0.65.2,!=0.66)"] [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -1076,19 +1082,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1096,100 +1102,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -1211,13 +1228,13 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1543,13 +1560,13 @@ tests = ["coverage (>=6.0.0)", "flake8", "mypy", "pytest (>=7.0.0)", "pytest-asy [[package]] name = "rich" -version = "13.9.3" +version = "13.9.4" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.8.0" files = [ - {file = "rich-13.9.3-py3-none-any.whl", hash = "sha256:9836f5096eb2172c9e77df411c1b009bace4193d6a481d534fea75ebba758283"}, - {file = "rich-13.9.3.tar.gz", hash = "sha256:bc1e01b899537598cf02579d2b9f4a415104d3fc439313a7a2c165d76557a08e"}, + {file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"}, + {file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"}, ] [package.dependencies] @@ -1562,33 +1579,33 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1619,13 +1636,13 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "textual" -version = "0.85.1" +version = "1.0.0" description = "Modern Text User Interface framework" optional = false python-versions = "<4.0.0,>=3.8.1" files = [ - {file = "textual-0.85.1-py3-none-any.whl", hash = "sha256:a1a064c67b9b81cfa0c1b14298aa52221855aa4a56ad17a9b89a5594c73657a8"}, - {file = "textual-0.85.1.tar.gz", hash = "sha256:9966214390fad9a84c3f69d49398487897577f5fa788838106dd77bd7babc9cd"}, + {file = "textual-1.0.0-py3-none-any.whl", hash = "sha256:2d4a701781c05104925e463ae370c630567c70c2880e92ab838052e3e23c986f"}, + {file = "textual-1.0.0.tar.gz", hash = "sha256:bec9fe63547c1c552569d1b75d309038b7d456c03f86dfa3706ddb099b151399"}, ] [package.dependencies] @@ -1635,28 +1652,58 @@ rich = ">=13.3.3" typing-extensions = ">=4.4.0,<5.0.0" [package.extras] -syntax = ["tree-sitter (>=0.20.1,<0.21.0)", "tree-sitter-languages (==1.10.2)"] +syntax = ["tree-sitter (>=0.23.0)", "tree-sitter-bash (>=0.23.0)", "tree-sitter-css (>=0.23.0)", "tree-sitter-go (>=0.23.0)", "tree-sitter-html (>=0.23.0)", "tree-sitter-java (>=0.23.0)", "tree-sitter-javascript (>=0.23.0)", "tree-sitter-json (>=0.24.0)", "tree-sitter-markdown (>=0.3.0)", "tree-sitter-python (>=0.23.0)", "tree-sitter-regex (>=0.24.0)", "tree-sitter-rust (>=0.23.0)", "tree-sitter-sql (>=0.3.0)", "tree-sitter-toml (>=0.6.0)", "tree-sitter-xml (>=0.7.0)", "tree-sitter-yaml (>=0.6.0)"] [[package]] name = "tomli" -version = "2.0.2" +version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] [[package]] name = "types-pyyaml" -version = "6.0.12.20240917" +version = "6.0.12.20241230" description = "Typing stubs for PyYAML" optional = false python-versions = ">=3.8" files = [ - {file = "types-PyYAML-6.0.12.20240917.tar.gz", hash = "sha256:d1405a86f9576682234ef83bcb4e6fff7c9305c8b1fbad5e0bcd4f7dbdc9c587"}, - {file = "types_PyYAML-6.0.12.20240917-py3-none-any.whl", hash = "sha256:392b267f1c0fe6022952462bf5d6523f31e37f6cea49b14cee7ad634b6301570"}, + {file = "types_PyYAML-6.0.12.20241230-py3-none-any.whl", hash = "sha256:fa4d32565219b68e6dee5f67534c722e53c00d1cfc09c435ef04d7353e1e96e6"}, + {file = "types_pyyaml-6.0.12.20241230.tar.gz", hash = "sha256:7f07622dbd34bb9c8b264fe860a17e0efcad00d50b5f27e93984909d9363498c"}, ] [[package]] @@ -1700,13 +1747,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1731,81 +1778,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-iterable/pyproject.toml b/airbyte-integrations/connectors/source-iterable/pyproject.toml index 65e924848656..ecb2af7bec2e 100644 --- a/airbyte-integrations/connectors/source-iterable/pyproject.toml +++ b/airbyte-integrations/connectors/source-iterable/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.6.17" +version = "0.6.23" name = "source-iterable" description = "Source implementation for Iterable." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-iterable/source_iterable/components.py b/airbyte-integrations/connectors/source-iterable/source_iterable/components.py index 19d218fff055..71f216c5af37 100644 --- a/airbyte-integrations/connectors/source-iterable/source_iterable/components.py +++ b/airbyte-integrations/connectors/source-iterable/source_iterable/components.py @@ -6,6 +6,7 @@ from typing import Any, Iterable, Mapping import requests + from airbyte_cdk.sources.declarative.extractors.dpath_extractor import DpathExtractor diff --git a/airbyte-integrations/connectors/source-iterable/source_iterable/source.py b/airbyte-integrations/connectors/source-iterable/source_iterable/source.py index 83fa25aa174b..f1e78543b423 100644 --- a/airbyte-integrations/connectors/source-iterable/source_iterable/source.py +++ b/airbyte-integrations/connectors/source-iterable/source_iterable/source.py @@ -47,6 +47,7 @@ WebPushSendSkip, ) + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. @@ -54,6 +55,7 @@ WARNING: Do not modify this file. """ + # Declarative Source class SourceIterable(YamlDeclarativeSource): def __init__(self): diff --git a/airbyte-integrations/connectors/source-iterable/source_iterable/streams.py b/airbyte-integrations/connectors/source-iterable/source_iterable/streams.py index dae02ef017f3..b7e232e5ab56 100644 --- a/airbyte-integrations/connectors/source-iterable/source_iterable/streams.py +++ b/airbyte-integrations/connectors/source-iterable/source_iterable/streams.py @@ -10,18 +10,20 @@ import pendulum import requests +from pendulum.datetime import DateTime +from requests import HTTPError +from requests.exceptions import ChunkedEncodingError + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.streams.availability_strategy import AvailabilityStrategy from airbyte_cdk.sources.streams.core import CheckpointMixin, package_name_from_class from airbyte_cdk.sources.streams.http import HttpStream from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException, UserDefinedBackoffException from airbyte_cdk.sources.utils.schema_helpers import ResourceSchemaLoader -from pendulum.datetime import DateTime -from requests import HTTPError -from requests.exceptions import ChunkedEncodingError from source_iterable.slice_generators import AdjustableSliceGenerator, RangeSliceGenerator, StreamSlice from source_iterable.utils import dateutil_parse + EVENT_ROWS_LIMIT = 200 CAMPAIGNS_PER_REQUEST = 20 @@ -202,7 +204,6 @@ def request_params( stream_slice: StreamSlice, next_page_token: Mapping[str, Any] = None, ) -> MutableMapping[str, Any]: - params = super().request_params(stream_state=stream_state) params.update( { @@ -250,7 +251,6 @@ def stream_slices( cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None, ) -> Iterable[Optional[StreamSlice]]: - start_datetime = self.get_start_date(stream_state) return [StreamSlice(start_datetime, self._end_date or pendulum.now("UTC"))] @@ -268,7 +268,6 @@ def stream_slices( cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None, ) -> Iterable[Optional[StreamSlice]]: - start_datetime = self.get_start_date(stream_state) return RangeSliceGenerator(start_datetime, self._end_date) @@ -303,7 +302,6 @@ def stream_slices( cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None, ) -> Iterable[Optional[StreamSlice]]: - start_datetime = self.get_start_date(stream_state) self._adjustable_generator = AdjustableSliceGenerator(start_datetime, self._end_date) return self._adjustable_generator @@ -318,7 +316,6 @@ def read_records( start_time = pendulum.now() for _ in range(self.CHUNKED_ENCODING_ERROR_RETRIES): try: - self.logger.info( f"Processing slice of {(stream_slice.end_date - stream_slice.start_date).total_days()} days for stream {self.name}" ) diff --git a/airbyte-integrations/connectors/source-iterable/unit_tests/conftest.py b/airbyte-integrations/connectors/source-iterable/unit_tests/conftest.py index 0210920dea23..f9053d5b44ad 100644 --- a/airbyte-integrations/connectors/source-iterable/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-iterable/unit_tests/conftest.py @@ -7,6 +7,7 @@ import pytest import responses + from airbyte_cdk.models import AirbyteStream, ConfiguredAirbyteCatalog, ConfiguredAirbyteStream diff --git a/airbyte-integrations/connectors/source-iterable/unit_tests/test_export_adjustable_range.py b/airbyte-integrations/connectors/source-iterable/unit_tests/test_export_adjustable_range.py index 90bd5b6ab286..3e54136178d5 100644 --- a/airbyte-integrations/connectors/source-iterable/unit_tests/test_export_adjustable_range.py +++ b/airbyte-integrations/connectors/source-iterable/unit_tests/test_export_adjustable_range.py @@ -12,11 +12,13 @@ import pendulum import pytest import responses -from airbyte_cdk.models import Type as MessageType from requests.exceptions import ChunkedEncodingError from source_iterable.slice_generators import AdjustableSliceGenerator from source_iterable.source import SourceIterable +from airbyte_cdk.models import Type as MessageType + + TEST_START_DATE = "2020" diff --git a/airbyte-integrations/connectors/source-iterable/unit_tests/test_exports_stream.py b/airbyte-integrations/connectors/source-iterable/unit_tests/test_exports_stream.py index 0353d32c22b3..15bdab16414d 100644 --- a/airbyte-integrations/connectors/source-iterable/unit_tests/test_exports_stream.py +++ b/airbyte-integrations/connectors/source-iterable/unit_tests/test_exports_stream.py @@ -8,9 +8,10 @@ import pendulum import pytest import responses +from source_iterable.source import SourceIterable + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.declarative.types import StreamSlice -from source_iterable.source import SourceIterable @pytest.fixture diff --git a/airbyte-integrations/connectors/source-iterable/unit_tests/test_extractors.py b/airbyte-integrations/connectors/source-iterable/unit_tests/test_extractors.py index 661e898d15de..09a49584e23a 100644 --- a/airbyte-integrations/connectors/source-iterable/unit_tests/test_extractors.py +++ b/airbyte-integrations/connectors/source-iterable/unit_tests/test_extractors.py @@ -4,9 +4,10 @@ import io import requests -from airbyte_cdk.sources.declarative.decoders.json_decoder import JsonlDecoder from source_iterable.components import EventsRecordExtractor +from airbyte_cdk.sources.declarative.decoders.json_decoder import JsonlDecoder + def test_events_extraction(): mock_response = requests.Response() diff --git a/airbyte-integrations/connectors/source-iterable/unit_tests/test_slice_generator.py b/airbyte-integrations/connectors/source-iterable/unit_tests/test_slice_generator.py index 5c4bcf85a4e9..ff5890eb4030 100644 --- a/airbyte-integrations/connectors/source-iterable/unit_tests/test_slice_generator.py +++ b/airbyte-integrations/connectors/source-iterable/unit_tests/test_slice_generator.py @@ -9,6 +9,7 @@ import pytest from source_iterable.slice_generators import AdjustableSliceGenerator, RangeSliceGenerator + TEST_DATE = pendulum.parse("2020-01-01") diff --git a/airbyte-integrations/connectors/source-iterable/unit_tests/test_stream_events.py b/airbyte-integrations/connectors/source-iterable/unit_tests/test_stream_events.py index e7ed3e0f75ca..0c44168c77cb 100644 --- a/airbyte-integrations/connectors/source-iterable/unit_tests/test_stream_events.py +++ b/airbyte-integrations/connectors/source-iterable/unit_tests/test_stream_events.py @@ -7,9 +7,10 @@ import pytest import requests import responses +from source_iterable.source import SourceIterable + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.declarative.types import StreamSlice -from source_iterable.source import SourceIterable @responses.activate diff --git a/airbyte-integrations/connectors/source-iterable/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-iterable/unit_tests/test_streams.py index 1c4d2347ba3d..4342e91af6b9 100644 --- a/airbyte-integrations/connectors/source-iterable/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-iterable/unit_tests/test_streams.py @@ -6,13 +6,14 @@ import pytest import requests import responses -from airbyte_cdk import AirbyteTracedException -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.declarative.types import StreamSlice from source_iterable.source import SourceIterable from source_iterable.streams import Campaigns, CampaignsMetrics, Templates from source_iterable.utils import dateutil_parse +from airbyte_cdk import AirbyteTracedException +from airbyte_cdk.models import SyncMode +from airbyte_cdk.sources.declarative.types import StreamSlice + def test_campaigns_metrics_csv(): csv_string = "a,b,c,d\n1, 2,,3\n6,,1, 2\n" @@ -190,7 +191,6 @@ def test_path(config, stream, date, slice, expected_path): def test_campaigns_metrics_parse_response(): - stream = CampaignsMetrics(authenticator=None, start_date="2019-10-10T00:00:00") with responses.RequestsMock() as rsps: rsps.add( diff --git a/airbyte-integrations/connectors/source-jina-ai-reader/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-jina-ai-reader/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-jina-ai-reader/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-jina-ai-reader/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-jina-ai-reader/main.py b/airbyte-integrations/connectors/source-jina-ai-reader/main.py index 33085d47ebf9..58af77ac1dd2 100644 --- a/airbyte-integrations/connectors/source-jina-ai-reader/main.py +++ b/airbyte-integrations/connectors/source-jina-ai-reader/main.py @@ -5,5 +5,6 @@ from source_jina_ai_reader.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-jina-ai-reader/metadata.yaml b/airbyte-integrations/connectors/source-jina-ai-reader/metadata.yaml index 08cb01915223..9ca931ea20e6 100644 --- a/airbyte-integrations/connectors/source-jina-ai-reader/metadata.yaml +++ b/airbyte-integrations/connectors/source-jina-ai-reader/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: true packageName: airbyte-source-jina-ai-reader connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 47077a7f-7ab0-47ee-b428-650396a708c7 - dockerImageTag: 0.1.20 + dockerImageTag: 0.1.26 dockerRepository: airbyte/source-jina-ai-reader githubIssueLabel: source-jina-ai-reader icon: jina-ai-reader.svg diff --git a/airbyte-integrations/connectors/source-jina-ai-reader/poetry.lock b/airbyte-integrations/connectors/source-jina-ai-reader/poetry.lock index 02302faf1ed9..c17ef8903eca 100644 --- a/airbyte-integrations/connectors/source-jina-ai-reader/poetry.lock +++ b/airbyte-integrations/connectors/source-jina-ai-reader/poetry.lock @@ -42,13 +42,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] @@ -56,41 +56,41 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -156,13 +156,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -246,116 +246,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -425,20 +412,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -488,13 +475,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -509,13 +496,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -523,7 +510,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -573,13 +559,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -669,22 +655,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -757,69 +746,86 @@ files = [ [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -911,54 +917,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -970,13 +976,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1043,13 +1049,13 @@ files = [ [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] @@ -1262,33 +1268,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1319,13 +1325,43 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "tomli" -version = "2.0.2" +version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] [[package]] @@ -1355,13 +1391,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1386,81 +1422,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-jina-ai-reader/pyproject.toml b/airbyte-integrations/connectors/source-jina-ai-reader/pyproject.toml index eec6162224be..22bfba1c4d48 100644 --- a/airbyte-integrations/connectors/source-jina-ai-reader/pyproject.toml +++ b/airbyte-integrations/connectors/source-jina-ai-reader/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.20" +version = "0.1.26" name = "source-jina-ai-reader" description = "Source implementation for jina-ai-reader." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-jina-ai-reader/source_jina_ai_reader/config_migration.py b/airbyte-integrations/connectors/source-jina-ai-reader/source_jina_ai_reader/config_migration.py index 7604776518b5..ba509deaa9ed 100644 --- a/airbyte-integrations/connectors/source-jina-ai-reader/source_jina_ai_reader/config_migration.py +++ b/airbyte-integrations/connectors/source-jina-ai-reader/source_jina_ai_reader/config_migration.py @@ -12,6 +12,7 @@ from airbyte_cdk.sources import Source from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-jina-ai-reader/source_jina_ai_reader/source.py b/airbyte-integrations/connectors/source-jina-ai-reader/source_jina_ai_reader/source.py index bf73db8f9ed6..392ff158b075 100644 --- a/airbyte-integrations/connectors/source-jina-ai-reader/source_jina_ai_reader/source.py +++ b/airbyte-integrations/connectors/source-jina-ai-reader/source_jina_ai_reader/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-jina-ai-reader/unit_tests/test_config_migrations.py b/airbyte-integrations/connectors/source-jina-ai-reader/unit_tests/test_config_migrations.py index 2edcb5eb27c7..9825027db046 100644 --- a/airbyte-integrations/connectors/source-jina-ai-reader/unit_tests/test_config_migrations.py +++ b/airbyte-integrations/connectors/source-jina-ai-reader/unit_tests/test_config_migrations.py @@ -5,6 +5,7 @@ from source_jina_ai_reader.config_migration import JinaAiReaderConfigMigration from source_jina_ai_reader.source import SourceJinaAiReader + TEST_CONFIG_PATH = f"{os.path.dirname(__file__)}/test_config.json" @@ -16,7 +17,7 @@ def test_should_migrate(): def test__modify_and_save(): source = SourceJinaAiReader() user_config = {"search_prompt": "What is AI"} - expected = {"search_prompt": "What%20is%20AI" } + expected = {"search_prompt": "What%20is%20AI"} modified_config = JinaAiReaderConfigMigration.modify_and_save(config_path=TEST_CONFIG_PATH, source=source, config=user_config) assert modified_config["search_prompt"] == expected["search_prompt"] assert modified_config.get("search_prompt") diff --git a/airbyte-integrations/connectors/source-jira/.coveragerc b/airbyte-integrations/connectors/source-jira/.coveragerc new file mode 100644 index 000000000000..561f740781bc --- /dev/null +++ b/airbyte-integrations/connectors/source-jira/.coveragerc @@ -0,0 +1,3 @@ +[run] +omit = + source_jira/run.py \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-jira/acceptance-test-config.yml b/airbyte-integrations/connectors/source-jira/acceptance-test-config.yml index 0fd75e938c9e..e3d102cac238 100644 --- a/airbyte-integrations/connectors/source-jira/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-jira/acceptance-test-config.yml @@ -32,7 +32,7 @@ acceptance_tests: - config_path: "secrets/config.json" configured_catalog_path: "integration_tests/configured_catalog.json" future_state: - future_state_path: "integration_tests/abnormal_state.json" + bypass_reason: "This test does not make sense using Concurrent CDK" full_refresh: tests: - config_path: "secrets/config.json" diff --git a/airbyte-integrations/connectors/source-jira/integration_tests/abnormal_state.json b/airbyte-integrations/connectors/source-jira/integration_tests/abnormal_state.json index 9dc1716efb6b..43bce095a999 100644 --- a/airbyte-integrations/connectors/source-jira/integration_tests/abnormal_state.json +++ b/airbyte-integrations/connectors/source-jira/integration_tests/abnormal_state.json @@ -93,11 +93,357 @@ "namespace": null }, "stream_state": { - "updated": "2222-05-08T03:04:45.056-0700" + "states": [ + { + "partition": { + "issue_id": "10063", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:39:56.480-0700" + } + }, + { + "partition": { + "issue_id": "10055", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:03.372-0700" + } + }, + { + "partition": { + "issue_id": "10069", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:39:52.625-0700" + } + }, + { + "partition": { + "issue_id": "10000", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:29.651-0700" + } + }, + { + "partition": { + "issue_id": "10001", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:26.631-0700" + } + }, + { + "partition": { + "issue_id": "10019", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:15.339-0700" + } + }, + { + "partition": { + "issue_id": "10007", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:25.984-0700" + } + }, + { + "partition": { + "issue_id": "10008", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:22.939-0700" + } + }, + { + "partition": { + "issue_id": "10017", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:16.658-0700" + } + }, + { + "partition": { + "issue_id": "10013", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:17.282-0700" + } + }, + { + "partition": { + "issue_id": "10024", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:13.547-0700" + } + }, + { + "partition": { + "issue_id": "10029", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:11.701-0700" + } + }, + { + "partition": { + "issue_id": "10037", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:08.524-0700" + } + }, + { + "partition": { + "issue_id": "10042", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:07.295-0700" + } + }, + { + "partition": { + "issue_id": "10043", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:06.582-0700" + } + }, + { + "partition": { + "issue_id": "10051", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:05.967-0700" + } + }, + { + "partition": { + "issue_id": "10061", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:01.993-0700" + } + }, + { + "partition": { + "issue_id": "10062", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:39:58.707-0700" + } + }, + { + "partition": { + "issue_id": "10065", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:39:55.810-0700" + } + }, + { + "partition": { + "issue_id": "10080", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:39:47.834-0700" + } + }, + { + "partition": { + "issue_id": "10021", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:14.775-0700" + } + }, + { + "partition": { + "issue_id": "10009", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:19.832-0700" + } + }, + { + "partition": { + "issue_id": "10012", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:40:18.557-0700" + } + }, + { + "partition": { + "issue_id": "10626", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-05T05:08:50.033-0700" + } + }, + { + "partition": { + "issue_id": "10075", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T11:39:50.205-0700" + } + }, + { + "partition": { + "issue_id": "10632", + "parent_slice": { + "parent_slice": {}, + "project_id": "10064" + } + }, + "cursor": { + "updated": "2222-05-08T03:04:45.056-0700" + } + } + ], + "parent_state": { + "issues": { + "states": [ + { + "partition": { + "parent_slice": {}, + "project_id": "10000" + }, + "cursor": { + "updated": "2222-10-12T13:43:50.735-0700" + } + }, + { + "partition": { + "parent_slice": {}, + "project_id": "10016" + }, + "cursor": { + "updated": "2222-07-05T12:57:51.258-0700" + } + }, + { + "partition": { + "parent_slice": {}, + "project_id": "10064" + }, + "cursor": { + "updated": "2222-05-08T03:04:45.139-0700" + } + } + ] + } + } } }, "sourceStats": { - "recordCount": 21.0 + "recordCount": 1.0 } }, { @@ -108,11 +454,297 @@ "namespace": null }, "stream_state": { - "updated": "2222-12-08T06:32:22.567-0800" + "states": [ + { + "partition": { + "issue_id": "10063", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-14T14:32:45.445-0700" + } + }, + { + "partition": { + "issue_id": "10055", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-14T14:32:48.961-0700" + } + }, + { + "partition": { + "issue_id": "10069", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T00:08:58.704-0700" + } + }, + { + "partition": { + "issue_id": "10625", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-05-17T04:06:55.076-0700" + } + }, + { + "partition": { + "issue_id": "10001", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T00:09:35.737-0700" + } + }, + { + "partition": { + "issue_id": "10019", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T00:09:14.283-0700" + } + }, + { + "partition": { + "issue_id": "10007", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-14T14:32:58.858-0700" + } + }, + { + "partition": { + "issue_id": "10008", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T00:09:34.423-0700" + } + }, + { + "partition": { + "issue_id": "10013", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T00:09:18.960-0700" + } + }, + { + "partition": { + "issue_id": "10024", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T00:09:10.916-0700" + } + }, + { + "partition": { + "issue_id": "10029", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-14T14:32:53.076-0700" + } + }, + { + "partition": { + "issue_id": "10037", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-14T14:32:51.879-0700" + } + }, + { + "partition": { + "issue_id": "10042", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-14T14:32:50.783-0700" + } + }, + { + "partition": { + "issue_id": "10043", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T00:09:10.146-0700" + } + }, + { + "partition": { + "issue_id": "10051", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-12-08T06:32:22.567-0800" + } + }, + { + "partition": { + "issue_id": "10062", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T00:09:02.883-0700" + } + }, + { + "partition": { + "issue_id": "10065", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-14T14:32:44.898-0700" + } + }, + { + "partition": { + "issue_id": "10021", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-14T14:32:53.670-0700" + } + }, + { + "partition": { + "issue_id": "10009", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T00:09:29.256-0700" + } + }, + { + "partition": { + "issue_id": "10012", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T00:09:23.970-0700" + } + }, + { + "partition": { + "issue_id": "10075", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2222-04-15T00:08:53.824-0700" + } + } + ], + "parent_state": { + "issues": { + "states": [ + { + "partition": { + "parent_slice": {}, + "project_id": "10000" + }, + "cursor": { + "updated": "2222-10-12T13:43:50.735-0700" + } + }, + { + "partition": { + "parent_slice": {}, + "project_id": "10016" + }, + "cursor": { + "updated": "2222-07-05T12:57:51.258-0700" + } + }, + { + "partition": { + "parent_slice": {}, + "project_id": "10064" + }, + "cursor": { + "updated": "2222-05-08T03:04:45.139-0700" + } + } + ] + } + } } }, "sourceStats": { - "recordCount": 2.0 + "recordCount": 0.0 } }, { diff --git a/airbyte-integrations/connectors/source-jira/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-jira/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-jira/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-jira/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-jira/integration_tests/fixtures/data_generator/generator.py b/airbyte-integrations/connectors/source-jira/integration_tests/fixtures/data_generator/generator.py index e4e2e8337782..fb8a0c348a1d 100644 --- a/airbyte-integrations/connectors/source-jira/integration_tests/fixtures/data_generator/generator.py +++ b/airbyte-integrations/connectors/source-jira/integration_tests/fixtures/data_generator/generator.py @@ -7,7 +7,6 @@ from base64 import b64encode from typing import Any, List, Mapping -from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator from streams import ( DashboardsGenerator, FiltersGenerator, @@ -29,6 +28,8 @@ WorkflowsGenerator, ) +from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator + class Generator: base_config_path = "secrets/config.json" diff --git a/airbyte-integrations/connectors/source-jira/integration_tests/fixtures/data_generator/streams.py b/airbyte-integrations/connectors/source-jira/integration_tests/fixtures/data_generator/streams.py index 5a295903035b..365af929548f 100644 --- a/airbyte-integrations/connectors/source-jira/integration_tests/fixtures/data_generator/streams.py +++ b/airbyte-integrations/connectors/source-jira/integration_tests/fixtures/data_generator/streams.py @@ -8,7 +8,6 @@ from typing import Any, Mapping, Optional import requests -from airbyte_cdk.models import SyncMode from source_jira.streams import ( Dashboards, Filters, @@ -31,6 +30,8 @@ WorkflowSchemes, ) +from airbyte_cdk.models import SyncMode + class GeneratorMixin: def get_generate_headers(self): diff --git a/airbyte-integrations/connectors/source-jira/integration_tests/sample_state.json b/airbyte-integrations/connectors/source-jira/integration_tests/sample_state.json index 7de4731a49d6..4200e8df37c7 100644 --- a/airbyte-integrations/connectors/source-jira/integration_tests/sample_state.json +++ b/airbyte-integrations/connectors/source-jira/integration_tests/sample_state.json @@ -93,11 +93,357 @@ "namespace": null }, "stream_state": { - "updated": "2023-05-08T03:04:45.056-0700" + "states": [ + { + "partition": { + "issue_id": "10063", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:39:56.480-0700" + } + }, + { + "partition": { + "issue_id": "10055", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:03.372-0700" + } + }, + { + "partition": { + "issue_id": "10069", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:39:52.625-0700" + } + }, + { + "partition": { + "issue_id": "10000", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:29.651-0700" + } + }, + { + "partition": { + "issue_id": "10001", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:26.631-0700" + } + }, + { + "partition": { + "issue_id": "10019", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:15.339-0700" + } + }, + { + "partition": { + "issue_id": "10007", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:25.984-0700" + } + }, + { + "partition": { + "issue_id": "10008", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:22.939-0700" + } + }, + { + "partition": { + "issue_id": "10017", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:16.658-0700" + } + }, + { + "partition": { + "issue_id": "10013", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:17.282-0700" + } + }, + { + "partition": { + "issue_id": "10024", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:13.547-0700" + } + }, + { + "partition": { + "issue_id": "10029", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:11.701-0700" + } + }, + { + "partition": { + "issue_id": "10037", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:08.524-0700" + } + }, + { + "partition": { + "issue_id": "10042", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:07.295-0700" + } + }, + { + "partition": { + "issue_id": "10043", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:06.582-0700" + } + }, + { + "partition": { + "issue_id": "10051", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:05.967-0700" + } + }, + { + "partition": { + "issue_id": "10061", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:01.993-0700" + } + }, + { + "partition": { + "issue_id": "10062", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:39:58.707-0700" + } + }, + { + "partition": { + "issue_id": "10065", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:39:55.810-0700" + } + }, + { + "partition": { + "issue_id": "10080", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:39:47.834-0700" + } + }, + { + "partition": { + "issue_id": "10021", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:14.775-0700" + } + }, + { + "partition": { + "issue_id": "10009", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:19.832-0700" + } + }, + { + "partition": { + "issue_id": "10012", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:40:18.557-0700" + } + }, + { + "partition": { + "issue_id": "10626", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2023-04-05T05:08:50.033-0700" + } + }, + { + "partition": { + "issue_id": "10075", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T11:39:50.205-0700" + } + }, + { + "partition": { + "issue_id": "10632", + "parent_slice": { + "parent_slice": {}, + "project_id": "10064" + } + }, + "cursor": { + "updated": "2023-05-08T03:04:45.056-0700" + } + } + ], + "parent_state": { + "issues": { + "states": [ + { + "partition": { + "parent_slice": {}, + "project_id": "10000" + }, + "cursor": { + "updated": "2023-10-12T13:43:50.735-0700" + } + }, + { + "partition": { + "parent_slice": {}, + "project_id": "10016" + }, + "cursor": { + "updated": "2023-07-05T12:57:51.258-0700" + } + }, + { + "partition": { + "parent_slice": {}, + "project_id": "10064" + }, + "cursor": { + "updated": "2023-05-08T03:04:45.139-0700" + } + } + ] + } + } } }, "sourceStats": { - "recordCount": 21.0 + "recordCount": 1.0 } }, { @@ -108,11 +454,297 @@ "namespace": null }, "stream_state": { - "updated": "2022-12-08T06:32:22.567-0800" + "states": [ + { + "partition": { + "issue_id": "10063", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-14T14:32:45.445-0700" + } + }, + { + "partition": { + "issue_id": "10055", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-14T14:32:48.961-0700" + } + }, + { + "partition": { + "issue_id": "10069", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T00:08:58.704-0700" + } + }, + { + "partition": { + "issue_id": "10625", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2022-05-17T04:06:55.076-0700" + } + }, + { + "partition": { + "issue_id": "10001", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T00:09:35.737-0700" + } + }, + { + "partition": { + "issue_id": "10019", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T00:09:14.283-0700" + } + }, + { + "partition": { + "issue_id": "10007", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-14T14:32:58.858-0700" + } + }, + { + "partition": { + "issue_id": "10008", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T00:09:34.423-0700" + } + }, + { + "partition": { + "issue_id": "10013", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T00:09:18.960-0700" + } + }, + { + "partition": { + "issue_id": "10024", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T00:09:10.916-0700" + } + }, + { + "partition": { + "issue_id": "10029", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-14T14:32:53.076-0700" + } + }, + { + "partition": { + "issue_id": "10037", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-14T14:32:51.879-0700" + } + }, + { + "partition": { + "issue_id": "10042", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-14T14:32:50.783-0700" + } + }, + { + "partition": { + "issue_id": "10043", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T00:09:10.146-0700" + } + }, + { + "partition": { + "issue_id": "10051", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2022-12-08T06:32:22.567-0800" + } + }, + { + "partition": { + "issue_id": "10062", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T00:09:02.883-0700" + } + }, + { + "partition": { + "issue_id": "10065", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-14T14:32:44.898-0700" + } + }, + { + "partition": { + "issue_id": "10021", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-14T14:32:53.670-0700" + } + }, + { + "partition": { + "issue_id": "10009", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T00:09:29.256-0700" + } + }, + { + "partition": { + "issue_id": "10012", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T00:09:23.970-0700" + } + }, + { + "partition": { + "issue_id": "10075", + "parent_slice": { + "parent_slice": {}, + "project_id": "10000" + } + }, + "cursor": { + "updated": "2021-04-15T00:08:53.824-0700" + } + } + ], + "parent_state": { + "issues": { + "states": [ + { + "partition": { + "parent_slice": {}, + "project_id": "10000" + }, + "cursor": { + "updated": "2023-10-12T13:43:50.735-0700" + } + }, + { + "partition": { + "parent_slice": {}, + "project_id": "10016" + }, + "cursor": { + "updated": "2023-07-05T12:57:51.258-0700" + } + }, + { + "partition": { + "parent_slice": {}, + "project_id": "10064" + }, + "cursor": { + "updated": "2023-05-08T03:04:45.139-0700" + } + } + ] + } + } } }, "sourceStats": { - "recordCount": 2.0 + "recordCount": 0.0 } }, { diff --git a/airbyte-integrations/connectors/source-jira/main.py b/airbyte-integrations/connectors/source-jira/main.py index 1885b3974def..528d513d7488 100644 --- a/airbyte-integrations/connectors/source-jira/main.py +++ b/airbyte-integrations/connectors/source-jira/main.py @@ -4,5 +4,6 @@ from source_jira.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-jira/metadata.yaml b/airbyte-integrations/connectors/source-jira/metadata.yaml index 7e9194dee3a4..6542ef977d3d 100644 --- a/airbyte-integrations/connectors/source-jira/metadata.yaml +++ b/airbyte-integrations/connectors/source-jira/metadata.yaml @@ -6,18 +6,18 @@ data: hosts: - ${domain} connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 68e63de2-bb83-4c7e-93fa-a8a9051e3993 - dockerImageTag: 3.2.1 + dockerImageTag: 3.4.7 dockerRepository: airbyte/source-jira documentationUrl: https://docs.airbyte.com/integrations/sources/jira erdUrl: https://dbdocs.io/airbyteio/source-jira?view=relationships githubIssueLabel: source-jira icon: jira.svg license: MIT - maxSecondsBetweenMessages: 5400 + maxSecondsBetweenMessages: 10800 name: Jira remoteRegistries: pypi: diff --git a/airbyte-integrations/connectors/source-jira/poetry.lock b/airbyte-integrations/connectors/source-jira/poetry.lock index 7efe81b83ad7..81eb0dd4b297 100644 --- a/airbyte-integrations/connectors/source-jira/poetry.lock +++ b/airbyte-integrations/connectors/source-jira/poetry.lock @@ -2,58 +2,63 @@ [[package]] name = "airbyte-cdk" -version = "5.13.0" +version = "6.12.4" description = "A framework for writing Airbyte Connectors." optional = false -python-versions = "<4.0,>=3.10" +python-versions = "<3.13,>=3.10" files = [ - {file = "airbyte_cdk-5.13.0-py3-none-any.whl", hash = "sha256:b26c99631e797c0bdb8373a6a05c81bf62b7d7397ca41b6ee05702d1013bd389"}, - {file = "airbyte_cdk-5.13.0.tar.gz", hash = "sha256:ab5799a238366dff61a8cded347b02deb63818513af4e61e2d1a51608a2280df"}, + {file = "airbyte_cdk-6.12.4-py3-none-any.whl", hash = "sha256:903f2c2d3be4d6595bc6c50a4625e2551308d2ca90e021bf489e0a82cf0f965d"}, + {file = "airbyte_cdk-6.12.4.tar.gz", hash = "sha256:f9f39746dec5e01a9d37255cfb45a753953227b7aafebf8f5603a6e9f943b182"}, ] [package.dependencies] -airbyte-protocol-models-dataclasses = ">=0.13,<0.14" +airbyte-protocol-models-dataclasses = ">=0.14,<0.15" backoff = "*" cachetools = "*" -cryptography = ">=42.0.5,<43.0.0" -Deprecated = ">=1.2,<1.3" +cryptography = ">=42.0.5,<44.0.0" dpath = ">=2.1.6,<3.0.0" -genson = "1.2.2" +dunamai = ">=1.22.0,<2.0.0" +genson = "1.3.0" isodate = ">=0.6.1,<0.7.0" Jinja2 = ">=3.1.2,<3.2.0" jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" +jsonschema = ">=4.17.3,<4.18.0" langchain_core = "0.1.42" -nltk = "3.8.1" +nltk = "3.9.1" +numpy = "<2" orjson = ">=3.10.7,<4.0.0" pandas = "2.2.2" pendulum = "<3.0.0" +psutil = "6.1.0" pydantic = ">=2.7,<3.0" pyjwt = ">=2.8.0,<3.0.0" pyrate-limiter = ">=3.1.0,<3.2.0" python-dateutil = "*" -pytz = "2024.1" +python-ulid = ">=3.0.0,<4.0.0" +pytz = "2024.2" PyYAML = ">=6.0.1,<7.0.0" +rapidfuzz = ">=3.10.1,<4.0.0" requests = "*" requests_cache = "*" serpyco-rs = ">=1.10.2,<2.0.0" -wcmatch = "8.4" +Unidecode = ">=1.3,<2.0" +wcmatch = "10.0" xmltodict = ">=0.13.0,<0.14.0" [package.extras] file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "python-snappy (==0.7.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] +sql = ["sqlalchemy (>=2.0,!=2.0.36,<3.0)"] +vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.8.0)"] [[package]] name = "airbyte-protocol-models-dataclasses" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models_dataclasses-0.13.0-py3-none-any.whl", hash = "sha256:0aedb99ffc4f9aab0ce91bba2c292fa17cd8fd4b42eeba196d6a16c20bbbd7a5"}, - {file = "airbyte_protocol_models_dataclasses-0.13.0.tar.gz", hash = "sha256:72e67850d661e2808406aec5839b3158ebb94d3553b798dbdae1b4a278548d2f"}, + {file = "airbyte_protocol_models_dataclasses-0.14.1-py3-none-any.whl", hash = "sha256:dfe10b32ee09e6ba9b4f17bd309e841b61cbd61ec8f80b1937ff104efd6209a9"}, + {file = "airbyte_protocol_models_dataclasses-0.14.1.tar.gz", hash = "sha256:f62a46556b82ea0d55de144983141639e8049d836dd4e0a9d7234c5b2e103c08"}, ] [[package]] @@ -69,24 +74,24 @@ files = [ [[package]] name = "anyio" -version = "4.6.0" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.0-py3-none-any.whl", hash = "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a"}, - {file = "anyio-4.6.0.tar.gz", hash = "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -112,19 +117,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -190,13 +195,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -280,127 +285,114 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -419,43 +411,38 @@ files = [ [[package]] name = "cryptography" -version = "42.0.8" +version = "43.0.3" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, + {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, + {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, + {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, + {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, + {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, + {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, + {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, ] [package.dependencies] @@ -468,26 +455,9 @@ nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] -[[package]] -name = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - [[package]] name = "dpath" version = "2.2.0" @@ -499,6 +469,20 @@ files = [ {file = "dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e"}, ] +[[package]] +name = "dunamai" +version = "1.23.0" +description = "Dynamic version generation" +optional = false +python-versions = ">=3.5" +files = [ + {file = "dunamai-1.23.0-py3-none-any.whl", hash = "sha256:a0906d876e92441793c6a423e16a4802752e723e9c9a5aabdc5535df02dbe041"}, + {file = "dunamai-1.23.0.tar.gz", hash = "sha256:a163746de7ea5acb6dacdab3a6ad621ebc612ed1e528aaa8beedb8887fccd2c4"}, +] + +[package.dependencies] +packaging = ">=20.9" + [[package]] name = "exceptiongroup" version = "1.2.2" @@ -514,13 +498,28 @@ files = [ test = ["pytest (>=6)"] [[package]] -name = "genson" +name = "freezegun" version = "1.2.2" +description = "Let your Python tests travel through time" +optional = false +python-versions = ">=3.6" +files = [ + {file = "freezegun-1.2.2-py3-none-any.whl", hash = "sha256:ea1b963b993cb9ea195adbd893a48d573fda951b0da64f60883d7e988b606c9f"}, + {file = "freezegun-1.2.2.tar.gz", hash = "sha256:cd22d1ba06941384410cd967d8a99d5ae2442f57dfafeff2fda5de8dc5c05446"}, +] + +[package.dependencies] +python-dateutil = ">=2.7" + +[[package]] +name = "genson" +version = "1.3.0" description = "GenSON is a powerful, user-friendly JSON Schema generator." optional = false python-versions = "*" files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, + {file = "genson-1.3.0-py3-none-any.whl", hash = "sha256:468feccd00274cc7e4c09e84b08704270ba8d95232aa280f65b986139cec67f7"}, + {file = "genson-1.3.0.tar.gz", hash = "sha256:e02db9ac2e3fd29e65b5286f7135762e2cd8a986537c075b06fc5f1517308e37"}, ] [[package]] @@ -536,13 +535,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -557,13 +556,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -571,7 +570,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -621,13 +619,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -685,24 +683,22 @@ files = [ [[package]] name = "jsonschema" -version = "3.2.0" +version = "4.17.3" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, ] [package.dependencies] attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" [package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] [[package]] name = "langchain-core" @@ -728,101 +724,104 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.134" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.134-py3-none-any.whl", hash = "sha256:ada98ad80ef38807725f32441a472da3dd28394010877751f48f458d3289da04"}, - {file = "langsmith-0.1.134.tar.gz", hash = "sha256:23abee3b508875a0e63c602afafffc02442a19cfd88f9daae05b3e9054fd6b61"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" -version = "3.0.1" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" files = [ - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win32.whl", hash = "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win32.whl", hash = "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win32.whl", hash = "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win32.whl", hash = "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win32.whl", hash = "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b"}, - {file = "markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] name = "nltk" -version = "3.8.1" +version = "3.9.1" description = "Natural Language Toolkit" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "nltk-3.8.1-py3-none-any.whl", hash = "sha256:fd5c9109f976fa86bcadba8f91e47f5e9293bd034474752e92a520f81c93dda5"}, - {file = "nltk-3.8.1.zip", hash = "sha256:1834da3d0682cba4f2cede2f9aad6b0fafb6461ba451db0efb6f9c39798d64d3"}, + {file = "nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1"}, + {file = "nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868"}, ] [package.dependencies] @@ -841,130 +840,131 @@ twitter = ["twython"] [[package]] name = "numpy" -version = "2.1.2" +version = "1.26.4" description = "Fundamental package for array computing in Python" optional = false -python-versions = ">=3.10" -files = [ - {file = "numpy-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466"}, - {file = "numpy-2.1.2-cp310-cp310-win32.whl", hash = "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb"}, - {file = "numpy-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146"}, - {file = "numpy-2.1.2-cp311-cp311-win32.whl", hash = "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c"}, - {file = "numpy-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142"}, - {file = "numpy-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550"}, - {file = "numpy-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe"}, - {file = "numpy-2.1.2-cp313-cp313-win32.whl", hash = "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a"}, - {file = "numpy-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e"}, - {file = "numpy-2.1.2.tar.gz", hash = "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c"}, +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, ] [[package]] name = "orjson" -version = "3.10.7" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:74f4544f5a6405b90da8ea724d15ac9c36da4d72a738c64685003337401f5c12"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34a566f22c28222b08875b18b0dfbf8a947e69df21a9ed5c51a6bf91cfb944ac"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf6ba8ebc8ef5792e2337fb0419f8009729335bb400ece005606336b7fd7bab7"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac7cf6222b29fbda9e3a472b41e6a5538b48f2c8f99261eecd60aafbdb60690c"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de817e2f5fc75a9e7dd350c4b0f54617b280e26d1631811a43e7e968fa71e3e9"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:348bdd16b32556cf8d7257b17cf2bdb7ab7976af4af41ebe79f9796c218f7e91"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:479fd0844ddc3ca77e0fd99644c7fe2de8e8be1efcd57705b5c92e5186e8a250"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fdf5197a21dd660cf19dfd2a3ce79574588f8f5e2dbf21bda9ee2d2b46924d84"}, - {file = "orjson-3.10.7-cp310-none-win32.whl", hash = "sha256:d374d36726746c81a49f3ff8daa2898dccab6596864ebe43d50733275c629175"}, - {file = "orjson-3.10.7-cp310-none-win_amd64.whl", hash = "sha256:cb61938aec8b0ffb6eef484d480188a1777e67b05d58e41b435c74b9d84e0b9c"}, - {file = "orjson-3.10.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0"}, - {file = "orjson-3.10.7-cp311-none-win32.whl", hash = "sha256:82763b46053727a7168d29c772ed5c870fdae2f61aa8a25994c7984a19b1021f"}, - {file = "orjson-3.10.7-cp311-none-win_amd64.whl", hash = "sha256:eb8d384a24778abf29afb8e41d68fdd9a156cf6e5390c04cc07bbc24b89e98b5"}, - {file = "orjson-3.10.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44a96f2d4c3af51bfac6bc4ef7b182aa33f2f054fd7f34cc0ee9a320d051d41f"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ac14cd57df0572453543f8f2575e2d01ae9e790c21f57627803f5e79b0d3c3"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bdbb61dcc365dd9be94e8f7df91975edc9364d6a78c8f7adb69c1cdff318ec93"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b48b3db6bb6e0a08fa8c83b47bc169623f801e5cc4f24442ab2b6617da3b5313"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23820a1563a1d386414fef15c249040042b8e5d07b40ab3fe3efbfbbcbcb8864"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0c6a008e91d10a2564edbb6ee5069a9e66df3fbe11c9a005cb411f441fd2c09"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d352ee8ac1926d6193f602cbe36b1643bbd1bbcb25e3c1a657a4390f3000c9a5"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b"}, - {file = "orjson-3.10.7-cp312-none-win32.whl", hash = "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb"}, - {file = "orjson-3.10.7-cp312-none-win_amd64.whl", hash = "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1"}, - {file = "orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149"}, - {file = "orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad"}, - {file = "orjson-3.10.7-cp313-none-win32.whl", hash = "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2"}, - {file = "orjson-3.10.7-cp313-none-win_amd64.whl", hash = "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024"}, - {file = "orjson-3.10.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6ea2b2258eff652c82652d5e0f02bd5e0463a6a52abb78e49ac288827aaa1469"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:430ee4d85841e1483d487e7b81401785a5dfd69db5de01314538f31f8fbf7ee1"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b6146e439af4c2472c56f8540d799a67a81226e11992008cb47e1267a9b3225"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:084e537806b458911137f76097e53ce7bf5806dda33ddf6aaa66a028f8d43a23"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829cf2195838e3f93b70fd3b4292156fc5e097aac3739859ac0dcc722b27ac0"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1193b2416cbad1a769f868b1749535d5da47626ac29445803dae7cc64b3f5c98"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4e6c3da13e5a57e4b3dca2de059f243ebec705857522f188f0180ae88badd354"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c31008598424dfbe52ce8c5b47e0752dca918a4fdc4a2a32004efd9fab41d866"}, - {file = "orjson-3.10.7-cp38-none-win32.whl", hash = "sha256:7122a99831f9e7fe977dc45784d3b2edc821c172d545e6420c375e5a935f5a1c"}, - {file = "orjson-3.10.7-cp38-none-win_amd64.whl", hash = "sha256:a763bc0e58504cc803739e7df040685816145a6f3c8a589787084b54ebc9f16e"}, - {file = "orjson-3.10.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e76be12658a6fa376fcd331b1ea4e58f5a06fd0220653450f0d415b8fd0fbe20"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed350d6978d28b92939bfeb1a0570c523f6170efc3f0a0ef1f1df287cd4f4960"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144888c76f8520e39bfa121b31fd637e18d4cc2f115727865fdf9fa325b10412"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09b2d92fd95ad2402188cf51573acde57eb269eddabaa60f69ea0d733e789fe9"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b24a579123fa884f3a3caadaed7b75eb5715ee2b17ab5c66ac97d29b18fe57f"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591bcfe7512353bd609875ab38050efe3d55e18934e2f18950c108334b4ff"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f4db56635b58cd1a200b0a23744ff44206ee6aa428185e2b6c4a65b3197abdcd"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0fa5886854673222618638c6df7718ea7fe2f3f2384c452c9ccedc70b4a510a5"}, - {file = "orjson-3.10.7-cp39-none-win32.whl", hash = "sha256:8272527d08450ab16eb405f47e0f4ef0e5ff5981c3d82afe0efd25dcbef2bcd2"}, - {file = "orjson-3.10.7-cp39-none-win_amd64.whl", hash = "sha256:974683d4618c0c7dbf4f69c95a979734bf183d0658611760017f6e70a145af58"}, - {file = "orjson-3.10.7.tar.gz", hash = "sha256:75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -1115,6 +1115,36 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "psutil" +version = "6.1.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, +] + +[package.extras] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + [[package]] name = "py" version = "1.11.0" @@ -1139,19 +1169,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1159,100 +1189,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -1260,13 +1301,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1386,15 +1427,29 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "python-ulid" +version = "3.0.0" +description = "Universally unique lexicographically sortable identifier" +optional = false +python-versions = ">=3.9" +files = [ + {file = "python_ulid-3.0.0-py3-none-any.whl", hash = "sha256:e4c4942ff50dbd79167ad01ac725ec58f924b4018025ce22c858bfcff99a5e31"}, + {file = "python_ulid-3.0.0.tar.gz", hash = "sha256:e50296a47dc8209d28629a22fc81ca26c00982c78934bd7766377ba37ea49a9f"}, +] + +[package.extras] +pydantic = ["pydantic (>=2.0)"] + [[package]] name = "pytz" -version = "2024.1" +version = "2024.2" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, + {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, + {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, ] [[package]] @@ -1470,107 +1525,207 @@ files = [ {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] +[[package]] +name = "rapidfuzz" +version = "3.11.0" +description = "rapid fuzzy string matching" +optional = false +python-versions = ">=3.9" +files = [ + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eb8a54543d16ab1b69e2c5ed96cabbff16db044a50eddfc028000138ca9ddf33"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:231c8b2efbd7f8d2ecd1ae900363ba168b8870644bb8f2b5aa96e4a7573bde19"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54e7f442fb9cca81e9df32333fb075ef729052bcabe05b0afc0441f462299114"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:906f1f2a1b91c06599b3dd1be207449c5d4fc7bd1e1fa2f6aef161ea6223f165"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed59044aea9eb6c663112170f2399b040d5d7b162828b141f2673e822093fa8"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cb1965a28b0fa64abdee130c788a0bc0bb3cf9ef7e3a70bf055c086c14a3d7e"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b488b244931d0291412917e6e46ee9f6a14376625e150056fe7c4426ef28225"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f0ba13557fec9d5ffc0a22826754a7457cc77f1b25145be10b7bb1d143ce84c6"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3871fa7dfcef00bad3c7e8ae8d8fd58089bad6fb21f608d2bf42832267ca9663"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b2669eafee38c5884a6e7cc9769d25c19428549dcdf57de8541cf9e82822e7db"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ffa1bb0e26297b0f22881b219ffc82a33a3c84ce6174a9d69406239b14575bd5"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:45b15b8a118856ac9caac6877f70f38b8a0d310475d50bc814698659eabc1cdb"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win32.whl", hash = "sha256:22033677982b9c4c49676f215b794b0404073f8974f98739cb7234e4a9ade9ad"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:be15496e7244361ff0efcd86e52559bacda9cd975eccf19426a0025f9547c792"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_arm64.whl", hash = "sha256:714a7ba31ba46b64d30fccfe95f8013ea41a2e6237ba11a805a27cdd3bce2573"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8724a978f8af7059c5323d523870bf272a097478e1471295511cf58b2642ff83"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b63cb1f2eb371ef20fb155e95efd96e060147bdd4ab9fc400c97325dfee9fe1"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82497f244aac10b20710448645f347d862364cc4f7d8b9ba14bd66b5ce4dec18"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:339607394941801e6e3f6c1ecd413a36e18454e7136ed1161388de674f47f9d9"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84819390a36d6166cec706b9d8f0941f115f700b7faecab5a7e22fc367408bc3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eea8d9e20632d68f653455265b18c35f90965e26f30d4d92f831899d6682149b"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b659e1e2ea2784a9a397075a7fc395bfa4fe66424042161c4bcaf6e4f637b38"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1315cd2a351144572e31fe3df68340d4b83ddec0af8b2e207cd32930c6acd037"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a7743cca45b4684c54407e8638f6d07b910d8d811347b9d42ff21262c7c23245"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:5bb636b0150daa6d3331b738f7c0f8b25eadc47f04a40e5c23c4bfb4c4e20ae3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:42f4dd264ada7a9aa0805ea0da776dc063533917773cf2df5217f14eb4429eae"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:51f24cb39e64256221e6952f22545b8ce21cacd59c0d3e367225da8fc4b868d8"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win32.whl", hash = "sha256:aaf391fb6715866bc14681c76dc0308f46877f7c06f61d62cc993b79fc3c4a2a"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:ebadd5b8624d8ad503e505a99b8eb26fe3ea9f8e9c2234e805a27b269e585842"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:d895998fec712544c13cfe833890e0226585cf0391dd3948412441d5d68a2b8c"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f382fec4a7891d66fb7163c90754454030bb9200a13f82ee7860b6359f3f2fa8"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dfaefe08af2a928e72344c800dcbaf6508e86a4ed481e28355e8d4b6a6a5230e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92ebb7c12f682b5906ed98429f48a3dd80dd0f9721de30c97a01473d1a346576"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a1b3ebc62d4bcdfdeba110944a25ab40916d5383c5e57e7c4a8dc0b6c17211a"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c6d7fea39cb33e71de86397d38bf7ff1a6273e40367f31d05761662ffda49e4"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99aebef8268f2bc0b445b5640fd3312e080bd17efd3fbae4486b20ac00466308"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4469307f464ae3089acf3210b8fc279110d26d10f79e576f385a98f4429f7d97"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:eb97c53112b593f89a90b4f6218635a9d1eea1d7f9521a3b7d24864228bbc0aa"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef8937dae823b889c0273dfa0f0f6c46a3658ac0d851349c464d1b00e7ff4252"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d95f9e9f3777b96241d8a00d6377cc9c716981d828b5091082d0fe3a2924b43e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:b1d67d67f89e4e013a5295e7523bc34a7a96f2dba5dd812c7c8cb65d113cbf28"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d994cf27e2f874069884d9bddf0864f9b90ad201fcc9cb2f5b82bacc17c8d5f2"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win32.whl", hash = "sha256:ba26d87fe7fcb56c4a53b549a9e0e9143f6b0df56d35fe6ad800c902447acd5b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:b1f7efdd7b7adb32102c2fa481ad6f11923e2deb191f651274be559d56fc913b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:ed78c8e94f57b44292c1a0350f580e18d3a3c5c0800e253f1583580c1b417ad2"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e60814edd0c9b511b5f377d48b9782b88cfe8be07a98f99973669299c8bb318a"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f28952da055dbfe75828891cd3c9abf0984edc8640573c18b48c14c68ca5e06"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e8f93bc736020351a6f8e71666e1f486bb8bd5ce8112c443a30c77bfde0eb68"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76a4a11ba8f678c9e5876a7d465ab86def047a4fcc043617578368755d63a1bc"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc0e0d41ad8a056a9886bac91ff9d9978e54a244deb61c2972cc76b66752de9c"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e8ea35f2419c7d56b3e75fbde2698766daedb374f20eea28ac9b1f668ef4f74"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd340bbd025302276b5aa221dccfe43040c7babfc32f107c36ad783f2ffd8775"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:494eef2c68305ab75139034ea25328a04a548d297712d9cf887bf27c158c388b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5a167344c1d6db06915fb0225592afdc24d8bafaaf02de07d4788ddd37f4bc2f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8c7af25bda96ac799378ac8aba54a8ece732835c7b74cfc201b688a87ed11152"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d2a0f7e17f33e7890257367a1662b05fecaf56625f7dbb6446227aaa2b86448b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4d0d26c7172bdb64f86ee0765c5b26ea1dc45c52389175888ec073b9b28f4305"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win32.whl", hash = "sha256:6ad02bab756751c90fa27f3069d7b12146613061341459abf55f8190d899649f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:b1472986fd9c5d318399a01a0881f4a0bf4950264131bb8e2deba9df6d8c362b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:c408f09649cbff8da76f8d3ad878b64ba7f7abdad1471efb293d2c075e80c822"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1bac4873f6186f5233b0084b266bfb459e997f4c21fc9f029918f44a9eccd304"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f9f12c2d0aa52b86206d2059916153876a9b1cf9dfb3cf2f344913167f1c3d4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd501de6f7a8f83557d20613b58734d1cb5f0be78d794cde64fe43cfc63f5f2"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4416ca69af933d4a8ad30910149d3db6d084781d5c5fdedb713205389f535385"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f0821b9bdf18c5b7d51722b906b233a39b17f602501a966cfbd9b285f8ab83cd"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0edecc3f90c2653298d380f6ea73b536944b767520c2179ec5d40b9145e47aa"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4513dd01cee11e354c31b75f652d4d466c9440b6859f84e600bdebfccb17735a"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d9727b85511b912571a76ce53c7640ba2c44c364e71cef6d7359b5412739c570"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ab9eab33ee3213f7751dc07a1a61b8d9a3d748ca4458fffddd9defa6f0493c16"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:6b01c1ddbb054283797967ddc5433d5c108d680e8fa2684cf368be05407b07e4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:3857e335f97058c4b46fa39ca831290b70de554a5c5af0323d2f163b19c5f2a6"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d98a46cf07c0c875d27e8a7ed50f304d83063e49b9ab63f21c19c154b4c0d08d"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win32.whl", hash = "sha256:c36539ed2c0173b053dafb221458812e178cfa3224ade0960599bec194637048"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:ec8d7d8567e14af34a7911c98f5ac74a3d4a743cd848643341fc92b12b3784ff"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_arm64.whl", hash = "sha256:62171b270ecc4071be1c1f99960317db261d4c8c83c169e7f8ad119211fe7397"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f06e3c4c0a8badfc4910b9fd15beb1ad8f3b8fafa8ea82c023e5e607b66a78e4"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fe7aaf5a54821d340d21412f7f6e6272a9b17a0cbafc1d68f77f2fc11009dcd5"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25398d9ac7294e99876a3027ffc52c6bebeb2d702b1895af6ae9c541ee676702"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a52eea839e4bdc72c5e60a444d26004da00bb5bc6301e99b3dde18212e41465"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c87319b0ab9d269ab84f6453601fd49b35d9e4a601bbaef43743f26fabf496c"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3048c6ed29d693fba7d2a7caf165f5e0bb2b9743a0989012a98a47b975355cca"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b04f29735bad9f06bb731c214f27253bd8bedb248ef9b8a1b4c5bde65b838454"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7864e80a0d4e23eb6194254a81ee1216abdc53f9dc85b7f4d56668eced022eb8"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3794df87313dfb56fafd679b962e0613c88a293fd9bd5dd5c2793d66bf06a101"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d71da0012face6f45432a11bc59af19e62fac5a41f8ce489e80c0add8153c3d1"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff38378346b7018f42cbc1f6d1d3778e36e16d8595f79a312b31e7c25c50bd08"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6668321f90aa02a5a789d4e16058f2e4f2692c5230252425c3532a8a62bc3424"}, + {file = "rapidfuzz-3.11.0.tar.gz", hash = "sha256:a53ca4d3f52f00b393fab9b5913c5bafb9afc27d030c8a1db1283da6917a860f"}, +] + +[package.extras] +all = ["numpy"] + [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -1729,35 +1884,15 @@ files = [ attributes-doc = "*" typing-extensions = "*" -[[package]] -name = "setuptools" -version = "75.1.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"}, - {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] - [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1799,20 +1934,21 @@ files = [ [[package]] name = "tqdm" -version = "4.66.5" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd"}, - {file = "tqdm-4.66.5.tar.gz", hash = "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -1850,6 +1986,17 @@ files = [ {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, ] +[[package]] +name = "unidecode" +version = "1.3.8" +description = "ASCII transliterations of Unicode text" +optional = false +python-versions = ">=3.5" +files = [ + {file = "Unidecode-1.3.8-py3-none-any.whl", hash = "sha256:d130a61ce6696f8148a3bd8fe779c99adeb4b870584eeb9526584e9aa091fd39"}, + {file = "Unidecode-1.3.8.tar.gz", hash = "sha256:cfdb349d46ed3873ece4586b96aa75258726e2fa8ec21d6f00a591d98806c2f4"}, +] + [[package]] name = "url-normalize" version = "1.4.3" @@ -1866,13 +2013,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1883,97 +2030,18 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "wcmatch" -version = "8.4" +version = "10.0" description = "Wildcard/glob file name matcher." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, + {file = "wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a"}, + {file = "wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a"}, ] [package.dependencies] bracex = ">=2.1.1" -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - [[package]] name = "xmltodict" version = "0.13.0" @@ -1988,4 +2056,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.10,<3.12" -content-hash = "0cdbe9e80ceaf2242d230152f179dcb048eb807ed6a796ffba21154635ef30a7" +content-hash = "72d248f774a68421f400671e384a73bbe6c228d20f78289d109573d06362fea7" diff --git a/airbyte-integrations/connectors/source-jira/pyproject.toml b/airbyte-integrations/connectors/source-jira/pyproject.toml index cf4b650c913f..27aeaf44fdc4 100644 --- a/airbyte-integrations/connectors/source-jira/pyproject.toml +++ b/airbyte-integrations/connectors/source-jira/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "3.2.1" +version = "3.4.7" name = "source-jira" description = "Source implementation for Jira." authors = [ "Airbyte ",] @@ -17,12 +17,13 @@ include = "source_jira" [tool.poetry.dependencies] python = "^3.10,<3.12" -airbyte-cdk = "^5" +airbyte-cdk = "^6" [tool.poetry.scripts] source-jira = "source_jira.run:run" [tool.poetry.group.dev.dependencies] +freezegun = "==1.2.2" pytest = "==6.2.5" requests-mock = "^1.9.3" pytest-mock = "^3.6.1" diff --git a/airbyte-integrations/connectors/source-jira/source_jira/components/extractors.py b/airbyte-integrations/connectors/source-jira/source_jira/components/extractors.py index 2a30cc666541..ff56146ada56 100644 --- a/airbyte-integrations/connectors/source-jira/source_jira/components/extractors.py +++ b/airbyte-integrations/connectors/source-jira/source_jira/components/extractors.py @@ -3,9 +3,10 @@ from dataclasses import dataclass from typing import Any, List, Mapping -from airbyte_cdk.sources.declarative.extractors import DpathExtractor from requests_cache import Response +from airbyte_cdk.sources.declarative.extractors import DpathExtractor + @dataclass class LabelsRecordExtractor(DpathExtractor): diff --git a/airbyte-integrations/connectors/source-jira/source_jira/components/partition_routers.py b/airbyte-integrations/connectors/source-jira/source_jira/components/partition_routers.py index 3766653d836e..cf0dd162a968 100644 --- a/airbyte-integrations/connectors/source-jira/source_jira/components/partition_routers.py +++ b/airbyte-integrations/connectors/source-jira/source_jira/components/partition_routers.py @@ -27,7 +27,9 @@ def stream_slices(self) -> Iterable[StreamSlice]: fields += ["key", "status", "created", "updated"] self.parent_stream_configs = parent_stream_configs for stream_slice in super().stream_slices(): - setattr(stream_slice, "parent_stream_fields", fields) + stream_slice = StreamSlice( + partition=stream_slice.partition, cursor_slice=stream_slice.cursor_slice, extra_fields={"fields": fields} + ) yield stream_slice diff --git a/airbyte-integrations/connectors/source-jira/source_jira/manifest.yaml b/airbyte-integrations/connectors/source-jira/source_jira/manifest.yaml index 7bff4be7541b..aadd4f0a17eb 100644 --- a/airbyte-integrations/connectors/source-jira/source_jira/manifest.yaml +++ b/airbyte-integrations/connectors/source-jira/source_jira/manifest.yaml @@ -1,4 +1,4 @@ -version: 0.72.1 +version: 0.51.42 type: DeclarativeSource definitions: @@ -1073,18 +1073,11 @@ definitions: # Incremental Streams - semi_incremental_retriever: - $ref: "#/definitions/retriever" - record_selector: - $ref: "#/definitions/selector" - record_filter: - condition: "{{ record['updated'] >= stream_slice['start_time'] }}" - incremental_sync: type: DatetimeBasedCursor cursor_field: "updated" start_datetime: "{{ config.get('start_date', '1970-01-01T00:00:00Z') }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" cursor_datetime_formats: - "%Y-%m-%dT%H:%M:%S.%f%z" lookback_window: "PT{{ config.get('lookback_window_minutes', '0') }}M" @@ -1096,7 +1089,9 @@ definitions: semi_incremental_stream: $ref: "#/definitions/incremental_stream" - retriever: "#/definitions/semi_incremental_retriever" + incremental_sync: + $ref: "#/definitions/incremental_sync" + is_client_side_incremental: true # https://developer.atlassian.com/cloud/jira/software/rest/api-group-board/#api-rest-agile-1-0-board-boardid-issue-get board_issues_stream: @@ -1116,7 +1111,7 @@ definitions: $ref: "#/definitions/requester_v1" request_parameters: fields: "['key', 'created', 'updated']" - jql: "updated >= '{{ format_datetime(stream_slice.start_time, '%Y/%m/%d %H:%M') }}'" + jql: "updated >= {{ (timestamp(stream_slice.start_time) * 1000)|int }}" error_handler: $ref: "#/definitions/error_handler" response_filters: @@ -1158,7 +1153,7 @@ definitions: request_parameters: fields: "*all" jql: > - "updated >= '{{ format_datetime(stream_slice.start_time, '%Y/%m/%d %H:%M') }}' " + "updated >= {{ (timestamp(stream_slice.start_time) * 1000)|int }} " "{{ ('and project in ' + '(' + stream_slice.project_id + ') ') if stream_slice.project_id else '' }}" "ORDER BY updated asc" expand: "renderedFields,transitions,changelog" @@ -1223,8 +1218,8 @@ definitions: requester: $ref: "#/definitions/retriever_v1/requester" request_parameters: - fields: "{{ stream_slice._partition.parent_stream_fields }}" - jql: "updated >= '{{ format_datetime(stream_slice.start_time, '%Y/%m/%d %H:%M') }}'" + fields: "{{ stream_slice._partition.extra_fields['fields'] }}" + jql: "updated >= {{ (timestamp(stream_slice.start_time) * 1000)|int }}" transformations: - type: AddFields fields: @@ -1247,6 +1242,56 @@ definitions: path: "sprint/{{ stream_slice.sprint_id }}/issue" extract_field: "issues" + # https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-get + issue_comments_stream: + $ref: "#/definitions/semi_incremental_stream" + name: issue_comments + primary_key: "id" + retriever: + $ref: "#/definitions/retriever" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: "#/definitions/issues_stream" + parent_key: "id" + partition_field: "issue_id" + incremental_dependency: true + transformations: + - type: AddFields + fields: + - path: ["issueId"] + value_type: string + value: "{{ stream_slice.issue_id }}" + $parameters: + path: "issue/{{ stream_slice.issue_id }}/comment" + extract_field: "comments" + + # https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-worklogs/#api-rest-api-3-issue-issueidorkey-worklog-get + issue_worklogs_stream: + $ref: "#/definitions/semi_incremental_stream" + name: issue_worklogs + primary_key: "id" + retriever: + $ref: "#/definitions/retriever" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: "#/definitions/issues_stream" + parent_key: "id" + partition_field: "issue_id" + incremental_dependency: true + transformations: + - type: AddFields + fields: + - path: ["issueId"] + value_type: string + value: "{{ stream_slice.issue_id }}" + $parameters: + path: "issue/{{ stream_slice.issue_id }}/worklog" + extract_field: "worklogs" + streams: # Full refresh streams @@ -1310,6 +1355,11 @@ streams: - "#/definitions/issues_stream" - "#/definitions/sprint_issues_stream" + # Incremental substreams + + - "#/definitions/issue_comments_stream" + - "#/definitions/issue_worklogs_stream" + check: type: CheckStream stream_names: @@ -1366,3 +1416,9 @@ check: - board_issues - issues - sprint_issues + +# Defining a value here is difficult because the Jira API documentation mentions "REST API rate limits are not published because the computation logic is evolving continuously to maximize reliability and performance for customers" regarding the API budget. Hence, we will need to empirically validate the values that are set here. +concurrency_level: + type: ConcurrencyLevel + default_concurrency: "{{ config.get('num_workers', 5) }}" + max_concurrency: 40 diff --git a/airbyte-integrations/connectors/source-jira/source_jira/run.py b/airbyte-integrations/connectors/source-jira/source_jira/run.py index c5702721e0b8..8f5465ccd6c7 100644 --- a/airbyte-integrations/connectors/source-jira/source_jira/run.py +++ b/airbyte-integrations/connectors/source-jira/source_jira/run.py @@ -1,14 +1,54 @@ # -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. # - import sys +import traceback +from datetime import datetime +from typing import List + +from orjson import orjson -from airbyte_cdk.entrypoint import launch +from airbyte_cdk.entrypoint import AirbyteEntrypoint, launch, logger +from airbyte_cdk.exception_handler import init_uncaught_exception_handler +from airbyte_cdk.models import AirbyteErrorTraceMessage, AirbyteMessage, AirbyteMessageSerializer, AirbyteTraceMessage, TraceType, Type from source_jira import SourceJira -def run(): - source = SourceJira() - launch(source, sys.argv[1:]) +def _get_source(args: List[str]): + catalog_path = AirbyteEntrypoint.extract_catalog(args) + config_path = AirbyteEntrypoint.extract_config(args) + state_path = AirbyteEntrypoint.extract_state(args) + try: + return SourceJira( + SourceJira.read_catalog(catalog_path) if catalog_path else None, + SourceJira.read_config(config_path) if config_path else None, + SourceJira.read_state(state_path) if state_path else None, + ) + except Exception as error: + print( + orjson.dumps( + AirbyteMessageSerializer.dump( + AirbyteMessage( + type=Type.TRACE, + trace=AirbyteTraceMessage( + type=TraceType.ERROR, + emitted_at=int(datetime.now().timestamp() * 1000), + error=AirbyteErrorTraceMessage( + message=f"Error starting the sync. This could be due to an invalid configuration or catalog. Please contact Support for assistance. Error: {error}", + stack_trace=traceback.format_exc(), + ), + ), + ) + ) + ).decode() + ) + return None + + +def run() -> None: + init_uncaught_exception_handler(logger) + _args = sys.argv[1:] + source = _get_source(_args) + if source: + launch(source, _args) diff --git a/airbyte-integrations/connectors/source-jira/source_jira/source.py b/airbyte-integrations/connectors/source-jira/source_jira/source.py index db2297393381..1e39ab123080 100644 --- a/airbyte-integrations/connectors/source-jira/source_jira/source.py +++ b/airbyte-integrations/connectors/source-jira/source_jira/source.py @@ -2,25 +2,27 @@ # Copyright (c) 2024 Airbyte, Inc., all rights reserved. # from logging import Logger -from typing import Any, List, Mapping, Tuple +from typing import Any, List, Mapping, Optional, Tuple import pendulum -from airbyte_cdk.models import FailureType +from pydantic import ValidationError +from requests.exceptions import InvalidURL + +from airbyte_cdk.models import ConfiguredAirbyteCatalog, FailureType from airbyte_cdk.sources.declarative.exceptions import ReadException from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource +from airbyte_cdk.sources.source import TState from airbyte_cdk.sources.streams.core import Stream from airbyte_cdk.sources.streams.http.requests_native_auth import BasicHttpAuthenticator from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from pydantic import ValidationError -from requests.exceptions import InvalidURL -from .streams import IssueComments, IssueFields, Issues, IssueWorklogs, PullRequests +from .streams import IssueFields, Issues, PullRequests from .utils import read_full_refresh class SourceJira(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) + def __init__(self, catalog: Optional[ConfiguredAirbyteCatalog], config: Optional[Mapping[str, Any]], state: TState, **kwargs): + super().__init__(catalog=catalog, config=config, state=state, **{"path_to_yaml": "manifest.yaml"}) def check_connection(self, logger: Logger, config: Mapping[str, Any]) -> Tuple[bool, any]: try: @@ -70,12 +72,12 @@ def _validate_and_transform_config(self, config: Mapping[str, Any]): @staticmethod def get_authenticator(config: Mapping[str, Any]): - return BasicHttpAuthenticator(config["email"], config["api_token"]) + return BasicHttpAuthenticator(config.get("email"), config["api_token"]) def get_non_portable_streams(self, config: Mapping[str, Any]) -> List[Stream]: config = self._validate_and_transform_config(config.copy()) authenticator = self.get_authenticator(config) - args = {"authenticator": authenticator, "domain": config["domain"], "projects": config["projects"]} + args = {"authenticator": authenticator, "domain": config.get("domain"), "projects": config["projects"]} incremental_args = { **args, "start_date": config.get("start_date"), @@ -84,11 +86,9 @@ def get_non_portable_streams(self, config: Mapping[str, Any]) -> List[Stream]: issues_stream = Issues(**incremental_args) issue_fields_stream = IssueFields(**args) - streams = [IssueComments(**incremental_args), IssueWorklogs(**incremental_args)] - experimental_streams = [] if config.get("enable_experimental_streams", False): experimental_streams.append( PullRequests(issues_stream=issues_stream, issue_fields_stream=issue_fields_stream, **incremental_args) ) - return streams + experimental_streams + return experimental_streams diff --git a/airbyte-integrations/connectors/source-jira/source_jira/spec.json b/airbyte-integrations/connectors/source-jira/source_jira/spec.json index fff67ec349e6..2d30b8222c2c 100644 --- a/airbyte-integrations/connectors/source-jira/source_jira/spec.json +++ b/airbyte-integrations/connectors/source-jira/source_jira/spec.json @@ -98,6 +98,16 @@ "description": "Allow the use of experimental streams which rely on undocumented Jira API endpoints. See https://docs.airbyte.com/integrations/sources/jira#experimental-tables for more info.", "default": false, "order": 6 + }, + "num_workers": { + "type": "integer", + "title": "Number of concurrent workers", + "minimum": 1, + "maximum": 40, + "default": 3, + "examples": [1, 2, 3], + "description": "The number of worker threads to use for the sync.", + "order": 7 } } } diff --git a/airbyte-integrations/connectors/source-jira/source_jira/streams.py b/airbyte-integrations/connectors/source-jira/source_jira/streams.py index 4e8d7f528e42..b9ef14e0cce3 100644 --- a/airbyte-integrations/connectors/source-jira/source_jira/streams.py +++ b/airbyte-integrations/connectors/source-jira/source_jira/streams.py @@ -12,6 +12,8 @@ import pendulum import requests +from requests.exceptions import HTTPError + from airbyte_cdk.sources import Source from airbyte_cdk.sources.streams import CheckpointMixin, Stream from airbyte_cdk.sources.streams.checkpoint.checkpoint_reader import FULL_REFRESH_COMPLETE_STATE @@ -21,11 +23,11 @@ from airbyte_cdk.sources.streams.http.error_handlers.http_status_error_handler import HttpStatusErrorHandler from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, ResponseAction from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer -from requests.exceptions import HTTPError from source_jira.type_transfromer import DateTimeTransformer from .utils import read_full_refresh, read_incremental, safe_max + API_VERSION = 3 @@ -173,7 +175,6 @@ def read_records(self, **kwargs) -> Iterable[Mapping[str, Any]]: class FullRefreshJiraStream(JiraStream): - """ This is a temporary solution to avoid incorrect state handling. See comments below for more info: @@ -224,8 +225,8 @@ def _get_updated_state(self, current_stream_state: MutableMapping[str, Any], lat def jql_compare_date(self, stream_state: Mapping[str, Any]) -> Optional[str]: compare_date = self.get_starting_point(stream_state) if compare_date: - compare_date = compare_date.strftime("%Y/%m/%d %H:%M") - return f"{self.cursor_field} >= '{compare_date}'" + compare_date_epoch = compare_date.int_timestamp * 1000 + return f"{self.cursor_field} >= {compare_date_epoch}" def get_starting_point(self, stream_state: Mapping[str, Any]) -> Optional[pendulum.DateTime]: if self.cursor_field not in self._starting_point_cache: @@ -379,70 +380,6 @@ def read_records(self, **kwargs) -> Iterable[Mapping[str, Any]]: yield project -class IssueWorklogs(IncrementalJiraStream): - """ - https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-worklogs/#api-rest-api-3-issue-issueidorkey-worklog-get - - Cannot be migrated at the moment: https://github.com/airbytehq/airbyte-internal-issues/issues/7522 - """ - - extract_field = "worklogs" - cursor_field = "updated" - - def __init__(self, **kwargs): - super().__init__(**kwargs) - self.issues_stream = Issues( - authenticator=self._http_client._session.auth, - domain=self._domain, - projects=self._projects, - start_date=self._start_date, - ) - - def path(self, stream_slice: Mapping[str, Any], **kwargs) -> str: - return f"issue/{stream_slice['key']}/worklog" - - def read_records( - self, stream_slice: Optional[Mapping[str, Any]] = None, stream_state: Mapping[str, Any] = None, **kwargs - ) -> Iterable[Mapping[str, Any]]: - for issue in read_incremental(self.issues_stream, stream_state=stream_state): - stream_slice = {"key": issue["key"]} - yield from super().read_records(stream_slice=stream_slice, stream_state=stream_state, **kwargs) - - -class IssueComments(IncrementalJiraStream): - """ - https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-get - - Cannot be migrated at the moment: https://github.com/airbytehq/airbyte-internal-issues/issues/7522 - """ - - extract_field = "comments" - cursor_field = "updated" - - def __init__(self, **kwargs): - super().__init__(**kwargs) - self.issues_stream = Issues( - authenticator=self._http_client._session.auth, - domain=self._domain, - projects=self._projects, - start_date=self._start_date, - ) - - def path(self, stream_slice: Mapping[str, Any], **kwargs) -> str: - return f"issue/{stream_slice['key']}/comment" - - def read_records( - self, stream_slice: Optional[Mapping[str, Any]] = None, stream_state: Mapping[str, Any] = None, **kwargs - ) -> Iterable[Mapping[str, Any]]: - for issue in read_incremental(self.issues_stream, stream_state=stream_state): - stream_slice = {"key": issue["key"]} - yield from super().read_records(stream_slice=stream_slice, stream_state=stream_state, **kwargs) - - def transform(self, record: MutableMapping[str, Any], stream_slice: Mapping[str, Any], **kwargs) -> MutableMapping[str, Any]: - record["issueId"] = stream_slice["key"] - return record - - class PullRequests(IncrementalJiraStream): """ This stream uses an undocumented internal API endpoint used by the Jira diff --git a/airbyte-integrations/connectors/source-jira/source_jira/type_transfromer.py b/airbyte-integrations/connectors/source-jira/source_jira/type_transfromer.py index 16fdfb000a4c..efb3bca61278 100644 --- a/airbyte-integrations/connectors/source-jira/source_jira/type_transfromer.py +++ b/airbyte-integrations/connectors/source-jira/source_jira/type_transfromer.py @@ -8,6 +8,7 @@ from airbyte_cdk.sources.utils.transform import TypeTransformer + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-jira/source_jira/utils.py b/airbyte-integrations/connectors/source-jira/source_jira/utils.py index f85c7363ff97..af6adbcf9108 100644 --- a/airbyte-integrations/connectors/source-jira/source_jira/utils.py +++ b/airbyte-integrations/connectors/source-jira/source_jira/utils.py @@ -6,6 +6,7 @@ from airbyte_cdk.sources.streams import Stream + _NO_STATE: MutableMapping[str, Any] = {} diff --git a/airbyte-integrations/connectors/source-jira/unit_tests/conftest.py b/airbyte-integrations/connectors/source-jira/unit_tests/conftest.py index 703a5604b444..b25b3acd3ba2 100644 --- a/airbyte-integrations/connectors/source-jira/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-jira/unit_tests/conftest.py @@ -11,6 +11,7 @@ from responses import matchers from source_jira.source import SourceJira + ENV_REQUEST_CACHE_PATH = "REQUEST_CACHE_PATH" os.environ["REQUEST_CACHE_PATH"] = ENV_REQUEST_CACHE_PATH @@ -38,6 +39,7 @@ def config(): "email": "email@email.com", "start_date": "2021-01-01T00:00:00Z", "projects": ["Project1"], + "enable_experimental_streams": True, } @@ -323,7 +325,7 @@ def mock_issues_responses_with_date_filter(config, issues_response): { "maxResults": 50, "fields": "*all", - "jql": "updated >= '2021/01/01 00:00' and project in (1) ORDER BY updated asc", + "jql": "updated >= 1609459200000 and project in (1) ORDER BY updated asc", "expand": "renderedFields,transitions,changelog", } ) @@ -338,7 +340,7 @@ def mock_issues_responses_with_date_filter(config, issues_response): { "maxResults": 50, "fields": "*all", - "jql": "updated >= '2021/01/01 00:00' and project in (2) ORDER BY updated asc", + "jql": "updated >= 1609459200000 and project in (2) ORDER BY updated asc", "expand": "renderedFields,transitions,changelog", } ) @@ -353,7 +355,7 @@ def mock_issues_responses_with_date_filter(config, issues_response): { "maxResults": 50, "fields": "*all", - "jql": "updated >= '2021/01/01 00:00' and project in (3) ORDER BY updated asc", + "jql": "updated >= 1609459200000 and project in (3) ORDER BY updated asc", "expand": "renderedFields,transitions,changelog", } ) @@ -369,7 +371,7 @@ def mock_issues_responses_with_date_filter(config, issues_response): { "maxResults": 50, "fields": "*all", - "jql": "updated >= '2021/01/01 00:00' and project in (4) ORDER BY updated asc", + "jql": "updated >= 1609459200000 and project in (4) ORDER BY updated asc", "expand": "renderedFields,transitions,changelog", } ) @@ -547,7 +549,7 @@ def mock_sprints_response(config, sprints_response): def find_stream(stream_name, config): - for stream in SourceJira().streams(config=config): + for stream in SourceJira(config=config, catalog=None, state=None).streams(config=config): if stream.name == stream_name: return stream raise ValueError(f"Stream {stream_name} not found") diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/__init__.py b/airbyte-integrations/connectors/source-jira/unit_tests/integration/__init__.py similarity index 100% rename from airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/concurrent/__init__.py rename to airbyte-integrations/connectors/source-jira/unit_tests/integration/__init__.py diff --git a/airbyte-integrations/connectors/source-jira/unit_tests/integration/config.py b/airbyte-integrations/connectors/source-jira/unit_tests/integration/config.py new file mode 100644 index 000000000000..ad2f7bd7b5ec --- /dev/null +++ b/airbyte-integrations/connectors/source-jira/unit_tests/integration/config.py @@ -0,0 +1,34 @@ +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. + +from datetime import datetime +from typing import Any, Dict, List + + +class ConfigBuilder: + def __init__(self) -> None: + self._config: Dict[str, Any] = { + "api_token": "any_api_token", + "domain": "airbyteio.atlassian.net", + "email": "integration-test@airbyte.io", + "start_date": "2021-01-01T00:00:00Z", + "projects": [], + } + + def with_api_token(self, api_token: str) -> "ConfigBuilder": + self._config["api_token"] = api_token + return self + + def with_domain(self, domain: str) -> "ConfigBuilder": + self._config["domain"] = domain + return self + + def with_start_date(self, start_datetime: datetime) -> "ConfigBuilder": + self._config["start_date"] = start_datetime.strftime("%Y-%m-%dT%H:%M:%SZ") + return self + + def with_projects(self, projects: List[str]) -> "ConfigBuilder": + self._config["projects"] = projects + return self + + def build(self) -> Dict[str, Any]: + return self._config diff --git a/airbyte-integrations/connectors/source-jira/unit_tests/integration/test_issues.py b/airbyte-integrations/connectors/source-jira/unit_tests/integration/test_issues.py new file mode 100644 index 000000000000..2d8f2b212741 --- /dev/null +++ b/airbyte-integrations/connectors/source-jira/unit_tests/integration/test_issues.py @@ -0,0 +1,95 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. +import json +import os +from datetime import datetime, timedelta, timezone +from typing import Any, Dict +from unittest import TestCase + +import freezegun +from source_jira import SourceJira + +from airbyte_cdk.models import ConfiguredAirbyteCatalog, SyncMode +from airbyte_cdk.test.catalog_builder import CatalogBuilder +from airbyte_cdk.test.entrypoint_wrapper import read +from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest +from airbyte_cdk.test.mock_http.response_builder import ( + FieldPath, + HttpResponseBuilder, + RecordBuilder, + create_record_builder, + create_response_builder, + find_template, +) +from airbyte_cdk.test.state_builder import StateBuilder +from integration.config import ConfigBuilder + + +_STREAM_NAME = "issues" +_API_TOKEN = "api_token" +_DOMAIN = "airbyteio.atlassian.net" +_NOW = datetime(2024, 1, 1, tzinfo=timezone.utc) + + +def _create_config() -> ConfigBuilder: + return ConfigBuilder().with_api_token(_API_TOKEN).with_domain(_DOMAIN) + + +def _create_catalog(sync_mode: SyncMode = SyncMode.full_refresh) -> ConfiguredAirbyteCatalog: + return CatalogBuilder().with_stream(name="issues", sync_mode=sync_mode).build() + + +def _response_template() -> Dict[str, Any]: + with open(os.path.join(os.path.dirname(__file__), "..", "responses", "issues.json")) as response_file_handler: + return json.load(response_file_handler) + + +def _create_response() -> HttpResponseBuilder: + return create_response_builder( + response_template=_response_template(), + records_path=FieldPath("issues"), + ) + + +def _create_record() -> RecordBuilder: + return create_record_builder( + _response_template(), FieldPath("issues"), record_id_path=FieldPath("id"), record_cursor_path=FieldPath("updated") + ) + + +@freezegun.freeze_time(_NOW.isoformat()) +class IssuesTest(TestCase): + @HttpMocker() + def test_given_timezone_in_state_when_read_consider_timezone(self, http_mocker: HttpMocker) -> None: + config = _create_config().build() + datetime_with_timezone = "2023-11-01T00:00:00.000-0800" + timestamp_with_timezone = 1698825600000 + state = ( + StateBuilder() + .with_stream_state( + "issues", + { + "use_global_cursor": False, + "state": {"updated": datetime_with_timezone}, + "lookback_window": 2, + "states": [{"partition": {"parent_slice": {}, "project_id": "10025"}, "cursor": {"updated": datetime_with_timezone}}], + }, + ) + .build() + ) + http_mocker.get( + HttpRequest( + f"https://{_DOMAIN}/rest/api/3/search", + { + "fields": "*all", + "jql": f"updated >= {timestamp_with_timezone} ORDER BY updated asc", + "expand": "renderedFields,transitions,changelog", + "maxResults": "50", + }, + ), + _create_response().with_record(_create_record()).with_record(_create_record()).build(), + ) + + source = SourceJira(config=config, catalog=_create_catalog(), state=state) + actual_messages = read(source, config=config, catalog=_create_catalog(), state=state) + + assert len(actual_messages.records) == 2 diff --git a/airbyte-integrations/connectors/source-jira/unit_tests/test_components.py b/airbyte-integrations/connectors/source-jira/unit_tests/test_components.py index fade1745ec3f..50e20916d093 100644 --- a/airbyte-integrations/connectors/source-jira/unit_tests/test_components.py +++ b/airbyte-integrations/connectors/source-jira/unit_tests/test_components.py @@ -4,10 +4,11 @@ import pytest import requests -from airbyte_cdk.sources.declarative.types import StreamSlice from source_jira.components.extractors import LabelsRecordExtractor from source_jira.components.partition_routers import SprintIssuesSubstreamPartitionRouter +from airbyte_cdk.sources.declarative.types import StreamSlice + @pytest.mark.parametrize( "json_response, expected_output", @@ -72,7 +73,7 @@ def test_sprint_issues_substream_partition_router(fields_data, other_data, expec assert slices, "There should be at least one slice generated" # Asserting the correct parent stream fields are set in slices assert all( - _slice.parent_stream_fields == expected_fields for _slice in slices + _slice.extra_fields["fields"] == expected_fields for _slice in slices ), f"Expected parent stream fields {expected_fields}, but got {slices}" assert all( _slice.partition["partition_id"] == expected_partition for _slice in slices diff --git a/airbyte-integrations/connectors/source-jira/unit_tests/test_date_time_transformer.py b/airbyte-integrations/connectors/source-jira/unit_tests/test_date_time_transformer.py index 7c9fbfff90ba..01e69cdb6853 100644 --- a/airbyte-integrations/connectors/source-jira/unit_tests/test_date_time_transformer.py +++ b/airbyte-integrations/connectors/source-jira/unit_tests/test_date_time_transformer.py @@ -17,7 +17,7 @@ ], ) def test_converting_date_to_date_time(origin_item, sub_schema, expected, config): - stream = find_stream("issue_comments", config) + stream = find_stream("pull_requests", config) actual = stream.transformer.default_convert(origin_item, sub_schema) assert actual == expected @@ -25,7 +25,7 @@ def test_converting_date_to_date_time(origin_item, sub_schema, expected, config) def test_converting_date_with_incorrect_format_returning_original_value(config, caplog): sub_schema = {"type": "string", "format": "date-time"} incorrectly_formatted_date = "incorrectly_formatted_date" - stream = find_stream("issue_comments", config) + stream = find_stream("pull_requests", config) actual = stream.transformer.default_convert(incorrectly_formatted_date, sub_schema) assert actual == incorrectly_formatted_date assert f"{incorrectly_formatted_date}: doesn't match expected format." in caplog.text diff --git a/airbyte-integrations/connectors/source-jira/unit_tests/test_source.py b/airbyte-integrations/connectors/source-jira/unit_tests/test_source.py index 5b427df66b66..e072cc6616ed 100644 --- a/airbyte-integrations/connectors/source-jira/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-jira/unit_tests/test_source.py @@ -6,15 +6,16 @@ import pytest import responses -from airbyte_cdk.utils.traced_exception import AirbyteTracedException from source_jira.source import SourceJira +from airbyte_cdk.utils.traced_exception import AirbyteTracedException + @responses.activate def test_streams(config): - source = SourceJira() + source = SourceJira(config=config, catalog=None, state=None) streams = source.streams(config) - expected_streams_number = 55 + expected_streams_number = 56 assert len(streams) == expected_streams_number @@ -36,7 +37,7 @@ def test_check_connection_config_no_access_to_one_stream(config, caplog, project json=avatars_response, ) responses.add(responses.GET, f"https://{config['domain']}/rest/api/3/label?maxResults=50", status=401) - source = SourceJira() + source = SourceJira(config=config, catalog=None, state=None) logger_mock = MagicMock() assert source.check_connection(logger=logger_mock, config=config) == (True, None) @@ -49,7 +50,7 @@ def test_check_connection_404_error(config): status=404, ) responses.add(responses.GET, f"https://{config['domain']}/rest/api/3/label?maxResults=50", status=404) - source = SourceJira() + source = SourceJira(config=config, catalog=None, state=None) logger_mock = MagicMock() with pytest.raises(AirbyteTracedException) as e: source.check_connection(logger=logger_mock, config=config) @@ -60,7 +61,7 @@ def test_check_connection_404_error(config): def test_get_authenticator(config): - source = SourceJira() + source = SourceJira(config=config, catalog=None, state=None) authenticator = source.get_authenticator(config=config) assert authenticator.get_auth_header() == {"Authorization": "Basic ZW1haWxAZW1haWwuY29tOnRva2Vu"} diff --git a/airbyte-integrations/connectors/source-jira/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-jira/unit_tests/test_streams.py index 67ba0e26a0c1..fd4f10dfd98a 100644 --- a/airbyte-integrations/connectors/source-jira/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-jira/unit_tests/test_streams.py @@ -2,28 +2,26 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # -import re - import pendulum import pytest import responses -from airbyte_cdk.models import SyncMode -from airbyte_cdk.test.catalog_builder import CatalogBuilder -from airbyte_cdk.test.entrypoint_wrapper import read -from airbyte_cdk.utils.traced_exception import AirbyteTracedException from conftest import find_stream from responses import matchers from source_jira.source import SourceJira from source_jira.streams import IssueFields, Issues, PullRequests from source_jira.utils import read_full_refresh, read_incremental +from airbyte_cdk.models import SyncMode +from airbyte_cdk.test.catalog_builder import CatalogBuilder +from airbyte_cdk.test.entrypoint_wrapper import read +from airbyte_cdk.utils.traced_exception import AirbyteTracedException + @responses.activate def test_application_roles_stream_401_error(config, caplog): config["domain"] = "test_application_domain" responses.add(responses.GET, f"https://{config['domain']}/rest/api/3/applicationrole", status=401) - authenticator = SourceJira().get_authenticator(config=config) stream = find_stream("application_roles", config) with pytest.raises( @@ -53,9 +51,7 @@ def test_application_roles_stream_http_error(config, application_roles_response) responses.add(responses.GET, f"https://{config['domain']}/rest/api/3/applicationrole", json={"error": "not found"}, status=404) stream = find_stream("application_roles", config) - with pytest.raises( - AirbyteTracedException, match="Not found. The requested resource was not found on the server" - ): + with pytest.raises(AirbyteTracedException, match="Not found. The requested resource was not found on the server"): list(read_full_refresh(stream)) @@ -85,10 +81,7 @@ def test_board_stream_forbidden(config, boards_response, caplog): ) stream = find_stream("boards", config) - with pytest.raises( - AirbyteTracedException, - match="Forbidden. You don't have permission to access this resource." - ): + with pytest.raises(AirbyteTracedException, match="Forbidden. You don't have permission to access this resource."): list(read_full_refresh(stream)) @@ -99,7 +92,7 @@ def test_dashboards_stream(config, dashboards_response): f"https://{config['domain']}/rest/api/3/dashboard", json=dashboards_response, ) - + stream = find_stream("dashboards", config) records = list(read_full_refresh(stream)) @@ -135,14 +128,14 @@ def test_groups_stream(config, groups_response): def test_issues_fields_stream(config, mock_fields_response): stream = find_stream("issue_fields", config) records = list(read_full_refresh(stream)) - + assert len(records) == 6 assert len(responses.calls) == 1 @responses.activate def test_python_issues_fields_ids_by_name(config, mock_fields_response): - authenticator = SourceJira().get_authenticator(config=config) + authenticator = SourceJira(config=config, catalog=None, state=None).get_authenticator(config=config) args = {"authenticator": authenticator, "domain": config["domain"], "projects": config["projects"]} stream = IssueFields(**args) @@ -152,7 +145,7 @@ def test_python_issues_fields_ids_by_name(config, mock_fields_response): "Issue Type": ["issuetype"], "Parent": ["parent"], "Issue Type2": ["issuetype2"], - "Issue Type3": ["issuetype3"] + "Issue Type3": ["issuetype3"], } assert expected_ids_by_name == stream.field_ids_by_name() @@ -296,18 +289,18 @@ def test_jira_settings_stream(config, jira_settings_response): def test_board_issues_stream(config, mock_board_response, board_issues_response): responses.add( responses.GET, - f"https://{config['domain']}/rest/agile/1.0/board/1/issue?maxResults=50&fields=key&fields=created&fields=updated&jql=updated+%3E%3D+%272021%2F01%2F01+00%3A00%27", + f"https://{config['domain']}/rest/agile/1.0/board/1/issue?maxResults=50&fields=key&fields=created&fields=updated&jql=updated+%3E%3D+1609459200000", json=board_issues_response, ) responses.add( responses.GET, - f"https://{config['domain']}/rest/agile/1.0/board/2/issue?maxResults=50&fields=key&fields=created&fields=updated&jql=updated+%3E%3D+%272021%2F01%2F01+00%3A00%27", + f"https://{config['domain']}/rest/agile/1.0/board/2/issue?maxResults=50&fields=key&fields=created&fields=updated&jql=updated+%3E%3D+1609459200000", json={"errorMessages": ["This board has no columns with a mapped status."], "errors": {}}, status=500, ) responses.add( responses.GET, - f"https://{config['domain']}/rest/agile/1.0/board/3/issue?maxResults=50&fields=key&fields=created&fields=updated&jql=updated+%3E%3D+%272021%2F01%2F01+00%3A00%27", + f"https://{config['domain']}/rest/agile/1.0/board/3/issue?maxResults=50&fields=key&fields=created&fields=updated&jql=updated+%3E%3D+1609459200000", json={}, ) @@ -403,7 +396,9 @@ def test_screen_tabs_stream(config, mock_screen_response, screen_tabs_response): @responses.activate def test_sprints_stream(config, mock_board_response, mock_sprints_response): - output = read(SourceJira(), config, CatalogBuilder().with_stream("sprints", SyncMode.full_refresh).build()) + output = read( + SourceJira(config=config, catalog=None, state=None), config, CatalogBuilder().with_stream("sprints", SyncMode.full_refresh).build() + ) assert len(output.records) == 3 assert len(responses.calls) == 4 @@ -420,7 +415,7 @@ def test_board_does_not_support_sprints(config, mock_board_response, sprints_res responses.GET, f"https://{config['domain']}/rest/agile/1.0/board/2/sprint?maxResults=50", json={"errorMessages": ["The board does not support sprints"], "errors": {}}, - status=400 + status=400, ) responses.add( responses.GET, @@ -442,11 +437,15 @@ def test_board_does_not_support_sprints(config, mock_board_response, sprints_res def test_sprint_issues_stream(config, mock_board_response, mock_fields_response, mock_sprints_response, sprints_issues_response): responses.add( responses.GET, - f"https://{config['domain']}/rest/agile/1.0/sprint/2/issue?maxResults=50&fields=key&fields=status&fields=created&fields=updated&jql=updated+%3E%3D+%272021%2F01%2F01+00%3A00%27", + f"https://{config['domain']}/rest/agile/1.0/sprint/2/issue?maxResults=50&fields=key&fields=status&fields=created&fields=updated&jql=updated+%3E%3D+1609459200000", json=sprints_issues_response, ) - output = read(SourceJira(), config, CatalogBuilder().with_stream("sprint_issues", SyncMode.full_refresh).build()) + output = read( + SourceJira(config=config, catalog=None, state=None), + config, + CatalogBuilder().with_stream("sprint_issues", SyncMode.full_refresh).build(), + ) assert len(output.records) == 3 assert len(responses.calls) == 8 @@ -588,7 +587,7 @@ def test_avatars_stream_should_retry(config, caplog): responses.GET, f"https://{config['domain']}/rest/api/3/avatar/{slice}/system", json={"errorMessages": ["The error message"], "errors": {}}, - status=400 + status=400, ) stream = find_stream("avatars", config) @@ -614,7 +613,7 @@ def test_declarative_issues_stream(config, mock_projects_responses_additional_pr @responses.activate def test_python_issues_stream(config, mock_projects_responses_additional_project, mock_issues_responses_with_date_filter, caplog): - authenticator = SourceJira().get_authenticator(config=config) + authenticator = SourceJira(config=config, catalog=None, state=None).get_authenticator(config=config) args = {"authenticator": authenticator, "domain": config["domain"], "projects": config["projects"] + ["Project3"]} stream = Issues(**args) records = list(read_incremental(stream, {"updated": "2021-01-01T00:00:00Z"})) @@ -625,9 +624,11 @@ def test_python_issues_stream(config, mock_projects_responses_additional_project assert "non_empty_field" in records[0]["fields"] assert len(responses.calls) == 3 - error_message = ("Stream `issues`. An error occurred, details: The user doesn't have " - 'permission to the project. Please grant the user to the project. Errors: ' - '["The value \'3\' does not exist for the field \'project\'."]') + error_message = ( + "Stream `issues`. An error occurred, details: The user doesn't have " + "permission to the project. Please grant the user to the project. Errors: " + "[\"The value '3' does not exist for the field 'project'.\"]" + ) assert error_message in caplog.messages @@ -635,23 +636,24 @@ def test_python_issues_stream(config, mock_projects_responses_additional_project @pytest.mark.parametrize( "status_code, response_errorMessages, expected_log_message", ( - (400, - ["The value 'incorrect_project' does not exist for the field 'project'."], - ( - "Stream `issues`. An error occurred, details: The user doesn't have permission to the project." - " Please grant the user to the project. " - "Errors: [\"The value \'incorrect_project\' does not exist for the field \'project\'.\"]" - ) - ), + ( + 400, + ["The value 'incorrect_project' does not exist for the field 'project'."], ( - 403, - ["The value 'incorrect_project' doesn't have permission for the field 'project'."], - ( - 'Stream `issues`. An error occurred, details:' - ' Errors: ["The value \'incorrect_project\' doesn\'t have permission for the field \'project\'."]' - ) + "Stream `issues`. An error occurred, details: The user doesn't have permission to the project." + " Please grant the user to the project. " + "Errors: [\"The value 'incorrect_project' does not exist for the field 'project'.\"]" ), - ) + ), + ( + 403, + ["The value 'incorrect_project' doesn't have permission for the field 'project'."], + ( + "Stream `issues`. An error occurred, details:" + " Errors: [\"The value 'incorrect_project' doesn't have permission for the field 'project'.\"]" + ), + ), + ), ) def test_python_issues_stream_skip_on_http_codes_error_handling(config, status_code, response_errorMessages, expected_log_message, caplog): responses.add( @@ -667,7 +669,7 @@ def test_python_issues_stream_skip_on_http_codes_error_handling(config, status_c { "maxResults": 50, "fields": "*all", - "jql": "updated >= '2021/01/01 00:00' and project in (incorrect_project) ORDER BY updated asc", + "jql": "updated >= 1609459200000 and project in (incorrect_project) ORDER BY updated asc", "expand": "renderedFields,transitions,changelog", } ) @@ -676,7 +678,7 @@ def test_python_issues_stream_skip_on_http_codes_error_handling(config, status_c status=status_code, ) - authenticator = SourceJira().get_authenticator(config=config) + authenticator = SourceJira(config=config, catalog=None, state=None).get_authenticator(config=config) args = {"authenticator": authenticator, "domain": config["domain"], "projects": "incorrect_project"} stream = Issues(**args) @@ -687,13 +689,12 @@ def test_python_issues_stream_skip_on_http_codes_error_handling(config, status_c def test_python_issues_stream_updated_state(config): - authenticator = SourceJira().get_authenticator(config=config) + authenticator = SourceJira(config=config, catalog=None, state=None).get_authenticator(config=config) args = {"authenticator": authenticator, "domain": config["domain"], "projects": config["projects"]} stream = Issues(**args) updated_state = stream._get_updated_state( - current_stream_state={"updated": "2021-01-01T00:00:00Z"}, - latest_record={"updated": "2021-01-02T00:00:00Z"} + current_stream_state={"updated": "2021-01-01T00:00:00Z"}, latest_record={"updated": "2021-01-02T00:00:00Z"} ) assert updated_state == {"updated": "2021-01-02T00:00:00Z"} @@ -706,10 +707,10 @@ def test_python_issues_stream_updated_state(config): ("pullrequest={dataType=pullrequest, state=thestate, stateCount=1}", True), ("pullrequest={dataType=pullrequest, state=thestate, stateCount=0}", False), ("{}", False), - ) + ), ) def test_python_pull_requests_stream_has_pull_request(config, dev_field, has_pull_request): - authenticator = SourceJira().get_authenticator(config=config) + authenticator = SourceJira(config=config, catalog=None, state=None).get_authenticator(config=config) args = {"authenticator": authenticator, "domain": config["domain"], "projects": config["projects"]} issues_stream = Issues(**args) issue_fields_stream = IssueFields(**args) @@ -724,8 +725,10 @@ def test_python_pull_requests_stream_has_pull_request(config, dev_field, has_pul @responses.activate -def test_python_pull_requests_stream_has_pull_request(config, mock_fields_response, mock_projects_responses_additional_project, mock_issues_responses_with_date_filter): - authenticator = SourceJira().get_authenticator(config=config) +def test_python_pull_requests_stream_has_pull_request( + config, mock_fields_response, mock_projects_responses_additional_project, mock_issues_responses_with_date_filter +): + authenticator = SourceJira(config=config, catalog=None, state=None).get_authenticator(config=config) args = {"authenticator": authenticator, "domain": config["domain"], "projects": config["projects"]} issues_stream = Issues(**args) issue_fields_stream = IssueFields(**args) @@ -752,12 +755,12 @@ def test_python_pull_requests_stream_has_pull_request(config, mock_fields_respon "start_date, lookback_window, stream_state, expected_query", [ (pendulum.parse("2023-09-09T00:00:00Z"), 0, None, None), - (None, 10, {"updated": "2023-12-14T09:47:00"}, "updated >= '2023/12/14 09:37'"), - (None, 0, {"updated": "2023-12-14T09:47:00"}, "updated >= '2023/12/14 09:47'"), + (None, 10, {"updated": "2023-12-14T09:47:00"}, "updated >= 1702546620000"), + (None, 0, {"updated": "2023-12-14T09:47:00"}, "updated >= 1702547220000"), ], ) def test_issues_stream_jql_compare_date(config, start_date, lookback_window, stream_state, expected_query, caplog): - authenticator = SourceJira().get_authenticator(config=config) + authenticator = SourceJira(config=config, catalog=None, state=None).get_authenticator(config=config) args = { "authenticator": authenticator, "domain": config["domain"], @@ -772,7 +775,7 @@ def test_issues_stream_jql_compare_date(config, start_date, lookback_window, str def test_python_issue_comments_stream(config, mock_projects_responses, mock_issues_responses_with_date_filter, issue_comments_response): responses.add( responses.GET, - f"https://{config['domain']}/rest/api/3/issue/TESTKEY13-1/comment?maxResults=50", + f"https://{config['domain']}/rest/api/3/issue/10627/comment?maxResults=50", json=issue_comments_response, ) @@ -825,7 +828,11 @@ def test_project_permissions_stream(config, mock_non_deleted_projects_responses, @responses.activate def test_project_email_stream(config, mock_non_deleted_projects_responses, mock_project_emails): - output = read(SourceJira(), config, CatalogBuilder().with_stream("project_email", SyncMode.full_refresh).build()) + output = read( + SourceJira(config=config, catalog=None, state=None), + config, + CatalogBuilder().with_stream("project_email", SyncMode.full_refresh).build(), + ) assert len(output.records) == 2 assert len(responses.calls) == 2 @@ -839,7 +846,11 @@ def test_project_components_stream(config, mock_non_deleted_projects_responses, json=project_components_response, ) - output = read(SourceJira(), config, CatalogBuilder().with_stream("project_components", SyncMode.full_refresh).build()) + output = read( + SourceJira(config=config, catalog=None, state=None), + config, + CatalogBuilder().with_stream("project_components", SyncMode.full_refresh).build(), + ) assert len(output.records) == 2 assert len(responses.calls) == 2 @@ -853,7 +864,11 @@ def test_permissions_stream(config, permissions_response): json=permissions_response, ) - output = read(SourceJira(), config, CatalogBuilder().with_stream("permissions", SyncMode.full_refresh).build()) + output = read( + SourceJira(config=config, catalog=None, state=None), + config, + CatalogBuilder().with_stream("permissions", SyncMode.full_refresh).build(), + ) assert len(output.records) == 1 assert len(responses.calls) == 1 @@ -872,7 +887,9 @@ def test_labels_stream(config, labels_response): json={}, ) - output = read(SourceJira(), config, CatalogBuilder().with_stream("labels", SyncMode.full_refresh).build()) + output = read( + SourceJira(config=config, catalog=None, state=None), config, CatalogBuilder().with_stream("labels", SyncMode.full_refresh).build() + ) assert len(output.records) == 2 assert len(responses.calls) == 2 @@ -882,7 +899,7 @@ def test_labels_stream(config, labels_response): def test_issue_worklogs_stream(config, mock_projects_responses, mock_issues_responses_with_date_filter, issue_worklogs_response): responses.add( responses.GET, - f"https://{config['domain']}/rest/api/3/issue/TESTKEY13-1/worklog?maxResults=50", + f"https://{config['domain']}/rest/api/3/issue/10627/worklog?maxResults=50", json=issue_worklogs_response, ) @@ -946,7 +963,7 @@ def test_project_versions_stream(config, mock_non_deleted_projects_responses, pr json=projects_versions_response, ) - authenticator = SourceJira().get_authenticator(config=config) + authenticator = SourceJira(config=config, catalog=None, state=None).get_authenticator(config=config) args = {"authenticator": authenticator, "domain": config["domain"], "projects": config.get("projects", [])} stream = find_stream("project_versions", config) records = list(read_full_refresh(stream)) @@ -958,38 +975,33 @@ def test_project_versions_stream(config, mock_non_deleted_projects_responses, pr @pytest.mark.parametrize( "stream, expected_records_number, expected_calls_number, log_message", [ - ( - "issues", - 2, - 4, - "The user doesn't have permission to the project. Please grant the user to the project." - ), + ("issues", 2, 4, "The user doesn't have permission to the project. Please grant the user to the project."), ( "issue_custom_field_contexts", 2, 4, - "Not found. The requested resource was not found on the server." + "Not found. The requested resource was not found on the server.", # "Stream `issue_custom_field_contexts`. An error occurred, details: ['Not found issue custom field context for issue fields issuetype2']. Skipping for now. ", ), ( "issue_custom_field_options", 1, 6, - "Not found. The requested resource was not found on the server." + "Not found. The requested resource was not found on the server.", # "Stream `issue_custom_field_options`. An error occurred, details: ['Not found issue custom field options for issue fields issuetype3']. Skipping for now. ", ), ( "issue_watchers", 1, 6, - "Not found. The requested resource was not found on the server." + "Not found. The requested resource was not found on the server.", # "Stream `issue_watchers`. An error occurred, details: ['Not found watchers for issue TESTKEY13-2']. Skipping for now. ", ), ( "project_email", 4, 4, - "Forbidden. You don't have permission to access this resource." + "Forbidden. You don't have permission to access this resource.", # "Stream `project_email`. An error occurred, details: ['No access to emails for project 3']. Skipping for now. ", ), ], @@ -1012,7 +1024,9 @@ def test_skip_slice( log_message, ): config["projects"] = config.get("projects", []) + ["Project3", "Project4"] - output = read(SourceJira(), config, CatalogBuilder().with_stream(stream, SyncMode.full_refresh).build()) + output = read( + SourceJira(config=config, catalog=None, state=None), config, CatalogBuilder().with_stream(stream, SyncMode.full_refresh).build() + ) assert len(output.records) == expected_records_number assert len(responses.calls) == expected_calls_number diff --git a/airbyte-integrations/connectors/source-jobnimbus/README.md b/airbyte-integrations/connectors/source-jobnimbus/README.md new file mode 100644 index 000000000000..a80b59fd0a07 --- /dev/null +++ b/airbyte-integrations/connectors/source-jobnimbus/README.md @@ -0,0 +1,33 @@ +# JobNimbus +This directory contains the manifest-only connector for `source-jobnimbus`. + +The JobNimbus Airbyte connector enables seamless integration between JobNimbus, a popular CRM and project management tool, and your data pipeline. This connector allows you to automatically sync data from JobNimbus, including contacts records, task information, and more, into your preferred destination. It simplifies data extraction and helps you streamline workflows, enabling efficient analysis and reporting for enhanced business insights. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-jobnimbus:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-jobnimbus build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-jobnimbus test +``` + diff --git a/airbyte-integrations/connectors/source-jobnimbus/acceptance-test-config.yml b/airbyte-integrations/connectors/source-jobnimbus/acceptance-test-config.yml new file mode 100644 index 000000000000..fcb55d97f254 --- /dev/null +++ b/airbyte-integrations/connectors/source-jobnimbus/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-jobnimbus:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-jobnimbus/icon.svg b/airbyte-integrations/connectors/source-jobnimbus/icon.svg new file mode 100644 index 000000000000..6b9f7bf24bcd --- /dev/null +++ b/airbyte-integrations/connectors/source-jobnimbus/icon.svg @@ -0,0 +1 @@ +/Logo Vector Files (PDF, EPS, SVG)/JN_Logo SVG/2. JN_Logo_Long-Blue diff --git a/airbyte-integrations/connectors/source-jobnimbus/manifest.yaml b/airbyte-integrations/connectors/source-jobnimbus/manifest.yaml new file mode 100644 index 000000000000..1a669af03dee --- /dev/null +++ b/airbyte-integrations/connectors/source-jobnimbus/manifest.yaml @@ -0,0 +1,1274 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + The JobNimbus Airbyte connector enables seamless integration between + JobNimbus, a popular CRM and project management tool, and your data pipeline. + This connector allows you to automatically sync data from JobNimbus, including + contacts records, task information, and more, into your preferred destination. + It simplifies data extraction and helps you streamline workflows, enabling + efficient analysis and reporting for enhanced business insights. + +check: + type: CheckStream + stream_names: + - jobs + +definitions: + streams: + jobs: + type: DeclarativeStream + name: jobs + primary_key: + - jnid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /jobs + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + pagination_strategy: + type: OffsetIncrement + page_size: 1000 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/jobs" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - jnid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + pagination_strategy: + type: OffsetIncrement + page_size: 1000 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + tasks: + type: DeclarativeStream + name: tasks + primary_key: + - jnid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /tasks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: size + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tasks" + activities: + type: DeclarativeStream + name: activities + primary_key: + - jnid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /activities + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - activity + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: size + pagination_strategy: + type: OffsetIncrement + page_size: 1000 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/activities" + files: + type: DeclarativeStream + name: files + primary_key: + - jnid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /files + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - files + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: size + pagination_strategy: + type: OffsetIncrement + page_size: 1000 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/files" + base_requester: + type: HttpRequester + url_base: https://app.jobnimbus.com/api1 + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/jobs" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/tasks" + - $ref: "#/definitions/streams/activities" + - $ref: "#/definitions/streams/files" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + description: >- + API key to use. Find it by logging into your JobNimbus account, + navigating to settings, and creating a new API key under the API + section. + name: api_key + order: 0 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + jobs: true + contacts: true + tasks: true + activities: true + files: true + testedStreams: + jobs: + streamHash: bca8871c147fef7f6d0f77bfce826a62427599f3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contacts: + streamHash: 252325bb77028aaf0376b4576d2cf10e3ab87481 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tasks: + streamHash: efb1562d11b177ff66e9d91bb3cf1ba1bcb74709 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + activities: + streamHash: d1ae5b85712261b52cae2a375adaf139c96978fd + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + files: + hasRecords: true + streamHash: 8a69c7b1902db69e4a5549ec3c52e587fd48d85d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://documenter.getpostman.com/view/3919598/S11PpG4x + +schemas: + jobs: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + actual_time: + type: + - number + - "null" + address_line1: + type: + - string + - "null" + address_line2: + type: + - string + - "null" + all_day: + type: + - boolean + - "null" + all_day_end_date: + type: + - string + - "null" + all_day_start_date: + type: + - string + - "null" + approved_estimate_total: + type: + - number + - "null" + approved_invoice_due: + type: + - number + - "null" + approved_invoice_total: + type: + - number + - "null" + attachment_count: + type: + - number + - "null" + city: + type: + - string + - "null" + country_name: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_name: + type: + - string + - "null" + customer: + type: + - string + - "null" + date_created: + type: + - number + - "null" + date_end: + type: + - number + - "null" + date_start: + type: + - number + - "null" + date_status_change: + type: + - number + - "null" + date_updated: + type: + - number + - "null" + estimated_time: + type: + - number + - "null" + geo: + type: + - object + - "null" + properties: + lat: + type: + - number + - "null" + lon: + type: + - number + - "null" + is_active: + type: + - boolean + - "null" + is_archived: + type: + - boolean + - "null" + jnid: + type: string + last_budget_gross_margin: + type: + - number + - "null" + last_budget_gross_profit: + type: + - number + - "null" + last_budget_revenue: + type: + - number + - "null" + last_estimate: + type: + - number + - "null" + last_estimate_date_created: + type: + - number + - "null" + last_estimate_date_estimate: + type: + - number + - "null" + last_invoice: + type: + - number + - "null" + last_invoice_date_created: + type: + - number + - "null" + last_invoice_date_invoice: + type: + - number + - "null" + location: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + number: + type: + - string + - "null" + owners: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + parent_approved_estimate_total: + type: + - number + - "null" + parent_approved_invoice_due: + type: + - number + - "null" + parent_approved_invoice_total: + type: + - number + - "null" + parent_fax_number: + type: + - string + - "null" + parent_home_phone: + type: + - string + - "null" + parent_last_estimate: + type: + - number + - "null" + parent_last_invoice: + type: + - number + - "null" + parent_mobile_phone: + type: + - string + - "null" + parent_work_phone: + type: + - string + - "null" + primary: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + number: + type: + - string + - "null" + recid: + type: + - number + - "null" + record_type: + type: + - number + - "null" + record_type_name: + type: + - string + - "null" + related: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + number: + type: + - string + - "null" + sales_rep: + type: + - string + - "null" + sales_rep_name: + type: + - string + - "null" + state_text: + type: + - string + - "null" + status: + type: + - number + - "null" + status_name: + type: + - string + - "null" + tags: + type: + - array + - "null" + task_count: + type: + - number + - "null" + zip: + type: + - string + - "null" + required: + - jnid + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + actual_time: + type: + - number + - "null" + address_line1: + type: + - string + - "null" + address_line2: + type: + - string + - "null" + approved_estimate_total: + type: + - number + - "null" + approved_invoice_due: + type: + - number + - "null" + approved_invoice_total: + type: + - number + - "null" + attachment_count: + type: + - number + - "null" + city: + type: + - string + - "null" + company: + type: + - string + - "null" + country_name: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_name: + type: + - string + - "null" + customer: + type: + - string + - "null" + date_created: + type: + - number + - "null" + date_end: + type: + - number + - "null" + date_start: + type: + - number + - "null" + date_status_change: + type: + - number + - "null" + date_updated: + type: + - number + - "null" + disable_auto_text: + type: + - boolean + - "null" + display_name: + type: + - string + - "null" + email: + type: + - string + - "null" + estimated_time: + type: + - number + - "null" + fax_number: + type: + - string + - "null" + first_name: + type: + - string + - "null" + geo: + type: + - object + - "null" + properties: + lat: + type: + - number + - "null" + lon: + type: + - number + - "null" + home_phone: + type: + - string + - "null" + is_active: + type: + - boolean + - "null" + is_archived: + type: + - boolean + - "null" + is_sub_contractor: + type: + - boolean + - "null" + is_user: + type: + - boolean + - "null" + jnid: + type: string + last_budget_gross_margin: + type: + - number + - "null" + last_budget_gross_profit: + type: + - number + - "null" + last_budget_revenue: + type: + - number + - "null" + last_estimate: + type: + - number + - "null" + last_estimate_date_created: + type: + - number + - "null" + last_estimate_date_estimate: + type: + - number + - "null" + last_invoice: + type: + - number + - "null" + last_invoice_date_created: + type: + - number + - "null" + last_invoice_date_invoice: + type: + - number + - "null" + last_name: + type: + - string + - "null" + location: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + mobile_phone: + type: + - string + - "null" + number: + type: + - string + - "null" + owners: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + recid: + type: + - number + - "null" + record_type: + type: + - number + - "null" + record_type_name: + type: + - string + - "null" + sales_rep: + type: + - string + - "null" + sales_rep_name: + type: + - string + - "null" + state_text: + type: + - string + - "null" + status: + type: + - number + - "null" + status_name: + type: + - string + - "null" + tags: + type: + - array + - "null" + task_count: + type: + - number + - "null" + website: + type: + - string + - "null" + work_phone: + type: + - string + - "null" + zip: + type: + - string + - "null" + required: + - jnid + tasks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + actual_time: + type: + - number + - "null" + all_day: + type: + - boolean + - "null" + all_day_end_date: + type: + - string + - "null" + all_day_start_date: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_name: + type: + - string + - "null" + customer: + type: + - string + - "null" + date_created: + type: + - number + - "null" + date_end: + type: + - number + - "null" + date_start: + type: + - number + - "null" + date_updated: + type: + - number + - "null" + estimated_time: + type: + - number + - "null" + hide_from_calendarview: + type: + - boolean + - "null" + hide_from_tasklist: + type: + - boolean + - "null" + is_active: + type: + - boolean + - "null" + is_archived: + type: + - boolean + - "null" + is_completed: + type: + - boolean + - "null" + jnid: + type: string + location: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + number: + type: + - string + - "null" + owners: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + priority: + type: + - number + - "null" + recid: + type: + - number + - "null" + record_type: + type: + - number + - "null" + record_type_name: + type: + - string + - "null" + related: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + number: + type: + - string + - "null" + tags: + type: + - array + - "null" + title: + type: + - string + - "null" + required: + - jnid + activities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_name: + type: + - string + - "null" + customer: + type: + - string + - "null" + date_created: + type: + - number + - "null" + date_updated: + type: + - number + - "null" + is_active: + type: + - boolean + - "null" + is_archived: + type: + - boolean + - "null" + is_editable: + type: + - boolean + - "null" + is_status_change: + type: + - boolean + - "null" + jnid: + type: string + location: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + note: + type: + - string + - "null" + owners: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + primary: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + new_status: + type: + - number + - "null" + number: + type: + - string + - "null" + record_type: + type: + - number + - "null" + record_type_name: + type: + - string + - "null" + related: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + new_status: + type: + - number + - "null" + number: + type: + - string + - "null" + sales_rep: + type: + - string + - "null" + sales_rep_name: + type: + - string + - "null" + source: + type: + - string + - "null" + required: + - jnid + files: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + content_type: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_by_name: + type: + - string + - "null" + customer: + type: + - string + - "null" + date_created: + type: + - number + - "null" + date_file_created: + type: + - number + - "null" + date_updated: + type: + - number + - "null" + exif: + type: + - array + - "null" + filename: + type: + - string + - "null" + is_active: + type: + - boolean + - "null" + jnid: + type: string + md5: + type: + - string + - "null" + owners: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + primary: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + record_type: + type: + - number + - "null" + record_type_name: + type: + - string + - "null" + related: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + size: + type: + - number + - "null" + required: + - jnid diff --git a/airbyte-integrations/connectors/source-jobnimbus/metadata.yaml b/airbyte-integrations/connectors/source-jobnimbus/metadata.yaml new file mode 100644 index 000000000000..ed442fbfb344 --- /dev/null +++ b/airbyte-integrations/connectors/source-jobnimbus/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "app.jobnimbus.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-jobnimbus + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 0b98589b-ccee-40fd-9e9d-28d94087b4e1 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-jobnimbus + githubIssueLabel: source-jobnimbus + icon: icon.svg + license: MIT + name: JobNimbus + releaseDate: 2024-10-29 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/jobnimbus + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-jotform/metadata.yaml b/airbyte-integrations/connectors/source-jotform/metadata.yaml index 510af22e783c..dcb233edb467 100644 --- a/airbyte-integrations/connectors/source-jotform/metadata.yaml +++ b/airbyte-integrations/connectors/source-jotform/metadata.yaml @@ -16,11 +16,11 @@ data: enabled: false packageName: airbyte-source-jotform connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 3456679e-2ff2-4ef7-aa9f-da6c0cc13894 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-jotform githubIssueLabel: source-jotform icon: icon.svg diff --git a/airbyte-integrations/connectors/source-just-sift/metadata.yaml b/airbyte-integrations/connectors/source-just-sift/metadata.yaml index fa241e3bd1de..b4d291739374 100644 --- a/airbyte-integrations/connectors/source-just-sift/metadata.yaml +++ b/airbyte-integrations/connectors/source-just-sift/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-just-sift connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 27b801a1-fd34-4470-829a-bb12c63c42f9 - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-just-sift githubIssueLabel: source-just-sift icon: icon.svg diff --git a/airbyte-integrations/connectors/source-justcall/metadata.yaml b/airbyte-integrations/connectors/source-justcall/metadata.yaml index dbf857ce5a44..a724bea17ed2 100644 --- a/airbyte-integrations/connectors/source-justcall/metadata.yaml +++ b/airbyte-integrations/connectors/source-justcall/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-justcall connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 488cdc64-36cd-451d-bcfa-c6478b461e94 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-justcall githubIssueLabel: source-justcall icon: icon.svg diff --git a/airbyte-integrations/connectors/source-k6-cloud/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-k6-cloud/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-k6-cloud/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-k6-cloud/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-k6-cloud/metadata.yaml b/airbyte-integrations/connectors/source-k6-cloud/metadata.yaml index 1ec903c7b85a..5bbcf9cf2562 100644 --- a/airbyte-integrations/connectors/source-k6-cloud/metadata.yaml +++ b/airbyte-integrations/connectors/source-k6-cloud/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: e300ece7-b073-43a3-852e-8aff36a57f13 - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.8 dockerRepository: airbyte/source-k6-cloud documentationUrl: https://docs.airbyte.com/integrations/sources/k6-cloud githubIssueLabel: source-k6-cloud diff --git a/airbyte-integrations/connectors/source-kafka/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-kafka/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-kafka/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-kafka/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-kafka/metadata.yaml b/airbyte-integrations/connectors/source-kafka/metadata.yaml index e019b692e960..acb46a8f6370 100644 --- a/airbyte-integrations/connectors/source-kafka/metadata.yaml +++ b/airbyte-integrations/connectors/source-kafka/metadata.yaml @@ -1,9 +1,18 @@ data: + ab_internal: + ql: 100 + sl: 100 + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a connectorSubtype: database + connectorTestSuitesOptions: + - suite: unitTests + - suite: integrationTests connectorType: source definitionId: d917a47b-8537-4d0d-8c10-36a9928d4265 - dockerImageTag: 0.2.5 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-kafka + documentationUrl: https://docs.airbyte.com/integrations/sources/kafka githubIssueLabel: source-kafka icon: kafka.svg license: MIT @@ -14,14 +23,7 @@ data: oss: enabled: true releaseStage: alpha - documentationUrl: https://docs.airbyte.com/integrations/sources/kafka + supportLevel: community tags: - language:java - ab_internal: - sl: 100 - ql: 100 - supportLevel: community - connectorTestSuitesOptions: - - suite: unitTests - - suite: integrationTests metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-katana/metadata.yaml b/airbyte-integrations/connectors/source-katana/metadata.yaml index 56e4ae9959d7..c73ac7000231 100644 --- a/airbyte-integrations/connectors/source-katana/metadata.yaml +++ b/airbyte-integrations/connectors/source-katana/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-katana connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 7408d324-0442-488c-95e3-9d3ec1d3cf59 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-katana githubIssueLabel: source-katana icon: icon.svg diff --git a/airbyte-integrations/connectors/source-kisi/metadata.yaml b/airbyte-integrations/connectors/source-kisi/metadata.yaml index 022e8bbbcfea..34324c717c9d 100644 --- a/airbyte-integrations/connectors/source-kisi/metadata.yaml +++ b/airbyte-integrations/connectors/source-kisi/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-kisi connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 7706728b-f644-456e-8dd4-ac92c4d8f31a - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.10 dockerRepository: airbyte/source-kisi githubIssueLabel: source-kisi icon: icon.svg diff --git a/airbyte-integrations/connectors/source-kissmetrics/metadata.yaml b/airbyte-integrations/connectors/source-kissmetrics/metadata.yaml index d60688e5cfb4..c7e97f4c9bdf 100644 --- a/airbyte-integrations/connectors/source-kissmetrics/metadata.yaml +++ b/airbyte-integrations/connectors/source-kissmetrics/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-kissmetrics connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: ea2607ce-b94d-4218-83f8-724010403c9e - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-kissmetrics githubIssueLabel: source-kissmetrics icon: icon.svg diff --git a/airbyte-integrations/connectors/source-klarna/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-klarna/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-klarna/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-klarna/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-klarna/metadata.yaml b/airbyte-integrations/connectors/source-klarna/metadata.yaml index f6faebffdc47..f6495f433944 100644 --- a/airbyte-integrations/connectors/source-klarna/metadata.yaml +++ b/airbyte-integrations/connectors/source-klarna/metadata.yaml @@ -9,11 +9,11 @@ data: - api-${config.region}.klarna.com - api-${config.region}.playground.klarna.com connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 60c24725-00ae-490c-991d-55b78c3197e0 - dockerImageTag: 0.3.3 + dockerImageTag: 0.3.7 dockerRepository: airbyte/source-klarna documentationUrl: https://docs.airbyte.com/integrations/sources/klarna githubIssueLabel: source-klarna diff --git a/airbyte-integrations/connectors/source-klaus-api/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-klaus-api/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-klaus-api/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-klaus-api/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-klaviyo/acceptance-test-config.yml b/airbyte-integrations/connectors/source-klaviyo/acceptance-test-config.yml index 7c822dc32a40..c1b121625086 100644 --- a/airbyte-integrations/connectors/source-klaviyo/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-klaviyo/acceptance-test-config.yml @@ -29,7 +29,7 @@ acceptance_tests: - config_path: secrets/config.json configured_catalog_path: integration_tests/configured_catalog.json future_state: - future_state_path: integration_tests/abnormal_state.json + bypass_reason: "This test does not make sense using Concurrent CDK" skip_comprehensive_incremental_tests: true timeout_seconds: 7200 spec: diff --git a/airbyte-integrations/connectors/source-klaviyo/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-klaviyo/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-klaviyo/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-klaviyo/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-klaviyo/main.py b/airbyte-integrations/connectors/source-klaviyo/main.py index 5b8c871c3d7d..bda84b0215c4 100644 --- a/airbyte-integrations/connectors/source-klaviyo/main.py +++ b/airbyte-integrations/connectors/source-klaviyo/main.py @@ -4,5 +4,6 @@ from source_klaviyo.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-klaviyo/metadata.yaml b/airbyte-integrations/connectors/source-klaviyo/metadata.yaml index 97109a3b31ab..604421ffa3c4 100644 --- a/airbyte-integrations/connectors/source-klaviyo/metadata.yaml +++ b/airbyte-integrations/connectors/source-klaviyo/metadata.yaml @@ -7,8 +7,8 @@ data: connectorType: source definitionId: 95e8cffd-b8c4-4039-968e-d32fb4a69bde connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 - dockerImageTag: 2.10.12 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 + dockerImageTag: 2.11.7 dockerRepository: airbyte/source-klaviyo githubIssueLabel: source-klaviyo icon: klaviyo.svg diff --git a/airbyte-integrations/connectors/source-klaviyo/poetry.lock b/airbyte-integrations/connectors/source-klaviyo/poetry.lock index 500809e88eb6..32a6e2a7e52b 100644 --- a/airbyte-integrations/connectors/source-klaviyo/poetry.lock +++ b/airbyte-integrations/connectors/source-klaviyo/poetry.lock @@ -2,60 +2,65 @@ [[package]] name = "airbyte-cdk" -version = "4.6.2" +version = "6.12.4" description = "A framework for writing Airbyte Connectors." optional = false -python-versions = "<4.0,>=3.10" +python-versions = "<3.13,>=3.10" files = [ - {file = "airbyte_cdk-4.6.2-py3-none-any.whl", hash = "sha256:3a37bd96c4b4f874b15fc18839b1e163eb30d1e4ef80d7dde2854e6a48efe934"}, - {file = "airbyte_cdk-4.6.2.tar.gz", hash = "sha256:c034f11ba6abe73dd7346ce2bc7017ff71ef0db1fd1ae86fb86beaeae35d8baf"}, + {file = "airbyte_cdk-6.12.4-py3-none-any.whl", hash = "sha256:903f2c2d3be4d6595bc6c50a4625e2551308d2ca90e021bf489e0a82cf0f965d"}, + {file = "airbyte_cdk-6.12.4.tar.gz", hash = "sha256:f9f39746dec5e01a9d37255cfb45a753953227b7aafebf8f5603a6e9f943b182"}, ] [package.dependencies] -airbyte-protocol-models-pdv2 = ">=0.12.2,<0.13.0" +airbyte-protocol-models-dataclasses = ">=0.14,<0.15" backoff = "*" cachetools = "*" -cryptography = ">=42.0.5,<43.0.0" -Deprecated = ">=1.2,<1.3" +cryptography = ">=42.0.5,<44.0.0" dpath = ">=2.1.6,<3.0.0" -genson = "1.2.2" +dunamai = ">=1.22.0,<2.0.0" +genson = "1.3.0" isodate = ">=0.6.1,<0.7.0" Jinja2 = ">=3.1.2,<3.2.0" jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" +jsonschema = ">=4.17.3,<4.18.0" langchain_core = "0.1.42" -nltk = "3.8.1" +nltk = "3.9.1" +numpy = "<2" orjson = ">=3.10.7,<4.0.0" +pandas = "2.2.2" pendulum = "<3.0.0" +psutil = "6.1.0" pydantic = ">=2.7,<3.0" pyjwt = ">=2.8.0,<3.0.0" pyrate-limiter = ">=3.1.0,<3.2.0" python-dateutil = "*" -pytz = "2024.1" +python-ulid = ">=3.0.0,<4.0.0" +pytz = "2024.2" PyYAML = ">=6.0.1,<7.0.0" +rapidfuzz = ">=3.10.1,<4.0.0" requests = "*" requests_cache = "*" -wcmatch = "8.4" +serpyco-rs = ">=1.10.2,<2.0.0" +Unidecode = ">=1.3,<2.0" +wcmatch = "10.0" +xmltodict = ">=0.13.0,<0.14.0" [package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pandas (==2.2.0)", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] +file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "python-snappy (==0.7.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] +sql = ["sqlalchemy (>=2.0,!=2.0.36,<3.0)"] +vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.8.0)"] [[package]] -name = "airbyte-protocol-models-pdv2" -version = "0.12.2" -description = "Declares the Airbyte Protocol." +name = "airbyte-protocol-models-dataclasses" +version = "0.14.1" +description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models_pdv2-0.12.2-py3-none-any.whl", hash = "sha256:8b3f9d0388928547cdf2e9134c0d589e4bcaa6f63bf71a21299f6824bfb7ad0e"}, - {file = "airbyte_protocol_models_pdv2-0.12.2.tar.gz", hash = "sha256:130c9ab289f3f53749ce63ff1abbfb67a44b7e5bd2794865315a2976138b672b"}, + {file = "airbyte_protocol_models_dataclasses-0.14.1-py3-none-any.whl", hash = "sha256:dfe10b32ee09e6ba9b4f17bd309e841b61cbd61ec8f80b1937ff104efd6209a9"}, + {file = "airbyte_protocol_models_dataclasses-0.14.1.tar.gz", hash = "sha256:f62a46556b82ea0d55de144983141639e8049d836dd4e0a9d7234c5b2e103c08"}, ] -[package.dependencies] -pydantic = ">=2.7.2,<3.0.0" - [[package]] name = "annotated-types" version = "0.7.0" @@ -69,24 +74,24 @@ files = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -99,21 +104,32 @@ files = [ {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, ] +[[package]] +name = "attributes-doc" +version = "0.4.0" +description = "PEP 224 implementation" +optional = false +python-versions = ">=3.8" +files = [ + {file = "attributes-doc-0.4.0.tar.gz", hash = "sha256:b1576c94a714e9fc2c65c47cf10d0c8e1a5f7c4f5ae7f69006be108d95cbfbfb"}, + {file = "attributes_doc-0.4.0-py2.py3-none-any.whl", hash = "sha256:4c3007d9e58f3a6cb4b9c614c4d4ce2d92161581f28e594ddd8241cc3a113bdd"}, +] + [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -179,13 +195,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -269,127 +285,114 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -408,43 +411,38 @@ files = [ [[package]] name = "cryptography" -version = "42.0.8" +version = "43.0.3" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, + {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, + {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, + {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, + {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, + {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, + {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, + {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, ] [package.dependencies] @@ -457,26 +455,9 @@ nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] -[[package]] -name = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - [[package]] name = "dpath" version = "2.2.0" @@ -488,6 +469,20 @@ files = [ {file = "dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e"}, ] +[[package]] +name = "dunamai" +version = "1.23.0" +description = "Dynamic version generation" +optional = false +python-versions = ">=3.5" +files = [ + {file = "dunamai-1.23.0-py3-none-any.whl", hash = "sha256:a0906d876e92441793c6a423e16a4802752e723e9c9a5aabdc5535df02dbe041"}, + {file = "dunamai-1.23.0.tar.gz", hash = "sha256:a163746de7ea5acb6dacdab3a6ad621ebc612ed1e528aaa8beedb8887fccd2c4"}, +] + +[package.dependencies] +packaging = ">=20.9" + [[package]] name = "exceptiongroup" version = "1.2.2" @@ -518,12 +513,13 @@ python-dateutil = ">=2.7" [[package]] name = "genson" -version = "1.2.2" +version = "1.3.0" description = "GenSON is a powerful, user-friendly JSON Schema generator." optional = false python-versions = "*" files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, + {file = "genson-1.3.0-py3-none-any.whl", hash = "sha256:468feccd00274cc7e4c09e84b08704270ba8d95232aa280f65b986139cec67f7"}, + {file = "genson-1.3.0.tar.gz", hash = "sha256:e02db9ac2e3fd29e65b5286f7135762e2cd8a986537c075b06fc5f1517308e37"}, ] [[package]] @@ -539,13 +535,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -560,13 +556,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -574,7 +570,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -624,13 +619,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -688,24 +683,22 @@ files = [ [[package]] name = "jsonschema" -version = "3.2.0" +version = "4.17.3" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, ] [package.dependencies] attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" [package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] [[package]] name = "langchain-core" @@ -731,22 +724,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -819,13 +815,13 @@ files = [ [[package]] name = "nltk" -version = "3.8.1" +version = "3.9.1" description = "Natural Language Toolkit" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "nltk-3.8.1-py3-none-any.whl", hash = "sha256:fd5c9109f976fa86bcadba8f91e47f5e9293bd034474752e92a520f81c93dda5"}, - {file = "nltk-3.8.1.zip", hash = "sha256:1834da3d0682cba4f2cede2f9aad6b0fafb6461ba451db0efb6f9c39798d64d3"}, + {file = "nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1"}, + {file = "nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868"}, ] [package.dependencies] @@ -842,71 +838,133 @@ plot = ["matplotlib"] tgrep = ["pyparsing"] twitter = ["twython"] +[[package]] +name = "numpy" +version = "1.26.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, +] + [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -920,6 +978,78 @@ files = [ {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] +[[package]] +name = "pandas" +version = "2.2.2" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + [[package]] name = "pendulum" version = "2.1.2" @@ -985,6 +1115,36 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "psutil" +version = "6.1.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, +] + +[package.extras] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + [[package]] name = "py" version = "1.11.0" @@ -1009,19 +1169,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1029,100 +1189,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -1130,13 +1301,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1256,15 +1427,29 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "python-ulid" +version = "3.0.0" +description = "Universally unique lexicographically sortable identifier" +optional = false +python-versions = ">=3.9" +files = [ + {file = "python_ulid-3.0.0-py3-none-any.whl", hash = "sha256:e4c4942ff50dbd79167ad01ac725ec58f924b4018025ce22c858bfcff99a5e31"}, + {file = "python_ulid-3.0.0.tar.gz", hash = "sha256:e50296a47dc8209d28629a22fc81ca26c00982c78934bd7766377ba37ea49a9f"}, +] + +[package.extras] +pydantic = ["pydantic (>=2.0)"] + [[package]] name = "pytz" -version = "2024.1" +version = "2024.2" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, + {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, + {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, ] [[package]] @@ -1340,107 +1525,207 @@ files = [ {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] +[[package]] +name = "rapidfuzz" +version = "3.11.0" +description = "rapid fuzzy string matching" +optional = false +python-versions = ">=3.9" +files = [ + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eb8a54543d16ab1b69e2c5ed96cabbff16db044a50eddfc028000138ca9ddf33"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:231c8b2efbd7f8d2ecd1ae900363ba168b8870644bb8f2b5aa96e4a7573bde19"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54e7f442fb9cca81e9df32333fb075ef729052bcabe05b0afc0441f462299114"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:906f1f2a1b91c06599b3dd1be207449c5d4fc7bd1e1fa2f6aef161ea6223f165"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed59044aea9eb6c663112170f2399b040d5d7b162828b141f2673e822093fa8"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cb1965a28b0fa64abdee130c788a0bc0bb3cf9ef7e3a70bf055c086c14a3d7e"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b488b244931d0291412917e6e46ee9f6a14376625e150056fe7c4426ef28225"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f0ba13557fec9d5ffc0a22826754a7457cc77f1b25145be10b7bb1d143ce84c6"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3871fa7dfcef00bad3c7e8ae8d8fd58089bad6fb21f608d2bf42832267ca9663"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b2669eafee38c5884a6e7cc9769d25c19428549dcdf57de8541cf9e82822e7db"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ffa1bb0e26297b0f22881b219ffc82a33a3c84ce6174a9d69406239b14575bd5"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:45b15b8a118856ac9caac6877f70f38b8a0d310475d50bc814698659eabc1cdb"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win32.whl", hash = "sha256:22033677982b9c4c49676f215b794b0404073f8974f98739cb7234e4a9ade9ad"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:be15496e7244361ff0efcd86e52559bacda9cd975eccf19426a0025f9547c792"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_arm64.whl", hash = "sha256:714a7ba31ba46b64d30fccfe95f8013ea41a2e6237ba11a805a27cdd3bce2573"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8724a978f8af7059c5323d523870bf272a097478e1471295511cf58b2642ff83"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b63cb1f2eb371ef20fb155e95efd96e060147bdd4ab9fc400c97325dfee9fe1"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82497f244aac10b20710448645f347d862364cc4f7d8b9ba14bd66b5ce4dec18"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:339607394941801e6e3f6c1ecd413a36e18454e7136ed1161388de674f47f9d9"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84819390a36d6166cec706b9d8f0941f115f700b7faecab5a7e22fc367408bc3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eea8d9e20632d68f653455265b18c35f90965e26f30d4d92f831899d6682149b"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b659e1e2ea2784a9a397075a7fc395bfa4fe66424042161c4bcaf6e4f637b38"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1315cd2a351144572e31fe3df68340d4b83ddec0af8b2e207cd32930c6acd037"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a7743cca45b4684c54407e8638f6d07b910d8d811347b9d42ff21262c7c23245"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:5bb636b0150daa6d3331b738f7c0f8b25eadc47f04a40e5c23c4bfb4c4e20ae3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:42f4dd264ada7a9aa0805ea0da776dc063533917773cf2df5217f14eb4429eae"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:51f24cb39e64256221e6952f22545b8ce21cacd59c0d3e367225da8fc4b868d8"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win32.whl", hash = "sha256:aaf391fb6715866bc14681c76dc0308f46877f7c06f61d62cc993b79fc3c4a2a"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:ebadd5b8624d8ad503e505a99b8eb26fe3ea9f8e9c2234e805a27b269e585842"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:d895998fec712544c13cfe833890e0226585cf0391dd3948412441d5d68a2b8c"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f382fec4a7891d66fb7163c90754454030bb9200a13f82ee7860b6359f3f2fa8"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dfaefe08af2a928e72344c800dcbaf6508e86a4ed481e28355e8d4b6a6a5230e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92ebb7c12f682b5906ed98429f48a3dd80dd0f9721de30c97a01473d1a346576"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a1b3ebc62d4bcdfdeba110944a25ab40916d5383c5e57e7c4a8dc0b6c17211a"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c6d7fea39cb33e71de86397d38bf7ff1a6273e40367f31d05761662ffda49e4"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99aebef8268f2bc0b445b5640fd3312e080bd17efd3fbae4486b20ac00466308"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4469307f464ae3089acf3210b8fc279110d26d10f79e576f385a98f4429f7d97"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:eb97c53112b593f89a90b4f6218635a9d1eea1d7f9521a3b7d24864228bbc0aa"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef8937dae823b889c0273dfa0f0f6c46a3658ac0d851349c464d1b00e7ff4252"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d95f9e9f3777b96241d8a00d6377cc9c716981d828b5091082d0fe3a2924b43e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:b1d67d67f89e4e013a5295e7523bc34a7a96f2dba5dd812c7c8cb65d113cbf28"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d994cf27e2f874069884d9bddf0864f9b90ad201fcc9cb2f5b82bacc17c8d5f2"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win32.whl", hash = "sha256:ba26d87fe7fcb56c4a53b549a9e0e9143f6b0df56d35fe6ad800c902447acd5b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:b1f7efdd7b7adb32102c2fa481ad6f11923e2deb191f651274be559d56fc913b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:ed78c8e94f57b44292c1a0350f580e18d3a3c5c0800e253f1583580c1b417ad2"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e60814edd0c9b511b5f377d48b9782b88cfe8be07a98f99973669299c8bb318a"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f28952da055dbfe75828891cd3c9abf0984edc8640573c18b48c14c68ca5e06"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e8f93bc736020351a6f8e71666e1f486bb8bd5ce8112c443a30c77bfde0eb68"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76a4a11ba8f678c9e5876a7d465ab86def047a4fcc043617578368755d63a1bc"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc0e0d41ad8a056a9886bac91ff9d9978e54a244deb61c2972cc76b66752de9c"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e8ea35f2419c7d56b3e75fbde2698766daedb374f20eea28ac9b1f668ef4f74"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd340bbd025302276b5aa221dccfe43040c7babfc32f107c36ad783f2ffd8775"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:494eef2c68305ab75139034ea25328a04a548d297712d9cf887bf27c158c388b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5a167344c1d6db06915fb0225592afdc24d8bafaaf02de07d4788ddd37f4bc2f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8c7af25bda96ac799378ac8aba54a8ece732835c7b74cfc201b688a87ed11152"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d2a0f7e17f33e7890257367a1662b05fecaf56625f7dbb6446227aaa2b86448b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4d0d26c7172bdb64f86ee0765c5b26ea1dc45c52389175888ec073b9b28f4305"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win32.whl", hash = "sha256:6ad02bab756751c90fa27f3069d7b12146613061341459abf55f8190d899649f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:b1472986fd9c5d318399a01a0881f4a0bf4950264131bb8e2deba9df6d8c362b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:c408f09649cbff8da76f8d3ad878b64ba7f7abdad1471efb293d2c075e80c822"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1bac4873f6186f5233b0084b266bfb459e997f4c21fc9f029918f44a9eccd304"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f9f12c2d0aa52b86206d2059916153876a9b1cf9dfb3cf2f344913167f1c3d4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd501de6f7a8f83557d20613b58734d1cb5f0be78d794cde64fe43cfc63f5f2"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4416ca69af933d4a8ad30910149d3db6d084781d5c5fdedb713205389f535385"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f0821b9bdf18c5b7d51722b906b233a39b17f602501a966cfbd9b285f8ab83cd"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0edecc3f90c2653298d380f6ea73b536944b767520c2179ec5d40b9145e47aa"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4513dd01cee11e354c31b75f652d4d466c9440b6859f84e600bdebfccb17735a"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d9727b85511b912571a76ce53c7640ba2c44c364e71cef6d7359b5412739c570"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ab9eab33ee3213f7751dc07a1a61b8d9a3d748ca4458fffddd9defa6f0493c16"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:6b01c1ddbb054283797967ddc5433d5c108d680e8fa2684cf368be05407b07e4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:3857e335f97058c4b46fa39ca831290b70de554a5c5af0323d2f163b19c5f2a6"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d98a46cf07c0c875d27e8a7ed50f304d83063e49b9ab63f21c19c154b4c0d08d"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win32.whl", hash = "sha256:c36539ed2c0173b053dafb221458812e178cfa3224ade0960599bec194637048"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:ec8d7d8567e14af34a7911c98f5ac74a3d4a743cd848643341fc92b12b3784ff"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_arm64.whl", hash = "sha256:62171b270ecc4071be1c1f99960317db261d4c8c83c169e7f8ad119211fe7397"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f06e3c4c0a8badfc4910b9fd15beb1ad8f3b8fafa8ea82c023e5e607b66a78e4"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fe7aaf5a54821d340d21412f7f6e6272a9b17a0cbafc1d68f77f2fc11009dcd5"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25398d9ac7294e99876a3027ffc52c6bebeb2d702b1895af6ae9c541ee676702"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a52eea839e4bdc72c5e60a444d26004da00bb5bc6301e99b3dde18212e41465"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c87319b0ab9d269ab84f6453601fd49b35d9e4a601bbaef43743f26fabf496c"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3048c6ed29d693fba7d2a7caf165f5e0bb2b9743a0989012a98a47b975355cca"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b04f29735bad9f06bb731c214f27253bd8bedb248ef9b8a1b4c5bde65b838454"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7864e80a0d4e23eb6194254a81ee1216abdc53f9dc85b7f4d56668eced022eb8"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3794df87313dfb56fafd679b962e0613c88a293fd9bd5dd5c2793d66bf06a101"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d71da0012face6f45432a11bc59af19e62fac5a41f8ce489e80c0add8153c3d1"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff38378346b7018f42cbc1f6d1d3778e36e16d8595f79a312b31e7c25c50bd08"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6668321f90aa02a5a789d4e16058f2e4f2692c5230252425c3532a8a62bc3424"}, + {file = "rapidfuzz-3.11.0.tar.gz", hash = "sha256:a53ca4d3f52f00b393fab9b5913c5bafb9afc27d030c8a1db1283da6917a860f"}, +] + +[package.extras] +all = ["numpy"] + [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -1526,34 +1811,68 @@ files = [ requests = ">=2.0.1,<3.0.0" [[package]] -name = "setuptools" -version = "75.3.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" +name = "serpyco-rs" +version = "1.11.0" +description = "" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4b2bd933539bd8c84315e2fb5ae52ef7a58ace5a6dfe3f8b73f74dc71216779e"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:627f957889ff73c4d2269fc7b6bba93212381befe03633e7cb5495de66ba9a33"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b0933620abc01434023e0e3e22255b7e4ab9b427b5a9a5ee00834656d792377a"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9ce46683d92e34abb20304817fc5ac6cb141a06fc7468dedb1d8865a8a9682f6"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bda437d86e8859bf91c189c1f4650899822f6d6d7b02b48f5729da904eb7bb7d"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a72bfbd282af17ebe76d122639013e802c09902543fdbbd828fb2159ec9755e"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d4808df5384e3e8581e31a90ba7a1fa501c0837b1f174284bb8a4555b6864ea"}, + {file = "serpyco_rs-1.11.0-cp310-none-win_amd64.whl", hash = "sha256:c7b60aef4c16d68efb0d6241f05d0a434d873d98449cbb4366b0d385f0a7172b"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d47ee577cf4d69b53917615cb031ad8708eb2f59fe78194b1968c13130fc2f7"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6090d9a1487237cdd4e9362a823eede23249602019b917e7bd57846179286e79"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7192eb3df576386fefd595ea31ae25c62522841ffec7e7aeb37a80b55bdc3213"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b52ef8affb7e71b9b98a7d5216d6a7ad03b04e990acb147cd9211c8b931c5487"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3480e09e473560c60e74aaa789e6b4d079637371aae0a98235440111464bbba7"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c92e36b0ab6fe866601c2331f7e99c809a126d21963c03d8a5c29331526deed"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84f497361952d4566bc1f77e9e15a84a2614f593cc671fbf0a0fa80046f9c3d7"}, + {file = "serpyco_rs-1.11.0-cp311-none-win_amd64.whl", hash = "sha256:37fc1cf192bef9784fbf1f4e03cec21750b9e704bef55cc0442f71a715eee920"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3ea93d485f03dc8b0cfb0d477f0ad2e86e78f0461b53010656ab5b4db1b41fb0"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7772410d15694b03f9c5500a2c47d62eed76e191bea4087ad042250346b1a38e"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42118463c1679846cffd2f06f47744c9b9eb33c5d0448afd88ea19e1a81a8ddd"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:79481a455b76cc56021dc55bb6d5bdda1b2b32bcb6a1ee711b597140d112e9b1"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8fd79051f9af9591fc03cf7d3033ff180416301f6a4fd3d1e3d92ebd2d68697"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d29c8f9aeed734a3b51f7349d04ec9063516ffa4e10b632d75e9b1309e4930e4"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15609158b0d9591ffa118302cd9d0039970cb3faf91dce32975f7d276e7411d5"}, + {file = "serpyco_rs-1.11.0-cp312-none-win_amd64.whl", hash = "sha256:00081eae77fbf4c5d88371c5586317ab02ccb293a330b460869a283edf2b7b69"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3028893366a1985adcedb13fa8f6f98c087c185efc427f94c2ccdafa40f45832"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c18bf511316f3abf648a68ee62ef88617bec57d3fcde69466b4361102715ae5"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7dde9ef09cdfaf7c62378186b9e29f54ec76114be4c347be6a06dd559c5681e"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:18500ebc5e75285841e35585a238629a990b709e14f68933233640d15ca17d5f"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47c23132d4e03982703a7630aa09877b41e499722142f76b6153f6619b612f3"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5f8e6ba499f6a0825bee0d8f8764569d367af871b563fc6512c171474e8e5383"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15438a076047c34cff6601a977df54948e8d39d1a86f89d05c48bc60f4c12a61"}, + {file = "serpyco_rs-1.11.0-cp313-none-win_amd64.whl", hash = "sha256:84ee2c109415bd81904fc9abb9aec86a5dd13166808c21142cf23ec639f683bd"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5c97c16c865261577fac4effeccc7ef5e0a1e8e35e7a3ee6c90c77c3a4cd7ff9"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47825e70f86fd6ef7c4a835dea3d6e8eef4fee354ed7b39ced99f31aba74a86e"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24d220220365110edba2f778f41ab3cf396883da0f26e1361a3ada9bd0227f73"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3a46f334af5a9d77acc6e1e58f355ae497900a2798929371f0545e274f6e6166"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d72b748acce4b4e3c7c9724e1eb33d033a1c26b08a698b393e0288060e0901"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2b8b6f205e8cc038d4d30dd0e70eece7bbecc816eb2f3787c330dc2218e232d"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:038d748bfff31f150f0c3edab2766b8843edb952cb1bd3bf547886beb0912dae"}, + {file = "serpyco_rs-1.11.0-cp39-none-win_amd64.whl", hash = "sha256:0fee1c89ec2cb013dc232e4ebef88e2844357ce8631063b56639dbfb83762f20"}, + {file = "serpyco_rs-1.11.0.tar.gz", hash = "sha256:70a844615ffb229e6e89c204b3ab7404aacaf2838911814c7d847969b8da2e3a"}, ] -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +[package.dependencies] +attributes-doc = "*" +typing-extensions = "*" [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1595,20 +1914,21 @@ files = [ [[package]] name = "tqdm" -version = "4.66.6" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63"}, - {file = "tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -1624,6 +1944,28 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] +[[package]] +name = "tzdata" +version = "2024.2" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, + {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, +] + +[[package]] +name = "unidecode" +version = "1.3.8" +description = "ASCII transliterations of Unicode text" +optional = false +python-versions = ">=3.5" +files = [ + {file = "Unidecode-1.3.8-py3-none-any.whl", hash = "sha256:d130a61ce6696f8148a3bd8fe779c99adeb4b870584eeb9526584e9aa091fd39"}, + {file = "Unidecode-1.3.8.tar.gz", hash = "sha256:cfdb349d46ed3873ece4586b96aa75258726e2fa8ec21d6f00a591d98806c2f4"}, +] + [[package]] name = "url-normalize" version = "1.4.3" @@ -1640,13 +1982,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1657,98 +1999,30 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "wcmatch" -version = "8.4" +version = "10.0" description = "Wildcard/glob file name matcher." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, + {file = "wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a"}, + {file = "wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a"}, ] [package.dependencies] bracex = ">=2.1.1" [[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." +name = "xmltodict" +version = "0.13.0" +description = "Makes working with XML feel like you are working with JSON" optional = false -python-versions = ">=3.6" +python-versions = ">=3.4" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "xmltodict-0.13.0-py2.py3-none-any.whl", hash = "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"}, + {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"}, ] [metadata] lock-version = "2.0" python-versions = "^3.10,<3.12" -content-hash = "1a51c577d6a82450bc128925daa6c163cb96729a9df2835522313a6d7938f1d5" +content-hash = "3cfa2b29c444ab0c35f30ed1cc0edcf31549057ef36997fefb59774817c40e90" diff --git a/airbyte-integrations/connectors/source-klaviyo/pyproject.toml b/airbyte-integrations/connectors/source-klaviyo/pyproject.toml index 93ce160d465b..cc2944e4b9b3 100644 --- a/airbyte-integrations/connectors/source-klaviyo/pyproject.toml +++ b/airbyte-integrations/connectors/source-klaviyo/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "2.10.12" +version = "2.11.7" name = "source-klaviyo" description = "Source implementation for Klaviyo." authors = [ "Airbyte ",] @@ -17,7 +17,7 @@ include = "source_klaviyo" [tool.poetry.dependencies] python = "^3.10,<3.12" -airbyte_cdk = "^4" +airbyte_cdk = "^6" [tool.poetry.scripts] source-klaviyo = "source_klaviyo.run:run" diff --git a/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/availability_strategy.py b/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/availability_strategy.py index f7938ab9e6e7..c25c6a8c4983 100644 --- a/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/availability_strategy.py +++ b/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/availability_strategy.py @@ -5,11 +5,12 @@ import logging from typing import Dict, Optional +from requests import HTTPError, codes + from airbyte_cdk.sources import Source from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http.availability_strategy import HttpAvailabilityStrategy from airbyte_cdk.sources.streams.http.error_handlers.default_error_mapping import DEFAULT_ERROR_MAPPING -from requests import HTTPError, codes class KlaviyoAvailabilityStrategy(HttpAvailabilityStrategy): diff --git a/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/components/datetime_based_cursor.py b/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/components/datetime_based_cursor.py deleted file mode 100644 index d8580fded7d3..000000000000 --- a/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/components/datetime_based_cursor.py +++ /dev/null @@ -1,55 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - - -from dataclasses import dataclass -from typing import Any, Mapping, Optional - -from airbyte_cdk.sources.declarative.incremental import DatetimeBasedCursor -from airbyte_cdk.sources.declarative.types import StreamSlice, StreamState - - -@dataclass -class KlaviyoDatetimeBasedCursor(DatetimeBasedCursor): - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - if not stream_slice: - return {} - - field = self.cursor_field.eval(self.config) - value = stream_slice.get(self._partition_field_start.eval(self.config)) - return {"filter": f"greater-than({field},{value})", "sort": field} - - -@dataclass -class KlaviyoCheckpointDatetimeBasedCursor(DatetimeBasedCursor): - """ - You can configure the declarative stream with a step to checkpoint after the slice is completed - e.g. - incremental_sync: - type: CustomIncrementalSync - ... some configuration - step: P1M - cursor_granularity: PT1S - """ - - def get_request_params( - self, - *, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - next_page_token: Optional[Mapping[str, Any]] = None, - ) -> Mapping[str, Any]: - if not stream_slice: - return {} - - field = self.cursor_field.eval(self.config) - start_value = stream_slice.get(self._partition_field_start.eval(self.config)) - end_value = stream_slice.get(self._partition_field_end.eval(self.config)) - return {"filter": f"greater-or-equal({field},{start_value}),less-or-equal({field},{end_value})", "sort": field} diff --git a/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/components/included_fields_extractor.py b/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/components/included_fields_extractor.py index c4088bf6c7b3..bd412653d7cf 100644 --- a/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/components/included_fields_extractor.py +++ b/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/components/included_fields_extractor.py @@ -7,6 +7,7 @@ import dpath import requests + from airbyte_cdk.sources.declarative.extractors.dpath_extractor import DpathExtractor diff --git a/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/components/klaviyo_error_handler.py b/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/components/klaviyo_error_handler.py new file mode 100644 index 000000000000..411cb965fc93 --- /dev/null +++ b/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/components/klaviyo_error_handler.py @@ -0,0 +1,26 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + +from typing import Optional, Union + +import requests +from requests.exceptions import InvalidURL + +from airbyte_cdk.models import FailureType +from airbyte_cdk.sources.declarative.requesters.error_handlers import DefaultErrorHandler +from airbyte_cdk.sources.streams.http.error_handlers import ErrorResolution, ResponseAction + + +class KlaviyoErrorHandler(DefaultErrorHandler): + def interpret_response(self, response_or_exception: Optional[Union[requests.Response, Exception]]) -> ErrorResolution: + """ + We have seen `[Errno -3] Temporary failure in name resolution` a couple of times on two different connections + (1fed2ede-2d33-4543-85e3-7d6e5736075d and 1b276f7d-358a-4fe3-a437-6747fd780eed). Retrying the requests on later syncs is working + which makes it sound like a transient issue. + """ + if isinstance(response_or_exception, InvalidURL): + return ErrorResolution( + response_action=ResponseAction.RETRY, + failure_type=FailureType.transient_error, + error_message="source-klaviyo has faced a temporary DNS resolution issue. Retrying...", + ) + return super().interpret_response(response_or_exception) diff --git a/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/manifest.yaml b/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/manifest.yaml index 4ea2663b513f..c42a758884bb 100644 --- a/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/manifest.yaml +++ b/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/manifest.yaml @@ -18,7 +18,8 @@ definitions: authenticator: "#/definitions/authenticator" http_method: GET error_handler: - type: DefaultErrorHandler + type: CustomErrorHandler + class_name: source_klaviyo.components.klaviyo_error_handler.KlaviyoErrorHandler backoff_strategies: - type: WaitTimeFromHeader header: "Retry-After" @@ -100,47 +101,6 @@ definitions: path: ["updated"] value: "{{ record.get('attributes', {}).get('updated') }}" - base_incremental_stream: - $ref: "#/definitions/base_stream" - retriever: "#/definitions/base_retriever" - incremental_sync: - type: CustomIncrementalSync - class_name: source_klaviyo.components.datetime_based_cursor.KlaviyoDatetimeBasedCursor - cursor_field: "{{ parameters.get('cursor_field', 'updated') }}" - start_datetime: "{{ config.get('start_date', '2012-01-01T00:00:00Z') }}" - datetime_format: "%Y-%m-%dT%H:%M:%S%z" - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - - "%Y-%m-%dT%H:%M:%S%z" - - "%Y-%m-%d %H:%M:%S%z" - start_time_option: - type: RequestOption - field_name: "{{ parameters.get('cursor_field', 'updated') }}" - inject_into: request_parameter - - base_incremental_checkpoint_stream: - $ref: "#/definitions/base_stream" - retriever: "#/definitions/base_retriever" - incremental_sync: - type: CustomIncrementalSync - class_name: source_klaviyo.components.datetime_based_cursor.KlaviyoCheckpointDatetimeBasedCursor - cursor_field: "{{ parameters.get('cursor_field', 'updated') }}" - start_datetime: "{{ config.get('start_date', '2012-01-01T00:00:00Z') }}" - datetime_format: "%Y-%m-%dT%H:%M:%S%z" - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - - "%Y-%m-%dT%H:%M:%S%z" - - "%Y-%m-%d %H:%M:%S%z" - start_time_option: - type: RequestOption - field_name: "{{ parameters.get('cursor_field', 'updated') }}" - inject_into: request_parameter - # Syncing historical data from events endpoint can take days to sync and cause memory issues. - # Checkpoint after each slice, which means the next sync will start from the last successful slice. - # This ensures that even if the sync runs out of memory or fails, it won’t start over from the beginning. - step: P1M - cursor_granularity: PT1S - base_semi_incremental_stream: $ref: "#/definitions/base_stream" retriever: "#/definitions/semi_incremental_retriever" @@ -154,17 +114,33 @@ definitions: profiles_stream: # Docs: https://developers.klaviyo.com/en/v2023-02-22/reference/get_profiles name: "profiles" - $ref: "#/definitions/base_incremental_stream" + $ref: "#/definitions/base_stream" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: "updated" + start_datetime: "{{ config.get('start_date', '2012-01-01T00:00:00Z') }}" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%d %H:%M:%S%z" schema_loader: type: InlineSchemaLoader schema: "#/definitions/profiles_schema" retriever: $ref: "#/definitions/profiles_retriever" + requester: + $ref: "#/definitions/profiles_retriever/requester" + request_parameters: + $ref: "#/definitions/profiles_retriever/requester/request_parameters" + "filter": "greater-than({{ parameters.cursor_field }},{{ stream_interval.start_time }})" + "sort": "{{ parameters.cursor_field }}" record_selector: $ref: "#/definitions/selector" schema_normalization: Default $parameters: path: "profiles" + cursor_field: "updated" global_exclusions_stream: # Docs: https://developers.klaviyo.com/en/v2023-02-22/reference/get_profiles @@ -184,7 +160,18 @@ definitions: events_stream: # Docs: https://developers.klaviyo.com/en/reference/get_events name: "events" - $ref: "#/definitions/base_incremental_checkpoint_stream" + $ref: "#/definitions/base_stream" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: "datetime" + start_datetime: "{{ config.get('start_date', '2012-01-01T00:00:00Z') }}" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%d %H:%M:%S%z" + step: P7D + cursor_granularity: PT1S retriever: $ref: "#/definitions/base_retriever" requester: @@ -192,6 +179,8 @@ definitions: request_parameters: "fields[metric]": "name,created,updated,integration" "include": "metric" + "filter": "greater-or-equal({{ parameters.cursor_field }},{{ stream_interval.start_time }}),less-or-equal({{ parameters.cursor_field }},{{ stream_interval.end_time }})" + "sort": "{{ parameters.cursor_field }}" schema_loader: type: InlineSchemaLoader schema: "#/definitions/events_schema" @@ -208,12 +197,29 @@ definitions: email_templates_stream: # Docs: https://developers.klaviyo.com/en/reference/get_templates name: "email_templates" - $ref: "#/definitions/base_incremental_stream" + $ref: "#/definitions/base_stream" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: "updated" + start_datetime: "{{ config.get('start_date', '2012-01-01T00:00:00Z') }}" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%d %H:%M:%S%z" schema_loader: type: InlineSchemaLoader schema: "#/definitions/email_templates_schema" + retriever: + $ref: "#/definitions/base_retriever" + requester: + $ref: "#/definitions/requester" + request_parameters: + "filter": "greater-than({{ parameters.cursor_field }},{{ stream_interval.start_time }})" + "sort": "{{ parameters.cursor_field }}" $parameters: path: "templates" + cursor_field: "updated" # Semi-Incremental streams metrics_stream: @@ -262,7 +268,16 @@ definitions: events_detailed_stream: # Docs: https://developers.klaviyo.com/en/reference/get_event name: "events_detailed" - $ref: "#/definitions/base_incremental_stream" + $ref: "#/definitions/base_stream" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: "{{ parameters.get('cursor_field') }}" + start_datetime: "{{ config.get('start_date', '2012-01-01T00:00:00Z') }}" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%d %H:%M:%S%z" schema_loader: type: InlineSchemaLoader schema: "#/definitions/events_detailed_schema" @@ -279,6 +294,8 @@ definitions: request_parameters: "include": "metric" "fields[metric]": "name" + "filter": "greater-than({{ parameters.cursor_field }},{{ stream_interval.start_time }})" + "sort": "{{ parameters.cursor_field }}" state_migrations: - type: CustomStateMigration class_name: source_klaviyo.components.per_partition_state_migration.PerPartitionToSingleStateMigration @@ -975,4 +992,94 @@ spec: be improved by not fetching this field. WARNING: Enabling this setting will stop the "predictive_analytics" column from being populated in your downstream destination. order: 2 + num_workers: + type: integer + title: Number of concurrent workers + minimum: 1 + maximum: 50 + default: 10 + examples: [1, 2, 3] + description: >- + The number of worker threads to use for the sync. + The performance upper boundary is based on the limit of your Chargebee plan. + More info about the rate limit plan tiers can be found on Chargebee's API docs. + order: 3 required: ["api_key"] + +metadata: + testedStreams: + profiles: + streamHash: 7d27c2aee801ec7d0038722136c6b7e06b14a9ed + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + global_exclusions: + streamHash: 7e7633526c2855390903d6e60973bb13b23272d7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + events: + streamHash: af0180236001cbacc0788046bdc916026e1f82f6 + hasResponse: true + responsesAreSuccessful: true + hasRecords: false + primaryKeysArePresent: true + primaryKeysAreUnique: true + lists: + streamHash: 9edcccbf069463bf70bdc40db756e0f81eba032b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + email_templates: + streamHash: 4c12cf304ffe3cd0fcaba1479498ad19c18c6f32 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + metrics: + streamHash: 96e06644c47a223a29c85dc4318ec5f7da1cc414 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + lists_detailed: + streamHash: 34e4a9f1fb0c879b915d8558d67feb887d76f8e5 + hasResponse: true + responsesAreSuccessful: false + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + +# Klaviyo's rate limiting is different by endpoints: +# - XS: 1/s burst; 15/m steady +# - S: 3/s burst; 60/m steady +# - M: 10/s burst; 150/m steady +# - L: 75/s burst; 700/m steady +# - XL: 350/s burst; 3500/m steady + +# As of 2024-11-11, we have the following streams: +# | Stream | Endpoint | Klaviyo Rate Limit Size | Source Concurrency Between Streams | Source Concurrency Within Stream | Source Max Number of Threads Sharing Rate Limits | | +#|-------------------|----------------------------------------------------------------------|-------------------------|------------------------------------|---------------------------------------------------|------------------------------------------------------------------|---------------------------------------------------------------------------------| +#| profiles | https://developers.klaviyo.com/en/v2023-02-22/reference/get_profiles | M | Yes, shared with global_exclusions | No as `step` is not defined in `incremental_sync` | 2 | With other streams (global_exclusions), not within stream as `step` not defined | +#| global_exclusions | https://developers.klaviyo.com/en/v2023-02-22/reference/get_profiles | M | Yes, shared with profiles | No as `step` is not defined in `incremental_sync` | 2 | With other streams (profiles), not within stream as `step` not defined | +#| events | https://developers.klaviyo.com/en/reference/get_events | XL | Yes, shared with events_detailed | Yes | number of steps for events + number of steps for events_detailed | With other streams (events_detailed) and within stream as sliced on `datetime` | +#| events_detailed | https://developers.klaviyo.com/en/reference/get_events | XL | Yes, shared with events | Yes | number of steps for events + number of steps for events_detailed | With other streams (events) and within stream as sliced on `datetime` | +#| email_templates | https://developers.klaviyo.com/en/reference/get_templates | M | None | No as `step` is not defined in `incremental_sync` | 1 | None | +#| metrics | https://developers.klaviyo.com/en/reference/get_metrics | M | None | No as `step` is not defined in `incremental_sync` | 1 | None | +#| lists | https://developers.klaviyo.com/en/reference/get_lists | L | Yes, shared with lists_detailed | No as `step` is not defined in `incremental_sync` | 2 | With other streams (lists_detailed), not within stream as `step` not defined | +#| lists_detailed | https://developers.klaviyo.com/en/reference/get_lists | L | Yes, shared with lists | No as `step` is not defined in `incremental_sync` | 2 | With other streams (lists), not within stream as `step` not defined | +# Note: As of 2024-11-11, `metrics`, `lists` and `lists_detailed` are not supported by the Concurrent CDK as they do client side-filtering. + +# Based on the above, the only threads that allow for slicing and hence might perform more concurrent HTTP requests are `events` and `events_detailed`. There are no slicing for the others and hence the concurrency is limited by the number of streams querying the same endpoint. Given that the event endpoint is XL, we will set a default concurrency to 10. +concurrency_level: + type: ConcurrencyLevel + default_concurrency: "{{ config.get('num_workers', 10) }}" + max_concurrency: 50 diff --git a/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/run.py b/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/run.py index afcae2272e29..54eda7f3b7cd 100644 --- a/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/run.py +++ b/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/run.py @@ -4,11 +4,49 @@ import sys +import time +import traceback +from typing import List -from airbyte_cdk.entrypoint import launch +from orjson import orjson + +from airbyte_cdk.entrypoint import AirbyteEntrypoint, launch +from airbyte_cdk.models import AirbyteErrorTraceMessage, AirbyteMessage, AirbyteMessageSerializer, AirbyteTraceMessage, TraceType, Type from source_klaviyo import SourceKlaviyo -def run(): - source = SourceKlaviyo() - launch(source, sys.argv[1:]) +def _get_source(args: List[str]): + catalog_path = AirbyteEntrypoint.extract_catalog(args) + config_path = AirbyteEntrypoint.extract_config(args) + state_path = AirbyteEntrypoint.extract_state(args) + try: + return SourceKlaviyo( + SourceKlaviyo.read_catalog(catalog_path) if catalog_path else None, + SourceKlaviyo.read_config(config_path) if config_path else None, + SourceKlaviyo.read_state(state_path) if state_path else None, + ) + except Exception as error: + print( + orjson.dumps( + AirbyteMessageSerializer.dump( + AirbyteMessage( + type=Type.TRACE, + trace=AirbyteTraceMessage( + type=TraceType.ERROR, + emitted_at=time.time_ns() // 1_000_000, + error=AirbyteErrorTraceMessage( + message=f"Error starting the sync. This could be due to an invalid configuration or catalog. Please contact Support for assistance. Error: {error}", + stack_trace=traceback.format_exc(), + ), + ), + ) + ) + ).decode() + ) + raise + + +def run() -> None: + args = sys.argv[1:] + source = _get_source(args) + launch(source, args) diff --git a/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/source.py b/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/source.py index 4530024120a7..f2f535e5a89a 100644 --- a/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/source.py +++ b/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/source.py @@ -3,16 +3,18 @@ # -from typing import Any, List, Mapping +from typing import Any, List, Mapping, Optional +from airbyte_cdk import TState +from airbyte_cdk.models import ConfiguredAirbyteCatalog from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource from airbyte_cdk.sources.streams import Stream from source_klaviyo.streams import Campaigns, CampaignsDetailed, Flows class SourceKlaviyo(YamlDeclarativeSource): - def __init__(self) -> None: - super().__init__(**{"path_to_yaml": "manifest.yaml"}) + def __init__(self, catalog: Optional[ConfiguredAirbyteCatalog], config: Optional[Mapping[str, Any]], state: TState, **kwargs): + super().__init__(catalog=catalog, config=config, state=state, **{"path_to_yaml": "manifest.yaml"}) def streams(self, config: Mapping[str, Any]) -> List[Stream]: """ @@ -31,6 +33,3 @@ def streams(self, config: Mapping[str, Any]) -> List[Stream]: ] ) return streams - - def continue_sync_on_stream_failure(self) -> bool: - return True diff --git a/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/streams.py b/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/streams.py index 1cff0bffa204..487d34bc4307 100644 --- a/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/streams.py +++ b/airbyte-integrations/connectors/source-klaviyo/source_klaviyo/streams.py @@ -8,6 +8,8 @@ from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Union import pendulum +from requests import Response + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies import WaitTimeFromHeaderBackoffStrategy from airbyte_cdk.sources.streams.availability_strategy import AvailabilityStrategy @@ -16,7 +18,6 @@ from airbyte_cdk.sources.streams.http.error_handlers import BackoffStrategy, ErrorHandler, HttpStatusErrorHandler from airbyte_cdk.sources.streams.http.error_handlers.default_error_mapping import DEFAULT_ERROR_MAPPING from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, FailureType, ResponseAction -from requests import Response from .availability_strategy import KlaviyoAvailabilityStrategy from .exceptions import KlaviyoBackoffError @@ -128,7 +129,6 @@ def read_records( stream_slice: Optional[Mapping[str, Any]] = None, stream_state: Optional[Mapping[str, Any]] = None, ) -> Iterable[StreamData]: - current_state = self.state or {} try: for record in super().read_records(sync_mode, cursor_field, stream_slice, current_state): @@ -263,7 +263,6 @@ def _set_campaign_message(self, record: Mapping[str, Any]) -> None: record["campaign_message"] = campaign_message_response.json().get("data") def get_error_handler(self) -> ErrorHandler: - error_mapping = DEFAULT_ERROR_MAPPING | { 404: ErrorResolution(ResponseAction.IGNORE, FailureType.config_error, "Resource not found. Ignoring.") } diff --git a/airbyte-integrations/connectors/source-klaviyo/unit_tests/integration/config.py b/airbyte-integrations/connectors/source-klaviyo/unit_tests/integration/config.py index f6839b1a8376..a217637afe7d 100644 --- a/airbyte-integrations/connectors/source-klaviyo/unit_tests/integration/config.py +++ b/airbyte-integrations/connectors/source-klaviyo/unit_tests/integration/config.py @@ -1,11 +1,15 @@ # Copyright (c) 2024 Airbyte, Inc., all rights reserved. - +from datetime import datetime from typing import Any, Dict class KlaviyoConfigBuilder: def __init__(self) -> None: - self._config = {"api_key":"an_api_key","start_date":"2021-01-01T00:00:00Z"} + self._config = {"api_key": "an_api_key", "start_date": "2021-01-01T00:00:00Z"} + + def with_start_date(self, start_date: datetime) -> "KlaviyoConfigBuilder": + self._config["start_date"] = start_date.strftime("%Y-%m-%dT%H:%M:%SZ") + return self def build(self) -> Dict[str, Any]: return self._config diff --git a/airbyte-integrations/connectors/source-klaviyo/unit_tests/integration/test_profiles.py b/airbyte-integrations/connectors/source-klaviyo/unit_tests/integration/test_profiles.py index 87287261dcee..2395a79040fa 100644 --- a/airbyte-integrations/connectors/source-klaviyo/unit_tests/integration/test_profiles.py +++ b/airbyte-integrations/connectors/source-klaviyo/unit_tests/integration/test_profiles.py @@ -1,12 +1,14 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. - +import datetime from typing import Any, Dict, Optional from unittest import TestCase +from source_klaviyo import SourceKlaviyo + +from airbyte_cdk.models import ConfiguredAirbyteCatalog, SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest -from airbyte_cdk.test.mock_http.request import ANY_QUERY_PARAMS from airbyte_cdk.test.mock_http.response_builder import ( FieldPath, HttpResponseBuilder, @@ -16,27 +18,32 @@ create_response_builder, find_template, ) -from airbyte_protocol.models import ConfiguredAirbyteCatalog, SyncMode from integration.config import KlaviyoConfigBuilder -from source_klaviyo import SourceKlaviyo + _ENDPOINT_TEMPLATE_NAME = "profiles" +_START_DATE = datetime.datetime(2021, 1, 1, tzinfo=datetime.timezone.utc) _STREAM_NAME = "profiles" _RECORDS_PATH = FieldPath("data") def _config() -> KlaviyoConfigBuilder: - return KlaviyoConfigBuilder() + return KlaviyoConfigBuilder().with_start_date(_START_DATE) def _catalog(sync_mode: SyncMode) -> ConfiguredAirbyteCatalog: return CatalogBuilder().with_stream(_STREAM_NAME, sync_mode).build() -def _a_profile_request() -> HttpRequest: +def _a_profile_request(start_date: datetime) -> HttpRequest: return HttpRequest( url=f"https://a.klaviyo.com/api/profiles", - query_params=ANY_QUERY_PARAMS + query_params={ + "additional-fields[profile]": "predictive_analytics", + "page[size]": "100", + "filter": f"greater-than(updated,{start_date.strftime('%Y-%m-%dT%H:%M:%S%z')})", + "sort": "updated", + }, ) @@ -61,14 +68,14 @@ def _read( ) -> EntrypointOutput: catalog = _catalog(sync_mode) config = config_builder.build() - return read(SourceKlaviyo(), config, catalog, state, expecting_exception) + return read(SourceKlaviyo(catalog, config, state), config, catalog, state, expecting_exception) class FullRefreshTest(TestCase): @HttpMocker() def test_when_read_then_extract_records(self, http_mocker: HttpMocker) -> None: http_mocker.get( - _a_profile_request(), + _a_profile_request(_START_DATE), _profiles_response().with_record(_a_profile()).build(), ) @@ -79,7 +86,7 @@ def test_when_read_then_extract_records(self, http_mocker: HttpMocker) -> None: @HttpMocker() def test_given_region_is_number_when_read_then_cast_as_string(self, http_mocker: HttpMocker) -> None: http_mocker.get( - _a_profile_request(), + _a_profile_request(_START_DATE), _profiles_response().with_record(_a_profile().with_field(NestedPath(["attributes", "location", "region"]), 10)).build(), ) diff --git a/airbyte-integrations/connectors/source-klaviyo/unit_tests/test_included_extractor.py b/airbyte-integrations/connectors/source-klaviyo/unit_tests/test_included_extractor.py index 211a158290e3..df84e66f8029 100644 --- a/airbyte-integrations/connectors/source-klaviyo/unit_tests/test_included_extractor.py +++ b/airbyte-integrations/connectors/source-klaviyo/unit_tests/test_included_extractor.py @@ -34,26 +34,26 @@ def extractor(mock_config, mock_field_path, mock_decoder): return KlaviyoIncludedFieldExtractor(mock_field_path, mock_config, mock_decoder) -@patch('dpath.get') -@patch('dpath.values') +@patch("dpath.get") +@patch("dpath.values") def test_extract_records_by_path(mock_values, mock_get, extractor, mock_response, mock_decoder): - mock_values.return_value = [{'key': 'value'}] - mock_get.return_value = {'key': 'value'} - mock_decoder.decode.return_value = {'data': 'value'} + mock_values.return_value = [{"key": "value"}] + mock_get.return_value = {"key": "value"} + mock_decoder.decode.return_value = {"data": "value"} - field_paths = ['data'] + field_paths = ["data"] records = list(extractor.extract_records_by_path(mock_response, field_paths)) - assert records == [{'key': 'value'}] + assert records == [{"key": "value"}] mock_values.return_value = [] mock_get.return_value = None - records = list(extractor.extract_records_by_path(mock_response, ['included'])) + records = list(extractor.extract_records_by_path(mock_response, ["included"])) assert records == [] def test_update_target_records_with_included(extractor): - target_records = [{'relationships': {'type1': {'data': {'id': 1}}}}] - included_records = [{'id': 1, 'type': 'type1', 'attributes': {'key': 'value'}}] + target_records = [{"relationships": {"type1": {"data": {"id": 1}}}}] + included_records = [{"id": 1, "type": "type1", "attributes": {"key": "value"}}] updated_records = list(extractor.update_target_records_with_included(target_records, included_records)) - assert updated_records[0]['relationships']['type1']['data'] == {'id': 1, 'key': 'value'} + assert updated_records[0]["relationships"]["type1"]["data"] == {"id": 1, "key": "value"} diff --git a/airbyte-integrations/connectors/source-klaviyo/unit_tests/test_per_partition_state_migration.py b/airbyte-integrations/connectors/source-klaviyo/unit_tests/test_per_partition_state_migration.py index 052a93ae0f30..7cf3138d22f9 100644 --- a/airbyte-integrations/connectors/source-klaviyo/unit_tests/test_per_partition_state_migration.py +++ b/airbyte-integrations/connectors/source-klaviyo/unit_tests/test_per_partition_state_migration.py @@ -4,6 +4,8 @@ from unittest.mock import MagicMock +from source_klaviyo.components.per_partition_state_migration import PerPartitionToSingleStateMigration + from airbyte_cdk.sources.declarative.models import ( CustomRetriever, DatetimeBasedCursor, @@ -14,7 +16,7 @@ from airbyte_cdk.sources.declarative.parsers.manifest_component_transformer import ManifestComponentTransformer from airbyte_cdk.sources.declarative.parsers.manifest_reference_resolver import ManifestReferenceResolver from airbyte_cdk.sources.declarative.parsers.model_to_component_factory import ModelToComponentFactory -from source_klaviyo.components.per_partition_state_migration import PerPartitionToSingleStateMigration + factory = ModelToComponentFactory() @@ -26,14 +28,8 @@ def test_migrate_a_valid_legacy_state_to_per_partition(): input_state = { "states": [ - { - "partition": {"parent_id": "13506132"}, - "cursor": {"last_changed": "2023-12-27T08:34:39+00:00"} - }, - { - "partition": {"parent_id": "14351124"}, - "cursor": {"last_changed": "2022-12-27T08:35:39+00:00"} - }, + {"partition": {"parent_id": "13506132"}, "cursor": {"last_changed": "2023-12-27T08:34:39+00:00"}}, + {"partition": {"parent_id": "14351124"}, "cursor": {"last_changed": "2022-12-27T08:35:39+00:00"}}, ] } @@ -61,14 +57,10 @@ def _migrator(): parent_key="{{ parameters['parent_key_id'] }}", partition_field="parent_id", stream=DeclarativeStream( - type="DeclarativeStream", - retriever=CustomRetriever( - type="CustomRetriever", - class_name="a_class_name" - ) - ) + type="DeclarativeStream", retriever=CustomRetriever(type="CustomRetriever", class_name="a_class_name") + ), ) - ] + ], ) cursor = DatetimeBasedCursor( type="DatetimeBasedCursor", diff --git a/airbyte-integrations/connectors/source-klaviyo/unit_tests/test_source.py b/airbyte-integrations/connectors/source-klaviyo/unit_tests/test_source.py index 432ad99a9133..17cc35eb6352 100644 --- a/airbyte-integrations/connectors/source-klaviyo/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-klaviyo/unit_tests/test_source.py @@ -7,11 +7,23 @@ import pendulum import pytest +from integration.config import KlaviyoConfigBuilder from source_klaviyo.source import SourceKlaviyo +from airbyte_cdk.test.catalog_builder import CatalogBuilder +from airbyte_cdk.test.state_builder import StateBuilder + + logger = logging.getLogger("airbyte") +def _source() -> SourceKlaviyo: + catalog = CatalogBuilder().build() + config = KlaviyoConfigBuilder().build() + state = StateBuilder().build() + return SourceKlaviyo(catalog, config, state) + + @pytest.mark.parametrize( ("status_code", "is_connection_successful", "error_msg"), ( @@ -19,16 +31,12 @@ ( 400, False, - ( - "Bad request. Please check your request parameters." - ), + ("Bad request. Please check your request parameters."), ), ( 403, False, - ( - "Please provide a valid API key and make sure it has permissions to read specified streams." - ), + ("Please provide a valid API key and make sure it has permissions to read specified streams."), ), ), ) @@ -39,7 +47,7 @@ def test_check_connection(requests_mock, status_code, is_connection_successful, status_code=status_code, json={"end": 1, "total": 1} if 200 >= status_code < 300 else {}, ) - source = SourceKlaviyo() + source = _source() success, error = source.check_connection(logger=logger, config={"api_key": "api_key"}) assert success is is_connection_successful assert error == error_msg @@ -48,14 +56,14 @@ def test_check_connection(requests_mock, status_code, is_connection_successful, def test_check_connection_unexpected_error(requests_mock): exception_info = "Something went wrong" requests_mock.register_uri("GET", "https://a.klaviyo.com/api/metrics", exc=Exception(exception_info)) - source = SourceKlaviyo() + source = _source() success, error = source.check_connection(logger=logger, config={"api_key": "api_key"}) assert success is False assert error == f"Unable to connect to stream metrics - {exception_info}" def test_streams(): - source = SourceKlaviyo() + source = _source() config = {"api_key": "some_key", "start_date": pendulum.datetime(2020, 10, 10).isoformat()} streams = source.streams(config) expected_streams_number = 11 diff --git a/airbyte-integrations/connectors/source-klaviyo/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-klaviyo/unit_tests/test_streams.py index 196c7e736f27..f501f5aeaa68 100644 --- a/airbyte-integrations/connectors/source-klaviyo/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-klaviyo/unit_tests/test_streams.py @@ -3,6 +3,7 @@ # +import math import urllib.parse from datetime import datetime, timedelta from typing import Any, List, Mapping, Optional @@ -13,15 +14,20 @@ import pendulum import pytest import requests -from airbyte_cdk import AirbyteTracedException -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.streams import Stream from dateutil.relativedelta import relativedelta +from integration.config import KlaviyoConfigBuilder from pydantic import BaseModel from source_klaviyo.availability_strategy import KlaviyoAvailabilityStrategy from source_klaviyo.source import SourceKlaviyo from source_klaviyo.streams import Campaigns, CampaignsDetailed, IncrementalKlaviyoStream, KlaviyoStream +from airbyte_cdk import AirbyteTracedException +from airbyte_cdk.models import SyncMode +from airbyte_cdk.sources.streams import Stream +from airbyte_cdk.test.catalog_builder import CatalogBuilder +from airbyte_cdk.test.state_builder import StateBuilder + + _ANY_ATTEMPT_COUNT = 123 API_KEY = "some_key" START_DATE = pendulum.datetime(2020, 10, 10) @@ -32,17 +38,18 @@ EVENTS_STREAM_STATE_DATE = (datetime.fromisoformat(EVENTS_STREAM_CONFIG_START_DATE) + relativedelta(years=1)).isoformat() EVENTS_STREAM_TESTING_FREEZE_TIME = "2023-12-12 12:00:00" -def get_months_diff(provided_date: str) -> int: + +def get_step_diff(provided_date: str) -> int: """ - This function returns the difference in months between provided date and freeze time. + This function returns the difference in weeks between provided date and freeze time. """ provided_date = datetime.fromisoformat(provided_date).replace(tzinfo=None) freeze_date = datetime.strptime(EVENTS_STREAM_TESTING_FREEZE_TIME, "%Y-%m-%d %H:%M:%S") - difference = relativedelta(freeze_date, provided_date) - return difference.years * 12 + difference.months + return (freeze_date - provided_date).days // 7 + def get_stream_by_name(stream_name: str, config: Mapping[str, Any]) -> Stream: - source = SourceKlaviyo() + source = SourceKlaviyo(CatalogBuilder().build(), KlaviyoConfigBuilder().build(), StateBuilder().build()) matches_by_name = [stream_config for stream_config in source.streams(config) if stream_config.name == stream_name] if not matches_by_name: raise ValueError("Please provide a valid stream name.") @@ -81,9 +88,7 @@ def path(self, **kwargs) -> str: class TestKlaviyoStream: def test_request_headers(self): stream = SomeStream(api_key=API_KEY) - expected_headers = { - "Accept": "application/json", "Revision": stream.api_revision, "Authorization": f"Klaviyo-API-Key {API_KEY}" - } + expected_headers = {"Accept": "application/json", "Revision": stream.api_revision, "Authorization": f"Klaviyo-API-Key {API_KEY}"} assert stream.request_headers() == expected_headers @pytest.mark.parametrize( @@ -145,9 +150,7 @@ def test_availability_strategy(self): "This is most likely due to insufficient permissions on the credentials in use. " "Try to create and use an API key with read permission for the 'some_stream' stream granted" ) - reasons_for_unavailable_status_codes = stream.availability_strategy.reasons_for_unavailable_status_codes( - stream, None, None, None - ) + reasons_for_unavailable_status_codes = stream.availability_strategy.reasons_for_unavailable_status_codes(stream, None, None, None) assert expected_status_code in reasons_for_unavailable_status_codes assert reasons_for_unavailable_status_codes[expected_status_code] == expected_message @@ -170,14 +173,11 @@ def test_backoff_time_large_retry_after(self): response_mock.headers = {"Retry-After": retry_after} with pytest.raises(AirbyteTracedException) as e: stream.get_backoff_strategy().backoff_time(response_mock, _ANY_ATTEMPT_COUNT) - error_message = ( - "Rate limit wait time 605.0 is greater than max waiting time of 600 seconds. Stopping the stream..." - ) + error_message = "Rate limit wait time 605.0 is greater than max waiting time of 600 seconds. Stopping the stream..." assert str(e.value) == error_message class TestIncrementalKlaviyoStream: - @staticmethod def generate_api_urls(start_date_str: str) -> list[(str, str)]: """ @@ -187,24 +187,25 @@ def generate_api_urls(start_date_str: str) -> list[(str, str)]: start_date = datetime.fromisoformat(start_date_str) current_date = datetime.now(start_date.tzinfo) urls = [] + step = relativedelta(days=7) while start_date < current_date: - end_date = start_date + relativedelta(months=1) - timedelta(seconds=1) + end_date = start_date + step - timedelta(seconds=1) if end_date > current_date: end_date = current_date start_date_str = start_date.strftime("%Y-%m-%dT%H:%M:%S") + start_date.strftime("%z") end_date_str = end_date.strftime("%Y-%m-%dT%H:%M:%S") + end_date.strftime("%z") - base_url = 'https://a.klaviyo.com/api/events' + base_url = "https://a.klaviyo.com/api/events" query_params = { - 'fields[metric]': 'name,created,updated,integration', - 'include': 'metric', - 'filter': f'greater-or-equal(datetime,{start_date_str}),less-or-equal(datetime,{end_date_str})', - 'sort': 'datetime' + "fields[metric]": "name,created,updated,integration", + "include": "metric", + "filter": f"greater-or-equal(datetime,{start_date_str}),less-or-equal(datetime,{end_date_str})", + "sort": "datetime", } encoded_query = urllib.parse.urlencode(query_params) encoded_url = f"{base_url}?{encoded_query}" dummy_record = {"attributes": {"datetime": start_date_str}, "datetime": start_date_str} urls.append((encoded_url, dummy_record)) - start_date = start_date + relativedelta(months=1) + start_date = start_date + step return urls def test_cursor_field_is_required(self): @@ -285,7 +286,6 @@ def test_get_updated_state(self, config_start_date, current_cursor, latest_curso latest_record={stream.cursor_field: latest_cursor}, ) == {stream.cursor_field: expected_cursor} - @freezegun.freeze_time("2023-12-12 12:00:00") @pytest.mark.parametrize( # expected_amount_of_results: we put 1 record for every request @@ -295,18 +295,18 @@ def test_get_updated_state(self, config_start_date, current_cursor, latest_curso # we pick the state EVENTS_STREAM_CONFIG_START_DATE, EVENTS_STREAM_STATE_DATE, - get_months_diff(EVENTS_STREAM_STATE_DATE) + 1 # adding last request + get_step_diff(EVENTS_STREAM_STATE_DATE) + 1, # adding last request ), ( - # we pick the config start date - EVENTS_STREAM_CONFIG_START_DATE, - None, - get_months_diff(EVENTS_STREAM_CONFIG_START_DATE) + 1 # adding last request + # we pick the config start date + EVENTS_STREAM_CONFIG_START_DATE, + None, + get_step_diff(EVENTS_STREAM_CONFIG_START_DATE) + 1, # adding last request ), ( - "", - "", - get_months_diff(EVENTS_STREAM_DEFAULT_START_DATE) + 1 # adding last request + "", + "", + get_step_diff(EVENTS_STREAM_DEFAULT_START_DATE) + 1, # adding last request ), ), ) @@ -366,31 +366,13 @@ class TestSemiIncrementalKlaviyoStream: ) def test_read_records(self, start_date, stream_state, input_records, expected_records, requests_mock): stream = get_stream_by_name("metrics", CONFIG | {"start_date": start_date}) - requests_mock.register_uri( - "GET", f"https://a.klaviyo.com/api/metrics", status_code=200, json={"data": input_records} - ) + requests_mock.register_uri("GET", f"https://a.klaviyo.com/api/metrics", status_code=200, json={"data": input_records}) stream.stream_state = {stream.cursor_field: stream_state if stream_state else start_date} records = get_records(stream=stream, sync_mode=SyncMode.incremental) assert records == expected_records class TestProfilesStream: - - @pytest.mark.parametrize( - "disable_predictive_analytics, expected_additional_fields", - [ - pytest.param(False, {"additional-fields[profile]": "predictive_analytics"}, id="test_config_with_disable_fetching_predictive_analytics"), - pytest.param(True, {}, id="test_config_with_disable_fetching_predictive_analytics_turned_on") - ] - ) - def test_request_params(self, disable_predictive_analytics, expected_additional_fields): - if disable_predictive_analytics: - config = {"disable_fetching_predictive_analytics": True} | CONFIG - else: - config = CONFIG - stream = get_stream_by_name("profiles", config) - assert stream.retriever.requester.get_request_params() == expected_additional_fields - def test_read_records(self, requests_mock): stream = get_stream_by_name("profiles", CONFIG) json = { @@ -628,9 +610,9 @@ def test_stream_slices(self): ) def test_request_params(self, stream_state, stream_slice, next_page_token, expected_params): stream = Campaigns(api_key=API_KEY) - assert stream.request_params( - stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token - ) == expected_params + assert ( + stream.request_params(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token) == expected_params + ) class TestCampaignsDetailedStream: @@ -658,7 +640,9 @@ def test_set_recipient_count_not_found(self, requests_mock): mocked_response.ok = False mocked_response.status_code = 404 mocked_response.json.return_value = {} - with patch.object(stream._http_client, "send_request", return_value=(mock.MagicMock(spec=requests.PreparedRequest), mocked_response)): + with patch.object( + stream._http_client, "send_request", return_value=(mock.MagicMock(spec=requests.PreparedRequest), mocked_response) + ): stream._set_recipient_count(record) assert record["estimated_recipient_count"] == 0 diff --git a/airbyte-integrations/connectors/source-kyriba/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-kyriba/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-kyriba/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-kyriba/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-kyriba/main.py b/airbyte-integrations/connectors/source-kyriba/main.py index cd0b8f1f2f3e..33236c5afe07 100644 --- a/airbyte-integrations/connectors/source-kyriba/main.py +++ b/airbyte-integrations/connectors/source-kyriba/main.py @@ -4,5 +4,6 @@ from source_kyriba.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-kyriba/metadata.yaml b/airbyte-integrations/connectors/source-kyriba/metadata.yaml index 21b70fa640cf..962a46118bc6 100644 --- a/airbyte-integrations/connectors/source-kyriba/metadata.yaml +++ b/airbyte-integrations/connectors/source-kyriba/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 547dc08e-ab51-421d-953b-8f3745201a8c - dockerImageTag: 0.1.24 + dockerImageTag: 0.1.29 dockerRepository: airbyte/source-kyriba documentationUrl: https://docs.airbyte.com/integrations/sources/kyriba githubIssueLabel: source-kyriba diff --git a/airbyte-integrations/connectors/source-kyriba/poetry.lock b/airbyte-integrations/connectors/source-kyriba/poetry.lock index daa4d036e32d..1077e5f93884 100644 --- a/airbyte-integrations/connectors/source-kyriba/poetry.lock +++ b/airbyte-integrations/connectors/source-kyriba/poetry.lock @@ -62,19 +62,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -140,127 +140,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -276,20 +263,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -367,13 +354,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -486,13 +473,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -573,54 +560,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -884,33 +871,33 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -951,13 +938,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -982,81 +969,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-kyriba/pyproject.toml b/airbyte-integrations/connectors/source-kyriba/pyproject.toml index a79537a49efb..d72819cda256 100644 --- a/airbyte-integrations/connectors/source-kyriba/pyproject.toml +++ b/airbyte-integrations/connectors/source-kyriba/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.24" +version = "0.1.29" name = "source-kyriba" description = "Source implementation for Kyriba." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-kyriba/source_kyriba/source.py b/airbyte-integrations/connectors/source-kyriba/source_kyriba/source.py index cac3eb31f5cf..81155b78ea89 100644 --- a/airbyte-integrations/connectors/source-kyriba/source_kyriba/source.py +++ b/airbyte-integrations/connectors/source-kyriba/source_kyriba/source.py @@ -8,6 +8,7 @@ import backoff import requests + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream diff --git a/airbyte-integrations/connectors/source-kyriba/unit_tests/test_bank_balances_stream.py b/airbyte-integrations/connectors/source-kyriba/unit_tests/test_bank_balances_stream.py index 58ff037abc67..9e53da81f4d2 100644 --- a/airbyte-integrations/connectors/source-kyriba/unit_tests/test_bank_balances_stream.py +++ b/airbyte-integrations/connectors/source-kyriba/unit_tests/test_bank_balances_stream.py @@ -20,10 +20,7 @@ def patch_base_class(mocker): def test_stream_slices(patch_base_class): stream = BankBalancesStream(**config()) - account_uuids = [ - {"account_uuid": "first"}, - {"account_uuid": "second"} - ] + account_uuids = [{"account_uuid": "first"}, {"account_uuid": "second"}] stream.get_account_uuids = MagicMock(return_value=account_uuids) stream.start_date = date(2022, 1, 1) stream.end_date = date(2022, 1, 2) @@ -43,7 +40,7 @@ def test_stream_slices(patch_base_class): { "account_uuid": "second", "date": "2022-01-02", - } + }, ] slices = stream.stream_slices() assert slices == expected diff --git a/airbyte-integrations/connectors/source-kyriba/unit_tests/test_cash_flows.py b/airbyte-integrations/connectors/source-kyriba/unit_tests/test_cash_flows.py index ae0b83acd3a4..904b7e0564ba 100644 --- a/airbyte-integrations/connectors/source-kyriba/unit_tests/test_cash_flows.py +++ b/airbyte-integrations/connectors/source-kyriba/unit_tests/test_cash_flows.py @@ -7,10 +7,11 @@ from unittest.mock import MagicMock import requests -from airbyte_cdk.models import SyncMode from pytest import fixture from source_kyriba.source import CashFlows +from airbyte_cdk.models import SyncMode + from .test_streams import config diff --git a/airbyte-integrations/connectors/source-kyriba/unit_tests/test_incremental_streams.py b/airbyte-integrations/connectors/source-kyriba/unit_tests/test_incremental_streams.py index 5ddcaa10b8d9..cd6223667e06 100644 --- a/airbyte-integrations/connectors/source-kyriba/unit_tests/test_incremental_streams.py +++ b/airbyte-integrations/connectors/source-kyriba/unit_tests/test_incremental_streams.py @@ -3,10 +3,11 @@ # -from airbyte_cdk.models import SyncMode from pytest import fixture from source_kyriba.source import IncrementalKyribaStream +from airbyte_cdk.models import SyncMode + from .test_streams import config diff --git a/airbyte-integrations/connectors/source-kyriba/unit_tests/test_source.py b/airbyte-integrations/connectors/source-kyriba/unit_tests/test_source.py index 1bda3981cbd6..6be7e9b33a63 100644 --- a/airbyte-integrations/connectors/source-kyriba/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-kyriba/unit_tests/test_source.py @@ -6,6 +6,7 @@ from source_kyriba.source import KyribaClient, SourceKyriba + config = { "username": "username", "password": "password", @@ -13,6 +14,7 @@ "start_date": "2022-01-01", } + def test_check_connection(mocker): source = SourceKyriba() KyribaClient.login = MagicMock() diff --git a/airbyte-integrations/connectors/source-kyriba/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-kyriba/unit_tests/test_streams.py index 85f363267d8b..99d6da8a1a89 100644 --- a/airbyte-integrations/connectors/source-kyriba/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-kyriba/unit_tests/test_streams.py @@ -7,9 +7,10 @@ import pytest import requests -from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator from source_kyriba.source import KyribaClient, KyribaStream +from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator + @pytest.fixture def patch_base_class(mocker): diff --git a/airbyte-integrations/connectors/source-kyve/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-kyve/integration_tests/acceptance.py index 77f078a20c15..6b6724504678 100644 --- a/airbyte-integrations/connectors/source-kyve/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-kyve/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-kyve/main.py b/airbyte-integrations/connectors/source-kyve/main.py index a3740b34d958..cd5ae9e0c5f3 100644 --- a/airbyte-integrations/connectors/source-kyve/main.py +++ b/airbyte-integrations/connectors/source-kyve/main.py @@ -4,5 +4,6 @@ from source_kyve.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-kyve/metadata.yaml b/airbyte-integrations/connectors/source-kyve/metadata.yaml index 22ff88a7ac73..3b712ce4ce0d 100644 --- a/airbyte-integrations/connectors/source-kyve/metadata.yaml +++ b/airbyte-integrations/connectors/source-kyve/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 60a1efcc-c31c-4c63-b508-5b48b6a9f4a6 - dockerImageTag: 0.2.20 + dockerImageTag: 0.2.25 maxSecondsBetweenMessages: 7200 dockerRepository: airbyte/source-kyve githubIssueLabel: source-kyve @@ -48,5 +48,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-kyve/poetry.lock b/airbyte-integrations/connectors/source-kyve/poetry.lock index a200e9d74ec8..ca66ba1fc81d 100644 --- a/airbyte-integrations/connectors/source-kyve/poetry.lock +++ b/airbyte-integrations/connectors/source-kyve/poetry.lock @@ -62,19 +62,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -140,127 +140,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -276,20 +263,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -367,13 +354,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -486,13 +473,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -573,54 +560,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -884,33 +871,33 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -951,13 +938,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -982,81 +969,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-kyve/pyproject.toml b/airbyte-integrations/connectors/source-kyve/pyproject.toml index c58802e36c66..6a8a67d862ab 100644 --- a/airbyte-integrations/connectors/source-kyve/pyproject.toml +++ b/airbyte-integrations/connectors/source-kyve/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.2.20" +version = "0.2.25" name = "source-kyve" description = "Source implementation for KYVE." authors = [ "KYVE Core Team ",] diff --git a/airbyte-integrations/connectors/source-kyve/source_kyve/source.py b/airbyte-integrations/connectors/source-kyve/source_kyve/source.py index 2ec43d5c80db..d9f7ba7806d7 100644 --- a/airbyte-integrations/connectors/source-kyve/source_kyve/source.py +++ b/airbyte-integrations/connectors/source-kyve/source_kyve/source.py @@ -6,6 +6,7 @@ from typing import Any, List, Mapping, Tuple import requests + from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream @@ -39,7 +40,7 @@ def streams(self, config: Mapping[str, Any]) -> List[Stream]: pools = config.get("pool_ids").split(",") start_ids = config.get("start_ids").split(",") - for (pool_id, start_id) in zip(pools, start_ids): + for pool_id, start_id in zip(pools, start_ids): response = requests.get(f"{config['url_base']}/kyve/query/v1beta1/pool/{pool_id}") pool_data = response.json().get("pool").get("data") diff --git a/airbyte-integrations/connectors/source-kyve/source_kyve/stream.py b/airbyte-integrations/connectors/source-kyve/source_kyve/stream.py index 6688a5832f2f..d2096615d53a 100644 --- a/airbyte-integrations/connectors/source-kyve/source_kyve/stream.py +++ b/airbyte-integrations/connectors/source-kyve/source_kyve/stream.py @@ -8,10 +8,12 @@ from typing import Any, Iterable, Mapping, MutableMapping, Optional import requests + from airbyte_cdk.sources.streams import IncrementalMixin from airbyte_cdk.sources.streams.http import HttpStream from source_kyve.utils import query_endpoint + logger = logging.getLogger("airbyte") # 1: Arweave diff --git a/airbyte-integrations/connectors/source-kyve/unit_tests/test_incremental_streams.py b/airbyte-integrations/connectors/source-kyve/unit_tests/test_incremental_streams.py index ea824656df58..1a87d748b08f 100644 --- a/airbyte-integrations/connectors/source-kyve/unit_tests/test_incremental_streams.py +++ b/airbyte-integrations/connectors/source-kyve/unit_tests/test_incremental_streams.py @@ -3,10 +3,11 @@ # -from airbyte_cdk.models import SyncMode from pytest import fixture from source_kyve.source import KYVEStream as IncrementalKyveStream +from airbyte_cdk.models import SyncMode + from . import config, pool_data diff --git a/airbyte-integrations/connectors/source-launchdarkly/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-launchdarkly/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-launchdarkly/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-launchdarkly/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-launchdarkly/metadata.yaml b/airbyte-integrations/connectors/source-launchdarkly/metadata.yaml index 87c566263645..5e0266e54627 100644 --- a/airbyte-integrations/connectors/source-launchdarkly/metadata.yaml +++ b/airbyte-integrations/connectors/source-launchdarkly/metadata.yaml @@ -6,11 +6,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: f96bb511-5e3c-48fc-b408-547953cd81a4 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-launchdarkly githubIssueLabel: source-launchdarkly icon: launchdarkly.svg diff --git a/airbyte-integrations/connectors/source-leadfeeder/metadata.yaml b/airbyte-integrations/connectors/source-leadfeeder/metadata.yaml index 682c9e7bdbad..7354b1695fe0 100644 --- a/airbyte-integrations/connectors/source-leadfeeder/metadata.yaml +++ b/airbyte-integrations/connectors/source-leadfeeder/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-leadfeeder connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: daa0fe89-6e72-479e-a314-5e65cfc7103c - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-leadfeeder githubIssueLabel: source-leadfeeder icon: icon.svg diff --git a/airbyte-integrations/connectors/source-lemlist/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-lemlist/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-lemlist/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-lemlist/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-lemlist/metadata.yaml b/airbyte-integrations/connectors/source-lemlist/metadata.yaml index bd074c63ecd0..528a9adb52c7 100644 --- a/airbyte-integrations/connectors/source-lemlist/metadata.yaml +++ b/airbyte-integrations/connectors/source-lemlist/metadata.yaml @@ -14,9 +14,9 @@ data: connectorSubtype: api connectorType: source connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc definitionId: 789f8e7a-2d28-11ec-8d3d-0242ac130003 - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.7 dockerRepository: airbyte/source-lemlist githubIssueLabel: source-lemlist icon: lemlist.svg diff --git a/airbyte-integrations/connectors/source-less-annoying-crm/README.md b/airbyte-integrations/connectors/source-less-annoying-crm/README.md new file mode 100644 index 000000000000..c0dec2aea72e --- /dev/null +++ b/airbyte-integrations/connectors/source-less-annoying-crm/README.md @@ -0,0 +1,33 @@ +# Less Annoying CRM +This directory contains the manifest-only connector for `source-less-annoying-crm`. + +Less Annoying CRM connector enables seamless data integration, allowing users to easily sync customer relationship management data into their data warehouses or analytics tools. This connector facilitates efficient tracking of customer information, interactions, and leads, helping businesses centralize CRM data for enhanced analysis and insights. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-less-annoying-crm:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-less-annoying-crm build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-less-annoying-crm test +``` + diff --git a/airbyte-integrations/connectors/source-less-annoying-crm/acceptance-test-config.yml b/airbyte-integrations/connectors/source-less-annoying-crm/acceptance-test-config.yml new file mode 100644 index 000000000000..4b8c5b5194c2 --- /dev/null +++ b/airbyte-integrations/connectors/source-less-annoying-crm/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-less-annoying-crm:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-less-annoying-crm/icon.svg b/airbyte-integrations/connectors/source-less-annoying-crm/icon.svg new file mode 100644 index 000000000000..f0d8c5d0c361 --- /dev/null +++ b/airbyte-integrations/connectors/source-less-annoying-crm/icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/airbyte-integrations/connectors/source-less-annoying-crm/manifest.yaml b/airbyte-integrations/connectors/source-less-annoying-crm/manifest.yaml new file mode 100644 index 000000000000..637236b6df25 --- /dev/null +++ b/airbyte-integrations/connectors/source-less-annoying-crm/manifest.yaml @@ -0,0 +1,1113 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + Less Annoying CRM connector enables seamless data integration, allowing users + to easily sync customer relationship management data into their data + warehouses or analytics tools. This connector facilitates efficient tracking + of customer information, interactions, and leads, helping businesses + centralize CRM data for enhanced analysis and insights. + +check: + type: CheckStream + stream_names: + - users + +definitions: + streams: + users: + type: DeclarativeStream + name: users + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: / + http_method: POST + request_headers: + Content-Type: application/json + request_body_json: + Function: GetUsers + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: Page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: MaxNumberOfResults + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 1000 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - ContactId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: / + http_method: POST + request_headers: + Content-Type: application/json + request_body_json: + Function: GetContacts + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: Page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: MaxNumberOfResults + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 1000 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + tasks: + type: DeclarativeStream + name: tasks + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: / + http_method: POST + request_headers: + Content-Type: application/json + request_body_json: + Function: GetTasks + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Results + - "*" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: Page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: MaxNumberOfResults + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 500 + inject_on_first_request: true + incremental_sync: + type: DatetimeBasedCursor + cursor_field: DateCreated + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: StartDate + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: EndDate + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tasks" + pipeline_items: + type: DeclarativeStream + name: pipeline_items + primary_key: + - PipelineItemId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: / + http_method: POST + request_parameters: + ContactId: "{{ stream_partition.Contact }}" + request_headers: + Content-Type: application/json + request_body_json: + Function: GetPipelineItemsAttachedToContact + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - PipelineItems + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: Page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: MaxNumberOfResults + pagination_strategy: + type: PageIncrement + page_size: 500 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: ContactId + partition_field: Contact + stream: + $ref: "#/definitions/streams/contacts" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/pipeline_items" + notes: + type: DeclarativeStream + name: notes + primary_key: + - NoteId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: / + http_method: POST + request_body_json: + Function: GetNotes + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: Page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: MaxNumberOfResults + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 1000 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/notes" + teams: + type: DeclarativeStream + name: teams + primary_key: + - TeamId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: / + http_method: POST + request_body_json: + Function: GetTeams + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/teams" + events: + type: DeclarativeStream + name: events + primary_key: + - EventId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: / + http_method: POST + request_body_json: + Function: GetEvents + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: Page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: MaxNumberOfResults + pagination_strategy: + type: PageIncrement + page_size: 500 + start_from_page: 1 + inject_on_first_request: true + incremental_sync: + type: DatetimeBasedCursor + cursor_field: DateUpdated + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: StartDate + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: EndDate + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/events" + contact_events: + type: DeclarativeStream + name: contact_events + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: / + http_method: POST + request_parameters: + ContactId: "{{ stream_partition.Contact }}" + request_body_json: + Function: GetEventsAttachedToContact + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: Page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: MaxNumberOfResults + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 1000 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: ContactId + partition_field: Contact + stream: + $ref: "#/definitions/streams/contacts" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contact_events" + base_requester: + type: HttpRequester + url_base: https://api.lessannoyingcrm.com/v2 + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: Authorization + inject_into: header + +streams: + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/tasks" + - $ref: "#/definitions/streams/pipeline_items" + - $ref: "#/definitions/streams/notes" + - $ref: "#/definitions/streams/teams" + - $ref: "#/definitions/streams/events" + - $ref: "#/definitions/streams/contact_events" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - start_date + properties: + api_key: + type: string + description: >- + API key to use. Manage and create your API keys on the Programmer API + settings page at https://account.lessannoyingcrm.com/app/Settings/Api. + name: api_key + order: 0 + title: API Key + airbyte_secret: true + start_date: + type: string + order: 1 + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + additionalProperties: true + +metadata: + autoImportSchema: + users: true + contacts: true + tasks: true + pipeline_items: true + notes: true + teams: true + events: true + contact_events: true + testedStreams: + users: + streamHash: af89a02af76ebc8f42f9d97b0b4fe1690835b3dc + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contacts: + streamHash: 0840e5dd7161d8b1da73c97d5cb4e59e8c63a62e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tasks: + streamHash: baea4572b1e6b594c46ba5bf9e45d09f0af76bc2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + pipeline_items: + streamHash: c9a4bdd21c0e3a6cb561185a171d9b58a1d0f8c9 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + notes: + streamHash: e959d84d3f3f2b16cf9f817b71e81cea1aa28fa1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + teams: + streamHash: d1bb0444059525f8891bab62538a4a28bd9dee5f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + events: + streamHash: 994ab2bb72df1a89e3a50a3e17d5f805e64b87d2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contact_events: + hasRecords: true + streamHash: 73d3307bb1704e7f2297a8dad7ad84e98e2ee5ab + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: >- + https://account.lessannoyingcrm.com/api_docs/v2/Getting_Started/Introduction + +schemas: + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + FirstName: + type: + - string + - "null" + LastName: + type: + - string + - "null" + Timezone: + type: + - string + - "null" + UserId: + type: + - string + - "null" + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Address: + type: + - array + - "null" + AssignedTo: + type: + - number + - "null" + Background Info: + type: + - string + - "null" + Company Name: + type: + - string + - "null" + CompanyId: + type: + - string + - "null" + CompanyMetaData: + type: + - object + - "null" + properties: + CompanyName: + type: + - string + - "null" + ContactId: + type: string + DateCreated: + type: + - string + - "null" + Email: + type: + - array + - "null" + IsCompany: + type: + - boolean + - "null" + Job Title: + type: + - string + - "null" + LastUpdate: + type: + - string + - "null" + Name: + type: + - object + - "null" + properties: + FirstName: + type: + - string + - "null" + LastName: + type: + - string + - "null" + MiddleName: + type: + - string + - "null" + Salutation: + type: + - string + - "null" + Suffix: + type: + - string + - "null" + Phone: + type: + - array + - "null" + UserMetaData: + type: + - object + - "null" + properties: + FirstName: + type: + - string + - "null" + LastName: + type: + - string + - "null" + Website: + type: + - array + - "null" + required: + - ContactId + tasks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + AssignedTo: + type: + - string + - "null" + AssignedToMetaData: + type: + - object + - "null" + properties: + FirstName: + type: + - string + - "null" + LastName: + type: + - string + - "null" + CalendarId: + type: + - string + - "null" + ContactId: + type: + - string + - "null" + ContactMetaData: + type: + - object + - "null" + properties: + AssignedTo: + type: + - string + - "null" + Name: + type: + - string + - "null" + DateCreated: + type: string + Description: + type: + - string + - "null" + DueDate: + type: + - string + - "null" + IsCompleted: + type: + - boolean + - "null" + Name: + type: + - string + - "null" + TaskId: + type: + - string + - "null" + required: + - DateCreated + pipeline_items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + ContactId: + type: + - string + - "null" + ContactMetaData: + type: + - object + - "null" + properties: + AssignedTo: + type: + - string + - "null" + Name: + type: + - string + - "null" + CreatedBy: + type: + - string + - "null" + DateCreated: + type: + - string + - "null" + LastNote: + type: + - string + - "null" + LastUpdate: + type: + - string + - "null" + LastUpdatedBy: + type: + - string + - "null" + NumberOfUpdates: + type: + - number + - "null" + PipelineId: + type: + - string + - "null" + PipelineItemId: + type: string + PipelineMetaData: + type: + - object + - "null" + properties: + Name: + type: + - string + - "null" + StatusId: + type: + - string + - "null" + StatusMetaData: + type: + - object + - "null" + properties: + Name: + type: + - string + - "null" + required: + - PipelineItemId + notes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + ContactId: + type: + - string + - "null" + ContactMetaData: + type: + - object + - "null" + properties: + AssignedTo: + type: + - string + - "null" + Name: + type: + - string + - "null" + DateCreated: + type: + - string + - "null" + DateDisplayedInHistory: + type: + - string + - "null" + IsRichText: + type: + - boolean + - "null" + Note: + type: + - string + - "null" + NoteId: + type: string + PipelineInfo: + type: + - object + - "null" + properties: + PipelineId: + type: + - string + - "null" + PipelineItemId: + type: + - string + - "null" + PipelineMetaData: + type: + - object + - "null" + properties: + Name: + type: + - string + - "null" + StatusId: + type: + - string + - "null" + StatusMetaData: + type: + - object + - "null" + properties: + Name: + type: + - string + - "null" + UserId: + type: + - string + - "null" + UserMetaData: + type: + - object + - "null" + properties: + FirstName: + type: + - string + - "null" + LastName: + type: + - string + - "null" + required: + - NoteId + teams: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + DateCreated: + type: + - string + - "null" + Name: + type: + - string + - "null" + TeamId: + type: string + UserIds: + type: + - array + - "null" + required: + - TeamId + events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Attendees: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + AttendanceStatus: + type: + - string + - "null" + AttendeeId: + type: + - string + - "null" + IsUser: + type: + - boolean + - "null" + CalendarMetaData: + type: + - object + - "null" + properties: + Name: + type: + - string + - "null" + ContactIds: + type: + - array + - "null" + items: + type: + - string + - "null" + ContactMetaData: + type: + - array + - "null" + DateCreated: + type: + - string + - "null" + DateUpdated: + type: string + Description: + type: + - string + - "null" + EndDate: + type: + - string + - "null" + EventId: + type: string + IsAllDay: + type: + - boolean + - "null" + IsRecurring: + type: + - boolean + - "null" + Location: + type: + - string + - "null" + Name: + type: + - string + - "null" + RecurrenceRule: + type: + - string + - "null" + SeriesNumber: + type: + - number + - "null" + StartDate: + type: + - string + - "null" + UserIds: + type: + - array + - "null" + items: + type: + - string + - "null" + UserMetaData: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + FirstName: + type: + - string + - "null" + LastName: + type: + - string + - "null" + required: + - EventId + - DateUpdated + contact_events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Attendees: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + AttendanceStatus: + type: + - string + - "null" + AttendeeId: + type: + - string + - "null" + IsUser: + type: + - boolean + - "null" + CalendarMetaData: + type: + - object + - "null" + properties: + Name: + type: + - string + - "null" + ContactIds: + type: + - array + - "null" + items: + type: + - string + - "null" + ContactMetaData: + type: + - array + - "null" + DateCreated: + type: + - string + - "null" + DateUpdated: + type: + - string + - "null" + Description: + type: + - string + - "null" + EndDate: + type: + - string + - "null" + EventId: + type: + - string + - "null" + IsAllDay: + type: + - boolean + - "null" + IsRecurring: + type: + - boolean + - "null" + Location: + type: + - string + - "null" + Name: + type: + - string + - "null" + RecurrenceRule: + type: + - string + - "null" + SeriesNumber: + type: + - number + - "null" + StartDate: + type: + - string + - "null" + UserIds: + type: + - array + - "null" + items: + type: + - string + - "null" + UserMetaData: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + FirstName: + type: + - string + - "null" + LastName: + type: + - string + - "null" diff --git a/airbyte-integrations/connectors/source-less-annoying-crm/metadata.yaml b/airbyte-integrations/connectors/source-less-annoying-crm/metadata.yaml new file mode 100644 index 000000000000..4d2eccbd91b7 --- /dev/null +++ b/airbyte-integrations/connectors/source-less-annoying-crm/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.lessannoyingcrm.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-less-annoying-crm + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 96f224c5-8e85-4427-b299-dbd5c52de47c + dockerImageTag: 0.0.4 + dockerRepository: airbyte/source-less-annoying-crm + githubIssueLabel: source-less-annoying-crm + icon: icon.svg + license: MIT + name: Less Annoying CRM + releaseDate: 2024-10-31 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/less-annoying-crm + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-lever-hiring/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-lever-hiring/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-lever-hiring/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-lever-hiring/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-lightspeed-retail/README.md b/airbyte-integrations/connectors/source-lightspeed-retail/README.md new file mode 100644 index 000000000000..4112070b4902 --- /dev/null +++ b/airbyte-integrations/connectors/source-lightspeed-retail/README.md @@ -0,0 +1,41 @@ +# Lightspeed Retail +This directory contains the manifest-only connector for `source-lightspeed-retail`. + +Lightspeed Retail is a one-stop commerce platform empowering merchants around the world to simplify, scale and provide exceptional customer experiences. This source connector ingests data from the lightspeed retail API https://www.lightspeedhq.com/ + +In order to use this source, you must first create an account. +Note down the store url name as this will be needed for your subdomain name in the source. +After logging in, you can create your personal token by navigating to Setup -> Personal Token. You can learn more about the API here https://x-series-api.lightspeedhq.com/reference/listcustomers + + + + + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-lightspeed-retail:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-lightspeed-retail build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-lightspeed-retail test +``` + diff --git a/airbyte-integrations/connectors/source-lightspeed-retail/acceptance-test-config.yml b/airbyte-integrations/connectors/source-lightspeed-retail/acceptance-test-config.yml new file mode 100644 index 000000000000..b78f1c7edd9d --- /dev/null +++ b/airbyte-integrations/connectors/source-lightspeed-retail/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-lightspeed-retail:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-lightspeed-retail/icon.svg b/airbyte-integrations/connectors/source-lightspeed-retail/icon.svg new file mode 100644 index 000000000000..521016539d4c --- /dev/null +++ b/airbyte-integrations/connectors/source-lightspeed-retail/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-lightspeed-retail/manifest.yaml b/airbyte-integrations/connectors/source-lightspeed-retail/manifest.yaml new file mode 100644 index 000000000000..e51d6467bdf7 --- /dev/null +++ b/airbyte-integrations/connectors/source-lightspeed-retail/manifest.yaml @@ -0,0 +1,3073 @@ +version: 5.14.0 +type: DeclarativeSource + +description: >- + Lightspeed Retail is a one-stop commerce platform empowering merchants around + the world to simplify, scale and provide exceptional customer experiences. + This source connector ingests data from the lightspeed retail API + https://www.lightspeedhq.com/ + + + In order to use this source, you must first create an account. + + Note down the store url name as this will be needed for your subdomain name in + the source. + + After logging in, you can create your personal token by navigating to Setup -> + Personal Token. You can learn more about the API here + https://x-series-api.lightspeedhq.com/reference/listcustomers + + + + + +check: + type: CheckStream + stream_names: + - users + +definitions: + streams: + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + customers: + type: DeclarativeStream + name: customers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/customers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers" + audit: + type: DeclarativeStream + name: audit + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/security_events + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/audit" + brands: + type: DeclarativeStream + name: brands + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/brands + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/brands" + attributes: + type: DeclarativeStream + name: attributes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: api/2.0/variant_attributes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/attributes" + taxes: + type: DeclarativeStream + name: taxes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/taxes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/taxes" + tags: + type: DeclarativeStream + name: tags + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/tags + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tags" + suppliers: + type: DeclarativeStream + name: suppliers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/suppliers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/suppliers" + serial_numbers: + type: DeclarativeStream + name: serial_numbers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/serialnumbers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/serial_numbers" + sales: + type: DeclarativeStream + name: sales + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/sales + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sales" + registers: + type: DeclarativeStream + name: registers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/registers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/registers" + quotes: + type: DeclarativeStream + name: quotes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/quotes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Quotes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/quotes" + services: + type: DeclarativeStream + name: services + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/services + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - jobs + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/services" + promotions: + type: DeclarativeStream + name: promotions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/promotions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/promotions" + products: + type: DeclarativeStream + name: products + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/products + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + product_categories: + type: DeclarativeStream + name: product_categories + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/product_categories + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - data + - categories + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/product_categories" + price_books: + type: DeclarativeStream + name: price_books + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/price_book_products + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/price_books" + payment_types: + type: DeclarativeStream + name: payment_types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/payment_types + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/payment_types" + outlets: + type: DeclarativeStream + name: outlets + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/outlets + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/outlets" + inventory: + type: DeclarativeStream + name: inventory + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/inventory + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/inventory" + fulfillments: + type: DeclarativeStream + name: fulfillments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/sales/{{ stream_partition.sale_id}}/fulfillments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: sale_id + stream: + $ref: "#/definitions/streams/sales" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/fulfillments" + customer_groups: + type: DeclarativeStream + name: customer_groups + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/customer_groups + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customer_groups" + consignments: + type: DeclarativeStream + name: consignments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: api/2.0/consignments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/consignments" + consignment_products: + type: DeclarativeStream + name: consignment_products + primary_key: + - product_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/2.0/consignments/{{stream_partition.consignment_id}}/products + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"version\", {}).get(\"max\", {}) }}" + stop_condition: "{{ not response.get(\"version\", {}).get(\"max\", {}) }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: consignment_id + stream: + $ref: "#/definitions/streams/consignments" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/consignment_products" + base_requester: + type: HttpRequester + url_base: https://{{ config['subdomain'] }}.retail.lightspeed.app + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/customers" + - $ref: "#/definitions/streams/audit" + - $ref: "#/definitions/streams/brands" + - $ref: "#/definitions/streams/attributes" + - $ref: "#/definitions/streams/taxes" + - $ref: "#/definitions/streams/tags" + - $ref: "#/definitions/streams/suppliers" + - $ref: "#/definitions/streams/serial_numbers" + - $ref: "#/definitions/streams/sales" + - $ref: "#/definitions/streams/registers" + - $ref: "#/definitions/streams/quotes" + - $ref: "#/definitions/streams/services" + - $ref: "#/definitions/streams/promotions" + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/product_categories" + - $ref: "#/definitions/streams/price_books" + - $ref: "#/definitions/streams/payment_types" + - $ref: "#/definitions/streams/outlets" + - $ref: "#/definitions/streams/inventory" + - $ref: "#/definitions/streams/fulfillments" + - $ref: "#/definitions/streams/customer_groups" + - $ref: "#/definitions/streams/consignments" + - $ref: "#/definitions/streams/consignment_products" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - subdomain + properties: + api_key: + type: string + description: API key or access token + name: api_key + order: 0 + title: API Key + airbyte_secret: true + subdomain: + type: string + description: >- + The subdomain for the retailer, e.g., 'example' in + 'example.retail.lightspeed.app'. + name: subdomain + order: 1 + title: Subdomain + additionalProperties: true + +metadata: + autoImportSchema: + users: true + customers: true + audit: true + brands: true + attributes: true + taxes: true + tags: true + suppliers: true + serial_numbers: true + sales: true + registers: true + quotes: true + services: true + promotions: true + products: true + product_categories: true + price_books: true + payment_types: true + outlets: true + inventory: true + fulfillments: true + customer_groups: true + consignments: true + consignment_products: true + testedStreams: + users: + hasRecords: true + streamHash: 751b8b9148096c8a9a5f71a3b1c484a7a82025ff + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + customers: + hasRecords: true + streamHash: 1c8e045f96f8147a7cc02e9d2b675ce81ab40bf9 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + audit: + hasRecords: true + streamHash: 0c1acba4335c198ffaae74fc885fef0eef44d1bd + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + brands: + hasRecords: true + streamHash: 219cb9e7b3f744042c7f75911cdf6cd83fc70003 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + attributes: + hasRecords: true + streamHash: 7b7c892515a5014c18f7dcfa42e8fe02c7e8d0b9 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + taxes: + streamHash: e182344e7fd52ec75e8509a157fe2fa0d3f6de40 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tags: + hasRecords: true + streamHash: d690b86dcd9bd3d46c198eb6643c7f41c30e4ba9 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + suppliers: + hasRecords: true + streamHash: 176e543b6fbea2916c8c61435443795d29019f78 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + serial_numbers: + streamHash: cc91fb2d3c3205bf28412832e8140da4dca3f1fe + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + sales: + streamHash: 7c7c25c3bb7dbf52c83acfb6500ce8f36a5ffedf + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + registers: + streamHash: f3124011e7301476806fca620bba0b68ff8a1835 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + quotes: + streamHash: 40956aab86903d5e717a375d7cba8224c0a6a669 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + services: + streamHash: 772135472936f9da613e338d2aeb357d35fc9ff6 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + promotions: + streamHash: dcca98f5fef5232b2e79fc89232d77c005c8049d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + products: + streamHash: 97ab2b66a57ccf26466597cd75054e7bc9b9af6c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + product_categories: + streamHash: fbff8212ac053f90f829b87bbef87bc2b0000656 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + price_books: + streamHash: 103f8720bfe259320932e058bc56575fefd29b5c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + payment_types: + streamHash: 6194f192d0d01e781d495443ec4e06225fd49aa8 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + outlets: + streamHash: 948836b196d9d60ceb1880bdeb3216216b4e38e9 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + inventory: + streamHash: be98a57ce2c142442808e7f5ea7ea74be3318fe9 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + fulfillments: + streamHash: 48a4341d944e53bc273fe4741da982db1026f8d4 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + customer_groups: + streamHash: 6dbcbaad97892a867e06606fcfb8a6db90839e9e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + consignments: + streamHash: 72df1dcc5cea93af7a72f1d7323fcfdb6d05e4ab + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + consignment_products: + streamHash: c8fdf41124665c0b50ae4eab1dde61423d9d8c46 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://x-series-api.lightspeedhq.com/docs/quick_start + +schemas: + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + account_type: + type: + - string + - "null" + created_at: + type: + - string + - "null" + display_name: + type: + - string + - "null" + email: + type: + - string + - "null" + email_verified_at: + type: + - string + - "null" + enabled: + type: + - boolean + - "null" + id: + type: string + image_source: + type: + - string + - "null" + is_primary_user: + type: + - boolean + - "null" + require_password_change: + type: + - boolean + - "null" + restricted_outlet_ids: + type: + - array + - "null" + roles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + system_role_id: + type: + - string + - "null" + rules: + type: + - object + - "null" + seen_at: + type: + - string + - "null" + switch_id: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + username: + type: + - string + - "null" + required: + - id + customers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + balance: + type: + - number + - "null" + created_at: + type: + - string + - "null" + customer_code: + type: + - string + - "null" + customer_group_id: + type: + - string + - "null" + customer_group_ids: + type: + - array + - "null" + items: + type: + - string + - "null" + do_not_email: + type: + - boolean + - "null" + enable_loyalty: + type: + - boolean + - "null" + id: + type: string + loyalty_balance: + type: + - number + - "null" + loyalty_email_sent: + type: + - boolean + - "null" + updated_at: + type: + - string + - "null" + year_to_date: + type: + - number + - "null" + required: + - id + audit: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + action: + type: + - string + - "null" + created_at: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + authentication_id: + type: + - string + - "null" + occurred_at: + type: + - string + - "null" + token_id: + type: + - string + - "null" + id: + type: string + ip_address: + type: + - string + - "null" + occurred_at: + type: + - string + - "null" + user_agent: + type: + - string + - "null" + user_id: + type: + - string + - "null" + required: + - id + brands: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + id: + type: string + name: + type: + - string + - "null" + required: + - id + attributes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: string + is_deprecated: + type: + - boolean + - "null" + name: + type: + - string + - "null" + required: + - id + taxes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + display_name: + type: + - string + - "null" + id: + type: string + is_default: + type: + - boolean + - "null" + name: + type: + - string + - "null" + rates: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + display_name: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + rate: + type: + - number + - "null" + rules: + type: + - array + - "null" + required: + - id + tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + id: + type: string + name: + type: + - string + - "null" + required: + - id + suppliers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + contact: + type: + - object + - "null" + properties: + company_name: + type: + - string + - "null" + default_markup: + type: + - number + - "null" + id: + type: string + name: + type: + - string + - "null" + source: + type: + - string + - "null" + required: + - id + serial_numbers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + code: + type: + - string + - "null" + id: + type: string + outlet_id: + type: + - string + - "null" + product_id: + type: + - string + - "null" + required: + - id + sales: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + adjustments: + type: + - array + - "null" + attributes: + type: + - array + - "null" + items: + type: + - string + - "null" + created_at: + type: + - string + - "null" + customer_id: + type: + - string + - "null" + external_applications: + type: + - array + - "null" + id: + type: string + invoice_number: + type: + - string + - "null" + line_items: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + cost: + type: + - number + - "null" + cost_total: + type: + - number + - "null" + discount: + type: + - number + - "null" + discount_total: + type: + - number + - "null" + id: + type: + - string + - "null" + is_return: + type: + - boolean + - "null" + loyalty_value: + type: + - number + - "null" + price: + type: + - number + - "null" + price_set: + type: + - boolean + - "null" + price_total: + type: + - number + - "null" + product_id: + type: + - string + - "null" + promotions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + amount: + type: + - number + - "null" + name: + type: + - string + - "null" + promo_code: + type: + - string + - "null" + promo_code_id: + type: + - string + - "null" + promotion_id: + type: + - string + - "null" + quantity: + type: + - number + - "null" + sequence: + type: + - number + - "null" + status: + type: + - string + - "null" + surcharges: + type: + - array + - "null" + tax: + type: + - number + - "null" + tax_components: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + rate_id: + type: + - string + - "null" + total_tax: + type: + - number + - "null" + tax_id: + type: + - string + - "null" + tax_total: + type: + - number + - "null" + total_cost: + type: + - number + - "null" + total_discount: + type: + - number + - "null" + total_loyalty_value: + type: + - number + - "null" + total_price: + type: + - number + - "null" + total_tax: + type: + - number + - "null" + unit_cost: + type: + - number + - "null" + unit_discount: + type: + - number + - "null" + unit_loyalty_value: + type: + - number + - "null" + unit_price: + type: + - number + - "null" + unit_tax: + type: + - number + - "null" + note: + type: + - string + - "null" + outlet_id: + type: + - string + - "null" + payments: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + amount: + type: + - number + - "null" + external_applications: + type: + - array + - "null" + external_attributes: + type: + - array + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + outlet_id: + type: + - string + - "null" + payment_date: + type: + - string + - "null" + payment_type_id: + type: + - string + - "null" + register_id: + type: + - string + - "null" + register_open_sequence_id: + type: + - string + - "null" + retailer_payment_type_id: + type: + - string + - "null" + receipt_number: + type: + - string + - "null" + register_id: + type: + - string + - "null" + return_ids: + type: + - array + - "null" + sale_date: + type: + - string + - "null" + short_code: + type: + - string + - "null" + source: + type: + - string + - "null" + status: + type: + - string + - "null" + taxes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + amount: + type: + - number + - "null" + id: + type: + - string + - "null" + total_loyalty: + type: + - number + - "null" + total_price: + type: + - number + - "null" + total_price_incl: + type: + - number + - "null" + total_surcharge: + type: + - number + - "null" + total_tax: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + user_id: + type: + - string + - "null" + required: + - id + registers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + ask_for_note_on_save: + type: + - number + - "null" + ask_for_user_on_sale: + type: + - boolean + - "null" + attributes: + type: + - array + - "null" + button_layout_id: + type: + - string + - "null" + cash_managed_payment_type_id: + type: + - string + - "null" + email_receipt: + type: + - boolean + - "null" + id: + type: string + invoice_prefix: + type: + - string + - "null" + invoice_sequence: + type: + - number + - "null" + invoice_suffix: + type: + - string + - "null" + is_open: + type: + - boolean + - "null" + is_quick_keys_enabled: + type: + - boolean + - "null" + name: + type: + - string + - "null" + outlet_id: + type: + - string + - "null" + print_note_on_receipt: + type: + - boolean + - "null" + print_receipt: + type: + - boolean + - "null" + receipt_template_id: + type: + - string + - "null" + register_close_time: + type: + - string + - "null" + register_open_sequence_id: + type: + - string + - "null" + show_discounts_on_receipts: + type: + - boolean + - "null" + required: + - id + quotes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + customer_id: + type: + - string + - "null" + expired_at: + type: + - string + - "null" + id: + type: string + loyalty: + type: + - number + - "null" + note: + type: + - string + - "null" + outlet_id: + type: + - string + - "null" + products: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + discount: + type: + - number + - "null" + id: + type: + - string + - "null" + note: + type: + - string + - "null" + price: + type: + - number + - "null" + product_id: + type: + - string + - "null" + product_tax_components: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + quote_product_id: + type: + - string + - "null" + rate_id: + type: + - string + - "null" + total_tax: + type: + - number + - "null" + quantity: + type: + - number + - "null" + quote_id: + type: + - string + - "null" + salesperson_id: + type: + - string + - "null" + sequence: + type: + - number + - "null" + tax: + type: + - number + - "null" + tax_id: + type: + - string + - "null" + register_id: + type: + - string + - "null" + retailer_id: + type: + - string + - "null" + short_code: + type: + - string + - "null" + status: + type: + - string + - "null" + total_price: + type: + - number + - "null" + total_tax: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + user_id: + type: + - string + - "null" + required: + - id + services: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + agenda: + type: + - object + - "null" + properties: + date: + type: + - string + - "null" + minutes_scheduled: + type: + - number + - "null" + created_at: + type: + - string + - "null" + id: + type: string + retailer_id: + type: + - string + - "null" + sale_id: + type: + - string + - "null" + status: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_by: + type: + - string + - "null" + required: + - id + promotions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + action: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - number + - "null" + channels: + type: + - array + - "null" + items: + type: + - string + - "null" + condition: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + exclude: + type: + - array + - "null" + include: + type: + - array + - "null" + quantity: + type: + - number + - "null" + customer_group_ids: + type: + - array + - "null" + id: + type: string + loyalty_multiplier: + type: + - number + - "null" + name: + type: + - string + - "null" + online_channel_ids: + type: + - array + - "null" + outlet_ids: + type: + - array + - "null" + promo_code_summary: + type: + - object + - "null" + properties: + redeemed_amount: + type: + - number + - "null" + total_promo_code: + type: + - number + - "null" + show_potential: + type: + - boolean + - "null" + start_time: + type: + - string + - "null" + status: + type: + - string + - "null" + use_promo_code: + type: + - boolean + - "null" + required: + - id + products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + type: + type: + - object + - "null" + properties: + version: + type: + - number + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + description: + type: + - string + - "null" + active: + type: + - boolean + - "null" + attributes: + type: + - array + - "null" + brand: + type: + - object + - "null" + properties: + version: + type: + - number + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + brand_id: + type: + - string + - "null" + button_order: + type: + - number + - "null" + categories: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + version: + type: + - number + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + created_at: + type: + - string + - "null" + ecwid_enabled_webstore: + type: + - boolean + - "null" + handle: + type: + - string + - "null" + has_inventory: + type: + - boolean + - "null" + has_variants: + type: + - boolean + - "null" + id: + type: string + image_thumbnail_url: + type: + - string + - "null" + image_url: + type: + - string + - "null" + images: + type: + - array + - "null" + is_active: + type: + - boolean + - "null" + is_composite: + type: + - boolean + - "null" + name: + type: + - string + - "null" + packaging: + type: + - object + - "null" + properties: + breaks_into: + type: + - array + - "null" + made_from: + type: + - array + - "null" + price_excluding_tax: + type: + - number + - "null" + price_including_tax: + type: + - number + - "null" + product_category: + type: + - object + - "null" + properties: + category_path: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: + - string + - "null" + leaf_category: + type: + - boolean + - "null" + name: + type: + - string + - "null" + product_codes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + code: + type: + - string + - "null" + id: + type: + - string + - "null" + product_suppliers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + price: + type: + - number + - "null" + product_id: + type: + - string + - "null" + supplier_id: + type: + - string + - "null" + supplier_name: + type: + - string + - "null" + product_type_id: + type: + - string + - "null" + sku: + type: + - string + - "null" + skuImages: + type: + - array + - "null" + source: + type: + - string + - "null" + supplier: + type: + - object + - "null" + properties: + version: + type: + - number + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + source: + type: + - string + - "null" + supplier_id: + type: + - string + - "null" + supply_price: + type: + - number + - "null" + tag_ids: + type: + - array + - "null" + items: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + variant_count: + type: + - number + - "null" + variant_name: + type: + - string + - "null" + variant_options: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + value: + type: + - string + - "null" + variant_parent_id: + type: + - string + - "null" + required: + - id + product_categories: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + PayloadID: + type: + - string + - "null" + category_path: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: string + leaf_category: + type: + - boolean + - "null" + name: + type: + - string + - "null" + root_category_id: + type: + - string + - "null" + required: + - id + price_books: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + adjustment: + type: + - number + - "null" + adjustment_type: + type: + - string + - "null" + created_at: + type: + - string + - "null" + default_display_price: + type: + - number + - "null" + discount: + type: + - number + - "null" + id: + type: string + price: + type: + - number + - "null" + price_book_id: + type: + - string + - "null" + product_id: + type: + - string + - "null" + retail_tax: + type: + - number + - "null" + rounding: + type: + - string + - "null" + tax_id: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + payment_types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + config: + type: + - object + - "null" + properties: + conceal_cash_totals: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + disabled: + type: + - boolean + - "null" + gateway: + type: + - boolean + - "null" + id: + type: string + internal: + type: + - boolean + - "null" + name: + type: + - string + - "null" + name_changed_by_user: + type: + - boolean + - "null" + payment_type: + type: + - object + - "null" + properties: + badge: + type: + - string + - "null" + category: + type: + - string + - "null" + id: + type: + - number + - "null" + internal: + type: + - boolean + - "null" + name: + type: + - string + - "null" + online_only: + type: + - boolean + - "null" + platforms: + type: + - array + - "null" + items: + type: + - string + - "null" + referred_inactive: + type: + - boolean + - "null" + show_banner: + type: + - boolean + - "null" + subcategory: + type: + - string + - "null" + subtext: + type: + - string + - "null" + type_id: + type: + - number + - "null" + required: + - id + outlets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + attributes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + key: + type: + - string + - "null" + value: + type: + - string + - "null" + currency: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + default_tax_id: + type: + - string + - "null" + display_prices: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + time_zone: + type: + - string + - "null" + required: + - id + inventory: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + average_cost: + type: + - number + - "null" + current_amount: + type: + - number + - "null" + id: + type: string + inventory_level: + type: + - number + - "null" + outlet_id: + type: + - string + - "null" + product_id: + type: + - string + - "null" + required: + - id + fulfillments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + id: + type: string + line_items: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + product_id: + type: + - string + - "null" + quantity: + type: + - string + - "null" + outlet_id: + type: + - string + - "null" + sale_id: + type: + - string + - "null" + status: + type: + - string + - "null" + user_id: + type: + - string + - "null" + required: + - id + customer_groups: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + created_at: + type: + - string + - "null" + group_id: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + retailer_id: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + consignments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + type: + type: + - string + - "null" + consignment_date: + type: + - string + - "null" + created_at: + type: + - string + - "null" + due_at: + type: + - string + - "null" + filters: + type: + - array + - "null" + id: + type: string + name: + type: + - string + - "null" + outlet_id: + type: + - string + - "null" + received_at: + type: + - string + - "null" + reference: + type: + - string + - "null" + show_inactive: + type: + - boolean + - "null" + status: + type: + - string + - "null" + supplier_id: + type: + - string + - "null" + total_cost_gain: + type: + - string + - "null" + total_cost_loss: + type: + - string + - "null" + total_count_gain: + type: + - string + - "null" + total_count_loss: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + consignment_products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + cost: + type: + - string + - "null" + count: + type: + - string + - "null" + created_at: + type: + - string + - "null" + is_included: + type: + - boolean + - "null" + product_id: + type: string + status: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - product_id diff --git a/airbyte-integrations/connectors/source-lightspeed-retail/metadata.yaml b/airbyte-integrations/connectors/source-lightspeed-retail/metadata.yaml new file mode 100644 index 000000000000..eb7d41539c8f --- /dev/null +++ b/airbyte-integrations/connectors/source-lightspeed-retail/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "https://*.retail.lightspeed.app" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-lightspeed-retail + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 0f242d62-dbef-49d7-8cc1-72ff7e54c9ca + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-lightspeed-retail + githubIssueLabel: source-lightspeed-retail + icon: icon.svg + license: MIT + name: Lightspeed Retail + releaseDate: 2024-10-23 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/lightspeed-retail + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-linkedin-ads/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-linkedin-ads/integration_tests/acceptance.py index d49b55882333..a9256a533972 100644 --- a/airbyte-integrations/connectors/source-linkedin-ads/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-linkedin-ads/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-linkedin-ads/main.py b/airbyte-integrations/connectors/source-linkedin-ads/main.py index 899a7e8614a4..bf3f38b6d9fc 100644 --- a/airbyte-integrations/connectors/source-linkedin-ads/main.py +++ b/airbyte-integrations/connectors/source-linkedin-ads/main.py @@ -4,5 +4,6 @@ from source_linkedin_ads.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-linkedin-ads/metadata.yaml b/airbyte-integrations/connectors/source-linkedin-ads/metadata.yaml index 78d241fe43ee..6f96ea0ebd33 100644 --- a/airbyte-integrations/connectors/source-linkedin-ads/metadata.yaml +++ b/airbyte-integrations/connectors/source-linkedin-ads/metadata.yaml @@ -11,7 +11,7 @@ data: connectorSubtype: api connectorType: source definitionId: 137ece28-5434-455c-8f34-69dc3782f451 - dockerImageTag: 4.1.4 + dockerImageTag: 5.0.0 dockerRepository: airbyte/source-linkedin-ads documentationUrl: https://docs.airbyte.com/integrations/sources/linkedin-ads githubIssueLabel: source-linkedin-ads @@ -87,6 +87,10 @@ data: - "creatives" - "campaign_groups" - "conversions" + 5.0.0: + message: We would like to inform you that the Primary Key (PK) for ad_campaign_analytics and Custom Ad Analytics Reports streams has been changed from [string_of_pivot_values, end_date] to [string_of_pivot_values, end_date, sponsoredCampaign] and Primary Key (PK) for account_users stream has been changed from [account] to [account, user]. This update is intended to improve data integrity and ensure optimal performance. Upgrade LinkedIn Ads to apply these changes immediately. Otherwise, LinkedIn Ads will be upgraded automatically on 2024-12-10. + upgradeDeadline: "2024-12-10" + deadlineAction: "auto_upgrade" suggestedStreams: streams: - accounts diff --git a/airbyte-integrations/connectors/source-linkedin-ads/pyproject.toml b/airbyte-integrations/connectors/source-linkedin-ads/pyproject.toml index 2b9d9fd3142f..b235a0e12fb4 100644 --- a/airbyte-integrations/connectors/source-linkedin-ads/pyproject.toml +++ b/airbyte-integrations/connectors/source-linkedin-ads/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "4.1.4" +version = "5.0.0" name = "source-linkedin-ads" description = "Source implementation for Linkedin Ads." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/components.py b/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/components.py index 2fcb05b7f7fb..1ecc55bcccba 100644 --- a/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/components.py +++ b/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/components.py @@ -12,6 +12,8 @@ import pendulum import requests +from isodate import Duration, parse_duration + from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor from airbyte_cdk.sources.declarative.incremental import CursorFactory, DatetimeBasedCursor, PerPartitionCursor from airbyte_cdk.sources.declarative.interpolation import InterpolatedString @@ -31,7 +33,6 @@ from airbyte_cdk.sources.streams.http import HttpClient from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException, RequestBodyException, UserDefinedBackoffException from airbyte_cdk.sources.streams.http.http import BODY_REQUEST_METHODS -from isodate import Duration, parse_duration from .utils import ANALYTICS_FIELDS_V2, FIELDS_CHUNK_SIZE, transform_data diff --git a/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/config_migrations.py b/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/config_migrations.py index 276afed6da58..5bfbe9788132 100644 --- a/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/config_migrations.py +++ b/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/config_migrations.py @@ -10,6 +10,7 @@ from airbyte_cdk import AirbyteEntrypoint, Source, create_connector_config_control_message from airbyte_cdk.config_observation import emit_configuration_as_airbyte_control_message + logger = logging.getLogger("airbyte_logger") diff --git a/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/manifest.yaml b/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/manifest.yaml index ea1a53ccf337..61ef31b21be0 100644 --- a/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/manifest.yaml +++ b/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/manifest.yaml @@ -55,6 +55,7 @@ definitions: name: account_users primary_key: - account + - user retriever: type: SimpleRetriever requester: @@ -387,6 +388,7 @@ definitions: primary_key: - string_of_pivot_values - end_date + - sponsoredCampaign retriever: class_name: "source_linkedin_ads.components.LinkedInAdsCustomRetriever" requester: diff --git a/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/source.py b/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/source.py index 6813aaf34da1..3933f7dca212 100644 --- a/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/source.py +++ b/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/source.py @@ -14,6 +14,7 @@ from .utils import update_specific_key + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/utils.py b/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/utils.py index b10d822ae9ca..5237fc476f4b 100644 --- a/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/utils.py +++ b/airbyte-integrations/connectors/source-linkedin-ads/source_linkedin_ads/utils.py @@ -7,6 +7,7 @@ import pendulum as pdm + # replace `pivot` with `_pivot`, to allow redshift normalization, # since `pivot` is a reserved keyword for Destination Redshift, # on behalf of https://github.com/airbytehq/airbyte/issues/13018, diff --git a/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/conftest.py b/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/conftest.py index d93575984386..69255efc6a07 100644 --- a/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/conftest.py @@ -8,6 +8,7 @@ from source_linkedin_ads.source import SourceLinkedinAds + os.environ["REQUEST_CACHE_PATH"] = "REQUEST_CACHE_PATH" diff --git a/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/test_components.py b/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/test_components.py index 2fa7fbf0dd34..3ac0fae77771 100644 --- a/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/test_components.py +++ b/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/test_components.py @@ -18,6 +18,7 @@ StreamSlice, ) + logger = logging.getLogger("airbyte") @@ -35,7 +36,13 @@ def mock_response(): @pytest.fixture def mock_analytics_cursor_params(): - return {"start_datetime": MagicMock(), "cursor_field": MagicMock(), "datetime_format": "%s", "config": MagicMock(), "parameters": MagicMock()} + return { + "start_datetime": MagicMock(), + "cursor_field": MagicMock(), + "datetime_format": "%s", + "config": MagicMock(), + "parameters": MagicMock(), + } @pytest.fixture diff --git a/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/test_source.py b/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/test_source.py index e0d2ccca0348..17ee2e8dde59 100644 --- a/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/test_source.py @@ -1,17 +1,20 @@ # # Copyright (c) 2024 Airbyte, Inc., all rights reserved. # - import logging +from typing import Any, Dict, List import pytest import requests +from conftest import find_stream +from source_linkedin_ads.source import SourceLinkedinAds + from airbyte_cdk.models import SyncMode +from airbyte_cdk.sources.declarative.manifest_declarative_source import ManifestDeclarativeSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException from airbyte_cdk.sources.streams.http.requests_native_auth import Oauth2Authenticator, TokenAuthenticator -from conftest import find_stream -from source_linkedin_ads.source import SourceLinkedinAds + logger = logging.getLogger("airbyte") @@ -57,8 +60,41 @@ class TestAllStreams: _instance: SourceLinkedinAds = SourceLinkedinAds() + @staticmethod + def _mock_initialize_cache_for_parent_streams(stream_configs: List[Dict[str, Any]]) -> List[Dict[str, Any]]: + parent_streams = set() + + def update_with_cache_parent_configs(parent_configs: list[dict[str, Any]]) -> None: + for parent_config in parent_configs: + parent_streams.add(parent_config["stream"]["name"]) + parent_config["stream"]["retriever"]["requester"]["use_cache"] = False + + for stream_config in stream_configs: + if stream_config.get("incremental_sync", {}).get("parent_stream"): + parent_streams.add(stream_config["incremental_sync"]["parent_stream"]["name"]) + stream_config["incremental_sync"]["parent_stream"]["retriever"]["requester"]["use_cache"] = False + + elif stream_config.get("retriever", {}).get("partition_router", {}): + partition_router = stream_config["retriever"]["partition_router"] + + if isinstance(partition_router, dict) and partition_router.get("parent_stream_configs"): + update_with_cache_parent_configs(partition_router["parent_stream_configs"]) + elif isinstance(partition_router, list): + for router in partition_router: + if router.get("parent_stream_configs"): + update_with_cache_parent_configs(router["parent_stream_configs"]) + + for stream_config in stream_configs: + if stream_config["name"] in parent_streams: + stream_config["retriever"]["requester"]["use_cache"] = False + + return stream_configs + @pytest.mark.parametrize("error_code", [429, 500, 503]) def test_should_retry_on_error(self, error_code, requests_mock, mocker): + mocker.patch.object( + ManifestDeclarativeSource, "_initialize_cache_for_parent_streams", side_effect=self._mock_initialize_cache_for_parent_streams + ) mocker.patch("time.sleep", lambda x: None) stream = find_stream("accounts", TEST_CONFIG) requests_mock.register_uri( @@ -70,11 +106,10 @@ def test_should_retry_on_error(self, error_code, requests_mock, mocker): def test_custom_streams(self): config = {"ad_analytics_reports": [{"name": "ShareAdByMonth", "pivot_by": "COMPANY", "time_granularity": "MONTHLY"}], **TEST_CONFIG} - ad_campaign_analytics = find_stream('ad_campaign_analytics', config) + ad_campaign_analytics = find_stream("ad_campaign_analytics", config) for stream in self._instance._create_custom_ad_analytics_streams(config=config): assert isinstance(stream, type(ad_campaign_analytics)) - @pytest.mark.parametrize( "stream_name, expected", [ @@ -104,24 +139,23 @@ def test_path(self, stream_name, expected): @pytest.mark.parametrize( ("status_code", "is_connection_successful", "error_msg"), ( - ( - 400, - False, - ( - "Bad request. Please check your request parameters." - ), - ), - ( - 403, - False, - ( - "Forbidden. You don't have permission to access this resource." - ), - ), - (200, True, None), + ( + 400, + False, + ("Bad request. Please check your request parameters."), + ), + ( + 403, + False, + ("Forbidden. You don't have permission to access this resource."), + ), + (200, True, None), ), ) def test_check_connection(self, requests_mock, status_code, is_connection_successful, error_msg, mocker): + mocker.patch.object( + ManifestDeclarativeSource, "_initialize_cache_for_parent_streams", side_effect=self._mock_initialize_cache_for_parent_streams + ) mocker.patch("time.sleep", lambda x: None) json = {"elements": [{"data": []}] * 500} if 200 >= status_code < 300 else {} requests_mock.register_uri( diff --git a/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/test_streams.py index 197f43ea8e64..01c828362c8f 100644 --- a/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/test_streams.py @@ -6,11 +6,13 @@ import os from typing import Any, Mapping -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator from conftest import find_stream from freezegun import freeze_time +from airbyte_cdk.models import SyncMode +from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator + + # Test input arguments for the `make_analytics_slices` TEST_KEY_VALUE_MAP = {"camp_id": "id"} TEST_START_DATE = "2021-08-01" @@ -50,7 +52,8 @@ def test_read_records(requests_mock): requests_mock.get("https://api.linkedin.com/rest/adAccounts", json={"elements": [{"id": 1}]}) requests_mock.get( "https://api.linkedin.com/rest/adAccounts/1/adCampaigns?q=search&search=(status:(values:List(ACTIVE,PAUSED,ARCHIVED,COMPLETED,CANCELED,DRAFT,PENDING_DELETION,REMOVED)))", - json={"elements": [{"id": 1111, "lastModified": "2021-01-15"}]}) + json={"elements": [{"id": 1111, "lastModified": "2021-01-15"}]}, + ) requests_mock.get( "https://api.linkedin.com/rest/adAnalytics", [ diff --git a/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/utils_tests/samples/test_data_for_tranform.py b/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/utils_tests/samples/test_data_for_tranform.py index e116afe2bbbd..83ca7aaf2547 100644 --- a/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/utils_tests/samples/test_data_for_tranform.py +++ b/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/utils_tests/samples/test_data_for_tranform.py @@ -2,7 +2,8 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # -""" This is the example of input record for the test_tranform_data. """ +"""This is the example of input record for the test_tranform_data.""" + input_test_data = [ { "targetingCriteria": { @@ -65,7 +66,7 @@ } }, "pivot": "TEST_PIVOT_VALUE", - "pivotValues": ["TEST_PIVOT_VALUE_1", "TEST_PIVOT_VALUE_2"] + "pivotValues": ["TEST_PIVOT_VALUE_1", "TEST_PIVOT_VALUE_2"], } ] @@ -144,6 +145,6 @@ "end_date": "2021-08-13", "_pivot": "TEST_PIVOT_VALUE", "string_of_pivot_values": "TEST_PIVOT_VALUE_1,TEST_PIVOT_VALUE_2", - "pivotValues": ["TEST_PIVOT_VALUE_1", "TEST_PIVOT_VALUE_2"] + "pivotValues": ["TEST_PIVOT_VALUE_1", "TEST_PIVOT_VALUE_2"], } ] diff --git a/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/utils_tests/test_update_specific_key.py b/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/utils_tests/test_update_specific_key.py index 73be5f6a0564..c62676cfc0ff 100644 --- a/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/utils_tests/test_update_specific_key.py +++ b/airbyte-integrations/connectors/source-linkedin-ads/unit_tests/utils_tests/test_update_specific_key.py @@ -74,8 +74,8 @@ "nested_dictionary_update", "list_of_dictionaries_update", "excluded_key_in_nested_dict", - "nested_list_with_mixed_types" - ] + "nested_list_with_mixed_types", + ], ) def test_update_specific_key(target_dict, target_key, target_value, condition_func, excluded_keys, expected_output): result = update_specific_key(target_dict, target_key, target_value, condition_func, excluded_keys) diff --git a/airbyte-integrations/connectors/source-linkedin-pages/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-linkedin-pages/integration_tests/acceptance.py index d49b55882333..a9256a533972 100644 --- a/airbyte-integrations/connectors/source-linkedin-pages/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-linkedin-pages/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-linkedin-pages/metadata.yaml b/airbyte-integrations/connectors/source-linkedin-pages/metadata.yaml index f430d570e72f..17134d41d924 100644 --- a/airbyte-integrations/connectors/source-linkedin-pages/metadata.yaml +++ b/airbyte-integrations/connectors/source-linkedin-pages/metadata.yaml @@ -16,11 +16,11 @@ data: enabled: false packageName: airbyte-source-linkedin-pages connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: af54297c-e8f8-4d63-a00d-a94695acc9d3 - dockerImageTag: 1.1.3 + dockerImageTag: 1.1.8 dockerRepository: airbyte/source-linkedin-pages documentationUrl: https://docs.airbyte.com/integrations/sources/linkedin-pages githubIssueLabel: source-linkedin-pages diff --git a/airbyte-integrations/connectors/source-linnworks/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-linnworks/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-linnworks/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-linnworks/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-linnworks/main.py b/airbyte-integrations/connectors/source-linnworks/main.py index ee964c061ce0..e6b07506ae4f 100644 --- a/airbyte-integrations/connectors/source-linnworks/main.py +++ b/airbyte-integrations/connectors/source-linnworks/main.py @@ -4,5 +4,6 @@ from source_linnworks.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-linnworks/metadata.yaml b/airbyte-integrations/connectors/source-linnworks/metadata.yaml index 133748bae7cb..a680ff6ba7a9 100644 --- a/airbyte-integrations/connectors/source-linnworks/metadata.yaml +++ b/airbyte-integrations/connectors/source-linnworks/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 7b86879e-26c5-4ef6-a5ce-2be5c7b46d1e - dockerImageTag: 0.1.32 + dockerImageTag: 0.1.37 dockerRepository: airbyte/source-linnworks documentationUrl: https://docs.airbyte.com/integrations/sources/linnworks githubIssueLabel: source-linnworks diff --git a/airbyte-integrations/connectors/source-linnworks/poetry.lock b/airbyte-integrations/connectors/source-linnworks/poetry.lock index e4159ab46d69..6329fae406ea 100644 --- a/airbyte-integrations/connectors/source-linnworks/poetry.lock +++ b/airbyte-integrations/connectors/source-linnworks/poetry.lock @@ -62,19 +62,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -140,127 +140,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -276,20 +263,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -367,13 +354,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -590,13 +577,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""} [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -666,109 +653,93 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "propcache" -version = "0.2.0" +version = "0.2.1" description = "Accelerated property cache" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"}, - {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"}, - {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"}, - {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"}, - {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, - {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, - {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544"}, - {file = "propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032"}, - {file = "propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed"}, - {file = "propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d"}, - {file = "propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798"}, - {file = "propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9"}, - {file = "propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df"}, - {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, - {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6445804cf4ec763dc70de65a3b0d9954e868609e83850a47ca4f0cb64bd79fea"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9479aa06a793c5aeba49ce5c5692ffb51fcd9a7016e017d555d5e2b0045d212"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9631c5e8b5b3a0fda99cb0d29c18133bca1e18aea9effe55adb3da1adef80d3"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3156628250f46a0895f1f36e1d4fbe062a1af8718ec3ebeb746f1d23f0c5dc4d"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b6fb63ae352e13748289f04f37868099e69dba4c2b3e271c46061e82c745634"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:887d9b0a65404929641a9fabb6452b07fe4572b269d901d622d8a34a4e9043b2"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a96dc1fa45bd8c407a0af03b2d5218392729e1822b0c32e62c5bf7eeb5fb3958"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a7e65eb5c003a303b94aa2c3852ef130230ec79e349632d030e9571b87c4698c"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:999779addc413181912e984b942fbcc951be1f5b3663cd80b2687758f434c583"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:19a0f89a7bb9d8048d9c4370c9c543c396e894c76be5525f5e1ad287f1750ddf"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1ac2f5fe02fa75f56e1ad473f1175e11f475606ec9bd0be2e78e4734ad575034"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:574faa3b79e8ebac7cb1d7930f51184ba1ccf69adfdec53a12f319a06030a68b"}, + {file = "propcache-0.2.1-cp310-cp310-win32.whl", hash = "sha256:03ff9d3f665769b2a85e6157ac8b439644f2d7fd17615a82fa55739bc97863f4"}, + {file = "propcache-0.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:2d3af2e79991102678f53e0dbf4c35de99b6b8b58f29a27ca0325816364caaba"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e"}, + {file = "propcache-0.2.1-cp311-cp311-win32.whl", hash = "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034"}, + {file = "propcache-0.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518"}, + {file = "propcache-0.2.1-cp312-cp312-win32.whl", hash = "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246"}, + {file = "propcache-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30"}, + {file = "propcache-0.2.1-cp313-cp313-win32.whl", hash = "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6"}, + {file = "propcache-0.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6a9a8c34fb7bb609419a211e59da8887eeca40d300b5ea8e56af98f6fbbb1541"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae1aa1cd222c6d205853b3013c69cd04515f9d6ab6de4b0603e2e1c33221303e"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:accb6150ce61c9c4b7738d45550806aa2b71c7668c6942f17b0ac182b6142fd4"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5eee736daafa7af6d0a2dc15cc75e05c64f37fc37bafef2e00d77c14171c2097"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7a31fc1e1bd362874863fdeed71aed92d348f5336fd84f2197ba40c59f061bd"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba4cfa1052819d16699e1d55d18c92b6e094d4517c41dd231a8b9f87b6fa681"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f089118d584e859c62b3da0892b88a83d611c2033ac410e929cb6754eec0ed16"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:781e65134efaf88feb447e8c97a51772aa75e48b794352f94cb7ea717dedda0d"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31f5af773530fd3c658b32b6bdc2d0838543de70eb9a2156c03e410f7b0d3aae"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:a7a078f5d37bee6690959c813977da5291b24286e7b962e62a94cec31aa5188b"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:cea7daf9fc7ae6687cf1e2c049752f19f146fdc37c2cc376e7d0032cf4f25347"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:8b3489ff1ed1e8315674d0775dc7d2195fb13ca17b3808721b54dbe9fd020faf"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9403db39be1393618dd80c746cb22ccda168efce239c73af13c3763ef56ffc04"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5d97151bc92d2b2578ff7ce779cdb9174337390a535953cbb9452fb65164c587"}, + {file = "propcache-0.2.1-cp39-cp39-win32.whl", hash = "sha256:9caac6b54914bdf41bcc91e7eb9147d331d29235a7c967c150ef5df6464fd1bb"}, + {file = "propcache-0.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:92fc4500fcb33899b05ba73276dfb684a20d31caa567b7cb5252d48f896a91b1"}, + {file = "propcache-0.2.1-py3-none-any.whl", hash = "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54"}, + {file = "propcache-0.2.1.tar.gz", hash = "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64"}, ] [[package]] @@ -784,54 +755,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -1095,33 +1066,33 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1178,13 +1149,13 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1232,172 +1203,167 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [[package]] name = "yarl" -version = "1.17.0" +version = "1.18.3" description = "Yet another URL library" optional = false python-versions = ">=3.9" files = [ - {file = "yarl-1.17.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2d8715edfe12eee6f27f32a3655f38d6c7410deb482158c0b7d4b7fad5d07628"}, - {file = "yarl-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1803bf2a7a782e02db746d8bd18f2384801bc1d108723840b25e065b116ad726"}, - {file = "yarl-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e66589110e20c2951221a938fa200c7aa134a8bdf4e4dc97e6b21539ff026d4"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7069d411cfccf868e812497e0ec4acb7c7bf8d684e93caa6c872f1e6f5d1664d"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cbf70ba16118db3e4b0da69dcde9d4d4095d383c32a15530564c283fa38a7c52"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0bc53cc349675b32ead83339a8de79eaf13b88f2669c09d4962322bb0f064cbc"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6aa18a402d1c80193ce97c8729871f17fd3e822037fbd7d9b719864018df746"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d89c5bc701861cfab357aa0cd039bc905fe919997b8c312b4b0c358619c38d4d"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b728bdf38ca58f2da1d583e4af4ba7d4cd1a58b31a363a3137a8159395e7ecc7"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:5542e57dc15d5473da5a39fbde14684b0cc4301412ee53cbab677925e8497c11"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e564b57e5009fb150cb513804d7e9e9912fee2e48835638f4f47977f88b4a39c"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:eb3c4cff524b4c1c1dba3a6da905edb1dfd2baf6f55f18a58914bbb2d26b59e1"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:05e13f389038842da930d439fbed63bdce3f7644902714cb68cf527c971af804"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:153c38ee2b4abba136385af4467459c62d50f2a3f4bde38c7b99d43a20c143ef"}, - {file = "yarl-1.17.0-cp310-cp310-win32.whl", hash = "sha256:4065b4259d1ae6f70fd9708ffd61e1c9c27516f5b4fae273c41028afcbe3a094"}, - {file = "yarl-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:abf366391a02a8335c5c26163b5fe6f514cc1d79e74d8bf3ffab13572282368e"}, - {file = "yarl-1.17.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:19a4fe0279626c6295c5b0c8c2bb7228319d2e985883621a6e87b344062d8135"}, - {file = "yarl-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cadd0113f4db3c6b56868d6a19ca6286f5ccfa7bc08c27982cf92e5ed31b489a"}, - {file = "yarl-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:60d6693eef43215b1ccfb1df3f6eae8db30a9ff1e7989fb6b2a6f0b468930ee8"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb8bf3843e1fa8cf3fe77813c512818e57368afab7ebe9ef02446fe1a10b492"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d2a5b35fd1d8d90443e061d0c8669ac7600eec5c14c4a51f619e9e105b136715"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5bf17b32f392df20ab5c3a69d37b26d10efaa018b4f4e5643c7520d8eee7ac7"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48f51b529b958cd06e78158ff297a8bf57b4021243c179ee03695b5dbf9cb6e1"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fcaa06bf788e19f913d315d9c99a69e196a40277dc2c23741a1d08c93f4d430"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:32f3ee19ff0f18a7a522d44e869e1ebc8218ad3ae4ebb7020445f59b4bbe5897"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:a4fb69a81ae2ec2b609574ae35420cf5647d227e4d0475c16aa861dd24e840b0"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7bacc8b77670322132a1b2522c50a1f62991e2f95591977455fd9a398b4e678d"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:437bf6eb47a2d20baaf7f6739895cb049e56896a5ffdea61a4b25da781966e8b"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:30534a03c87484092080e3b6e789140bd277e40f453358900ad1f0f2e61fc8ec"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b30df4ff98703649915144be6f0df3b16fd4870ac38a09c56d5d9e54ff2d5f96"}, - {file = "yarl-1.17.0-cp311-cp311-win32.whl", hash = "sha256:263b487246858e874ab53e148e2a9a0de8465341b607678106829a81d81418c6"}, - {file = "yarl-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:07055a9e8b647a362e7d4810fe99d8f98421575e7d2eede32e008c89a65a17bd"}, - {file = "yarl-1.17.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:84095ab25ba69a8fa3fb4936e14df631b8a71193fe18bd38be7ecbe34d0f5512"}, - {file = "yarl-1.17.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:02608fb3f6df87039212fc746017455ccc2a5fc96555ee247c45d1e9f21f1d7b"}, - {file = "yarl-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13468d291fe8c12162b7cf2cdb406fe85881c53c9e03053ecb8c5d3523822cd9"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8da3f8f368fb7e2f052fded06d5672260c50b5472c956a5f1bd7bf474ae504ab"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ec0507ab6523980bed050137007c76883d941b519aca0e26d4c1ec1f297dd646"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08fc76df7fd8360e9ff30e6ccc3ee85b8dbd6ed5d3a295e6ec62bcae7601b932"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d522f390686acb6bab2b917dd9ca06740c5080cd2eaa5aef8827b97e967319d"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:147c527a80bb45b3dcd6e63401af8ac574125d8d120e6afe9901049286ff64ef"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:24cf43bcd17a0a1f72284e47774f9c60e0bf0d2484d5851f4ddf24ded49f33c6"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:c28a44b9e0fba49c3857360e7ad1473fc18bc7f6659ca08ed4f4f2b9a52c75fa"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:350cacb2d589bc07d230eb995d88fcc646caad50a71ed2d86df533a465a4e6e1"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:fd1ab1373274dea1c6448aee420d7b38af163b5c4732057cd7ee9f5454efc8b1"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4934e0f96dadc567edc76d9c08181633c89c908ab5a3b8f698560124167d9488"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8d0a278170d75c88e435a1ce76557af6758bfebc338435b2eba959df2552163e"}, - {file = "yarl-1.17.0-cp312-cp312-win32.whl", hash = "sha256:61584f33196575a08785bb56db6b453682c88f009cd9c6f338a10f6737ce419f"}, - {file = "yarl-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:9987a439ad33a7712bd5bbd073f09ad10d38640425fa498ecc99d8aa064f8fc4"}, - {file = "yarl-1.17.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8deda7b8eb15a52db94c2014acdc7bdd14cb59ec4b82ac65d2ad16dc234a109e"}, - {file = "yarl-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56294218b348dcbd3d7fce0ffd79dd0b6c356cb2a813a1181af730b7c40de9e7"}, - {file = "yarl-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1fab91292f51c884b290ebec0b309a64a5318860ccda0c4940e740425a67b6b7"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cf93fa61ff4d9c7d40482ce1a2c9916ca435e34a1b8451e17f295781ccc034f"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:261be774a0d71908c8830c33bacc89eef15c198433a8cc73767c10eeeb35a7d0"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deec9693b67f6af856a733b8a3e465553ef09e5e8ead792f52c25b699b8f9e6e"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c804b07622ba50a765ca7fb8145512836ab65956de01307541def869e4a456c9"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d013a7c9574e98c14831a8f22d27277688ec3b2741d0188ac01a910b009987a"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e2cfcba719bd494c7413dcf0caafb51772dec168c7c946e094f710d6aa70494e"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:c068aba9fc5b94dfae8ea1cedcbf3041cd4c64644021362ffb750f79837e881f"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3616df510ffac0df3c9fa851a40b76087c6c89cbcea2de33a835fc80f9faac24"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:755d6176b442fba9928a4df787591a6a3d62d4969f05c406cad83d296c5d4e05"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c18f6e708d1cf9ff5b1af026e697ac73bea9cb70ee26a2b045b112548579bed2"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5b937c216b6dee8b858c6afea958de03c5ff28406257d22b55c24962a2baf6fd"}, - {file = "yarl-1.17.0-cp313-cp313-win32.whl", hash = "sha256:d0131b14cb545c1a7bd98f4565a3e9bdf25a1bd65c83fc156ee5d8a8499ec4a3"}, - {file = "yarl-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:01c96efa4313c01329e88b7e9e9e1b2fc671580270ddefdd41129fa8d0db7696"}, - {file = "yarl-1.17.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0d44f67e193f0a7acdf552ecb4d1956a3a276c68e7952471add9f93093d1c30d"}, - {file = "yarl-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:16ea0aa5f890cdcb7ae700dffa0397ed6c280840f637cd07bffcbe4b8d68b985"}, - {file = "yarl-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cf5469dc7dcfa65edf5cc3a6add9f84c5529c6b556729b098e81a09a92e60e51"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e662bf2f6e90b73cf2095f844e2bc1fda39826472a2aa1959258c3f2a8500a2f"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8260e88f1446904ba20b558fa8ce5d0ab9102747238e82343e46d056d7304d7e"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dc16477a4a2c71e64c5d3d15d7ae3d3a6bb1e8b955288a9f73c60d2a391282f"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46027e326cecd55e5950184ec9d86c803f4f6fe4ba6af9944a0e537d643cdbe0"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc95e46c92a2b6f22e70afe07e34dbc03a4acd07d820204a6938798b16f4014f"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:16ca76c7ac9515320cd09d6cc083d8d13d1803f6ebe212b06ea2505fd66ecff8"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:eb1a5b97388f2613f9305d78a3473cdf8d80c7034e554d8199d96dcf80c62ac4"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:41fd5498975418cdc34944060b8fbeec0d48b2741068077222564bea68daf5a6"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:146ca582ed04a5664ad04b0e0603934281eaab5c0115a5a46cce0b3c061a56a1"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:6abb8c06107dbec97481b2392dafc41aac091a5d162edf6ed7d624fe7da0587a"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4d14be4613dd4f96c25feb4bd8c0d8ce0f529ab0ae555a17df5789e69d8ec0c5"}, - {file = "yarl-1.17.0-cp39-cp39-win32.whl", hash = "sha256:174d6a6cad1068f7850702aad0c7b1bca03bcac199ca6026f84531335dfc2646"}, - {file = "yarl-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:6af417ca2c7349b101d3fd557ad96b4cd439fdb6ab0d288e3f64a068eea394d0"}, - {file = "yarl-1.17.0-py3-none-any.whl", hash = "sha256:62dd42bb0e49423f4dd58836a04fcf09c80237836796025211bbe913f1524993"}, - {file = "yarl-1.17.0.tar.gz", hash = "sha256:d3f13583f378930377e02002b4085a3d025b00402d5a80911726d43a67911cd9"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:602d98f2c2d929f8e697ed274fbadc09902c4025c5a9963bf4e9edfc3ab6f7ed"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c654d5207c78e0bd6d749f6dae1dcbbfde3403ad3a4b11f3c5544d9906969dde"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5094d9206c64181d0f6e76ebd8fb2f8fe274950a63890ee9e0ebfd58bf9d787b"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35098b24e0327fc4ebdc8ffe336cee0a87a700c24ffed13161af80124b7dc8e5"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3236da9272872443f81fedc389bace88408f64f89f75d1bdb2256069a8730ccc"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c08cc9b16f4f4bc522771d96734c7901e7ebef70c6c5c35dd0f10845270bcd"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80316a8bd5109320d38eef8833ccf5f89608c9107d02d2a7f985f98ed6876990"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1e1cc06da1491e6734f0ea1e6294ce00792193c463350626571c287c9a704db"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fea09ca13323376a2fdfb353a5fa2e59f90cd18d7ca4eaa1fd31f0a8b4f91e62"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e3b9fd71836999aad54084906f8663dffcd2a7fb5cdafd6c37713b2e72be1760"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:757e81cae69244257d125ff31663249b3013b5dc0a8520d73694aed497fb195b"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b1771de9944d875f1b98a745bc547e684b863abf8f8287da8466cf470ef52690"}, + {file = "yarl-1.18.3-cp310-cp310-win32.whl", hash = "sha256:8874027a53e3aea659a6d62751800cf6e63314c160fd607489ba5c2edd753cf6"}, + {file = "yarl-1.18.3-cp310-cp310-win_amd64.whl", hash = "sha256:93b2e109287f93db79210f86deb6b9bbb81ac32fc97236b16f7433db7fc437d8"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8503ad47387b8ebd39cbbbdf0bf113e17330ffd339ba1144074da24c545f0069"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02ddb6756f8f4517a2d5e99d8b2f272488e18dd0bfbc802f31c16c6c20f22193"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67a283dd2882ac98cc6318384f565bffc751ab564605959df4752d42483ad889"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d980e0325b6eddc81331d3f4551e2a333999fb176fd153e075c6d1c2530aa8a8"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b643562c12680b01e17239be267bc306bbc6aac1f34f6444d1bded0c5ce438ca"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c017a3b6df3a1bd45b9fa49a0f54005e53fbcad16633870104b66fa1a30a29d8"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75674776d96d7b851b6498f17824ba17849d790a44d282929c42dbb77d4f17ae"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccaa3a4b521b780a7e771cc336a2dba389a0861592bbce09a476190bb0c8b4b3"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d06d3005e668744e11ed80812e61efd77d70bb7f03e33c1598c301eea20efbb"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:9d41beda9dc97ca9ab0b9888cb71f7539124bc05df02c0cff6e5acc5a19dcc6e"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ba23302c0c61a9999784e73809427c9dbedd79f66a13d84ad1b1943802eaaf59"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6748dbf9bfa5ba1afcc7556b71cda0d7ce5f24768043a02a58846e4a443d808d"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0b0cad37311123211dc91eadcb322ef4d4a66008d3e1bdc404808992260e1a0e"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0fb2171a4486bb075316ee754c6d8382ea6eb8b399d4ec62fde2b591f879778a"}, + {file = "yarl-1.18.3-cp311-cp311-win32.whl", hash = "sha256:61b1a825a13bef4a5f10b1885245377d3cd0bf87cba068e1d9a88c2ae36880e1"}, + {file = "yarl-1.18.3-cp311-cp311-win_amd64.whl", hash = "sha256:b9d60031cf568c627d028239693fd718025719c02c9f55df0a53e587aab951b5"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285"}, + {file = "yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2"}, + {file = "yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:90adb47ad432332d4f0bc28f83a5963f426ce9a1a8809f5e584e704b82685dcb"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:913829534200eb0f789d45349e55203a091f45c37a2674678744ae52fae23efa"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ef9f7768395923c3039055c14334ba4d926f3baf7b776c923c93d80195624782"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a19f62ff30117e706ebc9090b8ecc79aeb77d0b1f5ec10d2d27a12bc9f66d0"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e17c9361d46a4d5addf777c6dd5eab0715a7684c2f11b88c67ac37edfba6c482"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a74a13a4c857a84a845505fd2d68e54826a2cd01935a96efb1e9d86c728e186"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41f7ce59d6ee7741af71d82020346af364949314ed3d87553763a2df1829cc58"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f52a265001d830bc425f82ca9eabda94a64a4d753b07d623a9f2863fde532b53"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:82123d0c954dc58db301f5021a01854a85bf1f3bb7d12ae0c01afc414a882ca2"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2ec9bbba33b2d00999af4631a3397d1fd78290c48e2a3e52d8dd72db3a067ac8"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbd6748e8ab9b41171bb95c6142faf068f5ef1511935a0aa07025438dd9a9bc1"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:877d209b6aebeb5b16c42cbb377f5f94d9e556626b1bfff66d7b0d115be88d0a"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b464c4ab4bfcb41e3bfd3f1c26600d038376c2de3297760dfe064d2cb7ea8e10"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8d39d351e7faf01483cc7ff7c0213c412e38e5a340238826be7e0e4da450fdc8"}, + {file = "yarl-1.18.3-cp313-cp313-win32.whl", hash = "sha256:61ee62ead9b68b9123ec24bc866cbef297dd266175d53296e2db5e7f797f902d"}, + {file = "yarl-1.18.3-cp313-cp313-win_amd64.whl", hash = "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:61e5e68cb65ac8f547f6b5ef933f510134a6bf31bb178be428994b0cb46c2a04"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe57328fbc1bfd0bd0514470ac692630f3901c0ee39052ae47acd1d90a436719"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a440a2a624683108a1b454705ecd7afc1c3438a08e890a1513d468671d90a04e"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09c7907c8548bcd6ab860e5f513e727c53b4a714f459b084f6580b49fa1b9cee"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4f6450109834af88cb4cc5ecddfc5380ebb9c228695afc11915a0bf82116789"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9ca04806f3be0ac6d558fffc2fdf8fcef767e0489d2684a21912cc4ed0cd1b8"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77a6e85b90a7641d2e07184df5557132a337f136250caafc9ccaa4a2a998ca2c"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6333c5a377c8e2f5fae35e7b8f145c617b02c939d04110c76f29ee3676b5f9a5"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0b3c92fa08759dbf12b3a59579a4096ba9af8dd344d9a813fc7f5070d86bbab1"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4ac515b860c36becb81bb84b667466885096b5fc85596948548b667da3bf9f24"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:045b8482ce9483ada4f3f23b3774f4e1bf4f23a2d5c912ed5170f68efb053318"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:a4bb030cf46a434ec0225bddbebd4b89e6471814ca851abb8696170adb163985"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:54d6921f07555713b9300bee9c50fb46e57e2e639027089b1d795ecd9f7fa910"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1d407181cfa6e70077df3377938c08012d18893f9f20e92f7d2f314a437c30b1"}, + {file = "yarl-1.18.3-cp39-cp39-win32.whl", hash = "sha256:ac36703a585e0929b032fbaab0707b75dc12703766d0b53486eabd5139ebadd5"}, + {file = "yarl-1.18.3-cp39-cp39-win_amd64.whl", hash = "sha256:ba87babd629f8af77f557b61e49e7c7cac36f22f871156b91e10a6e9d4f829e9"}, + {file = "yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b"}, + {file = "yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1"}, ] [package.dependencies] diff --git a/airbyte-integrations/connectors/source-linnworks/pyproject.toml b/airbyte-integrations/connectors/source-linnworks/pyproject.toml index c5e8beef35f1..dd9f73d4ee09 100644 --- a/airbyte-integrations/connectors/source-linnworks/pyproject.toml +++ b/airbyte-integrations/connectors/source-linnworks/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.32" +version = "0.1.37" name = "source-linnworks" description = "Source implementation for Linnworks." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-linnworks/source_linnworks/source.py b/airbyte-integrations/connectors/source-linnworks/source_linnworks/source.py index 7192e2ec5826..32761a344de5 100644 --- a/airbyte-integrations/connectors/source-linnworks/source_linnworks/source.py +++ b/airbyte-integrations/connectors/source-linnworks/source_linnworks/source.py @@ -7,6 +7,7 @@ import pendulum import requests + from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http.requests_native_auth import Oauth2Authenticator @@ -48,7 +49,6 @@ def get_auth_header(self) -> Mapping[str, Any]: return {"Authorization": self.get_access_token()} def get_access_token(self): - if self.token_has_expired(): t0 = pendulum.now() token, expires_in, server = self.refresh_access_token() diff --git a/airbyte-integrations/connectors/source-linnworks/source_linnworks/streams.py b/airbyte-integrations/connectors/source-linnworks/source_linnworks/streams.py index a3935d719844..fe7733524ec3 100644 --- a/airbyte-integrations/connectors/source-linnworks/source_linnworks/streams.py +++ b/airbyte-integrations/connectors/source-linnworks/source_linnworks/streams.py @@ -11,11 +11,12 @@ import pendulum import requests import vcr -from airbyte_cdk.sources.streams.http import HttpStream, HttpSubStream -from airbyte_cdk.sources.streams.http.auth.core import HttpAuthenticator from requests.auth import AuthBase from vcr.cassette import Cassette +from airbyte_cdk.sources.streams.http import HttpStream, HttpSubStream +from airbyte_cdk.sources.streams.http.auth.core import HttpAuthenticator + class LinnworksStream(HttpStream, ABC): http_method = "POST" diff --git a/airbyte-integrations/connectors/source-linnworks/unit_tests/test_incremental_streams.py b/airbyte-integrations/connectors/source-linnworks/unit_tests/test_incremental_streams.py index d0c1081e0625..1ab8760bc505 100644 --- a/airbyte-integrations/connectors/source-linnworks/unit_tests/test_incremental_streams.py +++ b/airbyte-integrations/connectors/source-linnworks/unit_tests/test_incremental_streams.py @@ -11,9 +11,10 @@ import pytest import requests import vcr +from source_linnworks.streams import IncrementalLinnworksStream, ProcessedOrderDetails, ProcessedOrders + from airbyte_cdk.models.airbyte_protocol import SyncMode from airbyte_cdk.sources.streams.http.http import HttpSubStream -from source_linnworks.streams import IncrementalLinnworksStream, ProcessedOrderDetails, ProcessedOrders @pytest.fixture diff --git a/airbyte-integrations/connectors/source-lob/metadata.yaml b/airbyte-integrations/connectors/source-lob/metadata.yaml index 5d3f2a0b4a7a..ae123bac13e4 100644 --- a/airbyte-integrations/connectors/source-lob/metadata.yaml +++ b/airbyte-integrations/connectors/source-lob/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-lob connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: c6d14c44-cd3e-4f94-8924-201c5615f3a7 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.9 dockerRepository: airbyte/source-lob githubIssueLabel: source-lob icon: icon.svg diff --git a/airbyte-integrations/connectors/source-lokalise/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-lokalise/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-lokalise/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-lokalise/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-lokalise/metadata.yaml b/airbyte-integrations/connectors/source-lokalise/metadata.yaml index 0ec22ac07f05..4b3dfc6a9d83 100644 --- a/airbyte-integrations/connectors/source-lokalise/metadata.yaml +++ b/airbyte-integrations/connectors/source-lokalise/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 45e0b135-615c-40ac-b38e-e65b0944197f - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-lokalise githubIssueLabel: source-lokalise icon: lokalise.svg @@ -41,5 +41,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-looker/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-looker/integration_tests/acceptance.py index 88fa5a9d4eaa..70e25009b6b4 100644 --- a/airbyte-integrations/connectors/source-looker/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-looker/integration_tests/acceptance.py @@ -7,6 +7,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-looker/main.py b/airbyte-integrations/connectors/source-looker/main.py index b6164cb0322b..cb6f8adb314b 100644 --- a/airbyte-integrations/connectors/source-looker/main.py +++ b/airbyte-integrations/connectors/source-looker/main.py @@ -4,5 +4,6 @@ from source_looker.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-looker/metadata.yaml b/airbyte-integrations/connectors/source-looker/metadata.yaml index b76f7245fcc2..b4b32e52af22 100644 --- a/airbyte-integrations/connectors/source-looker/metadata.yaml +++ b/airbyte-integrations/connectors/source-looker/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 00405b19-9768-4e0c-b1ae-9fc2ee2b2a8c - dockerImageTag: 1.0.13 + dockerImageTag: 1.0.19 dockerRepository: airbyte/source-looker githubIssueLabel: source-looker icon: looker.svg @@ -41,5 +41,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-looker/poetry.lock b/airbyte-integrations/connectors/source-looker/poetry.lock index a7ace37cb722..9ff923de2b48 100644 --- a/airbyte-integrations/connectors/source-looker/poetry.lock +++ b/airbyte-integrations/connectors/source-looker/poetry.lock @@ -69,41 +69,41 @@ files = [ [[package]] name = "anyio" -version = "4.6.0" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.0-py3-none-any.whl", hash = "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a"}, - {file = "anyio-4.6.0.tar.gz", hash = "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -169,13 +169,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -259,127 +259,114 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -452,20 +439,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -515,13 +502,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -536,13 +523,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -550,7 +537,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -600,13 +586,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -707,18 +693,18 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.134" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.134-py3-none-any.whl", hash = "sha256:ada98ad80ef38807725f32441a472da3dd28394010877751f48f458d3289da04"}, - {file = "langsmith-0.1.134.tar.gz", hash = "sha256:23abee3b508875a0e63c602afafffc02442a19cfd88f9daae05b3e9054fd6b61"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = [ {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""}, {version = ">=2.7.4,<3.0.0", markers = "python_full_version >= \"3.12.4\""}, @@ -726,74 +712,77 @@ pydantic = [ requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" -version = "3.0.1" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" files = [ - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win32.whl", hash = "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win32.whl", hash = "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win32.whl", hash = "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win32.whl", hash = "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win32.whl", hash = "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b"}, - {file = "markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] @@ -823,68 +812,86 @@ twitter = ["twython"] [[package]] name = "orjson" -version = "3.10.7" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:74f4544f5a6405b90da8ea724d15ac9c36da4d72a738c64685003337401f5c12"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34a566f22c28222b08875b18b0dfbf8a947e69df21a9ed5c51a6bf91cfb944ac"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf6ba8ebc8ef5792e2337fb0419f8009729335bb400ece005606336b7fd7bab7"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac7cf6222b29fbda9e3a472b41e6a5538b48f2c8f99261eecd60aafbdb60690c"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de817e2f5fc75a9e7dd350c4b0f54617b280e26d1631811a43e7e968fa71e3e9"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:348bdd16b32556cf8d7257b17cf2bdb7ab7976af4af41ebe79f9796c218f7e91"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:479fd0844ddc3ca77e0fd99644c7fe2de8e8be1efcd57705b5c92e5186e8a250"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fdf5197a21dd660cf19dfd2a3ce79574588f8f5e2dbf21bda9ee2d2b46924d84"}, - {file = "orjson-3.10.7-cp310-none-win32.whl", hash = "sha256:d374d36726746c81a49f3ff8daa2898dccab6596864ebe43d50733275c629175"}, - {file = "orjson-3.10.7-cp310-none-win_amd64.whl", hash = "sha256:cb61938aec8b0ffb6eef484d480188a1777e67b05d58e41b435c74b9d84e0b9c"}, - {file = "orjson-3.10.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0"}, - {file = "orjson-3.10.7-cp311-none-win32.whl", hash = "sha256:82763b46053727a7168d29c772ed5c870fdae2f61aa8a25994c7984a19b1021f"}, - {file = "orjson-3.10.7-cp311-none-win_amd64.whl", hash = "sha256:eb8d384a24778abf29afb8e41d68fdd9a156cf6e5390c04cc07bbc24b89e98b5"}, - {file = "orjson-3.10.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44a96f2d4c3af51bfac6bc4ef7b182aa33f2f054fd7f34cc0ee9a320d051d41f"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ac14cd57df0572453543f8f2575e2d01ae9e790c21f57627803f5e79b0d3c3"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bdbb61dcc365dd9be94e8f7df91975edc9364d6a78c8f7adb69c1cdff318ec93"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b48b3db6bb6e0a08fa8c83b47bc169623f801e5cc4f24442ab2b6617da3b5313"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23820a1563a1d386414fef15c249040042b8e5d07b40ab3fe3efbfbbcbcb8864"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0c6a008e91d10a2564edbb6ee5069a9e66df3fbe11c9a005cb411f441fd2c09"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d352ee8ac1926d6193f602cbe36b1643bbd1bbcb25e3c1a657a4390f3000c9a5"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b"}, - {file = "orjson-3.10.7-cp312-none-win32.whl", hash = "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb"}, - {file = "orjson-3.10.7-cp312-none-win_amd64.whl", hash = "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1"}, - {file = "orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149"}, - {file = "orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad"}, - {file = "orjson-3.10.7-cp313-none-win32.whl", hash = "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2"}, - {file = "orjson-3.10.7-cp313-none-win_amd64.whl", hash = "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024"}, - {file = "orjson-3.10.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6ea2b2258eff652c82652d5e0f02bd5e0463a6a52abb78e49ac288827aaa1469"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:430ee4d85841e1483d487e7b81401785a5dfd69db5de01314538f31f8fbf7ee1"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b6146e439af4c2472c56f8540d799a67a81226e11992008cb47e1267a9b3225"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:084e537806b458911137f76097e53ce7bf5806dda33ddf6aaa66a028f8d43a23"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829cf2195838e3f93b70fd3b4292156fc5e097aac3739859ac0dcc722b27ac0"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1193b2416cbad1a769f868b1749535d5da47626ac29445803dae7cc64b3f5c98"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4e6c3da13e5a57e4b3dca2de059f243ebec705857522f188f0180ae88badd354"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c31008598424dfbe52ce8c5b47e0752dca918a4fdc4a2a32004efd9fab41d866"}, - {file = "orjson-3.10.7-cp38-none-win32.whl", hash = "sha256:7122a99831f9e7fe977dc45784d3b2edc821c172d545e6420c375e5a935f5a1c"}, - {file = "orjson-3.10.7-cp38-none-win_amd64.whl", hash = "sha256:a763bc0e58504cc803739e7df040685816145a6f3c8a589787084b54ebc9f16e"}, - {file = "orjson-3.10.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e76be12658a6fa376fcd331b1ea4e58f5a06fd0220653450f0d415b8fd0fbe20"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed350d6978d28b92939bfeb1a0570c523f6170efc3f0a0ef1f1df287cd4f4960"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144888c76f8520e39bfa121b31fd637e18d4cc2f115727865fdf9fa325b10412"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09b2d92fd95ad2402188cf51573acde57eb269eddabaa60f69ea0d733e789fe9"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b24a579123fa884f3a3caadaed7b75eb5715ee2b17ab5c66ac97d29b18fe57f"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591bcfe7512353bd609875ab38050efe3d55e18934e2f18950c108334b4ff"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f4db56635b58cd1a200b0a23744ff44206ee6aa428185e2b6c4a65b3197abdcd"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0fa5886854673222618638c6df7718ea7fe2f3f2384c452c9ccedc70b4a510a5"}, - {file = "orjson-3.10.7-cp39-none-win32.whl", hash = "sha256:8272527d08450ab16eb405f47e0f4ef0e5ff5981c3d82afe0efd25dcbef2bcd2"}, - {file = "orjson-3.10.7-cp39-none-win_amd64.whl", hash = "sha256:974683d4618c0c7dbf4f69c95a979734bf183d0658611760017f6e70a145af58"}, - {file = "orjson-3.10.7.tar.gz", hash = "sha256:75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -976,22 +983,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = [ - {version = ">=4.6.1", markers = "python_version < \"3.13\""}, - {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, -] +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -999,100 +1003,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -1100,13 +1115,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1173,13 +1188,13 @@ files = [ [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] @@ -1310,105 +1325,105 @@ files = [ [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -1495,33 +1510,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.1.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"}, - {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1552,31 +1567,62 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "tomli" -version = "2.0.2" +version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] [[package]] name = "tqdm" -version = "4.66.5" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd"}, - {file = "tqdm-4.66.5.tar.gz", hash = "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -1608,13 +1654,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1639,81 +1685,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-looker/pyproject.toml b/airbyte-integrations/connectors/source-looker/pyproject.toml index d00d04ef6bc8..6af424a567c3 100644 --- a/airbyte-integrations/connectors/source-looker/pyproject.toml +++ b/airbyte-integrations/connectors/source-looker/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "1.0.13" +version = "1.0.19" name = "source-looker" description = "Source implementation for looker." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-looker/source_looker/components.py b/airbyte-integrations/connectors/source-looker/source_looker/components.py index d30b120a5e97..60352fffd197 100644 --- a/airbyte-integrations/connectors/source-looker/source_looker/components.py +++ b/airbyte-integrations/connectors/source-looker/source_looker/components.py @@ -7,14 +7,15 @@ import pendulum import requests + from airbyte_cdk.sources.declarative.auth.declarative_authenticator import NoAuth + API_VERSION = "4.0" @dataclass class LookerAuthenticator(NoAuth): - """ Authenticator that sets the Authorization header on the HTTP requests sent using access token which is updated upon expiration. diff --git a/airbyte-integrations/connectors/source-looker/source_looker/source.py b/airbyte-integrations/connectors/source-looker/source_looker/source.py index 5a6e0487f5bb..7799272df347 100644 --- a/airbyte-integrations/connectors/source-looker/source_looker/source.py +++ b/airbyte-integrations/connectors/source-looker/source_looker/source.py @@ -7,6 +7,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource from airbyte_cdk.sources.streams.core import Stream + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-luma/metadata.yaml b/airbyte-integrations/connectors/source-luma/metadata.yaml index 2d1fe3dab145..f6327d30bfd0 100644 --- a/airbyte-integrations/connectors/source-luma/metadata.yaml +++ b/airbyte-integrations/connectors/source-luma/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-luma connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 8ac29756-9a9d-4472-a20b-df29ac29764a - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.10 dockerRepository: airbyte/source-luma githubIssueLabel: source-luma icon: icon.svg diff --git a/airbyte-integrations/connectors/source-mailchimp/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-mailchimp/integration_tests/acceptance.py index 43ce950d77ca..72132012aaed 100644 --- a/airbyte-integrations/connectors/source-mailchimp/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-mailchimp/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-mailchimp/main.py b/airbyte-integrations/connectors/source-mailchimp/main.py index c61875fb7a72..0145a6e026ef 100644 --- a/airbyte-integrations/connectors/source-mailchimp/main.py +++ b/airbyte-integrations/connectors/source-mailchimp/main.py @@ -4,5 +4,6 @@ from source_mailchimp.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-mailchimp/metadata.yaml b/airbyte-integrations/connectors/source-mailchimp/metadata.yaml index 2d3ef01d95dc..4f2902588b9f 100644 --- a/airbyte-integrations/connectors/source-mailchimp/metadata.yaml +++ b/airbyte-integrations/connectors/source-mailchimp/metadata.yaml @@ -7,11 +7,11 @@ data: - "*.api.mailchimp.com" - "login.mailchimp.com" connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: b03a9f3e-22a5-11eb-adc1-0242ac120002 - dockerImageTag: 2.0.19 + dockerImageTag: 2.0.24 dockerRepository: airbyte/source-mailchimp documentationUrl: https://docs.airbyte.com/integrations/sources/mailchimp githubIssueLabel: source-mailchimp diff --git a/airbyte-integrations/connectors/source-mailchimp/poetry.lock b/airbyte-integrations/connectors/source-mailchimp/poetry.lock index 74bf62930082..60a4cbdf5dd1 100644 --- a/airbyte-integrations/connectors/source-mailchimp/poetry.lock +++ b/airbyte-integrations/connectors/source-mailchimp/poetry.lock @@ -67,25 +67,25 @@ files = [ [[package]] name = "anyio" -version = "4.4.0" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, - {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (>=0.23)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] +trio = ["trio (>=0.26.1)"] [[package]] name = "atomicwrites" @@ -99,19 +99,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -129,13 +129,13 @@ files = [ [[package]] name = "bracex" -version = "2.5" +version = "2.5.post1" description = "Bash style brace expander." optional = false python-versions = ">=3.8" files = [ - {file = "bracex-2.5-py3-none-any.whl", hash = "sha256:d2fcf4b606a82ac325471affe1706dd9bbaa3536c91ef86a31f6b766f3dad1d0"}, - {file = "bracex-2.5.tar.gz", hash = "sha256:0725da5045e8d37ea9592ab3614d8b561e22c3c5fde3964699be672e072ab611"}, + {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, + {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, ] [[package]] @@ -151,13 +151,13 @@ files = [ [[package]] name = "cattrs" -version = "24.1.0" +version = "24.1.2" description = "Composable complex class support for attrs and dataclasses." optional = false python-versions = ">=3.8" files = [ - {file = "cattrs-24.1.0-py3-none-any.whl", hash = "sha256:043bb8af72596432a7df63abcff0055ac0f198a4d2e95af8db5a936a7074a761"}, - {file = "cattrs-24.1.0.tar.gz", hash = "sha256:8274f18b253bf7674a43da851e3096370d67088165d23138b04a1c04c8eaf48e"}, + {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, + {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, ] [package.dependencies] @@ -177,89 +177,89 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "cffi" -version = "1.17.0" +version = "1.17.1" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" files = [ - {file = "cffi-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9338cc05451f1942d0d8203ec2c346c830f8e86469903d5126c1f0a13a2bcbb"}, - {file = "cffi-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0ce71725cacc9ebf839630772b07eeec220cbb5f03be1399e0457a1464f8e1a"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c815270206f983309915a6844fe994b2fa47e5d05c4c4cef267c3b30e34dbe42"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6bdcd415ba87846fd317bee0774e412e8792832e7805938987e4ede1d13046d"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a98748ed1a1df4ee1d6f927e151ed6c1a09d5ec21684de879c7ea6aa96f58f2"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a048d4f6630113e54bb4b77e315e1ba32a5a31512c31a273807d0027a7e69ab"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24aa705a5f5bd3a8bcfa4d123f03413de5d86e497435693b638cbffb7d5d8a1b"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:856bf0924d24e7f93b8aee12a3a1095c34085600aa805693fb7f5d1962393206"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4304d4416ff032ed50ad6bb87416d802e67139e31c0bde4628f36a47a3164bfa"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:331ad15c39c9fe9186ceaf87203a9ecf5ae0ba2538c9e898e3a6967e8ad3db6f"}, - {file = "cffi-1.17.0-cp310-cp310-win32.whl", hash = "sha256:669b29a9eca6146465cc574659058ed949748f0809a2582d1f1a324eb91054dc"}, - {file = "cffi-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:48b389b1fd5144603d61d752afd7167dfd205973a43151ae5045b35793232aa2"}, - {file = "cffi-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5d97162c196ce54af6700949ddf9409e9833ef1003b4741c2b39ef46f1d9720"}, - {file = "cffi-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ba5c243f4004c750836f81606a9fcb7841f8874ad8f3bf204ff5e56332b72b9"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb9333f58fc3a2296fb1d54576138d4cf5d496a2cc118422bd77835e6ae0b9cb"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:435a22d00ec7d7ea533db494da8581b05977f9c37338c80bc86314bec2619424"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1df34588123fcc88c872f5acb6f74ae59e9d182a2707097f9e28275ec26a12d"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df8bb0010fdd0a743b7542589223a2816bdde4d94bb5ad67884348fa2c1c67e8"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b5b9712783415695663bd463990e2f00c6750562e6ad1d28e072a611c5f2a6"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffef8fd58a36fb5f1196919638f73dd3ae0db1a878982b27a9a5a176ede4ba91"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e67d26532bfd8b7f7c05d5a766d6f437b362c1bf203a3a5ce3593a645e870b8"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45f7cd36186db767d803b1473b3c659d57a23b5fa491ad83c6d40f2af58e4dbb"}, - {file = "cffi-1.17.0-cp311-cp311-win32.whl", hash = "sha256:a9015f5b8af1bb6837a3fcb0cdf3b874fe3385ff6274e8b7925d81ccaec3c5c9"}, - {file = "cffi-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:b50aaac7d05c2c26dfd50c3321199f019ba76bb650e346a6ef3616306eed67b0"}, - {file = "cffi-1.17.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aec510255ce690d240f7cb23d7114f6b351c733a74c279a84def763660a2c3bc"}, - {file = "cffi-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2770bb0d5e3cc0e31e7318db06efcbcdb7b31bcb1a70086d3177692a02256f59"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db9a30ec064129d605d0f1aedc93e00894b9334ec74ba9c6bdd08147434b33eb"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a47eef975d2b8b721775a0fa286f50eab535b9d56c70a6e62842134cf7841195"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3e0992f23bbb0be00a921eae5363329253c3b86287db27092461c887b791e5e"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6107e445faf057c118d5050560695e46d272e5301feffda3c41849641222a828"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb862356ee9391dc5a0b3cbc00f416b48c1b9a52d252d898e5b7696a5f9fe150"}, - {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c1c13185b90bbd3f8b5963cd8ce7ad4ff441924c31e23c975cb150e27c2bf67a"}, - {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17c6d6d3260c7f2d94f657e6872591fe8733872a86ed1345bda872cfc8c74885"}, - {file = "cffi-1.17.0-cp312-cp312-win32.whl", hash = "sha256:c3b8bd3133cd50f6b637bb4322822c94c5ce4bf0d724ed5ae70afce62187c492"}, - {file = "cffi-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:dca802c8db0720ce1c49cce1149ff7b06e91ba15fa84b1d59144fef1a1bc7ac2"}, - {file = "cffi-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6ce01337d23884b21c03869d2f68c5523d43174d4fc405490eb0091057943118"}, - {file = "cffi-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cab2eba3830bf4f6d91e2d6718e0e1c14a2f5ad1af68a89d24ace0c6b17cced7"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14b9cbc8f7ac98a739558eb86fabc283d4d564dafed50216e7f7ee62d0d25377"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b00e7bcd71caa0282cbe3c90966f738e2db91e64092a877c3ff7f19a1628fdcb"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:41f4915e09218744d8bae14759f983e466ab69b178de38066f7579892ff2a555"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4760a68cab57bfaa628938e9c2971137e05ce48e762a9cb53b76c9b569f1204"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:011aff3524d578a9412c8b3cfaa50f2c0bd78e03eb7af7aa5e0df59b158efb2f"}, - {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:a003ac9edc22d99ae1286b0875c460351f4e101f8c9d9d2576e78d7e048f64e0"}, - {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ef9528915df81b8f4c7612b19b8628214c65c9b7f74db2e34a646a0a2a0da2d4"}, - {file = "cffi-1.17.0-cp313-cp313-win32.whl", hash = "sha256:70d2aa9fb00cf52034feac4b913181a6e10356019b18ef89bc7c12a283bf5f5a"}, - {file = "cffi-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7"}, - {file = "cffi-1.17.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:964823b2fc77b55355999ade496c54dde161c621cb1f6eac61dc30ed1b63cd4c"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:516a405f174fd3b88829eabfe4bb296ac602d6a0f68e0d64d5ac9456194a5b7e"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dec6b307ce928e8e112a6bb9921a1cb00a0e14979bf28b98e084a4b8a742bd9b"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4094c7b464cf0a858e75cd14b03509e84789abf7b79f8537e6a72152109c76e"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2404f3de742f47cb62d023f0ba7c5a916c9c653d5b368cc966382ae4e57da401"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa9d43b02a0c681f0bfbc12d476d47b2b2b6a3f9287f11ee42989a268a1833c"}, - {file = "cffi-1.17.0-cp38-cp38-win32.whl", hash = "sha256:0bb15e7acf8ab35ca8b24b90af52c8b391690ef5c4aec3d31f38f0d37d2cc499"}, - {file = "cffi-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:93a7350f6706b31f457c1457d3a3259ff9071a66f312ae64dc024f049055f72c"}, - {file = "cffi-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a2ddbac59dc3716bc79f27906c010406155031a1c801410f1bafff17ea304d2"}, - {file = "cffi-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6327b572f5770293fc062a7ec04160e89741e8552bf1c358d1a23eba68166759"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbc183e7bef690c9abe5ea67b7b60fdbca81aa8da43468287dae7b5c046107d4"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bdc0f1f610d067c70aa3737ed06e2726fd9d6f7bfee4a351f4c40b6831f4e82"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d872186c1617d143969defeadac5a904e6e374183e07977eedef9c07c8953bf"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d46ee4764b88b91f16661a8befc6bfb24806d885e27436fdc292ed7e6f6d058"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f76a90c345796c01d85e6332e81cab6d70de83b829cf1d9762d0a3da59c7932"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e60821d312f99d3e1569202518dddf10ae547e799d75aef3bca3a2d9e8ee693"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:eb09b82377233b902d4c3fbeeb7ad731cdab579c6c6fda1f763cd779139e47c3"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:24658baf6224d8f280e827f0a50c46ad819ec8ba380a42448e24459daf809cf4"}, - {file = "cffi-1.17.0-cp39-cp39-win32.whl", hash = "sha256:0fdacad9e0d9fc23e519efd5ea24a70348305e8d7d85ecbb1a5fa66dc834e7fb"}, - {file = "cffi-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:7cbc78dc018596315d4e7841c8c3a7ae31cc4d638c9b627f87d52e8abaaf2d29"}, - {file = "cffi-1.17.0.tar.gz", hash = "sha256:f3157624b7558b914cb039fd1af735e5e8049a87c817cc215109ad1c8779df76"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, + {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, + {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, + {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, + {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, ] [package.dependencies] @@ -267,101 +267,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.3.2" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -431,20 +433,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -508,13 +510,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.5" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"}, - {file = "httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -525,17 +527,17 @@ h11 = ">=0.13,<0.15" asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<0.26.0)"] +trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -543,7 +545,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -554,15 +555,18 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "idna" -version = "3.8" +version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" files = [ - {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"}, - {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, ] +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -590,13 +594,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -686,154 +690,177 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.108" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.108-py3-none-any.whl", hash = "sha256:407f318b0989e33f2cd30bc2fbd443e4ddfa7c2a93de7f795fb6b119b015583c"}, - {file = "langsmith-0.1.108.tar.gz", hash = "sha256:42f603e2d5770ba36093951bdb29eaab22451cb12ab8c062340c722cf60d4cec"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" +requests-toolbelt = ">=1.0.0,<2.0.0" + +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] [[package]] name = "markupsafe" -version = "2.1.5" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false -python-versions = ">=3.7" -files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +python-versions = ">=3.9" +files = [ + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] name = "orjson" -version = "3.10.7" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:74f4544f5a6405b90da8ea724d15ac9c36da4d72a738c64685003337401f5c12"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34a566f22c28222b08875b18b0dfbf8a947e69df21a9ed5c51a6bf91cfb944ac"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf6ba8ebc8ef5792e2337fb0419f8009729335bb400ece005606336b7fd7bab7"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac7cf6222b29fbda9e3a472b41e6a5538b48f2c8f99261eecd60aafbdb60690c"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de817e2f5fc75a9e7dd350c4b0f54617b280e26d1631811a43e7e968fa71e3e9"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:348bdd16b32556cf8d7257b17cf2bdb7ab7976af4af41ebe79f9796c218f7e91"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:479fd0844ddc3ca77e0fd99644c7fe2de8e8be1efcd57705b5c92e5186e8a250"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fdf5197a21dd660cf19dfd2a3ce79574588f8f5e2dbf21bda9ee2d2b46924d84"}, - {file = "orjson-3.10.7-cp310-none-win32.whl", hash = "sha256:d374d36726746c81a49f3ff8daa2898dccab6596864ebe43d50733275c629175"}, - {file = "orjson-3.10.7-cp310-none-win_amd64.whl", hash = "sha256:cb61938aec8b0ffb6eef484d480188a1777e67b05d58e41b435c74b9d84e0b9c"}, - {file = "orjson-3.10.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0"}, - {file = "orjson-3.10.7-cp311-none-win32.whl", hash = "sha256:82763b46053727a7168d29c772ed5c870fdae2f61aa8a25994c7984a19b1021f"}, - {file = "orjson-3.10.7-cp311-none-win_amd64.whl", hash = "sha256:eb8d384a24778abf29afb8e41d68fdd9a156cf6e5390c04cc07bbc24b89e98b5"}, - {file = "orjson-3.10.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44a96f2d4c3af51bfac6bc4ef7b182aa33f2f054fd7f34cc0ee9a320d051d41f"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ac14cd57df0572453543f8f2575e2d01ae9e790c21f57627803f5e79b0d3c3"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bdbb61dcc365dd9be94e8f7df91975edc9364d6a78c8f7adb69c1cdff318ec93"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b48b3db6bb6e0a08fa8c83b47bc169623f801e5cc4f24442ab2b6617da3b5313"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23820a1563a1d386414fef15c249040042b8e5d07b40ab3fe3efbfbbcbcb8864"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0c6a008e91d10a2564edbb6ee5069a9e66df3fbe11c9a005cb411f441fd2c09"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d352ee8ac1926d6193f602cbe36b1643bbd1bbcb25e3c1a657a4390f3000c9a5"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b"}, - {file = "orjson-3.10.7-cp312-none-win32.whl", hash = "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb"}, - {file = "orjson-3.10.7-cp312-none-win_amd64.whl", hash = "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1"}, - {file = "orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149"}, - {file = "orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad"}, - {file = "orjson-3.10.7-cp313-none-win32.whl", hash = "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2"}, - {file = "orjson-3.10.7-cp313-none-win_amd64.whl", hash = "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024"}, - {file = "orjson-3.10.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6ea2b2258eff652c82652d5e0f02bd5e0463a6a52abb78e49ac288827aaa1469"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:430ee4d85841e1483d487e7b81401785a5dfd69db5de01314538f31f8fbf7ee1"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b6146e439af4c2472c56f8540d799a67a81226e11992008cb47e1267a9b3225"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:084e537806b458911137f76097e53ce7bf5806dda33ddf6aaa66a028f8d43a23"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829cf2195838e3f93b70fd3b4292156fc5e097aac3739859ac0dcc722b27ac0"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1193b2416cbad1a769f868b1749535d5da47626ac29445803dae7cc64b3f5c98"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4e6c3da13e5a57e4b3dca2de059f243ebec705857522f188f0180ae88badd354"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c31008598424dfbe52ce8c5b47e0752dca918a4fdc4a2a32004efd9fab41d866"}, - {file = "orjson-3.10.7-cp38-none-win32.whl", hash = "sha256:7122a99831f9e7fe977dc45784d3b2edc821c172d545e6420c375e5a935f5a1c"}, - {file = "orjson-3.10.7-cp38-none-win_amd64.whl", hash = "sha256:a763bc0e58504cc803739e7df040685816145a6f3c8a589787084b54ebc9f16e"}, - {file = "orjson-3.10.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e76be12658a6fa376fcd331b1ea4e58f5a06fd0220653450f0d415b8fd0fbe20"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed350d6978d28b92939bfeb1a0570c523f6170efc3f0a0ef1f1df287cd4f4960"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144888c76f8520e39bfa121b31fd637e18d4cc2f115727865fdf9fa325b10412"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09b2d92fd95ad2402188cf51573acde57eb269eddabaa60f69ea0d733e789fe9"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b24a579123fa884f3a3caadaed7b75eb5715ee2b17ab5c66ac97d29b18fe57f"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591bcfe7512353bd609875ab38050efe3d55e18934e2f18950c108334b4ff"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f4db56635b58cd1a200b0a23744ff44206ee6aa428185e2b6c4a65b3197abdcd"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0fa5886854673222618638c6df7718ea7fe2f3f2384c452c9ccedc70b4a510a5"}, - {file = "orjson-3.10.7-cp39-none-win32.whl", hash = "sha256:8272527d08450ab16eb405f47e0f4ef0e5ff5981c3d82afe0efd25dcbef2bcd2"}, - {file = "orjson-3.10.7-cp39-none-win_amd64.whl", hash = "sha256:974683d4618c0c7dbf4f69c95a979734bf183d0658611760017f6e70a145af58"}, - {file = "orjson-3.10.7.tar.gz", hash = "sha256:75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -883,19 +910,19 @@ pytzdata = ">=2020.1" [[package]] name = "platformdirs" -version = "4.2.2" +version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, - {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "pluggy" @@ -936,119 +963,131 @@ files = [ [[package]] name = "pydantic" -version = "2.8.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, - {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] -annotated-types = ">=0.4.0" -pydantic-core = "2.20.1" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +annotated-types = ">=0.6.0" +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] +timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.20.1" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, - {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, - {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, - {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, - {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, - {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, - {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, - {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, - {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, - {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, - {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, - {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, - {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, - {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, - {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, - {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, - {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, - {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, - {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, - {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, - {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, - {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, - {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, - {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, - {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, - {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, - {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, - {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, - {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, - {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, - {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, - {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, - {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, - {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, - {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -1056,13 +1095,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1334,35 +1373,49 @@ requests = ">=2.22,<3" [package.extras] fixture = ["fixtures"] +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +description = "A utility belt for advanced users of python-requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, + {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, +] + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + [[package]] name = "setuptools" -version = "74.0.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-74.0.0-py3-none-any.whl", hash = "sha256:0274581a0037b638b9fc1c6883cc71c0210865aaa76073f7882376b641b84e8f"}, - {file = "setuptools-74.0.0.tar.gz", hash = "sha256:a85e96b8be2b906f3e3e789adec6a9323abf79758ecfa3065bd740d81158b11e"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1429,13 +1482,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.2" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, - {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1460,81 +1513,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-mailchimp/pyproject.toml b/airbyte-integrations/connectors/source-mailchimp/pyproject.toml index f2c929e7e9fe..d4e091fbacb2 100644 --- a/airbyte-integrations/connectors/source-mailchimp/pyproject.toml +++ b/airbyte-integrations/connectors/source-mailchimp/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "2.0.19" +version = "2.0.24" name = "source-mailchimp" description = "Source implementation for Mailchimp." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-mailchimp/source_mailchimp/components.py b/airbyte-integrations/connectors/source-mailchimp/source_mailchimp/components.py index 6df59797f6ae..f853ec6a4687 100644 --- a/airbyte-integrations/connectors/source-mailchimp/source_mailchimp/components.py +++ b/airbyte-integrations/connectors/source-mailchimp/source_mailchimp/components.py @@ -3,6 +3,7 @@ from typing import Any, Iterable, Mapping import requests + from airbyte_cdk.sources.declarative.extractors import DpathExtractor diff --git a/airbyte-integrations/connectors/source-mailchimp/source_mailchimp/config_migrations.py b/airbyte-integrations/connectors/source-mailchimp/source_mailchimp/config_migrations.py index 621edd5763f1..4952fac913eb 100644 --- a/airbyte-integrations/connectors/source-mailchimp/source_mailchimp/config_migrations.py +++ b/airbyte-integrations/connectors/source-mailchimp/source_mailchimp/config_migrations.py @@ -7,11 +7,13 @@ from typing import Any, List, Mapping import requests + from airbyte_cdk.config_observation import create_connector_config_control_message from airbyte_cdk.entrypoint import AirbyteEntrypoint +from airbyte_cdk.models import FailureType from airbyte_cdk.sources import Source from airbyte_cdk.utils import AirbyteTracedException -from airbyte_protocol.models import FailureType + logger = logging.getLogger("airbyte_logger") diff --git a/airbyte-integrations/connectors/source-mailchimp/unit_tests/integration/test_automations.py b/airbyte-integrations/connectors/source-mailchimp/unit_tests/integration/test_automations.py index 602562aa2db4..1b37739b4ab4 100644 --- a/airbyte-integrations/connectors/source-mailchimp/unit_tests/integration/test_automations.py +++ b/airbyte-integrations/connectors/source-mailchimp/unit_tests/integration/test_automations.py @@ -4,16 +4,18 @@ from unittest import TestCase import freezegun +from source_mailchimp import SourceMailchimp + from airbyte_cdk.models import SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import read from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse from airbyte_cdk.test.mock_http.response_builder import find_template from airbyte_cdk.test.state_builder import StateBuilder -from source_mailchimp import SourceMailchimp from .config import ConfigBuilder + _CONFIG = ConfigBuilder().with_start_date(datetime.datetime(2023, 1, 1, 0, 0, 0, 1000)).build() diff --git a/airbyte-integrations/connectors/source-mailchimp/unit_tests/test_component_custom_email_activity_extractor.py b/airbyte-integrations/connectors/source-mailchimp/unit_tests/test_component_custom_email_activity_extractor.py index 7f9ad40d0c7f..ec7029480f6a 100644 --- a/airbyte-integrations/connectors/source-mailchimp/unit_tests/test_component_custom_email_activity_extractor.py +++ b/airbyte-integrations/connectors/source-mailchimp/unit_tests/test_component_custom_email_activity_extractor.py @@ -6,9 +6,10 @@ import json import requests -from airbyte_cdk.sources.declarative.decoders import JsonDecoder from source_mailchimp.components import MailChimpRecordExtractorEmailActivity +from airbyte_cdk.sources.declarative.decoders import JsonDecoder + def test_email_activity_extractor(): decoder = JsonDecoder(parameters={}) diff --git a/airbyte-integrations/connectors/source-mailchimp/unit_tests/test_config_datacenter_migration.py b/airbyte-integrations/connectors/source-mailchimp/unit_tests/test_config_datacenter_migration.py index 20fe8312352e..b6d0e41de2c2 100644 --- a/airbyte-integrations/connectors/source-mailchimp/unit_tests/test_config_datacenter_migration.py +++ b/airbyte-integrations/connectors/source-mailchimp/unit_tests/test_config_datacenter_migration.py @@ -6,10 +6,12 @@ from typing import Any, Mapping import pytest -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource from source_mailchimp import SourceMailchimp from source_mailchimp.config_migrations import MigrateDataCenter +from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + + # BASE ARGS SOURCE: YamlDeclarativeSource = SourceMailchimp() diff --git a/airbyte-integrations/connectors/source-mailerlite/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-mailerlite/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-mailerlite/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-mailerlite/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-mailersend/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-mailersend/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-mailersend/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-mailersend/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-mailersend/metadata.yaml b/airbyte-integrations/connectors/source-mailersend/metadata.yaml index c5259fd0fecb..aed6acb6339d 100644 --- a/airbyte-integrations/connectors/source-mailersend/metadata.yaml +++ b/airbyte-integrations/connectors/source-mailersend/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 2707d529-3c04-46eb-9c7e-40d4038df6f7 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.8 dockerRepository: airbyte/source-mailersend githubIssueLabel: source-mailersend icon: mailersend.svg @@ -38,5 +38,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-mailgun/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-mailgun/integration_tests/acceptance.py index d49b55882333..a9256a533972 100644 --- a/airbyte-integrations/connectors/source-mailgun/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-mailgun/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-mailgun/metadata.yaml b/airbyte-integrations/connectors/source-mailgun/metadata.yaml index e00e18f85529..ba12c8c1f461 100644 --- a/airbyte-integrations/connectors/source-mailgun/metadata.yaml +++ b/airbyte-integrations/connectors/source-mailgun/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - https://api.mailgun.net/ connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.4.3@sha256:8937b693c7e01087f6e86e683826ac20f160f7952b8f0a13cbf4f9bfdd7af570 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 5b9cb09e-1003-4f9c-983d-5779d1b2cd51 - dockerImageTag: 0.3.1 + dockerImageTag: 0.3.5 dockerRepository: airbyte/source-mailgun documentationUrl: https://docs.airbyte.com/integrations/sources/mailgun githubIssueLabel: source-mailgun diff --git a/airbyte-integrations/connectors/source-mailjet-mail/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-mailjet-mail/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-mailjet-mail/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-mailjet-mail/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-mailjet-sms/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-mailjet-sms/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-mailjet-sms/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-mailjet-sms/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-mailjet-sms/metadata.yaml b/airbyte-integrations/connectors/source-mailjet-sms/metadata.yaml index 4c5bfa03d19b..e20512abc582 100644 --- a/airbyte-integrations/connectors/source-mailjet-sms/metadata.yaml +++ b/airbyte-integrations/connectors/source-mailjet-sms/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 6ec2acea-7fd1-4378-b403-41a666e0c028 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-mailjet-sms documentationUrl: https://docs.airbyte.com/integrations/sources/mailjet-sms githubIssueLabel: source-mailjet-sms diff --git a/airbyte-integrations/connectors/source-mailosaur/README.md b/airbyte-integrations/connectors/source-mailosaur/README.md new file mode 100644 index 000000000000..421743479ec3 --- /dev/null +++ b/airbyte-integrations/connectors/source-mailosaur/README.md @@ -0,0 +1,35 @@ +# Mailosaur +This directory contains the manifest-only connector for `source-mailosaur`. + +Mailosaur is a communication-testing platform . +With this connector we can easily fetch data from messages , servers and transactions streams! +Docs : https://mailosaur.com/docs + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-mailosaur:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-mailosaur build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-mailosaur test +``` + diff --git a/airbyte-integrations/connectors/source-mailosaur/acceptance-test-config.yml b/airbyte-integrations/connectors/source-mailosaur/acceptance-test-config.yml new file mode 100644 index 000000000000..4f5e243e8157 --- /dev/null +++ b/airbyte-integrations/connectors/source-mailosaur/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-mailosaur:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-mailosaur/icon.svg b/airbyte-integrations/connectors/source-mailosaur/icon.svg new file mode 100644 index 000000000000..30f7e2a68984 --- /dev/null +++ b/airbyte-integrations/connectors/source-mailosaur/icon.svg @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/airbyte-integrations/connectors/source-mailosaur/manifest.yaml b/airbyte-integrations/connectors/source-mailosaur/manifest.yaml new file mode 100644 index 000000000000..e5d76eba8770 --- /dev/null +++ b/airbyte-integrations/connectors/source-mailosaur/manifest.yaml @@ -0,0 +1,319 @@ +version: 6.1.0 + +type: DeclarativeSource + +description: >- + Mailosaur is a communication-testing platform . + + With this connector we can easily fetch data from messages , servers and + transactions streams! + + Docs : https://mailosaur.com/docs + +check: + type: CheckStream + stream_names: + - messages + +definitions: + streams: + messages: + type: DeclarativeStream + name: messages + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: messages + http_method: GET + request_parameters: + server: "{{ config['serverid'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: id + stream: + $ref: "#/definitions/streams/servers" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/messages" + servers: + type: DeclarativeStream + name: servers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: servers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/servers" + usage_transactions: + type: DeclarativeStream + name: usage_transactions + primary_key: + - timestamp + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: usage/transactions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/usage_transactions" + base_requester: + type: HttpRequester + url_base: https://mailosaur.com/api/ + authenticator: + type: BasicHttpAuthenticator + password: "{{ config[\"password\"] }}" + username: "{{ config[\"username\"] }}" + +streams: + - $ref: "#/definitions/streams/messages" + - $ref: "#/definitions/streams/servers" + - $ref: "#/definitions/streams/usage_transactions" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - username + properties: + username: + type: string + description: Enter "api" here + order: 0 + title: Username + password: + type: string + description: Enter your api key here + order: 1 + title: Password + always_show: true + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + messages: true + servers: true + usage_transactions: true + testedStreams: + messages: + streamHash: 43790685c6e14b63e2a804a1c3cb127b4ee0c979 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + servers: + streamHash: 116974be4035e4e5b2430535df86d0705e77822b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + usage_transactions: + streamHash: 78e92edef1f21ffc93b2de6d99fd562fabb2788b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + messages: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + attachments: + type: + - number + - "null" + bcc: + type: + - array + - "null" + cc: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + name: + type: + - string + - "null" + from: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: string + read: + type: + - boolean + - "null" + received: + type: + - string + - "null" + server: + type: + - string + - "null" + subject: + type: + - string + - "null" + summary: + type: + - string + - "null" + to: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + name: + type: + - string + - "null" + required: + - id + servers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + customId: + type: + - string + - "null" + domain: + type: + - string + - "null" + id: + type: string + messages: + type: + - number + - "null" + name: + type: + - string + - "null" + restricted: + type: + - boolean + - "null" + retention: + type: + - number + - "null" + users: + type: + - array + - "null" + required: + - id + usage_transactions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + email: + type: + - number + - "null" + emailSent: + type: + - number + - "null" + previews: + type: + - number + - "null" + screenshots: + type: + - number + - "null" + sms: + type: + - number + - "null" + smsSent: + type: + - number + - "null" + timestamp: + type: string + required: + - timestamp diff --git a/airbyte-integrations/connectors/source-mailosaur/metadata.yaml b/airbyte-integrations/connectors/source-mailosaur/metadata.yaml new file mode 100644 index 000000000000..217f62e04797 --- /dev/null +++ b/airbyte-integrations/connectors/source-mailosaur/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "mailosaur.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-mailosaur + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 251ed5c8-a927-4fb4-ad45-75393d564f3c + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-mailosaur + githubIssueLabel: source-mailosaur + icon: icon.svg + license: MIT + name: Mailosaur + releaseDate: 2024-11-04 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/mailosaur + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-mailtrap/README.md b/airbyte-integrations/connectors/source-mailtrap/README.md new file mode 100644 index 000000000000..55940c278116 --- /dev/null +++ b/airbyte-integrations/connectors/source-mailtrap/README.md @@ -0,0 +1,33 @@ +# Mailtrap +This directory contains the manifest-only connector for `source-mailtrap`. + +API Documentation: https://api-docs.mailtrap.io/docs/mailtrap-api-docs/5tjdeg9545058-mailtrap-api + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-mailtrap:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-mailtrap build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-mailtrap test +``` + diff --git a/airbyte-integrations/connectors/source-mailtrap/acceptance-test-config.yml b/airbyte-integrations/connectors/source-mailtrap/acceptance-test-config.yml new file mode 100644 index 000000000000..0475a836f260 --- /dev/null +++ b/airbyte-integrations/connectors/source-mailtrap/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-mailtrap:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-mailtrap/icon.svg b/airbyte-integrations/connectors/source-mailtrap/icon.svg new file mode 100644 index 000000000000..8149a2ce7e52 --- /dev/null +++ b/airbyte-integrations/connectors/source-mailtrap/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-mailtrap/manifest.yaml b/airbyte-integrations/connectors/source-mailtrap/manifest.yaml new file mode 100644 index 000000000000..7f82ca31ef61 --- /dev/null +++ b/airbyte-integrations/connectors/source-mailtrap/manifest.yaml @@ -0,0 +1,1155 @@ +version: 5.14.0 + +type: DeclarativeSource + +description: >- + API Documentation: + https://api-docs.mailtrap.io/docs/mailtrap-api-docs/5tjdeg9545058-mailtrap-api + +check: + type: CheckStream + stream_names: + - accounts + +definitions: + streams: + accounts: + type: DeclarativeStream + name: accounts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: accounts + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 2 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 5 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: Rate limit hit + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounts" + billing_usage: + type: DeclarativeStream + name: billing_usage + primary_key: + - uuid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: accounts/{{ stream_partition.account_id }}/billing/usage + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 2 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 5 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: Rate limit hit + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: account_id + stream: + $ref: "#/definitions/streams/accounts" + transformations: + - type: AddFields + fields: + - path: + - uuid + value: "{{ now_utc() }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/billing_usage" + resources: + type: DeclarativeStream + name: resources + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: accounts/{{ stream_partition.account_id }}/permissions/resources + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 2 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 5 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: Rate limit hit + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: account_id + stream: + $ref: "#/definitions/streams/accounts" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/resources" + sending_domains: + type: DeclarativeStream + name: sending_domains + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: accounts/{{ stream_partition.account_id }}/sending_domains + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 2 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 5 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: Rate limit hit + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: account_id + stream: + $ref: "#/definitions/streams/accounts" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sending_domains" + inboxes: + type: DeclarativeStream + name: inboxes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: accounts/{{ stream_partition.account_id }}/inboxes + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 2 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 5 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: Rate limit hit + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: account_id + stream: + $ref: "#/definitions/streams/accounts" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/inboxes" + messages: + type: DeclarativeStream + name: messages + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + accounts/{{ stream_partition.account_id }}/inboxes/{{ + stream_partition.inbox_id }}/messages + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 2 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 5 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: Rate limit hit + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: account_id + stream: + $ref: "#/definitions/streams/accounts" + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: inbox_id + stream: + $ref: "#/definitions/streams/inboxes" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/messages" + projects: + type: DeclarativeStream + name: projects + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: accounts/{{ stream_partition.account_id }}/projects + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 2 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 5 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: Rate limit hit + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: account_id + stream: + $ref: "#/definitions/streams/accounts" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/projects" + base_requester: + type: HttpRequester + url_base: https://mailtrap.io/api/ + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"api_token\"] }}" + +streams: + - $ref: "#/definitions/streams/accounts" + - $ref: "#/definitions/streams/billing_usage" + - $ref: "#/definitions/streams/resources" + - $ref: "#/definitions/streams/sending_domains" + - $ref: "#/definitions/streams/inboxes" + - $ref: "#/definitions/streams/messages" + - $ref: "#/definitions/streams/projects" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_token + properties: + api_token: + type: string + description: API token to use. Find it at https://mailtrap.io/account + name: api_token + order: 0 + title: API Token + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + accounts: true + billing_usage: true + resources: true + sending_domains: true + inboxes: true + messages: true + projects: true + testedStreams: + accounts: + hasRecords: true + streamHash: e5312e6c96d51bb45ad0910a266c2a8a12893f65 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + billing_usage: + hasRecords: true + streamHash: a7d463733dea7e568d8fd727cbde0af816e06c45 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + resources: + hasRecords: true + streamHash: 08e015bb3f7c5625c5a75063e366b5452e63b6b4 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + sending_domains: + hasRecords: true + streamHash: dd3d752192bccdc0a2b271323ce61dfe5331ccdd + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + inboxes: + hasRecords: true + streamHash: 387ee5198b1fcd6c2cd7e474c678e8562c8c4051 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + messages: + hasRecords: true + streamHash: ee5d6c933ba155fa4309c80a2cd29723987829d6 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + projects: + hasRecords: true + streamHash: 550f74784aa329550a3d52b8b7ddee52f4d17ba9 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://api-docs.mailtrap.io/docs/mailtrap-api-docs/82708d3cc9606-general + +schemas: + accounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + access_levels: + type: + - array + - "null" + items: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + required: + - id + billing_usage: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + billing: + type: + - object + - "null" + properties: + cycle_end: + type: + - string + - "null" + cycle_start: + type: + - string + - "null" + sending: + type: + - object + - "null" + properties: + plan: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + usage: + type: + - object + - "null" + properties: + sent_messages_count: + type: + - object + - "null" + properties: + current: + type: + - number + - "null" + limit: + type: + - number + - "null" + testing: + type: + - object + - "null" + properties: + plan: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + usage: + type: + - object + - "null" + properties: + forwarded_messages_count: + type: + - object + - "null" + properties: + current: + type: + - number + - "null" + limit: + type: + - number + - "null" + sent_messages_count: + type: + - object + - "null" + properties: + current: + type: + - number + - "null" + limit: + type: + - number + - "null" + uuid: + type: string + required: + - uuid + resources: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + access_level: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + resources: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + access_level: + type: + - number + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + resources: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + access_level: + type: + - number + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + resources: + type: + - array + - "null" + required: + - id + sending_domains: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + auto_bcc_config: + type: + - object + - "null" + properties: + emails: + type: + - array + - "null" + headers: + type: + - array + - "null" + auto_unsubscribe_link_enabled: + type: + - boolean + - "null" + click_tracking_enabled: + type: + - boolean + - "null" + compliance_status: + type: + - string + - "null" + critical_alerts_enabled: + type: + - boolean + - "null" + custom_domain_tracking_enabled: + type: + - boolean + - "null" + demo: + type: + - boolean + - "null" + dns_records: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + domain: + type: + - string + - "null" + key: + type: + - string + - "null" + name: + type: + - string + - "null" + status: + type: + - string + - "null" + value: + type: + - string + - "null" + dns_verified: + type: + - boolean + - "null" + domain_name: + type: + - string + - "null" + health_alerts_enabled: + type: + - boolean + - "null" + id: + type: number + open_tracking_enabled: + type: + - boolean + - "null" + permissions: + type: + - object + - "null" + properties: + can_destroy: + type: + - boolean + - "null" + can_read: + type: + - boolean + - "null" + can_update: + type: + - boolean + - "null" + tracking_domain_name: + type: + - string + - "null" + required: + - id + inboxes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + api_domain: + type: + - string + - "null" + domain: + type: + - string + - "null" + email_domain: + type: + - string + - "null" + email_username: + type: + - string + - "null" + email_username_enabled: + type: + - boolean + - "null" + emails_count: + type: + - number + - "null" + emails_unread_count: + type: + - number + - "null" + forward_from_email_address: + type: + - string + - "null" + forwarded_messages_count: + type: + - number + - "null" + id: + type: number + max_message_size: + type: + - number + - "null" + max_size: + type: + - number + - "null" + name: + type: + - string + - "null" + password: + type: + - string + - "null" + permissions: + type: + - object + - "null" + properties: + can_destroy: + type: + - boolean + - "null" + can_leave: + type: + - boolean + - "null" + can_read: + type: + - boolean + - "null" + can_update: + type: + - boolean + - "null" + pop3_domain: + type: + - string + - "null" + pop3_ports: + type: + - array + - "null" + items: + type: + - number + - "null" + project_id: + type: + - number + - "null" + sent_messages_count: + type: + - number + - "null" + smtp_ports: + type: + - array + - "null" + items: + type: + - number + - "null" + status: + type: + - string + - "null" + used: + type: + - boolean + - "null" + username: + type: + - string + - "null" + required: + - id + messages: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + blacklists_report_info: + type: + - object + - "null" + properties: + domain: + type: + - string + - "null" + ip: + type: + - string + - "null" + report: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + in_black_list: + type: + - boolean + - "null" + name: + type: + - string + - "null" + url: + type: + - string + - "null" + result: + type: + - string + - "null" + created_at: + type: + - string + - "null" + download_path: + type: + - string + - "null" + email_size: + type: + - number + - "null" + from_email: + type: + - string + - "null" + from_name: + type: + - string + - "null" + html_body_size: + type: + - number + - "null" + html_path: + type: + - string + - "null" + html_source_path: + type: + - string + - "null" + human_size: + type: + - string + - "null" + id: + type: number + inbox_id: + type: + - number + - "null" + is_read: + type: + - boolean + - "null" + raw_path: + type: + - string + - "null" + sent_at: + type: + - string + - "null" + smtp_information: + type: + - object + - "null" + properties: + ok: + type: + - boolean + - "null" + subject: + type: + - string + - "null" + text_body_size: + type: + - number + - "null" + to_email: + type: + - string + - "null" + to_name: + type: + - string + - "null" + txt_path: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + projects: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: number + inboxes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + api_domain: + type: + - string + - "null" + domain: + type: + - string + - "null" + email_domain: + type: + - string + - "null" + email_username: + type: + - string + - "null" + email_username_enabled: + type: + - boolean + - "null" + emails_count: + type: + - number + - "null" + emails_unread_count: + type: + - number + - "null" + forward_from_email_address: + type: + - string + - "null" + forwarded_messages_count: + type: + - number + - "null" + id: + type: + - number + - "null" + last_message_sent_at: + type: + - string + - "null" + max_message_size: + type: + - number + - "null" + max_size: + type: + - number + - "null" + name: + type: + - string + - "null" + password: + type: + - string + - "null" + permissions: + type: + - object + - "null" + properties: + can_destroy: + type: + - boolean + - "null" + can_leave: + type: + - boolean + - "null" + can_read: + type: + - boolean + - "null" + can_update: + type: + - boolean + - "null" + pop3_domain: + type: + - string + - "null" + pop3_ports: + type: + - array + - "null" + items: + type: + - number + - "null" + project_id: + type: + - number + - "null" + sent_messages_count: + type: + - number + - "null" + smtp_ports: + type: + - array + - "null" + items: + type: + - number + - "null" + status: + type: + - string + - "null" + used: + type: + - boolean + - "null" + username: + type: + - string + - "null" + name: + type: + - string + - "null" + permissions: + type: + - object + - "null" + properties: + can_destroy: + type: + - boolean + - "null" + can_leave: + type: + - boolean + - "null" + can_read: + type: + - boolean + - "null" + can_update: + type: + - boolean + - "null" + share_links: + type: + - object + - "null" + properties: + admin: + type: + - string + - "null" + viewer: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-mailtrap/metadata.yaml b/airbyte-integrations/connectors/source-mailtrap/metadata.yaml new file mode 100644 index 000000000000..bc0083a7b215 --- /dev/null +++ b/airbyte-integrations/connectors/source-mailtrap/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "mailtrap.io" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-mailtrap + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 9ba00df2-313c-46f2-b102-a5063a1ee18a + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-mailtrap + githubIssueLabel: source-mailtrap + icon: icon.svg + license: MIT + name: Mailtrap + releaseDate: 2024-10-23 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/mailtrap + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-marketo/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-marketo/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-marketo/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-marketo/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-marketo/main.py b/airbyte-integrations/connectors/source-marketo/main.py index 4b7b8e8d1708..0b087d968a27 100644 --- a/airbyte-integrations/connectors/source-marketo/main.py +++ b/airbyte-integrations/connectors/source-marketo/main.py @@ -4,5 +4,6 @@ from source_marketo.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-marketo/metadata.yaml b/airbyte-integrations/connectors/source-marketo/metadata.yaml index 8dc3328f0a62..bfce082130b9 100644 --- a/airbyte-integrations/connectors/source-marketo/metadata.yaml +++ b/airbyte-integrations/connectors/source-marketo/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - "*.mktorest.com" connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:1.2.2@sha256:57703de3b4c4204bd68a7b13c9300f8e03c0189bffddaffc796f1da25d2dbea0 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 9e0556f4-69df-4522-a3fb-03264d36b348 - dockerImageTag: 1.4.7 + dockerImageTag: 1.4.11 dockerRepository: airbyte/source-marketo documentationUrl: https://docs.airbyte.com/integrations/sources/marketo githubIssueLabel: source-marketo diff --git a/airbyte-integrations/connectors/source-marketo/poetry.lock b/airbyte-integrations/connectors/source-marketo/poetry.lock index f154e7b2b3ac..7e1ff44b4918 100644 --- a/airbyte-integrations/connectors/source-marketo/poetry.lock +++ b/airbyte-integrations/connectors/source-marketo/poetry.lock @@ -65,6 +65,28 @@ files = [ {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, ] +[[package]] +name = "anyio" +version = "4.7.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.9" +files = [ + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, +] + +[package.dependencies] +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} +idna = ">=2.8" +sniffio = ">=1.1" +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} + +[package.extras] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] +trio = ["trio (>=0.26.1)"] + [[package]] name = "atomicwrites" version = "1.4.1" @@ -77,22 +99,22 @@ files = [ [[package]] name = "attrs" -version = "23.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, - {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] -tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "backoff" @@ -107,35 +129,35 @@ files = [ [[package]] name = "bracex" -version = "2.4" +version = "2.5.post1" description = "Bash style brace expander." optional = false python-versions = ">=3.8" files = [ - {file = "bracex-2.4-py3-none-any.whl", hash = "sha256:efdc71eff95eaff5e0f8cfebe7d01adf2c8637c8c92edaf63ef348c241a82418"}, - {file = "bracex-2.4.tar.gz", hash = "sha256:a27eaf1df42cf561fed58b7a8f3fdf129d1ea16a81e1fadd1d17989bc6384beb"}, + {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, + {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, ] [[package]] name = "cachetools" -version = "5.3.3" +version = "5.5.0" description = "Extensible memoizing collections and decorators" optional = false python-versions = ">=3.7" files = [ - {file = "cachetools-5.3.3-py3-none-any.whl", hash = "sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945"}, - {file = "cachetools-5.3.3.tar.gz", hash = "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"}, + {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, + {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, ] [[package]] name = "cattrs" -version = "23.2.3" +version = "24.1.2" description = "Composable complex class support for attrs and dataclasses." optional = false python-versions = ">=3.8" files = [ - {file = "cattrs-23.2.3-py3-none-any.whl", hash = "sha256:0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108"}, - {file = "cattrs-23.2.3.tar.gz", hash = "sha256:a934090d95abaa9e911dac357e3a8699e0b4b14f8529bcc7d2b1ad9d51672b9f"}, + {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, + {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, ] [package.dependencies] @@ -147,6 +169,7 @@ typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_ver bson = ["pymongo (>=4.4.0)"] cbor2 = ["cbor2 (>=5.4.6)"] msgpack = ["msgpack (>=1.0.5)"] +msgspec = ["msgspec (>=0.18.5)"] orjson = ["orjson (>=3.9.2)"] pyyaml = ["pyyaml (>=6.0)"] tomlkit = ["tomlkit (>=0.11.8)"] @@ -154,74 +177,89 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.7.4" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "cffi" -version = "1.16.0" +version = "1.17.1" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" files = [ - {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, - {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, - {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, - {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, - {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, - {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, - {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, - {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, - {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, - {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, - {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, - {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, - {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, - {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, - {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, - {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, + {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, + {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, + {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, + {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, ] [package.dependencies] @@ -229,101 +267,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.3.2" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -393,20 +433,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -421,13 +461,13 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.2.1" +version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, - {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, ] [package.extras] @@ -435,17 +475,18 @@ test = ["pytest (>=6)"] [[package]] name = "faker" -version = "26.0.0" +version = "33.3.0" description = "Faker is a Python package that generates fake data for you." optional = false python-versions = ">=3.8" files = [ - {file = "Faker-26.0.0-py3-none-any.whl", hash = "sha256:886ee28219be96949cd21ecc96c4c742ee1680e77f687b095202c8def1a08f06"}, - {file = "Faker-26.0.0.tar.gz", hash = "sha256:0f60978314973de02c00474c2ae899785a42b2cf4f41b7987e93c132a2b8a4a9"}, + {file = "Faker-33.3.0-py3-none-any.whl", hash = "sha256:ae074d9c7ef65817a93b448141a5531a16b2ea2e563dc5774578197c7c84060c"}, + {file = "faker-33.3.0.tar.gz", hash = "sha256:2abb551a05b75d268780b6095100a48afc43c53e97422002efbfc1272ebf5f26"}, ] [package.dependencies] python-dateutil = ">=2.4" +typing-extensions = "*" [[package]] name = "genson" @@ -457,17 +498,76 @@ files = [ {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, ] +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.7" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<1.0)"] + +[[package]] +name = "httpx" +version = "0.28.1" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +zstd = ["zstandard (>=0.18.0)"] + [[package]] name = "idna" -version = "3.7" +version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, ] +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -495,13 +595,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -591,147 +691,177 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.83" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.83-py3-none-any.whl", hash = "sha256:f54d8cd8479b648b6339f3f735d19292c3516d080f680933ecdca3eab4b67ed3"}, - {file = "langsmith-0.1.83.tar.gz", hash = "sha256:5cdd947212c8ad19adb992c06471c860185a777daa6859bb47150f90daf64bf3"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] -orjson = ">=3.9.14,<4.0.0" +httpx = ">=0.23.0,<1" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" +requests-toolbelt = ">=1.0.0,<2.0.0" + +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] [[package]] name = "markupsafe" -version = "2.1.5" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] name = "orjson" -version = "3.10.6" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.6-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:fb0ee33124db6eaa517d00890fc1a55c3bfe1cf78ba4a8899d71a06f2d6ff5c7"}, - {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c1c4b53b24a4c06547ce43e5fee6ec4e0d8fe2d597f4647fc033fd205707365"}, - {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eadc8fd310edb4bdbd333374f2c8fec6794bbbae99b592f448d8214a5e4050c0"}, - {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:61272a5aec2b2661f4fa2b37c907ce9701e821b2c1285d5c3ab0207ebd358d38"}, - {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57985ee7e91d6214c837936dc1608f40f330a6b88bb13f5a57ce5257807da143"}, - {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:633a3b31d9d7c9f02d49c4ab4d0a86065c4a6f6adc297d63d272e043472acab5"}, - {file = "orjson-3.10.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1c680b269d33ec444afe2bdc647c9eb73166fa47a16d9a75ee56a374f4a45f43"}, - {file = "orjson-3.10.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f759503a97a6ace19e55461395ab0d618b5a117e8d0fbb20e70cfd68a47327f2"}, - {file = "orjson-3.10.6-cp310-none-win32.whl", hash = "sha256:95a0cce17f969fb5391762e5719575217bd10ac5a189d1979442ee54456393f3"}, - {file = "orjson-3.10.6-cp310-none-win_amd64.whl", hash = "sha256:df25d9271270ba2133cc88ee83c318372bdc0f2cd6f32e7a450809a111efc45c"}, - {file = "orjson-3.10.6-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b1ec490e10d2a77c345def52599311849fc063ae0e67cf4f84528073152bb2ba"}, - {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55d43d3feb8f19d07e9f01e5b9be4f28801cf7c60d0fa0d279951b18fae1932b"}, - {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac3045267e98fe749408eee1593a142e02357c5c99be0802185ef2170086a863"}, - {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c27bc6a28ae95923350ab382c57113abd38f3928af3c80be6f2ba7eb8d8db0b0"}, - {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d27456491ca79532d11e507cadca37fb8c9324a3976294f68fb1eff2dc6ced5a"}, - {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05ac3d3916023745aa3b3b388e91b9166be1ca02b7c7e41045da6d12985685f0"}, - {file = "orjson-3.10.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1335d4ef59ab85cab66fe73fd7a4e881c298ee7f63ede918b7faa1b27cbe5212"}, - {file = "orjson-3.10.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4bbc6d0af24c1575edc79994c20e1b29e6fb3c6a570371306db0993ecf144dc5"}, - {file = "orjson-3.10.6-cp311-none-win32.whl", hash = "sha256:450e39ab1f7694465060a0550b3f6d328d20297bf2e06aa947b97c21e5241fbd"}, - {file = "orjson-3.10.6-cp311-none-win_amd64.whl", hash = "sha256:227df19441372610b20e05bdb906e1742ec2ad7a66ac8350dcfd29a63014a83b"}, - {file = "orjson-3.10.6-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ea2977b21f8d5d9b758bb3f344a75e55ca78e3ff85595d248eee813ae23ecdfb"}, - {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b6f3d167d13a16ed263b52dbfedff52c962bfd3d270b46b7518365bcc2121eed"}, - {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f710f346e4c44a4e8bdf23daa974faede58f83334289df80bc9cd12fe82573c7"}, - {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7275664f84e027dcb1ad5200b8b18373e9c669b2a9ec33d410c40f5ccf4b257e"}, - {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0943e4c701196b23c240b3d10ed8ecd674f03089198cf503105b474a4f77f21f"}, - {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:446dee5a491b5bc7d8f825d80d9637e7af43f86a331207b9c9610e2f93fee22a"}, - {file = "orjson-3.10.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:64c81456d2a050d380786413786b057983892db105516639cb5d3ee3c7fd5148"}, - {file = "orjson-3.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:960db0e31c4e52fa0fc3ecbaea5b2d3b58f379e32a95ae6b0ebeaa25b93dfd34"}, - {file = "orjson-3.10.6-cp312-none-win32.whl", hash = "sha256:a6ea7afb5b30b2317e0bee03c8d34c8181bc5a36f2afd4d0952f378972c4efd5"}, - {file = "orjson-3.10.6-cp312-none-win_amd64.whl", hash = "sha256:874ce88264b7e655dde4aeaacdc8fd772a7962faadfb41abe63e2a4861abc3dc"}, - {file = "orjson-3.10.6-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:66680eae4c4e7fc193d91cfc1353ad6d01b4801ae9b5314f17e11ba55e934183"}, - {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:caff75b425db5ef8e8f23af93c80f072f97b4fb3afd4af44482905c9f588da28"}, - {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3722fddb821b6036fd2a3c814f6bd9b57a89dc6337b9924ecd614ebce3271394"}, - {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2c116072a8533f2fec435fde4d134610f806bdac20188c7bd2081f3e9e0133f"}, - {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6eeb13218c8cf34c61912e9df2de2853f1d009de0e46ea09ccdf3d757896af0a"}, - {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:965a916373382674e323c957d560b953d81d7a8603fbeee26f7b8248638bd48b"}, - {file = "orjson-3.10.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:03c95484d53ed8e479cade8628c9cea00fd9d67f5554764a1110e0d5aa2de96e"}, - {file = "orjson-3.10.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:e060748a04cccf1e0a6f2358dffea9c080b849a4a68c28b1b907f272b5127e9b"}, - {file = "orjson-3.10.6-cp38-none-win32.whl", hash = "sha256:738dbe3ef909c4b019d69afc19caf6b5ed0e2f1c786b5d6215fbb7539246e4c6"}, - {file = "orjson-3.10.6-cp38-none-win_amd64.whl", hash = "sha256:d40f839dddf6a7d77114fe6b8a70218556408c71d4d6e29413bb5f150a692ff7"}, - {file = "orjson-3.10.6-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:697a35a083c4f834807a6232b3e62c8b280f7a44ad0b759fd4dce748951e70db"}, - {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd502f96bf5ea9a61cbc0b2b5900d0dd68aa0da197179042bdd2be67e51a1e4b"}, - {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f215789fb1667cdc874c1b8af6a84dc939fd802bf293a8334fce185c79cd359b"}, - {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2debd8ddce948a8c0938c8c93ade191d2f4ba4649a54302a7da905a81f00b56"}, - {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5410111d7b6681d4b0d65e0f58a13be588d01b473822483f77f513c7f93bd3b2"}, - {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb1f28a137337fdc18384079fa5726810681055b32b92253fa15ae5656e1dddb"}, - {file = "orjson-3.10.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bf2fbbce5fe7cd1aa177ea3eab2b8e6a6bc6e8592e4279ed3db2d62e57c0e1b2"}, - {file = "orjson-3.10.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:79b9b9e33bd4c517445a62b90ca0cc279b0f1f3970655c3df9e608bc3f91741a"}, - {file = "orjson-3.10.6-cp39-none-win32.whl", hash = "sha256:30b0a09a2014e621b1adf66a4f705f0809358350a757508ee80209b2d8dae219"}, - {file = "orjson-3.10.6-cp39-none-win_amd64.whl", hash = "sha256:49e3bc615652617d463069f91b867a4458114c5b104e13b7ae6872e5f79d0844"}, - {file = "orjson-3.10.6.tar.gz", hash = "sha256:e54b63d0a7c6c54a5f5f726bc93a2078111ef060fec4ecbf34c5db800ca3b3a7"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -781,19 +911,19 @@ pytzdata = ">=2020.1" [[package]] name = "platformdirs" -version = "4.2.2" +version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, - {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "pluggy" @@ -834,119 +964,131 @@ files = [ [[package]] name = "pydantic" -version = "2.8.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, - {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] -annotated-types = ">=0.4.0" -pydantic-core = "2.20.1" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +annotated-types = ">=0.6.0" +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] +timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.20.1" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, - {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, - {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, - {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, - {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, - {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, - {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, - {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, - {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, - {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, - {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, - {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, - {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, - {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, - {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, - {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, - {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, - {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, - {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, - {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, - {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, - {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, - {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, - {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, - {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, - {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, - {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, - {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, - {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, - {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, - {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, - {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, - {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, - {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, - {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -954,19 +1096,19 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.8.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.8.0-py3-none-any.whl", hash = "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320"}, - {file = "PyJWT-2.8.0.tar.gz", hash = "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] crypto = ["cryptography (>=3.4.0)"] -dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] -docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] +docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] [[package]] @@ -1117,62 +1259,64 @@ files = [ [[package]] name = "pyyaml" -version = "6.0.1" +version = "6.0.2" description = "YAML parser and emitter for Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] [[package]] @@ -1243,30 +1387,60 @@ requests = ">=2.22,<3" [package.extras] fixture = ["fixtures"] +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +description = "A utility belt for advanced users of python-requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, + {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, +] + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + [[package]] name = "setuptools" -version = "70.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-70.2.0-py3-none-any.whl", hash = "sha256:b8b8060bb426838fbe942479c90296ce976249451118ef566a5a0b7d8b78fb05"}, - {file = "setuptools-70.2.0.tar.gz", hash = "sha256:bd63e505105011b25c3c11f753f7e3b8465ea739efddaccef8f0efac2137bac1"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, ] [[package]] @@ -1322,13 +1496,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.2" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, - {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1353,84 +1527,79 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] lock-version = "2.0" python-versions = "^3.9,<3.12" -content-hash = "e468e699e51a04f112db640a8e72cd3175296287e14c4ceb4b75cde6076d833d" +content-hash = "cce19500f48fbf5b5fae0f1f30b4da1ccfff0af670f9404ec8c597a418a8b55b" diff --git a/airbyte-integrations/connectors/source-marketo/pyproject.toml b/airbyte-integrations/connectors/source-marketo/pyproject.toml index 7ba05314469b..772c2ccb0109 100644 --- a/airbyte-integrations/connectors/source-marketo/pyproject.toml +++ b/airbyte-integrations/connectors/source-marketo/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "1.4.7" +version = "1.4.11" name = "source-marketo" description = "Source implementation for Marketo." authors = [ "Airbyte ",] @@ -17,7 +17,7 @@ include = "source_marketo" [tool.poetry.dependencies] python = "^3.9,<3.12" -airbyte-cdk = "*" +airbyte-cdk = "2.3.0" # Newer CDK versions cause breaking changes. This is the latest version that we are sure can pass tests. [tool.poetry.scripts] source-marketo = "source_marketo.run:run" diff --git a/airbyte-integrations/connectors/source-marketo/source_marketo/source.py b/airbyte-integrations/connectors/source-marketo/source_marketo/source.py index 418c327cc104..1eee453d1740 100644 --- a/airbyte-integrations/connectors/source-marketo/source_marketo/source.py +++ b/airbyte-integrations/connectors/source-marketo/source_marketo/source.py @@ -11,6 +11,7 @@ import pendulum import requests + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.declarative.exceptions import ReadException from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource diff --git a/airbyte-integrations/connectors/source-marketo/source_marketo/utils.py b/airbyte-integrations/connectors/source-marketo/source_marketo/utils.py index 9926e2e2084e..426d437b66a2 100644 --- a/airbyte-integrations/connectors/source-marketo/source_marketo/utils.py +++ b/airbyte-integrations/connectors/source-marketo/source_marketo/utils.py @@ -5,6 +5,7 @@ from datetime import datetime + STRING_TYPES = [ "string", "email", diff --git a/airbyte-integrations/connectors/source-marketo/unit_tests/conftest.py b/airbyte-integrations/connectors/source-marketo/unit_tests/conftest.py index f088ce69b9fc..b4f03f750bd4 100644 --- a/airbyte-integrations/connectors/source-marketo/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-marketo/unit_tests/conftest.py @@ -9,9 +9,11 @@ import pendulum import pytest -from airbyte_cdk.sources.declarative.declarative_stream import DeclarativeStream from source_marketo.source import Activities, MarketoAuthenticator, SourceMarketo +from airbyte_cdk.sources.declarative.declarative_stream import DeclarativeStream + + START_DATE = pendulum.now().subtract(days=75) @@ -77,7 +79,10 @@ def _generator(min_size: int): def fake_records_gen(): new_line = "\n" for i in range(1000): - yield f"{str(faker.random_int())},{faker.random_int()},{faker.date_of_birth()},{faker.random_int()}," f"{faker.random_int()},{faker.email()},{faker.postcode()}{new_line}" + yield ( + f"{str(faker.random_int())},{faker.random_int()},{faker.date_of_birth()},{faker.random_int()}," + f"{faker.random_int()},{faker.email()},{faker.postcode()}{new_line}" + ) size, records = 0, 0 path = os.path.realpath(str(time.time())) @@ -98,9 +103,7 @@ def fake_records_gen(): def get_stream_by_name(stream_name: str, config: Mapping[str, Any]) -> DeclarativeStream: source = SourceMarketo() - matches_by_name = [ - stream_config for stream_config in source._get_declarative_streams(config) if stream_config.name == stream_name - ] + matches_by_name = [stream_config for stream_config in source._get_declarative_streams(config) if stream_config.name == stream_name] if not matches_by_name: raise ValueError("Please provide a valid stream name.") return matches_by_name[0] diff --git a/airbyte-integrations/connectors/source-marketo/unit_tests/test_source.py b/airbyte-integrations/connectors/source-marketo/unit_tests/test_source.py index d77625438bbc..cb5d3988aa85 100644 --- a/airbyte-integrations/connectors/source-marketo/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-marketo/unit_tests/test_source.py @@ -11,13 +11,15 @@ import pendulum import pytest import requests +from source_marketo.source import Activities, IncrementalMarketoStream, Leads, MarketoExportCreate, MarketoStream, SourceMarketo + from airbyte_cdk.models.airbyte_protocol import SyncMode from airbyte_cdk.sources.declarative.declarative_stream import DeclarativeStream from airbyte_cdk.utils import AirbyteTracedException -from source_marketo.source import Activities, IncrementalMarketoStream, Leads, MarketoExportCreate, MarketoStream, SourceMarketo from .conftest import START_DATE, get_stream_by_name + logger = logging.getLogger("airbyte") @@ -38,12 +40,7 @@ def test_should_retry_quota_exceeded(config, requests_mock): response_json = { "requestId": "d2ca#18c0b9833bf", "success": False, - "errors": [ - { - "code": "1029", - "message": "Export daily quota 500MB exceeded." - } - ] + "errors": [{"code": "1029", "message": "Export daily quota 500MB exceeded."}], } requests_mock.register_uri("GET", create_job_url, status_code=200, json=response_json) @@ -132,8 +129,8 @@ def test_activities_schema(activity, expected_schema, config): ( ( "Campaign Run ID,Choice Number,Has Predictive,Step ID,Test Variant,attributes\n" - "1,3,true,10,15,{\"spam\": \"true\"}\n" - "2,3,false,11,16,{\"spam\": \"false\"}" + '1,3,true,10,15,{"spam": "true"}\n' + '2,3,false,11,16,{"spam": "false"}' ), [ { @@ -231,9 +228,7 @@ def test_parse_response_incremental(config, requests_mock): created_at_record_1 = START_DATE.add(days=1).strftime("%Y-%m-%dT%H:%M:%SZ") created_at_record_2 = START_DATE.add(days=3).strftime("%Y-%m-%dT%H:%M:%SZ") current_state = START_DATE.add(days=2).strftime("%Y-%m-%dT%H:%M:%SZ") - response = { - "result": [{"id": "1", "createdAt": created_at_record_1}, {"id": "2", "createdAt": created_at_record_2}] - } + response = {"result": [{"id": "1", "createdAt": created_at_record_1}, {"id": "2", "createdAt": created_at_record_2}]} requests_mock.get("/rest/v1/campaigns.json", json=response) stream = get_stream_by_name("campaigns", config) @@ -322,16 +317,8 @@ def test_get_updated_state(config, latest_record, current_state, expected_state) def test_filter_null_bytes(config): stream = Leads(config) - test_lines = [ - "Hello\x00World\n", - "Name,Email\n", - "John\x00Doe,john.doe@example.com\n" - ] - expected_lines = [ - "HelloWorld\n", - "Name,Email\n", - "JohnDoe,john.doe@example.com\n" - ] + test_lines = ["Hello\x00World\n", "Name,Email\n", "John\x00Doe,john.doe@example.com\n"] + expected_lines = ["HelloWorld\n", "Name,Email\n", "JohnDoe,john.doe@example.com\n"] filtered_lines = stream.filter_null_bytes(test_lines) for expected_line, filtered_line in zip(expected_lines, filtered_lines): assert expected_line == filtered_line @@ -340,15 +327,8 @@ def test_filter_null_bytes(config): def test_csv_rows(config): stream = Leads(config) - test_lines = [ - "Name,Email\n", - "John Doe,john.doe@example.com\n", - "Jane Doe,jane.doe@example.com\n" - ] - expected_records = [ - {"Name": "John Doe", "Email": "john.doe@example.com"}, - {"Name": "Jane Doe", "Email": "jane.doe@example.com"} - ] + test_lines = ["Name,Email\n", "John Doe,john.doe@example.com\n", "Jane Doe,jane.doe@example.com\n"] + expected_records = [{"Name": "John Doe", "Email": "john.doe@example.com"}, {"Name": "Jane Doe", "Email": "jane.doe@example.com"}] records = stream.csv_rows(test_lines) for expected_record, record in zip(expected_records, records): assert expected_record == record diff --git a/airbyte-integrations/connectors/source-marketo/unit_tests/test_utils.py b/airbyte-integrations/connectors/source-marketo/unit_tests/test_utils.py index 453954ab3641..38cff9225bdd 100644 --- a/airbyte-integrations/connectors/source-marketo/unit_tests/test_utils.py +++ b/airbyte-integrations/connectors/source-marketo/unit_tests/test_utils.py @@ -8,6 +8,7 @@ import pytest from source_marketo.utils import clean_string, format_value, to_datetime_str + test_data = [ (1, {"type": "integer"}, int), ("string", {"type": "string"}, str), diff --git a/airbyte-integrations/connectors/source-marketstack/README.md b/airbyte-integrations/connectors/source-marketstack/README.md new file mode 100644 index 000000000000..9e294dbaaf26 --- /dev/null +++ b/airbyte-integrations/connectors/source-marketstack/README.md @@ -0,0 +1,34 @@ +# Marketstack +This directory contains the manifest-only connector for `source-marketstack`. + +Marketstack provides data from 72 global stock exchanges. +Using this connector we can extract Historical Data , Splits and Dividends data ! + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-marketstack:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-marketstack build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-marketstack test +``` + diff --git a/airbyte-integrations/connectors/source-marketstack/acceptance-test-config.yml b/airbyte-integrations/connectors/source-marketstack/acceptance-test-config.yml new file mode 100644 index 000000000000..918b66337202 --- /dev/null +++ b/airbyte-integrations/connectors/source-marketstack/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-marketstack:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-marketstack/icon.svg b/airbyte-integrations/connectors/source-marketstack/icon.svg new file mode 100644 index 000000000000..e6d4e151a205 --- /dev/null +++ b/airbyte-integrations/connectors/source-marketstack/icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/airbyte-integrations/connectors/source-marketstack/manifest.yaml b/airbyte-integrations/connectors/source-marketstack/manifest.yaml new file mode 100644 index 000000000000..ed14165d6d12 --- /dev/null +++ b/airbyte-integrations/connectors/source-marketstack/manifest.yaml @@ -0,0 +1,526 @@ +version: 6.1.0 + +type: DeclarativeSource + +description: >- + Marketstack provides data from 72 global stock exchanges. + + Using this connector we can extract Historical Data , Splits and Dividends + data ! + +check: + type: CheckStream + stream_names: + - exchanges + +definitions: + streams: + exchanges: + type: DeclarativeStream + name: exchanges + primary_key: + - mic + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: exchanges + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 1000 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/exchanges" + tickers: + type: DeclarativeStream + name: tickers + primary_key: + - symbol + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /exchanges/{{ stream_partition.mic }}/tickers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - tickers + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 1000 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: mic + partition_field: mic + stream: + $ref: "#/definitions/streams/exchanges" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tickers" + historical_data: + type: DeclarativeStream + name: historical_data + primary_key: + - date + - symbol + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: eod + http_method: GET + request_parameters: + symbols: "{{ stream_partition.symbol }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 1000 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: symbol + partition_field: symbol + stream: + $ref: "#/definitions/streams/tickers" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: date + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S+0000" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: date_from + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: date_to + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/historical_data" + splits: + type: DeclarativeStream + name: splits + primary_key: + - date + - symbol + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: splits + http_method: GET + request_parameters: + symbols: "{{ stream_partition.symbol }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 1000 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: symbol + partition_field: symbol + stream: + $ref: "#/definitions/streams/tickers" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/splits" + dividends: + type: DeclarativeStream + name: dividends + primary_key: + - date + - symbol + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: dividends + http_method: GET + request_parameters: + symbols: "{{ stream_partition.symbol }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 1000 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: symbol + partition_field: symbol + stream: + $ref: "#/definitions/streams/tickers" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/dividends" + base_requester: + type: HttpRequester + url_base: https://api.marketstack.com/v1/ + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: access_key + inject_into: request_parameter + +streams: + - $ref: "#/definitions/streams/exchanges" + - $ref: "#/definitions/streams/tickers" + - $ref: "#/definitions/streams/historical_data" + - $ref: "#/definitions/streams/splits" + - $ref: "#/definitions/streams/dividends" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - start_date + properties: + api_key: + type: string + order: 0 + title: API Key + airbyte_secret: true + start_date: + type: string + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + order: 1 + additionalProperties: true + +metadata: + autoImportSchema: + exchanges: true + tickers: true + historical_data: true + splits: true + dividends: true + testedStreams: + exchanges: + streamHash: 0a78905be0177b4bee681650529804dc3d8d18cf + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tickers: + streamHash: fe40727a29551cbeb14d3f48eda18e244858ba51 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + historical_data: + streamHash: ca758d5c0e7bc4f30266c541b4ee5a5cbbf84bec + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + splits: + streamHash: a3749240755d1fc249172a5325e09ff82bdac97e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + dividends: + streamHash: 4cec9379a7dfedea697008e2b42b499006639a82 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + exchanges: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + acronym: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + country_code: + type: + - string + - "null" + currency: + type: + - object + - "null" + properties: + code: + type: + - string + - "null" + name: + type: + - string + - "null" + symbol: + type: + - string + - "null" + mic: + type: string + name: + type: + - string + - "null" + timezone: + type: + - object + - "null" + properties: + abbr: + type: + - string + - "null" + abbr_dst: + type: + - string + - "null" + timezone: + type: + - string + - "null" + website: + type: + - string + - "null" + required: + - mic + tickers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + has_eod: + type: + - boolean + - "null" + has_intraday: + type: + - boolean + - "null" + name: + type: + - string + - "null" + symbol: + type: string + required: + - symbol + historical_data: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + adj_close: + type: + - number + - "null" + adj_high: + type: + - number + - "null" + adj_low: + type: + - number + - "null" + adj_open: + type: + - number + - "null" + adj_volume: + type: + - number + - "null" + close: + type: + - number + - "null" + date: + type: string + dividend: + type: + - number + - "null" + exchange: + type: + - string + - "null" + high: + type: + - number + - "null" + low: + type: + - number + - "null" + open: + type: + - number + - "null" + split_factor: + type: + - number + - "null" + symbol: + type: string + volume: + type: + - number + - "null" + required: + - date + - symbol + splits: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + date: + type: string + split_factor: + type: + - number + - "null" + symbol: + type: string + required: + - date + - symbol + dividends: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + date: + type: string + dividend: + type: + - number + - "null" + symbol: + type: string + required: + - date + - symbol diff --git a/airbyte-integrations/connectors/source-marketstack/metadata.yaml b/airbyte-integrations/connectors/source-marketstack/metadata.yaml new file mode 100644 index 000000000000..447ada9bf3ab --- /dev/null +++ b/airbyte-integrations/connectors/source-marketstack/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.marketstack.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-marketstack + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 0caeba13-0807-46aa-a6c0-7e8d25d168be + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-marketstack + githubIssueLabel: source-marketstack + icon: icon.svg + license: MIT + name: Marketstack + releaseDate: 2024-11-07 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/marketstack + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-mention/metadata.yaml b/airbyte-integrations/connectors/source-mention/metadata.yaml index eca6df4e25fd..a93c05464600 100644 --- a/airbyte-integrations/connectors/source-mention/metadata.yaml +++ b/airbyte-integrations/connectors/source-mention/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-mention connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 1180b5a7-8658-4510-ba65-611191333ba8 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-mention githubIssueLabel: source-mention icon: icon.svg diff --git a/airbyte-integrations/connectors/source-merge/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-merge/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-merge/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-merge/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-merge/metadata.yaml b/airbyte-integrations/connectors/source-merge/metadata.yaml index 5613af9afa0a..ab3a01eaca09 100644 --- a/airbyte-integrations/connectors/source-merge/metadata.yaml +++ b/airbyte-integrations/connectors/source-merge/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 23240e9e-d14a-43bc-899f-72ea304d1994 - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-merge githubIssueLabel: source-merge icon: merge.svg @@ -37,5 +37,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-metabase/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-metabase/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-metabase/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-metabase/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-metabase/metadata.yaml b/airbyte-integrations/connectors/source-metabase/metadata.yaml index 7427fa517248..a5c1a348eb9e 100644 --- a/airbyte-integrations/connectors/source-metabase/metadata.yaml +++ b/airbyte-integrations/connectors/source-metabase/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - "*" connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: c7cb421b-942e-4468-99ee-e369bcabaec5 - dockerImageTag: 2.1.3 + dockerImageTag: 2.1.7 dockerRepository: airbyte/source-metabase documentationUrl: https://docs.airbyte.com/integrations/sources/metabase githubIssueLabel: source-metabase diff --git a/airbyte-integrations/connectors/source-microsoft-dataverse/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-microsoft-dataverse/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-microsoft-dataverse/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-microsoft-dataverse/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-microsoft-dataverse/main.py b/airbyte-integrations/connectors/source-microsoft-dataverse/main.py index 88b4cf3808e8..18cbfd717811 100644 --- a/airbyte-integrations/connectors/source-microsoft-dataverse/main.py +++ b/airbyte-integrations/connectors/source-microsoft-dataverse/main.py @@ -4,5 +4,6 @@ from source_microsoft_dataverse.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-microsoft-dataverse/source_microsoft_dataverse/dataverse.py b/airbyte-integrations/connectors/source-microsoft-dataverse/source_microsoft_dataverse/dataverse.py index a3a14fc8addb..8f33e6eaf55d 100644 --- a/airbyte-integrations/connectors/source-microsoft-dataverse/source_microsoft_dataverse/dataverse.py +++ b/airbyte-integrations/connectors/source-microsoft-dataverse/source_microsoft_dataverse/dataverse.py @@ -6,6 +6,7 @@ from typing import Any, Mapping, MutableMapping, Optional import requests + from airbyte_cdk.sources.streams.http.requests_native_auth.oauth import Oauth2Authenticator @@ -25,7 +26,6 @@ def build_refresh_request_body(self) -> Mapping[str, Any]: class AirbyteType(Enum): - String = {"type": ["null", "string"]} Boolean = {"type": ["null", "boolean"]} Timestamp = {"type": ["null", "string"], "format": "date-time", "airbyte_type": "timestamp_with_timezone"} @@ -34,7 +34,6 @@ class AirbyteType(Enum): class DataverseType(Enum): - String = AirbyteType.String Uniqueidentifier = AirbyteType.String DateTime = AirbyteType.Timestamp diff --git a/airbyte-integrations/connectors/source-microsoft-dataverse/source_microsoft_dataverse/streams.py b/airbyte-integrations/connectors/source-microsoft-dataverse/source_microsoft_dataverse/streams.py index a85426a7c098..3f384d8e31b8 100644 --- a/airbyte-integrations/connectors/source-microsoft-dataverse/source_microsoft_dataverse/streams.py +++ b/airbyte-integrations/connectors/source-microsoft-dataverse/source_microsoft_dataverse/streams.py @@ -8,13 +8,13 @@ from urllib import parse import requests + from airbyte_cdk.sources.streams import IncrementalMixin from airbyte_cdk.sources.streams.http import HttpStream # Basic full refresh stream class MicrosoftDataverseStream(HttpStream, ABC): - # Base url will be set by init(), using information provided by the user through config input url_base = "" primary_key = "" @@ -97,7 +97,6 @@ def path( # Basic incremental stream class IncrementalMicrosoftDataverseStream(MicrosoftDataverseStream, IncrementalMixin, ABC): - delta_token_field = "$deltatoken" state_checkpoint_interval = None # For now we just use the change tracking as state, and it is only emitted on last page diff --git a/airbyte-integrations/connectors/source-microsoft-dataverse/unit_tests/test_source.py b/airbyte-integrations/connectors/source-microsoft-dataverse/unit_tests/test_source.py index 0e93f16521ab..402667e9e3fd 100644 --- a/airbyte-integrations/connectors/source-microsoft-dataverse/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-microsoft-dataverse/unit_tests/test_source.py @@ -6,11 +6,12 @@ from unittest import mock from unittest.mock import MagicMock -from airbyte_cdk.models import SyncMode from source_microsoft_dataverse.dataverse import AirbyteType from source_microsoft_dataverse.source import SourceMicrosoftDataverse from source_microsoft_dataverse.streams import IncrementalMicrosoftDataverseStream, MicrosoftDataverseStream +from airbyte_cdk.models import SyncMode + @mock.patch("source_microsoft_dataverse.source.do_request") def test_check_connection(mock_request): diff --git a/airbyte-integrations/connectors/source-microsoft-entra-id/manifest.yaml b/airbyte-integrations/connectors/source-microsoft-entra-id/manifest.yaml index 810ef468a329..ce8308a25961 100644 --- a/airbyte-integrations/connectors/source-microsoft-entra-id/manifest.yaml +++ b/airbyte-integrations/connectors/source-microsoft-entra-id/manifest.yaml @@ -1,4 +1,4 @@ -version: 5.12.0 +version: 5.15.0 type: DeclarativeSource @@ -155,8 +155,8 @@ definitions: cursor_field: type request_option: type: RequestOption - inject_into: body_json field_name: type + inject_into: body_json schema_loader: type: InlineSchemaLoader schema: @@ -182,41 +182,6 @@ definitions: type: InlineSchemaLoader schema: $ref: "#/schemas/directoryroles" - auditlogs: - type: DeclarativeStream - name: auditlogs - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /auditLogs/directoryaudits - http_method: GET - request_parameters: - $top: "5" - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - value - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: $skiptoken - pagination_strategy: - type: CursorPagination - cursor_value: >- - {{ response.get("@odata.nextLink") | - regex_search('\$skiptoken=([^&]+)') }} - stop_condition: "{{ response.get('@odata.nextLink') is not defined }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/auditlogs" directoryroletemplates: type: DeclarativeStream name: directoryroletemplates @@ -374,7 +339,7 @@ definitions: grant_type: client_credentials client_secret: "{{ config[\"client_secret\"] }}" refresh_request_body: - scope: "{{ config['application_id_uri'] }}" + scope: https://graph.microsoft.com/.default token_refresh_endpoint: >- https://login.microsoftonline.com/{{ config['tenant_id'] }}/oauth2/v2.0/token @@ -385,7 +350,6 @@ streams: - $ref: "#/definitions/streams/applications" - $ref: "#/definitions/streams/user_owned_deleted_items" - $ref: "#/definitions/streams/directoryroles" - - $ref: "#/definitions/streams/auditlogs" - $ref: "#/definitions/streams/directoryroletemplates" - $ref: "#/definitions/streams/directoryaudits" - $ref: "#/definitions/streams/serviceprincipals" @@ -401,7 +365,6 @@ spec: - client_id - client_secret - tenant_id - - application_id_uri - user_id properties: client_id: @@ -419,14 +382,9 @@ spec: order: 2 title: Tenant Id airbyte_secret: true - application_id_uri: - type: string - order: 3 - title: Application Id URI - airbyte_secret: true user_id: type: string - order: 4 + order: 3 title: User Id airbyte_secret: true additionalProperties: true @@ -438,7 +396,6 @@ metadata: applications: true user_owned_deleted_items: true directoryroles: true - auditlogs: true directoryroletemplates: true directoryaudits: true serviceprincipals: true @@ -446,82 +403,75 @@ metadata: adminconsentrequestpolicy: true testedStreams: users: - streamHash: e9680d9cc418081a2f5fd4e59d7f575b311b8dc5 + streamHash: a3a8dbf864ffb336f197dcd7b5dc94276ac3804c hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true groups: - streamHash: c1a0432c5ce81363e75b39b503b7203fdecfeba6 + streamHash: f4d8c25569bc03e4282b8ab0e2206fe801f7abb4 hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true applications: - streamHash: 66f078a70b0c4d468592c3fa1b538bac620b2e7d + streamHash: aec5be1d8ca55d7d6d329969a469413a2799d204 hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true user_owned_deleted_items: - streamHash: 9265a6b09eed6ababab8f15d3522dca6e123febe + streamHash: f58339e36ff71c6055a1279d2ccc551a2280fa3f hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true directoryroles: - streamHash: 6ce30c704704828c251bbf8f402778fd8f639edb - hasResponse: true - responsesAreSuccessful: true - hasRecords: true - primaryKeysArePresent: true - primaryKeysAreUnique: true - auditlogs: - streamHash: d49fef83c93794e449409ac2a45685458e45ca57 + streamHash: 1e2973d7b724fe91d182c756dd1b4bb2b1d4d81b hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true directoryroletemplates: - streamHash: e885ecb2033544abad560f266f37176ade361abd + streamHash: 4ae0addeaa79492f472e034533b850b557b08fc1 hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true directoryaudits: - streamHash: 7c99e2b68ff2f120774a2091a4ac074c9efed0bc + streamHash: dee13f722e03affc089a46bfc8be8ecd910074a8 hasResponse: true responsesAreSuccessful: true hasRecords: true primaryKeysArePresent: true primaryKeysAreUnique: true serviceprincipals: - streamHash: 77a66c133cdcb1882c3dccbafc8fcd2c8164b4a8 - hasResponse: true - responsesAreSuccessful: true hasRecords: true - primaryKeysArePresent: true - primaryKeysAreUnique: true - identityproviders: - streamHash: af1b879e50673feb9b02c80422ad985050cbd927 + streamHash: 1a75792a5cb5d162fc0aaeda12e27a876fe42470 hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true responsesAreSuccessful: true + identityproviders: hasRecords: true - primaryKeysArePresent: true - primaryKeysAreUnique: true - adminconsentrequestpolicy: - streamHash: cbc9761c8b766e847cda5438825d79774f0175b9 + streamHash: 2a6f02761e0744572579767de223c98b35d89890 hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true responsesAreSuccessful: true + adminconsentrequestpolicy: hasRecords: true - primaryKeysArePresent: true + streamHash: c65392dbc76dd3c1700fc307a0cec08113d18deb + hasResponse: true primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true assist: docsUrl: >- https://learn.microsoft.com/en-us/graph/api/resources/identity-network-access-overview?view=graph-rest-1.0 @@ -1100,107 +1050,6 @@ schemas: - "null" required: - id - auditlogs: - type: object - $schema: http://json-schema.org/schema# - additionalProperties: true - properties: - activityDateTime: - type: - - string - - "null" - activityDisplayName: - type: - - string - - "null" - additionalDetails: - type: - - array - - "null" - items: - type: - - object - - "null" - properties: - key: - type: - - string - - "null" - value: - type: - - string - - "null" - category: - type: - - string - - "null" - correlationId: - type: - - string - - "null" - id: - type: string - initiatedBy: - type: - - object - - "null" - properties: - app: - type: - - object - - "null" - properties: - displayName: - type: - - string - - "null" - servicePrincipalId: - type: - - string - - "null" - servicePrincipalName: - type: - - string - - "null" - loggedByService: - type: - - string - - "null" - operationType: - type: - - string - - "null" - result: - type: - - string - - "null" - resultReason: - type: - - string - - "null" - targetResources: - type: - - array - - "null" - items: - type: - - object - - "null" - properties: - type: - type: - - string - - "null" - id: - type: - - string - - "null" - modifiedProperties: - type: - - array - - "null" - required: - - id directoryroletemplates: type: object $schema: http://json-schema.org/schema# @@ -1263,20 +1112,20 @@ schemas: - object - "null" properties: - app: + user: type: - object - "null" properties: - displayName: + id: type: - string - "null" - servicePrincipalId: + ipAddress: type: - string - "null" - servicePrincipalName: + userPrincipalName: type: - string - "null" @@ -1309,6 +1158,14 @@ schemas: type: - string - "null" + displayName: + type: + - string + - "null" + groupType: + type: + - string + - "null" id: type: - string @@ -1317,6 +1174,27 @@ schemas: type: - array - "null" + items: + type: + - object + - "null" + properties: + displayName: + type: + - string + - "null" + newValue: + type: + - string + - "null" + oldValue: + type: + - string + - "null" + userPrincipalName: + type: + - string + - "null" required: - id serviceprincipals: diff --git a/airbyte-integrations/connectors/source-microsoft-entra-id/metadata.yaml b/airbyte-integrations/connectors/source-microsoft-entra-id/metadata.yaml index 7ad5790d6c55..9626a506f351 100644 --- a/airbyte-integrations/connectors/source-microsoft-entra-id/metadata.yaml +++ b/airbyte-integrations/connectors/source-microsoft-entra-id/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-microsoft-entra-id connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 337930a3-778a-413e-99cf-e79a3fca1c74 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.9 dockerRepository: airbyte/source-microsoft-entra-id githubIssueLabel: source-microsoft-entra-id icon: icon.svg diff --git a/airbyte-integrations/connectors/source-microsoft-lists/metadata.yaml b/airbyte-integrations/connectors/source-microsoft-lists/metadata.yaml index da60bb599f13..a170d6c2dff7 100644 --- a/airbyte-integrations/connectors/source-microsoft-lists/metadata.yaml +++ b/airbyte-integrations/connectors/source-microsoft-lists/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-microsoft-lists connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 18ea5fae-f0b1-4d82-9aef-832bb922a5b5 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.9 dockerRepository: airbyte/source-microsoft-lists githubIssueLabel: source-microsoft-lists icon: icon.svg diff --git a/airbyte-integrations/connectors/source-microsoft-onedrive/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-microsoft-onedrive/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-microsoft-onedrive/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-microsoft-onedrive/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-microsoft-onedrive/main.py b/airbyte-integrations/connectors/source-microsoft-onedrive/main.py index f12c7112ca11..4d33342920aa 100644 --- a/airbyte-integrations/connectors/source-microsoft-onedrive/main.py +++ b/airbyte-integrations/connectors/source-microsoft-onedrive/main.py @@ -5,5 +5,6 @@ from source_microsoft_onedrive.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-microsoft-onedrive/metadata.yaml b/airbyte-integrations/connectors/source-microsoft-onedrive/metadata.yaml index bf95335c3a9d..3f03ead9a16a 100644 --- a/airbyte-integrations/connectors/source-microsoft-onedrive/metadata.yaml +++ b/airbyte-integrations/connectors/source-microsoft-onedrive/metadata.yaml @@ -16,11 +16,11 @@ data: cloud: enabled: true connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: file connectorType: source definitionId: 01d1c685-fd4a-4837-8f4c-93fe5a0d2188 - dockerImageTag: 0.2.22 + dockerImageTag: 0.2.28 dockerRepository: airbyte/source-microsoft-onedrive githubIssueLabel: source-microsoft-onedrive icon: microsoft-onedrive.svg diff --git a/airbyte-integrations/connectors/source-microsoft-onedrive/poetry.lock b/airbyte-integrations/connectors/source-microsoft-onedrive/poetry.lock index 787969028296..8748e67a13d8 100644 --- a/airbyte-integrations/connectors/source-microsoft-onedrive/poetry.lock +++ b/airbyte-integrations/connectors/source-microsoft-onedrive/poetry.lock @@ -51,13 +51,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] @@ -65,24 +65,24 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -97,19 +97,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -210,13 +210,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -311,127 +311,114 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -519,20 +506,20 @@ typing-inspect = ">=0.4.0,<1" [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -648,13 +635,13 @@ files = [ [[package]] name = "fsspec" -version = "2024.10.0" +version = "2024.12.0" description = "File-system specification" optional = false python-versions = ">=3.8" files = [ - {file = "fsspec-2024.10.0-py3-none-any.whl", hash = "sha256:03b9a6785766a4de40368b88906366755e2819e758b83705c88cd7cb5fe81871"}, - {file = "fsspec-2024.10.0.tar.gz", hash = "sha256:eda2d8a4116d4f2429db8550f2457da57279247dd930bb12f821b58391359493"}, + {file = "fsspec-2024.12.0-py3-none-any.whl", hash = "sha256:b520aed47ad9804237ff878b504267a3b0b441e97508bd6d2d8774e3db85cee2"}, + {file = "fsspec-2024.12.0.tar.gz", hash = "sha256:670700c977ed2fb51e0d9f9253177ed20cbde4a3e5c0283cc5385b5870c8533f"}, ] [package.extras] @@ -708,13 +695,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -729,13 +716,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -743,7 +730,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -754,13 +740,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "huggingface-hub" -version = "0.26.1" +version = "0.27.0" description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" optional = false python-versions = ">=3.8.0" files = [ - {file = "huggingface_hub-0.26.1-py3-none-any.whl", hash = "sha256:5927a8fc64ae68859cd954b7cc29d1c8390a5e15caba6d3d349c973be8fdacf3"}, - {file = "huggingface_hub-0.26.1.tar.gz", hash = "sha256:414c0d9b769eecc86c70f9d939d0f48bb28e8461dd1130021542eff0212db890"}, + {file = "huggingface_hub-0.27.0-py3-none-any.whl", hash = "sha256:8f2e834517f1f1ddf1ecc716f91b120d7333011b7485f665a9a412eacb1a2a81"}, + {file = "huggingface_hub-0.27.0.tar.gz", hash = "sha256:902cce1a1be5739f5589e560198a65a8edcfd3b830b1666f36e4b961f0454fac"}, ] [package.dependencies] @@ -850,13 +836,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -971,22 +957,25 @@ six = "*" [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "lxml" version = "5.3.0" @@ -1231,13 +1220,13 @@ files = [ [[package]] name = "marshmallow" -version = "3.23.0" +version = "3.23.3" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." optional = false python-versions = ">=3.9" files = [ - {file = "marshmallow-3.23.0-py3-none-any.whl", hash = "sha256:82f20a2397834fe6d9611b241f2f7e7b680ed89c49f84728a1ad937be6b4bdf4"}, - {file = "marshmallow-3.23.0.tar.gz", hash = "sha256:98d8827a9f10c03d44ead298d2e99c6aea8197df18ccfad360dae7f89a50da2e"}, + {file = "marshmallow-3.23.3-py3-none-any.whl", hash = "sha256:20c0f8c613f68bcb45b2a0d3282e2f172575560170bf220d67aafb42717910e4"}, + {file = "marshmallow-3.23.3.tar.gz", hash = "sha256:d586c8685ebdb80bf754e1f96e3f305aaf30951f1fc69175b977453633467e76"}, ] [package.dependencies] @@ -1245,7 +1234,7 @@ packaging = ">=17.0" [package.extras] dev = ["marshmallow[tests]", "pre-commit (>=3.5,<5.0)", "tox"] -docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.13)", "sphinx (==8.1.3)", "sphinx-issues (==5.0.0)", "sphinx-version-warning (==1.1.2)"] +docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.14)", "sphinx (==8.1.3)", "sphinx-issues (==5.0.0)"] tests = ["pytest", "simplejson"] [[package]] @@ -1370,69 +1359,86 @@ ntlmprovider = ["requests-ntlm"] [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -1516,93 +1522,89 @@ pytzdata = ">=2020.1" [[package]] name = "pillow" -version = "11.0.0" +version = "11.1.0" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.9" files = [ - {file = "pillow-11.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947"}, - {file = "pillow-11.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba"}, - {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086"}, - {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9"}, - {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488"}, - {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f"}, - {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb"}, - {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97"}, - {file = "pillow-11.0.0-cp310-cp310-win32.whl", hash = "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50"}, - {file = "pillow-11.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c"}, - {file = "pillow-11.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1"}, - {file = "pillow-11.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc"}, - {file = "pillow-11.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a"}, - {file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3"}, - {file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5"}, - {file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b"}, - {file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa"}, - {file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306"}, - {file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9"}, - {file = "pillow-11.0.0-cp311-cp311-win32.whl", hash = "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5"}, - {file = "pillow-11.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291"}, - {file = "pillow-11.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9"}, - {file = "pillow-11.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923"}, - {file = "pillow-11.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903"}, - {file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4"}, - {file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f"}, - {file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9"}, - {file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7"}, - {file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6"}, - {file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc"}, - {file = "pillow-11.0.0-cp312-cp312-win32.whl", hash = "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6"}, - {file = "pillow-11.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47"}, - {file = "pillow-11.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25"}, - {file = "pillow-11.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcd1fb5bb7b07f64c15618c89efcc2cfa3e95f0e3bcdbaf4642509de1942a699"}, - {file = "pillow-11.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e038b0745997c7dcaae350d35859c9715c71e92ffb7e0f4a8e8a16732150f38"}, - {file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ae08bd8ffc41aebf578c2af2f9d8749d91f448b3bfd41d7d9ff573d74f2a6b2"}, - {file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d69bfd8ec3219ae71bcde1f942b728903cad25fafe3100ba2258b973bd2bc1b2"}, - {file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:61b887f9ddba63ddf62fd02a3ba7add935d053b6dd7d58998c630e6dbade8527"}, - {file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:c6a660307ca9d4867caa8d9ca2c2658ab685de83792d1876274991adec7b93fa"}, - {file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:73e3a0200cdda995c7e43dd47436c1548f87a30bb27fb871f352a22ab8dcf45f"}, - {file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fba162b8872d30fea8c52b258a542c5dfd7b235fb5cb352240c8d63b414013eb"}, - {file = "pillow-11.0.0-cp313-cp313-win32.whl", hash = "sha256:f1b82c27e89fffc6da125d5eb0ca6e68017faf5efc078128cfaa42cf5cb38798"}, - {file = "pillow-11.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ba470552b48e5835f1d23ecb936bb7f71d206f9dfeee64245f30c3270b994de"}, - {file = "pillow-11.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:846e193e103b41e984ac921b335df59195356ce3f71dcfd155aa79c603873b84"}, - {file = "pillow-11.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4ad70c4214f67d7466bea6a08061eba35c01b1b89eaa098040a35272a8efb22b"}, - {file = "pillow-11.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6ec0d5af64f2e3d64a165f490d96368bb5dea8b8f9ad04487f9ab60dc4bb6003"}, - {file = "pillow-11.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c809a70e43c7977c4a42aefd62f0131823ebf7dd73556fa5d5950f5b354087e2"}, - {file = "pillow-11.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:4b60c9520f7207aaf2e1d94de026682fc227806c6e1f55bba7606d1c94dd623a"}, - {file = "pillow-11.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1e2688958a840c822279fda0086fec1fdab2f95bf2b717b66871c4ad9859d7e8"}, - {file = "pillow-11.0.0-cp313-cp313t-win32.whl", hash = "sha256:607bbe123c74e272e381a8d1957083a9463401f7bd01287f50521ecb05a313f8"}, - {file = "pillow-11.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c39ed17edea3bc69c743a8dd3e9853b7509625c2462532e62baa0732163a904"}, - {file = "pillow-11.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3"}, - {file = "pillow-11.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2e46773dc9f35a1dd28bd6981332fd7f27bec001a918a72a79b4133cf5291dba"}, - {file = "pillow-11.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2679d2258b7f1192b378e2893a8a0a0ca472234d4c2c0e6bdd3380e8dfa21b6a"}, - {file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eda2616eb2313cbb3eebbe51f19362eb434b18e3bb599466a1ffa76a033fb916"}, - {file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ec184af98a121fb2da42642dea8a29ec80fc3efbaefb86d8fdd2606619045d"}, - {file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:8594f42df584e5b4bb9281799698403f7af489fba84c34d53d1c4bfb71b7c4e7"}, - {file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:c12b5ae868897c7338519c03049a806af85b9b8c237b7d675b8c5e089e4a618e"}, - {file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:70fbbdacd1d271b77b7721fe3cdd2d537bbbd75d29e6300c672ec6bb38d9672f"}, - {file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5178952973e588b3f1360868847334e9e3bf49d19e169bbbdfaf8398002419ae"}, - {file = "pillow-11.0.0-cp39-cp39-win32.whl", hash = "sha256:8c676b587da5673d3c75bd67dd2a8cdfeb282ca38a30f37950511766b26858c4"}, - {file = "pillow-11.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:94f3e1780abb45062287b4614a5bc0874519c86a777d4a7ad34978e86428b8dd"}, - {file = "pillow-11.0.0-cp39-cp39-win_arm64.whl", hash = "sha256:290f2cc809f9da7d6d622550bbf4c1e57518212da51b6a30fe8e0a270a5b78bd"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316"}, - {file = "pillow-11.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5bd2d3bdb846d757055910f0a59792d33b555800813c3b39ada1829c372ccb06"}, - {file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:375b8dd15a1f5d2feafff536d47e22f69625c1aa92f12b339ec0b2ca40263273"}, - {file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:daffdf51ee5db69a82dd127eabecce20729e21f7a3680cf7cbb23f0829189790"}, - {file = "pillow-11.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7326a1787e3c7b0429659e0a944725e1b03eeaa10edd945a86dead1913383944"}, - {file = "pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739"}, + {file = "pillow-11.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:e1abe69aca89514737465752b4bcaf8016de61b3be1397a8fc260ba33321b3a8"}, + {file = "pillow-11.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c640e5a06869c75994624551f45e5506e4256562ead981cce820d5ab39ae2192"}, + {file = "pillow-11.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a07dba04c5e22824816b2615ad7a7484432d7f540e6fa86af60d2de57b0fcee2"}, + {file = "pillow-11.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e267b0ed063341f3e60acd25c05200df4193e15a4a5807075cd71225a2386e26"}, + {file = "pillow-11.1.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:bd165131fd51697e22421d0e467997ad31621b74bfc0b75956608cb2906dda07"}, + {file = "pillow-11.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:abc56501c3fd148d60659aae0af6ddc149660469082859fa7b066a298bde9482"}, + {file = "pillow-11.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:54ce1c9a16a9561b6d6d8cb30089ab1e5eb66918cb47d457bd996ef34182922e"}, + {file = "pillow-11.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:73ddde795ee9b06257dac5ad42fcb07f3b9b813f8c1f7f870f402f4dc54b5269"}, + {file = "pillow-11.1.0-cp310-cp310-win32.whl", hash = "sha256:3a5fe20a7b66e8135d7fd617b13272626a28278d0e578c98720d9ba4b2439d49"}, + {file = "pillow-11.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:b6123aa4a59d75f06e9dd3dac5bf8bc9aa383121bb3dd9a7a612e05eabc9961a"}, + {file = "pillow-11.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:a76da0a31da6fcae4210aa94fd779c65c75786bc9af06289cd1c184451ef7a65"}, + {file = "pillow-11.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:e06695e0326d05b06833b40b7ef477e475d0b1ba3a6d27da1bb48c23209bf457"}, + {file = "pillow-11.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96f82000e12f23e4f29346e42702b6ed9a2f2fea34a740dd5ffffcc8c539eb35"}, + {file = "pillow-11.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3cd561ded2cf2bbae44d4605837221b987c216cff94f49dfeed63488bb228d2"}, + {file = "pillow-11.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f189805c8be5ca5add39e6f899e6ce2ed824e65fb45f3c28cb2841911da19070"}, + {file = "pillow-11.1.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:dd0052e9db3474df30433f83a71b9b23bd9e4ef1de13d92df21a52c0303b8ab6"}, + {file = "pillow-11.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:837060a8599b8f5d402e97197d4924f05a2e0d68756998345c829c33186217b1"}, + {file = "pillow-11.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:aa8dd43daa836b9a8128dbe7d923423e5ad86f50a7a14dc688194b7be5c0dea2"}, + {file = "pillow-11.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0a2f91f8a8b367e7a57c6e91cd25af510168091fb89ec5146003e424e1558a96"}, + {file = "pillow-11.1.0-cp311-cp311-win32.whl", hash = "sha256:c12fc111ef090845de2bb15009372175d76ac99969bdf31e2ce9b42e4b8cd88f"}, + {file = "pillow-11.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fbd43429d0d7ed6533b25fc993861b8fd512c42d04514a0dd6337fb3ccf22761"}, + {file = "pillow-11.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:f7955ecf5609dee9442cbface754f2c6e541d9e6eda87fad7f7a989b0bdb9d71"}, + {file = "pillow-11.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2062ffb1d36544d42fcaa277b069c88b01bb7298f4efa06731a7fd6cc290b81a"}, + {file = "pillow-11.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a85b653980faad27e88b141348707ceeef8a1186f75ecc600c395dcac19f385b"}, + {file = "pillow-11.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9409c080586d1f683df3f184f20e36fb647f2e0bc3988094d4fd8c9f4eb1b3b3"}, + {file = "pillow-11.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fdadc077553621911f27ce206ffcbec7d3f8d7b50e0da39f10997e8e2bb7f6a"}, + {file = "pillow-11.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:93a18841d09bcdd774dcdc308e4537e1f867b3dec059c131fde0327899734aa1"}, + {file = "pillow-11.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9aa9aeddeed452b2f616ff5507459e7bab436916ccb10961c4a382cd3e03f47f"}, + {file = "pillow-11.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3cdcdb0b896e981678eee140d882b70092dac83ac1cdf6b3a60e2216a73f2b91"}, + {file = "pillow-11.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:36ba10b9cb413e7c7dfa3e189aba252deee0602c86c309799da5a74009ac7a1c"}, + {file = "pillow-11.1.0-cp312-cp312-win32.whl", hash = "sha256:cfd5cd998c2e36a862d0e27b2df63237e67273f2fc78f47445b14e73a810e7e6"}, + {file = "pillow-11.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:a697cd8ba0383bba3d2d3ada02b34ed268cb548b369943cd349007730c92bddf"}, + {file = "pillow-11.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:4dd43a78897793f60766563969442020e90eb7847463eca901e41ba186a7d4a5"}, + {file = "pillow-11.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae98e14432d458fc3de11a77ccb3ae65ddce70f730e7c76140653048c71bfcbc"}, + {file = "pillow-11.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc1331b6d5a6e144aeb5e626f4375f5b7ae9934ba620c0ac6b3e43d5e683a0f0"}, + {file = "pillow-11.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:758e9d4ef15d3560214cddbc97b8ef3ef86ce04d62ddac17ad39ba87e89bd3b1"}, + {file = "pillow-11.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b523466b1a31d0dcef7c5be1f20b942919b62fd6e9a9be199d035509cbefc0ec"}, + {file = "pillow-11.1.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:9044b5e4f7083f209c4e35aa5dd54b1dd5b112b108648f5c902ad586d4f945c5"}, + {file = "pillow-11.1.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:3764d53e09cdedd91bee65c2527815d315c6b90d7b8b79759cc48d7bf5d4f114"}, + {file = "pillow-11.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31eba6bbdd27dde97b0174ddf0297d7a9c3a507a8a1480e1e60ef914fe23d352"}, + {file = "pillow-11.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b5d658fbd9f0d6eea113aea286b21d3cd4d3fd978157cbf2447a6035916506d3"}, + {file = "pillow-11.1.0-cp313-cp313-win32.whl", hash = "sha256:f86d3a7a9af5d826744fabf4afd15b9dfef44fe69a98541f666f66fbb8d3fef9"}, + {file = "pillow-11.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:593c5fd6be85da83656b93ffcccc2312d2d149d251e98588b14fbc288fd8909c"}, + {file = "pillow-11.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:11633d58b6ee5733bde153a8dafd25e505ea3d32e261accd388827ee987baf65"}, + {file = "pillow-11.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:70ca5ef3b3b1c4a0812b5c63c57c23b63e53bc38e758b37a951e5bc466449861"}, + {file = "pillow-11.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8000376f139d4d38d6851eb149b321a52bb8893a88dae8ee7d95840431977081"}, + {file = "pillow-11.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee85f0696a17dd28fbcfceb59f9510aa71934b483d1f5601d1030c3c8304f3c"}, + {file = "pillow-11.1.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:dd0e081319328928531df7a0e63621caf67652c8464303fd102141b785ef9547"}, + {file = "pillow-11.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e63e4e5081de46517099dc30abe418122f54531a6ae2ebc8680bcd7096860eab"}, + {file = "pillow-11.1.0-cp313-cp313t-win32.whl", hash = "sha256:dda60aa465b861324e65a78c9f5cf0f4bc713e4309f83bc387be158b077963d9"}, + {file = "pillow-11.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ad5db5781c774ab9a9b2c4302bbf0c1014960a0a7be63278d13ae6fdf88126fe"}, + {file = "pillow-11.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756"}, + {file = "pillow-11.1.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:bf902d7413c82a1bfa08b06a070876132a5ae6b2388e2712aab3a7cbc02205c6"}, + {file = "pillow-11.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c1eec9d950b6fe688edee07138993e54ee4ae634c51443cfb7c1e7613322718e"}, + {file = "pillow-11.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e275ee4cb11c262bd108ab2081f750db2a1c0b8c12c1897f27b160c8bd57bbc"}, + {file = "pillow-11.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4db853948ce4e718f2fc775b75c37ba2efb6aaea41a1a5fc57f0af59eee774b2"}, + {file = "pillow-11.1.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:ab8a209b8485d3db694fa97a896d96dd6533d63c22829043fd9de627060beade"}, + {file = "pillow-11.1.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:54251ef02a2309b5eec99d151ebf5c9904b77976c8abdcbce7891ed22df53884"}, + {file = "pillow-11.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5bb94705aea800051a743aa4874bb1397d4695fb0583ba5e425ee0328757f196"}, + {file = "pillow-11.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:89dbdb3e6e9594d512780a5a1c42801879628b38e3efc7038094430844e271d8"}, + {file = "pillow-11.1.0-cp39-cp39-win32.whl", hash = "sha256:e5449ca63da169a2e6068dd0e2fcc8d91f9558aba89ff6d02121ca8ab11e79e5"}, + {file = "pillow-11.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:3362c6ca227e65c54bf71a5f88b3d4565ff1bcbc63ae72c34b07bbb1cc59a43f"}, + {file = "pillow-11.1.0-cp39-cp39-win_arm64.whl", hash = "sha256:b20be51b37a75cc54c2c55def3fa2c65bb94ba859dde241cd0a4fd302de5ae0a"}, + {file = "pillow-11.1.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8c730dc3a83e5ac137fbc92dfcfe1511ce3b2b5d7578315b63dbbb76f7f51d90"}, + {file = "pillow-11.1.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:7d33d2fae0e8b170b6a6c57400e077412240f6f5bb2a342cf1ee512a787942bb"}, + {file = "pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8d65b38173085f24bc07f8b6c505cbb7418009fa1a1fcb111b1f4961814a442"}, + {file = "pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:015c6e863faa4779251436db398ae75051469f7c903b043a48f078e437656f83"}, + {file = "pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d44ff19eea13ae4acdaaab0179fa68c0c6f2f45d66a4d8ec1eda7d6cecbcc15f"}, + {file = "pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d3d8da4a631471dfaf94c10c85f5277b1f8e42ac42bade1ac67da4b4a7359b73"}, + {file = "pillow-11.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:4637b88343166249fe8aa94e7c4a62a180c4b3898283bb5d3d2fd5fe10d8e4e0"}, + {file = "pillow-11.1.0.tar.gz", hash = "sha256:368da70808b36d73b4b390a8ffac11069f8a5c85f29eff1f1b01bcf3ef5b2a20"}, ] [package.extras] docs = ["furo", "olefile", "sphinx (>=8.1)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] fpx = ["olefile"] mic = ["olefile"] -tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "trove-classifiers (>=2024.10.12)"] typing = ["typing-extensions"] xmp = ["defusedxml"] @@ -1709,54 +1711,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -1768,13 +1770,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.dependencies] @@ -2053,99 +2055,99 @@ files = [ [[package]] name = "rapidfuzz" -version = "3.10.1" +version = "3.11.0" description = "rapid fuzzy string matching" optional = false python-versions = ">=3.9" files = [ - {file = "rapidfuzz-3.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f17d9f21bf2f2f785d74f7b0d407805468b4c173fa3e52c86ec94436b338e74a"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b31f358a70efc143909fb3d75ac6cd3c139cd41339aa8f2a3a0ead8315731f2b"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f4f43f2204b56a61448ec2dd061e26fd344c404da99fb19f3458200c5874ba2"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d81bf186a453a2757472133b24915768abc7c3964194406ed93e170e16c21cb"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3611c8f45379a12063d70075c75134f2a8bd2e4e9b8a7995112ddae95ca1c982"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c3b537b97ac30da4b73930fa8a4fe2f79c6d1c10ad535c5c09726612cd6bed9"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:231ef1ec9cf7b59809ce3301006500b9d564ddb324635f4ea8f16b3e2a1780da"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ed4f3adc1294834955b7e74edd3c6bd1aad5831c007f2d91ea839e76461a5879"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:7b6015da2e707bf632a71772a2dbf0703cff6525732c005ad24987fe86e8ec32"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1b35a118d61d6f008e8e3fb3a77674d10806a8972c7b8be433d6598df4d60b01"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:bc308d79a7e877226f36bdf4e149e3ed398d8277c140be5c1fd892ec41739e6d"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f017dbfecc172e2d0c37cf9e3d519179d71a7f16094b57430dffc496a098aa17"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-win32.whl", hash = "sha256:36c0e1483e21f918d0f2f26799fe5ac91c7b0c34220b73007301c4f831a9c4c7"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:10746c1d4c8cd8881c28a87fd7ba0c9c102346dfe7ff1b0d021cdf093e9adbff"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-win_arm64.whl", hash = "sha256:dfa64b89dcb906835e275187569e51aa9d546a444489e97aaf2cc84011565fbe"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:92958ae075c87fef393f835ed02d4fe8d5ee2059a0934c6c447ea3417dfbf0e8"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ba7521e072c53e33c384e78615d0718e645cab3c366ecd3cc8cb732befd94967"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d02cbd75d283c287471b5b3738b3e05c9096150f93f2d2dfa10b3d700f2db9"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:efa1582a397da038e2f2576c9cd49b842f56fde37d84a6b0200ffebc08d82350"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f12912acee1f506f974f58de9fdc2e62eea5667377a7e9156de53241c05fdba8"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666d5d8b17becc3f53447bcb2b6b33ce6c2df78792495d1fa82b2924cd48701a"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26f71582c0d62445067ee338ddad99b655a8f4e4ed517a90dcbfbb7d19310474"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8a2ef08b27167bcff230ffbfeedd4c4fa6353563d6aaa015d725dd3632fc3de7"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:365e4fc1a2b95082c890f5e98489b894e6bf8c338c6ac89bb6523c2ca6e9f086"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1996feb7a61609fa842e6b5e0c549983222ffdedaf29644cc67e479902846dfe"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:cf654702f144beaa093103841a2ea6910d617d0bb3fccb1d1fd63c54dde2cd49"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec108bf25de674781d0a9a935030ba090c78d49def3d60f8724f3fc1e8e75024"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-win32.whl", hash = "sha256:031f8b367e5d92f7a1e27f7322012f3c321c3110137b43cc3bf678505583ef48"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:f98f36c6a1bb9a6c8bbec99ad87c8c0e364f34761739b5ea9adf7b48129ae8cf"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-win_arm64.whl", hash = "sha256:f1da2028cb4e41be55ee797a82d6c1cf589442504244249dfeb32efc608edee7"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1340b56340896bede246f612b6ecf685f661a56aabef3d2512481bfe23ac5835"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2316515169b7b5a453f0ce3adbc46c42aa332cae9f2edb668e24d1fc92b2f2bb"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e06fe6a12241ec1b72c0566c6b28cda714d61965d86569595ad24793d1ab259"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d99c1cd9443b19164ec185a7d752f4b4db19c066c136f028991a480720472e23"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1d9aa156ed52d3446388ba4c2f335e312191d1ca9d1f5762ee983cf23e4ecf6"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:54bcf4efaaee8e015822be0c2c28214815f4f6b4f70d8362cfecbd58a71188ac"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0c955e32afdbfdf6e9ee663d24afb25210152d98c26d22d399712d29a9b976b"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:191633722203f5b7717efcb73a14f76f3b124877d0608c070b827c5226d0b972"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:195baad28057ec9609e40385991004e470af9ef87401e24ebe72c064431524ab"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0fff4a6b87c07366662b62ae994ffbeadc472e72f725923f94b72a3db49f4671"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4ffed25f9fdc0b287f30a98467493d1e1ce5b583f6317f70ec0263b3c97dbba6"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d02cf8e5af89a9ac8f53c438ddff6d773f62c25c6619b29db96f4aae248177c0"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-win32.whl", hash = "sha256:f3bb81d4fe6a5d20650f8c0afcc8f6e1941f6fecdb434f11b874c42467baded0"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:aaf83e9170cb1338922ae42d320699dccbbdca8ffed07faeb0b9257822c26e24"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-win_arm64.whl", hash = "sha256:c5da802a0d085ad81b0f62828fb55557996c497b2d0b551bbdfeafd6d447892f"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fc22d69a1c9cccd560a5c434c0371b2df0f47c309c635a01a913e03bbf183710"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38b0dac2c8e057562b8f0d8ae5b663d2d6a28c5ab624de5b73cef9abb6129a24"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fde3bbb14e92ce8fcb5c2edfff72e474d0080cadda1c97785bf4822f037a309"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9141fb0592e55f98fe9ac0f3ce883199b9c13e262e0bf40c5b18cdf926109d16"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:237bec5dd1bfc9b40bbd786cd27949ef0c0eb5fab5eb491904c6b5df59d39d3c"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18123168cba156ab5794ea6de66db50f21bb3c66ae748d03316e71b27d907b95"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b75fe506c8e02769cc47f5ab21ce3e09b6211d3edaa8f8f27331cb6988779be"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9da82aa4b46973aaf9e03bb4c3d6977004648c8638febfc0f9d237e865761270"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c34c022d5ad564f1a5a57a4a89793bd70d7bad428150fb8ff2760b223407cdcf"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1e96c84d6c2a0ca94e15acb5399118fff669f4306beb98a6d8ec6f5dccab4412"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e8e154b84a311263e1aca86818c962e1fa9eefdd643d1d5d197fcd2738f88cb9"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:335fee93188f8cd585552bb8057228ce0111bd227fa81bfd40b7df6b75def8ab"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-win32.whl", hash = "sha256:6729b856166a9e95c278410f73683957ea6100c8a9d0a8dbe434c49663689255"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-win_amd64.whl", hash = "sha256:0e06d99ad1ad97cb2ef7f51ec6b1fedd74a3a700e4949353871cf331d07b382a"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-win_arm64.whl", hash = "sha256:8d1b7082104d596a3eb012e0549b2634ed15015b569f48879701e9d8db959dbb"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:779027d3307e1a2b1dc0c03c34df87a470a368a1a0840a9d2908baf2d4067956"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:440b5608ab12650d0390128d6858bc839ae77ffe5edf0b33a1551f2fa9860651"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cac41a411e07a6f3dc80dfbd33f6be70ea0abd72e99c59310819d09f07d945"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:958473c9f0bca250590200fd520b75be0dbdbc4a7327dc87a55b6d7dc8d68552"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ef60dfa73749ef91cb6073be1a3e135f4846ec809cc115f3cbfc6fe283a5584"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7fbac18f2c19fc983838a60611e67e3262e36859994c26f2ee85bb268de2355"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a0d519ff39db887cd73f4e297922786d548f5c05d6b51f4e6754f452a7f4296"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bebb7bc6aeb91cc57e4881b222484c26759ca865794187217c9dcea6c33adae6"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fe07f8b9c3bb5c5ad1d2c66884253e03800f4189a60eb6acd6119ebaf3eb9894"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:bfa48a4a2d45a41457f0840c48e579db157a927f4e97acf6e20df8fc521c79de"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2cf44d01bfe8ee605b7eaeecbc2b9ca64fc55765f17b304b40ed8995f69d7716"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e6bbca9246d9eedaa1c84e04a7f555493ba324d52ae4d9f3d9ddd1b740dcd87"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-win32.whl", hash = "sha256:567f88180f2c1423b4fe3f3ad6e6310fc97b85bdba574801548597287fc07028"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:6b2cd7c29d6ecdf0b780deb587198f13213ac01c430ada6913452fd0c40190fc"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-win_arm64.whl", hash = "sha256:9f912d459e46607ce276128f52bea21ebc3e9a5ccf4cccfef30dd5bddcf47be8"}, - {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ac4452f182243cfab30ba4668ef2de101effaedc30f9faabb06a095a8c90fd16"}, - {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:565c2bd4f7d23c32834652b27b51dd711814ab614b4e12add8476be4e20d1cf5"}, - {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:187d9747149321607be4ccd6f9f366730078bed806178ec3eeb31d05545e9e8f"}, - {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:616290fb9a8fa87e48cb0326d26f98d4e29f17c3b762c2d586f2b35c1fd2034b"}, - {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:073a5b107e17ebd264198b78614c0206fa438cce749692af5bc5f8f484883f50"}, - {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:39c4983e2e2ccb9732f3ac7d81617088822f4a12291d416b09b8a1eadebb3e29"}, - {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ac7adee6bcf0c6fee495d877edad1540a7e0f5fc208da03ccb64734b43522d7a"}, - {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:425f4ac80b22153d391ee3f94bc854668a0c6c129f05cf2eaf5ee74474ddb69e"}, - {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65a2fa13e8a219f9b5dcb9e74abe3ced5838a7327e629f426d333dfc8c5a6e66"}, - {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75561f3df9a906aaa23787e9992b228b1ab69007932dc42070f747103e177ba8"}, - {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:edd062490537e97ca125bc6c7f2b7331c2b73d21dc304615afe61ad1691e15d5"}, - {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfcc8feccf63245a22dfdd16e222f1a39771a44b870beb748117a0e09cbb4a62"}, - {file = "rapidfuzz-3.10.1.tar.gz", hash = "sha256:5a15546d847a915b3f42dc79ef9b0c78b998b4e2c53b252e7166284066585979"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eb8a54543d16ab1b69e2c5ed96cabbff16db044a50eddfc028000138ca9ddf33"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:231c8b2efbd7f8d2ecd1ae900363ba168b8870644bb8f2b5aa96e4a7573bde19"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54e7f442fb9cca81e9df32333fb075ef729052bcabe05b0afc0441f462299114"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:906f1f2a1b91c06599b3dd1be207449c5d4fc7bd1e1fa2f6aef161ea6223f165"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed59044aea9eb6c663112170f2399b040d5d7b162828b141f2673e822093fa8"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cb1965a28b0fa64abdee130c788a0bc0bb3cf9ef7e3a70bf055c086c14a3d7e"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b488b244931d0291412917e6e46ee9f6a14376625e150056fe7c4426ef28225"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f0ba13557fec9d5ffc0a22826754a7457cc77f1b25145be10b7bb1d143ce84c6"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3871fa7dfcef00bad3c7e8ae8d8fd58089bad6fb21f608d2bf42832267ca9663"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b2669eafee38c5884a6e7cc9769d25c19428549dcdf57de8541cf9e82822e7db"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ffa1bb0e26297b0f22881b219ffc82a33a3c84ce6174a9d69406239b14575bd5"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:45b15b8a118856ac9caac6877f70f38b8a0d310475d50bc814698659eabc1cdb"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win32.whl", hash = "sha256:22033677982b9c4c49676f215b794b0404073f8974f98739cb7234e4a9ade9ad"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:be15496e7244361ff0efcd86e52559bacda9cd975eccf19426a0025f9547c792"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_arm64.whl", hash = "sha256:714a7ba31ba46b64d30fccfe95f8013ea41a2e6237ba11a805a27cdd3bce2573"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8724a978f8af7059c5323d523870bf272a097478e1471295511cf58b2642ff83"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b63cb1f2eb371ef20fb155e95efd96e060147bdd4ab9fc400c97325dfee9fe1"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82497f244aac10b20710448645f347d862364cc4f7d8b9ba14bd66b5ce4dec18"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:339607394941801e6e3f6c1ecd413a36e18454e7136ed1161388de674f47f9d9"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84819390a36d6166cec706b9d8f0941f115f700b7faecab5a7e22fc367408bc3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eea8d9e20632d68f653455265b18c35f90965e26f30d4d92f831899d6682149b"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b659e1e2ea2784a9a397075a7fc395bfa4fe66424042161c4bcaf6e4f637b38"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1315cd2a351144572e31fe3df68340d4b83ddec0af8b2e207cd32930c6acd037"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a7743cca45b4684c54407e8638f6d07b910d8d811347b9d42ff21262c7c23245"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:5bb636b0150daa6d3331b738f7c0f8b25eadc47f04a40e5c23c4bfb4c4e20ae3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:42f4dd264ada7a9aa0805ea0da776dc063533917773cf2df5217f14eb4429eae"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:51f24cb39e64256221e6952f22545b8ce21cacd59c0d3e367225da8fc4b868d8"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win32.whl", hash = "sha256:aaf391fb6715866bc14681c76dc0308f46877f7c06f61d62cc993b79fc3c4a2a"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:ebadd5b8624d8ad503e505a99b8eb26fe3ea9f8e9c2234e805a27b269e585842"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:d895998fec712544c13cfe833890e0226585cf0391dd3948412441d5d68a2b8c"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f382fec4a7891d66fb7163c90754454030bb9200a13f82ee7860b6359f3f2fa8"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dfaefe08af2a928e72344c800dcbaf6508e86a4ed481e28355e8d4b6a6a5230e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92ebb7c12f682b5906ed98429f48a3dd80dd0f9721de30c97a01473d1a346576"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a1b3ebc62d4bcdfdeba110944a25ab40916d5383c5e57e7c4a8dc0b6c17211a"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c6d7fea39cb33e71de86397d38bf7ff1a6273e40367f31d05761662ffda49e4"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99aebef8268f2bc0b445b5640fd3312e080bd17efd3fbae4486b20ac00466308"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4469307f464ae3089acf3210b8fc279110d26d10f79e576f385a98f4429f7d97"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:eb97c53112b593f89a90b4f6218635a9d1eea1d7f9521a3b7d24864228bbc0aa"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef8937dae823b889c0273dfa0f0f6c46a3658ac0d851349c464d1b00e7ff4252"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d95f9e9f3777b96241d8a00d6377cc9c716981d828b5091082d0fe3a2924b43e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:b1d67d67f89e4e013a5295e7523bc34a7a96f2dba5dd812c7c8cb65d113cbf28"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d994cf27e2f874069884d9bddf0864f9b90ad201fcc9cb2f5b82bacc17c8d5f2"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win32.whl", hash = "sha256:ba26d87fe7fcb56c4a53b549a9e0e9143f6b0df56d35fe6ad800c902447acd5b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:b1f7efdd7b7adb32102c2fa481ad6f11923e2deb191f651274be559d56fc913b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:ed78c8e94f57b44292c1a0350f580e18d3a3c5c0800e253f1583580c1b417ad2"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e60814edd0c9b511b5f377d48b9782b88cfe8be07a98f99973669299c8bb318a"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f28952da055dbfe75828891cd3c9abf0984edc8640573c18b48c14c68ca5e06"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e8f93bc736020351a6f8e71666e1f486bb8bd5ce8112c443a30c77bfde0eb68"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76a4a11ba8f678c9e5876a7d465ab86def047a4fcc043617578368755d63a1bc"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc0e0d41ad8a056a9886bac91ff9d9978e54a244deb61c2972cc76b66752de9c"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e8ea35f2419c7d56b3e75fbde2698766daedb374f20eea28ac9b1f668ef4f74"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd340bbd025302276b5aa221dccfe43040c7babfc32f107c36ad783f2ffd8775"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:494eef2c68305ab75139034ea25328a04a548d297712d9cf887bf27c158c388b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5a167344c1d6db06915fb0225592afdc24d8bafaaf02de07d4788ddd37f4bc2f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8c7af25bda96ac799378ac8aba54a8ece732835c7b74cfc201b688a87ed11152"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d2a0f7e17f33e7890257367a1662b05fecaf56625f7dbb6446227aaa2b86448b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4d0d26c7172bdb64f86ee0765c5b26ea1dc45c52389175888ec073b9b28f4305"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win32.whl", hash = "sha256:6ad02bab756751c90fa27f3069d7b12146613061341459abf55f8190d899649f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:b1472986fd9c5d318399a01a0881f4a0bf4950264131bb8e2deba9df6d8c362b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:c408f09649cbff8da76f8d3ad878b64ba7f7abdad1471efb293d2c075e80c822"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1bac4873f6186f5233b0084b266bfb459e997f4c21fc9f029918f44a9eccd304"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f9f12c2d0aa52b86206d2059916153876a9b1cf9dfb3cf2f344913167f1c3d4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd501de6f7a8f83557d20613b58734d1cb5f0be78d794cde64fe43cfc63f5f2"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4416ca69af933d4a8ad30910149d3db6d084781d5c5fdedb713205389f535385"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f0821b9bdf18c5b7d51722b906b233a39b17f602501a966cfbd9b285f8ab83cd"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0edecc3f90c2653298d380f6ea73b536944b767520c2179ec5d40b9145e47aa"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4513dd01cee11e354c31b75f652d4d466c9440b6859f84e600bdebfccb17735a"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d9727b85511b912571a76ce53c7640ba2c44c364e71cef6d7359b5412739c570"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ab9eab33ee3213f7751dc07a1a61b8d9a3d748ca4458fffddd9defa6f0493c16"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:6b01c1ddbb054283797967ddc5433d5c108d680e8fa2684cf368be05407b07e4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:3857e335f97058c4b46fa39ca831290b70de554a5c5af0323d2f163b19c5f2a6"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d98a46cf07c0c875d27e8a7ed50f304d83063e49b9ab63f21c19c154b4c0d08d"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win32.whl", hash = "sha256:c36539ed2c0173b053dafb221458812e178cfa3224ade0960599bec194637048"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:ec8d7d8567e14af34a7911c98f5ac74a3d4a743cd848643341fc92b12b3784ff"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_arm64.whl", hash = "sha256:62171b270ecc4071be1c1f99960317db261d4c8c83c169e7f8ad119211fe7397"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f06e3c4c0a8badfc4910b9fd15beb1ad8f3b8fafa8ea82c023e5e607b66a78e4"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fe7aaf5a54821d340d21412f7f6e6272a9b17a0cbafc1d68f77f2fc11009dcd5"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25398d9ac7294e99876a3027ffc52c6bebeb2d702b1895af6ae9c541ee676702"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a52eea839e4bdc72c5e60a444d26004da00bb5bc6301e99b3dde18212e41465"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c87319b0ab9d269ab84f6453601fd49b35d9e4a601bbaef43743f26fabf496c"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3048c6ed29d693fba7d2a7caf165f5e0bb2b9743a0989012a98a47b975355cca"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b04f29735bad9f06bb731c214f27253bd8bedb248ef9b8a1b4c5bde65b838454"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7864e80a0d4e23eb6194254a81ee1216abdc53f9dc85b7f4d56668eced022eb8"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3794df87313dfb56fafd679b962e0613c88a293fd9bd5dd5c2793d66bf06a101"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d71da0012face6f45432a11bc59af19e62fac5a41f8ce489e80c0add8153c3d1"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff38378346b7018f42cbc1f6d1d3778e36e16d8595f79a312b31e7c25c50bd08"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6668321f90aa02a5a789d4e16058f2e4f2692c5230252425c3532a8a62bc3424"}, + {file = "rapidfuzz-3.11.0.tar.gz", hash = "sha256:a53ca4d3f52f00b393fab9b5913c5bafb9afc27d030c8a1db1283da6917a860f"}, ] [package.extras] @@ -2153,105 +2155,105 @@ all = ["numpy"] [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -2338,121 +2340,26 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "safetensors" -version = "0.4.5" +version = "0.5.0" description = "" optional = false python-versions = ">=3.7" files = [ - {file = "safetensors-0.4.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a63eaccd22243c67e4f2b1c3e258b257effc4acd78f3b9d397edc8cf8f1298a7"}, - {file = "safetensors-0.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:23fc9b4ec7b602915cbb4ec1a7c1ad96d2743c322f20ab709e2c35d1b66dad27"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6885016f34bef80ea1085b7e99b3c1f92cb1be78a49839203060f67b40aee761"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:133620f443450429322f238fda74d512c4008621227fccf2f8cf4a76206fea7c"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4fb3e0609ec12d2a77e882f07cced530b8262027f64b75d399f1504ffec0ba56"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0f1dd769f064adc33831f5e97ad07babbd728427f98e3e1db6902e369122737"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6d156bdb26732feada84f9388a9f135528c1ef5b05fae153da365ad4319c4c5"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9e347d77e2c77eb7624400ccd09bed69d35c0332f417ce8c048d404a096c593b"}, - {file = "safetensors-0.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9f556eea3aec1d3d955403159fe2123ddd68e880f83954ee9b4a3f2e15e716b6"}, - {file = "safetensors-0.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9483f42be3b6bc8ff77dd67302de8ae411c4db39f7224dec66b0eb95822e4163"}, - {file = "safetensors-0.4.5-cp310-none-win32.whl", hash = "sha256:7389129c03fadd1ccc37fd1ebbc773f2b031483b04700923c3511d2a939252cc"}, - {file = "safetensors-0.4.5-cp310-none-win_amd64.whl", hash = "sha256:e98ef5524f8b6620c8cdef97220c0b6a5c1cef69852fcd2f174bb96c2bb316b1"}, - {file = "safetensors-0.4.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:21f848d7aebd5954f92538552d6d75f7c1b4500f51664078b5b49720d180e47c"}, - {file = "safetensors-0.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bb07000b19d41e35eecef9a454f31a8b4718a185293f0d0b1c4b61d6e4487971"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09dedf7c2fda934ee68143202acff6e9e8eb0ddeeb4cfc24182bef999efa9f42"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:59b77e4b7a708988d84f26de3ebead61ef1659c73dcbc9946c18f3b1786d2688"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d3bc83e14d67adc2e9387e511097f254bd1b43c3020440e708858c684cbac68"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39371fc551c1072976073ab258c3119395294cf49cdc1f8476794627de3130df"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6c19feda32b931cae0acd42748a670bdf56bee6476a046af20181ad3fee4090"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a659467495de201e2f282063808a41170448c78bada1e62707b07a27b05e6943"}, - {file = "safetensors-0.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bad5e4b2476949bcd638a89f71b6916fa9a5cae5c1ae7eede337aca2100435c0"}, - {file = "safetensors-0.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a3a315a6d0054bc6889a17f5668a73f94f7fe55121ff59e0a199e3519c08565f"}, - {file = "safetensors-0.4.5-cp311-none-win32.whl", hash = "sha256:a01e232e6d3d5cf8b1667bc3b657a77bdab73f0743c26c1d3c5dd7ce86bd3a92"}, - {file = "safetensors-0.4.5-cp311-none-win_amd64.whl", hash = "sha256:cbd39cae1ad3e3ef6f63a6f07296b080c951f24cec60188378e43d3713000c04"}, - {file = "safetensors-0.4.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:473300314e026bd1043cef391bb16a8689453363381561b8a3e443870937cc1e"}, - {file = "safetensors-0.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:801183a0f76dc647f51a2d9141ad341f9665602a7899a693207a82fb102cc53e"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1524b54246e422ad6fb6aea1ac71edeeb77666efa67230e1faf6999df9b2e27f"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b3139098e3e8b2ad7afbca96d30ad29157b50c90861084e69fcb80dec7430461"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65573dc35be9059770808e276b017256fa30058802c29e1038eb1c00028502ea"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd33da8e9407559f8779c82a0448e2133737f922d71f884da27184549416bfed"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3685ce7ed036f916316b567152482b7e959dc754fcc4a8342333d222e05f407c"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dde2bf390d25f67908278d6f5d59e46211ef98e44108727084d4637ee70ab4f1"}, - {file = "safetensors-0.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7469d70d3de970b1698d47c11ebbf296a308702cbaae7fcb993944751cf985f4"}, - {file = "safetensors-0.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3a6ba28118636a130ccbb968bc33d4684c48678695dba2590169d5ab03a45646"}, - {file = "safetensors-0.4.5-cp312-none-win32.whl", hash = "sha256:c859c7ed90b0047f58ee27751c8e56951452ed36a67afee1b0a87847d065eec6"}, - {file = "safetensors-0.4.5-cp312-none-win_amd64.whl", hash = "sha256:b5a8810ad6a6f933fff6c276eae92c1da217b39b4d8b1bc1c0b8af2d270dc532"}, - {file = "safetensors-0.4.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:25e5f8e2e92a74f05b4ca55686234c32aac19927903792b30ee6d7bd5653d54e"}, - {file = "safetensors-0.4.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:81efb124b58af39fcd684254c645e35692fea81c51627259cdf6d67ff4458916"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:585f1703a518b437f5103aa9cf70e9bd437cb78eea9c51024329e4fb8a3e3679"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b99fbf72e3faf0b2f5f16e5e3458b93b7d0a83984fe8d5364c60aa169f2da89"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b17b299ca9966ca983ecda1c0791a3f07f9ca6ab5ded8ef3d283fff45f6bcd5f"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76ded72f69209c9780fdb23ea89e56d35c54ae6abcdec67ccb22af8e696e449a"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2783956926303dcfeb1de91a4d1204cd4089ab441e622e7caee0642281109db3"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d94581aab8c6b204def4d7320f07534d6ee34cd4855688004a4354e63b639a35"}, - {file = "safetensors-0.4.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:67e1e7cb8678bb1b37ac48ec0df04faf689e2f4e9e81e566b5c63d9f23748523"}, - {file = "safetensors-0.4.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:dbd280b07e6054ea68b0cb4b16ad9703e7d63cd6890f577cb98acc5354780142"}, - {file = "safetensors-0.4.5-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:77d9b228da8374c7262046a36c1f656ba32a93df6cc51cd4453af932011e77f1"}, - {file = "safetensors-0.4.5-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:500cac01d50b301ab7bb192353317035011c5ceeef0fca652f9f43c000bb7f8d"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75331c0c746f03158ded32465b7d0b0e24c5a22121743662a2393439c43a45cf"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:670e95fe34e0d591d0529e5e59fd9d3d72bc77b1444fcaa14dccda4f36b5a38b"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:098923e2574ff237c517d6e840acada8e5b311cb1fa226019105ed82e9c3b62f"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13ca0902d2648775089fa6a0c8fc9e6390c5f8ee576517d33f9261656f851e3f"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f0032bedc869c56f8d26259fe39cd21c5199cd57f2228d817a0e23e8370af25"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f4b15f51b4f8f2a512341d9ce3475cacc19c5fdfc5db1f0e19449e75f95c7dc8"}, - {file = "safetensors-0.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f6594d130d0ad933d885c6a7b75c5183cb0e8450f799b80a39eae2b8508955eb"}, - {file = "safetensors-0.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:60c828a27e852ded2c85fc0f87bf1ec20e464c5cd4d56ff0e0711855cc2e17f8"}, - {file = "safetensors-0.4.5-cp37-none-win32.whl", hash = "sha256:6d3de65718b86c3eeaa8b73a9c3d123f9307a96bbd7be9698e21e76a56443af5"}, - {file = "safetensors-0.4.5-cp37-none-win_amd64.whl", hash = "sha256:5a2d68a523a4cefd791156a4174189a4114cf0bf9c50ceb89f261600f3b2b81a"}, - {file = "safetensors-0.4.5-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:e7a97058f96340850da0601a3309f3d29d6191b0702b2da201e54c6e3e44ccf0"}, - {file = "safetensors-0.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:63bfd425e25f5c733f572e2246e08a1c38bd6f2e027d3f7c87e2e43f228d1345"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3664ac565d0e809b0b929dae7ccd74e4d3273cd0c6d1220c6430035befb678e"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:313514b0b9b73ff4ddfb4edd71860696dbe3c1c9dc4d5cc13dbd74da283d2cbf"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31fa33ee326f750a2f2134a6174773c281d9a266ccd000bd4686d8021f1f3dac"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:09566792588d77b68abe53754c9f1308fadd35c9f87be939e22c623eaacbed6b"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309aaec9b66cbf07ad3a2e5cb8a03205663324fea024ba391594423d0f00d9fe"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:53946c5813b8f9e26103c5efff4a931cc45d874f45229edd68557ffb35ffb9f8"}, - {file = "safetensors-0.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:868f9df9e99ad1e7f38c52194063a982bc88fedc7d05096f4f8160403aaf4bd6"}, - {file = "safetensors-0.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9cc9449bd0b0bc538bd5e268221f0c5590bc5c14c1934a6ae359d44410dc68c4"}, - {file = "safetensors-0.4.5-cp38-none-win32.whl", hash = "sha256:83c4f13a9e687335c3928f615cd63a37e3f8ef072a3f2a0599fa09f863fb06a2"}, - {file = "safetensors-0.4.5-cp38-none-win_amd64.whl", hash = "sha256:b98d40a2ffa560653f6274e15b27b3544e8e3713a44627ce268f419f35c49478"}, - {file = "safetensors-0.4.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:cf727bb1281d66699bef5683b04d98c894a2803442c490a8d45cd365abfbdeb2"}, - {file = "safetensors-0.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:96f1d038c827cdc552d97e71f522e1049fef0542be575421f7684756a748e457"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:139fbee92570ecea774e6344fee908907db79646d00b12c535f66bc78bd5ea2c"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c36302c1c69eebb383775a89645a32b9d266878fab619819ce660309d6176c9b"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d641f5b8149ea98deb5ffcf604d764aad1de38a8285f86771ce1abf8e74c4891"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b4db6a61d968de73722b858038c616a1bebd4a86abe2688e46ca0cc2d17558f2"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b75a616e02f21b6f1d5785b20cecbab5e2bd3f6358a90e8925b813d557666ec1"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:788ee7d04cc0e0e7f944c52ff05f52a4415b312f5efd2ee66389fb7685ee030c"}, - {file = "safetensors-0.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:87bc42bd04fd9ca31396d3ca0433db0be1411b6b53ac5a32b7845a85d01ffc2e"}, - {file = "safetensors-0.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4037676c86365a721a8c9510323a51861d703b399b78a6b4486a54a65a975fca"}, - {file = "safetensors-0.4.5-cp39-none-win32.whl", hash = "sha256:1500418454529d0ed5c1564bda376c4ddff43f30fce9517d9bee7bcce5a8ef50"}, - {file = "safetensors-0.4.5-cp39-none-win_amd64.whl", hash = "sha256:9d1a94b9d793ed8fe35ab6d5cea28d540a46559bafc6aae98f30ee0867000cab"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fdadf66b5a22ceb645d5435a0be7a0292ce59648ca1d46b352f13cff3ea80410"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d42ffd4c2259f31832cb17ff866c111684c87bd930892a1ba53fed28370c918c"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd8a1f6d2063a92cd04145c7fd9e31a1c7d85fbec20113a14b487563fdbc0597"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:951d2fcf1817f4fb0ef0b48f6696688a4e852a95922a042b3f96aaa67eedc920"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6ac85d9a8c1af0e3132371d9f2d134695a06a96993c2e2f0bbe25debb9e3f67a"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e3cec4a29eb7fe8da0b1c7988bc3828183080439dd559f720414450de076fcab"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:21742b391b859e67b26c0b2ac37f52c9c0944a879a25ad2f9f9f3cd61e7fda8f"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c7db3006a4915151ce1913652e907cdede299b974641a83fbc092102ac41b644"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f68bf99ea970960a237f416ea394e266e0361895753df06e3e06e6ea7907d98b"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8158938cf3324172df024da511839d373c40fbfaa83e9abf467174b2910d7b4c"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:540ce6c4bf6b58cb0fd93fa5f143bc0ee341c93bb4f9287ccd92cf898cc1b0dd"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bfeaa1a699c6b9ed514bd15e6a91e74738b71125a9292159e3d6b7f0a53d2cde"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:01c8f00da537af711979e1b42a69a8ec9e1d7112f208e0e9b8a35d2c381085ef"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a0dd565f83b30f2ca79b5d35748d0d99dd4b3454f80e03dfb41f0038e3bdf180"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:023b6e5facda76989f4cba95a861b7e656b87e225f61811065d5c501f78cdb3f"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9633b663393d5796f0b60249549371e392b75a0b955c07e9c6f8708a87fc841f"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78dd8adfb48716233c45f676d6e48534d34b4bceb50162c13d1f0bdf6f78590a"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8e8deb16c4321d61ae72533b8451ec4a9af8656d1c61ff81aa49f966406e4b68"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:52452fa5999dc50c4decaf0c53aa28371f7f1e0fe5c2dd9129059fbe1e1599c7"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d5f23198821e227cfc52d50fa989813513db381255c6d100927b012f0cfec63d"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f4beb84b6073b1247a773141a6331117e35d07134b3bb0383003f39971d414bb"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:68814d599d25ed2fdd045ed54d370d1d03cf35e02dce56de44c651f828fb9b7b"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0b6453c54c57c1781292c46593f8a37254b8b99004c68d6c3ce229688931a22"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:adaa9c6dead67e2dd90d634f89131e43162012479d86e25618e821a03d1eb1dc"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73e7d408e9012cd17511b382b43547850969c7979efc2bc353f317abaf23c84c"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:775409ce0fcc58b10773fdb4221ed1eb007de10fe7adbdf8f5e8a56096b6f0bc"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:834001bed193e4440c4a3950a31059523ee5090605c907c66808664c932b549c"}, - {file = "safetensors-0.4.5.tar.gz", hash = "sha256:d73de19682deabb02524b3d5d1f8b3aaba94c72f1bbfc7911b9b9d5d391c0310"}, + {file = "safetensors-0.5.0-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:c683b9b485bee43422ba2855f72777c37647190281e03da4c8d2a69fa5336558"}, + {file = "safetensors-0.5.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:6106aa835deb7263f7014f74c05842ab828d6c11d789f2e7e98f26b1a305e72d"}, + {file = "safetensors-0.5.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1349611f74f55c5ee1c1c144c536a2743c38f7d8bf60b9fc8267e0efc0591a2"}, + {file = "safetensors-0.5.0-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:56d936028ac799e18644b08a91fd98b4b62ae3dcd0440b1cfcb56535785589f1"}, + {file = "safetensors-0.5.0-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2f26afada2233576ffea6b80042c2c0a8105c164254af56168ec14299ad3122"}, + {file = "safetensors-0.5.0-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20067e7a5e63f0cbc88457b2a1161e70ff73af4cc3a24bce90309430cd6f6e7e"}, + {file = "safetensors-0.5.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:649d6a4aa34d5174ae87289068ccc2fec2a1a998ecf83425aa5a42c3eff69bcf"}, + {file = "safetensors-0.5.0-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:debff88f41d569a3e93a955469f83864e432af35bb34b16f65a9ddf378daa3ae"}, + {file = "safetensors-0.5.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:bdf6a3e366ea8ba1a0538db6099229e95811194432c684ea28ea7ae28763b8dc"}, + {file = "safetensors-0.5.0-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:0371afd84c200a80eb7103bf715108b0c3846132fb82453ae018609a15551580"}, + {file = "safetensors-0.5.0-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:5ec7fc8c3d2f32ebf1c7011bc886b362e53ee0a1ec6d828c39d531fed8b325d6"}, + {file = "safetensors-0.5.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:53715e4ea0ef23c08f004baae0f609a7773de7d4148727760417c6760cfd6b76"}, + {file = "safetensors-0.5.0-cp38-abi3-win32.whl", hash = "sha256:b85565bc2f0456961a788d2f11d9d892eec46603db0e4923aa9512c2355aa727"}, + {file = "safetensors-0.5.0-cp38-abi3-win_amd64.whl", hash = "sha256:f451941f8aa11e7be5c3fa450e264609a2b1e65fa38ae590a74e55a94d646b76"}, + {file = "safetensors-0.5.0.tar.gz", hash = "sha256:c47b34c549fa1e0c655c4644da31332c61332c732c47c8dd9399347e9aac69d1"}, ] [package.extras] @@ -2462,7 +2369,7 @@ jax = ["flax (>=0.6.3)", "jax (>=0.3.25)", "jaxlib (>=0.3.25)", "safetensors[num mlx = ["mlx (>=0.0.9)"] numpy = ["numpy (>=1.21.6)"] paddlepaddle = ["paddlepaddle (>=2.4.1)", "safetensors[numpy]"] -pinned-tf = ["safetensors[numpy]", "tensorflow (==2.11.0)"] +pinned-tf = ["safetensors[numpy]", "tensorflow (==2.18.0)"] quality = ["black (==22.3)", "click (==8.0.4)", "flake8 (>=3.8.3)", "isort (>=5.5.4)"] tensorflow = ["safetensors[numpy]", "tensorflow (>=2.11.0)"] testing = ["h5py (>=3.7.0)", "huggingface-hub (>=0.12.1)", "hypothesis (>=6.70.2)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "safetensors[numpy]", "setuptools-rust (>=1.5.2)"] @@ -2470,33 +2377,33 @@ torch = ["safetensors[numpy]", "torch (>=1.10)"] [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -2711,20 +2618,21 @@ files = [ [[package]] name = "tqdm" -version = "4.66.5" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd"}, - {file = "tqdm-4.66.5.tar.gz", hash = "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -2934,13 +2842,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -2965,81 +2873,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [[package]] @@ -3055,13 +2958,13 @@ files = [ [[package]] name = "zipp" -version = "3.20.2" +version = "3.21.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"}, - {file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"}, + {file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"}, + {file = "zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4"}, ] [package.extras] diff --git a/airbyte-integrations/connectors/source-microsoft-onedrive/pyproject.toml b/airbyte-integrations/connectors/source-microsoft-onedrive/pyproject.toml index b3b60c10f1c3..231f1e073951 100644 --- a/airbyte-integrations/connectors/source-microsoft-onedrive/pyproject.toml +++ b/airbyte-integrations/connectors/source-microsoft-onedrive/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.2.22" +version = "0.2.28" name = "source-microsoft-onedrive" description = "Source implementation for Microsoft OneDrive." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-microsoft-onedrive/source_microsoft_onedrive/spec.py b/airbyte-integrations/connectors/source-microsoft-onedrive/source_microsoft_onedrive/spec.py index b5bc8890dacc..a94c5f3d02db 100644 --- a/airbyte-integrations/connectors/source-microsoft-onedrive/source_microsoft_onedrive/spec.py +++ b/airbyte-integrations/connectors/source-microsoft-onedrive/source_microsoft_onedrive/spec.py @@ -6,9 +6,10 @@ from typing import Any, Dict, Literal, Optional, Union import dpath.util -from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec from pydantic import BaseModel, Field +from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec + class OAuthCredentials(BaseModel): """ diff --git a/airbyte-integrations/connectors/source-microsoft-onedrive/source_microsoft_onedrive/stream_reader.py b/airbyte-integrations/connectors/source-microsoft-onedrive/source_microsoft_onedrive/stream_reader.py index b7c13534a3e5..2623fff2842f 100644 --- a/airbyte-integrations/connectors/source-microsoft-onedrive/source_microsoft_onedrive/stream_reader.py +++ b/airbyte-integrations/connectors/source-microsoft-onedrive/source_microsoft_onedrive/stream_reader.py @@ -11,12 +11,13 @@ import requests import smart_open -from airbyte_cdk import AirbyteTracedException, FailureType -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode -from airbyte_cdk.sources.file_based.remote_file import RemoteFile from msal import ConfidentialClientApplication from msal.exceptions import MsalServiceError from office365.graph_client import GraphClient + +from airbyte_cdk import AirbyteTracedException, FailureType +from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode +from airbyte_cdk.sources.file_based.remote_file import RemoteFile from source_microsoft_onedrive.spec import SourceMicrosoftOneDriveSpec diff --git a/airbyte-integrations/connectors/source-microsoft-sharepoint/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-microsoft-sharepoint/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-microsoft-sharepoint/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-microsoft-sharepoint/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-microsoft-sharepoint/main.py b/airbyte-integrations/connectors/source-microsoft-sharepoint/main.py index 4823f2652049..8c2d6ede5243 100644 --- a/airbyte-integrations/connectors/source-microsoft-sharepoint/main.py +++ b/airbyte-integrations/connectors/source-microsoft-sharepoint/main.py @@ -4,5 +4,6 @@ from source_microsoft_sharepoint.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-microsoft-sharepoint/source_microsoft_sharepoint/spec.py b/airbyte-integrations/connectors/source-microsoft-sharepoint/source_microsoft_sharepoint/spec.py index e1053a323696..c61196de4e47 100644 --- a/airbyte-integrations/connectors/source-microsoft-sharepoint/source_microsoft_sharepoint/spec.py +++ b/airbyte-integrations/connectors/source-microsoft-sharepoint/source_microsoft_sharepoint/spec.py @@ -6,9 +6,10 @@ from typing import Any, Dict, Literal, Optional, Union import dpath.util -from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec from pydantic.v1 import BaseModel, Field +from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec + class OAuthCredentials(BaseModel): """ diff --git a/airbyte-integrations/connectors/source-microsoft-sharepoint/source_microsoft_sharepoint/stream_reader.py b/airbyte-integrations/connectors/source-microsoft-sharepoint/source_microsoft_sharepoint/stream_reader.py index 8db55c5c6609..baab6f86505b 100644 --- a/airbyte-integrations/connectors/source-microsoft-sharepoint/source_microsoft_sharepoint/stream_reader.py +++ b/airbyte-integrations/connectors/source-microsoft-sharepoint/source_microsoft_sharepoint/stream_reader.py @@ -11,11 +11,12 @@ import requests import smart_open +from msal import ConfidentialClientApplication +from office365.graph_client import GraphClient + from airbyte_cdk import AirbyteTracedException, FailureType from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from msal import ConfidentialClientApplication -from office365.graph_client import GraphClient from source_microsoft_sharepoint.spec import SourceMicrosoftSharePointSpec from .utils import FolderNotFoundException, MicrosoftSharePointRemoteFile, execute_query_with_retry, filter_http_urls diff --git a/airbyte-integrations/connectors/source-microsoft-sharepoint/source_microsoft_sharepoint/utils.py b/airbyte-integrations/connectors/source-microsoft-sharepoint/source_microsoft_sharepoint/utils.py index 7a658c1b2431..a1741915978b 100644 --- a/airbyte-integrations/connectors/source-microsoft-sharepoint/source_microsoft_sharepoint/utils.py +++ b/airbyte-integrations/connectors/source-microsoft-sharepoint/source_microsoft_sharepoint/utils.py @@ -8,6 +8,7 @@ from airbyte_cdk import AirbyteTracedException, FailureType from airbyte_cdk.sources.file_based.remote_file import RemoteFile + LOGGER = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-microsoft-sharepoint/unit_tests/test_stream_reader.py b/airbyte-integrations/connectors/source-microsoft-sharepoint/unit_tests/test_stream_reader.py index 205e1399c52c..ee2d8a3e78b0 100644 --- a/airbyte-integrations/connectors/source-microsoft-sharepoint/unit_tests/test_stream_reader.py +++ b/airbyte-integrations/connectors/source-microsoft-sharepoint/unit_tests/test_stream_reader.py @@ -7,7 +7,6 @@ from unittest.mock import MagicMock, Mock, PropertyMock, call, patch import pytest -from airbyte_cdk import AirbyteTracedException from source_microsoft_sharepoint.spec import SourceMicrosoftSharePointSpec from source_microsoft_sharepoint.stream_reader import ( FileReadMode, @@ -17,6 +16,8 @@ ) from wcmatch.glob import GLOBSTAR, globmatch +from airbyte_cdk import AirbyteTracedException + def create_mock_drive_item(is_file, name, children=None): """Helper function to create a mock drive item.""" @@ -465,9 +466,10 @@ def test_get_shared_drive_object( ], ) def test_drives_property(auth_type, user_principal_name, has_refresh_token): - with patch("source_microsoft_sharepoint.stream_reader.execute_query_with_retry") as mock_execute_query, patch( - "source_microsoft_sharepoint.stream_reader.SourceMicrosoftSharePointStreamReader.one_drive_client" - ) as mock_one_drive_client: + with ( + patch("source_microsoft_sharepoint.stream_reader.execute_query_with_retry") as mock_execute_query, + patch("source_microsoft_sharepoint.stream_reader.SourceMicrosoftSharePointStreamReader.one_drive_client") as mock_one_drive_client, + ): refresh_token = "dummy_refresh_token" if has_refresh_token else None # Setup for different authentication types config_mock = MagicMock( diff --git a/airbyte-integrations/connectors/source-microsoft-sharepoint/unit_tests/test_utils.py b/airbyte-integrations/connectors/source-microsoft-sharepoint/unit_tests/test_utils.py index 5e88631a341f..f2eae51b2c76 100644 --- a/airbyte-integrations/connectors/source-microsoft-sharepoint/unit_tests/test_utils.py +++ b/airbyte-integrations/connectors/source-microsoft-sharepoint/unit_tests/test_utils.py @@ -6,9 +6,10 @@ from unittest.mock import Mock, patch import pytest -from airbyte_cdk import AirbyteTracedException from source_microsoft_sharepoint.utils import execute_query_with_retry, filter_http_urls +from airbyte_cdk import AirbyteTracedException + class MockResponse: def __init__(self, status_code, headers=None): @@ -49,9 +50,10 @@ def test_execute_query_with_retry(status_code, retry_after_header, expected_retr obj = Mock() obj.execute_query = Mock(side_effect=MockException(status_code, {"Retry-After": retry_after_header})) - with patch("source_microsoft_sharepoint.utils.time.sleep") as mock_sleep, patch( - "source_microsoft_sharepoint.utils.datetime" - ) as mock_datetime: + with ( + patch("source_microsoft_sharepoint.utils.time.sleep") as mock_sleep, + patch("source_microsoft_sharepoint.utils.datetime") as mock_datetime, + ): start_time = datetime(2021, 1, 1, 0, 0, 0) if retry_after_header: mock_datetime.now.side_effect = [start_time] * 2 + [ diff --git a/airbyte-integrations/connectors/source-microsoft-teams/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-microsoft-teams/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-microsoft-teams/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-microsoft-teams/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-miro/metadata.yaml b/airbyte-integrations/connectors/source-miro/metadata.yaml index 79bc19e378d6..2936adc70eed 100644 --- a/airbyte-integrations/connectors/source-miro/metadata.yaml +++ b/airbyte-integrations/connectors/source-miro/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-miro connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: f8276ae8-4ada-4ae5-819c-b1836aa78135 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-miro githubIssueLabel: source-miro icon: icon.svg diff --git a/airbyte-integrations/connectors/source-missive/metadata.yaml b/airbyte-integrations/connectors/source-missive/metadata.yaml index a1f6110a197c..0a1d93603643 100644 --- a/airbyte-integrations/connectors/source-missive/metadata.yaml +++ b/airbyte-integrations/connectors/source-missive/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-missive connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 740eadea-6f7a-49dc-a2e6-bdf935a79996 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-missive githubIssueLabel: source-missive icon: icon.svg diff --git a/airbyte-integrations/connectors/source-mixmax/metadata.yaml b/airbyte-integrations/connectors/source-mixmax/metadata.yaml index 80d24438c0f4..2640baae0bad 100644 --- a/airbyte-integrations/connectors/source-mixmax/metadata.yaml +++ b/airbyte-integrations/connectors/source-mixmax/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-mixmax connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 63df2e59-d086-4980-af83-01948325eacd - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.9 dockerRepository: airbyte/source-mixmax githubIssueLabel: source-mixmax icon: icon.svg diff --git a/airbyte-integrations/connectors/source-mixpanel/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-mixpanel/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-mixpanel/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-mixpanel/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-mixpanel/main.py b/airbyte-integrations/connectors/source-mixpanel/main.py index df8cb33fc826..b08271eca1ab 100644 --- a/airbyte-integrations/connectors/source-mixpanel/main.py +++ b/airbyte-integrations/connectors/source-mixpanel/main.py @@ -4,5 +4,6 @@ from source_mixpanel.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-mixpanel/metadata.yaml b/airbyte-integrations/connectors/source-mixpanel/metadata.yaml index b5c2ec9d3ac8..128405dd803b 100644 --- a/airbyte-integrations/connectors/source-mixpanel/metadata.yaml +++ b/airbyte-integrations/connectors/source-mixpanel/metadata.yaml @@ -7,11 +7,11 @@ data: - mixpanel.com - eu.mixpanel.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 12928b32-bf0a-4f1e-964f-07e12e37153a - dockerImageTag: 3.4.8 + dockerImageTag: 3.4.14 dockerRepository: airbyte/source-mixpanel documentationUrl: https://docs.airbyte.com/integrations/sources/mixpanel githubIssueLabel: source-mixpanel diff --git a/airbyte-integrations/connectors/source-mixpanel/poetry.lock b/airbyte-integrations/connectors/source-mixpanel/poetry.lock index 3fbb808a3933..47a018e45c80 100644 --- a/airbyte-integrations/connectors/source-mixpanel/poetry.lock +++ b/airbyte-integrations/connectors/source-mixpanel/poetry.lock @@ -69,24 +69,24 @@ files = [ [[package]] name = "anyio" -version = "4.6.0" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.0-py3-none-any.whl", hash = "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a"}, - {file = "anyio-4.6.0.tar.gz", hash = "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -101,19 +101,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -179,13 +179,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -269,127 +269,114 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -462,20 +449,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -525,13 +512,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -546,13 +533,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -560,7 +547,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -610,13 +596,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -717,90 +703,93 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.134" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.134-py3-none-any.whl", hash = "sha256:ada98ad80ef38807725f32441a472da3dd28394010877751f48f458d3289da04"}, - {file = "langsmith-0.1.134.tar.gz", hash = "sha256:23abee3b508875a0e63c602afafffc02442a19cfd88f9daae05b3e9054fd6b61"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" -version = "3.0.1" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" files = [ - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win32.whl", hash = "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win32.whl", hash = "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win32.whl", hash = "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win32.whl", hash = "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win32.whl", hash = "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b"}, - {file = "markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] @@ -830,68 +819,86 @@ twitter = ["twython"] [[package]] name = "orjson" -version = "3.10.7" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:74f4544f5a6405b90da8ea724d15ac9c36da4d72a738c64685003337401f5c12"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34a566f22c28222b08875b18b0dfbf8a947e69df21a9ed5c51a6bf91cfb944ac"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf6ba8ebc8ef5792e2337fb0419f8009729335bb400ece005606336b7fd7bab7"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac7cf6222b29fbda9e3a472b41e6a5538b48f2c8f99261eecd60aafbdb60690c"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de817e2f5fc75a9e7dd350c4b0f54617b280e26d1631811a43e7e968fa71e3e9"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:348bdd16b32556cf8d7257b17cf2bdb7ab7976af4af41ebe79f9796c218f7e91"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:479fd0844ddc3ca77e0fd99644c7fe2de8e8be1efcd57705b5c92e5186e8a250"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fdf5197a21dd660cf19dfd2a3ce79574588f8f5e2dbf21bda9ee2d2b46924d84"}, - {file = "orjson-3.10.7-cp310-none-win32.whl", hash = "sha256:d374d36726746c81a49f3ff8daa2898dccab6596864ebe43d50733275c629175"}, - {file = "orjson-3.10.7-cp310-none-win_amd64.whl", hash = "sha256:cb61938aec8b0ffb6eef484d480188a1777e67b05d58e41b435c74b9d84e0b9c"}, - {file = "orjson-3.10.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0"}, - {file = "orjson-3.10.7-cp311-none-win32.whl", hash = "sha256:82763b46053727a7168d29c772ed5c870fdae2f61aa8a25994c7984a19b1021f"}, - {file = "orjson-3.10.7-cp311-none-win_amd64.whl", hash = "sha256:eb8d384a24778abf29afb8e41d68fdd9a156cf6e5390c04cc07bbc24b89e98b5"}, - {file = "orjson-3.10.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44a96f2d4c3af51bfac6bc4ef7b182aa33f2f054fd7f34cc0ee9a320d051d41f"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ac14cd57df0572453543f8f2575e2d01ae9e790c21f57627803f5e79b0d3c3"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bdbb61dcc365dd9be94e8f7df91975edc9364d6a78c8f7adb69c1cdff318ec93"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b48b3db6bb6e0a08fa8c83b47bc169623f801e5cc4f24442ab2b6617da3b5313"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23820a1563a1d386414fef15c249040042b8e5d07b40ab3fe3efbfbbcbcb8864"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0c6a008e91d10a2564edbb6ee5069a9e66df3fbe11c9a005cb411f441fd2c09"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d352ee8ac1926d6193f602cbe36b1643bbd1bbcb25e3c1a657a4390f3000c9a5"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b"}, - {file = "orjson-3.10.7-cp312-none-win32.whl", hash = "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb"}, - {file = "orjson-3.10.7-cp312-none-win_amd64.whl", hash = "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1"}, - {file = "orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149"}, - {file = "orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad"}, - {file = "orjson-3.10.7-cp313-none-win32.whl", hash = "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2"}, - {file = "orjson-3.10.7-cp313-none-win_amd64.whl", hash = "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024"}, - {file = "orjson-3.10.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6ea2b2258eff652c82652d5e0f02bd5e0463a6a52abb78e49ac288827aaa1469"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:430ee4d85841e1483d487e7b81401785a5dfd69db5de01314538f31f8fbf7ee1"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b6146e439af4c2472c56f8540d799a67a81226e11992008cb47e1267a9b3225"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:084e537806b458911137f76097e53ce7bf5806dda33ddf6aaa66a028f8d43a23"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829cf2195838e3f93b70fd3b4292156fc5e097aac3739859ac0dcc722b27ac0"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1193b2416cbad1a769f868b1749535d5da47626ac29445803dae7cc64b3f5c98"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4e6c3da13e5a57e4b3dca2de059f243ebec705857522f188f0180ae88badd354"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c31008598424dfbe52ce8c5b47e0752dca918a4fdc4a2a32004efd9fab41d866"}, - {file = "orjson-3.10.7-cp38-none-win32.whl", hash = "sha256:7122a99831f9e7fe977dc45784d3b2edc821c172d545e6420c375e5a935f5a1c"}, - {file = "orjson-3.10.7-cp38-none-win_amd64.whl", hash = "sha256:a763bc0e58504cc803739e7df040685816145a6f3c8a589787084b54ebc9f16e"}, - {file = "orjson-3.10.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e76be12658a6fa376fcd331b1ea4e58f5a06fd0220653450f0d415b8fd0fbe20"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed350d6978d28b92939bfeb1a0570c523f6170efc3f0a0ef1f1df287cd4f4960"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144888c76f8520e39bfa121b31fd637e18d4cc2f115727865fdf9fa325b10412"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09b2d92fd95ad2402188cf51573acde57eb269eddabaa60f69ea0d733e789fe9"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b24a579123fa884f3a3caadaed7b75eb5715ee2b17ab5c66ac97d29b18fe57f"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591bcfe7512353bd609875ab38050efe3d55e18934e2f18950c108334b4ff"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f4db56635b58cd1a200b0a23744ff44206ee6aa428185e2b6c4a65b3197abdcd"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0fa5886854673222618638c6df7718ea7fe2f3f2384c452c9ccedc70b4a510a5"}, - {file = "orjson-3.10.7-cp39-none-win32.whl", hash = "sha256:8272527d08450ab16eb405f47e0f4ef0e5ff5981c3d82afe0efd25dcbef2bcd2"}, - {file = "orjson-3.10.7-cp39-none-win_amd64.whl", hash = "sha256:974683d4618c0c7dbf4f69c95a979734bf183d0658611760017f6e70a145af58"}, - {file = "orjson-3.10.7.tar.gz", hash = "sha256:75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -994,19 +1001,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1014,100 +1021,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -1115,13 +1133,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1327,105 +1345,105 @@ files = [ [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -1512,33 +1530,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.1.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"}, - {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1580,20 +1598,21 @@ files = [ [[package]] name = "tqdm" -version = "4.66.5" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd"}, - {file = "tqdm-4.66.5.tar.gz", hash = "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -1625,13 +1644,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1656,81 +1675,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-mixpanel/pyproject.toml b/airbyte-integrations/connectors/source-mixpanel/pyproject.toml index e873b304b0a1..7451acdec2d9 100644 --- a/airbyte-integrations/connectors/source-mixpanel/pyproject.toml +++ b/airbyte-integrations/connectors/source-mixpanel/pyproject.toml @@ -3,7 +3,7 @@ requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "3.4.8" +version = "3.4.14" name = "source-mixpanel" description = "Source implementation for Mixpanel." authors = ["Airbyte "] diff --git a/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/backoff_strategy.py b/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/backoff_strategy.py index 757909d1f8dc..838f3c1e1709 100644 --- a/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/backoff_strategy.py +++ b/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/backoff_strategy.py @@ -5,6 +5,7 @@ from typing import Any, Optional, Union import requests + from airbyte_cdk import BackoffStrategy from airbyte_cdk.sources.streams.http import HttpStream diff --git a/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/components.py b/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/components.py index 1730f7673647..9216c0cf7eaa 100644 --- a/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/components.py +++ b/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/components.py @@ -6,6 +6,7 @@ import dpath.util import requests + from airbyte_cdk.models import AirbyteMessage, SyncMode, Type from airbyte_cdk.sources.declarative.extractors import DpathExtractor from airbyte_cdk.sources.declarative.interpolation import InterpolatedString @@ -32,7 +33,6 @@ def get_request_headers( stream_slice: Optional[StreamSlice] = None, next_page_token: Optional[Mapping[str, Any]] = None, ) -> Mapping[str, Any]: - return {"Accept": "application/json"} def get_request_params( @@ -62,7 +62,6 @@ def _request_params( return super()._request_params(stream_state, stream_slice, next_page_token, extra_params) def send_request(self, **kwargs) -> Optional[requests.Response]: - if self.reqs_per_hour_limit: if self.is_first_request: self.is_first_request = False diff --git a/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/config_migrations.py b/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/config_migrations.py index 628cd46dcbda..06b61176db62 100644 --- a/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/config_migrations.py +++ b/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/config_migrations.py @@ -10,6 +10,7 @@ from airbyte_cdk.sources import Source from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository + logger = logging.getLogger("airbyte_logger") diff --git a/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/errors_handlers/base_errors_handler.py b/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/errors_handlers/base_errors_handler.py index a5d99f1566ae..815e24e61fa6 100644 --- a/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/errors_handlers/base_errors_handler.py +++ b/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/errors_handlers/base_errors_handler.py @@ -6,6 +6,7 @@ from typing import Optional, Union import requests + from airbyte_cdk.sources.streams.http import HttpStream from airbyte_cdk.sources.streams.http.error_handlers import ErrorResolution, HttpStatusErrorHandler, ResponseAction from airbyte_protocol.models import FailureType diff --git a/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/errors_handlers/export_errors_handler.py b/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/errors_handlers/export_errors_handler.py index 4ed3559f1af5..a47c2611854e 100644 --- a/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/errors_handlers/export_errors_handler.py +++ b/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/errors_handlers/export_errors_handler.py @@ -5,6 +5,7 @@ from typing import Optional, Union import requests + from airbyte_cdk.sources.streams.http import HttpStream from airbyte_cdk.sources.streams.http.error_handlers import ErrorResolution, HttpStatusErrorHandler, ResponseAction from airbyte_protocol.models import FailureType diff --git a/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/source.py b/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/source.py index 48a4184fbf42..1e5dccab2eeb 100644 --- a/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/source.py +++ b/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/source.py @@ -7,6 +7,7 @@ from typing import Any, List, Mapping, MutableMapping, Optional import pendulum + from airbyte_cdk.models import FailureType from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource from airbyte_cdk.sources.streams import Stream diff --git a/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/streams/base.py b/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/streams/base.py index 2d633492ddb1..c59258305abd 100644 --- a/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/streams/base.py +++ b/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/streams/base.py @@ -9,11 +9,12 @@ import pendulum import requests +from pendulum import Date +from requests.auth import AuthBase + from airbyte_cdk import BackoffStrategy from airbyte_cdk.sources.streams.http import HttpStream from airbyte_cdk.sources.streams.http.error_handlers import ErrorHandler -from pendulum import Date -from requests.auth import AuthBase from source_mixpanel.backoff_strategy import MixpanelStreamBackoffStrategy from source_mixpanel.errors_handlers import MixpanelStreamErrorHandler from source_mixpanel.utils import fix_date_time diff --git a/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/streams/export.py b/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/streams/export.py index e643b5836d43..ed3d202c98e7 100644 --- a/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/streams/export.py +++ b/airbyte-integrations/connectors/source-mixpanel/source_mixpanel/streams/export.py @@ -8,6 +8,7 @@ import pendulum import requests + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.streams.http.error_handlers import ErrorHandler from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer diff --git a/airbyte-integrations/connectors/source-mixpanel/unit_tests/conftest.py b/airbyte-integrations/connectors/source-mixpanel/unit_tests/conftest.py index 69c842e5e255..1df5c3b847c1 100644 --- a/airbyte-integrations/connectors/source-mixpanel/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-mixpanel/unit_tests/conftest.py @@ -45,12 +45,14 @@ def patch_time(mocker): ENV_REQUEST_CACHE_PATH = "REQUEST_CACHE_PATH" os.environ["REQUEST_CACHE_PATH"] = ENV_REQUEST_CACHE_PATH + def delete_cache_files(cache_directory): directory_path = Path(cache_directory) if directory_path.exists() and directory_path.is_dir(): for file_path in directory_path.glob("*.sqlite"): file_path.unlink() + @pytest.fixture(autouse=True) def clear_cache_before_each_test(): # The problem: Once the first request is cached, we will keep getting the cached result no matter what setup we prepared for a particular test. diff --git a/airbyte-integrations/connectors/source-mixpanel/unit_tests/test_migration.py b/airbyte-integrations/connectors/source-mixpanel/unit_tests/test_migration.py index a2132148baa2..57da922485ca 100644 --- a/airbyte-integrations/connectors/source-mixpanel/unit_tests/test_migration.py +++ b/airbyte-integrations/connectors/source-mixpanel/unit_tests/test_migration.py @@ -5,10 +5,12 @@ from unittest.mock import patch import pytest -from airbyte_cdk.entrypoint import AirbyteEntrypoint from source_mixpanel.config_migrations import MigrateProjectId from source_mixpanel.source import SourceMixpanel +from airbyte_cdk.entrypoint import AirbyteEntrypoint + + # Test data for parametrized test test_data = [ # Test when only api_secret is present diff --git a/airbyte-integrations/connectors/source-mixpanel/unit_tests/test_property_transformation.py b/airbyte-integrations/connectors/source-mixpanel/unit_tests/test_property_transformation.py index e1636caaef47..6a93ad167471 100644 --- a/airbyte-integrations/connectors/source-mixpanel/unit_tests/test_property_transformation.py +++ b/airbyte-integrations/connectors/source-mixpanel/unit_tests/test_property_transformation.py @@ -7,12 +7,14 @@ that will conflict in further data normalization, like: `userName` and `username` """ + from unittest.mock import MagicMock import pytest -from airbyte_cdk.models import SyncMode from source_mixpanel.streams import Export +from airbyte_cdk.models import SyncMode + from .utils import get_url_to_mock, setup_response diff --git a/airbyte-integrations/connectors/source-mixpanel/unit_tests/test_source.py b/airbyte-integrations/connectors/source-mixpanel/unit_tests/test_source.py index f877bdd99779..4471eaa511b3 100644 --- a/airbyte-integrations/connectors/source-mixpanel/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-mixpanel/unit_tests/test_source.py @@ -6,12 +6,14 @@ import logging import pytest -from airbyte_cdk.utils import AirbyteTracedException from source_mixpanel.source import SourceMixpanel, TokenAuthenticatorBase64 from source_mixpanel.streams import Export +from airbyte_cdk.utils import AirbyteTracedException + from .utils import command_check, get_url_to_mock, setup_response + logger = logging.getLogger("airbyte") @@ -22,12 +24,7 @@ def check_connection_url(config): return get_url_to_mock(export_stream) -@pytest.mark.parametrize( - "response_code,expect_success,response_json", - [ - (400, False, {"error": "Request error"}) - ] -) +@pytest.mark.parametrize("response_code,expect_success,response_json", [(400, False, {"error": "Request error"})]) def test_check_connection(requests_mock, check_connection_url, config_raw, response_code, expect_success, response_json): # requests_mock.register_uri("GET", check_connection_url, setup_response(response_code, response_json)) requests_mock.get("https://mixpanel.com/api/2.0/cohorts/list", status_code=response_code, json=response_json) @@ -135,7 +132,7 @@ def test_streams_string_date(requests_mock, config_raw): "select_properties_by_default": True, "region": "EU", "date_window_size": 10, - "page_size": 1000 + "page_size": 1000, }, True, None, @@ -143,9 +140,9 @@ def test_streams_string_date(requests_mock, config_raw): ), ) def test_config_validation(config, success, expected_error_message, requests_mock): - requests_mock.get("https://mixpanel.com/api/2.0/cohorts/list", status_code=200, json=[{'a': 1, 'created':'2021-02-11T00:00:00Z'}]) - requests_mock.get("https://mixpanel.com/api/2.0/cohorts/list", status_code=200, json=[{'a': 1, 'created':'2021-02-11T00:00:00Z'}]) - requests_mock.get("https://eu.mixpanel.com/api/2.0/cohorts/list", status_code=200, json=[{'a': 1, 'created':'2021-02-11T00:00:00Z'}]) + requests_mock.get("https://mixpanel.com/api/2.0/cohorts/list", status_code=200, json=[{"a": 1, "created": "2021-02-11T00:00:00Z"}]) + requests_mock.get("https://mixpanel.com/api/2.0/cohorts/list", status_code=200, json=[{"a": 1, "created": "2021-02-11T00:00:00Z"}]) + requests_mock.get("https://eu.mixpanel.com/api/2.0/cohorts/list", status_code=200, json=[{"a": 1, "created": "2021-02-11T00:00:00Z"}]) try: is_success, message = SourceMixpanel().check_connection(None, config) except AirbyteTracedException as e: diff --git a/airbyte-integrations/connectors/source-mixpanel/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-mixpanel/unit_tests/test_streams.py index 6f64dbf39aa5..9774037a6038 100644 --- a/airbyte-integrations/connectors/source-mixpanel/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-mixpanel/unit_tests/test_streams.py @@ -9,15 +9,17 @@ import pendulum import pytest -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.declarative.types import StreamSlice -from airbyte_cdk.utils import AirbyteTracedException from source_mixpanel import SourceMixpanel from source_mixpanel.streams import EngageSchema, Export, ExportSchema, IncrementalMixpanelStream, MixpanelStream from source_mixpanel.utils import read_full_refresh +from airbyte_cdk.models import SyncMode +from airbyte_cdk.sources.declarative.types import StreamSlice +from airbyte_cdk.utils import AirbyteTracedException + from .utils import get_url_to_mock, read_incremental, setup_response + logger = logging.getLogger("airbyte") MIXPANEL_BASE_URL = "https://mixpanel.com/api/2.0/" @@ -95,7 +97,7 @@ def cohorts_response(): ) -def init_stream(name='', config=None): +def init_stream(name="", config=None): streams = SourceMixpanel().streams(config) for stream in streams: if stream.name == name: @@ -104,10 +106,10 @@ def init_stream(name='', config=None): def test_cohorts_stream_incremental(requests_mock, cohorts_response, config_raw): """Filter 1 old value, 1 new record should be returned""" - config_raw['start_date'] = '2022-01-01T00:00:00Z' + config_raw["start_date"] = "2022-01-01T00:00:00Z" requests_mock.register_uri("GET", MIXPANEL_BASE_URL + "cohorts/list", cohorts_response) - cohorts_stream = init_stream('cohorts', config=config_raw) + cohorts_stream = init_stream("cohorts", config=config_raw) records = read_incremental(cohorts_stream, stream_state={"created": "2022-04-19 23:22:01"}, cursor_field=["created"]) @@ -158,25 +160,14 @@ def engage_response(): def test_engage_stream_incremental(requests_mock, engage_response, config_raw): """Filter 1 old value, 1 new record should be returned""" - engage_properties = { - "results": { - "$browser": { - "count": 124, - "type": "string" - }, - "$browser_version": { - "count": 124, - "type": "string" - } - } - } - config_raw['start_date'] = '2022-02-01T00:00:00Z' - config_raw['end_date'] = '2024-05-01T00:00:00Z' + engage_properties = {"results": {"$browser": {"count": 124, "type": "string"}, "$browser_version": {"count": 124, "type": "string"}}} + config_raw["start_date"] = "2022-02-01T00:00:00Z" + config_raw["end_date"] = "2024-05-01T00:00:00Z" requests_mock.register_uri("GET", MIXPANEL_BASE_URL + "engage/properties", json=engage_properties) requests_mock.register_uri("GET", MIXPANEL_BASE_URL + "engage?", engage_response) - stream = init_stream('engage', config=config_raw) + stream = init_stream("engage", config=config_raw) stream_state = {"last_seen": "2024-02-11T11:20:47"} records = list(read_incremental(stream, stream_state=stream_state, cursor_field=["last_seen"])) @@ -193,97 +184,97 @@ def test_engage_stream_incremental(requests_mock, engage_response, config_raw): {}, 2, { - 'states': [ + "states": [ { - 'cursor': {'last_seen': '2024-03-01T11:20:47'}, - 'partition': {'id': 1111, 'parent_slice': {}}, + "cursor": {"last_seen": "2024-03-01T11:20:47"}, + "partition": {"id": 1111, "parent_slice": {}}, } ] - } + }, ), ( "abnormal_state", { - 'states': [ + "states": [ { - 'cursor': {'last_seen': '2030-01-01T00:00:00'}, - 'partition': {'id': 1111, 'parent_slice': {}}, + "cursor": {"last_seen": "2030-01-01T00:00:00"}, + "partition": {"id": 1111, "parent_slice": {}}, } ] }, 0, { - 'states': [ + "states": [ { - 'cursor': {'last_seen': '2030-01-01T00:00:00'}, - 'partition': {'id': 1111, 'parent_slice': {}}, + "cursor": {"last_seen": "2030-01-01T00:00:00"}, + "partition": {"id": 1111, "parent_slice": {}}, } ] - } + }, ), ( "medium_state", { - 'states': [ + "states": [ { - 'cursor': {'last_seen': '2024-03-01T11:20:00'}, - 'partition': {'id': 1111, 'parent_slice': {}}, + "cursor": {"last_seen": "2024-03-01T11:20:00"}, + "partition": {"id": 1111, "parent_slice": {}}, } ] }, 1, { - 'states': [ + "states": [ { - 'cursor': {'last_seen': '2024-03-01T11:20:47'}, - 'partition': {'id': 1111, 'parent_slice': {}}, + "cursor": {"last_seen": "2024-03-01T11:20:47"}, + "partition": {"id": 1111, "parent_slice": {}}, } ] - } + }, ), ( "early_state", { - 'states': [ + "states": [ { - 'cursor': {'last_seen': '2024-02-01T00:00:00'}, - 'partition': {'id': 1111, 'parent_slice': {}}, + "cursor": {"last_seen": "2024-02-01T00:00:00"}, + "partition": {"id": 1111, "parent_slice": {}}, } ] }, 2, { - 'states': [ + "states": [ { - 'cursor': {'last_seen': '2024-03-01T11:20:47'}, - 'partition': {'id': 1111, 'parent_slice': {}}, + "cursor": {"last_seen": "2024-03-01T11:20:47"}, + "partition": {"id": 1111, "parent_slice": {}}, } ] - } + }, ), ( "state_for_different_partition", { - 'states': [ + "states": [ { - 'cursor': {'last_seen': '2024-02-01T00:00:00'}, - 'partition': {'id': 2222, 'parent_slice': {}}, + "cursor": {"last_seen": "2024-02-01T00:00:00"}, + "partition": {"id": 2222, "parent_slice": {}}, } ] }, 2, { - 'states': [ + "states": [ { - 'cursor': {'last_seen': '2024-02-01T00:00:00'}, - 'partition': {'id': 2222, 'parent_slice': {}}, + "cursor": {"last_seen": "2024-02-01T00:00:00"}, + "partition": {"id": 2222, "parent_slice": {}}, }, { - 'cursor': {'last_seen': '2024-03-01T11:20:47'}, - 'partition': {'id': 1111, 'parent_slice': {}}, - } + "cursor": {"last_seen": "2024-03-01T11:20:47"}, + "partition": {"id": 1111, "parent_slice": {}}, + }, ] - } + }, ), ), ) @@ -291,26 +282,17 @@ def test_cohort_members_stream_incremental(requests_mock, engage_response, confi """Cohort_members stream has legacy state but actually it should always return all records because members in cohorts can be updated at any time """ - engage_properties = { - "results": { - "$browser": { - "count": 124, - "type": "string" - }, - "$browser_version": { - "count": 124, - "type": "string" - } - } - } - config_raw['start_date'] = '2024-02-01T00:00:00Z' - config_raw['end_date'] = '2024-03-01T00:00:00Z' + engage_properties = {"results": {"$browser": {"count": 124, "type": "string"}, "$browser_version": {"count": 124, "type": "string"}}} + config_raw["start_date"] = "2024-02-01T00:00:00Z" + config_raw["end_date"] = "2024-03-01T00:00:00Z" - requests_mock.register_uri("GET", MIXPANEL_BASE_URL + "cohorts/list", json=[{'id': 1111, "name":'bla', 'created': '2024-02-02T00:00:00Z'}]) + requests_mock.register_uri( + "GET", MIXPANEL_BASE_URL + "cohorts/list", json=[{"id": 1111, "name": "bla", "created": "2024-02-02T00:00:00Z"}] + ) requests_mock.register_uri("GET", MIXPANEL_BASE_URL + "engage/properties", json=engage_properties) requests_mock.register_uri("POST", MIXPANEL_BASE_URL + "engage?", engage_response) - stream = init_stream('cohort_members', config=config_raw) + stream = init_stream("cohort_members", config=config_raw) records = list(read_incremental(stream, stream_state=state, cursor_field=["last_seen"])) @@ -321,99 +303,85 @@ def test_cohort_members_stream_incremental(requests_mock, engage_response, confi def test_cohort_members_stream_pagination(requests_mock, engage_response, config_raw): """Cohort_members pagination""" - engage_properties = { - "results": { - "$browser": { - "count": 124, - "type": "string" - }, - "$browser_version": { - "count": 124, - "type": "string" - } - } - } - config_raw['start_date'] = '2024-02-01T00:00:00Z' - config_raw['end_date'] = '2024-03-01T00:00:00Z' - - requests_mock.register_uri("GET", MIXPANEL_BASE_URL + "cohorts/list", json=[ - {'id': 71000, "name":'bla', 'created': '2024-02-01T00:00:00Z'}, - {'id': 71111, "name":'bla', 'created': '2024-02-02T00:00:00Z'}, - {'id': 72222, "name":'bla', 'created': '2024-02-01T00:00:00Z'}, - {'id': 73333, "name":'bla', 'created': '2024-02-03T00:00:00Z'}, - ]) - requests_mock.register_uri("GET", MIXPANEL_BASE_URL + "engage/properties", json=engage_properties) - requests_mock.register_uri("POST", MIXPANEL_BASE_URL + "engage", [ - { # initial request for 71000 cohort - 'status_code': 200, - 'json': { - "page": 0, - "page_size": 1000, - "session_id": "1234567890", - "status": "ok", - "total": 0, - "results": [] - } - }, - { # initial request for 71111 cohort and further pagination - 'status_code': 200, - 'json': { - "page": 0, - "page_size": 1000, - "session_id": "1234567890", - "status": "ok", - "total": 2002, - "results": [ - { - "$distinct_id": "71111_1", - "$properties": { - "$created": "2024-03-01T11:20:47", - "$last_seen": "2024-03-01T11:20:47", + engage_properties = {"results": {"$browser": {"count": 124, "type": "string"}, "$browser_version": {"count": 124, "type": "string"}}} + config_raw["start_date"] = "2024-02-01T00:00:00Z" + config_raw["end_date"] = "2024-03-01T00:00:00Z" + requests_mock.register_uri( + "GET", + MIXPANEL_BASE_URL + "cohorts/list", + json=[ + {"id": 71000, "name": "bla", "created": "2024-02-01T00:00:00Z"}, + {"id": 71111, "name": "bla", "created": "2024-02-02T00:00:00Z"}, + {"id": 72222, "name": "bla", "created": "2024-02-01T00:00:00Z"}, + {"id": 73333, "name": "bla", "created": "2024-02-03T00:00:00Z"}, + ], + ) + requests_mock.register_uri("GET", MIXPANEL_BASE_URL + "engage/properties", json=engage_properties) + requests_mock.register_uri( + "POST", + MIXPANEL_BASE_URL + "engage", + [ + { # initial request for 71000 cohort + "status_code": 200, + "json": {"page": 0, "page_size": 1000, "session_id": "1234567890", "status": "ok", "total": 0, "results": []}, + }, + { # initial request for 71111 cohort and further pagination + "status_code": 200, + "json": { + "page": 0, + "page_size": 1000, + "session_id": "1234567890", + "status": "ok", + "total": 2002, + "results": [ + { + "$distinct_id": "71111_1", + "$properties": { + "$created": "2024-03-01T11:20:47", + "$last_seen": "2024-03-01T11:20:47", + }, }, - }, - { - "$distinct_id": "71111_2", - "$properties": { - "$created": "2024-02-01T11:20:47", - "$last_seen": "2024-02-01T11:20:47", - } - } - ] - } - }, { # initial request for 72222 cohort without further pagination - 'status_code': 200, - 'json': { - "page": 0, - "page_size": 1000, - "session_id": "1234567890", - "status": "ok", - "total": 1, - "results": [ - { - "$distinct_id": "72222_1", - "$properties": { - "$created": "2024-02-01T11:20:47", - "$last_seen": "2024-02-01T11:20:47", + { + "$distinct_id": "71111_2", + "$properties": { + "$created": "2024-02-01T11:20:47", + "$last_seen": "2024-02-01T11:20:47", + }, + }, + ], + }, + }, + { # initial request for 72222 cohort without further pagination + "status_code": 200, + "json": { + "page": 0, + "page_size": 1000, + "session_id": "1234567890", + "status": "ok", + "total": 1, + "results": [ + { + "$distinct_id": "72222_1", + "$properties": { + "$created": "2024-02-01T11:20:47", + "$last_seen": "2024-02-01T11:20:47", + }, } - } - ] - } - },{ # initial request for 73333 cohort - 'status_code': 200, - 'json': { - "page": 0, - "page_size": 1000, - "session_id": "1234567890", - "status": "ok", - "total": 0, - "results": [] - } - } - ] + ], + }, + }, + { # initial request for 73333 cohort + "status_code": 200, + "json": {"page": 0, "page_size": 1000, "session_id": "1234567890", "status": "ok", "total": 0, "results": []}, + }, + ], ) # request for 1 page for 71111 cohort - requests_mock.register_uri("POST", MIXPANEL_BASE_URL + "engage?page_size=1000&session_id=1234567890&page=1", json={ + requests_mock.register_uri( + "POST", + MIXPANEL_BASE_URL + "engage?page_size=1000&session_id=1234567890&page=1", + json={ "page": 1, "session_id": "1234567890", "status": "ok", @@ -423,13 +391,16 @@ def test_cohort_members_stream_pagination(requests_mock, engage_response, config "$properties": { "$created": "2024-02-01T11:20:47", "$last_seen": "2024-02-01T11:20:47", - } + }, } - ] - } + ], + }, ) # request for 2 page for 71111 cohort - requests_mock.register_uri("POST", MIXPANEL_BASE_URL + "engage?page_size=1000&session_id=1234567890&page=2", json={ + requests_mock.register_uri( + "POST", + MIXPANEL_BASE_URL + "engage?page_size=1000&session_id=1234567890&page=2", + json={ "page": 2, "session_id": "1234567890", "status": "ok", @@ -439,27 +410,23 @@ def test_cohort_members_stream_pagination(requests_mock, engage_response, config "$properties": { "$created": "2024-02-01T11:20:47", "$last_seen": "2024-02-01T11:20:47", - } + }, } - ] - } + ], + }, ) - stream = init_stream('cohort_members', config=config_raw) - + stream = init_stream("cohort_members", config=config_raw) + records = list(read_incremental(stream, stream_state={}, cursor_field=["last_seen"])) assert len(records) == 5 new_updated_state = stream.get_updated_state(current_stream_state={}, latest_record=records[-1] if records else None) - assert new_updated_state == {'states': [ - { - 'cursor': {'last_seen': '2024-03-01T11:20:47'}, - 'partition': {'id': 71111, 'parent_slice': {}} - }, - { - 'cursor': {'last_seen': '2024-02-01T11:20:47'}, - 'partition': {'id': 72222, 'parent_slice': {}} - } - ]} + assert new_updated_state == { + "states": [ + {"cursor": {"last_seen": "2024-03-01T11:20:47"}, "partition": {"id": 71111, "parent_slice": {}}}, + {"cursor": {"last_seen": "2024-02-01T11:20:47"}, "partition": {"id": 72222, "parent_slice": {}}}, + ] + } @pytest.fixture @@ -493,37 +460,30 @@ def funnels_response(start_date): }, ) + @pytest.fixture def funnel_ids_response(start_date): - return setup_response( - 200, - [{ - "funnel_id": 36152117, - "name": "test" - }] - ) + return setup_response(200, [{"funnel_id": 36152117, "name": "test"}]) def test_funnels_stream(requests_mock, config, funnels_response, funnel_ids_response, config_raw): config_raw["start_date"] = "2024-01-01T00:00:00Z" config_raw["end_date"] = "2024-04-01T00:00:00Z" - stream = init_stream('funnels', config=config_raw) + stream = init_stream("funnels", config=config_raw) requests_mock.register_uri("GET", MIXPANEL_BASE_URL + "funnels/list", funnel_ids_response) requests_mock.register_uri("GET", MIXPANEL_BASE_URL + "funnels", funnels_response) stream_slices = list(stream.stream_slices(sync_mode=SyncMode.incremental)) assert len(stream_slices) > 3 - assert { - "funnel_id": stream_slices[0]['funnel_id'], - "name": stream_slices[0]['funnel_name'] - } == { + assert {"funnel_id": stream_slices[0]["funnel_id"], "name": stream_slices[0]["funnel_name"]} == { "funnel_id": "36152117", - "name": "test" + "name": "test", } records = stream.read_records(sync_mode=SyncMode.full_refresh, stream_slice=stream_slices[0]) records = list(records) assert len(records) == 2 + @pytest.fixture def engage_schema_response(): return setup_response( @@ -552,7 +512,7 @@ def _minimize_schema(fill_schema, schema_original): def test_engage_schema(requests_mock, engage_schema_response, config_raw): - stream = init_stream('engage', config=config_raw) + stream = init_stream("engage", config=config_raw) requests_mock.register_uri("GET", get_url_to_mock(EngageSchema(authenticator=MagicMock(), **config_raw)), engage_schema_response) type_schema = {} _minimize_schema(type_schema, stream.get_json_schema()) @@ -600,7 +560,7 @@ def test_update_engage_schema(requests_mock, config, config_raw): }, ), ) - engage_stream = init_stream('engage', config=config_raw) + engage_stream = init_stream("engage", config=config_raw) engage_schema = engage_stream.get_json_schema() assert "someNewSchemaField" in engage_schema["properties"] @@ -619,13 +579,10 @@ def annotations_response(): def test_annotations_stream(requests_mock, annotations_response, config_raw): - stream = init_stream('annotations', config=config_raw) + stream = init_stream("annotations", config=config_raw) requests_mock.register_uri("GET", "https://mixpanel.com/api/2.0/annotations", annotations_response) - stream_slice = StreamSlice(partition={}, cursor_slice= { - "start_time": "2021-01-25", - "end_time": "2021-07-25" - }) + stream_slice = StreamSlice(partition={}, cursor_slice={"start_time": "2021-01-25", "end_time": "2021-07-25"}) # read records for single slice records = stream.read_records(sync_mode=SyncMode.full_refresh, stream_slice=stream_slice) records = list(records) @@ -648,14 +605,12 @@ def revenue_response(): "status": "ok", }, ) -def test_revenue_stream(requests_mock, revenue_response, config_raw): - stream = init_stream('revenue', config=config_raw) + +def test_revenue_stream(requests_mock, revenue_response, config_raw): + stream = init_stream("revenue", config=config_raw) requests_mock.register_uri("GET", "https://mixpanel.com/api/2.0/engage/revenue", revenue_response) - stream_slice = StreamSlice(partition={}, cursor_slice= { - "start_time": "2021-01-25", - "end_time": "2021-07-25" - }) + stream_slice = StreamSlice(partition={}, cursor_slice={"start_time": "2021-01-25", "end_time": "2021-07-25"}) # read records for single slice records = stream.read_records(sync_mode=SyncMode.full_refresh, stream_slice=stream_slice) records = list(records) @@ -675,7 +630,6 @@ def export_schema_response(): def test_export_schema(requests_mock, export_schema_response, config): - stream = ExportSchema(authenticator=MagicMock(), **config) requests_mock.register_uri("GET", get_url_to_mock(stream), export_schema_response) @@ -684,14 +638,14 @@ def test_export_schema(requests_mock, export_schema_response, config): records_length = sum(1 for _ in records) assert records_length == 2 -def test_export_get_json_schema(requests_mock, export_schema_response, config): +def test_export_get_json_schema(requests_mock, export_schema_response, config): requests_mock.register_uri("GET", "https://mixpanel.com/api/2.0/events/properties/top", export_schema_response) stream = Export(authenticator=MagicMock(), **config) schema = stream.get_json_schema() - assert "DYNAMIC_FIELD" in schema['properties'] + assert "DYNAMIC_FIELD" in schema["properties"] @pytest.fixture @@ -717,7 +671,6 @@ def export_response(): def test_export_stream(requests_mock, export_response, config): - stream = Export(authenticator=MagicMock(), **config) requests_mock.register_uri("GET", get_url_to_mock(stream), export_response) @@ -728,8 +681,8 @@ def test_export_stream(requests_mock, export_response, config): records_length = sum(1 for _ in records) assert records_length == 1 -def test_export_stream_fail(requests_mock, export_response, config): +def test_export_stream_fail(requests_mock, export_response, config): stream = Export(authenticator=MagicMock(), **config) error_message = "" requests_mock.register_uri("GET", get_url_to_mock(stream), status_code=400, text="Unable to authenticate request") diff --git a/airbyte-integrations/connectors/source-mixpanel/unit_tests/unit_test.py b/airbyte-integrations/connectors/source-mixpanel/unit_tests/unit_test.py index 1762aa42c718..3eeff0eac9fd 100644 --- a/airbyte-integrations/connectors/source-mixpanel/unit_tests/unit_test.py +++ b/airbyte-integrations/connectors/source-mixpanel/unit_tests/unit_test.py @@ -9,7 +9,6 @@ def test_date_slices(): - now = pendulum.today(tz="US/Pacific").date() # test with stream_state diff --git a/airbyte-integrations/connectors/source-mixpanel/unit_tests/utils.py b/airbyte-integrations/connectors/source-mixpanel/unit_tests/utils.py index 5b08cd789244..4c2903b76df9 100644 --- a/airbyte-integrations/connectors/source-mixpanel/unit_tests/utils.py +++ b/airbyte-integrations/connectors/source-mixpanel/unit_tests/utils.py @@ -35,7 +35,9 @@ def read_incremental(stream_instance: Stream, stream_state: MutableMapping[str, stream_instance.state = stream_state slices = stream_instance.stream_slices(sync_mode=SyncMode.incremental, cursor_field=cursor_field, stream_state=stream_state) for slice in slices: - records = stream_instance.read_records(sync_mode=SyncMode.incremental, cursor_field=cursor_field, stream_slice=slice, stream_state=stream_state) + records = stream_instance.read_records( + sync_mode=SyncMode.incremental, cursor_field=cursor_field, stream_slice=slice, stream_state=stream_state + ) for record in records: stream_state = stream_instance.get_updated_state(stream_state, record) res.append(record) diff --git a/airbyte-integrations/connectors/source-mode/metadata.yaml b/airbyte-integrations/connectors/source-mode/metadata.yaml index 5055f32f1afc..950914b53a8a 100644 --- a/airbyte-integrations/connectors/source-mode/metadata.yaml +++ b/airbyte-integrations/connectors/source-mode/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-mode connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.13.0@sha256:ffc5977f59e1f38bf3f5dd70b6fa0520c2450ebf85153c5a8df315b8c918d5c3 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 948f3a37-f80b-4f57-a918-9fd733f7a018 - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-mode githubIssueLabel: source-mode icon: icon.svg diff --git a/airbyte-integrations/connectors/source-monday/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-monday/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-monday/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-monday/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-monday/main.py b/airbyte-integrations/connectors/source-monday/main.py index 14f4fa2d0439..68776ccfc1f5 100644 --- a/airbyte-integrations/connectors/source-monday/main.py +++ b/airbyte-integrations/connectors/source-monday/main.py @@ -4,5 +4,6 @@ from source_monday.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-monday/metadata.yaml b/airbyte-integrations/connectors/source-monday/metadata.yaml index d962682ecb11..331984802b93 100644 --- a/airbyte-integrations/connectors/source-monday/metadata.yaml +++ b/airbyte-integrations/connectors/source-monday/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - api.monday.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:1.2.2@sha256:57703de3b4c4204bd68a7b13c9300f8e03c0189bffddaffc796f1da25d2dbea0 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 80a54ea2-9959-4040-aac1-eee42423ec9b - dockerImageTag: 2.1.4 + dockerImageTag: 2.1.8 releases: breakingChanges: 2.0.0: diff --git a/airbyte-integrations/connectors/source-monday/poetry.lock b/airbyte-integrations/connectors/source-monday/poetry.lock index 0d28dc06353e..a2d62115446c 100644 --- a/airbyte-integrations/connectors/source-monday/poetry.lock +++ b/airbyte-integrations/connectors/source-monday/poetry.lock @@ -62,22 +62,22 @@ files = [ [[package]] name = "attrs" -version = "23.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, - {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] -tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "backoff" @@ -92,35 +92,35 @@ files = [ [[package]] name = "bracex" -version = "2.4" +version = "2.5.post1" description = "Bash style brace expander." optional = false python-versions = ">=3.8" files = [ - {file = "bracex-2.4-py3-none-any.whl", hash = "sha256:efdc71eff95eaff5e0f8cfebe7d01adf2c8637c8c92edaf63ef348c241a82418"}, - {file = "bracex-2.4.tar.gz", hash = "sha256:a27eaf1df42cf561fed58b7a8f3fdf129d1ea16a81e1fadd1d17989bc6384beb"}, + {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, + {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, ] [[package]] name = "cachetools" -version = "5.3.3" +version = "5.5.0" description = "Extensible memoizing collections and decorators" optional = false python-versions = ">=3.7" files = [ - {file = "cachetools-5.3.3-py3-none-any.whl", hash = "sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945"}, - {file = "cachetools-5.3.3.tar.gz", hash = "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"}, + {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, + {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, ] [[package]] name = "cattrs" -version = "23.2.3" +version = "24.1.2" description = "Composable complex class support for attrs and dataclasses." optional = false python-versions = ">=3.8" files = [ - {file = "cattrs-23.2.3-py3-none-any.whl", hash = "sha256:0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108"}, - {file = "cattrs-23.2.3.tar.gz", hash = "sha256:a934090d95abaa9e911dac357e3a8699e0b4b14f8529bcc7d2b1ad9d51672b9f"}, + {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, + {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, ] [package.dependencies] @@ -132,6 +132,7 @@ typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_ver bson = ["pymongo (>=4.4.0)"] cbor2 = ["cbor2 (>=5.4.6)"] msgpack = ["msgpack (>=1.0.5)"] +msgspec = ["msgspec (>=0.18.5)"] orjson = ["orjson (>=3.9.2)"] pyyaml = ["pyyaml (>=6.0)"] tomlkit = ["tomlkit (>=0.11.8)"] @@ -139,112 +140,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.2.2" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, - {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.3.2" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -260,20 +263,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -288,13 +291,13 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.2.0" +version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, - {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, ] [package.extras] @@ -312,15 +315,18 @@ files = [ [[package]] name = "idna" -version = "3.6" +version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, - {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, ] +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -348,13 +354,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.3" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, - {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -397,82 +403,83 @@ format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-va [[package]] name = "markupsafe" -version = "2.1.5" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] name = "packaging" -version = "24.0" +version = "24.2" description = "Core utilities for Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -511,28 +518,29 @@ pytzdata = ">=2020.1" [[package]] name = "platformdirs" -version = "4.2.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +version = "4.3.6" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, - {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "pluggy" -version = "1.4.0" +version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" files = [ - {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, - {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] [package.extras] @@ -552,47 +560,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.14" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.14-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f4fcec873f90537c382840f330b90f4715eebc2bc9925f04cb92de593eae054"}, - {file = "pydantic-1.10.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e3a76f571970fcd3c43ad982daf936ae39b3e90b8a2e96c04113a369869dc87"}, - {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d886bd3c3fbeaa963692ef6b643159ccb4b4cefaf7ff1617720cbead04fd1d"}, - {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:798a3d05ee3b71967844a1164fd5bdb8c22c6d674f26274e78b9f29d81770c4e"}, - {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:23d47a4b57a38e8652bcab15a658fdb13c785b9ce217cc3a729504ab4e1d6bc9"}, - {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f9f674b5c3bebc2eba401de64f29948ae1e646ba2735f884d1594c5f675d6f2a"}, - {file = "pydantic-1.10.14-cp310-cp310-win_amd64.whl", hash = "sha256:24a7679fab2e0eeedb5a8924fc4a694b3bcaac7d305aeeac72dd7d4e05ecbebf"}, - {file = "pydantic-1.10.14-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d578ac4bf7fdf10ce14caba6f734c178379bd35c486c6deb6f49006e1ba78a7"}, - {file = "pydantic-1.10.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa7790e94c60f809c95602a26d906eba01a0abee9cc24150e4ce2189352deb1b"}, - {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad4e10efa5474ed1a611b6d7f0d130f4aafadceb73c11d9e72823e8f508e663"}, - {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1245f4f61f467cb3dfeced2b119afef3db386aec3d24a22a1de08c65038b255f"}, - {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:21efacc678a11114c765eb52ec0db62edffa89e9a562a94cbf8fa10b5db5c046"}, - {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:412ab4a3f6dbd2bf18aefa9f79c7cca23744846b31f1d6555c2ee2b05a2e14ca"}, - {file = "pydantic-1.10.14-cp311-cp311-win_amd64.whl", hash = "sha256:e897c9f35281f7889873a3e6d6b69aa1447ceb024e8495a5f0d02ecd17742a7f"}, - {file = "pydantic-1.10.14-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d604be0f0b44d473e54fdcb12302495fe0467c56509a2f80483476f3ba92b33c"}, - {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42c7d17706911199798d4c464b352e640cab4351efe69c2267823d619a937e5"}, - {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:596f12a1085e38dbda5cbb874d0973303e34227b400b6414782bf205cc14940c"}, - {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bfb113860e9288d0886e3b9e49d9cf4a9d48b441f52ded7d96db7819028514cc"}, - {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bc3ed06ab13660b565eed80887fcfbc0070f0aa0691fbb351657041d3e874efe"}, - {file = "pydantic-1.10.14-cp37-cp37m-win_amd64.whl", hash = "sha256:ad8c2bc677ae5f6dbd3cf92f2c7dc613507eafe8f71719727cbc0a7dec9a8c01"}, - {file = "pydantic-1.10.14-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c37c28449752bb1f47975d22ef2882d70513c546f8f37201e0fec3a97b816eee"}, - {file = "pydantic-1.10.14-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49a46a0994dd551ec051986806122767cf144b9702e31d47f6d493c336462597"}, - {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53e3819bd20a42470d6dd0fe7fc1c121c92247bca104ce608e609b59bc7a77ee"}, - {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbb503bbbbab0c588ed3cd21975a1d0d4163b87e360fec17a792f7d8c4ff29f"}, - {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:336709883c15c050b9c55a63d6c7ff09be883dbc17805d2b063395dd9d9d0022"}, - {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4ae57b4d8e3312d486e2498d42aed3ece7b51848336964e43abbf9671584e67f"}, - {file = "pydantic-1.10.14-cp38-cp38-win_amd64.whl", hash = "sha256:dba49d52500c35cfec0b28aa8b3ea5c37c9df183ffc7210b10ff2a415c125c4a"}, - {file = "pydantic-1.10.14-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c66609e138c31cba607d8e2a7b6a5dc38979a06c900815495b2d90ce6ded35b4"}, - {file = "pydantic-1.10.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d986e115e0b39604b9eee3507987368ff8148222da213cd38c359f6f57b3b347"}, - {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:646b2b12df4295b4c3148850c85bff29ef6d0d9621a8d091e98094871a62e5c7"}, - {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282613a5969c47c83a8710cc8bfd1e70c9223feb76566f74683af889faadc0ea"}, - {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:466669501d08ad8eb3c4fecd991c5e793c4e0bbd62299d05111d4f827cded64f"}, - {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:13e86a19dca96373dcf3190fcb8797d40a6f12f154a244a8d1e8e03b8f280593"}, - {file = "pydantic-1.10.14-cp39-cp39-win_amd64.whl", hash = "sha256:08b6ec0917c30861e3fe71a93be1648a2aa4f62f866142ba21670b24444d7fd8"}, - {file = "pydantic-1.10.14-py3-none-any.whl", hash = "sha256:8ee853cd12ac2ddbf0ecbac1c289f95882b2d4482258048079d13be700aa114c"}, - {file = "pydantic-1.10.14.tar.gz", hash = "sha256:46f17b832fe27de7850896f3afee50ea682220dd218f7e9c88d436788419dca6"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -726,73 +741,75 @@ files = [ [[package]] name = "pyyaml" -version = "6.0.1" +version = "6.0.2" description = "YAML parser and emitter for Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] [[package]] name = "requests" -version = "2.31.0" +version = "2.32.3" description = "Python HTTP for Humans." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, ] [package.dependencies] @@ -807,13 +824,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "requests-cache" -version = "1.2.0" +version = "1.2.1" description = "A persistent cache for python requests" optional = false python-versions = ">=3.8" files = [ - {file = "requests_cache-1.2.0-py3-none-any.whl", hash = "sha256:490324301bf0cb924ff4e6324bd2613453e7e1f847353928b08adb0fdfb7f722"}, - {file = "requests_cache-1.2.0.tar.gz", hash = "sha256:db1c709ca343cc1cd5b6c8b1a5387298eceed02306a6040760db538c885e3838"}, + {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, + {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, ] [package.dependencies] @@ -854,29 +871,33 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "69.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-69.2.0-py3-none-any.whl", hash = "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c"}, - {file = "setuptools-69.2.0.tar.gz", hash = "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -892,13 +913,13 @@ files = [ [[package]] name = "typing-extensions" -version = "4.10.0" +version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, - {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] @@ -917,13 +938,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.1" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -948,84 +969,79 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] lock-version = "2.0" python-versions = "^3.9,<3.12" -content-hash = "25d79195c052c9654e64e6cd73809188b3aa16bd228841f214ff871a895c9c6c" +content-hash = "b931aa8394be53c1e721dccc0fc632c1d8890cf907cbad0ae7ceea8e89a6a9cb" diff --git a/airbyte-integrations/connectors/source-monday/pyproject.toml b/airbyte-integrations/connectors/source-monday/pyproject.toml index 31c4b1e6ac33..47a6ff7ef20d 100644 --- a/airbyte-integrations/connectors/source-monday/pyproject.toml +++ b/airbyte-integrations/connectors/source-monday/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "2.1.4" +version = "2.1.8" name = "source-monday" description = "Source implementation for Monday." authors = [ "Airbyte ",] @@ -17,7 +17,7 @@ include = "source_monday" [tool.poetry.dependencies] python = "^3.9,<3.12" -airbyte-cdk = "^0" +airbyte-cdk = "0.78.6" # Breaks with newer versions of the CDK [tool.poetry.scripts] source-monday = "source_monday.run:run" diff --git a/airbyte-integrations/connectors/source-monday/source_monday/components.py b/airbyte-integrations/connectors/source-monday/source_monday/components.py index 802d23aacc81..d79e8c8e0124 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/components.py +++ b/airbyte-integrations/connectors/source-monday/source_monday/components.py @@ -6,6 +6,7 @@ from typing import Any, Iterable, List, Mapping, Optional, Union import dpath.util + from airbyte_cdk.models import AirbyteMessage, SyncMode, Type from airbyte_cdk.sources.declarative.incremental import Cursor from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString @@ -14,6 +15,7 @@ from airbyte_cdk.sources.declarative.types import Config, Record, StreamSlice, StreamState from airbyte_cdk.sources.streams.core import Stream + RequestInput = Union[str, Mapping[str, str]] diff --git a/airbyte-integrations/connectors/source-monday/source_monday/extractor.py b/airbyte-integrations/connectors/source-monday/source_monday/extractor.py index 126839bdecc7..6b0d08427d93 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/extractor.py +++ b/airbyte-integrations/connectors/source-monday/source_monday/extractor.py @@ -10,12 +10,14 @@ import dpath.util import requests + from airbyte_cdk.sources.declarative.decoders.decoder import Decoder from airbyte_cdk.sources.declarative.decoders.json_decoder import JsonDecoder from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString from airbyte_cdk.sources.declarative.types import Config, Record + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-monday/source_monday/item_pagination_strategy.py b/airbyte-integrations/connectors/source-monday/source_monday/item_pagination_strategy.py index a6276416d2e5..131f69786a8e 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/item_pagination_strategy.py +++ b/airbyte-integrations/connectors/source-monday/source_monday/item_pagination_strategy.py @@ -6,6 +6,7 @@ from airbyte_cdk.sources.declarative.requesters.paginators.strategies.page_increment import PageIncrement + # # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # diff --git a/airbyte-integrations/connectors/source-monday/source_monday/source.py b/airbyte-integrations/connectors/source-monday/source_monday/source.py index 45fab7ff246f..868e33c0a027 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/source.py +++ b/airbyte-integrations/connectors/source-monday/source_monday/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-monday/source_monday/spec.json b/airbyte-integrations/connectors/source-monday/source_monday/spec.json index 9119d34d41c2..f615e370ef2a 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/spec.json +++ b/airbyte-integrations/connectors/source-monday/source_monday/spec.json @@ -116,6 +116,16 @@ } } }, + "oauth_connector_input_specification": { + "type": "object", + "additionalProperties": false, + "properties": { + "consent_url": "https://auth.monday.com/oauth2/authorize?{client_id_key}={{client_id_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}&{scope_key}={urlEncoder:{{scope_key}}}&{state_key}={{state_key}}&subdomain={subdomain}", + "scope": "me:read boards:read workspaces:read users:read account:read updates:read assets:read tags:read teams:read", + "access_token_url": "https://auth.monday.com/oauth2/token?{client_id_key}={{client_id_key}}&{client_secret_key}={{client_secret_key}}&{auth_code_key}={{auth_code_key}}&{redirect_uri_key}={urlEncoder:{{redirect_uri_key}}}", + "extract_output": ["access_token"] + } + }, "oauth_user_input_from_connector_config_specification": { "type": "object", "additionalProperties": false, diff --git a/airbyte-integrations/connectors/source-monday/unit_tests/integrations/monday_requests/base_requests_builder.py b/airbyte-integrations/connectors/source-monday/unit_tests/integrations/monday_requests/base_requests_builder.py index 3dd017d476b7..b25b2c27ad98 100644 --- a/airbyte-integrations/connectors/source-monday/unit_tests/integrations/monday_requests/base_requests_builder.py +++ b/airbyte-integrations/connectors/source-monday/unit_tests/integrations/monday_requests/base_requests_builder.py @@ -30,12 +30,7 @@ def request_body(self) -> Optional[str]: """A request body""" def build(self) -> HttpRequest: - return HttpRequest( - url=self.url, - query_params=self.query_params, - headers=self.headers, - body=self.request_body - ) + return HttpRequest(url=self.url, query_params=self.query_params, headers=self.headers, body=self.request_body) class MondayBaseRequestBuilder(MondayRequestBuilder): diff --git a/airbyte-integrations/connectors/source-monday/unit_tests/integrations/monday_responses/error_response_builder.py b/airbyte-integrations/connectors/source-monday/unit_tests/integrations/monday_responses/error_response_builder.py index 779d64d80af7..2457b51faac0 100644 --- a/airbyte-integrations/connectors/source-monday/unit_tests/integrations/monday_responses/error_response_builder.py +++ b/airbyte-integrations/connectors/source-monday/unit_tests/integrations/monday_responses/error_response_builder.py @@ -19,4 +19,3 @@ def build(self, file_path: Optional[str] = None) -> HttpResponse: if not file_path: return HttpResponse(json.dumps(find_template(str(self._status_code), __file__)), self._status_code) return HttpResponse(json.dumps(find_template(str(file_path), __file__)), self._status_code) - diff --git a/airbyte-integrations/connectors/source-monday/unit_tests/integrations/utils.py b/airbyte-integrations/connectors/source-monday/unit_tests/integrations/utils.py index eab0deb8d5b1..654e84f75192 100644 --- a/airbyte-integrations/connectors/source-monday/unit_tests/integrations/utils.py +++ b/airbyte-integrations/connectors/source-monday/unit_tests/integrations/utils.py @@ -3,12 +3,13 @@ import operator from typing import Any, Dict, List, Optional +from source_monday import SourceMonday + from airbyte_cdk.models import AirbyteMessage from airbyte_cdk.models import Level as LogLevel from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read from airbyte_protocol.models import SyncMode -from source_monday import SourceMonday def read_stream( diff --git a/airbyte-integrations/connectors/source-monday/unit_tests/test_components.py b/airbyte-integrations/connectors/source-monday/unit_tests/test_components.py index 30571cbd43f7..4b0aab530fb4 100644 --- a/airbyte-integrations/connectors/source-monday/unit_tests/test_components.py +++ b/airbyte-integrations/connectors/source-monday/unit_tests/test_components.py @@ -7,13 +7,14 @@ from unittest.mock import MagicMock, Mock import pytest -from airbyte_cdk.models import AirbyteMessage, SyncMode, Type -from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig -from airbyte_cdk.sources.streams import Stream from requests import Response from source_monday.components import IncrementalSingleSlice, IncrementalSubstreamSlicer from source_monday.extractor import MondayIncrementalItemsExtractor +from airbyte_cdk.models import AirbyteMessage, SyncMode, Type +from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig +from airbyte_cdk.sources.streams import Stream + def _create_response(content: Any) -> Response: response = Response() @@ -144,7 +145,6 @@ def mock_parent_stream_slices(*args, **kwargs): ids=["no stream state", "successfully read parent record", "skip non_record AirbyteMessage"], ) def test_read_parent_stream(mock_parent_stream, stream_state, parent_records, expected_slices): - slicer = IncrementalSubstreamSlicer( config={}, parameters={}, @@ -162,7 +162,6 @@ def test_read_parent_stream(mock_parent_stream, stream_state, parent_records, ex def test_set_initial_state(): - slicer = IncrementalSubstreamSlicer( config={}, parameters={}, diff --git a/airbyte-integrations/connectors/source-monday/unit_tests/test_graphql_requester.py b/airbyte-integrations/connectors/source-monday/unit_tests/test_graphql_requester.py index 2037f13ee02a..fcd494ecb348 100644 --- a/airbyte-integrations/connectors/source-monday/unit_tests/test_graphql_requester.py +++ b/airbyte-integrations/connectors/source-monday/unit_tests/test_graphql_requester.py @@ -5,10 +5,12 @@ from unittest.mock import MagicMock import pytest +from source_monday import MondayGraphqlRequester + from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString from airbyte_cdk.sources.declarative.requesters.requester import HttpMethod from airbyte_cdk.sources.declarative.schema.json_file_schema_loader import JsonFileSchemaLoader -from source_monday import MondayGraphqlRequester + nested_object_schema = { "root": { @@ -126,7 +128,6 @@ def test_get_schema_root_properties(mocker, monday_requester): def test_build_activity_query(mocker, monday_requester): - mock_stream_state = {"updated_at_int": 1636738688} object_arguments = {"stream_state": mock_stream_state} mocker.patch.object(MondayGraphqlRequester, "_get_object_arguments", return_value="stream_state:{{ stream_state['updated_at_int'] }}") @@ -140,7 +141,6 @@ def test_build_activity_query(mocker, monday_requester): def test_build_items_incremental_query(monday_requester): - object_name = "test_items" field_schema = { "id": {"type": "integer"}, @@ -151,20 +151,21 @@ def test_build_items_incremental_query(monday_requester): "text": {"type": ["null", "string"]}, "type": {"type": ["null", "string"]}, "value": {"type": ["null", "string"]}, - "display_value": {"type": ["null", "string"]} + "display_value": {"type": ["null", "string"]}, } - } + }, } stream_slice = {"ids": [1, 2, 3]} built_query = monday_requester._build_items_incremental_query(object_name, field_schema, stream_slice) - assert built_query == "items(limit:100,ids:[1, 2, 3]){id,name,column_values{id,text,type,value,... on MirrorValue{display_value}," \ - "... on BoardRelationValue{display_value},... on DependencyValue{display_value}}}" + assert ( + built_query == "items(limit:100,ids:[1, 2, 3]){id,name,column_values{id,text,type,value,... on MirrorValue{display_value}," + "... on BoardRelationValue{display_value},... on DependencyValue{display_value}}}" + ) def test_get_request_headers(monday_requester): - headers = monday_requester.get_request_headers() assert headers == {"API-Version": "2024-01"} diff --git a/airbyte-integrations/connectors/source-mongodb-v2/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-mongodb-v2/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-mongodb-v2/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-mongodb-v2/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-mongodb-v2/metadata.yaml b/airbyte-integrations/connectors/source-mongodb-v2/metadata.yaml index cb2cc8d32924..9a57f6b0d762 100644 --- a/airbyte-integrations/connectors/source-mongodb-v2/metadata.yaml +++ b/airbyte-integrations/connectors/source-mongodb-v2/metadata.yaml @@ -5,10 +5,38 @@ data: allowedHosts: hosts: - ${connection_string} + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a connectorSubtype: database + connectorTestSuitesOptions: + - suite: unitTests + - suite: integrationTests + testSecrets: + - fileName: credentials.json + name: SECRET_SOURCE-MONGODB-V2_CREDENTIALS__CREDS + secretStore: + alias: airbyte-connector-testing-secret-store + type: GSM + - fileName: config.json + name: SECRET_SOURCE-MONGODB-V2__CREDS + secretStore: + alias: airbyte-connector-testing-secret-store + type: GSM + - suite: acceptanceTests + testSecrets: + - fileName: credentials.json + name: SECRET_SOURCE-MONGODB-V2_CREDENTIALS__CREDS + secretStore: + alias: airbyte-connector-testing-secret-store + type: GSM + - fileName: config.json + name: SECRET_SOURCE-MONGODB-V2__CREDS + secretStore: + alias: airbyte-connector-testing-secret-store + type: GSM connectorType: source definitionId: b2e713cd-cc36-4c0a-b5bd-b47cb8a0561e - dockerImageTag: 1.5.11 + dockerImageTag: 1.5.13 dockerRepository: airbyte/source-mongodb-v2 documentationUrl: https://docs.airbyte.com/integrations/sources/mongodb-v2 githubIssueLabel: source-mongodb-v2 @@ -22,39 +50,23 @@ data: oss: enabled: true releaseStage: generally_available - supportLevel: certified - tags: - - language:java releases: breakingChanges: 1.0.0: - message: > - **We advise against upgrading until you have run a test upgrade as outlined [here](https://docs.airbyte.com/integrations/sources/mongodb-v2-migrations).** This version brings a host of updates to the MongoDB source connector, significantly increasing its scalability and reliability, especially for large collections. As of this version with checkpointing, [CDC incremental updates](https://docs.airbyte.com/understanding-airbyte/cdc) and improved schema discovery, this connector is also now [certified](https://docs.airbyte.com/integrations/). Selecting `Upgrade` will upgrade **all** connections using this source, require you to reconfigure the source, then run a full reset on **all** of your connections. + message: + "**We advise against upgrading until you have run a test upgrade + as outlined [here](https://docs.airbyte.com/integrations/sources/mongodb-v2-migrations).** This + version brings a host of updates to the MongoDB source connector, significantly + increasing its scalability and reliability, especially for large collections. + As of this version with checkpointing, [CDC incremental updates](https://docs.airbyte.com/understanding-airbyte/cdc) + and improved schema discovery, this connector is also now [certified](https://docs.airbyte.com/integrations/). + Selecting `Upgrade` will upgrade **all** connections using this source, + require you to reconfigure the source, then run a full reset on **all** + of your connections. + + " upgradeDeadline: "2023-12-01" - connectorTestSuitesOptions: - - suite: unitTests - - suite: integrationTests - testSecrets: - - name: SECRET_SOURCE-MONGODB-V2_CREDENTIALS__CREDS - fileName: credentials.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store - - name: SECRET_SOURCE-MONGODB-V2__CREDS - fileName: config.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store - - suite: acceptanceTests - testSecrets: - - name: SECRET_SOURCE-MONGODB-V2_CREDENTIALS__CREDS - fileName: credentials.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store - - name: SECRET_SOURCE-MONGODB-V2__CREDS - fileName: config.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store + supportLevel: certified + tags: + - language:java metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-mongodb-v2/src/main/java/io/airbyte/integrations/source/mongodb/MongoDbSource.java b/airbyte-integrations/connectors/source-mongodb-v2/src/main/java/io/airbyte/integrations/source/mongodb/MongoDbSource.java index 2eb6d2b212d6..d6f34e4d3e82 100644 --- a/airbyte-integrations/connectors/source-mongodb-v2/src/main/java/io/airbyte/integrations/source/mongodb/MongoDbSource.java +++ b/airbyte-integrations/connectors/source-mongodb-v2/src/main/java/io/airbyte/integrations/source/mongodb/MongoDbSource.java @@ -60,27 +60,21 @@ public AirbyteConnectionStatus check(final JsonNode config) { final MongoDbSourceConfig sourceConfig = new MongoDbSourceConfig(config); try (final MongoClient mongoClient = createMongoClient(sourceConfig)) { final String databaseName = sourceConfig.getDatabaseName(); - if (MongoUtil.checkDatabaseExists(mongoClient, databaseName)) { - /* - * Perform the authorized collections check before the cluster type check. The MongoDB Java driver - * needs to actually execute a command in order to fetch the cluster description. Querying for the - * authorized collections guarantees that the cluster description will be available to the driver. - */ - if (MongoUtil.getAuthorizedCollections(mongoClient, databaseName).isEmpty()) { - return new AirbyteConnectionStatus() - .withMessage("Target MongoDB database does not contain any authorized collections.") - .withStatus(AirbyteConnectionStatus.Status.FAILED); - } - if (!ClusterType.REPLICA_SET.equals(mongoClient.getClusterDescription().getType())) { - LOGGER.error("Target MongoDB instance is not a replica set cluster."); - return new AirbyteConnectionStatus() - .withMessage("Target MongoDB instance is not a replica set cluster.") - .withStatus(AirbyteConnectionStatus.Status.FAILED); - } - } else { - LOGGER.error("Unable to perform connection check. Database '" + databaseName + "' does not exist."); - return new AirbyteConnectionStatus().withStatus(AirbyteConnectionStatus.Status.FAILED) - .withMessage("Database does not exist. Please check the source's configured database name."); + /* + * Perform the authorized collections check before the cluster type check. The MongoDB Java driver + * needs to actually execute a command in order to fetch the cluster description. Querying for the + * authorized collections guarantees that the cluster description will be available to the driver. + */ + if (MongoUtil.getAuthorizedCollections(mongoClient, databaseName).isEmpty()) { + return new AirbyteConnectionStatus() + .withMessage("Target MongoDB database does not contain any authorized collections.") + .withStatus(AirbyteConnectionStatus.Status.FAILED); + } + if (!ClusterType.REPLICA_SET.equals(mongoClient.getClusterDescription().getType())) { + LOGGER.error("Target MongoDB instance is not a replica set cluster."); + return new AirbyteConnectionStatus() + .withMessage("Target MongoDB instance is not a replica set cluster.") + .withStatus(AirbyteConnectionStatus.Status.FAILED); } } catch (final MongoSecurityException e) { LOGGER.error("Unable to perform source check operation.", e); diff --git a/airbyte-integrations/connectors/source-mongodb-v2/src/main/java/io/airbyte/integrations/source/mongodb/MongoUtil.java b/airbyte-integrations/connectors/source-mongodb-v2/src/main/java/io/airbyte/integrations/source/mongodb/MongoUtil.java index b2bffab3cbd3..f57fa1ccd8cb 100644 --- a/airbyte-integrations/connectors/source-mongodb-v2/src/main/java/io/airbyte/integrations/source/mongodb/MongoUtil.java +++ b/airbyte-integrations/connectors/source-mongodb-v2/src/main/java/io/airbyte/integrations/source/mongodb/MongoUtil.java @@ -18,7 +18,6 @@ import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoCursor; import com.mongodb.client.MongoDatabase; -import com.mongodb.client.MongoIterable; import com.mongodb.client.model.Aggregates; import com.mongodb.client.model.Projections; import io.airbyte.commons.exceptions.ConfigErrorException; @@ -38,7 +37,6 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -import java.util.stream.StreamSupport; import org.bson.Document; import org.bson.conversions.Bson; import org.slf4j.Logger; @@ -76,20 +74,6 @@ public class MongoUtil { static final Set SCHEMALESS_FIELDS = Set.of(CDC_UPDATED_AT, CDC_DELETED_AT, DEFAULT_CURSOR_FIELD, DEFAULT_PRIMARY_KEY, SCHEMALESS_MODE_DATA_FIELD); - /** - * Tests whether the database exists in target MongoDB instance. - * - * @param mongoClient The {@link MongoClient} used to query the MongoDB server for the database - * names. - * @param databaseName The database name from the source's configuration. - * @return {@code true} if the database exists, {@code false} otherwise. - */ - public static boolean checkDatabaseExists(final MongoClient mongoClient, final String databaseName) { - final MongoIterable databaseNames = mongoClient.listDatabaseNames(); - return StreamSupport.stream(databaseNames.spliterator(), false) - .anyMatch(name -> name.equalsIgnoreCase(databaseName)); - } - /** * Returns the set of collections that the current credentials are authorized to access. * diff --git a/airbyte-integrations/connectors/source-mongodb-v2/src/test/java/io/airbyte/integrations/source/mongodb/MongoDbSourceTest.java b/airbyte-integrations/connectors/source-mongodb-v2/src/test/java/io/airbyte/integrations/source/mongodb/MongoDbSourceTest.java index b1bc2f484c2a..8967acb09e86 100644 --- a/airbyte-integrations/connectors/source-mongodb-v2/src/test/java/io/airbyte/integrations/source/mongodb/MongoDbSourceTest.java +++ b/airbyte-integrations/connectors/source-mongodb-v2/src/test/java/io/airbyte/integrations/source/mongodb/MongoDbSourceTest.java @@ -77,26 +77,6 @@ void testCheckOperation() throws IOException { assertEquals(AirbyteConnectionStatus.Status.SUCCEEDED, airbyteConnectionStatus.getStatus()); } - @Test - void testCheckOperationMissingDatabase() throws IOException { - final ClusterDescription clusterDescription = mock(ClusterDescription.class); - final Document response = Document.parse(MoreResources.readResource("authorized_collections_response.json")); - final MongoDatabase mongoDatabase = mock(MongoDatabase.class); - final MongoIterable iterable = mock(MongoIterable.class); - - when(iterable.spliterator()).thenReturn(List.of("other").spliterator()); - when(mongoClient.listDatabaseNames()).thenReturn(iterable); - - when(clusterDescription.getType()).thenReturn(ClusterType.REPLICA_SET); - when(mongoDatabase.runCommand(any())).thenReturn(response); - when(mongoClient.getDatabase(any())).thenReturn(mongoDatabase); - when(mongoClient.getClusterDescription()).thenReturn(clusterDescription); - - final AirbyteConnectionStatus airbyteConnectionStatus = source.check(airbyteSourceConfig); - assertNotNull(airbyteConnectionStatus); - assertEquals(AirbyteConnectionStatus.Status.FAILED, airbyteConnectionStatus.getStatus()); - } - @Test void testCheckOperationWithMissingConfiguration() throws IOException { final ClusterDescription clusterDescription = mock(ClusterDescription.class); diff --git a/airbyte-integrations/connectors/source-mongodb-v2/src/test/java/io/airbyte/integrations/source/mongodb/MongoUtilTest.java b/airbyte-integrations/connectors/source-mongodb-v2/src/test/java/io/airbyte/integrations/source/mongodb/MongoUtilTest.java index 68b67f3cc7bc..421fbdd49571 100644 --- a/airbyte-integrations/connectors/source-mongodb-v2/src/test/java/io/airbyte/integrations/source/mongodb/MongoUtilTest.java +++ b/airbyte-integrations/connectors/source-mongodb-v2/src/test/java/io/airbyte/integrations/source/mongodb/MongoUtilTest.java @@ -37,7 +37,6 @@ import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoCursor; import com.mongodb.client.MongoDatabase; -import com.mongodb.client.MongoIterable; import io.airbyte.commons.exceptions.ConfigErrorException; import io.airbyte.commons.json.Jsons; import io.airbyte.commons.resources.MoreResources; @@ -61,20 +60,6 @@ public class MongoUtilTest { private static final String JSON_TYPE_PROPERTY_NAME = "type"; - @Test - void testCheckDatabaseExists() { - final String databaseName = "test"; - final List databaseNames = List.of("test", "test1", "test2"); - final MongoIterable iterable = mock(MongoIterable.class); - final MongoClient mongoClient = mock(MongoClient.class); - - when(iterable.spliterator()).thenReturn(databaseNames.spliterator()); - when(mongoClient.listDatabaseNames()).thenReturn(iterable); - - assertTrue(MongoUtil.checkDatabaseExists(mongoClient, databaseName)); - assertFalse(MongoUtil.checkDatabaseExists(mongoClient, "other")); - } - @Test void testGetAirbyteStreams() throws IOException { final AggregateIterable aggregateIterable = mock(AggregateIterable.class); diff --git a/airbyte-integrations/connectors/source-mssql/build.gradle b/airbyte-integrations/connectors/source-mssql/build.gradle index 9edd19d73c3b..14b581fdd24d 100644 --- a/airbyte-integrations/connectors/source-mssql/build.gradle +++ b/airbyte-integrations/connectors/source-mssql/build.gradle @@ -35,3 +35,7 @@ dependencies { testImplementation 'org.hamcrest:hamcrest-all:1.3' testImplementation 'org.testcontainers:mssqlserver:1.19.0' } + +compileKotlin { + +} diff --git a/airbyte-integrations/connectors/source-mssql/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-mssql/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-mssql/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-mssql/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-mssql/metadata.yaml b/airbyte-integrations/connectors/source-mssql/metadata.yaml index 4b1cd2659478..c47c0884cd9a 100644 --- a/airbyte-integrations/connectors/source-mssql/metadata.yaml +++ b/airbyte-integrations/connectors/source-mssql/metadata.yaml @@ -9,7 +9,7 @@ data: connectorSubtype: database connectorType: source definitionId: b5ea17b1-f170-46dc-bc31-cc744ca984c1 - dockerImageTag: 4.1.15 + dockerImageTag: 4.1.18 dockerRepository: airbyte/source-mssql documentationUrl: https://docs.airbyte.com/integrations/sources/mssql githubIssueLabel: source-mssql @@ -37,6 +37,8 @@ data: 2.0.0: message: "Add default cursor for cdc" upgradeDeadline: "2023-08-23" + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:2.0.0@sha256:5a1a21c75c5e1282606de9fa539ba136520abe2fbd013058e988bb0297a9f454 connectorTestSuitesOptions: - suite: unitTests - suite: integrationTests diff --git a/airbyte-integrations/connectors/source-mssql/src/main/java/io/airbyte/integrations/source/mssql/MssqlSource.java b/airbyte-integrations/connectors/source-mssql/src/main/java/io/airbyte/integrations/source/mssql/MssqlSource.java index 94d81ac32c7d..de2520b069d9 100644 --- a/airbyte-integrations/connectors/source-mssql/src/main/java/io/airbyte/integrations/source/mssql/MssqlSource.java +++ b/airbyte-integrations/connectors/source-mssql/src/main/java/io/airbyte/integrations/source/mssql/MssqlSource.java @@ -572,8 +572,9 @@ public JdbcDatabase createDatabase(final JsonNode sourceConfig) throws SQLExcept public static void main(final String[] args) throws Exception { final Source source = MssqlSource.sshWrappedSource(new MssqlSource()); + final MSSqlSourceExceptionHandler exceptionHandler = new MSSqlSourceExceptionHandler(); LOGGER.info("starting source: {}", MssqlSource.class); - new IntegrationRunner(source).run(args); + new IntegrationRunner(source).run(args, exceptionHandler); LOGGER.info("completed source: {}", MssqlSource.class); } diff --git a/airbyte-integrations/connectors/source-mssql/src/main/kotlin/io/airbyte/integrations/source/mssql/MSSqlSourceExceptionHandler.kt b/airbyte-integrations/connectors/source-mssql/src/main/kotlin/io/airbyte/integrations/source/mssql/MSSqlSourceExceptionHandler.kt new file mode 100644 index 000000000000..24f3d588285d --- /dev/null +++ b/airbyte-integrations/connectors/source-mssql/src/main/kotlin/io/airbyte/integrations/source/mssql/MSSqlSourceExceptionHandler.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.mssql + +import io.airbyte.cdk.integrations.util.ConnectorErrorProfile +import io.airbyte.cdk.integrations.util.ConnectorExceptionHandler +import io.airbyte.cdk.integrations.util.FailureType + +class MSSqlSourceExceptionHandler : ConnectorExceptionHandler() { + override fun initializeErrorDictionary() { + + val DATABASE_READ_ERROR = "Encountered an error while reading the database, will retry" + + // include common error profiles + super.initializeErrorDictionary() + + // adding connector specific error profiles + add( + ConnectorErrorProfile( + errorClass = "MS SQL Exception", // which should we use? + regexMatchingPattern = + ".*returned an incomplete response. The connection has been closed.*", + failureType = FailureType.TRANSIENT, + externalMessage = DATABASE_READ_ERROR, + sampleInternalMessage = + "com.microsoft.sqlserver.jdbc.SQLServerException: SQL Server returned an incomplete response. The connection has been closed.", + referenceLinks = listOf("https://github.com/airbytehq/oncall/issues/6623") + ) + ) + } +} diff --git a/airbyte-integrations/connectors/source-mux/metadata.yaml b/airbyte-integrations/connectors/source-mux/metadata.yaml index 3a83cc657fe5..1acfcdaec3eb 100644 --- a/airbyte-integrations/connectors/source-mux/metadata.yaml +++ b/airbyte-integrations/connectors/source-mux/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-mux connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 7bc19e81-14ee-43cb-a2ac-f3bcf6ba0459 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.9 dockerRepository: airbyte/source-mux githubIssueLabel: source-mux icon: icon.svg diff --git a/airbyte-integrations/connectors/source-my-hours/components.py b/airbyte-integrations/connectors/source-my-hours/components.py index 4377ee24ff37..109b493ebd03 100644 --- a/airbyte-integrations/connectors/source-my-hours/components.py +++ b/airbyte-integrations/connectors/source-my-hours/components.py @@ -7,10 +7,12 @@ from typing import Any, Mapping, Union import requests +from requests import HTTPError + from airbyte_cdk.sources.declarative.auth.declarative_authenticator import NoAuth from airbyte_cdk.sources.declarative.interpolation import InterpolatedString from airbyte_cdk.sources.declarative.types import Config -from requests import HTTPError + # https://docs.airbyte.com/integrations/sources/my-hours # The Bearer token generated will expire in five days diff --git a/airbyte-integrations/connectors/source-my-hours/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-my-hours/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-my-hours/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-my-hours/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-my-hours/metadata.yaml b/airbyte-integrations/connectors/source-my-hours/metadata.yaml index 2bc0e3fa7cf5..2d7a5b4d0c3c 100644 --- a/airbyte-integrations/connectors/source-my-hours/metadata.yaml +++ b/airbyte-integrations/connectors/source-my-hours/metadata.yaml @@ -15,11 +15,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 722ba4bf-06ec-45a4-8dd5-72e4a5cf3903 - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.7 dockerRepository: airbyte/source-my-hours githubIssueLabel: source-my-hours icon: my-hours.svg diff --git a/airbyte-integrations/connectors/source-mysql-v2/build.gradle b/airbyte-integrations/connectors/source-mysql-v2/build.gradle deleted file mode 100644 index a11a6e59f352..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/build.gradle +++ /dev/null @@ -1,23 +0,0 @@ -plugins { - id 'airbyte-bulk-connector' -} - -application { - mainClass = 'io.airbyte.integrations.source.mysql.MysqlSource' -} - -airbyteBulkConnector { - core = 'extract' - toolkits = ['extract-jdbc', 'extract-cdc'] - cdk = 'local' -} - -dependencies { - implementation 'mysql:mysql-connector-java:8.0.30' - implementation 'org.codehaus.plexus:plexus-utils:4.0.0' - implementation 'io.debezium:debezium-connector-mysql' - - testImplementation platform('org.testcontainers:testcontainers-bom:1.20.2') - testImplementation 'org.testcontainers:mysql' - testImplementation("io.mockk:mockk:1.12.0") -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/gradle.properties b/airbyte-integrations/connectors/source-mysql-v2/gradle.properties deleted file mode 100644 index 04dcba8cefd7..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/gradle.properties +++ /dev/null @@ -1,2 +0,0 @@ -testExecutionConcurrency=1 -JunitMethodExecutionTimeout=5m \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-mysql-v2/icon.svg b/airbyte-integrations/connectors/source-mysql-v2/icon.svg deleted file mode 100644 index 607d361ed765..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/icon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-mysql-v2/metadata.yaml b/airbyte-integrations/connectors/source-mysql-v2/metadata.yaml deleted file mode 100644 index bad0e5851898..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/metadata.yaml +++ /dev/null @@ -1,28 +0,0 @@ -data: - ab_internal: - ql: 200 - sl: 0 - allowedHosts: - hosts: - - ${host} - - ${tunnel_method.tunnel_host} - connectorSubtype: database - connectorType: source - definitionId: 561393ed-7e3a-4d0d-8b8b-90ded371754c - dockerImageTag: 0.0.28 - dockerRepository: airbyte/source-mysql-v2 - documentationUrl: https://docs.airbyte.com/integrations/sources/mysql - githubIssueLabel: source-mysql-v2 - icon: mysql.svg - license: ELv2 - name: Mysqlv2 Source - registryOverrides: - cloud: - enabled: false - oss: - enabled: false - releaseStage: alpha - supportLevel: community - tags: - - language:java -metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlCdcInitialSnapshotStateValue.kt b/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlCdcInitialSnapshotStateValue.kt deleted file mode 100644 index 847571560c5a..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlCdcInitialSnapshotStateValue.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql - -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.databind.JsonNode -import io.airbyte.cdk.command.OpaqueStateValue -import io.airbyte.cdk.discover.Field -import io.airbyte.cdk.read.Stream -import io.airbyte.cdk.util.Jsons - -data class MysqlCdcInitialSnapshotStateValue( - @JsonProperty("pk_val") val pkVal: String? = null, - @JsonProperty("pk_name") val pkName: String? = null, - @JsonProperty("version") val version: Int? = null, - @JsonProperty("state_type") val stateType: String? = null, - @JsonProperty("incremental_state") val incrementalState: JsonNode? = null, - @JsonProperty("stream_name") val streamName: String? = null, - @JsonProperty("cursor_field") val cursorField: List? = null, - @JsonProperty("stream_namespace") val streamNamespace: String? = null, -) { - companion object { - /** Value representing the completion of a FULL_REFRESH snapshot. */ - fun getSnapshotCompletedState(stream: Stream): OpaqueStateValue = - Jsons.valueToTree( - MysqlCdcInitialSnapshotStateValue( - streamName = stream.name, - cursorField = listOf(), - streamNamespace = stream.namespace - ) - ) - - /** Value representing the progress of an ongoing snapshot. */ - fun snapshotCheckpoint( - primaryKey: List, - primaryKeyCheckpoint: List, - ): OpaqueStateValue { - val primaryKeyField = primaryKey.first() - return Jsons.valueToTree( - MysqlCdcInitialSnapshotStateValue( - pkName = primaryKeyField.id, - pkVal = primaryKeyCheckpoint.first().asText(), - stateType = "primary_key", - ) - ) - } - } -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlCdcMetaFields.kt b/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlCdcMetaFields.kt deleted file mode 100644 index d8f4ad6de14a..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlCdcMetaFields.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql - -import io.airbyte.cdk.discover.CdcIntegerMetaFieldType -import io.airbyte.cdk.discover.CdcStringMetaFieldType -import io.airbyte.cdk.discover.FieldType -import io.airbyte.cdk.discover.MetaField - -enum class MysqlCdcMetaFields( - override val type: FieldType, -) : MetaField { - CDC_CURSOR(CdcIntegerMetaFieldType), - CDC_LOG_POS(CdcIntegerMetaFieldType), - CDC_LOG_FILE(CdcStringMetaFieldType), - ; - - override val id: String - get() = MetaField.META_PREFIX + name.lowercase() -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlJdbcEncryption.kt b/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlJdbcEncryption.kt deleted file mode 100644 index ab21dbc88774..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlJdbcEncryption.kt +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql - -import io.airbyte.cdk.ConfigErrorException -import io.airbyte.cdk.SystemErrorException -import io.airbyte.cdk.jdbc.SSLCertificateUtils -import io.github.oshai.kotlinlogging.KotlinLogging -import java.net.MalformedURLException -import java.net.URI -import java.nio.file.FileSystems -import java.util.* - -private val log = KotlinLogging.logger {} - -class MysqlJdbcEncryption( - val sslMode: SSLMode = SSLMode.PREFERRED, - val caCertificate: String? = null, - val clientCertificate: String? = null, - val clientKey: String? = null, - val clientKeyPassword: String? = null, -) { - companion object { - const val TRUST_KEY_STORE_URL: String = "trustCertificateKeyStoreUrl" - const val TRUST_KEY_STORE_PASS: String = "trustCertificateKeyStorePassword" - const val CLIENT_KEY_STORE_URL: String = "clientCertificateKeyStoreUrl" - const val CLIENT_KEY_STORE_PASS: String = "clientCertificateKeyStorePassword" - const val CLIENT_KEY_STORE_TYPE: String = "clientCertificateKeyStoreType" - const val TRUST_KEY_STORE_TYPE: String = "trustCertificateKeyStoreType" - const val KEY_STORE_TYPE_PKCS12: String = "PKCS12" - const val SSL_MODE: String = "sslMode" - } - - private fun getOrGeneratePassword(): String { - if (!clientKeyPassword.isNullOrEmpty()) { - return clientKeyPassword - } else { - return UUID.randomUUID().toString() - } - } - - private fun prepareCACertificateKeyStore(): Pair? { - // if config is not available - done - // if has CA cert - make keystore with given password or generate a new password. - var caCertKeyStorePair: Pair? = null - - if (caCertificate.isNullOrEmpty()) { - return caCertKeyStorePair - } - val clientKeyPassword = getOrGeneratePassword() - try { - val caCertKeyStoreUri = - SSLCertificateUtils.keyStoreFromCertificate( - caCertificate, - clientKeyPassword, - FileSystems.getDefault(), - "" - ) - return Pair(caCertKeyStoreUri, clientKeyPassword) - } catch (ex: Exception) { - throw ConfigErrorException("Failed to create keystore for CA certificate.", ex) - } - } - - private fun prepareClientCertificateKeyStore(): Pair? { - var clientCertKeyStorePair: Pair? = null - - if (!clientCertificate.isNullOrEmpty() && !clientKey.isNullOrEmpty()) { - val clientKeyPassword = getOrGeneratePassword() - try { - val clientCertKeyStoreUri = - SSLCertificateUtils.keyStoreFromClientCertificate( - clientCertificate, - clientKey, - clientKeyPassword, - "" - ) - clientCertKeyStorePair = Pair(clientCertKeyStoreUri, clientKeyPassword) - } catch (ex: Exception) { - throw RuntimeException("Failed to create keystore for Client certificate", ex) - } - } - return clientCertKeyStorePair - } - - fun parseSSLConfig(): Map { - var caCertKeyStorePair: Pair? - var clientCertKeyStorePair: Pair? - val additionalParameters: MutableMap = mutableMapOf() - - additionalParameters[SSL_MODE] = sslMode.name.lowercase() - - caCertKeyStorePair = prepareCACertificateKeyStore() - - if (null != caCertKeyStorePair) { - log.debug { "uri for ca cert keystore: ${caCertKeyStorePair.first}" } - try { - additionalParameters.putAll( - mapOf( - TRUST_KEY_STORE_URL to caCertKeyStorePair.first.toURL().toString(), - TRUST_KEY_STORE_PASS to caCertKeyStorePair.second, - TRUST_KEY_STORE_TYPE to KEY_STORE_TYPE_PKCS12 - ) - ) - } catch (e: MalformedURLException) { - throw ConfigErrorException("Unable to get a URL for trust key store") - } - - clientCertKeyStorePair = prepareClientCertificateKeyStore() - - if (null != clientCertKeyStorePair) { - log.debug { - "uri for client cert keystore: ${clientCertKeyStorePair.first} / ${clientCertKeyStorePair.second}" - } - try { - additionalParameters.putAll( - mapOf( - CLIENT_KEY_STORE_URL to clientCertKeyStorePair.first.toURL().toString(), - CLIENT_KEY_STORE_PASS to clientCertKeyStorePair.second, - CLIENT_KEY_STORE_TYPE to KEY_STORE_TYPE_PKCS12 - ) - ) - } catch (e: MalformedURLException) { - throw ConfigErrorException("Unable to get a URL for client key store") - } - } - } - return additionalParameters - } -} - -/** - * Enum representing the SSL mode for MySQL connections. The actual jdbc property name is the lower - * case of the enum name. - */ -enum class SSLMode() { - PREFERRED, - REQUIRED, - VERIFY_CA, - VERIFY_IDENTITY; - - companion object { - - fun fromJdbcPropertyName(jdbcPropertyName: String): SSLMode { - return SSLMode.values().find { it.name.equals(jdbcPropertyName, ignoreCase = true) } - ?: throw SystemErrorException("Unknown SSL mode: $jdbcPropertyName") - } - } -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlJdbcPartition.kt b/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlJdbcPartition.kt deleted file mode 100644 index d32b35647dcb..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlJdbcPartition.kt +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql - -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.node.ObjectNode -import io.airbyte.cdk.command.OpaqueStateValue -import io.airbyte.cdk.discover.Field -import io.airbyte.cdk.read.And -import io.airbyte.cdk.read.DefaultJdbcStreamState -import io.airbyte.cdk.read.Equal -import io.airbyte.cdk.read.From -import io.airbyte.cdk.read.FromSample -import io.airbyte.cdk.read.Greater -import io.airbyte.cdk.read.GreaterOrEqual -import io.airbyte.cdk.read.JdbcCursorPartition -import io.airbyte.cdk.read.JdbcPartition -import io.airbyte.cdk.read.JdbcSplittablePartition -import io.airbyte.cdk.read.Lesser -import io.airbyte.cdk.read.LesserOrEqual -import io.airbyte.cdk.read.Limit -import io.airbyte.cdk.read.Or -import io.airbyte.cdk.read.OrderBy -import io.airbyte.cdk.read.SelectColumnMaxValue -import io.airbyte.cdk.read.SelectColumns -import io.airbyte.cdk.read.SelectQuery -import io.airbyte.cdk.read.SelectQueryGenerator -import io.airbyte.cdk.read.SelectQuerySpec -import io.airbyte.cdk.read.Stream -import io.airbyte.cdk.read.Where -import io.airbyte.cdk.read.WhereClauseLeafNode -import io.airbyte.cdk.read.WhereClauseNode -import io.airbyte.cdk.read.optimize -import io.airbyte.cdk.util.Jsons - -/** Base class for default implementations of [JdbcPartition] for non resumable partitions. */ -sealed class MysqlJdbcPartition( - val selectQueryGenerator: SelectQueryGenerator, - streamState: DefaultJdbcStreamState, -) : JdbcPartition { - val stream: Stream = streamState.stream - val from = From(stream.name, stream.namespace) - - override val nonResumableQuery: SelectQuery - get() = selectQueryGenerator.generate(nonResumableQuerySpec.optimize()) - - open val nonResumableQuerySpec = SelectQuerySpec(SelectColumns(stream.fields), from) - - override fun samplingQuery(sampleRateInvPow2: Int): SelectQuery { - val sampleSize: Int = streamState.sharedState.maxSampleSize - val querySpec = - SelectQuerySpec( - SelectColumns(stream.fields), - From(stream.name, stream.namespace), - limit = Limit(sampleSize.toLong()), - ) - return selectQueryGenerator.generate(querySpec.optimize()) - } -} - -/** Default implementation of a [JdbcPartition] for an unsplittable snapshot partition. */ -class MysqlJdbcNonResumableSnapshotPartition( - selectQueryGenerator: SelectQueryGenerator, - override val streamState: DefaultJdbcStreamState, -) : MysqlJdbcPartition(selectQueryGenerator, streamState) { - - override val completeState: OpaqueStateValue = MysqlJdbcStreamStateValue.snapshotCompleted -} - -/** - * Default implementation of a [JdbcPartition] for an non resumable snapshot partition preceding a - * cursor-based incremental sync. - */ -class MysqlJdbcNonResumableSnapshotWithCursorPartition( - selectQueryGenerator: SelectQueryGenerator, - override val streamState: DefaultJdbcStreamState, - val cursor: Field, -) : - MysqlJdbcPartition(selectQueryGenerator, streamState), - JdbcCursorPartition { - - override val completeState: OpaqueStateValue - get() = - MysqlJdbcStreamStateValue.cursorIncrementalCheckpoint( - cursor, - cursorCheckpoint = streamState.cursorUpperBound!!, - streamState.stream, - ) - - override val cursorUpperBoundQuery: SelectQuery - get() = selectQueryGenerator.generate(cursorUpperBoundQuerySpec.optimize()) - - val cursorUpperBoundQuerySpec = SelectQuerySpec(SelectColumnMaxValue(cursor), from) -} - -/** Base class for default implementations of [JdbcPartition] for partitions. */ -sealed class MysqlJdbcResumablePartition( - selectQueryGenerator: SelectQueryGenerator, - streamState: DefaultJdbcStreamState, - val checkpointColumns: List, -) : - MysqlJdbcPartition(selectQueryGenerator, streamState), - JdbcSplittablePartition { - abstract val lowerBound: List? - abstract val upperBound: List? - - override val nonResumableQuery: SelectQuery - get() = selectQueryGenerator.generate(nonResumableQuerySpec.optimize()) - - override val nonResumableQuerySpec: SelectQuerySpec - get() = SelectQuerySpec(SelectColumns(stream.fields), from, where) - - override fun resumableQuery(limit: Long): SelectQuery { - val querySpec = - SelectQuerySpec( - SelectColumns((stream.fields + checkpointColumns).distinct()), - from, - where, - OrderBy(checkpointColumns), - Limit(limit), - ) - return selectQueryGenerator.generate(querySpec.optimize()) - } - - override fun samplingQuery(sampleRateInvPow2: Int): SelectQuery { - val sampleSize: Int = streamState.sharedState.maxSampleSize - val querySpec = - SelectQuerySpec( - SelectColumns(stream.fields + checkpointColumns), - FromSample(stream.name, stream.namespace, sampleRateInvPow2, sampleSize), - where, - OrderBy(checkpointColumns), - ) - return selectQueryGenerator.generate(querySpec.optimize()) - } - - val where: Where - get() { - val zippedLowerBound: List> = - lowerBound?.let { checkpointColumns.zip(it) } ?: listOf() - val lowerBoundDisj: List = - zippedLowerBound.mapIndexed { idx: Int, (gtCol: Field, gtValue: JsonNode) -> - val lastLeaf: WhereClauseLeafNode = - if (isLowerBoundIncluded && idx == checkpointColumns.size - 1) { - GreaterOrEqual(gtCol, gtValue) - } else { - Greater(gtCol, gtValue) - } - And( - zippedLowerBound.take(idx).map { (eqCol: Field, eqValue: JsonNode) -> - Equal(eqCol, eqValue) - } + listOf(lastLeaf), - ) - } - val zippedUpperBound: List> = - upperBound?.let { checkpointColumns.zip(it) } ?: listOf() - val upperBoundDisj: List = - zippedUpperBound.mapIndexed { idx: Int, (leqCol: Field, leqValue: JsonNode) -> - val lastLeaf: WhereClauseLeafNode = - if (idx < zippedUpperBound.size - 1) { - Lesser(leqCol, leqValue) - } else { - LesserOrEqual(leqCol, leqValue) - } - And( - zippedUpperBound.take(idx).map { (eqCol: Field, eqValue: JsonNode) -> - Equal(eqCol, eqValue) - } + listOf(lastLeaf), - ) - } - return Where(And(Or(lowerBoundDisj), Or(upperBoundDisj))) - } - - open val isLowerBoundIncluded: Boolean = false -} - -/** Implementation of a [JdbcPartition] for a snapshot partition. */ -class MysqlJdbcSnapshotPartition( - selectQueryGenerator: SelectQueryGenerator, - override val streamState: DefaultJdbcStreamState, - primaryKey: List, - override val lowerBound: List?, - override val upperBound: List?, -) : MysqlJdbcResumablePartition(selectQueryGenerator, streamState, primaryKey) { - - // TODO: this needs to reflect lastRecord. Complete state needs to have last primary key value - // in RFR case. - override val completeState: OpaqueStateValue - get() = - MysqlJdbcStreamStateValue.snapshotCheckpoint( - primaryKey = checkpointColumns, - primaryKeyCheckpoint = listOf(), - ) - - override fun incompleteState(lastRecord: ObjectNode): OpaqueStateValue = - MysqlJdbcStreamStateValue.snapshotCheckpoint( - primaryKey = checkpointColumns, - primaryKeyCheckpoint = checkpointColumns.map { lastRecord[it.id] ?: Jsons.nullNode() }, - ) -} - -/** Implementation of a [JdbcPartition] for a CDC snapshot partition. */ -class MysqlJdbcCdcSnapshotPartition( - selectQueryGenerator: SelectQueryGenerator, - override val streamState: DefaultJdbcStreamState, - primaryKey: List, - override val lowerBound: List? -) : MysqlJdbcResumablePartition(selectQueryGenerator, streamState, primaryKey) { - override val upperBound: List? = null - override val completeState: OpaqueStateValue - get() = MysqlCdcInitialSnapshotStateValue.getSnapshotCompletedState(stream) - - override fun incompleteState(lastRecord: ObjectNode): OpaqueStateValue = - MysqlCdcInitialSnapshotStateValue.snapshotCheckpoint( - primaryKey = checkpointColumns, - primaryKeyCheckpoint = checkpointColumns.map { lastRecord[it.id] ?: Jsons.nullNode() }, - ) -} - -/** - * Default implementation of a [JdbcPartition] for a splittable partition involving cursor columns. - */ -sealed class MysqlJdbcCursorPartition( - selectQueryGenerator: SelectQueryGenerator, - streamState: DefaultJdbcStreamState, - checkpointColumns: List, - val cursor: Field, - private val explicitCursorUpperBound: JsonNode?, -) : - MysqlJdbcResumablePartition(selectQueryGenerator, streamState, checkpointColumns), - JdbcCursorPartition { - - val cursorUpperBound: JsonNode - get() = explicitCursorUpperBound ?: streamState.cursorUpperBound!! - - override val cursorUpperBoundQuery: SelectQuery - get() = selectQueryGenerator.generate(cursorUpperBoundQuerySpec.optimize()) - - val cursorUpperBoundQuerySpec = SelectQuerySpec(SelectColumnMaxValue(cursor), from) -} - -/** - * Default implementation of a [JdbcPartition] for a splittable snapshot partition preceding a - * cursor-based incremental sync. - */ -class MysqlJdbcSnapshotWithCursorPartition( - selectQueryGenerator: SelectQueryGenerator, - override val streamState: DefaultJdbcStreamState, - primaryKey: List, - override val lowerBound: List?, - cursor: Field, - cursorUpperBound: JsonNode?, -) : - MysqlJdbcCursorPartition( - selectQueryGenerator, - streamState, - primaryKey, - cursor, - cursorUpperBound - ) { - // UpperBound is not used because the partition is not splittable. - override val upperBound: List? = null - - override val completeState: OpaqueStateValue - get() = - MysqlJdbcStreamStateValue.cursorIncrementalCheckpoint( - cursor, - cursorUpperBound, - stream, - ) - - override fun incompleteState(lastRecord: ObjectNode): OpaqueStateValue = - MysqlJdbcStreamStateValue.snapshotWithCursorCheckpoint( - primaryKey = checkpointColumns, - primaryKeyCheckpoint = checkpointColumns.map { lastRecord[it.id] ?: Jsons.nullNode() }, - cursor, - stream, - ) -} - -/** - * Default implementation of a [JdbcPartition] for a cursor incremental partition. These are always - * splittable. - */ -class MysqlJdbcCursorIncrementalPartition( - selectQueryGenerator: SelectQueryGenerator, - override val streamState: DefaultJdbcStreamState, - cursor: Field, - val cursorLowerBound: JsonNode, - override val isLowerBoundIncluded: Boolean, - cursorUpperBound: JsonNode?, -) : - MysqlJdbcCursorPartition( - selectQueryGenerator, - streamState, - listOf(cursor), - cursor, - cursorUpperBound - ) { - - override val lowerBound: List = listOf(cursorLowerBound) - override val upperBound: List - get() = listOf(cursorUpperBound) - - override val completeState: OpaqueStateValue - get() = - MysqlJdbcStreamStateValue.cursorIncrementalCheckpoint( - cursor, - cursorCheckpoint = cursorUpperBound, - stream, - ) - - override fun incompleteState(lastRecord: ObjectNode): OpaqueStateValue = - MysqlJdbcStreamStateValue.cursorIncrementalCheckpoint( - cursor, - cursorCheckpoint = lastRecord[cursor.id] ?: Jsons.nullNode(), - stream, - ) -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlJdbcPartitionFactory.kt b/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlJdbcPartitionFactory.kt deleted file mode 100644 index f1217ac38acb..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlJdbcPartitionFactory.kt +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql - -import com.fasterxml.jackson.databind.JsonNode -import io.airbyte.cdk.ConfigErrorException -import io.airbyte.cdk.StreamIdentifier -import io.airbyte.cdk.command.OpaqueStateValue -import io.airbyte.cdk.data.LeafAirbyteSchemaType -import io.airbyte.cdk.discover.Field -import io.airbyte.cdk.read.ConfiguredSyncMode -import io.airbyte.cdk.read.DefaultJdbcSharedState -import io.airbyte.cdk.read.DefaultJdbcStreamState -import io.airbyte.cdk.read.JdbcPartitionFactory -import io.airbyte.cdk.read.Stream -import io.airbyte.cdk.read.StreamFeedBootstrap -import io.airbyte.cdk.util.Jsons -import io.micronaut.context.annotation.Primary -import java.util.concurrent.ConcurrentHashMap -import javax.inject.Singleton - -@Primary -@Singleton -class MysqlJdbcPartitionFactory( - override val sharedState: DefaultJdbcSharedState, - val selectQueryGenerator: MysqlSourceOperations, -) : - JdbcPartitionFactory< - DefaultJdbcSharedState, - DefaultJdbcStreamState, - MysqlJdbcPartition, - > { - - private val streamStates = ConcurrentHashMap() - - override fun streamState(streamFeedBootstrap: StreamFeedBootstrap): DefaultJdbcStreamState = - streamStates.getOrPut(streamFeedBootstrap.feed.id) { - DefaultJdbcStreamState(sharedState, streamFeedBootstrap) - } - - private fun coldStart(streamState: DefaultJdbcStreamState): MysqlJdbcPartition { - val stream: Stream = streamState.stream - val pkChosenFromCatalog: List = stream.configuredPrimaryKey ?: listOf() - - if (stream.configuredSyncMode == ConfiguredSyncMode.FULL_REFRESH) { - if (pkChosenFromCatalog.isEmpty()) { - return MysqlJdbcNonResumableSnapshotPartition( - selectQueryGenerator, - streamState, - ) - } - return MysqlJdbcSnapshotPartition( - selectQueryGenerator, - streamState, - pkChosenFromCatalog, - lowerBound = null, - upperBound = null, - ) - } - - if (sharedState.configuration.global) { - return MysqlJdbcCdcSnapshotPartition( - selectQueryGenerator, - streamState, - pkChosenFromCatalog, - lowerBound = null, - ) - } - - val cursorChosenFromCatalog: Field = - stream.configuredCursor as? Field ?: throw ConfigErrorException("no cursor") - - if (pkChosenFromCatalog.isEmpty()) { - return MysqlJdbcNonResumableSnapshotWithCursorPartition( - selectQueryGenerator, - streamState, - cursorChosenFromCatalog - ) - } - return MysqlJdbcSnapshotWithCursorPartition( - selectQueryGenerator, - streamState, - pkChosenFromCatalog, - lowerBound = null, - cursorChosenFromCatalog, - cursorUpperBound = null, - ) - } - - /** - * Flowchart: - * 1. If the input state is null - using coldstart. - * ``` - * a. If it's global but without PK, use non-resumable snapshot. - * b. If it's global with PK, use snapshot. - * c. If it's not global, use snapshot with cursor. - * ``` - * 2. If the input state is not null - - * ``` - * a. If it's in global mode, JdbcPartitionFactory will not handle this. (TODO) - * b. If it's cursor based, it could be either in PK read phase (initial read) or - * cursor read phase (incremental read). This is differentiated by the stateType. - * i. In PK read phase, use snapshot with cursor. If no PKs were found, - * use non-resumable snapshot with cursor. - * ii. In cursor read phase, use cursor incremental. - * ``` - */ - override fun create(streamFeedBootstrap: StreamFeedBootstrap): MysqlJdbcPartition? { - val stream: Stream = streamFeedBootstrap.feed - val streamState: DefaultJdbcStreamState = streamState(streamFeedBootstrap) - val opaqueStateValue: OpaqueStateValue = - streamFeedBootstrap.currentState ?: return coldStart(streamState) - - val isCursorBasedIncremental: Boolean = - stream.configuredSyncMode == ConfiguredSyncMode.INCREMENTAL && - !sharedState.configuration.global - - if (!isCursorBasedIncremental) { - val sv: MysqlCdcInitialSnapshotStateValue = - Jsons.treeToValue(opaqueStateValue, MysqlCdcInitialSnapshotStateValue::class.java) - - if (sv.pkName == null) { - // This indicates initial snapshot has been completed. CDC snapshot will be handled - // by CDCPartitionFactory. - // Nothing to do here. - return null - } else { - // This branch indicates snapshot is incomplete. We need to resume based on previous - // snapshot state. - val pkChosenFromCatalog: List = stream.configuredPrimaryKey!! - val pkField = pkChosenFromCatalog.first() - val pkLowerBound: JsonNode = stateValueToJsonNode(pkField, sv.pkVal) - return MysqlJdbcCdcSnapshotPartition( - selectQueryGenerator, - streamState, - pkChosenFromCatalog, - lowerBound = listOf(pkLowerBound), - ) - } - } else { - val sv: MysqlJdbcStreamStateValue = - Jsons.treeToValue(opaqueStateValue, MysqlJdbcStreamStateValue::class.java) - - if (sv.stateType != "cursor_based") { - // Loading value from catalog. Note there could be unexpected behaviors if user - // updates their schema but did not reset their state. - val pkChosenFromCatalog: List = stream.configuredPrimaryKey ?: listOf() - val pkLowerBound: JsonNode = Jsons.valueToTree(sv.pkValue) - val cursorChosenFromCatalog: Field = - stream.configuredCursor as? Field ?: throw ConfigErrorException("no cursor") - - // in a state where it's still in primary_key read part. - return MysqlJdbcSnapshotWithCursorPartition( - selectQueryGenerator, - streamState, - pkChosenFromCatalog, - lowerBound = listOf(pkLowerBound), - cursorChosenFromCatalog, - cursorUpperBound = null, - ) - } - // resume back to cursor based increment. - val cursor: Field = stream.fields.find { it.id == sv.cursorField.first() } as Field - val cursorCheckpoint: JsonNode = stateValueToJsonNode(cursor, sv.cursors) - - // Compose a jsonnode of cursor label to cursor value to fit in - // DefaultJdbcCursorIncrementalPartition - if (cursorCheckpoint == streamState.cursorUpperBound) { - // Incremental complete. - return null - } - return MysqlJdbcCursorIncrementalPartition( - selectQueryGenerator, - streamState, - cursor, - cursorLowerBound = cursorCheckpoint, - isLowerBoundIncluded = false, - cursorUpperBound = streamState.cursorUpperBound, - ) - } - } - - private fun stateValueToJsonNode(field: Field, stateValue: String?): JsonNode { - when (field.type.airbyteSchemaType) { - is LeafAirbyteSchemaType -> - return when (field.type.airbyteSchemaType as LeafAirbyteSchemaType) { - LeafAirbyteSchemaType.INTEGER -> { - Jsons.valueToTree(stateValue?.toInt()) - } - LeafAirbyteSchemaType.NUMBER -> { - Jsons.valueToTree(stateValue?.toDouble()) - } - else -> Jsons.valueToTree(stateValue) - } - else -> - throw IllegalStateException( - "PK field must be leaf type but is ${field.type.airbyteSchemaType}." - ) - } - } - - override fun split( - unsplitPartition: MysqlJdbcPartition, - opaqueStateValues: List - ): List { - // At this moment we don't support split on within mysql stream in any mode. - return listOf(unsplitPartition) - } -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlJdbcStreamStateValue.kt b/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlJdbcStreamStateValue.kt deleted file mode 100644 index a2de16471ef0..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlJdbcStreamStateValue.kt +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql - -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.databind.JsonNode -import io.airbyte.cdk.command.OpaqueStateValue -import io.airbyte.cdk.discover.Field -import io.airbyte.cdk.read.Stream -import io.airbyte.cdk.util.Jsons - -data class MysqlJdbcStreamStateValue( - @JsonProperty("cursor") val cursors: String = "", - @JsonProperty("version") val version: Int = 2, - @JsonProperty("state_type") val stateType: String = StateType.CURSOR_BASED.stateType, - @JsonProperty("stream_name") val streamName: String = "", - @JsonProperty("cursor_field") val cursorField: List = listOf(), - @JsonProperty("stream_namespace") val streamNamespace: String = "", - @JsonProperty("cursor_record_count") val cursorRecordCount: Int = 0, - @JsonProperty("pk_name") val pkName: String? = null, - @JsonProperty("pk_value") val pkValue: String? = null, - @JsonProperty("incremental_state") val incrementalState: JsonNode? = null, -) { - companion object { - /** Value representing the completion of a FULL_REFRESH snapshot. */ - val snapshotCompleted: OpaqueStateValue - get() = Jsons.valueToTree(MysqlJdbcStreamStateValue(stateType = "primary_key")) - - /** Value representing the progress of an ongoing incremental cursor read. */ - fun cursorIncrementalCheckpoint( - cursor: Field, - cursorCheckpoint: JsonNode, - stream: Stream, - ): OpaqueStateValue { - return Jsons.valueToTree( - MysqlJdbcStreamStateValue( - cursorField = listOf(cursor.id), - cursors = cursorCheckpoint.asText(), - streamName = stream.name, - streamNamespace = stream.namespace!! - ) - ) - } - - /** Value representing the progress of an ongoing snapshot not involving cursor columns. */ - fun snapshotCheckpoint( - primaryKey: List, - primaryKeyCheckpoint: List, - ): OpaqueStateValue { - val primaryKeyField = primaryKey.first() - return Jsons.valueToTree( - MysqlJdbcStreamStateValue( - pkName = primaryKeyField.id, - pkValue = primaryKeyCheckpoint.first().asText(), - stateType = StateType.PRIMARY_KEY.stateType, - ) - ) - } - - /** Value representing the progress of an ongoing snapshot involving cursor columns. */ - fun snapshotWithCursorCheckpoint( - primaryKey: List, - primaryKeyCheckpoint: List, - cursor: Field, - stream: Stream - ): OpaqueStateValue { - val primaryKeyField = primaryKey.first() - return Jsons.valueToTree( - MysqlJdbcStreamStateValue( - pkName = primaryKeyField.id, - pkValue = primaryKeyCheckpoint.first().asText(), - stateType = StateType.PRIMARY_KEY.stateType, - incrementalState = - Jsons.valueToTree( - MysqlJdbcStreamStateValue( - cursorField = listOf(cursor.id), - streamName = stream.name, - streamNamespace = stream.namespace!! - ) - ), - ) - ) - } - } -} - -enum class StateType(val stateType: String) { - PRIMARY_KEY("primary_key"), - CURSOR_BASED("cursor_based"), -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlSource.kt b/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlSource.kt deleted file mode 100644 index c46a2c053471..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlSource.kt +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ -package io.airbyte.integrations.source.mysql - -import io.airbyte.cdk.AirbyteSourceRunner - -object MysqlSource { - @JvmStatic - fun main(args: Array) { - AirbyteSourceRunner.run(*args) - } -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceConfiguration.kt b/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceConfiguration.kt deleted file mode 100644 index e4ca3972b0a6..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceConfiguration.kt +++ /dev/null @@ -1,195 +0,0 @@ -/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ -package io.airbyte.integrations.source.mysql - -import io.airbyte.cdk.ConfigErrorException -import io.airbyte.cdk.command.CdcSourceConfiguration -import io.airbyte.cdk.command.ConfigurationSpecificationSupplier -import io.airbyte.cdk.command.FeatureFlag -import io.airbyte.cdk.command.JdbcSourceConfiguration -import io.airbyte.cdk.command.SourceConfiguration -import io.airbyte.cdk.command.SourceConfigurationFactory -import io.airbyte.cdk.ssh.SshConnectionOptions -import io.airbyte.cdk.ssh.SshNoTunnelMethod -import io.airbyte.cdk.ssh.SshTunnelMethodConfiguration -import io.github.oshai.kotlinlogging.KotlinLogging -import io.micronaut.context.annotation.Factory -import jakarta.inject.Inject -import jakarta.inject.Singleton -import java.net.URLDecoder -import java.nio.charset.StandardCharsets -import java.time.Duration - -private val log = KotlinLogging.logger {} - -/** Mysql-specific implementation of [SourceConfiguration] */ -data class MysqlSourceConfiguration( - override val realHost: String, - override val realPort: Int, - override val sshTunnel: SshTunnelMethodConfiguration, - override val sshConnectionOptions: SshConnectionOptions, - override val jdbcUrlFmt: String, - override val jdbcProperties: Map, - override val namespaces: Set, - val incrementalConfiguration: IncrementalConfiguration, - override val maxConcurrency: Int, - override val resourceAcquisitionHeartbeat: Duration = Duration.ofMillis(100L), - override val checkpointTargetInterval: Duration, - override val checkPrivileges: Boolean, - override val debeziumHeartbeatInterval: Duration = Duration.ofSeconds(10), - val debeziumKeepAliveInterval: Duration = Duration.ofMinutes(1), - override val maxSnapshotReadDuration: Duration? -) : JdbcSourceConfiguration, CdcSourceConfiguration { - override val global = incrementalConfiguration is CdcIncrementalConfiguration - - /** Required to inject [MysqlSourceConfiguration] directly. */ - @Factory - private class MicronautFactory { - @Singleton - fun mysqlSourceConfig( - factory: - SourceConfigurationFactory< - MysqlSourceConfigurationSpecification, MysqlSourceConfiguration>, - supplier: ConfigurationSpecificationSupplier, - ): MysqlSourceConfiguration = factory.make(supplier.get()) - } -} - -sealed interface IncrementalConfiguration - -data object UserDefinedCursorIncrementalConfiguration : IncrementalConfiguration - -data class CdcIncrementalConfiguration( - val initialWaitDuration: Duration, - val initialLoadTimeout: Duration, - val serverTimezone: String?, - val invalidCdcCursorPositionBehavior: InvalidCdcCursorPositionBehavior -) : IncrementalConfiguration - -enum class InvalidCdcCursorPositionBehavior { - FAIL_SYNC, - RESET_SYNC, -} - -@Singleton -class MysqlSourceConfigurationFactory @Inject constructor(val featureFlags: Set) : - SourceConfigurationFactory { - - constructor() : this(emptySet()) - - override fun makeWithoutExceptionHandling( - pojo: MysqlSourceConfigurationSpecification, - ): MysqlSourceConfiguration { - val realHost: String = pojo.host - val realPort: Int = pojo.port - val sshTunnel: SshTunnelMethodConfiguration = pojo.getTunnelMethodValue() - val jdbcProperties = mutableMapOf() - jdbcProperties["user"] = pojo.username - pojo.password?.let { jdbcProperties["password"] = it } - - // Parse URL parameters. - val pattern = "^([^=]+)=(.*)$".toRegex() - for (pair in (pojo.jdbcUrlParams ?: "").trim().split("&".toRegex())) { - if (pair.isBlank()) { - continue - } - val result: MatchResult? = pattern.matchEntire(pair) - if (result == null) { - log.warn { "ignoring invalid JDBC URL param '$pair'" } - } else { - val key: String = result.groupValues[1].trim() - val urlEncodedValue: String = result.groupValues[2].trim() - jdbcProperties[key] = URLDecoder.decode(urlEncodedValue, StandardCharsets.UTF_8) - } - } - // Determine protocol and configure encryption. - val encryption: Encryption = pojo.getEncryptionValue() - val jdbcEncryption = - when (encryption) { - is EncryptionPreferred -> { - if ( - featureFlags.contains(FeatureFlag.AIRBYTE_CLOUD_DEPLOYMENT) && - sshTunnel is SshNoTunnelMethod - ) { - throw ConfigErrorException( - "Connection from Airbyte Cloud requires " + - "SSL encryption or an SSH tunnel." - ) - } - MysqlJdbcEncryption(sslMode = SSLMode.PREFERRED) - } - is EncryptionRequired -> MysqlJdbcEncryption(sslMode = SSLMode.REQUIRED) - is SslVerifyCertificate -> - MysqlJdbcEncryption( - sslMode = SSLMode.VERIFY_CA, - caCertificate = encryption.sslCertificate, - clientCertificate = encryption.sslClientCertificate, - clientKey = encryption.sslClientKey, - clientKeyPassword = encryption.sslClientPassword - ) - is SslVerifyIdentity -> - MysqlJdbcEncryption( - sslMode = SSLMode.VERIFY_IDENTITY, - caCertificate = encryption.sslCertificate, - clientCertificate = encryption.sslClientCertificate, - clientKey = encryption.sslClientKey, - clientKeyPassword = encryption.sslClientPassword - ) - } - val sslJdbcParameters = jdbcEncryption.parseSSLConfig() - jdbcProperties.putAll(sslJdbcParameters) - - val cursorConfig = pojo.getCursorMethodConfigurationValue() - val maxSnapshotReadTime: Duration? = - when (cursorConfig is CdcCursor) { - true -> cursorConfig.initialLoadTimeoutHours?.let { Duration.ofHours(it.toLong()) } - else -> null - } - // Build JDBC URL - val address = "%s:%d" - val jdbcUrlFmt = "jdbc:mysql://${address}" - jdbcProperties["useCursorFetch"] = "true" - jdbcProperties["sessionVariables"] = "autocommit=0" - val sshOpts = SshConnectionOptions.fromAdditionalProperties(pojo.getAdditionalProperties()) - val checkpointTargetInterval: Duration = - Duration.ofSeconds(pojo.checkpointTargetIntervalSeconds?.toLong() ?: 0) - if (!checkpointTargetInterval.isPositive) { - throw ConfigErrorException("Checkpoint Target Interval should be positive") - } - val maxConcurrency: Int = pojo.concurrency ?: 0 - if ((pojo.concurrency ?: 0) <= 0) { - throw ConfigErrorException("Concurrency setting should be positive") - } - val incrementalConfiguration: IncrementalConfiguration = - when (val incPojo = pojo.getCursorMethodConfigurationValue()) { - UserDefinedCursor -> UserDefinedCursorIncrementalConfiguration - is CdcCursor -> - CdcIncrementalConfiguration( - initialWaitDuration = - Duration.ofSeconds(incPojo.initialWaitTimeInSeconds!!.toLong()), - initialLoadTimeout = - Duration.ofHours(incPojo.initialLoadTimeoutHours!!.toLong()), - serverTimezone = incPojo.serverTimezone, - invalidCdcCursorPositionBehavior = - if (incPojo.invalidCdcCursorPositionBehavior == "Fail sync") { - InvalidCdcCursorPositionBehavior.FAIL_SYNC - } else { - InvalidCdcCursorPositionBehavior.RESET_SYNC - }, - ) - } - return MysqlSourceConfiguration( - realHost = realHost, - realPort = realPort, - sshTunnel = sshTunnel, - sshConnectionOptions = sshOpts, - jdbcUrlFmt = jdbcUrlFmt, - jdbcProperties = jdbcProperties, - namespaces = setOf(pojo.database), - incrementalConfiguration = incrementalConfiguration, - checkpointTargetInterval = checkpointTargetInterval, - maxConcurrency = maxConcurrency, - checkPrivileges = pojo.checkPrivileges ?: true, - maxSnapshotReadDuration = maxSnapshotReadTime - ) - } -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceConfigurationSpecification.kt b/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceConfigurationSpecification.kt deleted file mode 100644 index dd1a9a953f63..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceConfigurationSpecification.kt +++ /dev/null @@ -1,379 +0,0 @@ -/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ -package io.airbyte.integrations.source.mysql - -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonGetter -import com.fasterxml.jackson.annotation.JsonIgnore -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.annotation.JsonPropertyDescription -import com.fasterxml.jackson.annotation.JsonPropertyOrder -import com.fasterxml.jackson.annotation.JsonSetter -import com.fasterxml.jackson.annotation.JsonSubTypes -import com.fasterxml.jackson.annotation.JsonTypeInfo -import com.fasterxml.jackson.annotation.JsonValue -import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaDefault -import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaDescription -import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaInject -import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaTitle -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings -import io.airbyte.cdk.ConfigErrorException -import io.airbyte.cdk.command.CONNECTOR_CONFIG_PREFIX -import io.airbyte.cdk.command.ConfigurationSpecification -import io.airbyte.cdk.ssh.MicronautPropertiesFriendlySshTunnelMethodConfigurationSpecification -import io.airbyte.cdk.ssh.SshTunnelMethodConfiguration -import io.micronaut.context.annotation.ConfigurationBuilder -import io.micronaut.context.annotation.ConfigurationProperties -import jakarta.inject.Singleton - -/** - * The object which is mapped to the Mysql source configuration JSON. - * - * Use [MysqlSourceConfiguration] instead wherever possible. This object also allows injecting - * values through Micronaut properties, this is made possible by the classes named - * `MicronautPropertiesFriendly.*`. - */ -@JsonSchemaTitle("Mysql Source Spec") -@JsonPropertyOrder( - value = - ["host", "port", "database", "username", "tunnel_method", "ssl_mode", "replication_method"], -) -@Singleton -@ConfigurationProperties(CONNECTOR_CONFIG_PREFIX) -@SuppressFBWarnings(value = ["NP_NONNULL_RETURN_VIOLATION"], justification = "Micronaut DI") -class MysqlSourceConfigurationSpecification : ConfigurationSpecification() { - @JsonProperty("host") - @JsonSchemaTitle("Host") - @JsonSchemaInject(json = """{"order":1}""") - @JsonPropertyDescription("Hostname of the database.") - lateinit var host: String - - @JsonProperty("port") - @JsonSchemaTitle("Port") - @JsonSchemaInject(json = """{"order":2,"minimum": 0,"maximum": 65536}""") - @JsonSchemaDefault("3306") - @JsonPropertyDescription( - "Port of the database.", - ) - var port: Int = 3306 - - @JsonProperty("username") - @JsonSchemaTitle("User") - @JsonPropertyDescription("The username which is used to access the database.") - @JsonSchemaInject(json = """{"order":4}""") - lateinit var username: String - - @JsonProperty("password") - @JsonSchemaTitle("Password") - @JsonPropertyDescription("The password associated with the username.") - @JsonSchemaInject(json = """{"order":5,"always_show":true,"airbyte_secret":true}""") - var password: String? = null - - @JsonProperty("database") - @JsonSchemaTitle("Database") - @JsonPropertyDescription("The database name.") - @JsonSchemaInject(json = """{"order":6,"always_show":true}""") - lateinit var database: String - - @JsonProperty("jdbc_url_params") - @JsonSchemaTitle("JDBC URL Params") - @JsonPropertyDescription( - "Additional properties to pass to the JDBC URL string when connecting to the database " + - "formatted as 'key=value' pairs separated by the symbol '&'. " + - "(example: key1=value1&key2=value2&key3=value3).", - ) - @JsonSchemaInject(json = """{"order":7}""") - var jdbcUrlParams: String? = null - - @JsonIgnore - @ConfigurationBuilder(configurationPrefix = "ssl_mode") - var encryption = MicronautPropertiesFriendlyEncryption() - - @JsonIgnore var encryptionJson: Encryption? = null - - @JsonSetter("ssl_mode") - fun setEncryptionValue(value: Encryption) { - encryptionJson = value - } - - @JsonGetter("ssl_mode") - @JsonSchemaTitle("Encryption") - @JsonPropertyDescription( - "The encryption method with is used when communicating with the database.", - ) - @JsonSchemaInject(json = """{"order":8}""") - fun getEncryptionValue(): Encryption = encryptionJson ?: encryption.asEncryption() - - @JsonIgnore - @ConfigurationBuilder(configurationPrefix = "tunnel_method") - val tunnelMethod = MicronautPropertiesFriendlySshTunnelMethodConfigurationSpecification() - - @JsonIgnore var tunnelMethodJson: SshTunnelMethodConfiguration? = null - - @JsonSetter("tunnel_method") - fun setTunnelMethodValue(value: SshTunnelMethodConfiguration) { - tunnelMethodJson = value - } - - @JsonGetter("tunnel_method") - @JsonSchemaTitle("SSH Tunnel Method") - @JsonPropertyDescription( - "Whether to initiate an SSH tunnel before connecting to the database, " + - "and if so, which kind of authentication to use.", - ) - @JsonSchemaInject(json = """{"order":9}""") - fun getTunnelMethodValue(): SshTunnelMethodConfiguration = - tunnelMethodJson ?: tunnelMethod.asSshTunnelMethod() - - @JsonIgnore - @ConfigurationBuilder(configurationPrefix = "replication_method") - var replicationMethod = MicronautPropertiesFriendlyCursorMethodConfiguration() - - @JsonIgnore var replicationMethodJson: CursorMethodConfiguration? = null - - @JsonSetter("replication_method") - fun setMethodValue(value: CursorMethodConfiguration) { - replicationMethodJson = value - } - - @JsonGetter("replication_method") - @JsonSchemaTitle("Update Method") - @JsonPropertyDescription("Configures how data is extracted from the database.") - @JsonSchemaInject(json = """{"order":10,"display_type":"radio"}""") - fun getCursorMethodConfigurationValue(): CursorMethodConfiguration = - replicationMethodJson ?: replicationMethod.asCursorMethodConfiguration() - - @JsonProperty("checkpoint_target_interval_seconds") - @JsonSchemaTitle("Checkpoint Target Time Interval") - @JsonSchemaInject(json = """{"order":11}""") - @JsonSchemaDefault("300") - @JsonPropertyDescription("How often (in seconds) a stream should checkpoint, when possible.") - var checkpointTargetIntervalSeconds: Int? = 300 - - @JsonProperty("concurrency") - @JsonSchemaTitle("Concurrency") - @JsonSchemaInject(json = """{"order":12}""") - @JsonSchemaDefault("1") - @JsonPropertyDescription("Maximum number of concurrent queries to the database.") - var concurrency: Int? = 1 - - @JsonProperty("check_privileges") - @JsonSchemaTitle("Check Table and Column Access Privileges") - @JsonSchemaInject(json = """{"order":13,"display_type":"check"}""") - @JsonSchemaDefault("true") - @JsonPropertyDescription( - "When this feature is enabled, during schema discovery the connector " + - "will query each table or view individually to check access privileges " + - "and inaccessible tables, views, or columns therein will be removed. " + - "In large schemas, this might cause schema discovery to take too long, " + - "in which case it might be advisable to disable this feature.", - ) - var checkPrivileges: Boolean? = true - - @JsonIgnore var additionalPropertiesMap = mutableMapOf() - - @JsonAnyGetter fun getAdditionalProperties(): Map = additionalPropertiesMap - - @JsonAnySetter - fun setAdditionalProperty( - name: String, - value: Any, - ) { - additionalPropertiesMap[name] = value - } -} - -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "mode") -@JsonSubTypes( - JsonSubTypes.Type(value = EncryptionPreferred::class, name = "preferred"), - JsonSubTypes.Type(value = EncryptionRequired::class, name = "required"), - JsonSubTypes.Type(value = SslVerifyCertificate::class, name = "verify_ca"), - JsonSubTypes.Type(value = SslVerifyIdentity::class, name = "verify_identity"), -) -@JsonSchemaTitle("Encryption") -@JsonSchemaDescription("The encryption method which is used when communicating with the database.") -sealed interface Encryption - -@JsonSchemaTitle("preferred") -@JsonSchemaDescription( - "To allow unencrypted communication only when the source doesn't support encryption.", -) -data object EncryptionPreferred : Encryption - -@JsonSchemaTitle("required") -@JsonSchemaDescription( - "To always require encryption. Note: The connection will fail if the source doesn't support encryption.", -) -data object EncryptionRequired : Encryption - -@JsonSchemaTitle("verify_ca") -@JsonSchemaDescription( - "To always require encryption and verify that the source has a valid SSL certificate." -) -@SuppressFBWarnings(value = ["NP_NONNULL_RETURN_VIOLATION"], justification = "Micronaut DI") -class SslVerifyCertificate : Encryption { - @JsonProperty("ca_certificate", required = true) - @JsonSchemaTitle("CA certificate") - @JsonPropertyDescription( - "CA certificate", - ) - @JsonSchemaInject(json = """{"airbyte_secret":true,"multiline":true}""") - lateinit var sslCertificate: String - - @JsonProperty("client_certificate", required = false) - @JsonSchemaTitle("Client certificate File") - @JsonPropertyDescription( - "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", - ) - @JsonSchemaInject(json = """{"airbyte_secret":true,"multiline":true}""") - var sslClientCertificate: String? = null - - @JsonProperty("client_key") - @JsonSchemaTitle("Client Key") - @JsonPropertyDescription( - "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", - ) - @JsonSchemaInject(json = """{"airbyte_secret":true,"multiline":true}""") - var sslClientKey: String? = null - - @JsonProperty("client_key_password") - @JsonSchemaTitle("Client key password") - @JsonPropertyDescription( - "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", - ) - @JsonSchemaInject(json = """{"airbyte_secret":true,"multiline":true}""") - var sslClientPassword: String? = null -} - -@JsonSchemaTitle("verify_identity") -@JsonSchemaDescription( - "To always require encryption and verify that the source has a valid SSL certificate." -) -@SuppressFBWarnings(value = ["NP_NONNULL_RETURN_VIOLATION"], justification = "Micronaut DI") -class SslVerifyIdentity : Encryption { - @JsonProperty("ca_certificate", required = true) - @JsonSchemaTitle("CA certificate") - @JsonPropertyDescription( - "CA certificate", - ) - @JsonSchemaInject(json = """{"airbyte_secret":true,"multiline":true}""") - lateinit var sslCertificate: String - - @JsonProperty("client_certificate", required = false) - @JsonSchemaTitle("Client certificate File") - @JsonPropertyDescription( - "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", - ) - @JsonSchemaInject(json = """{"airbyte_secret":true,"multiline":true}""") - var sslClientCertificate: String? = null - - @JsonProperty("client_key") - @JsonSchemaTitle("Client Key") - @JsonPropertyDescription( - "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", - ) - @JsonSchemaInject(json = """{"airbyte_secret":true,"multiline":true}""") - var sslClientKey: String? = null - - @JsonProperty("client_key_password") - @JsonSchemaTitle("Client key password") - @JsonPropertyDescription( - "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", - ) - @JsonSchemaInject(json = """{"airbyte_secret":true,"multiline":true}""") - var sslClientPassword: String? = null -} - -@ConfigurationProperties("$CONNECTOR_CONFIG_PREFIX.ssl_mode") -class MicronautPropertiesFriendlyEncryption { - var mode: String = "preferred" - var sslCertificate: String? = null - - @JsonValue - fun asEncryption(): Encryption = - when (mode) { - "preferred" -> EncryptionPreferred - "required" -> EncryptionRequired - "verify_ca" -> SslVerifyCertificate().also { it.sslCertificate = sslCertificate!! } - "verify_identity" -> SslVerifyIdentity().also { it.sslCertificate = sslCertificate!! } - else -> throw ConfigErrorException("invalid value $mode") - } -} - -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "method") -@JsonSubTypes( - JsonSubTypes.Type(value = UserDefinedCursor::class, name = "STANDARD"), - JsonSubTypes.Type(value = CdcCursor::class, name = "CDC") -) -@JsonSchemaTitle("Update Method") -@JsonSchemaDescription("Configures how data is extracted from the database.") -sealed interface CursorMethodConfiguration - -@JsonSchemaTitle("Scan Changes with User Defined Cursor") -@JsonSchemaDescription( - "Incrementally detects new inserts and updates using the " + - "cursor column chosen when configuring a connection " + - "(e.g. created_at, updated_at).", -) -data object UserDefinedCursor : CursorMethodConfiguration - -@JsonSchemaTitle("Read Changes using Change Data Capture (CDC)") -@JsonSchemaDescription( - "Recommended - " + - "Incrementally reads new inserts, updates, and deletes using Mysql's change data capture feature. This must be enabled on your database.", -) -class CdcCursor : CursorMethodConfiguration { - @JsonProperty("initial_waiting_seconds") - @JsonSchemaTitle("Initial Waiting Time in Seconds (Advanced)") - @JsonSchemaDefault("300") - @JsonPropertyDescription( - "The amount of time the connector will wait when it launches to determine if there is new data to sync or not. Defaults to 300 seconds. Valid range: 120 seconds to 1200 seconds. Read about initial waiting time.", - ) - @JsonSchemaInject(json = """{"order":1, "max": 1200, "min": 120, "always_show": true}""") - var initialWaitTimeInSeconds: Int? = 300 - - @JsonProperty("server_timezone") - @JsonSchemaTitle("Configured server timezone for the MySQL source (Advanced)") - @JsonPropertyDescription( - "Enter the configured MySQL server timezone. This should only be done if the configured timezone in your MySQL instance does not conform to IANNA standard.", - ) - @JsonSchemaInject(json = """{"order":2,"always_show":true}""") - var serverTimezone: String? = null - - @JsonProperty("invalid_cdc_cursor_position_behavior") - @JsonSchemaTitle("Configured server timezone for the MySQL source (Advanced)") - @JsonPropertyDescription( - "Enter the configured MySQL server timezone. This should only be done if the configured timezone in your MySQL instance does not conform to IANNA standard.", - ) - @JsonSchemaDefault("Fail sync") - @JsonSchemaInject( - json = """{"order":3,"always_show":true, "enum": ["Fail sync","Re-sync data"]}""" - ) - var invalidCdcCursorPositionBehavior: String? = "Fail sync" - - @JsonProperty("initial_load_timeout_hours") - @JsonSchemaTitle("Initial Load Timeout in Hours (Advanced)") - @JsonPropertyDescription( - "The amount of time an initial load is allowed to continue for before catching up on CDC logs.", - ) - @JsonSchemaDefault("8") - @JsonSchemaInject(json = """{"order":4, "max": 24, "min": 4,"always_show": true}""") - var initialLoadTimeoutHours: Int? = 8 -} - -@ConfigurationProperties("$CONNECTOR_CONFIG_PREFIX.replication_method") -class MicronautPropertiesFriendlyCursorMethodConfiguration { - var method: String = "STANDARD" - - fun asCursorMethodConfiguration(): CursorMethodConfiguration = - when (method) { - "STANDARD" -> UserDefinedCursor - "CDC" -> CdcCursor() - else -> throw ConfigErrorException("invalid value $method") - } -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceMetadataQuerier.kt b/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceMetadataQuerier.kt deleted file mode 100644 index c1b4cd56374c..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceMetadataQuerier.kt +++ /dev/null @@ -1,228 +0,0 @@ -/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ -package io.airbyte.integrations.source.mysql - -import io.airbyte.cdk.ConfigErrorException -import io.airbyte.cdk.StreamIdentifier -import io.airbyte.cdk.check.JdbcCheckQueries -import io.airbyte.cdk.command.SourceConfiguration -import io.airbyte.cdk.discover.Field -import io.airbyte.cdk.discover.JdbcMetadataQuerier -import io.airbyte.cdk.discover.MetadataQuerier -import io.airbyte.cdk.discover.TableName -import io.airbyte.cdk.jdbc.DefaultJdbcConstants -import io.airbyte.cdk.jdbc.JdbcConnectionFactory -import io.airbyte.cdk.read.SelectQueryGenerator -import io.airbyte.protocol.models.v0.StreamDescriptor -import io.github.oshai.kotlinlogging.KotlinLogging -import io.micronaut.context.annotation.Primary -import jakarta.inject.Singleton -import java.sql.Connection -import java.sql.ResultSet -import java.sql.SQLException -import java.sql.Statement - -private val log = KotlinLogging.logger {} - -/** Delegates to [JdbcMetadataQuerier] except for [fields]. */ -class MysqlSourceMetadataQuerier( - val base: JdbcMetadataQuerier, -) : MetadataQuerier by base { - - override fun extraChecks() { - base.extraChecks() - if (base.config.global) { - // Extra checks for CDC - var cdcVariableCheckQueries: List> = - listOf( - Pair("show variables where Variable_name = 'log_bin'", "ON"), - Pair("show variables where Variable_name = 'binlog_format'", "ROW"), - Pair("show variables where Variable_name = 'binlog_row_image'", "FULL"), - Pair("show variables where Variable_name = 'gtid_mode'", "ON"), - ) - - cdcVariableCheckQueries.forEach { runVariableCheckSql(it.first, it.second, base.conn) } - - // Note: SHOW MASTER STATUS has been deprecated in latest mysql (8.4) and going forward - // it should be SHOW BINARY LOG STATUS. We will run both - if both have been failed we - // will throw exception. - try { - base.conn.createStatement().use { stmt: Statement -> - stmt.execute("SHOW MASTER STATUS") - } - } catch (e: SQLException) { - try { - base.conn.createStatement().use { stmt: Statement -> - stmt.execute("SHOW BINARY LOG STATUS") - } - } catch (ex: SQLException) { - throw ConfigErrorException( - "Please grant REPLICATION CLIENT privilege, so that binary log files are available for CDC mode." - ) - } - } - } - } - - private fun runVariableCheckSql(sql: String, expectedValue: String, conn: Connection) { - try { - conn.createStatement().use { stmt: Statement -> - stmt.executeQuery(sql).use { rs: ResultSet -> - if (!rs.next()) { - throw ConfigErrorException("Could not query the variable $sql") - } - val resultValue: String = rs.getString("Value") - if (!resultValue.equals(expectedValue, ignoreCase = true)) { - throw ConfigErrorException( - String.format( - "The variable should be set to \"%s\", but it is \"%s\"", - expectedValue, - resultValue, - ), - ) - } - if (rs.next()) { - throw ConfigErrorException("Could not query the variable $sql") - } - } - } - } catch (e: Exception) { - throw ConfigErrorException("Check query failed with: ${e.message}") - } - } - - override fun fields(streamID: StreamIdentifier): List { - val table: TableName = findTableName(streamID) ?: return listOf() - if (table !in base.memoizedColumnMetadata) return listOf() - return base.memoizedColumnMetadata[table]!!.map { - Field(it.label, base.fieldTypeMapper.toFieldType(it)) - } - } - - override fun streamNamespaces(): List = base.config.namespaces.toList() - - override fun streamNames(streamNamespace: String?): List = - base.memoizedTableNames - .filter { (it.schema ?: it.catalog) == streamNamespace } - .map { StreamDescriptor().withName(it.name).withNamespace(streamNamespace) } - .map(StreamIdentifier::from) - - fun findTableName( - streamID: StreamIdentifier, - ): TableName? = - base.memoizedTableNames.find { - it.name == streamID.name && (it.schema ?: it.catalog) == streamID.namespace - } - - val memoizedPrimaryKeys: Map>> by lazy { - val results = mutableListOf() - val schemas: List = streamNamespaces() - val sql: String = PK_QUERY_FMTSTR.format(schemas.joinToString { "\'$it\'" }) - log.info { "Querying Mysql system tables for all primary keys for catalog discovery." } - try { - // Get primary keys for the specified table - base.conn.createStatement().use { stmt: Statement -> - stmt.executeQuery(sql).use { rs: ResultSet -> - while (rs.next()) { - results.add( - AllPrimaryKeysRow( - rs.getString("table_schema"), - rs.getString("table_name"), - rs.getString("constraint_name"), - rs.getInt("ordinal_position").takeUnless { rs.wasNull() }, - rs.getString("column_name").takeUnless { rs.wasNull() }, - ), - ) - } - } - } - log.info { "Discovered all primary keys in ${schemas.size} Mysql schema(s)." } - return@lazy results - .groupBy { - findTableName( - StreamIdentifier.from( - StreamDescriptor().withName(it.tableName).withNamespace(it.tableSchema), - ), - ) - } - .mapNotNull { (table, rowsByTable) -> - if (table == null) return@mapNotNull null - val pkRows: List = - rowsByTable - .groupBy { it.constraintName } - .filterValues { rowsByPK: List -> - rowsByPK.all { it.position != null && it.columnName != null } - } - .values - .firstOrNull() - ?: return@mapNotNull null - val pkColumnNames: List> = - pkRows - .sortedBy { it.position } - .mapNotNull { it.columnName } - .map { listOf(it) } - table to pkColumnNames - } - .toMap() - } catch (e: Exception) { - throw RuntimeException("Mysql primary key discovery query failed: ${e.message}", e) - } - } - - override fun primaryKey( - streamID: StreamIdentifier, - ): List> { - val table: TableName = findTableName(streamID) ?: return listOf() - return memoizedPrimaryKeys[table] ?: listOf() - } - - private data class AllPrimaryKeysRow( - val tableSchema: String, - val tableName: String, - val constraintName: String, - val position: Int?, - val columnName: String?, - ) - - companion object { - - const val PK_QUERY_FMTSTR = - """ - SELECT - table_schema, - table_name, - column_name, - ordinal_position, - constraint_name - FROM - information_schema.key_column_usage - WHERE - table_schema IN (%s) - AND constraint_name = 'PRIMARY'; - """ - } - - /** Mysql implementation of [MetadataQuerier.Factory]. */ - @Singleton - @Primary - class Factory( - val constants: DefaultJdbcConstants, - val selectQueryGenerator: SelectQueryGenerator, - val fieldTypeMapper: JdbcMetadataQuerier.FieldTypeMapper, - val checkQueries: JdbcCheckQueries, - ) : MetadataQuerier.Factory { - /** The [SourceConfiguration] is deliberately not injected in order to support tests. */ - override fun session(config: MysqlSourceConfiguration): MetadataQuerier { - val jdbcConnectionFactory = JdbcConnectionFactory(config) - val base = - JdbcMetadataQuerier( - constants, - config, - selectQueryGenerator, - fieldTypeMapper, - checkQueries, - jdbcConnectionFactory, - ) - return MysqlSourceMetadataQuerier(base) - } - } -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceOperations.kt b/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceOperations.kt deleted file mode 100644 index 22053b65d485..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceOperations.kt +++ /dev/null @@ -1,261 +0,0 @@ -/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ -package io.airbyte.integrations.source.mysql - -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.node.ObjectNode -import com.mysql.cj.MysqlType -import io.airbyte.cdk.command.OpaqueStateValue -import io.airbyte.cdk.discover.CdcIntegerMetaFieldType -import io.airbyte.cdk.discover.CdcOffsetDateTimeMetaFieldType -import io.airbyte.cdk.discover.CdcStringMetaFieldType -import io.airbyte.cdk.discover.CommonMetaField -import io.airbyte.cdk.discover.Field -import io.airbyte.cdk.discover.FieldType -import io.airbyte.cdk.discover.JdbcAirbyteStreamFactory -import io.airbyte.cdk.discover.JdbcMetadataQuerier -import io.airbyte.cdk.discover.MetaField -import io.airbyte.cdk.discover.SystemType -import io.airbyte.cdk.jdbc.BigDecimalFieldType -import io.airbyte.cdk.jdbc.BigIntegerFieldType -import io.airbyte.cdk.jdbc.BinaryStreamFieldType -import io.airbyte.cdk.jdbc.BooleanFieldType -import io.airbyte.cdk.jdbc.ByteFieldType -import io.airbyte.cdk.jdbc.DoubleFieldType -import io.airbyte.cdk.jdbc.FloatFieldType -import io.airbyte.cdk.jdbc.IntFieldType -import io.airbyte.cdk.jdbc.JdbcFieldType -import io.airbyte.cdk.jdbc.LocalDateFieldType -import io.airbyte.cdk.jdbc.LocalDateTimeFieldType -import io.airbyte.cdk.jdbc.LocalTimeFieldType -import io.airbyte.cdk.jdbc.LongFieldType -import io.airbyte.cdk.jdbc.LosslessJdbcFieldType -import io.airbyte.cdk.jdbc.NullFieldType -import io.airbyte.cdk.jdbc.OffsetDateTimeFieldType -import io.airbyte.cdk.jdbc.PokemonFieldType -import io.airbyte.cdk.jdbc.ShortFieldType -import io.airbyte.cdk.jdbc.StringFieldType -import io.airbyte.cdk.read.And -import io.airbyte.cdk.read.Equal -import io.airbyte.cdk.read.From -import io.airbyte.cdk.read.FromNode -import io.airbyte.cdk.read.FromSample -import io.airbyte.cdk.read.Greater -import io.airbyte.cdk.read.GreaterOrEqual -import io.airbyte.cdk.read.Lesser -import io.airbyte.cdk.read.LesserOrEqual -import io.airbyte.cdk.read.Limit -import io.airbyte.cdk.read.LimitNode -import io.airbyte.cdk.read.NoFrom -import io.airbyte.cdk.read.NoLimit -import io.airbyte.cdk.read.NoOrderBy -import io.airbyte.cdk.read.NoWhere -import io.airbyte.cdk.read.Or -import io.airbyte.cdk.read.OrderBy -import io.airbyte.cdk.read.OrderByNode -import io.airbyte.cdk.read.SelectColumnMaxValue -import io.airbyte.cdk.read.SelectColumns -import io.airbyte.cdk.read.SelectNode -import io.airbyte.cdk.read.SelectQuery -import io.airbyte.cdk.read.SelectQueryGenerator -import io.airbyte.cdk.read.SelectQuerySpec -import io.airbyte.cdk.read.Stream -import io.airbyte.cdk.read.Where -import io.airbyte.cdk.read.WhereClauseLeafNode -import io.airbyte.cdk.read.WhereClauseNode -import io.airbyte.cdk.read.WhereNode -import io.airbyte.cdk.read.cdc.DebeziumState -import io.airbyte.cdk.util.Jsons -import io.airbyte.integrations.source.mysql.cdc.MySqlDebeziumOperations -import io.airbyte.integrations.source.mysql.cdc.MySqlPosition -import io.micronaut.context.annotation.Primary -import jakarta.inject.Singleton -import java.time.OffsetDateTime - -@Singleton -@Primary -class MysqlSourceOperations : - JdbcMetadataQuerier.FieldTypeMapper, SelectQueryGenerator, JdbcAirbyteStreamFactory { - - override val globalCursor: MetaField = MysqlCdcMetaFields.CDC_CURSOR - - override val globalMetaFields: Set = - setOf( - MysqlCdcMetaFields.CDC_CURSOR, - CommonMetaField.CDC_UPDATED_AT, - CommonMetaField.CDC_DELETED_AT, - MysqlCdcMetaFields.CDC_LOG_FILE, - MysqlCdcMetaFields.CDC_LOG_POS - ) - - override fun decorateRecordData( - timestamp: OffsetDateTime, - globalStateValue: OpaqueStateValue?, - stream: Stream, - recordData: ObjectNode - ) { - recordData.set( - CommonMetaField.CDC_UPDATED_AT.id, - CdcOffsetDateTimeMetaFieldType.jsonEncoder.encode(timestamp), - ) - recordData.set( - MysqlCdcMetaFields.CDC_LOG_POS.id, - CdcIntegerMetaFieldType.jsonEncoder.encode(0), - ) - if (globalStateValue == null) { - return - } - val debeziumState: DebeziumState = - MySqlDebeziumOperations.deserializeDebeziumState(globalStateValue) - val position: MySqlPosition = MySqlDebeziumOperations.position(debeziumState.offset) - recordData.set( - MysqlCdcMetaFields.CDC_LOG_FILE.id, - CdcStringMetaFieldType.jsonEncoder.encode(position.fileName), - ) - recordData.set( - MysqlCdcMetaFields.CDC_LOG_POS.id, - CdcIntegerMetaFieldType.jsonEncoder.encode(position.position), - ) - } - - override fun toFieldType(c: JdbcMetadataQuerier.ColumnMetadata): FieldType = - when (val type = c.type) { - is SystemType -> leafType(type) - else -> PokemonFieldType - } - - private fun leafType(type: SystemType): JdbcFieldType<*> { - return when (MysqlType.getByName(type.typeName)) { - MysqlType.BIT -> { - if (type.precision!! > 1) { - ByteFieldType - } else { - BooleanFieldType - } - } - MysqlType.BOOLEAN -> BooleanFieldType - MysqlType.TINYINT, - MysqlType.TINYINT_UNSIGNED, - MysqlType.YEAR -> ShortFieldType - MysqlType.SMALLINT, - MysqlType.SMALLINT_UNSIGNED, - MysqlType.MEDIUMINT, - MysqlType.MEDIUMINT_UNSIGNED, - MysqlType.INT -> IntFieldType - MysqlType.INT_UNSIGNED, - MysqlType.BIGINT, - MysqlType.BIGINT_UNSIGNED -> BigIntegerFieldType - MysqlType.FLOAT, - MysqlType.FLOAT_UNSIGNED -> FloatFieldType - MysqlType.DOUBLE, - MysqlType.DOUBLE_UNSIGNED -> DoubleFieldType - MysqlType.DECIMAL, - MysqlType.DECIMAL_UNSIGNED -> { - if (type.scale == 0) BigIntegerFieldType else BigDecimalFieldType - } - MysqlType.DATE -> LocalDateFieldType - MysqlType.DATETIME -> LocalDateTimeFieldType - MysqlType.TIMESTAMP -> OffsetDateTimeFieldType - MysqlType.TIME -> LocalTimeFieldType - MysqlType.CHAR, - MysqlType.VARCHAR, - MysqlType.TINYTEXT, - MysqlType.TEXT, - MysqlType.MEDIUMTEXT, - MysqlType.LONGTEXT, - MysqlType.JSON, - MysqlType.ENUM, - MysqlType.SET -> StringFieldType - MysqlType.TINYBLOB, - MysqlType.BLOB, - MysqlType.MEDIUMBLOB, - MysqlType.LONGBLOB, - MysqlType.BINARY, - MysqlType.VARBINARY, - MysqlType.GEOMETRY -> BinaryStreamFieldType - MysqlType.NULL -> NullFieldType - else -> { - print("test debug: unrecognized type: ${type.typeName}") - PokemonFieldType - } - } - } - - override fun generate(ast: SelectQuerySpec): SelectQuery = - SelectQuery(ast.sql(), ast.select.columns, ast.bindings()) - - fun SelectQuerySpec.sql(): String { - val components: List = listOf(select.sql(), from.sql(), where.sql(), orderBy.sql()) - val sqlWithoutLimit: String = components.filter { it.isNotBlank() }.joinToString(" ") - val rownumClause: String = - when (limit) { - NoLimit -> return sqlWithoutLimit - Limit(0) -> "LIMIT 0" - is Limit -> "LIMIT ?" - } - return "$sqlWithoutLimit $rownumClause" - } - - fun SelectNode.sql(): String = - "SELECT " + - when (this) { - is SelectColumns -> columns.joinToString(", ") { it.sql() } - is SelectColumnMaxValue -> "MAX(${column.sql()})" - } - - fun Field.sql(): String = "`$id`" - - fun FromNode.sql(): String = - when (this) { - NoFrom -> "" - is From -> if (this.namespace == null) "FROM `$name`" else "FROM `$namespace`.`$name`" - is FromSample -> TODO("not implemented in mysql") - } - - fun WhereNode.sql(): String = - when (this) { - NoWhere -> "" - is Where -> "WHERE ${clause.sql()}" - } - - fun WhereClauseNode.sql(): String = - when (this) { - is And -> conj.joinToString(") AND (", "(", ")") { it.sql() } - is Or -> disj.joinToString(") OR (", "(", ")") { it.sql() } - is Equal -> "${column.sql()} = ?" - is Greater -> "${column.sql()} > ?" - is GreaterOrEqual -> "${column.sql()} >= ?" - is LesserOrEqual -> "${column.sql()} <= ?" - is Lesser -> "${column.sql()} < ?" - } - - fun OrderByNode.sql(): String = - when (this) { - NoOrderBy -> "" - is OrderBy -> "ORDER BY " + columns.joinToString(", ") { it.sql() } - } - - fun SelectQuerySpec.bindings(): List = where.bindings() + limit.bindings() - - fun WhereNode.bindings(): List = - when (this) { - is NoWhere -> listOf() - is Where -> clause.bindings() - } - - fun WhereClauseNode.bindings(): List = - when (this) { - is And -> conj.flatMap { it.bindings() } - is Or -> disj.flatMap { it.bindings() } - is WhereClauseLeafNode -> { - val type = column.type as LosslessJdbcFieldType<*, *> - listOf(SelectQuery.Binding(bindingValue, type)) - } - } - - fun LimitNode.bindings(): List = - when (this) { - NoLimit, - Limit(0) -> listOf() - is Limit -> listOf(SelectQuery.Binding(Jsons.numberNode(n), LongFieldType)) - } -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/cdc/MySqlDebeziumOperations.kt b/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/cdc/MySqlDebeziumOperations.kt deleted file mode 100644 index 33e9bb228494..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/cdc/MySqlDebeziumOperations.kt +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.cdc - -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.node.ArrayNode -import com.fasterxml.jackson.databind.node.ObjectNode -import io.airbyte.cdk.ConfigErrorException -import io.airbyte.cdk.StreamIdentifier -import io.airbyte.cdk.command.OpaqueStateValue -import io.airbyte.cdk.data.LongCodec -import io.airbyte.cdk.data.OffsetDateTimeCodec -import io.airbyte.cdk.data.TextCodec -import io.airbyte.cdk.discover.CommonMetaField -import io.airbyte.cdk.discover.Field -import io.airbyte.cdk.jdbc.JdbcConnectionFactory -import io.airbyte.cdk.jdbc.LongFieldType -import io.airbyte.cdk.jdbc.StringFieldType -import io.airbyte.cdk.read.Stream -import io.airbyte.cdk.read.cdc.DebeziumInput -import io.airbyte.cdk.read.cdc.DebeziumOffset -import io.airbyte.cdk.read.cdc.DebeziumOperations -import io.airbyte.cdk.read.cdc.DebeziumPropertiesBuilder -import io.airbyte.cdk.read.cdc.DebeziumRecordKey -import io.airbyte.cdk.read.cdc.DebeziumRecordValue -import io.airbyte.cdk.read.cdc.DebeziumSchemaHistory -import io.airbyte.cdk.read.cdc.DebeziumState -import io.airbyte.cdk.read.cdc.DeserializedRecord -import io.airbyte.cdk.ssh.TunnelSession -import io.airbyte.cdk.util.Jsons -import io.airbyte.integrations.source.mysql.CdcIncrementalConfiguration -import io.airbyte.integrations.source.mysql.InvalidCdcCursorPositionBehavior -import io.airbyte.integrations.source.mysql.MysqlCdcMetaFields -import io.airbyte.integrations.source.mysql.MysqlSourceConfiguration -import io.airbyte.integrations.source.mysql.cdc.converters.MySQLDateTimeConverter -import io.airbyte.protocol.models.v0.StreamDescriptor -import io.debezium.connector.mysql.MySqlConnector -import io.debezium.connector.mysql.gtid.MySqlGtidSet -import io.debezium.document.DocumentReader -import io.debezium.document.DocumentWriter -import io.debezium.relational.history.HistoryRecord -import io.github.oshai.kotlinlogging.KotlinLogging -import jakarta.inject.Singleton -import java.io.ByteArrayInputStream -import java.io.ByteArrayOutputStream -import java.sql.Connection -import java.sql.ResultSet -import java.sql.Statement -import java.time.Instant -import java.time.OffsetDateTime -import java.time.ZoneOffset -import java.util.zip.GZIPInputStream -import java.util.zip.GZIPOutputStream -import kotlin.random.Random -import kotlin.random.nextInt -import org.apache.kafka.connect.json.JsonConverterConfig -import org.apache.kafka.connect.source.SourceRecord - -@Singleton -class MySqlDebeziumOperations( - val jdbcConnectionFactory: JdbcConnectionFactory, - val configuration: MysqlSourceConfiguration, - random: Random = Random.Default, -) : DebeziumOperations { - private val log = KotlinLogging.logger {} - - override fun deserialize( - key: DebeziumRecordKey, - value: DebeziumRecordValue - ): DeserializedRecord { - val before: JsonNode = value.before - val after: JsonNode = value.after - val source: JsonNode = value.source - val isDelete: Boolean = after.isNull - // Identify the stream. - val streamID: StreamIdentifier = - StreamIdentifier.from( - StreamDescriptor() - .withName(source["table"].asText()) - .withNamespace(source["db"].asText()) - ) - // Use either `before` or `after` as the record data, depending on the nature of the change. - val data: ObjectNode = (if (isDelete) before else after) as ObjectNode - // Set _ab_cdc_updated_at and _ab_cdc_deleted_at meta-field values. - val transactionMillis: Long = source["ts_ms"].asLong() - val transactionOffsetDateTime: OffsetDateTime = - OffsetDateTime.ofInstant(Instant.ofEpochMilli(transactionMillis), ZoneOffset.UTC) - val transactionTimestampJsonNode: JsonNode = - OffsetDateTimeCodec.encode(transactionOffsetDateTime) - data.set( - CommonMetaField.CDC_UPDATED_AT.id, - transactionTimestampJsonNode, - ) - data.set( - CommonMetaField.CDC_DELETED_AT.id, - if (isDelete) transactionTimestampJsonNode else Jsons.nullNode(), - ) - // Set _ab_cdc_log_file and _ab_cdc_log_pos meta-field values. - val position = MySqlPosition(source["file"].asText(), source["pos"].asLong()) - data.set(MysqlCdcMetaFields.CDC_LOG_FILE.id, TextCodec.encode(position.fileName)) - data.set(MysqlCdcMetaFields.CDC_LOG_POS.id, LongCodec.encode(position.position)) - // Set the _ab_cdc_cursor meta-field value. - data.set(MysqlCdcMetaFields.CDC_CURSOR.id, LongCodec.encode(position.cursorValue)) - // Return a DeserializedRecord instance. - return DeserializedRecord(streamID, data, changes = emptyMap()) - } - - /** - * Checks if GTIDs from previously saved state (debeziumInput) are still valid on DB. And also - * check if binlog exists or not. - * - * Validate is not supposed to perform on synthetic state. - */ - private fun validate(debeziumState: DebeziumState): CdcStateValidateResult { - val (_: MySqlPosition, gtidSet: String?) = queryPositionAndGtids() - if (gtidSet.isNullOrEmpty()) { - return abortCdcSync() - } - val savedStateOffset: SavedOffset = parseSavedOffset(debeziumState) - - val savedGtidSet = MySqlGtidSet(savedStateOffset.gtidSet) - val availableGtidSet = MySqlGtidSet(gtidSet) - if (!savedGtidSet.isContainedWithin(availableGtidSet)) { - log.info { - "Connector last known GTIDs are $savedGtidSet, but MySQL server only has $availableGtidSet" - } - return abortCdcSync() - } - - // newGtidSet is gtids from server that hasn't been seen by this connector yet. If the set - // exists, check that they are not purged, or we may lose those data. - val newGtidSet = availableGtidSet.subtract(savedGtidSet) - if (!newGtidSet.isEmpty) { - val purgedGtidSet = queryPurgedIds() - if (!newGtidSet.subtract(purgedGtidSet).equals(newGtidSet)) { - log.info { - "Connector has not seen GTIDs $newGtidSet, but MySQL server has purged $purgedGtidSet" - } - return abortCdcSync() - } - } - val existingLogFiles: List = getBinaryLogFileNames() - val found = existingLogFiles.contains(savedStateOffset.position.fileName) - if (!found) { - log.info { - "Connector last known binlog file ${savedStateOffset.position.fileName} is not found in the server" - } - return abortCdcSync() - } - return CdcStateValidateResult.VALID - } - - private fun abortCdcSync(): CdcStateValidateResult { - val cdcIncrementalConfiguration: CdcIncrementalConfiguration = - configuration.incrementalConfiguration as CdcIncrementalConfiguration - return when (cdcIncrementalConfiguration.invalidCdcCursorPositionBehavior) { - InvalidCdcCursorPositionBehavior.FAIL_SYNC -> { - log.info { "Current position is invalid, aborting sync." } - CdcStateValidateResult.INVALID_ABORT - } - InvalidCdcCursorPositionBehavior.RESET_SYNC -> { - log.info { "Current position is invalid, resetting sync." } - CdcStateValidateResult.INVALID_RESET - } - } - } - - private fun parseSavedOffset(debeziumState: DebeziumState): SavedOffset { - val position: MySqlPosition = position(debeziumState.offset) - val gtidSet: String? = debeziumState.offset.wrapped.values.first()["gtids"]?.asText() - return SavedOffset(position, gtidSet) - } - - data class SavedOffset(val position: MySqlPosition, val gtidSet: String?) - - enum class CdcStateValidateResult { - VALID, - INVALID_ABORT, - INVALID_RESET - } - - override fun position(offset: DebeziumOffset): MySqlPosition = Companion.position(offset) - - override fun position(recordValue: DebeziumRecordValue): MySqlPosition? { - val file: JsonNode = recordValue.source["file"]?.takeIf { it.isTextual } ?: return null - val pos: JsonNode = recordValue.source["pos"]?.takeIf { it.isIntegralNumber } ?: return null - return MySqlPosition(file.asText(), pos.asLong()) - } - - override fun position(sourceRecord: SourceRecord): MySqlPosition? { - val offset: Map = sourceRecord.sourceOffset() - val file: Any = offset["file"] ?: return null - val pos: Long = offset["pos"] as? Long ?: return null - return MySqlPosition(file.toString(), pos) - } - - override fun synthesize(): DebeziumInput { - val (mySqlPosition: MySqlPosition, gtidSet: String?) = queryPositionAndGtids() - val topicPrefixName: String = DebeziumPropertiesBuilder.sanitizeTopicPrefix(databaseName) - val timestamp: Instant = Instant.now() - val key: ArrayNode = - Jsons.arrayNode().apply { - add(databaseName) - add(Jsons.objectNode().apply { put("server", topicPrefixName) }) - } - val value: ObjectNode = - Jsons.objectNode().apply { - put("ts_sec", timestamp.epochSecond) - put("file", mySqlPosition.fileName) - put("pos", mySqlPosition.position) - if (gtidSet != null) { - put("gtids", gtidSet) - } - } - val offset = DebeziumOffset(mapOf(key to value)) - log.info { "Constructed synthetic $offset." } - val state = DebeziumState(offset, schemaHistory = null) - return DebeziumInput(syntheticProperties, state, isSynthetic = true) - } - - private fun queryPositionAndGtids(): Pair { - val file = Field("File", StringFieldType) - val pos = Field("Position", LongFieldType) - val gtids = Field("Executed_Gtid_Set", StringFieldType) - jdbcConnectionFactory.get().use { connection: Connection -> - connection.createStatement().use { stmt: Statement -> - val sql = "SHOW MASTER STATUS" - stmt.executeQuery(sql).use { rs: ResultSet -> - if (!rs.next()) throw ConfigErrorException("No results for query: $sql") - val mySqlPosition = - MySqlPosition( - fileName = rs.getString(file.id)?.takeUnless { rs.wasNull() } - ?: throw ConfigErrorException( - "No value for ${file.id} in: $sql", - ), - position = rs.getLong(pos.id).takeUnless { rs.wasNull() || it <= 0 } - ?: throw ConfigErrorException( - "No value for ${pos.id} in: $sql", - ), - ) - if (rs.metaData.columnCount <= 4) { - // This value exists only in MySQL 5.6.5 or later. - return mySqlPosition to null - } - val gtidSet: String? = - rs.getString(gtids.id) - ?.takeUnless { rs.wasNull() || it.isBlank() } - ?.trim() - ?.replace("\n", "") - ?.replace("\r", "") - return mySqlPosition to gtidSet - } - } - } - } - - private fun queryPurgedIds(): MySqlGtidSet { - val purgedGtidField = Field("@@global.gtid_purged", StringFieldType) - jdbcConnectionFactory.get().use { connection: Connection -> - connection.createStatement().use { stmt: Statement -> - val sql = "SELECT @@global.gtid_purged" - stmt.executeQuery(sql).use { rs: ResultSet -> - if (!rs.next()) throw ConfigErrorException("No results for query: $sql") - return MySqlGtidSet(rs.getString(purgedGtidField.id)) - } - } - } - } - - private fun getBinaryLogFileNames(): List { - val logNameField = Field("Log_name", StringFieldType) - return jdbcConnectionFactory.get().use { connection: Connection -> - connection.createStatement().use { stmt: Statement -> - val sql = "SHOW BINARY LOGS" - stmt.executeQuery(sql).use { rs: ResultSet -> - generateSequence { if (rs.next()) rs.getString(logNameField.id) else null } - .toList() - } - } - } - } - - override fun deserialize( - opaqueStateValue: OpaqueStateValue, - streams: List - ): DebeziumInput { - val debeziumState: DebeziumState = - try { - deserializeDebeziumState(opaqueStateValue) - } catch (e: Exception) { - throw ConfigErrorException("Error deserializing $opaqueStateValue", e) - } - val cdcValidationResult = validate(debeziumState) - if (cdcValidationResult != CdcStateValidateResult.VALID) { - if (cdcValidationResult == CdcStateValidateResult.INVALID_ABORT) { - throw ConfigErrorException("Current position is invalid.") - } - return synthesize() - } - - val properties: Map = - DebeziumPropertiesBuilder().with(commonProperties).withStreams(streams).buildMap() - return DebeziumInput(properties, debeziumState, isSynthetic = false) - } - - override fun serialize(debeziumState: DebeziumState): OpaqueStateValue { - val stateNode: ObjectNode = Jsons.objectNode() - // Serialize offset. - val offsetNode: JsonNode = - Jsons.objectNode().apply { - for ((k, v) in debeziumState.offset.wrapped) { - put(Jsons.writeValueAsString(k), Jsons.writeValueAsString(v)) - } - } - stateNode.set(MYSQL_CDC_OFFSET, offsetNode) - // Serialize schema history. - val schemaHistory: List? = debeziumState.schemaHistory?.wrapped - if (schemaHistory != null) { - val uncompressedString: String = - schemaHistory.joinToString(separator = "\n") { - DocumentWriter.defaultWriter().write(it.document()) - } - if (uncompressedString.length <= MAX_UNCOMPRESSED_LENGTH) { - stateNode.put(MYSQL_DB_HISTORY, uncompressedString) - } else { - stateNode.put(IS_COMPRESSED, true) - val baos = ByteArrayOutputStream() - GZIPOutputStream(baos).writer(Charsets.UTF_8).use { it.write(uncompressedString) } - stateNode.put(MYSQL_DB_HISTORY, baos.toByteArray()) - } - } - return Jsons.objectNode().apply { set(STATE, stateNode) } - } - - val databaseName: String = configuration.namespaces.first() - val serverID: Int = random.nextInt(MIN_SERVER_ID..MAX_SERVER_ID) - - val commonProperties: Map by lazy { - val tunnelSession: TunnelSession = jdbcConnectionFactory.ensureTunnelSession() - DebeziumPropertiesBuilder() - .withDefault() - .withConnector(MySqlConnector::class.java) - .withDebeziumName(databaseName) - .withHeartbeats(configuration.debeziumHeartbeatInterval) - // This to make sure that binary data represented as a base64-encoded String. - // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-property-binary-handling-mode - .with("binary.handling.mode", "base64") - // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-property-snapshot-mode - .with("snapshot.mode", "when_needed") - // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-property-snapshot-locking-mode - // This is to make sure other database clients are allowed to write to a table while - // Airbyte is taking a snapshot. There is a risk involved that if any database client - // makes a schema change then the sync might break - .with("snapshot.locking.mode", "none") - // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-property-include-schema-changes - .with("include.schema.changes", "false") - .with( - "connect.keep.alive.interval.ms", - configuration.debeziumKeepAliveInterval.toMillis().toString(), - ) - .withDatabase(configuration.jdbcProperties) - .withDatabase("hostname", tunnelSession.address.hostName) - .withDatabase("port", tunnelSession.address.port.toString()) - .withDatabase("dbname", databaseName) - .withDatabase("server.id", serverID.toString()) - .withDatabase("include.list", databaseName) - .withOffset() - .withSchemaHistory() - .with("converters", "datetime") - .with( - "datetime.type", - MySQLDateTimeConverter::class.java.getName(), - ) - // TODO: add missing properties, like MySQL converters, etc. Do a full audit. - .buildMap() - } - - val syntheticProperties: Map by lazy { - DebeziumPropertiesBuilder() - .with(commonProperties) - // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-property-snapshot-mode - // We use the recovery property cause using this mode will instruct Debezium to - // construct the db schema history. Note that we used to use schema_only_recovery mode - // instead, but this mode has been deprecated. - .with("snapshot.mode", "recovery") - .withStreams(listOf()) - .buildMap() - } - - companion object { - // Constants defining a range for the random value picked for the database.server.id - // Debezium property which uniquely identifies the binlog consumer. - // https://debezium.io/documentation/reference/stable/connectors/mysql.html#mysql-property-database-server-id - const val MIN_SERVER_ID = 5400 - const val MAX_SERVER_ID = 6400 - - const val MAX_UNCOMPRESSED_LENGTH = 1024 * 1024 - const val STATE = "state" - const val MYSQL_CDC_OFFSET = "mysql_cdc_offset" - const val MYSQL_DB_HISTORY = "mysql_db_history" - const val IS_COMPRESSED = "is_compressed" - - /** - * The name of the Debezium property that contains the unique name for the Debezium - * connector. - */ - const val CONNECTOR_NAME_PROPERTY: String = "name" - - /** Configuration for offset state key/value converters. */ - val INTERNAL_CONVERTER_CONFIG: Map = - java.util.Map.of(JsonConverterConfig.SCHEMAS_ENABLE_CONFIG, false.toString()) - - internal fun deserializeDebeziumState(opaqueStateValue: OpaqueStateValue): DebeziumState { - val stateNode: ObjectNode = opaqueStateValue[STATE] as ObjectNode - // Deserialize offset. - val offsetNode: ObjectNode = stateNode[MYSQL_CDC_OFFSET] as ObjectNode - val offsetMap: Map = - offsetNode - .fields() - .asSequence() - .map { (k, v) -> Jsons.readTree(k) to Jsons.readTree(v.textValue()) } - .toMap() - if (offsetMap.size != 1) { - throw RuntimeException("Offset object should have 1 key in $opaqueStateValue") - } - val offset = DebeziumOffset(offsetMap) - // Deserialize schema history. - val schemaNode: JsonNode = - stateNode[MYSQL_DB_HISTORY] ?: return DebeziumState(offset, schemaHistory = null) - val isCompressed: Boolean = stateNode[IS_COMPRESSED]?.asBoolean() ?: false - val uncompressedString: String = - if (isCompressed) { - val compressedBytes: ByteArray = - Jsons.readValue(schemaNode.textValue(), ByteArray::class.java) - GZIPInputStream(ByteArrayInputStream(compressedBytes)) - .reader(Charsets.UTF_8) - .readText() - } else { - schemaNode.textValue() - } - val schemaHistoryList: List = - uncompressedString - .lines() - .filter { it.isNotBlank() } - .map { HistoryRecord(DocumentReader.defaultReader().read(it)) } - return DebeziumState(offset, DebeziumSchemaHistory(schemaHistoryList)) - } - - internal fun position(offset: DebeziumOffset): MySqlPosition { - if (offset.wrapped.size != 1) { - throw ConfigErrorException("Expected exactly 1 key in $offset") - } - val offsetValue: ObjectNode = offset.wrapped.values.first() as ObjectNode - return MySqlPosition(offsetValue["file"].asText(), offsetValue["pos"].asLong()) - } - } -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/cdc/MySqlPosition.kt b/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/cdc/MySqlPosition.kt deleted file mode 100644 index bcb7abefbcfd..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/cdc/MySqlPosition.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.cdc - -import kotlin.io.path.Path -import kotlin.io.path.extension - -/** WAL position datum for MySQL. */ -data class MySqlPosition(val fileName: String, val position: Long) : Comparable { - - /** - * Numerical value encoded in the extension of the binlog file name. - * - * These files are typically named `binlog.000002` or something like that. These file's sizes - * are, according to the documentation, capped at 1 GB. - */ - val fileExtension: Int - get() = Path(fileName).extension.toInt() - - /** - * Numerical value obtained by ORing [fileExtension] in the high bits of [position]. This - * unsigned long integer can be used as a cursor value for the purposes of deduping records in - * incremental syncs; its value is meaningless in and of itself, all that matters is that it is - * monotonically increasing from one record to the next within the same sync. - * - * Specifically, deduplication will group all records by (_ab_cdc_updated_at, emitted_at) and - * will pick the record with the latest cursor value and discard the rest. - */ - val cursorValue: Long - get() = (fileExtension.toLong() shl Int.SIZE_BITS) or position - - override fun compareTo(other: MySqlPosition): Int = cursorValue.compareTo(other.cursorValue) -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/cdc/converters/MySQLDateTimeConverter.kt b/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/cdc/converters/MySQLDateTimeConverter.kt deleted file mode 100644 index a58d276f0041..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/main/kotlin/io/airbyte/integrations/source/mysql/cdc/converters/MySQLDateTimeConverter.kt +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.cdc.converters - -import io.airbyte.cdk.jdbc.converters.DateTimeConverter -import io.debezium.spi.converter.CustomConverter -import io.debezium.spi.converter.RelationalColumn -import io.debezium.time.Conversions -import java.time.LocalDate -import java.time.LocalTime -import java.util.* -import java.util.concurrent.TimeUnit -import org.apache.kafka.connect.data.SchemaBuilder - -/** - * This is a custom debezium converter used in MySQL to handle the DATETIME data type. We need a - * custom converter cause by default debezium returns the DATETIME values as numbers. We need to - * convert it to proper format. Ref : - * https://debezium.io/documentation/reference/2.1/development/converters.html This is built from - * reference with {@link io.debezium.connector.mysql.converters.TinyIntOneToBooleanConverter} If you - * rename this class then remember to rename the datetime.type property value in {@link - * MySqlCdcProperties#commonProperties(JdbcDatabase)} (If you don't rename, a test would still fail - * but it might be tricky to figure out where to change the property name) - */ -class MySQLDateTimeConverter : CustomConverter { - - private val DATE_TYPES = arrayOf("DATE", "DATETIME", "TIME", "TIMESTAMP") - override fun configure(props: Properties?) {} - - override fun converterFor( - field: RelationalColumn?, - registration: CustomConverter.ConverterRegistration? - ) { - if ( - Arrays.stream(DATE_TYPES).anyMatch { s: String -> - s.equals( - field!!.typeName(), - ignoreCase = true, - ) - } - ) { - registerDate(field, registration) - } - } - - private fun getTimePrecision(field: RelationalColumn): Int { - return field.length().orElse(-1) - } - - private fun registerDate( - field: RelationalColumn?, - registration: CustomConverter.ConverterRegistration? - ) { - val fieldType = field!!.typeName() - - registration?.register(SchemaBuilder.string().optional()) { x -> - if (x == null) { - convertDefaultValue(field) - } - - when (fieldType.uppercase()) { - "DATETIME" -> { - if (x is Long) { - if (getTimePrecision(field) <= 3) { - DateTimeConverter.convertToTimestamp( - Conversions.toInstantFromMillis(x), - ) - } - if (getTimePrecision(field) <= 6) { - DateTimeConverter.convertToTimestamp( - Conversions.toInstantFromMicros(x), - ) - } - } - DateTimeConverter.convertToTimestamp(x) - } - "DATE" -> { - if (x is Int) { - DateTimeConverter.convertToDate( - LocalDate.ofEpochDay( - x.toLong(), - ), - ) - } - DateTimeConverter.convertToDate(x) - } - "TIME" -> { - if (x is Long) { - val l = Math.multiplyExact(x, TimeUnit.MICROSECONDS.toNanos(1)) - DateTimeConverter.convertToTime( - LocalTime.ofNanoOfDay( - l, - ), - ) - } - DateTimeConverter.convertToTime(x) - } - "TIMESTAMP" -> - DateTimeConverter.convertToTimestampWithTimezone( - x, - ) - else -> - throw IllegalArgumentException("Unknown field type " + fieldType.uppercase()) - } - } - } - - companion object { - fun convertDefaultValue(field: RelationalColumn): Any? { - if (field.isOptional) { - return null - } else if (field.hasDefaultValue()) { - return field.defaultValue() - } - return null - } - } -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/main/resources/application.yml b/airbyte-integrations/connectors/source-mysql-v2/src/main/resources/application.yml deleted file mode 100644 index 0dde139e4093..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/main/resources/application.yml +++ /dev/null @@ -1,19 +0,0 @@ ---- -airbyte: - connector: - extract: - jdbc: - mode: sequential - throughput-bytes-per-second: 10000000 - min-fetch-size: 5 - default-fetch-size: 5 - max-fetch-size: 5 - memory-capacity-ratio: 0.6 - estimated-record-overhead-bytes: 16 - estimated-field-overhead-bytes: 16 - namespace-kind: CATALOG_AND_SCHEMA - check: - jdbc: - queries: - - >- - SELECT 1 where 1 = 0; diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlCdcIntegrationTest.kt b/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlCdcIntegrationTest.kt deleted file mode 100644 index 99b1b10d8d3b..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlCdcIntegrationTest.kt +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql - -import io.airbyte.cdk.StreamIdentifier -import io.airbyte.cdk.command.CliRunner -import io.airbyte.cdk.discover.DiscoveredStream -import io.airbyte.cdk.discover.Field -import io.airbyte.cdk.jdbc.IntFieldType -import io.airbyte.cdk.jdbc.JdbcConnectionFactory -import io.airbyte.cdk.jdbc.StringFieldType -import io.airbyte.cdk.output.BufferingOutputConsumer -import io.airbyte.integrations.source.mysql.MysqlContainerFactory.execAsRoot -import io.airbyte.protocol.models.v0.AirbyteConnectionStatus -import io.airbyte.protocol.models.v0.AirbyteMessage -import io.airbyte.protocol.models.v0.AirbyteStream -import io.airbyte.protocol.models.v0.CatalogHelpers -import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog -import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream -import io.airbyte.protocol.models.v0.StreamDescriptor -import io.airbyte.protocol.models.v0.SyncMode -import io.github.oshai.kotlinlogging.KotlinLogging -import java.sql.Connection -import java.sql.Statement -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.Timeout -import org.testcontainers.containers.MySQLContainer - -class MysqlCdcIntegrationTest { - - @Test - fun testCheck() { - val run1: BufferingOutputConsumer = CliRunner.source("check", config(), null).run() - - assertEquals(run1.messages().size, 1) - assertEquals( - run1.messages().first().connectionStatus.status, - AirbyteConnectionStatus.Status.SUCCEEDED - ) - - MysqlContainerFactory.exclusive( - imageName = "mysql:8.0", - MysqlContainerFactory.WithCdcOff, - ) - .use { nonCdcDbContainer -> - { - val invalidConfig: MysqlSourceConfigurationSpecification = - MysqlContainerFactory.config(nonCdcDbContainer).apply { - setMethodValue(CdcCursor()) - } - - val nonCdcConnectionFactory = - JdbcConnectionFactory(MysqlSourceConfigurationFactory().make(invalidConfig)) - - provisionTestContainer(nonCdcDbContainer, nonCdcConnectionFactory) - - val run2: BufferingOutputConsumer = - CliRunner.source("check", invalidConfig, null).run() - - val messageInRun2 = - run2 - .messages() - .filter { it.type == AirbyteMessage.Type.CONNECTION_STATUS } - .first() - - assertEquals( - AirbyteConnectionStatus.Status.FAILED, - messageInRun2.connectionStatus.status - ) - } - } - } - - @Test - fun test() { - CliRunner.source("read", config(), configuredCatalog).run() - // TODO: add assertions on run1 messages. - - connectionFactory.get().use { connection: Connection -> - connection.isReadOnly = false - connection.createStatement().use { stmt: Statement -> - stmt.execute("INSERT INTO test.tbl (k, v) VALUES (3, 'baz')") - } - } - } - - companion object { - val log = KotlinLogging.logger {} - lateinit var dbContainer: MySQLContainer<*> - - fun config(): MysqlSourceConfigurationSpecification = - MysqlContainerFactory.config(dbContainer).apply { setMethodValue(CdcCursor()) } - - val connectionFactory: JdbcConnectionFactory by lazy { - JdbcConnectionFactory(MysqlSourceConfigurationFactory().make(config())) - } - - val configuredCatalog: ConfiguredAirbyteCatalog = run { - val desc = StreamDescriptor().withName("tbl").withNamespace("test") - val discoveredStream = - DiscoveredStream( - id = StreamIdentifier.Companion.from(desc), - columns = listOf(Field("k", IntFieldType), Field("v", StringFieldType)), - primaryKeyColumnIDs = listOf(listOf("k")), - ) - val stream: AirbyteStream = MysqlSourceOperations().createGlobal(discoveredStream) - val configuredStream: ConfiguredAirbyteStream = - CatalogHelpers.toDefaultConfiguredStream(stream) - .withSyncMode(SyncMode.INCREMENTAL) - .withPrimaryKey(discoveredStream.primaryKeyColumnIDs) - .withCursorField(listOf(MysqlCdcMetaFields.CDC_CURSOR.id)) - ConfiguredAirbyteCatalog().withStreams(listOf(configuredStream)) - } - - @JvmStatic - @BeforeAll - @Timeout(value = 300) - fun startAndProvisionTestContainer() { - dbContainer = - MysqlContainerFactory.exclusive( - imageName = "mysql:8.0", - MysqlContainerFactory.WithNetwork, - ) - provisionTestContainer(dbContainer, connectionFactory) - } - - fun provisionTestContainer( - targetContainer: MySQLContainer<*>, - targetConnectionFactory: JdbcConnectionFactory - ) { - val gtidOn = - "SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 'ON';" + - "SET @@GLOBAL.GTID_MODE = 'OFF_PERMISSIVE';" + - "SET @@GLOBAL.GTID_MODE = 'ON_PERMISSIVE';" + - "SET @@GLOBAL.GTID_MODE = 'ON';" - val grant = - "GRANT SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT " + - "ON *.* TO '${targetContainer.username}'@'%';" - targetContainer.execAsRoot(gtidOn) - targetContainer.execAsRoot(grant) - targetContainer.execAsRoot("FLUSH PRIVILEGES;") - - targetConnectionFactory.get().use { connection: Connection -> - connection.isReadOnly = false - connection.createStatement().use { stmt: Statement -> - stmt.execute("CREATE TABLE test.tbl(k INT PRIMARY KEY, v VARCHAR(80))") - } - connection.createStatement().use { stmt: Statement -> - stmt.execute("INSERT INTO test.tbl (k, v) VALUES (1, 'foo'), (2, 'bar')") - } - } - } - } -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlContainerFactory.kt b/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlContainerFactory.kt deleted file mode 100644 index 13f8d439371b..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlContainerFactory.kt +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ -package io.airbyte.integrations.source.mysql - -import io.airbyte.cdk.testcontainers.TestContainerFactory -import io.github.oshai.kotlinlogging.KotlinLogging -import org.testcontainers.containers.Container -import org.testcontainers.containers.MySQLContainer -import org.testcontainers.containers.Network -import org.testcontainers.utility.DockerImageName - -object MysqlContainerFactory { - const val COMPATIBLE_NAME = "mysql:8.0" - private val log = KotlinLogging.logger {} - - init { - TestContainerFactory.register(COMPATIBLE_NAME, ::MySQLContainer) - } - - sealed interface MysqlContainerModifier : - TestContainerFactory.ContainerModifier> - - data object WithNetwork : MysqlContainerModifier { - override fun modify(container: MySQLContainer<*>) { - container.withNetwork(Network.newNetwork()) - } - } - - data object WithCdcOff : MysqlContainerModifier { - override fun modify(container: MySQLContainer<*>) { - container.withCommand("--skip-log-bin") - } - } - - fun exclusive( - imageName: String, - vararg modifiers: MysqlContainerModifier, - ): MySQLContainer<*> { - val dockerImageName = - DockerImageName.parse(imageName).asCompatibleSubstituteFor(COMPATIBLE_NAME) - return TestContainerFactory.exclusive(dockerImageName, *modifiers) - } - - fun shared( - imageName: String, - vararg modifiers: MysqlContainerModifier, - ): MySQLContainer<*> { - val dockerImageName = - DockerImageName.parse(imageName).asCompatibleSubstituteFor(COMPATIBLE_NAME) - return TestContainerFactory.shared(dockerImageName, *modifiers) - } - - @JvmStatic - fun config(mySQLContainer: MySQLContainer<*>): MysqlSourceConfigurationSpecification = - MysqlSourceConfigurationSpecification().apply { - host = mySQLContainer.host - port = mySQLContainer.getMappedPort(MySQLContainer.MYSQL_PORT) - username = mySQLContainer.username - password = mySQLContainer.password - jdbcUrlParams = "" - database = "test" - checkpointTargetIntervalSeconds = 60 - concurrency = 1 - setMethodValue(UserDefinedCursor) - } - - fun MySQLContainer<*>.execAsRoot(sql: String) { - val cleanSql: String = sql.trim().removeSuffix(";") + ";" - log.info { "Executing SQL as root: $cleanSql" } - val result: Container.ExecResult = - execInContainer("mysql", "-u", "root", "-ptest", "-e", cleanSql) - for (line in (result.stdout ?: "").lines()) { - log.info { "STDOUT: $line" } - } - for (line in (result.stderr ?: "").lines()) { - log.info { "STDOUT: $line" } - } - if (result.exitCode == 0) { - return - } - log.error { "Exit code ${result.exitCode}" } - throw RuntimeException("Failed to execute query $cleanSql") - } -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlCursorBasedIntegrationTest.kt b/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlCursorBasedIntegrationTest.kt deleted file mode 100644 index 2e8c2f32b2cc..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlCursorBasedIntegrationTest.kt +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql - -import io.airbyte.cdk.StreamIdentifier -import io.airbyte.cdk.command.CliRunner -import io.airbyte.cdk.discover.DiscoveredStream -import io.airbyte.cdk.discover.Field -import io.airbyte.cdk.jdbc.IntFieldType -import io.airbyte.cdk.jdbc.JdbcConnectionFactory -import io.airbyte.cdk.jdbc.StringFieldType -import io.airbyte.cdk.output.BufferingOutputConsumer -import io.airbyte.cdk.util.Jsons -import io.airbyte.protocol.models.v0.AirbyteRecordMessage -import io.airbyte.protocol.models.v0.AirbyteStateMessage -import io.airbyte.protocol.models.v0.AirbyteStream -import io.airbyte.protocol.models.v0.CatalogHelpers -import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog -import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream -import io.airbyte.protocol.models.v0.StreamDescriptor -import io.airbyte.protocol.models.v0.SyncMode -import io.github.oshai.kotlinlogging.KotlinLogging -import java.sql.Connection -import java.sql.Statement -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.Timeout -import org.testcontainers.containers.MySQLContainer - -class MysqlCursorBasedIntegrationTest { - - @Test - fun testCursorBasedRead() { - val run1: BufferingOutputConsumer = - CliRunner.source("read", config, getConfiguredCatalog()).run() - - val lastStateMessageFromRun1 = run1.states().last() - val lastStreamStateFromRun1 = lastStateMessageFromRun1.stream.streamState - - assertEquals("20", lastStreamStateFromRun1.get("cursor").textValue()) - assertEquals(2, lastStreamStateFromRun1.get("version").intValue()) - assertEquals("cursor_based", lastStreamStateFromRun1.get("state_type").asText()) - assertEquals(tableName, lastStreamStateFromRun1.get("stream_name").asText()) - assertEquals(listOf("k"), lastStreamStateFromRun1.get("cursor_field").map { it.asText() }) - assertEquals("test", lastStreamStateFromRun1.get("stream_namespace").asText()) - assertEquals(0, lastStreamStateFromRun1.get("cursor_record_count").asInt()) - - connectionFactory.get().use { connection: Connection -> - connection.isReadOnly = false - connection.createStatement().use { stmt: Statement -> - stmt.execute("INSERT INTO test.$tableName (k, v) VALUES (3, 'baz-ignore')") - stmt.execute("INSERT INTO test.$tableName (k, v) VALUES (13, 'baz-ignore')") - stmt.execute("INSERT INTO test.$tableName (k, v) VALUES (30, 'baz')") - } - } - - val run2InputState: List = listOf(lastStateMessageFromRun1) - val run2: BufferingOutputConsumer = - CliRunner.source("read", config, getConfiguredCatalog(), run2InputState).run() - val recordMessageFromRun2: List = run2.records() - assertEquals(recordMessageFromRun2.size, 1) - } - - @Test - fun testWithV1State() { - var state: AirbyteStateMessage = Jsons.readValue(V1_STATE, AirbyteStateMessage::class.java) - val run1: BufferingOutputConsumer = - CliRunner.source("read", config, getConfiguredCatalog(), listOf(state)).run() - val recordMessageFromRun1: List = run1.records() - assertEquals(recordMessageFromRun1.size, 1) - } - - companion object { - val log = KotlinLogging.logger {} - val dbContainer: MySQLContainer<*> = MysqlContainerFactory.shared(imageName = "mysql:8.0") - - val config: MysqlSourceConfigurationSpecification = - MysqlContainerFactory.config(dbContainer) - - val connectionFactory: JdbcConnectionFactory by lazy { - JdbcConnectionFactory(MysqlSourceConfigurationFactory().make(config)) - } - - fun getConfiguredCatalog(): ConfiguredAirbyteCatalog { - val desc = StreamDescriptor().withName(tableName).withNamespace("test") - val discoveredStream = - DiscoveredStream( - id = StreamIdentifier.Companion.from(desc), - columns = listOf(Field("k", IntFieldType), Field("v", StringFieldType)), - primaryKeyColumnIDs = listOf(listOf("k")), - ) - val stream: AirbyteStream = MysqlSourceOperations().createGlobal(discoveredStream) - val configuredStream: ConfiguredAirbyteStream = - CatalogHelpers.toDefaultConfiguredStream(stream) - .withSyncMode(SyncMode.INCREMENTAL) - .withPrimaryKey(discoveredStream.primaryKeyColumnIDs) - .withCursorField(listOf("k")) - return ConfiguredAirbyteCatalog().withStreams(listOf(configuredStream)) - } - - @JvmStatic - @BeforeAll - @Timeout(value = 300) - fun startAndProvisionTestContainer() { - provisionTestContainer(connectionFactory) - } - - lateinit var tableName: String - - fun provisionTestContainer(targetConnectionFactory: JdbcConnectionFactory) { - tableName = (1..8).map { ('a'..'z').random() }.joinToString("") - - targetConnectionFactory.get().use { connection: Connection -> - connection.isReadOnly = false - connection.createStatement().use { stmt: Statement -> - stmt.execute("CREATE TABLE test.$tableName(k INT PRIMARY KEY, v VARCHAR(80))") - } - connection.createStatement().use { stmt: Statement -> - stmt.execute( - "INSERT INTO test.$tableName (k, v) VALUES (10, 'foo'), (20, 'bar')" - ) - } - } - } - } - val V1_STATE: String = - """ - { - "type": "STREAM", - "stream": { - "stream_descriptor": { - "name": "${tableName}", - "namespace": "test" - }, - "stream_state": { - "cursor": "10", - "version": 2, - "state_type": "cursor_based", - "stream_name": "${tableName}", - "cursor_field": [ - "k" - ], - "stream_namespace": "test", - "cursor_record_count": 1 - } - } - } - """ -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlJdbcPartitionFactoryTest.kt b/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlJdbcPartitionFactoryTest.kt deleted file mode 100644 index 4d8166a7b476..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlJdbcPartitionFactoryTest.kt +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql - -import com.fasterxml.jackson.databind.node.ObjectNode -import io.airbyte.cdk.ClockFactory -import io.airbyte.cdk.StreamIdentifier -import io.airbyte.cdk.command.OpaqueStateValue -import io.airbyte.cdk.discover.Field -import io.airbyte.cdk.discover.MetaField -import io.airbyte.cdk.discover.MetaFieldDecorator -import io.airbyte.cdk.jdbc.DefaultJdbcConstants -import io.airbyte.cdk.jdbc.IntFieldType -import io.airbyte.cdk.output.BufferingOutputConsumer -import io.airbyte.cdk.read.ConcurrencyResource -import io.airbyte.cdk.read.ConfiguredSyncMode -import io.airbyte.cdk.read.DefaultJdbcSharedState -import io.airbyte.cdk.read.Feed -import io.airbyte.cdk.read.NoOpGlobalLockResource -import io.airbyte.cdk.read.SelectQuerier -import io.airbyte.cdk.read.StateQuerier -import io.airbyte.cdk.read.Stream -import io.airbyte.cdk.read.StreamFeedBootstrap -import io.airbyte.cdk.util.Jsons -import io.airbyte.protocol.models.v0.StreamDescriptor -import io.mockk.mockk -import java.time.OffsetDateTime -import kotlin.test.assertNull -import org.junit.jupiter.api.Assertions.assertTrue -import org.junit.jupiter.api.Test - -class MysqlJdbcPartitionFactoryTest { - companion object { - private val selectQueryGenerator = MysqlSourceOperations() - private val sharedState = sharedState() - private val cdcSharedState = sharedState(global = true) - - val mysqlJdbcPartitionFactory = MysqlJdbcPartitionFactory(sharedState, selectQueryGenerator) - val mysqlCdcJdbcPartitionFactory = - MysqlJdbcPartitionFactory(cdcSharedState, selectQueryGenerator) - - val fieldId = Field("id", IntFieldType) - val stream = - Stream( - id = - StreamIdentifier.from( - StreamDescriptor().withNamespace("test").withName("stream1") - ), - schema = setOf(fieldId), - configuredSyncMode = ConfiguredSyncMode.INCREMENTAL, - configuredPrimaryKey = listOf(fieldId), - configuredCursor = fieldId, - ) - - private fun sharedState( - global: Boolean = false, - ): DefaultJdbcSharedState { - - val configSpec = - MysqlSourceConfigurationSpecification().apply { - host = "" - port = 0 - username = "foo" - password = "bar" - database = "localhost" - } - if (global) { - configSpec.setMethodValue(CdcCursor()) - } else { - configSpec.setMethodValue(UserDefinedCursor) - } - val configFactory = MysqlSourceConfigurationFactory() - val configuration = configFactory.make(configSpec) - - val mockSelectQuerier = mockk() - - return DefaultJdbcSharedState( - configuration, - mockSelectQuerier, - DefaultJdbcConstants(), - ConcurrencyResource(configuration), - NoOpGlobalLockResource() - ) - } - - private fun streamFeedBootstrap( - stream: Stream, - incumbentStateValue: OpaqueStateValue? = null - ) = - StreamFeedBootstrap( - outputConsumer = BufferingOutputConsumer(ClockFactory().fixed()), - metaFieldDecorator = - object : MetaFieldDecorator { - override val globalCursor: MetaField? = null - override val globalMetaFields: Set = emptySet() - - override fun decorateRecordData( - timestamp: OffsetDateTime, - globalStateValue: OpaqueStateValue?, - stream: Stream, - recordData: ObjectNode - ) {} - }, - stateQuerier = - object : StateQuerier { - override val feeds: List = listOf(stream) - override fun current(feed: Feed): OpaqueStateValue? = - if (feed == stream) incumbentStateValue else null - }, - stream, - ) - } - - @Test - fun testColdStartWithPkCursorBased() { - val jdbcPartition = mysqlJdbcPartitionFactory.create(streamFeedBootstrap(stream)) - assertTrue(jdbcPartition is MysqlJdbcSnapshotWithCursorPartition) - } - - @Test - fun testColdStartWithPkCdc() { - val jdbcPartition = mysqlCdcJdbcPartitionFactory.create(streamFeedBootstrap(stream)) - assertTrue(jdbcPartition is MysqlJdbcCdcSnapshotPartition) - } - - @Test - fun testColdStartWithoutPk() { - val streamWithoutPk = - Stream( - id = - StreamIdentifier.from( - StreamDescriptor().withNamespace("test").withName("stream2") - ), - schema = setOf(fieldId), - configuredSyncMode = ConfiguredSyncMode.INCREMENTAL, - configuredPrimaryKey = listOf(), - configuredCursor = fieldId, - ) - val jdbcPartition = mysqlJdbcPartitionFactory.create(streamFeedBootstrap(streamWithoutPk)) - assertTrue(jdbcPartition is MysqlJdbcNonResumableSnapshotWithCursorPartition) - } - - @Test - fun testResumeFromCompletedCursorBasedRead() { - val incomingStateValue: OpaqueStateValue = - Jsons.readTree( - """ - { - "cursor": "2", - "version": 2, - "state_type": "cursor_based", - "stream_name": "stream1", - "cursor_field": [ - "id" - ], - "stream_namespace": "test", - "cursor_record_count": 1 - } - """.trimIndent() - ) - - val jdbcPartition = - mysqlJdbcPartitionFactory.create(streamFeedBootstrap(stream, incomingStateValue)) - assertTrue(jdbcPartition is MysqlJdbcCursorIncrementalPartition) - } - - @Test - fun testResumeFromCursorBasedReadInitialRead() { - val incomingStateValue: OpaqueStateValue = - Jsons.readTree( - """ - { - "pk_val": "9063170", - "pk_name": "id", - "version": 2, - "state_type": "primary_key", - "incremental_state": {} - } - """.trimIndent() - ) - - val jdbcPartition = - mysqlJdbcPartitionFactory.create(streamFeedBootstrap(stream, incomingStateValue)) - - assertTrue(jdbcPartition is MysqlJdbcSnapshotWithCursorPartition) - } - - @Test - fun testResumeFromCdcInitialRead() { - val incomingStateValue: OpaqueStateValue = - Jsons.readTree( - """ - { - "pk_val": "29999", - "pk_name": "id", - "version": 2, - "state_type": "primary_key", - "incremental_state": {} - } - """.trimIndent() - ) - - val jdbcPartition = - mysqlCdcJdbcPartitionFactory.create(streamFeedBootstrap(stream, incomingStateValue)) - assertTrue(jdbcPartition is MysqlJdbcCdcSnapshotPartition) - } - - @Test - fun testResumeFromCdcInitialReadComplete() { - val incomingStateValue: OpaqueStateValue = - Jsons.readTree( - """ - { - "stream_name": "stream1", - "cursor_field": [], - "stream_namespace": "test" - } - """.trimIndent() - ) - - val jdbcPartition = - mysqlCdcJdbcPartitionFactory.create(streamFeedBootstrap(stream, incomingStateValue)) - assertNull(jdbcPartition) - } -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceConfigurationSpecificationTest.kt b/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceConfigurationSpecificationTest.kt deleted file mode 100644 index 4f887d2a86da..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceConfigurationSpecificationTest.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ -package io.airbyte.integrations.source.mysql - -import io.airbyte.cdk.ConfigErrorException -import io.airbyte.cdk.command.ConfigurationSpecificationSupplier -import io.airbyte.cdk.ssh.SshPasswordAuthTunnelMethod -import io.airbyte.cdk.ssh.SshTunnelMethodConfiguration -import io.micronaut.context.annotation.Property -import io.micronaut.context.env.Environment -import io.micronaut.test.extensions.junit5.annotation.MicronautTest -import jakarta.inject.Inject -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test - -@MicronautTest(environments = [Environment.TEST], rebuildContext = true) -class MysqlSourceConfigurationSpecificationTestTest { - @Inject - lateinit var supplier: ConfigurationSpecificationSupplier - - @Test - fun testSchemaViolation() { - Assertions.assertThrows(ConfigErrorException::class.java, supplier::get) - } - - @Test - @Property(name = "airbyte.connector.config.json", value = CONFIG_JSON) - fun testJson() { - val pojo: MysqlSourceConfigurationSpecification = supplier.get() - Assertions.assertEquals("localhost", pojo.host) - Assertions.assertEquals(12345, pojo.port) - Assertions.assertEquals("FOO", pojo.username) - Assertions.assertEquals("BAR", pojo.password) - Assertions.assertEquals("SYSTEM", pojo.database) - val encryption: Encryption = pojo.getEncryptionValue() - Assertions.assertTrue(encryption is EncryptionPreferred, encryption::class.toString()) - val tunnelMethod: SshTunnelMethodConfiguration = pojo.getTunnelMethodValue() - Assertions.assertTrue( - tunnelMethod is SshPasswordAuthTunnelMethod, - tunnelMethod::class.toString(), - ) - Assertions.assertEquals(60, pojo.checkpointTargetIntervalSeconds) - Assertions.assertEquals(2, pojo.concurrency) - } -} - -const val CONFIG_JSON: String = - """ -{ - "host": "localhost", - "port": 12345, - "username": "FOO", - "password": "BAR", - "database": "SYSTEM", - "ssl_mode": { - "mode": "preferred" - }, - "tunnel_method": { - "tunnel_method": "SSH_PASSWORD_AUTH", - "tunnel_host": "localhost", - "tunnel_port": 2222, - "tunnel_user": "sshuser", - "tunnel_user_password": "***" - }, - "replication_method": { - "method": "STANDARD" - }, - "checkpoint_target_interval_seconds": 60, - "jdbc_url_params": "theAnswerToLiveAndEverything=42&sessionVariables=max_execution_time=10000&foo=bar&", - "concurrency": 2 -} -""" diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceConfigurationTest.kt b/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceConfigurationTest.kt deleted file mode 100644 index 98fd548677fa..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceConfigurationTest.kt +++ /dev/null @@ -1,149 +0,0 @@ -/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ -package io.airbyte.integrations.source.mysql - -import io.airbyte.cdk.ConfigErrorException -import io.airbyte.cdk.command.AIRBYTE_CLOUD_ENV -import io.airbyte.cdk.command.ConfigurationSpecificationSupplier -import io.airbyte.cdk.command.SourceConfigurationFactory -import io.airbyte.cdk.ssh.SshNoTunnelMethod -import io.micronaut.context.annotation.Property -import io.micronaut.context.env.Environment -import io.micronaut.test.extensions.junit5.annotation.MicronautTest -import jakarta.inject.Inject -import java.time.Duration -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test - -@MicronautTest(environments = [Environment.TEST, AIRBYTE_CLOUD_ENV], rebuildContext = true) -class MysqlSourceConfigurationTest { - @Inject - lateinit var pojoSupplier: - ConfigurationSpecificationSupplier - - @Inject - lateinit var factory: - SourceConfigurationFactory - - @Test - @Property(name = "airbyte.connector.config.host", value = "localhost") - @Property(name = "airbyte.connector.config.port", value = "12345") - @Property(name = "airbyte.connector.config.username", value = "FOO") - @Property(name = "airbyte.connector.config.password", value = "BAR") - @Property(name = "airbyte.connector.config.database", value = "SYSTEM") - @Property(name = "airbyte.connector.config.ssl_mode.mode", value = "required") - @Property( - name = "airbyte.connector.config.jdbc_url_params", - value = "theAnswerToLiveAndEverything=42&sessionVariables=max_execution_time=10000&foo=bar&" - ) - fun testParseJdbcParameters() { - val pojo: MysqlSourceConfigurationSpecification = pojoSupplier.get() - - val config = factory.makeWithoutExceptionHandling(pojo) - - Assertions.assertEquals(config.realHost, "localhost") - Assertions.assertEquals(config.realPort, 12345) - Assertions.assertEquals(config.namespaces, setOf("SYSTEM")) - Assertions.assertTrue(config.sshTunnel is SshNoTunnelMethod) - - Assertions.assertEquals(config.jdbcProperties["user"], "FOO") - Assertions.assertEquals(config.jdbcProperties["password"], "BAR") - - // Make sure we don't accidentally drop the following hardcoded settings for mysql. - Assertions.assertEquals(config.jdbcProperties["useCursorFetch"], "true") - Assertions.assertEquals(config.jdbcProperties["sessionVariables"], "autocommit=0") - - Assertions.assertEquals(config.jdbcProperties["theAnswerToLiveAndEverything"], "42") - Assertions.assertEquals(config.jdbcProperties["foo"], "bar") - } - - @Test - @Property(name = "airbyte.connector.config.host", value = "localhost") - @Property(name = "airbyte.connector.config.port", value = "12345") - @Property(name = "airbyte.connector.config.username", value = "FOO") - @Property(name = "airbyte.connector.config.password", value = "BAR") - @Property(name = "airbyte.connector.config.database", value = "SYSTEM") - fun testAirbyteCloudDeployment() { - val pojo: MysqlSourceConfigurationSpecification = pojoSupplier.get() - Assertions.assertThrows(ConfigErrorException::class.java) { - factory.makeWithoutExceptionHandling(pojo) - } - } - - @Test - @Property(name = "airbyte.connector.config.json", value = CONFIG_V1) - fun testParseConfigFromV1() { - val pojo: MysqlSourceConfigurationSpecification = pojoSupplier.get() - - val config = factory.makeWithoutExceptionHandling(pojo) - - Assertions.assertEquals(config.realHost, "localhost") - Assertions.assertEquals(config.realPort, 12345) - Assertions.assertEquals(config.namespaces, setOf("SYSTEM")) - - Assertions.assertEquals(config.jdbcProperties["user"], "FOO") - Assertions.assertEquals(config.jdbcProperties["password"], "BAR") - Assertions.assertEquals(config.jdbcProperties["sslMode"], "required") - Assertions.assertTrue(config.incrementalConfiguration is CdcIncrementalConfiguration) - - val cdcCursor = config.incrementalConfiguration as CdcIncrementalConfiguration - - Assertions.assertEquals(cdcCursor.initialWaitDuration, Duration.ofSeconds(301)) - Assertions.assertEquals(cdcCursor.initialLoadTimeout, Duration.ofHours(9)) - Assertions.assertEquals( - cdcCursor.invalidCdcCursorPositionBehavior, - InvalidCdcCursorPositionBehavior.RESET_SYNC - ) - - Assertions.assertTrue(config.sshTunnel is SshNoTunnelMethod) - } -} - -const val CONFIG: String = - """ -{ - "host": "localhost", - "port": 12345, - "username": "FOO", - "password": "BAR", - "database": "SYSTEM", - "ssl_mode": { - "mode": "preferred" - }, - "tunnel_method": { - "tunnel_method": "SSH_PASSWORD_AUTH", - "tunnel_host": "localhost", - "tunnel_port": 2222, - "tunnel_user": "sshuser", - "tunnel_user_password": "***" - }, - "replication_method": { - "method": "STANDARD" - }, - "checkpoint_target_interval_seconds": 60, - "jdbc_url_params": "theAnswerToLiveAndEverything=42&sessionVariables=max_execution_time=10000&foo=bar&", - "concurrency": 2 -} -""" - -const val CONFIG_V1: String = - """ -{ - "host": "localhost", - "port": 12345, - "database": "SYSTEM", - "password": "BAR", - "ssl_mode": { - "mode": "required" - }, - "username": "FOO", - "tunnel_method": { - "tunnel_method": "NO_TUNNEL" - }, - "replication_method": { - "method": "CDC", - "initial_waiting_seconds": 301, - "initial_load_timeout_hours": 9, - "invalid_cdc_cursor_position_behavior": "Re-sync data" - } -} -""" diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceDatatypeIntegrationTest.kt b/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceDatatypeIntegrationTest.kt deleted file mode 100644 index b7d5b26f0384..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceDatatypeIntegrationTest.kt +++ /dev/null @@ -1,466 +0,0 @@ -/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ -package io.airbyte.integrations.source.mysql - -import com.fasterxml.jackson.databind.JsonNode -import io.airbyte.cdk.ClockFactory -import io.airbyte.cdk.command.CliRunner -import io.airbyte.cdk.data.AirbyteSchemaType -import io.airbyte.cdk.data.LeafAirbyteSchemaType -import io.airbyte.cdk.jdbc.JdbcConnectionFactory -import io.airbyte.cdk.output.BufferingOutputConsumer -import io.airbyte.cdk.util.Jsons -import io.airbyte.protocol.models.v0.AirbyteMessage -import io.airbyte.protocol.models.v0.AirbyteRecordMessage -import io.airbyte.protocol.models.v0.AirbyteStream -import io.airbyte.protocol.models.v0.AirbyteTraceMessage -import io.airbyte.protocol.models.v0.CatalogHelpers -import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog -import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream -import io.airbyte.protocol.models.v0.SyncMode -import io.github.oshai.kotlinlogging.KotlinLogging -import java.sql.Connection -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.DynamicContainer -import org.junit.jupiter.api.DynamicNode -import org.junit.jupiter.api.DynamicTest -import org.junit.jupiter.api.TestFactory -import org.junit.jupiter.api.Timeout -import org.testcontainers.containers.MySQLContainer - -private val log = KotlinLogging.logger {} - -class MysqlSourceDatatypeIntegrationTest { - @TestFactory - @Timeout(300) - fun syncTests(): Iterable { - val discover: DynamicNode = - DynamicTest.dynamicTest("discover") { - Assertions.assertFalse(LazyValues.actualStreams.isEmpty()) - } - val read: DynamicNode = - DynamicTest.dynamicTest("read") { - Assertions.assertFalse(LazyValues.actualReads.isEmpty()) - } - val cases: List = - allStreamNamesAndRecordData.keys.map { streamName: String -> - DynamicContainer.dynamicContainer( - streamName, - listOf( - DynamicTest.dynamicTest("discover") { discover(streamName) }, - DynamicTest.dynamicTest("records") { records(streamName) }, - ), - ) - } - return listOf(discover, read) + cases - } - - object LazyValues { - val actualStreams: Map by lazy { - val output: BufferingOutputConsumer = CliRunner.source("discover", config()).run() - output.catalogs().firstOrNull()?.streams?.filterNotNull()?.associateBy { it.name } - ?: mapOf() - } - - val configuredCatalog: ConfiguredAirbyteCatalog by lazy { - val configuredStreams: List = - allStreamNamesAndRecordData.keys - .mapNotNull { actualStreams[it] } - .map(CatalogHelpers::toDefaultConfiguredStream) - for (configuredStream in configuredStreams) { - if (configuredStream.stream.supportedSyncModes.contains(SyncMode.INCREMENTAL)) { - configuredStream.syncMode = SyncMode.INCREMENTAL - } - } - ConfiguredAirbyteCatalog().withStreams(configuredStreams) - } - - val allReadMessages: List by lazy { - CliRunner.source("read", config(), configuredCatalog).run().messages() - } - - val actualReads: Map by lazy { - val result: Map = - allStreamNamesAndRecordData.keys.associateWith { - BufferingOutputConsumer(ClockFactory().fixed()) - } - for (msg in allReadMessages) { - result[streamName(msg) ?: continue]?.accept(msg) - } - result - } - - fun streamName(msg: AirbyteMessage): String? = - when (msg.type) { - AirbyteMessage.Type.RECORD -> msg.record?.stream - AirbyteMessage.Type.STATE -> msg.state?.stream?.streamDescriptor?.name - AirbyteMessage.Type.TRACE -> - when (msg.trace?.type) { - AirbyteTraceMessage.Type.ERROR -> msg.trace?.error?.streamDescriptor?.name - AirbyteTraceMessage.Type.ESTIMATE -> msg.trace?.estimate?.name - AirbyteTraceMessage.Type.STREAM_STATUS -> - msg.trace?.streamStatus?.streamDescriptor?.name - AirbyteTraceMessage.Type.ANALYTICS -> null - null -> null - } - else -> null - } - } - - private fun discover(streamName: String) { - val actualStream: AirbyteStream? = LazyValues.actualStreams[streamName] - log.info { "discover result: ${LazyValues.actualStreams}" } - log.info { "streamName: $streamName" } - Assertions.assertNotNull(actualStream) - log.info { - "test case $streamName: discovered stream ${ - Jsons.valueToTree( - actualStream, - ) - }" - } - val testCase: TestCase = - testCases.find { it.streamNamesToRecordData.keys.contains(streamName) }!! - val isIncrementalSupported: Boolean = - actualStream!!.supportedSyncModes.contains(SyncMode.INCREMENTAL) - val jsonSchema: JsonNode = actualStream.jsonSchema?.get("properties")!! - if (streamName == testCase.tableName) { - val actualSchema: JsonNode = jsonSchema[testCase.columnName] - Assertions.assertNotNull(actualSchema) - val expectedSchema: JsonNode = testCase.airbyteSchemaType.asJsonSchema() - Assertions.assertEquals(expectedSchema, actualSchema) - if (testCase.cursor) { - Assertions.assertTrue(isIncrementalSupported) - } else { - Assertions.assertFalse(isIncrementalSupported) - } - } - } - - private fun records(streamName: String) { - val actualRead: BufferingOutputConsumer? = LazyValues.actualReads[streamName] - Assertions.assertNotNull(actualRead) - - fun sortedRecordData(data: List): JsonNode = - Jsons.createArrayNode().apply { addAll(data.sortedBy { it.toString() }) } - - val actualRecords: List = actualRead?.records() ?: listOf() - - val actual: JsonNode = sortedRecordData(actualRecords.mapNotNull { it.data }) - log.info { "test case $streamName: emitted records $actual" } - val expected: JsonNode = sortedRecordData(allStreamNamesAndRecordData[streamName]!!) - - Assertions.assertEquals(expected, actual) - } - - companion object { - lateinit var dbContainer: MySQLContainer<*> - - fun config(): MysqlSourceConfigurationSpecification = - MysqlContainerFactory.config(dbContainer) - - val connectionFactory: JdbcConnectionFactory by lazy { - JdbcConnectionFactory(MysqlSourceConfigurationFactory().make(config())) - } - - val bitValues = - mapOf( - "b'1'" to "true", - "b'0'" to "false", - ) - - val longBitValues = - mapOf( - "b'10101010'" to """-86""", - ) - - val stringValues = - mapOf( - "'abcdef'" to """"abcdef"""", - "'ABCD'" to """"ABCD"""", - "'OXBEEF'" to """"OXBEEF"""", - ) - - val jsonValues = mapOf("""'{"col1": "v1"}'""" to """"{\"col1\": \"v1\"}"""") - - val yearValues = - mapOf( - "1992" to """1992""", - "2002" to """2002""", - "70" to """1970""", - ) - - val decimalValues = - mapOf( - "0.2" to """0.2""", - ) - - val zeroPrecisionDecimalValues = - mapOf( - "2" to """2""", - ) - - val tinyintValues = - mapOf( - "10" to "10", - "4" to "4", - "2" to "2", - ) - - val intValues = - mapOf( - "10" to "10", - "100000000" to "100000000", - "200000000" to "200000000", - ) - - val dateValues = - mapOf( - "'2022-01-01'" to """"2022-01-01"""", - ) - - val timeValues = - mapOf( - "'14:30:00'" to """"14:30:00.000000"""", - ) - - val dateTimeValues = - mapOf( - "'2024-09-13 14:30:00'" to """"2024-09-13T14:30:00.000000"""", - "'2024-09-13T14:40:00+00:00'" to """"2024-09-13T14:40:00.000000"""" - ) - - val timestampValues = - mapOf( - "'2024-09-12 14:30:00'" to """"2024-09-12T14:30:00.000000Z"""", - "CONVERT_TZ('2024-09-12 14:30:00', 'America/Los_Angeles', 'UTC')" to - """"2024-09-12T21:30:00.000000Z"""", - ) - - val booleanValues = - mapOf( - "TRUE" to "true", - "FALSE" to "false", - ) - - val enumValues = - mapOf( - "'a'" to """"a"""", - "'b'" to """"b"""", - "'c'" to """"c"""", - ) - - // Encoded into base64 - val binaryValues = - mapOf( - "X'89504E470D0A1A0A0000000D49484452'" to """"iVBORw0KGgoAAAANSUhEUg=="""", - ) - - val testCases: List = - listOf( - TestCase( - "BOOLEAN", - booleanValues, - airbyteSchemaType = LeafAirbyteSchemaType.BOOLEAN, - cursor = false - ), - TestCase( - "VARCHAR(10)", - stringValues, - airbyteSchemaType = LeafAirbyteSchemaType.STRING - ), - TestCase( - "DECIMAL(10,2)", - decimalValues, - airbyteSchemaType = LeafAirbyteSchemaType.NUMBER - ), - TestCase( - "DECIMAL(10,2) UNSIGNED", - decimalValues, - airbyteSchemaType = LeafAirbyteSchemaType.NUMBER - ), - TestCase( - "DECIMAL UNSIGNED", - zeroPrecisionDecimalValues, - airbyteSchemaType = LeafAirbyteSchemaType.INTEGER - ), - TestCase("FLOAT", decimalValues, airbyteSchemaType = LeafAirbyteSchemaType.NUMBER), - TestCase( - "FLOAT(7,4)", - decimalValues, - airbyteSchemaType = LeafAirbyteSchemaType.NUMBER - ), - TestCase( - "FLOAT(53,8)", - decimalValues, - airbyteSchemaType = LeafAirbyteSchemaType.NUMBER - ), - TestCase("DOUBLE", decimalValues, airbyteSchemaType = LeafAirbyteSchemaType.NUMBER), - TestCase( - "DOUBLE UNSIGNED", - decimalValues, - airbyteSchemaType = LeafAirbyteSchemaType.NUMBER - ), - TestCase( - "TINYINT", - tinyintValues, - airbyteSchemaType = LeafAirbyteSchemaType.INTEGER - ), - TestCase( - "TINYINT UNSIGNED", - tinyintValues, - airbyteSchemaType = LeafAirbyteSchemaType.INTEGER - ), - TestCase( - "SMALLINT", - tinyintValues, - airbyteSchemaType = LeafAirbyteSchemaType.INTEGER - ), - TestCase( - "MEDIUMINT", - tinyintValues, - airbyteSchemaType = LeafAirbyteSchemaType.INTEGER - ), - TestCase("BIGINT", intValues, airbyteSchemaType = LeafAirbyteSchemaType.INTEGER), - TestCase( - "SMALLINT UNSIGNED", - tinyintValues, - airbyteSchemaType = LeafAirbyteSchemaType.INTEGER - ), - TestCase( - "MEDIUMINT UNSIGNED", - tinyintValues, - airbyteSchemaType = LeafAirbyteSchemaType.INTEGER - ), - TestCase( - "BIGINT UNSIGNED", - intValues, - airbyteSchemaType = LeafAirbyteSchemaType.INTEGER - ), - TestCase("INT", intValues, airbyteSchemaType = LeafAirbyteSchemaType.INTEGER), - TestCase( - "INT UNSIGNED", - intValues, - airbyteSchemaType = LeafAirbyteSchemaType.INTEGER - ), - TestCase("DATE", dateValues, airbyteSchemaType = LeafAirbyteSchemaType.DATE), - TestCase( - "TIMESTAMP", - timestampValues, - airbyteSchemaType = LeafAirbyteSchemaType.TIMESTAMP_WITH_TIMEZONE - ), - TestCase( - "DATETIME", - dateTimeValues, - airbyteSchemaType = LeafAirbyteSchemaType.TIMESTAMP_WITHOUT_TIMEZONE - ), - TestCase( - "TIME", - timeValues, - airbyteSchemaType = LeafAirbyteSchemaType.TIME_WITHOUT_TIMEZONE - ), - TestCase("YEAR", yearValues, airbyteSchemaType = LeafAirbyteSchemaType.INTEGER), - TestCase( - "VARBINARY(255)", - binaryValues, - airbyteSchemaType = LeafAirbyteSchemaType.BINARY, - cursor = false, - noPK = true - ), - TestCase( - "BIT", - bitValues, - airbyteSchemaType = LeafAirbyteSchemaType.BOOLEAN, - cursor = false - ), - TestCase( - "BIT(8)", - longBitValues, - airbyteSchemaType = LeafAirbyteSchemaType.INTEGER - ), - TestCase( - "JSON", - jsonValues, - airbyteSchemaType = LeafAirbyteSchemaType.STRING, - noPK = true - ), - TestCase( - "ENUM('a', 'b', 'c')", - enumValues, - airbyteSchemaType = LeafAirbyteSchemaType.STRING, - noPK = true - ), - ) - - val allStreamNamesAndRecordData: Map> = - testCases.flatMap { it.streamNamesToRecordData.toList() }.toMap() - - @JvmStatic - @BeforeAll - @Timeout(value = 300) - fun startAndProvisionTestContainer() { - dbContainer = - MysqlContainerFactory.exclusive( - "mysql:8.0", - MysqlContainerFactory.WithNetwork, - ) - connectionFactory - .get() - .also { it.isReadOnly = false } - .use { connection: Connection -> - for (case in testCases) { - for (sql in case.sqlStatements) { - log.info { "test case ${case.id}: executing $sql" } - connection.createStatement().use { stmt -> stmt.execute(sql) } - } - } - } - } - } - - data class TestCase( - val sqlType: String, - val sqlToAirbyte: Map, - val airbyteSchemaType: AirbyteSchemaType = LeafAirbyteSchemaType.STRING, - val cursor: Boolean = true, - val noPK: Boolean = false, - val customDDL: List? = null, - ) { - val id: String - get() = - sqlType - .replace("[^a-zA-Z0-9]".toRegex(), " ") - .trim() - .replace(" +".toRegex(), "_") - .lowercase() - - val tableName: String - get() = "tbl_$id" - - val columnName: String - get() = "col_$id" - - val sqlStatements: List - get() { - val ddl: List = - listOf( - "CREATE DATABASE IF NOT EXISTS test", - "USE test", - "CREATE TABLE IF NOT EXISTS $tableName " + - "($columnName $sqlType ${if (noPK) "" else "PRIMARY KEY"})", - "TRUNCATE TABLE $tableName", - ) - val dml: List = - sqlToAirbyte.keys.map { "INSERT INTO $tableName ($columnName) VALUES ($it)" } - - return ddl + dml - } - - val streamNamesToRecordData: Map> - get() { - val recordData: List = - sqlToAirbyte.values.map { Jsons.readTree("""{"${columnName}":$it}""") } - return mapOf(tableName to recordData) - } - } -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceSelectQueryGeneratorTest.kt b/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceSelectQueryGeneratorTest.kt deleted file mode 100644 index 14fb19b67917..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceSelectQueryGeneratorTest.kt +++ /dev/null @@ -1,145 +0,0 @@ -/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ -package io.airbyte.integrations.source.mysql - -import com.fasterxml.jackson.databind.JsonNode -import io.airbyte.cdk.discover.Field -import io.airbyte.cdk.jdbc.DoubleFieldType -import io.airbyte.cdk.jdbc.IntFieldType -import io.airbyte.cdk.jdbc.LongFieldType -import io.airbyte.cdk.jdbc.LosslessJdbcFieldType -import io.airbyte.cdk.jdbc.OffsetDateTimeFieldType -import io.airbyte.cdk.jdbc.StringFieldType -import io.airbyte.cdk.read.And -import io.airbyte.cdk.read.Equal -import io.airbyte.cdk.read.From -import io.airbyte.cdk.read.Greater -import io.airbyte.cdk.read.LesserOrEqual -import io.airbyte.cdk.read.Limit -import io.airbyte.cdk.read.Or -import io.airbyte.cdk.read.OrderBy -import io.airbyte.cdk.read.SelectColumnMaxValue -import io.airbyte.cdk.read.SelectColumns -import io.airbyte.cdk.read.SelectQuery -import io.airbyte.cdk.read.SelectQuerySpec -import io.airbyte.cdk.read.Where -import io.airbyte.cdk.read.optimize -import io.airbyte.cdk.util.Jsons -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test - -class MysqlSourceSelectQueryGeneratorTest { - @Test - fun testSelectLimit0() { - SelectQuerySpec( - SelectColumns( - listOf( - Field("k", IntFieldType), - Field("v", StringFieldType), - ), - ), - From("TBL", "SC"), - limit = Limit(0), - ) - .assertSqlEquals("""SELECT `k`, `v` FROM `SC`.`TBL` LIMIT 0""") - } - - @Test - fun testSelectMaxCursor() { - SelectQuerySpec( - SelectColumnMaxValue(Field("ts", OffsetDateTimeFieldType)), - From("TBL", "SC"), - ) - .assertSqlEquals("""SELECT MAX(`ts`) FROM `SC`.`TBL`""") - } - - @Test - fun testSelectForNonResumableInitialSync() { - SelectQuerySpec( - SelectColumns( - listOf( - Field("k", IntFieldType), - Field("v", StringFieldType), - ), - ), - From("TBL", "SC"), - ) - .assertSqlEquals("""SELECT `k`, `v` FROM `SC`.`TBL`""") - } - - @Test - fun testSelectForResumableInitialSync() { - val k1 = Field("k1", IntFieldType) - val v1 = Jsons.numberNode(10) - val k2 = Field("k2", IntFieldType) - val v2 = Jsons.numberNode(20) - val k3 = Field("k3", IntFieldType) - val v3 = Jsons.numberNode(30) - SelectQuerySpec( - SelectColumns(listOf(k1, k2, k3, Field("msg", StringFieldType))), - From("TBL", "SC"), - Where( - Or( - listOf( - And(listOf(Greater(k1, v1))), - And(listOf(Equal(k1, v1), Greater(k2, v2))), - And(listOf(Equal(k1, v1), Equal(k2, v2), Greater(k3, v3))), - ), - ), - ), - OrderBy(listOf(k1, k2, k3)), - Limit(1000), - ) - .assertSqlEquals( - """SELECT `k1`, `k2`, `k3`, `msg` FROM """ + - """`SC`.`TBL` WHERE (`k1` > ?) OR """ + - """((`k1` = ?) AND (`k2` > ?)) OR """ + - """((`k1` = ?) AND (`k2` = ?) AND (`k3` > ?)) """ + - """ORDER BY `k1`, `k2`, `k3`""" + - " LIMIT ?", - v1 to IntFieldType, - v1 to IntFieldType, - v2 to IntFieldType, - v1 to IntFieldType, - v2 to IntFieldType, - v3 to IntFieldType, - Jsons.numberNode(1000L) to LongFieldType, - ) - } - - @Test - fun testSelectForCursorBasedIncrementalSync() { - val c = Field("c", DoubleFieldType) - val lb = Jsons.numberNode(0.5) - val ub = Jsons.numberNode(0.5) - SelectQuerySpec( - SelectColumns(listOf(Field("msg", StringFieldType), c)), - From("TBL", "SC"), - Where(And(listOf(Greater(c, lb), LesserOrEqual(c, ub)))), - OrderBy(listOf(c)), - Limit(1000), - ) - .assertSqlEquals( - """SELECT `msg`, `c` FROM """ + - """`SC`.`TBL` """ + - """WHERE (`c` > ?) AND (`c` <= ?) ORDER BY `c`""" + - " LIMIT ?", - lb to DoubleFieldType, - ub to DoubleFieldType, - Jsons.numberNode(1000L) to LongFieldType, - ) - } - - private fun SelectQuerySpec.assertSqlEquals( - sql: String, - vararg bindings: Pair>, - ) { - val expected = - SelectQuery( - sql, - select.columns, - bindings.map { SelectQuery.Binding(it.first, it.second) }, - ) - val actual: SelectQuery = MysqlSourceOperations().generate(this.optimize()) - Assertions.assertEquals(expected, actual) - } -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceTestConfigurationFactory.kt b/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceTestConfigurationFactory.kt deleted file mode 100644 index 60930cb82823..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSourceTestConfigurationFactory.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ -package io.airbyte.integrations.source.mysql - -import io.airbyte.cdk.command.FeatureFlag -import io.airbyte.cdk.command.SourceConfigurationFactory -import io.micronaut.context.annotation.Primary -import io.micronaut.context.annotation.Requires -import io.micronaut.context.env.Environment -import jakarta.inject.Singleton -import java.time.Duration - -@Singleton -@Requires(env = [Environment.TEST]) -@Primary -class MysqlSourceTestConfigurationFactory(val featureFlags: Set) : - SourceConfigurationFactory { - override fun makeWithoutExceptionHandling( - pojo: MysqlSourceConfigurationSpecification, - ): MysqlSourceConfiguration = - MysqlSourceConfigurationFactory(featureFlags) - .makeWithoutExceptionHandling(pojo) - .copy( - maxConcurrency = 1, - checkpointTargetInterval = Duration.ofSeconds(3), - debeziumHeartbeatInterval = Duration.ofMillis(100), - debeziumKeepAliveInterval = Duration.ofSeconds(1), - ) -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSpecIntegrationTest.kt b/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSpecIntegrationTest.kt deleted file mode 100644 index 63a29db649b6..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/test/kotlin/io/airbyte/integrations/source/mysql/MysqlSpecIntegrationTest.kt +++ /dev/null @@ -1,12 +0,0 @@ -/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ -package io.airbyte.integrations.source.mysql - -import io.airbyte.cdk.command.SyncsTestFixture -import org.junit.jupiter.api.Test - -class MysqlSpecIntegrationTest { - @Test - fun testSpec() { - SyncsTestFixture.testSpec("expected-spec.json") - } -} diff --git a/airbyte-integrations/connectors/source-mysql-v2/src/test/resources/expected-spec.json b/airbyte-integrations/connectors/source-mysql-v2/src/test/resources/expected-spec.json deleted file mode 100644 index dd46104f416b..000000000000 --- a/airbyte-integrations/connectors/source-mysql-v2/src/test/resources/expected-spec.json +++ /dev/null @@ -1,399 +0,0 @@ -{ - "documentationUrl": "https://docs.airbyte.com/integrations/sources/mysql", - "connectionSpecification": { - "type": "object", - "title": "Mysql Source Spec", - "$schema": "http://json-schema.org/draft-07/schema#", - "required": [ - "host", - "port", - "database", - "username", - "tunnel_method", - "ssl_mode", - "replication_method" - ], - "properties": { - "host": { - "type": "string", - "order": 1, - "title": "Host", - "description": "Hostname of the database." - }, - "port": { - "type": "integer", - "order": 2, - "title": "Port", - "default": 3306, - "maximum": 65536, - "minimum": 0, - "description": "Port of the database." - }, - "database": { - "type": "string", - "order": 6, - "title": "Database", - "always_show": true, - "description": "The database name." - }, - "password": { - "type": "string", - "order": 5, - "title": "Password", - "always_show": true, - "description": "The password associated with the username.", - "airbyte_secret": true - }, - "ssl_mode": { - "type": "object", - "oneOf": [ - { - "type": "object", - "title": "preferred", - "required": ["mode"], - "properties": { - "mode": { - "enum": ["preferred"], - "type": "string", - "default": "preferred" - } - }, - "description": "To allow unencrypted communication only when the source doesn't support encryption.", - "additionalProperties": true - }, - { - "type": "object", - "title": "required", - "required": ["mode"], - "properties": { - "mode": { - "enum": ["required"], - "type": "string", - "default": "required" - } - }, - "description": "To always require encryption. Note: The connection will fail if the source doesn't support encryption.", - "additionalProperties": true - }, - { - "type": "object", - "title": "verify_ca", - "required": ["mode", "ca_certificate"], - "properties": { - "mode": { - "enum": ["verify_ca"], - "type": "string", - "default": "verify_ca" - }, - "client_key": { - "type": "string", - "title": "Client Key", - "multiline": true, - "description": "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", - "airbyte_secret": true - }, - "ca_certificate": { - "type": "string", - "title": "CA certificate", - "multiline": true, - "description": "CA certificate", - "airbyte_secret": true - }, - "client_certificate": { - "type": "string", - "title": "Client certificate File", - "multiline": true, - "description": "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", - "airbyte_secret": true - }, - "client_key_password": { - "type": "string", - "title": "Client key password", - "multiline": true, - "description": "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", - "airbyte_secret": true - } - }, - "description": "To always require encryption and verify that the source has a valid SSL certificate.", - "additionalProperties": true - }, - { - "type": "object", - "title": "verify_identity", - "required": ["mode", "ca_certificate"], - "properties": { - "mode": { - "enum": ["verify_identity"], - "type": "string", - "default": "verify_identity" - }, - "client_key": { - "type": "string", - "title": "Client Key", - "multiline": true, - "description": "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", - "airbyte_secret": true - }, - "ca_certificate": { - "type": "string", - "title": "CA certificate", - "multiline": true, - "description": "CA certificate", - "airbyte_secret": true - }, - "client_certificate": { - "type": "string", - "title": "Client certificate File", - "multiline": true, - "description": "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", - "airbyte_secret": true - }, - "client_key_password": { - "type": "string", - "title": "Client key password", - "multiline": true, - "description": "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", - "airbyte_secret": true - } - }, - "description": "To always require encryption and verify that the source has a valid SSL certificate.", - "additionalProperties": true - } - ], - "order": 8, - "title": "Encryption", - "description": "The encryption method with is used when communicating with the database." - }, - "username": { - "type": "string", - "order": 4, - "title": "User", - "description": "The username which is used to access the database." - }, - "concurrency": { - "type": "integer", - "order": 12, - "title": "Concurrency", - "default": 1, - "description": "Maximum number of concurrent queries to the database." - }, - "tunnel_method": { - "type": "object", - "oneOf": [ - { - "type": "object", - "title": "No Tunnel", - "required": ["tunnel_method"], - "properties": { - "tunnel_method": { - "enum": ["NO_TUNNEL"], - "type": "string", - "default": "NO_TUNNEL" - } - }, - "description": "No ssh tunnel needed to connect to database", - "additionalProperties": true - }, - { - "type": "object", - "title": "SSH Key Authentication", - "required": [ - "tunnel_method", - "tunnel_host", - "tunnel_port", - "tunnel_user", - "ssh_key" - ], - "properties": { - "ssh_key": { - "type": "string", - "order": 4, - "title": "SSH Private Key", - "multiline": true, - "description": "OS-level user account ssh key credentials in RSA PEM format ( created with ssh-keygen -t rsa -m PEM -f myuser_rsa )", - "airbyte_secret": true - }, - "tunnel_host": { - "type": "string", - "order": 1, - "title": "SSH Tunnel Jump Server Host", - "description": "Hostname of the jump server host that allows inbound ssh tunnel." - }, - "tunnel_port": { - "type": "integer", - "order": 2, - "title": "SSH Connection Port", - "default": 22, - "maximum": 65536, - "minimum": 0, - "description": "Port on the proxy/jump server that accepts inbound ssh connections." - }, - "tunnel_user": { - "type": "string", - "order": 3, - "title": "SSH Login Username", - "description": "OS-level username for logging into the jump server host" - }, - "tunnel_method": { - "enum": ["SSH_KEY_AUTH"], - "type": "string", - "default": "SSH_KEY_AUTH" - } - }, - "description": "Connect through a jump server tunnel host using username and ssh key", - "additionalProperties": true - }, - { - "type": "object", - "title": "Password Authentication", - "required": [ - "tunnel_method", - "tunnel_host", - "tunnel_port", - "tunnel_user", - "tunnel_user_password" - ], - "properties": { - "tunnel_host": { - "type": "string", - "order": 1, - "title": "SSH Tunnel Jump Server Host", - "description": "Hostname of the jump server host that allows inbound ssh tunnel." - }, - "tunnel_port": { - "type": "integer", - "order": 2, - "title": "SSH Connection Port", - "default": 22, - "maximum": 65536, - "minimum": 0, - "description": "Port on the proxy/jump server that accepts inbound ssh connections." - }, - "tunnel_user": { - "type": "string", - "order": 3, - "title": "SSH Login Username", - "description": "OS-level username for logging into the jump server host" - }, - "tunnel_method": { - "enum": ["SSH_PASSWORD_AUTH"], - "type": "string", - "default": "SSH_PASSWORD_AUTH" - }, - "tunnel_user_password": { - "type": "string", - "order": 4, - "title": "Password", - "description": "OS-level password for logging into the jump server host", - "airbyte_secret": true - } - }, - "description": "Connect through a jump server tunnel host using username and password authentication", - "additionalProperties": true - } - ], - "order": 9, - "title": "SSH Tunnel Method", - "description": "Whether to initiate an SSH tunnel before connecting to the database, and if so, which kind of authentication to use." - }, - "jdbc_url_params": { - "type": "string", - "order": 7, - "title": "JDBC URL Params", - "description": "Additional properties to pass to the JDBC URL string when connecting to the database formatted as 'key=value' pairs separated by the symbol '&'. (example: key1=value1&key2=value2&key3=value3)." - }, - "check_privileges": { - "type": "boolean", - "order": 13, - "title": "Check Table and Column Access Privileges", - "default": true, - "description": "When this feature is enabled, during schema discovery the connector will query each table or view individually to check access privileges and inaccessible tables, views, or columns therein will be removed. In large schemas, this might cause schema discovery to take too long, in which case it might be advisable to disable this feature.", - "display_type": "check" - }, - "replication_method": { - "type": "object", - "oneOf": [ - { - "type": "object", - "title": "Scan Changes with User Defined Cursor", - "required": ["method"], - "properties": { - "method": { - "enum": ["STANDARD"], - "type": "string", - "default": "STANDARD" - } - }, - "description": "Incrementally detects new inserts and updates using the cursor column chosen when configuring a connection (e.g. created_at, updated_at).", - "additionalProperties": true - }, - { - "type": "object", - "title": "Read Changes using Change Data Capture (CDC)", - "required": ["method"], - "properties": { - "method": { - "enum": ["CDC"], - "type": "string", - "default": "CDC" - }, - "server_timezone": { - "type": "string", - "order": 2, - "title": "Configured server timezone for the MySQL source (Advanced)", - "always_show": true, - "description": "Enter the configured MySQL server timezone. This should only be done if the configured timezone in your MySQL instance does not conform to IANNA standard." - }, - "initial_waiting_seconds": { - "max": 1200, - "min": 120, - "type": "integer", - "order": 1, - "title": "Initial Waiting Time in Seconds (Advanced)", - "default": 300, - "always_show": true, - "description": "The amount of time the connector will wait when it launches to determine if there is new data to sync or not. Defaults to 300 seconds. Valid range: 120 seconds to 1200 seconds. Read about initial waiting time." - }, - "initial_load_timeout_hours": { - "max": 24, - "min": 4, - "type": "integer", - "order": 4, - "title": "Initial Load Timeout in Hours (Advanced)", - "default": 8, - "always_show": true, - "description": "The amount of time an initial load is allowed to continue for before catching up on CDC logs." - }, - "invalid_cdc_cursor_position_behavior": { - "enum": ["Fail sync", "Re-sync data"], - "default": "Fail sync", - "type": "string", - "order": 3, - "title": "Configured server timezone for the MySQL source (Advanced)", - "always_show": true, - "description": "Enter the configured MySQL server timezone. This should only be done if the configured timezone in your MySQL instance does not conform to IANNA standard." - } - }, - "description": "Recommended - Incrementally reads new inserts, updates, and deletes using Mysql's change data capture feature. This must be enabled on your database.", - "additionalProperties": true - } - ], - "order": 10, - "title": "Update Method", - "description": "Configures how data is extracted from the database.", - "display_type": "radio" - }, - "checkpoint_target_interval_seconds": { - "type": "integer", - "order": 11, - "title": "Checkpoint Target Time Interval", - "default": 300, - "description": "How often (in seconds) a stream should checkpoint, when possible." - } - }, - "additionalProperties": true - }, - "supportsNormalization": false, - "supportsDBT": false, - "supported_destination_sync_modes": [] -} diff --git a/airbyte-integrations/connectors/source-mysql/acceptance-test-config.yml b/airbyte-integrations/connectors/source-mysql/acceptance-test-config.yml index 575c91b8bb87..0a2250b6100d 100644 --- a/airbyte-integrations/connectors/source-mysql/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-mysql/acceptance-test-config.yml @@ -1,10 +1,95 @@ # See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) # for more information about how to configure these tests -connector_image: airbyte/source-mysql:dev -tests: +connector_image: airbyte/source-mysql-v2:dev +custom_environment_variables: + USE_STREAM_CAPABLE_STATE: true +acceptance_tests: + client_container_config: + client_container_dockerfile_path: "integration_tests/Dockerfile" + final_teardown_command: + - "python" + - "./hook.py" + - "final_teardown" spec: - - spec_path: "src/test-integration/resources/expected_oss_spec.json" - config_path: "src/test-integration/resources/dummy_config.json" - - deployment_mode: cloud - spec_path: "src/test-integration/resources/expected_cloud_spec.json" - config_path: "src/test-integration/resources/dummy_config.json" + tests: + - spec_path: "src/test/resources/expected-spec.json" + config_path: "secrets/cat-config.json" + connection: + tests: + - config_path: "secrets/cat-config.json" + status: "succeed" + discovery: + tests: + - config_path: "secrets/cat-config.json" + basic_read: + tests: + - config_path: "integration_tests/temp/config_active.json" + configured_catalog_path: "integration_tests/temp/configured_catalog_copy.json" + expect_records: + path: "integration_tests/expected_records.txt" + client_container_config: + client_container_dockerfile_path: "integration_tests/Dockerfile" + secrets_path: "secrets/cat-config.json" + setup_command: + - "python" + - "./hook.py" + - "setup" + teardown_command: + - "python" + - "./hook.py" + - "teardown" + full_refresh: + tests: + - config_path: "integration_tests/temp/config_active.json" + configured_catalog_path: "integration_tests/temp/configured_catalog_copy.json" + client_container_config: + client_container_dockerfile_path: "integration_tests/Dockerfile" + secrets_path: "secrets/cat-config.json" + setup_command: + - "python" + - "./hook.py" + - "setup" + teardown_command: + - "python" + - "./hook.py" + - "teardown" + incremental: + tests: + - config_path: "integration_tests/temp/config_active.json" + configured_catalog_path: "integration_tests/temp/incremental_configured_catalog_copy.json" + client_container_config: + client_container_dockerfile_path: "integration_tests/Dockerfile" + secrets_path: "secrets/cat-config.json" + setup_command: + - "python" + - "./hook.py" + - "setup" + teardown_command: + - "python" + - "./hook.py" + - "teardown" + between_syncs_command: + - "python" + - "./hook.py" + - "insert" + future_state: + future_state_path: "integration_tests/temp/abnormal_state_copy.json" + - config_path: "integration_tests/temp/config_cdc_active.json" + configured_catalog_path: "integration_tests/temp/incremental_configured_catalog_copy.json" + client_container_config: + client_container_dockerfile_path: "integration_tests/Dockerfile" + secrets_path: "secrets/cat-config-cdc.json" + setup_command: + - "python" + - "./hook.py" + - "setup_cdc" + between_syncs_command: + - "python" + - "./hook.py" + - "insert" + teardown_command: + - "python" + - "./hook.py" + - "teardown" + future_state: + bypass_reason: "CDC does not have a future state as LSN will be absent from DB, triggering a full refresh" diff --git a/airbyte-integrations/connectors/source-mysql/build.gradle b/airbyte-integrations/connectors/source-mysql/build.gradle index 3cdd608a6048..b65ad18b6304 100644 --- a/airbyte-integrations/connectors/source-mysql/build.gradle +++ b/airbyte-integrations/connectors/source-mysql/build.gradle @@ -1,54 +1,21 @@ -import org.jsonschema2pojo.SourceType - plugins { - id 'airbyte-java-connector' - id 'org.jsonschema2pojo' version '1.2.1' -} - -airbyteJavaConnector { - cdkVersionRequired = '0.45.1' - features = ['db-sources'] - useLocalCdk = false -} - -java { - compileJava { - options.compilerArgs += "-Xlint:-try,-rawtypes" - } + id 'airbyte-bulk-connector' } application { mainClass = 'io.airbyte.integrations.source.mysql.MySqlSource' - applicationDefaultJvmArgs = ['-XX:+ExitOnOutOfMemoryError', '-XX:MaxRAMPercentage=75.0'] } -dependencies { - implementation 'mysql:mysql-connector-java:8.0.30' - implementation 'io.debezium:debezium-embedded:2.7.1.Final' - implementation 'io.debezium:debezium-connector-mysql:2.7.1.Final' - - testFixturesImplementation 'org.testcontainers:mysql:1.19.0' - - testImplementation 'org.hamcrest:hamcrest-all:1.3' - testImplementation 'org.testcontainers:mysql:1.19.0' +airbyteBulkConnector { + core = 'extract' + toolkits = ['extract-jdbc', 'extract-cdc'] + cdk = '0.257' } -jsonSchema2Pojo { - sourceType = SourceType.YAMLSCHEMA - source = files("${sourceSets.main.output.resourcesDir}/internal_models") - targetDirectory = new File(project.buildDir, 'generated/src/gen/java/') - removeOldOutput = true - - targetPackage = 'io.airbyte.integrations.source.mysql.internal.models' - - useLongIntegers = true - generateBuilders = true - includeConstructors = false - includeSetters = true -} +dependencies { + implementation 'com.mysql:mysql-connector-j:9.1.0' + implementation 'io.debezium:debezium-connector-mysql' -compileKotlin { - dependsOn { - generateJsonSchema2Pojo - } + testImplementation 'org.testcontainers:mysql' + testImplementation 'io.mockk:mockk:1.12.0' } diff --git a/airbyte-integrations/connectors/source-mysql/gradle.properties b/airbyte-integrations/connectors/source-mysql/gradle.properties index 8ef098d20b92..04dcba8cefd7 100644 --- a/airbyte-integrations/connectors/source-mysql/gradle.properties +++ b/airbyte-integrations/connectors/source-mysql/gradle.properties @@ -1 +1,2 @@ -testExecutionConcurrency=-1 \ No newline at end of file +testExecutionConcurrency=1 +JunitMethodExecutionTimeout=5m \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-mysql/integration_tests/Dockerfile b/airbyte-integrations/connectors/source-mysql/integration_tests/Dockerfile new file mode 100644 index 000000000000..31a7e649b4f5 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/integration_tests/Dockerfile @@ -0,0 +1,13 @@ +# Use a base image with MySQL client +FROM python:3.9 + +WORKDIR /usr/src/app + +# Copy the script to the container and install the requirements. +COPY seed/requirements.txt . +RUN pip install --no-cache-dir -r ./requirements.txt +COPY seed/hook.py . + +# Give execution rights to the script and pre-generate all scripts. +RUN chmod +x ./hook.py +RUN python ./hook.py prepare \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-mysql/integration_tests/abnormal_state_template.json b/airbyte-integrations/connectors/source-mysql/integration_tests/abnormal_state_template.json new file mode 100644 index 000000000000..a17c2c6041c8 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/integration_tests/abnormal_state_template.json @@ -0,0 +1,20 @@ +[ + { + "type": "STREAM", + "stream": { + "stream_state": { + "version": 2, + "state_type": "cursor_based", + "stream_name": "id_and_name_cat", + "cursor_field": ["id"], + "cursor": "6", + "cursor_record_count": 1, + "stream_namespace": "%s" + }, + "stream_descriptor": { + "name": "id_and_name_cat", + "namespace": "%s" + } + } + } +] diff --git a/airbyte-integrations/connectors/source-mysql/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-mysql/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-mysql/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-mysql/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-mysql/integration_tests/configured_catalog_template.json b/airbyte-integrations/connectors/source-mysql/integration_tests/configured_catalog_template.json new file mode 100644 index 000000000000..dd07d403af3d --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/integration_tests/configured_catalog_template.json @@ -0,0 +1,32 @@ +{ + "streams": [ + { + "stream": { + "name": "id_and_name_cat", + "json_schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "string" + } + } + }, + "supported_sync_modes": ["full_refresh", "incremental"], + "default_cursor_field": [], + "source_defined_primary_key": [], + "namespace": "%s" + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "append", + "cursor_field": ["id"], + "user_defined_primary_key": ["id"], + "sync_id": 0, + "generation_id": 0, + "minimum_generation_id": 0, + "primary_key": [] + } + ] +} diff --git a/airbyte-integrations/connectors/source-mysql/integration_tests/expected_records.txt b/airbyte-integrations/connectors/source-mysql/integration_tests/expected_records.txt new file mode 100644 index 000000000000..8c60e5d1ee18 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/integration_tests/expected_records.txt @@ -0,0 +1,3 @@ +{"stream": "id_and_name_cat", "data": {"id": "1", "name": "one"}, "emitted_at": 999999} +{"stream": "id_and_name_cat", "data": {"id": "2", "name": "two"}, "emitted_at": 999999} +{"stream": "id_and_name_cat", "data": {"id": "3", "name": "three"}, "emitted_at": 999999} \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-mysql/integration_tests/incremental_configured_catalog_template.json b/airbyte-integrations/connectors/source-mysql/integration_tests/incremental_configured_catalog_template.json new file mode 100644 index 000000000000..496ccd7fb9f7 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/integration_tests/incremental_configured_catalog_template.json @@ -0,0 +1,32 @@ +{ + "streams": [ + { + "stream": { + "name": "id_and_name_cat", + "json_schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "string" + } + } + }, + "supported_sync_modes": ["full_refresh", "incremental"], + "default_cursor_field": [], + "source_defined_primary_key": [], + "namespace": "%s" + }, + "sync_mode": "incremental", + "destination_sync_mode": "append", + "cursor_field": ["id"], + "user_defined_primary_key": ["id"], + "sync_id": 0, + "generation_id": 0, + "minimum_generation_id": 0, + "primary_key": [] + } + ] +} diff --git a/airbyte-integrations/connectors/source-mysql/integration_tests/seed/basic.sql b/airbyte-integrations/connectors/source-mysql/integration_tests/seed/basic.sql deleted file mode 100644 index 17be356eebd3..000000000000 --- a/airbyte-integrations/connectors/source-mysql/integration_tests/seed/basic.sql +++ /dev/null @@ -1,153 +0,0 @@ -CREATE - DATABASE MYSQL_BASIC; - -USE MYSQL_BASIC; -SET -@@sql_mode = ''; - -CREATE - TABLE - test.TEST_DATASET( - id INTEGER PRIMARY KEY, - test_column_1 bit, - test_column_10 SMALLINT, - test_column_12 SMALLINT unsigned, - test_column_13 mediumint, - test_column_15 INT, - test_column_16 INT unsigned, - test_column_18 BIGINT, - test_column_19 FLOAT, - test_column_2 bit(1), - test_column_20 DOUBLE, - test_column_21 DECIMAL( - 10, - 3 - ), - test_column_22 DECIMAL( - 19, - 2 - ), - test_column_24 DATE, - test_column_25 datetime NOT NULL DEFAULT now(), - test_column_26 datetime, - test_column_27 TIMESTAMP, - test_column_29 TIME, - test_column_3 bit(7), - test_column_30 YEAR, - test_column_31 VARCHAR(63), - test_column_4 tinyint, - test_column_5 tinyint(1), - test_column_6 tinyint(1) unsigned, - test_column_7 tinyint(2), - test_column_8 BOOL, - test_column_9 BOOLEAN - ); - -INSERT - INTO - test.TEST_DATASET - VALUES( - 1, - 1, - - 32768, - 0, - - 8388608, - - 2147483648, - 3428724653, - 9223372036854775807, - 10.5, - 1, - POWER( 10, 308 ), - 0.188, - 1700000.01, - '1999-01-08', - '2005-10-10 23:22:21', - '2005-10-10 23:22:21', - '2021-01-00', - '-22:59:59', - b'1000001', - '1997', - 'Airbyte', - - 128, - 1, - 0, - - 128, - 1, - 1 - ); - -INSERT - INTO - test.TEST_DATASET - VALUES( - 2, - 0, - 32767, - 65535, - 8388607, - 2147483647, - 3428724653, - 9223372036854775807, - 10.5, - 0, - 1 / POWER( 10, 45 ), - 0.188, - 1700000.01, - '2021-01-01', - '2013-09-05T10:10:02', - '2013-09-05T10:10:02', - '2021-00-00', - '23:59:59', - b'1000001', - '0', - '!"#$%&\'()*+, - -./:; - -<=>? \@ [ \ ] ^_\ ` { | } ~ ', 127, 0, 1, 127, 0, 0); -INSERT INTO test.TEST_DATASET VALUES (3, 0, 32767, 65535, 8388607, 2147483647, 3428724653, 9223372036854775807, 10.5, 0, 10.5, 0.188, 1700000.01, ' 2021 - 01 - 01 ', ' 2013 - 09 - 06 T10:10:02 ', ' 2013 - 09 - 06 T10:10:02 ', ' 0000 - 00 - 00 ', ' 00:00:00 ', b' 1000001 ', ' 50 ', ' ! "#$%&\'()*+,-./:;<=>?\@[\]^_\`{|}~', 127, 0, 2, 127, 0, 0); -INSERT INTO test.TEST_DATASET VALUES (4, 0, 32767, 65535, 8388607, 2147483647, 3428724653, 9223372036854775807, 10.5, 0, 10.5, 0.188, 1700000.01, '2021-01-01', '2013-09-06T10:10:02', '2013-09-06T10:10:02', '2022-08-09T10:17:16.161342Z', '00:00:00', b'1000001', '70', '!" #$ %& \'()*+,-./:;<=>?\@[\]^_\`{|}~', -127, -0, -3, -127, -0, -0 - ); - -INSERT - INTO - test.TEST_DATASET - VALUES( - 5, - 0, - 32767, - 65535, - 8388607, - 2147483647, - 3428724653, - 9223372036854775807, - 10.5, - 0, - 10.5, - 0.188, - 1700000.01, - '2021-01-01', - '2013-09-06T10:10:02', - '2013-09-06T10:10:02', - '2022-08-09T10:17:16.161342Z', - '00:00:00', - b'1000001', - '80', - '!"#$%&\'()*+, - -./:; - -<=>? \@ [ \ ] ^_\ ` { | } ~ ', 127, 0, 3, 127, 0, 0); -INSERT INTO test.TEST_DATASET VALUES (6, 0, 32767, 65535, 8388607, 2147483647, 3428724653, 9223372036854775807, 10.5, 0, 10.5, 0.188, 1700000.01, ' 2021 - 01 - 01 ', ' 2013 - 09 - 06 T10:10:02 ', ' 2013 - 09 - 06 T10:10:02 ', ' 2022 - 08 - 09 T10:17:16.161342 Z', ' 00:00:00 ', b' 1000001 ', ' 99 ', ' ! "#$%&\'()*+,-./:;<=>?\@[\]^_\`{|}~', 127, 0, 3, 127, 0, 0); -INSERT INTO test.TEST_DATASET VALUES (7, 0, 32767, 65535, 8388607, 2147483647, 3428724653, 9223372036854775807, 10.5, 0, 10.5, 0.188, 1700000.01, '2021-01-01', '2013-09-06T10:10:02', '2013-09-06T10:10:02', '2022-08-09T10:17:16.161342Z', '00:00:00', b'1000001', '99', '!" #$ %& \'()*+,-./:;<=>?\@[\]^_\`{|}~', -127, -0, -3, -127, -0, -0 - ); diff --git a/airbyte-integrations/connectors/source-mysql/integration_tests/seed/full.sql b/airbyte-integrations/connectors/source-mysql/integration_tests/seed/full.sql deleted file mode 100644 index a6499c150184..000000000000 --- a/airbyte-integrations/connectors/source-mysql/integration_tests/seed/full.sql +++ /dev/null @@ -1,528 +0,0 @@ -CREATE - DATABASE MYSQL_FULL; - -USE MYSQL_FULL; -SET -@@sql_mode = ''; - -CREATE - TABLE - test.TEST_DATASET( - id INTEGER PRIMARY KEY, - test_column_1 bit, - test_column_10 SMALLINT, - test_column_11 SMALLINT zerofill, - test_column_12 SMALLINT unsigned, - test_column_13 mediumint, - test_column_14 mediumint zerofill, - test_column_15 INT, - test_column_16 INT unsigned, - test_column_17 INT zerofill, - test_column_18 BIGINT, - test_column_19 FLOAT, - test_column_2 bit(1), - test_column_20 DOUBLE, - test_column_21 DECIMAL( - 10, - 3 - ), - test_column_22 DECIMAL( - 19, - 2 - ), - test_column_23 DATE NOT NULL DEFAULT '0000-00-00', - test_column_24 DATE, - test_column_25 datetime NOT NULL DEFAULT now(), - test_column_26 datetime, - test_column_27 TIMESTAMP, - test_column_28 TIME NOT NULL DEFAULT '00:00:00', - test_column_29 TIME, - test_column_3 bit(7), - test_column_30 YEAR, - test_column_31 VARCHAR(63), - test_column_32 VARCHAR(63) CHARACTER - SET - utf16, - test_column_33 VARCHAR(63) CHARACTER - SET - cp1251, - test_column_34 VARCHAR(7) CHARACTER - SET - BINARY, - test_column_35 CHAR(63), - test_column_36 CHAR(63) CHARACTER - SET - utf16, - test_column_37 CHAR(63) CHARACTER - SET - cp1251, - test_column_38 CHAR(7) CHARACTER - SET - BINARY, - test_column_39 BLOB, - test_column_4 tinyint, - test_column_40 TINYBLOB, - test_column_5 tinyint(1), - test_column_51 json, - test_column_52 ENUM( - 'xs', - 's', - 'm', - 'l', - 'xl' - ), - test_column_53 - SET - ( - 'xs', - 's', - 'm', - 'l', - 'xl' - ), - test_column_6 tinyint(1) unsigned, - test_column_7 tinyint(2), - test_column_8 BOOL, - test_column_9 BOOLEAN - ); - -INSERT - INTO - test.TEST_DATASET - VALUES( - 1, - NULL, - NULL, - 1, - NULL, - NULL, - 1, - NULL, - 3428724653, - 1, - NULL, - NULL, - NULL, - NULL, - 0.188, - 1700000.01, - '1999-01-08', - '1999-01-08', - '2005-10-10 23:22:21', - '2005-10-10 23:22:21', - NULL, - '-22:59:59', - '-22:59:59', - NULL, - NULL, - NULL, - 0 xfffd, - 'тест', - NULL, - NULL, - 0 xfffd, - 'тест', - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - concat( - lpad( - '0', - 262144, - '0' - ), - lpad( - '0', - 262144, - '0' - ), - lpad( - '0', - 262144, - '0' - ), - lpad( - '0', - 261568, - '0' - ) - ), - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL - ); - -INSERT - INTO - test.TEST_DATASET - VALUES( - 2, - 1, - - 32768, - NULL, - 0, - - 8388608, - NULL, - - 2147483648, - NULL, - NULL, - 9223372036854775807, - 10.5, - 1, - POWER( 10, 308 ), - NULL, - NULL, - '2021-01-01', - '2021-01-01', - '2013-09-05T10:10:02', - '2013-09-05T10:10:02', - '2021-01-00', - '23:59:59', - '23:59:59', - b'1000001', - '1997', - 'Airbyte', - NULL, - NULL, - 'Airbyte', - 'Airbyte', - NULL, - NULL, - 'Airbyte', - 'Airbyte', - - 128, - 'Airbyte', - 'Airbyte', - 'Airbyte', - 'Airbyte', - 'Airbyte', - 'test', - 'Airbyte', - 'Airbyte', - 'Airbyte', - 'Airbyte', - 1, - 'test', - '{"a": 10, "b": 15}', - 'xs', - 'xs,s', - 0, - - 128, - 1, - 1 - ); - -INSERT - INTO - test.TEST_DATASET - VALUES( - 3, - 0, - 32767, - NULL, - 65535, - 8388607, - NULL, - 2147483647, - NULL, - NULL, - NULL, - NULL, - 0, - 1 / POWER( 10, 45 ), - NULL, - NULL, - NULL, - NULL, - '2013-09-06T10:10:02', - '2013-09-06T10:10:02', - '2021-00-00', - '00:00:00', - '00:00:00', - NULL, - '0', - '!"#$%&''()*+,-./:;<=>?\@[\]^_\`{|}~', - NULL, - NULL, - NULL, - '!"#$%&''()*+,-./:;<=>?\@[\]^_\`{|}~', - NULL, - NULL, - NULL, - NULL, - 127, - NULL, - NULL, - NULL, - NULL, - NULL, - 'тест', - 'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', - 'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', - 'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', - 'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', - 0, - NULL, - '{"fóo": "bär"}', - 'm', - 'm,xl', - 1, - 127, - 0, - 0 - ); - -INSERT - INTO - test.TEST_DATASET - VALUES( - 4, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - 10.5, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - '0000-00-00', - NULL, - NULL, - NULL, - '50', - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - FROM_BASE64('iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAYAAAA5ZDbSAAAACXBIWXMAACE4AAAhOAFFljFgAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAEIPSURBVHgB7b0JnFxXeSf6v3vtVV29791q7bIkS8iy5U3IC2DHNnIAJ2MYQl4AZ4HJQB6TmcybQQz5ZfHkDXmQkEcCgQDBwWb1IrDBu4wX7Vu31GpJve/Vta93e985996qlu1k3vzUJiq/d+xS13LrVtX9zrf9/9/5jmDbtgTAQl2Mzwn83zc8vfzBPn777Gc/az/y8qd9iaAULvoSoQYEVdGW1FLFtCuo6AFR0EoFcWkhX1xoX6uK5YnSr5fE4v7PXPPI3Oc+B+ENH/1Z79z/a+Oz/8KjX8IQBBKwQMPG22Q8e/Hrvuni+e6Z/MjWRD6xOVcsblRDaJMEKeRXA2pZL6NoFso+ySc3CO1TF3MjL/cG+62oHJCazYYH77v+C0W8TQbJVqxbAbvfm9/1nvv2kf/cO5ub+r2hpeO3SIF8d3bJipiirQX8klAsmYhFJdJdoFQxIKoG+qUd9lx5utTh7zRHkxdHFb/wj/F4/JsP3vizabwNRl0L+OsX9/mkhH63rAVeKKbThaHcqVv8duDP5tPT61PSFIKKhsSChfYOGZm0iWIZdF9EuWwjlbIQiZsIlltwXWQt5spFfH/weciajcbG8NnmePw/xiK+px+88aUs6ngwAYuo0/GRvn1l0YRhl/MfP7z48mdGps9+KSI1rNfJw8ZCKpKLJjRVhKaJKOVtiORWRUGERDejIsCqkDbLSxg++QouXDyE5rYgZNOH5FJh3cTs9JfG5xY+/fs/v7YVdT7qVsBkne2AobxUKVU+nEjPf6ot3NbdqDXBktIwSFuNiohgQIRtAqYuQBIFLmSZ5rRgC6gUBWhBCSdVHRdME9GwhEhMhmgpqJTQNbew9AcLudQff/LcJzXU77DrVsD/49RvxZ9KPfFHo3Pj/bd0vyd0+8CdmEmPQdJ0FAqOIMn3ks8VINB9SWIazAQtck02dHqORB5t89F7NHosoKlJhk+TIQsyFFMNT4zNfzRx/Mm/+E8/v7URdTrqUsD7Satmpi7+2sTs5Icmkxel7koRPUYOaWMMgqTCIuExASuyCL3CfqTIBUui5pos0V/bEkCKS5OAjiWB6yWaFAppcViGYJL2B2Vogg9zi6n7p3ILv/bFc3fUpSbLqMPx2tjYuuml2Y9WimK8pCxg7MgzSPiDKHUWYCsKLNMm4Qpca5kQBf4fuGlmkbdIQrbovmGQgDUJqmLRRLDofQLCIYkHYYJoIxwRkMyUGtLZ1EeHRuQDdIoTqLNRdxr88MMfkJbKyX+/mExu7wy3CLYUwvdm0vju2DiskEzaS8IzBKgq99P0GJegFlzQgiNsg46TScs1P2k03SffyzVaIW1nViBA51MFhVKs4rZ8qfzpD9gfkFBno+4EPNPZuGEhO/1ekBk1pQLWxq+CNtCI8NY4FEWGadiUHgASaTBlgKSpcCXK3i04Nxv8GJM0XaL/+iK9dJzlmHOJRd5M4CIiShQ+OqdgyEgVU/dseq6wAXU26krAtr1PHE8Nvz+XL8RVUUPJKqKk69i16h0IR8kcWxKa1Q4IFvlV2RUqEzBJ2WaStmuoiM3vCCgZJTSHmtAR6kWhrPO4U1UF+IQgOoJ9kFUToqnSxKk0jGem3s8sCOpo1JWA/+TFc+unc6N7YSiUz5IQpABOz59El7oKm1p2kHBU9Ac3U0RsgWX4lOg7grRdbSaNtZiwXZttsRSK/O5w+hRu7L4FQTFKQIhF+bOAgdha0mgy1z5HyyWTgJP8wr0nmzLrUUejbgS8b98+cWppYpuulzuhUypDAZRBwtINHacWjmKTdguujl8Pnx1BhaBIFmBxSXKttbmwmW9m0bMjdGcCEAGBVDmBUjmHa9puQJne61f9GGhch/nkPFTZxyNvwST/blodk+mFbey7oE5G3XzR7l8vBHPl9LWkdTEWGbNImEfIZI5Hc8MYnziNO/x90IqTBG5QFOz6WNs1ylybBfD3sKcsemzQcRbxaJrow7GZw9gavwZhqREdsQ60BtuRyCTJUkg83bINiVIOMVYs5q7133YkiDoZdZMmnZsYaa6US9vMsihblN4ITMAWS38oy6WI+fjCY4icUTFMM8Ai6TJBsuNIhnRjYha4MJnkTQqoVMpxo4qfhJyFT1YxsjiM+cQc3tX+a7A1C+n5DArFHILwQaUMuJRh75FlA8bVk5lcC52pLnDqutHgXCbZXjb1XstyzC4LjG2XxVboQTHmw/esLA6WS8uDZRK0ibZQuxNvuT7ZMA2sb7qK3qdApwnBoA9m6l8ZewUdUhu2aHHMpYd5rsysgMzUgO6LFICZhtGXz6XbUSejbgRs2+Y6EkKzaYluLuv6UvoFpMykxZS79kYgNwYpRRId6dKtTMltR6iHTG4XSLdJmw00BVqxunE9JrMTXLgEZJGflXBudhCzg99A6eLjkDPDzEzwScRSLvYZLFc2TLPJFsy6CbTqRsBls7LVNHSfTZmMIpJKSY6PZZrMI2YBDgxJwZWkOpPAoNdFst8XE6PY0bKH+1pm1vf03Yn5zAwFVhUedLGZwHLonF3AM+dO4NDRQxim1yVJ4lrMcWz6DF1nGm35KqaxBXUy6kPAJEfdNPqYUrK8tyfWSxBjkAdKXLKuNnMTDF6nwn8Ze45FyfPZWQSFCK5qvh5doTVYE9mIwZlBsFya5cfMk8s0YRSfgsG4D8+1KFiKyPziML8tkAYrCglXdxLpimH0A29S1nMFjroQ8Bd/8km1WMr1MhDCpCuuyQG0+LsoWrb5ZWYC5RbZFbJ36W0X2SgSRHVubhC7YjtxT+/dWMokMM00lCyB5fpzhmApqgR/RIHcqkH1Oabb8fekxbITgTONLxvlno88+5G6IB/qQ4NDoUjBKLUw2SmChmRhAX2BDRQQy9w3Mg00bU/ADqEgeCgWDYmkc3HmWRhDj6Bp9hiOjnyPgiudR+B2VYAi97UsOmePWZ7tBHJOxCYrDkHB+OWyXm5pj+bDqINRF2mSikozYUlRJpKyUUHOSCKuNhEs2YnpwggJxVcNqrjGcWBDqGoz86Epo4zXBk+iOTyMEQq0JGaTBds9hgRMAhQMoYpuitIy00//kTvmxzKSgiLpSChXaabDFnCFj7oQ8FIl0RhVor5NTVuRD5tYKJ9HhXDoTS3bcHFkiI7wuWiVIwzBkQ3XalYQzIj+ok/GqxoFU5KBBEGQErFF/D2We7zo5lZM+1lULdUidcudKJ6ACSDxpXKZZtTBqAsBL+Tn4xO5cbFIZMA1TTfhzoE70YgZ9GpLeIHSJoNBjlYtL7axrIZQcLRSIh8rxxT6xaStCzoHQNiRpu0d5ppkOKZekpY9ZjZBqPl327LEpXKmAXUw6kLAAdUfYFUYS6UkHh16FBdmT2EHZbVILRBAYTooFWpWmmue4DJGEr0qOVEX11HRI/3dZ5gph1DVevYUO5fInbtHPzkns90PsemOYhNIXQejLoIsyxRjzExKFnGzRAnO2GN4sjSJR5ZyKBHMJLjpkWXVTK5DIjkskjMurQx2BOpMBCZiLtDqrOAYB2pxms35YnZjE8Qg9Ktimqu+cujjCq7wURcaXCBzKAquFgqsWkOBSTpdIdpQEfQqW2QvW4DD7jv+2PGp3l+XPXQKAfhxbu4MR6jV2eHhnQDHrttCHUgpCRSsRbRF2jHQMBCbyQ5f8fXk9aDBQkUwNEdKIv/GAg+AGU8LBl9hWeL7etlUzS7XVNHRbp5Y0R0H1nYnjlQ9hYedVKtAdIq6G/wxbGjehLAvirvXvx8lwyjue+dzJq7wseICvmhf9Nk1u3jZ42H7YdHUjbBnUr2aKsffuigF4Aq3pn38K7D6ZyIRdNtwyu74oRbPZdc3beC+lP3HymqdhFpAdY2Hd0dwrMBsbg6bWrfhroH7UdEtHJl9LbLvuXde8dUdKy7gzNx4+9DMgb2zs7MrwpkOPvKIVDFLmuBKlftVuKAGP6L2L/fBtlDVPpHUcnXDGvRFVpGiqyBRM7IAmWIWzYFObG/bRdBnCc7U8KJm582iW8fF4zRCvOZz82jLDOKGiB8/Hf4R+3zf6YX5K94CrvgX1FuDk5VysUUXFt9DmqwNzTzbh8sY8VCbQEGN5GivUI2VLGuZOYaHYqEW+dLxBmnuTHYGcV8jbu29Czd23IMmfw8v1TkzPYRb+/YiojVz+FN4U5MuVIMxdufw0PN44vi3sFCcpbRMltpClRWzVG/VWPEga4ewQ3/21LeeVqF8NFkeb64oha0/vLDv2YpVqJALtSq6oKtiMKWa2tixdcXZfcK+f3Ft8pI/KxAEfUm0aguUpkgqYmoIGXuharMFr0RHsFxEi3Bos4ij0wcxlj6DXe034v6BTxAmPYXB6aPoJvp+V+MAThunavCml/l6YbQ7p1RNxpOk7VpmETalXoZtKll/L706git5rHwUTdfm7x/6Qk+j1LznzvZd1xRDF4TX8qd+m/kt5uaIiaHgyG/4NP98KBv74dMXvvZoj9n+/Jo1d5bf7HQRLU9MEs0JTvoyzJnyXpJ4WI0gGG7C4tIkCSPgfHS12Aq1AmgeDkhIG2k8v/Q9nFh8Adc27sVdLZthj/8Y15dnMEHRVp4Fa2xiCF7k7dw80ISHckEJop+AEp2lSoayOJy94k30SgtY+OA3tl87m57+qwVpdoM2fR5NQRVGj48D+xXD5pFwNluRm+PrOnQ787GF0Gg4mt/67D93wsxiUTBtQ2SXuSXYDMUoUgS7QLRfFLIVgkcecUiRf4NloIbgEg/0bpmwx4ZwjFKuLL554u/xC6IP90Z0zJEACx0qLllnadeAjyoAIgq10mqR5eamhM4rfxnxigr4o9+5dvP56bE/t0VjQ0tzBBm/QsSAjLCkcD5VrlgMtkdFLWGV0AJVGVAPzO9/r92p/4je/sM3Oye7hJZg8fA2S8K5rucmjFpH4FPCEMqaK1yhFk3Yy6BKHmQT+S+6kTIdFgz64fNZGM5l8ZWszc1tv+ScR/QyLvcvnxySd39Znizwgvor3v+ysSIm5vGxLzf8+dO/tXNycfqPBVG/qa2hCbGoD6YgIxLT3HSGKAEf4cYkq4bGIE6ffhzHzvwY87Pp6NHFn3/+W2f+4zVvll7dtmqHqEk+mb2SLmfw3MhzuLX5HtxMOSmMPBfgcuzZ9vJX70zM5FYF5kCQql+FP6DBChH3G9Uga5JTICDWrghHubx0a1ng5f0WBn5XUtYVL+QVEfAaeQNRqdrnTal4y0DLgNAajfGVBSZf+0NAASH6rLJRJFOpE8rvJ+51oknBfMSEavqQSWdXn0sd/rUfn30w9Ppzx+3OoCr5Gi2KdFmpDsOjXzz9AwgXfoEyYdIQnfjLsm039629t/awJgfmV2Ui9hW26IwYJo1ubFVhNUpnuDbDmimt6gp3UWJlOni1wIrvZLRH2vgicmsFc/23cqyIgGPBrmhMiV+3rm1tcFvbtcjbCU7GM7JcIBPIAizdsHiNlE73TRJyIKJBIsiRr8DPUXBaTL77TPrkqtef26eEpJgck1kNM3sfu/AT1jweunAaJ1IZXlEpkm31SwGaPAZ/TxWd4jehWoXJgQxWX8VuLsHPiH5Pwz1wg93ViXdeHVuPgBTk582Xc9i9+ha0R3sIONEdjqIOxmUL+OFT+9S/eeazv7060Bv5t2s+hemlObqA7AI59S5suUhFN2GQgCvkg8t04xE1aTOLqH1+CeW8gEwhvcGolO72znt89sngoUOHlFCwRWj2tQpMg5kHZ2AGNAWzTUGUaZLwGilTR2ewGz0RuvhW2Y2mXR63KgbBBTOc6JgJWZBc4VYPcScGTZiSVUKpZGB7+7XIlNK4pnM3dnTdhKHFk65LsKDGxLc/Fn1samjt0Mih22IzRzAxehhnFk8TvRfgzU4c8IFMoB3ktF6ZaTIJSndXHlR0MtsszKPwt1wypYyRvpmgSYn5YlnU1kpti/dKsBtjvmZLslWHzXENoyo6VZReffTw0llsbd/GiQCDBC5QdNSgNjoZk0v91aJq1Eh+Nx1iEVY1kILz3ERiFFuar8XG6A24a9XH8NS5HyNFLkKURNRHiHWZAmZrdC6On7tmdGGh96vP/ACPHH8IBsrcRDJhssGsZrPWwbWPpUmsMpGZW6YFTJN5XM0WalNumcovbtYuGk2s6082XThfrKTXpSrT/6VN8XVq0HgO7Gmkg0O4+DH9jJJexrnFs7htzR0kMwqixCBWRda7KbEbJS0TilCNlr1zOPcdxpBZGBnT6Sn00ON/t+2jWMzO4eDkS+QiFO8LWJjBFT8uS8DlG481LCYTewqmFTvZJmIpJIIZLbZyvlJxsMNsoYSo1EyBCUXTlDKxSoqKZXO6jvtkw+mAYxkSMuVMy3z6NF+De92aOzNlQf3S4viB2eTx73XLyTxdfKlamuMhTB6eoZJQT06fRClfxK9f9RF0+Tbwmi2LJkWNRbKrsKPnbZ2Hzpn4Kgb6T2PltDSDysUF6GPfgaK/ip9d+BvKCpw2EDbnj2H6G6S3t4men5lrKJX11UwB/ORLmallmsXwDNNwNJhepwsloD+0BT3+DfCCJdv1p0zIHKFik0KviFk90eKdf0//vSndCP7t4UThUIJsg1QjjuBppHeFOfdLQd2z559GuxjBPZ07IOpJdyWhXaX+ariowLngZl8zBXIatzosmOr291OUH+ATwwj58Mj5YXz70MO4kBtjq/2rkbloi3XR/vGyBJwspZpK5UoHC1iclXu2uyjMFRwYNElmlczb3ubdmEkvIEAX30eRKTuWvcbWBrHByAP2WDClSzraDLZHz463+gd1f43BYwIT3FjZkZ3TA4uZ1bnSIl45/U00TByAMf8K/4lWtV5LqL6HSYkR+UE5hu7gGpTMAiFjGjFPa5EsLnFcWw1IOOgT8Hw5D4NpL/fj3moKQc/N+q54IV9ekGVgTblstPAVALazes9rfGLx5ic2D3ZGp4/hyRcexFh2BG2+XrT6u1CgC9oYaEV/cC2Z7IoDNVqsSL1wSb3x6cGHmboY7Ly1paBwIuplnC0DMFgts0a56mulBfz1mefxQi7JAzGvEseDGkWPVKAn54jn7fddw9cO9wZX0/t9yJl5nnqxq6MQOKNqzn37Eo8u6KE29Yo30ZcFVZoVq4fSH02hC8CnsuWu27W9khmBR5yjGqVBUoHkRB7ODCCqBdCkdWF9fBfOFA6wJkduyY1NOLN+yYqBhlV+O380b1lV0NkhFRzuvloS6UbDIq/ysIj5Od/sp1SHXkpZ1fdU0yfHk3PAIl1KQM8b2BrZjcZoB1GBY5DJEjh+flm1CHAJQiba/x/IgyuG3kQCFllkyYANy3KCGNaOyAuA2D9aQIE/EmAr5MkEG1gX2kw+8jdwnqLeheI8xwi9VQkk5Uu+U0c2bEuiaGGZBrp0L5ZXc/DKSfchy2J8hFZJYg1mdKBGp85ZJexZoaCMN2IRTJxPnsD7V/8bbO7agvE0+VpZdX+LXYviPKDE+3xJNBuS/rd5HixIDQzAYELtDnRWQQS+4Nqu5TPsOXbRGbLVlruAzYQpH55+BUfmjkAyFUfjPc0Q5Ev82saFZpo6km55BtqqMUVerToP3VlttItSCV5OC6fo3XJ1lrdVog/bFL+Kt2ZgX1HTNFw0BoHCGCLCBRQqC9yiwJtwQg0NWz4kQdKTDave3j6YctqoSBchXy4gphHB4I86F5JrpF2rsoDjB9lykSOJaTx0+Bs4nHoRiqw5DnGZdjIjvvwzBgc32Yqilt2X+bJR55y2m7+6HtEFLoRlWkukPIJKCKsa+ilC1zmypQpBtAS6mK/nFKIsyTBUA8eP/l8YI/LDZOtTq6sU3S/huoZqWY/NQZbypsFH3uYabEPjESxd1FyhiN74KjSq7WjUWuni6vAyVWeJCAUsBD9Nh2UcDDpBEfOBPAiyHY0EX4urXkL8E5hi2QZK/Bq7FB4b1eJ270CpptHeMWR/sZCb50tcOiKrkNUz6PVTIEVCNuxKFfvQiGx4Qs/iH8ankePrRWvOVvQQL3cqVX86hQv79l35nfIvS8CO4RXgI02cWJjA1qZr8O6+XydSvcBfXw4F83iIhOALEMpEPDE3oyJcSg7uMn1W86zpb/gcRTCWrQp1nvOiYaH2bTiR4LoDjx1ine8OT7yK96+/n9dj7Wy7hcxwmtdhcTfCIE/6FmY8iArlvZIkumnYcqRMcBml2vel8xuog3FZAib9sxwxSxSx5hDPXUSvlECimKYrITlNT+BWOdn2JasJ+PAqF5flt6IgvaHWWJFEY3nQ5pzLNcvLNM07DReO+8tYADieGsNschQf6f8QOtUGzOVnl388PMrXYZk8Hy46/lxwKyy563E+j88LqT4EfFlpkiJJJQ/mkyg1OXD85xhJqDCDPt7eiKU9kofzehdHWJZNVoXNLqQTPcmi+gYNVmzV4GbeM71VYt4Ngqp0n/u6Vz/tCpmBoQdHH8ceeSd8kWGkc8MsmKue37aWR+ZOqscE2+7vwLQ+RS9W6LfK2NS+DhfypzlWLdnS21/AkqSkuBmkCySTf32mXEIzUX8NsQAYFM04YElwyH6+ms+NUBhcKTBOEXZ1lZ9H5SiC/EYNVuU8/zyBdbdja5Ec0yC6rBC3EIKDEnsm23YlJikMHxcwhxweO/szIvkpDjAplJOdz/fMh2OURRelEnknnpARxobmzTiTeQ13rPkATl64iFKlxIv+FE3JoQ7GZZloikqzXFAkJUach0IKAqTJ3nWzDMcJx8gs8ooLi1UjMtLe7+LKQhXBcpqGMi194zYDqqwU2PX3qRo6Ix1VYr9qol0/KQrVKKuqzXz1PvlVmybGiRYNh+N+6PSdRXt5tYfgfgHvSZE3QJvJzGBrw424vv1OdKjrcWz6NW7y3eLLMupgXJaANVFNy0TVsN5VDLFiQrYMZ40lJx1IwBbRg/3RAQL0A7yFUaPWRnjvAAladxZTk3SDxB/LrskUX2dVvvjKJyOKrDQTRQG/5qcUpxmGbjglrZ4QmeKKtY47ooSqv3fWMjmdcjSfwrvpiLWlD9V1v3wRWjUkt3nbh6XSElrp+927ai9eHX0O8WCELWV1UDBRvCwT/fFDH1f+9MX73/I1xpcl4EAgNCXLss6YI8FyfKRecYMR1jafNNswKgiJjWgL9iGuteCWgdtxLjnCu8uxC5st5rEq3ofuSA+XSskoX7LkJU7UQ2e4s7M13IqwFkHYF6kFbEBt9QFvmGVfgnR5QTYTMOuU46VPHt3oAVWOFaHvzzy9FxlaTqB18dg/4MzxL2CqMIT1TVsIvavwDvL5YrGCyxjtxoRfV+fv2HforgDewnGZZIM0LctKngcprPuNopB2ma6AWaWrwp/P59PY2rgL9679MMaS57CYT/GotzdCxAORD4ocIs3s4ILJVZbiy5t9fmjNlzKJYurAzo6dhF2vc0ykx+dWAQhUm7Gw+zLRet7aIsezwrXCQjWy915womKbs1veC+z7M8TL79ewv5TFI3ND2N51I4qVMipmhft0glf/lwTMtgT48on7GzwYXZAlSsXFVQHLirDH9ltUhnt5ebCMeb+ipkl/USkaaA41oyvah0Ipj4iPEKTYKueCpAdxY4MKozKPw7OH6GiCJ4luSpbmCZfegj1tN6CLtJNpzVJxseeuj911yer5dClXmkyOYysF2EpmhFdSem6WV0fZNUDFJ/vRH+5zGSo3WXbKw5xo2eWHqyYctedd5+Iea3EQxmzUEGzqx1VNu3Bx6RyPvtl5NVX5f2WiWX/pBwdv2p7XjX9vSuX/9tdn3/e//83Q+/8g5rd/x6/5rrXN4OYvvHzvhgeP3vOWtEe8rCi6s6VvcXJ2cjaTy/QZJR1LwhLuXv2reHbph9jafDXlnlMctpwmjvbxn34JrxKGIShB7t+YNpXtIn545oeIZU8hY+dJ7D7M56c2LxaG++n0p73PiQYj5umJI/jZ7CimkgaUtiDXUObnw0oELcEo5o0E96e95O81csKsvEdwF/06EKNHNbo9tZwHVZPOA0IWaLF2w0zgpu0K2sa1zbchkU5gIT+HYEhx0j/5jYDM68cXT+4dOG6c+8RUYu5/W9vUH6kQsjaTP0eZgIgcxREd4gCCdvQaUxT2R0T8F7wF47I0uD3WkVckdY61BzQqFvnTFOYWF8gUfxAD4QECGKZoBklIxTR8O6MjzcthHFSoQn6bbYgR8wfx8/I4XqX3SoaMvJFrPz738tVs1y7vc3xSwDDp0SHypRMBCsjcWirmI1nX9y7ilJuJYy4bBgZi65AsLBGvqy4DVxxtFUWhSht63QAEYZnQeTRv8TSJlX+xGCKstGFTbDuOTb3Cg0bTaVlLiLn4Ly7+/pOhvY0L1sSfBYSmB5r90UhTZSPidAuKFGwW/PCZYaiZJFpnkq0XRk/cniol34u3YFyWgDsVf17zaaN019CLzg8/M/oy3tPQQb6yiAwFUOUCCdIvI9QcYkutyT9aXEsqZOBYKqoS4C8oPviCGvQy74MRH0+P3PniyCPVyo6QGK5Q3mqpdB7GPQNV94uyWSK8eQLv6bmXC7qdiIQ0Rb+M0/Uap9ieM4YLny6r8HBycdb6HTz9alKbEZGilMMb5HNLuL5xHfzkbudLM9jRvQsbm65CSA3aiiz/sz74i/vv0LL5id/J6vP3qKWo//bGj6E/tJ20tZEmtEYgiYIGvw8JmixDxjmYcrZrMTWy7/mJr+7ECo/LEvB7byjmGyKNxwi2y7B11CqZxoSVxo9+8iAOj30PPjJnuZwJq2wgEJSJwWFVFxbHfvn2CGQ22f5ERZocskLvJ9DfzEOaz0//yk9G9+/1PicUjZdIq8zlvK5BEvLTxGhUGwldGiYTOoIHb/oIhMoc8lahinPzH7ksomajBm3Y5BY0xKVWvhBcJhexrfE6pAlqLVF6F03quEddQJs4gd+++pMUL6zGVGKSRf5mQPWV3uya7LP3ifPx3N0Vcel3hVxYnSMq8vzIEWylQBOLh8HairMKUkIBUSSTra2KIhwKUwRvNL948Vt/+vSFb/eyc6xUl4TLC7KEfdaq1u4LPk1K89ortmohJONvzs/hdCKPcEQhTaDUJ68TSMFyUY0CsArlkiwtEZEtEVrkIy0z6ceWTDREibojnqJUKEVHFk7+hwdf+Mx29jmqJfMtNRhcyKJoizX9JgF3RztJm0Jc4EfG9yN74XuYHP0pPTZrDJUXTXtSXkbwsbsG5earQ5s5jdhLAmSNwtN6GgJd/DS5lVcPDuK1l36Cbz77f+O7xx4ma7HI0iRLfRPEjY3gL843Fc3sr8qG0mJVFErtAjiROoz9I/+I00vD3M3rvPjf5pgBWwyg030fxSbT87NXjyV+cfc7R/q3fuHlT69Im6bLLnzvaF97MRaKTjPzVskZBCbQzw/4SKgmfBpr7SuhkDdgl8vY2L4JIbmbfmCWm2bNbuBUfJwmRb5AP1i0SMhkqgmYzBbSq185/+QX/uDxD7wjFozlKLCxGLq0rXsrN6UM0OhvHECeLcqmc82T8P786Kt4ZmHWhSHZqIZT7hCqgZMTd4sos51bjBxu6bob13behInUKFkimaNz5aAfX01l8c3EEI6nTzslRywFo3ua+uYCzliJfsr9r9OLvNslxwVkYqlm+31Yiiq8TJhBuIWSw2alycKx51S6FrpuRVOl+Y8HhcjtXZO7LivP9sZlCzg02j29rmfts6ago0yCFEi7fGEVubRJwQSBHA0+0k7S2HwFF9NnsLFlBzY33g6RfOe2tp0olYLw+YmY1xQsLNIEobS/Ma7R8SKSmfTNJ0ZPPPzcyecfkE2lnC5mkCql8L6rf53y5m60B7uRKae5uVOCKiYb2HIWv9tn0vl+QvVfwWlPCCda9gAOFtEfnTuMW9vWYWtLBGdmT/E2wwy8UVjH2a4wLII3FQra1jb2c19NCJyhioE3FYCuV24ulko9hbzlnN8MkhFRuNYyQeZLNl++ky1YPC1LZQyQasDKBSlVvFoKon1tQA5P33fffSvSweeyBcy+yIaujc8HAj6jVKHZmClDDRLgQd8+NUf5MJldgTXbzpr0Ywt48eJTiFNk+qtrfxMbmjagOdiGxWwBDSRYH5nf+cUyIU86WlpV3vSskC+sOjp68BOlrBFULA2nZwYp2hbxgdXvIdNdIQ2sQHDXovgUZ79Crw1wbRWEI3AGYdrLYGcPFCkYRQy99iWcO/4Q68nFD3KreTlmzjQ+6mtAM6FpLPgC+2Z+35ti0cVycaNhWJKui2Bb3cblTr5tbZldG93RXjZ52GM22YpMKUgMFxKj2Brbgk69VxwcO9WJFRorsrqwqaH/YFtj6wVW41xYqvDoOBgIQ8+SOTN0vpIwVyRTxdYiUUT63ePfgZzNYHe8jFVKCamCQCS8jqaYSZFwL/x6D9KFPDra/IgEGEBSUYl+lC1D5MtSXjqzH82Jw6hMPUdmXawiWE4xnFBtV1htyGLV+GPwVRW1kkgme5ny0q8Pnsc3Tp5iWzJxgVqmA3swJqxBimNb+zuc1Rj0GyVBNMPWG2lNtnFXvlzq0+mV/tB6skpRyGR67YpaXYBn8r2bTLJcvK6YMgebFx0uUcaRzD+P2cH9yvn5Y+/ACo0VEfB9Ox5Idzf1PqQEZCOT01Eiv9XR0IrVLRswM5pANEK+y6cimdJBd+Enc/r1I3+Prz/5V5hauICA7KMfZxMVR5PAN49NrRtwa9dvIJcidiooYMtAH2l4ADqBKXq2gtlSGn839CoeHSdMW2FrhWyOQ1dX4PPhthS+5FfW9kyCWzrrdIUXkGmJIhsLccLEEbBzY/sohewY9vS8kyxNgiNczETbfv8bBPyZp877C+V8O3vP8NwwtvvejR2hjVBIiKWSY6KLrGN9eBVNWgktvh4YJYEvxpNJ4w8sjOGhc4cwkRzdfGjq0Ipg1CsiYDY0NfTTxlDjxb72AVTSpFV0cVa1rMLSUgF2sYwIQX4lSg/KBR0NGmlGKIYfkf8ZpZncqlm8D+USWcd0sYjTC08SL5zA7133R1gXvAXv6n0fOprjaGqmqDSo8H0XJsN+JEMB+CWVbn63rKbK/AOvWwwOd1WClwPbbnWmkyuzrj3OYvVqC2HLbedP51kqJJHPTlHckOMlwYTOGZKovQGqXNM44NdNPSLYEjKFHF4Y/jGGDn6fXNUkp0otvjzHoHMY2NJwAyJWF1m2LCy+WRcRM+RDpKYQoVyp5n5fWxwrMFZMwNubNp5RFOXpdL5ovGvLXSTEVrRSGkMOGOn5HPyUGqkUTabJFwtl8k0hiqL9AWQrjGIkHDtI2svy6DRpE5nzQ3NPYDr1Ah64/ldxe/8WpGaKSKUqlDcLWNfWwzeNNAW2SHuABOyDZS2rf6vSSB575Arcc8wOn1t7aNeowhq75LZiosg9ayQxPfhdaIU0vcabdhhhFii8bmjIRwnRCzFBUiKFpJ3G94lcmWGd9ixnvRZbBjuWGkNzhlK55Az5aZsv1mPfSSczrpB/K5XzkenUaBtWYKyYgH/z3n2pmzZf/43ZzMLZV44exG39m7AmCjKtDUiSX85PphBtUCD5fJhbMiAVC2j0U6KvEf6csciEVYiooFw4oCCbFTG/pOKxocfx3Cv/HefPfI3AjgKlXWFMzZegp6NEKGzggc+q6GqKrDM80KoSEJYnKMuBFj1+kGmRbbsL36rFHG4xgnOzvD7SrO2EYfOemMxnfu21szg4lySolZlwUT9y+uwbKipLphjSbVNx9sG0WdUHAs0ESYZUvlaLCZLt48SqRb577Ac4ljgOTaC00HSWxQbIX7PvWCjryoW5U01YgbFiAmZjx469x66/ets/naBI9+kDj2DsxENQNdJYVUNiQYe1ROBHTCUySEV6SUKTEEEDaa5GsF0yJ2BhiXw0kTSdjRL8NJMzOQ0Pj47iT08cgkmutrtJwKaBCLIYRa+/H3vX7UWCzGeRomCxVoDlprsEHoga3/zKdLV7uRK7pFL1L5aR/Q7Z4EwQm3cWINAjTumO6hTEU6hn+kOK/frfnytkw7ZpqiLXcieaZ5OHJ0QE7LDAjQufFTo0RiCQObZIa9lnsdrgJqWdofW88wGheSuy6ceKCvjONXeWb9103d+u6u0+8eTYRfyPA+dgMf8bU3jJzPxEGnoqjViTRpbbj7DcizwhXi0Btts2oVymjJlEBcVsiVISG90tCuWiGtIk3bklYGZRRyqtE7iRhZkbxC1hC+fnjvNVhU6ZkNviwXLua2S6r2reSuR8obp9ju0eV6vkpP8Nh/Bng88Bbk5tvrxFI/SNoWYa24vJ9c8EuJhEILxBgzOFjJ9t1RSUw2jzd/DWEhVL53XiIQ5kmHxZKovMne4EjpWw+cpKQvjEGE3KAAWblBuXzBWRzYoKmI0Pv3vf/KZ1Wz4VbGg8m5Nke3EyDztXgj9GWulrgr/YBoOE6AtI6GrsI59Mgp/MIlgpoCXCut8EyOTKmJgnQeeLaA4Y6CFTH/OzHUdVCtRkErKI16aG8JdPfhVzxQThyc5yh+VlrSw4ms3MI+iLYHPzduTyeSeq5qbS2aGy1sHdrpIQzrC5D95EWYAM1dnk0vZcOueYrXz5jeuSSkIlyNIoduy2zu18j6du4sSvjr0DE5kJXl4cFuOEw5OlUmMICTESusEnJE+hKO+Pa7303h2IBRqxEmPFBczG2sZdL28c2PgFSVXnGdyTmi1ALBIB76sQsN6IXb3vQn9gNWlpA1pbGwloIGHMlVGczyIqltEUloh39ZPp9WM+JRCiVaEou0QXp0zaYKAlSuZbVXFMDXBzD5cCNGsSc3wyCfTViwewu/dWshZNvCaMmW62l6FsK+6m0U465G0gzXL5iBil+KCNr9RIE40puBOGB10202zNiDQF3yDgkBKJ2PQZRb1In9eIq5tvxjWR3Tg4fJDn5uxzmtCLuK8P6xrWIpvLV9fasX2MUUni3vU7ETJaMJedvTKQrDcbn77v08VNa7Z85/qrr/8LuqRm0WS7eRZhE3gxNH0Eh4aO4ta+jVgdTKNVKBOcqXH8mlw0FmgyFBPEHJeXsKYpjlWtlCuS5iZJqxNZm4RNFzBX5giTX5OqZtMrhne4XcFJfQgZm8vMEpCyhNv67uJ8sSYFcHX7NZyarDYvtVx82nY0NygGaVLsRlAJM2Sqil97C9KIazbWp/rfYKINq9LKivtYKlQhduvDPbdg4vw4Jgvj3NyXyAwTB4kPdN6F6dkZZPJZ7n9ZZGeSe8rNHsfCySdw+NwB9DRtKGIFxlvW0v8P9z7Itl/9i0995f7SgSMvfKpQyfXZi2UxSKZ5vHwGf/fEeWzviODs9BLssAJ/gx9+wqCLRDqoZMZCVhC5GQtre7uwaJ0nx0aRKAUgZQJDMumi2yKJqxS/zxsamU5FBtdI08Gb/WIITw8/gT+45bPIzJ+F6RfRVOqggChHpHuwKjwObPB+ITIWaUK8u6cHp2eHiei23UIAZ5WERamZpqqV1/xLl2jY/nP7tafO/NVan4+OKYgYPP4MKqcO4fn0EqL9AfpdDJokUqVyGs8+cxrDUo6IGq0awbPFzKcpwPz5oSOItDZW1rduTmAFxluiwctHd8OOr21Zs/UzrfHO54sWA9mJOqQLmaDI5qm5NLIUYecJxUpN51GezRDDVAGFUjzF2Nm3nbhYGUkWXM3lUFzIQswXSMPMqjbxHJfp0jICH5ZdjZYlSmvmcrM4NXMEt7Tfhd09N6JUzLHNrZwSX1f7vePZRMkTKX3x3PdhzR+hc6ncZ7Ngq7+hl08qVdb0z75zN6YIbfJ423DAaM3byQ2ySMdThnyYgqvv6/OoEN8dotSPMWqM756j4Pup9BzCZLUYAcFoMYZ7M9ZJ8UuwCJoNB6KZsK91Disw3nIBM3O98533PLZz846PrV+95euiGkwmyUxVigzwMFgIAz+xTwJFy3kCPTKU52bnkzg/fhQvDz2G46MvQYv4WJcXlMlvzqdMZBnM7wVH3lpk26vWEKo5rrdGmXXMeW30J2gsncMaWafPeI0fZ5q13NehEO0qCfHY8eN4bHAIPpkAFcpbI2oUbcFm3q5JsBRxId1+b0nCAPA5gQn51MIL78hUUgM+1ccj8lgnsVDhAAWTlAmoNnI5izd9Mwi2lOm3BMIyClmdrwhh7oK7FcNpKRUJNi+KopjECoxfyq4rD+x4gKE+579if+WB9HeHvnZ46OBHxqYvvKdcKreIhaLqU0scn2YNQm1Z4amDQWzLuUQG1qLJa7dUv0JAhwQxokIXrKpgHb8p8Lps5j8Fp5kGzzltN/WRBBmz+RkcfvmbiOYUDE4sEbOkcT/Nz2MuAzpc0z+hkYZRcN4gOrVZjWozIW0BQtE2473r7xkwc6VishNnWNHD0xN9O4dTxz4jKkZrMSWTpq9CRUljZmIGXT0+5JPEehlsC0aKIyby0EirG4iImE2W4GsVUaLYIhwKoZRz0rnWePtQZ2dnASswfqnb6jwgcEG/9KMDf37ipcHTP744NXx7Ort4Uz6f3VRMFVUlUyIoUnW6wRKoYPk07lZNyh+zaQrXFNL6sA9O4Gyj2rbD02RmuZkvFe1a+atbcFyhQO0p4qxTMwu4SGbXq+2q9u5YnhfbbLmMs4yUVYuIFOk205Xa3b8RG8vrCIDJD7V1bn3CwmH/ty/8510HJh/9k5ge2zlVmBYiFD+spdToidNPUSagIUg+//yFAqLxEJ3HxCJlC5H2CNoDrRiVSMChMtaIGzCRGsf4ZJKlgnbU1ziIFRr/Kvsm7b3xD7N0UZ/4x5/se+HQxROdJID3LKWXbplLTF27lFpstjNFusAsbybzpjndYCUSiE58ryXztmkkSIunGF6J66WmuqaNnC3k2RNxsVGiLdvDEGYNpygAqFZYLjfpXmsCTjmyLrk0caK5k2hItOEbg4No6F5VXL+4/x0vzf7wvuHpY/dMzSTW7Qq+Ezsa9qCN8teDB48gQ5N12/YWTJ9f4jFG31UBJMeTBMlSXBInjrwUQE/rADZ39+HksWEsFOdQyZsIRWJZihuOYoXGv9rGWIJTqJxxb0MP2w9/MXg003Vx7PzNZ8ePXzudmLx6KbPUVSyUo2alFBRYDNIcoKBZdaJa0/Gbgl1jiDjXyxrASMtMtAdNsnjGtp1tY3lvaJcztpxVDPzbeL7YRBUE4RQymf3HzyzgxanvI9nsQ0suf+Nfv/Sfnp2fXwwJusrbEp9IvIrflO+ERXTmhew5bNgQw8XBRSwsVDCwtQVmKo+xkSziPXGIxH2XJ8/jd3fejb9/4QgOjL6IliYfh1SbIvHhqBo7hRUaV8zOZ/cJvERljG7f2r//iw8bN0Rbz144uHp6abI/lUmtn8/P3VcU0j1eduQ05nYCJIHVaVo1YNnxp8AlDRY8U+wJzq6tU+ITBsustJcbu+diyp4MB1Ei/x/xSSBrEyZrzPcyZpMjNVXEVCqJxyYeQSQSgRYukXCLlOfa6N/UiDAFWSdeW4RCFGdHtw/jh2ZhpRP4eek7+PnQFJnsAMo5ky11NYNa9Pg7tl43jxUaV+TWdnfe+e9YnDzObqxK4sTcLv/f7f/iqhNjB3t4WTWlIIrF4EmZsFsVXaFWTFZm3IDL3XLHrKVLTqRs83W9VWLBxa29/Q5tb+aYzgGcaPCayTDigrTUT3ApKyEwycwuTZUp6q1ApVihgVKeliY/xglDTy5OEfxK2HXAj43b4xD0Ck6/TOmSJGHLhlaAsL25WcIwumPYn5yHQC6IlRrlc/SbNDXd3bzuwMyZQgYrNN7yNOlyB4tSt7a9Oy/JAuNcuCntj/egwd9EUGaFfF47utR2vujNq8KwvAgby6NjOH7bex6vE77nh4HaY49StKrr051JQd+kgbSxsz2I1kaKttMVjJ9J4eL5POEVPvSTIDdujaAj24HRwzqKkojrb1iHLeJGDB1OoHVVI+INBKhQft/YGoBOwtVNgmhDnac++M4PPrNSBXds1MXmlGxYNuuJIfCdy/g+wgTmX0csRNiSiWm64Gqt4PpnL0Vy82D3LieaeFhOj2Ub1ZUPy/hgLBM2vAniGW9XyS3dwtJ0kRfRsdIt1msrFAugNaoSuUGgVCaPU2eSWBOO4F2bb8ZF/znc0XQbHnniKVgRC80xIlMGE5DpYImw6zyBP+wr7N7yroc3brxxEis46kbAdHENyy13nUnNYP/Rn+H65i245ar1+E5pZlkVhlMRyctzqjgzLiEU4EbXHnlguc+zv7wTrikui6iX+2bnHGwdlhSQ0dIZIJ8cpLSsDJ3Am8xCklOaxYqAcBNF6+159Iej2NP5Phw+Mozh/AX0DgQxczbBV3k0t1HAuETZASFn/R3rRm676VceFnizkpUbdSNgSZLLvJURz2spXVIs/GziFYxNHYNOvLFAKZDlUoA88rUsl7S3uWnmUbfh0IVc8Kxiw6xpN6/ZovMG5SCdo+hlSnx4ZAQPuglU8fvYjVKttIC43omfnn4ebdFOdDT2Q+lZRFOLBoU+fHJoBhem96N1YQN+coow5gYiU85S2qRTXt3mw/rQWkwU55Ep60vb1l7/+e1rb17ACo+6EXBZr+iMAuT1ymwHFEpztGAQ58j3NpMwVc7KOCkO70Tr9mHjaBV3nrVct7q3MFDNl026se4BXcE2jOWHalyxe0yNL7aRTuiYGS2iKRbG9g2d2H31bVgTb8R46ThFxzrmzuQo2CqjXBbxgn8JQ4mXURENFGZpohFh0RBXsSGyEU1aDE/PHClvGXjH97Z1btiPt2DUjYDThYTudLK13ZX7DhDhI0CEQR+sCznXTsBd+un6YtNt3cT+Ojx/dXUD2yaghSDDtDnJX+uPEsRYyjjrxV0Uq4ZROzk3q8Zga4Q7+3xopAOvb7UxU16N7x9+lLcm1sv0fTQiDJqiaCe82SyUMLmQJ7KBInHCpgN+Ey0WkfptV+FbLz1Kk6Tn8J5rbvvrvXt/bwn4BFZ6XLECZgD+CEZU0gN7EzbpH/7yzaZfC7OlIVXzaduez3XVi5thp480K5L3NK6aOjHe1dVklgeXzCK6tS1YUAtIKymsi6/GU8OPw9/E1hZXUIvMakEX99kFA0sEWqSIOPinM4/iOLEfRpA0s7EBbQ0KoXAEjeZLSI9lUCjQJFPoNTLbNhEVVjKOvbfcjqdO/xxC0D+y79/+0R9uWbflAt6aDg5XtAZLWExvkvRk/8nyuHl13zX9yYUJjM3PYWThLFSWo7KjvPYL1UBKcJo5m65g3JDl0notpxiOEfP5ch5bYlshWzN0k5Ar5xCwWb3b6/Bp1D6nRIIVdAUiQahHyZE3dAURDMj8w/JzGSwSNcgsiOIjYKSJtWwyiVDIwyAo8t2b+pDLzqEx1Gbvufb2xZZIeIMhCyznz+MtGFeygE2L0kvoBqN9Nvf4mld1Boh1UlM4Y9jVtUNe8lpjl+D6YrtKplsCLs1zl6VFE9kJ/ErrZqzufAcOD71KRoDVoDhwKNz3WdVqDuc+258iEpN48KaznUgJ4FhMsEZPROmTedZCfoquybwThVTMFmlCkBZTLtwXENBRPoNiwkpfu373j1taOr9dELInho/PJzr31Oo6V3JcsQJ2sepF9/byh/5yd+/0xaEtjOZjRXa24dY3mw7+zP2tyyx42mq7eDX/j1VmUPpjGk4ebPNOaCLmCgs4N38Wd0SDOJA/79ROGbXZYFdRL7g5so0y4c1zxAqx5YpMizXSVFZUqKqEb5NGl4tlpJJst3GBt1CWFIF8u2Fkhfh5Mb715b72Nd+LdO9+8p179rzl7RDrJw+mq5kXbb5g2ydWIYwa7uyEuzWBuFF1FZZ082TLXQDGmsoyQVuihFPTr6I/MYj5hTSRtkJ1pwAI1iVCdgrm6V9RpIDJRyyX6GxdyyqfizqyWabRXj8Q1k3LoAllQtXC081t7Y9t3XjNP63e865De666Lwf8JX4Zo24ErIiqxcpvvFyYC9Zdf2ItQ6+4D7btKplvmV55j1g1t83+BlRYaZBVgkppy2S5gAdPzxCdGEA0FHEnhpNIeQvU2LBdV6CKxC8RmlYgrxnxhZGs5CETjcloTZXytUq5RCkS7HhDy2J7c+9P/cHwP21fc/XLv3v/n6X+WPjqW2KK/7lRPwKWJMPLW/lwNapaj7WcQvReJ4kG5ADPgyusNwTBmqxmanPnVXh17KCzrpidj8xoMRbh5TV8DbGLdNlWNSKDt7s4+8P7i1RsdDZ0Ik4sU2ZukC9Ctw2xRMnQXFtL3/BA/+qnb9r57h+87+YHRhx381Pgg/ilj7oRsChKptu2uQpWcG32AqBlHK7HKtl8b6YKblq7GwenDhI8mEVHrBcx0uB8pYSg2ziVmVSFFRXItb0Qq6bZAw7t2k2UDKIKTYq+Kd5u7CkrfpXiY3FU0QL7V3Wve2H1xo2D0nTr3Pt3M9Lgt/GvOIT68cEi603Dl/mIXqQMwVUwF2cWmI/1WCCDryFCppBFqVDEeza8G/vPfwu3r9uO5HSefKVO75OqGn/J/gxs2LVOeNXqDnfyNITb51f39b/W39Y81L1q65m1pjktqdb02i1bRnZ03r0itVQrNepGwDJUa3leCi8d8oIs06qZa5fcZ6+xBWi/GH4Jn+j6HXxox2+hR+3HQ8d+DLNiuqv4RdeXe+dEtVjAFmuRtO2afAZ1bN2468t/+fvf/Jzzpn/ElTyueD7YG9WNz0zP73r0HqrIlrfO1ym+s6r5MFvR8Mzxx3FjKIoGYwELqUlUm3XYTtrkjFpVZS3xrUq42pNasMX/aRvDK2XUjw+WZMtdVrYM+IcLcniFdcsAD6t2Y+2XxhMXcfyFh3hR+lJm2uljadf8Ldz54wVoy5Gsatgr8I0/bFb1WS+jjvJgwduRDryyw2ll567t8dgeN0Uyl9VkWdwIoyDL+Ie5aSQXKkgKBJYoQs1fc813fCzPc71JtFzCnOCw+ASQ3mTjkCt11I+J5rsgeUFtraGZ5W2PY9m1GixuynFJ/spNa0MQBt0USaj1kbZrYIiwrIyH/Q2qwSr06R3KYBACSf5/Aa/0kBTye6ILVbk3tpiabQfA9g32Fn1X2wBfkr86OS1lQVCX7evgmXqv4M52AzQWfLEtCPrjfTCYTa8GdyyatlhLxbrYcYWNuhEwXVddpHCXt1RwI2fWlKw92oZN7VchqkZ5kxPL6/ds11Y7WG7K4/lt0d0Cr7boTKhtqcOKcCl77I53I+qPUYCmw20X7xwvSJYoiivSZvCXMepGwIZFebAoehA0/0chQbA9H7Z1bUGAyHunatItuHPLddiq+oDiduHhgnfMu+gWDdQiZM8X21gTGUBvYy+KlRyvHBFcK8AMO8GldsXQ6yaKrh8TLfLAxq615XfACYM1NtVTyFUKfC9Ehi2zTSmZyFgzk554F3GvMd7A1FxWK+1UdtRW7bPB0uFSpYw10V6sb16HxcwS3w3Grn6g4/3ZTmyok1E3AhYNy7Z0Z2PiKolPf3P5HJ4/8hhBj2n+RHdDO7b1bCPivoCAFsB1/duxmHW2bPcCL09zncZoHu7sCJhNgvncDHqkBQhGprovhPMWzkQJtinbqJNRNwKWlfhIyN96hNfSLIMT80THncyVYcJJdcYTk9jcsRYbu7egM9qBBmJ7EukkReFCrcuZq43VvYhRO58mKTi3cApnTz0Oo5TltVxemiQKcqUp3HMk4I+NoE5G3Qh4V/OmIxv7r/3vxaI5VyoXq9ExC5YUlQEPzvayTHMPDL6Iuze+F+/axDbTWKJI2FjW2a5G/6H2VDWXZtvnLdHx3xyZw3iuwCNv5r9LRAGWSubc7qtv/Yv3XrPzIOpk1I2A2XolVfQfX9u1+dHGSMtB2xKzXud3VIvcLUqDZJyaOo+54SdxfbCIsYmjfEdvwYU5vc2wPAjSXYIGwcuF2Oko0S1pqmu6TQq0lFx7vOfQpp6djwd8kWNr1txZF9vasVFHSBbw+Y9+afTE3FN/eOTk6VWPPvPtPz4/NX4XpU6GaZiq7WLFTFA+nx+vjBxCbvoUhucyfAcWPuxqoFQzzba7dNR7jk15t4BPlJSybtjq2u7Vz/+b2z71f9x5ww0jn/vcl68otuh/NupKwG6dVv7Qoa+cOd698W9j0Z6DTaFoYnL2zPsnF0Z254umVCyVmcbhQiiEs/M5ZA2Bl85Y7mJxvv8zr5M2yKQrTk013YqUbhGJb9uijz1rru3d+sLG/q0/IA65MR6LH73zhr2n6fPrJj3yBm8gIni7RtXp+OYTX9rxnSe+/vlwJL6wa/Puw0fPHNkyPvvi/SQ3NZeTE5oUWzKRbopF7HhJN5AtyEsBf3xRENPxgN9ozKTNytqeXQ9tXb/z5JFzL2wrFlPN99/6+//1fbd9qG587ZsNNl3fFgI+dOiQMpE91yko/sTeG/dmT4y92PDlb/+f/y2VS7UNdG55dKBn7enXjr90zezSiQcYi9jWtOUru7becHBifnjThakT9/jk2Nxv7P0P/3XXxl1Lr776k0hGMBpv33k3W+VXdxr7usEF7O1w8LYaT778ZEOmPKM2o29xz549BmtUduqVA5tE0xI23nDzqTtW31F57rnnpALGmjQzqt96694l1Of4l5ZECP8PAPgFhqae3ywAAAAASUVORK5CYII='), - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - '{"春江潮水连海平": "海上明月共潮生"}', - NULL, - NULL, - 2, - NULL, - NULL, - NULL - ); - -INSERT - INTO - test.TEST_DATASET - VALUES( - 5, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - '2022-08-09T10:17:16.161342Z', - NULL, - NULL, - NULL, - '70', - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - 3, - NULL, - NULL, - NULL - ); - -INSERT - INTO - test.TEST_DATASET - VALUES( - 6, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - '80', - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL - ); - -INSERT - INTO - test.TEST_DATASET - VALUES( - 7, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - '99', - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL - ); diff --git a/airbyte-integrations/connectors/source-mysql/integration_tests/seed/full_without_nulls.sql b/airbyte-integrations/connectors/source-mysql/integration_tests/seed/full_without_nulls.sql deleted file mode 100644 index b4d6ff698342..000000000000 --- a/airbyte-integrations/connectors/source-mysql/integration_tests/seed/full_without_nulls.sql +++ /dev/null @@ -1,306 +0,0 @@ -CREATE - DATABASE MYSQL_FULL_NN; - -USE MYSQL_FULL_NN; -SET -@@sql_mode = ''; - -CREATE - TABLE - test.TEST_DATASET( - id INTEGER PRIMARY KEY, - test_column_1 bit, - test_column_10 SMALLINT, - test_column_11 SMALLINT zerofill, - test_column_12 SMALLINT unsigned, - test_column_13 mediumint, - test_column_14 mediumint zerofill, - test_column_15 INT, - test_column_16 INT unsigned, - test_column_17 INT zerofill, - test_column_18 BIGINT, - test_column_19 FLOAT, - test_column_2 bit(1), - test_column_20 DOUBLE, - test_column_21 DECIMAL( - 10, - 3 - ), - test_column_22 DECIMAL( - 19, - 2 - ), - test_column_23 DATE NOT NULL DEFAULT '0000-00-00', - test_column_24 DATE, - test_column_25 datetime NOT NULL DEFAULT now(), - test_column_26 datetime, - test_column_27 TIMESTAMP, - test_column_28 TIME NOT NULL DEFAULT '00:00:00', - test_column_29 TIME, - test_column_3 bit(7), - test_column_30 YEAR, - test_column_31 VARCHAR(63), - test_column_32 VARCHAR(63) CHARACTER - SET - utf16, - test_column_33 VARCHAR(63) CHARACTER - SET - cp1251, - test_column_34 VARCHAR(7) CHARACTER - SET - BINARY, - test_column_35 CHAR(63), - test_column_36 CHAR(63) CHARACTER - SET - utf16, - test_column_37 CHAR(63) CHARACTER - SET - cp1251, - test_column_38 CHAR(7) CHARACTER - SET - BINARY, - test_column_39 BLOB, - test_column_4 tinyint, - test_column_40 TINYBLOB, - test_column_5 tinyint(1), - test_column_51 json, - test_column_52 ENUM( - 'xs', - 's', - 'm', - 'l', - 'xl' - ), - test_column_53 - SET - ( - 'xs', - 's', - 'm', - 'l', - 'xl' - ), - test_column_6 tinyint(1) unsigned, - test_column_7 tinyint(2), - test_column_8 BOOL, - test_column_9 BOOLEAN - ); - -INSERT - INTO - test.TEST_DATASET - VALUES( - 1, - 1, - - 32768, - 1, - 0, - - 8388608, - 1, - - 2147483648, - 3428724653, - 1, - 9223372036854775807, - 10.5, - 1, - POWER( 10, 308 ), - 0.188, - 1700000.01, - '1999-01-08', - '1999-01-08', - '2005-10-10 23:22:21', - '2005-10-10 23:22:21', - '2021-01-00', - '-22:59:59', - '-22:59:59', - b'1000001', - '1997', - 'Airbyte', - 0 xfffd, - 'тест', - 'Airbyte', - 'Airbyte', - 0 xfffd, - 'тест', - 'Airbyte', - 'Airbyte', - - 128, - 'Airbyte', - 'Airbyte', - 'Airbyte', - 'Airbyte', - 'Airbyte', - 'test', - 'Airbyte', - 'Airbyte', - 'Airbyte', - 'Airbyte', - 1, - concat( - lpad( - '0', - 262144, - '0' - ), - lpad( - '0', - 262144, - '0' - ), - lpad( - '0', - 262144, - '0' - ), - lpad( - '0', - 261568, - '0' - ) - ), - '{"a": 10, "b": 15}', - 'xs', - 'xs,s', - 0, - - 128, - 1, - 1 - ); - -INSERT - INTO - test.TEST_DATASET - VALUES( - 2, - 0, - 32767, - 1, - 65535, - 8388607, - 1, - 2147483647, - 3428724653, - 1, - 9223372036854775807, - 10.5, - 0, - 1 / POWER( 10, 45 ), - 0.188, - 1700000.01, - '2021-01-01', - '2021-01-01', - '2013-09-05T10:10:02', - '2013-09-05T10:10:02', - '2021-00-00', - '23:59:59', - '23:59:59', - b'1000001', - '0', - '!"#$%&\'()*+, - -./:; - -<=>? \@ [ \ ] ^_\ ` { | } ~ ', 0xfffd, ' тест', ' Airbyte', ' ! "#$%&\'()*+,-./:;<=>?\@[\]^_\`{|}~', 0xfffd, 'тест', 'Airbyte', 'Airbyte', 127, 'Airbyte', 'Airbyte', 'Airbyte', 'Airbyte', 'Airbyte', 'тест', 'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', 'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', 'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', 'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', 0, 'test', '{" fóo": " bär"}', 'm', 'm,xl', 1, 127, 0, 0); -INSERT INTO test.TEST_DATASET VALUES (3, 0, 32767, 1, 65535, 8388607, 1, 2147483647, 3428724653, 1, 9223372036854775807, 10.5, 0, 10.5, 0.188, 1700000.01, '2021-01-01', '2021-01-01', '2013-09-06T10:10:02', '2013-09-06T10:10:02', '0000-00-00', '00:00:00', '00:00:00', b'1000001', '50', '!" #$ %& \'()*+,-./:;<=>?\@[\]^_\`{|}~', -0 xfffd, -'тест', -'Airbyte', -'!"#$%&\'()*+, --./:; - -<=>? \@ [ \ ] ^_\ ` { | } ~ ', 0xfffd, ' тест', ' Airbyte', ' Airbyte', 127, ' Airbyte', ' Airbyte', ' Airbyte', ' Airbyte', ' Airbyte', FROM_BASE64(' iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAYAAAA5ZDbSAAAACXBIWXMAACE4AAAhOAFFljFgAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAEIPSURBVHgB7b0JnFxXeSf6v3vtVV29791q7bIkS8iy5U3IC2DHNnIAJ2MYQl4AZ4HJQB6TmcybQQz5ZfHkDXmQkEcCgQDBwWb1IrDBu4wX7Vu31GpJve / Vta93e985996qlu1k3vzUJiq / d + xS13LrVtX9zrf9 / 9 / 5 jmDbtgTAQl2Mzwn83zc8vfzBPn777Gc / az / y8qd9iaAULvoSoQYEVdGW1FLFtCuo6AFR0EoFcWkhX1xoX6uK5YnSr5fE4v7PXPPI3Oc + B + ENH / 1 Z79z / a + Oz / 8 KjX8IQBBKwQMPG22Q8e / Hrvuni + e6Z / MjWRD6xOVcsblRDaJMEKeRXA2pZL6NoFso + ySc3CO1TF3MjL / cG + 62 oHJCazYYH77v + C0W8TQbJVqxbAbvfm9 / 1 nvv2kf / cO5ub + r2hpeO3SIF8d3bJipiirQX8klAsmYhFJdJdoFQxIKoG + qUd9lx5utTh7zRHkxdHFb / wj / F4 / JsP3vizabwNRl0L + OsX9 / mkhH63rAVeKKbThaHcqVv8duDP5tPT61PSFIKKhsSChfYOGZm0iWIZdF9EuWwjlbIQiZsIlltwXWQt5spFfH / weciajcbG8NnmePw / xiK + px + 88 aUs6ngwAYuo0 / GRvn1l0YRhl / MfP7z48mdGps9 + KSI1rNfJw8ZCKpKLJjRVhKaJKOVtiORWRUGERDejIsCqkDbLSxg ++ QouXDyE5rYgZNOH5FJh3cTs9JfG5xY +/ fs / v7YVdT7qVsBkne2AobxUKVU + nEjPf6ot3NbdqDXBktIwSFuNiohgQIRtAqYuQBIFLmSZ5rRgC6gUBWhBCSdVHRdME9GwhEhMhmgpqJTQNbew9AcLudQff / LcJzXU77DrVsD / 49 RvxZ9KPfFHo3Pj / bd0vyd0 + 8 CdmEmPQdJ0FAqOIMn3ks8VINB9SWIazAQtck02dHqORB5t89F7NHosoKlJhk + TIQsyFFMNT4zNfzRx / Mm /+ E8 / v7URdTrqUsD7Satmpi7 + 2 sTs5Icmkxel7koRPUYOaWMMgqTCIuExASuyCL3CfqTIBUui5pos0V / bEkCKS5OAjiWB6yWaFAppcViGYJL2B2Vogg9zi6n7p3ILv / bFc3fUpSbLqMPx2tjYuuml2Y9WimK8pCxg7MgzSPiDKHUWYCsKLNMm4Qpca5kQBf4fuGlmkbdIQrbovmGQgDUJqmLRRLDofQLCIYkHYYJoIxwRkMyUGtLZ1EeHRuQDdIoTqLNRdxr88MMfkJbKyX +/ mExu7wy3CLYUwvdm0vju2DiskEzaS8IzBKgq99P0GJegFlzQgiNsg46TScs1P2k03SffyzVaIW1nViBA51MFhVKs4rZ8qfzpD9gfkFBno + 4E PNPZuGEhO / 1e kBk1pQLWxq + CNtCI8NY4FEWGadiUHgASaTBlgKSpcCXK3i04Nxv8GJM0XaL /+ iK9dJzlmHOJRd5M4CIiShQ + OqdgyEgVU / dseq6wAXU26krAtr1PHE8Nvz + XL8RVUUPJKqKk69i16h0IR8kcWxKa1Q4IFvlV2RUqEzBJ2WaStmuoiM3vCCgZJTSHmtAR6kWhrPO4U1UF + IQgOoJ9kFUToqnSxKk0jGem3s8sCOpo1JWA /+ TFc + unc6N7YSiUz5IQpABOz59El7oKm1p2kHBU9Ac3U0RsgWX4lOg7grRdbSaNtZiwXZttsRSK / O5w + hRu7L4FQTFKQIhF + bOAgdha0mgy1z5HyyWTgJP8wr0nmzLrUUejbgS8b98 + cWppYpuulzuhUypDAZRBwtINHacWjmKTdguujl8Pnx1BhaBIFmBxSXKttbmwmW9m0bMjdGcCEAGBVDmBUjmHa9puQJne61f9GGhch / nkPFTZxyNvwST / blodk + mFbey7oE5G3XzR7l8vBHPl9LWkdTEWGbNImEfIZI5Hc8MYnziNO / x90IqTBG5QFOz6WNs1ylybBfD3sKcsemzQcRbxaJrow7GZw9gavwZhqREdsQ60BtuRyCTJUkg83bINiVIOMVYs5q7133YkiDoZdZMmnZsYaa6US9vMsihblN4ITMAWS38oy6WI + fjCY4icUTFMM8Ai6TJBsuNIhnRjYha4MJnkTQqoVMpxo4qfhJyFT1YxsjiM + cQc3tX + a7A1C + n5DArFHILwQaUMuJRh75FlA8bVk5lcC52pLnDqutHgXCbZXjb1XstyzC4LjG2XxVboQTHmw / esLA6WS8uDZRK0ibZQuxNvuT7ZMA2sb7qK3qdApwnBoA9m6l8ZewUdUhu2aHHMpYd5rsysgMzUgO6LFICZhtGXz6XbUSejbgRs2 + Y6EkKzaYluLuv6UvoFpMykxZS79kYgNwYpRRId6dKtTMltR6iHTG4XSLdJmw00BVqxunE9JrMTXLgEZJGflXBudhCzg99A6eLjkDPDzEzwScRSLvYZLFc2TLPJFsy6CbTqRsBls7LVNHSfTZmMIpJKSY6PZZrMI2YBDgxJwZWkOpPAoNdFst8XE6PY0bKH + 1 pm1vf03Yn5zAwFVhUedLGZwHLonF3AM + dO4NDRQxim1yVJ4lrMcWz6DF1nGm35KqaxBXUy6kPAJEfdNPqYUrK8tyfWSxBjkAdKXLKuNnMTDF6nwn8Ze45FyfPZWQSFCK5qvh5doTVYE9mIwZlBsFya5cfMk8s0YRSfgsG4D8 + 1 KFiKyPziML8tkAYrCglXdxLpimH0A29S1nMFjroQ8Bd / 8 km1WMr1MhDCpCuuyQG0 + LsoWrb5ZWYC5RbZFbJ36W0X2SgSRHVubhC7YjtxT +/ dWMokMM00lCyB5fpzhmApqgR / RIHcqkH1Oabb8fekxbITgTONLxvlno88 + 5 G6IB / qQ4NDoUjBKLUw2SmChmRhAX2BDRQQy9w3Mg00bU / ADqEgeCgWDYmkc3HmWRhDj6Bp9hiOjnyPgiudR + B2VYAi97UsOmePWZ7tBHJOxCYrDkHB + OWyXm5pj + bDqINRF2mSikozYUlRJpKyUUHOSCKuNhEs2YnpwggJxVcNqrjGcWBDqGoz86Epo4zXBk + iOTyMEQq0JGaTBds9hgRMAhQMoYpuitIy00 // kTvmxzKSgiLpSChXaabDFnCFj7oQ8FIl0RhVor5NTVuRD5tYKJ9HhXDoTS3bcHFkiI7wuWiVIwzBkQ3XalYQzIj + ok / GqxoFU5KBBEGQErFF / D2We7zo5lZM + 1 lULdUidcudKJ6ACSDxpXKZZtTBqAsBL + Tn4xO5cbFIZMA1TTfhzoE70YgZ9GpLeIHSJoNBjlYtL7axrIZQcLRSIh8rxxT6xaStCzoHQNiRpu0d5ppkOKZekpY9ZjZBqPl327LEpXKmAXUw6kLAAdUfYFUYS6UkHh16FBdmT2EHZbVILRBAYTooFWpWmmue4DJGEr0qOVEX11HRI / 3 dZ5gph1DVevYUO5fInbtHPzkns90PsemOYhNIXQejLoIsyxRjzExKFnGzRAnO2GN4sjSJR5ZyKBHMJLjpkWXVTK5DIjkskjMurQx2BOpMBCZiLtDqrOAYB2pxms35YnZjE8Qg9Ktimqu + cujjCq7wURcaXCBzKAquFgqsWkOBSTpdIdpQEfQqW2QvW4DD7jv + 2 PGp3l + XPXQKAfhxbu4MR6jV2eHhnQDHrttCHUgpCRSsRbRF2jHQMBCbyQ5f8fXk9aDBQkUwNEdKIv / GAg + AGU8LBl9hWeL7etlUzS7XVNHRbp5Y0R0H1nYnjlQ9hYedVKtAdIq6G / wxbGjehLAvirvXvx8lwyjue + dzJq7wseICvmhf9Nk1u3jZ42H7YdHUjbBnUr2aKsffuigF4Aq3pn38K7D6ZyIRdNtwyu74oRbPZdc3beC + lP3HymqdhFpAdY2Hd0dwrMBsbg6bWrfhroH7UdEtHJl9LbLvuXde8dUdKy7gzNx4 + 9 DMgb2zs7MrwpkOPvKIVDFLmuBKlftVuKAGP6L2L / fBtlDVPpHUcnXDGvRFVpGiqyBRM7IAmWIWzYFObG / bRdBnCc7U8KJm582iW8fF4zRCvOZz82jLDOKGiB8 / Hf4R + 3 zf6YX5K94CrvgX1FuDk5VysUUXFt9DmqwNzTzbh8sY8VCbQEGN5GivUI2VLGuZOYaHYqEW + dLxBmnuTHYGcV8jbu29Czd23IMmfw8v1TkzPYRb +/ YiojVz + FN4U5MuVIMxdufw0PN44vi3sFCcpbRMltpClRWzVG / VWPEga4ewQ3 / 21 LeeVqF8NFkeb64oha0 / vLDv2YpVqJALtSq6oKtiMKWa2tixdcXZfcK + f3Ft8pI / KxAEfUm0aguUpkgqYmoIGXuharMFr0RHsFxEi3Bos4ij0wcxlj6DXe034v6BTxAmPYXB6aPoJvp + V + MAThunavCml / l6YbQ7p1RNxpOk7VpmETalXoZtKll / L706git5rHwUTdfm7x / 6 Qk + j1LznzvZd1xRDF4TX8qd + m / kt5uaIiaHgyG / 4 NP98KBv74dMXvvZoj9n +/ Jo1d5bf7HQRLU9MEs0JTvoyzJnyXpJ4WI0gGG7C4tIkCSPgfHS12Aq1AmgeDkhIG2k8v / Q9nFh8Adc27sVdLZthj / 8 Y15dnMEHRVp4Fa2xiCF7k7dw80ISHckEJop + AEp2lSoayOJy94k30SgtY + OA3tl87m57 + qwVpdoM2fR5NQRVGj48D + xXD5pFwNluRm + PrOnQ787GF0Gg4mt / 67 D93wsxiUTBtQ2SXuSXYDMUoUgS7QLRfFLIVgkcecUiRf4NloIbgEg / 0 bpmwx4ZwjFKuLL554u / xC6IP90Z0zJEACx0qLllnadeAjyoAIgq10mqR5eamhM4rfxnxigr4o9 + 5 dvP56bE / t0VjQ0tzBBm / QsSAjLCkcD5VrlgMtkdFLWGV0AJVGVAPzO9 / r92p / 4 je / sM3Oye7hJZg8fA2S8K5rucmjFpH4FPCEMqaK1yhFk3Yy6BKHmQT + S + 6 kTIdFgz64fNZGM5l8ZWszc1tv + ScR / QyLvcvnxySd39Znizwgvor3v + ysSIm5vGxLzf8 + dO / tXNycfqPBVG / qa2hCbGoD6YgIxLT3HSGKAEf4cYkq4bGIE6ffhzHzvwY87Pp6NHFn3 /+ W2f + 4 zVvll7dtmqHqEk + mb2SLmfw3MhzuLX5HtxMOSmMPBfgcuzZ9vJX70zM5FYF5kCQql + FP6DBChH3G9Uga5JTICDWrghHubx0a1ng5f0WBn5XUtYVL + QVEfAaeQNRqdrnTal4y0DLgNAajfGVBSZf + 0 NAASH6rLJRJFOpE8rvJ + 51 oknBfMSEavqQSWdXn0sd / rUfn30w9Ppzx + 3 OoCr5Gi2KdFmpDsOjXzz9AwgXfoEyYdIQnfjLsm039629t / awJgfmV2Ui9hW26IwYJo1ubFVhNUpnuDbDmimt6gp3UWJlOni1wIrvZLRH2vgicmsFc / 23 cqyIgGPBrmhMiV + 3 rm1tcFvbtcjbCU7GM7JcIBPIAizdsHiNlE73TRJyIKJBIsiRr8DPUXBaTL77TPrkqtef26eEpJgck1kNM3sfu / AT1jweunAaJ1IZXlEpkm31SwGaPAZ / TxWd4jehWoXJgQxWX8VuLsHPiH5Pwz1wg93ViXdeHVuPgBTk582Xc9i9 + ha0R3sIONEdjqIOxmUL + OFT + 9 S / eeazv7060Bv5t2s + hemlObqA7AI59S5suUhFN2GQgCvkg8t04xE1aTOLqH1 + CeW8gEwhvcGolO72znt89sngoUOHlFCwRWj2tQpMg5kHZ2AGNAWzTUGUaZLwGilTR2ewGz0RuvhW2Y2mXR63KgbBBTOc6JgJWZBc4VYPcScGTZiSVUKpZGB7 + 7 XIlNK4pnM3dnTdhKHFk65LsKDGxLc / Fn1samjt0Mih22IzRzAxehhnFk8TvRfgzU4c8IFMoB3ktF6ZaTIJSndXHlR0MtsszKPwt1wypYyRvpmgSYn5YlnU1kpti / dKsBtjvmZLslWHzXENoyo6VZReffTw0llsbd / GiQCDBC5QdNSgNjoZk0v91aJq1Eh + Nx1iEVY1kILz3ERiFFuar8XG6A24a9XH8NS5HyNFLkKURNRHiHWZAmZrdC6On7tmdGGh96vP / ACPHH8IBsrcRDJhssGsZrPWwbWPpUmsMpGZW6YFTJN5XM0WalNumcovbtYuGk2s6082XThfrKTXpSrT / 6 VN8XVq0HgO7Gmkg0O4 + DH9jJJexrnFs7htzR0kMwqixCBWRda7KbEbJS0TilCNlr1zOPcdxpBZGBnT6Sn00ON / t + 2 jWMzO4eDkS + QiFO8LWJjBFT8uS8DlG481LCYTewqmFTvZJmIpJIIZLbZyvlJxsMNsoYSo1EyBCUXTlDKxSoqKZXO6jvtkw + mAYxkSMuVMy3z6NF + De92aOzNlQf3S4viB2eTx73XLyTxdfKlamuMhTB6eoZJQT06fRClfxK9f9RF0 + Tbwmi2LJkWNRbKrsKPnbZ2Hzpn4Kgb6T2PltDSDysUF6GPfgaK / ip9d + BvKCpw2EDbnj2H6G6S3t4men5lrKJX11UwB / ORLmallmsXwDNNwNJhepwsloD + 0 BT3 + DfCCJdv1p0zIHKFik0KviFk90eKdf0 // vSndCP7t4UThUIJsg1QjjuBppHeFOfdLQd2z559GuxjBPZ07IOpJdyWhXaX + ariowLngZl8zBXIatzosmOr291OUH + ATwwj58Mj5YXz70MO4kBtjq / 2 rkbloi3XR / vGyBJwspZpK5UoHC1iclXu2uyjMFRwYNElmlczb3ubdmEkvIEAX30eRKTuWvcbWBrHByAP2WDClSzraDLZHz463 + gd1f43BYwIT3FjZkZ3TA4uZ1bnSIl45 / U00TByAMf8K / 4 lWtV5LqL6HSYkR + UE5hu7gGpTMAiFjGjFPa5EsLnFcWw1IOOgT8Hw5D4NpL / fj3moKQc / N + q54IV9ekGVgTblstPAVALazes9rfGLx5ic2D3ZGp4 / hyRcexFh2BG2 + XrT6u1CgC9oYaEV / cC2Z7IoDNVqsSL1wSb3x6cGHmboY7Ly1paBwIuplnC0DMFgts0a56mulBfz1mefxQi7JAzGvEseDGkWPVKAn54jn7fddw9cO9wZX0 / t9yJl5nnqxq6MQOKNqzn37Eo8u6KE29Yo30ZcFVZoVq4fSH02hC8CnsuWu27W9khmBR5yjGqVBUoHkRB7ODCCqBdCkdWF9fBfOFA6wJkduyY1NOLN + yYqBhlV + O380b1lV0NkhFRzuvloS6UbDIq / ysIj5Od / sp1SHXkpZ1fdU0yfHk3PAIl1KQM8b2BrZjcZoB1GBY5DJEjh + flm1CHAJQiba / x / IgyuG3kQCFllkyYANy3KCGNaOyAuA2D9aQIE / EmAr5MkEG1gX2kw + 8 jdwnqLeheI8xwi9VQkk5Uu + U0c2bEuiaGGZBrp0L5ZXc / DKSfchy2J8hFZJYg1mdKBGp85ZJexZoaCMN2IRTJxPnsD7V / 8 bbO7agvE0 + VpZdX + LXYviPKDE + 3 xJNBuS / rd5HixIDQzAYELtDnRWQQS + 4 Nqu5TPsOXbRGbLVlruAzYQpH55 + BUfmjkAyFUfjPc0Q5Ev82saFZpo6km55BtqqMUVerToP3VlttItSCV5OC6fo3XJ1lrdVog / bFL + Kt2ZgX1HTNFw0BoHCGCLCBRQqC9yiwJtwQg0NWz4kQdKTDave3j6YctqoSBchXy4gphHB4I86F5JrpF2rsoDjB9lykSOJaTx0 + Bs4nHoRiqw5DnGZdjIjvvwzBgc32Yqilt2X + bJR55y2m7 + 6 HtEFLoRlWkukPIJKCKsa + ilC1zmypQpBtAS6mK / nFKIsyTBUA8eP / l8YI / LDZOtTq6sU3S / huoZqWY / NQZbypsFH3uYabEPjESxd1FyhiN74KjSq7WjUWuni6vAyVWeJCAUsBD9Nh2UcDDpBEfOBPAiyHY0EX4urXkL8E5hi2QZK / Bq7FB4b1eJ270CpptHeMWR / sZCb50tcOiKrkNUz6PVTIEVCNuxKFfvQiGx4Qs / iH8ankePrRWvOVvQQL3cqVX86hQv79l35nfIvS8CO4RXgI02cWJjA1qZr8O6 + XydSvcBfXw4F83iIhOALEMpEPDE3oyJcSg7uMn1W86zpb / gcRTCWrQp1nvOiYaH2bTiR4LoDjx1ine8OT7yK96 +/ n9dj7Wy7hcxwmtdhcTfCIE / 6 FmY8iArlvZIkumnYcqRMcBml2vel8xuog3FZAib9sxwxSxSx5hDPXUSvlECimKYrITlNT + BWOdn2JasJ + PAqF5flt6IgvaHWWJFEY3nQ5pzLNcvLNM07DReO + 8 tYADieGsNschQf6f8QOtUGzOVnl388PMrXYZk8Hy46 / lxwKyy563E + j88LqT4EfFlpkiJJJQ / mkyg1OXD85xhJqDCDPt7eiKU9kofzehdHWJZNVoXNLqQTPcmi + gYNVmzV4GbeM71VYt4Ngqp0n / u6Vz / tCpmBoQdHH8ceeSd8kWGkc8MsmKue37aWR + ZOqscE2 + 7 vwLQ + RS9W6LfK2NS + DhfypzlWLdnS21 / AkqSkuBmkCySTf32mXEIzUX8NsQAYFM04YElwyH6 + ms + NUBhcKTBOEXZ1lZ9H5SiC / EYNVuU8 / zyBdbdja5Ec0yC6rBC3EIKDEnsm23YlJikMHxcwhxweO / szIvkpDjAplJOdz / fMh2OURRelEnknnpARxobmzTiTeQ13rPkATl64iFKlxIv + FE3JoQ7GZZloikqzXFAkJUach0IKAqTJ3nWzDMcJx8gs8ooLi1UjMtLe7 + LKQhXBcpqGMi194zYDqqwU2PX3qRo6Ix1VYr9qol0 / KQrVKKuqzXz1PvlVmybGiRYNh + N + 6 PSdRXt5tYfgfgHvSZE3QJvJzGBrw424vv1OdKjrcWz6NW7y3eLLMupgXJaANVFNy0TVsN5VDLFiQrYMZ40lJx1IwBbRg / 3 RAQL0A7yFUaPWRnjvAAladxZTk3SDxB / LrskUX2dVvvjKJyOKrDQTRQG / 5 qcUpxmGbjglrZ4QmeKKtY47ooSqv3fWMjmdcjSfwrvpiLWlD9V1v3wRWjUkt3nbh6XSElrp + 927 ai9eHX0O8WCELWV1UDBRvCwT / fFDH1f + 9 MX73 / I1xpcl4EAgNCXLss6YI8FyfKRecYMR1jafNNswKgiJjWgL9iGuteCWgdtxLjnCu8uxC5st5rEq3ofuSA + XSskoX7LkJU7UQ2e4s7M13IqwFkHYF6kFbEBt9QFvmGVfgnR5QTYTMOuU46VPHt3oAVWOFaHvzzy9FxlaTqB18dg / 4 MzxL2CqMIT1TVsIvavwDvL5YrGCyxjtxoRfV + fv2HforgDewnGZZIM0LctKngcprPuNopB2ma6AWaWrwp / P59PY2rgL9679MMaS57CYT / GotzdCxAORD4ocIs3s4ILJVZbiy5t9fmjNlzKJYurAzo6dhF2vc0ykx + dWAQhUm7Gw + zLRet7aIsezwrXCQjWy915womKbs1veC + z7M8TL79ewv5TFI3ND2N51I4qVMipmhft0glf / lwTMtgT48on7GzwYXZAlSsXFVQHLirDH9ltUhnt5ebCMeb + ipkl / USkaaA41oyvah0Ipj4iPEKTYKueCpAdxY4MKozKPw7OH6GiCJ4luSpbmCZfegj1tN6CLtJNpzVJxseeuj911yer5dClXmkyOYysF2EpmhFdSem6WV0fZNUDFJ / vRH + 5 zGSo3WXbKw5xo2eWHqyYctedd5 + Iea3EQxmzUEGzqx1VNu3Bx6RyPvtl5NVX5f2WiWX / pBwdv2p7XjX9vSuX / 9 tdn3 / e // 83 Q +/ 8 g5rd / x6 / 5 rrXN4OYvvHzvhgeP3vOWtEe8rCi6s6VvcXJ2cjaTy / QZJR1LwhLuXv2reHbph9jafDXlnlMctpwmjvbxn34JrxKGIShB7t + YNpXtIn545oeIZU8hY + dJ7D7M56c2LxaG ++ n0p73PiQYj5umJI / jZ7CimkgaUtiDXUObnw0oELcEo5o0E96e95O81csKsvEdwF / 06E KNHNbo9tZwHVZPOA0IWaLF2w0zgpu0K2sa1zbchkU5gIT + HYEhx0j / 5 jYDM68cXT + 4 dOG6c + 8 RUYu5 / W9vUH6kQsjaTP0eZgIgcxREd4gCCdvQaUxT2R0T8F7wF47I0uD3WkVckdY61BzQqFvnTFOYWF8gUfxAD4QECGKZoBklIxTR8O6MjzcthHFSoQn6bbYgR8wfx8 / I4XqX3SoaMvJFrPz738tVs1y7vc3xSwDDp0SHypRMBCsjcWirmI1nX9y7ilJuJYy4bBgZi65AsLBGvqy4DVxxtFUWhSht63QAEYZnQeTRv8TSJlX + xGCKstGFTbDuOTb3Cg0bTaVlLiLn4Ly7 +/ pOhvY0L1sSfBYSmB5r90UhTZSPidAuKFGwW / PCZYaiZJFpnkq0XRk / cniol34u3YFyWgDsVf17zaaN019CLzg8 / M / oy3tPQQb6yiAwFUOUCCdIvI9QcYkutyT9aXEsqZOBYKqoS4C8oPviCGvQy74MRH0 + P3PniyCPVyo6QGK5Q3mqpdB7GPQNV94uyWSK8eQLv6bmXC7qdiIQ0Rb + M0 / Uap9ieM4YLny6r8HBycdb6HTz9alKbEZGilMMb5HNLuL5xHfzkbudLM9jRvQsbm65CSA3aiiz / sz74i / vv0LL5id / J6vP3qKWo // bGj6E / tJ20tZEmtEYgiYIGvw8JmixDxjmYcrZrMTWy7 / mJr + 7E Co / LEvB7byjmGyKNxwi2y7B11CqZxoSVxo9 + 8 iAOj30PPjJnuZwJq2wgEJSJwWFVFxbHfvn2CGQ22f5ERZocskLvJ9DfzEOaz0 // yk9G9 +/ 1 PicUjZdIq8zlvK5BEvLTxGhUGwldGiYTOoIHb / oIhMoc8lahinPzH7ksomajBm3Y5BY0xKVWvhBcJhexrfE6pAlqLVF6F03quEddQJs4gd +++ pMUL6zGVGKSRf5mQPWV3uya7LP3ifPx3N0Vcel3hVxYnSMq8vzIEWylQBOLh8HairMKUkIBUSSTra2KIhwKUwRvNL948Vt /+ vSFb / eyc6xUl4TLC7KEfdaq1u4LPk1K89ortmohJONvzs / hdCKPcEQhTaDUJ68TSMFyUY0CsArlkiwtEZEtEVrkIy0z6ceWTDREibojnqJUKEVHFk7 + hwdf + Mx29jmqJfMtNRhcyKJoizX9JgF3RztJm0Jc4EfG9yN74XuYHP0pPTZrDJUXTXtSXkbwsbsG5earQ5s5jdhLAmSNwtN6GgJd / DS5lVcPDuK1l36Cbz77f + O7xx4ma7HI0iRLfRPEjY3gL843Fc3sr8qG0mJVFErtAjiROoz9I /+ I00vD3M3rvPjf5pgBWwyg030fxSbT87NXjyV + cfc7R / q3fuHlT69Im6bLLnzvaF97MRaKTjPzVskZBCbQzw / 4 SKgmfBpr7SuhkDdgl8vY2L4JIbmbfmCWm2bNbuBUfJwmRb5AP1i0SMhkqgmYzBbSq185 /+ QX / uDxD7wjFozlKLCxGLq0rXsrN6UM0OhvHECeLcqmc82T8P786Kt4ZmHWhSHZqIZT7hCqgZMTd4sos51bjBxu6bob13behInUKFkimaNz5aAfX01l8c3EEI6nTzslRywFo3ua + uYCzliJfsr9r9OLvNslxwVkYqlm + 31 Yiiq8TJhBuIWSw2alycKx51S6FrpuRVOl + Y8HhcjtXZO7LivP9sZlCzg02j29rmfts6ago0yCFEi7fGEVubRJwQSBHA0 + 0 k7S2HwFF9NnsLFlBzY33g6RfOe2tp0olYLw + YmY1xQsLNIEobS / Ma7R8SKSmfTNJ0ZPPPzcyecfkE2lnC5mkCql8L6rf53y5m60B7uRKae5uVOCKiYb2HIWv9tn0vl + QvVfwWlPCCda9gAOFtEfnTuMW9vWYWtLBGdmT / E2wwy8UVjH2a4wLII3FQra1jb2c19NCJyhioE3FYCuV24ulko9hbzlnN8MkhFRuNYyQeZLNl ++ ky1YPC1LZQyQasDKBSlVvFoKon1tQA5P33fffSvSweeyBcy + yIaujc8HAj6jVKHZmClDDRLgQd8 + NUf5MJldgTXbzpr0Ywt48eJTiFNk + qtrfxMbmjagOdiGxWwBDSRYH5nf + cUyIU86WlpV3vSskC + sOjp68BOlrBFULA2nZwYp2hbxgdXvIdNdIQ2sQHDXovgUZ79Crw1wbRWEI3AGYdrLYGcPFCkYRQy99iWcO / 4 Q68nFD3KreTlmzjQ + 6 mtAM6FpLPgC + 2 Z + 35 ti0cVycaNhWJKui2Bb3cblTr5tbZldG93RXjZ52GM22YpMKUgMFxKj2Brbgk69VxwcO9WJFRorsrqwqaH / YFtj6wVW41xYqvDoOBgIQ8 + SOTN0vpIwVyRTxdYiUUT63ePfgZzNYHe8jFVKCamCQCS8jqaYSZFwL / x6D9KFPDra / IgEGEBSUYl + lC1D5MtSXjqzH82Jw6hMPUdmXawiWE4xnFBtV1htyGLV + GPwVRW1kkgme5ny0q8Pnsc3Tp5iWzJxgVqmA3swJqxBimNb + zuc1Rj0GyVBNMPWG2lNtnFXvlzq0 + mV / tB6skpRyGR67YpaXYBn8r2bTLJcvK6YMgebFx0uUcaRzD + P2cH9yvn5Y +/ ACo0VEfB9Ox5Idzf1PqQEZCOT01Eiv9XR0IrVLRswM5pANEK + y6cimdJBd + Enc / r1I3 + Prz / 5 V5hauICA7KMfZxMVR5PAN49NrRtwa9dvIJcidiooYMtAH2l4ADqBKXq2gtlSGn839CoeHSdMW2FrhWyOQ1dX4PPhthS + 5 FfW9kyCWzrrdIUXkGmJIhsLccLEEbBzY / sohewY9vS8kyxNgiNczETbfv8bBPyZp877C + V8O3vP8NwwtvvejR2hjVBIiKWSY6KLrGN9eBVNWgktvh4YJYEvxpNJ4w8sjOGhc4cwkRzdfGjq0Ipg1CsiYDY0NfTTxlDjxb72AVTSpFV0cVa1rMLSUgF2sYwIQX4lSg / KBR0NGmlGKIYfkf8ZpZncqlm8D + USWcd0sYjTC08SL5zA7133R1gXvAXv6n0fOprjaGqmqDSo8H0XJsN + JEMB + CWVbn63rKbK / AOvWwwOd1WClwPbbnWmkyuzrj3OYvVqC2HLbedP51kqJJHPTlHckOMlwYTOGZKovQGqXNM44NdNPSLYEjKFHF4Y / jGGDn6fXNUkp0otvjzHoHMY2NJwAyJWF1m2LCy + WRcRM + RDpKYQoVyp5n5fWxwrMFZMwNubNp5RFOXpdL5ovGvLXSTEVrRSGkMOGOn5HPyUGqkUTabJFwtl8k0hiqL9AWQrjGIkHDtI2svy6DRpE5nzQ3NPYDr1Ah64 / ldxe / 8 WpGaKSKUqlDcLWNfWwzeNNAW2SHuABOyDZS2rf6vSSB575Arcc8wOn1t7aNeowhq75LZiosg9ayQxPfhdaIU0vcabdhhhFii8bmjIRwnRCzFBUiKFpJ3G94lcmWGd9ixnvRZbBjuWGkNzhlK55Az5aZsv1mPfSSczrpB / K5XzkenUaBtWYKyYgH / z3n2pmzZf / 43 ZzMLZV44exG39m7AmCjKtDUiSX85PphBtUCD5fJhbMiAVC2j0U6KvEf6csciEVYiooFw4oCCbFTG / pOKxocfx3Cv / HefPfI3AjgKlXWFMzZegp6NEKGzggc + q6GqKrDM80KoSEJYnKMuBFj1 + kGmRbbsL36rFHG4xgnOzvD7SrO2EYfOemMxnfu21szg4lySolZlwUT9y + uwbKipLphjSbVNx9sG0WdUHAs0ESYZUvlaLCZLt48SqRb577Ac4ljgOTaC00HSWxQbIX7PvWCjryoW5U01YgbFiAmZjx469x66 / ets / naBI9 + kDj2DsxENQNdJYVUNiQYe1ROBHTCUySEV6SUKTEEEDaa5GsF0yJ2BhiXw0kTSdjRL8NJMzOQ0Pj47iT08cgkmutrtJwKaBCLIYRa +/ H3vX7UWCzGeRomCxVoDlprsEHoga3 / zKdLV7uRK7pFL1L5aR / Q7Z4EwQm3cWINAjTumO6hTEU6hn + kOK / frfnytkw7ZpqiLXcieaZ5OHJ0QE7LDAjQufFTo0RiCQObZIa9lnsdrgJqWdofW88wGheSuy6ceKCvjONXeWb9103d + u6u0 + 8e TYRfyPA + dgMf8bU3jJzPxEGnoqjViTRpbbj7DcizwhXi0Btts2oVymjJlEBcVsiVISG90tCuWiGtIk3bklYGZRRyqtE7iRhZkbxC1hC + fnjvNVhU6ZkNviwXLua2S6r2reSuR8obp9ju0eV6vkpP8Nh / Bng88Bbk5tvrxFI / SNoWYa24vJ9c8EuJhEILxBgzOFjJ9t1RSUw2jzd / DWEhVL53XiIQ5kmHxZKovMne4EjpWw + cpKQvjEGE3KAAWblBuXzBWRzYoKmI0Pv3vf / KZ1Wz4VbGg8m5Nke3EyDztXgj9GWulrgr / YBoOE6AtI6GrsI59Mgp / MIlgpoCXCut8EyOTKmJgnQeeLaA4Y6CFTH / OzHUdVCtRkErKI16aG8JdPfhVzxQThyc5yh + VlrSw4ms3MI + iLYHPzduTyeSeq5qbS2aGy1sHdrpIQzrC5D95EWYAM1dnk0vZcOueYrXz5jeuSSkIlyNIoduy2zu18j6du4sSvjr0DE5kJXl4cFuOEw5OlUmMICTESusEnJE + hKO + Pa7303h2IBRqxEmPFBczG2sZdL28c2PgFSVXnGdyTmi1ALBIB76sQsN6IXb3vQn9gNWlpA1pbGwloIGHMlVGczyIqltEUloh39ZPp9WM + JRCiVaEou0QXp0zaYKAlSuZbVXFMDXBzD5cCNGsSc3wyCfTViwewu / dWshZNvCaMmW62l6FsK + 6 m0U465G0gzXL5iBil + KCNr9RIE40puBOGB10202zNiDQF3yDgkBKJ2PQZRb1In9eIq5tvxjWR3Tg4fJDn5uxzmtCLuK8P6xrWIpvLV9fasX2MUUni3vU7ETJaMJedvTKQrDcbn77v08VNa7Z85 / qrr / 8 LuqRm0WS7eRZhE3gxNH0Eh4aO4ta + jVgdTKNVKBOcqXH8mlw0FmgyFBPEHJeXsKYpjlWtlCuS5iZJqxNZm4RNFzBX5giTX5OqZtMrhne4XcFJfQgZm8vMEpCyhNv67uJ8sSYFcHX7NZyarDYvtVx82nY0NygGaVLsRlAJM2Sqil97C9KIazbWp / rfYKINq9LKivtYKlQhduvDPbdg4vw4Jgvj3NyXyAwTB4kPdN6F6dkZZPJZ7n9ZZGeSe8rNHsfCySdw + NwB9DRtKGIFxlvW0v8P9z7Itl / 9 i0995f7SgSMvfKpQyfXZi2UxSKZ5vHwGf / fEeWzviODs9BLssAJ / gx9 + wqCLRDqoZMZCVhC5GQtre7uwaJ0nx0aRKAUgZQJDMumi2yKJqxS / zxsamU5FBtdI08Gb / WIITw8 / gT + 45 bPIzJ + F6RfRVOqggChHpHuwKjwObPB + ITIWaUK8u6cHp2eHiei23UIAZ5WERamZpqqV1 / xLl2jY / nP7tafO / NVan4 + OKYgYPP4MKqcO4fn0EqL9AfpdDJokUqVyGs8 + cxrDUo6IGq0awbPFzKcpwPz5oSOItDZW1rduTmAFxluiwctHd8OOr21Zs / UzrfHO54sWA9mJOqQLmaDI5qm5NLIUYecJxUpN51GezRDDVAGFUjzF2Nm3nbhYGUkWXM3lUFzIQswXSMPMqjbxHJfp0jICH5ZdjZYlSmvmcrM4NXMEt7Tfhd09N6JUzLHNrZwSX1f7vePZRMkTKX3x3PdhzR + hc6ncZ7Ngq7 + hl08qVdb0z75zN6YIbfJ423DAaM3byQ2ySMdThnyYgqvv6 / OoEN8dotSPMWqM756j4Pup9BzCZLUYAcFoMYZ7M9ZJ8UuwCJoNB6KZsK91Disw3nIBM3O98533PLZz846PrV + 95e uiGkwmyUxVigzwMFgIAz + xTwJFy3kCPTKU52bnkzg / fhQvDz2G46MvQYv4WJcXlMlvzqdMZBnM7wVH3lpk26vWEKo5rrdGmXXMeW30J2gsncMaWafPeI0fZ5q13NehEO0qCfHY8eN4bHAIPpkAFcpbI2oUbcFm3q5JsBRxId1 + b0nCAPA5gQn51MIL78hUUgM + 1 ccj8lgnsVDhAAWTlAmoNnI5izd9Mwi2lOm3BMIyClmdrwhh7oK7FcNpKRUJNi + KopjECoxfyq4rD + x4gKE + 579 IF + WB9HeHvnZ46OBHxqYvvKdcKreIhaLqU0scn2YNQm1Z4amDQWzLuUQG1qLJa7dUv0JAhwQxokIXrKpgHb8p8Lps5j8Fp5kGzzltN / WRBBmz + RkcfvmbiOYUDE4sEbOkcT / Nz2MuAzpc0z + hkYZRcN4gOrVZjWozIW0BQtE2473r7xkwc6VishNnWNHD0xN9O4dTxz4jKkZrMSWTpq9CRUljZmIGXT0 + 5 JPEehlsC0aKIyby0EirG4iImE2W4GsVUaLYIhwKoZRz0rnWePtQZ2dnASswfqnb6jwgcEG / 9 KMDf37ipcHTP744NXx7Ort4Uz6f3VRMFVUlUyIoUnW6wRKoYPk07lZNyh + zaQrXFNL6sA9O4Gyj2rbD02RmuZkvFe1a + atbcFyhQO0p4qxTMwu4SGbXq + 2 q9u5YnhfbbLmMs4yUVYuIFOk205Xa3b8RG8vrCIDJD7V1bn3CwmH / ty / 8510 HJh / 9 k5ge2zlVmBYiFD + spdToidNPUSagIUg +// yFAqLxEJ3HxCJlC5H2CNoDrRiVSMChMtaIGzCRGsf4ZJKlgnbU1ziIFRr / Kvsm7b3xD7N0UZ / 4 x5 / se + HQxROdJID3LKWXbplLTF27lFpstjNFusAsbybzpjndYCUSiE58ryXztmkkSIunGF6J66WmuqaNnC3k2RNxsVGiLdvDEGYNpygAqFZYLjfpXmsCTjmyLrk0caK5k2hItOEbg4No6F5VXL + 4 / x0vzf7wvuHpY / dMzSTW7Qq + Ezsa9qCN8teDB48gQ5N12 / YWTJ9f4jFG31UBJMeTBMlSXBInjrwUQE / rADZ39 + HksWEsFOdQyZsIRWJZihuOYoXGv9rGWIJTqJxxb0MP2w9 / MXg003Vx7PzNZ8ePXzudmLx6KbPUVSyUo2alFBRYDNIcoKBZdaJa0 / Gbgl1jiDjXyxrASMtMtAdNsnjGtp1tY3lvaJcztpxVDPzbeL7YRBUE4RQymf3HzyzgxanvI9nsQ0suf + Nfv / Sfnp2fXwwJusrbEp9IvIrflO + ERXTmhew5bNgQw8XBRSwsVDCwtQVmKo + xkSziPXGIxH2XJ8 / jd3fejb9 / 4 QgOjL6IliYfh1SbIvHhqBo7hRUaV8zOZ / cJvERljG7f2r // iw8bN0Rbz144uHp6abI / lUmtn8 / P3VcU0j1eduQ05nYCJIHVaVo1YNnxp8AlDRY8U + wJzq6tU + ITBsustJcbu + diyp4MB1Ei / x / xSSBrEyZrzPcyZpMjNVXEVCqJxyYeQSQSgRYukXCLlOfa6N / UiDAFWSdeW4RCFGdHtw / jh2ZhpRP4eek7 + PnQFJnsAMo5ky11NYNa9Pg7tl43jxUaV + TWdnfe + e9YnDzObqxK4sTcLv / f7f / iqhNjB3t4WTWlIIrF4EmZsFsVXaFWTFZm3IDL3XLHrKVLTqRs83W9VWLBxa29 / Q5tb + aYzgGcaPCayTDigrTUT3ApKyEwycwuTZUp6q1ApVihgVKeliY / xglDTy5OEfxK2HXAj43b4xD0Ck6 / TOmSJGHLhlaAsL25WcIwumPYn5yHQC6IlRrlc / SbNDXd3bzuwMyZQgYrNN7yNOlyB4tSt7a9Oy / JAuNcuCntj / egwd9EUGaFfF47utR2vujNq8KwvAgby6NjOH7bex6vE77nh4HaY49StKrr051JQd + kgbSxsz2I1kaKttMVjJ9J4eL5POEVPvSTIDdujaAj24HRwzqKkojrb1iHLeJGDB1OoHVVI + INBKhQft / YGoBOwtVNgmhDnac ++ M4PPrNSBXds1MXmlGxYNuuJIfCdy / g + wgTmX0csRNiSiWm64Gqt4PpnL0Vy82D3LieaeFhOj2Ub1ZUPy / hgLBM2vAniGW9XyS3dwtJ0kRfRsdIt1msrFAugNaoSuUGgVCaPU2eSWBOO4F2bb8ZF / znc0XQbHnniKVgRC80xIlMGE5DpYImw6zyBP + wr7N7yroc3brxxEis46kbAdHENyy13nUnNYP / Rn + H65i245ar1 + E5pZlkVhlMRyctzqjgzLiEU4EbXHnlguc + zv7wTrikui6iX + 2 bnHGwdlhSQ0dIZIJ8cpLSsDJ3Am8xCklOaxYqAcBNF6 + 159 Iej2NP5Phw + Mozh / AX0DgQxczbBV3k0t1HAuETZASFn / R3rRm676VceFnizkpUbdSNgSZLLvJURz2spXVIs / GziFYxNHYNOvLFAKZDlUoA88rUsl7S3uWnmUbfh0IVc8Kxiw6xpN6 / ZovMG5SCdo + hlSnx4ZAQPuglU8fvYjVKttIC43omfnn4ebdFOdDT2Q + lZRFOLBoU + fHJoBhem96N1YQN + coow5gYiU85S2qRTXt3mw / rQWkwU55Ep60vb1l7 /+ e1rb17ACo + 6E XBZr + iMAuT1ymwHFEpztGAQ58j3NpMwVc7KOCkO70Tr9mHjaBV3nrVct7q3MFDNl026se4BXcE2jOWHalyxe0yNL7aRTuiYGS2iKRbG9g2d2H31bVgTb8R46ThFxzrmzuQo2CqjXBbxgn8JQ4mXURENFGZpohFh0RBXsSGyEU1aDE / PHClvGXjH97Z1btiPt2DUjYDThYTudLK13ZX7DhDhI0CEQR + sCznXTsBd + un6YtNt3cT + Ojx / dXUD2yaghSDDtDnJX + uPEsRYyjjrxV0Uq4ZROzk3q8Zga4Q7 + 3 xopAOvb7UxU16N7x9 + lLcm1sv0fTQiDJqiaCe82SyUMLmQJ7KBInHCpgN + Ey0WkfptV + FbLz1Kk6Tn8J5rbvvrvXt / bwn4BFZ6XLECZgD + CEZU0gN7EzbpH / 7 yzaZfC7OlIVXzaduez3XVi5thp480K5L3NK6aOjHe1dVklgeXzCK6tS1YUAtIKymsi6 / GU8OPw9 / E1hZXUIvMakEX99kFA0sEWqSIOPinM4 / iOLEfRpA0s7EBbQ0KoXAEjeZLSI9lUCjQJFPoNTLbNhEVVjKOvbfcjqdO / xxC0D + y79 /+ 0 R9uWbflAt6aDg5XtAZLWExvkvRk / 8 nyuHl13zX9yYUJjM3PYWThLFSWo7KjvPYL1UBKcJo5m65g3JDl0notpxiOEfP5ch5bYlshWzN0k5Ar5xCwWb3b6 / Bp1D6nRIIVdAUiQahHyZE3dAURDMj8w / JzGSwSNcgsiOIjYKSJtWwyiVDIwyAo8t2b + pDLzqEx1Gbvufb2xZZIeIMhCyznz + MtGFeygE2L0kvoBqN9Nvf4mld1Boh1UlM4Y9jVtUNe8lpjl + D6YrtKplsCLs1zl6VFE9kJ / ErrZqzufAcOD71KRoDVoDhwKNz3WdVqDuc + 258 iEpN48KaznUgJ4FhMsEZPROmTedZCfoquybwThVTMFmlCkBZTLtwXENBRPoNiwkpfu373j1taOr9dELInho / PJzr31Oo6V3JcsQJ2sepF9 / byh / 5 yd +/ 0 xaEtjOZjRXa24dY3mw7 + zP2tyyx42mq7eDX / j1VmUPpjGk4ebPNOaCLmCgs4N38Wd0SDOJA / 79 ROGbXZYFdRL7g5so0y4c1zxAqx5YpMizXSVFZUqKqEb5NGl4tlpJJst3GBt1CWFIF8u2Fkhfh5Mb715b72Nd + LdO9 + 8 p179rzl7RDrJw + mq5kXbb5g2ydWIYwa7uyEuzWBuFF1FZZ082TLXQDGmsoyQVuihFPTr6I / MYj5hTSRtkJ1pwAI1iVCdgrm6V9RpIDJRyyX6GxdyyqfizqyWabRXj8Q1k3LoAllQtXC081t7Y9t3XjNP63e865De666Lwf8JX4Zo24ErIiqxcpvvFyYC9Zdf2ItQ6 + 4 D7btKplvmV55j1g1t83 + BlRYaZBVgkppy2S5gAdPzxCdGEA0FHEnhpNIeQvU2LBdV6CKxC8RmlYgrxnxhZGs5CETjcloTZXytUq5RCkS7HhDy2J7c + 9 P / cHwP21fc / XLv3v / n6X + WPjqW2KK / 7 lRPwKWJMPLW / lwNapaj7WcQvReJ4kG5ADPgyusNwTBmqxmanPnVXh17KCzrpidj8xoMRbh5TV8DbGLdNlWNSKDt7s4 + 8 P7i1RsdDZ0Ik4sU2ZukC9Ctw2xRMnQXFtL3 / BA /+ qnb9r57h + 87 + YHRhx381Pgg / ilj7oRsChKptu2uQpWcG32AqBlHK7HKtl8b6YKblq7GwenDhI8mEVHrBcx0uB8pYSg2ziVmVSFFRXItb0Qq6bZAw7t2k2UDKIKTYq + Kd5u7CkrfpXiY3FU0QL7V3Wve2H1xo2D0nTr3Pt3M9Lgt / GvOIT68cEi603Dl / mIXqQMwVUwF2cWmI / 1 WCCDryFCppBFqVDEeza8G / vPfwu3r9uO5HSefKVO75OqGn / J / gxs2LVOeNXqDnfyNITb51f39b / W39Y81L1q65m1pjktqdb02i1bRnZ03r0itVQrNepGwDJUa3leCi8d8oIs06qZa5fcZ6 + xBWi / GH4Jn + j6HXxox2 + hR + 3 HQ8d + DLNiuqv4RdeXe + dEtVjAFmuRtO2afAZ1bN2468t /+ fvf / Jzzpn / ElTyueD7YG9WNz0zP73r0HqrIlrfO1ym + s6r5MFvR8Mzxx3FjKIoGYwELqUlUm3XYTtrkjFpVZS3xrUq42pNasMX / aRvDK2XUjw + WZMtdVrYM + IcLcniFdcsAD6t2Y + 2 XxhMXcfyFh3hR + lJm2uljadf8Ldz54wVoy5Gsatgr8I0 / bFb1WS + jjvJgwduRDryyw2ll567t8dgeN0Uyl9VkWdwIoyDL + Ie5aSQXKkgKBJYoQs1fc813fCzPc71JtFzCnOCw + ASQ3mTjkCt11I + J5rsgeUFtraGZ5W2PY9m1GixuynFJ / spNa0MQBt0USaj1kbZrYIiwrIyH / Q2qwSr06R3KYBACSf5 / Aa / 0 kBTye6ILVbk3tpiabQfA9g32Fn1X2wBfkr86OS1lQVCX7evgmXqv4M52AzQWfLEtCPrjfTCYTa8GdyyatlhLxbrYcYWNuhEwXVddpHCXt1RwI2fWlKw92oZN7VchqkZ5kxPL6 / ds11Y7WG7K4 / lt0d0Cr7boTKhtqcOKcCl77I53I + qPUYCmw20X7xwvSJYoiivSZvCXMepGwIZFebAoehA0 / 0 chQbA9H7Z1bUGAyHunatItuHPLddiq + oDiduHhgnfMu + gWDdQiZM8X21gTGUBvYy + KlRyvHBFcK8AMO8GldsXQ6yaKrh8TLfLAxq615XfACYM1NtVTyFUKfC9Ehi2zTSmZyFgzk554F3GvMd7A1FxWK + 1 UdtRW7bPB0uFSpYw10V6sb16HxcwS3w3Grn6g4 / 3 ZTmyok1E3AhYNy7Z0Z2PiKolPf3P5HJ4 / 8 hhBj2n + RHdDO7b1bCPivoCAFsB1 / duxmHW2bPcCL09zncZoHu7sCJhNgvncDHqkBQhGprovhPMWzkQJtinbqJNRNwKWlfhIyN96hNfSLIMT80THncyVYcJJdcYTk9jcsRYbu7egM9qBBmJ7EukkReFCrcuZq43VvYhRO58mKTi3cApnTz0Oo5TltVxemiQKcqUp3HMk4I + NoE5G3Qh4V / OmIxv7r / 3 vxaI5VyoXq9ExC5YUlQEPzvayTHMPDL6Iuze + F +/ axDbTWKJI2FjW2a5G / 6 H2VDWXZtvnLdHx3xyZw3iuwCNv5r9LRAGWSubc7qtv / Yv3XrPzIOpk1I2A2XolVfQfX9u1 + dHGSMtB2xKzXud3VIvcLUqDZJyaOo + 54 SdxfbCIsYmjfEdvwYU5vc2wPAjSXYIGwcuF2Oko0S1pqmu6TQq0lFx7vOfQpp6djwd8kWNr1txZF9vasVFHSBbw + Y9 + afTE3FN / eOTk6VWPPvPtPz4 / NX4XpU6GaZiq7WLFTFA + nx + vjBxCbvoUhucyfAcWPuxqoFQzzba7dNR7jk15t4BPlJSybtjq2u7Vz /+ b2z71f9x5ww0jn / vcl68otuh / NupKwG6dVv7Qoa + cOd698W9j0Z6DTaFoYnL2zPsnF0Z254umVCyVmcbhQiiEs / M5ZA2Bl85Y7mJxvv8zr5M2yKQrTk013YqUbhGJb9uijz1rru3d + sLG / q0 / IA65MR6LH73zhr2n6fPrJj3yBm8gIni7RtXp + OYTX9rxnSe +/ vlwJL6wa / Puw0fPHNkyPvvi / SQ3NZeTE5oUWzKRbopF7HhJN5AtyEsBf3xRENPxgN9ozKTNytqeXQ9tXb / z5JFzL2wrFlPN99 / 6 +// 1 fbd9qG587ZsNNl3fFgI + dOiQMpE91yko / sTeG / dmT4y92PDlb /+ f / y2VS7UNdG55dKBn7enXjr90zezSiQcYi9jWtOUru7becHBifnjThakT9 / jk2Nxv7P0P / 3 XXxl1Lr776k0hGMBpv33k3W + VXdxr7usEF7O1w8LYaT778ZEOmPKM2o29xz549BmtUduqVA5tE0xI23nDzqTtW31F57rnnpALGmjQzqt96694l1Of4l5ZECP8PAPgFhqae3ywAAAAASUVORK5CYII = '), ' enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', ' enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', ' enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', ' enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', 0, ' test', ' {"春江潮水连海平":"海上明月共潮生" }', ' m', ' m, -xl', 2, 127, 0, 0); -INSERT INTO test.TEST_DATASET VALUES (4, 0, 32767, 1, 65535, 8388607, 1, 2147483647, 3428724653, 1, 9223372036854775807, 10.5, 0, 10.5, 0.188, 1700000.01, ' 2021 - 01 - 01 ', ' 2021 - 01 - 01 ', ' 2013 - 09 - 06 T10:10:02 ', ' 2013 - 09 - 06 T10:10:02 ', ' 2022 - 08 - 09 T10:17:16.161342 Z', ' 00:00:00 ', ' 00:00:00 ', b' 1000001 ', ' 70 ', ' ! "#$%&\'()*+,-./:;<=>?\@[\]^_\`{|}~', 0xfffd, 'тест', 'Airbyte', '!" #$ %& \'()*+,-./:;<=>?\@[\]^_\`{|}~', -0 xfffd, -'тест', -'Airbyte', -'Airbyte', -127, -'Airbyte', -'Airbyte', -'Airbyte', -'Airbyte', -'Airbyte', -FROM_BASE64('iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAYAAAA5ZDbSAAAACXBIWXMAACE4AAAhOAFFljFgAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAEIPSURBVHgB7b0JnFxXeSf6v3vtVV29791q7bIkS8iy5U3IC2DHNnIAJ2MYQl4AZ4HJQB6TmcybQQz5ZfHkDXmQkEcCgQDBwWb1IrDBu4wX7Vu31GpJve/Vta93e985996qlu1k3vzUJiq/d+xS13LrVtX9zrf9/9/5jmDbtgTAQl2Mzwn83zc8vfzBPn777Gc/az/y8qd9iaAULvoSoQYEVdGW1FLFtCuo6AFR0EoFcWkhX1xoX6uK5YnSr5fE4v7PXPPI3Oc+B+ENH/1Z79z/a+Oz/8KjX8IQBBKwQMPG22Q8e/Hrvuni+e6Z/MjWRD6xOVcsblRDaJMEKeRXA2pZL6NoFso+ySc3CO1TF3MjL/cG+62oHJCazYYH77v+C0W8TQbJVqxbAbvfm9/1nvv2kf/cO5ub+r2hpeO3SIF8d3bJipiirQX8klAsmYhFJdJdoFQxIKoG+qUd9lx5utTh7zRHkxdHFb/wj/F4/JsP3vizabwNRl0L+OsX9/mkhH63rAVeKKbThaHcqVv8duDP5tPT61PSFIKKhsSChfYOGZm0iWIZdF9EuWwjlbIQiZsIlltwXWQt5spFfH/weciajcbG8NnmePw/xiK+px+88aUs6ngwAYuo0/GRvn1l0YRhl/MfP7z48mdGps9+KSI1rNfJw8ZCKpKLJjRVhKaJKOVtiORWRUGERDejIsCqkDbLSxg++QouXDyE5rYgZNOH5FJh3cTs9JfG5xY+/fs/v7YVdT7qVsBkne2AobxUKVU+nEjPf6ot3NbdqDXBktIwSFuNiohgQIRtAqYuQBIFLmSZ5rRgC6gUBWhBCSdVHRdME9GwhEhMhmgpqJTQNbew9AcLudQff/LcJzXU77DrVsD/49RvxZ9KPfFHo3Pj/bd0vyd0+8CdmEmPQdJ0FAqOIMn3ks8VINB9SWIazAQtck02dHqORB5t89F7NHosoKlJhk+TIQsyFFMNT4zNfzRx/Mm/+E8/v7URdTrqUsD7Satmpi7+2sTs5Icmkxel7koRPUYOaWMMgqTCIuExASuyCL3CfqTIBUui5pos0V/bEkCKS5OAjiWB6yWaFAppcViGYJL2B2Vogg9zi6n7p3ILv/bFc3fUpSbLqMPx2tjYuuml2Y9WimK8pCxg7MgzSPiDKHUWYCsKLNMm4Qpca5kQBf4fuGlmkbdIQrbovmGQgDUJqmLRRLDofQLCIYkHYYJoIxwRkMyUGtLZ1EeHRuQDdIoTqLNRdxr88MMfkJbKyX+/mExu7wy3CLYUwvdm0vju2DiskEzaS8IzBKgq99P0GJegFlzQgiNsg46TScs1P2k03SffyzVaIW1nViBA51MFhVKs4rZ8qfzpD9gfkFBno+4EPNPZuGEhO/1ekBk1pQLWxq+CNtCI8NY4FEWGadiUHgASaTBlgKSpcCXK3i04Nxv8GJM0XaL/+iK9dJzlmHOJRd5M4CIiShQ+OqdgyEgVU/dseq6wAXU26krAtr1PHE8Nvz+XL8RVUUPJKqKk69i16h0IR8kcWxKa1Q4IFvlV2RUqEzBJ2WaStmuoiM3vCCgZJTSHmtAR6kWhrPO4U1UF+IQgOoJ9kFUToqnSxKk0jGem3s8sCOpo1JWA/+TFc+unc6N7YSiUz5IQpABOz59El7oKm1p2kHBU9Ac3U0RsgWX4lOg7grRdbSaNtZiwXZttsRSK/O5w+hRu7L4FQTFKQIhF+bOAgdha0mgy1z5HyyWTgJP8wr0nmzLrUUejbgS8b98+cWppYpuulzuhUypDAZRBwtINHacWjmKTdguujl8Pnx1BhaBIFmBxSXKttbmwmW9m0bMjdGcCEAGBVDmBUjmHa9puQJne61f9GGhch/nkPFTZxyNvwST/blodk+mFbey7oE5G3XzR7l8vBHPl9LWkdTEWGbNImEfIZI5Hc8MYnziNO/x90IqTBG5QFOz6WNs1ylybBfD3sKcsemzQcRbxaJrow7GZw9gavwZhqREdsQ60BtuRyCTJUkg83bINiVIOMVYs5q7133YkiDoZdZMmnZsYaa6US9vMsihblN4ITMAWS38oy6WI+fjCY4icUTFMM8Ai6TJBsuNIhnRjYha4MJnkTQqoVMpxo4qfhJyFT1YxsjiM+cQc3tX+a7A1C+n5DArFHILwQaUMuJRh75FlA8bVk5lcC52pLnDqutHgXCbZXjb1XstyzC4LjG2XxVboQTHmw/esLA6WS8uDZRK0ibZQuxNvuT7ZMA2sb7qK3qdApwnBoA9m6l8ZewUdUhu2aHHMpYd5rsysgMzUgO6LFICZhtGXz6XbUSejbgRs2+Y6EkKzaYluLuv6UvoFpMykxZS79kYgNwYpRRId6dKtTMltR6iHTG4XSLdJmw00BVqxunE9JrMTXLgEZJGflXBudhCzg99A6eLjkDPDzEzwScRSLvYZLFc2TLPJFsy6CbTqRsBls7LVNHSfTZmMIpJKSY6PZZrMI2YBDgxJwZWkOpPAoNdFst8XE6PY0bKH+1pm1vf03Yn5zAwFVhUedLGZwHLonF3AM+dO4NDRQxim1yVJ4lrMcWz6DF1nGm35KqaxBXUy6kPAJEfdNPqYUrK8tyfWSxBjkAdKXLKuNnMTDF6nwn8Ze45FyfPZWQSFCK5qvh5doTVYE9mIwZlBsFya5cfMk8s0YRSfgsG4D8+1KFiKyPziML8tkAYrCglXdxLpimH0A29S1nMFjroQ8Bd/8km1WMr1MhDCpCuuyQG0+LsoWrb5ZWYC5RbZFbJ36W0X2SgSRHVubhC7YjtxT+/dWMokMM00lCyB5fpzhmApqgR/RIHcqkH1Oabb8fekxbITgTONLxvlno88+5G6IB/qQ4NDoUjBKLUw2SmChmRhAX2BDRQQy9w3Mg00bU/ADqEgeCgWDYmkc3HmWRhDj6Bp9hiOjnyPgiudR+B2VYAi97UsOmePWZ7tBHJOxCYrDkHB+OWyXm5pj+bDqINRF2mSikozYUlRJpKyUUHOSCKuNhEs2YnpwggJxVcNqrjGcWBDqGoz86Epo4zXBk+iOTyMEQq0JGaTBds9hgRMAhQMoYpuitIy00//kTvmxzKSgiLpSChXaabDFnCFj7oQ8FIl0RhVor5NTVuRD5tYKJ9HhXDoTS3bcHFkiI7wuWiVIwzBkQ3XalYQzIj+ok/GqxoFU5KBBEGQErFF/D2We7zo5lZM+1lULdUidcudKJ6ACSDxpXKZZtTBqAsBL+Tn4xO5cbFIZMA1TTfhzoE70YgZ9GpLeIHSJoNBjlYtL7axrIZQcLRSIh8rxxT6xaStCzoHQNiRpu0d5ppkOKZekpY9ZjZBqPl327LEpXKmAXUw6kLAAdUfYFUYS6UkHh16FBdmT2EHZbVILRBAYTooFWpWmmue4DJGEr0qOVEX11HRI/3dZ5gph1DVevYUO5fInbtHPzkns90PsemOYhNIXQejLoIsyxRjzExKFnGzRAnO2GN4sjSJR5ZyKBHMJLjpkWXVTK5DIjkskjMurQx2BOpMBCZiLtDqrOAYB2pxms35YnZjE8Qg9Ktimqu+cujjCq7wURcaXCBzKAquFgqsWkOBSTpdIdpQEfQqW2QvW4DD7jv+2PGp3l+XPXQKAfhxbu4MR6jV2eHhnQDHrttCHUgpCRSsRbRF2jHQMBCbyQ5f8fXk9aDBQkUwNEdKIv/GAg+AGU8LBl9hWeL7etlUzS7XVNHRbp5Y0R0H1nYnjlQ9hYedVKtAdIq6G/wxbGjehLAvirvXvx8lwyjue+dzJq7wseICvmhf9Nk1u3jZ42H7YdHUjbBnUr2aKsffuigF4Aq3pn38K7D6ZyIRdNtwyu74oRbPZdc3beC+lP3HymqdhFpAdY2Hd0dwrMBsbg6bWrfhroH7UdEtHJl9LbLvuXde8dUdKy7gzNx4+9DMgb2zs7MrwpkOPvKIVDFLmuBKlftVuKAGP6L2L/fBtlDVPpHUcnXDGvRFVpGiqyBRM7IAmWIWzYFObG/bRdBnCc7U8KJm582iW8fF4zRCvOZz82jLDOKGiB8/Hf4R+3zf6YX5K94CrvgX1FuDk5VysUUXFt9DmqwNzTzbh8sY8VCbQEGN5GivUI2VLGuZOYaHYqEW+dLxBmnuTHYGcV8jbu29Czd23IMmfw8v1TkzPYRb+/YiojVz+FN4U5MuVIMxdufw0PN44vi3sFCcpbRMltpClRWzVG/VWPEga4ewQ3/21LeeVqF8NFkeb64oha0/vLDv2YpVqJALtSq6oKtiMKWa2tixdcXZfcK+f3Ft8pI/KxAEfUm0aguUpkgqYmoIGXuharMFr0RHsFxEi3Bos4ij0wcxlj6DXe034v6BTxAmPYXB6aPoJvp+V+MAThunavCml/l6YbQ7p1RNxpOk7VpmETalXoZtKll/L706git5rHwUTdfm7x/6Qk+j1LznzvZd1xRDF4TX8qd+m/kt5uaIiaHgyG/4NP98KBv74dMXvvZoj9n+/Jo1d5bf7HQRLU9MEs0JTvoyzJnyXpJ4WI0gGG7C4tIkCSPgfHS12Aq1AmgeDkhIG2k8v/Q9nFh8Adc27sVdLZthj/8Y15dnMEHRVp4Fa2xiCF7k7dw80ISHckEJop+AEp2lSoayOJy94k30SgtY+OA3tl87m57+qwVpdoM2fR5NQRVGj48D+xXD5pFwNluRm+PrOnQ787GF0Gg4mt/67D93wsxiUTBtQ2SXuSXYDMUoUgS7QLRfFLIVgkcecUiRf4NloIbgEg/0bpmwx4ZwjFKuLL554u/xC6IP90Z0zJEACx0qLllnadeAjyoAIgq10mqR5eamhM4rfxnxigr4o9+5dvP56bE/t0VjQ0tzBBm/QsSAjLCkcD5VrlgMtkdFLWGV0AJVGVAPzO9/r92p/4je/sM3Oye7hJZg8fA2S8K5rucmjFpH4FPCEMqaK1yhFk3Yy6BKHmQT+S+6kTIdFgz64fNZGM5l8ZWszc1tv+ScR/QyLvcvnxySd39Znizwgvor3v+ysSIm5vGxLzf8+dO/tXNycfqPBVG/qa2hCbGoD6YgIxLT3HSGKAEf4cYkq4bGIE6ffhzHzvwY87Pp6NHFn3/+W2f+4zVvll7dtmqHqEk+mb2SLmfw3MhzuLX5HtxMOSmMPBfgcuzZ9vJX70zM5FYF5kCQql+FP6DBChH3G9Uga5JTICDWrghHubx0a1ng5f0WBn5XUtYVL+QVEfAaeQNRqdrnTal4y0DLgNAajfGVBSZf+0NAASH6rLJRJFOpE8rvJ+51oknBfMSEavqQSWdXn0sd/rUfn30w9Ppzx+3OoCr5Gi2KdFmpDsOjXzz9AwgXfoEyYdIQnfjLsm039629t/awJgfmV2Ui9hW26IwYJo1ubFVhNUpnuDbDmimt6gp3UWJlOni1wIrvZLRH2vgicmsFc/23cqyIgGPBrmhMiV+3rm1tcFvbtcjbCU7GM7JcIBPIAizdsHiNlE73TRJyIKJBIsiRr8DPUXBaTL77TPrkqtef26eEpJgck1kNM3sfu/AT1jweunAaJ1IZXlEpkm31SwGaPAZ/TxWd4jehWoXJgQxWX8VuLsHPiH5Pwz1wg93ViXdeHVuPgBTk582Xc9i9+ha0R3sIONEdjqIOxmUL+OFT+9S/eeazv7060Bv5t2s+hemlObqA7AI59S5suUhFN2GQgCvkg8t04xE1aTOLqH1+CeW8gEwhvcGolO72znt89sngoUOHlFCwRWj2tQpMg5kHZ2AGNAWzTUGUaZLwGilTR2ewGz0RuvhW2Y2mXR63KgbBBTOc6JgJWZBc4VYPcScGTZiSVUKpZGB7+7XIlNK4pnM3dnTdhKHFk65LsKDGxLc/Fn1samjt0Mih22IzRzAxehhnFk8TvRfgzU4c8IFMoB3ktF6ZaTIJSndXHlR0MtsszKPwt1wypYyRvpmgSYn5YlnU1kpti/dKsBtjvmZLslWHzXENoyo6VZReffTw0llsbd/GiQCDBC5QdNSgNjoZk0v91aJq1Eh+Nx1iEVY1kILz3ERiFFuar8XG6A24a9XH8NS5HyNFLkKURNRHiHWZAmZrdC6On7tmdGGh96vP/ACPHH8IBsrcRDJhssGsZrPWwbWPpUmsMpGZW6YFTJN5XM0WalNumcovbtYuGk2s6082XThfrKTXpSrT/6VN8XVq0HgO7Gmkg0O4+DH9jJJexrnFs7htzR0kMwqixCBWRda7KbEbJS0TilCNlr1zOPcdxpBZGBnT6Sn00ON/t+2jWMzO4eDkS+QiFO8LWJjBFT8uS8DlG481LCYTewqmFTvZJmIpJIIZLbZyvlJxsMNsoYSo1EyBCUXTlDKxSoqKZXO6jvtkw+mAYxkSMuVMy3z6NF+De92aOzNlQf3S4viB2eTx73XLyTxdfKlamuMhTB6eoZJQT06fRClfxK9f9RF0+Tbwmi2LJkWNRbKrsKPnbZ2Hzpn4Kgb6T2PltDSDysUF6GPfgaK/ip9d+BvKCpw2EDbnj2H6G6S3t4men5lrKJX11UwB/ORLmallmsXwDNNwNJhepwsloD+0BT3+DfCCJdv1p0zIHKFik0KviFk90eKdf0//vSndCP7t4UThUIJsg1QjjuBppHeFOfdLQd2z559GuxjBPZ07IOpJdyWhXaX+ariowLngZl8zBXIatzosmOr291OUH+ATwwj58Mj5YXz70MO4kBtjq/2rkbloi3XR/vGyBJwspZpK5UoHC1iclXu2uyjMFRwYNElmlczb3ubdmEkvIEAX30eRKTuWvcbWBrHByAP2WDClSzraDLZHz463+gd1f43BYwIT3FjZkZ3TA4uZ1bnSIl45/U00TByAMf8K/4lWtV5LqL6HSYkR+UE5hu7gGpTMAiFjGjFPa5EsLnFcWw1IOOgT8Hw5D4NpL/fj3moKQc/N+q54IV9ekGVgTblstPAVALazes9rfGLx5ic2D3ZGp4/hyRcexFh2BG2+XrT6u1CgC9oYaEV/cC2Z7IoDNVqsSL1wSb3x6cGHmboY7Ly1paBwIuplnC0DMFgts0a56mulBfz1mefxQi7JAzGvEseDGkWPVKAn54jn7fddw9cO9wZX0/t9yJl5nnqxq6MQOKNqzn37Eo8u6KE29Yo30ZcFVZoVq4fSH02hC8CnsuWu27W9khmBR5yjGqVBUoHkRB7ODCCqBdCkdWF9fBfOFA6wJkduyY1NOLN+yYqBhlV+O380b1lV0NkhFRzuvloS6UbDIq/ysIj5Od/sp1SHXkpZ1fdU0yfHk3PAIl1KQM8b2BrZjcZoB1GBY5DJEjh+flm1CHAJQiba/x/IgyuG3kQCFllkyYANy3KCGNaOyAuA2D9aQIE/EmAr5MkEG1gX2kw+8jdwnqLeheI8xwi9VQkk5Uu+U0c2bEuiaGGZBrp0L5ZXc/DKSfchy2J8hFZJYg1mdKBGp85ZJexZoaCMN2IRTJxPnsD7V/8bbO7agvE0+VpZdX+LXYviPKDE+3xJNBuS/rd5HixIDQzAYELtDnRWQQS+4Nqu5TPsOXbRGbLVlruAzYQpH55+BUfmjkAyFUfjPc0Q5Ev82saFZpo6km55BtqqMUVerToP3VlttItSCV5OC6fo3XJ1lrdVog/bFL+Kt2ZgX1HTNFw0BoHCGCLCBRQqC9yiwJtwQg0NWz4kQdKTDave3j6YctqoSBchXy4gphHB4I86F5JrpF2rsoDjB9lykSOJaTx0+Bs4nHoRiqw5DnGZdjIjvvwzBgc32Yqilt2X+bJR55y2m7+6HtEFLoRlWkukPIJKCKsa+ilC1zmypQpBtAS6mK/nFKIsyTBUA8eP/l8YI/LDZOtTq6sU3S/huoZqWY/NQZbypsFH3uYabEPjESxd1FyhiN74KjSq7WjUWuni6vAyVWeJCAUsBD9Nh2UcDDpBEfOBPAiyHY0EX4urXkL8E5hi2QZK/Bq7FB4b1eJ270CpptHeMWR/sZCb50tcOiKrkNUz6PVTIEVCNuxKFfvQiGx4Qs/iH8ankePrRWvOVvQQL3cqVX86hQv79l35nfIvS8CO4RXgI02cWJjA1qZr8O6+XydSvcBfXw4F83iIhOALEMpEPDE3oyJcSg7uMn1W86zpb/gcRTCWrQp1nvOiYaH2bTiR4LoDjx1ine8OT7yK96+/n9dj7Wy7hcxwmtdhcTfCIE/6FmY8iArlvZIkumnYcqRMcBml2vel8xuog3FZAib9sxwxSxSx5hDPXUSvlECimKYrITlNT+BWOdn2JasJ+PAqF5flt6IgvaHWWJFEY3nQ5pzLNcvLNM07DReO+8tYADieGsNschQf6f8QOtUGzOVnl388PMrXYZk8Hy46/lxwKyy563E+j88LqT4EfFlpkiJJJQ/mkyg1OXD85xhJqDCDPt7eiKU9kofzehdHWJZNVoXNLqQTPcmi+gYNVmzV4GbeM71VYt4Ngqp0n/u6Vz/tCpmBoQdHH8ceeSd8kWGkc8MsmKue37aWR+ZOqscE2+7vwLQ+RS9W6LfK2NS+DhfypzlWLdnS21/AkqSkuBmkCySTf32mXEIzUX8NsQAYFM04YElwyH6+ms+NUBhcKTBOEXZ1lZ9H5SiC/EYNVuU8/zyBdbdja5Ec0yC6rBC3EIKDEnsm23YlJikMHxcwhxweO/szIvkpDjAplJOdz/fMh2OURRelEnknnpARxobmzTiTeQ13rPkATl64iFKlxIv+FE3JoQ7GZZloikqzXFAkJUach0IKAqTJ3nWzDMcJx8gs8ooLi1UjMtLe7+LKQhXBcpqGMi194zYDqqwU2PX3qRo6Ix1VYr9qol0/KQrVKKuqzXz1PvlVmybGiRYNh+N+6PSdRXt5tYfgfgHvSZE3QJvJzGBrw424vv1OdKjrcWz6NW7y3eLLMupgXJaANVFNy0TVsN5VDLFiQrYMZ40lJx1IwBbRg/3RAQL0A7yFUaPWRnjvAAladxZTk3SDxB/LrskUX2dVvvjKJyOKrDQTRQG/5qcUpxmGbjglrZ4QmeKKtY47ooSqv3fWMjmdcjSfwrvpiLWlD9V1v3wRWjUkt3nbh6XSElrp+927ai9eHX0O8WCELWV1UDBRvCwT/fFDH1f+9MX73/I1xpcl4EAgNCXLss6YI8FyfKRecYMR1jafNNswKgiJjWgL9iGuteCWgdtxLjnCu8uxC5st5rEq3ofuSA+XSskoX7LkJU7UQ2e4s7M13IqwFkHYF6kFbEBt9QFvmGVfgnR5QTYTMOuU46VPHt3oAVWOFaHvzzy9FxlaTqB18dg/4MzxL2CqMIT1TVsIvavwDvL5YrGCyxjtxoRfV+fv2HforgDewnGZZIM0LctKngcprPuNopB2ma6AWaWrwp/P59PY2rgL9679MMaS57CYT/GotzdCxAORD4ocIs3s4ILJVZbiy5t9fmjNlzKJYurAzo6dhF2vc0ykx+dWAQhUm7Gw+zLRet7aIsezwrXCQjWy915womKbs1veC+z7M8TL79ewv5TFI3ND2N51I4qVMipmhft0glf/lwTMtgT48on7GzwYXZAlSsXFVQHLirDH9ltUhnt5ebCMeb+ipkl/USkaaA41oyvah0Ipj4iPEKTYKueCpAdxY4MKozKPw7OH6GiCJ4luSpbmCZfegj1tN6CLtJNpzVJxseeuj911yer5dClXmkyOYysF2EpmhFdSem6WV0fZNUDFJ/vRH+5zGSo3WXbKw5xo2eWHqyYctedd5+Iea3EQxmzUEGzqx1VNu3Bx6RyPvtl5NVX5f2WiWX/pBwdv2p7XjX9vSuX/9tdn3/e//83Q+/8g5rd/x6/5rrXN4OYvvHzvhgeP3vOWtEe8rCi6s6VvcXJ2cjaTy/QZJR1LwhLuXv2reHbph9jafDXlnlMctpwmjvbxn34JrxKGIShB7t+YNpXtIn545oeIZU8hY+dJ7D7M56c2LxaG++n0p73PiQYj5umJI/jZ7CimkgaUtiDXUObnw0oELcEo5o0E96e95O81csKsvEdwF/06EKNHNbo9tZwHVZPOA0IWaLF2w0zgpu0K2sa1zbchkU5gIT+HYEhx0j/5jYDM68cXT+4dOG6c+8RUYu5/W9vUH6kQsjaTP0eZgIgcxREd4gCCdvQaUxT2R0T8F7wF47I0uD3WkVckdY61BzQqFvnTFOYWF8gUfxAD4QECGKZoBklIxTR8O6MjzcthHFSoQn6bbYgR8wfx8/I4XqX3SoaMvJFrPz738tVs1y7vc3xSwDDp0SHypRMBCsjcWirmI1nX9y7ilJuJYy4bBgZi65AsLBGvqy4DVxxtFUWhSht63QAEYZnQeTRv8TSJlX+xGCKstGFTbDuOTb3Cg0bTaVlLiLn4Ly7+/pOhvY0L1sSfBYSmB5r90UhTZSPidAuKFGwW/PCZYaiZJFpnkq0XRk/cniol34u3YFyWgDsVf17zaaN019CLzg8/M/oy3tPQQb6yiAwFUOUCCdIvI9QcYkutyT9aXEsqZOBYKqoS4C8oPviCGvQy74MRH0+P3PniyCPVyo6QGK5Q3mqpdB7GPQNV94uyWSK8eQLv6bmXC7qdiIQ0Rb+M0/Uap9ieM4YLny6r8HBycdb6HTz9alKbEZGilMMb5HNLuL5xHfzkbudLM9jRvQsbm65CSA3aiiz/sz74i/vv0LL5id/J6vP3qKWo//bGj6E/tJ20tZEmtEYgiYIGvw8JmixDxjmYcrZrMTWy7/mJr+7ECo/LEvB7byjmGyKNxwi2y7B11CqZxoSVxo9+8iAOj30PPjJnuZwJq2wgEJSJwWFVFxbHfvn2CGQ22f5ERZocskLvJ9DfzEOaz0//yk9G9+/1PicUjZdIq8zlvK5BEvLTxGhUGwldGiYTOoIHb/oIhMoc8lahinPzH7ksomajBm3Y5BY0xKVWvhBcJhexrfE6pAlqLVF6F03quEddQJs4gd+++pMUL6zGVGKSRf5mQPWV3uya7LP3ifPx3N0Vcel3hVxYnSMq8vzIEWylQBOLh8HairMKUkIBUSSTra2KIhwKUwRvNL948Vt/+vSFb/eyc6xUl4TLC7KEfdaq1u4LPk1K89ortmohJONvzs/hdCKPcEQhTaDUJ68TSMFyUY0CsArlkiwtEZEtEVrkIy0z6ceWTDREibojnqJUKEVHFk7+hwdf+Mx29jmqJfMtNRhcyKJoizX9JgF3RztJm0Jc4EfG9yN74XuYHP0pPTZrDJUXTXtSXkbwsbsG5earQ5s5jdhLAmSNwtN6GgJd/DS5lVcPDuK1l36Cbz77f+O7xx4ma7HI0iRLfRPEjY3gL843Fc3sr8qG0mJVFErtAjiROoz9I/+I00vD3M3rvPjf5pgBWwyg030fxSbT87NXjyV+cfc7R/q3fuHlT69Im6bLLnzvaF97MRaKTjPzVskZBCbQzw/4SKgmfBpr7SuhkDdgl8vY2L4JIbmbfmCWm2bNbuBUfJwmRb5AP1i0SMhkqgmYzBbSq185/+QX/uDxD7wjFozlKLCxGLq0rXsrN6UM0OhvHECeLcqmc82T8P786Kt4ZmHWhSHZqIZT7hCqgZMTd4sos51bjBxu6bob13behInUKFkimaNz5aAfX01l8c3EEI6nTzslRywFo3ua+uYCzliJfsr9r9OLvNslxwVkYqlm+31Yiiq8TJhBuIWSw2alycKx51S6FrpuRVOl+Y8HhcjtXZO7LivP9sZlCzg02j29rmfts6ago0yCFEi7fGEVubRJwQSBHA0+0k7S2HwFF9NnsLFlBzY33g6RfOe2tp0olYLw+YmY1xQsLNIEobS/Ma7R8SKSmfTNJ0ZPPPzcyecfkE2lnC5mkCql8L6rf53y5m60B7uRKae5uVOCKiYb2HIWv9tn0vl+QvVfwWlPCCda9gAOFtEfnTuMW9vWYWtLBGdmT/E2wwy8UVjH2a4wLII3FQra1jb2c19NCJyhioE3FYCuV24ulko9hbzlnN8MkhFRuNYyQeZLNl++ky1YPC1LZQyQasDKBSlVvFoKon1tQA5P33fffSvSweeyBcy+yIaujc8HAj6jVKHZmClDDRLgQd8+NUf5MJldgTXbzpr0Ywt48eJTiFNk+qtrfxMbmjagOdiGxWwBDSRYH5nf+cUyIU86WlpV3vSskC+sOjp68BOlrBFULA2nZwYp2hbxgdXvIdNdIQ2sQHDXovgUZ79Crw1wbRWEI3AGYdrLYGcPFCkYRQy99iWcO/4Q68nFD3KreTlmzjQ+6mtAM6FpLPgC+2Z+35ti0cVycaNhWJKui2Bb3cblTr5tbZldG93RXjZ52GM22YpMKUgMFxKj2Brbgk69VxwcO9WJFRorsrqwqaH/YFtj6wVW41xYqvDoOBgIQ8+SOTN0vpIwVyRTxdYiUUT63ePfgZzNYHe8jFVKCamCQCS8jqaYSZFwL/x6D9KFPDra/IgEGEBSUYl+lC1D5MtSXjqzH82Jw6hMPUdmXawiWE4xnFBtV1htyGLV+GPwVRW1kkgme5ny0q8Pnsc3Tp5iWzJxgVqmA3swJqxBimNb+zuc1Rj0GyVBNMPWG2lNtnFXvlzq0+mV/tB6skpRyGR67YpaXYBn8r2bTLJcvK6YMgebFx0uUcaRzD+P2cH9yvn5Y+/ACo0VEfB9Ox5Idzf1PqQEZCOT01Eiv9XR0IrVLRswM5pANEK+y6cimdJBd+Enc/r1I3+Prz/5V5hauICA7KMfZxMVR5PAN49NrRtwa9dvIJcidiooYMtAH2l4ADqBKXq2gtlSGn839CoeHSdMW2FrhWyOQ1dX4PPhthS+5FfW9kyCWzrrdIUXkGmJIhsLccLEEbBzY/sohewY9vS8kyxNgiNczETbfv8bBPyZp877C+V8O3vP8NwwtvvejR2hjVBIiKWSY6KLrGN9eBVNWgktvh4YJYEvxpNJ4w8sjOGhc4cwkRzdfGjq0Ipg1CsiYDY0NfTTxlDjxb72AVTSpFV0cVa1rMLSUgF2sYwIQX4lSg/KBR0NGmlGKIYfkf8ZpZncqlm8D+USWcd0sYjTC08SL5zA7133R1gXvAXv6n0fOprjaGqmqDSo8H0XJsN+JEMB+CWVbn63rKbK/AOvWwwOd1WClwPbbnWmkyuzrj3OYvVqC2HLbedP51kqJJHPTlHckOMlwYTOGZKovQGqXNM44NdNPSLYEjKFHF4Y/jGGDn6fXNUkp0otvjzHoHMY2NJwAyJWF1m2LCy+WRcRM+RDpKYQoVyp5n5fWxwrMFZMwNubNp5RFOXpdL5ovGvLXSTEVrRSGkMOGOn5HPyUGqkUTabJFwtl8k0hiqL9AWQrjGIkHDtI2svy6DRpE5nzQ3NPYDr1Ah64/ldxe/8WpGaKSKUqlDcLWNfWwzeNNAW2SHuABOyDZS2rf6vSSB575Arcc8wOn1t7aNeowhq75LZiosg9ayQxPfhdaIU0vcabdhhhFii8bmjIRwnRCzFBUiKFpJ3G94lcmWGd9ixnvRZbBjuWGkNzhlK55Az5aZsv1mPfSSczrpB/K5XzkenUaBtWYKyYgH/z3n2pmzZf/43ZzMLZV44exG39m7AmCjKtDUiSX85PphBtUCD5fJhbMiAVC2j0U6KvEf6csciEVYiooFw4oCCbFTG/pOKxocfx3Cv/HefPfI3AjgKlXWFMzZegp6NEKGzggc+q6GqKrDM80KoSEJYnKMuBFj1+kGmRbbsL36rFHG4xgnOzvD7SrO2EYfOemMxnfu21szg4lySolZlwUT9y+uwbKipLphjSbVNx9sG0WdUHAs0ESYZUvlaLCZLt48SqRb577Ac4ljgOTaC00HSWxQbIX7PvWCjryoW5U01YgbFiAmZjx469x66/ets/naBI9+kDj2DsxENQNdJYVUNiQYe1ROBHTCUySEV6SUKTEEEDaa5GsF0yJ2BhiXw0kTSdjRL8NJMzOQ0Pj47iT08cgkmutrtJwKaBCLIYRa+/H3vX7UWCzGeRomCxVoDlprsEHoga3/zKdLV7uRK7pFL1L5aR/Q7Z4EwQm3cWINAjTumO6hTEU6hn+kOK/frfnytkw7ZpqiLXcieaZ5OHJ0QE7LDAjQufFTo0RiCQObZIa9lnsdrgJqWdofW88wGheSuy6ceKCvjONXeWb9103d+u6u0+8eTYRfyPA+dgMf8bU3jJzPxEGnoqjViTRpbbj7DcizwhXi0Btts2oVymjJlEBcVsiVISG90tCuWiGtIk3bklYGZRRyqtE7iRhZkbxC1hC+fnjvNVhU6ZkNviwXLua2S6r2reSuR8obp9ju0eV6vkpP8Nh/Bng88Bbk5tvrxFI/SNoWYa24vJ9c8EuJhEILxBgzOFjJ9t1RSUw2jzd/DWEhVL53XiIQ5kmHxZKovMne4EjpWw+cpKQvjEGE3KAAWblBuXzBWRzYoKmI0Pv3vf/KZ1Wz4VbGg8m5Nke3EyDztXgj9GWulrgr/YBoOE6AtI6GrsI59Mgp/MIlgpoCXCut8EyOTKmJgnQeeLaA4Y6CFTH/OzHUdVCtRkErKI16aG8JdPfhVzxQThyc5yh+VlrSw4ms3MI+iLYHPzduTyeSeq5qbS2aGy1sHdrpIQzrC5D95EWYAM1dnk0vZcOueYrXz5jeuSSkIlyNIoduy2zu18j6du4sSvjr0DE5kJXl4cFuOEw5OlUmMICTESusEnJE+hKO+Pa7303h2IBRqxEmPFBczG2sZdL28c2PgFSVXnGdyTmi1ALBIB76sQsN6IXb3vQn9gNWlpA1pbGwloIGHMlVGczyIqltEUloh39ZPp9WM+JRCiVaEou0QXp0zaYKAlSuZbVXFMDXBzD5cCNGsSc3wyCfTViwewu/dWshZNvCaMmW62l6FsK+6m0U465G0gzXL5iBil+KCNr9RIE40puBOGB10202zNiDQF3yDgkBKJ2PQZRb1In9eIq5tvxjWR3Tg4fJDn5uxzmtCLuK8P6xrWIpvLV9fasX2MUUni3vU7ETJaMJedvTKQrDcbn77v08VNa7Z85/qrr/8LuqRm0WS7eRZhE3gxNH0Eh4aO4ta+jVgdTKNVKBOcqXH8mlw0FmgyFBPEHJeXsKYpjlWtlCuS5iZJqxNZm4RNFzBX5giTX5OqZtMrhne4XcFJfQgZm8vMEpCyhNv67uJ8sSYFcHX7NZyarDYvtVx82nY0NygGaVLsRlAJM2Sqil97C9KIazbWp/rfYKINq9LKivtYKlQhduvDPbdg4vw4Jgvj3NyXyAwTB4kPdN6F6dkZZPJZ7n9ZZGeSe8rNHsfCySdw+NwB9DRtKGIFxlvW0v8P9z7Itl/9i0995f7SgSMvfKpQyfXZi2UxSKZ5vHwGf/fEeWzviODs9BLssAJ/gx9+wqCLRDqoZMZCVhC5GQtre7uwaJ0nx0aRKAUgZQJDMumi2yKJqxS/zxsamU5FBtdI08Gb/WIITw8/gT+45bPIzJ+F6RfRVOqggChHpHuwKjwObPB+ITIWaUK8u6cHp2eHiei23UIAZ5WERamZpqqV1/xLl2jY/nP7tafO/NVan4+OKYgYPP4MKqcO4fn0EqL9AfpdDJokUqVyGs8+cxrDUo6IGq0awbPFzKcpwPz5oSOItDZW1rduTmAFxluiwctHd8OOr21Zs/UzrfHO54sWA9mJOqQLmaDI5qm5NLIUYecJxUpN51GezRDDVAGFUjzF2Nm3nbhYGUkWXM3lUFzIQswXSMPMqjbxHJfp0jICH5ZdjZYlSmvmcrM4NXMEt7Tfhd09N6JUzLHNrZwSX1f7vePZRMkTKX3x3PdhzR+hc6ncZ7Ngq7+hl08qVdb0z75zN6YIbfJ423DAaM3byQ2ySMdThnyYgqvv6/OoEN8dotSPMWqM756j4Pup9BzCZLUYAcFoMYZ7M9ZJ8UuwCJoNB6KZsK91Disw3nIBM3O98533PLZz846PrV+95euiGkwmyUxVigzwMFgIAz+xTwJFy3kCPTKU52bnkzg/fhQvDz2G46MvQYv4WJcXlMlvzqdMZBnM7wVH3lpk26vWEKo5rrdGmXXMeW30J2gsncMaWafPeI0fZ5q13NehEO0qCfHY8eN4bHAIPpkAFcpbI2oUbcFm3q5JsBRxId1+b0nCAPA5gQn51MIL78hUUgM+1ccj8lgnsVDhAAWTlAmoNnI5izd9Mwi2lOm3BMIyClmdrwhh7oK7FcNpKRUJNi+KopjECoxfyq4rD+x4gKE+579if+WB9HeHvnZ46OBHxqYvvKdcKreIhaLqU0scn2YNQm1Z4amDQWzLuUQG1qLJa7dUv0JAhwQxokIXrKpgHb8p8Lps5j8Fp5kGzzltN/WRBBmz+RkcfvmbiOYUDE4sEbOkcT/Nz2MuAzpc0z+hkYZRcN4gOrVZjWozIW0BQtE2473r7xkwc6VishNnWNHD0xN9O4dTxz4jKkZrMSWTpq9CRUljZmIGXT0+5JPEehlsC0aKIyby0EirG4iImE2W4GsVUaLYIhwKoZRz0rnWePtQZ2dnASswfqnb6jwgcEG/9KMDf37ipcHTP744NXx7Ort4Uz6f3VRMFVUlUyIoUnW6wRKoYPk07lZNyh+zaQrXFNL6sA9O4Gyj2rbD02RmuZkvFe1a+atbcFyhQO0p4qxTMwu4SGbXq+2q9u5YnhfbbLmMs4yUVYuIFOk205Xa3b8RG8vrCIDJD7V1bn3CwmH/ty/8510HJh/9k5ge2zlVmBYiFD+spdToidNPUSagIUg+//yFAqLxEJ3HxCJlC5H2CNoDrRiVSMChMtaIGzCRGsf4ZJKlgnbU1ziIFRr/Kvsm7b3xD7N0UZ/4x5/se+HQxROdJID3LKWXbplLTF27lFpstjNFusAsbybzpjndYCUSiE58ryXztmkkSIunGF6J66WmuqaNnC3k2RNxsVGiLdvDEGYNpygAqFZYLjfpXmsCTjmyLrk0caK5k2hItOEbg4No6F5VXL+4/x0vzf7wvuHpY/dMzSTW7Qq+Ezsa9qCN8teDB48gQ5N12/YWTJ9f4jFG31UBJMeTBMlSXBInjrwUQE/rADZ39+HksWEsFOdQyZsIRWJZihuOYoXGv9rGWIJTqJxxb0MP2w9/MXg003Vx7PzNZ8ePXzudmLx6KbPUVSyUo2alFBRYDNIcoKBZdaJa0/Gbgl1jiDjXyxrASMtMtAdNsnjGtp1tY3lvaJcztpxVDPzbeL7YRBUE4RQymf3HzyzgxanvI9nsQ0suf+Nfv/Sfnp2fXwwJusrbEp9IvIrflO+ERXTmhew5bNgQw8XBRSwsVDCwtQVmKo+xkSziPXGIxH2XJ8/jd3fejb9/4QgOjL6IliYfh1SbIvHhqBo7hRUaV8zOZ/cJvERljG7f2r//iw8bN0Rbz144uHp6abI/lUmtn8/P3VcU0j1eduQ05nYCJIHVaVo1YNnxp8AlDRY8U+wJzq6tU+ITBsustJcbu+diyp4MB1Ei/x/xSSBrEyZrzPcyZpMjNVXEVCqJxyYeQSQSgRYukXCLlOfa6N/UiDAFWSdeW4RCFGdHtw/jh2ZhpRP4eek7+PnQFJnsAMo5ky11NYNa9Pg7tl43jxUaV+TWdnfe+e9YnDzObqxK4sTcLv/f7f/iqhNjB3t4WTWlIIrF4EmZsFsVXaFWTFZm3IDL3XLHrKVLTqRs83W9VWLBxa29/Q5tb+aYzgGcaPCayTDigrTUT3ApKyEwycwuTZUp6q1ApVihgVKeliY/xglDTy5OEfxK2HXAj43b4xD0Ck6/TOmSJGHLhlaAsL25WcIwumPYn5yHQC6IlRrlc/SbNDXd3bzuwMyZQgYrNN7yNOlyB4tSt7a9Oy/JAuNcuCntj/egwd9EUGaFfF47utR2vujNq8KwvAgby6NjOH7bex6vE77nh4HaY49StKrr051JQd+kgbSxsz2I1kaKttMVjJ9J4eL5POEVPvSTIDdujaAj24HRwzqKkojrb1iHLeJGDB1OoHVVI+INBKhQft/YGoBOwtVNgmhDnac++M4PPrNSBXds1MXmlGxYNuuJIfCdy/g+wgTmX0csRNiSiWm64Gqt4PpnL0Vy82D3LieaeFhOj2Ub1ZUPy/hgLBM2vAniGW9XyS3dwtJ0kRfRsdIt1msrFAugNaoSuUGgVCaPU2eSWBOO4F2bb8ZF/znc0XQbHnniKVgRC80xIlMGE5DpYImw6zyBP+wr7N7yroc3brxxEis46kbAdHENyy13nUnNYP/Rn+H65i245ar1+E5pZlkVhlMRyctzqjgzLiEU4EbXHnlguc+zv7wTrikui6iX+2bnHGwdlhSQ0dIZIJ8cpLSsDJ3Am8xCklOaxYqAcBNF6+159Iej2NP5Phw+Mozh/AX0DgQxczbBV3k0t1HAuETZASFn/R3rRm676VceFnizkpUbdSNgSZLLvJURz2spXVIs/GziFYxNHYNOvLFAKZDlUoA88rUsl7S3uWnmUbfh0IVc8Kxiw6xpN6/ZovMG5SCdo+hlSnx4ZAQPuglU8fvYjVKttIC43omfnn4ebdFOdDT2Q+lZRFOLBoU+fHJoBhem96N1YQN+coow5gYiU85S2qRTXt3mw/rQWkwU55Ep60vb1l7/+e1rb17ACo+6EXBZr+iMAuT1ymwHFEpztGAQ58j3NpMwVc7KOCkO70Tr9mHjaBV3nrVct7q3MFDNl026se4BXcE2jOWHalyxe0yNL7aRTuiYGS2iKRbG9g2d2H31bVgTb8R46ThFxzrmzuQo2CqjXBbxgn8JQ4mXURENFGZpohFh0RBXsSGyEU1aDE/PHClvGXjH97Z1btiPt2DUjYDThYTudLK13ZX7DhDhI0CEQR+sCznXTsBd+un6YtNt3cT+Ojx/dXUD2yaghSDDtDnJX+uPEsRYyjjrxV0Uq4ZROzk3q8Zga4Q7+3xopAOvb7UxU16N7x9+lLcm1sv0fTQiDJqiaCe82SyUMLmQJ7KBInHCpgN+Ey0WkfptV+FbLz1Kk6Tn8J5rbvvrvXt/bwn4BFZ6XLECZgD+CEZU0gN7EzbpH/7yzaZfC7OlIVXzaduez3XVi5thp480K5L3NK6aOjHe1dVklgeXzCK6tS1YUAtIKymsi6/GU8OPw9/E1hZXUIvMakEX99kFA0sEWqSIOPinM4/iOLEfRpA0s7EBbQ0KoXAEjeZLSI9lUCjQJFPoNTLbNhEVVjKOvbfcjqdO/xxC0D+y79/+0R9uWbflAt6aDg5XtAZLWExvkvRk/8nyuHl13zX9yYUJjM3PYWThLFSWo7KjvPYL1UBKcJo5m65g3JDl0notpxiOEfP5ch5bYlshWzN0k5Ar5xCwWb3b6/Bp1D6nRIIVdAUiQahHyZE3dAURDMj8w/JzGSwSNcgsiOIjYKSJtWwyiVDIwyAo8t2b+pDLzqEx1Gbvufb2xZZIeIMhCyznz+MtGFeygE2L0kvoBqN9Nvf4mld1Boh1UlM4Y9jVtUNe8lpjl+D6YrtKplsCLs1zl6VFE9kJ/ErrZqzufAcOD71KRoDVoDhwKNz3WdVqDuc+258iEpN48KaznUgJ4FhMsEZPROmTedZCfoquybwThVTMFmlCkBZTLtwXENBRPoNiwkpfu373j1taOr9dELInho/PJzr31Oo6V3JcsQJ2sepF9/byh/5yd+/0xaEtjOZjRXa24dY3mw7+zP2tyyx42mq7eDX/j1VmUPpjGk4ebPNOaCLmCgs4N38Wd0SDOJA/79ROGbXZYFdRL7g5so0y4c1zxAqx5YpMizXSVFZUqKqEb5NGl4tlpJJst3GBt1CWFIF8u2Fkhfh5Mb715b72Nd+LdO9+8p179rzl7RDrJw+mq5kXbb5g2ydWIYwa7uyEuzWBuFF1FZZ082TLXQDGmsoyQVuihFPTr6I/MYj5hTSRtkJ1pwAI1iVCdgrm6V9RpIDJRyyX6GxdyyqfizqyWabRXj8Q1k3LoAllQtXC081t7Y9t3XjNP63e865De666Lwf8JX4Zo24ErIiqxcpvvFyYC9Zdf2ItQ6+4D7btKplvmV55j1g1t83+BlRYaZBVgkppy2S5gAdPzxCdGEA0FHEnhpNIeQvU2LBdV6CKxC8RmlYgrxnxhZGs5CETjcloTZXytUq5RCkS7HhDy2J7c+9P/cHwP21fc/XLv3v/n6X+WPjqW2KK/7lRPwKWJMPLW/lwNapaj7WcQvReJ4kG5ADPgyusNwTBmqxmanPnVXh17KCzrpidj8xoMRbh5TV8DbGLdNlWNSKDt7s4+8P7i1RsdDZ0Ik4sU2ZukC9Ctw2xRMnQXFtL3/BA/+qnb9r57h+87+YHRhx381Pgg/ilj7oRsChKptu2uQpWcG32AqBlHK7HKtl8b6YKblq7GwenDhI8mEVHrBcx0uB8pYSg2ziVmVSFFRXItb0Qq6bZAw7t2k2UDKIKTYq+Kd5u7CkrfpXiY3FU0QL7V3Wve2H1xo2D0nTr3Pt3M9Lgt/GvOIT68cEi603Dl/mIXqQMwVUwF2cWmI/1WCCDryFCppBFqVDEeza8G/vPfwu3r9uO5HSefKVO75OqGn/J/gxs2LVOeNXqDnfyNITb51f39b/W39Y81L1q65m1pjktqdb02i1bRnZ03r0itVQrNepGwDJUa3leCi8d8oIs06qZa5fcZ6+xBWi/GH4Jn+j6HXxox2+hR+3HQ8d+DLNiuqv4RdeXe+dEtVjAFmuRtO2afAZ1bN2468t/+fvf/Jzzpn/ElTyueD7YG9WNz0zP73r0HqrIlrfO1ym+s6r5MFvR8Mzxx3FjKIoGYwELqUlUm3XYTtrkjFpVZS3xrUq42pNasMX/aRvDK2XUjw+WZMtdVrYM+IcLcniFdcsAD6t2Y+2XxhMXcfyFh3hR+lJm2uljadf8Ldz54wVoy5Gsatgr8I0/bFb1WS+jjvJgwduRDryyw2ll567t8dgeN0Uyl9VkWdwIoyDL+Ie5aSQXKkgKBJYoQs1fc813fCzPc71JtFzCnOCw+ASQ3mTjkCt11I+J5rsgeUFtraGZ5W2PY9m1GixuynFJ/spNa0MQBt0USaj1kbZrYIiwrIyH/Q2qwSr06R3KYBACSf5/Aa/0kBTye6ILVbk3tpiabQfA9g32Fn1X2wBfkr86OS1lQVCX7evgmXqv4M52AzQWfLEtCPrjfTCYTa8GdyyatlhLxbrYcYWNuhEwXVddpHCXt1RwI2fWlKw92oZN7VchqkZ5kxPL6/ds11Y7WG7K4/lt0d0Cr7boTKhtqcOKcCl77I53I+qPUYCmw20X7xwvSJYoiivSZvCXMepGwIZFebAoehA0/0chQbA9H7Z1bUGAyHunatItuHPLddiq+oDiduHhgnfMu+gWDdQiZM8X21gTGUBvYy+KlRyvHBFcK8AMO8GldsXQ6yaKrh8TLfLAxq615XfACYM1NtVTyFUKfC9Ehi2zTSmZyFgzk554F3GvMd7A1FxWK+1UdtRW7bPB0uFSpYw10V6sb16HxcwS3w3Grn6g4/3ZTmyok1E3AhYNy7Z0Z2PiKolPf3P5HJ4/8hhBj2n+RHdDO7b1bCPivoCAFsB1/duxmHW2bPcCL09zncZoHu7sCJhNgvncDHqkBQhGprovhPMWzkQJtinbqJNRNwKWlfhIyN96hNfSLIMT80THncyVYcJJdcYTk9jcsRYbu7egM9qBBmJ7EukkReFCrcuZq43VvYhRO58mKTi3cApnTz0Oo5TltVxemiQKcqUp3HMk4I+NoE5G3Qh4V/OmIxv7r/3vxaI5VyoXq9ExC5YUlQEPzvayTHMPDL6Iuze+F+/axDbTWKJI2FjW2a5G/6H2VDWXZtvnLdHx3xyZw3iuwCNv5r9LRAGWSubc7qtv/Yv3XrPzIOpk1I2A2XolVfQfX9u1+dHGSMtB2xKzXud3VIvcLUqDZJyaOo+54SdxfbCIsYmjfEdvwYU5vc2wPAjSXYIGwcuF2Oko0S1pqmu6TQq0lFx7vOfQpp6djwd8kWNr1txZF9vasVFHSBbw+Y9+afTE3FN/eOTk6VWPPvPtPz4/NX4XpU6GaZiq7WLFTFA+nx+vjBxCbvoUhucyfAcWPuxqoFQzzba7dNR7jk15t4BPlJSybtjq2u7Vz/+b2z71f9x5ww0jn/vcl68otuh/NupKwG6dVv7Qoa+cOd698W9j0Z6DTaFoYnL2zPsnF0Z254umVCyVmcbhQiiEs/M5ZA2Bl85Y7mJxvv8zr5M2yKQrTk013YqUbhGJb9uijz1rru3d+sLG/q0/IA65MR6LH73zhr2n6fPrJj3yBm8gIni7RtXp+OYTX9rxnSe+/vlwJL6wa/Puw0fPHNkyPvvi/SQ3NZeTE5oUWzKRbopF7HhJN5AtyEsBf3xRENPxgN9ozKTNytqeXQ9tXb/z5JFzL2wrFlPN99/6+//1fbd9qG587ZsNNl3fFgI+dOiQMpE91yko/sTeG/dmT4y92PDlb/+f/y2VS7UNdG55dKBn7enXjr90zezSiQcYi9jWtOUru7becHBifnjThakT9/jk2Nxv7P0P/3XXxl1Lr776k0hGMBpv33k3W+VXdxr7usEF7O1w8LYaT778ZEOmPKM2o29xz549BmtUduqVA5tE0xI23nDzqTtW31F57rnnpALGmjQzqt96694l1Of4l5ZECP8PAPgFhqae3ywAAAAASUVORK5CYII='), -'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', -'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', -'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', -'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', -0, -'test', -'{"春江潮水连海平": "海上明月共潮生"}', -'m', -'m,xl', -3, -127, -0, -0 - ); - -INSERT - INTO - test.TEST_DATASET - VALUES( - 5, - 0, - 32767, - 1, - 65535, - 8388607, - 1, - 2147483647, - 3428724653, - 1, - 9223372036854775807, - 10.5, - 0, - 10.5, - 0.188, - 1700000.01, - '2021-01-01', - '2021-01-01', - '2013-09-06T10:10:02', - '2013-09-06T10:10:02', - '2022-08-09T10:17:16.161342Z', - '00:00:00', - '00:00:00', - b'1000001', - '80', - '!"#$%&\'()*+, - -./:; - -<=>? \@ [ \ ] ^_\ ` { | } ~ ', 0xfffd, ' тест', ' Airbyte', ' ! "#$%&\'()*+,-./:;<=>?\@[\]^_\`{|}~', 0xfffd, 'тест', 'Airbyte', 'Airbyte', 127, 'Airbyte', 'Airbyte', 'Airbyte', 'Airbyte', 'Airbyte', FROM_BASE64('iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAYAAAA5ZDbSAAAACXBIWXMAACE4AAAhOAFFljFgAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAEIPSURBVHgB7b0JnFxXeSf6v3vtVV29791q7bIkS8iy5U3IC2DHNnIAJ2MYQl4AZ4HJQB6TmcybQQz5ZfHkDXmQkEcCgQDBwWb1IrDBu4wX7Vu31GpJve/Vta93e985996qlu1k3vzUJiq/d+xS13LrVtX9zrf9/9/5jmDbtgTAQl2Mzwn83zc8vfzBPn777Gc/az/y8qd9iaAULvoSoQYEVdGW1FLFtCuo6AFR0EoFcWkhX1xoX6uK5YnSr5fE4v7PXPPI3Oc+B+ENH/1Z79z/a+Oz/8KjX8IQBBKwQMPG22Q8e/Hrvuni+e6Z/MjWRD6xOVcsblRDaJMEKeRXA2pZL6NoFso+ySc3CO1TF3MjL/cG+62oHJCazYYH77v+C0W8TQbJVqxbAbvfm9/1nvv2kf/cO5ub+r2hpeO3SIF8d3bJipiirQX8klAsmYhFJdJdoFQxIKoG+qUd9lx5utTh7zRHkxdHFb/wj/F4/JsP3vizabwNRl0L+OsX9/mkhH63rAVeKKbThaHcqVv8duDP5tPT61PSFIKKhsSChfYOGZm0iWIZdF9EuWwjlbIQiZsIlltwXWQt5spFfH/weciajcbG8NnmePw/xiK+px+88aUs6ngwAYuo0/GRvn1l0YRhl/MfP7z48mdGps9+KSI1rNfJw8ZCKpKLJjRVhKaJKOVtiORWRUGERDejIsCqkDbLSxg++QouXDyE5rYgZNOH5FJh3cTs9JfG5xY+/fs/v7YVdT7qVsBkne2AobxUKVU+nEjPf6ot3NbdqDXBktIwSFuNiohgQIRtAqYuQBIFLmSZ5rRgC6gUBWhBCSdVHRdME9GwhEhMhmgpqJTQNbew9AcLudQff/LcJzXU77DrVsD/49RvxZ9KPfFHo3Pj/bd0vyd0+8CdmEmPQdJ0FAqOIMn3ks8VINB9SWIazAQtck02dHqORB5t89F7NHosoKlJhk+TIQsyFFMNT4zNfzRx/Mm/+E8/v7URdTrqUsD7Satmpi7+2sTs5Icmkxel7koRPUYOaWMMgqTCIuExASuyCL3CfqTIBUui5pos0V/bEkCKS5OAjiWB6yWaFAppcViGYJL2B2Vogg9zi6n7p3ILv/bFc3fUpSbLqMPx2tjYuuml2Y9WimK8pCxg7MgzSPiDKHUWYCsKLNMm4Qpca5kQBf4fuGlmkbdIQrbovmGQgDUJqmLRRLDofQLCIYkHYYJoIxwRkMyUGtLZ1EeHRuQDdIoTqLNRdxr88MMfkJbKyX+/mExu7wy3CLYUwvdm0vju2DiskEzaS8IzBKgq99P0GJegFlzQgiNsg46TScs1P2k03SffyzVaIW1nViBA51MFhVKs4rZ8qfzpD9gfkFBno+4EPNPZuGEhO/1ekBk1pQLWxq+CNtCI8NY4FEWGadiUHgASaTBlgKSpcCXK3i04Nxv8GJM0XaL/+iK9dJzlmHOJRd5M4CIiShQ+OqdgyEgVU/dseq6wAXU26krAtr1PHE8Nvz+XL8RVUUPJKqKk69i16h0IR8kcWxKa1Q4IFvlV2RUqEzBJ2WaStmuoiM3vCCgZJTSHmtAR6kWhrPO4U1UF+IQgOoJ9kFUToqnSxKk0jGem3s8sCOpo1JWA/+TFc+unc6N7YSiUz5IQpABOz59El7oKm1p2kHBU9Ac3U0RsgWX4lOg7grRdbSaNtZiwXZttsRSK/O5w+hRu7L4FQTFKQIhF+bOAgdha0mgy1z5HyyWTgJP8wr0nmzLrUUejbgS8b98+cWppYpuulzuhUypDAZRBwtINHacWjmKTdguujl8Pnx1BhaBIFmBxSXKttbmwmW9m0bMjdGcCEAGBVDmBUjmHa9puQJne61f9GGhch/nkPFTZxyNvwST/blodk+mFbey7oE5G3XzR7l8vBHPl9LWkdTEWGbNImEfIZI5Hc8MYnziNO/x90IqTBG5QFOz6WNs1ylybBfD3sKcsemzQcRbxaJrow7GZw9gavwZhqREdsQ60BtuRyCTJUkg83bINiVIOMVYs5q7133YkiDoZdZMmnZsYaa6US9vMsihblN4ITMAWS38oy6WI+fjCY4icUTFMM8Ai6TJBsuNIhnRjYha4MJnkTQqoVMpxo4qfhJyFT1YxsjiM+cQc3tX+a7A1C+n5DArFHILwQaUMuJRh75FlA8bVk5lcC52pLnDqutHgXCbZXjb1XstyzC4LjG2XxVboQTHmw/esLA6WS8uDZRK0ibZQuxNvuT7ZMA2sb7qK3qdApwnBoA9m6l8ZewUdUhu2aHHMpYd5rsysgMzUgO6LFICZhtGXz6XbUSejbgRs2+Y6EkKzaYluLuv6UvoFpMykxZS79kYgNwYpRRId6dKtTMltR6iHTG4XSLdJmw00BVqxunE9JrMTXLgEZJGflXBudhCzg99A6eLjkDPDzEzwScRSLvYZLFc2TLPJFsy6CbTqRsBls7LVNHSfTZmMIpJKSY6PZZrMI2YBDgxJwZWkOpPAoNdFst8XE6PY0bKH+1pm1vf03Yn5zAwFVhUedLGZwHLonF3AM+dO4NDRQxim1yVJ4lrMcWz6DF1nGm35KqaxBXUy6kPAJEfdNPqYUrK8tyfWSxBjkAdKXLKuNnMTDF6nwn8Ze45FyfPZWQSFCK5qvh5doTVYE9mIwZlBsFya5cfMk8s0YRSfgsG4D8+1KFiKyPziML8tkAYrCglXdxLpimH0A29S1nMFjroQ8Bd/8km1WMr1MhDCpCuuyQG0+LsoWrb5ZWYC5RbZFbJ36W0X2SgSRHVubhC7YjtxT+/dWMokMM00lCyB5fpzhmApqgR/RIHcqkH1Oabb8fekxbITgTONLxvlno88+5G6IB/qQ4NDoUjBKLUw2SmChmRhAX2BDRQQy9w3Mg00bU/ADqEgeCgWDYmkc3HmWRhDj6Bp9hiOjnyPgiudR+B2VYAi97UsOmePWZ7tBHJOxCYrDkHB+OWyXm5pj+bDqINRF2mSikozYUlRJpKyUUHOSCKuNhEs2YnpwggJxVcNqrjGcWBDqGoz86Epo4zXBk+iOTyMEQq0JGaTBds9hgRMAhQMoYpuitIy00//kTvmxzKSgiLpSChXaabDFnCFj7oQ8FIl0RhVor5NTVuRD5tYKJ9HhXDoTS3bcHFkiI7wuWiVIwzBkQ3XalYQzIj+ok/GqxoFU5KBBEGQErFF/D2We7zo5lZM+1lULdUidcudKJ6ACSDxpXKZZtTBqAsBL+Tn4xO5cbFIZMA1TTfhzoE70YgZ9GpLeIHSJoNBjlYtL7axrIZQcLRSIh8rxxT6xaStCzoHQNiRpu0d5ppkOKZekpY9ZjZBqPl327LEpXKmAXUw6kLAAdUfYFUYS6UkHh16FBdmT2EHZbVILRBAYTooFWpWmmue4DJGEr0qOVEX11HRI/3dZ5gph1DVevYUO5fInbtHPzkns90PsemOYhNIXQejLoIsyxRjzExKFnGzRAnO2GN4sjSJR5ZyKBHMJLjpkWXVTK5DIjkskjMurQx2BOpMBCZiLtDqrOAYB2pxms35YnZjE8Qg9Ktimqu+cujjCq7wURcaXCBzKAquFgqsWkOBSTpdIdpQEfQqW2QvW4DD7jv+2PGp3l+XPXQKAfhxbu4MR6jV2eHhnQDHrttCHUgpCRSsRbRF2jHQMBCbyQ5f8fXk9aDBQkUwNEdKIv/GAg+AGU8LBl9hWeL7etlUzS7XVNHRbp5Y0R0H1nYnjlQ9hYedVKtAdIq6G/wxbGjehLAvirvXvx8lwyjue+dzJq7wseICvmhf9Nk1u3jZ42H7YdHUjbBnUr2aKsffuigF4Aq3pn38K7D6ZyIRdNtwyu74oRbPZdc3beC+lP3HymqdhFpAdY2Hd0dwrMBsbg6bWrfhroH7UdEtHJl9LbLvuXde8dUdKy7gzNx4+9DMgb2zs7MrwpkOPvKIVDFLmuBKlftVuKAGP6L2L/fBtlDVPpHUcnXDGvRFVpGiqyBRM7IAmWIWzYFObG/bRdBnCc7U8KJm582iW8fF4zRCvOZz82jLDOKGiB8/Hf4R+3zf6YX5K94CrvgX1FuDk5VysUUXFt9DmqwNzTzbh8sY8VCbQEGN5GivUI2VLGuZOYaHYqEW+dLxBmnuTHYGcV8jbu29Czd23IMmfw8v1TkzPYRb+/YiojVz+FN4U5MuVIMxdufw0PN44vi3sFCcpbRMltpClRWzVG/VWPEga4ewQ3/21LeeVqF8NFkeb64oha0/vLDv2YpVqJALtSq6oKtiMKWa2tixdcXZfcK+f3Ft8pI/KxAEfUm0aguUpkgqYmoIGXuharMFr0RHsFxEi3Bos4ij0wcxlj6DXe034v6BTxAmPYXB6aPoJvp+V+MAThunavCml/l6YbQ7p1RNxpOk7VpmETalXoZtKll/L706git5rHwUTdfm7x/6Qk+j1LznzvZd1xRDF4TX8qd+m/kt5uaIiaHgyG/4NP98KBv74dMXvvZoj9n+/Jo1d5bf7HQRLU9MEs0JTvoyzJnyXpJ4WI0gGG7C4tIkCSPgfHS12Aq1AmgeDkhIG2k8v/Q9nFh8Adc27sVdLZthj/8Y15dnMEHRVp4Fa2xiCF7k7dw80ISHckEJop+AEp2lSoayOJy94k30SgtY+OA3tl87m57+qwVpdoM2fR5NQRVGj48D+xXD5pFwNluRm+PrOnQ787GF0Gg4mt/67D93wsxiUTBtQ2SXuSXYDMUoUgS7QLRfFLIVgkcecUiRf4NloIbgEg/0bpmwx4ZwjFKuLL554u/xC6IP90Z0zJEACx0qLllnadeAjyoAIgq10mqR5eamhM4rfxnxigr4o9+5dvP56bE/t0VjQ0tzBBm/QsSAjLCkcD5VrlgMtkdFLWGV0AJVGVAPzO9/r92p/4je/sM3Oye7hJZg8fA2S8K5rucmjFpH4FPCEMqaK1yhFk3Yy6BKHmQT+S+6kTIdFgz64fNZGM5l8ZWszc1tv+ScR/QyLvcvnxySd39Znizwgvor3v+ysSIm5vGxLzf8+dO/tXNycfqPBVG/qa2hCbGoD6YgIxLT3HSGKAEf4cYkq4bGIE6ffhzHzvwY87Pp6NHFn3/+W2f+4zVvll7dtmqHqEk+mb2SLmfw3MhzuLX5HtxMOSmMPBfgcuzZ9vJX70zM5FYF5kCQql+FP6DBChH3G9Uga5JTICDWrghHubx0a1ng5f0WBn5XUtYVL+QVEfAaeQNRqdrnTal4y0DLgNAajfGVBSZf+0NAASH6rLJRJFOpE8rvJ+51oknBfMSEavqQSWdXn0sd/rUfn30w9Ppzx+3OoCr5Gi2KdFmpDsOjXzz9AwgXfoEyYdIQnfjLsm039629t/awJgfmV2Ui9hW26IwYJo1ubFVhNUpnuDbDmimt6gp3UWJlOni1wIrvZLRH2vgicmsFc/23cqyIgGPBrmhMiV+3rm1tcFvbtcjbCU7GM7JcIBPIAizdsHiNlE73TRJyIKJBIsiRr8DPUXBaTL77TPrkqtef26eEpJgck1kNM3sfu/AT1jweunAaJ1IZXlEpkm31SwGaPAZ/TxWd4jehWoXJgQxWX8VuLsHPiH5Pwz1wg93ViXdeHVuPgBTk582Xc9i9+ha0R3sIONEdjqIOxmUL+OFT+9S/eeazv7060Bv5t2s+hemlObqA7AI59S5suUhFN2GQgCvkg8t04xE1aTOLqH1+CeW8gEwhvcGolO72znt89sngoUOHlFCwRWj2tQpMg5kHZ2AGNAWzTUGUaZLwGilTR2ewGz0RuvhW2Y2mXR63KgbBBTOc6JgJWZBc4VYPcScGTZiSVUKpZGB7+7XIlNK4pnM3dnTdhKHFk65LsKDGxLc/Fn1samjt0Mih22IzRzAxehhnFk8TvRfgzU4c8IFMoB3ktF6ZaTIJSndXHlR0MtsszKPwt1wypYyRvpmgSYn5YlnU1kpti/dKsBtjvmZLslWHzXENoyo6VZReffTw0llsbd/GiQCDBC5QdNSgNjoZk0v91aJq1Eh+Nx1iEVY1kILz3ERiFFuar8XG6A24a9XH8NS5HyNFLkKURNRHiHWZAmZrdC6On7tmdGGh96vP/ACPHH8IBsrcRDJhssGsZrPWwbWPpUmsMpGZW6YFTJN5XM0WalNumcovbtYuGk2s6082XThfrKTXpSrT/6VN8XVq0HgO7Gmkg0O4+DH9jJJexrnFs7htzR0kMwqixCBWRda7KbEbJS0TilCNlr1zOPcdxpBZGBnT6Sn00ON/t+2jWMzO4eDkS+QiFO8LWJjBFT8uS8DlG481LCYTewqmFTvZJmIpJIIZLbZyvlJxsMNsoYSo1EyBCUXTlDKxSoqKZXO6jvtkw+mAYxkSMuVMy3z6NF+De92aOzNlQf3S4viB2eTx73XLyTxdfKlamuMhTB6eoZJQT06fRClfxK9f9RF0+Tbwmi2LJkWNRbKrsKPnbZ2Hzpn4Kgb6T2PltDSDysUF6GPfgaK/ip9d+BvKCpw2EDbnj2H6G6S3t4men5lrKJX11UwB/ORLmallmsXwDNNwNJhepwsloD+0BT3+DfCCJdv1p0zIHKFik0KviFk90eKdf0//vSndCP7t4UThUIJsg1QjjuBppHeFOfdLQd2z559GuxjBPZ07IOpJdyWhXaX+ariowLngZl8zBXIatzosmOr291OUH+ATwwj58Mj5YXz70MO4kBtjq/2rkbloi3XR/vGyBJwspZpK5UoHC1iclXu2uyjMFRwYNElmlczb3ubdmEkvIEAX30eRKTuWvcbWBrHByAP2WDClSzraDLZHz463+gd1f43BYwIT3FjZkZ3TA4uZ1bnSIl45/U00TByAMf8K/4lWtV5LqL6HSYkR+UE5hu7gGpTMAiFjGjFPa5EsLnFcWw1IOOgT8Hw5D4NpL/fj3moKQc/N+q54IV9ekGVgTblstPAVALazes9rfGLx5ic2D3ZGp4/hyRcexFh2BG2+XrT6u1CgC9oYaEV/cC2Z7IoDNVqsSL1wSb3x6cGHmboY7Ly1paBwIuplnC0DMFgts0a56mulBfz1mefxQi7JAzGvEseDGkWPVKAn54jn7fddw9cO9wZX0/t9yJl5nnqxq6MQOKNqzn37Eo8u6KE29Yo30ZcFVZoVq4fSH02hC8CnsuWu27W9khmBR5yjGqVBUoHkRB7ODCCqBdCkdWF9fBfOFA6wJkduyY1NOLN+yYqBhlV+O380b1lV0NkhFRzuvloS6UbDIq/ysIj5Od/sp1SHXkpZ1fdU0yfHk3PAIl1KQM8b2BrZjcZoB1GBY5DJEjh+flm1CHAJQiba/x/IgyuG3kQCFllkyYANy3KCGNaOyAuA2D9aQIE/EmAr5MkEG1gX2kw+8jdwnqLeheI8xwi9VQkk5Uu+U0c2bEuiaGGZBrp0L5ZXc/DKSfchy2J8hFZJYg1mdKBGp85ZJexZoaCMN2IRTJxPnsD7V/8bbO7agvE0+VpZdX+LXYviPKDE+3xJNBuS/rd5HixIDQzAYELtDnRWQQS+4Nqu5TPsOXbRGbLVlruAzYQpH55+BUfmjkAyFUfjPc0Q5Ev82saFZpo6km55BtqqMUVerToP3VlttItSCV5OC6fo3XJ1lrdVog/bFL+Kt2ZgX1HTNFw0BoHCGCLCBRQqC9yiwJtwQg0NWz4kQdKTDave3j6YctqoSBchXy4gphHB4I86F5JrpF2rsoDjB9lykSOJaTx0+Bs4nHoRiqw5DnGZdjIjvvwzBgc32Yqilt2X+bJR55y2m7+6HtEFLoRlWkukPIJKCKsa+ilC1zmypQpBtAS6mK/nFKIsyTBUA8eP/l8YI/LDZOtTq6sU3S/huoZqWY/NQZbypsFH3uYabEPjESxd1FyhiN74KjSq7WjUWuni6vAyVWeJCAUsBD9Nh2UcDDpBEfOBPAiyHY0EX4urXkL8E5hi2QZK/Bq7FB4b1eJ270CpptHeMWR/sZCb50tcOiKrkNUz6PVTIEVCNuxKFfvQiGx4Qs/iH8ankePrRWvOVvQQL3cqVX86hQv79l35nfIvS8CO4RXgI02cWJjA1qZr8O6+XydSvcBfXw4F83iIhOALEMpEPDE3oyJcSg7uMn1W86zpb/gcRTCWrQp1nvOiYaH2bTiR4LoDjx1ine8OT7yK96+/n9dj7Wy7hcxwmtdhcTfCIE/6FmY8iArlvZIkumnYcqRMcBml2vel8xuog3FZAib9sxwxSxSx5hDPXUSvlECimKYrITlNT+BWOdn2JasJ+PAqF5flt6IgvaHWWJFEY3nQ5pzLNcvLNM07DReO+8tYADieGsNschQf6f8QOtUGzOVnl388PMrXYZk8Hy46/lxwKyy563E+j88LqT4EfFlpkiJJJQ/mkyg1OXD85xhJqDCDPt7eiKU9kofzehdHWJZNVoXNLqQTPcmi+gYNVmzV4GbeM71VYt4Ngqp0n/u6Vz/tCpmBoQdHH8ceeSd8kWGkc8MsmKue37aWR+ZOqscE2+7vwLQ+RS9W6LfK2NS+DhfypzlWLdnS21/AkqSkuBmkCySTf32mXEIzUX8NsQAYFM04YElwyH6+ms+NUBhcKTBOEXZ1lZ9H5SiC/EYNVuU8/zyBdbdja5Ec0yC6rBC3EIKDEnsm23YlJikMHxcwhxweO/szIvkpDjAplJOdz/fMh2OURRelEnknnpARxobmzTiTeQ13rPkATl64iFKlxIv+FE3JoQ7GZZloikqzXFAkJUach0IKAqTJ3nWzDMcJx8gs8ooLi1UjMtLe7+LKQhXBcpqGMi194zYDqqwU2PX3qRo6Ix1VYr9qol0/KQrVKKuqzXz1PvlVmybGiRYNh+N+6PSdRXt5tYfgfgHvSZE3QJvJzGBrw424vv1OdKjrcWz6NW7y3eLLMupgXJaANVFNy0TVsN5VDLFiQrYMZ40lJx1IwBbRg/3RAQL0A7yFUaPWRnjvAAladxZTk3SDxB/LrskUX2dVvvjKJyOKrDQTRQG/5qcUpxmGbjglrZ4QmeKKtY47ooSqv3fWMjmdcjSfwrvpiLWlD9V1v3wRWjUkt3nbh6XSElrp+927ai9eHX0O8WCELWV1UDBRvCwT/fFDH1f+9MX73/I1xpcl4EAgNCXLss6YI8FyfKRecYMR1jafNNswKgiJjWgL9iGuteCWgdtxLjnCu8uxC5st5rEq3ofuSA+XSskoX7LkJU7UQ2e4s7M13IqwFkHYF6kFbEBt9QFvmGVfgnR5QTYTMOuU46VPHt3oAVWOFaHvzzy9FxlaTqB18dg/4MzxL2CqMIT1TVsIvavwDvL5YrGCyxjtxoRfV+fv2HforgDewnGZZIM0LctKngcprPuNopB2ma6AWaWrwp/P59PY2rgL9679MMaS57CYT/GotzdCxAORD4ocIs3s4ILJVZbiy5t9fmjNlzKJYurAzo6dhF2vc0ykx+dWAQhUm7Gw+zLRet7aIsezwrXCQjWy915womKbs1veC+z7M8TL79ewv5TFI3ND2N51I4qVMipmhft0glf/lwTMtgT48on7GzwYXZAlSsXFVQHLirDH9ltUhnt5ebCMeb+ipkl/USkaaA41oyvah0Ipj4iPEKTYKueCpAdxY4MKozKPw7OH6GiCJ4luSpbmCZfegj1tN6CLtJNpzVJxseeuj911yer5dClXmkyOYysF2EpmhFdSem6WV0fZNUDFJ/vRH+5zGSo3WXbKw5xo2eWHqyYctedd5+Iea3EQxmzUEGzqx1VNu3Bx6RyPvtl5NVX5f2WiWX/pBwdv2p7XjX9vSuX/9tdn3/e//83Q+/8g5rd/x6/5rrXN4OYvvHzvhgeP3vOWtEe8rCi6s6VvcXJ2cjaTy/QZJR1LwhLuXv2reHbph9jafDXlnlMctpwmjvbxn34JrxKGIShB7t+YNpXtIn545oeIZU8hY+dJ7D7M56c2LxaG++n0p73PiQYj5umJI/jZ7CimkgaUtiDXUObnw0oELcEo5o0E96e95O81csKsvEdwF/06EKNHNbo9tZwHVZPOA0IWaLF2w0zgpu0K2sa1zbchkU5gIT+HYEhx0j/5jYDM68cXT+4dOG6c+8RUYu5/W9vUH6kQsjaTP0eZgIgcxREd4gCCdvQaUxT2R0T8F7wF47I0uD3WkVckdY61BzQqFvnTFOYWF8gUfxAD4QECGKZoBklIxTR8O6MjzcthHFSoQn6bbYgR8wfx8/I4XqX3SoaMvJFrPz738tVs1y7vc3xSwDDp0SHypRMBCsjcWirmI1nX9y7ilJuJYy4bBgZi65AsLBGvqy4DVxxtFUWhSht63QAEYZnQeTRv8TSJlX+xGCKstGFTbDuOTb3Cg0bTaVlLiLn4Ly7+/pOhvY0L1sSfBYSmB5r90UhTZSPidAuKFGwW/PCZYaiZJFpnkq0XRk/cniol34u3YFyWgDsVf17zaaN019CLzg8/M/oy3tPQQb6yiAwFUOUCCdIvI9QcYkutyT9aXEsqZOBYKqoS4C8oPviCGvQy74MRH0+P3PniyCPVyo6QGK5Q3mqpdB7GPQNV94uyWSK8eQLv6bmXC7qdiIQ0Rb+M0/Uap9ieM4YLny6r8HBycdb6HTz9alKbEZGilMMb5HNLuL5xHfzkbudLM9jRvQsbm65CSA3aiiz/sz74i/vv0LL5id/J6vP3qKWo//bGj6E/tJ20tZEmtEYgiYIGvw8JmixDxjmYcrZrMTWy7/mJr+7ECo/LEvB7byjmGyKNxwi2y7B11CqZxoSVxo9+8iAOj30PPjJnuZwJq2wgEJSJwWFVFxbHfvn2CGQ22f5ERZocskLvJ9DfzEOaz0//yk9G9+/1PicUjZdIq8zlvK5BEvLTxGhUGwldGiYTOoIHb/oIhMoc8lahinPzH7ksomajBm3Y5BY0xKVWvhBcJhexrfE6pAlqLVF6F03quEddQJs4gd+++pMUL6zGVGKSRf5mQPWV3uya7LP3ifPx3N0Vcel3hVxYnSMq8vzIEWylQBOLh8HairMKUkIBUSSTra2KIhwKUwRvNL948Vt/+vSFb/eyc6xUl4TLC7KEfdaq1u4LPk1K89ortmohJONvzs/hdCKPcEQhTaDUJ68TSMFyUY0CsArlkiwtEZEtEVrkIy0z6ceWTDREibojnqJUKEVHFk7+hwdf+Mx29jmqJfMtNRhcyKJoizX9JgF3RztJm0Jc4EfG9yN74XuYHP0pPTZrDJUXTXtSXkbwsbsG5earQ5s5jdhLAmSNwtN6GgJd/DS5lVcPDuK1l36Cbz77f+O7xx4ma7HI0iRLfRPEjY3gL843Fc3sr8qG0mJVFErtAjiROoz9I/+I00vD3M3rvPjf5pgBWwyg030fxSbT87NXjyV+cfc7R/q3fuHlT69Im6bLLnzvaF97MRaKTjPzVskZBCbQzw/4SKgmfBpr7SuhkDdgl8vY2L4JIbmbfmCWm2bNbuBUfJwmRb5AP1i0SMhkqgmYzBbSq185/+QX/uDxD7wjFozlKLCxGLq0rXsrN6UM0OhvHECeLcqmc82T8P786Kt4ZmHWhSHZqIZT7hCqgZMTd4sos51bjBxu6bob13behInUKFkimaNz5aAfX01l8c3EEI6nTzslRywFo3ua+uYCzliJfsr9r9OLvNslxwVkYqlm+31Yiiq8TJhBuIWSw2alycKx51S6FrpuRVOl+Y8HhcjtXZO7LivP9sZlCzg02j29rmfts6ago0yCFEi7fGEVubRJwQSBHA0+0k7S2HwFF9NnsLFlBzY33g6RfOe2tp0olYLw+YmY1xQsLNIEobS/Ma7R8SKSmfTNJ0ZPPPzcyecfkE2lnC5mkCql8L6rf53y5m60B7uRKae5uVOCKiYb2HIWv9tn0vl+QvVfwWlPCCda9gAOFtEfnTuMW9vWYWtLBGdmT/E2wwy8UVjH2a4wLII3FQra1jb2c19NCJyhioE3FYCuV24ulko9hbzlnN8MkhFRuNYyQeZLNl++ky1YPC1LZQyQasDKBSlVvFoKon1tQA5P33fffSvSweeyBcy+yIaujc8HAj6jVKHZmClDDRLgQd8+NUf5MJldgTXbzpr0Ywt48eJTiFNk+qtrfxMbmjagOdiGxWwBDSRYH5nf+cUyIU86WlpV3vSskC+sOjp68BOlrBFULA2nZwYp2hbxgdXvIdNdIQ2sQHDXovgUZ79Crw1wbRWEI3AGYdrLYGcPFCkYRQy99iWcO/4Q68nFD3KreTlmzjQ+6mtAM6FpLPgC+2Z+35ti0cVycaNhWJKui2Bb3cblTr5tbZldG93RXjZ52GM22YpMKUgMFxKj2Brbgk69VxwcO9WJFRorsrqwqaH/YFtj6wVW41xYqvDoOBgIQ8+SOTN0vpIwVyRTxdYiUUT63ePfgZzNYHe8jFVKCamCQCS8jqaYSZFwL/x6D9KFPDra/IgEGEBSUYl+lC1D5MtSXjqzH82Jw6hMPUdmXawiWE4xnFBtV1htyGLV+GPwVRW1kkgme5ny0q8Pnsc3Tp5iWzJxgVqmA3swJqxBimNb+zuc1Rj0GyVBNMPWG2lNtnFXvlzq0+mV/tB6skpRyGR67YpaXYBn8r2bTLJcvK6YMgebFx0uUcaRzD+P2cH9yvn5Y+/ACo0VEfB9Ox5Idzf1PqQEZCOT01Eiv9XR0IrVLRswM5pANEK+y6cimdJBd+Enc/r1I3+Prz/5V5hauICA7KMfZxMVR5PAN49NrRtwa9dvIJcidiooYMtAH2l4ADqBKXq2gtlSGn839CoeHSdMW2FrhWyOQ1dX4PPhthS+5FfW9kyCWzrrdIUXkGmJIhsLccLEEbBzY/sohewY9vS8kyxNgiNczETbfv8bBPyZp877C+V8O3vP8NwwtvvejR2hjVBIiKWSY6KLrGN9eBVNWgktvh4YJYEvxpNJ4w8sjOGhc4cwkRzdfGjq0Ipg1CsiYDY0NfTTxlDjxb72AVTSpFV0cVa1rMLSUgF2sYwIQX4lSg/KBR0NGmlGKIYfkf8ZpZncqlm8D+USWcd0sYjTC08SL5zA7133R1gXvAXv6n0fOprjaGqmqDSo8H0XJsN+JEMB+CWVbn63rKbK/AOvWwwOd1WClwPbbnWmkyuzrj3OYvVqC2HLbedP51kqJJHPTlHckOMlwYTOGZKovQGqXNM44NdNPSLYEjKFHF4Y/jGGDn6fXNUkp0otvjzHoHMY2NJwAyJWF1m2LCy+WRcRM+RDpKYQoVyp5n5fWxwrMFZMwNubNp5RFOXpdL5ovGvLXSTEVrRSGkMOGOn5HPyUGqkUTabJFwtl8k0hiqL9AWQrjGIkHDtI2svy6DRpE5nzQ3NPYDr1Ah64/ldxe/8WpGaKSKUqlDcLWNfWwzeNNAW2SHuABOyDZS2rf6vSSB575Arcc8wOn1t7aNeowhq75LZiosg9ayQxPfhdaIU0vcabdhhhFii8bmjIRwnRCzFBUiKFpJ3G94lcmWGd9ixnvRZbBjuWGkNzhlK55Az5aZsv1mPfSSczrpB/K5XzkenUaBtWYKyYgH/z3n2pmzZf/43ZzMLZV44exG39m7AmCjKtDUiSX85PphBtUCD5fJhbMiAVC2j0U6KvEf6csciEVYiooFw4oCCbFTG/pOKxocfx3Cv/HefPfI3AjgKlXWFMzZegp6NEKGzggc+q6GqKrDM80KoSEJYnKMuBFj1+kGmRbbsL36rFHG4xgnOzvD7SrO2EYfOemMxnfu21szg4lySolZlwUT9y+uwbKipLphjSbVNx9sG0WdUHAs0ESYZUvlaLCZLt48SqRb577Ac4ljgOTaC00HSWxQbIX7PvWCjryoW5U01YgbFiAmZjx469x66/ets/naBI9+kDj2DsxENQNdJYVUNiQYe1ROBHTCUySEV6SUKTEEEDaa5GsF0yJ2BhiXw0kTSdjRL8NJMzOQ0Pj47iT08cgkmutrtJwKaBCLIYRa+/H3vX7UWCzGeRomCxVoDlprsEHoga3/zKdLV7uRK7pFL1L5aR/Q7Z4EwQm3cWINAjTumO6hTEU6hn+kOK/frfnytkw7ZpqiLXcieaZ5OHJ0QE7LDAjQufFTo0RiCQObZIa9lnsdrgJqWdofW88wGheSuy6ceKCvjONXeWb9103d+u6u0+8eTYRfyPA+dgMf8bU3jJzPxEGnoqjViTRpbbj7DcizwhXi0Btts2oVymjJlEBcVsiVISG90tCuWiGtIk3bklYGZRRyqtE7iRhZkbxC1hC+fnjvNVhU6ZkNviwXLua2S6r2reSuR8obp9ju0eV6vkpP8Nh/Bng88Bbk5tvrxFI/SNoWYa24vJ9c8EuJhEILxBgzOFjJ9t1RSUw2jzd/DWEhVL53XiIQ5kmHxZKovMne4EjpWw+cpKQvjEGE3KAAWblBuXzBWRzYoKmI0Pv3vf/KZ1Wz4VbGg8m5Nke3EyDztXgj9GWulrgr/YBoOE6AtI6GrsI59Mgp/MIlgpoCXCut8EyOTKmJgnQeeLaA4Y6CFTH/OzHUdVCtRkErKI16aG8JdPfhVzxQThyc5yh+VlrSw4ms3MI+iLYHPzduTyeSeq5qbS2aGy1sHdrpIQzrC5D95EWYAM1dnk0vZcOueYrXz5jeuSSkIlyNIoduy2zu18j6du4sSvjr0DE5kJXl4cFuOEw5OlUmMICTESusEnJE+hKO+Pa7303h2IBRqxEmPFBczG2sZdL28c2PgFSVXnGdyTmi1ALBIB76sQsN6IXb3vQn9gNWlpA1pbGwloIGHMlVGczyIqltEUloh39ZPp9WM+JRCiVaEou0QXp0zaYKAlSuZbVXFMDXBzD5cCNGsSc3wyCfTViwewu/dWshZNvCaMmW62l6FsK+6m0U465G0gzXL5iBil+KCNr9RIE40puBOGB10202zNiDQF3yDgkBKJ2PQZRb1In9eIq5tvxjWR3Tg4fJDn5uxzmtCLuK8P6xrWIpvLV9fasX2MUUni3vU7ETJaMJedvTKQrDcbn77v08VNa7Z85/qrr/8LuqRm0WS7eRZhE3gxNH0Eh4aO4ta+jVgdTKNVKBOcqXH8mlw0FmgyFBPEHJeXsKYpjlWtlCuS5iZJqxNZm4RNFzBX5giTX5OqZtMrhne4XcFJfQgZm8vMEpCyhNv67uJ8sSYFcHX7NZyarDYvtVx82nY0NygGaVLsRlAJM2Sqil97C9KIazbWp/rfYKINq9LKivtYKlQhduvDPbdg4vw4Jgvj3NyXyAwTB4kPdN6F6dkZZPJZ7n9ZZGeSe8rNHsfCySdw+NwB9DRtKGIFxlvW0v8P9z7Itl/9i0995f7SgSMvfKpQyfXZi2UxSKZ5vHwGf/fEeWzviODs9BLssAJ/gx9+wqCLRDqoZMZCVhC5GQtre7uwaJ0nx0aRKAUgZQJDMumi2yKJqxS/zxsamU5FBtdI08Gb/WIITw8/gT+45bPIzJ+F6RfRVOqggChHpHuwKjwObPB+ITIWaUK8u6cHp2eHiei23UIAZ5WERamZpqqV1/xLl2jY/nP7tafO/NVan4+OKYgYPP4MKqcO4fn0EqL9AfpdDJokUqVyGs8+cxrDUo6IGq0awbPFzKcpwPz5oSOItDZW1rduTmAFxluiwctHd8OOr21Zs/UzrfHO54sWA9mJOqQLmaDI5qm5NLIUYecJxUpN51GezRDDVAGFUjzF2Nm3nbhYGUkWXM3lUFzIQswXSMPMqjbxHJfp0jICH5ZdjZYlSmvmcrM4NXMEt7Tfhd09N6JUzLHNrZwSX1f7vePZRMkTKX3x3PdhzR+hc6ncZ7Ngq7+hl08qVdb0z75zN6YIbfJ423DAaM3byQ2ySMdThnyYgqvv6/OoEN8dotSPMWqM756j4Pup9BzCZLUYAcFoMYZ7M9ZJ8UuwCJoNB6KZsK91Disw3nIBM3O98533PLZz846PrV+95euiGkwmyUxVigzwMFgIAz+xTwJFy3kCPTKU52bnkzg/fhQvDz2G46MvQYv4WJcXlMlvzqdMZBnM7wVH3lpk26vWEKo5rrdGmXXMeW30J2gsncMaWafPeI0fZ5q13NehEO0qCfHY8eN4bHAIPpkAFcpbI2oUbcFm3q5JsBRxId1+b0nCAPA5gQn51MIL78hUUgM+1ccj8lgnsVDhAAWTlAmoNnI5izd9Mwi2lOm3BMIyClmdrwhh7oK7FcNpKRUJNi+KopjECoxfyq4rD+x4gKE+579if+WB9HeHvnZ46OBHxqYvvKdcKreIhaLqU0scn2YNQm1Z4amDQWzLuUQG1qLJa7dUv0JAhwQxokIXrKpgHb8p8Lps5j8Fp5kGzzltN/WRBBmz+RkcfvmbiOYUDE4sEbOkcT/Nz2MuAzpc0z+hkYZRcN4gOrVZjWozIW0BQtE2473r7xkwc6VishNnWNHD0xN9O4dTxz4jKkZrMSWTpq9CRUljZmIGXT0+5JPEehlsC0aKIyby0EirG4iImE2W4GsVUaLYIhwKoZRz0rnWePtQZ2dnASswfqnb6jwgcEG/9KMDf37ipcHTP744NXx7Ort4Uz6f3VRMFVUlUyIoUnW6wRKoYPk07lZNyh+zaQrXFNL6sA9O4Gyj2rbD02RmuZkvFe1a+atbcFyhQO0p4qxTMwu4SGbXq+2q9u5YnhfbbLmMs4yUVYuIFOk205Xa3b8RG8vrCIDJD7V1bn3CwmH/ty/8510HJh/9k5ge2zlVmBYiFD+spdToidNPUSagIUg+//yFAqLxEJ3HxCJlC5H2CNoDrRiVSMChMtaIGzCRGsf4ZJKlgnbU1ziIFRr/Kvsm7b3xD7N0UZ/4x5/se+HQxROdJID3LKWXbplLTF27lFpstjNFusAsbybzpjndYCUSiE58ryXztmkkSIunGF6J66WmuqaNnC3k2RNxsVGiLdvDEGYNpygAqFZYLjfpXmsCTjmyLrk0caK5k2hItOEbg4No6F5VXL+4/x0vzf7wvuHpY/dMzSTW7Qq+Ezsa9qCN8teDB48gQ5N12/YWTJ9f4jFG31UBJMeTBMlSXBInjrwUQE/rADZ39+HksWEsFOdQyZsIRWJZihuOYoXGv9rGWIJTqJxxb0MP2w9/MXg003Vx7PzNZ8ePXzudmLx6KbPUVSyUo2alFBRYDNIcoKBZdaJa0/Gbgl1jiDjXyxrASMtMtAdNsnjGtp1tY3lvaJcztpxVDPzbeL7YRBUE4RQymf3HzyzgxanvI9nsQ0suf+Nfv/Sfnp2fXwwJusrbEp9IvIrflO+ERXTmhew5bNgQw8XBRSwsVDCwtQVmKo+xkSziPXGIxH2XJ8/jd3fejb9/4QgOjL6IliYfh1SbIvHhqBo7hRUaV8zOZ/cJvERljG7f2r//iw8bN0Rbz144uHp6abI/lUmtn8/P3VcU0j1eduQ05nYCJIHVaVo1YNnxp8AlDRY8U+wJzq6tU+ITBsustJcbu+diyp4MB1Ei/x/xSSBrEyZrzPcyZpMjNVXEVCqJxyYeQSQSgRYukXCLlOfa6N/UiDAFWSdeW4RCFGdHtw/jh2ZhpRP4eek7+PnQFJnsAMo5ky11NYNa9Pg7tl43jxUaV+TWdnfe+e9YnDzObqxK4sTcLv/f7f/iqhNjB3t4WTWlIIrF4EmZsFsVXaFWTFZm3IDL3XLHrKVLTqRs83W9VWLBxa29/Q5tb+aYzgGcaPCayTDigrTUT3ApKyEwycwuTZUp6q1ApVihgVKeliY/xglDTy5OEfxK2HXAj43b4xD0Ck6/TOmSJGHLhlaAsL25WcIwumPYn5yHQC6IlRrlc/SbNDXd3bzuwMyZQgYrNN7yNOlyB4tSt7a9Oy/JAuNcuCntj/egwd9EUGaFfF47utR2vujNq8KwvAgby6NjOH7bex6vE77nh4HaY49StKrr051JQd+kgbSxsz2I1kaKttMVjJ9J4eL5POEVPvSTIDdujaAj24HRwzqKkojrb1iHLeJGDB1OoHVVI+INBKhQft/YGoBOwtVNgmhDnac++M4PPrNSBXds1MXmlGxYNuuJIfCdy/g+wgTmX0csRNiSiWm64Gqt4PpnL0Vy82D3LieaeFhOj2Ub1ZUPy/hgLBM2vAniGW9XyS3dwtJ0kRfRsdIt1msrFAugNaoSuUGgVCaPU2eSWBOO4F2bb8ZF/znc0XQbHnniKVgRC80xIlMGE5DpYImw6zyBP+wr7N7yroc3brxxEis46kbAdHENyy13nUnNYP/Rn+H65i245ar1+E5pZlkVhlMRyctzqjgzLiEU4EbXHnlguc+zv7wTrikui6iX+2bnHGwdlhSQ0dIZIJ8cpLSsDJ3Am8xCklOaxYqAcBNF6+159Iej2NP5Phw+Mozh/AX0DgQxczbBV3k0t1HAuETZASFn/R3rRm676VceFnizkpUbdSNgSZLLvJURz2spXVIs/GziFYxNHYNOvLFAKZDlUoA88rUsl7S3uWnmUbfh0IVc8Kxiw6xpN6/ZovMG5SCdo+hlSnx4ZAQPuglU8fvYjVKttIC43omfnn4ebdFOdDT2Q+lZRFOLBoU+fHJoBhem96N1YQN+coow5gYiU85S2qRTXt3mw/rQWkwU55Ep60vb1l7/+e1rb17ACo+6EXBZr+iMAuT1ymwHFEpztGAQ58j3NpMwVc7KOCkO70Tr9mHjaBV3nrVct7q3MFDNl026se4BXcE2jOWHalyxe0yNL7aRTuiYGS2iKRbG9g2d2H31bVgTb8R46ThFxzrmzuQo2CqjXBbxgn8JQ4mXURENFGZpohFh0RBXsSGyEU1aDE/PHClvGXjH97Z1btiPt2DUjYDThYTudLK13ZX7DhDhI0CEQR+sCznXTsBd+un6YtNt3cT+Ojx/dXUD2yaghSDDtDnJX+uPEsRYyjjrxV0Uq4ZROzk3q8Zga4Q7+3xopAOvb7UxU16N7x9+lLcm1sv0fTQiDJqiaCe82SyUMLmQJ7KBInHCpgN+Ey0WkfptV+FbLz1Kk6Tn8J5rbvvrvXt/bwn4BFZ6XLECZgD+CEZU0gN7EzbpH/7yzaZfC7OlIVXzaduez3XVi5thp480K5L3NK6aOjHe1dVklgeXzCK6tS1YUAtIKymsi6/GU8OPw9/E1hZXUIvMakEX99kFA0sEWqSIOPinM4/iOLEfRpA0s7EBbQ0KoXAEjeZLSI9lUCjQJFPoNTLbNhEVVjKOvbfcjqdO/xxC0D+y79/+0R9uWbflAt6aDg5XtAZLWExvkvRk/8nyuHl13zX9yYUJjM3PYWThLFSWo7KjvPYL1UBKcJo5m65g3JDl0notpxiOEfP5ch5bYlshWzN0k5Ar5xCwWb3b6/Bp1D6nRIIVdAUiQahHyZE3dAURDMj8w/JzGSwSNcgsiOIjYKSJtWwyiVDIwyAo8t2b+pDLzqEx1Gbvufb2xZZIeIMhCyznz+MtGFeygE2L0kvoBqN9Nvf4mld1Boh1UlM4Y9jVtUNe8lpjl+D6YrtKplsCLs1zl6VFE9kJ/ErrZqzufAcOD71KRoDVoDhwKNz3WdVqDuc+258iEpN48KaznUgJ4FhMsEZPROmTedZCfoquybwThVTMFmlCkBZTLtwXENBRPoNiwkpfu373j1taOr9dELInho/PJzr31Oo6V3JcsQJ2sepF9/byh/5yd+/0xaEtjOZjRXa24dY3mw7+zP2tyyx42mq7eDX/j1VmUPpjGk4ebPNOaCLmCgs4N38Wd0SDOJA/79ROGbXZYFdRL7g5so0y4c1zxAqx5YpMizXSVFZUqKqEb5NGl4tlpJJst3GBt1CWFIF8u2Fkhfh5Mb715b72Nd+LdO9+8p179rzl7RDrJw+mq5kXbb5g2ydWIYwa7uyEuzWBuFF1FZZ082TLXQDGmsoyQVuihFPTr6I/MYj5hTSRtkJ1pwAI1iVCdgrm6V9RpIDJRyyX6GxdyyqfizqyWabRXj8Q1k3LoAllQtXC081t7Y9t3XjNP63e865De666Lwf8JX4Zo24ErIiqxcpvvFyYC9Zdf2ItQ6+4D7btKplvmV55j1g1t83+BlRYaZBVgkppy2S5gAdPzxCdGEA0FHEnhpNIeQvU2LBdV6CKxC8RmlYgrxnxhZGs5CETjcloTZXytUq5RCkS7HhDy2J7c+9P/cHwP21fc/XLv3v/n6X+WPjqW2KK/7lRPwKWJMPLW/lwNapaj7WcQvReJ4kG5ADPgyusNwTBmqxmanPnVXh17KCzrpidj8xoMRbh5TV8DbGLdNlWNSKDt7s4+8P7i1RsdDZ0Ik4sU2ZukC9Ctw2xRMnQXFtL3/BA/+qnb9r57h+87+YHRhx381Pgg/ilj7oRsChKptu2uQpWcG32AqBlHK7HKtl8b6YKblq7GwenDhI8mEVHrBcx0uB8pYSg2ziVmVSFFRXItb0Qq6bZAw7t2k2UDKIKTYq+Kd5u7CkrfpXiY3FU0QL7V3Wve2H1xo2D0nTr3Pt3M9Lgt/GvOIT68cEi603Dl/mIXqQMwVUwF2cWmI/1WCCDryFCppBFqVDEeza8G/vPfwu3r9uO5HSefKVO75OqGn/J/gxs2LVOeNXqDnfyNITb51f39b/W39Y81L1q65m1pjktqdb02i1bRnZ03r0itVQrNepGwDJUa3leCi8d8oIs06qZa5fcZ6+xBWi/GH4Jn+j6HXxox2+hR+3HQ8d+DLNiuqv4RdeXe+dEtVjAFmuRtO2afAZ1bN2468t/+fvf/Jzzpn/ElTyueD7YG9WNz0zP73r0HqrIlrfO1ym+s6r5MFvR8Mzxx3FjKIoGYwELqUlUm3XYTtrkjFpVZS3xrUq42pNasMX/aRvDK2XUjw+WZMtdVrYM+IcLcniFdcsAD6t2Y+2XxhMXcfyFh3hR+lJm2uljadf8Ldz54wVoy5Gsatgr8I0/bFb1WS+jjvJgwduRDryyw2ll567t8dgeN0Uyl9VkWdwIoyDL+Ie5aSQXKkgKBJYoQs1fc813fCzPc71JtFzCnOCw+ASQ3mTjkCt11I+J5rsgeUFtraGZ5W2PY9m1GixuynFJ/spNa0MQBt0USaj1kbZrYIiwrIyH/Q2qwSr06R3KYBACSf5/Aa/0kBTye6ILVbk3tpiabQfA9g32Fn1X2wBfkr86OS1lQVCX7evgmXqv4M52AzQWfLEtCPrjfTCYTa8GdyyatlhLxbrYcYWNuhEwXVddpHCXt1RwI2fWlKw92oZN7VchqkZ5kxPL6/ds11Y7WG7K4/lt0d0Cr7boTKhtqcOKcCl77I53I+qPUYCmw20X7xwvSJYoiivSZvCXMepGwIZFebAoehA0/0chQbA9H7Z1bUGAyHunatItuHPLddiq+oDiduHhgnfMu+gWDdQiZM8X21gTGUBvYy+KlRyvHBFcK8AMO8GldsXQ6yaKrh8TLfLAxq615XfACYM1NtVTyFUKfC9Ehi2zTSmZyFgzk554F3GvMd7A1FxWK+1UdtRW7bPB0uFSpYw10V6sb16HxcwS3w3Grn6g4/3ZTmyok1E3AhYNy7Z0Z2PiKolPf3P5HJ4/8hhBj2n+RHdDO7b1bCPivoCAFsB1/duxmHW2bPcCL09zncZoHu7sCJhNgvncDHqkBQhGprovhPMWzkQJtinbqJNRNwKWlfhIyN96hNfSLIMT80THncyVYcJJdcYTk9jcsRYbu7egM9qBBmJ7EukkReFCrcuZq43VvYhRO58mKTi3cApnTz0Oo5TltVxemiQKcqUp3HMk4I+NoE5G3Qh4V/OmIxv7r/3vxaI5VyoXq9ExC5YUlQEPzvayTHMPDL6Iuze+F+/axDbTWKJI2FjW2a5G/6H2VDWXZtvnLdHx3xyZw3iuwCNv5r9LRAGWSubc7qtv/Yv3XrPzIOpk1I2A2XolVfQfX9u1+dHGSMtB2xKzXud3VIvcLUqDZJyaOo+54SdxfbCIsYmjfEdvwYU5vc2wPAjSXYIGwcuF2Oko0S1pqmu6TQq0lFx7vOfQpp6djwd8kWNr1txZF9vasVFHSBbw+Y9+afTE3FN/eOTk6VWPPvPtPz4/NX4XpU6GaZiq7WLFTFA+nx+vjBxCbvoUhucyfAcWPuxqoFQzzba7dNR7jk15t4BPlJSybtjq2u7Vz/+b2z71f9x5ww0jn/vcl68otuh/NupKwG6dVv7Qoa+cOd698W9j0Z6DTaFoYnL2zPsnF0Z254umVCyVmcbhQiiEs/M5ZA2Bl85Y7mJxvv8zr5M2yKQrTk013YqUbhGJb9uijz1rru3d+sLG/q0/IA65MR6LH73zhr2n6fPrJj3yBm8gIni7RtXp+OYTX9rxnSe+/vlwJL6wa/Puw0fPHNkyPvvi/SQ3NZeTE5oUWzKRbopF7HhJN5AtyEsBf3xRENPxgN9ozKTNytqeXQ9tXb/z5JFzL2wrFlPN99/6+//1fbd9qG587ZsNNl3fFgI+dOiQMpE91yko/sTeG/dmT4y92PDlb/+f/y2VS7UNdG55dKBn7enXjr90zezSiQcYi9jWtOUru7becHBifnjThakT9/jk2Nxv7P0P/3XXxl1Lr776k0hGMBpv33k3W+VXdxr7usEF7O1w8LYaT778ZEOmPKM2o29xz549BmtUduqVA5tE0xI23nDzqTtW31F57rnnpALGmjQzqt96694l1Of4l5ZECP8PAPgFhqae3ywAAAAASUVORK5CYII='), 'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', 'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', 'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', 'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', 0, 'test', '{" 春江潮水连海平": " 海上明月共潮生"}', 'm', 'm,xl', 3, 127, 0, 0); -INSERT INTO test.TEST_DATASET VALUES (6, 0, 32767, 1, 65535, 8388607, 1, 2147483647, 3428724653, 1, 9223372036854775807, 10.5, 0, 10.5, 0.188, 1700000.01, '2021-01-01', '2021-01-01', '2013-09-06T10:10:02', '2013-09-06T10:10:02', '2022-08-09T10:17:16.161342Z', '00:00:00', '00:00:00', b'1000001', '99', '!" #$ %& \'()*+,-./:;<=>?\@[\]^_\`{|}~', -0 xfffd, -'тест', -'Airbyte', -'!"#$%&\'()*+, --./:; - -<=>? \@ [ \ ] ^_\ ` { | } ~ ', 0xfffd, ' тест', ' Airbyte', ' Airbyte', 127, ' Airbyte', ' Airbyte', ' Airbyte', ' Airbyte', ' Airbyte', FROM_BASE64(' iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAYAAAA5ZDbSAAAACXBIWXMAACE4AAAhOAFFljFgAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAEIPSURBVHgB7b0JnFxXeSf6v3vtVV29791q7bIkS8iy5U3IC2DHNnIAJ2MYQl4AZ4HJQB6TmcybQQz5ZfHkDXmQkEcCgQDBwWb1IrDBu4wX7Vu31GpJve / Vta93e985996qlu1k3vzUJiq / d + xS13LrVtX9zrf9 / 9 / 5 jmDbtgTAQl2Mzwn83zc8vfzBPn777Gc / az / y8qd9iaAULvoSoQYEVdGW1FLFtCuo6AFR0EoFcWkhX1xoX6uK5YnSr5fE4v7PXPPI3Oc + B + ENH / 1 Z79z / a + Oz / 8 KjX8IQBBKwQMPG22Q8e / Hrvuni + e6Z / MjWRD6xOVcsblRDaJMEKeRXA2pZL6NoFso + ySc3CO1TF3MjL / cG + 62 oHJCazYYH77v + C0W8TQbJVqxbAbvfm9 / 1 nvv2kf / cO5ub + r2hpeO3SIF8d3bJipiirQX8klAsmYhFJdJdoFQxIKoG + qUd9lx5utTh7zRHkxdHFb / wj / F4 / JsP3vizabwNRl0L + OsX9 / mkhH63rAVeKKbThaHcqVv8duDP5tPT61PSFIKKhsSChfYOGZm0iWIZdF9EuWwjlbIQiZsIlltwXWQt5spFfH / weciajcbG8NnmePw / xiK + px + 88 aUs6ngwAYuo0 / GRvn1l0YRhl / MfP7z48mdGps9 + KSI1rNfJw8ZCKpKLJjRVhKaJKOVtiORWRUGERDejIsCqkDbLSxg ++ QouXDyE5rYgZNOH5FJh3cTs9JfG5xY +/ fs / v7YVdT7qVsBkne2AobxUKVU + nEjPf6ot3NbdqDXBktIwSFuNiohgQIRtAqYuQBIFLmSZ5rRgC6gUBWhBCSdVHRdME9GwhEhMhmgpqJTQNbew9AcLudQff / LcJzXU77DrVsD / 49 RvxZ9KPfFHo3Pj / bd0vyd0 + 8 CdmEmPQdJ0FAqOIMn3ks8VINB9SWIazAQtck02dHqORB5t89F7NHosoKlJhk + TIQsyFFMNT4zNfzRx / Mm /+ E8 / v7URdTrqUsD7Satmpi7 + 2 sTs5Icmkxel7koRPUYOaWMMgqTCIuExASuyCL3CfqTIBUui5pos0V / bEkCKS5OAjiWB6yWaFAppcViGYJL2B2Vogg9zi6n7p3ILv / bFc3fUpSbLqMPx2tjYuuml2Y9WimK8pCxg7MgzSPiDKHUWYCsKLNMm4Qpca5kQBf4fuGlmkbdIQrbovmGQgDUJqmLRRLDofQLCIYkHYYJoIxwRkMyUGtLZ1EeHRuQDdIoTqLNRdxr88MMfkJbKyX +/ mExu7wy3CLYUwvdm0vju2DiskEzaS8IzBKgq99P0GJegFlzQgiNsg46TScs1P2k03SffyzVaIW1nViBA51MFhVKs4rZ8qfzpD9gfkFBno + 4E PNPZuGEhO / 1e kBk1pQLWxq + CNtCI8NY4FEWGadiUHgASaTBlgKSpcCXK3i04Nxv8GJM0XaL /+ iK9dJzlmHOJRd5M4CIiShQ + OqdgyEgVU / dseq6wAXU26krAtr1PHE8Nvz + XL8RVUUPJKqKk69i16h0IR8kcWxKa1Q4IFvlV2RUqEzBJ2WaStmuoiM3vCCgZJTSHmtAR6kWhrPO4U1UF + IQgOoJ9kFUToqnSxKk0jGem3s8sCOpo1JWA /+ TFc + unc6N7YSiUz5IQpABOz59El7oKm1p2kHBU9Ac3U0RsgWX4lOg7grRdbSaNtZiwXZttsRSK / O5w + hRu7L4FQTFKQIhF + bOAgdha0mgy1z5HyyWTgJP8wr0nmzLrUUejbgS8b98 + cWppYpuulzuhUypDAZRBwtINHacWjmKTdguujl8Pnx1BhaBIFmBxSXKttbmwmW9m0bMjdGcCEAGBVDmBUjmHa9puQJne61f9GGhch / nkPFTZxyNvwST / blodk + mFbey7oE5G3XzR7l8vBHPl9LWkdTEWGbNImEfIZI5Hc8MYnziNO / x90IqTBG5QFOz6WNs1ylybBfD3sKcsemzQcRbxaJrow7GZw9gavwZhqREdsQ60BtuRyCTJUkg83bINiVIOMVYs5q7133YkiDoZdZMmnZsYaa6US9vMsihblN4ITMAWS38oy6WI + fjCY4icUTFMM8Ai6TJBsuNIhnRjYha4MJnkTQqoVMpxo4qfhJyFT1YxsjiM + cQc3tX + a7A1C + n5DArFHILwQaUMuJRh75FlA8bVk5lcC52pLnDqutHgXCbZXjb1XstyzC4LjG2XxVboQTHmw / esLA6WS8uDZRK0ibZQuxNvuT7ZMA2sb7qK3qdApwnBoA9m6l8ZewUdUhu2aHHMpYd5rsysgMzUgO6LFICZhtGXz6XbUSejbgRs2 + Y6EkKzaYluLuv6UvoFpMykxZS79kYgNwYpRRId6dKtTMltR6iHTG4XSLdJmw00BVqxunE9JrMTXLgEZJGflXBudhCzg99A6eLjkDPDzEzwScRSLvYZLFc2TLPJFsy6CbTqRsBls7LVNHSfTZmMIpJKSY6PZZrMI2YBDgxJwZWkOpPAoNdFst8XE6PY0bKH + 1 pm1vf03Yn5zAwFVhUedLGZwHLonF3AM + dO4NDRQxim1yVJ4lrMcWz6DF1nGm35KqaxBXUy6kPAJEfdNPqYUrK8tyfWSxBjkAdKXLKuNnMTDF6nwn8Ze45FyfPZWQSFCK5qvh5doTVYE9mIwZlBsFya5cfMk8s0YRSfgsG4D8 + 1 KFiKyPziML8tkAYrCglXdxLpimH0A29S1nMFjroQ8Bd / 8 km1WMr1MhDCpCuuyQG0 + LsoWrb5ZWYC5RbZFbJ36W0X2SgSRHVubhC7YjtxT +/ dWMokMM00lCyB5fpzhmApqgR / RIHcqkH1Oabb8fekxbITgTONLxvlno88 + 5 G6IB / qQ4NDoUjBKLUw2SmChmRhAX2BDRQQy9w3Mg00bU / ADqEgeCgWDYmkc3HmWRhDj6Bp9hiOjnyPgiudR + B2VYAi97UsOmePWZ7tBHJOxCYrDkHB + OWyXm5pj + bDqINRF2mSikozYUlRJpKyUUHOSCKuNhEs2YnpwggJxVcNqrjGcWBDqGoz86Epo4zXBk + iOTyMEQq0JGaTBds9hgRMAhQMoYpuitIy00 // kTvmxzKSgiLpSChXaabDFnCFj7oQ8FIl0RhVor5NTVuRD5tYKJ9HhXDoTS3bcHFkiI7wuWiVIwzBkQ3XalYQzIj + ok / GqxoFU5KBBEGQErFF / D2We7zo5lZM + 1 lULdUidcudKJ6ACSDxpXKZZtTBqAsBL + Tn4xO5cbFIZMA1TTfhzoE70YgZ9GpLeIHSJoNBjlYtL7axrIZQcLRSIh8rxxT6xaStCzoHQNiRpu0d5ppkOKZekpY9ZjZBqPl327LEpXKmAXUw6kLAAdUfYFUYS6UkHh16FBdmT2EHZbVILRBAYTooFWpWmmue4DJGEr0qOVEX11HRI / 3 dZ5gph1DVevYUO5fInbtHPzkns90PsemOYhNIXQejLoIsyxRjzExKFnGzRAnO2GN4sjSJR5ZyKBHMJLjpkWXVTK5DIjkskjMurQx2BOpMBCZiLtDqrOAYB2pxms35YnZjE8Qg9Ktimqu + cujjCq7wURcaXCBzKAquFgqsWkOBSTpdIdpQEfQqW2QvW4DD7jv + 2 PGp3l + XPXQKAfhxbu4MR6jV2eHhnQDHrttCHUgpCRSsRbRF2jHQMBCbyQ5f8fXk9aDBQkUwNEdKIv / GAg + AGU8LBl9hWeL7etlUzS7XVNHRbp5Y0R0H1nYnjlQ9hYedVKtAdIq6G / wxbGjehLAvirvXvx8lwyjue + dzJq7wseICvmhf9Nk1u3jZ42H7YdHUjbBnUr2aKsffuigF4Aq3pn38K7D6ZyIRdNtwyu74oRbPZdc3beC + lP3HymqdhFpAdY2Hd0dwrMBsbg6bWrfhroH7UdEtHJl9LbLvuXde8dUdKy7gzNx4 + 9 DMgb2zs7MrwpkOPvKIVDFLmuBKlftVuKAGP6L2L / fBtlDVPpHUcnXDGvRFVpGiqyBRM7IAmWIWzYFObG / bRdBnCc7U8KJm582iW8fF4zRCvOZz82jLDOKGiB8 / Hf4R + 3 zf6YX5K94CrvgX1FuDk5VysUUXFt9DmqwNzTzbh8sY8VCbQEGN5GivUI2VLGuZOYaHYqEW + dLxBmnuTHYGcV8jbu29Czd23IMmfw8v1TkzPYRb +/ YiojVz + FN4U5MuVIMxdufw0PN44vi3sFCcpbRMltpClRWzVG / VWPEga4ewQ3 / 21 LeeVqF8NFkeb64oha0 / vLDv2YpVqJALtSq6oKtiMKWa2tixdcXZfcK + f3Ft8pI / KxAEfUm0aguUpkgqYmoIGXuharMFr0RHsFxEi3Bos4ij0wcxlj6DXe034v6BTxAmPYXB6aPoJvp + V + MAThunavCml / l6YbQ7p1RNxpOk7VpmETalXoZtKll / L706git5rHwUTdfm7x / 6 Qk + j1LznzvZd1xRDF4TX8qd + m / kt5uaIiaHgyG / 4 NP98KBv74dMXvvZoj9n +/ Jo1d5bf7HQRLU9MEs0JTvoyzJnyXpJ4WI0gGG7C4tIkCSPgfHS12Aq1AmgeDkhIG2k8v / Q9nFh8Adc27sVdLZthj / 8 Y15dnMEHRVp4Fa2xiCF7k7dw80ISHckEJop + AEp2lSoayOJy94k30SgtY + OA3tl87m57 + qwVpdoM2fR5NQRVGj48D + xXD5pFwNluRm + PrOnQ787GF0Gg4mt / 67 D93wsxiUTBtQ2SXuSXYDMUoUgS7QLRfFLIVgkcecUiRf4NloIbgEg / 0 bpmwx4ZwjFKuLL554u / xC6IP90Z0zJEACx0qLllnadeAjyoAIgq10mqR5eamhM4rfxnxigr4o9 + 5 dvP56bE / t0VjQ0tzBBm / QsSAjLCkcD5VrlgMtkdFLWGV0AJVGVAPzO9 / r92p / 4 je / sM3Oye7hJZg8fA2S8K5rucmjFpH4FPCEMqaK1yhFk3Yy6BKHmQT + S + 6 kTIdFgz64fNZGM5l8ZWszc1tv + ScR / QyLvcvnxySd39Znizwgvor3v + ysSIm5vGxLzf8 + dO / tXNycfqPBVG / qa2hCbGoD6YgIxLT3HSGKAEf4cYkq4bGIE6ffhzHzvwY87Pp6NHFn3 /+ W2f + 4 zVvll7dtmqHqEk + mb2SLmfw3MhzuLX5HtxMOSmMPBfgcuzZ9vJX70zM5FYF5kCQql + FP6DBChH3G9Uga5JTICDWrghHubx0a1ng5f0WBn5XUtYVL + QVEfAaeQNRqdrnTal4y0DLgNAajfGVBSZf + 0 NAASH6rLJRJFOpE8rvJ + 51 oknBfMSEavqQSWdXn0sd / rUfn30w9Ppzx + 3 OoCr5Gi2KdFmpDsOjXzz9AwgXfoEyYdIQnfjLsm039629t / awJgfmV2Ui9hW26IwYJo1ubFVhNUpnuDbDmimt6gp3UWJlOni1wIrvZLRH2vgicmsFc / 23 cqyIgGPBrmhMiV + 3 rm1tcFvbtcjbCU7GM7JcIBPIAizdsHiNlE73TRJyIKJBIsiRr8DPUXBaTL77TPrkqtef26eEpJgck1kNM3sfu / AT1jweunAaJ1IZXlEpkm31SwGaPAZ / TxWd4jehWoXJgQxWX8VuLsHPiH5Pwz1wg93ViXdeHVuPgBTk582Xc9i9 + ha0R3sIONEdjqIOxmUL + OFT + 9 S / eeazv7060Bv5t2s + hemlObqA7AI59S5suUhFN2GQgCvkg8t04xE1aTOLqH1 + CeW8gEwhvcGolO72znt89sngoUOHlFCwRWj2tQpMg5kHZ2AGNAWzTUGUaZLwGilTR2ewGz0RuvhW2Y2mXR63KgbBBTOc6JgJWZBc4VYPcScGTZiSVUKpZGB7 + 7 XIlNK4pnM3dnTdhKHFk65LsKDGxLc / Fn1samjt0Mih22IzRzAxehhnFk8TvRfgzU4c8IFMoB3ktF6ZaTIJSndXHlR0MtsszKPwt1wypYyRvpmgSYn5YlnU1kpti / dKsBtjvmZLslWHzXENoyo6VZReffTw0llsbd / GiQCDBC5QdNSgNjoZk0v91aJq1Eh + Nx1iEVY1kILz3ERiFFuar8XG6A24a9XH8NS5HyNFLkKURNRHiHWZAmZrdC6On7tmdGGh96vP / ACPHH8IBsrcRDJhssGsZrPWwbWPpUmsMpGZW6YFTJN5XM0WalNumcovbtYuGk2s6082XThfrKTXpSrT / 6 VN8XVq0HgO7Gmkg0O4 + DH9jJJexrnFs7htzR0kMwqixCBWRda7KbEbJS0TilCNlr1zOPcdxpBZGBnT6Sn00ON / t + 2 jWMzO4eDkS + QiFO8LWJjBFT8uS8DlG481LCYTewqmFTvZJmIpJIIZLbZyvlJxsMNsoYSo1EyBCUXTlDKxSoqKZXO6jvtkw + mAYxkSMuVMy3z6NF + De92aOzNlQf3S4viB2eTx73XLyTxdfKlamuMhTB6eoZJQT06fRClfxK9f9RF0 + Tbwmi2LJkWNRbKrsKPnbZ2Hzpn4Kgb6T2PltDSDysUF6GPfgaK / ip9d + BvKCpw2EDbnj2H6G6S3t4men5lrKJX11UwB / ORLmallmsXwDNNwNJhepwsloD + 0 BT3 + DfCCJdv1p0zIHKFik0KviFk90eKdf0 // vSndCP7t4UThUIJsg1QjjuBppHeFOfdLQd2z559GuxjBPZ07IOpJdyWhXaX + ariowLngZl8zBXIatzosmOr291OUH + ATwwj58Mj5YXz70MO4kBtjq / 2 rkbloi3XR / vGyBJwspZpK5UoHC1iclXu2uyjMFRwYNElmlczb3ubdmEkvIEAX30eRKTuWvcbWBrHByAP2WDClSzraDLZHz463 + gd1f43BYwIT3FjZkZ3TA4uZ1bnSIl45 / U00TByAMf8K / 4 lWtV5LqL6HSYkR + UE5hu7gGpTMAiFjGjFPa5EsLnFcWw1IOOgT8Hw5D4NpL / fj3moKQc / N + q54IV9ekGVgTblstPAVALazes9rfGLx5ic2D3ZGp4 / hyRcexFh2BG2 + XrT6u1CgC9oYaEV / cC2Z7IoDNVqsSL1wSb3x6cGHmboY7Ly1paBwIuplnC0DMFgts0a56mulBfz1mefxQi7JAzGvEseDGkWPVKAn54jn7fddw9cO9wZX0 / t9yJl5nnqxq6MQOKNqzn37Eo8u6KE29Yo30ZcFVZoVq4fSH02hC8CnsuWu27W9khmBR5yjGqVBUoHkRB7ODCCqBdCkdWF9fBfOFA6wJkduyY1NOLN + yYqBhlV + O380b1lV0NkhFRzuvloS6UbDIq / ysIj5Od / sp1SHXkpZ1fdU0yfHk3PAIl1KQM8b2BrZjcZoB1GBY5DJEjh + flm1CHAJQiba / x / IgyuG3kQCFllkyYANy3KCGNaOyAuA2D9aQIE / EmAr5MkEG1gX2kw + 8 jdwnqLeheI8xwi9VQkk5Uu + U0c2bEuiaGGZBrp0L5ZXc / DKSfchy2J8hFZJYg1mdKBGp85ZJexZoaCMN2IRTJxPnsD7V / 8 bbO7agvE0 + VpZdX + LXYviPKDE + 3 xJNBuS / rd5HixIDQzAYELtDnRWQQS + 4 Nqu5TPsOXbRGbLVlruAzYQpH55 + BUfmjkAyFUfjPc0Q5Ev82saFZpo6km55BtqqMUVerToP3VlttItSCV5OC6fo3XJ1lrdVog / bFL + Kt2ZgX1HTNFw0BoHCGCLCBRQqC9yiwJtwQg0NWz4kQdKTDave3j6YctqoSBchXy4gphHB4I86F5JrpF2rsoDjB9lykSOJaTx0 + Bs4nHoRiqw5DnGZdjIjvvwzBgc32Yqilt2X + bJR55y2m7 + 6 HtEFLoRlWkukPIJKCKsa + ilC1zmypQpBtAS6mK / nFKIsyTBUA8eP / l8YI / LDZOtTq6sU3S / huoZqWY / NQZbypsFH3uYabEPjESxd1FyhiN74KjSq7WjUWuni6vAyVWeJCAUsBD9Nh2UcDDpBEfOBPAiyHY0EX4urXkL8E5hi2QZK / Bq7FB4b1eJ270CpptHeMWR / sZCb50tcOiKrkNUz6PVTIEVCNuxKFfvQiGx4Qs / iH8ankePrRWvOVvQQL3cqVX86hQv79l35nfIvS8CO4RXgI02cWJjA1qZr8O6 + XydSvcBfXw4F83iIhOALEMpEPDE3oyJcSg7uMn1W86zpb / gcRTCWrQp1nvOiYaH2bTiR4LoDjx1ine8OT7yK96 +/ n9dj7Wy7hcxwmtdhcTfCIE / 6 FmY8iArlvZIkumnYcqRMcBml2vel8xuog3FZAib9sxwxSxSx5hDPXUSvlECimKYrITlNT + BWOdn2JasJ + PAqF5flt6IgvaHWWJFEY3nQ5pzLNcvLNM07DReO + 8 tYADieGsNschQf6f8QOtUGzOVnl388PMrXYZk8Hy46 / lxwKyy563E + j88LqT4EfFlpkiJJJQ / mkyg1OXD85xhJqDCDPt7eiKU9kofzehdHWJZNVoXNLqQTPcmi + gYNVmzV4GbeM71VYt4Ngqp0n / u6Vz / tCpmBoQdHH8ceeSd8kWGkc8MsmKue37aWR + ZOqscE2 + 7 vwLQ + RS9W6LfK2NS + DhfypzlWLdnS21 / AkqSkuBmkCySTf32mXEIzUX8NsQAYFM04YElwyH6 + ms + NUBhcKTBOEXZ1lZ9H5SiC / EYNVuU8 / zyBdbdja5Ec0yC6rBC3EIKDEnsm23YlJikMHxcwhxweO / szIvkpDjAplJOdz / fMh2OURRelEnknnpARxobmzTiTeQ13rPkATl64iFKlxIv + FE3JoQ7GZZloikqzXFAkJUach0IKAqTJ3nWzDMcJx8gs8ooLi1UjMtLe7 + LKQhXBcpqGMi194zYDqqwU2PX3qRo6Ix1VYr9qol0 / KQrVKKuqzXz1PvlVmybGiRYNh + N + 6 PSdRXt5tYfgfgHvSZE3QJvJzGBrw424vv1OdKjrcWz6NW7y3eLLMupgXJaANVFNy0TVsN5VDLFiQrYMZ40lJx1IwBbRg / 3 RAQL0A7yFUaPWRnjvAAladxZTk3SDxB / LrskUX2dVvvjKJyOKrDQTRQG / 5 qcUpxmGbjglrZ4QmeKKtY47ooSqv3fWMjmdcjSfwrvpiLWlD9V1v3wRWjUkt3nbh6XSElrp + 927 ai9eHX0O8WCELWV1UDBRvCwT / fFDH1f + 9 MX73 / I1xpcl4EAgNCXLss6YI8FyfKRecYMR1jafNNswKgiJjWgL9iGuteCWgdtxLjnCu8uxC5st5rEq3ofuSA + XSskoX7LkJU7UQ2e4s7M13IqwFkHYF6kFbEBt9QFvmGVfgnR5QTYTMOuU46VPHt3oAVWOFaHvzzy9FxlaTqB18dg / 4 MzxL2CqMIT1TVsIvavwDvL5YrGCyxjtxoRfV + fv2HforgDewnGZZIM0LctKngcprPuNopB2ma6AWaWrwp / P59PY2rgL9679MMaS57CYT / GotzdCxAORD4ocIs3s4ILJVZbiy5t9fmjNlzKJYurAzo6dhF2vc0ykx + dWAQhUm7Gw + zLRet7aIsezwrXCQjWy915womKbs1veC + z7M8TL79ewv5TFI3ND2N51I4qVMipmhft0glf / lwTMtgT48on7GzwYXZAlSsXFVQHLirDH9ltUhnt5ebCMeb + ipkl / USkaaA41oyvah0Ipj4iPEKTYKueCpAdxY4MKozKPw7OH6GiCJ4luSpbmCZfegj1tN6CLtJNpzVJxseeuj911yer5dClXmkyOYysF2EpmhFdSem6WV0fZNUDFJ / vRH + 5 zGSo3WXbKw5xo2eWHqyYctedd5 + Iea3EQxmzUEGzqx1VNu3Bx6RyPvtl5NVX5f2WiWX / pBwdv2p7XjX9vSuX / 9 tdn3 / e // 83 Q +/ 8 g5rd / x6 / 5 rrXN4OYvvHzvhgeP3vOWtEe8rCi6s6VvcXJ2cjaTy / QZJR1LwhLuXv2reHbph9jafDXlnlMctpwmjvbxn34JrxKGIShB7t + YNpXtIn545oeIZU8hY + dJ7D7M56c2LxaG ++ n0p73PiQYj5umJI / jZ7CimkgaUtiDXUObnw0oELcEo5o0E96e95O81csKsvEdwF / 06E KNHNbo9tZwHVZPOA0IWaLF2w0zgpu0K2sa1zbchkU5gIT + HYEhx0j / 5 jYDM68cXT + 4 dOG6c + 8 RUYu5 / W9vUH6kQsjaTP0eZgIgcxREd4gCCdvQaUxT2R0T8F7wF47I0uD3WkVckdY61BzQqFvnTFOYWF8gUfxAD4QECGKZoBklIxTR8O6MjzcthHFSoQn6bbYgR8wfx8 / I4XqX3SoaMvJFrPz738tVs1y7vc3xSwDDp0SHypRMBCsjcWirmI1nX9y7ilJuJYy4bBgZi65AsLBGvqy4DVxxtFUWhSht63QAEYZnQeTRv8TSJlX + xGCKstGFTbDuOTb3Cg0bTaVlLiLn4Ly7 +/ pOhvY0L1sSfBYSmB5r90UhTZSPidAuKFGwW / PCZYaiZJFpnkq0XRk / cniol34u3YFyWgDsVf17zaaN019CLzg8 / M / oy3tPQQb6yiAwFUOUCCdIvI9QcYkutyT9aXEsqZOBYKqoS4C8oPviCGvQy74MRH0 + P3PniyCPVyo6QGK5Q3mqpdB7GPQNV94uyWSK8eQLv6bmXC7qdiIQ0Rb + M0 / Uap9ieM4YLny6r8HBycdb6HTz9alKbEZGilMMb5HNLuL5xHfzkbudLM9jRvQsbm65CSA3aiiz / sz74i / vv0LL5id / J6vP3qKWo // bGj6E / tJ20tZEmtEYgiYIGvw8JmixDxjmYcrZrMTWy7 / mJr + 7E Co / LEvB7byjmGyKNxwi2y7B11CqZxoSVxo9 + 8 iAOj30PPjJnuZwJq2wgEJSJwWFVFxbHfvn2CGQ22f5ERZocskLvJ9DfzEOaz0 // yk9G9 +/ 1 PicUjZdIq8zlvK5BEvLTxGhUGwldGiYTOoIHb / oIhMoc8lahinPzH7ksomajBm3Y5BY0xKVWvhBcJhexrfE6pAlqLVF6F03quEddQJs4gd +++ pMUL6zGVGKSRf5mQPWV3uya7LP3ifPx3N0Vcel3hVxYnSMq8vzIEWylQBOLh8HairMKUkIBUSSTra2KIhwKUwRvNL948Vt /+ vSFb / eyc6xUl4TLC7KEfdaq1u4LPk1K89ortmohJONvzs / hdCKPcEQhTaDUJ68TSMFyUY0CsArlkiwtEZEtEVrkIy0z6ceWTDREibojnqJUKEVHFk7 + hwdf + Mx29jmqJfMtNRhcyKJoizX9JgF3RztJm0Jc4EfG9yN74XuYHP0pPTZrDJUXTXtSXkbwsbsG5earQ5s5jdhLAmSNwtN6GgJd / DS5lVcPDuK1l36Cbz77f + O7xx4ma7HI0iRLfRPEjY3gL843Fc3sr8qG0mJVFErtAjiROoz9I /+ I00vD3M3rvPjf5pgBWwyg030fxSbT87NXjyV + cfc7R / q3fuHlT69Im6bLLnzvaF97MRaKTjPzVskZBCbQzw / 4 SKgmfBpr7SuhkDdgl8vY2L4JIbmbfmCWm2bNbuBUfJwmRb5AP1i0SMhkqgmYzBbSq185 /+ QX / uDxD7wjFozlKLCxGLq0rXsrN6UM0OhvHECeLcqmc82T8P786Kt4ZmHWhSHZqIZT7hCqgZMTd4sos51bjBxu6bob13behInUKFkimaNz5aAfX01l8c3EEI6nTzslRywFo3ua + uYCzliJfsr9r9OLvNslxwVkYqlm + 31 Yiiq8TJhBuIWSw2alycKx51S6FrpuRVOl + Y8HhcjtXZO7LivP9sZlCzg02j29rmfts6ago0yCFEi7fGEVubRJwQSBHA0 + 0 k7S2HwFF9NnsLFlBzY33g6RfOe2tp0olYLw + YmY1xQsLNIEobS / Ma7R8SKSmfTNJ0ZPPPzcyecfkE2lnC5mkCql8L6rf53y5m60B7uRKae5uVOCKiYb2HIWv9tn0vl + QvVfwWlPCCda9gAOFtEfnTuMW9vWYWtLBGdmT / E2wwy8UVjH2a4wLII3FQra1jb2c19NCJyhioE3FYCuV24ulko9hbzlnN8MkhFRuNYyQeZLNl ++ ky1YPC1LZQyQasDKBSlVvFoKon1tQA5P33fffSvSweeyBcy + yIaujc8HAj6jVKHZmClDDRLgQd8 + NUf5MJldgTXbzpr0Ywt48eJTiFNk + qtrfxMbmjagOdiGxWwBDSRYH5nf + cUyIU86WlpV3vSskC + sOjp68BOlrBFULA2nZwYp2hbxgdXvIdNdIQ2sQHDXovgUZ79Crw1wbRWEI3AGYdrLYGcPFCkYRQy99iWcO / 4 Q68nFD3KreTlmzjQ + 6 mtAM6FpLPgC + 2 Z + 35 ti0cVycaNhWJKui2Bb3cblTr5tbZldG93RXjZ52GM22YpMKUgMFxKj2Brbgk69VxwcO9WJFRorsrqwqaH / YFtj6wVW41xYqvDoOBgIQ8 + SOTN0vpIwVyRTxdYiUUT63ePfgZzNYHe8jFVKCamCQCS8jqaYSZFwL / x6D9KFPDra / IgEGEBSUYl + lC1D5MtSXjqzH82Jw6hMPUdmXawiWE4xnFBtV1htyGLV + GPwVRW1kkgme5ny0q8Pnsc3Tp5iWzJxgVqmA3swJqxBimNb + zuc1Rj0GyVBNMPWG2lNtnFXvlzq0 + mV / tB6skpRyGR67YpaXYBn8r2bTLJcvK6YMgebFx0uUcaRzD + P2cH9yvn5Y +/ ACo0VEfB9Ox5Idzf1PqQEZCOT01Eiv9XR0IrVLRswM5pANEK + y6cimdJBd + Enc / r1I3 + Prz / 5 V5hauICA7KMfZxMVR5PAN49NrRtwa9dvIJcidiooYMtAH2l4ADqBKXq2gtlSGn839CoeHSdMW2FrhWyOQ1dX4PPhthS + 5 FfW9kyCWzrrdIUXkGmJIhsLccLEEbBzY / sohewY9vS8kyxNgiNczETbfv8bBPyZp877C + V8O3vP8NwwtvvejR2hjVBIiKWSY6KLrGN9eBVNWgktvh4YJYEvxpNJ4w8sjOGhc4cwkRzdfGjq0Ipg1CsiYDY0NfTTxlDjxb72AVTSpFV0cVa1rMLSUgF2sYwIQX4lSg / KBR0NGmlGKIYfkf8ZpZncqlm8D + USWcd0sYjTC08SL5zA7133R1gXvAXv6n0fOprjaGqmqDSo8H0XJsN + JEMB + CWVbn63rKbK / AOvWwwOd1WClwPbbnWmkyuzrj3OYvVqC2HLbedP51kqJJHPTlHckOMlwYTOGZKovQGqXNM44NdNPSLYEjKFHF4Y / jGGDn6fXNUkp0otvjzHoHMY2NJwAyJWF1m2LCy + WRcRM + RDpKYQoVyp5n5fWxwrMFZMwNubNp5RFOXpdL5ovGvLXSTEVrRSGkMOGOn5HPyUGqkUTabJFwtl8k0hiqL9AWQrjGIkHDtI2svy6DRpE5nzQ3NPYDr1Ah64 / ldxe / 8 WpGaKSKUqlDcLWNfWwzeNNAW2SHuABOyDZS2rf6vSSB575Arcc8wOn1t7aNeowhq75LZiosg9ayQxPfhdaIU0vcabdhhhFii8bmjIRwnRCzFBUiKFpJ3G94lcmWGd9ixnvRZbBjuWGkNzhlK55Az5aZsv1mPfSSczrpB / K5XzkenUaBtWYKyYgH / z3n2pmzZf / 43 ZzMLZV44exG39m7AmCjKtDUiSX85PphBtUCD5fJhbMiAVC2j0U6KvEf6csciEVYiooFw4oCCbFTG / pOKxocfx3Cv / HefPfI3AjgKlXWFMzZegp6NEKGzggc + q6GqKrDM80KoSEJYnKMuBFj1 + kGmRbbsL36rFHG4xgnOzvD7SrO2EYfOemMxnfu21szg4lySolZlwUT9y + uwbKipLphjSbVNx9sG0WdUHAs0ESYZUvlaLCZLt48SqRb577Ac4ljgOTaC00HSWxQbIX7PvWCjryoW5U01YgbFiAmZjx469x66 / ets / naBI9 + kDj2DsxENQNdJYVUNiQYe1ROBHTCUySEV6SUKTEEEDaa5GsF0yJ2BhiXw0kTSdjRL8NJMzOQ0Pj47iT08cgkmutrtJwKaBCLIYRa +/ H3vX7UWCzGeRomCxVoDlprsEHoga3 / zKdLV7uRK7pFL1L5aR / Q7Z4EwQm3cWINAjTumO6hTEU6hn + kOK / frfnytkw7ZpqiLXcieaZ5OHJ0QE7LDAjQufFTo0RiCQObZIa9lnsdrgJqWdofW88wGheSuy6ceKCvjONXeWb9103d + u6u0 + 8e TYRfyPA + dgMf8bU3jJzPxEGnoqjViTRpbbj7DcizwhXi0Btts2oVymjJlEBcVsiVISG90tCuWiGtIk3bklYGZRRyqtE7iRhZkbxC1hC + fnjvNVhU6ZkNviwXLua2S6r2reSuR8obp9ju0eV6vkpP8Nh / Bng88Bbk5tvrxFI / SNoWYa24vJ9c8EuJhEILxBgzOFjJ9t1RSUw2jzd / DWEhVL53XiIQ5kmHxZKovMne4EjpWw + cpKQvjEGE3KAAWblBuXzBWRzYoKmI0Pv3vf / KZ1Wz4VbGg8m5Nke3EyDztXgj9GWulrgr / YBoOE6AtI6GrsI59Mgp / MIlgpoCXCut8EyOTKmJgnQeeLaA4Y6CFTH / OzHUdVCtRkErKI16aG8JdPfhVzxQThyc5yh + VlrSw4ms3MI + iLYHPzduTyeSeq5qbS2aGy1sHdrpIQzrC5D95EWYAM1dnk0vZcOueYrXz5jeuSSkIlyNIoduy2zu18j6du4sSvjr0DE5kJXl4cFuOEw5OlUmMICTESusEnJE + hKO + Pa7303h2IBRqxEmPFBczG2sZdL28c2PgFSVXnGdyTmi1ALBIB76sQsN6IXb3vQn9gNWlpA1pbGwloIGHMlVGczyIqltEUloh39ZPp9WM + JRCiVaEou0QXp0zaYKAlSuZbVXFMDXBzD5cCNGsSc3wyCfTViwewu / dWshZNvCaMmW62l6FsK + 6 m0U465G0gzXL5iBil + KCNr9RIE40puBOGB10202zNiDQF3yDgkBKJ2PQZRb1In9eIq5tvxjWR3Tg4fJDn5uxzmtCLuK8P6xrWIpvLV9fasX2MUUni3vU7ETJaMJedvTKQrDcbn77v08VNa7Z85 / qrr / 8 LuqRm0WS7eRZhE3gxNH0Eh4aO4ta + jVgdTKNVKBOcqXH8mlw0FmgyFBPEHJeXsKYpjlWtlCuS5iZJqxNZm4RNFzBX5giTX5OqZtMrhne4XcFJfQgZm8vMEpCyhNv67uJ8sSYFcHX7NZyarDYvtVx82nY0NygGaVLsRlAJM2Sqil97C9KIazbWp / rfYKINq9LKivtYKlQhduvDPbdg4vw4Jgvj3NyXyAwTB4kPdN6F6dkZZPJZ7n9ZZGeSe8rNHsfCySdw + NwB9DRtKGIFxlvW0v8P9z7Itl / 9 i0995f7SgSMvfKpQyfXZi2UxSKZ5vHwGf / fEeWzviODs9BLssAJ / gx9 + wqCLRDqoZMZCVhC5GQtre7uwaJ0nx0aRKAUgZQJDMumi2yKJqxS / zxsamU5FBtdI08Gb / WIITw8 / gT + 45 bPIzJ + F6RfRVOqggChHpHuwKjwObPB + ITIWaUK8u6cHp2eHiei23UIAZ5WERamZpqqV1 / xLl2jY / nP7tafO / NVan4 + OKYgYPP4MKqcO4fn0EqL9AfpdDJokUqVyGs8 + cxrDUo6IGq0awbPFzKcpwPz5oSOItDZW1rduTmAFxluiwctHd8OOr21Zs / UzrfHO54sWA9mJOqQLmaDI5qm5NLIUYecJxUpN51GezRDDVAGFUjzF2Nm3nbhYGUkWXM3lUFzIQswXSMPMqjbxHJfp0jICH5ZdjZYlSmvmcrM4NXMEt7Tfhd09N6JUzLHNrZwSX1f7vePZRMkTKX3x3PdhzR + hc6ncZ7Ngq7 + hl08qVdb0z75zN6YIbfJ423DAaM3byQ2ySMdThnyYgqvv6 / OoEN8dotSPMWqM756j4Pup9BzCZLUYAcFoMYZ7M9ZJ8UuwCJoNB6KZsK91Disw3nIBM3O98533PLZz846PrV + 95e uiGkwmyUxVigzwMFgIAz + xTwJFy3kCPTKU52bnkzg / fhQvDz2G46MvQYv4WJcXlMlvzqdMZBnM7wVH3lpk26vWEKo5rrdGmXXMeW30J2gsncMaWafPeI0fZ5q13NehEO0qCfHY8eN4bHAIPpkAFcpbI2oUbcFm3q5JsBRxId1 + b0nCAPA5gQn51MIL78hUUgM + 1 ccj8lgnsVDhAAWTlAmoNnI5izd9Mwi2lOm3BMIyClmdrwhh7oK7FcNpKRUJNi + KopjECoxfyq4rD + x4gKE + 579 IF + WB9HeHvnZ46OBHxqYvvKdcKreIhaLqU0scn2YNQm1Z4amDQWzLuUQG1qLJa7dUv0JAhwQxokIXrKpgHb8p8Lps5j8Fp5kGzzltN / WRBBmz + RkcfvmbiOYUDE4sEbOkcT / Nz2MuAzpc0z + hkYZRcN4gOrVZjWozIW0BQtE2473r7xkwc6VishNnWNHD0xN9O4dTxz4jKkZrMSWTpq9CRUljZmIGXT0 + 5 JPEehlsC0aKIyby0EirG4iImE2W4GsVUaLYIhwKoZRz0rnWePtQZ2dnASswfqnb6jwgcEG / 9 KMDf37ipcHTP744NXx7Ort4Uz6f3VRMFVUlUyIoUnW6wRKoYPk07lZNyh + zaQrXFNL6sA9O4Gyj2rbD02RmuZkvFe1a + atbcFyhQO0p4qxTMwu4SGbXq + 2 q9u5YnhfbbLmMs4yUVYuIFOk205Xa3b8RG8vrCIDJD7V1bn3CwmH / ty / 8510 HJh / 9 k5ge2zlVmBYiFD + spdToidNPUSagIUg +// yFAqLxEJ3HxCJlC5H2CNoDrRiVSMChMtaIGzCRGsf4ZJKlgnbU1ziIFRr / Kvsm7b3xD7N0UZ / 4 x5 / se + HQxROdJID3LKWXbplLTF27lFpstjNFusAsbybzpjndYCUSiE58ryXztmkkSIunGF6J66WmuqaNnC3k2RNxsVGiLdvDEGYNpygAqFZYLjfpXmsCTjmyLrk0caK5k2hItOEbg4No6F5VXL + 4 / x0vzf7wvuHpY / dMzSTW7Qq + Ezsa9qCN8teDB48gQ5N12 / YWTJ9f4jFG31UBJMeTBMlSXBInjrwUQE / rADZ39 + HksWEsFOdQyZsIRWJZihuOYoXGv9rGWIJTqJxxb0MP2w9 / MXg003Vx7PzNZ8ePXzudmLx6KbPUVSyUo2alFBRYDNIcoKBZdaJa0 / Gbgl1jiDjXyxrASMtMtAdNsnjGtp1tY3lvaJcztpxVDPzbeL7YRBUE4RQymf3HzyzgxanvI9nsQ0suf + Nfv / Sfnp2fXwwJusrbEp9IvIrflO + ERXTmhew5bNgQw8XBRSwsVDCwtQVmKo + xkSziPXGIxH2XJ8 / jd3fejb9 / 4 QgOjL6IliYfh1SbIvHhqBo7hRUaV8zOZ / cJvERljG7f2r // iw8bN0Rbz144uHp6abI / lUmtn8 / P3VcU0j1eduQ05nYCJIHVaVo1YNnxp8AlDRY8U + wJzq6tU + ITBsustJcbu + diyp4MB1Ei / x / xSSBrEyZrzPcyZpMjNVXEVCqJxyYeQSQSgRYukXCLlOfa6N / UiDAFWSdeW4RCFGdHtw / jh2ZhpRP4eek7 + PnQFJnsAMo5ky11NYNa9Pg7tl43jxUaV + TWdnfe + e9YnDzObqxK4sTcLv / f7f / iqhNjB3t4WTWlIIrF4EmZsFsVXaFWTFZm3IDL3XLHrKVLTqRs83W9VWLBxa29 / Q5tb + aYzgGcaPCayTDigrTUT3ApKyEwycwuTZUp6q1ApVihgVKeliY / xglDTy5OEfxK2HXAj43b4xD0Ck6 / TOmSJGHLhlaAsL25WcIwumPYn5yHQC6IlRrlc / SbNDXd3bzuwMyZQgYrNN7yNOlyB4tSt7a9Oy / JAuNcuCntj / egwd9EUGaFfF47utR2vujNq8KwvAgby6NjOH7bex6vE77nh4HaY49StKrr051JQd + kgbSxsz2I1kaKttMVjJ9J4eL5POEVPvSTIDdujaAj24HRwzqKkojrb1iHLeJGDB1OoHVVI + INBKhQft / YGoBOwtVNgmhDnac ++ M4PPrNSBXds1MXmlGxYNuuJIfCdy / g + wgTmX0csRNiSiWm64Gqt4PpnL0Vy82D3LieaeFhOj2Ub1ZUPy / hgLBM2vAniGW9XyS3dwtJ0kRfRsdIt1msrFAugNaoSuUGgVCaPU2eSWBOO4F2bb8ZF / znc0XQbHnniKVgRC80xIlMGE5DpYImw6zyBP + wr7N7yroc3brxxEis46kbAdHENyy13nUnNYP / Rn + H65i245ar1 + E5pZlkVhlMRyctzqjgzLiEU4EbXHnlguc + zv7wTrikui6iX + 2 bnHGwdlhSQ0dIZIJ8cpLSsDJ3Am8xCklOaxYqAcBNF6 + 159 Iej2NP5Phw + Mozh / AX0DgQxczbBV3k0t1HAuETZASFn / R3rRm676VceFnizkpUbdSNgSZLLvJURz2spXVIs / GziFYxNHYNOvLFAKZDlUoA88rUsl7S3uWnmUbfh0IVc8Kxiw6xpN6 / ZovMG5SCdo + hlSnx4ZAQPuglU8fvYjVKttIC43omfnn4ebdFOdDT2Q + lZRFOLBoU + fHJoBhem96N1YQN + coow5gYiU85S2qRTXt3mw / rQWkwU55Ep60vb1l7 /+ e1rb17ACo + 6E XBZr + iMAuT1ymwHFEpztGAQ58j3NpMwVc7KOCkO70Tr9mHjaBV3nrVct7q3MFDNl026se4BXcE2jOWHalyxe0yNL7aRTuiYGS2iKRbG9g2d2H31bVgTb8R46ThFxzrmzuQo2CqjXBbxgn8JQ4mXURENFGZpohFh0RBXsSGyEU1aDE / PHClvGXjH97Z1btiPt2DUjYDThYTudLK13ZX7DhDhI0CEQR + sCznXTsBd + un6YtNt3cT + Ojx / dXUD2yaghSDDtDnJX + uPEsRYyjjrxV0Uq4ZROzk3q8Zga4Q7 + 3 xopAOvb7UxU16N7x9 + lLcm1sv0fTQiDJqiaCe82SyUMLmQJ7KBInHCpgN + Ey0WkfptV + FbLz1Kk6Tn8J5rbvvrvXt / bwn4BFZ6XLECZgD + CEZU0gN7EzbpH / 7 yzaZfC7OlIVXzaduez3XVi5thp480K5L3NK6aOjHe1dVklgeXzCK6tS1YUAtIKymsi6 / GU8OPw9 / E1hZXUIvMakEX99kFA0sEWqSIOPinM4 / iOLEfRpA0s7EBbQ0KoXAEjeZLSI9lUCjQJFPoNTLbNhEVVjKOvbfcjqdO / xxC0D + y79 /+ 0 R9uWbflAt6aDg5XtAZLWExvkvRk / 8 nyuHl13zX9yYUJjM3PYWThLFSWo7KjvPYL1UBKcJo5m65g3JDl0notpxiOEfP5ch5bYlshWzN0k5Ar5xCwWb3b6 / Bp1D6nRIIVdAUiQahHyZE3dAURDMj8w / JzGSwSNcgsiOIjYKSJtWwyiVDIwyAo8t2b + pDLzqEx1Gbvufb2xZZIeIMhCyznz + MtGFeygE2L0kvoBqN9Nvf4mld1Boh1UlM4Y9jVtUNe8lpjl + D6YrtKplsCLs1zl6VFE9kJ / ErrZqzufAcOD71KRoDVoDhwKNz3WdVqDuc + 258 iEpN48KaznUgJ4FhMsEZPROmTedZCfoquybwThVTMFmlCkBZTLtwXENBRPoNiwkpfu373j1taOr9dELInho / PJzr31Oo6V3JcsQJ2sepF9 / byh / 5 yd +/ 0 xaEtjOZjRXa24dY3mw7 + zP2tyyx42mq7eDX / j1VmUPpjGk4ebPNOaCLmCgs4N38Wd0SDOJA / 79 ROGbXZYFdRL7g5so0y4c1zxAqx5YpMizXSVFZUqKqEb5NGl4tlpJJst3GBt1CWFIF8u2Fkhfh5Mb715b72Nd + LdO9 + 8 p179rzl7RDrJw + mq5kXbb5g2ydWIYwa7uyEuzWBuFF1FZZ082TLXQDGmsoyQVuihFPTr6I / MYj5hTSRtkJ1pwAI1iVCdgrm6V9RpIDJRyyX6GxdyyqfizqyWabRXj8Q1k3LoAllQtXC081t7Y9t3XjNP63e865De666Lwf8JX4Zo24ErIiqxcpvvFyYC9Zdf2ItQ6 + 4 D7btKplvmV55j1g1t83 + BlRYaZBVgkppy2S5gAdPzxCdGEA0FHEnhpNIeQvU2LBdV6CKxC8RmlYgrxnxhZGs5CETjcloTZXytUq5RCkS7HhDy2J7c + 9 P / cHwP21fc / XLv3v / n6X + WPjqW2KK / 7 lRPwKWJMPLW / lwNapaj7WcQvReJ4kG5ADPgyusNwTBmqxmanPnVXh17KCzrpidj8xoMRbh5TV8DbGLdNlWNSKDt7s4 + 8 P7i1RsdDZ0Ik4sU2ZukC9Ctw2xRMnQXFtL3 / BA /+ qnb9r57h + 87 + YHRhx381Pgg / ilj7oRsChKptu2uQpWcG32AqBlHK7HKtl8b6YKblq7GwenDhI8mEVHrBcx0uB8pYSg2ziVmVSFFRXItb0Qq6bZAw7t2k2UDKIKTYq + Kd5u7CkrfpXiY3FU0QL7V3Wve2H1xo2D0nTr3Pt3M9Lgt / GvOIT68cEi603Dl / mIXqQMwVUwF2cWmI / 1 WCCDryFCppBFqVDEeza8G / vPfwu3r9uO5HSefKVO75OqGn / J / gxs2LVOeNXqDnfyNITb51f39b / W39Y81L1q65m1pjktqdb02i1bRnZ03r0itVQrNepGwDJUa3leCi8d8oIs06qZa5fcZ6 + xBWi / GH4Jn + j6HXxox2 + hR + 3 HQ8d + DLNiuqv4RdeXe + dEtVjAFmuRtO2afAZ1bN2468t /+ fvf / Jzzpn / ElTyueD7YG9WNz0zP73r0HqrIlrfO1ym + s6r5MFvR8Mzxx3FjKIoGYwELqUlUm3XYTtrkjFpVZS3xrUq42pNasMX / aRvDK2XUjw + WZMtdVrYM + IcLcniFdcsAD6t2Y + 2 XxhMXcfyFh3hR + lJm2uljadf8Ldz54wVoy5Gsatgr8I0 / bFb1WS + jjvJgwduRDryyw2ll567t8dgeN0Uyl9VkWdwIoyDL + Ie5aSQXKkgKBJYoQs1fc813fCzPc71JtFzCnOCw + ASQ3mTjkCt11I + J5rsgeUFtraGZ5W2PY9m1GixuynFJ / spNa0MQBt0USaj1kbZrYIiwrIyH / Q2qwSr06R3KYBACSf5 / Aa / 0 kBTye6ILVbk3tpiabQfA9g32Fn1X2wBfkr86OS1lQVCX7evgmXqv4M52AzQWfLEtCPrjfTCYTa8GdyyatlhLxbrYcYWNuhEwXVddpHCXt1RwI2fWlKw92oZN7VchqkZ5kxPL6 / ds11Y7WG7K4 / lt0d0Cr7boTKhtqcOKcCl77I53I + qPUYCmw20X7xwvSJYoiivSZvCXMepGwIZFebAoehA0 / 0 chQbA9H7Z1bUGAyHunatItuHPLddiq + oDiduHhgnfMu + gWDdQiZM8X21gTGUBvYy + KlRyvHBFcK8AMO8GldsXQ6yaKrh8TLfLAxq615XfACYM1NtVTyFUKfC9Ehi2zTSmZyFgzk554F3GvMd7A1FxWK + 1 UdtRW7bPB0uFSpYw10V6sb16HxcwS3w3Grn6g4 / 3 ZTmyok1E3AhYNy7Z0Z2PiKolPf3P5HJ4 / 8 hhBj2n + RHdDO7b1bCPivoCAFsB1 / duxmHW2bPcCL09zncZoHu7sCJhNgvncDHqkBQhGprovhPMWzkQJtinbqJNRNwKWlfhIyN96hNfSLIMT80THncyVYcJJdcYTk9jcsRYbu7egM9qBBmJ7EukkReFCrcuZq43VvYhRO58mKTi3cApnTz0Oo5TltVxemiQKcqUp3HMk4I + NoE5G3Qh4V / OmIxv7r / 3 vxaI5VyoXq9ExC5YUlQEPzvayTHMPDL6Iuze + F +/ axDbTWKJI2FjW2a5G / 6 H2VDWXZtvnLdHx3xyZw3iuwCNv5r9LRAGWSubc7qtv / Yv3XrPzIOpk1I2A2XolVfQfX9u1 + dHGSMtB2xKzXud3VIvcLUqDZJyaOo + 54 SdxfbCIsYmjfEdvwYU5vc2wPAjSXYIGwcuF2Oko0S1pqmu6TQq0lFx7vOfQpp6djwd8kWNr1txZF9vasVFHSBbw + Y9 + afTE3FN / eOTk6VWPPvPtPz4 / NX4XpU6GaZiq7WLFTFA + nx + vjBxCbvoUhucyfAcWPuxqoFQzzba7dNR7jk15t4BPlJSybtjq2u7Vz /+ b2z71f9x5ww0jn / vcl68otuh / NupKwG6dVv7Qoa + cOd698W9j0Z6DTaFoYnL2zPsnF0Z254umVCyVmcbhQiiEs / M5ZA2Bl85Y7mJxvv8zr5M2yKQrTk013YqUbhGJb9uijz1rru3d + sLG / q0 / IA65MR6LH73zhr2n6fPrJj3yBm8gIni7RtXp + OYTX9rxnSe +/ vlwJL6wa / Puw0fPHNkyPvvi / SQ3NZeTE5oUWzKRbopF7HhJN5AtyEsBf3xRENPxgN9ozKTNytqeXQ9tXb / z5JFzL2wrFlPN99 / 6 +// 1 fbd9qG587ZsNNl3fFgI + dOiQMpE91yko / sTeG / dmT4y92PDlb /+ f / y2VS7UNdG55dKBn7enXjr90zezSiQcYi9jWtOUru7becHBifnjThakT9 / jk2Nxv7P0P / 3 XXxl1Lr776k0hGMBpv33k3W + VXdxr7usEF7O1w8LYaT778ZEOmPKM2o29xz549BmtUduqVA5tE0xI23nDzqTtW31F57rnnpALGmjQzqt96694l1Of4l5ZECP8PAPgFhqae3ywAAAAASUVORK5CYII = '), ' enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', ' enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', ' enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', ' enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', 0, ' test', ' {"春江潮水连海平":"海上明月共潮生" }', ' m', ' m, -xl', 3, 127, 0, 0); -INSERT INTO test.TEST_DATASET VALUES (7, 0, 32767, 1, 65535, 8388607, 1, 2147483647, 3428724653, 1, 9223372036854775807, 10.5, 0, 10.5, 0.188, 1700000.01, ' 2021 - 01 - 01 ', ' 2021 - 01 - 01 ', ' 2013 - 09 - 06 T10:10:02 ', ' 2013 - 09 - 06 T10:10:02 ', ' 2022 - 08 - 09 T10:17:16.161342 Z', ' 00:00:00 ', ' 00:00:00 ', b' 1000001 ', ' 99 ', ' ! "#$%&\'()*+,-./:;<=>?\@[\]^_\`{|}~', 0xfffd, 'тест', 'Airbyte', '!" #$ %& \'()*+,-./:;<=>?\@[\]^_\`{|}~', -0 xfffd, -'тест', -'Airbyte', -'Airbyte', -127, -'Airbyte', -'Airbyte', -'Airbyte', -'Airbyte', -'Airbyte', -FROM_BASE64('iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAYAAAA5ZDbSAAAACXBIWXMAACE4AAAhOAFFljFgAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAEIPSURBVHgB7b0JnFxXeSf6v3vtVV29791q7bIkS8iy5U3IC2DHNnIAJ2MYQl4AZ4HJQB6TmcybQQz5ZfHkDXmQkEcCgQDBwWb1IrDBu4wX7Vu31GpJve/Vta93e985996qlu1k3vzUJiq/d+xS13LrVtX9zrf9/9/5jmDbtgTAQl2Mzwn83zc8vfzBPn777Gc/az/y8qd9iaAULvoSoQYEVdGW1FLFtCuo6AFR0EoFcWkhX1xoX6uK5YnSr5fE4v7PXPPI3Oc+B+ENH/1Z79z/a+Oz/8KjX8IQBBKwQMPG22Q8e/Hrvuni+e6Z/MjWRD6xOVcsblRDaJMEKeRXA2pZL6NoFso+ySc3CO1TF3MjL/cG+62oHJCazYYH77v+C0W8TQbJVqxbAbvfm9/1nvv2kf/cO5ub+r2hpeO3SIF8d3bJipiirQX8klAsmYhFJdJdoFQxIKoG+qUd9lx5utTh7zRHkxdHFb/wj/F4/JsP3vizabwNRl0L+OsX9/mkhH63rAVeKKbThaHcqVv8duDP5tPT61PSFIKKhsSChfYOGZm0iWIZdF9EuWwjlbIQiZsIlltwXWQt5spFfH/weciajcbG8NnmePw/xiK+px+88aUs6ngwAYuo0/GRvn1l0YRhl/MfP7z48mdGps9+KSI1rNfJw8ZCKpKLJjRVhKaJKOVtiORWRUGERDejIsCqkDbLSxg++QouXDyE5rYgZNOH5FJh3cTs9JfG5xY+/fs/v7YVdT7qVsBkne2AobxUKVU+nEjPf6ot3NbdqDXBktIwSFuNiohgQIRtAqYuQBIFLmSZ5rRgC6gUBWhBCSdVHRdME9GwhEhMhmgpqJTQNbew9AcLudQff/LcJzXU77DrVsD/49RvxZ9KPfFHo3Pj/bd0vyd0+8CdmEmPQdJ0FAqOIMn3ks8VINB9SWIazAQtck02dHqORB5t89F7NHosoKlJhk+TIQsyFFMNT4zNfzRx/Mm/+E8/v7URdTrqUsD7Satmpi7+2sTs5Icmkxel7koRPUYOaWMMgqTCIuExASuyCL3CfqTIBUui5pos0V/bEkCKS5OAjiWB6yWaFAppcViGYJL2B2Vogg9zi6n7p3ILv/bFc3fUpSbLqMPx2tjYuuml2Y9WimK8pCxg7MgzSPiDKHUWYCsKLNMm4Qpca5kQBf4fuGlmkbdIQrbovmGQgDUJqmLRRLDofQLCIYkHYYJoIxwRkMyUGtLZ1EeHRuQDdIoTqLNRdxr88MMfkJbKyX+/mExu7wy3CLYUwvdm0vju2DiskEzaS8IzBKgq99P0GJegFlzQgiNsg46TScs1P2k03SffyzVaIW1nViBA51MFhVKs4rZ8qfzpD9gfkFBno+4EPNPZuGEhO/1ekBk1pQLWxq+CNtCI8NY4FEWGadiUHgASaTBlgKSpcCXK3i04Nxv8GJM0XaL/+iK9dJzlmHOJRd5M4CIiShQ+OqdgyEgVU/dseq6wAXU26krAtr1PHE8Nvz+XL8RVUUPJKqKk69i16h0IR8kcWxKa1Q4IFvlV2RUqEzBJ2WaStmuoiM3vCCgZJTSHmtAR6kWhrPO4U1UF+IQgOoJ9kFUToqnSxKk0jGem3s8sCOpo1JWA/+TFc+unc6N7YSiUz5IQpABOz59El7oKm1p2kHBU9Ac3U0RsgWX4lOg7grRdbSaNtZiwXZttsRSK/O5w+hRu7L4FQTFKQIhF+bOAgdha0mgy1z5HyyWTgJP8wr0nmzLrUUejbgS8b98+cWppYpuulzuhUypDAZRBwtINHacWjmKTdguujl8Pnx1BhaBIFmBxSXKttbmwmW9m0bMjdGcCEAGBVDmBUjmHa9puQJne61f9GGhch/nkPFTZxyNvwST/blodk+mFbey7oE5G3XzR7l8vBHPl9LWkdTEWGbNImEfIZI5Hc8MYnziNO/x90IqTBG5QFOz6WNs1ylybBfD3sKcsemzQcRbxaJrow7GZw9gavwZhqREdsQ60BtuRyCTJUkg83bINiVIOMVYs5q7133YkiDoZdZMmnZsYaa6US9vMsihblN4ITMAWS38oy6WI+fjCY4icUTFMM8Ai6TJBsuNIhnRjYha4MJnkTQqoVMpxo4qfhJyFT1YxsjiM+cQc3tX+a7A1C+n5DArFHILwQaUMuJRh75FlA8bVk5lcC52pLnDqutHgXCbZXjb1XstyzC4LjG2XxVboQTHmw/esLA6WS8uDZRK0ibZQuxNvuT7ZMA2sb7qK3qdApwnBoA9m6l8ZewUdUhu2aHHMpYd5rsysgMzUgO6LFICZhtGXz6XbUSejbgRs2+Y6EkKzaYluLuv6UvoFpMykxZS79kYgNwYpRRId6dKtTMltR6iHTG4XSLdJmw00BVqxunE9JrMTXLgEZJGflXBudhCzg99A6eLjkDPDzEzwScRSLvYZLFc2TLPJFsy6CbTqRsBls7LVNHSfTZmMIpJKSY6PZZrMI2YBDgxJwZWkOpPAoNdFst8XE6PY0bKH+1pm1vf03Yn5zAwFVhUedLGZwHLonF3AM+dO4NDRQxim1yVJ4lrMcWz6DF1nGm35KqaxBXUy6kPAJEfdNPqYUrK8tyfWSxBjkAdKXLKuNnMTDF6nwn8Ze45FyfPZWQSFCK5qvh5doTVYE9mIwZlBsFya5cfMk8s0YRSfgsG4D8+1KFiKyPziML8tkAYrCglXdxLpimH0A29S1nMFjroQ8Bd/8km1WMr1MhDCpCuuyQG0+LsoWrb5ZWYC5RbZFbJ36W0X2SgSRHVubhC7YjtxT+/dWMokMM00lCyB5fpzhmApqgR/RIHcqkH1Oabb8fekxbITgTONLxvlno88+5G6IB/qQ4NDoUjBKLUw2SmChmRhAX2BDRQQy9w3Mg00bU/ADqEgeCgWDYmkc3HmWRhDj6Bp9hiOjnyPgiudR+B2VYAi97UsOmePWZ7tBHJOxCYrDkHB+OWyXm5pj+bDqINRF2mSikozYUlRJpKyUUHOSCKuNhEs2YnpwggJxVcNqrjGcWBDqGoz86Epo4zXBk+iOTyMEQq0JGaTBds9hgRMAhQMoYpuitIy00//kTvmxzKSgiLpSChXaabDFnCFj7oQ8FIl0RhVor5NTVuRD5tYKJ9HhXDoTS3bcHFkiI7wuWiVIwzBkQ3XalYQzIj+ok/GqxoFU5KBBEGQErFF/D2We7zo5lZM+1lULdUidcudKJ6ACSDxpXKZZtTBqAsBL+Tn4xO5cbFIZMA1TTfhzoE70YgZ9GpLeIHSJoNBjlYtL7axrIZQcLRSIh8rxxT6xaStCzoHQNiRpu0d5ppkOKZekpY9ZjZBqPl327LEpXKmAXUw6kLAAdUfYFUYS6UkHh16FBdmT2EHZbVILRBAYTooFWpWmmue4DJGEr0qOVEX11HRI/3dZ5gph1DVevYUO5fInbtHPzkns90PsemOYhNIXQejLoIsyxRjzExKFnGzRAnO2GN4sjSJR5ZyKBHMJLjpkWXVTK5DIjkskjMurQx2BOpMBCZiLtDqrOAYB2pxms35YnZjE8Qg9Ktimqu+cujjCq7wURcaXCBzKAquFgqsWkOBSTpdIdpQEfQqW2QvW4DD7jv+2PGp3l+XPXQKAfhxbu4MR6jV2eHhnQDHrttCHUgpCRSsRbRF2jHQMBCbyQ5f8fXk9aDBQkUwNEdKIv/GAg+AGU8LBl9hWeL7etlUzS7XVNHRbp5Y0R0H1nYnjlQ9hYedVKtAdIq6G/wxbGjehLAvirvXvx8lwyjue+dzJq7wseICvmhf9Nk1u3jZ42H7YdHUjbBnUr2aKsffuigF4Aq3pn38K7D6ZyIRdNtwyu74oRbPZdc3beC+lP3HymqdhFpAdY2Hd0dwrMBsbg6bWrfhroH7UdEtHJl9LbLvuXde8dUdKy7gzNx4+9DMgb2zs7MrwpkOPvKIVDFLmuBKlftVuKAGP6L2L/fBtlDVPpHUcnXDGvRFVpGiqyBRM7IAmWIWzYFObG/bRdBnCc7U8KJm582iW8fF4zRCvOZz82jLDOKGiB8/Hf4R+3zf6YX5K94CrvgX1FuDk5VysUUXFt9DmqwNzTzbh8sY8VCbQEGN5GivUI2VLGuZOYaHYqEW+dLxBmnuTHYGcV8jbu29Czd23IMmfw8v1TkzPYRb+/YiojVz+FN4U5MuVIMxdufw0PN44vi3sFCcpbRMltpClRWzVG/VWPEga4ewQ3/21LeeVqF8NFkeb64oha0/vLDv2YpVqJALtSq6oKtiMKWa2tixdcXZfcK+f3Ft8pI/KxAEfUm0aguUpkgqYmoIGXuharMFr0RHsFxEi3Bos4ij0wcxlj6DXe034v6BTxAmPYXB6aPoJvp+V+MAThunavCml/l6YbQ7p1RNxpOk7VpmETalXoZtKll/L706git5rHwUTdfm7x/6Qk+j1LznzvZd1xRDF4TX8qd+m/kt5uaIiaHgyG/4NP98KBv74dMXvvZoj9n+/Jo1d5bf7HQRLU9MEs0JTvoyzJnyXpJ4WI0gGG7C4tIkCSPgfHS12Aq1AmgeDkhIG2k8v/Q9nFh8Adc27sVdLZthj/8Y15dnMEHRVp4Fa2xiCF7k7dw80ISHckEJop+AEp2lSoayOJy94k30SgtY+OA3tl87m57+qwVpdoM2fR5NQRVGj48D+xXD5pFwNluRm+PrOnQ787GF0Gg4mt/67D93wsxiUTBtQ2SXuSXYDMUoUgS7QLRfFLIVgkcecUiRf4NloIbgEg/0bpmwx4ZwjFKuLL554u/xC6IP90Z0zJEACx0qLllnadeAjyoAIgq10mqR5eamhM4rfxnxigr4o9+5dvP56bE/t0VjQ0tzBBm/QsSAjLCkcD5VrlgMtkdFLWGV0AJVGVAPzO9/r92p/4je/sM3Oye7hJZg8fA2S8K5rucmjFpH4FPCEMqaK1yhFk3Yy6BKHmQT+S+6kTIdFgz64fNZGM5l8ZWszc1tv+ScR/QyLvcvnxySd39Znizwgvor3v+ysSIm5vGxLzf8+dO/tXNycfqPBVG/qa2hCbGoD6YgIxLT3HSGKAEf4cYkq4bGIE6ffhzHzvwY87Pp6NHFn3/+W2f+4zVvll7dtmqHqEk+mb2SLmfw3MhzuLX5HtxMOSmMPBfgcuzZ9vJX70zM5FYF5kCQql+FP6DBChH3G9Uga5JTICDWrghHubx0a1ng5f0WBn5XUtYVL+QVEfAaeQNRqdrnTal4y0DLgNAajfGVBSZf+0NAASH6rLJRJFOpE8rvJ+51oknBfMSEavqQSWdXn0sd/rUfn30w9Ppzx+3OoCr5Gi2KdFmpDsOjXzz9AwgXfoEyYdIQnfjLsm039629t/awJgfmV2Ui9hW26IwYJo1ubFVhNUpnuDbDmimt6gp3UWJlOni1wIrvZLRH2vgicmsFc/23cqyIgGPBrmhMiV+3rm1tcFvbtcjbCU7GM7JcIBPIAizdsHiNlE73TRJyIKJBIsiRr8DPUXBaTL77TPrkqtef26eEpJgck1kNM3sfu/AT1jweunAaJ1IZXlEpkm31SwGaPAZ/TxWd4jehWoXJgQxWX8VuLsHPiH5Pwz1wg93ViXdeHVuPgBTk582Xc9i9+ha0R3sIONEdjqIOxmUL+OFT+9S/eeazv7060Bv5t2s+hemlObqA7AI59S5suUhFN2GQgCvkg8t04xE1aTOLqH1+CeW8gEwhvcGolO72znt89sngoUOHlFCwRWj2tQpMg5kHZ2AGNAWzTUGUaZLwGilTR2ewGz0RuvhW2Y2mXR63KgbBBTOc6JgJWZBc4VYPcScGTZiSVUKpZGB7+7XIlNK4pnM3dnTdhKHFk65LsKDGxLc/Fn1samjt0Mih22IzRzAxehhnFk8TvRfgzU4c8IFMoB3ktF6ZaTIJSndXHlR0MtsszKPwt1wypYyRvpmgSYn5YlnU1kpti/dKsBtjvmZLslWHzXENoyo6VZReffTw0llsbd/GiQCDBC5QdNSgNjoZk0v91aJq1Eh+Nx1iEVY1kILz3ERiFFuar8XG6A24a9XH8NS5HyNFLkKURNRHiHWZAmZrdC6On7tmdGGh96vP/ACPHH8IBsrcRDJhssGsZrPWwbWPpUmsMpGZW6YFTJN5XM0WalNumcovbtYuGk2s6082XThfrKTXpSrT/6VN8XVq0HgO7Gmkg0O4+DH9jJJexrnFs7htzR0kMwqixCBWRda7KbEbJS0TilCNlr1zOPcdxpBZGBnT6Sn00ON/t+2jWMzO4eDkS+QiFO8LWJjBFT8uS8DlG481LCYTewqmFTvZJmIpJIIZLbZyvlJxsMNsoYSo1EyBCUXTlDKxSoqKZXO6jvtkw+mAYxkSMuVMy3z6NF+De92aOzNlQf3S4viB2eTx73XLyTxdfKlamuMhTB6eoZJQT06fRClfxK9f9RF0+Tbwmi2LJkWNRbKrsKPnbZ2Hzpn4Kgb6T2PltDSDysUF6GPfgaK/ip9d+BvKCpw2EDbnj2H6G6S3t4men5lrKJX11UwB/ORLmallmsXwDNNwNJhepwsloD+0BT3+DfCCJdv1p0zIHKFik0KviFk90eKdf0//vSndCP7t4UThUIJsg1QjjuBppHeFOfdLQd2z559GuxjBPZ07IOpJdyWhXaX+ariowLngZl8zBXIatzosmOr291OUH+ATwwj58Mj5YXz70MO4kBtjq/2rkbloi3XR/vGyBJwspZpK5UoHC1iclXu2uyjMFRwYNElmlczb3ubdmEkvIEAX30eRKTuWvcbWBrHByAP2WDClSzraDLZHz463+gd1f43BYwIT3FjZkZ3TA4uZ1bnSIl45/U00TByAMf8K/4lWtV5LqL6HSYkR+UE5hu7gGpTMAiFjGjFPa5EsLnFcWw1IOOgT8Hw5D4NpL/fj3moKQc/N+q54IV9ekGVgTblstPAVALazes9rfGLx5ic2D3ZGp4/hyRcexFh2BG2+XrT6u1CgC9oYaEV/cC2Z7IoDNVqsSL1wSb3x6cGHmboY7Ly1paBwIuplnC0DMFgts0a56mulBfz1mefxQi7JAzGvEseDGkWPVKAn54jn7fddw9cO9wZX0/t9yJl5nnqxq6MQOKNqzn37Eo8u6KE29Yo30ZcFVZoVq4fSH02hC8CnsuWu27W9khmBR5yjGqVBUoHkRB7ODCCqBdCkdWF9fBfOFA6wJkduyY1NOLN+yYqBhlV+O380b1lV0NkhFRzuvloS6UbDIq/ysIj5Od/sp1SHXkpZ1fdU0yfHk3PAIl1KQM8b2BrZjcZoB1GBY5DJEjh+flm1CHAJQiba/x/IgyuG3kQCFllkyYANy3KCGNaOyAuA2D9aQIE/EmAr5MkEG1gX2kw+8jdwnqLeheI8xwi9VQkk5Uu+U0c2bEuiaGGZBrp0L5ZXc/DKSfchy2J8hFZJYg1mdKBGp85ZJexZoaCMN2IRTJxPnsD7V/8bbO7agvE0+VpZdX+LXYviPKDE+3xJNBuS/rd5HixIDQzAYELtDnRWQQS+4Nqu5TPsOXbRGbLVlruAzYQpH55+BUfmjkAyFUfjPc0Q5Ev82saFZpo6km55BtqqMUVerToP3VlttItSCV5OC6fo3XJ1lrdVog/bFL+Kt2ZgX1HTNFw0BoHCGCLCBRQqC9yiwJtwQg0NWz4kQdKTDave3j6YctqoSBchXy4gphHB4I86F5JrpF2rsoDjB9lykSOJaTx0+Bs4nHoRiqw5DnGZdjIjvvwzBgc32Yqilt2X+bJR55y2m7+6HtEFLoRlWkukPIJKCKsa+ilC1zmypQpBtAS6mK/nFKIsyTBUA8eP/l8YI/LDZOtTq6sU3S/huoZqWY/NQZbypsFH3uYabEPjESxd1FyhiN74KjSq7WjUWuni6vAyVWeJCAUsBD9Nh2UcDDpBEfOBPAiyHY0EX4urXkL8E5hi2QZK/Bq7FB4b1eJ270CpptHeMWR/sZCb50tcOiKrkNUz6PVTIEVCNuxKFfvQiGx4Qs/iH8ankePrRWvOVvQQL3cqVX86hQv79l35nfIvS8CO4RXgI02cWJjA1qZr8O6+XydSvcBfXw4F83iIhOALEMpEPDE3oyJcSg7uMn1W86zpb/gcRTCWrQp1nvOiYaH2bTiR4LoDjx1ine8OT7yK96+/n9dj7Wy7hcxwmtdhcTfCIE/6FmY8iArlvZIkumnYcqRMcBml2vel8xuog3FZAib9sxwxSxSx5hDPXUSvlECimKYrITlNT+BWOdn2JasJ+PAqF5flt6IgvaHWWJFEY3nQ5pzLNcvLNM07DReO+8tYADieGsNschQf6f8QOtUGzOVnl388PMrXYZk8Hy46/lxwKyy563E+j88LqT4EfFlpkiJJJQ/mkyg1OXD85xhJqDCDPt7eiKU9kofzehdHWJZNVoXNLqQTPcmi+gYNVmzV4GbeM71VYt4Ngqp0n/u6Vz/tCpmBoQdHH8ceeSd8kWGkc8MsmKue37aWR+ZOqscE2+7vwLQ+RS9W6LfK2NS+DhfypzlWLdnS21/AkqSkuBmkCySTf32mXEIzUX8NsQAYFM04YElwyH6+ms+NUBhcKTBOEXZ1lZ9H5SiC/EYNVuU8/zyBdbdja5Ec0yC6rBC3EIKDEnsm23YlJikMHxcwhxweO/szIvkpDjAplJOdz/fMh2OURRelEnknnpARxobmzTiTeQ13rPkATl64iFKlxIv+FE3JoQ7GZZloikqzXFAkJUach0IKAqTJ3nWzDMcJx8gs8ooLi1UjMtLe7+LKQhXBcpqGMi194zYDqqwU2PX3qRo6Ix1VYr9qol0/KQrVKKuqzXz1PvlVmybGiRYNh+N+6PSdRXt5tYfgfgHvSZE3QJvJzGBrw424vv1OdKjrcWz6NW7y3eLLMupgXJaANVFNy0TVsN5VDLFiQrYMZ40lJx1IwBbRg/3RAQL0A7yFUaPWRnjvAAladxZTk3SDxB/LrskUX2dVvvjKJyOKrDQTRQG/5qcUpxmGbjglrZ4QmeKKtY47ooSqv3fWMjmdcjSfwrvpiLWlD9V1v3wRWjUkt3nbh6XSElrp+927ai9eHX0O8WCELWV1UDBRvCwT/fFDH1f+9MX73/I1xpcl4EAgNCXLss6YI8FyfKRecYMR1jafNNswKgiJjWgL9iGuteCWgdtxLjnCu8uxC5st5rEq3ofuSA+XSskoX7LkJU7UQ2e4s7M13IqwFkHYF6kFbEBt9QFvmGVfgnR5QTYTMOuU46VPHt3oAVWOFaHvzzy9FxlaTqB18dg/4MzxL2CqMIT1TVsIvavwDvL5YrGCyxjtxoRfV+fv2HforgDewnGZZIM0LctKngcprPuNopB2ma6AWaWrwp/P59PY2rgL9679MMaS57CYT/GotzdCxAORD4ocIs3s4ILJVZbiy5t9fmjNlzKJYurAzo6dhF2vc0ykx+dWAQhUm7Gw+zLRet7aIsezwrXCQjWy915womKbs1veC+z7M8TL79ewv5TFI3ND2N51I4qVMipmhft0glf/lwTMtgT48on7GzwYXZAlSsXFVQHLirDH9ltUhnt5ebCMeb+ipkl/USkaaA41oyvah0Ipj4iPEKTYKueCpAdxY4MKozKPw7OH6GiCJ4luSpbmCZfegj1tN6CLtJNpzVJxseeuj911yer5dClXmkyOYysF2EpmhFdSem6WV0fZNUDFJ/vRH+5zGSo3WXbKw5xo2eWHqyYctedd5+Iea3EQxmzUEGzqx1VNu3Bx6RyPvtl5NVX5f2WiWX/pBwdv2p7XjX9vSuX/9tdn3/e//83Q+/8g5rd/x6/5rrXN4OYvvHzvhgeP3vOWtEe8rCi6s6VvcXJ2cjaTy/QZJR1LwhLuXv2reHbph9jafDXlnlMctpwmjvbxn34JrxKGIShB7t+YNpXtIn545oeIZU8hY+dJ7D7M56c2LxaG++n0p73PiQYj5umJI/jZ7CimkgaUtiDXUObnw0oELcEo5o0E96e95O81csKsvEdwF/06EKNHNbo9tZwHVZPOA0IWaLF2w0zgpu0K2sa1zbchkU5gIT+HYEhx0j/5jYDM68cXT+4dOG6c+8RUYu5/W9vUH6kQsjaTP0eZgIgcxREd4gCCdvQaUxT2R0T8F7wF47I0uD3WkVckdY61BzQqFvnTFOYWF8gUfxAD4QECGKZoBklIxTR8O6MjzcthHFSoQn6bbYgR8wfx8/I4XqX3SoaMvJFrPz738tVs1y7vc3xSwDDp0SHypRMBCsjcWirmI1nX9y7ilJuJYy4bBgZi65AsLBGvqy4DVxxtFUWhSht63QAEYZnQeTRv8TSJlX+xGCKstGFTbDuOTb3Cg0bTaVlLiLn4Ly7+/pOhvY0L1sSfBYSmB5r90UhTZSPidAuKFGwW/PCZYaiZJFpnkq0XRk/cniol34u3YFyWgDsVf17zaaN019CLzg8/M/oy3tPQQb6yiAwFUOUCCdIvI9QcYkutyT9aXEsqZOBYKqoS4C8oPviCGvQy74MRH0+P3PniyCPVyo6QGK5Q3mqpdB7GPQNV94uyWSK8eQLv6bmXC7qdiIQ0Rb+M0/Uap9ieM4YLny6r8HBycdb6HTz9alKbEZGilMMb5HNLuL5xHfzkbudLM9jRvQsbm65CSA3aiiz/sz74i/vv0LL5id/J6vP3qKWo//bGj6E/tJ20tZEmtEYgiYIGvw8JmixDxjmYcrZrMTWy7/mJr+7ECo/LEvB7byjmGyKNxwi2y7B11CqZxoSVxo9+8iAOj30PPjJnuZwJq2wgEJSJwWFVFxbHfvn2CGQ22f5ERZocskLvJ9DfzEOaz0//yk9G9+/1PicUjZdIq8zlvK5BEvLTxGhUGwldGiYTOoIHb/oIhMoc8lahinPzH7ksomajBm3Y5BY0xKVWvhBcJhexrfE6pAlqLVF6F03quEddQJs4gd+++pMUL6zGVGKSRf5mQPWV3uya7LP3ifPx3N0Vcel3hVxYnSMq8vzIEWylQBOLh8HairMKUkIBUSSTra2KIhwKUwRvNL948Vt/+vSFb/eyc6xUl4TLC7KEfdaq1u4LPk1K89ortmohJONvzs/hdCKPcEQhTaDUJ68TSMFyUY0CsArlkiwtEZEtEVrkIy0z6ceWTDREibojnqJUKEVHFk7+hwdf+Mx29jmqJfMtNRhcyKJoizX9JgF3RztJm0Jc4EfG9yN74XuYHP0pPTZrDJUXTXtSXkbwsbsG5earQ5s5jdhLAmSNwtN6GgJd/DS5lVcPDuK1l36Cbz77f+O7xx4ma7HI0iRLfRPEjY3gL843Fc3sr8qG0mJVFErtAjiROoz9I/+I00vD3M3rvPjf5pgBWwyg030fxSbT87NXjyV+cfc7R/q3fuHlT69Im6bLLnzvaF97MRaKTjPzVskZBCbQzw/4SKgmfBpr7SuhkDdgl8vY2L4JIbmbfmCWm2bNbuBUfJwmRb5AP1i0SMhkqgmYzBbSq185/+QX/uDxD7wjFozlKLCxGLq0rXsrN6UM0OhvHECeLcqmc82T8P786Kt4ZmHWhSHZqIZT7hCqgZMTd4sos51bjBxu6bob13behInUKFkimaNz5aAfX01l8c3EEI6nTzslRywFo3ua+uYCzliJfsr9r9OLvNslxwVkYqlm+31Yiiq8TJhBuIWSw2alycKx51S6FrpuRVOl+Y8HhcjtXZO7LivP9sZlCzg02j29rmfts6ago0yCFEi7fGEVubRJwQSBHA0+0k7S2HwFF9NnsLFlBzY33g6RfOe2tp0olYLw+YmY1xQsLNIEobS/Ma7R8SKSmfTNJ0ZPPPzcyecfkE2lnC5mkCql8L6rf53y5m60B7uRKae5uVOCKiYb2HIWv9tn0vl+QvVfwWlPCCda9gAOFtEfnTuMW9vWYWtLBGdmT/E2wwy8UVjH2a4wLII3FQra1jb2c19NCJyhioE3FYCuV24ulko9hbzlnN8MkhFRuNYyQeZLNl++ky1YPC1LZQyQasDKBSlVvFoKon1tQA5P33fffSvSweeyBcy+yIaujc8HAj6jVKHZmClDDRLgQd8+NUf5MJldgTXbzpr0Ywt48eJTiFNk+qtrfxMbmjagOdiGxWwBDSRYH5nf+cUyIU86WlpV3vSskC+sOjp68BOlrBFULA2nZwYp2hbxgdXvIdNdIQ2sQHDXovgUZ79Crw1wbRWEI3AGYdrLYGcPFCkYRQy99iWcO/4Q68nFD3KreTlmzjQ+6mtAM6FpLPgC+2Z+35ti0cVycaNhWJKui2Bb3cblTr5tbZldG93RXjZ52GM22YpMKUgMFxKj2Brbgk69VxwcO9WJFRorsrqwqaH/YFtj6wVW41xYqvDoOBgIQ8+SOTN0vpIwVyRTxdYiUUT63ePfgZzNYHe8jFVKCamCQCS8jqaYSZFwL/x6D9KFPDra/IgEGEBSUYl+lC1D5MtSXjqzH82Jw6hMPUdmXawiWE4xnFBtV1htyGLV+GPwVRW1kkgme5ny0q8Pnsc3Tp5iWzJxgVqmA3swJqxBimNb+zuc1Rj0GyVBNMPWG2lNtnFXvlzq0+mV/tB6skpRyGR67YpaXYBn8r2bTLJcvK6YMgebFx0uUcaRzD+P2cH9yvn5Y+/ACo0VEfB9Ox5Idzf1PqQEZCOT01Eiv9XR0IrVLRswM5pANEK+y6cimdJBd+Enc/r1I3+Prz/5V5hauICA7KMfZxMVR5PAN49NrRtwa9dvIJcidiooYMtAH2l4ADqBKXq2gtlSGn839CoeHSdMW2FrhWyOQ1dX4PPhthS+5FfW9kyCWzrrdIUXkGmJIhsLccLEEbBzY/sohewY9vS8kyxNgiNczETbfv8bBPyZp877C+V8O3vP8NwwtvvejR2hjVBIiKWSY6KLrGN9eBVNWgktvh4YJYEvxpNJ4w8sjOGhc4cwkRzdfGjq0Ipg1CsiYDY0NfTTxlDjxb72AVTSpFV0cVa1rMLSUgF2sYwIQX4lSg/KBR0NGmlGKIYfkf8ZpZncqlm8D+USWcd0sYjTC08SL5zA7133R1gXvAXv6n0fOprjaGqmqDSo8H0XJsN+JEMB+CWVbn63rKbK/AOvWwwOd1WClwPbbnWmkyuzrj3OYvVqC2HLbedP51kqJJHPTlHckOMlwYTOGZKovQGqXNM44NdNPSLYEjKFHF4Y/jGGDn6fXNUkp0otvjzHoHMY2NJwAyJWF1m2LCy+WRcRM+RDpKYQoVyp5n5fWxwrMFZMwNubNp5RFOXpdL5ovGvLXSTEVrRSGkMOGOn5HPyUGqkUTabJFwtl8k0hiqL9AWQrjGIkHDtI2svy6DRpE5nzQ3NPYDr1Ah64/ldxe/8WpGaKSKUqlDcLWNfWwzeNNAW2SHuABOyDZS2rf6vSSB575Arcc8wOn1t7aNeowhq75LZiosg9ayQxPfhdaIU0vcabdhhhFii8bmjIRwnRCzFBUiKFpJ3G94lcmWGd9ixnvRZbBjuWGkNzhlK55Az5aZsv1mPfSSczrpB/K5XzkenUaBtWYKyYgH/z3n2pmzZf/43ZzMLZV44exG39m7AmCjKtDUiSX85PphBtUCD5fJhbMiAVC2j0U6KvEf6csciEVYiooFw4oCCbFTG/pOKxocfx3Cv/HefPfI3AjgKlXWFMzZegp6NEKGzggc+q6GqKrDM80KoSEJYnKMuBFj1+kGmRbbsL36rFHG4xgnOzvD7SrO2EYfOemMxnfu21szg4lySolZlwUT9y+uwbKipLphjSbVNx9sG0WdUHAs0ESYZUvlaLCZLt48SqRb577Ac4ljgOTaC00HSWxQbIX7PvWCjryoW5U01YgbFiAmZjx469x66/ets/naBI9+kDj2DsxENQNdJYVUNiQYe1ROBHTCUySEV6SUKTEEEDaa5GsF0yJ2BhiXw0kTSdjRL8NJMzOQ0Pj47iT08cgkmutrtJwKaBCLIYRa+/H3vX7UWCzGeRomCxVoDlprsEHoga3/zKdLV7uRK7pFL1L5aR/Q7Z4EwQm3cWINAjTumO6hTEU6hn+kOK/frfnytkw7ZpqiLXcieaZ5OHJ0QE7LDAjQufFTo0RiCQObZIa9lnsdrgJqWdofW88wGheSuy6ceKCvjONXeWb9103d+u6u0+8eTYRfyPA+dgMf8bU3jJzPxEGnoqjViTRpbbj7DcizwhXi0Btts2oVymjJlEBcVsiVISG90tCuWiGtIk3bklYGZRRyqtE7iRhZkbxC1hC+fnjvNVhU6ZkNviwXLua2S6r2reSuR8obp9ju0eV6vkpP8Nh/Bng88Bbk5tvrxFI/SNoWYa24vJ9c8EuJhEILxBgzOFjJ9t1RSUw2jzd/DWEhVL53XiIQ5kmHxZKovMne4EjpWw+cpKQvjEGE3KAAWblBuXzBWRzYoKmI0Pv3vf/KZ1Wz4VbGg8m5Nke3EyDztXgj9GWulrgr/YBoOE6AtI6GrsI59Mgp/MIlgpoCXCut8EyOTKmJgnQeeLaA4Y6CFTH/OzHUdVCtRkErKI16aG8JdPfhVzxQThyc5yh+VlrSw4ms3MI+iLYHPzduTyeSeq5qbS2aGy1sHdrpIQzrC5D95EWYAM1dnk0vZcOueYrXz5jeuSSkIlyNIoduy2zu18j6du4sSvjr0DE5kJXl4cFuOEw5OlUmMICTESusEnJE+hKO+Pa7303h2IBRqxEmPFBczG2sZdL28c2PgFSVXnGdyTmi1ALBIB76sQsN6IXb3vQn9gNWlpA1pbGwloIGHMlVGczyIqltEUloh39ZPp9WM+JRCiVaEou0QXp0zaYKAlSuZbVXFMDXBzD5cCNGsSc3wyCfTViwewu/dWshZNvCaMmW62l6FsK+6m0U465G0gzXL5iBil+KCNr9RIE40puBOGB10202zNiDQF3yDgkBKJ2PQZRb1In9eIq5tvxjWR3Tg4fJDn5uxzmtCLuK8P6xrWIpvLV9fasX2MUUni3vU7ETJaMJedvTKQrDcbn77v08VNa7Z85/qrr/8LuqRm0WS7eRZhE3gxNH0Eh4aO4ta+jVgdTKNVKBOcqXH8mlw0FmgyFBPEHJeXsKYpjlWtlCuS5iZJqxNZm4RNFzBX5giTX5OqZtMrhne4XcFJfQgZm8vMEpCyhNv67uJ8sSYFcHX7NZyarDYvtVx82nY0NygGaVLsRlAJM2Sqil97C9KIazbWp/rfYKINq9LKivtYKlQhduvDPbdg4vw4Jgvj3NyXyAwTB4kPdN6F6dkZZPJZ7n9ZZGeSe8rNHsfCySdw+NwB9DRtKGIFxlvW0v8P9z7Itl/9i0995f7SgSMvfKpQyfXZi2UxSKZ5vHwGf/fEeWzviODs9BLssAJ/gx9+wqCLRDqoZMZCVhC5GQtre7uwaJ0nx0aRKAUgZQJDMumi2yKJqxS/zxsamU5FBtdI08Gb/WIITw8/gT+45bPIzJ+F6RfRVOqggChHpHuwKjwObPB+ITIWaUK8u6cHp2eHiei23UIAZ5WERamZpqqV1/xLl2jY/nP7tafO/NVan4+OKYgYPP4MKqcO4fn0EqL9AfpdDJokUqVyGs8+cxrDUo6IGq0awbPFzKcpwPz5oSOItDZW1rduTmAFxluiwctHd8OOr21Zs/UzrfHO54sWA9mJOqQLmaDI5qm5NLIUYecJxUpN51GezRDDVAGFUjzF2Nm3nbhYGUkWXM3lUFzIQswXSMPMqjbxHJfp0jICH5ZdjZYlSmvmcrM4NXMEt7Tfhd09N6JUzLHNrZwSX1f7vePZRMkTKX3x3PdhzR+hc6ncZ7Ngq7+hl08qVdb0z75zN6YIbfJ423DAaM3byQ2ySMdThnyYgqvv6/OoEN8dotSPMWqM756j4Pup9BzCZLUYAcFoMYZ7M9ZJ8UuwCJoNB6KZsK91Disw3nIBM3O98533PLZz846PrV+95euiGkwmyUxVigzwMFgIAz+xTwJFy3kCPTKU52bnkzg/fhQvDz2G46MvQYv4WJcXlMlvzqdMZBnM7wVH3lpk26vWEKo5rrdGmXXMeW30J2gsncMaWafPeI0fZ5q13NehEO0qCfHY8eN4bHAIPpkAFcpbI2oUbcFm3q5JsBRxId1+b0nCAPA5gQn51MIL78hUUgM+1ccj8lgnsVDhAAWTlAmoNnI5izd9Mwi2lOm3BMIyClmdrwhh7oK7FcNpKRUJNi+KopjECoxfyq4rD+x4gKE+579if+WB9HeHvnZ46OBHxqYvvKdcKreIhaLqU0scn2YNQm1Z4amDQWzLuUQG1qLJa7dUv0JAhwQxokIXrKpgHb8p8Lps5j8Fp5kGzzltN/WRBBmz+RkcfvmbiOYUDE4sEbOkcT/Nz2MuAzpc0z+hkYZRcN4gOrVZjWozIW0BQtE2473r7xkwc6VishNnWNHD0xN9O4dTxz4jKkZrMSWTpq9CRUljZmIGXT0+5JPEehlsC0aKIyby0EirG4iImE2W4GsVUaLYIhwKoZRz0rnWePtQZ2dnASswfqnb6jwgcEG/9KMDf37ipcHTP744NXx7Ort4Uz6f3VRMFVUlUyIoUnW6wRKoYPk07lZNyh+zaQrXFNL6sA9O4Gyj2rbD02RmuZkvFe1a+atbcFyhQO0p4qxTMwu4SGbXq+2q9u5YnhfbbLmMs4yUVYuIFOk205Xa3b8RG8vrCIDJD7V1bn3CwmH/ty/8510HJh/9k5ge2zlVmBYiFD+spdToidNPUSagIUg+//yFAqLxEJ3HxCJlC5H2CNoDrRiVSMChMtaIGzCRGsf4ZJKlgnbU1ziIFRr/Kvsm7b3xD7N0UZ/4x5/se+HQxROdJID3LKWXbplLTF27lFpstjNFusAsbybzpjndYCUSiE58ryXztmkkSIunGF6J66WmuqaNnC3k2RNxsVGiLdvDEGYNpygAqFZYLjfpXmsCTjmyLrk0caK5k2hItOEbg4No6F5VXL+4/x0vzf7wvuHpY/dMzSTW7Qq+Ezsa9qCN8teDB48gQ5N12/YWTJ9f4jFG31UBJMeTBMlSXBInjrwUQE/rADZ39+HksWEsFOdQyZsIRWJZihuOYoXGv9rGWIJTqJxxb0MP2w9/MXg003Vx7PzNZ8ePXzudmLx6KbPUVSyUo2alFBRYDNIcoKBZdaJa0/Gbgl1jiDjXyxrASMtMtAdNsnjGtp1tY3lvaJcztpxVDPzbeL7YRBUE4RQymf3HzyzgxanvI9nsQ0suf+Nfv/Sfnp2fXwwJusrbEp9IvIrflO+ERXTmhew5bNgQw8XBRSwsVDCwtQVmKo+xkSziPXGIxH2XJ8/jd3fejb9/4QgOjL6IliYfh1SbIvHhqBo7hRUaV8zOZ/cJvERljG7f2r//iw8bN0Rbz144uHp6abI/lUmtn8/P3VcU0j1eduQ05nYCJIHVaVo1YNnxp8AlDRY8U+wJzq6tU+ITBsustJcbu+diyp4MB1Ei/x/xSSBrEyZrzPcyZpMjNVXEVCqJxyYeQSQSgRYukXCLlOfa6N/UiDAFWSdeW4RCFGdHtw/jh2ZhpRP4eek7+PnQFJnsAMo5ky11NYNa9Pg7tl43jxUaV+TWdnfe+e9YnDzObqxK4sTcLv/f7f/iqhNjB3t4WTWlIIrF4EmZsFsVXaFWTFZm3IDL3XLHrKVLTqRs83W9VWLBxa29/Q5tb+aYzgGcaPCayTDigrTUT3ApKyEwycwuTZUp6q1ApVihgVKeliY/xglDTy5OEfxK2HXAj43b4xD0Ck6/TOmSJGHLhlaAsL25WcIwumPYn5yHQC6IlRrlc/SbNDXd3bzuwMyZQgYrNN7yNOlyB4tSt7a9Oy/JAuNcuCntj/egwd9EUGaFfF47utR2vujNq8KwvAgby6NjOH7bex6vE77nh4HaY49StKrr051JQd+kgbSxsz2I1kaKttMVjJ9J4eL5POEVPvSTIDdujaAj24HRwzqKkojrb1iHLeJGDB1OoHVVI+INBKhQft/YGoBOwtVNgmhDnac++M4PPrNSBXds1MXmlGxYNuuJIfCdy/g+wgTmX0csRNiSiWm64Gqt4PpnL0Vy82D3LieaeFhOj2Ub1ZUPy/hgLBM2vAniGW9XyS3dwtJ0kRfRsdIt1msrFAugNaoSuUGgVCaPU2eSWBOO4F2bb8ZF/znc0XQbHnniKVgRC80xIlMGE5DpYImw6zyBP+wr7N7yroc3brxxEis46kbAdHENyy13nUnNYP/Rn+H65i245ar1+E5pZlkVhlMRyctzqjgzLiEU4EbXHnlguc+zv7wTrikui6iX+2bnHGwdlhSQ0dIZIJ8cpLSsDJ3Am8xCklOaxYqAcBNF6+159Iej2NP5Phw+Mozh/AX0DgQxczbBV3k0t1HAuETZASFn/R3rRm676VceFnizkpUbdSNgSZLLvJURz2spXVIs/GziFYxNHYNOvLFAKZDlUoA88rUsl7S3uWnmUbfh0IVc8Kxiw6xpN6/ZovMG5SCdo+hlSnx4ZAQPuglU8fvYjVKttIC43omfnn4ebdFOdDT2Q+lZRFOLBoU+fHJoBhem96N1YQN+coow5gYiU85S2qRTXt3mw/rQWkwU55Ep60vb1l7/+e1rb17ACo+6EXBZr+iMAuT1ymwHFEpztGAQ58j3NpMwVc7KOCkO70Tr9mHjaBV3nrVct7q3MFDNl026se4BXcE2jOWHalyxe0yNL7aRTuiYGS2iKRbG9g2d2H31bVgTb8R46ThFxzrmzuQo2CqjXBbxgn8JQ4mXURENFGZpohFh0RBXsSGyEU1aDE/PHClvGXjH97Z1btiPt2DUjYDThYTudLK13ZX7DhDhI0CEQR+sCznXTsBd+un6YtNt3cT+Ojx/dXUD2yaghSDDtDnJX+uPEsRYyjjrxV0Uq4ZROzk3q8Zga4Q7+3xopAOvb7UxU16N7x9+lLcm1sv0fTQiDJqiaCe82SyUMLmQJ7KBInHCpgN+Ey0WkfptV+FbLz1Kk6Tn8J5rbvvrvXt/bwn4BFZ6XLECZgD+CEZU0gN7EzbpH/7yzaZfC7OlIVXzaduez3XVi5thp480K5L3NK6aOjHe1dVklgeXzCK6tS1YUAtIKymsi6/GU8OPw9/E1hZXUIvMakEX99kFA0sEWqSIOPinM4/iOLEfRpA0s7EBbQ0KoXAEjeZLSI9lUCjQJFPoNTLbNhEVVjKOvbfcjqdO/xxC0D+y79/+0R9uWbflAt6aDg5XtAZLWExvkvRk/8nyuHl13zX9yYUJjM3PYWThLFSWo7KjvPYL1UBKcJo5m65g3JDl0notpxiOEfP5ch5bYlshWzN0k5Ar5xCwWb3b6/Bp1D6nRIIVdAUiQahHyZE3dAURDMj8w/JzGSwSNcgsiOIjYKSJtWwyiVDIwyAo8t2b+pDLzqEx1Gbvufb2xZZIeIMhCyznz+MtGFeygE2L0kvoBqN9Nvf4mld1Boh1UlM4Y9jVtUNe8lpjl+D6YrtKplsCLs1zl6VFE9kJ/ErrZqzufAcOD71KRoDVoDhwKNz3WdVqDuc+258iEpN48KaznUgJ4FhMsEZPROmTedZCfoquybwThVTMFmlCkBZTLtwXENBRPoNiwkpfu373j1taOr9dELInho/PJzr31Oo6V3JcsQJ2sepF9/byh/5yd+/0xaEtjOZjRXa24dY3mw7+zP2tyyx42mq7eDX/j1VmUPpjGk4ebPNOaCLmCgs4N38Wd0SDOJA/79ROGbXZYFdRL7g5so0y4c1zxAqx5YpMizXSVFZUqKqEb5NGl4tlpJJst3GBt1CWFIF8u2Fkhfh5Mb715b72Nd+LdO9+8p179rzl7RDrJw+mq5kXbb5g2ydWIYwa7uyEuzWBuFF1FZZ082TLXQDGmsoyQVuihFPTr6I/MYj5hTSRtkJ1pwAI1iVCdgrm6V9RpIDJRyyX6GxdyyqfizqyWabRXj8Q1k3LoAllQtXC081t7Y9t3XjNP63e865De666Lwf8JX4Zo24ErIiqxcpvvFyYC9Zdf2ItQ6+4D7btKplvmV55j1g1t83+BlRYaZBVgkppy2S5gAdPzxCdGEA0FHEnhpNIeQvU2LBdV6CKxC8RmlYgrxnxhZGs5CETjcloTZXytUq5RCkS7HhDy2J7c+9P/cHwP21fc/XLv3v/n6X+WPjqW2KK/7lRPwKWJMPLW/lwNapaj7WcQvReJ4kG5ADPgyusNwTBmqxmanPnVXh17KCzrpidj8xoMRbh5TV8DbGLdNlWNSKDt7s4+8P7i1RsdDZ0Ik4sU2ZukC9Ctw2xRMnQXFtL3/BA/+qnb9r57h+87+YHRhx381Pgg/ilj7oRsChKptu2uQpWcG32AqBlHK7HKtl8b6YKblq7GwenDhI8mEVHrBcx0uB8pYSg2ziVmVSFFRXItb0Qq6bZAw7t2k2UDKIKTYq+Kd5u7CkrfpXiY3FU0QL7V3Wve2H1xo2D0nTr3Pt3M9Lgt/GvOIT68cEi603Dl/mIXqQMwVUwF2cWmI/1WCCDryFCppBFqVDEeza8G/vPfwu3r9uO5HSefKVO75OqGn/J/gxs2LVOeNXqDnfyNITb51f39b/W39Y81L1q65m1pjktqdb02i1bRnZ03r0itVQrNepGwDJUa3leCi8d8oIs06qZa5fcZ6+xBWi/GH4Jn+j6HXxox2+hR+3HQ8d+DLNiuqv4RdeXe+dEtVjAFmuRtO2afAZ1bN2468t/+fvf/Jzzpn/ElTyueD7YG9WNz0zP73r0HqrIlrfO1ym+s6r5MFvR8Mzxx3FjKIoGYwELqUlUm3XYTtrkjFpVZS3xrUq42pNasMX/aRvDK2XUjw+WZMtdVrYM+IcLcniFdcsAD6t2Y+2XxhMXcfyFh3hR+lJm2uljadf8Ldz54wVoy5Gsatgr8I0/bFb1WS+jjvJgwduRDryyw2ll567t8dgeN0Uyl9VkWdwIoyDL+Ie5aSQXKkgKBJYoQs1fc813fCzPc71JtFzCnOCw+ASQ3mTjkCt11I+J5rsgeUFtraGZ5W2PY9m1GixuynFJ/spNa0MQBt0USaj1kbZrYIiwrIyH/Q2qwSr06R3KYBACSf5/Aa/0kBTye6ILVbk3tpiabQfA9g32Fn1X2wBfkr86OS1lQVCX7evgmXqv4M52AzQWfLEtCPrjfTCYTa8GdyyatlhLxbrYcYWNuhEwXVddpHCXt1RwI2fWlKw92oZN7VchqkZ5kxPL6/ds11Y7WG7K4/lt0d0Cr7boTKhtqcOKcCl77I53I+qPUYCmw20X7xwvSJYoiivSZvCXMepGwIZFebAoehA0/0chQbA9H7Z1bUGAyHunatItuHPLddiq+oDiduHhgnfMu+gWDdQiZM8X21gTGUBvYy+KlRyvHBFcK8AMO8GldsXQ6yaKrh8TLfLAxq615XfACYM1NtVTyFUKfC9Ehi2zTSmZyFgzk554F3GvMd7A1FxWK+1UdtRW7bPB0uFSpYw10V6sb16HxcwS3w3Grn6g4/3ZTmyok1E3AhYNy7Z0Z2PiKolPf3P5HJ4/8hhBj2n+RHdDO7b1bCPivoCAFsB1/duxmHW2bPcCL09zncZoHu7sCJhNgvncDHqkBQhGprovhPMWzkQJtinbqJNRNwKWlfhIyN96hNfSLIMT80THncyVYcJJdcYTk9jcsRYbu7egM9qBBmJ7EukkReFCrcuZq43VvYhRO58mKTi3cApnTz0Oo5TltVxemiQKcqUp3HMk4I+NoE5G3Qh4V/OmIxv7r/3vxaI5VyoXq9ExC5YUlQEPzvayTHMPDL6Iuze+F+/axDbTWKJI2FjW2a5G/6H2VDWXZtvnLdHx3xyZw3iuwCNv5r9LRAGWSubc7qtv/Yv3XrPzIOpk1I2A2XolVfQfX9u1+dHGSMtB2xKzXud3VIvcLUqDZJyaOo+54SdxfbCIsYmjfEdvwYU5vc2wPAjSXYIGwcuF2Oko0S1pqmu6TQq0lFx7vOfQpp6djwd8kWNr1txZF9vasVFHSBbw+Y9+afTE3FN/eOTk6VWPPvPtPz4/NX4XpU6GaZiq7WLFTFA+nx+vjBxCbvoUhucyfAcWPuxqoFQzzba7dNR7jk15t4BPlJSybtjq2u7Vz/+b2z71f9x5ww0jn/vcl68otuh/NupKwG6dVv7Qoa+cOd698W9j0Z6DTaFoYnL2zPsnF0Z254umVCyVmcbhQiiEs/M5ZA2Bl85Y7mJxvv8zr5M2yKQrTk013YqUbhGJb9uijz1rru3d+sLG/q0/IA65MR6LH73zhr2n6fPrJj3yBm8gIni7RtXp+OYTX9rxnSe+/vlwJL6wa/Puw0fPHNkyPvvi/SQ3NZeTE5oUWzKRbopF7HhJN5AtyEsBf3xRENPxgN9ozKTNytqeXQ9tXb/z5JFzL2wrFlPN99/6+//1fbd9qG587ZsNNl3fFgI+dOiQMpE91yko/sTeG/dmT4y92PDlb/+f/y2VS7UNdG55dKBn7enXjr90zezSiQcYi9jWtOUru7becHBifnjThakT9/jk2Nxv7P0P/3XXxl1Lr776k0hGMBpv33k3W+VXdxr7usEF7O1w8LYaT778ZEOmPKM2o29xz549BmtUduqVA5tE0xI23nDzqTtW31F57rnnpALGmjQzqt96694l1Of4l5ZECP8PAPgFhqae3ywAAAAASUVORK5CYII='), -'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', -'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', -'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', -'enQPSYCmDJBWtMJlV3kHBq4m2OQaTf5SbOH6eSGUqotmtAwWzw', -0, -'test', -'{"春江潮水连海平": "海上明月共潮生"}', -'m', -'m,xl', -3, -127, -0, -0 - ); diff --git a/airbyte-integrations/connectors/source-mysql/integration_tests/seed/hook.py b/airbyte-integrations/connectors/source-mysql/integration_tests/seed/hook.py new file mode 100755 index 000000000000..0fcfbd6ff847 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/integration_tests/seed/hook.py @@ -0,0 +1,213 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + +import datetime +import json +import random +import string +import sys +from contextlib import contextmanager +from datetime import timedelta +from pathlib import Path +from typing import List, Tuple + +import mysql.connector +import pytz +from mysql.connector import Error + + +support_file_path_prefix = "/connector/integration_tests" +catalog_write_file = support_file_path_prefix + "/temp/configured_catalog_copy.json" +catalog_source_file = support_file_path_prefix + "/configured_catalog_template.json" +catalog_incremental_write_file = support_file_path_prefix + "/temp/incremental_configured_catalog_copy.json" +catalog_incremental_source_file = support_file_path_prefix + "/incremental_configured_catalog_template.json" +abnormal_state_write_file = support_file_path_prefix + "/temp/abnormal_state_copy.json" +abnormal_state_file = support_file_path_prefix + "/abnormal_state_template.json" + +secret_config_file = "/connector/secrets/cat-config.json" +secret_active_config_file = support_file_path_prefix + "/temp/config_active.json" +secret_config_cdc_file = "/connector/secrets/cat-config-cdc.json" +secret_active_config_cdc_file = support_file_path_prefix + "/temp/config_cdc_active.json" + +la_timezone = pytz.timezone("America/Los_Angeles") + + +@contextmanager +def connect_to_db(): + with open(secret_config_file) as f: + secret = json.load(f) + conn = None + try: + conn = mysql.connector.connect( + database=None, user=secret["username"], password=secret["password"], host=secret["host"], port=secret["port"] + ) + print("Connected to the database successfully") + yield conn + except Error as error: + print(f"Error connecting to the database: {error}") + if conn: + conn.rollback() + sys.exit(1) + finally: + if conn: + conn.close() + print("Database connection closed") + + +def insert_records(conn, schema_name: str, table_name: str, records: List[Tuple[str, str]]) -> None: + insert_query = f"INSERT INTO {schema_name}.{table_name} (id, name) VALUES (%s, %s) ON DUPLICATE KEY UPDATE id=id" + try: + with conn.cursor() as cursor: + for record in records: + cursor.execute(insert_query, record) + conn.commit() + print("Records inserted successfully") + except Error as error: + print(f"Error inserting records: {error}") + conn.rollback() + + +def create_schema(conn, schema_name: str) -> None: + create_schema_query = f"CREATE DATABASE IF NOT EXISTS {schema_name}" + try: + with conn.cursor() as cursor: + cursor.execute(create_schema_query) + conn.commit() + print(f"Database '{schema_name}' created successfully") + except Error as error: + print(f"Error creating database: {error}") + conn.rollback() + + +def write_supporting_file(schema_name: str) -> None: + print(f"writing schema name to files: {schema_name}") + Path(support_file_path_prefix + "/temp").mkdir(parents=False, exist_ok=True) + + with open(catalog_write_file, "w") as file: + with open(catalog_source_file, "r") as source_file: + file.write(source_file.read() % schema_name) + with open(catalog_incremental_write_file, "w") as file: + with open(catalog_incremental_source_file, "r") as source_file: + file.write(source_file.read() % schema_name) + with open(abnormal_state_write_file, "w") as file: + with open(abnormal_state_file, "r") as source_file: + file.write(source_file.read() % (schema_name, schema_name)) + + with open(secret_config_file) as base_config: + secret = json.load(base_config) + secret["database"] = schema_name + with open(secret_active_config_file, "w") as f: + json.dump(secret, f) + + with open(secret_config_cdc_file) as base_config: + secret = json.load(base_config) + secret["database"] = schema_name + with open(secret_active_config_cdc_file, "w") as f: + json.dump(secret, f) + + +def create_table(conn, schema_name: str, table_name: str) -> None: + create_table_query = f""" + CREATE TABLE IF NOT EXISTS {schema_name}.{table_name} ( + id VARCHAR(100) PRIMARY KEY, + name VARCHAR(255) NOT NULL + ) + """ + try: + with conn.cursor() as cursor: + cursor.execute(create_table_query) + conn.commit() + print(f"Table '{schema_name}.{table_name}' created successfully") + except Error as error: + print(f"Error creating table: {error}") + conn.rollback() + + +def generate_schema_date_with_suffix() -> str: + current_date = datetime.datetime.now(la_timezone).strftime("%Y%m%d") + suffix = "".join(random.choices(string.ascii_lowercase + string.digits, k=8)) + return f"{current_date}_{suffix}" + + +def prepare() -> None: + schema_name = generate_schema_date_with_suffix() + print(f"schema_name: {schema_name}") + with open("./generated_schema.txt", "w") as f: + f.write(schema_name) + + +def cdc_insert(): + schema_name = load_schema_name_from_catalog() + new_records = [("4", "four"), ("5", "five")] + table_name = "id_and_name_cat" + with connect_to_db() as conn: + insert_records(conn, schema_name, table_name, new_records) + + +def setup(): + schema_name = load_schema_name_from_catalog() + write_supporting_file(schema_name) + table_name = "id_and_name_cat" + records = [("1", "one"), ("2", "two"), ("3", "three")] + with connect_to_db() as conn: + create_schema(conn, schema_name) + create_table(conn, schema_name, table_name) + insert_records(conn, schema_name, table_name, records) + + +def load_schema_name_from_catalog(): + with open("./generated_schema.txt", "r") as f: + return f.read() + + +def delete_schemas_with_prefix(conn, date_prefix): + query = f""" + SELECT schema_name + FROM information_schema.schemata + WHERE schema_name LIKE '{date_prefix}%'; + """ + try: + with conn.cursor() as cursor: + cursor.execute(query) + schemas = cursor.fetchall() + for schema in schemas: + drop_query = f"DROP DATABASE IF EXISTS {schema[0]};" + cursor.execute(drop_query) + print(f"Database {schema[0]} has been dropped.") + conn.commit() + except Error as error: + print(f"An error occurred in deleting schema: {e}") + sys.exit(1) + + +def teardown() -> None: + today = datetime.datetime.now(la_timezone) + yesterday = today - timedelta(days=1) + formatted_yesterday = yesterday.strftime("%Y%m%d") + with connect_to_db() as conn: + delete_schemas_with_prefix(conn, formatted_yesterday) + + +def final_teardown() -> None: + schema_name = load_schema_name_from_catalog() + print(f"delete database {schema_name}") + with connect_to_db() as conn: + delete_schemas_with_prefix(conn, schema_name) + + +if __name__ == "__main__": + command = sys.argv[1] + if command == "setup": + setup() + elif command == "setup_cdc": + setup() + elif command == "teardown": + teardown() + elif command == "final_teardown": + final_teardown() + elif command == "prepare": + prepare() + elif command == "insert": + cdc_insert() + else: + print(f"Unrecognized command {command}.") + exit(1) diff --git a/airbyte-integrations/connectors/source-mysql/integration_tests/seed/requirements.txt b/airbyte-integrations/connectors/source-mysql/integration_tests/seed/requirements.txt new file mode 100644 index 000000000000..97b176cab978 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/integration_tests/seed/requirements.txt @@ -0,0 +1,2 @@ +mysql-connector-python +pytz \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-mysql/metadata.yaml b/airbyte-integrations/connectors/source-mysql/metadata.yaml index bfd5d41d6c72..dabf948bc729 100644 --- a/airbyte-integrations/connectors/source-mysql/metadata.yaml +++ b/airbyte-integrations/connectors/source-mysql/metadata.yaml @@ -1,6 +1,6 @@ data: ab_internal: - ql: 300 + ql: 400 sl: 300 allowedHosts: hosts: @@ -9,7 +9,7 @@ data: connectorSubtype: database connectorType: source definitionId: 435bb9a5-7887-4809-aa58-28c27df0d7ad - dockerImageTag: 3.7.3 + dockerImageTag: 3.10.0-rc.9 dockerRepository: airbyte/source-mysql documentationUrl: https://docs.airbyte.com/integrations/sources/mysql githubIssueLabel: source-mysql @@ -17,23 +17,19 @@ data: license: ELv2 maxSecondsBetweenMessages: 7200 name: MySQL + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a registryOverrides: cloud: enabled: true oss: enabled: true - releaseStage: generally_available - releases: - breakingChanges: - 3.0.0: - message: Add default cursor for cdc - upgradeDeadline: "2023-08-17" + releaseStage: alpha supportLevel: certified tags: - language:java connectorTestSuitesOptions: - - suite: unitTests - - suite: integrationTests + - suite: acceptanceTests testSecrets: - name: SECRET_SOURCE-MYSQL_SSH-KEY-REPL__CREDS fileName: ssh-key-repl-config.json @@ -60,31 +56,21 @@ data: secretStore: type: GSM alias: airbyte-connector-testing-secret-store - - suite: acceptanceTests - testSecrets: - - name: SECRET_SOURCE-MYSQL_SSH-KEY-REPL__CREDS - fileName: ssh-key-repl-config.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store - - name: SECRET_SOURCE-MYSQL_SSH-KEY__CREDS - fileName: ssh-key-config.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store - - name: SECRET_SOURCE-MYSQL_SSH-PWD-REPL__CREDS - fileName: ssh-pwd-repl-config.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store - - name: SECRET_SOURCE-MYSQL_SSH-PWD__CREDS - fileName: ssh-pwd-config.json + - name: SECRET_SOURCE_MYSQL_ACCEPTANCE_TEST_CREDS + fileName: cat-config.json secretStore: type: GSM alias: airbyte-connector-testing-secret-store - - name: SECRET_SOURCE_MYSQL_PERFORMANCE_TEST_CREDS - fileName: performance-config.json + - name: SECRET_SOURCE_MYSQL_ACCEPTANCE_TEST_CDC_CREDS + fileName: cat-config-cdc.json secretStore: type: GSM alias: airbyte-connector-testing-secret-store + releases: + breakingChanges: + 3.0.0: + message: Add default cursor for cdc + upgradeDeadline: "2023-08-17" + rolloutConfiguration: + enableProgressiveRollout: true metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/MySqlQueryUtils.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/MySqlQueryUtils.java deleted file mode 100644 index adf8a108a921..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/MySqlQueryUtils.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -import static io.airbyte.cdk.integrations.source.relationaldb.RelationalDbQueryUtils.getFullyQualifiedTableNameWithQuoting; -import static io.airbyte.cdk.integrations.source.relationaldb.RelationalDbQueryUtils.getIdentifierWithQuoting; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import io.airbyte.cdk.db.jdbc.JdbcDatabase; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.cdk.integrations.source.relationaldb.CursorInfo; -import io.airbyte.cdk.integrations.source.relationaldb.state.StateManager; -import io.airbyte.integrations.source.mysql.internal.models.CursorBasedStatus; -import io.airbyte.integrations.source.mysql.internal.models.InternalModels.StateType; -import io.airbyte.protocol.models.AirbyteStreamNameNamespacePair; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; -import java.sql.SQLException; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MySqlQueryUtils { - - private static final Logger LOGGER = LoggerFactory.getLogger(MySqlQueryUtils.class); - - public record TableSizeInfo(Long tableSize, Long avgRowLength) {} - - public static final String TABLE_ESTIMATE_QUERY = """ - SELECT - (data_length + index_length) as %s, - AVG_ROW_LENGTH as %s - FROM - information_schema.tables - WHERE - table_schema = '%s' AND table_name = '%s'; - """; - - public static final String MAX_PK_VALUE_QUERY = - """ - SELECT MAX(%s) as %s FROM %s; - """; - - public static final String SHOW_TABLE_QUERY = - """ - SHOW TABLE STATUS; - """; - public static final String MAX_CURSOR_VALUE_QUERY = - """ - SELECT %s FROM %s WHERE %s = (SELECT MAX(%s) FROM %s); - """; - - public static final String MAX_PK_COL = "max_pk"; - public static final String TABLE_SIZE_BYTES_COL = "TotalSizeBytes"; - public static final String AVG_ROW_LENGTH = "AVG_ROW_LENGTH"; - - // Returns a set of all storage engines used by the configured tables - public static Set getStorageEngines(final JdbcDatabase database, final Set streamNames) { - try { - // Construct the query. - final List jsonNodes = database.bufferedResultSetQuery(conn -> conn.createStatement().executeQuery(SHOW_TABLE_QUERY), - resultSet -> JdbcUtils.getDefaultSourceOperations().rowToJson(resultSet)); - final Set storageEngines = new HashSet<>(); - if (jsonNodes != null) { - jsonNodes.stream().forEach(jsonNode -> { - final String tableName = jsonNode.get("Name").asText(); - final String storageEngine = jsonNode.get("Engine").asText(); - if (streamNames.contains(tableName)) { - storageEngines.add(storageEngine); - } - }); - } - return storageEngines; - } catch (final Exception e) { - LOGGER.info("Storage engines could not be determined"); - return Collections.emptySet(); - } - } - - public static String getMaxPkValueForStream(final JdbcDatabase database, - final ConfiguredAirbyteStream stream, - final String pkFieldName, - final String quoteString) { - final String name = stream.getStream().getName(); - final String namespace = stream.getStream().getNamespace(); - final String fullTableName = - getFullyQualifiedTableNameWithQuoting(namespace, name, quoteString); - final String maxPkQuery = String.format(MAX_PK_VALUE_QUERY, - getIdentifierWithQuoting(pkFieldName, quoteString), - MAX_PK_COL, - fullTableName); - LOGGER.info("Querying for max pk value: {}", maxPkQuery); - try { - final List jsonNodes = database.bufferedResultSetQuery(conn -> conn.prepareStatement(maxPkQuery).executeQuery(), - resultSet -> JdbcUtils.getDefaultSourceOperations().rowToJson(resultSet)); - Preconditions.checkState(jsonNodes.size() == 1); - if (jsonNodes.get(0).get(MAX_PK_COL) == null) { - LOGGER.info("Max PK is null for table {} - this could indicate an empty table", fullTableName); - return null; - } - return jsonNodes.get(0).get(MAX_PK_COL).asText(); - } catch (final SQLException e) { - throw new RuntimeException(e); - } - } - - public static Map getTableSizeInfoForStreams(final JdbcDatabase database, - final List streams, - final String quoteString) { - final Map tableSizeInfoMap = new HashMap<>(); - streams.forEach(stream -> { - try { - final String name = stream.getStream().getName(); - final String namespace = stream.getStream().getNamespace(); - final String fullTableName = - getFullyQualifiedTableNameWithQuoting(name, namespace, quoteString); - final List tableEstimateResult = getTableEstimate(database, namespace, name); - - if (tableEstimateResult != null - && tableEstimateResult.size() == 1 - && tableEstimateResult.get(0).get(TABLE_SIZE_BYTES_COL) != null - && tableEstimateResult.get(0).get(AVG_ROW_LENGTH) != null) { - final long tableEstimateBytes = tableEstimateResult.get(0).get(TABLE_SIZE_BYTES_COL).asLong(); - final long avgTableRowSizeBytes = tableEstimateResult.get(0).get(AVG_ROW_LENGTH).asLong(); - LOGGER.info("Stream {} size estimate is {}, average row size estimate is {}", fullTableName, tableEstimateBytes, avgTableRowSizeBytes); - final TableSizeInfo tableSizeInfo = new TableSizeInfo(tableEstimateBytes, avgTableRowSizeBytes); - final AirbyteStreamNameNamespacePair namespacePair = - new AirbyteStreamNameNamespacePair(stream.getStream().getName(), stream.getStream().getNamespace()); - tableSizeInfoMap.put(namespacePair, tableSizeInfo); - } - } catch (final Exception e) { - LOGGER.warn("Error occurred while attempting to estimate sync size", e); - } - }); - return tableSizeInfoMap; - } - - /** - * Iterates through each stream and find the max cursor value and the record count which has that - * value based on each cursor field provided by the customer per stream This information is saved in - * a Hashmap with the mapping being the AirbyteStreamNameNamespacepair -> CursorBasedStatus - * - * @param database the source db - * @param streams streams to be synced - * @param stateManager stream stateManager - * @return Map of streams to statuses - */ - public static Map getCursorBasedSyncStatusForStreams(final JdbcDatabase database, - final List streams, - final StateManager stateManager, - final String quoteString) { - - final Map cursorBasedStatusMap = new HashMap<>(); - streams.forEach(stream -> { - try { - final String name = stream.getStream().getName(); - final String namespace = stream.getStream().getNamespace(); - final String fullTableName = - getFullyQualifiedTableNameWithQuoting(namespace, name, quoteString); - - final Optional cursorInfoOptional = - stateManager.getCursorInfo(new io.airbyte.protocol.models.v0.AirbyteStreamNameNamespacePair(name, namespace)); - if (cursorInfoOptional.isEmpty()) { - throw new RuntimeException(String.format("Stream %s was not provided with an appropriate cursor", stream.getStream().getName())); - } - - LOGGER.info("Querying max cursor value for {}.{}", namespace, name); - - final String cursorField = cursorInfoOptional.get().getCursorField(); - LOGGER.info("cursor field", cursorField); - final String quotedCursorField = getIdentifierWithQuoting(cursorField, quoteString); - final String cursorBasedSyncStatusQuery = String.format(MAX_CURSOR_VALUE_QUERY, - quotedCursorField, - fullTableName, - quotedCursorField, - quotedCursorField, - fullTableName); - final List jsonNodes = database.bufferedResultSetQuery(conn -> conn.prepareStatement(cursorBasedSyncStatusQuery).executeQuery(), - resultSet -> JdbcUtils.getDefaultSourceOperations().rowToJson(resultSet)); - final CursorBasedStatus cursorBasedStatus = new CursorBasedStatus(); - cursorBasedStatus.setStateType(StateType.CURSOR_BASED); - cursorBasedStatus.setVersion(2L); - cursorBasedStatus.setStreamName(name); - cursorBasedStatus.setStreamNamespace(namespace); - cursorBasedStatus.setCursorField(ImmutableList.of(cursorField)); - - if (!jsonNodes.isEmpty()) { - final JsonNode result = jsonNodes.get(0); - cursorBasedStatus.setCursor(result.get(cursorField).asText()); - cursorBasedStatus.setCursorRecordCount((long) jsonNodes.size()); - } - - cursorBasedStatusMap.put(new io.airbyte.protocol.models.v0.AirbyteStreamNameNamespacePair(name, namespace), cursorBasedStatus); - } catch (final SQLException e) { - throw new RuntimeException(e); - } - }); - - return cursorBasedStatusMap; - } - - private static List getTableEstimate(final JdbcDatabase database, final String namespace, final String name) - throws SQLException { - // Construct the table estimate query. - final String tableEstimateQuery = - String.format(TABLE_ESTIMATE_QUERY, TABLE_SIZE_BYTES_COL, AVG_ROW_LENGTH, namespace, name); - LOGGER.info("Querying for table size estimate: {}", tableEstimateQuery); - final List jsonNodes = database.bufferedResultSetQuery(conn -> conn.createStatement().executeQuery(tableEstimateQuery), - resultSet -> JdbcUtils.getDefaultSourceOperations().rowToJson(resultSet)); - Preconditions.checkState(jsonNodes.size() == 1); - return jsonNodes; - } - - public static void logStreamSyncStatus(final List streams, final String syncType) { - if (streams.isEmpty()) { - LOGGER.info("No Streams will be synced via {}.", syncType); - } else { - LOGGER.info("Streams to be synced via {} : {}", syncType, streams.size()); - LOGGER.info("Streams: {}", prettyPrintConfiguredAirbyteStreamList(streams)); - } - } - - public static String prettyPrintConfiguredAirbyteStreamList(final List streamList) { - return streamList.stream().map(s -> "%s.%s".formatted(s.getStream().getNamespace(), s.getStream().getName())).collect(Collectors.joining(", ")); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/MySqlSource.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/MySqlSource.java deleted file mode 100644 index 2c3eb8f78ef7..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/MySqlSource.java +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -import static io.airbyte.cdk.db.jdbc.JdbcUtils.EQUALS; -import static io.airbyte.cdk.integrations.debezium.AirbyteDebeziumHandler.isAnyStreamIncrementalSyncMode; -import static io.airbyte.cdk.integrations.debezium.internals.DebeziumEventConverter.CDC_DELETED_AT; -import static io.airbyte.cdk.integrations.debezium.internals.DebeziumEventConverter.CDC_UPDATED_AT; -import static io.airbyte.cdk.integrations.source.jdbc.JdbcDataSourceUtils.DEFAULT_JDBC_PARAMETERS_DELIMITER; -import static io.airbyte.cdk.integrations.source.jdbc.JdbcDataSourceUtils.assertCustomParametersDontOverwriteDefaultParameters; -import static io.airbyte.integrations.source.mysql.MySqlQueryUtils.getCursorBasedSyncStatusForStreams; -import static io.airbyte.integrations.source.mysql.MySqlQueryUtils.getTableSizeInfoForStreams; -import static io.airbyte.integrations.source.mysql.MySqlQueryUtils.logStreamSyncStatus; -import static io.airbyte.integrations.source.mysql.initialsync.MySqlInitialReadUtil.convertNameNamespacePairFromV0; -import static io.airbyte.integrations.source.mysql.initialsync.MySqlInitialReadUtil.filterStreamInIncrementalMode; -import static io.airbyte.integrations.source.mysql.initialsync.MySqlInitialReadUtil.getMySqlFullRefreshInitialLoadHandler; -import static io.airbyte.integrations.source.mysql.initialsync.MySqlInitialReadUtil.getMySqlInitialLoadGlobalStateManager; -import static io.airbyte.integrations.source.mysql.initialsync.MySqlInitialReadUtil.initPairToPrimaryKeyInfoMap; -import static io.airbyte.integrations.source.mysql.initialsync.MySqlInitialReadUtil.isSavedOffsetStillPresentOnServer; -import static io.airbyte.integrations.source.mysql.initialsync.MySqlInitialReadUtil.streamsForInitialPrimaryKeyLoad; -import static java.util.stream.Collectors.toList; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; -import com.mysql.cj.MysqlType; -import io.airbyte.cdk.db.factory.DataSourceFactory; -import io.airbyte.cdk.db.factory.DatabaseDriver; -import io.airbyte.cdk.db.jdbc.JdbcDatabase; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.cdk.db.jdbc.StreamingJdbcDatabase; -import io.airbyte.cdk.integrations.base.IntegrationRunner; -import io.airbyte.cdk.integrations.base.Source; -import io.airbyte.cdk.integrations.base.adaptive.AdaptiveSourceRunner; -import io.airbyte.cdk.integrations.base.ssh.SshWrappedSource; -import io.airbyte.cdk.integrations.debezium.internals.RecordWaitTimeUtil; -import io.airbyte.cdk.integrations.source.jdbc.AbstractJdbcSource; -import io.airbyte.cdk.integrations.source.jdbc.JdbcDataSourceUtils; -import io.airbyte.cdk.integrations.source.jdbc.JdbcSSLConnectionUtils; -import io.airbyte.cdk.integrations.source.jdbc.JdbcSSLConnectionUtils.SslMode; -import io.airbyte.cdk.integrations.source.relationaldb.DbSourceDiscoverUtil; -import io.airbyte.cdk.integrations.source.relationaldb.InitialLoadHandler; -import io.airbyte.cdk.integrations.source.relationaldb.TableInfo; -import io.airbyte.cdk.integrations.source.relationaldb.state.NonResumableStateMessageProducer; -import io.airbyte.cdk.integrations.source.relationaldb.state.SourceStateMessageProducer; -import io.airbyte.cdk.integrations.source.relationaldb.state.StateGeneratorUtils; -import io.airbyte.cdk.integrations.source.relationaldb.state.StateManager; -import io.airbyte.cdk.integrations.source.relationaldb.state.StateManagerFactory; -import io.airbyte.cdk.integrations.source.relationaldb.streamstatus.StreamStatusTraceEmitterIterator; -import io.airbyte.commons.exceptions.ConfigErrorException; -import io.airbyte.commons.functional.CheckedConsumer; -import io.airbyte.commons.json.Jsons; -import io.airbyte.commons.map.MoreMaps; -import io.airbyte.commons.stream.AirbyteStreamStatusHolder; -import io.airbyte.commons.util.AutoCloseableIterator; -import io.airbyte.commons.util.AutoCloseableIterators; -import io.airbyte.integrations.source.mysql.cdc.CdcConfigurationHelper; -import io.airbyte.integrations.source.mysql.cursor_based.MySqlCursorBasedStateManager; -import io.airbyte.integrations.source.mysql.initialsync.MySqlInitialLoadGlobalStateManager; -import io.airbyte.integrations.source.mysql.initialsync.MySqlInitialLoadHandler; -import io.airbyte.integrations.source.mysql.initialsync.MySqlInitialLoadStateManager; -import io.airbyte.integrations.source.mysql.initialsync.MySqlInitialLoadStreamStateManager; -import io.airbyte.integrations.source.mysql.initialsync.MySqlInitialReadUtil; -import io.airbyte.integrations.source.mysql.initialsync.MySqlInitialReadUtil.CursorBasedStreams; -import io.airbyte.integrations.source.mysql.initialsync.MySqlInitialReadUtil.InitialLoadStreams; -import io.airbyte.integrations.source.mysql.internal.models.CursorBasedStatus; -import io.airbyte.protocol.models.CommonField; -import io.airbyte.protocol.models.v0.*; -import io.airbyte.protocol.models.v0.AirbyteConnectionStatus.Status; -import io.airbyte.protocol.models.v0.AirbyteStateMessage.AirbyteStateType; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.sql.SQLException; -import java.time.Instant; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import javax.sql.DataSource; -import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MySqlSource extends AbstractJdbcSource implements Source { - - public static final String TUNNEL_METHOD = "tunnel_method"; - public static final String NO_TUNNEL = "NO_TUNNEL"; - public static final String SSL_MODE = "ssl_mode"; - private static final String MODE = "mode"; - public static final String SSL_MODE_PREFERRED = "preferred"; - public static final String SSL_MODE_REQUIRED = "required"; - - private static final Logger LOGGER = LoggerFactory.getLogger(MySqlSource.class); - private static final int INTERMEDIATE_STATE_EMISSION_FREQUENCY = 10_000; - public static final String NULL_CURSOR_VALUE_WITH_SCHEMA_QUERY = - """ - SELECT (EXISTS (SELECT * from `%s`.`%s` where `%s` IS NULL LIMIT 1)) AS %s - """; - public static final String NULL_CURSOR_VALUE_WITHOUT_SCHEMA_QUERY = - """ - SELECT (EXISTS (SELECT * from %s where `%s` IS NULL LIMIT 1)) AS %s - """; - public static final String DESCRIBE_TABLE_WITHOUT_SCHEMA_QUERY = - """ - DESCRIBE %s - """; - public static final String DESCRIBE_TABLE_WITH_SCHEMA_QUERY = - """ - DESCRIBE `%s`.`%s` - """; - - public static final String DRIVER_CLASS = DatabaseDriver.MYSQL.getDriverClassName(); - public static final String CDC_LOG_FILE = "_ab_cdc_log_file"; - public static final String CDC_LOG_POS = "_ab_cdc_log_pos"; - public static final String CDC_DEFAULT_CURSOR = "_ab_cdc_cursor"; - - public static Source sshWrappedSource(final MySqlSource source) { - return new SshWrappedSource(source, JdbcUtils.HOST_LIST_KEY, JdbcUtils.PORT_LIST_KEY); - } - - private ConnectorSpecification getCloudDeploymentSpec(final ConnectorSpecification originalSpec) { - final ConnectorSpecification spec = Jsons.clone(originalSpec); - // Remove the SSL options - ((ObjectNode) spec.getConnectionSpecification().get("properties")).remove(JdbcUtils.SSL_KEY); - // Set SSL_MODE to required by default - ((ObjectNode) spec.getConnectionSpecification().get("properties").get(SSL_MODE)).put("default", SSL_MODE_REQUIRED); - return spec; - } - - @Override - public @NotNull ConnectorSpecification spec() throws Exception { - if (cloudDeploymentMode()) { - return getCloudDeploymentSpec(super.spec()); - } - return super.spec(); - } - - @Override - public AirbyteConnectionStatus check(final @NotNull JsonNode config) throws Exception { - // #15808 Disallow connecting to db with disable, prefer or allow SSL mode when connecting directly - // and not over SSH tunnel - if (cloudDeploymentMode()) { - if (config.has(TUNNEL_METHOD) - && config.get(TUNNEL_METHOD).has(TUNNEL_METHOD) - && config.get(TUNNEL_METHOD).get(TUNNEL_METHOD).asText().equals(NO_TUNNEL)) { - // If no SSH tunnel - if (config.has(SSL_MODE) && config.get(SSL_MODE).has(MODE)) { - if (Set.of(SSL_MODE_PREFERRED).contains(config.get(SSL_MODE).get(MODE).asText())) { - // Fail in case SSL mode is preferred - return new AirbyteConnectionStatus() - .withStatus(Status.FAILED) - .withMessage( - "Unsecured connection not allowed. If no SSH Tunnel set up, please use one of the following SSL modes: required, verify-ca, verify-identity"); - } - } - } - } - return super.check(config); - } - - public MySqlSource() { - super(DRIVER_CLASS, MySqlStreamingQueryConfig::new, new MySqlSourceOperations()); - } - - @Override - public boolean supportResumableFullRefresh(final JdbcDatabase database, final ConfiguredAirbyteStream airbyteStream) { - if (airbyteStream.getStream() != null && airbyteStream.getStream().getSourceDefinedPrimaryKey() != null - && !airbyteStream.getStream().getSourceDefinedPrimaryKey().isEmpty()) { - return true; - } - - return false; - } - - private MySqlInitialLoadStateManager initialLoadStateManager = null; - private boolean isSavedOffsetStillPresentOnServer = false; - - @Override - protected void initializeForStateManager(final JdbcDatabase database, - final @NotNull ConfiguredAirbyteCatalog catalog, - final @NotNull Map>> tableNameToTable, - final @NotNull StateManager stateManager) { - if (initialLoadStateManager != null) { - return; - } - final var sourceConfig = database.getSourceConfig(); - - if (isCdc(sourceConfig)) { - isSavedOffsetStillPresentOnServer = isSavedOffsetStillPresentOnServer(database, catalog, stateManager); - initialLoadStateManager = getMySqlInitialLoadGlobalStateManager(database, catalog, stateManager, tableNameToTable, getQuoteString(), - isSavedOffsetStillPresentOnServer); - } else { - final MySqlCursorBasedStateManager cursorBasedStateManager = new MySqlCursorBasedStateManager(stateManager.getRawStateMessages(), catalog); - final InitialLoadStreams initialLoadStreams = streamsForInitialPrimaryKeyLoad(cursorBasedStateManager, catalog); - initialLoadStateManager = - new MySqlInitialLoadStreamStateManager(catalog, initialLoadStreams, - initPairToPrimaryKeyInfoMap(database, catalog, tableNameToTable, getQuoteString())); - } - } - - @Override - public InitialLoadHandler getInitialLoadHandler(final JdbcDatabase database, - final ConfiguredAirbyteStream stream, - final ConfiguredAirbyteCatalog catalog, - final StateManager stateManager) { - - var sourceConfig = database.getSourceConfig(); - - if (isCdc(sourceConfig)) { - return getMySqlFullRefreshInitialLoadHandler(database, catalog, (MySqlInitialLoadGlobalStateManager) initialLoadStateManager, stateManager, - stream, Instant.now(), getQuoteString(), isSavedOffsetStillPresentOnServer) - .get(); - } else { - return new MySqlInitialLoadHandler(sourceConfig, database, new MySqlSourceOperations(), getQuoteString(), initialLoadStateManager, - Optional.empty(), - getTableSizeInfoForStreams(database, catalog.getStreams(), getQuoteString())); - } - } - - @Override - protected SourceStateMessageProducer getSourceStateProducerForNonResumableFullRefreshStream(final JdbcDatabase database) { - return new NonResumableStateMessageProducer<>(isCdc(database.getSourceConfig()), initialLoadStateManager); - } - - private static AirbyteStream overrideSyncModes(final AirbyteStream stream) { - return stream.withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL)); - } - - private static AirbyteStream removeIncrementalWithoutPk(final AirbyteStream stream) { - if (stream.getSourceDefinedPrimaryKey().isEmpty()) { - stream.getSupportedSyncModes().remove(SyncMode.INCREMENTAL); - } - - return stream; - } - - private static AirbyteStream setIncrementalToSourceDefined(final AirbyteStream stream) { - if (stream.getSupportedSyncModes().contains(SyncMode.INCREMENTAL)) { - stream.setSourceDefinedCursor(true); - } - - return stream; - } - - /* - * To prepare for Destination v2, cdc streams must have a default cursor field Cursor format: the - * airbyte [emittedAt(converted to nano seconds)] + [sync wide record counter] - */ - private static AirbyteStream setDefaultCursorFieldForCdc(final AirbyteStream stream) { - if (stream.getSupportedSyncModes().contains(SyncMode.INCREMENTAL)) { - stream.setDefaultCursorField(ImmutableList.of(CDC_DEFAULT_CURSOR)); - } - return stream; - } - - // Note: in place mutation. - private static AirbyteStream addCdcMetadataColumns(final AirbyteStream stream) { - final ObjectNode jsonSchema = (ObjectNode) stream.getJsonSchema(); - final ObjectNode properties = (ObjectNode) jsonSchema.get("properties"); - - final JsonNode numberType = Jsons.jsonNode(ImmutableMap.of("type", "number")); - final JsonNode airbyteIntegerType = Jsons.jsonNode(ImmutableMap.of("type", "number", "airbyte_type", "integer")); - final JsonNode stringType = Jsons.jsonNode(ImmutableMap.of("type", "string")); - properties.set(CDC_LOG_FILE, stringType); - properties.set(CDC_LOG_POS, numberType); - properties.set(CDC_UPDATED_AT, stringType); - properties.set(CDC_DELETED_AT, stringType); - properties.set(CDC_DEFAULT_CURSOR, airbyteIntegerType); - - return stream; - } - - @Override - public List> getCheckOperations(final JsonNode config) throws Exception { - final List> checkOperations = new ArrayList<>(super.getCheckOperations(config)); - if (isCdc(config)) { - checkOperations.addAll(CdcConfigurationHelper.getCheckOperations()); - - checkOperations.add(database -> { - RecordWaitTimeUtil.checkFirstRecordWaitTime(config); - CdcConfigurationHelper.checkServerTimeZoneConfig(config); - }); - } - return checkOperations; - } - - @Override - public AirbyteCatalog discover(final JsonNode config) { - final AirbyteCatalog catalog = super.discover(config); - - if (isCdc(config)) { - final List streams = catalog.getStreams().stream() - .map(MySqlSource::overrideSyncModes) - .map(MySqlSource::removeIncrementalWithoutPk) - .map(MySqlSource::setIncrementalToSourceDefined) - .map(MySqlSource::setDefaultCursorFieldForCdc) - .map(MySqlSource::addCdcMetadataColumns) - .collect(toList()); - - catalog.setStreams(streams); - } - - return catalog; - } - - @Override - public Collection> readStreams(final JsonNode config, - final ConfiguredAirbyteCatalog catalog, - final JsonNode state) - throws Exception { - final AirbyteStateType supportedStateType = getSupportedStateType(config); - final StateManager stateManager = - StateManagerFactory.createStateManager(supportedStateType, - StateGeneratorUtils.deserializeInitialState(state, supportedStateType), catalog); - final Instant emittedAt = Instant.now(); - - final JdbcDatabase database = createDatabase(config); - - logPreSyncDebugData(database, catalog); - - final Map>> fullyQualifiedTableNameToInfo = - discoverWithoutSystemTables(database) - .stream() - .collect(Collectors.toMap(t -> String.format("%s.%s", t.getNameSpace(), t.getName()), - Function - .identity())); - - validateCursorFieldForIncrementalTables(fullyQualifiedTableNameToInfo, catalog, database); - - initializeForStateManager(database, catalog, fullyQualifiedTableNameToInfo, stateManager); - - DbSourceDiscoverUtil.logSourceSchemaChange(fullyQualifiedTableNameToInfo, catalog, this::getAirbyteType); - - final List> incrementalIterators = - getIncrementalIterators(database, catalog, fullyQualifiedTableNameToInfo, stateManager, - emittedAt); - final List> fullRefreshIterators = - getFullRefreshIterators(database, catalog, fullyQualifiedTableNameToInfo, stateManager, - emittedAt); - final List> iteratorList = Stream - .of(incrementalIterators, fullRefreshIterators) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - - return iteratorList; - } - - @Override - protected void logPreSyncDebugData(final JdbcDatabase database, final ConfiguredAirbyteCatalog catalog) - throws SQLException { - super.logPreSyncDebugData(database, catalog); - final Set streamNames = new HashSet<>(); - for (final ConfiguredAirbyteStream stream : catalog.getStreams()) { - streamNames.add(stream.getStream().getName()); - } - final Set storageEngines = MySqlQueryUtils.getStorageEngines(database, streamNames); - LOGGER.info(String.format("Detected the following storage engines for MySQL: %s", storageEngines.toString())); - } - - @Override - public JsonNode toDatabaseConfig(final JsonNode config) { - final String encodedDatabaseName = URLEncoder.encode(config.get(JdbcUtils.DATABASE_KEY).asText(), StandardCharsets.UTF_8); - final StringBuilder jdbcUrl = new StringBuilder(String.format("jdbc:mysql://%s:%s/%s", - config.get(JdbcUtils.HOST_KEY).asText(), - config.get(JdbcUtils.PORT_KEY).asText(), - encodedDatabaseName)); - - // To fetch the result in batches, the "useCursorFetch=true" must be set. - // https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-implementation-notes.html. - // When using this approach MySql creates a temporary table which may have some effect on db - // performance. - jdbcUrl.append("?useCursorFetch=true"); - // What should happen when the driver encounters DATETIME values that are composed entirely of zeros - // https://dev.mysql.com/doc/connector-j/8.1/en/connector-j-connp-props-datetime-types-processing.html#cj-conn-prop_zeroDateTimeBehavior - jdbcUrl.append("&zeroDateTimeBehavior=CONVERT_TO_NULL"); - // ensure the return tinyint(1) is boolean - jdbcUrl.append("&tinyInt1isBit=true"); - // ensure the return year value is a Date; see the rationale - // in the setJsonField method in MySqlSourceOperations.java - jdbcUrl.append("&yearIsDateType=false"); - if (config.get(JdbcUtils.JDBC_URL_PARAMS_KEY) != null && !config.get(JdbcUtils.JDBC_URL_PARAMS_KEY).asText().isEmpty()) { - jdbcUrl.append(JdbcUtils.AMPERSAND).append(config.get(JdbcUtils.JDBC_URL_PARAMS_KEY).asText()); - } - final Map sslParameters = JdbcSSLConnectionUtils.parseSSLConfig(config); - jdbcUrl.append(JdbcUtils.AMPERSAND).append(toJDBCQueryParams(sslParameters)); - - final ImmutableMap.Builder configBuilder = ImmutableMap.builder() - .put(JdbcUtils.USERNAME_KEY, config.get(JdbcUtils.USERNAME_KEY).asText()) - .put(JdbcUtils.JDBC_URL_KEY, jdbcUrl.toString()); - - configBuilder.putAll(sslParameters); - - if (config.has(JdbcUtils.PASSWORD_KEY)) { - configBuilder.put(JdbcUtils.PASSWORD_KEY, config.get(JdbcUtils.PASSWORD_KEY).asText()); - } - return Jsons.jsonNode(configBuilder.build()); - } - - /** - * Generates SSL related query parameters from map of parsed values. - * - * @apiNote Different connector may need an override for specific implementation - * @param sslParams - * @return SSL portion of JDBC question params or and empty string - */ - private String toJDBCQueryParams(final Map sslParams) { - return Objects.isNull(sslParams) ? "" - : sslParams.entrySet() - .stream() - .map((entry) -> { - if (entry.getKey().equals(SSL_MODE)) { - return entry.getKey() + EQUALS + toSslJdbcParam(SslMode.valueOf(entry.getValue())); - } else { - return entry.getKey() + EQUALS + entry.getValue(); - } - }) - .collect(Collectors.joining(JdbcUtils.AMPERSAND)); - } - - private static boolean isCdc(final JsonNode config) { - if (config.hasNonNull("replication_method")) { - if (config.get("replication_method").isTextual()) { - return ReplicationMethod.valueOf(config.get("replication_method").asText()) - .equals(ReplicationMethod.CDC); - } else if (config.get("replication_method").isObject()) { - return config.get("replication_method").get("method").asText() - .equals(ReplicationMethod.CDC.name()); - } - } - return false; - } - - @Override - protected AirbyteStateType getSupportedStateType(final JsonNode config) { - return isCdc(config) ? AirbyteStateType.GLOBAL : AirbyteStateType.STREAM; - } - - @Override - public List> getIncrementalIterators(final JdbcDatabase database, - final ConfiguredAirbyteCatalog catalog, - final Map>> tableNameToTable, - final StateManager stateManager, - final Instant emittedAt) { - - final JsonNode sourceConfig = database.getSourceConfig(); - if (isCdc(sourceConfig) && isAnyStreamIncrementalSyncMode(catalog)) { - LOGGER.info("Using PK + CDC"); - return MySqlInitialReadUtil.getCdcReadIterators(database, catalog, tableNameToTable, stateManager, - (MySqlInitialLoadGlobalStateManager) initialLoadStateManager, emittedAt, - getQuoteString(), isSavedOffsetStillPresentOnServer); - } else { - if (isAnyStreamIncrementalSyncMode(catalog)) { - LOGGER.info("Syncing via Primary Key"); - final MySqlCursorBasedStateManager cursorBasedStateManager = new MySqlCursorBasedStateManager(stateManager.getRawStateMessages(), catalog); - final InitialLoadStreams initialLoadStreams = - filterStreamInIncrementalMode(streamsForInitialPrimaryKeyLoad(cursorBasedStateManager, catalog)); - final Map pairToCursorBasedStatus = - getCursorBasedSyncStatusForStreams(database, initialLoadStreams.streamsForInitialLoad(), stateManager, getQuoteString()); - final CursorBasedStreams cursorBasedStreams = - new CursorBasedStreams(MySqlInitialReadUtil.identifyStreamsForCursorBased(catalog, initialLoadStreams.streamsForInitialLoad()), - pairToCursorBasedStatus); - - logStreamSyncStatus(initialLoadStreams.streamsForInitialLoad(), "Primary Key"); - logStreamSyncStatus(cursorBasedStreams.streamsForCursorBased(), "Cursor"); - - final MySqlInitialLoadHandler initialLoadHandler = - new MySqlInitialLoadHandler(sourceConfig, database, new MySqlSourceOperations(), getQuoteString(), initialLoadStateManager, - Optional.of(namespacePair -> Jsons.jsonNode(pairToCursorBasedStatus.get(convertNameNamespacePairFromV0(namespacePair)))), - getTableSizeInfoForStreams(database, catalog.getStreams(), getQuoteString())); - // Cursor based incremental iterators are decorated with start and complete status traces - final List> initialLoadIterator = new ArrayList<>(initialLoadHandler.getIncrementalIterators( - new ConfiguredAirbyteCatalog().withStreams(initialLoadStreams.streamsForInitialLoad()), - tableNameToTable, - emittedAt, true, true, Optional.empty())); - - // Build Cursor based iterator - final List> cursorBasedIterator = - new ArrayList<>(super.getIncrementalIterators(database, - new ConfiguredAirbyteCatalog().withStreams( - cursorBasedStreams.streamsForCursorBased()), - tableNameToTable, - cursorBasedStateManager, emittedAt)); - - return Stream.of(initialLoadIterator, cursorBasedIterator).flatMap(Collection::stream).collect(Collectors.toList()); - } - } - - LOGGER.info("using CDC: {}", false); - return super.getIncrementalIterators(database, catalog, tableNameToTable, stateManager, - emittedAt); - } - - @Override - public Set getExcludedInternalNameSpaces() { - return Set.of( - "information_schema", - "mysql", - "performance_schema", - "sys"); - } - - @Override - protected boolean verifyCursorColumnValues(final JdbcDatabase database, final String schema, final String tableName, final String columnName) - throws SQLException { - final boolean nullValExist; - final String resultColName = "nullValue"; - final String descQuery = schema == null || schema.isBlank() - ? String.format(DESCRIBE_TABLE_WITHOUT_SCHEMA_QUERY, tableName) - : String.format(DESCRIBE_TABLE_WITH_SCHEMA_QUERY, schema, tableName); - final List tableRows = database.bufferedResultSetQuery(conn -> conn.createStatement() - .executeQuery(descQuery), - resultSet -> JdbcUtils.getDefaultSourceOperations().rowToJson(resultSet)); - - Optional field = Optional.empty(); - String nullableColumnName = ""; - for (final JsonNode tableRow : tableRows) { - LOGGER.info("MySQL Table Structure {}, {}, {}", tableRow.toString(), schema, tableName); - if (tableRow.get("Field") != null && tableRow.get("Field").asText().equalsIgnoreCase(columnName)) { - field = Optional.of(tableRow); - nullableColumnName = "Null"; - } else if (tableRow.get("COLUMN_NAME") != null && tableRow.get("COLUMN_NAME").asText().equalsIgnoreCase(columnName)) { - field = Optional.of(tableRow); - nullableColumnName = "IS_NULLABLE"; - } - } - if (field.isPresent()) { - final JsonNode jsonNode = field.get(); - final JsonNode isNullable = jsonNode.get(nullableColumnName); - if (isNullable != null) { - if (isNullable.asText().equalsIgnoreCase("YES")) { - final String query = schema == null || schema.isBlank() - ? String.format(NULL_CURSOR_VALUE_WITHOUT_SCHEMA_QUERY, - tableName, columnName, resultColName) - : String.format(NULL_CURSOR_VALUE_WITH_SCHEMA_QUERY, - schema, tableName, columnName, resultColName); - - LOGGER.debug("null value query: {}", query); - final List jsonNodes = database.bufferedResultSetQuery(conn -> conn.createStatement().executeQuery(query), - resultSet -> JdbcUtils.getDefaultSourceOperations().rowToJson(resultSet)); - Preconditions.checkState(jsonNodes.size() == 1); - nullValExist = convertToBoolean(jsonNodes.get(0).get(resultColName).toString()); - LOGGER.info("null cursor value for MySQL source : {}, shema {} , tableName {}, columnName {} ", nullValExist, schema, tableName, - columnName); - } - } - } - // return !nullValExist; - // will enable after we have sent comms to users this affects - return true; - } - - private boolean convertToBoolean(final String value) { - return "1".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value); - } - - private boolean cloudDeploymentMode() { - return AdaptiveSourceRunner.CLOUD_MODE.equalsIgnoreCase(getFeatureFlags().deploymentMode()); - } - - @Override - protected int getStateEmissionFrequency() { - return INTERMEDIATE_STATE_EMISSION_FREQUENCY; - } - - public static String toSslJdbcParam(final SslMode sslMode) { - final var result = switch (sslMode) { - case DISABLED, PREFERRED, REQUIRED, VERIFY_CA, VERIFY_IDENTITY -> sslMode.name(); - default -> throw new IllegalArgumentException("unexpected ssl mode"); - }; - return result; - } - - @Override - public JdbcDatabase createDatabase(final JsonNode sourceConfig) throws SQLException { - // return super.createDatabase(sourceConfig, this::getConnectionProperties); - final JsonNode jdbcConfig = toDatabaseConfig(sourceConfig); - final Map connectionProperties = this.getConnectionProperties(sourceConfig); - // Create the data source - final DataSource dataSource = DataSourceFactory.create( - jdbcConfig.has(JdbcUtils.USERNAME_KEY) ? jdbcConfig.get(JdbcUtils.USERNAME_KEY).asText() : null, - jdbcConfig.has(JdbcUtils.PASSWORD_KEY) ? jdbcConfig.get(JdbcUtils.PASSWORD_KEY).asText() : null, - driverClassName, - jdbcConfig.get(JdbcUtils.JDBC_URL_KEY).asText(), - connectionProperties, - getConnectionTimeout(connectionProperties, driverClassName)); - // Record the data source so that it can be closed. - dataSources.add(dataSource); - - final JdbcDatabase database = new StreamingJdbcDatabase( - dataSource, - sourceOperations, - streamingQueryConfigProvider); - - setQuoteString((getQuoteString() == null ? database.getMetaData().getIdentifierQuoteString() : getQuoteString())); - database.setSourceConfig(sourceConfig); - database.setDatabaseConfig(jdbcConfig); - return database; - } - - public Map getConnectionProperties(final JsonNode config) { - final Map customProperties = - config.has(JdbcUtils.JDBC_URL_PARAMS_KEY) - ? parseJdbcParameters(config.get(JdbcUtils.JDBC_URL_PARAMS_KEY).asText(), DEFAULT_JDBC_PARAMETERS_DELIMITER) - : new HashMap<>(); - final Map defaultProperties = JdbcDataSourceUtils.getDefaultConnectionProperties(config); - assertCustomParametersDontOverwriteDefaultParameters(customProperties, defaultProperties); - return MoreMaps.merge(customProperties, defaultProperties); - } - - public static Map parseJdbcParameters(final String jdbcPropertiesString, final String delimiter) { - final Map parameters = new HashMap<>(); - if (!jdbcPropertiesString.isBlank()) { - final String[] keyValuePairs = jdbcPropertiesString.split(delimiter); - for (final String kv : keyValuePairs) { - final String[] split = kv.split("="); - if (split.length == 2) { - parameters.put(split[0], split[1]); - } else if (split.length == 3 && kv.contains("sessionVariables")) { - parameters.put(split[0], split[1] + "=" + split[2]); - } else { - throw new ConfigErrorException( - "jdbc_url_params must be formatted as 'key=value' pairs separated by the symbol '&'. (example: key1=value1&key2=value2&key3=value3). Got " - + jdbcPropertiesString); - } - } - } - return parameters; - } - - public static void main(final String[] args) throws Exception { - final Source source = MySqlSource.sshWrappedSource(new MySqlSource()); - final MySqlSourceExceptionHandler exceptionHandler = new MySqlSourceExceptionHandler(); - LOGGER.info("starting source: {}", MySqlSource.class); - new IntegrationRunner(source).run(args, exceptionHandler); - LOGGER.info("completed source: {}", MySqlSource.class); - } - - public enum ReplicationMethod { - STANDARD, - CDC - } - - @NotNull - @Override - public AutoCloseableIterator augmentWithStreamStatus(@NotNull final ConfiguredAirbyteStream airbyteStream, - @NotNull final AutoCloseableIterator streamItrator) { - final var pair = - new io.airbyte.protocol.models.AirbyteStreamNameNamespacePair(airbyteStream.getStream().getName(), airbyteStream.getStream().getNamespace()); - final var starterStatus = - new StreamStatusTraceEmitterIterator(new AirbyteStreamStatusHolder(pair, AirbyteStreamStatusTraceMessage.AirbyteStreamStatus.STARTED)); - final var completeStatus = - new StreamStatusTraceEmitterIterator(new AirbyteStreamStatusHolder(pair, AirbyteStreamStatusTraceMessage.AirbyteStreamStatus.COMPLETE)); - return AutoCloseableIterators.concatWithEagerClose(starterStatus, streamItrator, completeStatus); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/MySqlSourceOperations.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/MySqlSourceOperations.java deleted file mode 100644 index c322ebb2ed60..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/MySqlSourceOperations.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -import static com.mysql.cj.MysqlType.BIGINT; -import static com.mysql.cj.MysqlType.BIGINT_UNSIGNED; -import static com.mysql.cj.MysqlType.DATE; -import static com.mysql.cj.MysqlType.DATETIME; -import static com.mysql.cj.MysqlType.DECIMAL; -import static com.mysql.cj.MysqlType.DECIMAL_UNSIGNED; -import static com.mysql.cj.MysqlType.DOUBLE; -import static com.mysql.cj.MysqlType.DOUBLE_UNSIGNED; -import static com.mysql.cj.MysqlType.FLOAT; -import static com.mysql.cj.MysqlType.FLOAT_UNSIGNED; -import static com.mysql.cj.MysqlType.INT; -import static com.mysql.cj.MysqlType.INT_UNSIGNED; -import static com.mysql.cj.MysqlType.LONGTEXT; -import static com.mysql.cj.MysqlType.MEDIUMINT; -import static com.mysql.cj.MysqlType.MEDIUMINT_UNSIGNED; -import static com.mysql.cj.MysqlType.MEDIUMTEXT; -import static com.mysql.cj.MysqlType.SMALLINT; -import static com.mysql.cj.MysqlType.SMALLINT_UNSIGNED; -import static com.mysql.cj.MysqlType.TEXT; -import static com.mysql.cj.MysqlType.TIME; -import static com.mysql.cj.MysqlType.TIMESTAMP; -import static com.mysql.cj.MysqlType.TINYINT; -import static com.mysql.cj.MysqlType.TINYINT_UNSIGNED; -import static com.mysql.cj.MysqlType.TINYTEXT; -import static com.mysql.cj.MysqlType.VARCHAR; -import static com.mysql.cj.MysqlType.YEAR; -import static io.airbyte.cdk.db.jdbc.JdbcConstants.INTERNAL_COLUMN_NAME; -import static io.airbyte.cdk.db.jdbc.JdbcConstants.INTERNAL_COLUMN_SIZE; -import static io.airbyte.cdk.db.jdbc.JdbcConstants.INTERNAL_COLUMN_TYPE; -import static io.airbyte.cdk.db.jdbc.JdbcConstants.INTERNAL_COLUMN_TYPE_NAME; -import static io.airbyte.cdk.db.jdbc.JdbcConstants.INTERNAL_DECIMAL_DIGITS; -import static io.airbyte.cdk.db.jdbc.JdbcConstants.INTERNAL_SCHEMA_NAME; -import static io.airbyte.cdk.db.jdbc.JdbcConstants.INTERNAL_TABLE_NAME; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.NullNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.mysql.cj.MysqlType; -import com.mysql.cj.jdbc.result.ResultSetMetaData; -import com.mysql.cj.result.Field; -import io.airbyte.cdk.db.SourceOperations; -import io.airbyte.cdk.db.jdbc.AbstractJdbcCompatibleSourceOperations; -import io.airbyte.cdk.db.jdbc.AirbyteRecordData; -import io.airbyte.integrations.source.mysql.initialsync.CdcMetadataInjector; -import io.airbyte.protocol.models.JsonSchemaType; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.OffsetDateTime; -import java.time.format.DateTimeParseException; -import java.util.Optional; -import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MySqlSourceOperations extends AbstractJdbcCompatibleSourceOperations implements SourceOperations { - - private static final Logger LOGGER = LoggerFactory.getLogger(MySqlSourceOperations.class); - private static final Set ALLOWED_CURSOR_TYPES = Set.of(TINYINT, TINYINT_UNSIGNED, SMALLINT, - SMALLINT_UNSIGNED, MEDIUMINT, MEDIUMINT_UNSIGNED, INT, INT_UNSIGNED, BIGINT, BIGINT_UNSIGNED, - FLOAT, FLOAT_UNSIGNED, DOUBLE, DOUBLE_UNSIGNED, DECIMAL, DECIMAL_UNSIGNED, DATE, DATETIME, TIMESTAMP, - TIME, YEAR, VARCHAR, TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT); - - private final Optional metadataInjector; - - public MySqlSourceOperations() { - super(); - this.metadataInjector = Optional.empty(); - } - - public MySqlSourceOperations(final Optional metadataInjector) { - super(); - this.metadataInjector = metadataInjector; - } - - @Override - public AirbyteRecordData convertDatabaseRowToAirbyteRecordData(final ResultSet queryContext) throws SQLException { - final AirbyteRecordData recordData = super.convertDatabaseRowToAirbyteRecordData(queryContext); - final ObjectNode jsonNode = (ObjectNode) recordData.rawRowData(); - if (!metadataInjector.isPresent()) { - return recordData; - } - metadataInjector.get().inject(jsonNode); - return new AirbyteRecordData(jsonNode, recordData.meta()); - } - - /** - * @param colIndex 1-based column index. - */ - @Override - public void copyToJsonField(final ResultSet resultSet, final int colIndex, final ObjectNode json) throws SQLException { - final ResultSetMetaData metaData = (ResultSetMetaData) resultSet.getMetaData(); - final Field field = metaData.getFields()[colIndex - 1]; - final String columnName = field.getName(); - final MysqlType columnType = field.getMysqlType(); - - // Attempt to access the column. this allows us to know if it is null before we do - // type-specific parsing. If the column is null, we will populate the null value and skip attempting - // to - // parse the column value. - resultSet.getObject(colIndex); - if (resultSet.wasNull()) { - json.putNull(columnName); - } else { - // https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-type-conversions.html - switch (columnType) { - case BIT -> { - if (field.getLength() == 1L) { - // BIT(1) is boolean - putBoolean(json, columnName, resultSet, colIndex); - } else { - putBinary(json, columnName, resultSet, colIndex); - } - } - case BOOLEAN -> putBoolean(json, columnName, resultSet, colIndex); - case TINYINT -> { - if (field.getLength() == 1L) { - // TINYINT(1) is boolean - putBoolean(json, columnName, resultSet, colIndex); - } else { - putShortInt(json, columnName, resultSet, colIndex); - } - } - case TINYINT_UNSIGNED, YEAR -> putShortInt(json, columnName, resultSet, colIndex); - case SMALLINT, SMALLINT_UNSIGNED, MEDIUMINT, MEDIUMINT_UNSIGNED -> putInteger(json, columnName, resultSet, colIndex); - case INT, INT_UNSIGNED -> { - if (field.isUnsigned()) { - putBigInt(json, columnName, resultSet, colIndex); - } else { - putInteger(json, columnName, resultSet, colIndex); - } - } - case BIGINT, BIGINT_UNSIGNED -> putBigInt(json, columnName, resultSet, colIndex); - case FLOAT, FLOAT_UNSIGNED -> putFloat(json, columnName, resultSet, colIndex); - case DOUBLE, DOUBLE_UNSIGNED -> putDouble(json, columnName, resultSet, colIndex); - case DECIMAL, DECIMAL_UNSIGNED -> { - if (field.getDecimals() == 0) { - putBigInt(json, columnName, resultSet, colIndex); - } else { - putBigDecimal(json, columnName, resultSet, colIndex); - } - } - case DATE -> putDate(json, columnName, resultSet, colIndex); - case DATETIME -> putTimestamp(json, columnName, resultSet, colIndex); - case TIMESTAMP -> putTimestampWithTimezone(json, columnName, resultSet, colIndex); - case TIME -> putTime(json, columnName, resultSet, colIndex); - case CHAR, VARCHAR -> putString(json, columnName, resultSet, colIndex); - case TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB, BINARY, VARBINARY, GEOMETRY -> putBinary(json, columnName, resultSet, colIndex); - case TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT, JSON, ENUM, SET -> putString(json, columnName, resultSet, colIndex); - case NULL -> json.set(columnName, NullNode.instance); - default -> putDefault(json, columnName, resultSet, colIndex); - } - } - } - - /** - * MySQL boolean is equivalent to tinyint(1). - */ - @Override - protected void putBoolean(final ObjectNode node, final String columnName, final ResultSet resultSet, final int index) throws SQLException { - node.put(columnName, resultSet.getInt(index) > 0); - } - - @Override - public void setCursorField(final PreparedStatement preparedStatement, - final int parameterIndex, - final MysqlType cursorFieldType, - final String value) - throws SQLException { - switch (cursorFieldType) { - case BIT -> setBit(preparedStatement, parameterIndex, value); - case BOOLEAN -> setBoolean(preparedStatement, parameterIndex, value); - case YEAR, TINYINT, TINYINT_UNSIGNED, SMALLINT, SMALLINT_UNSIGNED, MEDIUMINT, MEDIUMINT_UNSIGNED -> setInteger(preparedStatement, - parameterIndex, - value); - case INT, INT_UNSIGNED, BIGINT, BIGINT_UNSIGNED -> setBigInteger(preparedStatement, parameterIndex, value); - case FLOAT, FLOAT_UNSIGNED, DOUBLE, DOUBLE_UNSIGNED -> setDouble(preparedStatement, parameterIndex, value); - case DECIMAL, DECIMAL_UNSIGNED -> setDecimal(preparedStatement, parameterIndex, value); - case DATE -> setDate(preparedStatement, parameterIndex, value); - case DATETIME -> setTimestamp(preparedStatement, parameterIndex, value); - case TIMESTAMP -> setTimestampWithTimezone(preparedStatement, parameterIndex, value); - case TIME -> setTime(preparedStatement, parameterIndex, value); - case CHAR, VARCHAR, TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT, ENUM, SET -> setString(preparedStatement, parameterIndex, value); - case TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB, BINARY, VARBINARY -> setBinary(preparedStatement, parameterIndex, value); - // since cursor are expected to be comparable, handle cursor typing strictly and error on - // unrecognized types - default -> throw new IllegalArgumentException(String.format("%s cannot be used as a cursor.", cursorFieldType)); - } - } - - @Override - public MysqlType getDatabaseFieldType(final JsonNode field) { - try { - // MysqlType#getByName can handle the full MySQL type name - // e.g. MEDIUMINT UNSIGNED - final MysqlType literalType = MysqlType.getByName(field.get(INTERNAL_COLUMN_TYPE_NAME).asText()); - final int columnSize = field.get(INTERNAL_COLUMN_SIZE).asInt(); - switch (literalType) { - // BIT(1) and TINYINT(1) are interpreted as boolean - case BIT, TINYINT -> { - if (columnSize == 1) { - return MysqlType.BOOLEAN; - } - } - case YEAR -> { - return SMALLINT; - } - // When CHAR[N] and VARCHAR[N] columns have binary character set, the returned - // types are BINARY[N] and VARBINARY[N], respectively. So we don't need to - // convert them here. This is verified in MySqlSourceDatatypeTest. - case DECIMAL -> { - if (field.get(INTERNAL_DECIMAL_DIGITS) != null && field.get(INTERNAL_DECIMAL_DIGITS).asInt() == 0) { - return BIGINT; - } - } - case DECIMAL_UNSIGNED -> { - if (field.get(INTERNAL_DECIMAL_DIGITS) != null && field.get(INTERNAL_DECIMAL_DIGITS).asInt() == 0) { - return BIGINT_UNSIGNED; - } - } - } - return literalType; - } catch (final IllegalArgumentException ex) { - LOGGER.warn(String.format("Could not convert column: %s from table: %s.%s with type: %s (type name: %s). Casting to VARCHAR.", - field.get(INTERNAL_COLUMN_NAME), - field.get(INTERNAL_SCHEMA_NAME), - field.get(INTERNAL_TABLE_NAME), - field.get(INTERNAL_COLUMN_TYPE), - field.get(INTERNAL_COLUMN_TYPE_NAME))); - return MysqlType.VARCHAR; - } - } - - @Override - public boolean isCursorType(final MysqlType type) { - return ALLOWED_CURSOR_TYPES.contains(type); - } - - @Override - public JsonSchemaType getAirbyteType(final MysqlType mysqlType) { - return switch (mysqlType) { - case - // TINYINT(1) is boolean, but it should have been converted to MysqlType.BOOLEAN in {@link - // getFieldType} - TINYINT, TINYINT_UNSIGNED, SMALLINT, SMALLINT_UNSIGNED, INT, MEDIUMINT, MEDIUMINT_UNSIGNED, INT_UNSIGNED, BIGINT, BIGINT_UNSIGNED -> JsonSchemaType.INTEGER; - case FLOAT, FLOAT_UNSIGNED, DOUBLE, DOUBLE_UNSIGNED, DECIMAL, DECIMAL_UNSIGNED -> JsonSchemaType.NUMBER; - case BOOLEAN -> JsonSchemaType.BOOLEAN; - case NULL -> JsonSchemaType.NULL; - // BIT(1) is boolean, but it should have been converted to MysqlType.BOOLEAN in {@link getFieldType} - case BIT, TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB, BINARY, VARBINARY, GEOMETRY -> JsonSchemaType.STRING_BASE_64; - case TIME -> JsonSchemaType.STRING_TIME_WITHOUT_TIMEZONE; - case DATETIME -> JsonSchemaType.STRING_TIMESTAMP_WITHOUT_TIMEZONE; - case TIMESTAMP -> JsonSchemaType.STRING_TIMESTAMP_WITH_TIMEZONE; - case DATE -> JsonSchemaType.STRING_DATE; - default -> JsonSchemaType.STRING; - }; - } - - @Override - protected void setDate(final PreparedStatement preparedStatement, final int parameterIndex, final String value) throws SQLException { - try { - preparedStatement.setObject(parameterIndex, LocalDate.parse(value)); - } catch (final DateTimeParseException e) { - // This is just for backward compatibility for connectors created on versions before PR - // https://github.com/airbytehq/airbyte/pull/15504 - LOGGER.warn("Exception occurred while trying to parse value for date column the new way, trying the old way", e); - super.setDate(preparedStatement, parameterIndex, value); - } - } - - @Override - protected void setTimestamp(final PreparedStatement preparedStatement, final int parameterIndex, final String value) throws SQLException { - try { - preparedStatement.setObject(parameterIndex, LocalDateTime.parse(value)); - } catch (final DateTimeParseException e) { - // This is just for backward compatibility for connectors created on versions before PR - // https://github.com/airbytehq/airbyte/pull/15504 - LOGGER.warn("Exception occurred while trying to parse value for datetime column the new way, trying the old way", e); - preparedStatement.setObject(parameterIndex, OffsetDateTime.parse(value)); - } - } - - private void setTimestampWithTimezone(final PreparedStatement preparedStatement, final int parameterIndex, final String value) throws SQLException { - try { - preparedStatement.setObject(parameterIndex, OffsetDateTime.parse(value)); - } catch (final DateTimeParseException e) { - // This is just for backward compatibility for connectors created on versions before PR - // https://github.com/airbytehq/airbyte/pull/15504 - LOGGER.warn("Exception occurred while trying to parse value for timestamp column the new way, trying the old way", e); - preparedStatement.setObject(parameterIndex, LocalDateTime.parse(value)); - } - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/MySqlSpecConstants.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/MySqlSpecConstants.java deleted file mode 100644 index 7735470482da..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/MySqlSpecConstants.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -// Constants defined in -// airbyte-integrations/connectors/source-postgres/src/main/resources/spec.json. -public class MySqlSpecConstants { - - public static final String INVALID_CDC_CURSOR_POSITION_PROPERTY = "invalid_cdc_cursor_position_behavior"; - public static final String FAIL_SYNC_OPTION = "Fail sync"; - public static final String RESYNC_DATA_OPTION = "Re-sync data"; - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/MySqlStreamingQueryConfig.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/MySqlStreamingQueryConfig.java deleted file mode 100644 index 029cfc2c3d66..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/MySqlStreamingQueryConfig.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -import io.airbyte.cdk.db.jdbc.streaming.AdaptiveStreamingQueryConfig; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MySqlStreamingQueryConfig extends AdaptiveStreamingQueryConfig { - - private static final Logger LOGGER = LoggerFactory.getLogger(MySqlStreamingQueryConfig.class); - - public MySqlStreamingQueryConfig() { - super(); - } - - @Override - public void initialize(final Connection connection, final Statement preparedStatement) throws SQLException { - preparedStatement.setFetchSize(Integer.MIN_VALUE); - LOGGER.info("Set initial fetch size: {} rows", preparedStatement.getFetchSize()); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/CdcConfigurationHelper.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/CdcConfigurationHelper.java deleted file mode 100644 index 2f5d02caf72f..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/CdcConfigurationHelper.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.cdc; - -import com.fasterxml.jackson.databind.JsonNode; -import io.airbyte.cdk.db.jdbc.JdbcDatabase; -import io.airbyte.commons.exceptions.ConfigErrorException; -import io.airbyte.commons.functional.CheckedConsumer; -import java.sql.SQLException; -import java.time.ZoneId; -import java.util.List; -import java.util.Optional; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Helper class for MySqlSource used to check cdc configuration in case of: - *

- * 1. adding new source and checking operations #getCheckOperations method. - *

- *

- * 2. checking whether binlog required from saved cdc offset is available on mysql server - * #checkBinlog method - *

- * 3. configuring initial CDC wait time. TODO : There is a lot of shared logic for this - * functionality between MySQL and Postgres. Refactor it to reduce code de-duplication. - */ -public class CdcConfigurationHelper { - - private static final Logger LOGGER = LoggerFactory.getLogger(CdcConfigurationHelper.class); - private static final String LOG_BIN = "log_bin"; - private static final String BINLOG_FORMAT = "binlog_format"; - private static final String BINLOG_ROW_IMAGE = "binlog_row_image"; - - /** - * Method will get required configurations for cdc sync - * - * @return list of List> - */ - public static List> getCheckOperations() { - return List.of(getMasterStatusOperation(), - getCheckOperation(LOG_BIN, "ON"), - getCheckOperation(BINLOG_FORMAT, "ROW"), - getCheckOperation(BINLOG_ROW_IMAGE, "FULL")); - - } - - // Checks whether the user has REPLICATION CLIENT privilege needed to query status information about - // the binary log files, which are needed for CDC. - private static CheckedConsumer getMasterStatusOperation() { - return database -> { - try { - database.unsafeResultSetQuery( - connection -> connection.createStatement().executeQuery("SHOW MASTER STATUS"), - resultSet -> resultSet); - } catch (final SQLException e) { - throw new ConfigErrorException("Please grant REPLICATION CLIENT privilege, so that binary log files are available" - + " for CDC mode."); - } - }; - } - - private static CheckedConsumer getCheckOperation(final String name, final String value) { - return database -> { - final List result = database.queryStrings( - connection -> connection.createStatement().executeQuery(String.format("show variables where Variable_name = '%s'", name)), - resultSet -> resultSet.getString("Value")); - - if (result.size() != 1) { - throw new RuntimeException("Could not query the variable " + name); - } - - final String resultValue = result.get(0); - if (!resultValue.equalsIgnoreCase(value)) { - throw new RuntimeException(String.format("The variable \"%s\" should be set to \"%s\", but it is \"%s\"", name, value, resultValue)); - } - }; - } - - private static Optional getCdcServerTimezone(final JsonNode config) { - final JsonNode replicationMethod = config.get("replication_method"); - if (replicationMethod != null && replicationMethod.has("server_time_zone")) { - final String serverTimeZone = config.get("replication_method").get("server_time_zone").asText(); - return Optional.of(serverTimeZone); - } - return Optional.empty(); - } - - public static void checkServerTimeZoneConfig(final JsonNode config) { - final Optional serverTimeZone = getCdcServerTimezone(config); - if (serverTimeZone.isPresent()) { - final String timeZone = serverTimeZone.get(); - if (!timeZone.isEmpty() && !ZoneId.getAvailableZoneIds().contains((timeZone))) { - throw new IllegalArgumentException(String.format("Given timezone %s is not valid. The given timezone must conform to the IANNA standard. " - + "See https://www.iana.org/time-zones for more details", serverTimeZone.get())); - } - } - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/CustomMySQLTinyIntOneToBooleanConverter.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/CustomMySQLTinyIntOneToBooleanConverter.java deleted file mode 100644 index 38a4162287b7..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/CustomMySQLTinyIntOneToBooleanConverter.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.cdc; - -import io.debezium.connector.binlog.converters.TinyIntOneToBooleanConverter; -import io.debezium.spi.converter.RelationalColumn; -import org.apache.kafka.connect.data.SchemaBuilder; - -public class CustomMySQLTinyIntOneToBooleanConverter extends TinyIntOneToBooleanConverter { - - @Override - public void converterFor(final RelationalColumn field, final ConverterRegistration registration) { - if (!"TINYINT".equalsIgnoreCase(field.typeName())) { - return; - } - super.converterFor(field, registration); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySQLDateTimeConverter.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySQLDateTimeConverter.java deleted file mode 100644 index 233948c5b31b..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySQLDateTimeConverter.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.cdc; - -import io.airbyte.cdk.db.jdbc.DateTimeConverter; -import io.airbyte.cdk.db.jdbc.JdbcDatabase; -import io.airbyte.cdk.integrations.debezium.internals.DebeziumConverterUtils; -import io.debezium.spi.converter.CustomConverter; -import io.debezium.spi.converter.RelationalColumn; -import io.debezium.time.Conversions; -import java.time.LocalDate; -import java.time.LocalTime; -import java.util.Arrays; -import java.util.Locale; -import java.util.Properties; -import java.util.concurrent.TimeUnit; -import org.apache.kafka.connect.data.SchemaBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This is a custom debezium converter used in MySQL to handle the DATETIME data type. We need a - * custom converter cause by default debezium returns the DATETIME values as numbers. We need to - * convert it to proper format. Ref : - * https://debezium.io/documentation/reference/2.1/development/converters.html This is built from - * reference with {@link io.debezium.connector.mysql.converters.TinyIntOneToBooleanConverter} If you - * rename this class then remember to rename the datetime.type property value in - * {@link MySqlCdcProperties#commonProperties(JdbcDatabase)} (If you don't rename, a test would - * still fail but it might be tricky to figure out where to change the property name) - */ -public class MySQLDateTimeConverter implements CustomConverter { - - private static final Logger LOGGER = LoggerFactory.getLogger(MySQLDateTimeConverter.class); - - private final String[] DATE_TYPES = {"DATE", "DATETIME", "TIME", "TIMESTAMP"}; - - @Override - public void configure(final Properties props) {} - - @Override - public void converterFor(final RelationalColumn field, final ConverterRegistration registration) { - if (Arrays.stream(DATE_TYPES).anyMatch(s -> s.equalsIgnoreCase(field.typeName()))) { - registerDate(field, registration); - } - } - - private int getTimePrecision(final RelationalColumn field) { - return field.length().orElse(-1); - } - - // Ref : - // https://debezium.io/documentation/reference/2.1/connectors/mysql.html#mysql-temporal-types - private void registerDate(final RelationalColumn field, final ConverterRegistration registration) { - final var fieldType = field.typeName(); - - registration.register(SchemaBuilder.string().optional(), x -> { - if (x == null) { - return DebeziumConverterUtils.convertDefaultValue(field); - } - - switch (fieldType.toUpperCase(Locale.ROOT)) { - case "DATETIME": - if (x instanceof final Long l) { - if (getTimePrecision(field) <= 3) { - return DateTimeConverter.convertToTimestamp(Conversions.toInstantFromMillis(l)); - } - if (getTimePrecision(field) <= 6) { - return DateTimeConverter.convertToTimestamp(Conversions.toInstantFromMicros(l)); - } - } - return DateTimeConverter.convertToTimestamp(x); - case "DATE": - if (x instanceof final Integer i) { - return DateTimeConverter.convertToDate(LocalDate.ofEpochDay(i)); - } - return DateTimeConverter.convertToDate(x); - case "TIME": - if (x instanceof Long) { - long l = Math.multiplyExact((Long) x, TimeUnit.MICROSECONDS.toNanos(1)); - return DateTimeConverter.convertToTime(LocalTime.ofNanoOfDay(l)); - } - return DateTimeConverter.convertToTime(x); - case "TIMESTAMP": - return DateTimeConverter.convertToTimestampWithTimezone(x); - default: - throw new IllegalArgumentException("Unknown field type " + fieldType.toUpperCase(Locale.ROOT)); - } - }); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcConnectorMetadataInjector.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcConnectorMetadataInjector.java deleted file mode 100644 index d43f83e725c9..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcConnectorMetadataInjector.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.cdc; - -import static io.airbyte.cdk.integrations.debezium.internals.DebeziumEventConverter.CDC_DELETED_AT; -import static io.airbyte.cdk.integrations.debezium.internals.DebeziumEventConverter.CDC_UPDATED_AT; -import static io.airbyte.integrations.source.mysql.MySqlSource.CDC_DEFAULT_CURSOR; -import static io.airbyte.integrations.source.mysql.MySqlSource.CDC_LOG_FILE; -import static io.airbyte.integrations.source.mysql.MySqlSource.CDC_LOG_POS; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import io.airbyte.cdk.integrations.debezium.CdcMetadataInjector; -import io.airbyte.integrations.source.mysql.cdc.MySqlDebeziumStateUtil.MysqlDebeziumStateAttributes; -import java.time.Instant; -import java.util.concurrent.atomic.AtomicLong; - -public class MySqlCdcConnectorMetadataInjector implements CdcMetadataInjector { - - private final long emittedAtConverted; - - // This now makes this class stateful. Please make sure to use the same instance within a sync - private final AtomicLong recordCounter = new AtomicLong(1); - private static final long ONE_HUNDRED_MILLION = 100_000_000; - private static MySqlCdcConnectorMetadataInjector mySqlCdcConnectorMetadataInjector; - - private MySqlCdcConnectorMetadataInjector(final Instant emittedAt) { - this.emittedAtConverted = emittedAt.getEpochSecond() * ONE_HUNDRED_MILLION; - } - - public static MySqlCdcConnectorMetadataInjector getInstance(final Instant emittedAt) { - if (mySqlCdcConnectorMetadataInjector == null) { - mySqlCdcConnectorMetadataInjector = new MySqlCdcConnectorMetadataInjector(emittedAt); - } - - return mySqlCdcConnectorMetadataInjector; - } - - @Override - public void addMetaData(final ObjectNode event, final JsonNode source) { - event.put(CDC_LOG_FILE, source.get("file").asText()); - event.put(CDC_LOG_POS, source.get("pos").asLong()); - event.put(CDC_DEFAULT_CURSOR, getCdcDefaultCursor()); - } - - @Override - public void addMetaDataToRowsFetchedOutsideDebezium(final ObjectNode record, - final String transactionTimestamp, - final MysqlDebeziumStateAttributes debeziumStateAttributes) { - record.put(CDC_UPDATED_AT, transactionTimestamp); - record.put(CDC_LOG_FILE, debeziumStateAttributes.binlogFilename()); - record.put(CDC_LOG_POS, debeziumStateAttributes.binlogPosition()); - record.put(CDC_DELETED_AT, (String) null); - record.put(CDC_DEFAULT_CURSOR, getCdcDefaultCursor()); - } - - @Override - public String namespace(final JsonNode source) { - return source.get("db").asText(); - } - - @Override - public String name(JsonNode source) { - return source.get("table").asText(); - } - - private Long getCdcDefaultCursor() { - return this.emittedAtConverted + this.recordCounter.getAndIncrement(); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcPosition.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcPosition.java deleted file mode 100644 index 04cc8430142f..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcPosition.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.cdc; - -import java.util.Objects; - -public class MySqlCdcPosition { - - public final String fileName; - public final Long position; - - public MySqlCdcPosition(final String fileName, final Long position) { - this.fileName = fileName; - this.position = position; - } - - @Override - public boolean equals(final Object obj) { - if (obj instanceof final MySqlCdcPosition mySqlCdcPosition) { - return fileName.equals(mySqlCdcPosition.fileName) && mySqlCdcPosition.position.equals(position); - } - return false; - } - - @Override - public int hashCode() { - return Objects.hash(fileName, position); - } - - @Override - public String toString() { - return "FileName: " + fileName + ", Position : " + position; - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcProperties.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcProperties.java deleted file mode 100644 index 9b54d0588f67..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcProperties.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.cdc; - -import static io.airbyte.cdk.integrations.source.jdbc.JdbcSSLConnectionUtils.CLIENT_KEY_STORE_PASS; -import static io.airbyte.cdk.integrations.source.jdbc.JdbcSSLConnectionUtils.CLIENT_KEY_STORE_URL; -import static io.airbyte.cdk.integrations.source.jdbc.JdbcSSLConnectionUtils.SSL_MODE; -import static io.airbyte.cdk.integrations.source.jdbc.JdbcSSLConnectionUtils.TRUST_KEY_STORE_PASS; -import static io.airbyte.cdk.integrations.source.jdbc.JdbcSSLConnectionUtils.TRUST_KEY_STORE_URL; - -import com.fasterxml.jackson.databind.JsonNode; -import io.airbyte.cdk.db.jdbc.JdbcDatabase; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.cdk.integrations.source.jdbc.JdbcSSLConnectionUtils.SslMode; -import io.airbyte.integrations.source.mysql.MySqlSource; -import java.net.URI; -import java.nio.file.Path; -import java.time.Duration; -import java.util.Properties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MySqlCdcProperties { - - private static final Logger LOGGER = LoggerFactory.getLogger(MySqlCdcProperties.class); - private static final Duration HEARTBEAT_INTERVAL = Duration.ofSeconds(10L); - - // Test execution latency is lower when heartbeats are more frequent. - private static final Duration HEARTBEAT_INTERVAL_IN_TESTS = Duration.ofSeconds(1L); - - public static Properties getDebeziumProperties(final JdbcDatabase database) { - final JsonNode sourceConfig = database.getSourceConfig(); - final Properties props = commonProperties(database); - // snapshot config - if (sourceConfig.has("snapshot_mode")) { - // The parameter `snapshot_mode` is passed in test to simulate reading the binlog directly and skip - // initial snapshot - props.setProperty("snapshot.mode", sourceConfig.get("snapshot_mode").asText()); - } else { - // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-property-snapshot-mode - props.setProperty("snapshot.mode", "when_needed"); - } - - return props; - } - - private static Properties commonProperties(final JdbcDatabase database) { - final Properties props = new Properties(); - final JsonNode sourceConfig = database.getSourceConfig(); - final JsonNode dbConfig = database.getDatabaseConfig(); - // debezium engine configuration - props.setProperty("connector.class", "io.debezium.connector.mysql.MySqlConnector"); - - props.setProperty("database.server.id", String.valueOf(generateServerID())); - // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-boolean-values - // https://debezium.io/documentation/reference/2.2/development/converters.html - /** - * {@link io.debezium.connector.mysql.converters.TinyIntOneToBooleanConverter} - * {@link MySQLConverter} - */ - props.setProperty("converters", "boolean, datetime"); - props.setProperty("boolean.type", CustomMySQLTinyIntOneToBooleanConverter.class.getName()); - props.setProperty("datetime.type", MySQLDateTimeConverter.class.getName()); - - final Duration heartbeatInterval = - (database.getSourceConfig().has("is_test") && database.getSourceConfig().get("is_test").asBoolean()) - ? HEARTBEAT_INTERVAL_IN_TESTS - : HEARTBEAT_INTERVAL; - props.setProperty("heartbeat.interval.ms", Long.toString(heartbeatInterval.toMillis())); - - // For CDC mode, the user cannot provide timezone arguments as JDBC parameters - they are - // specifically defined in the replication_method - // config. - if (sourceConfig.get("replication_method").has("server_time_zone")) { - final String serverTimeZone = sourceConfig.get("replication_method").get("server_time_zone").asText(); - if (!serverTimeZone.isEmpty()) { - /** - * Per Debezium docs, - * https://debezium.io/documentation/reference/stable/connectors/mysql.html#mysql-temporal-types - * this property is now connectionTimeZone {@link com.mysql.cj.conf.PropertyKey#connectionTimeZone} - **/ - props.setProperty("database.connectionTimeZone", serverTimeZone); - } - } - - // Check params for SSL connection in config and add properties for CDC SSL connection - // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-property-database-ssl-mode - if (!sourceConfig.has(JdbcUtils.SSL_KEY) || sourceConfig.get(JdbcUtils.SSL_KEY).asBoolean()) { - if (dbConfig.has(SSL_MODE) && !dbConfig.get(SSL_MODE).asText().isEmpty()) { - props.setProperty("database.ssl.mode", MySqlSource.toSslJdbcParam(SslMode.valueOf(dbConfig.get(SSL_MODE).asText()))); - - if (dbConfig.has(TRUST_KEY_STORE_URL) && !dbConfig.get(TRUST_KEY_STORE_URL).asText().isEmpty()) { - props.setProperty("database.ssl.truststore", Path.of(URI.create(dbConfig.get(TRUST_KEY_STORE_URL).asText())).toString()); - } - - if (dbConfig.has(TRUST_KEY_STORE_PASS) && !dbConfig.get(TRUST_KEY_STORE_PASS).asText().isEmpty()) { - props.setProperty("database.ssl.truststore.password", dbConfig.get(TRUST_KEY_STORE_PASS).asText()); - } - - if (dbConfig.has(CLIENT_KEY_STORE_URL) && !dbConfig.get(CLIENT_KEY_STORE_URL).asText().isEmpty()) { - props.setProperty("database.ssl.keystore", Path.of(URI.create(dbConfig.get(CLIENT_KEY_STORE_URL).asText())).toString()); - } - - if (dbConfig.has(CLIENT_KEY_STORE_PASS) && !dbConfig.get(CLIENT_KEY_STORE_PASS).asText().isEmpty()) { - props.setProperty("database.ssl.keystore.password", dbConfig.get(CLIENT_KEY_STORE_PASS).asText()); - } - - } else { - props.setProperty("database.ssl.mode", "required"); - } - } - - // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-property-snapshot-locking-mode - // This is to make sure other database clients are allowed to write to a table while Airbyte is - // taking a snapshot. There is a risk involved that - // if any database client makes a schema change then the sync might break - props.setProperty("snapshot.locking.mode", "none"); - // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-property-include-schema-changes - props.setProperty("include.schema.changes", "false"); - // This to make sure that binary data represented as a base64-encoded String. - // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-property-binary-handling-mode - props.setProperty("binary.handling.mode", "base64"); - props.setProperty("database.include.list", sourceConfig.get("database").asText()); - - return props; - } - - private static int generateServerID() { - final int min = 5400; - final int max = 6400; - - final int serverId = (int) Math.floor(Math.random() * (max - min + 1) + min); - LOGGER.info("Randomly generated Server ID : " + serverId); - return serverId; - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcSavedInfoFetcher.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcSavedInfoFetcher.java deleted file mode 100644 index 7d23671afacb..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcSavedInfoFetcher.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.cdc; - -import static io.airbyte.integrations.source.mysql.cdc.MysqlCdcStateConstants.IS_COMPRESSED; -import static io.airbyte.integrations.source.mysql.cdc.MysqlCdcStateConstants.MYSQL_CDC_OFFSET; -import static io.airbyte.integrations.source.mysql.cdc.MysqlCdcStateConstants.MYSQL_DB_HISTORY; - -import com.fasterxml.jackson.databind.JsonNode; -import io.airbyte.cdk.integrations.debezium.CdcSavedInfoFetcher; -import io.airbyte.cdk.integrations.debezium.internals.AirbyteSchemaHistoryStorage.SchemaHistory; -import io.airbyte.cdk.integrations.source.relationaldb.models.CdcState; -import java.util.Optional; - -public class MySqlCdcSavedInfoFetcher implements CdcSavedInfoFetcher { - - private final JsonNode savedOffset; - private final JsonNode savedSchemaHistory; - private final boolean isSavedSchemaHistoryCompressed; - - public MySqlCdcSavedInfoFetcher(final CdcState savedState) { - final boolean savedStatePresent = savedState != null && savedState.getState() != null; - this.savedOffset = savedStatePresent ? savedState.getState().get(MYSQL_CDC_OFFSET) : null; - this.savedSchemaHistory = savedStatePresent ? savedState.getState().get(MYSQL_DB_HISTORY) : null; - this.isSavedSchemaHistoryCompressed = - savedStatePresent && savedState.getState().has(IS_COMPRESSED) && savedState.getState().get(IS_COMPRESSED).asBoolean(); - } - - @Override - public JsonNode getSavedOffset() { - return savedOffset; - } - - @Override - public SchemaHistory> getSavedSchemaHistory() { - return new SchemaHistory<>(Optional.ofNullable(savedSchemaHistory), isSavedSchemaHistoryCompressed); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcStateHandler.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcStateHandler.java deleted file mode 100644 index a6f672c7ab40..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcStateHandler.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.cdc; - -import static io.airbyte.integrations.source.mysql.cdc.MySqlDebeziumStateUtil.serialize; -import static io.airbyte.integrations.source.mysql.cdc.MysqlCdcStateConstants.COMPRESSION_ENABLED; - -import com.fasterxml.jackson.databind.JsonNode; -import io.airbyte.cdk.integrations.debezium.CdcStateHandler; -import io.airbyte.cdk.integrations.debezium.internals.AirbyteSchemaHistoryStorage.SchemaHistory; -import io.airbyte.cdk.integrations.source.relationaldb.models.CdcState; -import io.airbyte.cdk.integrations.source.relationaldb.state.StateManager; -import io.airbyte.protocol.models.v0.AirbyteMessage; -import io.airbyte.protocol.models.v0.AirbyteMessage.Type; -import io.airbyte.protocol.models.v0.AirbyteStateMessage; -import java.util.Map; -import java.util.Optional; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MySqlCdcStateHandler implements CdcStateHandler { - - private static final Logger LOGGER = LoggerFactory.getLogger(MySqlCdcStateHandler.class); - - private final StateManager stateManager; - - public MySqlCdcStateHandler(final StateManager stateManager) { - this.stateManager = stateManager; - } - - @Override - public boolean isCdcCheckpointEnabled() { - return true; - } - - @Override - public AirbyteMessage saveState(final Map offset, final SchemaHistory dbHistory) { - final JsonNode asJson = serialize(offset, dbHistory); - - LOGGER.info("debezium state: {}", asJson); - - final CdcState cdcState = new CdcState().withState(asJson); - stateManager.getCdcStateManager().setCdcState(cdcState); - /* - * Namespace pair is ignored by global state manager, but is needed for satisfy the API contract. - * Therefore, provide an empty optional. - */ - final AirbyteStateMessage stateMessage = stateManager.emit(Optional.empty()); - return new AirbyteMessage().withType(Type.STATE).withState(stateMessage); - } - - @Override - public AirbyteMessage saveStateAfterCompletionOfSnapshotOfNewStreams() { - LOGGER.info("Snapshot of new tables is complete, saving state"); - /* - * Namespace pair is ignored by global state manager, but is needed for satisfy the API contract. - * Therefore, provide an empty optional. - */ - final AirbyteStateMessage stateMessage = stateManager.emit(Optional.empty()); - return new AirbyteMessage().withType(Type.STATE).withState(stateMessage); - } - - @Override - public boolean compressSchemaHistoryForState() { - return COMPRESSION_ENABLED; - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcTargetPosition.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcTargetPosition.java deleted file mode 100644 index 201a2417b3ef..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlCdcTargetPosition.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.cdc; - -import com.fasterxml.jackson.databind.JsonNode; -import io.airbyte.cdk.db.jdbc.JdbcDatabase; -import io.airbyte.cdk.integrations.debezium.CdcTargetPosition; -import io.airbyte.cdk.integrations.debezium.internals.ChangeEventWithMetadata; -import io.airbyte.cdk.integrations.debezium.internals.SnapshotMetadata; -import io.airbyte.commons.json.Jsons; -import java.sql.SQLException; -import java.util.List; -import java.util.Map; -import java.util.stream.Stream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MySqlCdcTargetPosition implements CdcTargetPosition { - - private static final Logger LOGGER = LoggerFactory.getLogger(MySqlCdcTargetPosition.class); - private final MySqlCdcPosition targetPosition; - - public MySqlCdcTargetPosition(final String fileName, final Long position) { - this(new MySqlCdcPosition(fileName, position)); - } - - @Override - public boolean equals(final Object obj) { - if (obj instanceof final MySqlCdcTargetPosition cdcTargetPosition) { - return targetPosition.equals(cdcTargetPosition.targetPosition); - } - return false; - } - - @Override - public int hashCode() { - return targetPosition.hashCode(); - } - - @Override - public String toString() { - return targetPosition.toString(); - } - - public MySqlCdcTargetPosition(final MySqlCdcPosition targetPosition) { - this.targetPosition = targetPosition; - } - - public static MySqlCdcTargetPosition targetPosition(final JdbcDatabase database) { - try (final Stream stream = database.unsafeResultSetQuery( - connection -> connection.createStatement().executeQuery("SHOW MASTER STATUS"), - resultSet -> { - final String file = resultSet.getString("File"); - final long position = resultSet.getLong("Position"); - if (file == null || position == 0) { - return new MySqlCdcTargetPosition(null, null); - } - return new MySqlCdcTargetPosition(file, position); - })) { - final List masterStatus = stream.toList(); - final MySqlCdcTargetPosition targetPosition = masterStatus.get(0); - LOGGER.info("Target File position : " + targetPosition); - return targetPosition; - } catch (final SQLException e) { - throw new RuntimeException(e); - } - - } - - @Override - public boolean reachedTargetPosition(final ChangeEventWithMetadata changeEventWithMetadata) { - if (changeEventWithMetadata.isSnapshotEvent()) { - return false; - } else if (SnapshotMetadata.LAST == changeEventWithMetadata.getSnapshotMetadata()) { - LOGGER.info("Signalling close because Snapshot is complete"); - return true; - } else { - final String eventFileName = changeEventWithMetadata.getEventValueAsJson().get("source").get("file").asText(); - final long eventPosition = changeEventWithMetadata.getEventValueAsJson().get("source").get("pos").asLong(); - final boolean isEventPositionAfter = - eventFileName.compareTo(targetPosition.fileName) > 0 || (eventFileName.compareTo( - targetPosition.fileName) == 0 && eventPosition >= targetPosition.position); - if (isEventPositionAfter) { - LOGGER.info("Signalling close because record's binlog file : " + eventFileName + " , position : " + eventPosition - + " is after target file : " - + targetPosition.fileName + " , target position : " + targetPosition.position); - } - return isEventPositionAfter; - } - - } - - @Override - public boolean reachedTargetPosition(final MySqlCdcPosition positionFromHeartbeat) { - return positionFromHeartbeat.fileName.compareTo(targetPosition.fileName) > 0 || - (positionFromHeartbeat.fileName.compareTo(targetPosition.fileName) == 0 - && positionFromHeartbeat.position >= targetPosition.position); - } - - @Override - public boolean isHeartbeatSupported() { - return true; - } - - @Override - public boolean isEventAheadOffset(final Map offset, final ChangeEventWithMetadata event) { - if (offset.size() != 1) { - return false; - } - - final String eventFileName = event.getEventValueAsJson().get("source").get("file").asText(); - final long eventPosition = event.getEventValueAsJson().get("source").get("pos").asLong(); - - final JsonNode offsetJson = Jsons.deserialize((String) offset.values().toArray()[0]); - - final String offsetFileName = offsetJson.get("file").asText(); - final long offsetPosition = offsetJson.get("pos").asLong(); - if (eventFileName.compareTo(offsetFileName) != 0) { - return eventFileName.compareTo(offsetFileName) > 0; - } - - return eventPosition > offsetPosition; - } - - @Override - public boolean isSameOffset(final Map offsetA, final Map offsetB) { - if ((offsetA == null || offsetA.size() != 1) || (offsetB == null || offsetB.size() != 1)) { - return false; - } - - final JsonNode offsetJsonA = Jsons.deserialize((String) offsetA.values().toArray()[0]); - final String offsetAFileName = offsetJsonA.get("file").asText(); - final long offsetAPosition = offsetJsonA.get("pos").asLong(); - - final JsonNode offsetJsonB = Jsons.deserialize((String) offsetB.values().toArray()[0]); - final String offsetBFileName = offsetJsonB.get("file").asText(); - final long offsetBPosition = offsetJsonB.get("pos").asLong(); - - return offsetAFileName.equals(offsetBFileName) && offsetAPosition == offsetBPosition; - } - - @Override - public MySqlCdcPosition extractPositionFromHeartbeatOffset(final Map sourceOffset) { - return new MySqlCdcPosition(sourceOffset.get("file").toString(), (Long) sourceOffset.get("pos")); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlDebeziumStateUtil.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlDebeziumStateUtil.java deleted file mode 100644 index 36d6115a3cec..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MySqlDebeziumStateUtil.java +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.cdc; - -import static io.airbyte.integrations.source.mysql.cdc.MysqlCdcStateConstants.COMPRESSION_ENABLED; -import static io.debezium.relational.RelationalDatabaseConnectorConfig.DATABASE_NAME; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.annotations.VisibleForTesting; -import io.airbyte.cdk.db.jdbc.JdbcDatabase; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.cdk.integrations.debezium.internals.AirbyteFileOffsetBackingStore; -import io.airbyte.cdk.integrations.debezium.internals.AirbyteSchemaHistoryStorage; -import io.airbyte.cdk.integrations.debezium.internals.AirbyteSchemaHistoryStorage.SchemaHistory; -import io.airbyte.cdk.integrations.debezium.internals.DebeziumPropertiesManager; -import io.airbyte.cdk.integrations.debezium.internals.DebeziumRecordPublisher; -import io.airbyte.cdk.integrations.debezium.internals.DebeziumStateUtil; -import io.airbyte.cdk.integrations.debezium.internals.RecordWaitTimeUtil; -import io.airbyte.cdk.integrations.debezium.internals.RelationalDbDebeziumPropertiesManager; -import io.airbyte.commons.json.Jsons; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; -import io.debezium.config.Configuration; -import io.debezium.connector.common.OffsetReader; -import io.debezium.connector.mysql.MySqlConnectorConfig; -import io.debezium.connector.mysql.MySqlOffsetContext; -import io.debezium.connector.mysql.MySqlOffsetContext.Loader; -import io.debezium.connector.mysql.MySqlPartition; -import io.debezium.connector.mysql.gtid.MySqlGtidSet; -import io.debezium.engine.ChangeEvent; -import io.debezium.pipeline.spi.Offsets; -import io.debezium.pipeline.spi.Partition; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Properties; -import java.util.Set; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.stream.Stream; -import org.apache.kafka.connect.storage.FileOffsetBackingStore; -import org.apache.kafka.connect.storage.OffsetStorageReaderImpl; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MySqlDebeziumStateUtil implements DebeziumStateUtil { - - private static final Logger LOGGER = LoggerFactory.getLogger(MySqlDebeziumStateUtil.class); - - public boolean savedOffsetStillPresentOnServer(final JdbcDatabase database, final MysqlDebeziumStateAttributes savedState) { - if (savedState.gtidSet().isPresent()) { - final Optional availableGtidStr = getStateAttributesFromDB(database).gtidSet(); - if (availableGtidStr.isEmpty()) { - // Last offsets had GTIDs but the server does not use them - LOGGER.info("Connector used GTIDs previously, but MySQL server does not know of any GTIDs or they are not enabled"); - return false; - } - final MySqlGtidSet gtidSetFromSavedState = new MySqlGtidSet(savedState.gtidSet().get()); - // Get the GTID set that is available in the server - final MySqlGtidSet availableGtidSet = new MySqlGtidSet(availableGtidStr.get()); - if (gtidSetFromSavedState.isContainedWithin(availableGtidSet)) { - LOGGER.info("MySQL server current GTID set {} does contain the GTID set required by the connector {}", availableGtidSet, - gtidSetFromSavedState); - final Optional gtidSetToReplicate = subtractGtidSet(availableGtidSet, gtidSetFromSavedState, database); - if (gtidSetToReplicate.isPresent()) { - final Optional purgedGtidSet = purgedGtidSet(database); - if (purgedGtidSet.isPresent()) { - LOGGER.info("MySQL server has already purged {} GTIDs", purgedGtidSet.get()); - final Optional nonPurgedGtidSetToReplicate = subtractGtidSet(gtidSetToReplicate.get(), purgedGtidSet.get(), database); - if (nonPurgedGtidSetToReplicate.isPresent()) { - LOGGER.info("GTIDs known by the MySQL server but not processed yet {}, for replication are available only {}", gtidSetToReplicate, - nonPurgedGtidSetToReplicate); - if (!gtidSetToReplicate.equals(nonPurgedGtidSetToReplicate)) { - LOGGER.info("Some of the GTIDs needed to replicate have been already purged by MySQL server"); - return false; - } - } - } - } - return true; - } - LOGGER.info("Connector last known GTIDs are {}, but MySQL server only has {}", gtidSetFromSavedState, availableGtidSet); - return false; - } - - final List existingLogFiles = getExistingLogFiles(database); - final boolean found = existingLogFiles.stream().anyMatch(savedState.binlogFilename()::equals); - if (!found) { - LOGGER.info("Connector requires binlog file '{}', but MySQL server only has {}", savedState.binlogFilename(), - String.join(", ", existingLogFiles)); - } else { - LOGGER.info("MySQL server has the binlog file '{}' required by the connector", savedState.binlogFilename()); - } - - return found; - - } - - private List getExistingLogFiles(final JdbcDatabase database) { - try (final Stream stream = database.unsafeResultSetQuery( - connection -> connection.createStatement().executeQuery("SHOW BINARY LOGS"), - resultSet -> resultSet.getString(1))) { - return stream.toList(); - } catch (final SQLException e) { - throw new RuntimeException(e); - } - } - - private Optional subtractGtidSet(final MySqlGtidSet set1, final MySqlGtidSet set2, final JdbcDatabase database) { - try (final Stream stream = database.unsafeResultSetQuery( - connection -> { - final PreparedStatement ps = connection.prepareStatement("SELECT GTID_SUBTRACT(?, ?)"); - ps.setString(1, set1.toString()); - ps.setString(2, set2.toString()); - return ps.executeQuery(); - }, - resultSet -> new MySqlGtidSet(resultSet.getString(1)))) { - final List gtidSets = stream.toList(); - if (gtidSets.isEmpty()) { - return Optional.empty(); - } else if (gtidSets.size() == 1) { - return Optional.of(gtidSets.get(0)); - } else { - throw new RuntimeException("Not expecting gtid set size to be greater than 1"); - } - } catch (final SQLException e) { - throw new RuntimeException(e); - } - } - - private Optional purgedGtidSet(final JdbcDatabase database) { - try (final Stream> stream = database.unsafeResultSetQuery( - connection -> connection.createStatement().executeQuery("SELECT @@global.gtid_purged"), - resultSet -> { - if (resultSet.getMetaData().getColumnCount() > 0) { - String string = resultSet.getString(1); - if (string != null && !string.isEmpty()) { - return Optional.of(new MySqlGtidSet(string)); - } - } - return Optional.empty(); - })) { - final List> gtidSet = stream.toList(); - if (gtidSet.isEmpty()) { - return Optional.empty(); - } else if (gtidSet.size() == 1) { - return gtidSet.get(0); - } else { - throw new RuntimeException("Not expecting the size to be greater than 1"); - } - } catch (final SQLException e) { - throw new RuntimeException(e); - } - } - - public Optional savedOffset(final Properties baseProperties, - final ConfiguredAirbyteCatalog catalog, - final JsonNode cdcOffset, - final JsonNode config) { - if (Objects.isNull(cdcOffset)) { - return Optional.empty(); - } - - final var offsetManager = AirbyteFileOffsetBackingStore.initializeState(cdcOffset, Optional.empty()); - final DebeziumPropertiesManager debeziumPropertiesManager = new RelationalDbDebeziumPropertiesManager(baseProperties, config, catalog, - new ArrayList()); - final Properties debeziumProperties = debeziumPropertiesManager.getDebeziumProperties(offsetManager); - return parseSavedOffset(debeziumProperties); - } - - private Optional parseSavedOffset(final Properties properties) { - FileOffsetBackingStore fileOffsetBackingStore = null; - OffsetStorageReaderImpl offsetStorageReader = null; - - try { - fileOffsetBackingStore = getFileOffsetBackingStore(properties); - offsetStorageReader = getOffsetStorageReader(fileOffsetBackingStore, properties); - - final MySqlConnectorConfig connectorConfig = new MySqlConnectorConfig(Configuration.from(properties)); - final MySqlOffsetContext.Loader loader = new MySqlOffsetContext.Loader(connectorConfig); - final Set partitions = - Collections.singleton(new MySqlPartition(connectorConfig.getLogicalName(), properties.getProperty(DATABASE_NAME.name()))); - - final OffsetReader offsetReader = new OffsetReader<>(offsetStorageReader, - loader); - final Map offsets = offsetReader.offsets(partitions); - - return extractStateAttributes(partitions, offsets); - } finally { - LOGGER.info("Closing offsetStorageReader and fileOffsetBackingStore"); - if (offsetStorageReader != null) { - offsetStorageReader.close(); - } - - if (fileOffsetBackingStore != null) { - fileOffsetBackingStore.stop(); - } - } - } - - private Optional extractStateAttributes(final Set partitions, - final Map offsets) { - boolean found = false; - for (final Partition partition : partitions) { - final MySqlOffsetContext mySqlOffsetContext = offsets.get(partition); - - if (mySqlOffsetContext != null) { - found = true; - LOGGER.info("Found previous partition offset {}: {}", partition, mySqlOffsetContext.getOffset()); - } - } - - if (!found) { - LOGGER.info("No previous offsets found"); - return Optional.empty(); - } - - final Offsets of = Offsets.of(offsets); - final MySqlOffsetContext previousOffset = of.getTheOnlyOffset(); - - return Optional.of(new MysqlDebeziumStateAttributes(previousOffset.getSource().binlogFilename(), previousOffset.getSource().binlogPosition(), - Optional.ofNullable(previousOffset.gtidSet()))); - - } - - public JsonNode constructInitialDebeziumState(final Properties properties, - final ConfiguredAirbyteCatalog catalog, - final JdbcDatabase database) { - // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-property-snapshot-mode - // We use the recovery property cause using this mode will instruct Debezium to - // construct the db schema history. - // Note that we used to use schema_only_recovery mode, but this mode has been deprecated. - properties.setProperty("snapshot.mode", "recovery"); - final String dbName = database.getSourceConfig().get(JdbcUtils.DATABASE_KEY).asText(); - // Topic.prefix is sanitized version of database name. At this stage properties does not have this - // value - it's set in RelationalDbDebeziumPropertiesManager. - final AirbyteFileOffsetBackingStore offsetManager = AirbyteFileOffsetBackingStore.initializeState( - constructBinlogOffset(database, dbName, DebeziumPropertiesManager.sanitizeTopicPrefix(dbName)), - Optional.empty()); - final AirbyteSchemaHistoryStorage schemaHistoryStorage = - AirbyteSchemaHistoryStorage.initializeDBHistory(new SchemaHistory<>(Optional.empty(), false), COMPRESSION_ENABLED); - final LinkedBlockingQueue> queue = new LinkedBlockingQueue<>(); - final var debeziumPropertiesManager = - new RelationalDbDebeziumPropertiesManager(properties, database.getSourceConfig(), catalog, new ArrayList()); - - try (final DebeziumRecordPublisher publisher = new DebeziumRecordPublisher(debeziumPropertiesManager)) { - publisher.start(queue, offsetManager, Optional.of(schemaHistoryStorage)); - final Instant engineStartTime = Instant.now(); - while (!publisher.hasClosed()) { - final ChangeEvent event = queue.poll(10, TimeUnit.SECONDS); - if (event == null) { - Duration initialWaitingDuration = Duration.ofMinutes(5L); - // If initial waiting seconds is configured and it's greater than 5 minutes, use that value instead - // of the default value - final Duration configuredDuration = RecordWaitTimeUtil.getFirstRecordWaitTime(database.getSourceConfig()); - if (configuredDuration.compareTo(initialWaitingDuration) > 0) { - initialWaitingDuration = configuredDuration; - } - if (Duration.between(engineStartTime, Instant.now()).compareTo(initialWaitingDuration) > 0) { - LOGGER.error("No record is returned even after {} seconds of waiting, closing the engine", initialWaitingDuration.getSeconds()); - publisher.close(); - throw new RuntimeException( - "Building schema history has timed out. Please consider increasing the debezium wait time in advanced options."); - } - continue; - } - LOGGER.info("A record is returned, closing the engine since the state is constructed"); - publisher.close(); - break; - } - } catch (final Exception e) { - throw new RuntimeException(e); - } - - final Map offset = offsetManager.read(); - final SchemaHistory schemaHistory = schemaHistoryStorage.read(); - - assert !offset.isEmpty(); - assert Objects.nonNull(schemaHistory); - assert Objects.nonNull(schemaHistory.getSchema()); - - final JsonNode asJson = serialize(offset, schemaHistory); - LOGGER.info("Initial Debezium state constructed: {}", asJson); - - if (asJson.get(MysqlCdcStateConstants.MYSQL_DB_HISTORY).asText().isBlank()) { - throw new RuntimeException("Schema history snapshot returned empty history."); - } - return asJson; - } - - public static JsonNode serialize(final Map offset, final SchemaHistory dbHistory) { - final Map state = new HashMap<>(); - state.put(MysqlCdcStateConstants.MYSQL_CDC_OFFSET, offset); - state.put(MysqlCdcStateConstants.MYSQL_DB_HISTORY, dbHistory.getSchema()); - state.put(MysqlCdcStateConstants.IS_COMPRESSED, dbHistory.isCompressed()); - - return Jsons.jsonNode(state); - } - - /** - * Method to construct initial Debezium state which can be passed onto Debezium engine to make it - * process binlogs from a specific file and position and skip snapshot phase - */ - private JsonNode constructBinlogOffset(final JdbcDatabase database, final String debeziumName, final String topicPrefixName) { - return format(getStateAttributesFromDB(database), debeziumName, topicPrefixName, Instant.now()); - } - - @VisibleForTesting - public JsonNode format(final MysqlDebeziumStateAttributes attributes, final String debeziumName, final String topicPrefixName, final Instant time) { - final String key = "[\"" + debeziumName + "\",{\"server\":\"" + topicPrefixName + "\"}]"; - final String gtidSet = attributes.gtidSet().isPresent() ? ",\"gtids\":\"" + attributes.gtidSet().get() + "\"" : ""; - final String value = - "{\"transaction_id\":null,\"ts_sec\":" + time.getEpochSecond() + ",\"file\":\"" + attributes.binlogFilename() + "\",\"pos\":" - + attributes.binlogPosition() - + gtidSet + "}"; - - final Map result = new HashMap<>(); - result.put(key, value); - - final JsonNode jsonNode = Jsons.jsonNode(result); - LOGGER.info("Initial Debezium state offset constructed: {}", jsonNode); - - return jsonNode; - } - - public static MysqlDebeziumStateAttributes getStateAttributesFromDB(final JdbcDatabase database) { - try (final Stream stream = database.unsafeResultSetQuery( - connection -> connection.createStatement().executeQuery("SHOW MASTER STATUS"), - resultSet -> { - final String file = resultSet.getString("File"); - final long position = resultSet.getLong("Position"); - assert file != null; - assert position >= 0; - if (resultSet.getMetaData().getColumnCount() > 4) { - // This column exists only in MySQL 5.6.5 or later ... - final String gtidSet = resultSet.getString(5); // GTID set, may be null, blank, or contain a GTID set - return new MysqlDebeziumStateAttributes(file, position, removeNewLineChars(gtidSet)); - } - return new MysqlDebeziumStateAttributes(file, position, Optional.empty()); - })) { - final List stateAttributes = stream.toList(); - assert stateAttributes.size() == 1; - return stateAttributes.get(0); - } catch (final SQLException e) { - throw new RuntimeException(e); - } - } - - private static Optional removeNewLineChars(final String gtidSet) { - if (gtidSet != null && !gtidSet.trim().isEmpty()) { - // Remove all the newline chars that exist in the GTID set string ... - return Optional.of(gtidSet.replace("\n", "").replace("\r", "")); - } - - return Optional.empty(); - } - - public record MysqlDebeziumStateAttributes(String binlogFilename, long binlogPosition, Optional gtidSet) { - - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MysqlCdcStateConstants.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MysqlCdcStateConstants.java deleted file mode 100644 index cac1bfd997d5..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cdc/MysqlCdcStateConstants.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.cdc; - -public class MysqlCdcStateConstants { - - public static final String MYSQL_CDC_OFFSET = "mysql_cdc_offset"; - public static final String MYSQL_DB_HISTORY = "mysql_db_history"; - public static final String IS_COMPRESSED = "is_compressed"; - public static final boolean COMPRESSION_ENABLED = true; - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cursor_based/MySqlCursorBasedStateManager.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cursor_based/MySqlCursorBasedStateManager.java deleted file mode 100644 index 9741c9b2b7ca..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/cursor_based/MySqlCursorBasedStateManager.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.cursor_based; - -import com.google.common.collect.Lists; -import io.airbyte.cdk.integrations.source.relationaldb.CursorInfo; -import io.airbyte.cdk.integrations.source.relationaldb.state.StreamStateManager; -import io.airbyte.commons.json.Jsons; -import io.airbyte.integrations.source.mysql.internal.models.CursorBasedStatus; -import io.airbyte.integrations.source.mysql.internal.models.InternalModels.StateType; -import io.airbyte.protocol.models.v0.AirbyteStateMessage; -import io.airbyte.protocol.models.v0.AirbyteStateMessage.AirbyteStateType; -import io.airbyte.protocol.models.v0.AirbyteStreamNameNamespacePair; -import io.airbyte.protocol.models.v0.AirbyteStreamState; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; -import io.airbyte.protocol.models.v0.StreamDescriptor; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MySqlCursorBasedStateManager extends StreamStateManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(MySqlCursorBasedStateManager.class); - - public MySqlCursorBasedStateManager(final List airbyteStateMessages, final ConfiguredAirbyteCatalog catalog) { - super(airbyteStateMessages, catalog); - } - - @Override - public AirbyteStateMessage toState(final Optional pair) { - if (pair.isPresent()) { - final Map pairToCursorInfoMap = getPairToCursorInfoMap(); - final Optional cursorInfo = Optional.ofNullable(pairToCursorInfoMap.get(pair.get())); - - if (cursorInfo.isPresent()) { - LOGGER.debug("Generating state message for {}...", pair); - return new AirbyteStateMessage() - .withType(AirbyteStateType.STREAM) - // Temporarily include legacy state for backwards compatibility with the platform - .withStream(generateStreamState(pair.get(), cursorInfo.get())); - } else { - LOGGER.warn("Cursor information could not be located in state for stream {}. Returning a new, empty state message...", pair); - return new AirbyteStateMessage().withType(AirbyteStateType.STREAM).withStream(new AirbyteStreamState()); - } - } else { - LOGGER.warn("Stream not provided. Returning a new, empty state message..."); - return new AirbyteStateMessage().withType(AirbyteStateType.STREAM).withStream(new AirbyteStreamState()); - } - } - - /** - * Generates the stream state for the given stream and cursor information. - * - * @param airbyteStreamNameNamespacePair The stream. - * @param cursorInfo The current cursor. - * @return The {@link AirbyteStreamState} representing the current state of the stream. - */ - private AirbyteStreamState generateStreamState(final AirbyteStreamNameNamespacePair airbyteStreamNameNamespacePair, - final CursorInfo cursorInfo) { - return new AirbyteStreamState() - .withStreamDescriptor( - new StreamDescriptor().withName(airbyteStreamNameNamespacePair.getName()).withNamespace(airbyteStreamNameNamespacePair.getNamespace())) - .withStreamState(Jsons.jsonNode(generateDbStreamState(airbyteStreamNameNamespacePair, cursorInfo))); - } - - private CursorBasedStatus generateDbStreamState(final AirbyteStreamNameNamespacePair airbyteStreamNameNamespacePair, - final CursorInfo cursorInfo) { - final CursorBasedStatus state = new CursorBasedStatus(); - state.setStateType(StateType.CURSOR_BASED); - state.setVersion(2L); - state.setStreamName(airbyteStreamNameNamespacePair.getName()); - state.setStreamNamespace(airbyteStreamNameNamespacePair.getNamespace()); - state.setCursorField(cursorInfo.getCursorField() == null ? Collections.emptyList() : Lists.newArrayList(cursorInfo.getCursorField())); - state.setCursor(cursorInfo.getCursor()); - if (cursorInfo.getCursorRecordCount() > 0L) { - state.setCursorRecordCount(cursorInfo.getCursorRecordCount()); - } - return state; - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/CdcMetadataInjector.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/CdcMetadataInjector.java deleted file mode 100644 index cde1f645a60f..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/CdcMetadataInjector.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.initialsync; - -import com.fasterxml.jackson.databind.node.ObjectNode; -import io.airbyte.integrations.source.mysql.cdc.MySqlCdcConnectorMetadataInjector; -import io.airbyte.integrations.source.mysql.cdc.MySqlDebeziumStateUtil.MysqlDebeziumStateAttributes; - -public class CdcMetadataInjector { - - private final String transactionTimestamp; - private final MysqlDebeziumStateAttributes stateAttributes; - private final MySqlCdcConnectorMetadataInjector metadataInjector; - - public CdcMetadataInjector(final String transactionTimestamp, - final MysqlDebeziumStateAttributes stateAttributes, - final MySqlCdcConnectorMetadataInjector metadataInjector) { - this.transactionTimestamp = transactionTimestamp; - this.stateAttributes = stateAttributes; - this.metadataInjector = metadataInjector; - } - - public void inject(final ObjectNode record) { - metadataInjector.addMetaDataToRowsFetchedOutsideDebezium(record, transactionTimestamp, stateAttributes); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialLoadGlobalStateManager.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialLoadGlobalStateManager.java deleted file mode 100644 index 9b3de8d4047e..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialLoadGlobalStateManager.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.initialsync; - -import com.fasterxml.jackson.databind.JsonNode; -import io.airbyte.cdk.integrations.source.relationaldb.models.CdcState; -import io.airbyte.cdk.integrations.source.relationaldb.models.DbStreamState; -import io.airbyte.cdk.integrations.source.relationaldb.state.StateManager; -import io.airbyte.commons.json.Jsons; -import io.airbyte.integrations.source.mysql.initialsync.MySqlInitialReadUtil.InitialLoadStreams; -import io.airbyte.integrations.source.mysql.initialsync.MySqlInitialReadUtil.PrimaryKeyInfo; -import io.airbyte.protocol.models.AirbyteStreamNameNamespacePair; -import io.airbyte.protocol.models.v0.AirbyteGlobalState; -import io.airbyte.protocol.models.v0.AirbyteStateMessage; -import io.airbyte.protocol.models.v0.AirbyteStateMessage.AirbyteStateType; -import io.airbyte.protocol.models.v0.AirbyteStreamState; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; -import io.airbyte.protocol.models.v0.StreamDescriptor; -import io.airbyte.protocol.models.v0.SyncMode; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MySqlInitialLoadGlobalStateManager extends MySqlInitialLoadStateManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(MySqlInitialLoadGlobalStateManager.class); - protected StateManager stateManager; - - // Only one global state is emitted, which is fanned out into many entries in the DB by platform. As - // a result, we need to keep track of streams that - // have completed the snapshot. - private Set streamsThatHaveCompletedSnapshot; - - // No special handling for resumable full refresh streams. We will report the cursor as it is. - private Set resumableFullRefreshStreams; - - // non ResumableFullRefreshStreams do not have any state. We only report count for them. - private Set nonResumableFullRefreshStreams; - private Set completedNonResumableFullRefreshStreams; - - private final boolean savedOffsetStillPresentOnServer; - private final ConfiguredAirbyteCatalog catalog; - private final CdcState defaultCdcState; - - public MySqlInitialLoadGlobalStateManager(final InitialLoadStreams initialLoadStreams, - final Map pairToPrimaryKeyInfo, - final StateManager stateManager, - final ConfiguredAirbyteCatalog catalog, - - final boolean savedOffsetStillPresentOnServer, - final CdcState defaultCdcState) { - this.stateManager = stateManager; - this.pairToPrimaryKeyLoadStatus = MySqlInitialLoadStateManager.initPairToPrimaryKeyLoadStatusMap(initialLoadStreams.pairToInitialLoadStatus()); - this.pairToPrimaryKeyInfo = pairToPrimaryKeyInfo; - this.catalog = catalog; - this.savedOffsetStillPresentOnServer = savedOffsetStillPresentOnServer; - this.defaultCdcState = defaultCdcState; - this.streamStateForIncrementalRunSupplier = pair -> Jsons.emptyObject(); - initStreams(initialLoadStreams, catalog); - } - - private void initStreams(final InitialLoadStreams initialLoadStreams, - final ConfiguredAirbyteCatalog catalog) { - this.streamsThatHaveCompletedSnapshot = new HashSet<>(); - this.resumableFullRefreshStreams = new HashSet<>(); - this.nonResumableFullRefreshStreams = new HashSet<>(); - this.completedNonResumableFullRefreshStreams = new HashSet<>(); - - catalog.getStreams().forEach(configuredAirbyteStream -> { - var pairInStream = - new AirbyteStreamNameNamespacePair(configuredAirbyteStream.getStream().getName(), configuredAirbyteStream.getStream().getNamespace()); - if (!initialLoadStreams.streamsForInitialLoad().contains(configuredAirbyteStream) - && configuredAirbyteStream.getSyncMode() == SyncMode.INCREMENTAL) { - this.streamsThatHaveCompletedSnapshot.add(pairInStream); - } - if (configuredAirbyteStream.getSyncMode() == SyncMode.FULL_REFRESH) { - if (configuredAirbyteStream.getStream().getSourceDefinedPrimaryKey() != null - && !configuredAirbyteStream.getStream().getSourceDefinedPrimaryKey().isEmpty()) { - this.resumableFullRefreshStreams.add(pairInStream); - } else { - this.nonResumableFullRefreshStreams.add(pairInStream); - } - } - }); - } - - private AirbyteGlobalState generateGlobalState(final List streamStates) { - CdcState cdcState = stateManager.getCdcStateManager().getCdcState(); - - if (!savedOffsetStillPresentOnServer || cdcState == null - || cdcState.getState() == null) { - cdcState = defaultCdcState; - } - - final AirbyteGlobalState globalState = new AirbyteGlobalState(); - globalState.setSharedState(Jsons.jsonNode(cdcState)); - globalState.setStreamStates(streamStates); - return globalState; - } - - @Override - public AirbyteStateMessage generateStateMessageAtCheckpoint(final ConfiguredAirbyteStream airbyteStream) { - final List streamStates = new ArrayList<>(); - streamsThatHaveCompletedSnapshot.forEach(stream -> { - final DbStreamState state = getFinalState(stream); - streamStates.add(getAirbyteStreamState(stream, Jsons.jsonNode(state))); - }); - - resumableFullRefreshStreams.forEach(stream -> { - var pkStatus = getPrimaryKeyLoadStatus(stream); - if (pkStatus != null) { - streamStates.add(getAirbyteStreamState(stream, (Jsons.jsonNode(pkStatus)))); - } - }); - - completedNonResumableFullRefreshStreams.forEach(stream -> { - streamStates.add(new AirbyteStreamState() - .withStreamDescriptor( - new StreamDescriptor().withName(stream.getName()).withNamespace(stream.getNamespace()))); - }); - - if (airbyteStream.getSyncMode() == SyncMode.INCREMENTAL) { - AirbyteStreamNameNamespacePair pair = - new AirbyteStreamNameNamespacePair(airbyteStream.getStream().getName(), airbyteStream.getStream().getNamespace()); - var pkStatus = getPrimaryKeyLoadStatus(pair); - streamStates.add(getAirbyteStreamState(pair, (Jsons.jsonNode(pkStatus)))); - } - - return new AirbyteStateMessage() - .withType(AirbyteStateType.GLOBAL) - .withGlobal(generateGlobalState(streamStates)); - } - - @Override - public AirbyteStateMessage createFinalStateMessage(final ConfiguredAirbyteStream airbyteStream) { - final AirbyteStreamNameNamespacePair pair = - new AirbyteStreamNameNamespacePair(airbyteStream.getStream().getName(), airbyteStream.getStream().getNamespace()); - if (airbyteStream.getSyncMode() == SyncMode.INCREMENTAL) { - streamsThatHaveCompletedSnapshot.add(pair); - } else if (nonResumableFullRefreshStreams.contains(pair)) { - completedNonResumableFullRefreshStreams.add(pair); - } - final List streamStates = new ArrayList<>(); - - streamsThatHaveCompletedSnapshot.forEach(stream -> { - final DbStreamState state = getFinalState(stream); - streamStates.add(getAirbyteStreamState(stream, Jsons.jsonNode(state))); - }); - - resumableFullRefreshStreams.forEach(stream -> { - var pkStatus = getPrimaryKeyLoadStatus(stream); - streamStates.add(getAirbyteStreamState(stream, (Jsons.jsonNode(pkStatus)))); - }); - - completedNonResumableFullRefreshStreams.forEach(stream -> { - streamStates.add(new AirbyteStreamState() - .withStreamDescriptor( - new StreamDescriptor().withName(stream.getName()).withNamespace(stream.getNamespace()))); - }); - - return new AirbyteStateMessage() - .withType(AirbyteStateType.GLOBAL) - .withGlobal(generateGlobalState(streamStates)); - } - - @Override - public PrimaryKeyInfo getPrimaryKeyInfo(final AirbyteStreamNameNamespacePair pair) { - return pairToPrimaryKeyInfo.get(pair); - } - - private AirbyteStreamState getAirbyteStreamState(final io.airbyte.protocol.models.AirbyteStreamNameNamespacePair pair, final JsonNode stateData) { - assert Objects.nonNull(pair); - assert Objects.nonNull(pair.getName()); - assert Objects.nonNull(pair.getNamespace()); - - return new AirbyteStreamState() - .withStreamDescriptor( - new StreamDescriptor().withName(pair.getName()).withNamespace(pair.getNamespace())) - .withStreamState(stateData); - } - - private DbStreamState getFinalState(final io.airbyte.protocol.models.AirbyteStreamNameNamespacePair pair) { - assert Objects.nonNull(pair); - assert Objects.nonNull(pair.getName()); - assert Objects.nonNull(pair.getNamespace()); - - return new DbStreamState() - .withStreamName(pair.getName()) - .withStreamNamespace(pair.getNamespace()) - .withCursorField(Collections.emptyList()) - .withCursor(null); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialLoadHandler.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialLoadHandler.java deleted file mode 100644 index f9684c33ea1f..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialLoadHandler.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.initialsync; - -import static io.airbyte.cdk.integrations.debezium.DebeziumIteratorConstants.SYNC_CHECKPOINT_DURATION_PROPERTY; -import static io.airbyte.cdk.integrations.debezium.DebeziumIteratorConstants.SYNC_CHECKPOINT_RECORDS_PROPERTY; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.annotations.VisibleForTesting; -import com.mysql.cj.MysqlType; -import io.airbyte.cdk.db.jdbc.AirbyteRecordData; -import io.airbyte.cdk.db.jdbc.JdbcDatabase; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.cdk.integrations.debezium.DebeziumIteratorConstants; -import io.airbyte.cdk.integrations.source.relationaldb.DbSourceDiscoverUtil; -import io.airbyte.cdk.integrations.source.relationaldb.InitialLoadHandler; -import io.airbyte.cdk.integrations.source.relationaldb.TableInfo; -import io.airbyte.cdk.integrations.source.relationaldb.state.SourceStateIterator; -import io.airbyte.cdk.integrations.source.relationaldb.state.StateEmitFrequency; -import io.airbyte.cdk.integrations.source.relationaldb.streamstatus.StreamStatusTraceEmitterIterator; -import io.airbyte.commons.stream.AirbyteStreamStatusHolder; -import io.airbyte.commons.stream.AirbyteStreamUtils; -import io.airbyte.commons.util.AutoCloseableIterator; -import io.airbyte.commons.util.AutoCloseableIterators; -import io.airbyte.integrations.source.mysql.MySqlQueryUtils.TableSizeInfo; -import io.airbyte.integrations.source.mysql.MySqlSourceOperations; -import io.airbyte.integrations.source.mysql.internal.models.PrimaryKeyLoadStatus; -import io.airbyte.protocol.models.AirbyteStreamNameNamespacePair; -import io.airbyte.protocol.models.CommonField; -import io.airbyte.protocol.models.v0.*; -import io.airbyte.protocol.models.v0.AirbyteMessage.Type; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicLong; -import java.util.function.Function; -import java.util.stream.Collectors; -import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MySqlInitialLoadHandler implements InitialLoadHandler { - - private static final Logger LOGGER = LoggerFactory.getLogger(MySqlInitialLoadHandler.class); - - private static final long RECORD_LOGGING_SAMPLE_RATE = 1_000_000; - private final JsonNode config; - private final JdbcDatabase database; - private final MySqlSourceOperations sourceOperations; - private final String quoteString; - private final MySqlInitialLoadStateManager initialLoadStateManager; - private final Optional> streamStateForIncrementalRunSupplier; - - private static final long QUERY_TARGET_SIZE_GB = 1_073_741_824; - private static final long DEFAULT_CHUNK_SIZE = 1_000_000; - private long MAX_CHUNK_SIZE = Long.MAX_VALUE; - final Map tableSizeInfoMap; - - public MySqlInitialLoadHandler(final JsonNode config, - final JdbcDatabase database, - final MySqlSourceOperations sourceOperations, - final String quoteString, - final MySqlInitialLoadStateManager initialLoadStateManager, - final Optional> streamStateForIncrementalRunSupplier, - final Map tableSizeInfoMap) { - this.config = config; - this.database = database; - this.sourceOperations = sourceOperations; - this.quoteString = quoteString; - this.initialLoadStateManager = initialLoadStateManager; - this.streamStateForIncrementalRunSupplier = streamStateForIncrementalRunSupplier; - this.tableSizeInfoMap = tableSizeInfoMap; - adjustChunkSizeLimitForMySQLVariants(); - } - - private void adjustChunkSizeLimitForMySQLVariants() { - // For PSDB, we need to limit the chunk size to 100k rows to avoid the query being killed by the - // server. - // Reference: - // https://planetscale.com/docs/reference/planetscale-system-limits - if (config.get(JdbcUtils.HOST_KEY).asText().toLowerCase().contains("psdb.cloud")) - MAX_CHUNK_SIZE = 100_000; - } - - public List> getIncrementalIterators( - final ConfiguredAirbyteCatalog catalog, - final Map>> tableNameToTable, - final Instant emittedAt, - final boolean decorateWithStartedStatus, - final boolean decorateWithCompletedStatus, - final Optional cdcInitialLoadTimeout) { - final List> iteratorList = new ArrayList<>(); - for (final ConfiguredAirbyteStream airbyteStream : catalog.getStreams()) { - final AirbyteStream stream = airbyteStream.getStream(); - final String streamName = stream.getName(); - final String namespace = stream.getNamespace(); - final AirbyteStreamNameNamespacePair pair = new AirbyteStreamNameNamespacePair(streamName, namespace); - if (airbyteStream.getSyncMode().equals(SyncMode.INCREMENTAL)) { - final String fullyQualifiedTableName = DbSourceDiscoverUtil.getFullyQualifiedTableName(namespace, streamName); - final TableInfo> table = tableNameToTable.get(fullyQualifiedTableName); - if (decorateWithStartedStatus) { - iteratorList.add( - new StreamStatusTraceEmitterIterator(new AirbyteStreamStatusHolder(pair, AirbyteStreamStatusTraceMessage.AirbyteStreamStatus.STARTED))); - } - - iteratorList.add(getIteratorForStream(airbyteStream, table, emittedAt, cdcInitialLoadTimeout)); - if (decorateWithCompletedStatus) { - iteratorList.add(new StreamStatusTraceEmitterIterator( - new AirbyteStreamStatusHolder(pair, AirbyteStreamStatusTraceMessage.AirbyteStreamStatus.COMPLETE))); - } - } - } - return iteratorList; - } - - @Override - public AutoCloseableIterator getIteratorForStream( - @NotNull ConfiguredAirbyteStream airbyteStream, - @NotNull TableInfo> table, - @NotNull Instant emittedAt, - @NotNull final Optional cdcInitialLoadTimeout) { - - final AirbyteStream stream = airbyteStream.getStream(); - final String streamName = stream.getName(); - final String namespace = stream.getNamespace(); - final AirbyteStreamNameNamespacePair pair = new AirbyteStreamNameNamespacePair(streamName, namespace); - final List selectedDatabaseFields = table.getFields() - .stream() - .map(CommonField::getName) - .filter(CatalogHelpers.getTopLevelFieldNames(airbyteStream)::contains) - .collect(Collectors.toList()); - final AutoCloseableIterator queryStream = - new MySqlInitialLoadRecordIterator(database, sourceOperations, quoteString, initialLoadStateManager, selectedDatabaseFields, pair, - Long.min(calculateChunkSize(tableSizeInfoMap.get(pair), pair), MAX_CHUNK_SIZE), isCompositePrimaryKey(airbyteStream), emittedAt, - cdcInitialLoadTimeout); - final AutoCloseableIterator recordIterator = - getRecordIterator(queryStream, streamName, namespace, emittedAt.toEpochMilli()); - final AutoCloseableIterator recordAndMessageIterator = augmentWithState(recordIterator, airbyteStream, pair); - - return augmentWithLogs(recordAndMessageIterator, pair, streamName); - } - - private static boolean isCompositePrimaryKey(final ConfiguredAirbyteStream stream) { - return stream.getStream().getSourceDefinedPrimaryKey().size() > 1; - } - - // Calculates the number of rows to fetch per query. - @VisibleForTesting - public static long calculateChunkSize(final TableSizeInfo tableSizeInfo, final AirbyteStreamNameNamespacePair pair) { - // If table size info could not be calculated, a default chunk size will be provided. - if (tableSizeInfo == null || tableSizeInfo.tableSize() == 0 || tableSizeInfo.avgRowLength() == 0) { - LOGGER.info("Chunk size could not be determined for pair: {}, defaulting to {} rows", pair, DEFAULT_CHUNK_SIZE); - return DEFAULT_CHUNK_SIZE; - } - final long avgRowLength = tableSizeInfo.avgRowLength(); - final long chunkSize = QUERY_TARGET_SIZE_GB / avgRowLength; - LOGGER.info("Chunk size determined for pair: {}, is {}", pair, chunkSize); - return chunkSize; - } - - // Transforms the given iterator to create an {@link AirbyteRecordMessage} - private AutoCloseableIterator getRecordIterator( - final AutoCloseableIterator recordIterator, - final String streamName, - final String namespace, - final long emittedAt) { - return AutoCloseableIterators.transform(recordIterator, r -> new AirbyteMessage() - .withType(Type.RECORD) - .withRecord(new AirbyteRecordMessage() - .withStream(streamName) - .withNamespace(namespace) - .withEmittedAt(emittedAt) - .withData(r.rawRowData()) - .withMeta(isMetaChangesEmptyOrNull(r.meta()) ? null : r.meta()))); - } - - private boolean isMetaChangesEmptyOrNull(AirbyteRecordMessageMeta meta) { - return meta == null || meta.getChanges() == null || meta.getChanges().isEmpty(); - } - - // Augments the given iterator with record count logs. - private AutoCloseableIterator augmentWithLogs(final AutoCloseableIterator iterator, - final io.airbyte.protocol.models.AirbyteStreamNameNamespacePair pair, - final String streamName) { - final AtomicLong recordCount = new AtomicLong(); - return AutoCloseableIterators.transform(iterator, - AirbyteStreamUtils.convertFromNameAndNamespace(pair.getName(), pair.getNamespace()), - r -> { - final long count = recordCount.incrementAndGet(); - if (count % RECORD_LOGGING_SAMPLE_RATE == 0) { - LOGGER.info("Reading stream {}. Records read: {}", streamName, count); - } - return r; - }); - } - - private AutoCloseableIterator augmentWithState(final AutoCloseableIterator recordIterator, - final ConfiguredAirbyteStream airbyteStream, - final AirbyteStreamNameNamespacePair pair) { - - final PrimaryKeyLoadStatus currentPkLoadStatus = initialLoadStateManager.getPrimaryKeyLoadStatus(pair); - - final Duration syncCheckpointDuration = - config.get(SYNC_CHECKPOINT_DURATION_PROPERTY) != null ? Duration.ofSeconds(config.get(SYNC_CHECKPOINT_DURATION_PROPERTY).asLong()) - : DebeziumIteratorConstants.SYNC_CHECKPOINT_DURATION; - final Long syncCheckpointRecords = config.get(SYNC_CHECKPOINT_RECORDS_PROPERTY) != null ? config.get(SYNC_CHECKPOINT_RECORDS_PROPERTY).asLong() - : DebeziumIteratorConstants.SYNC_CHECKPOINT_RECORDS; - - if (streamStateForIncrementalRunSupplier.isPresent()) { - initialLoadStateManager.setStreamStateForIncrementalRunSupplier(streamStateForIncrementalRunSupplier.get()); - } - return AutoCloseableIterators.transformIterator( - r -> new SourceStateIterator<>(r, airbyteStream, initialLoadStateManager, - new StateEmitFrequency(syncCheckpointRecords, syncCheckpointDuration)), - recordIterator, pair); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialLoadRecordIterator.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialLoadRecordIterator.java deleted file mode 100644 index 1093560ad43d..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialLoadRecordIterator.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.initialsync; - -import static io.airbyte.cdk.db.DbAnalyticsUtils.cdcSnapshotForceShutdownMessage; - -import com.google.common.collect.AbstractIterator; -import com.mysql.cj.MysqlType; -import io.airbyte.cdk.db.JdbcCompatibleSourceOperations; -import io.airbyte.cdk.db.jdbc.AirbyteRecordData; -import io.airbyte.cdk.db.jdbc.JdbcDatabase; -import io.airbyte.cdk.integrations.base.AirbyteTraceMessageUtility; -import io.airbyte.cdk.integrations.source.relationaldb.RelationalDbQueryUtils; -import io.airbyte.commons.exceptions.TransientErrorException; -import io.airbyte.commons.util.AutoCloseableIterator; -import io.airbyte.commons.util.AutoCloseableIterators; -import io.airbyte.integrations.source.mysql.initialsync.MySqlInitialReadUtil.PrimaryKeyInfo; -import io.airbyte.integrations.source.mysql.internal.models.PrimaryKeyLoadStatus; -import io.airbyte.protocol.models.AirbyteStreamNameNamespacePair; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.time.Duration; -import java.time.Instant; -import java.util.List; -import java.util.Optional; -import java.util.stream.Stream; -import javax.annotation.CheckForNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This record iterator operates over a single stream. It continuously reads data from a table via - * multiple queries with the configured chunk size until the entire table is processed. The next - * query uses the highest watermark of the primary key seen in the previous subquery. Consider a - * table with chunk size = 1,000,000, and 3,500,000 records. The series of queries executed are : - * Query 1 : select * from table order by pk limit 1,800,000, pk_max = pk_max_1 Query 2 : select * - * from table where pk > pk_max_1 order by pk limit 1,800,000, pk_max = pk_max_2 Query 3 : select * - * from table where pk > pk_max_2 order by pk limit 1,800,000, pk_max = pk_max_3 Query 4 : select * - * from table where pk > pk_max_3 order by pk limit 1,800,000, pk_max = pk_max_4 Query 5 : select * - * from table where pk > pk_max_4 order by pk limit 1,800,000. Final query, since there are zero - * records processed here. - */ -@SuppressWarnings("try") -public class MySqlInitialLoadRecordIterator extends AbstractIterator - implements AutoCloseableIterator { - - private static final Logger LOGGER = LoggerFactory.getLogger(MySqlInitialLoadRecordIterator.class); - - private final JdbcCompatibleSourceOperations sourceOperations; - - private final String quoteString; - private final MySqlInitialLoadStateManager initialLoadStateManager; - private final List columnNames; - private final AirbyteStreamNameNamespacePair pair; - private final JdbcDatabase database; - // Represents the number of rows to get with each query. - private final long chunkSize; - private final PrimaryKeyInfo pkInfo; - private final boolean isCompositeKeyLoad; - - private final Instant startInstant; - private int numSubqueries = 0; - private AutoCloseableIterator currentIterator; - - private Optional cdcInitialLoadTimeout; - private boolean isCdcSync; - - MySqlInitialLoadRecordIterator( - final JdbcDatabase database, - final JdbcCompatibleSourceOperations sourceOperations, - final String quoteString, - final MySqlInitialLoadStateManager initialLoadStateManager, - final List columnNames, - final AirbyteStreamNameNamespacePair pair, - final long chunkSize, - final boolean isCompositeKeyLoad, - final Instant startInstant, - final Optional cdcInitialLoadTimeout) { - this.database = database; - this.sourceOperations = sourceOperations; - this.quoteString = quoteString; - this.initialLoadStateManager = initialLoadStateManager; - this.columnNames = columnNames; - this.pair = pair; - this.chunkSize = chunkSize; - this.pkInfo = initialLoadStateManager.getPrimaryKeyInfo(pair); - this.isCompositeKeyLoad = isCompositeKeyLoad; - this.startInstant = startInstant; - this.cdcInitialLoadTimeout = cdcInitialLoadTimeout; - this.isCdcSync = isCdcSync(initialLoadStateManager); - } - - @CheckForNull - @Override - protected AirbyteRecordData computeNext() { - if (isCdcSync && cdcInitialLoadTimeout.isPresent() - && Duration.between(startInstant, Instant.now()).compareTo(cdcInitialLoadTimeout.get()) > 0) { - final String cdcInitialLoadTimeoutMessage = String.format( - "Initial load for table %s has taken longer than %s hours, Canceling sync so that CDC replication can catch-up on subsequent attempt, and then initial snapshotting will resume", - getAirbyteStream().get(), cdcInitialLoadTimeout.get().toHours()); - LOGGER.info(cdcInitialLoadTimeoutMessage); - AirbyteTraceMessageUtility.emitAnalyticsTrace(cdcSnapshotForceShutdownMessage()); - throw new TransientErrorException(cdcInitialLoadTimeoutMessage); - } - if (shouldBuildNextSubquery()) { - try { - // We will only issue one query for a composite key load. If we have already processed all the data - // associated with this - // query, we should indicate that we are done processing for the given stream. - if (isCompositeKeyLoad && numSubqueries >= 1) { - return endOfData(); - } - // Previous stream (and connection) must be manually closed in this iterator. - if (currentIterator != null) { - currentIterator.close(); - } - - LOGGER.info("Subquery number : {}", numSubqueries); - final Stream stream = database.unsafeQuery( - this::getPkPreparedStatement, sourceOperations::convertDatabaseRowToAirbyteRecordData); - - currentIterator = AutoCloseableIterators.fromStream(stream, pair); - numSubqueries++; - // If the current subquery has no records associated with it, the entire stream has been read. - if (!currentIterator.hasNext()) { - return endOfData(); - } - } catch (final Exception e) { - throw new RuntimeException(e); - } - } - return currentIterator.next(); - } - - private boolean shouldBuildNextSubquery() { - // The next sub-query should be built if (i) it is the first subquery in the sequence. (ii) the - // previous subquery has finished. - return (currentIterator == null || !currentIterator.hasNext()); - } - - private PreparedStatement getPkPreparedStatement(final Connection connection) { - try { - final String tableName = pair.getName(); - final String schemaName = pair.getNamespace(); - LOGGER.info("Preparing query for table: {}", tableName); - final String fullTableName = RelationalDbQueryUtils.getFullyQualifiedTableNameWithQuoting(schemaName, tableName, - quoteString); - - final String wrappedColumnNames = RelationalDbQueryUtils.enquoteIdentifierList(columnNames, quoteString); - - final PrimaryKeyLoadStatus pkLoadStatus = initialLoadStateManager.getPrimaryKeyLoadStatus(pair); - - if (pkLoadStatus == null) { - LOGGER.info("pkLoadStatus is null"); - final String quotedCursorField = RelationalDbQueryUtils.enquoteIdentifier(pkInfo.pkFieldName(), quoteString); - final String sql; - // We cannot load in chunks for a composite key load, since each field might not have distinct - // values. - if (isCompositeKeyLoad) { - sql = String.format("SELECT %s FROM %s ORDER BY %s", wrappedColumnNames, fullTableName, - quotedCursorField); - } else { - sql = String.format("SELECT %s FROM %s ORDER BY %s LIMIT %s", wrappedColumnNames, fullTableName, - quotedCursorField, chunkSize); - } - final PreparedStatement preparedStatement = connection.prepareStatement(sql); - LOGGER.info("Executing query for table {}: {}", tableName, preparedStatement); - return preparedStatement; - } else { - LOGGER.info("pkLoadStatus value is : {}", pkLoadStatus.getPkVal()); - final String quotedCursorField = RelationalDbQueryUtils.enquoteIdentifier(pkLoadStatus.getPkName(), quoteString); - final String sql; - // We cannot load in chunks for a composite key load, since each field might not have distinct - // values. Furthermore, we have to issue a >= - // query since we may not have processed all of the data associated with the last saved primary key - // value. - if (isCompositeKeyLoad) { - sql = String.format("SELECT %s FROM %s WHERE %s >= ? ORDER BY %s", wrappedColumnNames, fullTableName, - quotedCursorField, quotedCursorField); - } else { - // The pk max value could be null - this can happen in the case of empty tables. In this case, we - // can just issue a query - // without any chunking. - if (pkInfo.pkMaxValue() != null) { - sql = String.format("SELECT %s FROM %s WHERE %s > ? AND %s <= ? ORDER BY %s LIMIT %s", wrappedColumnNames, fullTableName, - quotedCursorField, quotedCursorField, quotedCursorField, chunkSize); - } else { - sql = String.format("SELECT %s FROM %s WHERE %s > ? ORDER BY %s", wrappedColumnNames, fullTableName, - quotedCursorField, quotedCursorField); - } - } - final PreparedStatement preparedStatement = connection.prepareStatement(sql); - final MysqlType cursorFieldType = pkInfo.fieldType(); - sourceOperations.setCursorField(preparedStatement, 1, cursorFieldType, pkLoadStatus.getPkVal()); - if (!isCompositeKeyLoad && pkInfo.pkMaxValue() != null) { - sourceOperations.setCursorField(preparedStatement, 2, cursorFieldType, pkInfo.pkMaxValue()); - } - LOGGER.info("Executing query for table {}: {}", tableName, preparedStatement); - return preparedStatement; - } - } catch (final SQLException e) { - throw new RuntimeException(e); - } - } - - @Override - public void close() throws Exception { - if (currentIterator != null) { - currentIterator.close(); - } - } - - @Override - public Optional getAirbyteStream() { - return Optional.of(pair); - } - - private boolean isCdcSync(MySqlInitialLoadStateManager initialLoadStateManager) { - if (initialLoadStateManager instanceof MySqlInitialLoadGlobalStateManager) { - LOGGER.info("Running a cdc sync"); - return true; - } else { - LOGGER.info("Not running a cdc sync"); - return false; - } - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialLoadStateManager.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialLoadStateManager.java deleted file mode 100644 index 6109191bcedf..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialLoadStateManager.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.initialsync; - -import com.fasterxml.jackson.databind.JsonNode; -import io.airbyte.cdk.integrations.source.relationaldb.state.SourceStateMessageProducer; -import io.airbyte.integrations.source.mysql.initialsync.MySqlInitialReadUtil.PrimaryKeyInfo; -import io.airbyte.integrations.source.mysql.internal.models.InternalModels.StateType; -import io.airbyte.integrations.source.mysql.internal.models.PrimaryKeyLoadStatus; -import io.airbyte.protocol.models.AirbyteStreamNameNamespacePair; -import io.airbyte.protocol.models.v0.AirbyteMessage; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.function.Function; - -public abstract class MySqlInitialLoadStateManager implements SourceStateMessageProducer { - - public static final long MYSQL_STATUS_VERSION = 2; - public static final String STATE_TYPE_KEY = "state_type"; - public static final String PRIMARY_KEY_STATE_TYPE = "primary_key"; - - protected Function streamStateForIncrementalRunSupplier; - - protected Map pairToPrimaryKeyLoadStatus; - - // Map of pair to the primary key info (field name & data type) associated with it. - protected Map pairToPrimaryKeyInfo; - - void setStreamStateForIncrementalRunSupplier(final Function streamStateForIncrementalRunSupplier) { - this.streamStateForIncrementalRunSupplier = streamStateForIncrementalRunSupplier; - } - - // Updates the {@link PrimaryKeyLoadStatus} for the state associated with the given pair - public void updatePrimaryKeyLoadState(final AirbyteStreamNameNamespacePair pair, final PrimaryKeyLoadStatus pkLoadStatus) { - pairToPrimaryKeyLoadStatus.put(pair, pkLoadStatus); - } - - // Returns the previous state emitted, represented as a {@link PrimaryKeyLoadStatus} associated with - // the stream. - public PrimaryKeyLoadStatus getPrimaryKeyLoadStatus(final AirbyteStreamNameNamespacePair pair) { - return pairToPrimaryKeyLoadStatus.get(pair); - } - - // Returns the current {@PrimaryKeyInfo}, associated with the stream. This includes the data type & - // the column name associated with the stream. - public abstract PrimaryKeyInfo getPrimaryKeyInfo(final AirbyteStreamNameNamespacePair pair); - - protected JsonNode getIncrementalState(final AirbyteStreamNameNamespacePair pair) { - final PrimaryKeyLoadStatus currentPkLoadStatus = getPrimaryKeyLoadStatus(pair); - return (currentPkLoadStatus == null || currentPkLoadStatus.getIncrementalState() == null) ? streamStateForIncrementalRunSupplier.apply(pair) - : currentPkLoadStatus.getIncrementalState(); - } - - @Override - public AirbyteMessage processRecordMessage(final ConfiguredAirbyteStream stream, final AirbyteMessage message) { - if (Objects.nonNull(message)) { - final AirbyteStreamNameNamespacePair pair = new AirbyteStreamNameNamespacePair(stream.getStream().getName(), stream.getStream().getNamespace()); - final String pkFieldName = this.getPrimaryKeyInfo(pair).pkFieldName(); - final String lastPk = message.getRecord().getData().get(pkFieldName).asText(); - final PrimaryKeyLoadStatus pkStatus = new PrimaryKeyLoadStatus() - .withVersion(MYSQL_STATUS_VERSION) - .withStateType(StateType.PRIMARY_KEY) - .withPkName(pkFieldName) - .withPkVal(lastPk) - .withIncrementalState(getIncrementalState(pair)); - this.updatePrimaryKeyLoadState(pair, pkStatus); - } - return message; - } - - @Override - public boolean shouldEmitStateMessage(final ConfiguredAirbyteStream stream) { - return true; - } - - public static Map initPairToPrimaryKeyLoadStatusMap( - final Map pairToPkStatus) { - final Map map = new HashMap<>(); - pairToPkStatus.forEach((pair, pkStatus) -> { - final AirbyteStreamNameNamespacePair updatedPair = new AirbyteStreamNameNamespacePair(pair.getName(), pair.getNamespace()); - map.put(updatedPair, pkStatus); - }); - return map; - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialLoadStreamStateManager.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialLoadStreamStateManager.java deleted file mode 100644 index 3cf91c569226..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialLoadStreamStateManager.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.initialsync; - -import com.fasterxml.jackson.databind.JsonNode; -import io.airbyte.commons.json.Jsons; -import io.airbyte.integrations.source.mysql.initialsync.MySqlInitialReadUtil.InitialLoadStreams; -import io.airbyte.integrations.source.mysql.initialsync.MySqlInitialReadUtil.PrimaryKeyInfo; -import io.airbyte.protocol.models.AirbyteStreamNameNamespacePair; -import io.airbyte.protocol.models.v0.AirbyteStateMessage; -import io.airbyte.protocol.models.v0.AirbyteStateMessage.AirbyteStateType; -import io.airbyte.protocol.models.v0.AirbyteStreamState; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; -import io.airbyte.protocol.models.v0.StreamDescriptor; -import java.util.Map; -import java.util.Objects; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This state manager extends the StreamStateManager to enable writing the state_type and version - * keys to the stream state when they're going through the iterator Once we have verified that - * expanding StreamStateManager itself to include this functionality, this class will be removed - */ -public class MySqlInitialLoadStreamStateManager extends MySqlInitialLoadStateManager { - - private static final Logger LOGGER = LoggerFactory.getLogger(MySqlInitialLoadStreamStateManager.class); - - public MySqlInitialLoadStreamStateManager(final ConfiguredAirbyteCatalog catalog, - final InitialLoadStreams initialLoadStreams, - final Map pairToPrimaryKeyInfo) { - this.pairToPrimaryKeyInfo = pairToPrimaryKeyInfo; - this.pairToPrimaryKeyLoadStatus = MySqlInitialLoadStateManager.initPairToPrimaryKeyLoadStatusMap(initialLoadStreams.pairToInitialLoadStatus()); - this.streamStateForIncrementalRunSupplier = pair -> Jsons.emptyObject(); - } - - @Override - public AirbyteStateMessage createFinalStateMessage(final ConfiguredAirbyteStream stream) { - AirbyteStreamNameNamespacePair pair = new AirbyteStreamNameNamespacePair(stream.getStream().getName(), stream.getStream().getNamespace()); - final JsonNode incrementalState = getIncrementalState(pair); - if (incrementalState == null || incrementalState.isEmpty()) { - // resumeable full refresh - return generateStateMessageAtCheckpoint(stream); - } - - return new AirbyteStateMessage() - .withType(AirbyteStateType.STREAM) - .withStream(getAirbyteStreamState(pair, incrementalState)); - } - - @Override - public PrimaryKeyInfo getPrimaryKeyInfo(final io.airbyte.protocol.models.AirbyteStreamNameNamespacePair pair) { - return pairToPrimaryKeyInfo.get(pair); - } - - @Override - public AirbyteStateMessage generateStateMessageAtCheckpoint(final ConfiguredAirbyteStream stream) { - AirbyteStreamNameNamespacePair pair = new AirbyteStreamNameNamespacePair(stream.getStream().getName(), stream.getStream().getNamespace()); - var pkStatus = getPrimaryKeyLoadStatus(pair); - return new AirbyteStateMessage() - .withType(AirbyteStateType.STREAM) - .withStream(getAirbyteStreamState(pair, Jsons.jsonNode(pkStatus))); - } - - protected AirbyteStreamState getAirbyteStreamState(final io.airbyte.protocol.models.AirbyteStreamNameNamespacePair pair, final JsonNode stateData) { - LOGGER.info("STATE DATA FOR {}: {}", pair.getNamespace().concat("_").concat(pair.getName()), stateData); - assert Objects.nonNull(pair.getName()); - assert Objects.nonNull(pair.getNamespace()); - - return new AirbyteStreamState() - .withStreamDescriptor( - new StreamDescriptor().withName(pair.getName()).withNamespace(pair.getNamespace())) - .withStreamState(stateData); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialReadUtil.java b/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialReadUtil.java deleted file mode 100644 index 3a7d99c2805f..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/java/io/airbyte/integrations/source/mysql/initialsync/MySqlInitialReadUtil.java +++ /dev/null @@ -1,582 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql.initialsync; - -import static io.airbyte.cdk.db.DbAnalyticsUtils.cdcCursorInvalidMessage; -import static io.airbyte.cdk.db.DbAnalyticsUtils.cdcResyncMessage; -import static io.airbyte.cdk.db.DbAnalyticsUtils.wassOccurrenceMessage; -import static io.airbyte.integrations.source.mysql.MySqlQueryUtils.getTableSizeInfoForStreams; -import static io.airbyte.integrations.source.mysql.MySqlSpecConstants.FAIL_SYNC_OPTION; -import static io.airbyte.integrations.source.mysql.MySqlSpecConstants.INVALID_CDC_CURSOR_POSITION_PROPERTY; -import static io.airbyte.integrations.source.mysql.MySqlSpecConstants.RESYNC_DATA_OPTION; -import static io.airbyte.integrations.source.mysql.cdc.MysqlCdcStateConstants.MYSQL_CDC_OFFSET; -import static io.airbyte.integrations.source.mysql.initialsync.MySqlInitialLoadGlobalStateManager.STATE_TYPE_KEY; -import static io.airbyte.integrations.source.mysql.initialsync.MySqlInitialLoadStateManager.PRIMARY_KEY_STATE_TYPE; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.collect.Sets; -import com.mysql.cj.MysqlType; -import io.airbyte.cdk.db.jdbc.JdbcDatabase; -import io.airbyte.cdk.integrations.base.AirbyteTraceMessageUtility; -import io.airbyte.cdk.integrations.debezium.AirbyteDebeziumHandler; -import io.airbyte.cdk.integrations.debezium.internals.DebeziumEventConverter; -import io.airbyte.cdk.integrations.debezium.internals.RecordWaitTimeUtil; -import io.airbyte.cdk.integrations.debezium.internals.RelationalDbDebeziumEventConverter; -import io.airbyte.cdk.integrations.debezium.internals.RelationalDbDebeziumPropertiesManager; -import io.airbyte.cdk.integrations.source.relationaldb.CdcStateManager; -import io.airbyte.cdk.integrations.source.relationaldb.DbSourceDiscoverUtil; -import io.airbyte.cdk.integrations.source.relationaldb.InitialLoadTimeoutUtil; -import io.airbyte.cdk.integrations.source.relationaldb.TableInfo; -import io.airbyte.cdk.integrations.source.relationaldb.models.CdcState; -import io.airbyte.cdk.integrations.source.relationaldb.state.StateManager; -import io.airbyte.cdk.integrations.source.relationaldb.streamstatus.StreamStatusTraceEmitterIterator; -import io.airbyte.commons.exceptions.ConfigErrorException; -import io.airbyte.commons.json.Jsons; -import io.airbyte.commons.stream.AirbyteStreamStatusHolder; -import io.airbyte.commons.util.AutoCloseableIterator; -import io.airbyte.commons.util.AutoCloseableIterators; -import io.airbyte.integrations.source.mysql.MySqlQueryUtils; -import io.airbyte.integrations.source.mysql.MySqlSourceOperations; -import io.airbyte.integrations.source.mysql.cdc.MySqlCdcConnectorMetadataInjector; -import io.airbyte.integrations.source.mysql.cdc.MySqlCdcPosition; -import io.airbyte.integrations.source.mysql.cdc.MySqlCdcProperties; -import io.airbyte.integrations.source.mysql.cdc.MySqlCdcSavedInfoFetcher; -import io.airbyte.integrations.source.mysql.cdc.MySqlCdcStateHandler; -import io.airbyte.integrations.source.mysql.cdc.MySqlCdcTargetPosition; -import io.airbyte.integrations.source.mysql.cdc.MySqlDebeziumStateUtil; -import io.airbyte.integrations.source.mysql.cdc.MySqlDebeziumStateUtil.MysqlDebeziumStateAttributes; -import io.airbyte.integrations.source.mysql.internal.models.CursorBasedStatus; -import io.airbyte.integrations.source.mysql.internal.models.PrimaryKeyLoadStatus; -import io.airbyte.protocol.models.CommonField; -import io.airbyte.protocol.models.v0.*; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class MySqlInitialReadUtil { - - private static final Logger LOGGER = LoggerFactory.getLogger(MySqlInitialReadUtil.class); - - public static Optional getMySqlFullRefreshInitialLoadHandler(final JdbcDatabase database, - final ConfiguredAirbyteCatalog catalog, - final MySqlInitialLoadGlobalStateManager initialLoadStateManager, - final StateManager stateManager, - final ConfiguredAirbyteStream fullRefreshStream, - final Instant emittedAt, - final String quoteString, - final boolean savedOffsetStillPresentOnServer) { - final InitialLoadStreams initialLoadStreams = - cdcStreamsForInitialPrimaryKeyLoad(stateManager.getCdcStateManager(), catalog, savedOffsetStillPresentOnServer); - - // State manager will need to know all streams in order to produce a state message - // But for initial load handler we only want to produce iterator on the single full refresh stream. - if (!initialLoadStreams.streamsForInitialLoad().isEmpty()) { - - // Filter on initialLoadStream - final var pair = new AirbyteStreamNameNamespacePair(fullRefreshStream.getStream().getName(), fullRefreshStream.getStream().getNamespace()); - final var pkStatus = initialLoadStreams.pairToInitialLoadStatus.get(pair); - final Map fullRefreshPkStatus; - if (pkStatus == null) { - fullRefreshPkStatus = Map.of(); - } else { - fullRefreshPkStatus = Map.of(pair, pkStatus); - } - - var fullRefreshStreamInitialLoad = new InitialLoadStreams(List.of(fullRefreshStream), - fullRefreshPkStatus); - return Optional - .of(getMySqlInitialLoadHandler(database, emittedAt, quoteString, fullRefreshStreamInitialLoad, initialLoadStateManager, Optional.empty())); - } - return Optional.empty(); - } - - private static MySqlInitialLoadHandler getMySqlInitialLoadHandler( - final JdbcDatabase database, - final Instant emittedAt, - final String quoteString, - final InitialLoadStreams initialLoadStreams, - final MySqlInitialLoadStateManager initialLoadStateManager, - final Optional cdcMetadataInjector) { - final JsonNode sourceConfig = database.getSourceConfig(); - - final MySqlSourceOperations sourceOperations = - new MySqlSourceOperations(cdcMetadataInjector); - return new MySqlInitialLoadHandler(sourceConfig, database, - sourceOperations, - quoteString, - initialLoadStateManager, - Optional.empty(), - getTableSizeInfoForStreams(database, initialLoadStreams.streamsForInitialLoad(), quoteString)); - } - - private static CdcState getDefaultCdcState(final JdbcDatabase database, - final ConfiguredAirbyteCatalog catalog) { - - // Construct the initial state for MySQL. If there is already existing state, we use that instead - // since that is associated with the debezium - // state associated with the initial sync. - final MySqlDebeziumStateUtil mySqlDebeziumStateUtil = new MySqlDebeziumStateUtil(); - final JsonNode initialDebeziumState = mySqlDebeziumStateUtil.constructInitialDebeziumState( - MySqlCdcProperties.getDebeziumProperties(database), catalog, database); - return new CdcState().withState(initialDebeziumState); - } - - public static boolean isSavedOffsetStillPresentOnServer(final JdbcDatabase database, - final ConfiguredAirbyteCatalog catalog, - final StateManager stateManager) { - final MySqlDebeziumStateUtil mySqlDebeziumStateUtil = new MySqlDebeziumStateUtil(); - final JsonNode sourceConfig = database.getSourceConfig(); - final JsonNode initialDebeziumState = mySqlDebeziumStateUtil.constructInitialDebeziumState( - MySqlCdcProperties.getDebeziumProperties(database), catalog, database); - - final JsonNode state = - (stateManager.getCdcStateManager().getCdcState() == null || stateManager.getCdcStateManager().getCdcState().getState() == null) - ? initialDebeziumState - : Jsons.clone(stateManager.getCdcStateManager().getCdcState().getState()); - - final Optional savedOffset = mySqlDebeziumStateUtil.savedOffset( - MySqlCdcProperties.getDebeziumProperties(database), catalog, state.get(MYSQL_CDC_OFFSET), sourceConfig); - - final boolean savedOffsetStillPresentOnServer = - savedOffset.isPresent() && mySqlDebeziumStateUtil.savedOffsetStillPresentOnServer(database, savedOffset.get()); - if (!savedOffsetStillPresentOnServer) { - AirbyteTraceMessageUtility.emitAnalyticsTrace(cdcCursorInvalidMessage()); - if (!sourceConfig.get("replication_method").has(INVALID_CDC_CURSOR_POSITION_PROPERTY) || sourceConfig.get("replication_method").get( - INVALID_CDC_CURSOR_POSITION_PROPERTY).asText().equals(FAIL_SYNC_OPTION)) { - throw new ConfigErrorException( - "Saved offset no longer present on the server. Please reset the connection, and then increase binlog retention and/or increase sync frequency. See https://docs.airbyte.com/integrations/sources/mysql/mysql-troubleshooting#under-cdc-incremental-mode-there-are-still-full-refresh-syncs for more details."); - } else if (sourceConfig.get("replication_method").get(INVALID_CDC_CURSOR_POSITION_PROPERTY).asText().equals(RESYNC_DATA_OPTION)) { - AirbyteTraceMessageUtility.emitAnalyticsTrace(cdcResyncMessage()); - LOGGER.warn("Saved offset no longer present on the server, Airbyte is going to trigger a sync from scratch"); - } - } - return savedOffsetStillPresentOnServer; - } - - public static MySqlInitialLoadGlobalStateManager getMySqlInitialLoadGlobalStateManager(final JdbcDatabase database, - final ConfiguredAirbyteCatalog catalog, - final StateManager stateManager, - final Map>> tableNameToTable, - final String quoteString, - final boolean savedOffsetStillPresentOnServer) { - final InitialLoadStreams initialLoadStreams = - cdcStreamsForInitialPrimaryKeyLoad(stateManager.getCdcStateManager(), catalog, savedOffsetStillPresentOnServer); - - return new MySqlInitialLoadGlobalStateManager(initialLoadStreams, - initPairToPrimaryKeyInfoMap(database, catalog, tableNameToTable, quoteString), - stateManager, catalog, savedOffsetStillPresentOnServer, getDefaultCdcState(database, catalog)); - } - - /* - * Returns the read iterators associated with : 1. Initial cdc read snapshot via primary key - * queries. 2. Incremental cdc reads via debezium. - * - * The initial load iterators need to always be run before the incremental cdc iterators. This is to - * prevent advancing the binlog offset in the state before all streams have snapshotted. Otherwise, - * there could be data loss. - */ - public static List> getCdcReadIterators(final JdbcDatabase database, - final ConfiguredAirbyteCatalog catalog, - final Map>> tableNameToTable, - final StateManager stateManager, - final MySqlInitialLoadGlobalStateManager initialLoadGlobalStateManager, - final Instant emittedAt, - final String quoteString, - final boolean savedOffsetStillPresentOnServer) { - final JsonNode sourceConfig = database.getSourceConfig(); - final Duration firstRecordWaitTime = RecordWaitTimeUtil.getFirstRecordWaitTime(sourceConfig); - LOGGER.info("First record waiting time: {} seconds", firstRecordWaitTime.getSeconds()); - final Duration initialLoadTimeout = InitialLoadTimeoutUtil.getInitialLoadTimeout(sourceConfig); - // Determine the streams that need to be loaded via primary key sync. - final List> initialLoadIterator = new ArrayList<>(); - final InitialLoadStreams initialLoadStreams = - cdcStreamsForInitialPrimaryKeyLoad(stateManager.getCdcStateManager(), catalog, savedOffsetStillPresentOnServer); - - final MySqlCdcConnectorMetadataInjector metadataInjector = MySqlCdcConnectorMetadataInjector.getInstance(emittedAt); - final CdcState stateToBeUsed; - final CdcState cdcState = stateManager.getCdcStateManager().getCdcState(); - if (!savedOffsetStillPresentOnServer || cdcState == null - || cdcState.getState() == null) { - stateToBeUsed = getDefaultCdcState(database, catalog); - } else { - stateToBeUsed = cdcState; - } - - // Debezium is started for streams that have been started - that is they have been partially or - // fully completed. - final var startedCdcStreamList = catalog.getStreams().stream() - .filter(stream -> stream.getSyncMode() == SyncMode.INCREMENTAL) - .filter(stream -> isStreamPartiallyOrFullyCompleted(stream, initialLoadStreams)) - .map(stream -> stream.getStream().getNamespace() + "." + stream.getStream().getName()).toList(); - - final var allCdcStreamList = catalog.getStreams().stream() - .filter(stream -> stream.getSyncMode() == SyncMode.INCREMENTAL) - .map(stream -> stream.getStream().getNamespace() + "." + stream.getStream().getName()).toList(); - - // If there are streams to sync via primary key load, build the relevant iterators. - if (!initialLoadStreams.streamsForInitialLoad().isEmpty()) { - - final MysqlDebeziumStateAttributes stateAttributes = MySqlDebeziumStateUtil.getStateAttributesFromDB(database); - - final MySqlInitialLoadHandler initialLoadHandler = - getMySqlInitialLoadHandler(database, emittedAt, quoteString, initialLoadStreams, initialLoadGlobalStateManager, - Optional.of(new CdcMetadataInjector(emittedAt.toString(), stateAttributes, metadataInjector))); - - // Start and complete stream status messages are emitted while constructing the full set of initial - // load and incremental debezium iterators. - initialLoadIterator.addAll(initialLoadHandler.getIncrementalIterators( - new ConfiguredAirbyteCatalog().withStreams(initialLoadStreams.streamsForInitialLoad()), - tableNameToTable, - emittedAt, false, false, Optional.of(initialLoadTimeout))); - } - - // CDC stream status messages should be emitted for streams. - final List> cdcStreamsStartStatusEmitters = catalog.getStreams().stream() - .filter(stream -> stream.getSyncMode() == SyncMode.INCREMENTAL) - .map(stream -> (AutoCloseableIterator) new StreamStatusTraceEmitterIterator( - new AirbyteStreamStatusHolder( - new io.airbyte.protocol.models.AirbyteStreamNameNamespacePair(stream.getStream().getName(), stream.getStream().getNamespace()), - AirbyteStreamStatusTraceMessage.AirbyteStreamStatus.STARTED))) - .toList(); - - final List> cdcStreamsEndStatusEmitters = catalog.getStreams().stream() - .filter(stream -> stream.getSyncMode() == SyncMode.INCREMENTAL) - .map(stream -> (AutoCloseableIterator) new StreamStatusTraceEmitterIterator( - new AirbyteStreamStatusHolder( - new io.airbyte.protocol.models.AirbyteStreamNameNamespacePair(stream.getStream().getName(), stream.getStream().getNamespace()), - AirbyteStreamStatusTraceMessage.AirbyteStreamStatus.COMPLETE))) - .toList(); - - // Build the incremental CDC iterators. - final AirbyteDebeziumHandler handler = new AirbyteDebeziumHandler( - sourceConfig, - MySqlCdcTargetPosition.targetPosition(database), - true, - firstRecordWaitTime, - AirbyteDebeziumHandler.QUEUE_CAPACITY, - false); - final var eventConverter = new RelationalDbDebeziumEventConverter(metadataInjector, emittedAt); - - if (startedCdcStreamList.isEmpty()) { - LOGGER.info("First sync - no cdc streams have been completed or started"); - /* - * This is the first run case - no initial loads have been started. In this case, we want to run the - * iterators in the following order: 1. Run the initial load iterators. This step will timeout and - * throw a transient error if run for too long (> 8hrs by default). 2. Run the debezium iterators - * with ALL of the incremental streams configured. This is because if step 1 completes, the initial - * load can be considered finished. - */ - final var propertiesManager = new RelationalDbDebeziumPropertiesManager( - MySqlCdcProperties.getDebeziumProperties(database), sourceConfig, catalog, allCdcStreamList); - final Supplier> incrementalIteratorsSupplier = getCdcIncrementalIteratorsSupplier(handler, - propertiesManager, eventConverter, stateToBeUsed, stateManager); - return Collections.singletonList( - AutoCloseableIterators.concatWithEagerClose( - Stream - .of( - cdcStreamsStartStatusEmitters, - initialLoadIterator, - Collections.singletonList(AutoCloseableIterators.lazyIterator(incrementalIteratorsSupplier, null)), - cdcStreamsEndStatusEmitters) - .flatMap(Collection::stream) - .collect(Collectors.toList()), - AirbyteTraceMessageUtility::emitStreamStatusTrace)); - } else if (initialLoadIterator.isEmpty()) { - LOGGER.info("Initial load has finished completely - only reading the binlog"); - /* - * In this case, the initial load has completed and only debezium should be run. The iterators - * should be run in the following order: 1. Run the debezium iterators with ALL of the incremental - * streams configured. - */ - final var propertiesManager = new RelationalDbDebeziumPropertiesManager( - MySqlCdcProperties.getDebeziumProperties(database), sourceConfig, catalog, allCdcStreamList); - final Supplier> incrementalIteratorSupplier = getCdcIncrementalIteratorsSupplier(handler, - propertiesManager, eventConverter, stateToBeUsed, stateManager); - return Collections.singletonList( - AutoCloseableIterators.concatWithEagerClose( - Stream - .of( - cdcStreamsStartStatusEmitters, - Collections.singletonList(AutoCloseableIterators.lazyIterator(incrementalIteratorSupplier, null)), - cdcStreamsEndStatusEmitters) - .flatMap(Collection::stream) - .collect(Collectors.toList()), - AirbyteTraceMessageUtility::emitStreamStatusTrace)); - } else { - LOGGER.info("Initial load is in progress - reading binlog first and then resuming with initial load."); - /* - * In this case, the initial load has partially completed (WASS case). The iterators should be run - * in the following order: 1. Run the debezium iterators with only the incremental streams which - * have been fully or partially completed configured. 2. Resume initial load for partially completed - * and not started streams. This step will timeout and throw a transient error if run for too long - * (> 8hrs by default). - */ - AirbyteTraceMessageUtility.emitAnalyticsTrace(wassOccurrenceMessage()); - final var propertiesManager = new RelationalDbDebeziumPropertiesManager( - MySqlCdcProperties.getDebeziumProperties(database), sourceConfig, catalog, startedCdcStreamList); - final Supplier> incrementalIteratorSupplier = getCdcIncrementalIteratorsSupplier(handler, - propertiesManager, eventConverter, stateToBeUsed, stateManager); - return Collections.singletonList( - AutoCloseableIterators.concatWithEagerClose( - Stream - .of( - cdcStreamsStartStatusEmitters, - Collections.singletonList(AutoCloseableIterators.lazyIterator(incrementalIteratorSupplier, null)), - initialLoadIterator, - cdcStreamsEndStatusEmitters) - .flatMap(Collection::stream) - .collect(Collectors.toList()), - AirbyteTraceMessageUtility::emitStreamStatusTrace)); - } - } - - @SuppressWarnings("unchecked") - private static Supplier> getCdcIncrementalIteratorsSupplier(AirbyteDebeziumHandler handler, - RelationalDbDebeziumPropertiesManager propertiesManager, - DebeziumEventConverter eventConverter, - CdcState stateToBeUsed, - StateManager stateManager) { - return () -> handler.getIncrementalIterators( - propertiesManager, eventConverter, new MySqlCdcSavedInfoFetcher(stateToBeUsed), new MySqlCdcStateHandler(stateManager)); - } - - /** - * CDC specific: Determines the streams to sync for initial primary key load. These include streams - * that are (i) currently in primary key load (ii) newly added incremental streams. - */ - public static InitialLoadStreams cdcStreamsForInitialPrimaryKeyLoad(final CdcStateManager stateManager, - final ConfiguredAirbyteCatalog fullCatalog, - final boolean savedOffsetStillPresentOnServer) { - - if (!savedOffsetStillPresentOnServer) { - // Add a filter here to identify resumable full refresh streams. - return new InitialLoadStreams( - fullCatalog.getStreams() - .stream() - .collect(Collectors.toList()), - new HashMap<>()); - } - - final AirbyteStateMessage airbyteStateMessage = stateManager.getRawStateMessage(); - final Set streamsStillinPkSync = new HashSet<>(); - - // Build a map of stream <-> initial load status for streams that currently have an initial primary - // key load in progress. - final Map pairToInitialLoadStatus = new HashMap<>(); - if (airbyteStateMessage != null && airbyteStateMessage.getGlobal() != null && airbyteStateMessage.getGlobal().getStreamStates() != null) { - airbyteStateMessage.getGlobal().getStreamStates().forEach(stateMessage -> { - final JsonNode streamState = stateMessage.getStreamState(); - final StreamDescriptor streamDescriptor = stateMessage.getStreamDescriptor(); - if (streamState == null || streamDescriptor == null) { - return; - } - - if (streamState.has(STATE_TYPE_KEY)) { - if (streamState.get(STATE_TYPE_KEY).asText().equalsIgnoreCase(PRIMARY_KEY_STATE_TYPE)) { - final PrimaryKeyLoadStatus primaryKeyLoadStatus = Jsons.object(streamState, PrimaryKeyLoadStatus.class); - final AirbyteStreamNameNamespacePair pair = new AirbyteStreamNameNamespacePair(streamDescriptor.getName(), - streamDescriptor.getNamespace()); - pairToInitialLoadStatus.put(pair, primaryKeyLoadStatus); - streamsStillinPkSync.add(pair); - } - } - }); - } - - final List streamsForPkSync = new ArrayList<>(); - fullCatalog.getStreams().stream() - .filter(stream -> streamsStillinPkSync.contains(AirbyteStreamNameNamespacePair.fromAirbyteStream(stream.getStream()))) - .map(Jsons::clone) - .forEach(streamsForPkSync::add); - final List newlyAddedStreams = - identifyStreamsToSnapshot(fullCatalog, stateManager.getInitialStreamsSynced()); - streamsForPkSync.addAll(newlyAddedStreams); - - return new InitialLoadStreams(streamsForPkSync, pairToInitialLoadStatus); - } - - /** - * Determines the streams to sync for initial primary key load. These include streams that are (i) - * currently in primary key load (ii) newly added incremental streams. - */ - public static InitialLoadStreams streamsForInitialPrimaryKeyLoad(final StateManager stateManager, - final ConfiguredAirbyteCatalog fullCatalog) { - - final List rawStateMessages = stateManager.getRawStateMessages(); - final Set streamsStillInPkSync = new HashSet<>(); - final Set alreadySeenStreamPairs = new HashSet<>(); - - // Build a map of stream <-> initial load status for streams that currently have an initial primary - // key load in progress. - final Map pairToInitialLoadStatus = new HashMap<>(); - - if (rawStateMessages != null) { - rawStateMessages.forEach(stateMessage -> { - final AirbyteStreamState stream = stateMessage.getStream(); - final JsonNode streamState = stream.getStreamState(); - final StreamDescriptor streamDescriptor = stateMessage.getStream().getStreamDescriptor(); - if (streamState == null || streamDescriptor == null) { - return; - } - - final AirbyteStreamNameNamespacePair pair = new AirbyteStreamNameNamespacePair(streamDescriptor.getName(), - streamDescriptor.getNamespace()); - - // Build a map of stream <-> initial load status for streams that currently have an initial primary - // key load in progress. - - if (streamState.has(STATE_TYPE_KEY)) { - if (streamState.get(STATE_TYPE_KEY).asText().equalsIgnoreCase(PRIMARY_KEY_STATE_TYPE)) { - final PrimaryKeyLoadStatus primaryKeyLoadStatus = Jsons.object(streamState, PrimaryKeyLoadStatus.class); - pairToInitialLoadStatus.put(pair, primaryKeyLoadStatus); - streamsStillInPkSync.add(pair); - } - alreadySeenStreamPairs.add(new AirbyteStreamNameNamespacePair(streamDescriptor.getName(), streamDescriptor.getNamespace())); - } - }); - } - final List streamsForPkSync = new ArrayList<>(); - fullCatalog.getStreams().stream() - .filter(stream -> streamsStillInPkSync.contains(AirbyteStreamNameNamespacePair.fromAirbyteStream(stream.getStream()))) - .map(Jsons::clone) - .forEach(streamsForPkSync::add); - - final List newlyAddedStreams = identifyStreamsToSnapshot(fullCatalog, - Collections.unmodifiableSet(alreadySeenStreamPairs)); - streamsForPkSync.addAll(newlyAddedStreams); - return new InitialLoadStreams(streamsForPkSync.stream().filter(MySqlInitialReadUtil::streamHasPrimaryKey).collect(Collectors.toList()), - pairToInitialLoadStatus); - } - - private static boolean streamHasPrimaryKey(final ConfiguredAirbyteStream stream) { - return stream.getStream().getSourceDefinedPrimaryKey().size() > 0; - } - - public static InitialLoadStreams filterStreamInIncrementalMode(final InitialLoadStreams stream) { - return new InitialLoadStreams( - stream.streamsForInitialLoad.stream().filter(airbyteStream -> airbyteStream.getSyncMode() == SyncMode.INCREMENTAL) - .collect(Collectors.toList()), - stream.pairToInitialLoadStatus); - } - - public static List identifyStreamsToSnapshot(final ConfiguredAirbyteCatalog catalog, - final Set alreadySyncedStreams) { - final Set allStreams = AirbyteStreamNameNamespacePair.fromConfiguredCatalog(catalog); - final Set newlyAddedStreams = new HashSet<>(Sets.difference(allStreams, alreadySyncedStreams)); - // Add a filter here to exclude non resumable full refresh streams. - return catalog.getStreams().stream() - .filter(stream -> newlyAddedStreams.contains(AirbyteStreamNameNamespacePair.fromAirbyteStream(stream.getStream()))) - .map(Jsons::clone) - .collect(Collectors.toList()); - } - - public static List identifyStreamsForCursorBased(final ConfiguredAirbyteCatalog catalog, - final List streamsForInitialLoad) { - - final Set initialLoadStreamsNamespacePairs = - streamsForInitialLoad.stream().map(stream -> AirbyteStreamNameNamespacePair.fromAirbyteStream(stream.getStream())) - .collect( - Collectors.toSet()); - return catalog.getStreams().stream() - .filter(stream -> !initialLoadStreamsNamespacePairs.contains(AirbyteStreamNameNamespacePair.fromAirbyteStream(stream.getStream()))) - .map(Jsons::clone) - .collect(Collectors.toList()); - } - - // Build a map of stream <-> primary key info (primary key field name + datatype) for all streams - // currently undergoing initial primary key syncs. - public static Map initPairToPrimaryKeyInfoMap( - final JdbcDatabase database, - final ConfiguredAirbyteCatalog catalog, - final Map>> tableNameToTable, - final String quoteString) { - final Map pairToPkInfoMap = new HashMap<>(); - // For every stream that was in primary initial key sync, we want to maintain information about the - // current primary key info associated with the - // stream - catalog.getStreams().forEach(stream -> { - final io.airbyte.protocol.models.AirbyteStreamNameNamespacePair pair = - new io.airbyte.protocol.models.AirbyteStreamNameNamespacePair(stream.getStream().getName(), stream.getStream().getNamespace()); - final Optional pkInfo = getPrimaryKeyInfo(database, stream, tableNameToTable, quoteString); - if (pkInfo.isPresent()) { - pairToPkInfoMap.put(pair, pkInfo.get()); - } - }); - return pairToPkInfoMap; - } - - // Returns the primary key info associated with the stream. - private static Optional getPrimaryKeyInfo(final JdbcDatabase database, - final ConfiguredAirbyteStream stream, - final Map>> tableNameToTable, - final String quoteString) { - final String fullyQualifiedTableName = - DbSourceDiscoverUtil.getFullyQualifiedTableName(stream.getStream().getNamespace(), (stream.getStream().getName())); - final TableInfo> table = tableNameToTable - .get(fullyQualifiedTableName); - return getPrimaryKeyInfo(database, stream, table, quoteString); - } - - private static Optional getPrimaryKeyInfo(final JdbcDatabase database, - final ConfiguredAirbyteStream stream, - final TableInfo> table, - final String quoteString) { - // For cursor-based syncs, we cannot always assume a primary key field exists. We need to handle the - // case where it does not exist when we support - // cursor-based syncs. - if (stream.getStream().getSourceDefinedPrimaryKey().size() > 1) { - LOGGER.info("Composite primary key detected for {namespace, stream} : {}, {}", stream.getStream().getNamespace(), stream.getStream().getName()); - } - if (stream.getStream().getSourceDefinedPrimaryKey().isEmpty()) { - return Optional.empty(); - } - - final String pkFieldName = stream.getStream().getSourceDefinedPrimaryKey().getFirst().getFirst(); - final MysqlType pkFieldType = table.getFields().stream() - .filter(field -> field.getName().equals(pkFieldName)) - .findFirst().get().getType(); - - final String pkMaxValue = MySqlQueryUtils.getMaxPkValueForStream(database, stream, pkFieldName, quoteString); - return Optional.of(new PrimaryKeyInfo(pkFieldName, pkFieldType, pkMaxValue)); - } - - private static boolean isStreamPartiallyOrFullyCompleted(ConfiguredAirbyteStream stream, InitialLoadStreams initialLoadStreams) { - boolean isStreamCompleted = !initialLoadStreams.streamsForInitialLoad.contains(stream); - // A stream has been partially completed if an initial load status exists. - boolean isStreamPartiallyCompleted = (initialLoadStreams.pairToInitialLoadStatus - .get(new AirbyteStreamNameNamespacePair(stream.getStream().getName(), stream.getStream().getNamespace()))) != null; - return isStreamCompleted || isStreamPartiallyCompleted; - } - - public record InitialLoadStreams(List streamsForInitialLoad, - Map pairToInitialLoadStatus) { - - } - - public record CursorBasedStreams(List streamsForCursorBased, - Map pairToCursorBasedStatus) { - - } - - public record PrimaryKeyInfo(String pkFieldName, MysqlType fieldType, String pkMaxValue) {} - - public static AirbyteStreamNameNamespacePair convertNameNamespacePairFromV0(final io.airbyte.protocol.models.AirbyteStreamNameNamespacePair v1NameNamespacePair) { - return new AirbyteStreamNameNamespacePair(v1NameNamespacePair.getName(), v1NameNamespacePair.getNamespace()); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/MySqlSourceExceptionHandler.kt b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/MySqlSourceExceptionHandler.kt deleted file mode 100644 index 7853afc08fb4..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/MySqlSourceExceptionHandler.kt +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ -package io.airbyte.integrations.source.mysql - -import io.airbyte.cdk.integrations.util.ConnectorErrorProfile -import io.airbyte.cdk.integrations.util.ConnectorExceptionHandler -import io.airbyte.cdk.integrations.util.FailureType - -class MySqlSourceExceptionHandler : ConnectorExceptionHandler() { - override fun initializeErrorDictionary() { - // adding common error profiles - super.initializeErrorDictionary() - // adding connector specific error profiles - add( - ConnectorErrorProfile( - errorClass = "MySQL Syntax Exception", - regexMatchingPattern = ".*unknown column '.+' in 'field list'.*", - failureType = FailureType.CONFIG, - externalMessage = - "A column needed by MySQL source connector is missing in the database", - sampleInternalMessage = "Unknown column 'X' in 'field list'", - ), - ) - - add( - ConnectorErrorProfile( - errorClass = "MySQL EOF Exception", - regexMatchingPattern = - ".*can not read response from server. expected to read [1-9]\\d* bytes.*", - failureType = FailureType.TRANSIENT, - externalMessage = "Can not read data from MySQL server", - sampleInternalMessage = - "java.io.EOFException: Can not read response from server. Expected to read X bytes, read Y bytes before connection was unexpectedly lost.", - ), - ) - - add( - ConnectorErrorProfile( - errorClass = "MySQL Hikari Connection Error", - regexMatchingPattern = ".*connection is not available, request timed out after*", - failureType = FailureType.TRANSIENT, - externalMessage = "Database read failed due to connection timeout, will retry.", - sampleInternalMessage = - "java.sql.SQLTransientConnectionException: HikariPool-x - Connection is not available, request timed out after xms", - referenceLinks = listOf("https://github.com/airbytehq/airbyte/issues/41614"), - ), - ) - - add( - ConnectorErrorProfile( - errorClass = "MySQL Timezone Error", - regexMatchingPattern = ".*is unrecognized or represents more than one time zone*", - failureType = FailureType.CONFIG, - externalMessage = - "Please configure your database with the correct timezone found in the detailed error message. " + - "Please refer to the following documentation: https://dev.mysql.com/doc/refman/8.4/en/time-zone-support.html", - sampleInternalMessage = - "java.lang.RuntimeException: Connector configuration is not valid. Unable to connect: " + - "The server time zone value 'PDT' is unrecognized or represents more than one time zone. " + - "You must configure either the server or JDBC driver (via the 'connectionTimeZone' configuration property) to " + - "use a more specific time zone value if you want to utilize time zone support.", - referenceLinks = - listOf( - "https://github.com/airbytehq/airbyte/issues/41614", - "https://github.com/airbytehq/oncall/issues/5250", - ), - ), - ) - - add( - ConnectorErrorProfile( - errorClass = "MySQL Schema change error", - regexMatchingPattern = ".*whose schema isn't known to this connector*", - failureType = FailureType.CONFIG, - externalMessage = - "Your connection could not be completed because changes were detected on an unknown table (see detailed error for the table name), " + - "please refresh your schema or reset the connection.", - sampleInternalMessage = - "java.lang.RuntimeException: java.lang.RuntimeException: org.apache.kafka.connect.errors." + - "ConnectException: An exception occurred in the change event producer. This connector will be stopped.", - referenceLinks = - listOf("https://github.com/airbytehq/airbyte-internal-issues/issues/7156"), - ), - ) - - add( - ConnectorErrorProfile( - errorClass = "MySQL limit reached", - regexMatchingPattern = - ".*query execution was interrupted, maximum statement execution time exceeded*", - failureType = FailureType.TRANSIENT, - externalMessage = - "The query took too long to return results, the database read was aborted. Will retry.", - sampleInternalMessage = - "java.lang.RuntimeException: java.lang.RuntimeException: java.sql.SQLException: " + - "Query execution was interrupted, maximum statement execution time exceeded", - referenceLinks = - listOf("https://github.com/airbytehq/airbyte-internal-issues/issues/7155"), - ), - ) - } -} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSource.kt b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSource.kt new file mode 100644 index 000000000000..29caa56c7aaf --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSource.kt @@ -0,0 +1,11 @@ +/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ +package io.airbyte.integrations.source.mysql + +import io.airbyte.cdk.AirbyteSourceRunner + +object MySqlSource { + @JvmStatic + fun main(args: Array) { + AirbyteSourceRunner.run(*args) + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcBooleanConverter.kt b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcBooleanConverter.kt new file mode 100644 index 000000000000..b29fbcdea228 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcBooleanConverter.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.mysql + +import io.airbyte.cdk.read.cdc.Converted +import io.airbyte.cdk.read.cdc.NoConversion +import io.airbyte.cdk.read.cdc.NullFallThrough +import io.airbyte.cdk.read.cdc.PartialConverter +import io.airbyte.cdk.read.cdc.RelationalColumnCustomConverter +import io.debezium.spi.converter.RelationalColumn +import org.apache.kafka.connect.data.SchemaBuilder + +class MySqlSourceCdcBooleanConverter : RelationalColumnCustomConverter { + + override val debeziumPropertiesKey: String = "boolean" + override val handlers: List = listOf(TinyInt1Handler) + + data object TinyInt1Handler : RelationalColumnCustomConverter.Handler { + + override fun matches(column: RelationalColumn): Boolean = + column.typeName().equals("TINYINT", ignoreCase = true) && + column.length().isPresent && + column.length().asInt == 1 + + override fun outputSchemaBuilder(): SchemaBuilder = SchemaBuilder.bool() + + override val partialConverters: List = + listOf( + NullFallThrough, + PartialConverter { if (it is Number) Converted(it != 0) else NoConversion } + ) + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcInitialSnapshotStateValue.kt b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcInitialSnapshotStateValue.kt new file mode 100644 index 000000000000..621966c080a5 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcInitialSnapshotStateValue.kt @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.mysql + +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.databind.JsonNode +import io.airbyte.cdk.command.OpaqueStateValue +import io.airbyte.cdk.discover.Field +import io.airbyte.cdk.read.Stream +import io.airbyte.cdk.util.Jsons + +data class MySqlSourceCdcInitialSnapshotStateValue( + @JsonProperty("pk_val") val pkVal: String? = null, + @JsonProperty("pk_name") val pkName: String? = null, + @JsonProperty("version") val version: Int? = null, + @JsonProperty("state_type") val stateType: String? = null, + @JsonProperty("incremental_state") val incrementalState: JsonNode? = null, + @JsonProperty("stream_name") val streamName: String? = null, + @JsonProperty("cursor_field") val cursorField: List? = null, + @JsonProperty("stream_namespace") val streamNamespace: String? = null, +) { + companion object { + /** Value representing the completion of a FULL_REFRESH snapshot. */ + fun getSnapshotCompletedState(stream: Stream): OpaqueStateValue = + Jsons.valueToTree( + MySqlSourceCdcInitialSnapshotStateValue( + streamName = stream.name, + cursorField = listOf(), + streamNamespace = stream.namespace + ) + ) + + /** Value representing the progress of an ongoing snapshot. */ + fun snapshotCheckpoint( + primaryKey: List, + primaryKeyCheckpoint: List, + ): OpaqueStateValue { + val primaryKeyField = primaryKey.first() + return when (primaryKeyCheckpoint.first().isNull) { + true -> Jsons.nullNode() + false -> + Jsons.valueToTree( + MySqlSourceCdcInitialSnapshotStateValue( + pkName = primaryKeyField.id, + pkVal = primaryKeyCheckpoint.first().asText(), + stateType = "primary_key", + ) + ) + } + } + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcMetaFields.kt b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcMetaFields.kt new file mode 100644 index 000000000000..c079bb0c0202 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcMetaFields.kt @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.mysql + +import io.airbyte.cdk.discover.CdcIntegerMetaFieldType +import io.airbyte.cdk.discover.CdcStringMetaFieldType +import io.airbyte.cdk.discover.FieldType +import io.airbyte.cdk.discover.MetaField + +enum class MySqlSourceCdcMetaFields( + override val type: FieldType, +) : MetaField { + CDC_CURSOR(CdcIntegerMetaFieldType), + CDC_LOG_POS(CdcIntegerMetaFieldType), + CDC_LOG_FILE(CdcStringMetaFieldType), + ; + + override val id: String + get() = MetaField.META_PREFIX + name.lowercase() +} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcPosition.kt b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcPosition.kt new file mode 100644 index 000000000000..13598aba4b89 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcPosition.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.mysql + +import kotlin.io.path.Path +import kotlin.io.path.extension + +/** WAL position datum for MySQL. */ +data class MySqlSourceCdcPosition(val fileName: String, val position: Long) : + Comparable { + + /** + * Numerical value encoded in the extension of the binlog file name. + * + * These files are typically named `binlog.000002` or something like that. These file's sizes + * are, according to the documentation, capped at 1 GB. + */ + val fileExtension: Int + get() = Path(fileName).extension.toInt() + + /** + * Numerical value obtained by ORing [fileExtension] in the high bits of [position]. This + * unsigned long integer can be used as a cursor value for the purposes of deduping records in + * incremental syncs; its value is meaningless in and of itself, all that matters is that it is + * monotonically increasing from one record to the next within the same sync. + * + * Specifically, deduplication will group all records by (_ab_cdc_updated_at, emitted_at) and + * will pick the record with the latest cursor value and discard the rest. + */ + val cursorValue: Long + get() = (fileExtension.toLong() shl Int.SIZE_BITS) or position + + override fun compareTo(other: MySqlSourceCdcPosition): Int = + cursorValue.compareTo(other.cursorValue) +} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcTemporalConverter.kt b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcTemporalConverter.kt new file mode 100644 index 000000000000..ded4475e2c2e --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcTemporalConverter.kt @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.mysql + +import io.airbyte.cdk.data.LocalDateCodec +import io.airbyte.cdk.data.LocalDateTimeCodec +import io.airbyte.cdk.data.LocalTimeCodec +import io.airbyte.cdk.data.OffsetDateTimeCodec +import io.airbyte.cdk.read.cdc.Converted +import io.airbyte.cdk.read.cdc.NoConversion +import io.airbyte.cdk.read.cdc.NullFallThrough +import io.airbyte.cdk.read.cdc.PartialConverter +import io.airbyte.cdk.read.cdc.RelationalColumnCustomConverter +import io.debezium.spi.converter.RelationalColumn +import java.time.Duration +import java.time.Instant +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.LocalTime +import java.time.OffsetDateTime +import java.time.ZoneOffset +import java.time.ZonedDateTime +import java.time.temporal.ChronoUnit +import org.apache.kafka.connect.data.SchemaBuilder + +class MySqlSourceCdcTemporalConverter : RelationalColumnCustomConverter { + + override val debeziumPropertiesKey: String = "temporal" + + override val handlers: List = + listOf( + DatetimeMillisHandler, + DatetimeMicrosHandler, + DateHandler, + TimeHandler, + TimestampHandler + ) + + data object DatetimeMillisHandler : RelationalColumnCustomConverter.Handler { + + override fun matches(column: RelationalColumn): Boolean = + column.typeName().equals("DATETIME", ignoreCase = true) && + column.length().orElse(0) <= 3 + + override fun outputSchemaBuilder(): SchemaBuilder = SchemaBuilder.string() + + override val partialConverters: List = + listOf( + NullFallThrough, + PartialConverter { + if (it is LocalDateTime) { + Converted(it.format(LocalDateTimeCodec.formatter)) + } else { + NoConversion + } + }, + PartialConverter { + // Required for default values. + if (it is Number) { + val delta: Duration = Duration.ofMillis(it.toLong()) + val instant: Instant = Instant.EPOCH.plus(delta) + val localDateTime: LocalDateTime = + LocalDateTime.ofInstant(instant, ZoneOffset.UTC) + Converted(localDateTime.format(LocalDateTimeCodec.formatter)) + } else { + NoConversion + } + } + ) + } + + data object DatetimeMicrosHandler : RelationalColumnCustomConverter.Handler { + + override fun matches(column: RelationalColumn): Boolean = + column.typeName().equals("DATETIME", ignoreCase = true) && column.length().orElse(0) > 3 + + override fun outputSchemaBuilder(): SchemaBuilder = SchemaBuilder.string() + + override val partialConverters: List = + listOf( + NullFallThrough, + PartialConverter { + if (it is LocalDateTime) { + Converted(it.format(LocalDateTimeCodec.formatter)) + } else { + NoConversion + } + }, + PartialConverter { + // Required for default values. + if (it is Number) { + val delta: Duration = Duration.of(it.toLong(), ChronoUnit.MICROS) + val instant: Instant = Instant.EPOCH.plus(delta) + val localDateTime: LocalDateTime = + LocalDateTime.ofInstant(instant, ZoneOffset.UTC) + Converted(localDateTime.format(LocalDateTimeCodec.formatter)) + } else { + NoConversion + } + } + ) + } + + data object DateHandler : RelationalColumnCustomConverter.Handler { + + override fun matches(column: RelationalColumn): Boolean = + column.typeName().equals("DATE", ignoreCase = true) + + override fun outputSchemaBuilder(): SchemaBuilder = SchemaBuilder.string() + + override val partialConverters: List = + listOf( + NullFallThrough, + PartialConverter { + if (it is LocalDate) { + Converted(it.format(LocalDateCodec.formatter)) + } else { + NoConversion + } + }, + PartialConverter { + // Required for default values. + if (it is Number) { + val localDate: LocalDate = LocalDate.ofEpochDay(it.toLong()) + Converted(localDate.format(LocalDateCodec.formatter)) + } else { + NoConversion + } + } + ) + } + + data object TimeHandler : RelationalColumnCustomConverter.Handler { + + override fun matches(column: RelationalColumn): Boolean = + column.typeName().equals("TIME", ignoreCase = true) + + override fun outputSchemaBuilder(): SchemaBuilder = SchemaBuilder.string() + + override val partialConverters: List = + listOf( + NullFallThrough, + PartialConverter { + if (it is Duration) { + val localTime: LocalTime = LocalTime.MIDNIGHT.plus(it) + Converted(localTime.format(LocalTimeCodec.formatter)) + } else { + NoConversion + } + }, + PartialConverter { + // Required for default values. + if (it is Number) { + val delta: Duration = Duration.of(it.toLong(), ChronoUnit.MICROS) + val localTime: LocalTime = LocalTime.ofNanoOfDay(delta.toNanos()) + Converted(localTime.format(LocalTimeCodec.formatter)) + } else { + NoConversion + } + } + ) + } + + data object TimestampHandler : RelationalColumnCustomConverter.Handler { + override fun matches(column: RelationalColumn): Boolean = + column.typeName().equals("TIMESTAMP", ignoreCase = true) + + override fun outputSchemaBuilder(): SchemaBuilder = SchemaBuilder.string() + + override val partialConverters: List = + listOf( + NullFallThrough, + PartialConverter { + if (it is ZonedDateTime) { + val offsetDateTime: OffsetDateTime = it.toOffsetDateTime() + Converted(offsetDateTime.format(OffsetDateTimeCodec.formatter)) + } else { + NoConversion + } + }, + PartialConverter { + // Required for default values. + if (it is String) { + val instant: Instant = Instant.parse(it) + val offsetDateTime: OffsetDateTime = + OffsetDateTime.ofInstant(instant, ZoneOffset.UTC) + Converted(offsetDateTime.format(OffsetDateTimeCodec.formatter)) + } else { + NoConversion + } + } + ) + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceConfiguration.kt b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceConfiguration.kt new file mode 100644 index 000000000000..d58b22725edf --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceConfiguration.kt @@ -0,0 +1,285 @@ +/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ +package io.airbyte.integrations.source.mysql + +import io.airbyte.cdk.ConfigErrorException +import io.airbyte.cdk.command.CdcSourceConfiguration +import io.airbyte.cdk.command.ConfigurationSpecificationSupplier +import io.airbyte.cdk.command.FeatureFlag +import io.airbyte.cdk.command.JdbcSourceConfiguration +import io.airbyte.cdk.command.SourceConfiguration +import io.airbyte.cdk.command.SourceConfigurationFactory +import io.airbyte.cdk.jdbc.SSLCertificateUtils +import io.airbyte.cdk.ssh.SshConnectionOptions +import io.airbyte.cdk.ssh.SshNoTunnelMethod +import io.airbyte.cdk.ssh.SshTunnelMethodConfiguration +import io.github.oshai.kotlinlogging.KotlinLogging +import io.micronaut.context.annotation.Factory +import jakarta.inject.Inject +import jakarta.inject.Singleton +import java.net.MalformedURLException +import java.net.URI +import java.net.URL +import java.net.URLDecoder +import java.nio.charset.StandardCharsets +import java.nio.file.FileSystems +import java.time.Duration +import java.util.UUID + +private val log = KotlinLogging.logger {} + +/** MySQL-specific implementation of [SourceConfiguration] */ +data class MySqlSourceConfiguration( + override val realHost: String, + override val realPort: Int, + override val sshTunnel: SshTunnelMethodConfiguration?, + override val sshConnectionOptions: SshConnectionOptions, + override val jdbcUrlFmt: String, + override val jdbcProperties: Map, + override val namespaces: Set, + val incrementalConfiguration: IncrementalConfiguration, + override val maxConcurrency: Int, + override val resourceAcquisitionHeartbeat: Duration = Duration.ofMillis(100L), + override val checkpointTargetInterval: Duration, + override val checkPrivileges: Boolean, + override val debeziumHeartbeatInterval: Duration = Duration.ofSeconds(10), + val debeziumKeepAliveInterval: Duration = Duration.ofMinutes(1), +) : JdbcSourceConfiguration, CdcSourceConfiguration { + override val global = incrementalConfiguration is CdcIncrementalConfiguration + override val maxSnapshotReadDuration: Duration? + get() = (incrementalConfiguration as? CdcIncrementalConfiguration)?.initialLoadTimeout + + /** Required to inject [MySqlSourceConfiguration] directly. */ + @Factory + private class MicronautFactory { + @Singleton + fun mysqlSourceConfig( + factory: + SourceConfigurationFactory< + MySqlSourceConfigurationSpecification, MySqlSourceConfiguration>, + supplier: ConfigurationSpecificationSupplier, + ): MySqlSourceConfiguration = factory.make(supplier.get()) + } +} + +sealed interface IncrementalConfiguration + +data object UserDefinedCursorIncrementalConfiguration : IncrementalConfiguration + +data class CdcIncrementalConfiguration( + val initialLoadTimeout: Duration, + val serverTimezone: String?, + val invalidCdcCursorPositionBehavior: InvalidCdcCursorPositionBehavior +) : IncrementalConfiguration + +enum class InvalidCdcCursorPositionBehavior { + FAIL_SYNC, + RESET_SYNC, +} + +@Singleton +class MySqlSourceConfigurationFactory @Inject constructor(val featureFlags: Set) : + SourceConfigurationFactory { + + constructor() : this(emptySet()) + + override fun makeWithoutExceptionHandling( + pojo: MySqlSourceConfigurationSpecification, + ): MySqlSourceConfiguration { + val realHost: String = pojo.host + val realPort: Int = pojo.port + val jdbcProperties = mutableMapOf() + jdbcProperties["user"] = pojo.username + pojo.password?.let { jdbcProperties["password"] = it } + + // Parse URL parameters. + val pattern = "^([^=]+)=(.*)$".toRegex() + for (pair in (pojo.jdbcUrlParams ?: "").trim().split("&".toRegex())) { + if (pair.isBlank()) { + continue + } + val result: MatchResult? = pattern.matchEntire(pair) + if (result == null) { + log.warn { "ignoring invalid JDBC URL param '$pair'" } + } else { + val key: String = result.groupValues[1].trim() + val urlEncodedValue: String = result.groupValues[2].trim() + jdbcProperties[key] = URLDecoder.decode(urlEncodedValue, StandardCharsets.UTF_8) + } + } + + // Configure SSH tunneling. + val sshTunnel: SshTunnelMethodConfiguration? = pojo.getTunnelMethodValue() + val sshOpts: SshConnectionOptions = + SshConnectionOptions.fromAdditionalProperties(pojo.getAdditionalProperties()) + + // Configure SSL encryption. + if ( + pojo.getEncryptionValue() is EncryptionPreferred && + sshTunnel is SshNoTunnelMethod && + featureFlags.contains(FeatureFlag.AIRBYTE_CLOUD_DEPLOYMENT) + ) { + throw ConfigErrorException( + "Connection from Airbyte Cloud requires SSL encryption or an SSH tunnel." + ) + } + val sslJdbcProperties: Map = fromEncryptionSpec(pojo.getEncryptionValue()!!) + jdbcProperties.putAll(sslJdbcProperties) + + // Configure cursor. + val incremental: IncrementalConfiguration = fromIncrementalSpec(pojo.getIncrementalValue()) + + // Build JDBC URL. + val address = "%s:%d" + val jdbcUrlFmt = "jdbc:mysql://${address}" + jdbcProperties["useCursorFetch"] = "true" + jdbcProperties["sessionVariables"] = "autocommit=0" + + // Internal configuration settings. + val checkpointTargetInterval: Duration = + Duration.ofSeconds(pojo.checkpointTargetIntervalSeconds?.toLong() ?: 0) + if (!checkpointTargetInterval.isPositive) { + throw ConfigErrorException("Checkpoint Target Interval should be positive") + } + val maxConcurrency: Int = pojo.concurrency ?: 0 + if ((pojo.concurrency ?: 0) <= 0) { + throw ConfigErrorException("Concurrency setting should be positive") + } + + return MySqlSourceConfiguration( + realHost = realHost, + realPort = realPort, + sshTunnel = sshTunnel, + sshConnectionOptions = sshOpts, + jdbcUrlFmt = jdbcUrlFmt, + jdbcProperties = jdbcProperties, + namespaces = setOf(pojo.database), + incrementalConfiguration = incremental, + checkpointTargetInterval = checkpointTargetInterval, + maxConcurrency = maxConcurrency, + checkPrivileges = pojo.checkPrivileges ?: true, + ) + } + + private fun fromIncrementalSpec( + incrementalSpec: IncrementalConfigurationSpecification + ): IncrementalConfiguration = + when (incrementalSpec) { + UserDefinedCursor -> UserDefinedCursorIncrementalConfiguration + is Cdc -> { + val initialLoadTimeout: Duration = + Duration.ofHours(incrementalSpec.initialLoadTimeoutHours!!.toLong()) + val invalidCdcCursorPositionBehavior: InvalidCdcCursorPositionBehavior = + if (incrementalSpec.invalidCdcCursorPositionBehavior == "Fail sync") { + InvalidCdcCursorPositionBehavior.FAIL_SYNC + } else { + InvalidCdcCursorPositionBehavior.RESET_SYNC + } + CdcIncrementalConfiguration( + initialLoadTimeout, + incrementalSpec.serverTimezone, + invalidCdcCursorPositionBehavior, + ) + } + } + + private fun fromEncryptionSpec(encryptionSpec: EncryptionSpecification): Map { + val extraJdbcProperties: MutableMap = mutableMapOf() + val sslData: SslData = + when (encryptionSpec) { + is EncryptionPreferred -> SslData("preferred") + is EncryptionRequired -> SslData("required") + is SslVerifyCertificate -> + SslData( + mode = "verify_ca", + caCertificate = encryptionSpec.sslCertificate, + clientCertificate = encryptionSpec.sslClientCertificate, + clientKey = encryptionSpec.sslClientKey, + keyStorePassword = encryptionSpec.sslClientPassword, + ) + is SslVerifyIdentity -> + SslData( + mode = "verify_identity", + caCertificate = encryptionSpec.sslCertificate, + clientCertificate = encryptionSpec.sslClientCertificate, + clientKey = encryptionSpec.sslClientKey, + keyStorePassword = encryptionSpec.sslClientPassword, + ) + } + extraJdbcProperties[SSL_MODE] = sslData.mode + if (sslData.caCertificate.isNullOrBlank()) { + // if CA cert is not available - done + return extraJdbcProperties + } + val password: String = + sslData.keyStorePassword.takeUnless { it.isNullOrBlank() } + ?: UUID.randomUUID().toString() + // Make keystore for CA cert with given password or generate a new password. + val caCertKeyStoreUrl: URL = + buildKeyStore("trust") { + SSLCertificateUtils.keyStoreFromCertificate( + sslData.caCertificate, + password, + FileSystems.getDefault(), + directory = "", + ) + } + extraJdbcProperties[TRUST_KEY_STORE_URL] = caCertKeyStoreUrl.toString() + extraJdbcProperties[TRUST_KEY_STORE_PASS] = password + extraJdbcProperties[TRUST_KEY_STORE_TYPE] = KEY_STORE_TYPE_PKCS12 + + if (sslData.clientCertificate.isNullOrBlank() || sslData.clientKey.isNullOrBlank()) { + // if Client cert is not available - done + return extraJdbcProperties + } + // Make keystore for Client cert with given password or generate a new password. + val clientCertKeyStoreUrl: URL = + buildKeyStore("client") { + SSLCertificateUtils.keyStoreFromClientCertificate( + sslData.clientCertificate, + sslData.clientKey, + password, + directory = "" + ) + } + extraJdbcProperties[CLIENT_KEY_STORE_URL] = clientCertKeyStoreUrl.toString() + extraJdbcProperties[CLIENT_KEY_STORE_PASS] = password + extraJdbcProperties[CLIENT_KEY_STORE_TYPE] = KEY_STORE_TYPE_PKCS12 + return extraJdbcProperties + } + + private data class SslData( + val mode: String, + val caCertificate: String? = null, + val clientCertificate: String? = null, + val clientKey: String? = null, + val keyStorePassword: String? = null, + ) + + private fun buildKeyStore(kind: String, uriSupplier: () -> URI): URL { + val keyStoreUri: URI = + try { + uriSupplier() + } catch (ex: Exception) { + throw ConfigErrorException("Failed to create keystore for $kind certificate", ex) + } + val keyStoreUrl: URL = + try { + keyStoreUri.toURL() + } catch (ex: MalformedURLException) { + throw ConfigErrorException("Unable to get a URL for $kind key store", ex) + } + log.debug { "URL for $kind certificate keystore is $keyStoreUrl" } + return keyStoreUrl + } + + companion object { + const val TRUST_KEY_STORE_URL: String = "trustCertificateKeyStoreUrl" + const val TRUST_KEY_STORE_PASS: String = "trustCertificateKeyStorePassword" + const val CLIENT_KEY_STORE_URL: String = "clientCertificateKeyStoreUrl" + const val CLIENT_KEY_STORE_PASS: String = "clientCertificateKeyStorePassword" + const val CLIENT_KEY_STORE_TYPE: String = "clientCertificateKeyStoreType" + const val TRUST_KEY_STORE_TYPE: String = "trustCertificateKeyStoreType" + const val KEY_STORE_TYPE_PKCS12: String = "PKCS12" + const val SSL_MODE: String = "sslMode" + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceConfigurationSpecification.kt b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceConfigurationSpecification.kt new file mode 100644 index 000000000000..372ad820f183 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceConfigurationSpecification.kt @@ -0,0 +1,367 @@ +/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ +package io.airbyte.integrations.source.mysql + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonGetter +import com.fasterxml.jackson.annotation.JsonIgnore +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonPropertyDescription +import com.fasterxml.jackson.annotation.JsonPropertyOrder +import com.fasterxml.jackson.annotation.JsonSetter +import com.fasterxml.jackson.annotation.JsonSubTypes +import com.fasterxml.jackson.annotation.JsonTypeInfo +import com.fasterxml.jackson.annotation.JsonValue +import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaDefault +import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaDescription +import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaInject +import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaTitle +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings +import io.airbyte.cdk.ConfigErrorException +import io.airbyte.cdk.command.CONNECTOR_CONFIG_PREFIX +import io.airbyte.cdk.command.ConfigurationSpecification +import io.airbyte.cdk.ssh.MicronautPropertiesFriendlySshTunnelMethodConfigurationSpecification +import io.airbyte.cdk.ssh.SshTunnelMethodConfiguration +import io.micronaut.context.annotation.ConfigurationBuilder +import io.micronaut.context.annotation.ConfigurationProperties +import jakarta.inject.Singleton + +/** + * The object which is mapped to the MySQL source configuration JSON. + * + * Use [MySqlSourceConfiguration] instead wherever possible. This object also allows injecting + * values through Micronaut properties, this is made possible by the classes named + * `MicronautPropertiesFriendly.*`. + */ +@JsonSchemaTitle("MySQL Source Spec") +@JsonPropertyOrder( + value = ["host", "port", "database", "username", "replication_method"], +) +@Singleton +@ConfigurationProperties(CONNECTOR_CONFIG_PREFIX) +@SuppressFBWarnings(value = ["NP_NONNULL_RETURN_VIOLATION"], justification = "Micronaut DI") +class MySqlSourceConfigurationSpecification : ConfigurationSpecification() { + @JsonProperty("host") + @JsonSchemaTitle("Host") + @JsonSchemaInject(json = """{"order":1}""") + @JsonPropertyDescription("Hostname of the database.") + lateinit var host: String + + @JsonProperty("port") + @JsonSchemaTitle("Port") + @JsonSchemaInject(json = """{"order":2,"minimum": 0,"maximum": 65536}""") + @JsonSchemaDefault("3306") + @JsonPropertyDescription( + "Port of the database.", + ) + var port: Int = 3306 + + @JsonProperty("username") + @JsonSchemaTitle("User") + @JsonPropertyDescription("The username which is used to access the database.") + @JsonSchemaInject(json = """{"order":4}""") + lateinit var username: String + + @JsonProperty("password") + @JsonSchemaTitle("Password") + @JsonPropertyDescription("The password associated with the username.") + @JsonSchemaInject(json = """{"order":5,"always_show":true,"airbyte_secret":true}""") + var password: String? = null + + @JsonProperty("database") + @JsonSchemaTitle("Database") + @JsonPropertyDescription("The database name.") + @JsonSchemaInject(json = """{"order":6,"always_show":true}""") + lateinit var database: String + + @JsonProperty("jdbc_url_params") + @JsonSchemaTitle("JDBC URL Params") + @JsonPropertyDescription( + "Additional properties to pass to the JDBC URL string when connecting to the database " + + "formatted as 'key=value' pairs separated by the symbol '&'. " + + "(example: key1=value1&key2=value2&key3=value3).", + ) + @JsonSchemaInject(json = """{"order":7}""") + var jdbcUrlParams: String? = null + + @JsonIgnore + @ConfigurationBuilder(configurationPrefix = "ssl_mode") + var encryption = MicronautPropertiesFriendlyEncryptionSpecification() + + @JsonIgnore var encryptionJson: EncryptionSpecification? = null + + @JsonSetter("ssl_mode") + fun setEncryptionValue(value: EncryptionSpecification) { + encryptionJson = value + } + + @JsonGetter("ssl_mode") + @JsonSchemaTitle("Encryption") + @JsonPropertyDescription( + "The encryption method with is used when communicating with the database.", + ) + @JsonSchemaInject(json = """{"order":8}""") + fun getEncryptionValue(): EncryptionSpecification? = encryptionJson ?: encryption.asEncryption() + + @JsonIgnore + @ConfigurationBuilder(configurationPrefix = "tunnel_method") + val tunnelMethod = MicronautPropertiesFriendlySshTunnelMethodConfigurationSpecification() + + @JsonIgnore var tunnelMethodJson: SshTunnelMethodConfiguration? = null + + @JsonSetter("tunnel_method") + fun setTunnelMethodValue(value: SshTunnelMethodConfiguration) { + tunnelMethodJson = value + } + + @JsonGetter("tunnel_method") + @JsonSchemaTitle("SSH Tunnel Method") + @JsonPropertyDescription( + "Whether to initiate an SSH tunnel before connecting to the database, " + + "and if so, which kind of authentication to use.", + ) + @JsonSchemaInject(json = """{"order":9}""") + fun getTunnelMethodValue(): SshTunnelMethodConfiguration? = + tunnelMethodJson ?: tunnelMethod.asSshTunnelMethod() + + @JsonIgnore + @ConfigurationBuilder(configurationPrefix = "replication_method") + var replicationMethod = MicronautPropertiesFriendlyIncrementalConfigurationSpecification() + + @JsonIgnore var replicationMethodJson: IncrementalConfigurationSpecification? = null + + @JsonSetter("replication_method") + fun setIncrementalValue(value: IncrementalConfigurationSpecification) { + replicationMethodJson = value + } + + @JsonGetter("replication_method") + @JsonSchemaTitle("Update Method") + @JsonPropertyDescription("Configures how data is extracted from the database.") + @JsonSchemaInject(json = """{"order":10,"display_type":"radio"}""") + fun getIncrementalValue(): IncrementalConfigurationSpecification = + replicationMethodJson ?: replicationMethod.asCursorMethodConfiguration() + + @JsonProperty("checkpoint_target_interval_seconds") + @JsonSchemaTitle("Checkpoint Target Time Interval") + @JsonSchemaInject(json = """{"order":11}""") + @JsonSchemaDefault("300") + @JsonPropertyDescription("How often (in seconds) a stream should checkpoint, when possible.") + var checkpointTargetIntervalSeconds: Int? = 300 + + @JsonProperty("concurrency") + @JsonSchemaTitle("Concurrency") + @JsonSchemaInject(json = """{"order":12}""") + @JsonSchemaDefault("1") + @JsonPropertyDescription("Maximum number of concurrent queries to the database.") + var concurrency: Int? = 1 + + @JsonProperty("check_privileges") + @JsonSchemaTitle("Check Table and Column Access Privileges") + @JsonSchemaInject(json = """{"order":13}""") + @JsonSchemaDefault("true") + @JsonPropertyDescription( + "When this feature is enabled, during schema discovery the connector " + + "will query each table or view individually to check access privileges " + + "and inaccessible tables, views, or columns therein will be removed. " + + "In large schemas, this might cause schema discovery to take too long, " + + "in which case it might be advisable to disable this feature.", + ) + var checkPrivileges: Boolean? = true + + @JsonIgnore var additionalPropertiesMap = mutableMapOf() + + @JsonAnyGetter fun getAdditionalProperties(): Map = additionalPropertiesMap + + @JsonAnySetter + fun setAdditionalProperty( + name: String, + value: Any, + ) { + additionalPropertiesMap[name] = value + } +} + +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "mode") +@JsonSubTypes( + JsonSubTypes.Type(value = EncryptionPreferred::class, name = "preferred"), + JsonSubTypes.Type(value = EncryptionRequired::class, name = "required"), + JsonSubTypes.Type(value = SslVerifyCertificate::class, name = "verify_ca"), + JsonSubTypes.Type(value = SslVerifyIdentity::class, name = "verify_identity"), +) +@JsonSchemaTitle("Encryption") +@JsonSchemaDescription("The encryption method which is used when communicating with the database.") +sealed interface EncryptionSpecification + +@JsonSchemaTitle("preferred") +@JsonSchemaDescription( + "To allow unencrypted communication only when the source doesn't support encryption.", +) +data object EncryptionPreferred : EncryptionSpecification + +@JsonSchemaTitle("required") +@JsonSchemaDescription( + "To always require encryption. Note: The connection will fail if the source doesn't support encryption.", +) +data object EncryptionRequired : EncryptionSpecification + +@JsonSchemaTitle("verify_ca") +@JsonSchemaDescription( + "To always require encryption and verify that the source has a valid SSL certificate." +) +@SuppressFBWarnings(value = ["NP_NONNULL_RETURN_VIOLATION"], justification = "Micronaut DI") +class SslVerifyCertificate : EncryptionSpecification { + @JsonProperty("ca_certificate", required = true) + @JsonSchemaTitle("CA certificate") + @JsonPropertyDescription( + "CA certificate", + ) + @JsonSchemaInject(json = """{"airbyte_secret":true,"multiline":true}""") + lateinit var sslCertificate: String + + @JsonProperty("client_certificate", required = false) + @JsonSchemaTitle("Client certificate File") + @JsonPropertyDescription( + "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", + ) + @JsonSchemaInject(json = """{"airbyte_secret":true,"multiline":true}""") + var sslClientCertificate: String? = null + + @JsonProperty("client_key") + @JsonSchemaTitle("Client Key") + @JsonPropertyDescription( + "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", + ) + @JsonSchemaInject(json = """{"airbyte_secret":true,"multiline":true}""") + var sslClientKey: String? = null + + @JsonProperty("client_key_password") + @JsonSchemaTitle("Client key password") + @JsonPropertyDescription( + "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", + ) + @JsonSchemaInject(json = """{"airbyte_secret":true,"multiline":true}""") + var sslClientPassword: String? = null +} + +@JsonSchemaTitle("verify_identity") +@JsonSchemaDescription( + "To always require encryption and verify that the source has a valid SSL certificate." +) +@SuppressFBWarnings(value = ["NP_NONNULL_RETURN_VIOLATION"], justification = "Micronaut DI") +class SslVerifyIdentity : EncryptionSpecification { + @JsonProperty("ca_certificate", required = true) + @JsonSchemaTitle("CA certificate") + @JsonPropertyDescription( + "CA certificate", + ) + @JsonSchemaInject(json = """{"airbyte_secret":true,"multiline":true}""") + lateinit var sslCertificate: String + + @JsonProperty("client_certificate", required = false) + @JsonSchemaTitle("Client certificate File") + @JsonPropertyDescription( + "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", + ) + @JsonSchemaInject(json = """{"airbyte_secret":true,"multiline":true}""") + var sslClientCertificate: String? = null + + @JsonProperty("client_key") + @JsonSchemaTitle("Client Key") + @JsonPropertyDescription( + "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", + ) + @JsonSchemaInject(json = """{"airbyte_secret":true,"multiline":true}""") + var sslClientKey: String? = null + + @JsonProperty("client_key_password") + @JsonSchemaTitle("Client key password") + @JsonPropertyDescription( + "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", + ) + @JsonSchemaInject(json = """{"airbyte_secret":true,"multiline":true}""") + var sslClientPassword: String? = null +} + +@ConfigurationProperties("$CONNECTOR_CONFIG_PREFIX.ssl_mode") +class MicronautPropertiesFriendlyEncryptionSpecification { + var mode: String = "preferred" + var sslCertificate: String? = null + + @JsonValue + fun asEncryption(): EncryptionSpecification = + when (mode) { + "preferred" -> EncryptionPreferred + "required" -> EncryptionRequired + "verify_ca" -> SslVerifyCertificate().also { it.sslCertificate = sslCertificate!! } + "verify_identity" -> SslVerifyIdentity().also { it.sslCertificate = sslCertificate!! } + else -> throw ConfigErrorException("invalid value $mode") + } +} + +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "method") +@JsonSubTypes( + JsonSubTypes.Type(value = UserDefinedCursor::class, name = "STANDARD"), + JsonSubTypes.Type(value = Cdc::class, name = "CDC") +) +@JsonSchemaTitle("Update Method") +@JsonSchemaDescription("Configures how data is extracted from the database.") +sealed interface IncrementalConfigurationSpecification + +@JsonSchemaTitle("Scan Changes with User Defined Cursor") +@JsonSchemaDescription( + "Incrementally detects new inserts and updates using the " + + "cursor column chosen when configuring a connection " + + "(e.g. created_at, updated_at).", +) +data object UserDefinedCursor : IncrementalConfigurationSpecification + +@JsonSchemaTitle("Read Changes using Change Data Capture (CDC)") +@JsonSchemaDescription( + "Recommended - " + + "Incrementally reads new inserts, updates, and deletes using MySQL's change data capture feature. This must be enabled on your database.", +) +class Cdc : IncrementalConfigurationSpecification { + @JsonProperty("server_timezone") + @JsonSchemaTitle("Configured server timezone for the MySQL source (Advanced)") + @JsonPropertyDescription( + "Enter the configured MySQL server timezone. This should only be done if the configured timezone in your MySQL instance does not conform to IANNA standard.", + ) + @JsonSchemaInject(json = """{"order":1,"always_show":true}""") + var serverTimezone: String? = null + + @JsonProperty("invalid_cdc_cursor_position_behavior") + @JsonSchemaTitle("Configured server timezone for the MySQL source (Advanced)") + @JsonPropertyDescription( + "Enter the configured MySQL server timezone. This should only be done if the configured timezone in your MySQL instance does not conform to IANNA standard.", + ) + @JsonSchemaDefault("Fail sync") + @JsonSchemaInject( + json = """{"order":2,"always_show":true, "enum": ["Fail sync","Re-sync data"]}""" + ) + var invalidCdcCursorPositionBehavior: String? = "Fail sync" + + @JsonProperty("initial_load_timeout_hours") + @JsonSchemaTitle("Initial Load Timeout in Hours (Advanced)") + @JsonPropertyDescription( + "The amount of time an initial load is allowed to continue for before catching up on CDC logs.", + ) + @JsonSchemaDefault("8") + @JsonSchemaInject(json = """{"order":3, "max": 24, "min": 4,"always_show": true}""") + var initialLoadTimeoutHours: Int? = 8 +} + +@ConfigurationProperties("$CONNECTOR_CONFIG_PREFIX.replication_method") +class MicronautPropertiesFriendlyIncrementalConfigurationSpecification { + var method: String = "STANDARD" + + fun asCursorMethodConfiguration(): IncrementalConfigurationSpecification = + when (method) { + "STANDARD" -> UserDefinedCursor + "CDC" -> Cdc() + else -> throw ConfigErrorException("invalid value $method") + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceDebeziumOperations.kt b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceDebeziumOperations.kt new file mode 100644 index 000000000000..3256101a0a24 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceDebeziumOperations.kt @@ -0,0 +1,518 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.mysql + +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.ArrayNode +import com.fasterxml.jackson.databind.node.ObjectNode +import com.fasterxml.jackson.databind.node.TextNode +import io.airbyte.cdk.ConfigErrorException +import io.airbyte.cdk.command.OpaqueStateValue +import io.airbyte.cdk.data.LeafAirbyteSchemaType +import io.airbyte.cdk.data.LongCodec +import io.airbyte.cdk.data.OffsetDateTimeCodec +import io.airbyte.cdk.data.TextCodec +import io.airbyte.cdk.discover.CommonMetaField +import io.airbyte.cdk.discover.Field +import io.airbyte.cdk.jdbc.JdbcConnectionFactory +import io.airbyte.cdk.jdbc.LongFieldType +import io.airbyte.cdk.jdbc.StringFieldType +import io.airbyte.cdk.read.Stream +import io.airbyte.cdk.read.cdc.CdcPartitionsCreator.OffsetInvalidNeedsResyncIllegalStateException +import io.airbyte.cdk.read.cdc.DebeziumInput +import io.airbyte.cdk.read.cdc.DebeziumOffset +import io.airbyte.cdk.read.cdc.DebeziumOperations +import io.airbyte.cdk.read.cdc.DebeziumPropertiesBuilder +import io.airbyte.cdk.read.cdc.DebeziumRecordKey +import io.airbyte.cdk.read.cdc.DebeziumRecordValue +import io.airbyte.cdk.read.cdc.DebeziumSchemaHistory +import io.airbyte.cdk.read.cdc.DebeziumState +import io.airbyte.cdk.read.cdc.DeserializedRecord +import io.airbyte.cdk.ssh.TunnelSession +import io.airbyte.cdk.util.Jsons +import io.debezium.connector.mysql.MySqlConnector +import io.debezium.connector.mysql.gtid.MySqlGtidSet +import io.debezium.document.DocumentReader +import io.debezium.document.DocumentWriter +import io.debezium.relational.history.HistoryRecord +import io.github.oshai.kotlinlogging.KotlinLogging +import jakarta.inject.Singleton +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.math.BigDecimal +import java.sql.Connection +import java.sql.ResultSet +import java.sql.Statement +import java.time.Instant +import java.time.OffsetDateTime +import java.time.ZoneOffset +import java.util.zip.GZIPInputStream +import java.util.zip.GZIPOutputStream +import kotlin.random.Random +import kotlin.random.nextInt +import org.apache.kafka.connect.json.JsonConverterConfig +import org.apache.kafka.connect.source.SourceRecord +import org.apache.mina.util.Base64 + +@Singleton +class MySqlSourceDebeziumOperations( + val jdbcConnectionFactory: JdbcConnectionFactory, + val configuration: MySqlSourceConfiguration, + random: Random = Random.Default, +) : DebeziumOperations { + private val log = KotlinLogging.logger {} + + override fun deserialize( + key: DebeziumRecordKey, + value: DebeziumRecordValue, + stream: Stream, + ): DeserializedRecord { + val before: JsonNode = value.before + val after: JsonNode = value.after + val source: JsonNode = value.source + val isDelete: Boolean = after.isNull + // Use either `before` or `after` as the record data, depending on the nature of the change. + val data: ObjectNode = (if (isDelete) before else after) as ObjectNode + // Turn string representations of numbers into BigDecimals. + for (field in stream.schema) { + when (field.type.airbyteSchemaType) { + LeafAirbyteSchemaType.INTEGER, + LeafAirbyteSchemaType.NUMBER -> { + val textNode: TextNode = data[field.id] as? TextNode ?: continue + val bigDecimal = BigDecimal(textNode.textValue()).stripTrailingZeros() + data.put(field.id, bigDecimal) + } + LeafAirbyteSchemaType.JSONB -> { + val textNode: TextNode = data[field.id] as? TextNode ?: continue + data.set(field.id, Jsons.readTree(textNode.textValue())) + } + else -> continue + } + } + // Set _ab_cdc_updated_at and _ab_cdc_deleted_at meta-field values. + val transactionMillis: Long = source["ts_ms"].asLong() + val transactionOffsetDateTime: OffsetDateTime = + OffsetDateTime.ofInstant(Instant.ofEpochMilli(transactionMillis), ZoneOffset.UTC) + val transactionTimestampJsonNode: JsonNode = + OffsetDateTimeCodec.encode(transactionOffsetDateTime) + data.set( + CommonMetaField.CDC_UPDATED_AT.id, + transactionTimestampJsonNode, + ) + data.set( + CommonMetaField.CDC_DELETED_AT.id, + if (isDelete) transactionTimestampJsonNode else Jsons.nullNode(), + ) + // Set _ab_cdc_log_file and _ab_cdc_log_pos meta-field values. + val position = MySqlSourceCdcPosition(source["file"].asText(), source["pos"].asLong()) + data.set( + MySqlSourceCdcMetaFields.CDC_LOG_FILE.id, + TextCodec.encode(position.fileName) + ) + data.set( + MySqlSourceCdcMetaFields.CDC_LOG_POS.id, + LongCodec.encode(position.position) + ) + // Set the _ab_cdc_cursor meta-field value. + data.set( + MySqlSourceCdcMetaFields.CDC_CURSOR.id, + LongCodec.encode(position.cursorValue) + ) + // Return a DeserializedRecord instance. + return DeserializedRecord(data, changes = emptyMap()) + } + + override fun findStreamNamespace(key: DebeziumRecordKey, value: DebeziumRecordValue): String? = + value.source["db"]?.asText() + + override fun findStreamName(key: DebeziumRecordKey, value: DebeziumRecordValue): String? = + value.source["table"]?.asText() + + /** + * Checks if GTIDs from previously saved state (debeziumInput) are still valid on DB. And also + * check if binlog exists or not. + * + * Validate is not supposed to perform on synthetic state. + */ + private fun validate(debeziumState: DebeziumState): CdcStateValidateResult { + val savedStateOffset: SavedOffset = parseSavedOffset(debeziumState) + val (_: MySqlSourceCdcPosition, gtidSet: String?) = queryPositionAndGtids() + if (gtidSet.isNullOrEmpty() && !savedStateOffset.gtidSet.isNullOrEmpty()) { + log.info { + "Connector used GTIDs previously, but MySQL server does not know of any GTIDs or they are not enabled" + } + return abortCdcSync() + } + + val savedGtidSet = MySqlGtidSet(savedStateOffset.gtidSet) + val availableGtidSet = MySqlGtidSet(gtidSet) + if (!savedGtidSet.isContainedWithin(availableGtidSet)) { + log.info { + "Connector last known GTIDs are $savedGtidSet, but MySQL server only has $availableGtidSet" + } + return abortCdcSync() + } + + // newGtidSet is gtids from server that hasn't been seen by this connector yet. If the set + // exists, check that they are not purged, or we may lose those data. + val newGtidSet = availableGtidSet.subtract(savedGtidSet) + if (!newGtidSet.isEmpty) { + val purgedGtidSet = queryPurgedIds() + if (!purgedGtidSet.isEmpty && !newGtidSet.subtract(purgedGtidSet).equals(newGtidSet)) { + log.info { + "Connector has not seen GTIDs $newGtidSet, but MySQL server has purged $purgedGtidSet" + } + return abortCdcSync() + } + } + if (!savedGtidSet.isEmpty) { + // If the connector has saved GTID set, we will use that to validate and skip + // binlog validation. GTID and binlog works in an independent way to ensure data + // integrity where GTID is for storing transactions and binlog is for storing changes + // in DB. + return CdcStateValidateResult.VALID + } + val existingLogFiles: List = getBinaryLogFileNames() + val found = existingLogFiles.contains(savedStateOffset.position.fileName) + if (!found) { + log.info { + "Connector last known binlog file ${savedStateOffset.position.fileName} is " + + "not found in the server. Server has $existingLogFiles" + } + return abortCdcSync() + } + return CdcStateValidateResult.VALID + } + + private fun abortCdcSync(): CdcStateValidateResult { + val cdcIncrementalConfiguration: CdcIncrementalConfiguration = + configuration.incrementalConfiguration as CdcIncrementalConfiguration + return when (cdcIncrementalConfiguration.invalidCdcCursorPositionBehavior) { + InvalidCdcCursorPositionBehavior.FAIL_SYNC -> { + log.warn { "Saved offset no longer present on the server. aborting sync." } + CdcStateValidateResult.INVALID_ABORT + } + InvalidCdcCursorPositionBehavior.RESET_SYNC -> { + log.warn { + "Saved offset no longer present on the server, Airbyte is going to trigger a sync from scratch." + } + CdcStateValidateResult.INVALID_RESET + } + } + } + + private fun parseSavedOffset(debeziumState: DebeziumState): SavedOffset { + val position: MySqlSourceCdcPosition = position(debeziumState.offset) + val gtidSet: String? = debeziumState.offset.wrapped.values.first()["gtids"]?.asText() + return SavedOffset(position, gtidSet) + } + + data class SavedOffset(val position: MySqlSourceCdcPosition, val gtidSet: String?) + + enum class CdcStateValidateResult { + VALID, + INVALID_ABORT, + INVALID_RESET + } + + override fun position(offset: DebeziumOffset): MySqlSourceCdcPosition = + Companion.position(offset) + + override fun position(recordValue: DebeziumRecordValue): MySqlSourceCdcPosition? { + val file: JsonNode = recordValue.source["file"]?.takeIf { it.isTextual } ?: return null + val pos: JsonNode = recordValue.source["pos"]?.takeIf { it.isIntegralNumber } ?: return null + return MySqlSourceCdcPosition(file.asText(), pos.asLong()) + } + + override fun position(sourceRecord: SourceRecord): MySqlSourceCdcPosition? { + val offset: Map = sourceRecord.sourceOffset() + val file: Any = offset["file"] ?: return null + val pos: Long = offset["pos"] as? Long ?: return null + return MySqlSourceCdcPosition(file.toString(), pos) + } + + override fun synthesize(): DebeziumInput { + val (mySqlSourceCdcPosition: MySqlSourceCdcPosition, gtidSet: String?) = + queryPositionAndGtids() + val topicPrefixName: String = DebeziumPropertiesBuilder.sanitizeTopicPrefix(databaseName) + val timestamp: Instant = Instant.now() + val key: ArrayNode = + Jsons.arrayNode().apply { + add(databaseName) + add(Jsons.objectNode().apply { put("server", topicPrefixName) }) + } + val value: ObjectNode = + Jsons.objectNode().apply { + put("ts_sec", timestamp.epochSecond) + put("file", mySqlSourceCdcPosition.fileName) + put("pos", mySqlSourceCdcPosition.position) + if (gtidSet != null) { + put("gtids", gtidSet) + } + } + val offset = DebeziumOffset(mapOf(key to value)) + log.info { "Constructed synthetic $offset." } + val state = DebeziumState(offset, schemaHistory = null) + return DebeziumInput(syntheticProperties, state, isSynthetic = true) + } + + private fun queryPositionAndGtids(): Pair { + val file = Field("File", StringFieldType) + val pos = Field("Position", LongFieldType) + val gtids = Field("Executed_Gtid_Set", StringFieldType) + jdbcConnectionFactory.get().use { connection: Connection -> + connection.createStatement().use { stmt: Statement -> + val sql = "SHOW MASTER STATUS" + stmt.executeQuery(sql).use { rs: ResultSet -> + if (!rs.next()) throw ConfigErrorException("No results for query: $sql") + val mySqlSourceCdcPosition = + MySqlSourceCdcPosition( + fileName = rs.getString(file.id)?.takeUnless { rs.wasNull() } + ?: throw ConfigErrorException( + "No value for ${file.id} in: $sql", + ), + position = rs.getLong(pos.id).takeUnless { rs.wasNull() || it <= 0 } + ?: throw ConfigErrorException( + "No value for ${pos.id} in: $sql", + ), + ) + if (rs.metaData.columnCount <= 4) { + // This value exists only in MySQL 5.6.5 or later. + return mySqlSourceCdcPosition to null + } + val gtidSet: String? = + rs.getString(gtids.id) + ?.takeUnless { rs.wasNull() || it.isBlank() } + ?.trim() + ?.replace("\n", "") + ?.replace("\r", "") + return mySqlSourceCdcPosition to gtidSet + } + } + } + } + + private fun queryPurgedIds(): MySqlGtidSet { + val purgedGtidField = Field("@@global.gtid_purged", StringFieldType) + jdbcConnectionFactory.get().use { connection: Connection -> + connection.createStatement().use { stmt: Statement -> + val sql = "SELECT @@global.gtid_purged" + stmt.executeQuery(sql).use { rs: ResultSet -> + if (!rs.next()) throw ConfigErrorException("No results for query: $sql") + return MySqlGtidSet(rs.getString(purgedGtidField.id)) + } + } + } + } + + private fun getBinaryLogFileNames(): List { + // Very old MySQL version (4.x) has different output of SHOW BINARY LOGS output. + return jdbcConnectionFactory.get().use { connection: Connection -> + connection.createStatement().use { stmt: Statement -> + val sql = "SHOW BINARY LOGS" + stmt.executeQuery(sql).use { rs: ResultSet -> + generateSequence { if (rs.next()) rs.getString(1) else null }.toList() + } + } + } + } + + override fun deserialize( + opaqueStateValue: OpaqueStateValue, + streams: List + ): DebeziumInput { + val debeziumState: DebeziumState = + try { + deserializeDebeziumState(opaqueStateValue) + } catch (e: Exception) { + throw ConfigErrorException("Error deserializing $opaqueStateValue", e) + } + val cdcValidationResult = validate(debeziumState) + if (cdcValidationResult != CdcStateValidateResult.VALID) { + if (cdcValidationResult == CdcStateValidateResult.INVALID_ABORT) { + throw ConfigErrorException( + "Saved offset no longer present on the server. Please reset the connection, and then increase binlog retention and/or increase sync frequency." + ) + } + if (cdcValidationResult == CdcStateValidateResult.INVALID_RESET) { + throw OffsetInvalidNeedsResyncIllegalStateException() + } + return synthesize() + } + + val properties: Map = + DebeziumPropertiesBuilder().with(commonProperties).withStreams(streams).buildMap() + return DebeziumInput(properties, debeziumState, isSynthetic = false) + } + + override fun serialize(debeziumState: DebeziumState): OpaqueStateValue { + val stateNode: ObjectNode = Jsons.objectNode() + // Serialize offset. + val offsetNode: JsonNode = + Jsons.objectNode().apply { + for ((k, v) in debeziumState.offset.wrapped) { + put(Jsons.writeValueAsString(k), Jsons.writeValueAsString(v)) + } + } + stateNode.set(MYSQL_CDC_OFFSET, offsetNode) + // Serialize schema history. + val schemaHistory: List? = debeziumState.schemaHistory?.wrapped + if (schemaHistory != null) { + val uncompressedString: String = + schemaHistory.joinToString(separator = "\n") { + DocumentWriter.defaultWriter().write(it.document()) + } + if (uncompressedString.length <= MAX_UNCOMPRESSED_LENGTH) { + stateNode.put(MYSQL_DB_HISTORY, uncompressedString) + } else { + stateNode.put(IS_COMPRESSED, true) + val baos = ByteArrayOutputStream() + val builder = StringBuilder() + GZIPOutputStream(baos).writer(Charsets.UTF_8).use { it.write(uncompressedString) } + + builder.append("\"") + builder.append(Base64.encodeBase64(baos.toByteArray()).toString(Charsets.UTF_8)) + builder.append("\"") + + stateNode.put(MYSQL_DB_HISTORY, builder.toString()) + } + } + return Jsons.objectNode().apply { set(STATE, stateNode) } + } + + val databaseName: String = configuration.namespaces.first() + val serverID: Int = random.nextInt(MIN_SERVER_ID..MAX_SERVER_ID) + + val commonProperties: Map by lazy { + val tunnelSession: TunnelSession = jdbcConnectionFactory.ensureTunnelSession() + val dbzPropertiesBuilder = + DebeziumPropertiesBuilder() + .withDefault() + .withConnector(MySqlConnector::class.java) + .withDebeziumName(databaseName) + .withHeartbeats(configuration.debeziumHeartbeatInterval) + // This to make sure that binary data represented as a base64-encoded String. + // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-property-binary-handling-mode + .with("binary.handling.mode", "base64") + // This is to make sure that numbers are represented as strings. + .with("decimal.handling.mode", "string") + // This is to make sure that temporal data is represented without loss of precision. + .with("time.precision.mode", "adaptive_time_microseconds") + // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-property-snapshot-mode + .with("snapshot.mode", "when_needed") + // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-property-snapshot-locking-mode + // This is to make sure other database clients are allowed to write to a table while + // Airbyte is taking a snapshot. There is a risk involved that if any database + // client + // makes a schema change then the sync might break + .with("snapshot.locking.mode", "none") + // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-property-include-schema-changes + .with("include.schema.changes", "false") + .with( + "connect.keep.alive.interval.ms", + configuration.debeziumKeepAliveInterval.toMillis().toString(), + ) + .withDatabase(configuration.jdbcProperties) + .withDatabase("hostname", tunnelSession.address.hostName) + .withDatabase("port", tunnelSession.address.port.toString()) + .withDatabase("dbname", databaseName) + .withDatabase("server.id", serverID.toString()) + .withDatabase("include.list", databaseName) + .withOffset() + .withSchemaHistory() + .withConverters( + MySqlSourceCdcBooleanConverter::class, + MySqlSourceCdcTemporalConverter::class + ) + + val serverTimezone: String? = + (configuration.incrementalConfiguration as CdcIncrementalConfiguration).serverTimezone + if (!serverTimezone.isNullOrBlank()) { + dbzPropertiesBuilder.with("database.connectionTimezone", serverTimezone) + } + dbzPropertiesBuilder.buildMap() + } + + val syntheticProperties: Map by lazy { + DebeziumPropertiesBuilder() + .with(commonProperties) + // https://debezium.io/documentation/reference/2.2/connectors/mysql.html#mysql-property-snapshot-mode + // We use the recovery property cause using this mode will instruct Debezium to + // construct the db schema history. Note that we used to use schema_only_recovery mode + // instead, but this mode has been deprecated. + .with("snapshot.mode", "recovery") + .withStreams(listOf()) + .buildMap() + } + + companion object { + // Constants defining a range for the random value picked for the database.server.id + // Debezium property which uniquely identifies the binlog consumer. + // https://debezium.io/documentation/reference/stable/connectors/mysql.html#mysql-property-database-server-id + const val MIN_SERVER_ID = 5400 + const val MAX_SERVER_ID = 6400 + + const val MAX_UNCOMPRESSED_LENGTH = 1024 * 1024 + const val STATE = "state" + const val MYSQL_CDC_OFFSET = "mysql_cdc_offset" + const val MYSQL_DB_HISTORY = "mysql_db_history" + const val IS_COMPRESSED = "is_compressed" + + /** + * The name of the Debezium property that contains the unique name for the Debezium + * connector. + */ + const val CONNECTOR_NAME_PROPERTY: String = "name" + + /** Configuration for offset state key/value converters. */ + val INTERNAL_CONVERTER_CONFIG: Map = + java.util.Map.of(JsonConverterConfig.SCHEMAS_ENABLE_CONFIG, false.toString()) + + internal fun deserializeDebeziumState(opaqueStateValue: OpaqueStateValue): DebeziumState { + val stateNode: ObjectNode = opaqueStateValue[STATE] as ObjectNode + // Deserialize offset. + val offsetNode: ObjectNode = stateNode[MYSQL_CDC_OFFSET] as ObjectNode + val offsetMap: Map = + offsetNode + .fields() + .asSequence() + .map { (k, v) -> Jsons.readTree(k) to Jsons.readTree(v.textValue()) } + .toMap() + if (offsetMap.size != 1) { + throw RuntimeException("Offset object should have 1 key in $opaqueStateValue") + } + val offset = DebeziumOffset(offsetMap) + // Deserialize schema history. + val schemaNode: JsonNode = + stateNode[MYSQL_DB_HISTORY] ?: return DebeziumState(offset, schemaHistory = null) + val isCompressed: Boolean = stateNode[IS_COMPRESSED]?.asBoolean() ?: false + val uncompressedString: String = + if (isCompressed) { + val textValue: String = schemaNode.textValue() + val compressedBytes: ByteArray = + textValue.substring(1, textValue.length - 1).toByteArray(Charsets.UTF_8) + val decoded = Base64.decodeBase64(compressedBytes) + + GZIPInputStream(ByteArrayInputStream(decoded)).reader(Charsets.UTF_8).readText() + } else { + schemaNode.textValue() + } + val schemaHistoryList: List = + uncompressedString + .lines() + .filter { it.isNotBlank() } + .map { HistoryRecord(DocumentReader.defaultReader().read(it)) } + return DebeziumState(offset, DebeziumSchemaHistory(schemaHistoryList)) + } + + internal fun position(offset: DebeziumOffset): MySqlSourceCdcPosition { + if (offset.wrapped.size != 1) { + throw ConfigErrorException("Expected exactly 1 key in $offset") + } + val offsetValue: ObjectNode = offset.wrapped.values.first() as ObjectNode + return MySqlSourceCdcPosition(offsetValue["file"].asText(), offsetValue["pos"].asLong()) + } + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceJdbcPartition.kt b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceJdbcPartition.kt new file mode 100644 index 000000000000..ecb94853c552 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceJdbcPartition.kt @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.mysql + +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.ObjectNode +import io.airbyte.cdk.command.OpaqueStateValue +import io.airbyte.cdk.discover.Field +import io.airbyte.cdk.read.And +import io.airbyte.cdk.read.DefaultJdbcStreamState +import io.airbyte.cdk.read.Equal +import io.airbyte.cdk.read.From +import io.airbyte.cdk.read.FromSample +import io.airbyte.cdk.read.Greater +import io.airbyte.cdk.read.GreaterOrEqual +import io.airbyte.cdk.read.JdbcCursorPartition +import io.airbyte.cdk.read.JdbcPartition +import io.airbyte.cdk.read.JdbcSplittablePartition +import io.airbyte.cdk.read.Lesser +import io.airbyte.cdk.read.LesserOrEqual +import io.airbyte.cdk.read.Limit +import io.airbyte.cdk.read.NoWhere +import io.airbyte.cdk.read.Or +import io.airbyte.cdk.read.OrderBy +import io.airbyte.cdk.read.SelectColumnMaxValue +import io.airbyte.cdk.read.SelectColumns +import io.airbyte.cdk.read.SelectQuery +import io.airbyte.cdk.read.SelectQueryGenerator +import io.airbyte.cdk.read.SelectQuerySpec +import io.airbyte.cdk.read.Stream +import io.airbyte.cdk.read.Where +import io.airbyte.cdk.read.WhereClauseLeafNode +import io.airbyte.cdk.read.WhereClauseNode +import io.airbyte.cdk.read.optimize +import io.airbyte.cdk.util.Jsons + +/** Base class for default implementations of [JdbcPartition] for non resumable partitions. */ +sealed class MySqlSourceJdbcPartition( + val selectQueryGenerator: SelectQueryGenerator, + streamState: DefaultJdbcStreamState, +) : JdbcPartition { + val stream: Stream = streamState.stream + val from = From(stream.name, stream.namespace) + + override val nonResumableQuery: SelectQuery + get() = selectQueryGenerator.generate(nonResumableQuerySpec.optimize()) + + open val nonResumableQuerySpec = SelectQuerySpec(SelectColumns(stream.fields), from) + + override fun samplingQuery(sampleRateInvPow2: Int): SelectQuery { + val sampleSize: Int = streamState.sharedState.maxSampleSize + val querySpec = + SelectQuerySpec( + SelectColumns(stream.fields), + From(stream.name, stream.namespace), + limit = Limit(sampleSize.toLong()), + ) + return selectQueryGenerator.generate(querySpec.optimize()) + } +} + +/** Default implementation of a [JdbcPartition] for an unsplittable snapshot partition. */ +class MySqlSourceJdbcNonResumableSnapshotPartition( + selectQueryGenerator: SelectQueryGenerator, + override val streamState: DefaultJdbcStreamState, +) : MySqlSourceJdbcPartition(selectQueryGenerator, streamState) { + + override val completeState: OpaqueStateValue = MySqlSourceJdbcStreamStateValue.snapshotCompleted +} + +/** + * Default implementation of a [JdbcPartition] for an non resumable snapshot partition preceding a + * cursor-based incremental sync. + */ +class MySqlSourceJdbcNonResumableSnapshotWithCursorPartition( + selectQueryGenerator: SelectQueryGenerator, + override val streamState: DefaultJdbcStreamState, + val cursor: Field, +) : + MySqlSourceJdbcPartition(selectQueryGenerator, streamState), + JdbcCursorPartition { + + override val completeState: OpaqueStateValue + get() = + MySqlSourceJdbcStreamStateValue.cursorIncrementalCheckpoint( + cursor, + cursorCheckpoint = streamState.cursorUpperBound!!, + streamState.stream, + ) + + override val cursorUpperBoundQuery: SelectQuery + get() = selectQueryGenerator.generate(cursorUpperBoundQuerySpec.optimize()) + + val cursorUpperBoundQuerySpec = SelectQuerySpec(SelectColumnMaxValue(cursor), from) +} + +/** Base class for default implementations of [JdbcPartition] for partitions. */ +sealed class MySqlSourceJdbcResumablePartition( + selectQueryGenerator: SelectQueryGenerator, + streamState: DefaultJdbcStreamState, + val checkpointColumns: List, +) : + MySqlSourceJdbcPartition(selectQueryGenerator, streamState), + JdbcSplittablePartition { + abstract val lowerBound: List? + abstract val upperBound: List? + + override val nonResumableQuery: SelectQuery + get() = selectQueryGenerator.generate(nonResumableQuerySpec.optimize()) + + override val nonResumableQuerySpec: SelectQuerySpec + get() = SelectQuerySpec(SelectColumns(stream.fields), from, where) + + override fun resumableQuery(limit: Long): SelectQuery { + val querySpec = + SelectQuerySpec( + SelectColumns((stream.fields + checkpointColumns).distinct()), + from, + where, + OrderBy(checkpointColumns), + Limit(limit), + ) + return selectQueryGenerator.generate(querySpec.optimize()) + } + + override fun samplingQuery(sampleRateInvPow2: Int): SelectQuery { + val sampleSize: Int = streamState.sharedState.maxSampleSize + val querySpec = + SelectQuerySpec( + SelectColumns(stream.fields + checkpointColumns), + FromSample(stream.name, stream.namespace, sampleRateInvPow2, sampleSize), + NoWhere, + OrderBy(checkpointColumns), + Limit(sampleSize.toLong()) + ) + return selectQueryGenerator.generate(querySpec.optimize()) + } + + val where: Where + get() { + val zippedLowerBound: List> = + lowerBound?.let { checkpointColumns.zip(it) } ?: listOf() + val lowerBoundDisj: List = + zippedLowerBound.mapIndexed { idx: Int, (gtCol: Field, gtValue: JsonNode) -> + val lastLeaf: WhereClauseLeafNode = + if (isLowerBoundIncluded && idx == checkpointColumns.size - 1) { + GreaterOrEqual(gtCol, gtValue) + } else { + Greater(gtCol, gtValue) + } + And( + zippedLowerBound.take(idx).map { (eqCol: Field, eqValue: JsonNode) -> + Equal(eqCol, eqValue) + } + listOf(lastLeaf), + ) + } + val zippedUpperBound: List> = + upperBound?.let { checkpointColumns.zip(it) } ?: listOf() + val upperBoundDisj: List = + zippedUpperBound.mapIndexed { idx: Int, (leqCol: Field, leqValue: JsonNode) -> + val lastLeaf: WhereClauseLeafNode = + if (idx < zippedUpperBound.size - 1) { + Lesser(leqCol, leqValue) + } else { + LesserOrEqual(leqCol, leqValue) + } + And( + zippedUpperBound.take(idx).map { (eqCol: Field, eqValue: JsonNode) -> + Equal(eqCol, eqValue) + } + listOf(lastLeaf), + ) + } + return Where(And(Or(lowerBoundDisj), Or(upperBoundDisj))) + } + + open val isLowerBoundIncluded: Boolean = false +} + +/** RFR for cursor based read. */ +class MySqlSourceJdbcRfrSnapshotPartition( + selectQueryGenerator: SelectQueryGenerator, + override val streamState: DefaultJdbcStreamState, + primaryKey: List, + override val lowerBound: List?, + override val upperBound: List?, +) : MySqlSourceJdbcResumablePartition(selectQueryGenerator, streamState, primaryKey) { + + // TODO: this needs to reflect lastRecord. Complete state needs to have last primary key value + // in RFR case. + override val completeState: OpaqueStateValue + get() = + MySqlSourceJdbcStreamStateValue.snapshotCheckpoint( + primaryKey = checkpointColumns, + primaryKeyCheckpoint = + checkpointColumns.map { upperBound?.get(0) ?: Jsons.nullNode() }, + ) + + override fun incompleteState(lastRecord: ObjectNode): OpaqueStateValue = + MySqlSourceJdbcStreamStateValue.snapshotCheckpoint( + primaryKey = checkpointColumns, + primaryKeyCheckpoint = checkpointColumns.map { lastRecord[it.id] ?: Jsons.nullNode() }, + ) +} + +/** RFR for CDC. */ +class MySqlSourceJdbcCdcRfrSnapshotPartition( + selectQueryGenerator: SelectQueryGenerator, + override val streamState: DefaultJdbcStreamState, + primaryKey: List, + override val lowerBound: List?, + override val upperBound: List?, +) : MySqlSourceJdbcResumablePartition(selectQueryGenerator, streamState, primaryKey) { + override val completeState: OpaqueStateValue + get() = + MySqlSourceCdcInitialSnapshotStateValue.snapshotCheckpoint( + primaryKey = checkpointColumns, + primaryKeyCheckpoint = + checkpointColumns.map { upperBound?.get(0) ?: Jsons.nullNode() }, + ) + + override fun incompleteState(lastRecord: ObjectNode): OpaqueStateValue = + MySqlSourceCdcInitialSnapshotStateValue.snapshotCheckpoint( + primaryKey = checkpointColumns, + primaryKeyCheckpoint = checkpointColumns.map { lastRecord[it.id] ?: Jsons.nullNode() }, + ) +} + +/** + * Implementation of a [JdbcPartition] for a CDC snapshot partition. Used for incremental CDC + * initial sync. + */ +class MySqlSourceJdbcCdcSnapshotPartition( + selectQueryGenerator: SelectQueryGenerator, + override val streamState: DefaultJdbcStreamState, + primaryKey: List, + override val lowerBound: List? +) : MySqlSourceJdbcResumablePartition(selectQueryGenerator, streamState, primaryKey) { + override val upperBound: List? = null + override val completeState: OpaqueStateValue + get() = MySqlSourceCdcInitialSnapshotStateValue.getSnapshotCompletedState(stream) + + override fun incompleteState(lastRecord: ObjectNode): OpaqueStateValue = + MySqlSourceCdcInitialSnapshotStateValue.snapshotCheckpoint( + primaryKey = checkpointColumns, + primaryKeyCheckpoint = checkpointColumns.map { lastRecord[it.id] ?: Jsons.nullNode() }, + ) +} + +/** + * Default implementation of a [JdbcPartition] for a splittable partition involving cursor columns. + */ +sealed class MySqlSourceJdbcCursorPartition( + selectQueryGenerator: SelectQueryGenerator, + streamState: DefaultJdbcStreamState, + checkpointColumns: List, + val cursor: Field, + private val explicitCursorUpperBound: JsonNode?, +) : + MySqlSourceJdbcResumablePartition(selectQueryGenerator, streamState, checkpointColumns), + JdbcCursorPartition { + + val cursorUpperBound: JsonNode + get() = explicitCursorUpperBound ?: streamState.cursorUpperBound ?: Jsons.nullNode() + + override val cursorUpperBoundQuery: SelectQuery + get() = selectQueryGenerator.generate(cursorUpperBoundQuerySpec.optimize()) + + val cursorUpperBoundQuerySpec = SelectQuerySpec(SelectColumnMaxValue(cursor), from) +} + +/** + * Default implementation of a [JdbcPartition] for a splittable snapshot partition preceding a + * cursor-based incremental sync. + */ +class MySqlSourceJdbcSnapshotWithCursorPartition( + selectQueryGenerator: SelectQueryGenerator, + override val streamState: DefaultJdbcStreamState, + primaryKey: List, + override val lowerBound: List?, + cursor: Field, + cursorUpperBound: JsonNode?, +) : + MySqlSourceJdbcCursorPartition( + selectQueryGenerator, + streamState, + primaryKey, + cursor, + cursorUpperBound + ) { + // UpperBound is not used because the partition is not splittable. + override val upperBound: List? = null + + override val completeState: OpaqueStateValue + get() = + MySqlSourceJdbcStreamStateValue.cursorIncrementalCheckpoint( + cursor, + cursorUpperBound, + stream, + ) + + override fun incompleteState(lastRecord: ObjectNode): OpaqueStateValue = + MySqlSourceJdbcStreamStateValue.snapshotWithCursorCheckpoint( + primaryKey = checkpointColumns, + primaryKeyCheckpoint = checkpointColumns.map { lastRecord[it.id] ?: Jsons.nullNode() }, + cursor, + stream, + ) +} + +/** + * Default implementation of a [JdbcPartition] for a cursor incremental partition. These are always + * splittable. + */ +class MySqlSourceJdbcCursorIncrementalPartition( + selectQueryGenerator: SelectQueryGenerator, + override val streamState: DefaultJdbcStreamState, + cursor: Field, + val cursorLowerBound: JsonNode, + override val isLowerBoundIncluded: Boolean, + cursorUpperBound: JsonNode?, +) : + MySqlSourceJdbcCursorPartition( + selectQueryGenerator, + streamState, + listOf(cursor), + cursor, + cursorUpperBound + ) { + + override val lowerBound: List = listOf(cursorLowerBound) + override val upperBound: List + get() = listOf(cursorUpperBound) + + override val completeState: OpaqueStateValue + get() = + MySqlSourceJdbcStreamStateValue.cursorIncrementalCheckpoint( + cursor, + cursorCheckpoint = cursorUpperBound, + stream, + ) + + override fun incompleteState(lastRecord: ObjectNode): OpaqueStateValue = + MySqlSourceJdbcStreamStateValue.cursorIncrementalCheckpoint( + cursor, + cursorCheckpoint = lastRecord[cursor.id] ?: Jsons.nullNode(), + stream, + ) +} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceJdbcPartitionFactory.kt b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceJdbcPartitionFactory.kt new file mode 100644 index 000000000000..b40ffc3e6331 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceJdbcPartitionFactory.kt @@ -0,0 +1,403 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.mysql + +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.BinaryNode +import io.airbyte.cdk.ConfigErrorException +import io.airbyte.cdk.StreamIdentifier +import io.airbyte.cdk.command.OpaqueStateValue +import io.airbyte.cdk.data.LeafAirbyteSchemaType +import io.airbyte.cdk.data.LocalDateTimeCodec +import io.airbyte.cdk.data.OffsetDateTimeCodec +import io.airbyte.cdk.discover.Field +import io.airbyte.cdk.jdbc.JdbcConnectionFactory +import io.airbyte.cdk.jdbc.JdbcFieldType +import io.airbyte.cdk.read.ConfiguredSyncMode +import io.airbyte.cdk.read.DefaultJdbcSharedState +import io.airbyte.cdk.read.DefaultJdbcStreamState +import io.airbyte.cdk.read.From +import io.airbyte.cdk.read.JdbcPartitionFactory +import io.airbyte.cdk.read.SelectColumnMaxValue +import io.airbyte.cdk.read.SelectQuerySpec +import io.airbyte.cdk.read.Stream +import io.airbyte.cdk.read.StreamFeedBootstrap +import io.airbyte.cdk.util.Jsons +import io.micronaut.context.annotation.Primary +import jakarta.inject.Singleton +import java.time.LocalDateTime +import java.time.OffsetDateTime +import java.time.ZoneOffset.UTC +import java.time.format.DateTimeFormatter +import java.time.format.DateTimeFormatterBuilder +import java.time.format.DateTimeParseException +import java.time.temporal.ChronoField +import java.util.* +import java.util.concurrent.ConcurrentHashMap + +@Primary +@Singleton +class MySqlSourceJdbcPartitionFactory( + override val sharedState: DefaultJdbcSharedState, + val selectQueryGenerator: MySqlSourceOperations, + val config: MySqlSourceConfiguration, +) : + JdbcPartitionFactory< + DefaultJdbcSharedState, + DefaultJdbcStreamState, + MySqlSourceJdbcPartition, + > { + + private val streamStates = ConcurrentHashMap() + + override fun streamState(streamFeedBootstrap: StreamFeedBootstrap): DefaultJdbcStreamState = + streamStates.getOrPut(streamFeedBootstrap.feed.id) { + DefaultJdbcStreamState(sharedState, streamFeedBootstrap) + } + + private fun findPkUpperBound(stream: Stream, pkChosenFromCatalog: List): JsonNode { + // find upper bound using maxPk query + val jdbcConnectionFactory = JdbcConnectionFactory(config) + val from = From(stream.name, stream.namespace) + val maxPkQuery = SelectQuerySpec(SelectColumnMaxValue(pkChosenFromCatalog[0]), from) + + jdbcConnectionFactory.get().use { connection -> + val stmt = connection.prepareStatement(selectQueryGenerator.generate(maxPkQuery).sql) + val rs = stmt.executeQuery() + + if (rs.next()) { + val jdbcFieldType = pkChosenFromCatalog[0].type as JdbcFieldType<*> + val pkUpperBound: JsonNode = jdbcFieldType.get(rs, 1) + return pkUpperBound + } else { + // Table might be empty thus there is no max PK value. + return Jsons.nullNode() + } + } + } + + private fun coldStart(streamState: DefaultJdbcStreamState): MySqlSourceJdbcPartition { + val stream: Stream = streamState.stream + val pkChosenFromCatalog: List = stream.configuredPrimaryKey ?: listOf() + + if (stream.configuredSyncMode == ConfiguredSyncMode.FULL_REFRESH) { + if (pkChosenFromCatalog.isEmpty()) { + return MySqlSourceJdbcNonResumableSnapshotPartition( + selectQueryGenerator, + streamState, + ) + } + + val upperBound = findPkUpperBound(stream, pkChosenFromCatalog) + if (sharedState.configuration.global) { + return MySqlSourceJdbcCdcRfrSnapshotPartition( + selectQueryGenerator, + streamState, + pkChosenFromCatalog, + lowerBound = null, + upperBound = listOf(upperBound) + ) + } else { + return MySqlSourceJdbcRfrSnapshotPartition( + selectQueryGenerator, + streamState, + pkChosenFromCatalog, + lowerBound = null, + upperBound = listOf(upperBound) + ) + } + } + + if (sharedState.configuration.global) { + return MySqlSourceJdbcCdcSnapshotPartition( + selectQueryGenerator, + streamState, + pkChosenFromCatalog, + lowerBound = null, + ) + } + + val cursorChosenFromCatalog: Field = + stream.configuredCursor as? Field ?: throw ConfigErrorException("no cursor") + + if (pkChosenFromCatalog.isEmpty()) { + return MySqlSourceJdbcNonResumableSnapshotWithCursorPartition( + selectQueryGenerator, + streamState, + cursorChosenFromCatalog + ) + } + return MySqlSourceJdbcSnapshotWithCursorPartition( + selectQueryGenerator, + streamState, + pkChosenFromCatalog, + lowerBound = null, + cursorChosenFromCatalog, + cursorUpperBound = null, + ) + } + + /** + * Flowchart: + * 1. If the input state is null - using coldstart. + * ``` + * a. If it's global but without PK, use non-resumable snapshot. + * b. If it's global with PK, use snapshot. + * c. If it's not global, use snapshot with cursor. + * ``` + * 2. If the input state is not null - + * ``` + * a. If it's in global mode, JdbcPartitionFactory will not handle this. (TODO) + * b. If it's cursor based, it could be either in PK read phase (initial read) or + * cursor read phase (incremental read). This is differentiated by the stateType. + * i. In PK read phase, use snapshot with cursor. If no PKs were found, + * use non-resumable snapshot with cursor. + * ii. In cursor read phase, use cursor incremental. + * ``` + */ + override fun create(streamFeedBootstrap: StreamFeedBootstrap): MySqlSourceJdbcPartition? { + val stream: Stream = streamFeedBootstrap.feed + val streamState: DefaultJdbcStreamState = streamState(streamFeedBootstrap) + + // An empty table stream state will be marked as a nullNode. This prevents repeated attempt + // to read it + if (streamFeedBootstrap.currentState?.isNull == true) { + return null + } + + // A legacy saved state may be null for an empty table. We will attempt to read it again + if ( + streamFeedBootstrap.currentState == null || + streamFeedBootstrap.currentState?.isEmpty == true + ) { + return coldStart(streamState) + } + + val opaqueStateValue: OpaqueStateValue = streamFeedBootstrap.currentState!! + + val isCursorBased: Boolean = !sharedState.configuration.global + + val pkChosenFromCatalog: List = stream.configuredPrimaryKey ?: listOf() + + if ( + pkChosenFromCatalog.isEmpty() && + stream.configuredSyncMode == ConfiguredSyncMode.FULL_REFRESH + ) { + if ( + streamState.streamFeedBootstrap.currentState == + MySqlSourceJdbcStreamStateValue.snapshotCompleted + ) { + return null + } + return MySqlSourceJdbcNonResumableSnapshotPartition( + selectQueryGenerator, + streamState, + ) + } + + if (!isCursorBased) { + val sv: MySqlSourceCdcInitialSnapshotStateValue = + Jsons.treeToValue( + opaqueStateValue, + MySqlSourceCdcInitialSnapshotStateValue::class.java + ) + + if (stream.configuredSyncMode == ConfiguredSyncMode.FULL_REFRESH) { + val upperBound = findPkUpperBound(stream, pkChosenFromCatalog) + if (sv.pkVal == upperBound.asText()) { + return null + } + val pkLowerBound: JsonNode = stateValueToJsonNode(pkChosenFromCatalog[0], sv.pkVal) + + return MySqlSourceJdbcRfrSnapshotPartition( + selectQueryGenerator, + streamState, + pkChosenFromCatalog, + lowerBound = if (pkLowerBound.isNull) null else listOf(pkLowerBound), + upperBound = listOf(upperBound) + ) + } + + if (sv.pkName == null) { + // This indicates initial snapshot has been completed. CDC snapshot will be handled + // by CDCPartitionFactory. + // Nothing to do here. + return null + } else { + // This branch indicates snapshot is incomplete. We need to resume based on previous + // snapshot state. + val pkField = pkChosenFromCatalog.first() + val pkLowerBound: JsonNode = stateValueToJsonNode(pkField, sv.pkVal) + + if (stream.configuredSyncMode == ConfiguredSyncMode.FULL_REFRESH) { + val upperBound = findPkUpperBound(stream, pkChosenFromCatalog) + if (sv.pkVal == upperBound.asText()) { + return null + } + return MySqlSourceJdbcCdcRfrSnapshotPartition( + selectQueryGenerator, + streamState, + pkChosenFromCatalog, + lowerBound = if (pkLowerBound.isNull) null else listOf(pkLowerBound), + upperBound = listOf(upperBound) + ) + } + return MySqlSourceJdbcCdcSnapshotPartition( + selectQueryGenerator, + streamState, + pkChosenFromCatalog, + lowerBound = listOf(pkLowerBound), + ) + } + } else { + val sv: MySqlSourceJdbcStreamStateValue = + Jsons.treeToValue(opaqueStateValue, MySqlSourceJdbcStreamStateValue::class.java) + + if (stream.configuredSyncMode == ConfiguredSyncMode.FULL_REFRESH) { + val upperBound = findPkUpperBound(stream, pkChosenFromCatalog) + if (sv.pkValue == upperBound.asText()) { + return null + } + val pkLowerBound: JsonNode = + stateValueToJsonNode(pkChosenFromCatalog[0], sv.pkValue) + + return MySqlSourceJdbcCdcRfrSnapshotPartition( + selectQueryGenerator, + streamState, + pkChosenFromCatalog, + lowerBound = if (pkLowerBound.isNull) null else listOf(pkLowerBound), + upperBound = listOf(upperBound) + ) + } + + if (sv.stateType != "cursor_based") { + // Loading value from catalog. Note there could be unexpected behaviors if user + // updates their schema but did not reset their state. + val pkField = pkChosenFromCatalog.first() + val pkLowerBound: JsonNode = stateValueToJsonNode(pkField, sv.pkValue) + + val cursorChosenFromCatalog: Field = + stream.configuredCursor as? Field ?: throw ConfigErrorException("no cursor") + + // in a state where it's still in primary_key read part. + return MySqlSourceJdbcSnapshotWithCursorPartition( + selectQueryGenerator, + streamState, + pkChosenFromCatalog, + lowerBound = listOf(pkLowerBound), + cursorChosenFromCatalog, + cursorUpperBound = null, + ) + } + // resume back to cursor based increment. + val cursor: Field = stream.fields.find { it.id == sv.cursorField.first() } as Field + val cursorCheckpoint: JsonNode = stateValueToJsonNode(cursor, sv.cursors) + + // Compose a jsonnode of cursor label to cursor value to fit in + // DefaultJdbcCursorIncrementalPartition + if (cursorCheckpoint.isNull) { + return coldStart(streamState) + } + + if (cursorCheckpoint.toString() == streamState.cursorUpperBound?.toString()) { + // Incremental complete. + return null + } + return MySqlSourceJdbcCursorIncrementalPartition( + selectQueryGenerator, + streamState, + cursor, + cursorLowerBound = cursorCheckpoint, + isLowerBoundIncluded = false, + cursorUpperBound = streamState.cursorUpperBound, + ) + } + } + + private fun stateValueToJsonNode(field: Field, stateValue: String?): JsonNode { + when (field.type.airbyteSchemaType) { + is LeafAirbyteSchemaType -> + return when (field.type.airbyteSchemaType as LeafAirbyteSchemaType) { + LeafAirbyteSchemaType.INTEGER -> { + Jsons.valueToTree(stateValue?.toBigInteger()) + } + LeafAirbyteSchemaType.NUMBER -> { + Jsons.valueToTree(stateValue?.toDouble()) + } + LeafAirbyteSchemaType.BINARY -> { + try { + val ba = Base64.getDecoder().decode(stateValue!!) + Jsons.valueToTree(ba) + } catch (_: RuntimeException) { + Jsons.valueToTree(stateValue) + } + } + LeafAirbyteSchemaType.TIMESTAMP_WITHOUT_TIMEZONE -> { + val timestampInStatePattern = "yyyy-MM-dd'T'HH:mm:ss" + try { + val formatter: DateTimeFormatter = + DateTimeFormatterBuilder() + .appendPattern(timestampInStatePattern) + .optionalStart() + .appendFraction(ChronoField.NANO_OF_SECOND, 1, 9, true) + .optionalEnd() + .toFormatter() + + Jsons.textNode( + LocalDateTime.parse(stateValue, formatter) + .format(LocalDateTimeCodec.formatter) + ) + } catch (_: RuntimeException) { + // Resolve to use the new format. + Jsons.valueToTree(stateValue) + } + } + LeafAirbyteSchemaType.TIMESTAMP_WITH_TIMEZONE -> { + val timestampInStatePattern = "yyyy-MM-dd'T'HH:mm:ss" + val formatter = + DateTimeFormatterBuilder() + .appendPattern(timestampInStatePattern) + .optionalStart() + .appendFraction(ChronoField.NANO_OF_SECOND, 1, 9, true) + .optionalEnd() + .optionalStart() + .optionalStart() + .appendLiteral(' ') + .optionalEnd() + .appendOffset("+HH:mm", "Z") + .optionalEnd() + .toFormatter() + + try { + val offsetDateTime = + try { + OffsetDateTime.parse(stateValue, formatter) + } catch (_: DateTimeParseException) { + // if no offset exists, we assume it's UTC + LocalDateTime.parse(stateValue, formatter).atOffset(UTC) + } + Jsons.valueToTree(offsetDateTime.format(OffsetDateTimeCodec.formatter)) + } catch (_: RuntimeException) { + // Resolve to use the new format. + Jsons.valueToTree(stateValue) + } + } + else -> Jsons.valueToTree(stateValue) + } + else -> + throw IllegalStateException( + "PK field must be leaf type but is ${field.type.airbyteSchemaType}." + ) + } + } + + override fun split( + unsplitPartition: MySqlSourceJdbcPartition, + opaqueStateValues: List + ): List { + // At this moment we don't support split on within mysql stream in any mode. + return listOf(unsplitPartition) + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceJdbcStreamStateValue.kt b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceJdbcStreamStateValue.kt new file mode 100644 index 000000000000..53f755a06a5e --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceJdbcStreamStateValue.kt @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.mysql + +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.databind.JsonNode +import io.airbyte.cdk.command.OpaqueStateValue +import io.airbyte.cdk.discover.Field +import io.airbyte.cdk.read.Stream +import io.airbyte.cdk.util.Jsons + +data class MySqlSourceJdbcStreamStateValue( + @JsonProperty("cursor") val cursors: String? = null, + @JsonProperty("version") val version: Int = 2, + @JsonProperty("state_type") val stateType: String = StateType.CURSOR_BASED.serialized, + @JsonProperty("stream_name") val streamName: String = "", + @JsonProperty("cursor_field") val cursorField: List = listOf(), + @JsonProperty("stream_namespace") val streamNamespace: String = "", + @JsonProperty("cursor_record_count") val cursorRecordCount: Int = 0, + @JsonProperty("pk_name") val pkName: String? = null, + @JsonProperty("pk_val") val pkValue: String? = null, + @JsonProperty("incremental_state") val incrementalState: JsonNode? = null, +) { + companion object { + /** Value representing the completion of a FULL_REFRESH snapshot. */ + val snapshotCompleted: OpaqueStateValue + get() = Jsons.valueToTree(MySqlSourceJdbcStreamStateValue(stateType = "primary_key")) + + /** Value representing the progress of an ongoing incremental cursor read. */ + fun cursorIncrementalCheckpoint( + cursor: Field, + cursorCheckpoint: JsonNode, + stream: Stream, + ): OpaqueStateValue { + return when (cursorCheckpoint.isNull) { + true -> Jsons.nullNode() + false -> + Jsons.valueToTree( + MySqlSourceJdbcStreamStateValue( + cursorField = listOf(cursor.id), + cursors = cursorCheckpoint.asText(), + streamName = stream.name, + streamNamespace = stream.namespace!! + ) + ) + } + } + + /** Value representing the progress of an ongoing snapshot not involving cursor columns. */ + fun snapshotCheckpoint( + primaryKey: List, + primaryKeyCheckpoint: List, + ): OpaqueStateValue { + val primaryKeyField = primaryKey.first() + return when (primaryKeyCheckpoint.first().isNull) { + true -> Jsons.nullNode() + false -> + Jsons.valueToTree( + MySqlSourceJdbcStreamStateValue( + pkName = primaryKeyField.id, + pkValue = primaryKeyCheckpoint.first().asText(), + stateType = StateType.PRIMARY_KEY.serialized, + ) + ) + } + } + + /** Value representing the progress of an ongoing snapshot involving cursor columns. */ + fun snapshotWithCursorCheckpoint( + primaryKey: List, + primaryKeyCheckpoint: List, + cursor: Field, + stream: Stream + ): OpaqueStateValue { + val primaryKeyField = primaryKey.first() + return when (primaryKeyCheckpoint.first().isNull) { + true -> Jsons.nullNode() + false -> + Jsons.valueToTree( + MySqlSourceJdbcStreamStateValue( + pkName = primaryKeyField.id, + pkValue = primaryKeyCheckpoint.first().asText(), + stateType = StateType.PRIMARY_KEY.serialized, + incrementalState = + Jsons.valueToTree( + MySqlSourceJdbcStreamStateValue( + cursorField = listOf(cursor.id), + streamName = stream.name, + streamNamespace = stream.namespace!! + ) + ), + ) + ) + } + } + } + + enum class StateType { + PRIMARY_KEY, + CURSOR_BASED, + ; + + val serialized: String = name.lowercase() + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceMetadataQuerier.kt b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceMetadataQuerier.kt new file mode 100644 index 000000000000..54e0a2d6f146 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceMetadataQuerier.kt @@ -0,0 +1,227 @@ +/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ +package io.airbyte.integrations.source.mysql + +import io.airbyte.cdk.ConfigErrorException +import io.airbyte.cdk.StreamIdentifier +import io.airbyte.cdk.check.JdbcCheckQueries +import io.airbyte.cdk.command.SourceConfiguration +import io.airbyte.cdk.discover.Field +import io.airbyte.cdk.discover.JdbcMetadataQuerier +import io.airbyte.cdk.discover.MetadataQuerier +import io.airbyte.cdk.discover.TableName +import io.airbyte.cdk.jdbc.DefaultJdbcConstants +import io.airbyte.cdk.jdbc.JdbcConnectionFactory +import io.airbyte.cdk.read.SelectQueryGenerator +import io.airbyte.protocol.models.v0.StreamDescriptor +import io.github.oshai.kotlinlogging.KotlinLogging +import io.micronaut.context.annotation.Primary +import jakarta.inject.Singleton +import java.sql.Connection +import java.sql.ResultSet +import java.sql.SQLException +import java.sql.Statement + +private val log = KotlinLogging.logger {} + +/** Delegates to [JdbcMetadataQuerier] except for [fields]. */ +class MySqlSourceMetadataQuerier( + val base: JdbcMetadataQuerier, +) : MetadataQuerier by base { + + override fun extraChecks() { + base.extraChecks() + if (base.config.global) { + // Extra checks for CDC + var cdcVariableCheckQueries: List> = + listOf( + Pair("show variables where Variable_name = 'log_bin'", "ON"), + Pair("show variables where Variable_name = 'binlog_format'", "ROW"), + Pair("show variables where Variable_name = 'binlog_row_image'", "FULL"), + ) + + cdcVariableCheckQueries.forEach { runVariableCheckSql(it.first, it.second, base.conn) } + + // Note: SHOW MASTER STATUS has been deprecated in latest mysql (8.4) and going forward + // it should be SHOW BINARY LOG STATUS. We will run both - if both have been failed we + // will throw exception. + try { + base.conn.createStatement().use { stmt: Statement -> + stmt.execute("SHOW MASTER STATUS") + } + } catch (e: SQLException) { + try { + base.conn.createStatement().use { stmt: Statement -> + stmt.execute("SHOW BINARY LOG STATUS") + } + } catch (ex: SQLException) { + throw ConfigErrorException( + "Please grant REPLICATION CLIENT privilege, so that binary log files are available for CDC mode." + ) + } + } + } + } + + private fun runVariableCheckSql(sql: String, expectedValue: String, conn: Connection) { + try { + conn.createStatement().use { stmt: Statement -> + stmt.executeQuery(sql).use { rs: ResultSet -> + if (!rs.next()) { + throw ConfigErrorException("Could not query the variable $sql") + } + val resultValue: String = rs.getString("Value") + if (!resultValue.equals(expectedValue, ignoreCase = true)) { + throw ConfigErrorException( + String.format( + "The variable should be set to \"%s\", but it is \"%s\"", + expectedValue, + resultValue, + ), + ) + } + if (rs.next()) { + throw ConfigErrorException("Could not query the variable $sql") + } + } + } + } catch (e: Exception) { + throw ConfigErrorException("Check query failed with: ${e.message}") + } + } + + override fun fields(streamID: StreamIdentifier): List { + val table: TableName = findTableName(streamID) ?: return listOf() + if (table !in base.memoizedColumnMetadata) return listOf() + return base.memoizedColumnMetadata[table]!!.map { + Field(it.label, base.fieldTypeMapper.toFieldType(it)) + } + } + + override fun streamNamespaces(): List = base.config.namespaces.toList() + + override fun streamNames(streamNamespace: String?): List = + base.memoizedTableNames + .filter { (it.schema ?: it.catalog) == streamNamespace } + .map { StreamDescriptor().withName(it.name).withNamespace(streamNamespace) } + .map(StreamIdentifier::from) + + fun findTableName( + streamID: StreamIdentifier, + ): TableName? = + base.memoizedTableNames.find { + it.name == streamID.name && (it.schema ?: it.catalog) == streamID.namespace + } + + val memoizedPrimaryKeys: Map>> by lazy { + val results = mutableListOf() + val schemas: List = streamNamespaces() + val sql: String = PK_QUERY_FMTSTR.format(schemas.joinToString { "\'$it\'" }) + log.info { "Querying MySQL system tables for all primary keys for catalog discovery." } + try { + // Get primary keys for the specified table + base.conn.createStatement().use { stmt: Statement -> + stmt.executeQuery(sql).use { rs: ResultSet -> + while (rs.next()) { + results.add( + AllPrimaryKeysRow( + rs.getString("table_schema"), + rs.getString("table_name"), + rs.getString("constraint_name"), + rs.getInt("ordinal_position").takeUnless { rs.wasNull() }, + rs.getString("column_name").takeUnless { rs.wasNull() }, + ), + ) + } + } + } + log.info { "Discovered all primary keys in ${schemas.size} MySQL schema(s)." } + return@lazy results + .groupBy { + findTableName( + StreamIdentifier.from( + StreamDescriptor().withName(it.tableName).withNamespace(it.tableSchema), + ), + ) + } + .mapNotNull { (table, rowsByTable) -> + if (table == null) return@mapNotNull null + val pkRows: List = + rowsByTable + .groupBy { it.constraintName } + .filterValues { rowsByPK: List -> + rowsByPK.all { it.position != null && it.columnName != null } + } + .values + .firstOrNull() + ?: return@mapNotNull null + val pkColumnNames: List> = + pkRows + .sortedBy { it.position } + .mapNotNull { it.columnName } + .map { listOf(it) } + table to pkColumnNames + } + .toMap() + } catch (e: Exception) { + throw RuntimeException("MySQL primary key discovery query failed: ${e.message}", e) + } + } + + override fun primaryKey( + streamID: StreamIdentifier, + ): List> { + val table: TableName = findTableName(streamID) ?: return listOf() + return memoizedPrimaryKeys[table] ?: listOf() + } + + private data class AllPrimaryKeysRow( + val tableSchema: String, + val tableName: String, + val constraintName: String, + val position: Int?, + val columnName: String?, + ) + + companion object { + + const val PK_QUERY_FMTSTR = + """ + SELECT + table_schema, + table_name, + column_name, + ordinal_position, + constraint_name + FROM + information_schema.key_column_usage + WHERE + table_schema IN (%s) + AND constraint_name = 'PRIMARY'; + """ + } + + /** MySQL implementation of [MetadataQuerier.Factory]. */ + @Singleton + @Primary + class Factory( + val constants: DefaultJdbcConstants, + val selectQueryGenerator: SelectQueryGenerator, + val fieldTypeMapper: JdbcMetadataQuerier.FieldTypeMapper, + val checkQueries: JdbcCheckQueries, + ) : MetadataQuerier.Factory { + /** The [SourceConfiguration] is deliberately not injected in order to support tests. */ + override fun session(config: MySqlSourceConfiguration): MetadataQuerier { + val jdbcConnectionFactory = JdbcConnectionFactory(config) + val base = + JdbcMetadataQuerier( + constants, + config, + selectQueryGenerator, + fieldTypeMapper, + checkQueries, + jdbcConnectionFactory, + ) + return MySqlSourceMetadataQuerier(base) + } + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceOperations.kt b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceOperations.kt new file mode 100644 index 000000000000..dc7930ea91bc --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceOperations.kt @@ -0,0 +1,275 @@ +/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ +package io.airbyte.integrations.source.mysql + +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.ObjectNode +import com.mysql.cj.MysqlType +import io.airbyte.cdk.command.OpaqueStateValue +import io.airbyte.cdk.discover.CdcIntegerMetaFieldType +import io.airbyte.cdk.discover.CdcOffsetDateTimeMetaFieldType +import io.airbyte.cdk.discover.CdcStringMetaFieldType +import io.airbyte.cdk.discover.CommonMetaField +import io.airbyte.cdk.discover.Field +import io.airbyte.cdk.discover.FieldType +import io.airbyte.cdk.discover.JdbcAirbyteStreamFactory +import io.airbyte.cdk.discover.JdbcMetadataQuerier +import io.airbyte.cdk.discover.MetaField +import io.airbyte.cdk.discover.SystemType +import io.airbyte.cdk.jdbc.BigDecimalFieldType +import io.airbyte.cdk.jdbc.BigIntegerFieldType +import io.airbyte.cdk.jdbc.BinaryStreamFieldType +import io.airbyte.cdk.jdbc.BooleanFieldType +import io.airbyte.cdk.jdbc.BytesFieldType +import io.airbyte.cdk.jdbc.DoubleFieldType +import io.airbyte.cdk.jdbc.FloatFieldType +import io.airbyte.cdk.jdbc.IntFieldType +import io.airbyte.cdk.jdbc.JdbcFieldType +import io.airbyte.cdk.jdbc.LocalDateFieldType +import io.airbyte.cdk.jdbc.LocalDateTimeFieldType +import io.airbyte.cdk.jdbc.LocalTimeFieldType +import io.airbyte.cdk.jdbc.LongFieldType +import io.airbyte.cdk.jdbc.LosslessJdbcFieldType +import io.airbyte.cdk.jdbc.NullFieldType +import io.airbyte.cdk.jdbc.OffsetDateTimeFieldType +import io.airbyte.cdk.jdbc.PokemonFieldType +import io.airbyte.cdk.jdbc.ShortFieldType +import io.airbyte.cdk.jdbc.StringFieldType +import io.airbyte.cdk.read.And +import io.airbyte.cdk.read.Equal +import io.airbyte.cdk.read.From +import io.airbyte.cdk.read.FromNode +import io.airbyte.cdk.read.FromSample +import io.airbyte.cdk.read.Greater +import io.airbyte.cdk.read.GreaterOrEqual +import io.airbyte.cdk.read.Lesser +import io.airbyte.cdk.read.LesserOrEqual +import io.airbyte.cdk.read.Limit +import io.airbyte.cdk.read.LimitNode +import io.airbyte.cdk.read.NoFrom +import io.airbyte.cdk.read.NoLimit +import io.airbyte.cdk.read.NoOrderBy +import io.airbyte.cdk.read.NoWhere +import io.airbyte.cdk.read.Or +import io.airbyte.cdk.read.OrderBy +import io.airbyte.cdk.read.OrderByNode +import io.airbyte.cdk.read.SelectColumnMaxValue +import io.airbyte.cdk.read.SelectColumns +import io.airbyte.cdk.read.SelectNode +import io.airbyte.cdk.read.SelectQuery +import io.airbyte.cdk.read.SelectQueryGenerator +import io.airbyte.cdk.read.SelectQuerySpec +import io.airbyte.cdk.read.Stream +import io.airbyte.cdk.read.Where +import io.airbyte.cdk.read.WhereClauseLeafNode +import io.airbyte.cdk.read.WhereClauseNode +import io.airbyte.cdk.read.WhereNode +import io.airbyte.cdk.read.cdc.DebeziumState +import io.airbyte.cdk.util.Jsons +import io.micronaut.context.annotation.Primary +import jakarta.inject.Singleton +import java.time.OffsetDateTime + +@Singleton +@Primary +class MySqlSourceOperations : + JdbcMetadataQuerier.FieldTypeMapper, SelectQueryGenerator, JdbcAirbyteStreamFactory { + + override val globalCursor: MetaField = MySqlSourceCdcMetaFields.CDC_CURSOR + + override val globalMetaFields: Set = + setOf( + MySqlSourceCdcMetaFields.CDC_CURSOR, + CommonMetaField.CDC_UPDATED_AT, + CommonMetaField.CDC_DELETED_AT, + MySqlSourceCdcMetaFields.CDC_LOG_FILE, + MySqlSourceCdcMetaFields.CDC_LOG_POS + ) + + override fun decorateRecordData( + timestamp: OffsetDateTime, + globalStateValue: OpaqueStateValue?, + stream: Stream, + recordData: ObjectNode + ) { + recordData.set( + CommonMetaField.CDC_UPDATED_AT.id, + CdcOffsetDateTimeMetaFieldType.jsonEncoder.encode(timestamp), + ) + recordData.set( + MySqlSourceCdcMetaFields.CDC_LOG_POS.id, + CdcIntegerMetaFieldType.jsonEncoder.encode(0), + ) + if (globalStateValue == null) { + return + } + val debeziumState: DebeziumState = + MySqlSourceDebeziumOperations.deserializeDebeziumState(globalStateValue) + val position: MySqlSourceCdcPosition = + MySqlSourceDebeziumOperations.position(debeziumState.offset) + recordData.set( + MySqlSourceCdcMetaFields.CDC_LOG_FILE.id, + CdcStringMetaFieldType.jsonEncoder.encode(position.fileName), + ) + recordData.set( + MySqlSourceCdcMetaFields.CDC_LOG_POS.id, + CdcIntegerMetaFieldType.jsonEncoder.encode(position.position), + ) + } + + override fun toFieldType(c: JdbcMetadataQuerier.ColumnMetadata): FieldType = + when (val type = c.type) { + is SystemType -> leafType(type) + else -> PokemonFieldType + } + + private fun leafType(type: SystemType): JdbcFieldType<*> { + return when (MysqlType.getByName(type.typeName)) { + MysqlType.BIT -> if (type.precision == 1) BooleanFieldType else BytesFieldType + MysqlType.BOOLEAN -> BooleanFieldType + MysqlType.TINYINT, + MysqlType.TINYINT_UNSIGNED, + MysqlType.YEAR -> ShortFieldType + MysqlType.SMALLINT, + MysqlType.SMALLINT_UNSIGNED, + MysqlType.MEDIUMINT, + MysqlType.MEDIUMINT_UNSIGNED, + MysqlType.INT -> IntFieldType + MysqlType.INT_UNSIGNED, + MysqlType.BIGINT -> LongFieldType + MysqlType.BIGINT_UNSIGNED -> BigIntegerFieldType + MysqlType.FLOAT, + MysqlType.FLOAT_UNSIGNED, + MysqlType.DOUBLE, + MysqlType.DOUBLE_UNSIGNED -> { + if ((type.precision ?: 0) <= 23) FloatFieldType else DoubleFieldType + } + MysqlType.DECIMAL, + MysqlType.DECIMAL_UNSIGNED -> { + if (type.scale == 0) BigIntegerFieldType else BigDecimalFieldType + } + MysqlType.DATE -> LocalDateFieldType + MysqlType.DATETIME -> LocalDateTimeFieldType + MysqlType.TIMESTAMP -> OffsetDateTimeFieldType + MysqlType.TIME -> LocalTimeFieldType + MysqlType.CHAR, + MysqlType.VARCHAR, + MysqlType.TINYTEXT, + MysqlType.TEXT, + MysqlType.MEDIUMTEXT, + MysqlType.LONGTEXT, + MysqlType.ENUM, + MysqlType.SET -> StringFieldType + MysqlType.JSON -> StringFieldType // TODO: replace this with JsonStringFieldType + MysqlType.TINYBLOB, + MysqlType.BLOB, + MysqlType.MEDIUMBLOB, + MysqlType.LONGBLOB, + MysqlType.BINARY, + MysqlType.VARBINARY, + MysqlType.GEOMETRY -> BinaryStreamFieldType + MysqlType.NULL -> NullFieldType + MysqlType.VECTOR, + MysqlType.UNKNOWN, + null -> PokemonFieldType + } + } + + override fun generate(ast: SelectQuerySpec): SelectQuery = + SelectQuery(ast.sql(), ast.select.columns, ast.bindings()) + + fun SelectQuerySpec.sql(): String { + val components: List = listOf(select.sql(), from.sql(), where.sql(), orderBy.sql()) + val sqlWithoutLimit: String = components.filter { it.isNotBlank() }.joinToString(" ") + val rownumClause: String = + when (limit) { + NoLimit -> return sqlWithoutLimit + Limit(0) -> "LIMIT 0" + is Limit -> "LIMIT ?" + } + return "$sqlWithoutLimit $rownumClause" + } + + fun SelectNode.sql(): String = + "SELECT " + + when (this) { + is SelectColumns -> columns.joinToString(", ") { it.sql() } + is SelectColumnMaxValue -> "MAX(${column.sql()})" + } + + fun Field.sql(): String = "`$id`" + + fun FromNode.sql(): String = + when (this) { + NoFrom -> "" + is From -> if (this.namespace == null) "FROM `$name`" else "FROM `$namespace`.`$name`" + is FromSample -> { + val from: String = From(name, namespace).sql() + // On a table that is very big we limit sampling to no less than 0.05% + // chance of a row getting picked. This comes at a price of bias to the beginning + // of table on very large tables ( > 100s million of rows) + val greatestRate: String = 0.00005.toString() + // We only do a full count in case information schema contains no row count. + // This is the case for views. + val fullCount = "SELECT COUNT(*) FROM `$namespace`.`$name`" + // Quick approximation to "select count(*) from table" which doesn't require + // full table scan. However, note this could give delayed summary info about a table + // and thus a new table could be treated as empty despite we recently added rows. + // To prevent that from happening and resulted for skipping the table altogether, + // the minimum count is set to 10. + val quickCount = + "SELECT GREATEST(10, COALESCE(table_rows, ($fullCount))) FROM information_schema.tables WHERE table_schema = '$namespace' AND table_name = '$name'" + val greatest = "GREATEST($greatestRate, $sampleSize / ($quickCount))" + // Rand returns a value between 0 and 1 + val where = "WHERE RAND() < $greatest " + "$from $where" + } + } + + fun WhereNode.sql(): String = + when (this) { + NoWhere -> "" + is Where -> "WHERE ${clause.sql()}" + } + + fun WhereClauseNode.sql(): String = + when (this) { + is And -> conj.joinToString(") AND (", "(", ")") { it.sql() } + is Or -> disj.joinToString(") OR (", "(", ")") { it.sql() } + is Equal -> "${column.sql()} = ?" + is Greater -> "${column.sql()} > ?" + is GreaterOrEqual -> "${column.sql()} >= ?" + is LesserOrEqual -> "${column.sql()} <= ?" + is Lesser -> "${column.sql()} < ?" + } + + fun OrderByNode.sql(): String = + when (this) { + NoOrderBy -> "" + is OrderBy -> "ORDER BY " + columns.joinToString(", ") { it.sql() } + } + + fun SelectQuerySpec.bindings(): List = where.bindings() + limit.bindings() + + fun WhereNode.bindings(): List = + when (this) { + is NoWhere -> listOf() + is Where -> clause.bindings() + } + + fun WhereClauseNode.bindings(): List = + when (this) { + is And -> conj.flatMap { it.bindings() } + is Or -> disj.flatMap { it.bindings() } + is WhereClauseLeafNode -> { + val type = column.type as LosslessJdbcFieldType<*, *> + listOf(SelectQuery.Binding(bindingValue, type)) + } + } + + fun LimitNode.bindings(): List = + when (this) { + NoLimit, + Limit(0) -> listOf() + is Limit -> listOf(SelectQuery.Binding(Jsons.numberNode(n), LongFieldType)) + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceSelectQuerier.kt b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceSelectQuerier.kt new file mode 100644 index 000000000000..c981fb9e5a52 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/main/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceSelectQuerier.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.mysql + +import io.airbyte.cdk.jdbc.JdbcConnectionFactory +import io.airbyte.cdk.read.JdbcSelectQuerier +import io.airbyte.cdk.read.SelectQuerier +import io.airbyte.cdk.read.SelectQuery +import io.micronaut.context.annotation.Primary +import jakarta.inject.Singleton + +/** Mysql implementation of [JdbcSelectQuerier], which sets fetch size differently */ +@Singleton +@Primary +class MySqlSourceSelectQuerier( + jdbcConnectionFactory: JdbcConnectionFactory, +) : SelectQuerier { + + private val wrapped = JdbcSelectQuerier(jdbcConnectionFactory) + + override fun executeQuery( + q: SelectQuery, + parameters: SelectQuerier.Parameters, + ): SelectQuerier.Result { + val mySqlParameters: SelectQuerier.Parameters = + // MySQL requires this fetchSize setting on JDBC Statements to enable adaptive fetching. + // The ResultSet fetchSize value is what's used as an actual hint by the JDBC driver. + parameters.copy(statementFetchSize = Int.MIN_VALUE) + return wrapped.executeQuery(q, mySqlParameters) + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/main/resources/application.yml b/airbyte-integrations/connectors/source-mysql/src/main/resources/application.yml new file mode 100644 index 000000000000..d6b88c65548d --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/main/resources/application.yml @@ -0,0 +1,123 @@ +--- +airbyte: + connector: + extract: + jdbc: + mode: sequential + with-sampling: true + table-sample-size: 1024 + throughput-bytes-per-second: 10000000 + min-fetch-size: 10 + default-fetch-size: 1024 + max-fetch-size: 1000000000 + memory-capacity-ratio: 0.6 + estimated-record-overhead-bytes: 16 + estimated-field-overhead-bytes: 16 + namespace-kind: CATALOG_AND_SCHEMA + check: + jdbc: + queries: + - >- + SELECT 1 FROM dual WHERE 1 = 0; + + exception-classifiers: + regex: + # The following rules are for the RegexExceptionClassifier [0] which are applied + # sequentially on a Throwable's message [1] and its nested messages by cause [2]. + # + # This classifier's rules are applied ahead of the JdbcExceptionClassifier's further down. + # + # [0] https://github.com/airbytehq/airbyte/blob/master/airbyte-cdk/bulk/core/base/src/main/kotlin/io/airbyte/cdk/output/ExceptionClassifier.kt + # [1] https://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html#getMessage-- + # [2] https://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html#getCause-- + + rules: + ## REGEX RULE TEMPLATE: + # pattern: Required; regex pattern, c.f. https://www.freeformatter.com/java-regex-tester.html. + # Note that regex patterns are not case-sensitive and are multiline. + # input-example: Required, string matching regex pattern. + # error: Required, one of (transient|config|system). + # group: Optional, string prefixing user-facing error message. + # output: Optional, user-facing error message; when not set, the exception message is used instead. + # reference-links: Optional, list of URLs appended to user-facing message after a newline. + + - pattern: (?i).*can not read response from server\. expected to read ([1-9]\d*) bytes.* + input-example: >- + java.io.EOFException: Can not read response from server. + Expected to read 10 bytes, read 5 bytes before connection was unexpectedly lost. + error: transient + group: MySQL EOF Exception + output: Can not read data from MySQL server, will retry. + reference-links: -https://docs.oracle.com/javase/8/docs/api/index.html?java/io/EOFException.html + + - pattern: (?i).*connection is not available, request timed out after.* + input-example: >- + java.sql.SQLTransientConnectionException: HikariPool-x - + Connection is not available, request timed out after 10 ms + error: transient + group: MySQL Hikari Connection Error + output: Database read failed due to connection timeout, will retry. + reference-links: -https://docs.oracle.com/javase/9/docs/api/java/sql/SQLTransientConnectionException.html + + - pattern: (?i).*is unrecognized or represents more than one time zone.* + input-example: >- + java.sql.SQLException: The server time zone value 'PDT' is unrecognized or represents more than one time zone. + You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value + if you want to utilize time zone support. + error: config + group: MySQL Timezone Error + output: >- + Please configure your database with the correct timezone found in the detailed error message. + Please refer to the following documentation: https://dev.mysql.com/doc/refman/8.4/en/time-zone-support.html + reference-links: -https://docs.oracle.com/javase/8/docs/api/index.html?java/io/SQLException.html + + - pattern: (?i).*exception occurred in the change event produce.* + input-example: >- + java.lang.RuntimeException: org.apache.kafka.connect.errors.ConnectException: + An exception occurred in the change event producer. This connector will be stopped. + error: config + group: MySQL Schema Change Error + output: >- + Your connection could not be completed because changes were detected on an unknown table (see detailed error for the table name), + please refresh your schema or reset the connection. + reference-links: -https://kafka.apache.org/11/javadoc/org/apache/kafka/connect/errors/ConnectException.html + + - pattern: | + (?i).*vttablet: rpc error: code = Unavailable desc = error reading from server: EOF.* + input-example: >- + java.lang.RuntimeException: java.lang.RuntimeException: java.sql.SQLException: target: ai-solutions.-.primary: + vttablet: rpc error: code = Unavailable desc = error reading from server: EOF + error: transient + group: MySQL Vitess Connection Error + output: Database read failed due to connection timeout, will retry. + reference-links: -https://docs.oracle.com/javase/8/docs/api/index.html?java/sql/SQLException.html + + jdbc: + # The following rules are for the JdbcExceptionClassifier [0] which are applied on a + # MySQL's error code [1]. The vendor error code is printed in the exception + # message, and is not to be confused with the SQLState [2] which is also in the message. + # + # [0] https://github.com/airbytehq/airbyte/blob/master/airbyte-cdk/bulk/toolkits/extract-jdbc/src/main/kotlin/io/airbyte/cdk/output/JdbcExceptionClassifier.kt + # [1] https://dev.mysql.com/doc/mysql-errors/5.7/en/server-error-reference.html + # [2] https://en.wikipedia.org/wiki/SQLSTATE + # + rules: + ## JDBC RULE TEMPLATE + # code: Required, MySQL vendor error code. + # error: Required, one of (transient|config|system). + # output: Optional, user-facing error message; the exception message is used instead when this is not defined. + # reference-links: Optional, list of URLs appended to user-facing message after newline. + + - code: 1054 + error: config + output: >- + A required column for the MySQL source connector is missing in the database. + Please review your SQL statement to ensure it referencing existing columns. + group: MySQL Syntax Exception + reference-links: https://dev.mysql.com/doc/mysql-errors/9.1/en/server-error-reference.html#error_er_bad_field_error + + - code: 3024 + error: transient + output: The query took too long to return results, the database read was aborted. Will retry. + group: MySQL Limit Reached + reference-links: https://dev.mysql.com/doc/mysql-errors/5.7/en/server-error-reference.html#error_er_query_timeout diff --git a/airbyte-integrations/connectors/source-mysql/src/main/resources/internal_models/internal_models.yaml b/airbyte-integrations/connectors/source-mysql/src/main/resources/internal_models/internal_models.yaml deleted file mode 100644 index d7c998e4c714..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/resources/internal_models/internal_models.yaml +++ /dev/null @@ -1,48 +0,0 @@ ---- -"$schema": http://json-schema.org/draft-07/schema# -title: MySQL Models -type: object -description: MySQL Models -properties: - state_type: - "$ref": "#/definitions/StateType" - primary_key_state: - "$ref": "#/definitions/PrimaryKeyLoadStatus" - cursor_based_state: - "$ref": "#/definitions/CursorBasedStatus" -definitions: - StateType: - description: Enum to define the sync mode of state. - type: string - enum: - - cursor_based - - primary_key - CursorBasedStatus: - type: object - extends: - type: object - existingJavaType: "io.airbyte.cdk.integrations.source.relationaldb.models.DbStreamState" - properties: - state_type: - "$ref": "#/definitions/StateType" - version: - description: Version of state. - type: integer - PrimaryKeyLoadStatus: - type: object - properties: - version: - description: Version of state. - type: integer - state_type: - "$ref": "#/definitions/StateType" - pk_name: - description: primary key name - type: string - pk_val: - description: primary key watermark - type: string - incremental_state: - description: State to switch to after completion of primary key initial sync - type: object - existingJavaType: com.fasterxml.jackson.databind.JsonNode diff --git a/airbyte-integrations/connectors/source-mysql/src/main/resources/spec.json b/airbyte-integrations/connectors/source-mysql/src/main/resources/spec.json deleted file mode 100644 index 5a9304326cdd..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/main/resources/spec.json +++ /dev/null @@ -1,252 +0,0 @@ -{ - "documentationUrl": "https://docs.airbyte.com/integrations/sources/mysql", - "connectionSpecification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MySql Source Spec", - "type": "object", - "required": ["host", "port", "database", "username", "replication_method"], - "properties": { - "host": { - "description": "The host name of the database.", - "title": "Host", - "type": "string", - "order": 0 - }, - "port": { - "description": "The port to connect to.", - "title": "Port", - "type": "integer", - "minimum": 0, - "maximum": 65536, - "default": 3306, - "examples": ["3306"], - "order": 1 - }, - "database": { - "description": "The database name.", - "title": "Database", - "type": "string", - "order": 2 - }, - "username": { - "description": "The username which is used to access the database.", - "title": "Username", - "type": "string", - "order": 3 - }, - "password": { - "description": "The password associated with the username.", - "title": "Password", - "type": "string", - "airbyte_secret": true, - "order": 4, - "always_show": true - }, - "jdbc_url_params": { - "description": "Additional properties to pass to the JDBC URL string when connecting to the database formatted as 'key=value' pairs separated by the symbol '&'. (example: key1=value1&key2=value2&key3=value3). For more information read about JDBC URL parameters.", - "title": "JDBC URL Parameters (Advanced)", - "type": "string", - "order": 5 - }, - "ssl": { - "title": "SSL Connection", - "description": "Encrypt data using SSL.", - "type": "boolean", - "default": true, - "order": 6 - }, - "ssl_mode": { - "title": "SSL modes", - "description": "SSL connection modes. Read more in the docs.", - "type": "object", - "order": 7, - "oneOf": [ - { - "title": "preferred", - "description": "Automatically attempt SSL connection. If the MySQL server does not support SSL, continue with a regular connection.", - "required": ["mode"], - "properties": { - "mode": { - "type": "string", - "const": "preferred", - "order": 0 - } - } - }, - { - "title": "required", - "description": "Always connect with SSL. If the MySQL server doesn’t support SSL, the connection will not be established. Certificate Authority (CA) and Hostname are not verified.", - "required": ["mode"], - "properties": { - "mode": { - "type": "string", - "const": "required", - "order": 0 - } - } - }, - { - "title": "Verify CA", - "description": "Always connect with SSL. Verifies CA, but allows connection even if Hostname does not match.", - "required": ["mode", "ca_certificate"], - "properties": { - "mode": { - "type": "string", - "const": "verify_ca", - "order": 0 - }, - "ca_certificate": { - "type": "string", - "title": "CA certificate", - "description": "CA certificate", - "airbyte_secret": true, - "multiline": true, - "order": 1 - }, - "client_certificate": { - "type": "string", - "title": "Client certificate", - "description": "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", - "airbyte_secret": true, - "multiline": true, - "order": 2, - "always_show": true - }, - "client_key": { - "type": "string", - "title": "Client key", - "description": "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", - "airbyte_secret": true, - "multiline": true, - "order": 3, - "always_show": true - }, - "client_key_password": { - "type": "string", - "title": "Client key password", - "description": "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", - "airbyte_secret": true, - "order": 4 - } - } - }, - { - "title": "Verify Identity", - "description": "Always connect with SSL. Verify both CA and Hostname.", - "required": ["mode", "ca_certificate"], - "properties": { - "mode": { - "type": "string", - "const": "verify_identity", - "order": 0 - }, - "ca_certificate": { - "type": "string", - "title": "CA certificate", - "description": "CA certificate", - "airbyte_secret": true, - "multiline": true, - "order": 1 - }, - "client_certificate": { - "type": "string", - "title": "Client certificate", - "description": "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", - "airbyte_secret": true, - "multiline": true, - "order": 2, - "always_show": true - }, - "client_key": { - "type": "string", - "title": "Client key", - "description": "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", - "airbyte_secret": true, - "multiline": true, - "order": 3, - "always_show": true - }, - "client_key_password": { - "type": "string", - "title": "Client key password", - "description": "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", - "airbyte_secret": true, - "order": 4 - } - } - } - ] - }, - "replication_method": { - "type": "object", - "title": "Update Method", - "description": "Configures how data is extracted from the database.", - "order": 8, - "default": "CDC", - "display_type": "radio", - "oneOf": [ - { - "title": "Read Changes using Binary Log (CDC)", - "description": "Recommended - Incrementally reads new inserts, updates, and deletes using the MySQL binary log. This must be enabled on your database.", - "required": ["method"], - "properties": { - "method": { - "type": "string", - "const": "CDC", - "order": 0 - }, - "initial_waiting_seconds": { - "type": "integer", - "title": "Initial Waiting Time in Seconds (Advanced)", - "description": "The amount of time the connector will wait when it launches to determine if there is new data to sync or not. Defaults to 300 seconds. Valid range: 120 seconds to 1200 seconds. Read about initial waiting time.", - "default": 300, - "min": 120, - "max": 1200, - "order": 1, - "always_show": true - }, - "server_time_zone": { - "type": "string", - "title": "Configured server timezone for the MySQL source (Advanced)", - "description": "Enter the configured MySQL server timezone. This should only be done if the configured timezone in your MySQL instance does not conform to IANNA standard.", - "order": 2, - "always_show": true - }, - "invalid_cdc_cursor_position_behavior": { - "type": "string", - "title": "Invalid CDC position behavior (Advanced)", - "description": "Determines whether Airbyte should fail or re-sync data in case of an stale/invalid cursor value into the WAL. If 'Fail sync' is chosen, a user will have to manually reset the connection before being able to continue syncing data. If 'Re-sync data' is chosen, Airbyte will automatically trigger a refresh but could lead to higher cloud costs and data loss.", - "enum": ["Fail sync", "Re-sync data"], - "default": "Fail sync", - "order": 3, - "always_show": true - }, - "initial_load_timeout_hours": { - "type": "integer", - "title": "Initial Load Timeout in Hours (Advanced)", - "description": "The amount of time an initial load is allowed to continue for before catching up on CDC logs.", - "default": 8, - "min": 4, - "max": 24, - "order": 4, - "always_show": true - } - } - }, - { - "title": "Scan Changes with User Defined Cursor", - "description": "Incrementally detects new inserts and updates using the cursor column chosen when configuring a connection (e.g. created_at, updated_at).", - "required": ["method"], - "properties": { - "method": { - "type": "string", - "const": "STANDARD", - "order": 0 - } - } - } - ] - } - } - } -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/AbstractMySqlSourceDatatypeTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/AbstractMySqlSourceDatatypeTest.java deleted file mode 100644 index 8eb622e72716..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/AbstractMySqlSourceDatatypeTest.java +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import com.mysql.cj.MysqlType; -import io.airbyte.cdk.integrations.standardtest.source.AbstractSourceDatabaseTypeTest; -import io.airbyte.cdk.integrations.standardtest.source.TestDataHolder; -import io.airbyte.cdk.integrations.standardtest.source.TestDestinationEnv; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase; -import io.airbyte.protocol.models.JsonSchemaType; -import java.io.File; -import java.io.IOException; -import java.util.Base64; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.RandomStringUtils; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class AbstractMySqlSourceDatatypeTest extends AbstractSourceDatabaseTypeTest { - - protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractMySqlSourceDatatypeTest.class); - - protected MySQLTestDatabase testdb; - - @Override - protected String getNameSpace() { - return testdb.getDatabaseName(); - } - - @Override - protected void tearDown(final TestDestinationEnv testEnv) { - testdb.close(); - } - - @Override - protected String getImageName() { - return "airbyte/source-mysql:dev"; - } - - @Override - protected void initTests() { - // bit defaults to bit(1), which is equivalent to boolean - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("bit") - .airbyteType(JsonSchemaType.BOOLEAN) - .addInsertValues("null", "1", "0") - .addExpectedValues(null, "true", "false") - .build()); - - // bit(1) is equivalent to boolean - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("bit") - .fullSourceDataType("bit(1)") - .airbyteType(JsonSchemaType.BOOLEAN) - .addInsertValues("null", "1", "0") - .addExpectedValues(null, "true", "false") - .build()); - - // bit(>1) is binary - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("bit") - .fullSourceDataType("bit(7)") - .airbyteType(JsonSchemaType.STRING_BASE_64) - // 1000001 is binary for A - .addInsertValues("null", "b'1000001'") - // QQo= is base64 encoding in charset UTF-8 for A - .addExpectedValues(null, "QQ==") - .build()); - - // tinyint without width - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("tinyint") - .airbyteType(JsonSchemaType.INTEGER) - .addInsertValues("null", "-128", "127") - .addExpectedValues(null, "-128", "127") - .build()); - - // tinyint(1) is equivalent to boolean - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("tinyint") - .fullSourceDataType("tinyint(1)") - .airbyteType(JsonSchemaType.BOOLEAN) - .addInsertValues("null", "1", "0") - .addExpectedValues(null, "true", "false") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("tinyint") - .fullSourceDataType("tinyint(1) unsigned") - .airbyteType(JsonSchemaType.INTEGER) - .addInsertValues("null", "0", "1", "2", "3") - .addExpectedValues(null, "0", "1", "2", "3") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("tinyint") - .fullSourceDataType("tinyint(2)") - .airbyteType(JsonSchemaType.INTEGER) - .addInsertValues("null", "-128", "127") - .addExpectedValues(null, "-128", "127") - .build()); - - final Set booleanTypes = Set.of("BOOLEAN", "BOOL"); - for (final String booleanType : booleanTypes) { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(booleanType) - .airbyteType(JsonSchemaType.BOOLEAN) - // MySql booleans are tinyint(1), and only 1 is true - .addInsertValues("null", "1", "0") - .addExpectedValues(null, "true", "false") - .build()); - } - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("smallint") - .airbyteType(JsonSchemaType.INTEGER) - .addInsertValues("null", "-32768", "32767") - .addExpectedValues(null, "-32768", "32767") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("smallint") - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("smallint zerofill") - .addInsertValues("1") - .addExpectedValues("1") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("smallint") - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("smallint unsigned") - .addInsertValues("null", "0", "65535") - .addExpectedValues(null, "0", "65535") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("mediumint") - .airbyteType(JsonSchemaType.INTEGER) - .addInsertValues("null", "-8388608", "8388607") - .addExpectedValues(null, "-8388608", "8388607") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("mediumint") - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("mediumint zerofill") - .addInsertValues("1") - .addExpectedValues("1") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("int") - .airbyteType(JsonSchemaType.INTEGER) - .addInsertValues("null", "-2147483648", "2147483647") - .addExpectedValues(null, "-2147483648", "2147483647") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("int") - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("int unsigned") - .addInsertValues("3428724653") - .addExpectedValues("3428724653") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("int") - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("int zerofill") - .addInsertValues("1") - .addExpectedValues("1") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("bigint") - .airbyteType(JsonSchemaType.INTEGER) - .addInsertValues("null", "9223372036854775807") - .addExpectedValues(null, "9223372036854775807") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("float") - .airbyteType(JsonSchemaType.NUMBER) - .addInsertValues("null", "10.5") - .addExpectedValues(null, "10.5") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("double") - .airbyteType(JsonSchemaType.NUMBER) - .addInsertValues("null", "power(10, 308)", "1/power(10, 45)", "10.5") - .addExpectedValues(null, String.valueOf(Math.pow(10, 308)), String.valueOf(1 / Math.pow(10, 45)), "10.5") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("decimal") - .airbyteType(JsonSchemaType.NUMBER) - .fullSourceDataType("decimal(10,3)") - .addInsertValues("0.188", "null") - .addExpectedValues("0.188", null) - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("decimal") - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("decimal(32,0)") - .addInsertValues("1700000.01", "123") - .addExpectedValues("1700000", "123") - .build()); - - for (final String type : Set.of("date", "date not null default '0000-00-00'")) { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("date") - .fullSourceDataType(type) - .airbyteType(JsonSchemaType.STRING_DATE) - .addInsertValues("'1999-01-08'", "'2021-01-01'", "'2022/11/12'", "'1987.12.01'") - .addExpectedValues("1999-01-08", "2021-01-01", "2022-11-12", "1987-12-01") - .build()); - } - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("date") - .airbyteType(JsonSchemaType.STRING_DATE) - .addInsertValues("null") - .addExpectedValues((String) null) - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("date") - .airbyteType(JsonSchemaType.STRING_DATE) - .addInsertValues("0000-00-00") - .addExpectedValues((String) null) - .build()); - - for (final String fullSourceType : Set.of("datetime", "datetime not null default now()")) { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("datetime") - .fullSourceDataType(fullSourceType) - .airbyteType(JsonSchemaType.STRING_TIMESTAMP_WITHOUT_TIMEZONE) - .addInsertValues("'2005-10-10 23:22:21'", "'2013-09-05T10:10:02'", "'2013-09-06T10:10:02'") - .addExpectedValues("2005-10-10T23:22:21", "2013-09-05T10:10:02", "2013-09-06T10:10:02") - .build()); - } - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("datetime") - .airbyteType(JsonSchemaType.STRING_TIMESTAMP_WITHOUT_TIMEZONE) - .addInsertValues("null") - .addExpectedValues((String) null) - .build()); - - addTimestampDataTypeTest(); - - for (final String fullSourceType : Set.of("time", "time not null default '00:00:00'")) { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("time") - .fullSourceDataType(fullSourceType) - .airbyteType(JsonSchemaType.STRING_TIME_WITHOUT_TIMEZONE) - // JDBC driver can process only "clock"(00:00:00-23:59:59) values. - .addInsertValues("'-22:59:59'", "'23:59:59'", "'00:00:00'") - .addExpectedValues("22:59:59", "23:59:59", "00:00:00.000000") - .build()); - - } - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("time") - .airbyteType(JsonSchemaType.STRING_TIME_WITHOUT_TIMEZONE) - // JDBC driver can process only "clock"(00:00:00-23:59:59) values. - .addInsertValues("null") - .addExpectedValues((String) null) - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("year") - .airbyteType(JsonSchemaType.INTEGER) - // MySQL converts values in the ranges '0' - '69' to YEAR value in the range 2000 - 2069 - // and '70' - '99' to 1970 - 1999. - .addInsertValues("null", "'1997'", "'0'", "'50'", "'70'", "'80'", "'99'", "'00'", "'000'") - .addExpectedValues(null, "1997", "2000", "2050", "1970", "1980", "1999", "2000", "2000") - .build()); - - // char types can be string or binary, so they are tested separately - final Set charTypes = Stream.of(MysqlType.CHAR, MysqlType.VARCHAR) - .map(Enum::name) - .collect(Collectors.toSet()); - for (final String charType : charTypes) { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(charType) - .airbyteType(JsonSchemaType.STRING) - .fullSourceDataType(charType + "(63)") - .addInsertValues("null", "'Airbyte'", "'!\"#$%&\\'()*+,-./:;<=>?\\@[\\]^_\\`{|}~'") - .addExpectedValues(null, "Airbyte", "!\"#$%&'()*+,-./:;<=>?@[]^_`{|}~") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(charType) - .airbyteType(JsonSchemaType.STRING) - .fullSourceDataType(charType + "(63) character set utf16") - .addInsertValues("0xfffd") - .addExpectedValues("�") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(charType) - .airbyteType(JsonSchemaType.STRING) - .fullSourceDataType(charType + "(63) character set cp1251") - .addInsertValues("'тест'") - .addExpectedValues("тест") - .build()); - - // when charset is binary, return binary in base64 encoding in charset UTF-8 - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(charType) - .airbyteType(JsonSchemaType.STRING_BASE_64) - .fullSourceDataType(charType + "(7) character set binary") - .addInsertValues("null", "'Airbyte'") - .addExpectedValues(null, "QWlyYnl0ZQ==") - .build()); - } - - final Set blobTypes = Stream - .of(MysqlType.TINYBLOB, MysqlType.BLOB, MysqlType.MEDIUMBLOB, MysqlType.LONGBLOB) - .map(Enum::name) - .collect(Collectors.toSet()); - for (final String blobType : blobTypes) { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(blobType) - .airbyteType(JsonSchemaType.STRING_BASE_64) - .addInsertValues("null", "'Airbyte'") - .addExpectedValues(null, "QWlyYnl0ZQ==") - .build()); - } - - // binary appends '\0' to the end of the string - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(MysqlType.BINARY.name()) - .fullSourceDataType(MysqlType.BINARY.name() + "(10)") - .airbyteType(JsonSchemaType.STRING_BASE_64) - .addInsertValues("null", "'Airbyte'") - .addExpectedValues(null, "QWlyYnl0ZQAAAA==") - .build()); - - // varbinary does not append '\0' to the end of the string - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(MysqlType.VARBINARY.name()) - .fullSourceDataType(MysqlType.VARBINARY.name() + "(10)") - .airbyteType(JsonSchemaType.STRING_BASE_64) - .addInsertValues("null", "'Airbyte'") - .addExpectedValues(null, "QWlyYnl0ZQ==") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(MysqlType.VARBINARY.name()) - .airbyteType(JsonSchemaType.STRING_BASE_64) - .fullSourceDataType(MysqlType.VARBINARY.name() + "(20000)") // size should be enough to save test.png - .addInsertValues("null", "'test'", "'тест'", String.format("FROM_BASE64('%s')", getFileDataInBase64())) - .addExpectedValues(null, "dGVzdA==", "0YLQtdGB0YI=", getFileDataInBase64()) - .build()); - - final Set textTypes = Stream - .of(MysqlType.TINYTEXT, MysqlType.TEXT, MysqlType.MEDIUMTEXT, MysqlType.LONGTEXT) - .map(Enum::name) - .collect(Collectors.toSet()); - final String randomText = RandomStringUtils.random(50, true, true); - for (final String textType : textTypes) { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(textType) - .airbyteType(JsonSchemaType.STRING) - .addInsertValues("null", "'Airbyte'", String.format("'%s'", randomText)) - .addExpectedValues(null, "Airbyte", randomText) - .build()); - } - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("mediumtext") - .airbyteType(JsonSchemaType.STRING) - .addInsertValues(getLogString(1048000), "'test'") - .addExpectedValues(StringUtils.leftPad("0", 1048000, "0"), "test") - .build()); - - addJsonDataTypeTest(); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("enum") - .fullSourceDataType("ENUM('xs', 's', 'm', 'l', 'xl')") - .airbyteType(JsonSchemaType.STRING) - .addInsertValues("null", "'xs'", "'m'") - .addExpectedValues(null, "xs", "m") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("set") - .fullSourceDataType("SET('xs', 's', 'm', 'l', 'xl')") - .airbyteType(JsonSchemaType.STRING) - .addInsertValues("null", "'xs,s'", "'m,xl'") - .addExpectedValues(null, "xs,s", "m,xl") - .build()); - - addDecimalValuesTest(); - } - - protected void addJsonDataTypeTest() { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("json") - .airbyteType(JsonSchemaType.STRING) - .addInsertValues("null", "'{\"a\": 10, \"b\": 15}'", "'{\"fóo\": \"bär\"}'", "'{\"春江潮水连海平\": \"海上明月共潮生\"}'") - .addExpectedValues(null, "{\"a\": 10, \"b\": 15}", "{\"fóo\": \"bär\"}", "{\"春江潮水连海平\": \"海上明月共潮生\"}") - .build()); - } - - protected void addTimestampDataTypeTest() { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("timestamp") - .airbyteType(JsonSchemaType.STRING_TIMESTAMP_WITH_TIMEZONE) - .addInsertValues("null", "'2021-01-00'", "'2021-00-00'", "'0000-00-00'", "'2022-08-09T10:17:16.161342Z'") - .addExpectedValues(null, null, null, null, "2022-08-09T10:17:16.000000Z") - .build()); - } - - private String getLogString(final int length) { - final int maxLpadLength = 262144; - final StringBuilder stringBuilder = new StringBuilder("concat("); - final int fullChunks = length / maxLpadLength; - stringBuilder.append("lpad('0', 262144, '0'),".repeat(fullChunks)); - stringBuilder.append("lpad('0', ").append(length % maxLpadLength).append(", '0'))"); - return stringBuilder.toString(); - } - - private String getFileDataInBase64() { - final File file = new File(getClass().getClassLoader().getResource("test.png").getFile()); - try { - return Base64.getEncoder().encodeToString(FileUtils.readFileToByteArray(file)); - } catch (final IOException e) { - LOGGER.error(String.format("Fail to read the file: %s. Error: %s", file.getAbsoluteFile(), e.getMessage())); - } - return null; - } - - protected void addDecimalValuesTest() { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("decimal") - .airbyteType(JsonSchemaType.NUMBER) - .fullSourceDataType("decimal(19,2)") - .addInsertValues("1700000.01", "'123'") - .addExpectedValues("1700000.01", "123.0") - .build()); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/AbstractSshMySqlSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/AbstractSshMySqlSourceAcceptanceTest.java deleted file mode 100644 index 765495b85469..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/AbstractSshMySqlSourceAcceptanceTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.collect.Lists; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.cdk.integrations.base.ssh.SshHelpers; -import io.airbyte.cdk.integrations.standardtest.source.SourceAcceptanceTest; -import io.airbyte.cdk.integrations.standardtest.source.TestDestinationEnv; -import io.airbyte.commons.io.IOs; -import io.airbyte.commons.json.Jsons; -import io.airbyte.protocol.models.Field; -import io.airbyte.protocol.models.JsonSchemaType; -import io.airbyte.protocol.models.v0.CatalogHelpers; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; -import io.airbyte.protocol.models.v0.ConnectorSpecification; -import io.airbyte.protocol.models.v0.DestinationSyncMode; -import io.airbyte.protocol.models.v0.SyncMode; -import java.nio.file.Path; -import java.util.HashMap; - -public abstract class AbstractSshMySqlSourceAcceptanceTest extends SourceAcceptanceTest { - - private static final String STREAM_NAME = "id_and_name"; - private static final String STREAM_NAME2 = "starships"; - - private JsonNode config; - - public abstract Path getConfigFilePath(); - - @Override - protected void setupEnvironment(final TestDestinationEnv environment) { - config = Jsons.deserialize(IOs.readFile(getConfigFilePath())); - } - - @Override - protected void tearDown(final TestDestinationEnv testEnv) {} - - @Override - protected String getImageName() { - return "airbyte/source-mysql:dev"; - } - - @Override - protected ConnectorSpecification getSpec() throws Exception { - return SshHelpers.getSpecAndInjectSsh(); - } - - @Override - protected JsonNode getConfig() { - return config; - } - - @Override - protected ConfiguredAirbyteCatalog getConfiguredCatalog() { - return new ConfiguredAirbyteCatalog().withStreams(Lists.newArrayList( - new ConfiguredAirbyteStream() - .withSyncMode(SyncMode.INCREMENTAL) - .withCursorField(Lists.newArrayList("id")) - .withDestinationSyncMode(DestinationSyncMode.APPEND) - .withStream(CatalogHelpers.createAirbyteStream( - String.format("%s", STREAM_NAME), - Field.of("id", JsonSchemaType.NUMBER), - Field.of("name", JsonSchemaType.STRING)) - .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL))), - new ConfiguredAirbyteStream() - .withSyncMode(SyncMode.INCREMENTAL) - .withCursorField(Lists.newArrayList("id")) - .withDestinationSyncMode(DestinationSyncMode.APPEND) - .withStream(CatalogHelpers.createAirbyteStream( - String.format("%s", STREAM_NAME2), - config.get(JdbcUtils.DATABASE_KEY).asText(), - Field.of("id", JsonSchemaType.NUMBER), - Field.of("name", JsonSchemaType.STRING)) - .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL))))); - } - - @Override - protected JsonNode getState() { - return Jsons.jsonNode(new HashMap<>()); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CDCMySqlDatatypeAccuracyTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CDCMySqlDatatypeAccuracyTest.java deleted file mode 100644 index 9400c4e66368..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CDCMySqlDatatypeAccuracyTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import com.fasterxml.jackson.databind.JsonNode; -import io.airbyte.cdk.db.Database; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.BaseImage; -import org.junit.jupiter.api.Test; - -public class CDCMySqlDatatypeAccuracyTest extends MySqlDatatypeAccuracyTest { - - @Override - protected JsonNode getConfig() { - return testdb.integrationTestConfigBuilder() - .withoutSsl() - .withCdcReplication() - .with("snapshot_mode", "initial_only") - .build(); - } - - @Override - protected Database setupDatabase() { - testdb = MySQLTestDatabase.in(BaseImage.MYSQL_8).withoutStrictMode().withCdcPermissions(); - return testdb.getDatabase(); - } - - // Temporarily disable this test since it's causing trouble on GHA. - @Override - @Test - public void testDataContent() { - // Do Nothing - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CdcBinlogsMySqlSourceDatatypeTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CdcBinlogsMySqlSourceDatatypeTest.java deleted file mode 100644 index 82ab112d7e15..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CdcBinlogsMySqlSourceDatatypeTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.collect.Iterables; -import io.airbyte.cdk.db.Database; -import io.airbyte.cdk.integrations.standardtest.source.TestDataHolder; -import io.airbyte.commons.json.Jsons; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.BaseImage; -import io.airbyte.protocol.models.JsonSchemaType; -import io.airbyte.protocol.models.v0.AirbyteMessage; -import io.airbyte.protocol.models.v0.AirbyteStateMessage; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; -import java.util.List; - -public class CdcBinlogsMySqlSourceDatatypeTest extends AbstractMySqlSourceDatatypeTest { - - private JsonNode stateAfterFirstSync; - - @Override - protected JsonNode getConfig() { - return testdb.integrationTestConfigBuilder() - .withoutSsl() - .withCdcReplication() - .build(); - } - - @Override - protected Database setupDatabase() { - testdb = MySQLTestDatabase.in(BaseImage.MYSQL_8).withoutStrictMode().withCdcPermissions(); - return testdb.getDatabase(); - } - - @Override - protected List runRead(final ConfiguredAirbyteCatalog configuredCatalog) throws Exception { - if (stateAfterFirstSync == null) { - throw new RuntimeException("stateAfterFirstSync is null"); - } - return super.runRead(configuredCatalog, stateAfterFirstSync); - } - - @Override - protected void postSetup() throws Exception { - final var database = testdb.getDatabase(); - for (final TestDataHolder test : testDataHolders) { - database.query(ctx -> { - ctx.execute("TRUNCATE TABLE " + test.getNameWithTestPrefix() + ";"); - return null; - }); - } - - final ConfiguredAirbyteStream dummyTableWithData = createDummyTableWithData(database); - final ConfiguredAirbyteCatalog catalog = getConfiguredCatalog(); - catalog.getStreams().add(dummyTableWithData); - - final List allMessages = super.runRead(catalog); - final List stateAfterFirstBatch = extractStateMessages(allMessages); - stateAfterFirstSync = Jsons.jsonNode(List.of(Iterables.getLast(stateAfterFirstBatch))); - if (stateAfterFirstSync == null) { - throw new RuntimeException("stateAfterFirstSync should not be null"); - } - for (final TestDataHolder test : testDataHolders) { - database.query(ctx -> { - test.getInsertSqlQueries().forEach(ctx::fetch); - return null; - }); - } - } - - @Override - public boolean testCatalog() { - return true; - } - - @Override - protected void addTimestampDataTypeTest() { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("timestamp") - .airbyteType(JsonSchemaType.STRING_TIMESTAMP_WITH_TIMEZONE) - .addInsertValues("null", "'2021-01-00'", "'2021-00-00'", "'0000-00-00'", "'2022-08-09T10:17:16.161342Z'") - .addExpectedValues(null, "1970-01-01T00:00:00.000000Z", "1970-01-01T00:00:00.000000Z", "1970-01-01T00:00:00.000000Z", - "2022-08-09T10:17:16.000000Z") - .build()); - } - - @Override - protected void addJsonDataTypeTest() { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("json") - .airbyteType(JsonSchemaType.STRING) - .addInsertValues("null", "'{\"a\":10,\"b\":15}'", "'{\"fóo\":\"bär\"}'", "'{\"春江潮水连海平\":\"海上明月共潮生\"}'") - .addExpectedValues(null, "{\"a\":10,\"b\":15}", "{\"fóo\":\"bär\"}", "{\"春江潮水连海平\":\"海上明月共潮生\"}") - .build()); - } - - @Override - protected void addDecimalValuesTest() { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType("decimal") - .airbyteType(JsonSchemaType.NUMBER) - .fullSourceDataType("decimal(19,2)") - .addInsertValues("1700000.01", "'123'") - .addExpectedValues("1700000.01", "123.00") - .build()); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CdcInitialSnapshotMySqlSourceDatatypeTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CdcInitialSnapshotMySqlSourceDatatypeTest.java deleted file mode 100644 index 6b971c86927c..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CdcInitialSnapshotMySqlSourceDatatypeTest.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import com.fasterxml.jackson.databind.JsonNode; -import io.airbyte.cdk.db.Database; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.BaseImage; - -public class CdcInitialSnapshotMySqlSourceDatatypeTest extends AbstractMySqlSourceDatatypeTest { - - @Override - protected JsonNode getConfig() { - return testdb.integrationTestConfigBuilder() - .withoutSsl() - .withCdcReplication() - .with("snapshot_mode", "initial_only") - .build(); - } - - @Override - protected Database setupDatabase() { - testdb = MySQLTestDatabase.in(BaseImage.MYSQL_8).withoutStrictMode().withCdcPermissions(); - return testdb.getDatabase(); - } - - @Override - public boolean testCatalog() { - return true; - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CdcMySqlSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CdcMySqlSourceAcceptanceTest.java deleted file mode 100644 index 8286c3087991..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CdcMySqlSourceAcceptanceTest.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import static io.airbyte.protocol.models.v0.SyncMode.FULL_REFRESH; -import static io.airbyte.protocol.models.v0.SyncMode.INCREMENTAL; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import io.airbyte.cdk.integrations.base.ssh.SshHelpers; -import io.airbyte.cdk.integrations.standardtest.source.SourceAcceptanceTest; -import io.airbyte.cdk.integrations.standardtest.source.TestDestinationEnv; -import io.airbyte.commons.json.Jsons; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.BaseImage; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.ContainerModifier; -import io.airbyte.protocol.models.Field; -import io.airbyte.protocol.models.JsonSchemaType; -import io.airbyte.protocol.models.v0.AirbyteMessage; -import io.airbyte.protocol.models.v0.AirbyteRecordMessage; -import io.airbyte.protocol.models.v0.AirbyteStateMessage; -import io.airbyte.protocol.models.v0.CatalogHelpers; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; -import io.airbyte.protocol.models.v0.ConnectorSpecification; -import io.airbyte.protocol.models.v0.DestinationSyncMode; -import io.airbyte.protocol.models.v0.SyncMode; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; -import org.apache.commons.lang3.ArrayUtils; -import org.junit.Assert; -import org.junit.jupiter.api.Test; - -public class CdcMySqlSourceAcceptanceTest extends SourceAcceptanceTest { - - protected static final String STREAM_NAME = "id_and_name"; - protected static final String STREAM_NAME2 = "starships"; - protected static final String STREAM_NAME3 = "stream3"; - - protected MySQLTestDatabase testdb; - - @Override - protected String getImageName() { - return "airbyte/source-mysql:dev"; - } - - @Override - protected ConnectorSpecification getSpec() throws Exception { - return SshHelpers.getSpecAndInjectSsh(); - } - - @Override - protected JsonNode getConfig() { - return testdb.integrationTestConfigBuilder() - .withCdcReplication() - .withoutSsl() - .build(); - } - - @Override - protected ConfiguredAirbyteCatalog getConfiguredCatalog() { - return new ConfiguredAirbyteCatalog().withStreams(Lists.newArrayList( - new ConfiguredAirbyteStream() - .withSyncMode(INCREMENTAL) - .withDestinationSyncMode(DestinationSyncMode.APPEND) - .withStream(CatalogHelpers.createAirbyteStream( - STREAM_NAME, testdb.getDatabaseName(), - Field.of("id", JsonSchemaType.NUMBER), - Field.of("name", JsonSchemaType.STRING)) - .withSourceDefinedCursor(true) - .withSourceDefinedPrimaryKey(List.of(List.of("id"))) - .withSupportedSyncModes( - Lists.newArrayList(SyncMode.FULL_REFRESH, INCREMENTAL))), - new ConfiguredAirbyteStream() - .withSyncMode(INCREMENTAL) - .withDestinationSyncMode(DestinationSyncMode.APPEND) - .withStream(CatalogHelpers.createAirbyteStream( - STREAM_NAME2, testdb.getDatabaseName(), - Field.of("id", JsonSchemaType.NUMBER), - Field.of("name", JsonSchemaType.STRING)) - .withSourceDefinedCursor(true) - .withSourceDefinedPrimaryKey(List.of(List.of("id"))) - .withSupportedSyncModes( - Lists.newArrayList(SyncMode.FULL_REFRESH, INCREMENTAL))))); - } - - @Override - protected JsonNode getState() { - return null; - } - - @Override - protected void setupEnvironment(final TestDestinationEnv environment) { - testdb = MySQLTestDatabase.in(BaseImage.MYSQL_8, getContainerModifiers()) - .withCdcPermissions() - .with("CREATE TABLE id_and_name(id INTEGER, name VARCHAR(200));") - .with("INSERT INTO id_and_name (id, name) VALUES (1,'picard'), (2, 'crusher'), (3, 'vash');") - .with("CREATE TABLE starships(id INTEGER, name VARCHAR(200));") - .with("INSERT INTO starships (id, name) VALUES (1,'enterprise-d'), (2, 'defiant'), (3, 'yamato');") - .with("CREATE TABLE %s (id INTEGER PRIMARY KEY, name VARCHAR(200), userid INTEGER DEFAULT NULL);", STREAM_NAME3) - .with("INSERT INTO %s (id, name) VALUES (4,'voyager');", STREAM_NAME3); - } - - protected ContainerModifier[] getContainerModifiers() { - return ArrayUtils.toArray(); - } - - @Override - protected void tearDown(final TestDestinationEnv testEnv) { - testdb.close(); - } - - @Test - public void testIncrementalSyncShouldNotFailIfBinlogIsDeleted() throws Exception { - final ConfiguredAirbyteCatalog configuredCatalog = withSourceDefinedCursors(getConfiguredCatalog()); - // only sync incremental streams - configuredCatalog.setStreams( - configuredCatalog.getStreams().stream().filter(s -> s.getSyncMode() == INCREMENTAL).collect(Collectors.toList())); - - final List airbyteMessages = runRead(configuredCatalog, getState()); - final List recordMessages = filterRecords(airbyteMessages); - final List stateMessages = airbyteMessages - .stream() - .filter(m -> m.getType() == AirbyteMessage.Type.STATE) - .map(AirbyteMessage::getState) - .collect(Collectors.toList()); - assertFalse(recordMessages.isEmpty(), "Expected the first incremental sync to produce records"); - assertFalse(stateMessages.isEmpty(), "Expected incremental sync to produce STATE messages"); - - // when we run incremental sync again there should be no new records. Run a sync with the latest - // state message and assert no records were emitted. - final JsonNode latestState = Jsons.jsonNode(List.of(Iterables.getLast(stateMessages))); - // RESET MASTER removes all binary log files that are listed in the index file, - // leaving only a single, empty binary log file with a numeric suffix of .000001 - testdb.with("RESET MASTER;"); - - assertEquals(6, filterRecords(runRead(configuredCatalog, latestState)).size()); - } - - @Test - public void testIncrementalReadSelectedColumns() throws Exception { - final ConfiguredAirbyteCatalog catalog = getConfiguredCatalogWithPartialColumns(); - final List allMessages = runRead(catalog); - - final List records = filterRecords(allMessages); - assertFalse(records.isEmpty(), "Expected a incremental sync to produce records"); - verifyFieldNotExist(records, STREAM_NAME, "name"); - verifyFieldNotExist(records, STREAM_NAME2, "name"); - } - - private ConfiguredAirbyteCatalog getConfiguredCatalogWithPartialColumns() { - // We cannot strip the primary key field as that is required for a successful CDC sync - return new ConfiguredAirbyteCatalog().withStreams(Lists.newArrayList( - new ConfiguredAirbyteStream() - .withSyncMode(INCREMENTAL) - .withDestinationSyncMode(DestinationSyncMode.APPEND) - .withStream(CatalogHelpers.createAirbyteStream( - STREAM_NAME, testdb.getDatabaseName(), - Field.of("id", JsonSchemaType.NUMBER) - /* no name field */) - .withSourceDefinedCursor(true) - .withSourceDefinedPrimaryKey(List.of(List.of("id"))) - .withSupportedSyncModes( - Lists.newArrayList(SyncMode.FULL_REFRESH, INCREMENTAL))), - new ConfiguredAirbyteStream() - .withSyncMode(INCREMENTAL) - .withDestinationSyncMode(DestinationSyncMode.APPEND) - .withStream(CatalogHelpers.createAirbyteStream( - STREAM_NAME2, testdb.getDatabaseName(), - /* no name field */ - Field.of("id", JsonSchemaType.NUMBER)) - .withSourceDefinedCursor(true) - .withSourceDefinedPrimaryKey(List.of(List.of("id"))) - .withSupportedSyncModes( - Lists.newArrayList(SyncMode.FULL_REFRESH, INCREMENTAL))))); - } - - private void verifyFieldNotExist(final List records, final String stream, final String field) { - assertTrue(records.stream().noneMatch(r -> r.getStream().equals(stream) && r.getData().get(field) != null), - "Records contain unselected columns [%s:%s]".formatted(stream, field)); - } - - @Test - protected void testNullValueConversion() throws Exception { - final List configuredAirbyteStreams = - Lists.newArrayList(new ConfiguredAirbyteStream() - .withSyncMode(INCREMENTAL) - .withDestinationSyncMode(DestinationSyncMode.APPEND) - .withStream(CatalogHelpers.createAirbyteStream(STREAM_NAME3, - testdb.getDatabaseName(), - Field.of("id", JsonSchemaType.NUMBER), - Field.of("name", JsonSchemaType.STRING), - Field.of("userid", JsonSchemaType.NUMBER)) - .withSourceDefinedCursor(true) - .withSourceDefinedPrimaryKey(List.of(List.of("id"))) - .withSupportedSyncModes(Lists.newArrayList(FULL_REFRESH, INCREMENTAL)))); - - final ConfiguredAirbyteCatalog configuredCatalogWithOneStream = - new ConfiguredAirbyteCatalog().withStreams(List.of(configuredAirbyteStreams.get(0))); - - final List airbyteMessages = runRead(configuredCatalogWithOneStream, getState()); - final List recordMessages = filterRecords(airbyteMessages); - final List stateMessages = airbyteMessages - .stream() - .filter(m -> m.getType() == AirbyteMessage.Type.STATE) - .map(AirbyteMessage::getState) - .collect(Collectors.toList()); - Assert.assertEquals(recordMessages.size(), 1); - assertFalse(stateMessages.isEmpty(), "Reason"); - ObjectMapper mapper = new ObjectMapper(); - - assertEquals(cdcFieldsOmitted(recordMessages.get(0).getData()), - mapper.readTree("{\"id\":4, \"name\":\"voyager\", \"userid\":null}")); - - // when we run incremental sync again there should be no new records. Run a sync with the latest - // state message and assert no records were emitted. - JsonNode latestState = extractLatestState(stateMessages); - - testdb.getDatabase().query(c -> { - return c.query("INSERT INTO %s.%s (id, name) VALUES (5,'deep space nine');".formatted(testdb.getDatabaseName(), STREAM_NAME3)); - }).execute(); - - assert Objects.nonNull(latestState); - final List secondSyncRecords = filterRecords(runRead(configuredCatalogWithOneStream, latestState)); - assertFalse( - secondSyncRecords.isEmpty(), - "Expected the second incremental sync to produce records."); - assertEquals(cdcFieldsOmitted(secondSyncRecords.get(0).getData()), - mapper.readTree("{\"id\":5, \"name\":\"deep space nine\", \"userid\":null}")); - - } - - private JsonNode cdcFieldsOmitted(final JsonNode node) { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode object = mapper.createObjectNode(); - node.fieldNames().forEachRemaining(name -> { - if (!name.toLowerCase().startsWith("_ab_cdc_")) { - object.put(name, node.get(name)); - } - - }); - return object; - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CdcMySqlSslCaCertificateSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CdcMySqlSslCaCertificateSourceAcceptanceTest.java deleted file mode 100644 index 98ccf8c7f50f..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CdcMySqlSslCaCertificateSourceAcceptanceTest.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.collect.ImmutableMap; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.ContainerModifier; -import org.apache.commons.lang3.ArrayUtils; - -public class CdcMySqlSslCaCertificateSourceAcceptanceTest extends CdcMySqlSourceAcceptanceTest { - - @Override - protected JsonNode getConfig() { - return testdb.integrationTestConfigBuilder() - .withCdcReplication() - .withSsl(ImmutableMap.builder() - .put(JdbcUtils.MODE_KEY, "verify_ca") - .put("ca_certificate", testdb.getCertificates().caCertificate()) - .build()) - .build(); - } - - @Override - protected ContainerModifier[] getContainerModifiers() { - return ArrayUtils.toArray(ContainerModifier.ROOT_AND_SERVER_CERTIFICATES); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CdcMySqlSslRequiredSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CdcMySqlSslRequiredSourceAcceptanceTest.java deleted file mode 100644 index f508513b72d8..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CdcMySqlSslRequiredSourceAcceptanceTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.collect.ImmutableMap; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.cdk.integrations.standardtest.source.TestDestinationEnv; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.ContainerModifier; -import org.apache.commons.lang3.ArrayUtils; - -public class CdcMySqlSslRequiredSourceAcceptanceTest extends CdcMySqlSourceAcceptanceTest { - - @Override - protected JsonNode getConfig() { - return testdb.integrationTestConfigBuilder() - .withCdcReplication() - .withSsl(ImmutableMap.builder().put(JdbcUtils.MODE_KEY, "required").build()) - .build(); - } - - @Override - protected void setupEnvironment(final TestDestinationEnv environment) { - super.setupEnvironment(environment); - testdb.with("ALTER USER %s REQUIRE SSL;", testdb.getUserName()); - } - - @Override - protected ContainerModifier[] getContainerModifiers() { - return ArrayUtils.toArray(ContainerModifier.ROOT_AND_SERVER_CERTIFICATES, ContainerModifier.CLIENT_CERTITICATE); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CloudDeploymentMySqlSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CloudDeploymentMySqlSourceAcceptanceTest.java deleted file mode 100644 index 8b607cc092f8..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CloudDeploymentMySqlSourceAcceptanceTest.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import io.airbyte.cdk.integrations.base.ssh.SshHelpers; -import io.airbyte.commons.features.FeatureFlags; -import io.airbyte.commons.features.FeatureFlagsWrapper; -import io.airbyte.commons.json.Jsons; -import io.airbyte.commons.resources.MoreResources; -import io.airbyte.protocol.models.v0.ConnectorSpecification; - -public class CloudDeploymentMySqlSourceAcceptanceTest extends MySqlSslSourceAcceptanceTest { - - @Override - protected FeatureFlags featureFlags() { - return FeatureFlagsWrapper.overridingDeploymentMode(super.featureFlags(), "CLOUD"); - } - - @Override - protected ConnectorSpecification getSpec() throws Exception { - return SshHelpers.injectSshIntoSpec(Jsons.deserialize(MoreResources.readResource("expected_cloud_spec.json"), ConnectorSpecification.class)); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CloudDeploymentMySqlSslCaCertificateSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CloudDeploymentMySqlSslCaCertificateSourceAcceptanceTest.java deleted file mode 100644 index 15f0b5b5a612..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CloudDeploymentMySqlSslCaCertificateSourceAcceptanceTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.collect.ImmutableMap; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.cdk.integrations.base.ssh.SshHelpers; -import io.airbyte.commons.features.FeatureFlags; -import io.airbyte.commons.features.FeatureFlagsWrapper; -import io.airbyte.commons.json.Jsons; -import io.airbyte.commons.resources.MoreResources; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.ContainerModifier; -import io.airbyte.protocol.models.v0.ConnectorSpecification; -import org.apache.commons.lang3.ArrayUtils; - -public class CloudDeploymentMySqlSslCaCertificateSourceAcceptanceTest extends MySqlSourceAcceptanceTest { - - private static final String PASSWORD = "Passw0rd"; - - @Override - protected FeatureFlags featureFlags() { - return FeatureFlagsWrapper.overridingDeploymentMode(super.featureFlags(), "CLOUD"); - } - - @Override - protected ContainerModifier[] getContainerModifiers() { - return ArrayUtils.toArray(ContainerModifier.ROOT_AND_SERVER_CERTIFICATES); - } - - @Override - protected JsonNode getConfig() { - return testdb.integrationTestConfigBuilder() - .withStandardReplication() - .withSsl(ImmutableMap.builder() - .put(JdbcUtils.MODE_KEY, "verify_ca") - .put("ca_certificate", testdb.getCaCertificate()) - .put("client_key_password", PASSWORD) - .build()) - .build(); - } - - @Override - protected ConnectorSpecification getSpec() throws Exception { - return SshHelpers.injectSshIntoSpec(Jsons.deserialize(MoreResources.readResource("expected_cloud_spec.json"), ConnectorSpecification.class)); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CloudDeploymentMySqlSslFullCertificateSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CloudDeploymentMySqlSslFullCertificateSourceAcceptanceTest.java deleted file mode 100644 index 298276ee443f..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/CloudDeploymentMySqlSslFullCertificateSourceAcceptanceTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.collect.ImmutableMap; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.cdk.integrations.base.ssh.SshHelpers; -import io.airbyte.commons.features.FeatureFlags; -import io.airbyte.commons.features.FeatureFlagsWrapper; -import io.airbyte.commons.json.Jsons; -import io.airbyte.commons.resources.MoreResources; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.ContainerModifier; -import io.airbyte.protocol.models.v0.ConnectorSpecification; -import org.apache.commons.lang3.ArrayUtils; - -public class CloudDeploymentMySqlSslFullCertificateSourceAcceptanceTest extends MySqlSourceAcceptanceTest { - - private static final String PASSWORD = "Passw0rd"; - - @Override - protected FeatureFlags featureFlags() { - return FeatureFlagsWrapper.overridingDeploymentMode(super.featureFlags(), "CLOUD"); - } - - @Override - protected ContainerModifier[] getContainerModifiers() { - return ArrayUtils.toArray(ContainerModifier.ROOT_AND_SERVER_CERTIFICATES, ContainerModifier.CLIENT_CERTITICATE); - } - - @Override - protected JsonNode getConfig() { - return testdb.integrationTestConfigBuilder() - .withStandardReplication() - .withSsl(ImmutableMap.builder() - .put(JdbcUtils.MODE_KEY, "verify_ca") - .put("ca_certificate", testdb.getCertificates().caCertificate()) - .put("client_certificate", testdb.getCertificates().clientCertificate()) - .put("client_key", testdb.getCertificates().clientKey()) - .put("client_key_password", PASSWORD) - .build()) - .build(); - } - - @Override - protected ConnectorSpecification getSpec() throws Exception { - return SshHelpers.injectSshIntoSpec(Jsons.deserialize(MoreResources.readResource("expected_cloud_spec.json"), ConnectorSpecification.class)); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlDatatypeAccuracyTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlDatatypeAccuracyTest.java deleted file mode 100644 index 516d6c20a425..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlDatatypeAccuracyTest.java +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import com.fasterxml.jackson.databind.JsonNode; -import com.mysql.cj.MysqlType; -import io.airbyte.cdk.db.Database; -import io.airbyte.cdk.integrations.standardtest.source.TestDataHolder; -import io.airbyte.integrations.source.mysql.MySQLContainerFactory; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase; -import io.airbyte.protocol.models.JsonSchemaType; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -public class MySqlDatatypeAccuracyTest extends AbstractMySqlSourceDatatypeTest { - - @Override - protected JsonNode getConfig() { - return testdb.integrationTestConfigBuilder() - .withoutSsl() - .withStandardReplication() - .build(); - } - - @Override - protected Database setupDatabase() { - final var sharedContainer = new MySQLContainerFactory().shared("mysql:8.0"); - testdb = new MySQLTestDatabase(sharedContainer) - .withConnectionProperty("zeroDateTimeBehavior", "convertToNull") - .initialized() - .withoutStrictMode(); - return testdb.getDatabase(); - } - - private final Map> charsetsCollationsMap = Map.of( - "UTF8", Arrays.asList("UTF8_bin", "UTF8_general_ci"), - "UTF8MB4", Arrays.asList("UTF8MB4_general_ci", "utf8mb4_0900_ai_ci"), - "UTF16", Arrays.asList("UTF16_bin", "UTF16_general_ci"), - "binary", Arrays.asList("binary"), - "CP1250", Arrays.asList("CP1250_general_ci", "cp1250_czech_cs")); - - @Override - public boolean testCatalog() { - return true; - } - - @Override - protected void initTests() { - for (final MysqlType mst : MysqlType.values()) { - switch (mst) { - case DECIMAL -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("%s(10,0)".formatted(mst.getName())) - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.NUMBER) - .fullSourceDataType("%s(%d,30)".formatted(mst.getName(), mst.getPrecision())) - .build()); - } - case DECIMAL_UNSIGNED -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("DECIMAL(32,0) UNSIGNED") - .build()); - - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.NUMBER) - .fullSourceDataType("DECIMAL(%d,30) UNSIGNED".formatted(mst.getPrecision())) - .build()); - } - case TINYINT -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.BOOLEAN) - .fullSourceDataType("%s(1)".formatted(mst.getName())) - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("%s(%d)".formatted(mst.getName(), mst.getPrecision())) - .build()); - } - case TINYINT_UNSIGNED -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("TINYINT(1) UNSIGNED") - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("TINYINT(%d) UNSIGNED".formatted(mst.getPrecision())) - .build()); - } - case BOOLEAN -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.BOOLEAN) - .fullSourceDataType("%s".formatted(mst.getName())) - .build()); - } - case SMALLINT, BIGINT, MEDIUMINT, INT -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("%s(1)".formatted(mst.getName())) - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("%s(%d)".formatted(mst.getName(), mst.getPrecision())) - .build()); - } - case SMALLINT_UNSIGNED -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("SMALLINT(1) UNSIGNED") - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("SMALLINT(%d) UNSIGNED".formatted(mst.getPrecision())) - .build()); - } - case INT_UNSIGNED -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("INT(1) UNSIGNED") - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("INT(%d) UNSIGNED".formatted(mst.getPrecision())) - .build()); - } - case FLOAT -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.NUMBER) - .fullSourceDataType("%s(0)".formatted(mst.getName())) - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.NUMBER) - .fullSourceDataType("%s(24)".formatted(mst.getName())) - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.NUMBER) - .fullSourceDataType("%s(25)".formatted(mst.getName())) - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.NUMBER) - .fullSourceDataType("%s(53)".formatted(mst.getName())) - .build()); - } - case FLOAT_UNSIGNED -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.NUMBER) - .fullSourceDataType("FLOAT(0) UNSIGNED") - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.NUMBER) - .fullSourceDataType("FLOAT(24) UNSIGNED") - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.NUMBER) - .fullSourceDataType("FLOAT(25) UNSIGNED") - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.NUMBER) - .fullSourceDataType("FLOAT(53) UNSIGNED") - .build()); - - } - case DOUBLE -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.NUMBER) - .fullSourceDataType("DOUBLE PRECISION") - .build()); - } - case DOUBLE_UNSIGNED -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.NUMBER) - .fullSourceDataType("DOUBLE PRECISION UNSIGNED") - .build()); - } - case TIMESTAMP -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.STRING_TIMESTAMP_WITH_TIMEZONE) - .fullSourceDataType("%s(0)".formatted(mst.getName())) - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.STRING_TIMESTAMP_WITH_TIMEZONE) - .fullSourceDataType("%s(6)".formatted(mst.getName())) - .build()); - } - case BIGINT_UNSIGNED -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("BIGINT(1) UNSIGNED") - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("BIGINT(%d) UNSIGNED".formatted(mst.getPrecision())) - .build()); - } - case MEDIUMINT_UNSIGNED -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("MEDIUMINT(1) UNSIGNED") - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("MEDIUMINT(%d) UNSIGNED".formatted(mst.getPrecision())) - .build()); - } - case DATE -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.STRING_DATE) - .fullSourceDataType("%s".formatted(mst.getName())) - .build()); - } - case TIME -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.STRING_TIME_WITHOUT_TIMEZONE) - .fullSourceDataType("%s".formatted(mst.getName())) - .build()); - } - case DATETIME -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.STRING_TIMESTAMP_WITHOUT_TIMEZONE) - .fullSourceDataType("%s".formatted(mst.getName())) - .build()); - } - case YEAR -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.INTEGER) - .fullSourceDataType("%s".formatted(mst.getName())) - .build()); - } - case VARCHAR -> { - for (final Entry entry : charsetsCollationsMap.entrySet()) { - List collations = (List) entry.getValue(); - final var airbyteType = (entry.getKey() == "binary") ? JsonSchemaType.STRING_BASE_64 : JsonSchemaType.STRING; - for (final String collation : collations) { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(airbyteType) - .fullSourceDataType("%s(0) CHARACTER SET %s COLLATE %s".formatted(mst.getName(), entry.getKey(), collation)) - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(airbyteType) - .fullSourceDataType("%s(60000) CHARACTER SET %s COLLATE %s".formatted(mst.getName(), entry.getKey(), collation)) - .build()); - } - } - } - case VARBINARY -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.STRING_BASE_64) - .fullSourceDataType("%s(1)".formatted(mst.getName())) - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.STRING_BASE_64) - .fullSourceDataType("%s(65000)".formatted(mst.getName())) - .build()); - } - case BIT -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.BOOLEAN) - .fullSourceDataType("%s(1)".formatted(mst.getName())) - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.STRING_BASE_64) - .fullSourceDataType("%s(64)".formatted(mst.getName())) - .build()); - - } - case JSON -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.STRING) - .fullSourceDataType("%s".formatted(mst.getName())) - .build()); - } - case ENUM, SET -> { - for (final Entry entry : charsetsCollationsMap.entrySet()) { - List collations = (List) entry.getValue(); - for (final String collation : collations) { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.STRING) - .fullSourceDataType( - "%s('value1', 'value2', 'value3') CHARACTER SET %s COLLATE %s".formatted(mst.getName(), entry.getKey(), collation)) - .build()); - } - } - } - case TINYBLOB, MEDIUMBLOB, LONGBLOB, GEOMETRY -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.STRING_BASE_64) - .fullSourceDataType("%s".formatted(mst.getName())) - .build()); - } - case TINYTEXT, MEDIUMTEXT, LONGTEXT -> { - for (final Entry entry : charsetsCollationsMap.entrySet()) { - final var airbyteType = (entry.getKey() == "binary") ? JsonSchemaType.STRING_BASE_64 : JsonSchemaType.STRING; - List collations = (List) entry.getValue(); - for (final String collation : collations) { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(airbyteType) - .fullSourceDataType("%s CHARACTER SET %s COLLATE %s".formatted(mst.getName(), entry.getKey(), collation)) - .build()); - } - } - } - case BLOB -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.STRING_BASE_64) - .fullSourceDataType("%s(0)".formatted(mst.getName())) - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.STRING_BASE_64) - .fullSourceDataType("%s(65000)".formatted(mst.getName())) - .build()); - } - case TEXT -> { - for (final Entry entry : charsetsCollationsMap.entrySet()) { - final var airbyteType = (entry.getKey() == "binary") ? JsonSchemaType.STRING_BASE_64 : JsonSchemaType.STRING; - List collations = (List) entry.getValue(); - for (final String collation : collations) { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(airbyteType) - .fullSourceDataType("%s(0) CHARACTER SET %s COLLATE %s".formatted(mst.getName(), entry.getKey(), collation)) - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(airbyteType) - .fullSourceDataType("%s(65000) CHARACTER SET %s COLLATE %s".formatted(mst.getName(), entry.getKey(), collation)) - .build()); - } - } - } - case CHAR -> { - for (final Entry entry : charsetsCollationsMap.entrySet()) { - final var airbyteType = (entry.getKey() == "binary") ? JsonSchemaType.STRING_BASE_64 : JsonSchemaType.STRING; - List collations = (List) entry.getValue(); - for (final String collation : collations) { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(airbyteType) - .fullSourceDataType("%s(0) CHARACTER SET %s COLLATE %s".formatted(mst.getName(), entry.getKey(), collation)) - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(airbyteType) - .fullSourceDataType("%s(255) CHARACTER SET %s COLLATE %s".formatted(mst.getName(), entry.getKey(), collation)) - .build()); - } - } - } - case BINARY -> { - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.STRING_BASE_64) - .fullSourceDataType("%s(0)".formatted(mst.getName())) - .build()); - addDataTypeTestData( - TestDataHolder.builder() - .sourceType(mst.name()) - .airbyteType(JsonSchemaType.STRING_BASE_64) - .fullSourceDataType("%s(255)".formatted(mst.getName())) - .build()); - } - case NULL, UNKNOWN -> { - // no-op - } - default -> throw new IllegalStateException("Unexpected value: " + mst); - } - } - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlSourceAcceptanceTest.java deleted file mode 100644 index 6044c66cf9cb..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlSourceAcceptanceTest.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import static io.airbyte.protocol.models.v0.SyncMode.INCREMENTAL; -import static org.junit.Assert.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.Lists; -import io.airbyte.cdk.integrations.base.ssh.SshHelpers; -import io.airbyte.cdk.integrations.standardtest.source.SourceAcceptanceTest; -import io.airbyte.cdk.integrations.standardtest.source.TestDestinationEnv; -import io.airbyte.commons.json.Jsons; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.BaseImage; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.ContainerModifier; -import io.airbyte.protocol.models.Field; -import io.airbyte.protocol.models.JsonSchemaType; -import io.airbyte.protocol.models.v0.*; -import java.util.HashMap; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; -import org.apache.commons.lang3.ArrayUtils; -import org.junit.jupiter.api.Test; - -public class MySqlSourceAcceptanceTest extends SourceAcceptanceTest { - - protected MySQLTestDatabase testdb; - - private static final String STREAM_NAME = "id_and_name"; - private static final String STREAM_NAME2 = "public.starships"; - - @Override - protected void setupEnvironment(final TestDestinationEnv environment) throws Exception { - testdb = MySQLTestDatabase.in(BaseImage.MYSQL_8, getContainerModifiers()) - .with("CREATE TABLE id_and_name(id INTEGER, name VARCHAR(200));") - .with("INSERT INTO id_and_name (id, name) VALUES (1,'picard'), (2, 'crusher'), (3, 'vash');") - .with("CREATE TABLE starships(id INTEGER, name VARCHAR(200));") - .with("INSERT INTO starships (id, name) VALUES (1,'enterprise-d'), (2, 'defiant'), (3, 'yamato');"); - } - - protected ContainerModifier[] getContainerModifiers() { - return ArrayUtils.toArray(); - } - - @Override - protected void tearDown(final TestDestinationEnv testEnv) { - testdb.close(); - } - - @Override - protected String getImageName() { - return "airbyte/source-mysql:dev"; - } - - @Override - protected ConnectorSpecification getSpec() throws Exception { - return SshHelpers.getSpecAndInjectSsh(); - } - - @Override - protected JsonNode getConfig() { - return testdb.integrationTestConfigBuilder() - .withStandardReplication() - .withoutSsl() - .build(); - } - - @Override - protected ConfiguredAirbyteCatalog getConfiguredCatalog() { - return new ConfiguredAirbyteCatalog().withStreams(Lists.newArrayList( - new ConfiguredAirbyteStream() - .withSyncMode(SyncMode.INCREMENTAL) - .withCursorField(Lists.newArrayList("id")) - .withDestinationSyncMode(DestinationSyncMode.APPEND) - .withStream(CatalogHelpers.createAirbyteStream( - STREAM_NAME, testdb.getDatabaseName(), - Field.of("id", JsonSchemaType.NUMBER), - Field.of("name", JsonSchemaType.STRING)) - .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL))), - new ConfiguredAirbyteStream() - .withSyncMode(SyncMode.INCREMENTAL) - .withCursorField(Lists.newArrayList("id")) - .withDestinationSyncMode(DestinationSyncMode.APPEND) - .withStream(CatalogHelpers.createAirbyteStream( - STREAM_NAME2, testdb.getDatabaseName(), - Field.of("id", JsonSchemaType.NUMBER), - Field.of("name", JsonSchemaType.STRING)) - .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL))))); - } - - @Override - protected JsonNode getState() { - return Jsons.jsonNode(new HashMap<>()); - } - - @Test - protected void testNullValueConversion() throws Exception { - final String STREAM_NAME3 = "stream3"; - testdb.getDatabase().query(c -> { - return c.query(""" - CREATE TABLE %s.%s (id INTEGER PRIMARY KEY, name VARCHAR(200), userid INTEGER DEFAULT NULL); - """.formatted(testdb.getDatabaseName(), STREAM_NAME3)); - }).execute(); - - testdb.getDatabase().query(c -> { - return c.query(""" - INSERT INTO %s.%s (id, name) VALUES (4,'voyager'); - """.formatted(testdb.getDatabaseName(), STREAM_NAME3)); - }).execute(); - - final List configuredAirbyteStreams = - Lists.newArrayList(CatalogHelpers.createConfiguredAirbyteStream(STREAM_NAME3, - testdb.getDatabaseName(), - Field.of("id", JsonSchemaType.NUMBER), - Field.of("name", JsonSchemaType.STRING), - Field.of("userid", JsonSchemaType.NUMBER)) - .withDestinationSyncMode(DestinationSyncMode.APPEND) - .withSyncMode(INCREMENTAL) - .withCursorField(List.of("id"))); - final ConfiguredAirbyteCatalog configuredCatalogWithOneStream = - new ConfiguredAirbyteCatalog().withStreams(List.of(configuredAirbyteStreams.get(0))); - - final List airbyteMessages = runRead(configuredCatalogWithOneStream, getState()); - final List recordMessages = filterRecords(airbyteMessages); - final List stateMessages = airbyteMessages - .stream() - .filter(m -> m.getType() == AirbyteMessage.Type.STATE) - .map(AirbyteMessage::getState) - .collect(Collectors.toList()); - assertEquals(recordMessages.size(), 1); - assertFalse(stateMessages.isEmpty(), "Reason"); - ObjectMapper mapper = new ObjectMapper(); - - assertEquals(recordMessages.get(0).getData(), - mapper.readTree("{\"id\":4, \"name\":\"voyager\", \"userid\":null}")); - - // when we run incremental sync again there should be no new records. Run a sync with the latest - // state message and assert no records were emitted. - JsonNode latestState = extractLatestState(stateMessages); - - testdb.getDatabase().query(c -> { - return c.query("INSERT INTO %s.%s (id, name) VALUES (5,'deep space nine');".formatted(testdb.getDatabaseName(), STREAM_NAME3)); - }).execute(); - - assert Objects.nonNull(latestState); - final List secondSyncRecords = filterRecords(runRead(configuredCatalogWithOneStream, latestState)); - assertFalse( - secondSyncRecords.isEmpty(), - "Expected the second incremental sync to produce records."); - assertEquals(secondSyncRecords.get(0).getData(), - mapper.readTree("{\"id\":5, \"name\":\"deep space nine\", \"userid\":null}")); - - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlSourceDatatypeTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlSourceDatatypeTest.java deleted file mode 100644 index cbfa689562dc..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlSourceDatatypeTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import com.fasterxml.jackson.databind.JsonNode; -import io.airbyte.cdk.db.Database; -import io.airbyte.integrations.source.mysql.MySQLContainerFactory; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase; - -public class MySqlSourceDatatypeTest extends AbstractMySqlSourceDatatypeTest { - - @Override - protected JsonNode getConfig() { - return testdb.integrationTestConfigBuilder() - .withoutSsl() - .withStandardReplication() - .build(); - } - - @Override - protected Database setupDatabase() { - final var sharedContainer = new MySQLContainerFactory().shared("mysql:8.0"); - testdb = new MySQLTestDatabase(sharedContainer) - .withConnectionProperty("zeroDateTimeBehavior", "convertToNull") - .initialized() - .withoutStrictMode(); - return testdb.getDatabase(); - } - - @Override - public boolean testCatalog() { - return true; - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlSslCaCertificateSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlSslCaCertificateSourceAcceptanceTest.java deleted file mode 100644 index 71f36aa027f4..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlSslCaCertificateSourceAcceptanceTest.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.collect.ImmutableMap; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.ContainerModifier; -import org.apache.commons.lang3.ArrayUtils; - -public class MySqlSslCaCertificateSourceAcceptanceTest extends MySqlSourceAcceptanceTest { - - private static final String PASSWORD = "Passw0rd"; - - @Override - protected ContainerModifier[] getContainerModifiers() { - return ArrayUtils.toArray(ContainerModifier.ROOT_AND_SERVER_CERTIFICATES); - } - - @Override - protected JsonNode getConfig() { - return testdb.integrationTestConfigBuilder() - .withStandardReplication() - .withSsl(ImmutableMap.builder() - .put(JdbcUtils.MODE_KEY, "verify_ca") - .put("ca_certificate", testdb.getCaCertificate()) - .put("client_key_password", PASSWORD) - .build()) - .build(); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlSslFullCertificateSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlSslFullCertificateSourceAcceptanceTest.java deleted file mode 100644 index d9f325d9db31..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlSslFullCertificateSourceAcceptanceTest.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.collect.ImmutableMap; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.ContainerModifier; -import org.apache.commons.lang3.ArrayUtils; - -public class MySqlSslFullCertificateSourceAcceptanceTest extends MySqlSourceAcceptanceTest { - - private static final String PASSWORD = "Passw0rd"; - - @Override - protected ContainerModifier[] getContainerModifiers() { - return ArrayUtils.toArray(ContainerModifier.ROOT_AND_SERVER_CERTIFICATES, ContainerModifier.CLIENT_CERTITICATE); - } - - @Override - protected JsonNode getConfig() { - return testdb.integrationTestConfigBuilder() - .withStandardReplication() - .withSsl(ImmutableMap.builder() - .put(JdbcUtils.MODE_KEY, "verify_ca") - .put("ca_certificate", testdb.getCertificates().caCertificate()) - .put("client_certificate", testdb.getCertificates().clientCertificate()) - .put("client_key", testdb.getCertificates().clientKey()) - .put("client_key_password", PASSWORD) - .build()) - .build(); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlSslSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlSslSourceAcceptanceTest.java deleted file mode 100644 index 5f46e43808e4..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/MySqlSslSourceAcceptanceTest.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.collect.ImmutableMap; -import io.airbyte.cdk.db.jdbc.JdbcUtils; - -public class MySqlSslSourceAcceptanceTest extends MySqlSourceAcceptanceTest { - - @Override - protected JsonNode getConfig() { - return testdb.integrationTestConfigBuilder() - .withStandardReplication() - .withSsl(ImmutableMap.builder().put(JdbcUtils.MODE_KEY, "required").build()) - .build(); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/SshKeyMySqlSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/SshKeyMySqlSourceAcceptanceTest.java deleted file mode 100644 index 7d5f060f34c2..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/SshKeyMySqlSourceAcceptanceTest.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import java.nio.file.Path; - -public class SshKeyMySqlSourceAcceptanceTest extends AbstractSshMySqlSourceAcceptanceTest { - - @Override - public Path getConfigFilePath() { - return Path.of("secrets/ssh-key-repl-config.json"); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/SshPasswordMySqlSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/SshPasswordMySqlSourceAcceptanceTest.java deleted file mode 100644 index 998e304d7145..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/SshPasswordMySqlSourceAcceptanceTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.io.airbyte.integration_tests.sources; - -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import io.airbyte.cdk.integrations.base.Source; -import io.airbyte.cdk.integrations.base.ssh.SshBastionContainer; -import io.airbyte.cdk.integrations.base.ssh.SshTunnel; -import io.airbyte.commons.exceptions.ConfigErrorException; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.BaseImage; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.ContainerModifier; -import io.airbyte.integrations.source.mysql.MySqlSource; -import java.nio.file.Path; -import org.junit.jupiter.api.Test; - -public class SshPasswordMySqlSourceAcceptanceTest extends AbstractSshMySqlSourceAcceptanceTest { - - @Override - public Path getConfigFilePath() { - return Path.of("secrets/ssh-pwd-repl-config.json"); - } - - @Test - public void sshTimeoutExceptionMarkAsConfigErrorTest() throws Exception { - try (final var testdb = MySQLTestDatabase.in(BaseImage.MYSQL_8, ContainerModifier.NETWORK)) { - final SshBastionContainer bastion = new SshBastionContainer(); - bastion.initAndStartBastion(testdb.getContainer().getNetwork()); - final var config = testdb.integrationTestConfigBuilder() - .withoutSsl() - .with("tunnel_method", bastion.getTunnelMethod(SshTunnel.TunnelMethod.SSH_PASSWORD_AUTH, true)) - .build(); - bastion.stopAndClose(); - - final Source sshWrappedSource = MySqlSource.sshWrappedSource(new MySqlSource()); - final Exception exception = assertThrows(ConfigErrorException.class, () -> sshWrappedSource.discover(config)); - - final String expectedMessage = - "Timed out while opening a SSH Tunnel. Please double check the given SSH configurations and try again."; - final String actualMessage = exception.getMessage(); - assertTrue(actualMessage.contains(expectedMessage)); - } - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/resources/dummy_config.json b/airbyte-integrations/connectors/source-mysql/src/test-integration/resources/dummy_config.json deleted file mode 100644 index e17733f16b23..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/resources/dummy_config.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "host": "default", - "port": 5555, - "database": "default", - "username": "default", - "replication_method": { "method": "STANDARD" } -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/resources/expected_cloud_spec.json b/airbyte-integrations/connectors/source-mysql/src/test-integration/resources/expected_cloud_spec.json deleted file mode 100644 index b76358180e65..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/resources/expected_cloud_spec.json +++ /dev/null @@ -1,343 +0,0 @@ -{ - "documentationUrl": "https://docs.airbyte.com/integrations/sources/mysql", - "connectionSpecification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MySql Source Spec", - "type": "object", - "required": ["host", "port", "database", "username", "replication_method"], - "properties": { - "host": { - "description": "The host name of the database.", - "title": "Host", - "type": "string", - "order": 0 - }, - "port": { - "description": "The port to connect to.", - "title": "Port", - "type": "integer", - "minimum": 0, - "maximum": 65536, - "default": 3306, - "examples": ["3306"], - "order": 1 - }, - "database": { - "description": "The database name.", - "title": "Database", - "type": "string", - "order": 2 - }, - "username": { - "description": "The username which is used to access the database.", - "title": "Username", - "type": "string", - "order": 3 - }, - "password": { - "description": "The password associated with the username.", - "title": "Password", - "type": "string", - "airbyte_secret": true, - "order": 4, - "always_show": true - }, - "jdbc_url_params": { - "description": "Additional properties to pass to the JDBC URL string when connecting to the database formatted as 'key=value' pairs separated by the symbol '&'. (example: key1=value1&key2=value2&key3=value3). For more information read about JDBC URL parameters.", - "title": "JDBC URL Parameters (Advanced)", - "type": "string", - "order": 5 - }, - "ssl_mode": { - "title": "SSL modes", - "description": "SSL connection modes. Read more in the docs.", - "type": "object", - "order": 7, - "oneOf": [ - { - "title": "preferred", - "description": "Automatically attempt SSL connection. If the MySQL server does not support SSL, continue with a regular connection.", - "required": ["mode"], - "properties": { - "mode": { "type": "string", "const": "preferred", "order": 0 } - } - }, - { - "title": "required", - "description": "Always connect with SSL. If the MySQL server doesn’t support SSL, the connection will not be established. Certificate Authority (CA) and Hostname are not verified.", - "required": ["mode"], - "properties": { - "mode": { "type": "string", "const": "required", "order": 0 } - } - }, - { - "title": "Verify CA", - "description": "Always connect with SSL. Verifies CA, but allows connection even if Hostname does not match.", - "required": ["mode", "ca_certificate"], - "properties": { - "mode": { "type": "string", "const": "verify_ca", "order": 0 }, - "ca_certificate": { - "type": "string", - "title": "CA certificate", - "description": "CA certificate", - "airbyte_secret": true, - "multiline": true, - "order": 1 - }, - "client_certificate": { - "type": "string", - "title": "Client certificate", - "description": "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", - "airbyte_secret": true, - "multiline": true, - "order": 2, - "always_show": true - }, - "client_key": { - "type": "string", - "title": "Client key", - "description": "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", - "airbyte_secret": true, - "multiline": true, - "order": 3, - "always_show": true - }, - "client_key_password": { - "type": "string", - "title": "Client key password", - "description": "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", - "airbyte_secret": true, - "order": 4 - } - } - }, - { - "title": "Verify Identity", - "description": "Always connect with SSL. Verify both CA and Hostname.", - "required": ["mode", "ca_certificate"], - "properties": { - "mode": { - "type": "string", - "const": "verify_identity", - "order": 0 - }, - "ca_certificate": { - "type": "string", - "title": "CA certificate", - "description": "CA certificate", - "airbyte_secret": true, - "multiline": true, - "order": 1 - }, - "client_certificate": { - "type": "string", - "title": "Client certificate", - "description": "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", - "airbyte_secret": true, - "multiline": true, - "order": 2, - "always_show": true - }, - "client_key": { - "type": "string", - "title": "Client key", - "description": "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", - "airbyte_secret": true, - "multiline": true, - "order": 3, - "always_show": true - }, - "client_key_password": { - "type": "string", - "title": "Client key password", - "description": "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", - "airbyte_secret": true, - "order": 4 - } - } - } - ], - "default": "required" - }, - "replication_method": { - "type": "object", - "title": "Update Method", - "description": "Configures how data is extracted from the database.", - "order": 8, - "default": "CDC", - "display_type": "radio", - "oneOf": [ - { - "title": "Read Changes using Binary Log (CDC)", - "description": "Recommended - Incrementally reads new inserts, updates, and deletes using the MySQL binary log. This must be enabled on your database.", - "required": ["method"], - "properties": { - "method": { "type": "string", "const": "CDC", "order": 0 }, - "initial_waiting_seconds": { - "type": "integer", - "title": "Initial Waiting Time in Seconds (Advanced)", - "description": "The amount of time the connector will wait when it launches to determine if there is new data to sync or not. Defaults to 300 seconds. Valid range: 120 seconds to 1200 seconds. Read about initial waiting time.", - "default": 300, - "min": 120, - "max": 1200, - "order": 1, - "always_show": true - }, - "server_time_zone": { - "type": "string", - "title": "Configured server timezone for the MySQL source (Advanced)", - "description": "Enter the configured MySQL server timezone. This should only be done if the configured timezone in your MySQL instance does not conform to IANNA standard.", - "order": 2, - "always_show": true - }, - "invalid_cdc_cursor_position_behavior": { - "type": "string", - "title": "Invalid CDC position behavior (Advanced)", - "description": "Determines whether Airbyte should fail or re-sync data in case of an stale/invalid cursor value into the WAL. If 'Fail sync' is chosen, a user will have to manually reset the connection before being able to continue syncing data. If 'Re-sync data' is chosen, Airbyte will automatically trigger a refresh but could lead to higher cloud costs and data loss.", - "enum": ["Fail sync", "Re-sync data"], - "default": "Fail sync", - "order": 3, - "always_show": true - }, - "initial_load_timeout_hours": { - "type": "integer", - "title": "Initial Load Timeout in Hours (Advanced)", - "description": "The amount of time an initial load is allowed to continue for before catching up on CDC logs.", - "default": 8, - "min": 4, - "max": 24, - "order": 4, - "always_show": true - } - } - }, - { - "title": "Scan Changes with User Defined Cursor", - "description": "Incrementally detects new inserts and updates using the cursor column chosen when configuring a connection (e.g. created_at, updated_at).", - "required": ["method"], - "properties": { - "method": { "type": "string", "const": "STANDARD", "order": 0 } - } - } - ] - }, - "tunnel_method": { - "type": "object", - "title": "SSH Tunnel Method", - "description": "Whether to initiate an SSH tunnel before connecting to the database, and if so, which kind of authentication to use.", - "oneOf": [ - { - "title": "No Tunnel", - "required": ["tunnel_method"], - "properties": { - "tunnel_method": { - "description": "No ssh tunnel needed to connect to database", - "type": "string", - "const": "NO_TUNNEL", - "order": 0 - } - } - }, - { - "title": "SSH Key Authentication", - "required": [ - "tunnel_method", - "tunnel_host", - "tunnel_port", - "tunnel_user", - "ssh_key" - ], - "properties": { - "tunnel_method": { - "description": "Connect through a jump server tunnel host using username and ssh key", - "type": "string", - "const": "SSH_KEY_AUTH", - "order": 0 - }, - "tunnel_host": { - "title": "SSH Tunnel Jump Server Host", - "description": "Hostname of the jump server host that allows inbound ssh tunnel.", - "type": "string", - "order": 1 - }, - "tunnel_port": { - "title": "SSH Connection Port", - "description": "Port on the proxy/jump server that accepts inbound ssh connections.", - "type": "integer", - "minimum": 0, - "maximum": 65536, - "default": 22, - "examples": ["22"], - "order": 2 - }, - "tunnel_user": { - "title": "SSH Login Username", - "description": "OS-level username for logging into the jump server host.", - "type": "string", - "order": 3 - }, - "ssh_key": { - "title": "SSH Private Key", - "description": "OS-level user account ssh key credentials in RSA PEM format ( created with ssh-keygen -t rsa -m PEM -f myuser_rsa )", - "type": "string", - "airbyte_secret": true, - "multiline": true, - "order": 4 - } - } - }, - { - "title": "Password Authentication", - "required": [ - "tunnel_method", - "tunnel_host", - "tunnel_port", - "tunnel_user", - "tunnel_user_password" - ], - "properties": { - "tunnel_method": { - "description": "Connect through a jump server tunnel host using username and password authentication", - "type": "string", - "const": "SSH_PASSWORD_AUTH", - "order": 0 - }, - "tunnel_host": { - "title": "SSH Tunnel Jump Server Host", - "description": "Hostname of the jump server host that allows inbound ssh tunnel.", - "type": "string", - "order": 1 - }, - "tunnel_port": { - "title": "SSH Connection Port", - "description": "Port on the proxy/jump server that accepts inbound ssh connections.", - "type": "integer", - "minimum": 0, - "maximum": 65536, - "default": 22, - "examples": ["22"], - "order": 2 - }, - "tunnel_user": { - "title": "SSH Login Username", - "description": "OS-level username for logging into the jump server host", - "type": "string", - "order": 3 - }, - "tunnel_user_password": { - "title": "Password", - "description": "OS-level password for logging into the jump server host", - "type": "string", - "airbyte_secret": true, - "order": 4 - } - } - } - ] - } - } - }, - "supportsNormalization": false, - "supportsDBT": false, - "supported_destination_sync_modes": [] -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/resources/expected_oss_spec.json b/airbyte-integrations/connectors/source-mysql/src/test-integration/resources/expected_oss_spec.json deleted file mode 100644 index d45898990ba5..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test-integration/resources/expected_oss_spec.json +++ /dev/null @@ -1,367 +0,0 @@ -{ - "documentationUrl": "https://docs.airbyte.com/integrations/sources/mysql", - "connectionSpecification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MySql Source Spec", - "type": "object", - "required": ["host", "port", "database", "username", "replication_method"], - "properties": { - "host": { - "description": "The host name of the database.", - "title": "Host", - "type": "string", - "order": 0 - }, - "port": { - "description": "The port to connect to.", - "title": "Port", - "type": "integer", - "minimum": 0, - "maximum": 65536, - "default": 3306, - "examples": ["3306"], - "order": 1 - }, - "database": { - "description": "The database name.", - "title": "Database", - "type": "string", - "order": 2 - }, - "username": { - "description": "The username which is used to access the database.", - "title": "Username", - "type": "string", - "order": 3 - }, - "password": { - "description": "The password associated with the username.", - "title": "Password", - "type": "string", - "airbyte_secret": true, - "order": 4, - "always_show": true - }, - "jdbc_url_params": { - "description": "Additional properties to pass to the JDBC URL string when connecting to the database formatted as 'key=value' pairs separated by the symbol '&'. (example: key1=value1&key2=value2&key3=value3). For more information read about JDBC URL parameters.", - "title": "JDBC URL Parameters (Advanced)", - "type": "string", - "order": 5 - }, - "ssl": { - "title": "SSL Connection", - "description": "Encrypt data using SSL.", - "type": "boolean", - "default": true, - "order": 6 - }, - "ssl_mode": { - "title": "SSL modes", - "description": "SSL connection modes. Read more in the docs.", - "type": "object", - "order": 7, - "oneOf": [ - { - "title": "preferred", - "description": "Automatically attempt SSL connection. If the MySQL server does not support SSL, continue with a regular connection.", - "required": ["mode"], - "properties": { - "mode": { - "type": "string", - "const": "preferred", - "order": 0 - } - } - }, - { - "title": "required", - "description": "Always connect with SSL. If the MySQL server doesn’t support SSL, the connection will not be established. Certificate Authority (CA) and Hostname are not verified.", - "required": ["mode"], - "properties": { - "mode": { - "type": "string", - "const": "required", - "order": 0 - } - } - }, - { - "title": "Verify CA", - "description": "Always connect with SSL. Verifies CA, but allows connection even if Hostname does not match.", - "required": ["mode", "ca_certificate"], - "properties": { - "mode": { - "type": "string", - "const": "verify_ca", - "order": 0 - }, - "ca_certificate": { - "type": "string", - "title": "CA certificate", - "description": "CA certificate", - "airbyte_secret": true, - "multiline": true, - "order": 1 - }, - "client_certificate": { - "type": "string", - "title": "Client certificate", - "description": "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", - "airbyte_secret": true, - "multiline": true, - "order": 2, - "always_show": true - }, - "client_key": { - "type": "string", - "title": "Client key", - "description": "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", - "airbyte_secret": true, - "multiline": true, - "order": 3, - "always_show": true - }, - "client_key_password": { - "type": "string", - "title": "Client key password", - "description": "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", - "airbyte_secret": true, - "order": 4 - } - } - }, - { - "title": "Verify Identity", - "description": "Always connect with SSL. Verify both CA and Hostname.", - "required": ["mode", "ca_certificate"], - "properties": { - "mode": { - "type": "string", - "const": "verify_identity", - "order": 0 - }, - "ca_certificate": { - "type": "string", - "title": "CA certificate", - "description": "CA certificate", - "airbyte_secret": true, - "multiline": true, - "order": 1 - }, - "client_certificate": { - "type": "string", - "title": "Client certificate", - "description": "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", - "airbyte_secret": true, - "multiline": true, - "order": 2, - "always_show": true - }, - "client_key": { - "type": "string", - "title": "Client key", - "description": "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", - "airbyte_secret": true, - "multiline": true, - "order": 3, - "always_show": true - }, - "client_key_password": { - "type": "string", - "title": "Client key password", - "description": "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", - "airbyte_secret": true, - "order": 4 - } - } - } - ] - }, - "replication_method": { - "type": "object", - "title": "Update Method", - "description": "Configures how data is extracted from the database.", - "order": 8, - "default": "CDC", - "display_type": "radio", - "oneOf": [ - { - "title": "Read Changes using Binary Log (CDC)", - "description": "Recommended - Incrementally reads new inserts, updates, and deletes using the MySQL binary log. This must be enabled on your database.", - "required": ["method"], - "properties": { - "method": { - "type": "string", - "const": "CDC", - "order": 0 - }, - "initial_waiting_seconds": { - "type": "integer", - "title": "Initial Waiting Time in Seconds (Advanced)", - "description": "The amount of time the connector will wait when it launches to determine if there is new data to sync or not. Defaults to 300 seconds. Valid range: 120 seconds to 1200 seconds. Read about initial waiting time.", - "default": 300, - "min": 120, - "max": 1200, - "order": 1, - "always_show": true - }, - "server_time_zone": { - "type": "string", - "title": "Configured server timezone for the MySQL source (Advanced)", - "description": "Enter the configured MySQL server timezone. This should only be done if the configured timezone in your MySQL instance does not conform to IANNA standard.", - "order": 2, - "always_show": true - }, - "invalid_cdc_cursor_position_behavior": { - "type": "string", - "title": "Invalid CDC position behavior (Advanced)", - "description": "Determines whether Airbyte should fail or re-sync data in case of an stale/invalid cursor value into the WAL. If 'Fail sync' is chosen, a user will have to manually reset the connection before being able to continue syncing data. If 'Re-sync data' is chosen, Airbyte will automatically trigger a refresh but could lead to higher cloud costs and data loss.", - "enum": ["Fail sync", "Re-sync data"], - "default": "Fail sync", - "order": 3, - "always_show": true - }, - "initial_load_timeout_hours": { - "type": "integer", - "title": "Initial Load Timeout in Hours (Advanced)", - "description": "The amount of time an initial load is allowed to continue for before catching up on CDC logs.", - "default": 8, - "min": 4, - "max": 24, - "order": 4, - "always_show": true - } - } - }, - { - "title": "Scan Changes with User Defined Cursor", - "description": "Incrementally detects new inserts and updates using the cursor column chosen when configuring a connection (e.g. created_at, updated_at).", - "required": ["method"], - "properties": { - "method": { - "type": "string", - "const": "STANDARD", - "order": 0 - } - } - } - ] - }, - "tunnel_method": { - "type": "object", - "title": "SSH Tunnel Method", - "description": "Whether to initiate an SSH tunnel before connecting to the database, and if so, which kind of authentication to use.", - "oneOf": [ - { - "title": "No Tunnel", - "required": ["tunnel_method"], - "properties": { - "tunnel_method": { - "description": "No ssh tunnel needed to connect to database", - "type": "string", - "const": "NO_TUNNEL", - "order": 0 - } - } - }, - { - "title": "SSH Key Authentication", - "required": [ - "tunnel_method", - "tunnel_host", - "tunnel_port", - "tunnel_user", - "ssh_key" - ], - "properties": { - "tunnel_method": { - "description": "Connect through a jump server tunnel host using username and ssh key", - "type": "string", - "const": "SSH_KEY_AUTH", - "order": 0 - }, - "tunnel_host": { - "title": "SSH Tunnel Jump Server Host", - "description": "Hostname of the jump server host that allows inbound ssh tunnel.", - "type": "string", - "order": 1 - }, - "tunnel_port": { - "title": "SSH Connection Port", - "description": "Port on the proxy/jump server that accepts inbound ssh connections.", - "type": "integer", - "minimum": 0, - "maximum": 65536, - "default": 22, - "examples": ["22"], - "order": 2 - }, - "tunnel_user": { - "title": "SSH Login Username", - "description": "OS-level username for logging into the jump server host.", - "type": "string", - "order": 3 - }, - "ssh_key": { - "title": "SSH Private Key", - "description": "OS-level user account ssh key credentials in RSA PEM format ( created with ssh-keygen -t rsa -m PEM -f myuser_rsa )", - "type": "string", - "airbyte_secret": true, - "multiline": true, - "order": 4 - } - } - }, - { - "title": "Password Authentication", - "required": [ - "tunnel_method", - "tunnel_host", - "tunnel_port", - "tunnel_user", - "tunnel_user_password" - ], - "properties": { - "tunnel_method": { - "description": "Connect through a jump server tunnel host using username and password authentication", - "type": "string", - "const": "SSH_PASSWORD_AUTH", - "order": 0 - }, - "tunnel_host": { - "title": "SSH Tunnel Jump Server Host", - "description": "Hostname of the jump server host that allows inbound ssh tunnel.", - "type": "string", - "order": 1 - }, - "tunnel_port": { - "title": "SSH Connection Port", - "description": "Port on the proxy/jump server that accepts inbound ssh connections.", - "type": "integer", - "minimum": 0, - "maximum": 65536, - "default": 22, - "examples": ["22"], - "order": 2 - }, - "tunnel_user": { - "title": "SSH Login Username", - "description": "OS-level username for logging into the jump server host", - "type": "string", - "order": 3 - }, - "tunnel_user_password": { - "title": "Password", - "description": "OS-level password for logging into the jump server host", - "type": "string", - "airbyte_secret": true, - "order": 4 - } - } - } - ] - } - } - }, - "supported_destination_sync_modes": [] -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test-integration/resources/test.png b/airbyte-integrations/connectors/source-mysql/src/test-integration/resources/test.png deleted file mode 100644 index ca452bd25e3c..000000000000 Binary files a/airbyte-integrations/connectors/source-mysql/src/test-integration/resources/test.png and /dev/null differ diff --git a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/CdcConfigurationHelperTest.java b/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/CdcConfigurationHelperTest.java deleted file mode 100644 index 6c6a370c15fd..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/CdcConfigurationHelperTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import com.fasterxml.jackson.databind.JsonNode; -import io.airbyte.commons.json.Jsons; -import io.airbyte.integrations.source.mysql.cdc.CdcConfigurationHelper; -import java.util.Collections; -import java.util.Map; -import org.junit.jupiter.api.Test; - -public class CdcConfigurationHelperTest { - - @Test - void testServerTimeConfig() { - final JsonNode emptyConfig = Jsons.jsonNode(Collections.emptyMap()); - assertDoesNotThrow(() -> CdcConfigurationHelper.checkServerTimeZoneConfig(emptyConfig)); - - final JsonNode normalConfig = Jsons.jsonNode(Map.of("replication_method", - Map.of("method", "CDC", "server_time_zone", "America/Los_Angeles"))); - assertDoesNotThrow(() -> CdcConfigurationHelper.checkServerTimeZoneConfig(normalConfig)); - - final JsonNode invalidConfig = Jsons.jsonNode(Map.of("replication_method", - Map.of("method", "CDC", "server_time_zone", "CEST"))); - assertThrows(IllegalArgumentException.class, () -> CdcConfigurationHelper.checkServerTimeZoneConfig(invalidConfig)); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/CdcMysqlSourceTest.java b/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/CdcMysqlSourceTest.java deleted file mode 100644 index 85ab5a0f4c7a..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/CdcMysqlSourceTest.java +++ /dev/null @@ -1,930 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -import static io.airbyte.cdk.integrations.debezium.DebeziumIteratorConstants.SYNC_CHECKPOINT_RECORDS_PROPERTY; -import static io.airbyte.cdk.integrations.debezium.internals.DebeziumEventConverter.CDC_DELETED_AT; -import static io.airbyte.cdk.integrations.debezium.internals.DebeziumEventConverter.CDC_UPDATED_AT; -import static io.airbyte.integrations.source.mysql.MySqlSource.CDC_DEFAULT_CURSOR; -import static io.airbyte.integrations.source.mysql.MySqlSource.CDC_LOG_FILE; -import static io.airbyte.integrations.source.mysql.MySqlSource.CDC_LOG_POS; -import static io.airbyte.integrations.source.mysql.MySqlSpecConstants.FAIL_SYNC_OPTION; -import static io.airbyte.integrations.source.mysql.cdc.MysqlCdcStateConstants.IS_COMPRESSED; -import static io.airbyte.integrations.source.mysql.cdc.MysqlCdcStateConstants.MYSQL_CDC_OFFSET; -import static io.airbyte.integrations.source.mysql.cdc.MysqlCdcStateConstants.MYSQL_DB_HISTORY; -import static io.airbyte.integrations.source.mysql.initialsync.MySqlInitialLoadStateManager.PRIMARY_KEY_STATE_TYPE; -import static io.airbyte.integrations.source.mysql.initialsync.MySqlInitialLoadStateManager.STATE_TYPE_KEY; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.common.collect.Streams; -import io.airbyte.cdk.db.jdbc.DefaultJdbcDatabase; -import io.airbyte.cdk.db.jdbc.JdbcDatabase; -import io.airbyte.cdk.integrations.debezium.CdcSourceTest; -import io.airbyte.cdk.integrations.debezium.internals.AirbyteSchemaHistoryStorage; -import io.airbyte.commons.exceptions.ConfigErrorException; -import io.airbyte.commons.json.Jsons; -import io.airbyte.commons.util.AutoCloseableIterator; -import io.airbyte.commons.util.AutoCloseableIterators; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.BaseImage; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.ContainerModifier; -import io.airbyte.integrations.source.mysql.cdc.MySqlCdcProperties; -import io.airbyte.integrations.source.mysql.cdc.MySqlCdcTargetPosition; -import io.airbyte.protocol.models.Field; -import io.airbyte.protocol.models.JsonSchemaType; -import io.airbyte.protocol.models.v0.AirbyteConnectionStatus; -import io.airbyte.protocol.models.v0.AirbyteConnectionStatus.Status; -import io.airbyte.protocol.models.v0.AirbyteGlobalState; -import io.airbyte.protocol.models.v0.AirbyteMessage; -import io.airbyte.protocol.models.v0.AirbyteRecordMessage; -import io.airbyte.protocol.models.v0.AirbyteRecordMessageMeta; -import io.airbyte.protocol.models.v0.AirbyteRecordMessageMetaChange; -import io.airbyte.protocol.models.v0.AirbyteRecordMessageMetaChange.Change; -import io.airbyte.protocol.models.v0.AirbyteRecordMessageMetaChange.Reason; -import io.airbyte.protocol.models.v0.AirbyteStateMessage; -import io.airbyte.protocol.models.v0.AirbyteStateMessage.AirbyteStateType; -import io.airbyte.protocol.models.v0.AirbyteStream; -import io.airbyte.protocol.models.v0.AirbyteStreamState; -import io.airbyte.protocol.models.v0.CatalogHelpers; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; -import io.airbyte.protocol.models.v0.StreamDescriptor; -import io.airbyte.protocol.models.v0.SyncMode; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Properties; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; -import java.util.stream.Collectors; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -@Order(1) -@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NP_NULL_ON_SOME_PATH") -public class CdcMysqlSourceTest extends CdcSourceTest { - - private static final String INVALID_TIMEZONE_CEST = "CEST"; - - private static final Random RANDOM = new Random(); - - private static final String TEST_DATE_STREAM_NAME = "TEST_DATE_TABLE"; - private static final String COL_DATE_TIME = "CAR_DATE"; - private static final List DATE_TIME_RECORDS = ImmutableList.of( - Jsons.jsonNode(ImmutableMap.of(COL_ID, 120, COL_DATE_TIME, "'2023-00-00 20:37:47'"))); - - @Override - protected void assertExpectedStateMessageCountMatches(final List stateMessages, long totalCount) { - AtomicLong count = new AtomicLong(0L); - stateMessages.stream().forEach( - stateMessage -> count.addAndGet(stateMessage.getSourceStats() != null ? stateMessage.getSourceStats().getRecordCount().longValue() : 0L)); - assertEquals(totalCount, count.get()); - } - - @Override - protected MySQLTestDatabase createTestDatabase() { - return MySQLTestDatabase.in(BaseImage.MYSQL_8, ContainerModifier.INVALID_TIMEZONE_CEST).withCdcPermissions(); - } - - @Override - protected MySqlSource source() { - return new MySqlSource(); - } - - @Override - protected JsonNode config() { - return testdb.testConfigBuilder() - .withCdcReplication() - .with(SYNC_CHECKPOINT_RECORDS_PROPERTY, 1) - .build(); - } - - protected void purgeAllBinaryLogs() { - testdb.with("RESET MASTER;"); - } - - @Override - protected String createSchemaSqlFmt() { - return "CREATE DATABASE IF NOT EXISTS `%s`;"; - } - - @Override - protected String createTableSqlFmt() { - return "CREATE TABLE `%s`.`%s`(%s);"; - } - - @Override - protected String modelsSchema() { - return getDatabaseName(); - } - - @Override - protected String randomSchema() { - return getDatabaseName(); - } - - protected String getDatabaseName() { - return testdb.getDatabaseName(); - } - - @Override - protected MySqlCdcTargetPosition cdcLatestTargetPosition() { - return MySqlCdcTargetPosition.targetPosition(new DefaultJdbcDatabase(testdb.getDataSource())); - } - - @Override - protected MySqlCdcTargetPosition extractPosition(final JsonNode record) { - return new MySqlCdcTargetPosition(record.get(CDC_LOG_FILE).asText(), record.get(CDC_LOG_POS).asLong()); - } - - @Override - protected void assertNullCdcMetaData(final JsonNode data) { - assertNull(data.get(CDC_LOG_FILE)); - assertNull(data.get(CDC_LOG_POS)); - assertNull(data.get(CDC_UPDATED_AT)); - assertNull(data.get(CDC_DELETED_AT)); - assertNull(data.get(CDC_DEFAULT_CURSOR)); - } - - @Override - protected void assertCdcMetaData(final JsonNode data, final boolean deletedAtNull) { - assertNotNull(data.get(CDC_LOG_FILE)); - assertNotNull(data.get(CDC_LOG_POS)); - assertNotNull(data.get(CDC_UPDATED_AT)); - assertNotNull(data.get(CDC_DEFAULT_CURSOR)); - if (deletedAtNull) { - assertTrue(data.get(CDC_DELETED_AT).isNull()); - } else { - assertFalse(data.get(CDC_DELETED_AT).isNull()); - } - } - - @Override - protected void removeCDCColumns(final ObjectNode data) { - data.remove(CDC_LOG_FILE); - data.remove(CDC_LOG_POS); - data.remove(CDC_UPDATED_AT); - data.remove(CDC_DELETED_AT); - data.remove(CDC_DEFAULT_CURSOR); - } - - @Override - protected void addCdcMetadataColumns(final AirbyteStream stream) { - final ObjectNode jsonSchema = (ObjectNode) stream.getJsonSchema(); - final ObjectNode properties = (ObjectNode) jsonSchema.get("properties"); - - final JsonNode airbyteIntegerType = Jsons.jsonNode(ImmutableMap.of("type", "number", "airbyte_type", "integer")); - final JsonNode numberType = Jsons.jsonNode(ImmutableMap.of("type", "number")); - final JsonNode stringType = Jsons.jsonNode(ImmutableMap.of("type", "string")); - properties.set(CDC_LOG_FILE, stringType); - properties.set(CDC_LOG_POS, numberType); - properties.set(CDC_UPDATED_AT, stringType); - properties.set(CDC_DELETED_AT, stringType); - properties.set(CDC_DEFAULT_CURSOR, airbyteIntegerType); - } - - @Override - protected void addCdcDefaultCursorField(final AirbyteStream stream) { - if (stream.getSupportedSyncModes().contains(SyncMode.INCREMENTAL)) { - stream.setDefaultCursorField(ImmutableList.of(CDC_DEFAULT_CURSOR)); - } - } - - @Override - protected void writeRecords( - final JsonNode recordJson, - final String dbName, - final String streamName, - final String idCol, - final String makeIdCol, - final String modelCol) { - testdb.with("INSERT INTO `%s` .`%s` (%s, %s, %s) VALUES (%s, %s, '%s');", dbName, streamName, - idCol, makeIdCol, modelCol, - recordJson.get(idCol).asInt(), recordJson.get(makeIdCol).asInt(), - recordJson.get(modelCol).asText()); - } - - @Override - protected void deleteMessageOnIdCol(final String streamName, final String idCol, final int idValue) { - testdb.with("DELETE FROM `%s`.`%s` WHERE %s = %s", modelsSchema(), streamName, idCol, idValue); - } - - @Override - protected void deleteCommand(final String streamName) { - testdb.with("DELETE FROM `%s`.`%s`", modelsSchema(), streamName); - } - - @Override - protected void updateCommand(final String streamName, final String modelCol, final String modelVal, final String idCol, final int idValue) { - testdb.with("UPDATE `%s`.`%s` SET %s = '%s' WHERE %s = %s", modelsSchema(), streamName, - modelCol, modelVal, COL_ID, 11); - } - - @Override - protected boolean supportResumableFullRefresh() { - return true; - } - - @Override - protected void addIsResumableFlagForNonPkTable(final AirbyteStream stream) { - stream.setIsResumable(false); - } - - @Test - protected void syncWithReplicationClientPrivilegeRevokedFailsCheck() throws Exception { - testdb.with("REVOKE REPLICATION CLIENT ON *.* FROM %s@'%%';", testdb.getUserName()); - final AirbyteConnectionStatus status = source().check(config()); - final String expectedErrorMessage = "Please grant REPLICATION CLIENT privilege, so that binary log files are available" - + " for CDC mode."; - assertTrue(status.getStatus().equals(Status.FAILED)); - assertTrue(status.getMessage().contains(expectedErrorMessage)); - } - - @Test - protected void syncShouldHandlePurgedLogsGracefully() throws Exception { - - final int recordsToCreate = 20; - // first batch of records. 20 created here and 6 created in setup method. - for (int recordsCreated = 0; recordsCreated < recordsToCreate; recordsCreated++) { - final JsonNode record = - Jsons.jsonNode(ImmutableMap - .of(COL_ID, 100 + recordsCreated, COL_MAKE_ID, 1, COL_MODEL, - "F-" + recordsCreated)); - writeModelRecord(record); - } - - final AutoCloseableIterator firstBatchIterator = source() - .read(config(), getConfiguredCatalog(), null); - final List dataFromFirstBatch = AutoCloseableIterators - .toListAndClose(firstBatchIterator); - final List stateAfterFirstBatch = extractStateMessages(dataFromFirstBatch); - assertStateForSyncShouldHandlePurgedLogsGracefully(stateAfterFirstBatch, 1); - final Set recordsFromFirstBatch = extractRecordMessages( - dataFromFirstBatch); - - final int recordsCreatedBeforeTestCount = MODEL_RECORDS.size(); - assertEquals((recordsCreatedBeforeTestCount + recordsToCreate), recordsFromFirstBatch.size()); - // sometimes there can be more than one of these at the end of the snapshot and just before the - // first incremental. - final Set recordsFromFirstBatchWithoutDuplicates = removeDuplicates( - recordsFromFirstBatch); - - assertTrue(recordsCreatedBeforeTestCount < recordsFromFirstBatchWithoutDuplicates.size(), - "Expected first sync to include records created while the test was running."); - - // second batch of records again 20 being created - for (int recordsCreated = 0; recordsCreated < recordsToCreate; recordsCreated++) { - final JsonNode record = - Jsons.jsonNode(ImmutableMap - .of(COL_ID, 200 + recordsCreated, COL_MAKE_ID, 1, COL_MODEL, - "F-" + recordsCreated)); - writeModelRecord(record); - } - - purgeAllBinaryLogs(); - - final JsonNode state = Jsons.jsonNode(Collections.singletonList(stateAfterFirstBatch.get(stateAfterFirstBatch.size() - 1))); - final AutoCloseableIterator secondBatchIterator = source() - .read(config(), getConfiguredCatalog(), state); - final List dataFromSecondBatch = AutoCloseableIterators - .toListAndClose(secondBatchIterator); - - final List stateAfterSecondBatch = extractStateMessages(dataFromSecondBatch); - assertStateForSyncShouldHandlePurgedLogsGracefully(stateAfterSecondBatch, 2); - - final Set recordsFromSecondBatch = extractRecordMessages( - dataFromSecondBatch); - assertEquals((recordsToCreate * 2) + recordsCreatedBeforeTestCount, recordsFromSecondBatch.size(), - "Expected 46 records to be replicated in the second sync."); - - JsonNode failSyncConfig = testdb.testConfigBuilder() - .withCdcReplication(FAIL_SYNC_OPTION) - .with(SYNC_CHECKPOINT_RECORDS_PROPERTY, 1) - .build(); - assertThrows(ConfigErrorException.class, () -> source().read(failSyncConfig, getConfiguredCatalog(), state)); - } - - /** - * This test verifies that multiple states are sent during the CDC process based on number of - * records. We can ensure that more than one `STATE` type of message is sent, but we are not able to - * assert the exact number of messages sent as depends on Debezium. - * - * @throws Exception Exception happening in the test. - */ - @Test - @Timeout(value = 5, - unit = TimeUnit.MINUTES) - protected void verifyCheckpointStatesByRecords() throws Exception { - // We require a huge amount of records, otherwise Debezium will notify directly the last offset. - final int recordsToCreate = 20_000; - - final AutoCloseableIterator firstBatchIterator = source() - .read(config(), getConfiguredCatalog(), null); - final List dataFromFirstBatch = AutoCloseableIterators - .toListAndClose(firstBatchIterator); - final List stateMessages = extractStateMessages(dataFromFirstBatch); - - // As first `read` operation is from snapshot, it would generate only one state message at the end - // of the process. - assertExpectedStateMessages(stateMessages); - - for (int recordsCreated = 0; recordsCreated < recordsToCreate; recordsCreated++) { - final JsonNode record = Jsons.jsonNode(ImmutableMap - .of(COL_ID, 200 + recordsCreated, COL_MAKE_ID, 1, COL_MODEL, "F-" + recordsCreated)); - writeModelRecord(record); - } - - final JsonNode stateAfterFirstSync = Jsons.jsonNode(Collections.singletonList(stateMessages.get(stateMessages.size() - 1))); - final AutoCloseableIterator secondBatchIterator = source() - .read(config(), getConfiguredCatalog(), stateAfterFirstSync); - final List dataFromSecondBatch = AutoCloseableIterators - .toListAndClose(secondBatchIterator); - assertEquals(recordsToCreate, extractRecordMessages(dataFromSecondBatch).size()); - final List stateMessagesCDC = extractStateMessages(dataFromSecondBatch); - assertTrue(stateMessagesCDC.size() > 1, "Generated only the final state."); - assertEquals(stateMessagesCDC.size(), stateMessagesCDC.stream().distinct().count(), "There are duplicated states."); - } - - @Override - protected void assertExpectedStateMessages(final List stateMessages) { - assertEquals(7, stateMessages.size()); - assertStateTypes(stateMessages, 4, supportResumableFullRefresh()); - } - - @Override - protected void assertExpectedStateMessagesForFullRefresh(final List stateMessages) { - // Full refresh will only send 6 state messages - one for each record (including the final one). - assertEquals(6, stateMessages.size()); - } - - protected void assertExpectedStateMessagesWithTotalCount(final List stateMessages, final long totalRecordCount) { - long actualRecordCount = 0L; - for (final AirbyteStateMessage message : stateMessages) { - actualRecordCount += message.getSourceStats().getRecordCount(); - } - assertEquals(actualRecordCount, totalRecordCount); - } - - @Override - protected void assertExpectedStateMessagesFromIncrementalSync(final List stateMessages) { - assertEquals(1, stateMessages.size()); - assertNotNull(stateMessages.get(0).getData()); - for (final AirbyteStateMessage stateMessage : stateMessages) { - assertNotNull(stateMessage.getData().get("cdc_state").get("state").get(MYSQL_CDC_OFFSET)); - assertNotNull(stateMessage.getData().get("cdc_state").get("state").get(MYSQL_DB_HISTORY)); - } - } - - private void assertStateForSyncShouldHandlePurgedLogsGracefully(final List stateMessages, final int syncNumber) { - if (syncNumber == 1) { - assertExpectedStateMessagesForRecordsProducedDuringAndAfterSync(stateMessages); - } else if (syncNumber == 2) { - // Sync number 2 uses the state from sync number 1 but before we trigger the sync 2 we purge the - // binary logs and as a result the validation of - // logs present on the server fails, and we trigger a sync from scratch - assertEquals(47, stateMessages.size()); - assertStateTypes(stateMessages, 44); - } else { - throw new RuntimeException("Unknown sync number"); - } - - } - - @Override - protected void assertExpectedStateMessagesForRecordsProducedDuringAndAfterSync(final List stateAfterFirstBatch) { - assertEquals(27, stateAfterFirstBatch.size()); - assertStateTypes(stateAfterFirstBatch, 24); - } - - @Override - protected void assertExpectedStateMessagesForNoData(final List stateMessages) { - assertEquals(2, stateMessages.size()); - } - - @Override - protected void validateStreamStateInResumableFullRefresh(final JsonNode streamStateToBeTested) { - // Pk should be pointing to the last element from MODEL_RECORDS table. - assertEquals("16", streamStateToBeTested.get("pk_val").asText()); - assertEquals("id", streamStateToBeTested.get("pk_name").asText()); - assertEquals("primary_key", streamStateToBeTested.get("state_type").asText()); - } - - private void assertStateTypes(final List stateMessages, final int indexTillWhichExpectPkState) { - assertStateTypes(stateMessages, indexTillWhichExpectPkState, false); - } - - private void assertStateTypes(final List stateMessages, - final int indexTillWhichExpectPkState, - boolean expectSharedStateChange) { - JsonNode sharedState = null; - - for (int i = 0; i < stateMessages.size(); i++) { - final AirbyteStateMessage stateMessage = stateMessages.get(i); - assertEquals(AirbyteStateType.GLOBAL, stateMessage.getType()); - final AirbyteGlobalState global = stateMessage.getGlobal(); - assertNotNull(global.getSharedState()); - if (Objects.isNull(sharedState)) { - sharedState = global.getSharedState(); - } else if (expectSharedStateChange && i == indexTillWhichExpectPkState) { - sharedState = global.getSharedState(); - } else if (i != stateMessages.size() - 1) { - assertEquals(sharedState, global.getSharedState()); - } - assertEquals(1, global.getStreamStates().size()); - final AirbyteStreamState streamState = global.getStreamStates().get(0); - if (i <= indexTillWhichExpectPkState) { - assertTrue(streamState.getStreamState().has(STATE_TYPE_KEY)); - assertEquals(PRIMARY_KEY_STATE_TYPE, streamState.getStreamState().get(STATE_TYPE_KEY).asText()); - } else { - assertFalse(streamState.getStreamState().has(STATE_TYPE_KEY)); - } - } - } - - @Override - protected void assertStateMessagesForNewTableSnapshotTest(final List stateMessages, - final AirbyteStateMessage stateMessageEmittedAfterFirstSyncCompletion) { - - // First message emitted in the WASS case is a CDC state message. This should have a different - // global state (LSN) as compared to the previous - // finishing state. The streams in snapshot phase should be the one that is completed at that point. - assertEquals(7, stateMessages.size()); - final AirbyteStateMessage cdcStateMessage = stateMessages.get(0); - assertNotEquals(stateMessageEmittedAfterFirstSyncCompletion.getGlobal().getSharedState(), cdcStateMessage.getGlobal().getSharedState()); - Set streamsInSnapshotState = cdcStateMessage.getGlobal().getStreamStates() - .stream() - .map(AirbyteStreamState::getStreamDescriptor) - .collect(Collectors.toSet()); - assertEquals(1, streamsInSnapshotState.size()); - assertTrue(streamsInSnapshotState.contains(new StreamDescriptor().withName(MODELS_STREAM_NAME).withNamespace(getDatabaseName()))); - - for (int i = 1; i <= 5; i++) { - final AirbyteStateMessage stateMessage = stateMessages.get(i); - assertEquals(AirbyteStateType.GLOBAL, stateMessage.getType()); - // Shared state should not be the same as the first (CDC) state message as it should not change in - // initial sync. - assertEquals(cdcStateMessage.getGlobal().getSharedState(), stateMessage.getGlobal().getSharedState()); - streamsInSnapshotState.clear(); - streamsInSnapshotState = stateMessage.getGlobal().getStreamStates() - .stream() - .map(AirbyteStreamState::getStreamDescriptor) - .collect(Collectors.toSet()); - assertEquals(2, streamsInSnapshotState.size()); - assertTrue( - streamsInSnapshotState.contains(new StreamDescriptor().withName(MODELS_STREAM_NAME + "_random").withNamespace(randomSchema()))); - assertTrue(streamsInSnapshotState.contains(new StreamDescriptor().withName(MODELS_STREAM_NAME).withNamespace(getDatabaseName()))); - - stateMessage.getGlobal().getStreamStates().forEach(s -> { - final JsonNode streamState = s.getStreamState(); - if (s.getStreamDescriptor().equals(new StreamDescriptor().withName(MODELS_STREAM_NAME + "_random").withNamespace(randomSchema()))) { - assertEquals(PRIMARY_KEY_STATE_TYPE, streamState.get(STATE_TYPE_KEY).asText()); - } else if (s.getStreamDescriptor().equals(new StreamDescriptor().withName(MODELS_STREAM_NAME).withNamespace(getDatabaseName()))) { - assertFalse(streamState.has(STATE_TYPE_KEY)); - } else { - throw new RuntimeException("Unknown stream"); - } - }); - } - - // The last message emitted should indicate that initial PK load has finished for both streams. - final AirbyteStateMessage stateMessageEmittedAfterSecondSyncCompletion = stateMessages.get(6); - assertEquals(AirbyteStateType.GLOBAL, stateMessageEmittedAfterSecondSyncCompletion.getType()); - assertEquals(cdcStateMessage.getGlobal().getSharedState(), - stateMessageEmittedAfterSecondSyncCompletion.getGlobal().getSharedState()); - streamsInSnapshotState.clear(); - streamsInSnapshotState = stateMessageEmittedAfterSecondSyncCompletion.getGlobal().getStreamStates() - .stream() - .map(AirbyteStreamState::getStreamDescriptor) - .collect(Collectors.toSet()); - assertEquals(2, streamsInSnapshotState.size()); - assertTrue( - streamsInSnapshotState.contains(new StreamDescriptor().withName(MODELS_STREAM_NAME + "_random").withNamespace(randomSchema()))); - assertTrue(streamsInSnapshotState.contains(new StreamDescriptor().withName(MODELS_STREAM_NAME).withNamespace(getDatabaseName()))); - stateMessageEmittedAfterSecondSyncCompletion.getGlobal().getStreamStates().forEach(s -> { - final JsonNode streamState = s.getStreamState(); - assertFalse(streamState.has(STATE_TYPE_KEY)); - }); - } - - @Test - @Timeout(value = 60) - public void syncWouldWorkWithDBWithInvalidTimezone() throws Exception { - final String systemTimeZone = "@@system_time_zone"; - final JdbcDatabase jdbcDatabase = source().createDatabase(config()); - final Properties properties = MySqlCdcProperties.getDebeziumProperties(jdbcDatabase); - final String databaseTimezone = jdbcDatabase.unsafeQuery(String.format("SELECT %s;", systemTimeZone)).toList().get(0).get(systemTimeZone) - .asText(); - final String debeziumEngineTimezone = properties.getProperty("database.connectionTimeZone"); - - assertEquals(INVALID_TIMEZONE_CEST, databaseTimezone); - assertEquals("America/Los_Angeles", debeziumEngineTimezone); - - final AutoCloseableIterator read = source() - .read(config(), getConfiguredCatalog(), null); - - final List actualRecords = AutoCloseableIterators.toListAndClose(read); - - final Set recordMessages = extractRecordMessages(actualRecords); - final List stateMessages = extractStateMessages(actualRecords); - - assertExpectedRecords(new HashSet<>(MODEL_RECORDS), recordMessages); - assertExpectedStateMessages(stateMessages); - assertExpectedStateMessagesWithTotalCount(stateMessages, 6); - } - - @Test - public void testCompositeIndexInitialLoad() throws Exception { - // Simulate adding a composite index by modifying the catalog. - final ConfiguredAirbyteCatalog configuredCatalog = Jsons.clone(getConfiguredCatalog()); - final List> primaryKeys = configuredCatalog.getStreams().get(0).getStream().getSourceDefinedPrimaryKey(); - primaryKeys.add(List.of("make_id")); - - final AutoCloseableIterator read1 = source() - .read(config(), configuredCatalog, null); - - final List actualRecords1 = AutoCloseableIterators.toListAndClose(read1); - - final Set recordMessages1 = extractRecordMessages(actualRecords1); - final List stateMessages1 = extractStateMessages(actualRecords1); - assertExpectedRecords(new HashSet<>(MODEL_RECORDS), recordMessages1); - assertExpectedStateMessages(stateMessages1); - assertExpectedStateMessagesWithTotalCount(stateMessages1, 6); - - // Re-run the sync with state associated with record w/ id = 15 (second to last record). - // We expect to read 2 records, since in the case of a composite PK we issue a >= query. - // We also expect 3 state records. One associated with the pk state, one to signify end of initial - // load, and - // the last one indicating the cdc position we have synced until. - final JsonNode state = Jsons.jsonNode(Collections.singletonList(stateMessages1.get(4))); - final AutoCloseableIterator read2 = source() - .read(config(), configuredCatalog, state); - - final List actualRecords2 = AutoCloseableIterators.toListAndClose(read2); - final Set recordMessages2 = extractRecordMessages(actualRecords2); - final List stateMessages2 = extractStateMessages(actualRecords2); - - assertExpectedRecords(new HashSet<>(MODEL_RECORDS.subList(4, 6)), recordMessages2); - assertEquals(3, stateMessages2.size()); - // In the second sync (WASS case), the first state message is emitted via debezium use case, which - // should still have the pk state encoded within. The second state message emitted will contain - // state from the initial - // sync and the last (3rd) state message will not have any pk state as the initial sync can now be - // considered complete. - assertStateTypes(stateMessages2, 1); - } - - // Remove all timestamp related fields in shared state. We want to make sure other information will - // not change. - private void pruneSharedStateTimestamp(final JsonNode rootNode) throws Exception { - ObjectMapper mapper = new ObjectMapper(); - - // Navigate to the specific node - JsonNode historyNode = rootNode.path("state").path("mysql_db_history"); - if (historyNode.isMissingNode()) { - return; // Node not found, nothing to do - } - String historyJson = historyNode.asText(); - JsonNode historyJsonNode = mapper.readTree(historyJson); - - ObjectNode objectNode = (ObjectNode) historyJsonNode; - objectNode.remove("ts_ms"); - - if (objectNode.has("position") && objectNode.get("position").has("ts_sec")) { - ((ObjectNode) objectNode.get("position")).remove("ts_sec"); - } - - JsonNode offsetNode = rootNode.path("state").path("mysql_cdc_offset"); - JsonNode offsetJsonNode = mapper.readTree(offsetNode.asText()); - if (offsetJsonNode.has("ts_sec")) { - ((ObjectNode) offsetJsonNode).remove("ts_sec"); - } - - // Replace the original string with the modified one - ((ObjectNode) rootNode.path("state")).put("mysql_db_history", mapper.writeValueAsString(historyJsonNode)); - ((ObjectNode) rootNode.path("state")).put("mysql_cdc_offset", mapper.writeValueAsString(offsetJsonNode)); - } - - @Test - public void testTwoStreamSync() throws Exception { - // Add another stream models_2 and read that one as well. - final ConfiguredAirbyteCatalog configuredCatalog = Jsons.clone(getConfiguredCatalog()); - - final List MODEL_RECORDS_2 = ImmutableList.of( - Jsons.jsonNode(ImmutableMap.of(COL_ID, 110, COL_MAKE_ID, 1, COL_MODEL, "Fiesta-2")), - Jsons.jsonNode(ImmutableMap.of(COL_ID, 120, COL_MAKE_ID, 1, COL_MODEL, "Focus-2")), - Jsons.jsonNode(ImmutableMap.of(COL_ID, 130, COL_MAKE_ID, 1, COL_MODEL, "Ranger-2")), - Jsons.jsonNode(ImmutableMap.of(COL_ID, 140, COL_MAKE_ID, 2, COL_MODEL, "GLA-2")), - Jsons.jsonNode(ImmutableMap.of(COL_ID, 150, COL_MAKE_ID, 2, COL_MODEL, "A 220-2")), - Jsons.jsonNode(ImmutableMap.of(COL_ID, 160, COL_MAKE_ID, 2, COL_MODEL, "E 350-2"))); - - testdb.with(createTableSqlFmt(), getDatabaseName(), MODELS_STREAM_NAME + "_2", - columnClause(ImmutableMap.of(COL_ID, "INTEGER", COL_MAKE_ID, "INTEGER", COL_MODEL, "VARCHAR(200)"), Optional.of(COL_ID))); - - for (final JsonNode recordJson : MODEL_RECORDS_2) { - writeRecords(recordJson, getDatabaseName(), MODELS_STREAM_NAME + "_2", COL_ID, - COL_MAKE_ID, COL_MODEL); - } - - final ConfiguredAirbyteStream airbyteStream = new ConfiguredAirbyteStream() - .withStream(CatalogHelpers.createAirbyteStream( - MODELS_STREAM_NAME + "_2", - getDatabaseName(), - Field.of(COL_ID, JsonSchemaType.INTEGER), - Field.of(COL_MAKE_ID, JsonSchemaType.INTEGER), - Field.of(COL_MODEL, JsonSchemaType.STRING)) - .withSupportedSyncModes( - Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL)) - .withSourceDefinedPrimaryKey(List.of(List.of(COL_ID)))); - airbyteStream.setSyncMode(SyncMode.INCREMENTAL); - - final List streams = configuredCatalog.getStreams(); - streams.add(airbyteStream); - configuredCatalog.withStreams(streams); - - final AutoCloseableIterator read1 = source() - .read(config(), configuredCatalog, null); - final List actualRecords1 = AutoCloseableIterators.toListAndClose(read1); - - final Set recordMessages1 = extractRecordMessages(actualRecords1); - final List stateMessages1 = extractStateMessages(actualRecords1); - assertEquals(13, stateMessages1.size()); - assertExpectedStateMessagesWithTotalCount(stateMessages1, 12); - - JsonNode sharedState = null; - StreamDescriptor firstStreamInState = null; - for (int i = 0; i < stateMessages1.size(); i++) { - final AirbyteStateMessage stateMessage = stateMessages1.get(i); - assertEquals(AirbyteStateType.GLOBAL, stateMessage.getType()); - final AirbyteGlobalState global = stateMessage.getGlobal(); - assertNotNull(global.getSharedState()); - if (Objects.isNull(sharedState)) { - ObjectMapper mapper = new ObjectMapper(); - sharedState = mapper.valueToTree(global.getSharedState()); - pruneSharedStateTimestamp(sharedState); - } else { - ObjectMapper mapper = new ObjectMapper(); - var newSharedState = mapper.valueToTree(global.getSharedState()); - pruneSharedStateTimestamp(newSharedState); - assertEquals(sharedState, newSharedState); - } - - if (Objects.isNull(firstStreamInState)) { - assertEquals(1, global.getStreamStates().size()); - firstStreamInState = global.getStreamStates().get(0).getStreamDescriptor(); - } - - if (i <= 4) { - // First 4 state messages are pk state - assertEquals(1, global.getStreamStates().size()); - final AirbyteStreamState streamState = global.getStreamStates().get(0); - assertTrue(streamState.getStreamState().has(STATE_TYPE_KEY)); - assertEquals(PRIMARY_KEY_STATE_TYPE, streamState.getStreamState().get(STATE_TYPE_KEY).asText()); - } else if (i == 5) { - // 5th state message is the final state message emitted for the stream - assertEquals(1, global.getStreamStates().size()); - final AirbyteStreamState streamState = global.getStreamStates().get(0); - assertFalse(streamState.getStreamState().has(STATE_TYPE_KEY)); - } else if (i <= 10) { - // 6th to 10th is the primary_key state message for the 2nd stream but final state message for 1st - // stream - assertEquals(2, global.getStreamStates().size()); - final StreamDescriptor finalFirstStreamInState = firstStreamInState; - global.getStreamStates().forEach(c -> { - if (c.getStreamDescriptor().equals(finalFirstStreamInState)) { - assertFalse(c.getStreamState().has(STATE_TYPE_KEY)); - } else { - assertTrue(c.getStreamState().has(STATE_TYPE_KEY)); - assertEquals(PRIMARY_KEY_STATE_TYPE, c.getStreamState().get(STATE_TYPE_KEY).asText()); - } - }); - } else { - // last 2 state messages don't contain primary_key info cause primary_key sync should be complete - assertEquals(2, global.getStreamStates().size()); - global.getStreamStates().forEach(c -> assertFalse(c.getStreamState().has(STATE_TYPE_KEY))); - } - } - - final Set names = new HashSet<>(STREAM_NAMES); - names.add(MODELS_STREAM_NAME + "_2"); - assertExpectedRecords(Streams.concat(MODEL_RECORDS_2.stream(), MODEL_RECORDS.stream()) - .collect(Collectors.toSet()), - recordMessages1, - names, - names, - getDatabaseName()); - - assertEquals(new StreamDescriptor().withName(MODELS_STREAM_NAME).withNamespace(getDatabaseName()), firstStreamInState); - - // Triggering a sync with a primary_key state for 1 stream and complete state for other stream - final AutoCloseableIterator read2 = source() - .read(config(), configuredCatalog, Jsons.jsonNode(Collections.singletonList(stateMessages1.get(6)))); - final List actualRecords2 = AutoCloseableIterators.toListAndClose(read2); - - final List stateMessages2 = extractStateMessages(actualRecords2); - - assertEquals(6, stateMessages2.size()); - // State was reset to the 7th; thus 5 remaining records were expected to be reloaded. - assertExpectedStateMessagesWithTotalCount(stateMessages2, 5); - for (int i = 0; i < stateMessages2.size(); i++) { - final AirbyteStateMessage stateMessage = stateMessages2.get(i); - assertEquals(AirbyteStateType.GLOBAL, stateMessage.getType()); - final AirbyteGlobalState global = stateMessage.getGlobal(); - assertNotNull(global.getSharedState()); - assertEquals(2, global.getStreamStates().size()); - - if (i <= 4) { - final StreamDescriptor finalFirstStreamInState = firstStreamInState; - global.getStreamStates().forEach(c -> { - // First 5 state messages are primary_key state for the stream that didn't complete primary_key sync - // the first time - if (c.getStreamDescriptor().equals(finalFirstStreamInState)) { - assertFalse(c.getStreamState().has(STATE_TYPE_KEY)); - } else { - assertTrue(c.getStreamState().has(STATE_TYPE_KEY)); - assertEquals(PRIMARY_KEY_STATE_TYPE, c.getStreamState().get(STATE_TYPE_KEY).asText()); - } - }); - } else { - // last state messages doesn't contain primary_key info cause primary_key sync should be complete - global.getStreamStates().forEach(c -> assertFalse(c.getStreamState().has(STATE_TYPE_KEY))); - } - } - - final Set recordMessages2 = extractRecordMessages(actualRecords2); - assertEquals(5, recordMessages2.size()); - assertExpectedRecords(new HashSet<>(MODEL_RECORDS_2.subList(1, MODEL_RECORDS_2.size())), - recordMessages2, - names, - names, - getDatabaseName()); - } - - /** - * This test creates lots of tables increasing the schema history size above the limit of forcing - * the {@link AirbyteSchemaHistoryStorage#read()} method to compress the schema history blob as part - * of the state message which allows us to test that the next sync is able to work fine when - * provided with a compressed blob in the state. - */ - @Test - @Timeout(value = 120) - public void testCompressedSchemaHistory() throws Exception { - createTablesToIncreaseSchemaHistorySize(); - final AutoCloseableIterator firstBatchIterator = source() - .read(config(), getConfiguredCatalog(), null); - final List dataFromFirstBatch = AutoCloseableIterators - .toListAndClose(firstBatchIterator); - final AirbyteStateMessage lastStateMessageFromFirstBatch = Iterables.getLast(extractStateMessages(dataFromFirstBatch)); - assertNotNull(lastStateMessageFromFirstBatch.getGlobal().getSharedState()); - assertNotNull(lastStateMessageFromFirstBatch.getGlobal().getSharedState().get("state")); - assertNotNull(lastStateMessageFromFirstBatch.getGlobal().getSharedState().get("state").get(IS_COMPRESSED)); - assertNotNull(lastStateMessageFromFirstBatch.getGlobal().getSharedState().get("state").get(MYSQL_DB_HISTORY)); - assertNotNull(lastStateMessageFromFirstBatch.getGlobal().getSharedState().get("state").get(MYSQL_CDC_OFFSET)); - assertTrue(lastStateMessageFromFirstBatch.getGlobal().getSharedState().get("state").get(IS_COMPRESSED).asBoolean()); - - // INSERT records so that events are written to binlog and Debezium tries to parse them - final int recordsToCreate = 20; - // first batch of records. 20 created here and 6 created in setup method. - for (int recordsCreated = 0; recordsCreated < recordsToCreate; recordsCreated++) { - final JsonNode record = - Jsons.jsonNode(ImmutableMap - .of(COL_ID, 100 + recordsCreated, COL_MAKE_ID, 1, COL_MODEL, - "F-" + recordsCreated)); - writeModelRecord(record); - } - - final AutoCloseableIterator secondBatchIterator = source() - .read(config(), getConfiguredCatalog(), Jsons.jsonNode(Collections.singletonList(lastStateMessageFromFirstBatch))); - final List dataFromSecondBatch = AutoCloseableIterators - .toListAndClose(secondBatchIterator); - final AirbyteStateMessage lastStateMessageFromSecondBatch = Iterables.getLast(extractStateMessages(dataFromSecondBatch)); - assertNotNull(lastStateMessageFromSecondBatch.getGlobal().getSharedState()); - assertNotNull(lastStateMessageFromSecondBatch.getGlobal().getSharedState().get("state")); - assertNotNull(lastStateMessageFromSecondBatch.getGlobal().getSharedState().get("state").get(IS_COMPRESSED)); - assertNotNull(lastStateMessageFromSecondBatch.getGlobal().getSharedState().get("state").get(MYSQL_DB_HISTORY)); - assertNotNull(lastStateMessageFromSecondBatch.getGlobal().getSharedState().get("state").get(MYSQL_CDC_OFFSET)); - assertTrue(lastStateMessageFromSecondBatch.getGlobal().getSharedState().get("state").get(IS_COMPRESSED).asBoolean()); - - assertEquals(lastStateMessageFromFirstBatch.getGlobal().getSharedState().get("state").get(MYSQL_DB_HISTORY), - lastStateMessageFromSecondBatch.getGlobal().getSharedState().get("state").get(MYSQL_DB_HISTORY)); - - assertEquals(recordsToCreate, extractRecordMessages(dataFromSecondBatch).size()); - } - - private void writeDateRecords( - final JsonNode recordJson, - final String dbName, - final String streamName, - final String idCol, - final String dateCol) { - testdb.with("INSERT INTO `%s` .`%s` (%s, %s) VALUES (%s, %s);", dbName, streamName, - idCol, dateCol, - recordJson.get(idCol).asInt(), recordJson.get(dateCol).asText()); - } - - @Test - public void testInvalidDatetime_metaChangesPopulated() throws Exception { - final ConfiguredAirbyteCatalog configuredCatalog = Jsons.clone(getConfiguredCatalog()); - - // Add a datetime stream to the catalog - testdb - .withoutStrictMode() - .with(createTableSqlFmt(), getDatabaseName(), TEST_DATE_STREAM_NAME, - columnClause(ImmutableMap.of(COL_ID, "INTEGER", COL_DATE_TIME, "DATETIME"), Optional.of(COL_ID))); - - for (final JsonNode recordJson : DATE_TIME_RECORDS) { - writeDateRecords(recordJson, getDatabaseName(), TEST_DATE_STREAM_NAME, COL_ID, COL_DATE_TIME); - } - - final ConfiguredAirbyteStream airbyteStream = new ConfiguredAirbyteStream() - .withStream(CatalogHelpers.createAirbyteStream( - TEST_DATE_STREAM_NAME, - getDatabaseName(), - Field.of(COL_ID, JsonSchemaType.INTEGER), - Field.of(COL_DATE_TIME, JsonSchemaType.STRING_TIMESTAMP_WITHOUT_TIMEZONE)) - .withSupportedSyncModes( - Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL)) - .withSourceDefinedPrimaryKey(List.of(List.of(COL_ID)))); - airbyteStream.setSyncMode(SyncMode.INCREMENTAL); - - final List streams = new ArrayList<>(); - streams.add(airbyteStream); - configuredCatalog.withStreams(streams); - - final AutoCloseableIterator read1 = source() - .read(config(), configuredCatalog, null); - final List actualRecords = AutoCloseableIterators.toListAndClose(read1); - - // Sync is expected to succeed with one record. However, the meta changes column should be populated - // for this record - // as it is an invalid date. As a result, this field will be omitted as Airbyte is unable to - // serialize the source value. - final Set recordMessages = extractRecordMessages(actualRecords); - assertEquals(recordMessages.size(), 1); - final AirbyteRecordMessage invalidDateRecord = recordMessages.stream().findFirst().get(); - - final AirbyteRecordMessageMetaChange expectedChange = - new AirbyteRecordMessageMetaChange().withReason(Reason.SOURCE_SERIALIZATION_ERROR).withChange( - Change.NULLED).withField(COL_DATE_TIME); - final AirbyteRecordMessageMeta expectedMessageMeta = new AirbyteRecordMessageMeta().withChanges(List.of(expectedChange)); - assertEquals(expectedMessageMeta, invalidDateRecord.getMeta()); - - ObjectMapper mapper = new ObjectMapper(); - final JsonNode expectedDataWithoutCdcFields = mapper.readTree("{\"id\":120, \"CAR_DATE\":null}"); - removeCDCColumns((ObjectNode) invalidDateRecord.getData()); - assertEquals(expectedDataWithoutCdcFields, invalidDateRecord.getData()); - } - - private void createTablesToIncreaseSchemaHistorySize() { - for (int i = 0; i <= 200; i++) { - final String tableName = generateRandomStringOf32Characters(); - final StringBuilder createTableQuery = new StringBuilder("CREATE TABLE " + tableName + "("); - String firstCol = null; - for (int j = 1; j <= 250; j++) { - final String columnName = generateRandomStringOf32Characters(); - if (j == 1) { - firstCol = columnName; - - } - createTableQuery.append(columnName).append(" INTEGER, "); - } - createTableQuery.append("PRIMARY KEY (").append(firstCol).append("));"); - testdb.with(createTableQuery.toString()); - } - } - - private static String generateRandomStringOf32Characters() { - final String characters = "abcdefghijklmnopqrstuvwxyz"; - final int length = 32; - - final StringBuilder randomString = new StringBuilder(length); - - for (int i = 0; i < length; i++) { - final int index = RANDOM.nextInt(characters.length()); - final char randomChar = characters.charAt(index); - randomString.append(randomChar); - } - - return randomString.toString(); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/CdcMysqlSourceWithSpecialDbNameTest.java b/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/CdcMysqlSourceWithSpecialDbNameTest.java deleted file mode 100644 index 74dec8a9ce77..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/CdcMysqlSourceWithSpecialDbNameTest.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.BaseImage; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.ContainerModifier; -import org.testcontainers.containers.MySQLContainer; - -public class CdcMysqlSourceWithSpecialDbNameTest extends CdcMysqlSourceTest { - - @Override - protected MySQLTestDatabase createTestDatabase() { - var container = new MySQLContainerFactory().shared( - BaseImage.MYSQL_8.reference, - ContainerModifier.INVALID_TIMEZONE_CEST.methodName, - ContainerModifier.CUSTOM_NAME.methodName); - return new TestDatabaseWithInvalidDatabaseName(container) - .initialized() - .withCdcPermissions(); - } - - static class TestDatabaseWithInvalidDatabaseName extends MySQLTestDatabase { - - public static final String INVALID_DB_NAME = "invalid@name"; - - public TestDatabaseWithInvalidDatabaseName(MySQLContainer container) { - super(container); - } - - @Override - public String getDatabaseName() { - return withNamespace(INVALID_DB_NAME); - } - - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/CloudDeploymentMySqlSslTest.java b/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/CloudDeploymentMySqlSslTest.java deleted file mode 100644 index 9cc966b6b5df..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/CloudDeploymentMySqlSslTest.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.google.common.collect.ImmutableMap; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.cdk.integrations.base.Source; -import io.airbyte.cdk.integrations.base.ssh.SshBastionContainer; -import io.airbyte.cdk.integrations.base.ssh.SshHelpers; -import io.airbyte.cdk.integrations.base.ssh.SshTunnel; -import io.airbyte.commons.features.EnvVariableFeatureFlags; -import io.airbyte.commons.features.FeatureFlagsWrapper; -import io.airbyte.commons.json.Jsons; -import io.airbyte.commons.resources.MoreResources; -import io.airbyte.protocol.models.v0.AirbyteConnectionStatus; -import io.airbyte.protocol.models.v0.ConnectorSpecification; -import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -public class CloudDeploymentMySqlSslTest { - - private MySQLTestDatabase createTestDatabase(String... containerFactoryMethods) { - final var container = new MySQLContainerFactory().shared("mysql:8.0", containerFactoryMethods); - return new MySQLTestDatabase(container) - .withConnectionProperty("useSSL", "true") - .withConnectionProperty("requireSSL", "true") - .initialized(); - } - - private Source source() { - final var source = new MySqlSource(); - source.setFeatureFlags(FeatureFlagsWrapper.overridingDeploymentMode(new EnvVariableFeatureFlags(), "CLOUD")); - return MySqlSource.sshWrappedSource(source); - } - - @Test - void testSpec() throws Exception { - final ConnectorSpecification actual = source().spec(); - final ConnectorSpecification expected = - SshHelpers.injectSshIntoSpec(Jsons.deserialize(MoreResources.readResource("expected_cloud_spec.json"), ConnectorSpecification.class)); - assertEquals(expected, actual); - } - - @Test - void testStrictSSLUnsecuredNoTunnel() throws Exception { - try (final var testdb = createTestDatabase()) { - final var config = testdb.configBuilder() - .withHostAndPort() - .withDatabase() - .with(JdbcUtils.USERNAME_KEY, testdb.getUserName()) - .with(JdbcUtils.PASSWORD_KEY, "fake") - .with("tunnel_method", ImmutableMap.builder().put("tunnel_method", "NO_TUNNEL").build()) - .withSsl(ImmutableMap.builder() - .put(JdbcUtils.MODE_KEY, "preferred") - .build()) - .build(); - final AirbyteConnectionStatus actual = source().check(config); - assertEquals(AirbyteConnectionStatus.Status.FAILED, actual.getStatus()); - assertTrue(actual.getMessage().contains("Unsecured connection not allowed"), actual.getMessage()); - } - } - - @Test - void testStrictSSLSecuredNoTunnel() throws Exception { - final String PASSWORD = "Passw0rd"; - try (final var testdb = createTestDatabase("withRootAndServerCertificates", "withClientCertificate")) { - final var config = testdb.testConfigBuilder() - .with("tunnel_method", ImmutableMap.builder().put("tunnel_method", "NO_TUNNEL").build()) - .withSsl(ImmutableMap.builder() - .put(JdbcUtils.MODE_KEY, "verify_ca") - .put("ca_certificate", testdb.getCertificates().caCertificate()) - .put("client_certificate", testdb.getCertificates().clientCertificate()) - .put("client_key", testdb.getCertificates().clientKey()) - .put("client_key_password", PASSWORD) - .build()) - .build(); - final AirbyteConnectionStatus actual = source().check(config); - assertEquals(AirbyteConnectionStatus.Status.FAILED, actual.getStatus()); - assertTrue(actual.getMessage().contains("Failed to create keystore for Client certificate"), actual.getMessage()); - } - } - - @Test - void testStrictSSLSecuredWithTunnel() throws Exception { - final String PASSWORD = "Passw0rd"; - try (final var testdb = createTestDatabase("withRootAndServerCertificates", "withClientCertificate")) { - final var config = testdb.configBuilder() - .withHostAndPort() - .withDatabase() - .with(JdbcUtils.USERNAME_KEY, testdb.getUserName()) - .with(JdbcUtils.PASSWORD_KEY, "fake") - .withSsl(ImmutableMap.builder() - .put(JdbcUtils.MODE_KEY, "verify_ca") - .put("ca_certificate", testdb.getCertificates().caCertificate()) - .put("client_certificate", testdb.getCertificates().clientCertificate()) - .put("client_key", testdb.getCertificates().clientKey()) - .put("client_key_password", PASSWORD) - .build()) - .with("tunnel_method", ImmutableMap.builder().put("tunnel_method", "SSH_KEY_AUTH").build()) - .build(); - final AirbyteConnectionStatus actual = source().check(config); - assertEquals(AirbyteConnectionStatus.Status.FAILED, actual.getStatus()); - assertTrue(actual.getMessage().contains("Could not connect with provided SSH configuration."), actual.getMessage()); - } - } - - @Test - void testStrictSSLUnsecuredWithTunnel() throws Exception { - try (final var testdb = createTestDatabase()) { - final var config = testdb.configBuilder() - .withHostAndPort() - .withDatabase() - .with(JdbcUtils.USERNAME_KEY, testdb.getUserName()) - .with(JdbcUtils.PASSWORD_KEY, "fake") - .withSsl(ImmutableMap.builder() - .put(JdbcUtils.MODE_KEY, "preferred") - .build()) - .with("tunnel_method", ImmutableMap.builder().put("tunnel_method", "SSH_KEY_AUTH").build()) - .build(); - final AirbyteConnectionStatus actual = source().check(config); - assertEquals(AirbyteConnectionStatus.Status.FAILED, actual.getStatus()); - assertTrue(actual.getMessage().contains("Could not connect with provided SSH configuration."), actual.getMessage()); - } - } - - @Test - @Timeout(value = 5, - unit = TimeUnit.MINUTES) - void testCheckWithSslModeDisabled() throws Exception { - try (final var testdb = createTestDatabase("withNetwork")) { - try (final SshBastionContainer bastion = new SshBastionContainer()) { - bastion.initAndStartBastion(testdb.getContainer().getNetwork()); - final var config = testdb.integrationTestConfigBuilder() - .with("tunnel_method", bastion.getTunnelMethod(SshTunnel.TunnelMethod.SSH_PASSWORD_AUTH, false)) - .withoutSsl() - .build(); - final AirbyteConnectionStatus actual = source().check(config); - assertEquals(AirbyteConnectionStatus.Status.SUCCEEDED, actual.getStatus()); - } - } - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlDebugger.java b/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlDebugger.java deleted file mode 100644 index 67c8f4d68687..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlDebugger.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ -package io.airbyte.integrations.source.mysql; - -import io.airbyte.cdk.integrations.debug.DebugUtil; - -public class MySqlDebugger { - - @SuppressWarnings({"unchecked", "deprecation", "resource"}) - public static void main(final String[] args) throws Exception { - final MySqlSource mysqlSource = new MySqlSource(); - DebugUtil.debug(mysqlSource); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlInitialLoadHandlerTest.java b/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlInitialLoadHandlerTest.java deleted file mode 100644 index 7f09a54fcffb..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlInitialLoadHandlerTest.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import io.airbyte.integrations.source.mysql.MySqlQueryUtils.TableSizeInfo; -import io.airbyte.integrations.source.mysql.initialsync.MySqlInitialLoadHandler; -import io.airbyte.protocol.models.AirbyteStreamNameNamespacePair; -import org.junit.jupiter.api.Test; - -public class MySqlInitialLoadHandlerTest { - - private static final long ONE_GB = 1_073_741_824; - private static final long ONE_MB = 1_048_576; - - @Test - void testInvalidOrNullTableSizeInfo() { - final AirbyteStreamNameNamespacePair pair = new AirbyteStreamNameNamespacePair("table_name", "schema_name"); - assertEquals(MySqlInitialLoadHandler.calculateChunkSize(null, pair), 1_000_000L); - final TableSizeInfo invalidRowLengthInfo = new TableSizeInfo(ONE_GB, 0L); - assertEquals(MySqlInitialLoadHandler.calculateChunkSize(invalidRowLengthInfo, pair), 1_000_000L); - final TableSizeInfo invalidTableSizeInfo = new TableSizeInfo(0L, 0L); - assertEquals(MySqlInitialLoadHandler.calculateChunkSize(invalidTableSizeInfo, pair), 1_000_000L); - } - - @Test - void testTableSizeInfo() { - final AirbyteStreamNameNamespacePair pair = new AirbyteStreamNameNamespacePair("table_name", "schema_name"); - assertEquals(MySqlInitialLoadHandler.calculateChunkSize(new TableSizeInfo(ONE_GB, 2 * ONE_MB), pair), 512L); - assertEquals(MySqlInitialLoadHandler.calculateChunkSize(new TableSizeInfo(ONE_GB, 200L), pair), 5368709L); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlJdbcSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlJdbcSourceAcceptanceTest.java deleted file mode 100644 index d1ec0aacb680..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlJdbcSourceAcceptanceTest.java +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -import static io.airbyte.cdk.integrations.debezium.DebeziumIteratorConstants.SYNC_CHECKPOINT_RECORDS_PROPERTY; -import static io.airbyte.integrations.source.mysql.initialsync.MySqlInitialLoadStateManager.STATE_TYPE_KEY; -import static java.util.stream.Collectors.toList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.cdk.integrations.source.jdbc.test.JdbcSourceAcceptanceTest; -import io.airbyte.cdk.integrations.source.relationaldb.models.DbStreamState; -import io.airbyte.commons.json.Jsons; -import io.airbyte.commons.resources.MoreResources; -import io.airbyte.commons.util.MoreIterators; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.BaseImage; -import io.airbyte.integrations.source.mysql.internal.models.CursorBasedStatus; -import io.airbyte.integrations.source.mysql.internal.models.InternalModels.StateType; -import io.airbyte.protocol.models.Field; -import io.airbyte.protocol.models.JsonSchemaType; -import io.airbyte.protocol.models.v0.AirbyteCatalog; -import io.airbyte.protocol.models.v0.AirbyteConnectionStatus; -import io.airbyte.protocol.models.v0.AirbyteMessage; -import io.airbyte.protocol.models.v0.AirbyteMessage.Type; -import io.airbyte.protocol.models.v0.AirbyteRecordMessage; -import io.airbyte.protocol.models.v0.AirbyteStateMessage; -import io.airbyte.protocol.models.v0.AirbyteStateMessage.AirbyteStateType; -import io.airbyte.protocol.models.v0.AirbyteStateStats; -import io.airbyte.protocol.models.v0.AirbyteStream; -import io.airbyte.protocol.models.v0.AirbyteStreamState; -import io.airbyte.protocol.models.v0.CatalogHelpers; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; -import io.airbyte.protocol.models.v0.ConnectorSpecification; -import io.airbyte.protocol.models.v0.DestinationSyncMode; -import io.airbyte.protocol.models.v0.StreamDescriptor; -import io.airbyte.protocol.models.v0.SyncMode; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; - -@Order(2) -@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NP_NULL_ON_SOME_PATH") -class MySqlJdbcSourceAcceptanceTest extends JdbcSourceAcceptanceTest { - - protected static final String USERNAME_WITHOUT_PERMISSION = "new_user"; - protected static final String PASSWORD_WITHOUT_PERMISSION = "new_password"; - - @Override - protected JsonNode config() { - return testdb.testConfigBuilder().build(); - } - - @Override - protected MySqlSource source() { - return new MySqlSource(); - } - - @Override - protected MySQLTestDatabase createTestDatabase() { - return MySQLTestDatabase.in(BaseImage.MYSQL_8); - } - - @Override - protected void maybeSetShorterConnectionTimeout(final JsonNode config) { - ((ObjectNode) config).put(JdbcUtils.JDBC_URL_PARAMS_KEY, "connectTimeout=1000"); - } - - // MySql does not support schemas in the way most dbs do. Instead we namespace by db name. - @Override - protected boolean supportsSchemas() { - return false; - } - - @Override - protected void validateFullRefreshStateMessageReadSuccess(final List stateMessages) { - var finalStateMessage = stateMessages.get(stateMessages.size() - 1); - assertEquals( - finalStateMessage.getStream().getStreamState().get("state_type").textValue(), - "primary_key"); - assertEquals(finalStateMessage.getStream().getStreamState().get("pk_name").textValue(), "id"); - assertEquals(finalStateMessage.getStream().getStreamState().get("pk_val").textValue(), "3"); - } - - @Test - @Override - protected void testReadMultipleTablesIncrementally() throws Exception { - final var config = config(); - ((ObjectNode) config).put(SYNC_CHECKPOINT_RECORDS_PROPERTY, 1); - final String streamOneName = TABLE_NAME + "one"; - // Create a fresh first table - testdb.with("CREATE TABLE %s (\n" - + " id int PRIMARY KEY,\n" - + " name VARCHAR(200) NOT NULL,\n" - + " updated_at VARCHAR(200) NOT NULL\n" - + ");", streamOneName) - .with("INSERT INTO %s(id, name, updated_at) VALUES (1,'picard', '2004-10-19')", - getFullyQualifiedTableName(streamOneName)) - .with("INSERT INTO %s(id, name, updated_at) VALUES (2, 'crusher', '2005-10-19')", - getFullyQualifiedTableName(streamOneName)) - .with("INSERT INTO %s(id, name, updated_at) VALUES (3, 'vash', '2006-10-19')", - getFullyQualifiedTableName(streamOneName)); - - // Create a fresh second table - final String streamTwoName = TABLE_NAME + "two"; - final String streamTwoFullyQualifiedName = getFullyQualifiedTableName(streamTwoName); - // Insert records into second table - testdb.with("CREATE TABLE %s (\n" - + " id int PRIMARY KEY,\n" - + " name VARCHAR(200) NOT NULL,\n" - + " updated_at DATE NOT NULL\n" - + ");", streamTwoName) - .with("INSERT INTO %s(id, name, updated_at) VALUES (40,'Jean Luc','2006-10-19')", - streamTwoFullyQualifiedName) - .with("INSERT INTO %s(id, name, updated_at) VALUES (41, 'Groot', '2006-10-19')", - streamTwoFullyQualifiedName) - .with("INSERT INTO %s(id, name, updated_at) VALUES (42, 'Thanos','2006-10-19')", - streamTwoFullyQualifiedName); - - // Create records list that we expect to see in the state message - final List streamTwoExpectedRecords = Arrays.asList( - createRecord(streamTwoName, getDefaultNamespace(), ImmutableMap.of( - COL_ID, 40, - COL_NAME, "Jean Luc", - COL_UPDATED_AT, "2006-10-19")), - createRecord(streamTwoName, getDefaultNamespace(), ImmutableMap.of( - COL_ID, 41, - COL_NAME, "Groot", - COL_UPDATED_AT, "2006-10-19")), - createRecord(streamTwoName, getDefaultNamespace(), ImmutableMap.of( - COL_ID, 42, - COL_NAME, "Thanos", - COL_UPDATED_AT, "2006-10-19"))); - - // Prep and create a configured catalog to perform sync - final AirbyteStream streamOne = getAirbyteStream(streamOneName, getDefaultNamespace()); - final AirbyteStream streamTwo = getAirbyteStream(streamTwoName, getDefaultNamespace()); - - final ConfiguredAirbyteCatalog configuredCatalog = CatalogHelpers.toDefaultConfiguredCatalog( - new AirbyteCatalog().withStreams(List.of(streamOne, streamTwo))); - configuredCatalog.getStreams().forEach(airbyteStream -> { - airbyteStream.setSyncMode(SyncMode.INCREMENTAL); - airbyteStream.setCursorField(List.of(COL_ID)); - airbyteStream.setDestinationSyncMode(DestinationSyncMode.APPEND); - airbyteStream.withPrimaryKey(List.of(List.of(COL_ID))); - }); - - // Perform initial sync - final List messagesFromFirstSync = MoreIterators - .toList(source().read(config, configuredCatalog, null)); - - final List recordsFromFirstSync = filterRecords(messagesFromFirstSync); - - setEmittedAtToNull(messagesFromFirstSync); - // All records in the 2 configured streams should be present - assertThat(filterRecords(recordsFromFirstSync)).containsExactlyElementsOf( - Stream.concat(getTestMessages(streamOneName).stream().parallel(), - streamTwoExpectedRecords.stream().parallel()).collect(toList())); - - final List actualFirstSyncState = extractStateMessage(messagesFromFirstSync); - // Since we are emitting a state message after each record, we should have 1 state for each record - - // 3 from stream1 and 3 from stream2 - assertEquals(6, actualFirstSyncState.size()); - - // The expected state type should be 2 primaryKey's and the last one being standard - final List expectedStateTypesFromFirstSync = List.of("primary_key", "primary_key", "cursor_based"); - final List stateTypeOfStreamOneStatesFromFirstSync = - extractSpecificFieldFromCombinedMessages(messagesFromFirstSync, streamOneName, STATE_TYPE_KEY); - final List stateTypeOfStreamTwoStatesFromFirstSync = - extractSpecificFieldFromCombinedMessages(messagesFromFirstSync, streamTwoName, STATE_TYPE_KEY); - // It should be the same for stream1 and stream2 - assertEquals(stateTypeOfStreamOneStatesFromFirstSync, expectedStateTypesFromFirstSync); - assertEquals(stateTypeOfStreamTwoStatesFromFirstSync, expectedStateTypesFromFirstSync); - - // Create the expected primaryKeys that we should see - final List expectedPrimaryKeysFromFirstSync = List.of("1", "2"); - final List primaryKeyFromStreamOneStatesFromFirstSync = - extractSpecificFieldFromCombinedMessages(messagesFromFirstSync, streamOneName, "pk_val"); - final List primaryKeyFromStreamTwoStatesFromFirstSync = - extractSpecificFieldFromCombinedMessages(messagesFromFirstSync, streamOneName, "pk_val"); - - // Verifying each element and its index to match. - // Only checking the first 2 elements since we have verified that the last state_type is - // "cursor_based" - assertEquals(primaryKeyFromStreamOneStatesFromFirstSync.get(0), expectedPrimaryKeysFromFirstSync.get(0)); - assertEquals(primaryKeyFromStreamOneStatesFromFirstSync.get(1), expectedPrimaryKeysFromFirstSync.get(1)); - assertEquals(primaryKeyFromStreamTwoStatesFromFirstSync.get(0), expectedPrimaryKeysFromFirstSync.get(0)); - assertEquals(primaryKeyFromStreamTwoStatesFromFirstSync.get(1), expectedPrimaryKeysFromFirstSync.get(1)); - - // Extract only state messages for each stream - final List streamOneStateMessagesFromFirstSync = extractStateMessage(messagesFromFirstSync, streamOneName); - final List streamTwoStateMessagesFromFirstSync = extractStateMessage(messagesFromFirstSync, streamTwoName); - - // Extract the incremental states of each stream's first and second state message - final List streamOneIncrementalStatesFromFirstSync = - List.of(streamOneStateMessagesFromFirstSync.get(0).getStream().getStreamState().get("incremental_state"), - streamOneStateMessagesFromFirstSync.get(1).getStream().getStreamState().get("incremental_state")); - final JsonNode streamOneFinalStreamStateFromFirstSync = streamOneStateMessagesFromFirstSync.get(2).getStream().getStreamState(); - - final List streamTwoIncrementalStatesFromFirstSync = - List.of(streamTwoStateMessagesFromFirstSync.get(0).getStream().getStreamState().get("incremental_state"), - streamTwoStateMessagesFromFirstSync.get(1).getStream().getStreamState().get("incremental_state")); - final JsonNode streamTwoFinalStreamStateFromFirstSync = streamTwoStateMessagesFromFirstSync.get(2).getStream().getStreamState(); - - // The incremental_state of each stream's first and second incremental states is expected - // to be identical to the stream_state of the final state message for each stream - assertEquals(streamOneIncrementalStatesFromFirstSync.get(0), streamOneFinalStreamStateFromFirstSync); - assertEquals(streamOneIncrementalStatesFromFirstSync.get(1), streamOneFinalStreamStateFromFirstSync); - assertEquals(streamTwoIncrementalStatesFromFirstSync.get(0), streamTwoFinalStreamStateFromFirstSync); - assertEquals(streamTwoIncrementalStatesFromFirstSync.get(1), streamTwoFinalStreamStateFromFirstSync); - - // Sync should work with a primaryKey state AND a cursor-based state from each stream - // Forcing a sync with - // - stream one state still being the first record read via Primary Key. - // - stream two state being the Primary Key state before the final emitted state before the cursor - // switch - final List messagesFromSecondSyncWithMixedStates = MoreIterators - .toList(source().read(config, configuredCatalog, - Jsons.jsonNode(List.of(streamOneStateMessagesFromFirstSync.get(0), - streamTwoStateMessagesFromFirstSync.get(1))))); - - // Extract only state messages for each stream after second sync - final List streamOneStateMessagesFromSecondSync = - extractStateMessage(messagesFromSecondSyncWithMixedStates, streamOneName); - final List stateTypeOfStreamOneStatesFromSecondSync = - extractSpecificFieldFromCombinedMessages(messagesFromSecondSyncWithMixedStates, streamOneName, STATE_TYPE_KEY); - - final List streamTwoStateMessagesFromSecondSync = - extractStateMessage(messagesFromSecondSyncWithMixedStates, streamTwoName); - final List stateTypeOfStreamTwoStatesFromSecondSync = - extractSpecificFieldFromCombinedMessages(messagesFromSecondSyncWithMixedStates, streamTwoName, STATE_TYPE_KEY); - - // Stream One states after the second sync are expected to have 2 stream states - // - 1 with PrimaryKey state_type and 1 state that is of cursorBased state type - assertEquals(2, streamOneStateMessagesFromSecondSync.size()); - assertEquals(List.of("primary_key", "cursor_based"), stateTypeOfStreamOneStatesFromSecondSync); - - // Stream Two states after the second sync are expected to have 1 stream state - // - The state that is of cursorBased state type - assertEquals(1, streamTwoStateMessagesFromSecondSync.size()); - assertEquals(List.of("cursor_based"), stateTypeOfStreamTwoStatesFromSecondSync); - - // Add some data to each table and perform a third read. - // Expect to see all records be synced via cursorBased method and not primaryKey - testdb.with("INSERT INTO %s(id, name, updated_at) VALUES (4,'Hooper','2006-10-19')", - getFullyQualifiedTableName(streamOneName)) - .with("INSERT INTO %s(id, name, updated_at) VALUES (43, 'Iron Man', '2006-10-19')", - streamTwoFullyQualifiedName); - - final List messagesFromThirdSync = MoreIterators - .toList(source().read(config, configuredCatalog, - Jsons.jsonNode(List.of(streamOneStateMessagesFromSecondSync.get(1), - streamTwoStateMessagesFromSecondSync.get(0))))); - - // Extract only state messages, state type, and cursor for each stream after second sync - final List streamOneStateMessagesFromThirdSync = - extractStateMessage(messagesFromThirdSync, streamOneName); - final List stateTypeOfStreamOneStatesFromThirdSync = - extractSpecificFieldFromCombinedMessages(messagesFromThirdSync, streamOneName, STATE_TYPE_KEY); - final List cursorOfStreamOneStatesFromThirdSync = - extractSpecificFieldFromCombinedMessages(messagesFromThirdSync, streamOneName, "cursor"); - - final List streamTwoStateMessagesFromThirdSync = - extractStateMessage(messagesFromThirdSync, streamTwoName); - final List stateTypeOfStreamTwoStatesFromThirdSync = - extractSpecificFieldFromCombinedMessages(messagesFromThirdSync, streamTwoName, STATE_TYPE_KEY); - final List cursorOfStreamTwoStatesFromThirdSync = - extractSpecificFieldFromCombinedMessages(messagesFromThirdSync, streamTwoName, "cursor"); - - // Both streams should now be synced via standard cursor and have updated max cursor values - // cursor: 4 for stream one - // cursor: 43 for stream two - assertEquals(1, streamOneStateMessagesFromThirdSync.size()); - assertEquals(List.of("cursor_based"), stateTypeOfStreamOneStatesFromThirdSync); - assertEquals(List.of("4"), cursorOfStreamOneStatesFromThirdSync); - - assertEquals(1, streamTwoStateMessagesFromThirdSync.size()); - assertEquals(List.of("cursor_based"), stateTypeOfStreamTwoStatesFromThirdSync); - assertEquals(List.of("43"), cursorOfStreamTwoStatesFromThirdSync); - } - - @Test - public void testSpec() throws Exception { - final ConnectorSpecification actual = source().spec(); - final ConnectorSpecification expected = Jsons.deserialize(MoreResources.readResource("spec.json"), ConnectorSpecification.class); - - assertEquals(expected, actual); - } - - /** - * MySQL Error Codes: - *

- * https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-error-sqlstates.html - *

- * - * @throws Exception - */ - @Test - void testCheckIncorrectPasswordFailure() throws Exception { - final var config = config(); - maybeSetShorterConnectionTimeout(config); - ((ObjectNode) config).put(JdbcUtils.PASSWORD_KEY, "fake"); - final AirbyteConnectionStatus status = source().check(config); - assertEquals(AirbyteConnectionStatus.Status.FAILED, status.getStatus()); - assertTrue(status.getMessage().contains("State code: 08001;"), status.getMessage()); - } - - @Test - public void testCheckIncorrectUsernameFailure() throws Exception { - final var config = config(); - maybeSetShorterConnectionTimeout(config); - ((ObjectNode) config).put(JdbcUtils.USERNAME_KEY, "fake"); - final AirbyteConnectionStatus status = source().check(config); - assertEquals(AirbyteConnectionStatus.Status.FAILED, status.getStatus()); - // do not test for message since there seems to be flakiness where sometimes the test will get the - // message with - // State code: 08001 or State code: 28000 - } - - @Test - public void testCheckIncorrectHostFailure() throws Exception { - final var config = config(); - maybeSetShorterConnectionTimeout(config); - ((ObjectNode) config).put(JdbcUtils.HOST_KEY, "localhost2"); - final AirbyteConnectionStatus status = source().check(config); - assertEquals(AirbyteConnectionStatus.Status.FAILED, status.getStatus()); - assertTrue(status.getMessage().contains("State code: 08S01;"), status.getMessage()); - } - - @Test - public void testCheckIncorrectPortFailure() throws Exception { - final var config = config(); - maybeSetShorterConnectionTimeout(config); - ((ObjectNode) config).put(JdbcUtils.PORT_KEY, "0000"); - final AirbyteConnectionStatus status = source().check(config); - assertEquals(AirbyteConnectionStatus.Status.FAILED, status.getStatus()); - assertTrue(status.getMessage().contains("State code: 08S01;"), status.getMessage()); - } - - @Test - public void testCheckIncorrectDataBaseFailure() throws Exception { - final var config = config(); - maybeSetShorterConnectionTimeout(config); - ((ObjectNode) config).put(JdbcUtils.DATABASE_KEY, "wrongdatabase"); - final AirbyteConnectionStatus status = source().check(config); - assertEquals(AirbyteConnectionStatus.Status.FAILED, status.getStatus()); - assertTrue(status.getMessage().contains("State code: 42000; Error code: 1049;"), status.getMessage()); - } - - @Test - public void testUserHasNoPermissionToDataBase() throws Exception { - final var config = config(); - maybeSetShorterConnectionTimeout(config); - final String usernameWithoutPermission = testdb.withNamespace(USERNAME_WITHOUT_PERMISSION); - testdb.with("CREATE USER '%s'@'%%' IDENTIFIED BY '%s';", usernameWithoutPermission, PASSWORD_WITHOUT_PERMISSION); - ((ObjectNode) config).put(JdbcUtils.USERNAME_KEY, usernameWithoutPermission); - ((ObjectNode) config).put(JdbcUtils.PASSWORD_KEY, PASSWORD_WITHOUT_PERMISSION); - final AirbyteConnectionStatus status = source().check(config); - assertEquals(AirbyteConnectionStatus.Status.FAILED, status.getStatus()); - assertTrue(status.getMessage().contains("State code: 08001;"), status.getMessage()); - } - - @Test - public void testFullRefresh() throws Exception { - - } - - @Override - protected DbStreamState buildStreamState(final ConfiguredAirbyteStream configuredAirbyteStream, - final String cursorField, - final String cursorValue) { - return new CursorBasedStatus().withStateType(StateType.CURSOR_BASED).withVersion(2L) - .withStreamName(configuredAirbyteStream.getStream().getName()) - .withStreamNamespace(configuredAirbyteStream.getStream().getNamespace()) - .withCursorField(List.of(cursorField)) - .withCursor(cursorValue) - .withCursorRecordCount(1L); - } - - @Override - protected List getExpectedAirbyteMessagesSecondSync(final String namespace) { - final List expectedMessages = new ArrayList<>(); - expectedMessages.add(new AirbyteMessage().withType(Type.RECORD) - .withRecord(new AirbyteRecordMessage().withStream(streamName()).withNamespace(namespace) - .withData(Jsons.jsonNode(ImmutableMap - .of(COL_ID, ID_VALUE_4, - COL_NAME, "riker", - COL_UPDATED_AT, "2006-10-19"))))); - expectedMessages.add(new AirbyteMessage().withType(Type.RECORD) - .withRecord(new AirbyteRecordMessage().withStream(streamName()).withNamespace(namespace) - .withData(Jsons.jsonNode(ImmutableMap - .of(COL_ID, ID_VALUE_5, - COL_NAME, "data", - COL_UPDATED_AT, "2006-10-19"))))); - final DbStreamState state = new CursorBasedStatus() - .withStateType(StateType.CURSOR_BASED) - .withVersion(2L) - .withStreamName(streamName()) - .withStreamNamespace(namespace) - .withCursorField(ImmutableList.of(COL_ID)) - .withCursor("5") - .withCursorRecordCount(1L); - - expectedMessages.addAll(createExpectedTestMessages(List.of(state), 2L)); - return expectedMessages; - } - - @Override - protected List getTestMessages() { - return getTestMessages(streamName()); - } - - protected List getTestMessages(final String streamName) { - return List.of( - new AirbyteMessage().withType(Type.RECORD) - .withRecord(new AirbyteRecordMessage().withStream(streamName).withNamespace(getDefaultNamespace()) - .withData(Jsons.jsonNode(Map - .of(COL_ID, ID_VALUE_1, - COL_NAME, "picard", - COL_UPDATED_AT, "2004-10-19")))), - new AirbyteMessage().withType(Type.RECORD) - .withRecord(new AirbyteRecordMessage().withStream(streamName).withNamespace(getDefaultNamespace()) - .withData(Jsons.jsonNode(Map - .of(COL_ID, ID_VALUE_2, - COL_NAME, "crusher", - COL_UPDATED_AT, - "2005-10-19")))), - new AirbyteMessage().withType(Type.RECORD) - .withRecord(new AirbyteRecordMessage().withStream(streamName).withNamespace(getDefaultNamespace()) - .withData(Jsons.jsonNode(Map - .of(COL_ID, ID_VALUE_3, - COL_NAME, "vash", - COL_UPDATED_AT, "2006-10-19"))))); - } - - private AirbyteStream getAirbyteStream(final String tableName, final String namespace) { - return CatalogHelpers.createAirbyteStream( - tableName, - namespace, - Field.of(COL_ID, JsonSchemaType.INTEGER), - Field.of(COL_NAME, JsonSchemaType.STRING), - Field.of(COL_UPDATED_AT, JsonSchemaType.STRING_DATE)) - .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL)) - .withSourceDefinedPrimaryKey(List.of(List.of(COL_ID))); - } - - @Override - protected AirbyteCatalog getCatalog(final String defaultNamespace) { - return new AirbyteCatalog().withStreams(Lists.newArrayList( - CatalogHelpers.createAirbyteStream( - TABLE_NAME, - defaultNamespace, - Field.of(COL_ID, JsonSchemaType.INTEGER), - Field.of(COL_NAME, JsonSchemaType.STRING), - Field.of(COL_UPDATED_AT, JsonSchemaType.STRING_DATE)) - .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL)) - .withSourceDefinedPrimaryKey(List.of(List.of(COL_ID))) - .withIsResumable(true), - CatalogHelpers.createAirbyteStream( - TABLE_NAME_WITHOUT_PK, - defaultNamespace, - Field.of(COL_ID, JsonSchemaType.INTEGER), - Field.of(COL_NAME, JsonSchemaType.STRING), - Field.of(COL_UPDATED_AT, JsonSchemaType.STRING_DATE)) - .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL)) - .withSourceDefinedPrimaryKey(Collections.emptyList()) - .withIsResumable(false), - CatalogHelpers.createAirbyteStream( - TABLE_NAME_COMPOSITE_PK, - defaultNamespace, - Field.of(COL_FIRST_NAME, JsonSchemaType.STRING), - Field.of(COL_LAST_NAME, JsonSchemaType.STRING), - Field.of(COL_UPDATED_AT, JsonSchemaType.STRING_DATE)) - .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL)) - .withSourceDefinedPrimaryKey( - List.of(List.of(COL_FIRST_NAME), List.of(COL_LAST_NAME))) - .withIsResumable(true))); - } - - // Override from parent class as we're no longer including the legacy Data field. - @Override - protected List createExpectedTestMessages(final List states, final long numRecords) { - return states.stream() - .map(s -> new AirbyteMessage().withType(Type.STATE) - .withState( - new AirbyteStateMessage().withType(AirbyteStateType.STREAM) - .withStream(new AirbyteStreamState() - .withStreamDescriptor(new StreamDescriptor().withNamespace(s.getStreamNamespace()).withName(s.getStreamName())) - .withStreamState(Jsons.jsonNode(s))) - .withSourceStats(new AirbyteStateStats().withRecordCount((double) numRecords)))) - .collect( - Collectors.toList()); - } - - @Override - protected List createState(final List states) { - return states.stream() - .map(s -> new AirbyteStateMessage().withType(AirbyteStateType.STREAM) - .withStream(new AirbyteStreamState() - .withStreamDescriptor(new StreamDescriptor().withNamespace(s.getStreamNamespace()).withName(s.getStreamName())) - .withStreamState(Jsons.jsonNode(s)))) - .collect( - Collectors.toList()); - } - - @Override - protected JsonNode getStateData(final AirbyteMessage airbyteMessage, final String streamName) { - final JsonNode streamState = airbyteMessage.getState().getStream().getStreamState(); - if (streamState.get("stream_name").asText().equals(streamName)) { - return streamState; - } - - throw new IllegalArgumentException("Stream not found in state message: " + streamName); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlSourceOperationsTest.java b/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlSourceOperationsTest.java deleted file mode 100644 index b989e2163c84..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlSourceOperationsTest.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsInAnyOrder; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.mysql.cj.MysqlType; -import io.airbyte.cdk.db.jdbc.DateTimeConverter; -import io.airbyte.commons.json.Jsons; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.BaseImage; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.function.Function; -import java.util.function.IntFunction; -import org.junit.jupiter.api.Test; - -public class MySqlSourceOperationsTest { - - @Test - public void dateColumnAsCursor() throws SQLException { - testImpl( - "DATE", - i -> LocalDate.of(2019, 1, i), - DateTimeConverter::convertToDate, - LocalDate::toString, - MysqlType.DATE, - DateTimeConverter.convertToDate(LocalDate.of(2019, 1, 1)), - "2019-01-01T00:00:00Z"); - } - - @Test - public void timeColumnAsCursor() throws SQLException { - testImpl( - "TIME", - i -> LocalTime.of(20, i, 0), - DateTimeConverter::convertToTime, - LocalTime::toString, - MysqlType.TIME, - DateTimeConverter.convertToTime(LocalTime.of(20, 1, 0)), - "1970-01-01T20:01:00Z"); - } - - @Test - public void dateTimeColumnAsCursor() throws SQLException { - testImpl( - "DATETIME", - i -> LocalDateTime.of(2019, i, 20, 3, 0, 0), - DateTimeConverter::convertToTimestamp, - LocalDateTime::toString, - MysqlType.DATETIME, - DateTimeConverter.convertToTimestamp(LocalDateTime.of(2019, 1, 20, 3, 0, 0)), - "2019-01-20T03:00:00.000000"); - } - - @Test - public void timestampColumnAsCursor() throws SQLException { - testImpl( - "TIMESTAMP", - i -> Instant.ofEpochSecond(1660298508L).plusSeconds(i - 1), - DateTimeConverter::convertToTimestampWithTimezone, - r -> Timestamp.from(r).toString(), - MysqlType.TIMESTAMP, - DateTimeConverter.convertToTimestampWithTimezone(Instant.ofEpochSecond(1660298508L)), - Instant.ofEpochSecond(1660298508L).toString()); - } - - private void testImpl( - final String sqlType, - IntFunction recordBuilder, - Function airbyteRecordStringifier, - Function sqlRecordStringifier, - MysqlType mysqlType, - String initialCursorFieldValue, - // Test to check backward compatibility for connectors created before PR - // https://github.com/airbytehq/airbyte/pull/15504 - String backwardCompatibleInitialCursorFieldValue) - throws SQLException { - final var sqlSourceOperations = new MySqlSourceOperations(); - final String cursorColumn = "cursor_column"; - try (final var testdb = MySQLTestDatabase.in(BaseImage.MYSQL_8) - .with("CREATE TABLE cursor_table (id INTEGER PRIMARY KEY, %s %s);", cursorColumn, sqlType)) { - - final List expectedRecords = new ArrayList<>(); - for (int i = 1; i <= 4; i++) { - final ObjectNode jsonNode = (ObjectNode) Jsons.jsonNode(Collections.emptyMap()); - jsonNode.put("id", i); - final T cursorValue = recordBuilder.apply(i); - jsonNode.put("cursor_column", airbyteRecordStringifier.apply(cursorValue)); - testdb.with("INSERT INTO cursor_table VALUES (%d, '%s');", i, sqlRecordStringifier.apply(cursorValue)); - if (i >= 2) { - expectedRecords.add(jsonNode); - } - } - - try (final Connection connection = testdb.getContainer().createConnection("")) { - final PreparedStatement preparedStatement = connection.prepareStatement( - "SELECT * FROM " + testdb.getDatabaseName() + ".cursor_table WHERE " + cursorColumn + " > ?"); - for (final var initialValue : List.of(initialCursorFieldValue, backwardCompatibleInitialCursorFieldValue)) { - sqlSourceOperations.setCursorField(preparedStatement, 1, mysqlType, initialValue); - final List actualRecords = new ArrayList<>(); - try (final ResultSet resultSet = preparedStatement.executeQuery()) { - while (resultSet.next()) { - final ObjectNode jsonNode = (ObjectNode) Jsons.jsonNode(Collections.emptyMap()); - for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) { - sqlSourceOperations.copyToJsonField(resultSet, i, jsonNode); - } - actualRecords.add(jsonNode); - } - } - assertThat(actualRecords, containsInAnyOrder(expectedRecords.toArray())); - } - } - } - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlSourceTests.java b/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlSourceTests.java deleted file mode 100644 index ef8bb7646677..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlSourceTests.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.assertj.core.api.AssertionsForClassTypes.catchThrowable; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.cdk.integrations.source.jdbc.AbstractJdbcSource; -import io.airbyte.cdk.integrations.source.jdbc.AbstractJdbcSource.PrimaryKeyAttributesFromDb; -import io.airbyte.commons.exceptions.ConfigErrorException; -import io.airbyte.commons.json.Jsons; -import io.airbyte.commons.util.MoreIterators; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.BaseImage; -import io.airbyte.integrations.source.mysql.MySQLTestDatabase.ContainerModifier; -import io.airbyte.protocol.models.Field; -import io.airbyte.protocol.models.JsonSchemaType; -import io.airbyte.protocol.models.v0.AirbyteConnectionStatus; -import io.airbyte.protocol.models.v0.CatalogHelpers; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; -import io.airbyte.protocol.models.v0.DestinationSyncMode; -import io.airbyte.protocol.models.v0.SyncMode; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -public class MySqlSourceTests { - - public MySqlSource source() { - return new MySqlSource(); - } - - @Test - public void testSettingTimezones() throws Exception { - try (final var testdb = MySQLTestDatabase.in(BaseImage.MYSQL_8, ContainerModifier.MOSCOW_TIMEZONE)) { - final var config = testdb.testConfigBuilder() - .with(JdbcUtils.JDBC_URL_PARAMS_KEY, "serverTimezone=Europe/Moscow") - .withoutSsl() - .build(); - final AirbyteConnectionStatus check = source().check(config); - assertEquals(AirbyteConnectionStatus.Status.SUCCEEDED, check.getStatus(), check.getMessage()); - } - } - - @Test - void testJdbcUrlWithEscapedDatabaseName() { - final JsonNode jdbcConfig = source().toDatabaseConfig(buildConfigEscapingNeeded()); - assertNotNull(jdbcConfig.get(JdbcUtils.JDBC_URL_KEY).asText()); - assertTrue(jdbcConfig.get(JdbcUtils.JDBC_URL_KEY).asText().startsWith(EXPECTED_JDBC_ESCAPED_URL)); - } - - private static final String EXPECTED_JDBC_ESCAPED_URL = "jdbc:mysql://localhost:1111/db%2Ffoo?"; - - private JsonNode buildConfigEscapingNeeded() { - return Jsons.jsonNode(ImmutableMap.of( - JdbcUtils.HOST_KEY, "localhost", - JdbcUtils.PORT_KEY, 1111, - JdbcUtils.USERNAME_KEY, "user", - JdbcUtils.DATABASE_KEY, "db/foo")); - } - - @Test - @Disabled("See https://github.com/airbytehq/airbyte/pull/23908#issuecomment-1463753684, enable once communication is out") - public void testNullCursorValueShouldThrowException() { - try (final var testdb = MySQLTestDatabase.in(BaseImage.MYSQL_8) - .with("CREATE TABLE null_cursor_table(id INTEGER NULL);") - .with("INSERT INTO null_cursor_table(id) VALUES (1), (2), (NULL);") - .with("CREATE VIEW null_cursor_view(id) AS SELECT null_cursor_table.id FROM null_cursor_table;")) { - final var config = testdb.testConfigBuilder().withoutSsl().build(); - - final var tableStream = new ConfiguredAirbyteStream() - .withCursorField(Lists.newArrayList("id")) - .withDestinationSyncMode(DestinationSyncMode.APPEND) - .withSyncMode(SyncMode.INCREMENTAL) - .withStream(CatalogHelpers.createAirbyteStream( - "null_cursor_table", - testdb.getDatabaseName(), - Field.of("id", JsonSchemaType.STRING)) - .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL)) - .withSourceDefinedPrimaryKey(List.of(List.of("id")))); - final var tableCatalog = new ConfiguredAirbyteCatalog().withStreams(List.of(tableStream)); - final var tableThrowable = catchThrowable(() -> MoreIterators.toSet(source().read(config, tableCatalog, null))); - assertThat(tableThrowable).isInstanceOf(ConfigErrorException.class).hasMessageContaining(NULL_CURSOR_EXCEPTION_MESSAGE_CONTAINS); - - final var viewStream = new ConfiguredAirbyteStream() - .withCursorField(Lists.newArrayList("id")) - .withDestinationSyncMode(DestinationSyncMode.APPEND) - .withSyncMode(SyncMode.INCREMENTAL) - .withStream(CatalogHelpers.createAirbyteStream( - "null_cursor_view", - testdb.getDatabaseName(), - Field.of("id", JsonSchemaType.STRING)) - .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL)) - .withSourceDefinedPrimaryKey(List.of(List.of("id")))); - final var viewCatalog = new ConfiguredAirbyteCatalog().withStreams(List.of(viewStream)); - final var viewThrowable = catchThrowable(() -> MoreIterators.toSet(source().read(config, viewCatalog, null))); - assertThat(viewThrowable).isInstanceOf(ConfigErrorException.class).hasMessageContaining(NULL_CURSOR_EXCEPTION_MESSAGE_CONTAINS); - } - } - - static private final String NULL_CURSOR_EXCEPTION_MESSAGE_CONTAINS = "The following tables have invalid columns " + - "selected as cursor, please select a column with a well-defined ordering with no null values as a cursor."; - - @Test - void testParseJdbcParameters() { - Map parameters = - MySqlSource.parseJdbcParameters("theAnswerToLiveAndEverything=42&sessionVariables=max_execution_time=10000&foo=bar", "&"); - assertEquals("max_execution_time=10000", parameters.get("sessionVariables")); - assertEquals("42", parameters.get("theAnswerToLiveAndEverything")); - assertEquals("bar", parameters.get("foo")); - } - - @Test - public void testJDBCSessionVariable() throws Exception { - try (final var testdb = MySQLTestDatabase.in(BaseImage.MYSQL_8)) { - final var config = testdb.testConfigBuilder() - .with(JdbcUtils.JDBC_URL_PARAMS_KEY, "sessionVariables=MAX_EXECUTION_TIME=28800000") - .withoutSsl() - .build(); - final AirbyteConnectionStatus check = source().check(config); - assertEquals(AirbyteConnectionStatus.Status.SUCCEEDED, check.getStatus()); - } - } - - @Test - public void testPrimaryKeyOrder() { - final List primaryKeys = new ArrayList<>(); - primaryKeys.add(new PrimaryKeyAttributesFromDb("stream-a", "col1", 3)); - primaryKeys.add(new PrimaryKeyAttributesFromDb("stream-b", "xcol1", 3)); - primaryKeys.add(new PrimaryKeyAttributesFromDb("stream-a", "col2", 2)); - primaryKeys.add(new PrimaryKeyAttributesFromDb("stream-b", "xcol2", 2)); - primaryKeys.add(new PrimaryKeyAttributesFromDb("stream-a", "col3", 1)); - primaryKeys.add(new PrimaryKeyAttributesFromDb("stream-b", "xcol3", 1)); - - final Map> result = AbstractJdbcSource.aggregatePrimateKeys(primaryKeys); - assertEquals(2, result.size()); - assertTrue(result.containsKey("stream-a")); - assertEquals(3, result.get("stream-a").size()); - assertEquals(Arrays.asList("col3", "col2", "col1"), result.get("stream-a")); - - assertTrue(result.containsKey("stream-b")); - assertEquals(3, result.get("stream-b").size()); - assertEquals(Arrays.asList("xcol3", "xcol2", "xcol1"), result.get("stream-b")); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlSslJdbcSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlSslJdbcSourceAcceptanceTest.java deleted file mode 100644 index bf47dd4da9bb..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlSslJdbcSourceAcceptanceTest.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -import com.fasterxml.jackson.databind.JsonNode; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import org.junit.jupiter.api.Order; - -@Order(3) -@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NP_NULL_ON_SOME_PATH") -class MySqlSslJdbcSourceAcceptanceTest extends MySqlJdbcSourceAcceptanceTest { - - @Override - protected JsonNode config() { - return testdb.testConfigBuilder() - .with(JdbcUtils.SSL_KEY, true) - .build(); - } - - @Override - protected MySQLTestDatabase createTestDatabase() { - return new MySQLTestDatabase(new MySQLContainerFactory().shared("mysql:8.0")) - .withConnectionProperty("useSSL", "true") - .withConnectionProperty("requireSSL", "true") - .initialized() - .with("SHOW STATUS LIKE 'Ssl_cipher'"); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlStressTest.java b/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlStressTest.java deleted file mode 100644 index 66fba410c3c0..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MySqlStressTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.collect.ImmutableMap; -import com.mysql.cj.MysqlType; -import io.airbyte.cdk.db.Database; -import io.airbyte.cdk.db.factory.DSLContextFactory; -import io.airbyte.cdk.db.factory.DatabaseDriver; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.cdk.integrations.source.jdbc.AbstractJdbcSource; -import io.airbyte.cdk.integrations.source.jdbc.test.JdbcStressTest; -import io.airbyte.commons.json.Jsons; -import io.airbyte.commons.string.Strings; -import java.sql.Connection; -import java.sql.DriverManager; -import java.util.Optional; -import java.util.concurrent.Callable; -import org.jooq.DSLContext; -import org.jooq.SQLDialect; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.testcontainers.containers.MySQLContainer; - -@Disabled -class MySqlStressTest extends JdbcStressTest { - - private static final String TEST_USER = "test"; - private static final Callable TEST_PASSWORD = () -> "test"; - private static MySQLContainer container; - - private JsonNode config; - private Database database; - private DSLContext dslContext; - - @BeforeAll - static void init() throws Exception { - container = new MySQLContainer<>("mysql:8.0") - .withUsername(TEST_USER) - .withPassword(TEST_PASSWORD.call()) - .withEnv("MYSQL_ROOT_HOST", "%") - .withEnv("MYSQL_ROOT_PASSWORD", TEST_PASSWORD.call()); - container.start(); - final Connection connection = DriverManager.getConnection(container.getJdbcUrl(), "root", TEST_PASSWORD.call()); - connection.createStatement().execute("GRANT ALL PRIVILEGES ON *.* TO '" + TEST_USER + "'@'%';\n"); - } - - @BeforeEach - public void setup() throws Exception { - config = Jsons.jsonNode(ImmutableMap.builder() - .put(JdbcUtils.HOST_KEY, container.getHost()) - .put(JdbcUtils.PORT_KEY, container.getFirstMappedPort()) - .put(JdbcUtils.DATABASE_KEY, Strings.addRandomSuffix("db", "_", 10)) - .put(JdbcUtils.USERNAME_KEY, TEST_USER) - .put(JdbcUtils.PASSWORD_KEY, TEST_PASSWORD.call()) - .build()); - - dslContext = DSLContextFactory.create( - config.get(JdbcUtils.USERNAME_KEY).asText(), - config.get(JdbcUtils.PASSWORD_KEY).asText(), - DatabaseDriver.MYSQL.getDriverClassName(), - String.format("jdbc:mysql://%s:%s", - config.get(JdbcUtils.HOST_KEY).asText(), - config.get(JdbcUtils.PORT_KEY).asText()), - SQLDialect.MYSQL); - database = new Database(dslContext); - - database.query(ctx -> { - ctx.fetch("CREATE DATABASE " + config.get(JdbcUtils.DATABASE_KEY).asText()); - return null; - }); - - super.setup(); - } - - @AfterAll - static void cleanUp() { - container.close(); - } - - // MySql does not support schemas in the way most dbs do. Instead we namespace by db name. - @Override - public Optional getDefaultSchemaName() { - return Optional.of(config.get(JdbcUtils.DATABASE_KEY).asText()); - } - - @Override - public AbstractJdbcSource getSource() { - return new MySqlSource(); - } - - @Override - public String getDriverClass() { - return MySqlSource.DRIVER_CLASS; - } - - @Override - public JsonNode getConfig() { - return Jsons.clone(config); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MysqlDebeziumStateUtilTest.java b/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MysqlDebeziumStateUtilTest.java deleted file mode 100644 index 284fdaa300f0..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/MysqlDebeziumStateUtilTest.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; -import io.airbyte.cdk.db.Database; -import io.airbyte.cdk.db.factory.DSLContextFactory; -import io.airbyte.cdk.db.factory.DataSourceFactory; -import io.airbyte.cdk.db.factory.DatabaseDriver; -import io.airbyte.cdk.db.jdbc.DefaultJdbcDatabase; -import io.airbyte.cdk.db.jdbc.JdbcDatabase; -import io.airbyte.cdk.db.jdbc.JdbcUtils; -import io.airbyte.commons.json.Jsons; -import io.airbyte.commons.string.Strings; -import io.airbyte.integrations.source.mysql.cdc.MySqlDebeziumStateUtil; -import io.airbyte.integrations.source.mysql.cdc.MySqlDebeziumStateUtil.MysqlDebeziumStateAttributes; -import io.airbyte.protocol.models.Field; -import io.airbyte.protocol.models.JsonSchemaType; -import io.airbyte.protocol.models.v0.AirbyteCatalog; -import io.airbyte.protocol.models.v0.CatalogHelpers; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; -import io.airbyte.protocol.models.v0.SyncMode; -import java.sql.SQLException; -import java.time.Instant; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Properties; -import org.jooq.SQLDialect; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.testcontainers.containers.MySQLContainer; - -public class MysqlDebeziumStateUtilTest { - - private static final String DB_NAME = Strings.addRandomSuffix("db", "_", 10).toLowerCase(); - private static final String TABLE_NAME = Strings.addRandomSuffix("table", "_", 10).toLowerCase(); - private static final Properties MYSQL_PROPERTIES = new Properties(); - private static final String DB_CREATE_QUERY = "CREATE DATABASE " + DB_NAME; - private static final String TABLE_CREATE_QUERY = "CREATE TABLE " + DB_NAME + "." + TABLE_NAME + " (id INTEGER, name VARCHAR(200), PRIMARY KEY(id))"; - private static final AirbyteCatalog CATALOG = new AirbyteCatalog().withStreams(List.of( - CatalogHelpers.createAirbyteStream( - TABLE_NAME, - DB_NAME, - Field.of("id", JsonSchemaType.INTEGER), - Field.of("string", JsonSchemaType.STRING)) - .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL)) - .withSourceDefinedPrimaryKey(List.of(List.of("id"))))); - protected static final ConfiguredAirbyteCatalog CONFIGURED_CATALOG = CatalogHelpers.toDefaultConfiguredCatalog(CATALOG); - - static { - CONFIGURED_CATALOG.getStreams().forEach(s -> s.setSyncMode(SyncMode.INCREMENTAL)); - MYSQL_PROPERTIES.setProperty("connector.class", "io.debezium.connector.mysql.MySqlConnector"); - MYSQL_PROPERTIES.setProperty("database.server.id", "5000"); - } - - @Test - public void debeziumInitialStateConstructTest() throws SQLException { - try (final MySQLContainer container = new MySQLContainer<>("mysql:8.0")) { - container.start(); - initDB(container); - final JdbcDatabase database = getJdbcDatabase(container); - final MySqlDebeziumStateUtil mySqlDebeziumStateUtil = new MySqlDebeziumStateUtil(); - final JsonNode debeziumState = mySqlDebeziumStateUtil.constructInitialDebeziumState(MYSQL_PROPERTIES, CONFIGURED_CATALOG, database); - Assertions.assertEquals(3, Jsons.object(debeziumState, Map.class).size()); - Assertions.assertTrue(debeziumState.has("is_compressed")); - Assertions.assertFalse(debeziumState.get("is_compressed").asBoolean()); - Assertions.assertTrue(debeziumState.has("mysql_db_history")); - Assertions.assertNotNull(debeziumState.get("mysql_db_history")); - Assertions.assertTrue(debeziumState.has("mysql_cdc_offset")); - final Map mysqlCdcOffset = Jsons.object(debeziumState.get("mysql_cdc_offset"), Map.class); - Assertions.assertEquals(1, mysqlCdcOffset.size()); - Assertions.assertTrue(mysqlCdcOffset.containsKey("[\"" + DB_NAME + "\",{\"server\":\"" + DB_NAME + "\"}]")); - Assertions.assertNotNull(mysqlCdcOffset.get("[\"" + DB_NAME + "\",{\"server\":\"" + DB_NAME + "\"}]")); - - final Optional parsedOffset = mySqlDebeziumStateUtil.savedOffset(MYSQL_PROPERTIES, CONFIGURED_CATALOG, - debeziumState.get("mysql_cdc_offset"), database.getSourceConfig()); - Assertions.assertTrue(parsedOffset.isPresent()); - Assertions.assertNotNull(parsedOffset.get().binlogFilename()); - Assertions.assertTrue(parsedOffset.get().binlogPosition() > 0); - Assertions.assertTrue(parsedOffset.get().gtidSet().isEmpty()); - container.stop(); - } - } - - @Test - public void formatTestWithGtid() { - final MySqlDebeziumStateUtil mySqlDebeziumStateUtil = new MySqlDebeziumStateUtil(); - final JsonNode debeziumState = mySqlDebeziumStateUtil.format(new MysqlDebeziumStateAttributes("binlog.000002", 633, - Optional.of("3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5")), "db_fgnfxvllud", "db_fgnfxvllud", Instant.parse("2023-06-06T08:36:10.341842Z")); - final Map stateAsMap = Jsons.object(debeziumState, Map.class); - Assertions.assertEquals(1, stateAsMap.size()); - Assertions.assertTrue(stateAsMap.containsKey("[\"db_fgnfxvllud\",{\"server\":\"db_fgnfxvllud\"}]")); - Assertions.assertEquals( - "{\"transaction_id\":null,\"ts_sec\":1686040570,\"file\":\"binlog.000002\",\"pos\":633,\"gtids\":\"3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5\"}", - stateAsMap.get("[\"db_fgnfxvllud\",{\"server\":\"db_fgnfxvllud\"}]")); - - final JsonNode config = Jsons.jsonNode(ImmutableMap.builder() - .put(JdbcUtils.HOST_KEY, "host") - .put(JdbcUtils.PORT_KEY, "5432") - .put(JdbcUtils.DATABASE_KEY, "db_fgnfxvllud") - .put(JdbcUtils.USERNAME_KEY, "username") - .put(JdbcUtils.PASSWORD_KEY, "password") - .put(JdbcUtils.SSL_KEY, false) - .build()); - - final Optional parsedOffset = mySqlDebeziumStateUtil.savedOffset(MYSQL_PROPERTIES, CONFIGURED_CATALOG, - debeziumState, config); - Assertions.assertTrue(parsedOffset.isPresent()); - final JsonNode stateGeneratedUsingParsedOffset = - mySqlDebeziumStateUtil.format(parsedOffset.get(), "db_fgnfxvllud", "db_fgnfxvllud", Instant.parse("2023-06-06T08:36:10.341842Z")); - Assertions.assertEquals(debeziumState, stateGeneratedUsingParsedOffset); - } - - @Test - public void formatTestWithoutGtid() { - final MySqlDebeziumStateUtil mySqlDebeziumStateUtil = new MySqlDebeziumStateUtil(); - final JsonNode debeziumState = mySqlDebeziumStateUtil.format(new MysqlDebeziumStateAttributes("binlog.000002", 633, - Optional.empty()), "db_fgnfxvllud", "db_fgnfxvllud", Instant.parse("2023-06-06T08:36:10.341842Z")); - final Map stateAsMap = Jsons.object(debeziumState, Map.class); - Assertions.assertEquals(1, stateAsMap.size()); - Assertions.assertTrue(stateAsMap.containsKey("[\"db_fgnfxvllud\",{\"server\":\"db_fgnfxvllud\"}]")); - Assertions.assertEquals("{\"transaction_id\":null,\"ts_sec\":1686040570,\"file\":\"binlog.000002\",\"pos\":633}", - stateAsMap.get("[\"db_fgnfxvllud\",{\"server\":\"db_fgnfxvllud\"}]")); - - final JsonNode config = Jsons.jsonNode(ImmutableMap.builder() - .put(JdbcUtils.HOST_KEY, "host") - .put(JdbcUtils.PORT_KEY, "5432") - .put(JdbcUtils.DATABASE_KEY, "db_fgnfxvllud") - .put(JdbcUtils.USERNAME_KEY, "username") - .put(JdbcUtils.PASSWORD_KEY, "password") - .put(JdbcUtils.SSL_KEY, false) - .build()); - - final Optional parsedOffset = mySqlDebeziumStateUtil.savedOffset(MYSQL_PROPERTIES, CONFIGURED_CATALOG, - debeziumState, config); - Assertions.assertTrue(parsedOffset.isPresent()); - final JsonNode stateGeneratedUsingParsedOffset = - mySqlDebeziumStateUtil.format(parsedOffset.get(), "db_fgnfxvllud", "db_fgnfxvllud", Instant.parse("2023-06-06T08:36:10.341842Z")); - Assertions.assertEquals(debeziumState, stateGeneratedUsingParsedOffset); - } - - private JdbcDatabase getJdbcDatabase(final MySQLContainer container) { - final JdbcDatabase database = new DefaultJdbcDatabase( - DataSourceFactory.create( - "root", - "test", - DatabaseDriver.MYSQL.getDriverClassName(), - String.format(DatabaseDriver.MYSQL.getUrlFormatString(), - container.getHost(), - container.getFirstMappedPort(), - DB_NAME))); - database.setSourceConfig(getSourceConfig(container)); - return database; - } - - private void initDB(final MySQLContainer container) throws SQLException { - final Database db = new Database(DSLContextFactory.create( - "root", - "test", - DatabaseDriver.MYSQL.getDriverClassName(), - String.format("jdbc:mysql://%s:%s", - container.getHost(), - container.getFirstMappedPort()), - SQLDialect.MYSQL)); - db.query(ctx -> ctx.execute(DB_CREATE_QUERY)); - db.query(ctx -> ctx.execute(TABLE_CREATE_QUERY)); - } - - private JsonNode getSourceConfig(final MySQLContainer container) { - final Map config = new HashMap<>(); - config.put(JdbcUtils.USERNAME_KEY, "root"); - config.put(JdbcUtils.PASSWORD_KEY, "test"); - config.put(JdbcUtils.HOST_KEY, container.getHost()); - config.put(JdbcUtils.PORT_KEY, container.getFirstMappedPort()); - config.put(JdbcUtils.DATABASE_KEY, DB_NAME); - return Jsons.jsonNode(config); - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/kotlin/MySqlSourceExceptionHandlerTest.kt b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/MySqlSourceExceptionHandlerTest.kt deleted file mode 100644 index b5049d3c1b95..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test/kotlin/MySqlSourceExceptionHandlerTest.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2024 Airbyte, Inc., all rights reserved. - */ - -import io.airbyte.cdk.integrations.util.FailureType -import io.airbyte.integrations.source.mysql.MySqlSourceExceptionHandler -import java.io.EOFException -import java.sql.SQLSyntaxErrorException -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test - -class MySqlSourceExceptionHandlerTest { - private var exceptionHandler: MySqlSourceExceptionHandler? = null - - @BeforeEach - fun setUp() { - exceptionHandler = MySqlSourceExceptionHandler() - } - - @Test - fun testTranslateMySQLSyntaxException() { - val exception = SQLSyntaxErrorException("Unknown column 'xmin' in 'field list'") - val externalMessage = exceptionHandler!!.getExternalMessage(exception) - Assertions.assertTrue(exceptionHandler!!.checkErrorType(exception, FailureType.CONFIG)) - Assertions.assertEquals( - "A column needed by MySQL source connector is missing in the database", - externalMessage - ) - } - - @Test - fun testTranslateEOFException() { - val exception = - EOFException( - "Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost." - ) - val externalMessage = exceptionHandler!!.getExternalMessage(exception) - Assertions.assertTrue(exceptionHandler!!.checkErrorType(exception, FailureType.TRANSIENT)) - Assertions.assertEquals("Can not read data from MySQL server", externalMessage) - } -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlContainerFactory.kt b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlContainerFactory.kt new file mode 100644 index 000000000000..2df3338e4f86 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlContainerFactory.kt @@ -0,0 +1,102 @@ +/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ +package io.airbyte.integrations.source.mysql + +import io.airbyte.cdk.testcontainers.TestContainerFactory +import io.github.oshai.kotlinlogging.KotlinLogging +import org.testcontainers.containers.Container +import org.testcontainers.containers.MySQLContainer +import org.testcontainers.containers.Network +import org.testcontainers.utility.DockerImageName + +object MySqlContainerFactory { + const val COMPATIBLE_NAME = "mysql:8.0" + private val log = KotlinLogging.logger {} + + init { + TestContainerFactory.register(COMPATIBLE_NAME, ::MySQLContainer) + } + + sealed interface MySqlContainerModifier : + TestContainerFactory.ContainerModifier> + + data object WithNetwork : MySqlContainerModifier { + override fun modify(container: MySQLContainer<*>) { + container.withNetwork(Network.newNetwork()) + } + } + + data object WithCdc : MySqlContainerModifier { + override fun modify(container: MySQLContainer<*>) { + container.start() + container.execAsRoot(GTID_ON) + container.execAsRoot(GRANT.format(container.username)) + container.execAsRoot("FLUSH PRIVILEGES;") + } + + const val GTID_ON = + "SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 'ON';" + + "SET @@GLOBAL.GTID_MODE = 'OFF_PERMISSIVE';" + + "SET @@GLOBAL.GTID_MODE = 'ON_PERMISSIVE';" + + "SET @@GLOBAL.GTID_MODE = 'ON';" + + const val GRANT = + "GRANT SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT " + + "ON *.* TO '%s'@'%%';" + } + + data object WithCdcOff : MySqlContainerModifier { + override fun modify(container: MySQLContainer<*>) { + container.withCommand("--skip-log-bin") + } + } + + fun exclusive( + imageName: String, + vararg modifiers: MySqlContainerModifier, + ): MySQLContainer<*> { + val dockerImageName = + DockerImageName.parse(imageName).asCompatibleSubstituteFor(COMPATIBLE_NAME) + return TestContainerFactory.exclusive(dockerImageName, *modifiers) + } + + fun shared( + imageName: String, + vararg modifiers: MySqlContainerModifier, + ): MySQLContainer<*> { + val dockerImageName = + DockerImageName.parse(imageName).asCompatibleSubstituteFor(COMPATIBLE_NAME) + return TestContainerFactory.shared(dockerImageName, *modifiers) + } + + @JvmStatic + fun config(mySQLContainer: MySQLContainer<*>): MySqlSourceConfigurationSpecification = + MySqlSourceConfigurationSpecification().apply { + host = mySQLContainer.host + port = mySQLContainer.getMappedPort(MySQLContainer.MYSQL_PORT) + username = mySQLContainer.username + password = mySQLContainer.password + jdbcUrlParams = "" + database = "test" + checkpointTargetIntervalSeconds = 60 + concurrency = 1 + setIncrementalValue(UserDefinedCursor) + } + + fun MySQLContainer<*>.execAsRoot(sql: String) { + val cleanSql: String = sql.trim().removeSuffix(";") + ";" + log.info { "Executing SQL as root: $cleanSql" } + val result: Container.ExecResult = + execInContainer("mysql", "-u", "root", "-ptest", "-e", cleanSql) + for (line in (result.stdout ?: "").lines()) { + log.info { "STDOUT: $line" } + } + for (line in (result.stderr ?: "").lines()) { + log.info { "STDOUT: $line" } + } + if (result.exitCode == 0) { + return + } + log.error { "Exit code ${result.exitCode}" } + throw RuntimeException("Failed to execute query $cleanSql") + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcIntegrationTest.kt b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcIntegrationTest.kt new file mode 100644 index 000000000000..e2407e724cc3 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCdcIntegrationTest.kt @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.mysql + +import io.airbyte.cdk.StreamIdentifier +import io.airbyte.cdk.command.CliRunner +import io.airbyte.cdk.discover.DiscoveredStream +import io.airbyte.cdk.discover.Field +import io.airbyte.cdk.jdbc.IntFieldType +import io.airbyte.cdk.jdbc.JdbcConnectionFactory +import io.airbyte.cdk.jdbc.StringFieldType +import io.airbyte.cdk.output.BufferingOutputConsumer +import io.airbyte.integrations.source.mysql.MySqlContainerFactory.execAsRoot +import io.airbyte.protocol.models.v0.AirbyteConnectionStatus +import io.airbyte.protocol.models.v0.AirbyteMessage +import io.airbyte.protocol.models.v0.AirbyteStateMessage +import io.airbyte.protocol.models.v0.AirbyteStream +import io.airbyte.protocol.models.v0.CatalogHelpers +import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog +import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream +import io.airbyte.protocol.models.v0.StreamDescriptor +import io.airbyte.protocol.models.v0.SyncMode +import io.github.oshai.kotlinlogging.KotlinLogging +import java.sql.Connection +import java.sql.Statement +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Timeout +import org.testcontainers.containers.MySQLContainer + +class MySqlSourceCdcIntegrationTest { + + @Test + fun testCheck() { + val run1: BufferingOutputConsumer = CliRunner.source("check", config(), null).run() + + assertEquals(run1.messages().size, 1) + assertEquals( + run1.messages().first().connectionStatus.status, + AirbyteConnectionStatus.Status.SUCCEEDED + ) + + MySqlContainerFactory.exclusive( + imageName = "mysql:8.0", + MySqlContainerFactory.WithCdcOff, + ) + .use { nonCdcDbContainer -> + { + val invalidConfig: MySqlSourceConfigurationSpecification = + MySqlContainerFactory.config(nonCdcDbContainer).apply { + setIncrementalValue(Cdc()) + } + + val nonCdcConnectionFactory = + JdbcConnectionFactory(MySqlSourceConfigurationFactory().make(invalidConfig)) + + provisionTestContainer(nonCdcDbContainer, nonCdcConnectionFactory) + + val run2: BufferingOutputConsumer = + CliRunner.source("check", invalidConfig, null).run() + + val messageInRun2 = + run2 + .messages() + .filter { it.type == AirbyteMessage.Type.CONNECTION_STATUS } + .first() + + assertEquals( + AirbyteConnectionStatus.Status.FAILED, + messageInRun2.connectionStatus.status + ) + } + } + } + + @Test + fun test() { + val state1 = CliRunner.source("read", config(), configuredCatalog).run().states().last() + + connectionFactory.get().use { connection: Connection -> + connection.isReadOnly = false + connection.createStatement().use { stmt: Statement -> + stmt.execute("INSERT INTO test.tbl (k, v) VALUES (3, 'baz')") + } + } + + val run2InputState: List = listOf(state1) + CliRunner.source("read", config(), configuredCatalog, run2InputState).run().records() + } + + @Test + fun testFullRefresh() { + val fullRefreshCatalog = + configuredCatalog.apply { streams.forEach { it.syncMode = SyncMode.FULL_REFRESH } } + CliRunner.source("read", config(), fullRefreshCatalog).run() + connectionFactory.get().use { connection: Connection -> + connection.isReadOnly = false + connection.createStatement().use { stmt: Statement -> + stmt.execute("INSERT INTO test.tbl (k, v) VALUES (4, 'baz')") + } + } + } + + companion object { + val log = KotlinLogging.logger {} + lateinit var dbContainer: MySQLContainer<*> + + fun config(): MySqlSourceConfigurationSpecification = + MySqlContainerFactory.config(dbContainer).apply { setIncrementalValue(Cdc()) } + + val connectionFactory: JdbcConnectionFactory by lazy { + JdbcConnectionFactory(MySqlSourceConfigurationFactory().make(config())) + } + + val configuredCatalog: ConfiguredAirbyteCatalog = run { + val desc = StreamDescriptor().withName("tbl").withNamespace("test") + val discoveredStream = + DiscoveredStream( + id = StreamIdentifier.Companion.from(desc), + columns = listOf(Field("k", IntFieldType), Field("v", StringFieldType)), + primaryKeyColumnIDs = listOf(listOf("k")), + ) + val stream: AirbyteStream = MySqlSourceOperations().createGlobal(discoveredStream) + val configuredStream: ConfiguredAirbyteStream = + CatalogHelpers.toDefaultConfiguredStream(stream) + .withSyncMode(SyncMode.INCREMENTAL) + .withPrimaryKey(discoveredStream.primaryKeyColumnIDs) + .withCursorField(listOf(MySqlSourceCdcMetaFields.CDC_CURSOR.id)) + ConfiguredAirbyteCatalog().withStreams(listOf(configuredStream)) + } + + @JvmStatic + @BeforeAll + @Timeout(value = 300) + fun startAndProvisionTestContainer() { + dbContainer = + MySqlContainerFactory.exclusive( + imageName = "mysql:8.0", + MySqlContainerFactory.WithNetwork, + ) + provisionTestContainer(dbContainer, connectionFactory) + } + + fun provisionTestContainer( + targetContainer: MySQLContainer<*>, + targetConnectionFactory: JdbcConnectionFactory + ) { + val gtidOn = + "SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 'ON';" + + "SET @@GLOBAL.GTID_MODE = 'OFF_PERMISSIVE';" + + "SET @@GLOBAL.GTID_MODE = 'ON_PERMISSIVE';" + + "SET @@GLOBAL.GTID_MODE = 'ON';" + val grant = + "GRANT SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT " + + "ON *.* TO '${targetContainer.username}'@'%';" + targetContainer.execAsRoot(gtidOn) + targetContainer.execAsRoot(grant) + targetContainer.execAsRoot("FLUSH PRIVILEGES;") + + targetConnectionFactory.get().use { connection: Connection -> + connection.isReadOnly = false + connection.createStatement().use { stmt: Statement -> + stmt.execute("CREATE TABLE test.tbl(k INT PRIMARY KEY, v VARCHAR(80))") + } + connection.createStatement().use { stmt: Statement -> + stmt.execute("INSERT INTO test.tbl (k, v) VALUES (1, 'foo'), (2, 'bar')") + } + } + } + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceConfigurationSpecificationTest.kt b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceConfigurationSpecificationTest.kt new file mode 100644 index 000000000000..b4a3f8262eef --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceConfigurationSpecificationTest.kt @@ -0,0 +1,75 @@ +/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ +package io.airbyte.integrations.source.mysql + +import io.airbyte.cdk.ConfigErrorException +import io.airbyte.cdk.command.ConfigurationSpecificationSupplier +import io.airbyte.cdk.ssh.SshPasswordAuthTunnelMethod +import io.airbyte.cdk.ssh.SshTunnelMethodConfiguration +import io.micronaut.context.annotation.Property +import io.micronaut.context.env.Environment +import io.micronaut.test.extensions.junit5.annotation.MicronautTest +import jakarta.inject.Inject +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +@MicronautTest(environments = [Environment.TEST], rebuildContext = true) +class MySqlSourceConfigurationSpecificationTest { + + @Inject + lateinit var supplier: ConfigurationSpecificationSupplier + + @Test + fun testSchemaViolation() { + Assertions.assertThrows(ConfigErrorException::class.java, supplier::get) + } + + @Test + @Property(name = "airbyte.connector.config.json", value = CONFIG_JSON) + fun testJson() { + val pojo: MySqlSourceConfigurationSpecification = supplier.get() + Assertions.assertEquals("localhost", pojo.host) + Assertions.assertEquals(12345, pojo.port) + Assertions.assertEquals("FOO", pojo.username) + Assertions.assertEquals("BAR", pojo.password) + Assertions.assertEquals("SYSTEM", pojo.database) + val encryption: EncryptionSpecification = pojo.getEncryptionValue()!! + Assertions.assertTrue(encryption is EncryptionPreferred, encryption::class.toString()) + val tunnelMethod: SshTunnelMethodConfiguration? = pojo.getTunnelMethodValue() + Assertions.assertTrue( + tunnelMethod is SshPasswordAuthTunnelMethod, + tunnelMethod!!::class.toString(), + ) + Assertions.assertEquals(60, pojo.checkpointTargetIntervalSeconds) + Assertions.assertEquals(2, pojo.concurrency) + } + + companion object { + + const val CONFIG_JSON: String = + """ +{ + "host": "localhost", + "port": 12345, + "username": "FOO", + "password": "BAR", + "database": "SYSTEM", + "ssl_mode": { + "mode": "preferred" + }, + "tunnel_method": { + "tunnel_method": "SSH_PASSWORD_AUTH", + "tunnel_host": "localhost", + "tunnel_port": 2222, + "tunnel_user": "sshuser", + "tunnel_user_password": "***" + }, + "replication_method": { + "method": "STANDARD" + }, + "checkpoint_target_interval_seconds": 60, + "jdbc_url_params": "theAnswerToLiveAndEverything=42&sessionVariables=max_execution_time=10000&foo=bar&", + "concurrency": 2 +} +""" + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceConfigurationTest.kt b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceConfigurationTest.kt new file mode 100644 index 000000000000..63fdb8c5ab56 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceConfigurationTest.kt @@ -0,0 +1,124 @@ +/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ +package io.airbyte.integrations.source.mysql + +import io.airbyte.cdk.ConfigErrorException +import io.airbyte.cdk.command.AIRBYTE_CLOUD_ENV +import io.airbyte.cdk.command.ConfigurationSpecificationSupplier +import io.airbyte.cdk.command.SourceConfigurationFactory +import io.airbyte.cdk.ssh.SshNoTunnelMethod +import io.micronaut.context.annotation.Property +import io.micronaut.context.env.Environment +import io.micronaut.test.extensions.junit5.annotation.MicronautTest +import jakarta.inject.Inject +import java.time.Duration +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +@MicronautTest(environments = [Environment.TEST, AIRBYTE_CLOUD_ENV], rebuildContext = true) +class MySqlSourceConfigurationTest { + @Inject + lateinit var pojoSupplier: + ConfigurationSpecificationSupplier + + @Inject + lateinit var factory: + SourceConfigurationFactory + + @Test + @Property(name = "airbyte.connector.config.host", value = "localhost") + @Property(name = "airbyte.connector.config.port", value = "12345") + @Property(name = "airbyte.connector.config.username", value = "FOO") + @Property(name = "airbyte.connector.config.password", value = "BAR") + @Property(name = "airbyte.connector.config.database", value = "SYSTEM") + @Property(name = "airbyte.connector.config.ssl_mode.mode", value = "required") + @Property( + name = "airbyte.connector.config.jdbc_url_params", + value = "theAnswerToLiveAndEverything=42&sessionVariables=max_execution_time=10000&foo=bar&" + ) + fun testParseJdbcParameters() { + val pojo: MySqlSourceConfigurationSpecification = pojoSupplier.get() + + val config = factory.makeWithoutExceptionHandling(pojo) + + Assertions.assertEquals(config.realHost, "localhost") + Assertions.assertEquals(config.realPort, 12345) + Assertions.assertEquals(config.namespaces, setOf("SYSTEM")) + Assertions.assertTrue(config.sshTunnel is SshNoTunnelMethod) + + Assertions.assertEquals(config.jdbcProperties["user"], "FOO") + Assertions.assertEquals(config.jdbcProperties["password"], "BAR") + + // Make sure we don't accidentally drop the following hardcoded settings for mysql. + Assertions.assertEquals(config.jdbcProperties["useCursorFetch"], "true") + Assertions.assertEquals(config.jdbcProperties["sessionVariables"], "autocommit=0") + + Assertions.assertEquals(config.jdbcProperties["theAnswerToLiveAndEverything"], "42") + Assertions.assertEquals(config.jdbcProperties["foo"], "bar") + } + + @Test + @Property(name = "airbyte.connector.config.host", value = "localhost") + @Property(name = "airbyte.connector.config.port", value = "12345") + @Property(name = "airbyte.connector.config.username", value = "FOO") + @Property(name = "airbyte.connector.config.password", value = "BAR") + @Property(name = "airbyte.connector.config.database", value = "SYSTEM") + fun testAirbyteCloudDeployment() { + val pojo: MySqlSourceConfigurationSpecification = pojoSupplier.get() + Assertions.assertThrows(ConfigErrorException::class.java) { + factory.makeWithoutExceptionHandling(pojo) + } + } + + @Test + @Property(name = "airbyte.connector.config.json", value = CONFIG_V1) + fun testParseConfigFromV1() { + val pojo: MySqlSourceConfigurationSpecification = pojoSupplier.get() + + val config = factory.makeWithoutExceptionHandling(pojo) + + Assertions.assertEquals(config.realHost, "localhost") + Assertions.assertEquals(config.realPort, 12345) + Assertions.assertEquals(config.namespaces, setOf("SYSTEM")) + + Assertions.assertEquals(config.jdbcProperties["user"], "FOO") + Assertions.assertEquals(config.jdbcProperties["password"], "BAR") + Assertions.assertEquals(config.jdbcProperties["sslMode"], "required") + Assertions.assertTrue(config.incrementalConfiguration is CdcIncrementalConfiguration) + + val cdcCursor = config.incrementalConfiguration as CdcIncrementalConfiguration + + Assertions.assertEquals(cdcCursor.initialLoadTimeout, Duration.ofHours(9)) + Assertions.assertEquals( + cdcCursor.invalidCdcCursorPositionBehavior, + InvalidCdcCursorPositionBehavior.RESET_SYNC + ) + + Assertions.assertTrue(config.sshTunnel is SshNoTunnelMethod) + } + + companion object { + + const val CONFIG_V1: String = + """ +{ + "host": "localhost", + "port": 12345, + "database": "SYSTEM", + "password": "BAR", + "ssl_mode": { + "mode": "required" + }, + "username": "FOO", + "tunnel_method": { + "tunnel_method": "NO_TUNNEL" + }, + "replication_method": { + "method": "CDC", + "initial_waiting_seconds": 301, + "initial_load_timeout_hours": 9, + "invalid_cdc_cursor_position_behavior": "Re-sync data" + } +} +""" + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCursorBasedIntegrationTest.kt b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCursorBasedIntegrationTest.kt new file mode 100644 index 000000000000..5e2f9267fc0a --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceCursorBasedIntegrationTest.kt @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.mysql + +import io.airbyte.cdk.StreamIdentifier +import io.airbyte.cdk.command.CliRunner +import io.airbyte.cdk.discover.DiscoveredStream +import io.airbyte.cdk.discover.Field +import io.airbyte.cdk.jdbc.IntFieldType +import io.airbyte.cdk.jdbc.JdbcConnectionFactory +import io.airbyte.cdk.jdbc.StringFieldType +import io.airbyte.cdk.output.BufferingOutputConsumer +import io.airbyte.cdk.util.Jsons +import io.airbyte.protocol.models.v0.AirbyteRecordMessage +import io.airbyte.protocol.models.v0.AirbyteStateMessage +import io.airbyte.protocol.models.v0.AirbyteStream +import io.airbyte.protocol.models.v0.CatalogHelpers +import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog +import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream +import io.airbyte.protocol.models.v0.StreamDescriptor +import io.airbyte.protocol.models.v0.SyncMode +import io.github.oshai.kotlinlogging.KotlinLogging +import java.sql.Connection +import java.sql.Statement +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Timeout +import org.testcontainers.containers.MySQLContainer + +class MySqlSourceCursorBasedIntegrationTest { + + @BeforeEach + fun resetTable() { + connectionFactory.get().use { connection: Connection -> + connection.isReadOnly = false + connection.createStatement().use { stmt: Statement -> + stmt.execute("DELETE FROM test.$tableName") + } + connection.createStatement().use { stmt: Statement -> + stmt.execute("INSERT INTO test.$tableName (k, v) VALUES (10, 'foo'), (20, 'bar')") + } + } + } + + @Test + fun testCursorBasedRead() { + val run1: BufferingOutputConsumer = + CliRunner.source("read", config, getConfiguredCatalog()).run() + + val lastStateMessageFromRun1 = run1.states().last() + val lastStreamStateFromRun1 = lastStateMessageFromRun1.stream.streamState + + assertEquals("20", lastStreamStateFromRun1.get("cursor").textValue()) + assertEquals(2, lastStreamStateFromRun1.get("version").intValue()) + assertEquals("cursor_based", lastStreamStateFromRun1.get("state_type").asText()) + assertEquals(tableName, lastStreamStateFromRun1.get("stream_name").asText()) + assertEquals(listOf("k"), lastStreamStateFromRun1.get("cursor_field").map { it.asText() }) + assertEquals("test", lastStreamStateFromRun1.get("stream_namespace").asText()) + assertEquals(0, lastStreamStateFromRun1.get("cursor_record_count").asInt()) + + connectionFactory.get().use { connection: Connection -> + connection.isReadOnly = false + connection.createStatement().use { stmt: Statement -> + stmt.execute("INSERT INTO test.$tableName (k, v) VALUES (3, 'baz-ignore')") + stmt.execute("INSERT INTO test.$tableName (k, v) VALUES (13, 'baz-ignore')") + stmt.execute("INSERT INTO test.$tableName (k, v) VALUES (30, 'baz')") + } + } + + val run2InputState: List = listOf(lastStateMessageFromRun1) + val run2: BufferingOutputConsumer = + CliRunner.source("read", config, getConfiguredCatalog(), run2InputState).run() + val recordMessageFromRun2: List = run2.records() + assertEquals(recordMessageFromRun2.size, 1) + } + + @Test + fun testWithV1State() { + var state: AirbyteStateMessage = Jsons.readValue(V1_STATE, AirbyteStateMessage::class.java) + val run1: BufferingOutputConsumer = + CliRunner.source("read", config, getConfiguredCatalog(), listOf(state)).run() + val recordMessageFromRun1: List = run1.records() + assertEquals(recordMessageFromRun1.size, 1) + } + + @Test + fun testWithV1StateEmptyCursor() { + var state: AirbyteStateMessage = + Jsons.readValue(V1_STATE_EMPTY_CURSOR, AirbyteStateMessage::class.java) + val run1: BufferingOutputConsumer = + CliRunner.source("read", config, getConfiguredCatalog(), listOf(state)).run() + val recordMessageFromRun1: List = run1.records() + assertEquals(recordMessageFromRun1.size, 2) + } + + @Test + fun testWithFullRefresh() { + val fullRefreshCatalog = + getConfiguredCatalog().apply { streams[0].syncMode = SyncMode.FULL_REFRESH } + val run1: BufferingOutputConsumer = + CliRunner.source("read", config, fullRefreshCatalog).run() + val recordMessageFromRun1: List = run1.records() + assertEquals(recordMessageFromRun1.size, 2) + val lastStateMessageFromRun1 = run1.states().last() + + val run2: BufferingOutputConsumer = + CliRunner.source("read", config, fullRefreshCatalog, listOf(lastStateMessageFromRun1)) + .run() + val recordMessageFromRun2: List = run2.records() + assertEquals(recordMessageFromRun2.size, 0) + } + + @Test + fun testWithFullRefreshWithEmptyTable() { + connectionFactory.get().use { connection: Connection -> + connection.isReadOnly = false + connection.createStatement().use { stmt: Statement -> + stmt.execute("DELETE FROM test.$tableName") + } + } + + val fullRefreshCatalog = + getConfiguredCatalog().apply { streams[0].syncMode = SyncMode.FULL_REFRESH } + val run1: BufferingOutputConsumer = + CliRunner.source("read", config, fullRefreshCatalog).run() + + assertTrue(run1.states().isEmpty()) + assertTrue(run1.records().isEmpty()) + + val run2: BufferingOutputConsumer = + CliRunner.source("read", config, fullRefreshCatalog).run() + assertTrue(run2.states().isEmpty()) + assertTrue(run2.records().isEmpty()) + } + + @Test + fun testCursorBasedReadWithEmptyTable() { + connectionFactory.get().use { connection: Connection -> + connection.isReadOnly = false + connection.createStatement().use { stmt: Statement -> + stmt.execute("DELETE FROM test.$tableName") + } + } + + val run1: BufferingOutputConsumer = + CliRunner.source("read", config, getConfiguredCatalog()).run() + + assertTrue(run1.states().isEmpty()) + assertTrue(run1.records().isEmpty()) + + val run2: BufferingOutputConsumer = + CliRunner.source("read", config, getConfiguredCatalog()).run() + assertTrue(run2.states().isEmpty()) + assertTrue(run2.records().isEmpty()) + } + + @Test + fun testCursorBasedViewRead() { + provisionView(connectionFactory) + val catalog = getConfiguredCatalog() + catalog.streams[0].stream.name = viewName + val run1: BufferingOutputConsumer = CliRunner.source("read", config, catalog).run() + val lastStateMessageFromRun1 = run1.states().last() + val lastStreamStateFromRun1 = lastStateMessageFromRun1.stream.streamState + + assertEquals("20", lastStreamStateFromRun1.get("cursor").textValue()) + assertEquals(2, lastStreamStateFromRun1.get("version").intValue()) + assertEquals("cursor_based", lastStreamStateFromRun1.get("state_type").asText()) + assertEquals(viewName, lastStreamStateFromRun1.get("stream_name").asText()) + assertEquals(listOf("k"), lastStreamStateFromRun1.get("cursor_field").map { it.asText() }) + assertEquals("test", lastStreamStateFromRun1.get("stream_namespace").asText()) + assertEquals(0, lastStreamStateFromRun1.get("cursor_record_count").asInt()) + } + + companion object { + val log = KotlinLogging.logger {} + val dbContainer: MySQLContainer<*> = MySqlContainerFactory.shared(imageName = "mysql:8.0") + + val config: MySqlSourceConfigurationSpecification = + MySqlContainerFactory.config(dbContainer) + + val connectionFactory: JdbcConnectionFactory by lazy { + JdbcConnectionFactory(MySqlSourceConfigurationFactory().make(config)) + } + + fun getConfiguredCatalog(): ConfiguredAirbyteCatalog { + val desc = StreamDescriptor().withName(tableName).withNamespace("test") + val discoveredStream = + DiscoveredStream( + id = StreamIdentifier.Companion.from(desc), + columns = listOf(Field("k", IntFieldType), Field("v", StringFieldType)), + primaryKeyColumnIDs = listOf(listOf("k")), + ) + val stream: AirbyteStream = MySqlSourceOperations().createGlobal(discoveredStream) + val configuredStream: ConfiguredAirbyteStream = + CatalogHelpers.toDefaultConfiguredStream(stream) + .withSyncMode(SyncMode.INCREMENTAL) + .withPrimaryKey(discoveredStream.primaryKeyColumnIDs) + .withCursorField(listOf("k")) + return ConfiguredAirbyteCatalog().withStreams(listOf(configuredStream)) + } + + @JvmStatic + @BeforeAll + @Timeout(value = 300) + fun startAndProvisionTestContainer() { + provisionTestContainer(connectionFactory) + } + + lateinit var tableName: String + + fun provisionTestContainer(targetConnectionFactory: JdbcConnectionFactory) { + tableName = (1..8).map { ('a'..'z').random() }.joinToString("") + + targetConnectionFactory.get().use { connection: Connection -> + connection.isReadOnly = false + connection.createStatement().use { stmt: Statement -> + stmt.execute("CREATE TABLE test.$tableName(k INT PRIMARY KEY, v VARCHAR(80))") + } + } + } + + lateinit var viewName: String + fun provisionView(targetConnectionFactory: JdbcConnectionFactory) { + viewName = "$tableName-view" + targetConnectionFactory.get().use { connection: Connection -> + connection.isReadOnly = false + connection.createStatement().use { stmt: Statement -> + stmt.execute("CREATE VIEW test.`$viewName` AS SELECT * FROM test.`$tableName`") + } + } + } + } + val V1_STATE: String = + """ + { + "type": "STREAM", + "stream": { + "stream_descriptor": { + "name": "$tableName", + "namespace": "test" + }, + "stream_state": { + "cursor": "10", + "version": 2, + "state_type": "cursor_based", + "stream_name": "$tableName", + "cursor_field": [ + "k" + ], + "stream_namespace": "test", + "cursor_record_count": 1 + } + } + } + """ + + // Legacy mysql connector saved the following state for an empty table in user cursor mode + val V1_STATE_EMPTY_CURSOR: String = + """ + { + "type": "STREAM", + "stream": { + "stream_descriptor": { + "name": "$tableName", + "namespace": "test" + }, + "stream_state": { + "version": 2, + "state_type": "cursor_based", + "stream_name": "$tableName", + "cursor_field": [ + "k" + ], + "stream_namespace": "test", + "cursor_record_count": 1 + } + } + } + """ +} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceDatatypeIntegrationTest.kt b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceDatatypeIntegrationTest.kt new file mode 100644 index 000000000000..06a256a29fe0 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceDatatypeIntegrationTest.kt @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.mysql + +import io.airbyte.cdk.data.AirbyteSchemaType +import io.airbyte.cdk.data.LeafAirbyteSchemaType +import io.airbyte.cdk.discover.MetaField +import io.airbyte.cdk.jdbc.JdbcConnectionFactory +import io.airbyte.cdk.read.DatatypeTestCase +import io.airbyte.cdk.read.DatatypeTestOperations +import io.airbyte.cdk.read.DynamicDatatypeTestFactory +import io.github.oshai.kotlinlogging.KotlinLogging +import java.sql.Connection +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.DynamicNode +import org.junit.jupiter.api.TestFactory +import org.junit.jupiter.api.Timeout +import org.testcontainers.containers.MySQLContainer + +class MySqlSourceDatatypeIntegrationTest { + + @TestFactory + @Timeout(300) + fun syncTests(): Iterable = + DynamicDatatypeTestFactory(MySqlSourceDatatypeTestOperations).build(dbContainer) + + companion object { + + lateinit var dbContainer: MySQLContainer<*> + + @JvmStatic + @BeforeAll + @Timeout(value = 300) + fun startAndProvisionTestContainer() { + dbContainer = MySqlContainerFactory.shared("mysql:8.0", MySqlContainerFactory.WithCdc) + } + } +} + +object MySqlSourceDatatypeTestOperations : + DatatypeTestOperations< + MySQLContainer<*>, + MySqlSourceConfigurationSpecification, + MySqlSourceConfiguration, + MySqlSourceConfigurationFactory, + MySqlSourceDatatypeTestCase + > { + + private val log = KotlinLogging.logger {} + + override val withGlobal: Boolean = true + override val globalCursorMetaField: MetaField = MySqlSourceCdcMetaFields.CDC_CURSOR + + override fun streamConfigSpec( + container: MySQLContainer<*> + ): MySqlSourceConfigurationSpecification = + MySqlContainerFactory.config(container).also { it.setIncrementalValue(UserDefinedCursor) } + + override fun globalConfigSpec( + container: MySQLContainer<*> + ): MySqlSourceConfigurationSpecification = + MySqlContainerFactory.config(container).also { it.setIncrementalValue(Cdc()) } + + override val configFactory: MySqlSourceConfigurationFactory = MySqlSourceConfigurationFactory() + + override fun createStreams(config: MySqlSourceConfiguration) { + JdbcConnectionFactory(config).get().use { connection: Connection -> + connection.isReadOnly = false + connection.createStatement().use { it.execute("CREATE DATABASE IF NOT EXISTS test") } + connection.createStatement().use { it.execute("USE test") } + for ((_, case) in testCases) { + for (ddl in case.ddl) { + log.info { "test case ${case.id}: executing $ddl" } + connection.createStatement().use { stmt -> stmt.execute(ddl) } + } + } + } + } + + override fun populateStreams(config: MySqlSourceConfiguration) { + JdbcConnectionFactory(config).get().use { connection: Connection -> + connection.isReadOnly = false + connection.createStatement().use { it.execute("USE test") } + for ((_, case) in testCases) { + for (dml in case.dml) { + log.info { "test case ${case.id}: executing $dml" } + connection.createStatement().use { stmt -> stmt.execute(dml) } + } + } + } + } + + val bitValues = + mapOf( + "b'1'" to "true", + "b'0'" to "false", + ) + + val multiBitValues = + mapOf( + "b'10101010'" to """"qg=="""", + ) + + val stringValues = + mapOf( + "'abcdef'" to """"abcdef"""", + "'ABCD'" to """"ABCD"""", + "'OXBEEF'" to """"OXBEEF"""", + ) + + val jsonValues = mapOf("""'{"col1": "v1"}'""" to """"{\"col1\": \"v1\"}"""") + + val yearValues = + mapOf( + "1992" to """1992""", + "2002" to """2002""", + "70" to """1970""", + ) + + val bigDecimalValues = + mapOf( + "10000000000000000000000000000000000000000.0001" to + "10000000000000000000000000000000000000000.0001", + ) + + val bigIntegerValues = + mapOf( + "10000000000000000000000000000000000000000" to + "10000000000000000000000000000000000000000", + ) + + val decimalValues = + mapOf( + "0.2" to """0.2""", + ) + + val floatValues = + mapOf( + "123.4567" to """123.4567""", + ) + + val doubleValues = + mapOf( + "123.4567" to """123.45670318603516""", + ) + + val zeroPrecisionDecimalValues = + mapOf( + "2" to """2""", + ) + + val tinyintValues = + mapOf( + "10" to "10", + "4" to "4", + "2" to "2", + ) + + val intValues = + mapOf( + "10" to "10", + "100000000" to "100000000", + "200000000" to "200000000", + ) + + val dateValues = + mapOf( + "'2022-01-01'" to """"2022-01-01"""", + "'0600-12-02'" to """"0600-12-02"""", + "'1752-09-09'" to """"1752-09-09"""", + "NULL" to """"2020-03-30"""" + ) + + val timeValues = + mapOf( + "'14:30:00'" to """"14:30:00.000000"""", + "NULL" to """"10:30:00.000000"""", + ) + + val dateTimeValues = + mapOf( + "'2024-09-13 14:30:00'" to """"2024-09-13T14:30:00.000000"""", + "'2024-09-13T14:40:00+00:00'" to """"2024-09-13T14:40:00.000000"""", + "'1752-09-01 14:30:00'" to """"1752-09-01T14:30:00.000000"""", + "NULL" to """"2020-03-30T10:30:00.000000"""", + ) + + val timestampValues = + mapOf( + "'2024-09-12 14:30:00'" to """"2024-09-12T14:30:00.000000Z"""", + "CONVERT_TZ('2024-09-12 14:30:00', 'America/Los_Angeles', 'UTC')" to + """"2024-09-12T21:30:00.000000Z"""", + "NULL" to """"2020-03-30T10:30:00.000000Z"""", + ) + + val booleanValues = + mapOf( + "TRUE" to "true", + "FALSE" to "false", + "NULL" to "null", + ) + + val enumValues = + mapOf( + "'a'" to """"a"""", + "'b'" to """"b"""", + "'c'" to """"c"""", + ) + + // Encoded into base64 + val binaryValues = + mapOf( + "X'89504E470D0A1A0A0000000D49484452'" to """"iVBORw0KGgoAAAANSUhEUg=="""", + ) + + override val testCases: Map = + listOf( + MySqlSourceDatatypeTestCase( + "BOOLEAN", + booleanValues, + LeafAirbyteSchemaType.BOOLEAN, + ), + MySqlSourceDatatypeTestCase( + "VARCHAR(10)", + stringValues, + LeafAirbyteSchemaType.STRING, + ), + MySqlSourceDatatypeTestCase( + "DECIMAL(60,4)", + bigDecimalValues, + LeafAirbyteSchemaType.NUMBER, + ), + MySqlSourceDatatypeTestCase( + "DECIMAL(60,0)", + bigIntegerValues, + LeafAirbyteSchemaType.INTEGER, + ), + MySqlSourceDatatypeTestCase( + "DECIMAL(10,2)", + decimalValues, + LeafAirbyteSchemaType.NUMBER, + ), + MySqlSourceDatatypeTestCase( + "DECIMAL(10,2) UNSIGNED", + decimalValues, + LeafAirbyteSchemaType.NUMBER, + ), + MySqlSourceDatatypeTestCase( + "DECIMAL UNSIGNED", + zeroPrecisionDecimalValues, + LeafAirbyteSchemaType.INTEGER, + ), + MySqlSourceDatatypeTestCase("FLOAT", floatValues, LeafAirbyteSchemaType.NUMBER), + MySqlSourceDatatypeTestCase( + "FLOAT(34)", + floatValues, + LeafAirbyteSchemaType.NUMBER, + ), + MySqlSourceDatatypeTestCase( + "FLOAT(7,4)", + floatValues, + LeafAirbyteSchemaType.NUMBER, + isGlobal = false // 123.4567 renders as 123.45670318603516 with CDC, which is OK + ), + MySqlSourceDatatypeTestCase( + "FLOAT(53,8)", + floatValues, + LeafAirbyteSchemaType.NUMBER, + // Disable CDC testing for this case: + // - 123.4567 is rendered as 123.45670318603516 + // not strictly equal due to IEEE754 encoding artifacts, but acceptable. + isGlobal = false, + ), + MySqlSourceDatatypeTestCase( + "FLOAT(53,8)", + doubleValues, + LeafAirbyteSchemaType.NUMBER, + ), + MySqlSourceDatatypeTestCase("DOUBLE", decimalValues, LeafAirbyteSchemaType.NUMBER), + MySqlSourceDatatypeTestCase( + "DOUBLE UNSIGNED", + decimalValues, + LeafAirbyteSchemaType.NUMBER, + ), + MySqlSourceDatatypeTestCase( + "TINYINT", + tinyintValues, + LeafAirbyteSchemaType.INTEGER, + ), + MySqlSourceDatatypeTestCase( + "TINYINT UNSIGNED", + tinyintValues, + LeafAirbyteSchemaType.INTEGER, + ), + MySqlSourceDatatypeTestCase( + "SMALLINT", + tinyintValues, + LeafAirbyteSchemaType.INTEGER, + ), + MySqlSourceDatatypeTestCase( + "MEDIUMINT", + tinyintValues, + LeafAirbyteSchemaType.INTEGER, + ), + MySqlSourceDatatypeTestCase("BIGINT", intValues, LeafAirbyteSchemaType.INTEGER), + MySqlSourceDatatypeTestCase( + "SMALLINT UNSIGNED", + tinyintValues, + LeafAirbyteSchemaType.INTEGER, + ), + MySqlSourceDatatypeTestCase( + "MEDIUMINT UNSIGNED", + tinyintValues, + LeafAirbyteSchemaType.INTEGER, + ), + MySqlSourceDatatypeTestCase( + "BIGINT UNSIGNED", + intValues, + LeafAirbyteSchemaType.INTEGER, + ), + MySqlSourceDatatypeTestCase("INT", intValues, LeafAirbyteSchemaType.INTEGER), + MySqlSourceDatatypeTestCase( + "INT UNSIGNED", + intValues, + LeafAirbyteSchemaType.INTEGER, + ), + MySqlSourceDatatypeTestCase( + "DATE NOT NULL DEFAULT '2020-03-30'", + dateValues, + LeafAirbyteSchemaType.DATE, + ), + MySqlSourceDatatypeTestCase( + "TIMESTAMP NOT NULL DEFAULT '2020-03-30 10:30:00'", + timestampValues, + LeafAirbyteSchemaType.TIMESTAMP_WITH_TIMEZONE, + ), + MySqlSourceDatatypeTestCase( + "DATETIME(3) NOT NULL DEFAULT '2020-03-30 10:30:00'", + dateTimeValues, + LeafAirbyteSchemaType.TIMESTAMP_WITHOUT_TIMEZONE, + ), + MySqlSourceDatatypeTestCase( + "TIME NOT NULL DEFAULT '10:30:00'", + timeValues, + LeafAirbyteSchemaType.TIME_WITHOUT_TIMEZONE, + ), + MySqlSourceDatatypeTestCase("YEAR", yearValues, LeafAirbyteSchemaType.INTEGER), + MySqlSourceDatatypeTestCase( + "VARBINARY(255)", + binaryValues, + LeafAirbyteSchemaType.BINARY, + ), + MySqlSourceDatatypeTestCase( + "BIT", + bitValues, + LeafAirbyteSchemaType.BOOLEAN, + ), + MySqlSourceDatatypeTestCase( + "BIT(8)", + multiBitValues, + LeafAirbyteSchemaType.BINARY, + ), + MySqlSourceDatatypeTestCase( + "JSON", + jsonValues, + LeafAirbyteSchemaType.STRING, // TODO: fix this bug, should be JSONB + isGlobal = false // different, more compact rendering with CDC, which is OK + ), + MySqlSourceDatatypeTestCase( + "ENUM('a', 'b', 'c')", + enumValues, + LeafAirbyteSchemaType.STRING, + ), + ) + .associateBy { it.id } +} + +data class MySqlSourceDatatypeTestCase( + val sqlType: String, + val sqlToAirbyte: Map, + override val expectedAirbyteSchemaType: AirbyteSchemaType, + override val isGlobal: Boolean = true, +) : DatatypeTestCase { + + override val isStream: Boolean + get() = true + + private val typeName: String + get() = + sqlType + .replace("[^a-zA-Z0-9]".toRegex(), " ") + .trim() + .replace(" +".toRegex(), "_") + .lowercase() + + override val id: String + get() = "tbl_$typeName" + + override val fieldName: String + get() = "col_$typeName" + + override val expectedData: List + get() = sqlToAirbyte.values.map { """{"${fieldName}":$it}""" } + + val ddl: List + get() = + listOf( + "CREATE TABLE IF NOT EXISTS $id " + + "(pk INT AUTO_INCREMENT, $fieldName $sqlType, PRIMARY KEY (pk))", + "TRUNCATE TABLE $id", + ) + + val dml: List + get() = + sqlToAirbyte.keys.map { + if (it == "NULL") { + "INSERT INTO $id VALUES ()" + } else { + "INSERT INTO $id ($fieldName) VALUES ($it)" + } + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceJdbcPartitionFactoryTest.kt b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceJdbcPartitionFactoryTest.kt new file mode 100644 index 000000000000..2075d3f44578 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceJdbcPartitionFactoryTest.kt @@ -0,0 +1,388 @@ +/* + * Copyright (c) 2024 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.mysql + +import com.fasterxml.jackson.databind.node.BinaryNode +import com.fasterxml.jackson.databind.node.ObjectNode +import io.airbyte.cdk.ClockFactory +import io.airbyte.cdk.StreamIdentifier +import io.airbyte.cdk.command.OpaqueStateValue +import io.airbyte.cdk.discover.Field +import io.airbyte.cdk.discover.MetaField +import io.airbyte.cdk.discover.MetaFieldDecorator +import io.airbyte.cdk.jdbc.BinaryStreamFieldType +import io.airbyte.cdk.jdbc.DefaultJdbcConstants +import io.airbyte.cdk.jdbc.IntFieldType +import io.airbyte.cdk.jdbc.LocalDateTimeFieldType +import io.airbyte.cdk.jdbc.OffsetDateTimeFieldType +import io.airbyte.cdk.output.BufferingOutputConsumer +import io.airbyte.cdk.read.ConcurrencyResource +import io.airbyte.cdk.read.ConfiguredSyncMode +import io.airbyte.cdk.read.DefaultJdbcSharedState +import io.airbyte.cdk.read.Feed +import io.airbyte.cdk.read.SelectQuerier +import io.airbyte.cdk.read.StateQuerier +import io.airbyte.cdk.read.Stream +import io.airbyte.cdk.read.StreamFeedBootstrap +import io.airbyte.cdk.util.Jsons +import io.airbyte.protocol.models.v0.StreamDescriptor +import io.mockk.mockk +import java.time.OffsetDateTime +import java.util.Base64 +import kotlin.test.assertNull +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.CsvSource + +class MySqlSourceJdbcPartitionFactoryTest { + companion object { + private val selectQueryGenerator = MySqlSourceOperations() + private val sharedState = sharedState() + private val cdcSharedState = sharedState(global = true) + private val config = mockk() + + val mySqlSourceJdbcPartitionFactory = + MySqlSourceJdbcPartitionFactory(sharedState, selectQueryGenerator, config) + val mysqlCdcJdbcPartitionFactory = + MySqlSourceJdbcPartitionFactory(cdcSharedState, selectQueryGenerator, config) + + val fieldId = Field("id", IntFieldType) + val stream = + Stream( + id = + StreamIdentifier.from( + StreamDescriptor().withNamespace("test").withName("stream1") + ), + schema = setOf(fieldId), + configuredSyncMode = ConfiguredSyncMode.INCREMENTAL, + configuredPrimaryKey = listOf(fieldId), + configuredCursor = fieldId, + ) + val timestampFieldId = Field("id2", OffsetDateTimeFieldType) + + val timestampStream = + Stream( + id = + StreamIdentifier.from( + StreamDescriptor().withNamespace("test").withName("stream2") + ), + schema = setOf(timestampFieldId), + configuredSyncMode = ConfiguredSyncMode.INCREMENTAL, + configuredPrimaryKey = listOf(timestampFieldId), + configuredCursor = timestampFieldId, + ) + + val binaryFieldId = Field("id3", BinaryStreamFieldType) + + val binaryStream = + Stream( + id = + StreamIdentifier.from( + StreamDescriptor().withNamespace("test").withName("stream3") + ), + schema = setOf(binaryFieldId), + configuredSyncMode = ConfiguredSyncMode.INCREMENTAL, + configuredPrimaryKey = listOf(binaryFieldId), + configuredCursor = binaryFieldId, + ) + + val datetimeFieldId = Field("id4", LocalDateTimeFieldType) + + val datetimeStream = + Stream( + id = + StreamIdentifier.from( + StreamDescriptor().withNamespace("test").withName("stream4") + ), + schema = setOf(datetimeFieldId), + configuredSyncMode = ConfiguredSyncMode.INCREMENTAL, + configuredPrimaryKey = listOf(datetimeFieldId), + configuredCursor = datetimeFieldId, + ) + + private fun sharedState( + global: Boolean = false, + ): DefaultJdbcSharedState { + + val configSpec = + MySqlSourceConfigurationSpecification().apply { + host = "" + port = 0 + username = "foo" + password = "bar" + database = "localhost" + } + if (global) { + configSpec.setIncrementalValue(Cdc()) + } else { + configSpec.setIncrementalValue(UserDefinedCursor) + } + val configFactory = MySqlSourceConfigurationFactory() + val configuration = configFactory.make(configSpec) + + val mockSelectQuerier = mockk() + + return DefaultJdbcSharedState( + configuration, + mockSelectQuerier, + DefaultJdbcConstants(), + ConcurrencyResource(configuration), + ) + } + + private fun streamFeedBootstrap( + stream: Stream, + incumbentStateValue: OpaqueStateValue? = null + ) = + StreamFeedBootstrap( + outputConsumer = BufferingOutputConsumer(ClockFactory().fixed()), + metaFieldDecorator = + object : MetaFieldDecorator { + override val globalCursor: MetaField? = null + override val globalMetaFields: Set = emptySet() + + override fun decorateRecordData( + timestamp: OffsetDateTime, + globalStateValue: OpaqueStateValue?, + stream: Stream, + recordData: ObjectNode + ) {} + }, + stateQuerier = + object : StateQuerier { + override val feeds: List = listOf(stream) + override fun current(feed: Feed): OpaqueStateValue? = + if (feed == stream) incumbentStateValue else null + override fun resetFeedStates() { + /* no-op */ + } + }, + stream, + ) + } + + @Test + fun testColdStartWithPkCursorBased() { + val jdbcPartition = mySqlSourceJdbcPartitionFactory.create(streamFeedBootstrap(stream)) + assertTrue(jdbcPartition is MySqlSourceJdbcSnapshotWithCursorPartition) + } + + @Test + fun testColdStartWithPkCdc() { + val jdbcPartition = mysqlCdcJdbcPartitionFactory.create(streamFeedBootstrap(stream)) + assertTrue(jdbcPartition is MySqlSourceJdbcCdcSnapshotPartition) + } + + @Test + fun testColdStartWithoutPk() { + val streamWithoutPk = + Stream( + id = + StreamIdentifier.from( + StreamDescriptor().withNamespace("test").withName("stream7") + ), + schema = setOf(fieldId), + configuredSyncMode = ConfiguredSyncMode.INCREMENTAL, + configuredPrimaryKey = listOf(), + configuredCursor = fieldId, + ) + val jdbcPartition = + mySqlSourceJdbcPartitionFactory.create(streamFeedBootstrap(streamWithoutPk)) + assertTrue(jdbcPartition is MySqlSourceJdbcNonResumableSnapshotWithCursorPartition) + } + + @Test + fun testResumeFromCompletedCursorBasedRead() { + val incomingStateValue: OpaqueStateValue = + Jsons.readTree( + """ + { + "cursor": "2", + "version": 2, + "state_type": "cursor_based", + "stream_name": "stream1", + "cursor_field": [ + "id" + ], + "stream_namespace": "test", + "cursor_record_count": 1 + } + """.trimIndent() + ) + + val jdbcPartition = + mySqlSourceJdbcPartitionFactory.create(streamFeedBootstrap(stream, incomingStateValue)) + assertTrue(jdbcPartition is MySqlSourceJdbcCursorIncrementalPartition) + } + + @ParameterizedTest + @CsvSource( + "'2025-09-03T05:23:35', '2025-09-03T05:23:35.000000Z'", + "'2025-09-03T05:23:35.0', '2025-09-03T05:23:35.000000Z'", + "'2025-09-03T05:23:35.1', '2025-09-03T05:23:35.100000Z'", + "'2025-09-03T05:23:35.123', '2025-09-03T05:23:35.123000Z'", + "'2025-09-03T05:23:35.123456789', '2025-09-03T05:23:35.123456Z'", + "'2025-09-03T05:23:35.123+00:00', '2025-09-03T05:23:35.123000Z'", + "'2025-09-03T05:23:35.123+00:00', '2025-09-03T05:23:35.123000Z'", + "'2025-09-03T05:23:35Z', '2025-09-03T05:23:35.000000Z'", + "'2025-09-03T05:23:35 Z', '2025-09-03T05:23:35.000000Z'", + "'2025-09-03T05:23:35.12345 +12:34', '2025-09-03T05:23:35.123450+12:34'", + ) + fun testResumeFromCompletedCursorBasedReadTimestamp( + cursorVal: String, + expectedLowerBound: String + ) { + val incomingStateValue: OpaqueStateValue = + Jsons.readTree( + """ + { + "cursor": "$cursorVal", + "version": 2, + "state_type": "cursor_based", + "stream_name": "stream2", + "cursor_field": [ + "id2" + ], + "stream_namespace": "test", + "cursor_record_count": 1 + } + """.trimIndent() + ) + + val jdbcPartition = + mySqlSourceJdbcPartitionFactory.create( + streamFeedBootstrap(timestampStream, incomingStateValue) + ) + assertTrue(jdbcPartition is MySqlSourceJdbcCursorIncrementalPartition) + + assertEquals( + Jsons.valueToTree(expectedLowerBound), + (jdbcPartition as MySqlSourceJdbcCursorIncrementalPartition).cursorLowerBound + ) + } + + @Test + fun testResumeFromCompletedCursorBasedReadTimestampWithoutTimezone() { + val incomingStateValue: OpaqueStateValue = + Jsons.readTree( + """ + { + "cursor": "2024-11-21T11:59:57.123", + "version": 2, + "state_type": "cursor_based", + "stream_name": "stream4", + "cursor_field": [ + "id4" + ], + "stream_namespace": "test", + "cursor_record_count": 1 + } + """.trimIndent() + ) + + val jdbcPartition = + mySqlSourceJdbcPartitionFactory.create( + streamFeedBootstrap(datetimeStream, incomingStateValue) + ) + assertTrue(jdbcPartition is MySqlSourceJdbcCursorIncrementalPartition) + + assertEquals( + Jsons.valueToTree("2024-11-21T11:59:57.123000"), + (jdbcPartition as MySqlSourceJdbcCursorIncrementalPartition).cursorLowerBound + ) + } + + @Test + fun testResumeFromCursorBasedReadInitialRead() { + val incomingStateValue: OpaqueStateValue = + Jsons.readTree( + """ + { + "pk_val": "9063170", + "pk_name": "id", + "version": 2, + "state_type": "primary_key", + "incremental_state": {} + } + """.trimIndent() + ) + + val jdbcPartition = + mySqlSourceJdbcPartitionFactory.create(streamFeedBootstrap(stream, incomingStateValue)) + + assertTrue(jdbcPartition is MySqlSourceJdbcSnapshotWithCursorPartition) + } + + @Test + fun testResumeFromCdcInitialRead() { + val incomingStateValue: OpaqueStateValue = + Jsons.readTree( + """ + { + "pk_val": "29999", + "pk_name": "id", + "version": 2, + "state_type": "primary_key", + "incremental_state": {} + } + """.trimIndent() + ) + + val jdbcPartition = + mysqlCdcJdbcPartitionFactory.create(streamFeedBootstrap(stream, incomingStateValue)) + assertTrue(jdbcPartition is MySqlSourceJdbcCdcSnapshotPartition) + } + + @Test + fun testResumeFromCdcInitialReadComplete() { + val incomingStateValue: OpaqueStateValue = + Jsons.readTree( + """ + { + "stream_name": "stream1", + "cursor_field": [], + "stream_namespace": "test" + } + """.trimIndent() + ) + + val jdbcPartition = + mysqlCdcJdbcPartitionFactory.create(streamFeedBootstrap(stream, incomingStateValue)) + assertNull(jdbcPartition) + } + + @Test + fun testResumeFromCompletedCursorBasedReadBinary() { + val incomingStateValue: OpaqueStateValue = + Jsons.readTree( + """ + { + "cursor": "OQAAAAAAAAAAAAAAAAAAAA==", + "version": 2, + "state_type": "cursor_based", + "stream_name": "stream3", + "cursor_field": [ + "id3" + ], + "stream_namespace": "test", + "cursor_record_count": 1 + } + """.trimIndent() + ) + + val jdbcPartition = + mySqlSourceJdbcPartitionFactory.create( + streamFeedBootstrap(binaryStream, incomingStateValue) + ) + assertTrue(jdbcPartition is MySqlSourceJdbcCursorIncrementalPartition) + + assertEquals( + Jsons.valueToTree(Base64.getDecoder().decode("OQAAAAAAAAAAAAAAAAAAAA==")), + (jdbcPartition as MySqlSourceJdbcCursorIncrementalPartition).cursorLowerBound + ) + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceSelectQueryGeneratorTest.kt b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceSelectQueryGeneratorTest.kt new file mode 100644 index 000000000000..226ba557234e --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceSelectQueryGeneratorTest.kt @@ -0,0 +1,145 @@ +/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ +package io.airbyte.integrations.source.mysql + +import com.fasterxml.jackson.databind.JsonNode +import io.airbyte.cdk.discover.Field +import io.airbyte.cdk.jdbc.DoubleFieldType +import io.airbyte.cdk.jdbc.IntFieldType +import io.airbyte.cdk.jdbc.LongFieldType +import io.airbyte.cdk.jdbc.LosslessJdbcFieldType +import io.airbyte.cdk.jdbc.OffsetDateTimeFieldType +import io.airbyte.cdk.jdbc.StringFieldType +import io.airbyte.cdk.read.And +import io.airbyte.cdk.read.Equal +import io.airbyte.cdk.read.From +import io.airbyte.cdk.read.Greater +import io.airbyte.cdk.read.LesserOrEqual +import io.airbyte.cdk.read.Limit +import io.airbyte.cdk.read.Or +import io.airbyte.cdk.read.OrderBy +import io.airbyte.cdk.read.SelectColumnMaxValue +import io.airbyte.cdk.read.SelectColumns +import io.airbyte.cdk.read.SelectQuery +import io.airbyte.cdk.read.SelectQuerySpec +import io.airbyte.cdk.read.Where +import io.airbyte.cdk.read.optimize +import io.airbyte.cdk.util.Jsons +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class MySqlSourceSelectQueryGeneratorTest { + @Test + fun testSelectLimit0() { + SelectQuerySpec( + SelectColumns( + listOf( + Field("k", IntFieldType), + Field("v", StringFieldType), + ), + ), + From("TBL", "SC"), + limit = Limit(0), + ) + .assertSqlEquals("""SELECT `k`, `v` FROM `SC`.`TBL` LIMIT 0""") + } + + @Test + fun testSelectMaxCursor() { + SelectQuerySpec( + SelectColumnMaxValue(Field("ts", OffsetDateTimeFieldType)), + From("TBL", "SC"), + ) + .assertSqlEquals("""SELECT MAX(`ts`) FROM `SC`.`TBL`""") + } + + @Test + fun testSelectForNonResumableInitialSync() { + SelectQuerySpec( + SelectColumns( + listOf( + Field("k", IntFieldType), + Field("v", StringFieldType), + ), + ), + From("TBL", "SC"), + ) + .assertSqlEquals("""SELECT `k`, `v` FROM `SC`.`TBL`""") + } + + @Test + fun testSelectForResumableInitialSync() { + val k1 = Field("k1", IntFieldType) + val v1 = Jsons.numberNode(10) + val k2 = Field("k2", IntFieldType) + val v2 = Jsons.numberNode(20) + val k3 = Field("k3", IntFieldType) + val v3 = Jsons.numberNode(30) + SelectQuerySpec( + SelectColumns(listOf(k1, k2, k3, Field("msg", StringFieldType))), + From("TBL", "SC"), + Where( + Or( + listOf( + And(listOf(Greater(k1, v1))), + And(listOf(Equal(k1, v1), Greater(k2, v2))), + And(listOf(Equal(k1, v1), Equal(k2, v2), Greater(k3, v3))), + ), + ), + ), + OrderBy(listOf(k1, k2, k3)), + Limit(1000), + ) + .assertSqlEquals( + """SELECT `k1`, `k2`, `k3`, `msg` FROM """ + + """`SC`.`TBL` WHERE (`k1` > ?) OR """ + + """((`k1` = ?) AND (`k2` > ?)) OR """ + + """((`k1` = ?) AND (`k2` = ?) AND (`k3` > ?)) """ + + """ORDER BY `k1`, `k2`, `k3`""" + + " LIMIT ?", + v1 to IntFieldType, + v1 to IntFieldType, + v2 to IntFieldType, + v1 to IntFieldType, + v2 to IntFieldType, + v3 to IntFieldType, + Jsons.numberNode(1000L) to LongFieldType, + ) + } + + @Test + fun testSelectForCursorBasedIncrementalSync() { + val c = Field("c", DoubleFieldType) + val lb = Jsons.numberNode(0.5) + val ub = Jsons.numberNode(0.5) + SelectQuerySpec( + SelectColumns(listOf(Field("msg", StringFieldType), c)), + From("TBL", "SC"), + Where(And(listOf(Greater(c, lb), LesserOrEqual(c, ub)))), + OrderBy(listOf(c)), + Limit(1000), + ) + .assertSqlEquals( + """SELECT `msg`, `c` FROM """ + + """`SC`.`TBL` """ + + """WHERE (`c` > ?) AND (`c` <= ?) ORDER BY `c`""" + + " LIMIT ?", + lb to DoubleFieldType, + ub to DoubleFieldType, + Jsons.numberNode(1000L) to LongFieldType, + ) + } + + private fun SelectQuerySpec.assertSqlEquals( + sql: String, + vararg bindings: Pair>, + ) { + val expected = + SelectQuery( + sql, + select.columns, + bindings.map { SelectQuery.Binding(it.first, it.second) }, + ) + val actual: SelectQuery = MySqlSourceOperations().generate(this.optimize()) + Assertions.assertEquals(expected, actual) + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceSpecIntegrationTest.kt b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceSpecIntegrationTest.kt new file mode 100644 index 000000000000..bd77db88b100 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceSpecIntegrationTest.kt @@ -0,0 +1,12 @@ +/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ +package io.airbyte.integrations.source.mysql + +import io.airbyte.cdk.command.SyncsTestFixture +import org.junit.jupiter.api.Test + +class MySqlSourceSpecIntegrationTest { + @Test + fun testSpec() { + SyncsTestFixture.testSpec("expected-spec.json") + } +} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceTestConfigurationFactory.kt b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceTestConfigurationFactory.kt new file mode 100644 index 000000000000..ef6621958f59 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/test/kotlin/io/airbyte/integrations/source/mysql/MySqlSourceTestConfigurationFactory.kt @@ -0,0 +1,28 @@ +/* Copyright (c) 2024 Airbyte, Inc., all rights reserved. */ +package io.airbyte.integrations.source.mysql + +import io.airbyte.cdk.command.FeatureFlag +import io.airbyte.cdk.command.SourceConfigurationFactory +import io.micronaut.context.annotation.Primary +import io.micronaut.context.annotation.Requires +import io.micronaut.context.env.Environment +import jakarta.inject.Singleton +import java.time.Duration + +@Singleton +@Requires(env = [Environment.TEST]) +@Primary +class MySqlSourceTestConfigurationFactory(val featureFlags: Set) : + SourceConfigurationFactory { + override fun makeWithoutExceptionHandling( + pojo: MySqlSourceConfigurationSpecification, + ): MySqlSourceConfiguration = + MySqlSourceConfigurationFactory(featureFlags) + .makeWithoutExceptionHandling(pojo) + .copy( + maxConcurrency = 1, + checkpointTargetInterval = Duration.ofSeconds(3), + debeziumHeartbeatInterval = Duration.ofMillis(100), + debeziumKeepAliveInterval = Duration.ofSeconds(1), + ) +} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/resources/expected-spec.json b/airbyte-integrations/connectors/source-mysql/src/test/resources/expected-spec.json new file mode 100644 index 000000000000..4bdfdc184ae8 --- /dev/null +++ b/airbyte-integrations/connectors/source-mysql/src/test/resources/expected-spec.json @@ -0,0 +1,380 @@ +{ + "connectionSpecification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "check_privileges": { + "default": true, + "description": "When this feature is enabled, during schema discovery the connector will query each table or view individually to check access privileges and inaccessible tables, views, or columns therein will be removed. In large schemas, this might cause schema discovery to take too long, in which case it might be advisable to disable this feature.", + "order": 13, + "title": "Check Table and Column Access Privileges", + "type": "boolean" + }, + "checkpoint_target_interval_seconds": { + "default": 300, + "description": "How often (in seconds) a stream should checkpoint, when possible.", + "order": 11, + "title": "Checkpoint Target Time Interval", + "type": "integer" + }, + "concurrency": { + "default": 1, + "description": "Maximum number of concurrent queries to the database.", + "order": 12, + "title": "Concurrency", + "type": "integer" + }, + "database": { + "always_show": true, + "description": "The database name.", + "order": 6, + "title": "Database", + "type": "string" + }, + "host": { + "description": "Hostname of the database.", + "order": 1, + "title": "Host", + "type": "string" + }, + "jdbc_url_params": { + "description": "Additional properties to pass to the JDBC URL string when connecting to the database formatted as 'key=value' pairs separated by the symbol '&'. (example: key1=value1&key2=value2&key3=value3).", + "order": 7, + "title": "JDBC URL Params", + "type": "string" + }, + "password": { + "airbyte_secret": true, + "always_show": true, + "description": "The password associated with the username.", + "order": 5, + "title": "Password", + "type": "string" + }, + "port": { + "default": 3306, + "description": "Port of the database.", + "maximum": 65536, + "minimum": 0, + "order": 2, + "title": "Port", + "type": "integer" + }, + "replication_method": { + "description": "Configures how data is extracted from the database.", + "display_type": "radio", + "oneOf": [ + { + "additionalProperties": true, + "description": "Incrementally detects new inserts and updates using the cursor column chosen when configuring a connection (e.g. created_at, updated_at).", + "properties": { + "method": { + "default": "STANDARD", + "enum": ["STANDARD"], + "type": "string" + } + }, + "required": ["method"], + "title": "Scan Changes with User Defined Cursor", + "type": "object" + }, + { + "additionalProperties": true, + "description": "Recommended - Incrementally reads new inserts, updates, and deletes using MySQL's change data capture feature. This must be enabled on your database.", + "properties": { + "initial_load_timeout_hours": { + "always_show": true, + "default": 8, + "description": "The amount of time an initial load is allowed to continue for before catching up on CDC logs.", + "max": 24, + "min": 4, + "order": 3, + "title": "Initial Load Timeout in Hours (Advanced)", + "type": "integer" + }, + "invalid_cdc_cursor_position_behavior": { + "always_show": true, + "default": "Fail sync", + "description": "Enter the configured MySQL server timezone. This should only be done if the configured timezone in your MySQL instance does not conform to IANNA standard.", + "enum": ["Fail sync", "Re-sync data"], + "order": 2, + "title": "Configured server timezone for the MySQL source (Advanced)", + "type": "string" + }, + "method": { + "default": "CDC", + "enum": ["CDC"], + "type": "string" + }, + "server_timezone": { + "always_show": true, + "description": "Enter the configured MySQL server timezone. This should only be done if the configured timezone in your MySQL instance does not conform to IANNA standard.", + "order": 1, + "title": "Configured server timezone for the MySQL source (Advanced)", + "type": "string" + } + }, + "required": ["method"], + "title": "Read Changes using Change Data Capture (CDC)", + "type": "object" + } + ], + "order": 10, + "title": "Update Method", + "type": "object" + }, + "ssl_mode": { + "description": "The encryption method with is used when communicating with the database.", + "oneOf": [ + { + "additionalProperties": true, + "description": "To allow unencrypted communication only when the source doesn't support encryption.", + "properties": { + "mode": { + "default": "preferred", + "enum": ["preferred"], + "type": "string" + } + }, + "required": ["mode"], + "title": "preferred", + "type": "object" + }, + { + "additionalProperties": true, + "description": "To always require encryption. Note: The connection will fail if the source doesn't support encryption.", + "properties": { + "mode": { + "default": "required", + "enum": ["required"], + "type": "string" + } + }, + "required": ["mode"], + "title": "required", + "type": "object" + }, + { + "additionalProperties": true, + "description": "To always require encryption and verify that the source has a valid SSL certificate.", + "properties": { + "ca_certificate": { + "airbyte_secret": true, + "description": "CA certificate", + "multiline": true, + "title": "CA certificate", + "type": "string" + }, + "client_certificate": { + "airbyte_secret": true, + "description": "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", + "multiline": true, + "title": "Client certificate File", + "type": "string" + }, + "client_key": { + "airbyte_secret": true, + "description": "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", + "multiline": true, + "title": "Client Key", + "type": "string" + }, + "client_key_password": { + "airbyte_secret": true, + "description": "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", + "multiline": true, + "title": "Client key password", + "type": "string" + }, + "mode": { + "default": "verify_ca", + "enum": ["verify_ca"], + "type": "string" + } + }, + "required": ["mode", "ca_certificate"], + "title": "verify_ca", + "type": "object" + }, + { + "additionalProperties": true, + "description": "To always require encryption and verify that the source has a valid SSL certificate.", + "properties": { + "ca_certificate": { + "airbyte_secret": true, + "description": "CA certificate", + "multiline": true, + "title": "CA certificate", + "type": "string" + }, + "client_certificate": { + "airbyte_secret": true, + "description": "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", + "multiline": true, + "title": "Client certificate File", + "type": "string" + }, + "client_key": { + "airbyte_secret": true, + "description": "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", + "multiline": true, + "title": "Client Key", + "type": "string" + }, + "client_key_password": { + "airbyte_secret": true, + "description": "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", + "multiline": true, + "title": "Client key password", + "type": "string" + }, + "mode": { + "default": "verify_identity", + "enum": ["verify_identity"], + "type": "string" + } + }, + "required": ["mode", "ca_certificate"], + "title": "verify_identity", + "type": "object" + } + ], + "order": 8, + "title": "Encryption", + "type": "object" + }, + "tunnel_method": { + "description": "Whether to initiate an SSH tunnel before connecting to the database, and if so, which kind of authentication to use.", + "oneOf": [ + { + "additionalProperties": true, + "description": "No ssh tunnel needed to connect to database", + "properties": { + "tunnel_method": { + "default": "NO_TUNNEL", + "enum": ["NO_TUNNEL"], + "type": "string" + } + }, + "required": ["tunnel_method"], + "title": "No Tunnel", + "type": "object" + }, + { + "additionalProperties": true, + "description": "Connect through a jump server tunnel host using username and ssh key", + "properties": { + "ssh_key": { + "airbyte_secret": true, + "description": "OS-level user account ssh key credentials in RSA PEM format ( created with ssh-keygen -t rsa -m PEM -f myuser_rsa )", + "multiline": true, + "order": 4, + "title": "SSH Private Key", + "type": "string" + }, + "tunnel_host": { + "description": "Hostname of the jump server host that allows inbound ssh tunnel.", + "order": 1, + "title": "SSH Tunnel Jump Server Host", + "type": "string" + }, + "tunnel_method": { + "default": "SSH_KEY_AUTH", + "enum": ["SSH_KEY_AUTH"], + "type": "string" + }, + "tunnel_port": { + "default": 22, + "description": "Port on the proxy/jump server that accepts inbound ssh connections.", + "maximum": 65536, + "minimum": 0, + "order": 2, + "title": "SSH Connection Port", + "type": "integer" + }, + "tunnel_user": { + "description": "OS-level username for logging into the jump server host", + "order": 3, + "title": "SSH Login Username", + "type": "string" + } + }, + "required": [ + "tunnel_method", + "tunnel_host", + "tunnel_port", + "tunnel_user", + "ssh_key" + ], + "title": "SSH Key Authentication", + "type": "object" + }, + { + "additionalProperties": true, + "description": "Connect through a jump server tunnel host using username and password authentication", + "properties": { + "tunnel_host": { + "description": "Hostname of the jump server host that allows inbound ssh tunnel.", + "order": 1, + "title": "SSH Tunnel Jump Server Host", + "type": "string" + }, + "tunnel_method": { + "default": "SSH_PASSWORD_AUTH", + "enum": ["SSH_PASSWORD_AUTH"], + "type": "string" + }, + "tunnel_port": { + "default": 22, + "description": "Port on the proxy/jump server that accepts inbound ssh connections.", + "maximum": 65536, + "minimum": 0, + "order": 2, + "title": "SSH Connection Port", + "type": "integer" + }, + "tunnel_user": { + "description": "OS-level username for logging into the jump server host", + "order": 3, + "title": "SSH Login Username", + "type": "string" + }, + "tunnel_user_password": { + "airbyte_secret": true, + "description": "OS-level password for logging into the jump server host", + "order": 4, + "title": "Password", + "type": "string" + } + }, + "required": [ + "tunnel_method", + "tunnel_host", + "tunnel_port", + "tunnel_user", + "tunnel_user_password" + ], + "title": "Password Authentication", + "type": "object" + } + ], + "order": 9, + "title": "SSH Tunnel Method", + "type": "object" + }, + "username": { + "description": "The username which is used to access the database.", + "order": 4, + "title": "User", + "type": "string" + } + }, + "required": ["host", "port", "database", "username", "replication_method"], + "title": "MySQL Source Spec", + "type": "object" + }, + "documentationUrl": "https://docs.airbyte.com/integrations/sources/mysql", + "supported_destination_sync_modes": [], + "supportsDBT": false, + "supportsNormalization": false +} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/resources/expected_cloud_spec.json b/airbyte-integrations/connectors/source-mysql/src/test/resources/expected_cloud_spec.json deleted file mode 100644 index 29c00d0c7b7a..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test/resources/expected_cloud_spec.json +++ /dev/null @@ -1,246 +0,0 @@ -{ - "documentationUrl": "https://docs.airbyte.com/integrations/sources/mysql", - "connectionSpecification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MySql Source Spec", - "type": "object", - "required": ["host", "port", "database", "username", "replication_method"], - "properties": { - "host": { - "description": "The host name of the database.", - "title": "Host", - "type": "string", - "order": 0 - }, - "port": { - "description": "The port to connect to.", - "title": "Port", - "type": "integer", - "minimum": 0, - "maximum": 65536, - "default": 3306, - "examples": ["3306"], - "order": 1 - }, - "database": { - "description": "The database name.", - "title": "Database", - "type": "string", - "order": 2 - }, - "username": { - "description": "The username which is used to access the database.", - "title": "Username", - "type": "string", - "order": 3 - }, - "password": { - "description": "The password associated with the username.", - "title": "Password", - "type": "string", - "airbyte_secret": true, - "order": 4, - "always_show": true - }, - "jdbc_url_params": { - "description": "Additional properties to pass to the JDBC URL string when connecting to the database formatted as 'key=value' pairs separated by the symbol '&'. (example: key1=value1&key2=value2&key3=value3). For more information read about JDBC URL parameters.", - "title": "JDBC URL Parameters (Advanced)", - "type": "string", - "order": 5 - }, - "ssl_mode": { - "title": "SSL modes", - "description": "SSL connection modes. Read more in the docs.", - "type": "object", - "order": 7, - "oneOf": [ - { - "title": "preferred", - "description": "Automatically attempt SSL connection. If the MySQL server does not support SSL, continue with a regular connection.", - "required": ["mode"], - "properties": { - "mode": { - "type": "string", - "const": "preferred", - "order": 0 - } - } - }, - { - "title": "required", - "description": "Always connect with SSL. If the MySQL server doesn’t support SSL, the connection will not be established. Certificate Authority (CA) and Hostname are not verified.", - "required": ["mode"], - "properties": { - "mode": { - "type": "string", - "const": "required", - "order": 0 - } - } - }, - { - "title": "Verify CA", - "description": "Always connect with SSL. Verifies CA, but allows connection even if Hostname does not match.", - "required": ["mode", "ca_certificate"], - "properties": { - "mode": { - "type": "string", - "const": "verify_ca", - "order": 0 - }, - "ca_certificate": { - "type": "string", - "title": "CA certificate", - "description": "CA certificate", - "airbyte_secret": true, - "multiline": true, - "order": 1 - }, - "client_certificate": { - "type": "string", - "title": "Client certificate", - "description": "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", - "airbyte_secret": true, - "multiline": true, - "order": 2, - "always_show": true - }, - "client_key": { - "type": "string", - "title": "Client key", - "description": "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", - "airbyte_secret": true, - "multiline": true, - "order": 3, - "always_show": true - }, - "client_key_password": { - "type": "string", - "title": "Client key password", - "description": "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", - "airbyte_secret": true, - "order": 4 - } - } - }, - { - "title": "Verify Identity", - "description": "Always connect with SSL. Verify both CA and Hostname.", - "required": ["mode", "ca_certificate"], - "properties": { - "mode": { - "type": "string", - "const": "verify_identity", - "order": 0 - }, - "ca_certificate": { - "type": "string", - "title": "CA certificate", - "description": "CA certificate", - "airbyte_secret": true, - "multiline": true, - "order": 1 - }, - "client_certificate": { - "type": "string", - "title": "Client certificate", - "description": "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", - "airbyte_secret": true, - "multiline": true, - "order": 2, - "always_show": true - }, - "client_key": { - "type": "string", - "title": "Client key", - "description": "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", - "airbyte_secret": true, - "multiline": true, - "order": 3, - "always_show": true - }, - "client_key_password": { - "type": "string", - "title": "Client key password", - "description": "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", - "airbyte_secret": true, - "order": 4 - } - } - } - ], - "default": "required" - }, - "replication_method": { - "type": "object", - "title": "Update Method", - "description": "Configures how data is extracted from the database.", - "order": 8, - "default": "CDC", - "display_type": "radio", - "oneOf": [ - { - "title": "Read Changes using Binary Log (CDC)", - "description": "Recommended - Incrementally reads new inserts, updates, and deletes using the MySQL binary log. This must be enabled on your database.", - "required": ["method"], - "properties": { - "method": { - "type": "string", - "const": "CDC", - "order": 0 - }, - "initial_waiting_seconds": { - "type": "integer", - "title": "Initial Waiting Time in Seconds (Advanced)", - "description": "The amount of time the connector will wait when it launches to determine if there is new data to sync or not. Defaults to 300 seconds. Valid range: 120 seconds to 1200 seconds. Read about initial waiting time.", - "default": 300, - "min": 120, - "max": 1200, - "order": 1, - "always_show": true - }, - "server_time_zone": { - "type": "string", - "title": "Configured server timezone for the MySQL source (Advanced)", - "description": "Enter the configured MySQL server timezone. This should only be done if the configured timezone in your MySQL instance does not conform to IANNA standard.", - "order": 2, - "always_show": true - }, - "invalid_cdc_cursor_position_behavior": { - "type": "string", - "title": "Invalid CDC position behavior (Advanced)", - "description": "Determines whether Airbyte should fail or re-sync data in case of an stale/invalid cursor value into the WAL. If 'Fail sync' is chosen, a user will have to manually reset the connection before being able to continue syncing data. If 'Re-sync data' is chosen, Airbyte will automatically trigger a refresh but could lead to higher cloud costs and data loss.", - "enum": ["Fail sync", "Re-sync data"], - "default": "Fail sync", - "order": 3, - "always_show": true - }, - "initial_load_timeout_hours": { - "type": "integer", - "title": "Initial Load Timeout in Hours (Advanced)", - "description": "The amount of time an initial load is allowed to continue for before catching up on CDC logs.", - "default": 8, - "min": 4, - "max": 24, - "order": 4, - "always_show": true - } - } - }, - { - "title": "Scan Changes with User Defined Cursor", - "description": "Incrementally detects new inserts and updates using the cursor column chosen when configuring a connection (e.g. created_at, updated_at).", - "required": ["method"], - "properties": { - "method": { - "type": "string", - "const": "STANDARD", - "order": 0 - } - } - } - ] - } - } - } -} diff --git a/airbyte-integrations/connectors/source-mysql/src/test/resources/expected_oss_spec.json b/airbyte-integrations/connectors/source-mysql/src/test/resources/expected_oss_spec.json deleted file mode 100644 index 5a9304326cdd..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/test/resources/expected_oss_spec.json +++ /dev/null @@ -1,252 +0,0 @@ -{ - "documentationUrl": "https://docs.airbyte.com/integrations/sources/mysql", - "connectionSpecification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MySql Source Spec", - "type": "object", - "required": ["host", "port", "database", "username", "replication_method"], - "properties": { - "host": { - "description": "The host name of the database.", - "title": "Host", - "type": "string", - "order": 0 - }, - "port": { - "description": "The port to connect to.", - "title": "Port", - "type": "integer", - "minimum": 0, - "maximum": 65536, - "default": 3306, - "examples": ["3306"], - "order": 1 - }, - "database": { - "description": "The database name.", - "title": "Database", - "type": "string", - "order": 2 - }, - "username": { - "description": "The username which is used to access the database.", - "title": "Username", - "type": "string", - "order": 3 - }, - "password": { - "description": "The password associated with the username.", - "title": "Password", - "type": "string", - "airbyte_secret": true, - "order": 4, - "always_show": true - }, - "jdbc_url_params": { - "description": "Additional properties to pass to the JDBC URL string when connecting to the database formatted as 'key=value' pairs separated by the symbol '&'. (example: key1=value1&key2=value2&key3=value3). For more information read about JDBC URL parameters.", - "title": "JDBC URL Parameters (Advanced)", - "type": "string", - "order": 5 - }, - "ssl": { - "title": "SSL Connection", - "description": "Encrypt data using SSL.", - "type": "boolean", - "default": true, - "order": 6 - }, - "ssl_mode": { - "title": "SSL modes", - "description": "SSL connection modes. Read more in the docs.", - "type": "object", - "order": 7, - "oneOf": [ - { - "title": "preferred", - "description": "Automatically attempt SSL connection. If the MySQL server does not support SSL, continue with a regular connection.", - "required": ["mode"], - "properties": { - "mode": { - "type": "string", - "const": "preferred", - "order": 0 - } - } - }, - { - "title": "required", - "description": "Always connect with SSL. If the MySQL server doesn’t support SSL, the connection will not be established. Certificate Authority (CA) and Hostname are not verified.", - "required": ["mode"], - "properties": { - "mode": { - "type": "string", - "const": "required", - "order": 0 - } - } - }, - { - "title": "Verify CA", - "description": "Always connect with SSL. Verifies CA, but allows connection even if Hostname does not match.", - "required": ["mode", "ca_certificate"], - "properties": { - "mode": { - "type": "string", - "const": "verify_ca", - "order": 0 - }, - "ca_certificate": { - "type": "string", - "title": "CA certificate", - "description": "CA certificate", - "airbyte_secret": true, - "multiline": true, - "order": 1 - }, - "client_certificate": { - "type": "string", - "title": "Client certificate", - "description": "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", - "airbyte_secret": true, - "multiline": true, - "order": 2, - "always_show": true - }, - "client_key": { - "type": "string", - "title": "Client key", - "description": "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", - "airbyte_secret": true, - "multiline": true, - "order": 3, - "always_show": true - }, - "client_key_password": { - "type": "string", - "title": "Client key password", - "description": "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", - "airbyte_secret": true, - "order": 4 - } - } - }, - { - "title": "Verify Identity", - "description": "Always connect with SSL. Verify both CA and Hostname.", - "required": ["mode", "ca_certificate"], - "properties": { - "mode": { - "type": "string", - "const": "verify_identity", - "order": 0 - }, - "ca_certificate": { - "type": "string", - "title": "CA certificate", - "description": "CA certificate", - "airbyte_secret": true, - "multiline": true, - "order": 1 - }, - "client_certificate": { - "type": "string", - "title": "Client certificate", - "description": "Client certificate (this is not a required field, but if you want to use it, you will need to add the Client key as well)", - "airbyte_secret": true, - "multiline": true, - "order": 2, - "always_show": true - }, - "client_key": { - "type": "string", - "title": "Client key", - "description": "Client key (this is not a required field, but if you want to use it, you will need to add the Client certificate as well)", - "airbyte_secret": true, - "multiline": true, - "order": 3, - "always_show": true - }, - "client_key_password": { - "type": "string", - "title": "Client key password", - "description": "Password for keystorage. This field is optional. If you do not add it - the password will be generated automatically.", - "airbyte_secret": true, - "order": 4 - } - } - } - ] - }, - "replication_method": { - "type": "object", - "title": "Update Method", - "description": "Configures how data is extracted from the database.", - "order": 8, - "default": "CDC", - "display_type": "radio", - "oneOf": [ - { - "title": "Read Changes using Binary Log (CDC)", - "description": "Recommended - Incrementally reads new inserts, updates, and deletes using the MySQL binary log. This must be enabled on your database.", - "required": ["method"], - "properties": { - "method": { - "type": "string", - "const": "CDC", - "order": 0 - }, - "initial_waiting_seconds": { - "type": "integer", - "title": "Initial Waiting Time in Seconds (Advanced)", - "description": "The amount of time the connector will wait when it launches to determine if there is new data to sync or not. Defaults to 300 seconds. Valid range: 120 seconds to 1200 seconds. Read about initial waiting time.", - "default": 300, - "min": 120, - "max": 1200, - "order": 1, - "always_show": true - }, - "server_time_zone": { - "type": "string", - "title": "Configured server timezone for the MySQL source (Advanced)", - "description": "Enter the configured MySQL server timezone. This should only be done if the configured timezone in your MySQL instance does not conform to IANNA standard.", - "order": 2, - "always_show": true - }, - "invalid_cdc_cursor_position_behavior": { - "type": "string", - "title": "Invalid CDC position behavior (Advanced)", - "description": "Determines whether Airbyte should fail or re-sync data in case of an stale/invalid cursor value into the WAL. If 'Fail sync' is chosen, a user will have to manually reset the connection before being able to continue syncing data. If 'Re-sync data' is chosen, Airbyte will automatically trigger a refresh but could lead to higher cloud costs and data loss.", - "enum": ["Fail sync", "Re-sync data"], - "default": "Fail sync", - "order": 3, - "always_show": true - }, - "initial_load_timeout_hours": { - "type": "integer", - "title": "Initial Load Timeout in Hours (Advanced)", - "description": "The amount of time an initial load is allowed to continue for before catching up on CDC logs.", - "default": 8, - "min": 4, - "max": 24, - "order": 4, - "always_show": true - } - } - }, - { - "title": "Scan Changes with User Defined Cursor", - "description": "Incrementally detects new inserts and updates using the cursor column chosen when configuring a connection (e.g. created_at, updated_at).", - "required": ["method"], - "properties": { - "method": { - "type": "string", - "const": "STANDARD", - "order": 0 - } - } - } - ] - } - } - } -} diff --git a/airbyte-integrations/connectors/source-mysql/src/testFixtures/java/io/airbyte/integrations/source/mysql/MySQLContainerFactory.java b/airbyte-integrations/connectors/source-mysql/src/testFixtures/java/io/airbyte/integrations/source/mysql/MySQLContainerFactory.java deleted file mode 100644 index 2e9fba65fbb7..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/testFixtures/java/io/airbyte/integrations/source/mysql/MySQLContainerFactory.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -import io.airbyte.cdk.testutils.ContainerFactory; -import java.io.IOException; -import java.io.UncheckedIOException; -import org.testcontainers.containers.MySQLContainer; -import org.testcontainers.containers.Network; -import org.testcontainers.utility.DockerImageName; - -public class MySQLContainerFactory extends ContainerFactory> { - - @Override - protected MySQLContainer createNewContainer(DockerImageName imageName) { - return new MySQLContainer<>(imageName.asCompatibleSubstituteFor("mysql")); - } - - /** - * Create a new network and bind it to the container. - */ - public void withNetwork(MySQLContainer container) { - container.withNetwork(Network.newNetwork()); - } - - private static final String INVALID_TIMEZONE_CEST = "CEST"; - - public void withInvalidTimezoneCEST(MySQLContainer container) { - container.withEnv("TZ", INVALID_TIMEZONE_CEST); - } - - public void withMoscowTimezone(MySQLContainer container) { - container.withEnv("TZ", "Europe/Moscow"); - } - - public void withCustomName(MySQLContainer container) {} // do nothing - - public void withRootAndServerCertificates(MySQLContainer container) { - execInContainer(container, - "sed -i '31 a ssl' /etc/my.cnf", - "sed -i '32 a ssl-ca=/var/lib/mysql/ca.pem' /etc/my.cnf", - "sed -i '33 a ssl-cert=/var/lib/mysql/server-cert.pem' /etc/my.cnf", - "sed -i '34 a ssl-key=/var/lib/mysql/server-key.pem' /etc/my.cnf", - "sed -i '35 a require_secure_transport=ON' /etc/my.cnf"); - } - - public void withClientCertificate(MySQLContainer container) { - execInContainer(container, - "sed -i '39 a [client]' /etc/mysql/my.cnf", - "sed -i '40 a ssl-ca=/var/lib/mysql/ca.pem' /etc/my.cnf", - "sed -i '41 a ssl-cert=/var/lib/mysql/client-cert.pem' /etc/my.cnf", - "sed -i '42 a ssl-key=/var/lib/mysql/client-key.pem' /etc/my.cnf"); - } - - static private void execInContainer(MySQLContainer container, String... commands) { - container.start(); - try { - for (String command : commands) { - container.execInContainer("sh", "-c", command); - } - } catch (IOException e) { - throw new UncheckedIOException(e); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/airbyte-integrations/connectors/source-mysql/src/testFixtures/java/io/airbyte/integrations/source/mysql/MySQLTestDatabase.java b/airbyte-integrations/connectors/source-mysql/src/testFixtures/java/io/airbyte/integrations/source/mysql/MySQLTestDatabase.java deleted file mode 100644 index 219d5e90f479..000000000000 --- a/airbyte-integrations/connectors/source-mysql/src/testFixtures/java/io/airbyte/integrations/source/mysql/MySQLTestDatabase.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.source.mysql; - -import static io.airbyte.integrations.source.mysql.MySqlSpecConstants.INVALID_CDC_CURSOR_POSITION_PROPERTY; -import static io.airbyte.integrations.source.mysql.MySqlSpecConstants.RESYNC_DATA_OPTION; - -import com.google.common.collect.ImmutableMap; -import io.airbyte.cdk.db.factory.DatabaseDriver; -import io.airbyte.cdk.testutils.TestDatabase; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.jooq.SQLDialect; -import org.testcontainers.containers.MySQLContainer; - -public class MySQLTestDatabase extends - TestDatabase, MySQLTestDatabase, MySQLTestDatabase.MySQLConfigBuilder> { - - public enum BaseImage { - - MYSQL_8("mysql:8.0"), - ; - - public final String reference; - - BaseImage(String reference) { - this.reference = reference; - } - - } - - public enum ContainerModifier { - - MOSCOW_TIMEZONE("withMoscowTimezone"), - INVALID_TIMEZONE_CEST("withInvalidTimezoneCEST"), - ROOT_AND_SERVER_CERTIFICATES("withRootAndServerCertificates"), - CLIENT_CERTITICATE("withClientCertificate"), - NETWORK("withNetwork"), - - CUSTOM_NAME("withCustomName"); - - public final String methodName; - - ContainerModifier(String methodName) { - this.methodName = methodName; - } - - } - - static public MySQLTestDatabase in(BaseImage baseImage, ContainerModifier... methods) { - String[] methodNames = Stream.of(methods).map(im -> im.methodName).toList().toArray(new String[0]); - final var container = new MySQLContainerFactory().shared(baseImage.reference, methodNames); - return new MySQLTestDatabase(container).initialized(); - } - - public MySQLTestDatabase(MySQLContainer container) { - super(container); - } - - public MySQLTestDatabase withCdcPermissions() { - return this - .with("REVOKE ALL PRIVILEGES, GRANT OPTION FROM '%s';", getUserName()) - .with("GRANT SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO '%s';", getUserName()); - } - - public MySQLTestDatabase withoutStrictMode() { - // This disables strict mode in the DB and allows to insert specific values. - // For example, it's possible to insert date with zero values "2021-00-00" - return with("SET @@sql_mode=''"); - } - - static private final int MAX_CONNECTIONS = 1000; - - @Override - protected Stream> inContainerBootstrapCmd() { - // Besides setting up user and privileges, we also need to create a soft link otherwise - // airbyte-ci on github runner would not be able to connect to DB, because the sock file does not - // exist. - return Stream.of(Stream.of( - "sh", "-c", "ln -s -f /var/lib/mysql/mysql.sock /var/run/mysqld/mysqld.sock"), - mysqlCmd(Stream.of( - String.format("SET GLOBAL max_connections=%d", MAX_CONNECTIONS), - String.format("CREATE DATABASE \\`%s\\`", getDatabaseName()), - String.format("CREATE USER '%s' IDENTIFIED BY '%s'", getUserName(), getPassword()), - // Grant privileges also to the container's user, which is not root. - String.format("GRANT ALL PRIVILEGES ON *.* TO '%s', '%s' WITH GRANT OPTION", getUserName(), - getContainer().getUsername())))); - - } - - @Override - protected Stream inContainerUndoBootstrapCmd() { - return mysqlCmd(Stream.of( - String.format("DROP USER '%s'", getUserName()), - String.format("DROP DATABASE \\`%s\\`", getDatabaseName()))); - } - - @Override - public DatabaseDriver getDatabaseDriver() { - return DatabaseDriver.MYSQL; - } - - @Override - public SQLDialect getSqlDialect() { - return SQLDialect.MYSQL; - } - - @Override - public MySQLConfigBuilder configBuilder() { - return new MySQLConfigBuilder(this); - } - - public Stream mysqlCmd(Stream sql) { - return Stream.of("bash", "-c", String.format( - "set -o errexit -o pipefail; echo \"%s\" | mysql -v -v -v --user=root --password=test", - sql.collect(Collectors.joining("; ")))); - } - - static public class MySQLConfigBuilder extends ConfigBuilder { - - protected MySQLConfigBuilder(MySQLTestDatabase testDatabase) { - super(testDatabase); - } - - public MySQLConfigBuilder withStandardReplication() { - return with("replication_method", ImmutableMap.builder().put("method", "STANDARD").build()); - } - - public MySQLConfigBuilder withCdcReplication() { - return withCdcReplication(RESYNC_DATA_OPTION); - } - - public MySQLConfigBuilder withCdcReplication(String cdcCursorFailBehaviour) { - return this - .with("is_test", true) - .with("replication_method", ImmutableMap.builder() - .put("method", "CDC") - .put("initial_waiting_seconds", 5) - .put("server_time_zone", "America/Los_Angeles") - .put(INVALID_CDC_CURSOR_POSITION_PROPERTY, cdcCursorFailBehaviour) - .build()); - } - - } - - private String cachedCaCertificate; - private Certificates cachedCertificates; - - public synchronized String getCaCertificate() { - if (cachedCaCertificate == null) { - cachedCaCertificate = catFileInContainer("/var/lib/mysql/ca.pem"); - } - return cachedCaCertificate; - } - - public synchronized Certificates getCertificates() { - if (cachedCertificates == null) { - cachedCertificates = new Certificates( - catFileInContainer("/var/lib/mysql/ca.pem"), - catFileInContainer("/var/lib/mysql/client-cert.pem"), - catFileInContainer("/var/lib/mysql/client-key.pem")); - } - return cachedCertificates; - } - - public record Certificates(String caCertificate, String clientCertificate, String clientKey) {} - - private String catFileInContainer(String filePath) { - try { - return getContainer().execInContainer("sh", "-c", "cat " + filePath).getStdout().trim(); - } catch (IOException e) { - throw new UncheckedIOException(e); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/airbyte-integrations/connectors/source-n8n/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-n8n/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-n8n/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-n8n/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-nasa/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-nasa/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-nasa/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-nasa/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-nasa/metadata.yaml b/airbyte-integrations/connectors/source-nasa/metadata.yaml index 8653b029e2ef..0a9ffdf7755e 100644 --- a/airbyte-integrations/connectors/source-nasa/metadata.yaml +++ b/airbyte-integrations/connectors/source-nasa/metadata.yaml @@ -14,7 +14,7 @@ data: connectorSubtype: api connectorType: source definitionId: 1a8667d7-7978-43cd-ba4d-d32cbd478971 - dockerImageTag: 0.3.3 + dockerImageTag: 0.3.8 dockerRepository: airbyte/source-nasa githubIssueLabel: source-nasa icon: nasa.svg @@ -38,5 +38,5 @@ data: # alias: airbyte-connector-testing-secret-store - language:manifest-only connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-navan/README.md b/airbyte-integrations/connectors/source-navan/README.md new file mode 100644 index 000000000000..e4589be80b87 --- /dev/null +++ b/airbyte-integrations/connectors/source-navan/README.md @@ -0,0 +1,33 @@ +# Navan +This directory contains the manifest-only connector for `source-navan`. + +Connector for hotel and flight data + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-navan:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-navan build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-navan test +``` + diff --git a/airbyte-integrations/connectors/source-navan/acceptance-test-config.yml b/airbyte-integrations/connectors/source-navan/acceptance-test-config.yml new file mode 100644 index 000000000000..76c80e2683f0 --- /dev/null +++ b/airbyte-integrations/connectors/source-navan/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-navan:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-navan/icon.svg b/airbyte-integrations/connectors/source-navan/icon.svg new file mode 100644 index 000000000000..5a08c4f7101d --- /dev/null +++ b/airbyte-integrations/connectors/source-navan/icon.svg @@ -0,0 +1,15 @@ + + + + + + diff --git a/airbyte-integrations/connectors/source-navan/manifest.yaml b/airbyte-integrations/connectors/source-navan/manifest.yaml new file mode 100644 index 000000000000..62c89d802399 --- /dev/null +++ b/airbyte-integrations/connectors/source-navan/manifest.yaml @@ -0,0 +1,911 @@ +version: 6.5.2 + +type: DeclarativeSource + +description: Connector for hotel and flight data + +check: + type: CheckStream + stream_names: + - bookings + +definitions: + streams: + bookings: + type: DeclarativeStream + name: bookings + primary_key: + - uuid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v1/bookings + http_method: GET + request_parameters: + bookingType: FLIGHT + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: size + pagination_strategy: + type: PageIncrement + start_from_page: 0 + page_size: 50 + inject_on_first_request: true + incremental_sync: + type: DatetimeBasedCursor + cursor_field: lastModified + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%fZ" + datetime_format: "%s" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: createdFrom + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: createdTo + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/bookings" + base_requester: + type: HttpRequester + url_base: https://api.navan.com + authenticator: + type: OAuthAuthenticator + client_id: "{{ config[\"client_id\"] }}" + grant_type: client_credentials + client_secret: "{{ config[\"client_secret\"] }}" + expires_in_name: expires_in + access_token_name: access_token + token_refresh_endpoint: https://api.navan.com/ta-auth/oauth/token + refresh_request_body: {} + +streams: + - $ref: "#/definitions/streams/bookings" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - client_id + - client_secret + - start_date + properties: + client_id: + type: string + name: client_id + title: OAuth Client ID + airbyte_secret: true + order: 0 + client_secret: + type: string + name: client_secret + title: OAuth Client Secret + airbyte_secret: true + order: 1 + start_date: + type: string + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + order: 2 + additionalProperties: true + +metadata: + autoImportSchema: + bookings: true + testedStreams: + bookings: + streamHash: 2fb7b082e892f0b73646c417bdca3537e411801f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://app.navan.com/open-api/trips/swagger-ui/index.html + +schemas: + bookings: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + airlineCreditCardSurcharge: + type: + - number + - "null" + approvalStatus: + type: + - string + - "null" + approverEmail: + type: + - string + - "null" + approverReason: + type: + - string + - "null" + basePrice: + type: + - number + - "null" + billableEntities: + type: + - array + - "null" + items: + type: + - string + - "null" + booker: + type: + - object + - "null" + properties: + costCenter: + type: + - string + - "null" + department: + type: + - string + - "null" + email: + type: + - string + - "null" + managerUuid: + type: + - string + - "null" + name: + type: + - string + - "null" + region: + type: + - string + - "null" + subsidiary: + type: + - string + - "null" + uuid: + type: + - string + - "null" + bookingDuration: + type: + - number + - "null" + bookingFee: + type: + - number + - "null" + bookingId: + type: + - string + - "null" + bookingMethod: + type: + - string + - "null" + bookingStatus: + type: + - string + - "null" + bookingType: + type: + - string + - "null" + cabin: + type: + - string + - "null" + cabinPurchased: + type: + - string + - "null" + cancellationReason: + type: + - string + - "null" + cancelledAt: + type: + - string + - "null" + carbonEmissions: + type: + - number + - "null" + carbonOffsetCost: + type: + - number + - "null" + cnr: + type: + - object + - "null" + properties: {} + companyOffice: + type: + - string + - "null" + companyPaymentMethod: + type: + - string + - "null" + confirmationNumber: + type: + - string + - "null" + corporateDiscountUsed: + type: + - string + - "null" + costCenters: + type: + - array + - "null" + items: + type: + - string + - "null" + created: + type: + - string + - "null" + credit: + type: + - object + - "null" + properties: + creditAvailable: + type: + - number + - "null" + creditAvailableUsd: + type: + - number + - "null" + creditExchangeFeeUsd: + type: + - number + - "null" + creditUsed: + type: + - number + - "null" + creditUsedUsd: + type: + - number + - "null" + residualCredit: + type: + - number + - "null" + currency: + type: + - string + - "null" + currencyExhangeRateFromUsd: + type: + - number + - "null" + customFields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + value: + type: + - string + - "null" + departments: + type: + - array + - "null" + items: + type: + - string + - "null" + destination: + type: + - object + - "null" + properties: + airportCode: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + state: + type: + - string + - "null" + domestic: + type: + - string + - "null" + endDate: + type: + - string + - "null" + etickets: + type: + - array + - "null" + items: + type: + - string + - "null" + exchangeAmount: + type: + - number + - "null" + exchangeFee: + type: + - number + - "null" + expensed: + type: + - boolean + - "null" + extrasFees: + type: + - number + - "null" + fareBasisCode: + type: + - string + - "null" + fareClass: + type: + - string + - "null" + flight: + type: + - string + - "null" + flightMiles: + type: + - number + - "null" + grandTotal: + type: + - number + - "null" + gst: + type: + - number + - "null" + handlingFees: + type: + - number + - "null" + hst: + type: + - number + - "null" + inventory: + type: + - string + - "null" + inventorySource: + type: + - string + - "null" + invoice: + type: + - string + - "null" + invoiceCollectionFees: + type: + - number + - "null" + invoiceNumber: + type: + - string + - "null" + lastModified: + type: string + leadTimeInDays: + type: + - number + - "null" + loggedAsUserName: + type: + - string + - "null" + maxCancellationLoss: + type: + - number + - "null" + maxPricePolicy: + type: + - number + - "null" + nameOnCreditCard: + type: + - string + - "null" + navanPro: + type: + - boolean + - "null" + netCharge: + type: + - number + - "null" + numberOfPassengers: + type: + - number + - "null" + optimalPrice: + type: + - number + - "null" + origin: + type: + - object + - "null" + properties: + airportCode: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + state: + type: + - string + - "null" + outOfPolicy: + type: + - boolean + - "null" + outOfPolicyDescription: + type: + - string + - "null" + outOfPolicyViolationTypes: + type: + - array + - "null" + items: + type: + - string + - "null" + outOfPolicyViolations: + type: + - string + - "null" + passengers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + person: + type: + - object + - "null" + properties: + billableEntity: + type: + - string + - "null" + costCenter: + type: + - string + - "null" + department: + type: + - string + - "null" + email: + type: + - string + - "null" + managerEmail: + type: + - string + - "null" + managerName: + type: + - string + - "null" + managerUuid: + type: + - string + - "null" + name: + type: + - string + - "null" + passport: + type: + - object + - "null" + properties: + countryOfCitizenship: + type: + - string + - "null" + countryOfIssue: + type: + - string + - "null" + expiresOn: + type: + - string + - "null" + issuedOn: + type: + - string + - "null" + region: + type: + - string + - "null" + subsidiary: + type: + - string + - "null" + uuid: + type: + - string + - "null" + status: + type: + - string + - "null" + travelerType: + type: + - string + - "null" + paymentCreditCardTypeName: + type: + - string + - "null" + paymentMethod: + type: + - string + - "null" + paymentMethodUsed: + type: + - string + - "null" + paymentSchedule: + type: + - string + - "null" + pcc: + type: + - string + - "null" + pdf: + type: + - string + - "null" + policyLevel: + type: + - string + - "null" + ppbPointsBurned: + type: + - number + - "null" + preferredVendor: + type: + - string + - "null" + purpose: + type: + - string + - "null" + qst: + type: + - number + - "null" + reason: + type: + - string + - "null" + regions: + type: + - array + - "null" + items: + type: + - string + - "null" + reshopping: + type: + - object + - "null" + properties: + reshoppingIsRebooked: + type: + - boolean + - "null" + reshoppingNewPrice: + type: + - number + - "null" + reshoppingOriginalPrice: + type: + - number + - "null" + resortFee: + type: + - number + - "null" + routeType: + type: + - string + - "null" + saving: + type: + - number + - "null" + savingMissed: + type: + - number + - "null" + seats: + type: + - array + - "null" + items: + type: + - string + - "null" + seatsFee: + type: + - number + - "null" + segments: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + airlineAlliance: + type: + - string + - "null" + arrival: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + airportCode: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + state: + type: + - string + - "null" + cabin: + type: + - string + - "null" + cabinPurchased: + type: + - string + - "null" + departure: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + airportCode: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + state: + type: + - string + - "null" + endLocalDateTime: + type: + - string + - "null" + endTimestamp: + type: + - number + - "null" + fareClass: + type: + - string + - "null" + flightNumber: + type: + - string + - "null" + providerCode: + type: + - string + - "null" + providerName: + type: + - string + - "null" + startLocalDateTime: + type: + - string + - "null" + startTimestamp: + type: + - number + - "null" + startDate: + type: + - string + - "null" + subsidiaries: + type: + - array + - "null" + items: + type: + - string + - "null" + tax: + type: + - number + - "null" + trainMiles: + type: + - number + - "null" + transactionFees: + type: + - number + - "null" + travelAgentRequestFee: + type: + - number + - "null" + travelSpend: + type: + - number + - "null" + tripBucksEarned: + type: + - number + - "null" + tripBucksEarnedUsd: + type: + - number + - "null" + tripDescription: + type: + - string + - "null" + tripFee: + type: + - number + - "null" + tripLength: + type: + - string + - "null" + tripName: + type: + - string + - "null" + tripUuids: + type: + - array + - "null" + items: + type: + - string + - "null" + unitaryPrice: + type: + - number + - "null" + usdGrandTotal: + type: + - number + - "null" + uuid: + type: string + vat: + type: + - number + - "null" + vendor: + type: + - string + - "null" + vipFee: + type: + - number + - "null" + required: + - uuid + - lastModified diff --git a/airbyte-integrations/connectors/source-navan/metadata.yaml b/airbyte-integrations/connectors/source-navan/metadata.yaml new file mode 100644 index 000000000000..abc8f2ae1ae6 --- /dev/null +++ b/airbyte-integrations/connectors/source-navan/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.navan.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-navan + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 4ea87f6d-def2-4e77-8a28-7b860cd52f94 + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-navan + githubIssueLabel: source-navan + icon: icon.svg + license: MIT + name: Navan + releaseDate: 2024-11-26 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/navan + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-netsuite/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-netsuite/integration_tests/acceptance.py index ea1ca1161ee2..a9256a533972 100644 --- a/airbyte-integrations/connectors/source-netsuite/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-netsuite/integration_tests/acceptance.py @@ -5,10 +5,10 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) @pytest.fixture(scope="session", autouse=True) def connector_setup(): - yield diff --git a/airbyte-integrations/connectors/source-netsuite/main.py b/airbyte-integrations/connectors/source-netsuite/main.py index 492266da15e2..5d7d745b82af 100644 --- a/airbyte-integrations/connectors/source-netsuite/main.py +++ b/airbyte-integrations/connectors/source-netsuite/main.py @@ -4,5 +4,6 @@ from source_netsuite.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-netsuite/setup.py b/airbyte-integrations/connectors/source-netsuite/setup.py index e16d4d5b270f..682252ab2124 100644 --- a/airbyte-integrations/connectors/source-netsuite/setup.py +++ b/airbyte-integrations/connectors/source-netsuite/setup.py @@ -5,6 +5,7 @@ from setuptools import find_packages, setup + MAIN_REQUIREMENTS = [ "airbyte-cdk", "requests-oauthlib", diff --git a/airbyte-integrations/connectors/source-netsuite/source_netsuite/source.py b/airbyte-integrations/connectors/source-netsuite/source_netsuite/source.py index 610adece4944..e7f64474b9b2 100644 --- a/airbyte-integrations/connectors/source-netsuite/source_netsuite/source.py +++ b/airbyte-integrations/connectors/source-netsuite/source_netsuite/source.py @@ -9,15 +9,15 @@ from typing import Any, List, Mapping, Tuple, Union import requests +from requests_oauthlib import OAuth1 + from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream -from requests_oauthlib import OAuth1 from source_netsuite.constraints import CUSTOM_INCREMENTAL_CURSOR, INCREMENTAL_CURSOR, META_PATH, RECORD_PATH, SCHEMA_HEADERS from source_netsuite.streams import CustomIncrementalNetsuiteStream, IncrementalNetsuiteStream, NetsuiteStream class SourceNetsuite(AbstractSource): - logger: logging.Logger = logging.getLogger("airbyte") def auth(self, config: Mapping[str, Any]) -> OAuth1: @@ -109,7 +109,6 @@ def generate_stream( window_in_days: int, max_retry: int = 3, ) -> Union[NetsuiteStream, IncrementalNetsuiteStream, CustomIncrementalNetsuiteStream]: - input_args = { "auth": auth, "object_name": object_name, diff --git a/airbyte-integrations/connectors/source-netsuite/source_netsuite/streams.py b/airbyte-integrations/connectors/source-netsuite/source_netsuite/streams.py index 57ab51643782..4d59ac547034 100644 --- a/airbyte-integrations/connectors/source-netsuite/source_netsuite/streams.py +++ b/airbyte-integrations/connectors/source-netsuite/source_netsuite/streams.py @@ -9,8 +9,9 @@ from typing import Any, Iterable, Mapping, MutableMapping, Optional, Union import requests -from airbyte_cdk.sources.streams.http import HttpStream from requests_oauthlib import OAuth1 + +from airbyte_cdk.sources.streams.http import HttpStream from source_netsuite.constraints import ( CUSTOM_INCREMENTAL_CURSOR, INCREMENTAL_CURSOR, @@ -159,7 +160,6 @@ def parse_response( next_page_token: Mapping[str, Any] = None, **kwargs, ) -> Iterable[Mapping]: - records = response.json().get("items") request_kwargs = self.request_kwargs(stream_slice, next_page_token) if records: diff --git a/airbyte-integrations/connectors/source-news-api/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-news-api/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-news-api/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-news-api/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-news-api/metadata.yaml b/airbyte-integrations/connectors/source-news-api/metadata.yaml index 746be876d2d2..8dd04fc21077 100644 --- a/airbyte-integrations/connectors/source-news-api/metadata.yaml +++ b/airbyte-integrations/connectors/source-news-api/metadata.yaml @@ -12,11 +12,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: df38991e-f35b-4af2-996d-36817f614587 - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-news-api githubIssueLabel: source-news-api icon: newsapi.svg diff --git a/airbyte-integrations/connectors/source-newsdata-io/README.md b/airbyte-integrations/connectors/source-newsdata-io/README.md new file mode 100644 index 000000000000..ad7c3ea2bc25 --- /dev/null +++ b/airbyte-integrations/connectors/source-newsdata-io/README.md @@ -0,0 +1,33 @@ +# NewsData.io +This directory contains the manifest-only connector for `source-newsdata-io`. + +Connector for NewsData.io to get the latest news in pagination and the latest news from specific countries, categories and domains. You can also get the news sources from specific categories, countries and languages. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-newsdata-io:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-newsdata-io build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-newsdata-io test +``` + diff --git a/airbyte-integrations/connectors/source-newsdata-io/acceptance-test-config.yml b/airbyte-integrations/connectors/source-newsdata-io/acceptance-test-config.yml new file mode 100644 index 000000000000..bdaa58f78616 --- /dev/null +++ b/airbyte-integrations/connectors/source-newsdata-io/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-newsdata-io:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-newsdata-io/icon.svg b/airbyte-integrations/connectors/source-newsdata-io/icon.svg new file mode 100644 index 000000000000..b29ce446a95b --- /dev/null +++ b/airbyte-integrations/connectors/source-newsdata-io/icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/airbyte-integrations/connectors/source-newsdata-io/manifest.yaml b/airbyte-integrations/connectors/source-newsdata-io/manifest.yaml new file mode 100644 index 000000000000..15827c2d510b --- /dev/null +++ b/airbyte-integrations/connectors/source-newsdata-io/manifest.yaml @@ -0,0 +1,345 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Connector for NewsData.io to get the latest news in pagination and the latest + news from specific countries, categories and domains. You can also get the + news sources from specific categories, countries and languages. + +check: + type: CheckStream + stream_names: + - latest_news + +definitions: + streams: + latest_news: + type: DeclarativeStream + name: latest_news + primary_key: + - article_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /latest + http_method: GET + request_parameters: + q: "{{ config.get('search_query') }}" + country: "{{ ','.join(config.get('countries', [])) }}" + domain: "{{ ','.join(config.get('domains', [])) }}" + language: "{{ ','.join(config.get('languages', [])) }}" + category: "{{ ','.join(config.get('categories', [])) }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.nextPage }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/latest_news" + historical_news: + type: DeclarativeStream + name: historical_news + primary_key: + - article_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /archive + http_method: GET + request_parameters: + q: "{{ config.get('search_query') }}" + country: "{{ ','.join(config.get('countries', [])) }}" + domain: "{{ ','.join(config.get('domains', [])) }}" + language: "{{ ','.join(config.get('languages', [])) }}" + category: "{{ ','.join(config.get('categories', [])) }}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: FAIL + http_codes: + - 403 + error_message: >- + Only Available for Premium Users. You don't have + permission to access this resource. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.nextPage }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: pubDate + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: from_date + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: to_date + end_datetime: + type: MinMaxDatetime + datetime: "{{ config.end_date or now_utc() }}" + datetime_format: "%Y-%m-%d" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/historical_news" + base_requester: + type: HttpRequester + url_base: https://newsdata.io/api/1 + authenticator: + type: ApiKeyAuthenticator + inject_into: + type: RequestOption + inject_into: request_parameter + field_name: apikey + api_token: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/latest_news" + - $ref: "#/definitions/streams/historical_news" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - start_date + properties: + api_key: + type: string + title: API Key + airbyte_secret: true + order: 0 + search_query: + type: string + description: >- + Search news articles for specific keywords or phrases present in the + news title, content, URL, meta keywords and meta description. + title: Search Query + order: 1 + countries: + type: array + description: >- + Search the news articles from a specific country. You can add up to 5 + countries in a single query. Example: au, jp, br + title: Countries + order: 2 + categories: + type: array + description: >- + Search the news articles for a specific category. You can add up to 5 + categories in a single query. + title: Categories + order: 3 + languages: + type: array + description: >- + Search the news articles for a specific language. You can add up to 5 + languages in a single query. + title: Languages + order: 4 + domains: + type: array + description: >- + Search the news articles for specific domains or news sources. You can + add up to 5 domains in a single query. + title: Domains + order: 5 + start_date: + type: string + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + order: 6 + end_date: + type: string + description: Choose an end date. Now UTC is default value + title: End Date + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ + format: date + order: 7 + additionalProperties: true + +metadata: + autoImportSchema: + latest_news: true + historical_news: true + testedStreams: + latest_news: + streamHash: 0be45d711c84bdae778c031b0489a7c9c0a8ad3a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + historical_news: + streamHash: aead131d550591d7bba43702875d23d4558cebc0 + hasResponse: true + responsesAreSuccessful: false + hasRecords: false + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + latest_news: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + ai_org: + type: + - string + - "null" + ai_region: + type: + - string + - "null" + ai_tag: + type: + - string + - "null" + article_id: + type: string + category: + type: + - array + - "null" + items: + type: + - string + - "null" + content: + type: + - string + - "null" + country: + type: + - array + - "null" + items: + type: + - string + - "null" + creator: + type: + - array + - "null" + items: + type: + - string + - "null" + duplicate: + type: + - boolean + - "null" + image_url: + type: + - string + - "null" + keywords: + type: + - array + - "null" + items: + type: + - string + - "null" + language: + type: + - string + - "null" + link: + type: + - string + - "null" + pubDate: + type: + - string + - "null" + pubDateTZ: + type: + - string + - "null" + sentiment: + type: + - string + - "null" + sentiment_stats: + type: + - string + - "null" + source_icon: + type: + - string + - "null" + source_id: + type: + - string + - "null" + source_name: + type: + - string + - "null" + source_priority: + type: + - number + - "null" + source_url: + type: + - string + - "null" + title: + type: + - string + - "null" + required: + - article_id + historical_news: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} diff --git a/airbyte-integrations/connectors/source-newsdata-io/metadata.yaml b/airbyte-integrations/connectors/source-newsdata-io/metadata.yaml new file mode 100644 index 000000000000..da292f4eaa27 --- /dev/null +++ b/airbyte-integrations/connectors/source-newsdata-io/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "newsdata.io" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-newsdata-io + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 67f03df4-2c61-4d8c-80cd-0931287f87d8 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-newsdata-io + githubIssueLabel: source-newsdata-io + icon: icon.svg + license: MIT + name: NewsData.io + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/newsdata-io + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-newsdata/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-newsdata/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-newsdata/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-newsdata/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-newsdata/metadata.yaml b/airbyte-integrations/connectors/source-newsdata/metadata.yaml index 1a6346ed996e..38735a48a9fb 100644 --- a/airbyte-integrations/connectors/source-newsdata/metadata.yaml +++ b/airbyte-integrations/connectors/source-newsdata/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.4.3@sha256:8937b693c7e01087f6e86e683826ac20f160f7952b8f0a13cbf4f9bfdd7af570 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 60bd11d8-2632-4daa-a688-b47336d32093 - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.3 dockerRepository: airbyte/source-newsdata documentationUrl: https://docs.airbyte.com/integrations/sources/newsdata githubIssueLabel: source-newsdata diff --git a/airbyte-integrations/connectors/source-nocrm/README.md b/airbyte-integrations/connectors/source-nocrm/README.md new file mode 100644 index 000000000000..ddc2a0d59f3f --- /dev/null +++ b/airbyte-integrations/connectors/source-nocrm/README.md @@ -0,0 +1,33 @@ +# NoCRM +This directory contains the manifest-only connector for `source-nocrm`. + +[NoCRM](https://nocrm.io) connector enables seamless data integration between NoCRM.io, a lead management tool, and other platforms or data warehouses. It allows for the automated extraction and synchronization of lead data, activities, and contact details from NoCRM.io into analytics systems, supporting data-driven decisions and streamlined workflows. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-nocrm:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-nocrm build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-nocrm test +``` + diff --git a/airbyte-integrations/connectors/source-nocrm/acceptance-test-config.yml b/airbyte-integrations/connectors/source-nocrm/acceptance-test-config.yml new file mode 100644 index 000000000000..42c7801825af --- /dev/null +++ b/airbyte-integrations/connectors/source-nocrm/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-nocrm:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-nocrm/icon.svg b/airbyte-integrations/connectors/source-nocrm/icon.svg new file mode 100644 index 000000000000..92ed82dcad93 --- /dev/null +++ b/airbyte-integrations/connectors/source-nocrm/icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/airbyte-integrations/connectors/source-nocrm/manifest.yaml b/airbyte-integrations/connectors/source-nocrm/manifest.yaml new file mode 100644 index 000000000000..7836a135e9a2 --- /dev/null +++ b/airbyte-integrations/connectors/source-nocrm/manifest.yaml @@ -0,0 +1,1291 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + [NoCRM](https://nocrm.io) connector enables seamless data integration between + NoCRM.io, a lead management tool, and other platforms or data warehouses. It + allows for the automated extraction and synchronization of lead data, + activities, and contact details from NoCRM.io into analytics systems, + supporting data-driven decisions and streamlined workflows. + +check: + type: CheckStream + stream_names: + - steps + +definitions: + streams: + steps: + type: DeclarativeStream + name: steps + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /steps + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/steps" + pipelines: + type: DeclarativeStream + name: pipelines + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /pipelines + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/pipelines" + clients_folders: + type: DeclarativeStream + name: clients_folders + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /clients + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/clients_folders" + categories: + type: DeclarativeStream + name: categories + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /categories + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/categories" + predefined_tags: + type: DeclarativeStream + name: predefined_tags + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /predefined_tags + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/predefined_tags" + fields: + type: DeclarativeStream + name: fields + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /fields + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/fields" + leads: + type: DeclarativeStream + name: leads + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /leads + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: false + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/leads" + follow_ups: + type: DeclarativeStream + name: follow_ups + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /follow_ups + http_method: GET + request_parameters: + lead_id: "{{ stream_partition.lead_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: lead_id + stream: + $ref: "#/definitions/streams/leads" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/follow_ups" + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + teams: + type: DeclarativeStream + name: teams + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /teams + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/teams" + webhooks: + type: DeclarativeStream + name: webhooks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /webhooks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/webhooks" + webhook_events: + type: DeclarativeStream + name: webhook_events + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /webhook_events + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/webhook_events" + activities: + type: DeclarativeStream + name: activities + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /activities + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/activities" + prospecting_lists: + type: DeclarativeStream + name: prospecting_lists + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /spreadsheets + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/prospecting_lists" + base_requester: + type: HttpRequester + url_base: https://{{ config['subdomain'] }}.nocrm.io/api/v2 + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: X-API-KEY + inject_into: header + +streams: + - $ref: "#/definitions/streams/steps" + - $ref: "#/definitions/streams/pipelines" + - $ref: "#/definitions/streams/clients_folders" + - $ref: "#/definitions/streams/categories" + - $ref: "#/definitions/streams/predefined_tags" + - $ref: "#/definitions/streams/fields" + - $ref: "#/definitions/streams/leads" + - $ref: "#/definitions/streams/follow_ups" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/teams" + - $ref: "#/definitions/streams/webhooks" + - $ref: "#/definitions/streams/webhook_events" + - $ref: "#/definitions/streams/activities" + - $ref: "#/definitions/streams/prospecting_lists" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - subdomain + properties: + api_key: + type: string + description: >- + API key to use. Generate it from the admin section of your noCRM.io + account. + name: api_key + order: 0 + title: API Key + airbyte_secret: true + subdomain: + type: string + description: >- + The subdomain specific to your noCRM.io account, e.g., 'yourcompany' + in 'yourcompany.nocrm.io'. + name: subdomain + order: 1 + title: Subdomain + additionalProperties: true + +metadata: + autoImportSchema: + steps: true + pipelines: true + clients_folders: true + categories: true + predefined_tags: true + fields: true + leads: true + follow_ups: true + users: true + teams: true + webhooks: true + webhook_events: true + activities: true + prospecting_lists: true + testedStreams: + steps: + streamHash: bbe33ded47e5f9017aea1a1548eb8d8e03803371 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + pipelines: + streamHash: 9cb665bb6c60cc9e8f8ae32df6b46f990afdb439 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + clients_folders: + streamHash: b6960e4601a1ad11bf1946f7f21cb9226a34bed3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + categories: + streamHash: 31cc6e3cf85813b6dd06a8ea08d1ff19eb83cca2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + predefined_tags: + streamHash: 88e7080a74bb2b144bb86e9034c7988c32798bba + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + fields: + streamHash: dc22d32d52de864571e505e5ba6320747572265f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + leads: + streamHash: 0d089a4251f7134e23e26f6bd1c95aa4612b7348 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + follow_ups: + streamHash: d95a7583edf054fc6d56c35de9a51fc10b2f24eb + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + users: + streamHash: fbed530a1c080141e45f23f2a2a5c7815b216893 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + teams: + streamHash: c67521197e1db5efbee06143f88f0d3ac8cb80aa + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + webhooks: + hasRecords: true + streamHash: 3275886e75785d6f4479e68c7550a87e827f5c29 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + webhook_events: + streamHash: 530a2503347ffff3f82cf445f738ffe461f8d072 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + activities: + streamHash: 977f32b68d4b8a81b07d00ebb7878ec24b3ac13e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + prospecting_lists: + streamHash: 90d5128519f2ca52040ffca414854a824790655e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://www.nocrm.io/api + +schemas: + steps: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + pipeline: + type: + - object + - "null" + properties: + created_at: + type: + - string + - "null" + id: + type: + - number + - "null" + is_default: + type: + - boolean + - "null" + name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + pipeline_id: + type: + - number + - "null" + position: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + required: + - id + pipelines: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + id: + type: number + is_default: + type: + - boolean + - "null" + name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + clients_folders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: number + is_active: + type: + - boolean + - "null" + name: + type: + - string + - "null" + user_id: + type: + - number + - "null" + required: + - id + categories: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + id: + type: number + is_required: + type: + - boolean + - "null" + name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + predefined_tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + category: + type: + - string + - "null" + category_id: + type: + - number + - "null" + created_at: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + required: + - id + fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: number + is_key: + type: + - boolean + - "null" + name: + type: + - string + - "null" + parent_type: + type: + - string + - "null" + position: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + required: + - id + leads: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + attachment_count: + type: + - number + - "null" + closed_at: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by_id: + type: + - number + - "null" + created_from: + type: + - string + - "null" + currency: + type: + - string + - "null" + html_description: + type: + - string + - "null" + id: + type: number + next_action_at: + type: + - string + - "null" + pipeline: + type: + - string + - "null" + probability: + type: + - number + - "null" + remind_date: + type: + - string + - "null" + starred: + type: + - boolean + - "null" + status: + type: + - string + - "null" + step: + type: + - string + - "null" + step_id: + type: + - number + - "null" + tags: + type: + - array + - "null" + items: + type: + - string + - "null" + title: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + user_id: + type: + - number + - "null" + required: + - id + follow_ups: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: number + lead_id: + type: + - number + - "null" + next_action_at: + type: + - string + - "null" + status: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - string + - "null" + tasks_count: + type: + - number + - "null" + tasks_done_count: + type: + - number + - "null" + title: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + user_id: + type: + - number + - "null" + required: + - id + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + email: + type: + - string + - "null" + firstname: + type: + - string + - "null" + has_activated: + type: + - boolean + - "null" + id: + type: number + is_admin: + type: + - boolean + - "null" + is_disabled: + type: + - boolean + - "null" + lastname: + type: + - string + - "null" + locale: + type: + - string + - "null" + permalink: + type: + - string + - "null" + teams: + type: + - array + - "null" + time_zone: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + teams: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + users: + type: + - array + - "null" + required: + - id + webhooks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + event: + type: + - string + - "null" + id: + type: number + is_disabled: + type: + - boolean + - "null" + target: + type: + - string + - "null" + target_type: + type: + - string + - "null" + required: + - id + webhook_events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + data: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + all_contact_emails: + type: + - array + - "null" + bcc_count: + type: + - number + - "null" + comment_count: + type: + - number + - "null" + comments: + type: + - array + - "null" + created_at: + type: + - string + - "null" + currency: + type: + - string + - "null" + extended_info: + type: + - object + - "null" + properties: + created_by: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + firstname: + type: + - string + - "null" + id: + type: + - number + - "null" + lastname: + type: + - string + - "null" + created_by_id: + type: + - number + - "null" + fields_by_name: + type: + - object + - "null" + properties: + Email: + type: + - string + - "null" + First name: + type: + - string + - "null" + Last name: + type: + - string + - "null" + Phone: + type: + - string + - "null" + fields: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + last_name: + type: + - string + - "null" + phone: + type: + - string + - "null" + id: + type: + - number + - "null" + next_action_at: + type: + - string + - "null" + permalink: + type: + - string + - "null" + pipeline: + type: + - string + - "null" + remind_date: + type: + - string + - "null" + reminder_duration: + type: + - number + - "null" + status: + type: + - string + - "null" + step: + type: + - string + - "null" + step_id: + type: + - number + - "null" + tags: + type: + - array + - "null" + text_description: + type: + - string + - "null" + title: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + user: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + firstname: + type: + - string + - "null" + id: + type: + - number + - "null" + lastname: + type: + - string + - "null" + event: + type: + - string + - "null" + has_succeeded: + type: + - boolean + - "null" + id: + type: number + last_returned_code: + type: + - number + - "null" + signature: + type: + - string + - "null" + try_count: + type: + - number + - "null" + required: + - id + activities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + color: + type: + - string + - "null" + icon: + type: + - string + - "null" + id: + type: number + is_disabled: + type: + - boolean + - "null" + kind: + type: + - string + - "null" + name: + type: + - string + - "null" + parent_id: + type: + - number + - "null" + position: + type: + - number + - "null" + required: + - id + prospecting_lists: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + column_count: + type: + - number + - "null" + column_names: + type: + - array + - "null" + items: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: number + is_archived: + type: + - boolean + - "null" + permalink: + type: + - string + - "null" + privacy: + type: + - number + - "null" + tags: + type: + - array + - "null" + items: + type: + - string + - "null" + title: + type: + - string + - "null" + to_qualify_row_count: + type: + - number + - "null" + total_row_count: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + user: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + firstname: + type: + - string + - "null" + id: + type: + - number + - "null" + lastname: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-nocrm/metadata.yaml b/airbyte-integrations/connectors/source-nocrm/metadata.yaml new file mode 100644 index 000000000000..99ff917eb581 --- /dev/null +++ b/airbyte-integrations/connectors/source-nocrm/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "https:" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-nocrm + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: b58ba2a9-6335-496d-8c55-4e9d483f49a1 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-nocrm + githubIssueLabel: source-nocrm + icon: icon.svg + license: MIT + name: NoCRM + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/nocrm + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-northpass-lms/metadata.yaml b/airbyte-integrations/connectors/source-northpass-lms/metadata.yaml index 25b144d5e912..d5103fba98b9 100644 --- a/airbyte-integrations/connectors/source-northpass-lms/metadata.yaml +++ b/airbyte-integrations/connectors/source-northpass-lms/metadata.yaml @@ -15,11 +15,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: dd4d317e-7537-456c-b6ba-264b17ce6daa - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.8 dockerRepository: airbyte/source-northpass-lms githubIssueLabel: source-northpass-lms icon: icon.svg diff --git a/airbyte-integrations/connectors/source-notion/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-notion/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-notion/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-notion/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-notion/main.py b/airbyte-integrations/connectors/source-notion/main.py index 671d6cd692fa..0c88cd7df7d3 100644 --- a/airbyte-integrations/connectors/source-notion/main.py +++ b/airbyte-integrations/connectors/source-notion/main.py @@ -4,5 +4,6 @@ from source_notion.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-notion/source_notion/streams.py b/airbyte-integrations/connectors/source-notion/source_notion/streams.py index 5b92270c10e2..d93ce9fb56d2 100644 --- a/airbyte-integrations/connectors/source-notion/source_notion/streams.py +++ b/airbyte-integrations/connectors/source-notion/source_notion/streams.py @@ -9,13 +9,15 @@ import pendulum import pydantic import requests +from requests import HTTPError + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources import Source from airbyte_cdk.sources.streams import CheckpointMixin, Stream from airbyte_cdk.sources.streams.http import HttpStream, HttpSubStream from airbyte_cdk.sources.streams.http.availability_strategy import HttpAvailabilityStrategy from airbyte_cdk.sources.streams.http.exceptions import UserDefinedBackoffException -from requests import HTTPError + # maximum block hierarchy recursive request depth MAX_BLOCK_DEPTH = 30 @@ -27,7 +29,6 @@ class NotionAvailabilityStrategy(HttpAvailabilityStrategy): """ def reasons_for_unavailable_status_codes(self, stream: Stream, logger: Logger, source: Source, error: HTTPError) -> Dict[int, str]: - reasons_for_codes: Dict[int, str] = { requests.codes.FORBIDDEN: "This is likely due to insufficient permissions for your Notion integration. " "Please make sure your integration has read access for the resources you are trying to sync" @@ -36,7 +37,6 @@ def reasons_for_unavailable_status_codes(self, stream: Stream, logger: Logger, s class NotionStream(HttpStream, ABC): - url_base = "https://api.notion.com/v1/" primary_key = "id" @@ -146,7 +146,6 @@ def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapp class StateValueWrapper(pydantic.BaseModel): - stream: T state_value: str max_cursor_time: Any = "" @@ -166,7 +165,6 @@ def dict(self, **kwargs): class IncrementalNotionStream(NotionStream, CheckpointMixin, ABC): - cursor_field = "last_edited_time" http_method = "POST" diff --git a/airbyte-integrations/connectors/source-notion/unit_tests/test_components.py b/airbyte-integrations/connectors/source-notion/unit_tests/test_components.py index 6f5965486181..be48cadc1a21 100644 --- a/airbyte-integrations/connectors/source-notion/unit_tests/test_components.py +++ b/airbyte-integrations/connectors/source-notion/unit_tests/test_components.py @@ -8,52 +8,79 @@ def test_users_stream_transformation(): input_record = { - "object": "user", "id": "123", "name": "Airbyte", "avatar_url": "some url", "type": "bot", - "bot": {"owner": {"type": "user", "user": {"object": "user", "id": "id", "name": "Test User", "avatar_url": None, "type": "person", - "person": {"email": "email"}}}, "workspace_name": "test"} + "object": "user", + "id": "123", + "name": "Airbyte", + "avatar_url": "some url", + "type": "bot", + "bot": { + "owner": { + "type": "user", + "user": { + "object": "user", + "id": "id", + "name": "Test User", + "avatar_url": None, + "type": "person", + "person": {"email": "email"}, + }, + }, + "workspace_name": "test", + }, } output_record = { - "object": "user", "id": "123", "name": "Airbyte", "avatar_url": "some url", "type": "bot", - "bot": {"owner": {"type": "user", "info": {"object": "user", "id": "id", "name": "Test User", "avatar_url": None, "type": "person", - "person": {"email": "email"}}}, "workspace_name": "test"} + "object": "user", + "id": "123", + "name": "Airbyte", + "avatar_url": "some url", + "type": "bot", + "bot": { + "owner": { + "type": "user", + "info": { + "object": "user", + "id": "id", + "name": "Test User", + "avatar_url": None, + "type": "person", + "person": {"email": "email"}, + }, + }, + "workspace_name": "test", + }, } assert NotionUserTransformation().transform(input_record) == output_record def test_notion_properties_transformation(): input_record = { - "id": "123", "properties": { - "Due date": { - "id": "M%3BBw", "type": "date", "date": { - "start": "2023-02-23", "end": None, "time_zone": None - } - }, + "id": "123", + "properties": { + "Due date": {"id": "M%3BBw", "type": "date", "date": {"start": "2023-02-23", "end": None, "time_zone": None}}, "Status": { - "id": "Z%3ClH", "type": "status", "status": { - "id": "86ddb6ec-0627-47f8-800d-b65afd28be13", "name": "Not started", "color": "default" - } - } - } + "id": "Z%3ClH", + "type": "status", + "status": {"id": "86ddb6ec-0627-47f8-800d-b65afd28be13", "name": "Not started", "color": "default"}, + }, + }, } output_record = { - "id": "123", "properties": [ + "id": "123", + "properties": [ { - "name": "Due date", "value": { - "id": "M%3BBw", "type": "date", "date": { - "start": "2023-02-23", "end": None, "time_zone": None - } - } + "name": "Due date", + "value": {"id": "M%3BBw", "type": "date", "date": {"start": "2023-02-23", "end": None, "time_zone": None}}, }, { "name": "Status", "value": { - "id": "Z%3ClH", "type": "status", "status": { - "id": "86ddb6ec-0627-47f8-800d-b65afd28be13", "name": "Not started", "color": "default" - } - } - } - ] + "id": "Z%3ClH", + "type": "status", + "status": {"id": "86ddb6ec-0627-47f8-800d-b65afd28be13", "name": "Not started", "color": "default"}, + }, + }, + ], } assert NotionPropertiesTransformation().transform(input_record) == output_record @@ -64,55 +91,38 @@ def test_notion_properties_transformation(): {"id": "3", "last_edited_time": "2022-01-04T00:00:00.000Z"}, ] + @pytest.fixture def data_feed_config(): return NotionDataFeedFilter(parameters={}, config={"start_date": "2021-01-01T00:00:00.000Z"}) + @pytest.mark.parametrize( "state_value, expected_return", [ - ( - "2021-02-01T00:00:00.000Z", "2021-02-01T00:00:00.000Z" - ), - ( - "2020-01-01T00:00:00.000Z", "2021-01-01T00:00:00.000Z" - ), - ( - {}, "2021-01-01T00:00:00.000Z" - ) + ("2021-02-01T00:00:00.000Z", "2021-02-01T00:00:00.000Z"), + ("2020-01-01T00:00:00.000Z", "2021-01-01T00:00:00.000Z"), + ({}, "2021-01-01T00:00:00.000Z"), ], - ids=["State value is greater than start_date", "State value is less than start_date", "Empty state, default to start_date"] + ids=["State value is greater than start_date", "State value is less than start_date", "Empty state, default to start_date"], ) def test_data_feed_get_filter_date(data_feed_config, state_value, expected_return): start_date = data_feed_config.config["start_date"] - + result = data_feed_config._get_filter_date(start_date, state_value) assert result == expected_return, f"Expected {expected_return}, but got {result}." -@pytest.mark.parametrize("stream_state,stream_slice,expected_records", [ - ( - {"last_edited_time": "2022-01-01T00:00:00.000Z"}, - {"id": "some_id"}, - state_test_records - ), - ( - {"last_edited_time": "2022-01-03T00:00:00.000Z"}, - {"id": "some_id"}, - [state_test_records[-2], state_test_records[-1]] - ), - ( - {"last_edited_time": "2022-01-05T00:00:00.000Z"}, - {"id": "some_id"}, - [] - ), - ( - {}, - {"id": "some_id"}, - state_test_records - ) -], -ids=["No records filtered", "Some records filtered", "All records filtered", "Empty state: no records filtered"]) +@pytest.mark.parametrize( + "stream_state,stream_slice,expected_records", + [ + ({"last_edited_time": "2022-01-01T00:00:00.000Z"}, {"id": "some_id"}, state_test_records), + ({"last_edited_time": "2022-01-03T00:00:00.000Z"}, {"id": "some_id"}, [state_test_records[-2], state_test_records[-1]]), + ({"last_edited_time": "2022-01-05T00:00:00.000Z"}, {"id": "some_id"}, []), + ({}, {"id": "some_id"}, state_test_records), + ], + ids=["No records filtered", "Some records filtered", "All records filtered", "Empty state: no records filtered"], +) def test_data_feed_filter_records(data_feed_config, stream_state, stream_slice, expected_records): filtered_records = data_feed_config.filter_records(state_test_records, stream_state, stream_slice) assert filtered_records == expected_records, "Filtered records do not match the expected records." diff --git a/airbyte-integrations/connectors/source-notion/unit_tests/test_python_streams.py b/airbyte-integrations/connectors/source-notion/unit_tests/test_python_streams.py index 7b323ed72257..46b97f977cb2 100644 --- a/airbyte-integrations/connectors/source-notion/unit_tests/test_python_streams.py +++ b/airbyte-integrations/connectors/source-notion/unit_tests/test_python_streams.py @@ -10,11 +10,12 @@ import freezegun import pytest import requests -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException, UserDefinedBackoffException from pytest import fixture, mark from source_notion.streams import Blocks, IncrementalNotionStream, NotionStream, Pages +from airbyte_cdk.models import SyncMode +from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException, UserDefinedBackoffException + @pytest.fixture def patch_base_class(mocker): @@ -79,11 +80,7 @@ def test_http_method(patch_base_class): @pytest.mark.parametrize( "response_json, expected_output", - [ - ({"next_cursor": "some_cursor", "has_more": True}, {"next_cursor": "some_cursor"}), - ({"has_more": False}, None), - ({}, None) - ], + [({"next_cursor": "some_cursor", "has_more": True}, {"next_cursor": "some_cursor"}), ({"has_more": False}, None), ({}, None)], ids=["Next_page_token exists with cursor", "No next_page_token", "No next_page_token"], ) def test_next_page_token(patch_base_class, response_json, expected_output): @@ -454,21 +451,149 @@ def test_request_throttle(initial_page_size, expected_page_size, mock_response, def test_block_record_transformation(): stream = Blocks(parent=None, config=MagicMock()) response_record = { - "object": "block", "id": "id", "parent": {"type": "page_id", "page_id": "id"}, "created_time": "2021-10-19T13:33:00.000Z", "last_edited_time": "2021-10-19T13:33:00.000Z", - "created_by": {"object": "user", "id": "id"}, "last_edited_by": {"object": "user", "id": "id"}, "has_children": False, "archived": False, "type": "paragraph", - "paragraph": {"rich_text": [{"type": "text", "text": {"content": "test", "link": None}, "annotations": {"bold": False, "italic": False, "strikethrough": False, "underline": False, "code": False, "color": "default"}, "plain_text": "test", "href": None}, - {"type": "text", "text": {"content": "@", "link": None}, "annotations": {"bold": False, "italic": False, "strikethrough": False, "underline": False, "code": True, "color": "default"}, "plain_text": "@", "href": None}, - {"type": "text", "text": {"content": "test", "link": None}, "annotations": {"bold": False, "italic": False, "strikethrough": False, "underline": False, "code": False, "color": "default"}, "plain_text": "test", "href": None}, - {"type": "mention", "mention": {"type": "page", "page": {"id": "id"}}, "annotations": {"bold": False, "italic": False, "strikethrough": False, "underline": False, "code": False, "color": "default"}, - "plain_text": "test", "href": "https://www.notion.so/id"}], "color": "default"} + "object": "block", + "id": "id", + "parent": {"type": "page_id", "page_id": "id"}, + "created_time": "2021-10-19T13:33:00.000Z", + "last_edited_time": "2021-10-19T13:33:00.000Z", + "created_by": {"object": "user", "id": "id"}, + "last_edited_by": {"object": "user", "id": "id"}, + "has_children": False, + "archived": False, + "type": "paragraph", + "paragraph": { + "rich_text": [ + { + "type": "text", + "text": {"content": "test", "link": None}, + "annotations": { + "bold": False, + "italic": False, + "strikethrough": False, + "underline": False, + "code": False, + "color": "default", + }, + "plain_text": "test", + "href": None, + }, + { + "type": "text", + "text": {"content": "@", "link": None}, + "annotations": { + "bold": False, + "italic": False, + "strikethrough": False, + "underline": False, + "code": True, + "color": "default", + }, + "plain_text": "@", + "href": None, + }, + { + "type": "text", + "text": {"content": "test", "link": None}, + "annotations": { + "bold": False, + "italic": False, + "strikethrough": False, + "underline": False, + "code": False, + "color": "default", + }, + "plain_text": "test", + "href": None, + }, + { + "type": "mention", + "mention": {"type": "page", "page": {"id": "id"}}, + "annotations": { + "bold": False, + "italic": False, + "strikethrough": False, + "underline": False, + "code": False, + "color": "default", + }, + "plain_text": "test", + "href": "https://www.notion.so/id", + }, + ], + "color": "default", + }, } expected_record = { - "object": "block", "id": "id", "parent": {"type": "page_id", "page_id": "id"}, "created_time": "2021-10-19T13:33:00.000Z", "last_edited_time": "2021-10-19T13:33:00.000Z", - "created_by": {"object": "user", "id": "id"}, "last_edited_by": {"object": "user", "id": "id"}, "has_children": False, "archived": False, "type": "paragraph", - "paragraph": {"rich_text": [{"type": "text", "text": {"content": "test", "link": None}, "annotations":{"bold": False, "italic": False, "strikethrough": False, "underline": False, "code": False, "color": "default"}, "plain_text":"test", "href": None}, - {"type": "text", "text": {"content": "@", "link": None}, "annotations": {"bold": False, "italic": False, "strikethrough": False, "underline": False, "code": True, "color": "default"}, "plain_text": "@", "href": None}, - {"type": "text", "text": {"content": "test", "link": None}, "annotations": {"bold": False, "italic": False, "strikethrough": False, "underline": False, "code": False, "color": "default"}, "plain_text": "test", "href": None}, - {"type": "mention", "mention": {"type": "page", "info": {"id": "id"}}, "annotations": {"bold": False, "italic": False, "strikethrough": False, "underline": False, "code": False, "color": "default"}, "plain_text": "test", "href": "https://www.notion.so/id"}], - "color": "default"} + "object": "block", + "id": "id", + "parent": {"type": "page_id", "page_id": "id"}, + "created_time": "2021-10-19T13:33:00.000Z", + "last_edited_time": "2021-10-19T13:33:00.000Z", + "created_by": {"object": "user", "id": "id"}, + "last_edited_by": {"object": "user", "id": "id"}, + "has_children": False, + "archived": False, + "type": "paragraph", + "paragraph": { + "rich_text": [ + { + "type": "text", + "text": {"content": "test", "link": None}, + "annotations": { + "bold": False, + "italic": False, + "strikethrough": False, + "underline": False, + "code": False, + "color": "default", + }, + "plain_text": "test", + "href": None, + }, + { + "type": "text", + "text": {"content": "@", "link": None}, + "annotations": { + "bold": False, + "italic": False, + "strikethrough": False, + "underline": False, + "code": True, + "color": "default", + }, + "plain_text": "@", + "href": None, + }, + { + "type": "text", + "text": {"content": "test", "link": None}, + "annotations": { + "bold": False, + "italic": False, + "strikethrough": False, + "underline": False, + "code": False, + "color": "default", + }, + "plain_text": "test", + "href": None, + }, + { + "type": "mention", + "mention": {"type": "page", "info": {"id": "id"}}, + "annotations": { + "bold": False, + "italic": False, + "strikethrough": False, + "underline": False, + "code": False, + "color": "default", + }, + "plain_text": "test", + "href": "https://www.notion.so/id", + }, + ], + "color": "default", + }, } assert stream.transform(response_record) == expected_record diff --git a/airbyte-integrations/connectors/source-notion/unit_tests/test_source.py b/airbyte-integrations/connectors/source-notion/unit_tests/test_source.py index c270f0894e5e..3a5696e77574 100644 --- a/airbyte-integrations/connectors/source-notion/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-notion/unit_tests/test_source.py @@ -3,9 +3,10 @@ # import pytest -from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator from source_notion.source import SourceNotion +from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator + @pytest.mark.parametrize( "config, expected_token", @@ -29,8 +30,7 @@ def test_get_authenticator(config, expected_token): def test_streams(): source = SourceNotion() - config_mock = {"start_date": "2020-01-01T00:00:00.000Z", - "credentials": {"auth_type": "token", "token": "abcd"}} + config_mock = {"start_date": "2020-01-01T00:00:00.000Z", "credentials": {"auth_type": "token", "token": "abcd"}} streams = source.streams(config_mock) expected_streams_number = 5 assert len(streams) == expected_streams_number diff --git a/airbyte-integrations/connectors/source-nutshell/README.md b/airbyte-integrations/connectors/source-nutshell/README.md new file mode 100644 index 000000000000..a60ce86fcbe0 --- /dev/null +++ b/airbyte-integrations/connectors/source-nutshell/README.md @@ -0,0 +1,35 @@ +# Nutshell +This directory contains the manifest-only connector for `source-nutshell`. + +Nutshell is a CRM tool. +Using this connector we can extract data from various streams such as contacts , events , products and pipelines. +Docs : https://developers.nutshell.com/docs/getting-started + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-nutshell:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-nutshell build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-nutshell test +``` + diff --git a/airbyte-integrations/connectors/source-nutshell/acceptance-test-config.yml b/airbyte-integrations/connectors/source-nutshell/acceptance-test-config.yml new file mode 100644 index 000000000000..f58afe11e410 --- /dev/null +++ b/airbyte-integrations/connectors/source-nutshell/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-nutshell:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-nutshell/icon.svg b/airbyte-integrations/connectors/source-nutshell/icon.svg new file mode 100644 index 000000000000..7aa322cc08e4 --- /dev/null +++ b/airbyte-integrations/connectors/source-nutshell/icon.svg @@ -0,0 +1 @@ +Nutshell_lockup_full_color diff --git a/airbyte-integrations/connectors/source-nutshell/manifest.yaml b/airbyte-integrations/connectors/source-nutshell/manifest.yaml new file mode 100644 index 000000000000..47569121ecf3 --- /dev/null +++ b/airbyte-integrations/connectors/source-nutshell/manifest.yaml @@ -0,0 +1,5510 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Nutshell is a CRM tool. + + Using this connector we can extract data from various streams such as contacts + , events , products and pipelines. + + Docs : https://developers.nutshell.com/docs/getting-started + +check: + type: CheckStream + stream_names: + - accounts + +definitions: + streams: + accounts: + type: DeclarativeStream + name: accounts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: accounts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - accounts + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page[page] + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: page[limit] + pagination_strategy: + type: PageIncrement + start_from_page: 0 + page_size: 500 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounts" + accounts_list_items: + type: DeclarativeStream + name: accounts_list_items + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: accounts/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - listItems + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounts_list_items" + account_types: + type: DeclarativeStream + name: account_types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: accounttypes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - accountTypes + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/account_types" + industries: + type: DeclarativeStream + name: industries + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: industries + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - industries + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/industries" + activities: + type: DeclarativeStream + name: activities + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: activities + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - activities + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page[page] + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: page[limit] + pagination_strategy: + type: PageIncrement + start_from_page: 0 + page_size: 500 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/activities" + activity_types: + type: DeclarativeStream + name: activity_types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: activitytypes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - activityTypes + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/activity_types" + audiences: + type: DeclarativeStream + name: audiences + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: audiences + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - emAudiences + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/audiences" + competitors: + type: DeclarativeStream + name: competitors + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: competitors + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - competitors + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/competitors" + competitor_maps: + type: DeclarativeStream + name: competitor_maps + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: competitormaps + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - competitorMaps + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/competitor_maps" + leads_custom_fields: + type: DeclarativeStream + name: leads_custom_fields + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: leads/customfields/attributes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - customFields + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/leads_custom_fields" + leads_list_items: + type: DeclarativeStream + name: leads_list_items + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: leads/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - listItems + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/leads_list_items" + leads: + type: DeclarativeStream + name: leads + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: leads + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - accounts + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page[page] + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: page[limit] + pagination_strategy: + type: PageIncrement + start_from_page: 0 + page_size: 500 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/leads" + leads_report: + type: DeclarativeStream + name: leads_report + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: leads/report + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - reports + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/leads_report" + contacts_custom_fields: + type: DeclarativeStream + name: contacts_custom_fields + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: contacts/customfields/attributes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - customFields + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts_custom_fields" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - contacts + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page[page] + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: page[limit] + pagination_strategy: + type: PageIncrement + start_from_page: 0 + page_size: 500 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + contacts_list_items: + type: DeclarativeStream + name: contacts_list_items + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: contacts/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - listItems + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts_list_items" + events: + type: DeclarativeStream + name: events + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: events + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - events + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + page_size: 500 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/events" + filters: + type: DeclarativeStream + name: filters + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: filters + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - filters + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/filters" + notes: + type: DeclarativeStream + name: notes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: notes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - notes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page[page] + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: page[limit] + pagination_strategy: + type: PageIncrement + start_from_page: 0 + page_size: 1000 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/notes" + products: + type: DeclarativeStream + name: products + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: products + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - products + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + lead_products: + type: DeclarativeStream + name: lead_products + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: productmaps + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - productMaps + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/lead_products" + sources: + type: DeclarativeStream + name: sources + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sources + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - sources + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sources" + stages: + type: DeclarativeStream + name: stages + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: stages + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - stages + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stages" + pipelines: + type: DeclarativeStream + name: pipelines + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: stagesets + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - stagesets + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/pipelines" + tags: + type: DeclarativeStream + name: tags + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: tags + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - tags + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tags" + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - users + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + base_requester: + type: HttpRequester + url_base: https://app.nutshell.com/rest/ + authenticator: + type: BasicHttpAuthenticator + password: "{{ config[\"password\"] }}" + username: "{{ config[\"username\"] }}" + +streams: + - $ref: "#/definitions/streams/accounts" + - $ref: "#/definitions/streams/accounts_list_items" + - $ref: "#/definitions/streams/account_types" + - $ref: "#/definitions/streams/industries" + - $ref: "#/definitions/streams/activities" + - $ref: "#/definitions/streams/activity_types" + - $ref: "#/definitions/streams/audiences" + - $ref: "#/definitions/streams/competitors" + - $ref: "#/definitions/streams/competitor_maps" + - $ref: "#/definitions/streams/leads_custom_fields" + - $ref: "#/definitions/streams/leads_list_items" + - $ref: "#/definitions/streams/leads" + - $ref: "#/definitions/streams/leads_report" + - $ref: "#/definitions/streams/contacts_custom_fields" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/contacts_list_items" + - $ref: "#/definitions/streams/events" + - $ref: "#/definitions/streams/filters" + - $ref: "#/definitions/streams/notes" + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/lead_products" + - $ref: "#/definitions/streams/sources" + - $ref: "#/definitions/streams/stages" + - $ref: "#/definitions/streams/pipelines" + - $ref: "#/definitions/streams/tags" + - $ref: "#/definitions/streams/users" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - username + properties: + username: + type: string + order: 0 + title: Username + password: + type: string + order: 1 + title: API Token + always_show: true + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + accounts: true + accounts_list_items: true + account_types: true + industries: true + activities: true + activity_types: true + audiences: true + competitors: true + competitor_maps: true + leads_custom_fields: true + leads_list_items: true + leads: true + leads_report: true + contacts_custom_fields: true + contacts: true + contacts_list_items: true + events: true + filters: true + notes: true + products: true + lead_products: true + sources: true + stages: true + pipelines: true + tags: true + users: true + testedStreams: + accounts: + streamHash: 96176c8138e2947189c8248d0e107c45e2213c1d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + accounts_list_items: + hasRecords: true + streamHash: 950a82a5cb97a96275f458afab995a8b7f7f4253 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + account_types: + hasRecords: true + streamHash: 3971bad17989f52be26760bf32361dada60abffb + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + industries: + hasRecords: true + streamHash: 090308ee3fd98e1d63726112a68f5603c6a640ab + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + activities: + streamHash: 9ecc362e2ccb01a394d8b7b896dd08c05348038f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + activity_types: + hasRecords: true + streamHash: 75d8067582013231d6422857b1809e33a988dc79 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + audiences: + hasRecords: true + streamHash: 1740633999bd89071ff1cd5815596cbc54ae992e + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + competitors: + hasRecords: true + streamHash: f228a19770cc2cd56bdc0ae29ff514b5004ed1ca + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + competitor_maps: + hasRecords: true + streamHash: 9c9a560b8998b245b53e489926b82bf88eb0ac65 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + leads_custom_fields: + hasRecords: true + streamHash: efc120a9dd34396060e67db65ce8d30c87909fc0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + leads_list_items: + hasRecords: true + streamHash: 3ccca9e30beaefb65eb56df09e2c4071661f2571 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + leads: + streamHash: 713b65b5d2b685ca04263fc807932e804b4207d3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + leads_report: + hasRecords: true + streamHash: 8fada2e36796f20d464127fe1cbb8db5bbd4bec1 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + contacts_custom_fields: + hasRecords: true + streamHash: 5ce848d74dc68b2437021e5ef54dce4b21152e80 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + contacts: + streamHash: 57a95ebdcdd0abb5d0cc85d688cd483dca929c11 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contacts_list_items: + hasRecords: true + streamHash: 3acd42b55b54243d6fd283f8797d3d5922f82b29 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + events: + streamHash: f0ce38f5cbaf8b080683b37903d431cdd473d600 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + filters: + hasRecords: true + streamHash: c421400c7d79583d7cdf23b502009ee9d50a7efb + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + notes: + streamHash: d8b92a0d1132bad5d95d178bcd4d02718f07634b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + products: + hasRecords: true + streamHash: 2ff96073d3e16d854f41423cd115d5bf2103cea6 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + lead_products: + hasRecords: true + streamHash: a4f6eb55ac384e9ff0c3d6520f3a58f057413c1a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + sources: + hasRecords: true + streamHash: 50b294bf440887aebdbe3649ddf763a08f5e113e + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + stages: + hasRecords: true + streamHash: 7d4571033d422d8bece1b991415e857e035ee259 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + pipelines: + hasRecords: true + streamHash: 05a244867424c123a2ff84728827bd623b4190ef + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + tags: + hasRecords: true + streamHash: e9314e64ff51a372efe7cb64cf5ad72e6007f15f + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + users: + hasRecords: true + streamHash: 9715618f1ce6e97522d9f18503982a8547fe6933 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: {} + +schemas: + accounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + addresses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + isPrimary: + type: + - boolean + - "null" + name: + type: + - string + - "null" + value: + type: + - object + - "null" + properties: + address_1: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + location: + type: + - object + - "null" + properties: + latitude: + type: + - number + - "null" + longitude: + type: + - number + - "null" + locationAccuracy: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + state: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + emails: + type: + - array + - "null" + href: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: string + initials: + type: + - string + - "null" + links: + type: + - object + - "null" + properties: + accountType: + type: + - string + - "null" + contacts: + type: + - array + - "null" + items: + type: + - string + - "null" + files: + type: + - array + - "null" + industry: + type: + - string + - "null" + relatedFiles: + type: + - array + - "null" + tags: + type: + - array + - "null" + name: + type: + - string + - "null" + phones: + type: + - array + - "null" + urls: + type: + - array + - "null" + required: + - id + accounts_list_items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + fields: + type: + - object + - "null" + properties: + description: + type: + - object + - "null" + properties: {} + accountType: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + address: + type: + - object + - "null" + properties: + address_1: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + postal_code: + type: + - string + - "null" + state: + type: + - string + - "null" + value: + type: + - string + - "null" + childAccounts: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: + - string + - "null" + initials: + type: + - string + - "null" + name: + type: + - string + - "null" + clickedEmailSequenceTemplates: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + contactIds: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + contacts: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: + - string + - "null" + initials: + type: + - string + - "null" + name: + type: + - string + - "null" + createdTime: + type: + - object + - "null" + properties: + absoluteLocalizedString: + type: + - string + - "null" + timestamp: + type: + - number + - "null" + value: + type: + - string + - "null" + creator: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + id: + type: + - string + - "null" + initials: + type: + - string + - "null" + name: + type: + - string + - "null" + ctctBounceRate: + type: + - object + - "null" + properties: {} + ctctClickRate: + type: + - object + - "null" + properties: {} + ctctEmailAddress: + type: + - object + - "null" + properties: {} + ctctEngagementRating: + type: + - object + - "null" + properties: {} + ctctLastClickTime: + type: + - object + - "null" + properties: {} + ctctLastOpenTime: + type: + - object + - "null" + properties: {} + ctctLists: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + ctctNumberOfEmailsSent: + type: + - object + - "null" + properties: {} + ctctOpenRate: + type: + - object + - "null" + properties: {} + ctctStatus: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: {} + deletedTime: + type: + - object + - "null" + properties: {} + email: + type: + - object + - "null" + properties: {} + emailClickCount: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + emailClickRate: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + emailLastClickTime: + type: + - object + - "null" + properties: {} + emailLastOpenTime: + type: + - object + - "null" + properties: {} + emailOpenCount: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + emailOpenRate: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + inProgressEmailSequenceTemplates: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + industry: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + lastContactedTime: + type: + - object + - "null" + properties: + absoluteLocalizedString: + type: + - string + - "null" + timestamp: + type: + - number + - "null" + value: + type: + - string + - "null" + lastLoggedActivity_11_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_15_Time: + type: + - object + - "null" + properties: + absoluteLocalizedString: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + value: + type: + - string + - "null" + lastLoggedActivity_19_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_1_Time: + type: + - object + - "null" + properties: + absoluteLocalizedString: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + value: + type: + - string + - "null" + lastLoggedActivity_23_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_27_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_2_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_3_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_6_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_7_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_8_Time: + type: + - object + - "null" + properties: + absoluteLocalizedString: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + value: + type: + - string + - "null" + leadIds: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + leads: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + legacyId: + type: + - object + - "null" + properties: {} + name: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + nextActivityStartTime: + type: + - object + - "null" + properties: {} + noReplyEmailSequenceTemplates: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + numChildAccounts: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + numberOfCancelledLeads: + type: + - object + - "null" + properties: {} + numberOfContacts: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + numberOfEmailsReceived: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + numberOfEmailsSent: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + numberOfEmployees: + type: + - object + - "null" + properties: {} + numberOfLeads: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + numberOfLostLeads: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + numberOfOpenLeads: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + numberOfWonLeads: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + openedEmailSequenceTemplates: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + origin: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + id: + type: + - string + - "null" + initials: + type: + - string + - "null" + name: + type: + - string + - "null" + parentAccount: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: + - string + - "null" + initials: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - object + - "null" + properties: {} + phones: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + fax: + type: + - array + - "null" + home: + type: + - array + - "null" + mobile: + type: + - array + - "null" + other: + type: + - array + - "null" + phone: + type: + - array + - "null" + work: + type: + - array + - "null" + postalCode: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + receivedEmailSequenceTemplates: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + receivedReplyEmailSequenceTemplates: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + revenue: + type: + - object + - "null" + properties: {} + tags: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + territory: + type: + - object + - "null" + properties: {} + url: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: {} + valueOfCancelledLeads: + type: + - object + - "null" + properties: {} + valueOfLostLeads: + type: + - object + - "null" + properties: + formattedValue: + type: + - object + - "null" + properties: + formatted: + type: + - string + - "null" + prefix: + type: + - string + - "null" + suffix: + type: + - string + - "null" + value: + type: + - number + - "null" + value: + type: + - string + - "null" + valueOfOpenLeads: + type: + - object + - "null" + properties: + formattedValue: + type: + - object + - "null" + properties: + formatted: + type: + - string + - "null" + prefix: + type: + - string + - "null" + suffix: + type: + - string + - "null" + value: + type: + - number + - "null" + value: + type: + - string + - "null" + valueOfWonLeads: + type: + - object + - "null" + properties: + formattedValue: + type: + - object + - "null" + properties: + formatted: + type: + - string + - "null" + prefix: + type: + - string + - "null" + suffix: + type: + - string + - "null" + value: + type: + - number + - "null" + value: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: string + initials: + type: + - string + - "null" + isDeleted: + type: + - boolean + - "null" + latlon: + type: + - array + - "null" + items: + type: + - string + - "null" + links: + type: + - object + - "null" + properties: + entity: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + href: + type: + - string + - "null" + id: + type: + - string + - "null" + mapUrl: + type: + - string + - "null" + primaryInfo: + type: + - string + - "null" + primaryName: + type: + - string + - "null" + relatedInfo: + type: + - string + - "null" + relatedName: + type: + - string + - "null" + relatedType: + type: + - string + - "null" + relatedUrl: + type: + - string + - "null" + relatedUrlPath: + type: + - string + - "null" + required: + - id + account_types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + id: + type: string + modifiedTime: + type: + - number + - "null" + name: + type: + - string + - "null" + required: + - id + industries: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + id: + type: string + modifiedTime: + type: + - number + - "null" + name: + type: + - string + - "null" + required: + - id + activities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + agenda: + type: + - string + - "null" + createdTime: + type: + - number + - "null" + endTime: + type: + - number + - "null" + href: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: string + isAllDay: + type: + - boolean + - "null" + isCancelled: + type: + - boolean + - "null" + isEditable: + type: + - boolean + - "null" + isFlagged: + type: + - boolean + - "null" + isLogged: + type: + - boolean + - "null" + isMediaLogged: + type: + - boolean + - "null" + isOverdue: + type: + - boolean + - "null" + links: + type: + - object + - "null" + properties: + accounts: + type: + - array + - "null" + activityType: + type: + - string + - "null" + comments: + type: + - array + - "null" + contacts: + type: + - array + - "null" + creator: + type: + - string + - "null" + leads: + type: + - array + - "null" + items: + type: + - string + - "null" + logger: + type: + - string + - "null" + users: + type: + - array + - "null" + items: + type: + - string + - "null" + loggedTime: + type: + - number + - "null" + modifiedTime: + type: + - number + - "null" + name: + type: + - string + - "null" + startTime: + type: + - number + - "null" + required: + - id + activity_types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + id: + type: string + isBenchmarkable: + type: + - boolean + - "null" + name: + type: + - string + - "null" + required: + - id + audiences: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + id: + type: string + isWebFX: + type: + - boolean + - "null" + name: + type: + - string + - "null" + required: + - id + competitors: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + id: + type: string + modifiedTime: + type: + - number + - "null" + name: + type: + - string + - "null" + required: + - id + competitor_maps: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + id: + type: string + links: + type: + - object + - "null" + properties: + competitor: + type: + - string + - "null" + lead: + type: + - string + - "null" + name: + type: + - string + - "null" + status: + type: + - string + - "null" + required: + - id + leads_custom_fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + enum: + type: + - array + - "null" + items: + type: + - string + - "null" + id: + type: string + title: + type: + - string + - "null" + required: + - id + leads_list_items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + fields: + type: + - object + - "null" + properties: + accounts: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: + - string + - "null" + initials: + type: + - string + - "null" + name: + type: + - string + - "null" + contacts: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: + - string + - "null" + initials: + type: + - string + - "null" + name: + type: + - string + - "null" + name: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + nextActivityStartTime: + type: + - object + - "null" + properties: {} + overdueDuration: + type: + - object + - "null" + properties: {} + owner: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + id: + type: + - string + - "null" + initials: + type: + - string + - "null" + name: + type: + - string + - "null" + status: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + value: + type: + - string + - "null" + value: + type: + - object + - "null" + properties: + formattedValue: + type: + - object + - "null" + properties: + formatted: + type: + - string + - "null" + prefix: + type: + - string + - "null" + suffix: + type: + - string + - "null" + value: + type: + - number + - "null" + value: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: string + isDeleted: + type: + - boolean + - "null" + latlon: + type: + - array + - "null" + items: + type: + - string + - "null" + links: + type: + - object + - "null" + properties: + entity: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + href: + type: + - string + - "null" + id: + type: + - string + - "null" + mapUrl: + type: + - string + - "null" + primaryAccount: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + primaryContact: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + primaryInfo: + type: + - string + - "null" + primaryName: + type: + - string + - "null" + priority: + type: + - string + - "null" + relatedInfo: + type: + - string + - "null" + relatedName: + type: + - string + - "null" + relatedType: + type: + - string + - "null" + relatedUrl: + type: + - string + - "null" + relatedUrlPath: + type: + - string + - "null" + sortKey: + type: + - string + - "null" + required: + - id + leads: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + addresses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + isPrimary: + type: + - boolean + - "null" + name: + type: + - string + - "null" + value: + type: + - object + - "null" + properties: + address_1: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + location: + type: + - object + - "null" + properties: + latitude: + type: + - number + - "null" + longitude: + type: + - number + - "null" + locationAccuracy: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + state: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + emails: + type: + - array + - "null" + href: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: string + initials: + type: + - string + - "null" + links: + type: + - object + - "null" + properties: + accountType: + type: + - string + - "null" + contacts: + type: + - array + - "null" + items: + type: + - string + - "null" + files: + type: + - array + - "null" + industry: + type: + - string + - "null" + relatedFiles: + type: + - array + - "null" + tags: + type: + - array + - "null" + name: + type: + - string + - "null" + phones: + type: + - array + - "null" + urls: + type: + - array + - "null" + required: + - id + leads_report: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + data: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + bucket: + type: + - string + - "null" + bucketType: + type: + - string + - "null" + count: + type: + - object + - "null" + properties: + formatted: + type: + - string + - "null" + label: + type: + - string + - "null" + prefix: + type: + - string + - "null" + subvalues: + type: + - array + - "null" + suffix: + type: + - string + - "null" + value: + type: + - number + - "null" + filters: + type: + - object + - "null" + properties: + createdTime: + type: + - string + - "null" + segments: + type: + - array + - "null" + total: + type: + - object + - "null" + properties: + formatted: + type: + - string + - "null" + label: + type: + - string + - "null" + prefix: + type: + - string + - "null" + subvalues: + type: + - array + - "null" + suffix: + type: + - string + - "null" + value: + type: + - number + - "null" + id: + type: string + key: + type: + - string + - "null" + name: + type: + - string + - "null" + prefix: + type: + - string + - "null" + summary: + type: + - object + - "null" + properties: + bucket: + type: + - string + - "null" + bucketType: + type: + - string + - "null" + count: + type: + - object + - "null" + properties: + formatted: + type: + - string + - "null" + prefix: + type: + - string + - "null" + subvalues: + type: + - array + - "null" + suffix: + type: + - string + - "null" + value: + type: + - number + - "null" + filters: + type: + - object + - "null" + segments: + type: + - array + - "null" + total: + type: + - object + - "null" + properties: + formatted: + type: + - string + - "null" + prefix: + type: + - string + - "null" + subvalues: + type: + - array + - "null" + suffix: + type: + - string + - "null" + value: + type: + - number + - "null" + required: + - id + contacts_custom_fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + id: + type: string + title: + type: + - string + - "null" + required: + - id + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + addresses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + isPrimary: + type: + - boolean + - "null" + name: + type: + - string + - "null" + value: + type: + - object + - "null" + properties: + address_1: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + location: + type: + - object + - "null" + properties: + latitude: + type: + - number + - "null" + longitude: + type: + - number + - "null" + locationAccuracy: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + state: + type: + - string + - "null" + timezone: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + emails: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + isPrimary: + type: + - boolean + - "null" + name: + type: + - string + - "null" + value: + type: + - string + - "null" + firstName: + type: + - string + - "null" + href: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: string + initials: + type: + - string + - "null" + jobTitle: + type: + - string + - "null" + jobs: + anyOf: + - type: array + - type: object + properties: + 1-accounts: + type: object + properties: + title: + type: "null" + 10-accounts: + type: object + properties: + title: + type: "null" + 11-accounts: + type: object + properties: + title: + type: "null" + 12-accounts: + type: object + properties: + title: + type: "null" + 13-accounts: + type: object + properties: + title: + type: "null" + 14-accounts: + type: object + properties: + title: + type: "null" + 15-accounts: + type: object + properties: + title: + type: "null" + 16-accounts: + type: object + properties: + title: + type: "null" + 17-accounts: + type: object + properties: + title: + type: "null" + 18-accounts: + type: object + properties: + title: + type: "null" + 19-accounts: + type: object + properties: + title: + type: "null" + 2-accounts: + type: object + properties: + title: + type: "null" + 20-accounts: + type: object + properties: + title: + type: "null" + 21-accounts: + type: object + properties: + title: + type: "null" + 22-accounts: + type: object + properties: + title: + type: "null" + 23-accounts: + type: object + properties: + title: + type: "null" + 24-accounts: + type: object + properties: + title: + type: "null" + 25-accounts: + type: object + properties: + title: + type: "null" + 26-accounts: + type: object + properties: + title: + type: "null" + 27-accounts: + type: object + properties: + title: + type: "null" + 28-accounts: + type: object + properties: + title: + type: "null" + 29-accounts: + type: object + properties: + title: + type: "null" + 3-accounts: + type: object + properties: + title: + type: "null" + 30-accounts: + type: object + properties: + title: + type: "null" + 31-accounts: + type: object + properties: + title: + type: "null" + 32-accounts: + type: object + properties: + title: + type: "null" + 4-accounts: + type: object + properties: + title: + type: "null" + 5-accounts: + type: object + properties: + title: + type: "null" + 6-accounts: + type: object + properties: + title: + type: "null" + 7-accounts: + type: object + properties: + title: + type: "null" + 8-accounts: + type: object + properties: + title: + type: "null" + 9-accounts: + type: object + properties: + title: + type: "null" + lastName: + type: + - string + - "null" + links: + type: + - object + - "null" + properties: + accounts: + type: + - array + - "null" + items: + type: + - string + - "null" + files: + type: + - array + - "null" + relatedFiles: + type: + - array + - "null" + tags: + type: + - array + - "null" + items: + type: + - string + - "null" + name: + type: + - string + - "null" + phones: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + isPrimary: + type: + - boolean + - "null" + name: + type: + - string + - "null" + value: + type: + - object + - "null" + properties: + E164: + type: + - string + - "null" + countryCode: + type: + - string + - "null" + countryCodeAndNumber: + type: + - string + - "null" + number: + type: + - string + - "null" + numberFormatted: + type: + - string + - "null" + urls: + type: + - array + - "null" + required: + - id + contacts_list_items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + fields: + type: + - object + - "null" + properties: + description: + type: + - object + - "null" + properties: {} + Starting Date: + type: + - object + - "null" + properties: {} + accountIds: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + accountTags: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + accountType: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + accounts: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: + - string + - "null" + initials: + type: + - string + - "null" + name: + type: + - string + - "null" + address: + type: + - object + - "null" + properties: + address_1: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + postal_code: + type: + - string + - "null" + state: + type: + - string + - "null" + value: + type: + - string + - "null" + audiences: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + bouncedDripSequences: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + bouncedEditions: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + clickedDripSequences: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + clickedEditions: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + clickedEmailSequenceTemplates: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + companyAddress: + type: + - object + - "null" + properties: + address_1: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + postal_code: + type: + - string + - "null" + state: + type: + - string + - "null" + value: + type: + - string + - "null" + companyPhone: + type: + - object + - "null" + properties: {} + createdTime: + type: + - object + - "null" + properties: + absoluteLocalizedString: + type: + - string + - "null" + timestamp: + type: + - number + - "null" + value: + type: + - string + - "null" + creator: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + id: + type: + - string + - "null" + initials: + type: + - string + - "null" + name: + type: + - string + - "null" + ctctBounceRate: + type: + - object + - "null" + properties: {} + ctctClickRate: + type: + - object + - "null" + properties: {} + ctctEmailAddress: + type: + - object + - "null" + properties: {} + ctctEngagementRating: + type: + - object + - "null" + properties: {} + ctctLastClickTime: + type: + - object + - "null" + properties: {} + ctctLastOpenTime: + type: + - object + - "null" + properties: {} + ctctLists: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + ctctNumberOfEmailsSent: + type: + - object + - "null" + properties: {} + ctctOpenRate: + type: + - object + - "null" + properties: {} + ctctStatus: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: {} + deletedTime: + type: + - object + - "null" + properties: {} + email: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + emailClickCount: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + emailClickRate: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + emailLastClickTime: + type: + - object + - "null" + properties: + absoluteLocalizedString: + type: + - string + - "null" + timestamp: + type: + - number + - "null" + value: + type: + - string + - "null" + emailLastOpenTime: + type: + - object + - "null" + properties: + absoluteLocalizedString: + type: + - string + - "null" + timestamp: + type: + - number + - "null" + value: + type: + - string + - "null" + emailOpenCount: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + emailOpenRate: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + engagementRating: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + inProgressDripSequences: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + inProgressEmailSequenceTemplates: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + industry: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + jobTitle: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + lastContactedTime: + type: + - object + - "null" + properties: + absoluteLocalizedString: + type: + - string + - "null" + timestamp: + type: + - number + - "null" + value: + type: + - string + - "null" + lastLoggedActivity_11_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_15_Time: + type: + - object + - "null" + properties: + absoluteLocalizedString: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + value: + type: + - string + - "null" + lastLoggedActivity_19_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_1_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_23_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_27_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_2_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_3_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_6_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_7_Time: + type: + - object + - "null" + properties: {} + lastLoggedActivity_8_Time: + type: + - object + - "null" + properties: + absoluteLocalizedString: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + value: + type: + - string + - "null" + leadIds: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + leads: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: + - string + - "null" + initials: + type: + - string + - "null" + name: + type: + - string + - "null" + legacyId: + type: + - object + - "null" + properties: {} + marketingLastContactedTime: + type: + - object + - "null" + properties: + absoluteLocalizedString: + type: + - string + - "null" + timestamp: + type: + - string + - "null" + value: + type: + - string + - "null" + marketingStatus: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + name: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + nextActivityStartTime: + type: + - object + - "null" + properties: {} + noReplyEmailSequenceTemplates: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + numberOfCancelledLeads: + type: + - object + - "null" + properties: {} + numberOfEmailsReceived: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + numberOfEmailsSent: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + numberOfLeads: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + numberOfLostLeads: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + numberOfOpenLeads: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + numberOfWonLeads: + type: + - object + - "null" + properties: + value: + type: + - number + - "null" + openedEmailSequenceTemplates: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + origin: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + id: + type: + - string + - "null" + initials: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + phones: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + fax: + type: + - array + - "null" + home: + type: + - array + - "null" + mobile: + type: + - array + - "null" + items: + type: + - string + - "null" + other: + type: + - array + - "null" + phone: + type: + - array + - "null" + items: + type: + - string + - "null" + work: + type: + - array + - "null" + postalCode: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + primaryAccountOwner: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + id: + type: + - string + - "null" + initials: + type: + - string + - "null" + name: + type: + - string + - "null" + receivedAllMessagesDripSequences: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + receivedDripSequences: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + receivedEditions: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + receivedEmailSequenceTemplates: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + receivedReplyEmailSequenceTemplates: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + sentEditions: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + subscribedAudiences: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + tags: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + color: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + territory: + type: + - object + - "null" + properties: {} + unsubscribedAudiences: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + unsubscribedFromAllEmails: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + url: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: {} + valueOfCancelledLeads: + type: + - object + - "null" + properties: {} + valueOfLostLeads: + type: + - object + - "null" + properties: + formattedValue: + type: + - object + - "null" + properties: + formatted: + type: + - string + - "null" + prefix: + type: + - string + - "null" + suffix: + type: + - string + - "null" + value: + type: + - number + - "null" + value: + type: + - string + - "null" + valueOfOpenLeads: + type: + - object + - "null" + properties: + formattedValue: + type: + - object + - "null" + properties: + formatted: + type: + - string + - "null" + prefix: + type: + - string + - "null" + suffix: + type: + - string + - "null" + value: + type: + - number + - "null" + value: + type: + - string + - "null" + valueOfWonLeads: + type: + - object + - "null" + properties: + formattedValue: + type: + - object + - "null" + properties: + formatted: + type: + - string + - "null" + prefix: + type: + - string + - "null" + suffix: + type: + - string + - "null" + value: + type: + - number + - "null" + value: + type: + - string + - "null" + viewedDripSequences: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + viewedEditions: + type: + - object + - "null" + properties: + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + value: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: string + initials: + type: + - string + - "null" + isDeleted: + type: + - boolean + - "null" + latlon: + type: + - array + - "null" + items: + type: + - string + - "null" + links: + type: + - object + - "null" + properties: + entity: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + href: + type: + - string + - "null" + id: + type: + - string + - "null" + mapUrl: + type: + - string + - "null" + primaryInfo: + type: + - string + - "null" + primaryName: + type: + - string + - "null" + relatedInfo: + type: + - string + - "null" + relatedName: + type: + - string + - "null" + relatedType: + type: + - string + - "null" + relatedUrl: + type: + - string + - "null" + relatedUrlPath: + type: + - string + - "null" + required: + - id + events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + action: + type: + - string + - "null" + actorType: + type: + - string + - "null" + changes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribute: + type: + - string + - "null" + newValue: + anyOf: + - type: string + - type: object + properties: + type: + type: string + id: + type: string + name: + type: string + position: + type: number + oldValue: + anyOf: + - type: string + - type: object + properties: + type: + type: string + id: + type: string + name: + type: string + position: + type: number + createdTime: + type: + - number + - "null" + id: + type: string + links: + type: + - object + - "null" + properties: + actor: + type: + - string + - "null" + comments: + type: + - array + - "null" + payloads: + type: + - array + - "null" + items: + type: + - string + - "null" + payloadType: + type: + - string + - "null" + required: + - id + filters: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + createdTime: + type: + - number + - "null" + href: + type: + - string + - "null" + id: + type: string + isDeleteable: + type: + - boolean + - "null" + isImmutable: + type: + - boolean + - "null" + isShared: + type: + - boolean + - "null" + isUpdateable: + type: + - boolean + - "null" + links: + type: + - object + - "null" + properties: + user: + type: + - string + - "null" + usersAndTeams: + type: + - array + - "null" + name: + type: + - string + - "null" + reportType: + type: + - string + - "null" + value: + type: + - string + - "null" + required: + - id + notes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + body: + type: + - string + - "null" + bodyMarkup: + type: + - string + - "null" + createdTime: + type: + - number + - "null" + href: + type: + - string + - "null" + htmlUrl: + type: + - string + - "null" + htmlUrlPath: + type: + - string + - "null" + id: + type: string + isEditable: + type: + - boolean + - "null" + links: + type: + - object + - "null" + properties: + comments: + type: + - array + - "null" + parent: + type: + - string + - "null" + parentType: + type: + - string + - "null" + required: + - id + products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + href: + type: + - string + - "null" + id: + type: string + modifiedTime: + type: + - number + - "null" + name: + type: + - string + - "null" + price: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + currency: + type: + - string + - "null" + currencySymbol: + type: + - string + - "null" + formatted: + type: + - string + - "null" + prices: + type: + - object + - "null" + properties: + 1-markets: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + currency: + type: + - string + - "null" + currencySymbol: + type: + - string + - "null" + formatted: + type: + - string + - "null" + productType: + type: + - string + - "null" + required: + - id + lead_products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + id: + type: string + links: + type: + - object + - "null" + properties: + lead: + type: + - string + - "null" + product: + type: + - string + - "null" + name: + type: + - string + - "null" + price: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + currency: + type: + - string + - "null" + formatted: + type: + - string + - "null" + productType: + type: + - string + - "null" + quantity: + type: + - number + - "null" + unit: + type: + - string + - "null" + required: + - id + sources: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + href: + type: + - string + - "null" + id: + type: string + modifiedTime: + type: + - number + - "null" + name: + type: + - string + - "null" + sourceType: + type: + - number + - "null" + required: + - id + stages: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + activeAvatarUrl: + type: + - string + - "null" + completeAvatarUrl: + type: + - string + - "null" + id: + type: string + incompleteAvatarUrl: + type: + - string + - "null" + links: + type: + - object + - "null" + properties: + stageset: + type: + - string + - "null" + name: + type: + - string + - "null" + overdueAvatarUrl: + type: + - string + - "null" + position: + type: + - number + - "null" + required: + - id + pipelines: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + canAccess: + type: + - boolean + - "null" + default: + type: + - boolean + - "null" + id: + type: string + links: + type: + - object + - "null" + properties: + stages: + type: + - array + - "null" + items: + type: + - string + - "null" + name: + type: + - string + - "null" + required: + - id + tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + colorType: + type: + - string + - "null" + count: + type: + - number + - "null" + href: + type: + - string + - "null" + id: + type: string + modifiedTime: + type: + - number + - "null" + name: + type: + - string + - "null" + tagType: + type: + - string + - "null" + required: + - id + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + agentStatus: + type: + - string + - "null" + avatarUrl: + type: + - string + - "null" + canAccessEmailMarketing: + type: + - boolean + - "null" + emails: + type: + - array + - "null" + items: + type: + - string + - "null" + firstName: + type: + - string + - "null" + hasSetPassword: + type: + - boolean + - "null" + id: + type: string + initials: + type: + - string + - "null" + isAdministrator: + type: + - boolean + - "null" + isEnabled: + type: + - boolean + - "null" + isHiddenFromFilters: + type: + - boolean + - "null" + isViewingRestricted: + type: + - boolean + - "null" + links: + type: + - object + - "null" + properties: + teams: + type: + - array + - "null" + items: + type: + - string + - "null" + modifiedTime: + type: + - number + - "null" + name: + type: + - string + - "null" + permissions: + type: + - object + - "null" + properties: + canAccessBilling: + type: + - boolean + - "null" + canAccessCrm: + type: + - boolean + - "null" + canAccessFullCampaigns: + type: + - boolean + - "null" + canAccessMarketing: + type: + - boolean + - "null" + canAccessSetup: + type: + - boolean + - "null" + canAssignEntities: + type: + - boolean + - "null" + canBulkEdit: + type: + - boolean + - "null" + canDeleteEntities: + type: + - boolean + - "null" + canExport: + type: + - boolean + - "null" + canImport: + type: + - boolean + - "null" + canManageEmailTemplates: + type: + - boolean + - "null" + canMergeEntities: + type: + - boolean + - "null" + canUseInbox: + type: + - boolean + - "null" + canUseOrTryInbox: + type: + - boolean + - "null" + canUsePeopleIQ: + type: + - boolean + - "null" + canViewSharedEmails: + type: + - boolean + - "null" + phonecallerType: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-nutshell/metadata.yaml b/airbyte-integrations/connectors/source-nutshell/metadata.yaml new file mode 100644 index 000000000000..efedbd1203e3 --- /dev/null +++ b/airbyte-integrations/connectors/source-nutshell/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "app.nutshell.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-nutshell + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 8ac02323-03a3-4026-96f0-68573237c49a + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-nutshell + githubIssueLabel: source-nutshell + icon: icon.svg + license: MIT + name: Nutshell + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/nutshell + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-nylas/metadata.yaml b/airbyte-integrations/connectors/source-nylas/metadata.yaml index e956b9eb948c..8890783ff15d 100644 --- a/airbyte-integrations/connectors/source-nylas/metadata.yaml +++ b/airbyte-integrations/connectors/source-nylas/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-nylas connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 136a1ee6-5b95-4e09-9f3f-5c8df35df690 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-nylas githubIssueLabel: source-nylas icon: icon.svg diff --git a/airbyte-integrations/connectors/source-nytimes/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-nytimes/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-nytimes/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-nytimes/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-okta/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-okta/integration_tests/acceptance.py index 6f2ccc74201a..6541b9a7db2c 100644 --- a/airbyte-integrations/connectors/source-okta/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-okta/integration_tests/acceptance.py @@ -4,6 +4,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-okta/main.py b/airbyte-integrations/connectors/source-okta/main.py index 7b372b3507e7..dabf89ea556f 100644 --- a/airbyte-integrations/connectors/source-okta/main.py +++ b/airbyte-integrations/connectors/source-okta/main.py @@ -4,5 +4,6 @@ from source_okta.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-okta/metadata.yaml b/airbyte-integrations/connectors/source-okta/metadata.yaml index 73ec5fa8045b..7c5094643b7c 100644 --- a/airbyte-integrations/connectors/source-okta/metadata.yaml +++ b/airbyte-integrations/connectors/source-okta/metadata.yaml @@ -15,11 +15,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 1d4fdb25-64fc-4569-92da-fcdca79a8372 - dockerImageTag: 0.3.10 + dockerImageTag: 0.3.16 dockerRepository: airbyte/source-okta githubIssueLabel: source-okta icon: icon.svg diff --git a/airbyte-integrations/connectors/source-okta/poetry.lock b/airbyte-integrations/connectors/source-okta/poetry.lock index 17e1b3f16e04..89b859d085b4 100644 --- a/airbyte-integrations/connectors/source-okta/poetry.lock +++ b/airbyte-integrations/connectors/source-okta/poetry.lock @@ -42,13 +42,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] @@ -56,24 +56,24 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -88,19 +88,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -166,13 +166,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -256,116 +256,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -435,20 +422,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -498,13 +485,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -519,13 +506,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -533,7 +520,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -583,13 +569,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -679,22 +665,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -767,69 +756,86 @@ files = [ [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -932,54 +938,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -991,13 +997,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1285,33 +1291,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1378,13 +1384,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1409,81 +1415,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-okta/pyproject.toml b/airbyte-integrations/connectors/source-okta/pyproject.toml index de6af65e7afc..b5369d163516 100644 --- a/airbyte-integrations/connectors/source-okta/pyproject.toml +++ b/airbyte-integrations/connectors/source-okta/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.3.10" +version = "0.3.16" name = "source-okta" description = "Source implementation for okta." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-okta/source_okta/components.py b/airbyte-integrations/connectors/source-okta/source_okta/components.py index bfe858878197..1f95fcaba7ad 100644 --- a/airbyte-integrations/connectors/source-okta/source_okta/components.py +++ b/airbyte-integrations/connectors/source-okta/source_okta/components.py @@ -9,6 +9,7 @@ import jwt import requests + from airbyte_cdk.sources.declarative.auth import DeclarativeOauth2Authenticator from airbyte_cdk.sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator from airbyte_cdk.sources.declarative.types import Config diff --git a/airbyte-integrations/connectors/source-okta/source_okta/config_migration.py b/airbyte-integrations/connectors/source-okta/source_okta/config_migration.py index 82fcef527e4b..eb7e58a41d68 100644 --- a/airbyte-integrations/connectors/source-okta/source_okta/config_migration.py +++ b/airbyte-integrations/connectors/source-okta/source_okta/config_migration.py @@ -11,6 +11,7 @@ from airbyte_cdk.sources import Source from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-okta/source_okta/source.py b/airbyte-integrations/connectors/source-okta/source_okta/source.py index b550116424cc..ed2e1e6ebc47 100644 --- a/airbyte-integrations/connectors/source-okta/source_okta/source.py +++ b/airbyte-integrations/connectors/source-okta/source_okta/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-okta/unit_tests/test_migration.py b/airbyte-integrations/connectors/source-okta/unit_tests/test_migration.py index 0211ef7e482f..9cf815ff3dda 100644 --- a/airbyte-integrations/connectors/source-okta/unit_tests/test_migration.py +++ b/airbyte-integrations/connectors/source-okta/unit_tests/test_migration.py @@ -5,11 +5,13 @@ import json from typing import Any, Mapping -from airbyte_cdk.models import OrchestratorType, Type -from airbyte_cdk.sources import Source from source_okta.config_migration import OktaConfigMigration from source_okta.source import SourceOkta +from airbyte_cdk.models import OrchestratorType, Type +from airbyte_cdk.sources import Source + + CMD = "check" SOURCE: Source = SourceOkta() diff --git a/airbyte-integrations/connectors/source-okta/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-okta/unit_tests/test_streams.py index 546e50c59041..9b880749910f 100644 --- a/airbyte-integrations/connectors/source-okta/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-okta/unit_tests/test_streams.py @@ -9,10 +9,11 @@ import pytest import requests -from airbyte_cdk.sources.streams import Stream from source_okta.components import CustomBearerAuthenticator, CustomOauth2Authenticator from source_okta.source import SourceOkta +from airbyte_cdk.sources.streams import Stream + def get_stream_by_name(stream_name: str, config: Mapping[str, Any]) -> Stream: source = SourceOkta() diff --git a/airbyte-integrations/connectors/source-omnisend/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-omnisend/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-omnisend/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-omnisend/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-omnisend/metadata.yaml b/airbyte-integrations/connectors/source-omnisend/metadata.yaml index 67f1438ada1a..06efe0f819b4 100644 --- a/airbyte-integrations/connectors/source-omnisend/metadata.yaml +++ b/airbyte-integrations/connectors/source-omnisend/metadata.yaml @@ -12,11 +12,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: e7f0c5e2-4815-48c4-90cf-f47124209835 - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.5 dockerRepository: airbyte/source-omnisend githubIssueLabel: source-omnisend icon: omnisend.svg diff --git a/airbyte-integrations/connectors/source-oncehub/README.md b/airbyte-integrations/connectors/source-oncehub/README.md new file mode 100644 index 000000000000..5709a7ec60f8 --- /dev/null +++ b/airbyte-integrations/connectors/source-oncehub/README.md @@ -0,0 +1,38 @@ +# Oncehub +This directory contains the manifest-only connector for `source-oncehub`. + +This is the Oncehub source that ingests data from the Oncehub API. + +Oncehub is a no-code conversational journeys builder, integrating AI, chatbots, live chat, instant calls, and scheduled meetings https://oncehub.com/. + +To use this source you must first create an account. Once logged in head over to Settings -> API & Webhooks and copy your API Key. +You can learn more about the API here https://developers.oncehub.com/reference/introduction + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-oncehub:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-oncehub build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-oncehub test +``` + diff --git a/airbyte-integrations/connectors/source-oncehub/acceptance-test-config.yml b/airbyte-integrations/connectors/source-oncehub/acceptance-test-config.yml new file mode 100644 index 000000000000..53c258e680d2 --- /dev/null +++ b/airbyte-integrations/connectors/source-oncehub/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-oncehub:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-oncehub/icon.svg b/airbyte-integrations/connectors/source-oncehub/icon.svg new file mode 100644 index 000000000000..8dfe04d9338e --- /dev/null +++ b/airbyte-integrations/connectors/source-oncehub/icon.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-oncehub/manifest.yaml b/airbyte-integrations/connectors/source-oncehub/manifest.yaml new file mode 100644 index 000000000000..8ae71503bf25 --- /dev/null +++ b/airbyte-integrations/connectors/source-oncehub/manifest.yaml @@ -0,0 +1,706 @@ +version: 5.17.0 + +type: DeclarativeSource + +description: >- + This is the Oncehub source that ingests data from the Oncehub API. + + + Oncehub is a no-code conversational journeys builder, integrating AI, + chatbots, live chat, instant calls, and scheduled meetings + https://oncehub.com/. + + + To use this source you must first create an account. Once logged in head over + to Settings -> API & Webhooks and copy your API Key. + + You can learn more about the API here + https://developers.oncehub.com/reference/introduction + +check: + type: CheckStream + stream_names: + - bookings + +definitions: + streams: + bookings: + type: DeclarativeStream + name: bookings + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/bookings + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not \"next\" in headers.get('Link') }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: last_updated_time + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%fZ" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: last_updated_time.gt + inject_into: request_parameter + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/bookings" + booking_pages: + type: DeclarativeStream + name: booking_pages + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/booking-pages + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not \"next\" in headers.get('Link') }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/booking_pages" + event_types: + type: DeclarativeStream + name: event_types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/event-types + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not \"next\" in headers.get('Link') }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/event_types" + master_pages: + type: DeclarativeStream + name: master_pages + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/master-pages + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not \"next\" in headers.get('Link') }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/master_pages" + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not \"next\" in headers.get('Link') }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + teams: + type: DeclarativeStream + name: teams + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/teams + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not \"next\" in headers.get('Link') }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/teams" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not \"next\" in headers.get('Link') }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + base_requester: + type: HttpRequester + url_base: https://api.oncehub.com + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: API-Key + inject_into: header + +streams: + - $ref: "#/definitions/streams/bookings" + - $ref: "#/definitions/streams/booking_pages" + - $ref: "#/definitions/streams/event_types" + - $ref: "#/definitions/streams/master_pages" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/teams" + - $ref: "#/definitions/streams/contacts" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - start_date + properties: + api_key: + type: string + description: >- + API key to use. Find it in your OnceHub account under the API & + Webhooks Integration page. + name: api_key + order: 0 + title: API Key + airbyte_secret: true + start_date: + type: string + order: 1 + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + additionalProperties: true + +metadata: + autoImportSchema: + bookings: true + booking_pages: true + event_types: true + master_pages: true + users: true + teams: true + contacts: true + testedStreams: + bookings: + streamHash: b4534fe52430a16dd1749313c416c3aae3afa1fd + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + booking_pages: + streamHash: a5a0c1642c867aa24c640bd35cfe09e4dd7208da + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + event_types: + streamHash: 6915cf4ab58a9e3d09d7207939c6503c7d7ad93b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + master_pages: + streamHash: ee2a4a22dff22bcb7cacff32ac8568e4a02855d6 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + users: + streamHash: 69a6491af772e323c874c16583464f4a0d410fe1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + teams: + hasRecords: true + streamHash: 731b8cb9bc9b1d0465c1f22c09baf2ef5d851fc0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + contacts: + hasRecords: true + streamHash: 2681d6726d862fae187bbd97b96efebe52ea2856 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://developers.oncehub.com/docs/introduction-to-the-scheduleonce-api + +schemas: + bookings: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attendees: + type: + - array + - "null" + items: + type: + - string + - "null" + booking_page: + type: + - string + - "null" + contact: + type: + - string + - "null" + creation_time: + type: + - string + - "null" + customer_timezone: + type: + - string + - "null" + duration_minutes: + type: + - number + - "null" + event_type: + type: + - string + - "null" + external_calendar: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + event_id: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + form_submission: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + guests: + type: + - array + - "null" + mobile_phone: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: string + in_trash: + type: + - boolean + - "null" + last_updated_time: + type: string + location_description: + type: + - string + - "null" + object: + type: + - string + - "null" + owner: + type: + - string + - "null" + starting_time: + type: + - string + - "null" + status: + type: + - string + - "null" + subject: + type: + - string + - "null" + tracking_id: + type: + - string + - "null" + virtual_conferencing: + type: + - object + - "null" + properties: + join_url: + type: + - string + - "null" + required: + - id + - last_updated_time + booking_pages: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active: + type: + - boolean + - "null" + id: + type: string + label: + type: + - string + - "null" + name: + type: + - string + - "null" + object: + type: + - string + - "null" + timezone: + type: + - string + - "null" + url: + type: + - string + - "null" + required: + - id + event_types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: string + label: + type: + - string + - "null" + name: + type: + - string + - "null" + object: + type: + - string + - "null" + required: + - id + master_pages: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active: + type: + - boolean + - "null" + id: + type: string + label: + type: + - string + - "null" + name: + type: + - string + - "null" + object: + type: + - string + - "null" + url: + type: + - string + - "null" + required: + - id + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + id: + type: string + last_name: + type: + - string + - "null" + object: + type: + - string + - "null" + role_name: + type: + - string + - "null" + status: + type: + - string + - "null" + required: + - id + teams: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: string + name: + type: + - string + - "null" + object: + type: + - string + - "null" + required: + - id + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + creation_time: + type: + - string + - "null" + custom_fields: + type: + - array + - "null" + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + id: + type: string + last_updated_time: + type: + - string + - "null" + mobile_phone: + type: + - string + - "null" + object: + type: + - string + - "null" + owner: + type: + - string + - "null" + timezone: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-oncehub/metadata.yaml b/airbyte-integrations/connectors/source-oncehub/metadata.yaml new file mode 100644 index 000000000000..aa40e9959c04 --- /dev/null +++ b/airbyte-integrations/connectors/source-oncehub/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.oncehub.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-oncehub + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 4f200d9c-08a6-4e8f-9391-ea303a5d0e4d + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-oncehub + githubIssueLabel: source-oncehub + icon: icon.svg + license: MIT + name: Oncehub + releaseDate: 2024-10-30 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/oncehub + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-onepagecrm/README.md b/airbyte-integrations/connectors/source-onepagecrm/README.md new file mode 100644 index 000000000000..16bb86d5de09 --- /dev/null +++ b/airbyte-integrations/connectors/source-onepagecrm/README.md @@ -0,0 +1,35 @@ +# Onepagecrm +This directory contains the manifest-only connector for `source-onepagecrm`. + +Onepagecrm is a CRM solution for small busineeses. +Using this stream we can extarct data from various streams such as contacts , deals , pipelines and meetings +Docs : https://developer.onepagecrm.com/api/ + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-onepagecrm:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-onepagecrm build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-onepagecrm test +``` + diff --git a/airbyte-integrations/connectors/source-onepagecrm/acceptance-test-config.yml b/airbyte-integrations/connectors/source-onepagecrm/acceptance-test-config.yml new file mode 100644 index 000000000000..807e4d4d87b2 --- /dev/null +++ b/airbyte-integrations/connectors/source-onepagecrm/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-onepagecrm:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-onepagecrm/icon.svg b/airbyte-integrations/connectors/source-onepagecrm/icon.svg new file mode 100644 index 000000000000..7fc1db25f437 --- /dev/null +++ b/airbyte-integrations/connectors/source-onepagecrm/icon.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-onepagecrm/manifest.yaml b/airbyte-integrations/connectors/source-onepagecrm/manifest.yaml new file mode 100644 index 000000000000..717108982fda --- /dev/null +++ b/airbyte-integrations/connectors/source-onepagecrm/manifest.yaml @@ -0,0 +1,3456 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Onepagecrm is a CRM solution for small busineeses. + + Using this stream we can extarct data from various streams such as contacts , + deals , pipelines and meetings + + Docs : https://developer.onepagecrm.com/api/ + +check: + type: CheckStream + stream_names: + - contacts + +definitions: + streams: + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - contacts + - "*" + - contact + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - "*" + - user + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + bootstrap: + type: DeclarativeStream + name: bootstrap + primary_key: + - user_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: bootstrap + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/bootstrap" + companies: + type: DeclarativeStream + name: companies + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: companies + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - companies + - "*" + - company + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/companies" + actions: + type: DeclarativeStream + name: actions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: actions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - actions + - "*" + - action + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/actions" + action_stream: + type: DeclarativeStream + name: action_stream + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: action_stream + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - contacts + - "*" + - contact + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/action_stream" + team_stream: + type: DeclarativeStream + name: team_stream + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: team_stream + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - contacts + - "*" + - contact + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/team_stream" + deals: + type: DeclarativeStream + name: deals + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: deals + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - deals + - "*" + - deal + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/deals" + notes: + type: DeclarativeStream + name: notes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: notes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - notes + - "*" + - note + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/notes" + relationship_types: + type: DeclarativeStream + name: relationship_types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: relationship_types + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - relationship_types + - "*" + - relationship_type + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/relationship_types" + pipelines: + type: DeclarativeStream + name: pipelines + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pipelines + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - pipelines + - "*" + - pipeline + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/pipelines" + statuses: + type: DeclarativeStream + name: statuses + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: statuses + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - "*" + - status + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/statuses" + lead_sources: + type: DeclarativeStream + name: lead_sources + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: lead_sources + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/lead_sources" + filters: + type: DeclarativeStream + name: filters + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: filters + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - filters + - "*" + - filter + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/filters" + predefined_actions: + type: DeclarativeStream + name: predefined_actions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: predefined_actions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - predefined_actions + - "*" + - predefined_action + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/predefined_actions" + predefined_items: + type: DeclarativeStream + name: predefined_items + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: predefined_items + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - predefined_items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/predefined_items" + custom_fields: + type: DeclarativeStream + name: custom_fields + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: custom_fields + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - custom_fields + - "*" + - custom_field + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/custom_fields" + calls: + type: DeclarativeStream + name: calls + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: calls + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - calls + - "*" + - call + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/calls" + meetings: + type: DeclarativeStream + name: meetings + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: meetings + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - meetings + - "*" + - meeting + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/meetings" + base_requester: + type: HttpRequester + url_base: https://app.onepagecrm.com/api/v3/ + authenticator: + type: BasicHttpAuthenticator + password: "{{ config[\"password\"] }}" + username: "{{ config[\"username\"] }}" + +streams: + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/bootstrap" + - $ref: "#/definitions/streams/companies" + - $ref: "#/definitions/streams/actions" + - $ref: "#/definitions/streams/action_stream" + - $ref: "#/definitions/streams/team_stream" + - $ref: "#/definitions/streams/deals" + - $ref: "#/definitions/streams/notes" + - $ref: "#/definitions/streams/relationship_types" + - $ref: "#/definitions/streams/pipelines" + - $ref: "#/definitions/streams/statuses" + - $ref: "#/definitions/streams/lead_sources" + - $ref: "#/definitions/streams/filters" + - $ref: "#/definitions/streams/predefined_actions" + - $ref: "#/definitions/streams/predefined_items" + - $ref: "#/definitions/streams/custom_fields" + - $ref: "#/definitions/streams/calls" + - $ref: "#/definitions/streams/meetings" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - username + properties: + username: + type: string + description: Enter the user ID of your API app + order: 0 + title: Username + password: + type: string + description: Enter your API Key of your API app + order: 1 + title: Password + always_show: true + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + contacts: true + users: true + bootstrap: true + companies: true + actions: true + action_stream: true + team_stream: true + deals: true + notes: true + relationship_types: true + pipelines: true + statuses: true + lead_sources: true + filters: true + predefined_actions: true + predefined_items: true + custom_fields: true + calls: true + meetings: true + testedStreams: + contacts: + streamHash: 06ce92bcf6d640369df5eaf8da3ef346abf2d64e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + users: + streamHash: 22003c3855db928ae3f867eb7f28fc94a8a6525d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + bootstrap: + streamHash: fc6dd707cd79cf754316e18c1d340d1c2e1f021d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + companies: + streamHash: 7312a2a979698dbbfb0686984760edf3795bcb84 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + actions: + streamHash: 64f7c9c02fc042a6b0643370f11b2d87ec1ebfc6 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + action_stream: + streamHash: ceecc67cb97e8167c9d89afffe004554d67f5359 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + team_stream: + streamHash: 1cd192c8d4f707e3b038e669eb591a1a5ec00209 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + deals: + streamHash: bc7f9772f5687078b8781913a103217c076d695d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + notes: + streamHash: a4bb26f23939d0d65f8d6873e888d31234273a12 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + relationship_types: + streamHash: e6b42d0d6fcbb51b53a8eb83fbdec5aa4fc94219 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + pipelines: + streamHash: 20bb29598673e65aa51983595285d23be9162fd1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + statuses: + streamHash: c95e4f28ee436dd7dd585dac4642648b9684b1d6 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + lead_sources: + streamHash: b48a41a79686b71164d8b9e89288f49e8eb38e6f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + filters: + streamHash: 4d212113b76a91e37a36d29b0bb85a1e81474865 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + predefined_actions: + streamHash: 732b1dc7a6784428916470b67feb9bdb7b8dfbd4 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + predefined_items: + streamHash: 552609f0a4cfaa6f29c599ce6ebc048d500164eb + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + custom_fields: + streamHash: 409703f19317a646c520d9a8ec3a59a68aac16e5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + calls: + streamHash: b74fae76c231a845ce35a39e0bad1cfc894dfde7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + meetings: + streamHash: f394ab61c4daf7bec64b718c2f10b6f949aefeea + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address_list: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country_code: + type: + - string + - "null" + state: + type: + - string + - "null" + zip_code: + type: + - string + - "null" + background: + type: + - string + - "null" + closed_sales: + type: + - array + - "null" + company_id: + type: + - string + - "null" + company_name: + type: + - string + - "null" + company_size: + type: + - number + - "null" + created_at: + type: + - string + - "null" + custom_fields: + type: + - array + - "null" + email_sync_available: + type: + - boolean + - "null" + email_sync_enabled: + type: + - boolean + - "null" + emails: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - string + - "null" + enhanceable: + type: + - boolean + - "null" + first_name: + type: + - string + - "null" + id: + type: string + job_title: + type: + - string + - "null" + last_name: + type: + - string + - "null" + lead_source: + type: + - string + - "null" + lead_source_id: + type: + - string + - "null" + letter: + type: + - string + - "null" + modified_at: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + pending_deal: + type: + - boolean + - "null" + phones: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - string + - "null" + photo_url: + type: + - string + - "null" + sales_closed_for: + type: + - array + - "null" + starred: + type: + - boolean + - "null" + status: + type: + - string + - "null" + status_id: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - string + - "null" + total_deals_count: + type: + - number + - "null" + total_pendings: + type: + - number + - "null" + urls: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - string + - "null" + required: + - id + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account_rights: + type: + - array + - "null" + items: + type: + - string + - "null" + account_role: + type: + - string + - "null" + bcc_email: + type: + - string + - "null" + company_name: + type: + - string + - "null" + country_code: + type: + - string + - "null" + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + id: + type: string + last_name: + type: + - string + - "null" + photo_url: + type: + - string + - "null" + virtual_group_id: + type: + - string + - "null" + required: + - id + bootstrap: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account_type: + type: + - string + - "null" + auth_key: + type: + - string + - "null" + call_results: + type: + - object + - "null" + properties: + interested: + type: + - string + - "null" + left_message: + type: + - string + - "null" + no_answer: + type: + - string + - "null" + not_interested: + type: + - string + - "null" + other: + type: + - string + - "null" + call_results_order: + type: + - array + - "null" + items: + type: + - string + - "null" + company_fields: + type: + - array + - "null" + cost_setup: + type: + - object + - "null" + properties: + commission_base: + type: + - string + - "null" + commission_percentage: + type: + - number + - "null" + cost_enabled: + type: + - boolean + - "null" + cost_required: + type: + - boolean + - "null" + current_card_scans_number: + type: + - number + - "null" + custom_fields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + custom_field: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + mandatory: + type: + - boolean + - "null" + name: + type: + - string + - "null" + position: + type: + - number + - "null" + reminder_days: + type: + - number + - "null" + deal_fields: + type: + - array + - "null" + filters: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + filter: + type: + - object + - "null" + properties: + conditions: + type: + - array + - "null" + items: + type: + - array + - "null" + items: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + max_card_scans_limit: + type: + - number + - "null" + next_action_dates: + type: + - array + - "null" + predefined_action_groups: + type: + - array + - "null" + predefined_actions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + predefined_action: + type: + - object + - "null" + properties: + action_group_id: + type: + - string + - "null" + days: + type: + - number + - "null" + id: + type: + - string + - "null" + position: + type: + - number + - "null" + text: + type: + - string + - "null" + reason_losts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + position: + type: + - number + - "null" + settings: + type: + - object + - "null" + properties: + bcc_email_enabled: + type: + - boolean + - "null" + company_address_enabled: + type: + - boolean + - "null" + company_description_enabled: + type: + - boolean + - "null" + company_phone_enabled: + type: + - boolean + - "null" + company_url_enabled: + type: + - boolean + - "null" + contact_attributes_default_types: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + email: + type: + - string + - "null" + phone: + type: + - string + - "null" + url: + type: + - string + - "null" + currency: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + date_format: + type: + - string + - "null" + deal_stages: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + stage: + type: + - number + - "null" + default_contact_type: + type: + - string + - "null" + delimiter: + type: + - string + - "null" + listing_size: + type: + - number + - "null" + not_working_days: + type: + - string + - "null" + pipelines: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + pipeline: + type: + - object + - "null" + properties: + default: + type: + - boolean + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + stages: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + stage: + type: + - number + - "null" + won_column_enabled: + type: + - boolean + - "null" + won_column_name: + type: + - string + - "null" + popular_countries: + type: + - array + - "null" + items: + type: + - string + - "null" + reason_lost_enabled: + type: + - boolean + - "null" + reminder: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + hour: + type: + - number + - "null" + send_push_notifications: + type: + - boolean + - "null" + separator: + type: + - string + - "null" + show_company_fields_with_contact: + type: + - boolean + - "null" + show_deals_and_pipeline: + type: + - boolean + - "null" + show_tidy_stream: + type: + - boolean + - "null" + time_with_ampm: + type: + - boolean + - "null" + time_zone: + type: + - string + - "null" + virtual_groups_enabled: + type: + - boolean + - "null" + subscription_plan: + type: + - object + - "null" + properties: + display_name: + type: + - string + - "null" + name: + type: + - string + - "null" + team: + type: + - array + - "null" + user: + type: + - object + - "null" + properties: + user: + type: + - object + - "null" + properties: + account_rights: + type: + - array + - "null" + items: + type: + - string + - "null" + account_role: + type: + - string + - "null" + bcc_email: + type: + - string + - "null" + company_name: + type: + - string + - "null" + country_code: + type: + - string + - "null" + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + id: + type: + - string + - "null" + last_name: + type: + - string + - "null" + photo_url: + type: + - string + - "null" + virtual_group_id: + type: + - string + - "null" + user_id: + type: string + virtual_groups: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + default: + type: + - boolean + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + required: + - user_id + companies: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + address: + type: + - object + - "null" + properties: {} + company_fields: + type: + - array + - "null" + contacts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + contact: + type: + - object + - "null" + properties: + address_list: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country_code: + type: + - string + - "null" + state: + type: + - string + - "null" + zip_code: + type: + - string + - "null" + background: + type: + - string + - "null" + closed_sales: + type: + - array + - "null" + company_id: + type: + - string + - "null" + company_name: + type: + - string + - "null" + company_size: + type: + - number + - "null" + created_at: + type: + - string + - "null" + custom_fields: + type: + - array + - "null" + email_sync_available: + type: + - boolean + - "null" + email_sync_enabled: + type: + - boolean + - "null" + emails: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - string + - "null" + enhanceable: + type: + - boolean + - "null" + first_name: + type: + - string + - "null" + id: + type: + - string + - "null" + job_title: + type: + - string + - "null" + last_name: + type: + - string + - "null" + lead_source: + type: + - string + - "null" + lead_source_id: + type: + - string + - "null" + letter: + type: + - string + - "null" + modified_at: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + pending_deal: + type: + - boolean + - "null" + phones: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - string + - "null" + photo_url: + type: + - string + - "null" + sales_closed_for: + type: + - array + - "null" + starred: + type: + - boolean + - "null" + status: + type: + - string + - "null" + status_id: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - string + - "null" + total_deals_count: + type: + - number + - "null" + total_pendings: + type: + - number + - "null" + urls: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - string + - "null" + most_urgent_action: + type: + - object + - "null" + properties: + assignee_id: + type: + - string + - "null" + contact_id: + type: + - string + - "null" + created_at: + type: + - string + - "null" + date: + type: + - string + - "null" + done: + type: + - boolean + - "null" + id: + type: + - string + - "null" + modified_at: + type: + - string + - "null" + status: + type: + - string + - "null" + text: + type: + - string + - "null" + next_action: + type: + - object + - "null" + properties: + assignee_id: + type: + - string + - "null" + contact_id: + type: + - string + - "null" + created_at: + type: + - string + - "null" + date: + type: + - string + - "null" + done: + type: + - boolean + - "null" + id: + type: + - string + - "null" + modified_at: + type: + - string + - "null" + status: + type: + - string + - "null" + text: + type: + - string + - "null" + next_action_conflicts: + type: + - array + - "null" + next_actions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + assignee_id: + type: + - string + - "null" + contact_id: + type: + - string + - "null" + created_at: + type: + - string + - "null" + date: + type: + - string + - "null" + done: + type: + - boolean + - "null" + id: + type: + - string + - "null" + modified_at: + type: + - string + - "null" + status: + type: + - string + - "null" + text: + type: + - string + - "null" + queued_actions: + type: + - array + - "null" + contacts_count: + type: + - number + - "null" + created_at: + type: + - string + - "null" + id: + type: string + modified_at: + type: + - string + - "null" + name: + type: + - string + - "null" + pending_deals: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + deal: + type: + - object + - "null" + properties: + amount: + type: + - number + - "null" + attachments: + type: + - array + - "null" + author: + type: + - string + - "null" + commission: + type: + - number + - "null" + commission_base: + type: + - string + - "null" + commission_percentage: + type: + - number + - "null" + commission_type: + type: + - string + - "null" + contact_id: + type: + - string + - "null" + contact_info: + type: + - object + - "null" + properties: + company: + type: + - string + - "null" + contact_name: + type: + - string + - "null" + contact_owner_id: + type: + - string + - "null" + cost: + type: + - number + - "null" + created_at: + type: + - string + - "null" + date: + type: + - string + - "null" + deal_fields: + type: + - array + - "null" + deal_items: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + amount: + type: + - number + - "null" + cost: + type: + - number + - "null" + created_at: + type: + - string + - "null" + deal_id: + type: + - string + - "null" + id: + type: + - string + - "null" + modified_at: + type: + - string + - "null" + name: + type: + - string + - "null" + position: + type: + - number + - "null" + predefined_item_id: + type: + - string + - "null" + price: + type: + - number + - "null" + qty: + type: + - number + - "null" + expected_close_date: + type: + - string + - "null" + has_deal_items: + type: + - boolean + - "null" + has_related_notes: + type: + - boolean + - "null" + id: + type: + - string + - "null" + margin: + type: + - number + - "null" + modified_at: + type: + - string + - "null" + months: + type: + - number + - "null" + name: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + pipeline_id: + type: + - string + - "null" + stage: + type: + - number + - "null" + status: + type: + - string + - "null" + text: + type: + - string + - "null" + total_amount: + type: + - number + - "null" + total_cost: + type: + - number + - "null" + pending_deals_count: + type: + - number + - "null" + phone: + type: + - string + - "null" + syncing_status: + type: + - boolean + - "null" + syncing_tags: + type: + - boolean + - "null" + total_pending_amount: + type: + - number + - "null" + total_won_amount: + type: + - number + - "null" + url: + type: + - string + - "null" + won_deals_count: + type: + - number + - "null" + required: + - id + actions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + assignee_id: + type: + - string + - "null" + contact_id: + type: + - string + - "null" + created_at: + type: + - string + - "null" + date: + type: + - string + - "null" + done: + type: + - boolean + - "null" + done_at: + type: + - string + - "null" + id: + type: string + modified_at: + type: + - string + - "null" + status: + type: + - string + - "null" + text: + type: + - string + - "null" + required: + - id + action_stream: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address_list: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country_code: + type: + - string + - "null" + state: + type: + - string + - "null" + zip_code: + type: + - string + - "null" + background: + type: + - string + - "null" + closed_sales: + type: + - array + - "null" + company_id: + type: + - string + - "null" + company_name: + type: + - string + - "null" + company_size: + type: + - number + - "null" + created_at: + type: + - string + - "null" + custom_fields: + type: + - array + - "null" + email_sync_available: + type: + - boolean + - "null" + email_sync_enabled: + type: + - boolean + - "null" + emails: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - string + - "null" + enhanceable: + type: + - boolean + - "null" + first_name: + type: + - string + - "null" + id: + type: + - string + - "null" + job_title: + type: + - string + - "null" + last_name: + type: + - string + - "null" + lead_source: + type: + - string + - "null" + lead_source_id: + type: + - string + - "null" + letter: + type: + - string + - "null" + modified_at: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + pending_deal: + type: + - boolean + - "null" + phones: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - string + - "null" + photo_url: + type: + - string + - "null" + sales_closed_for: + type: + - array + - "null" + starred: + type: + - boolean + - "null" + status: + type: + - string + - "null" + status_id: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - string + - "null" + total_deals_count: + type: + - number + - "null" + total_pendings: + type: + - number + - "null" + urls: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - string + - "null" + team_stream: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address_list: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country_code: + type: + - string + - "null" + state: + type: + - string + - "null" + zip_code: + type: + - string + - "null" + background: + type: + - string + - "null" + closed_sales: + type: + - array + - "null" + company_id: + type: + - string + - "null" + company_name: + type: + - string + - "null" + company_size: + type: + - number + - "null" + created_at: + type: + - string + - "null" + custom_fields: + type: + - array + - "null" + email_sync_available: + type: + - boolean + - "null" + email_sync_enabled: + type: + - boolean + - "null" + emails: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - string + - "null" + enhanceable: + type: + - boolean + - "null" + first_name: + type: + - string + - "null" + id: + type: + - string + - "null" + job_title: + type: + - string + - "null" + last_name: + type: + - string + - "null" + lead_source: + type: + - string + - "null" + lead_source_id: + type: + - string + - "null" + letter: + type: + - string + - "null" + modified_at: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + pending_deal: + type: + - boolean + - "null" + phones: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - string + - "null" + photo_url: + type: + - string + - "null" + sales_closed_for: + type: + - array + - "null" + starred: + type: + - boolean + - "null" + status: + type: + - string + - "null" + status_id: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - string + - "null" + total_deals_count: + type: + - number + - "null" + total_pendings: + type: + - number + - "null" + urls: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - string + - "null" + deals: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + amount: + type: + - number + - "null" + attachments: + type: + - array + - "null" + author: + type: + - string + - "null" + close_date: + type: + - string + - "null" + commission: + type: + - number + - "null" + commission_base: + type: + - string + - "null" + commission_percentage: + type: + - number + - "null" + commission_type: + type: + - string + - "null" + contact_id: + type: + - string + - "null" + contact_info: + type: + - object + - "null" + properties: + company: + type: + - string + - "null" + contact_name: + type: + - string + - "null" + contact_owner_id: + type: + - string + - "null" + cost: + type: + - number + - "null" + created_at: + type: + - string + - "null" + date: + type: + - string + - "null" + deal_fields: + type: + - array + - "null" + deal_items: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + amount: + type: + - number + - "null" + cost: + type: + - number + - "null" + created_at: + type: + - string + - "null" + deal_id: + type: + - string + - "null" + id: + type: + - string + - "null" + modified_at: + type: + - string + - "null" + name: + type: + - string + - "null" + position: + type: + - number + - "null" + predefined_item_id: + type: + - string + - "null" + price: + type: + - number + - "null" + qty: + type: + - number + - "null" + expected_close_date: + type: + - string + - "null" + has_deal_items: + type: + - boolean + - "null" + has_related_notes: + type: + - boolean + - "null" + id: + type: string + margin: + type: + - number + - "null" + modified_at: + type: + - string + - "null" + months: + type: + - number + - "null" + name: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + pipeline_id: + type: + - string + - "null" + stage: + type: + - number + - "null" + status: + type: + - string + - "null" + text: + type: + - string + - "null" + total_amount: + type: + - number + - "null" + total_cost: + type: + - number + - "null" + required: + - id + notes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attachments: + type: + - array + - "null" + author: + type: + - string + - "null" + contact_id: + type: + - string + - "null" + created_at: + type: + - string + - "null" + date: + type: + - string + - "null" + id: + type: string + linked_deal_id: + type: + - string + - "null" + linked_deal_name: + type: + - string + - "null" + modified_at: + type: + - string + - "null" + text: + type: + - string + - "null" + required: + - id + relationship_types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + id: + type: string + modified_at: + type: + - string + - "null" + relationship_variants: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + symmetrical: + type: + - boolean + - "null" + required: + - id + pipelines: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + default: + type: + - boolean + - "null" + id: + type: string + name: + type: + - string + - "null" + stages: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + stage: + type: + - number + - "null" + won_column_enabled: + type: + - boolean + - "null" + won_column_name: + type: + - string + - "null" + required: + - id + statuses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + action_stream_count: + type: + - number + - "null" + color: + type: + - string + - "null" + counts: + type: + - number + - "null" + id: + type: string + status: + type: + - string + - "null" + team_counts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + counts: + type: + - number + - "null" + user_id: + type: + - string + - "null" + text: + type: + - string + - "null" + total_count: + type: + - number + - "null" + required: + - id + lead_sources: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + action_stream_count: + type: + - number + - "null" + counts: + type: + - number + - "null" + id: + type: string + team_counts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + counts: + type: + - number + - "null" + user_id: + type: + - string + - "null" + text: + type: + - string + - "null" + total_count: + type: + - number + - "null" + required: + - id + filters: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + conditions: + type: + - array + - "null" + items: + type: + - array + - "null" + items: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + required: + - id + predefined_actions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + action_group_id: + type: + - string + - "null" + days: + type: + - number + - "null" + id: + type: string + position: + type: + - number + - "null" + text: + type: + - string + - "null" + required: + - id + predefined_items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + cost: + type: + - number + - "null" + id: + type: string + name: + type: + - string + - "null" + price: + type: + - number + - "null" + required: + - id + custom_fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + id: + type: string + mandatory: + type: + - boolean + - "null" + name: + type: + - string + - "null" + position: + type: + - number + - "null" + reminder_days: + type: + - number + - "null" + required: + - id + calls: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attachments: + type: + - array + - "null" + author: + type: + - string + - "null" + call_result: + type: + - string + - "null" + call_time_int: + type: + - number + - "null" + contact_id: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: string + index: + type: + - number + - "null" + modified_at: + type: + - string + - "null" + phone_number: + type: + - string + - "null" + recording_link: + type: + - string + - "null" + text: + type: + - string + - "null" + via: + type: + - string + - "null" + required: + - id + meetings: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attachments: + type: + - array + - "null" + author: + type: + - string + - "null" + contact_id: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: string + index: + type: + - number + - "null" + meeting_time_int: + type: + - number + - "null" + modified_at: + type: + - string + - "null" + place: + type: + - string + - "null" + text: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-onepagecrm/metadata.yaml b/airbyte-integrations/connectors/source-onepagecrm/metadata.yaml new file mode 100644 index 000000000000..d96256da2dae --- /dev/null +++ b/airbyte-integrations/connectors/source-onepagecrm/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "app.onepagecrm.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-onepagecrm + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: d59cce29-baa8-4202-b1ca-a4759c20c908 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-onepagecrm + githubIssueLabel: source-onepagecrm + icon: icon.svg + license: MIT + name: Onepagecrm + releaseDate: 2024-11-09 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/onepagecrm + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-onesignal/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-onesignal/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-onesignal/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-onesignal/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-onesignal/metadata.yaml b/airbyte-integrations/connectors/source-onesignal/metadata.yaml index 72cb7a2fd6a1..d85641118c7d 100644 --- a/airbyte-integrations/connectors/source-onesignal/metadata.yaml +++ b/airbyte-integrations/connectors/source-onesignal/metadata.yaml @@ -3,7 +3,7 @@ data: hosts: - onesignal.com connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorTestSuitesOptions: - suite: liveTests @@ -19,7 +19,7 @@ data: type: GSM connectorType: source definitionId: bb6afd81-87d5-47e3-97c4-e2c2901b1cf8 - dockerImageTag: 1.2.1 + dockerImageTag: 1.2.6 dockerRepository: airbyte/source-onesignal documentationUrl: https://docs.airbyte.com/integrations/sources/onesignal githubIssueLabel: source-onesignal diff --git a/airbyte-integrations/connectors/source-onfleet/README.md b/airbyte-integrations/connectors/source-onfleet/README.md new file mode 100644 index 000000000000..36a39206e30d --- /dev/null +++ b/airbyte-integrations/connectors/source-onfleet/README.md @@ -0,0 +1,39 @@ +# Onfleet +This directory contains the manifest-only connector for `source-onfleet`. + +This is the Onfleet connector that ingests data from the Onfleet API. + +Onfleet is the world's advanced logistics software that delights customers, scale operations, and boost efficiency https://onfleet.com/ + +In order to use this source you must first create an account on Onfleet. Once logged in, you can find the can create an API keys through the settings menu in the dashboard, by going into the API section. + +You can find more information about the API here https://docs.onfleet.com/reference/setup-tutorial + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-onfleet:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-onfleet build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-onfleet test +``` + diff --git a/airbyte-integrations/connectors/source-onfleet/acceptance-test-config.yml b/airbyte-integrations/connectors/source-onfleet/acceptance-test-config.yml new file mode 100644 index 000000000000..f77a7e15f95b --- /dev/null +++ b/airbyte-integrations/connectors/source-onfleet/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-onfleet:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-onfleet/icon.svg b/airbyte-integrations/connectors/source-onfleet/icon.svg new file mode 100644 index 000000000000..6a793049b3b9 --- /dev/null +++ b/airbyte-integrations/connectors/source-onfleet/icon.svg @@ -0,0 +1,43 @@ + + + + + + + diff --git a/airbyte-integrations/connectors/source-onfleet/manifest.yaml b/airbyte-integrations/connectors/source-onfleet/manifest.yaml new file mode 100644 index 000000000000..d6351444f8e6 --- /dev/null +++ b/airbyte-integrations/connectors/source-onfleet/manifest.yaml @@ -0,0 +1,827 @@ +version: 5.16.0 + +type: DeclarativeSource + +description: >- + This is the Onfleet connector that ingests data from the Onfleet API. + + + Onfleet is the world's advanced logistics software that delights customers, + scale operations, and boost efficiency https://onfleet.com/ + + + In order to use this source you must first create an account on Onfleet. Once + logged in, you can find the can create an API keys through the settings menu + in the dashboard, by going into the API section. + + + You can find more information about the API here + https://docs.onfleet.com/reference/setup-tutorial + +check: + type: CheckStream + stream_names: + - workers + +definitions: + streams: + workers: + type: DeclarativeStream + name: workers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/workers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/workers" + administrators: + type: DeclarativeStream + name: administrators + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/admins + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/administrators" + teams: + type: DeclarativeStream + name: teams + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/teams + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/teams" + hubs: + type: DeclarativeStream + name: hubs + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/hubs + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/hubs" + tasks: + type: DeclarativeStream + name: tasks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/tasks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: lastId + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('lastId') }}" + stop_condition: "{{ response.get('lastId') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tasks" + containers: + type: DeclarativeStream + name: containers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/containers/workers/{{ stream_slice.worker_id }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: worker_id + stream: + $ref: "#/definitions/streams/workers" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/containers" + base_requester: + type: HttpRequester + url_base: https://onfleet.com + authenticator: + type: BasicHttpAuthenticator + password: "{{ config[\"password\"] }}" + username: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/workers" + - $ref: "#/definitions/streams/administrators" + - $ref: "#/definitions/streams/teams" + - $ref: "#/definitions/streams/hubs" + - $ref: "#/definitions/streams/tasks" + - $ref: "#/definitions/streams/containers" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - password + properties: + api_key: + type: string + description: >- + API key to use for authenticating requests. You can create and manage + your API keys in the API section of the Onfleet dashboard. + name: api_key + order: 0 + title: API Key + airbyte_secret: true + password: + type: string + description: >- + Placeholder for basic HTTP auth password - should be set to empty + string + name: password + order: 1 + title: Placeholder Password + default: x + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + workers: true + administrators: false + teams: false + hubs: false + tasks: false + containers: true + testedStreams: + workers: + streamHash: 4e4085588a0a68d16ff464a0f06756f90ba1579c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + administrators: + streamHash: 86bf4b87b06b606bf5317cd75403626232cc338e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + teams: + streamHash: 5c5a6e8dfa1d1f93921563dbbe5c24179c4e3b54 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + hubs: + streamHash: 05fc33213f414d818d7100942eb057100bdcdbb5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tasks: + hasRecords: true + streamHash: e95fcb0a6846523fa0bd74c3aa979463ff7705f0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + containers: + streamHash: 2621785beff7dd4b16bc99cd0d2da1087166191c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://docs.onfleet.com/reference/setup-tutorial + +schemas: + workers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + metadata: + type: + - array + - "null" + accountStatus: + type: + - string + - "null" + additionalCapacities: + type: + - object + - "null" + properties: + capacityA: + type: + - number + - "null" + capacityB: + type: + - number + - "null" + capacityC: + type: + - number + - "null" + capacity: + type: + - number + - "null" + displayName: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + onDuty: + type: + - boolean + - "null" + organization: + type: + - string + - "null" + phone: + type: + - string + - "null" + tasks: + type: + - array + - "null" + teams: + type: + - array + - "null" + items: + type: + - string + - "null" + timeCreated: + type: + - number + - "null" + timeLastModified: + type: + - number + - "null" + userData: + type: + - object + - "null" + vehicle: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + timeCreated: + type: + - number + - "null" + timeLastModified: + type: + - number + - "null" + required: + - id + administrators: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + metadata: + type: + - array + - "null" + email: + type: + - string + - "null" + id: + type: string + isAccountOwner: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isReadOnly: + type: + - boolean + - "null" + name: + type: + - string + - "null" + organization: + type: + - string + - "null" + phone: + type: + - string + - "null" + teams: + type: + - array + - "null" + timeCreated: + type: + - number + - "null" + timeLastModified: + type: + - number + - "null" + required: + - id + teams: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} + hubs: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address: + type: + - object + - "null" + properties: + apartment: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + number: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + state: + type: + - string + - "null" + street: + type: + - string + - "null" + id: + type: string + location: + type: + - array + - "null" + items: + type: + - number + - "null" + name: + type: + - string + - "null" + teams: + type: + - array + - "null" + items: + type: + - string + - "null" + required: + - id + tasks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + metadata: + type: + - array + - "null" + additionalQuantities: + type: + - object + - "null" + properties: + quantityA: + type: + - number + - "null" + quantityB: + type: + - number + - "null" + quantityC: + type: + - number + - "null" + appearance: + type: + - object + - "null" + properties: {} + completeAfter: + type: + - number + - "null" + completionDetails: + type: + - object + - "null" + properties: + actions: + type: + - array + - "null" + events: + type: + - array + - "null" + failureNotes: + type: + - string + - "null" + failureReason: + type: + - string + - "null" + firstLocation: + type: + - array + - "null" + lastLocation: + type: + - array + - "null" + successNotes: + type: + - string + - "null" + unavailableAttachments: + type: + - array + - "null" + container: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + organization: + type: + - string + - "null" + creator: + type: + - string + - "null" + customFields: + type: + - array + - "null" + dependencies: + type: + - array + - "null" + destination: + type: + - object + - "null" + properties: + metadata: + type: + - array + - "null" + address: + type: + - object + - "null" + properties: + apartment: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + number: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + state: + type: + - string + - "null" + street: + type: + - string + - "null" + googlePlaceId: + type: + - string + - "null" + id: + type: + - string + - "null" + location: + type: + - array + - "null" + items: + type: + - number + - "null" + notes: + type: + - string + - "null" + timeCreated: + type: + - number + - "null" + timeLastModified: + type: + - number + - "null" + useGPS: + type: + - boolean + - "null" + warnings: + type: + - array + - "null" + executor: + type: + - string + - "null" + feedback: + type: + - array + - "null" + id: + type: string + identity: + type: + - object + - "null" + properties: + failedScanCount: + type: + - number + - "null" + merchant: + type: + - string + - "null" + notes: + type: + - string + - "null" + organization: + type: + - string + - "null" + overrides: + type: + - object + - "null" + pickupTask: + type: + - boolean + - "null" + quantity: + type: + - number + - "null" + recipients: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + metadata: + type: + - array + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + organization: + type: + - string + - "null" + phone: + type: + - string + - "null" + skipSMSNotifications: + type: + - boolean + - "null" + timeCreated: + type: + - number + - "null" + timeLastModified: + type: + - number + - "null" + scanOnlyRequiredBarcodes: + type: + - boolean + - "null" + serviceTime: + type: + - number + - "null" + shortId: + type: + - string + - "null" + state: + type: + - number + - "null" + timeCreated: + type: + - number + - "null" + timeLastModified: + type: + - number + - "null" + trackingURL: + type: + - string + - "null" + trackingViewed: + type: + - boolean + - "null" + required: + - id + containers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + id: + type: string + organization: + type: + - string + - "null" + tasks: + type: + - array + - "null" + timeCreated: + type: + - number + - "null" + timeLastModified: + type: + - number + - "null" + worker: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-onfleet/metadata.yaml b/airbyte-integrations/connectors/source-onfleet/metadata.yaml new file mode 100644 index 000000000000..a77da7bc82f8 --- /dev/null +++ b/airbyte-integrations/connectors/source-onfleet/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "onfleet.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-onfleet + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.3@sha256:9214270d83304213977c08e91fd9c55a98819543dbbf0df25a4356299af4f3ab + connectorSubtype: api + connectorType: source + definitionId: e4285e7f-ee6c-4b8b-b231-746c9640164e + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-onfleet + githubIssueLabel: source-onfleet + icon: icon.svg + license: MIT + name: Onfleet + releaseDate: 2024-10-27 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/onfleet + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-open-data-dc/metadata.yaml b/airbyte-integrations/connectors/source-open-data-dc/metadata.yaml index a8c8c91cbe9c..97bdba87d532 100644 --- a/airbyte-integrations/connectors/source-open-data-dc/metadata.yaml +++ b/airbyte-integrations/connectors/source-open-data-dc/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-open-data-dc connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 1178ad64-72bb-4326-86fb-b623663842b6 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-open-data-dc githubIssueLabel: source-open-data-dc icon: icon.svg diff --git a/airbyte-integrations/connectors/source-open-exchange-rates/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-open-exchange-rates/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-open-exchange-rates/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-open-exchange-rates/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-open-exchange-rates/metadata.yaml b/airbyte-integrations/connectors/source-open-exchange-rates/metadata.yaml index 7df75371a218..7ad9910957e1 100644 --- a/airbyte-integrations/connectors/source-open-exchange-rates/metadata.yaml +++ b/airbyte-integrations/connectors/source-open-exchange-rates/metadata.yaml @@ -3,11 +3,11 @@ data: hosts: - openexchangerates.org connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 77d5ca6b-d345-4dce-ba1e-1935a75778b8 - dockerImageTag: 0.3.3 + dockerImageTag: 0.3.7 dockerRepository: airbyte/source-open-exchange-rates documentationUrl: https://docs.airbyte.com/integrations/sources/open-exchange-rates githubIssueLabel: source-open-exchange-rates diff --git a/airbyte-integrations/connectors/source-openaq/README.md b/airbyte-integrations/connectors/source-openaq/README.md new file mode 100644 index 000000000000..fe90cdf7aea4 --- /dev/null +++ b/airbyte-integrations/connectors/source-openaq/README.md @@ -0,0 +1,36 @@ +# OpenAQ +This directory contains the manifest-only connector for `source-openaq`. + +The OpenAQ API provides open access to global air quality data. +This connector enables you to fetch data from all the streams listed on their website such as Locations , Sensors , Measurements and much more. + +Docs : https://docs.openaq.org/using-the-api/quick-start + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-openaq:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-openaq build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-openaq test +``` + diff --git a/airbyte-integrations/connectors/source-openaq/acceptance-test-config.yml b/airbyte-integrations/connectors/source-openaq/acceptance-test-config.yml new file mode 100644 index 000000000000..e4d77afa656b --- /dev/null +++ b/airbyte-integrations/connectors/source-openaq/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-openaq:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-openaq/icon.svg b/airbyte-integrations/connectors/source-openaq/icon.svg new file mode 100644 index 000000000000..58bac52844b4 --- /dev/null +++ b/airbyte-integrations/connectors/source-openaq/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-openaq/manifest.yaml b/airbyte-integrations/connectors/source-openaq/manifest.yaml new file mode 100644 index 000000000000..0b26cfa0d889 --- /dev/null +++ b/airbyte-integrations/connectors/source-openaq/manifest.yaml @@ -0,0 +1,2060 @@ +version: 5.14.0 + +type: DeclarativeSource + +description: >- + The OpenAQ API provides open access to global air quality data. + + This connector enables you to fetch data from all the streams listed on their + website such as Locations , Sensors , Measurements and much more. + + + Docs : https://docs.openaq.org/using-the-api/quick-start + +check: + type: CheckStream + stream_names: + - instruments + +definitions: + streams: + instruments: + type: DeclarativeStream + name: instruments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: instruments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/instruments" + manufacturers: + type: DeclarativeStream + name: manufacturers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: manufacturers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/manufacturers" + manufacturer_instruments: + type: DeclarativeStream + name: manufacturer_instruments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: manufacturers/{{ stream_partition.manufacturer_id }}/instruments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: manufacturer_id + stream: + $ref: "#/definitions/streams/manufacturers" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/manufacturer_instruments" + locations: + type: DeclarativeStream + name: locations + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: locations + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 2 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 5 + response_filters: + - type: HttpResponseFilter + action: RETRY + http_codes: + - 500 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: ListPartitionRouter + values: "{{ config.country_ids }}" + cursor_field: co_id + request_option: + type: RequestOption + inject_into: request_parameter + field_name: countries_id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/locations" + licenses: + type: DeclarativeStream + name: licenses + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: licenses + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/licenses" + license_instrument: + type: DeclarativeStream + name: license_instrument + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: licenses/{{ stream_partition.licenses_id }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: licenses_id + stream: + $ref: "#/definitions/streams/licenses" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/license_instrument" + parameters: + type: DeclarativeStream + name: parameters + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: parameters + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/parameters" + countries: + type: DeclarativeStream + name: countries + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: countries + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/countries" + latest_parameters: + type: DeclarativeStream + name: latest_parameters + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: parameters/{{ stream_partition.parameters_id }}/latest + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: parameters_id + stream: + $ref: "#/definitions/streams/parameters" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/latest_parameters" + sensors: + type: DeclarativeStream + name: sensors + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: locations/{{ stream_partition.location_id }}/sensors + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 10 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 5 + response_filters: + - type: HttpResponseFilter + action: RETRY + http_codes: + - 500 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: location_id + stream: + $ref: "#/definitions/streams/locations" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sensors" + providers: + type: DeclarativeStream + name: providers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: providers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/providers" + owners: + type: DeclarativeStream + name: owners + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: owners + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/owners" + location_latest_measure: + type: DeclarativeStream + name: location_latest_measure + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: locations/{{ stream_partition.location_id }}/latest + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: location_id + stream: + $ref: "#/definitions/streams/locations" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/location_latest_measure" + sensor_measurements: + type: DeclarativeStream + name: sensor_measurements + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sensors/{{ stream_partition.sensor_id }}/measurements + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: sensor_id + stream: + $ref: "#/definitions/streams/sensors" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sensor_measurements" + measurements_daily: + type: DeclarativeStream + name: measurements_daily + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sensors/{{ stream_partition.sensor_id }}/days + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 10 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 10 + response_filters: + - type: HttpResponseFilter + action: SUCCESS + http_codes: + - 500 + error_message: Internal Server Error + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 1000 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: sensor_id + stream: + $ref: "#/definitions/streams/sensors" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/measurements_daily" + measurements_yearly: + type: DeclarativeStream + name: measurements_yearly + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sensors/{{ stream_partition.sensor_id }}/years + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: sensor_id + stream: + $ref: "#/definitions/streams/sensors" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/measurements_yearly" + base_requester: + type: HttpRequester + url_base: https://api.openaq.org/v3/ + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: X-API-Key + inject_into: header + +streams: + - $ref: "#/definitions/streams/instruments" + - $ref: "#/definitions/streams/manufacturers" + - $ref: "#/definitions/streams/manufacturer_instruments" + - $ref: "#/definitions/streams/locations" + - $ref: "#/definitions/streams/licenses" + - $ref: "#/definitions/streams/license_instrument" + - $ref: "#/definitions/streams/parameters" + - $ref: "#/definitions/streams/countries" + - $ref: "#/definitions/streams/latest_parameters" + - $ref: "#/definitions/streams/sensors" + - $ref: "#/definitions/streams/providers" + - $ref: "#/definitions/streams/owners" + - $ref: "#/definitions/streams/location_latest_measure" + - $ref: "#/definitions/streams/sensor_measurements" + - $ref: "#/definitions/streams/measurements_daily" + - $ref: "#/definitions/streams/measurements_yearly" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - country_ids + properties: + api_key: + type: string + order: 0 + title: API Key + airbyte_secret: true + country_ids: + type: array + description: >- + The list of IDs of countries (comma separated) you need the data for, + check more: https://docs.openaq.org/resources/countries + order: 1 + title: Countries + additionalProperties: true + +metadata: + autoImportSchema: + instruments: true + manufacturers: true + manufacturer_instruments: true + locations: true + licenses: true + license_instrument: true + parameters: true + countries: true + latest_parameters: true + sensors: true + providers: true + owners: true + location_latest_measure: true + sensor_measurements: true + measurements_daily: true + measurements_yearly: true + testedStreams: + instruments: + streamHash: 37ced606dd4d1ee203685c7dfff05e26f1c6fbe0 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + manufacturers: + streamHash: 758a158a89e8f45543eb8c22c99ea8643ea462ab + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + manufacturer_instruments: + streamHash: 1d7607c726b0ca392e558ae0b2244c6696b67a0e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + locations: + streamHash: 19ade0d6f041647c45cc191e69b2d4fb6c4a5203 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + licenses: + streamHash: 186c2b5653b20ef06c281f6aef755eee7b1c050f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + license_instrument: + streamHash: 1ba49590965222df97cb14b486c66eddbffd3253 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + parameters: + streamHash: 2957351af4367680bc00dee0b089bb0b44ab51f1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + countries: + streamHash: 8d9861715c30528ea96f98e4cb461a87ab3fbef0 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + latest_parameters: + streamHash: 5c9ed8694a093960cd9fa4a5a5821d4b2ccd9282 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + sensors: + streamHash: 32b6ebb6a4882b0e0b46b458aa2ad685df21be9e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + providers: + streamHash: d4d7e6b2db844501fb3a3a8b004071d0be10c22a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + owners: + streamHash: f39546df1a5c47d70a3c98d020dae113f1bcd6f5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + location_latest_measure: + streamHash: d55e14b3570d202bb19b85675d5de26b634a8597 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + sensor_measurements: + streamHash: b1a0f502086b51e638bc82d67731db75b05d2392 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + measurements_daily: + streamHash: 1c3febd96e12e486b4a47d61cff3e6b6026a2157 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + measurements_yearly: + streamHash: 713432a65dbf7b74fa621638c524aa2c3def25b2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + instruments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: number + isMonitor: + type: + - boolean + - "null" + manufacturer: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + name: + type: + - string + - "null" + required: + - id + manufacturers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: number + instruments: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + name: + type: + - string + - "null" + required: + - id + manufacturer_instruments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: number + isMonitor: + type: + - boolean + - "null" + manufacturer: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + name: + type: + - string + - "null" + required: + - id + locations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + bounds: + type: + - array + - "null" + items: + type: + - number + - "null" + coordinates: + type: + - object + - "null" + properties: + latitude: + type: + - number + - "null" + longitude: + type: + - number + - "null" + country: + type: + - object + - "null" + properties: + code: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + datetimeFirst: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + datetimeLast: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + id: + type: number + instruments: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + isMobile: + type: + - boolean + - "null" + isMonitor: + type: + - boolean + - "null" + licenses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + attribution: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + dateFrom: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + locality: + type: + - string + - "null" + name: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + provider: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + sensors: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + parameter: + type: + - object + - "null" + properties: + displayName: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + units: + type: + - string + - "null" + timezone: + type: + - string + - "null" + required: + - id + licenses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attributionRequired: + type: + - boolean + - "null" + commercialUseAllowed: + type: + - boolean + - "null" + id: + type: + - number + - "null" + modificationAllowed: + type: + - boolean + - "null" + name: + type: + - string + - "null" + redistributionAllowed: + type: + - boolean + - "null" + shareAlikeRequired: + type: + - boolean + - "null" + sourceUrl: + type: + - string + - "null" + license_instrument: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attributionRequired: + type: + - boolean + - "null" + commercialUseAllowed: + type: + - boolean + - "null" + id: + type: number + modificationAllowed: + type: + - boolean + - "null" + name: + type: + - string + - "null" + redistributionAllowed: + type: + - boolean + - "null" + shareAlikeRequired: + type: + - boolean + - "null" + sourceUrl: + type: + - string + - "null" + required: + - id + parameters: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + displayName: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + units: + type: + - string + - "null" + required: + - id + countries: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + code: + type: + - string + - "null" + datetimeFirst: + type: + - string + - "null" + datetimeLast: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + parameters: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + units: + type: + - string + - "null" + required: + - id + latest_parameters: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + coordinates: + type: + - object + - "null" + properties: + latitude: + type: + - number + - "null" + longitude: + type: + - number + - "null" + datetime: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + locationsId: + type: + - number + - "null" + sensorsId: + type: + - number + - "null" + value: + type: + - number + - "null" + sensors: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + coverage: + type: + - object + - "null" + properties: + datetimeFrom: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + datetimeTo: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + expectedCount: + type: + - number + - "null" + expectedInterval: + type: + - string + - "null" + observedCount: + type: + - number + - "null" + observedInterval: + type: + - string + - "null" + percentComplete: + type: + - number + - "null" + percentCoverage: + type: + - number + - "null" + datetimeFirst: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + datetimeLast: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + id: + type: number + latest: + type: + - object + - "null" + properties: + coordinates: + type: + - object + - "null" + properties: + latitude: + type: + - number + - "null" + longitude: + type: + - number + - "null" + datetime: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + value: + type: + - number + - "null" + name: + type: + - string + - "null" + parameter: + type: + - object + - "null" + properties: + displayName: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + units: + type: + - string + - "null" + summary: + type: + - object + - "null" + properties: + avg: + type: + - number + - "null" + max: + type: + - number + - "null" + min: + type: + - number + - "null" + required: + - id + providers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + bbox: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + coordinates: + type: + - array + - "null" + items: + anyOf: + - type: number + - type: array + items: + type: array + items: + type: number + datetimeAdded: + type: + - string + - "null" + datetimeFirst: + type: + - string + - "null" + datetimeLast: + type: + - string + - "null" + entitiesId: + type: + - number + - "null" + exportPrefix: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + parameters: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + units: + type: + - string + - "null" + sourceName: + type: + - string + - "null" + required: + - id + owners: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: number + name: + type: + - string + - "null" + required: + - id + location_latest_measure: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + coordinates: + type: + - object + - "null" + properties: + latitude: + type: + - number + - "null" + longitude: + type: + - number + - "null" + datetime: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + locationsId: + type: + - number + - "null" + sensorsId: + type: + - number + - "null" + value: + type: + - number + - "null" + sensor_measurements: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + coverage: + type: + - object + - "null" + properties: + datetimeFrom: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + datetimeTo: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + expectedCount: + type: + - number + - "null" + expectedInterval: + type: + - string + - "null" + observedCount: + type: + - number + - "null" + observedInterval: + type: + - string + - "null" + percentComplete: + type: + - number + - "null" + percentCoverage: + type: + - number + - "null" + flagInfo: + type: + - object + - "null" + properties: + hasFlags: + type: + - boolean + - "null" + parameter: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + units: + type: + - string + - "null" + period: + type: + - object + - "null" + properties: + datetimeFrom: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + datetimeTo: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + interval: + type: + - string + - "null" + label: + type: + - string + - "null" + value: + type: + - number + - "null" + measurements_daily: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + coverage: + type: + - object + - "null" + properties: + datetimeFrom: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + datetimeTo: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + expectedCount: + type: + - number + - "null" + expectedInterval: + type: + - string + - "null" + observedCount: + type: + - number + - "null" + observedInterval: + type: + - string + - "null" + percentComplete: + type: + - number + - "null" + percentCoverage: + type: + - number + - "null" + flagInfo: + type: + - object + - "null" + properties: + hasFlags: + type: + - boolean + - "null" + parameter: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + units: + type: + - string + - "null" + period: + type: + - object + - "null" + properties: + datetimeFrom: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + datetimeTo: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + interval: + type: + - string + - "null" + label: + type: + - string + - "null" + summary: + type: + - object + - "null" + properties: + avg: + type: + - number + - "null" + max: + type: + - number + - "null" + median: + type: + - number + - "null" + min: + type: + - number + - "null" + q02: + type: + - number + - "null" + q25: + type: + - number + - "null" + q75: + type: + - number + - "null" + q98: + type: + - number + - "null" + sd: + type: + - number + - "null" + value: + type: + - number + - "null" + measurements_yearly: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + coverage: + type: + - object + - "null" + properties: + datetimeFrom: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + datetimeTo: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + expectedCount: + type: + - number + - "null" + expectedInterval: + type: + - string + - "null" + observedCount: + type: + - number + - "null" + observedInterval: + type: + - string + - "null" + percentComplete: + type: + - number + - "null" + percentCoverage: + type: + - number + - "null" + flagInfo: + type: + - object + - "null" + properties: + hasFlags: + type: + - boolean + - "null" + parameter: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + units: + type: + - string + - "null" + period: + type: + - object + - "null" + properties: + datetimeFrom: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + datetimeTo: + type: + - object + - "null" + properties: + local: + type: + - string + - "null" + utc: + type: + - string + - "null" + interval: + type: + - string + - "null" + label: + type: + - string + - "null" + summary: + type: + - object + - "null" + properties: + avg: + type: + - number + - "null" + max: + type: + - number + - "null" + median: + type: + - number + - "null" + min: + type: + - number + - "null" + q02: + type: + - number + - "null" + q25: + type: + - number + - "null" + q75: + type: + - number + - "null" + q98: + type: + - number + - "null" + sd: + type: + - number + - "null" + value: + type: + - number + - "null" diff --git a/airbyte-integrations/connectors/source-openaq/metadata.yaml b/airbyte-integrations/connectors/source-openaq/metadata.yaml new file mode 100644 index 000000000000..b7e5d96502c3 --- /dev/null +++ b/airbyte-integrations/connectors/source-openaq/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.openaq.org" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-openaq + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 5b7216ca-1d6d-4a50-89c3-067746806586 + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-openaq + githubIssueLabel: source-openaq + icon: icon.svg + license: MIT + name: OpenAQ + releaseDate: 2024-10-19 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/openaq + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-openfda/README.md b/airbyte-integrations/connectors/source-openfda/README.md new file mode 100644 index 000000000000..b14054f1e09f --- /dev/null +++ b/airbyte-integrations/connectors/source-openfda/README.md @@ -0,0 +1,35 @@ +# OpenFDA +This directory contains the manifest-only connector for `source-openfda`. + +OpenFDA provides access to a number of high-value, high priority and scalable structured datasets, including adverse events, drug product labeling, and recall enforcement reports. +With this conenctor we can fetch data from the streams like Drugs , Animal and Veterinary Adverse Events and Food Adverse Events etc. +Docs:https://open.fda.gov/apis/ + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-openfda:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-openfda build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-openfda test +``` + diff --git a/airbyte-integrations/connectors/source-openfda/acceptance-test-config.yml b/airbyte-integrations/connectors/source-openfda/acceptance-test-config.yml new file mode 100644 index 000000000000..447b1590cba3 --- /dev/null +++ b/airbyte-integrations/connectors/source-openfda/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-openfda:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-openfda/icon.svg b/airbyte-integrations/connectors/source-openfda/icon.svg new file mode 100644 index 000000000000..4bef8f853cca --- /dev/null +++ b/airbyte-integrations/connectors/source-openfda/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-openfda/manifest.yaml b/airbyte-integrations/connectors/source-openfda/manifest.yaml new file mode 100644 index 000000000000..884fb656591d --- /dev/null +++ b/airbyte-integrations/connectors/source-openfda/manifest.yaml @@ -0,0 +1,3281 @@ +version: 5.14.0 + +type: DeclarativeSource + +description: >- + OpenFDA provides access to a number of high-value, high priority and scalable + structured datasets, including adverse events, drug product labeling, and + recall enforcement reports. + + With this conenctor we can fetch data from the streams like Drugs , Animal and + Veterinary Adverse Events and Food Adverse Events etc. + + Docs:https://open.fda.gov/apis/ + +check: + type: CheckStream + stream_names: + - animal_veterinary_adverse_events + +definitions: + streams: + animal_veterinary_adverse_events: + type: DeclarativeStream + name: animal_veterinary_adverse_events + primary_key: + - unique_aer_id_number + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: animalandveterinary/event.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 1000 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/animal_veterinary_adverse_events" + tobacco_problems_reports: + type: DeclarativeStream + name: tobacco_problems_reports + primary_key: + - report_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: tobacco/problem.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 1000 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tobacco_problems_reports" + food_adverse_events: + type: DeclarativeStream + name: food_adverse_events + primary_key: + - report_number + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: food/event.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 1000 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/food_adverse_events" + food_enforcement_reports: + type: DeclarativeStream + name: food_enforcement_reports + primary_key: + - recall_number + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: food/enforcement.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 1000 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/food_enforcement_reports" + drug_adverse_events: + type: DeclarativeStream + name: drug_adverse_events + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: drug/event.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/drug_adverse_events" + drug_product_labelling: + type: DeclarativeStream + name: drug_product_labelling + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: drug/label.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/drug_product_labelling" + drug_ndc_library: + type: DeclarativeStream + name: drug_ndc_library + primary_key: + - product_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: drug/ndc.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/drug_ndc_library" + drug_recall_enforcement_reports: + type: DeclarativeStream + name: drug_recall_enforcement_reports + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: drug/enforcement.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/drug_recall_enforcement_reports" + drugs: + type: DeclarativeStream + name: drugs + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: drug/drugsfda.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 1000 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/drugs" + base_requester: + type: HttpRequester + url_base: https://api.fda.gov/ + +streams: + - $ref: "#/definitions/streams/animal_veterinary_adverse_events" + - $ref: "#/definitions/streams/tobacco_problems_reports" + - $ref: "#/definitions/streams/food_adverse_events" + - $ref: "#/definitions/streams/food_enforcement_reports" + - $ref: "#/definitions/streams/drug_adverse_events" + - $ref: "#/definitions/streams/drug_product_labelling" + - $ref: "#/definitions/streams/drug_ndc_library" + - $ref: "#/definitions/streams/drug_recall_enforcement_reports" + - $ref: "#/definitions/streams/drugs" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: [] + properties: {} + additionalProperties: true + +metadata: + autoImportSchema: + animal_veterinary_adverse_events: true + tobacco_problems_reports: true + food_adverse_events: true + food_enforcement_reports: true + drug_adverse_events: true + drug_product_labelling: true + drug_ndc_library: true + drug_recall_enforcement_reports: true + drugs: true + testedStreams: + animal_veterinary_adverse_events: + streamHash: 1d0606cba68cd120e0e232fe4c17a4052a81a21b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tobacco_problems_reports: + streamHash: 9abc5a930b34a95b05781474ce33d3813517d6e7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + food_adverse_events: + streamHash: 47564cfd48ee2b7e8f3dea3865a5d9e0ae320d41 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + food_enforcement_reports: + streamHash: 672fd13cf7193fe36af6e381ceb415d1a9cc5a5f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + drug_adverse_events: + streamHash: 0fb7eea38b63cb80d6a875aed3b775d57e7db890 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + drug_product_labelling: + streamHash: c680cd6d8b4d7c25af12a0f1178c9a2a8526384d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + drug_ndc_library: + streamHash: 904ce65d91f343f4e7dbd7900e29922e1df56f8f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + drug_recall_enforcement_reports: + streamHash: 3eabe167039177cba2fa2d94cd4121fed5856ee9 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + drugs: + streamHash: 828d896d5246308d786abbe20e3cd693afb7a2d3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + animal_veterinary_adverse_events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + animal: + type: + - object + - "null" + properties: + age: + type: + - object + - "null" + properties: + max: + type: + - string + - "null" + min: + type: + - string + - "null" + qualifier: + type: + - string + - "null" + unit: + type: + - string + - "null" + breed: + type: + - object + - "null" + properties: + breed_component: + anyOf: + - type: string + - type: array + items: + type: string + is_crossbred: + type: + - string + - "null" + female_animal_physiological_status: + type: + - string + - "null" + gender: + type: + - string + - "null" + reproductive_status: + type: + - string + - "null" + species: + type: + - string + - "null" + weight: + type: + - object + - "null" + properties: + max: + type: + - string + - "null" + min: + type: + - string + - "null" + qualifier: + type: + - string + - "null" + unit: + type: + - string + - "null" + drug: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + active_ingredients: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + dose: + type: + - object + - "null" + properties: + denominator: + type: + - string + - "null" + denominator_unit: + type: + - string + - "null" + numerator: + type: + - string + - "null" + numerator_unit: + type: + - string + - "null" + name: + type: + - string + - "null" + administered_by: + type: + - string + - "null" + ae_abated_after_stopping_drug: + type: + - string + - "null" + ae_reappeared_after_resuming_drug: + type: + - string + - "null" + atc_vet_code: + type: + - string + - "null" + brand_name: + type: + - string + - "null" + dosage_form: + type: + - string + - "null" + dose: + type: + - object + - "null" + properties: + denominator: + type: + - string + - "null" + denominator_unit: + type: + - string + - "null" + numerator: + type: + - string + - "null" + numerator_unit: + type: + - string + - "null" + first_exposure_date: + type: + - string + - "null" + frequency_of_administration: + type: + - object + - "null" + properties: + unit: + type: + - string + - "null" + value: + type: + - string + - "null" + last_exposure_date: + type: + - string + - "null" + lot_expiration: + type: + - string + - "null" + lot_number: + type: + - string + - "null" + manufacturer: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + registration_number: + type: + - string + - "null" + manufacturing_date: + type: + - string + - "null" + number_of_defective_items: + type: + - string + - "null" + number_of_items_returned: + type: + - string + - "null" + off_label_use: + anyOf: + - type: string + - type: array + items: + type: string + previous_ae_to_drug: + type: + - string + - "null" + previous_exposure_to_drug: + type: + - string + - "null" + product_ndc: + type: + - string + - "null" + route: + type: + - string + - "null" + used_according_to_label: + type: + - string + - "null" + duration: + type: + - object + - "null" + properties: + unit: + type: + - string + - "null" + value: + type: + - string + - "null" + health_assessment_prior_to_exposure: + type: + - object + - "null" + properties: + assessed_by: + type: + - string + - "null" + condition: + type: + - string + - "null" + number_of_animals_affected: + type: + - string + - "null" + number_of_animals_treated: + type: + - string + - "null" + onset_date: + type: + - string + - "null" + original_receive_date: + type: + - string + - "null" + outcome: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + medical_status: + type: + - string + - "null" + number_of_animals_affected: + type: + - string + - "null" + primary_reporter: + type: + - string + - "null" + reaction: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + accuracy: + type: + - string + - "null" + number_of_animals_affected: + type: + - string + - "null" + veddra_term_code: + type: + - string + - "null" + veddra_term_name: + type: + - string + - "null" + veddra_version: + type: + - string + - "null" + receiver: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + country: + type: + - string + - "null" + organization: + type: + - string + - "null" + postal_code: + type: + - string + - "null" + state: + type: + - string + - "null" + street_address: + type: + - string + - "null" + report_id: + type: + - string + - "null" + secondary_reporter: + type: + - string + - "null" + serious_ae: + type: + - string + - "null" + time_between_exposure_and_onset: + type: + - string + - "null" + treated_for_ae: + type: + - string + - "null" + type_of_information: + type: + - string + - "null" + unique_aer_id_number: + type: string + required: + - unique_aer_id_number + tobacco_problems_reports: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + date_submitted: + type: + - string + - "null" + nonuser_affected: + type: + - string + - "null" + number_health_problems: + type: + - number + - "null" + number_product_problems: + type: + - number + - "null" + number_tobacco_products: + type: + - number + - "null" + report_id: + type: number + reported_health_problems: + type: + - array + - "null" + items: + type: + - string + - "null" + reported_product_problems: + type: + - array + - "null" + items: + type: + - string + - "null" + tobacco_products: + type: + - array + - "null" + items: + type: + - string + - "null" + required: + - report_id + food_adverse_events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + consumer: + type: + - object + - "null" + properties: + age: + type: + - string + - "null" + age_unit: + type: + - string + - "null" + gender: + type: + - string + - "null" + date_created: + type: + - string + - "null" + date_started: + type: + - string + - "null" + outcomes: + type: + - array + - "null" + items: + type: + - string + - "null" + products: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + industry_code: + type: + - string + - "null" + industry_name: + type: + - string + - "null" + name_brand: + type: + - string + - "null" + role: + type: + - string + - "null" + reactions: + type: + - array + - "null" + items: + type: + - string + - "null" + report_number: + type: string + required: + - report_number + food_enforcement_reports: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address_1: + type: + - string + - "null" + address_2: + type: + - string + - "null" + center_classification_date: + type: + - string + - "null" + city: + type: + - string + - "null" + classification: + type: + - string + - "null" + code_info: + type: + - string + - "null" + country: + type: + - string + - "null" + distribution_pattern: + type: + - string + - "null" + event_id: + type: + - string + - "null" + initial_firm_notification: + type: + - string + - "null" + more_code_info: + type: + - string + - "null" + openfda: + type: + - object + - "null" + postal_code: + type: + - string + - "null" + product_description: + type: + - string + - "null" + product_quantity: + type: + - string + - "null" + product_type: + type: + - string + - "null" + reason_for_recall: + type: + - string + - "null" + recall_initiation_date: + type: + - string + - "null" + recall_number: + type: string + recalling_firm: + type: + - string + - "null" + report_date: + type: + - string + - "null" + state: + type: + - string + - "null" + status: + type: + - string + - "null" + termination_date: + type: + - string + - "null" + voluntary_mandated: + type: + - string + - "null" + required: + - recall_number + drug_adverse_events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + companynumb: + type: + - string + - "null" + duplicate: + type: + - string + - "null" + fulfillexpeditecriteria: + type: + - string + - "null" + occurcountry: + type: + - string + - "null" + patient: + type: + - object + - "null" + properties: + drug: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + actiondrug: + type: + - string + - "null" + activesubstance: + type: + - object + - "null" + properties: + activesubstancename: + type: + - string + - "null" + drugadditional: + type: + - string + - "null" + drugadministrationroute: + type: + - string + - "null" + drugauthorizationnumb: + type: + - string + - "null" + drugbatchnumb: + type: + - string + - "null" + drugcharacterization: + type: + - string + - "null" + drugcumulativedosagenumb: + type: + - string + - "null" + drugcumulativedosageunit: + type: + - string + - "null" + drugdosageform: + type: + - string + - "null" + drugdosagetext: + type: + - string + - "null" + drugenddate: + type: + - string + - "null" + drugenddateformat: + type: + - string + - "null" + drugindication: + type: + - string + - "null" + drugintervaldosagedefinition: + type: + - string + - "null" + drugintervaldosageunitnumb: + type: + - string + - "null" + drugrecurreadministration: + type: + - string + - "null" + drugseparatedosagenumb: + type: + - string + - "null" + drugstartdate: + type: + - string + - "null" + drugstartdateformat: + type: + - string + - "null" + drugstructuredosagenumb: + type: + - string + - "null" + drugstructuredosageunit: + type: + - string + - "null" + medicinalproduct: + type: + - string + - "null" + openfda: + type: + - object + - "null" + properties: + application_number: + type: + - array + - "null" + items: + type: + - string + - "null" + brand_name: + type: + - array + - "null" + items: + type: + - string + - "null" + generic_name: + type: + - array + - "null" + items: + type: + - string + - "null" + manufacturer_name: + type: + - array + - "null" + items: + type: + - string + - "null" + nui: + type: + - array + - "null" + items: + type: + - string + - "null" + package_ndc: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_cs: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_epc: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_moa: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_pe: + type: + - array + - "null" + items: + type: + - string + - "null" + product_ndc: + type: + - array + - "null" + items: + type: + - string + - "null" + product_type: + type: + - array + - "null" + items: + type: + - string + - "null" + route: + type: + - array + - "null" + items: + type: + - string + - "null" + rxcui: + type: + - array + - "null" + items: + type: + - string + - "null" + spl_id: + type: + - array + - "null" + items: + type: + - string + - "null" + spl_set_id: + type: + - array + - "null" + items: + type: + - string + - "null" + substance_name: + type: + - array + - "null" + items: + type: + - string + - "null" + unii: + type: + - array + - "null" + items: + type: + - string + - "null" + patientagegroup: + type: + - string + - "null" + patientdeath: + type: + - object + - "null" + properties: {} + patientonsetage: + type: + - string + - "null" + patientonsetageunit: + type: + - string + - "null" + patientsex: + type: + - string + - "null" + patientweight: + type: + - string + - "null" + reaction: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + reactionmeddrapt: + type: + - string + - "null" + reactionmeddraversionpt: + type: + - string + - "null" + reactionoutcome: + type: + - string + - "null" + summary: + type: + - object + - "null" + properties: + narrativeincludeclinical: + type: + - string + - "null" + primarysource: + type: + - object + - "null" + properties: + literaturereference: + type: + - string + - "null" + qualification: + type: + - string + - "null" + reportercountry: + type: + - string + - "null" + primarysourcecountry: + type: + - string + - "null" + receiptdate: + type: + - string + - "null" + receiptdateformat: + type: + - string + - "null" + receivedate: + type: + - string + - "null" + receivedateformat: + type: + - string + - "null" + receiver: + type: + - object + - "null" + properties: + receiverorganization: + type: + - string + - "null" + receivertype: + type: + - string + - "null" + reportduplicate: + type: + - object + - "null" + properties: + duplicatenumb: + type: + - string + - "null" + duplicatesource: + type: + - string + - "null" + reporttype: + type: + - string + - "null" + safetyreportid: + type: + - string + - "null" + safetyreportversion: + type: + - string + - "null" + sender: + type: + - object + - "null" + properties: + senderorganization: + type: + - string + - "null" + sendertype: + type: + - string + - "null" + serious: + type: + - string + - "null" + seriousnesscongenitalanomali: + type: + - string + - "null" + seriousnessdeath: + type: + - string + - "null" + seriousnessdisabling: + type: + - string + - "null" + seriousnesshospitalization: + type: + - string + - "null" + seriousnesslifethreatening: + type: + - string + - "null" + seriousnessother: + type: + - string + - "null" + transmissiondate: + type: + - string + - "null" + transmissiondateformat: + type: + - string + - "null" + drug_product_labelling: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - string + - "null" + description: + type: + - array + - "null" + items: + type: + - string + - "null" + abuse: + type: + - array + - "null" + items: + type: + - string + - "null" + active_ingredient: + type: + - array + - "null" + items: + type: + - string + - "null" + active_ingredient_table: + type: + - array + - "null" + items: + type: + - string + - "null" + adverse_reactions: + type: + - array + - "null" + items: + type: + - string + - "null" + adverse_reactions_table: + type: + - array + - "null" + items: + type: + - string + - "null" + animal_pharmacology_and_or_toxicology: + type: + - array + - "null" + items: + type: + - string + - "null" + animal_pharmacology_and_or_toxicology_table: + type: + - array + - "null" + items: + type: + - string + - "null" + ask_doctor: + type: + - array + - "null" + items: + type: + - string + - "null" + ask_doctor_or_pharmacist: + type: + - array + - "null" + items: + type: + - string + - "null" + boxed_warning: + type: + - array + - "null" + items: + type: + - string + - "null" + carcinogenesis_and_mutagenesis_and_impairment_of_fertility: + type: + - array + - "null" + items: + type: + - string + - "null" + clinical_pharmacology: + type: + - array + - "null" + items: + type: + - string + - "null" + clinical_pharmacology_table: + type: + - array + - "null" + items: + type: + - string + - "null" + clinical_studies: + type: + - array + - "null" + items: + type: + - string + - "null" + clinical_studies_table: + type: + - array + - "null" + items: + type: + - string + - "null" + contraindications: + type: + - array + - "null" + items: + type: + - string + - "null" + controlled_substance: + type: + - array + - "null" + items: + type: + - string + - "null" + dependence: + type: + - array + - "null" + items: + type: + - string + - "null" + description_table: + type: + - array + - "null" + items: + type: + - string + - "null" + do_not_use: + type: + - array + - "null" + items: + type: + - string + - "null" + dosage_and_administration: + type: + - array + - "null" + items: + type: + - string + - "null" + dosage_and_administration_table: + type: + - array + - "null" + items: + type: + - string + - "null" + dosage_forms_and_strengths: + type: + - array + - "null" + items: + type: + - string + - "null" + dosage_forms_and_strengths_table: + type: + - array + - "null" + items: + type: + - string + - "null" + drug_abuse_and_dependence: + type: + - array + - "null" + items: + type: + - string + - "null" + drug_abuse_and_dependence_table: + type: + - array + - "null" + items: + type: + - string + - "null" + drug_and_or_laboratory_test_interactions: + type: + - array + - "null" + items: + type: + - string + - "null" + drug_interactions: + type: + - array + - "null" + items: + type: + - string + - "null" + drug_interactions_table: + type: + - array + - "null" + items: + type: + - string + - "null" + effective_time: + type: + - string + - "null" + general_precautions: + type: + - array + - "null" + items: + type: + - string + - "null" + geriatric_use: + type: + - array + - "null" + items: + type: + - string + - "null" + geriatric_use_table: + type: + - array + - "null" + items: + type: + - string + - "null" + how_supplied: + type: + - array + - "null" + items: + type: + - string + - "null" + how_supplied_table: + type: + - array + - "null" + items: + type: + - string + - "null" + id: + type: + - string + - "null" + inactive_ingredient: + type: + - array + - "null" + items: + type: + - string + - "null" + inactive_ingredient_table: + type: + - array + - "null" + items: + type: + - string + - "null" + indications_and_usage: + type: + - array + - "null" + items: + type: + - string + - "null" + indications_and_usage_table: + type: + - array + - "null" + items: + type: + - string + - "null" + information_for_patients: + type: + - array + - "null" + items: + type: + - string + - "null" + information_for_patients_table: + type: + - array + - "null" + items: + type: + - string + - "null" + instructions_for_use: + type: + - array + - "null" + items: + type: + - string + - "null" + instructions_for_use_table: + type: + - array + - "null" + items: + type: + - string + - "null" + keep_out_of_reach_of_children: + type: + - array + - "null" + items: + type: + - string + - "null" + labor_and_delivery: + type: + - array + - "null" + items: + type: + - string + - "null" + laboratory_tests: + type: + - array + - "null" + items: + type: + - string + - "null" + mechanism_of_action: + type: + - array + - "null" + items: + type: + - string + - "null" + microbiology: + type: + - array + - "null" + items: + type: + - string + - "null" + microbiology_table: + type: + - array + - "null" + items: + type: + - string + - "null" + nonclinical_toxicology: + type: + - array + - "null" + items: + type: + - string + - "null" + nonteratogenic_effects: + type: + - array + - "null" + items: + type: + - string + - "null" + nursing_mothers: + type: + - array + - "null" + items: + type: + - string + - "null" + openfda: + type: + - object + - "null" + properties: + application_number: + type: + - array + - "null" + items: + type: + - string + - "null" + brand_name: + type: + - array + - "null" + items: + type: + - string + - "null" + generic_name: + type: + - array + - "null" + items: + type: + - string + - "null" + is_original_packager: + type: + - array + - "null" + items: + type: + - boolean + - "null" + manufacturer_name: + type: + - array + - "null" + items: + type: + - string + - "null" + nui: + type: + - array + - "null" + items: + type: + - string + - "null" + original_packager_product_ndc: + type: + - array + - "null" + items: + type: + - string + - "null" + package_ndc: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_cs: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_epc: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_moa: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_pe: + type: + - array + - "null" + items: + type: + - string + - "null" + product_ndc: + type: + - array + - "null" + items: + type: + - string + - "null" + product_type: + type: + - array + - "null" + items: + type: + - string + - "null" + route: + type: + - array + - "null" + items: + type: + - string + - "null" + rxcui: + type: + - array + - "null" + items: + type: + - string + - "null" + spl_id: + type: + - array + - "null" + items: + type: + - string + - "null" + spl_set_id: + type: + - array + - "null" + items: + type: + - string + - "null" + substance_name: + type: + - array + - "null" + items: + type: + - string + - "null" + unii: + type: + - array + - "null" + items: + type: + - string + - "null" + upc: + type: + - array + - "null" + items: + type: + - string + - "null" + other_safety_information: + type: + - array + - "null" + items: + type: + - string + - "null" + overdosage: + type: + - array + - "null" + items: + type: + - string + - "null" + package_label_principal_display_panel: + type: + - array + - "null" + items: + type: + - string + - "null" + patient_medication_information: + type: + - array + - "null" + items: + type: + - string + - "null" + pediatric_use: + type: + - array + - "null" + items: + type: + - string + - "null" + pediatric_use_table: + type: + - array + - "null" + items: + type: + - string + - "null" + pharmacodynamics: + type: + - array + - "null" + items: + type: + - string + - "null" + pharmacodynamics_table: + type: + - array + - "null" + items: + type: + - string + - "null" + pharmacogenomics: + type: + - array + - "null" + items: + type: + - string + - "null" + pharmacokinetics: + type: + - array + - "null" + items: + type: + - string + - "null" + pharmacokinetics_table: + type: + - array + - "null" + items: + type: + - string + - "null" + precautions: + type: + - array + - "null" + items: + type: + - string + - "null" + precautions_table: + type: + - array + - "null" + items: + type: + - string + - "null" + pregnancy: + type: + - array + - "null" + items: + type: + - string + - "null" + pregnancy_or_breast_feeding: + type: + - array + - "null" + items: + type: + - string + - "null" + purpose: + type: + - array + - "null" + items: + type: + - string + - "null" + purpose_table: + type: + - array + - "null" + items: + type: + - string + - "null" + questions: + type: + - array + - "null" + items: + type: + - string + - "null" + recent_major_changes: + type: + - array + - "null" + items: + type: + - string + - "null" + recent_major_changes_table: + type: + - array + - "null" + items: + type: + - string + - "null" + references: + type: + - array + - "null" + items: + type: + - string + - "null" + references_table: + type: + - array + - "null" + items: + type: + - string + - "null" + risks: + type: + - array + - "null" + items: + type: + - string + - "null" + route: + type: + - array + - "null" + items: + type: + - string + - "null" + safe_handling_warning: + type: + - array + - "null" + items: + type: + - string + - "null" + set_id: + type: + - string + - "null" + spl_medguide: + type: + - array + - "null" + items: + type: + - string + - "null" + spl_medguide_table: + type: + - array + - "null" + items: + type: + - string + - "null" + spl_patient_package_insert: + type: + - array + - "null" + items: + type: + - string + - "null" + spl_patient_package_insert_table: + type: + - array + - "null" + items: + type: + - string + - "null" + spl_product_data_elements: + type: + - array + - "null" + items: + type: + - string + - "null" + spl_unclassified_section: + type: + - array + - "null" + items: + type: + - string + - "null" + spl_unclassified_section_table: + type: + - array + - "null" + items: + type: + - string + - "null" + statement_of_identity: + type: + - array + - "null" + items: + type: + - string + - "null" + stop_use: + type: + - array + - "null" + items: + type: + - string + - "null" + storage_and_handling: + type: + - array + - "null" + items: + type: + - string + - "null" + teratogenic_effects: + type: + - array + - "null" + items: + type: + - string + - "null" + use_in_specific_populations: + type: + - array + - "null" + items: + type: + - string + - "null" + use_in_specific_populations_table: + type: + - array + - "null" + items: + type: + - string + - "null" + user_safety_warnings: + type: + - array + - "null" + items: + type: + - string + - "null" + warnings: + type: + - array + - "null" + items: + type: + - string + - "null" + warnings_and_cautions: + type: + - array + - "null" + items: + type: + - string + - "null" + warnings_and_cautions_table: + type: + - array + - "null" + items: + type: + - string + - "null" + warnings_table: + type: + - array + - "null" + items: + type: + - string + - "null" + when_using: + type: + - array + - "null" + items: + type: + - string + - "null" + drug_ndc_library: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active_ingredients: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + strength: + type: + - string + - "null" + application_number: + type: + - string + - "null" + brand_name: + type: + - string + - "null" + brand_name_base: + type: + - string + - "null" + brand_name_suffix: + type: + - string + - "null" + dea_schedule: + type: + - string + - "null" + dosage_form: + type: + - string + - "null" + finished: + type: + - boolean + - "null" + generic_name: + type: + - string + - "null" + labeler_name: + type: + - string + - "null" + listing_expiration_date: + type: + - string + - "null" + marketing_category: + type: + - string + - "null" + marketing_end_date: + type: + - string + - "null" + marketing_start_date: + type: + - string + - "null" + openfda: + type: + - object + - "null" + properties: + is_original_packager: + type: + - array + - "null" + items: + type: + - boolean + - "null" + manufacturer_name: + type: + - array + - "null" + items: + type: + - string + - "null" + nui: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_cs: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_epc: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_moa: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_pe: + type: + - array + - "null" + items: + type: + - string + - "null" + rxcui: + type: + - array + - "null" + items: + type: + - string + - "null" + spl_set_id: + type: + - array + - "null" + items: + type: + - string + - "null" + unii: + type: + - array + - "null" + items: + type: + - string + - "null" + upc: + type: + - array + - "null" + items: + type: + - string + - "null" + packaging: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + marketing_end_date: + type: + - string + - "null" + marketing_start_date: + type: + - string + - "null" + package_ndc: + type: + - string + - "null" + sample: + type: + - boolean + - "null" + pharm_class: + type: + - array + - "null" + items: + type: + - string + - "null" + product_id: + type: string + product_ndc: + type: + - string + - "null" + product_type: + type: + - string + - "null" + route: + type: + - array + - "null" + items: + type: + - string + - "null" + spl_id: + type: + - string + - "null" + required: + - product_id + drug_recall_enforcement_reports: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address_1: + type: + - string + - "null" + address_2: + type: + - string + - "null" + center_classification_date: + type: + - string + - "null" + city: + type: + - string + - "null" + classification: + type: + - string + - "null" + code_info: + type: + - string + - "null" + country: + type: + - string + - "null" + distribution_pattern: + type: + - string + - "null" + event_id: + type: + - string + - "null" + initial_firm_notification: + type: + - string + - "null" + more_code_info: + type: + - string + - "null" + openfda: + type: + - object + - "null" + properties: + application_number: + type: + - array + - "null" + items: + type: + - string + - "null" + brand_name: + type: + - array + - "null" + items: + type: + - string + - "null" + generic_name: + type: + - array + - "null" + items: + type: + - string + - "null" + is_original_packager: + type: + - array + - "null" + items: + type: + - boolean + - "null" + manufacturer_name: + type: + - array + - "null" + items: + type: + - string + - "null" + nui: + type: + - array + - "null" + items: + type: + - string + - "null" + original_packager_product_ndc: + type: + - array + - "null" + items: + type: + - string + - "null" + package_ndc: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_cs: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_epc: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_moa: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_pe: + type: + - array + - "null" + items: + type: + - string + - "null" + product_ndc: + type: + - array + - "null" + items: + type: + - string + - "null" + product_type: + type: + - array + - "null" + items: + type: + - string + - "null" + route: + type: + - array + - "null" + items: + type: + - string + - "null" + rxcui: + type: + - array + - "null" + items: + type: + - string + - "null" + spl_id: + type: + - array + - "null" + items: + type: + - string + - "null" + spl_set_id: + type: + - array + - "null" + items: + type: + - string + - "null" + substance_name: + type: + - array + - "null" + items: + type: + - string + - "null" + unii: + type: + - array + - "null" + items: + type: + - string + - "null" + upc: + type: + - array + - "null" + items: + type: + - string + - "null" + postal_code: + type: + - string + - "null" + product_description: + type: + - string + - "null" + product_quantity: + type: + - string + - "null" + product_type: + type: + - string + - "null" + reason_for_recall: + type: + - string + - "null" + recall_initiation_date: + type: + - string + - "null" + recall_number: + type: + - string + - "null" + recalling_firm: + type: + - string + - "null" + report_date: + type: + - string + - "null" + state: + type: + - string + - "null" + status: + type: + - string + - "null" + termination_date: + type: + - string + - "null" + voluntary_mandated: + type: + - string + - "null" + drugs: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + application_number: + type: + - string + - "null" + openfda: + type: + - object + - "null" + properties: + application_number: + type: + - array + - "null" + items: + type: + - string + - "null" + brand_name: + type: + - array + - "null" + items: + type: + - string + - "null" + generic_name: + type: + - array + - "null" + items: + type: + - string + - "null" + manufacturer_name: + type: + - array + - "null" + items: + type: + - string + - "null" + nui: + type: + - array + - "null" + items: + type: + - string + - "null" + package_ndc: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_cs: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_epc: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_moa: + type: + - array + - "null" + items: + type: + - string + - "null" + pharm_class_pe: + type: + - array + - "null" + items: + type: + - string + - "null" + product_ndc: + type: + - array + - "null" + items: + type: + - string + - "null" + product_type: + type: + - array + - "null" + items: + type: + - string + - "null" + route: + type: + - array + - "null" + items: + type: + - string + - "null" + rxcui: + type: + - array + - "null" + items: + type: + - string + - "null" + spl_id: + type: + - array + - "null" + items: + type: + - string + - "null" + spl_set_id: + type: + - array + - "null" + items: + type: + - string + - "null" + substance_name: + type: + - array + - "null" + items: + type: + - string + - "null" + unii: + type: + - array + - "null" + items: + type: + - string + - "null" + products: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + active_ingredients: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + strength: + type: + - string + - "null" + brand_name: + type: + - string + - "null" + dosage_form: + type: + - string + - "null" + marketing_status: + type: + - string + - "null" + product_number: + type: + - string + - "null" + reference_drug: + type: + - string + - "null" + reference_standard: + type: + - string + - "null" + route: + type: + - string + - "null" + te_code: + type: + - string + - "null" + sponsor_name: + type: + - string + - "null" + submissions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + application_docs: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + date: + type: + - string + - "null" + id: + type: + - string + - "null" + title: + type: + - string + - "null" + url: + type: + - string + - "null" + review_priority: + type: + - string + - "null" + submission_class_code: + type: + - string + - "null" + submission_class_code_description: + type: + - string + - "null" + submission_number: + type: + - string + - "null" + submission_property_type: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + code: + type: + - string + - "null" + submission_public_notes: + type: + - string + - "null" + submission_status: + type: + - string + - "null" + submission_status_date: + type: + - string + - "null" + submission_type: + type: + - string + - "null" diff --git a/airbyte-integrations/connectors/source-openfda/metadata.yaml b/airbyte-integrations/connectors/source-openfda/metadata.yaml new file mode 100644 index 000000000000..fadec40bbfda --- /dev/null +++ b/airbyte-integrations/connectors/source-openfda/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.fda.gov" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-openfda + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: b97d588f-d49f-440c-9158-9dd33c59fd26 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-openfda + githubIssueLabel: source-openfda + icon: icon.svg + license: MIT + name: OpenFDA + releaseDate: 2024-10-23 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/openfda + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-openweather/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-openweather/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-openweather/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-openweather/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-openweather/metadata.yaml b/airbyte-integrations/connectors/source-openweather/metadata.yaml index 60cd633a95d3..6830e3b82639 100644 --- a/airbyte-integrations/connectors/source-openweather/metadata.yaml +++ b/airbyte-integrations/connectors/source-openweather/metadata.yaml @@ -3,11 +3,11 @@ data: hosts: - api.openweathermap.org connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 561d7787-b45e-4f3b-af58-0163c3ba9d5a - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.7 dockerRepository: airbyte/source-openweather documentationUrl: https://docs.airbyte.com/integrations/sources/openweather githubIssueLabel: source-openweather diff --git a/airbyte-integrations/connectors/source-opinion-stage/README.md b/airbyte-integrations/connectors/source-opinion-stage/README.md new file mode 100644 index 000000000000..c06b9c18525e --- /dev/null +++ b/airbyte-integrations/connectors/source-opinion-stage/README.md @@ -0,0 +1,33 @@ +# Opinion Stage +This directory contains the manifest-only connector for `source-opinion-stage`. + +The Airbyte connector for [OpinionStage](https://opinionstage.com) enables seamless data integration from the OpinionStage platform, facilitating the extraction of interactive content data. It streams data from items such as forms, quizzes, and polls, as well as capturing responses and specific questions associated with each item. This connector is ideal for users looking to analyze audience engagement, response patterns, and question insights from OpinionStage in their data workflows. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-opinion-stage:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-opinion-stage build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-opinion-stage test +``` + diff --git a/airbyte-integrations/connectors/source-opinion-stage/acceptance-test-config.yml b/airbyte-integrations/connectors/source-opinion-stage/acceptance-test-config.yml new file mode 100644 index 000000000000..79a9b22a7452 --- /dev/null +++ b/airbyte-integrations/connectors/source-opinion-stage/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-opinion-stage:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-opinion-stage/icon.svg b/airbyte-integrations/connectors/source-opinion-stage/icon.svg new file mode 100644 index 000000000000..3d3e6495de9c --- /dev/null +++ b/airbyte-integrations/connectors/source-opinion-stage/icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/airbyte-integrations/connectors/source-opinion-stage/manifest.yaml b/airbyte-integrations/connectors/source-opinion-stage/manifest.yaml new file mode 100644 index 000000000000..5e03bffe02b7 --- /dev/null +++ b/airbyte-integrations/connectors/source-opinion-stage/manifest.yaml @@ -0,0 +1,429 @@ +version: 6.1.0 + +type: DeclarativeSource + +description: >- + The Airbyte connector for [OpinionStage](https://opinionstage.com) enables + seamless data integration from the OpinionStage platform, facilitating the + extraction of interactive content data. It streams data from items such as + forms, quizzes, and polls, as well as capturing responses and specific + questions associated with each item. This connector is ideal for users looking + to analyze audience engagement, response patterns, and question insights from + OpinionStage in their data workflows. + +check: + type: CheckStream + stream_names: + - items + +definitions: + streams: + items: + type: DeclarativeStream + name: items + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/items + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page[number] + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: page[size] + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 50 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/items" + responses: + type: DeclarativeStream + name: responses + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/items/{{ stream_partition.item_id }}/responses + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page[number] + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: page[size] + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 50 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: item_id + stream: + $ref: "#/definitions/streams/items" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/responses" + questions: + type: DeclarativeStream + name: questions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/items/{{ stream_partition.item_id }}/questions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page[number] + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: page[size] + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 50 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: item_id + stream: + $ref: "#/definitions/streams/items" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/questions" + base_requester: + type: HttpRequester + url_base: https://api.opinionstage.com + authenticator: + type: BasicHttpAuthenticator + username: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/items" + - $ref: "#/definitions/streams/responses" + - $ref: "#/definitions/streams/questions" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + title: API Key + airbyte_secret: true + order: 0 + additionalProperties: true + +metadata: + autoImportSchema: + items: true + responses: true + questions: true + yamlComponents: + global: + - authenticator + testedStreams: + items: + streamHash: 3eb9bbc141d2ba106b4814eb8dd7dd2243565ab6 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + responses: + streamHash: 931591907dcd96ac607fe6c058b59ab70fe9590c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + questions: + streamHash: ac650cec34e18e6e4717c41725e1c16fa5469aac + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://api.opinionstage.com/api-docs/index.html + +schemas: + items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + attributes: + type: + - object + - "null" + properties: + embed: + type: + - object + - "null" + properties: + iframe: + type: + - string + - "null" + script: + type: + - string + - "null" + status: + type: + - string + - "null" + timestamps: + type: + - object + - "null" + properties: + created: + type: + - string + - "null" + modified: + type: + - string + - "null" + title: + type: + - string + - "null" + id: + type: string + links: + type: + - object + - "null" + properties: + edit: + type: + - string + - "null" + iframe: + type: + - string + - "null" + landing: + type: + - string + - "null" + results: + type: + - string + - "null" + self: + type: + - string + - "null" + relationships: + type: + - object + - "null" + properties: + questions: + type: + - object + - "null" + properties: + links: + type: + - object + - "null" + properties: + related: + type: + - string + - "null" + required: + - id + responses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + attributes: + type: + - object + - "null" + properties: + answers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + question: + type: + - string + - "null" + selection: + type: + - array + - "null" + items: + type: + - string + - "null" + result: + type: + - object + - "null" + properties: + text: + type: + - string + - "null" + title: + type: + - string + - "null" + timestamps: + type: + - object + - "null" + properties: + created: + type: + - string + - "null" + timings: + type: + - object + - "null" + properties: + duration: + type: + - number + - "null" + utm: + type: + - object + - "null" + properties: {} + id: + type: string + links: + type: + - object + - "null" + properties: + hosting: + type: + - string + - "null" + self: + type: + - string + - "null" + required: + - id + questions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + attributes: + type: + - object + - "null" + properties: + kind: + type: + - string + - "null" + lead: + type: + - boolean + - "null" + timestamps: + type: + - object + - "null" + properties: + created: + type: + - string + - "null" + modified: + type: + - string + - "null" + title: + type: + - string + - "null" + id: + type: string + required: + - id diff --git a/airbyte-integrations/connectors/source-opinion-stage/metadata.yaml b/airbyte-integrations/connectors/source-opinion-stage/metadata.yaml new file mode 100644 index 000000000000..9af9271ba9ff --- /dev/null +++ b/airbyte-integrations/connectors/source-opinion-stage/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.opinionstage.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-opinion-stage + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 2718eb27-a931-450d-91b2-8bc084f341e7 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-opinion-stage + githubIssueLabel: source-opinion-stage + icon: icon.svg + license: MIT + name: Opinion Stage + releaseDate: 2024-10-31 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/opinion-stage + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-opsgenie/metadata.yaml b/airbyte-integrations/connectors/source-opsgenie/metadata.yaml index 17d09538b8c5..17b40e918270 100644 --- a/airbyte-integrations/connectors/source-opsgenie/metadata.yaml +++ b/airbyte-integrations/connectors/source-opsgenie/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.11.1@sha256:0d0f562a70c0ed19ab605f0c83802a2e052712587692e2f3a1cc794fe7cd7007 connectorSubtype: api connectorType: source definitionId: 06bdb480-2598-40b8-8b0f-fc2e2d2abdda - dockerImageTag: 0.4.3 + dockerImageTag: 0.4.5 dockerRepository: airbyte/source-opsgenie documentationUrl: https://docs.airbyte.com/integrations/sources/opsgenie githubIssueLabel: source-opsgenie diff --git a/airbyte-integrations/connectors/source-oracle-strict-encrypt/metadata.yaml b/airbyte-integrations/connectors/source-oracle-strict-encrypt/metadata.yaml index f7f9c7681efd..d996ca5b68e3 100644 --- a/airbyte-integrations/connectors/source-oracle-strict-encrypt/metadata.yaml +++ b/airbyte-integrations/connectors/source-oracle-strict-encrypt/metadata.yaml @@ -3,25 +3,27 @@ data: hosts: - ${host} - ${tunnel_method.tunnel_host} - registryOverrides: - cloud: - enabled: false # strict encrypt connectors are deployed to Cloud by their non strict encrypt sibling. - oss: - enabled: false # strict encrypt connectors are not used on OSS. + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a connectorSubtype: database + connectorTestSuitesOptions: + - suite: unitTests + - suite: integrationTests connectorType: source definitionId: b39a7370-74c3-45a6-ac3a-380d48520a83 - dockerImageTag: 0.5.2 + dockerImageTag: 0.5.3 dockerRepository: airbyte/source-oracle-strict-encrypt + documentationUrl: https://docs.airbyte.com/integrations/sources/oracle githubIssueLabel: source-oracle icon: oracle.svg license: ELv2 name: Oracle DB + registryOverrides: + cloud: + enabled: false + oss: + enabled: false releaseStage: alpha - documentationUrl: https://docs.airbyte.com/integrations/sources/oracle tags: - language:java - connectorTestSuitesOptions: - - suite: unitTests - - suite: integrationTests metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-oracle/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-oracle/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-oracle/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-oracle/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-oracle/metadata.yaml b/airbyte-integrations/connectors/source-oracle/metadata.yaml index 40f10e106b02..c8fc9af90f4d 100644 --- a/airbyte-integrations/connectors/source-oracle/metadata.yaml +++ b/airbyte-integrations/connectors/source-oracle/metadata.yaml @@ -6,10 +6,21 @@ data: hosts: - ${host} - ${tunnel_method.tunnel_host} + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a connectorSubtype: database + connectorTestSuitesOptions: + - suite: unitTests + - suite: integrationTests + testSecrets: + - fileName: performance-config.json + name: SECRET_SOURCE_ORACLE_PERFORMANCE_TEST_CREDS + secretStore: + alias: airbyte-connector-testing-secret-store + type: GSM connectorType: source definitionId: b39a7370-74c3-45a6-ac3a-380d48520a83 - dockerImageTag: 0.5.2 + dockerImageTag: 0.5.3 dockerRepository: airbyte/source-oracle documentationUrl: https://docs.airbyte.com/integrations/sources/oracle githubIssueLabel: source-oracle @@ -18,7 +29,7 @@ data: name: Oracle DB registryOverrides: cloud: - dockerImageTag: 0.5.2 + dockerImageTag: 0.5.3 dockerRepository: airbyte/source-oracle-strict-encrypt enabled: true oss: @@ -27,13 +38,4 @@ data: supportLevel: community tags: - language:java - connectorTestSuitesOptions: - - suite: unitTests - - suite: integrationTests - testSecrets: - - name: SECRET_SOURCE_ORACLE_PERFORMANCE_TEST_CREDS - fileName: performance-config.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-orb/README.md b/airbyte-integrations/connectors/source-orb/README.md index 6fba4ce53be9..e77a5faa3c25 100644 --- a/airbyte-integrations/connectors/source-orb/README.md +++ b/airbyte-integrations/connectors/source-orb/README.md @@ -1,89 +1,63 @@ # Orb source connector +This directory contains the manifest-only connector for `source-orb`. +This _manifest-only_ connector is not a Python package on its own, as it runs inside of the base `source-declarative-manifest` image. -This is the repository for the Orb configuration based source connector. -For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.com/integrations/sources/orb). +For information about how to configure and use this connector within Airbyte, see [the connector's full documentation](https://docs.airbyte.com/integrations/sources/orb). ## Local development -### Prerequisites -* Python (~=3.9) -* Poetry (~=1.7) - installation instructions [here](https://python-poetry.org/docs/#installation) +We recommend using the Connector Builder to edit this connector. +Using either Airbyte Cloud or your local Airbyte OSS instance, navigate to the **Builder** tab and select **Import a YAML**. +Then select the connector's `manifest.yaml` file to load the connector into the Builder. You're now ready to make changes to the connector! +If you prefer to develop locally, you can follow the instructions below. -### Installing the connector -From this connector directory, run: -```bash -poetry install --with dev -``` - - -### Create credentials -**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/orb) -to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_orb/spec.yaml` file. -Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. -See `integration_tests/sample_config.json` for a sample config file. - - -### Locally running the connector -``` -poetry run source-orb spec -poetry run source-orb check --config secrets/config.json -poetry run source-orb discover --config secrets/config.json -poetry run source-orb read --config secrets/config.json --catalog integration_tests/configured_catalog.json -``` +### Building the docker image -### Running unit tests -To run unit tests locally, from the connector directory run: -``` -poetry run pytest unit_tests -``` +You can build any manifest-only connector with `airbyte-ci`: -### Building the docker image 1. Install [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md) 2. Run the following command to build the docker image: + ```bash airbyte-ci connectors --name=source-orb build ``` An image will be available on your host with the tag `airbyte/source-orb:dev`. +### Creating credentials + +**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/orb) +to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `spec` object in the connector's `manifest.yaml` file. +Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. ### Running as a docker container -Then run any of the connector commands as follows: -``` + +Then run any of the standard source connector commands: + +```bash docker run --rm airbyte/source-orb:dev spec docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-orb:dev check --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-orb:dev discover --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-orb:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json ``` -### Running our CI test suite -You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): -```bash -airbyte-ci connectors --name=source-orb test -``` +### Running the CI test suite -### Customizing acceptance Tests -Customize `acceptance-test-config.yml` file to configure acceptance tests. See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) for more information. -If your connector requires to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py. +You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): -### Dependency Management -All of your dependencies should be managed via Poetry. -To add a new dependency, run: ```bash -poetry add +airbyte-ci connectors --name=source-orb test ``` -Please commit the changes to `pyproject.toml` and `poetry.lock` files. - ## Publishing a new version of the connector -You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what? -1. Make sure your changes are passing our test suite: `airbyte-ci connectors --name=source-orb test` -2. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): + +If you want to contribute changes to `source-orb`, here's how you can do that: +1. Make your changes locally, or load the connector's manifest into Connector Builder and make changes there. +2. Make sure your changes are passing our test suite with `airbyte-ci connectors --name=source-orb test` +3. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): - bump the `dockerImageTag` value in in `metadata.yaml` - - bump the `version` value in `pyproject.toml` -3. Make sure the `metadata.yaml` content is up to date. 4. Make sure the connector documentation and its changelog is up to date (`docs/integrations/sources/orb.md`). 5. Create a Pull Request: use [our PR naming conventions](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#pull-request-title-convention). 6. Pat yourself on the back for being an awesome contributor. diff --git a/airbyte-integrations/connectors/source-orb/acceptance-test-config.yml b/airbyte-integrations/connectors/source-orb/acceptance-test-config.yml index 4080daab6166..695e5467ba61 100644 --- a/airbyte-integrations/connectors/source-orb/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-orb/acceptance-test-config.yml @@ -3,7 +3,7 @@ connector_image: airbyte/source-orb:dev tests: spec: - - spec_path: "source_orb/spec.json" + - spec_path: "manifest.yaml" backward_compatibility_tests_config: disable_for_version: "0.1.4" connection: diff --git a/airbyte-integrations/connectors/source-orb/bootstrap.md b/airbyte-integrations/connectors/source-orb/bootstrap.md deleted file mode 100644 index 84b5a9bf260a..000000000000 --- a/airbyte-integrations/connectors/source-orb/bootstrap.md +++ /dev/null @@ -1,29 +0,0 @@ -## Streams - -Orb is a REST API. Connector has the following streams, and all of them support incremental refresh. - -- [Subscriptions](https://docs.withorb.com/reference/list-subscriptions) -- [Plans](https://docs.withorb.com/reference/list-plans) -- [Customers](https://docs.withorb.com/reference/list-customers) -- [Credits Ledger Entries](https://docs.withorb.com/reference/view-credits-ledger) -- [Invoices](https://docs.withorb.com/docs/orb-docs/api-reference/schemas/invoice) - -Note that the Credits Ledger Entries must read all Customers for an incremental sync, but will only incrementally return new ledger entries for each customer. - -Since the Orb API does not allow querying objects based on `updated_at`, these incremental syncs will capture updates to newly created objects but not resources updated after object creation. Use a full resync in order to capture newly updated entries. - -## Pagination - -Orb's API uses cursor-based pagination, which is documented [here](https://docs.withorb.com/reference/pagination). - -## Enriching Credit Ledger entries - -The connector configuration includes two properties: `numeric_event_properties_keys` and `string_event_properties_keys`. - -When a ledger entry has an `event_id` attached to it (e.g. an automated decrement), the connector will make a follow-up request to enrich those entries with event properties corresponding to the keys provided. The connector assumes (and generates schema) that property values corresponding to the keys listed in `numeric_event_properties_keys` are numeric, and the property values corresponding to the keys listed in `string_event_properties_keys` are string typed. - -## Authentication - -This connector authenticates against the Orb API with an API key that can be issued via the Orb Admin Console. - -Please reach out to the Orb team at [team@withorb.com](mailto:team@withorb.com) to request an Orb Account and API Key. diff --git a/airbyte-integrations/connectors/source-orb/components.py b/airbyte-integrations/connectors/source-orb/components.py new file mode 100644 index 000000000000..cf349c394936 --- /dev/null +++ b/airbyte-integrations/connectors/source-orb/components.py @@ -0,0 +1,117 @@ +# +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. +# + +from dataclasses import dataclass +from typing import Iterable, Optional + +from airbyte_cdk.models import SyncMode +from airbyte_cdk.sources.declarative.stream_slicers.stream_slicer import StreamSlicer +from airbyte_cdk.sources.declarative.transformations.transformation import RecordTransformation +from airbyte_cdk.sources.declarative.types import Config, Record, StreamSlice, StreamState +from airbyte_cdk.sources.streams.core import Stream + + +@dataclass +class SubscriptionUsageTransformation(RecordTransformation): + subscription_id: str + + def transform( + self, + record: Record, + config: Optional[Config] = None, + stream_state: Optional[StreamState] = None, + stream_slice: Optional[StreamSlice] = None, + ) -> Record: + # for each top level response record, there can be multiple sub-records depending + # on granularity and other input params. This function yields one transformed record + # for each subrecord in the response. + + subrecords = record.get("usage", []) + del record["usage"] + for subrecord in subrecords: + # skip records that don't contain any actual usage + if subrecord.get("quantity", 0) > 0: + # Merge the parent record with the sub record + output = record.update(subrecord) + + # Add the subscription ID to the output + output["subscription_id"] = self.subscription_id + + # Un-nest billable_metric -> name,id into billable_metric_name and billable_metric_id + nested_billable_metric_name = output["billable_metric"]["name"] + nested_billable_metric_id = output["billable_metric"]["id"] + del output["billable_metric"] + output["billable_metric_name"] = nested_billable_metric_name + output["billable_metric_id"] = nested_billable_metric_id + + # If a group_by key is specified, un-nest it + if config.subscription_usage_grouping_key: + nested_key = output["metric_group"]["property_key"] + nested_value = output["metric_group"]["property_value"] + del output["metric_group"] + output[nested_key] = nested_value + yield output + yield from [] + + +@dataclass +class SubscriptionUsagePartitionRouter(StreamSlicer): + plans_stream: Stream + subscriptions_stream: Stream + config: Config + + def stream_slices(self) -> Iterable[StreamSlice]: + """ + This stream is sliced per `subscription_id` and day, as well as `billable_metric_id` + if a grouping key is provided. This is because the API only supports a + single billable_metric_id per API call when using a group_by param. + + """ + slice_yielded = False + subscriptions_stream = self.subscriptions_stream + plans_stream = self.plans_stream + + # if using a group_by key, populate prices_by_plan_id so that each + # billable metric will get its own slice + if self.config.get("subscription_usage_grouping_key"): + metric_ids_by_plan_id = {} + + for plan in plans_stream.read_records(sync_mode=SyncMode.full_refresh): + # if a plan_id filter is specified, skip any plan that doesn't match + if self.config.get("plan_id") and plan["id"] != self.config.get("plan_id"): + continue + + prices = plan.get("prices", []) + metric_ids_by_plan_id[plan["id"]] = [(price.get("billable_metric") or {}).get("id") for price in prices] + + for subscription in subscriptions_stream.read_records(sync_mode=SyncMode.full_refresh): + subscription_id = subscription["id"] + subscription_plan_id = subscription["plan_id"] + + # if filtering subscription usage by plan ID, skip any subscription that doesn't match the plan_id + if self.config.get("plan_id") and subscription_plan_id != self.config.get("plan_id"): + continue + + slice = { + "subscription_id": subscription_id, + } + + # if using a group_by key, yield one slice per billable_metric_id. + # otherwise, yield slices without a billable_metric_id because + # each API call will return usage broken down by billable metric + # when grouping isn't used. + if self.config.get("subscription_usage_grouping_key"): + metric_ids = metric_ids_by_plan_id.get(subscription_plan_id) + if metric_ids is not None: + for metric_id in metric_ids: + # self.logger.warning("stream_slices is about to yield the following slice: %s", slice) + yield {**slice, "billable_metric_id": metric_id} + slice_yielded = True + else: + # self.logger.warning("stream_slices is about to yield the following slice: %s", slice) + yield slice + slice_yielded = True + if not slice_yielded: + # yield an empty slice to checkpoint state later + yield {} diff --git a/airbyte-integrations/connectors/source-orb/integration_tests/abnormal_state.json b/airbyte-integrations/connectors/source-orb/integration_tests/abnormal_state.json index 4d16164bd3e0..07a961d21360 100644 --- a/airbyte-integrations/connectors/source-orb/integration_tests/abnormal_state.json +++ b/airbyte-integrations/connectors/source-orb/integration_tests/abnormal_state.json @@ -1,14 +1,46 @@ -{ - "customers": { - "created_at": "2122-01-01T00:00:00+00:00" +[ + { + "type": "STREAM", + "stream": { + "stream_state": { + "created_at": "2122-01-01T00:00:00+00:00" + }, + "stream_descriptor": { + "name": "customers" + } + } }, - "plans": { - "created_at": "2122-01-01T00:00:00+00:00" + { + "type": "STREAM", + "stream": { + "stream_state": { + "created_at": "2122-01-01T00:00:00+00:00" + }, + "stream_descriptor": { + "name": "plans" + } + } }, - "subscriptions": { - "created_at": "2122-01-01T00:00:00+00:00" + { + "type": "STREAM", + "stream": { + "stream_state": { + "created_at": "2122-01-01T00:00:00+00:00" + }, + "stream_descriptor": { + "name": "subscriptions" + } + } }, - "invoices": { - "invoice_date": "2122-01-01T00:00:00+00:00" + { + "type": "STREAM", + "stream": { + "stream_state": { + "invoice_date": "2122-01-01T00:00:00+00:00" + }, + "stream_descriptor": { + "name": "invoices" + } + } } -} +] diff --git a/airbyte-integrations/connectors/source-orb/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-orb/integration_tests/acceptance.py index efc25f08ce82..78b220cebb18 100644 --- a/airbyte-integrations/connectors/source-orb/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-orb/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-orb/main.py b/airbyte-integrations/connectors/source-orb/main.py deleted file mode 100644 index 55d51ff75b4a..000000000000 --- a/airbyte-integrations/connectors/source-orb/main.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from source_orb.run import run - -if __name__ == "__main__": - run() diff --git a/airbyte-integrations/connectors/source-orb/manifest.yaml b/airbyte-integrations/connectors/source-orb/manifest.yaml new file mode 100644 index 000000000000..e3fb4e919fad --- /dev/null +++ b/airbyte-integrations/connectors/source-orb/manifest.yaml @@ -0,0 +1,3368 @@ +version: 4.3.2 +type: DeclarativeSource +check: + type: CheckStream + stream_names: + - subscriptions +definitions: + selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", {}) }} + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%dT%H:%M:%S.%fZ" + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_at[gte] + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ config['end_date'] if config['end_date'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') + }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: created_at[lte] + inject_into: request_parameter + customers_stream: + type: DeclarativeStream + name: customers + primary_key: id + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: customers + request_parameters: {} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", {}) + }} + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + additionalProperties: true + properties: + id: + description: The unique identifier of the customer. + type: string + external_customer_id: + description: The ID of the customer in an external system. + type: + - string + - "null" + name: + description: The name of the customer. + type: string + email: + description: The email address of the customer. + type: + - string + - "null" + created_at: + description: The date and time when the customer account was created. + type: + - "null" + - string + format: date-time + payment_provider: + description: The payment provider used by the customer. + type: + - "null" + - string + payment_provider_id: + description: The ID of the customer in the payment provider's system. + type: + - "null" + - string + timezone: + description: The timezone setting of the customer. + type: + - "null" + - string + shipping_address: + description: The shipping address of the customer. + type: + - "null" + - object + properties: + city: + description: The city of the shipping address. + type: + - "null" + - string + country: + description: The country of the shipping address. + type: + - "null" + - string + line1: + description: The first line in the shipping address. + type: + - "null" + - string + line2: + description: The second line in the shipping address if applicable. + type: + - "null" + - string + postal_code: + description: The postal code of the shipping address. + type: + - "null" + - string + state: + description: The state or region of the shipping address. + type: + - "null" + - string + billing_address: + description: The billing address of the customer. + type: + - "null" + - object + properties: + city: + description: The city of the billing address. + type: + - "null" + - string + country: + description: The country of the billing address. + type: + - "null" + - string + line1: + description: The first line in the billing address. + type: + - "null" + - string + line2: + description: The second line in the billing address if applicable. + type: + - "null" + - string + postal_code: + description: The postal code of the billing address. + type: + - "null" + - string + state: + description: The state or region of the billing address. + type: + - "null" + - string + required: + - id + - created_at + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%dT%H:%M:%S.%fZ" + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_at[gte] + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ config['end_date'] if config['end_date'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') + }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: created_at[lte] + inject_into: request_parameter + subscriptions_stream: + type: DeclarativeStream + name: subscriptions + primary_key: id + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: subscriptions + request_parameters: {} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", {}) + }} + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + additionalProperties: true + properties: + id: + description: The unique identifier of the subscription. + type: string + created_at: + description: The date and time when the subscription was created. + type: + - "null" + - string + format: date-time + customer_id: + description: The unique identifier of the customer associated with the + subscription. + type: string + external_customer_id: + description: The external identifier of the customer associated with the + subscription. + type: + - "null" + - string + start_date: + description: The date and time when the subscription is set to start. + type: + - "null" + - string + format: date-time + end_date: + description: The date and time when the subscription is set to end. + type: + - "null" + - string + format: date-time + plan_id: + description: >- + The unique identifier of the subscription plan assigned to the + subscription. + type: string + status: + description: The current status of the subscription. + type: string + required: + - id + - created_at + transformations: + - type: AddFields + fields: + - path: + - customer_id + value: "{{ record['customer']['id'] }}" + - type: AddFields + fields: + - path: + - external_customer_id + value: "{{ record['customer']['external_customer_id'] }}" + - type: RemoveFields + field_pointers: + - - customer + - type: AddFields + fields: + - path: + - plan_id + value: "{{ record['plan']['id'] }}" + - type: RemoveFields + field_pointers: + - - plan + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%dT%H:%M:%S.%fZ" + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_at[gte] + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ config['end_date'] if config['end_date'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') + }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: created_at[lte] + inject_into: request_parameter + plans_stream: + type: DeclarativeStream + name: plans + primary_key: id + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: plans + request_parameters: {} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", {}) + }} + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + properties: + id: + description: The unique identifier of the plan + type: string + created_at: + description: The timestamp of when the plan was created + type: + - "null" + - string + format: date-time + description: + description: A short description of the plan + type: + - "null" + - string + name: + description: The name of the plan + type: + - "null" + - string + prices: + description: An array of pricing options for the plan + type: + - array + items: + type: object + properties: + id: + description: The unique identifier of the price option + type: string + product: + description: The product to which the plan belongs + type: object + properties: + id: + description: The unique identifier of the product + type: string + required: + - id + - created_at + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%dT%H:%M:%S.%fZ" + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_at[gte] + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ config['end_date'] if config['end_date'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') + }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: created_at[lte] + inject_into: request_parameter + invoices_stream: + type: DeclarativeStream + name: invoices + primary_key: id + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: invoices + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", {}) + }} + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + properties: + id: + description: The unique identifier of the invoice. + type: string + created_at: + description: The date and time when the invoice was created. + type: + - "null" + - string + format: date-time + invoice_date: + description: The date when the invoice was issued. + type: + - string + format: date-time + due_date: + description: The due date for the payment of the invoice. + type: + - string + format: date-time + invoice_pdf: + description: The URL to download the PDF version of the invoice. + type: + - "null" + - string + subtotal: + description: The subtotal amount before applying taxes or discounts. + type: + - string + total: + description: The total amount of the invoice including all charges. + type: + - string + amount_due: + description: The total amount due on the invoice. + type: + - string + status: + description: "The current status of the invoice (e.g., pending, paid, + voided)." + type: + - string + memo: + description: Any additional notes or comments associated with the invoice. + type: + - "null" + - string + issue_failed_at: + description: The date and time when issuing the invoice failed. + type: + - "null" + - string + format: date-time + sync_failed_at: + description: The date and time when syncing the invoice data failed. + type: + - "null" + - string + format: date-time + payment_failed_at: + description: The date and time when the payment for the invoice failed. + type: + - "null" + - string + format: date-time + payment_started_at: + description: The date and time when the payment process started for the + invoice. + type: + - "null" + - string + format: date-time + voided_at: + description: The date and time when the invoice was voided. + type: + - "null" + - string + format: date-time + paid_at: + description: The date and time when the invoice was paid. + type: + - "null" + - string + format: date-time + issued_at: + description: The date and time when the invoice was issued. + type: + - "null" + - string + format: date-time + hosted_invoice_url: + description: The URL to view the hosted invoice online. + type: + - "null" + - string + line_items: + description: The line items included in the invoice. + type: + - array + items: + type: object + properties: + id: + description: The unique identifier of the line item. + type: string + quantity: + description: The quantity of the item included in the invoice. + type: number + amount: + description: The amount for the line item. + type: string + name: + description: The name or description of the line item. + type: string + start_date: + description: The start date of the service period for the line item. + type: + - "null" + - string + format: date-time + end_date: + description: The end date of the service period for the line item. + type: + - "null" + - string + format: date-time + subscription: + description: Information about the subscription associated with the invoice. + type: + - object + - "null" + properties: + id: + description: The unique identifier of the subscription. + type: string + required: + - id + - created_at + incremental_sync: + type: DatetimeBasedCursor + cursor_field: invoice_date + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S+00:00" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: invoice_date[gte] + inject_into: request_parameter + partition_router: + - type: ListPartitionRouter + values: + - void + - paid + - issued + - synced + cursor_field: status + request_option: + type: RequestOption + inject_into: request_parameter + field_name: status[] + credits_ledger_entries_stream: + type: DeclarativeStream + name: credits_ledger_entries + primary_key: id + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: customers/{{ stream_partition.customer_id }}/credits/ledger + request_parameters: + entry_status: committed + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", {}) + }} + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: customer_id + stream: + type: DeclarativeStream + name: customers + primary_key: id + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: customers + request_parameters: {} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", + {}) }} + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + additionalProperties: true + properties: + id: + description: The unique identifier of the customer. + type: string + external_customer_id: + description: The ID of the customer in an external system. + type: + - string + - "null" + name: + description: The name of the customer. + type: string + email: + description: The email address of the customer. + type: + - string + - "null" + created_at: + description: The date and time when the customer account was created. + type: + - "null" + - string + format: date-time + payment_provider: + description: The payment provider used by the customer. + type: + - "null" + - string + payment_provider_id: + description: The ID of the customer in the payment provider's + system. + type: + - "null" + - string + timezone: + description: The timezone setting of the customer. + type: + - "null" + - string + shipping_address: + description: The shipping address of the customer. + type: + - "null" + - object + properties: + city: + description: The city of the shipping address. + type: + - "null" + - string + country: + description: The country of the shipping address. + type: + - "null" + - string + line1: + description: The first line in the shipping address. + type: + - "null" + - string + line2: + description: The second line in the shipping address if applicable. + type: + - "null" + - string + postal_code: + description: The postal code of the shipping address. + type: + - "null" + - string + state: + description: The state or region of the shipping address. + type: + - "null" + - string + billing_address: + description: The billing address of the customer. + type: + - "null" + - object + properties: + city: + description: The city of the billing address. + type: + - "null" + - string + country: + description: The country of the billing address. + type: + - "null" + - string + line1: + description: The first line in the billing address. + type: + - "null" + - string + line2: + description: The second line in the billing address if applicable. + type: + - "null" + - string + postal_code: + description: The postal code of the billing address. + type: + - "null" + - string + state: + description: The state or region of the billing address. + type: + - "null" + - string + required: + - id + - created_at + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%dT%H:%M:%S.%fZ" + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_at[gte] + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ config['end_date'] if config['end_date'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') + }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: created_at[lte] + inject_into: request_parameter + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + properties: + id: + description: The unique ID of the ledger entry + type: string + starting_balance: + description: The starting balance before the ledger entry + type: number + ending_balance: + description: The ending balance after the ledger entry + type: number + amount: + description: The amount of credits involved in the ledger entry + type: + - "null" + - number + block_expiry_date: + description: The date and time when the credit block will expire + type: + - "null" + - string + format: date-time + created_at: + description: The date and time when the ledger entry was created + type: + - "null" + - string + format: date-time + entry_type: + description: "The type of ledger entry (e.g., debit, credit)" + type: string + new_block_expiry_date: + description: The new expiry date and time of the credit block after the + ledger entry + type: + - "null" + - string + format: date-time + customer_id: + description: The ID of the customer associated with the ledger entry + type: string + credit_block_per_unit_cost_basis: + description: The cost per unit of the credit block + type: + - "null" + - number + description: + description: A description of the ledger entry + type: + - "null" + - string + credit_block_id: + description: The ID of the associated credit block + type: + - "null" + - string + required: + - id + - created_at + - customer_id + - credit_block_id + transformations: + - type: AddFields + fields: + - path: + - customer_id + value: "{{ record['customer']['id'] }}" + - type: RemoveFields + field_pointers: + - - customer + - type: AddFields + fields: + - path: + - block_expiry_date + value: "{{ record['credit_block']['expiry_date'] }}" + - type: AddFields + fields: + - path: + - credit_block_id + value: "{{ record['credit_block']['id'] }}" + - type: AddFields + fields: + - path: + - credit_block_per_unit_cost_basis + value: "{{ record['credit_block']['per_unit_cost_basis'] }}" + - type: RemoveFields + field_pointers: + - - credit_block + - type: AddFields + fields: + - path: + - event + - id + value: "{{ record['event_id'] }}" + - type: RemoveFields + field_pointers: + - - event_id + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%dT%H:%M:%S.%fZ" + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_at[gte] + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ config['end_date'] if config['end_date'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') + }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: created_at[lte] + inject_into: request_parameter + subscription_usage_stream: + type: DeclarativeStream + name: subscription_usage + primary_key: + - subscription_id + - billable_metric_id + - timeframe_start + - grouping_key + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: subscriptions/{{ stream_partition.subscription_id }}/usage + request_parameters: + group_by: "{{ config.get('subscription_usage_grouping_key', '') }}" + granularity: day + billable_metric_id: "{{ stream_partition.billable_metric_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + - type: CustomPartitionRouter + class_name: source_declarative_manifest.components.SubscriptionUsagePartitionRouter + plans_stream: + type: DeclarativeStream + name: plans + primary_key: id + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: plans + request_parameters: {} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", + {}) }} + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + properties: + id: + description: The unique identifier of the plan + type: string + created_at: + description: The timestamp of when the plan was created + type: + - "null" + - string + format: date-time + description: + description: A short description of the plan + type: + - "null" + - string + name: + description: The name of the plan + type: + - "null" + - string + prices: + description: An array of pricing options for the plan + type: + - array + items: + type: object + properties: + id: + description: The unique identifier of the price option + type: string + product: + description: The product to which the plan belongs + type: object + properties: + id: + description: The unique identifier of the product + type: string + required: + - id + - created_at + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%dT%H:%M:%S.%fZ" + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_at[gte] + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ config['end_date'] if config['end_date'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') + }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: created_at[lte] + inject_into: request_parameter + subscriptions_stream: + type: DeclarativeStream + name: subscriptions + primary_key: id + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: subscriptions + request_parameters: {} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", + {}) }} + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + additionalProperties: true + properties: + id: + description: The unique identifier of the subscription. + type: string + created_at: + description: The date and time when the subscription was created. + type: + - "null" + - string + format: date-time + customer_id: + description: The unique identifier of the customer associated with + the subscription. + type: string + external_customer_id: + description: The external identifier of the customer associated + with the subscription. + type: + - "null" + - string + start_date: + description: The date and time when the subscription is set to start. + type: + - "null" + - string + format: date-time + end_date: + description: The date and time when the subscription is set to end. + type: + - "null" + - string + format: date-time + plan_id: + description: >- + The unique identifier of the subscription plan assigned to the + subscription. + type: string + status: + description: The current status of the subscription. + type: string + required: + - id + - created_at + transformations: + - type: AddFields + fields: + - path: + - customer_id + value: "{{ record['customer']['id'] }}" + - type: AddFields + fields: + - path: + - external_customer_id + value: "{{ record['customer']['external_customer_id'] }}" + - type: RemoveFields + field_pointers: + - - customer + - type: AddFields + fields: + - path: + - plan_id + value: "{{ record['plan']['id'] }}" + - type: RemoveFields + field_pointers: + - - plan + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%dT%H:%M:%S.%fZ" + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_at[gte] + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ config['end_date'] if config['end_date'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') + }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: created_at[lte] + inject_into: request_parameter + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + additionalProperties: true + properties: + quantity: + description: Quantity of the billable metric used during the specified + timeframe + type: number + timeframe_start: + description: Start timestamp of the timeframe during which the usage data + is captured + type: string + format: date-time + timeframe_end: + description: End timestamp of the timeframe during which the usage data + is captured + type: string + format: date-time + billable_metric_name: + description: Name of the billable metric associated with the subscription + usage + type: string + billable_metric_id: + description: >- + Unique identifier for the billable metric associated with the subscription + usage + type: string + subscription_id: + description: Unique identifier for the subscription the usage data belongs + to + type: string + grouping_key: + type: + - "null" + - string + required: + - timeframe_start + - timeframe_end + - billable_metric_id + - subscription_id + transformations: + - type: RemoveFields + field_pointers: + - - usage + - type: CustomTransformation + class_name: source_declarative_manifest.components.SubscriptionUsageTransformation + subscription_id: "{{ stream_partition.subscription_id }}" + - type: AddFields + fields: + - path: + - grouping_key + value: "{{ config.get('subscription_usage_grouping_key', '') }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: timeframe_start + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: timeframe_start + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: timeframe_end + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" +streams: +- type: DeclarativeStream + name: subscriptions + primary_key: id + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: subscriptions + request_parameters: {} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", {}) }} + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + additionalProperties: true + properties: + id: + description: The unique identifier of the subscription. + type: string + created_at: + description: The date and time when the subscription was created. + type: + - "null" + - string + format: date-time + customer_id: + description: The unique identifier of the customer associated with the subscription. + type: string + external_customer_id: + description: The external identifier of the customer associated with the + subscription. + type: + - "null" + - string + start_date: + description: The date and time when the subscription is set to start. + type: + - "null" + - string + format: date-time + end_date: + description: The date and time when the subscription is set to end. + type: + - "null" + - string + format: date-time + plan_id: + description: >- + The unique identifier of the subscription plan assigned to the + subscription. + type: string + status: + description: The current status of the subscription. + type: string + required: + - id + - created_at + transformations: + - type: AddFields + fields: + - path: + - customer_id + value: "{{ record['customer']['id'] }}" + type: AddedFieldDefinition + - type: AddFields + fields: + - path: + - external_customer_id + value: "{{ record['customer']['external_customer_id'] }}" + type: AddedFieldDefinition + - type: RemoveFields + field_pointers: + - - customer + - type: AddFields + fields: + - path: + - plan_id + value: "{{ record['plan']['id'] }}" + type: AddedFieldDefinition + - type: RemoveFields + field_pointers: + - - plan + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%dT%H:%M:%S.%fZ" + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_at[gte] + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ config['end_date'] if config['end_date'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') + }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: created_at[lte] + inject_into: request_parameter +- type: DeclarativeStream + name: customers + primary_key: id + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: customers + request_parameters: {} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", {}) }} + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + additionalProperties: true + properties: + id: + description: The unique identifier of the customer. + type: string + external_customer_id: + description: The ID of the customer in an external system. + type: + - string + - "null" + name: + description: The name of the customer. + type: string + email: + description: The email address of the customer. + type: + - string + - "null" + created_at: + description: The date and time when the customer account was created. + type: + - "null" + - string + format: date-time + payment_provider: + description: The payment provider used by the customer. + type: + - "null" + - string + payment_provider_id: + description: The ID of the customer in the payment provider's system. + type: + - "null" + - string + timezone: + description: The timezone setting of the customer. + type: + - "null" + - string + shipping_address: + description: The shipping address of the customer. + type: + - "null" + - object + properties: + city: + description: The city of the shipping address. + type: + - "null" + - string + country: + description: The country of the shipping address. + type: + - "null" + - string + line1: + description: The first line in the shipping address. + type: + - "null" + - string + line2: + description: The second line in the shipping address if applicable. + type: + - "null" + - string + postal_code: + description: The postal code of the shipping address. + type: + - "null" + - string + state: + description: The state or region of the shipping address. + type: + - "null" + - string + billing_address: + description: The billing address of the customer. + type: + - "null" + - object + properties: + city: + description: The city of the billing address. + type: + - "null" + - string + country: + description: The country of the billing address. + type: + - "null" + - string + line1: + description: The first line in the billing address. + type: + - "null" + - string + line2: + description: The second line in the billing address if applicable. + type: + - "null" + - string + postal_code: + description: The postal code of the billing address. + type: + - "null" + - string + state: + description: The state or region of the billing address. + type: + - "null" + - string + required: + - id + - created_at + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%dT%H:%M:%S.%fZ" + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_at[gte] + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ config['end_date'] if config['end_date'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') + }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: created_at[lte] + inject_into: request_parameter +- type: DeclarativeStream + name: subscription_usage + primary_key: + - subscription_id + - billable_metric_id + - timeframe_start + - grouping_key + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: subscriptions/{{ stream_partition.subscription_id }}/usage + request_parameters: + group_by: "{{ config.get('subscription_usage_grouping_key', '') }}" + granularity: day + billable_metric_id: "{{ stream_partition.billable_metric_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + - type: CustomPartitionRouter + class_name: source_declarative_manifest.components.SubscriptionUsagePartitionRouter + plans_stream: + type: DeclarativeStream + name: plans + primary_key: id + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: plans + request_parameters: {} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", + {}) }} + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + properties: + id: + description: The unique identifier of the plan + type: string + created_at: + description: The timestamp of when the plan was created + type: + - "null" + - string + format: date-time + description: + description: A short description of the plan + type: + - "null" + - string + name: + description: The name of the plan + type: + - "null" + - string + prices: + description: An array of pricing options for the plan + type: + - array + items: + type: object + properties: + id: + description: The unique identifier of the price option + type: string + product: + description: The product to which the plan belongs + type: object + properties: + id: + description: The unique identifier of the product + type: string + required: + - id + - created_at + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%dT%H:%M:%S.%fZ" + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_at[gte] + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ config['end_date'] if config['end_date'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') + }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: created_at[lte] + inject_into: request_parameter + subscriptions_stream: + type: DeclarativeStream + name: subscriptions + primary_key: id + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: subscriptions + request_parameters: {} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", + {}) }} + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + additionalProperties: true + properties: + id: + description: The unique identifier of the subscription. + type: string + created_at: + description: The date and time when the subscription was created. + type: + - "null" + - string + format: date-time + customer_id: + description: The unique identifier of the customer associated with + the subscription. + type: string + external_customer_id: + description: The external identifier of the customer associated with + the subscription. + type: + - "null" + - string + start_date: + description: The date and time when the subscription is set to start. + type: + - "null" + - string + format: date-time + end_date: + description: The date and time when the subscription is set to end. + type: + - "null" + - string + format: date-time + plan_id: + description: >- + The unique identifier of the subscription plan assigned to the + subscription. + type: string + status: + description: The current status of the subscription. + type: string + required: + - id + - created_at + transformations: + - type: AddFields + fields: + - path: + - customer_id + value: "{{ record['customer']['id'] }}" + type: AddedFieldDefinition + - type: AddFields + fields: + - path: + - external_customer_id + value: "{{ record['customer']['external_customer_id'] }}" + type: AddedFieldDefinition + - type: RemoveFields + field_pointers: + - - customer + - type: AddFields + fields: + - path: + - plan_id + value: "{{ record['plan']['id'] }}" + type: AddedFieldDefinition + - type: RemoveFields + field_pointers: + - - plan + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%dT%H:%M:%S.%fZ" + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_at[gte] + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ config['end_date'] if config['end_date'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') + }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: created_at[lte] + inject_into: request_parameter + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + additionalProperties: true + properties: + quantity: + description: Quantity of the billable metric used during the specified timeframe + type: number + timeframe_start: + description: Start timestamp of the timeframe during which the usage data + is captured + type: string + format: date-time + timeframe_end: + description: End timestamp of the timeframe during which the usage data + is captured + type: string + format: date-time + billable_metric_name: + description: Name of the billable metric associated with the subscription + usage + type: string + billable_metric_id: + description: >- + Unique identifier for the billable metric associated with the subscription + usage + type: string + subscription_id: + description: Unique identifier for the subscription the usage data belongs + to + type: string + grouping_key: + type: + - "null" + - string + required: + - timeframe_start + - timeframe_end + - billable_metric_id + - subscription_id + transformations: + - type: RemoveFields + field_pointers: + - - usage + - type: CustomTransformation + class_name: source_declarative_manifest.components.SubscriptionUsageTransformation + subscription_id: "{{ stream_partition.subscription_id }}" + - type: AddFields + fields: + - path: + - grouping_key + value: "{{ config.get('subscription_usage_grouping_key', '') }}" + type: AddedFieldDefinition + incremental_sync: + type: DatetimeBasedCursor + cursor_field: timeframe_start + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: timeframe_start + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: timeframe_end + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" +- type: DeclarativeStream + name: plans + primary_key: id + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: plans + request_parameters: {} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", {}) }} + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + properties: + id: + description: The unique identifier of the plan + type: string + created_at: + description: The timestamp of when the plan was created + type: + - "null" + - string + format: date-time + description: + description: A short description of the plan + type: + - "null" + - string + name: + description: The name of the plan + type: + - "null" + - string + prices: + description: An array of pricing options for the plan + type: + - array + items: + type: object + properties: + id: + description: The unique identifier of the price option + type: string + product: + description: The product to which the plan belongs + type: object + properties: + id: + description: The unique identifier of the product + type: string + required: + - id + - created_at + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%dT%H:%M:%S.%fZ" + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_at[gte] + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ config['end_date'] if config['end_date'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') + }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: created_at[lte] + inject_into: request_parameter +- type: DeclarativeStream + name: invoices + primary_key: id + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: invoices + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", {}) }} + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + properties: + id: + description: The unique identifier of the invoice. + type: string + created_at: + description: The date and time when the invoice was created. + type: + - "null" + - string + format: date-time + invoice_date: + description: The date when the invoice was issued. + type: + - string + format: date-time + due_date: + description: The due date for the payment of the invoice. + type: + - string + format: date-time + invoice_pdf: + description: The URL to download the PDF version of the invoice. + type: + - "null" + - string + subtotal: + description: The subtotal amount before applying taxes or discounts. + type: + - string + total: + description: The total amount of the invoice including all charges. + type: + - string + amount_due: + description: The total amount due on the invoice. + type: + - string + status: + description: "The current status of the invoice (e.g., pending, paid, voided)." + type: + - string + memo: + description: Any additional notes or comments associated with the invoice. + type: + - "null" + - string + issue_failed_at: + description: The date and time when issuing the invoice failed. + type: + - "null" + - string + format: date-time + sync_failed_at: + description: The date and time when syncing the invoice data failed. + type: + - "null" + - string + format: date-time + payment_failed_at: + description: The date and time when the payment for the invoice failed. + type: + - "null" + - string + format: date-time + payment_started_at: + description: The date and time when the payment process started for the + invoice. + type: + - "null" + - string + format: date-time + voided_at: + description: The date and time when the invoice was voided. + type: + - "null" + - string + format: date-time + paid_at: + description: The date and time when the invoice was paid. + type: + - "null" + - string + format: date-time + issued_at: + description: The date and time when the invoice was issued. + type: + - "null" + - string + format: date-time + hosted_invoice_url: + description: The URL to view the hosted invoice online. + type: + - "null" + - string + line_items: + description: The line items included in the invoice. + type: + - array + items: + type: object + properties: + id: + description: The unique identifier of the line item. + type: string + quantity: + description: The quantity of the item included in the invoice. + type: number + amount: + description: The amount for the line item. + type: string + name: + description: The name or description of the line item. + type: string + start_date: + description: The start date of the service period for the line item. + type: + - "null" + - string + format: date-time + end_date: + description: The end date of the service period for the line item. + type: + - "null" + - string + format: date-time + subscription: + description: Information about the subscription associated with the invoice. + type: + - object + - "null" + properties: + id: + description: The unique identifier of the subscription. + type: string + required: + - id + - created_at + incremental_sync: + type: DatetimeBasedCursor + cursor_field: invoice_date + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S+00:00" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: invoice_date[gte] + inject_into: request_parameter + partition_router: + - type: ListPartitionRouter + values: + - void + - paid + - issued + - synced + cursor_field: status + request_option: + type: RequestOption + inject_into: request_parameter + field_name: status[] +- type: DeclarativeStream + name: credits_ledger_entries + primary_key: id + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: customers/{{ stream_partition.customer_id }}/credits/ledger + request_parameters: + entry_status: committed + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", {}) }} + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: customer_id + stream: + type: DeclarativeStream + name: customers + primary_key: id + retriever: + type: SimpleRetriever + requester: + type: HttpRequester + url_base: https://api.billwithorb.com/v1/ + http_method: GET + request_headers: {} + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + request_body_json: {} + path: customers + request_parameters: {} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: cursor + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", + {}) }}' + stop_condition: >- + {{ not response.get("pagination_metadata", {}).get("next_cursor", + {}) }} + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + additionalProperties: true + properties: + id: + description: The unique identifier of the customer. + type: string + external_customer_id: + description: The ID of the customer in an external system. + type: + - string + - "null" + name: + description: The name of the customer. + type: string + email: + description: The email address of the customer. + type: + - string + - "null" + created_at: + description: The date and time when the customer account was created. + type: + - "null" + - string + format: date-time + payment_provider: + description: The payment provider used by the customer. + type: + - "null" + - string + payment_provider_id: + description: The ID of the customer in the payment provider's system. + type: + - "null" + - string + timezone: + description: The timezone setting of the customer. + type: + - "null" + - string + shipping_address: + description: The shipping address of the customer. + type: + - "null" + - object + properties: + city: + description: The city of the shipping address. + type: + - "null" + - string + country: + description: The country of the shipping address. + type: + - "null" + - string + line1: + description: The first line in the shipping address. + type: + - "null" + - string + line2: + description: The second line in the shipping address if applicable. + type: + - "null" + - string + postal_code: + description: The postal code of the shipping address. + type: + - "null" + - string + state: + description: The state or region of the shipping address. + type: + - "null" + - string + billing_address: + description: The billing address of the customer. + type: + - "null" + - object + properties: + city: + description: The city of the billing address. + type: + - "null" + - string + country: + description: The country of the billing address. + type: + - "null" + - string + line1: + description: The first line in the billing address. + type: + - "null" + - string + line2: + description: The second line in the billing address if applicable. + type: + - "null" + - string + postal_code: + description: The postal code of the billing address. + type: + - "null" + - string + state: + description: The state or region of the billing address. + type: + - "null" + - string + required: + - id + - created_at + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%dT%H:%M:%S.%fZ" + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_at[gte] + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ config['end_date'] if config['end_date'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') + }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: created_at[lte] + inject_into: request_parameter + schema_loader: + type: InlineSchemaLoader + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + properties: + id: + description: The unique ID of the ledger entry + type: string + starting_balance: + description: The starting balance before the ledger entry + type: number + ending_balance: + description: The ending balance after the ledger entry + type: number + amount: + description: The amount of credits involved in the ledger entry + type: + - "null" + - number + block_expiry_date: + description: The date and time when the credit block will expire + type: + - "null" + - string + format: date-time + created_at: + description: The date and time when the ledger entry was created + type: + - "null" + - string + format: date-time + entry_type: + description: "The type of ledger entry (e.g., debit, credit)" + type: string + new_block_expiry_date: + description: The new expiry date and time of the credit block after the + ledger entry + type: + - "null" + - string + format: date-time + customer_id: + description: The ID of the customer associated with the ledger entry + type: string + credit_block_per_unit_cost_basis: + description: The cost per unit of the credit block + type: + - "null" + - number + description: + description: A description of the ledger entry + type: + - "null" + - string + credit_block_id: + description: The ID of the associated credit block + type: + - "null" + - string + required: + - id + - created_at + - customer_id + - credit_block_id + transformations: + - type: AddFields + fields: + - path: + - customer_id + value: "{{ record['customer']['id'] }}" + type: AddedFieldDefinition + - type: RemoveFields + field_pointers: + - - customer + - type: AddFields + fields: + - path: + - block_expiry_date + value: "{{ record['credit_block']['expiry_date'] }}" + type: AddedFieldDefinition + - type: AddFields + fields: + - path: + - credit_block_id + value: "{{ record['credit_block']['id'] }}" + type: AddedFieldDefinition + - type: AddFields + fields: + - path: + - credit_block_per_unit_cost_basis + value: "{{ record['credit_block']['per_unit_cost_basis'] }}" + type: AddedFieldDefinition + - type: RemoveFields + field_pointers: + - - credit_block + - type: AddFields + fields: + - path: + - event + - id + value: "{{ record['event_id'] }}" + type: AddedFieldDefinition + - type: RemoveFields + field_pointers: + - - event_id + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + lookback_window: P{{ config.get('lookback_window_days', 0) }}D + cursor_datetime_formats: + - "%Y-%m-%d %H:%M:%S.%f+00:00" + - "%Y-%m-%dT%H:%M:%S.%fZ" + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_at[gte] + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ config['end_date'] if config['end_date'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') + }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_time_option: + type: RequestOption + field_name: created_at[lte] + inject_into: request_parameter +schemas: + subscriptions: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + additionalProperties: true + properties: + id: + description: The unique identifier of the subscription. + type: string + created_at: + description: The date and time when the subscription was created. + type: + - "null" + - string + format: date-time + customer_id: + description: The unique identifier of the customer associated with the subscription. + type: string + external_customer_id: + description: The external identifier of the customer associated with the subscription. + type: + - "null" + - string + start_date: + description: The date and time when the subscription is set to start. + type: + - "null" + - string + format: date-time + end_date: + description: The date and time when the subscription is set to end. + type: + - "null" + - string + format: date-time + plan_id: + description: >- + The unique identifier of the subscription plan assigned to the + subscription. + type: string + status: + description: The current status of the subscription. + type: string + required: + - id + - created_at + customers: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + additionalProperties: true + properties: + id: + description: The unique identifier of the customer. + type: string + external_customer_id: + description: The ID of the customer in an external system. + type: + - string + - "null" + name: + description: The name of the customer. + type: string + email: + description: The email address of the customer. + type: + - string + - "null" + created_at: + description: The date and time when the customer account was created. + type: + - "null" + - string + format: date-time + payment_provider: + description: The payment provider used by the customer. + type: + - "null" + - string + payment_provider_id: + description: The ID of the customer in the payment provider's system. + type: + - "null" + - string + timezone: + description: The timezone setting of the customer. + type: + - "null" + - string + shipping_address: + description: The shipping address of the customer. + type: + - "null" + - object + properties: + city: + description: The city of the shipping address. + type: + - "null" + - string + country: + description: The country of the shipping address. + type: + - "null" + - string + line1: + description: The first line in the shipping address. + type: + - "null" + - string + line2: + description: The second line in the shipping address if applicable. + type: + - "null" + - string + postal_code: + description: The postal code of the shipping address. + type: + - "null" + - string + state: + description: The state or region of the shipping address. + type: + - "null" + - string + billing_address: + description: The billing address of the customer. + type: + - "null" + - object + properties: + city: + description: The city of the billing address. + type: + - "null" + - string + country: + description: The country of the billing address. + type: + - "null" + - string + line1: + description: The first line in the billing address. + type: + - "null" + - string + line2: + description: The second line in the billing address if applicable. + type: + - "null" + - string + postal_code: + description: The postal code of the billing address. + type: + - "null" + - string + state: + description: The state or region of the billing address. + type: + - "null" + - string + required: + - id + - created_at + subscription_usage: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + additionalProperties: true + properties: + quantity: + description: Quantity of the billable metric used during the specified timeframe + type: number + timeframe_start: + description: Start timestamp of the timeframe during which the usage data + is captured + type: string + format: date-time + timeframe_end: + description: End timestamp of the timeframe during which the usage data is + captured + type: string + format: date-time + billable_metric_name: + description: Name of the billable metric associated with the subscription + usage + type: string + billable_metric_id: + description: >- + Unique identifier for the billable metric associated with the subscription + usage + type: string + subscription_id: + description: Unique identifier for the subscription the usage data belongs + to + type: string + grouping_key: + type: + - "null" + - string + required: + - billable_metric_id + - subscription_id + plans: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + properties: + id: + description: The unique identifier of the plan + type: string + created_at: + description: The timestamp of when the plan was created + type: + - "null" + - string + format: date-time + description: + description: A short description of the plan + type: + - "null" + - string + name: + description: The name of the plan + type: + - "null" + - string + prices: + description: An array of pricing options for the plan + type: + - array + items: + type: object + properties: + id: + description: The unique identifier of the price option + type: string + product: + description: The product to which the plan belongs + type: object + properties: + id: + description: The unique identifier of the product + type: string + required: + - id + - created_at + invoices: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + properties: + id: + description: The unique identifier of the invoice. + type: string + created_at: + description: The date and time when the invoice was created. + type: + - "null" + - string + format: date-time + invoice_date: + description: The date when the invoice was issued. + type: + - string + format: date-time + due_date: + description: The due date for the payment of the invoice. + type: + - string + format: date-time + invoice_pdf: + description: The URL to download the PDF version of the invoice. + type: + - "null" + - string + subtotal: + description: The subtotal amount before applying taxes or discounts. + type: + - string + total: + description: The total amount of the invoice including all charges. + type: + - string + amount_due: + description: The total amount due on the invoice. + type: + - string + status: + description: "The current status of the invoice (e.g., pending, paid, voided)." + type: + - string + memo: + description: Any additional notes or comments associated with the invoice. + type: + - "null" + - string + issue_failed_at: + description: The date and time when issuing the invoice failed. + type: + - "null" + - string + format: date-time + sync_failed_at: + description: The date and time when syncing the invoice data failed. + type: + - "null" + - string + format: date-time + payment_failed_at: + description: The date and time when the payment for the invoice failed. + type: + - "null" + - string + format: date-time + payment_started_at: + description: The date and time when the payment process started for the invoice. + type: + - "null" + - string + format: date-time + voided_at: + description: The date and time when the invoice was voided. + type: + - "null" + - string + format: date-time + paid_at: + description: The date and time when the invoice was paid. + type: + - "null" + - string + format: date-time + issued_at: + description: The date and time when the invoice was issued. + type: + - "null" + - string + format: date-time + hosted_invoice_url: + description: The URL to view the hosted invoice online. + type: + - "null" + - string + line_items: + description: The line items included in the invoice. + type: + - array + items: + type: object + properties: + id: + description: The unique identifier of the line item. + type: string + quantity: + description: The quantity of the item included in the invoice. + type: number + amount: + description: The amount for the line item. + type: string + name: + description: The name or description of the line item. + type: string + start_date: + description: The start date of the service period for the line item. + type: + - "null" + - string + format: date-time + end_date: + description: The end date of the service period for the line item. + type: + - "null" + - string + format: date-time + subscription: + description: Information about the subscription associated with the invoice. + type: + - object + - "null" + properties: + id: + description: The unique identifier of the subscription. + type: string + required: + - id + - created_at + credits_ledger_entries: + $schema: "http://json-schema.org/draft-07/schema#" + type: + - "null" + - object + properties: + id: + description: The unique ID of the ledger entry + type: string + starting_balance: + description: The starting balance before the ledger entry + type: number + ending_balance: + description: The ending balance after the ledger entry + type: number + amount: + description: The amount of credits involved in the ledger entry + type: + - "null" + - number + block_expiry_date: + description: The date and time when the credit block will expire + type: + - "null" + - string + format: date-time + created_at: + description: The date and time when the ledger entry was created + type: + - "null" + - string + format: date-time + entry_type: + description: "The type of ledger entry (e.g., debit, credit)" + type: string + new_block_expiry_date: + description: The new expiry date and time of the credit block after the ledger + entry + type: + - "null" + - string + format: date-time + customer_id: + description: The ID of the customer associated with the ledger entry + type: string + credit_block_per_unit_cost_basis: + description: The cost per unit of the credit block + type: + - "null" + - number + description: + description: A description of the ledger entry + type: + - "null" + - string + credit_block_id: + description: The ID of the associated credit block + type: + - "null" + - string + required: + - id + - created_at + - customer_id + - credit_block_id +spec: + type: Spec + documentation_url: https://docs.withorb.com/ + connection_specification: + $schema: http://json-schema.org/draft-07/schema# + type: object + additionalProperties: true + required: + - start_date + - api_key + properties: + api_key: + type: string + title: Orb API Key + description: Orb API Key, issued from the Orb admin console. + airbyte_secret: true + order: 0 + start_date: + type: string + title: Start Date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + description: UTC date and time in the format 2022-03-01T00:00:00Z. Any data + with created_at before this data will not be synced. For Subscription Usage, + this becomes the `timeframe_start` API parameter. + examples: + - "2022-03-01T00:00:00Z" + order: 1 + end_date: + type: string + title: End Date + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + description: UTC date and time in the format 2022-03-01T00:00:00Z. Any data + with created_at after this data will not be synced. For Subscription Usage, + this becomes the `timeframe_start` API parameter. + examples: + - "2024-03-01T00:00:00Z" + order: 2 + lookback_window_days: + type: integer + title: Lookback Window (in days) + default: 0 + minimum: 0 + description: When set to N, the connector will always refresh resources created + within the past N days. By default, updated objects that are not newly created + are not incrementally synced. + order: 3 + string_event_properties_keys: + type: array + items: + type: string + title: Event properties keys (string values) + description: Property key names to extract from all events, in order to enrich + ledger entries corresponding to an event deduction. + order: 4 + numeric_event_properties_keys: + type: array + items: + type: string + title: Event properties keys (numeric values) + description: Property key names to extract from all events, in order to enrich + ledger entries corresponding to an event deduction. + order: 5 + subscription_usage_grouping_key: + type: string + title: Subscription usage grouping key (string value) + description: Property key name to group subscription usage by. + order: 6 + plan_id: + type: string + title: Orb Plan ID for Subscription Usage (string value) + description: Orb Plan ID to filter subscriptions that should have usage fetched. + order: 7 diff --git a/airbyte-integrations/connectors/source-orb/metadata.yaml b/airbyte-integrations/connectors/source-orb/metadata.yaml index 8effe1fbcfa3..d79ee30c629b 100644 --- a/airbyte-integrations/connectors/source-orb/metadata.yaml +++ b/airbyte-integrations/connectors/source-orb/metadata.yaml @@ -1,10 +1,10 @@ data: connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 7f0455fb-4518-4ec0-b7a3-d808bf8081cc - dockerImageTag: 2.0.14 + dockerImageTag: 2.1.4 dockerRepository: airbyte/source-orb githubIssueLabel: source-orb icon: orb.svg @@ -12,7 +12,7 @@ data: name: Orb remoteRegistries: pypi: - enabled: true + enabled: false packageName: airbyte-source-orb registryOverrides: cloud: @@ -22,13 +22,15 @@ data: releases: breakingChanges: 2.0.0: - message: This version changes the datatype of the `credit_block_per_unit_cost_basis` field in the `credits_ledger_entries` from `string` to `number`. + message: + This version changes the datatype of the `credit_block_per_unit_cost_basis` + field in the `credits_ledger_entries` from `string` to `number`. upgradeDeadline: "2024-12-30" releaseStage: alpha documentationUrl: https://docs.airbyte.com/integrations/sources/orb tags: - - language:python - cdk:low-code + - language:manifest-only ab_internal: sl: 100 ql: 100 diff --git a/airbyte-integrations/connectors/source-orb/poetry.lock b/airbyte-integrations/connectors/source-orb/poetry.lock deleted file mode 100644 index fde056326f1b..000000000000 --- a/airbyte-integrations/connectors/source-orb/poetry.lock +++ /dev/null @@ -1,1112 +0,0 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. - -[[package]] -name = "airbyte-cdk" -version = "0.80.0" -description = "A framework for writing Airbyte Connectors." -optional = false -python-versions = "<4.0,>=3.9" -files = [ - {file = "airbyte_cdk-0.80.0-py3-none-any.whl", hash = "sha256:060e92323a73674fa4e9e2e4a1eb312b9b9d072c9bbe5fa28f54ef21cb4974f3"}, - {file = "airbyte_cdk-0.80.0.tar.gz", hash = "sha256:1383512a83917fecca5b24cea4c72aa5c561cf96dd464485fbcefda48fe574c5"}, -] - -[package.dependencies] -airbyte-protocol-models = "0.5.1" -backoff = "*" -cachetools = "*" -Deprecated = ">=1.2,<1.3" -dpath = ">=2.0.1,<2.1.0" -genson = "1.2.2" -isodate = ">=0.6.1,<0.7.0" -Jinja2 = ">=3.1.2,<3.2.0" -jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" -pendulum = "<3.0.0" -pydantic = ">=1.10.8,<2.0.0" -pyrate-limiter = ">=3.1.0,<3.2.0" -python-dateutil = "*" -PyYAML = ">=6.0.1,<7.0.0" -requests = "*" -requests_cache = "*" -wcmatch = "8.4" - -[package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.0.271)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] - -[[package]] -name = "airbyte-protocol-models" -version = "0.5.1" -description = "Declares the Airbyte Protocol." -optional = false -python-versions = ">=3.8" -files = [ - {file = "airbyte_protocol_models-0.5.1-py3-none-any.whl", hash = "sha256:dfe84e130e51ce2ae81a06d5aa36f6c5ce3152b9e36e6f0195fad6c3dab0927e"}, - {file = "airbyte_protocol_models-0.5.1.tar.gz", hash = "sha256:7c8b16c7c1c7956b1996052e40585a3a93b1e44cb509c4e97c1ee4fe507ea086"}, -] - -[package.dependencies] -pydantic = ">=1.9.2,<2.0.0" - -[[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, -] - -[[package]] -name = "attrs" -version = "24.2.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" -files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, -] - -[package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] - -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "bracex" -version = "2.5.post1" -description = "Bash style brace expander." -optional = false -python-versions = ">=3.8" -files = [ - {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, - {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, -] - -[[package]] -name = "cachetools" -version = "5.5.0" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, - {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, -] - -[[package]] -name = "cattrs" -version = "24.1.2" -description = "Composable complex class support for attrs and dataclasses." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, - {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, -] - -[package.dependencies] -attrs = ">=23.1.0" -exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} - -[package.extras] -bson = ["pymongo (>=4.4.0)"] -cbor2 = ["cbor2 (>=5.4.6)"] -msgpack = ["msgpack (>=1.0.5)"] -msgspec = ["msgspec (>=0.18.5)"] -orjson = ["orjson (>=3.9.2)"] -pyyaml = ["pyyaml (>=6.0)"] -tomlkit = ["tomlkit (>=0.11.8)"] -ujson = ["ujson (>=5.7.0)"] - -[[package]] -name = "certifi" -version = "2024.8.30" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.0" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -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 = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - -[[package]] -name = "dpath" -version = "2.0.8" -description = "Filesystem-like pathing and searching for dictionaries" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dpath-2.0.8-py3-none-any.whl", hash = "sha256:f92f595214dd93a00558d75d4b858beee519f4cffca87f02616ad6cd013f3436"}, - {file = "dpath-2.0.8.tar.gz", hash = "sha256:a3440157ebe80d0a3ad794f1b61c571bef125214800ffdb9afc9424e8250fe9b"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "faker" -version = "30.8.1" -description = "Faker is a Python package that generates fake data for you." -optional = false -python-versions = ">=3.8" -files = [ - {file = "Faker-30.8.1-py3-none-any.whl", hash = "sha256:4f7f133560b9d4d2a915581f4ba86f9a6a83421b89e911f36c4c96cff58135a5"}, - {file = "faker-30.8.1.tar.gz", hash = "sha256:93e8b70813f76d05d98951154681180cb795cfbcff3eced7680d963bcc0da2a9"}, -] - -[package.dependencies] -python-dateutil = ">=2.4" -typing-extensions = "*" - -[[package]] -name = "genson" -version = "1.2.2" -description = "GenSON is a powerful, user-friendly JSON Schema generator." -optional = false -python-versions = "*" -files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, -] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isodate" -version = "0.6.1" -description = "An ISO 8601 date/time/duration parser and formatter" -optional = false -python-versions = "*" -files = [ - {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, - {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "jinja2" -version = "3.1.4" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "jsonref" -version = "0.2" -description = "An implementation of JSON Reference for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonref-0.2-py3-none-any.whl", hash = "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f"}, - {file = "jsonref-0.2.tar.gz", hash = "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697"}, -] - -[[package]] -name = "jsonschema" -version = "3.2.0" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, -] - -[package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" - -[package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] - -[[package]] -name = "markupsafe" -version = "3.0.2" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -files = [ - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, - {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, -] - -[[package]] -name = "packaging" -version = "24.1" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, -] - -[[package]] -name = "pendulum" -version = "2.1.2" -description = "Python datetimes made easy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, - {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, - {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, - {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, - {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, - {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, - {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, - {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, - {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, - {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, - {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, -] - -[package.dependencies] -python-dateutil = ">=2.6,<3.0" -pytzdata = ">=2020.1" - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] - -[[package]] -name = "pydantic" -version = "1.10.18" -description = "Data validation and settings management using python type hints" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, -] - -[package.dependencies] -typing-extensions = ">=4.2.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] - -[[package]] -name = "pyrate-limiter" -version = "3.1.1" -description = "Python Rate-Limiter using Leaky-Bucket Algorithm" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, - {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, -] - -[package.extras] -all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] -docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] - -[[package]] -name = "pyrsistent" -version = "0.20.0" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7"}, - {file = "pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee"}, - {file = "pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d"}, - {file = "pyrsistent-0.20.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win32.whl", hash = "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d"}, - {file = "pyrsistent-0.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win32.whl", hash = "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf"}, - {file = "pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b"}, - {file = "pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4"}, -] - -[[package]] -name = "pytest" -version = "6.2.5" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, -] - -[package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] - -[[package]] -name = "pytest-faker" -version = "2.0.0" -description = "Faker integration with the pytest framework." -optional = false -python-versions = "*" -files = [ - {file = "pytest-faker-2.0.0.tar.gz", hash = "sha256:6b37bb89d94f96552bfa51f8e8b89d32addded8ddb58a331488299ef0137d9b6"}, -] - -[package.dependencies] -Faker = ">=0.7.3" - -[[package]] -name = "pytest-mock" -version = "3.14.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, -] - -[package.dependencies] -pytest = ">=6.2.5" - -[package.extras] -dev = ["pre-commit", "pytest-asyncio", "tox"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytzdata" -version = "2020.1" -description = "The Olson timezone database for Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, - {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-cache" -version = "1.2.1" -description = "A persistent cache for python requests" -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, - {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, -] - -[package.dependencies] -attrs = ">=21.2" -cattrs = ">=22.2" -platformdirs = ">=2.5" -requests = ">=2.22" -url-normalize = ">=1.4" -urllib3 = ">=1.25.5" - -[package.extras] -all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] -bson = ["bson (>=0.5)"] -docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] -dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] -json = ["ujson (>=5.4)"] -mongodb = ["pymongo (>=3)"] -redis = ["redis (>=3)"] -security = ["itsdangerous (>=2.0)"] -yaml = ["pyyaml (>=6.0.1)"] - -[[package]] -name = "requests-mock" -version = "1.12.1" -description = "Mock out responses from the requests package" -optional = false -python-versions = ">=3.5" -files = [ - {file = "requests-mock-1.12.1.tar.gz", hash = "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401"}, - {file = "requests_mock-1.12.1-py2.py3-none-any.whl", hash = "sha256:b1e37054004cdd5e56c84454cc7df12b25f90f382159087f4b6915aaeef39563"}, -] - -[package.dependencies] -requests = ">=2.22,<3" - -[package.extras] -fixture = ["fixtures"] - -[[package]] -name = "responses" -version = "0.13.4" -description = "A utility library for mocking out the `requests` Python library." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "responses-0.13.4-py2.py3-none-any.whl", hash = "sha256:d8d0f655710c46fd3513b9202a7f0dcedd02ca0f8cf4976f27fa8ab5b81e656d"}, - {file = "responses-0.13.4.tar.gz", hash = "sha256:9476775d856d3c24ae660bbebe29fb6d789d4ad16acd723efbfb6ee20990b899"}, -] - -[package.dependencies] -requests = ">=2.0" -six = "*" -urllib3 = ">=1.25.10" - -[package.extras] -tests = ["coverage (>=3.7.1,<6.0.0)", "flake8", "mypy", "pytest (>=4.6)", "pytest (>=4.6,<5.0)", "pytest-cov", "pytest-localserver", "types-mock", "types-requests", "types-six"] - -[[package]] -name = "setuptools" -version = "75.3.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "url-normalize" -version = "1.4.3" -description = "URL normalization for Python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, - {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "urllib3" -version = "2.2.3" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "wcmatch" -version = "8.4" -description = "Wildcard/glob file name matcher." -optional = false -python-versions = ">=3.7" -files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, -] - -[package.dependencies] -bracex = ">=2.1.1" - -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "a2e250b05457b6d6d79c1c658812df875ea2a40eb372a76e13c57347f0744a18" diff --git a/airbyte-integrations/connectors/source-orb/pyproject.toml b/airbyte-integrations/connectors/source-orb/pyproject.toml deleted file mode 100644 index abf1c1ac1d86..000000000000 --- a/airbyte-integrations/connectors/source-orb/pyproject.toml +++ /dev/null @@ -1,33 +0,0 @@ -[build-system] -requires = [ "poetry-core>=1.0.0",] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -version = "2.0.14" -name = "source-orb" -description = "Source implementation for Orb." -authors = [ "Airbyte ",] -license = "MIT" -readme = "README.md" -documentation = "https://docs.airbyte.com/integrations/sources/orb" -homepage = "https://airbyte.com" -repository = "https://github.com/airbytehq/airbyte" -[[tool.poetry.packages]] -include = "source_orb" - -[tool.poetry.dependencies] -python = "^3.9,<3.12" -airbyte-cdk = "0.80.0" -pendulum = "==2.1.2" - -[tool.poetry.scripts] -source-orb = "source_orb.run:run" - -[tool.poetry.group.dev.dependencies] -pytest = "^6.1" -requests-mock = "^1.11.0" -pytest-faker = "==2.0.0" -pytest-mock = "^3.6.1" -pendulum = "==2.1.2" -responses = "^0.13.3" - diff --git a/airbyte-integrations/connectors/source-orb/source_orb/__init__.py b/airbyte-integrations/connectors/source-orb/source_orb/__init__.py deleted file mode 100644 index 0444e121319c..000000000000 --- a/airbyte-integrations/connectors/source-orb/source_orb/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - - -from .source import SourceOrb - -__all__ = ["SourceOrb"] diff --git a/airbyte-integrations/connectors/source-orb/source_orb/components.py b/airbyte-integrations/connectors/source-orb/source_orb/components.py deleted file mode 100644 index 3732d1f5954a..000000000000 --- a/airbyte-integrations/connectors/source-orb/source_orb/components.py +++ /dev/null @@ -1,119 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from dataclasses import dataclass -from typing import Iterable, Optional - -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.declarative.stream_slicers.stream_slicer import StreamSlicer -from airbyte_cdk.sources.declarative.transformations.transformation import RecordTransformation -from airbyte_cdk.sources.declarative.types import Config, Record, StreamSlice, StreamState -from airbyte_cdk.sources.streams.core import Stream - - -@dataclass -class SubscriptionUsageTransformation(RecordTransformation): - subscription_id: str - - def transform( - self, - record: Record, - config: Optional[Config] = None, - stream_state: Optional[StreamState] = None, - stream_slice: Optional[StreamSlice] = None, - ) -> Record: - - # for each top level response record, there can be multiple sub-records depending - # on granularity and other input params. This function yields one transformed record - # for each subrecord in the response. - - subrecords = record.get("usage", []) - del record["usage"] - for subrecord in subrecords: - # skip records that don't contain any actual usage - if subrecord.get("quantity", 0) > 0: - # Merge the parent record with the sub record - output = record.update(subrecord) - - # Add the subscription ID to the output - output["subscription_id"] = self.subscription_id - - # Un-nest billable_metric -> name,id into billable_metric_name and billable_metric_id - nested_billable_metric_name = output["billable_metric"]["name"] - nested_billable_metric_id = output["billable_metric"]["id"] - del output["billable_metric"] - output["billable_metric_name"] = nested_billable_metric_name - output["billable_metric_id"] = nested_billable_metric_id - - # If a group_by key is specified, un-nest it - if config.subscription_usage_grouping_key: - nested_key = output["metric_group"]["property_key"] - nested_value = output["metric_group"]["property_value"] - del output["metric_group"] - output[nested_key] = nested_value - yield output - yield from [] - - -@dataclass -class SubscriptionUsagePartitionRouter(StreamSlicer): - plans_stream: Stream - subscriptions_stream: Stream - config: Config - - def stream_slices(self) -> Iterable[StreamSlice]: - - """ - This stream is sliced per `subscription_id` and day, as well as `billable_metric_id` - if a grouping key is provided. This is because the API only supports a - single billable_metric_id per API call when using a group_by param. - - """ - slice_yielded = False - subscriptions_stream = self.subscriptions_stream - plans_stream = self.plans_stream - - # if using a group_by key, populate prices_by_plan_id so that each - # billable metric will get its own slice - if self.config.get("subscription_usage_grouping_key"): - metric_ids_by_plan_id = {} - - for plan in plans_stream.read_records(sync_mode=SyncMode.full_refresh): - # if a plan_id filter is specified, skip any plan that doesn't match - if self.config.get("plan_id") and plan["id"] != self.config.get("plan_id"): - continue - - prices = plan.get("prices", []) - metric_ids_by_plan_id[plan["id"]] = [(price.get("billable_metric") or {}).get("id") for price in prices] - - for subscription in subscriptions_stream.read_records(sync_mode=SyncMode.full_refresh): - subscription_id = subscription["id"] - subscription_plan_id = subscription["plan_id"] - - # if filtering subscription usage by plan ID, skip any subscription that doesn't match the plan_id - if self.config.get("plan_id") and subscription_plan_id != self.config.get("plan_id"): - continue - - slice = { - "subscription_id": subscription_id, - } - - # if using a group_by key, yield one slice per billable_metric_id. - # otherwise, yield slices without a billable_metric_id because - # each API call will return usage broken down by billable metric - # when grouping isn't used. - if self.config.get("subscription_usage_grouping_key"): - metric_ids = metric_ids_by_plan_id.get(subscription_plan_id) - if metric_ids is not None: - for metric_id in metric_ids: - # self.logger.warning("stream_slices is about to yield the following slice: %s", slice) - yield {**slice, "billable_metric_id": metric_id} - slice_yielded = True - else: - # self.logger.warning("stream_slices is about to yield the following slice: %s", slice) - yield slice - slice_yielded = True - if not slice_yielded: - # yield an empty slice to checkpoint state later - yield {} diff --git a/airbyte-integrations/connectors/source-orb/source_orb/manifest.yaml b/airbyte-integrations/connectors/source-orb/source_orb/manifest.yaml deleted file mode 100644 index 6de482574aae..000000000000 --- a/airbyte-integrations/connectors/source-orb/source_orb/manifest.yaml +++ /dev/null @@ -1,871 +0,0 @@ -version: 0.51.2 - -type: DeclarativeSource - -check: - type: CheckStream - stream_names: - - subscriptions - -definitions: - selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: cursor - page_size_option: - type: RequestOption - field_name: limit - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 50 - cursor_value: '{{ response.get("pagination_metadata", {}).get("next_cursor", {}) }}' - stop_condition: >- - {{ not response.get("pagination_metadata", {}).get("next_cursor", {}) }} - requester: - type: HttpRequester - url_base: https://api.billwithorb.com/v1/ - http_method: GET - request_headers: {} - authenticator: - type: BearerAuthenticator - api_token: "{{ config['api_key'] }}" - request_body_json: {} - incremental_sync: - type: DatetimeBasedCursor - cursor_field: created_at - lookback_window: P{{ config.get('lookback_window_days', 0) }}D - cursor_datetime_formats: - - "%Y-%m-%d %H:%M:%S.%f+00:00" - - "%Y-%m-%dT%H:%M:%S.%fZ" - - "%Y-%m-%dT%H:%M:%SZ" - datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - start_time_option: - type: RequestOption - field_name: created_at[gte] - inject_into: request_parameter - end_datetime: - type: MinMaxDatetime - datetime: "{{ config['end_date'] if config['end_date'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - end_time_option: - type: RequestOption - field_name: created_at[lte] - inject_into: request_parameter - customers_stream: - type: DeclarativeStream - name: customers - primary_key: id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: customers - request_parameters: {} - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/customers" - incremental_sync: - $ref: "#/definitions/incremental_sync" - subscriptions_stream: - type: DeclarativeStream - name: subscriptions - primary_key: id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: subscriptions - request_parameters: {} - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/subscriptions" - transformations: - - type: AddFields - fields: - - path: - - customer_id - value: "{{ record['customer']['id'] }}" - - type: AddFields - fields: - - path: - - external_customer_id - value: "{{ record['customer']['external_customer_id'] }}" - - type: RemoveFields - field_pointers: - - - customer - - type: AddFields - fields: - - path: - - plan_id - value: "{{ record['plan']['id'] }}" - - type: RemoveFields - field_pointers: - - - plan - incremental_sync: - $ref: "#/definitions/incremental_sync" - plans_stream: - type: DeclarativeStream - name: plans - primary_key: id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: plans - request_parameters: {} - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/plans" - incremental_sync: - $ref: "#/definitions/incremental_sync" - invoices_stream: - type: DeclarativeStream - name: invoices - primary_key: id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: invoices - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/invoices" - incremental_sync: - type: DatetimeBasedCursor - cursor_field: invoice_date - lookback_window: P{{ config.get('lookback_window_days', 0) }}D - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S+00:00" - datetime_format: "%Y-%m-%dT%H:%M:%S+00:00" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - start_time_option: - type: RequestOption - field_name: invoice_date[gte] - inject_into: request_parameter - partition_router: - - type: ListPartitionRouter - values: - - void - - paid - - issued - - synced - cursor_field: status - request_option: - type: RequestOption - inject_into: request_parameter - field_name: status[] - credits_ledger_entries_stream: - type: DeclarativeStream - name: credits_ledger_entries - primary_key: id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: customers/{{ stream_partition.customer_id }}/credits/ledger - request_parameters: - entry_status: committed - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator" - partition_router: - - type: SubstreamPartitionRouter - parent_stream_configs: - - type: ParentStreamConfig - parent_key: id - partition_field: customer_id - stream: - $ref: "#/definitions/customers_stream" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/credits_ledger_entries" - transformations: - - type: AddFields - fields: - - path: - - customer_id - value: "{{ record['customer']['id'] }}" - - type: RemoveFields - field_pointers: - - - customer - - type: AddFields - fields: - - path: - - block_expiry_date - value: "{{ record['credit_block']['expiry_date'] }}" - - type: AddFields - fields: - - path: - - credit_block_id - value: "{{ record['credit_block']['id'] }}" - - type: AddFields - fields: - - path: - - credit_block_per_unit_cost_basis - value: "{{ record['credit_block']['per_unit_cost_basis'] }}" - - type: RemoveFields - field_pointers: - - - credit_block - - type: AddFields - fields: - - path: - - event - - id - value: "{{ record['event_id'] }}" - - type: RemoveFields - field_pointers: - - - event_id - incremental_sync: - $ref: "#/definitions/incremental_sync" - subscription_usage_stream: - type: DeclarativeStream - name: subscription_usage - primary_key: - - subscription_id - - billable_metric_id - - timeframe_start - - grouping_key - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: subscriptions/{{ stream_partition.subscription_id }}/usage - request_parameters: - group_by: "{{ config.get('subscription_usage_grouping_key', '') }}" - granularity: day - billable_metric_id: "{{ stream_partition.billable_metric_id }}" - record_selector: - $ref: "#/definitions/selector" - partition_router: - - type: CustomPartitionRouter - class_name: source_orb.components.SubscriptionUsagePartitionRouter - plans_stream: - $ref: "#/definitions/plans_stream" - subscriptions_stream: - $ref: "#/definitions/subscriptions_stream" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/subscription_usage" - transformations: - - type: RemoveFields - field_pointers: - - - usage - - type: CustomTransformation - class_name: source_orb.components.SubscriptionUsageTransformation - subscription_id: "{{ stream_partition.subscription_id }}" - - type: AddFields - fields: - - path: - - grouping_key - value: "{{ config.get('subscription_usage_grouping_key', '') }}" - incremental_sync: - type: DatetimeBasedCursor - cursor_field: timeframe_start - lookback_window: P{{ config.get('lookback_window_days', 0) }}D - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - start_time_option: - type: RequestOption - field_name: timeframe_start - inject_into: request_parameter - end_time_option: - type: RequestOption - field_name: timeframe_end - inject_into: request_parameter - end_datetime: - type: MinMaxDatetime - datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - -streams: - - "#/definitions/subscriptions_stream" - - "#/definitions/customers_stream" - - "#/definitions/subscription_usage_stream" - - "#/definitions/plans_stream" - - "#/definitions/invoices_stream" - - "#/definitions/credits_ledger_entries_stream" - -schemas: - subscriptions: - $schema: "http://json-schema.org/draft-07/schema#" - type: - - "null" - - object - additionalProperties: true - properties: - id: - description: The unique identifier of the subscription. - type: string - created_at: - description: The date and time when the subscription was created. - type: - - "null" - - string - format: date-time - customer_id: - description: The unique identifier of the customer associated with the subscription. - type: string - external_customer_id: - description: The external identifier of the customer associated with the subscription. - type: - - "null" - - string - start_date: - description: The date and time when the subscription is set to start. - type: - - "null" - - string - format: date-time - end_date: - description: The date and time when the subscription is set to end. - type: - - "null" - - string - format: date-time - plan_id: - description: >- - The unique identifier of the subscription plan assigned to the - subscription. - type: string - status: - description: The current status of the subscription. - type: string - required: - - id - - created_at - - status - - customers: - $schema: "http://json-schema.org/draft-07/schema#" - type: - - "null" - - object - additionalProperties: true - properties: - id: - description: The unique identifier of the customer. - type: string - external_customer_id: - description: The ID of the customer in an external system. - type: - - string - - "null" - name: - description: The name of the customer. - type: string - email: - description: The email address of the customer. - type: - - string - - "null" - created_at: - description: The date and time when the customer account was created. - type: - - "null" - - string - format: date-time - payment_provider: - description: The payment provider used by the customer. - type: - - "null" - - string - payment_provider_id: - description: The ID of the customer in the payment provider's system. - type: - - "null" - - string - timezone: - description: The timezone setting of the customer. - type: - - "null" - - string - shipping_address: - description: The shipping address of the customer. - type: - - "null" - - object - properties: - city: - description: The city of the shipping address. - type: - - "null" - - string - country: - description: The country of the shipping address. - type: - - "null" - - string - line1: - description: The first line in the shipping address. - type: - - "null" - - string - line2: - description: The second line in the shipping address if applicable. - type: - - "null" - - string - postal_code: - description: The postal code of the shipping address. - type: - - "null" - - string - state: - description: The state or region of the shipping address. - type: - - "null" - - string - billing_address: - description: The billing address of the customer. - type: - - "null" - - object - properties: - city: - description: The city of the billing address. - type: - - "null" - - string - country: - description: The country of the billing address. - type: - - "null" - - string - line1: - description: The first line in the billing address. - type: - - "null" - - string - line2: - description: The second line in the billing address if applicable. - type: - - "null" - - string - postal_code: - description: The postal code of the billing address. - type: - - "null" - - string - state: - description: The state or region of the billing address. - type: - - "null" - - string - required: - - id - - created_at - - subscription_usage: - $schema: "http://json-schema.org/draft-07/schema#" - type: - - "null" - - object - additionalProperties: true - properties: - quantity: - description: Quantity of the billable metric used during the specified timeframe - type: number - timeframe_start: - description: Start timestamp of the timeframe during which the usage data is captured - type: string - format: date-time - timeframe_end: - description: End timestamp of the timeframe during which the usage data is captured - type: string - format: date-time - billable_metric_name: - description: Name of the billable metric associated with the subscription usage - type: string - billable_metric_id: - description: >- - Unique identifier for the billable metric associated with the subscription - usage - type: string - subscription_id: - description: Unique identifier for the subscription the usage data belongs to - type: string - grouping_key: - type: - - "null" - - string - required: - - quantity - - timeframe_start - - timeframe_end - - billable_metric_name - - billable_metric_id - - subscription_id - - plans: - $schema: "http://json-schema.org/draft-07/schema#" - type: - - "null" - - object - properties: - id: - description: The unique identifier of the plan - type: string - created_at: - description: The timestamp of when the plan was created - type: - - "null" - - string - format: date-time - description: - description: A short description of the plan - type: - - "null" - - string - name: - description: The name of the plan - type: - - "null" - - string - prices: - description: An array of pricing options for the plan - type: - - array - items: - type: object - properties: - id: - description: The unique identifier of the price option - type: string - product: - description: The product to which the plan belongs - type: object - properties: - id: - description: The unique identifier of the product - type: string - required: - - id - - created_at - - invoices: - $schema: "http://json-schema.org/draft-07/schema#" - type: - - "null" - - object - properties: - id: - description: The unique identifier of the invoice. - type: string - created_at: - description: The date and time when the invoice was created. - type: - - "null" - - string - format: date-time - invoice_date: - description: The date when the invoice was issued. - type: - - string - format: date-time - due_date: - description: The due date for the payment of the invoice. - type: - - string - format: date-time - invoice_pdf: - description: The URL to download the PDF version of the invoice. - type: - - "null" - - string - subtotal: - description: The subtotal amount before applying taxes or discounts. - type: - - string - total: - description: The total amount of the invoice including all charges. - type: - - string - amount_due: - description: The total amount due on the invoice. - type: - - string - status: - description: "The current status of the invoice (e.g., pending, paid, voided)." - type: - - string - memo: - description: Any additional notes or comments associated with the invoice. - type: - - "null" - - string - issue_failed_at: - description: The date and time when issuing the invoice failed. - type: - - "null" - - string - format: date-time - sync_failed_at: - description: The date and time when syncing the invoice data failed. - type: - - "null" - - string - format: date-time - payment_failed_at: - description: The date and time when the payment for the invoice failed. - type: - - "null" - - string - format: date-time - payment_started_at: - description: The date and time when the payment process started for the invoice. - type: - - "null" - - string - format: date-time - voided_at: - description: The date and time when the invoice was voided. - type: - - "null" - - string - format: date-time - paid_at: - description: The date and time when the invoice was paid. - type: - - "null" - - string - format: date-time - issued_at: - description: The date and time when the invoice was issued. - type: - - "null" - - string - format: date-time - hosted_invoice_url: - description: The URL to view the hosted invoice online. - type: - - "null" - - string - line_items: - description: The line items included in the invoice. - type: - - array - items: - type: object - properties: - id: - description: The unique identifier of the line item. - type: string - quantity: - description: The quantity of the item included in the invoice. - type: number - amount: - description: The amount for the line item. - type: string - name: - description: The name or description of the line item. - type: string - start_date: - description: The start date of the service period for the line item. - type: - - "null" - - string - format: date-time - end_date: - description: The end date of the service period for the line item. - type: - - "null" - - string - format: date-time - subscription: - description: Information about the subscription associated with the invoice. - type: - - object - - "null" - properties: - id: - description: The unique identifier of the subscription. - type: string - required: - - id - - created_at - - invoice_date - - due_date - - subtotal - - total - - amount_due - - status - - credits_ledger_entries: - $schema: "http://json-schema.org/draft-07/schema#" - type: - - "null" - - object - properties: - id: - description: The unique ID of the ledger entry - type: string - starting_balance: - description: The starting balance before the ledger entry - type: number - ending_balance: - description: The ending balance after the ledger entry - type: number - amount: - description: The amount of credits involved in the ledger entry - type: - - "null" - - number - block_expiry_date: - description: The date and time when the credit block will expire - type: - - "null" - - string - format: date-time - created_at: - description: The date and time when the ledger entry was created - type: - - "null" - - string - format: date-time - entry_type: - description: "The type of ledger entry (e.g., debit, credit)" - type: string - new_block_expiry_date: - description: The new expiry date and time of the credit block after the ledger entry - type: - - "null" - - string - format: date-time - customer_id: - description: The ID of the customer associated with the ledger entry - type: string - credit_block_per_unit_cost_basis: - description: The cost per unit of the credit block - type: - - "null" - - number - description: - description: A description of the ledger entry - type: - - "null" - - string - credit_block_id: - description: The ID of the associated credit block - type: - - "null" - - string - required: - - id - - starting_balance - - ending_balance - - amount - - created_at - - customer_id - - entry_type - - credit_block_per_unit_cost_basis - - description - - credit_block_id - -spec: - type: Spec - documentation_url: https://docs.withorb.com/ - connection_specification: - $schema: http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - required: - - start_date - - api_key - properties: - api_key: - type: string - title: Orb API Key - description: Orb API Key, issued from the Orb admin console. - airbyte_secret: true - order: 0 - start_date: - type: string - title: Start Date - format: date-time - pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ - description: UTC date and time in the format 2022-03-01T00:00:00Z. Any data with created_at before this data will not be synced. For Subscription Usage, this becomes the `timeframe_start` API parameter. - examples: - - "2022-03-01T00:00:00Z" - order: 1 - end_date: - type: string - title: End Date - pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ - description: UTC date and time in the format 2022-03-01T00:00:00Z. Any data with created_at after this data will not be synced. For Subscription Usage, this becomes the `timeframe_start` API parameter. - examples: ["2024-03-01T00:00:00Z"] - order: 2 - lookback_window_days: - type: integer - title: Lookback Window (in days) - default: 0 - minimum: 0 - description: When set to N, the connector will always refresh resources created within the past N days. By default, updated objects that are not newly created are not incrementally synced. - order: 3 - string_event_properties_keys: - type: array - items: - type: string - title: Event properties keys (string values) - description: Property key names to extract from all events, in order to enrich ledger entries corresponding to an event deduction. - order: 4 - numeric_event_properties_keys: - type: array - items: - type: string - title: Event properties keys (numeric values) - description: Property key names to extract from all events, in order to enrich ledger entries corresponding to an event deduction. - order: 5 - subscription_usage_grouping_key: - type: string - title: Subscription usage grouping key (string value) - description: Property key name to group subscription usage by. - order: 6 - plan_id: - type: string - title: Orb Plan ID for Subscription Usage (string value) - description: Orb Plan ID to filter subscriptions that should have usage fetched. - order: 7 diff --git a/airbyte-integrations/connectors/source-orb/source_orb/run.py b/airbyte-integrations/connectors/source-orb/source_orb/run.py deleted file mode 100644 index 3b45f9dc03d8..000000000000 --- a/airbyte-integrations/connectors/source-orb/source_orb/run.py +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - - -import sys - -from airbyte_cdk.entrypoint import launch - -from .source import SourceOrb - - -def run(): - source = SourceOrb() - launch(source, sys.argv[1:]) diff --git a/airbyte-integrations/connectors/source-orb/source_orb/source.py b/airbyte-integrations/connectors/source-orb/source_orb/source.py deleted file mode 100644 index 6c12618e25f2..000000000000 --- a/airbyte-integrations/connectors/source-orb/source_orb/source.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource - -""" -This file provides the necessary constructs to interpret a provided declarative YAML configuration file into -source connector. - -WARNING: Do not modify this file. -""" - - -# Declarative Source -class SourceOrb(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-orb/unit_tests/__init__.py b/airbyte-integrations/connectors/source-orb/unit_tests/__init__.py deleted file mode 100644 index 66f6de8cb2bb..000000000000 --- a/airbyte-integrations/connectors/source-orb/unit_tests/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-integrations/connectors/source-orb/unit_tests/conftest.py b/airbyte-integrations/connectors/source-orb/unit_tests/conftest.py deleted file mode 100644 index fe2358763db8..000000000000 --- a/airbyte-integrations/connectors/source-orb/unit_tests/conftest.py +++ /dev/null @@ -1,330 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# -from pytest import fixture - - -@fixture -def config_pass(): - return {"api_key": "test-token", "start_date": "2023-01-25T00:00:00Z"} - - -@fixture -def subscriptions_url(): - return "https://api.billwithorb.com/v1/subscriptions" - - -@fixture -def mock_subscriptions_response(): - return { - "data": [ - { - "metadata": {}, - "id": "string", - "customer": { - "metadata": {}, - "id": "string", - "external_customer_id": "string", - "name": "string", - "email": "string", - "timezone": "string", - "payment_provider_id": "string", - "payment_provider": "quickbooks", - "created_at": "2024-06-21T22:27:22.230Z", - "shipping_address": { - "line1": "string", - "line2": "string", - "city": "string", - "state": "string", - "postal_code": "string", - "country": "string" - }, - "billing_address": { - "line1": "string", - "line2": "string", - "city": "string", - "state": "string", - "postal_code": "string", - "country": "string" - }, - "balance": "string", - "currency": "string", - "tax_id": { - "country": "AD", - "type": "ad_nrt", - "value": "string" - }, - "auto_collection": True, - "email_delivery": True, - "additional_emails": [ - "string" - ], - "portal_url": "string", - "accounting_sync_configuration": { - "excluded": True, - "accounting_providers": [ - { - "provider_type": "quickbooks", - "external_provider_id": "string" - } - ] - }, - "reporting_configuration": { - "exempt": True - } - }, - "plan": { - "metadata": {}, - "id": "string", - "name": "string", - "description": "string", - "maximum_amount": "string", - "minimum_amount": "string", - "created_at": "2024-06-21T22:27:22.233Z", - "status": "active", - "maximum": { - "maximum_amount": "string", - "applies_to_price_ids": [ - "string" - ] - }, - "minimum": { - "minimum_amount": "string", - "applies_to_price_ids": [ - "string" - ] - }, - "discount": { - "discount_type": "percentage", - "applies_to_price_ids": [ - "h74gfhdjvn7ujokd", - "7hfgtgjnbvc3ujkl" - ], - "reason": "string", - "percentage_discount": 0.15 - }, - "product": { - "created_at": "2024-06-21T22:27:22.234Z", - "id": "string", - "name": "string" - }, - "version": 0, - "trial_config": { - "trial_period": 0, - "trial_period_unit": "days" - }, - "plan_phases": [ - { - "id": "string", - "description": "string", - "duration": 0, - "duration_unit": "daily", - "name": "string", - "order": 0, - "minimum": { - "minimum_amount": "string", - "applies_to_price_ids": [ - "string" - ] - }, - "maximum": { - "maximum_amount": "string", - "applies_to_price_ids": [ - "string" - ] - }, - "maximum_amount": "string", - "minimum_amount": "string", - "discount": { - "discount_type": "percentage", - "applies_to_price_ids": [ - "h74gfhdjvn7ujokd", - "7hfgtgjnbvc3ujkl" - ], - "reason": "string", - "percentage_discount": 0.15 - } - } - ], - "base_plan": { - "id": "m2t5akQeh2obwxeU", - "external_plan_id": "m2t5akQeh2obwxeU", - "name": "Example plan" - }, - "base_plan_id": "string", - "external_plan_id": "string", - "currency": "string", - "invoicing_currency": "string", - "net_terms": 0, - "default_invoice_memo": "string", - "prices": [ - {}, - {}, - {}, - {}, - {}, - {}, - {}, - {}, - {}, - {}, - {}, - {}, - {}, - {}, - {}, - {}, - {}, - {} - ] - }, - "start_date": "2024-06-21T22:27:22.237Z", - "end_date": "2024-06-21T22:27:22.237Z", - "created_at": "2024-06-21T22:27:22.237Z", - "current_billing_period_start_date": "2024-06-21T22:27:22.237Z", - "current_billing_period_end_date": "2024-06-21T22:27:22.237Z", - "status": "active", - "trial_info": { - "end_date": "2024-06-21T22:27:22.237Z" - }, - "active_plan_phase_order": 0, - "fixed_fee_quantity_schedule": [ - { - "price_id": "string", - "start_date": "2024-06-21T22:27:22.237Z", - "end_date": "2024-06-21T22:27:22.237Z", - "quantity": 0 - } - ], - "default_invoice_memo": "string", - "auto_collection": True, - "net_terms": 0, - "redeemed_coupon": { - "coupon_id": "string", - "start_date": "2024-06-21T22:27:22.237Z", - "end_date": "2024-06-21T22:27:22.237Z" - }, - "billing_cycle_day": 0, - "invoicing_threshold": "string", - "price_intervals": [ - { - "id": "string", - "start_date": "2024-06-21T22:27:22.245Z", - "end_date": "2024-06-21T22:27:22.245Z", - "price": { - "id": "string", - "name": "string", - "external_price_id": "string", - "price_type": "usage_price", - "model_type": "unit", - "created_at": "2024-06-21T22:27:22.245Z", - "cadence": "one_time", - "billable_metric": { - "id": "string" - }, - "fixed_price_quantity": 0, - "plan_phase_order": 0, - "currency": "string", - "conversion_rate": 0, - "item": { - "id": "string", - "name": "string" - }, - "credit_allocation": { - "currency": "string", - "allows_rollover": True - }, - "discount": { - "discount_type": "percentage", - "applies_to_price_ids": [ - "h74gfhdjvn7ujokd", - "7hfgtgjnbvc3ujkl" - ], - "reason": "string", - "percentage_discount": 0.15 - }, - "minimum": { - "minimum_amount": "string", - "applies_to_price_ids": [ - "string" - ] - }, - "minimum_amount": "string", - "maximum": { - "maximum_amount": "string", - "applies_to_price_ids": [ - "string" - ] - }, - "maximum_amount": "string", - "unit_config": { - "unit_amount": "string" - } - }, - "billing_cycle_day": 0, - "fixed_fee_quantity_transitions": [ - { - "price_id": "string", - "effective_date": "2024-06-21T22:27:22.246Z", - "quantity": 0 - } - ], - "current_billing_period_start_date": "2024-06-21T22:27:22.246Z", - "current_billing_period_end_date": "2024-06-21T22:27:22.246Z" - } - ], - "adjustment_intervals": [ - { - "id": "string", - "adjustment": { - "applies_to_price_ids": [ - "string" - ], - "reason": "string", - "adjustment_type": "amount_discount", - "amount_discount": "string" - }, - "start_date": "2024-06-21T22:27:22.246Z", - "end_date": "2024-06-21T22:27:22.246Z", - "applies_to_price_interval_ids": [ - "string" - ] - } - ], - "discount_intervals": [ - {}, - {}, - {} - ], - "minimum_intervals": [ - { - "start_date": "2024-06-21T22:27:22.246Z", - "end_date": "2024-06-21T22:27:22.246Z", - "applies_to_price_ids": [ - "string" - ], - "applies_to_price_interval_ids": [ - "string" - ], - "minimum_amount": "string" - } - ], - "maximum_intervals": [ - { - "start_date": "2024-06-21T22:27:22.246Z", - "end_date": "2024-06-21T22:27:22.246Z", - "applies_to_price_ids": [ - "string" - ], - "applies_to_price_interval_ids": [ - "string" - ], - "maximum_amount": "string" - } - ] - } - ], - "pagination_metadata": { - "has_more": False, - } -} diff --git a/airbyte-integrations/connectors/source-orb/unit_tests/test_incremental_streams.py b/airbyte-integrations/connectors/source-orb/unit_tests/test_incremental_streams.py deleted file mode 100644 index 3c7766a3baf8..000000000000 --- a/airbyte-integrations/connectors/source-orb/unit_tests/test_incremental_streams.py +++ /dev/null @@ -1,62 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Mapping - -import pytest -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.streams import Stream -from source_orb.source import SourceOrb - - -def get_stream_by_name(stream_name: str, config: Mapping[str, Any]) -> Stream: - source = SourceOrb() - matches_by_name = [stream_config for stream_config in source.streams(config) if stream_config.name == stream_name] - if not matches_by_name: - raise ValueError("Please provide a valid stream name.") - return matches_by_name[0] - - -def test_cursor_field(config_pass): - stream = get_stream_by_name("subscriptions", config_pass) - expected_cursor_field = "created_at" - assert stream.cursor_field == expected_cursor_field - - -def test_get_updated_state(requests_mock, config_pass, subscriptions_url, mock_subscriptions_response): - requests_mock.get(url=subscriptions_url, status_code=200, json=mock_subscriptions_response) - stream = get_stream_by_name("subscriptions", config_pass) - stream.state = {"created_at": "2020-01-10T00:00:00.000Z"} - records = [] - for stream_slice in stream.stream_slices(sync_mode=SyncMode.incremental): - for record in stream.read_records(sync_mode=SyncMode.incremental, stream_slice=stream_slice): - record_dict = dict(record) - records.append(record_dict) - new_stream_state = record_dict.get("created_at") - stream.state = {"created_at": new_stream_state} - expected_state = {"created_at": "2024-06-21T22:27:22.237Z"} - assert stream.state == expected_state - - -def test_stream_slices(requests_mock, config_pass, subscriptions_url, mock_subscriptions_response): - requests_mock.get(url=subscriptions_url, status_code=200, json=mock_subscriptions_response) - stream = get_stream_by_name("subscriptions", config_pass) - inputs = {"sync_mode": SyncMode.incremental, "cursor_field": ["created_at"], "stream_state": {"updatedAt": "2020-01-10T00:00:00.000Z"}} - assert stream.stream_slices(**inputs) is not None - - -def test_supports_incremental(config_pass): - stream = get_stream_by_name("subscriptions", config_pass) - assert stream.supports_incremental - - -def test_source_defined_cursor(config_pass): - stream = get_stream_by_name("subscriptions", config_pass) - assert stream.source_defined_cursor - - -def test_stream_checkpoint_interval(config_pass): - stream = get_stream_by_name("subscriptions", config_pass) - expected_checkpoint_interval = None - assert stream.state_checkpoint_interval == expected_checkpoint_interval diff --git a/airbyte-integrations/connectors/source-orb/unit_tests/test_source.py b/airbyte-integrations/connectors/source-orb/unit_tests/test_source.py deleted file mode 100644 index 22d93fb177aa..000000000000 --- a/airbyte-integrations/connectors/source-orb/unit_tests/test_source.py +++ /dev/null @@ -1,41 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from datetime import datetime, timedelta -from unittest.mock import MagicMock -from urllib import parse - -from source_orb.source import SourceOrb - - -def get_mocked_url(base_url, config_pass): - start_datetime = datetime.strptime(config_pass.get("start_date"), "%Y-%m-%dT%H:%M:%SZ").strftime('%Y-%m-%dT%H:%M:%S+00:00') - encoded_start_datetime = parse.quote(start_datetime, safe='') - # Add an offset because the time changes by the time python makes the request - end_datetime = (datetime.utcnow() + timedelta(milliseconds=400)).strftime('%Y-%m-%dT%H:%M:%S+00:00') - encoded_end_datetime = parse.quote(end_datetime, safe='') - return base_url + "?limit=50&created_at%5Bgte%5D=" + encoded_start_datetime + "&created_at%5Blte%5D=" + encoded_end_datetime - -def test_check_connection(requests_mock, config_pass, subscriptions_url, mock_subscriptions_response): - requests_mock.get(url=get_mocked_url(subscriptions_url, config_pass), status_code=200, json=mock_subscriptions_response) - source = SourceOrb() - logger_mock = MagicMock() - assert source.check_connection(logger_mock, config_pass) == (True, None) - - -def test_check_connection_fail(requests_mock, config_pass, subscriptions_url): - print(get_mocked_url(subscriptions_url, config_pass)) - requests_mock.get(url=get_mocked_url(subscriptions_url, config_pass), status_code=401, json={"error": "Unauthorized"}) - source = SourceOrb() - logger_mock = MagicMock() - (status, message) = source.check_connection(logger_mock, config_pass) - assert (status, message.split('-')[0].strip()) == (False, "Unable to connect to stream subscriptions") - - -def test_streams(requests_mock, config_pass, subscriptions_url, mock_subscriptions_response): - requests_mock.get(url=get_mocked_url(subscriptions_url, config_pass), status_code=200, json=mock_subscriptions_response) - source = SourceOrb() - streams = source.streams(config_pass) - expected_streams_number = 6 - assert len(streams) == expected_streams_number diff --git a/airbyte-integrations/connectors/source-orb/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-orb/unit_tests/test_streams.py deleted file mode 100644 index 1385ba2b9a1a..000000000000 --- a/airbyte-integrations/connectors/source-orb/unit_tests/test_streams.py +++ /dev/null @@ -1,76 +0,0 @@ -# -# Copyright (c) 2024s Airbyte, Inc., all rights reserved. -# - -from typing import Any, Mapping - -import pytest -from airbyte_cdk.sources.streams import Stream -from airbyte_protocol.models import SyncMode -from jsonref import requests -from source_orb.source import SourceOrb - - -def get_stream_by_name(stream_name: str, config: Mapping[str, Any]) -> Stream: - source = SourceOrb() - matches_by_name = [stream_config for stream_config in source.streams(config) if stream_config.name == stream_name] - if not matches_by_name: - raise ValueError("Please provide a valid stream name.") - return matches_by_name[0] - - -def test_request_params(config_pass): - stream = get_stream_by_name("subscriptions", config_pass) - expected_params = {} - assert stream.retriever.requester.get_request_params() == expected_params - - -@pytest.mark.parametrize( - ("mock_response", "expected_token"), - [ - ({}, None), - (dict(pagination_metadata=dict(has_more=True, next_cursor="orb-test-cursor")), dict(next_page_token="orb-test-cursor")), - (dict(pagination_metadata=dict(has_more=False)), None), - ], -) -def test_next_page_token(requests_mock, config_pass, subscriptions_url, mock_response, expected_token): - requests_mock.get(url=subscriptions_url, status_code=200, json=mock_response) - stream = get_stream_by_name("subscriptions", config_pass) - inputs = {"response": requests.get(subscriptions_url)} - assert stream.retriever._next_page_token(**inputs) == expected_token - - -@pytest.mark.parametrize( - ("mock_response", "expected_parsed_records"), - [ - ({}, []), - (dict(data=[]), []), - (dict(data=[{"id": "test-customer-id", "customer": {"id": "1", "external_customer_id": "2"}, "plan": {"id": "3"}}]), - [{"id": "test-customer-id", "customer_id": "1", "external_customer_id": "2", "plan_id": "3"}]), - (dict(data=[{"id": "test-customer-id", "customer": {"id": "7", "external_customer_id": "8"}, "plan": {"id": "9"}}, - {"id": "test-customer-id-2", "customer": {"id": "10", "external_customer_id": "11"}, "plan": {"id": "12"}}]), - [{"id": "test-customer-id", "customer_id": "7", "external_customer_id": "8", "plan_id": "9"}, - {"id": "test-customer-id-2", "customer_id": "10", "external_customer_id": "11", "plan_id": "9"}]), - ], -) -def test_parse_response(requests_mock, config_pass, subscriptions_url, mock_response, expected_parsed_records): - requests_mock.get(url=subscriptions_url, status_code=200, json=mock_response) - stream = get_stream_by_name("subscriptions", config_pass) - records = [] - for stream_slice in stream.stream_slices(sync_mode=SyncMode.full_refresh): - records.extend(list(stream.read_records(sync_mode=SyncMode.full_refresh, stream_slice=stream_slice))) - assert len(records) == len(expected_parsed_records) - for i in range(len(records)): - assert sorted(records[i].keys()) == sorted(expected_parsed_records[i].keys()) - - -def test_http_method(config_pass): - stream = get_stream_by_name("subscriptions", config_pass) - expected_method = "GET" - assert stream.retriever.requester.http_method.value == expected_method - - -def test_subscription_usage_schema(config_pass): - stream = get_stream_by_name("subscription_usage", config_pass) - json_schema = stream.get_json_schema() - assert len(json_schema["properties"]) == 7 diff --git a/airbyte-integrations/connectors/source-oura/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-oura/integration_tests/acceptance.py index efc25f08ce82..78b220cebb18 100644 --- a/airbyte-integrations/connectors/source-oura/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-oura/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-oura/metadata.yaml b/airbyte-integrations/connectors/source-oura/metadata.yaml index ffd8db94318b..ceb4e278ce81 100644 --- a/airbyte-integrations/connectors/source-oura/metadata.yaml +++ b/airbyte-integrations/connectors/source-oura/metadata.yaml @@ -12,11 +12,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 2bf6c581-bec5-4e32-891d-de33036bd631 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.8 dockerRepository: airbyte/source-oura githubIssueLabel: source-oura icon: oura.svg diff --git a/airbyte-integrations/connectors/source-outbrain-amplify/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-outbrain-amplify/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-outbrain-amplify/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-outbrain-amplify/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-outbrain-amplify/main.py b/airbyte-integrations/connectors/source-outbrain-amplify/main.py index dc58d39d5bcd..4b31ffa82fcf 100644 --- a/airbyte-integrations/connectors/source-outbrain-amplify/main.py +++ b/airbyte-integrations/connectors/source-outbrain-amplify/main.py @@ -4,5 +4,6 @@ from source_outbrain_amplify.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-outbrain-amplify/metadata.yaml b/airbyte-integrations/connectors/source-outbrain-amplify/metadata.yaml index caa928f0125c..e8d75e607dd3 100644 --- a/airbyte-integrations/connectors/source-outbrain-amplify/metadata.yaml +++ b/airbyte-integrations/connectors/source-outbrain-amplify/metadata.yaml @@ -3,7 +3,7 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorTestSuitesOptions: - suite: unitTests @@ -16,7 +16,7 @@ data: type: GSM connectorType: source definitionId: 4fe962d0-a70e-4516-aa99-c551abf46352 - dockerImageTag: 0.1.20 + dockerImageTag: 0.1.25 dockerRepository: airbyte/source-outbrain-amplify documentationUrl: https://docs.airbyte.com/integrations/sources/outbrain-amplify githubIssueLabel: source-outbrain-amplify diff --git a/airbyte-integrations/connectors/source-outbrain-amplify/poetry.lock b/airbyte-integrations/connectors/source-outbrain-amplify/poetry.lock index 955ecb2c35d5..1cebd7e7bcb4 100644 --- a/airbyte-integrations/connectors/source-outbrain-amplify/poetry.lock +++ b/airbyte-integrations/connectors/source-outbrain-amplify/poetry.lock @@ -52,19 +52,19 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -130,127 +130,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -266,20 +253,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -371,13 +358,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -490,13 +477,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -566,54 +553,54 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -681,13 +668,13 @@ files = [ [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] @@ -875,44 +862,74 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] name = "tomli" -version = "2.0.2" +version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] [[package]] @@ -942,13 +959,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -973,81 +990,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-outbrain-amplify/pyproject.toml b/airbyte-integrations/connectors/source-outbrain-amplify/pyproject.toml index 6221c5bcb461..4b54e3ea4a7f 100644 --- a/airbyte-integrations/connectors/source-outbrain-amplify/pyproject.toml +++ b/airbyte-integrations/connectors/source-outbrain-amplify/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.20" +version = "0.1.25" name = "source-outbrain-amplify" description = "Source implementation for outbrain amplify." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-outbrain-amplify/source_outbrain_amplify/auth.py b/airbyte-integrations/connectors/source-outbrain-amplify/source_outbrain_amplify/auth.py index 18248b027d46..4fa2955b1a75 100644 --- a/airbyte-integrations/connectors/source-outbrain-amplify/source_outbrain_amplify/auth.py +++ b/airbyte-integrations/connectors/source-outbrain-amplify/source_outbrain_amplify/auth.py @@ -5,9 +5,10 @@ from typing import Any, Mapping import requests -from airbyte_cdk.sources.streams.http.auth import TokenAuthenticator from requests.auth import HTTPBasicAuth +from airbyte_cdk.sources.streams.http.auth import TokenAuthenticator + class OutbrainAmplifyAuthenticator(TokenAuthenticator): def __init__(self, config, url_base): diff --git a/airbyte-integrations/connectors/source-outbrain-amplify/source_outbrain_amplify/source.py b/airbyte-integrations/connectors/source-outbrain-amplify/source_outbrain_amplify/source.py index ae0a7b4d6c70..628314fc4659 100644 --- a/airbyte-integrations/connectors/source-outbrain-amplify/source_outbrain_amplify/source.py +++ b/airbyte-integrations/connectors/source-outbrain-amplify/source_outbrain_amplify/source.py @@ -8,6 +8,7 @@ import pendulum import requests + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream @@ -15,6 +16,7 @@ from .auth import OutbrainAmplifyAuthenticator + DEFAULT_END_DATE = pendulum.now() DEFAULT_GEO_LOCATION_BREAKDOWN = "region" DEFAULT_REPORT_GRANULARITY = "daily" @@ -122,7 +124,6 @@ def name(self) -> str: def stream_slices( self, sync_mode: SyncMode.full_refresh, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - parent_stream_slices = self.parent.stream_slices( sync_mode=SyncMode.full_refresh, cursor_field=cursor_field, stream_state=stream_state ) @@ -174,7 +175,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def stream_slices( self, sync_mode: SyncMode.full_refresh, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - parent_stream_slices = self.parent.stream_slices( sync_mode=SyncMode.full_refresh, cursor_field=cursor_field, stream_state=stream_state ) @@ -223,7 +223,6 @@ def name(self) -> str: def stream_slices( self, sync_mode: SyncMode.full_refresh, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - parent_stream_slices = self.parent.stream_slices( sync_mode=SyncMode.full_refresh, cursor_field=cursor_field, stream_state=stream_state ) @@ -267,7 +266,6 @@ def __init__(self, authenticator, config, parent: CampaignsByMarketers, **kwargs def stream_slices( self, sync_mode: SyncMode.full_refresh, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - parent_stream_slices = self.parent.stream_slices( sync_mode=SyncMode.full_refresh, cursor_field=cursor_field, stream_state=stream_state ) @@ -323,7 +321,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def stream_slices( self, sync_mode: SyncMode.full_refresh, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - parent_stream_slices = self.parent.stream_slices( sync_mode=SyncMode.full_refresh, cursor_field=cursor_field, stream_state=stream_state ) @@ -376,7 +373,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def stream_slices( self, sync_mode: SyncMode.full_refresh, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - parent_stream_slices = self.parent.stream_slices( sync_mode=SyncMode.full_refresh, cursor_field=cursor_field, stream_state=stream_state ) @@ -437,7 +433,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def stream_slices( self, sync_mode: SyncMode.full_refresh, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - parent_stream_slices = self.parent.stream_slices( sync_mode=SyncMode.full_refresh, cursor_field=cursor_field, stream_state=stream_state ) @@ -500,7 +495,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def stream_slices( self, sync_mode: SyncMode.full_refresh, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - parent_stream_slices = self.parent.stream_slices( sync_mode=SyncMode.full_refresh, cursor_field=cursor_field, stream_state=stream_state ) @@ -569,7 +563,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def stream_slices( self, sync_mode: SyncMode.full_refresh, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - parent_stream_slices = self.parent.stream_slices( sync_mode=SyncMode.full_refresh, cursor_field=cursor_field, stream_state=stream_state ) @@ -635,7 +628,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def stream_slices( self, sync_mode: SyncMode.full_refresh, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - parent_stream_slices = self.parent.stream_slices( sync_mode=SyncMode.full_refresh, cursor_field=cursor_field, stream_state=stream_state ) @@ -696,7 +688,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def stream_slices( self, sync_mode: SyncMode.full_refresh, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - parent_stream_slices = self.parent.stream_slices( sync_mode=SyncMode.full_refresh, cursor_field=cursor_field, stream_state=stream_state ) @@ -759,7 +750,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def stream_slices( self, sync_mode: SyncMode.full_refresh, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - parent_stream_slices = self.parent.stream_slices( sync_mode=SyncMode.full_refresh, cursor_field=cursor_field, stream_state=stream_state ) @@ -820,7 +810,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def stream_slices( self, sync_mode: SyncMode.full_refresh, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - parent_stream_slices = self.parent.stream_slices( sync_mode=SyncMode.full_refresh, cursor_field=cursor_field, stream_state=stream_state ) @@ -883,7 +872,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def stream_slices( self, sync_mode: SyncMode.full_refresh, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - parent_stream_slices = self.parent.stream_slices( sync_mode=SyncMode.full_refresh, cursor_field=cursor_field, stream_state=stream_state ) @@ -946,7 +934,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def stream_slices( self, sync_mode: SyncMode.full_refresh, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - parent_stream_slices = self.parent.stream_slices( sync_mode=SyncMode.full_refresh, cursor_field=cursor_field, stream_state=stream_state ) @@ -1011,7 +998,6 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, def stream_slices( self, sync_mode: SyncMode.full_refresh, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None ) -> Iterable[Optional[Mapping[str, Any]]]: - parent_stream_slices = self.parent.stream_slices( sync_mode=SyncMode.full_refresh, cursor_field=cursor_field, stream_state=stream_state ) @@ -1051,7 +1037,6 @@ def path( class IncrementalOutbrainAmplifyStream(OutbrainAmplifyStream, ABC): - state_checkpoint_interval = None @property @@ -1098,7 +1083,7 @@ def streams(self, config: Mapping[str, Any]) -> List[Stream]: # Budget for Marketers stream. # 1. Budget stream based on marketers id. - stream.extend([BudgetsForMarketers(authenticator=auth, config=config, parent=Marketers(authenticator=auth, config=config))]), + (stream.extend([BudgetsForMarketers(authenticator=auth, config=config, parent=Marketers(authenticator=auth, config=config))]),) # Promoted Links stream. # 1. Promoted Links stream for campaigns. diff --git a/airbyte-integrations/connectors/source-outbrain-amplify/unit_tests/test_incremental_streams.py b/airbyte-integrations/connectors/source-outbrain-amplify/unit_tests/test_incremental_streams.py index 5f06ad6891b3..f545aa24ff73 100644 --- a/airbyte-integrations/connectors/source-outbrain-amplify/unit_tests/test_incremental_streams.py +++ b/airbyte-integrations/connectors/source-outbrain-amplify/unit_tests/test_incremental_streams.py @@ -3,10 +3,11 @@ # -from airbyte_cdk.models import SyncMode from pytest import fixture from source_outbrain_amplify.source import IncrementalOutbrainAmplifyStream +from airbyte_cdk.models import SyncMode + @fixture def patch_incremental_base_class(mocker): diff --git a/airbyte-integrations/connectors/source-outreach/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-outreach/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-outreach/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-outreach/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-outreach/main.py b/airbyte-integrations/connectors/source-outreach/main.py index a5b35a64025f..3fbcc84e8fb7 100644 --- a/airbyte-integrations/connectors/source-outreach/main.py +++ b/airbyte-integrations/connectors/source-outreach/main.py @@ -4,5 +4,6 @@ from source_outreach.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-outreach/metadata.yaml b/airbyte-integrations/connectors/source-outreach/metadata.yaml index ffda57f7c0ed..a980a429b590 100644 --- a/airbyte-integrations/connectors/source-outreach/metadata.yaml +++ b/airbyte-integrations/connectors/source-outreach/metadata.yaml @@ -22,11 +22,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 3490c201-5d95-4783-b600-eaf07a4c7787 - dockerImageTag: 1.0.22 + dockerImageTag: 1.0.27 dockerRepository: airbyte/source-outreach githubIssueLabel: source-outreach icon: outreach.svg diff --git a/airbyte-integrations/connectors/source-outreach/poetry.lock b/airbyte-integrations/connectors/source-outreach/poetry.lock index 95df18bc0255..0fe55e803c83 100644 --- a/airbyte-integrations/connectors/source-outreach/poetry.lock +++ b/airbyte-integrations/connectors/source-outreach/poetry.lock @@ -42,13 +42,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] @@ -56,41 +56,41 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -156,13 +156,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -246,116 +246,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -425,20 +412,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -488,13 +475,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -509,13 +496,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -523,7 +510,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -573,13 +559,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -669,22 +655,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -757,69 +746,86 @@ files = [ [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -911,54 +917,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -970,13 +976,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1043,13 +1049,13 @@ files = [ [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] @@ -1262,33 +1268,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1319,13 +1325,43 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "tomli" -version = "2.0.2" +version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] [[package]] @@ -1355,13 +1391,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1386,81 +1422,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-outreach/pyproject.toml b/airbyte-integrations/connectors/source-outreach/pyproject.toml index d35b68deae30..1c25165612b4 100644 --- a/airbyte-integrations/connectors/source-outreach/pyproject.toml +++ b/airbyte-integrations/connectors/source-outreach/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "1.0.22" +version = "1.0.27" name = "source-outreach" description = "Source implementation for outreach." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-outreach/source_outreach/components.py b/airbyte-integrations/connectors/source-outreach/source_outreach/components.py index 48ee70c5c1b6..2fe67a2a6bbd 100644 --- a/airbyte-integrations/connectors/source-outreach/source_outreach/components.py +++ b/airbyte-integrations/connectors/source-outreach/source_outreach/components.py @@ -6,6 +6,7 @@ from typing import Any, Dict, List, Mapping, MutableMapping, Optional import requests + from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor from airbyte_cdk.sources.declarative.incremental import DatetimeBasedCursor from airbyte_cdk.sources.declarative.types import StreamSlice, StreamState diff --git a/airbyte-integrations/connectors/source-outreach/source_outreach/run.py b/airbyte-integrations/connectors/source-outreach/source_outreach/run.py index f9daaa87c1e4..a3af865c1b7f 100644 --- a/airbyte-integrations/connectors/source-outreach/source_outreach/run.py +++ b/airbyte-integrations/connectors/source-outreach/source_outreach/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_outreach import SourceOutreach +from airbyte_cdk.entrypoint import launch + def run(): source = SourceOutreach() diff --git a/airbyte-integrations/connectors/source-outreach/source_outreach/source.py b/airbyte-integrations/connectors/source-outreach/source_outreach/source.py index 3faed388f99e..4f55b84029a8 100644 --- a/airbyte-integrations/connectors/source-outreach/source_outreach/source.py +++ b/airbyte-integrations/connectors/source-outreach/source_outreach/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-oveit/README.md b/airbyte-integrations/connectors/source-oveit/README.md new file mode 100644 index 000000000000..bc2cb47e3bc3 --- /dev/null +++ b/airbyte-integrations/connectors/source-oveit/README.md @@ -0,0 +1,33 @@ +# Oveit +This directory contains the manifest-only connector for `source-oveit`. + +An Airbyte connector for Oveit enables seamless data synchronization by extracting and integrating data from Oveit’s event management platform into your data warehouse. This connector helps automate the flow of information, providing up-to-date insights on event registrations, ticketing, and attendee information. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-oveit:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-oveit build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-oveit test +``` + diff --git a/airbyte-integrations/connectors/source-oveit/acceptance-test-config.yml b/airbyte-integrations/connectors/source-oveit/acceptance-test-config.yml new file mode 100644 index 000000000000..922a47b88a7b --- /dev/null +++ b/airbyte-integrations/connectors/source-oveit/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-oveit:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-oveit/icon.svg b/airbyte-integrations/connectors/source-oveit/icon.svg new file mode 100644 index 000000000000..a9a64d949c46 --- /dev/null +++ b/airbyte-integrations/connectors/source-oveit/icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/airbyte-integrations/connectors/source-oveit/manifest.yaml b/airbyte-integrations/connectors/source-oveit/manifest.yaml new file mode 100644 index 000000000000..7ca5df7825ee --- /dev/null +++ b/airbyte-integrations/connectors/source-oveit/manifest.yaml @@ -0,0 +1,334 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + An Airbyte connector for Oveit enables seamless data synchronization by + extracting and integrating data from Oveit’s event management platform into + your data warehouse. This connector helps automate the flow of information, + providing up-to-date insights on event registrations, ticketing, and attendee + information. + +check: + type: CheckStream + stream_names: + - events + +definitions: + streams: + events: + type: DeclarativeStream + name: events + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /seller/events + http_method: POST + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - events + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/events" + attendees: + type: DeclarativeStream + name: attendees + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /events/attendees + http_method: POST + request_parameters: + id: "{{ stream_partition.event_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - attendees + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: since + pagination_strategy: + type: CursorPagination + cursor_value: >- + {{ response.get('attendees', [])[-1].get('ticket_code') if + response.get('attendees') else None }} + stop_condition: "{{ not response.get('attendees') }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: event_id + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/attendees" + tickets: + type: DeclarativeStream + name: tickets + primary_key: + - code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /events/tickets + http_method: POST + request_parameters: + id: "{{ stream_partition.event_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - tickets + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: event_id + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tickets" + base_requester: + type: HttpRequester + url_base: https://l.oveit.com/api + authenticator: + type: SessionTokenAuthenticator + login_requester: + type: HttpRequester + url_base: https://l.oveit.com/api/seller + path: login + authenticator: + type: NoAuth + http_method: POST + request_parameters: + email: "{{ config['email'] }}" + password: "{{ config['password'] }}" + request_headers: {} + session_token_path: + - token + expiration_duration: PT8H + request_authentication: + type: Bearer + +streams: + - $ref: "#/definitions/streams/events" + - $ref: "#/definitions/streams/attendees" + - $ref: "#/definitions/streams/tickets" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - email + - password + properties: + email: + type: string + description: Oveit's login Email + order: 0 + title: Email + password: + type: string + description: Oveit's login Password + order: 1 + title: Password + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + events: true + attendees: false + tickets: false + testedStreams: + events: + hasRecords: true + streamHash: f272daaa63d772d4796ff2cb115233deb778f6a4 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + attendees: + hasRecords: true + streamHash: 617e77af6059788b625edcd74f29a72c8395285f + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + tickets: + hasRecords: true + streamHash: 6fb2c2f08030125bcee98b6bab8d99a56b21ebaa + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://l.oveit.com/api-documentation/ + +schemas: + events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + hash: + type: + - string + - "null" + id: + type: number + location: + type: + - string + - "null" + name: + type: + - string + - "null" + starts_at: + type: + - string + - "null" + ticket_types: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + addons: + type: + - array + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + price: + type: + - string + - "null" + tickets: + type: + - number + - "null" + tickets_checked_in: + type: + - number + - "null" + tickets_sold: + type: + - number + - "null" + required: + - id + attendees: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + checkins: + type: + - array + - "null" + created_at: + type: + - string + - "null" + id: + type: string + links: + type: + - array + - "null" + order_id: + type: + - string + - "null" + order_uuid: + type: + - string + - "null" + ticket_code: + type: + - string + - "null" + ticket_id: + type: + - string + - "null" + ticket_type: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + values: + type: + - array + - "null" + items: + type: + - string + - "null" + required: + - id + tickets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + checked_in: + type: + - boolean + - "null" + checkins: + type: + - array + - "null" + code: + type: string + ticket_type_id: + type: + - number + - "null" + required: + - code diff --git a/airbyte-integrations/connectors/source-oveit/metadata.yaml b/airbyte-integrations/connectors/source-oveit/metadata.yaml new file mode 100644 index 000000000000..b085104f2aba --- /dev/null +++ b/airbyte-integrations/connectors/source-oveit/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "l.oveit.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-oveit + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 339a939f-b56c-48d7-9f3a-1362d6a3fdeb + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-oveit + githubIssueLabel: source-oveit + icon: icon.svg + license: MIT + name: Oveit + releaseDate: 2024-10-24 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/oveit + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-pabbly-subscriptions-billing/README.md b/airbyte-integrations/connectors/source-pabbly-subscriptions-billing/README.md new file mode 100644 index 000000000000..2c97d1098809 --- /dev/null +++ b/airbyte-integrations/connectors/source-pabbly-subscriptions-billing/README.md @@ -0,0 +1,33 @@ +# Pabbly Subscriptions Billing +This directory contains the manifest-only connector for `source-pabbly-subscriptions-billing`. + +Airbyte connector for [Pabbly Subscriptions Billing](https://www.pabbly.com/subscriptions/) enables seamless data synchronization between Pabbly's subscription management platform and your preferred data warehouse or analytics environment. With this connector, users can automate the extraction of key subscription data—such as customer details, payment transactions, and subscription statuses—allowing for efficient reporting, analysis, and decision-making without manual intervention + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-pabbly-subscriptions-billing:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-pabbly-subscriptions-billing build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-pabbly-subscriptions-billing test +``` + diff --git a/airbyte-integrations/connectors/source-pabbly-subscriptions-billing/acceptance-test-config.yml b/airbyte-integrations/connectors/source-pabbly-subscriptions-billing/acceptance-test-config.yml new file mode 100644 index 000000000000..7fcff5b8ee81 --- /dev/null +++ b/airbyte-integrations/connectors/source-pabbly-subscriptions-billing/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-pabbly-subscriptions-billing:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-pabbly-subscriptions-billing/icon.svg b/airbyte-integrations/connectors/source-pabbly-subscriptions-billing/icon.svg new file mode 100644 index 000000000000..ee24bd1cbe07 --- /dev/null +++ b/airbyte-integrations/connectors/source-pabbly-subscriptions-billing/icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/airbyte-integrations/connectors/source-pabbly-subscriptions-billing/manifest.yaml b/airbyte-integrations/connectors/source-pabbly-subscriptions-billing/manifest.yaml new file mode 100644 index 000000000000..700494b9087f --- /dev/null +++ b/airbyte-integrations/connectors/source-pabbly-subscriptions-billing/manifest.yaml @@ -0,0 +1,2777 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Airbyte connector for [Pabbly Subscriptions + Billing](https://www.pabbly.com/subscriptions/) enables seamless data + synchronization between Pabbly's subscription management platform and your + preferred data warehouse or analytics environment. With this connector, users + can automate the extraction of key subscription data—such as customer details, + payment transactions, and subscription statuses—allowing for efficient + reporting, analysis, and decision-making without manual intervention + +check: + type: CheckStream + stream_names: + - customers + +definitions: + streams: + addons: + type: DeclarativeStream + name: addons + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /addons/{{ stream_partition.product_id }} + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: + $ref: "#/definitions/streams/products" + parent_key: id + partition_field: product_id + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/addons" + coupons: + type: DeclarativeStream + name: coupons + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /coupon/{{ stream_partition.product_id }} + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: + $ref: "#/definitions/streams/products" + parent_key: id + partition_field: product_id + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/coupons" + refunds: + type: DeclarativeStream + name: refunds + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /refund/{{ stream_partition.customer_id }} + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + predicate: "{{ response.message== 'No transaction found'}}" + http_codes: [] + error_message: No transaction found + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: + $ref: "#/definitions/streams/customers" + parent_key: id + partition_field: customer_id + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/refunds" + invoices: + type: DeclarativeStream + name: invoices + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /invoices + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/invoices" + licenses: + type: DeclarativeStream + name: licenses + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /products/{{ stream_partition.product_id }}/licenses + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: + $ref: "#/definitions/streams/products" + parent_key: id + partition_field: product_id + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/licenses" + products: + type: DeclarativeStream + name: products + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /products + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + customers: + type: DeclarativeStream + name: customers + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /customers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers" + multiplans: + type: DeclarativeStream + name: multiplans + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /multiplans + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/multiplans" + transactions: + type: DeclarativeStream + name: transactions + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /transactions/{{ stream_partition.customer_id }} + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: + $ref: "#/definitions/streams/customers" + parent_key: id + partition_field: customer_id + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/transactions" + subscriptions: + type: DeclarativeStream + name: subscriptions + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /subscriptions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/subscriptions" + payment_methods: + type: DeclarativeStream + name: payment_methods + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /paymentmethods/{{ stream_partition.customer_id }} + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: + $ref: "#/definitions/streams/customers" + parent_key: id + partition_field: customer_id + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/payment_methods" + payment_gateways: + type: DeclarativeStream + name: payment_gateways + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /paymentgateways + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/payment_gateways" + addon_list_category: + type: DeclarativeStream + name: addon_list_category + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + requester: + $ref: "#/definitions/base_requester" + path: /addonlistcategory/{{ stream_partition.product_id }} + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: + $ref: "#/definitions/streams/products" + parent_key: id + partition_field: product_id + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/addon_list_category" + base_requester: + type: HttpRequester + url_base: https://payments.pabbly.com/api/v1 + authenticator: + type: BasicHttpAuthenticator + password: "{{ config[\"password\"] }}" + username: "{{ config[\"username\"] }}" + +streams: + - $ref: "#/definitions/streams/customers" + - $ref: "#/definitions/streams/subscriptions" + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/coupons" + - $ref: "#/definitions/streams/invoices" + - $ref: "#/definitions/streams/payment_methods" + - $ref: "#/definitions/streams/transactions" + - $ref: "#/definitions/streams/refunds" + - $ref: "#/definitions/streams/addons" + - $ref: "#/definitions/streams/addon_list_category" + - $ref: "#/definitions/streams/licenses" + - $ref: "#/definitions/streams/multiplans" + - $ref: "#/definitions/streams/payment_gateways" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - username + properties: + password: + type: string + order: 1 + title: Password + always_show: true + airbyte_secret: true + username: + type: string + order: 0 + title: Username + additionalProperties: true + +metadata: + assist: + docsUrl: https://apidocs.pabbly.com/ + testedStreams: + addons: + hasRecords: true + streamHash: 9e77c73d301959eb49d8d41acf99de2a4ae7aa5c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + coupons: + hasRecords: true + streamHash: d6bf85e555edcc9c395c18326406b3ba962ce3b4 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + refunds: + hasRecords: true + streamHash: 1aaf274d35f632f81505cbdc1eadd2452a945618 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + invoices: + hasRecords: true + streamHash: bfa30465ad31cf33eb2a8815af03ffa584bfc432 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + licenses: + hasRecords: true + streamHash: f1c21c05c57c6c41a766d063fb669dc43d629435 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + products: + hasRecords: true + streamHash: f666802a2848ab12299682b153349af368a903d1 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + customers: + hasRecords: true + streamHash: 4c13be96256301b04b3a74652003ff62a4701f9c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + multiplans: + hasRecords: true + streamHash: 9a56e8ca6faa40a19a34c336d33eaf5c1b3cc61f + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + transactions: + hasRecords: true + streamHash: 371c1470744bd0d2867ec874c0395125ee9d7855 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + subscriptions: + hasRecords: true + streamHash: a27f2ad6ac7ee192dd9c2407529c64948d824582 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + payment_methods: + hasRecords: true + streamHash: e3c561b1fe2781418fd5a5f0926b33271ec73d72 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + payment_gateways: + hasRecords: true + streamHash: 48acc04f743c33500d13f5c20922657764fcedb5 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + addon_list_category: + hasRecords: true + streamHash: 14a6b33c340e647211090394ef8059533f7ac9f5 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + autoImportSchema: + addons: false + coupons: false + refunds: false + invoices: false + licenses: false + products: false + customers: false + multiplans: false + transactions: false + subscriptions: false + payment_methods: false + payment_gateways: false + addon_list_category: false + +schemas: + addons: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + code: + type: + - string + - "null" + name: + type: + - string + - "null" + price: + type: + - number + - "null" + status: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + product_id: + type: + - string + - "null" + billing_cycle: + type: + - string + - "null" + category_list: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + billing_period: + type: + - string + - "null" + category_array: + type: + - array + - "null" + items: + type: + - string + - "null" + associate_plans: + type: + - string + - "null" + additionalProperties: true + coupons: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + status: + type: + - string + - "null" + apply_to: + type: + - string + - "null" + discount: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + product_id: + type: + - string + - "null" + valid_upto: + type: + - string + - "null" + coupon_code: + type: + - string + - "null" + coupon_name: + type: + - string + - "null" + plans_array: + type: + - array + - "null" + items: + type: + - string + - "null" + discount_type: + type: + - string + - "null" + associate_plans: + type: + - string + - "null" + redemption_type: + type: + - string + - "null" + used_redemption: + type: + - number + - "null" + redemption_cycle: + type: + - number + - "null" + maximum_redemption: + type: + - number + - "null" + additionalProperties: true + refunds: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + id: + type: string + amount: + type: + - number + - "null" + status: + type: + - string + - "null" + plan_id: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + invoice_id: + type: + - string + - "null" + product_id: + type: + - string + - "null" + customer_id: + type: + - string + - "null" + transaction: + type: + - object + - "null" + properties: + transaction: + type: + - object + - "null" + properties: + state: + type: + - string + - "null" + token: + type: + - string + - "null" + amount: + type: + - number + - "null" + message: + type: + - string + - "null" + api_urls: + type: + - array + - "null" + response: + type: + - object + - "null" + properties: + message: + type: + - string + - "null" + pending: + type: + - boolean + - "null" + success: + type: + - boolean + - "null" + cancelled: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + result_unknown: + type: + - boolean + - "null" + succeeded: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + message_key: + type: + - string + - "null" + gateway_type: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + gateway_token: + type: + - string + - "null" + on_test_gateway: + type: + - boolean + - "null" + reference_token: + type: + - string + - "null" + shipping_address: + type: + - object + - "null" + properties: {} + transaction_type: + type: + - string + - "null" + gateway_latency_ms: + type: + - number + - "null" + gateway_transaction_id: + type: + - string + - "null" + gateway_specific_response_fields: + type: + - object + - "null" + gateway_type: + type: + - string + - "null" + reference_id: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + type_formated: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + subscription_id: + type: + - string + - "null" + status_formatted: + type: + - string + - "null" + additionalProperties: true + invoices: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + amount: + type: + - number + - "null" + status: + type: + - string + - "null" + license: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + codes: + type: + - array + - "null" + items: + type: + - string + - "null" + due_date: + type: + - string + - "null" + quantity: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + paid_date: + type: + - string + - "null" + setup_fee: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + due_amount: + type: + - number + - "null" + invoice_id: + type: + - string + - "null" + product_id: + type: + - string + - "null" + credit_note: + type: + - object + - "null" + properties: + status: + type: + - string + - "null" + total_tax: + type: + - string + - "null" + charge_amount: + type: + - number + - "null" + credit_applied: + type: + - array + - "null" + new_plan_total: + type: + - number + - "null" + total_credit_amount: + type: + - number + - "null" + customer_id: + type: + - string + - "null" + invoice_link: + type: + - string + - "null" + order_number: + type: + - string + - "null" + payment_term: + type: + - string + - "null" + subscription: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + plan: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + price: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + plan_code: + type: + - string + - "null" + plan_name: + type: + - string + - "null" + plan_type: + type: + - string + - "null" + setup_fee: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + product_id: + type: + - string + - "null" + plan_active: + type: + - string + - "null" + trial_period: + type: + - number + - "null" + billing_cycle: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + billing_period: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + plan_description: + type: + - string + - "null" + billing_period_num: + type: + - string + - "null" + addons: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + code: + type: + - string + - "null" + name: + type: + - string + - "null" + price: + type: + - number + - "null" + quantity: + type: + - number + - "null" + product_id: + type: + - string + - "null" + billing_cycle: + type: + - string + - "null" + billing_period: + type: + - string + - "null" + category_array: + type: + - array + - "null" + items: + type: + - string + - "null" + adjusted_amount: + type: + - number + - "null" + associate_plans: + type: + - string + - "null" + amount: + type: + - number + - "null" + coupon: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + status: + type: + - string + - "null" + apply_to: + type: + - string + - "null" + discount: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + product_id: + type: + - string + - "null" + valid_upto: + type: + - string + - "null" + coupon_code: + type: + - string + - "null" + coupon_name: + type: + - string + - "null" + discount_type: + type: + - string + - "null" + associate_plans: + type: + - string + - "null" + redemption_type: + type: + - string + - "null" + used_redemption: + type: + - number + - "null" + redemption_cycle: + type: + - number + - "null" + maximum_redemption: + type: + - number + - "null" + status: + type: + - string + - "null" + plan_id: + type: + - string + - "null" + taxable: + type: + - boolean + - "null" + email_id: + type: + - string + - "null" + quantity: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + setup_fee: + type: + - number + - "null" + starts_at: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + gateway_id: + type: + - string + - "null" + product_id: + type: + - string + - "null" + trial_days: + type: + - number + - "null" + customer_id: + type: + - string + - "null" + expiry_date: + type: + - string + - "null" + gateway_name: + type: + - string + - "null" + gateway_type: + type: + - string + - "null" + requested_ip: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + custom_fields: + type: + - array + - "null" + payment_terms: + type: + - string + - "null" + payment_method: + type: + - string + - "null" + activation_date: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + last_billing_date: + type: + - string + - "null" + next_billing_date: + type: + - string + - "null" + trial_expiry_date: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + subscription_id: + type: + - string + - "null" + additionalProperties: true + licenses: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + name: + type: + - string + - "null" + method: + type: + - string + - "null" + status: + type: + - string + - "null" + plan_id: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + used_license: + type: + - number + - "null" + license_codes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + code: + type: + - string + - "null" + is_used: + type: + - string + - "null" + total_license: + type: + - number + - "null" + additionalProperties: true + products: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + status: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + product_name: + type: + - string + - "null" + additionalProperties: true + customers: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + phone: + type: + - string + - "null" + credit: + type: + - object + - "null" + properties: + remaining: + type: + - number + - "null" + tax_id: + type: + - string + - "null" + website: + type: + - string + - "null" + email_id: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + last_name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + first_name: + type: + - string + - "null" + referral_id: + type: + - string + - "null" + company_name: + type: + - string + - "null" + is_affiliate: + type: + - boolean + - "null" + portal_status: + type: + - boolean + - "null" + billing_address: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + state: + type: + - string + - "null" + country: + type: + - string + - "null" + street1: + type: + - string + - "null" + street2: + type: + - string + - "null" + zip_code: + type: + - string + - "null" + attention: + type: + - string + - "null" + state_code: + type: + - string + - "null" + shipping_address: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + state: + type: + - string + - "null" + country: + type: + - string + - "null" + street1: + type: + - string + - "null" + street2: + type: + - string + - "null" + zip_code: + type: + - string + - "null" + attention: + type: + - string + - "null" + state_code: + type: + - string + - "null" + additionalProperties: true + multiplans: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + plans: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + price: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + plan_code: + type: + - string + - "null" + plan_name: + type: + - string + - "null" + plan_type: + type: + - string + - "null" + setup_fee: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + product_id: + type: + - string + - "null" + plan_active: + type: + - string + - "null" + trial_period: + type: + - number + - "null" + billing_cycle: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + billing_period: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + plan_description: + type: + - string + - "null" + billing_period_num: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + page_title: + type: + - string + - "null" + product_id: + type: + - string + - "null" + checkout_page: + type: + - string + - "null" + multiplan_list: + type: + - string + - "null" + additionalProperties: true + transactions: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + id: + type: string + amount: + type: + - number + - "null" + status: + type: + - string + - "null" + plan_id: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + invoice_id: + type: + - string + - "null" + product_id: + type: + - string + - "null" + customer_id: + type: + - string + - "null" + transaction: + type: + - object + - "null" + properties: + state: + type: + - string + - "null" + token: + type: + - string + - "null" + amount: + type: + - number + - "null" + message: + type: + - string + - "null" + api_urls: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + failover_transaction: + type: + - array + - "null" + referencing_transaction: + type: + - array + - "null" + response: + type: + - object + - "null" + properties: + message: + type: + - string + - "null" + pending: + type: + - boolean + - "null" + success: + type: + - boolean + - "null" + cancelled: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + result_unknown: + type: + - boolean + - "null" + succeeded: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + message_key: + type: + - string + - "null" + transaction: + type: + - object + - "null" + properties: + state: + type: + - string + - "null" + token: + type: + - string + - "null" + amount: + type: + - number + - "null" + message: + type: + - string + - "null" + api_urls: + type: + - array + - "null" + response: + type: + - object + - "null" + properties: + message: + type: + - string + - "null" + pending: + type: + - boolean + - "null" + success: + type: + - boolean + - "null" + cancelled: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + result_unknown: + type: + - boolean + - "null" + succeeded: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + message_key: + type: + - string + - "null" + gateway_type: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + gateway_token: + type: + - string + - "null" + on_test_gateway: + type: + - boolean + - "null" + reference_token: + type: + - string + - "null" + shipping_address: + type: + - object + - "null" + properties: {} + transaction_type: + type: + - string + - "null" + gateway_latency_ms: + type: + - number + - "null" + gateway_transaction_id: + type: + - string + - "null" + gateway_specific_response_fields: + type: + - object + - "null" + gateway_type: + type: + - string + - "null" + smart_routed: + type: + - boolean + - "null" + currency_code: + type: + - string + - "null" + gateway_token: + type: + - string + - "null" + payment_method: + type: + - object + - "null" + properties: + zip: + type: + - string + - "null" + city: + type: + - string + - "null" + test: + type: + - boolean + - "null" + year: + type: + - number + - "null" + email: + type: + - string + - "null" + month: + type: + - number + - "null" + state: + type: + - string + - "null" + token: + type: + - string + - "null" + errors: + type: + - array + - "null" + number: + type: + - string + - "null" + country: + type: + - string + - "null" + managed: + type: + - boolean + - "null" + address1: + type: + - string + - "null" + card_type: + type: + - string + - "null" + full_name: + type: + - string + - "null" + last_name: + type: + - string + - "null" + created_at: + type: + - string + - "null" + first_name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + fingerprint: + type: + - string + - "null" + bin_metadata: + type: + - object + - "null" + properties: + message: + type: + - string + - "null" + click_to_pay: + type: + - boolean + - "null" + storage_state: + type: + - string + - "null" + first_six_digits: + type: + - string + - "null" + last_four_digits: + type: + - string + - "null" + verification_value: + type: + - string + - "null" + payment_method_type: + type: + - string + - "null" + eligible_for_card_updater: + type: + - boolean + - "null" + issuer_identification_number: + type: + - string + - "null" + on_test_gateway: + type: + - boolean + - "null" + attempt_3dsecure: + type: + - boolean + - "null" + shipping_address: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + transaction_type: + type: + - string + - "null" + retain_on_success: + type: + - boolean + - "null" + gateway_latency_ms: + type: + - number + - "null" + populate_mit_fields: + type: + - boolean + - "null" + payment_method_added: + type: + - boolean + - "null" + gateway_transaction_id: + type: + - string + - "null" + gateway_specific_response_fields: + type: + - object + - "null" + gateway_type: + type: + - string + - "null" + reference_id: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + type_formated: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + subscription_id: + type: + - string + - "null" + status_formatted: + type: + - string + - "null" + additionalProperties: true + subscriptions: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + plan: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + price: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + plan_code: + type: + - string + - "null" + plan_name: + type: + - string + - "null" + plan_type: + type: + - string + - "null" + setup_fee: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + product_id: + type: + - string + - "null" + plan_active: + type: + - string + - "null" + trial_period: + type: + - number + - "null" + billing_cycle: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + billing_period: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + plan_description: + type: + - string + - "null" + billing_period_num: + type: + - string + - "null" + addons: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + code: + type: + - string + - "null" + name: + type: + - string + - "null" + price: + type: + - number + - "null" + quantity: + type: + - number + - "null" + product_id: + type: + - string + - "null" + billing_cycle: + type: + - string + - "null" + billing_period: + type: + - string + - "null" + category_array: + type: + - array + - "null" + items: + type: + - string + - "null" + adjusted_amount: + type: + - number + - "null" + associate_plans: + type: + - string + - "null" + amount: + type: + - number + - "null" + coupon: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + status: + type: + - string + - "null" + apply_to: + type: + - string + - "null" + discount: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + product_id: + type: + - string + - "null" + valid_upto: + type: + - string + - "null" + coupon_code: + type: + - string + - "null" + coupon_name: + type: + - string + - "null" + discount_type: + type: + - string + - "null" + associate_plans: + type: + - string + - "null" + redemption_type: + type: + - string + - "null" + used_redemption: + type: + - number + - "null" + redemption_cycle: + type: + - number + - "null" + maximum_redemption: + type: + - number + - "null" + status: + type: + - string + - "null" + plan_id: + type: + - string + - "null" + taxable: + type: + - boolean + - "null" + email_id: + type: + - string + - "null" + quantity: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + setup_fee: + type: + - number + - "null" + starts_at: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + gateway_id: + type: + - string + - "null" + product_id: + type: + - string + - "null" + trial_days: + type: + - number + - "null" + customer_id: + type: + - string + - "null" + expiry_date: + type: + - string + - "null" + gateway_name: + type: + - string + - "null" + gateway_type: + type: + - string + - "null" + requested_ip: + type: + - string + - "null" + canceled_date: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + custom_fields: + type: + - array + - "null" + payment_terms: + type: + - string + - "null" + payment_method: + type: + - string + - "null" + activation_date: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + last_billing_date: + type: + - string + - "null" + next_billing_date: + type: + - string + - "null" + trial_expiry_date: + type: + - string + - "null" + additionalProperties: true + payment_methods: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + type: + type: + - string + - "null" + id: + type: string + gateway: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + customer_id: + type: + - string + - "null" + additionalProperties: true + payment_gateways: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + createdAt: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + gateway_url: + type: + - string + - "null" + gateway_name: + type: + - string + - "null" + gateway_type: + type: + - string + - "null" + gateway_status: + type: + - boolean + - "null" + custom_gateway_type: + type: + - string + - "null" + additionalProperties: true + addon_list_category: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + category_name: + type: + - string + - "null" + additionalProperties: true diff --git a/airbyte-integrations/connectors/source-pabbly-subscriptions-billing/metadata.yaml b/airbyte-integrations/connectors/source-pabbly-subscriptions-billing/metadata.yaml new file mode 100644 index 000000000000..73fe4f1ad756 --- /dev/null +++ b/airbyte-integrations/connectors/source-pabbly-subscriptions-billing/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "payments.pabbly.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-pabbly-subscriptions-billing + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: b461c060-9d6a-43c9-a73c-634eaf83c4bf + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-pabbly-subscriptions-billing + githubIssueLabel: source-pabbly-subscriptions-billing + icon: icon.svg + license: MIT + name: Pabbly Subscriptions Billing + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/pabbly-subscriptions-billing + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-pagerduty/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-pagerduty/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-pagerduty/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-pagerduty/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-pagerduty/main.py b/airbyte-integrations/connectors/source-pagerduty/main.py index 22537946cc8c..15c7eed00df9 100644 --- a/airbyte-integrations/connectors/source-pagerduty/main.py +++ b/airbyte-integrations/connectors/source-pagerduty/main.py @@ -4,5 +4,6 @@ from source_pagerduty.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-pagerduty/source_pagerduty/run.py b/airbyte-integrations/connectors/source-pagerduty/source_pagerduty/run.py index f73afe9c6592..21f3c24f9f92 100644 --- a/airbyte-integrations/connectors/source-pagerduty/source_pagerduty/run.py +++ b/airbyte-integrations/connectors/source-pagerduty/source_pagerduty/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_pagerduty import SourcePagerduty +from airbyte_cdk.entrypoint import launch + def run(): source = SourcePagerduty() diff --git a/airbyte-integrations/connectors/source-pagerduty/source_pagerduty/source.py b/airbyte-integrations/connectors/source-pagerduty/source_pagerduty/source.py index 96ff2d87bbfb..2008ace84e36 100644 --- a/airbyte-integrations/connectors/source-pagerduty/source_pagerduty/source.py +++ b/airbyte-integrations/connectors/source-pagerduty/source_pagerduty/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-pandadoc/metadata.yaml b/airbyte-integrations/connectors/source-pandadoc/metadata.yaml index 542c24e0c9cf..1c7899747fc6 100644 --- a/airbyte-integrations/connectors/source-pandadoc/metadata.yaml +++ b/airbyte-integrations/connectors/source-pandadoc/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-pandadoc connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: c5719626-6fc3-48e6-8f1d-ca5d4ecd2b5c - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-pandadoc githubIssueLabel: source-pandadoc icon: icon.svg diff --git a/airbyte-integrations/connectors/source-paperform/README.md b/airbyte-integrations/connectors/source-paperform/README.md new file mode 100644 index 000000000000..2ce131a03c29 --- /dev/null +++ b/airbyte-integrations/connectors/source-paperform/README.md @@ -0,0 +1,33 @@ +# Paperform +This directory contains the manifest-only connector for `source-paperform`. + +Airbyte connector for [Paperform](https://paperform.co/) enables seamless data integration between Paperform and other platforms, allowing automated data synchronization and transfer from Paperform form submissions to your data warehouse or analytics tools. This connector helps streamline workflows by enabling data extraction, transformation, and loading (ETL) to leverage form data for insights and reporting across systems. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-paperform:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-paperform build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-paperform test +``` + diff --git a/airbyte-integrations/connectors/source-paperform/acceptance-test-config.yml b/airbyte-integrations/connectors/source-paperform/acceptance-test-config.yml new file mode 100644 index 000000000000..a0be688629f9 --- /dev/null +++ b/airbyte-integrations/connectors/source-paperform/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-paperform:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-paperform/icon.svg b/airbyte-integrations/connectors/source-paperform/icon.svg new file mode 100644 index 000000000000..01727ddcb67d --- /dev/null +++ b/airbyte-integrations/connectors/source-paperform/icon.svg @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-paperform/manifest.yaml b/airbyte-integrations/connectors/source-paperform/manifest.yaml new file mode 100644 index 000000000000..c5fc8d01a3b8 --- /dev/null +++ b/airbyte-integrations/connectors/source-paperform/manifest.yaml @@ -0,0 +1,849 @@ +version: 5.17.0 + +type: DeclarativeSource + +description: >- + Airbyte connector for [Paperform](https://paperform.co/) enables seamless data + integration between Paperform and other platforms, allowing automated data + synchronization and transfer from Paperform form submissions to your data + warehouse or analytics tools. This connector helps streamline workflows by + enabling data extraction, transformation, and loading (ETL) to leverage form + data for insights and reporting across systems. + +check: + type: CheckStream + stream_names: + - forms + +definitions: + streams: + forms: + type: DeclarativeStream + name: forms + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /forms + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + - forms + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/forms" + form_fields: + type: DeclarativeStream + name: form_fields + primary_key: + - key + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /forms/{{ stream_partition.form_id }}/fields + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + - fields + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: form_id + stream: + $ref: "#/definitions/streams/forms" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/form_fields" + submissions: + type: DeclarativeStream + name: submissions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /forms/{{ stream_partition.form_id }}/submissions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + - submissions + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: form_id + stream: + $ref: "#/definitions/streams/forms" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/submissions" + partial_submissions: + type: DeclarativeStream + name: partial_submissions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /forms/{{ stream_partition.form_id }}/partial-submissions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + - partial-submissions + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: form_id + stream: + $ref: "#/definitions/streams/forms" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/partial_submissions" + coupons: + type: DeclarativeStream + name: coupons + primary_key: + - code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /forms/{{ stream_partition.form_id }}/coupons + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + - coupons + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: form_id + stream: + $ref: "#/definitions/streams/forms" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/coupons" + products: + type: DeclarativeStream + name: products + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /forms/{{ stream_partition.form_id }}/products + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + - products + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: form_id + stream: + $ref: "#/definitions/streams/forms" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + base_requester: + type: HttpRequester + url_base: https://api.paperform.co//v1 + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/forms" + - $ref: "#/definitions/streams/form_fields" + - $ref: "#/definitions/streams/submissions" + - $ref: "#/definitions/streams/partial_submissions" + - $ref: "#/definitions/streams/coupons" + - $ref: "#/definitions/streams/products" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + description: >- + API key to use. Generate it on your account page at + https://paperform.co/account/developer. + name: api_key + order: 0 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + forms: true + form_fields: true + submissions: true + partial_submissions: true + coupons: true + products: true + testedStreams: + forms: + streamHash: aa67f03ee4f154e60b419de1521d239201e8a7ee + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + form_fields: + streamHash: 42a60b80dc7be85c5b20ee7f7a3e0d686d3ef2c3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + submissions: + streamHash: 2ca6affa344eeb9597a0fcc4b6164a4d7b220de1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + partial_submissions: + streamHash: 7ec53bf61d6b9c66cbaf8dd4ddcb66b5458f1abb + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + coupons: + streamHash: 9be02da03521a039f6f882d88f1725fd2fc91d3c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + products: + streamHash: 547dd27235ce6bfa7ba8d7f1e49c3898c8d44a9b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://paperform.readme.io/reference/getting-started-1 + +schemas: + forms: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account_timezone: + type: + - string + - "null" + additional_urls: + type: + - object + - "null" + properties: + duplicate_url: + type: + - string + - "null" + edit_url: + type: + - string + - "null" + submissions_url: + type: + - string + - "null" + cover_image_url: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_at_utc: + type: + - string + - "null" + id: + type: string + live: + type: + - boolean + - "null" + slug: + type: + - string + - "null" + space_id: + type: + - number + - "null" + submission_count: + type: + - number + - "null" + title: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_at_utc: + type: + - string + - "null" + url: + type: + - string + - "null" + required: + - id + form_fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + key: + type: string + options: + type: + - array + - "null" + items: + type: + - string + - "null" + required: + type: + - boolean + - "null" + title: + type: + - string + - "null" + required: + - key + submissions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account_timezone: + type: + - string + - "null" + charge: + type: + - object + - "null" + properties: + coupon: + type: + - boolean + - "null" + discount: + type: + - number + - "null" + discounted_subscriptions: + type: + - array + - "null" + live: + type: + - boolean + - "null" + payment_source_service: + type: + - string + - "null" + processing_fee: + type: + - number + - "null" + products: + type: + - object + - "null" + properties: + Option1: + type: + - object + - "null" + properties: + price: + type: + - number + - "null" + quantity: + type: + - number + - "null" + summary: + type: + - string + - "null" + total: + type: + - number + - "null" + Option2: + type: + - object + - "null" + properties: + price: + type: + - number + - "null" + quantity: + type: + - number + - "null" + summary: + type: + - string + - "null" + total: + type: + - number + - "null" + receipt_email: + type: + - boolean + - "null" + summary: + type: + - string + - "null" + tax: + type: + - number + - "null" + tax_percentage: + type: + - number + - "null" + total: + type: + - number + - "null" + total_cents: + type: + - number + - "null" + created_at: + type: + - string + - "null" + created_at_utc: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + 66oq6: + type: + - string + - "null" + 7n2l5: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + SKU: + type: + - string + - "null" + quantity: + type: + - number + - "null" + cels3: + type: + - string + - "null" + f87f1: + type: + - string + - "null" + score: + type: + - boolean + - "null" + device: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + browser: + type: + - string + - "null" + device: + type: + - string + - "null" + embedded: + type: + - boolean + - "null" + ip_address: + type: + - string + - "null" + platform: + type: + - string + - "null" + url: + type: + - string + - "null" + user_agent: + type: + - string + - "null" + form_id: + type: + - string + - "null" + id: + type: string + ip_address: + type: + - string + - "null" + required: + - id + partial_submissions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account_timezone: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_at_utc: + type: + - string + - "null" + data: + type: + - object + - "null" + properties: + 2146r: + type: + - string + - "null" + 2pdff: + type: + - string + - "null" + 3kbdh: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + height: + type: + - number + - "null" + name: + type: + - string + - "null" + size: + type: + - number + - "null" + url: + type: + - string + - "null" + width: + type: + - number + - "null" + 4opht: + type: + - string + - "null" + 4usob: + type: + - string + - "null" + 5e5ed: + type: + - string + - "null" + 5kk2h: + type: + - string + - "null" + 62t0e: + type: + - string + - "null" + 66oq6: + type: + - string + - "null" + 7n2l5: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + SKU: + type: + - string + - "null" + quantity: + type: + - number + - "null" + 9c68q: + type: + - string + - "null" + agllc: + type: + - array + - "null" + items: + type: + - string + - "null" + ap5sv: + type: + - string + - "null" + cels3: + type: + - string + - "null" + dedlp: + type: + - string + - "null" + f87f1: + type: + - string + - "null" + sq70: + type: + - string + - "null" + form_id: + type: + - string + - "null" + id: + type: string + last_answered: + type: + - string + - "null" + submitted_at: + type: + - string + - "null" + submitted_at_utc: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + updated_at_utc: + type: + - string + - "null" + required: + - id + coupons: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + code: + type: string + discountAmount: + type: + - number + - "null" + discountPercentage: + type: + - number + - "null" + enabled: + type: + - boolean + - "null" + target: + type: + - string + - "null" + required: + - code + products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + SKU: + type: + - string + - "null" + discountable: + type: + - boolean + - "null" + images: + type: + - array + - "null" + maximum: + type: + - number + - "null" + name: + type: + - string + - "null" + price: + type: + - string + - "null" + sold: + type: + - number + - "null" diff --git a/airbyte-integrations/connectors/source-paperform/metadata.yaml b/airbyte-integrations/connectors/source-paperform/metadata.yaml new file mode 100644 index 000000000000..0492fc0b697e --- /dev/null +++ b/airbyte-integrations/connectors/source-paperform/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.paperform.co" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-paperform + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 9855e6be-a7b7-48a1-acc4-935f88215aed + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-paperform + githubIssueLabel: source-paperform + icon: icon.svg + license: MIT + name: Paperform + releaseDate: 2024-10-31 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/paperform + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-papersign/README.md b/airbyte-integrations/connectors/source-papersign/README.md new file mode 100644 index 000000000000..98b81073e724 --- /dev/null +++ b/airbyte-integrations/connectors/source-papersign/README.md @@ -0,0 +1,33 @@ +# Papersign +This directory contains the manifest-only connector for `source-papersign`. + +The Airbyte connector for [Papersign](https://paperform.co/products/papersign/) enables seamless integration between Airbyte and Papersign, allowing automated data syncs between your Papersign documents and other platforms. This connector facilitates the extraction, transformation, and loading of e-signature data, document statuses, and user interactions, streamlining workflows and ensuring your e-signature data is easily accessible across systems. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-papersign:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-papersign build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-papersign test +``` + diff --git a/airbyte-integrations/connectors/source-papersign/acceptance-test-config.yml b/airbyte-integrations/connectors/source-papersign/acceptance-test-config.yml new file mode 100644 index 000000000000..dcfb09caaaa5 --- /dev/null +++ b/airbyte-integrations/connectors/source-papersign/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-papersign:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-papersign/icon.svg b/airbyte-integrations/connectors/source-papersign/icon.svg new file mode 100644 index 000000000000..534760f12a14 --- /dev/null +++ b/airbyte-integrations/connectors/source-papersign/icon.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-papersign/manifest.yaml b/airbyte-integrations/connectors/source-papersign/manifest.yaml new file mode 100644 index 000000000000..73973e724cc1 --- /dev/null +++ b/airbyte-integrations/connectors/source-papersign/manifest.yaml @@ -0,0 +1,389 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + The Airbyte connector for + [Papersign](https://paperform.co/products/papersign/) enables seamless + integration between Airbyte and Papersign, allowing automated data syncs + between your Papersign documents and other platforms. This connector + facilitates the extraction, transformation, and loading of e-signature data, + document statuses, and user interactions, streamlining workflows and ensuring + your e-signature data is easily accessible across systems. + +check: + type: CheckStream + stream_names: + - documents + +definitions: + streams: + documents: + type: DeclarativeStream + name: documents + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /documents + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + - documents + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: skip + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/documents" + folders: + type: DeclarativeStream + name: folders + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /folders + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + - folders + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/folders" + spaces: + type: DeclarativeStream + name: spaces + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /spaces + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + - spaces + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/spaces" + webhooks: + type: DeclarativeStream + name: webhooks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /folders/{{ stream_partition.folder_id }}/webhooks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + - webhooks + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: folder_id + stream: + $ref: "#/definitions/streams/folders" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/webhooks" + base_requester: + type: HttpRequester + url_base: https://api.paperform.co/v1/papersign + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/documents" + - $ref: "#/definitions/streams/folders" + - $ref: "#/definitions/streams/spaces" + - $ref: "#/definitions/streams/webhooks" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + description: >- + API key to use. Generate it on your account page at + https://paperform.co/account/developer. + name: api_key + order: 0 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + documents: true + folders: true + spaces: true + webhooks: true + testedStreams: + documents: + streamHash: a59e7aff6341401663261c4dfa54fa0d64aabdb9 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + folders: + streamHash: 4c2adb17d08b637fa0ebdad93ca1052403353a3b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + spaces: + streamHash: 212fa07c2680bd48e6f635aa1f86e75f35727043 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + webhooks: + streamHash: c7677b1788e9080c894e3e42cda63df94e057f60 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://paperform.readme.io/reference/getting-started-1 + +schemas: + documents: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + completed_at_utc: + type: + - string + - "null" + created_at_utc: + type: + - string + - "null" + folder: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + space_id: + type: + - number + - "null" + id: + type: string + name: + type: + - string + - "null" + sent_at_utc: + type: + - string + - "null" + signers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + custom_attributes: + type: + - array + - "null" + email: + type: + - string + - "null" + key: + type: + - string + - "null" + name: + type: + - string + - "null" + space: + type: + - object + - "null" + properties: + allow_team_access: + type: + - boolean + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + root_folder_id: + type: + - number + - "null" + status: + type: + - string + - "null" + updated_at_utc: + type: + - string + - "null" + variables: + type: + - array + - "null" + required: + - id + folders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: number + name: + type: + - string + - "null" + parent_id: + type: + - number + - "null" + space_id: + type: + - number + - "null" + required: + - id + spaces: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + allow_team_access: + type: + - boolean + - "null" + id: + type: number + name: + type: + - string + - "null" + root_folder_id: + type: + - number + - "null" + required: + - id + webhooks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + folder: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + space_id: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + scope: + type: + - string + - "null" + target_url: + type: + - string + - "null" + triggers: + type: + - array + - "null" + items: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-papersign/metadata.yaml b/airbyte-integrations/connectors/source-papersign/metadata.yaml new file mode 100644 index 000000000000..2fb998fa34f2 --- /dev/null +++ b/airbyte-integrations/connectors/source-papersign/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.paperform.co" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-papersign + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: afdc7cc3-a424-4118-9714-c8faca04c72c + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-papersign + githubIssueLabel: source-papersign + icon: icon.svg + license: MIT + name: Papersign + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/papersign + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-pardot/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-pardot/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-pardot/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-pardot/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-pardot/manifest.yaml b/airbyte-integrations/connectors/source-pardot/manifest.yaml index 495ec71883a6..13ac303ce829 100644 --- a/airbyte-integrations/connectors/source-pardot/manifest.yaml +++ b/airbyte-integrations/connectors/source-pardot/manifest.yaml @@ -1,1226 +1,4795 @@ -version: 5.13.0 - -type: DeclarativeSource - -check: - type: CheckStream - stream_names: - - campaigns - -definitions: - streams: - campaigns: - type: DeclarativeStream - name: campaigns - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: campaign/version/4/do/query - http_method: GET - request_parameters: - format: json - sort_by: id - sort_order: ascending - created_after: "{{ format_datetime(config['start_date'], '%Y-%m-%dT%H:%M:%SZ') }}" - request_headers: - Pardot-Business-Unit-Id: "{{ config[\"pardot_business_unit_id\"] }}" - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - result - - campaign - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: id_greater_than - pagination_strategy: - type: CursorPagination - cursor_value: "{{ response.get(\"campaign\", {})[-1].get(\"id\", {}) }}" - stop_condition: "{{ not response.get(\"campaign\", {})[-1].get(\"id\", {}) }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/campaigns" - email_clicks: - type: DeclarativeStream - name: email_clicks - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: emailClick/version/4/do/query - http_method: GET - request_parameters: - format: json - created_after: "{{ format_datetime(config['start_date'], '%Y-%m-%dT%H:%M:%SZ') }}" - request_headers: - Pardot-Business-Unit-Id: "{{ config[\"pardot_business_unit_id\"] }}" - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - result - - emailClick - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: id_greater_than - pagination_strategy: - type: CursorPagination - cursor_value: "{{ response.get(\"emailClick\", {})[-1].get(\"id\", {}) }}" - stop_condition: "{{ not response.get(\"emailClick\", {})[-1].get(\"id\", {}) }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/email_clicks" - list_membership: - type: DeclarativeStream - name: list_membership - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: listMembership/version/4/do/query - http_method: GET - request_parameters: - format: json - sort_by: id - sort_order: ascending - created_after: "{{ format_datetime(config['start_date'], '%Y-%m-%dT%H:%M:%SZ') }}" - request_headers: - Pardot-Business-Unit-Id: "{{ config[\"pardot_business_unit_id\"] }}" - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - result - - list_membership - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: updated_after - pagination_strategy: - type: CursorPagination - cursor_value: >- - {{ response.get("list_membership", {})[-1].get("updated_at", {}) - }} - stop_condition: >- - {{ not response.get("list_membership", {})[-1].get("updated_at", - {}) }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/list_membership" - lists: - type: DeclarativeStream - name: lists - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: list/version/4/do/query - http_method: GET - request_parameters: - format: json - sort_by: updated_at - sort_order: ascending - created_after: "{{ format_datetime(config['start_date'], '%Y-%m-%dT%H:%M:%SZ') }}" - request_headers: - Pardot-Business-Unit-Id: "{{ config[\"pardot_business_unit_id\"] }}" - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - result - - list - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: updated_after - pagination_strategy: - type: CursorPagination - cursor_value: "{{ response.get(\"list\", {})[-1].get(\"updated_at\", {}) }}" - stop_condition: "{{ not response.get(\"list\", {})[-1].get(\"updated_at\", {}) }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/lists" - prospect_accounts: - type: DeclarativeStream - name: prospect_accounts - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: prospectAccount/version/4/do/query - http_method: GET - request_parameters: - format: json - sort_by: updated_at - sort_order: ascending - created_after: "{{ format_datetime(config['start_date'], '%Y-%m-%dT%H:%M:%SZ') }}" - request_headers: - Pardot-Business-Unit-Id: "{{ config[\"pardot_business_unit_id\"] }}" - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - result - - prospectAccount - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: updated_after - pagination_strategy: - type: CursorPagination - cursor_value: >- - {{ response.get("prospectAccount", {})[-1].get("updated_at", {}) - }} - stop_condition: >- - {{ not response.get("prospectAccount", {})[-1].get("updated_at", - {}) }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/prospect_accounts" - prospects: - type: DeclarativeStream - name: prospects - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: prospect/version/4/do/query - http_method: GET - request_parameters: - format: json - sort_by: updated_at - sort_order: ascending - created_after: "{{ format_datetime(config['start_date'], '%Y-%m-%dT%H:%M:%SZ') }}" - request_headers: - Pardot-Business-Unit-Id: "{{ config[\"pardot_business_unit_id\"] }}" - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - result - - prospect - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: updated_after - pagination_strategy: - type: CursorPagination - cursor_value: "{{ response.get(\"prospect\", {})[-1].get(\"updated_at\", {}) }}" - stop_condition: "{{ not response.get(\"prospect\", {})[-1].get(\"updated_at\", {}) }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/prospects" - users: - type: DeclarativeStream - name: users - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: user - http_method: GET - request_parameters: - format: json - created_after: "{{ format_datetime(config['start_date'], '%Y-%m-%dT%H:%M:%SZ') }}" - request_headers: - Pardot-Business-Unit-Id: "{{ config[\"pardot_business_unit_id\"] }}" - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - result - - user - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: created_after - pagination_strategy: - type: CursorPagination - cursor_value: "{{ response.get(\"user\", {})[-1].get(\"created_at\", {}) }}" - stop_condition: "{{ not response.get(\"user\", {})[-1].get(\"created_at\", {}) }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/users" - visitor_activities: - type: DeclarativeStream - name: visitor_activities - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: visitorActivity/version/4/do/query - http_method: GET - request_parameters: - format: json - created_after: "{{ format_datetime(config['start_date'], '%Y-%m-%dT%H:%M:%SZ') }}" - request_headers: - Pardot-Business-Unit-Id: "{{ config[\"pardot_business_unit_id\"] }}" - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - result - - visitor_activity - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: id_greater_than - pagination_strategy: - type: CursorPagination - cursor_value: "{{ response.get(\"visitor_activity\", {})[-1].get(\"id\", {}) }}" - stop_condition: "{{ not response.get(\"visitor_activity\", {})[-1].get(\"id\", {}) }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/visitor_activities" - visitors: - type: DeclarativeStream - name: visitors - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: visitor/version/4/do/query - http_method: GET - request_parameters: - format: json - sort_by: updated_at - sort_order: ascending - created_after: "{{ format_datetime(config['start_date'], '%Y-%m-%dT%H:%M:%SZ') }}" - request_headers: - Pardot-Business-Unit-Id: "{{ config[\"pardot_business_unit_id\"] }}" - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - result - - visitor - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: updated_after - pagination_strategy: - type: CursorPagination - cursor_value: "{{ response.get(\"visitor\", {})[-1].get(\"updated_at\", {}) }}" - stop_condition: "{{ not response.get(\"visitor\", {})[-1].get(\"updated_at\", {}) }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/visitors" - visits: - type: DeclarativeStream - name: visits - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: visit/version/4/do/query - http_method: GET - request_parameters: - format: json - sort_order: ascending - created_after: "{{ format_datetime(config['start_date'], '%Y-%m-%dT%H:%M:%SZ') }}" - request_headers: - Pardot-Business-Unit-Id: "{{ config[\"pardot_business_unit_id\"] }}" - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - result - - visit - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/visits" - opportunities: - type: DeclarativeStream - name: opportunities - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: opportunity/version/4/do/query - http_method: GET - request_parameters: - format: json - created_after: "{{ format_datetime(config['start_date'], '%Y-%m-%dT%H:%M:%SZ') }}" - request_headers: - Pardot-Business-Unit-Id: "{{ config[\"pardot_business_unit_id\"] }}" - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - result - - opportunity - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: created_after - pagination_strategy: - type: CursorPagination - cursor_value: "{{ response.get(\"opportunity\", {})[-1].get(\"created_at\", {}) }}" - stop_condition: >- - {{ not response.get("opportunity", {})[-1].get("created_at", {}) - }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/opportunities" - base_requester: - type: HttpRequester - url_base: https://pi.pardot.com/api/ - authenticator: - type: OAuthAuthenticator - client_id: "{{ config[\"client_id\"] }}" - grant_type: refresh_token - client_secret: "{{ config[\"client_secret\"] }}" - refresh_token: "{{ config[\"client_refresh_token\"] }}" - refresh_request_body: {} - token_refresh_endpoint: >- - https://{{ 'test' if config['is_sandbox'] else 'login' - }}.salesforce.com/services/oauth2/token - -streams: - - $ref: "#/definitions/streams/campaigns" - - $ref: "#/definitions/streams/email_clicks" - - $ref: "#/definitions/streams/list_membership" - - $ref: "#/definitions/streams/lists" - - $ref: "#/definitions/streams/prospect_accounts" - - $ref: "#/definitions/streams/prospects" - - $ref: "#/definitions/streams/users" - - $ref: "#/definitions/streams/visitor_activities" - - $ref: "#/definitions/streams/visitors" - - $ref: "#/definitions/streams/visits" - # - $ref: "#/definitions/streams/opportunities" # Currently disabled because test account doesn't have any data - - -spec: - type: Spec - connection_specification: - type: object - $schema: http://json-schema.org/draft-07/schema# - required: - - client_id - - client_secret - - refresh_token - - pardot_business_unit_id - properties: - client_id: - type: string - description: The Consumer Key that can be found when viewing your app in Salesforce - airbyte_secret: true - order: 0 - is_sandbox: - type: boolean - description: >- - Whether or not the the app is in a Salesforce sandbox. If you do not - know what this, assume it is false. - default: false - order: 1 - start_date: - type: string - description: >- - UTC date and time in the format 2017-01-25T00:00:00Z. Any data before - this date will not be replicated. Leave blank to skip this filter - default: null - pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ - examples: - - "2021-07-25T00:00:00Z" - order: 2 - client_secret: - type: string - description: >- - The Consumer Secret that can be found when viewing your app in - Salesforce - airbyte_secret: true - order: 3 - refresh_token: - type: string - description: >- - Salesforce Refresh Token used for Airbyte to access your Salesforce - account. If you don't know what this is, follow this guide - to retrieve it. - airbyte_secret: true - order: 4 - pardot_business_unit_id: - type: string - description: >- - Pardot Business ID, can be found at Setup > Pardot > Pardot Account - Setup - order: 5 - additionalProperties: true - -metadata: - autoImportSchema: - campaigns: false - email_clicks: false - list_membership: false - lists: false - prospect_accounts: false - prospects: false - users: false - visitor_activities: false - visitors: false - visits: false - opportunities: false - yamlComponents: - global: - - authenticator - testedStreams: - campaigns: - streamHash: ef6fbf0ab7ffa8f81749103d94235abd001d0f39 - email_clicks: - streamHash: 2d74c8aab6c19a77ed2315e36c2fcb18296b641a - list_membership: - streamHash: 33edc450360e922bd939bf7aea5bb756e8714d64 - lists: - streamHash: 984611ea793da473a3cfa6968fb01a4a36b6145f - prospect_accounts: - streamHash: 5938979e371a63739b281c64cd4f61064331d513 - prospects: - streamHash: 4bcf3735358cd3942c17750ef76e052faf5a034e - users: - streamHash: 21012c537f20aed85d8fca2a91c135a2ed9a8e34 - visitor_activities: - streamHash: 857eb94e1cf16eac22e0386450e79abfeffdf347 - visitors: - streamHash: 339bee895c4c803eccc98ba0b836fbc0cb36d937 - visits: - streamHash: c526ae3538c2c4f9b434e803521c509c0e5271a2 - opportunities: - streamHash: fe2484cadf31a482f5f5421ac4a70d14f03e8796 - assist: {} - -schemas: - campaigns: - type: object - $schema: http://json-schema.org/draft-07/schema# - additionalProperties: true - properties: - cost: - type: - - "null" - - integer - id: - type: - - integer - name: - type: - - "null" - - string - email_clicks: - type: object - $schema: http://json-schema.org/draft-07/schema# - additionalProperties: true - properties: - created_at: - type: - - "null" - - string - format: date-time - drip_program_action_id: - type: - - "null" - - integer - email_template_id: - type: - - "null" - - integer - id: - type: - - integer - list_email_id: - type: - - "null" - - integer - prospect_id: - type: - - "null" - - integer - tracker_redirect_id: - type: - - "null" - - integer - url: - type: - - "null" - - string - list_membership: - type: object - $schema: http://json-schema.org/draft-07/schema# - additionalProperties: true - properties: - created_at: - type: - - "null" - - string - format: date-time - id: - type: - - integer - list_id: - type: - - integer - opted_out: - type: - - "null" - - boolean - prospect_id: - type: - - integer - updated_at: - type: - - "null" - - string - format: date-time - lists: - type: object - $schema: http://json-schema.org/draft-07/schema# - additionalProperties: true - properties: - description: - type: - - "null" - - string - created_at: - type: - - "null" - - string - format: date-time - id: - type: - - integer - is_crm_visible: - type: - - "null" - - boolean - is_dynamic: - type: - - "null" - - boolean - is_public: - type: - - "null" - - boolean - name: - type: - - "null" - - string - title: - type: - - "null" - - string - updated_at: - type: - - "null" - - string - format: date-time - prospect_accounts: - type: object - $schema: http://json-schema.org/draft-07/schema# - additionalProperties: true - properties: - assigned_to: - type: - - "null" - - object - created_at: - type: - - "null" - - string - format: date-time - id: - type: - - integer - name: - type: - - "null" - - string - updated_at: - type: - - "null" - - string - format: date-time - prospects: - type: object - $schema: http://json-schema.org/draft-07/schema# - additionalProperties: true - properties: - address_one: - type: - - "null" - - string - address_two: - type: - - "null" - - string - annual_revenue: - type: - - "null" - - string - campaign_id: - type: - - "null" - - integer - city: - type: - - "null" - - string - comments: - type: - - "null" - - string - company: - type: - - "null" - - string - country: - type: - - "null" - - string - created_at: - type: - - "null" - - string - format: date-time - crm_account_fid: - type: - - "null" - - string - crm_contact_fid: - type: - - "null" - - string - crm_last_sync: - type: - - "null" - - string - format: date-time - crm_lead_fid: - type: - - "null" - - string - crm_owner_fid: - type: - - "null" - - string - crm_url: - type: - - "null" - - string - department: - type: - - "null" - - string - email: - type: - - "null" - - string - employees: - type: - - "null" - - string - fax: - type: - - "null" - - string - first_name: - type: - - "null" - - string - grade: - type: - - "null" - - string - id: - type: - - integer - industry: - type: - - "null" - - string - is_do_not_call: - type: - - "null" - - integer - is_do_not_email: - type: - - "null" - - integer - is_reviewed: - type: - - "null" - - integer - is_starred: - type: - - "null" - - integer - job_title: - type: - - "null" - - string - last_activity_at: - type: - - "null" - - string - format: date-time - last_name: - type: - - "null" - - string - notes: - type: - - "null" - - string - opted_out: - type: - - "null" - - integer - password: - type: - - "null" - - string - phone: - type: - - "null" - - string - prospect_account_id: - type: - - "null" - - integer - recent_interaction: - type: - - "null" - - string - salutation: - type: - - "null" - - string - score: - type: - - "null" - - integer - source: - type: - - "null" - - string - state: - type: - - "null" - - string - territory: - type: - - "null" - - string - updated_at: - type: - - "null" - - string - format: date-time - website: - type: - - "null" - - string - years_in_business: - type: - - "null" - - string - zip: - type: - - "null" - - string - users: - type: object - $schema: http://json-schema.org/draft-07/schema# - additionalProperties: true - properties: - created_at: - type: - - "null" - - string - format: date-time - email: - type: - - "null" - - string - first_name: - type: - - "null" - - string - id: - type: - - integer - job_title: - type: - - "null" - - string - last_name: - type: - - "null" - - string - role: - type: - - "null" - - string - updated_at: - type: - - "null" - - string - format: date-time - visitor_activities: - type: object - $schema: http://json-schema.org/draft-07/schema# - additionalProperties: true - properties: - type: - type: - - "null" - - integer - campaign: - type: - - "null" - - object - campaign_id: - type: - - "null" - - integer - created_at: - type: - - "null" - - string - format: date-time - details: - type: - - "null" - - string - email_id: - type: - - "null" - - integer - email_template_id: - type: - - "null" - - integer - file_id: - type: - - "null" - - integer - form_handler_id: - type: - - "null" - - integer - form_id: - type: - - "null" - - integer - id: - type: - - integer - landing_page_id: - type: - - "null" - - integer - list_email_id: - type: - - "null" - - integer - multivariate_test_variation_id: - type: - - "null" - - integer - paid_search_id_id: - type: - - "null" - - integer - prospect_id: - type: - - "null" - - integer - site_search_query_id: - type: - - "null" - - integer - type_name: - type: - - "null" - - string - updated_at: - type: - - "null" - - string - format: date-time - visitor_id: - type: - - "null" - - integer - visitor_page_view_id: - type: - - "null" - - integer - visitors: - type: object - $schema: http://json-schema.org/draft-07/schema# - additionalProperties: true - properties: - campaign_parameter: - type: - - "null" - - string - content_parameter: - type: - - "null" - - string - created_at: - type: - - "null" - - string - format: date-time - hostname: - type: - - "null" - - string - id: - type: - - integer - ip_address: - type: - - "null" - - string - medium_parameter: - type: - - "null" - - string - page_view_count: - type: - - "null" - - integer - source_parameter: - type: - - "null" - - string - term_parameter: - type: - - "null" - - string - updated_at: - type: - - "null" - - string - format: date-time - visits: - type: object - $schema: http://json-schema.org/draft-07/schema# - additionalProperties: true - properties: - type: - type: - - "null" - - integer - campaign: - type: - - "null" - - object - campaign_parameter: - type: - - "null" - - string - content_parameter: - type: - - "null" - - string - created_at: - type: - - "null" - - string - format: date-time - details: - type: - - "null" - - string - duration_in_seconds: - type: - - "null" - - integer - email: - type: - - "null" - - object - email_id: - type: - - "null" - - integer - email_template_id: - type: - - "null" - - integer - first_visitor_page_view_at: - type: - - "null" - - string - format: date-time - id: - type: - - integer - last_visitor_page_view_at: - type: - - "null" - - string - format: date-time - list_email_id: - type: - - "null" - - integer - medium_parameter: - type: - - "null" - - string - prospect_id: - type: - - "null" - - integer - source_parameter: - type: - - "null" - - string - term_parameter: - type: - - "null" - - string - type_name: - type: - - "null" - - string - updated_at: - type: - - "null" - - string - format: date-time - visit_id: - type: - - "null" - - integer - visitor_id: - type: - - "null" - - integer - visitor_page_view_count: - type: - - "null" - - integer - visitor_page_views: - type: - - "null" - - object - opportunities: - type: object - $schema: http://json-schema.org/draft-07/schema# - additionalProperties: true - properties: - type: - type: - - "null" - - string - campaign_id: - type: - - "null" - - integer - closed_at: - type: - - "null" - - string - format: date-time - created_at: - type: - - "null" - - string - format: date-time - id: - type: - - integer - name: - type: - - "null" - - string - probability: - type: - - "null" - - integer - stage: - type: - - "null" - - string - status: - type: - - "null" - - string - updated_at: - type: - - "null" - - string - format: date-time - value: - type: - - "null" - - number +version: 6.10.0 + +type: DeclarativeSource + +check: + type: CheckStream + stream_names: + - campaigns + +definitions: + streams: + campaigns: + type: DeclarativeStream + name: campaigns + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/campaigns + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,name,isDeleted,folderId,cost,parentCampaignId,createdById,updatedById,createdAt,updatedAt,salesforceId + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/campaigns" + email_clicks: + type: DeclarativeStream + name: email_clicks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: emailClick/version/4/do/query + http_method: GET + request_parameters: + format: json + output: bulk + sort_by: id + sort_order: ascending + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - result + - emailClick + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: id_greater_than + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ last_record.id }}" + stop_condition: >- + {{ not response.result.emailClick or + response.result.emailClick|length < 200 }} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%d %H:%M:%S" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: created_after + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: created_before + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/email_clicks" + list_membership: + type: DeclarativeStream + name: list_membership + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/list-memberships + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,listId,prospectId,optedOut,createdAt,updatedAt,createdById,updatedById + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_membership" + lists: + type: DeclarativeStream + name: lists + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/lists + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,name,title,description,isPublic,folderId,campaignId,isDeleted,isDynamic,createdAt,updatedAt,createdById,updatedById + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/lists" + prospect_accounts: + type: DeclarativeStream + name: prospect_accounts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/prospect-accounts + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,name,salesforceId,isDeleted,annualRevenue,billingAddressOne,billingAddressTwo,billingCity,billingCountry,billingState,billingZip,description,employees,fax,industry,number,ownership,phone,rating,shippingAddressOne,shippingAddressTwo,shippingCity,shippingCountry,shippingState,shippingZip,sic,site,tickerSymbol,type,website,createdAt,updatedAt,createdById,updatedById,assignedToId + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'id ASC' if not next_page_token.next_page_token }}" + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + partition_router: + type: ListPartitionRouter + values: + - "1" + cursor_field: >- + magic config: this is just a trick to make the next_page_token + object populate, which for some reason doesn't happen when only + Pagination is used (without Incremental or Param + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/prospect_accounts" + prospects: + type: DeclarativeStream + name: prospects + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/prospects + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,email,optedOut,isDeleted,isDoNotCall,isDoNotEmail,isEmailHardBounced,isReviewed,isStarred,doNotSell,prospectAccountId,campaignId,profileId,lifecycleStageId,userId,lastActivityAt,recentInteraction,firstName,lastName,salutation,jobTitle,emailBouncedAt,emailBouncedReason,source,sourceParameter,campaignParameter,mediumParameter,contentParameter,termParameter,firstActivityAt,firstAssignedAt,firstReferrerQuery,firstReferrerType,firstReferrerUrl,salesforceId,salesforceContactId,salesforceLeadId,salesforceAccountId,salesforceCampaignId,salesforceOwnerId,salesforceUrl,salesforceLastSync,assignedToId,convertedAt,convertedFromObjectName,convertedFromObjectType,grade,phone,fax,addressOne,addressTwo,city,state,zip,country,company,annualRevenue,website,industry,department,yearsInBusiness,employees,score,territory,comments,notes,createdAt,updatedAt,createdById,updatedById + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/prospects" + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/users + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,email,username,isDeleted,firstName,jobTitle,role,roleName,salesforceId,tagReplacementLanguage,createdAt,updatedAt,createdById,updatedById + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + visitor_activities: + type: DeclarativeStream + name: visitor_activities + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/visitor-activities + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,visitId,prospectId,visitorId,emailId,type,typeName,details,campaignId,customRedirectId,emailTemplateId,fileId,formHandlerId,formId,landingPageId,listEmailId,multivariateTestVariationId,opportunityId,paidSearchAdId,siteSearchQueryId,visitorPageViewId,createdAt,updatedAt + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/visitor_activities" + visitors: + type: DeclarativeStream + name: visitors + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/visitors + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,prospectId,pageViewCount,isIdentified,doNotSell,hostname,ipAddress,campaignId,sourceParameter,campaignParameter,mediumParameter,contentParameter,termParameter,createdAt,updatedAt + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/visitors" + visits: + type: DeclarativeStream + name: visits + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/visits + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,visitorId,prospectId,visitorPageViewCount,firstVisitorPageViewAt,lastVisitorPageViewAt,durationInSeconds,sourceParameter,campaignParameter,mediumParameter,contentParameter,termParameter,createdAt,updatedAt + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/visits" + folders: + type: DeclarativeStream + name: folders + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/folders + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,name,parentFolderId,path,usePermissions,createdAt,updatedAt,createdById,updatedById + orderBy: "{{ 'id ASC' if not next_page_token.next_page_token }}" + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + partition_router: + type: ListPartitionRouter + values: + - "1" + cursor_field: >- + magic config: this is just a trick to make the next_page_token + object populate, which for some reason doesn't happen when only + Pagination is used (without Incremental or Param + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/folders" + custom_redirects: + type: DeclarativeStream + name: custom_redirects + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/custom-redirects + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,name,url,destinationUrl,vanityUrl,campaignId,salesforceId,isDeleted,folderId,trackerDomainId,trackerDomain.domain,vanityUrlPath,trackedUrl,bitlyIsPersonalized,bitlyShortUrl,gaSource,gaMedium,gaTerm,gaContent,gaCampaign,createdAt,updatedAt,createdById,updatedById + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'id ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/custom_redirects" + emails: + type: DeclarativeStream + name: emails + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/emails + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,name,type,sentAt,subject,clientType,isOperational,campaignId,prospectId,folderId,listId,listEmailId,emailTemplateId,trackerDomainId,senderOptions.type,senderOptions.address,senderOptions.name,senderOptions.userId,senderOptions.prospectCustomFieldId,senderOptions.accountCustomFieldId,replyToOptions.type,replyToOptions.address,replyToOptions.userId,replyToOptions.prospectCustomFieldId,replyToOptions.accountCustomFieldId,createdById + orderBy: "{{ 'sentAt ASC' if not next_page_token.next_page_token }}" + sentAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + sentAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: sentAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: P1D + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/emails" + engagement_studio_programs: + type: DeclarativeStream + name: engagement_studio_programs + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/engagement-studio-programs + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,status,isDeleted,salesforceId,description,businessHours,prospectsMultipleEntry,schedule,scheduleCreatedById,recipientListIds,suppressionListIds,createdAt,updatedAt,createdById,updatedById + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/engagement_studio_programs" + files: + type: DeclarativeStream + name: files + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/files + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,name,folderId,campaignId,salesforceId,trackerDomainId,vanityUrl,vanityUrlPath,url,size,isTracked,bitlyIsPersonalized,bitlyShortUrl,createdAt,updatedAt,createdById,updatedById + orderBy: "{{ 'id ASC' if not next_page_token.next_page_token }}" + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/files" + folder_contents: + type: DeclarativeStream + name: folder_contents + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/folder-contents + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,folderId,folderRef,objectType,objectId,objectName,objectRef,createdAt,updatedAt,createdById,updatedById + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/folder_contents" + forms: + type: DeclarativeStream + name: forms + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/forms + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,name,campaignId,layoutTemplateId,folderId,trackerDomainId,salesforceId,isDeleted,isUseRedirectLocation,isAlwaysDisplay,isCookieless,isCaptchaEnabled,showNotProspect,embedCode,submitButtonText,beforeFormContent,afterFormContent,thankYouContent,thankYouCode,redirectLocation,fontSize,fontFamily,fontColor,labelAlignment,radioAlignment,checkboxAlignment,requiredCharacter,createdById,updatedById,createdAt,updatedAt + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'id ASC' if not next_page_token.next_page_token }}" + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/forms" + form_fields: + type: DeclarativeStream + name: form_fields + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/form-fields + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,formId,prospectApiFieldId,type,dataFormat,sortOrder,hasDependents,hasProgressives,hasValues,label,errorMessage,cssClasses,isRequired,isAlwaysDisplay,isMaintainInitialValue,isDoNotPrefill,createdById,updatedById,createdAt,updatedAt + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/form_fields" + form_handlers: + type: DeclarativeStream + name: form_handlers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/form-handlers + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,name,folderId,campaignId,trackerDomainId,isDataForwarded,successLocation,errorLocation,isAlwaysEmail,isCookieless,salesforceId,embedCode,createdAt,createdById,isDeleted,updatedById + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'id ASC' if not next_page_token.next_page_token }}" + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/form_handlers" + form_handler_fields: + type: DeclarativeStream + name: form_handler_fields + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/form-handler-fields + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,name,formHandlerId,dataFormat,prospectApiFieldId,isMaintainInitialValue,errorMessage,isRequired,createdAt,createdById + orderBy: "{{ 'id ASC' if not next_page_token.next_page_token }}" + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/form_handler_fields" + landing_pages: + type: DeclarativeStream + name: landing_pages + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/landing-pages + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,name,campaignId,salesforceId,isDeleted,layoutType,layoutTableBorder,isUseRedirectLocation,bitlyIsPersonalized,bitlyShortUrl,url,vanityUrl,folderId,formId,layoutTemplateId,title,description,isDoNotIndex,vanityUrlPath,redirectLocation,trackerDomainId,archiveDate,createdAt,updatedAt,createdById,updatedById + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/landing_pages" + layout_templates: + type: DeclarativeStream + name: layout_templates + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/layout-templates + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,name,layoutContent,siteSearchContent,formContent,folderId,isDeleted,isIncludeDefaultCss,createdAt,updatedAt,createdById,updatedById + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'id ASC' if not next_page_token.next_page_token }}" + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/layout_templates" + lifecycle_stages: + type: DeclarativeStream + name: lifecycle_stages + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/lifecycle-stages + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: id,name,isDeleted,isLocked,position,matchType,createdAt,updatedAt + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/lifecycle_stages" + lifecycle_histories: + type: DeclarativeStream + name: lifecycle_histories + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/lifecycle-histories + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: id,prospectId,previousStageId,nextStageId,secondsElapsed,createdAt + orderBy: "{{ 'createdAt ASC' if not next_page_token.next_page_token }}" + createdAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + createdAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: createdAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/lifecycle_histories" + list_emails: + type: DeclarativeStream + name: list_emails + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/list-emails + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,name,subject,isPaused,isSent,isDeleted,isOperational,sentAt,campaignId,clientType,senderOptions.type,senderOptions.address,senderOptions.name,senderOptions.userId,senderOptions.prospectCustomFieldId,senderOptions.accountCustomFieldId,replyToOptions.type,replyToOptions.address,replyToOptions.userId,replyToOptions.prospectCustomFieldId,replyToOptions.accountCustomFieldId,emailTemplateId,trackerDomainId,folderId,createdAt,updatedAt,createdById,updatedById + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_emails" + opportunities: + type: DeclarativeStream + name: opportunities + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/opportunities + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,closedAt,name,type,stage,status,probability,value,campaignId,salesforceId,createdAt,updatedAt,createdById,updatedById + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/opportunities" + tags: + type: DeclarativeStream + name: tags + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/tags + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: id,name,objectCount,createdById,updatedById,createdAt,updatedAt + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tags" + tracker_domains: + type: DeclarativeStream + name: tracker_domains + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/tracker-domains + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,domain,isPrimary,isDeleted,defaultCampaignId,httpsStatus,sslStatus,sslStatusDetails,sslRequestedById,validationStatus,validatedAt,vanityUrlStatus,trackingCode,createdAt,updatedAt,createdById,updatedById + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'id ASC' if not next_page_token.next_page_token }}" + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tracker_domains" + visitor_page_views: + type: DeclarativeStream + name: visitor_page_views + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/visitor-page-views + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,url,title,visitorId,campaignId,visitId,durationInSeconds,salesforceId,createdAt + orderBy: "{{ 'createdAt ASC' if not next_page_token.next_page_token }}" + createdAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + createdAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: createdAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/visitor_page_views" + account: + type: DeclarativeStream + name: account + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/account + http_method: GET + request_parameters: + fields: >- + id,company,level,website,pluginCampaignId,addressOne,addressTwo,city,state,zip,territory,country,phone,fax,adminId,maximumDailyApiCalls,apiCallsUsed,createdAt,updatedAt,createdById,updatedById + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/account" + custom_fields: + type: DeclarativeStream + name: custom_fields + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/custom-fields + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,name,fieldId,type,salesforceId,isRequired,isRecordMultipleResponses,isUseValues,isAnalyticsSynced,createdAt,updatedAt,createdById,updatedById + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/custom_fields" + dynamic_contents: + type: DeclarativeStream + name: dynamic_contents + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/dynamic-contents + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: >- + id,name,basedOnProspectApiFieldId,embedCode,embedUrl,basedOn,tagReplacementLanguage,folderId,trackerDomainId,createdAt,updatedAt,isDeleted,createdById,updatedById + deleted: "{{ 'all' if not next_page_token.next_page_token }}" + orderBy: "{{ 'updatedAt ASC' if not next_page_token.next_page_token }}" + updatedAtAfterOrEqualTo: >- + {{ stream_interval.start_time if stream_interval.start_time and + not next_page_token.next_page_token }} + updatedAtBeforeOrEqualTo: >- + {{ stream_interval.end_time if stream_interval.end_time and not + next_page_token.next_page_token }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%SZ" + - "%Y-%m-%d %H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S-12:00" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config.start_date }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + step: "{{ config.split_up_interval }}" + cursor_granularity: PT1S + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/dynamic_contents" + dynamic_content_variations: + type: DeclarativeStream + name: dynamic_content_variations + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v5/objects/dynamic-content-variations + http_method: GET + request_parameters: + limit: "{{ config.page_size if not next_page_token.next_page_token }}" + fields: id,dynamicContentId,comparison,operator,value1,value2,content + orderBy: "{{ 'id ASC' if not next_page_token.next_page_token }}" + dynamicContentId: >- + {{ stream_partition.parent_id.dynamic_content_id if + stream_interval.start_time and not next_page_token.next_page_token + }} + request_headers: + Pardot-Business-Unit-Id: "{{ config.pardot_business_unit_id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - values + schema_normalization: Default + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"nextPageUrl\", {}) }}" + stop_condition: "{{ not response.get(\"nextPageUrl\", {}) }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: dynamic_content_id + stream: + $ref: "#/definitions/streams/dynamic_contents" + incremental_dependency: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/dynamic_content_variations" + base_requester: + type: HttpRequester + url_base: https://pi.pardot.com/api/ + authenticator: + type: SessionTokenAuthenticator + login_requester: + type: HttpRequester + url_base: >- + https://{{ 'test' if config['is_sandbox'] else + 'login'}}.salesforce.com/services/oauth2 + path: token + authenticator: + type: NoAuth + http_method: POST + request_parameters: {} + request_headers: {} + request_body_data: + client_id: "'{{ config.client_id }}'" + grant_type: refresh_token + client_secret: "'{{ config.client_secret }}'" + refresh_token: "'{{ config.refresh_token }}'" + session_token_path: + - access_token + expiration_duration: PT24H + request_authentication: + type: Bearer + +streams: + - $ref: "#/definitions/streams/campaigns" + - $ref: "#/definitions/streams/email_clicks" + - $ref: "#/definitions/streams/list_membership" + - $ref: "#/definitions/streams/lists" + - $ref: "#/definitions/streams/prospect_accounts" + - $ref: "#/definitions/streams/prospects" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/visitor_activities" + - $ref: "#/definitions/streams/visitors" + - $ref: "#/definitions/streams/visits" + - $ref: "#/definitions/streams/folders" + - $ref: "#/definitions/streams/custom_redirects" + - $ref: "#/definitions/streams/emails" + - $ref: "#/definitions/streams/engagement_studio_programs" + - $ref: "#/definitions/streams/files" + - $ref: "#/definitions/streams/folder_contents" + - $ref: "#/definitions/streams/forms" + - $ref: "#/definitions/streams/form_fields" + - $ref: "#/definitions/streams/form_handlers" + - $ref: "#/definitions/streams/form_handler_fields" + - $ref: "#/definitions/streams/landing_pages" + - $ref: "#/definitions/streams/layout_templates" + - $ref: "#/definitions/streams/lifecycle_stages" + - $ref: "#/definitions/streams/lifecycle_histories" + - $ref: "#/definitions/streams/list_emails" + - $ref: "#/definitions/streams/opportunities" + - $ref: "#/definitions/streams/tags" + - $ref: "#/definitions/streams/tracker_domains" + - $ref: "#/definitions/streams/visitor_page_views" + - $ref: "#/definitions/streams/account" + - $ref: "#/definitions/streams/custom_fields" + - $ref: "#/definitions/streams/dynamic_contents" + - $ref: "#/definitions/streams/dynamic_content_variations" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - pardot_business_unit_id + - client_id + - client_secret + - refresh_token + properties: + pardot_business_unit_id: + type: string + description: >- + Pardot Business ID, can be found at Setup > Pardot > Pardot Account + Setup + order: 0 + title: Pardot Business Unit ID + client_id: + type: string + description: The Consumer Key that can be found when viewing your app in Salesforce + order: 1 + title: Client ID + airbyte_secret: true + client_secret: + type: string + description: >- + The Consumer Secret that can be found when viewing your app in + Salesforce + order: 2 + title: Client Secret + airbyte_secret: true + refresh_token: + type: string + description: >- + Salesforce Refresh Token used for Airbyte to access your Salesforce + account. If you don't know what this is, follow this guide + to retrieve it. + order: 3 + title: Refresh Token + airbyte_secret: true + start_date: + type: string + description: >- + UTC date and time in the format 2000-01-01T00:00:00Z. Any data before + this date will not be replicated. Defaults to the year Pardot was + released. + order: 4 + title: Start Date + format: date-time + default: "2007-01-01T00:00:00Z" + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + examples: + - "2021-07-25T00:00:00Z" + page_size: + type: string + description: The maximum number of records to return per request + order: 5 + title: Page Size Limit + default: "1000" + is_sandbox: + type: boolean + description: >- + Whether or not the the app is in a Salesforce sandbox. If you do not + know what this, assume it is false. + order: 6 + title: Is Sandbox App? + default: false + split_up_interval: + type: string + description: >- + If you're hitting the max pagination limit of the v5 API (100K), try + choosing a more granular value (e.g. P7D). Similarly for small + accounts unlikely to hit this limit, a less granular value (e.g. P1Y) + may speed up the sync. + enum: + - P1Y + - P6M + - P3M + - P1M + - P14D + - P7D + - P3D + - P1D + order: 7 + title: Default Split Up Interval + default: P3M + additionalProperties: true + +metadata: + autoImportSchema: + campaigns: false + email_clicks: false + list_membership: false + lists: false + prospect_accounts: false + prospects: false + users: false + visitor_activities: false + visitors: false + visits: false + folders: false + custom_redirects: false + emails: false + engagement_studio_programs: false + files: false + folder_contents: false + forms: false + form_fields: false + form_handlers: false + form_handler_fields: false + landing_pages: false + layout_templates: false + lifecycle_stages: false + lifecycle_histories: false + list_emails: false + opportunities: false + tags: false + tracker_domains: false + visitor_page_views: false + account: false + custom_fields: false + dynamic_contents: false + dynamic_content_variations: false + testedStreams: + campaigns: + hasRecords: true + streamHash: fc1d627201b08eec5c250804ed7dcd7f09f9675c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + email_clicks: + hasRecords: true + streamHash: 411f4328e02a6d5ce0a3ec3a9a3cb54804e374e0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_membership: + hasRecords: true + streamHash: e3d9c46036a8c5281ad1cec8c9a1b1246ae6df97 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + lists: + hasRecords: true + streamHash: d6ee1f6521a0fc63d809c213ea53613d50d4c178 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + prospect_accounts: + hasRecords: true + streamHash: 37a2ac73f3e6564eba2aad749645c81ee4b7e8ba + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + prospects: + hasRecords: true + streamHash: eaf5ca07271f45b4128dcb4e6da41df2dd853f5d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + users: + hasRecords: true + streamHash: bfaff23353daea243780a306ede24a6abc60ded3 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + visitor_activities: + hasRecords: true + streamHash: 8544f58fbc35ed2e59f62caf60e6fdf7224d7cf8 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + visitors: + hasRecords: true + streamHash: 2fdf03a97b7ae2186d2a32a3dcae26abd2b6d06c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + visits: + hasRecords: true + streamHash: 788619013dc2ed5e75320de887b02d3f0ffc0495 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + folders: + hasRecords: true + streamHash: 952ec71d864df0763936fcf9a48ca5ee2a3f9037 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + custom_redirects: + hasRecords: false + streamHash: 73ca21e4c8acb6ca7a4efad4517b31af4dfcb6f6 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + emails: + hasRecords: true + streamHash: 25e6dc61f25fb81825b764af684379d04e748854 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + engagement_studio_programs: + hasRecords: true + streamHash: 2108ab2546a6df889a2420e2d8cb3aac4b790b70 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + files: + hasRecords: false + streamHash: 9dd470ef4814f6fab7a1acf61671ef171b839da2 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + folder_contents: + hasRecords: true + streamHash: 80dc85cda30756bb57fb750432ad8e580d32a245 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + forms: + hasRecords: true + streamHash: a8143b403bf769d4d24dc771da7888a45cc8cf0c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + form_fields: + hasRecords: true + streamHash: 6f148b11889ab260145dd5e865a142a85ee35d9f + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + form_handlers: + hasRecords: true + streamHash: 8621f40695e6f14df6b5ac1c5c90f6334fc5866a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + form_handler_fields: + hasRecords: true + streamHash: 1827a46a501b04b0c21e6411d464c77a08dfb848 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + landing_pages: + hasRecords: true + streamHash: fc06118614b8de9f2c2c53e6c5bbe88745e28c55 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + layout_templates: + hasRecords: true + streamHash: 9088e72d125495ef1d72d881a8c6b72e4950e06d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + lifecycle_stages: + hasRecords: true + streamHash: c0eab225bad7533145cfeac38e57bb70745f9a79 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + lifecycle_histories: + hasRecords: true + streamHash: 21a5786703917ee27352156ea80fa93cce846954 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_emails: + streamHash: 1823761c89debf594562433f63c8661b3be55524 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + opportunities: + streamHash: 0def746ae5fd7dde2e85858a1be8b72501dca4d5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tags: + streamHash: 4ce0030af2ff46782dfdb5a1bea97e8b92e2a493 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tracker_domains: + streamHash: e441705cc25b37d24b9163afac9e22a734f2185f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + visitor_page_views: + streamHash: 561cc8d52b41daa6f4697d2e2a3efdee3cc3a14d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + account: + streamHash: 0893578c116978dad6459ef40fe2a52ea26a68e9 + hasResponse: true + responsesAreSuccessful: false + hasRecords: false + primaryKeysArePresent: true + primaryKeysAreUnique: true + custom_fields: + streamHash: 020b57ff80114642d70f122a63b22f05d63d8386 + hasResponse: true + responsesAreSuccessful: false + hasRecords: false + primaryKeysArePresent: true + primaryKeysAreUnique: true + dynamic_contents: + streamHash: 795500f19349e89d320fb4814aedf19f5bff9dff + hasResponse: true + responsesAreSuccessful: true + hasRecords: false + primaryKeysArePresent: true + primaryKeysAreUnique: true + dynamic_content_variations: + streamHash: null + assist: {} + +schemas: + campaigns: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + cost: + type: + - "null" + - integer + id: + type: + - integer + name: + type: + - "null" + - string + email_clicks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - "null" + - string + format: date-time + drip_program_action_id: + type: + - "null" + - integer + email_template_id: + type: + - "null" + - integer + id: + type: + - integer + list_email_id: + type: + - "null" + - integer + prospect_id: + type: + - "null" + - integer + tracker_redirect_id: + type: + - "null" + - integer + url: + type: + - "null" + - string + list_membership: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - "null" + - string + format: date-time + createdById: + type: + - "null" + - integer + id: + type: + - integer + listId: + type: + - integer + optedOut: + type: + - "null" + - boolean + prospectId: + type: + - integer + updatedAt: + type: + - "null" + - string + format: date-time + updatedById: + type: + - "null" + - integer + required: + - id + - updatedAt + lists: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - "null" + - string + createdAt: + type: + - "null" + - string + format: date-time + createdById: + type: + - "null" + - integer + folderId: + type: + - "null" + - integer + id: + type: + - integer + isDeleted: + type: + - "null" + - boolean + isDynamic: + type: + - "null" + - boolean + isPublic: + type: + - "null" + - boolean + name: + type: + - "null" + - string + title: + type: + - "null" + - string + updatedAt: + type: + - "null" + - string + format: date-time + updatedById: + type: + - "null" + - integer + prospect_accounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: + type: + - "null" + - string + annualRevenue: + type: + - "null" + - string + assignedToId: + type: + - "null" + - integer + billingAddressOne: + type: + - "null" + - string + billingAddressTwo: + type: + - "null" + - string + billingCity: + type: + - "null" + - string + billingCountry: + type: + - "null" + - string + billingState: + type: + - "null" + - string + billingZip: + type: + - "null" + - string + createdAt: + type: + - "null" + - string + format: date-time + createdById: + type: + - "null" + - integer + employees: + type: + - "null" + - string + fax: + type: + - "null" + - string + id: + type: + - integer + industry: + type: + - "null" + - string + isDeleted: + type: + - "null" + - boolean + name: + type: + - "null" + - string + number: + type: + - "null" + - string + ownership: + type: + - "null" + - string + phone: + type: + - "null" + - string + rating: + type: + - "null" + - string + salesforceId: + type: + - "null" + - string + shippingAddressOne: + type: + - "null" + - string + shippingAddressTwo: + type: + - "null" + - string + shippingCity: + type: + - "null" + - string + shippingCountry: + type: + - "null" + - string + shippingState: + type: + - "null" + - string + shippingZip: + type: + - "null" + - string + sic: + type: + - "null" + - string + site: + type: + - "null" + - string + tickerSymbol: + type: + - "null" + - string + updatedAt: + type: + - "null" + - string + format: date-time + updatedById: + type: + - "null" + - integer + website: + type: + - "null" + - string + prospects: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + addressOne: + type: + - "null" + - string + addressTwo: + type: + - "null" + - string + annualRevenue: + type: + - "null" + - string + assignedToId: + type: + - "null" + - string + campaignId: + type: + - "null" + - integer + campaignParameter: + type: + - "null" + - string + city: + type: + - "null" + - string + comments: + type: + - "null" + - string + company: + type: + - "null" + - string + contentParameter: + type: + - "null" + - string + convertedAt: + type: + - "null" + - string + format: date-time + convertedFromObjectName: + type: + - "null" + - string + convertedFromObjectType: + type: + - "null" + - string + country: + type: + - "null" + - string + createdAt: + type: + - "null" + - string + format: date-time + createdById: + type: + - "null" + - integer + department: + type: + - "null" + - string + doNotSell: + type: + - "null" + - boolean + email: + type: + - "null" + - string + emailBouncedAt: + type: + - "null" + - string + format: date-time + emailBouncedReason: + type: + - "null" + - string + employees: + type: + - "null" + - string + fax: + type: + - "null" + - string + firstActivityAt: + type: + - "null" + - string + format: date-time + firstAssignedAt: + type: + - "null" + - string + format: date-time + firstName: + type: + - "null" + - string + firstReferrerQuery: + type: + - "null" + - string + firstReferrerType: + type: + - "null" + - string + firstReferrerUrl: + type: + - "null" + - string + grade: + type: + - "null" + - string + id: + type: + - integer + industry: + type: + - "null" + - string + isDeleted: + type: + - "null" + - boolean + isDoNotCall: + type: + - "null" + - boolean + isDoNotEmail: + type: + - "null" + - boolean + isEmailHardBounced: + type: + - "null" + - boolean + isReviewed: + type: + - "null" + - boolean + isStarred: + type: + - "null" + - boolean + jobTitle: + type: + - "null" + - string + lastActivityAt: + type: + - "null" + - string + format: date-time + lastName: + type: + - "null" + - string + lifecycleStageId: + type: + - "null" + - integer + mediumParameter: + type: + - "null" + - string + notes: + type: + - "null" + - string + optedOut: + type: + - "null" + - boolean + phone: + type: + - "null" + - string + profileId: + type: + - "null" + - integer + prospectAccountId: + type: + - "null" + - integer + recentInteraction: + type: + - "null" + - string + salesforceAccountId: + type: + - "null" + - string + salesforceCampaignId: + type: + - "null" + - string + salesforceContactId: + type: + - "null" + - string + salesforceId: + type: + - "null" + - string + salesforceLastSync: + type: + - "null" + - string + format: date-time + salesforceLeadId: + type: + - "null" + - string + salesforceOwnerId: + type: + - "null" + - string + salesforceUrl: + type: + - "null" + - string + salutation: + type: + - "null" + - string + score: + type: + - "null" + - string + source: + type: + - "null" + - string + sourceParameter: + type: + - "null" + - string + state: + type: + - "null" + - string + termParameter: + type: + - "null" + - string + territory: + type: + - "null" + - string + updatedAt: + type: + - "null" + - string + format: date-time + updatedById: + type: + - "null" + - integer + userId: + type: + - "null" + - integer + website: + type: + - "null" + - string + yearsInBusiness: + type: + - "null" + - string + zip: + type: + - "null" + - string + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - "null" + - string + format: date-time + createdById: + type: + - "null" + - integer + email: + type: + - "null" + - string + firstName: + type: + - "null" + - string + id: + type: + - integer + isDeleted: + type: + - "null" + - boolean + jobTitle: + type: + - "null" + - string + role: + type: + - "null" + - string + roleName: + type: + - "null" + - string + salesforceId: + type: + - "null" + - string + tagReplacementLanguage: + type: + - "null" + - string + updatedAt: + type: + - "null" + - string + format: date-time + updatedById: + type: + - "null" + - integer + username: + type: + - "null" + - string + visitor_activities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - "null" + - integer + campaignId: + type: + - "null" + - integer + createdAt: + type: + - "null" + - string + format: date-time + customRedirectId: + type: + - "null" + - integer + details: + type: + - "null" + - string + emailId: + type: + - "null" + - integer + emailTemplateId: + type: + - "null" + - integer + fileId: + type: + - "null" + - integer + formHandlerId: + type: + - "null" + - integer + formId: + type: + - "null" + - integer + id: + type: + - integer + landingPageId: + type: + - "null" + - integer + listEmailId: + type: + - "null" + - integer + multivariateTestVariationId: + type: + - "null" + - integer + opportunityId: + type: + - "null" + - integer + paidSearchAdId: + type: + - "null" + - integer + prospectId: + type: + - "null" + - integer + siteSearchQueryId: + type: + - "null" + - integer + typeName: + type: + - "null" + - string + updatedAt: + type: + - "null" + - string + format: date-time + visitId: + type: + - "null" + - integer + visitorId: + type: + - "null" + - integer + visitorPageViewId: + type: + - "null" + - integer + visitors: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + campaignId: + type: + - "null" + - integer + campaignParameter: + type: + - "null" + - string + contentParameter: + type: + - "null" + - string + createdAt: + type: + - "null" + - string + format: date-time + doNotSell: + type: + - "null" + - boolean + hostname: + type: + - "null" + - string + id: + type: + - integer + ipAddress: + type: + - "null" + - string + isIdentified: + type: + - "null" + - boolean + mediumParameter: + type: + - "null" + - string + pageViewCount: + type: + - "null" + - integer + prospectId: + type: + - "null" + - integer + sourceParameter: + type: + - "null" + - string + termParameter: + type: + - "null" + - string + updatedAt: + type: + - "null" + - string + format: date-time + visits: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + campaignParameter: + type: + - "null" + - string + contentParameter: + type: + - "null" + - string + createdAt: + type: + - "null" + - string + format: date-time + durationInSeconds: + type: + - "null" + - integer + firstVisitorPageViewAt: + type: + - "null" + - string + format: date-time + id: + type: + - integer + lastVisitorPageViewAt: + type: + - "null" + - string + format: date-time + mediumParameter: + type: + - "null" + - string + prospectId: + type: + - "null" + - integer + sourceParameter: + type: + - "null" + - string + termParameter: + type: + - "null" + - string + updatedAt: + type: + - "null" + - string + format: date-time + visitorId: + type: + - "null" + - integer + visitorPageViewCount: + type: + - "null" + - integer + folders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - "null" + - string + createdById: + type: + - "null" + - integer + id: + type: integer + name: + type: + - "null" + - string + parentFolderId: + type: + - "null" + - integer + path: + type: + - "null" + - string + updatedAt: + type: + - "null" + - string + updatedById: + type: + - "null" + - integer + usePermissions: + type: + - "null" + - boolean + required: + - id + custom_redirects: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + bitlyIsPersonalized: + type: + - "null" + - boolean + bitlyShortUrl: + type: + - "null" + - string + campaignId: + type: + - "null" + - integer + createdAt: + type: + - "null" + - string + createdById: + type: + - "null" + - integer + destinationUrl: + type: + - "null" + - string + folderId: + type: + - "null" + - integer + gaCampaign: + type: + - "null" + - string + gaContent: + type: + - "null" + - string + gaMedium: + type: + - "null" + - string + gaSource: + type: + - "null" + - string + gaTerm: + type: + - "null" + - string + id: + type: integer + isDeleted: + type: + - "null" + - boolean + name: + type: + - "null" + - string + salesforceId: + type: + - "null" + - integer + trackedUrl: + type: + - "null" + - string + trackerDomain.domain: + type: + - "null" + - string + trackerDomainId: + type: + - "null" + - integer + updatedAt: + type: + - "null" + - string + updatedById: + type: + - "null" + - integer + url: + type: + - "null" + - string + vanityUrl: + type: + - "null" + - string + vanityUrlPath: + type: + - "null" + - string + required: + - id + emails: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + campaignId: + type: + - integer + - "null" + clientType: + type: + - string + - "null" + createdById: + type: + - integer + - "null" + emailTemplateId: + type: + - integer + - "null" + id: + type: integer + isOperational: + type: + - boolean + - "null" + listEmailId: + type: + - integer + - "null" + name: + type: + - string + - "null" + prospectId: + type: + - integer + - "null" + replyToOptions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + accountCustomFieldId: + type: + - integer + - "null" + address: + type: + - string + - "null" + name: + type: + - string + - "null" + prospectCustomFieldId: + type: + - integer + - "null" + userId: + type: + - integer + - "null" + senderOptions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + accountCustomFieldId: + type: + - integer + - "null" + address: + type: + - string + - "null" + name: + type: + - string + - "null" + prospectCustomFieldId: + type: + - integer + - "null" + userId: + type: + - integer + - "null" + sentAt: + type: + - "null" + - string + format: date-time + subject: + type: + - string + - "null" + required: + - id + - sentAt + engagement_studio_programs: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + businessHours: + type: + - object + - "null" + properties: + days: + type: + - array + - "null" + items: + type: + - string + - "null" + endTime: + type: + - string + - "null" + airbyte_type: time_without_timezone + format: time + startTime: + type: + - string + - "null" + airbyte_type: time_without_timezone + format: time + timezone: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + format: date-time + createdById: + type: + - integer + - "null" + id: + type: integer + isDeleted: + type: + - boolean + - "null" + prospectsMultipleEntry: + type: + - object + - "null" + properties: + maximumEntries: + type: + - integer + - "null" + minimumDurationInDays: + type: + - integer + - "null" + recipientListIds: + type: + - array + - "null" + items: + type: + - integer + - "null" + salesforceId: + type: + - string + - "null" + schedule: + type: + - object + - "null" + properties: + createdAt: + type: + - string + - "null" + format: date-time + startOn: + type: + - string + - "null" + format: date-time + stopOn: + type: + - string + - "null" + format: date-time + scheduleCreatedById: + type: + - integer + - "null" + status: + type: + - string + - "null" + suppressionListIds: + type: + - array + - "null" + items: + type: + - integer + - "null" + updatedAt: + type: + - string + - "null" + format: date-time + updatedById: + type: + - integer + - "null" + required: + - id + - updatedAt + files: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + bitlyIsPersonalized: + type: + - boolean + - "null" + bitlyShortUrl: + type: + - string + - "null" + campaignId: + type: + - integer + - "null" + createdAt: + type: + - string + - "null" + format: date-time + createdById: + type: + - integer + - "null" + folderId: + type: + - integer + - "null" + id: + type: integer + isTracked: + type: + - boolean + - "null" + name: + type: + - string + - "null" + salesforceId: + type: + - string + - "null" + size: + type: + - integer + - "null" + trackerDomainId: + type: + - integer + - "null" + updatedAt: + type: + - string + - "null" + format: date-time + updatedById: + type: + - integer + - "null" + url: + type: + - string + - "null" + vanityUrl: + type: + - string + - "null" + vanityUrlPath: + type: + - string + - "null" + required: + - id + folder_contents: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + format: date-time + createdById: + type: + - integer + - "null" + folderId: + type: + - integer + - "null" + folderRef: + type: + - string + - "null" + id: + type: integer + objectId: + type: + - integer + - "null" + objectName: + type: + - string + - "null" + objectRef: + type: + - string + - "null" + objectType: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + format: date-time + updatedById: + type: + - integer + - "null" + required: + - id + - updatedAt + forms: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + afterFormContent: + type: + - string + - "null" + beforeFormContent: + type: + - string + - "null" + campaignId: + type: + - integer + - "null" + checkboxAlignment: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + format: date-time + createdById: + type: + - integer + - "null" + embedCode: + type: + - string + - "null" + folderId: + type: + - integer + - "null" + fontColor: + type: + - string + - "null" + fontFamily: + type: + - string + - "null" + fontSize: + type: + - string + - "null" + id: + type: integer + isAlwaysDisplay: + type: + - boolean + - "null" + isCaptchaEnabled: + type: + - boolean + - "null" + isCookieless: + type: + - boolean + - "null" + isDeleted: + type: + - boolean + - "null" + isUseRedirectLocation: + type: + - boolean + - "null" + labelAlignment: + type: + - string + - "null" + layoutTemplateId: + type: + - integer + - "null" + name: + type: + - string + - "null" + radioAlignment: + type: + - string + - "null" + redirectLocation: + type: + - string + - "null" + requiredCharacter: + type: + - string + - "null" + salesforceId: + type: + - string + - "null" + showNotProspect: + type: + - boolean + - "null" + submitButtonText: + type: + - string + - "null" + thankYouCode: + type: + - string + - "null" + thankYouContent: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + format: date-time + updatedById: + type: + - integer + - "null" + required: + - id + form_fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + format: date-time + createdById: + type: + - integer + - "null" + cssClasses: + type: + - string + - "null" + dataFormat: + type: + - string + - "null" + errorMessage: + type: + - string + - "null" + formId: + type: + - integer + - "null" + hasDependents: + type: + - boolean + - "null" + hasProgressives: + type: + - boolean + - "null" + hasValues: + type: + - boolean + - "null" + id: + type: integer + isAlwaysDisplay: + type: + - boolean + - "null" + isDoNotPrefill: + type: + - boolean + - "null" + isMaintainInitialValue: + type: + - boolean + - "null" + isRequired: + type: + - boolean + - "null" + label: + type: + - string + - "null" + prospectApiFieldId: + type: + - string + - "null" + sortOrder: + type: + - integer + - "null" + updatedAt: + type: + - string + - "null" + format: date-time + updatedById: + type: + - integer + - "null" + required: + - id + - updatedAt + form_handlers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + campaignId: + type: + - integer + - "null" + createdAt: + type: + - string + - "null" + format: date-time + createdById: + type: + - integer + - "null" + embedCode: + type: + - string + - "null" + errorLocation: + type: + - string + - "null" + folderId: + type: + - integer + - "null" + id: + type: integer + isAlwaysEmail: + type: + - boolean + - "null" + isCookieless: + type: + - boolean + - "null" + isDataForwarded: + type: + - boolean + - "null" + isDeleted: + type: + - boolean + - "null" + name: + type: + - string + - "null" + salesforceId: + type: + - string + - "null" + successLocation: + type: + - string + - "null" + trackerDomainId: + type: + - integer + - "null" + updatedById: + type: + - integer + - "null" + required: + - id + form_handler_fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + format: date-time + createdById: + type: + - integer + - "null" + dataFormat: + type: + - string + - "null" + errorMessage: + type: + - string + - "null" + formHandlerId: + type: + - integer + - "null" + id: + type: integer + isMaintainInitialValue: + type: + - boolean + - "null" + isRequired: + type: + - boolean + - "null" + name: + type: + - string + - "null" + prospectApiFieldId: + type: + - string + - "null" + required: + - id + landing_pages: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + archiveDate: + type: + - string + - "null" + format: date + bitlyIsPersonalized: + type: + - boolean + - "null" + bitlyShortUrl: + type: + - string + - "null" + campaignId: + type: + - integer + - "null" + createdAt: + type: + - string + - "null" + format: date-time + createdById: + type: + - integer + - "null" + folderId: + type: + - integer + - "null" + formId: + type: + - integer + - "null" + id: + type: integer + isDeleted: + type: + - boolean + - "null" + isDoNotIndex: + type: + - boolean + - "null" + isUseRedirectLocation: + type: + - boolean + - "null" + layoutTableBorder: + type: + - integer + - "null" + layoutTemplateId: + type: + - integer + - "null" + layoutType: + type: + - string + - "null" + name: + type: + - string + - "null" + redirectLocation: + type: + - string + - "null" + salesforceId: + type: + - string + - "null" + title: + type: + - string + - "null" + trackerDomainId: + type: + - integer + - "null" + updatedAt: + type: + - string + - "null" + format: date-time + updatedById: + type: + - integer + - "null" + url: + type: + - string + - "null" + vanityUrl: + type: + - string + - "null" + vanityUrlPath: + type: + - string + - "null" + required: + - id + - updatedAt + layout_templates: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + format: date-time + createdById: + type: + - integer + - "null" + folderId: + type: + - integer + - "null" + formContent: + type: + - string + - "null" + id: + type: integer + isDeleted: + type: + - boolean + - "null" + isIncludeDefaultCss: + type: + - boolean + - "null" + layoutContent: + type: + - string + - "null" + name: + type: + - string + - "null" + siteSearchContent: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + format: date-time + updatedById: + type: + - integer + - "null" + required: + - id + lifecycle_stages: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + format: date-time + id: + type: integer + isDeleted: + type: + - boolean + - "null" + isLocked: + type: + - boolean + - "null" + matchType: + type: + - string + - "null" + name: + type: + - string + - "null" + position: + type: + - integer + - "null" + updatedAt: + type: + - string + - "null" + format: date-time + required: + - id + - updatedAt + lifecycle_histories: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + format: date-time + id: + type: integer + nextStageId: + type: + - integer + - "null" + previousStageId: + type: + - integer + - "null" + prospectId: + type: + - integer + - "null" + secondsElapsed: + type: + - integer + - "null" + required: + - id + - createdAt + list_emails: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + campaignId: + type: + - integer + - "null" + clientType: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + format: date-time + createdById: + type: + - integer + - "null" + emailTemplateId: + type: + - integer + - "null" + folderId: + type: + - integer + - "null" + id: + type: integer + isDeleted: + type: + - boolean + - "null" + isOperational: + type: + - boolean + - "null" + isPaused: + type: + - boolean + - "null" + isSent: + type: + - boolean + - "null" + name: + type: + - string + - "null" + replyToOptions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + accountCustomFieldId: + type: + - integer + - "null" + address: + type: + - string + - "null" + prospectCustomFieldId: + type: + - integer + - "null" + userId: + type: + - integer + - "null" + senderOptions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + accountCustomFieldId: + type: + - integer + - "null" + address: + type: + - string + - "null" + name: + type: + - string + - "null" + prospectCustomFieldId: + type: + - integer + - "null" + userId: + type: + - integer + - "null" + sentAt: + type: + - string + - "null" + subject: + type: + - string + - "null" + trackerDomainId: + type: + - integer + - "null" + updatedAt: + type: + - string + - "null" + format: date-time + updatedById: + type: + - integer + - "null" + required: + - id + - updatedAt + opportunities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + campaignId: + type: + - integer + - "null" + closedAt: + type: + - string + - "null" + format: date-time + createdAt: + type: + - string + - "null" + format: date-time + createdById: + type: + - integer + - "null" + id: + type: integer + name: + type: + - string + - "null" + probability: + type: + - integer + - "null" + salesforceId: + type: + - string + - "null" + stage: + type: + - string + - "null" + status: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + format: date-time + updatedById: + type: + - integer + - "null" + value: + type: + - number + - "null" + required: + - id + - updatedAt + tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + format: date-time + createdById: + type: + - integer + - "null" + id: + type: integer + name: + type: + - string + - "null" + objectCount: + type: + - integer + - "null" + updatedAt: + type: + - string + - "null" + format: date-time + updatedById: + type: + - integer + - "null" + required: + - id + - updatedAt + tracker_domains: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + format: date-time + createdById: + type: + - integer + - "null" + defaultCampaignId: + type: + - integer + - "null" + domain: + type: + - string + - "null" + httpsStatus: + type: + - string + - "null" + id: + type: integer + isDeleted: + type: + - boolean + - "null" + isPrimary: + type: + - boolean + - "null" + sslRequestedById: + type: + - integer + - "null" + sslStatus: + type: + - string + - "null" + sslStatusDetails: + type: + - string + - "null" + trackingCode: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + format: date-time + updatedById: + type: + - integer + - "null" + validatedAt: + type: + - string + - "null" + format: date-time + validationStatus: + type: + - string + - "null" + vanityUrlStatus: + type: + - string + - "null" + required: + - id + visitor_page_views: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + campaignId: + type: + - integer + - "null" + createdAt: + type: + - string + - "null" + format: date-time + durationInSeconds: + type: + - integer + - "null" + id: + type: integer + salesforceId: + type: + - string + - "null" + title: + type: + - string + - "null" + url: + type: + - string + - "null" + visitId: + type: + - integer + - "null" + visitorId: + type: + - integer + - "null" + required: + - id + - createdAt + account: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + addressOne: + type: + - string + - "null" + addressTwo: + type: + - string + - "null" + adminId: + type: + - integer + - "null" + apiCallsUsed: + type: + - integer + - "null" + city: + type: + - string + - "null" + company: + type: + - string + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + format: date-time + createdById: + type: + - integer + - "null" + fax: + type: + - string + - "null" + id: + type: integer + level: + type: + - string + - "null" + maximumDailyApiCalls: + type: + - integer + - "null" + phone: + type: + - string + - "null" + pluginCampaignId: + type: + - integer + - "null" + state: + type: + - string + - "null" + territory: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + format: date-time + updatedById: + type: + - integer + - "null" + website: + type: + - string + - "null" + zip: + type: + - string + - "null" + required: + - id + - createdAt + - updatedAt + custom_fields: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + format: date-time + createdById: + type: + - integer + - "null" + fieldId: + type: + - integer + - "null" + id: + type: integer + isAnalyticsSynced: + type: + - boolean + - "null" + isRecordMultipleResponses: + type: + - boolean + - "null" + isRequired: + type: + - boolean + - "null" + isUseValues: + type: + - boolean + - "null" + name: + type: + - string + - "null" + salesforceId: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + format: date-time + updatedById: + type: + - integer + - "null" + required: + - id + - createdAt + - updatedAt + dynamic_contents: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + basedOn: + type: + - string + - "null" + basedOnProspectApiFieldId: + type: + - integer + - "null" + createdAt: + type: + - string + - "null" + format: date-time + createdById: + type: + - integer + - "null" + embedCode: + type: + - string + - "null" + embedUrl: + type: + - string + - "null" + folderId: + type: + - integer + - "null" + id: + type: integer + isDeleted: + type: + - boolean + - "null" + name: + type: + - string + - "null" + tagReplacementLanguage: + type: + - string + - "null" + trackerDomainId: + type: + - integer + - "null" + updatedAt: + type: + - string + - "null" + format: date-time + updatedById: + type: + - integer + - "null" + required: + - id + - updatedAt + dynamic_content_variations: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + id: + type: integer + dynamicContentId: + type: + - integer + - "null" + comparison: + type: + - string + - "null" + operator: + type: + - string + - "null" + value1: + type: + - string + - "null" + value2: + type: + - string + - "null" + content: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-pardot/metadata.yaml b/airbyte-integrations/connectors/source-pardot/metadata.yaml index 55e8e0bfbf5f..1596dd7938af 100644 --- a/airbyte-integrations/connectors/source-pardot/metadata.yaml +++ b/airbyte-integrations/connectors/source-pardot/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: ad15c7ba-72a7-440b-af15-b9a963dc1a8a - dockerImageTag: 0.2.0 + dockerImageTag: 1.0.0 dockerRepository: airbyte/source-pardot githubIssueLabel: source-pardot icon: salesforcepardot.svg @@ -18,6 +18,11 @@ data: oss: enabled: true releaseStage: alpha + releases: + breakingChanges: + 1.0.0: + message: Most streams have been migrated to use Pardot API V5 in this release. The authentication flow, which was previously broken, should now work for new connections using this version. + upgradeDeadline: "2024-12-26" documentationUrl: https://docs.airbyte.com/integrations/sources/pardot tags: - language:manifest-only @@ -29,5 +34,5 @@ data: connectorTestSuitesOptions: - suite: unitTests connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.13.0@sha256:ffc5977f59e1f38bf3f5dd70b6fa0520c2450ebf85153c5a8df315b8c918d5c3 + baseImage: docker.io/airbyte/source-declarative-manifest:6.10.0@sha256:58722e84dbd06bb2af9250e37d24d1c448e247fc3a84d75ee4407d52771b6f03 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-partnerstack/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-partnerstack/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-partnerstack/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-partnerstack/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-partnerstack/integration_tests/configured_catalog.json b/airbyte-integrations/connectors/source-partnerstack/integration_tests/configured_catalog.json index f86aa59251d9..3dd0c9c905ec 100644 --- a/airbyte-integrations/connectors/source-partnerstack/integration_tests/configured_catalog.json +++ b/airbyte-integrations/connectors/source-partnerstack/integration_tests/configured_catalog.json @@ -4,46 +4,46 @@ "stream": { "name": "customers", "json_schema": {}, - "supported_sync_modes": ["full_refresh"] + "supported_sync_modes": ["full_refresh", "incremental"] }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" + "sync_mode": "incremental", + "destination_sync_mode": "append" }, { "stream": { "name": "deals", "json_schema": {}, - "supported_sync_modes": ["full_refresh"] + "supported_sync_modes": ["full_refresh", "incremental"] }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" + "sync_mode": "incremental", + "destination_sync_mode": "append" }, { "stream": { "name": "groups", "json_schema": {}, - "supported_sync_modes": ["full_refresh"] + "supported_sync_modes": ["full_refresh", "incremental"] }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" + "sync_mode": "incremental", + "destination_sync_mode": "append" }, { "stream": { "name": "leads", "json_schema": {}, - "supported_sync_modes": ["full_refresh"] + "supported_sync_modes": ["full_refresh", "incremental"] }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" + "sync_mode": "incremental", + "destination_sync_mode": "append" }, { "stream": { "name": "partnerships", "json_schema": {}, - "supported_sync_modes": ["full_refresh"] + "supported_sync_modes": ["full_refresh", "incremental"] }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" + "sync_mode": "incremental", + "destination_sync_mode": "append" }, { "stream": { diff --git a/airbyte-integrations/connectors/source-partnerstack/main.py b/airbyte-integrations/connectors/source-partnerstack/main.py index d22642a3ee66..6cc90fad696d 100644 --- a/airbyte-integrations/connectors/source-partnerstack/main.py +++ b/airbyte-integrations/connectors/source-partnerstack/main.py @@ -4,5 +4,6 @@ from source_partnerstack.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-partnerstack/metadata.yaml b/airbyte-integrations/connectors/source-partnerstack/metadata.yaml index bb28bbee6f5f..a1b35af24783 100644 --- a/airbyte-integrations/connectors/source-partnerstack/metadata.yaml +++ b/airbyte-integrations/connectors/source-partnerstack/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: d30fb809-6456-484d-8e2c-ee12e0f6888d - dockerImageTag: 0.1.24 + dockerImageTag: 0.2.5 dockerRepository: airbyte/source-partnerstack githubIssueLabel: source-partnerstack icon: partnerstack.svg @@ -27,5 +27,5 @@ data: ql: 100 supportLevel: community connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-partnerstack/poetry.lock b/airbyte-integrations/connectors/source-partnerstack/poetry.lock index 3a612d453b37..e563263b1bd0 100644 --- a/airbyte-integrations/connectors/source-partnerstack/poetry.lock +++ b/airbyte-integrations/connectors/source-partnerstack/poetry.lock @@ -42,13 +42,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] @@ -56,24 +56,24 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -88,19 +88,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -166,13 +166,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -256,116 +256,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -435,20 +422,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -498,13 +485,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -519,13 +506,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -533,7 +520,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -583,13 +569,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -679,22 +665,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -767,69 +756,86 @@ files = [ [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -932,54 +938,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -991,13 +997,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1285,33 +1291,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1378,13 +1384,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1409,81 +1415,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-partnerstack/pyproject.toml b/airbyte-integrations/connectors/source-partnerstack/pyproject.toml index 0b221460234a..1278802f09db 100644 --- a/airbyte-integrations/connectors/source-partnerstack/pyproject.toml +++ b/airbyte-integrations/connectors/source-partnerstack/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.24" +version = "0.2.5" name = "source-partnerstack" description = "Source implementation for Partnerstack." authors = [ "Elliot Trabac ",] diff --git a/airbyte-integrations/connectors/source-partnerstack/source_partnerstack/manifest.yaml b/airbyte-integrations/connectors/source-partnerstack/source_partnerstack/manifest.yaml index 55514abff0ba..b1c028167b0a 100644 --- a/airbyte-integrations/connectors/source-partnerstack/source_partnerstack/manifest.yaml +++ b/airbyte-integrations/connectors/source-partnerstack/source_partnerstack/manifest.yaml @@ -4,73 +4,112 @@ definitions: selector: extractor: field_path: ["data", "items"] - requester: - url_base: "https://api.partnerstack.com/api/v2/" + + schema_loader: + type: JsonFileSchemaLoader + file_path: "./source_partnerstack/schemas/{{ parameters.get('schema_name') or parameters['name'] }}.json" + + base_requester: + url_base: "https://api.partnerstack.com/api/v2" http_method: "GET" authenticator: type: BasicHttpAuthenticator username: "{{ config['public_key'] }}" password: "{{ config['private_key'] }}" - request_parameters: - min_created: "{{ timestamp(config['start_date']) * 1000 }}" - partition_router: - request_cursor_field: "min_updated" - cursor_field: "updated_at" - class_name: source_partnerstack.components.PartnerstackSlicer + + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: starting_after + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 250 + cursor_value: "{{ last_record['key'] }}" + stop_condition: "{{ response.data.has_more is false }}" + + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%ms" + datetime_format: "%ms" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: min_updated + inject_into: request_parameter + retriever: record_selector: $ref: "#/definitions/selector" paginator: - type: DefaultPaginator - pagination_strategy: - type: "CursorPagination" - cursor_value: "{{ last_record['key'] }}" - stop_condition: "{{ response.data.has_more is false }}" - page_size: 250 - page_size_option: - field_name: "limit" - inject_into: "request_parameter" - page_token_option: - type: RequestOption - field_name: "starting_after" - inject_into: "request_parameter" + $ref: "#/definitions/paginator" requester: - $ref: "#/definitions/requester" - partition_router: - $ref: "#/definitions/partition_router" + $ref: "#/definitions/base_requester" # base stream base_stream: retriever: - $ref: "#/definitions/retriever" + record_selector: + $ref: "#/definitions/selector" + paginator: + $ref: "#/definitions/paginator" + requester: + $ref: "#/definitions/base_requester" + request_parameters: + min_created: "{{ (timestamp(config['start_date']) * 1000) | int }}" + schema_loader: + $ref: "#/definitions/schema_loader" + + incremental_stream: + retriever: + record_selector: + $ref: "#/definitions/selector" + paginator: + $ref: "#/definitions/paginator" + requester: + $ref: "#/definitions/base_requester" + incremental_sync: + $ref: "#/definitions/incremental_sync" + schema_loader: + $ref: "#/definitions/schema_loader" # stream definitions customers_stream: - $ref: "#/definitions/base_stream" + $ref: "#/definitions/incremental_stream" $parameters: name: "customers" primary_key: "key" path: "/customers" deals_stream: - $ref: "#/definitions/base_stream" + $ref: "#/definitions/incremental_stream" $parameters: name: "deals" primary_key: "key" path: "/deals" groups_stream: - $ref: "#/definitions/base_stream" + $ref: "#/definitions/incremental_stream" $parameters: name: "groups" primary_key: "key" path: "/groups" leads_stream: - $ref: "#/definitions/base_stream" + $ref: "#/definitions/incremental_stream" $parameters: name: "leads" primary_key: "key" path: "/leads" partnerships_stream: - $ref: "#/definitions/base_stream" + $ref: "#/definitions/incremental_stream" $parameters: name: "partnerships" primary_key: "key" diff --git a/airbyte-integrations/connectors/source-partnerstack/source_partnerstack/run.py b/airbyte-integrations/connectors/source-partnerstack/source_partnerstack/run.py index 1b7dad130b55..9fc7e58ecb5f 100644 --- a/airbyte-integrations/connectors/source-partnerstack/source_partnerstack/run.py +++ b/airbyte-integrations/connectors/source-partnerstack/source_partnerstack/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_partnerstack import SourcePartnerstack +from airbyte_cdk.entrypoint import launch + def run(): source = SourcePartnerstack() diff --git a/airbyte-integrations/connectors/source-partnerstack/source_partnerstack/source.py b/airbyte-integrations/connectors/source-partnerstack/source_partnerstack/source.py index 79d39b4f690b..baacf122c6e7 100644 --- a/airbyte-integrations/connectors/source-partnerstack/source_partnerstack/source.py +++ b/airbyte-integrations/connectors/source-partnerstack/source_partnerstack/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-paypal-transaction/bin/disputes_generator.py b/airbyte-integrations/connectors/source-paypal-transaction/bin/disputes_generator.py index c371024b7ff9..02aa30582dd4 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/bin/disputes_generator.py +++ b/airbyte-integrations/connectors/source-paypal-transaction/bin/disputes_generator.py @@ -62,7 +62,6 @@ def read_json(filepath): def main(): - operation = sys.argv[1] CREDS = read_json("../secrets/config.json") diff --git a/airbyte-integrations/connectors/source-paypal-transaction/bin/fixture_helper.py b/airbyte-integrations/connectors/source-paypal-transaction/bin/fixture_helper.py index cf9d8d86e92d..2228f436d5f5 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/bin/fixture_helper.py +++ b/airbyte-integrations/connectors/source-paypal-transaction/bin/fixture_helper.py @@ -8,6 +8,7 @@ # %% import requests + logging.basicConfig(level=logging.DEBUG) # %% diff --git a/airbyte-integrations/connectors/source-paypal-transaction/bin/payments_generator.py b/airbyte-integrations/connectors/source-paypal-transaction/bin/payments_generator.py index 6a2f46c3b524..8be90ea420c7 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/bin/payments_generator.py +++ b/airbyte-integrations/connectors/source-paypal-transaction/bin/payments_generator.py @@ -82,7 +82,6 @@ def read_json(filepath): def main(): - CREDS = read_json("../secrets/config.json") client_id = CREDS.get("client_id") secret_id = CREDS.get("client_secret") diff --git a/airbyte-integrations/connectors/source-paypal-transaction/bin/paypal_transaction_generator.py b/airbyte-integrations/connectors/source-paypal-transaction/bin/paypal_transaction_generator.py index d8067ec1e2bf..1568d1ace9b3 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/bin/paypal_transaction_generator.py +++ b/airbyte-integrations/connectors/source-paypal-transaction/bin/paypal_transaction_generator.py @@ -34,6 +34,7 @@ from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait + # from pprint import pprint @@ -104,7 +105,6 @@ def read_json(filepath): def get_api_token(): - client_id = CREDS.get("client_id") secret = CREDS.get("client_secret") @@ -126,7 +126,6 @@ def random_digits(digits): def make_payment(): - # generate new invoice_number PAYMENT_DATA["transactions"][0]["invoice_number"] = random_digits(11) diff --git a/airbyte-integrations/connectors/source-paypal-transaction/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-paypal-transaction/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-paypal-transaction/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-paypal-transaction/main.py b/airbyte-integrations/connectors/source-paypal-transaction/main.py index 06823a4a71e5..302035ec0bc2 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/main.py +++ b/airbyte-integrations/connectors/source-paypal-transaction/main.py @@ -4,5 +4,6 @@ from source_paypal_transaction.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-paypal-transaction/source_paypal_transaction/components.py b/airbyte-integrations/connectors/source-paypal-transaction/source_paypal_transaction/components.py index af883e9c1c19..814bfd5b0c43 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/source_paypal_transaction/components.py +++ b/airbyte-integrations/connectors/source-paypal-transaction/source_paypal_transaction/components.py @@ -10,11 +10,13 @@ import backoff import requests + from airbyte_cdk.sources.declarative.auth import DeclarativeOauth2Authenticator from airbyte_cdk.sources.declarative.requesters.http_requester import HttpRequester from airbyte_cdk.sources.declarative.types import StreamSlice, StreamState from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-paypal-transaction/source_paypal_transaction/run.py b/airbyte-integrations/connectors/source-paypal-transaction/source_paypal_transaction/run.py index 1a6d4cc56c0e..a6433dd29bdf 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/source_paypal_transaction/run.py +++ b/airbyte-integrations/connectors/source-paypal-transaction/source_paypal_transaction/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_paypal_transaction import SourcePaypalTransaction +from airbyte_cdk.entrypoint import launch + def run(): source = SourcePaypalTransaction() diff --git a/airbyte-integrations/connectors/source-paypal-transaction/source_paypal_transaction/source.py b/airbyte-integrations/connectors/source-paypal-transaction/source_paypal_transaction/source.py index 07d75f4bc281..c71a7fb2a782 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/source_paypal_transaction/source.py +++ b/airbyte-integrations/connectors/source-paypal-transaction/source_paypal_transaction/source.py @@ -6,6 +6,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. @@ -13,6 +14,7 @@ WARNING: Do not modify this file. """ + # Declarative Source class SourcePaypalTransaction(YamlDeclarativeSource): def __init__(self): diff --git a/airbyte-integrations/connectors/source-paypal-transaction/unit_tests/auth_components_test.py b/airbyte-integrations/connectors/source-paypal-transaction/unit_tests/auth_components_test.py index dd19b6306e77..1bf0f5692aaa 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/unit_tests/auth_components_test.py +++ b/airbyte-integrations/connectors/source-paypal-transaction/unit_tests/auth_components_test.py @@ -7,58 +7,59 @@ import pytest import requests import requests_mock -from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException from source_paypal_transaction.components import PayPalOauth2Authenticator +from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException + @pytest.fixture def mock_authenticator(): return PayPalOauth2Authenticator( config={}, parameters={}, - client_id='test_client_id', - client_secret='test_client_secret', - token_refresh_endpoint='https://test.token.endpoint', - grant_type='test_grant_type' + client_id="test_client_id", + client_secret="test_client_secret", + token_refresh_endpoint="https://test.token.endpoint", + grant_type="test_grant_type", ) + def test_get_refresh_access_token_response(mock_authenticator): - expected_response_json = {'access_token': 'test_access_token', 'expires_in': 3600} + expected_response_json = {"access_token": "test_access_token", "expires_in": 3600} with requests_mock.Mocker() as mock_request: - mock_request.post('https://test.token.endpoint', json=expected_response_json, status_code=200) + mock_request.post("https://test.token.endpoint", json=expected_response_json, status_code=200) # Call _get_refresh method mock_authenticator._get_refresh_access_token_response() - - assert mock_authenticator.access_token == expected_response_json['access_token'] + + assert mock_authenticator.access_token == expected_response_json["access_token"] + def test_token_expiration(mock_authenticator): # Mock response for initial token request - initial_response_json = {'access_token': 'initial_access_token', 'expires_in': 1} + initial_response_json = {"access_token": "initial_access_token", "expires_in": 1} # Mock response for token refresh request - refresh_response_json = {'access_token': 'refreshed_access_token', 'expires_in': 3600} + refresh_response_json = {"access_token": "refreshed_access_token", "expires_in": 3600} with requests_mock.Mocker() as mock_request: - - mock_request.post('https://test.token.endpoint', json=initial_response_json, status_code=200) + mock_request.post("https://test.token.endpoint", json=initial_response_json, status_code=200) mock_authenticator._get_refresh_access_token_response() # Assert that the initial access token is set correctly - assert mock_authenticator.access_token == initial_response_json['access_token'] + assert mock_authenticator.access_token == initial_response_json["access_token"] time.sleep(2) - mock_request.post('https://test.token.endpoint', json=refresh_response_json, status_code=200) + mock_request.post("https://test.token.endpoint", json=refresh_response_json, status_code=200) mock_authenticator._get_refresh_access_token_response() # Assert that the access token is refreshed - assert mock_authenticator.access_token == refresh_response_json['access_token'] + assert mock_authenticator.access_token == refresh_response_json["access_token"] def test_backoff_retry(mock_authenticator, caplog): - - mock_response = {'access_token': 'test_access_token', 'expires_in': 3600} + mock_response = {"access_token": "test_access_token", "expires_in": 3600} mock_reason = "Too Many Requests" - + with requests_mock.Mocker() as mock_request: - mock_request.post('https://test.token.endpoint', json=mock_response, status_code=429, reason=mock_reason) + mock_request.post("https://test.token.endpoint", json=mock_response, status_code=429, reason=mock_reason) with caplog.at_level(logging.INFO): try: mock_authenticator._get_refresh_access_token_response() @@ -67,6 +68,7 @@ def test_backoff_retry(mock_authenticator, caplog): else: pytest.fail("Expected DefaultBackoffException to be raised") + @pytest.fixture def authenticator_parameters(): return { @@ -75,14 +77,12 @@ def authenticator_parameters(): "config": {}, "parameters": {}, "token_refresh_endpoint": "https://test.token.endpoint", - "grant_type": "test_grant_type" + "grant_type": "test_grant_type", } + def test_get_headers(authenticator_parameters): expected_basic_auth = "Basic dGVzdF9jbGllbnRfaWQ6dGVzdF9jbGllbnRfc2VjcmV0" authenticator = PayPalOauth2Authenticator(**authenticator_parameters) headers = authenticator.get_headers() assert headers == {"Authorization": expected_basic_auth} - - - diff --git a/airbyte-integrations/connectors/source-paypal-transaction/unit_tests/conftest.py b/airbyte-integrations/connectors/source-paypal-transaction/unit_tests/conftest.py index 06dd08dc74a6..bd2f9c89836a 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-paypal-transaction/unit_tests/conftest.py @@ -11,21 +11,21 @@ @pytest.fixture(name="config") def config_fixture(): - #From File test + # From File test # with open('../secrets/config.json') as f: # return json.load(f) - #Mock test + # Mock test return { - "client_id": "your_client_id", - "client_secret": "your_client_secret", - "start_date": "2024-01-30T00:00:00Z", - "end_date": "2024-02-01T00:00:00Z", - "dispute_start_date": "2024-02-01T00:00:00.000Z", - "dispute_end_date": "2024-02-05T23:59:00.000Z", - "buyer_username": "Your Buyer email", - "buyer_password": "Your Buyer Password", - "payer_id": "ypur ACCOUNT ID", - "is_sandbox": True + "client_id": "your_client_id", + "client_secret": "your_client_secret", + "start_date": "2024-01-30T00:00:00Z", + "end_date": "2024-02-01T00:00:00Z", + "dispute_start_date": "2024-02-01T00:00:00.000Z", + "dispute_end_date": "2024-02-05T23:59:00.000Z", + "buyer_username": "Your Buyer email", + "buyer_password": "Your Buyer Password", + "payer_id": "ypur ACCOUNT ID", + "is_sandbox": True, } @@ -33,21 +33,24 @@ def config_fixture(): def source_fixture(): return SourcePaypalTransaction() + def validate_date_format(date_str, format): try: datetime.strptime(date_str, format) return True except ValueError: return False - + + def test_date_formats_in_config(config): start_date_format = "%Y-%m-%dT%H:%M:%SZ" dispute_date_format = "%Y-%m-%dT%H:%M:%S.%fZ" - assert validate_date_format(config['start_date'], start_date_format), "Start date format is incorrect" - assert validate_date_format(config['end_date'], start_date_format), "End date format is incorrect" - assert validate_date_format(config['dispute_start_date'], dispute_date_format), "Dispute start date format is incorrect" - assert validate_date_format(config['dispute_end_date'], dispute_date_format), "Dispute end date format is incorrect" + assert validate_date_format(config["start_date"], start_date_format), "Start date format is incorrect" + assert validate_date_format(config["end_date"], start_date_format), "End date format is incorrect" + assert validate_date_format(config["dispute_start_date"], dispute_date_format), "Dispute start date format is incorrect" + assert validate_date_format(config["dispute_end_date"], dispute_date_format), "Dispute end date format is incorrect" + @pytest.fixture(name="logger_mock") def logger_mock_fixture(): - return patch("source_paypal_transactions.source.AirbyteLogger") \ No newline at end of file + return patch("source_paypal_transactions.source.AirbyteLogger") diff --git a/airbyte-integrations/connectors/source-paypal-transaction/unit_tests/pagination_cursor.py b/airbyte-integrations/connectors/source-paypal-transaction/unit_tests/pagination_cursor.py index 958db41262da..ddf832641c2d 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/unit_tests/pagination_cursor.py +++ b/airbyte-integrations/connectors/source-paypal-transaction/unit_tests/pagination_cursor.py @@ -8,6 +8,7 @@ import pytest import requests import requests_mock + from airbyte_cdk.sources.declarative.decoders.decoder import Decoder from airbyte_cdk.sources.declarative.decoders.json_decoder import JsonDecoder from airbyte_cdk.sources.declarative.interpolation.interpolated_boolean import InterpolatedBoolean @@ -27,23 +28,23 @@ class CursorPaginationStrategy(PaginationStrategy): stop_condition (Optional[InterpolatedBoolean]): template string evaluating when to stop paginating decoder (Decoder): decoder to decode the response """ + cursor_value: Union[InterpolatedString, str] config: Config parameters: Mapping[str, Any] page_size: Optional[int] = None stop_condition: Optional[Union[InterpolatedBoolean, str]] = None decoder: Decoder = field(default_factory=JsonDecoder) - + def __post_init__(self): if isinstance(self.cursor_value, str): self.cursor_value = InterpolatedString.create(self.cursor_value, parameters=self.parameters) if isinstance(self.stop_condition, str): self.stop_condition = InterpolatedBoolean(condition=self.stop_condition, parameters=self.parameters) - + @property def initial_token(self) -> Optional[Any]: return None - def next_page_token(self, response: requests.Response, last_records: List[Mapping[str, Any]]) -> Optional[Any]: decoded_response = self.decoder.decode(response) @@ -51,53 +52,45 @@ def next_page_token(self, response: requests.Response, last_records: List[Mappin headers["link"] = response.links print("STOP CONDITION", self.stop_condition) - + if self.stop_condition: should_stop = self.stop_condition.eval(self.config, response=decoded_response, headers=headers, last_records=last_records) if should_stop: print("Stopping...") return None - + # Update cursor_value with the next_id from the response self.cursor_value = InterpolatedString.create(decoded_response.get("next_id"), parameters=self.parameters) token = self.cursor_value.eval(config=self.config, last_records=last_records, response=decoded_response, headers=headers) print("TOKEN", token) return token if token else None - + def reset(self): pass - + def get_page_size(self) -> Optional[int]: return self.page_size @pytest.fixture def mock_responses(): - return [ - "token_page_init.json", - "token_PAY-0L38757939422510JMW5ZJVA.json", - "token_PAYID-MW5XXZY5YL87592N34454913.json" - ] + return ["token_page_init.json", "token_PAY-0L38757939422510JMW5ZJVA.json", "token_PAYID-MW5XXZY5YL87592N34454913.json"] + @pytest.fixture -def cursor_pagination_strategy(mock_responses, stop_condition = None): +def cursor_pagination_strategy(mock_responses, stop_condition=None): parameters = {} decoder = JsonDecoder(parameters=parameters) cursor_value = "start_id" # Initialize with a default value - + for response_file in mock_responses: if cursor_value == "start_id": cursor_value = load_mock_data(response_file).get("next_id") else: break # Stop after getting the next_id from the first response - + return CursorPaginationStrategy( - cursor_value=cursor_value, - config={}, - parameters=parameters, - page_size=3, - stop_condition=stop_condition, - decoder=decoder + cursor_value=cursor_value, config={}, parameters=parameters, page_size=3, stop_condition=stop_condition, decoder=decoder ) @@ -105,6 +98,7 @@ def load_mock_data(filename): with open(os.path.join("./unit_tests/test_files", filename), "r") as file: return json.load(file) + def test_cursor_pagination(cursor_pagination_strategy, mock_responses): with requests_mock.Mocker() as m: base_url = "http://example.com/api/resource" @@ -126,21 +120,21 @@ def test_cursor_pagination(cursor_pagination_strategy, mock_responses): if i < len(mock_responses) - 1: next_id = load_mock_data(response_file)["next_id"] print("FOUND NEXT ID:", next_id) - + else: next_id = None - cursor_pagination_strategy(mock_responses, stop_condition = True) + cursor_pagination_strategy(mock_responses, stop_condition=True) # Make API call and process response response = requests.get(url) print("GET RESPONSE:", response) assert response.status_code == 200 - + decoded_response = response.json() last_records = decoded_response["payments"] next_id = cursor_pagination_strategy.next_page_token(response, last_records) print("NEXT ID:", next_id) - + # Verify the pagination stopped assert next_id is None print("No more pages") diff --git a/airbyte-integrations/connectors/source-paypal-transaction/unit_tests/pagination_increment.py b/airbyte-integrations/connectors/source-paypal-transaction/unit_tests/pagination_increment.py index 05b98d04f90a..1166076c7972 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/unit_tests/pagination_increment.py +++ b/airbyte-integrations/connectors/source-paypal-transaction/unit_tests/pagination_increment.py @@ -6,6 +6,7 @@ import pytest import requests import requests_mock + from airbyte_cdk.sources.declarative.requesters.paginators import DefaultPaginator, PaginationStrategy @@ -29,24 +30,25 @@ def reset(self): def get_page_size(self): return self.page_size + @pytest.fixture def mock_pagination_strategy(): return MockPaginationStrategy(page_size=500) + @pytest.fixture def paginator(): pagination_strategy = MockPaginationStrategy(page_size=3) return DefaultPaginator( - pagination_strategy=pagination_strategy, - config={}, - url_base="http://example.com/v1/reporting/transactions", - parameters={} + pagination_strategy=pagination_strategy, config={}, url_base="http://example.com/v1/reporting/transactions", parameters={} ) - + + def load_mock_data(page): with open(f"./unit_tests/test_files/page_{page}.json", "r") as file: return file.read() + # Test to verify pagination logic transitions from page 1 to page 2 def test_pagination_logic(paginator): page_1_data = load_mock_data(1) @@ -54,7 +56,7 @@ def test_pagination_logic(paginator): paginator_url_1 = f"{paginator.url_base.string}?page=1&page_size={paginator.pagination_strategy.get_page_size}" paginator_url_2 = f"{paginator.url_base.string}?page=2&page_size={paginator.pagination_strategy.get_page_size}" - + with requests_mock.Mocker() as m: m.get(paginator_url_1, text=page_1_data, status_code=200) m.get(paginator_url_2, text=page_2_data, status_code=200) @@ -64,16 +66,14 @@ def test_pagination_logic(paginator): response_page_2 = requests.get(paginator_url_2) response_page_2._content = str.encode(page_2_data) - # Simulate getting the next page token from page 1's response next_page_token_page_1 = paginator.next_page_token(response_page_1, []) print("NEXT PAGE TOKEN", next_page_token_page_1) # Assert that the next page token indicates moving to page 2 - assert next_page_token_page_1['next_page_token'] == 2, "Failed to transition from page 1 to page 2" + assert next_page_token_page_1["next_page_token"] == 2, "Failed to transition from page 1 to page 2" - # Check that the correct page size is used in requests and that we have the right number of pages - assert len(m.request_history) == 2 - assert "page_size=3" in m.request_history[0].url - assert "page_size=3" in m.request_history[1].url \ No newline at end of file + assert len(m.request_history) == 2 + assert "page_size=3" in m.request_history[0].url + assert "page_size=3" in m.request_history[1].url diff --git a/airbyte-integrations/connectors/source-paystack/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-paystack/integration_tests/acceptance.py index efc25f08ce82..78b220cebb18 100644 --- a/airbyte-integrations/connectors/source-paystack/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-paystack/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-pendo/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-pendo/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-pendo/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-pendo/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-pendo/metadata.yaml b/airbyte-integrations/connectors/source-pendo/metadata.yaml index 20811e3dd5fd..9cbf8d835758 100644 --- a/airbyte-integrations/connectors/source-pendo/metadata.yaml +++ b/airbyte-integrations/connectors/source-pendo/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: b1ccb590-e84f-46c0-83a0-2048ccfffdae - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.5 dockerRepository: airbyte/source-pendo documentationUrl: https://docs.airbyte.com/integrations/sources/pendo githubIssueLabel: source-pendo diff --git a/airbyte-integrations/connectors/source-pennylane/manifest.yaml b/airbyte-integrations/connectors/source-pennylane/manifest.yaml index a35423e830d4..cddb5b96cbdf 100644 --- a/airbyte-integrations/connectors/source-pennylane/manifest.yaml +++ b/airbyte-integrations/connectors/source-pennylane/manifest.yaml @@ -497,10 +497,40 @@ streams: properties: amount: type: string + billing_subscription: + type: object + properties: + id: + type: integer + v2_id: + type: integer categories: type: array credit_notes: type: array + items: + type: object + properties: + amount: + type: string + currency: + type: string + currency_amount: + type: string + currency_price_before_tax: + type: string + currency_tax: + type: string + draft: + type: boolean + id: + type: string + invoice_number: + type: string + tax: + type: string + v2_id: + type: integer currency: type: string currency_amount: @@ -572,10 +602,19 @@ streams: type: string id: type: string + imputation_dates: + type: object + properties: + end_date: + type: string + start_date: + type: string invoice_number: type: string is_draft: type: boolean + is_estimate: + type: boolean label: type: string language: @@ -630,6 +669,17 @@ streams: type: array paid: type: boolean + payments: + type: array + items: + type: object + properties: + created_at: + type: string + currency_amount: + type: string + label: + type: string pdf_invoice_free_text: type: string pdf_invoice_subject: @@ -646,8 +696,19 @@ streams: type: string status: type: string + transactions_reference: + type: object + properties: + banking_provider: + type: string + provider_field_name: + type: string + provider_field_value: + type: string updated_at: type: string + v2_id: + type: integer retriever: type: SimpleRetriever requester: @@ -975,4 +1036,4 @@ metadata: customer_invoices: true products: true category_groups: true - categories: true + categories: true \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-pennylane/metadata.yaml b/airbyte-integrations/connectors/source-pennylane/metadata.yaml index febde32d6307..d4520691770b 100644 --- a/airbyte-integrations/connectors/source-pennylane/metadata.yaml +++ b/airbyte-integrations/connectors/source-pennylane/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-pennylane connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.3@sha256:9214270d83304213977c08e91fd9c55a98819543dbbf0df25a4356299af4f3ab connectorSubtype: api connectorType: source definitionId: b9e4a306-4e3b-4387-a01d-c00d03d8c28c - dockerImageTag: 0.0.2 + dockerImageTag: 0.1.1 dockerRepository: airbyte/source-pennylane githubIssueLabel: source-pennylane icon: icon.svg diff --git a/airbyte-integrations/connectors/source-persistiq/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-persistiq/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-persistiq/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-persistiq/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-persistiq/metadata.yaml b/airbyte-integrations/connectors/source-persistiq/metadata.yaml index cfed763550e1..b7f11d16d91c 100644 --- a/airbyte-integrations/connectors/source-persistiq/metadata.yaml +++ b/airbyte-integrations/connectors/source-persistiq/metadata.yaml @@ -3,7 +3,7 @@ data: hosts: - api.persistiq.com connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc remoteRegistries: pypi: enabled: false @@ -16,7 +16,7 @@ data: connectorSubtype: api connectorType: source definitionId: 3052c77e-8b91-47e2-97a0-a29a22794b4b - dockerImageTag: 0.3.4 + dockerImageTag: 0.3.8 dockerRepository: airbyte/source-persistiq githubIssueLabel: source-persistiq icon: persistiq.svg diff --git a/airbyte-integrations/connectors/source-persona/metadata.yaml b/airbyte-integrations/connectors/source-persona/metadata.yaml index a761ea4527ce..05a64ff68566 100644 --- a/airbyte-integrations/connectors/source-persona/metadata.yaml +++ b/airbyte-integrations/connectors/source-persona/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-persona connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 7e55429a-a1ea-43c2-81c2-4fc3cf88f81f - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-persona githubIssueLabel: source-persona icon: icon.svg diff --git a/airbyte-integrations/connectors/source-pexels-api/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-pexels-api/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-pexels-api/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-pexels-api/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-pexels-api/metadata.yaml b/airbyte-integrations/connectors/source-pexels-api/metadata.yaml index 16494d725886..f5341dd526d3 100644 --- a/airbyte-integrations/connectors/source-pexels-api/metadata.yaml +++ b/airbyte-integrations/connectors/source-pexels-api/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 69d9eb65-8026-47dc-baf1-e4bf67901fd6 - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-pexels-api githubIssueLabel: source-pexels-api icon: pexels.svg @@ -39,5 +39,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.4.3@sha256:8937b693c7e01087f6e86e683826ac20f160f7952b8f0a13cbf4f9bfdd7af570 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-picqer/metadata.yaml b/airbyte-integrations/connectors/source-picqer/metadata.yaml index ca0f4d5840a4..5d4a71afd5d6 100644 --- a/airbyte-integrations/connectors/source-picqer/metadata.yaml +++ b/airbyte-integrations/connectors/source-picqer/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-picqer connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 860ca029-c88c-4c0a-a7d8-08ce6e84729c - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.9 dockerRepository: airbyte/source-picqer githubIssueLabel: source-picqer icon: icon.svg diff --git a/airbyte-integrations/connectors/source-pingdom/README.md b/airbyte-integrations/connectors/source-pingdom/README.md new file mode 100644 index 000000000000..9be2f8d533a0 --- /dev/null +++ b/airbyte-integrations/connectors/source-pingdom/README.md @@ -0,0 +1,43 @@ +# Pingdom +This directory contains the manifest-only connector for `source-pingdom`. + +This Source is capable of syncing the following core Streams: + +- [checks](https://docs.pingdom.com/api/#tag/Checks/paths/~1checks/get) +- [performance](https://docs.pingdom.com/api/#tag/Summary.performance/paths/~1summary.performance~1{checkid}/get) + +## Requirements + +- **Pingdom API Key**.[required] See the [PingDom API docs](https://docs.pingdom.com/api/#section/Authentication) for information on how to obtain the API token. +- **Start date**.[required]. To Fetch data from. Only use for Incremental way. +- **Probes**[optional]. Filter to only use results from a list of probes. Format is a comma separated list of probe identifiers. +- **Resolution**[optional]. Interval Size. Should be `hour`, `day`, `week`. Default: `hour` + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-pingdom:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-pingdom build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-pingdom test +``` + diff --git a/airbyte-integrations/connectors/source-pingdom/acceptance-test-config.yml b/airbyte-integrations/connectors/source-pingdom/acceptance-test-config.yml new file mode 100644 index 000000000000..28dfc4e806f2 --- /dev/null +++ b/airbyte-integrations/connectors/source-pingdom/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-pingdom:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-pingdom/icon.svg b/airbyte-integrations/connectors/source-pingdom/icon.svg new file mode 100644 index 000000000000..e7a3e1db1f31 --- /dev/null +++ b/airbyte-integrations/connectors/source-pingdom/icon.svg @@ -0,0 +1 @@ +Pingdom icon diff --git a/airbyte-integrations/connectors/source-pingdom/manifest.yaml b/airbyte-integrations/connectors/source-pingdom/manifest.yaml new file mode 100644 index 000000000000..bfb4289424b8 --- /dev/null +++ b/airbyte-integrations/connectors/source-pingdom/manifest.yaml @@ -0,0 +1,217 @@ +version: 5.7.5 + +type: DeclarativeSource + +description: >- + This Source is capable of syncing the following core Streams: + + + - [checks](https://docs.pingdom.com/api/#tag/Checks/paths/~1checks/get) + + - + [performance](https://docs.pingdom.com/api/#tag/Summary.performance/paths/~1summary.performance~1{checkid}/get) + + + ## Requirements + + + - **Pingdom API Key**.[required] See the [PingDom API + docs](https://docs.pingdom.com/api/#section/Authentication) for information on + how to obtain the API token. + + - **Start date**.[required]. To Fetch data from. Only use for Incremental way. + + - **Probes**[optional]. Filter to only use results from a list of probes. + Format is a comma separated list of probe identifiers. + + - **Resolution**[optional]. Interval Size. Should be `hour`, `day`, `week`. + Default: `hour` + +check: + type: CheckStream + stream_names: + - checks + +definitions: + streams: + checks: + type: DeclarativeStream + name: checks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: checks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - checks + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 25000 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/checks" + performance: + type: DeclarativeStream + name: performance + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: summary.performance/{{stream_partition.check_id}} + http_method: GET + request_parameters: + probes: "{{ config['probes'] }}" + resolution: "{{ config['resolution'] }}" + includeuptime: "true" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: check_id + stream: + $ref: "#/definitions/streams/checks" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: stream_end_time + cursor_datetime_formats: + - "%s" + datetime_format: "%s" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: from + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: to + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + transformations: + - type: AddFields + fields: + - path: + - check_id + value: "{{stream_partition.check_id}}" + - type: AddFields + fields: + - path: + - stream_end_time + value: "{{stream_interval.end_time}}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/performance" + base_requester: + type: HttpRequester + url_base: https://api.pingdom.com/api/3.1/ + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + +streams: + - $ref: "#/definitions/streams/checks" + - $ref: "#/definitions/streams/performance" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - start_date + properties: + probes: + type: string + title: probes + examples: + - probe1 + - probe2 + order: 0 + api_key: + type: string + title: API Key + airbyte_secret: true + order: 1 + resolution: + type: string + enum: + - hour + - day + - week + title: resolution + default: hour + order: 2 + start_date: + type: string + title: Start date + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + format: date-time + order: 3 + additionalProperties: true + +metadata: + autoImportSchema: + checks: false + performance: false + yamlComponents: + global: + - authenticator + testedStreams: + checks: + hasRecords: true + streamHash: 3b361da7c9405a1ad99f5d338b01400dde2b683a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + performance: + streamHash: d3620787044ce3c1be05dcc027713739407d57d9 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + checks: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} + performance: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} diff --git a/airbyte-integrations/connectors/source-pingdom/metadata.yaml b/airbyte-integrations/connectors/source-pingdom/metadata.yaml new file mode 100644 index 000000000000..cfb5b3184ee2 --- /dev/null +++ b/airbyte-integrations/connectors/source-pingdom/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "https://api.pingdom.com/api" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-pingdom + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + connectorSubtype: api + connectorType: source + definitionId: 14fb7a17-a371-4ebc-a072-b339c4daa4c1 + dockerImageTag: 0.0.1 + dockerRepository: airbyte/source-pingdom + githubIssueLabel: source-pingdom + icon: icon.svg + license: MIT + name: Pingdom + releaseDate: 2024-12-03 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/pingdom + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-pinterest/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-pinterest/integration_tests/acceptance.py index d49b55882333..a9256a533972 100644 --- a/airbyte-integrations/connectors/source-pinterest/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-pinterest/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-pinterest/main.py b/airbyte-integrations/connectors/source-pinterest/main.py index aff013c70319..59806e3eb585 100644 --- a/airbyte-integrations/connectors/source-pinterest/main.py +++ b/airbyte-integrations/connectors/source-pinterest/main.py @@ -4,5 +4,6 @@ from source_pinterest.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-pinterest/metadata.yaml b/airbyte-integrations/connectors/source-pinterest/metadata.yaml index c76e7ea5f578..b7c53c4e0525 100644 --- a/airbyte-integrations/connectors/source-pinterest/metadata.yaml +++ b/airbyte-integrations/connectors/source-pinterest/metadata.yaml @@ -5,10 +5,10 @@ data: connectorSubtype: api connectorType: source definitionId: 5cb7e5fe-38c2-11ec-8d3d-0242ac130003 - dockerImageTag: 2.0.21 + dockerImageTag: 2.0.26 dockerRepository: airbyte/source-pinterest connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 githubIssueLabel: source-pinterest icon: pinterest.svg license: MIT diff --git a/airbyte-integrations/connectors/source-pinterest/poetry.lock b/airbyte-integrations/connectors/source-pinterest/poetry.lock index 8f54d3644dfe..0feaee7faf23 100644 --- a/airbyte-integrations/connectors/source-pinterest/poetry.lock +++ b/airbyte-integrations/connectors/source-pinterest/poetry.lock @@ -69,24 +69,24 @@ files = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -101,19 +101,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -179,13 +179,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -269,127 +269,114 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -462,20 +449,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -525,13 +512,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -546,13 +533,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -560,7 +547,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -610,13 +596,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -717,22 +703,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -830,69 +819,86 @@ twitter = ["twython"] [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -995,19 +1001,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1015,100 +1021,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -1116,13 +1133,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1328,105 +1345,105 @@ files = [ [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -1532,33 +1549,33 @@ tests = ["coverage (>=3.7.1,<6.0.0)", "flake8", "mypy", "pytest (>=4.6)", "pytes [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1600,20 +1617,21 @@ files = [ [[package]] name = "tqdm" -version = "4.66.6" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63"}, - {file = "tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -1645,13 +1663,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1676,81 +1694,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-pinterest/pyproject.toml b/airbyte-integrations/connectors/source-pinterest/pyproject.toml index 0212a1b54d5a..6339a590a782 100644 --- a/airbyte-integrations/connectors/source-pinterest/pyproject.toml +++ b/airbyte-integrations/connectors/source-pinterest/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "2.0.21" +version = "2.0.26" name = "source-pinterest" description = "Source implementation for Pinterest." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-pinterest/source_pinterest/components/auth.py b/airbyte-integrations/connectors/source-pinterest/source_pinterest/components/auth.py index f31a115c09a9..91a946b0b711 100644 --- a/airbyte-integrations/connectors/source-pinterest/source_pinterest/components/auth.py +++ b/airbyte-integrations/connectors/source-pinterest/source_pinterest/components/auth.py @@ -9,12 +9,14 @@ import backoff import requests + from airbyte_cdk.models import FailureType from airbyte_cdk.sources.declarative.auth import DeclarativeOauth2Authenticator from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException from airbyte_cdk.utils import AirbyteTracedException from airbyte_cdk.utils.airbyte_secrets_utils import add_to_secrets + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-pinterest/source_pinterest/python_stream_auth.py b/airbyte-integrations/connectors/source-pinterest/source_pinterest/python_stream_auth.py index d689a4643205..bfdcd32d582b 100644 --- a/airbyte-integrations/connectors/source-pinterest/source_pinterest/python_stream_auth.py +++ b/airbyte-integrations/connectors/source-pinterest/source_pinterest/python_stream_auth.py @@ -6,6 +6,7 @@ import pendulum import requests + from airbyte_cdk.models import FailureType from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException from airbyte_cdk.sources.streams.http.requests_native_auth import Oauth2Authenticator diff --git a/airbyte-integrations/connectors/source-pinterest/source_pinterest/reports/reports.py b/airbyte-integrations/connectors/source-pinterest/source_pinterest/reports/reports.py index 892b5fc652f2..f469def56e9c 100644 --- a/airbyte-integrations/connectors/source-pinterest/source_pinterest/reports/reports.py +++ b/airbyte-integrations/connectors/source-pinterest/source_pinterest/reports/reports.py @@ -8,9 +8,10 @@ from typing import Any, Iterable, List, Mapping, MutableMapping, Optional from urllib.parse import urljoin -import airbyte_cdk.sources.utils.casing as casing import backoff import requests + +import airbyte_cdk.sources.utils.casing as casing from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.streams.core import package_name_from_class from airbyte_cdk.sources.utils.schema_helpers import ResourceSchemaLoader diff --git a/airbyte-integrations/connectors/source-pinterest/source_pinterest/source.py b/airbyte-integrations/connectors/source-pinterest/source_pinterest/source.py index bdcb8f7c00ce..44de3103bdc7 100644 --- a/airbyte-integrations/connectors/source-pinterest/source_pinterest/source.py +++ b/airbyte-integrations/connectors/source-pinterest/source_pinterest/source.py @@ -8,6 +8,7 @@ from typing import Any, List, Mapping import pendulum + from airbyte_cdk.models import FailureType from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource from airbyte_cdk.sources.streams import Stream @@ -32,6 +33,7 @@ ) from .streams import PinterestStream + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-pinterest/source_pinterest/streams.py b/airbyte-integrations/connectors/source-pinterest/source_pinterest/streams.py index d90f3e0862e6..94045a7e7013 100644 --- a/airbyte-integrations/connectors/source-pinterest/source_pinterest/streams.py +++ b/airbyte-integrations/connectors/source-pinterest/source_pinterest/streams.py @@ -9,6 +9,7 @@ import pendulum import requests + from airbyte_cdk import AirbyteTracedException, BackoffStrategy from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies import WaitTimeFromHeaderBackoffStrategy @@ -20,6 +21,7 @@ from .utils import get_analytics_columns, to_datetime_str + # For Pinterest analytics streams rate limit is 300 calls per day / per user. # once hit - response would contain `code` property with int. MAX_RATE_LIMIT_CODE = 8 diff --git a/airbyte-integrations/connectors/source-pinterest/unit_tests/conftest.py b/airbyte-integrations/connectors/source-pinterest/unit_tests/conftest.py index 0ca0151e2db8..271de750bcff 100644 --- a/airbyte-integrations/connectors/source-pinterest/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-pinterest/unit_tests/conftest.py @@ -5,11 +5,12 @@ from typing import Any, Mapping from unittest.mock import MagicMock -from airbyte_cdk.sources.streams import Stream from pytest import fixture from source_pinterest.reports import CampaignAnalyticsReport from source_pinterest.source import SourcePinterest +from airbyte_cdk.sources.streams import Stream + @fixture def test_config() -> Mapping[str, str]: diff --git a/airbyte-integrations/connectors/source-pinterest/unit_tests/test_auth.py b/airbyte-integrations/connectors/source-pinterest/unit_tests/test_auth.py index 86cc6f23f8f4..6f2f2207cdb8 100644 --- a/airbyte-integrations/connectors/source-pinterest/unit_tests/test_auth.py +++ b/airbyte-integrations/connectors/source-pinterest/unit_tests/test_auth.py @@ -7,16 +7,19 @@ import pendulum import pytest import requests +from requests import Response +from source_pinterest.python_stream_auth import PinterestOauthAuthenticator + from airbyte_cdk.models import FailureType from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from requests import Response -from source_pinterest.python_stream_auth import PinterestOauthAuthenticator + LOGGER = logging.getLogger(__name__) resp = Response() + class TestPinterestOauthAuthenticator: """ Test class for custom PinterestOauthAuthenticator, derived from the CDK's Oauth2Authenticator class. @@ -69,7 +72,9 @@ def test_refresh_access_token_invalid_or_expired(self, mocker, oauth): mocker.patch.object(resp, "status_code", 400) mocker.patch.object(oauth, "_wrap_refresh_token_exception", return_value=True) - with pytest.raises(AirbyteTracedException, match="Refresh token is invalid or expired. Please re-authenticate from Sources//Settings."): + with pytest.raises( + AirbyteTracedException, match="Refresh token is invalid or expired. Please re-authenticate from Sources//Settings." + ): oauth.refresh_access_token() diff --git a/airbyte-integrations/connectors/source-pinterest/unit_tests/test_incremental_streams.py b/airbyte-integrations/connectors/source-pinterest/unit_tests/test_incremental_streams.py index 3dd38604a86e..bfa60d227e31 100644 --- a/airbyte-integrations/connectors/source-pinterest/unit_tests/test_incremental_streams.py +++ b/airbyte-integrations/connectors/source-pinterest/unit_tests/test_incremental_streams.py @@ -7,11 +7,12 @@ from unittest.mock import MagicMock import pytest -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.streams.http.error_handlers import ResponseAction from pytest import fixture from source_pinterest.streams import IncrementalPinterestSubStream +from airbyte_cdk.models import SyncMode +from airbyte_cdk.sources.streams.http.error_handlers import ResponseAction + from .conftest import get_stream_by_name from .utils import create_requests_response @@ -135,7 +136,8 @@ def test_semi_incremental_read(requests_mock, test_config, start_date, stream_st stream.state = stream_state actual_records = [ - dict(record) for stream_slice in stream.stream_slices(sync_mode=SyncMode.incremental) + dict(record) + for stream_slice in stream.stream_slices(sync_mode=SyncMode.incremental) for record in stream.read_records(sync_mode=SyncMode.incremental, stream_slice=stream_slice) ] assert actual_records == expected_records diff --git a/airbyte-integrations/connectors/source-pinterest/unit_tests/test_reports.py b/airbyte-integrations/connectors/source-pinterest/unit_tests/test_reports.py index df5c903ee347..16df2e7ad9cf 100644 --- a/airbyte-integrations/connectors/source-pinterest/unit_tests/test_reports.py +++ b/airbyte-integrations/connectors/source-pinterest/unit_tests/test_reports.py @@ -24,7 +24,8 @@ ) from source_pinterest.utils import get_analytics_columns -os.environ["REQUEST_CACHE_PATH"] = '/tmp' + +os.environ["REQUEST_CACHE_PATH"] = "/tmp" def test_request_body_json(analytics_report_stream, date_range): @@ -79,18 +80,20 @@ def test_streams(test_config): def test_custom_streams(test_config): config = copy.deepcopy(test_config) - config['custom_reports'] = [{ - "name": "vadim_report", - "level": "AD_GROUP", - "granularity": "MONTH", - "click_window_days": 30, - "engagement_window_days": 30, - "view_window_days": 30, - "conversion_report_time": "TIME_OF_CONVERSION", - "attribution_types": ["INDIVIDUAL", "HOUSEHOLD"], - "columns": ["ADVERTISER_ID", "AD_ACCOUNT_ID", "AD_GROUP_ID", "CTR", "IMPRESSION_2"], - "start_date": "2023-01-08" - }] + config["custom_reports"] = [ + { + "name": "vadim_report", + "level": "AD_GROUP", + "granularity": "MONTH", + "click_window_days": 30, + "engagement_window_days": 30, + "view_window_days": 30, + "conversion_report_time": "TIME_OF_CONVERSION", + "attribution_types": ["INDIVIDUAL", "HOUSEHOLD"], + "columns": ["ADVERTISER_ID", "AD_ACCOUNT_ID", "AD_GROUP_ID", "CTR", "IMPRESSION_2"], + "start_date": "2023-01-08", + } + ] source = SourcePinterest() streams = source.streams(config) expected_streams_number = 33 @@ -100,18 +103,18 @@ def test_custom_streams(test_config): @pytest.mark.parametrize( ("report_name", "expected_level"), ( - [CampaignAnalyticsReport, 'CAMPAIGN'], - [CampaignTargetingReport, 'CAMPAIGN_TARGETING'], - [AdvertiserReport, 'ADVERTISER'], - [AdvertiserTargetingReport, 'ADVERTISER_TARGETING'], - [AdGroupReport, 'AD_GROUP'], - [AdGroupTargetingReport, 'AD_GROUP_TARGETING'], - [PinPromotionReport, 'PIN_PROMOTION'], - [PinPromotionTargetingReport, 'PIN_PROMOTION_TARGETING'], - [ProductGroupReport, 'PRODUCT_GROUP'], - [ProductGroupTargetingReport, 'PRODUCT_GROUP_TARGETING'], - [ProductItemReport, 'PRODUCT_ITEM'], - [KeywordReport, 'KEYWORD'] + [CampaignAnalyticsReport, "CAMPAIGN"], + [CampaignTargetingReport, "CAMPAIGN_TARGETING"], + [AdvertiserReport, "ADVERTISER"], + [AdvertiserTargetingReport, "ADVERTISER_TARGETING"], + [AdGroupReport, "AD_GROUP"], + [AdGroupTargetingReport, "AD_GROUP_TARGETING"], + [PinPromotionReport, "PIN_PROMOTION"], + [PinPromotionTargetingReport, "PIN_PROMOTION_TARGETING"], + [ProductGroupReport, "PRODUCT_GROUP"], + [ProductGroupTargetingReport, "PRODUCT_GROUP_TARGETING"], + [ProductItemReport, "PRODUCT_ITEM"], + [KeywordReport, "KEYWORD"], ), ) def test_level(test_config, report_name, expected_level): diff --git a/airbyte-integrations/connectors/source-pinterest/unit_tests/test_source.py b/airbyte-integrations/connectors/source-pinterest/unit_tests/test_source.py index 6012f9d1b211..5e615e7c2e8d 100644 --- a/airbyte-integrations/connectors/source-pinterest/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-pinterest/unit_tests/test_source.py @@ -5,9 +5,10 @@ from unittest.mock import MagicMock import pytest -from airbyte_cdk.utils import AirbyteTracedException from source_pinterest.source import SourcePinterest +from airbyte_cdk.utils import AirbyteTracedException + def test_check_connection(requests_mock, test_config): requests_mock.get("https://api.pinterest.com/v5/boards", status_code=200) @@ -30,8 +31,7 @@ def test_check_connection_expired_token(requests_mock, test_config): logger_mock = MagicMock() assert source.check_connection(logger_mock, test_config) == ( False, - "Unable to connect to stream boards - 401 Client Error: None " - "for url: https://api.pinterest.com/v5/oauth/token", + "Unable to connect to stream boards - 401 Client Error: None " "for url: https://api.pinterest.com/v5/oauth/token", ) diff --git a/airbyte-integrations/connectors/source-pinterest/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-pinterest/unit_tests/test_streams.py index 80f5d4aa37a7..b1ecc6bfef44 100644 --- a/airbyte-integrations/connectors/source-pinterest/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-pinterest/unit_tests/test_streams.py @@ -8,10 +8,6 @@ import pytest import requests -from airbyte_cdk import AirbyteTracedException -from airbyte_cdk.models.airbyte_protocol import SyncMode -from airbyte_cdk.sources.declarative.types import StreamSlice -from airbyte_cdk.sources.streams.http.error_handlers import ResponseAction from source_pinterest.streams import ( AnalyticsApiBackoffStrategyDecorator, NonJSONResponse, @@ -22,9 +18,15 @@ ) from source_pinterest.utils import get_analytics_columns +from airbyte_cdk import AirbyteTracedException +from airbyte_cdk.models.airbyte_protocol import SyncMode +from airbyte_cdk.sources.declarative.types import StreamSlice +from airbyte_cdk.sources.streams.http.error_handlers import ResponseAction + from .conftest import get_stream_by_name from .utils import create_requests_response + os.environ["REQUEST_CACHE_PATH"] = "/tmp" _ANY_STREAM_NAME = "any_stream_name" _RETRY_AFTER_HEADER = "XRetry-After" @@ -80,7 +82,8 @@ def test_parse_response_with_sensitive_data(requests_mock, test_config): json={"items": [{"id": "CatalogsFeeds1", "credentials": {"password": "bla"}}]}, ) actual_response = [ - dict(record) for stream_slice in stream.stream_slices(sync_mode=SyncMode.full_refresh) + dict(record) + for stream_slice in stream.stream_slices(sync_mode=SyncMode.full_refresh) for record in stream.read_records(sync_mode=SyncMode.full_refresh, stream_slice=stream_slice) ] assert actual_response == [{"id": "CatalogsFeeds1"}] @@ -122,7 +125,9 @@ def test_response_action(requests_mock, patch_base_class, http_status, expected_ ), ) @patch("time.sleep", return_value=None) -def test_declarative_stream_response_action_on_max_rate_limit_error(mock_sleep, requests_mock, test_response, status_code, expected_response_action): +def test_declarative_stream_response_action_on_max_rate_limit_error( + mock_sleep, requests_mock, test_response, status_code, expected_response_action +): response_mock = create_requests_response(requests_mock, status_code, {}) error_handler = PinterestErrorHandler(logger=MagicMock(), stream_name="any_stream_name") assert error_handler.interpret_response(response_mock).response_action == expected_response_action diff --git a/airbyte-integrations/connectors/source-pipedrive/acceptance-test-config.yml b/airbyte-integrations/connectors/source-pipedrive/acceptance-test-config.yml index 303f046105c3..8f4edb5f0c74 100644 --- a/airbyte-integrations/connectors/source-pipedrive/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-pipedrive/acceptance-test-config.yml @@ -17,6 +17,9 @@ acceptance_tests: basic_read: tests: - config_path: "secrets/config.json" + expect_records: + path: "integration_tests/expected_records.jsonl" + exact_order: no configured_catalog_path: "integration_tests/configured_catalog.json" fail_on_extra_columns: false empty_streams: @@ -30,13 +33,12 @@ acceptance_tests: - name: stages - name: deal_products - name: mail + - name: deals + - name: users + - name: persons incremental: - tests: - - config_path: "secrets/config.json" - configured_catalog_path: "integration_tests/configured_catalog.json" - future_state: - future_state_path: "integration_tests/abnormal_state.json" + bypass_reason: "All incremental streams are empty in sandbox account." full_refresh: tests: - config_path: "secrets/config.json" diff --git a/airbyte-integrations/connectors/source-pipedrive/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-pipedrive/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-pipedrive/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-pipedrive/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-pipedrive/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-pipedrive/integration_tests/expected_records.jsonl new file mode 100644 index 000000000000..e97465c57468 --- /dev/null +++ b/airbyte-integrations/connectors/source-pipedrive/integration_tests/expected_records.jsonl @@ -0,0 +1,34 @@ +{"stream":"deal_fields","data":{"id":12488,"key":"eae9c2a5b618934581aebed0747cc33cd681379e","name":"Test field 3","order_nr":4,"field_type":"enum","json_column_flag":true,"add_time":"2023-02-22 11:04:13","update_time":"2023-02-22 11:04:13","last_updated_by_user_id":11884360,"edit_flag":true,"details_visible_flag":true,"add_visible_flag":true,"important_flag":true,"bulk_edit_allowed":true,"filtering_allowed":true,"sortable_flag":true,"mandatory_flag":false,"searchable_flag":true,"active_flag":true,"projects_detail_visible_flag":false,"show_in_pipelines":{"show_in_all":true,"pipeline_ids":[]},"options":[{"id":23,"label":"Test"}]},"emitted_at":1733742439563} +{"stream":"deal_fields","data":{"id":12489,"key":"bed1d9f4cfdaf761fab04b38df20144b0fd156d6","name":"Test field 4","order_nr":5,"field_type":"varchar","json_column_flag":true,"add_time":"2023-02-22 11:04:30","update_time":"2023-02-22 11:04:30","last_updated_by_user_id":11884360,"edit_flag":true,"details_visible_flag":true,"add_visible_flag":true,"important_flag":true,"bulk_edit_allowed":true,"filtering_allowed":true,"sortable_flag":true,"mandatory_flag":false,"searchable_flag":true,"active_flag":true,"projects_detail_visible_flag":false,"show_in_pipelines":{"show_in_all":true,"pipeline_ids":[]}},"emitted_at":1733742439563} +{"stream":"deal_fields","data":{"id":12490,"key":"41505adc22569bf93214dd7f7eaa10eaa387947d","name":"Test field 5","order_nr":6,"field_type":"varchar","json_column_flag":true,"add_time":"2023-02-22 11:04:43","update_time":"2023-02-22 11:04:43","last_updated_by_user_id":11884360,"edit_flag":true,"details_visible_flag":true,"add_visible_flag":true,"important_flag":true,"bulk_edit_allowed":true,"filtering_allowed":true,"sortable_flag":true,"mandatory_flag":false,"searchable_flag":true,"active_flag":true,"projects_detail_visible_flag":false,"show_in_pipelines":{"show_in_all":true,"pipeline_ids":[]}},"emitted_at":1733742439563} +{"stream":"goals","data":{"id":"404e9d01204e052dff21ec32121f0270","owner_id":11884360,"title":"Activities added Team Airbyte","type":{"name":"activities_added","params":{"pipeline_id":null,"activity_type_id":[1]}},"assignee":{"type":"person","id":11884360},"expected_outcome":{"tracking_metric":"quantity","target":100},"interval":"weekly","duration":{"start":"2023-10-15","end":"2023-11-03"},"report_ids":["389fb0576579ea5b28761aef85af7e8a"],"is_active":false},"emitted_at":1733742439864} +{"stream":"goals","data":{"id":"b1b124b30aea9704b28dde37a41b1cb2","owner_id":11884360,"title":"Activities completed Team Airbyte","type":{"name":"activities_completed","params":{"pipeline_id":null,"activity_type_id":[1]}},"assignee":{"type":"person","id":11884360},"expected_outcome":{"tracking_metric":"quantity","target":10},"interval":"weekly","duration":{"start":"2023-09-01","end":"2023-10-10"},"report_ids":["cf970db4608d730d53dc87875ebb2302"],"is_active":false},"emitted_at":1733742439890} +{"stream":"goals","data":{"id":"b1b124b30aea9704b28dde37a41b2bcb","owner_id":11884360,"title":"Deals won Team Airbyte","type":{"name":"deals_won","params":{"pipeline_id":[1]}},"assignee":{"type":"person","id":11884360},"expected_outcome":{"tracking_metric":"sum","currency_id":148,"target":100},"interval":"monthly","duration":{"start":"2023-10-01","end":null},"report_ids":["ddbcc8dc48e84aea5e28a2db3488e89d"],"is_active":true},"emitted_at":1733742439890} +{"stream":"lead_labels","data":{"id":"aecece60-c069-11eb-93bf-b59c4f1731e6","name":"Hot","color":"red","add_time":"2021-05-29T10:36:10.182Z","update_time":"2021-05-29T10:36:10.182Z"},"emitted_at":1733742439909} +{"stream":"lead_labels","data":{"id":"aecece61-c069-11eb-93bf-b59c4f1731e6","name":"Warm","color":"yellow","add_time":"2021-05-29T10:36:10.182Z","update_time":"2021-05-29T10:36:10.182Z"},"emitted_at":1733742439910} +{"stream":"lead_labels","data":{"id":"aecece62-c069-11eb-93bf-b59c4f1731e6","name":"Cold","color":"blue","add_time":"2021-05-29T10:36:10.182Z","update_time":"2021-05-29T10:36:10.182Z"},"emitted_at":1733742439910} +{"stream":"activity_types","data":{"id":5,"order_nr":5,"name":"Email","key_string":"email","icon_key":"email","active_flag":true,"is_custom_flag":false,"add_time":"2020-12-10 07:23:48"},"emitted_at":1733742439922} +{"stream":"activity_types","data":{"id":6,"order_nr":6,"name":"Lunch","key_string":"lunch","icon_key":"lunch","active_flag":true,"is_custom_flag":false,"add_time":"2020-12-10 07:23:48"},"emitted_at":1733742439922} +{"stream":"activity_types","data":{"id":7,"order_nr":7,"name":"Test 1","key_string":"test_1","icon_key":"car","active_flag":true,"is_custom_flag":true,"add_time":"2023-02-22 11:13:54","update_time":"2023-02-22 11:13:54"},"emitted_at":1733742439922} +{"stream":"leads","data":{"id":"56b65210-b28f-11ed-8345-ef71fee43bbf","title":"Test Organization 6 lead","owner_id":11884360,"creator_id":11884360,"label_ids":["aecece60-c069-11eb-93bf-b59c4f1731e6"],"value":{"amount":800,"currency":"USD"},"expected_close_date":"2023-03-30","person_id":7,"organization_id":6,"is_archived":false,"source_name":"Manually created","origin":"ManuallyCreated","was_seen":true,"next_activity_id":30,"add_time":"2023-02-22T09:00:22.321Z","update_time":"2023-02-22T11:48:49.834Z","visible_to":"3","cc_email":"airbyte-sandbox+7780468+lead54t3wth3rdv6nou8zygue80qn@pipedrivemail.com"},"emitted_at":1733742439928} +{"stream":"leads","data":{"id":"11761620-b29b-11ed-83bc-c5d5bb21e359","title":"Test Organization 8 lead","owner_id":11884360,"creator_id":11884360,"label_ids":["aecece61-c069-11eb-93bf-b59c4f1731e6"],"value":{"amount":3000,"currency":"USD"},"expected_close_date":"2023-04-28","person_id":9,"organization_id":8,"is_archived":false,"source_name":"Manually created","origin":"ManuallyCreated","was_seen":true,"next_activity_id":31,"add_time":"2023-02-22T10:24:20.098Z","update_time":"2023-02-22T11:49:10.328Z","visible_to":"3","cc_email":"airbyte-sandbox+7780468+lead117qmm8o4y5irltqaigfmfdcp@pipedrivemail.com"},"emitted_at":1733742439928} +{"stream":"leads","data":{"id":"98b9c5a0-b29b-11ed-83b4-fd61bd275e86","title":"Test Organization 10 lead","owner_id":11884360,"creator_id":11884360,"label_ids":["aecece60-c069-11eb-93bf-b59c4f1731e6"],"value":{"amount":2000,"currency":"USD"},"expected_close_date":"2023-05-30","person_id":11,"organization_id":10,"is_archived":false,"source_name":"Manually created","origin":"ManuallyCreated","was_seen":true,"next_activity_id":32,"add_time":"2023-02-22T10:28:07.034Z","update_time":"2023-02-22T11:49:24.853Z","visible_to":"3","cc_email":"airbyte-sandbox+7780468+lead91i2xdc9n1af14fee3k0llapy@pipedrivemail.com"},"emitted_at":1733742439928} +{"stream":"organizations","data":{"id":12,"company_id":7780468,"owner_id":{"id":11884360,"name":"Team Airbyte","email":"integration-test@airbyte.io","has_pic":0,"pic_hash":null,"active_flag":true,"value":11884360},"name":"Test Organization 7","open_deals_count":0,"related_open_deals_count":0,"closed_deals_count":0,"related_closed_deals_count":0,"email_messages_count":0,"people_count":0,"activities_count":0,"done_activities_count":0,"undone_activities_count":0,"files_count":0,"notes_count":0,"followers_count":1,"won_deals_count":0,"related_won_deals_count":0,"lost_deals_count":0,"related_lost_deals_count":0,"active_flag":true,"first_char":"t","update_time":"2023-02-22 08:21:58","add_time":"2023-02-22 08:18:16","visible_to":"3","label":5,"label_ids":[5],"address":"DY Patil College, Sant Tukaram Nagar, Pimpri Colony, Pimpri-Chinchwad, Maharashtra, India","address_subpremise":"","address_street_number":"","address_route":"","address_sublocality":"Pimpri Colony","address_locality":"Pimpri-Chinchwad","address_admin_area_level_1":"Maharashtra","address_admin_area_level_2":"Pune Division","address_country":"India","address_postal_code":"411018","address_formatted_address":"DY Patil College, DR. D Y PATIL MEDICAL COLLEGE, Sant Tukaram Nagar, Pimpri Colony, Pimpri-Chinchwad, Maharashtra 411018, India","owner_name":"Team Airbyte","cc_email":"airbyte-sandbox@pipedrivemail.com"},"emitted_at":1733742440202} +{"stream":"organizations","data":{"id":13,"company_id":7780468,"owner_id":{"id":11884360,"name":"Team Airbyte","email":"integration-test@airbyte.io","has_pic":0,"pic_hash":null,"active_flag":true,"value":11884360},"name":"Test Organization 6","open_deals_count":0,"related_open_deals_count":0,"closed_deals_count":0,"related_closed_deals_count":0,"email_messages_count":0,"people_count":0,"activities_count":0,"done_activities_count":0,"undone_activities_count":0,"files_count":0,"notes_count":0,"followers_count":1,"won_deals_count":0,"related_won_deals_count":0,"lost_deals_count":0,"related_lost_deals_count":0,"active_flag":true,"first_char":"t","update_time":"2023-02-22 08:23:17","add_time":"2023-02-22 08:18:33","visible_to":"3","label":5,"label_ids":[5],"address":"Anand Vihar Railway Station, Block D, Anand Vihar, Delhi, Uttar Pradesh, India","address_subpremise":"","address_street_number":"","address_route":"","address_sublocality":"Anand Vihar","address_locality":"Delhi","address_admin_area_level_1":"Uttar Pradesh","address_admin_area_level_2":"Delhi Division","address_country":"India","address_postal_code":"261205","address_formatted_address":"J8X8+F33, Block D, Anand Vihar, Delhi, Uttar Pradesh 261205, India","owner_name":"Team Airbyte","cc_email":"airbyte-sandbox@pipedrivemail.com"},"emitted_at":1733742440202} +{"stream":"organizations","data":{"id":14,"company_id":7780468,"owner_id":{"id":11884360,"name":"Team Airbyte","email":"integration-test@airbyte.io","has_pic":0,"pic_hash":null,"active_flag":true,"value":11884360},"name":"Test Organization 8","open_deals_count":1,"related_open_deals_count":0,"closed_deals_count":0,"related_closed_deals_count":0,"email_messages_count":0,"people_count":1,"activities_count":0,"done_activities_count":0,"undone_activities_count":0,"files_count":0,"notes_count":0,"followers_count":1,"won_deals_count":0,"related_won_deals_count":0,"lost_deals_count":0,"related_lost_deals_count":0,"active_flag":true,"first_char":"t","update_time":"2023-10-13 13:25:00","add_time":"2023-02-22 08:18:50","visible_to":"3","label":5,"label_ids":[5],"address":"London Eye, London, UK","address_subpremise":"Riverside Building","address_street_number":"","address_route":"","address_sublocality":"","address_locality":"","address_admin_area_level_1":"","address_admin_area_level_2":"Greater London","address_country":"United Kingdom","address_postal_code":"SE1 7PB","address_formatted_address":"Riverside Building, County Hall, London SE1 7PB, UK","owner_name":"Team Airbyte","16a9e1fcbccc7f7a5f429a1840c9f66db9ee901a":"My Custom Field Value","cc_email":"airbyte-sandbox@pipedrivemail.com"},"emitted_at":1733742440202} +{"stream":"organization_fields","data":{"key":"address_formatted_address","name":"Full/combined address of Address","field_type":"varchar","edit_flag":false,"active_flag":true,"is_subfield":true,"mandatory_flag":false,"parent_id":4021,"id_suffix":"formatted_address"},"emitted_at":1733742440211} +{"stream":"organization_fields","data":{"id":4023,"key":"label_ids","name":"Labels","order_nr":0,"field_type":"set","json_column_flag":false,"add_time":"2024-04-29 09:28:14","edit_flag":false,"details_visible_flag":true,"add_visible_flag":true,"important_flag":true,"bulk_edit_allowed":true,"filtering_allowed":true,"sortable_flag":true,"mandatory_flag":false,"searchable_flag":false,"active_flag":true,"options":[{"id":5,"label":"Customer","color":"green"},{"id":6,"label":"Hot lead","color":"red"},{"id":7,"label":"Warm lead","color":"yellow"},{"id":8,"label":"Cold lead","color":"blue"}]},"emitted_at":1733742440211} +{"stream":"organization_fields","data":{"id":4022,"key":"16a9e1fcbccc7f7a5f429a1840c9f66db9ee901a","name":"Pipedrive Custom Fields","order_nr":1,"field_type":"varchar","json_column_flag":true,"add_time":"2023-10-13 13:23:22","update_time":"2023-10-13 13:23:22","last_updated_by_user_id":11884360,"edit_flag":true,"details_visible_flag":true,"add_visible_flag":true,"important_flag":false,"bulk_edit_allowed":true,"filtering_allowed":true,"sortable_flag":true,"mandatory_flag":false,"searchable_flag":true,"active_flag":true},"emitted_at":1733742440211} +{"stream":"permission_sets","data":{"id":"fa17fff0-db56-11ec-93f1-e9cfc58fcd59","name":"Global admin","assignment_count":1,"app":"global","type":"admin"},"emitted_at":1733742440211} +{"stream":"permission_sets","data":{"id":"fa287ab0-db56-11ec-93f1-e9cfc58fcd59","name":"Global regular user","assignment_count":4,"app":"global","type":"regular"},"emitted_at":1733742440211} +{"stream":"permission_sets","data":{"id":"57b60400-ed6c-11ec-88fb-4fe88bf2db36","name":"Account settings","assignment_count":1,"app":"account_settings","type":"admin"},"emitted_at":1733742440211} +{"stream":"person_fields","data":{"id":9065,"key":"last_name","name":"Last name","order_nr":0,"field_type":"varchar","json_column_flag":false,"add_time":"2020-12-10 07:23:49","update_time":"2023-07-20 09:24:05","last_updated_by_user_id":0,"edit_flag":false,"details_visible_flag":true,"add_visible_flag":false,"important_flag":true,"bulk_edit_allowed":true,"filtering_allowed":true,"sortable_flag":true,"mandatory_flag":false,"searchable_flag":false,"active_flag":true},"emitted_at":1733742440213} +{"stream":"person_fields","data":{"id":9067,"key":"label_ids","name":"Labels","order_nr":0,"field_type":"set","json_column_flag":false,"add_time":"2024-04-29 09:28:14","edit_flag":false,"details_visible_flag":true,"add_visible_flag":true,"important_flag":true,"bulk_edit_allowed":true,"filtering_allowed":true,"sortable_flag":true,"mandatory_flag":false,"searchable_flag":false,"active_flag":true,"options":[{"id":1,"label":"Customer","color":"green"},{"id":2,"label":"Hot lead","color":"red"},{"id":3,"label":"Warm lead","color":"yellow"},{"id":4,"label":"Cold lead","color":"blue"}]},"emitted_at":1733742440213} +{"stream":"person_fields","data":{"id":9066,"key":"aa02d059909fdc632d590bd578d7b3baf4bf9780","name":"Custom Field 1","order_nr":1,"field_type":"varchar","json_column_flag":true,"add_time":"2023-07-12 17:53:46","update_time":"2023-07-12 17:53:46","last_updated_by_user_id":11884360,"edit_flag":true,"details_visible_flag":true,"add_visible_flag":false,"important_flag":false,"bulk_edit_allowed":true,"filtering_allowed":true,"sortable_flag":true,"mandatory_flag":false,"searchable_flag":true,"active_flag":true},"emitted_at":1733742440213} +{"stream":"currencies","data":{"id":166,"code":"ZMK","name":"Zambian Kwacha","symbol":"ZMK","decimal_points":2,"active_flag":true,"is_custom_flag":false},"emitted_at":1733742440218} +{"stream":"currencies","data":{"id":201,"code":"ZMW","name":"Zambian Kwacha","symbol":"ZMW","decimal_points":2,"active_flag":true,"is_custom_flag":false},"emitted_at":1733742440218} +{"stream":"currencies","data":{"id":167,"code":"ZWL","name":"Zimbabwe Dollar","symbol":"ZWL","decimal_points":2,"active_flag":true,"is_custom_flag":false},"emitted_at":1733742440219} +{"stream":"roles","data":{"id":1,"name":"(Unassigned users)","active_flag":true,"assignment_count":"5","sub_role_count":"0","level":1,"description":"This is the default group for managing your visibility settings. New users are added automatically unless you change their group when you invite them."},"emitted_at":1733742444262} +{"stream":"product_fields","data":{"id":26,"key":"category","name":"Category","order_nr":0,"field_type":"enum","json_column_flag":false,"add_time":"2020-12-10 07:23:48","update_time":"2023-07-20 09:24:08","last_updated_by_user_id":11884360,"edit_flag":false,"details_visible_flag":true,"add_visible_flag":true,"important_flag":true,"bulk_edit_allowed":true,"filtering_allowed":true,"sortable_flag":true,"mandatory_flag":false,"searchable_flag":false,"active_flag":true,"options":[{"id":12,"label":"Food"}]},"emitted_at":1733742444467} +{"stream":"product_fields","data":{"id":27,"key":"description","name":"Description","order_nr":0,"field_type":"text","json_column_flag":false,"add_time":"2020-12-10 07:23:48","update_time":"2023-07-20 09:24:08","last_updated_by_user_id":0,"edit_flag":false,"details_visible_flag":true,"add_visible_flag":false,"important_flag":true,"bulk_edit_allowed":true,"filtering_allowed":true,"sortable_flag":true,"mandatory_flag":false,"searchable_flag":false,"active_flag":true},"emitted_at":1733742444468} +{"stream":"product_fields","data":{"id":28,"key":"unit_prices","name":"Unit prices","order_nr":0,"field_type":"double","json_column_flag":false,"add_time":"2020-12-10 07:23:48","update_time":"2023-09-21 07:51:19","last_updated_by_user_id":0,"edit_flag":false,"details_visible_flag":false,"add_visible_flag":true,"important_flag":true,"bulk_edit_allowed":false,"filtering_allowed":true,"sortable_flag":true,"mandatory_flag":true,"searchable_flag":false,"active_flag":true},"emitted_at":1733742444468} diff --git a/airbyte-integrations/connectors/source-pipedrive/main.py b/airbyte-integrations/connectors/source-pipedrive/main.py index 64fe456c34fd..4b1f33f52ccc 100644 --- a/airbyte-integrations/connectors/source-pipedrive/main.py +++ b/airbyte-integrations/connectors/source-pipedrive/main.py @@ -4,5 +4,6 @@ from source_pipedrive.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-pipedrive/metadata.yaml b/airbyte-integrations/connectors/source-pipedrive/metadata.yaml index 40d2742ad7e0..8ec8b9651ca5 100644 --- a/airbyte-integrations/connectors/source-pipedrive/metadata.yaml +++ b/airbyte-integrations/connectors/source-pipedrive/metadata.yaml @@ -17,7 +17,7 @@ data: connectorSubtype: api connectorType: source definitionId: d8286229-c680-4063-8c59-23b9b391c700 - dockerImageTag: 2.2.25 + dockerImageTag: 2.3.2 dockerRepository: airbyte/source-pipedrive documentationUrl: https://docs.airbyte.com/integrations/sources/pipedrive githubIssueLabel: source-pipedrive @@ -63,5 +63,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-pipedrive/poetry.lock b/airbyte-integrations/connectors/source-pipedrive/poetry.lock index 6b6708a000d6..dd59697e650a 100644 --- a/airbyte-integrations/connectors/source-pipedrive/poetry.lock +++ b/airbyte-integrations/connectors/source-pipedrive/poetry.lock @@ -2,78 +2,96 @@ [[package]] name = "airbyte-cdk" -version = "0.90.0" +version = "6.12.4" description = "A framework for writing Airbyte Connectors." optional = false -python-versions = "<4.0,>=3.9" +python-versions = "<3.13,>=3.10" files = [ - {file = "airbyte_cdk-0.90.0-py3-none-any.whl", hash = "sha256:bd0aa5843cdc4901f2e482f0e86695ca4e6db83b65c5017799255dd20535cf56"}, - {file = "airbyte_cdk-0.90.0.tar.gz", hash = "sha256:25cefc010718bada5cce3f87e7ae93068630732c0d34ce5145f8ddf7457d4d3c"}, + {file = "airbyte_cdk-6.12.4-py3-none-any.whl", hash = "sha256:903f2c2d3be4d6595bc6c50a4625e2551308d2ca90e021bf489e0a82cf0f965d"}, + {file = "airbyte_cdk-6.12.4.tar.gz", hash = "sha256:f9f39746dec5e01a9d37255cfb45a753953227b7aafebf8f5603a6e9f943b182"}, ] [package.dependencies] -airbyte-protocol-models = ">=0.9.0,<1.0" +airbyte-protocol-models-dataclasses = ">=0.14,<0.15" backoff = "*" cachetools = "*" -cryptography = ">=42.0.5,<43.0.0" -Deprecated = ">=1.2,<1.3" -dpath = ">=2.0.1,<2.1.0" -genson = "1.2.2" +cryptography = ">=42.0.5,<44.0.0" +dpath = ">=2.1.6,<3.0.0" +dunamai = ">=1.22.0,<2.0.0" +genson = "1.3.0" isodate = ">=0.6.1,<0.7.0" Jinja2 = ">=3.1.2,<3.2.0" jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" +jsonschema = ">=4.17.3,<4.18.0" langchain_core = "0.1.42" +nltk = "3.9.1" +numpy = "<2" +orjson = ">=3.10.7,<4.0.0" +pandas = "2.2.2" pendulum = "<3.0.0" -pydantic = ">=1.10.8,<2.0.0" +psutil = "6.1.0" +pydantic = ">=2.7,<3.0" pyjwt = ">=2.8.0,<3.0.0" pyrate-limiter = ">=3.1.0,<3.2.0" python-dateutil = "*" -pytz = "2024.1" +python-ulid = ">=3.0.0,<4.0.0" +pytz = "2024.2" PyYAML = ">=6.0.1,<7.0.0" +rapidfuzz = ">=3.10.1,<4.0.0" requests = "*" requests_cache = "*" -wcmatch = "8.4" +serpyco-rs = ">=1.10.2,<2.0.0" +Unidecode = ">=1.3,<2.0" +wcmatch = "10.0" +xmltodict = ">=0.13.0,<0.14.0" [package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] +file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "python-snappy (==0.7.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] +sql = ["sqlalchemy (>=2.0,!=2.0.36,<3.0)"] +vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.8.0)"] [[package]] -name = "airbyte-protocol-models" -version = "0.13.0" -description = "Declares the Airbyte Protocol." +name = "airbyte-protocol-models-dataclasses" +version = "0.14.1" +description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models_dataclasses-0.14.1-py3-none-any.whl", hash = "sha256:dfe10b32ee09e6ba9b4f17bd309e841b61cbd61ec8f80b1937ff104efd6209a9"}, + {file = "airbyte_protocol_models_dataclasses-0.14.1.tar.gz", hash = "sha256:f62a46556b82ea0d55de144983141639e8049d836dd4e0a9d7234c5b2e103c08"}, ] -[package.dependencies] -pydantic = ">=1.9.2,<2.0.0" +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -86,21 +104,32 @@ files = [ {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, ] +[[package]] +name = "attributes-doc" +version = "0.4.0" +description = "PEP 224 implementation" +optional = false +python-versions = ">=3.8" +files = [ + {file = "attributes-doc-0.4.0.tar.gz", hash = "sha256:b1576c94a714e9fc2c65c47cf10d0c8e1a5f7c4f5ae7f69006be108d95cbfbfb"}, + {file = "attributes_doc-0.4.0-py2.py3-none-any.whl", hash = "sha256:4c3007d9e58f3a6cb4b9c614c4d4ce2d92161581f28e594ddd8241cc3a113bdd"}, +] + [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -166,13 +195,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -256,118 +285,119 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, +] + +[[package]] +name = "click" +version = "8.1.8" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + [[package]] name = "colorama" version = "0.4.6" @@ -381,43 +411,38 @@ files = [ [[package]] name = "cryptography" -version = "42.0.8" +version = "43.0.3" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, + {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, + {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, + {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, + {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, + {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, + {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, + {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, ] [package.dependencies] @@ -430,37 +455,34 @@ nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] [[package]] -name = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." +name = "dpath" +version = "2.2.0" +description = "Filesystem-like pathing and searching for dictionaries" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "dpath-2.2.0-py3-none-any.whl", hash = "sha256:b330a375ded0a0d2ed404440f6c6a715deae5313af40bbb01c8a41d891900576"}, + {file = "dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e"}, ] -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - [[package]] -name = "dpath" -version = "2.0.8" -description = "Filesystem-like pathing and searching for dictionaries" +name = "dunamai" +version = "1.23.0" +description = "Dynamic version generation" optional = false -python-versions = ">=3.7" +python-versions = ">=3.5" files = [ - {file = "dpath-2.0.8-py3-none-any.whl", hash = "sha256:f92f595214dd93a00558d75d4b858beee519f4cffca87f02616ad6cd013f3436"}, - {file = "dpath-2.0.8.tar.gz", hash = "sha256:a3440157ebe80d0a3ad794f1b61c571bef125214800ffdb9afc9424e8250fe9b"}, + {file = "dunamai-1.23.0-py3-none-any.whl", hash = "sha256:a0906d876e92441793c6a423e16a4802752e723e9c9a5aabdc5535df02dbe041"}, + {file = "dunamai-1.23.0.tar.gz", hash = "sha256:a163746de7ea5acb6dacdab3a6ad621ebc612ed1e528aaa8beedb8887fccd2c4"}, ] +[package.dependencies] +packaging = ">=20.9" + [[package]] name = "exceptiongroup" version = "1.2.2" @@ -477,12 +499,13 @@ test = ["pytest (>=6)"] [[package]] name = "genson" -version = "1.2.2" +version = "1.3.0" description = "GenSON is a powerful, user-friendly JSON Schema generator." optional = false python-versions = "*" files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, + {file = "genson-1.3.0-py3-none-any.whl", hash = "sha256:468feccd00274cc7e4c09e84b08704270ba8d95232aa280f65b986139cec67f7"}, + {file = "genson-1.3.0.tar.gz", hash = "sha256:e02db9ac2e3fd29e65b5286f7135762e2cd8a986537c075b06fc5f1517308e37"}, ] [[package]] @@ -498,13 +521,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -519,13 +542,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -533,7 +556,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -583,13 +605,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -598,6 +620,17 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "joblib" +version = "1.4.2" +description = "Lightweight pipelining with Python functions" +optional = false +python-versions = ">=3.8" +files = [ + {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, + {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, +] + [[package]] name = "jsonpatch" version = "1.33" @@ -636,24 +669,22 @@ files = [ [[package]] name = "jsonschema" -version = "3.2.0" +version = "4.17.3" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, ] [package.dependencies] attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" [package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] [[package]] name = "langchain-core" @@ -679,22 +710,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -765,71 +799,158 @@ files = [ {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] +[[package]] +name = "nltk" +version = "3.9.1" +description = "Natural Language Toolkit" +optional = false +python-versions = ">=3.8" +files = [ + {file = "nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1"}, + {file = "nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868"}, +] + +[package.dependencies] +click = "*" +joblib = "*" +regex = ">=2021.8.3" +tqdm = "*" + +[package.extras] +all = ["matplotlib", "numpy", "pyparsing", "python-crfsuite", "requests", "scikit-learn", "scipy", "twython"] +corenlp = ["requests"] +machine-learning = ["numpy", "python-crfsuite", "scikit-learn", "scipy"] +plot = ["matplotlib"] +tgrep = ["pyparsing"] +twitter = ["twython"] + +[[package]] +name = "numpy" +version = "1.26.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, +] + [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -843,6 +964,78 @@ files = [ {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] +[[package]] +name = "pandas" +version = "2.2.2" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + [[package]] name = "pendulum" version = "2.1.2" @@ -908,6 +1101,36 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "psutil" +version = "6.1.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, +] + +[package.extras] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + [[package]] name = "py" version = "1.11.0" @@ -932,72 +1155,145 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" -description = "Data validation and settings management using python type hints" +version = "2.10.4" +description = "Data validation using Python type hints" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] -typing-extensions = ">=4.2.0" +annotated-types = ">=0.6.0" +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] +email = ["email-validator (>=2.0.0)"] +timezone = ["tzdata"] + +[[package]] +name = "pydantic-core" +version = "2.27.2" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1117,15 +1413,29 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "python-ulid" +version = "3.0.0" +description = "Universally unique lexicographically sortable identifier" +optional = false +python-versions = ">=3.9" +files = [ + {file = "python_ulid-3.0.0-py3-none-any.whl", hash = "sha256:e4c4942ff50dbd79167ad01ac725ec58f924b4018025ce22c858bfcff99a5e31"}, + {file = "python_ulid-3.0.0.tar.gz", hash = "sha256:e50296a47dc8209d28629a22fc81ca26c00982c78934bd7766377ba37ea49a9f"}, +] + +[package.extras] +pydantic = ["pydantic (>=2.0)"] + [[package]] name = "pytz" -version = "2024.1" +version = "2024.2" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, + {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, + {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, ] [[package]] @@ -1201,6 +1511,209 @@ files = [ {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] +[[package]] +name = "rapidfuzz" +version = "3.11.0" +description = "rapid fuzzy string matching" +optional = false +python-versions = ">=3.9" +files = [ + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eb8a54543d16ab1b69e2c5ed96cabbff16db044a50eddfc028000138ca9ddf33"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:231c8b2efbd7f8d2ecd1ae900363ba168b8870644bb8f2b5aa96e4a7573bde19"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54e7f442fb9cca81e9df32333fb075ef729052bcabe05b0afc0441f462299114"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:906f1f2a1b91c06599b3dd1be207449c5d4fc7bd1e1fa2f6aef161ea6223f165"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed59044aea9eb6c663112170f2399b040d5d7b162828b141f2673e822093fa8"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cb1965a28b0fa64abdee130c788a0bc0bb3cf9ef7e3a70bf055c086c14a3d7e"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b488b244931d0291412917e6e46ee9f6a14376625e150056fe7c4426ef28225"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f0ba13557fec9d5ffc0a22826754a7457cc77f1b25145be10b7bb1d143ce84c6"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3871fa7dfcef00bad3c7e8ae8d8fd58089bad6fb21f608d2bf42832267ca9663"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b2669eafee38c5884a6e7cc9769d25c19428549dcdf57de8541cf9e82822e7db"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ffa1bb0e26297b0f22881b219ffc82a33a3c84ce6174a9d69406239b14575bd5"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:45b15b8a118856ac9caac6877f70f38b8a0d310475d50bc814698659eabc1cdb"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win32.whl", hash = "sha256:22033677982b9c4c49676f215b794b0404073f8974f98739cb7234e4a9ade9ad"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:be15496e7244361ff0efcd86e52559bacda9cd975eccf19426a0025f9547c792"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_arm64.whl", hash = "sha256:714a7ba31ba46b64d30fccfe95f8013ea41a2e6237ba11a805a27cdd3bce2573"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8724a978f8af7059c5323d523870bf272a097478e1471295511cf58b2642ff83"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b63cb1f2eb371ef20fb155e95efd96e060147bdd4ab9fc400c97325dfee9fe1"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82497f244aac10b20710448645f347d862364cc4f7d8b9ba14bd66b5ce4dec18"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:339607394941801e6e3f6c1ecd413a36e18454e7136ed1161388de674f47f9d9"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84819390a36d6166cec706b9d8f0941f115f700b7faecab5a7e22fc367408bc3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eea8d9e20632d68f653455265b18c35f90965e26f30d4d92f831899d6682149b"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b659e1e2ea2784a9a397075a7fc395bfa4fe66424042161c4bcaf6e4f637b38"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1315cd2a351144572e31fe3df68340d4b83ddec0af8b2e207cd32930c6acd037"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a7743cca45b4684c54407e8638f6d07b910d8d811347b9d42ff21262c7c23245"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:5bb636b0150daa6d3331b738f7c0f8b25eadc47f04a40e5c23c4bfb4c4e20ae3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:42f4dd264ada7a9aa0805ea0da776dc063533917773cf2df5217f14eb4429eae"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:51f24cb39e64256221e6952f22545b8ce21cacd59c0d3e367225da8fc4b868d8"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win32.whl", hash = "sha256:aaf391fb6715866bc14681c76dc0308f46877f7c06f61d62cc993b79fc3c4a2a"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:ebadd5b8624d8ad503e505a99b8eb26fe3ea9f8e9c2234e805a27b269e585842"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:d895998fec712544c13cfe833890e0226585cf0391dd3948412441d5d68a2b8c"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f382fec4a7891d66fb7163c90754454030bb9200a13f82ee7860b6359f3f2fa8"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dfaefe08af2a928e72344c800dcbaf6508e86a4ed481e28355e8d4b6a6a5230e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92ebb7c12f682b5906ed98429f48a3dd80dd0f9721de30c97a01473d1a346576"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a1b3ebc62d4bcdfdeba110944a25ab40916d5383c5e57e7c4a8dc0b6c17211a"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c6d7fea39cb33e71de86397d38bf7ff1a6273e40367f31d05761662ffda49e4"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99aebef8268f2bc0b445b5640fd3312e080bd17efd3fbae4486b20ac00466308"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4469307f464ae3089acf3210b8fc279110d26d10f79e576f385a98f4429f7d97"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:eb97c53112b593f89a90b4f6218635a9d1eea1d7f9521a3b7d24864228bbc0aa"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef8937dae823b889c0273dfa0f0f6c46a3658ac0d851349c464d1b00e7ff4252"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d95f9e9f3777b96241d8a00d6377cc9c716981d828b5091082d0fe3a2924b43e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:b1d67d67f89e4e013a5295e7523bc34a7a96f2dba5dd812c7c8cb65d113cbf28"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d994cf27e2f874069884d9bddf0864f9b90ad201fcc9cb2f5b82bacc17c8d5f2"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win32.whl", hash = "sha256:ba26d87fe7fcb56c4a53b549a9e0e9143f6b0df56d35fe6ad800c902447acd5b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:b1f7efdd7b7adb32102c2fa481ad6f11923e2deb191f651274be559d56fc913b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:ed78c8e94f57b44292c1a0350f580e18d3a3c5c0800e253f1583580c1b417ad2"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e60814edd0c9b511b5f377d48b9782b88cfe8be07a98f99973669299c8bb318a"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f28952da055dbfe75828891cd3c9abf0984edc8640573c18b48c14c68ca5e06"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e8f93bc736020351a6f8e71666e1f486bb8bd5ce8112c443a30c77bfde0eb68"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76a4a11ba8f678c9e5876a7d465ab86def047a4fcc043617578368755d63a1bc"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc0e0d41ad8a056a9886bac91ff9d9978e54a244deb61c2972cc76b66752de9c"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e8ea35f2419c7d56b3e75fbde2698766daedb374f20eea28ac9b1f668ef4f74"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd340bbd025302276b5aa221dccfe43040c7babfc32f107c36ad783f2ffd8775"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:494eef2c68305ab75139034ea25328a04a548d297712d9cf887bf27c158c388b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5a167344c1d6db06915fb0225592afdc24d8bafaaf02de07d4788ddd37f4bc2f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8c7af25bda96ac799378ac8aba54a8ece732835c7b74cfc201b688a87ed11152"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d2a0f7e17f33e7890257367a1662b05fecaf56625f7dbb6446227aaa2b86448b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4d0d26c7172bdb64f86ee0765c5b26ea1dc45c52389175888ec073b9b28f4305"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win32.whl", hash = "sha256:6ad02bab756751c90fa27f3069d7b12146613061341459abf55f8190d899649f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:b1472986fd9c5d318399a01a0881f4a0bf4950264131bb8e2deba9df6d8c362b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:c408f09649cbff8da76f8d3ad878b64ba7f7abdad1471efb293d2c075e80c822"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1bac4873f6186f5233b0084b266bfb459e997f4c21fc9f029918f44a9eccd304"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f9f12c2d0aa52b86206d2059916153876a9b1cf9dfb3cf2f344913167f1c3d4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd501de6f7a8f83557d20613b58734d1cb5f0be78d794cde64fe43cfc63f5f2"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4416ca69af933d4a8ad30910149d3db6d084781d5c5fdedb713205389f535385"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f0821b9bdf18c5b7d51722b906b233a39b17f602501a966cfbd9b285f8ab83cd"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0edecc3f90c2653298d380f6ea73b536944b767520c2179ec5d40b9145e47aa"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4513dd01cee11e354c31b75f652d4d466c9440b6859f84e600bdebfccb17735a"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d9727b85511b912571a76ce53c7640ba2c44c364e71cef6d7359b5412739c570"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ab9eab33ee3213f7751dc07a1a61b8d9a3d748ca4458fffddd9defa6f0493c16"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:6b01c1ddbb054283797967ddc5433d5c108d680e8fa2684cf368be05407b07e4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:3857e335f97058c4b46fa39ca831290b70de554a5c5af0323d2f163b19c5f2a6"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d98a46cf07c0c875d27e8a7ed50f304d83063e49b9ab63f21c19c154b4c0d08d"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win32.whl", hash = "sha256:c36539ed2c0173b053dafb221458812e178cfa3224ade0960599bec194637048"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:ec8d7d8567e14af34a7911c98f5ac74a3d4a743cd848643341fc92b12b3784ff"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_arm64.whl", hash = "sha256:62171b270ecc4071be1c1f99960317db261d4c8c83c169e7f8ad119211fe7397"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f06e3c4c0a8badfc4910b9fd15beb1ad8f3b8fafa8ea82c023e5e607b66a78e4"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fe7aaf5a54821d340d21412f7f6e6272a9b17a0cbafc1d68f77f2fc11009dcd5"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25398d9ac7294e99876a3027ffc52c6bebeb2d702b1895af6ae9c541ee676702"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a52eea839e4bdc72c5e60a444d26004da00bb5bc6301e99b3dde18212e41465"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c87319b0ab9d269ab84f6453601fd49b35d9e4a601bbaef43743f26fabf496c"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3048c6ed29d693fba7d2a7caf165f5e0bb2b9743a0989012a98a47b975355cca"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b04f29735bad9f06bb731c214f27253bd8bedb248ef9b8a1b4c5bde65b838454"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7864e80a0d4e23eb6194254a81ee1216abdc53f9dc85b7f4d56668eced022eb8"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3794df87313dfb56fafd679b962e0613c88a293fd9bd5dd5c2793d66bf06a101"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d71da0012face6f45432a11bc59af19e62fac5a41f8ce489e80c0add8153c3d1"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff38378346b7018f42cbc1f6d1d3778e36e16d8595f79a312b31e7c25c50bd08"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6668321f90aa02a5a789d4e16058f2e4f2692c5230252425c3532a8a62bc3424"}, + {file = "rapidfuzz-3.11.0.tar.gz", hash = "sha256:a53ca4d3f52f00b393fab9b5913c5bafb9afc27d030c8a1db1283da6917a860f"}, +] + +[package.extras] +all = ["numpy"] + +[[package]] +name = "regex" +version = "2024.11.6" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.8" +files = [ + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, +] + [[package]] name = "requests" version = "2.32.3" @@ -1267,34 +1780,68 @@ files = [ requests = ">=2.0.1,<3.0.0" [[package]] -name = "setuptools" -version = "75.3.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" +name = "serpyco-rs" +version = "1.11.0" +description = "" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4b2bd933539bd8c84315e2fb5ae52ef7a58ace5a6dfe3f8b73f74dc71216779e"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:627f957889ff73c4d2269fc7b6bba93212381befe03633e7cb5495de66ba9a33"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b0933620abc01434023e0e3e22255b7e4ab9b427b5a9a5ee00834656d792377a"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9ce46683d92e34abb20304817fc5ac6cb141a06fc7468dedb1d8865a8a9682f6"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bda437d86e8859bf91c189c1f4650899822f6d6d7b02b48f5729da904eb7bb7d"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a72bfbd282af17ebe76d122639013e802c09902543fdbbd828fb2159ec9755e"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d4808df5384e3e8581e31a90ba7a1fa501c0837b1f174284bb8a4555b6864ea"}, + {file = "serpyco_rs-1.11.0-cp310-none-win_amd64.whl", hash = "sha256:c7b60aef4c16d68efb0d6241f05d0a434d873d98449cbb4366b0d385f0a7172b"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d47ee577cf4d69b53917615cb031ad8708eb2f59fe78194b1968c13130fc2f7"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6090d9a1487237cdd4e9362a823eede23249602019b917e7bd57846179286e79"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7192eb3df576386fefd595ea31ae25c62522841ffec7e7aeb37a80b55bdc3213"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b52ef8affb7e71b9b98a7d5216d6a7ad03b04e990acb147cd9211c8b931c5487"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3480e09e473560c60e74aaa789e6b4d079637371aae0a98235440111464bbba7"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c92e36b0ab6fe866601c2331f7e99c809a126d21963c03d8a5c29331526deed"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84f497361952d4566bc1f77e9e15a84a2614f593cc671fbf0a0fa80046f9c3d7"}, + {file = "serpyco_rs-1.11.0-cp311-none-win_amd64.whl", hash = "sha256:37fc1cf192bef9784fbf1f4e03cec21750b9e704bef55cc0442f71a715eee920"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3ea93d485f03dc8b0cfb0d477f0ad2e86e78f0461b53010656ab5b4db1b41fb0"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7772410d15694b03f9c5500a2c47d62eed76e191bea4087ad042250346b1a38e"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42118463c1679846cffd2f06f47744c9b9eb33c5d0448afd88ea19e1a81a8ddd"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:79481a455b76cc56021dc55bb6d5bdda1b2b32bcb6a1ee711b597140d112e9b1"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8fd79051f9af9591fc03cf7d3033ff180416301f6a4fd3d1e3d92ebd2d68697"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d29c8f9aeed734a3b51f7349d04ec9063516ffa4e10b632d75e9b1309e4930e4"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15609158b0d9591ffa118302cd9d0039970cb3faf91dce32975f7d276e7411d5"}, + {file = "serpyco_rs-1.11.0-cp312-none-win_amd64.whl", hash = "sha256:00081eae77fbf4c5d88371c5586317ab02ccb293a330b460869a283edf2b7b69"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3028893366a1985adcedb13fa8f6f98c087c185efc427f94c2ccdafa40f45832"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c18bf511316f3abf648a68ee62ef88617bec57d3fcde69466b4361102715ae5"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7dde9ef09cdfaf7c62378186b9e29f54ec76114be4c347be6a06dd559c5681e"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:18500ebc5e75285841e35585a238629a990b709e14f68933233640d15ca17d5f"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47c23132d4e03982703a7630aa09877b41e499722142f76b6153f6619b612f3"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5f8e6ba499f6a0825bee0d8f8764569d367af871b563fc6512c171474e8e5383"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15438a076047c34cff6601a977df54948e8d39d1a86f89d05c48bc60f4c12a61"}, + {file = "serpyco_rs-1.11.0-cp313-none-win_amd64.whl", hash = "sha256:84ee2c109415bd81904fc9abb9aec86a5dd13166808c21142cf23ec639f683bd"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5c97c16c865261577fac4effeccc7ef5e0a1e8e35e7a3ee6c90c77c3a4cd7ff9"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47825e70f86fd6ef7c4a835dea3d6e8eef4fee354ed7b39ced99f31aba74a86e"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24d220220365110edba2f778f41ab3cf396883da0f26e1361a3ada9bd0227f73"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3a46f334af5a9d77acc6e1e58f355ae497900a2798929371f0545e274f6e6166"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d72b748acce4b4e3c7c9724e1eb33d033a1c26b08a698b393e0288060e0901"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2b8b6f205e8cc038d4d30dd0e70eece7bbecc816eb2f3787c330dc2218e232d"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:038d748bfff31f150f0c3edab2766b8843edb952cb1bd3bf547886beb0912dae"}, + {file = "serpyco_rs-1.11.0-cp39-none-win_amd64.whl", hash = "sha256:0fee1c89ec2cb013dc232e4ebef88e2844357ce8631063b56639dbfb83762f20"}, + {file = "serpyco_rs-1.11.0.tar.gz", hash = "sha256:70a844615ffb229e6e89c204b3ab7404aacaf2838911814c7d847969b8da2e3a"}, ] -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +[package.dependencies] +attributes-doc = "*" +typing-extensions = "*" [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1334,6 +1881,27 @@ files = [ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] +[[package]] +name = "tqdm" +version = "4.67.1" +description = "Fast, Extensible Progress Meter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + [[package]] name = "typing-extensions" version = "4.12.2" @@ -1345,6 +1913,28 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] +[[package]] +name = "tzdata" +version = "2024.2" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, + {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, +] + +[[package]] +name = "unidecode" +version = "1.3.8" +description = "ASCII transliterations of Unicode text" +optional = false +python-versions = ">=3.5" +files = [ + {file = "Unidecode-1.3.8-py3-none-any.whl", hash = "sha256:d130a61ce6696f8148a3bd8fe779c99adeb4b870584eeb9526584e9aa091fd39"}, + {file = "Unidecode-1.3.8.tar.gz", hash = "sha256:cfdb349d46ed3873ece4586b96aa75258726e2fa8ec21d6f00a591d98806c2f4"}, +] + [[package]] name = "url-normalize" version = "1.4.3" @@ -1361,13 +1951,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1378,98 +1968,30 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "wcmatch" -version = "8.4" +version = "10.0" description = "Wildcard/glob file name matcher." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, + {file = "wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a"}, + {file = "wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a"}, ] [package.dependencies] bracex = ">=2.1.1" [[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." +name = "xmltodict" +version = "0.13.0" +description = "Makes working with XML feel like you are working with JSON" optional = false -python-versions = ">=3.6" +python-versions = ">=3.4" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "xmltodict-0.13.0-py2.py3-none-any.whl", hash = "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"}, + {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"}, ] [metadata] lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "b45c7da2b07fd3a9a79c2ffac21f4db7af48b0884a6e1c9f41f17035161a5fab" +python-versions = "^3.10,<3.12" +content-hash = "8060c30cd8661d53311681f3681fba0d293f827a08512361393d1721da608a67" diff --git a/airbyte-integrations/connectors/source-pipedrive/pyproject.toml b/airbyte-integrations/connectors/source-pipedrive/pyproject.toml index 01871f4c551a..957ba4e1c19f 100644 --- a/airbyte-integrations/connectors/source-pipedrive/pyproject.toml +++ b/airbyte-integrations/connectors/source-pipedrive/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "2.2.25" +version = "2.3.2" name = "source-pipedrive" description = "Source implementation for Pipedrive." authors = [ "Airbyte ",] @@ -16,8 +16,8 @@ repository = "https://github.com/airbytehq/airbyte" include = "source_pipedrive" [tool.poetry.dependencies] -python = "^3.9,<3.12" -airbyte-cdk = "^0" +python = "^3.10,<3.12" +airbyte-cdk = "^6" [tool.poetry.scripts] source-pipedrive = "source_pipedrive.run:run" diff --git a/airbyte-integrations/connectors/source-pipedrive/source_pipedrive/extractor.py b/airbyte-integrations/connectors/source-pipedrive/source_pipedrive/extractor.py index 961438884da6..2f34fa080e10 100644 --- a/airbyte-integrations/connectors/source-pipedrive/source_pipedrive/extractor.py +++ b/airbyte-integrations/connectors/source-pipedrive/source_pipedrive/extractor.py @@ -5,6 +5,7 @@ from typing import Any, List, Mapping, Union import requests + from airbyte_cdk.sources.declarative.decoders.decoder import Decoder from airbyte_cdk.sources.declarative.decoders.json_decoder import JsonDecoder from airbyte_cdk.sources.declarative.extractors.dpath_extractor import DpathExtractor diff --git a/airbyte-integrations/connectors/source-pipedrive/source_pipedrive/manifest.yaml b/airbyte-integrations/connectors/source-pipedrive/source_pipedrive/manifest.yaml index 8b02277d3d67..a49dd6bd9064 100644 --- a/airbyte-integrations/connectors/source-pipedrive/source_pipedrive/manifest.yaml +++ b/airbyte-integrations/connectors/source-pipedrive/source_pipedrive/manifest.yaml @@ -411,3 +411,46 @@ spec: examples: - "2017-01-25 00:00:00Z" type: string + num_workers: + title: Number of concurrent workers + description: Number of concurrent workers to be used in the sync. This number should be set according to your Pipedrive subscription plan and its rate limits, which coule be found here on Pipedrive Rate limiting page. Please note that Pipedrive API rate limits are reset daily. If you experience rate limiting issues, please lower the number of workers according to your plan. + type: integer + default: 10 + minimum: 1 + maximum: 40 + +# rate limiting https://pipedrive.readme.io/docs/core-api-concepts-rate-limiting + +# Tokens Daily Budget: +# Each company account is allocated a daily API token budget, which is shared among all users within that account. +# This budget is exclusively for API traffic authenticated by API tokens or OAuth tokens, +# and it does not impact actions performed directly within the Pipedrive user interface. +# 30,000 base tokens × subscription plan multiplier × number of seats + +#| Plan | Plan multiplier | +#|:-------------|-----------------| +#| Essential | 1 | +#| Advanced | 2 | +#| Professional | 3 | +#| Power | 5 | +#| Enterprise | 7 | + +# API Requests: + +# Each API request consumes a specific number of tokens, with each API endpoint assigned cost in tokens based on the complexity and resource demand of the endpoint. +# When a request is made, the corresponding token cost is deducted from the company’s daily API budget. +# Lightweight endpoints consume fewer tokens, while more complex or data-intensive endpoints require a higher token cost. + +# | API Endpoint type | Cost in tokens | +# |---------------------------------------------| +# | Get list of entities | 20 | + +# We assume that airbyte users mostly on Essential plan, so they have 30k(Tokens Daily Budget) * 20(Cost in tokens) requests per day, which should be enough with 10 workers. +# If it's not, users can increase/decrease the number of workers. + +# Max value of workers: 40, Min value of workers: 1, Default: 10. + +concurrency_level: + type: ConcurrencyLevel + default_concurrency: "{{ config.get('num_workers', 10)}}" + max_concurrency: 40 diff --git a/airbyte-integrations/connectors/source-pipedrive/source_pipedrive/run.py b/airbyte-integrations/connectors/source-pipedrive/source_pipedrive/run.py index 2ff2b80c12a8..fd9c66cb3824 100644 --- a/airbyte-integrations/connectors/source-pipedrive/source_pipedrive/run.py +++ b/airbyte-integrations/connectors/source-pipedrive/source_pipedrive/run.py @@ -1,14 +1,54 @@ # -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. # - import sys +import traceback +from datetime import datetime +from typing import List -from airbyte_cdk.entrypoint import launch +from orjson import orjson from source_pipedrive import SourcePipedrive +from airbyte_cdk.entrypoint import AirbyteEntrypoint, launch, logger +from airbyte_cdk.exception_handler import init_uncaught_exception_handler +from airbyte_cdk.models import AirbyteErrorTraceMessage, AirbyteMessage, AirbyteMessageSerializer, AirbyteTraceMessage, TraceType, Type + + +def _get_source(args: List[str]): + catalog_path = AirbyteEntrypoint.extract_catalog(args) + config_path = AirbyteEntrypoint.extract_config(args) + state_path = AirbyteEntrypoint.extract_state(args) + try: + return SourcePipedrive( + SourcePipedrive.read_catalog(catalog_path) if catalog_path else None, + SourcePipedrive.read_config(config_path) if config_path else None, + SourcePipedrive.read_state(state_path) if state_path else None, + ) + except Exception as error: + print( + orjson.dumps( + AirbyteMessageSerializer.dump( + AirbyteMessage( + type=Type.TRACE, + trace=AirbyteTraceMessage( + type=TraceType.ERROR, + emitted_at=int(datetime.now().timestamp() * 1000), + error=AirbyteErrorTraceMessage( + message=f"Error starting the sync. This could be due to an invalid configuration or catalog. Please contact Support for assistance. Error: {error}", + stack_trace=traceback.format_exc(), + ), + ), + ) + ) + ).decode() + ) + return None + -def run(): - source = SourcePipedrive() - launch(source, sys.argv[1:]) +def run() -> None: + init_uncaught_exception_handler(logger) + _args = sys.argv[1:] + source = _get_source(_args) + if source: + launch(source, _args) diff --git a/airbyte-integrations/connectors/source-pipedrive/source_pipedrive/source.py b/airbyte-integrations/connectors/source-pipedrive/source_pipedrive/source.py index 32dd3a077d5d..b109d02ac76c 100644 --- a/airbyte-integrations/connectors/source-pipedrive/source_pipedrive/source.py +++ b/airbyte-integrations/connectors/source-pipedrive/source_pipedrive/source.py @@ -1,8 +1,12 @@ # # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # +from typing import Any, Mapping, Optional +from airbyte_cdk.models import ConfiguredAirbyteCatalog from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource +from airbyte_cdk.sources.source import TState + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into @@ -14,5 +18,5 @@ # Declarative Source class SourcePipedrive(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) + def __init__(self, catalog: Optional[ConfiguredAirbyteCatalog], config: Optional[Mapping[str, Any]], state: TState, **kwargs): + super().__init__(catalog=catalog, config=config, state=state, **{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-pipeliner/README.md b/airbyte-integrations/connectors/source-pipeliner/README.md new file mode 100644 index 000000000000..a093775789b0 --- /dev/null +++ b/airbyte-integrations/connectors/source-pipeliner/README.md @@ -0,0 +1,35 @@ +# Pipeliner +This directory contains the manifest-only connector for `source-pipeliner`. + +Pipeliner is a CRM tool. +Using this connector we fetch data from various streams such as contacts , data , leads and quotes. +Docs : https://pipeliner.stoplight.io/docs/api-docs + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-pipeliner:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-pipeliner build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-pipeliner test +``` + diff --git a/airbyte-integrations/connectors/source-pipeliner/acceptance-test-config.yml b/airbyte-integrations/connectors/source-pipeliner/acceptance-test-config.yml new file mode 100644 index 000000000000..5fc754da4152 --- /dev/null +++ b/airbyte-integrations/connectors/source-pipeliner/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-pipeliner:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-pipeliner/icon.svg b/airbyte-integrations/connectors/source-pipeliner/icon.svg new file mode 100644 index 000000000000..73e57042515d --- /dev/null +++ b/airbyte-integrations/connectors/source-pipeliner/icon.svg @@ -0,0 +1 @@ +-icon-color diff --git a/airbyte-integrations/connectors/source-pipeliner/manifest.yaml b/airbyte-integrations/connectors/source-pipeliner/manifest.yaml new file mode 100644 index 000000000000..8d3342e57f85 --- /dev/null +++ b/airbyte-integrations/connectors/source-pipeliner/manifest.yaml @@ -0,0 +1,6091 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Pipeliner is a CRM tool. + + Using this connector we fetch data from various streams such as contacts , + data , leads and quotes. + + Docs : https://pipeliner.stoplight.io/docs/api-docs + +check: + type: CheckStream + stream_names: + - accounts + +definitions: + streams: + accounts: + type: DeclarativeStream + name: accounts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Accounts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounts" + activities: + type: DeclarativeStream + name: activities + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Activities + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/activities" + clients: + type: DeclarativeStream + name: clients + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Clients + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/clients" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + entities: + type: DeclarativeStream + name: entities + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Entities + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/entities" + data: + type: DeclarativeStream + name: data + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Data + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/data" + cloud_objects: + type: DeclarativeStream + name: cloud_objects + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/CloudObjects + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/cloud_objects" + fields: + type: DeclarativeStream + name: fields + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Fields + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/fields" + forecasts: + type: DeclarativeStream + name: forecasts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Forecasts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/forecasts" + form_views: + type: DeclarativeStream + name: form_views + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/FormViews + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/form_views" + entity_scorings: + type: DeclarativeStream + name: entity_scorings + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/EntityScorings + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/entity_scorings" + leads: + type: DeclarativeStream + name: leads + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Leads + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/leads" + lead_oppties: + type: DeclarativeStream + name: lead_oppties + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/LeadOppties + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/lead_oppties" + memos: + type: DeclarativeStream + name: memos + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Memos + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/memos" + notes: + type: DeclarativeStream + name: notes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Notes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/notes" + entity_fitnesses: + type: DeclarativeStream + name: entity_fitnesses + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/EntityFitnesses + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/entity_fitnesses" + pipelines: + type: DeclarativeStream + name: pipelines + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Pipelines + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/pipelines" + products: + type: DeclarativeStream + name: products + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Products + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + oppty_product_relations: + type: DeclarativeStream + name: oppty_product_relations + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/OpptyProductRelations + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/oppty_product_relations" + profiles: + type: DeclarativeStream + name: profiles + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Profiles + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/profiles" + quotes: + type: DeclarativeStream + name: quotes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Quotes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/quotes" + reports: + type: DeclarativeStream + name: reports + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Reports + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/reports" + steps: + type: DeclarativeStream + name: steps + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Steps + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/steps" + tags: + type: DeclarativeStream + name: tags + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: entities/Tags + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: after + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: first + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.page_info.end_cursor }}" + stop_condition: "{{ not response.page_info.has_next_page }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tags" + base_requester: + type: HttpRequester + url_base: >- + https://{{ config['service'] + }}.api.pipelinersales.com/api/v100/rest/spaces/{{ config['spaceid'] }}/ + authenticator: + type: BasicHttpAuthenticator + password: "{{ config[\"password\"] }}" + username: "{{ config[\"username\"] }}" + +streams: + - $ref: "#/definitions/streams/accounts" + - $ref: "#/definitions/streams/activities" + - $ref: "#/definitions/streams/clients" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/entities" + - $ref: "#/definitions/streams/data" + - $ref: "#/definitions/streams/cloud_objects" + - $ref: "#/definitions/streams/fields" + - $ref: "#/definitions/streams/forecasts" + - $ref: "#/definitions/streams/form_views" + - $ref: "#/definitions/streams/entity_scorings" + - $ref: "#/definitions/streams/leads" + - $ref: "#/definitions/streams/lead_oppties" + - $ref: "#/definitions/streams/memos" + - $ref: "#/definitions/streams/notes" + - $ref: "#/definitions/streams/entity_fitnesses" + - $ref: "#/definitions/streams/pipelines" + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/oppty_product_relations" + - $ref: "#/definitions/streams/profiles" + - $ref: "#/definitions/streams/quotes" + - $ref: "#/definitions/streams/reports" + - $ref: "#/definitions/streams/steps" + - $ref: "#/definitions/streams/tags" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - username + - service + - spaceid + properties: + username: + type: string + order: 0 + title: Username + password: + type: string + order: 1 + title: Password + always_show: true + airbyte_secret: true + service: + type: string + enum: + - eu-central + - us-east + - ca-central + - ap-southeast + order: 2 + title: Data Center + spaceid: + type: string + order: 3 + title: Space ID + additionalProperties: true + +metadata: + autoImportSchema: + accounts: true + activities: true + clients: true + contacts: true + entities: true + data: true + cloud_objects: true + fields: true + forecasts: true + form_views: true + entity_scorings: true + leads: true + lead_oppties: true + memos: true + notes: true + entity_fitnesses: true + pipelines: true + products: true + oppty_product_relations: true + profiles: true + quotes: true + reports: true + steps: true + tags: true + testedStreams: + accounts: + streamHash: 6ab8ec476ef56d01c02264ec96a27e40c63906cd + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + activities: + streamHash: 6c22c38ce0651fc3a4fb494eeb9b4a5deae98344 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + clients: + streamHash: d7f078ebd342effe553723ed59738e9feb28312a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contacts: + streamHash: c4119ed4afe702ee0e695a58cf743ae81c468dcc + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + entities: + streamHash: d74086e4537bae1c9ca6cb8319f8843e4999599e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + data: + streamHash: 55f82848cab8951657b5cfb60bd9a8e5f8fe1125 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + cloud_objects: + streamHash: 2381d99248683f4ca86a4a8a0d7998d244fba81c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + fields: + streamHash: 90a35bed39bd52eafb34420840248f8fb0d48b16 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + forecasts: + streamHash: bb5755a564616be24973cc2ba36ce1cc2a79b9d6 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + form_views: + streamHash: a166cdcdf567396ead58d8a3b9c579c5b668c0b0 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + entity_scorings: + streamHash: cf8eb86ff8dc28c2843f564fd9ff0adf5cba89b1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + leads: + streamHash: 04131f5bf9cfafda1a011607abc47c18a6c80dad + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + lead_oppties: + streamHash: e0f8c448daa23fab0bc06b8e335c136e763c9840 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + memos: + streamHash: db68807e8384d83696928f31ef8f79c89e1c7409 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + notes: + streamHash: f87012a0d4f0566df56ae23deea98c8176476583 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + entity_fitnesses: + streamHash: e4e9f3342a71246edc7cd36b711554c16f056ad6 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + pipelines: + streamHash: b9fa3f7934aac48815de30ef3c3c982ae9b0b8b7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + products: + streamHash: abd7be207544b1011c6f5c0d8006066da2633f29 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + oppty_product_relations: + streamHash: 5b248475e04bcbdc79df30042ec5fe168f7e1b96 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + profiles: + streamHash: 3a5c1edbcbe6ca4aaa2f4b5f0b47e363e09c9f3b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + quotes: + hasRecords: true + streamHash: 719daa6b53bc16b1eb48cc67b10cf49b618a4f16 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + reports: + hasRecords: true + streamHash: f3e96474b73105728db63696a4627c8849539f7d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + steps: + hasRecords: true + streamHash: 7140340d07c6a2821ed61666515fc89b9eed8276 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + tags: + hasRecords: true + streamHash: 6e0c5f0c1a5c5184f06dff912e85916a0688f872 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: {} + +schemas: + accounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account_class: + type: + - number + - "null" + account_type: + type: + - string + - "null" + account_type_id: + type: + - string + - "null" + address: + type: + - string + - "null" + city: + type: + - string + - "null" + comments: + type: + - string + - "null" + country: + type: + - string + - "null" + created: + type: + - string + - "null" + currency_exchange_rates_list: + type: + - string + - "null" + currency_exchange_rates_list_id: + type: + - string + - "null" + customer_type: + type: + - string + - "null" + customer_type_id: + type: + - string + - "null" + documents: + type: + - array + - "null" + items: + type: + - string + - "null" + email1: + type: + - string + - "null" + email2: + type: + - string + - "null" + email3: + type: + - string + - "null" + email4: + type: + - string + - "null" + email5: + type: + - string + - "null" + formatted_name: + type: + - string + - "null" + health: + type: + - object + - "null" + properties: + indicators: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + indicator: + type: + - string + - "null" + rule: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + field: + type: + - string + - "null" + id: + type: + - string + - "null" + operator: + type: + - string + - "null" + score: + type: + - number + - "null" + values: + type: + - array + - "null" + items: + type: + - array + - "null" + items: + type: + - number + - string + - "null" + value: + type: + - boolean + - number + - string + - "null" + last_calculation: + type: + - string + - "null" + score: + type: + - number + - "null" + trend: + type: + - string + - "null" + health_category: + type: + - string + - "null" + health_status: + type: + - number + - "null" + home_page: + type: + - string + - "null" + id: + type: string + industry: + type: + - string + - "null" + industry_id: + type: + - string + - "null" + is_archived: + type: + - boolean + - "null" + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + is_favorite: + type: + - boolean + - "null" + is_unsubscribed: + type: + - boolean + - "null" + modified: + type: + - string + - "null" + name: + type: + - string + - "null" + owner: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + phone1: + type: + - string + - "null" + phone2: + type: + - string + - "null" + phone3: + type: + - string + - "null" + phone4: + type: + - string + - "null" + phone5: + type: + - string + - "null" + picture: + type: + - string + - "null" + picture_id: + type: + - string + - "null" + quick_parent_account_name: + type: + - string + - "null" + revision: + type: + - number + - "null" + share_mode: + type: + - number + - "null" + sharing_clients: + type: + - array + - "null" + sharing_units: + type: + - array + - "null" + state_province: + type: + - string + - "null" + tags: + type: + - array + - "null" + unit: + type: + - string + - "null" + unit_id: + type: + - string + - "null" + zip_code: + type: + - string + - "null" + required: + - id + activities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + account_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + activity_type: + type: + - string + - "null" + activity_type_id: + type: + - string + - "null" + call_duration: + type: + - number + - "null" + comments: + type: + - array + - "null" + contact_relations: + type: + - array + - "null" + created: + type: + - string + - "null" + currency_exchange_rates_list: + type: + - string + - "null" + currency_exchange_rates_list_id: + type: + - string + - "null" + custom_entity_relations: + type: + - array + - "null" + documents: + type: + - array + - "null" + due_date: + type: + - string + - "null" + end_date: + type: + - string + - "null" + formatted_name: + type: + - string + - "null" + has_3rd_party_mapping: + type: + - boolean + - "null" + id: + type: string + invitees_can_edit: + type: + - boolean + - "null" + invitees_clients: + type: + - array + - "null" + invitees_contacts: + type: + - array + - "null" + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + is_recurrence_active: + type: + - boolean + - "null" + is_recurrence_exception: + type: + - boolean + - "null" + lead_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + location: + type: + - string + - "null" + modified: + type: + - string + - "null" + opportunity_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + owner: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + priority: + type: + - number + - "null" + project_relations: + type: + - array + - "null" + quote_relations: + type: + - array + - "null" + revision: + type: + - number + - "null" + share_mode: + type: + - number + - "null" + sharing_clients: + type: + - array + - "null" + sharing_units: + type: + - array + - "null" + start_date: + type: + - string + - "null" + status: + type: + - number + - "null" + subject: + type: + - string + - "null" + table_name: + type: + - string + - "null" + unit: + type: + - string + - "null" + unit_id: + type: + - string + - "null" + required: + - id + clients: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + account_favorite: + type: + - array + - "null" + items: + type: + - string + - "null" + appointment_favorite: + type: + - array + - "null" + contact_favorite: + type: + - array + - "null" + items: + type: + - string + - "null" + created: + type: + - string + - "null" + default_unit: + type: + - string + - "null" + default_unit_id: + type: + - string + - "null" + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + formatted_name: + type: + - string + - "null" + id: + type: string + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + last_active: + type: + - string + - "null" + last_name: + type: + - string + - "null" + lead_favorite: + type: + - array + - "null" + master_right: + type: + - string + - "null" + master_right_id: + type: + - string + - "null" + middle_name: + type: + - string + - "null" + modified: + type: + - string + - "null" + name: + type: + - string + - "null" + opportunity_favorite: + type: + - array + - "null" + phone: + type: + - string + - "null" + picture_url: + type: + - string + - "null" + position: + type: + - string + - "null" + profile_favorite: + type: + - array + - "null" + items: + type: + - string + - "null" + region: + type: + - string + - "null" + report_favorite: + type: + - array + - "null" + revision: + type: + - number + - "null" + task_favorite: + type: + - array + - "null" + timezone: + type: + - string + - "null" + unit_manager_ids: + type: + - array + - "null" + items: + type: + - string + - "null" + unit_member_ids: + type: + - array + - "null" + unit_membership: + type: + - array + - "null" + items: + type: + - string + - "null" + user_profile_id: + type: + - number + - "null" + user_recalculation_state: + type: + - string + - "null" + required: + - id + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account_position: + type: + - string + - "null" + account_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + address: + type: + - string + - "null" + city: + type: + - string + - "null" + comments: + type: + - string + - "null" + contact_type: + type: + - string + - "null" + contact_type_id: + type: + - string + - "null" + country: + type: + - string + - "null" + created: + type: + - string + - "null" + currency_exchange_rates_list: + type: + - string + - "null" + currency_exchange_rates_list_id: + type: + - string + - "null" + documents: + type: + - array + - "null" + email1: + type: + - string + - "null" + email2: + type: + - string + - "null" + email3: + type: + - string + - "null" + email4: + type: + - string + - "null" + email5: + type: + - string + - "null" + first_name: + type: + - string + - "null" + formatted_name: + type: + - string + - "null" + gender: + type: + - number + - "null" + id: + type: string + is_archived: + type: + - boolean + - "null" + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + is_favorite: + type: + - boolean + - "null" + is_unsubscribed: + type: + - boolean + - "null" + last_name: + type: + - string + - "null" + middle_name: + type: + - string + - "null" + modified: + type: + - string + - "null" + modified_by_user: + type: + - string + - "null" + owner: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + phone1: + type: + - string + - "null" + phone2: + type: + - string + - "null" + phone3: + type: + - string + - "null" + phone4: + type: + - string + - "null" + phone5: + type: + - string + - "null" + picture: + type: + - string + - "null" + picture_id: + type: + - string + - "null" + position: + type: + - string + - "null" + primary_account: + type: + - string + - "null" + primary_account_account_roles: + type: + - array + - "null" + items: + type: + - string + - "null" + primary_account_position: + type: + - string + - "null" + primary_account_relationship: + type: + - number + - "null" + quick_account_name: + type: + - string + - "null" + revision: + type: + - number + - "null" + share_mode: + type: + - number + - "null" + sharing_clients: + type: + - array + - "null" + sharing_units: + type: + - array + - "null" + state_province: + type: + - string + - "null" + tags: + type: + - array + - "null" + title: + type: + - string + - "null" + unit: + type: + - string + - "null" + unit_id: + type: + - string + - "null" + zip_code: + type: + - string + - "null" + required: + - id + entities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + abstract_entity_id: + type: + - string + - "null" + access_mode: + type: + - number + - "null" + allows_multiple_relation: + type: + - boolean + - "null" + created: + type: + - string + - "null" + default_view_field_id: + type: + - string + - "null" + entity_name: + type: + - string + - "null" + entity_type: + type: + - number + - "null" + has_draft: + type: + - boolean + - "null" + icon: + type: + - number + - "null" + id: + type: string + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + modified: + type: + - string + - "null" + preference_order: + type: + - number + - "null" + table_data_ex: + type: + - string + - "null" + table_ex: + type: + - string + - "null" + table_name: + type: + - string + - "null" + required: + - id + data: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + calc_value: + type: + - number + - "null" + created: + type: + - string + - "null" + data_set_id: + type: + - string + - "null" + has_draft: + type: + - boolean + - "null" + id: + type: string + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + is_published: + type: + - boolean + - "null" + modified: + type: + - string + - "null" + option_name: + type: + - string + - "null" + option_name_translations: + type: + - object + - "null" + revision: + type: + - number + - "null" + sort_order: + type: + - number + - "null" + required: + - id + cloud_objects: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + company_cloud_object_folder: + type: + - string + - "null" + company_cloud_object_folder_id: + type: + - string + - "null" + created: + type: + - string + - "null" + filename: + type: + - string + - "null" + id: + type: string + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + is_public: + type: + - boolean + - "null" + mime_type: + type: + - string + - "null" + modified: + type: + - string + - "null" + params: + type: + - object + - "null" + revision: + type: + - number + - "null" + size: + type: + - number + - "null" + url: + type: + - string + - "null" + required: + - id + fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + api_name: + type: + - string + - "null" + calc_formula: + type: + - string + - "null" + column_name: + type: + - string + - "null" + column_source: + type: + - number + - "null" + composite_field_id: + type: + - string + - "null" + created: + type: + - string + - "null" + data_set: + type: + - array + - "null" + items: + type: + - string + - "null" + data_set_id: + type: + - string + - "null" + default_value: + type: + - string + - "null" + entity_name: + type: + - string + - "null" + field_permissions: + type: + - array + - "null" + has_draft: + type: + - boolean + - "null" + id: + type: string + is_available_for_advanced_formula: + type: + - boolean + - "null" + is_available_for_webresource: + type: + - boolean + - "null" + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + is_published: + type: + - boolean + - "null" + is_unique: + type: + - boolean + - "null" + modified: + type: + - string + - "null" + name: + type: + - string + - "null" + name_translations: + type: + - object + - "null" + options: + type: + - object + - "null" + properties: + decimal_places: + type: + - number + - "null" + original_dataset_field_id: + type: + - string + - "null" + primitive_type: + type: + - string + - "null" + relation_id: + type: + - string + - "null" + relation_with_entity_id: + type: + - string + - "null" + sequence_id: + type: + - string + - "null" + sequence_pattern: + type: + - string + - "null" + settings: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + decimal_places: + type: + - number + - "null" + shared_with_field_id: + type: + - string + - "null" + source_field_id: + type: + - string + - "null" + source_type_id: + type: + - string + - "null" + system_readonly: + type: + - boolean + - "null" + system_required: + type: + - boolean + - "null" + system_type: + type: + - number + - "null" + translated_name: + type: + - string + - "null" + type_id: + type: + - string + - "null" + use_in_global_search: + type: + - boolean + - "null" + use_in_interface_preview: + type: + - boolean + - "null" + use_lang: + type: + - number + - "null" + required: + - id + forecasts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - array + - "null" + items: + type: + - string + - "null" + description: + type: + - string + - "null" + created: + type: + - string + - "null" + end_date: + type: + - string + - "null" + field: + type: + - string + - "null" + field_id: + type: + - string + - "null" + id: + type: string + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + modified: + type: + - string + - "null" + name: + type: + - string + - "null" + owner: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + pipeline: + type: + - string + - "null" + pipeline_id: + type: + - string + - "null" + revision: + type: + - number + - "null" + settings: + type: + - object + - "null" + properties: + type: + type: + - array + - "null" + items: + type: + - string + - "null" + columns: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + base_value: + type: + - string + - "null" + id: + type: + - string + - "null" + open_value_type: + type: + - string + - "null" + value_comparison: + type: + - string + - "null" + currency_id: + type: + - string + - "null" + date_field_id: + type: + - string + - "null" + end_date: + type: + - string + - "null" + field_filter: + type: + - object + - "null" + properties: + filter_main_box: + type: + - object + - "null" + properties: + entity: + type: + - string + - "null" + filter_fields: + type: + - array + - "null" + id: + type: + - string + - "null" + filter_sibling_boxes: + type: + - array + - "null" + is_enabled: + type: + - boolean + - "null" + operator: + type: + - string + - "null" + field_id: + type: + - string + - "null" + filter: + type: + - object + - "null" + properties: + filter_main_box: + type: + - object + - "null" + properties: + entity: + type: + - string + - "null" + filter_fields: + type: + - array + - "null" + id: + type: + - string + - "null" + filter_sibling_boxes: + type: + - array + - "null" + is_custom: + type: + - boolean + - "null" + is_enabled: + type: + - boolean + - "null" + operator: + type: + - string + - "null" + hide_empty_rows: + type: + - boolean + - "null" + items: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + entity_id: + type: + - string + - "null" + entity_type: + type: + - string + - "null" + id: + type: + - string + - "null" + is_active: + type: + - boolean + - "null" + quota_split_type: + type: + - string + - "null" + values: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + date: + type: + - string + - "null" + quota: + type: + - number + - "null" + items_by_level: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + b637ee4d-0c37-4dab-a985-e20f3485c3aa: + type: + - object + - "null" + properties: + entity_id: + type: + - string + - "null" + entity_type: + type: + - string + - "null" + id: + type: + - string + - "null" + is_active: + type: + - boolean + - "null" + quota_split_type: + type: + - string + - "null" + values: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + date: + type: + - string + - "null" + quota: + type: + - number + - "null" + list_view_options: + type: + - object + - "null" + properties: + columns: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + field_id: + type: + - string + - "null" + frozen: + type: + - boolean + - "null" + pixels: + type: + - boolean + - "null" + width: + type: + - number + - "null" + sort_by: + type: + - string + - "null" + sort_order: + type: + - string + - "null" + period: + type: + - string + - "null" + pipeline_id: + type: + - string + - "null" + pipeline_view_options: + type: + - object + - "null" + properties: + group_by: + type: + - string + - "null" + show_card_fitness: + type: + - boolean + - "null" + show_card_labels: + type: + - boolean + - "null" + show_card_ranking: + type: + - boolean + - "null" + show_card_value: + type: + - boolean + - "null" + show_card_velocity: + type: + - boolean + - "null" + sort_by: + type: + - string + - "null" + sort_order: + type: + - string + - "null" + quota_comparison_type: + type: + - string + - "null" + start_date: + type: + - string + - "null" + trend_view_options: + type: + - object + - "null" + properties: + running_total: + type: + - boolean + - "null" + share_mode: + type: + - number + - "null" + share_mode_params: + type: + - number + - "null" + shared_clients: + type: + - array + - "null" + items: + type: + - string + - "null" + shared_units: + type: + - array + - "null" + start_date: + type: + - string + - "null" + required: + - id + form_views: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account_type: + type: + - string + - "null" + account_type_id: + type: + - string + - "null" + contact_type: + type: + - string + - "null" + contact_type_id: + type: + - string + - "null" + created: + type: + - string + - "null" + entity_type_id: + type: + - string + - "null" + hidden_item_ids: + type: + - array + - "null" + items: + type: + - string + - "null" + id: + type: string + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + item_colors: + type: + - array + - "null" + lead_type: + type: + - string + - "null" + lead_type_id: + type: + - string + - "null" + modified: + type: + - string + - "null" + name: + type: + - string + - "null" + oppty_type: + type: + - string + - "null" + oppty_type_id: + type: + - string + - "null" + owner: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + revision: + type: + - number + - "null" + share_mode: + type: + - number + - "null" + sharing_clients: + type: + - array + - "null" + sharing_units: + type: + - array + - "null" + use_lang: + type: + - boolean + - "null" + required: + - id + entity_scorings: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created: + type: + - string + - "null" + entity_type: + type: + - number + - "null" + id: + type: string + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + is_enabled: + type: + - boolean + - "null" + modified: + type: + - string + - "null" + name: + type: + - string + - "null" + revision: + type: + - number + - "null" + settings: + type: + - object + - "null" + properties: + categories: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + color: + type: + - number + - "null" + id: + type: + - string + - "null" + label: + type: + - string + - "null" + use_lang: + type: + - boolean + - "null" + value: + type: + - number + - "null" + filter: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + filter_main_box: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + entity: + type: + - string + - "null" + filter_fields: + type: + - array + - "null" + id: + type: + - string + - "null" + filter_sibling_boxes: + type: + - array + - "null" + is_enabled: + type: + - boolean + - "null" + operator: + type: + - string + - "null" + rules: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + activity_status: + type: + - number + - "null" + conditions: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + filter_main_box: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + entity: + type: + - string + - "null" + filter_fields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + field: + type: + - string + - "null" + operator: + type: + - string + - "null" + values: + type: + - array + - "null" + items: + type: + - array + - "null" + items: + type: + - string + - "null" + id: + type: + - string + - "null" + filter_sibling_boxes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + entity: + type: + - string + - "null" + filter_fields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + field: + type: + - string + - "null" + operator: + type: + - string + - "null" + values: + type: + - array + - "null" + items: + type: + - array + - "null" + items: + type: + - string + - "null" + id: + type: + - string + - "null" + relation: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + kind: + type: + - string + - "null" + operator: + type: + - string + - "null" + email_event_type: + type: + - string + - "null" + expiration: + type: + - number + - "null" + expiration_enabled: + type: + - boolean + - "null" + expiration_unit: + type: + - string + - "null" + id: + type: + - string + - "null" + is_enabled: + type: + - boolean + - "null" + name: + type: + - string + - "null" + score: + type: + - number + - "null" + score_multiplier: + type: + - boolean + - "null" + score_multiplier_field_id: + type: + - string + - "null" + use_lang: + type: + - boolean + - "null" + sort_order: + type: + - number + - "null" + use_lang: + type: + - boolean + - "null" + required: + - id + leads: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + account_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + cf_lead_source1: + type: + - string + - "null" + cf_lead_source1_id: + type: + - string + - "null" + cf_other_lead_source: + type: + - string + - "null" + contact_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + created: + type: + - string + - "null" + currency_exchange_rates_list: + type: + - string + - "null" + currency_exchange_rates_list_id: + type: + - string + - "null" + days_in_step: + type: + - number + - "null" + documents: + type: + - array + - "null" + formatted_name: + type: + - string + - "null" + id: + type: string + is_archived: + type: + - boolean + - "null" + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + is_favorite: + type: + - boolean + - "null" + label_flag: + type: + - number + - "null" + lead_type: + type: + - string + - "null" + lead_type_id: + type: + - string + - "null" + lost_date: + type: + - string + - "null" + modified: + type: + - string + - "null" + modified_by_user: + type: + - string + - "null" + name: + type: + - string + - "null" + owner: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + primary_account: + type: + - string + - "null" + primary_contact: + type: + - string + - "null" + qualify_date: + type: + - string + - "null" + quick_account_email: + type: + - string + - "null" + quick_account_name: + type: + - string + - "null" + quick_account_phone: + type: + - string + - "null" + quick_contact_name: + type: + - string + - "null" + quick_email: + type: + - string + - "null" + quick_phone: + type: + - string + - "null" + ranking: + type: + - number + - "null" + reason_of_close_description: + type: + - string + - "null" + revision: + type: + - number + - "null" + scoring: + type: + - object + - "null" + properties: + categories: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + color: + type: + - number + - "null" + id: + type: + - string + - "null" + label: + type: + - string + - "null" + use_lang: + type: + - boolean + - "null" + value: + type: + - number + - "null" + entity_scoring_id: + type: + - string + - "null" + entity_scoring_name: + type: + - string + - "null" + entity_scoring_use_lang: + type: + - boolean + - "null" + last_calculation: + type: + - string + - "null" + raw_score: + type: + - number + - "null" + rules: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + created: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + score: + type: + - number + - "null" + trend: + type: + - string + - "null" + use_lang: + type: + - boolean + - "null" + score: + type: + - number + - "null" + trend: + type: + - string + - "null" + share_mode: + type: + - number + - "null" + sharing_clients: + type: + - array + - "null" + sharing_units: + type: + - array + - "null" + status: + type: + - number + - "null" + step: + type: + - string + - "null" + step_id: + type: + - string + - "null" + table_name: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - string + - "null" + unit: + type: + - string + - "null" + unit_id: + type: + - string + - "null" + required: + - id + lead_oppties: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + account_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + active_quote: + type: + - string + - "null" + active_quote_id: + type: + - string + - "null" + cf_lead_source1: + type: + - string + - "null" + cf_lead_source1_id: + type: + - string + - "null" + cf_other_lead_source: + type: + - string + - "null" + closing_date: + type: + - string + - "null" + contact_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + created: + type: + - string + - "null" + currency_exchange_rates_list: + type: + - string + - "null" + currency_exchange_rates_list_id: + type: + - string + - "null" + days_in_step: + type: + - number + - "null" + documents: + type: + - array + - "null" + items: + type: + - string + - "null" + formatted_name: + type: + - string + - "null" + id: + type: string + is_archived: + type: + - boolean + - "null" + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + is_favorite: + type: + - boolean + - "null" + is_value_auto_calculate: + type: + - boolean + - "null" + label_flag: + type: + - number + - "null" + lead_type: + type: + - string + - "null" + lead_type_id: + type: + - string + - "null" + lost_date: + type: + - string + - "null" + modified: + type: + - string + - "null" + modified_by_user: + type: + - string + - "null" + name: + type: + - string + - "null" + oppty_type: + type: + - string + - "null" + oppty_type_id: + type: + - string + - "null" + owner: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + primary_account: + type: + - string + - "null" + primary_contact: + type: + - string + - "null" + product_currency: + type: + - string + - "null" + product_currency_id: + type: + - string + - "null" + product_price_list: + type: + - string + - "null" + product_price_list_id: + type: + - string + - "null" + product_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + product_sections: + type: + - array + - "null" + qualify_date: + type: + - string + - "null" + quick_account_email: + type: + - string + - "null" + quick_account_name: + type: + - string + - "null" + quick_account_phone: + type: + - string + - "null" + quick_contact_name: + type: + - string + - "null" + quick_email: + type: + - string + - "null" + quick_phone: + type: + - string + - "null" + quote_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + ranking: + type: + - number + - "null" + reason_of_close: + type: + - string + - "null" + reason_of_close_description: + type: + - string + - "null" + reason_of_close_id: + type: + - string + - "null" + revision: + type: + - number + - "null" + scoring: + type: + - object + - "null" + properties: + categories: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + color: + type: + - number + - "null" + id: + type: + - string + - "null" + label: + type: + - string + - "null" + use_lang: + type: + - boolean + - "null" + value: + type: + - number + - "null" + entity_scoring_id: + type: + - string + - "null" + entity_scoring_name: + type: + - string + - "null" + entity_scoring_use_lang: + type: + - boolean + - "null" + last_calculation: + type: + - string + - "null" + raw_score: + type: + - number + - "null" + rules: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + created: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + score: + type: + - number + - "null" + trend: + type: + - string + - "null" + use_lang: + type: + - boolean + - "null" + score: + type: + - number + - "null" + trend: + type: + - string + - "null" + share_mode: + type: + - number + - "null" + sharing_clients: + type: + - array + - "null" + sharing_units: + type: + - array + - "null" + status: + type: + - number + - "null" + step: + type: + - string + - "null" + step_id: + type: + - string + - "null" + table_name: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - string + - "null" + unit: + type: + - string + - "null" + unit_id: + type: + - string + - "null" + value: + type: + - object + - "null" + properties: + base_value: + type: + - number + - "null" + currency_id: + type: + - string + - "null" + value_foreign: + type: + - number + - "null" + was_qualified: + type: + - boolean + - "null" + won_date: + type: + - string + - "null" + required: + - id + memos: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + comments: + type: + - array + - "null" + items: + type: + - string + - "null" + contact_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + created: + type: + - string + - "null" + custom_entity_relations: + type: + - array + - "null" + documents: + type: + - array + - "null" + items: + type: + - string + - "null" + id: + type: string + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + lead_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + modified: + type: + - string + - "null" + opportunity_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + owner: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + project_relations: + type: + - array + - "null" + quote_relations: + type: + - array + - "null" + revision: + type: + - number + - "null" + sharing_clients: + type: + - array + - "null" + sharing_units: + type: + - array + - "null" + subject: + type: + - string + - "null" + table_name: + type: + - string + - "null" + required: + - id + notes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account: + type: + - string + - "null" + account_id: + type: + - string + - "null" + created: + type: + - string + - "null" + id: + type: string + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + lead: + type: + - string + - "null" + lead_oppty_id: + type: + - string + - "null" + modified: + type: + - string + - "null" + note: + type: + - string + - "null" + oppty: + type: + - string + - "null" + owner: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + revision: + type: + - number + - "null" + required: + - id + entity_fitnesses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created: + type: + - string + - "null" + entity_type: + type: + - number + - "null" + entity_type_id: + type: + - string + - "null" + id: + type: string + indicator_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + lead_type: + type: + - string + - "null" + lead_type_id: + type: + - string + - "null" + modified: + type: + - string + - "null" + oppty_type: + type: + - string + - "null" + oppty_type_id: + type: + - string + - "null" + revision: + type: + - number + - "null" + required: + - id + pipelines: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + color: + type: + - number + - "null" + created: + type: + - string + - "null" + id: + type: string + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + modified: + type: + - string + - "null" + name: + type: + - string + - "null" + opportunity_types: + type: + - array + - "null" + items: + type: + - string + - "null" + revision: + type: + - number + - "null" + steps: + type: + - array + - "null" + items: + type: + - string + - "null" + required: + - id + products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + allowed_pipelines: + type: + - number + - "null" + created: + type: + - string + - "null" + currency_exchange_rates_list: + type: + - string + - "null" + currency_exchange_rates_list_id: + type: + - string + - "null" + formatted_name: + type: + - string + - "null" + id: + type: string + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + modified: + type: + - string + - "null" + name: + type: + - string + - "null" + oppty_product_relation_type_id: + type: + - string + - "null" + product_category: + type: + - string + - "null" + product_category_id: + type: + - string + - "null" + product_pipeline_relations: + type: + - array + - "null" + product_pipelines: + type: + - object + - "null" + properties: + allowed_pipelines: + type: + - number + - "null" + pipelines: + type: + - array + - "null" + product_type: + type: + - string + - "null" + product_type_id: + type: + - string + - "null" + revision: + type: + - number + - "null" + sku: + type: + - string + - "null" + unit_symbol: + type: + - string + - "null" + required: + - id + oppty_product_relations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + amount: + type: + - number + - "null" + comment: + type: + - string + - "null" + created: + type: + - string + - "null" + currency_exchange_rates_list: + type: + - string + - "null" + currency_exchange_rates_list_id: + type: + - string + - "null" + discount_percentage: + type: + - number + - "null" + discount_value: + type: + - number + - "null" + id: + type: string + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + modified: + type: + - string + - "null" + modified_by_user: + type: + - string + - "null" + oppty: + type: + - string + - "null" + oppty_id: + type: + - string + - "null" + oppty_product_relation_type: + type: + - string + - "null" + oppty_product_relation_type_id: + type: + - string + - "null" + paired_oppty_product_relation: + type: + - string + - "null" + paired_oppty_product_relation_id: + type: + - string + - "null" + price: + type: + - number + - "null" + product: + type: + - string + - "null" + product_id: + type: + - string + - "null" + quantity: + type: + - number + - "null" + quote: + type: + - string + - "null" + quote_id: + type: + - string + - "null" + revision: + type: + - number + - "null" + sort_order: + type: + - number + - "null" + required: + - id + profiles: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + created: + type: + - string + - "null" + entity: + type: + - number + - "null" + id: + type: string + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + modified: + type: + - string + - "null" + name: + type: + - string + - "null" + owner: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + pipelines: + type: + - array + - "null" + items: + type: + - string + - "null" + revision: + type: + - number + - "null" + settings: + type: + - object + - "null" + properties: + entity_types: + type: + - object + - "null" + properties: + show_account: + type: + - boolean + - "null" + show_activities: + type: + - boolean + - "null" + show_contact: + type: + - boolean + - "null" + show_custom_entities: + type: + - array + - "null" + show_document: + type: + - boolean + - "null" + show_email: + type: + - boolean + - "null" + show_lead: + type: + - boolean + - "null" + show_mass_email: + type: + - boolean + - "null" + show_memo: + type: + - boolean + - "null" + show_note: + type: + - boolean + - "null" + show_online_form: + type: + - boolean + - "null" + show_opportunity: + type: + - boolean + - "null" + show_project: + type: + - boolean + - "null" + show_quote: + type: + - boolean + - "null" + show_text_message: + type: + - boolean + - "null" + show_whats_app_message: + type: + - boolean + - "null" + filter: + type: + - object + - "null" + properties: + filter_by_period: + type: + - object + - "null" + properties: + period: + type: + - string + - "null" + filter_main_box: + type: + - object + - "null" + properties: + entity: + type: + - string + - "null" + filter_fields: + type: + - array + - "null" + id: + type: + - string + - "null" + filter_sibling_boxes: + type: + - array + - "null" + has_attachment: + type: + - boolean + - "null" + is_custom: + type: + - boolean + - "null" + is_enabled: + type: + - boolean + - "null" + operator: + type: + - string + - "null" + show_only_favorite: + type: + - boolean + - "null" + filter_by_period: + type: + - object + - "null" + properties: + period: + type: + - string + - "null" + has_attachment: + type: + - boolean + - "null" + lead_process: + type: + - array + - "null" + items: + type: + - string + - "null" + quote_process: + type: + - array + - "null" + items: + type: + - string + - "null" + related_messages: + type: + - boolean + - "null" + role: + type: + - object + - "null" + properties: + show_managing_unit_items: + type: + - boolean + - "null" + show_my_items: + type: + - boolean + - "null" + show_my_shared_items: + type: + - boolean + - "null" + show_unassigned_items: + type: + - boolean + - "null" + sales_pipeline: + type: + - array + - "null" + items: + type: + - string + - "null" + show_only_favorite: + type: + - boolean + - "null" + show_only_my: + type: + - boolean + - "null" + target: + type: + - object + - "null" + properties: + goal: + type: + - number + - "null" + show_target_on_top: + type: + - boolean + - "null" + target_period_compare: + type: + - object + - "null" + properties: + period: + type: + - string + - "null" + target_period_current: + type: + - object + - "null" + properties: + period: + type: + - string + - "null" + target_source: + type: + - string + - "null" + target_value_field_id: + type: + - string + - "null" + target_value_type: + type: + - string + - "null" + view: + type: + - object + - "null" + properties: + bubble_chart_size_calculated_by: + type: + - string + - "null" + conversion_value: + type: + - string + - "null" + entity_types: + type: + - object + - "null" + properties: + show_account: + type: + - boolean + - "null" + show_activities: + type: + - boolean + - "null" + show_contact: + type: + - boolean + - "null" + show_document: + type: + - boolean + - "null" + show_email: + type: + - boolean + - "null" + show_lead: + type: + - boolean + - "null" + show_mass_email: + type: + - boolean + - "null" + show_memo: + type: + - boolean + - "null" + show_note: + type: + - boolean + - "null" + show_opportunity: + type: + - boolean + - "null" + show_project: + type: + - boolean + - "null" + show_text_message: + type: + - boolean + - "null" + show_whats_app_message: + type: + - boolean + - "null" + grid_columns: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + field_id: + type: + - string + - "null" + frozen: + type: + - boolean + - "null" + pixels: + type: + - boolean + - "null" + width: + type: + - number + - "null" + group_by: + type: + - string + - "null" + matrix: + type: + - object + - "null" + properties: + axis_x: + type: + - object + - "null" + properties: + date_display: + type: + - string + - "null" + field_id: + type: + - string + - "null" + sort_order: + type: + - string + - "null" + axis_y: + type: + - object + - "null" + properties: + field_id: + type: + - string + - "null" + sort_order: + type: + - string + - "null" + bubble_display: + type: + - string + - "null" + show_account_names: + type: + - boolean + - "null" + show_segmentation_grid: + type: + - boolean + - "null" + period: + type: + - object + - "null" + properties: + period: + type: + - string + - "null" + period_granularity: + type: + - string + - "null" + report_by: + type: + - string + - "null" + show_card_fitness: + type: + - boolean + - "null" + show_card_labels: + type: + - boolean + - "null" + show_card_ranking: + type: + - boolean + - "null" + show_card_value: + type: + - boolean + - "null" + show_card_velocity: + type: + - boolean + - "null" + show_deleted_units: + type: + - boolean + - "null" + show_due_date: + type: + - boolean + - "null" + show_email: + type: + - boolean + - "null" + show_excluded_items: + type: + - boolean + - "null" + show_inactive_clients: + type: + - boolean + - "null" + show_linked_items: + type: + - boolean + - "null" + show_memo: + type: + - boolean + - "null" + show_outside_target: + type: + - boolean + - "null" + show_progress: + type: + - boolean + - "null" + show_unassigned_lead: + type: + - boolean + - "null" + sort_by: + type: + - string + - "null" + sort_by_modified: + type: + - boolean + - "null" + sort_order: + type: + - string + - "null" + share_mode: + type: + - number + - "null" + use_lang: + type: + - boolean + - "null" + required: + - id + quotes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - number + - "null" + description: + type: + - string + - "null" + account_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + contact_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + created: + type: + - string + - "null" + currency_exchange_rates_list: + type: + - string + - "null" + currency_exchange_rates_list_id: + type: + - string + - "null" + documents: + type: + - array + - "null" + formatted_name: + type: + - string + - "null" + id: + type: string + is_active_in_opportunity: + type: + - boolean + - "null" + is_archived: + type: + - boolean + - "null" + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + is_favorite: + type: + - boolean + - "null" + modified: + type: + - string + - "null" + modified_by_user: + type: + - string + - "null" + name: + type: + - string + - "null" + oppty: + type: + - string + - "null" + oppty_id: + type: + - string + - "null" + owner: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + primary_account: + type: + - string + - "null" + primary_contact: + type: + - string + - "null" + product_currency: + type: + - string + - "null" + product_currency_id: + type: + - string + - "null" + product_relations: + type: + - array + - "null" + items: + type: + - string + - "null" + product_sections: + type: + - array + - "null" + quick_account_email: + type: + - string + - "null" + quick_account_name: + type: + - string + - "null" + quick_account_phone: + type: + - string + - "null" + quick_contact_name: + type: + - string + - "null" + quick_email: + type: + - string + - "null" + quick_phone: + type: + - string + - "null" + quote_number: + type: + - string + - "null" + quote_type: + type: + - string + - "null" + quote_type_id: + type: + - string + - "null" + reason_of_close_description: + type: + - string + - "null" + revision: + type: + - number + - "null" + share_mode: + type: + - number + - "null" + sharing_clients: + type: + - array + - "null" + sharing_units: + type: + - array + - "null" + status: + type: + - number + - "null" + step: + type: + - string + - "null" + step_id: + type: + - string + - "null" + total_amount: + type: + - object + - "null" + properties: + base_value: + type: + - number + - "null" + currency_id: + type: + - string + - "null" + value_foreign: + type: + - number + - "null" + unit: + type: + - string + - "null" + unit_id: + type: + - string + - "null" + required: + - id + reports: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - number + - "null" + description: + type: + - string + - "null" + access_link: + type: + - string + - "null" + created: + type: + - string + - "null" + id: + type: string + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + is_favorite: + type: + - boolean + - "null" + modified: + type: + - string + - "null" + name: + type: + - string + - "null" + owner: + type: + - string + - "null" + owner_id: + type: + - string + - "null" + reports_folder: + type: + - string + - "null" + reports_folder_id: + type: + - string + - "null" + revision: + type: + - number + - "null" + settings: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + filter: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + isEnabled: + type: + - boolean + - "null" + ownerIds: + type: + - array + - "null" + unitIds: + type: + - array + - "null" + isAdvancedReport: + type: + - boolean + - "null" + items: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + chart: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + reportId: + type: + - string + - "null" + id: + type: + - string + - "null" + position: + type: + - object + - "null" + properties: + height: + type: + - number + - "null" + width: + type: + - number + - "null" + x: + type: + - number + - "null" + "y": + type: + - number + - "null" + structure: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + calculationFieldId: + type: + - string + - "null" + entitySubtypes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + kind: + type: + - string + - "null" + entityType: + type: + - string + - "null" + id: + type: + - string + - "null" + mainBox: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + calculationFieldId: + type: + - string + - "null" + displayFields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + columnAlignment: + type: + - string + - "null" + columnColor: + type: + - number + - "null" + columnWidth: + type: + - number + - "null" + fieldId: + type: + - string + - "null" + entitySubtypes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + kind: + type: + - string + - "null" + entityType: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + siblingBoxes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + displayFields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + columnColor: + type: + - number + - "null" + fieldId: + type: + - string + - "null" + entitySubtypes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + kind: + type: + - string + - "null" + entityType: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + relation: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + aggregationType: + type: + - string + - "null" + onlyRowsWithRelatedRecords: + type: + - boolean + - "null" + relationType: + type: + - string + - "null" + sortOrder: + type: + - number + - "null" + tabs: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + filter: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + filterMainBox: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + entity: + type: + - string + - "null" + filterFields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + field: + type: + - string + - "null" + operator: + type: + - string + - "null" + values: + type: + - array + - "null" + items: + type: + - array + - "null" + items: + type: + - number + - string + - "null" + id: + type: + - string + - "null" + filterSiblingBoxes: + type: + - array + - "null" + isCustom: + type: + - boolean + - "null" + isEnabled: + type: + - boolean + - "null" + operator: + type: + - string + - "null" + role: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + showManagingUnitItems: + type: + - boolean + - "null" + showMyItems: + type: + - boolean + - "null" + showMySharedItems: + type: + - boolean + - "null" + showUnassignedItems: + type: + - boolean + - "null" + target: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + goal: + type: + - number + - "null" + isVisible: + type: + - boolean + - "null" + showTargetOnTop: + type: + - boolean + - "null" + targetPeriodCompare: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + period: + type: + - string + - "null" + targetPeriodCurrent: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + period: + type: + - string + - "null" + targetSource: + type: + - string + - "null" + targetValueFieldId: + type: + - string + - "null" + view: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + aggregationFields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + comparison: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + isEnabled: + type: + - boolean + - "null" + operator: + type: + - string + - "null" + fieldId: + type: + - string + - "null" + id: + type: + - string + - "null" + operator: + type: + - string + - "null" + chart: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + __typename: + type: + - string + - "null" + fieldId: + type: + - string + - "null" + groupFieldId: + type: + - string + - "null" + isEnabled: + type: + - boolean + - "null" + operator: + type: + - string + - "null" + segmentFieldId: + type: + - string + - "null" + showNegativeValues: + type: + - boolean + - "null" + showPercentageValues: + type: + - boolean + - "null" + columnFields: + type: + - array + - "null" + currencyId: + type: + - string + - "null" + drilldownFields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + fieldId: + type: + - string + - "null" + frozenPanes: + type: + - string + - "null" + groupFields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + boxId: + type: + - string + - "null" + fieldId: + type: + - string + - "null" + isDrilldownEnabled: + type: + - boolean + - "null" + keepLineBreaks: + type: + - boolean + - "null" + rowFields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + fieldId: + type: + - string + - "null" + sortFields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + __typename: + type: + - string + - "null" + boxId: + type: + - string + - "null" + direction: + type: + - string + - "null" + fieldId: + type: + - string + - "null" + share_mode: + type: + - number + - "null" + share_mode_params: + type: + - number + - "null" + sharing_clients: + type: + - array + - "null" + sharing_units: + type: + - array + - "null" + required: + - id + steps: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created: + type: + - string + - "null" + documents: + type: + - array + - "null" + items: + type: + - string + - "null" + has_readonly_form: + type: + - boolean + - "null" + has_version_increment: + type: + - boolean + - "null" + id: + type: string + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + lead_process: + type: + - string + - "null" + lead_process_id: + type: + - string + - "null" + modified: + type: + - string + - "null" + name: + type: + - string + - "null" + percent: + type: + - number + - "null" + pipeline: + type: + - string + - "null" + pipeline_id: + type: + - string + - "null" + quote_process: + type: + - string + - "null" + quote_process_id: + type: + - string + - "null" + revision: + type: + - number + - "null" + sort_order: + type: + - number + - "null" + step_checklists: + type: + - array + - "null" + items: + type: + - string + - "null" + timeframe: + type: + - number + - "null" + required: + - id + tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + color: + type: + - number + - "null" + created: + type: + - string + - "null" + id: + type: string + is_delete_protected: + type: + - boolean + - "null" + is_deleted: + type: + - boolean + - "null" + modified: + type: + - string + - "null" + name: + type: + - string + - "null" + revision: + type: + - number + - "null" + supported_entities: + type: + - number + - "null" + use_lang: + type: + - boolean + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-pipeliner/metadata.yaml b/airbyte-integrations/connectors/source-pipeliner/metadata.yaml new file mode 100644 index 000000000000..aaffe1f3d990 --- /dev/null +++ b/airbyte-integrations/connectors/source-pipeliner/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "https://*.api.pipelinersales.com/api/v100/rest/" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-pipeliner + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 39fd5da7-5713-446b-a9c6-c695f0352f20 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-pipeliner + githubIssueLabel: source-pipeliner + icon: icon.svg + license: MIT + name: Pipeliner + releaseDate: 2024-11-09 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/pipeliner + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-pivotal-tracker/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-pivotal-tracker/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-pivotal-tracker/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-pivotal-tracker/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-pivotal-tracker/metadata.yaml b/airbyte-integrations/connectors/source-pivotal-tracker/metadata.yaml index 918cb00b743f..01fa0c7ed193 100644 --- a/airbyte-integrations/connectors/source-pivotal-tracker/metadata.yaml +++ b/airbyte-integrations/connectors/source-pivotal-tracker/metadata.yaml @@ -15,11 +15,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: d60f5393-f99e-4310-8d05-b1876820f40e - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.6 dockerRepository: airbyte/source-pivotal-tracker githubIssueLabel: source-pivotal-tracker icon: pivotal-tracker.svg diff --git a/airbyte-integrations/connectors/source-piwik/metadata.yaml b/airbyte-integrations/connectors/source-piwik/metadata.yaml index e69350cd3540..85566d4a0d04 100644 --- a/airbyte-integrations/connectors/source-piwik/metadata.yaml +++ b/airbyte-integrations/connectors/source-piwik/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-piwik connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 09f894a4-d2fb-488f-b0eb-640205314296 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.9 dockerRepository: airbyte/source-piwik githubIssueLabel: source-piwik icon: icon.svg diff --git a/airbyte-integrations/connectors/source-plaid/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-plaid/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-plaid/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-plaid/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-planhat/metadata.yaml b/airbyte-integrations/connectors/source-planhat/metadata.yaml index 14ad2ec83177..904f30927d2f 100644 --- a/airbyte-integrations/connectors/source-planhat/metadata.yaml +++ b/airbyte-integrations/connectors/source-planhat/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-planhat connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 03fdd212-bd09-4e7b-b472-5b8f1b73969b - dockerImageTag: 0.0.4 + dockerImageTag: 0.0.10 dockerRepository: airbyte/source-planhat githubIssueLabel: source-planhat icon: icon.svg diff --git a/airbyte-integrations/connectors/source-plausible/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-plausible/integration_tests/acceptance.py index 3a0f562732fb..6e0d32803f45 100644 --- a/airbyte-integrations/connectors/source-plausible/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-plausible/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-pocket/components.py b/airbyte-integrations/connectors/source-pocket/components.py index 0d5ef1cec552..19414f6f4561 100644 --- a/airbyte-integrations/connectors/source-pocket/components.py +++ b/airbyte-integrations/connectors/source-pocket/components.py @@ -6,6 +6,7 @@ from typing import Any, List, Mapping import requests + from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor from airbyte_cdk.sources.declarative.types import Record diff --git a/airbyte-integrations/connectors/source-pocket/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-pocket/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-pocket/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-pocket/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-pocket/metadata.yaml b/airbyte-integrations/connectors/source-pocket/metadata.yaml index a1753e90bf7d..2be4044561f3 100644 --- a/airbyte-integrations/connectors/source-pocket/metadata.yaml +++ b/airbyte-integrations/connectors/source-pocket/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: b0dd65f1-081f-4731-9c51-38e9e6aa0ebf - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.5 dockerRepository: airbyte/source-pocket documentationUrl: https://docs.airbyte.com/integrations/sources/pocket githubIssueLabel: source-pocket diff --git a/airbyte-integrations/connectors/source-pokeapi/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-pokeapi/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-pokeapi/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-pokeapi/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-pokeapi/metadata.yaml b/airbyte-integrations/connectors/source-pokeapi/metadata.yaml index 03037a2384d4..acc4519cfcb6 100644 --- a/airbyte-integrations/connectors/source-pokeapi/metadata.yaml +++ b/airbyte-integrations/connectors/source-pokeapi/metadata.yaml @@ -15,11 +15,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 6371b14b-bc68-4236-bfbd-468e8df8e968 - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.7 dockerRepository: airbyte/source-pokeapi githubIssueLabel: source-pokeapi icon: pokeapi.svg diff --git a/airbyte-integrations/connectors/source-polygon-stock-api/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-polygon-stock-api/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-polygon-stock-api/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-polygon-stock-api/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-polygon-stock-api/metadata.yaml b/airbyte-integrations/connectors/source-polygon-stock-api/metadata.yaml index df39c7b97fd1..0b2ebb52e421 100644 --- a/airbyte-integrations/connectors/source-polygon-stock-api/metadata.yaml +++ b/airbyte-integrations/connectors/source-polygon-stock-api/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - api.polygon.io connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 5807d72f-0abc-49f9-8fa5-ae820007032b - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-polygon-stock-api documentationUrl: https://docs.airbyte.com/integrations/sources/polygon-stock-api githubIssueLabel: source-polygon-stock-api diff --git a/airbyte-integrations/connectors/source-postgres/build.gradle b/airbyte-integrations/connectors/source-postgres/build.gradle index 7f58327ba57d..1a94803549d9 100644 --- a/airbyte-integrations/connectors/source-postgres/build.gradle +++ b/airbyte-integrations/connectors/source-postgres/build.gradle @@ -12,7 +12,7 @@ java { } airbyteJavaConnector { - cdkVersionRequired = '0.47.1' + cdkVersionRequired = '0.48.4' features = ['db-sources', 'datastore-postgres'] useLocalCdk = false } @@ -24,8 +24,8 @@ application { dependencies { implementation 'commons-codec:commons-codec:1.16.0' - implementation 'io.debezium:debezium-embedded:2.6.2.Final' - implementation 'io.debezium:debezium-connector-postgres:2.6.2.Final' + implementation 'io.debezium:debezium-embedded:3.0.1.Final' + implementation 'io.debezium:debezium-connector-postgres:3.0.1.Final' testFixturesApi 'org.testcontainers:postgresql:1.19.0' diff --git a/airbyte-integrations/connectors/source-postgres/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-postgres/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-postgres/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-postgres/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-postgres/integration_tests/seed/hook.py b/airbyte-integrations/connectors/source-postgres/integration_tests/seed/hook.py index 56afb0875706..93a63daefa3c 100644 --- a/airbyte-integrations/connectors/source-postgres/integration_tests/seed/hook.py +++ b/airbyte-integrations/connectors/source-postgres/integration_tests/seed/hook.py @@ -13,6 +13,7 @@ import pytz from psycopg2 import extensions, sql + catalog_write_file = "/connector/integration_tests/temp/configured_catalog_copy.json" catalog_source_file = "/connector/integration_tests/configured_catalog_template.json" catalog_incremental_write_file = "/connector/integration_tests/temp/incremental_configured_catalog_copy.json" @@ -20,12 +21,13 @@ abnormal_state_write_file = "/connector/integration_tests/temp/abnormal_state_copy.json" abnormal_state_file = "/connector/integration_tests/abnormal_state_template.json" -secret_config_file = '/connector/secrets/config.json' -secret_active_config_file = '/connector/integration_tests/temp/config_active.json' -secret_config_cdc_file = '/connector/secrets/config_cdc.json' -secret_active_config_cdc_file = '/connector/integration_tests/temp/config_cdc_active.json' +secret_config_file = "/connector/secrets/config.json" +secret_active_config_file = "/connector/integration_tests/temp/config_active.json" +secret_config_cdc_file = "/connector/secrets/config_cdc.json" +secret_active_config_cdc_file = "/connector/integration_tests/temp/config_cdc_active.json" + +la_timezone = pytz.timezone("America/Los_Angeles") -la_timezone = pytz.timezone('America/Los_Angeles') def connect_to_db() -> extensions.connection: with open(secret_config_file) as f: @@ -33,11 +35,7 @@ def connect_to_db() -> extensions.connection: try: conn: extensions.connection = psycopg2.connect( - dbname=secret["database"], - user=secret["username"], - password=secret["password"], - host=secret["host"], - port=secret["port"] + dbname=secret["database"], user=secret["username"], password=secret["password"], host=secret["host"], port=secret["port"] ) print("Connected to the database successfully") return conn @@ -45,6 +43,7 @@ def connect_to_db() -> extensions.connection: print(f"Error connecting to the database: {error}") sys.exit(1) + def insert_records(conn: extensions.connection, schema_name: str, table_name: str, records: List[Tuple[str, str]]) -> None: try: cursor = conn.cursor() @@ -64,6 +63,7 @@ def insert_records(conn: extensions.connection, schema_name: str, table_name: st finally: cursor.close() + def create_schema(conn: extensions.connection, schema_name: str) -> None: try: cursor = conn.cursor() @@ -77,24 +77,25 @@ def create_schema(conn: extensions.connection, schema_name: str) -> None: finally: cursor.close() + def write_supporting_file(schema_name: str) -> None: print(f"writing schema name to files: {schema_name}") Path("/connector/integration_tests/temp").mkdir(parents=False, exist_ok=True) with open(catalog_write_file, "w") as file: - with open(catalog_source_file, 'r') as source_file: + with open(catalog_source_file, "r") as source_file: file.write(source_file.read() % schema_name) with open(catalog_incremental_write_file, "w") as file: - with open(catalog_incremental_source_file, 'r') as source_file: + with open(catalog_incremental_source_file, "r") as source_file: file.write(source_file.read() % schema_name) with open(abnormal_state_write_file, "w") as file: - with open(abnormal_state_file, 'r') as source_file: + with open(abnormal_state_file, "r") as source_file: file.write(source_file.read() % (schema_name, schema_name)) with open(secret_config_file) as base_config: secret = json.load(base_config) secret["schemas"] = [schema_name] - with open(secret_active_config_file, 'w') as f: + with open(secret_active_config_file, "w") as f: json.dump(secret, f) with open(secret_config_cdc_file) as base_config: @@ -104,9 +105,10 @@ def write_supporting_file(schema_name: str) -> None: secret["replication_method"]["publication"] = schema_name secret["ssl_mode"] = {} secret["ssl_mode"]["mode"] = "require" - with open(secret_active_config_cdc_file, 'w') as f: + with open(secret_active_config_cdc_file, "w") as f: json.dump(secret, f) + def create_table(conn: extensions.connection, schema_name: str, table_name: str) -> None: try: cursor = conn.cursor() @@ -126,40 +128,37 @@ def create_table(conn: extensions.connection, schema_name: str, table_name: str) finally: cursor.close() + def generate_schema_date_with_suffix() -> str: current_date = datetime.datetime.now(la_timezone).strftime("%Y%m%d") - suffix = ''.join(random.choices(string.ascii_lowercase + string.digits, k=8)) + suffix = "".join(random.choices(string.ascii_lowercase + string.digits, k=8)) return f"{current_date}_{suffix}" + def prepare() -> None: schema_name = generate_schema_date_with_suffix() print(f"schema_name: {schema_name}") with open("./generated_schema.txt", "w") as f: f.write(schema_name) + def cdc_insert(): schema_name = load_schema_name_from_catalog() - new_records = [ - ('4', 'four'), - ('5', 'five') - ] + new_records = [("4", "four"), ("5", "five")] connection = connect_to_db() - table_name = 'id_and_name_cat' + table_name = "id_and_name_cat" if connection: insert_records(connection, schema_name, table_name, new_records) connection.close() + def setup(with_cdc=False): schema_name = load_schema_name_from_catalog() write_supporting_file(schema_name) table_name = "id_and_name_cat" # Define the records to be inserted - records = [ - ('1', 'one'), - ('2', 'two'), - ('3', 'three') - ] + records = [("1", "one"), ("2", "two"), ("3", "three")] # Connect to the database connection = connect_to_db() @@ -167,7 +166,7 @@ def setup(with_cdc=False): # Create the schema create_schema(connection, schema_name) create_table(connection, schema_name, table_name) - if (with_cdc): + if with_cdc: setup_cdc(connection, replication_slot_and_publication_name=schema_name) # Insert the records insert_records(connection, schema_name, table_name, records) @@ -175,6 +174,7 @@ def setup(with_cdc=False): # Close the connection connection.close() + def replication_slot_existed(connection, replication_slot_name): cursor = connection.cursor() cursor.execute("SELECT slot_name FROM pg_replication_slots;") @@ -185,22 +185,31 @@ def replication_slot_existed(connection, replication_slot_name): return True return False + def setup_cdc(connection, replication_slot_and_publication_name): cursor = connection.cursor() if replication_slot_existed(connection, replication_slot_and_publication_name): return - create_logical_replication_query = sql.SQL("SELECT pg_create_logical_replication_slot({}, 'pgoutput')").format(sql.Literal(replication_slot_and_publication_name)) + create_logical_replication_query = sql.SQL("SELECT pg_create_logical_replication_slot({}, 'pgoutput')").format( + sql.Literal(replication_slot_and_publication_name) + ) cursor.execute(create_logical_replication_query) - alter_table_replica_query = sql.SQL("ALTER TABLE {}.id_and_name_cat REPLICA IDENTITY DEFAULT").format(sql.Identifier(replication_slot_and_publication_name)) + alter_table_replica_query = sql.SQL("ALTER TABLE {}.id_and_name_cat REPLICA IDENTITY DEFAULT").format( + sql.Identifier(replication_slot_and_publication_name) + ) cursor.execute(alter_table_replica_query) - create_publication_query = sql.SQL("CREATE PUBLICATION {} FOR TABLE {}.id_and_name_cat").format(sql.Identifier(replication_slot_and_publication_name), sql.Identifier(replication_slot_and_publication_name)) + create_publication_query = sql.SQL("CREATE PUBLICATION {} FOR TABLE {}.id_and_name_cat").format( + sql.Identifier(replication_slot_and_publication_name), sql.Identifier(replication_slot_and_publication_name) + ) cursor.execute(create_publication_query) connection.commit() + def load_schema_name_from_catalog(): with open("./generated_schema.txt", "r") as f: return f.read() + def delete_cdc_with_prefix(conn, prefix): try: # Connect to the PostgreSQL database @@ -224,6 +233,7 @@ def delete_cdc_with_prefix(conn, prefix): if cursor: cursor.close() + def delete_schemas_with_prefix(conn, date_prefix): try: # Connect to the PostgreSQL database @@ -252,14 +262,16 @@ def delete_schemas_with_prefix(conn, date_prefix): finally: cursor.close() + def teardown() -> None: conn = connect_to_db() today = datetime.datetime.now(la_timezone) yesterday = today - timedelta(days=1) - formatted_yesterday = yesterday.strftime('%Y%m%d') + formatted_yesterday = yesterday.strftime("%Y%m%d") delete_schemas_with_prefix(conn, formatted_yesterday) delete_cdc_with_prefix(conn, formatted_yesterday) + def final_teardown() -> None: conn = connect_to_db() schema_name = load_schema_name_from_catalog() @@ -267,6 +279,7 @@ def final_teardown() -> None: delete_schemas_with_prefix(conn, schema_name) delete_cdc_with_prefix(conn, schema_name) + if __name__ == "__main__": command = sys.argv[1] if command == "setup": diff --git a/airbyte-integrations/connectors/source-postgres/metadata.yaml b/airbyte-integrations/connectors/source-postgres/metadata.yaml index 178560522845..2d3a95418f35 100644 --- a/airbyte-integrations/connectors/source-postgres/metadata.yaml +++ b/airbyte-integrations/connectors/source-postgres/metadata.yaml @@ -9,7 +9,7 @@ data: connectorSubtype: database connectorType: source definitionId: decd338e-5647-4c0b-adf4-da0e75f5a750 - dockerImageTag: 3.6.22 + dockerImageTag: 3.6.28 dockerRepository: airbyte/source-postgres documentationUrl: https://docs.airbyte.com/integrations/sources/postgres githubIssueLabel: source-postgres @@ -26,6 +26,8 @@ data: supportLevel: certified tags: - language:java + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:2.0.0@sha256:5a1a21c75c5e1282606de9fa539ba136520abe2fbd013058e988bb0297a9f454 connectorTestSuitesOptions: - suite: unitTests - suite: integrationTests diff --git a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresQueryUtils.java b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresQueryUtils.java index 4cbac03d2115..8aaf42b508a8 100644 --- a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresQueryUtils.java +++ b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresQueryUtils.java @@ -95,13 +95,13 @@ SELECT pg_relation_filenode('%s') public static final String TOTAL_BYTES_RESULT_COL = "totalbytes"; /** - * Query returns the size table data takes on DB server disk (not incling any index or other + * Query returns the size table data takes on DB server disk (not including any index or other * metadata) And the size of each page used in (page, tuple) ctid. This helps us evaluate how many * pages we need to read to traverse the entire table. */ public static final String CTID_TABLE_BLOCK_SIZE = """ - WITH block_sz AS (SELECT current_setting('block_size')::int), rel_sz AS (select pg_relation_size('%s')) SELECT * from block_sz, rel_sz + SELECT current_setting('block_size')::int, pg_relation_size('%s') """; /** diff --git a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresSourceOperations.java b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresSourceOperations.java index 3bf92c8aba10..a627a2c0c843 100644 --- a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresSourceOperations.java +++ b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresSourceOperations.java @@ -30,6 +30,7 @@ import io.airbyte.protocol.models.JsonSchemaPrimitiveUtil.JsonSchemaPrimitive; import io.airbyte.protocol.models.JsonSchemaType; import java.math.BigDecimal; +import java.math.BigInteger; import java.sql.Date; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -172,7 +173,7 @@ public void copyToJsonField(final ResultSet resultSet, final int colIndex, final // If a numeric_array column precision is not 0 AND scale is 0, // then we know the precision and scale are purposefully chosen if (metadata.getPrecision(colIndex) != 0 && metadata.getScale(colIndex) == 0) { - putBigIntArray(json, columnName, resultSet, colIndex); + putBigIntegerArray(json, columnName, resultSet, colIndex); } else { putBigDecimalArray(json, columnName, resultSet, colIndex); } @@ -197,7 +198,7 @@ public void copyToJsonField(final ResultSet resultSet, final int colIndex, final case REAL -> putFloat(json, columnName, resultSet, colIndex); case NUMERIC, DECIMAL -> { if (metadata.getPrecision(colIndex) != 0 && metadata.getScale(colIndex) == 0) { - putBigInt(json, columnName, resultSet, colIndex); + putBigInteger(json, columnName, resultSet, colIndex); } else { putBigDecimal(json, columnName, resultSet, colIndex); } @@ -367,6 +368,16 @@ private void putBigIntArray(final ObjectNode node, final String columnName, fina node.set(columnName, arrayNode); } + private void putBigIntegerArray(final ObjectNode node, final String columnName, final ResultSet resultSet, final int colIndex) throws SQLException { + final ArrayNode arrayNode = Jsons.arrayNode(); + final ResultSet arrayResultSet = resultSet.getArray(colIndex).getResultSet(); + while (arrayResultSet.next()) { + final BigInteger value = DataTypeUtils.throwExceptionIfInvalid(() -> arrayResultSet.getBigDecimal(2).toBigInteger()); + arrayNode.add(value); + } + node.set(columnName, arrayNode); + } + private void putDoubleArray(final ObjectNode node, final String columnName, final ResultSet resultSet, final int colIndex) throws SQLException { final ArrayNode arrayNode = Jsons.arrayNode(); final ResultSet arrayResultSet = resultSet.getArray(colIndex).getResultSet(); diff --git a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresUtils.java b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresUtils.java index 4f54e714f282..101f82310d3f 100644 --- a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresUtils.java +++ b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresUtils.java @@ -44,7 +44,7 @@ public class PostgresUtils { private static final String PGOUTPUT_PLUGIN = "pgoutput"; public static final Duration MIN_FIRST_RECORD_WAIT_TIME = Duration.ofMinutes(2); - public static final Duration MAX_FIRST_RECORD_WAIT_TIME = Duration.ofMinutes(40); + public static final Duration MAX_FIRST_RECORD_WAIT_TIME = Duration.ofMinutes(120); public static final Duration DEFAULT_FIRST_RECORD_WAIT_TIME = Duration.ofMinutes(20); public static final Duration DEFAULT_SUBSEQUENT_RECORD_WAIT_TIME = Duration.ofMinutes(1); diff --git a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/PostgresSourceOperationsTest.java b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/PostgresSourceOperationsTest.java index ebf181a8bcb6..e9b529a40820 100644 --- a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/PostgresSourceOperationsTest.java +++ b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/PostgresSourceOperationsTest.java @@ -14,6 +14,7 @@ import io.airbyte.commons.json.Jsons; import io.airbyte.integrations.source.postgres.PostgresTestDatabase.BaseImage; import io.airbyte.integrations.source.postgres.PostgresTestDatabase.ContainerModifier; +import java.math.BigInteger; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -54,7 +55,7 @@ public void numericColumnAsCursor() throws SQLException { for (int i = 1; i <= 4; i++) { final ObjectNode jsonNode = (ObjectNode) Jsons.jsonNode(Collections.emptyMap()); jsonNode.put("id", i); - final long cursorValue = i * 10; + final BigInteger cursorValue = BigInteger.valueOf(i * 10); jsonNode.put(cursorColumn, cursorValue); final String insertQuery = String.format("INSERT INTO %s VALUES (%s, %s);", tableName, diff --git a/airbyte-integrations/connectors/source-posthog/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-posthog/integration_tests/acceptance.py index 43ce950d77ca..72132012aaed 100644 --- a/airbyte-integrations/connectors/source-posthog/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-posthog/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-posthog/main.py b/airbyte-integrations/connectors/source-posthog/main.py index f7e69357d999..e6ff813e7420 100644 --- a/airbyte-integrations/connectors/source-posthog/main.py +++ b/airbyte-integrations/connectors/source-posthog/main.py @@ -4,5 +4,6 @@ from source_posthog.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-posthog/metadata.yaml b/airbyte-integrations/connectors/source-posthog/metadata.yaml index 910575e68e41..c683c7130dbc 100644 --- a/airbyte-integrations/connectors/source-posthog/metadata.yaml +++ b/airbyte-integrations/connectors/source-posthog/metadata.yaml @@ -9,12 +9,12 @@ data: connectorSubtype: api connectorType: source definitionId: af6d50ee-dddf-4126-a8ee-7faee990774f - dockerImageTag: 1.1.17 + dockerImageTag: 1.1.21 dockerRepository: airbyte/source-posthog documentationUrl: https://docs.airbyte.com/integrations/sources/posthog githubIssueLabel: source-posthog connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 icon: posthog.svg license: MIT name: PostHog diff --git a/airbyte-integrations/connectors/source-posthog/poetry.lock b/airbyte-integrations/connectors/source-posthog/poetry.lock index 6a32b1a07579..72e90cc4577d 100644 --- a/airbyte-integrations/connectors/source-posthog/poetry.lock +++ b/airbyte-integrations/connectors/source-posthog/poetry.lock @@ -63,19 +63,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -141,127 +141,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -277,20 +264,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -368,13 +355,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -487,13 +474,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -574,54 +561,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -885,33 +872,33 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -952,13 +939,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -983,81 +970,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-posthog/pyproject.toml b/airbyte-integrations/connectors/source-posthog/pyproject.toml index 008179e5becf..5a2d532f5177 100644 --- a/airbyte-integrations/connectors/source-posthog/pyproject.toml +++ b/airbyte-integrations/connectors/source-posthog/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "1.1.17" +version = "1.1.21" name = "source-posthog" description = "Source implementation for Posthog." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-posthog/source_posthog/source.py b/airbyte-integrations/connectors/source-posthog/source_posthog/source.py index 268ce3822d51..a7ded5e7a793 100644 --- a/airbyte-integrations/connectors/source-posthog/source_posthog/source.py +++ b/airbyte-integrations/connectors/source-posthog/source_posthog/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-posthog/unit_tests/test_components.py b/airbyte-integrations/connectors/source-posthog/unit_tests/test_components.py index a7c40deb21fe..7e1bb5bd1d0b 100644 --- a/airbyte-integrations/connectors/source-posthog/unit_tests/test_components.py +++ b/airbyte-integrations/connectors/source-posthog/unit_tests/test_components.py @@ -3,11 +3,13 @@ # import pytest as pytest +from source_posthog.components import EventsCartesianProductStreamSlicer + from airbyte_cdk.sources.declarative.datetime.min_max_datetime import MinMaxDatetime from airbyte_cdk.sources.declarative.incremental.datetime_based_cursor import DatetimeBasedCursor from airbyte_cdk.sources.declarative.partition_routers.list_partition_router import ListPartitionRouter from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption -from source_posthog.components import EventsCartesianProductStreamSlicer + stream_slicers = [ ListPartitionRouter(values=[2331], cursor_field="project_id", config={}, parameters={}), diff --git a/airbyte-integrations/connectors/source-posthog/unit_tests/unit_test.py b/airbyte-integrations/connectors/source-posthog/unit_tests/unit_test.py index 04bbfbafe845..5016adc4b09f 100644 --- a/airbyte-integrations/connectors/source-posthog/unit_tests/unit_test.py +++ b/airbyte-integrations/connectors/source-posthog/unit_tests/unit_test.py @@ -3,9 +3,10 @@ # -from airbyte_cdk.logger import AirbyteLogger from source_posthog import SourcePosthog +from airbyte_cdk.logger import AirbyteLogger + def test_client_wrong_credentials(): source = SourcePosthog() diff --git a/airbyte-integrations/connectors/source-postmarkapp/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-postmarkapp/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-postmarkapp/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-postmarkapp/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-postmarkapp/metadata.yaml b/airbyte-integrations/connectors/source-postmarkapp/metadata.yaml index 9dbdf6126280..59e91bbf11a9 100644 --- a/airbyte-integrations/connectors/source-postmarkapp/metadata.yaml +++ b/airbyte-integrations/connectors/source-postmarkapp/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: cde75ca1-1e28-4a0f-85bb-90c546de9f1f - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.5 dockerRepository: airbyte/source-postmarkapp documentationUrl: https://docs.airbyte.com/integrations/sources/postmarkapp githubIssueLabel: source-postmarkapp diff --git a/airbyte-integrations/connectors/source-prestashop/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-prestashop/integration_tests/acceptance.py index 51f9b12de27d..e023a7a92b30 100644 --- a/airbyte-integrations/connectors/source-prestashop/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-prestashop/integration_tests/acceptance.py @@ -4,6 +4,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-prestashop/main.py b/airbyte-integrations/connectors/source-prestashop/main.py index e51c47a996aa..1daf7c26e83b 100644 --- a/airbyte-integrations/connectors/source-prestashop/main.py +++ b/airbyte-integrations/connectors/source-prestashop/main.py @@ -4,5 +4,6 @@ from source_prestashop.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-prestashop/source_prestashop/components.py b/airbyte-integrations/connectors/source-prestashop/source_prestashop/components.py index 0175750fc814..a3f42725cfce 100644 --- a/airbyte-integrations/connectors/source-prestashop/source_prestashop/components.py +++ b/airbyte-integrations/connectors/source-prestashop/source_prestashop/components.py @@ -6,10 +6,11 @@ from typing import Any, List, Mapping, Optional, Tuple import pendulum +from pendulum.parsing.exceptions import ParserError + from airbyte_cdk.sources.declarative.schema import JsonFileSchemaLoader from airbyte_cdk.sources.declarative.transformations import RecordTransformation from airbyte_cdk.sources.declarative.types import Config, Record, StreamSlice, StreamState -from pendulum.parsing.exceptions import ParserError @dataclass diff --git a/airbyte-integrations/connectors/source-pretix/README.md b/airbyte-integrations/connectors/source-pretix/README.md new file mode 100644 index 000000000000..a52e55b9f3c8 --- /dev/null +++ b/airbyte-integrations/connectors/source-pretix/README.md @@ -0,0 +1,33 @@ +# Pretix +This directory contains the manifest-only connector for `source-pretix`. + +[Pretix](https://pretix.eu/about/en/) connector enables seamless data integration with the Pretix event ticketing platform, allowing users to sync ticket sales, attendee information, event data, and other metrics directly into their data warehouse or analytics tools. This connector supports automated data extraction for efficient, reporting and data-driven insights across events managed in Pretix. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-pretix:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-pretix build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-pretix test +``` + diff --git a/airbyte-integrations/connectors/source-pretix/acceptance-test-config.yml b/airbyte-integrations/connectors/source-pretix/acceptance-test-config.yml new file mode 100644 index 000000000000..3b6e0b39c056 --- /dev/null +++ b/airbyte-integrations/connectors/source-pretix/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-pretix:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-pretix/icon.svg b/airbyte-integrations/connectors/source-pretix/icon.svg new file mode 100644 index 000000000000..5f9242e1aa2b --- /dev/null +++ b/airbyte-integrations/connectors/source-pretix/icon.svg @@ -0,0 +1,94 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-pretix/manifest.yaml b/airbyte-integrations/connectors/source-pretix/manifest.yaml new file mode 100644 index 000000000000..ac145dfce0a8 --- /dev/null +++ b/airbyte-integrations/connectors/source-pretix/manifest.yaml @@ -0,0 +1,3404 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + [Pretix](https://pretix.eu/about/en/) connector enables seamless data + integration with the Pretix event ticketing platform, allowing users to sync + ticket sales, attendee information, event data, and other metrics directly + into their data warehouse or analytics tools. This connector supports + automated data extraction for efficient, reporting and data-driven insights + across events managed in Pretix. + +check: + type: CheckStream + stream_names: + - orgainzers + +definitions: + streams: + orgainzers: + type: DeclarativeStream + name: orgainzers + primary_key: + - slug + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /organizers + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/orgainzers" + events: + type: DeclarativeStream + name: events + primary_key: + - slug + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /organizers/{{ stream_partition.organizer }}/events + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/events" + tax_rules: + type: DeclarativeStream + name: tax_rules + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /organizers/{{ stream_partition.organizer }}/events/{{ + stream_partition.event }}/taxrules + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: event + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tax_rules" + categories: + type: DeclarativeStream + name: categories + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /organizers/{{ stream_partition.organizer }}/events/{{ + stream_partition.event }}/categories + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: event + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/categories" + items: + type: DeclarativeStream + name: items + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /organizers/{{ stream_partition.organizer }}/events/{{ + stream_partition.event }}/items + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: event + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/items" + orders: + type: DeclarativeStream + name: orders + primary_key: + - code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /organizers/{{ stream_partition.organizer }}/events/{{ + stream_partition.event }}/orders + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 48 + start_from_page: 1 + inject_on_first_request: true + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: event + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/orders" + vouchers: + type: DeclarativeStream + name: vouchers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /organizers/{{ stream_partition.organizer }}/events/{{ + stream_partition.event }}/vouchers + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: event + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/vouchers" + discounts: + type: DeclarativeStream + name: discounts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /organizers/{{ stream_partition.organizer }}/events/{{ + stream_partition.event }}/discounts + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: event + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/discounts" + checkin_lists: + type: DeclarativeStream + name: checkin_lists + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /organizers/{{ stream_partition.organizer }}/events/{{ + stream_partition.event }}/checkinlists + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: event + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/checkin_lists" + waiting_list_entries: + type: DeclarativeStream + name: waiting_list_entries + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /organizers/{{ stream_partition.organizer }}/events/{{ + stream_partition.event }}/waitinglistentries + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: event + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/waiting_list_entries" + customers: + type: DeclarativeStream + name: customers + primary_key: + - identifier + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /organizers/{{ stream_partition.organizer }}/customers + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers" + sales_channels: + type: DeclarativeStream + name: sales_channels + primary_key: + - identifier + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /organizers/{{ stream_partition.organizer }}/saleschannels + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sales_channels" + membership_types: + type: DeclarativeStream + name: membership_types + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /organizers/{{ stream_partition.organizer }}/membershiptypes + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/membership_types" + memberships: + type: DeclarativeStream + name: memberships + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /organizers/{{ stream_partition.organizer }}/memberships + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/memberships" + giftcards: + type: DeclarativeStream + name: giftcards + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /organizers/{{ stream_partition.organizer }}/giftcards + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/giftcards" + reusable_media: + type: DeclarativeStream + name: reusable_media + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /organizers/{{ stream_partition.organizer }}/reusablemedia + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/reusable_media" + teams: + type: DeclarativeStream + name: teams + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /organizers/{{ stream_partition.organizer }}/teams + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/teams" + devices: + type: DeclarativeStream + name: devices + primary_key: + - device_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /organizers/{{ stream_partition.organizer }}/devices + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/devices" + webhooks: + type: DeclarativeStream + name: webhooks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /organizers/{{ stream_partition.organizer }}/webhooks + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/webhooks" + seating_plans: + type: DeclarativeStream + name: seating_plans + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /organizers/{{ stream_partition.organizer }}/seatingplans + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/seating_plans" + auto_checkin_rules: + type: DeclarativeStream + name: auto_checkin_rules + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /organizers/{{ stream_partition.organizer }}/events/{{ + stream_partition.event }}/auto_checkin_rules + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 400 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: page_size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 50 + inject_on_first_request: true + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: event + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/auto_checkin_rules" + shredders: + type: DeclarativeStream + name: shredders + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /organizers/{{ stream_partition.organizer }}/events/{{ + stream_partition.event }}/shredders + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: event + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/shredders" + exporters: + type: DeclarativeStream + name: exporters + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /organizers/{{ stream_partition.organizer }}/events/{{ + stream_partition.event }}/exporters + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + partition_router: + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: organizer + stream: + $ref: "#/definitions/streams/orgainzers" + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: slug + partition_field: event + stream: + $ref: "#/definitions/streams/events" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/exporters" + base_requester: + type: HttpRequester + url_base: https://pretix.eu/api/v1 + authenticator: + type: ApiKeyAuthenticator + api_token: Token {{ config["api_token"] }} + inject_into: + type: RequestOption + field_name: Authorization + inject_into: header + +streams: + - $ref: "#/definitions/streams/orgainzers" + - $ref: "#/definitions/streams/events" + - $ref: "#/definitions/streams/tax_rules" + - $ref: "#/definitions/streams/categories" + - $ref: "#/definitions/streams/items" + - $ref: "#/definitions/streams/orders" + - $ref: "#/definitions/streams/vouchers" + - $ref: "#/definitions/streams/discounts" + - $ref: "#/definitions/streams/checkin_lists" + - $ref: "#/definitions/streams/waiting_list_entries" + - $ref: "#/definitions/streams/customers" + - $ref: "#/definitions/streams/sales_channels" + - $ref: "#/definitions/streams/membership_types" + - $ref: "#/definitions/streams/memberships" + - $ref: "#/definitions/streams/giftcards" + - $ref: "#/definitions/streams/reusable_media" + - $ref: "#/definitions/streams/teams" + - $ref: "#/definitions/streams/devices" + - $ref: "#/definitions/streams/webhooks" + - $ref: "#/definitions/streams/seating_plans" + - $ref: "#/definitions/streams/auto_checkin_rules" + - $ref: "#/definitions/streams/shredders" + - $ref: "#/definitions/streams/exporters" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_token + properties: + api_token: + type: string + description: >- + API token to use. Obtain it from the pretix web interface by creating + a new token under your team settings. + name: api_token + order: 0 + title: API Token + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + orgainzers: true + events: true + tax_rules: false + categories: false + items: true + orders: true + vouchers: true + discounts: true + checkin_lists: false + waiting_list_entries: true + customers: true + sales_channels: true + membership_types: true + memberships: true + giftcards: true + reusable_media: true + teams: true + devices: true + webhooks: true + seating_plans: true + auto_checkin_rules: true + shredders: true + exporters: true + yamlComponents: + global: + - authenticator + testedStreams: + orgainzers: + hasRecords: true + streamHash: 71df86303da56c37087c8dc7c3fe193aee0d370e + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + events: + hasRecords: true + streamHash: a35a5b6abafdd3f3f21c3e901ae66ea6cf4c05d1 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + tax_rules: + hasRecords: true + streamHash: e5b835ae0164ff344746429de633b582b8a258c0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + categories: + hasRecords: true + streamHash: 1732d6956f60faca41006d4d22138a1582bf6f96 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + items: + hasRecords: true + streamHash: 02785ca498916592f4d8ae47c8172ca7fa7a18f8 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + orders: + hasRecords: true + streamHash: dd32655a3bea0224845c7ecff7a60b86d592efb3 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + vouchers: + hasRecords: true + streamHash: 96fb0f599e05c754ffeb82d16eeae3d4dd1fe89a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + discounts: + hasRecords: true + streamHash: 25af16d94a1bbf482b41df14fafa2de4c519a9ae + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + checkin_lists: + hasRecords: true + streamHash: 8214bcb4cad80c750d19125470c90386922df19c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + waiting_list_entries: + hasRecords: true + streamHash: 6a8d1ccb27e908020e1c57ebae64083b296da398 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + customers: + hasRecords: true + streamHash: 99629857c7369843288e16a042d86724e6502c78 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + sales_channels: + hasRecords: true + streamHash: e2cc6678b341091399e5cc1c355c5a31e5980d50 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + membership_types: + hasRecords: true + streamHash: 39280de26f977943caff109fcaf969410004b1dc + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + memberships: + hasRecords: true + streamHash: 3c93fa3a7658c70702a566c1c2e6078020d79e65 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + giftcards: + hasRecords: true + streamHash: 18c34c70c7e23211d25d0ccecb1669f11e22ceb5 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + reusable_media: + hasRecords: true + streamHash: fafbecc6573f6bd7d49b95a78b4b45cd1a8089a6 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + teams: + hasRecords: true + streamHash: 1dbd52e2e92c7852ddf900650887a049292e41f4 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + devices: + hasRecords: true + streamHash: a3acf3b16a430f0dda0e96c8299d05b732255445 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + webhooks: + hasRecords: true + streamHash: 23e05fa9f8440a2770727fb43190d3e3a4ddf2c8 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + seating_plans: + hasRecords: true + streamHash: 15f050c79c35db58b7aa978f5458b2206ec112cf + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + auto_checkin_rules: + streamHash: 1bfb584f3aa6df391f80eb6c7fceb80417512e8c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + shredders: + streamHash: 5c204b52d0a4628bd9c1555f0e9ea01e991f39f6 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + exporters: + streamHash: eedd896748b5db5330d7c7f07475e53eba9f6dc2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://docs.pretix.eu/en/latest/api/fundamentals.html + +schemas: + orgainzers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + name: + type: + - string + - "null" + public_url: + type: + - string + - "null" + slug: + type: string + required: + - slug + events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + all_sales_channels: + type: + - boolean + - "null" + currency: + type: + - string + - "null" + date_from: + type: + - string + - "null" + date_to: + type: + - string + - "null" + has_subevents: + type: + - boolean + - "null" + is_public: + type: + - boolean + - "null" + item_meta_properties: + type: + - object + - "null" + limit_sales_channels: + type: + - array + - "null" + live: + type: + - boolean + - "null" + location: + type: + - object + - "null" + meta_data: + type: + - object + - "null" + name: + type: + - object + - "null" + properties: + en: + type: + - string + - "null" + plugins: + type: + - array + - "null" + items: + type: + - string + - "null" + public_url: + type: + - string + - "null" + sales_channels: + type: + - array + - "null" + items: + type: + - string + - "null" + seat_category_mapping: + type: + - object + - "null" + slug: + type: string + testmode: + type: + - boolean + - "null" + timezone: + type: + - string + - "null" + required: + - slug + tax_rules: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + custom_rules: + type: + - array + - "null" + eu_reverse_charge: + type: + - boolean + - "null" + home_country: + type: + - string + - "null" + id: + type: number + internal_name: + type: + - string + - "null" + keep_gross_if_rate_changes: + type: + - boolean + - "null" + name: + type: + - object + - "null" + properties: + en: + type: + - string + - "null" + price_includes_tax: + type: + - boolean + - "null" + rate: + type: + - string + - "null" + required: + - id + categories: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - object + - "null" + properties: + en: + type: + - string + - "null" + cross_selling_match_products: + type: + - array + - "null" + id: + type: number + is_addon: + type: + - boolean + - "null" + name: + type: + - object + - "null" + properties: + ar: + type: + - string + - "null" + ca: + type: + - string + - "null" + cs: + type: + - string + - "null" + da: + type: + - string + - "null" + de: + type: + - string + - "null" + de-informal: + type: + - string + - "null" + el: + type: + - string + - "null" + en: + type: + - string + - "null" + es: + type: + - string + - "null" + eu: + type: + - string + - "null" + fr: + type: + - string + - "null" + id: + type: + - string + - "null" + it: + type: + - string + - "null" + lv: + type: + - string + - "null" + nb-no: + type: + - string + - "null" + nl: + type: + - string + - "null" + nl-informal: + type: + - string + - "null" + pl: + type: + - string + - "null" + pt-pt: + type: + - string + - "null" + ro: + type: + - string + - "null" + ru: + type: + - string + - "null" + sk: + type: + - string + - "null" + sv: + type: + - string + - "null" + tr: + type: + - string + - "null" + uk: + type: + - string + - "null" + zh-hans: + type: + - string + - "null" + zh-hant: + type: + - string + - "null" + position: + type: + - number + - "null" + required: + - id + items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - object + - "null" + active: + type: + - boolean + - "null" + addons: + type: + - array + - "null" + admission: + type: + - boolean + - "null" + all_sales_channels: + type: + - boolean + - "null" + allow_cancel: + type: + - boolean + - "null" + allow_waitinglist: + type: + - boolean + - "null" + available_from_mode: + type: + - string + - "null" + available_until_mode: + type: + - string + - "null" + bundles: + type: + - array + - "null" + category: + type: + - number + - "null" + checkin_attention: + type: + - boolean + - "null" + checkin_text: + type: + - string + - "null" + default_price: + type: + - string + - "null" + free_price: + type: + - boolean + - "null" + grant_membership_duration_days: + type: + - number + - "null" + grant_membership_duration_like_event: + type: + - boolean + - "null" + grant_membership_duration_months: + type: + - number + - "null" + has_variations: + type: + - boolean + - "null" + hide_without_voucher: + type: + - boolean + - "null" + id: + type: number + issue_giftcard: + type: + - boolean + - "null" + limit_sales_channels: + type: + - array + - "null" + meta_data: + type: + - object + - "null" + name: + type: + - object + - "null" + properties: + en: + type: + - string + - "null" + personalized: + type: + - boolean + - "null" + position: + type: + - number + - "null" + require_approval: + type: + - boolean + - "null" + require_bundling: + type: + - boolean + - "null" + require_membership: + type: + - boolean + - "null" + require_membership_hidden: + type: + - boolean + - "null" + require_membership_types: + type: + - array + - "null" + require_voucher: + type: + - boolean + - "null" + sales_channels: + type: + - array + - "null" + items: + type: + - string + - "null" + tax_rate: + type: + - string + - "null" + validity_dynamic_start_choice: + type: + - boolean + - "null" + variations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - object + - "null" + active: + type: + - boolean + - "null" + all_sales_channels: + type: + - boolean + - "null" + available_from_mode: + type: + - string + - "null" + available_until_mode: + type: + - string + - "null" + checkin_attention: + type: + - boolean + - "null" + checkin_text: + type: + - string + - "null" + hide_without_voucher: + type: + - boolean + - "null" + id: + type: + - number + - "null" + limit_sales_channels: + type: + - array + - "null" + meta_data: + type: + - object + - "null" + position: + type: + - number + - "null" + price: + type: + - string + - "null" + require_approval: + type: + - boolean + - "null" + require_membership: + type: + - boolean + - "null" + require_membership_hidden: + type: + - boolean + - "null" + require_membership_types: + type: + - array + - "null" + sales_channels: + type: + - array + - "null" + items: + type: + - string + - "null" + value: + type: + - object + - "null" + properties: + en: + type: + - string + - "null" + required: + - id + orders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + api_meta: + type: + - object + - "null" + checkin_attention: + type: + - boolean + - "null" + checkin_text: + type: + - string + - "null" + code: + type: string + comment: + type: + - string + - "null" + datetime: + type: + - string + - "null" + downloads: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + output: + type: + - string + - "null" + url: + type: + - string + - "null" + email: + type: + - string + - "null" + event: + type: + - string + - "null" + expires: + type: + - string + - "null" + fees: + type: + - array + - "null" + invoice_address: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + company: + type: + - string + - "null" + country: + type: + - string + - "null" + internal_reference: + type: + - string + - "null" + is_business: + type: + - boolean + - "null" + last_modified: + type: + - string + - "null" + name: + type: + - string + - "null" + name_parts: + type: + - object + - "null" + properties: + _scheme: + type: + - string + - "null" + family_name: + type: + - string + - "null" + given_name: + type: + - string + - "null" + state: + type: + - string + - "null" + street: + type: + - string + - "null" + vat_id: + type: + - string + - "null" + vat_id_validated: + type: + - boolean + - "null" + zipcode: + type: + - string + - "null" + last_modified: + type: + - string + - "null" + locale: + type: + - string + - "null" + payment_date: + type: + - string + - "null" + payment_provider: + type: + - string + - "null" + payments: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + created: + type: + - string + - "null" + details: + type: + - object + - "null" + local_id: + type: + - number + - "null" + payment_date: + type: + - string + - "null" + provider: + type: + - string + - "null" + state: + type: + - string + - "null" + positions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + answers: + type: + - array + - "null" + attendee_name: + type: + - string + - "null" + attendee_name_parts: + type: + - object + - "null" + properties: + _scheme: + type: + - string + - "null" + family_name: + type: + - string + - "null" + given_name: + type: + - string + - "null" + canceled: + type: + - boolean + - "null" + checkins: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + auto_checked_in: + type: + - boolean + - "null" + datetime: + type: + - string + - "null" + id: + type: + - number + - "null" + list: + type: + - number + - "null" + downloads: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + output: + type: + - string + - "null" + url: + type: + - string + - "null" + id: + type: + - number + - "null" + item: + type: + - number + - "null" + order: + type: + - string + - "null" + positionid: + type: + - number + - "null" + price: + type: + - string + - "null" + print_logs: + type: + - array + - "null" + pseudonymization_id: + type: + - string + - "null" + secret: + type: + - string + - "null" + tax_rate: + type: + - string + - "null" + tax_value: + type: + - string + - "null" + refunds: + type: + - array + - "null" + require_approval: + type: + - boolean + - "null" + sales_channel: + type: + - string + - "null" + secret: + type: + - string + - "null" + status: + type: + - string + - "null" + testmode: + type: + - boolean + - "null" + total: + type: + - string + - "null" + url: + type: + - string + - "null" + valid_if_pending: + type: + - boolean + - "null" + required: + - code + vouchers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + all_addons_included: + type: + - boolean + - "null" + all_bundles_included: + type: + - boolean + - "null" + allow_ignore_quota: + type: + - boolean + - "null" + block_quota: + type: + - boolean + - "null" + code: + type: + - string + - "null" + comment: + type: + - string + - "null" + id: + type: number + max_usages: + type: + - number + - "null" + min_usages: + type: + - number + - "null" + price_mode: + type: + - string + - "null" + redeemed: + type: + - number + - "null" + show_hidden_items: + type: + - boolean + - "null" + tag: + type: + - string + - "null" + valid_until: + type: + - string + - "null" + value: + type: + - string + - "null" + required: + - id + discounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active: + type: + - boolean + - "null" + all_sales_channels: + type: + - boolean + - "null" + benefit_apply_to_addons: + type: + - boolean + - "null" + benefit_discount_matching_percent: + type: + - string + - "null" + benefit_ignore_voucher_discounted: + type: + - boolean + - "null" + benefit_limit_products: + type: + - array + - "null" + benefit_same_products: + type: + - boolean + - "null" + condition_all_products: + type: + - boolean + - "null" + condition_apply_to_addons: + type: + - boolean + - "null" + condition_ignore_voucher_discounted: + type: + - boolean + - "null" + condition_limit_products: + type: + - array + - "null" + condition_min_count: + type: + - number + - "null" + condition_min_value: + type: + - string + - "null" + id: + type: number + internal_name: + type: + - string + - "null" + limit_sales_channels: + type: + - array + - "null" + position: + type: + - number + - "null" + sales_channels: + type: + - array + - "null" + items: + type: + - string + - "null" + subevent_mode: + type: + - string + - "null" + required: + - id + checkin_lists: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + addon_match: + type: + - boolean + - "null" + all_products: + type: + - boolean + - "null" + allow_entry_after_exit: + type: + - boolean + - "null" + allow_multiple_entries: + type: + - boolean + - "null" + checkin_count: + type: + - number + - "null" + consider_tickets_used: + type: + - boolean + - "null" + id: + type: number + ignore_in_statistics: + type: + - boolean + - "null" + include_pending: + type: + - boolean + - "null" + limit_products: + type: + - array + - "null" + name: + type: + - string + - "null" + position_count: + type: + - number + - "null" + rules: + type: + - object + - "null" + required: + - id + waiting_list_entries: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: number + item: + type: + - number + - "null" + locale: + type: + - string + - "null" + name_parts: + type: + - object + - "null" + priority: + type: + - number + - "null" + required: + - id + customers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + date_joined: + type: + - string + - "null" + email: + type: + - string + - "null" + identifier: + type: string + is_active: + type: + - boolean + - "null" + is_verified: + type: + - boolean + - "null" + last_modified: + type: + - string + - "null" + locale: + type: + - string + - "null" + name: + type: + - string + - "null" + name_parts: + type: + - object + - "null" + phone: + type: + - string + - "null" + required: + - identifier + sales_channels: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + identifier: + type: string + label: + type: + - object + - "null" + properties: + ar: + type: + - string + - "null" + ca: + type: + - string + - "null" + cs: + type: + - string + - "null" + da: + type: + - string + - "null" + de: + type: + - string + - "null" + de-informal: + type: + - string + - "null" + el: + type: + - string + - "null" + en: + type: + - string + - "null" + es: + type: + - string + - "null" + eu: + type: + - string + - "null" + fr: + type: + - string + - "null" + id: + type: + - string + - "null" + it: + type: + - string + - "null" + lv: + type: + - string + - "null" + nb-no: + type: + - string + - "null" + nl: + type: + - string + - "null" + nl-informal: + type: + - string + - "null" + pl: + type: + - string + - "null" + pt-pt: + type: + - string + - "null" + ro: + type: + - string + - "null" + ru: + type: + - string + - "null" + sk: + type: + - string + - "null" + sv: + type: + - string + - "null" + tr: + type: + - string + - "null" + uk: + type: + - string + - "null" + zh-hans: + type: + - string + - "null" + zh-hant: + type: + - string + - "null" + position: + type: + - number + - "null" + required: + - identifier + membership_types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + allow_parallel_usage: + type: + - boolean + - "null" + id: + type: + - number + - "null" + max_usages: + type: + - number + - "null" + name: + type: + - object + - "null" + properties: + de: + type: + - string + - "null" + en: + type: + - string + - "null" + transferable: + type: + - boolean + - "null" + memberships: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attendee_name_parts: + type: + - object + - "null" + properties: + _scheme: + type: + - string + - "null" + family_name: + type: + - string + - "null" + given_name: + type: + - string + - "null" + title: + type: + - string + - "null" + customer: + type: + - string + - "null" + date_end: + type: + - string + - "null" + date_start: + type: + - string + - "null" + id: + type: + - number + - "null" + membership_type: + type: + - number + - "null" + testmode: + type: + - boolean + - "null" + giftcards: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + conditions: + type: + - string + - "null" + currency: + type: + - string + - "null" + expires: + type: + - string + - "null" + id: + type: number + issuance: + type: + - string + - "null" + issuer: + type: + - string + - "null" + secret: + type: + - string + - "null" + testmode: + type: + - boolean + - "null" + value: + type: + - string + - "null" + required: + - id + reusable_media: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + active: + type: + - boolean + - "null" + created: + type: + - string + - "null" + id: + type: number + identifier: + type: + - string + - "null" + info: + type: + - object + - "null" + organizer: + type: + - string + - "null" + updated: + type: + - string + - "null" + required: + - id + teams: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + all_events: + type: + - boolean + - "null" + can_change_event_settings: + type: + - boolean + - "null" + can_change_items: + type: + - boolean + - "null" + can_change_orders: + type: + - boolean + - "null" + can_change_organizer_settings: + type: + - boolean + - "null" + can_change_teams: + type: + - boolean + - "null" + can_change_vouchers: + type: + - boolean + - "null" + can_checkin_orders: + type: + - boolean + - "null" + can_create_events: + type: + - boolean + - "null" + can_manage_customers: + type: + - boolean + - "null" + can_manage_gift_cards: + type: + - boolean + - "null" + can_manage_reusable_media: + type: + - boolean + - "null" + can_view_orders: + type: + - boolean + - "null" + can_view_vouchers: + type: + - boolean + - "null" + id: + type: number + limit_events: + type: + - array + - "null" + name: + type: + - string + - "null" + require_2fa: + type: + - boolean + - "null" + required: + - id + devices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + all_events: + type: + - boolean + - "null" + created: + type: + - string + - "null" + device_id: + type: number + initialization_token: + type: + - string + - "null" + limit_events: + type: + - array + - "null" + items: + type: + - string + - "null" + name: + type: + - string + - "null" + revoked: + type: + - boolean + - "null" + security_profile: + type: + - string + - "null" + unique_serial: + type: + - string + - "null" + required: + - device_id + webhooks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + action_types: + type: + - array + - "null" + items: + type: + - string + - "null" + all_events: + type: + - boolean + - "null" + enabled: + type: + - boolean + - "null" + id: + type: number + limit_events: + type: + - array + - "null" + target_url: + type: + - string + - "null" + required: + - id + seating_plans: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: number + layout: + type: + - object + - "null" + properties: + categories: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + color: + type: + - string + - "null" + name: + type: + - string + - "null" + name: + type: + - string + - "null" + size: + type: + - object + - "null" + properties: + height: + type: + - number + - "null" + width: + type: + - number + - "null" + zones: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + areas: + type: + - array + - "null" + name: + type: + - string + - "null" + position: + type: + - object + - "null" + properties: + x: + type: + - number + - "null" + "y": + type: + - number + - "null" + rows: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + position: + type: + - object + - "null" + properties: + x: + type: + - number + - "null" + "y": + type: + - number + - "null" + row_number: + type: + - string + - "null" + row_number_position: + type: + - string + - "null" + seats: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + category: + type: + - string + - "null" + position: + type: + - object + - "null" + properties: + x: + type: + - number + - "null" + "y": + type: + - number + - "null" + seat_guid: + type: + - string + - "null" + seat_number: + type: + - string + - "null" + uuid: + type: + - string + - "null" + uuid: + type: + - string + - "null" + uuid: + type: + - string + - "null" + zone_id: + type: + - string + - "null" + name: + type: + - string + - "null" + required: + - id + auto_checkin_rules: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + all_payment_methods: + type: + - boolean + - "null" + all_products: + type: + - boolean + - "null" + all_sales_channels: + type: + - boolean + - "null" + id: + type: number + limit_payment_methods: + type: + - array + - "null" + limit_products: + type: + - array + - "null" + items: + type: + - number + - "null" + limit_sales_channels: + type: + - array + - "null" + items: + type: + - string + - "null" + limit_variations: + type: + - array + - "null" + mode: + type: + - string + - "null" + required: + - id + shredders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + identifier: + type: + - string + - "null" + verbose_name: + type: + - string + - "null" + exporters: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + identifier: + type: + - string + - "null" + input_parameters: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + choices: + type: + - array + - "null" + items: + type: + - string + - "null" + name: + type: + - string + - "null" + required: + type: + - boolean + - "null" + verbose_name: + type: + - string + - "null" diff --git a/airbyte-integrations/connectors/source-pretix/metadata.yaml b/airbyte-integrations/connectors/source-pretix/metadata.yaml new file mode 100644 index 000000000000..9b5640d7aad3 --- /dev/null +++ b/airbyte-integrations/connectors/source-pretix/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "pretix.eu" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-pretix + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: c32e6012-96cf-45f7-8c09-ac9a32484d96 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-pretix + githubIssueLabel: source-pretix + icon: icon.svg + license: MIT + name: Pretix + releaseDate: 2024-11-09 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/pretix + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-primetric/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-primetric/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-primetric/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-primetric/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-primetric/metadata.yaml b/airbyte-integrations/connectors/source-primetric/metadata.yaml index 85d5344bd595..0302ef43bfd7 100644 --- a/airbyte-integrations/connectors/source-primetric/metadata.yaml +++ b/airbyte-integrations/connectors/source-primetric/metadata.yaml @@ -23,11 +23,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:4.4.3@sha256:8937b693c7e01087f6e86e683826ac20f160f7952b8f0a13cbf4f9bfdd7af570 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: f636c3c6-4077-45ac-b109-19fc62a283c1 - dockerImageTag: 1.1.1 + dockerImageTag: 1.1.4 dockerRepository: airbyte/source-primetric githubIssueLabel: source-primetric icon: primetric.svg diff --git a/airbyte-integrations/connectors/source-productboard/metadata.yaml b/airbyte-integrations/connectors/source-productboard/metadata.yaml index 5a08a2ad68e2..143f61ceeccc 100644 --- a/airbyte-integrations/connectors/source-productboard/metadata.yaml +++ b/airbyte-integrations/connectors/source-productboard/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-productboard connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 43ae66ee-e3df-4fb7-bff5-9625d25cdc14 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.10 dockerRepository: airbyte/source-productboard githubIssueLabel: source-productboard icon: icon.svg diff --git a/airbyte-integrations/connectors/source-productive/metadata.yaml b/airbyte-integrations/connectors/source-productive/metadata.yaml index b1460dd7e122..c9c243fff824 100644 --- a/airbyte-integrations/connectors/source-productive/metadata.yaml +++ b/airbyte-integrations/connectors/source-productive/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-productive connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 51766ab3-df25-4c8c-98a4-647440d0dfbb - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-productive githubIssueLabel: source-productive icon: icon.svg diff --git a/airbyte-integrations/connectors/source-public-apis/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-public-apis/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-public-apis/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-public-apis/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-public-apis/main.py b/airbyte-integrations/connectors/source-public-apis/main.py index c9796a4aa4ef..d39349fbd421 100644 --- a/airbyte-integrations/connectors/source-public-apis/main.py +++ b/airbyte-integrations/connectors/source-public-apis/main.py @@ -4,5 +4,6 @@ from source_public_apis.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-public-apis/metadata.yaml b/airbyte-integrations/connectors/source-public-apis/metadata.yaml index b398ce95e783..637f1f3b19a4 100644 --- a/airbyte-integrations/connectors/source-public-apis/metadata.yaml +++ b/airbyte-integrations/connectors/source-public-apis/metadata.yaml @@ -17,7 +17,7 @@ data: connectorSubtype: api connectorType: source definitionId: a4617b39-3c14-44cd-a2eb-6e720f269235 - dockerImageTag: 0.2.21 + dockerImageTag: 0.2.27 dockerRepository: airbyte/source-public-apis documentationUrl: https://docs.airbyte.com/integrations/sources/public-apis githubIssueLabel: source-public-apis @@ -42,5 +42,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-public-apis/poetry.lock b/airbyte-integrations/connectors/source-public-apis/poetry.lock index c2268c5899fb..67d96c050603 100644 --- a/airbyte-integrations/connectors/source-public-apis/poetry.lock +++ b/airbyte-integrations/connectors/source-public-apis/poetry.lock @@ -42,13 +42,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] @@ -56,24 +56,24 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -88,19 +88,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -166,13 +166,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -256,116 +256,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -435,20 +422,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -498,13 +485,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -519,13 +506,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -533,7 +520,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -583,13 +569,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -679,22 +665,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -767,69 +756,86 @@ files = [ [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -932,54 +938,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -991,13 +997,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1285,33 +1291,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1378,13 +1384,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1409,81 +1415,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-public-apis/pyproject.toml b/airbyte-integrations/connectors/source-public-apis/pyproject.toml index 2ae92364b3b3..56d32d63c423 100644 --- a/airbyte-integrations/connectors/source-public-apis/pyproject.toml +++ b/airbyte-integrations/connectors/source-public-apis/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.2.21" +version = "0.2.27" name = "source-public-apis" description = "Source implementation for Public Apis." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-public-apis/source_public_apis/components.py b/airbyte-integrations/connectors/source-public-apis/source_public_apis/components.py index d659c4dfe5b1..f5b17ab6ba99 100644 --- a/airbyte-integrations/connectors/source-public-apis/source_public_apis/components.py +++ b/airbyte-integrations/connectors/source-public-apis/source_public_apis/components.py @@ -5,10 +5,10 @@ from typing import Any, List, Mapping import requests + from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor class CustomExtractor(RecordExtractor): def extract_records(self, response: requests.Response, **kwargs) -> List[Mapping[str, Any]]: - return [{"name": cat} for cat in response.json()["categories"]] diff --git a/airbyte-integrations/connectors/source-public-apis/source_public_apis/run.py b/airbyte-integrations/connectors/source-public-apis/source_public_apis/run.py index b4927fb5a5e2..951a517434cf 100644 --- a/airbyte-integrations/connectors/source-public-apis/source_public_apis/run.py +++ b/airbyte-integrations/connectors/source-public-apis/source_public_apis/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_public_apis import SourcePublicApis +from airbyte_cdk.entrypoint import launch + def run(): source = SourcePublicApis() diff --git a/airbyte-integrations/connectors/source-public-apis/source_public_apis/source.py b/airbyte-integrations/connectors/source-public-apis/source_public_apis/source.py index b9925483338d..ab25aeb7a367 100644 --- a/airbyte-integrations/connectors/source-public-apis/source_public_apis/source.py +++ b/airbyte-integrations/connectors/source-public-apis/source_public_apis/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-pypi/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-pypi/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-pypi/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-pypi/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-pypi/metadata.yaml b/airbyte-integrations/connectors/source-pypi/metadata.yaml index 34c3ccddef3c..a8795961cd00 100644 --- a/airbyte-integrations/connectors/source-pypi/metadata.yaml +++ b/airbyte-integrations/connectors/source-pypi/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 88ecd3a8-5f5b-11ed-9b6a-0242ac120002 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-pypi documentationUrl: https://docs.airbyte.com/integrations/sources/pypi githubIssueLabel: source-pypi diff --git a/airbyte-integrations/connectors/source-python-http-tutorial/main.py b/airbyte-integrations/connectors/source-python-http-tutorial/main.py index 57dce4e0679c..e38c9bbaf28e 100644 --- a/airbyte-integrations/connectors/source-python-http-tutorial/main.py +++ b/airbyte-integrations/connectors/source-python-http-tutorial/main.py @@ -4,5 +4,6 @@ from source_python_http_tutorial.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-python-http-tutorial/setup.py b/airbyte-integrations/connectors/source-python-http-tutorial/setup.py index 35164f2108aa..9c354e0ab0ff 100644 --- a/airbyte-integrations/connectors/source-python-http-tutorial/setup.py +++ b/airbyte-integrations/connectors/source-python-http-tutorial/setup.py @@ -4,6 +4,7 @@ from setuptools import find_packages, setup + setup( entry_points={ "console_scripts": [ diff --git a/airbyte-integrations/connectors/source-python-http-tutorial/source_python_http_tutorial/source.py b/airbyte-integrations/connectors/source-python-http-tutorial/source_python_http_tutorial/source.py index 07921116b35c..f287a682d498 100644 --- a/airbyte-integrations/connectors/source-python-http-tutorial/source_python_http_tutorial/source.py +++ b/airbyte-integrations/connectors/source-python-http-tutorial/source_python_http_tutorial/source.py @@ -7,6 +7,7 @@ from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Tuple import requests + from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http import HttpStream diff --git a/airbyte-integrations/connectors/source-qonto/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-qonto/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-qonto/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-qonto/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-qonto/metadata.yaml b/airbyte-integrations/connectors/source-qonto/metadata.yaml index 58d849301c21..514d4f33d3e6 100644 --- a/airbyte-integrations/connectors/source-qonto/metadata.yaml +++ b/airbyte-integrations/connectors/source-qonto/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: ccd3901d-edf3-4e58-900c-942d6990aa59 - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.8 dockerRepository: airbyte/source-qonto githubIssueLabel: source-qonto icon: qonto.svg @@ -27,7 +27,7 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc remoteRegistries: pypi: enabled: false diff --git a/airbyte-integrations/connectors/source-qualaroo/README.md b/airbyte-integrations/connectors/source-qualaroo/README.md index dcf330fcbf13..b3f9f56f97d9 100644 --- a/airbyte-integrations/connectors/source-qualaroo/README.md +++ b/airbyte-integrations/connectors/source-qualaroo/README.md @@ -1,89 +1,63 @@ # Qualaroo source connector +This directory contains the manifest-only connector for `source-qualaroo`. +This _manifest-only_ connector is not a Python package on its own, as it runs inside of the base `source-declarative-manifest` image. -This is the repository for the Qualaroo source connector, written in Python. -For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.com/integrations/sources/qualaroo). +For information about how to configure and use this connector within Airbyte, see [the connector's full documentation](https://docs.airbyte.com/integrations/sources/qualaroo). ## Local development -### Prerequisites -* Python (~=3.9) -* Poetry (~=1.7) - installation instructions [here](https://python-poetry.org/docs/#installation) +We recommend using the Connector Builder to edit this connector. +Using either Airbyte Cloud or your local Airbyte OSS instance, navigate to the **Builder** tab and select **Import a YAML**. +Then select the connector's `manifest.yaml` file to load the connector into the Builder. You're now ready to make changes to the connector! +If you prefer to develop locally, you can follow the instructions below. -### Installing the connector -From this connector directory, run: -```bash -poetry install --with dev -``` - - -### Create credentials -**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/qualaroo) -to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_qualaroo/spec.yaml` file. -Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. -See `sample_files/sample_config.json` for a sample config file. - - -### Locally running the connector -``` -poetry run source-qualaroo spec -poetry run source-qualaroo check --config secrets/config.json -poetry run source-qualaroo discover --config secrets/config.json -poetry run source-qualaroo read --config secrets/config.json --catalog sample_files/configured_catalog.json -``` +### Building the docker image -### Running unit tests -To run unit tests locally, from the connector directory run: -``` -poetry run pytest unit_tests -``` +You can build any manifest-only connector with `airbyte-ci`: -### Building the docker image 1. Install [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md) 2. Run the following command to build the docker image: + ```bash airbyte-ci connectors --name=source-qualaroo build ``` An image will be available on your host with the tag `airbyte/source-qualaroo:dev`. +### Creating credentials + +**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/qualaroo) +to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `spec` object in the connector's `manifest.yaml` file. +Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. ### Running as a docker container -Then run any of the connector commands as follows: -``` + +Then run any of the standard source connector commands: + +```bash docker run --rm airbyte/source-qualaroo:dev spec docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-qualaroo:dev check --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-qualaroo:dev discover --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-qualaroo:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json ``` -### Running our CI test suite -You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): -```bash -airbyte-ci connectors --name=source-qualaroo test -``` +### Running the CI test suite -### Customizing acceptance Tests -Customize `acceptance-test-config.yml` file to configure acceptance tests. See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) for more information. -If your connector requires to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py. +You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): -### Dependency Management -All of your dependencies should be managed via Poetry. -To add a new dependency, run: ```bash -poetry add +airbyte-ci connectors --name=source-qualaroo test ``` -Please commit the changes to `pyproject.toml` and `poetry.lock` files. - ## Publishing a new version of the connector -You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what? -1. Make sure your changes are passing our test suite: `airbyte-ci connectors --name=source-qualaroo test` -2. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): + +If you want to contribute changes to `source-qualaroo`, here's how you can do that: +1. Make your changes locally, or load the connector's manifest into Connector Builder and make changes there. +2. Make sure your changes are passing our test suite with `airbyte-ci connectors --name=source-qualaroo test` +3. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): - bump the `dockerImageTag` value in in `metadata.yaml` - - bump the `version` value in `pyproject.toml` -3. Make sure the `metadata.yaml` content is up to date. 4. Make sure the connector documentation and its changelog is up to date (`docs/integrations/sources/qualaroo.md`). 5. Create a Pull Request: use [our PR naming conventions](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#pull-request-title-convention). 6. Pat yourself on the back for being an awesome contributor. diff --git a/airbyte-integrations/connectors/source-qualaroo/__init__.py b/airbyte-integrations/connectors/source-qualaroo/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-integrations/connectors/source-qualaroo/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-integrations/connectors/source-qualaroo/acceptance-test-config.yml b/airbyte-integrations/connectors/source-qualaroo/acceptance-test-config.yml index 6241c7d6d3c7..4b383a66d097 100644 --- a/airbyte-integrations/connectors/source-qualaroo/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-qualaroo/acceptance-test-config.yml @@ -4,7 +4,7 @@ connector_image: airbyte/source-qualaroo:dev acceptance_tests: spec: tests: - - spec_path: "source_qualaroo/spec.yaml" + - spec_path: "manifest.yaml" connection: tests: - config_path: "secrets/config.json" diff --git a/airbyte-integrations/connectors/source-qualaroo/components.py b/airbyte-integrations/connectors/source-qualaroo/components.py new file mode 100644 index 000000000000..5c700af307b2 --- /dev/null +++ b/airbyte-integrations/connectors/source-qualaroo/components.py @@ -0,0 +1,33 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +from base64 import b64encode +from dataclasses import dataclass +from typing import Any, List, Mapping + +import requests + +from airbyte_cdk.sources.declarative.auth.token import BasicHttpAuthenticator +from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor + + +@dataclass +class CustomAuthenticator(BasicHttpAuthenticator): + @property + def token(self): + key = str(self._username.eval(self.config)).encode("latin1") + token = self._password.eval(self.config).encode("latin1") + encoded_credentials = b64encode(b":".join((key, token))).strip() + token = "Basic " + encoded_credentials.decode("ascii") + return token + + +class CustomExtractor(RecordExtractor): + def extract_records(self, response: requests.Response, **kwargs) -> List[Mapping[str, Any]]: + extracted = [] + for record in response.json(): + if "answered_questions" in record: + record["answered_questions"] = list(record["answered_questions"].values()) + extracted.append(record) + return extracted diff --git a/airbyte-integrations/connectors/source-qualaroo/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-qualaroo/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-qualaroo/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-qualaroo/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-qualaroo/main.py b/airbyte-integrations/connectors/source-qualaroo/main.py deleted file mode 100644 index 7a7ed24a96bf..000000000000 --- a/airbyte-integrations/connectors/source-qualaroo/main.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from source_qualaroo.run import run - -if __name__ == "__main__": - run() diff --git a/airbyte-integrations/connectors/source-qualaroo/manifest.yaml b/airbyte-integrations/connectors/source-qualaroo/manifest.yaml new file mode 100644 index 000000000000..94f2c4db0522 --- /dev/null +++ b/airbyte-integrations/connectors/source-qualaroo/manifest.yaml @@ -0,0 +1,335 @@ +version: 5.14.0 + +type: DeclarativeSource + +check: + type: CheckStream + stream_names: + - surveys + +definitions: + streams: + surveys: + type: DeclarativeStream + name: surveys + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: nudges + http_method: GET + request_parameters: + limit: "500" + start_date: "{{config['start_date']}}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + http_codes: + - 500 + action: FAIL + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 504 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + record_filter: + type: RecordFilter + condition: >- + {{ record['id'] in config['survey_ids'] if config['survey_ids'] + else true}} + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + pagination_strategy: + type: OffsetIncrement + page_size: 500 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/surveys" + responses: + type: DeclarativeStream + name: responses + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: nudges/{{ stream_slice.parent_id }}/responses.json + http_method: GET + request_parameters: + limit: "500" + start_date: "{{config['start_date']}}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + http_codes: + - 500 + action: FAIL + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + http_codes: + - 504 + record_selector: + type: RecordSelector + extractor: + type: CustomRecordExtractor + class_name: source_declarative_manifest.components.CustomExtractor + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + pagination_strategy: + type: OffsetIncrement + page_size: 500 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: parent_id + stream: + $ref: "#/definitions/streams/surveys" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/responses" + base_requester: + type: HttpRequester + url_base: https://api.qualaroo.com/api/v1/ + authenticator: + type: CustomAuthenticator + class_name: source_declarative_manifest.components.CustomAuthenticator + username: "{{config['key']}}" + password: "{{config['token']}}" + +streams: + - $ref: "#/definitions/streams/surveys" + - $ref: "#/definitions/streams/responses" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - token + - key + - start_date + properties: + token: + type: string + description: >- + A Qualaroo token. See the docs + for instructions on how to generate it. + title: API token + airbyte_secret: true + order: 0 + key: + type: string + description: >- + A Qualaroo token. See the docs + for instructions on how to generate it. + title: API key + airbyte_secret: true + order: 1 + start_date: + type: string + description: >- + UTC date and time in the format 2017-01-25T00:00:00Z. Any data before + this date will not be replicated. + title: Start Date + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}Z$ + examples: + - "2021-03-01T00:00:00.000Z" + order: 2 + survey_ids: + type: array + description: >- + IDs of the surveys from which you'd like to replicate data. If left + empty, data from all surveys to which you have access will be + replicated. + items: + type: string + pattern: ^[0-9]{1,8}$ + title: Qualaroo survey IDs + order: 3 + additionalProperties: true + +metadata: + autoImportSchema: + surveys: false + responses: false + yamlComponents: + streams: + responses: + - recordSelector + global: + - authenticator + testedStreams: {} + assist: {} + +schemas: + surveys: + type: object + properties: + type: + type: + - "null" + - string + active: + type: + - "null" + - boolean + canonical_name: + type: + - "null" + - string + created_at: + type: + - "null" + - string + format: date-time + id: + type: + - "null" + - integer + kind: + type: + - "null" + - string + name: + type: + - "null" + - string + site_id: + type: + - "null" + - integer + survey_url: + type: + - "null" + - string + uuid: + type: + - "null" + - string + additionalProperties: true + responses: + type: object + properties: + anon_visitor_id: + type: + - "null" + - string + answered_questions: + type: array + items: + type: + - "null" + - object + emitted_at: + type: + - "null" + - string + format: date-time + id: + type: + - "null" + - integer + identity: + type: + - "null" + - string + ip_address: + type: + - "null" + - string + location: + type: + - "null" + - string + nps: + type: + - "null" + - object + properties: + category: + type: + - "null" + - string + reason: + type: + - "null" + - string + respondent_id: + type: + - "null" + - integer + response_uri: + type: + - "null" + - string + score: + type: + - "null" + - integer + time: + type: + - "null" + - string + format: date-time + nudge_id: + type: + - "null" + - integer + nudge_name: + type: + - "null" + - string + page: + type: + - "null" + - string + properties: + type: + - "null" + - object + referrer: + type: + - "null" + - string + time: + type: + - "null" + - string + format: date-time + user_agent: + type: + - "null" + - string + additionalProperties: true diff --git a/airbyte-integrations/connectors/source-qualaroo/metadata.yaml b/airbyte-integrations/connectors/source-qualaroo/metadata.yaml index 055973b457f5..98513a43a19a 100644 --- a/airbyte-integrations/connectors/source-qualaroo/metadata.yaml +++ b/airbyte-integrations/connectors/source-qualaroo/metadata.yaml @@ -4,7 +4,7 @@ data: - "*" # Please change to the hostname of the source. remoteRegistries: pypi: - enabled: true + enabled: false packageName: airbyte-source-qualaroo registryOverrides: oss: @@ -14,7 +14,7 @@ data: connectorSubtype: api connectorType: source definitionId: eb655362-28a8-4311-8806-4fcc612734a7 - dockerImageTag: 0.3.24 + dockerImageTag: 0.4.5 dockerRepository: airbyte/source-qualaroo githubIssueLabel: source-qualaroo icon: qualaroo.svg @@ -25,24 +25,21 @@ data: supportLevel: community documentationUrl: https://docs.airbyte.com/integrations/sources/qualaroo tags: - - language:python - cdk:low-code + - language:manifest-only connectorTestSuitesOptions: - suite: liveTests testConnections: - name: qualaroo_config_dev_null id: 8178b8f4-9511-442c-9ddf-4cd31713266c - # Disable acceptance tests for now - # They are not passing - # No Airbyte Cloud usage - # - suite: unitTests - # - suite: acceptanceTests - # testSecrets: - # - name: SECRET_SOURCE-QUALAROO_CREDS - # fileName: config.json - # secretStore: - # type: GSM - # alias: airbyte-connector-testing-secret-store + - suite: unitTests + - suite: acceptanceTests + testSecrets: + - name: SECRET_SOURCE-QUALAROO_CREDS + fileName: config.json + secretStore: + type: GSM + alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-qualaroo/poetry.lock b/airbyte-integrations/connectors/source-qualaroo/poetry.lock deleted file mode 100644 index 711efc8fb7ce..000000000000 --- a/airbyte-integrations/connectors/source-qualaroo/poetry.lock +++ /dev/null @@ -1,1492 +0,0 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. - -[[package]] -name = "airbyte-cdk" -version = "1.0.0" -description = "A framework for writing Airbyte Connectors." -optional = false -python-versions = "<4.0,>=3.9" -files = [ - {file = "airbyte_cdk-1.0.0-py3-none-any.whl", hash = "sha256:74cd8d4f9790b9a164731c42236cb015166b5ab2b0754b6a1fd730f223eb4e7f"}, - {file = "airbyte_cdk-1.0.0.tar.gz", hash = "sha256:102b75ce589460be4f75dabd3402ac7aa633c90758558c81d140fd436b76371f"}, -] - -[package.dependencies] -airbyte-protocol-models = ">=0.9.0,<1.0" -backoff = "*" -cachetools = "*" -cryptography = ">=42.0.5,<43.0.0" -Deprecated = ">=1.2,<1.3" -dpath = ">=2.0.1,<2.1.0" -genson = "1.2.2" -isodate = ">=0.6.1,<0.7.0" -Jinja2 = ">=3.1.2,<3.2.0" -jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" -langchain_core = "0.1.42" -pendulum = "<3.0.0" -pydantic = ">=1.10.8,<2.0.0" -pyjwt = ">=2.8.0,<3.0.0" -pyrate-limiter = ">=3.1.0,<3.2.0" -python-dateutil = "*" -pytz = "2024.1" -PyYAML = ">=6.0.1,<7.0.0" -requests = "*" -requests_cache = "*" -wcmatch = "8.4" - -[package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] - -[[package]] -name = "airbyte-protocol-models" -version = "0.13.0" -description = "Declares the Airbyte Protocol." -optional = false -python-versions = ">=3.8" -files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, -] - -[package.dependencies] -pydantic = ">=1.9.2,<2.0.0" - -[[package]] -name = "anyio" -version = "4.6.2.post1" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.9" -files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, -] - -[package.dependencies] -exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} - -[package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] -trio = ["trio (>=0.26.1)"] - -[[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, -] - -[[package]] -name = "attrs" -version = "24.2.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" -files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, -] - -[package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] - -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "bracex" -version = "2.5.post1" -description = "Bash style brace expander." -optional = false -python-versions = ">=3.8" -files = [ - {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, - {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, -] - -[[package]] -name = "cachetools" -version = "5.5.0" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, - {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, -] - -[[package]] -name = "cattrs" -version = "24.1.2" -description = "Composable complex class support for attrs and dataclasses." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, - {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, -] - -[package.dependencies] -attrs = ">=23.1.0" -exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} - -[package.extras] -bson = ["pymongo (>=4.4.0)"] -cbor2 = ["cbor2 (>=5.4.6)"] -msgpack = ["msgpack (>=1.0.5)"] -msgspec = ["msgspec (>=0.18.5)"] -orjson = ["orjson (>=3.9.2)"] -pyyaml = ["pyyaml (>=6.0)"] -tomlkit = ["tomlkit (>=0.11.8)"] -ujson = ["ujson (>=5.7.0)"] - -[[package]] -name = "certifi" -version = "2024.8.30" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, -] - -[[package]] -name = "cffi" -version = "1.17.1" -description = "Foreign Function Interface for Python calling C code." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, - {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, - {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, - {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, - {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, - {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, - {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, - {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, - {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, - {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, - {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, - {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, - {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, - {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, - {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, - {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, -] - -[package.dependencies] -pycparser = "*" - -[[package]] -name = "charset-normalizer" -version = "3.4.0" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -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 = "cryptography" -version = "42.0.8" -description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -optional = false -python-versions = ">=3.7" -files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, -] - -[package.dependencies] -cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} - -[package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] -docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] -nox = ["nox"] -pep8test = ["check-sdist", "click", "mypy", "ruff"] -sdist = ["build"] -ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] -test-randomorder = ["pytest-randomly"] - -[[package]] -name = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - -[[package]] -name = "dpath" -version = "2.0.8" -description = "Filesystem-like pathing and searching for dictionaries" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dpath-2.0.8-py3-none-any.whl", hash = "sha256:f92f595214dd93a00558d75d4b858beee519f4cffca87f02616ad6cd013f3436"}, - {file = "dpath-2.0.8.tar.gz", hash = "sha256:a3440157ebe80d0a3ad794f1b61c571bef125214800ffdb9afc9424e8250fe9b"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "genson" -version = "1.2.2" -description = "GenSON is a powerful, user-friendly JSON Schema generator." -optional = false -python-versions = "*" -files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, -] - -[[package]] -name = "h11" -version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.7" -files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, -] - -[[package]] -name = "httpcore" -version = "1.0.6" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.13,<0.15" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<1.0)"] - -[[package]] -name = "httpx" -version = "0.27.2" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isodate" -version = "0.6.1" -description = "An ISO 8601 date/time/duration parser and formatter" -optional = false -python-versions = "*" -files = [ - {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, - {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "jinja2" -version = "3.1.4" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "jsonpatch" -version = "1.33" -description = "Apply JSON-Patches (RFC 6902)" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" -files = [ - {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, - {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, -] - -[package.dependencies] -jsonpointer = ">=1.9" - -[[package]] -name = "jsonpointer" -version = "3.0.0" -description = "Identify specific nodes in a JSON document (RFC 6901)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, - {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, -] - -[[package]] -name = "jsonref" -version = "0.2" -description = "An implementation of JSON Reference for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonref-0.2-py3-none-any.whl", hash = "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f"}, - {file = "jsonref-0.2.tar.gz", hash = "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697"}, -] - -[[package]] -name = "jsonschema" -version = "3.2.0" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, -] - -[package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" - -[package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] - -[[package]] -name = "langchain-core" -version = "0.1.42" -description = "Building applications with LLMs through composability" -optional = false -python-versions = "<4.0,>=3.8.1" -files = [ - {file = "langchain_core-0.1.42-py3-none-any.whl", hash = "sha256:c5653ffa08a44f740295c157a24c0def4a753333f6a2c41f76bf431cd00be8b5"}, - {file = "langchain_core-0.1.42.tar.gz", hash = "sha256:40751bf60ea5d8e2b2efe65290db434717ee3834870c002e40e2811f09d814e6"}, -] - -[package.dependencies] -jsonpatch = ">=1.33,<2.0" -langsmith = ">=0.1.0,<0.2.0" -packaging = ">=23.2,<24.0" -pydantic = ">=1,<3" -PyYAML = ">=5.3" -tenacity = ">=8.1.0,<9.0.0" - -[package.extras] -extended-testing = ["jinja2 (>=3,<4)"] - -[[package]] -name = "langsmith" -version = "0.1.137" -description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." -optional = false -python-versions = "<4.0,>=3.8.1" -files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, -] - -[package.dependencies] -httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" -pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} -requests = ">=2,<3" -requests-toolbelt = ">=1.0.0,<2.0.0" - -[[package]] -name = "markupsafe" -version = "3.0.2" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -files = [ - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, - {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, -] - -[[package]] -name = "orjson" -version = "3.10.10" -description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" -optional = false -python-versions = ">=3.8" -files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, -] - -[[package]] -name = "packaging" -version = "23.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, -] - -[[package]] -name = "pendulum" -version = "2.1.2" -description = "Python datetimes made easy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, - {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, - {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, - {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, - {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, - {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, - {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, - {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, - {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, - {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, - {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, -] - -[package.dependencies] -python-dateutil = ">=2.6,<3.0" -pytzdata = ">=2020.1" - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] - -[[package]] -name = "pycparser" -version = "2.22" -description = "C parser in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, - {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, -] - -[[package]] -name = "pydantic" -version = "1.10.18" -description = "Data validation and settings management using python type hints" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, -] - -[package.dependencies] -typing-extensions = ">=4.2.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] - -[[package]] -name = "pyjwt" -version = "2.9.0" -description = "JSON Web Token implementation in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, -] - -[package.extras] -crypto = ["cryptography (>=3.4.0)"] -dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] -docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] -tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] - -[[package]] -name = "pyrate-limiter" -version = "3.1.1" -description = "Python Rate-Limiter using Leaky-Bucket Algorithm" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, - {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, -] - -[package.extras] -all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] -docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] - -[[package]] -name = "pyrsistent" -version = "0.20.0" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7"}, - {file = "pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee"}, - {file = "pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d"}, - {file = "pyrsistent-0.20.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win32.whl", hash = "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d"}, - {file = "pyrsistent-0.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win32.whl", hash = "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf"}, - {file = "pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b"}, - {file = "pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4"}, -] - -[[package]] -name = "pytest" -version = "6.2.5" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, -] - -[package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] - -[[package]] -name = "pytest-mock" -version = "3.14.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, -] - -[package.dependencies] -pytest = ">=6.2.5" - -[package.extras] -dev = ["pre-commit", "pytest-asyncio", "tox"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytz" -version = "2024.1" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, -] - -[[package]] -name = "pytzdata" -version = "2020.1" -description = "The Olson timezone database for Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, - {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-cache" -version = "1.2.1" -description = "A persistent cache for python requests" -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, - {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, -] - -[package.dependencies] -attrs = ">=21.2" -cattrs = ">=22.2" -platformdirs = ">=2.5" -requests = ">=2.22" -url-normalize = ">=1.4" -urllib3 = ">=1.25.5" - -[package.extras] -all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] -bson = ["bson (>=0.5)"] -docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] -dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] -json = ["ujson (>=5.4)"] -mongodb = ["pymongo (>=3)"] -redis = ["redis (>=3)"] -security = ["itsdangerous (>=2.0)"] -yaml = ["pyyaml (>=6.0.1)"] - -[[package]] -name = "requests-mock" -version = "1.12.1" -description = "Mock out responses from the requests package" -optional = false -python-versions = ">=3.5" -files = [ - {file = "requests-mock-1.12.1.tar.gz", hash = "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401"}, - {file = "requests_mock-1.12.1-py2.py3-none-any.whl", hash = "sha256:b1e37054004cdd5e56c84454cc7df12b25f90f382159087f4b6915aaeef39563"}, -] - -[package.dependencies] -requests = ">=2.22,<3" - -[package.extras] -fixture = ["fixtures"] - -[[package]] -name = "requests-toolbelt" -version = "1.0.0" -description = "A utility belt for advanced users of python-requests" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, - {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, -] - -[package.dependencies] -requests = ">=2.0.1,<3.0.0" - -[[package]] -name = "setuptools" -version = "75.2.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - -[[package]] -name = "tenacity" -version = "8.5.0" -description = "Retry code until it succeeds" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, - {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, -] - -[package.extras] -doc = ["reno", "sphinx"] -test = ["pytest", "tornado (>=4.5)", "typeguard"] - -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "url-normalize" -version = "1.4.3" -description = "URL normalization for Python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, - {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "urllib3" -version = "2.2.3" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "wcmatch" -version = "8.4" -description = "Wildcard/glob file name matcher." -optional = false -python-versions = ">=3.7" -files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, -] - -[package.dependencies] -bracex = ">=2.1.1" - -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "7837a8e446313e068be6245532d7ddb3a63f70da7bc4c6613d26c3a1443db8e7" diff --git a/airbyte-integrations/connectors/source-qualaroo/pyproject.toml b/airbyte-integrations/connectors/source-qualaroo/pyproject.toml deleted file mode 100644 index 3975b69f9a54..000000000000 --- a/airbyte-integrations/connectors/source-qualaroo/pyproject.toml +++ /dev/null @@ -1,28 +0,0 @@ -[build-system] -requires = [ "poetry-core>=1.0.0",] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -version = "0.3.24" -name = "source-qualaroo" -description = "Source implementation for Qualaroo." -authors = [ "Airbyte ",] -license = "MIT" -readme = "README.md" -documentation = "https://docs.airbyte.com/integrations/sources/qualaroo" -homepage = "https://airbyte.com" -repository = "https://github.com/airbytehq/airbyte" -[[tool.poetry.packages]] -include = "source_qualaroo" - -[tool.poetry.dependencies] -python = "^3.9,<3.12" -airbyte-cdk = "1.0.0" - -[tool.poetry.scripts] -source-qualaroo = "source_qualaroo.run:run" - -[tool.poetry.group.dev.dependencies] -requests-mock = "^1.9.3" -pytest = "^6.2" -pytest-mock = "^3.6.1" diff --git a/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/__init__.py b/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/__init__.py deleted file mode 100644 index 99c5fb690f89..000000000000 --- a/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from .source import SourceQualaroo - -__all__ = ["SourceQualaroo"] diff --git a/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/components.py b/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/components.py deleted file mode 100644 index 5e4e619d4d44..000000000000 --- a/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/components.py +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from base64 import b64encode -from dataclasses import dataclass -from typing import Any, List, Mapping - -import requests -from airbyte_cdk.sources.declarative.auth.token import BasicHttpAuthenticator -from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor - - -@dataclass -class CustomAuthenticator(BasicHttpAuthenticator): - @property - def token(self): - - key = str(self._username.eval(self.config)).encode("latin1") - token = self._password.eval(self.config).encode("latin1") - encoded_credentials = b64encode(b":".join((key, token))).strip() - token = "Basic " + encoded_credentials.decode("ascii") - return token - - -class CustomExtractor(RecordExtractor): - def extract_records(self, response: requests.Response, **kwargs) -> List[Mapping[str, Any]]: - - extracted = [] - for record in response.json(): - if "answered_questions" in record: - record["answered_questions"] = list(record["answered_questions"].values()) - extracted.append(record) - return extracted diff --git a/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/manifest.yaml b/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/manifest.yaml deleted file mode 100644 index 2f3fa4f94a94..000000000000 --- a/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/manifest.yaml +++ /dev/null @@ -1,131 +0,0 @@ -version: "0.29.0" - -definitions: - selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: [] - record_filter: - condition: "{{ record['id'] in config['survey_ids'] if config['survey_ids'] else true}}" - requester: - type: HttpRequester - url_base: "https://api.qualaroo.com/api/v1/" - http_method: "GET" - authenticator: - class_name: source_qualaroo.components.CustomAuthenticator - username: "{{config['key']}}" - password: "{{config['token']}}" - request_parameters: - limit: "500" - start_date: "{{config['start_date']}}" - error_handler: - response_filters: - - http_codes: [500] - action: FAIL - retriever: - type: SimpleRetriever - record_selector: - $ref: "#/definitions/selector" - paginator: - type: "DefaultPaginator" - pagination_strategy: - type: "OffsetIncrement" - page_size: 500 - page_token_option: - type: "RequestOption" - field_name: "offset" - inject_into: "request_parameter" - requester: - $ref: "#/definitions/requester" - base_stream: - type: DeclarativeStream - retriever: - $ref: "#/definitions/retriever" - - surveys_stream: - $ref: "#/definitions/base_stream" - $parameters: - name: "surveys" - primary_key: "id" - path: "nudges" - - responses_stream: - $ref: "#/definitions/base_stream" - $parameters: - name: "responses" - primary_key: "id" - retriever: - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "nudges/{{ stream_slice.parent_id }}/responses.json" - record_selector: - type: RecordSelector - extractor: - class_name: source_qualaroo.components.CustomExtractor - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/surveys_stream" - parent_key: "id" - partition_field: "parent_id" - -streams: - - "#/definitions/surveys_stream" - - "#/definitions/responses_stream" - -check: - type: CheckStream - stream_names: - - "responses" - - "surveys" - -spec: - type: Spec - documentationUrl: https://docs.airbyte.com/integrations/sources/qualaroo - connection_specification: - $schema: http://json-schema.org/draft-07/schema# - title: Qualaroo Spec - type: object - required: - - token - - key - - start_date - additionalProperties: true - properties: - token: - type: string - title: API token - description: >- - A Qualaroo token. See the docs - for instructions on how to generate it. - airbyte_secret: true - key: - type: string - title: API key - description: >- - A Qualaroo token. See the docs - for instructions on how to generate it. - airbyte_secret: true - start_date: - type: string - title: Start Date - pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}Z$ - description: >- - UTC date and time in the format 2017-01-25T00:00:00Z. Any data before - this date will not be replicated. - examples: - - "2021-03-01T00:00:00.000Z" - survey_ids: - type: array - items: - type: string - pattern: ^[0-9]{1,8}$ - title: Qualaroo survey IDs - description: >- - IDs of the surveys from which you'd like to replicate data. If left - empty, data from all surveys to which you have access will be - replicated. diff --git a/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/run.py b/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/run.py deleted file mode 100644 index c6b4c65009e5..000000000000 --- a/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/run.py +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import sys - -from airbyte_cdk.entrypoint import launch -from source_qualaroo import SourceQualaroo - - -def run(): - source = SourceQualaroo() - launch(source, sys.argv[1:]) diff --git a/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/schemas/responses.json b/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/schemas/responses.json deleted file mode 100644 index db74aa16cfa5..000000000000 --- a/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/schemas/responses.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "type": "object", - "properties": { - "id": { - "type": ["null", "integer"] - }, - "time": { - "type": ["null", "string"], - "format": "date-time" - }, - "emitted_at": { - "type": ["null", "string"], - "format": "date-time" - }, - "identity": { - "type": ["null", "string"] - }, - "location": { - "type": ["null", "string"] - }, - "page": { - "type": ["null", "string"] - }, - "referrer": { - "type": ["null", "string"] - }, - "user_agent": { - "type": ["null", "string"] - }, - "nudge_id": { - "type": ["null", "integer"] - }, - "nudge_name": { - "type": ["null", "string"] - }, - "anon_visitor_id": { - "type": ["null", "string"] - }, - "ip_address": { - "type": ["null", "string"] - }, - "answered_questions": { - "type": "array", - "items": { - "type": ["null", "object"] - } - }, - "properties": { - "type": ["null", "object"] - }, - "nps": { - "type": ["null", "object"], - "properties": { - "score": { - "type": ["null", "integer"] - }, - "reason": { - "type": ["null", "string"] - }, - "respondent_id": { - "type": ["null", "integer"] - }, - "time": { - "type": ["null", "string"], - "format": "date-time" - }, - "category": { - "type": ["null", "string"] - }, - "response_uri": { - "type": ["null", "string"] - } - } - } - } -} diff --git a/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/schemas/surveys.json b/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/schemas/surveys.json deleted file mode 100644 index dd24014963e6..000000000000 --- a/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/schemas/surveys.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "type": "object", - "properties": { - "id": { - "type": ["null", "integer"] - }, - "site_id": { - "type": ["null", "integer"] - }, - "uuid": { - "type": ["null", "string"] - }, - "name": { - "type": ["null", "string"] - }, - "active": { - "type": ["null", "boolean"] - }, - "kind": { - "type": ["null", "string"] - }, - "canonical_name": { - "type": ["null", "string"] - }, - "created_at": { - "type": ["null", "string"], - "format": "date-time" - }, - "survey_url": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/source.py b/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/source.py deleted file mode 100644 index d9312d834b37..000000000000 --- a/airbyte-integrations/connectors/source-qualaroo/source_qualaroo/source.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource - -""" -This file provides the necessary constructs to interpret a provided declarative YAML configuration file into -source connector. - -WARNING: Do not modify this file. -""" - - -# Declarative Source -class SourceQualaroo(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-qualaroo/unit_tests/test_components.py b/airbyte-integrations/connectors/source-qualaroo/unit_tests/test_components.py deleted file mode 100644 index f34157a71350..000000000000 --- a/airbyte-integrations/connectors/source-qualaroo/unit_tests/test_components.py +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json - -import requests -from source_qualaroo.components import CustomAuthenticator, CustomExtractor - - -def test_token_generation(): - - config = {"key": "4524324", "token": "token"} - authenticator = CustomAuthenticator(config=config, username="example@gmail.com", password="api_key", parameters=None) - token = authenticator.token - expected_token = "Basic ZXhhbXBsZUBnbWFpbC5jb206YXBpX2tleQ==" - assert expected_token == token - - -def test_extract_records_with_answered_questions(): - - response_data = [ - {"id": 1, "answered_questions": {"q1": "A1", "q2": "A2"}}, - {"id": 2, "answered_questions": {"q3": "A3"}}, - ] - response = requests.Response() - response._content = json.dumps(response_data).encode("utf-8") - extracted_records = CustomExtractor().extract_records(response) - expected_records = [{"id": 1, "answered_questions": ["A1", "A2"]}, {"id": 2, "answered_questions": ["A3"]}] - assert expected_records == extracted_records diff --git a/airbyte-integrations/connectors/source-quickbooks/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-quickbooks/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-quickbooks/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-quickbooks/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-quickbooks/main.py b/airbyte-integrations/connectors/source-quickbooks/main.py index abeed13585f5..bce6717c1dc9 100644 --- a/airbyte-integrations/connectors/source-quickbooks/main.py +++ b/airbyte-integrations/connectors/source-quickbooks/main.py @@ -4,5 +4,6 @@ from source_quickbooks.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-quickbooks/metadata.yaml b/airbyte-integrations/connectors/source-quickbooks/metadata.yaml index 14cf457f2b0d..2c714bb9212c 100644 --- a/airbyte-integrations/connectors/source-quickbooks/metadata.yaml +++ b/airbyte-integrations/connectors/source-quickbooks/metadata.yaml @@ -9,7 +9,7 @@ data: baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 connectorType: source definitionId: cf9c4355-b171-4477-8f2d-6c5cc5fc8b7e - dockerImageTag: 3.0.26-rc.1 + dockerImageTag: 3.0.26 dockerRepository: airbyte/source-quickbooks githubIssueLabel: source-quickbooks icon: quickbooks.svg @@ -27,7 +27,7 @@ data: releaseStage: alpha releases: rolloutConfiguration: - enableProgressiveRollout: true + enableProgressiveRollout: false breakingChanges: 3.0.0: message: diff --git a/airbyte-integrations/connectors/source-quickbooks/pyproject.toml b/airbyte-integrations/connectors/source-quickbooks/pyproject.toml index fc136a044f6e..7f310817bd58 100644 --- a/airbyte-integrations/connectors/source-quickbooks/pyproject.toml +++ b/airbyte-integrations/connectors/source-quickbooks/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "3.0.26-rc.1" +version = "3.0.26" name = "source-quickbooks" description = "Source implementation for quickbooks." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-quickbooks/source_quickbooks/source.py b/airbyte-integrations/connectors/source-quickbooks/source_quickbooks/source.py index 644d8d5b227e..77fa08020777 100644 --- a/airbyte-integrations/connectors/source-quickbooks/source_quickbooks/source.py +++ b/airbyte-integrations/connectors/source-quickbooks/source_quickbooks/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-railz/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-railz/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-railz/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-railz/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-railz/main.py b/airbyte-integrations/connectors/source-railz/main.py index bfa6b9fadb2f..ec454b464ed9 100644 --- a/airbyte-integrations/connectors/source-railz/main.py +++ b/airbyte-integrations/connectors/source-railz/main.py @@ -4,5 +4,6 @@ from source_railz.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-railz/metadata.yaml b/airbyte-integrations/connectors/source-railz/metadata.yaml index 541ec796ad88..599b593a41ca 100644 --- a/airbyte-integrations/connectors/source-railz/metadata.yaml +++ b/airbyte-integrations/connectors/source-railz/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 9b6cc0c0-da81-4103-bbfd-5279e18a849a - dockerImageTag: 0.1.18 + dockerImageTag: 0.1.22 dockerRepository: airbyte/source-railz githubIssueLabel: source-railz icon: railz.svg @@ -41,5 +41,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-railz/poetry.lock b/airbyte-integrations/connectors/source-railz/poetry.lock index 07bd7c9e6d5f..5f645aeac28d 100644 --- a/airbyte-integrations/connectors/source-railz/poetry.lock +++ b/airbyte-integrations/connectors/source-railz/poetry.lock @@ -42,13 +42,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] @@ -56,24 +56,24 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -88,19 +88,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -166,13 +166,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -256,116 +256,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -435,20 +422,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -512,13 +499,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -533,13 +520,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -547,7 +534,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -597,13 +583,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -693,22 +679,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -781,69 +770,86 @@ files = [ [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -946,54 +952,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -1005,13 +1011,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1299,33 +1305,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1422,81 +1428,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-railz/pyproject.toml b/airbyte-integrations/connectors/source-railz/pyproject.toml index cc0554cbf1aa..beaae1e1c2d1 100644 --- a/airbyte-integrations/connectors/source-railz/pyproject.toml +++ b/airbyte-integrations/connectors/source-railz/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.18" +version = "0.1.22" name = "source-railz" description = "Source implementation for Railz." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-railz/source_railz/components.py b/airbyte-integrations/connectors/source-railz/source_railz/components.py index 36a9351f859d..c7c4ef88a467 100644 --- a/airbyte-integrations/connectors/source-railz/source_railz/components.py +++ b/airbyte-integrations/connectors/source-railz/source_railz/components.py @@ -8,6 +8,8 @@ from typing import Any, Iterable, Mapping, Optional, Union import requests +from isodate import Duration, parse_duration + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator from airbyte_cdk.sources.declarative.auth.token import BasicHttpAuthenticator @@ -15,7 +17,6 @@ from airbyte_cdk.sources.declarative.stream_slicers import CartesianProductStreamSlicer from airbyte_cdk.sources.declarative.types import Config, Record, StreamSlice from airbyte_cdk.sources.streams.http.requests_native_auth.abstract_token import AbstractHeaderAuthenticator -from isodate import Duration, parse_duration @dataclass diff --git a/airbyte-integrations/connectors/source-railz/source_railz/run.py b/airbyte-integrations/connectors/source-railz/source_railz/run.py index 831b665a05da..92d5008017b4 100644 --- a/airbyte-integrations/connectors/source-railz/source_railz/run.py +++ b/airbyte-integrations/connectors/source-railz/source_railz/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_railz import SourceRailz +from airbyte_cdk.entrypoint import launch + def run(): source = SourceRailz() diff --git a/airbyte-integrations/connectors/source-railz/source_railz/source.py b/airbyte-integrations/connectors/source-railz/source_railz/source.py index d5c9010ae224..642ebb4eb236 100644 --- a/airbyte-integrations/connectors/source-railz/source_railz/source.py +++ b/airbyte-integrations/connectors/source-railz/source_railz/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-rd-station-marketing/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-rd-station-marketing/integration_tests/acceptance.py index efc25f08ce82..78b220cebb18 100644 --- a/airbyte-integrations/connectors/source-rd-station-marketing/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-rd-station-marketing/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-rd-station-marketing/metadata.yaml b/airbyte-integrations/connectors/source-rd-station-marketing/metadata.yaml index 60774f9fcdae..33681009f9c8 100644 --- a/airbyte-integrations/connectors/source-rd-station-marketing/metadata.yaml +++ b/airbyte-integrations/connectors/source-rd-station-marketing/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: fb141f29-be2a-450b-a4f2-2cd203a00f84 - dockerImageTag: 0.3.3 + dockerImageTag: 0.3.8 dockerRepository: airbyte/source-rd-station-marketing githubIssueLabel: source-rd-station-marketing icon: rdstation.svg @@ -36,5 +36,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-recharge/acceptance-test-config.yml b/airbyte-integrations/connectors/source-recharge/acceptance-test-config.yml index 9640b3668c92..cbaea3144849 100644 --- a/airbyte-integrations/connectors/source-recharge/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-recharge/acceptance-test-config.yml @@ -9,6 +9,10 @@ acceptance_tests: bypass_reason: "The stream is tested with `Integration Tests`, since no data is available" - name: onetimes bypass_reason: "The stream is tested with `Integration Tests`, since no data is available" + - name: events + bypass_reason: "The stream is tested with `Integration Tests`, since no data is available" + - name: bundle_selections + bypass_reason: "The stream is tested with `Integration Tests`, since no data is available" - name: shop bypass_reason: "The stream is not empty, but the primary key is the entire record, so it is constantly changing" expect_records: @@ -21,6 +25,10 @@ acceptance_tests: bypass_reason: "The stream is tested with `Integration Tests`, since no data is available" - name: onetimes bypass_reason: "The stream is tested with `Integration Tests`, since no data is available" + - name: events + bypass_reason: "The stream is tested with `Integration Tests`, since no data is available" + - name: bundle_selections + bypass_reason: "The stream is tested with `Integration Tests`, since no data is available" - name: shop bypass_reason: "The stream is not empty, but the primary key is the entire record, so it is constantly changing" expect_records: diff --git a/airbyte-integrations/connectors/source-recharge/integration_tests/abnormal_state.json b/airbyte-integrations/connectors/source-recharge/integration_tests/abnormal_state.json index 9def67c7e481..bef7bce52ee0 100644 --- a/airbyte-integrations/connectors/source-recharge/integration_tests/abnormal_state.json +++ b/airbyte-integrations/connectors/source-recharge/integration_tests/abnormal_state.json @@ -47,5 +47,19 @@ "stream_state": { "updated_at": "2050-05-18T00:00:00Z" }, "stream_descriptor": { "name": "subscriptions" } } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "created_at": "2050-05-18T00:00:00Z" }, + "stream_descriptor": { "name": "events" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "updated_at": "2050-05-18T00:00:00Z" }, + "stream_descriptor": { "name": "bundle_selections" } + } } ] diff --git a/airbyte-integrations/connectors/source-recharge/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-recharge/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-recharge/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-recharge/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-recharge/integration_tests/configured_catalog.json b/airbyte-integrations/connectors/source-recharge/integration_tests/configured_catalog.json index 15779454cc1c..d30546acb617 100644 --- a/airbyte-integrations/connectors/source-recharge/integration_tests/configured_catalog.json +++ b/airbyte-integrations/connectors/source-recharge/integration_tests/configured_catalog.json @@ -1,5 +1,18 @@ { "streams": [ + { + "stream": { + "name": "events", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["created_at"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "destination_sync_mode": "append", + "cursor_field": ["created_at"] + }, { "stream": { "name": "subscriptions", @@ -130,6 +143,19 @@ }, "sync_mode": "full_refresh", "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "bundle_selections", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated_at"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "destination_sync_mode": "append", + "cursor_field": ["updated_at"] } ] } diff --git a/airbyte-integrations/connectors/source-recharge/integration_tests/streams_with_output_records_catalog.json b/airbyte-integrations/connectors/source-recharge/integration_tests/streams_with_output_records_catalog.json index e661526835d4..41696ba5b2f7 100644 --- a/airbyte-integrations/connectors/source-recharge/integration_tests/streams_with_output_records_catalog.json +++ b/airbyte-integrations/connectors/source-recharge/integration_tests/streams_with_output_records_catalog.json @@ -108,6 +108,19 @@ "destination_sync_mode": "append", "cursor_field": ["updated_at"] }, + { + "stream": { + "name": "events", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["created_at"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "destination_sync_mode": "append", + "cursor_field": ["created_at"] + }, { "stream": { "name": "metafields", @@ -117,6 +130,19 @@ }, "sync_mode": "full_refresh", "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "bundle_selections", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated_at"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "destination_sync_mode": "append", + "cursor_field": ["updated_at"] } ] } diff --git a/airbyte-integrations/connectors/source-recharge/main.py b/airbyte-integrations/connectors/source-recharge/main.py index d8ccf40b711e..5f5e6b67eed1 100644 --- a/airbyte-integrations/connectors/source-recharge/main.py +++ b/airbyte-integrations/connectors/source-recharge/main.py @@ -4,5 +4,6 @@ from source_recharge.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-recharge/metadata.yaml b/airbyte-integrations/connectors/source-recharge/metadata.yaml index cf7331178e17..d8ef9aa3110b 100644 --- a/airbyte-integrations/connectors/source-recharge/metadata.yaml +++ b/airbyte-integrations/connectors/source-recharge/metadata.yaml @@ -5,9 +5,9 @@ data: connectorSubtype: api connectorType: source connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 definitionId: 45d2e135-2ede-49e1-939f-3e3ec357a65e - dockerImageTag: 2.4.14 + dockerImageTag: 2.6.0 dockerRepository: airbyte/source-recharge githubIssueLabel: source-recharge icon: recharge.svg diff --git a/airbyte-integrations/connectors/source-recharge/poetry.lock b/airbyte-integrations/connectors/source-recharge/poetry.lock index 85ebd0d56886..1934571725f2 100644 --- a/airbyte-integrations/connectors/source-recharge/poetry.lock +++ b/airbyte-integrations/connectors/source-recharge/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "airbyte-cdk" @@ -69,24 +69,24 @@ files = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.8.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a"}, + {file = "anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -101,19 +101,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -179,13 +179,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -269,127 +269,114 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -462,20 +449,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -539,13 +526,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -560,13 +547,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -574,7 +561,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -624,13 +610,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -731,22 +717,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -844,69 +833,86 @@ twitter = ["twython"] [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -1009,19 +1015,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1029,100 +1035,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -1130,13 +1147,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1342,105 +1359,105 @@ files = [ [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -1527,33 +1544,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.7.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.7.0-py3-none-any.whl", hash = "sha256:84fb203f278ebcf5cd08f97d3fb96d3fbed4b629d500b29ad60d11e00769b183"}, + {file = "setuptools-75.7.0.tar.gz", hash = "sha256:886ff7b16cd342f1d1defc16fc98c9ce3fde69e087a4e1983d7ab634e5f41f4f"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.8.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.14.*)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1595,20 +1612,21 @@ files = [ [[package]] name = "tqdm" -version = "4.66.6" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63"}, - {file = "tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -1640,13 +1658,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1671,81 +1689,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-recharge/pyproject.toml b/airbyte-integrations/connectors/source-recharge/pyproject.toml index f2fc34540a9b..29a33b814921 100644 --- a/airbyte-integrations/connectors/source-recharge/pyproject.toml +++ b/airbyte-integrations/connectors/source-recharge/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "2.4.14" +version = "2.6.0" name = "source-recharge" description = "Source implementation for Recharge." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-recharge/sample_files/sample_state.json b/airbyte-integrations/connectors/source-recharge/sample_files/sample_state.json index f667a07e67b9..7993da59a6a2 100644 --- a/airbyte-integrations/connectors/source-recharge/sample_files/sample_state.json +++ b/airbyte-integrations/connectors/source-recharge/sample_files/sample_state.json @@ -19,5 +19,11 @@ }, "subscriptions": { "updated_at": "2021-04-02T00:00:00" + }, + "events": { + "created_at": "2021-04-02T00:00:00" + }, + "bundle_selections": { + "updated_at": "2021-04-02T00:00:00" } } diff --git a/airbyte-integrations/connectors/source-recharge/source_recharge/components/recharge_error_handler.py b/airbyte-integrations/connectors/source-recharge/source_recharge/components/recharge_error_handler.py index 80d19ac2eca2..d89d6281908c 100644 --- a/airbyte-integrations/connectors/source-recharge/source_recharge/components/recharge_error_handler.py +++ b/airbyte-integrations/connectors/source-recharge/source_recharge/components/recharge_error_handler.py @@ -5,9 +5,10 @@ import logging from typing import Optional, Union +from requests import Response + from airbyte_cdk.sources.streams.http.error_handlers import HttpStatusErrorHandler from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, FailureType, ResponseAction -from requests import Response class RechargeErrorHandler(HttpStatusErrorHandler): @@ -16,7 +17,6 @@ def __init__(self, logger: logging.Logger) -> None: super().__init__(logger=logger) def interpret_response(self, response_or_exception: Optional[Union[Response, Exception]] = None) -> ErrorResolution: - if isinstance(response_or_exception, Response): content_length = int(response_or_exception.headers.get("Content-Length", 0)) incomplete_data_response = response_or_exception.status_code == 200 and content_length > len(response_or_exception.content) diff --git a/airbyte-integrations/connectors/source-recharge/source_recharge/manifest.yaml b/airbyte-integrations/connectors/source-recharge/source_recharge/manifest.yaml index d3938e05caf0..2f6762ec4af9 100644 --- a/airbyte-integrations/connectors/source-recharge/source_recharge/manifest.yaml +++ b/airbyte-integrations/connectors/source-recharge/source_recharge/manifest.yaml @@ -153,6 +153,23 @@ definitions: type: RequestOption field_name: "updated_at_min" inject_into: request_parameter + base_incremental_events_stream: + $ref: "#/definitions/base_modern_api_stream" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + - "%Y-%m-%dT%H:%M:%S" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: "created_at_min" + inject_into: request_parameter # FULL-REFRESH STREAMS # COLLECTIONS @@ -256,6 +273,21 @@ definitions: $parameters: name: "subscriptions" data_path: "subscriptions" + events_stream: + description: >- + Events Stream: https://developer.rechargepayments.com/2021-11/events/events_list + $ref: "#/definitions/base_incremental_events_stream" + $parameters: + name: "events" + data_path: "events" + # BUNDLE SELECTIONS + bundle_selections_stream: + description: >- + Bundle Selections Stream: https://developer.rechargepayments.com/2021-11/bundle_selections/bundle_selection_list + $ref: "#/definitions/base_incremental_stream" + $parameters: + name: "bundle_selections" + data_path: "bundle_selections" streams: - "#/definitions/addresses_stream" @@ -268,6 +300,8 @@ streams: - "#/definitions/products_stream" - "#/definitions/shop_stream" - "#/definitions/subscriptions_stream" + - "#/definitions/events_stream" + - "#/definitions/bundle_selections_stream" # The `orders` stream remains implemented in `streams.py` due to: # 1. Inability to resolve `$ref` conditionally # 2. Inability to dynamically switch between paginators (diff api versions, require diff pagination approach) (or create the CustomPaginator component) diff --git a/airbyte-integrations/connectors/source-recharge/source_recharge/schemas/bundle_selections.json b/airbyte-integrations/connectors/source-recharge/source_recharge/schemas/bundle_selections.json new file mode 100644 index 000000000000..4b802543cc47 --- /dev/null +++ b/airbyte-integrations/connectors/source-recharge/source_recharge/schemas/bundle_selections.json @@ -0,0 +1,66 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "id": { + "type": ["integer"] + }, + "bundle_variant": { + "type": ["integer"] + }, + "purchase_item_id": { + "type": ["integer"] + }, + "created_at": { + "type": ["string"], + "format": "date-time" + }, + "external_product_id": { + "type": ["string"] + }, + "external_variant_id": { + "type": ["string"] + }, + "items": { + "type": ["array"], + "items": { + "type": ["object"], + "properties": { + "id": { + "type": ["integer"] + }, + "collection_id": { + "type": ["string"] + }, + "collection_source": { + "type": ["string"] + }, + "created_at": { + "type": ["string"], + "format": "date-time" + }, + "external_product_id": { + "type": ["string"] + }, + "external_variant_id": { + "type": ["string"] + }, + "price": { + "type": ["string"] + }, + "quantity": { + "type": ["integer"] + }, + "updated_at": { + "type": ["string"], + "format": "date-time" + } + } + } + }, + "updated_at": { + "type": ["string"], + "format": "date-time" + } + } +} diff --git a/airbyte-integrations/connectors/source-recharge/source_recharge/schemas/events.json b/airbyte-integrations/connectors/source-recharge/source_recharge/schemas/events.json new file mode 100644 index 000000000000..4bd3ae8d5a78 --- /dev/null +++ b/airbyte-integrations/connectors/source-recharge/source_recharge/schemas/events.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "id": { + "type": ["null", "integer"] + }, + "customer_id": { + "type": ["null", "integer"] + }, + "object_id": { + "type": ["null", "integer"] + }, + "created_at": { + "type": ["null", "string"], + "format": "date-time" + }, + "custom_attributes": { + "type": ["null", "array"] + }, + "description": { + "type": ["null", "string"] + }, + "object_type": { + "type": ["null", "string"] + }, + "source": { + "type": ["null", "object"], + "properties": { + "account_id": { + "type": ["null", "integer"] + }, + "api_token_id": { + "type": ["null", "integer"] + }, + "account_email": { + "type": ["null", "string"] + }, + "api_token_name": { + "type": ["null", "string"] + }, + "origin": { + "type": ["null", "string"] + }, + "user_type": { + "type": ["null", "string"] + } + } + }, + "updated_attributes": { + "type": ["null", "array"] + }, + "verb": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-recharge/source_recharge/source.py b/airbyte-integrations/connectors/source-recharge/source_recharge/source.py index be0b9d43509d..e2aa51028f59 100644 --- a/airbyte-integrations/connectors/source-recharge/source_recharge/source.py +++ b/airbyte-integrations/connectors/source-recharge/source_recharge/source.py @@ -9,6 +9,7 @@ from airbyte_cdk.sources.streams import Stream from source_recharge.streams import Orders, RechargeTokenAuthenticator + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-recharge/source_recharge/streams.py b/airbyte-integrations/connectors/source-recharge/source_recharge/streams.py index 39b44c35cf3d..be01b454fa1c 100644 --- a/airbyte-integrations/connectors/source-recharge/source_recharge/streams.py +++ b/airbyte-integrations/connectors/source-recharge/source_recharge/streams.py @@ -8,6 +8,7 @@ import pendulum import requests + from airbyte_cdk.sources.streams.http import HttpStream from airbyte_cdk.sources.streams.http.error_handlers import ErrorHandler from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator diff --git a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/config.py b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/config.py index 3581ace5712d..a014169b9c07 100644 --- a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/config.py +++ b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/config.py @@ -10,6 +10,7 @@ import pendulum + START_DATE = "2023-01-01T00:00:00Z" ACCESS_TOKEN = "test_access_token" DATE_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S%z" diff --git a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/pagination.py b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/pagination.py index 4522eec9675e..cb3c13212c37 100644 --- a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/pagination.py +++ b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/pagination.py @@ -8,6 +8,7 @@ from airbyte_cdk.test.mock_http.request import HttpRequest from airbyte_cdk.test.mock_http.response_builder import PaginationStrategy + NEXT_PAGE_TOKEN = "New_Next_Page_Token" diff --git a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/request_builder.py b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/request_builder.py index cc7c51dfa307..cebf1c676549 100644 --- a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/request_builder.py +++ b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/request_builder.py @@ -48,6 +48,10 @@ def with_old_api_version(self, api_version: str) -> RequestBuilder: self._headers["X-Recharge-Version"] = api_version return self + def with_created_min(self, value: str) -> RequestBuilder: + self._query_params["created_at_min"] = dt.datetime.strptime(value, DATE_TIME_FORMAT).strftime(DATE_TIME_FORMAT) + return self + def build(self) -> HttpRequest: return HttpRequest( url=f"https://api.rechargeapps.com/{self._endpoint}", diff --git a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_bundle_selections.py b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_bundle_selections.py new file mode 100644 index 000000000000..4bfa88ffc5ea --- /dev/null +++ b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_bundle_selections.py @@ -0,0 +1,88 @@ +# +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. +# + + +from unittest import TestCase + +import freezegun + +from airbyte_cdk.test.mock_http import HttpMocker + +from ..config import NOW, START_DATE +from ..response_builder import NEXT_PAGE_TOKEN, get_stream_record, get_stream_response +from ..utils import StreamTestCase, config, get_cursor_value_from_state_message, read_full_refresh, read_incremental + + +_STREAM_NAME = "bundle_selections" +_CURSOR_FIELD = "updated_at" + + +@freezegun.freeze_time(NOW.isoformat()) +class TestFullRefresh(StreamTestCase): + _STREAM_NAME = "bundle_selections" + + @HttpMocker() + def test_given_one_page_when_read_then_return_records(self, http_mocker: HttpMocker) -> None: + http_mocker.get( + self.stream_request().with_limit(250).with_updated_at_min(START_DATE).build(), + get_stream_response(_STREAM_NAME).with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD)).build(), + ) + output = read_full_refresh(self._config, _STREAM_NAME) + assert len(output.records) == 1 + + @HttpMocker() + def test_given_multiple_pages_when_read_then_return_records(self, http_mocker: HttpMocker) -> None: + http_mocker.get( + self.stream_request().with_limit(250).with_next_page_token(NEXT_PAGE_TOKEN).build(), + get_stream_response(_STREAM_NAME).with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD)).build(), + ) + http_mocker.get( + self.stream_request().with_limit(250).with_updated_at_min(START_DATE).build(), + get_stream_response(_STREAM_NAME).with_pagination().with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD)).build(), + ) + + output = read_full_refresh(self._config, _STREAM_NAME) + assert len(output.records) == 2 + + +@freezegun.freeze_time(NOW.isoformat()) +class TestIncremental(StreamTestCase): + _STREAM_NAME = "bundle_selections" + + @HttpMocker() + def test_state_message_produced_while_read_and_state_match_latest_record(self, http_mocker: HttpMocker) -> None: + min_cursor_value = "2024-01-01T00:00:00+00:00" + max_cursor_value = "2024-02-01T00:00:00+00:00" + + http_mocker.get( + self.stream_request().with_limit(250).with_updated_at_min(START_DATE).build(), + get_stream_response(_STREAM_NAME) + .with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD).with_cursor(min_cursor_value)) + .with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD).with_cursor(max_cursor_value)) + .build(), + ) + + output = read_incremental(self._config, _STREAM_NAME) + test_cursor_value = get_cursor_value_from_state_message(output, _CURSOR_FIELD) + assert test_cursor_value == max_cursor_value + + @HttpMocker() + def test_given_multiple_pages_when_read_then_return_records_with_state(self, http_mocker: HttpMocker) -> None: + min_cursor_value = "2024-01-01T00:00:00+00:00" + max_cursor_value = "2024-02-01T00:00:00+00:00" + http_mocker.get( + self.stream_request().with_limit(250).with_next_page_token(NEXT_PAGE_TOKEN).build(), + get_stream_response(_STREAM_NAME).with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD)).build(), + ) + http_mocker.get( + self.stream_request().with_limit(250).with_updated_at_min(START_DATE).build(), + get_stream_response(_STREAM_NAME) + .with_pagination() + .with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD).with_cursor(min_cursor_value)) + .with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD).with_cursor(max_cursor_value)) + .build(), + ) + + output = read_incremental(self._config, _STREAM_NAME) + assert len(output.records) == 3 diff --git a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_collections.py b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_collections.py index 91ebbbcb26e6..b6055873bc81 100644 --- a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_collections.py +++ b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_collections.py @@ -5,12 +5,14 @@ from unittest import TestCase import freezegun + from airbyte_cdk.test.mock_http import HttpMocker from ..config import NOW from ..response_builder import NEXT_PAGE_TOKEN, get_stream_record, get_stream_response from ..utils import StreamTestCase, config, read_full_refresh + _STREAM_NAME = "collections" diff --git a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_discounts.py b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_discounts.py index 906fb220c3fc..430a27d2a0ce 100644 --- a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_discounts.py +++ b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_discounts.py @@ -6,12 +6,14 @@ from unittest import TestCase import freezegun + from airbyte_cdk.test.mock_http import HttpMocker from ..config import NOW, START_DATE from ..response_builder import NEXT_PAGE_TOKEN, get_stream_record, get_stream_response from ..utils import StreamTestCase, config, get_cursor_value_from_state_message, read_full_refresh, read_incremental + _STREAM_NAME = "discounts" _CURSOR_FIELD = "updated_at" @@ -31,7 +33,6 @@ def test_given_one_page_when_read_then_return_records(self, http_mocker: HttpMoc @HttpMocker() def test_given_multiple_pages_when_read_then_return_records(self, http_mocker: HttpMocker) -> None: - http_mocker.get( self.stream_request().with_limit(250).with_next_page_token(NEXT_PAGE_TOKEN).build(), get_stream_response(_STREAM_NAME).with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD)).build(), diff --git a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_events.py b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_events.py new file mode 100644 index 000000000000..4093fba40a02 --- /dev/null +++ b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_events.py @@ -0,0 +1,89 @@ +# +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. +# + + +from unittest import TestCase + +import freezegun + +from airbyte_cdk.test.mock_http import HttpMocker + +from ..config import NOW, START_DATE +from ..response_builder import NEXT_PAGE_TOKEN, get_stream_record, get_stream_response +from ..utils import StreamTestCase, config, get_cursor_value_from_state_message, read_full_refresh, read_incremental + + +_STREAM_NAME = "events" +_CURSOR_FIELD = "created_at" + + +@freezegun.freeze_time(NOW.isoformat()) +class TestFullRefresh(StreamTestCase): + _STREAM_NAME = "events" + + @HttpMocker() + def test_given_one_page_when_read_then_return_records(self, http_mocker: HttpMocker) -> None: + req = self.stream_request().with_limit(250).with_created_min(START_DATE).build() + http_mocker.get( + req, + get_stream_response(_STREAM_NAME).with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD)).build(), + ) + output = read_full_refresh(self._config, _STREAM_NAME) + assert len(output.records) == 1 + + @HttpMocker() + def test_given_multiple_pages_when_read_then_return_records(self, http_mocker: HttpMocker) -> None: + http_mocker.get( + self.stream_request().with_limit(250).with_next_page_token(NEXT_PAGE_TOKEN).build(), + get_stream_response(_STREAM_NAME).with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD)).build(), + ) + http_mocker.get( + self.stream_request().with_limit(250).with_created_min(START_DATE).build(), + get_stream_response(_STREAM_NAME).with_pagination().with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD)).build(), + ) + + output = read_full_refresh(self._config, _STREAM_NAME) + assert len(output.records) == 2 + + +@freezegun.freeze_time(NOW.isoformat()) +class TestIncremental(StreamTestCase): + _STREAM_NAME = "events" + + @HttpMocker() + def test_state_message_produced_while_read_and_state_match_latest_record(self, http_mocker: HttpMocker) -> None: + min_cursor_value = "2024-01-01T00:00:00+00:00" + max_cursor_value = "2024-02-01T00:00:00+00:00" + + http_mocker.get( + self.stream_request().with_limit(250).with_created_min(START_DATE).build(), + get_stream_response(_STREAM_NAME) + .with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD).with_cursor(min_cursor_value)) + .with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD).with_cursor(max_cursor_value)) + .build(), + ) + + output = read_incremental(self._config, _STREAM_NAME) + test_cursor_value = get_cursor_value_from_state_message(output, _CURSOR_FIELD) + assert test_cursor_value == max_cursor_value + + @HttpMocker() + def test_given_multiple_pages_when_read_then_return_records_with_state(self, http_mocker: HttpMocker) -> None: + min_cursor_value = "2024-01-01T00:00:00+00:00" + max_cursor_value = "2024-02-01T00:00:00+00:00" + http_mocker.get( + self.stream_request().with_limit(250).with_next_page_token(NEXT_PAGE_TOKEN).build(), + get_stream_response(_STREAM_NAME).with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD)).build(), + ) + http_mocker.get( + self.stream_request().with_limit(250).with_created_min(START_DATE).build(), + get_stream_response(_STREAM_NAME) + .with_pagination() + .with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD).with_cursor(min_cursor_value)) + .with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD).with_cursor(max_cursor_value)) + .build(), + ) + + output = read_incremental(self._config, _STREAM_NAME) + assert len(output.records) == 3 diff --git a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_onetimes.py b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_onetimes.py index 713678584e21..64255813f503 100644 --- a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_onetimes.py +++ b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_onetimes.py @@ -6,12 +6,14 @@ from unittest import TestCase import freezegun + from airbyte_cdk.test.mock_http import HttpMocker from ..config import NOW, START_DATE from ..response_builder import NEXT_PAGE_TOKEN, get_stream_record, get_stream_response from ..utils import StreamTestCase, config, get_cursor_value_from_state_message, read_full_refresh, read_incremental + _STREAM_NAME = "onetimes" _CURSOR_FIELD = "updated_at" @@ -31,7 +33,6 @@ def test_given_one_page_when_read_then_return_records(self, http_mocker: HttpMoc @HttpMocker() def test_given_multiple_pages_when_read_then_return_records(self, http_mocker: HttpMocker) -> None: - http_mocker.get( self.stream_request().with_limit(250).with_next_page_token(NEXT_PAGE_TOKEN).build(), get_stream_response(_STREAM_NAME).with_record(get_stream_record(_STREAM_NAME, "id", _CURSOR_FIELD)).build(), diff --git a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_shop.py b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_shop.py index 3970bf63fad1..0991a86f1d9b 100644 --- a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_shop.py +++ b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/streams/test_shop.py @@ -6,12 +6,14 @@ from unittest import TestCase import freezegun + from airbyte_cdk.test.mock_http import HttpMocker, HttpResponse from airbyte_cdk.test.mock_http.response_builder import find_template from ..config import NOW from ..utils import StreamTestCase, read_full_refresh + _STREAM_NAME = "shop" diff --git a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/utils.py b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/utils.py index 3da0b1d06775..475f8d95ee1d 100644 --- a/airbyte-integrations/connectors/source-recharge/unit_tests/integration/utils.py +++ b/airbyte-integrations/connectors/source-recharge/unit_tests/integration/utils.py @@ -8,10 +8,11 @@ from typing import Any, List, Mapping, Optional from unittest import TestCase +from source_recharge import SourceRecharge + from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read from airbyte_protocol.models import AirbyteStateMessage, ConfiguredAirbyteCatalog, SyncMode -from source_recharge import SourceRecharge from .config import ConfigBuilder from .request_builder import RequestBuilder diff --git a/airbyte-integrations/connectors/source-recharge/unit_tests/resource/http/response/bundle_selections.json b/airbyte-integrations/connectors/source-recharge/unit_tests/resource/http/response/bundle_selections.json new file mode 100644 index 000000000000..f75bd3ffed5e --- /dev/null +++ b/airbyte-integrations/connectors/source-recharge/unit_tests/resource/http/response/bundle_selections.json @@ -0,0 +1,89 @@ +{ + "next_cursor": null, + "previous_cursor": null, + "bundle_selections": [ + { + "id": 1, + "bundle_variant_id": 1, + "charge_id": null, + "order_id": null, + "purchase_item_id": 1, + "created_at": "2024-12-09T08:11:01+00:00", + "external_product_id": "1234567890123", + "external_variant_id": "12345", + "is_fallback": false, + "items": [ + { + "id": 1, + "collection_id": "2", + "collection_source": "test", + "created_at": "2024-12-09T08:11:01+00:00", + "external_product_id": "1", + "external_variant_id": "2", + "price": "10.00", + "quantity": 1, + "updated_at": "2024-12-09T08:11:01+00:00" + }, + { + "id": 2, + "collection_id": "2", + "collection_source": "test", + "created_at": "2024-12-09T08:11:01+00:00", + "external_product_id": "7625137913910", + "external_variant_id": "42941000745014", + "price": "11.00", + "quantity": 1, + "updated_at": "2024-12-09T08:11:01+00:00" + }, + { + "id": 3, + "collection_id": "1", + "collection_source": "test", + "created_at": "2024-12-09T08:11:01+00:00", + "external_product_id": "1", + "external_variant_id": "2", + "price": "12.00", + "quantity": 2, + "updated_at": "2024-12-09T08:11:01+00:00" + }, + { + "id": 4, + "collection_id": "3", + "collection_source": "test", + "created_at": "2024-12-09T08:11:01+00:00", + "external_product_id": "4", + "external_variant_id": "2", + "price": "13.00", + "quantity": 2, + "updated_at": "2024-12-09T08:11:01+00:00" + } + ], + "updated_at": "2024-12-09T08:11:01+00:00" + }, + { + "id": 2, + "bundle_variant_id": 3, + "charge_id": null, + "order_id": null, + "purchase_item_id": 4, + "created_at": "2024-12-09T08:08:34+00:00", + "external_product_id": "1", + "external_variant_id": "2", + "is_fallback": false, + "items": [ + { + "id": 6, + "collection_id": "4", + "collection_source": "test", + "created_at": "2024-12-09T08:08:34+00:00", + "external_product_id": "2", + "external_variant_id": "5", + "price": "14.00", + "quantity": 1, + "updated_at": "2024-12-09T08:08:34+00:00" + } + ], + "updated_at": "2024-12-09T08:08:34+00:00" + } + ] +} diff --git a/airbyte-integrations/connectors/source-recharge/unit_tests/resource/http/response/events.json b/airbyte-integrations/connectors/source-recharge/unit_tests/resource/http/response/events.json new file mode 100644 index 000000000000..17708af0c590 --- /dev/null +++ b/airbyte-integrations/connectors/source-recharge/unit_tests/resource/http/response/events.json @@ -0,0 +1,63 @@ +{ + "next_cursor": null, + "previous_cursor": null, + "events": [ + { + "id": 1, + "customer_id": 1, + "object_id": 1, + "created_at": "2024-10-28T12:56:16", + "custom_attributes": [], + "description": "Cancelled subscription for Something from Customer", + "object_type": "subscription", + "source": { + "account_id": null, + "api_token_id": null, + "account_email": null, + "api_token_name": null, + "origin": null, + "user_type": null + }, + "updated_attributes": [], + "verb": "cancelled" + }, + { + "id": 2, + "customer_id": 2, + "object_id": 2, + "created_at": "2024-10-28T14:41:32", + "custom_attributes": [], + "description": "Deleted charge #2", + "object_type": "charge", + "source": { + "account_id": null, + "api_token_id": null, + "account_email": null, + "api_token_name": null, + "origin": "somewhere", + "user_type": "customer" + }, + "updated_attributes": [], + "verb": "deleted" + }, + { + "id": 3, + "customer_id": 3, + "object_id": 3, + "created_at": "2024-10-28T15:41:02", + "custom_attributes": [], + "description": "Failed charge #3", + "object_type": "charge", + "source": { + "account_id": null, + "api_token_id": null, + "account_email": null, + "api_token_name": null, + "origin": "api", + "user_type": null + }, + "updated_attributes": [], + "verb": "failed" + } + ] +} diff --git a/airbyte-integrations/connectors/source-recharge/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-recharge/unit_tests/test_streams.py index ce44c9bfcdfa..0256854c882b 100644 --- a/airbyte-integrations/connectors/source-recharge/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-recharge/unit_tests/test_streams.py @@ -8,9 +8,10 @@ import pytest import requests -from airbyte_cdk.sources.streams.http.error_handlers.response_models import ResponseAction from source_recharge.source import Orders, RechargeTokenAuthenticator, SourceRecharge +from airbyte_cdk.sources.streams.http.error_handlers.response_models import ResponseAction + def use_orders_deprecated_api_config( config: Mapping[str, Any] = None, @@ -30,7 +31,7 @@ def test_get_auth_header(config) -> None: def test_streams(config) -> None: streams = SourceRecharge().streams(config) - assert len(streams) == 11 + assert len(streams) == 13 class TestCommon: @@ -88,6 +89,7 @@ def test_should_retry(self, config, http_status, headers, expected_action) -> No error_resolution = stream.get_error_handler().interpret_response(response) error_resolution.response_action == expected_action + class TestFullRefreshStreams: def generate_records(self, stream_name, count) -> Union[Mapping[str, List[Mapping[str, Any]]], Mapping[str, Any]]: if not stream_name: diff --git a/airbyte-integrations/connectors/source-recreation/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-recreation/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-recreation/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-recreation/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-recreation/metadata.yaml b/airbyte-integrations/connectors/source-recreation/metadata.yaml index 1054d6889260..da7666d7daeb 100644 --- a/airbyte-integrations/connectors/source-recreation/metadata.yaml +++ b/airbyte-integrations/connectors/source-recreation/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 25d7535d-91e0-466a-aa7f-af81578be277 - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-recreation documentationUrl: https://docs.airbyte.com/integrations/sources/recreation githubIssueLabel: source-recreation diff --git a/airbyte-integrations/connectors/source-recruitee/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-recruitee/integration_tests/acceptance.py index efc25f08ce82..78b220cebb18 100644 --- a/airbyte-integrations/connectors/source-recruitee/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-recruitee/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-recruitee/metadata.yaml b/airbyte-integrations/connectors/source-recruitee/metadata.yaml index b3d678329a62..eff8391fb972 100644 --- a/airbyte-integrations/connectors/source-recruitee/metadata.yaml +++ b/airbyte-integrations/connectors/source-recruitee/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 3b046ac7-d8d3-4eb3-b122-f96b2a16d8a8 - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-recruitee githubIssueLabel: source-recruitee icon: recruitee.svg @@ -39,5 +39,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-recurly/README.md b/airbyte-integrations/connectors/source-recurly/README.md index 240ca632a261..74b62d4a3653 100644 --- a/airbyte-integrations/connectors/source-recurly/README.md +++ b/airbyte-integrations/connectors/source-recurly/README.md @@ -1,52 +1,22 @@ # Recurly source connector -This is the repository for the Recurly configuration based source connector. -For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.io/integrations/sources/recurly). +This directory contains the manifest-only connector for `source-recurly`. +This _manifest-only_ connector is not a Python package on its own, as it runs inside of the base `source-declarative-manifest` image. -## Local development - -### Prerequisites - -- Python (~=3.9) -- Poetry (~=1.7) - installation instructions [here](https://python-poetry.org/docs/#installation) - -### Installing the connector - -From this connector directory, run: - -```bash -poetry install --with dev -``` - -### Creating credentials - -**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.io/integrations/sources/recurly) -to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_recurly/spec.json` file. -Note that the `secrets` directory is gitignored by default, so there is no danger of accidentally checking in sensitive information. -See `integration_tests/sample_config.json` for a sample config file. - -**If you are an Airbyte core member**, copy the credentials in Lastpass under the secret name `source recurly test creds` -and place them into `secrets/config.json`. - -### Locally running the connector - -```bash -poetry run source-recurly spec -poetry run source-recurly check --config secrets/config.json -poetry run source-recurly discover --config secrets/config.json -poetry run source-recurly read --config secrets/config.json --catalog integration_tests/configured_catalog.json -``` +For information about how to configure and use this connector within Airbyte, see [the connector's full documentation](https://docs.airbyte.com/integrations/sources/recurly). -### Running unit tests +## Local development -To run unit tests locally, from the connector directory run: +We recommend using the Connector Builder to edit this connector. +Using either Airbyte Cloud or your local Airbyte OSS instance, navigate to the **Builder** tab and select **Import a YAML**. +Then select the connector's `manifest.yaml` file to load the connector into the Builder. You're now ready to make changes to the connector! -```bash -poetry run pytest unit_tests -``` +If you prefer to develop locally, you can follow the instructions below. ### Building the docker image +You can build any manifest-only connector with `airbyte-ci`: + 1. Install [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md) 2. Run the following command to build the docker image: @@ -56,9 +26,15 @@ airbyte-ci connectors --name=source-recurly build An image will be available on your host with the tag `airbyte/source-recurly:dev`. -### Running the docker container +### Creating credentials + +**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/recurly) +to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `spec` object in the connector's `manifest.yaml` file. +Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. -Then run any of the connector commands as follows: +### Running as a docker container + +Then run any of the standard source connector commands: ```bash docker run --rm airbyte/source-recurly:dev spec @@ -67,7 +43,7 @@ docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-recurly:dev discover - docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-recurly:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json ``` -### Running our CI test suite +### Running the CI test suite You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): @@ -75,30 +51,15 @@ You can run our full test suite locally using [`airbyte-ci`](https://github.com/ airbyte-ci connectors --name=source-recurly test ``` -### Customizing acceptance Tests - -Customize the `acceptance-test-config.yml` file to configure acceptance tests. See our [Connector Acceptance Tests reference](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) for more information. -If your connector requires you to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py. - -### Dependency Management - -All of your dependencies should be managed via Poetry. To add a new dependency, run: - -```bash -poetry add -``` - -Please commit the changes to the `pyproject.toml` and `poetry.lock` files. - ## Publishing a new version of the connector -You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what? - -1. Make sure your changes are passing our test suite: `airbyte-ci connectors --name=source-recurly test` -2. Bump the connector version listed as `dockerImageTag` in `metadata.yaml`. Please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors). -3. Make sure the `metadata.yaml` content is up to date. -4. Make the connector documentation and its changelog is up to date (`docs/integrations/sources/recurly.md`). +If you want to contribute changes to `source-recurly`, here's how you can do that: +1. Make your changes locally, or load the connector's manifest into Connector Builder and make changes there. +2. Make sure your changes are passing our test suite with `airbyte-ci connectors --name=source-recurly test` +3. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): + - bump the `dockerImageTag` value in in `metadata.yaml` +4. Make sure the connector documentation and its changelog is up to date (`docs/integrations/sources/recurly.md`). 5. Create a Pull Request: use [our PR naming conventions](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#pull-request-title-convention). 6. Pat yourself on the back for being an awesome contributor. 7. Someone from Airbyte will take a look at your PR and iterate with you to merge it into master. -8. Once your PR is merged, the new version of the connector will be automatically published to Docker Hub and our connector registry. +8. Once your PR is merged, the new version of the connector will be automatically published to Docker Hub and our connector registry. \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-recurly/acceptance-test-config.yml b/airbyte-integrations/connectors/source-recurly/acceptance-test-config.yml index b5e27e07c2a2..cb55d8b68f27 100644 --- a/airbyte-integrations/connectors/source-recurly/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-recurly/acceptance-test-config.yml @@ -4,7 +4,7 @@ connector_image: airbyte/source-recurly:dev acceptance_tests: spec: tests: - - spec_path: "source_recurly/spec.yaml" + - spec_path: "manifest.yaml" connection: tests: - config_path: "secrets/config.json" diff --git a/airbyte-integrations/connectors/source-recurly/components.py b/airbyte-integrations/connectors/source-recurly/components.py new file mode 100644 index 000000000000..6cebf58f980d --- /dev/null +++ b/airbyte-integrations/connectors/source-recurly/components.py @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + +from typing import Any, List, Mapping + +import requests + +from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor + + +class ExportDatesExtractor(RecordExtractor): + def extract_records(self, response: requests.Response) -> List[Mapping[str, Any]]: + try: + dates = response.json()["dates"] + except requests.exceptions.JSONDecodeError: + dates = [] + return [{"dates": dates}] diff --git a/airbyte-integrations/connectors/source-recurly/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-recurly/integration_tests/acceptance.py index efc25f08ce82..78b220cebb18 100644 --- a/airbyte-integrations/connectors/source-recurly/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-recurly/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-recurly/integration_tests/configured_catalog.json b/airbyte-integrations/connectors/source-recurly/integration_tests/configured_catalog.json index 75bcfeaf58ad..a9de884d01a6 100644 --- a/airbyte-integrations/connectors/source-recurly/integration_tests/configured_catalog.json +++ b/airbyte-integrations/connectors/source-recurly/integration_tests/configured_catalog.json @@ -200,6 +200,18 @@ }, "sync_mode": "incremental", "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "unique_coupons_parent", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated_at"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "destination_sync_mode": "overwrite" } ] } diff --git a/airbyte-integrations/connectors/source-recurly/integration_tests/future_state.json b/airbyte-integrations/connectors/source-recurly/integration_tests/future_state.json index 1c9442f7c6d3..d6287e181fbb 100644 --- a/airbyte-integrations/connectors/source-recurly/integration_tests/future_state.json +++ b/airbyte-integrations/connectors/source-recurly/integration_tests/future_state.json @@ -110,5 +110,12 @@ "stream_state": { "updated_at": "2036-07-19T22:21:37Z" }, "stream_descriptor": { "name": "unique_coupons" } } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "updated_at": "2036-07-19T22:21:37Z" }, + "stream_descriptor": { "name": "unique_coupons_parent" } + } } ] diff --git a/airbyte-integrations/connectors/source-recurly/main.py b/airbyte-integrations/connectors/source-recurly/main.py deleted file mode 100644 index d8c1a4490315..000000000000 --- a/airbyte-integrations/connectors/source-recurly/main.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from source_recurly.run import run - -if __name__ == "__main__": - run() diff --git a/airbyte-integrations/connectors/source-recurly/manifest.yaml b/airbyte-integrations/connectors/source-recurly/manifest.yaml new file mode 100644 index 000000000000..9795d824f4c4 --- /dev/null +++ b/airbyte-integrations/connectors/source-recurly/manifest.yaml @@ -0,0 +1,6669 @@ +version: 5.7.0 + +type: DeclarativeSource + +check: + type: CheckStream + stream_names: + - accounts + +definitions: + streams: + accounts: + type: DeclarativeStream + name: accounts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: accounts + http_method: GET + request_parameters: + sort: updated_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounts" + account_coupon_redemptions: + type: DeclarativeStream + name: account_coupon_redemptions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounts/{{ stream_partition['account_id'] }}/coupon_redemptions + http_method: GET + request_parameters: + sort: updated_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: account_id + stream: + $ref: "#/definitions/streams/accounts" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/account_coupon_redemptions" + account_notes: + type: DeclarativeStream + name: account_notes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounts/{{ stream_partition['account_id'] }}/notes + http_method: GET + request_parameters: + sort: created_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: account_id + stream: + $ref: "#/definitions/streams/accounts" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/account_notes" + add_ons: + type: DeclarativeStream + name: add_ons + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /add_ons + http_method: GET + request_parameters: + sort: updated_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/add_ons" + billing_infos: + type: DeclarativeStream + name: billing_infos + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounts/{{ stream_partition['account_id'] }}/billing_infos + http_method: GET + request_parameters: + sort: updated_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: account_id + stream: + $ref: "#/definitions/streams/accounts" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/billing_infos" + coupons: + type: DeclarativeStream + name: coupons + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: coupons + http_method: GET + request_parameters: + sort: updated_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/coupons" + credit_payments: + type: DeclarativeStream + name: credit_payments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: credit_payments + http_method: GET + request_parameters: + sort: updated_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/credit_payments" + export_dates: + type: DeclarativeStream + name: export_dates + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: export_dates + http_method: GET + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: CustomRecordExtractor + class_name: source_declarative_manifest.components.ExportDatesExtractor + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/export_dates" + invoices: + type: DeclarativeStream + name: invoices + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: invoices + http_method: GET + request_parameters: + sort: updated_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/invoices" + line_items: + type: DeclarativeStream + name: line_items + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: line_items + http_method: GET + request_parameters: + sort: updated_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/line_items" + measured_units: + type: DeclarativeStream + name: measured_units + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: measured_units + http_method: GET + request_parameters: + sort: updated_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/measured_units" + plans: + type: DeclarativeStream + name: plans + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: plans + http_method: GET + request_parameters: + sort: updated_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/plans" + shipping_addresses: + type: DeclarativeStream + name: shipping_addresses + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounts/{{ stream_partition['account_id'] }}/shipping_addresses + http_method: GET + request_parameters: + sort: updated_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: account_id + stream: + $ref: "#/definitions/streams/accounts" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/shipping_addresses" + shipping_methods: + type: DeclarativeStream + name: shipping_methods + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: shipping_methods + http_method: GET + request_parameters: + sort: updated_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/shipping_methods" + subscriptions: + type: DeclarativeStream + name: subscriptions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: subscriptions + http_method: GET + request_parameters: + sort: updated_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/subscriptions" + transactions: + type: DeclarativeStream + name: transactions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: transactions + http_method: GET + request_parameters: + sort: updated_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/transactions" + unique_coupons: + type: DeclarativeStream + name: unique_coupons + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /coupons/{{ stream_partition['coupon_id'] }}/unique_coupon_codes + http_method: GET + request_parameters: + sort: updated_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: coupon_id + stream: + $ref: "#/definitions/streams/unique_coupons_parent" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/unique_coupons" + unique_coupons_parent: + type: DeclarativeStream + name: unique_coupons_parent + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: coupons + http_method: GET + request_parameters: + sort: updated_at + order: asc + request_headers: + Accept: application/vnd.recurly.v2021-02-25 + User-Agent: USER_AGENT + Content-Type: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + record_filter: + type: RecordFilter + condition: "{{ record['coupon_type'] == 'bulk' }}" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next }}" + stop_condition: "{{ response.has_more is false }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['begin_time'] if config['begin_time'] else (now_utc() - + duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: begin_time + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: end_time + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: >- + {{ config['end_time'] if config['end_time'] else + now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }} + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/unique_coupons_parent" + base_requester: + type: HttpRequester + url_base: https://v3.recurly.com + authenticator: + type: BasicHttpAuthenticator + username: "{{ config['api_key'] }}" + +streams: + - $ref: "#/definitions/streams/accounts" + - $ref: "#/definitions/streams/account_coupon_redemptions" + - $ref: "#/definitions/streams/account_notes" + - $ref: "#/definitions/streams/add_ons" + - $ref: "#/definitions/streams/billing_infos" + - $ref: "#/definitions/streams/coupons" + - $ref: "#/definitions/streams/credit_payments" + - $ref: "#/definitions/streams/export_dates" + - $ref: "#/definitions/streams/invoices" + - $ref: "#/definitions/streams/line_items" + - $ref: "#/definitions/streams/measured_units" + - $ref: "#/definitions/streams/plans" + - $ref: "#/definitions/streams/shipping_addresses" + - $ref: "#/definitions/streams/shipping_methods" + - $ref: "#/definitions/streams/subscriptions" + - $ref: "#/definitions/streams/transactions" + - $ref: "#/definitions/streams/unique_coupons" + - $ref: "#/definitions/streams/unique_coupons_parent" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + description: >- + Recurly API Key. See the docs + for more information on how to generate this key. + order: 0 + title: API Key + airbyte_secret: true + begin_time: + type: string + description: >- + ISO8601 timestamp from which the replication from Recurly API will + start from. + order: 1 + pattern: ^$|^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$ + examples: + - "2021-12-01T00:00:00" + end_time: + type: string + description: >- + ISO8601 timestamp to which the replication from Recurly API will stop. + Records after that date won't be imported. + order: 2 + pattern: ^$|^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$ + examples: + - "2021-12-01T00:00:00" + additionalProperties: true + +metadata: + autoImportSchema: + accounts: false + account_coupon_redemptions: false + account_notes: false + add_ons: false + billing_infos: false + coupons: false + credit_payments: false + export_dates: false + invoices: false + line_items: false + measured_units: false + plans: false + shipping_addresses: false + shipping_methods: false + subscriptions: false + transactions: false + unique_coupons: false + unique_coupons_parent: true + yamlComponents: + streams: + export_dates: + - recordSelector + global: + - authenticator + testedStreams: + accounts: + hasRecords: true + streamHash: 11d3bfcfbacd601ab5efcc68218a6cdef23b6f47 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + account_coupon_redemptions: + streamHash: d724e45e08324b43a94e0e500e664403fe80332c + account_notes: + streamHash: 9db06dff3323ea995b085cf95342db9b2029bb7c + add_ons: + streamHash: 94072f96983e4e96f54c7baaa24b0375f57331e1 + billing_infos: + streamHash: f8f164bc26871caaa7fd5cd8ca27310eec6dcfcc + coupons: + streamHash: 4d8f143623054d6cf60e5e350d8b476830a29840 + credit_payments: + streamHash: 434c5210f63cdd1583ecc09d1b606a5e453e3932 + export_dates: + streamHash: d0aade1accdb8ac55ebc1669020c001b02fb3307 + invoices: + streamHash: 8bd7d5dd7d691a0198ad949b14a637af241e3525 + line_items: + streamHash: 1542034779aaf8c8dae770fd352618fbe3543b90 + measured_units: + streamHash: a07fb60b432098f1cada954a3830c698ae37a21c + plans: + streamHash: b8d262d1c35ffeae577ca07dfe497cd16c81ecef + shipping_addresses: + streamHash: 8c103ffaa8b1b579b830aaf66df7d20cbf96cf7e + shipping_methods: + streamHash: 26109dca0fcc6c5c236b80f42caf2db14472d433 + subscriptions: + streamHash: ddab1a73c61da0588d7af3f3f28acdeb0f683a48 + transactions: + streamHash: a4690ee75cbd87be5f86185f97b4e7e4132a9c1f + unique_coupons: + streamHash: 0c5af71a0eebdb74c86b2945aed8ff369c82b671 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + unique_coupons_parent: + streamHash: ea27ebf3a3b2052a576a3fb3d7a63b52308ca5bc + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + accounts: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + address: + type: object + description: The address details of the account + properties: + city: + type: string + description: City of the address + maxLength: 256 + title: City + country: + type: string + description: Country, 2-letter ISO 3166-1 alpha-2 code. + maxLength: 2 + title: Country + geo_code: + type: + - "null" + - string + description: Geographical coordinates of the address + phone: + type: string + description: Phone number associated with the address + maxLength: 256 + title: Phone number + postal_code: + type: string + description: Zip or postal code. + maxLength: 256 + title: Zip/Postal code + region: + type: string + description: State or province. + maxLength: 256 + title: State/Province + street1: + type: string + description: First line of the street address + maxLength: 256 + title: Street 1 + street2: + type: string + description: Second line of the street address + maxLength: 256 + title: Street 2 + bill_to: + type: + - "null" + - string + description: The billing details + maxLength: 6 + billing_info: + type: object + description: Billing information + $schema: http://json-schema.org/draft-07/schema# + properties: + account_id: + type: string + maxLength: 13 + readOnly: true + address: + type: object + properties: + city: + type: + - "null" + - string + maxLength: 256 + title: City + country: + type: + - "null" + - string + description: Country, 2-letter ISO 3166-1 alpha-2 code. + maxLength: 2 + title: Country + phone: + type: + - "null" + - string + maxLength: 256 + title: Phone number + postal_code: + type: + - "null" + - string + description: Zip or postal code. + maxLength: 256 + title: Zip/Postal code + region: + type: + - "null" + - string + description: State or province. + maxLength: 256 + title: State/Province + street1: + type: + - "null" + - string + maxLength: 256 + title: Street 1 + street2: + type: + - "null" + - string + maxLength: 256 + title: Street 2 + backup_payment_method: + type: boolean + description: >- + The `backup_payment_method` field is used to indicate a billing + info as a backup on the account that will be tried if the initial + billing info used for an invoice is declined. + company: + type: + - "null" + - string + maxLength: 100 + created_at: + type: string + description: When the billing information was created. + format: date-time + readOnly: true + first_name: + type: + - "null" + - string + maxLength: 50 + fraud: + type: + - "null" + - object + description: Most recent fraud result. + properties: + decision: + type: + - "null" + - string + maxLength: 10 + title: Kount decision + risk_rules_triggered: + type: object + title: Kount rules + score: + type: + - "null" + - integer + title: Kount score + readOnly: true + title: Fraud information + id: + type: string + maxLength: 13 + readOnly: true + last_name: + type: + - "null" + - string + maxLength: 50 + object: + type: + - "null" + - string + payment_method: + type: object + properties: + account_type: + type: + - "null" + - string + description: The bank account type. Only present for ACH payment methods. + maxLength: 256 + billing_agreement_id: + type: + - "null" + - string + description: >- + Billing Agreement identifier. Only present for Amazon or + Paypal payment methods. + maxLength: 256 + card_type: + type: + - "null" + - string + description: Visa, MasterCard, American Express, Discover, JCB, etc. + maxLength: 256 + cc_bin_country: + type: + - "null" + - string + description: >- + The 2-letter ISO 3166-1 alpha-2 country code associated with + the credit card BIN, if known by Recurly. Available on the + BillingInfo object only. Available when the BIN country lookup + feature is enabled. + maxLength: 256 + exp_month: + type: + - "null" + - integer + description: Expiration month. + maxLength: 2 + exp_year: + type: + - "null" + - integer + description: Expiration year. + maxLength: 4 + first_six: + type: + - "null" + - string + description: Credit card number's first six digits. + maxLength: 6 + gateway_code: + type: + - "null" + - string + description: An identifier for a specific payment gateway. + maxLength: 13 + gateway_token: + type: + - "null" + - string + description: >- + A token used in place of a credit card in order to perform + transactions. + maxLength: 50 + last_four: + type: + - "null" + - string + description: >- + Credit card number's last four digits. Will refer to bank + account if payment method is ACH. + maxLength: 4 + last_two: + type: + - "null" + - string + description: The IBAN bank account's last two digits. + maxLength: 2 + name_on_account: + type: + - "null" + - string + description: The name associated with the bank account. + maxLength: 256 + object: + type: + - "null" + - string + routing_number: + type: + - "null" + - string + description: >- + The bank account's routing number. Only present for ACH + payment methods. + maxLength: 256 + routing_number_bank: + type: + - "null" + - string + description: The bank name of this routing number. + maxLength: 256 + primary_payment_method: + type: boolean + description: >- + The `primary_payment_method` field is used to indicate the primary + billing info on the account. The first billing info created on an + account will always become primary. This payment method will be + used + updated_at: + type: string + description: When the billing information was last changed. + format: date-time + readOnly: true + updated_by: + type: + - "null" + - object + properties: + country: + type: + - "null" + - string + ip: + type: + - "null" + - string + valid: + type: boolean + readOnly: true + vat_number: + type: + - "null" + - string + description: >- + Customer's VAT number (to avoid having the VAT applied). This is + only used for automatically collected invoices. + maxLength: 20 + cc_emails: + type: + - "null" + - string + description: Email addresses for carbon copy (CC) + maxLength: 256 + code: + type: + - "null" + - string + description: Unique code assigned to the account + maxLength: 256 + company: + type: + - "null" + - string + description: Company associated with the account + maxLength: 50 + created_at: + type: + - "null" + - string + description: Date and time when the account was created + format: date-time + custom_fields: + type: + - "null" + - array + description: Custom fields associated with the account + items: + type: + - "null" + - object + additionalProperties: true + deleted_at: + type: + - "null" + - string + description: Date and time when the account was deleted + format: date-time + dunning_campaign_id: + type: + - "null" + - string + description: Campaign ID for dunning management + maxLength: 256 + email: + type: + - "null" + - string + description: Email address of the account holder + maxLength: 256 + exemption_certificate: + type: + - "null" + - string + description: Exemption certificate details + maxLength: 30 + external_accounts: + type: + - "null" + - array + description: External accounts associated with the account + items: + type: object + $schema: http://json-schema.org/draft-07/schema# + properties: + created_at: + type: + - "null" + - string + external_account_code: + type: + - "null" + - string + external_connection_type: + type: + - "null" + - string + id: + type: + - "null" + - string + object: + type: + - "null" + - string + updated_at: + type: + - "null" + - string + first_name: + type: + - "null" + - string + description: First name of the account holder + maxLength: 256 + has_active_subscription: + type: + - "null" + - boolean + description: Flag indicating if the account has an active subscription + has_canceled_subscription: + type: + - "null" + - boolean + description: Flag indicating if the account has a canceled subscription + has_future_subscription: + type: + - "null" + - boolean + description: Flag indicating if the account has a future subscription + has_live_subscription: + type: + - "null" + - boolean + description: Flag indicating if the account has a live subscription + has_past_due_invoice: + type: + - "null" + - boolean + description: Flag indicating if the account has a past due invoice + has_paused_subscription: + type: + - "null" + - boolean + description: Flag indicating if the account has a paused subscription + hosted_login_token: + type: + - "null" + - string + description: Token for hosted login functionality + id: + type: + - "null" + - string + description: Unique identifier of the account + maxLength: 13 + invoice_template_id: + type: + - "null" + - string + description: ID of the invoice template used + last_name: + type: + - "null" + - string + description: Last name of the account holder + maxLength: 256 + object: + type: + - "null" + - string + description: Type of object + override_business_entity_id: + type: + - "null" + - string + description: ID for overriding business entity + parent_account_id: + type: + - "null" + - string + description: ID of the parent account + maxLength: 13 + preferred_locale: + type: + - "null" + - string + description: Preferred language/locale of the account holder + maxLength: 12 + preferred_time_zone: + type: + - "null" + - string + description: Preferred time zone of the account holder + shipping_addresses: + type: + - "null" + - array + description: Addresses for shipping + items: + type: + - "null" + - object + $schema: http://json-schema.org/draft-07/schema# + properties: + account_id: + type: string + maxLength: 13 + readOnly: true + title: Account ID + city: + type: string + maxLength: 255 + company: + type: string + maxLength: 255 + country: + type: string + description: Country, 2-letter ISO 3166-1 alpha-2 code. + maxLength: 50 + created_at: + type: string + format: date-time + readOnly: true + title: Created at + email: + type: string + maxLength: 255 + first_name: + type: string + maxLength: 255 + geo_code: + type: + - "null" + - string + id: + type: string + maxLength: 13 + readOnly: true + title: Shipping Address ID + last_name: + type: string + maxLength: 255 + nickname: + type: string + maxLength: 255 + object: + type: + - "null" + - string + phone: + type: string + maxLength: 30 + postal_code: + type: string + description: Zip or postal code. + maxLength: 20 + region: + type: string + description: State or province. + maxLength: 255 + street1: + type: string + maxLength: 255 + street2: + type: string + maxLength: 255 + updated_at: + type: string + format: date-time + readOnly: true + title: Updated at + vat_number: + type: string + maxLength: 20 + state: + type: + - "null" + - string + description: State/province of the account address + maxLength: 256 + tax_exempt: + type: + - "null" + - boolean + description: Flag indicating if the account is tax exempt + updated_at: + type: + - "null" + - string + description: Date and time when the account was last updated + format: date-time + username: + type: + - "null" + - string + description: Username of the account holder + maxLength: 256 + vat_number: + type: + - "null" + - string + description: VAT (Value Added Tax) number of the account + maxLength: 20 + account_coupon_redemptions: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + account: + type: + - "null" + - object + description: The account associated with the coupon redemption + properties: + bill_to: + type: + - "null" + - string + code: + type: + - "null" + - string + company: + type: + - "null" + - string + dunning_campaign_id: + type: + - "null" + - string + email: + type: + - "null" + - string + first_name: + type: + - "null" + - string + id: + type: string + last_name: + type: + - "null" + - string + object: + type: + - "null" + - string + parent_account_id: + type: + - "null" + - string + coupon: + type: object + description: The coupon being redeemed + $schema: http://json-schema.org/draft-07/schema# + properties: + applies_to_all_items: + type: + - "null" + - boolean + applies_to_all_plans: + type: + - "null" + - boolean + applies_to_non_plan_charges: + type: + - "null" + - boolean + code: + type: + - "null" + - string + maxLength: 256 + coupon_type: + type: + - "null" + - string + maxLength: 256 + created_at: + type: + - "null" + - string + format: date-time + discount: + type: + - "null" + - object + description: > + Details of the discount a coupon applies. Will contain a `type` + + property and one of the following properties: `percent`, `fixed`, + `trial`. + properties: + type: + type: string + maxLength: 256 + currencies: + type: array + description: This is only present when `type=fixed`. + items: + type: + - "null" + - object + properties: + amount: + type: number + description: Value of the fixed discount that this coupon applies. + format: float + title: Discount Amount + currency: + type: string + description: 3-letter ISO 4217 currency code. + maxLength: 3 + title: Currency + percent: + type: integer + description: This is only present when `type=percent`. + trial: + type: object + description: This is only present when `type=free_trial`. + properties: + length: + type: integer + description: >- + Trial length measured in the units specified by the + sibling `unit` property + title: Trial length + unit: + type: string + description: Temporal unit of the free trial + maxLength: 256 + title: Trial unit + duration: + type: + - "null" + - string + maxLength: 256 + expired_at: + type: + - "null" + - string + format: date-time + free_trial_amount: + type: + - "null" + - number + free_trial_unit: + type: + - "null" + - string + maxLength: 256 + hosted_page_description: + type: + - "null" + - string + maxLength: 1024 + id: + type: + - "null" + - string + maxLength: 13 + invoice_description: + type: + - "null" + - string + maxLength: 1024 + items: + type: + - "null" + - array + description: | + A list of items for which this coupon applies. This will be + `null` if `applies_to_all_items=true`. + items: + type: + - "null" + - object + description: Just the important parts. + properties: + id: + type: string + maxLength: 13 + readOnly: true + title: Item ID + title: Item mini details + title: Items + max_redemptions: + type: + - "null" + - number + max_redemptions_per_account: + type: + - "null" + - number + name: + type: + - "null" + - string + maxLength: 256 + object: + type: + - "null" + - string + plans: + type: + - "null" + - array + description: >- + A list of plans for which this coupon applies. This will be `null` + if `applies_to_all_plans=true`. + items: + type: object + description: Just the important parts. + properties: + code: + type: string + description: >- + Unique code to identify the plan. This is used in Hosted + Payment Page URLs and in the invoice exports. + maxLength: 13 + title: Plan code + id: + type: string + maxLength: 13 + readOnly: true + title: Plan ID + title: Plan mini details + title: Plans + redeem_by: + type: + - "null" + - string + maxLength: 256 + redemption_resource: + type: + - "null" + - string + maxLength: 256 + state: + type: + - "null" + - string + maxLength: 256 + temporal_amount: + type: + - "null" + - number + temporal_unit: + type: + - "null" + - string + maxLength: 256 + unique_code_template: + type: + - "null" + - string + maxLength: 256 + unique_coupon_code: + type: + - "null" + - object + description: A unique coupon code for a bulk coupon. + $schema: http://json-schema.org/draft-07/schema# + properties: + bulk_coupon_code: + type: + - "null" + - string + description: The Coupon code of the parent Bulk Coupon + maxLength: 256 + title: Bulk Coupon code + bulk_coupon_id: + type: + - "null" + - string + description: The Coupon ID of the parent Bulk Coupon + maxLength: 13 + readOnly: true + title: Bulk Coupon ID + code: + type: string + description: The code the customer enters to redeem the coupon. + maxLength: 256 + title: Coupon code + created_at: + type: string + format: date-time + readOnly: true + title: Created at + expired_at: + type: + - "null" + - string + description: >- + The date and time the coupon was expired early or reached its + `max_redemptions`. + format: date-time + title: Expired at + id: + type: string + maxLength: 13 + readOnly: true + title: Unique Coupon Code ID + object: + type: string + redeemed_at: + type: + - "null" + - string + description: The date and time the unique coupon code was redeemed. + format: date-time + readOnly: true + title: Redeemed at + state: + type: + - "null" + - string + description: Indicates if the unique coupon code is redeemable or why not. + maxLength: 256 + title: State + updated_at: + type: string + format: date-time + readOnly: true + title: Updated at + unique_coupon_codes_count: + type: + - "null" + - number + updated_at: + type: + - "null" + - string + format: date-time + created_at: + type: + - "null" + - string + description: The date and time when the redemption was created + format: date-time + currency: + type: + - "null" + - string + description: The currency in which the redemption was made + maxLength: 3 + discounted: + type: + - "null" + - number + description: The amount discounted by the coupon + id: + type: + - "null" + - string + description: The unique identifier for the redemption + maxLength: 13 + object: + type: + - "null" + - string + description: The type of object this represents + removed_at: + type: + - "null" + - string + description: The date and time when the redemption was removed (if applicable) + format: date-time + state: + type: + - "null" + - string + description: The current state of the redemption + maxLength: 256 + subscription_id: + type: + - "null" + - string + description: The subscription associated with the redemption + maxLength: 13 + updated_at: + type: + - "null" + - string + description: The date and time when the redemption was last updated + format: date-time + account_notes: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + account_id: + type: string + description: The unique identifier of the account associated with this note. + maxLength: 13 + created_at: + type: string + description: The date and time when the note was created. + format: date-time + readOnly: true + id: + type: string + description: The unique identifier for this note. + maxLength: 13 + readOnly: true + message: + type: + - "null" + - string + description: The content or message of the note. + maxLength: 2048 + object: + type: + - "null" + - string + description: Represents the object type, in this case, 'note'. + user: + type: + - "null" + - object + description: The user who created the note. + properties: + created_at: + type: + - "null" + - string + format: date-time + deleted_at: + type: + - "null" + - string + format: date-time + email: + type: + - "null" + - string + first_name: + type: + - "null" + - string + id: + type: string + last_name: + type: + - "null" + - string + object: + type: + - "null" + - string + time_zone: + type: + - "null" + - string + add_ons: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accounting_code: + type: + - "null" + - string + description: >- + Accounting code for invoice line items for this add-on. If no value is + provided, it defaults to add-on's code. + maxLength: 256 + title: Accounting code + add_on_type: + type: + - "null" + - string + description: Whether the add-on type is fixed, or usage-based. + maxLength: 256 + title: Add-on Type + avalara_service_type: + type: + - string + - integer + description: >- + Used by Avalara for Communications taxes. The transaction type in + combination with the service type describe how the add-on is taxed. + Refer to [the + documentation](https://help.avalara.com/AvaTax_for_Communications/Tax_Calculation/AvaTax_for_Communications_Tax_Engine/Mapping_Resources/TM_00115_AFC_Modules_Corresponding_Transaction_Types) + for more available t/s types. + minimum: 0 + title: Avalara Service Type + avalara_transaction_type: + type: + - string + - integer + description: >- + Used by Avalara for Communications taxes. The transaction type in + combination with the service type describe how the add-on is taxed. + Refer to [the + documentation](https://help.avalara.com/AvaTax_for_Communications/Tax_Calculation/AvaTax_for_Communications_Tax_Engine/Mapping_Resources/TM_00115_AFC_Modules_Corresponding_Transaction_Types) + for more available t/s types. + minimum: 0 + title: Avalara Transaction Type + code: + type: string + description: The unique identifier for the add-on within its plan. + maxLength: 50 + title: Add-on code + created_at: + type: string + description: The date and time when the add-on was created. + format: date-time + readOnly: true + title: Created at + currencies: + type: array + description: This is only present when `type=fixed`. + items: + type: + - "null" + - object + properties: + currency: + type: string + description: 3-letter ISO 4217 currency code. + maxLength: 3 + title: Currency + unit_amount: + type: number + description: Value of the fixed discount that this coupon applies. + format: float + title: Discount Amount + default_quantity: + type: + - "null" + - integer + description: Default quantity for the hosted pages. + title: Default quantity + deleted_at: + type: string + description: The date and time when the add-on was deleted, if applicable. + format: date-time + readOnly: true + title: Deleted at + display_quantity: + type: + - "null" + - boolean + description: >- + Determines if the quantity field is displayed on the hosted pages for + the add-on. + title: Display quantity? + id: + type: string + description: The unique identifier for the add-on. + maxLength: 13 + readOnly: true + title: Add-on ID + measured_unit_id: + type: + - "null" + - string + description: >- + System-generated unique identifier for an measured unit associated + with the add-on. + maxLength: 13 + title: Measured Unit ID + name: + type: string + description: Describes your add-on and will appear in subscribers' invoices. + maxLength: 255 + title: Name + optional: + type: + - "null" + - boolean + description: >- + Whether the add-on is optional for the customer to include in their + purchase on the hosted payment page. If false, the add-on will be + included when a subscription is created through the Recurly UI. + However, the add-on will not be included when a subscription is + created through the API. + title: Optional + plan_id: + type: string + description: The ID of the plan to which the add-on is associated. + maxLength: 13 + readOnly: true + title: Plan ID + revenue_schedule_type: + type: string + description: >- + When this add-on is invoiced, the line item will use this revenue + schedule. If `item_code`/`item_id` is part of the request then + `revenue_schedule_type` must be absent in the request as the value + will be set from the item. + maxLength: 256 + title: Revenue schedule type + state: + type: string + description: Add-ons can be either active or inactive. + maxLength: 256 + readOnly: true + title: State + tax_code: + type: + - "null" + - string + description: >- + Used by Avalara, Vertex, and Recurly’s EU VAT tax feature. The tax + code values are specific to each tax system. If you are using + Recurly’s EU VAT feature you can use `unknown`, `physical`, or + `digital`. + maxLength: 50 + title: Tax code + tier_type: + type: + - "null" + - string + description: > + The pricing model for the add-on. For more information, + + [click + here](https://docs.recurly.com/docs/billing-models#section-quantity-based). + See our + + [Guide](https://developers.recurly.com/guides/item-addon-guide.html) + for an overview of how + + to configure quantity-based pricing models. + maxLength: 256 + title: Tier type + updated_at: + type: string + description: The date and time when the add-on was last updated. + format: date-time + readOnly: true + title: Last updated at + usage_percentage: + type: + - "null" + - number + description: >- + The percentage taken of the monetary amount of usage tracked. This can + be up to 4 decimal places. A value between 0.0 and 100.0. + format: float + title: Usage Percentage + usage_type: + type: string + description: Type of usage, returns usage type if `add_on_type` is `usage`. + maxLength: 256 + title: Usage Type + billing_infos: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + account_id: + type: string + maxLength: 13 + readOnly: true + address: + type: object + properties: + city: + type: + - "null" + - string + maxLength: 256 + title: City + country: + type: + - "null" + - string + description: Country, 2-letter ISO 3166-1 alpha-2 code. + maxLength: 2 + title: Country + phone: + type: + - "null" + - string + maxLength: 256 + title: Phone number + postal_code: + type: + - "null" + - string + description: Zip or postal code. + maxLength: 256 + title: Zip/Postal code + region: + type: + - "null" + - string + description: State or province. + maxLength: 256 + title: State/Province + street1: + type: + - "null" + - string + maxLength: 256 + title: Street 1 + street2: + type: + - "null" + - string + maxLength: 256 + title: Street 2 + backup_payment_method: + type: boolean + description: >- + The `backup_payment_method` field is used to indicate a billing info + as a backup on the account that will be tried if the initial billing + info used for an invoice is declined. + company: + type: + - "null" + - string + maxLength: 100 + created_at: + type: string + description: When the billing information was created. + format: date-time + readOnly: true + first_name: + type: + - "null" + - string + maxLength: 50 + fraud: + type: + - "null" + - object + description: Most recent fraud result. + properties: + decision: + type: + - "null" + - string + maxLength: 10 + title: Kount decision + risk_rules_triggered: + type: object + title: Kount rules + score: + type: + - "null" + - integer + title: Kount score + readOnly: true + title: Fraud information + id: + type: string + maxLength: 13 + readOnly: true + last_name: + type: + - "null" + - string + maxLength: 50 + object: + type: + - "null" + - string + payment_method: + type: object + properties: + account_type: + type: + - "null" + - string + description: The bank account type. Only present for ACH payment methods. + maxLength: 256 + billing_agreement_id: + type: + - "null" + - string + description: >- + Billing Agreement identifier. Only present for Amazon or Paypal + payment methods. + maxLength: 256 + card_type: + type: + - "null" + - string + description: Visa, MasterCard, American Express, Discover, JCB, etc. + maxLength: 256 + cc_bin_country: + type: + - "null" + - string + description: >- + The 2-letter ISO 3166-1 alpha-2 country code associated with the + credit card BIN, if known by Recurly. Available on the BillingInfo + object only. Available when the BIN country lookup feature is + enabled. + maxLength: 256 + exp_month: + type: + - "null" + - integer + description: Expiration month. + maxLength: 2 + exp_year: + type: + - "null" + - integer + description: Expiration year. + maxLength: 4 + first_six: + type: + - "null" + - string + description: Credit card number's first six digits. + maxLength: 6 + gateway_code: + type: + - "null" + - string + description: An identifier for a specific payment gateway. + maxLength: 13 + gateway_token: + type: + - "null" + - string + description: >- + A token used in place of a credit card in order to perform + transactions. + maxLength: 50 + last_four: + type: + - "null" + - string + description: >- + Credit card number's last four digits. Will refer to bank account + if payment method is ACH. + maxLength: 4 + last_two: + type: + - "null" + - string + description: The IBAN bank account's last two digits. + maxLength: 2 + name_on_account: + type: + - "null" + - string + description: The name associated with the bank account. + maxLength: 256 + object: + type: + - "null" + - string + routing_number: + type: + - "null" + - string + description: >- + The bank account's routing number. Only present for ACH payment + methods. + maxLength: 256 + routing_number_bank: + type: + - "null" + - string + description: The bank name of this routing number. + maxLength: 256 + primary_payment_method: + type: boolean + description: >- + The `primary_payment_method` field is used to indicate the primary + billing info on the account. The first billing info created on an + account will always become primary. This payment method will be used + updated_at: + type: string + description: When the billing information was last changed. + format: date-time + readOnly: true + updated_by: + type: + - "null" + - object + properties: + country: + type: + - "null" + - string + ip: + type: + - "null" + - string + valid: + type: boolean + readOnly: true + vat_number: + type: + - "null" + - string + description: >- + Customer's VAT number (to avoid having the VAT applied). This is only + used for automatically collected invoices. + maxLength: 20 + coupons: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + applies_to_all_items: + type: + - "null" + - boolean + applies_to_all_plans: + type: + - "null" + - boolean + applies_to_non_plan_charges: + type: + - "null" + - boolean + code: + type: + - "null" + - string + maxLength: 256 + coupon_type: + type: + - "null" + - string + maxLength: 256 + created_at: + type: + - "null" + - string + format: date-time + discount: + type: + - "null" + - object + description: > + Details of the discount a coupon applies. Will contain a `type` + + property and one of the following properties: `percent`, `fixed`, + `trial`. + properties: + type: + type: string + maxLength: 256 + currencies: + type: array + description: This is only present when `type=fixed`. + items: + type: + - "null" + - object + properties: + amount: + type: number + description: Value of the fixed discount that this coupon applies. + format: float + title: Discount Amount + currency: + type: string + description: 3-letter ISO 4217 currency code. + maxLength: 3 + title: Currency + percent: + type: integer + description: This is only present when `type=percent`. + trial: + type: object + description: This is only present when `type=free_trial`. + properties: + length: + type: integer + description: >- + Trial length measured in the units specified by the sibling + `unit` property + title: Trial length + unit: + type: string + description: Temporal unit of the free trial + maxLength: 256 + title: Trial unit + duration: + type: + - "null" + - string + maxLength: 256 + expired_at: + type: + - "null" + - string + format: date-time + free_trial_amount: + type: + - "null" + - number + free_trial_unit: + type: + - "null" + - string + maxLength: 256 + hosted_page_description: + type: + - "null" + - string + maxLength: 1024 + id: + type: + - "null" + - string + maxLength: 13 + invoice_description: + type: + - "null" + - string + maxLength: 1024 + items: + type: + - "null" + - array + description: | + A list of items for which this coupon applies. This will be + `null` if `applies_to_all_items=true`. + items: + type: + - "null" + - object + description: Just the important parts. + properties: + id: + type: string + maxLength: 13 + readOnly: true + title: Item ID + title: Item mini details + title: Items + max_redemptions: + type: + - "null" + - number + max_redemptions_per_account: + type: + - "null" + - number + name: + type: + - "null" + - string + maxLength: 256 + object: + type: + - "null" + - string + plans: + type: + - "null" + - array + description: >- + A list of plans for which this coupon applies. This will be `null` if + `applies_to_all_plans=true`. + items: + type: object + description: Just the important parts. + properties: + code: + type: string + description: >- + Unique code to identify the plan. This is used in Hosted Payment + Page URLs and in the invoice exports. + maxLength: 13 + title: Plan code + id: + type: string + maxLength: 13 + readOnly: true + title: Plan ID + title: Plan mini details + title: Plans + redeem_by: + type: + - "null" + - string + maxLength: 256 + redemption_resource: + type: + - "null" + - string + maxLength: 256 + state: + type: + - "null" + - string + maxLength: 256 + temporal_amount: + type: + - "null" + - number + temporal_unit: + type: + - "null" + - string + maxLength: 256 + unique_code_template: + type: + - "null" + - string + maxLength: 256 + unique_coupon_code: + type: + - "null" + - object + description: A unique coupon code for a bulk coupon. + $schema: http://json-schema.org/draft-07/schema# + properties: + bulk_coupon_code: + type: + - "null" + - string + description: The Coupon code of the parent Bulk Coupon + maxLength: 256 + title: Bulk Coupon code + bulk_coupon_id: + type: + - "null" + - string + description: The Coupon ID of the parent Bulk Coupon + maxLength: 13 + readOnly: true + title: Bulk Coupon ID + code: + type: string + description: The code the customer enters to redeem the coupon. + maxLength: 256 + title: Coupon code + created_at: + type: string + format: date-time + readOnly: true + title: Created at + expired_at: + type: + - "null" + - string + description: >- + The date and time the coupon was expired early or reached its + `max_redemptions`. + format: date-time + title: Expired at + id: + type: string + maxLength: 13 + readOnly: true + title: Unique Coupon Code ID + object: + type: string + redeemed_at: + type: + - "null" + - string + description: The date and time the unique coupon code was redeemed. + format: date-time + readOnly: true + title: Redeemed at + state: + type: + - "null" + - string + description: Indicates if the unique coupon code is redeemable or why not. + maxLength: 256 + title: State + updated_at: + type: string + format: date-time + readOnly: true + title: Updated at + unique_coupon_codes_count: + type: + - "null" + - number + updated_at: + type: + - "null" + - string + format: date-time + credit_payments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account: + type: object + description: Details about the account associated with the credit payment. + properties: + code: + type: string + description: The unique identifier of the account. + maxLength: 50 + id: + type: string + description: The ID of the account associated with the credit payment. + maxLength: 13 + readOnly: true + title: Account mini details + action: + type: string + description: The action for which the credit was created. + maxLength: 256 + title: Action + amount: + type: number + description: Total credit payment amount applied to the charge invoice. + format: float + title: Amount + applied_to_invoice: + type: + - "null" + - object + description: Details about the invoice to which the credit payment is applied. + properties: + id: + type: string + description: The ID of the invoice to which the credit payment is applied. + maxLength: 13 + title: Invoice ID + number: + type: string + description: The number of the invoice to which the credit payment is applied. + maxLength: 256 + title: Invoice number + title: Invoice mini details + created_at: + type: string + description: The date and time when the credit payment was created. + format: date-time + readOnly: true + title: Created at + currency: + type: string + description: 3-letter ISO 4217 currency code. + maxLength: 3 + title: Currency + id: + type: string + description: The unique identifier of the credit payment. + maxLength: 13 + title: Credit Payment ID + original_credit_payment_id: + type: + - "null" + - string + description: >- + For credit payments with action `refund`, this is the credit payment + that was refunded. + maxLength: 13 + title: Original Credit Payment ID + original_invoice: + type: + - "null" + - object + description: >- + Details about the original invoice for which the credit payment is + made. + properties: + id: + type: string + description: >- + The ID of the original invoice for which the credit payment was + made. + maxLength: 13 + title: Invoice ID + number: + type: string + description: >- + The number of the original invoice for which the credit payment + was made. + maxLength: 256 + title: Invoice number + title: Invoice mini details + refund_transaction: + type: + - "null" + - object + description: >- + Details about the refund transaction associated with the credit + payment. + properties: + id: + type: string + description: >- + The ID of the refund transaction associated with the credit + payment. + maxLength: 13 + title: Transaction ID + uuid: + type: string + description: >- + The UUID is useful for matching data with the CSV exports and + building URLs into Recurly's UI. + maxLength: 32 + title: Recurly UUID + updated_at: + type: string + description: The date and time when the credit payment was last updated. + format: date-time + readOnly: true + title: Last updated at + uuid: + type: string + description: >- + The UUID is useful for matching data with the CSV exports and building + URLs into Recurly's UI. + maxLength: 32 + title: Recurly UUID + voided_at: + type: + - "null" + - string + description: The date and time when the credit payment was voided. + format: date-time + readOnly: true + title: Voided at + export_dates: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + dates: + type: + - "null" + - array + description: List of export dates + items: + type: + - "null" + - string + description: Date of the export + maxLength: 256 + invoices: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: Invoices are either charge, credit, or legacy invoices. + maxLength: 256 + title: Invoice type + account: + type: + - "null" + - object + description: The account associated with the invoice. + properties: + bill_to: + type: + - "null" + - string + code: + type: + - "null" + - string + company: + type: + - "null" + - string + dunning_campaign_id: + type: + - "null" + - string + email: + type: + - "null" + - string + first_name: + type: + - "null" + - string + id: + type: string + last_name: + type: + - "null" + - string + object: + type: + - "null" + - string + parent_account_id: + type: + - "null" + - string + address: + type: + - "null" + - object + description: The address details related to the invoice recipient. + properties: + city: + type: + - "null" + - string + description: The city in the address. + maxLength: 256 + title: City + company: + type: + - "null" + - string + description: The company name in the address. + maxLength: 256 + title: Company + country: + type: + - "null" + - string + description: Country, 2-letter ISO 3166-1 alpha-2 code. + maxLength: 2 + title: Country + first_name: + type: + - "null" + - string + description: The first name of the recipient. + maxLength: 256 + last_name: + type: + - "null" + - string + description: The last name of the recipient. + maxLength: 256 + name_on_account: + type: + - "null" + - string + description: The name on the account. + maxLength: 256 + title: Name on account + phone: + type: + - "null" + - string + description: The phone number associated with the address. + maxLength: 256 + title: Phone number + postal_code: + type: + - "null" + - string + description: Zip or postal code. + maxLength: 256 + title: Zip/Postal code + region: + type: + - "null" + - string + description: State or province. + maxLength: 256 + title: State/Province + street1: + type: + - "null" + - string + description: The first line of the street address. + maxLength: 256 + title: Street 1 + street2: + type: + - "null" + - string + description: The second line of the street address. + maxLength: 256 + title: Street 2 + balance: + type: + - "null" + - number + description: The outstanding balance remaining on this invoice. + format: float + title: Balance + billing_info_id: + type: + - "null" + - string + description: >- + The `billing_info_id` is the value that represents a specific billing + info for an end customer. When `billing_info_id` is used to assign + billing info to the subscription, all future billing events for the + subscription will bill to the specified billing info. + `billing_info_id` can ONLY be used for sites utilizing the Wallet + feature. + maxLength: 256 + title: Billing info ID + business_entity_id: + type: + - "null" + - string + description: The business entity ID linked to the invoice. + closed_at: + type: + - "null" + - string + description: Date invoice was marked paid or failed. + format: date-time + title: Closed at + collection_method: + type: + - "null" + - string + description: >- + An automatic invoice means a corresponding transaction is run using + the account's billing information at the same time the invoice is + created. Manual invoices are created without a corresponding + transaction. The merchant must enter a manual payment transaction or + have the customer pay the invoice with an automatic method, like + credit card, PayPal, Amazon, or ACH bank payment. + maxLength: 256 + title: Collection method + created_at: + type: + - "null" + - string + description: The date and time when the invoice was created. + format: date-time + readOnly: true + title: Created at + credit_payments: + type: + - "null" + - array + description: The credit payments related to the invoice. + items: + type: + - "null" + - object + properties: + id: + type: string + description: The ID of a credit payment associated with the invoice. + maxLength: 13 + title: Credit Payment ID + uuid: + type: string + description: >- + The UUID is useful for matching data with the CSV exports and + building URLs into Recurly's UI. + maxLength: 32 + title: Recurly UUID + title: Credit payments + currency: + type: + - "null" + - string + description: 3-letter ISO 4217 currency code. + maxLength: 3 + title: Currency + customer_notes: + type: + - "null" + - string + description: >- + This will default to the Customer Notes text specified on the Invoice + Settings. Specify custom notes to add or override Customer Notes. + maxLength: 2048 + title: Customer notes + discount: + type: + - "null" + - number + description: Total discounts applied to this invoice. + format: float + title: Discount + due_at: + type: + - "null" + - string + description: Date invoice is due. This is the date the net terms are reached. + format: date-time + title: Due at + dunning_campaign_id: + type: + - "null" + - string + description: >- + Unique ID to identify the dunning campaign used when dunning the + invoice. Available when the Dunning Campaigns feature is enabled. For + sites without multiple dunning campaigns enabled, this will always be + the default dunning campaign. + maxLength: 256 + title: Dunning Campaign ID + dunning_events_sent: + type: + - "null" + - integer + description: The number of dunning events sent for the invoice. + final_dunning_event: + type: + - "null" + - boolean + description: The final dunning event related to the invoice if applicable. + has_more_line_items: + type: + - "null" + - boolean + description: Indicates if there are more line items in the invoice. + id: + type: + - "null" + - string + description: The unique ID of the invoice. + maxLength: 13 + readOnly: true + title: Invoice ID + line_items: + type: + - "null" + - array + description: The line items included in the invoice. + items: + type: + - "null" + - object + $schema: http://json-schema.org/draft-07/schema# + properties: + type: + type: string + description: >- + Charges are positive line items that debit the account. Credits + are negative line items that credit the account. + maxLength: 256 + title: Line item type + description: + type: string + description: >- + Description that appears on the invoice. For subscription + related items this will be filled in automatically. + maxLength: 255 + title: Description + account: + type: + - "null" + - object + properties: + bill_to: + type: + - "null" + - string + code: + type: + - "null" + - string + company: + type: + - "null" + - string + dunning_campaign_id: + type: + - "null" + - string + email: + type: + - "null" + - string + first_name: + type: + - "null" + - string + id: + type: string + last_name: + type: + - "null" + - string + object: + type: + - "null" + - string + parent_account_id: + type: + - "null" + - string + accounting_code: + type: string + description: >- + Internal accounting code to help you reconcile your revenue to + the correct ledger. Line items created as part of a subscription + invoice will use the plan or add-on's accounting code, otherwise + the value will only be present if you define an accounting code + when creating the line item. + maxLength: 20 + title: Accounting code + add_on_code: + type: + - "null" + - string + description: >- + If the line item is a charge or credit for an add-on, this is + its code. + maxLength: 50 + title: Add-on code + add_on_id: + type: + - "null" + - string + description: >- + If the line item is a charge or credit for an add-on this is its + ID. + maxLength: 13 + title: Add-on ID + amount: + type: number + description: "`(quantity * unit_amount) - (discount + tax)`" + format: float + title: Total after discounts and taxes + bill_for_account_id: + type: string + description: >- + The UUID of the account responsible for originating the line + item. + maxLength: 13 + title: Bill For Account ID + created_at: + type: string + description: When the line item was created. + format: date-time + title: Created at + credit_applied: + type: + - "null" + - number + description: >- + The amount of credit from this line item that was applied to the + invoice. + format: float + title: Credit Applied + credit_reason_code: + type: + - "null" + - string + description: The reason the credit was given when line item is `type=credit`. + default: general + maxLength: 256 + title: Credit reason code + currency: + type: string + description: 3-letter ISO 4217 currency code. + maxLength: 3 + title: Currency + custom_fields: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + name: + type: + - "null" + - string + value: + type: + - "null" + - string + discount: + type: + - "null" + - number + description: The discount applied to the line item. + format: float + title: Discount + end_date: + type: + - "null" + - string + description: If this date is provided, it indicates the end of a time range. + format: date-time + title: End date + external_sku: + type: + - "null" + - string + description: >- + Optional Stock Keeping Unit assigned to an item. Available when + the Credit Invoices and Subscription Billing Terms features are + enabled. + maxLength: 50 + title: External SKU + id: + type: string + maxLength: 13 + title: Line item ID + invoice_id: + type: + - "null" + - string + description: >- + Once the line item has been invoiced this will be the invoice's + ID. + maxLength: 13 + title: Invoice ID + invoice_number: + type: + - "null" + - string + description: >- + Once the line item has been invoiced this will be the invoice's + number. If VAT taxation and the Country Invoice Sequencing + feature are enabled, invoices will have country-specific invoice + numbers for invoices billed to EU countries (ex: FR1001). Non-EU + invoices will continue to use the site-level invoice number + sequence. + maxLength: 256 + title: Invoice number + item_code: + type: + - "null" + - string + description: >- + Unique code to identify an item. Available when the Credit + Invoices and Subscription Billing Terms features are enabled. + maxLength: 50 + title: Item Code + item_id: + type: + - "null" + - string + description: >- + System-generated unique identifier for an item. Available when + the Credit Invoices and Subscription Billing Terms features are + enabled. + maxLength: 13 + title: Item ID + legacy_category: + type: + - "null" + - string + description: > + Category to describe the role of a line item on a legacy + invoice: + + - "charges" refers to charges being billed for on this invoice. + + - "credits" refers to refund or proration credits. This portion + of the invoice can be considered a credit memo. + + - "applied_credits" refers to previous credits applied to this + invoice. See their original_line_item_id to determine where the + credit first originated. + + - "carryforwards" can be ignored. They exist to consume any + remaining credit balance. A new credit with the same amount will + be created and placed back on the account. + title: Legacy category + object: + type: + - "null" + - string + origin: + type: string + description: >- + A credit created from an original charge will have the value of + the charge's origin. + maxLength: 256 + title: Origin of line item + original_line_item_invoice_id: + type: + - "null" + - string + description: >- + The invoice where the credit originated. Will only have a value + if the line item is a credit created from a previous credit, or + if the credit was created from a charge refund. + maxLength: 13 + title: Original line item's invoice ID + plan_code: + type: + - "null" + - string + description: >- + If the line item is a charge or credit for a plan or add-on, + this is the plan's code. + maxLength: 50 + title: Plan code + plan_id: + type: + - "null" + - string + description: >- + If the line item is a charge or credit for a plan or add-on, + this is the plan's ID. + maxLength: 13 + title: Plan ID + previous_line_item_id: + type: + - "null" + - string + description: >- + Will only have a value if the line item is a credit created from + a previous credit, or if the credit was created from a charge + refund. + maxLength: 13 + title: Previous line item ID + product_code: + type: string + description: >- + For plan-related line items this will be the plan's code, for + add-on related line items it will be the add-on's code. For + item-related line items it will be the item's `external_sku`. + maxLength: 50 + title: Product code + proration_rate: + type: + - "null" + - number + description: >- + When a line item has been prorated, this is the rate of the + proration. Proration rates were made available for line items + created after March 30, 2017. For line items created prior to + that date, the proration rate will be `null`, even if the line + item was prorated. + format: float + maximum: 1 + minimum: 0 + title: Proration rate + quantity: + type: integer + description: >- + This number will be multiplied by the unit amount to compute the + subtotal before any discounts or taxes. + default: 1 + title: Quantity + refund: + type: boolean + title: Refund? + refunded_quantity: + type: + - "null" + - integer + description: >- + For refund charges, the quantity being refunded. For non-refund + charges, the total quantity refunded (possibly over multiple + refunds). + title: Refunded Quantity + revenue_schedule_type: + type: + - "null" + - string + maxLength: 256 + title: Revenue schedule type + shipping_address: + type: + - "null" + - object + properties: + id: + type: string + maxLength: 13 + readOnly: true + title: Shipping Address ID + start_date: + type: + - "null" + - string + description: >- + If an end date is present, this is value indicates the beginning + of a billing time range. If no end date is present it indicates + billing for a specific date. + format: date-time + title: Start date + state: + type: string + description: >- + Pending line items are charges or credits on an account that + have not been applied to an invoice yet. Invoiced line items + will always have an `invoice_id` value. + maxLength: 256 + title: Current state of the line item + subscription_id: + type: + - "null" + - string + description: >- + If the line item is a charge or credit for a subscription, this + is its ID. + maxLength: 13 + title: Subscription ID + subtotal: + type: number + description: "`quantity * unit_amount`" + format: float + title: Total before discounts and taxes + tax: + type: + - "null" + - number + description: The tax amount for the line item. + format: float + title: Tax + tax_code: + type: + - "null" + - string + description: >- + Used by Avalara, Vertex, and Recurly’s EU VAT tax feature. The + tax code values are specific to each tax system. If you are + using Recurly’s EU VAT feature you can use `unknown`, + `physical`, or `digital`. + maxLength: 50 + title: Tax code + tax_exempt: + type: boolean + description: >- + `true` exempts tax on charges, `false` applies tax on charges. + If not defined, then defaults to the Plan and Site settings. + This attribute does not work for credits (negative line items). + Credits are always applied post-tax. Pre-tax discounts should + use the Coupons feature. + title: Tax exempt? + tax_info: + type: + - "null" + - object + $schema: http://json-schema.org/draft-07/schema# + properties: + type: + type: + - "null" + - string + rate: + type: + - "null" + - number + region: + type: + - "null" + - string + tax_details: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + billable: + type: + - "null" + - boolean + level: + type: + - "null" + - string + name: + type: + - "null" + - string + rate: + type: + - "null" + - number + region: + type: + - "null" + - string + tax: + type: + - "null" + - number + taxable: + type: boolean + description: "`true` if the line item is taxable, `false` if it is not." + title: Taxable? + unit_amount: + type: number + description: Positive amount for a charge, negative amount for a credit. + format: float + title: Unit amount + unit_amount_decimal: + type: + - "null" + - string + description: Positive amount for a charge, negative amount for a credit. + title: Unit amount decimal + updated_at: + type: string + description: When the line item was last changed. + format: date-time + title: Last updated at + uuid: + type: string + description: >- + The UUID is useful for matching data with the CSV exports and + building URLs into Recurly's UI. + maxLength: 32 + title: UUID + title: Line item + title: Line Items + net_terms: + type: + - "null" + - integer + description: >- + Integer representing the number of days after an invoice's creation + that the invoice will become past due. If an invoice's net terms are + set to '0', it is due 'On Receipt' and will become past due 24 hours + after it’s created. If an invoice is due net 30, it will become past + due at 31 days exactly. + default: 0 + minimum: 0 + title: Net terms + number: + type: + - "null" + - string + description: >- + If VAT taxation and the Country Invoice Sequencing feature are + enabled, invoices will have country-specific invoice numbers for + invoices billed to EU countries (ex: FR1001). Non-EU invoices will + continue to use the site-level invoice number sequence. + maxLength: 256 + title: Invoice number + object: + type: + - "null" + - string + description: The type of object, in this case, an invoice. + origin: + type: + - "null" + - string + description: The event that created the invoice. + maxLength: 256 + title: Origin + paid: + type: + - "null" + - number + description: The total amount of successful payments transaction on this invoice. + format: float + title: Paid + po_number: + type: + - "null" + - string + description: >- + For manual invoicing, this identifies the PO number associated with + the subscription. + maxLength: 50 + title: Purchase order number + previous_invoice_id: + type: + - "null" + - string + description: >- + On refund invoices, this value will exist and show the invoice ID of + the purchase invoice the refund was created from. + maxLength: 13 + title: Previous invoice ID + refundable_amount: + type: + - "null" + - number + description: >- + The refundable amount on a charge invoice. It will be null for all + other invoices. + format: float + title: Refundable amount + shipping_address: + type: + - "null" + - object + description: The shipping address details for the invoice delivery. + properties: + id: + type: + - "null" + - string + description: The ID of the shipping address. + maxLength: 13 + readOnly: true + title: Shipping Address ID + state: + type: + - "null" + - string + description: The current state of the invoice. + maxLength: 256 + title: Invoice state + subscription_ids: + type: + - "null" + - array + description: >- + If the invoice is charging or refunding for one or more subscriptions, + these are their IDs. + items: + type: + - "null" + - string + maxLength: 13 + title: Subscription ID + title: Subscription IDs + subtotal: + type: + - "null" + - number + description: The summation of charges and credits, before discounts and taxes. + format: float + title: Subtotal + tax: + type: + - "null" + - number + description: The total tax on this invoice. + format: float + title: Tax + tax_info: + type: + - "null" + - object + description: Tax information related to the invoice. + properties: + type: + type: + - "null" + - string + description: >- + Provides the tax type as "vat" for EU VAT, "usst" for U.S. Sales + Tax, or the 2 letter country code for country level tax types like + Canada, Australia, New Zealand, Israel, and all non-EU European + countries. + maxLength: 256 + title: Type + rate: + type: + - "null" + - number + description: The tax rate applied to the invoice. + format: float + title: Rate + region: + type: + - "null" + - string + description: >- + Provides the tax region applied on an invoice. For U.S. Sales Tax, + this will be the 2 letter state code. For EU VAT this will be the + 2 letter country code. For all country level tax types, this will + display the regional tax, like VAT, GST, or PST. + title: Region + tax_details: + type: array + description: >- + Provides additional tax details for Canadian Sales Tax when there + is tax applied at both the country and province levels. This will + only be populated for the Invoice response when fetching a single + invoice and not for the InvoiceList or LineItem. + items: + type: object + properties: + type: + type: + - "null" + - string + description: >- + Provides the tax type for the region. For Canadian Sales + Tax, this will be GST, HST, QST or PST. + maxLength: 256 + title: Type + rate: + type: + - "null" + - number + description: Provides the tax rate for the region. + format: float + title: Rate + region: + type: + - "null" + - string + description: >- + Provides the tax region applied on an invoice. For Canadian + Sales Tax, this will be either the 2 letter province code or + country code. + maxLength: 256 + title: Region + tax: + type: + - "null" + - number + description: The total tax applied for this tax type. + format: float + title: Tax + title: Tax detail + title: Tax info + terms_and_conditions: + type: + - "null" + - string + description: >- + This will default to the Terms and Conditions text specified on the + Invoice Settings page in your Recurly admin. Specify custom notes to + add or override Terms and Conditions. + maxLength: 16384 + title: Terms and conditions + total: + type: + - "null" + - number + description: >- + The final total on this invoice. The summation of invoice charges, + discounts, credits, and tax. + format: float + title: Total + transactions: + type: + - "null" + - array + description: The transactions associated with the invoice. + items: + type: + - "null" + - object + properties: + id: + type: string + description: The ID of a transaction linked to the invoice. + maxLength: 13 + title: Transaction ID + uuid: + type: string + description: >- + The UUID is useful for matching data with the CSV exports and + building URLs into Recurly's UI. + maxLength: 32 + title: Recurly UUID + title: Transactions + updated_at: + type: + - "null" + - string + description: The date and time when the invoice was last updated. + format: date-time + readOnly: true + title: Last updated at + used_tax_service: + type: + - "null" + - boolean + description: Indicates if a tax service was used for the invoice. + uuid: + type: + - "null" + - string + description: The universally unique identifier (UUID) of the invoice. + vat_number: + type: + - "null" + - string + description: >- + VAT registration number for the customer on this invoice. This will + come from the VAT Number field in the Billing Info or the Account Info + depending on your tax settings and the invoice collection method. + maxLength: 20 + title: VAT number + vat_reverse_charge_notes: + type: + - "null" + - string + description: >- + VAT Reverse Charge Notes only appear if you have EU VAT enabled or are + using your own Avalara AvaTax account and the customer is in the EU, + has a VAT number, and is in a different country than your own. This + will default to the VAT Reverse Charge Notes text specified on the Tax + Settings page in your Recurly admin, unless custom notes were created + with the original subscription. + maxLength: 1024 + title: VAT reverse charge notes + line_items: + type: + - "null" + - object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + type: + type: string + description: >- + Charges are positive line items that debit the account. Credits are + negative line items that credit the account. + maxLength: 256 + title: Line item type + description: + type: string + description: >- + Description that appears on the invoice. For subscription related + items this will be filled in automatically. + maxLength: 255 + title: Description + account: + type: + - "null" + - object + properties: + bill_to: + type: + - "null" + - string + code: + type: + - "null" + - string + company: + type: + - "null" + - string + dunning_campaign_id: + type: + - "null" + - string + email: + type: + - "null" + - string + first_name: + type: + - "null" + - string + id: + type: string + last_name: + type: + - "null" + - string + object: + type: + - "null" + - string + parent_account_id: + type: + - "null" + - string + accounting_code: + type: string + description: >- + Internal accounting code to help you reconcile your revenue to the + correct ledger. Line items created as part of a subscription invoice + will use the plan or add-on's accounting code, otherwise the value + will only be present if you define an accounting code when creating + the line item. + maxLength: 20 + title: Accounting code + add_on_code: + type: + - "null" + - string + description: >- + If the line item is a charge or credit for an add-on, this is its + code. + maxLength: 50 + title: Add-on code + add_on_id: + type: + - "null" + - string + description: If the line item is a charge or credit for an add-on this is its ID. + maxLength: 13 + title: Add-on ID + amount: + type: number + description: "`(quantity * unit_amount) - (discount + tax)`" + format: float + title: Total after discounts and taxes + bill_for_account_id: + type: string + description: The UUID of the account responsible for originating the line item. + maxLength: 13 + title: Bill For Account ID + created_at: + type: string + description: When the line item was created. + format: date-time + title: Created at + credit_applied: + type: + - "null" + - number + description: >- + The amount of credit from this line item that was applied to the + invoice. + format: float + title: Credit Applied + credit_reason_code: + type: + - "null" + - string + description: The reason the credit was given when line item is `type=credit`. + default: general + maxLength: 256 + title: Credit reason code + currency: + type: string + description: 3-letter ISO 4217 currency code. + maxLength: 3 + title: Currency + custom_fields: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + name: + type: + - "null" + - string + value: + type: + - "null" + - string + discount: + type: + - "null" + - number + description: The discount applied to the line item. + format: float + title: Discount + end_date: + type: + - "null" + - string + description: If this date is provided, it indicates the end of a time range. + format: date-time + title: End date + external_sku: + type: + - "null" + - string + description: >- + Optional Stock Keeping Unit assigned to an item. Available when the + Credit Invoices and Subscription Billing Terms features are enabled. + maxLength: 50 + title: External SKU + id: + type: string + maxLength: 13 + title: Line item ID + invoice_id: + type: + - "null" + - string + description: Once the line item has been invoiced this will be the invoice's ID. + maxLength: 13 + title: Invoice ID + invoice_number: + type: + - "null" + - string + description: >- + Once the line item has been invoiced this will be the invoice's + number. If VAT taxation and the Country Invoice Sequencing feature are + enabled, invoices will have country-specific invoice numbers for + invoices billed to EU countries (ex: FR1001). Non-EU invoices will + continue to use the site-level invoice number sequence. + maxLength: 256 + title: Invoice number + item_code: + type: + - "null" + - string + description: >- + Unique code to identify an item. Available when the Credit Invoices + and Subscription Billing Terms features are enabled. + maxLength: 50 + title: Item Code + item_id: + type: + - "null" + - string + description: >- + System-generated unique identifier for an item. Available when the + Credit Invoices and Subscription Billing Terms features are enabled. + maxLength: 13 + title: Item ID + legacy_category: + type: + - "null" + - string + description: > + Category to describe the role of a line item on a legacy invoice: + + - "charges" refers to charges being billed for on this invoice. + + - "credits" refers to refund or proration credits. This portion of the + invoice can be considered a credit memo. + + - "applied_credits" refers to previous credits applied to this + invoice. See their original_line_item_id to determine where the credit + first originated. + + - "carryforwards" can be ignored. They exist to consume any remaining + credit balance. A new credit with the same amount will be created and + placed back on the account. + title: Legacy category + object: + type: + - "null" + - string + origin: + type: string + description: >- + A credit created from an original charge will have the value of the + charge's origin. + maxLength: 256 + title: Origin of line item + original_line_item_invoice_id: + type: + - "null" + - string + description: >- + The invoice where the credit originated. Will only have a value if the + line item is a credit created from a previous credit, or if the credit + was created from a charge refund. + maxLength: 13 + title: Original line item's invoice ID + plan_code: + type: + - "null" + - string + description: >- + If the line item is a charge or credit for a plan or add-on, this is + the plan's code. + maxLength: 50 + title: Plan code + plan_id: + type: + - "null" + - string + description: >- + If the line item is a charge or credit for a plan or add-on, this is + the plan's ID. + maxLength: 13 + title: Plan ID + previous_line_item_id: + type: + - "null" + - string + description: >- + Will only have a value if the line item is a credit created from a + previous credit, or if the credit was created from a charge refund. + maxLength: 13 + title: Previous line item ID + product_code: + type: string + description: >- + For plan-related line items this will be the plan's code, for add-on + related line items it will be the add-on's code. For item-related line + items it will be the item's `external_sku`. + maxLength: 50 + title: Product code + proration_rate: + type: + - "null" + - number + description: >- + When a line item has been prorated, this is the rate of the proration. + Proration rates were made available for line items created after March + 30, 2017. For line items created prior to that date, the proration + rate will be `null`, even if the line item was prorated. + format: float + maximum: 1 + minimum: 0 + title: Proration rate + quantity: + type: integer + description: >- + This number will be multiplied by the unit amount to compute the + subtotal before any discounts or taxes. + default: 1 + title: Quantity + refund: + type: boolean + title: Refund? + refunded_quantity: + type: + - "null" + - integer + description: >- + For refund charges, the quantity being refunded. For non-refund + charges, the total quantity refunded (possibly over multiple refunds). + title: Refunded Quantity + revenue_schedule_type: + type: + - "null" + - string + maxLength: 256 + title: Revenue schedule type + shipping_address: + type: + - "null" + - object + properties: + id: + type: string + maxLength: 13 + readOnly: true + title: Shipping Address ID + start_date: + type: + - "null" + - string + description: >- + If an end date is present, this is value indicates the beginning of a + billing time range. If no end date is present it indicates billing for + a specific date. + format: date-time + title: Start date + state: + type: string + description: >- + Pending line items are charges or credits on an account that have not + been applied to an invoice yet. Invoiced line items will always have + an `invoice_id` value. + maxLength: 256 + title: Current state of the line item + subscription_id: + type: + - "null" + - string + description: >- + If the line item is a charge or credit for a subscription, this is its + ID. + maxLength: 13 + title: Subscription ID + subtotal: + type: number + description: "`quantity * unit_amount`" + format: float + title: Total before discounts and taxes + tax: + type: + - "null" + - number + description: The tax amount for the line item. + format: float + title: Tax + tax_code: + type: + - "null" + - string + description: >- + Used by Avalara, Vertex, and Recurly’s EU VAT tax feature. The tax + code values are specific to each tax system. If you are using + Recurly’s EU VAT feature you can use `unknown`, `physical`, or + `digital`. + maxLength: 50 + title: Tax code + tax_exempt: + type: boolean + description: >- + `true` exempts tax on charges, `false` applies tax on charges. If not + defined, then defaults to the Plan and Site settings. This attribute + does not work for credits (negative line items). Credits are always + applied post-tax. Pre-tax discounts should use the Coupons feature. + title: Tax exempt? + tax_info: + type: + - "null" + - object + $schema: http://json-schema.org/draft-07/schema# + properties: + type: + type: + - "null" + - string + rate: + type: + - "null" + - number + region: + type: + - "null" + - string + tax_details: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + billable: + type: + - "null" + - boolean + level: + type: + - "null" + - string + name: + type: + - "null" + - string + rate: + type: + - "null" + - number + region: + type: + - "null" + - string + tax: + type: + - "null" + - number + taxable: + type: boolean + description: "`true` if the line item is taxable, `false` if it is not." + title: Taxable? + unit_amount: + type: number + description: Positive amount for a charge, negative amount for a credit. + format: float + title: Unit amount + unit_amount_decimal: + type: + - "null" + - string + description: Positive amount for a charge, negative amount for a credit. + title: Unit amount decimal + updated_at: + type: string + description: When the line item was last changed. + format: date-time + title: Last updated at + uuid: + type: string + description: >- + The UUID is useful for matching data with the CSV exports and building + URLs into Recurly's UI. + maxLength: 32 + title: UUID + title: Line item + measured_units: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + description: + type: + - "null" + - string + description: Description of the measured unit + maxLength: 1024 + created_at: + type: + - "null" + - string + description: Timestamp indicating when the measured unit was created + format: date-time + deleted_at: + type: + - "null" + - string + description: >- + Timestamp indicating when the measured unit was deleted (if + applicable) + format: date-time + display_name: + type: + - "null" + - string + description: Human-readable name used for display purposes + maxLength: 255 + id: + type: + - "null" + - string + description: Unique identifier for the measured unit + maxLength: 13 + name: + type: + - "null" + - string + description: Internal name used to identify the measured unit + maxLength: 256 + object: + type: + - "null" + - string + description: Type of object, in this case, 'measured_unit' + state: + type: + - "null" + - string + description: Current state of the measured unit + maxLength: 255 + updated_at: + type: + - "null" + - string + description: Timestamp indicating when the measured unit was last updated + format: date-time + plans: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + description: + type: + - "null" + - string + description: Description of the plan. + maxLength: 1024 + accounting_code: + type: + - "null" + - string + description: The accounting code associated with the plan. + maxLength: 256 + allow_any_item_on_subscriptions: + type: + - "null" + - boolean + description: Determines if any item can be added to subscriptions using this plan. + auto_renew: + type: + - "null" + - boolean + description: Indicates whether the plan should automatically renew. + avalara_service_type: + type: + - "null" + - number + description: The Avalara service type used for tax calculation. + avalara_transaction_type: + type: + - "null" + - number + description: The Avalara transaction type used for tax calculation. + code: + type: + - "null" + - string + description: Unique identifier code for the plan. + maxLength: 256 + created_at: + type: + - "null" + - string + description: Timestamp indicating when the plan was created. + format: date-time + currencies: + type: array + description: Contains information about the currencies supported by the plan. + items: + type: object + properties: + currency: + type: string + description: 3-letter ISO 4217 currency code. + maxLength: 3 + title: Currency + setup_fee: + type: number + description: >- + Amount of one-time setup fee automatically charged at the + beginning of a subscription billing cycle. For subscription + plans with a trial, the setup fee will be charged at the time of + signup. Setup fees do not increase with the quantity of a + subscription plan. + format: float + maximum: 1000000 + minimum: 0 + title: Setup fee + unit_amount: + type: number + description: Unit amount for the currency in the plan. + format: float + maximum: 1000000 + minimum: 0 + title: Unit price + title: Pricing + custom_fields: + type: + - "null" + - array + description: Includes any custom fields associated with the plan. + items: + type: + - "null" + - object + properties: + name: + type: + - "null" + - string + description: Name of the custom field. + value: + type: + - "null" + - string + description: Value of the custom field. + deleted_at: + type: + - "null" + - string + description: Timestamp indicating when the plan was deleted. + format: date-time + dunning_campaign_id: + type: + - "null" + - string + description: ID of the dunning campaign associated with the plan. + maxLength: 256 + hosted_pages: + type: object + description: Provides details about hosted pages related to the plan. + properties: + bypass_confirmation: + type: + - "null" + - boolean + description: Determines if confirmation is bypassed on hosted pages. + cancel_url: + type: + - "null" + - string + description: URL to redirect when a user cancels during hosted page process. + maxLength: 2048 + display_quantity: + type: + - "null" + - boolean + description: Determines if quantity is displayed on hosted pages. + success_url: + type: + - "null" + - string + description: >- + URL to redirect when a user successfully completes hosted page + process. + maxLength: 2048 + id: + type: + - "null" + - string + description: Unique identifier of the plan. + maxLength: 13 + interval_length: + type: + - "null" + - number + description: Length of the billing interval for the plan. + interval_unit: + type: + - "null" + - string + description: Unit of the billing interval for the plan. + maxLength: 256 + name: + type: + - "null" + - string + description: Name of the plan. + maxLength: 256 + object: + type: + - "null" + - string + description: Indicates the type of object which in this case is 'plan'. + pricing_model: + type: + - "null" + - string + description: The pricing model used for the plan. + ramp_intervals: + type: + - "null" + - array + description: Specifies ramp intervals for the plan. + items: + type: + - "null" + - object + properties: + currencies: + type: + - "null" + - array + description: Contains currencies information within the ramp intervals. + items: + type: + - "null" + - object + properties: + currency: + type: + - "null" + - string + description: Currency code for the interval. + unit_amount: + type: + - "null" + - number + description: Unit amount for the currency in the interval. + starting_billing_cycle: + type: + - "null" + - integer + description: The starting billing cycle for the ramp interval. + revenue_schedule_type: + type: + - "null" + - string + description: Type of revenue schedule for the plan. + maxLength: 256 + setup_fee_accounting_code: + type: + - "null" + - string + description: The accounting code associated with the setup fee. + maxLength: 256 + setup_fee_revenue_schedule_type: + type: + - "null" + - string + description: Revenue schedule type for the setup fee. + maxLength: 256 + state: + type: + - "null" + - string + description: The current state of the plan. + maxLength: 256 + tax_code: + type: + - "null" + - string + description: Tax code used for the plan. + maxLength: 256 + tax_exempt: + type: + - "null" + - boolean + description: Determines if the plan is tax exempt. + total_billing_cycles: + type: + - "null" + - number + description: Total number of billing cycles the plan will run for. + trial_length: + type: + - "null" + - number + description: Length of the trial period for the plan. + trial_requires_billing_info: + type: + - "null" + - boolean + description: Determines if billing information is required for the trial. + trial_unit: + type: + - "null" + - string + description: Unit of the trial period for the plan. + maxLength: 256 + updated_at: + type: + - "null" + - string + description: Timestamp indicating when the plan was last updated. + format: date-time + shipping_addresses: + type: + - "null" + - object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + account_id: + type: string + maxLength: 13 + readOnly: true + title: Account ID + city: + type: string + maxLength: 255 + company: + type: string + maxLength: 255 + country: + type: string + description: Country, 2-letter ISO 3166-1 alpha-2 code. + maxLength: 50 + created_at: + type: string + format: date-time + readOnly: true + title: Created at + email: + type: string + maxLength: 255 + first_name: + type: string + maxLength: 255 + geo_code: + type: + - "null" + - string + id: + type: string + maxLength: 13 + readOnly: true + title: Shipping Address ID + last_name: + type: string + maxLength: 255 + nickname: + type: string + maxLength: 255 + object: + type: + - "null" + - string + phone: + type: string + maxLength: 30 + postal_code: + type: string + description: Zip or postal code. + maxLength: 20 + region: + type: string + description: State or province. + maxLength: 255 + street1: + type: string + maxLength: 255 + street2: + type: string + maxLength: 255 + updated_at: + type: string + format: date-time + readOnly: true + title: Updated at + vat_number: + type: string + maxLength: 20 + shipping_methods: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accounting_code: + type: string + description: Accounting code for shipping method. + maxLength: 20 + title: Accounting Code + code: + type: string + description: The internal name used identify the shipping method. + maxLength: 50 + title: Code + created_at: + type: string + description: Timestamp indicating when the shipping method was created + format: date-time + readOnly: true + title: Created at + deleted_at: + type: string + description: Timestamp indicating when the shipping method was deleted + format: date-time + readOnly: true + title: Deleted at + id: + type: string + description: Unique identifier for the shipping method + maxLength: 13 + readOnly: true + title: Shipping Method ID + name: + type: string + description: The name of the shipping method displayed to customers. + maxLength: 100 + title: Name + tax_code: + type: string + description: > + Used by Avalara, Vertex, and Recurly’s built-in tax feature. The tax + + code values are specific to each tax system. If you are using + Recurly’s + + built-in taxes the values are: + + + - `FR` – Common Carrier FOB Destination + + - `FR022000` – Common Carrier FOB Origin + + - `FR020400` – Non Common Carrier FOB Destination + + - `FR020500` – Non Common Carrier FOB Origin + + - `FR010100` – Delivery by Company Vehicle Before Passage of Title + + - `FR010200` – Delivery by Company Vehicle After Passage of Title + + - `NT` – Non-Taxable + maxLength: 50 + title: Tax code + updated_at: + type: string + description: Timestamp indicating when the shipping method was last updated + format: date-time + readOnly: true + title: Last updated at + subscriptions: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + account: + type: + - "null" + - object + description: Information about the associated account for the subscription + properties: + bill_to: + type: + - "null" + - string + code: + type: + - "null" + - string + maxLength: 256 + company: + type: + - "null" + - string + dunning_campaign_id: + type: + - "null" + - string + email: + type: + - "null" + - string + maxLength: 256 + first_name: + type: + - "null" + - string + id: + type: + - "null" + - string + maxLength: 13 + last_name: + type: + - "null" + - string + object: + type: + - "null" + - string + parent_account_id: + type: + - "null" + - string + action_result: + type: + - "null" + - object + description: Result of the action performed on the subscription. + additionalProperties: true + activated_at: + type: + - "null" + - string + description: Timestamp when the subscription was activated + format: date-time + active_invoice_id: + type: + - "null" + - string + description: ID of the active invoice associated with the subscription. + add_ons: + type: + - "null" + - array + description: Any additional services or items added to the subscription. + items: + type: + - "null" + - object + description: This links an Add-on to a specific Subscription. + properties: + code: + type: string + description: The unique identifier for the add-on within its plan. + maxLength: 50 + title: Add-on code + id: + type: string + maxLength: 13 + title: Subscription Add-on ID + title: Subscription Add-on + title: Add-ons + add_ons_total: + type: + - "null" + - number + description: Total amount charged for the additional services or items. + auto_renew: + type: + - "null" + - boolean + description: Flag indicating whether the subscription auto renews. + bank_account_authorized_at: + type: + - "null" + - string + description: Timestamp when bank account authorization occurred + format: date-time + billing_info_id: + type: + - "null" + - string + description: ID of the billing information associated with the subscription. + maxLength: 13 + canceled_at: + type: + - "null" + - string + description: Timestamp when the subscription was canceled + format: date-time + collection_method: + type: + - "null" + - string + description: Method used for collecting payments for the subscription. + maxLength: 256 + converted_at: + type: + - "null" + - string + description: Timestamp when the subscription was converted + format: date-time + coupon_redemptions: + type: + - "null" + - object + description: Details of any coupons redeemed for the subscription. + $schema: http://json-schema.org/draft-07/schema# + properties: + coupon: + type: + - "null" + - object + properties: + code: + type: + - "null" + - string + coupon_type: + type: + - "null" + - string + discount: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + currencies: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + amount: + type: + - "null" + - number + currency: + type: + - "null" + - string + percent: + type: + - "null" + - integer + trial: + type: + - "null" + - object + properties: + length: + type: + - "null" + - integer + unit: + type: + - "null" + - string + expired_at: + type: + - "null" + - string + format: date-time + id: + type: + - "null" + - string + name: + type: + - "null" + - string + object: + type: + - "null" + - string + state: + type: + - "null" + - string + created_at: + type: + - "null" + - string + format: date-time + discounted: + type: + - "null" + - number + id: + type: + - "null" + - string + object: + type: + - "null" + - string + state: + type: + - "null" + - string + created_at: + type: + - "null" + - string + description: Timestamp when the subscription was created + format: date-time + currency: + type: + - "null" + - string + description: Currency used for billing the subscription. + maxLength: 3 + current_period_ends_at: + type: + - "null" + - string + description: Timestamp when the current period ends + format: date-time + current_period_started_at: + type: + - "null" + - string + description: Timestamp when the current period started + format: date-time + current_term_ends_at: + type: + - "null" + - string + description: Timestamp when the current term ends + format: date-time + current_term_started_at: + type: + - "null" + - string + description: Timestamp when the current term started + format: date-time + custom_fields: + type: + - "null" + - array + description: Custom fields associated with the subscription + items: + type: + - "null" + - object + properties: + name: + type: + - "null" + - string + value: + type: + - "null" + - string + customer_notes: + type: + - "null" + - string + description: Any notes or comments added by the customer. + maxLength: 1024 + expiration_reason: + type: + - "null" + - string + description: Reason for the subscription expiration. + maxLength: 1024 + expires_at: + type: + - "null" + - string + description: Timestamp when the subscription expires + format: date-time + gateway_code: + type: + - "null" + - string + description: Code associated with the payment gateway used for processing payments. + maxLength: 256 + id: + type: + - "null" + - string + description: Unique identifier for the subscription. + maxLength: 13 + net_terms: + type: + - "null" + - number + description: Number of net terms for payment. + net_terms_type: + type: + - "null" + - string + description: Type of net terms (e.g., days). + object: + type: + - "null" + - string + description: Indicates the type of object (subscription). + paused_at: + type: + - "null" + - string + description: Timestamp when the subscription was paused + format: date-time + pending_change: + type: + - "null" + - object + description: Information about any pending changes to the subscription + properties: + activate_at: + type: string + description: Timestamp when the pending change will be activated + format: date-time + readOnly: true + title: Activated at + activated: + type: boolean + description: Returns `true` if the subscription change is activated. + title: Activated? + created_at: + type: string + description: Timestamp when the pending change was created + format: date-time + readOnly: true + title: Created at + deleted_at: + type: string + description: Timestamp when the pending change was deleted + format: date-time + readOnly: true + title: Deleted at + id: + type: string + description: The ID of the Subscription Change. + maxLength: 13 + title: Subscription Change ID + subscription_id: + type: string + description: The ID of the subscription that is going to be changed. + maxLength: 13 + title: Subscription ID + updated_at: + type: string + description: Timestamp when the pending change was last updated + format: date-time + readOnly: true + title: Updated at + title: Subscription Change + plan: + type: object + description: Information about the plan associated with the subscription + properties: + code: + type: + - "null" + - string + maxLength: 256 + id: + type: + - "null" + - string + maxLength: 13 + name: + type: + - "null" + - string + object: + type: + - "null" + - string + po_number: + type: + - "null" + - string + description: Purchase order number associated with the subscription. + maxLength: 256 + quantity: + type: + - "null" + - number + description: Number of units or items included in the subscription. + ramp_intervals: + type: + - "null" + - array + description: Information about any ramp intervals associated with the subscription + items: + type: + - "null" + - object + properties: + ending_on: + type: + - "null" + - string + description: Timestamp when the ramp interval ends + format: date-time + remaining_billing_cycles: + type: + - "null" + - integer + starting_billing_cycle: + type: + - "null" + - integer + starting_on: + type: + - "null" + - string + description: Timestamp when the ramp interval starts + format: date-time + unit_amount: + type: + - "null" + - number + remaining_billing_cycles: + type: + - "null" + - number + description: Number of billing cycles remaining before subscription ends. + remaining_pause_cycles: + type: + - "null" + - number + description: Number of pause cycles remaining for the subscription. + renewal_billing_cycles: + type: + - "null" + - number + description: Number of billing cycles in the renewal period. + revenue_schedule_type: + type: + - "null" + - string + description: Type of revenue schedule for the subscription. + maxLength: 256 + shipping: + type: + - "null" + - object + description: Information about the shipping associated with the subscription + properties: + address: + type: + - "null" + - object + $schema: http://json-schema.org/draft-07/schema# + properties: + account_id: + type: string + maxLength: 13 + readOnly: true + title: Account ID + city: + type: string + maxLength: 255 + company: + type: string + maxLength: 255 + country: + type: string + description: Country, 2-letter ISO 3166-1 alpha-2 code. + maxLength: 50 + created_at: + type: string + format: date-time + readOnly: true + title: Created at + email: + type: string + maxLength: 255 + first_name: + type: string + maxLength: 255 + geo_code: + type: + - "null" + - string + id: + type: string + maxLength: 13 + readOnly: true + title: Shipping Address ID + last_name: + type: string + maxLength: 255 + nickname: + type: string + maxLength: 255 + object: + type: + - "null" + - string + phone: + type: string + maxLength: 30 + postal_code: + type: string + description: Zip or postal code. + maxLength: 20 + region: + type: string + description: State or province. + maxLength: 255 + street1: + type: string + maxLength: 255 + street2: + type: string + maxLength: 255 + updated_at: + type: string + format: date-time + readOnly: true + title: Updated at + vat_number: + type: string + maxLength: 20 + amount: + type: + - "null" + - number + method: + type: + - "null" + - object + description: Information about the shipping method + properties: + code: + type: + - "null" + - string + id: + type: string + maxLength: 13 + readOnly: true + title: Shipping Method ID + name: + type: + - "null" + - string + object: + type: + - "null" + - string + object: + type: + - "null" + - string + started_with_gift: + type: + - "null" + - boolean + description: Indicates if the subscription started with a gift or promotion. + state: + type: + - "null" + - string + description: Current state of the subscription (e.g., active, cancelled). + maxLength: 256 + subtotal: + type: + - "null" + - number + description: Subtotal amount before taxes and additional charges. + tax: + type: + - "null" + - number + description: Total tax amount applied to the subscription. + tax_inclusive: + type: + - "null" + - boolean + description: Flag indicating if taxes are included in the total amount. + tax_info: + type: + - "null" + - object + description: Details of the tax information for the subscription. + $schema: http://json-schema.org/draft-07/schema# + properties: + type: + type: + - "null" + - string + rate: + type: + - "null" + - number + region: + type: + - "null" + - string + tax_details: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + billable: + type: + - "null" + - boolean + level: + type: + - "null" + - string + name: + type: + - "null" + - string + rate: + type: + - "null" + - number + region: + type: + - "null" + - string + tax: + type: + - "null" + - number + terms_and_conditions: + type: + - "null" + - string + description: Terms and conditions agreed upon for the subscription. + maxLength: 16384 + total: + type: + - "null" + - number + description: Total amount including taxes and additional charges. + total_billing_cycles: + type: + - "null" + - number + description: Total number of billing cycles for the subscription. + trial_ends_at: + type: + - "null" + - string + description: Timestamp when the trial period ends + format: date-time + trial_started_at: + type: + - "null" + - string + description: Timestamp when the trial period started + format: date-time + unit_amount: + type: + - "null" + - number + description: Amount charged per unit for the subscription. + updated_at: + type: + - "null" + - string + description: Timestamp when the subscription was last updated + format: date-time + uuid: + type: + - "null" + - string + description: Universally unique identifier for the subscription. + maxLength: 32 + transactions: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: Type of transaction + maxLength: 256 + account: + type: + - "null" + - object + description: Details of the account associated with the transaction + properties: + bill_to: + type: + - "null" + - string + code: + type: + - "null" + - string + company: + type: + - "null" + - string + dunning_campaign_id: + type: + - "null" + - string + email: + type: + - "null" + - string + first_name: + type: + - "null" + - string + id: + type: string + last_name: + type: + - "null" + - string + object: + type: + - "null" + - string + parent_account_id: + type: + - "null" + - string + action_result: + type: + - "null" + - object + description: Result of the action taken for the transaction + additionalProperties: true + amount: + type: + - "null" + - number + description: Amount of the transaction + avs_check: + type: + - "null" + - string + description: Result of the Address Verification System check + maxLength: 256 + backup_payment_method_used: + type: + - "null" + - boolean + description: Indicates whether a backup payment method was used + billing_address: + type: object + description: Billing address details of the transaction + properties: + city: + type: + - "null" + - string + maxLength: 256 + country: + type: + - "null" + - string + maxLength: 256 + first_name: + type: + - "null" + - string + maxLength: 256 + geo_code: + type: + - "null" + - string + last_name: + type: + - "null" + - string + maxLength: 256 + phone: + type: + - "null" + - string + maxLength: 256 + postal_code: + type: + - "null" + - string + maxLength: 256 + region: + type: + - "null" + - string + maxLength: 256 + street1: + type: + - "null" + - string + maxLength: 256 + street2: + type: + - "null" + - string + maxLength: 256 + collected_at: + type: + - "null" + - string + description: Date and time when the transaction was collected + format: date-time + collection_method: + type: + - "null" + - string + description: Method used to collect the transaction + maxLength: 256 + created_at: + type: + - "null" + - string + description: Date and time when the transaction was created + format: date-time + currency: + type: + - "null" + - string + description: Currency used for the transaction + maxLength: 3 + customer_message: + type: + - "null" + - string + description: Message for the customer related to the transaction + maxLength: 1024 + customer_message_locale: + type: + - "null" + - string + description: Locale of the customer message + maxLength: 12 + cvv_check: + type: + - "null" + - string + description: Result of the CVV check + maxLength: 256 + fraud_info: + type: + - "null" + - object + description: Information related to fraud check for the transaction + properties: + decision: + type: + - "null" + - string + object: + type: + - "null" + - string + reference: + type: + - "null" + - string + risk_rules_triggered: + type: + - "null" + - array + items: + type: + - "null" + - object + description: Details of individual risk rules triggered + properties: + code: + type: + - "null" + - string + message: + type: + - "null" + - string + score: + type: + - "null" + - integer + gateway_approval_code: + type: + - "null" + - string + description: Approval code provided by the payment gateway + maxLength: 256 + gateway_message: + type: + - "null" + - string + description: Message returned by the payment gateway + maxLength: 256 + gateway_reference: + type: + - "null" + - string + description: Reference number provided by the payment gateway + maxLength: 256 + gateway_response_code: + type: + - "null" + - string + description: Response code from the payment gateway + maxLength: 256 + gateway_response_time: + type: + - "null" + - number + description: Time taken for the payment gateway to respond + gateway_response_values: + type: object + description: Additional values in the gateway response + id: + type: + - "null" + - string + description: Unique identifier for the transaction + maxLength: 13 + invoice: + type: + - "null" + - object + description: Details of the invoice associated with the transaction + properties: + type: + type: + - "null" + - string + business_entity_id: + type: + - "null" + - string + id: + type: + - "null" + - string + maxLength: 13 + number: + type: + - "null" + - string + maxLength: 256 + state: + type: + - "null" + - string + ip_address_country: + type: + - "null" + - string + description: Country of the IP address used for the transaction + maxLength: 256 + ip_address_v4: + type: + - "null" + - string + description: IPv4 address of the transaction + maxLength: 256 + object: + type: + - "null" + - string + description: Type of object (transaction) + origin: + type: + - "null" + - string + description: Source or origin of the transaction + maxLength: 256 + original_transaction_id: + type: + - "null" + - string + description: ID of the original transaction, if applicable + maxLength: 13 + payment_gateway: + type: object + description: Details of the payment gateway used for the transaction + properties: + type: + type: + - "null" + - string + id: + type: + - "null" + - string + maxLength: 13 + name: + type: + - "null" + - string + object: + type: + - "null" + - string + payment_method: + type: object + description: Details of the payment method used for the transaction + properties: + account_type: + type: + - "null" + - string + maxLength: 256 + billing_agreement_id: + type: + - "null" + - string + maxLength: 256 + card_type: + type: + - "null" + - string + maxLength: 256 + cc_bin_country: + type: + - "null" + - string + exp_month: + type: + - "null" + - number + exp_year: + type: + - "null" + - number + first_six: + type: + - "null" + - string + maxLength: 6 + gateway_code: + type: + - "null" + - string + maxLength: 256 + gateway_token: + type: + - "null" + - string + maxLength: 256 + last_four: + type: + - "null" + - string + maxLength: 4 + last_two: + type: + - "null" + - string + maxLength: 2 + name_on_account: + type: + - "null" + - string + maxLength: 256 + object: + type: + - "null" + - string + routing_number: + type: + - "null" + - string + maxLength: 256 + routing_number_bank: + type: + - "null" + - string + maxLength: 256 + username: + type: + - "null" + - string + refunded: + type: + - "null" + - boolean + description: Indicates whether the transaction has been refunded + status: + type: + - "null" + - string + description: Current status of the transaction + maxLength: 256 + status_code: + type: + - "null" + - string + description: Status code of the transaction + maxLength: 256 + status_message: + type: + - "null" + - string + description: Message related to the status of the transaction + maxLength: 1024 + subscription_ids: + type: array + description: List of subscription IDs associated with the transaction + items: + type: + - "null" + - string + maxLength: 13 + success: + type: + - "null" + - boolean + description: Indicates the success status of the transaction + updated_at: + type: + - "null" + - string + description: Date and time of the last update to the transaction + format: date-time + uuid: + type: + - "null" + - string + description: Universally unique identifier for the transaction + maxLength: 32 + vat_number: + type: + - "null" + - string + description: VAT number associated with the transaction + voided_at: + type: + - "null" + - string + description: Date and time when the transaction was voided + format: date-time + voided_by_invoice: + type: + - "null" + - object + description: Details of the invoice that voided the transaction + properties: + type: + type: + - "null" + - string + business_entity_id: + type: + - "null" + - string + id: + type: + - "null" + - string + maxLength: 13 + number: + type: + - "null" + - string + maxLength: 256 + object: + type: + - "null" + - string + state: + type: + - "null" + - string + unique_coupons: + type: + - "null" + - object + description: A unique coupon code for a bulk coupon. + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + bulk_coupon_code: + type: + - "null" + - string + description: The Coupon code of the parent Bulk Coupon + maxLength: 256 + title: Bulk Coupon code + bulk_coupon_id: + type: + - "null" + - string + description: The Coupon ID of the parent Bulk Coupon + maxLength: 13 + readOnly: true + title: Bulk Coupon ID + code: + type: string + description: The code the customer enters to redeem the coupon. + maxLength: 256 + title: Coupon code + created_at: + type: string + format: date-time + readOnly: true + title: Created at + expired_at: + type: + - "null" + - string + description: >- + The date and time the coupon was expired early or reached its + `max_redemptions`. + format: date-time + title: Expired at + id: + type: string + maxLength: 13 + readOnly: true + title: Unique Coupon Code ID + object: + type: string + redeemed_at: + type: + - "null" + - string + description: The date and time the unique coupon code was redeemed. + format: date-time + readOnly: true + title: Redeemed at + state: + type: + - "null" + - string + description: Indicates if the unique coupon code is redeemable or why not. + maxLength: 256 + title: State + updated_at: + type: string + format: date-time + readOnly: true + title: Updated at + unique_coupons_parent: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + applies_to_all_items: + type: + - boolean + - "null" + applies_to_all_plans: + type: + - boolean + - "null" + applies_to_non_plan_charges: + type: + - boolean + - "null" + code: + type: + - string + - "null" + coupon_type: + type: + - string + - "null" + created_at: + type: + - string + - "null" + discount: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + currencies: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + amount: + type: + - number + - "null" + currency: + type: + - string + - "null" + duration: + type: + - string + - "null" + hosted_page_description: + type: + - string + - "null" + id: + type: string + invoice_description: + type: + - string + - "null" + max_redemptions_per_account: + type: + - number + - "null" + name: + type: + - string + - "null" + object: + type: + - string + - "null" + redemption_resource: + type: + - string + - "null" + state: + type: + - string + - "null" + unique_code_template: + type: + - string + - "null" + unique_coupon_codes_count: + type: + - number + - "null" + updated_at: + type: string + required: + - id + - updated_at diff --git a/airbyte-integrations/connectors/source-recurly/metadata.yaml b/airbyte-integrations/connectors/source-recurly/metadata.yaml index a09c31c91544..cae32d96dca8 100644 --- a/airbyte-integrations/connectors/source-recurly/metadata.yaml +++ b/airbyte-integrations/connectors/source-recurly/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 200 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: cd42861b-01fc-4658-a8ab-5d11d0510f01 - dockerImageTag: 1.1.12 + dockerImageTag: 1.3.5 dockerRepository: airbyte/source-recurly documentationUrl: https://docs.airbyte.com/integrations/sources/recurly githubIssueLabel: source-recurly @@ -22,17 +22,20 @@ data: releases: breakingChanges: 1.0.0: - message: Version 1.0.0 introduces a number of schema updates to the Recurly connector. To ensure a smooth upgrade, please refresh your schemas and reset your data before resuming syncs. + message: + Version 1.0.0 introduces a number of schema updates to the Recurly + connector. To ensure a smooth upgrade, please refresh your schemas and reset + your data before resuming syncs. upgradeDeadline: "2024-03-05" releaseStage: alpha remoteRegistries: pypi: - enabled: true + enabled: false packageName: airbyte-source-recurly supportLevel: community tags: - - language:python - cdk:low-code + - language:manifest-only connectorTestSuitesOptions: - suite: liveTests testConnections: diff --git a/airbyte-integrations/connectors/source-recurly/poetry.lock b/airbyte-integrations/connectors/source-recurly/poetry.lock deleted file mode 100644 index a5b4b7f8e604..000000000000 --- a/airbyte-integrations/connectors/source-recurly/poetry.lock +++ /dev/null @@ -1,1076 +0,0 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. - -[[package]] -name = "airbyte-cdk" -version = "0.80.0" -description = "A framework for writing Airbyte Connectors." -optional = false -python-versions = "<4.0,>=3.9" -files = [ - {file = "airbyte_cdk-0.80.0-py3-none-any.whl", hash = "sha256:060e92323a73674fa4e9e2e4a1eb312b9b9d072c9bbe5fa28f54ef21cb4974f3"}, - {file = "airbyte_cdk-0.80.0.tar.gz", hash = "sha256:1383512a83917fecca5b24cea4c72aa5c561cf96dd464485fbcefda48fe574c5"}, -] - -[package.dependencies] -airbyte-protocol-models = "0.5.1" -backoff = "*" -cachetools = "*" -Deprecated = ">=1.2,<1.3" -dpath = ">=2.0.1,<2.1.0" -genson = "1.2.2" -isodate = ">=0.6.1,<0.7.0" -Jinja2 = ">=3.1.2,<3.2.0" -jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" -pendulum = "<3.0.0" -pydantic = ">=1.10.8,<2.0.0" -pyrate-limiter = ">=3.1.0,<3.2.0" -python-dateutil = "*" -PyYAML = ">=6.0.1,<7.0.0" -requests = "*" -requests_cache = "*" -wcmatch = "8.4" - -[package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.0.271)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] - -[[package]] -name = "airbyte-protocol-models" -version = "0.5.1" -description = "Declares the Airbyte Protocol." -optional = false -python-versions = ">=3.8" -files = [ - {file = "airbyte_protocol_models-0.5.1-py3-none-any.whl", hash = "sha256:dfe84e130e51ce2ae81a06d5aa36f6c5ce3152b9e36e6f0195fad6c3dab0927e"}, - {file = "airbyte_protocol_models-0.5.1.tar.gz", hash = "sha256:7c8b16c7c1c7956b1996052e40585a3a93b1e44cb509c4e97c1ee4fe507ea086"}, -] - -[package.dependencies] -pydantic = ">=1.9.2,<2.0.0" - -[[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, -] - -[[package]] -name = "attrs" -version = "24.2.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" -files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, -] - -[package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] - -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "bracex" -version = "2.5.post1" -description = "Bash style brace expander." -optional = false -python-versions = ">=3.8" -files = [ - {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, - {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, -] - -[[package]] -name = "cachetools" -version = "5.5.0" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, - {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, -] - -[[package]] -name = "cattrs" -version = "24.1.2" -description = "Composable complex class support for attrs and dataclasses." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, - {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, -] - -[package.dependencies] -attrs = ">=23.1.0" -exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} - -[package.extras] -bson = ["pymongo (>=4.4.0)"] -cbor2 = ["cbor2 (>=5.4.6)"] -msgpack = ["msgpack (>=1.0.5)"] -msgspec = ["msgspec (>=0.18.5)"] -orjson = ["orjson (>=3.9.2)"] -pyyaml = ["pyyaml (>=6.0)"] -tomlkit = ["tomlkit (>=0.11.8)"] -ujson = ["ujson (>=5.7.0)"] - -[[package]] -name = "certifi" -version = "2024.8.30" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.0" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -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 = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - -[[package]] -name = "dpath" -version = "2.0.8" -description = "Filesystem-like pathing and searching for dictionaries" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dpath-2.0.8-py3-none-any.whl", hash = "sha256:f92f595214dd93a00558d75d4b858beee519f4cffca87f02616ad6cd013f3436"}, - {file = "dpath-2.0.8.tar.gz", hash = "sha256:a3440157ebe80d0a3ad794f1b61c571bef125214800ffdb9afc9424e8250fe9b"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "genson" -version = "1.2.2" -description = "GenSON is a powerful, user-friendly JSON Schema generator." -optional = false -python-versions = "*" -files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, -] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isodate" -version = "0.6.1" -description = "An ISO 8601 date/time/duration parser and formatter" -optional = false -python-versions = "*" -files = [ - {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, - {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "jinja2" -version = "3.1.4" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "jsonref" -version = "0.2" -description = "An implementation of JSON Reference for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonref-0.2-py3-none-any.whl", hash = "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f"}, - {file = "jsonref-0.2.tar.gz", hash = "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697"}, -] - -[[package]] -name = "jsonschema" -version = "3.2.0" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, -] - -[package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" - -[package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] - -[[package]] -name = "markupsafe" -version = "3.0.2" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -files = [ - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, - {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, -] - -[[package]] -name = "packaging" -version = "24.1" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, -] - -[[package]] -name = "pendulum" -version = "2.1.2" -description = "Python datetimes made easy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, - {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, - {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, - {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, - {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, - {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, - {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, - {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, - {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, - {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, - {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, -] - -[package.dependencies] -python-dateutil = ">=2.6,<3.0" -pytzdata = ">=2020.1" - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] - -[[package]] -name = "pydantic" -version = "1.10.18" -description = "Data validation and settings management using python type hints" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, -] - -[package.dependencies] -typing-extensions = ">=4.2.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] - -[[package]] -name = "pyrate-limiter" -version = "3.1.1" -description = "Python Rate-Limiter using Leaky-Bucket Algorithm" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, - {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, -] - -[package.extras] -all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] -docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] - -[[package]] -name = "pyrsistent" -version = "0.20.0" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7"}, - {file = "pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee"}, - {file = "pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d"}, - {file = "pyrsistent-0.20.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win32.whl", hash = "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d"}, - {file = "pyrsistent-0.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win32.whl", hash = "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf"}, - {file = "pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b"}, - {file = "pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4"}, -] - -[[package]] -name = "pytest" -version = "6.2.5" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, -] - -[package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] - -[[package]] -name = "pytest-mock" -version = "3.14.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, -] - -[package.dependencies] -pytest = ">=6.2.5" - -[package.extras] -dev = ["pre-commit", "pytest-asyncio", "tox"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytzdata" -version = "2020.1" -description = "The Olson timezone database for Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, - {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "recurly" -version = "4.10.0" -description = "Recurly v4" -optional = false -python-versions = "*" -files = [ - {file = "recurly-4.10.0-py3-none-any.whl", hash = "sha256:b8e3b1ec58f7b1e1b91286f2db864f6ba4053837ad920d0c2868508020442aaf"}, - {file = "recurly-4.10.0.tar.gz", hash = "sha256:a8dddab76bb38f76a715644448f45499227bfd00529ef33f7945b3bcc5a8f3a2"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-cache" -version = "1.2.1" -description = "A persistent cache for python requests" -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, - {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, -] - -[package.dependencies] -attrs = ">=21.2" -cattrs = ">=22.2" -platformdirs = ">=2.5" -requests = ">=2.22" -url-normalize = ">=1.4" -urllib3 = ">=1.25.5" - -[package.extras] -all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] -bson = ["bson (>=0.5)"] -docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] -dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] -json = ["ujson (>=5.4)"] -mongodb = ["pymongo (>=3)"] -redis = ["redis (>=3)"] -security = ["itsdangerous (>=2.0)"] -yaml = ["pyyaml (>=6.0.1)"] - -[[package]] -name = "requests-mock" -version = "1.12.1" -description = "Mock out responses from the requests package" -optional = false -python-versions = ">=3.5" -files = [ - {file = "requests-mock-1.12.1.tar.gz", hash = "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401"}, - {file = "requests_mock-1.12.1-py2.py3-none-any.whl", hash = "sha256:b1e37054004cdd5e56c84454cc7df12b25f90f382159087f4b6915aaeef39563"}, -] - -[package.dependencies] -requests = ">=2.22,<3" - -[package.extras] -fixture = ["fixtures"] - -[[package]] -name = "setuptools" -version = "75.2.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "url-normalize" -version = "1.4.3" -description = "URL normalization for Python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, - {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "urllib3" -version = "2.2.3" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "wcmatch" -version = "8.4" -description = "Wildcard/glob file name matcher." -optional = false -python-versions = ">=3.7" -files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, -] - -[package.dependencies] -bracex = ">=2.1.1" - -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "4843eceb07967beaffe917740b8353dfbd8fcfdfa662940ae76db251b0ff6a4f" diff --git a/airbyte-integrations/connectors/source-recurly/pyproject.toml b/airbyte-integrations/connectors/source-recurly/pyproject.toml deleted file mode 100644 index 835af1388b0e..000000000000 --- a/airbyte-integrations/connectors/source-recurly/pyproject.toml +++ /dev/null @@ -1,29 +0,0 @@ -[build-system] -requires = [ "poetry-core>=1.0.0",] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -version = "1.1.12" -name = "source-recurly" -description = "Source implementation for Recurly." -authors = [ "Airbyte ",] -license = "MIT" -readme = "README.md" -documentation = "https://docs.airbyte.com/integrations/sources/recurly" -homepage = "https://airbyte.com" -repository = "https://github.com/airbytehq/airbyte" -[[tool.poetry.packages]] -include = "source_recurly" - -[tool.poetry.dependencies] -python = "^3.9,<3.12" -airbyte-cdk = "0.80.0" -recurly = "==4.10.0" - -[tool.poetry.scripts] -source-recurly = "source_recurly.run:run" - -[tool.poetry.group.dev.dependencies] -requests-mock = "^1.9.3" -pytest-mock = "^3.6.1" -pytest = "^6.1" diff --git a/airbyte-integrations/connectors/source-recurly/source_recurly/__init__.py b/airbyte-integrations/connectors/source-recurly/source_recurly/__init__.py deleted file mode 100644 index 3f9c7687435e..000000000000 --- a/airbyte-integrations/connectors/source-recurly/source_recurly/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from .source import SourceRecurly - -__all__ = ["SourceRecurly"] diff --git a/airbyte-integrations/connectors/source-recurly/source_recurly/components.py b/airbyte-integrations/connectors/source-recurly/source_recurly/components.py deleted file mode 100644 index 335c318c7944..000000000000 --- a/airbyte-integrations/connectors/source-recurly/source_recurly/components.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. - -from typing import Any, List, Mapping - -import requests -from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor - - -class ExportDatesExtractor(RecordExtractor): - def extract_records(self, response: requests.Response) -> List[Mapping[str, Any]]: - try: - dates = response.json()["dates"] - except requests.exceptions.JSONDecodeError: - dates = [] - return [{"dates": dates}] diff --git a/airbyte-integrations/connectors/source-recurly/source_recurly/manifest.yaml b/airbyte-integrations/connectors/source-recurly/source_recurly/manifest.yaml deleted file mode 100644 index f8afe168a43b..000000000000 --- a/airbyte-integrations/connectors/source-recurly/source_recurly/manifest.yaml +++ /dev/null @@ -1,5568 +0,0 @@ -version: 0.80.0 - -type: DeclarativeSource - -check: - type: CheckStream - stream_names: - - accounts - -definitions: - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%SZ" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['begin_time'] if config['begin_time'] else (now_utc() - duration('P5Y')).strftime('%Y-%m-%dT%H:%M:%SZ') }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - start_time_option: - type: RequestOption - inject_into: request_parameter - field_name: begin_time - end_time_option: - type: RequestOption - inject_into: request_parameter - field_name: end_time - end_datetime: - type: MinMaxDatetime - datetime: "{{ config['end_time'] if config['end_time'] else now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - streams: - accounts: - type: DeclarativeStream - name: accounts - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: accounts - http_method: GET - request_parameters: - order: asc - sort: updated_at - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - $ref: "#/definitions/record_selector" - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - pagination_strategy: - type: CursorPagination - page_size: 200 - cursor_value: "{{ response.next }}" - stop_condition: "{{ response.has_more is false }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/accounts" - incremental_sync: - $ref: "#/definitions/incremental_sync" - account_coupon_redemptions: - type: DeclarativeStream - name: account_coupon_redemptions - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /accounts/{{ stream_partition['account_id'] }}/coupon_redemptions - http_method: GET - request_parameters: - order: asc - sort: updated_at - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - $ref: "#/definitions/record_selector" - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - pagination_strategy: - type: CursorPagination - page_size: 200 - cursor_value: "{{ response.next }}" - stop_condition: "{{ response.has_more is false }}" - partition_router: - - type: SubstreamPartitionRouter - parent_stream_configs: - - type: ParentStreamConfig - parent_key: id - partition_field: account_id - stream: - $ref: "#/definitions/streams/accounts" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/account_coupon_redemptions" - incremental_sync: - $ref: "#/definitions/incremental_sync" - account_notes: - type: DeclarativeStream - name: account_notes - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /accounts/{{ stream_partition['account_id'] }}/notes - http_method: GET - request_parameters: - order: asc - sort: created_at - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - $ref: "#/definitions/record_selector" - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - pagination_strategy: - type: CursorPagination - page_size: 200 - cursor_value: "{{ response.next }}" - stop_condition: "{{ response.has_more is false }}" - partition_router: - - type: SubstreamPartitionRouter - parent_stream_configs: - - type: ParentStreamConfig - parent_key: id - partition_field: account_id - stream: - $ref: "#/definitions/streams/accounts" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/account_notes" - incremental_sync: - $ref: "#/definitions/incremental_sync" - cursor_field: created_at - add_ons: - type: DeclarativeStream - name: add_ons - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /add_ons - http_method: GET - request_parameters: - order: asc - sort: updated_at - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - $ref: "#/definitions/record_selector" - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - pagination_strategy: - type: CursorPagination - page_size: 200 - cursor_value: "{{ response.next }}" - stop_condition: "{{ response.has_more is false }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/add_ons" - incremental_sync: - $ref: "#/definitions/incremental_sync" - billing_infos: - type: DeclarativeStream - name: billing_infos - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /accounts/{{ stream_partition['account_id'] }}/billing_infos - http_method: GET - request_parameters: - order: asc - sort: updated_at - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - $ref: "#/definitions/record_selector" - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - pagination_strategy: - type: CursorPagination - page_size: 200 - cursor_value: "{{ response.next }}" - stop_condition: "{{ response.has_more is false }}" - partition_router: - - type: SubstreamPartitionRouter - parent_stream_configs: - - type: ParentStreamConfig - parent_key: id - partition_field: account_id - stream: - $ref: "#/definitions/streams/accounts" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/billing_infos" - incremental_sync: - $ref: "#/definitions/incremental_sync" - coupons: - type: DeclarativeStream - name: coupons - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: coupons - http_method: GET - request_parameters: - order: asc - sort: updated_at - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - $ref: "#/definitions/record_selector" - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - pagination_strategy: - type: CursorPagination - page_size: 200 - cursor_value: "{{ response.next }}" - stop_condition: "{{ response.has_more is false }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/coupons" - incremental_sync: - $ref: "#/definitions/incremental_sync" - credit_payments: - type: DeclarativeStream - name: credit_payments - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: credit_payments - http_method: GET - request_parameters: - order: asc - sort: updated_at - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - $ref: "#/definitions/record_selector" - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - pagination_strategy: - type: CursorPagination - page_size: 200 - cursor_value: "{{ response.next }}" - stop_condition: "{{ response.has_more is false }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/credit_payments" - incremental_sync: - $ref: "#/definitions/incremental_sync" - export_dates: - type: DeclarativeStream - name: export_dates - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: export_dates - http_method: GET - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - type: RecordSelector - extractor: - type: CustomRecordExtractor - class_name: source_recurly.components.ExportDatesExtractor - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/export_dates" - invoices: - type: DeclarativeStream - name: invoices - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: invoices - http_method: GET - request_parameters: - order: asc - sort: updated_at - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - $ref: "#/definitions/record_selector" - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - pagination_strategy: - type: CursorPagination - page_size: 200 - cursor_value: "{{ response.next }}" - stop_condition: "{{ response.has_more is false }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/invoices" - incremental_sync: - $ref: "#/definitions/incremental_sync" - line_items: - type: DeclarativeStream - name: line_items - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: line_items - http_method: GET - request_parameters: - order: asc - sort: updated_at - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - $ref: "#/definitions/record_selector" - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - pagination_strategy: - type: CursorPagination - page_size: 200 - cursor_value: "{{ response.next }}" - stop_condition: "{{ response.has_more is false }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/line_items" - incremental_sync: - $ref: "#/definitions/incremental_sync" - measured_units: - type: DeclarativeStream - name: measured_units - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: measured_units - http_method: GET - request_parameters: - order: asc - sort: updated_at - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - $ref: "#/definitions/record_selector" - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - pagination_strategy: - type: CursorPagination - page_size: 200 - cursor_value: "{{ response.next }}" - stop_condition: "{{ response.has_more is false }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/measured_units" - incremental_sync: - $ref: "#/definitions/incremental_sync" - plans: - type: DeclarativeStream - name: plans - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: plans - http_method: GET - request_parameters: - order: asc - sort: updated_at - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - $ref: "#/definitions/record_selector" - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - pagination_strategy: - type: CursorPagination - page_size: 200 - cursor_value: "{{ response.next }}" - stop_condition: "{{ response.has_more is false }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/plans" - incremental_sync: - $ref: "#/definitions/incremental_sync" - shipping_addresses: - type: DeclarativeStream - name: shipping_addresses - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /accounts/{{ stream_partition['account_id'] }}/shipping_addresses - http_method: GET - request_parameters: - order: asc - sort: updated_at - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - $ref: "#/definitions/record_selector" - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - pagination_strategy: - type: CursorPagination - page_size: 200 - cursor_value: "{{ response.next }}" - stop_condition: "{{ response.has_more is false }}" - partition_router: - - type: SubstreamPartitionRouter - parent_stream_configs: - - type: ParentStreamConfig - parent_key: id - partition_field: account_id - stream: - $ref: "#/definitions/streams/accounts" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/shipping_addresses" - incremental_sync: - $ref: "#/definitions/incremental_sync" - shipping_methods: - type: DeclarativeStream - name: shipping_methods - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: shipping_methods - http_method: GET - request_parameters: - order: asc - sort: updated_at - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - $ref: "#/definitions/record_selector" - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - pagination_strategy: - type: CursorPagination - page_size: 200 - cursor_value: "{{ response.next }}" - stop_condition: "{{ response.has_more is false }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/shipping_methods" - incremental_sync: - $ref: "#/definitions/incremental_sync" - subscriptions: - type: DeclarativeStream - name: subscriptions - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: subscriptions - http_method: GET - request_parameters: - order: asc - sort: updated_at - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - $ref: "#/definitions/record_selector" - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - pagination_strategy: - type: CursorPagination - page_size: 200 - cursor_value: "{{ response.next }}" - stop_condition: "{{ response.has_more is false }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/subscriptions" - incremental_sync: - $ref: "#/definitions/incremental_sync" - transactions: - type: DeclarativeStream - name: transactions - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: transactions - http_method: GET - request_parameters: - order: asc - sort: updated_at - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - $ref: "#/definitions/record_selector" - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - pagination_strategy: - type: CursorPagination - page_size: 200 - cursor_value: "{{ response.next }}" - stop_condition: "{{ response.has_more is false }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/transactions" - incremental_sync: - $ref: "#/definitions/incremental_sync" - unique_coupons: - type: DeclarativeStream - name: unique_coupons - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /coupons/{{ stream_partition['coupon_id'] }}/unique_coupon_codes - http_method: GET - request_parameters: - order: asc - sort: updated_at - request_headers: - User-Agent: USER_AGENT - Accept: application/vnd.recurly.v2021-02-25 - Content-Type: application/json - record_selector: - $ref: "#/definitions/record_selector" - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - inject_into: request_parameter - field_name: limit - pagination_strategy: - type: CursorPagination - page_size: 200 - cursor_value: "{{ response.next }}" - stop_condition: "{{ response.has_more is false }}" - partition_router: - - type: SubstreamPartitionRouter - parent_stream_configs: - - type: ParentStreamConfig - parent_key: id - partition_field: coupon_id - stream: - $ref: "#/definitions/streams/coupons" - retriever: - $ref: "#/definitions/streams/coupons/retriever" - record_selector: - $ref: "#/definitions/record_selector" - record_filter: - condition: "{{ record['coupon_type'] == 'bulk' }}" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/unique_coupons" - incremental_sync: - $ref: "#/definitions/incremental_sync" - base_requester: - type: HttpRequester - url_base: https://v3.recurly.com - authenticator: - type: BasicHttpAuthenticator - username: "{{ config['api_key'] }}" - password: "" - -streams: - - $ref: "#/definitions/streams/accounts" - - $ref: "#/definitions/streams/account_coupon_redemptions" - - $ref: "#/definitions/streams/account_notes" - - $ref: "#/definitions/streams/add_ons" - - $ref: "#/definitions/streams/billing_infos" - - $ref: "#/definitions/streams/coupons" - - $ref: "#/definitions/streams/credit_payments" - - $ref: "#/definitions/streams/export_dates" - - $ref: "#/definitions/streams/invoices" - - $ref: "#/definitions/streams/line_items" - - $ref: "#/definitions/streams/measured_units" - - $ref: "#/definitions/streams/plans" - - $ref: "#/definitions/streams/shipping_addresses" - - $ref: "#/definitions/streams/shipping_methods" - - $ref: "#/definitions/streams/subscriptions" - - $ref: "#/definitions/streams/transactions" - - $ref: "#/definitions/streams/unique_coupons" - -spec: - type: Spec - connection_specification: - type: object - $schema: http://json-schema.org/draft-07/schema# - additionalProperties: true - required: - - api_key - properties: - api_key: - type: string - title: API Key - airbyte_secret: true - description: >- - Recurly API Key. See the docs - for more information on how to generate this key. - order: 0 - begin_time: - type: string - description: >- - ISO8601 timestamp from which the replication from Recurly API will - start from. - examples: - - "2021-12-01T00:00:00" - pattern: ^$|^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$ - order: 1 - end_time: - type: string - description: >- - ISO8601 timestamp to which the replication from Recurly API will stop. - Records after that date won't be imported. - examples: - - "2021-12-01T00:00:00" - pattern: ^$|^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$ - order: 2 - -schemas: - accounts: - $schema: "http://json-schema.org/draft-07/schema#" - additionalProperties: true - type: object - properties: - id: - description: Unique identifier of the account - type: - - "null" - - string - maxLength: 13 - object: - description: Type of object - type: - - "null" - - string - hosted_login_token: - description: Token for hosted login functionality - type: - - "null" - - string - code: - description: Unique code assigned to the account - type: - - "null" - - string - maxLength: 256 - parent_account_id: - description: ID of the parent account - type: - - "null" - - string - maxLength: 13 - bill_to: - description: The billing details - type: - - "null" - - string - maxLength: 6 - state: - description: State/province of the account address - type: - - "null" - - string - maxLength: 256 - username: - description: Username of the account holder - type: - - "null" - - string - maxLength: 256 - email: - description: Email address of the account holder - type: - - "null" - - string - maxLength: 256 - cc_emails: - description: Email addresses for carbon copy (CC) - type: - - "null" - - string - maxLength: 256 - preferred_locale: - description: Preferred language/locale of the account holder - type: - - "null" - - string - maxLength: 12 - first_name: - description: First name of the account holder - type: - - "null" - - string - maxLength: 256 - last_name: - description: Last name of the account holder - type: - - "null" - - string - maxLength: 256 - company: - description: Company associated with the account - type: - - "null" - - string - maxLength: 50 - vat_number: - description: VAT (Value Added Tax) number of the account - type: - - "null" - - string - maxLength: 20 - tax_exempt: - description: Flag indicating if the account is tax exempt - type: - - "null" - - boolean - exemption_certificate: - description: Exemption certificate details - type: - - "null" - - string - maxLength: 30 - address: - description: The address details of the account - type: object - properties: - phone: - description: Phone number associated with the address - type: string - title: Phone number - maxLength: 256 - street1: - description: First line of the street address - type: string - title: Street 1 - maxLength: 256 - street2: - description: Second line of the street address - type: string - title: Street 2 - maxLength: 256 - city: - description: City of the address - type: string - title: City - maxLength: 256 - region: - type: string - title: State/Province - description: State or province. - maxLength: 256 - postal_code: - type: string - title: Zip/Postal code - description: Zip or postal code. - maxLength: 256 - country: - type: string - title: Country - description: "Country, 2-letter ISO 3166-1 alpha-2 code." - maxLength: 2 - geo_code: - description: Geographical coordinates of the address - type: - - "null" - - string - custom_fields: - description: Custom fields associated with the account - type: - - "null" - - array - items: - type: - - "null" - - object - additionalProperties: true - has_live_subscription: - description: Flag indicating if the account has a live subscription - type: - - "null" - - boolean - has_active_subscription: - description: Flag indicating if the account has an active subscription - type: - - "null" - - boolean - has_future_subscription: - description: Flag indicating if the account has a future subscription - type: - - "null" - - boolean - has_canceled_subscription: - description: Flag indicating if the account has a canceled subscription - type: - - "null" - - boolean - has_paused_subscription: - description: Flag indicating if the account has a paused subscription - type: - - "null" - - boolean - has_past_due_invoice: - description: Flag indicating if the account has a past due invoice - type: - - "null" - - boolean - dunning_campaign_id: - description: Campaign ID for dunning management - type: - - "null" - - string - maxLength: 256 - created_at: - description: Date and time when the account was created - type: - - "null" - - string - format: date-time - updated_at: - description: Date and time when the account was last updated - type: - - "null" - - string - format: date-time - deleted_at: - description: Date and time when the account was deleted - type: - - "null" - - string - format: date-time - billing_info: - description: Billing information - $ref: "#/schemas/billing_infos_common" - external_accounts: - description: External accounts associated with the account - type: - - "null" - - array - items: - $ref: "#/schemas/external_accounts_common" - invoice_template_id: - description: ID of the invoice template used - type: - - "null" - - string - override_business_entity_id: - description: ID for overriding business entity - type: - - "null" - - string - preferred_time_zone: - description: Preferred time zone of the account holder - type: - - "null" - - string - shipping_addresses: - description: Addresses for shipping - type: - - "null" - - array - items: - $ref: "#/schemas/shipping_addresses_common" - - account_coupon_redemptions: - $schema: "http://json-schema.org/draft-07/schema#" - additionalProperties: true - type: object - properties: - id: - description: The unique identifier for the redemption - type: - - "null" - - string - maxLength: 13 - object: - description: The type of object this represents - type: - - "null" - - string - account: - description: The account associated with the coupon redemption - $ref: "#/schemas/account_details_common" - subscription_id: - description: The subscription associated with the redemption - type: - - "null" - - string - maxLength: 13 - coupon: - description: The coupon being redeemed - $ref: "#/schemas/coupons_common" - state: - description: The current state of the redemption - type: - - "null" - - string - maxLength: 256 - currency: - description: The currency in which the redemption was made - type: - - "null" - - string - maxLength: 3 - discounted: - description: The amount discounted by the coupon - type: - - "null" - - number - created_at: - description: The date and time when the redemption was created - type: - - "null" - - string - format: date-time - updated_at: - description: The date and time when the redemption was last updated - type: - - "null" - - string - format: date-time - removed_at: - description: The date and time when the redemption was removed (if applicable) - type: - - "null" - - string - format: date-time - - account_notes: - $schema: "http://json-schema.org/draft-07/schema#" - additionalProperties: true - type: object - properties: - id: - description: The unique identifier for this note. - type: string - maxLength: 13 - readOnly: true - object: - description: "Represents the object type, in this case, 'note'." - type: - - "null" - - string - account_id: - description: The unique identifier of the account associated with this note. - type: string - maxLength: 13 - user: - description: The user who created the note. - $ref: "#/schemas/users_common" - message: - description: The content or message of the note. - type: - - "null" - - string - maxLength: 2048 - created_at: - description: The date and time when the note was created. - type: string - format: date-time - readOnly: true - - add_ons: - $schema: "http://json-schema.org/schema#" - additionalProperties: true - type: object - properties: - id: - description: The unique identifier for the add-on. - type: string - title: Add-on ID - maxLength: 13 - readOnly: true - plan_id: - description: The ID of the plan to which the add-on is associated. - type: string - title: Plan ID - maxLength: 13 - readOnly: true - code: - type: string - title: Add-on code - description: The unique identifier for the add-on within its plan. - maxLength: 50 - state: - title: State - description: Add-ons can be either active or inactive. - readOnly: true - type: string - maxLength: 256 - name: - type: string - title: Name - description: Describes your add-on and will appear in subscribers' invoices. - maxLength: 255 - add_on_type: - type: - - "null" - - string - title: Add-on Type - description: "Whether the add-on type is fixed, or usage-based." - maxLength: 256 - usage_type: - type: string - title: Usage Type - description: "Type of usage, returns usage type if `add_on_type` is `usage`." - maxLength: 256 - usage_percentage: - type: - - "null" - - number - format: float - title: Usage Percentage - description: >- - The percentage taken of the monetary amount of usage tracked. This can be - up to 4 decimal places. A value between 0.0 and 100.0. - measured_unit_id: - type: - - "null" - - string - title: Measured Unit ID - description: >- - System-generated unique identifier for an measured unit associated with - the add-on. - maxLength: 13 - accounting_code: - type: - - "null" - - string - title: Accounting code - description: >- - Accounting code for invoice line items for this add-on. If no value is - provided, it defaults to add-on's code. - maxLength: 256 - revenue_schedule_type: - title: Revenue schedule type - description: >- - When this add-on is invoiced, the line item will use this revenue - schedule. If `item_code`/`item_id` is part of the request then - `revenue_schedule_type` must be absent in the request as the value will be - set from the item. - type: string - maxLength: 256 - avalara_transaction_type: - type: - - string - - integer - title: Avalara Transaction Type - description: >- - Used by Avalara for Communications taxes. The transaction type in - combination with the service type describe how the add-on is taxed. Refer - to [the - documentation](https://help.avalara.com/AvaTax_for_Communications/Tax_Calculation/AvaTax_for_Communications_Tax_Engine/Mapping_Resources/TM_00115_AFC_Modules_Corresponding_Transaction_Types) - for more available t/s types. - minimum: 0 - avalara_service_type: - type: - - string - - integer - title: Avalara Service Type - description: >- - Used by Avalara for Communications taxes. The transaction type in - combination with the service type describe how the add-on is taxed. Refer - to [the - documentation](https://help.avalara.com/AvaTax_for_Communications/Tax_Calculation/AvaTax_for_Communications_Tax_Engine/Mapping_Resources/TM_00115_AFC_Modules_Corresponding_Transaction_Types) - for more available t/s types. - minimum: 0 - tax_code: - type: - - "null" - - string - title: Tax code - description: >- - Used by Avalara, Vertex, and Recurly’s EU VAT tax feature. The tax code - values are specific to each tax system. If you are using Recurly’s EU VAT - feature you can use `unknown`, `physical`, or `digital`. - maxLength: 50 - display_quantity: - type: - - "null" - - boolean - title: Display quantity? - description: >- - Determines if the quantity field is displayed on the hosted pages for the - add-on. - default_quantity: - type: - - "null" - - integer - title: Default quantity - description: Default quantity for the hosted pages. - optional: - type: - - "null" - - boolean - title: Optional - description: >- - Whether the add-on is optional for the customer to include in their - purchase on the hosted payment page. If false, the add-on will be included - when a subscription is created through the Recurly UI. However, the add-on - will not be included when a subscription is created through the API. - currencies: - type: array - description: This is only present when `type=fixed`. - items: - type: - - "null" - - object - properties: - currency: - type: string - title: Currency - description: 3-letter ISO 4217 currency code. - maxLength: 3 - unit_amount: - type: number - format: float - title: Discount Amount - description: Value of the fixed discount that this coupon applies. - tier_type: - type: - - "null" - - string - title: Tier type - description: > - The pricing model for the add-on. For more information, - - [click - here](https://docs.recurly.com/docs/billing-models#section-quantity-based). - See our - - [Guide](https://developers.recurly.com/guides/item-addon-guide.html) for - an overview of how - - to configure quantity-based pricing models. - maxLength: 256 - created_at: - description: The date and time when the add-on was created. - type: string - format: date-time - title: Created at - readOnly: true - updated_at: - description: The date and time when the add-on was last updated. - type: string - format: date-time - title: Last updated at - readOnly: true - deleted_at: - description: "The date and time when the add-on was deleted, if applicable." - type: string - format: date-time - title: Deleted at - readOnly: true - - billing_infos: - $schema: "http://json-schema.org/draft-07/schema#" - additionalProperties: true - type: object - properties: - id: - type: string - maxLength: 13 - readOnly: true - object: - type: - - "null" - - string - account_id: - type: string - maxLength: 13 - readOnly: true - first_name: - type: - - "null" - - string - maxLength: 50 - last_name: - type: - - "null" - - string - maxLength: 50 - company: - type: - - "null" - - string - maxLength: 100 - address: - type: object - properties: - phone: - type: - - "null" - - string - title: Phone number - maxLength: 256 - street1: - type: - - "null" - - string - title: Street 1 - maxLength: 256 - street2: - type: - - "null" - - string - title: Street 2 - maxLength: 256 - city: - type: - - "null" - - string - title: City - maxLength: 256 - region: - type: - - "null" - - string - title: State/Province - description: State or province. - maxLength: 256 - postal_code: - type: - - "null" - - string - title: Zip/Postal code - description: Zip or postal code. - maxLength: 256 - country: - type: - - "null" - - string - title: Country - description: "Country, 2-letter ISO 3166-1 alpha-2 code." - maxLength: 2 - vat_number: - type: - - "null" - - string - description: >- - Customer's VAT number (to avoid having the VAT applied). This is only used - for automatically collected invoices. - maxLength: 20 - valid: - type: boolean - readOnly: true - payment_method: - type: object - properties: - card_type: - description: "Visa, MasterCard, American Express, Discover, JCB, etc." - type: - - "null" - - string - maxLength: 256 - object: - type: - - "null" - - string - first_six: - type: - - "null" - - string - description: Credit card number's first six digits. - maxLength: 6 - last_four: - type: - - "null" - - string - description: >- - Credit card number's last four digits. Will refer to bank account if - payment method is ACH. - maxLength: 4 - last_two: - type: - - "null" - - string - description: The IBAN bank account's last two digits. - maxLength: 2 - exp_month: - type: - - "null" - - integer - description: Expiration month. - maxLength: 2 - exp_year: - type: - - "null" - - integer - description: Expiration year. - maxLength: 4 - gateway_token: - type: - - "null" - - string - description: >- - A token used in place of a credit card in order to perform - transactions. - maxLength: 50 - cc_bin_country: - type: - - "null" - - string - description: >- - The 2-letter ISO 3166-1 alpha-2 country code associated with the - credit card BIN, if known by Recurly. Available on the BillingInfo - object only. Available when the BIN country lookup feature is enabled. - maxLength: 256 - gateway_code: - type: - - "null" - - string - description: An identifier for a specific payment gateway. - maxLength: 13 - billing_agreement_id: - type: - - "null" - - string - description: >- - Billing Agreement identifier. Only present for Amazon or Paypal - payment methods. - maxLength: 256 - name_on_account: - type: - - "null" - - string - description: The name associated with the bank account. - maxLength: 256 - account_type: - description: The bank account type. Only present for ACH payment methods. - type: - - "null" - - string - maxLength: 256 - routing_number: - type: - - "null" - - string - description: >- - The bank account's routing number. Only present for ACH payment - methods. - maxLength: 256 - routing_number_bank: - type: - - "null" - - string - description: The bank name of this routing number. - maxLength: 256 - fraud: - type: - - "null" - - object - title: Fraud information - description: Most recent fraud result. - readOnly: true - properties: - score: - type: - - "null" - - integer - title: Kount score - decision: - title: Kount decision - maxLength: 10 - type: - - "null" - - string - risk_rules_triggered: - type: object - title: Kount rules - primary_payment_method: - type: boolean - description: >- - The `primary_payment_method` field is used to indicate the primary billing - info on the account. The first billing info created on an account will - always become primary. This payment method will be used - backup_payment_method: - type: boolean - description: >- - The `backup_payment_method` field is used to indicate a billing info as a - backup on the account that will be tried if the initial billing info used - for an invoice is declined. - created_at: - type: string - format: date-time - description: When the billing information was created. - readOnly: true - updated_at: - type: string - format: date-time - description: When the billing information was last changed. - readOnly: true - updated_by: - type: - - "null" - - object - properties: - ip: - type: - - "null" - - string - country: - type: - - "null" - - string - - coupons: - $schema: "http://json-schema.org/draft-07/schema#" - additionalProperties: true - type: object - properties: - id: - type: - - "null" - - string - maxLength: 13 - object: - type: - - "null" - - string - code: - type: - - "null" - - string - maxLength: 256 - name: - type: - - "null" - - string - maxLength: 256 - state: - type: - - "null" - - string - maxLength: 256 - max_redemptions: - type: - - "null" - - number - max_redemptions_per_account: - type: - - "null" - - number - unique_coupon_codes_count: - type: - - "null" - - number - unique_code_template: - type: - - "null" - - string - maxLength: 256 - unique_coupon_code: - $ref: "#/schemas/unique_coupons_common" - duration: - type: - - "null" - - string - maxLength: 256 - temporal_amount: - type: - - "null" - - number - temporal_unit: - type: - - "null" - - string - maxLength: 256 - free_trial_unit: - type: - - "null" - - string - maxLength: 256 - free_trial_amount: - type: - - "null" - - number - applies_to_all_plans: - type: - - "null" - - boolean - applies_to_all_items: - type: - - "null" - - boolean - applies_to_non_plan_charges: - type: - - "null" - - boolean - plans: - type: - - "null" - - array - title: Plans - description: >- - A list of plans for which this coupon applies. This will be `null` if - `applies_to_all_plans=true`. - items: - type: object - title: Plan mini details - description: Just the important parts. - properties: - id: - type: string - title: Plan ID - maxLength: 13 - readOnly: true - code: - type: string - title: Plan code - description: >- - Unique code to identify the plan. This is used in Hosted Payment - Page URLs and in the invoice exports. - maxLength: 13 - items: - type: - - "null" - - array - title: Items - description: | - A list of items for which this coupon applies. This will be - `null` if `applies_to_all_items=true`. - items: - type: - - "null" - - object - title: Item mini details - description: Just the important parts. - properties: - id: - type: string - title: Item ID - maxLength: 13 - readOnly: true - redemption_resource: - type: - - "null" - - string - maxLength: 256 - discount: - type: - - "null" - - object - description: | - Details of the discount a coupon applies. Will contain a `type` - property and one of the following properties: `percent`, `fixed`, `trial`. - properties: - type: - type: string - maxLength: 256 - percent: - description: This is only present when `type=percent`. - type: integer - currencies: - type: array - description: This is only present when `type=fixed`. - items: - type: - - "null" - - object - properties: - currency: - type: string - title: Currency - description: 3-letter ISO 4217 currency code. - maxLength: 3 - amount: - type: number - format: float - title: Discount Amount - description: Value of the fixed discount that this coupon applies. - trial: - type: object - description: This is only present when `type=free_trial`. - properties: - unit: - title: Trial unit - description: Temporal unit of the free trial - type: string - maxLength: 256 - length: - type: integer - title: Trial length - description: >- - Trial length measured in the units specified by the sibling `unit` - property - coupon_type: - type: - - "null" - - string - maxLength: 256 - hosted_page_description: - type: - - "null" - - string - maxLength: 1024 - invoice_description: - type: - - "null" - - string - maxLength: 1024 - redeem_by: - type: - - "null" - - string - maxLength: 256 - created_at: - type: - - "null" - - string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - expired_at: - type: - - "null" - - string - format: date-time - - credit_payments: - $schema: "http://json-schema.org/schema#" - additionalProperties: true - type: object - properties: - id: - description: The unique identifier of the credit payment. - type: string - title: Credit Payment ID - maxLength: 13 - uuid: - type: string - title: Recurly UUID - description: >- - The UUID is useful for matching data with the CSV exports and building - URLs into Recurly's UI. - maxLength: 32 - action: - title: Action - description: The action for which the credit was created. - type: string - maxLength: 256 - account: - description: Details about the account associated with the credit payment. - type: object - title: Account mini details - properties: - id: - description: The ID of the account associated with the credit payment. - type: string - maxLength: 13 - readOnly: true - code: - type: string - description: The unique identifier of the account. - maxLength: 50 - applied_to_invoice: - description: Details about the invoice to which the credit payment is applied. - type: - - "null" - - object - title: Invoice mini details - properties: - id: - description: The ID of the invoice to which the credit payment is applied. - type: string - title: Invoice ID - maxLength: 13 - number: - description: The number of the invoice to which the credit payment is applied. - type: string - title: Invoice number - maxLength: 256 - original_invoice: - description: Details about the original invoice for which the credit payment is made. - type: - - "null" - - object - title: Invoice mini details - properties: - id: - description: The ID of the original invoice for which the credit payment was made. - type: string - title: Invoice ID - maxLength: 13 - number: - description: >- - The number of the original invoice for which the credit payment was - made. - type: string - title: Invoice number - maxLength: 256 - currency: - type: string - title: Currency - description: 3-letter ISO 4217 currency code. - maxLength: 3 - amount: - type: number - format: float - title: Amount - description: Total credit payment amount applied to the charge invoice. - original_credit_payment_id: - type: - - "null" - - string - title: Original Credit Payment ID - description: >- - For credit payments with action `refund`, this is the credit payment that - was refunded. - maxLength: 13 - refund_transaction: - description: Details about the refund transaction associated with the credit payment. - type: - - "null" - - object - properties: - id: - description: The ID of the refund transaction associated with the credit payment. - type: string - title: Transaction ID - maxLength: 13 - uuid: - type: string - title: Recurly UUID - description: >- - The UUID is useful for matching data with the CSV exports and building - URLs into Recurly's UI. - maxLength: 32 - created_at: - description: The date and time when the credit payment was created. - type: string - title: Created at - format: date-time - readOnly: true - updated_at: - description: The date and time when the credit payment was last updated. - type: string - title: Last updated at - format: date-time - readOnly: true - voided_at: - description: The date and time when the credit payment was voided. - type: - - "null" - - string - title: Voided at - format: date-time - readOnly: true - - export_dates: - $schema: "http://json-schema.org/draft-07/schema#" - additionalProperties: true - type: object - properties: - dates: - description: List of export dates - type: - - "null" - - array - items: - description: Date of the export - type: - - "null" - - string - maxLength: 256 - - invoices: - $schema: "http://json-schema.org/draft-07/schema#" - additionalProperties: true - type: object - properties: - id: - description: The unique ID of the invoice. - type: - - "null" - - string - title: Invoice ID - readOnly: true - maxLength: 13 - uuid: - description: The universally unique identifier (UUID) of the invoice. - type: - - "null" - - string - object: - description: "The type of object, in this case, an invoice." - type: - - "null" - - string - type: - title: Invoice type - description: "Invoices are either charge, credit, or legacy invoices." - type: - - "null" - - string - maxLength: 256 - origin: - type: - - "null" - - string - title: Origin - description: The event that created the invoice. - maxLength: 256 - state: - description: The current state of the invoice. - title: Invoice state - type: - - "null" - - string - maxLength: 256 - account: - description: The account associated with the invoice. - $ref: "#/schemas/account_details_common" - billing_info_id: - type: - - "null" - - string - title: Billing info ID - description: >- - The `billing_info_id` is the value that represents a specific billing info - for an end customer. When `billing_info_id` is used to assign billing info - to the subscription, all future billing events for the subscription will - bill to the specified billing info. `billing_info_id` can ONLY be used for - sites utilizing the Wallet feature. - maxLength: 256 - subscription_ids: - type: - - "null" - - array - title: Subscription IDs - description: >- - If the invoice is charging or refunding for one or more subscriptions, - these are their IDs. - items: - type: - - "null" - - string - title: Subscription ID - maxLength: 13 - previous_invoice_id: - type: - - "null" - - string - title: Previous invoice ID - description: >- - On refund invoices, this value will exist and show the invoice ID of the - purchase invoice the refund was created from. - maxLength: 13 - number: - type: - - "null" - - string - title: Invoice number - description: >- - If VAT taxation and the Country Invoice Sequencing feature are enabled, - invoices will have country-specific invoice numbers for invoices billed to - EU countries (ex: FR1001). Non-EU invoices will continue to use the - site-level invoice number sequence. - maxLength: 256 - collection_method: - type: - - "null" - - string - title: Collection method - description: >- - An automatic invoice means a corresponding transaction is run using the - account's billing information at the same time the invoice is created. - Manual invoices are created without a corresponding transaction. The - merchant must enter a manual payment transaction or have the customer pay - the invoice with an automatic method, like credit card, PayPal, Amazon, or - ACH bank payment. - maxLength: 256 - po_number: - type: - - "null" - - string - title: Purchase order number - description: >- - For manual invoicing, this identifies the PO number associated with the - subscription. - maxLength: 50 - net_terms: - type: - - "null" - - integer - title: Net terms - description: >- - Integer representing the number of days after an invoice's creation that - the invoice will become past due. If an invoice's net terms are set to - '0', it is due 'On Receipt' and will become past due 24 hours after it’s - created. If an invoice is due net 30, it will become past due at 31 days - exactly. - minimum: 0 - default: 0 - address: - description: The address details related to the invoice recipient. - type: - - "null" - - object - properties: - name_on_account: - description: The name on the account. - type: - - "null" - - string - title: Name on account - maxLength: 256 - company: - description: The company name in the address. - type: - - "null" - - string - title: Company - maxLength: 256 - phone: - description: The phone number associated with the address. - type: - - "null" - - string - title: Phone number - maxLength: 256 - street1: - description: The first line of the street address. - type: - - "null" - - string - title: Street 1 - maxLength: 256 - street2: - description: The second line of the street address. - type: - - "null" - - string - title: Street 2 - maxLength: 256 - city: - description: The city in the address. - type: - - "null" - - string - title: City - maxLength: 256 - region: - type: - - "null" - - string - title: State/Province - description: State or province. - maxLength: 256 - postal_code: - type: - - "null" - - string - title: Zip/Postal code - description: Zip or postal code. - maxLength: 256 - country: - type: - - "null" - - string - title: Country - description: "Country, 2-letter ISO 3166-1 alpha-2 code." - maxLength: 2 - first_name: - description: The first name of the recipient. - type: - - "null" - - string - maxLength: 256 - last_name: - description: The last name of the recipient. - type: - - "null" - - string - maxLength: 256 - shipping_address: - description: The shipping address details for the invoice delivery. - type: - - "null" - - object - properties: - id: - description: The ID of the shipping address. - type: - - "null" - - string - title: Shipping Address ID - maxLength: 13 - readOnly: true - currency: - type: - - "null" - - string - title: Currency - description: 3-letter ISO 4217 currency code. - maxLength: 3 - discount: - type: - - "null" - - number - format: float - title: Discount - description: Total discounts applied to this invoice. - subtotal: - type: - - "null" - - number - format: float - title: Subtotal - description: "The summation of charges and credits, before discounts and taxes." - tax: - type: - - "null" - - number - format: float - title: Tax - description: The total tax on this invoice. - total: - type: - - "null" - - number - format: float - title: Total - description: >- - The final total on this invoice. The summation of invoice charges, - discounts, credits, and tax. - refundable_amount: - type: - - "null" - - number - format: float - title: Refundable amount - description: >- - The refundable amount on a charge invoice. It will be null for all other - invoices. - paid: - type: - - "null" - - number - format: float - title: Paid - description: The total amount of successful payments transaction on this invoice. - balance: - type: - - "null" - - number - format: float - title: Balance - description: The outstanding balance remaining on this invoice. - tax_info: - description: Tax information related to the invoice. - type: - - "null" - - object - title: Tax info - properties: - type: - type: - - "null" - - string - title: Type - description: >- - Provides the tax type as "vat" for EU VAT, "usst" for U.S. Sales Tax, - or the 2 letter country code for country level tax types like Canada, - Australia, New Zealand, Israel, and all non-EU European countries. - maxLength: 256 - region: - type: - - "null" - - string - title: Region - description: >- - Provides the tax region applied on an invoice. For U.S. Sales Tax, - this will be the 2 letter state code. For EU VAT this will be the 2 - letter country code. For all country level tax types, this will - display the regional tax, like VAT, GST, or PST. - rate: - description: The tax rate applied to the invoice. - type: - - "null" - - number - format: float - title: Rate - tax_details: - type: array - description: >- - Provides additional tax details for Canadian Sales Tax when there is - tax applied at both the country and province levels. This will only be - populated for the Invoice response when fetching a single invoice and - not for the InvoiceList or LineItem. - items: - type: object - title: Tax detail - properties: - type: - type: - - "null" - - string - title: Type - description: >- - Provides the tax type for the region. For Canadian Sales Tax, - this will be GST, HST, QST or PST. - maxLength: 256 - region: - type: - - "null" - - string - title: Region - description: >- - Provides the tax region applied on an invoice. For Canadian - Sales Tax, this will be either the 2 letter province code or - country code. - maxLength: 256 - rate: - type: - - "null" - - number - format: float - title: Rate - description: Provides the tax rate for the region. - tax: - type: - - "null" - - number - format: float - title: Tax - description: The total tax applied for this tax type. - used_tax_service: - description: Indicates if a tax service was used for the invoice. - type: - - "null" - - boolean - vat_number: - type: - - "null" - - string - title: VAT number - description: >- - VAT registration number for the customer on this invoice. This will come - from the VAT Number field in the Billing Info or the Account Info - depending on your tax settings and the invoice collection method. - maxLength: 20 - vat_reverse_charge_notes: - type: - - "null" - - string - title: VAT reverse charge notes - description: >- - VAT Reverse Charge Notes only appear if you have EU VAT enabled or are - using your own Avalara AvaTax account and the customer is in the EU, has a - VAT number, and is in a different country than your own. This will default - to the VAT Reverse Charge Notes text specified on the Tax Settings page in - your Recurly admin, unless custom notes were created with the original - subscription. - maxLength: 1024 - terms_and_conditions: - type: - - "null" - - string - title: Terms and conditions - description: >- - This will default to the Terms and Conditions text specified on the - Invoice Settings page in your Recurly admin. Specify custom notes to add - or override Terms and Conditions. - maxLength: 16384 - customer_notes: - type: - - "null" - - string - title: Customer notes - description: >- - This will default to the Customer Notes text specified on the Invoice - Settings. Specify custom notes to add or override Customer Notes. - maxLength: 2048 - line_items: - description: The line items included in the invoice. - type: - - "null" - - array - title: Line Items - items: - $ref: "#/schemas/line_items_common" - has_more_line_items: - description: Indicates if there are more line items in the invoice. - type: - - "null" - - boolean - transactions: - description: The transactions associated with the invoice. - type: - - "null" - - array - title: Transactions - items: - type: - - "null" - - object - properties: - id: - description: The ID of a transaction linked to the invoice. - type: string - title: Transaction ID - maxLength: 13 - uuid: - type: string - title: Recurly UUID - description: >- - The UUID is useful for matching data with the CSV exports and - building URLs into Recurly's UI. - maxLength: 32 - credit_payments: - description: The credit payments related to the invoice. - type: - - "null" - - array - title: Credit payments - items: - type: - - "null" - - object - properties: - id: - description: The ID of a credit payment associated with the invoice. - type: string - title: Credit Payment ID - maxLength: 13 - uuid: - type: string - title: Recurly UUID - description: >- - The UUID is useful for matching data with the CSV exports and - building URLs into Recurly's UI. - maxLength: 32 - created_at: - description: The date and time when the invoice was created. - type: - - "null" - - string - format: date-time - title: Created at - readOnly: true - updated_at: - description: The date and time when the invoice was last updated. - type: - - "null" - - string - format: date-time - title: Last updated at - readOnly: true - due_at: - type: - - "null" - - string - format: date-time - title: Due at - description: Date invoice is due. This is the date the net terms are reached. - closed_at: - type: - - "null" - - string - format: date-time - title: Closed at - description: Date invoice was marked paid or failed. - dunning_campaign_id: - type: - - "null" - - string - title: Dunning Campaign ID - description: >- - Unique ID to identify the dunning campaign used when dunning the invoice. - Available when the Dunning Campaigns feature is enabled. For sites without - multiple dunning campaigns enabled, this will always be the default - dunning campaign. - maxLength: 256 - dunning_events_sent: - description: The number of dunning events sent for the invoice. - type: - - "null" - - integer - final_dunning_event: - description: The final dunning event related to the invoice if applicable. - type: - - "null" - - boolean - business_entity_id: - description: The business entity ID linked to the invoice. - type: - - "null" - - string - - line_items: - $schema: "http://json-schema.org/draft-07/schema#" - additionalProperties: true - type: - - "null" - - object - title: Line item - properties: - id: - type: string - title: Line item ID - maxLength: 13 - object: - type: - - "null" - - string - uuid: - type: string - title: UUID - description: >- - The UUID is useful for matching data with the CSV exports and building - URLs into Recurly's UI. - maxLength: 32 - type: - type: string - title: Line item type - description: >- - Charges are positive line items that debit the account. Credits are - negative line items that credit the account. - maxLength: 256 - item_code: - type: - - "null" - - string - title: Item Code - description: >- - Unique code to identify an item. Available when the Credit Invoices and - Subscription Billing Terms features are enabled. - maxLength: 50 - item_id: - type: - - "null" - - string - title: Item ID - description: >- - System-generated unique identifier for an item. Available when the Credit - Invoices and Subscription Billing Terms features are enabled. - maxLength: 13 - external_sku: - type: - - "null" - - string - title: External SKU - description: >- - Optional Stock Keeping Unit assigned to an item. Available when the Credit - Invoices and Subscription Billing Terms features are enabled. - maxLength: 50 - revenue_schedule_type: - type: - - "null" - - string - title: Revenue schedule type - maxLength: 256 - state: - type: string - title: Current state of the line item - description: >- - Pending line items are charges or credits on an account that have not been - applied to an invoice yet. Invoiced line items will always have an - `invoice_id` value. - maxLength: 256 - legacy_category: - type: - - "null" - - string - title: Legacy category - description: > - Category to describe the role of a line item on a legacy invoice: - - - "charges" refers to charges being billed for on this invoice. - - - "credits" refers to refund or proration credits. This portion of the - invoice can be considered a credit memo. - - - "applied_credits" refers to previous credits applied to this invoice. - See their original_line_item_id to determine where the credit first - originated. - - - "carryforwards" can be ignored. They exist to consume any remaining - credit balance. A new credit with the same amount will be created and - placed back on the account. - account: - $ref: "#/schemas/account_details_common" - bill_for_account_id: - type: string - title: Bill For Account ID - maxLength: 13 - description: The UUID of the account responsible for originating the line item. - subscription_id: - type: - - "null" - - string - title: Subscription ID - description: "If the line item is a charge or credit for a subscription, this is its ID." - maxLength: 13 - plan_id: - type: - - "null" - - string - title: Plan ID - description: >- - If the line item is a charge or credit for a plan or add-on, this is the - plan's ID. - maxLength: 13 - plan_code: - type: - - "null" - - string - title: Plan code - description: >- - If the line item is a charge or credit for a plan or add-on, this is the - plan's code. - maxLength: 50 - add_on_id: - type: - - "null" - - string - title: Add-on ID - description: If the line item is a charge or credit for an add-on this is its ID. - maxLength: 13 - add_on_code: - type: - - "null" - - string - title: Add-on code - description: "If the line item is a charge or credit for an add-on, this is its code." - maxLength: 50 - invoice_id: - type: - - "null" - - string - title: Invoice ID - description: Once the line item has been invoiced this will be the invoice's ID. - maxLength: 13 - invoice_number: - type: - - "null" - - string - title: Invoice number - description: >- - Once the line item has been invoiced this will be the invoice's number. If - VAT taxation and the Country Invoice Sequencing feature are enabled, - invoices will have country-specific invoice numbers for invoices billed to - EU countries (ex: FR1001). Non-EU invoices will continue to use the - site-level invoice number sequence. - maxLength: 256 - previous_line_item_id: - type: - - "null" - - string - title: Previous line item ID - description: >- - Will only have a value if the line item is a credit created from a - previous credit, or if the credit was created from a charge refund. - maxLength: 13 - original_line_item_invoice_id: - type: - - "null" - - string - title: Original line item's invoice ID - description: >- - The invoice where the credit originated. Will only have a value if the - line item is a credit created from a previous credit, or if the credit was - created from a charge refund. - maxLength: 13 - origin: - type: string - title: Origin of line item - description: >- - A credit created from an original charge will have the value of the - charge's origin. - maxLength: 256 - accounting_code: - type: string - title: Accounting code - description: >- - Internal accounting code to help you reconcile your revenue to the correct - ledger. Line items created as part of a subscription invoice will use the - plan or add-on's accounting code, otherwise the value will only be present - if you define an accounting code when creating the line item. - maxLength: 20 - product_code: - type: string - title: Product code - description: >- - For plan-related line items this will be the plan's code, for add-on - related line items it will be the add-on's code. For item-related line - items it will be the item's `external_sku`. - maxLength: 50 - credit_reason_code: - type: - - "null" - - string - title: Credit reason code - description: The reason the credit was given when line item is `type=credit`. - default: general - maxLength: 256 - currency: - type: string - title: Currency - description: 3-letter ISO 4217 currency code. - maxLength: 3 - amount: - type: number - format: float - title: Total after discounts and taxes - description: "`(quantity * unit_amount) - (discount + tax)`" - description: - type: string - title: Description - description: >- - Description that appears on the invoice. For subscription related items - this will be filled in automatically. - maxLength: 255 - quantity: - type: integer - title: Quantity - description: >- - This number will be multiplied by the unit amount to compute the subtotal - before any discounts or taxes. - default: 1 - unit_amount: - type: number - format: float - title: Unit amount - description: "Positive amount for a charge, negative amount for a credit." - unit_amount_decimal: - type: - - "null" - - string - title: Unit amount decimal - description: "Positive amount for a charge, negative amount for a credit." - subtotal: - type: number - format: float - title: Total before discounts and taxes - description: "`quantity * unit_amount`" - discount: - type: - - "null" - - number - format: float - title: Discount - description: The discount applied to the line item. - tax: - type: - - "null" - - number - format: float - title: Tax - description: The tax amount for the line item. - taxable: - type: boolean - title: Taxable? - description: "`true` if the line item is taxable, `false` if it is not." - tax_exempt: - type: boolean - title: Tax exempt? - description: >- - `true` exempts tax on charges, `false` applies tax on charges. If not - defined, then defaults to the Plan and Site settings. This attribute does - not work for credits (negative line items). Credits are always applied - post-tax. Pre-tax discounts should use the Coupons feature. - tax_code: - type: - - "null" - - string - title: Tax code - description: >- - Used by Avalara, Vertex, and Recurly’s EU VAT tax feature. The tax code - values are specific to each tax system. If you are using Recurly’s EU VAT - feature you can use `unknown`, `physical`, or `digital`. - maxLength: 50 - tax_info: - $ref: "#/schemas/tax_info_common" - proration_rate: - type: - - "null" - - number - format: float - title: Proration rate - description: >- - When a line item has been prorated, this is the rate of the proration. - Proration rates were made available for line items created after March 30, - 2017. For line items created prior to that date, the proration rate will - be `null`, even if the line item was prorated. - minimum: 0 - maximum: 1 - refund: - type: boolean - title: Refund? - refunded_quantity: - type: - - "null" - - integer - title: Refunded Quantity - description: >- - For refund charges, the quantity being refunded. For non-refund charges, - the total quantity refunded (possibly over multiple refunds). - credit_applied: - type: - - "null" - - number - format: float - title: Credit Applied - description: The amount of credit from this line item that was applied to the invoice. - shipping_address: - type: - - "null" - - object - properties: - id: - type: string - title: Shipping Address ID - maxLength: 13 - readOnly: true - start_date: - type: - - "null" - - string - format: date-time - title: Start date - description: >- - If an end date is present, this is value indicates the beginning of a - billing time range. If no end date is present it indicates billing for a - specific date. - end_date: - type: - - "null" - - string - format: date-time - title: End date - description: "If this date is provided, it indicates the end of a time range." - custom_fields: - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - name: - type: - - "null" - - string - value: - type: - - "null" - - string - created_at: - type: string - format: date-time - title: Created at - description: When the line item was created. - updated_at: - type: string - format: date-time - title: Last updated at - description: When the line item was last changed. - - measured_units: - $schema: "http://json-schema.org/draft-07/schema#" - additionalProperties: true - type: object - properties: - id: - description: Unique identifier for the measured unit - type: - - "null" - - string - maxLength: 13 - object: - description: "Type of object, in this case, 'measured_unit'" - type: - - "null" - - string - name: - description: Internal name used to identify the measured unit - type: - - "null" - - string - maxLength: 256 - display_name: - description: Human-readable name used for display purposes - type: - - "null" - - string - maxLength: 255 - state: - description: Current state of the measured unit - type: - - "null" - - string - maxLength: 255 - description: - description: Description of the measured unit - type: - - "null" - - string - maxLength: 1024 - created_at: - description: Timestamp indicating when the measured unit was created - type: - - "null" - - string - format: date-time - updated_at: - description: Timestamp indicating when the measured unit was last updated - type: - - "null" - - string - format: date-time - deleted_at: - description: Timestamp indicating when the measured unit was deleted (if applicable) - type: - - "null" - - string - format: date-time - - plans: - $schema: "http://json-schema.org/draft-07/schema#" - additionalProperties: true - type: object - properties: - id: - description: Unique identifier of the plan. - type: - - "null" - - string - maxLength: 13 - object: - description: Indicates the type of object which in this case is 'plan'. - type: - - "null" - - string - code: - description: Unique identifier code for the plan. - type: - - "null" - - string - maxLength: 256 - state: - description: The current state of the plan. - type: - - "null" - - string - maxLength: 256 - name: - description: Name of the plan. - type: - - "null" - - string - maxLength: 256 - description: - description: Description of the plan. - type: - - "null" - - string - maxLength: 1024 - interval_unit: - description: Unit of the billing interval for the plan. - type: - - "null" - - string - maxLength: 256 - interval_length: - description: Length of the billing interval for the plan. - type: - - "null" - - number - trial_unit: - description: Unit of the trial period for the plan. - type: - - "null" - - string - maxLength: 256 - trial_length: - description: Length of the trial period for the plan. - type: - - "null" - - number - trial_requires_billing_info: - description: Determines if billing information is required for the trial. - type: - - "null" - - boolean - total_billing_cycles: - description: Total number of billing cycles the plan will run for. - type: - - "null" - - number - auto_renew: - description: Indicates whether the plan should automatically renew. - type: - - "null" - - boolean - pricing_model: - description: The pricing model used for the plan. - type: - - "null" - - string - ramp_intervals: - description: Specifies ramp intervals for the plan. - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - starting_billing_cycle: - description: The starting billing cycle for the ramp interval. - type: - - "null" - - integer - currencies: - description: Contains currencies information within the ramp intervals. - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - currency: - description: Currency code for the interval. - type: - - "null" - - string - unit_amount: - description: Unit amount for the currency in the interval. - type: - - "null" - - number - custom_fields: - description: Includes any custom fields associated with the plan. - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - name: - description: Name of the custom field. - type: - - "null" - - string - value: - description: Value of the custom field. - type: - - "null" - - string - accounting_code: - description: The accounting code associated with the plan. - type: - - "null" - - string - maxLength: 256 - revenue_schedule_type: - description: Type of revenue schedule for the plan. - type: - - "null" - - string - maxLength: 256 - setup_fee_revenue_schedule_type: - description: Revenue schedule type for the setup fee. - type: - - "null" - - string - maxLength: 256 - setup_fee_accounting_code: - description: The accounting code associated with the setup fee. - type: - - "null" - - string - maxLength: 256 - avalara_transaction_type: - description: The Avalara transaction type used for tax calculation. - type: - - "null" - - number - avalara_service_type: - description: The Avalara service type used for tax calculation. - type: - - "null" - - number - tax_code: - description: Tax code used for the plan. - type: - - "null" - - string - maxLength: 256 - tax_exempt: - description: Determines if the plan is tax exempt. - type: - - "null" - - boolean - currencies: - description: Contains information about the currencies supported by the plan. - type: array - title: Pricing - items: - type: object - properties: - currency: - type: string - title: Currency - description: 3-letter ISO 4217 currency code. - maxLength: 3 - setup_fee: - type: number - format: float - title: Setup fee - description: >- - Amount of one-time setup fee automatically charged at the beginning - of a subscription billing cycle. For subscription plans with a - trial, the setup fee will be charged at the time of signup. Setup - fees do not increase with the quantity of a subscription plan. - minimum: 0 - maximum: 1000000 - unit_amount: - description: Unit amount for the currency in the plan. - type: number - format: float - title: Unit price - minimum: 0 - maximum: 1000000 - hosted_pages: - description: Provides details about hosted pages related to the plan. - type: object - properties: - success_url: - description: >- - URL to redirect when a user successfully completes hosted page - process. - type: - - "null" - - string - maxLength: 2048 - cancel_url: - description: URL to redirect when a user cancels during hosted page process. - type: - - "null" - - string - maxLength: 2048 - bypass_confirmation: - description: Determines if confirmation is bypassed on hosted pages. - type: - - "null" - - boolean - display_quantity: - description: Determines if quantity is displayed on hosted pages. - type: - - "null" - - boolean - allow_any_item_on_subscriptions: - description: Determines if any item can be added to subscriptions using this plan. - type: - - "null" - - boolean - dunning_campaign_id: - description: ID of the dunning campaign associated with the plan. - type: - - "null" - - string - maxLength: 256 - created_at: - description: Timestamp indicating when the plan was created. - type: - - "null" - - string - format: date-time - updated_at: - description: Timestamp indicating when the plan was last updated. - type: - - "null" - - string - format: date-time - deleted_at: - description: Timestamp indicating when the plan was deleted. - type: - - "null" - - string - format: date-time - - shipping_addresses: - $schema: "http://json-schema.org/draft-07/schema#" - additionalProperties: true - type: - - "null" - - object - properties: - id: - type: string - title: Shipping Address ID - maxLength: 13 - readOnly: true - object: - type: - - "null" - - string - account_id: - type: string - title: Account ID - maxLength: 13 - readOnly: true - nickname: - type: string - maxLength: 255 - first_name: - type: string - maxLength: 255 - last_name: - type: string - maxLength: 255 - company: - type: string - maxLength: 255 - email: - type: string - maxLength: 255 - vat_number: - type: string - maxLength: 20 - phone: - type: string - maxLength: 30 - street1: - type: string - maxLength: 255 - street2: - type: string - maxLength: 255 - city: - type: string - maxLength: 255 - region: - type: string - maxLength: 255 - description: State or province. - postal_code: - type: string - maxLength: 20 - description: Zip or postal code. - country: - type: string - maxLength: 50 - description: "Country, 2-letter ISO 3166-1 alpha-2 code." - geo_code: - type: - - "null" - - string - created_at: - type: string - title: Created at - format: date-time - readOnly: true - updated_at: - type: string - title: Updated at - format: date-time - readOnly: true - - shipping_methods: - $schema: "http://json-schema.org/schema#" - additionalProperties: true - type: object - properties: - id: - description: Unique identifier for the shipping method - type: string - title: Shipping Method ID - readOnly: true - maxLength: 13 - code: - type: string - title: Code - description: The internal name used identify the shipping method. - maxLength: 50 - name: - type: string - title: Name - description: The name of the shipping method displayed to customers. - maxLength: 100 - accounting_code: - type: string - title: Accounting Code - description: Accounting code for shipping method. - maxLength: 20 - tax_code: - type: string - title: Tax code - description: | - Used by Avalara, Vertex, and Recurly’s built-in tax feature. The tax - code values are specific to each tax system. If you are using Recurly’s - built-in taxes the values are: - - - `FR` – Common Carrier FOB Destination - - `FR022000` – Common Carrier FOB Origin - - `FR020400` – Non Common Carrier FOB Destination - - `FR020500` – Non Common Carrier FOB Origin - - `FR010100` – Delivery by Company Vehicle Before Passage of Title - - `FR010200` – Delivery by Company Vehicle After Passage of Title - - `NT` – Non-Taxable - maxLength: 50 - created_at: - description: Timestamp indicating when the shipping method was created - type: string - format: date-time - title: Created at - readOnly: true - updated_at: - description: Timestamp indicating when the shipping method was last updated - type: string - format: date-time - title: Last updated at - readOnly: true - deleted_at: - description: Timestamp indicating when the shipping method was deleted - type: string - format: date-time - title: Deleted at - readOnly: true - - subscriptions: - $schema: "http://json-schema.org/draft-07/schema#" - additionalProperties: true - type: object - properties: - id: - description: Unique identifier for the subscription. - type: - - "null" - - string - maxLength: 13 - object: - description: Indicates the type of object (subscription). - type: - - "null" - - string - uuid: - description: Universally unique identifier for the subscription. - type: - - "null" - - string - maxLength: 32 - account: - description: Information about the associated account for the subscription - type: - - "null" - - object - properties: - id: - type: - - "null" - - string - maxLength: 13 - object: - type: - - "null" - - string - code: - type: - - "null" - - string - maxLength: 256 - email: - type: - - "null" - - string - maxLength: 256 - first_name: - type: - - "null" - - string - last_name: - type: - - "null" - - string - company: - type: - - "null" - - string - parent_account_id: - type: - - "null" - - string - bill_to: - type: - - "null" - - string - dunning_campaign_id: - type: - - "null" - - string - plan: - description: Information about the plan associated with the subscription - type: object - properties: - id: - type: - - "null" - - string - maxLength: 13 - object: - type: - - "null" - - string - code: - type: - - "null" - - string - maxLength: 256 - name: - type: - - "null" - - string - state: - description: "Current state of the subscription (e.g., active, cancelled)." - type: - - "null" - - string - maxLength: 256 - shipping: - description: Information about the shipping associated with the subscription - type: - - "null" - - object - properties: - object: - type: - - "null" - - string - address: - $ref: "#/schemas/shipping_addresses_common" - method: - description: Information about the shipping method - type: - - "null" - - object - properties: - id: - type: string - title: Shipping Method ID - readOnly: true - maxLength: 13 - object: - type: - - "null" - - string - code: - type: - - "null" - - string - name: - type: - - "null" - - string - amount: - type: - - "null" - - number - coupon_redemptions: - description: Details of any coupons redeemed for the subscription. - $ref: "#/schemas/coupon_redemptions_common" - pending_change: - description: Information about any pending changes to the subscription - type: - - "null" - - object - title: Subscription Change - properties: - id: - type: string - title: Subscription Change ID - description: The ID of the Subscription Change. - maxLength: 13 - subscription_id: - type: string - title: Subscription ID - description: The ID of the subscription that is going to be changed. - maxLength: 13 - activate_at: - description: Timestamp when the pending change will be activated - type: string - format: date-time - title: Activated at - readOnly: true - activated: - type: boolean - title: Activated? - description: Returns `true` if the subscription change is activated. - created_at: - description: Timestamp when the pending change was created - type: string - format: date-time - title: Created at - readOnly: true - updated_at: - description: Timestamp when the pending change was last updated - type: string - format: date-time - title: Updated at - readOnly: true - deleted_at: - description: Timestamp when the pending change was deleted - type: string - format: date-time - title: Deleted at - readOnly: true - current_period_started_at: - description: Timestamp when the current period started - type: - - "null" - - string - format: date-time - current_period_ends_at: - description: Timestamp when the current period ends - type: - - "null" - - string - format: date-time - current_term_started_at: - description: Timestamp when the current term started - type: - - "null" - - string - format: date-time - current_term_ends_at: - description: Timestamp when the current term ends - type: - - "null" - - string - format: date-time - trial_started_at: - description: Timestamp when the trial period started - type: - - "null" - - string - format: date-time - trial_ends_at: - description: Timestamp when the trial period ends - type: - - "null" - - string - format: date-time - remaining_billing_cycles: - description: Number of billing cycles remaining before subscription ends. - type: - - "null" - - number - total_billing_cycles: - description: Total number of billing cycles for the subscription. - type: - - "null" - - number - renewal_billing_cycles: - description: Number of billing cycles in the renewal period. - type: - - "null" - - number - auto_renew: - description: Flag indicating whether the subscription auto renews. - type: - - "null" - - boolean - ramp_intervals: - description: Information about any ramp intervals associated with the subscription - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - starting_billing_cycle: - type: - - "null" - - integer - remaining_billing_cycles: - type: - - "null" - - integer - starting_on: - description: Timestamp when the ramp interval starts - type: - - "null" - - string - format: date-time - ending_on: - description: Timestamp when the ramp interval ends - type: - - "null" - - string - format: date-time - unit_amount: - type: - - "null" - - number - paused_at: - description: Timestamp when the subscription was paused - type: - - "null" - - string - format: date-time - remaining_pause_cycles: - description: Number of pause cycles remaining for the subscription. - type: - - "null" - - number - currency: - description: Currency used for billing the subscription. - type: - - "null" - - string - maxLength: 3 - revenue_schedule_type: - description: Type of revenue schedule for the subscription. - type: - - "null" - - string - maxLength: 256 - unit_amount: - description: Amount charged per unit for the subscription. - type: - - "null" - - number - tax_inclusive: - description: Flag indicating if taxes are included in the total amount. - type: - - "null" - - boolean - quantity: - description: Number of units or items included in the subscription. - type: - - "null" - - number - add_ons: - description: Any additional services or items added to the subscription. - type: - - "null" - - array - title: Add-ons - items: - type: - - "null" - - object - title: Subscription Add-on - description: This links an Add-on to a specific Subscription. - properties: - id: - type: string - title: Subscription Add-on ID - maxLength: 13 - code: - type: string - title: Add-on code - description: The unique identifier for the add-on within its plan. - maxLength: 50 - add_ons_total: - description: Total amount charged for the additional services or items. - type: - - "null" - - number - subtotal: - description: Subtotal amount before taxes and additional charges. - type: - - "null" - - number - tax: - description: Total tax amount applied to the subscription. - type: - - "null" - - number - tax_info: - description: Details of the tax information for the subscription. - $ref: "#/schemas/tax_info_common" - total: - description: Total amount including taxes and additional charges. - type: - - "null" - - number - collection_method: - description: Method used for collecting payments for the subscription. - type: - - "null" - - string - maxLength: 256 - po_number: - description: Purchase order number associated with the subscription. - type: - - "null" - - string - maxLength: 256 - net_terms: - description: Number of net terms for payment. - type: - - "null" - - number - net_terms_type: - description: "Type of net terms (e.g., days)." - type: - - "null" - - string - terms_and_conditions: - description: Terms and conditions agreed upon for the subscription. - type: - - "null" - - string - maxLength: 16384 - customer_notes: - description: Any notes or comments added by the customer. - type: - - "null" - - string - maxLength: 1024 - expiration_reason: - description: Reason for the subscription expiration. - type: - - "null" - - string - maxLength: 1024 - custom_fields: - description: Custom fields associated with the subscription - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - name: - type: - - "null" - - string - value: - type: - - "null" - - string - created_at: - description: Timestamp when the subscription was created - type: - - "null" - - string - format: date-time - updated_at: - description: Timestamp when the subscription was last updated - type: - - "null" - - string - format: date-time - activated_at: - description: Timestamp when the subscription was activated - type: - - "null" - - string - format: date-time - canceled_at: - description: Timestamp when the subscription was canceled - type: - - "null" - - string - format: date-time - expires_at: - description: Timestamp when the subscription expires - type: - - "null" - - string - format: date-time - bank_account_authorized_at: - description: Timestamp when bank account authorization occurred - type: - - "null" - - string - format: date-time - gateway_code: - description: Code associated with the payment gateway used for processing payments. - type: - - "null" - - string - maxLength: 256 - billing_info_id: - description: ID of the billing information associated with the subscription. - type: - - "null" - - string - maxLength: 13 - active_invoice_id: - description: ID of the active invoice associated with the subscription. - type: - - "null" - - string - started_with_gift: - description: Indicates if the subscription started with a gift or promotion. - type: - - "null" - - boolean - converted_at: - description: Timestamp when the subscription was converted - type: - - "null" - - string - format: date-time - action_result: - description: Result of the action performed on the subscription. - type: - - "null" - - object - additionalProperties: true - - transactions: - $schema: "http://json-schema.org/draft-07/schema#" - type: object - additionalProperties: true - properties: - id: - description: Unique identifier for the transaction - type: - - "null" - - string - maxLength: 13 - object: - description: Type of object (transaction) - type: - - "null" - - string - uuid: - description: Universally unique identifier for the transaction - type: - - "null" - - string - maxLength: 32 - original_transaction_id: - description: "ID of the original transaction, if applicable" - type: - - "null" - - string - maxLength: 13 - account: - description: Details of the account associated with the transaction - $ref: "#/schemas/account_details_common" - invoice: - description: Details of the invoice associated with the transaction - type: - - "null" - - object - properties: - id: - type: - - "null" - - string - maxLength: 13 - number: - type: - - "null" - - string - maxLength: 256 - business_entity_id: - type: - - "null" - - string - type: - type: - - "null" - - string - state: - type: - - "null" - - string - voided_by_invoice: - description: Details of the invoice that voided the transaction - type: - - "null" - - object - properties: - id: - type: - - "null" - - string - maxLength: 13 - object: - type: - - "null" - - string - number: - type: - - "null" - - string - maxLength: 256 - business_entity_id: - type: - - "null" - - string - type: - type: - - "null" - - string - state: - type: - - "null" - - string - subscription_ids: - description: List of subscription IDs associated with the transaction - type: array - items: - type: - - "null" - - string - maxLength: 13 - type: - description: Type of transaction - type: - - "null" - - string - maxLength: 256 - origin: - description: Source or origin of the transaction - type: - - "null" - - string - maxLength: 256 - currency: - description: Currency used for the transaction - type: - - "null" - - string - maxLength: 3 - amount: - description: Amount of the transaction - type: - - "null" - - number - status: - description: Current status of the transaction - type: - - "null" - - string - maxLength: 256 - success: - description: Indicates the success status of the transaction - type: - - "null" - - boolean - backup_payment_method_used: - description: Indicates whether a backup payment method was used - type: - - "null" - - boolean - refunded: - description: Indicates whether the transaction has been refunded - type: - - "null" - - boolean - billing_address: - description: Billing address details of the transaction - type: object - properties: - first_name: - type: - - "null" - - string - maxLength: 256 - last_name: - type: - - "null" - - string - maxLength: 256 - phone: - type: - - "null" - - string - maxLength: 256 - street1: - type: - - "null" - - string - maxLength: 256 - street2: - type: - - "null" - - string - maxLength: 256 - city: - type: - - "null" - - string - maxLength: 256 - region: - type: - - "null" - - string - maxLength: 256 - postal_code: - type: - - "null" - - string - maxLength: 256 - country: - type: - - "null" - - string - maxLength: 256 - geo_code: - type: - - "null" - - string - collection_method: - description: Method used to collect the transaction - type: - - "null" - - string - maxLength: 256 - payment_method: - description: Details of the payment method used for the transaction - type: object - properties: - object: - type: - - "null" - - string - card_type: - type: - - "null" - - string - maxLength: 256 - first_six: - type: - - "null" - - string - maxLength: 6 - last_four: - type: - - "null" - - string - maxLength: 4 - last_two: - type: - - "null" - - string - maxLength: 2 - exp_month: - type: - - "null" - - number - exp_year: - type: - - "null" - - number - gateway_token: - type: - - "null" - - string - maxLength: 256 - cc_bin_country: - type: - - "null" - - string - gateway_code: - type: - - "null" - - string - maxLength: 256 - billing_agreement_id: - type: - - "null" - - string - maxLength: 256 - name_on_account: - type: - - "null" - - string - maxLength: 256 - account_type: - type: - - "null" - - string - maxLength: 256 - routing_number: - type: - - "null" - - string - maxLength: 256 - routing_number_bank: - type: - - "null" - - string - maxLength: 256 - username: - type: - - "null" - - string - ip_address_v4: - description: IPv4 address of the transaction - type: - - "null" - - string - maxLength: 256 - ip_address_country: - description: Country of the IP address used for the transaction - type: - - "null" - - string - maxLength: 256 - status_code: - description: Status code of the transaction - type: - - "null" - - string - maxLength: 256 - status_message: - description: Message related to the status of the transaction - type: - - "null" - - string - maxLength: 1024 - customer_message: - description: Message for the customer related to the transaction - type: - - "null" - - string - maxLength: 1024 - customer_message_locale: - description: Locale of the customer message - type: - - "null" - - string - maxLength: 12 - payment_gateway: - description: Details of the payment gateway used for the transaction - type: object - properties: - id: - type: - - "null" - - string - maxLength: 13 - object: - type: - - "null" - - string - type: - type: - - "null" - - string - name: - type: - - "null" - - string - gateway_message: - description: Message returned by the payment gateway - type: - - "null" - - string - maxLength: 256 - gateway_reference: - description: Reference number provided by the payment gateway - type: - - "null" - - string - maxLength: 256 - gateway_approval_code: - description: Approval code provided by the payment gateway - type: - - "null" - - string - maxLength: 256 - gateway_response_code: - description: Response code from the payment gateway - type: - - "null" - - string - maxLength: 256 - gateway_response_time: - description: Time taken for the payment gateway to respond - type: - - "null" - - number - gateway_response_values: - description: Additional values in the gateway response - type: object - cvv_check: - description: Result of the CVV check - type: - - "null" - - string - maxLength: 256 - avs_check: - description: Result of the Address Verification System check - type: - - "null" - - string - maxLength: 256 - created_at: - description: Date and time when the transaction was created - type: - - "null" - - string - format: date-time - updated_at: - description: Date and time of the last update to the transaction - type: - - "null" - - string - format: date-time - voided_at: - description: Date and time when the transaction was voided - type: - - "null" - - string - format: date-time - collected_at: - description: Date and time when the transaction was collected - type: - - "null" - - string - format: date-time - action_result: - description: Result of the action taken for the transaction - type: - - "null" - - object - additionalProperties: true - vat_number: - description: VAT number associated with the transaction - type: - - "null" - - string - fraud_info: - description: Information related to fraud check for the transaction - type: - - "null" - - object - properties: - object: - type: - - "null" - - string - score: - type: - - "null" - - integer - decision: - type: - - "null" - - string - reference: - type: - - "null" - - string - risk_rules_triggered: - type: - - "null" - - array - items: - description: Details of individual risk rules triggered - type: - - "null" - - object - properties: - code: - type: - - "null" - - string - message: - type: - - "null" - - string - - unique_coupons: - $schema: "http://json-schema.org/draft-07/schema#" - additionalProperties: true - type: - - "null" - - object - description: A unique coupon code for a bulk coupon. - properties: - id: - type: string - title: Unique Coupon Code ID - readOnly: true - maxLength: 13 - object: - type: string - code: - type: string - title: Coupon code - description: The code the customer enters to redeem the coupon. - maxLength: 256 - state: - type: - - "null" - - string - title: State - description: Indicates if the unique coupon code is redeemable or why not. - maxLength: 256 - bulk_coupon_id: - type: - - "null" - - string - title: Bulk Coupon ID - description: The Coupon ID of the parent Bulk Coupon - readOnly: true - maxLength: 13 - bulk_coupon_code: - type: - - "null" - - string - title: Bulk Coupon code - description: The Coupon code of the parent Bulk Coupon - maxLength: 256 - created_at: - type: string - title: Created at - format: date-time - readOnly: true - updated_at: - type: string - title: Updated at - format: date-time - readOnly: true - redeemed_at: - type: - - "null" - - string - title: Redeemed at - description: The date and time the unique coupon code was redeemed. - format: date-time - readOnly: true - expired_at: - type: - - "null" - - string - title: Expired at - description: >- - The date and time the coupon was expired early or reached its - `max_redemptions`. - format: date-time - billing_infos_common: - $schema: "http://json-schema.org/draft-07/schema#" - type: object - properties: - id: - type: string - maxLength: 13 - readOnly: true - object: - type: - - "null" - - string - account_id: - type: string - maxLength: 13 - readOnly: true - first_name: - type: - - "null" - - string - maxLength: 50 - last_name: - type: - - "null" - - string - maxLength: 50 - company: - type: - - "null" - - string - maxLength: 100 - address: - type: object - properties: - phone: - type: - - "null" - - string - title: Phone number - maxLength: 256 - street1: - type: - - "null" - - string - title: Street 1 - maxLength: 256 - street2: - type: - - "null" - - string - title: Street 2 - maxLength: 256 - city: - type: - - "null" - - string - title: City - maxLength: 256 - region: - type: - - "null" - - string - title: State/Province - description: State or province. - maxLength: 256 - postal_code: - type: - - "null" - - string - title: Zip/Postal code - description: Zip or postal code. - maxLength: 256 - country: - type: - - "null" - - string - title: Country - description: "Country, 2-letter ISO 3166-1 alpha-2 code." - maxLength: 2 - vat_number: - type: - - "null" - - string - description: >- - Customer's VAT number (to avoid having the VAT applied). This is only used - for automatically collected invoices. - maxLength: 20 - valid: - type: boolean - readOnly: true - payment_method: - type: object - properties: - card_type: - description: "Visa, MasterCard, American Express, Discover, JCB, etc." - type: - - "null" - - string - maxLength: 256 - object: - type: - - "null" - - string - first_six: - type: - - "null" - - string - description: Credit card number's first six digits. - maxLength: 6 - last_four: - type: - - "null" - - string - description: >- - Credit card number's last four digits. Will refer to bank account if - payment method is ACH. - maxLength: 4 - last_two: - type: - - "null" - - string - description: The IBAN bank account's last two digits. - maxLength: 2 - exp_month: - type: - - "null" - - integer - description: Expiration month. - maxLength: 2 - exp_year: - type: - - "null" - - integer - description: Expiration year. - maxLength: 4 - gateway_token: - type: - - "null" - - string - description: >- - A token used in place of a credit card in order to perform - transactions. - maxLength: 50 - cc_bin_country: - type: - - "null" - - string - description: >- - The 2-letter ISO 3166-1 alpha-2 country code associated with the - credit card BIN, if known by Recurly. Available on the BillingInfo - object only. Available when the BIN country lookup feature is enabled. - maxLength: 256 - gateway_code: - type: - - "null" - - string - description: An identifier for a specific payment gateway. - maxLength: 13 - billing_agreement_id: - type: - - "null" - - string - description: >- - Billing Agreement identifier. Only present for Amazon or Paypal - payment methods. - maxLength: 256 - name_on_account: - type: - - "null" - - string - description: The name associated with the bank account. - maxLength: 256 - account_type: - description: The bank account type. Only present for ACH payment methods. - type: - - "null" - - string - maxLength: 256 - routing_number: - type: - - "null" - - string - description: >- - The bank account's routing number. Only present for ACH payment - methods. - maxLength: 256 - routing_number_bank: - type: - - "null" - - string - description: The bank name of this routing number. - maxLength: 256 - fraud: - type: - - "null" - - object - title: Fraud information - description: Most recent fraud result. - readOnly: true - properties: - score: - type: - - "null" - - integer - title: Kount score - decision: - title: Kount decision - maxLength: 10 - type: - - "null" - - string - risk_rules_triggered: - type: object - title: Kount rules - primary_payment_method: - type: boolean - description: >- - The `primary_payment_method` field is used to indicate the primary billing - info on the account. The first billing info created on an account will - always become primary. This payment method will be used - backup_payment_method: - type: boolean - description: >- - The `backup_payment_method` field is used to indicate a billing info as a - backup on the account that will be tried if the initial billing info used - for an invoice is declined. - created_at: - type: string - format: date-time - description: When the billing information was created. - readOnly: true - updated_at: - type: string - format: date-time - description: When the billing information was last changed. - readOnly: true - updated_by: - type: - - "null" - - object - properties: - ip: - type: - - "null" - - string - country: - type: - - "null" - - string - external_accounts_common: - $schema: "http://json-schema.org/draft-07/schema#" - type: object - properties: - object: - type: - - "null" - - string - id: - type: - - "null" - - string - external_account_code: - type: - - "null" - - string - external_connection_type: - type: - - "null" - - string - created_at: - type: - - "null" - - string - updated_at: - type: - - "null" - - string - shipping_addresses_common: - $schema: "http://json-schema.org/draft-07/schema#" - type: - - "null" - - object - properties: - id: - type: string - title: Shipping Address ID - maxLength: 13 - readOnly: true - object: - type: - - "null" - - string - account_id: - type: string - title: Account ID - maxLength: 13 - readOnly: true - nickname: - type: string - maxLength: 255 - first_name: - type: string - maxLength: 255 - last_name: - type: string - maxLength: 255 - company: - type: string - maxLength: 255 - email: - type: string - maxLength: 255 - vat_number: - type: string - maxLength: 20 - phone: - type: string - maxLength: 30 - street1: - type: string - maxLength: 255 - street2: - type: string - maxLength: 255 - city: - type: string - maxLength: 255 - region: - type: string - maxLength: 255 - description: State or province. - postal_code: - type: string - maxLength: 20 - description: Zip or postal code. - country: - type: string - maxLength: 50 - description: "Country, 2-letter ISO 3166-1 alpha-2 code." - geo_code: - type: - - "null" - - string - created_at: - type: string - title: Created at - format: date-time - readOnly: true - updated_at: - type: string - title: Updated at - format: date-time - readOnly: true - account_details_common: - type: - - "null" - - object - properties: - id: - type: string - object: - type: - - "null" - - string - code: - type: - - "null" - - string - email: - type: - - "null" - - string - first_name: - type: - - "null" - - string - last_name: - type: - - "null" - - string - company: - type: - - "null" - - string - parent_account_id: - type: - - "null" - - string - bill_to: - type: - - "null" - - string - dunning_campaign_id: - type: - - "null" - - string - coupons_common: - $schema: "http://json-schema.org/draft-07/schema#" - type: object - properties: - id: - type: - - "null" - - string - maxLength: 13 - object: - type: - - "null" - - string - code: - type: - - "null" - - string - maxLength: 256 - name: - type: - - "null" - - string - maxLength: 256 - state: - type: - - "null" - - string - maxLength: 256 - max_redemptions: - type: - - "null" - - number - max_redemptions_per_account: - type: - - "null" - - number - unique_coupon_codes_count: - type: - - "null" - - number - unique_code_template: - type: - - "null" - - string - maxLength: 256 - unique_coupon_code: - $ref: "#/schemas/unique_coupons_common" - duration: - type: - - "null" - - string - maxLength: 256 - temporal_amount: - type: - - "null" - - number - temporal_unit: - type: - - "null" - - string - maxLength: 256 - free_trial_unit: - type: - - "null" - - string - maxLength: 256 - free_trial_amount: - type: - - "null" - - number - applies_to_all_plans: - type: - - "null" - - boolean - applies_to_all_items: - type: - - "null" - - boolean - applies_to_non_plan_charges: - type: - - "null" - - boolean - plans: - type: - - "null" - - array - title: Plans - description: >- - A list of plans for which this coupon applies. This will be `null` if - `applies_to_all_plans=true`. - items: - type: object - title: Plan mini details - description: Just the important parts. - properties: - id: - type: string - title: Plan ID - maxLength: 13 - readOnly: true - code: - type: string - title: Plan code - description: >- - Unique code to identify the plan. This is used in Hosted Payment - Page URLs and in the invoice exports. - maxLength: 13 - items: - type: - - "null" - - array - title: Items - description: | - A list of items for which this coupon applies. This will be - `null` if `applies_to_all_items=true`. - items: - type: - - "null" - - object - title: Item mini details - description: Just the important parts. - properties: - id: - type: string - title: Item ID - maxLength: 13 - readOnly: true - redemption_resource: - type: - - "null" - - string - maxLength: 256 - discount: - type: - - "null" - - object - description: | - Details of the discount a coupon applies. Will contain a `type` - property and one of the following properties: `percent`, `fixed`, `trial`. - properties: - type: - type: string - maxLength: 256 - percent: - description: This is only present when `type=percent`. - type: integer - currencies: - type: array - description: This is only present when `type=fixed`. - items: - type: - - "null" - - object - properties: - currency: - type: string - title: Currency - description: 3-letter ISO 4217 currency code. - maxLength: 3 - amount: - type: number - format: float - title: Discount Amount - description: Value of the fixed discount that this coupon applies. - trial: - type: object - description: This is only present when `type=free_trial`. - properties: - unit: - title: Trial unit - description: Temporal unit of the free trial - type: string - maxLength: 256 - length: - type: integer - title: Trial length - description: >- - Trial length measured in the units specified by the sibling `unit` - property - coupon_type: - type: - - "null" - - string - maxLength: 256 - hosted_page_description: - type: - - "null" - - string - maxLength: 1024 - invoice_description: - type: - - "null" - - string - maxLength: 1024 - redeem_by: - type: - - "null" - - string - maxLength: 256 - created_at: - type: - - "null" - - string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - expired_at: - type: - - "null" - - string - format: date-time - unique_coupons_common: - $schema: "http://json-schema.org/draft-07/schema#" - type: - - "null" - - object - description: A unique coupon code for a bulk coupon. - properties: - id: - type: string - title: Unique Coupon Code ID - readOnly: true - maxLength: 13 - object: - type: string - code: - type: string - title: Coupon code - description: The code the customer enters to redeem the coupon. - maxLength: 256 - state: - type: - - "null" - - string - title: State - description: Indicates if the unique coupon code is redeemable or why not. - maxLength: 256 - bulk_coupon_id: - type: - - "null" - - string - title: Bulk Coupon ID - description: The Coupon ID of the parent Bulk Coupon - readOnly: true - maxLength: 13 - bulk_coupon_code: - type: - - "null" - - string - title: Bulk Coupon code - description: The Coupon code of the parent Bulk Coupon - maxLength: 256 - created_at: - type: string - title: Created at - format: date-time - readOnly: true - updated_at: - type: string - title: Updated at - format: date-time - readOnly: true - redeemed_at: - type: - - "null" - - string - title: Redeemed at - description: The date and time the unique coupon code was redeemed. - format: date-time - readOnly: true - expired_at: - type: - - "null" - - string - title: Expired at - description: >- - The date and time the coupon was expired early or reached its - `max_redemptions`. - format: date-time - users_common: - type: - - "null" - - object - properties: - id: - type: string - object: - type: - - "null" - - string - email: - type: - - "null" - - string - first_name: - type: - - "null" - - string - last_name: - type: - - "null" - - string - time_zone: - type: - - "null" - - string - created_at: - type: - - "null" - - string - format: date-time - deleted_at: - type: - - "null" - - string - format: date-time - line_items_common: - $schema: "http://json-schema.org/draft-07/schema#" - type: - - "null" - - object - title: Line item - properties: - id: - type: string - title: Line item ID - maxLength: 13 - object: - type: - - "null" - - string - uuid: - type: string - title: UUID - description: >- - The UUID is useful for matching data with the CSV exports and building - URLs into Recurly's UI. - maxLength: 32 - type: - type: string - title: Line item type - description: >- - Charges are positive line items that debit the account. Credits are - negative line items that credit the account. - maxLength: 256 - item_code: - type: - - "null" - - string - title: Item Code - description: >- - Unique code to identify an item. Available when the Credit Invoices and - Subscription Billing Terms features are enabled. - maxLength: 50 - item_id: - type: - - "null" - - string - title: Item ID - description: >- - System-generated unique identifier for an item. Available when the Credit - Invoices and Subscription Billing Terms features are enabled. - maxLength: 13 - external_sku: - type: - - "null" - - string - title: External SKU - description: >- - Optional Stock Keeping Unit assigned to an item. Available when the Credit - Invoices and Subscription Billing Terms features are enabled. - maxLength: 50 - revenue_schedule_type: - type: - - "null" - - string - title: Revenue schedule type - maxLength: 256 - state: - type: string - title: Current state of the line item - description: >- - Pending line items are charges or credits on an account that have not been - applied to an invoice yet. Invoiced line items will always have an - `invoice_id` value. - maxLength: 256 - legacy_category: - type: - - "null" - - string - title: Legacy category - description: > - Category to describe the role of a line item on a legacy invoice: - - - "charges" refers to charges being billed for on this invoice. - - - "credits" refers to refund or proration credits. This portion of the - invoice can be considered a credit memo. - - - "applied_credits" refers to previous credits applied to this invoice. - See their original_line_item_id to determine where the credit first - originated. - - - "carryforwards" can be ignored. They exist to consume any remaining - credit balance. A new credit with the same amount will be created and - placed back on the account. - account: - $ref: "#/schemas/account_details_common" - bill_for_account_id: - type: string - title: Bill For Account ID - maxLength: 13 - description: The UUID of the account responsible for originating the line item. - subscription_id: - type: - - "null" - - string - title: Subscription ID - description: "If the line item is a charge or credit for a subscription, this is its ID." - maxLength: 13 - plan_id: - type: - - "null" - - string - title: Plan ID - description: >- - If the line item is a charge or credit for a plan or add-on, this is the - plan's ID. - maxLength: 13 - plan_code: - type: - - "null" - - string - title: Plan code - description: >- - If the line item is a charge or credit for a plan or add-on, this is the - plan's code. - maxLength: 50 - add_on_id: - type: - - "null" - - string - title: Add-on ID - description: If the line item is a charge or credit for an add-on this is its ID. - maxLength: 13 - add_on_code: - type: - - "null" - - string - title: Add-on code - description: "If the line item is a charge or credit for an add-on, this is its code." - maxLength: 50 - invoice_id: - type: - - "null" - - string - title: Invoice ID - description: Once the line item has been invoiced this will be the invoice's ID. - maxLength: 13 - invoice_number: - type: - - "null" - - string - title: Invoice number - description: >- - Once the line item has been invoiced this will be the invoice's number. If - VAT taxation and the Country Invoice Sequencing feature are enabled, - invoices will have country-specific invoice numbers for invoices billed to - EU countries (ex: FR1001). Non-EU invoices will continue to use the - site-level invoice number sequence. - maxLength: 256 - previous_line_item_id: - type: - - "null" - - string - title: Previous line item ID - description: >- - Will only have a value if the line item is a credit created from a - previous credit, or if the credit was created from a charge refund. - maxLength: 13 - original_line_item_invoice_id: - type: - - "null" - - string - title: Original line item's invoice ID - description: >- - The invoice where the credit originated. Will only have a value if the - line item is a credit created from a previous credit, or if the credit was - created from a charge refund. - maxLength: 13 - origin: - type: string - title: Origin of line item - description: >- - A credit created from an original charge will have the value of the - charge's origin. - maxLength: 256 - accounting_code: - type: string - title: Accounting code - description: >- - Internal accounting code to help you reconcile your revenue to the correct - ledger. Line items created as part of a subscription invoice will use the - plan or add-on's accounting code, otherwise the value will only be present - if you define an accounting code when creating the line item. - maxLength: 20 - product_code: - type: string - title: Product code - description: >- - For plan-related line items this will be the plan's code, for add-on - related line items it will be the add-on's code. For item-related line - items it will be the item's `external_sku`. - maxLength: 50 - credit_reason_code: - type: - - "null" - - string - title: Credit reason code - description: The reason the credit was given when line item is `type=credit`. - default: general - maxLength: 256 - currency: - type: string - title: Currency - description: 3-letter ISO 4217 currency code. - maxLength: 3 - amount: - type: number - format: float - title: Total after discounts and taxes - description: "`(quantity * unit_amount) - (discount + tax)`" - description: - type: string - title: Description - description: >- - Description that appears on the invoice. For subscription related items - this will be filled in automatically. - maxLength: 255 - quantity: - type: integer - title: Quantity - description: >- - This number will be multiplied by the unit amount to compute the subtotal - before any discounts or taxes. - default: 1 - unit_amount: - type: number - format: float - title: Unit amount - description: "Positive amount for a charge, negative amount for a credit." - unit_amount_decimal: - type: - - "null" - - string - title: Unit amount decimal - description: "Positive amount for a charge, negative amount for a credit." - subtotal: - type: number - format: float - title: Total before discounts and taxes - description: "`quantity * unit_amount`" - discount: - type: - - "null" - - number - format: float - title: Discount - description: The discount applied to the line item. - tax: - type: - - "null" - - number - format: float - title: Tax - description: The tax amount for the line item. - taxable: - type: boolean - title: Taxable? - description: "`true` if the line item is taxable, `false` if it is not." - tax_exempt: - type: boolean - title: Tax exempt? - description: >- - `true` exempts tax on charges, `false` applies tax on charges. If not - defined, then defaults to the Plan and Site settings. This attribute does - not work for credits (negative line items). Credits are always applied - post-tax. Pre-tax discounts should use the Coupons feature. - tax_code: - type: - - "null" - - string - title: Tax code - description: >- - Used by Avalara, Vertex, and Recurly’s EU VAT tax feature. The tax code - values are specific to each tax system. If you are using Recurly’s EU VAT - feature you can use `unknown`, `physical`, or `digital`. - maxLength: 50 - tax_info: - $ref: "#/schemas/tax_info_common" - proration_rate: - type: - - "null" - - number - format: float - title: Proration rate - description: >- - When a line item has been prorated, this is the rate of the proration. - Proration rates were made available for line items created after March 30, - 2017. For line items created prior to that date, the proration rate will - be `null`, even if the line item was prorated. - minimum: 0 - maximum: 1 - refund: - type: boolean - title: Refund? - refunded_quantity: - type: - - "null" - - integer - title: Refunded Quantity - description: >- - For refund charges, the quantity being refunded. For non-refund charges, - the total quantity refunded (possibly over multiple refunds). - credit_applied: - type: - - "null" - - number - format: float - title: Credit Applied - description: The amount of credit from this line item that was applied to the invoice. - shipping_address: - type: - - "null" - - object - properties: - id: - type: string - title: Shipping Address ID - maxLength: 13 - readOnly: true - start_date: - type: - - "null" - - string - format: date-time - title: Start date - description: >- - If an end date is present, this is value indicates the beginning of a - billing time range. If no end date is present it indicates billing for a - specific date. - end_date: - type: - - "null" - - string - format: date-time - title: End date - description: "If this date is provided, it indicates the end of a time range." - custom_fields: - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - name: - type: - - "null" - - string - value: - type: - - "null" - - string - created_at: - type: string - format: date-time - title: Created at - description: When the line item was created. - updated_at: - type: string - format: date-time - title: Last updated at - description: When the line item was last changed. - tax_info_common: - $schema: "http://json-schema.org/draft-07/schema#" - type: - - "null" - - object - properties: - type: - type: - - "null" - - string - region: - type: - - "null" - - string - rate: - type: - - "null" - - number - tax_details: - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - type: - type: - - "null" - - string - region: - type: - - "null" - - string - rate: - type: - - "null" - - number - tax: - type: - - "null" - - number - name: - type: - - "null" - - string - level: - type: - - "null" - - string - billable: - type: - - "null" - - boolean - coupon_redemptions_common: - $schema: "http://json-schema.org/draft-07/schema#" - type: - - "null" - - object - properties: - id: - type: - - "null" - - string - object: - type: - - "null" - - string - coupon: - type: - - "null" - - object - properties: - id: - type: - - "null" - - string - object: - type: - - "null" - - string - code: - type: - - "null" - - string - name: - type: - - "null" - - string - state: - type: - - "null" - - string - discount: - type: - - "null" - - object - properties: - type: - type: - - "null" - - string - percent: - type: - - "null" - - integer - currencies: - type: - - "null" - - array - items: - type: - - "null" - - object - properties: - currency: - type: - - "null" - - string - amount: - type: - - "null" - - number - trial: - type: - - "null" - - object - properties: - unit: - type: - - "null" - - string - length: - type: - - "null" - - integer - coupon_type: - type: - - "null" - - string - expired_at: - type: - - "null" - - string - format: date-time - state: - type: - - "null" - - string - discounted: - type: - - "null" - - number - created_at: - type: - - "null" - - string - format: date-time diff --git a/airbyte-integrations/connectors/source-recurly/source_recurly/run.py b/airbyte-integrations/connectors/source-recurly/source_recurly/run.py deleted file mode 100644 index 281390e8dfae..000000000000 --- a/airbyte-integrations/connectors/source-recurly/source_recurly/run.py +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - - -import sys - -from airbyte_cdk.entrypoint import launch - -from .source import SourceRecurly - - -def run(): - source = SourceRecurly() - launch(source, sys.argv[1:]) diff --git a/airbyte-integrations/connectors/source-recurly/source_recurly/source.py b/airbyte-integrations/connectors/source-recurly/source_recurly/source.py deleted file mode 100644 index b95ad6327718..000000000000 --- a/airbyte-integrations/connectors/source-recurly/source_recurly/source.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource - -""" -This file provides the necessary constructs to interpret a provided declarative YAML configuration file into -source connector. - -WARNING: Do not modify this file. -""" - - -# Declarative Source -class SourceRecurly(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-recurly/unit_tests/__init__.py b/airbyte-integrations/connectors/source-recurly/unit_tests/__init__.py deleted file mode 100644 index 66f6de8cb2bb..000000000000 --- a/airbyte-integrations/connectors/source-recurly/unit_tests/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-integrations/connectors/source-recurly/unit_tests/conftest.py b/airbyte-integrations/connectors/source-recurly/unit_tests/conftest.py deleted file mode 100644 index 6e106acb461a..000000000000 --- a/airbyte-integrations/connectors/source-recurly/unit_tests/conftest.py +++ /dev/null @@ -1,124 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# -from pytest import fixture - - -@fixture -def config_pass(): - return { - "api_key": "abcd1234" - } - - -@fixture -def incremental_config_pass(): - return { - "api_key": "abcd1234", - "begin_time": "2024-01-10T00:00:00Z", - "end_time": "2024-07-01T23:59:59Z" - } - - -@fixture -def accounts_url(): - return "https://v3.recurly.com/accounts" - - -@fixture -def account_coupon_redemptions_url(): - return "https://v3.recurly.com/accounts/abc/coupon_redemptions" - - -@fixture -def account_notes_url(): - return "https://v3.recurly.com/accounts/abc/notes" - - -@fixture -def coupons_url(): - return "https://v3.recurly.com/coupons" - - -@fixture -def mock_accounts_response(): - return { - "data": [ - {"address": {"street1": "", "street2": "", "city": "", "region": "", "postal_code": "", "country": "", "phone": ""}, - "bill_to": "self", - "billing_info": {"id": "abcdef", "object": "billing_info", "account_id": "abc", "primary_payment_method": True, - "backup_payment_method": False, "first_name": "test_user", "last_name": "", "company": "", - "address": {"street1": "lorem ipsum", "street2": "", "city": "lorem ipsum", "region": "lorem ipsum", - "postal_code": "85475", "country": "US", "phone": ""}, "vat_number": "", "valid": True, - "payment_method": {"object": "credit_card", "card_type": "Visa", "first_six": "400000", "last_four": "2024", - "cc_bin_country": None, "exp_month": 11, "exp_year": 2020, - "card_network_preference": None}, "created_at": "2024-04-20T15:52:10Z", - "updated_at": "2024-04-20T15:52:10Z", "updated_by": {"ip": None, "country": None}, "fraud": None}, - "cc_emails": "", "code": "test-account1", "company": "", "created_at": "2024-04-20T03:42:49Z", "custom_fields": [], - "deleted_at": None, "dunning_campaign_id": None, "email": "", "exemption_certificate": None, "external_accounts": [], - "first_name": "test_user", "has_active_subscription": False, "has_canceled_subscription": False, - "has_future_subscription": False, - "has_live_subscription": False, "has_past_due_invoice": False, "has_paused_subscription": False, "id": "abc", - "last_name": "", "object": "account", "parent_account_id": None, "preferred_locale": "", "preferred_time_zone": None, - "shipping_addresses": [{"object": "shipping_address", "first_name": "Test", "last_name": "Name", "company": "", "phone": "", - "street1": "first street", "street2": "", "city": "Montana City", "region": "", "postal_code": "58745", - "country": "US", "nickname": "Test Name", "email": "", "vat_number": "", "id": "nwnsbcqp9u6c", - "account_id": "abc", "created_at": "2024-04-20T15:15:04Z", - "updated_at": "2024-04-20T15:15:04Z"}], "state": "active", "tax_exempt": False, - "updated_at": "2024-04-20T15:52:10Z", "username": "test_user", "vat_number": "", "invoice_template_id": None, - "override_business_entity_id": None} - ], - "has_more": False, - } - - -@fixture -def mock_account_coupon_redemptions_response(): - return { - "data": [ - {"id": "abcde", "object": "coupon_redemption", - "account": {"id": "abc", "object": "account", "code": "test-account-2", "email": "", "first_name": "test", - "last_name": "user", "company": "", "parent_account_id": None, "bill_to": "self", "dunning_campaign_id": None}, - "subscription_id": None, - "coupon": {"id": "abcdef", "object": "coupon", "code": "aaja1xpwrotu", "name": "Integration Coupon test number 1", - "state": "redeemable", "max_redemptions": None, "max_redemptions_per_account": None, "duration": "forever", - "temporal_unit": None, "temporal_amount": None, "applies_to_all_plans": True, "applies_to_all_items": False, - "applies_to_non_plan_charges": False, "redemption_resource": "Account", - "discount": {"type": "percent", "percent": 97}, "coupon_type": "single_code", "hosted_page_description": None, - "invoice_description": None, "unique_coupon_codes_count": 0, "unique_code_template": None, - "unique_coupon_code": None, "plans": None, "items": None, "redeem_by": None, "created_at": "2024-04-24T12:14:40Z", - "updated_at": "2024-04-23T02:51:38Z", "expired_at": None}, "state": "inactive", "currency": "USD", - "discounted": 0.0, "created_at": "2024-04-23T02:51:32Z", "updated_at": "2024-04-23T02:51:39Z", - "removed_at": "2024-04-23T02:51:39Z"} - ], - "has_more": False, - } - - -@fixture -def mock_account_notes_response(): - return { - "data": [ - {"id": "abc", "object": "account_note", "account_id": "abc", - "user": {"id": "abcde", "object": "user", "email": "integration-test@airbyte.io", "first_name": "Team", - "last_name": "Airbyte", "time_zone": None, "created_at": "2024-04-21T04:05:42Z", "deleted_at": None}, - "message": "This is a second test note because two notes is better than one.", "created_at": "2024-04-21T20:42:25Z"} - ], - "has_more": False, - } - - -@fixture -def mock_coupons_response(): - return { - "data": [ - {"id": "efg", "object": "coupon", "code": "81818asdasd", "name": "third coupon", "state": "redeemable", - "max_redemptions": None, "max_redemptions_per_account": None, "duration": "forever", "temporal_unit": None, - "temporal_amount": None, "applies_to_all_plans": True, "applies_to_all_items": False, "applies_to_non_plan_charges": False, - "redemption_resource": "Account", "discount": {"type": "percent", "percent": 12}, "coupon_type": "single_code", - "hosted_page_description": None, "invoice_description": None, "unique_coupon_codes_count": 0, "unique_code_template": None, - "unique_coupon_code": None, "plans": None, "items": None, "redeem_by": None, "created_at": "2024-04-24T11:55:23Z", - "updated_at": "2024-04-24T11:55:23Z", "expired_at": None} - ], - "has_more": False, - } diff --git a/airbyte-integrations/connectors/source-recurly/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-recurly/unit_tests/test_streams.py deleted file mode 100644 index 1056f3dcb1cd..000000000000 --- a/airbyte-integrations/connectors/source-recurly/unit_tests/test_streams.py +++ /dev/null @@ -1,79 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Mapping - -from airbyte_cdk.sources.streams import Stream -from airbyte_protocol.models import SyncMode -from source_recurly.source import SourceRecurly - - -def get_stream_by_name(stream_name: str, config: Mapping[str, Any]) -> Stream: - source = SourceRecurly() - matches_by_name = [stream_config for stream_config in source.streams(config) if stream_config.name == stream_name] - if not matches_by_name: - raise ValueError("Please provide a valid stream name.") - return matches_by_name[0] - - -class TestStreams: - def test_request_params(config_pass): - stream = get_stream_by_name("accounts", config_pass) - expected_params = {'order': 'asc', 'sort': 'updated_at'} - assert stream.retriever.requester.get_request_params() == expected_params - - def test_read_records(self, requests_mock, config_pass, accounts_url, mock_accounts_response): - requests_mock.get(url=accounts_url, status_code=200, json=mock_accounts_response) - stream = get_stream_by_name("accounts", config_pass) - expected_parsed_records = mock_accounts_response.get("data") - records = [] - for stream_slice in stream.stream_slices(sync_mode=SyncMode.full_refresh): - records.extend(list(stream.read_records(sync_mode=SyncMode.full_refresh, stream_slice=stream_slice))) - records.sort() - expected_parsed_records.sort() - assert len(records) == len(expected_parsed_records) - for i in range(len(records)): - assert sorted(records[i].keys()) == sorted(expected_parsed_records[i].keys()) - - def test_account_coupon_redemptions_read_records(self, requests_mock, config_pass, accounts_url, mock_accounts_response, account_coupon_redemptions_url, mock_account_coupon_redemptions_response): - requests_mock.get(url=accounts_url, status_code=200, json=mock_accounts_response) - requests_mock.get(url=account_coupon_redemptions_url, status_code=200, json=mock_account_coupon_redemptions_response) - stream = get_stream_by_name("account_coupon_redemptions", config_pass) - expected_parsed_records = mock_account_coupon_redemptions_response.get("data") - records = [] - for stream_slice in stream.stream_slices(sync_mode=SyncMode.full_refresh): - records.extend(list(stream.read_records(sync_mode=SyncMode.full_refresh, stream_slice=stream_slice))) - records.sort() - expected_parsed_records.sort() - assert len(records) == len(expected_parsed_records) - for i in range(len(records)): - assert sorted(records[i].keys()) == sorted(expected_parsed_records[i].keys()) - - def test_account_notes_read_records(self, requests_mock, config_pass, accounts_url, mock_accounts_response, account_notes_url, mock_account_notes_response): - requests_mock.get(url=accounts_url, status_code=200, json=mock_accounts_response) - requests_mock.get(url=account_notes_url, status_code=200, json=mock_account_notes_response) - stream = get_stream_by_name("account_notes", config_pass) - expected_parsed_records = mock_account_notes_response.get("data") - records = [] - for stream_slice in stream.stream_slices(sync_mode=SyncMode.full_refresh): - records.extend(list(stream.read_records(sync_mode=SyncMode.full_refresh, stream_slice=stream_slice))) - records.sort() - expected_parsed_records.sort() - assert len(records) == len(expected_parsed_records) - for i in range(len(records)): - assert sorted(records[i].keys()) == sorted(expected_parsed_records[i].keys()) - - - def test_coupons_read_records(self, requests_mock, config_pass, coupons_url, mock_coupons_response): - requests_mock.get(url=coupons_url, status_code=200, json=mock_coupons_response) - stream = get_stream_by_name("coupons", config_pass) - expected_parsed_records = mock_coupons_response.get("data") - records = [] - for stream_slice in stream.stream_slices(sync_mode=SyncMode.full_refresh): - records.extend(list(stream.read_records(sync_mode=SyncMode.full_refresh, stream_slice=stream_slice))) - records.sort() - expected_parsed_records.sort() - assert len(records) == len(expected_parsed_records) - for i in range(len(records)): - assert sorted(records[i].keys()) == sorted(expected_parsed_records[i].keys()) diff --git a/airbyte-integrations/connectors/source-reddit/metadata.yaml b/airbyte-integrations/connectors/source-reddit/metadata.yaml index f3ede0a2925d..ab8247db8ecf 100644 --- a/airbyte-integrations/connectors/source-reddit/metadata.yaml +++ b/airbyte-integrations/connectors/source-reddit/metadata.yaml @@ -14,11 +14,11 @@ data: enabled: false packageName: airbyte-source-reddit connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 3ed344ac-4099-402c-bf83-1cfdc53295d9 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-reddit githubIssueLabel: source-reddit icon: icon.svg diff --git a/airbyte-integrations/connectors/source-redshift/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-redshift/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-redshift/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-redshift/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-redshift/metadata.yaml b/airbyte-integrations/connectors/source-redshift/metadata.yaml index 2a8d1bc45e9a..798a2c5b9fca 100644 --- a/airbyte-integrations/connectors/source-redshift/metadata.yaml +++ b/airbyte-integrations/connectors/source-redshift/metadata.yaml @@ -2,10 +2,21 @@ data: ab_internal: ql: 200 sl: 100 + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a connectorSubtype: database + connectorTestSuitesOptions: + - suite: unitTests + - suite: integrationTests + testSecrets: + - fileName: config.json + name: SECRET_SOURCE-REDSHIFT__CREDS + secretStore: + alias: airbyte-connector-testing-secret-store + type: GSM connectorType: source definitionId: e87ffa8e-a3b5-f69c-9076-6011339de1f6 - dockerImageTag: 0.5.2 + dockerImageTag: 0.5.3 dockerRepository: airbyte/source-redshift documentationUrl: https://docs.airbyte.com/integrations/sources/redshift githubIssueLabel: source-redshift @@ -21,13 +32,4 @@ data: supportLevel: community tags: - language:java - connectorTestSuitesOptions: - - suite: unitTests - - suite: integrationTests - testSecrets: - - name: SECRET_SOURCE-REDSHIFT__CREDS - fileName: config.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-rentcast/metadata.yaml b/airbyte-integrations/connectors/source-rentcast/metadata.yaml index 35ce0ca8e491..df8c51805514 100644 --- a/airbyte-integrations/connectors/source-rentcast/metadata.yaml +++ b/airbyte-integrations/connectors/source-rentcast/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-rentcast connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.14.0@sha256:accdf6c1bbcabd45b40f836692e4f3b1a1e1f0b28267973802ee212cd9c2c16a + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: f1d3c80a-b443-49b9-ad32-560ce3d61edb - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-rentcast githubIssueLabel: source-rentcast icon: icon.svg diff --git a/airbyte-integrations/connectors/source-repairshopr/README.md b/airbyte-integrations/connectors/source-repairshopr/README.md new file mode 100644 index 000000000000..79fd9a4727ab --- /dev/null +++ b/airbyte-integrations/connectors/source-repairshopr/README.md @@ -0,0 +1,35 @@ +# Repairshopr +This directory contains the manifest-only connector for `source-repairshopr`. + +Repairshopr is a CRM and an integrated marketing platform. +With this connector we can extract data from various streams such as customers , invoices and payments. +Docs : https://api-docs.repairshopr.com/#/ + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-repairshopr:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-repairshopr build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-repairshopr test +``` + diff --git a/airbyte-integrations/connectors/source-repairshopr/acceptance-test-config.yml b/airbyte-integrations/connectors/source-repairshopr/acceptance-test-config.yml new file mode 100644 index 000000000000..1ce63264ca19 --- /dev/null +++ b/airbyte-integrations/connectors/source-repairshopr/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-repairshopr:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-repairshopr/icon.svg b/airbyte-integrations/connectors/source-repairshopr/icon.svg new file mode 100644 index 000000000000..90cb358cdf0d --- /dev/null +++ b/airbyte-integrations/connectors/source-repairshopr/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-repairshopr/manifest.yaml b/airbyte-integrations/connectors/source-repairshopr/manifest.yaml new file mode 100644 index 000000000000..a75286848c04 --- /dev/null +++ b/airbyte-integrations/connectors/source-repairshopr/manifest.yaml @@ -0,0 +1,2554 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Repairshopr is a CRM and an integrated marketing platform. + + With this connector we can extract data from various streams such as customers + , invoices and payments. + + Docs : https://api-docs.repairshopr.com/#/ + +check: + type: CheckStream + stream_names: + - appointment types + +definitions: + streams: + appointment types: + type: DeclarativeStream + name: appointment types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: appointment_types + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - appointment_types + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/appointment types" + appointments: + type: DeclarativeStream + name: appointments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: appointments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - appointments + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/appointments" + customer assets: + type: DeclarativeStream + name: customer assets + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: customer_assets + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - assets + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customer assets" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - contacts + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + contracts: + type: DeclarativeStream + name: contracts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: contracts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - contracts + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contracts" + customers: + type: DeclarativeStream + name: customers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: customers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - customers + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers" + estimates: + type: DeclarativeStream + name: estimates + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: estimates + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - estimates + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/estimates" + invoices: + type: DeclarativeStream + name: invoices + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: invoices + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - invoices + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/invoices" + items: + type: DeclarativeStream + name: items + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: items + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/items" + line items: + type: DeclarativeStream + name: line items + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: line_items + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - line_items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/line items" + leads: + type: DeclarativeStream + name: leads + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: leads + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - leads + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/leads" + payments: + type: DeclarativeStream + name: payments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: payments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - payments + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/payments" + products: + type: DeclarativeStream + name: products + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: products + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - products + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + tickets: + type: DeclarativeStream + name: tickets + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: tickets + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - tickets + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tickets" + base_requester: + type: HttpRequester + url_base: https://{{ config['subdomain'] }}.repairshopr.com/api/v1/ + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: Authorization + inject_into: header + +streams: + - $ref: "#/definitions/streams/appointment types" + - $ref: "#/definitions/streams/appointments" + - $ref: "#/definitions/streams/customer assets" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/contracts" + - $ref: "#/definitions/streams/customers" + - $ref: "#/definitions/streams/estimates" + - $ref: "#/definitions/streams/invoices" + - $ref: "#/definitions/streams/items" + - $ref: "#/definitions/streams/line items" + - $ref: "#/definitions/streams/leads" + - $ref: "#/definitions/streams/payments" + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/tickets" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - subdomain + properties: + api_key: + type: string + order: 0 + title: API Key + airbyte_secret: true + subdomain: + type: string + title: subdomain + order: 1 + additionalProperties: true + +metadata: + autoImportSchema: + appointment types: true + appointments: true + customer assets: true + contacts: true + contracts: true + customers: true + estimates: true + invoices: true + items: true + line items: true + leads: true + payments: true + products: true + tickets: true + testedStreams: + appointment types: + streamHash: 9bd524cc4dec30ae9e0026d0a319906a1f104d22 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + appointments: + streamHash: 660796a6de6114f11bc3c833bd779ba5e1f3a771 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + customer assets: + streamHash: 58d5d6723004c6aebc2695a6c53347925a79de1a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contacts: + streamHash: 6523837fc9e9204e11daeb17ca0c4c1e6022af48 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contracts: + streamHash: 993bdf7daa2bd1f1432fc1d12391de91ac70cad4 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + customers: + streamHash: ffff51cb1124e6aecf0cfb9f9e6a48e6a942a792 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + estimates: + streamHash: 6432c3ec23ae8bd8fa2a256ce7b2e7270284c4a2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + invoices: + streamHash: 7605e6bf794b79ae578cdf72884bb414bd5728cf + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + items: + streamHash: 04ac1d3ee76b42c5dc0cec48939997e3a3881419 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + line items: + streamHash: f7a8f45509fcb692f708e03fe8b8eeb18aada5d5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + leads: + streamHash: bd61222bca09f154bc2537c02b63bd8294c8a906 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + payments: + streamHash: 191598f1f67454557dc9c6a0c724428d77c06ebc + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + products: + streamHash: 571aa7b8a3919b9fc116b803ed6ef1b95beaaf16 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tickets: + streamHash: 8ce78432e0fdfa48d0468fc650faa2fbc5ffd0f4 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + appointment types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account_id: + type: + - number + - "null" + created_at: + type: + - string + - "null" + email_instructions: + type: + - string + - "null" + id: + type: number + location_hard_code: + type: + - string + - "null" + location_type: + type: + - string + - "null" + name: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + appointments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + all_day: + type: + - boolean + - "null" + appointment_location_type: + type: + - string + - "null" + created_at: + type: + - string + - "null" + customer: + type: + - object + - "null" + properties: + account_id: + type: + - number + - "null" + address1: + type: + - string + - "null" + address2: + type: + - string + - "null" + city: + type: + - string + - "null" + created_at: + type: + - string + - "null" + customer_id: + type: + - number + - "null" + email: + type: + - string + - "null" + extension: + type: + - string + - "null" + id: + type: + - number + - "null" + mobile: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + opt_out: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + processed_mobile: + type: + - string + - "null" + processed_phone: + type: + - string + - "null" + properties: + type: + - object + - "null" + properties: + direct_report: + type: + - string + - "null" + notification_billing: + type: + - string + - "null" + notification_marketing: + type: + - string + - "null" + notification_reports: + type: + - string + - "null" + title: + type: + - string + - "null" + since_updated_at: + type: + - string + - "null" + state: + type: + - string + - "null" + ticket_matching_emails: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + zip: + type: + - string + - "null" + duration: + type: + - number + - "null" + end_at: + type: + - string + - "null" + id: + type: number + location: + type: + - string + - "null" + start_at: + type: + - string + - "null" + start_at_label: + type: + - string + - "null" + summary: + type: + - string + - "null" + ticket: + type: + - object + - "null" + properties: + billing_status: + type: + - string + - "null" + child: + type: + - boolean + - "null" + comments: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + body: + type: + - string + - "null" + created_at: + type: + - string + - "null" + hidden: + type: + - boolean + - "null" + id: + type: + - number + - "null" + subject: + type: + - string + - "null" + tech: + type: + - string + - "null" + ticket_id: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + user_id: + type: + - number + - "null" + contact_fullname: + type: + - string + - "null" + created_at: + type: + - string + - "null" + creator_name_or_email: + type: + - string + - "null" + customer_business_then_name: + type: + - string + - "null" + customer_id: + type: + - number + - "null" + customer_reply: + type: + - boolean + - "null" + due_date: + type: + - string + - "null" + id: + type: + - number + - "null" + number: + type: + - number + - "null" + parent: + type: + - boolean + - "null" + priority: + type: + - string + - "null" + problem_type: + type: + - string + - "null" + properties: + type: + - object + - "null" + recurring: + type: + - boolean + - "null" + status: + type: + - string + - "null" + subject: + type: + - string + - "null" + tag_list: + type: + - array + - "null" + items: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + ticket_id: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + required: + - id + customer assets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + asset_serial: + type: + - string + - "null" + asset_type: + type: + - string + - "null" + created_at: + type: + - string + - "null" + customer: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + address_2: + type: + - string + - "null" + business_and_full_name: + type: + - string + - "null" + business_name: + type: + - string + - "null" + business_then_name: + type: + - string + - "null" + city: + type: + - string + - "null" + created_at: + type: + - string + - "null" + disabled: + type: + - boolean + - "null" + email: + type: + - string + - "null" + firstname: + type: + - string + - "null" + fullname: + type: + - string + - "null" + get_sms: + type: + - boolean + - "null" + id: + type: + - number + - "null" + invoice_cc_emails: + type: + - string + - "null" + lastname: + type: + - string + - "null" + mobile: + type: + - string + - "null" + no_email: + type: + - boolean + - "null" + notification_email: + type: + - string + - "null" + online_profile_url: + type: + - string + - "null" + opt_out: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + properties: + type: + - object + - "null" + properties: + notification_billing: + type: + - string + - "null" + notification_marketing: + type: + - string + - "null" + notification_reports: + type: + - string + - "null" + referred_by: + type: + - string + - "null" + state: + type: + - string + - "null" + tax_rate_id: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + zip: + type: + - string + - "null" + customer_id: + type: + - number + - "null" + device_info: + type: + - object + - "null" + properties: + snmp_config: + type: + - object + - "null" + properties: + version: + type: + - number + - "null" + community: + type: + - string + - "null" + enabled: + type: + - boolean + - "null" + port: + type: + - number + - "null" + has_live_chat: + type: + - boolean + - "null" + id: + type: number + name: + type: + - string + - "null" + properties: + type: + - object + - "null" + properties: + Make: + type: + - string + - "null" + Model: + type: + - string + - "null" + Service Tag: + type: + - string + - "null" + rmm_links: + type: + - array + - "null" + rmm_store: + type: + - object + - "null" + properties: + account_id: + type: + - number + - "null" + asset_id: + type: + - number + - "null" + created_at: + type: + - string + - "null" + emsisoft: + type: + - object + - "null" + general: + type: + - object + - "null" + id: + type: + - number + - "null" + triggers: + type: + - object + - "null" + properties: + agent_offline_triggered: + type: + - string + - "null" + app_crash_triggered: + type: + - string + - "null" + bsod_triggered: + type: + - string + - "null" + defrag_triggered: + type: + - string + - "null" + device_manager_triggered: + type: + - string + - "null" + firewall_triggered: + type: + - string + - "null" + low_hd_space_triggered: + type: + - string + - "null" + no_av_triggered: + type: + - string + - "null" + smart_failure_triggered: + type: + - string + - "null" + time_triggered: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + windows_updates: + type: + - object + - "null" + since_updated_at: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account_id: + type: + - number + - "null" + address1: + type: + - string + - "null" + address2: + type: + - string + - "null" + city: + type: + - string + - "null" + created_at: + type: + - string + - "null" + customer_id: + type: + - number + - "null" + email: + type: + - string + - "null" + extension: + type: + - string + - "null" + id: + type: number + mobile: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + opt_out: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + processed_mobile: + type: + - string + - "null" + processed_phone: + type: + - string + - "null" + properties: + type: + - object + - "null" + properties: + direct_report: + type: + - string + - "null" + notification_billing: + type: + - string + - "null" + notification_marketing: + type: + - string + - "null" + notification_reports: + type: + - string + - "null" + title: + type: + - string + - "null" + since_updated_at: + type: + - string + - "null" + state: + type: + - string + - "null" + ticket_matching_emails: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + zip: + type: + - string + - "null" + required: + - id + contracts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + account_id: + type: + - number + - "null" + apply_to_all: + type: + - boolean + - "null" + contract_amount: + type: + - string + - "null" + created_at: + type: + - string + - "null" + customer_id: + type: + - number + - "null" + end_date: + type: + - string + - "null" + id: + type: number + likelihood: + type: + - number + - "null" + name: + type: + - string + - "null" + primary_contact: + type: + - string + - "null" + start_date: + type: + - string + - "null" + status: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + customers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address: + type: + - string + - "null" + address_2: + type: + - string + - "null" + business_and_full_name: + type: + - string + - "null" + business_name: + type: + - string + - "null" + business_then_name: + type: + - string + - "null" + city: + type: + - string + - "null" + contacts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + account_id: + type: + - number + - "null" + address1: + type: + - string + - "null" + address2: + type: + - string + - "null" + city: + type: + - string + - "null" + created_at: + type: + - string + - "null" + customer_id: + type: + - number + - "null" + email: + type: + - string + - "null" + extension: + type: + - string + - "null" + id: + type: + - number + - "null" + mobile: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + opt_out: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + processed_mobile: + type: + - string + - "null" + processed_phone: + type: + - string + - "null" + properties: + type: + - object + - "null" + properties: + direct_report: + type: + - string + - "null" + notification_billing: + type: + - string + - "null" + notification_marketing: + type: + - string + - "null" + notification_reports: + type: + - string + - "null" + title: + type: + - string + - "null" + since_updated_at: + type: + - string + - "null" + state: + type: + - string + - "null" + ticket_matching_emails: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + zip: + type: + - string + - "null" + created_at: + type: + - string + - "null" + disabled: + type: + - boolean + - "null" + email: + type: + - string + - "null" + firstname: + type: + - string + - "null" + fullname: + type: + - string + - "null" + get_sms: + type: + - boolean + - "null" + id: + type: number + invoice_cc_emails: + type: + - string + - "null" + lastname: + type: + - string + - "null" + mobile: + type: + - string + - "null" + no_email: + type: + - boolean + - "null" + notification_email: + type: + - string + - "null" + online_profile_url: + type: + - string + - "null" + opt_out: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + properties: + type: + - object + - "null" + properties: + notification_billing: + type: + - string + - "null" + notification_marketing: + type: + - string + - "null" + notification_reports: + type: + - string + - "null" + referred_by: + type: + - string + - "null" + state: + type: + - string + - "null" + tax_rate_id: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + zip: + type: + - string + - "null" + required: + - id + estimates: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + customer_business_then_name: + type: + - string + - "null" + customer_id: + type: + - number + - "null" + date: + type: + - string + - "null" + employee: + type: + - string + - "null" + id: + type: number + number: + type: + - string + - "null" + status: + type: + - string + - "null" + subtotal: + type: + - string + - "null" + tax: + type: + - string + - "null" + total: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + invoices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + contact_id: + type: + - number + - "null" + created_at: + type: + - string + - "null" + customer_business_then_name: + type: + - string + - "null" + customer_id: + type: + - number + - "null" + date: + type: + - string + - "null" + due_date: + type: + - string + - "null" + hardwarecost: + type: + - string + - "null" + id: + type: number + is_paid: + type: + - boolean + - "null" + number: + type: + - string + - "null" + po_number: + type: + - string + - "null" + subtotal: + type: + - string + - "null" + tax: + type: + - string + - "null" + tech_marked_paid: + type: + - boolean + - "null" + total: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + user_id: + type: + - number + - "null" + verified_paid: + type: + - boolean + - "null" + required: + - id + items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + account_id: + type: + - number + - "null" + converted: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + id: + type: number + invoice_id: + type: + - number + - "null" + logistic_state: + type: + - string + - "null" + notes: + type: + - string + - "null" + orderedon: + type: + - string + - "null" + parturl: + type: + - string + - "null" + price: + type: + - string + - "null" + quantity: + type: + - number + - "null" + requestedon: + type: + - string + - "null" + retail_cents: + type: + - number + - "null" + round_trip: + type: + - boolean + - "null" + shipping: + type: + - string + - "null" + taxable: + type: + - boolean + - "null" + ticket_id: + type: + - number + - "null" + ticketnum: + type: + - number + - "null" + trackingnum: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + user_id: + type: + - number + - "null" + required: + - id + line items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + cost: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: number + invoice_id: + type: + - number + - "null" + item: + type: + - string + - "null" + name: + type: + - string + - "null" + position: + type: + - number + - "null" + price: + type: + - string + - "null" + product_category: + type: + - string + - "null" + quantity: + type: + - string + - "null" + since_updated_at: + type: + - string + - "null" + taxable: + type: + - boolean + - "null" + updated_at: + type: + - string + - "null" + required: + - id + leads: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address: + type: + - string + - "null" + business_then_name: + type: + - string + - "null" + city: + type: + - string + - "null" + created_at: + type: + - string + - "null" + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + has_attachments: + type: + - boolean + - "null" + id: + type: number + last_name: + type: + - string + - "null" + message_read: + type: + - boolean + - "null" + mobile: + type: + - string + - "null" + phone: + type: + - string + - "null" + state: + type: + - string + - "null" + status: + type: + - string + - "null" + ticket_description: + type: + - string + - "null" + ticket_problem_type: + type: + - string + - "null" + ticket_subject: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + zip: + type: + - string + - "null" + required: + - id + payments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + applied_at: + type: + - string + - "null" + created_at: + type: + - string + - "null" + customer: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + address_2: + type: + - string + - "null" + business_and_full_name: + type: + - string + - "null" + business_name: + type: + - string + - "null" + business_then_name: + type: + - string + - "null" + city: + type: + - string + - "null" + contacts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + account_id: + type: + - number + - "null" + address1: + type: + - string + - "null" + address2: + type: + - string + - "null" + city: + type: + - string + - "null" + created_at: + type: + - string + - "null" + customer_id: + type: + - number + - "null" + email: + type: + - string + - "null" + extension: + type: + - string + - "null" + id: + type: + - number + - "null" + mobile: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + opt_out: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + processed_mobile: + type: + - string + - "null" + processed_phone: + type: + - string + - "null" + properties: + type: + - object + - "null" + properties: + direct_report: + type: + - string + - "null" + notification_billing: + type: + - string + - "null" + notification_marketing: + type: + - string + - "null" + notification_reports: + type: + - string + - "null" + title: + type: + - string + - "null" + since_updated_at: + type: + - string + - "null" + state: + type: + - string + - "null" + ticket_matching_emails: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + zip: + type: + - string + - "null" + created_at: + type: + - string + - "null" + disabled: + type: + - boolean + - "null" + email: + type: + - string + - "null" + firstname: + type: + - string + - "null" + fullname: + type: + - string + - "null" + get_sms: + type: + - boolean + - "null" + id: + type: + - number + - "null" + invoice_cc_emails: + type: + - string + - "null" + lastname: + type: + - string + - "null" + mobile: + type: + - string + - "null" + no_email: + type: + - boolean + - "null" + notification_email: + type: + - string + - "null" + online_profile_url: + type: + - string + - "null" + opt_out: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + properties: + type: + - object + - "null" + properties: + notification_billing: + type: + - string + - "null" + notification_marketing: + type: + - string + - "null" + notification_reports: + type: + - string + - "null" + referred_by: + type: + - string + - "null" + state: + type: + - string + - "null" + tax_rate_id: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + zip: + type: + - string + - "null" + id: + type: number + invoice_ids: + type: + - array + - "null" + items: + type: + - number + - "null" + payment_amount: + type: + - number + - "null" + payment_method: + type: + - string + - "null" + ref_num: + type: + - string + - "null" + success: + type: + - boolean + - "null" + updated_at: + type: + - string + - "null" + required: + - id + products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + category_path: + type: + - string + - "null" + condition: + type: + - string + - "null" + desired_stock_level: + type: + - number + - "null" + disabled: + type: + - boolean + - "null" + id: + type: number + location_quantities: + type: + - array + - "null" + maintain_stock: + type: + - boolean + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + photos: + type: + - array + - "null" + physical_location: + type: + - string + - "null" + price_cost: + type: + - number + - "null" + price_retail: + type: + - number + - "null" + price_wholesale: + type: + - number + - "null" + product_category: + type: + - string + - "null" + quantity: + type: + - number + - "null" + reorder_at: + type: + - number + - "null" + serialized: + type: + - boolean + - "null" + since_updated_at: + type: + - string + - "null" + sort_order: + type: + - number + - "null" + taxable: + type: + - boolean + - "null" + upc_code: + type: + - string + - "null" + vendor_ids: + type: + - array + - "null" + warranty_template_id: + type: + - number + - "null" + required: + - id + tickets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + billing_status: + type: + - string + - "null" + child: + type: + - boolean + - "null" + comments: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + body: + type: + - string + - "null" + created_at: + type: + - string + - "null" + hidden: + type: + - boolean + - "null" + id: + type: + - number + - "null" + subject: + type: + - string + - "null" + tech: + type: + - string + - "null" + ticket_id: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + user_id: + type: + - number + - "null" + contact_fullname: + type: + - string + - "null" + created_at: + type: + - string + - "null" + creator_name_or_email: + type: + - string + - "null" + customer_business_then_name: + type: + - string + - "null" + customer_id: + type: + - number + - "null" + customer_reply: + type: + - boolean + - "null" + due_date: + type: + - string + - "null" + id: + type: number + number: + type: + - number + - "null" + parent: + type: + - boolean + - "null" + priority: + type: + - string + - "null" + problem_type: + type: + - string + - "null" + properties: + type: + - object + - "null" + recurring: + type: + - boolean + - "null" + status: + type: + - string + - "null" + subject: + type: + - string + - "null" + tag_list: + type: + - array + - "null" + items: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-repairshopr/metadata.yaml b/airbyte-integrations/connectors/source-repairshopr/metadata.yaml new file mode 100644 index 000000000000..011fe142811c --- /dev/null +++ b/airbyte-integrations/connectors/source-repairshopr/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "https://*.repairshopr.com/api/v1/" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-repairshopr + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: d12ba86d-e393-4269-a6b7-4eddcba98eb4 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-repairshopr + githubIssueLabel: source-repairshopr + icon: icon.svg + license: MIT + name: Repairshopr + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/repairshopr + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-reply-io/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-reply-io/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-reply-io/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-reply-io/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-reply-io/metadata.yaml b/airbyte-integrations/connectors/source-reply-io/metadata.yaml index b3ab16e3f830..1cda8853b1f6 100644 --- a/airbyte-integrations/connectors/source-reply-io/metadata.yaml +++ b/airbyte-integrations/connectors/source-reply-io/metadata.yaml @@ -12,11 +12,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 8cc6537e-f8a6-423c-b960-e927af76116e - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-reply-io githubIssueLabel: source-reply-io icon: reply-io.svg diff --git a/airbyte-integrations/connectors/source-retently/README.md b/airbyte-integrations/connectors/source-retently/README.md index f43e8d7db841..f08ac608277f 100644 --- a/airbyte-integrations/connectors/source-retently/README.md +++ b/airbyte-integrations/connectors/source-retently/README.md @@ -1,49 +1,22 @@ # Retently source connector -This is the repository for the Retently source connector, written in Python. -For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.com/integrations/sources/retently). +This directory contains the manifest-only connector for `source-retently`. +This _manifest-only_ connector is not a Python package on its own, as it runs inside of the base `source-declarative-manifest` image. -## Local development - -### Prerequisites - -- Python (~=3.9) -- Poetry (~=1.7) - installation instructions [here](https://python-poetry.org/docs/#installation) - -### Installing the connector - -From this connector directory, run: - -```bash -poetry install --with dev -``` - -### Create credentials +For information about how to configure and use this connector within Airbyte, see [the connector's full documentation](https://docs.airbyte.com/integrations/sources/retently). -**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/retently) -to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_retently/spec.yaml` file. -Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. -See `sample_files/sample_config.json` for a sample config file. - -### Locally running the connector - -``` -poetry run source-retently spec -poetry run source-retently check --config secrets/config.json -poetry run source-retently discover --config secrets/config.json -poetry run source-retently read --config secrets/config.json --catalog sample_files/configured_catalog.json -``` +## Local development -### Running unit tests +We recommend using the Connector Builder to edit this connector. +Using either Airbyte Cloud or your local Airbyte OSS instance, navigate to the **Builder** tab and select **Import a YAML**. +Then select the connector's `manifest.yaml` file to load the connector into the Builder. You're now ready to make changes to the connector! -To run unit tests locally, from the connector directory run: - -``` -poetry run pytest unit_tests -``` +If you prefer to develop locally, you can follow the instructions below. ### Building the docker image +You can build any manifest-only connector with `airbyte-ci`: + 1. Install [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md) 2. Run the following command to build the docker image: @@ -53,18 +26,24 @@ airbyte-ci connectors --name=source-retently build An image will be available on your host with the tag `airbyte/source-retently:dev`. +### Creating credentials + +**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/retently) +to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `spec` object in the connector's `manifest.yaml` file. +Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. + ### Running as a docker container -Then run any of the connector commands as follows: +Then run any of the standard source connector commands: -``` +```bash docker run --rm airbyte/source-retently:dev spec docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-retently:dev check --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-retently:dev discover --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-retently:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json ``` -### Running our CI test suite +### Running the CI test suite You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): @@ -72,33 +51,15 @@ You can run our full test suite locally using [`airbyte-ci`](https://github.com/ airbyte-ci connectors --name=source-retently test ``` -### Customizing acceptance Tests - -Customize `acceptance-test-config.yml` file to configure acceptance tests. See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) for more information. -If your connector requires to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py. - -### Dependency Management - -All of your dependencies should be managed via Poetry. -To add a new dependency, run: - -```bash -poetry add -``` - -Please commit the changes to `pyproject.toml` and `poetry.lock` files. - ## Publishing a new version of the connector -You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what? - -1. Make sure your changes are passing our test suite: `airbyte-ci connectors --name=source-retently test` -2. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): - - bump the `dockerImageTag` value in in `metadata.yaml` - - bump the `version` value in `pyproject.toml` -3. Make sure the `metadata.yaml` content is up to date. +If you want to contribute changes to `source-retently`, here's how you can do that: +1. Make your changes locally, or load the connector's manifest into Connector Builder and make changes there. +2. Make sure your changes are passing our test suite with `airbyte-ci connectors --name=source-retently test` +3. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): + - bump the `dockerImageTag` value in in `metadata.yaml` 4. Make sure the connector documentation and its changelog is up to date (`docs/integrations/sources/retently.md`). 5. Create a Pull Request: use [our PR naming conventions](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#pull-request-title-convention). 6. Pat yourself on the back for being an awesome contributor. 7. Someone from Airbyte will take a look at your PR and iterate with you to merge it into master. -8. Once your PR is merged, the new version of the connector will be automatically published to Docker Hub and our connector registry. +8. Once your PR is merged, the new version of the connector will be automatically published to Docker Hub and our connector registry. \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-retently/__init__.py b/airbyte-integrations/connectors/source-retently/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-integrations/connectors/source-retently/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-integrations/connectors/source-retently/acceptance-test-config.yml b/airbyte-integrations/connectors/source-retently/acceptance-test-config.yml index a6f87e59bebf..abad282d14c7 100644 --- a/airbyte-integrations/connectors/source-retently/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-retently/acceptance-test-config.yml @@ -4,7 +4,7 @@ connector_image: airbyte/source-retently:dev acceptance_tests: spec: tests: - - spec_path: "source_retently/spec.yaml" + - spec_path: "manifest.yaml" connection: tests: - config_path: "secrets/config.json" @@ -22,6 +22,7 @@ acceptance_tests: configured_catalog_path: "integration_tests/configured_catalog.json" empty_streams: - name: templates + - name: outbox incremental: bypass_reason: "This connector does not implement incremental sync" full_refresh: diff --git a/airbyte-integrations/connectors/source-retently/source_retently/components.py b/airbyte-integrations/connectors/source-retently/components.py similarity index 100% rename from airbyte-integrations/connectors/source-retently/source_retently/components.py rename to airbyte-integrations/connectors/source-retently/components.py diff --git a/airbyte-integrations/connectors/source-retently/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-retently/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-retently/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-retently/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-retently/main.py b/airbyte-integrations/connectors/source-retently/main.py deleted file mode 100644 index dec9d2267e7b..000000000000 --- a/airbyte-integrations/connectors/source-retently/main.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from source_retently.run import run - -if __name__ == "__main__": - run() diff --git a/airbyte-integrations/connectors/source-retently/manifest.yaml b/airbyte-integrations/connectors/source-retently/manifest.yaml new file mode 100644 index 000000000000..83759cd94db7 --- /dev/null +++ b/airbyte-integrations/connectors/source-retently/manifest.yaml @@ -0,0 +1,1078 @@ +version: 5.15.0 + +type: DeclarativeSource + +check: + type: CheckStream + stream_names: + - customers + +definitions: + streams: + campaigns: + type: DeclarativeStream + name: campaigns + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: campaigns + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - campaigns + record_filter: + type: RecordFilter + condition: >- + {{ record['id'] in config['survey_ids'] if config['survey_ids'] + else true}} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/campaigns" + companies: + type: DeclarativeStream + name: companies + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: companies + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - companies + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + page_size: 20 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/companies" + customers: + type: DeclarativeStream + name: customers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: nps/customers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - subscribers + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + page_size: 20 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers" + feedback: + type: DeclarativeStream + name: feedback + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: feedback + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - responses + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + page_size: 10 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/feedback" + outbox: + type: DeclarativeStream + name: outbox + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: nps/outbox + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - surveys + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + page_size: 20 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/outbox" + reports: + type: DeclarativeStream + name: reports + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: reports + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/reports" + nps: + type: DeclarativeStream + name: nps + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: nps/score + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/nps" + templates: + type: DeclarativeStream + name: templates + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: templates + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + page_size: 20 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/templates" + base_requester: + type: HttpRequester + url_base: https://app.retently.com/api/v2/ + authenticator: + type: CustomAuthenticator + class_name: source_declarative_manifest.components.AuthenticatorRetently + api_auth: + type: ApiKeyAuthenticator + header: Authorization + api_token: api_key={{ config['credentials']['api_key'] }} + oauth: + type: OAuthAuthenticator + token_refresh_endpoint: https://app.retently.com/api/oauth/token + client_id: "{{ config['credentials']['client_id'] }}" + client_secret: "{{ config['credentials']['client_secret'] }}" + refresh_token: "{{ config['credentials']['refresh_token'] }}" + +streams: + - $ref: "#/definitions/streams/campaigns" + - $ref: "#/definitions/streams/companies" + - $ref: "#/definitions/streams/customers" + - $ref: "#/definitions/streams/feedback" + - $ref: "#/definitions/streams/outbox" + - $ref: "#/definitions/streams/reports" + - $ref: "#/definitions/streams/nps" + - $ref: "#/definitions/streams/templates" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: [] + properties: + credentials: + type: object + description: Choose how to authenticate to Retently + title: Authentication Mechanism + oneOf: + - type: object + title: Authenticate via Retently (OAuth) + required: + - client_id + - client_secret + - refresh_token + additionalProperties: true + properties: + auth_type: + type: string + const: Client + order: 0 + client_id: + type: string + description: The Client ID of your Retently developer application. + title: Client ID + client_secret: + type: string + description: The Client Secret of your Retently developer application. + title: Client Secret + airbyte_secret: true + refresh_token: + type: string + description: >- + Retently Refresh Token which can be used to fetch new Bearer + Tokens when the current one expires. + title: Refresh Token + airbyte_secret: true + - type: object + title: Authenticate with API Token + required: + - api_key + additionalProperties: true + properties: + auth_type: + type: string + const: Token + order: 0 + api_key: + type: string + description: >- + Retently API Token. See the docs + for more information on how to obtain this key. + title: API Token + airbyte_secret: true + order: 0 + additionalProperties: true + +schemas: + campaigns: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: The type of the campaign (e.g., feedback request, promotional offer). + channel: + type: + - "null" + - string + description: >- + The communication channel used for the campaign (e.g., email, SMS, + in-app push notification). + id: + type: + - "null" + - string + description: The unique identifier of the campaign. + isActive: + type: + - "null" + - boolean + description: Indicates whether the campaign is currently active or not. + metric: + type: + - "null" + - string + description: The metric associated with the campaign (e.g., NPS score, CSAT score). + name: + type: + - "null" + - string + description: The name or title of the campaign. + templateId: + type: + - "null" + - string + description: The ID of the template used for the campaign. + companies: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + companyName: + type: + - "null" + - string + description: The name of the company. + contactsCount: + type: + - "null" + - number + description: The number of contacts associated with the company. + createdDate: + type: + - "null" + - string + description: The date and time when the company was created. + format: yyyy-MM-dd'T'HH:mm:ss.SSSZ + cxMetrics: + type: + - "null" + - object + description: Various customer experience metrics associated with the company. + additionalProperties: true + properties: + CES: + type: + - "null" + - number + description: Customer Effort Score for the company. + CSAT: + type: + - "null" + - number + description: Customer Satisfaction Score for the company. + NPS: + type: + - "null" + - number + description: Net Promoter Score for the company. + STAR: + type: + - "null" + - number + description: STAR rating for the company. + domain: + type: + - "null" + - string + description: The domain of the company. + id: + type: + - "null" + - string + description: Unique identifier for the company. + industryName: + type: + - "null" + - string + description: The industry to which the company belongs. + tags: + type: array + description: Tags associated with the company. + items: + type: + - "null" + - string + description: Individual tag related to the company. + customers: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + companyId: + type: + - "null" + - string + description: The unique identifier of the company the customer belongs to. + companyName: + type: + - "null" + - string + description: The name of the company the customer belongs to. + createdDate: + type: + - "null" + - string + description: The date and time when the customer record was created. + format: yyyy-MM-dd'T'HH:mm:ss.SSSZ + email: + type: + - "null" + - string + description: The email address of the customer. + firstName: + type: + - "null" + - string + description: The first name of the customer. + id: + type: + - "null" + - string + description: The unique identifier of the customer. + lastName: + type: + - "null" + - string + description: The last name of the customer. + properties: + type: array + description: Custom properties associated with the customer. + items: + type: + - "null" + - object + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: The data type of the custom property. + label: + type: + - "null" + - string + description: The label for the custom property. + name: + type: + - "null" + - string + description: The name of the custom property. + value: + type: + - "null" + - string + description: The value of the custom property. + tags: + type: array + description: Tags associated with the customer. + items: + type: + - "null" + - string + feedback: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + additionalQuestions: + type: array + description: Additional questions included in the feedback form + items: + type: object + assigned: + type: + - "null" + - string + description: User or team assigned to handle the feedback + campaignId: + type: + - "null" + - string + description: ID of the campaign associated with the feedback + campaignName: + type: + - "null" + - string + description: Name of the campaign associated with the feedback + channel: + type: + - "null" + - string + description: Communication channel used to collect the feedback + checkbox: + type: + - "null" + - boolean + description: Checkbox responses provided in the feedback + city: + type: + - "null" + - string + description: City of the feedback provider + comment: + type: + - "null" + - string + description: Open text comment provided as feedback + companyId: + type: + - "null" + - string + description: ID of the company receiving the feedback + companyName: + type: + - "null" + - string + description: Name of the company receiving the feedback + country: + type: + - "null" + - string + description: Country of the feedback provider + createdDate: + type: + - "null" + - string + description: Date and time when the feedback was created + format: yyyy-MM-dd'T'HH:mm:ss.SSSZ + customProps: + type: array + description: Custom properties associated with the feedback + items: + type: object + customerId: + type: + - "null" + - string + description: ID of the customer providing the feedback + email: + type: + - "null" + - string + description: Email address of the feedback provider + feedbackTags: + type: array + description: Tags associated with the feedback + items: + type: string + feedbackTagsNew: + type: array + description: Additional tags for categorizing the feedback + items: + type: string + feedbackTopics: + type: array + description: Topics covered in the feedback + items: + type: object + firstName: + type: + - "null" + - string + description: First name of the feedback provider + id: + type: + - "null" + - string + description: Unique identifier for the feedback entry + isBogus: + type: + - "null" + - boolean + description: Flag indicating if the feedback is deemed bogus + jobTitle: + type: + - "null" + - string + description: Job title of the feedback provider + lastName: + type: + - "null" + - string + description: Last name of the feedback provider + metricsType: + type: + - "null" + - string + description: Type of metrics used in evaluating the feedback + notes: + type: array + description: Additional notes or comments on the feedback + items: + type: object + ratingCategory: + type: + - "null" + - string + description: Category under which the feedback is rated + resolved: + type: + - "null" + - boolean + description: Indicator of whether the feedback has been resolved or not + score: + type: + - "null" + - number + description: Numeric score assigned to the feedback + state: + type: + - "null" + - string + description: State or region of the feedback provider + status: + type: + - string + - "null" + description: Current status of the feedback entry + tags: + type: array + description: Various tags associated with the feedback entry + items: + type: string + outbox: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + additionalRecipients: + type: + - "null" + - array + description: List of additional email recipients for the outbox message. + items: + type: + - "null" + - object + additionalProperties: true + mandrillMessageId: + type: + - "null" + - string + attributes: + type: + - "null" + - object + description: Additional attributes associated with the outbox data. + additionalProperties: true + properties: + customProps: + type: + - "null" + - array + description: >- + Custom properties with label, name, type, and value for + customization. + items: + type: object + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: Type of the custom property data. + label: + type: + - "null" + - string + description: Label for the custom property. + name: + type: + - "null" + - string + description: Name of the custom property. + value: + type: + - "null" + - string + description: Value of the custom property data. + customerTags: + type: + - "null" + - array + description: Tags associated with the customer for segmentation. + items: + type: string + campaign: + type: + - "null" + - string + description: Name or identifier of the campaign associated with the outbox data. + campaignId: + type: + - "null" + - string + description: Unique ID of the campaign associated with the outbox data. + channel: + type: + - "null" + - string + description: Communication channel used for sending the outbox message. + companyId: + type: + - "null" + - string + description: Unique ID of the company sending the outbox message. + companyName: + type: + - "null" + - string + description: Name of the company sending the outbox message. + customerId: + type: + - "null" + - string + description: Unique ID of the customer who received the outbox message. + detailedStatus: + type: + - "null" + - object + description: >- + Detailed status information about the outbox message delivery and + interaction. + additionalProperties: true + properties: + hasFeedback: + type: + - "null" + - boolean + description: Indicates if there is feedback for the outbox message. + isBounced: + type: + - "null" + - boolean + description: Indicates if the message bounced. + isOpened: + type: + - "null" + - boolean + description: Indicates if the message was opened. + isOptedOut: + type: + - "null" + - boolean + description: Indicates if the recipient opted out of receiving messages. + isResponded: + type: + - "null" + - boolean + description: Indicates if the recipient responded to the message. + openedDate: + type: + - "null" + - string + description: Date and time when the message was opened. + format: yyyy-MM-dd'T'HH:mm:ss.SSSZ + respondedDate: + type: + - "null" + - string + description: Date and time when the recipient responded to the message. + format: yyyy-MM-dd'T'HH:mm:ss.SSSZ + email: + type: + - "null" + - string + description: Email address of the recipient who received the outbox message. + firstName: + type: + - "null" + - string + description: First name of the recipient who received the outbox message. + lastName: + type: + - "null" + - string + description: Last name of the recipient who received the outbox message. + mandrillMessageId: + type: + - "null" + - string + description: Unique ID assigned by Mandrill for the outbox message. + personTags: + type: + - array + - "null" + description: Tags associated with the individual recipient for segmentation. + items: + type: string + sentBy: + type: + - "null" + - string + description: Identifier of the user or system that sent the outbox message. + sentDate: + type: + - "null" + - string + description: Date and time when the outbox message was sent. + format: yyyy-MM-dd'T'HH:mm:ss.SSSZ + status: + type: + - "null" + - string + description: Overall status of the outbox message delivery. + subject: + type: + - "null" + - string + description: Subject of the outbox message. + surveyTemplateId: + type: + - "null" + - string + description: Unique ID of the survey template associated with the outbox message. + reports: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + campaignId: + type: + - "null" + - string + description: Unique identifier for the campaign. + deliveryStats: + type: + - "null" + - object + description: Statistics related to the delivery of the campaign emails. + additionalProperties: true + properties: + isBounced: + type: + - "null" + - number + description: Number of emails that bounced. + opened: + type: + - "null" + - number + description: Number of emails that were opened. + optedOut: + type: + - "null" + - number + description: Number of recipients who opted out of receiving further emails. + responded: + type: + - "null" + - number + description: Number of recipients who responded to the campaign. + totalCount: + type: + - "null" + - number + description: Total count of delivered emails. + last: + type: + - "null" + - object + description: Snapshot of the last feedback received from recipients. + additionalProperties: true + properties: + detractors: + type: + - "null" + - number + description: Number of detractors in the feedback. + passives: + type: + - "null" + - number + description: Number of passives in the feedback. + promoters: + type: + - "null" + - number + description: Number of promoters in the feedback. + score: + type: + - "null" + - number + description: >- + Overall feedback score calculated based on detractors, passives, + and promoters. + total: + type: + - "null" + - number + description: Total count of feedback received. + questionsStats: + type: + - "null" + - array + description: >- + Statistics related to specific questions asked in the campaign + feedback. + items: + type: object + description: Details of each question's statistics. + additionalProperties: true + trend: + type: + - "null" + - array + description: Trend analysis data over a specific period. + items: + type: + - "null" + - object + description: Details of the trend data for each day. + additionalProperties: true + properties: + day: + type: + - "null" + - string + description: Day for which the trend data is recorded. + detractors: + type: + - "null" + - number + description: Number of detractors on the specific day. + passives: + type: + - "null" + - number + description: Number of passives on the specific day. + promoters: + type: + - "null" + - number + description: Number of promoters on the specific day. + score: + type: + - "null" + - number + description: Overall feedback score calculated for the specific day. + total: + type: + - "null" + - number + description: Total feedback count on the specific day. + nps: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + detractors: + type: + - "null" + - integer + description: Array of responses falling under the detractor category. + detractorsCount: + type: + - "null" + - integer + description: Total count of detractor responses. + metricsType: + type: + - "null" + - string + description: Type of metrics being used (e.g., Net Promoter Score). + passives: + type: + - "null" + - integer + description: Array of responses falling under the passive category. + passivesCount: + type: + - "null" + - integer + description: Total count of passive responses. + promoters: + type: + - "null" + - integer + description: Array of responses falling under the promoter category. + promotersCount: + type: + - "null" + - integer + description: Total count of promoter responses. + score: + type: + - "null" + - integer + description: Calculated Net Promoter Score based on the responses. + scoreSum: + type: + - "null" + - integer + description: Sum of scores received from all responses. + totalResponses: + type: + - "null" + - integer + description: Total count of responses received for NPS calculation. + templates: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + channel: + type: + - "null" + - string + description: >- + The communication channel for the template (e.g., email, SMS, in-app + notification) + id: + type: + - "null" + - string + description: The unique identifier of the template + metric: + type: + - "null" + - string + description: >- + The key metric that this template is associated with (e.g., NPS score, + CSAT rating) + name: + type: + - "null" + - string + description: The name or title of the template diff --git a/airbyte-integrations/connectors/source-retently/metadata.yaml b/airbyte-integrations/connectors/source-retently/metadata.yaml index 7e092ebd40bf..0ba2ff830020 100644 --- a/airbyte-integrations/connectors/source-retently/metadata.yaml +++ b/airbyte-integrations/connectors/source-retently/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - "*" connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: db04ecd1-42e7-4115-9cec-95812905c626 - dockerImageTag: 0.2.24 + dockerImageTag: 0.3.4 dockerRepository: airbyte/source-retently documentationUrl: https://docs.airbyte.com/integrations/sources/retently githubIssueLabel: source-retently @@ -25,12 +25,12 @@ data: releaseStage: alpha remoteRegistries: pypi: - enabled: true + enabled: false packageName: airbyte-source-retently supportLevel: community tags: - - language:python - cdk:low-code + - language:manifest-only connectorTestSuitesOptions: - suite: liveTests testConnections: diff --git a/airbyte-integrations/connectors/source-retently/poetry.lock b/airbyte-integrations/connectors/source-retently/poetry.lock deleted file mode 100644 index a200e9d74ec8..000000000000 --- a/airbyte-integrations/connectors/source-retently/poetry.lock +++ /dev/null @@ -1,1065 +0,0 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. - -[[package]] -name = "airbyte-cdk" -version = "0.80.0" -description = "A framework for writing Airbyte Connectors." -optional = false -python-versions = "<4.0,>=3.9" -files = [ - {file = "airbyte_cdk-0.80.0-py3-none-any.whl", hash = "sha256:060e92323a73674fa4e9e2e4a1eb312b9b9d072c9bbe5fa28f54ef21cb4974f3"}, - {file = "airbyte_cdk-0.80.0.tar.gz", hash = "sha256:1383512a83917fecca5b24cea4c72aa5c561cf96dd464485fbcefda48fe574c5"}, -] - -[package.dependencies] -airbyte-protocol-models = "0.5.1" -backoff = "*" -cachetools = "*" -Deprecated = ">=1.2,<1.3" -dpath = ">=2.0.1,<2.1.0" -genson = "1.2.2" -isodate = ">=0.6.1,<0.7.0" -Jinja2 = ">=3.1.2,<3.2.0" -jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" -pendulum = "<3.0.0" -pydantic = ">=1.10.8,<2.0.0" -pyrate-limiter = ">=3.1.0,<3.2.0" -python-dateutil = "*" -PyYAML = ">=6.0.1,<7.0.0" -requests = "*" -requests_cache = "*" -wcmatch = "8.4" - -[package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.0.271)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] - -[[package]] -name = "airbyte-protocol-models" -version = "0.5.1" -description = "Declares the Airbyte Protocol." -optional = false -python-versions = ">=3.8" -files = [ - {file = "airbyte_protocol_models-0.5.1-py3-none-any.whl", hash = "sha256:dfe84e130e51ce2ae81a06d5aa36f6c5ce3152b9e36e6f0195fad6c3dab0927e"}, - {file = "airbyte_protocol_models-0.5.1.tar.gz", hash = "sha256:7c8b16c7c1c7956b1996052e40585a3a93b1e44cb509c4e97c1ee4fe507ea086"}, -] - -[package.dependencies] -pydantic = ">=1.9.2,<2.0.0" - -[[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, -] - -[[package]] -name = "attrs" -version = "24.2.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" -files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, -] - -[package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] - -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "bracex" -version = "2.5.post1" -description = "Bash style brace expander." -optional = false -python-versions = ">=3.8" -files = [ - {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, - {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, -] - -[[package]] -name = "cachetools" -version = "5.5.0" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, - {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, -] - -[[package]] -name = "cattrs" -version = "24.1.2" -description = "Composable complex class support for attrs and dataclasses." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, - {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, -] - -[package.dependencies] -attrs = ">=23.1.0" -exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} - -[package.extras] -bson = ["pymongo (>=4.4.0)"] -cbor2 = ["cbor2 (>=5.4.6)"] -msgpack = ["msgpack (>=1.0.5)"] -msgspec = ["msgspec (>=0.18.5)"] -orjson = ["orjson (>=3.9.2)"] -pyyaml = ["pyyaml (>=6.0)"] -tomlkit = ["tomlkit (>=0.11.8)"] -ujson = ["ujson (>=5.7.0)"] - -[[package]] -name = "certifi" -version = "2024.8.30" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.0" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -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 = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - -[[package]] -name = "dpath" -version = "2.0.8" -description = "Filesystem-like pathing and searching for dictionaries" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dpath-2.0.8-py3-none-any.whl", hash = "sha256:f92f595214dd93a00558d75d4b858beee519f4cffca87f02616ad6cd013f3436"}, - {file = "dpath-2.0.8.tar.gz", hash = "sha256:a3440157ebe80d0a3ad794f1b61c571bef125214800ffdb9afc9424e8250fe9b"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "genson" -version = "1.2.2" -description = "GenSON is a powerful, user-friendly JSON Schema generator." -optional = false -python-versions = "*" -files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, -] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isodate" -version = "0.6.1" -description = "An ISO 8601 date/time/duration parser and formatter" -optional = false -python-versions = "*" -files = [ - {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, - {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "jinja2" -version = "3.1.4" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "jsonref" -version = "0.2" -description = "An implementation of JSON Reference for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonref-0.2-py3-none-any.whl", hash = "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f"}, - {file = "jsonref-0.2.tar.gz", hash = "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697"}, -] - -[[package]] -name = "jsonschema" -version = "3.2.0" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, -] - -[package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" - -[package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] - -[[package]] -name = "markupsafe" -version = "3.0.2" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -files = [ - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, - {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, -] - -[[package]] -name = "packaging" -version = "24.1" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, -] - -[[package]] -name = "pendulum" -version = "2.1.2" -description = "Python datetimes made easy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, - {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, - {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, - {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, - {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, - {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, - {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, - {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, - {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, - {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, - {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, -] - -[package.dependencies] -python-dateutil = ">=2.6,<3.0" -pytzdata = ">=2020.1" - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] - -[[package]] -name = "pydantic" -version = "1.10.18" -description = "Data validation and settings management using python type hints" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, -] - -[package.dependencies] -typing-extensions = ">=4.2.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] - -[[package]] -name = "pyrate-limiter" -version = "3.1.1" -description = "Python Rate-Limiter using Leaky-Bucket Algorithm" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, - {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, -] - -[package.extras] -all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] -docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] - -[[package]] -name = "pyrsistent" -version = "0.20.0" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7"}, - {file = "pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee"}, - {file = "pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d"}, - {file = "pyrsistent-0.20.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win32.whl", hash = "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d"}, - {file = "pyrsistent-0.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win32.whl", hash = "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf"}, - {file = "pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b"}, - {file = "pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4"}, -] - -[[package]] -name = "pytest" -version = "6.2.5" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, -] - -[package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] - -[[package]] -name = "pytest-mock" -version = "3.14.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, -] - -[package.dependencies] -pytest = ">=6.2.5" - -[package.extras] -dev = ["pre-commit", "pytest-asyncio", "tox"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytzdata" -version = "2020.1" -description = "The Olson timezone database for Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, - {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-cache" -version = "1.2.1" -description = "A persistent cache for python requests" -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, - {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, -] - -[package.dependencies] -attrs = ">=21.2" -cattrs = ">=22.2" -platformdirs = ">=2.5" -requests = ">=2.22" -url-normalize = ">=1.4" -urllib3 = ">=1.25.5" - -[package.extras] -all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] -bson = ["bson (>=0.5)"] -docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] -dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] -json = ["ujson (>=5.4)"] -mongodb = ["pymongo (>=3)"] -redis = ["redis (>=3)"] -security = ["itsdangerous (>=2.0)"] -yaml = ["pyyaml (>=6.0.1)"] - -[[package]] -name = "requests-mock" -version = "1.12.1" -description = "Mock out responses from the requests package" -optional = false -python-versions = ">=3.5" -files = [ - {file = "requests-mock-1.12.1.tar.gz", hash = "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401"}, - {file = "requests_mock-1.12.1-py2.py3-none-any.whl", hash = "sha256:b1e37054004cdd5e56c84454cc7df12b25f90f382159087f4b6915aaeef39563"}, -] - -[package.dependencies] -requests = ">=2.22,<3" - -[package.extras] -fixture = ["fixtures"] - -[[package]] -name = "setuptools" -version = "75.2.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "url-normalize" -version = "1.4.3" -description = "URL normalization for Python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, - {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "urllib3" -version = "2.2.3" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "wcmatch" -version = "8.4" -description = "Wildcard/glob file name matcher." -optional = false -python-versions = ">=3.7" -files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, -] - -[package.dependencies] -bracex = ">=2.1.1" - -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "990042bd8aff2361370f7cea38b2dffbadb5bd28397a241166061ec2619f6426" diff --git a/airbyte-integrations/connectors/source-retently/pyproject.toml b/airbyte-integrations/connectors/source-retently/pyproject.toml deleted file mode 100644 index 0e3dd8627748..000000000000 --- a/airbyte-integrations/connectors/source-retently/pyproject.toml +++ /dev/null @@ -1,28 +0,0 @@ -[build-system] -requires = [ "poetry-core>=1.0.0",] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -version = "0.2.24" -name = "source-retently" -description = "Source implementation for Retently." -authors = [ "Airbyte ",] -license = "MIT" -readme = "README.md" -documentation = "https://docs.airbyte.com/integrations/sources/retently" -homepage = "https://airbyte.com" -repository = "https://github.com/airbytehq/airbyte" -[[tool.poetry.packages]] -include = "source_retently" - -[tool.poetry.dependencies] -python = "^3.9,<3.12" -airbyte-cdk = "0.80.0" - -[tool.poetry.scripts] -source-retently = "source_retently.run:run" - -[tool.poetry.group.dev.dependencies] -pytest-mock = "^3.6.1" -requests-mock = "^1.9.3" -pytest = "^6.2" diff --git a/airbyte-integrations/connectors/source-retently/source_retently/__init__.py b/airbyte-integrations/connectors/source-retently/source_retently/__init__.py deleted file mode 100644 index 5e67e6349bf7..000000000000 --- a/airbyte-integrations/connectors/source-retently/source_retently/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from .source import SourceRetently - -__all__ = ["SourceRetently"] diff --git a/airbyte-integrations/connectors/source-retently/source_retently/manifest.yaml b/airbyte-integrations/connectors/source-retently/source_retently/manifest.yaml deleted file mode 100644 index 0405aef94272..000000000000 --- a/airbyte-integrations/connectors/source-retently/source_retently/manifest.yaml +++ /dev/null @@ -1,952 +0,0 @@ -version: "0.29.0" - -definitions: - selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: ["data", "{{ parameters.path_extractor }}"] - selector_data: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: ["{{ parameters.path_extractor }}"] - - oauth_authenticator: - type: OAuthAuthenticator - token_refresh_endpoint: https://app.retently.com/api/oauth/token - client_id: "{{ config['credentials']['client_id'] }}" - client_secret: "{{ config['credentials']['client_secret'] }}" - refresh_token: "{{ config['credentials']['refresh_token'] }}" - api_authenticator: - type: ApiKeyAuthenticator - header: "Authorization" - api_token: "api_key={{ config['credentials']['api_key'] }}" - - requester: - type: HttpRequester - url_base: "https://app.retently.com/api/v2/" - http_method: "GET" - authenticator: - class_name: source_retently.components.AuthenticatorRetently - api_auth: "#/definitions/api_authenticator" - oauth: "#/definitions/oauth_authenticator" - - retriever: - type: SimpleRetriever - record_selector: - $ref: "#/definitions/selector" - paginator: - type: "DefaultPaginator" - pagination_strategy: - type: "PageIncrement" - page_size: 20 - start_from_page: 1 - page_token_option: - type: "RequestOption" - inject_into: "request_parameter" - field_name: "page" - requester: - $ref: "#/definitions/requester" - - base_stream: - type: DeclarativeStream - retriever: - $ref: "#/definitions/retriever" - - campaigns_stream: - $ref: "#/definitions/base_stream" - retriever: - $ref: "#/definitions/retriever" - record_selector: - $ref: "#/definitions/selector_data" - paginator: - type: NoPagination - name: "campaigns" - primary_key: "id" - $parameters: - path_extractor: "campaigns" - path: "campaigns" - - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - description: The unique identifier of the campaign. - type: - - "null" - - string - name: - description: The name or title of the campaign. - type: - - "null" - - string - isActive: - description: Indicates whether the campaign is currently active or not. - type: - - "null" - - boolean - templateId: - description: The ID of the template used for the campaign. - type: - - "null" - - string - metric: - description: - The metric associated with the campaign (e.g., NPS score, - CSAT score). - type: - - "null" - - string - type: - description: - The type of the campaign (e.g., feedback request, promotional - offer). - type: - - "null" - - string - channel: - description: - The communication channel used for the campaign (e.g., email, - SMS, in-app push notification). - type: - - "null" - - string - companies_stream: - $ref: "#/definitions/base_stream" - name: "companies" - primary_key: "id" - $parameters: - path_extractor: "companies" - path: "companies" - - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - description: Unique identifier for the company. - type: - - "null" - - string - createdDate: - description: The date and time when the company was created. - type: - - "null" - - string - format: yyyy-MM-dd'T'HH:mm:ss.SSSZ - domain: - description: The domain of the company. - type: - - "null" - - string - companyName: - description: The name of the company. - type: - - "null" - - string - industryName: - description: The industry to which the company belongs. - type: - - "null" - - string - tags: - description: Tags associated with the company. - type: array - items: - description: Individual tag related to the company. - type: - - "null" - - string - cxMetrics: - description: Various customer experience metrics associated with the company. - type: - - "null" - - object - additionalProperties: true - properties: - NPS: - description: Net Promoter Score for the company. - type: - - "null" - - number - CSAT: - description: Customer Satisfaction Score for the company. - type: - - "null" - - number - CES: - description: Customer Effort Score for the company. - type: - - "null" - - number - STAR: - description: STAR rating for the company. - type: - - "null" - - number - contactsCount: - description: The number of contacts associated with the company. - type: - - "null" - - number - customers_stream: - $ref: "#/definitions/base_stream" - name: "customers" - primary_key: "id" - $parameters: - path_extractor: "subscribers" - path: "nps/customers" - - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - description: The unique identifier of the customer. - type: - - "null" - - string - email: - description: The email address of the customer. - type: - - "null" - - string - firstName: - description: The first name of the customer. - type: - - "null" - - string - lastName: - description: The last name of the customer. - type: - - "null" - - string - companyName: - description: The name of the company the customer belongs to. - type: - - "null" - - string - companyId: - description: - The unique identifier of the company the customer belongs - to. - type: - - "null" - - string - tags: - description: Tags associated with the customer. - type: array - items: - type: - - "null" - - string - createdDate: - description: The date and time when the customer record was created. - type: - - "null" - - string - format: yyyy-MM-dd'T'HH:mm:ss.SSSZ - properties: - description: Custom properties associated with the customer. - type: array - items: - type: - - "null" - - object - additionalProperties: true - properties: - label: - description: The label for the custom property. - type: - - "null" - - string - name: - description: The name of the custom property. - type: - - "null" - - string - type: - description: The data type of the custom property. - type: - - "null" - - string - value: - description: The value of the custom property. - type: - - "null" - - string - feedback_stream: - $ref: "#/definitions/base_stream" - retriever: - $ref: "#/definitions/retriever" - paginator: - type: "DefaultPaginator" - pagination_strategy: - type: "PageIncrement" - page_size: 10 - start_from_page: 1 - page_token_option: - type: "RequestOption" - inject_into: "request_parameter" - field_name: "page" - name: "feedback" - primary_key: "id" - $parameters: - path_extractor: "responses" - path: "feedback" - - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - description: Unique identifier for the feedback entry - type: - - "null" - - string - customerId: - description: ID of the customer providing the feedback - type: - - "null" - - string - email: - description: Email address of the feedback provider - type: - - "null" - - string - firstName: - description: First name of the feedback provider - type: - - "null" - - string - lastName: - description: Last name of the feedback provider - type: - - "null" - - string - companyName: - description: Name of the company receiving the feedback - type: - - "null" - - string - companyId: - description: ID of the company receiving the feedback - type: - - "null" - - string - jobTitle: - description: Job title of the feedback provider - type: - - "null" - - string - country: - description: Country of the feedback provider - type: - - "null" - - string - state: - description: State or region of the feedback provider - type: - - "null" - - string - city: - description: City of the feedback provider - type: - - "null" - - string - tags: - description: Various tags associated with the feedback entry - type: array - items: - type: string - customProps: - description: Custom properties associated with the feedback - type: array - items: - type: object - campaignId: - description: ID of the campaign associated with the feedback - type: - - "null" - - string - campaignName: - description: Name of the campaign associated with the feedback - type: - - "null" - - string - createdDate: - description: Date and time when the feedback was created - type: - - "null" - - string - format: yyyy-MM-dd'T'HH:mm:ss.SSSZ - score: - description: Numeric score assigned to the feedback - type: - - "null" - - number - comment: - description: Open text comment provided as feedback - type: - - "null" - - string - checkbox: - description: Checkbox responses provided in the feedback - type: - - "null" - - boolean - additionalQuestions: - description: Additional questions included in the feedback form - type: array - items: - type: object - feedbackTopics: - description: Topics covered in the feedback - type: array - items: - type: object - feedbackTags: - description: Tags associated with the feedback - type: array - items: - type: string - feedbackTagsNew: - description: Additional tags for categorizing the feedback - type: array - items: - type: string - notes: - description: Additional notes or comments on the feedback - type: array - items: - type: object - status: - description: Current status of the feedback entry - type: - - string - - "null" - assigned: - description: User or team assigned to handle the feedback - type: - - "null" - - string - ratingCategory: - description: Category under which the feedback is rated - type: - - "null" - - string - resolved: - description: Indicator of whether the feedback has been resolved or not - type: - - "null" - - boolean - channel: - description: Communication channel used to collect the feedback - type: - - "null" - - string - metricsType: - description: Type of metrics used in evaluating the feedback - type: - - "null" - - string - isBogus: - description: Flag indicating if the feedback is deemed bogus - type: - - "null" - - boolean - outbox_stream: - $ref: "#/definitions/base_stream" - name: "outbox" - $parameters: - path_extractor: "surveys" - path: "nps/outbox" - - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - email: - description: Email address of the recipient who received the outbox message. - type: - - "null" - - string - customerId: - description: Unique ID of the customer who received the outbox message. - type: - - "null" - - string - firstName: - description: First name of the recipient who received the outbox message. - type: - - "null" - - string - lastName: - description: Last name of the recipient who received the outbox message. - type: - - "null" - - string - companyName: - description: Name of the company sending the outbox message. - type: - - "null" - - string - companyId: - description: Unique ID of the company sending the outbox message. - type: - - "null" - - string - sentDate: - description: Date and time when the outbox message was sent. - type: - - "null" - - string - format: yyyy-MM-dd'T'HH:mm:ss.SSSZ - channel: - description: Communication channel used for sending the outbox message. - type: - - "null" - - string - personTags: - description: Tags associated with the individual recipient for segmentation. - type: - - array - - "null" - items: - type: string - campaign: - description: - Name or identifier of the campaign associated with the outbox - data. - type: - - "null" - - string - campaignId: - description: Unique ID of the campaign associated with the outbox data. - type: - - "null" - - string - surveyTemplateId: - description: - Unique ID of the survey template associated with the outbox - message. - type: - - "null" - - string - subject: - description: Subject of the outbox message. - type: - - "null" - - string - sentBy: - description: Identifier of the user or system that sent the outbox message. - type: - - "null" - - string - status: - description: Overall status of the outbox message delivery. - type: - - "null" - - string - attributes: - description: Additional attributes associated with the outbox data. - type: - - "null" - - object - additionalProperties: true - properties: - customerTags: - description: Tags associated with the customer for segmentation. - type: - - "null" - - array - items: - type: string - customProps: - description: - Custom properties with label, name, type, and value for - customization. - type: - - "null" - - array - items: - type: object - additionalProperties: true - properties: - label: - description: Label for the custom property. - type: - - "null" - - string - name: - description: Name of the custom property. - type: - - "null" - - string - type: - description: Type of the custom property data. - type: - - "null" - - string - value: - description: Value of the custom property data. - type: - - "null" - - string - detailedStatus: - description: - Detailed status information about the outbox message delivery - and interaction. - type: - - "null" - - object - additionalProperties: true - properties: - isOpened: - description: Indicates if the message was opened. - type: - - "null" - - boolean - openedDate: - description: Date and time when the message was opened. - format: yyyy-MM-dd'T'HH:mm:ss.SSSZ - type: - - "null" - - string - isResponded: - description: Indicates if the recipient responded to the message. - type: - - "null" - - boolean - respondedDate: - description: Date and time when the recipient responded to the message. - format: yyyy-MM-dd'T'HH:mm:ss.SSSZ - type: - - "null" - - string - hasFeedback: - description: Indicates if there is feedback for the outbox message. - type: - - "null" - - boolean - isOptedOut: - description: Indicates if the recipient opted out of receiving messages. - type: - - "null" - - boolean - isBounced: - description: Indicates if the message bounced. - type: - - "null" - - boolean - mandrillMessageId: - description: Unique ID assigned by Mandrill for the outbox message. - type: - - "null" - - string - additionalRecipients: - description: List of additional email recipients for the outbox message. - type: - - "null" - - array - items: - type: - - "null" - - object - additionalProperties: true - mandrillMessageId: - type: - - "null" - - string - reports_stream: - $ref: "#/definitions/base_stream" - retriever: - $ref: "#/definitions/retriever" - record_selector: - $ref: "#/definitions/selector_data" - paginator: - type: NoPagination - name: "reports" - $parameters: - path_extractor: "data" - path: "reports" - - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - campaignId: - description: Unique identifier for the campaign. - type: - - "null" - - string - questionsStats: - description: - Statistics related to specific questions asked in the campaign - feedback. - type: - - "null" - - array - items: - description: Details of each question's statistics. - type: object - additionalProperties: true - trend: - description: Trend analysis data over a specific period. - type: - - "null" - - array - items: - description: Details of the trend data for each day. - type: - - "null" - - object - additionalProperties: true - properties: - day: - description: Day for which the trend data is recorded. - type: - - "null" - - string - promoters: - description: Number of promoters on the specific day. - type: - - "null" - - number - passives: - description: Number of passives on the specific day. - type: - - "null" - - number - detractors: - description: Number of detractors on the specific day. - type: - - "null" - - number - total: - description: Total feedback count on the specific day. - type: - - "null" - - number - score: - description: - Overall feedback score calculated for the specific - day. - type: - - "null" - - number - last: - description: Snapshot of the last feedback received from recipients. - type: - - "null" - - object - additionalProperties: true - properties: - promoters: - description: Number of promoters in the feedback. - type: - - "null" - - number - passives: - description: Number of passives in the feedback. - type: - - "null" - - number - detractors: - description: Number of detractors in the feedback. - type: - - "null" - - number - total: - description: Total count of feedback received. - type: - - "null" - - number - score: - description: - Overall feedback score calculated based on detractors, - passives, and promoters. - type: - - "null" - - number - deliveryStats: - description: Statistics related to the delivery of the campaign emails. - type: - - "null" - - object - additionalProperties: true - properties: - totalCount: - description: Total count of delivered emails. - type: - - "null" - - number - opened: - description: Number of emails that were opened. - type: - - "null" - - number - responded: - description: Number of recipients who responded to the campaign. - type: - - "null" - - number - optedOut: - description: - Number of recipients who opted out of receiving further - emails. - type: - - "null" - - number - isBounced: - description: Number of emails that bounced. - type: - - "null" - - number - nps_stream: - $ref: "#/definitions/base_stream" - retriever: - $ref: "#/definitions/retriever" - record_selector: - $ref: "#/definitions/selector_data" - paginator: - type: NoPagination - name: "nps" - $parameters: - path_extractor: "data" - path: "nps/score" - - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - score: - description: Calculated Net Promoter Score based on the responses. - type: - - "null" - - integer - scoreSum: - description: Sum of scores received from all responses. - type: - - "null" - - integer - metricsType: - description: Type of metrics being used (e.g., Net Promoter Score). - type: - - "null" - - string - promoters: - description: Array of responses falling under the promoter category. - type: - - "null" - - integer - passives: - description: Array of responses falling under the passive category. - type: - - "null" - - integer - detractors: - description: Array of responses falling under the detractor category. - type: - - "null" - - integer - promotersCount: - description: Total count of promoter responses. - type: - - "null" - - integer - passivesCount: - description: Total count of passive responses. - type: - - "null" - - integer - detractorsCount: - description: Total count of detractor responses. - type: - - "null" - - integer - totalResponses: - description: Total count of responses received for NPS calculation. - type: - - "null" - - integer - templates_stream: - $ref: "#/definitions/base_stream" - name: "templates" - retriever: - $ref: "#/definitions/retriever" - record_selector: - $ref: "#/definitions/selector_data" - primary_key: "id" - $parameters: - path_extractor: "data" - path: "templates" - - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - description: The unique identifier of the template - type: - - "null" - - string - name: - description: The name or title of the template - type: - - "null" - - string - channel: - description: - The communication channel for the template (e.g., email, - SMS, in-app notification) - type: - - "null" - - string - metric: - description: - The key metric that this template is associated with (e.g., - NPS score, CSAT rating) - type: - - "null" - - string -streams: - - "#/definitions/campaigns_stream" - - "#/definitions/companies_stream" - - "#/definitions/customers_stream" - - "#/definitions/feedback_stream" - - "#/definitions/outbox_stream" - - "#/definitions/reports_stream" - - "#/definitions/nps_stream" - - "#/definitions/templates_stream" - -check: - type: CheckStream - stream_names: - - "customers" diff --git a/airbyte-integrations/connectors/source-retently/source_retently/run.py b/airbyte-integrations/connectors/source-retently/source_retently/run.py deleted file mode 100644 index 4e0687b5c6a9..000000000000 --- a/airbyte-integrations/connectors/source-retently/source_retently/run.py +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import sys - -from airbyte_cdk.entrypoint import launch -from source_retently import SourceRetently - - -def run(): - source = SourceRetently() - launch(source, sys.argv[1:]) diff --git a/airbyte-integrations/connectors/source-retently/source_retently/source.py b/airbyte-integrations/connectors/source-retently/source_retently/source.py deleted file mode 100644 index 2443de44572a..000000000000 --- a/airbyte-integrations/connectors/source-retently/source_retently/source.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource - -""" -This file provides the necessary constructs to interpret a provided declarative YAML configuration file into -source connector. - -WARNING: Do not modify this file. -""" - - -# Declarative Source -class SourceRetently(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-retently/source_retently/spec.yaml b/airbyte-integrations/connectors/source-retently/source_retently/spec.yaml deleted file mode 100644 index 92b3bb578366..000000000000 --- a/airbyte-integrations/connectors/source-retently/source_retently/spec.yaml +++ /dev/null @@ -1,96 +0,0 @@ ---- -documentationUrl: https://docs.airbyte.com/integrations/sources/retently -connectionSpecification: - "$schema": http://json-schema.org/draft-07/schema# - title: Retently Api Spec - type: object - additionalProperties: true - properties: - credentials: - title: Authentication Mechanism - description: Choose how to authenticate to Retently - type: object - oneOf: - - type: object - title: Authenticate via Retently (OAuth) - required: - - client_id - - client_secret - - refresh_token - additionalProperties: true - properties: - auth_type: - type: string - const: Client - order: 0 - client_id: - title: Client ID - type: string - description: The Client ID of your Retently developer application. - client_secret: - title: Client Secret - type: string - description: The Client Secret of your Retently developer application. - airbyte_secret: true - refresh_token: - title: Refresh Token - type: string - description: - Retently Refresh Token which can be used to fetch new Bearer - Tokens when the current one expires. - airbyte_secret: true - - type: object - title: Authenticate with API Token - required: - - api_key - additionalProperties: true - properties: - auth_type: - type: string - const: Token - order: 0 - api_key: - title: API Token - description: - Retently API Token. See the docs - for more information on how to obtain this key. - type: string - airbyte_secret: true -advanced_auth: - auth_flow_type: oauth2.0 - predicate_key: - - credentials - - auth_type - predicate_value: Client - oauth_config_specification: - complete_oauth_output_specification: - type: object - additionalProperties: true - properties: - refresh_token: - type: string - path_in_connector_config: - - credentials - - refresh_token - complete_oauth_server_input_specification: - type: object - additionalProperties: true - properties: - client_id: - type: string - client_secret: - type: string - complete_oauth_server_output_specification: - type: object - additionalProperties: true - properties: - client_id: - type: string - path_in_connector_config: - - credentials - - client_id - client_secret: - type: string - path_in_connector_config: - - credentials - - client_secret diff --git a/airbyte-integrations/connectors/source-revenuecat/metadata.yaml b/airbyte-integrations/connectors/source-revenuecat/metadata.yaml index 34dc5b7163dd..67bd0817210d 100644 --- a/airbyte-integrations/connectors/source-revenuecat/metadata.yaml +++ b/airbyte-integrations/connectors/source-revenuecat/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-revenuecat connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.7.3@sha256:4c4a567211fbcdf42805f261020bf5be46454bfeba781a92d30fe414ef964212 + baseImage: docker.io/airbyte/source-declarative-manifest:6.9.2@sha256:ea8087899b36a891ce16e47035b10de8d52b0fb041b593b18e53ed2d699e3b46 connectorSubtype: api connectorType: source definitionId: d8b3b5d6-7b64-49f7-9e73-73a1da277cf2 - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.2 dockerRepository: airbyte/source-revenuecat githubIssueLabel: source-revenuecat icon: icon.svg diff --git a/airbyte-integrations/connectors/source-revolut-merchant/README.md b/airbyte-integrations/connectors/source-revolut-merchant/README.md new file mode 100644 index 000000000000..80e258841fc7 --- /dev/null +++ b/airbyte-integrations/connectors/source-revolut-merchant/README.md @@ -0,0 +1,44 @@ +# Revolut Merchant +This directory contains the manifest-only connector for `source-revolut-merchant`. + +This is the Revolut Merchant source that ingests data from the Revolut Merchant API. + +Revolut helps you spend, send, and save smarter https://www.revolut.com/ + +The Revolut Merchant account is a sub-account of your Revolut Business account. While a Business account is for managing your business finances, the Merchant account is dedicated to helping you accept online payments from your e-commerce customers. + +This source uses the Merchant API and has the orders, customers and location endpoints. In order to use this API, you must first create a Revolut account. +Log in to your Revolut Business account: Access the Revolut Business log in page and enter your credentials. +Navigate to Merchant API settings: Once logged in, access the Merchant API settings page by clicking your profile icon in the top left corner, then selecting APIs > Merchant API. +Here you can access your Production API keys (Public, Secret) specific to your Merchant account. +Get API keys: If you're visiting this page for the first time, you'll need to initiate the process by clicking the Get started button. To generate your Production API Secret key, click the Generate button. +You can find more about the API here https://developer.revolut.com/docs/merchant/merchant-api + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-revolut-merchant:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-revolut-merchant build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-revolut-merchant test +``` + diff --git a/airbyte-integrations/connectors/source-revolut-merchant/acceptance-test-config.yml b/airbyte-integrations/connectors/source-revolut-merchant/acceptance-test-config.yml new file mode 100644 index 000000000000..51bc125eee7e --- /dev/null +++ b/airbyte-integrations/connectors/source-revolut-merchant/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-revolut-merchant:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-revolut-merchant/icon.svg b/airbyte-integrations/connectors/source-revolut-merchant/icon.svg new file mode 100644 index 000000000000..c5520e22bd4e --- /dev/null +++ b/airbyte-integrations/connectors/source-revolut-merchant/icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/airbyte-integrations/connectors/source-revolut-merchant/manifest.yaml b/airbyte-integrations/connectors/source-revolut-merchant/manifest.yaml new file mode 100644 index 000000000000..392da90cf303 --- /dev/null +++ b/airbyte-integrations/connectors/source-revolut-merchant/manifest.yaml @@ -0,0 +1,339 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + This is the Revolut Merchant source that ingests data from the Revolut + Merchant API. + + + Revolut helps you spend, send, and save smarter https://www.revolut.com/ + + + The Revolut Merchant account is a sub-account of your Revolut Business + account. While a Business account is for managing your business finances, the + Merchant account is dedicated to helping you accept online payments from your + e-commerce customers. + + + This source uses the Merchant API and has the orders, customers and location + endpoints. In order to use this API, you must first create a Revolut account. + + Log in to your Revolut Business account: Access the Revolut Business log in + page and enter your credentials. + + Navigate to Merchant API settings: Once logged in, access the Merchant API + settings page by clicking your profile icon in the top left corner, then + selecting APIs > Merchant API. + + Here you can access your Production API keys (Public, Secret) specific to your + Merchant account. + + Get API keys: If you're visiting this page for the first time, you'll need to + initiate the process by clicking the Get started button. To generate your + Production API Secret key, click the Generate button. + + You can find more about the API here + https://developer.revolut.com/docs/merchant/merchant-api + +check: + type: CheckStream + stream_names: + - orders + +definitions: + streams: + orders: + type: DeclarativeStream + name: orders + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/1.0/orders + http_method: GET + request_headers: + Revolut-Api-Version: "{{ config[\"api_version\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 1000 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%fZ" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: from_created_date + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/orders" + customers: + type: DeclarativeStream + name: customers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/1.0/customers + http_method: GET + request_headers: + Revolut-Api-Version: "{{ config[\"api_version\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers" + locations: + type: DeclarativeStream + name: locations + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/locations + http_method: GET + request_headers: + Revolut-Api-Version: "{{ config[\"api_version\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/locations" + base_requester: + type: HttpRequester + url_base: https://{{ config["environment"] }}.revolut.com + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"secret_api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/orders" + - $ref: "#/definitions/streams/customers" + - $ref: "#/definitions/streams/locations" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_version + - secret_api_key + - start_date + - environment + properties: + api_version: + type: string + description: >- + Specify the API version to use. This is required for certain API + calls. Example: '2024-09-01'. + name: api_version + title: API Version + order: 0 + secret_api_key: + type: string + description: >- + Secret API key to use for authenticating with the Revolut Merchant + API. Find it in your Revolut Business account under APIs > Merchant + API. + name: secret_api_key + title: Secret API Key + airbyte_secret: true + order: 1 + start_date: + type: string + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + order: 2 + environment: + type: string + description: The base url of your environment. Either sandbox or production + title: environment + enum: + - sandbox-merchant + - merchant + order: 3 + additionalProperties: true + +metadata: + autoImportSchema: + orders: true + customers: true + locations: false + testedStreams: + orders: + streamHash: 029edb3159cb90ba6d7e54b216a2d6f118665165 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + customers: + streamHash: dc0f2db5574ead07283be51fafd8d5037e689124 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + locations: + streamHash: 2fbbfea59789b5f870d88a118d29d4fb59b35797 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://developer.revolut.com/docs/merchant/merchant-api + +schemas: + orders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + metadata: + type: + - object + - "null" + capture_mode: + type: + - string + - "null" + created_at: + type: string + id: + type: string + order_amount: + type: + - object + - "null" + properties: + currency: + type: + - string + - "null" + value: + type: + - number + - "null" + order_outstanding_amount: + type: + - object + - "null" + properties: + currency: + type: + - string + - "null" + value: + type: + - number + - "null" + state: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + - created_at + customers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + business_name: + type: + - string + - "null" + created_at: + type: + - string + - "null" + email: + type: + - string + - "null" + full_name: + type: + - string + - "null" + id: + type: string + phone: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + locations: + type: object + $schema: http://json-schema.org/schema# + properties: + type: + type: + - string + - "null" + details: + type: + - object + - "null" + properties: + domain: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + required: + - id + additionalProperties: true diff --git a/airbyte-integrations/connectors/source-revolut-merchant/metadata.yaml b/airbyte-integrations/connectors/source-revolut-merchant/metadata.yaml new file mode 100644 index 000000000000..c77392a02baf --- /dev/null +++ b/airbyte-integrations/connectors/source-revolut-merchant/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "https://*.revolut.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-revolut-merchant + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 47a7a5cf-7bfa-406e-8ef8-f23cd041866b + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-revolut-merchant + githubIssueLabel: source-revolut-merchant + icon: icon.svg + license: MIT + name: Revolut Merchant + releaseDate: 2024-10-27 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/revolut-merchant + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-ringcentral/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-ringcentral/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-ringcentral/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-ringcentral/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-ringcentral/metadata.yaml b/airbyte-integrations/connectors/source-ringcentral/metadata.yaml index b790db0aaba3..a980be7f1d49 100644 --- a/airbyte-integrations/connectors/source-ringcentral/metadata.yaml +++ b/airbyte-integrations/connectors/source-ringcentral/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 213d69b9-da66-419e-af29-c23142d4af5f - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-ringcentral githubIssueLabel: source-ringcentral icon: icon.svg @@ -38,5 +38,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-rki-covid/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-rki-covid/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-rki-covid/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-rki-covid/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-rki-covid/main.py b/airbyte-integrations/connectors/source-rki-covid/main.py index a104106001cb..1e4d286df619 100644 --- a/airbyte-integrations/connectors/source-rki-covid/main.py +++ b/airbyte-integrations/connectors/source-rki-covid/main.py @@ -4,5 +4,6 @@ from source_rki_covid.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-rki-covid/metadata.yaml b/airbyte-integrations/connectors/source-rki-covid/metadata.yaml index 670619bfc38d..0a06d5309976 100644 --- a/airbyte-integrations/connectors/source-rki-covid/metadata.yaml +++ b/airbyte-integrations/connectors/source-rki-covid/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: d78e5de0-aa44-4744-aa4f-74c818ccfe19 - dockerImageTag: 0.1.24 + dockerImageTag: 0.1.29 dockerRepository: airbyte/source-rki-covid githubIssueLabel: source-rki-covid icon: rki.svg @@ -40,5 +40,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-rki-covid/poetry.lock b/airbyte-integrations/connectors/source-rki-covid/poetry.lock index 7a6a3934921d..1077e5f93884 100644 --- a/airbyte-integrations/connectors/source-rki-covid/poetry.lock +++ b/airbyte-integrations/connectors/source-rki-covid/poetry.lock @@ -62,19 +62,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -140,127 +140,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -276,20 +263,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -367,13 +354,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -486,13 +473,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -573,54 +560,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -884,33 +871,33 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -951,13 +938,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -982,81 +969,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-rki-covid/pyproject.toml b/airbyte-integrations/connectors/source-rki-covid/pyproject.toml index 426d4e9c8a56..002019a94a19 100644 --- a/airbyte-integrations/connectors/source-rki-covid/pyproject.toml +++ b/airbyte-integrations/connectors/source-rki-covid/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.24" +version = "0.1.29" name = "source-rki-covid" description = "Source implementation for Rki Covid." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-rki-covid/source_rki_covid/source.py b/airbyte-integrations/connectors/source-rki-covid/source_rki_covid/source.py index 65fe10330a2e..ee3cc9e34ea5 100644 --- a/airbyte-integrations/connectors/source-rki-covid/source_rki_covid/source.py +++ b/airbyte-integrations/connectors/source-rki-covid/source_rki_covid/source.py @@ -8,6 +8,7 @@ from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Tuple import requests + from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http import HttpStream @@ -15,7 +16,6 @@ # Basic full refresh stream class RkiCovidStream(HttpStream, ABC): - url_base = "https://api.corona-zahlen.org/" def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: @@ -106,7 +106,6 @@ def path( # Basic incremental stream class IncrementalRkiCovidStream(RkiCovidStream, ABC): - state_checkpoint_interval = None @property diff --git a/airbyte-integrations/connectors/source-rki-covid/unit_tests/test_incremental_streams.py b/airbyte-integrations/connectors/source-rki-covid/unit_tests/test_incremental_streams.py index e701d03455d4..a4058a6f3deb 100644 --- a/airbyte-integrations/connectors/source-rki-covid/unit_tests/test_incremental_streams.py +++ b/airbyte-integrations/connectors/source-rki-covid/unit_tests/test_incremental_streams.py @@ -3,10 +3,11 @@ # -from airbyte_cdk.models import SyncMode from pytest import fixture from source_rki_covid.source import IncrementalRkiCovidStream +from airbyte_cdk.models import SyncMode + @fixture def patch_incremental_base_class(mocker): diff --git a/airbyte-integrations/connectors/source-rocket-chat/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-rocket-chat/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-rocket-chat/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-rocket-chat/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-rocket-chat/metadata.yaml b/airbyte-integrations/connectors/source-rocket-chat/metadata.yaml index 14e4a2d51add..9dc86d7fca41 100644 --- a/airbyte-integrations/connectors/source-rocket-chat/metadata.yaml +++ b/airbyte-integrations/connectors/source-rocket-chat/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 921d9608-3915-450b-8078-0af18801ea1b - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.8 dockerRepository: airbyte/source-rocket-chat githubIssueLabel: source-rocket-chat icon: rocket-chat.svg @@ -38,5 +38,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-rocketlane/README.md b/airbyte-integrations/connectors/source-rocketlane/README.md new file mode 100644 index 000000000000..3b49478be780 --- /dev/null +++ b/airbyte-integrations/connectors/source-rocketlane/README.md @@ -0,0 +1,33 @@ +# Rocketlane +This directory contains the manifest-only connector for `source-rocketlane`. + +Rocketlane connector enables seamless data integration by syncing project, task, and user data from Rocketlane into various data warehouses or analytics platforms. It ensures real-time access to operational insights, enhancing project visibility and performance tracking across tools. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-rocketlane:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-rocketlane build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-rocketlane test +``` + diff --git a/airbyte-integrations/connectors/source-rocketlane/acceptance-test-config.yml b/airbyte-integrations/connectors/source-rocketlane/acceptance-test-config.yml new file mode 100644 index 000000000000..8a492e98c94c --- /dev/null +++ b/airbyte-integrations/connectors/source-rocketlane/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-rocketlane:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-rocketlane/icon.svg b/airbyte-integrations/connectors/source-rocketlane/icon.svg new file mode 100644 index 000000000000..9289547c6fad --- /dev/null +++ b/airbyte-integrations/connectors/source-rocketlane/icon.svg @@ -0,0 +1,361 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-rocketlane/manifest.yaml b/airbyte-integrations/connectors/source-rocketlane/manifest.yaml new file mode 100644 index 000000000000..9366ef786c5c --- /dev/null +++ b/airbyte-integrations/connectors/source-rocketlane/manifest.yaml @@ -0,0 +1,1360 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Rocketlane connector enables seamless data integration by syncing project, + task, and user data from Rocketlane into various data warehouses or analytics + platforms. It ensures real-time access to operational insights, enhancing + project visibility and performance tracking across tools. + +check: + type: CheckStream + stream_names: + - tasks + +definitions: + streams: + tasks: + type: DeclarativeStream + name: tasks + primary_key: + - taskId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/1.0/tasks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + page_size_option: + type: RequestOption + field_name: pageSize + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.pagination.nextPageToken }}" + stop_condition: "{{ response.pagination.hasMore is false }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tasks" + users: + type: DeclarativeStream + name: users + primary_key: + - userId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/1.0/users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.pagination.nextPageToken }}" + stop_condition: "{{ response.pagination.hasMore is false }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + projects: + type: DeclarativeStream + name: projects + primary_key: + - projectId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/1.0/projects + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.pagination.nextPageToken }}" + stop_condition: "{{ response.pagination.hasMore is false }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/projects" + fields: + type: DeclarativeStream + name: fields + primary_key: + - fieldId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/1.0/fields + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.pagination.nextPageToken }}" + stop_condition: "{{ response.pagination.hasMore is false }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/fields" + time-offs: + type: DeclarativeStream + name: time-offs + primary_key: + - timeOffId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/1.0/time-offs + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.pagination.nextPageToken }}" + stop_condition: "{{ response.pagination.hasMore is false }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/time-offs" + spaces: + type: DeclarativeStream + name: spaces + primary_key: + - spaceId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/1.0/spaces + http_method: GET + request_parameters: + projectId: "{{ stream_partition.project }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.pagination.nextPageToken }}" + stop_condition: "{{ response.pagination.hasMore is false }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: projectId + partition_field: project + stream: + $ref: "#/definitions/streams/projects" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/spaces" + phases: + type: DeclarativeStream + name: phases + primary_key: + - phaseId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/1.0/phases + http_method: GET + request_parameters: + projectId: "{{ stream_partition.project }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.pagination.nextPageToken }}" + stop_condition: "{{ response.pagination.hasMore is false }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: projectId + partition_field: project + stream: + $ref: "#/definitions/streams/projects" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/phases" + time-entries: + type: DeclarativeStream + name: time-entries + primary_key: + - timeEntryId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/1.0/time-entries + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.pagination.nextPageToken }}" + stop_condition: "{{ response.pagination.hasMore is false }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/time-entries" + space-documents: + type: DeclarativeStream + name: space-documents + primary_key: + - spaceDocumentId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/1.0/space-documents + http_method: GET + request_parameters: + projectId: "{{ stream_partition.project }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: pageSize + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.pagination.nextPageToken }}" + stop_condition: "{{ response.pagination.hasMore is false }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: projectId + partition_field: project + stream: + $ref: "#/definitions/streams/projects" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/space-documents" + base_requester: + type: HttpRequester + url_base: https://api.rocketlane.com + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: api-key + inject_into: header + +streams: + - $ref: "#/definitions/streams/tasks" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/projects" + - $ref: "#/definitions/streams/fields" + - $ref: "#/definitions/streams/time-offs" + - $ref: "#/definitions/streams/spaces" + - $ref: "#/definitions/streams/phases" + - $ref: "#/definitions/streams/time-entries" + - $ref: "#/definitions/streams/space-documents" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + description: >- + API key to use. Generate it from the API section in Settings of your + Rocketlane account. + name: api_key + order: 0 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + tasks: true + users: true + projects: true + fields: true + time-offs: true + spaces: true + phases: true + time-entries: true + space-documents: true + testedStreams: + tasks: + streamHash: f42abcda6d23be242fcdfd02fa69d7f813784337 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + users: + streamHash: f1c9f61039abee9ad2a2f71a86608c4e9736e9bf + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + projects: + streamHash: c5a42726642e82e4357b9133692ca2c02f79c64d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + fields: + streamHash: fb5daf45eae67a9eec80e7920863eeafc4c3d944 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + time-offs: + streamHash: 634785a588835d479a1bdff8b777345649f2c5c1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + spaces: + streamHash: 48ca68b40d0d0a3ce547fccfb3729d6e42a791d2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + phases: + streamHash: f58f9b3165c815b7c66273fcfc6b207c4f016add + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + time-entries: + streamHash: 3a782d94a3ca6fb1bf3aa871c1e51ae3fcb2199c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + space-documents: + hasRecords: true + streamHash: 04ce76a7e12b2a7634b1d2f574bc4aacfdad0783 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://developer.rocketlane.com/docs/overview + +schemas: + tasks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + archived: + type: + - boolean + - "null" + createdAt: + type: + - number + - "null" + createdBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + userId: + type: + - number + - "null" + dueDate: + type: + - string + - "null" + fields: + type: + - array + - "null" + project: + type: + - object + - "null" + properties: + projectId: + type: + - number + - "null" + projectName: + type: + - string + - "null" + startDate: + type: + - string + - "null" + status: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - number + - "null" + taskDescription: + type: + - string + - "null" + taskId: + type: number + taskName: + type: + - string + - "null" + updatedAt: + type: + - number + - "null" + updatedBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + userId: + type: + - number + - "null" + required: + - taskId + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + createdAt: + type: + - number + - "null" + createdBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + userId: + type: + - number + - "null" + email: + type: + - string + - "null" + fields: + type: + - array + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + status: + type: + - string + - "null" + updatedAt: + type: + - number + - "null" + updatedBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + userId: + type: + - number + - "null" + userId: + type: number + required: + - userId + projects: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + archived: + type: + - boolean + - "null" + createdAt: + type: + - number + - "null" + createdBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + userId: + type: + - number + - "null" + currency: + type: + - object + - "null" + properties: + currencyCode: + type: + - string + - "null" + currencyName: + type: + - string + - "null" + currencySymbol: + type: + - string + - "null" + customer: + type: + - object + - "null" + properties: + companyId: + type: + - number + - "null" + companyName: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + fields: + type: + - array + - "null" + owner: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + userId: + type: + - number + - "null" + partnerCompanies: + type: + - array + - "null" + projectId: + type: number + projectName: + type: + - string + - "null" + startDate: + type: + - string + - "null" + status: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - number + - "null" + teamMembers: + type: + - object + - "null" + properties: + customers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + userId: + type: + - number + - "null" + members: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + userId: + type: + - number + - "null" + updatedAt: + type: + - number + - "null" + updatedBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + userId: + type: + - number + - "null" + visibility: + type: + - string + - "null" + required: + - projectId + fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + enabled: + type: + - boolean + - "null" + fieldId: + type: number + fieldLabel: + type: + - string + - "null" + fieldType: + type: + - string + - "null" + objectType: + type: + - string + - "null" + private: + type: + - boolean + - "null" + updatedAt: + type: + - number + - "null" + updatedBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + userId: + type: + - number + - "null" + required: + - fieldId + time-offs: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + createdAt: + type: + - number + - "null" + durationInMinutes: + type: + - number + - "null" + endDate: + type: + - string + - "null" + startDate: + type: + - string + - "null" + timeOffId: + type: number + user: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + userId: + type: + - number + - "null" + required: + - timeOffId + spaces: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - number + - "null" + createdBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + userId: + type: + - number + - "null" + private: + type: + - boolean + - "null" + project: + type: + - object + - "null" + properties: + projectId: + type: + - number + - "null" + projectName: + type: + - string + - "null" + spaceId: + type: number + spaceName: + type: + - string + - "null" + updatedAt: + type: + - number + - "null" + updatedBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + userId: + type: + - number + - "null" + required: + - spaceId + phases: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - number + - "null" + createdBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + userId: + type: + - number + - "null" + dueDate: + type: + - string + - "null" + phaseId: + type: number + phaseName: + type: + - string + - "null" + private: + type: + - boolean + - "null" + project: + type: + - object + - "null" + properties: + projectId: + type: + - number + - "null" + projectName: + type: + - string + - "null" + startDate: + type: + - string + - "null" + status: + type: + - object + - "null" + properties: + label: + type: + - string + - "null" + value: + type: + - number + - "null" + updatedAt: + type: + - number + - "null" + updatedBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + userId: + type: + - number + - "null" + required: + - phaseId + time-entries: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + billable: + type: + - boolean + - "null" + createdAt: + type: + - number + - "null" + createdBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + userId: + type: + - number + - "null" + date: + type: + - string + - "null" + minutes: + type: + - number + - "null" + project: + type: + - object + - "null" + properties: + projectId: + type: + - number + - "null" + projectName: + type: + - string + - "null" + timeEntryId: + type: number + updatedAt: + type: + - number + - "null" + updatedBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + userId: + type: + - number + - "null" + user: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + userId: + type: + - number + - "null" + required: + - timeEntryId + space-documents: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - number + - "null" + createdBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + userId: + type: + - number + - "null" + source: + type: + - object + - "null" + properties: + templateId: + type: + - number + - "null" + templateName: + type: + - string + - "null" + space: + type: + - object + - "null" + properties: + spaceId: + type: + - number + - "null" + spaceName: + type: + - string + - "null" + spaceDocumentId: + type: number + spaceDocumentName: + type: + - string + - "null" + spaceDocumentType: + type: + - string + - "null" + updatedAt: + type: + - number + - "null" + updatedBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + userId: + type: + - number + - "null" + url: + type: + - string + - "null" + required: + - spaceDocumentId diff --git a/airbyte-integrations/connectors/source-rocketlane/metadata.yaml b/airbyte-integrations/connectors/source-rocketlane/metadata.yaml new file mode 100644 index 000000000000..4b878342afab --- /dev/null +++ b/airbyte-integrations/connectors/source-rocketlane/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.rocketlane.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-rocketlane + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 6c817011-0b41-47ce-9b50-0274e0c6b127 + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-rocketlane + githubIssueLabel: source-rocketlane + icon: icon.svg + license: MIT + name: Rocketlane + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/rocketlane + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-rollbar/metadata.yaml b/airbyte-integrations/connectors/source-rollbar/metadata.yaml index 795b25c37320..39c425f4b279 100644 --- a/airbyte-integrations/connectors/source-rollbar/metadata.yaml +++ b/airbyte-integrations/connectors/source-rollbar/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-rollbar connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.6.2@sha256:f5fcd3d4703b7590b6166a7853c5ed1686731607cd30a159a8c24e2fe2c1ee98 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 8d518856-6bfa-4d92-80ca-796b0338e341 - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-rollbar githubIssueLabel: source-rollbar icon: icon.svg diff --git a/airbyte-integrations/connectors/source-rootly/metadata.yaml b/airbyte-integrations/connectors/source-rootly/metadata.yaml index d5a0373dcf3c..808caa0a3a0d 100644 --- a/airbyte-integrations/connectors/source-rootly/metadata.yaml +++ b/airbyte-integrations/connectors/source-rootly/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-rootly connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 2f111b00-0b92-4329-8481-6d7aa27a3991 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-rootly githubIssueLabel: source-rootly icon: icon.svg diff --git a/airbyte-integrations/connectors/source-rss/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-rss/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-rss/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-rss/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-rss/main.py b/airbyte-integrations/connectors/source-rss/main.py index 9e21c3c97793..c8e2b7f3042c 100644 --- a/airbyte-integrations/connectors/source-rss/main.py +++ b/airbyte-integrations/connectors/source-rss/main.py @@ -4,5 +4,6 @@ from source_rss.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-rss/metadata.yaml b/airbyte-integrations/connectors/source-rss/metadata.yaml index a223dc0df961..0d4fd3661eb9 100644 --- a/airbyte-integrations/connectors/source-rss/metadata.yaml +++ b/airbyte-integrations/connectors/source-rss/metadata.yaml @@ -20,11 +20,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 0efee448-6948-49e2-b786-17db50647908 - dockerImageTag: 1.0.23 + dockerImageTag: 1.0.29 dockerRepository: airbyte/source-rss githubIssueLabel: source-rss icon: rss.svg diff --git a/airbyte-integrations/connectors/source-rss/poetry.lock b/airbyte-integrations/connectors/source-rss/poetry.lock index 8c1e317345cf..dd07afbad041 100644 --- a/airbyte-integrations/connectors/source-rss/poetry.lock +++ b/airbyte-integrations/connectors/source-rss/poetry.lock @@ -41,13 +41,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] @@ -55,41 +55,41 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -155,13 +155,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -245,116 +245,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -424,20 +411,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -501,13 +488,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -522,13 +509,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -536,7 +523,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -586,13 +572,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -682,22 +668,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -770,69 +759,86 @@ files = [ [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -924,54 +930,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -983,13 +989,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1056,13 +1062,13 @@ files = [ [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] @@ -1275,23 +1281,23 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "sgmllib3k" @@ -1305,13 +1311,13 @@ files = [ [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1342,13 +1348,43 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "tomli" -version = "2.0.2" +version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] [[package]] @@ -1378,13 +1414,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1409,81 +1445,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-rss/pyproject.toml b/airbyte-integrations/connectors/source-rss/pyproject.toml index e0e3e8935ffe..a2531c318d35 100644 --- a/airbyte-integrations/connectors/source-rss/pyproject.toml +++ b/airbyte-integrations/connectors/source-rss/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "1.0.23" +version = "1.0.29" name = "source-rss" description = "Source implementation for rss." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-rss/source_rss/components.py b/airbyte-integrations/connectors/source-rss/source_rss/components.py index 571d1a0a2e0c..4379d281e143 100644 --- a/airbyte-integrations/connectors/source-rss/source_rss/components.py +++ b/airbyte-integrations/connectors/source-rss/source_rss/components.py @@ -12,12 +12,13 @@ import feedparser import pytz import requests +from dateutil.parser import parse + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor from airbyte_cdk.sources.declarative.incremental import DatetimeBasedCursor from airbyte_cdk.sources.declarative.types import StreamSlice from airbyte_cdk.sources.streams.core import Stream -from dateutil.parser import parse class CustomExtractor(RecordExtractor): diff --git a/airbyte-integrations/connectors/source-rss/source_rss/run.py b/airbyte-integrations/connectors/source-rss/source_rss/run.py index 90f8a101fcfa..c91bcd0dfb70 100644 --- a/airbyte-integrations/connectors/source-rss/source_rss/run.py +++ b/airbyte-integrations/connectors/source-rss/source_rss/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_rss import SourceRss +from airbyte_cdk.entrypoint import launch + def run(): source = SourceRss() diff --git a/airbyte-integrations/connectors/source-rss/source_rss/source.py b/airbyte-integrations/connectors/source-rss/source_rss/source.py index 297b6a38c9ef..b9e4d0882b56 100644 --- a/airbyte-integrations/connectors/source-rss/source_rss/source.py +++ b/airbyte-integrations/connectors/source-rss/source_rss/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-ruddr/README.md b/airbyte-integrations/connectors/source-ruddr/README.md new file mode 100644 index 000000000000..bc7881b35f91 --- /dev/null +++ b/airbyte-integrations/connectors/source-ruddr/README.md @@ -0,0 +1,33 @@ +# Ruddr +This directory contains the manifest-only connector for `source-ruddr`. + +Ruddr connector enables seamless data synchronization from Ruddr to various data warehouses, lakes, and destinations. It simplifies data pipelines by extracting projects and analytics data, ensuring reliable and efficient data integration for real-time insights. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-ruddr:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-ruddr build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-ruddr test +``` + diff --git a/airbyte-integrations/connectors/source-ruddr/acceptance-test-config.yml b/airbyte-integrations/connectors/source-ruddr/acceptance-test-config.yml new file mode 100644 index 000000000000..875d3b09acfb --- /dev/null +++ b/airbyte-integrations/connectors/source-ruddr/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-ruddr:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-ruddr/icon.svg b/airbyte-integrations/connectors/source-ruddr/icon.svg new file mode 100644 index 000000000000..060ca575d7e4 --- /dev/null +++ b/airbyte-integrations/connectors/source-ruddr/icon.svg @@ -0,0 +1,165 @@ + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-ruddr/manifest.yaml b/airbyte-integrations/connectors/source-ruddr/manifest.yaml new file mode 100644 index 000000000000..9eab44c46aee --- /dev/null +++ b/airbyte-integrations/connectors/source-ruddr/manifest.yaml @@ -0,0 +1,1908 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Ruddr connector enables seamless data synchronization from Ruddr to various + data warehouses, lakes, and destinations. It simplifies data pipelines by + extracting projects and analytics data, ensuring reliable and efficient data + integration for real-time insights. + +check: + type: CheckStream + stream_names: + - clients + +definitions: + streams: + clients: + type: DeclarativeStream + name: clients + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/workspace/clients + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not response.get('hasMore', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/clients" + projects: + type: DeclarativeStream + name: projects + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/workspace/projects + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not response.get('hasMore', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/projects" + project_members: + type: DeclarativeStream + name: project_members + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/workspace/project-members + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not response.get('hasMore', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/project_members" + project_tasks: + type: DeclarativeStream + name: project_tasks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/workspace/project-tasks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not response.get('hasMore', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/project_tasks" + expense_reports: + type: DeclarativeStream + name: expense_reports + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/workspace/expense-reports + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not response.get('hasMore', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/expense_reports" + expense_items: + type: DeclarativeStream + name: expense_items + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/workspace/expense-items + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not response.get('hasMore', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/expense_items" + expense_categories: + type: DeclarativeStream + name: expense_categories + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/workspace/expense-categories + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not response.get('hasMore', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/expense_categories" + project_expense: + type: DeclarativeStream + name: project_expense + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/workspace/project-expenses + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not response.get('hasMore', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/project_expense" + project_budget_expenses: + type: DeclarativeStream + name: project_budget_expenses + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/workspace/project-budget-expenses + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not response.get('hasMore', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/project_budget_expenses" + workspace members: + type: DeclarativeStream + name: workspace members + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/workspace/members + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not response.get('hasMore', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/workspace members" + opportunity_stages: + type: DeclarativeStream + name: opportunity_stages + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/workspace/opportunity-stages + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not response.get('hasMore', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/opportunity_stages" + invoices: + type: DeclarativeStream + name: invoices + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/workspace/invoices + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not response.get('hasMore', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/invoices" + holidays: + type: DeclarativeStream + name: holidays + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/workspace/holidays + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ not response.get('hasMore', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/holidays" + base_requester: + type: HttpRequester + url_base: https://www.ruddr.io + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"api_token\"] }}" + +streams: + - $ref: "#/definitions/streams/clients" + - $ref: "#/definitions/streams/projects" + - $ref: "#/definitions/streams/project_members" + - $ref: "#/definitions/streams/project_tasks" + - $ref: "#/definitions/streams/expense_reports" + - $ref: "#/definitions/streams/expense_items" + - $ref: "#/definitions/streams/expense_categories" + - $ref: "#/definitions/streams/project_expense" + - $ref: "#/definitions/streams/project_budget_expenses" + - $ref: "#/definitions/streams/workspace members" + - $ref: "#/definitions/streams/opportunity_stages" + - $ref: "#/definitions/streams/invoices" + - $ref: "#/definitions/streams/holidays" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_token + properties: + api_token: + type: string + description: >- + API token to use. Generate it in the API Keys section of your Ruddr + workspace settings. + name: api_token + order: 0 + title: API Token + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + clients: true + projects: true + project_members: true + project_tasks: true + expense_reports: true + expense_items: true + expense_categories: true + project_expense: true + project_budget_expenses: true + workspace members: true + opportunity_stages: true + invoices: true + holidays: true + testedStreams: + clients: + hasRecords: true + streamHash: d7206bb2a9ad7cce15d43b31687a019f79fc239c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + projects: + streamHash: 5aad516081ec65cdd3bf3b2c79e604b2e01abea9 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + project_members: + streamHash: e09568cf09727d066c1743fc464033f59d269c69 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + project_tasks: + streamHash: 5afca7a8466e35bd552966fd99d25de2876a9ef1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + expense_reports: + streamHash: 2e9256559152503a60f8225ca4304f302ef56a4f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + expense_items: + streamHash: 39f7c16617da1c6d9cd5cbc05a06e9ba3b00f3eb + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + expense_categories: + streamHash: 1adead20f712af318ed9aab10d9567a69102f686 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + project_expense: + streamHash: 3ad86157361c59c1e8bcd6d7baa60e8c7db5ee46 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + project_budget_expenses: + streamHash: a18fe92c139cacb1b8e4dd76e8c416a7a13837f2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + workspace members: + streamHash: 3399f8bbd6125bbfa1defc38ef3d9ebe68525b20 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + opportunity_stages: + streamHash: d673b9f52d2e25a4cf933749311caf54d1496cfe + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + invoices: + streamHash: 7b2e25709fe845c1f988073f0f11fe930fc99338 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + holidays: + streamHash: 8f154ff1c0caa11ee1fc59870ea2f1ab07dad225 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://ruddr.readme.io/reference/introduction + +schemas: + clients: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + currency: + type: + - string + - "null" + emails: + type: + - array + - "null" + id: + type: string + invoiceNotes: + type: + - string + - "null" + isInternal: + type: + - boolean + - "null" + key: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + paymentTermsId: + type: + - string + - "null" + recordStatusId: + type: + - string + - "null" + salesRepresentative: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + tags: + type: + - array + - "null" + useWorkspaceInvoiceDetails: + type: + - boolean + - "null" + required: + - id + projects: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + billingTypeId: + type: + - string + - "null" + budget: + type: + - object + - "null" + properties: + billableExpenses: + type: + - number + - "null" + billableHours: + type: + - number + - "null" + nonBillableExpenses: + type: + - number + - "null" + nonBillableHours: + type: + - number + - "null" + otherRevenue: + type: + - number + - "null" + revenue: + type: + - number + - "null" + servicesRevenue: + type: + - number + - "null" + budgetMode: + type: + - string + - "null" + client: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + currency: + type: + - string + - "null" + end: + type: + - string + - "null" + id: + type: string + isBillable: + type: + - boolean + - "null" + isProductive: + type: + - boolean + - "null" + key: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + recordStatusId: + type: + - string + - "null" + requiresNotes: + type: + - boolean + - "null" + requiresTasks: + type: + - boolean + - "null" + revenueRecognitionMethod: + type: + - string + - "null" + salesRepresentative: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + start: + type: + - string + - "null" + statusId: + type: + - string + - "null" + tags: + type: + - array + - "null" + useBudget: + type: + - boolean + - "null" + useMonthlyBudget: + type: + - boolean + - "null" + useRoles: + type: + - boolean + - "null" + required: + - id + project_members: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + id: + type: string + isActive: + type: + - boolean + - "null" + isBillable: + type: + - boolean + - "null" + member: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + overrideCostRate: + type: + - boolean + - "null" + project: + type: + - object + - "null" + properties: + client: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + roles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + typeId: + type: + - string + - "null" + required: + - id + project_tasks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + budgetedHours: + type: + - number + - "null" + budgetedServicesRevenue: + type: + - number + - "null" + capAssignedHours: + type: + - boolean + - "null" + capHours: + type: + - boolean + - "null" + createdAt: + type: + - string + - "null" + end: + type: + - string + - "null" + forAssignedOnly: + type: + - boolean + - "null" + id: + type: string + isBillable: + type: + - boolean + - "null" + lockTime: + type: + - boolean + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + order: + type: + - number + - "null" + project: + type: + - object + - "null" + properties: + client: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + projectMembers: + type: + - array + - "null" + requireNotes: + type: + - boolean + - "null" + roles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + hours: + type: + - number + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + start: + type: + - string + - "null" + statusId: + type: + - string + - "null" + tags: + type: + - array + - "null" + required: + - id + expense_reports: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + date: + type: + - string + - "null" + id: + type: string + member: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + number: + type: + - number + - "null" + title: + type: + - string + - "null" + required: + - id + expense_items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + amount: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + currency: + type: + - string + - "null" + date: + type: + - string + - "null" + expenseCategory: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + expenseReport: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + title: + type: + - string + - "null" + id: + type: string + invoiced: + type: + - boolean + - "null" + isBillable: + type: + - boolean + - "null" + isReimbursable: + type: + - boolean + - "null" + member: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + project: + type: + - object + - "null" + properties: + client: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + statusId: + type: + - string + - "null" + vendor: + type: + - string + - "null" + required: + - id + expense_categories: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + id: + type: string + invoiceItem: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + requireAttendees: + type: + - boolean + - "null" + requireNotes: + type: + - boolean + - "null" + requireReceipt: + type: + - boolean + - "null" + unitAmount: + type: + - number + - "null" + unitName: + type: + - string + - "null" + required: + - id + project_expense: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + amount: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + date: + type: + - string + - "null" + expenseCategory: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: string + invoiced: + type: + - boolean + - "null" + isBillable: + type: + - boolean + - "null" + project: + type: + - object + - "null" + properties: + client: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + required: + - id + project_budget_expenses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + billableAmount: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + expenseCategory: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: string + nonBillableAmount: + type: + - number + - "null" + project: + type: + - object + - "null" + properties: + client: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + required: + - id + workspace members: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + hasMore: + type: + - boolean + - "null" + results: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + activeStartDate: + type: + - string + - "null" + availabilityPeriods: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + hoursPerDay: + type: + - array + - "null" + items: + type: + - number + - "null" + id: + type: + - string + - "null" + start: + type: + - string + - "null" + costMethodId: + type: + - string + - "null" + costPeriods: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + costPerHour: + type: + - number + - "null" + currency: + type: + - string + - "null" + currencyName: + type: + - string + - "null" + id: + type: + - string + - "null" + overheadCostPerHour: + type: + - number + - "null" + start: + type: + - string + - "null" + totalCostPerHour: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + defaultRateCurrency: + type: + - string + - "null" + email: + type: + - string + - "null" + employmentTypeId: + type: + - string + - "null" + forbidTimesheetSubmissionWhenBelowCapacity: + type: + - boolean + - "null" + holidaySchedule: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: + - string + - "null" + invitationStatusId: + type: + - string + - "null" + isActive: + type: + - boolean + - "null" + isBillable: + type: + - boolean + - "null" + loginEnabled: + type: + - boolean + - "null" + name: + type: + - string + - "null" + receiveMissingTimeReminders: + type: + - boolean + - "null" + securityRole: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + skills: + type: + - array + - "null" + tags: + type: + - array + - "null" + timeOffAllowed: + type: + - boolean + - "null" + timeOffApprovalMode: + type: + - string + - "null" + unsubmittedTimesheetReminders: + type: + - boolean + - "null" + utilizationTargetPeriods: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + start: + type: + - string + - "null" + targetPercentage: + type: + - number + - "null" + opportunity_stages: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + id: + type: string + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + probability: + type: + - number + - "null" + statusId: + type: + - string + - "null" + required: + - id + invoices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + amountCredited: + type: + - number + - "null" + amountDue: + type: + - number + - "null" + amountPaid: + type: + - number + - "null" + billTo: + type: + - string + - "null" + ccEmails: + type: + - array + - "null" + client: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + companyName: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + creditNotes: + type: + - array + - "null" + currency: + type: + - string + - "null" + dueOn: + type: + - string + - "null" + emailBody: + type: + - string + - "null" + emailFromName: + type: + - string + - "null" + emailSubject: + type: + - string + - "null" + emails: + type: + - array + - "null" + id: + type: string + invoiceFor: + type: + - string + - "null" + issuedOn: + type: + - string + - "null" + lines: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + amount: + type: + - number + - "null" + id: + type: + - string + - "null" + invoiceItem: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + item: + type: + - string + - "null" + lineNumber: + type: + - number + - "null" + project: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + quantity: + type: + - number + - "null" + rate: + type: + - number + - "null" + taxable: + type: + - boolean + - "null" + notes: + type: + - string + - "null" + number: + type: + - string + - "null" + paymentTermsId: + type: + - string + - "null" + payments: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + amount: + type: + - number + - "null" + id: + type: + - string + - "null" + projects: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + replyTo: + type: + - string + - "null" + sendBcc: + type: + - boolean + - "null" + servicesThrough: + type: + - string + - "null" + statusId: + type: + - string + - "null" + subtotal: + type: + - number + - "null" + total: + type: + - number + - "null" + totalTax: + type: + - number + - "null" + required: + - id + holidays: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + id: + type: string + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + occurrences: + type: + - array + - "null" + items: + type: + - string + - "null" + readOnly: + type: + - boolean + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-ruddr/metadata.yaml b/airbyte-integrations/connectors/source-ruddr/metadata.yaml new file mode 100644 index 000000000000..a4900aec84c3 --- /dev/null +++ b/airbyte-integrations/connectors/source-ruddr/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "ruddr.io" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-ruddr + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 6e87d8e2-47bc-4a0a-a175-62e2b926bb07 + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-ruddr + githubIssueLabel: source-ruddr + icon: icon.svg + license: MIT + name: Ruddr + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/ruddr + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-s3/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-s3/integration_tests/acceptance.py index 706e9eba88be..de2ec1e2928c 100644 --- a/airbyte-integrations/connectors/source-s3/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-s3/integration_tests/acceptance.py @@ -11,6 +11,7 @@ import pytest import yaml + pytest_plugins = ("connector_acceptance_test.plugin",) logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-s3/integration_tests/cloud_spec.json b/airbyte-integrations/connectors/source-s3/integration_tests/cloud_spec.json index 7f18f8208448..4a84a545efa9 100644 --- a/airbyte-integrations/connectors/source-s3/integration_tests/cloud_spec.json +++ b/airbyte-integrations/connectors/source-s3/integration_tests/cloud_spec.json @@ -372,6 +372,46 @@ "required": ["name", "format"] } }, + "delivery_method": { + "title": "Delivery Method", + "default": "use_records_transfer", + "type": "object", + "order": 6, + "display_type": "radio", + "group": "advanced", + "oneOf": [ + { + "title": "Replicate Records", + "type": "object", + "properties": { + "delivery_type": { + "title": "Delivery Type", + "default": "use_records_transfer", + "const": "use_records_transfer", + "enum": ["use_records_transfer"], + "type": "string" + } + }, + "description": "Recommended - Extract and load structured records into your destination of choice. This is the classic method of moving data in Airbyte. It allows for blocking and hashing individual fields or files from a structured schema. Data can be flattened, typed and deduped depending on the destination.", + "required": ["delivery_type"] + }, + { + "title": "Copy Raw Files", + "type": "object", + "properties": { + "delivery_type": { + "title": "Delivery Type", + "default": "use_file_transfer", + "const": "use_file_transfer", + "enum": ["use_file_transfer"], + "type": "string" + } + }, + "description": "Copy raw files without parsing their contents. Bits are copied into the destination exactly as they appeared in the source. Recommended for use with unstructured text data, non-text and compressed files.", + "required": ["delivery_type"] + } + ] + }, "bucket": { "title": "Bucket", "description": "Name of the S3 bucket where the file(s) exist.", diff --git a/airbyte-integrations/connectors/source-s3/integration_tests/spec.json b/airbyte-integrations/connectors/source-s3/integration_tests/spec.json index 2b89a7812eaf..f3cab1f3a0c6 100644 --- a/airbyte-integrations/connectors/source-s3/integration_tests/spec.json +++ b/airbyte-integrations/connectors/source-s3/integration_tests/spec.json @@ -372,6 +372,46 @@ "required": ["name", "format"] } }, + "delivery_method": { + "title": "Delivery Method", + "default": "use_records_transfer", + "type": "object", + "order": 6, + "display_type": "radio", + "group": "advanced", + "oneOf": [ + { + "title": "Replicate Records", + "type": "object", + "properties": { + "delivery_type": { + "title": "Delivery Type", + "default": "use_records_transfer", + "const": "use_records_transfer", + "enum": ["use_records_transfer"], + "type": "string" + } + }, + "description": "Recommended - Extract and load structured records into your destination of choice. This is the classic method of moving data in Airbyte. It allows for blocking and hashing individual fields or files from a structured schema. Data can be flattened, typed and deduped depending on the destination.", + "required": ["delivery_type"] + }, + { + "title": "Copy Raw Files", + "type": "object", + "properties": { + "delivery_type": { + "title": "Delivery Type", + "default": "use_file_transfer", + "const": "use_file_transfer", + "enum": ["use_file_transfer"], + "type": "string" + } + }, + "description": "Copy raw files without parsing their contents. Bits are copied into the destination exactly as they appeared in the source. Recommended for use with unstructured text data, non-text and compressed files.", + "required": ["delivery_type"] + } + ] + }, "bucket": { "title": "Bucket", "description": "Name of the S3 bucket where the file(s) exist.", diff --git a/airbyte-integrations/connectors/source-s3/integration_tests/test_acceptance.py b/airbyte-integrations/connectors/source-s3/integration_tests/test_acceptance.py index 26647e4f62ad..9f4f69e5a062 100644 --- a/airbyte-integrations/connectors/source-s3/integration_tests/test_acceptance.py +++ b/airbyte-integrations/connectors/source-s3/integration_tests/test_acceptance.py @@ -19,6 +19,9 @@ import orjson import pytest import yaml +from pydantic import BaseModel +from source_s3.v4.source import SourceS3 + from airbyte_cdk.models import ( AirbyteMessage, AirbyteStream, @@ -29,8 +32,7 @@ Type, ) from airbyte_cdk.test import entrypoint_wrapper -from pydantic import BaseModel -from source_s3.v4.source import SourceS3 + if TYPE_CHECKING: from airbyte_cdk import Source @@ -70,6 +72,7 @@ def expect_exception(self) -> bool: def instance_name(self) -> str: return self.config_path.stem + def get_acceptance_tests(category: str) -> list[AcceptanceTestInstance]: all_tests_config = yaml.safe_load(ACCEPTANCE_TEST_CONFIG_PATH.read_text()) return [ @@ -78,6 +81,7 @@ def get_acceptance_tests(category: str) -> list[AcceptanceTestInstance]: if "iam_role" not in test["config_path"] ] + # TODO: Convert to a CDK class for better reuse and portability. # class TestSourceAcceptanceTestSuiteBase: # """Test suite for acceptance tests.""" diff --git a/airbyte-integrations/connectors/source-s3/main.py b/airbyte-integrations/connectors/source-s3/main.py index 6f38722d30cc..2596833e33a4 100644 --- a/airbyte-integrations/connectors/source-s3/main.py +++ b/airbyte-integrations/connectors/source-s3/main.py @@ -4,5 +4,6 @@ from source_s3.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-s3/metadata.yaml b/airbyte-integrations/connectors/source-s3/metadata.yaml index 599967946faa..32f9a3c07b1c 100644 --- a/airbyte-integrations/connectors/source-s3/metadata.yaml +++ b/airbyte-integrations/connectors/source-s3/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - "*.s3.amazonaws.com" connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: file connectorType: source definitionId: 69589781-7828-43c5-9f63-8925b1c1ccc2 - dockerImageTag: 4.9.1 + dockerImageTag: 4.11.3 dockerRepository: airbyte/source-s3 documentationUrl: https://docs.airbyte.com/integrations/sources/s3 githubIssueLabel: source-s3 @@ -39,6 +39,7 @@ data: message: Following 4.0.0 config change, we are eliminating the `streams.*.file_type` field which was redundant with `streams.*.format` upgradeDeadline: "2023-10-18" supportLevel: certified + supportsFileTransfer: true tags: - language:python - cdk:python-file-based diff --git a/airbyte-integrations/connectors/source-s3/poetry.lock b/airbyte-integrations/connectors/source-s3/poetry.lock index 4604549ac973..8b9a749e8924 100644 --- a/airbyte-integrations/connectors/source-s3/poetry.lock +++ b/airbyte-integrations/connectors/source-s3/poetry.lock @@ -2,13 +2,13 @@ [[package]] name = "airbyte-cdk" -version = "5.11.1" +version = "6.5.3" description = "A framework for writing Airbyte Connectors." optional = false python-versions = "<4.0,>=3.10" files = [ - {file = "airbyte_cdk-5.11.1-py3-none-any.whl", hash = "sha256:efddee85179128cb7d65b11a9a4aba353ea5b01daaa56fc3069d12ce156d2857"}, - {file = "airbyte_cdk-5.11.1.tar.gz", hash = "sha256:0cc1cdc1d50909bbb2791a9c389c0f3db32474502addf65eb745d87af7d36fd9"}, + {file = "airbyte_cdk-6.5.3-py3-none-any.whl", hash = "sha256:63c1aaf7b83bbe3ad07c7916ec23bd42e1d08281d989682a091d0cd019ab5b18"}, + {file = "airbyte_cdk-6.5.3.tar.gz", hash = "sha256:732d34632144d944e9ec027a4981886ed77b1dce477da524ee67ccd19730056c"}, ] [package.dependencies] @@ -19,6 +19,7 @@ cachetools = "*" cryptography = ">=42.0.5,<43.0.0" Deprecated = ">=1.2,<1.3" dpath = ">=2.1.6,<3.0.0" +dunamai = ">=1.22.0,<2.0.0" fastavro = {version = ">=1.8.0,<1.9.0", optional = true, markers = "extra == \"file-based\""} genson = "1.2.2" isodate = ">=0.6.1,<0.7.0" @@ -28,11 +29,13 @@ jsonschema = ">=3.2.0,<3.3.0" langchain_core = "0.1.42" markdown = {version = "*", optional = true, markers = "extra == \"file-based\""} nltk = "3.8.1" +numpy = "<2" orjson = ">=3.10.7,<4.0.0" pandas = "2.2.2" pdf2image = {version = "1.16.3", optional = true, markers = "extra == \"file-based\""} "pdfminer.six" = {version = "20221105", optional = true, markers = "extra == \"file-based\""} pendulum = "<3.0.0" +psutil = "6.1.0" pyarrow = {version = ">=15.0.0,<15.1.0", optional = true, markers = "extra == \"file-based\""} pydantic = ">=2.7,<3.0" pyjwt = ">=2.8.0,<3.0.0" @@ -41,6 +44,7 @@ pytesseract = {version = "0.3.10", optional = true, markers = "extra == \"file-b python-calamine = {version = "0.2.3", optional = true, markers = "extra == \"file-based\""} python-dateutil = "*" python-snappy = {version = "0.7.3", optional = true, markers = "extra == \"file-based\""} +python-ulid = ">=3.0.0,<4.0.0" pytz = "2024.1" PyYAML = ">=6.0.1,<7.0.0" requests = "*" @@ -49,21 +53,23 @@ serpyco-rs = ">=1.10.2,<2.0.0" unstructured = {version = "0.10.27", extras = ["docx", "pptx"], optional = true, markers = "extra == \"file-based\""} "unstructured.pytesseract" = {version = ">=0.3.12", optional = true, markers = "extra == \"file-based\""} wcmatch = "8.4" +xmltodict = ">=0.13.0,<0.14.0" [package.extras] file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "python-snappy (==0.7.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] +sql = ["sqlalchemy (>=2.0,!=2.0.36,<3.0)"] vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] [[package]] name = "airbyte-protocol-models-dataclasses" -version = "0.13.0" +version = "0.13.1" description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models_dataclasses-0.13.0-py3-none-any.whl", hash = "sha256:0aedb99ffc4f9aab0ce91bba2c292fa17cd8fd4b42eeba196d6a16c20bbbd7a5"}, - {file = "airbyte_protocol_models_dataclasses-0.13.0.tar.gz", hash = "sha256:72e67850d661e2808406aec5839b3158ebb94d3553b798dbdae1b4a278548d2f"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1-py3-none-any.whl", hash = "sha256:20a734b7b1c3479a643777830db6a2e0a34428f33d16abcfd320552576fabe5a"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1.tar.gz", hash = "sha256:ec6a0fb6b16267bde910f52279445d06c8e1a3e4ed82ac2937b405ab280449d5"}, ] [[package]] @@ -79,24 +85,24 @@ files = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -122,19 +128,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -187,17 +193,17 @@ lxml = ["lxml"] [[package]] name = "boto3" -version = "1.35.50" +version = "1.35.92" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.35.50-py3-none-any.whl", hash = "sha256:14724b905fd13f26d9d8f7cdcea0fa65a9acad79f60f41f7662667f4e233d97c"}, - {file = "boto3-1.35.50.tar.gz", hash = "sha256:4f15d1ccb481d66f6925b8c91c970ce41b956b6ecf7c479f23e2159531b37eec"}, + {file = "boto3-1.35.92-py3-none-any.whl", hash = "sha256:786930d5f1cd13d03db59ff2abbb2b7ffc173fd66646d5d8bee07f316a5f16ca"}, + {file = "boto3-1.35.92.tar.gz", hash = "sha256:f7851cb320dcb2a53fc73b4075187ec9b05d51291539601fa238623fdc0e8cd3"}, ] [package.dependencies] -botocore = ">=1.35.50,<1.36.0" +botocore = ">=1.35.92,<1.36.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -206,13 +212,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.35.50" +version = "1.35.92" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.35.50-py3-none-any.whl", hash = "sha256:965d3b99179ac04aa98e4c4baf4a970ebce77a5e02bb2a0a21cb6304e2bc0955"}, - {file = "botocore-1.35.50.tar.gz", hash = "sha256:136ecef8d5a1088f1ba485c0bbfca40abd42b9f9fe9e11d8cde4e53b4c05b188"}, + {file = "botocore-1.35.92-py3-none-any.whl", hash = "sha256:f94ae1e056a675bd67c8af98a6858d06e3927d974d6c712ed6e27bb1d11bee1d"}, + {file = "botocore-1.35.92.tar.gz", hash = "sha256:caa7d5d857fed5b3d694b89c45f82b9f938f840e90a4eb7bf50aa65da2ba8f82"}, ] [package.dependencies] @@ -273,13 +279,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -374,127 +380,114 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -513,101 +506,101 @@ files = [ [[package]] name = "cramjam" -version = "2.9.0" +version = "2.9.1" description = "Thin Python bindings to de/compression algorithms in Rust" optional = false python-versions = ">=3.8" files = [ - {file = "cramjam-2.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:eb16d995e454b0155b166f6e6da7df4ac812d44e0f3b6dc0f344a934609fd5bc"}, - {file = "cramjam-2.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cb1e86bfea656b51f2e75f2cedb17fc08b552d105b814d19b595294ecbe94d8d"}, - {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4bd76b654275736fd4f55521981b73751c34dacf70a1dbce96e454a39d43201f"}, - {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21569f19d5848606b85ac0dde0dc3639319d26fed8522c7103515df875bcb300"}, - {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b8f8b1117b4e697d39950ecab01700ce0aef66541e4478eb4d7b3ade8703347b"}, - {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3464d0042a03e8ef38a2b774ef23163cf3c0cdc41b8dfbf7c4aadf93e40b459"}, - {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0711c776750e243ae347d6609c975f0ff4be9ae65b2764d29e4bbdad8e574c3a"}, - {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00d96f798bc980b29f8e1c3ed7d554050e05d4cde23d1633ffed4cd63110024a"}, - {file = "cramjam-2.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fc49b6575e3cb15da3180c5a3926ec81db33b109e48530708da76614b306904b"}, - {file = "cramjam-2.9.0-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:c4fa6c23e56d48df18f534af921ec936c812743a8972ecdd5e5ff47b464fea00"}, - {file = "cramjam-2.9.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b4b8d8160685c11ffb4e8e6daaab79cb351a1c54ceec41cc18a0a62c89309fe0"}, - {file = "cramjam-2.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0ed6362cb6c964f8d0c6e7f790e8961b9242cd3acd87c56169ca14d642653707"}, - {file = "cramjam-2.9.0-cp310-none-win32.whl", hash = "sha256:fe9af350dfbdc7ed4c93a8016a8ad7b5492fc116e7197cad7cbce99b434d3fe1"}, - {file = "cramjam-2.9.0-cp310-none-win_amd64.whl", hash = "sha256:37054c73704a3183b60869e7fec1614648752c31d89f44de1ffe1f01ad4d20d5"}, - {file = "cramjam-2.9.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:170a50407f9400073621cc1d5f3200ca3ad9de3000831e3e86f5561ca8048a08"}, - {file = "cramjam-2.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:912c94781c8ff318a4d3f3306f8d94d41ae5aa7b9760c4bb0476b01142084845"}, - {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:df089639983a03070be6eabc60317aa1ffbf2c5409023b57a5fc2e4975163bc4"}, - {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ca28a8f6ab5fca35f163fd7d7a970880ce4fc1a0bead1249ecdaa96ec9ac1f4"}, - {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:abd8bf9a94e3866215ac181a7dbcfa1ddbedca4f8048494a79934febe88537df"}, - {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7de19a382bcab93cd4d028d51f6f581920a3b79659a384775188135b7fc64f15"}, - {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a4156fcefa1dfaa65d35ff82c252d1e32be12820f26d04748be6cd3b461cf85f"}, - {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4a3104022129d7463100dfaf12efd398ebfa4b7e4e50832ccc596754f7c26df"}, - {file = "cramjam-2.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6ebee5f5d7e2b9277895ea4fd94646b72075fe9cfc0e8f4770b65c9e72b1fec1"}, - {file = "cramjam-2.9.0-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:8e33ebe4d709b21bc15e7ddf485ac6b30d7fdc7ed7c3c65130654c007f50c183"}, - {file = "cramjam-2.9.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4d5a39118008bb9f2fba36a0ceea6c41fbd0b55d2647b043ba51a868e5f6de92"}, - {file = "cramjam-2.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7f6ef35eba883927af2678b561cc4407e0b3b0d58a251c863bec4b3d8258cc2f"}, - {file = "cramjam-2.9.0-cp311-none-win32.whl", hash = "sha256:b21e55b5cfdaff96eae1f323ae9a0d36e86852cdf62fe23b60a2481d2fed5571"}, - {file = "cramjam-2.9.0-cp311-none-win_amd64.whl", hash = "sha256:9f685fe4e49b2f3e233548e3397b3f9189d71a265718ec631d13eca3d5718ddb"}, - {file = "cramjam-2.9.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:34578e4c1518b10dad5e0ba40c721e529ef13e7742a528843b40e1f20dd6078c"}, - {file = "cramjam-2.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1d5b5512dc61ea78f32e021e88a5fd5b46a821409479e6657d33614fc9e45677"}, - {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0b4f1b5e33915ed591c0c19b8c3bbdd7aa0f6a9bfe2b7246b475d497bda15f18"}, - {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad301801afa0eecdacabf353a2802df5e6770f9bfb0a559d6c069813d83cfd42"}, - {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:399baf80fea574e3870f233e12e6a12f02c53b054e13d792348b272b0614370a"}, - {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3121e2fbec58907fa70636adaeaf30c27614c867e08a7a5bd2887b33786ff790"}, - {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd04205b2a87087ffc2257c3ad33f11daabc053956f64ac1ec7bae299cac3f2f"}, - {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddb9c4db36188a8f08c2303100a83100f26a8572803ae35eadff359bebd3d204"}, - {file = "cramjam-2.9.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ef553d4080368006817c1a935ed619c71987cf10417a32386acc00c5418a2934"}, - {file = "cramjam-2.9.0-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:9862ca8ead80857ecfb9b07f02f577733261e981346f31585fe118975eabb738"}, - {file = "cramjam-2.9.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4714e1ea0c3329368b83fe5ad6e831d5ca11fb794ca7cf491622eb6b2d420d2f"}, - {file = "cramjam-2.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1b4ca30c9f27e3b88bc082d4637e7648f93da5cb69a2dbe0c0300bc51353c820"}, - {file = "cramjam-2.9.0-cp312-none-win32.whl", hash = "sha256:0ed2fef010d1caca9ea63814e9cb5b1d47d907b80302b8cc0b3a1e116ea241e2"}, - {file = "cramjam-2.9.0-cp312-none-win_amd64.whl", hash = "sha256:bd26d71939de5dcf169d479fbc7fcfed21e6675bab33e7f7e9f8405f19711c71"}, - {file = "cramjam-2.9.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:dd70ea5d7b2c5e479e04ac3a00d8bc3deca146d2b5dbfbe3d7b42ed136e19de4"}, - {file = "cramjam-2.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b1410e68c464666473a89cade17483b94bb4639d9161c440ee54ee1e0eca583"}, - {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b0078727fe8c28ef1695e5d04aae5c41ac697eb087cba387c6a02b825f9071c0"}, - {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a63c4e63319bf7dfc3ab46c06afb76d3d9cc1c94369b609dde480e5cc78e4de"}, - {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47d7253b5a10c201cc65aecfb517dfa1c0b5831b2524ac32dd2964fceafc0dc4"}, - {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05970fb640f236767003e62c256a085754536169bac863f4a3502ecb59cbf197"}, - {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0b062d261fa3fac00146cf801896c8cfafe1e41332eb047aa0a36558299daa6"}, - {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:017b7066f18b7b676068f51b1dbdecc02d76d9af10092252b22dcbd03a78ed33"}, - {file = "cramjam-2.9.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:9de33ef3bc006c11fbad1dc8b15341dcc78430df2c5ce1e790dfb729b11ab593"}, - {file = "cramjam-2.9.0-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:b99efaf81be8e381de1cde6574e2c89030ed53994e73b0e75b62d6e232f491c5"}, - {file = "cramjam-2.9.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:36426e3f1920f6aa4c644d007bf9cfad06dd9f1a30cd0a921d72b010492d8447"}, - {file = "cramjam-2.9.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ea9bcaff298f5d35ef67346d474fca388c5cf6d4edab1d06b84868800f88bd36"}, - {file = "cramjam-2.9.0-cp313-none-win32.whl", hash = "sha256:c48da60a5eb481b412e5e462b81ad307fb2203178a2840a743f0a7c5fc1718c9"}, - {file = "cramjam-2.9.0-cp313-none-win_amd64.whl", hash = "sha256:97a6311bd32f301ff1b922bc9de62ace3d9fd845e20efc0f71b4d0239a45b8d2"}, - {file = "cramjam-2.9.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:78e7349f945a83bc48855fb042873092a69b155a088b8c11942eb76418b32705"}, - {file = "cramjam-2.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:65a097ea765dd4ef2fb868b5b0959d7c93a64c250b2c52f462898c823ae4b950"}, - {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:35cad507eb02c775e6c5444312f98b28dd8bf122425677ae199484996e838673"}, - {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8982925d179b940efa860513a31b839bb06343501077cca3e67f7a2f7360d355"}, - {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ba7e2d33e1d092dffd0a3ff4bd1b86177594aa3c2901fd478e78e1fb2aee8ed3"}, - {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:904be92e3bc25e78343ee52aa0fd5fba3a31d11d474e8af4623a9d00baa84bc2"}, - {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9221297c547d702e1431e96705fce26c6a87df34a681a6b97fe63b536d09c1d8"}, - {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e98a18c22a85f321091cc8db6694af1d713a369c2d60ec611c10ccfe24ab103a"}, - {file = "cramjam-2.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e248510f8e2dbc71fa99f86238c9023365dbe1a4520eb40e33d73416527349f2"}, - {file = "cramjam-2.9.0-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:dc07376aa33b6004ea372ac9b0ba0ed3455aa2fc4e18727414142ecb46b176b8"}, - {file = "cramjam-2.9.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e94021c541eb2a199b5a2ffae0ea84fb8b99863dab99a5b154b00bc7a44b5c48"}, - {file = "cramjam-2.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4adbf4366f8dc29b7c5c731c800cf633be76c9911e928daeb606827d6ae7c599"}, - {file = "cramjam-2.9.0-cp38-none-win32.whl", hash = "sha256:ca880f555c8db40942acc8a50722c33e229b6be90e598acc1a201f36487b917d"}, - {file = "cramjam-2.9.0-cp38-none-win_amd64.whl", hash = "sha256:ab17a429a92db90bf40115efb97d10e71b94b0dcacf30cf724552df2794a58fb"}, - {file = "cramjam-2.9.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ed7fd7bc2b86ec3161fe0cc49f5f392e6efa55c91a95397d5047820c38117660"}, - {file = "cramjam-2.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a0f654c739a6bc4a69a2aaf31463328a208757ed780ff886234532f78e06a864"}, - {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cd4d4ab9deb5846af0ac6cf1fa139cfa40291ad14d073efa8b8e20c8d1aa90bd"}, - {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bafc32f01d4ab64f83fdbc29bc5bd25a920b59c751c12e06e6f4b1e379be7600"}, - {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0fb5ea631dbf998f667766a9e485e757817d66ed559916ba553a0ec2f902d788"}, - {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c902e56e60c48f5f15e55257aaa1c2678323df5f18a1b839e8d05cac1107576c"}, - {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:441d3875cdffe5df9294b93ef570058837732dd727cd9d18efa0f089f1c2687a"}, - {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed486e57a79ccc7aebaa2ec12517d891fdc5d2fde16915e3db705b8a47570981"}, - {file = "cramjam-2.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:013cb872205641c6e5269f530ed40aaaa5640d84e0d8f33b89f5a1bf7f655527"}, - {file = "cramjam-2.9.0-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:a41b4b10a381be1d42a1a7dd07b8c3faccd3d12c7e98e973a6ec558fd040a607"}, - {file = "cramjam-2.9.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:598eac1713ddbe69c3b30dcc890d69b206ce08903fc3aed58149aae87c61973a"}, - {file = "cramjam-2.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:72e9ebc27c557706a3c9964c1d1b4522857760dbd60c105a4f5421f3b66e31a2"}, - {file = "cramjam-2.9.0-cp39-none-win32.whl", hash = "sha256:dbbd6fba677e1cbc9d6bd4ebbe3e8b3667d0295f1731489db2a971c95f0ceca0"}, - {file = "cramjam-2.9.0-cp39-none-win_amd64.whl", hash = "sha256:7f33a83969fa94ee8e0c1f0aef8eb303ead3e9142338dc543abeb7e1a28734ab"}, - {file = "cramjam-2.9.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:132db7d3346ea21ba44e7ee23ec73bd6fa9eb1e77133ca6dfe1f7449a69999af"}, - {file = "cramjam-2.9.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2addf801c88bead21256ccd87dc97cffead03758c4a4947fad8e454f4abfda0a"}, - {file = "cramjam-2.9.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24afad3ba62774abbb150dc25aab21b047ab999c4143c7a8d96577848baf7af6"}, - {file = "cramjam-2.9.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:604c16052cf29d0c796927ed7e107f65429d2036c82c9a8009bd453c94e5e4f0"}, - {file = "cramjam-2.9.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:65bded20fd2cef17b22246c336ddd67fac842341ee311042b4a70e65dc745aa7"}, - {file = "cramjam-2.9.0.tar.gz", hash = "sha256:f103e648aa3ebe9b8e2c1a3a92719288d8f3f41007c319ad298cdce2d0c28641"}, + {file = "cramjam-2.9.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:8e82464d1e00fbbb12958999b8471ba5e9f3d9711954505a0a7b378762332e6f"}, + {file = "cramjam-2.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d2df8a6511cc08ef1fccd2e0c65e2ebc9f57574ec8376052a76851af5398810"}, + {file = "cramjam-2.9.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:21ea784e6c3f1843d3523ae0f03651dd06058b39eeb64beb82ee3b100fa83662"}, + {file = "cramjam-2.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e0c5d98a4e791f0bbd0ffcb7dae879baeb2dcc357348a8dc2be0a8c10403a2a"}, + {file = "cramjam-2.9.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e076fd87089197cb61117c63dbe7712ad5eccb93968860eb3bae09b767bac813"}, + {file = "cramjam-2.9.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d86b44933aea0151e4a2e1e6935448499849045c38167d288ca4c59d5b8cd4e"}, + {file = "cramjam-2.9.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7eb032549dec897b942ddcf80c1cdccbcb40629f15fc902731dbe6362da49326"}, + {file = "cramjam-2.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf29b4def86ec503e329fe138842a9b79a997e3beb6c7809b05665a0d291edff"}, + {file = "cramjam-2.9.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a36adf7d13b7accfa206e1c917f08924eb905b45aa8e62176509afa7b14db71e"}, + {file = "cramjam-2.9.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:cf4ea758d98b6fad1b4b2d808d0de690d3162ac56c26968aea0af6524e3eb736"}, + {file = "cramjam-2.9.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4826d6d81ea490fa7a3ae7a4b9729866a945ffac1f77fe57b71e49d6e1b21efd"}, + {file = "cramjam-2.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:335103317475bf992953c58838152a4761fc3c87354000edbfc4d7e57cf05909"}, + {file = "cramjam-2.9.1-cp310-cp310-win32.whl", hash = "sha256:258120cb1e3afc3443f756f9de161ed63eed56a2c31f6093e81c571c0f2dc9f6"}, + {file = "cramjam-2.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:c60e5996aa02547d12bc2740d44e90e006b0f93100f53206f7abe6732ad56e69"}, + {file = "cramjam-2.9.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b9db1debe48060e41a5b91af9193c524e473c57f6105462c5524a41f5aabdb88"}, + {file = "cramjam-2.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f6f18f0242212d3409d26ce3874937b5b979cebd61f08b633a6ea893c32fc7b6"}, + {file = "cramjam-2.9.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b5b1cd7d39242b2b903cf09cd4696b3a6e04dc537ffa9f3ac8668edae76eecb6"}, + {file = "cramjam-2.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a47de0a68f5f4d9951250ef5af31f2a7228132caa9ed60994234f7eb98090d33"}, + {file = "cramjam-2.9.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e13c9a697881e5e38148958612dc6856967f5ff8cd7bba5ff751f2d6ac020aa4"}, + {file = "cramjam-2.9.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba560244bc1335b420b74e91e35f9d4e7f307a3be3a4603ce0f0d7e15a0acdf0"}, + {file = "cramjam-2.9.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d47fd41ce260cf4f0ff0e788de961fab9e9c6844a05ce55d06ce31e06107bdc"}, + {file = "cramjam-2.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84d154fbadece82935396eb6bcb502085d944d2fd13b07a94348364344370c2c"}, + {file = "cramjam-2.9.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:038df668ffb94d64d67b6ecc59cbd206745a425ffc0402897dde12d89fa6a870"}, + {file = "cramjam-2.9.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:4125d8cd86fa08495d310e80926c2f0563f157b76862e7479f9b2cf94823ea0c"}, + {file = "cramjam-2.9.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4206ebdd1d1ef0f3f86c8c2f7c426aa4af6094f4f41e274601fd4c4569f37454"}, + {file = "cramjam-2.9.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ab687bef5c493732b9a4ab870542ee43f5eae0025f9c684c7cb399c3a85cb380"}, + {file = "cramjam-2.9.1-cp311-cp311-win32.whl", hash = "sha256:dda7698b6d7caeae1047adafebc4b43b2a82478234f6c2b45bc3edad854e0600"}, + {file = "cramjam-2.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:872b00ff83e84bcbdc7e951af291ebe65eed20b09c47e7c4af21c312f90b796f"}, + {file = "cramjam-2.9.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:79417957972553502b217a0093532e48893c8b4ca30ccc941cefe9c72379df7c"}, + {file = "cramjam-2.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce2b94117f373defc876f88e74e44049a9969223dbca3240415b71752d0422fb"}, + {file = "cramjam-2.9.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:67040e0fd84404885ec716a806bee6110f9960c3647e0ef1670aab3b7375a70a"}, + {file = "cramjam-2.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bedb84e068b53c944bd08dcb501fd00d67daa8a917922356dd559b484ce7eab"}, + {file = "cramjam-2.9.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:06e3f97a379386d97debf08638a78b3d3850fdf6124755eb270b54905a169930"}, + {file = "cramjam-2.9.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11118675e9c7952ececabc62f023290ee4f8ecf0bee0d2c7eb8d1c402ee9769d"}, + {file = "cramjam-2.9.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b7de6b61b11545570e4d6033713f3599525efc615ee353a822be8f6b0c65b77"}, + {file = "cramjam-2.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57ca8f3775324a9de3ee6f05ca172687ba258c0dea79f7e3a6b4112834982f2a"}, + {file = "cramjam-2.9.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9847dd6f288f1c56359f52acb48ff2df848ff3e3bff34d23855bbcf7016427cc"}, + {file = "cramjam-2.9.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d1248dfa7f151e893ce819670f00879e4b7650b8d4c01279ce4f12140d68dd2"}, + {file = "cramjam-2.9.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9da6d970281083bae91b914362de325414aa03c01fc806f6bb2cc006322ec834"}, + {file = "cramjam-2.9.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1c33bc095db5733c841a102b8693062be5db8cdac17b9782ebc00577c6a94480"}, + {file = "cramjam-2.9.1-cp312-cp312-win32.whl", hash = "sha256:9e9193cd4bb57e7acd3af24891526299244bfed88168945efdaa09af4e50720f"}, + {file = "cramjam-2.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:15955dd75e80f66c1ea271167a5347661d9bdc365f894a57698c383c9b7d465c"}, + {file = "cramjam-2.9.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5a7797a2fff994fc5e323f7a967a35a3e37e3006ed21d64dcded086502f482af"}, + {file = "cramjam-2.9.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d51b9b140b1df39a44bff7896d98a10da345b7d5f5ce92368d328c1c2c829167"}, + {file = "cramjam-2.9.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:07ac76b7f992556e7aa910244be11ece578cdf84f4d5d5297461f9a895e18312"}, + {file = "cramjam-2.9.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d90a72608c7550cd7eba914668f6277bfb0b24f074d1f1bd9d061fcb6f2adbd6"}, + {file = "cramjam-2.9.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:56495975401b1821dbe1f29cf222e23556232209a2fdb809fe8156d120ca9c7f"}, + {file = "cramjam-2.9.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b695259e71fde6d5be66b77a4474523ced9ffe9fe8a34cb9b520ec1241a14d3"}, + {file = "cramjam-2.9.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab1e69dc4831bbb79b6d547077aae89074c83e8ad94eba1a3d80e94d2424fd02"}, + {file = "cramjam-2.9.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:440b489902bfb7a26d3fec1ca888007615336ff763d2a32a2fc40586548a0dbf"}, + {file = "cramjam-2.9.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:217fe22b41f8c3dce03852f828b059abfad11d1344a1df2f43d3eb8634b18d75"}, + {file = "cramjam-2.9.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:95f3646ddc98af25af25d5692ae65966488a283813336ea9cf41b22e542e7c0d"}, + {file = "cramjam-2.9.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:6b19fc60ead1cae9795a5b359599da3a1c95d38f869bdfb51c441fd76b04e926"}, + {file = "cramjam-2.9.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:8dc5207567459d049696f62a1fdfb220f3fe6aa0d722285d44753e12504dac6c"}, + {file = "cramjam-2.9.1-cp313-cp313-win32.whl", hash = "sha256:fbfe35929a61b914de9e5dbacde0cfbba86cbf5122f9285a24c14ed0b645490b"}, + {file = "cramjam-2.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:06068bd191a82ad4fc1ac23d6f8627fb5e37ec4be0431711b9a2dbacaccfeddb"}, + {file = "cramjam-2.9.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:6a2ca4d3c683d28d3217821029eb08d3487d5043d7eb455df11ff3cacfd4c916"}, + {file = "cramjam-2.9.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:008b49b455b396acc5459dfb06fb9d56049c4097ee8e590892a4d3da9a711da3"}, + {file = "cramjam-2.9.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:45c18cc13156e8697a8d3f9e57e49a69b00e14a103196efab0893fae1a5257f8"}, + {file = "cramjam-2.9.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d14a0efb21e0fec0631bcd66040b06e6a0fe10825f3aacffded38c1c978bdff9"}, + {file = "cramjam-2.9.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3f815fb0eba625af45139af4f90f5fc2ddda61b171c2cc3ab63d44b40c5c7768"}, + {file = "cramjam-2.9.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04828cbfad7384f06a4a7d0d927c3e85ef11dc5a40b9cf5f3e29ac4e23ecd678"}, + {file = "cramjam-2.9.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0944a7c3a78f940c06d1b29bdce91a17798d80593dd01ebfeb842761e48a8b5"}, + {file = "cramjam-2.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec769e5b16251704502277a1163dcf2611551452d7590ff4cc422b7b0367fc96"}, + {file = "cramjam-2.9.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3ba79c7d2cc5adb897b690c05dd9b67c4d401736d207314b99315f7be3cd94fd"}, + {file = "cramjam-2.9.1-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d35923fb5411bde30b53c0696dff8e24c8a38b010b89544834c53f4462fd71df"}, + {file = "cramjam-2.9.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:da0cc0efdbfb8ee2361f89f38ded03d11678f37e392afff7a97b09c55dadfc83"}, + {file = "cramjam-2.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f89924858712b8b936f04f3d690e72825a3e5127a140b434c79030c1c5a887ce"}, + {file = "cramjam-2.9.1-cp38-cp38-win32.whl", hash = "sha256:5925a738b8478f223ab9756fc794e3cabd5917fd7846f66adcf1d5fc2bf9864c"}, + {file = "cramjam-2.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:b7ac273498a2c6772d67707e101b74014c0d9413bb4711c51d8ec311de59b4b1"}, + {file = "cramjam-2.9.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:af39006faddfc6253beb93ca821d544931cfee7f0177b99ff106dfd8fd6a2cd8"}, + {file = "cramjam-2.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b3291be0d3f73d5774d69013be4ab33978c777363b5312d14f62f77817c2f75a"}, + {file = "cramjam-2.9.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1539fd758f0e57fad7913cebff8baaee871bb561ddf6fa710a427b74da6b6778"}, + {file = "cramjam-2.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff362f68bd68ac0eccb445209238d589bba728fb6d7f2e9dc199e0ec3a61d6e0"}, + {file = "cramjam-2.9.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:23b9786d1d17686fb8d600ade2a19374c7188d4b8867efa9af0d8274a220aec7"}, + {file = "cramjam-2.9.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8bc9c2c748aaf91863d89c4583f529c1c709485c94f8dfeb3ee48662d88e3258"}, + {file = "cramjam-2.9.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd0fa9a0e7f18224b6d2d1d69dbdc3aecec80ef1393c59244159b131604a4395"}, + {file = "cramjam-2.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ceef6e09ee22457997370882aa3c69de01e6dd0aaa2f953e1e87ad11641d042"}, + {file = "cramjam-2.9.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1376f6fdbf0b30712413a0b4e51663a4938ae2f6b449f8e4635dbb3694db83cf"}, + {file = "cramjam-2.9.1-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:342fb946f8d3e9e35b837288b03ab23cfbe0bb5a30e582ed805ef79706823a96"}, + {file = "cramjam-2.9.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a237064a6e2c2256c9a1cf2beb7c971382190c0f1eb2e810e02e971881756132"}, + {file = "cramjam-2.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53145fc9f2319c1245d4329e1da8cfacd6e35e27090c07c0b9d453ae2bbdac3e"}, + {file = "cramjam-2.9.1-cp39-cp39-win32.whl", hash = "sha256:8a9f52c27292c21457f43c4ce124939302a9acfb62295e7cda8667310563a5a3"}, + {file = "cramjam-2.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:8097ee39b61c86848a443c0b25b2df1de6b331fd512b20836a4f5cfde51ab255"}, + {file = "cramjam-2.9.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:86824c695688fcd06c5ac9bbd3fea9bdfb4cca194b1e706fbf11a629df48d2b4"}, + {file = "cramjam-2.9.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:27571bfa5a5d618604696747d0dc1d2a99b5906c967c8dee53c13a7107edfde6"}, + {file = "cramjam-2.9.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb01f6e38719818778144d3165a89ea1ad9dc58c6342b7f20aa194c70f34cbd1"}, + {file = "cramjam-2.9.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b5cef5cf40725fe64592af9ec163e7389855077700678a1d94bec549403a74d"}, + {file = "cramjam-2.9.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ac48b978aa0675f62b642750e798c394a64d25ce852e4e541f69bef9a564c2f0"}, + {file = "cramjam-2.9.1.tar.gz", hash = "sha256:336cc591d86cbd225d256813779f46624f857bc9c779db126271eff9ddc524ae"}, ] [package.extras] @@ -684,20 +677,20 @@ typing-inspect = ">=0.4.0,<1" [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dill" @@ -746,6 +739,20 @@ files = [ {file = "dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e"}, ] +[[package]] +name = "dunamai" +version = "1.23.0" +description = "Dynamic version generation" +optional = false +python-versions = ">=3.5" +files = [ + {file = "dunamai-1.23.0-py3-none-any.whl", hash = "sha256:a0906d876e92441793c6a423e16a4802752e723e9c9a5aabdc5535df02dbe041"}, + {file = "dunamai-1.23.0.tar.gz", hash = "sha256:a163746de7ea5acb6dacdab3a6ad621ebc612ed1e528aaa8beedb8887fccd2c4"}, +] + +[package.dependencies] +packaging = ">=20.9" + [[package]] name = "emoji" version = "2.14.0" @@ -849,13 +856,13 @@ files = [ [[package]] name = "fsspec" -version = "2024.10.0" +version = "2024.12.0" description = "File-system specification" optional = false python-versions = ">=3.8" files = [ - {file = "fsspec-2024.10.0-py3-none-any.whl", hash = "sha256:03b9a6785766a4de40368b88906366755e2819e758b83705c88cd7cb5fe81871"}, - {file = "fsspec-2024.10.0.tar.gz", hash = "sha256:eda2d8a4116d4f2429db8550f2457da57279247dd930bb12f821b58391359493"}, + {file = "fsspec-2024.12.0-py3-none-any.whl", hash = "sha256:b520aed47ad9804237ff878b504267a3b0b441e97508bd6d2d8774e3db85cee2"}, + {file = "fsspec-2024.12.0.tar.gz", hash = "sha256:670700c977ed2fb51e0d9f9253177ed20cbde4a3e5c0283cc5385b5870c8533f"}, ] [package.extras] @@ -909,13 +916,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -930,13 +937,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -944,7 +951,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -955,13 +961,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "huggingface-hub" -version = "0.26.2" +version = "0.27.0" description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" optional = false python-versions = ">=3.8.0" files = [ - {file = "huggingface_hub-0.26.2-py3-none-any.whl", hash = "sha256:98c2a5a8e786c7b2cb6fdeb2740893cba4d53e312572ed3d8afafda65b128c46"}, - {file = "huggingface_hub-0.26.2.tar.gz", hash = "sha256:b100d853465d965733964d123939ba287da60a547087783ddff8a323f340332b"}, + {file = "huggingface_hub-0.27.0-py3-none-any.whl", hash = "sha256:8f2e834517f1f1ddf1ecc716f91b120d7333011b7485f665a9a412eacb1a2a81"}, + {file = "huggingface_hub-0.27.0.tar.gz", hash = "sha256:902cce1a1be5739f5589e560198a65a8edcfd3b830b1666f36e4b961f0454fac"}, ] [package.dependencies] @@ -1028,13 +1034,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -1160,22 +1166,25 @@ six = "*" [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "lxml" version = "5.3.0" @@ -1417,13 +1426,13 @@ files = [ [[package]] name = "marshmallow" -version = "3.23.0" +version = "3.23.3" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." optional = false python-versions = ">=3.9" files = [ - {file = "marshmallow-3.23.0-py3-none-any.whl", hash = "sha256:82f20a2397834fe6d9611b241f2f7e7b680ed89c49f84728a1ad937be6b4bdf4"}, - {file = "marshmallow-3.23.0.tar.gz", hash = "sha256:98d8827a9f10c03d44ead298d2e99c6aea8197df18ccfad360dae7f89a50da2e"}, + {file = "marshmallow-3.23.3-py3-none-any.whl", hash = "sha256:20c0f8c613f68bcb45b2a0d3282e2f172575560170bf220d67aafb42717910e4"}, + {file = "marshmallow-3.23.3.tar.gz", hash = "sha256:d586c8685ebdb80bf754e1f96e3f305aaf30951f1fc69175b977453633467e76"}, ] [package.dependencies] @@ -1431,7 +1440,7 @@ packaging = ">=17.0" [package.extras] dev = ["marshmallow[tests]", "pre-commit (>=3.5,<5.0)", "tox"] -docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.13)", "sphinx (==8.1.3)", "sphinx-issues (==5.0.0)", "sphinx-version-warning (==1.1.2)"] +docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.14)", "sphinx (==8.1.3)", "sphinx-issues (==5.0.0)"] tests = ["pytest", "simplejson"] [[package]] @@ -1561,69 +1570,86 @@ files = [ [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -1779,93 +1805,89 @@ pytzdata = ">=2020.1" [[package]] name = "pillow" -version = "11.0.0" +version = "11.1.0" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.9" files = [ - {file = "pillow-11.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947"}, - {file = "pillow-11.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba"}, - {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086"}, - {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9"}, - {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488"}, - {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f"}, - {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb"}, - {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97"}, - {file = "pillow-11.0.0-cp310-cp310-win32.whl", hash = "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50"}, - {file = "pillow-11.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c"}, - {file = "pillow-11.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1"}, - {file = "pillow-11.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc"}, - {file = "pillow-11.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a"}, - {file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3"}, - {file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5"}, - {file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b"}, - {file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa"}, - {file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306"}, - {file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9"}, - {file = "pillow-11.0.0-cp311-cp311-win32.whl", hash = "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5"}, - {file = "pillow-11.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291"}, - {file = "pillow-11.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9"}, - {file = "pillow-11.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923"}, - {file = "pillow-11.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903"}, - {file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4"}, - {file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f"}, - {file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9"}, - {file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7"}, - {file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6"}, - {file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc"}, - {file = "pillow-11.0.0-cp312-cp312-win32.whl", hash = "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6"}, - {file = "pillow-11.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47"}, - {file = "pillow-11.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25"}, - {file = "pillow-11.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcd1fb5bb7b07f64c15618c89efcc2cfa3e95f0e3bcdbaf4642509de1942a699"}, - {file = "pillow-11.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e038b0745997c7dcaae350d35859c9715c71e92ffb7e0f4a8e8a16732150f38"}, - {file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ae08bd8ffc41aebf578c2af2f9d8749d91f448b3bfd41d7d9ff573d74f2a6b2"}, - {file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d69bfd8ec3219ae71bcde1f942b728903cad25fafe3100ba2258b973bd2bc1b2"}, - {file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:61b887f9ddba63ddf62fd02a3ba7add935d053b6dd7d58998c630e6dbade8527"}, - {file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:c6a660307ca9d4867caa8d9ca2c2658ab685de83792d1876274991adec7b93fa"}, - {file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:73e3a0200cdda995c7e43dd47436c1548f87a30bb27fb871f352a22ab8dcf45f"}, - {file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fba162b8872d30fea8c52b258a542c5dfd7b235fb5cb352240c8d63b414013eb"}, - {file = "pillow-11.0.0-cp313-cp313-win32.whl", hash = "sha256:f1b82c27e89fffc6da125d5eb0ca6e68017faf5efc078128cfaa42cf5cb38798"}, - {file = "pillow-11.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ba470552b48e5835f1d23ecb936bb7f71d206f9dfeee64245f30c3270b994de"}, - {file = "pillow-11.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:846e193e103b41e984ac921b335df59195356ce3f71dcfd155aa79c603873b84"}, - {file = "pillow-11.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4ad70c4214f67d7466bea6a08061eba35c01b1b89eaa098040a35272a8efb22b"}, - {file = "pillow-11.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6ec0d5af64f2e3d64a165f490d96368bb5dea8b8f9ad04487f9ab60dc4bb6003"}, - {file = "pillow-11.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c809a70e43c7977c4a42aefd62f0131823ebf7dd73556fa5d5950f5b354087e2"}, - {file = "pillow-11.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:4b60c9520f7207aaf2e1d94de026682fc227806c6e1f55bba7606d1c94dd623a"}, - {file = "pillow-11.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1e2688958a840c822279fda0086fec1fdab2f95bf2b717b66871c4ad9859d7e8"}, - {file = "pillow-11.0.0-cp313-cp313t-win32.whl", hash = "sha256:607bbe123c74e272e381a8d1957083a9463401f7bd01287f50521ecb05a313f8"}, - {file = "pillow-11.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c39ed17edea3bc69c743a8dd3e9853b7509625c2462532e62baa0732163a904"}, - {file = "pillow-11.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3"}, - {file = "pillow-11.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2e46773dc9f35a1dd28bd6981332fd7f27bec001a918a72a79b4133cf5291dba"}, - {file = "pillow-11.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2679d2258b7f1192b378e2893a8a0a0ca472234d4c2c0e6bdd3380e8dfa21b6a"}, - {file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eda2616eb2313cbb3eebbe51f19362eb434b18e3bb599466a1ffa76a033fb916"}, - {file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ec184af98a121fb2da42642dea8a29ec80fc3efbaefb86d8fdd2606619045d"}, - {file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:8594f42df584e5b4bb9281799698403f7af489fba84c34d53d1c4bfb71b7c4e7"}, - {file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:c12b5ae868897c7338519c03049a806af85b9b8c237b7d675b8c5e089e4a618e"}, - {file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:70fbbdacd1d271b77b7721fe3cdd2d537bbbd75d29e6300c672ec6bb38d9672f"}, - {file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5178952973e588b3f1360868847334e9e3bf49d19e169bbbdfaf8398002419ae"}, - {file = "pillow-11.0.0-cp39-cp39-win32.whl", hash = "sha256:8c676b587da5673d3c75bd67dd2a8cdfeb282ca38a30f37950511766b26858c4"}, - {file = "pillow-11.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:94f3e1780abb45062287b4614a5bc0874519c86a777d4a7ad34978e86428b8dd"}, - {file = "pillow-11.0.0-cp39-cp39-win_arm64.whl", hash = "sha256:290f2cc809f9da7d6d622550bbf4c1e57518212da51b6a30fe8e0a270a5b78bd"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734"}, - {file = "pillow-11.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316"}, - {file = "pillow-11.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5bd2d3bdb846d757055910f0a59792d33b555800813c3b39ada1829c372ccb06"}, - {file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:375b8dd15a1f5d2feafff536d47e22f69625c1aa92f12b339ec0b2ca40263273"}, - {file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:daffdf51ee5db69a82dd127eabecce20729e21f7a3680cf7cbb23f0829189790"}, - {file = "pillow-11.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7326a1787e3c7b0429659e0a944725e1b03eeaa10edd945a86dead1913383944"}, - {file = "pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739"}, + {file = "pillow-11.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:e1abe69aca89514737465752b4bcaf8016de61b3be1397a8fc260ba33321b3a8"}, + {file = "pillow-11.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c640e5a06869c75994624551f45e5506e4256562ead981cce820d5ab39ae2192"}, + {file = "pillow-11.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a07dba04c5e22824816b2615ad7a7484432d7f540e6fa86af60d2de57b0fcee2"}, + {file = "pillow-11.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e267b0ed063341f3e60acd25c05200df4193e15a4a5807075cd71225a2386e26"}, + {file = "pillow-11.1.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:bd165131fd51697e22421d0e467997ad31621b74bfc0b75956608cb2906dda07"}, + {file = "pillow-11.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:abc56501c3fd148d60659aae0af6ddc149660469082859fa7b066a298bde9482"}, + {file = "pillow-11.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:54ce1c9a16a9561b6d6d8cb30089ab1e5eb66918cb47d457bd996ef34182922e"}, + {file = "pillow-11.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:73ddde795ee9b06257dac5ad42fcb07f3b9b813f8c1f7f870f402f4dc54b5269"}, + {file = "pillow-11.1.0-cp310-cp310-win32.whl", hash = "sha256:3a5fe20a7b66e8135d7fd617b13272626a28278d0e578c98720d9ba4b2439d49"}, + {file = "pillow-11.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:b6123aa4a59d75f06e9dd3dac5bf8bc9aa383121bb3dd9a7a612e05eabc9961a"}, + {file = "pillow-11.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:a76da0a31da6fcae4210aa94fd779c65c75786bc9af06289cd1c184451ef7a65"}, + {file = "pillow-11.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:e06695e0326d05b06833b40b7ef477e475d0b1ba3a6d27da1bb48c23209bf457"}, + {file = "pillow-11.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96f82000e12f23e4f29346e42702b6ed9a2f2fea34a740dd5ffffcc8c539eb35"}, + {file = "pillow-11.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3cd561ded2cf2bbae44d4605837221b987c216cff94f49dfeed63488bb228d2"}, + {file = "pillow-11.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f189805c8be5ca5add39e6f899e6ce2ed824e65fb45f3c28cb2841911da19070"}, + {file = "pillow-11.1.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:dd0052e9db3474df30433f83a71b9b23bd9e4ef1de13d92df21a52c0303b8ab6"}, + {file = "pillow-11.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:837060a8599b8f5d402e97197d4924f05a2e0d68756998345c829c33186217b1"}, + {file = "pillow-11.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:aa8dd43daa836b9a8128dbe7d923423e5ad86f50a7a14dc688194b7be5c0dea2"}, + {file = "pillow-11.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0a2f91f8a8b367e7a57c6e91cd25af510168091fb89ec5146003e424e1558a96"}, + {file = "pillow-11.1.0-cp311-cp311-win32.whl", hash = "sha256:c12fc111ef090845de2bb15009372175d76ac99969bdf31e2ce9b42e4b8cd88f"}, + {file = "pillow-11.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fbd43429d0d7ed6533b25fc993861b8fd512c42d04514a0dd6337fb3ccf22761"}, + {file = "pillow-11.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:f7955ecf5609dee9442cbface754f2c6e541d9e6eda87fad7f7a989b0bdb9d71"}, + {file = "pillow-11.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2062ffb1d36544d42fcaa277b069c88b01bb7298f4efa06731a7fd6cc290b81a"}, + {file = "pillow-11.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a85b653980faad27e88b141348707ceeef8a1186f75ecc600c395dcac19f385b"}, + {file = "pillow-11.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9409c080586d1f683df3f184f20e36fb647f2e0bc3988094d4fd8c9f4eb1b3b3"}, + {file = "pillow-11.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fdadc077553621911f27ce206ffcbec7d3f8d7b50e0da39f10997e8e2bb7f6a"}, + {file = "pillow-11.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:93a18841d09bcdd774dcdc308e4537e1f867b3dec059c131fde0327899734aa1"}, + {file = "pillow-11.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9aa9aeddeed452b2f616ff5507459e7bab436916ccb10961c4a382cd3e03f47f"}, + {file = "pillow-11.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3cdcdb0b896e981678eee140d882b70092dac83ac1cdf6b3a60e2216a73f2b91"}, + {file = "pillow-11.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:36ba10b9cb413e7c7dfa3e189aba252deee0602c86c309799da5a74009ac7a1c"}, + {file = "pillow-11.1.0-cp312-cp312-win32.whl", hash = "sha256:cfd5cd998c2e36a862d0e27b2df63237e67273f2fc78f47445b14e73a810e7e6"}, + {file = "pillow-11.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:a697cd8ba0383bba3d2d3ada02b34ed268cb548b369943cd349007730c92bddf"}, + {file = "pillow-11.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:4dd43a78897793f60766563969442020e90eb7847463eca901e41ba186a7d4a5"}, + {file = "pillow-11.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae98e14432d458fc3de11a77ccb3ae65ddce70f730e7c76140653048c71bfcbc"}, + {file = "pillow-11.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc1331b6d5a6e144aeb5e626f4375f5b7ae9934ba620c0ac6b3e43d5e683a0f0"}, + {file = "pillow-11.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:758e9d4ef15d3560214cddbc97b8ef3ef86ce04d62ddac17ad39ba87e89bd3b1"}, + {file = "pillow-11.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b523466b1a31d0dcef7c5be1f20b942919b62fd6e9a9be199d035509cbefc0ec"}, + {file = "pillow-11.1.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:9044b5e4f7083f209c4e35aa5dd54b1dd5b112b108648f5c902ad586d4f945c5"}, + {file = "pillow-11.1.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:3764d53e09cdedd91bee65c2527815d315c6b90d7b8b79759cc48d7bf5d4f114"}, + {file = "pillow-11.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31eba6bbdd27dde97b0174ddf0297d7a9c3a507a8a1480e1e60ef914fe23d352"}, + {file = "pillow-11.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b5d658fbd9f0d6eea113aea286b21d3cd4d3fd978157cbf2447a6035916506d3"}, + {file = "pillow-11.1.0-cp313-cp313-win32.whl", hash = "sha256:f86d3a7a9af5d826744fabf4afd15b9dfef44fe69a98541f666f66fbb8d3fef9"}, + {file = "pillow-11.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:593c5fd6be85da83656b93ffcccc2312d2d149d251e98588b14fbc288fd8909c"}, + {file = "pillow-11.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:11633d58b6ee5733bde153a8dafd25e505ea3d32e261accd388827ee987baf65"}, + {file = "pillow-11.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:70ca5ef3b3b1c4a0812b5c63c57c23b63e53bc38e758b37a951e5bc466449861"}, + {file = "pillow-11.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8000376f139d4d38d6851eb149b321a52bb8893a88dae8ee7d95840431977081"}, + {file = "pillow-11.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee85f0696a17dd28fbcfceb59f9510aa71934b483d1f5601d1030c3c8304f3c"}, + {file = "pillow-11.1.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:dd0e081319328928531df7a0e63621caf67652c8464303fd102141b785ef9547"}, + {file = "pillow-11.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e63e4e5081de46517099dc30abe418122f54531a6ae2ebc8680bcd7096860eab"}, + {file = "pillow-11.1.0-cp313-cp313t-win32.whl", hash = "sha256:dda60aa465b861324e65a78c9f5cf0f4bc713e4309f83bc387be158b077963d9"}, + {file = "pillow-11.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ad5db5781c774ab9a9b2c4302bbf0c1014960a0a7be63278d13ae6fdf88126fe"}, + {file = "pillow-11.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756"}, + {file = "pillow-11.1.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:bf902d7413c82a1bfa08b06a070876132a5ae6b2388e2712aab3a7cbc02205c6"}, + {file = "pillow-11.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c1eec9d950b6fe688edee07138993e54ee4ae634c51443cfb7c1e7613322718e"}, + {file = "pillow-11.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e275ee4cb11c262bd108ab2081f750db2a1c0b8c12c1897f27b160c8bd57bbc"}, + {file = "pillow-11.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4db853948ce4e718f2fc775b75c37ba2efb6aaea41a1a5fc57f0af59eee774b2"}, + {file = "pillow-11.1.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:ab8a209b8485d3db694fa97a896d96dd6533d63c22829043fd9de627060beade"}, + {file = "pillow-11.1.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:54251ef02a2309b5eec99d151ebf5c9904b77976c8abdcbce7891ed22df53884"}, + {file = "pillow-11.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5bb94705aea800051a743aa4874bb1397d4695fb0583ba5e425ee0328757f196"}, + {file = "pillow-11.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:89dbdb3e6e9594d512780a5a1c42801879628b38e3efc7038094430844e271d8"}, + {file = "pillow-11.1.0-cp39-cp39-win32.whl", hash = "sha256:e5449ca63da169a2e6068dd0e2fcc8d91f9558aba89ff6d02121ca8ab11e79e5"}, + {file = "pillow-11.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:3362c6ca227e65c54bf71a5f88b3d4565ff1bcbc63ae72c34b07bbb1cc59a43f"}, + {file = "pillow-11.1.0-cp39-cp39-win_arm64.whl", hash = "sha256:b20be51b37a75cc54c2c55def3fa2c65bb94ba859dde241cd0a4fd302de5ae0a"}, + {file = "pillow-11.1.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8c730dc3a83e5ac137fbc92dfcfe1511ce3b2b5d7578315b63dbbb76f7f51d90"}, + {file = "pillow-11.1.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:7d33d2fae0e8b170b6a6c57400e077412240f6f5bb2a342cf1ee512a787942bb"}, + {file = "pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8d65b38173085f24bc07f8b6c505cbb7418009fa1a1fcb111b1f4961814a442"}, + {file = "pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:015c6e863faa4779251436db398ae75051469f7c903b043a48f078e437656f83"}, + {file = "pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d44ff19eea13ae4acdaaab0179fa68c0c6f2f45d66a4d8ec1eda7d6cecbcc15f"}, + {file = "pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d3d8da4a631471dfaf94c10c85f5277b1f8e42ac42bade1ac67da4b4a7359b73"}, + {file = "pillow-11.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:4637b88343166249fe8aa94e7c4a62a180c4b3898283bb5d3d2fd5fe10d8e4e0"}, + {file = "pillow-11.1.0.tar.gz", hash = "sha256:368da70808b36d73b4b390a8ffac11069f8a5c85f29eff1f1b01bcf3ef5b2a20"}, ] [package.extras] docs = ["furo", "olefile", "sphinx (>=8.1)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] fpx = ["olefile"] mic = ["olefile"] -tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "trove-classifiers (>=2024.10.12)"] typing = ["typing-extensions"] xmp = ["defusedxml"] @@ -1900,6 +1922,36 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "psutil" +version = "6.1.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, +] + +[package.extras] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + [[package]] name = "py" version = "1.11.0" @@ -1972,19 +2024,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1992,100 +2044,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -2093,13 +2156,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -2412,6 +2475,20 @@ files = [ [package.dependencies] cramjam = "*" +[[package]] +name = "python-ulid" +version = "3.0.0" +description = "Universally unique lexicographically sortable identifier" +optional = false +python-versions = ">=3.9" +files = [ + {file = "python_ulid-3.0.0-py3-none-any.whl", hash = "sha256:e4c4942ff50dbd79167ad01ac725ec58f924b4018025ce22c858bfcff99a5e31"}, + {file = "python_ulid-3.0.0.tar.gz", hash = "sha256:e50296a47dc8209d28629a22fc81ca26c00982c78934bd7766377ba37ea49a9f"}, +] + +[package.extras] +pydantic = ["pydantic (>=2.0)"] + [[package]] name = "pytz" version = "2024.1" @@ -2525,99 +2602,99 @@ files = [ [[package]] name = "rapidfuzz" -version = "3.10.1" +version = "3.11.0" description = "rapid fuzzy string matching" optional = false python-versions = ">=3.9" files = [ - {file = "rapidfuzz-3.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f17d9f21bf2f2f785d74f7b0d407805468b4c173fa3e52c86ec94436b338e74a"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b31f358a70efc143909fb3d75ac6cd3c139cd41339aa8f2a3a0ead8315731f2b"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f4f43f2204b56a61448ec2dd061e26fd344c404da99fb19f3458200c5874ba2"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d81bf186a453a2757472133b24915768abc7c3964194406ed93e170e16c21cb"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3611c8f45379a12063d70075c75134f2a8bd2e4e9b8a7995112ddae95ca1c982"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c3b537b97ac30da4b73930fa8a4fe2f79c6d1c10ad535c5c09726612cd6bed9"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:231ef1ec9cf7b59809ce3301006500b9d564ddb324635f4ea8f16b3e2a1780da"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ed4f3adc1294834955b7e74edd3c6bd1aad5831c007f2d91ea839e76461a5879"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:7b6015da2e707bf632a71772a2dbf0703cff6525732c005ad24987fe86e8ec32"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1b35a118d61d6f008e8e3fb3a77674d10806a8972c7b8be433d6598df4d60b01"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:bc308d79a7e877226f36bdf4e149e3ed398d8277c140be5c1fd892ec41739e6d"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f017dbfecc172e2d0c37cf9e3d519179d71a7f16094b57430dffc496a098aa17"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-win32.whl", hash = "sha256:36c0e1483e21f918d0f2f26799fe5ac91c7b0c34220b73007301c4f831a9c4c7"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:10746c1d4c8cd8881c28a87fd7ba0c9c102346dfe7ff1b0d021cdf093e9adbff"}, - {file = "rapidfuzz-3.10.1-cp310-cp310-win_arm64.whl", hash = "sha256:dfa64b89dcb906835e275187569e51aa9d546a444489e97aaf2cc84011565fbe"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:92958ae075c87fef393f835ed02d4fe8d5ee2059a0934c6c447ea3417dfbf0e8"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ba7521e072c53e33c384e78615d0718e645cab3c366ecd3cc8cb732befd94967"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d02cbd75d283c287471b5b3738b3e05c9096150f93f2d2dfa10b3d700f2db9"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:efa1582a397da038e2f2576c9cd49b842f56fde37d84a6b0200ffebc08d82350"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f12912acee1f506f974f58de9fdc2e62eea5667377a7e9156de53241c05fdba8"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666d5d8b17becc3f53447bcb2b6b33ce6c2df78792495d1fa82b2924cd48701a"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26f71582c0d62445067ee338ddad99b655a8f4e4ed517a90dcbfbb7d19310474"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8a2ef08b27167bcff230ffbfeedd4c4fa6353563d6aaa015d725dd3632fc3de7"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:365e4fc1a2b95082c890f5e98489b894e6bf8c338c6ac89bb6523c2ca6e9f086"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1996feb7a61609fa842e6b5e0c549983222ffdedaf29644cc67e479902846dfe"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:cf654702f144beaa093103841a2ea6910d617d0bb3fccb1d1fd63c54dde2cd49"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec108bf25de674781d0a9a935030ba090c78d49def3d60f8724f3fc1e8e75024"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-win32.whl", hash = "sha256:031f8b367e5d92f7a1e27f7322012f3c321c3110137b43cc3bf678505583ef48"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:f98f36c6a1bb9a6c8bbec99ad87c8c0e364f34761739b5ea9adf7b48129ae8cf"}, - {file = "rapidfuzz-3.10.1-cp311-cp311-win_arm64.whl", hash = "sha256:f1da2028cb4e41be55ee797a82d6c1cf589442504244249dfeb32efc608edee7"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1340b56340896bede246f612b6ecf685f661a56aabef3d2512481bfe23ac5835"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2316515169b7b5a453f0ce3adbc46c42aa332cae9f2edb668e24d1fc92b2f2bb"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e06fe6a12241ec1b72c0566c6b28cda714d61965d86569595ad24793d1ab259"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d99c1cd9443b19164ec185a7d752f4b4db19c066c136f028991a480720472e23"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1d9aa156ed52d3446388ba4c2f335e312191d1ca9d1f5762ee983cf23e4ecf6"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:54bcf4efaaee8e015822be0c2c28214815f4f6b4f70d8362cfecbd58a71188ac"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0c955e32afdbfdf6e9ee663d24afb25210152d98c26d22d399712d29a9b976b"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:191633722203f5b7717efcb73a14f76f3b124877d0608c070b827c5226d0b972"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:195baad28057ec9609e40385991004e470af9ef87401e24ebe72c064431524ab"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0fff4a6b87c07366662b62ae994ffbeadc472e72f725923f94b72a3db49f4671"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4ffed25f9fdc0b287f30a98467493d1e1ce5b583f6317f70ec0263b3c97dbba6"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d02cf8e5af89a9ac8f53c438ddff6d773f62c25c6619b29db96f4aae248177c0"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-win32.whl", hash = "sha256:f3bb81d4fe6a5d20650f8c0afcc8f6e1941f6fecdb434f11b874c42467baded0"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:aaf83e9170cb1338922ae42d320699dccbbdca8ffed07faeb0b9257822c26e24"}, - {file = "rapidfuzz-3.10.1-cp312-cp312-win_arm64.whl", hash = "sha256:c5da802a0d085ad81b0f62828fb55557996c497b2d0b551bbdfeafd6d447892f"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fc22d69a1c9cccd560a5c434c0371b2df0f47c309c635a01a913e03bbf183710"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38b0dac2c8e057562b8f0d8ae5b663d2d6a28c5ab624de5b73cef9abb6129a24"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fde3bbb14e92ce8fcb5c2edfff72e474d0080cadda1c97785bf4822f037a309"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9141fb0592e55f98fe9ac0f3ce883199b9c13e262e0bf40c5b18cdf926109d16"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:237bec5dd1bfc9b40bbd786cd27949ef0c0eb5fab5eb491904c6b5df59d39d3c"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18123168cba156ab5794ea6de66db50f21bb3c66ae748d03316e71b27d907b95"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b75fe506c8e02769cc47f5ab21ce3e09b6211d3edaa8f8f27331cb6988779be"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9da82aa4b46973aaf9e03bb4c3d6977004648c8638febfc0f9d237e865761270"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c34c022d5ad564f1a5a57a4a89793bd70d7bad428150fb8ff2760b223407cdcf"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1e96c84d6c2a0ca94e15acb5399118fff669f4306beb98a6d8ec6f5dccab4412"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e8e154b84a311263e1aca86818c962e1fa9eefdd643d1d5d197fcd2738f88cb9"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:335fee93188f8cd585552bb8057228ce0111bd227fa81bfd40b7df6b75def8ab"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-win32.whl", hash = "sha256:6729b856166a9e95c278410f73683957ea6100c8a9d0a8dbe434c49663689255"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-win_amd64.whl", hash = "sha256:0e06d99ad1ad97cb2ef7f51ec6b1fedd74a3a700e4949353871cf331d07b382a"}, - {file = "rapidfuzz-3.10.1-cp313-cp313-win_arm64.whl", hash = "sha256:8d1b7082104d596a3eb012e0549b2634ed15015b569f48879701e9d8db959dbb"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:779027d3307e1a2b1dc0c03c34df87a470a368a1a0840a9d2908baf2d4067956"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:440b5608ab12650d0390128d6858bc839ae77ffe5edf0b33a1551f2fa9860651"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cac41a411e07a6f3dc80dfbd33f6be70ea0abd72e99c59310819d09f07d945"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:958473c9f0bca250590200fd520b75be0dbdbc4a7327dc87a55b6d7dc8d68552"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ef60dfa73749ef91cb6073be1a3e135f4846ec809cc115f3cbfc6fe283a5584"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7fbac18f2c19fc983838a60611e67e3262e36859994c26f2ee85bb268de2355"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a0d519ff39db887cd73f4e297922786d548f5c05d6b51f4e6754f452a7f4296"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bebb7bc6aeb91cc57e4881b222484c26759ca865794187217c9dcea6c33adae6"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fe07f8b9c3bb5c5ad1d2c66884253e03800f4189a60eb6acd6119ebaf3eb9894"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:bfa48a4a2d45a41457f0840c48e579db157a927f4e97acf6e20df8fc521c79de"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2cf44d01bfe8ee605b7eaeecbc2b9ca64fc55765f17b304b40ed8995f69d7716"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e6bbca9246d9eedaa1c84e04a7f555493ba324d52ae4d9f3d9ddd1b740dcd87"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-win32.whl", hash = "sha256:567f88180f2c1423b4fe3f3ad6e6310fc97b85bdba574801548597287fc07028"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:6b2cd7c29d6ecdf0b780deb587198f13213ac01c430ada6913452fd0c40190fc"}, - {file = "rapidfuzz-3.10.1-cp39-cp39-win_arm64.whl", hash = "sha256:9f912d459e46607ce276128f52bea21ebc3e9a5ccf4cccfef30dd5bddcf47be8"}, - {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ac4452f182243cfab30ba4668ef2de101effaedc30f9faabb06a095a8c90fd16"}, - {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:565c2bd4f7d23c32834652b27b51dd711814ab614b4e12add8476be4e20d1cf5"}, - {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:187d9747149321607be4ccd6f9f366730078bed806178ec3eeb31d05545e9e8f"}, - {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:616290fb9a8fa87e48cb0326d26f98d4e29f17c3b762c2d586f2b35c1fd2034b"}, - {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:073a5b107e17ebd264198b78614c0206fa438cce749692af5bc5f8f484883f50"}, - {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:39c4983e2e2ccb9732f3ac7d81617088822f4a12291d416b09b8a1eadebb3e29"}, - {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ac7adee6bcf0c6fee495d877edad1540a7e0f5fc208da03ccb64734b43522d7a"}, - {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:425f4ac80b22153d391ee3f94bc854668a0c6c129f05cf2eaf5ee74474ddb69e"}, - {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65a2fa13e8a219f9b5dcb9e74abe3ced5838a7327e629f426d333dfc8c5a6e66"}, - {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75561f3df9a906aaa23787e9992b228b1ab69007932dc42070f747103e177ba8"}, - {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:edd062490537e97ca125bc6c7f2b7331c2b73d21dc304615afe61ad1691e15d5"}, - {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfcc8feccf63245a22dfdd16e222f1a39771a44b870beb748117a0e09cbb4a62"}, - {file = "rapidfuzz-3.10.1.tar.gz", hash = "sha256:5a15546d847a915b3f42dc79ef9b0c78b998b4e2c53b252e7166284066585979"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eb8a54543d16ab1b69e2c5ed96cabbff16db044a50eddfc028000138ca9ddf33"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:231c8b2efbd7f8d2ecd1ae900363ba168b8870644bb8f2b5aa96e4a7573bde19"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54e7f442fb9cca81e9df32333fb075ef729052bcabe05b0afc0441f462299114"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:906f1f2a1b91c06599b3dd1be207449c5d4fc7bd1e1fa2f6aef161ea6223f165"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed59044aea9eb6c663112170f2399b040d5d7b162828b141f2673e822093fa8"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cb1965a28b0fa64abdee130c788a0bc0bb3cf9ef7e3a70bf055c086c14a3d7e"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b488b244931d0291412917e6e46ee9f6a14376625e150056fe7c4426ef28225"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f0ba13557fec9d5ffc0a22826754a7457cc77f1b25145be10b7bb1d143ce84c6"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3871fa7dfcef00bad3c7e8ae8d8fd58089bad6fb21f608d2bf42832267ca9663"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b2669eafee38c5884a6e7cc9769d25c19428549dcdf57de8541cf9e82822e7db"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ffa1bb0e26297b0f22881b219ffc82a33a3c84ce6174a9d69406239b14575bd5"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:45b15b8a118856ac9caac6877f70f38b8a0d310475d50bc814698659eabc1cdb"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win32.whl", hash = "sha256:22033677982b9c4c49676f215b794b0404073f8974f98739cb7234e4a9ade9ad"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:be15496e7244361ff0efcd86e52559bacda9cd975eccf19426a0025f9547c792"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_arm64.whl", hash = "sha256:714a7ba31ba46b64d30fccfe95f8013ea41a2e6237ba11a805a27cdd3bce2573"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8724a978f8af7059c5323d523870bf272a097478e1471295511cf58b2642ff83"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b63cb1f2eb371ef20fb155e95efd96e060147bdd4ab9fc400c97325dfee9fe1"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82497f244aac10b20710448645f347d862364cc4f7d8b9ba14bd66b5ce4dec18"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:339607394941801e6e3f6c1ecd413a36e18454e7136ed1161388de674f47f9d9"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84819390a36d6166cec706b9d8f0941f115f700b7faecab5a7e22fc367408bc3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eea8d9e20632d68f653455265b18c35f90965e26f30d4d92f831899d6682149b"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b659e1e2ea2784a9a397075a7fc395bfa4fe66424042161c4bcaf6e4f637b38"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1315cd2a351144572e31fe3df68340d4b83ddec0af8b2e207cd32930c6acd037"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a7743cca45b4684c54407e8638f6d07b910d8d811347b9d42ff21262c7c23245"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:5bb636b0150daa6d3331b738f7c0f8b25eadc47f04a40e5c23c4bfb4c4e20ae3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:42f4dd264ada7a9aa0805ea0da776dc063533917773cf2df5217f14eb4429eae"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:51f24cb39e64256221e6952f22545b8ce21cacd59c0d3e367225da8fc4b868d8"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win32.whl", hash = "sha256:aaf391fb6715866bc14681c76dc0308f46877f7c06f61d62cc993b79fc3c4a2a"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:ebadd5b8624d8ad503e505a99b8eb26fe3ea9f8e9c2234e805a27b269e585842"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:d895998fec712544c13cfe833890e0226585cf0391dd3948412441d5d68a2b8c"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f382fec4a7891d66fb7163c90754454030bb9200a13f82ee7860b6359f3f2fa8"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dfaefe08af2a928e72344c800dcbaf6508e86a4ed481e28355e8d4b6a6a5230e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92ebb7c12f682b5906ed98429f48a3dd80dd0f9721de30c97a01473d1a346576"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a1b3ebc62d4bcdfdeba110944a25ab40916d5383c5e57e7c4a8dc0b6c17211a"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c6d7fea39cb33e71de86397d38bf7ff1a6273e40367f31d05761662ffda49e4"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99aebef8268f2bc0b445b5640fd3312e080bd17efd3fbae4486b20ac00466308"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4469307f464ae3089acf3210b8fc279110d26d10f79e576f385a98f4429f7d97"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:eb97c53112b593f89a90b4f6218635a9d1eea1d7f9521a3b7d24864228bbc0aa"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef8937dae823b889c0273dfa0f0f6c46a3658ac0d851349c464d1b00e7ff4252"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d95f9e9f3777b96241d8a00d6377cc9c716981d828b5091082d0fe3a2924b43e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:b1d67d67f89e4e013a5295e7523bc34a7a96f2dba5dd812c7c8cb65d113cbf28"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d994cf27e2f874069884d9bddf0864f9b90ad201fcc9cb2f5b82bacc17c8d5f2"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win32.whl", hash = "sha256:ba26d87fe7fcb56c4a53b549a9e0e9143f6b0df56d35fe6ad800c902447acd5b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:b1f7efdd7b7adb32102c2fa481ad6f11923e2deb191f651274be559d56fc913b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:ed78c8e94f57b44292c1a0350f580e18d3a3c5c0800e253f1583580c1b417ad2"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e60814edd0c9b511b5f377d48b9782b88cfe8be07a98f99973669299c8bb318a"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f28952da055dbfe75828891cd3c9abf0984edc8640573c18b48c14c68ca5e06"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e8f93bc736020351a6f8e71666e1f486bb8bd5ce8112c443a30c77bfde0eb68"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76a4a11ba8f678c9e5876a7d465ab86def047a4fcc043617578368755d63a1bc"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc0e0d41ad8a056a9886bac91ff9d9978e54a244deb61c2972cc76b66752de9c"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e8ea35f2419c7d56b3e75fbde2698766daedb374f20eea28ac9b1f668ef4f74"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd340bbd025302276b5aa221dccfe43040c7babfc32f107c36ad783f2ffd8775"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:494eef2c68305ab75139034ea25328a04a548d297712d9cf887bf27c158c388b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5a167344c1d6db06915fb0225592afdc24d8bafaaf02de07d4788ddd37f4bc2f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8c7af25bda96ac799378ac8aba54a8ece732835c7b74cfc201b688a87ed11152"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d2a0f7e17f33e7890257367a1662b05fecaf56625f7dbb6446227aaa2b86448b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4d0d26c7172bdb64f86ee0765c5b26ea1dc45c52389175888ec073b9b28f4305"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win32.whl", hash = "sha256:6ad02bab756751c90fa27f3069d7b12146613061341459abf55f8190d899649f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:b1472986fd9c5d318399a01a0881f4a0bf4950264131bb8e2deba9df6d8c362b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:c408f09649cbff8da76f8d3ad878b64ba7f7abdad1471efb293d2c075e80c822"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1bac4873f6186f5233b0084b266bfb459e997f4c21fc9f029918f44a9eccd304"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f9f12c2d0aa52b86206d2059916153876a9b1cf9dfb3cf2f344913167f1c3d4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd501de6f7a8f83557d20613b58734d1cb5f0be78d794cde64fe43cfc63f5f2"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4416ca69af933d4a8ad30910149d3db6d084781d5c5fdedb713205389f535385"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f0821b9bdf18c5b7d51722b906b233a39b17f602501a966cfbd9b285f8ab83cd"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0edecc3f90c2653298d380f6ea73b536944b767520c2179ec5d40b9145e47aa"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4513dd01cee11e354c31b75f652d4d466c9440b6859f84e600bdebfccb17735a"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d9727b85511b912571a76ce53c7640ba2c44c364e71cef6d7359b5412739c570"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ab9eab33ee3213f7751dc07a1a61b8d9a3d748ca4458fffddd9defa6f0493c16"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:6b01c1ddbb054283797967ddc5433d5c108d680e8fa2684cf368be05407b07e4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:3857e335f97058c4b46fa39ca831290b70de554a5c5af0323d2f163b19c5f2a6"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d98a46cf07c0c875d27e8a7ed50f304d83063e49b9ab63f21c19c154b4c0d08d"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win32.whl", hash = "sha256:c36539ed2c0173b053dafb221458812e178cfa3224ade0960599bec194637048"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:ec8d7d8567e14af34a7911c98f5ac74a3d4a743cd848643341fc92b12b3784ff"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_arm64.whl", hash = "sha256:62171b270ecc4071be1c1f99960317db261d4c8c83c169e7f8ad119211fe7397"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f06e3c4c0a8badfc4910b9fd15beb1ad8f3b8fafa8ea82c023e5e607b66a78e4"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fe7aaf5a54821d340d21412f7f6e6272a9b17a0cbafc1d68f77f2fc11009dcd5"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25398d9ac7294e99876a3027ffc52c6bebeb2d702b1895af6ae9c541ee676702"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a52eea839e4bdc72c5e60a444d26004da00bb5bc6301e99b3dde18212e41465"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c87319b0ab9d269ab84f6453601fd49b35d9e4a601bbaef43743f26fabf496c"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3048c6ed29d693fba7d2a7caf165f5e0bb2b9743a0989012a98a47b975355cca"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b04f29735bad9f06bb731c214f27253bd8bedb248ef9b8a1b4c5bde65b838454"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7864e80a0d4e23eb6194254a81ee1216abdc53f9dc85b7f4d56668eced022eb8"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3794df87313dfb56fafd679b962e0613c88a293fd9bd5dd5c2793d66bf06a101"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d71da0012face6f45432a11bc59af19e62fac5a41f8ce489e80c0add8153c3d1"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff38378346b7018f42cbc1f6d1d3778e36e16d8595f79a312b31e7c25c50bd08"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6668321f90aa02a5a789d4e16058f2e4f2692c5230252425c3532a8a62bc3424"}, + {file = "rapidfuzz-3.11.0.tar.gz", hash = "sha256:a53ca4d3f52f00b393fab9b5913c5bafb9afc27d030c8a1db1283da6917a860f"}, ] [package.extras] @@ -2625,105 +2702,105 @@ all = ["numpy"] [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -2829,13 +2906,13 @@ tests = ["coverage (>=6.0.0)", "flake8", "mypy", "pytest (>=7.0.0)", "pytest-asy [[package]] name = "s3transfer" -version = "0.10.3" +version = "0.10.4" description = "An Amazon S3 Transfer Manager" optional = false python-versions = ">=3.8" files = [ - {file = "s3transfer-0.10.3-py3-none-any.whl", hash = "sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d"}, - {file = "s3transfer-0.10.3.tar.gz", hash = "sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c"}, + {file = "s3transfer-0.10.4-py3-none-any.whl", hash = "sha256:244a76a24355363a68164241438de1b72f8781664920260c48465896b712a41e"}, + {file = "s3transfer-0.10.4.tar.gz", hash = "sha256:29edc09801743c21eb5ecbc617a152df41d3c287f67b615f73e5f750583666a7"}, ] [package.dependencies] @@ -2846,121 +2923,26 @@ crt = ["botocore[crt] (>=1.33.2,<2.0a.0)"] [[package]] name = "safetensors" -version = "0.4.5" +version = "0.5.0" description = "" optional = false python-versions = ">=3.7" files = [ - {file = "safetensors-0.4.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a63eaccd22243c67e4f2b1c3e258b257effc4acd78f3b9d397edc8cf8f1298a7"}, - {file = "safetensors-0.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:23fc9b4ec7b602915cbb4ec1a7c1ad96d2743c322f20ab709e2c35d1b66dad27"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6885016f34bef80ea1085b7e99b3c1f92cb1be78a49839203060f67b40aee761"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:133620f443450429322f238fda74d512c4008621227fccf2f8cf4a76206fea7c"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4fb3e0609ec12d2a77e882f07cced530b8262027f64b75d399f1504ffec0ba56"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0f1dd769f064adc33831f5e97ad07babbd728427f98e3e1db6902e369122737"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6d156bdb26732feada84f9388a9f135528c1ef5b05fae153da365ad4319c4c5"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9e347d77e2c77eb7624400ccd09bed69d35c0332f417ce8c048d404a096c593b"}, - {file = "safetensors-0.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9f556eea3aec1d3d955403159fe2123ddd68e880f83954ee9b4a3f2e15e716b6"}, - {file = "safetensors-0.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9483f42be3b6bc8ff77dd67302de8ae411c4db39f7224dec66b0eb95822e4163"}, - {file = "safetensors-0.4.5-cp310-none-win32.whl", hash = "sha256:7389129c03fadd1ccc37fd1ebbc773f2b031483b04700923c3511d2a939252cc"}, - {file = "safetensors-0.4.5-cp310-none-win_amd64.whl", hash = "sha256:e98ef5524f8b6620c8cdef97220c0b6a5c1cef69852fcd2f174bb96c2bb316b1"}, - {file = "safetensors-0.4.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:21f848d7aebd5954f92538552d6d75f7c1b4500f51664078b5b49720d180e47c"}, - {file = "safetensors-0.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bb07000b19d41e35eecef9a454f31a8b4718a185293f0d0b1c4b61d6e4487971"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09dedf7c2fda934ee68143202acff6e9e8eb0ddeeb4cfc24182bef999efa9f42"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:59b77e4b7a708988d84f26de3ebead61ef1659c73dcbc9946c18f3b1786d2688"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d3bc83e14d67adc2e9387e511097f254bd1b43c3020440e708858c684cbac68"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39371fc551c1072976073ab258c3119395294cf49cdc1f8476794627de3130df"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6c19feda32b931cae0acd42748a670bdf56bee6476a046af20181ad3fee4090"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a659467495de201e2f282063808a41170448c78bada1e62707b07a27b05e6943"}, - {file = "safetensors-0.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bad5e4b2476949bcd638a89f71b6916fa9a5cae5c1ae7eede337aca2100435c0"}, - {file = "safetensors-0.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a3a315a6d0054bc6889a17f5668a73f94f7fe55121ff59e0a199e3519c08565f"}, - {file = "safetensors-0.4.5-cp311-none-win32.whl", hash = "sha256:a01e232e6d3d5cf8b1667bc3b657a77bdab73f0743c26c1d3c5dd7ce86bd3a92"}, - {file = "safetensors-0.4.5-cp311-none-win_amd64.whl", hash = "sha256:cbd39cae1ad3e3ef6f63a6f07296b080c951f24cec60188378e43d3713000c04"}, - {file = "safetensors-0.4.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:473300314e026bd1043cef391bb16a8689453363381561b8a3e443870937cc1e"}, - {file = "safetensors-0.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:801183a0f76dc647f51a2d9141ad341f9665602a7899a693207a82fb102cc53e"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1524b54246e422ad6fb6aea1ac71edeeb77666efa67230e1faf6999df9b2e27f"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b3139098e3e8b2ad7afbca96d30ad29157b50c90861084e69fcb80dec7430461"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65573dc35be9059770808e276b017256fa30058802c29e1038eb1c00028502ea"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd33da8e9407559f8779c82a0448e2133737f922d71f884da27184549416bfed"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3685ce7ed036f916316b567152482b7e959dc754fcc4a8342333d222e05f407c"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dde2bf390d25f67908278d6f5d59e46211ef98e44108727084d4637ee70ab4f1"}, - {file = "safetensors-0.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7469d70d3de970b1698d47c11ebbf296a308702cbaae7fcb993944751cf985f4"}, - {file = "safetensors-0.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3a6ba28118636a130ccbb968bc33d4684c48678695dba2590169d5ab03a45646"}, - {file = "safetensors-0.4.5-cp312-none-win32.whl", hash = "sha256:c859c7ed90b0047f58ee27751c8e56951452ed36a67afee1b0a87847d065eec6"}, - {file = "safetensors-0.4.5-cp312-none-win_amd64.whl", hash = "sha256:b5a8810ad6a6f933fff6c276eae92c1da217b39b4d8b1bc1c0b8af2d270dc532"}, - {file = "safetensors-0.4.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:25e5f8e2e92a74f05b4ca55686234c32aac19927903792b30ee6d7bd5653d54e"}, - {file = "safetensors-0.4.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:81efb124b58af39fcd684254c645e35692fea81c51627259cdf6d67ff4458916"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:585f1703a518b437f5103aa9cf70e9bd437cb78eea9c51024329e4fb8a3e3679"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b99fbf72e3faf0b2f5f16e5e3458b93b7d0a83984fe8d5364c60aa169f2da89"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b17b299ca9966ca983ecda1c0791a3f07f9ca6ab5ded8ef3d283fff45f6bcd5f"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76ded72f69209c9780fdb23ea89e56d35c54ae6abcdec67ccb22af8e696e449a"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2783956926303dcfeb1de91a4d1204cd4089ab441e622e7caee0642281109db3"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d94581aab8c6b204def4d7320f07534d6ee34cd4855688004a4354e63b639a35"}, - {file = "safetensors-0.4.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:67e1e7cb8678bb1b37ac48ec0df04faf689e2f4e9e81e566b5c63d9f23748523"}, - {file = "safetensors-0.4.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:dbd280b07e6054ea68b0cb4b16ad9703e7d63cd6890f577cb98acc5354780142"}, - {file = "safetensors-0.4.5-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:77d9b228da8374c7262046a36c1f656ba32a93df6cc51cd4453af932011e77f1"}, - {file = "safetensors-0.4.5-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:500cac01d50b301ab7bb192353317035011c5ceeef0fca652f9f43c000bb7f8d"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75331c0c746f03158ded32465b7d0b0e24c5a22121743662a2393439c43a45cf"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:670e95fe34e0d591d0529e5e59fd9d3d72bc77b1444fcaa14dccda4f36b5a38b"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:098923e2574ff237c517d6e840acada8e5b311cb1fa226019105ed82e9c3b62f"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13ca0902d2648775089fa6a0c8fc9e6390c5f8ee576517d33f9261656f851e3f"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f0032bedc869c56f8d26259fe39cd21c5199cd57f2228d817a0e23e8370af25"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f4b15f51b4f8f2a512341d9ce3475cacc19c5fdfc5db1f0e19449e75f95c7dc8"}, - {file = "safetensors-0.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f6594d130d0ad933d885c6a7b75c5183cb0e8450f799b80a39eae2b8508955eb"}, - {file = "safetensors-0.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:60c828a27e852ded2c85fc0f87bf1ec20e464c5cd4d56ff0e0711855cc2e17f8"}, - {file = "safetensors-0.4.5-cp37-none-win32.whl", hash = "sha256:6d3de65718b86c3eeaa8b73a9c3d123f9307a96bbd7be9698e21e76a56443af5"}, - {file = "safetensors-0.4.5-cp37-none-win_amd64.whl", hash = "sha256:5a2d68a523a4cefd791156a4174189a4114cf0bf9c50ceb89f261600f3b2b81a"}, - {file = "safetensors-0.4.5-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:e7a97058f96340850da0601a3309f3d29d6191b0702b2da201e54c6e3e44ccf0"}, - {file = "safetensors-0.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:63bfd425e25f5c733f572e2246e08a1c38bd6f2e027d3f7c87e2e43f228d1345"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3664ac565d0e809b0b929dae7ccd74e4d3273cd0c6d1220c6430035befb678e"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:313514b0b9b73ff4ddfb4edd71860696dbe3c1c9dc4d5cc13dbd74da283d2cbf"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31fa33ee326f750a2f2134a6174773c281d9a266ccd000bd4686d8021f1f3dac"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:09566792588d77b68abe53754c9f1308fadd35c9f87be939e22c623eaacbed6b"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309aaec9b66cbf07ad3a2e5cb8a03205663324fea024ba391594423d0f00d9fe"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:53946c5813b8f9e26103c5efff4a931cc45d874f45229edd68557ffb35ffb9f8"}, - {file = "safetensors-0.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:868f9df9e99ad1e7f38c52194063a982bc88fedc7d05096f4f8160403aaf4bd6"}, - {file = "safetensors-0.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9cc9449bd0b0bc538bd5e268221f0c5590bc5c14c1934a6ae359d44410dc68c4"}, - {file = "safetensors-0.4.5-cp38-none-win32.whl", hash = "sha256:83c4f13a9e687335c3928f615cd63a37e3f8ef072a3f2a0599fa09f863fb06a2"}, - {file = "safetensors-0.4.5-cp38-none-win_amd64.whl", hash = "sha256:b98d40a2ffa560653f6274e15b27b3544e8e3713a44627ce268f419f35c49478"}, - {file = "safetensors-0.4.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:cf727bb1281d66699bef5683b04d98c894a2803442c490a8d45cd365abfbdeb2"}, - {file = "safetensors-0.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:96f1d038c827cdc552d97e71f522e1049fef0542be575421f7684756a748e457"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:139fbee92570ecea774e6344fee908907db79646d00b12c535f66bc78bd5ea2c"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c36302c1c69eebb383775a89645a32b9d266878fab619819ce660309d6176c9b"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d641f5b8149ea98deb5ffcf604d764aad1de38a8285f86771ce1abf8e74c4891"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b4db6a61d968de73722b858038c616a1bebd4a86abe2688e46ca0cc2d17558f2"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b75a616e02f21b6f1d5785b20cecbab5e2bd3f6358a90e8925b813d557666ec1"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:788ee7d04cc0e0e7f944c52ff05f52a4415b312f5efd2ee66389fb7685ee030c"}, - {file = "safetensors-0.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:87bc42bd04fd9ca31396d3ca0433db0be1411b6b53ac5a32b7845a85d01ffc2e"}, - {file = "safetensors-0.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4037676c86365a721a8c9510323a51861d703b399b78a6b4486a54a65a975fca"}, - {file = "safetensors-0.4.5-cp39-none-win32.whl", hash = "sha256:1500418454529d0ed5c1564bda376c4ddff43f30fce9517d9bee7bcce5a8ef50"}, - {file = "safetensors-0.4.5-cp39-none-win_amd64.whl", hash = "sha256:9d1a94b9d793ed8fe35ab6d5cea28d540a46559bafc6aae98f30ee0867000cab"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fdadf66b5a22ceb645d5435a0be7a0292ce59648ca1d46b352f13cff3ea80410"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d42ffd4c2259f31832cb17ff866c111684c87bd930892a1ba53fed28370c918c"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd8a1f6d2063a92cd04145c7fd9e31a1c7d85fbec20113a14b487563fdbc0597"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:951d2fcf1817f4fb0ef0b48f6696688a4e852a95922a042b3f96aaa67eedc920"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6ac85d9a8c1af0e3132371d9f2d134695a06a96993c2e2f0bbe25debb9e3f67a"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e3cec4a29eb7fe8da0b1c7988bc3828183080439dd559f720414450de076fcab"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:21742b391b859e67b26c0b2ac37f52c9c0944a879a25ad2f9f9f3cd61e7fda8f"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c7db3006a4915151ce1913652e907cdede299b974641a83fbc092102ac41b644"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f68bf99ea970960a237f416ea394e266e0361895753df06e3e06e6ea7907d98b"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8158938cf3324172df024da511839d373c40fbfaa83e9abf467174b2910d7b4c"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:540ce6c4bf6b58cb0fd93fa5f143bc0ee341c93bb4f9287ccd92cf898cc1b0dd"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bfeaa1a699c6b9ed514bd15e6a91e74738b71125a9292159e3d6b7f0a53d2cde"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:01c8f00da537af711979e1b42a69a8ec9e1d7112f208e0e9b8a35d2c381085ef"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a0dd565f83b30f2ca79b5d35748d0d99dd4b3454f80e03dfb41f0038e3bdf180"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:023b6e5facda76989f4cba95a861b7e656b87e225f61811065d5c501f78cdb3f"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9633b663393d5796f0b60249549371e392b75a0b955c07e9c6f8708a87fc841f"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78dd8adfb48716233c45f676d6e48534d34b4bceb50162c13d1f0bdf6f78590a"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8e8deb16c4321d61ae72533b8451ec4a9af8656d1c61ff81aa49f966406e4b68"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:52452fa5999dc50c4decaf0c53aa28371f7f1e0fe5c2dd9129059fbe1e1599c7"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d5f23198821e227cfc52d50fa989813513db381255c6d100927b012f0cfec63d"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f4beb84b6073b1247a773141a6331117e35d07134b3bb0383003f39971d414bb"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:68814d599d25ed2fdd045ed54d370d1d03cf35e02dce56de44c651f828fb9b7b"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0b6453c54c57c1781292c46593f8a37254b8b99004c68d6c3ce229688931a22"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:adaa9c6dead67e2dd90d634f89131e43162012479d86e25618e821a03d1eb1dc"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73e7d408e9012cd17511b382b43547850969c7979efc2bc353f317abaf23c84c"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:775409ce0fcc58b10773fdb4221ed1eb007de10fe7adbdf8f5e8a56096b6f0bc"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:834001bed193e4440c4a3950a31059523ee5090605c907c66808664c932b549c"}, - {file = "safetensors-0.4.5.tar.gz", hash = "sha256:d73de19682deabb02524b3d5d1f8b3aaba94c72f1bbfc7911b9b9d5d391c0310"}, + {file = "safetensors-0.5.0-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:c683b9b485bee43422ba2855f72777c37647190281e03da4c8d2a69fa5336558"}, + {file = "safetensors-0.5.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:6106aa835deb7263f7014f74c05842ab828d6c11d789f2e7e98f26b1a305e72d"}, + {file = "safetensors-0.5.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1349611f74f55c5ee1c1c144c536a2743c38f7d8bf60b9fc8267e0efc0591a2"}, + {file = "safetensors-0.5.0-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:56d936028ac799e18644b08a91fd98b4b62ae3dcd0440b1cfcb56535785589f1"}, + {file = "safetensors-0.5.0-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2f26afada2233576ffea6b80042c2c0a8105c164254af56168ec14299ad3122"}, + {file = "safetensors-0.5.0-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20067e7a5e63f0cbc88457b2a1161e70ff73af4cc3a24bce90309430cd6f6e7e"}, + {file = "safetensors-0.5.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:649d6a4aa34d5174ae87289068ccc2fec2a1a998ecf83425aa5a42c3eff69bcf"}, + {file = "safetensors-0.5.0-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:debff88f41d569a3e93a955469f83864e432af35bb34b16f65a9ddf378daa3ae"}, + {file = "safetensors-0.5.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:bdf6a3e366ea8ba1a0538db6099229e95811194432c684ea28ea7ae28763b8dc"}, + {file = "safetensors-0.5.0-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:0371afd84c200a80eb7103bf715108b0c3846132fb82453ae018609a15551580"}, + {file = "safetensors-0.5.0-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:5ec7fc8c3d2f32ebf1c7011bc886b362e53ee0a1ec6d828c39d531fed8b325d6"}, + {file = "safetensors-0.5.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:53715e4ea0ef23c08f004baae0f609a7773de7d4148727760417c6760cfd6b76"}, + {file = "safetensors-0.5.0-cp38-abi3-win32.whl", hash = "sha256:b85565bc2f0456961a788d2f11d9d892eec46603db0e4923aa9512c2355aa727"}, + {file = "safetensors-0.5.0-cp38-abi3-win_amd64.whl", hash = "sha256:f451941f8aa11e7be5c3fa450e264609a2b1e65fa38ae590a74e55a94d646b76"}, + {file = "safetensors-0.5.0.tar.gz", hash = "sha256:c47b34c549fa1e0c655c4644da31332c61332c732c47c8dd9399347e9aac69d1"}, ] [package.extras] @@ -2970,7 +2952,7 @@ jax = ["flax (>=0.6.3)", "jax (>=0.3.25)", "jaxlib (>=0.3.25)", "safetensors[num mlx = ["mlx (>=0.0.9)"] numpy = ["numpy (>=1.21.6)"] paddlepaddle = ["paddlepaddle (>=2.4.1)", "safetensors[numpy]"] -pinned-tf = ["safetensors[numpy]", "tensorflow (==2.11.0)"] +pinned-tf = ["safetensors[numpy]", "tensorflow (==2.18.0)"] quality = ["black (==22.3)", "click (==8.0.4)", "flake8 (>=3.8.3)", "isort (>=5.5.4)"] tensorflow = ["safetensors[numpy]", "tensorflow (>=2.11.0)"] testing = ["h5py (>=3.7.0)", "huggingface-hub (>=0.12.1)", "hypothesis (>=6.70.2)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "safetensors[numpy]", "setuptools-rust (>=1.5.2)"] @@ -3032,33 +3014,33 @@ typing-extensions = "*" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -3275,20 +3257,21 @@ files = [ [[package]] name = "tqdm" -version = "4.66.6" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63"}, - {file = "tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -3539,13 +3522,13 @@ bracex = ">=2.1.1" [[package]] name = "werkzeug" -version = "3.0.6" +version = "3.1.3" description = "The comprehensive WSGI web application library." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "werkzeug-3.0.6-py3-none-any.whl", hash = "sha256:1bc0c2310d2fbb07b1dd1105eba2f7af72f322e1e455f2f93c993bee8c8a5f17"}, - {file = "werkzeug-3.0.6.tar.gz", hash = "sha256:a8dd59d4de28ca70471a34cba79bed5f7ef2e036a76b3ab0835474246eb41f8d"}, + {file = "werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e"}, + {file = "werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746"}, ] [package.dependencies] @@ -3556,81 +3539,76 @@ watchdog = ["watchdog (>=2.3)"] [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [[package]] @@ -3646,16 +3624,16 @@ files = [ [[package]] name = "xmltodict" -version = "0.14.2" +version = "0.13.0" description = "Makes working with XML feel like you are working with JSON" optional = false -python-versions = ">=3.6" +python-versions = ">=3.4" files = [ - {file = "xmltodict-0.14.2-py2.py3-none-any.whl", hash = "sha256:20cc7d723ed729276e808f26fb6b3599f786cbc37e06c65e192ba77c40f20aac"}, - {file = "xmltodict-0.14.2.tar.gz", hash = "sha256:201e7c28bb210e374999d1dde6382923ab0ed1a8a5faeece48ab525b7810a553"}, + {file = "xmltodict-0.13.0-py2.py3-none-any.whl", hash = "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"}, + {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"}, ] [metadata] lock-version = "2.0" python-versions = "^3.10,<3.12" -content-hash = "991c6a8c2048db0182ec59fc540454f25d0cd6973595731baf1aa0509f369e86" +content-hash = "245a6af0b3725c6c360b99a653210c751a518e973925d9c094fad0ce253e52d7" diff --git a/airbyte-integrations/connectors/source-s3/pyproject.toml b/airbyte-integrations/connectors/source-s3/pyproject.toml index a1d316bf7daa..ef32ba72d914 100644 --- a/airbyte-integrations/connectors/source-s3/pyproject.toml +++ b/airbyte-integrations/connectors/source-s3/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "4.9.1" +version = "4.11.3" name = "source-s3" description = "Source implementation for S3." authors = [ "Airbyte ",] @@ -22,7 +22,7 @@ wcmatch = "==8.4" dill = "==0.3.4" transformers = "4.38.2" urllib3 = "<2" -airbyte-cdk = {extras = ["file-based"], version = "^5.7.4"} +airbyte-cdk = {extras = ["file-based"], version = "^6.5.2"} [tool.poetry.scripts] source-s3 = "source_s3.run:run" diff --git a/airbyte-integrations/connectors/source-s3/scripts/fetch_test_secrets.py b/airbyte-integrations/connectors/source-s3/scripts/fetch_test_secrets.py index 88908adc107d..135162253839 100644 --- a/airbyte-integrations/connectors/source-s3/scripts/fetch_test_secrets.py +++ b/airbyte-integrations/connectors/source-s3/scripts/fetch_test_secrets.py @@ -28,6 +28,7 @@ import airbyte as ab from airbyte.secrets import GoogleGSMSecretManager, SecretHandle + AIRBYTE_INTERNAL_GCP_PROJECT = "dataline-integration-testing" CONNECTOR_NAME = "source-s3" MISSING_ONLY = True diff --git a/airbyte-integrations/connectors/source-s3/scripts/rotate_creds.py b/airbyte-integrations/connectors/source-s3/scripts/rotate_creds.py index f9b8f6a85523..969c27f609dc 100644 --- a/airbyte-integrations/connectors/source-s3/scripts/rotate_creds.py +++ b/airbyte-integrations/connectors/source-s3/scripts/rotate_creds.py @@ -30,6 +30,7 @@ from airbyte.secrets import get_secret from airbyte.secrets.google_gsm import GoogleGSMSecretManager, GSMSecretHandle + AIRBYTE_INTERNAL_GCP_PROJECT = "dataline-integration-testing" CONNECTOR_NAME = "source-s3" diff --git a/airbyte-integrations/connectors/source-s3/source_s3/source_files_abstract/source.py b/airbyte-integrations/connectors/source-s3/source_s3/source_files_abstract/source.py index 69799dfa2dae..4ad361ac89aa 100644 --- a/airbyte-integrations/connectors/source-s3/source_s3/source_files_abstract/source.py +++ b/airbyte-integrations/connectors/source-s3/source_s3/source_files_abstract/source.py @@ -7,9 +7,11 @@ from traceback import format_exc from typing import Any, List, Mapping, Optional, Tuple -from airbyte_cdk import AbstractSource, ConnectorSpecification, DestinationSyncMode, Stream, SyncMode from wcmatch.glob import GLOBSTAR, SPLIT, globmatch +from airbyte_cdk import AbstractSource, ConnectorSpecification, DestinationSyncMode, Stream, SyncMode + + # ideas on extending this to handle multiple streams: # - "dataset" is currently the name of the single table/stream. We could allow comma-split table names in this string for many streams. # - "path_pattern" currently uses https://facelessuser.github.io/wcmatch/glob/ to match a single string pattern (can be multiple | separated) diff --git a/airbyte-integrations/connectors/source-s3/source_s3/source_files_abstract/spec.py b/airbyte-integrations/connectors/source-s3/source_s3/source_files_abstract/spec.py index a623f8ccf4e4..6e206b720a02 100644 --- a/airbyte-integrations/connectors/source-s3/source_s3/source_files_abstract/spec.py +++ b/airbyte-integrations/connectors/source-s3/source_s3/source_files_abstract/spec.py @@ -15,6 +15,7 @@ from .formats.jsonl_spec import JsonlFormat from .formats.parquet_spec import ParquetFormat + # To implement your provider specific spec, inherit from SourceFilesAbstractSpec and add provider-specific settings e.g.: # class SourceS3Spec(SourceFilesAbstractSpec, BaseModel): diff --git a/airbyte-integrations/connectors/source-s3/source_s3/stream.py b/airbyte-integrations/connectors/source-s3/source_s3/stream.py index b99632dbdc51..6ea5ed89e969 100644 --- a/airbyte-integrations/connectors/source-s3/source_s3/stream.py +++ b/airbyte-integrations/connectors/source-s3/source_s3/stream.py @@ -6,11 +6,12 @@ from typing import Any, Iterator, Mapping import pendulum -from airbyte_cdk import AirbyteTracedException, FailureType from boto3 import session as boto3session from botocore import UNSIGNED from botocore.config import Config from botocore.exceptions import ClientError + +from airbyte_cdk import AirbyteTracedException, FailureType from source_s3.s3_utils import make_s3_client from .s3file import S3File @@ -51,9 +52,7 @@ def filepath_iterator(self, stream_state: Mapping[str, Any] = None) -> Iterator[ # list_objects_v2 doesn't like a None value for ContinuationToken # so we don't set it if we don't have one. if ctoken: - kwargs = dict( - Bucket=provider["bucket"], Prefix=provider.get("path_prefix", ""), ContinuationToken=ctoken - ) # type: ignore[unreachable] + kwargs = dict(Bucket=provider["bucket"], Prefix=provider.get("path_prefix", ""), ContinuationToken=ctoken) # type: ignore[unreachable] else: kwargs = dict(Bucket=provider["bucket"], Prefix=provider.get("path_prefix", "")) try: diff --git a/airbyte-integrations/connectors/source-s3/source_s3/utils.py b/airbyte-integrations/connectors/source-s3/source_s3/utils.py index 9118ec151ff8..f3715bb367a7 100644 --- a/airbyte-integrations/connectors/source-s3/source_s3/utils.py +++ b/airbyte-integrations/connectors/source-s3/source_s3/utils.py @@ -11,6 +11,7 @@ import dill import orjson + from airbyte_cdk.models import AirbyteMessage, AirbyteMessageSerializer diff --git a/airbyte-integrations/connectors/source-s3/source_s3/v4/config.py b/airbyte-integrations/connectors/source-s3/source_s3/v4/config.py index 0fafd9a5ae52..cdc66ab06fc7 100644 --- a/airbyte-integrations/connectors/source-s3/source_s3/v4/config.py +++ b/airbyte-integrations/connectors/source-s3/source_s3/v4/config.py @@ -5,11 +5,12 @@ from typing import Any, Dict, Optional import dpath.util -from airbyte_cdk import is_cloud_environment -from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec from pydantic.v1 import AnyUrl, Field, root_validator from pydantic.v1.error_wrappers import ValidationError +from airbyte_cdk import is_cloud_environment +from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec, DeliverRawFiles, DeliverRecords + class Config(AbstractFileBasedSpec): """ @@ -64,6 +65,16 @@ def documentation_url(cls) -> AnyUrl: order=5, ) + delivery_method: DeliverRecords | DeliverRawFiles = Field( + title="Delivery Method", + discriminator="delivery_type", + type="object", + order=6, + display_type="radio", + group="advanced", + default="use_records_transfer", + ) + @root_validator def validate_optional_args(cls, values): aws_access_key_id = values.get("aws_access_key_id") diff --git a/airbyte-integrations/connectors/source-s3/source_s3/v4/cursor.py b/airbyte-integrations/connectors/source-s3/source_s3/v4/cursor.py index 0e6cf7528eee..ab60ecf088a1 100644 --- a/airbyte-integrations/connectors/source-s3/source_s3/v4/cursor.py +++ b/airbyte-integrations/connectors/source-s3/source_s3/v4/cursor.py @@ -11,6 +11,7 @@ from airbyte_cdk.sources.file_based.stream.cursor import DefaultFileBasedCursor from airbyte_cdk.sources.file_based.types import StreamState + logger = logging.Logger("source-S3") diff --git a/airbyte-integrations/connectors/source-s3/source_s3/v4/legacy_config_transformer.py b/airbyte-integrations/connectors/source-s3/source_s3/v4/legacy_config_transformer.py index 4d04411a6694..c6db739caf2f 100644 --- a/airbyte-integrations/connectors/source-s3/source_s3/v4/legacy_config_transformer.py +++ b/airbyte-integrations/connectors/source-s3/source_s3/v4/legacy_config_transformer.py @@ -12,6 +12,7 @@ from source_s3.source_files_abstract.formats.jsonl_spec import JsonlFormat from source_s3.source_files_abstract.formats.parquet_spec import ParquetFormat + SECONDS_FORMAT = "%Y-%m-%dT%H:%M:%SZ" MICROS_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ" diff --git a/airbyte-integrations/connectors/source-s3/source_s3/v4/source.py b/airbyte-integrations/connectors/source-s3/source_s3/v4/source.py index 9991c444ff64..2e3ac647a3a0 100644 --- a/airbyte-integrations/connectors/source-s3/source_s3/v4/source.py +++ b/airbyte-integrations/connectors/source-s3/source_s3/v4/source.py @@ -10,6 +10,7 @@ from typing import Any, Dict, Mapping, Optional import orjson + from airbyte_cdk import ( AirbyteEntrypoint, ConnectorSpecification, @@ -34,6 +35,7 @@ from source_s3.v4.legacy_config_transformer import LegacyConfigTransformer from source_s3.v4.stream_reader import SourceS3StreamReader + _V3_DEPRECATION_FIELD_MAPPING = { "dataset": "streams.name", "format": "streams.format", diff --git a/airbyte-integrations/connectors/source-s3/source_s3/v4/stream_reader.py b/airbyte-integrations/connectors/source-s3/source_s3/v4/stream_reader.py index 62d7376e861b..9c6051c8dd16 100644 --- a/airbyte-integrations/connectors/source-s3/source_s3/v4/stream_reader.py +++ b/airbyte-integrations/connectors/source-s3/source_s3/v4/stream_reader.py @@ -3,31 +3,38 @@ # import logging +import time from datetime import datetime from io import IOBase -from os import getenv -from typing import Iterable, List, Optional, Set +from os import getenv, makedirs, path +from typing import Dict, Iterable, List, Optional, Set, cast import boto3.session import pendulum +import psutil import pytz import smart_open -from airbyte_cdk import FailureType -from airbyte_cdk.sources.file_based.exceptions import CustomFileBasedException, ErrorListingFiles, FileBasedSourceError -from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode -from airbyte_cdk.sources.file_based.remote_file import RemoteFile from botocore.client import BaseClient from botocore.client import Config as ClientConfig from botocore.credentials import RefreshableCredentials from botocore.exceptions import ClientError from botocore.session import get_session +from typing_extensions import override + +from airbyte_cdk import FailureType +from airbyte_cdk.sources.file_based.exceptions import CustomFileBasedException, ErrorListingFiles, FileBasedSourceError, FileSizeLimitError +from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode +from airbyte_cdk.sources.file_based.remote_file import RemoteFile from source_s3.v4.config import Config from source_s3.v4.zip_reader import DecompressedStream, RemoteFileInsideArchive, ZipContentReader, ZipFileHandler + AWS_EXTERNAL_ID = getenv("AWS_ASSUME_ROLE_EXTERNAL_ID") class SourceS3StreamReader(AbstractFileBasedStreamReader): + FILE_SIZE_LIMIT = 1_500_000_000 + def __init__(self): super().__init__() self._s3_client = None @@ -183,6 +190,84 @@ def open_file(self, file: RemoteFile, mode: FileReadMode, encoding: Optional[str # we can simply return the result here as it is a context manager itself that will release all resources return result + @staticmethod + def create_progress_handler(file_size: int, local_file_path: str, logger: logging.Logger): + previous_bytes_checkpoint = 0 + total_bytes_transferred = 0 + + def progress_handler(bytes_transferred: int): + nonlocal previous_bytes_checkpoint, total_bytes_transferred + total_bytes_transferred += bytes_transferred + if total_bytes_transferred - previous_bytes_checkpoint >= 100 * 1024 * 1024: + logger.info( + f"{total_bytes_transferred / (1024 * 1024):,.2f} MB ({total_bytes_transferred / (1024 * 1024 * 1024):.2f} GB) " + f"of {file_size / (1024 * 1024):,.2f} MB ({file_size / (1024 * 1024 * 1024):.2f} GB) " + f"written to {local_file_path}" + ) + previous_bytes_checkpoint = total_bytes_transferred + + # Get available disk space + disk_usage = psutil.disk_usage("/") + available_disk_space = disk_usage.free + + # Get available memory + memory_info = psutil.virtual_memory() + available_memory = memory_info.available + logger.info( + f"Available disk space: {available_disk_space / (1024 * 1024):,.2f} MB ({available_disk_space / (1024 * 1024 * 1024):.2f} GB), " + f"available memory: {available_memory / (1024 * 1024):,.2f} MB ({available_memory / (1024 * 1024 * 1024):.2f} GB)." + ) + + return progress_handler + + @override + def get_file(self, file: RemoteFile, local_directory: str, logger: logging.Logger) -> Dict[str, str | int]: + """ + Downloads a file from an S3 bucket to a specified local directory. + + Args: + file (RemoteFile): The remote file object containing URI and metadata. + local_directory (str): The local directory path where the file will be downloaded. + logger (logging.Logger): Logger for logging information and errors. + + Returns: + dict: A dictionary containing the following: + - "file_url" (str): The absolute path of the downloaded file. + - "bytes" (int): The file size in bytes. + - "file_relative_path" (str): The relative path of the file for local storage. Is relative to local_directory as + this a mounted volume in the pod container. + + Raises: + FileSizeLimitError: If the file size exceeds the predefined limit (1 GB). + """ + file_size = self.file_size(file) + # I'm putting this check here so we can remove the safety wheels per connector when ready. + if file_size > self.FILE_SIZE_LIMIT: + message = "File size exceeds the 1 GB limit." + raise FileSizeLimitError(message=message, internal_message=message, failure_type=FailureType.config_error) + + file_relative_path, local_file_path, absolute_file_path = self._get_file_transfer_paths(file, local_directory) + + logger.info( + f"Starting to download the file {file.uri} with size: {file_size / (1024 * 1024):,.2f} MB ({file_size / (1024 * 1024 * 1024):.2f} GB)" + ) + # at some moment maybe we will require to play with the max_pool_connections and max_concurrency of s3 config + start_download_time = time.time() + progress_handler = self.create_progress_handler(file_size, local_file_path, logger) + self.s3_client.download_file(self.config.bucket, file.uri, local_file_path, Callback=progress_handler) + write_duration = time.time() - start_download_time + logger.info(f"Finished downloading the file {file.uri} and saved to {local_file_path} in {write_duration:,.2f} seconds.") + + return {"file_url": absolute_file_path, "bytes": file_size, "file_relative_path": file_relative_path} + + @override + def file_size(self, file: RemoteFile) -> int: + s3_object: boto3.s3.Object = self.s3_client.get_object( + Bucket=self.config.bucket, + Key=file.uri, + ) + return cast(int, s3_object["ContentLength"]) + @staticmethod def _is_folder(file) -> bool: return file["Key"].endswith("/") diff --git a/airbyte-integrations/connectors/source-s3/source_s3/v4/zip_reader.py b/airbyte-integrations/connectors/source-s3/source_s3/v4/zip_reader.py index 4f475b80c797..12d0ed1ff8f0 100644 --- a/airbyte-integrations/connectors/source-s3/source_s3/v4/zip_reader.py +++ b/airbyte-integrations/connectors/source-s3/source_s3/v4/zip_reader.py @@ -5,10 +5,12 @@ import zipfile from typing import IO, List, Optional, Tuple, Union -from airbyte_cdk.sources.file_based.remote_file import RemoteFile from botocore.client import BaseClient + +from airbyte_cdk.sources.file_based.remote_file import RemoteFile from source_s3.v4.config import Config + # Buffer constants BUFFER_SIZE_DEFAULT = 1024 * 1024 MAX_BUFFER_SIZE_DEFAULT: int = 16 * BUFFER_SIZE_DEFAULT diff --git a/airbyte-integrations/connectors/source-s3/unit_tests/v4/test_config.py b/airbyte-integrations/connectors/source-s3/unit_tests/v4/test_config.py index 13e84edd6cb6..1f2e8c726162 100644 --- a/airbyte-integrations/connectors/source-s3/unit_tests/v4/test_config.py +++ b/airbyte-integrations/connectors/source-s3/unit_tests/v4/test_config.py @@ -9,6 +9,7 @@ from pydantic.v1.error_wrappers import ValidationError from source_s3.v4.config import Config + logger = logging.Logger("") diff --git a/airbyte-integrations/connectors/source-s3/unit_tests/v4/test_cursor.py b/airbyte-integrations/connectors/source-s3/unit_tests/v4/test_cursor.py index f06e8fd9ae7c..8b064c65df26 100644 --- a/airbyte-integrations/connectors/source-s3/unit_tests/v4/test_cursor.py +++ b/airbyte-integrations/connectors/source-s3/unit_tests/v4/test_cursor.py @@ -7,11 +7,12 @@ from unittest.mock import Mock import pytest +from source_s3.v4.cursor import Cursor + from airbyte_cdk.sources.file_based.config.csv_format import CsvFormat from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig from airbyte_cdk.sources.file_based.remote_file import RemoteFile from airbyte_cdk.sources.file_based.stream.cursor.default_file_based_cursor import DefaultFileBasedCursor -from source_s3.v4.cursor import Cursor def _create_datetime(dt: str) -> datetime: diff --git a/airbyte-integrations/connectors/source-s3/unit_tests/v4/test_source.py b/airbyte-integrations/connectors/source-s3/unit_tests/v4/test_source.py index cf4a82f8d3d0..04a23079910b 100644 --- a/airbyte-integrations/connectors/source-s3/unit_tests/v4/test_source.py +++ b/airbyte-integrations/connectors/source-s3/unit_tests/v4/test_source.py @@ -8,6 +8,7 @@ from source_s3.v4 import Config, SourceS3, SourceS3StreamReader + _V3_FIELDS = ["dataset", "format", "path_pattern", "provider", "schema"] TEST_FILES_FOLDER = Path(__file__).resolve().parent.parent.joinpath("sample_files") diff --git a/airbyte-integrations/connectors/source-s3/unit_tests/v4/test_stream_reader.py b/airbyte-integrations/connectors/source-s3/unit_tests/v4/test_stream_reader.py index 37de3ec1bf08..2512d5672daa 100644 --- a/airbyte-integrations/connectors/source-s3/unit_tests/v4/test_stream_reader.py +++ b/airbyte-integrations/connectors/source-s3/unit_tests/v4/test_stream_reader.py @@ -8,19 +8,21 @@ from datetime import datetime, timedelta from itertools import product from typing import Any, Dict, List, Optional, Set -from unittest.mock import MagicMock, patch +from unittest.mock import ANY, MagicMock, Mock, patch import pytest -from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec -from airbyte_cdk.sources.file_based.exceptions import ErrorListingFiles, FileBasedSourceError -from airbyte_cdk.sources.file_based.file_based_stream_reader import FileReadMode -from airbyte_cdk.sources.file_based.remote_file import RemoteFile from botocore.stub import Stubber from moto import mock_sts from pydantic.v1 import AnyUrl from source_s3.v4.config import Config from source_s3.v4.stream_reader import SourceS3StreamReader +from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec +from airbyte_cdk.sources.file_based.exceptions import ErrorListingFiles, FileBasedSourceError +from airbyte_cdk.sources.file_based.file_based_stream_reader import FileReadMode +from airbyte_cdk.sources.file_based.remote_file import RemoteFile + + logger = logging.Logger("") endpoint_values = ["https://fake.com", None] @@ -124,7 +126,7 @@ def test_get_matching_files( except Exception as exc: raise exc - with patch.object(SourceS3StreamReader, 's3_client', new_callable=MagicMock) as mock_s3_client: + with patch.object(SourceS3StreamReader, "s3_client", new_callable=MagicMock) as mock_s3_client: _setup_mock_s3_client(mock_s3_client, mocked_response, multiple_pages) files = list(reader.get_matching_files(globs, None, logger)) assert set(f.uri for f in files) == expected_uris @@ -134,27 +136,33 @@ def _setup_mock_s3_client(mock_s3_client, mocked_response, multiple_pages): responses = [] if multiple_pages and len(mocked_response) > 1: # Split the mocked_response for pagination simulation - first_half = mocked_response[:len(mocked_response) // 2] - second_half = mocked_response[len(mocked_response) // 2:] - - responses.append({ - "IsTruncated": True, - "Contents": first_half, - "KeyCount": len(first_half), - "NextContinuationToken": "token", - }) - - responses.append({ - "IsTruncated": False, - "Contents": second_half, - "KeyCount": len(second_half), - }) + first_half = mocked_response[: len(mocked_response) // 2] + second_half = mocked_response[len(mocked_response) // 2 :] + + responses.append( + { + "IsTruncated": True, + "Contents": first_half, + "KeyCount": len(first_half), + "NextContinuationToken": "token", + } + ) + + responses.append( + { + "IsTruncated": False, + "Contents": second_half, + "KeyCount": len(second_half), + } + ) else: - responses.append({ - "IsTruncated": False, - "Contents": mocked_response, - "KeyCount": len(mocked_response), - }) + responses.append( + { + "IsTruncated": False, + "Contents": mocked_response, + "KeyCount": len(mocked_response), + } + ) def list_objects_v2_side_effect(Bucket, Prefix=None, ContinuationToken=None, **kwargs): if ContinuationToken == "token": @@ -242,6 +250,41 @@ def test_open_file_calls_any_open_with_the_right_encoding(smart_open_mock): assert smart_open_mock.call_args.kwargs["encoding"] == encoding +@patch("source_s3.v4.stream_reader.SourceS3StreamReader.file_size") +@patch("boto3.client") +def test_get_file(mock_boto_client, s3_reader_file_size_mock): + s3_reader_file_size_mock.return_value = 100 + + mock_s3_client_instance = Mock() + mock_boto_client.return_value = mock_s3_client_instance + mock_s3_client_instance.download_file.return_value = None + + reader = SourceS3StreamReader() + reader.config = Config( + bucket="test", + aws_access_key_id="test", + aws_secret_access_key="test", + streams=[], + delivery_method={"delivery_type": "use_file_transfer"}, + ) + try: + reader.config = Config( + bucket="test", + aws_access_key_id="test", + aws_secret_access_key="test", + streams=[], + endpoint=None, + delivery_method={"delivery_type": "use_file_transfer"}, + ) + except Exception as exc: + raise exc + test_file_path = "directory/file.txt" + result = reader.get_file(RemoteFile(uri="", last_modified=datetime.now()), test_file_path, logger) + + assert result == {"bytes": 100, "file_relative_path": ANY, "file_url": ANY} + assert result["file_url"].endswith(test_file_path) + + def test_get_s3_client_without_config_raises_exception(): with pytest.raises(ValueError): SourceS3StreamReader().s3_client @@ -288,27 +331,20 @@ def test_get_iam_s3_client(boto3_client_mock): # Assertions to validate the s3 client assert s3_client is not None + @pytest.mark.parametrize( "start_date, last_modified_date, expected_result", ( # True when file is new or modified after given start_date - ( - datetime.now() - timedelta(days=180), - datetime.now(), - True - ), + (datetime.now() - timedelta(days=180), datetime.now(), True), ( datetime.strptime("2024-01-01T00:00:00Z", "%Y-%m-%dT%H:%M:%SZ"), datetime.strptime("2024-01-01T00:00:00Z", "%Y-%m-%dT%H:%M:%SZ"), - True + True, ), # False when file is older than given start_date - ( - datetime.now(), - datetime.now() - timedelta(days=180), - False - ) - ) + (datetime.now(), datetime.now() - timedelta(days=180), False), + ), ) def test_filter_file_by_start_date(start_date: datetime, last_modified_date: datetime, expected_result: bool) -> None: reader = SourceS3StreamReader() @@ -318,7 +354,7 @@ def test_filter_file_by_start_date(start_date: datetime, last_modified_date: dat aws_access_key_id="test", aws_secret_access_key="test", streams=[], - start_date=start_date.strftime("%Y-%m-%dT%H:%M:%SZ") + start_date=start_date.strftime("%Y-%m-%dT%H:%M:%SZ"), ) assert expected_result == reader.is_modified_after_start_date(last_modified_date) diff --git a/airbyte-integrations/connectors/source-safetyculture/metadata.yaml b/airbyte-integrations/connectors/source-safetyculture/metadata.yaml index 5a4f2b1a839b..bd10988e8b41 100644 --- a/airbyte-integrations/connectors/source-safetyculture/metadata.yaml +++ b/airbyte-integrations/connectors/source-safetyculture/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-safetyculture connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 570b875e-52d9-40e0-a43c-340ebae2d9f8 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.10 dockerRepository: airbyte/source-safetyculture githubIssueLabel: source-safetyculture icon: icon.svg diff --git a/airbyte-integrations/connectors/source-sage-hr/metadata.yaml b/airbyte-integrations/connectors/source-sage-hr/metadata.yaml index 9e186b620b2c..885c3e413ffd 100644 --- a/airbyte-integrations/connectors/source-sage-hr/metadata.yaml +++ b/airbyte-integrations/connectors/source-sage-hr/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-sage-hr connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: d8384215-9de6-4268-bbea-40c636ee14c7 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.9 dockerRepository: airbyte/source-sage-hr githubIssueLabel: source-sage-hr icon: icon.svg diff --git a/airbyte-integrations/connectors/source-salesflare/README.md b/airbyte-integrations/connectors/source-salesflare/README.md new file mode 100644 index 000000000000..404f9f90d348 --- /dev/null +++ b/airbyte-integrations/connectors/source-salesflare/README.md @@ -0,0 +1,35 @@ +# Salesflare +This directory contains the manifest-only connector for `source-salesflare`. + +Salesflare is a CRM tool for small and medium businesses. +Using this connector we can extract data from various streams such as opportunities , workflows and pipelines. +Docs : https://api.salesflare.com/docs + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-salesflare:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-salesflare build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-salesflare test +``` + diff --git a/airbyte-integrations/connectors/source-salesflare/acceptance-test-config.yml b/airbyte-integrations/connectors/source-salesflare/acceptance-test-config.yml new file mode 100644 index 000000000000..28474548d1e2 --- /dev/null +++ b/airbyte-integrations/connectors/source-salesflare/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-salesflare:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-salesflare/icon.svg b/airbyte-integrations/connectors/source-salesflare/icon.svg new file mode 100644 index 000000000000..2b7d4f7df17b --- /dev/null +++ b/airbyte-integrations/connectors/source-salesflare/icon.svg @@ -0,0 +1,188 @@ + + + + diff --git a/airbyte-integrations/connectors/source-salesflare/manifest.yaml b/airbyte-integrations/connectors/source-salesflare/manifest.yaml new file mode 100644 index 000000000000..3f8bf3eaa50d --- /dev/null +++ b/airbyte-integrations/connectors/source-salesflare/manifest.yaml @@ -0,0 +1,2195 @@ +version: 6.1.0 + +type: DeclarativeSource + +description: >- + Salesflare is a CRM tool for small and medium businesses. + + Using this connector we can extract data from various streams such as + opportunities , workflows and pipelines. + + Docs : https://api.salesflare.com/docs + +check: + type: CheckStream + stream_names: + - tasks + +definitions: + streams: + tasks: + type: DeclarativeStream + name: tasks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: tasks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 20 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tasks" + accounts: + type: DeclarativeStream + name: accounts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: accounts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 10 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounts" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 20 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + opportunities: + type: DeclarativeStream + name: opportunities + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: opportunities + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 20 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/opportunities" + workflows: + type: DeclarativeStream + name: workflows + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: workflows + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 20 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/workflows" + tags: + type: DeclarativeStream + name: tags + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: tags + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 20 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tags" + persons: + type: DeclarativeStream + name: persons + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: persons + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/persons" + email data sources: + type: DeclarativeStream + name: email data sources + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: datasources/email + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/email data sources" + custom field types: + type: DeclarativeStream + name: custom field types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: customfields/types + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/custom field types" + pipelines: + type: DeclarativeStream + name: pipelines + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pipelines + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/pipelines" + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 20 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + base_requester: + type: HttpRequester + url_base: https://api.salesflare.com/ + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: Authorization + inject_into: header + +streams: + - $ref: "#/definitions/streams/tasks" + - $ref: "#/definitions/streams/accounts" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/opportunities" + - $ref: "#/definitions/streams/workflows" + - $ref: "#/definitions/streams/tags" + - $ref: "#/definitions/streams/persons" + - $ref: "#/definitions/streams/email data sources" + - $ref: "#/definitions/streams/custom field types" + - $ref: "#/definitions/streams/pipelines" + - $ref: "#/definitions/streams/users" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + description: "Enter you api key like this : Bearer YOUR_API_KEY" + order: 0 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + tasks: true + accounts: true + contacts: true + opportunities: true + workflows: true + tags: true + persons: true + email data sources: true + custom field types: true + pipelines: true + users: true + testedStreams: + tasks: + hasRecords: true + streamHash: 4afe935d7b371d7ca3c1118f204594f612bb26f9 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + accounts: + hasRecords: true + streamHash: a2b02a7b6dc2f874679649a2b3e2232907dcd269 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + contacts: + hasRecords: true + streamHash: d8c27f18a1e8a7e906a9ec8dc2154366032efb27 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + opportunities: + hasRecords: true + streamHash: 1536aa5c34adb9703f039b971d7968b9efb71dd7 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + workflows: + hasRecords: true + streamHash: e24f462be53bd36f71b9280cc16de99e7c58e90f + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + tags: + hasRecords: true + streamHash: bbb4d37d5f81bf936a2b444ee2b5c076ad63026c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + persons: + hasRecords: true + streamHash: 81c21e4b4310dcbd9b235f905743303a73e43ebe + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + email data sources: + hasRecords: true + streamHash: 44e767c5abae8d6e264b8082d033660b6af3c449 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + custom field types: + hasRecords: true + streamHash: 6ea245f971acb34ccb65ac54c5f423fe5714f44d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + pipelines: + hasRecords: true + streamHash: 1193de2ee994831ccf6dac18718c9edc8925e572 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + users: + hasRecords: true + streamHash: 9dc2333a4151500b5125359f05e7ceab46d304ce + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: {} + +schemas: + tasks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + account: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + picture: + type: + - string + - "null" + archived: + type: + - boolean + - "null" + assignees: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + disabled: + type: + - boolean + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + picture: + type: + - string + - "null" + can_edit: + type: + - boolean + - "null" + completed: + type: + - boolean + - "null" + completion_date: + type: + - string + - "null" + completor: + type: + - number + - "null" + creation_date: + type: + - string + - "null" + creator: + type: + - number + - "null" + email: + type: + - object + - "null" + properties: + data_source: + type: + - number + - "null" + email_message_id: + type: + - string + - "null" + id: + type: + - number + - "null" + service_message_id: + type: + - string + - "null" + subject: + type: + - string + - "null" + id: + type: number + last_modified_by: + type: + - number + - "null" + modification_date: + type: + - string + - "null" + reminder_date: + type: + - string + - "null" + required: + - id + accounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + addresses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + country: + type: + - string + - "null" + id: + type: + - number + - "null" + region: + type: + - string + - "null" + state_region: + type: + - string + - "null" + street: + type: + - string + - "null" + zip: + type: + - string + - "null" + can_edit: + type: + - boolean + - "null" + creation_date: + type: + - string + - "null" + domain: + type: + - string + - "null" + email_addresses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - number + - "null" + hotness: + type: + - number + - "null" + id: + type: number + last_email_date: + type: + - string + - "null" + last_interaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + date: + type: + - string + - "null" + person: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + picture: + type: + - string + - "null" + last_interaction_date: + type: + - string + - "null" + modification_date: + type: + - string + - "null" + name: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + picture: + type: + - string + - "null" + part_of: + type: + - boolean + - "null" + phone_numbers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + number: + type: + - string + - "null" + picture: + type: + - string + - "null" + size: + type: + - number + - "null" + social_profiles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + url: + type: + - string + - "null" + username: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + website: + type: + - string + - "null" + required: + - id + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account: + type: + - object + - "null" + properties: + domain: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + picture: + type: + - string + - "null" + addresses: + type: + - array + - "null" + archived: + type: + - boolean + - "null" + bounced: + type: + - boolean + - "null" + can_edit: + type: + - boolean + - "null" + creation_date: + type: + - string + - "null" + domain: + type: + - string + - "null" + email: + type: + - string + - "null" + firstname: + type: + - string + - "null" + id: + type: number + last_email_date: + type: + - string + - "null" + lastname: + type: + - string + - "null" + middle: + type: + - string + - "null" + modification_date: + type: + - string + - "null" + name: + type: + - string + - "null" + not_viewed: + type: + - boolean + - "null" + opt-out: + type: + - boolean + - "null" + organisation: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + picture: + type: + - string + - "null" + phone_number: + type: + - string + - "null" + phone_numbers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + number: + type: + - string + - "null" + picture: + type: + - string + - "null" + positions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + organisation: + type: + - string + - "null" + role: + type: + - string + - "null" + prefix: + type: + - string + - "null" + role: + type: + - string + - "null" + social_profiles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + url: + type: + - string + - "null" + username: + type: + - string + - "null" + suffix: + type: + - string + - "null" + tags: + type: + - array + - "null" + required: + - id + opportunities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account: + type: + - object + - "null" + properties: + hotness: + type: + - number + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + picture: + type: + - string + - "null" + assignee: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + picture: + type: + - string + - "null" + calculated_value: + type: + - number + - "null" + can_edit: + type: + - boolean + - "null" + close_date: + type: + - string + - "null" + closed: + type: + - boolean + - "null" + creation_date: + type: + - string + - "null" + creator: + type: + - number + - "null" + currency: + type: + - object + - "null" + properties: + html: + type: + - string + - "null" + id: + type: + - number + - "null" + iso: + type: + - string + - "null" + done: + type: + - boolean + - "null" + id: + type: number + last_interaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + date: + type: + - string + - "null" + person: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + picture: + type: + - string + - "null" + last_modified_by: + type: + - number + - "null" + last_stage_change_date: + type: + - string + - "null" + modification_date: + type: + - string + - "null" + name: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + disabled: + type: + - boolean + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + picture: + type: + - string + - "null" + pipeline: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + probability: + type: + - number + - "null" + stage: + type: + - object + - "null" + properties: + color: + type: + - string + - "null" + fixed_stage: + type: + - number + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + order: + type: + - number + - "null" + probability: + type: + - number + - "null" + start_date: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + units: + type: + - number + - "null" + value: + type: + - number + - "null" + required: + - id + workflows: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + analytics: + type: + - object + - "null" + properties: + exited: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + name: + type: + - string + - "null" + value: + type: + - number + - "null" + in: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + name: + type: + - string + - "null" + value: + type: + - number + - "null" + met_goal: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + name: + type: + - string + - "null" + value: + type: + - number + - "null" + total: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + name: + type: + - string + - "null" + value: + type: + - number + - "null" + archived: + type: + - boolean + - "null" + can_edit: + type: + - boolean + - "null" + continuous: + type: + - boolean + - "null" + created_by: + type: + - number + - "null" + creation_date: + type: + - string + - "null" + creator_name: + type: + - string + - "null" + exit_after_days: + type: + - number + - "null" + id: + type: number + modification_date: + type: + - string + - "null" + multi_step_before_pro_release: + type: + - boolean + - "null" + name: + type: + - string + - "null" + record_type: + type: + - string + - "null" + schedule_date: + type: + - string + - "null" + schedule_days: + type: + - array + - "null" + items: + type: + - number + - "null" + schedule_time_end: + type: + - string + - "null" + schedule_time_start: + type: + - string + - "null" + scheduled_before_pro_release: + type: + - boolean + - "null" + status: + type: + - string + - "null" + step_amount: + type: + - number + - "null" + team: + type: + - number + - "null" + required: + - id + tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + account_count: + type: + - number + - "null" + automated: + type: + - boolean + - "null" + creation_date: + type: + - string + - "null" + id: + type: number + modification_date: + type: + - string + - "null" + name: + type: + - string + - "null" + opportunity_count: + type: + - number + - "null" + person_count: + type: + - number + - "null" + team: + type: + - number + - "null" + total_count: + type: + - number + - "null" + required: + - id + persons: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + account: + type: + - object + - "null" + properties: + domain: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + picture: + type: + - string + - "null" + addresses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + country: + type: + - string + - "null" + id: + type: + - number + - "null" + region: + type: + - string + - "null" + state_region: + type: + - string + - "null" + street: + type: + - string + - "null" + zip: + type: + - string + - "null" + archived: + type: + - boolean + - "null" + bounced: + type: + - boolean + - "null" + can_edit: + type: + - boolean + - "null" + creation_date: + type: + - string + - "null" + data_sources: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + status: + type: + - string + - "null" + status_message: + type: + - string + - "null" + sync_status: + type: + - string + - "null" + disabled: + type: + - boolean + - "null" + domain: + type: + - string + - "null" + email: + type: + - string + - "null" + firstname: + type: + - string + - "null" + id: + type: number + last_email_date: + type: + - string + - "null" + lastname: + type: + - string + - "null" + middle: + type: + - string + - "null" + modification_date: + type: + - string + - "null" + name: + type: + - string + - "null" + not_viewed: + type: + - boolean + - "null" + opt-out: + type: + - boolean + - "null" + owner: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + picture: + type: + - string + - "null" + phone_number: + type: + - string + - "null" + phone_numbers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + number: + type: + - string + - "null" + picture: + type: + - string + - "null" + positions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + organisation: + type: + - string + - "null" + role: + type: + - string + - "null" + prefix: + type: + - string + - "null" + social_profiles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + url: + type: + - string + - "null" + username: + type: + - string + - "null" + suffix: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + team: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + required: + - id + email data sources: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + add_signature_to_campaign: + type: + - boolean + - "null" + add_signature_to_replies: + type: + - boolean + - "null" + aliases: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + display_name: + type: + - string + - "null" + email: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: number + max_emails_day: + type: + - number + - "null" + max_emails_hour: + type: + - number + - "null" + name: + type: + - string + - "null" + primary: + type: + - boolean + - "null" + status: + type: + - string + - "null" + sync_status: + type: + - string + - "null" + team: + type: + - number + - "null" + user: + type: + - number + - "null" + required: + - id + custom field types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + displayName: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + required: + - id + pipelines: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + archived: + type: + - boolean + - "null" + creation_date: + type: + - string + - "null" + currency: + type: + - object + - "null" + properties: + html: + type: + - string + - "null" + id: + type: + - number + - "null" + iso: + type: + - string + - "null" + default_pipeline: + type: + - boolean + - "null" + follows_default_team_currency: + type: + - boolean + - "null" + groups: + type: + - array + - "null" + id: + type: number + modification_date: + type: + - string + - "null" + name: + type: + - string + - "null" + order: + type: + - number + - "null" + recurring: + type: + - boolean + - "null" + stages: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + color: + type: + - string + - "null" + days_until_account_inactive: + type: + - number + - "null" + fixed_stage: + type: + - number + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + order: + type: + - number + - "null" + probability: + type: + - number + - "null" + team: + type: + - number + - "null" + required: + - id + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + addresses: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + country: + type: + - string + - "null" + id: + type: + - number + - "null" + region: + type: + - string + - "null" + state_region: + type: + - string + - "null" + street: + type: + - string + - "null" + zip: + type: + - string + - "null" + creation_date: + type: + - string + - "null" + data_sources: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + status: + type: + - string + - "null" + status_message: + type: + - string + - "null" + sync_status: + type: + - string + - "null" + disabled: + type: + - boolean + - "null" + domain: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: number + modification_date: + type: + - string + - "null" + name: + type: + - string + - "null" + phone_numbers: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + number: + type: + - string + - "null" + picture: + type: + - string + - "null" + positions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + organisation: + type: + - string + - "null" + role: + type: + - string + - "null" + social_profiles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + url: + type: + - string + - "null" + username: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + team: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-salesflare/metadata.yaml b/airbyte-integrations/connectors/source-salesflare/metadata.yaml new file mode 100644 index 000000000000..caca83bee3d5 --- /dev/null +++ b/airbyte-integrations/connectors/source-salesflare/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.salesflare.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-salesflare + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: a312f5ec-ba92-4c5b-a03c-197fbd961b91 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-salesflare + githubIssueLabel: source-salesflare + icon: icon.svg + license: MIT + name: Salesflare + releaseDate: 2024-11-07 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/salesflare + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-salesforce/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-salesforce/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-salesforce/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-salesforce/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-salesforce/integration_tests/bulk_error_test.py b/airbyte-integrations/connectors/source-salesforce/integration_tests/bulk_error_test.py index 829350b46560..7372ebf129c4 100644 --- a/airbyte-integrations/connectors/source-salesforce/integration_tests/bulk_error_test.py +++ b/airbyte-integrations/connectors/source-salesforce/integration_tests/bulk_error_test.py @@ -10,10 +10,12 @@ import pytest import requests_mock +from source_salesforce.source import SourceSalesforce + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.streams import Stream from airbyte_cdk.test.catalog_builder import CatalogBuilder -from source_salesforce.source import SourceSalesforce + HERE = Path(__file__).parent _ANY_CATALOG = CatalogBuilder().build() diff --git a/airbyte-integrations/connectors/source-salesforce/integration_tests/integration_test.py b/airbyte-integrations/connectors/source-salesforce/integration_tests/integration_test.py index 1742ef72a923..50926148b631 100644 --- a/airbyte-integrations/connectors/source-salesforce/integration_tests/integration_test.py +++ b/airbyte-integrations/connectors/source-salesforce/integration_tests/integration_test.py @@ -12,11 +12,13 @@ import pendulum import pytest import requests -from airbyte_cdk.models import SyncMode -from airbyte_cdk.test.catalog_builder import CatalogBuilder from source_salesforce.api import Salesforce from source_salesforce.source import SourceSalesforce +from airbyte_cdk.models import SyncMode +from airbyte_cdk.test.catalog_builder import CatalogBuilder + + HERE = Path(__file__).parent NOTE_CONTENT = "It's the note for integration test" @@ -51,7 +53,11 @@ def stream_name(): @pytest.fixture(scope="module") def stream(input_sandbox_config, stream_name, sf): - return SourceSalesforce(_ANY_CATALOG, _ANY_CONFIG, _ANY_STATE).generate_streams(input_sandbox_config, {stream_name: None}, sf)[0]._legacy_stream + return ( + SourceSalesforce(_ANY_CATALOG, _ANY_CONFIG, _ANY_STATE) + .generate_streams(input_sandbox_config, {stream_name: None}, sf)[0] + ._legacy_stream + ) def _encode_content(text): diff --git a/airbyte-integrations/connectors/source-salesforce/integration_tests/state_migration.py b/airbyte-integrations/connectors/source-salesforce/integration_tests/state_migration.py index d03de9ed39e8..d6820c89bfbe 100644 --- a/airbyte-integrations/connectors/source-salesforce/integration_tests/state_migration.py +++ b/airbyte-integrations/connectors/source-salesforce/integration_tests/state_migration.py @@ -2612,11 +2612,12 @@ import json + result = [] for stream in json.loads(x): stream["stream_descriptor"] = stream.pop("streamDescriptor") stream["stream_state"] = stream.pop("streamState") - y = { + y = { "type": "STREAM", "stream": stream, } diff --git a/airbyte-integrations/connectors/source-salesforce/main.py b/airbyte-integrations/connectors/source-salesforce/main.py index 67536217f497..5ae62f667335 100644 --- a/airbyte-integrations/connectors/source-salesforce/main.py +++ b/airbyte-integrations/connectors/source-salesforce/main.py @@ -5,5 +5,6 @@ from source_salesforce.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-salesforce/metadata.yaml b/airbyte-integrations/connectors/source-salesforce/metadata.yaml index 1b02acbb7e25..630ecf0c05b7 100644 --- a/airbyte-integrations/connectors/source-salesforce/metadata.yaml +++ b/airbyte-integrations/connectors/source-salesforce/metadata.yaml @@ -10,7 +10,7 @@ data: connectorSubtype: api connectorType: source definitionId: b117307c-14b6-41aa-9422-947e34922962 - dockerImageTag: 2.6.2 + dockerImageTag: 2.6.3 dockerRepository: airbyte/source-salesforce documentationUrl: https://docs.airbyte.com/integrations/sources/salesforce githubIssueLabel: source-salesforce diff --git a/airbyte-integrations/connectors/source-salesforce/poetry.lock b/airbyte-integrations/connectors/source-salesforce/poetry.lock index 0f9efab2609d..df1baa0b2e15 100644 --- a/airbyte-integrations/connectors/source-salesforce/poetry.lock +++ b/airbyte-integrations/connectors/source-salesforce/poetry.lock @@ -1,14 +1,14 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "airbyte-cdk" -version = "5.13.0" +version = "5.17.0" description = "A framework for writing Airbyte Connectors." optional = false python-versions = "<4.0,>=3.10" files = [ - {file = "airbyte_cdk-5.13.0-py3-none-any.whl", hash = "sha256:b26c99631e797c0bdb8373a6a05c81bf62b7d7397ca41b6ee05702d1013bd389"}, - {file = "airbyte_cdk-5.13.0.tar.gz", hash = "sha256:ab5799a238366dff61a8cded347b02deb63818513af4e61e2d1a51608a2280df"}, + {file = "airbyte_cdk-5.17.0-py3-none-any.whl", hash = "sha256:135a8fc43b00a92169dfcdc43c1d7c629aba871a0b471f950ca5d76d3741fc92"}, + {file = "airbyte_cdk-5.17.0.tar.gz", hash = "sha256:5db70cbacec80ba3beabe4253480ab9a3947a450e8d0e39af4a91638b317b32a"}, ] [package.dependencies] @@ -43,6 +43,7 @@ xmltodict = ">=0.13.0,<0.14.0" [package.extras] file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "python-snappy (==0.7.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] +sql = ["sqlalchemy (>=2.0,!=2.0.36,<3.0)"] vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] [[package]] @@ -69,13 +70,13 @@ files = [ [[package]] name = "anyio" -version = "4.6.0" +version = "4.6.2.post1" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.0-py3-none-any.whl", hash = "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a"}, - {file = "anyio-4.6.0.tar.gz", hash = "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb"}, + {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, + {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, ] [package.dependencies] @@ -86,7 +87,7 @@ typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} [package.extras] doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.21.0b1)"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -742,13 +743,13 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.133" +version = "0.1.139" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.133-py3-none-any.whl", hash = "sha256:82e837a6039c483beadbe19c2ba7ebafbd402d3e8105234f5ef334425cff7b45"}, - {file = "langsmith-0.1.133.tar.gz", hash = "sha256:7bfd8bef166b9a64ee540a11bee4aa7bf43b1d9229f95b0fc19086454955185d"}, + {file = "langsmith-0.1.139-py3-none-any.whl", hash = "sha256:2a4a541bfbd0a9727255df28a60048c85bc8c4c6a276975923785c3fd82dc879"}, + {file = "langsmith-0.1.139.tar.gz", hash = "sha256:2f9e4d32fef3ad7ef42c8506448cce3a31ad6b78bb4f3310db04ddaa1e9d744d"}, ] [package.dependencies] @@ -760,72 +761,72 @@ requests-toolbelt = ">=1.0.0,<2.0.0" [[package]] name = "markupsafe" -version = "3.0.1" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" files = [ - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win32.whl", hash = "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win32.whl", hash = "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win32.whl", hash = "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win32.whl", hash = "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win32.whl", hash = "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b"}, - {file = "markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] @@ -855,130 +856,133 @@ twitter = ["twython"] [[package]] name = "numpy" -version = "2.1.2" +version = "2.1.3" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.10" files = [ - {file = "numpy-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466"}, - {file = "numpy-2.1.2-cp310-cp310-win32.whl", hash = "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb"}, - {file = "numpy-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146"}, - {file = "numpy-2.1.2-cp311-cp311-win32.whl", hash = "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c"}, - {file = "numpy-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142"}, - {file = "numpy-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550"}, - {file = "numpy-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe"}, - {file = "numpy-2.1.2-cp313-cp313-win32.whl", hash = "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a"}, - {file = "numpy-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e"}, - {file = "numpy-2.1.2.tar.gz", hash = "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c"}, + {file = "numpy-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c894b4305373b9c5576d7a12b473702afdf48ce5369c074ba304cc5ad8730dff"}, + {file = "numpy-2.1.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b47fbb433d3260adcd51eb54f92a2ffbc90a4595f8970ee00e064c644ac788f5"}, + {file = "numpy-2.1.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:825656d0743699c529c5943554d223c021ff0494ff1442152ce887ef4f7561a1"}, + {file = "numpy-2.1.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:6a4825252fcc430a182ac4dee5a505053d262c807f8a924603d411f6718b88fd"}, + {file = "numpy-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e711e02f49e176a01d0349d82cb5f05ba4db7d5e7e0defd026328e5cfb3226d3"}, + {file = "numpy-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78574ac2d1a4a02421f25da9559850d59457bac82f2b8d7a44fe83a64f770098"}, + {file = "numpy-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c7662f0e3673fe4e832fe07b65c50342ea27d989f92c80355658c7f888fcc83c"}, + {file = "numpy-2.1.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fa2d1337dc61c8dc417fbccf20f6d1e139896a30721b7f1e832b2bb6ef4eb6c4"}, + {file = "numpy-2.1.3-cp310-cp310-win32.whl", hash = "sha256:72dcc4a35a8515d83e76b58fdf8113a5c969ccd505c8a946759b24e3182d1f23"}, + {file = "numpy-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:ecc76a9ba2911d8d37ac01de72834d8849e55473457558e12995f4cd53e778e0"}, + {file = "numpy-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4d1167c53b93f1f5d8a139a742b3c6f4d429b54e74e6b57d0eff40045187b15d"}, + {file = "numpy-2.1.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c80e4a09b3d95b4e1cac08643f1152fa71a0a821a2d4277334c88d54b2219a41"}, + {file = "numpy-2.1.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:576a1c1d25e9e02ed7fa5477f30a127fe56debd53b8d2c89d5578f9857d03ca9"}, + {file = "numpy-2.1.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:973faafebaae4c0aaa1a1ca1ce02434554d67e628b8d805e61f874b84e136b09"}, + {file = "numpy-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:762479be47a4863e261a840e8e01608d124ee1361e48b96916f38b119cfda04a"}, + {file = "numpy-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc6f24b3d1ecc1eebfbf5d6051faa49af40b03be1aaa781ebdadcbc090b4539b"}, + {file = "numpy-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:17ee83a1f4fef3c94d16dc1802b998668b5419362c8a4f4e8a491de1b41cc3ee"}, + {file = "numpy-2.1.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:15cb89f39fa6d0bdfb600ea24b250e5f1a3df23f901f51c8debaa6a5d122b2f0"}, + {file = "numpy-2.1.3-cp311-cp311-win32.whl", hash = "sha256:d9beb777a78c331580705326d2367488d5bc473b49a9bc3036c154832520aca9"}, + {file = "numpy-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:d89dd2b6da69c4fff5e39c28a382199ddedc3a5be5390115608345dec660b9e2"}, + {file = "numpy-2.1.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f55ba01150f52b1027829b50d70ef1dafd9821ea82905b63936668403c3b471e"}, + {file = "numpy-2.1.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13138eadd4f4da03074851a698ffa7e405f41a0845a6b1ad135b81596e4e9958"}, + {file = "numpy-2.1.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:a6b46587b14b888e95e4a24d7b13ae91fa22386c199ee7b418f449032b2fa3b8"}, + {file = "numpy-2.1.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:0fa14563cc46422e99daef53d725d0c326e99e468a9320a240affffe87852564"}, + {file = "numpy-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8637dcd2caa676e475503d1f8fdb327bc495554e10838019651b76d17b98e512"}, + {file = "numpy-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2312b2aa89e1f43ecea6da6ea9a810d06aae08321609d8dc0d0eda6d946a541b"}, + {file = "numpy-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a38c19106902bb19351b83802531fea19dee18e5b37b36454f27f11ff956f7fc"}, + {file = "numpy-2.1.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:02135ade8b8a84011cbb67dc44e07c58f28575cf9ecf8ab304e51c05528c19f0"}, + {file = "numpy-2.1.3-cp312-cp312-win32.whl", hash = "sha256:e6988e90fcf617da2b5c78902fe8e668361b43b4fe26dbf2d7b0f8034d4cafb9"}, + {file = "numpy-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:0d30c543f02e84e92c4b1f415b7c6b5326cbe45ee7882b6b77db7195fb971e3a"}, + {file = "numpy-2.1.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96fe52fcdb9345b7cd82ecd34547fca4321f7656d500eca497eb7ea5a926692f"}, + {file = "numpy-2.1.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f653490b33e9c3a4c1c01d41bc2aef08f9475af51146e4a7710c450cf9761598"}, + {file = "numpy-2.1.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:dc258a761a16daa791081d026f0ed4399b582712e6fc887a95af09df10c5ca57"}, + {file = "numpy-2.1.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:016d0f6f5e77b0f0d45d77387ffa4bb89816b57c835580c3ce8e099ef830befe"}, + {file = "numpy-2.1.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c181ba05ce8299c7aa3125c27b9c2167bca4a4445b7ce73d5febc411ca692e43"}, + {file = "numpy-2.1.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5641516794ca9e5f8a4d17bb45446998c6554704d888f86df9b200e66bdcce56"}, + {file = "numpy-2.1.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ea4dedd6e394a9c180b33c2c872b92f7ce0f8e7ad93e9585312b0c5a04777a4a"}, + {file = "numpy-2.1.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0df3635b9c8ef48bd3be5f862cf71b0a4716fa0e702155c45067c6b711ddcef"}, + {file = "numpy-2.1.3-cp313-cp313-win32.whl", hash = "sha256:50ca6aba6e163363f132b5c101ba078b8cbd3fa92c7865fd7d4d62d9779ac29f"}, + {file = "numpy-2.1.3-cp313-cp313-win_amd64.whl", hash = "sha256:747641635d3d44bcb380d950679462fae44f54b131be347d5ec2bce47d3df9ed"}, + {file = "numpy-2.1.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:996bb9399059c5b82f76b53ff8bb686069c05acc94656bb259b1d63d04a9506f"}, + {file = "numpy-2.1.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:45966d859916ad02b779706bb43b954281db43e185015df6eb3323120188f9e4"}, + {file = "numpy-2.1.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:baed7e8d7481bfe0874b566850cb0b85243e982388b7b23348c6db2ee2b2ae8e"}, + {file = "numpy-2.1.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:a9f7f672a3388133335589cfca93ed468509cb7b93ba3105fce780d04a6576a0"}, + {file = "numpy-2.1.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7aac50327da5d208db2eec22eb11e491e3fe13d22653dce51b0f4109101b408"}, + {file = "numpy-2.1.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4394bc0dbd074b7f9b52024832d16e019decebf86caf909d94f6b3f77a8ee3b6"}, + {file = "numpy-2.1.3-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:50d18c4358a0a8a53f12a8ba9d772ab2d460321e6a93d6064fc22443d189853f"}, + {file = "numpy-2.1.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:14e253bd43fc6b37af4921b10f6add6925878a42a0c5fe83daee390bca80bc17"}, + {file = "numpy-2.1.3-cp313-cp313t-win32.whl", hash = "sha256:08788d27a5fd867a663f6fc753fd7c3ad7e92747efc73c53bca2f19f8bc06f48"}, + {file = "numpy-2.1.3-cp313-cp313t-win_amd64.whl", hash = "sha256:2564fbdf2b99b3f815f2107c1bbc93e2de8ee655a69c261363a1172a79a257d4"}, + {file = "numpy-2.1.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4f2015dfe437dfebbfce7c85c7b53d81ba49e71ba7eadbf1df40c915af75979f"}, + {file = "numpy-2.1.3-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:3522b0dfe983a575e6a9ab3a4a4dfe156c3e428468ff08ce582b9bb6bd1d71d4"}, + {file = "numpy-2.1.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c006b607a865b07cd981ccb218a04fc86b600411d83d6fc261357f1c0966755d"}, + {file = "numpy-2.1.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e14e26956e6f1696070788252dcdff11b4aca4c3e8bd166e0df1bb8f315a67cb"}, + {file = "numpy-2.1.3.tar.gz", hash = "sha256:aa08e04e08aaf974d4458def539dece0d28146d866a39da5639596f4921fd761"}, ] [[package]] name = "orjson" -version = "3.10.7" +version = "3.10.11" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:74f4544f5a6405b90da8ea724d15ac9c36da4d72a738c64685003337401f5c12"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34a566f22c28222b08875b18b0dfbf8a947e69df21a9ed5c51a6bf91cfb944ac"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf6ba8ebc8ef5792e2337fb0419f8009729335bb400ece005606336b7fd7bab7"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac7cf6222b29fbda9e3a472b41e6a5538b48f2c8f99261eecd60aafbdb60690c"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de817e2f5fc75a9e7dd350c4b0f54617b280e26d1631811a43e7e968fa71e3e9"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:348bdd16b32556cf8d7257b17cf2bdb7ab7976af4af41ebe79f9796c218f7e91"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:479fd0844ddc3ca77e0fd99644c7fe2de8e8be1efcd57705b5c92e5186e8a250"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fdf5197a21dd660cf19dfd2a3ce79574588f8f5e2dbf21bda9ee2d2b46924d84"}, - {file = "orjson-3.10.7-cp310-none-win32.whl", hash = "sha256:d374d36726746c81a49f3ff8daa2898dccab6596864ebe43d50733275c629175"}, - {file = "orjson-3.10.7-cp310-none-win_amd64.whl", hash = "sha256:cb61938aec8b0ffb6eef484d480188a1777e67b05d58e41b435c74b9d84e0b9c"}, - {file = "orjson-3.10.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0"}, - {file = "orjson-3.10.7-cp311-none-win32.whl", hash = "sha256:82763b46053727a7168d29c772ed5c870fdae2f61aa8a25994c7984a19b1021f"}, - {file = "orjson-3.10.7-cp311-none-win_amd64.whl", hash = "sha256:eb8d384a24778abf29afb8e41d68fdd9a156cf6e5390c04cc07bbc24b89e98b5"}, - {file = "orjson-3.10.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44a96f2d4c3af51bfac6bc4ef7b182aa33f2f054fd7f34cc0ee9a320d051d41f"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ac14cd57df0572453543f8f2575e2d01ae9e790c21f57627803f5e79b0d3c3"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bdbb61dcc365dd9be94e8f7df91975edc9364d6a78c8f7adb69c1cdff318ec93"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b48b3db6bb6e0a08fa8c83b47bc169623f801e5cc4f24442ab2b6617da3b5313"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23820a1563a1d386414fef15c249040042b8e5d07b40ab3fe3efbfbbcbcb8864"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0c6a008e91d10a2564edbb6ee5069a9e66df3fbe11c9a005cb411f441fd2c09"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d352ee8ac1926d6193f602cbe36b1643bbd1bbcb25e3c1a657a4390f3000c9a5"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b"}, - {file = "orjson-3.10.7-cp312-none-win32.whl", hash = "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb"}, - {file = "orjson-3.10.7-cp312-none-win_amd64.whl", hash = "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1"}, - {file = "orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149"}, - {file = "orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad"}, - {file = "orjson-3.10.7-cp313-none-win32.whl", hash = "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2"}, - {file = "orjson-3.10.7-cp313-none-win_amd64.whl", hash = "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024"}, - {file = "orjson-3.10.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6ea2b2258eff652c82652d5e0f02bd5e0463a6a52abb78e49ac288827aaa1469"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:430ee4d85841e1483d487e7b81401785a5dfd69db5de01314538f31f8fbf7ee1"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b6146e439af4c2472c56f8540d799a67a81226e11992008cb47e1267a9b3225"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:084e537806b458911137f76097e53ce7bf5806dda33ddf6aaa66a028f8d43a23"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829cf2195838e3f93b70fd3b4292156fc5e097aac3739859ac0dcc722b27ac0"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1193b2416cbad1a769f868b1749535d5da47626ac29445803dae7cc64b3f5c98"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4e6c3da13e5a57e4b3dca2de059f243ebec705857522f188f0180ae88badd354"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c31008598424dfbe52ce8c5b47e0752dca918a4fdc4a2a32004efd9fab41d866"}, - {file = "orjson-3.10.7-cp38-none-win32.whl", hash = "sha256:7122a99831f9e7fe977dc45784d3b2edc821c172d545e6420c375e5a935f5a1c"}, - {file = "orjson-3.10.7-cp38-none-win_amd64.whl", hash = "sha256:a763bc0e58504cc803739e7df040685816145a6f3c8a589787084b54ebc9f16e"}, - {file = "orjson-3.10.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e76be12658a6fa376fcd331b1ea4e58f5a06fd0220653450f0d415b8fd0fbe20"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed350d6978d28b92939bfeb1a0570c523f6170efc3f0a0ef1f1df287cd4f4960"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144888c76f8520e39bfa121b31fd637e18d4cc2f115727865fdf9fa325b10412"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09b2d92fd95ad2402188cf51573acde57eb269eddabaa60f69ea0d733e789fe9"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b24a579123fa884f3a3caadaed7b75eb5715ee2b17ab5c66ac97d29b18fe57f"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591bcfe7512353bd609875ab38050efe3d55e18934e2f18950c108334b4ff"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f4db56635b58cd1a200b0a23744ff44206ee6aa428185e2b6c4a65b3197abdcd"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0fa5886854673222618638c6df7718ea7fe2f3f2384c452c9ccedc70b4a510a5"}, - {file = "orjson-3.10.7-cp39-none-win32.whl", hash = "sha256:8272527d08450ab16eb405f47e0f4ef0e5ff5981c3d82afe0efd25dcbef2bcd2"}, - {file = "orjson-3.10.7-cp39-none-win_amd64.whl", hash = "sha256:974683d4618c0c7dbf4f69c95a979734bf183d0658611760017f6e70a145af58"}, - {file = "orjson-3.10.7.tar.gz", hash = "sha256:75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3"}, + {file = "orjson-3.10.11-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6dade64687f2bd7c090281652fe18f1151292d567a9302b34c2dbb92a3872f1f"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82f07c550a6ccd2b9290849b22316a609023ed851a87ea888c0456485a7d196a"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd9a187742d3ead9df2e49240234d728c67c356516cf4db018833a86f20ec18c"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77b0fed6f209d76c1c39f032a70df2d7acf24b1812ca3e6078fd04e8972685a3"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63fc9d5fe1d4e8868f6aae547a7b8ba0a2e592929245fff61d633f4caccdcdd6"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65cd3e3bb4fbb4eddc3c1e8dce10dc0b73e808fcb875f9fab40c81903dd9323e"}, + {file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6f67c570602300c4befbda12d153113b8974a3340fdcf3d6de095ede86c06d92"}, + {file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1f39728c7f7d766f1f5a769ce4d54b5aaa4c3f92d5b84817053cc9995b977acc"}, + {file = "orjson-3.10.11-cp310-none-win32.whl", hash = "sha256:1789d9db7968d805f3d94aae2c25d04014aae3a2fa65b1443117cd462c6da647"}, + {file = "orjson-3.10.11-cp310-none-win_amd64.whl", hash = "sha256:5576b1e5a53a5ba8f8df81872bb0878a112b3ebb1d392155f00f54dd86c83ff6"}, + {file = "orjson-3.10.11-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1444f9cb7c14055d595de1036f74ecd6ce15f04a715e73f33bb6326c9cef01b6"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdec57fe3b4bdebcc08a946db3365630332dbe575125ff3d80a3272ebd0ddafe"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4eed32f33a0ea6ef36ccc1d37f8d17f28a1d6e8eefae5928f76aff8f1df85e67"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80df27dd8697242b904f4ea54820e2d98d3f51f91e97e358fc13359721233e4b"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:705f03cee0cb797256d54de6695ef219e5bc8c8120b6654dd460848d57a9af3d"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03246774131701de8e7059b2e382597da43144a9a7400f178b2a32feafc54bd5"}, + {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8b5759063a6c940a69c728ea70d7c33583991c6982915a839c8da5f957e0103a"}, + {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:677f23e32491520eebb19c99bb34675daf5410c449c13416f7f0d93e2cf5f981"}, + {file = "orjson-3.10.11-cp311-none-win32.whl", hash = "sha256:a11225d7b30468dcb099498296ffac36b4673a8398ca30fdaec1e6c20df6aa55"}, + {file = "orjson-3.10.11-cp311-none-win_amd64.whl", hash = "sha256:df8c677df2f9f385fcc85ab859704045fa88d4668bc9991a527c86e710392bec"}, + {file = "orjson-3.10.11-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:360a4e2c0943da7c21505e47cf6bd725588962ff1d739b99b14e2f7f3545ba51"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:496e2cb45de21c369079ef2d662670a4892c81573bcc143c4205cae98282ba97"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7dfa8db55c9792d53c5952900c6a919cfa377b4f4534c7a786484a6a4a350c19"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:51f3382415747e0dbda9dade6f1e1a01a9d37f630d8c9049a8ed0e385b7a90c0"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f35a1b9f50a219f470e0e497ca30b285c9f34948d3c8160d5ad3a755d9299433"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f3b7c5803138e67028dde33450e054c87e0703afbe730c105f1fcd873496d5"}, + {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f91d9eb554310472bd09f5347950b24442600594c2edc1421403d7610a0998fd"}, + {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dfbb2d460a855c9744bbc8e36f9c3a997c4b27d842f3d5559ed54326e6911f9b"}, + {file = "orjson-3.10.11-cp312-none-win32.whl", hash = "sha256:d4a62c49c506d4d73f59514986cadebb7e8d186ad510c518f439176cf8d5359d"}, + {file = "orjson-3.10.11-cp312-none-win_amd64.whl", hash = "sha256:f1eec3421a558ff7a9b010a6c7effcfa0ade65327a71bb9b02a1c3b77a247284"}, + {file = "orjson-3.10.11-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c46294faa4e4d0eb73ab68f1a794d2cbf7bab33b1dda2ac2959ffb7c61591899"}, + {file = "orjson-3.10.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52e5834d7d6e58a36846e059d00559cb9ed20410664f3ad156cd2cc239a11230"}, + {file = "orjson-3.10.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2fc947e5350fdce548bfc94f434e8760d5cafa97fb9c495d2fef6757aa02ec0"}, + {file = "orjson-3.10.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0efabbf839388a1dab5b72b5d3baedbd6039ac83f3b55736eb9934ea5494d258"}, + {file = "orjson-3.10.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3f29634260708c200c4fe148e42b4aae97d7b9fee417fbdd74f8cfc265f15b0"}, + {file = "orjson-3.10.11-cp313-none-win32.whl", hash = "sha256:1a1222ffcee8a09476bbdd5d4f6f33d06d0d6642df2a3d78b7a195ca880d669b"}, + {file = "orjson-3.10.11-cp313-none-win_amd64.whl", hash = "sha256:bc274ac261cc69260913b2d1610760e55d3c0801bb3457ba7b9004420b6b4270"}, + {file = "orjson-3.10.11-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:19b3763e8bbf8ad797df6b6b5e0fc7c843ec2e2fc0621398534e0c6400098f87"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1be83a13312e5e58d633580c5eb8d0495ae61f180da2722f20562974188af205"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:afacfd1ab81f46dedd7f6001b6d4e8de23396e4884cd3c3436bd05defb1a6446"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb4d0bea56bba596723d73f074c420aec3b2e5d7d30698bc56e6048066bd560c"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96ed1de70fcb15d5fed529a656df29f768187628727ee2788344e8a51e1c1350"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bfb30c891b530f3f80e801e3ad82ef150b964e5c38e1fb8482441c69c35c61c"}, + {file = "orjson-3.10.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d496c74fc2b61341e3cefda7eec21b7854c5f672ee350bc55d9a4997a8a95204"}, + {file = "orjson-3.10.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:655a493bac606655db9a47fe94d3d84fc7f3ad766d894197c94ccf0c5408e7d3"}, + {file = "orjson-3.10.11-cp38-none-win32.whl", hash = "sha256:b9546b278c9fb5d45380f4809e11b4dd9844ca7aaf1134024503e134ed226161"}, + {file = "orjson-3.10.11-cp38-none-win_amd64.whl", hash = "sha256:b592597fe551d518f42c5a2eb07422eb475aa8cfdc8c51e6da7054b836b26782"}, + {file = "orjson-3.10.11-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c95f2ecafe709b4e5c733b5e2768ac569bed308623c85806c395d9cca00e08af"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80c00d4acded0c51c98754fe8218cb49cb854f0f7eb39ea4641b7f71732d2cb7"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:461311b693d3d0a060439aa669c74f3603264d4e7a08faa68c47ae5a863f352d"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52ca832f17d86a78cbab86cdc25f8c13756ebe182b6fc1a97d534051c18a08de"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c57ea78a753812f528178aa2f1c57da633754c91d2124cb28991dab4c79a54"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7fcfc6f7ca046383fb954ba528587e0f9336828b568282b27579c49f8e16aad"}, + {file = "orjson-3.10.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:86b9dd983857970c29e4c71bb3e95ff085c07d3e83e7c46ebe959bac07ebd80b"}, + {file = "orjson-3.10.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4d83f87582d223e54efb2242a79547611ba4ebae3af8bae1e80fa9a0af83bb7f"}, + {file = "orjson-3.10.11-cp39-none-win32.whl", hash = "sha256:9fd0ad1c129bc9beb1154c2655f177620b5beaf9a11e0d10bac63ef3fce96950"}, + {file = "orjson-3.10.11-cp39-none-win_amd64.whl", hash = "sha256:10f416b2a017c8bd17f325fb9dee1fb5cdd7a54e814284896b7c3f2763faa017"}, + {file = "orjson-3.10.11.tar.gz", hash = "sha256:e35b6d730de6384d5b2dab5fd23f0d76fae8bbc8c353c2f78210aa5fa4beb3ef"}, ] [[package]] @@ -1739,23 +1743,23 @@ typing-extensions = "*" [[package]] name = "setuptools" -version = "75.1.0" +version = "75.3.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"}, - {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"}, + {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, + {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, ] [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] [[package]] name = "six" @@ -1807,13 +1811,13 @@ files = [ [[package]] name = "tqdm" -version = "4.66.5" +version = "4.66.6" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd"}, - {file = "tqdm-4.66.5.tar.gz", hash = "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad"}, + {file = "tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63"}, + {file = "tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090"}, ] [package.dependencies] diff --git a/airbyte-integrations/connectors/source-salesforce/pyproject.toml b/airbyte-integrations/connectors/source-salesforce/pyproject.toml index ce4e0928f242..a729c2555a8b 100644 --- a/airbyte-integrations/connectors/source-salesforce/pyproject.toml +++ b/airbyte-integrations/connectors/source-salesforce/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "2.6.2" +version = "2.6.3" name = "source-salesforce" description = "Source implementation for Salesforce." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-salesforce/source_salesforce/api.py b/airbyte-integrations/connectors/source-salesforce/source_salesforce/api.py index 688962a4f8dd..1317006b402b 100644 --- a/airbyte-integrations/connectors/source-salesforce/source_salesforce/api.py +++ b/airbyte-integrations/connectors/source-salesforce/source_salesforce/api.py @@ -7,16 +7,18 @@ from typing import Any, List, Mapping, Optional, Tuple import requests # type: ignore[import] +from requests import adapters as request_adapters +from requests.exceptions import RequestException # type: ignore[import] + from airbyte_cdk.models import ConfiguredAirbyteCatalog, FailureType, StreamDescriptor from airbyte_cdk.sources.streams.http import HttpClient from airbyte_cdk.utils import AirbyteTracedException -from requests import adapters as request_adapters -from requests.exceptions import RequestException # type: ignore[import] from .exceptions import TypeSalesforceException from .rate_limiting import SalesforceErrorHandler, default_backoff_handler from .utils import filter_streams_by_criteria + STRING_TYPES = [ "byte", "combobox", diff --git a/airbyte-integrations/connectors/source-salesforce/source_salesforce/availability_strategy.py b/airbyte-integrations/connectors/source-salesforce/source_salesforce/availability_strategy.py index a4fcca0c1e7a..179c45ea65f4 100644 --- a/airbyte-integrations/connectors/source-salesforce/source_salesforce/availability_strategy.py +++ b/airbyte-integrations/connectors/source-salesforce/source_salesforce/availability_strategy.py @@ -6,9 +6,11 @@ import typing from typing import Optional, Tuple +from requests import HTTPError, codes + from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http.availability_strategy import HttpAvailabilityStrategy -from requests import HTTPError, codes + if typing.TYPE_CHECKING: from airbyte_cdk.sources import Source diff --git a/airbyte-integrations/connectors/source-salesforce/source_salesforce/rate_limiting.py b/airbyte-integrations/connectors/source-salesforce/source_salesforce/rate_limiting.py index 2fa5db058805..13948c7131de 100644 --- a/airbyte-integrations/connectors/source-salesforce/source_salesforce/rate_limiting.py +++ b/airbyte-integrations/connectors/source-salesforce/source_salesforce/rate_limiting.py @@ -9,10 +9,12 @@ import backoff import requests +from requests import codes, exceptions # type: ignore[import] + from airbyte_cdk.models import FailureType from airbyte_cdk.sources.streams.http.error_handlers import ErrorHandler, ErrorResolution, ResponseAction from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException -from requests import codes, exceptions # type: ignore[import] + RESPONSE_CONSUMPTION_EXCEPTIONS = ( # We've had a couple of customers with ProtocolErrors, namely: diff --git a/airbyte-integrations/connectors/source-salesforce/source_salesforce/source.py b/airbyte-integrations/connectors/source-salesforce/source_salesforce/source.py index a4236f1ff728..ac9a1af9d0dd 100644 --- a/airbyte-integrations/connectors/source-salesforce/source_salesforce/source.py +++ b/airbyte-integrations/connectors/source-salesforce/source_salesforce/source.py @@ -8,6 +8,10 @@ import isodate import pendulum +from dateutil.relativedelta import relativedelta +from pendulum.parsing.exceptions import ParserError +from requests import codes, exceptions # type: ignore[import] + from airbyte_cdk.logger import AirbyteLogFormatter from airbyte_cdk.models import ( AirbyteMessage, @@ -30,9 +34,6 @@ from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator from airbyte_cdk.sources.utils.schema_helpers import InternalConfig from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from dateutil.relativedelta import relativedelta -from pendulum.parsing.exceptions import ParserError -from requests import codes, exceptions # type: ignore[import] from .api import PARENT_SALESFORCE_OBJECTS, UNSUPPORTED_BULK_API_SALESFORCE_OBJECTS, UNSUPPORTED_FILTERING_STREAMS, Salesforce from .streams import ( @@ -46,6 +47,7 @@ RestSalesforceSubStream, ) + _DEFAULT_CONCURRENCY = 10 _MAX_CONCURRENCY = 10 logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-salesforce/source_salesforce/streams.py b/airbyte-integrations/connectors/source-salesforce/source_salesforce/streams.py index 6f0ca9a0f60e..2de1867674cb 100644 --- a/airbyte-integrations/connectors/source-salesforce/source_salesforce/streams.py +++ b/airbyte-integrations/connectors/source-salesforce/source_salesforce/streams.py @@ -11,6 +11,9 @@ import pendulum import requests # type: ignore[import] +from pendulum import DateTime # type: ignore[attr-defined] +from requests import exceptions + from airbyte_cdk import ( BearerAuthenticator, CursorPaginationStrategy, @@ -46,13 +49,12 @@ from airbyte_cdk.sources.streams.http import HttpClient, HttpStream, HttpSubStream from airbyte_cdk.sources.types import StreamState from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer -from pendulum import DateTime # type: ignore[attr-defined] -from requests import exceptions from .api import PARENT_SALESFORCE_OBJECTS, UNSUPPORTED_FILTERING_STREAMS, Salesforce from .availability_strategy import SalesforceAvailabilityStrategy from .rate_limiting import BulkNotSupportedException, SalesforceErrorHandler, default_backoff_handler + # https://stackoverflow.com/a/54517228 CSV_FIELD_SIZE_LIMIT = int(ctypes.c_ulong(-1).value // 2) csv.field_size_limit(CSV_FIELD_SIZE_LIMIT) diff --git a/airbyte-integrations/connectors/source-salesforce/unit_tests/api_test.py b/airbyte-integrations/connectors/source-salesforce/unit_tests/api_test.py index 1a59386a1b95..a571cada4f53 100644 --- a/airbyte-integrations/connectors/source-salesforce/unit_tests/api_test.py +++ b/airbyte-integrations/connectors/source-salesforce/unit_tests/api_test.py @@ -13,6 +13,20 @@ import freezegun import pytest import requests_mock +from config_builder import ConfigBuilder +from conftest import generate_stream +from salesforce_job_response_builder import JobInfoResponseBuilder +from source_salesforce.api import Salesforce +from source_salesforce.source import SourceSalesforce +from source_salesforce.streams import ( + CSV_FIELD_SIZE_LIMIT, + BulkIncrementalSalesforceStream, + BulkSalesforceStream, + BulkSalesforceSubStream, + IncrementalRestSalesforceStream, + RestSalesforceStream, +) + from airbyte_cdk.models import ( AirbyteStateBlob, AirbyteStream, @@ -28,19 +42,7 @@ from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.state_builder import StateBuilder from airbyte_cdk.utils import AirbyteTracedException -from config_builder import ConfigBuilder -from conftest import generate_stream -from salesforce_job_response_builder import JobInfoResponseBuilder -from source_salesforce.api import Salesforce -from source_salesforce.source import SourceSalesforce -from source_salesforce.streams import ( - CSV_FIELD_SIZE_LIMIT, - BulkIncrementalSalesforceStream, - BulkSalesforceStream, - BulkSalesforceSubStream, - IncrementalRestSalesforceStream, - RestSalesforceStream, -) + _A_CHUNKED_RESPONSE = [b"first chunk", b"second chunk"] _A_JSON_RESPONSE = {"id": "any id"} @@ -100,9 +102,7 @@ def test_stream_slice_step_validation(stream_slice_step: str, expected_error_mes ), ], ) -def test_login_authentication_error_handler( - stream_config, requests_mock, login_status_code, login_json_resp, expected_error_msg -): +def test_login_authentication_error_handler(stream_config, requests_mock, login_status_code, login_json_resp, expected_error_msg): source = SourceSalesforce(_ANY_CATALOG, _ANY_CONFIG, _ANY_STATE) logger = logging.getLogger("airbyte") requests_mock.register_uri( @@ -557,13 +557,21 @@ def test_bulk_stream_request_params_states(stream_config_date_format, stream_api stream: BulkIncrementalSalesforceStream = generate_stream("Account", stream_config_date_format, stream_api, state=state, legacy=True) job_id_1 = "fake_job_1" - requests_mock.register_uri("GET", _bulk_stream_path() + f"/{job_id_1}", [{"json": JobInfoResponseBuilder().with_id(job_id_1).with_state("JobComplete").get_response()}]) + requests_mock.register_uri( + "GET", + _bulk_stream_path() + f"/{job_id_1}", + [{"json": JobInfoResponseBuilder().with_id(job_id_1).with_state("JobComplete").get_response()}], + ) requests_mock.register_uri("DELETE", _bulk_stream_path() + f"/{job_id_1}") requests_mock.register_uri("GET", _bulk_stream_path() + f"/{job_id_1}/results", text="Field1,LastModifiedDate,ID\ntest,2023-01-15,1") requests_mock.register_uri("PATCH", _bulk_stream_path() + f"/{job_id_1}") job_id_2 = "fake_job_2" - requests_mock.register_uri("GET", _bulk_stream_path() + f"/{job_id_2}", [{"json": JobInfoResponseBuilder().with_id(job_id_2).with_state("JobComplete").get_response()}]) + requests_mock.register_uri( + "GET", + _bulk_stream_path() + f"/{job_id_2}", + [{"json": JobInfoResponseBuilder().with_id(job_id_2).with_state("JobComplete").get_response()}], + ) requests_mock.register_uri("DELETE", _bulk_stream_path() + f"/{job_id_2}") requests_mock.register_uri( "GET", _bulk_stream_path() + f"/{job_id_2}/results", text="Field1,LastModifiedDate,ID\ntest,2023-04-01,2\ntest,2023-02-20,22" @@ -574,7 +582,11 @@ def test_bulk_stream_request_params_states(stream_config_date_format, stream_api queries_history = requests_mock.register_uri( "POST", _bulk_stream_path(), [{"json": {"id": job_id_1}}, {"json": {"id": job_id_2}}, {"json": {"id": job_id_3}}] ) - requests_mock.register_uri("GET", _bulk_stream_path() + f"/{job_id_3}", [{"json": JobInfoResponseBuilder().with_id(job_id_3).with_state("JobComplete").get_response()}]) + requests_mock.register_uri( + "GET", + _bulk_stream_path() + f"/{job_id_3}", + [{"json": JobInfoResponseBuilder().with_id(job_id_3).with_state("JobComplete").get_response()}], + ) requests_mock.register_uri("DELETE", _bulk_stream_path() + f"/{job_id_3}") requests_mock.register_uri("GET", _bulk_stream_path() + f"/{job_id_3}/results", text="Field1,LastModifiedDate,ID\ntest,2023-04-01,3") requests_mock.register_uri("PATCH", _bulk_stream_path() + f"/{job_id_3}") @@ -586,18 +598,24 @@ def test_bulk_stream_request_params_states(stream_config_date_format, stream_api # assert request params: has requests might not be performed in a specific order because of concurrent CDK, we match on any request all_requests = {request.text for request in queries_history.request_history} - assert any([ - "LastModifiedDate >= 2023-01-01T10:10:10.000+00:00 AND LastModifiedDate < 2023-01-31T10:10:10.000+00:00" - in request for request in all_requests - ]) - assert any([ - "LastModifiedDate >= 2023-01-31T10:10:10.000+00:00 AND LastModifiedDate < 2023-03-02T10:10:10.000+00:00" - in request for request in all_requests - ]) - assert any([ - "LastModifiedDate >= 2023-03-02T10:10:10.000+00:00 AND LastModifiedDate < 2023-04-01T00:00:00.000+00:00" - in request for request in all_requests - ]) + assert any( + [ + "LastModifiedDate >= 2023-01-01T10:10:10.000+00:00 AND LastModifiedDate < 2023-01-31T10:10:10.000+00:00" in request + for request in all_requests + ] + ) + assert any( + [ + "LastModifiedDate >= 2023-01-31T10:10:10.000+00:00 AND LastModifiedDate < 2023-03-02T10:10:10.000+00:00" in request + for request in all_requests + ] + ) + assert any( + [ + "LastModifiedDate >= 2023-03-02T10:10:10.000+00:00 AND LastModifiedDate < 2023-04-01T00:00:00.000+00:00" in request + for request in all_requests + ] + ) # as the execution is concurrent, we can only assert the last state message here last_actual_state = [item.state.stream.stream_state for item in result if item.type == Type.STATE][-1] diff --git a/airbyte-integrations/connectors/source-salesforce/unit_tests/conftest.py b/airbyte-integrations/connectors/source-salesforce/unit_tests/conftest.py index 92df1b20876e..348d2de1b081 100644 --- a/airbyte-integrations/connectors/source-salesforce/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-salesforce/unit_tests/conftest.py @@ -7,13 +7,15 @@ from unittest.mock import Mock import pytest -from airbyte_cdk.models import AirbyteStateMessage, ConfiguredAirbyteCatalogSerializer -from airbyte_cdk.test.catalog_builder import CatalogBuilder -from airbyte_cdk.test.state_builder import StateBuilder from config_builder import ConfigBuilder from source_salesforce.api import Salesforce from source_salesforce.source import SourceSalesforce +from airbyte_cdk.models import AirbyteStateMessage, ConfiguredAirbyteCatalogSerializer +from airbyte_cdk.test.catalog_builder import CatalogBuilder +from airbyte_cdk.test.state_builder import StateBuilder + + _ANY_CATALOG = CatalogBuilder().build() _ANY_CONFIG = ConfigBuilder().build() _ANY_STATE = StateBuilder().build() diff --git a/airbyte-integrations/connectors/source-salesforce/unit_tests/integration/test_bulk_stream.py b/airbyte-integrations/connectors/source-salesforce/unit_tests/integration/test_bulk_stream.py index a5156457d1f2..1aa5376552cb 100644 --- a/airbyte-integrations/connectors/source-salesforce/unit_tests/integration/test_bulk_stream.py +++ b/airbyte-integrations/connectors/source-salesforce/unit_tests/integration/test_bulk_stream.py @@ -8,15 +8,17 @@ from unittest import TestCase import freezegun +from config_builder import ConfigBuilder +from salesforce_describe_response_builder import SalesforceDescribeResponseBuilder +from salesforce_job_response_builder import JobCreateResponseBuilder, JobInfoResponseBuilder +from source_salesforce.streams import BulkSalesforceStream + from airbyte_cdk.models import AirbyteStreamStatus, SyncMode from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse -from config_builder import ConfigBuilder from integration.test_rest_stream import create_http_request as create_standard_http_request from integration.test_rest_stream import create_http_response as create_standard_http_response from integration.utils import create_base_url, given_authentication, given_stream, read -from salesforce_describe_response_builder import SalesforceDescribeResponseBuilder -from salesforce_job_response_builder import JobCreateResponseBuilder, JobInfoResponseBuilder -from source_salesforce.streams import BulkSalesforceStream + _A_FIELD_NAME = "a_field" _ANOTHER_FIELD_NAME = "another_field" @@ -25,7 +27,9 @@ _CLIENT_SECRET = "a_client_secret" _CURSOR_FIELD = "SystemModstamp" _INCREMENTAL_FIELDS = [_A_FIELD_NAME, _CURSOR_FIELD] -_INCREMENTAL_SCHEMA_BUILDER = SalesforceDescribeResponseBuilder().field(_A_FIELD_NAME).field(_CURSOR_FIELD, "datetime") # re-using same fields as _INCREMENTAL_FIELDS +_INCREMENTAL_SCHEMA_BUILDER = ( + SalesforceDescribeResponseBuilder().field(_A_FIELD_NAME).field(_CURSOR_FIELD, "datetime") +) # re-using same fields as _INCREMENTAL_FIELDS _INSTANCE_URL = "https://instance.salesforce.com" _JOB_ID = "a-job-id" _ANOTHER_JOB_ID = "another-job-id" @@ -60,17 +64,16 @@ def _calculate_start_time(start_time: datetime) -> datetime: def _build_job_creation_request(query: str) -> HttpRequest: - return HttpRequest(f"{_BASE_URL}/jobs/query", body=json.dumps({ - "operation": "queryAll", - "query": query, - "contentType": "CSV", - "columnDelimiter": "COMMA", - "lineEnding": "LF" - })) + return HttpRequest( + f"{_BASE_URL}/jobs/query", + body=json.dumps({"operation": "queryAll", "query": query, "contentType": "CSV", "columnDelimiter": "COMMA", "lineEnding": "LF"}), + ) def _make_sliced_job_request(lower_boundary: datetime, upper_boundary: datetime, fields: List[str]) -> HttpRequest: - return _build_job_creation_request(f"SELECT {', '.join(fields)} FROM a_stream_name WHERE SystemModstamp >= {lower_boundary.isoformat(timespec='milliseconds')} AND SystemModstamp < {upper_boundary.isoformat(timespec='milliseconds')}") + return _build_job_creation_request( + f"SELECT {', '.join(fields)} FROM a_stream_name WHERE SystemModstamp >= {lower_boundary.isoformat(timespec='milliseconds')} AND SystemModstamp < {upper_boundary.isoformat(timespec='milliseconds')}" + ) def _make_full_job_request(fields: List[str]) -> HttpRequest: @@ -78,7 +81,6 @@ def _make_full_job_request(fields: List[str]) -> HttpRequest: class BulkStreamTest(TestCase): - def setUp(self) -> None: self._config = ConfigBuilder().client_id(_CLIENT_ID).client_secret(_CLIENT_SECRET).refresh_token(_REFRESH_TOKEN) @@ -168,7 +170,9 @@ def test_given_type_when_read_then_field_is_casted_with_right_type(self) -> None @freezegun.freeze_time(_NOW.isoformat()) def test_given_no_data_provided_when_read_then_field_is_none(self) -> None: - given_stream(self._http_mocker, _BASE_URL, _STREAM_NAME, SalesforceDescribeResponseBuilder().field(_A_FIELD_NAME).field(_ANOTHER_FIELD_NAME)) + given_stream( + self._http_mocker, _BASE_URL, _STREAM_NAME, SalesforceDescribeResponseBuilder().field(_A_FIELD_NAME).field(_ANOTHER_FIELD_NAME) + ) self._http_mocker.post( _make_full_job_request([_A_FIELD_NAME, _ANOTHER_FIELD_NAME]), JobCreateResponseBuilder().with_id(_JOB_ID).build(), @@ -192,7 +196,9 @@ def test_given_no_data_provided_when_read_then_field_is_none(self) -> None: @freezegun.freeze_time(_NOW.isoformat()) def test_given_csv_unix_dialect_provided_when_read_then_parse_csv_properly(self) -> None: - given_stream(self._http_mocker, _BASE_URL, _STREAM_NAME, SalesforceDescribeResponseBuilder().field(_A_FIELD_NAME).field(_ANOTHER_FIELD_NAME)) + given_stream( + self._http_mocker, _BASE_URL, _STREAM_NAME, SalesforceDescribeResponseBuilder().field(_A_FIELD_NAME).field(_ANOTHER_FIELD_NAME) + ) self._http_mocker.post( _make_full_job_request([_A_FIELD_NAME, _ANOTHER_FIELD_NAME]), JobCreateResponseBuilder().with_id(_JOB_ID).build(), @@ -220,7 +226,9 @@ def test_given_csv_unix_dialect_provided_when_read_then_parse_csv_properly(self) @freezegun.freeze_time(_NOW.isoformat()) def test_given_specific_encoding_when_read_then_parse_csv_properly(self) -> None: - given_stream(self._http_mocker, _BASE_URL, _STREAM_NAME, SalesforceDescribeResponseBuilder().field(_A_FIELD_NAME).field(_ANOTHER_FIELD_NAME)) + given_stream( + self._http_mocker, _BASE_URL, _STREAM_NAME, SalesforceDescribeResponseBuilder().field(_A_FIELD_NAME).field(_ANOTHER_FIELD_NAME) + ) self._http_mocker.post( _make_full_job_request([_A_FIELD_NAME, _ANOTHER_FIELD_NAME]), JobCreateResponseBuilder().with_id(_JOB_ID).build(), @@ -338,7 +346,17 @@ def test_given_non_transient_error_on_job_creation_when_read_then_fail_sync(self given_stream(self._http_mocker, _BASE_URL, _STREAM_NAME, SalesforceDescribeResponseBuilder().field(_A_FIELD_NAME)) self._http_mocker.post( _make_full_job_request([_A_FIELD_NAME]), - HttpResponse(json.dumps([{"errorCode": "API_ERROR", "message": "Implementation restriction... "}]), 400), + HttpResponse( + json.dumps( + [ + { + "errorCode": "API_ERROR", + "message": "Implementation restriction... ", + } + ] + ), + 400, + ), ) output = read(_STREAM_NAME, SyncMode.full_refresh, self._config) @@ -526,11 +544,21 @@ def test_given_parent_stream_when_read_then_return_record_for_all_children(self) self._config.start_date(start_date).stream_slice_step("P7D") given_stream(self._http_mocker, _BASE_URL, _STREAM_WITH_PARENT_NAME, SalesforceDescribeResponseBuilder().field(_A_FIELD_NAME)) - self._create_sliced_job_with_records(start_date, first_upper_boundary, _PARENT_STREAM_NAME, "first_parent_slice_job_id", [{"Id": "parent1", "SystemModstamp": "any"}, {"Id": "parent2", "SystemModstamp": "any"}]) - self._create_sliced_job_with_records(first_upper_boundary, _NOW, _PARENT_STREAM_NAME, "second_parent_slice_job_id", [{"Id": "parent3", "SystemModstamp": "any"}]) + self._create_sliced_job_with_records( + start_date, + first_upper_boundary, + _PARENT_STREAM_NAME, + "first_parent_slice_job_id", + [{"Id": "parent1", "SystemModstamp": "any"}, {"Id": "parent2", "SystemModstamp": "any"}], + ) + self._create_sliced_job_with_records( + first_upper_boundary, _NOW, _PARENT_STREAM_NAME, "second_parent_slice_job_id", [{"Id": "parent3", "SystemModstamp": "any"}] + ) self._http_mocker.post( - self._build_job_creation_request(f"SELECT {', '.join([_A_FIELD_NAME])} FROM {_STREAM_WITH_PARENT_NAME} WHERE ContentDocumentId IN ('parent1', 'parent2', 'parent3')"), + self._build_job_creation_request( + f"SELECT {', '.join([_A_FIELD_NAME])} FROM {_STREAM_WITH_PARENT_NAME} WHERE ContentDocumentId IN ('parent1', 'parent2', 'parent3')" + ), JobCreateResponseBuilder().with_id(_JOB_ID).build(), ) self._http_mocker.get( @@ -547,10 +575,16 @@ def test_given_parent_stream_when_read_then_return_record_for_all_children(self) assert len(output.records) == 1 - def _create_sliced_job(self, lower_boundary: datetime, upper_boundary: datetime, stream_name: str, fields: List[str], job_id: str, record_count: int) -> None: - self._create_sliced_job_with_records(lower_boundary, upper_boundary, stream_name, job_id, self._generate_random_records(fields, record_count)) + def _create_sliced_job( + self, lower_boundary: datetime, upper_boundary: datetime, stream_name: str, fields: List[str], job_id: str, record_count: int + ) -> None: + self._create_sliced_job_with_records( + lower_boundary, upper_boundary, stream_name, job_id, self._generate_random_records(fields, record_count) + ) - def _create_sliced_job_with_records(self, lower_boundary: datetime, upper_boundary: datetime, stream_name: str, job_id: str, records: List[Dict[str, str]]) -> None: + def _create_sliced_job_with_records( + self, lower_boundary: datetime, upper_boundary: datetime, stream_name: str, job_id: str, records: List[Dict[str, str]] + ) -> None: self._http_mocker.post( self._make_sliced_job_request(lower_boundary, upper_boundary, stream_name, list(records[0].keys())), JobCreateResponseBuilder().with_id(job_id).build(), @@ -581,8 +615,12 @@ def _create_csv(self, headers: List[str], data: List[Dict[str, str]], dialect: s writer.writerow(line) return csvfile.getvalue() - def _make_sliced_job_request(self, lower_boundary: datetime, upper_boundary: datetime, stream_name: str, fields: List[str]) -> HttpRequest: - return self._build_job_creation_request(f"SELECT {', '.join(fields)} FROM {stream_name} WHERE SystemModstamp >= {lower_boundary.isoformat(timespec='milliseconds')} AND SystemModstamp < {upper_boundary.isoformat(timespec='milliseconds')}") + def _make_sliced_job_request( + self, lower_boundary: datetime, upper_boundary: datetime, stream_name: str, fields: List[str] + ) -> HttpRequest: + return self._build_job_creation_request( + f"SELECT {', '.join(fields)} FROM {stream_name} WHERE SystemModstamp >= {lower_boundary.isoformat(timespec='milliseconds')} AND SystemModstamp < {upper_boundary.isoformat(timespec='milliseconds')}" + ) def _make_full_job_request(self, fields: List[str], stream_name: str = _STREAM_NAME) -> HttpRequest: return self._build_job_creation_request(f"SELECT {', '.join(fields)} FROM {stream_name}") @@ -601,14 +639,13 @@ def _generate_csv(self, records: List[Dict[str, str]]) -> str: for record in records: csv_entry.append(",".join([record[key] for key in keys])) - entries = '\n'.join(csv_entry) + entries = "\n".join(csv_entry) return f"{','.join(keys)}\n{entries}" def _build_job_creation_request(self, query: str) -> HttpRequest: - return HttpRequest(f"{_BASE_URL}/jobs/query", body=json.dumps({ - "operation": "queryAll", - "query": query, - "contentType": "CSV", - "columnDelimiter": "COMMA", - "lineEnding": "LF" - })) + return HttpRequest( + f"{_BASE_URL}/jobs/query", + body=json.dumps( + {"operation": "queryAll", "query": query, "contentType": "CSV", "columnDelimiter": "COMMA", "lineEnding": "LF"} + ), + ) diff --git a/airbyte-integrations/connectors/source-salesforce/unit_tests/integration/test_rest_stream.py b/airbyte-integrations/connectors/source-salesforce/unit_tests/integration/test_rest_stream.py index 85805d29cb74..d61328f9c5ba 100644 --- a/airbyte-integrations/connectors/source-salesforce/unit_tests/integration/test_rest_stream.py +++ b/airbyte-integrations/connectors/source-salesforce/unit_tests/integration/test_rest_stream.py @@ -7,15 +7,17 @@ from unittest import TestCase import freezegun -from airbyte_cdk.models import AirbyteStateBlob, SyncMode -from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse -from airbyte_cdk.test.state_builder import StateBuilder from config_builder import ConfigBuilder -from integration.utils import create_base_url, given_authentication, given_stream, read from salesforce_describe_response_builder import SalesforceDescribeResponseBuilder from source_salesforce.api import UNSUPPORTED_BULK_API_SALESFORCE_OBJECTS from source_salesforce.streams import LOOKBACK_SECONDS +from airbyte_cdk.models import AirbyteStateBlob, SyncMode +from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse +from airbyte_cdk.test.state_builder import StateBuilder +from integration.utils import create_base_url, given_authentication, given_stream, read + + _A_FIELD_NAME = "a_field" _CLIENT_ID = "a_client_id" _CLIENT_SECRET = "a_client_secret" @@ -31,7 +33,7 @@ def create_http_request(stream_name: str, field_names: List[str], access_token: Optional[str] = None) -> HttpRequest: return HttpRequest( f"{_BASE_URL}/queryAll?q=SELECT+{','.join(field_names)}+FROM+{stream_name}+", - headers={"Authorization": f"Bearer {access_token}"} if access_token else None + headers={"Authorization": f"Bearer {access_token}"} if access_token else None, ) @@ -40,7 +42,10 @@ def create_http_response(field_names: List[str], record_count: int = 1) -> HttpR This method does not handle field types for now which may cause some test failures on change if we start considering using some fields for calculation. One example of that would be cursor field parsing to datetime. """ - records = [{field: "2021-01-18T21:18:20.000Z" if field in {"SystemModstamp"} else f"{field}_value" for field in field_names} for i in range(record_count)] + records = [ + {field: "2021-01-18T21:18:20.000Z" if field in {"SystemModstamp"} else f"{field}_value" for field in field_names} + for i in range(record_count) + ] return HttpResponse(json.dumps({"records": records})) @@ -64,7 +69,6 @@ def _calculate_start_time(start_time: datetime) -> datetime: @freezegun.freeze_time(_NOW.isoformat()) class FullRefreshTest(TestCase): - def setUp(self) -> None: self._config = ConfigBuilder().client_id(_CLIENT_ID).client_secret(_CLIENT_SECRET).refresh_token(_REFRESH_TOKEN) @@ -77,7 +81,7 @@ def test_given_error_on_fetch_chunk_of_properties_when_read_then_retry(self, htt [ HttpResponse("", status_code=406), create_http_response([_A_FIELD_NAME], record_count=1), - ] + ], ) output = read(_STREAM_NAME, SyncMode.full_refresh, self._config) @@ -94,7 +98,12 @@ def setUp(self) -> None: self._http_mocker.__enter__() given_authentication(self._http_mocker, _CLIENT_ID, _CLIENT_SECRET, _REFRESH_TOKEN, _INSTANCE_URL) - given_stream(self._http_mocker, _BASE_URL, _STREAM_NAME, SalesforceDescribeResponseBuilder().field(_A_FIELD_NAME).field(_CURSOR_FIELD, "datetime")) + given_stream( + self._http_mocker, + _BASE_URL, + _STREAM_NAME, + SalesforceDescribeResponseBuilder().field(_A_FIELD_NAME).field(_CURSOR_FIELD, "datetime"), + ) def tearDown(self) -> None: self._http_mocker.__exit__(None, None, None) @@ -102,11 +111,13 @@ def tearDown(self) -> None: def test_given_no_state_when_read_then_start_sync_from_start(self) -> None: start = _calculate_start_time(_NOW - timedelta(days=5)) # as the start comes from the config, we can't use the same format as `_to_url` - start_format_url = urllib.parse.quote_plus(start.strftime('%Y-%m-%dT%H:%M:%SZ')) + start_format_url = urllib.parse.quote_plus(start.strftime("%Y-%m-%dT%H:%M:%SZ")) self._config.stream_slice_step("P30D").start_date(start) self._http_mocker.get( - HttpRequest(f"{_BASE_URL}/queryAll?q=SELECT+{_A_FIELD_NAME},{_CURSOR_FIELD}+FROM+{_STREAM_NAME}+WHERE+SystemModstamp+%3E%3D+{start_format_url}+AND+SystemModstamp+%3C+{_to_url(_NOW)}"), + HttpRequest( + f"{_BASE_URL}/queryAll?q=SELECT+{_A_FIELD_NAME},{_CURSOR_FIELD}+FROM+{_STREAM_NAME}+WHERE+SystemModstamp+%3E%3D+{start_format_url}+AND+SystemModstamp+%3C+{_to_url(_NOW)}" + ), create_http_response([_A_FIELD_NAME], record_count=1), ) @@ -119,13 +130,22 @@ def test_given_sequential_state_when_read_then_migrate_to_partitioned_state(self start = _calculate_start_time(_NOW - timedelta(days=10)) self._config.stream_slice_step("P30D").start_date(start) self._http_mocker.get( - HttpRequest(f"{_BASE_URL}/queryAll?q=SELECT+{_A_FIELD_NAME},{_CURSOR_FIELD}+FROM+{_STREAM_NAME}+WHERE+SystemModstamp+%3E%3D+{_to_url(cursor_value - _LOOKBACK_WINDOW)}+AND+SystemModstamp+%3C+{_to_url(_NOW)}"), + HttpRequest( + f"{_BASE_URL}/queryAll?q=SELECT+{_A_FIELD_NAME},{_CURSOR_FIELD}+FROM+{_STREAM_NAME}+WHERE+SystemModstamp+%3E%3D+{_to_url(cursor_value - _LOOKBACK_WINDOW)}+AND+SystemModstamp+%3C+{_to_url(_NOW)}" + ), create_http_response([_A_FIELD_NAME, _CURSOR_FIELD], record_count=1), ) - output = read(_STREAM_NAME, SyncMode.incremental, self._config, StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: cursor_value.isoformat(timespec="milliseconds")})) + output = read( + _STREAM_NAME, + SyncMode.incremental, + self._config, + StateBuilder().with_stream_state(_STREAM_NAME, {_CURSOR_FIELD: cursor_value.isoformat(timespec="milliseconds")}), + ) - assert output.most_recent_state.stream_state == AirbyteStateBlob({"state_type": "date-range", "slices": [{"start": _to_partitioned_datetime(start), "end": _to_partitioned_datetime(_NOW)}]}) + assert output.most_recent_state.stream_state == AirbyteStateBlob( + {"state_type": "date-range", "slices": [{"start": _to_partitioned_datetime(start), "end": _to_partitioned_datetime(_NOW)}]} + ) def test_given_partitioned_state_when_read_then_sync_missing_partitions_and_update_state(self) -> None: missing_chunk = (_NOW - timedelta(days=5), _NOW - timedelta(days=3)) @@ -138,21 +158,27 @@ def test_given_partitioned_state_when_read_then_sync_missing_partitions_and_upda "slices": [ {"start": start.strftime("%Y-%m-%dT%H:%M:%S.000") + "Z", "end": _to_partitioned_datetime(missing_chunk[0])}, {"start": _to_partitioned_datetime(missing_chunk[1]), "end": _to_partitioned_datetime(most_recent_state_value)}, - ] - } + ], + }, ) self._config.stream_slice_step("P30D").start_date(start) self._http_mocker.get( - HttpRequest(f"{_BASE_URL}/queryAll?q=SELECT+{_A_FIELD_NAME},{_CURSOR_FIELD}+FROM+{_STREAM_NAME}+WHERE+SystemModstamp+%3E%3D+{_to_url(missing_chunk[0])}+AND+SystemModstamp+%3C+{_to_url(missing_chunk[1])}"), + HttpRequest( + f"{_BASE_URL}/queryAll?q=SELECT+{_A_FIELD_NAME},{_CURSOR_FIELD}+FROM+{_STREAM_NAME}+WHERE+SystemModstamp+%3E%3D+{_to_url(missing_chunk[0])}+AND+SystemModstamp+%3C+{_to_url(missing_chunk[1])}" + ), create_http_response([_A_FIELD_NAME, _CURSOR_FIELD], record_count=1), ) self._http_mocker.get( - HttpRequest(f"{_BASE_URL}/queryAll?q=SELECT+{_A_FIELD_NAME},{_CURSOR_FIELD}+FROM+{_STREAM_NAME}+WHERE+SystemModstamp+%3E%3D+{_to_url(most_recent_state_value - _LOOKBACK_WINDOW)}+AND+SystemModstamp+%3C+{_to_url(_NOW)}"), + HttpRequest( + f"{_BASE_URL}/queryAll?q=SELECT+{_A_FIELD_NAME},{_CURSOR_FIELD}+FROM+{_STREAM_NAME}+WHERE+SystemModstamp+%3E%3D+{_to_url(most_recent_state_value - _LOOKBACK_WINDOW)}+AND+SystemModstamp+%3C+{_to_url(_NOW)}" + ), create_http_response([_A_FIELD_NAME, _CURSOR_FIELD], record_count=1), ) output = read(_STREAM_NAME, SyncMode.incremental, self._config, state) # the start is granular to the second hence why we have `000` in terms of milliseconds - assert output.most_recent_state.stream_state == AirbyteStateBlob({"state_type": "date-range", "slices": [{"start": _to_partitioned_datetime(start), "end": _to_partitioned_datetime(_NOW)}]}) + assert output.most_recent_state.stream_state == AirbyteStateBlob( + {"state_type": "date-range", "slices": [{"start": _to_partitioned_datetime(start), "end": _to_partitioned_datetime(_NOW)}]} + ) diff --git a/airbyte-integrations/connectors/source-salesforce/unit_tests/integration/test_source.py b/airbyte-integrations/connectors/source-salesforce/unit_tests/integration/test_source.py index 3fa57dfbd0a1..cd380be8ee2c 100644 --- a/airbyte-integrations/connectors/source-salesforce/unit_tests/integration/test_source.py +++ b/airbyte-integrations/connectors/source-salesforce/unit_tests/integration/test_source.py @@ -4,15 +4,17 @@ from unittest import TestCase import pytest +from config_builder import ConfigBuilder +from salesforce_describe_response_builder import SalesforceDescribeResponseBuilder +from source_salesforce import SourceSalesforce + from airbyte_cdk.models import FailureType, SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse from airbyte_cdk.test.state_builder import StateBuilder from airbyte_cdk.utils.traced_exception import AirbyteTracedException -from config_builder import ConfigBuilder from integration.utils import create_base_url, given_authentication, given_stream -from salesforce_describe_response_builder import SalesforceDescribeResponseBuilder -from source_salesforce import SourceSalesforce + _CLIENT_ID = "a_client_id" _CLIENT_SECRET = "a_client_secret" @@ -25,13 +27,10 @@ class StreamGenerationTest(TestCase): - def setUp(self) -> None: self._config = ConfigBuilder().client_id(_CLIENT_ID).client_secret(_CLIENT_SECRET).refresh_token(_REFRESH_TOKEN).build() self._source = SourceSalesforce( - CatalogBuilder().with_stream(_STREAM_NAME, SyncMode.full_refresh).build(), - self._config, - StateBuilder().build() + CatalogBuilder().with_stream(_STREAM_NAME, SyncMode.full_refresh).build(), self._config, StateBuilder().build() ) self._http_mocker = HttpMocker() @@ -48,10 +47,7 @@ def test_given_transient_error_fetching_schema_when_streams_then_retry(self) -> ) self._http_mocker.get( HttpRequest(f"{_BASE_URL}/sobjects/{_STREAM_NAME}/describe"), - [ - HttpResponse("", status_code=406), - SalesforceDescribeResponseBuilder().field("a_field_name").build() - ] + [HttpResponse("", status_code=406), SalesforceDescribeResponseBuilder().field("a_field_name").build()], ) streams = self._source.streams(self._config) diff --git a/airbyte-integrations/connectors/source-salesforce/unit_tests/integration/utils.py b/airbyte-integrations/connectors/source-salesforce/unit_tests/integration/utils.py index b547a297c439..bae6d4bd1445 100644 --- a/airbyte-integrations/connectors/source-salesforce/unit_tests/integration/utils.py +++ b/airbyte-integrations/connectors/source-salesforce/unit_tests/integration/utils.py @@ -3,6 +3,10 @@ import json from typing import Any, Dict, Optional +from config_builder import ConfigBuilder +from salesforce_describe_response_builder import SalesforceDescribeResponseBuilder +from source_salesforce import SourceSalesforce + from airbyte_cdk.models import ConfiguredAirbyteCatalog, SyncMode from airbyte_cdk.sources.source import TState from airbyte_cdk.test.catalog_builder import CatalogBuilder @@ -11,9 +15,7 @@ from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse from airbyte_cdk.test.mock_http.request import ANY_QUERY_PARAMS from airbyte_cdk.test.state_builder import StateBuilder -from config_builder import ConfigBuilder -from salesforce_describe_response_builder import SalesforceDescribeResponseBuilder -from source_salesforce import SourceSalesforce + _API_VERSION = "v57.0" @@ -35,7 +37,7 @@ def read( sync_mode: SyncMode, config_builder: Optional[ConfigBuilder] = None, state_builder: Optional[StateBuilder] = None, - expecting_exception: bool = False + expecting_exception: bool = False, ) -> EntrypointOutput: catalog = _catalog(stream_name, sync_mode) config = config_builder.build() if config_builder else ConfigBuilder().build() @@ -43,12 +45,19 @@ def read( return entrypoint_read(_source(catalog, config, state), config, catalog, state, expecting_exception) -def given_authentication(http_mocker: HttpMocker, client_id: str, client_secret: str, refresh_token: str, instance_url: str, access_token: str = "any_access_token") -> None: +def given_authentication( + http_mocker: HttpMocker, + client_id: str, + client_secret: str, + refresh_token: str, + instance_url: str, + access_token: str = "any_access_token", +) -> None: http_mocker.post( HttpRequest( "https://login.salesforce.com/services/oauth2/token", query_params=ANY_QUERY_PARAMS, - body=f"grant_type=refresh_token&client_id={client_id}&client_secret={client_secret}&refresh_token={refresh_token}" + body=f"grant_type=refresh_token&client_id={client_id}&client_secret={client_secret}&refresh_token={refresh_token}", ), HttpResponse(json.dumps({"access_token": access_token, "instance_url": instance_url})), ) diff --git a/airbyte-integrations/connectors/source-salesforce/unit_tests/salesforce_job_response_builder.py b/airbyte-integrations/connectors/source-salesforce/unit_tests/salesforce_job_response_builder.py index 55bc8b8f65dd..76af9b7eaf38 100644 --- a/airbyte-integrations/connectors/source-salesforce/unit_tests/salesforce_job_response_builder.py +++ b/airbyte-integrations/connectors/source-salesforce/unit_tests/salesforce_job_response_builder.py @@ -9,18 +9,18 @@ class JobCreateResponseBuilder: def __init__(self) -> None: self._response = { - "id": "any_id", - "operation": "query", - "object": "Account", - "createdById": "005R0000000GiwjIAC", - "createdDate": "2018-12-17T21:00:17.000+0000", - "systemModstamp": "2018-12-17T21:00:17.000+0000", - "state": "UploadComplete", - "concurrencyMode": "Parallel", - "contentType": "CSV", - "apiVersion": 46.0, - "lineEnding": "LF", - "columnDelimiter": "COMMA" + "id": "any_id", + "operation": "query", + "object": "Account", + "createdById": "005R0000000GiwjIAC", + "createdDate": "2018-12-17T21:00:17.000+0000", + "systemModstamp": "2018-12-17T21:00:17.000+0000", + "state": "UploadComplete", + "concurrencyMode": "Parallel", + "contentType": "CSV", + "apiVersion": 46.0, + "lineEnding": "LF", + "columnDelimiter": "COMMA", } self._status_code = 200 @@ -52,11 +52,11 @@ def with_state(self, state: str) -> "JobInfoResponseBuilder": def with_status_code(self, status_code: int) -> "JobInfoResponseBuilder": self._status_code = status_code return self - + def with_error_message(self, error_message: str) -> "JobInfoResponseBuilder": self._response["errorMessage"] = error_message return self - + def get_response(self) -> any: return self._response diff --git a/airbyte-integrations/connectors/source-salesforce/unit_tests/test_availability_strategy.py b/airbyte-integrations/connectors/source-salesforce/unit_tests/test_availability_strategy.py index 2c8abd44f859..cd00f723774a 100644 --- a/airbyte-integrations/connectors/source-salesforce/unit_tests/test_availability_strategy.py +++ b/airbyte-integrations/connectors/source-salesforce/unit_tests/test_availability_strategy.py @@ -4,10 +4,12 @@ from unittest.mock import Mock import pytest -from airbyte_cdk.sources.streams import Stream from requests import HTTPError, Response from source_salesforce.availability_strategy import SalesforceAvailabilityStrategy +from airbyte_cdk.sources.streams import Stream + + _NO_SOURCE = None diff --git a/airbyte-integrations/connectors/source-salesforce/unit_tests/test_rate_limiting.py b/airbyte-integrations/connectors/source-salesforce/unit_tests/test_rate_limiting.py index c6b9d1ea1731..c00beb8981c1 100644 --- a/airbyte-integrations/connectors/source-salesforce/unit_tests/test_rate_limiting.py +++ b/airbyte-integrations/connectors/source-salesforce/unit_tests/test_rate_limiting.py @@ -6,11 +6,13 @@ import pytest import requests import requests_mock -from airbyte_cdk.models import FailureType -from airbyte_cdk.sources.streams.http.error_handlers import ResponseAction from requests.exceptions import ChunkedEncodingError from source_salesforce.rate_limiting import BulkNotSupportedException, SalesforceErrorHandler +from airbyte_cdk.models import FailureType +from airbyte_cdk.sources.streams.http.error_handlers import ResponseAction + + _ANY = "any" _ANY_BASE_URL = "https://any-base-url.com" _SF_API_VERSION = "v57.0" @@ -20,18 +22,32 @@ class SalesforceErrorHandlerTest(TestCase): def setUp(self) -> None: self._error_handler = SalesforceErrorHandler() - def test_given_invalid_entity_with_bulk_not_supported_message_on_job_creation_when_interpret_response_then_raise_bulk_not_supported(self) -> None: - response = self._create_response("POST", self._url_for_job_creation(), 400, [{"errorCode": "INVALIDENTITY", "message": "X is not supported by the Bulk API"}]) + def test_given_invalid_entity_with_bulk_not_supported_message_on_job_creation_when_interpret_response_then_raise_bulk_not_supported( + self, + ) -> None: + response = self._create_response( + "POST", self._url_for_job_creation(), 400, [{"errorCode": "INVALIDENTITY", "message": "X is not supported by the Bulk API"}] + ) with pytest.raises(BulkNotSupportedException): self._error_handler.interpret_response(response) def test_given_compound_data_error_on_job_creation_when_interpret_response_then_raise_bulk_not_supported(self) -> None: - response = self._create_response("POST", self._url_for_job_creation(), 400, [{"errorCode": _ANY, "message": "Selecting compound data not supported in Bulk Query"}]) + response = self._create_response( + "POST", + self._url_for_job_creation(), + 400, + [{"errorCode": _ANY, "message": "Selecting compound data not supported in Bulk Query"}], + ) with pytest.raises(BulkNotSupportedException): self._error_handler.interpret_response(response) def test_given_request_limit_exceeded_on_job_creation_when_interpret_response_then_raise_bulk_not_supported(self) -> None: - response = self._create_response("POST", self._url_for_job_creation(), 400, [{"errorCode": "REQUEST_LIMIT_EXCEEDED", "message": "Selecting compound data not supported in Bulk Query"}]) + response = self._create_response( + "POST", + self._url_for_job_creation(), + 400, + [{"errorCode": "REQUEST_LIMIT_EXCEEDED", "message": "Selecting compound data not supported in Bulk Query"}], + ) with pytest.raises(BulkNotSupportedException): self._error_handler.interpret_response(response) @@ -41,12 +57,24 @@ def test_given_limit_exceeded_on_job_creation_when_interpret_response_then_raise self._error_handler.interpret_response(response) def test_given_query_not_supported_on_job_creation_when_interpret_response_then_raise_bulk_not_supported(self) -> None: - response = self._create_response("POST", self._url_for_job_creation(), 400, [{"errorCode": "API_ERROR", "message": "API does not support query"}]) + response = self._create_response( + "POST", self._url_for_job_creation(), 400, [{"errorCode": "API_ERROR", "message": "API does not support query"}] + ) with pytest.raises(BulkNotSupportedException): self._error_handler.interpret_response(response) def test_given_txn_security_metering_error_when_interpret_response_then_raise_config_error(self) -> None: - response = self._create_response("GET", self._url_for_job_creation() + "/job_id", 400, [{"errorCode": "TXN_SECURITY_METERING_ERROR", "message": "We can't complete the action because enabled transaction security policies took too long to complete."}]) + response = self._create_response( + "GET", + self._url_for_job_creation() + "/job_id", + 400, + [ + { + "errorCode": "TXN_SECURITY_METERING_ERROR", + "message": "We can't complete the action because enabled transaction security policies took too long to complete.", + } + ], + ) error_resolution = self._error_handler.interpret_response(response) diff --git a/airbyte-integrations/connectors/source-salesforce/unit_tests/test_slice_generation.py b/airbyte-integrations/connectors/source-salesforce/unit_tests/test_slice_generation.py index 25ea70f6362c..b2f335f594e8 100644 --- a/airbyte-integrations/connectors/source-salesforce/unit_tests/test_slice_generation.py +++ b/airbyte-integrations/connectors/source-salesforce/unit_tests/test_slice_generation.py @@ -4,20 +4,24 @@ from unittest import TestCase import freezegun -from airbyte_cdk.models import SyncMode from config_builder import ConfigBuilder from conftest import generate_stream, mock_stream_api from source_salesforce.api import UNSUPPORTED_BULK_API_SALESFORCE_OBJECTS +from airbyte_cdk.models import SyncMode + + _NOW = datetime.fromisoformat("2020-01-01T00:00:00+00:00") _STREAM_NAME = UNSUPPORTED_BULK_API_SALESFORCE_OBJECTS[0] + @freezegun.freeze_time(time_to_freeze=_NOW) class IncrementalSliceGenerationTest(TestCase): """ For this, we will be testing with UNSUPPORTED_BULK_API_SALESFORCE_OBJECTS[0] as bulk stream slicing actually creates jobs. We will assume the bulk one usese the same logic. """ + def test_given_start_within_slice_range_when_stream_slices_then_return_one_slice_considering_10_minutes_lookback(self) -> None: config = ConfigBuilder().start_date(_NOW - timedelta(days=15)).stream_slice_step("P30D").build() stream = generate_stream(_STREAM_NAME, config, mock_stream_api(config)) @@ -34,5 +38,5 @@ def test_given_slice_range_smaller_than_now_minus_start_date_when_stream_slices_ assert slices == [ {"start_date": "2019-11-22T00:00:00.000+00:00", "end_date": "2019-12-22T00:00:00.000+00:00"}, - {"start_date": "2019-12-22T00:00:00.000+00:00", "end_date": "2020-01-01T00:00:00.000+00:00"} + {"start_date": "2019-12-22T00:00:00.000+00:00", "end_date": "2020-01-01T00:00:00.000+00:00"}, ] diff --git a/airbyte-integrations/connectors/source-salesloft/README.md b/airbyte-integrations/connectors/source-salesloft/README.md index fcf3c5dbd01b..fa381e8bc5f4 100644 --- a/airbyte-integrations/connectors/source-salesloft/README.md +++ b/airbyte-integrations/connectors/source-salesloft/README.md @@ -1,47 +1,22 @@ # Salesloft source connector -This is the repository for the Salesloft configuration based source connector. -For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.com/integrations/sources/salesloft). +This directory contains the manifest-only connector for `source-salesloft`. +This _manifest-only_ connector is not a Python package on its own, as it runs inside of the base `source-declarative-manifest` image. -## Local development - -### Prerequisites -* Python (^3.9) -* Poetry (^1.7) - installation instructions [here](https://python-poetry.org/docs/#installation) - -### Installing the connector - -From this connector directory, run: -```bash -poetry install --with dev -``` - -### Create credentials -**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/salesloft) -to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_salesloft/spec.yaml` file. - -Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. -See `sample_files/sample_config.json` for a sample config file. - - -### Locally running the connector -``` -poetry run source-salesloft spec -poetry run source-salesloft check --config secrets/config.json -poetry run source-salesloft discover --config secrets/config.json -poetry run source-salesloft read --config secrets/config.json --catalog integration_tests/configured_catalog.json -``` +For information about how to configure and use this connector within Airbyte, see [the connector's full documentation](https://docs.airbyte.com/integrations/sources/salesloft). -### Running tests +## Local development -To run tests locally, from the connector directory run: +We recommend using the Connector Builder to edit this connector. +Using either Airbyte Cloud or your local Airbyte OSS instance, navigate to the **Builder** tab and select **Import a YAML**. +Then select the connector's `manifest.yaml` file to load the connector into the Builder. You're now ready to make changes to the connector! -``` -poetry run pytest tests -``` +If you prefer to develop locally, you can follow the instructions below. ### Building the docker image +You can build any manifest-only connector with `airbyte-ci`: + 1. Install [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md) 2. Run the following command to build the docker image: @@ -51,46 +26,40 @@ airbyte-ci connectors --name=source-salesloft build An image will be available on your host with the tag `airbyte/source-salesloft:dev`. +### Creating credentials + +**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/salesloft) +to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `spec` object in the connector's `manifest.yaml` file. +Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. + ### Running as a docker container -Then run any of the connector commands as follows: -``` + +Then run any of the standard source connector commands: + +```bash docker run --rm airbyte/source-salesloft:dev spec docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-salesloft:dev check --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-salesloft:dev discover --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-salesloft:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json ``` -### Running our CI test suite +### Running the CI test suite You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): -```bash -airbyte-ci connectors --name=source-salesloft test -``` - -### Customizing acceptance Tests - -Customize `acceptance-test-config.yml` file to configure acceptance tests. See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) for more information. -If your connector requires to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py. -### Dependency Management - -All of your dependencies should be managed via Poetry. -To add a new dependency, run: ```bash -poetry add +airbyte-ci connectors --name=source-salesloft test ``` -Please commit the changes to `pyproject.toml` and `poetry.lock` files. - ## Publishing a new version of the connector -You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what? -1. Make sure your changes are passing our test suite: `airbyte-ci connectors --name=source-salesloft test` -2. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): + +If you want to contribute changes to `source-salesloft`, here's how you can do that: +1. Make your changes locally, or load the connector's manifest into Connector Builder and make changes there. +2. Make sure your changes are passing our test suite with `airbyte-ci connectors --name=source-salesloft test` +3. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): - bump the `dockerImageTag` value in in `metadata.yaml` - - bump the `version` value in `pyproject.toml` -3. Make sure the `metadata.yaml` content is up to date. 4. Make sure the connector documentation and its changelog is up to date (`docs/integrations/sources/salesloft.md`). 5. Create a Pull Request: use [our PR naming conventions](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#pull-request-title-convention). 6. Pat yourself on the back for being an awesome contributor. 7. Someone from Airbyte will take a look at your PR and iterate with you to merge it into master. -8. Once your PR is merged, the new version of the connector will be automatically published to Docker Hub and our connector registry. +8. Once your PR is merged, the new version of the connector will be automatically published to Docker Hub and our connector registry. \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-salesloft/__init__.py b/airbyte-integrations/connectors/source-salesloft/__init__.py deleted file mode 100644 index 66f6de8cb2bb..000000000000 --- a/airbyte-integrations/connectors/source-salesloft/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-integrations/connectors/source-salesloft/acceptance-test-config.yml b/airbyte-integrations/connectors/source-salesloft/acceptance-test-config.yml index f16683cb483a..746b8b26e018 100644 --- a/airbyte-integrations/connectors/source-salesloft/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-salesloft/acceptance-test-config.yml @@ -4,7 +4,7 @@ connector_image: airbyte/source-salesloft:dev acceptance_tests: spec: tests: - - spec_path: "source_salesloft/spec.yaml" + - spec_path: "manifest.yaml" connection: tests: - config_path: "secrets/config.json" @@ -24,13 +24,11 @@ acceptance_tests: # path: "integration_tests/expected_records.jsonl" # exact_order: no incremental: - bypass_reason: "This connector does not implement incremental sync" - # TODO uncomment this block this block if your connector implements incremental sync: - # tests: - # - config_path: "secrets/config.json" - # configured_catalog_path: "integration_tests/configured_catalog.json" - # future_state: - # future_state_path: "integration_tests/abnormal_state.json" + tests: + - config_path: "secrets/config.json" + configured_catalog_path: "integration_tests/incremental_catalog.json" + future_state: + future_state_path: "integration_tests/abnormal_state.json" full_refresh: tests: - config_path: "secrets/config.json" diff --git a/airbyte-integrations/connectors/source-salesloft/components.py b/airbyte-integrations/connectors/source-salesloft/components.py new file mode 100644 index 000000000000..4d94758110e5 --- /dev/null +++ b/airbyte-integrations/connectors/source-salesloft/components.py @@ -0,0 +1,27 @@ +# +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. +# + +from dataclasses import dataclass + +from airbyte_cdk.sources.declarative.auth.oauth import DeclarativeSingleUseRefreshTokenOauth2Authenticator +from airbyte_cdk.sources.declarative.types import Config + + +@dataclass +class SingleUseOauth2Authenticator(DeclarativeSingleUseRefreshTokenOauth2Authenticator): + config: Config + + def __post_init__(self): + self._connector_config = self.config + self._token_expiry_date_config_path = "credentials/token_expiry_date" + self.token_refresh_endpoint = "https://accounts.salesloft.com/oauth/token" + self._access_token_config_path = "credentials/access_token" + + @property + def auth_header(self) -> str: + return "Authorization" + + @property + def token(self) -> str: + return f"Bearer {self.get_access_token()}" diff --git a/airbyte-integrations/connectors/source-salesloft/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-salesloft/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-salesloft/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-salesloft/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-salesloft/integration_tests/configured_catalog.json b/airbyte-integrations/connectors/source-salesloft/integration_tests/configured_catalog.json index 0c353aa8ae7c..71e16ead203e 100644 --- a/airbyte-integrations/connectors/source-salesloft/integration_tests/configured_catalog.json +++ b/airbyte-integrations/connectors/source-salesloft/integration_tests/configured_catalog.json @@ -9,8 +9,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -21,8 +22,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -33,8 +35,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -55,8 +58,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -67,18 +71,22 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { "name": "account_stages", "json_schema": {}, "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -99,8 +107,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -111,18 +120,22 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { "name": "email_templates", "json_schema": {}, "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -143,8 +156,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -181,10 +195,13 @@ "name": "team_templates", "json_schema": {}, "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -205,8 +222,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -237,8 +255,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -269,8 +288,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -311,8 +331,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "full_refresh" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" } ] } diff --git a/airbyte-integrations/connectors/source-salesloft/integration_tests/incremental_catalog.json b/airbyte-integrations/connectors/source-salesloft/integration_tests/incremental_catalog.json index 40243c5e9248..436d5a4def0e 100644 --- a/airbyte-integrations/connectors/source-salesloft/integration_tests/incremental_catalog.json +++ b/airbyte-integrations/connectors/source-salesloft/integration_tests/incremental_catalog.json @@ -9,8 +9,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "incremental" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -21,8 +22,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "incremental" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -33,8 +35,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "incremental" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -45,8 +48,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "incremental" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -57,8 +61,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "incremental" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -69,8 +74,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "incremental" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -81,8 +87,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "incremental" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -93,8 +100,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "incremental" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -105,8 +113,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "incremental" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -117,38 +126,48 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "incremental" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { "name": "account_stages", "json_schema": {}, "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "incremental" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { "name": "email_templates", "json_schema": {}, "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "incremental" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { "name": "team_templates", "json_schema": {}, "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "incremental" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -159,8 +178,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "incremental" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" }, { "stream": { @@ -171,8 +191,9 @@ "default_cursor_field": ["updated_at"], "source_defined_primary_key": [["id"]] }, - "destination_sync_mode": "overwrite", - "sync_mode": "incremental" + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "destination_sync_mode": "append" } ] } diff --git a/airbyte-integrations/connectors/source-salesloft/main.py b/airbyte-integrations/connectors/source-salesloft/main.py deleted file mode 100644 index 7a6c7f75fe43..000000000000 --- a/airbyte-integrations/connectors/source-salesloft/main.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from source_salesloft.run import run - -if __name__ == "__main__": - run() diff --git a/airbyte-integrations/connectors/source-salesloft/manifest.yaml b/airbyte-integrations/connectors/source-salesloft/manifest.yaml new file mode 100644 index 000000000000..4cac375f3692 --- /dev/null +++ b/airbyte-integrations/connectors/source-salesloft/manifest.yaml @@ -0,0 +1,4534 @@ +version: 5.15.0 + +type: DeclarativeSource + +check: + type: CheckStream + stream_names: + - users + +definitions: + streams: + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + account_tiers: + type: DeclarativeStream + name: account_tiers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /account_tiers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/account_tiers" + import: + type: DeclarativeStream + name: import + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /imports + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/import" + person_stages: + type: DeclarativeStream + name: person_stages + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /person_stages + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/person_stages" + phone_number_assignments: + type: DeclarativeStream + name: phone_number_assignments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /phone_number_assignments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/phone_number_assignments" + steps: + type: DeclarativeStream + name: steps + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /steps + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/steps" + team_template_attachments: + type: DeclarativeStream + name: team_template_attachments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /team_template_attachments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/team_template_attachments" + email_template_attachments: + type: DeclarativeStream + name: email_template_attachments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: email_template_attachments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/email_template_attachments" + crm_users: + type: DeclarativeStream + name: crm_users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: crm_users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/crm_users" + groups: + type: DeclarativeStream + name: groups + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /groups + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/groups" + custom_fields: + type: DeclarativeStream + name: custom_fields + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /custom_fields + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/custom_fields" + call_dispositions: + type: DeclarativeStream + name: call_dispositions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /call_dispositions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/call_dispositions" + call_sentiments: + type: DeclarativeStream + name: call_sentiments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /call_sentiments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/call_sentiments" + meetings: + type: DeclarativeStream + name: meetings + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /meetings + http_method: GET + request_parameters: + created_at[gt]: "{{ config['start_date'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/meetings" + people: + type: DeclarativeStream + name: people + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /people + http_method: GET + request_parameters: + sort_direction: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[gte] + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[lte] + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/people" + cadences: + type: DeclarativeStream + name: cadences + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /cadences + http_method: GET + request_parameters: + sort_direction: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[gte] + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[lte] + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/cadences" + cadence_memberships: + type: DeclarativeStream + name: cadence_memberships + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /cadence_memberships + http_method: GET + request_parameters: + sort_direction: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[gte] + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[lte] + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/cadence_memberships" + emails: + type: DeclarativeStream + name: emails + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /activities/emails + http_method: GET + request_parameters: + sort_direction: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[gte] + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[lte] + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/emails" + calls: + type: DeclarativeStream + name: calls + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /activities/calls + http_method: GET + request_parameters: + sort_direction: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[gte] + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[lte] + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/calls" + accounts: + type: DeclarativeStream + name: accounts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounts + http_method: GET + request_parameters: + sort_direction: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[gte] + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[lte] + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounts" + account_stages: + type: DeclarativeStream + name: account_stages + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /account_stages + http_method: GET + request_parameters: + sort_direction: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[gte] + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[lte] + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/account_stages" + actions: + type: DeclarativeStream + name: actions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /actions + http_method: GET + request_parameters: + sort_direction: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[gte] + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[lte] + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/actions" + email_templates: + type: DeclarativeStream + name: email_templates + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /email_templates + http_method: GET + request_parameters: + sort_direction: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[gte] + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[lte] + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/email_templates" + notes: + type: DeclarativeStream + name: notes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /notes + http_method: GET + request_parameters: + sort_direction: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[gte] + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[lte] + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/notes" + team_templates: + type: DeclarativeStream + name: team_templates + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /team_templates + http_method: GET + request_parameters: + sort_direction: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[gte] + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[lte] + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/team_templates" + crm_activities: + type: DeclarativeStream + name: crm_activities + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /crm_activities + http_method: GET + request_parameters: + sort_direction: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[gte] + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[lte] + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/crm_activities" + successes: + type: DeclarativeStream + name: successes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /successes + http_method: GET + request_parameters: + sort_direction: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[gte] + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[lte] + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/successes" + call_data_records: + type: DeclarativeStream + name: call_data_records + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /call_data_records + http_method: GET + request_parameters: + updated_at[gt]: "{{ config['start_date'] }}" + sort_direction: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/call_data_records" + searches: + type: DeclarativeStream + name: searches + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /meetings/settings/searches + http_method: POST + request_parameters: + sort_direction: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response['metadata']['paging']['next_page'] }}" + stop_condition: >- + {{ response['metadata']['paging'] is not defined or not + response['metadata']['paging'] or + response['metadata']['paging']['next_page'] is not defined or not + response['metadata']['paging']['next_page'] }} + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[gte] + end_time_option: + type: RequestOption + inject_into: request_parameter + field_name: updated_at[lte] + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/searches" + base_requester: + type: HttpRequester + url_base: https://api.salesloft.com/v2 + authenticator: + type: SelectiveAuthenticator + authenticator_selection_path: + - credentials + - auth_type + authenticators: + oauth2.0: + type: CustomAuthenticator + class_name: source_declarative_manifest.components.SingleUseOauth2Authenticator + client_id: "{{ config['credentials']['client_id'] }}" + client_secret: "{{ config['credentials']['client_secret'] }}" + refresh_token: "{{ config['credentials']['refresh_token'] }}" + refresh_request_body: {} + token_refresh_endpoint: https://accounts.salesloft.com/oauth/token + grant_type: refresh_token + api_key: + type: BearerAuthenticator + api_token: "{{ config['credentials']['api_key'] }}" + +streams: + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/account_tiers" + - $ref: "#/definitions/streams/import" + - $ref: "#/definitions/streams/person_stages" + - $ref: "#/definitions/streams/phone_number_assignments" + - $ref: "#/definitions/streams/steps" + - $ref: "#/definitions/streams/team_template_attachments" + - $ref: "#/definitions/streams/email_template_attachments" + - $ref: "#/definitions/streams/crm_users" + - $ref: "#/definitions/streams/groups" + - $ref: "#/definitions/streams/custom_fields" + - $ref: "#/definitions/streams/call_dispositions" + - $ref: "#/definitions/streams/call_sentiments" + - $ref: "#/definitions/streams/meetings" + - $ref: "#/definitions/streams/people" + - $ref: "#/definitions/streams/cadences" + - $ref: "#/definitions/streams/cadence_memberships" + - $ref: "#/definitions/streams/emails" + - $ref: "#/definitions/streams/calls" + - $ref: "#/definitions/streams/accounts" + - $ref: "#/definitions/streams/account_stages" + - $ref: "#/definitions/streams/actions" + - $ref: "#/definitions/streams/email_templates" + - $ref: "#/definitions/streams/notes" + - $ref: "#/definitions/streams/team_templates" + - $ref: "#/definitions/streams/crm_activities" + - $ref: "#/definitions/streams/successes" + - $ref: "#/definitions/streams/call_data_records" + - $ref: "#/definitions/streams/searches" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - credentials + - start_date + properties: + credentials: + type: object + oneOf: + - type: object + title: Authenticate via OAuth + required: + - client_id + - client_secret + - refresh_token + - access_token + - token_expiry_date + - auth_type + properties: + auth_type: + type: string + const: oauth2.0 + client_id: + type: string + description: The Client ID of your Salesloft developer application. + title: Client ID + access_token: + type: string + description: Access Token for making authenticated requests. + airbyte_secret: true + client_secret: + type: string + description: The Client Secret of your Salesloft developer application. + title: Client Secret + airbyte_secret: true + refresh_token: + type: string + description: The token for obtaining a new access token. + title: Refresh Token + airbyte_secret: true + token_expiry_date: + type: string + description: The date-time when the access token should be refreshed. + format: date-time + - type: object + title: Authenticate via API Key + required: + - api_key + - auth_type + properties: + api_key: + type: string + description: >- + API Key for making authenticated requests. More instruction on + how to find this value in our docs + title: API Key + airbyte_secret: true + auth_type: + type: string + const: api_key + order: 0 + title: Credentials + start_date: + type: string + description: >- + The date from which you'd like to replicate data for Salesloft API, in + the format YYYY-MM-DDT00:00:00Z. All data generated after this date + will be replicated. + title: Start Date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + order: 1 + examples: + - "2020-11-16T00:00:00Z" + additionalProperties: true + +metadata: + autoImportSchema: + users: true + account_tiers: true + import: true + person_stages: true + phone_number_assignments: true + steps: true + team_template_attachments: true + email_template_attachments: true + crm_users: true + groups: true + custom_fields: true + call_dispositions: true + call_sentiments: true + meetings: true + people: true + cadences: true + cadence_memberships: true + emails: true + calls: true + accounts: true + account_stages: true + actions: true + email_templates: true + notes: true + team_templates: true + crm_activities: true + successes: true + call_data_records: true + searches: true + yamlComponents: + global: + - authenticator + testedStreams: {} + assist: {} + +schemas: + users: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + active: + type: + - "null" + - boolean + bcc_email_address: + type: + - "null" + - string + click_to_call_enabled: + type: + - "null" + - boolean + created_at: + type: string + format: date-time + crm_connected: + type: + - "null" + - boolean + email: + type: + - "null" + - string + email_client_configured: + type: + - "null" + - boolean + email_client_email_address: + type: + - "null" + - string + email_signature: + type: + - "null" + - string + email_signature_click_tracking_disabled: + type: + - "null" + - boolean + email_signature_type: + type: + - "null" + - string + external_feature_flags: + type: + - "null" + - object + additionalProperties: true + properties: {} + first_name: + type: + - "null" + - string + from_address: + type: + - "null" + - string + full_email_address: + type: + - "null" + - string + group: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + guid: + type: + - "null" + - string + id: + type: integer + job_role: + type: + - "null" + - string + last_name: + type: + - "null" + - string + local_dial_enabled: + type: + - "null" + - boolean + name: + type: + - "null" + - string + phone_client: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + phone_number_assignment: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + role: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + - string + sending_email_address: + type: + - "null" + - string + slack_username: + type: + - "null" + - string + team: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + team_admin: + type: + - "null" + - boolean + time_zone: + type: + - "null" + - string + twitter_handle: + type: + - "null" + - string + updated_at: + type: + - "null" + - string + format: date-time + account_tiers: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + created_at: + type: string + format: date-time + id: + type: integer + name: + type: + - "null" + - string + order: + type: + - "null" + - integer + updated_at: + type: + - "null" + - string + format: date-time + import: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + created_at: + type: string + format: date-time + current_people_count: + type: + - "null" + - integer + id: + type: integer + imported_people_count: + type: + - "null" + - integer + name: + type: + - "null" + - string + updated_at: + type: + - "null" + - string + format: date-time + person_stages: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + created_at: + type: string + format: date-time + id: + type: integer + name: + type: + - "null" + - string + order: + type: + - "null" + - integer + updated_at: + type: + - "null" + - string + format: date-time + phone_number_assignments: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + id: + type: integer + number: + type: + - "null" + - string + user: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + steps: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + type: + type: + - "null" + - string + cadence: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + created_at: + type: + - "null" + - string + format: date-time + day: + type: + - "null" + - integer + details: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + disabled: + type: + - "null" + - boolean + display_name: + type: + - "null" + - string + id: + type: integer + name: + type: + - "null" + - string + step_number: + type: + - "null" + - integer + updated_at: + type: + - "null" + - string + format: date-time + team_template_attachments: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + attachment_file_size: + type: + - "null" + - integer + attachment_id: + type: + - "null" + - integer + download_url: + type: + - "null" + - string + id: + type: integer + name: + type: + - "null" + - string + team_template: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - string + email_template_attachments: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + attachment_file_size: + type: + - "null" + - integer + attachment_id: + type: + - "null" + - integer + download_url: + type: + - "null" + - string + id: + type: integer + name: + type: + - "null" + - string + team_template: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + crm_users: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + created_at: + type: string + format: date-time + crm_id: + type: + - "null" + - string + id: + type: integer + updated_at: + type: + - "null" + - string + format: date-time + user: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + groups: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + id: + type: integer + name: + type: + - "null" + - string + parent_id: + type: + - "null" + - integer + custom_fields: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + created_at: + type: + - "null" + - string + format: date-time + field_type: + type: + - "null" + - string + id: + type: + - "null" + - integer + name: + type: + - "null" + - string + updated_at: + type: + - "null" + - string + format: date-time + value_type: + type: + - "null" + - string + call_dispositions: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + created_at: + type: + - "null" + - string + format: date-time + id: + type: + - "null" + - integer + name: + type: + - "null" + - string + updated_at: + type: + - "null" + - string + format: date-time + call_sentiments: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + created_at: + type: + - "null" + - string + format: date-time + id: + type: + - "null" + - integer + name: + type: + - "null" + - string + updated_at: + type: + - "null" + - string + format: date-time + meetings: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + description: + type: + - "null" + - string + account_id: + type: + - "null" + - string + all_day: + type: + - "null" + - boolean + attendees: + type: + - "null" + - array + items: + type: + - "null" + - object + additionalProperties: true + properties: + deleted_at: + type: + - "null" + - string + format: date-time + email: + type: + - "null" + - string + name: + type: + - "null" + - string + organizer: + type: + - "null" + - boolean + status: + type: + - "null" + - string + status_changed: + type: + - "null" + - boolean + booked_by_meetings_settings: + type: + - "null" + - object + additionalProperties: true + properties: + id: + email_address: + - "null" + - string + booked_by_user: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - string + cadence: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + calendar_id: + type: + - "null" + - string + calendar_type: + type: + - "null" + - string + canceled_at: + type: + - "null" + - string + format: date-time + created_at: + type: + - "null" + - string + format: date-time + crm_custom_fields: + type: + - "null" + - object + additionalProperties: true + crm_references: + type: + - "null" + - object + additionalProperties: true + end_time: + type: + - "null" + - string + format: date-time + event_id: + type: + - "null" + - string + event_source: + type: + - "null" + - string + guests: + type: + - "null" + - array + items: + type: + - "null" + - string + i_cal_uid: + type: + - "null" + - string + id: + type: + - "null" + - integer + location: + type: + - "null" + - string + meeting_type: + type: + - "null" + - string + no_show: + type: + - "null" + - boolean + owned_by_meetings_settings: + type: + - "null" + - object + additionalProperties: true + properties: + id: + email_address: + - "null" + - string + person: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + recipient_email: + type: + - "null" + - string + recipient_name: + type: + - "null" + - string + reschedule_status: + type: + - "null" + - string + start_time: + type: + - "null" + - string + format: date-time + status: + type: + - "null" + - string + step: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + strict_attribution: + type: + - "null" + - boolean + task_id: + type: + - "null" + - integer + title: + type: + - "null" + - string + updated_at: + type: + - "null" + - string + format: date-time + people: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + account: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + bouncing: + type: + - "null" + - boolean + city: + type: + - "null" + - string + contact_restrictions: + type: + - "null" + - array + items: + type: + - "null" + - string + country: + type: + - "null" + - string + counts: + type: + - "null" + - object + additionalProperties: true + properties: + calls: + type: + - "null" + - integer + emails_bounced: + type: + - "null" + - integer + emails_clicked: + type: + - "null" + - integer + emails_replied_to: + type: + - "null" + - integer + emails_sent: + type: + - "null" + - integer + emails_viewed: + type: + - "null" + - integer + created_at: + type: string + format: date-time + crm_id: + type: + - "null" + - string + crm_object_type: + type: + - "null" + - string + crm_url: + type: + - "null" + - string + custom_fields: + type: + - "null" + - object + additionalProperties: true + properties: {} + display_name: + type: + - "null" + - string + do_not_contact: + type: + - "null" + - boolean + email_address: + type: + - "null" + - string + first_name: + type: + - "null" + - string + full_email_address: + type: + - "null" + - string + home_phone: + type: + - "null" + - string + id: + type: integer + import: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + job_seniority: + type: + - "null" + - string + last_completed_step: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + last_completed_step_cadence: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + last_contacted_at: + type: + - "null" + - string + format: date-time + last_contacted_by: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + last_contacted_type: + type: + - "null" + - string + last_name: + type: + - "null" + - string + last_replied_at: + type: + - "null" + - string + format: date-time + linkedin_url: + type: + - "null" + - string + locale: + type: + - "null" + - string + mobile_phone: + type: + - "null" + - string + most_recent_cadence: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + owner: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + owner_crm_id: + type: + - "null" + - string + person_company_industry: + type: + - "null" + - string + person_company_name: + type: + - "null" + - string + person_company_website: + type: + - "null" + - string + person_stage: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + personal_email_address: + type: + - "null" + - string + personal_website: + type: + - "null" + - string + phone: + type: + - "null" + - string + phone_extension: + type: + - "null" + - string + secondary_email_address: + type: + - "null" + - string + state: + type: + - "null" + - string + tags: + type: + - "null" + - array + items: + type: + - "null" + - string + title: + type: + - "null" + - string + twitter_handle: + type: + - "null" + - string + updated_at: + type: string + format: date-time + work_city: + type: + - "null" + - string + work_country: + type: + - "null" + - string + work_state: + type: + - "null" + - string + cadences: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + added_stage: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + archived_at: + type: + - "null" + - string + format: date-time + bounced_stage: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + counts: + type: + - "null" + - object + additionalProperties: true + properties: + cadence_people: + type: + - "null" + - integer + target_daily_people: + type: + - "null" + - integer + created_at: + type: string + format: date-time + creator: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + finished_stage: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + id: + type: integer + latest_active_date: + type: + - "null" + - string + format: date + name: + type: + - "null" + - string + opt_out_link_included: + type: + - "null" + - boolean + owner: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + remove_bounces_enabled: + type: + - "null" + - boolean + remove_replies_enabled: + type: + - "null" + - boolean + replied_stage: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + shared: + type: + - "null" + - boolean + tags: + type: + - "null" + - array + items: + type: + - "null" + - string + team_cadence: + type: + - "null" + - boolean + updated_at: + type: string + format: date-time + cadence_memberships: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + added_at: + type: + - "null" + - string + format: date-time + cadence: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + counts: + type: + - "null" + - object + additionalProperties: true + properties: + bounces: + type: + - "null" + - integer + calls: + type: + - "null" + - integer + clicks: + type: + - "null" + - integer + replies: + type: + - "null" + - integer + sent_emails: + type: + - "null" + - integer + views: + type: + - "null" + - integer + created_at: + type: string + format: date-time + current_state: + type: + - "null" + - string + currently_on_cadence: + type: + - "null" + - boolean + id: + type: integer + latest_action: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + person: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + person_deleted: + type: + - "null" + - boolean + updated_at: + type: string + format: date-time + user: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + emails: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + action: + type: + - "null" + - object + additionalProperties: true + properties: + id: + type: + - "null" + - integer + bounced: + type: + - "null" + - boolean + cadence: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + click_tracking: + type: + - "null" + - boolean + counts: + type: + - "null" + - object + additionalProperties: true + properties: + attachments: + type: + - "null" + - integer + clicks: + type: + - "null" + - integer + replies: + type: + - "null" + - integer + unique_devices: + type: + - "null" + - integer + unique_locations: + type: + - "null" + - integer + views: + type: + - "null" + - integer + created_at: + type: string + format: date-time + crm_activity: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + email_template: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + headers: + type: + - "null" + - object + additionalProperties: true + properties: + In-Reply-To: + type: + - "null" + - string + References: + type: + - "null" + - string + bcc: + type: + - "null" + - string + cc: + type: + - "null" + - string + in_reply_to: + type: + - "null" + - string + to: + type: + - "null" + - string + id: + type: integer + mailing: + type: + - "null" + - object + additionalProperties: true + properties: + id: + type: + - "null" + - integer + personalization: + type: + - "null" + - string + recipient: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + recipient_email_address: + type: + - "null" + - string + send_after: + type: + - "null" + - string + format: date-time + sent_at: + type: + - "null" + - string + format: date-time + status: + type: + - "null" + - string + step: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + updated_at: + type: string + format: date-time + user: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + view_tracking: + type: + - "null" + - boolean + calls: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + action: + type: + - "null" + - object + additionalProperties: true + properties: + id: + type: + - "null" + - integer + cadence: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + called_person: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + created_at: + type: string + format: date-time + crm_activity: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + disposition: + type: + - "null" + - string + duration: + type: + - "null" + - integer + id: + type: integer + note: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + sentiment: + type: + - "null" + - string + step: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + to: + type: + - "null" + - string + updated_at: + type: string + format: date-time + user: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + accounts: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + description: + type: + - "null" + - string + account_tier: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + archived_at: + type: + - "null" + - string + format: date-time + city: + type: + - "null" + - string + company_stage: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + company_type: + type: + - "null" + - string + conversational_name: + type: + - "null" + - string + country: + type: + - "null" + - string + counts: + type: + - "null" + - object + additionalProperties: true + properties: + people: + type: + - "null" + - integer + created_at: + type: string + format: date-time + creator: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + crm_id: + type: + - "null" + - string + crm_object_type: + type: + - "null" + - string + crm_url: + type: + - "null" + - string + do_not_contact: + type: + - "null" + - boolean + domain: + type: + - "null" + - string + founded: + type: + - "null" + - string + id: + type: integer + industry: + type: + - "null" + - string + last_contacted_at: + type: + - "null" + - string + format: date-time + last_contacted_by: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + last_contacted_person: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + last_contacted_type: + type: + - "null" + - string + linkedin_url: + type: + - "null" + - string + locale: + type: + - "null" + - string + name: + type: + - "null" + - string + owner: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + owner_crm_id: + type: + - "null" + - string + phone: + type: + - "null" + - string + postal_code: + type: + - "null" + - string + revenue_range: + type: + - "null" + - string + size: + type: + - "null" + - string + state: + type: + - "null" + - string + street: + type: + - "null" + - string + tags: + type: + - "null" + - array + items: + type: + - "null" + - string + twitter_handle: + type: + - "null" + - string + updated_at: + type: string + format: date-time + website: + type: + - "null" + - string + account_stages: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + created_at: + type: + - "null" + - string + format: date-time + id: + type: integer + name: + type: + - "null" + - string + order: + type: + - "null" + - integer + updated_at: + type: + - "null" + - string + format: date-time + actions: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + type: + type: + - "null" + - string + action_details: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + cadence: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + created_at: + type: string + format: date-time + due: + type: + - "null" + - boolean + due_on: + type: + - "null" + - string + format: date-time + id: + type: integer + multitouch_group_id: + type: + - "null" + - integer + person: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + status: + type: + - "null" + - string + step: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + updated_at: + type: string + format: date-time + user: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + email_templates: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + _links: + type: + - "null" + - object + additionalProperties: true + properties: + attachments: + type: + - "null" + - string + archived_at: + type: + - "null" + - string + format: date-time + body: + type: + - "null" + - string + body_preview: + type: + - "null" + - string + cadence_template: + type: + - "null" + - boolean + click_tracking_enabled: + type: + - "null" + - boolean + counts: + type: + - "null" + - object + additionalProperties: true + properties: + bounces: + type: + - "null" + - integer + clicks: + type: + - "null" + - integer + replies: + type: + - "null" + - integer + sent_emails: + type: + - "null" + - integer + views: + type: + - "null" + - integer + created_at: + type: string + format: date-time + groups: + type: + - "null" + - array + items: + type: object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + id: + type: integer + last_used_at: + type: + - "null" + - string + format: date-time + open_tracking_enabled: + type: + - "null" + - boolean + shared: + type: + - "null" + - boolean + subject: + type: + - "null" + - string + tags: + type: + - "null" + - array + items: + type: + - "null" + - string + team_template: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - string + template_owner: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + title: + type: + - "null" + - string + updated_at: + type: + - "null" + - string + format: date-time + notes: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + associated_with: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + call: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + content: + type: + - "null" + - string + created_at: + type: string + format: date-time + id: + type: integer + updated_at: + type: string + format: date-time + user: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + team_templates: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + _links: + type: + - "null" + - object + additionalProperties: true + properties: + attachments: + type: + - "null" + - string + archived_at: + type: + - "null" + - string + format: date-time + body: + type: + - "null" + - string + body_preview: + type: + - "null" + - string + click_tracking_enabled: + type: + - "null" + - boolean + counts: + type: + - "null" + - object + additionalProperties: true + properties: + bounces: + type: + - "null" + - integer + clicks: + type: + - "null" + - integer + replies: + type: + - "null" + - integer + sent_emails: + type: + - "null" + - integer + views: + type: + - "null" + - integer + created_at: + type: + - "null" + - string + format: date-time + id: + type: string + last_modified_at: + type: + - "null" + - string + format: date-time + last_modified_user: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + last_used_at: + type: + - "null" + - string + format: date-time + open_tracking_enabled: + type: + - "null" + - boolean + subject: + type: + - "null" + - string + tags: + type: + - "null" + - array + items: + type: + - "null" + - string + title: + type: + - "null" + - string + updated_at: + type: + - "null" + - string + format: date-time + crm_activities: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + description: + type: + - "null" + - string + activity_type: + type: + - "null" + - string + created_at: + type: string + format: date-time + crm_id: + type: + - "null" + - string + custom_crm_fields: + type: + - "null" + - object + error: + type: + - "null" + - string + id: + type: integer + person: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + subject: + type: + - "null" + - string + updated_at: + type: string + format: date-time + user: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + successes: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + counts: + type: + - "null" + - object + additionalProperties: true + properties: + total_calls: + type: + - "null" + - integer + total_emails: + type: + - "null" + - integer + total_other_touches: + type: + - "null" + - integer + created_at: + type: string + format: date-time + id: + type: integer + latest_action: + type: + - "null" + - object + additionalProperties: true + properties: + id: + type: + - "null" + - integer + latest_cadence: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + latest_call: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + latest_email: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + latest_step: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + person: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + succeeded_at: + type: + - "null" + - string + format: date-time + success_window_started_at: + type: + - "null" + - string + format: date-time + updated_at: + type: string + format: date-time + user: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + call_data_records: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + call: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + call_type: + type: + - "null" + - string + call_uuid: + type: + - "null" + - string + called_person: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + created_at: + type: + - "null" + - string + format: date-time + direction: + type: + - "null" + - string + duration: + type: + - "null" + - integer + from: + type: + - "null" + - string + id: + type: + - "null" + - integer + recording: + type: + - "null" + - object + additionalProperties: true + properties: + recording_status: + type: + - "null" + - string + status: + type: + - "null" + - string + url: + type: + - "null" + - string + status: + type: + - "null" + - string + to: + type: + - "null" + - string + updated_at: + type: + - "null" + - string + format: date-time + user: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - integer + searches: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + description: + type: + - "null" + - string + active_meeting_url: + type: + - "null" + - object + additionalProperties: true + properties: + created_at: + type: + - "null" + - string + format: date-time + updated_at: + type: + - "null" + - string + format: date-time + url: + type: + - "null" + - string + allow_booking_on_behalf: + type: + - "null" + - boolean + allow_booking_overtime: + type: + - "null" + - boolean + allow_event_detail: + type: + - "null" + - boolean + allow_event_overlap: + type: + - "null" + - boolean + availability_limit: + type: + - "null" + - integer + availability_limit_enabled: + type: + - "null" + - boolean + buffer_time_duration: + type: + - "null" + - integer + calendar_type: + type: + - "null" + - string + created_at: + type: + - "null" + - string + format: date-time + default_meeting_length: + type: + - "null" + - integer + email_address: + type: + - "null" + - string + enable_calendar_sync: + type: + - "null" + - boolean + enable_dynamic_location: + type: + - "null" + - boolean + id: + type: + - "null" + - integer + location: + type: + - "null" + - string + primary_calendar_connection_failed: + type: + - "null" + - boolean + primary_calendar_id: + type: + - "null" + - string + primary_calendar_name: + type: + - "null" + - string + reschedule_meetings_enabled: + type: + - "null" + - boolean + schedule_buffer_enabled: + type: + - "null" + - boolean + schedule_delay: + type: + - "null" + - integer + time_zone: + type: + - "null" + - string + times_available: + type: + - "null" + - object + additionalProperties: true + title: + type: + - "null" + - string + updated_at: + type: + - "null" + - string + format: date-time + user: + type: + - "null" + - object + additionalProperties: true + properties: + _href: + type: + - "null" + - string + id: + type: + - "null" + - string + user_details: + type: + - "null" + - object + additionalProperties: true + user_slug: + type: + - "null" + - string diff --git a/airbyte-integrations/connectors/source-salesloft/metadata.yaml b/airbyte-integrations/connectors/source-salesloft/metadata.yaml index fae7c1da1cd7..002b34c70e5c 100644 --- a/airbyte-integrations/connectors/source-salesloft/metadata.yaml +++ b/airbyte-integrations/connectors/source-salesloft/metadata.yaml @@ -12,17 +12,17 @@ data: enabled: true remoteRegistries: pypi: - enabled: true + enabled: false packageName: airbyte-source-salesloft connectorBuildOptions: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/source-declarative-manifest:5.15.0@sha256:09a84e0622f36393077332faf11cc239e77083fae5fa500592c049dca25888a7 connectorSubtype: api connectorType: source definitionId: 41991d12-d4b5-439e-afd0-260a31d4c53f - dockerImageTag: 1.2.24 + dockerImageTag: 1.3.1 dockerRepository: airbyte/source-salesloft githubIssueLabel: source-salesloft icon: icon.svg @@ -33,8 +33,8 @@ data: supportLevel: community documentationUrl: https://docs.airbyte.com/integrations/sources/salesloft tags: - - language:python - cdk:low-code + - language:manifest-only connectorTestSuitesOptions: - suite: liveTests testConnections: diff --git a/airbyte-integrations/connectors/source-salesloft/poetry.lock b/airbyte-integrations/connectors/source-salesloft/poetry.lock deleted file mode 100644 index 732d61e9625f..000000000000 --- a/airbyte-integrations/connectors/source-salesloft/poetry.lock +++ /dev/null @@ -1,1480 +0,0 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. - -[[package]] -name = "airbyte-cdk" -version = "0.83.0" -description = "A framework for writing Airbyte Connectors." -optional = false -python-versions = "<4.0,>=3.9" -files = [ - {file = "airbyte_cdk-0.83.0-py3-none-any.whl", hash = "sha256:03c5b3dec45bbf9726d69239d992a0a411726727cc9ba405e30cfa86321b3a0f"}, - {file = "airbyte_cdk-0.83.0.tar.gz", hash = "sha256:131f6f0f50c3ddc36d1772ac897cf3e9a6be8d15a52b338e70d3a747f44f9d39"}, -] - -[package.dependencies] -airbyte-protocol-models = "*" -backoff = "*" -cachetools = "*" -cryptography = ">=42.0.5,<43.0.0" -Deprecated = ">=1.2,<1.3" -dpath = ">=2.0.1,<2.1.0" -genson = "1.2.2" -isodate = ">=0.6.1,<0.7.0" -Jinja2 = ">=3.1.2,<3.2.0" -jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" -langchain_core = "0.1.42" -pendulum = "<3.0.0" -pydantic = ">=1.10.8,<2.0.0" -pyjwt = ">=2.8.0,<3.0.0" -pyrate-limiter = ">=3.1.0,<3.2.0" -python-dateutil = "*" -PyYAML = ">=6.0.1,<7.0.0" -requests = "*" -requests_cache = "*" -wcmatch = "8.4" - -[package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] - -[[package]] -name = "airbyte-protocol-models" -version = "0.13.0" -description = "Declares the Airbyte Protocol." -optional = false -python-versions = ">=3.8" -files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, -] - -[package.dependencies] -pydantic = ">=1.9.2,<2.0.0" - -[[package]] -name = "anyio" -version = "4.6.2.post1" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.9" -files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, -] - -[package.dependencies] -exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} - -[package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] -trio = ["trio (>=0.26.1)"] - -[[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, -] - -[[package]] -name = "attrs" -version = "24.2.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" -files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, -] - -[package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] - -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "bracex" -version = "2.5.post1" -description = "Bash style brace expander." -optional = false -python-versions = ">=3.8" -files = [ - {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, - {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, -] - -[[package]] -name = "cachetools" -version = "5.5.0" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, - {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, -] - -[[package]] -name = "cattrs" -version = "24.1.2" -description = "Composable complex class support for attrs and dataclasses." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, - {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, -] - -[package.dependencies] -attrs = ">=23.1.0" -exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} - -[package.extras] -bson = ["pymongo (>=4.4.0)"] -cbor2 = ["cbor2 (>=5.4.6)"] -msgpack = ["msgpack (>=1.0.5)"] -msgspec = ["msgspec (>=0.18.5)"] -orjson = ["orjson (>=3.9.2)"] -pyyaml = ["pyyaml (>=6.0)"] -tomlkit = ["tomlkit (>=0.11.8)"] -ujson = ["ujson (>=5.7.0)"] - -[[package]] -name = "certifi" -version = "2024.8.30" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, -] - -[[package]] -name = "cffi" -version = "1.17.1" -description = "Foreign Function Interface for Python calling C code." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, - {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, - {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, - {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, - {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, - {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, - {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, - {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, - {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, - {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, - {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, - {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, - {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, - {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, - {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, - {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, -] - -[package.dependencies] -pycparser = "*" - -[[package]] -name = "charset-normalizer" -version = "3.4.0" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -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 = "cryptography" -version = "42.0.8" -description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -optional = false -python-versions = ">=3.7" -files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, -] - -[package.dependencies] -cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} - -[package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] -docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] -nox = ["nox"] -pep8test = ["check-sdist", "click", "mypy", "ruff"] -sdist = ["build"] -ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] -test-randomorder = ["pytest-randomly"] - -[[package]] -name = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - -[[package]] -name = "dpath" -version = "2.0.8" -description = "Filesystem-like pathing and searching for dictionaries" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dpath-2.0.8-py3-none-any.whl", hash = "sha256:f92f595214dd93a00558d75d4b858beee519f4cffca87f02616ad6cd013f3436"}, - {file = "dpath-2.0.8.tar.gz", hash = "sha256:a3440157ebe80d0a3ad794f1b61c571bef125214800ffdb9afc9424e8250fe9b"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "genson" -version = "1.2.2" -description = "GenSON is a powerful, user-friendly JSON Schema generator." -optional = false -python-versions = "*" -files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, -] - -[[package]] -name = "h11" -version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.7" -files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, -] - -[[package]] -name = "httpcore" -version = "1.0.6" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.13,<0.15" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<1.0)"] - -[[package]] -name = "httpx" -version = "0.27.2" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isodate" -version = "0.6.1" -description = "An ISO 8601 date/time/duration parser and formatter" -optional = false -python-versions = "*" -files = [ - {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, - {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "jinja2" -version = "3.1.4" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "jsonpatch" -version = "1.33" -description = "Apply JSON-Patches (RFC 6902)" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" -files = [ - {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, - {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, -] - -[package.dependencies] -jsonpointer = ">=1.9" - -[[package]] -name = "jsonpointer" -version = "3.0.0" -description = "Identify specific nodes in a JSON document (RFC 6901)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, - {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, -] - -[[package]] -name = "jsonref" -version = "0.2" -description = "An implementation of JSON Reference for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonref-0.2-py3-none-any.whl", hash = "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f"}, - {file = "jsonref-0.2.tar.gz", hash = "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697"}, -] - -[[package]] -name = "jsonschema" -version = "3.2.0" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, -] - -[package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" - -[package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] - -[[package]] -name = "langchain-core" -version = "0.1.42" -description = "Building applications with LLMs through composability" -optional = false -python-versions = "<4.0,>=3.8.1" -files = [ - {file = "langchain_core-0.1.42-py3-none-any.whl", hash = "sha256:c5653ffa08a44f740295c157a24c0def4a753333f6a2c41f76bf431cd00be8b5"}, - {file = "langchain_core-0.1.42.tar.gz", hash = "sha256:40751bf60ea5d8e2b2efe65290db434717ee3834870c002e40e2811f09d814e6"}, -] - -[package.dependencies] -jsonpatch = ">=1.33,<2.0" -langsmith = ">=0.1.0,<0.2.0" -packaging = ">=23.2,<24.0" -pydantic = ">=1,<3" -PyYAML = ">=5.3" -tenacity = ">=8.1.0,<9.0.0" - -[package.extras] -extended-testing = ["jinja2 (>=3,<4)"] - -[[package]] -name = "langsmith" -version = "0.1.137" -description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." -optional = false -python-versions = "<4.0,>=3.8.1" -files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, -] - -[package.dependencies] -httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" -pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} -requests = ">=2,<3" -requests-toolbelt = ">=1.0.0,<2.0.0" - -[[package]] -name = "markupsafe" -version = "3.0.2" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -files = [ - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, - {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, -] - -[[package]] -name = "orjson" -version = "3.10.10" -description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" -optional = false -python-versions = ">=3.8" -files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, -] - -[[package]] -name = "packaging" -version = "23.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, -] - -[[package]] -name = "pendulum" -version = "2.1.2" -description = "Python datetimes made easy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, - {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, - {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, - {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, - {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, - {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, - {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, - {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, - {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, - {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, - {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, -] - -[package.dependencies] -python-dateutil = ">=2.6,<3.0" -pytzdata = ">=2020.1" - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] - -[[package]] -name = "pycparser" -version = "2.22" -description = "C parser in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, - {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, -] - -[[package]] -name = "pydantic" -version = "1.10.18" -description = "Data validation and settings management using python type hints" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, -] - -[package.dependencies] -typing-extensions = ">=4.2.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] - -[[package]] -name = "pyjwt" -version = "2.9.0" -description = "JSON Web Token implementation in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, -] - -[package.extras] -crypto = ["cryptography (>=3.4.0)"] -dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] -docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] -tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] - -[[package]] -name = "pyrate-limiter" -version = "3.1.1" -description = "Python Rate-Limiter using Leaky-Bucket Algorithm" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, - {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, -] - -[package.extras] -all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] -docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] - -[[package]] -name = "pyrsistent" -version = "0.20.0" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7"}, - {file = "pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee"}, - {file = "pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d"}, - {file = "pyrsistent-0.20.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win32.whl", hash = "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d"}, - {file = "pyrsistent-0.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win32.whl", hash = "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf"}, - {file = "pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b"}, - {file = "pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4"}, -] - -[[package]] -name = "pytest" -version = "6.2.5" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, -] - -[package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] - -[[package]] -name = "pytest-mock" -version = "3.14.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, -] - -[package.dependencies] -pytest = ">=6.2.5" - -[package.extras] -dev = ["pre-commit", "pytest-asyncio", "tox"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytzdata" -version = "2020.1" -description = "The Olson timezone database for Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, - {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-cache" -version = "1.2.1" -description = "A persistent cache for python requests" -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, - {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, -] - -[package.dependencies] -attrs = ">=21.2" -cattrs = ">=22.2" -platformdirs = ">=2.5" -requests = ">=2.22" -url-normalize = ">=1.4" -urllib3 = ">=1.25.5" - -[package.extras] -all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] -bson = ["bson (>=0.5)"] -docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] -dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] -json = ["ujson (>=5.4)"] -mongodb = ["pymongo (>=3)"] -redis = ["redis (>=3)"] -security = ["itsdangerous (>=2.0)"] -yaml = ["pyyaml (>=6.0.1)"] - -[[package]] -name = "requests-mock" -version = "1.12.1" -description = "Mock out responses from the requests package" -optional = false -python-versions = ">=3.5" -files = [ - {file = "requests-mock-1.12.1.tar.gz", hash = "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401"}, - {file = "requests_mock-1.12.1-py2.py3-none-any.whl", hash = "sha256:b1e37054004cdd5e56c84454cc7df12b25f90f382159087f4b6915aaeef39563"}, -] - -[package.dependencies] -requests = ">=2.22,<3" - -[package.extras] -fixture = ["fixtures"] - -[[package]] -name = "requests-toolbelt" -version = "1.0.0" -description = "A utility belt for advanced users of python-requests" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, - {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, -] - -[package.dependencies] -requests = ">=2.0.1,<3.0.0" - -[[package]] -name = "setuptools" -version = "75.3.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - -[[package]] -name = "tenacity" -version = "8.5.0" -description = "Retry code until it succeeds" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, - {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, -] - -[package.extras] -doc = ["reno", "sphinx"] -test = ["pytest", "tornado (>=4.5)", "typeguard"] - -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "url-normalize" -version = "1.4.3" -description = "URL normalization for Python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, - {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "urllib3" -version = "2.2.3" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "wcmatch" -version = "8.4" -description = "Wildcard/glob file name matcher." -optional = false -python-versions = ">=3.7" -files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, -] - -[package.dependencies] -bracex = ">=2.1.1" - -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "2716d2a16b00d9d809aeb2c60b080c75cd8b652a853860e7cabffd9de85ba3ac" diff --git a/airbyte-integrations/connectors/source-salesloft/pyproject.toml b/airbyte-integrations/connectors/source-salesloft/pyproject.toml deleted file mode 100644 index 34ea141a90fa..000000000000 --- a/airbyte-integrations/connectors/source-salesloft/pyproject.toml +++ /dev/null @@ -1,29 +0,0 @@ -[build-system] -requires = [ "poetry-core>=1.0.0",] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -version = "1.2.24" -name = "source-salesloft" -description = "Source implementation for Salesloft." -authors = [ "Airbyte ",] -license = "MIT" -readme = "README.md" -documentation = "https://docs.airbyte.com/integrations/sources/salesloft" -homepage = "https://airbyte.com" -repository = "https://github.com/airbytehq/airbyte" -[[tool.poetry.packages]] -include = "source_salesloft" - -[tool.poetry.dependencies] -python = "^3.9,<3.12" -pendulum = "==2.1.2" -airbyte-cdk = "0.83.0" - -[tool.poetry.scripts] -source-salesloft = "source_salesloft.run:run" - -[tool.poetry.group.dev.dependencies] -requests-mock = "^1.12.1" -pytest-mock = "^3.6.1" -pytest = "^6.1" diff --git a/airbyte-integrations/connectors/source-salesloft/source_salesloft/__init__.py b/airbyte-integrations/connectors/source-salesloft/source_salesloft/__init__.py deleted file mode 100644 index aea360546b43..000000000000 --- a/airbyte-integrations/connectors/source-salesloft/source_salesloft/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - - -from .source import SourceSalesloft - -__all__ = ["SourceSalesloft", "custom_authenticators"] diff --git a/airbyte-integrations/connectors/source-salesloft/source_salesloft/custom_authenticators.py b/airbyte-integrations/connectors/source-salesloft/source_salesloft/custom_authenticators.py deleted file mode 100644 index 5475aa13ca33..000000000000 --- a/airbyte-integrations/connectors/source-salesloft/source_salesloft/custom_authenticators.py +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from dataclasses import dataclass - -from airbyte_cdk.sources.declarative.auth.oauth import DeclarativeSingleUseRefreshTokenOauth2Authenticator -from airbyte_cdk.sources.declarative.types import Config - - -@dataclass -class SingleUseOauth2Authenticator(DeclarativeSingleUseRefreshTokenOauth2Authenticator): - - config: Config - - def __post_init__(self): - self._connector_config = self.config - self._token_expiry_date_config_path = "credentials/token_expiry_date" - self.token_refresh_endpoint = "https://accounts.salesloft.com/oauth/token" - self._access_token_config_path = "credentials/access_token" - - @property - def auth_header(self) -> str: - return "Authorization" - - @property - def token(self) -> str: - return f"Bearer {self.get_access_token()}" diff --git a/airbyte-integrations/connectors/source-salesloft/source_salesloft/manifest.yaml b/airbyte-integrations/connectors/source-salesloft/source_salesloft/manifest.yaml deleted file mode 100644 index a98faca2decd..000000000000 --- a/airbyte-integrations/connectors/source-salesloft/source_salesloft/manifest.yaml +++ /dev/null @@ -1,4476 +0,0 @@ -version: 0.78.1 - -type: DeclarativeSource - -check: - type: CheckStream - stream_names: - - users - -definitions: - custom_oauth_authenticator: - type: CustomAuthenticator - class_name: source_salesloft.custom_authenticators.SingleUseOauth2Authenticator - client_id: "{{ config['credentials']['client_id'] }}" - client_secret: "{{ config['credentials']['client_secret'] }}" - refresh_token: "{{ config['credentials']['refresh_token'] }}" - refresh_request_body: {} - token_refresh_endpoint: "https://accounts.salesloft.com/oauth/token" - grant_type: refresh_token - - bearer_authenticator: - type: BearerAuthenticator - api_token: "{{ config['credentials']['api_key'] }}" - - selective_authenticator: - type: SelectiveAuthenticator - authenticator_selection_path: ["credentials", "auth_type"] - authenticators: - oauth2.0: "#/definitions/custom_oauth_authenticator" - api_key: "#/definitions/bearer_authenticator" - - streams: - users: - type: DeclarativeStream - name: users - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /users - http_method: GET - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/users" - account_tiers: - type: DeclarativeStream - name: account_tiers - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /account_tiers - http_method: GET - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/account_tiers" - import: - type: DeclarativeStream - name: import - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /imports - http_method: GET - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/import" - person_stages: - type: DeclarativeStream - name: person_stages - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /person_stages - http_method: GET - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/person_stages" - phone_number_assignments: - type: DeclarativeStream - name: phone_number_assignments - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /phone_number_assignments - http_method: GET - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/phone_number_assignments" - steps: - type: DeclarativeStream - name: steps - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /steps - http_method: GET - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/steps" - team_template_attachments: - type: DeclarativeStream - name: team_template_attachments - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /team_template_attachments - http_method: GET - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/team_template_attachments" - email_template_attachments: - type: DeclarativeStream - name: email_template_attachments - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: email_template_attachments - http_method: GET - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/email_template_attachments" - crm_users: - type: DeclarativeStream - name: crm_users - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: crm_users - http_method: GET - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/crm_users" - groups: - type: DeclarativeStream - name: groups - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /groups - http_method: GET - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/groups" - custom_fields: - type: DeclarativeStream - name: custom_fields - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /custom_fields - http_method: GET - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/custom_fields" - call_dispositions: - type: DeclarativeStream - name: call_dispositions - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /call_dispositions - http_method: GET - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/call_dispositions" - call_sentiments: - type: DeclarativeStream - name: call_sentiments - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /call_sentiments - http_method: GET - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/call_sentiments" - meetings: - type: DeclarativeStream - name: meetings - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /meetings - http_method: GET - request_parameters: - created_at[gt]: "{{ config['start_date'] }}" - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/meetings" - people: - type: DeclarativeStream - name: people - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /people - http_method: GET - request_parameters: - created_at[gt]: "{{ config['start_date'] }}" - updated_at[gt]: >- - {{ - format_datetime( - (config['start_date'] if stream_state['updated_at'] is not defined else - (stream_state.updated_at if stream_state.updated_at < now_utc() else now_utc())), - '%Y-%m-%dT%H:%M:%S.%fZ' - ) - }} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/people" - cadences: - type: DeclarativeStream - name: cadences - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /cadences - http_method: GET - request_parameters: - updated_at[gt]: >- - {{ - format_datetime( - (config['start_date'] if stream_state['updated_at'] is not defined else - (stream_state.updated_at if stream_state.updated_at < now_utc() else now_utc())), - '%Y-%m-%dT%H:%M:%S.%fZ' - ) - }} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/cadences" - cadence_memberships: - type: DeclarativeStream - name: cadence_memberships - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /cadence_memberships - http_method: GET - request_parameters: - created_at[gt]: "{{ config['start_date'] }}" - updated_at[gt]: >- - {{ - format_datetime( - (config['start_date'] if stream_state['updated_at'] is not defined else - (stream_state.updated_at if stream_state.updated_at < now_utc() else now_utc())), - '%Y-%m-%dT%H:%M:%S.%fZ' - ) - }} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/cadence_memberships" - emails: - type: DeclarativeStream - name: emails - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /activities/emails - http_method: GET - request_parameters: - sent_at[gt]: "{{ config['start_date'] }}" - updated_at[gt]: >- - {{ - format_datetime( - (config['start_date'] if stream_state['updated_at'] is not defined else - (stream_state.updated_at if stream_state.updated_at < now_utc() else now_utc())), - '%Y-%m-%dT%H:%M:%S.%fZ' - ) - }} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/emails" - calls: - type: DeclarativeStream - name: calls - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /activities/calls - http_method: GET - request_parameters: - created_at[gt]: "{{ config['start_date'] }}" - updated_at[gt]: >- - {{ - format_datetime( - (config['start_date'] if stream_state['updated_at'] is not defined else - (stream_state.updated_at if stream_state.updated_at < now_utc() else now_utc())), - '%Y-%m-%dT%H:%M:%S.%fZ' - ) - }} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/calls" - accounts: - type: DeclarativeStream - name: accounts - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /accounts - http_method: GET - request_parameters: - created_at[gt]: "{{ config['start_date'] }}" - updated_at[gt]: >- - {{ - format_datetime( - (config['start_date'] if stream_state['updated_at'] is not defined else - (stream_state.updated_at if stream_state.updated_at < now_utc() else now_utc())), - '%Y-%m-%dT%H:%M:%S.%fZ' - ) - }} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/accounts" - account_stages: - type: DeclarativeStream - name: account_stages - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /account_stages - http_method: GET - request_parameters: - updated_at[gt]: >- - {{ - format_datetime( - (config['start_date'] if stream_state['updated_at'] is not defined else - (stream_state.updated_at if stream_state.updated_at < now_utc() else now_utc())), - '%Y-%m-%dT%H:%M:%S.%fZ' - ) - }} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/account_stages" - actions: - type: DeclarativeStream - name: actions - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /actions - http_method: GET - request_parameters: - updated_at[gt]: >- - {{ - format_datetime( - (config['start_date'] if stream_state['updated_at'] is not defined else - (stream_state.updated_at if stream_state.updated_at < now_utc() else now_utc())), - '%Y-%m-%dT%H:%M:%S.%fZ' - ) - }} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/actions" - email_templates: - type: DeclarativeStream - name: email_templates - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /email_templates - http_method: GET - request_parameters: - updated_at[gt]: >- - {{ - format_datetime( - (config['start_date'] if stream_state['updated_at'] is not defined else - (stream_state.updated_at if stream_state.updated_at < now_utc() else now_utc())), - '%Y-%m-%dT%H:%M:%S.%fZ' - ) - }} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/email_templates" - notes: - type: DeclarativeStream - name: notes - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /notes - http_method: GET - request_parameters: - updated_at[gt]: >- - {{ - format_datetime( - (config['start_date'] if stream_state['updated_at'] is not defined else - (stream_state.updated_at if stream_state.updated_at < now_utc() else now_utc())), - '%Y-%m-%dT%H:%M:%S.%fZ' - ) - }} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/notes" - team_templates: - type: DeclarativeStream - name: team_templates - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /team_templates - http_method: GET - request_parameters: - updated_at[gt]: >- - {{ - format_datetime( - (config['start_date'] if stream_state['updated_at'] is not defined else - (stream_state.updated_at if stream_state.updated_at < now_utc() else now_utc())), - '%Y-%m-%dT%H:%M:%S.%fZ' - ) - }} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/team_templates" - crm_activities: - type: DeclarativeStream - name: crm_activities - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /crm_activities - http_method: GET - request_parameters: - updated_at[gt]: >- - {{ - format_datetime( - (config['start_date'] if stream_state['updated_at'] is not defined else - (stream_state.updated_at if stream_state.updated_at < now_utc() else now_utc())), - '%Y-%m-%dT%H:%M:%S.%fZ' - ) - }} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/crm_activities" - successes: - type: DeclarativeStream - name: successes - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /successes - http_method: GET - request_parameters: - updated_at[gt]: >- - {{ - format_datetime( - (config['start_date'] if stream_state['updated_at'] is not defined else - (stream_state.updated_at if stream_state.updated_at < now_utc() else now_utc())), - '%Y-%m-%dT%H:%M:%S.%fZ' - ) - }} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/successes" - call_data_records: - type: DeclarativeStream - name: call_data_records - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /call_data_records - http_method: GET - request_parameters: - updated_at[gt]: >- - {{ - format_datetime( - (config['start_date'] if stream_state['updated_at'] is not defined else - (stream_state.updated_at if stream_state.updated_at < now_utc() else now_utc())), - '%Y-%m-%dT%H:%M:%S.%fZ' - ) - }} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/call_data_records" - searches: - type: DeclarativeStream - name: searches - primary_key: - - id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/base_requester" - path: /meetings/settings/searches - http_method: POST - request_parameters: - created_at[gt]: "{{ config['start_date'] }}" - updated_at[gt]: >- - {{ - format_datetime( - (config['start_date'] if stream_state['updated_at'] is not defined else - (stream_state.updated_at if stream_state.updated_at < now_utc() else now_utc())), - '%Y-%m-%dT%H:%M:%S.%fZ' - ) - }} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestOption - inject_into: request_parameter - field_name: page - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: "{{ response['metadata']['paging']['next_page'] }}" - stop_condition: >- - {{ response['metadata']['paging'] is not defined or not - response['metadata']['paging'] or - response['metadata']['paging']['next_page'] is not defined or not - response['metadata']['paging']['next_page'] }} - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - schema_loader: - type: InlineSchemaLoader - schema: - $ref: "#/schemas/searches" - base_requester: - type: HttpRequester - url_base: https://api.salesloft.com/v2 - authenticator: - $ref: "#/definitions/selective_authenticator" - -streams: - - $ref: "#/definitions/streams/users" - - $ref: "#/definitions/streams/account_tiers" - - $ref: "#/definitions/streams/import" - - $ref: "#/definitions/streams/person_stages" - - $ref: "#/definitions/streams/phone_number_assignments" - - $ref: "#/definitions/streams/steps" - - $ref: "#/definitions/streams/team_template_attachments" - - $ref: "#/definitions/streams/email_template_attachments" - - $ref: "#/definitions/streams/crm_users" - - $ref: "#/definitions/streams/groups" - - $ref: "#/definitions/streams/custom_fields" - - $ref: "#/definitions/streams/call_dispositions" - - $ref: "#/definitions/streams/call_sentiments" - - $ref: "#/definitions/streams/meetings" - - $ref: "#/definitions/streams/people" - - $ref: "#/definitions/streams/cadences" - - $ref: "#/definitions/streams/cadence_memberships" - - $ref: "#/definitions/streams/emails" - - $ref: "#/definitions/streams/calls" - - $ref: "#/definitions/streams/accounts" - - $ref: "#/definitions/streams/account_stages" - - $ref: "#/definitions/streams/actions" - - $ref: "#/definitions/streams/email_templates" - - $ref: "#/definitions/streams/notes" - - $ref: "#/definitions/streams/team_templates" - - $ref: "#/definitions/streams/crm_activities" - - $ref: "#/definitions/streams/successes" - - $ref: "#/definitions/streams/call_data_records" - - $ref: "#/definitions/streams/searches" - -spec: - type: Spec - connection_specification: - type: object - $schema: http://json-schema.org/draft-07/schema# - required: - - credentials - - start_date - properties: - credentials: - type: object - oneOf: - - type: object - title: Authenticate via OAuth - required: - - client_id - - client_secret - - refresh_token - - access_token - - token_expiry_date - - auth_type - properties: - auth_type: - type: string - const: oauth2.0 - client_id: - type: string - title: Client ID - description: The Client ID of your Salesloft developer application. - access_token: - type: string - description: Access Token for making authenticated requests. - airbyte_secret: true - client_secret: - type: string - title: Client Secret - description: The Client Secret of your Salesloft developer application. - airbyte_secret: true - refresh_token: - type: string - title: Refresh Token - description: The token for obtaining a new access token. - airbyte_secret: true - token_expiry_date: - type: string - format: date-time - description: The date-time when the access token should be refreshed. - - type: object - title: Authenticate via API Key - required: - - api_key - - auth_type - properties: - api_key: - type: string - title: API Key - description: >- - API Key for making authenticated requests. More instruction on - how to find this value in our docs - airbyte_secret: true - auth_type: - type: string - const: api_key - order: 0 - title: Credentials - start_date: - type: string - title: Start Date - format: date-time - pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ - order: 1 - examples: - - "2020-11-16T00:00:00Z" - description: >- - The date from which you'd like to replicate data for Salesloft API, in - the format YYYY-MM-DDT00:00:00Z. All data generated after this date - will be replicated. - additionalProperties: true - -metadata: - autoImportSchema: - users: false - account_tiers: false - import: false - person_stages: false - phone_number_assignments: false - steps: false - team_template_attachments: false - email_template_attachments: false - crm_users: false - groups: false - custom_fields: false - call_dispositions: false - call_sentiments: false - meetings: false - people: false - cadences: false - cadence_memberships: false - emails: false - calls: false - accounts: false - account_stages: false - actions: false - email_templates: false - notes: false - team_templates: false - crm_activities: false - successes: false - call_data_records: false - searches: false - -schemas: - users: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - guid: - type: - - "null" - - string - created_at: - type: string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - name: - type: - - "null" - - string - first_name: - type: - - "null" - - string - last_name: - type: - - "null" - - string - job_role: - type: - - "null" - - string - active: - type: - - "null" - - boolean - time_zone: - type: - - "null" - - string - slack_username: - type: - - "null" - - string - twitter_handle: - type: - - "null" - - string - email: - type: - - "null" - - string - email_client_email_address: - type: - - "null" - - string - sending_email_address: - type: - - "null" - - string - from_address: - type: - - "null" - - string - full_email_address: - type: - - "null" - - string - bcc_email_address: - type: - - "null" - - string - email_signature: - type: - - "null" - - string - email_signature_type: - type: - - "null" - - string - email_signature_click_tracking_disabled: - type: - - "null" - - boolean - team_admin: - type: - - "null" - - boolean - local_dial_enabled: - type: - - "null" - - boolean - click_to_call_enabled: - type: - - "null" - - boolean - email_client_configured: - type: - - "null" - - boolean - crm_connected: - type: - - "null" - - boolean - external_feature_flags: - type: - - "null" - - object - additionalProperties: true - properties: {} - phone_client: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - phone_number_assignment: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - group: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - team: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - role: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - - string - account_tiers: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - name: - type: - - "null" - - string - order: - type: - - "null" - - integer - created_at: - type: string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - import: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - created_at: - type: string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - name: - type: - - "null" - - string - current_people_count: - type: - - "null" - - integer - imported_people_count: - type: - - "null" - - integer - person_stages: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - name: - type: - - "null" - - string - created_at: - type: string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - order: - type: - - "null" - - integer - phone_number_assignments: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - number: - type: - - "null" - - string - user: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - steps: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - created_at: - type: - - "null" - - string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - disabled: - type: - - "null" - - boolean - type: - type: - - "null" - - string - name: - type: - - "null" - - string - display_name: - type: - - "null" - - string - day: - type: - - "null" - - integer - step_number: - type: - - "null" - - integer - details: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - cadence: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - team_template_attachments: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - attachment_id: - type: - - "null" - - integer - team_template: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - string - _href: - type: - - "null" - - string - name: - type: - - "null" - - string - download_url: - type: - - "null" - - string - attachment_file_size: - type: - - "null" - - integer - email_template_attachments: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - attachment_id: - type: - - "null" - - integer - team_template: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - name: - type: - - "null" - - string - download_url: - type: - - "null" - - string - attachment_file_size: - type: - - "null" - - integer - crm_users: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - crm_id: - type: - - "null" - - string - created_at: - type: string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - user: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - groups: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - name: - type: - - "null" - - string - parent_id: - type: - - "null" - - integer - custom_fields: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - name: - type: - - "null" - - string - field_type: - type: - - "null" - - string - value_type: - type: - - "null" - - string - created_at: - type: - - "null" - - string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - call_dispositions: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - created_at: - type: - - "null" - - string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - name: - type: - - "null" - - string - call_sentiments: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - created_at: - type: - - "null" - - string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - name: - type: - - "null" - - string - meetings: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - title: - type: - - "null" - - string - start_time: - type: - - "null" - - string - format: date-time - end_time: - type: - - "null" - - string - format: date-time - calendar_id: - type: - - "null" - - string - calendar_type: - type: - - "null" - - string - meeting_type: - type: - - "null" - - string - recipient_name: - type: - - "null" - - string - recipient_email: - type: - - "null" - - string - location: - type: - - "null" - - string - description: - type: - - "null" - - string - event_id: - type: - - "null" - - string - account_id: - type: - - "null" - - string - task_id: - type: - - "null" - - integer - created_at: - type: - - "null" - - string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - guests: - type: - - "null" - - array - items: - type: - - "null" - - string - attendees: - type: - - "null" - - array - items: - type: - - "null" - - object - additionalProperties: true - properties: - email: - type: - - "null" - - string - name: - type: - - "null" - - string - organizer: - type: - - "null" - - boolean - status: - type: - - "null" - - string - status_changed: - type: - - "null" - - boolean - deleted_at: - type: - - "null" - - string - format: date-time - person: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - cadence: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - step: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - booked_by_user: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - string - _href: - type: - - "null" - - string - crm_references: - type: - - "null" - - object - additionalProperties: true - event_source: - type: - - "null" - - string - canceled_at: - type: - - "null" - - string - format: date-time - all_day: - type: - - "null" - - boolean - no_show: - type: - - "null" - - boolean - crm_custom_fields: - type: - - "null" - - object - additionalProperties: true - strict_attribution: - type: - - "null" - - boolean - i_cal_uid: - type: - - "null" - - string - status: - type: - - "null" - - string - reschedule_status: - type: - - "null" - - string - owned_by_meetings_settings: - type: - - "null" - - object - additionalProperties: true - properties: - id: - email_address: - - "null" - - string - booked_by_meetings_settings: - type: - - "null" - - object - additionalProperties: true - properties: - id: - email_address: - - "null" - - string - people: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - last_contacted_at: - type: - - "null" - - string - format: date-time - last_replied_at: - type: - - "null" - - string - format: date-time - first_name: - type: - - "null" - - string - last_name: - type: - - "null" - - string - display_name: - type: - - "null" - - string - email_address: - type: - - "null" - - string - full_email_address: - type: - - "null" - - string - secondary_email_address: - type: - - "null" - - string - personal_email_address: - type: - - "null" - - string - phone: - type: - - "null" - - string - phone_extension: - type: - - "null" - - string - home_phone: - type: - - "null" - - string - mobile_phone: - type: - - "null" - - string - linkedin_url: - type: - - "null" - - string - title: - type: - - "null" - - string - city: - type: - - "null" - - string - state: - type: - - "null" - - string - country: - type: - - "null" - - string - work_city: - type: - - "null" - - string - work_state: - type: - - "null" - - string - work_country: - type: - - "null" - - string - crm_url: - type: - - "null" - - string - crm_id: - type: - - "null" - - string - crm_object_type: - type: - - "null" - - string - owner_crm_id: - type: - - "null" - - string - person_company_name: - type: - - "null" - - string - person_company_website: - type: - - "null" - - string - person_company_industry: - type: - - "null" - - string - do_not_contact: - type: - - "null" - - boolean - bouncing: - type: - - "null" - - boolean - locale: - type: - - "null" - - string - personal_website: - type: - - "null" - - string - twitter_handle: - type: - - "null" - - string - last_contacted_type: - type: - - "null" - - string - job_seniority: - type: - - "null" - - string - custom_fields: - type: - - "null" - - object - additionalProperties: true - properties: {} - tags: - type: - - "null" - - array - items: - type: - - "null" - - string - contact_restrictions: - type: - - "null" - - array - items: - type: - - "null" - - string - counts: - type: - - "null" - - object - additionalProperties: true - properties: - emails_sent: - type: - - "null" - - integer - emails_viewed: - type: - - "null" - - integer - emails_clicked: - type: - - "null" - - integer - emails_replied_to: - type: - - "null" - - integer - emails_bounced: - type: - - "null" - - integer - calls: - type: - - "null" - - integer - account: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - owner: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - last_contacted_by: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - import: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - person_stage: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - most_recent_cadence: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - last_completed_step_cadence: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - last_completed_step: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - cadences: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - archived_at: - type: - - "null" - - string - format: date-time - team_cadence: - type: - - "null" - - boolean - shared: - type: - - "null" - - boolean - remove_bounces_enabled: - type: - - "null" - - boolean - remove_replies_enabled: - type: - - "null" - - boolean - opt_out_link_included: - type: - - "null" - - boolean - name: - type: - - "null" - - string - tags: - type: - - "null" - - array - items: - type: - - "null" - - string - creator: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - owner: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - bounced_stage: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - replied_stage: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - added_stage: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - finished_stage: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - counts: - type: - - "null" - - object - additionalProperties: true - properties: - cadence_people: - type: - - "null" - - integer - target_daily_people: - type: - - "null" - - integer - latest_active_date: - type: - - "null" - - string - format: date - cadence_memberships: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - added_at: - type: - - "null" - - string - format: date-time - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - person_deleted: - type: - - "null" - - boolean - currently_on_cadence: - type: - - "null" - - boolean - current_state: - type: - - "null" - - string - cadence: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - person: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - user: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - latest_action: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - counts: - type: - - "null" - - object - additionalProperties: true - properties: - views: - type: - - "null" - - integer - clicks: - type: - - "null" - - integer - replies: - type: - - "null" - - integer - calls: - type: - - "null" - - integer - sent_emails: - type: - - "null" - - integer - bounces: - type: - - "null" - - integer - emails: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - recipient_email_address: - type: - - "null" - - string - status: - type: - - "null" - - string - bounced: - type: - - "null" - - boolean - send_after: - type: - - "null" - - string - format: date-time - sent_at: - type: - - "null" - - string - format: date-time - view_tracking: - type: - - "null" - - boolean - click_tracking: - type: - - "null" - - boolean - personalization: - type: - - "null" - - string - counts: - type: - - "null" - - object - additionalProperties: true - properties: - clicks: - type: - - "null" - - integer - views: - type: - - "null" - - integer - replies: - type: - - "null" - - integer - unique_devices: - type: - - "null" - - integer - unique_locations: - type: - - "null" - - integer - attachments: - type: - - "null" - - integer - headers: - type: - - "null" - - object - additionalProperties: true - properties: - In-Reply-To: - type: - - "null" - - string - References: - type: - - "null" - - string - to: - type: - - "null" - - string - cc: - type: - - "null" - - string - in_reply_to: - type: - - "null" - - string - bcc: - type: - - "null" - - string - user: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - recipient: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - mailing: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - action: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - crm_activity: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - cadence: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - step: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - email_template: - type: - - "null" - - object - additionalProperties: true - properties: - _href: - type: - - "null" - - string - id: - type: - - "null" - - integer - calls: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - to: - type: - - "null" - - string - duration: - type: - - "null" - - integer - sentiment: - type: - - "null" - - string - disposition: - type: - - "null" - - string - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - user: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - action: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - called_person: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - crm_activity: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - note: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - cadence: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - step: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - accounts: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - archived_at: - type: - - "null" - - string - format: date-time - name: - type: - - "null" - - string - domain: - type: - - "null" - - string - conversational_name: - type: - - "null" - - string - description: - type: - - "null" - - string - phone: - type: - - "null" - - string - website: - type: - - "null" - - string - linkedin_url: - type: - - "null" - - string - twitter_handle: - type: - - "null" - - string - street: - type: - - "null" - - string - city: - type: - - "null" - - string - state: - type: - - "null" - - string - postal_code: - type: - - "null" - - string - country: - type: - - "null" - - string - locale: - type: - - "null" - - string - industry: - type: - - "null" - - string - company_type: - type: - - "null" - - string - founded: - type: - - "null" - - string - revenue_range: - type: - - "null" - - string - size: - type: - - "null" - - string - crm_id: - type: - - "null" - - string - crm_url: - type: - - "null" - - string - crm_object_type: - type: - - "null" - - string - owner_crm_id: - type: - - "null" - - string - last_contacted_at: - type: - - "null" - - string - format: date-time - last_contacted_type: - type: - - "null" - - string - do_not_contact: - type: - - "null" - - boolean - counts: - type: - - "null" - - object - additionalProperties: true - properties: - people: - type: - - "null" - - integer - owner: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - creator: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - last_contacted_by: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - last_contacted_person: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - company_stage: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - account_tier: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - tags: - type: - - "null" - - array - items: - type: - - "null" - - string - account_stages: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - name: - type: - - "null" - - string - created_at: - type: - - "null" - - string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - order: - type: - - "null" - - integer - actions: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - due: - type: - - "null" - - boolean - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - type: - type: - - "null" - - string - status: - type: - - "null" - - string - due_on: - type: - - "null" - - string - format: date-time - multitouch_group_id: - type: - - "null" - - integer - action_details: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - user: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - person: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - cadence: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - step: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - email_templates: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - title: - type: - - "null" - - string - subject: - type: - - "null" - - string - body: - type: - - "null" - - string - body_preview: - type: - - "null" - - string - created_at: - type: string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - last_used_at: - type: - - "null" - - string - format: date-time - archived_at: - type: - - "null" - - string - format: date-time - shared: - type: - - "null" - - boolean - open_tracking_enabled: - type: - - "null" - - boolean - click_tracking_enabled: - type: - - "null" - - boolean - cadence_template: - type: - - "null" - - boolean - counts: - type: - - "null" - - object - additionalProperties: true - properties: - sent_emails: - type: - - "null" - - integer - views: - type: - - "null" - - integer - clicks: - type: - - "null" - - integer - replies: - type: - - "null" - - integer - bounces: - type: - - "null" - - integer - template_owner: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - team_template: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - string - _href: - type: - - "null" - - string - _links: - type: - - "null" - - object - additionalProperties: true - properties: - attachments: - type: - - "null" - - string - groups: - type: - - "null" - - array - items: - type: object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - tags: - type: - - "null" - - array - items: - type: - - "null" - - string - notes: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - content: - type: - - "null" - - string - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - user: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - associated_with: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - call: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - team_templates: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: string - title: - type: - - "null" - - string - subject: - type: - - "null" - - string - body: - type: - - "null" - - string - body_preview: - type: - - "null" - - string - created_at: - type: - - "null" - - string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - last_used_at: - type: - - "null" - - string - format: date-time - archived_at: - type: - - "null" - - string - format: date-time - last_modified_at: - type: - - "null" - - string - format: date-time - open_tracking_enabled: - type: - - "null" - - boolean - click_tracking_enabled: - type: - - "null" - - boolean - counts: - type: - - "null" - - object - additionalProperties: true - properties: - sent_emails: - type: - - "null" - - integer - views: - type: - - "null" - - integer - clicks: - type: - - "null" - - integer - replies: - type: - - "null" - - integer - bounces: - type: - - "null" - - integer - last_modified_user: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - _links: - type: - - "null" - - object - additionalProperties: true - properties: - attachments: - type: - - "null" - - string - tags: - type: - - "null" - - array - items: - type: - - "null" - - string - crm_activities: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - subject: - type: - - "null" - - string - description: - type: - - "null" - - string - crm_id: - type: - - "null" - - string - activity_type: - type: - - "null" - - string - error: - type: - - "null" - - string - custom_crm_fields: - type: - - "null" - - object - person: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - user: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - successes: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: integer - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - succeeded_at: - type: - - "null" - - string - format: date-time - success_window_started_at: - type: - - "null" - - string - format: date-time - user: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - person: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - latest_email: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - latest_call: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - latest_action: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - latest_cadence: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - latest_step: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - counts: - type: - - "null" - - object - additionalProperties: true - properties: - total_emails: - type: - - "null" - - integer - total_calls: - type: - - "null" - - integer - total_other_touches: - type: - - "null" - - integer - call_data_records: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - created_at: - type: - - "null" - - string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - to: - type: - - "null" - - string - from: - type: - - "null" - - string - duration: - type: - - "null" - - integer - direction: - type: - - "null" - - string - status: - type: - - "null" - - string - call_type: - type: - - "null" - - string - call_uuid: - type: - - "null" - - string - recording: - type: - - "null" - - object - additionalProperties: true - properties: - url: - type: - - "null" - - string - status: - type: - - "null" - - string - recording_status: - type: - - "null" - - string - call: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - user: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - called_person: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - _href: - type: - - "null" - - string - searches: - "$schema": http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - type: - - "null" - - integer - user: - type: - - "null" - - object - additionalProperties: true - properties: - id: - type: - - "null" - - string - _href: - type: - - "null" - - string - user_slug: - type: - - "null" - - string - primary_calendar_id: - type: - - "null" - - string - primary_calendar_name: - type: - - "null" - - string - email_address: - type: - - "null" - - string - user_details: - type: - - "null" - - object - additionalProperties: true - calendar_type: - type: - - "null" - - string - title: - type: - - "null" - - string - description: - type: - - "null" - - string - location: - type: - - "null" - - string - default_meeting_length: - type: - - "null" - - integer - availability_limit_enabled: - type: - - "null" - - boolean - availability_limit: - type: - - "null" - - integer - schedule_delay: - type: - - "null" - - integer - buffer_time_duration: - type: - - "null" - - integer - schedule_buffer_enabled: - type: - - "null" - - boolean - times_available: - type: - - "null" - - object - additionalProperties: true - allow_booking_on_behalf: - type: - - "null" - - boolean - allow_booking_overtime: - type: - - "null" - - boolean - allow_event_overlap: - type: - - "null" - - boolean - allow_event_detail: - type: - - "null" - - boolean - enable_dynamic_location: - type: - - "null" - - boolean - created_at: - type: - - "null" - - string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time - time_zone: - type: - - "null" - - string - primary_calendar_connection_failed: - type: - - "null" - - boolean - enable_calendar_sync: - type: - - "null" - - boolean - reschedule_meetings_enabled: - type: - - "null" - - boolean - active_meeting_url: - type: - - "null" - - object - additionalProperties: true - properties: - url: - type: - - "null" - - string - created_at: - type: - - "null" - - string - format: date-time - updated_at: - type: - - "null" - - string - format: date-time diff --git a/airbyte-integrations/connectors/source-salesloft/source_salesloft/run.py b/airbyte-integrations/connectors/source-salesloft/source_salesloft/run.py deleted file mode 100644 index aa9f841fa8df..000000000000 --- a/airbyte-integrations/connectors/source-salesloft/source_salesloft/run.py +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - - -import sys - -from airbyte_cdk.entrypoint import launch - -from .source import SourceSalesloft - - -def run(): - source = SourceSalesloft() - launch(source, sys.argv[1:]) diff --git a/airbyte-integrations/connectors/source-salesloft/source_salesloft/source.py b/airbyte-integrations/connectors/source-salesloft/source_salesloft/source.py deleted file mode 100644 index ed97803a6c6c..000000000000 --- a/airbyte-integrations/connectors/source-salesloft/source_salesloft/source.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource - -""" -This file provides the necessary constructs to interpret a provided declarative YAML configuration file into -source connector. - -WARNING: Do not modify this file. -""" - - -# Declarative Source -class SourceSalesloft(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-salesloft/unit_tests/conftest.py b/airbyte-integrations/connectors/source-salesloft/unit_tests/conftest.py deleted file mode 100644 index 5f7390d53f95..000000000000 --- a/airbyte-integrations/connectors/source-salesloft/unit_tests/conftest.py +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from pytest import fixture - - -@fixture -def config(): - return { - "credentials": { - "auth_type": "oauth2.0", - "client_id": "client_id", - "client_secret": "client_secret", - "refresh_token": "refresh_token", - "access_token": "access_token", - "token_expiry_date": "2222-02-02T00:00:00Z", - }, - "start_date": "2020-01-01T00:00:00.000Z", - } diff --git a/airbyte-integrations/connectors/source-salesloft/unit_tests/test_source.py b/airbyte-integrations/connectors/source-salesloft/unit_tests/test_source.py deleted file mode 100644 index 1f5966263483..000000000000 --- a/airbyte-integrations/connectors/source-salesloft/unit_tests/test_source.py +++ /dev/null @@ -1,29 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -import logging - -import pytest -from source_salesloft.source import SourceSalesloft - - -def mock_response(): - return {"data": [{"id": "mock1"}, {"id": "mock2"}]} - - -def test_streams(config): - source = SourceSalesloft() - streams = source.streams(config) - expected_streams_number = 29 - assert len(streams) == expected_streams_number - - -@pytest.mark.parametrize("status_code, check_successful", ((403, False), (200, True))) -def test_check_connection(requests_mock, config, status_code, check_successful): - requests_mock.post("https://accounts.salesloft.com/oauth/token", json={"access_token": "token", "expires_in": 7200}) - requests_mock.get("https://api.salesloft.com/v2/users", status_code=status_code, json=mock_response()) - source = SourceSalesloft() - ok, error = source.check_connection(logging.getLogger(), config) - assert ok is check_successful - assert bool(error) is not check_successful diff --git a/airbyte-integrations/connectors/source-salesloft/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-salesloft/unit_tests/test_streams.py deleted file mode 100644 index 29effbdbc95d..000000000000 --- a/airbyte-integrations/connectors/source-salesloft/unit_tests/test_streams.py +++ /dev/null @@ -1,88 +0,0 @@ -# -# Copyright (c) 2024 Airbyte, Inc., all rights reserved. -# - -from typing import Any, Mapping - -import pytest -from airbyte_cdk.sources.streams import Stream -from airbyte_protocol.models import SyncMode -from jsonref import requests -from source_salesloft.source import SourceSalesloft - - -def mock_response(): - return {"data": [{"id": "mock1"}, {"id": "mock2"}]} - - -def get_stream_by_name(stream_name: str, config: Mapping[str, Any]) -> Stream: - source = SourceSalesloft() - matches_by_name = [stream_config for stream_config in source.streams(config) if stream_config.name == stream_name] - if not matches_by_name: - raise ValueError("Please provide a valid stream name.") - return matches_by_name[0] - - -def test_request_params(config): - stream = get_stream_by_name("users", config) - inputs = {"stream_slice": None, "stream_state": None, "next_page_token": None} - expected_params = {} - assert stream.retriever.requester.get_request_params(**inputs) == expected_params - - -def test_incremental_request_params(config): - stream = get_stream_by_name("accounts", config) - inputs = {"stream_slice": None, "stream_state": None, "next_page_token": None} - expected_params = { - "created_at[gt]": "2020-01-01T00:00:00.000Z", - "updated_at[gt]": "2020-01-01T00:00:00.000000Z", - } - assert stream.retriever.requester.get_request_params(**inputs) == expected_params - - -def test_next_page_token(requests_mock, config): - stream = get_stream_by_name("users", config) - response = {"metadata": {"paging": {"next_page": 2}}} - requests_mock.post("https://accounts.salesloft.com/oauth/token", json={"access_token": "token", "expires_in": 7200}) - requests_mock.get("https://api.salesloft.com/v2/users", status_code=200, json=response) - inputs = {"response": requests.get("https://api.salesloft.com/v2/users")} - expected_token = {"next_page_token": 2} - assert stream.retriever._next_page_token(**inputs) == expected_token - - -def test_next_page_token_invalid(requests_mock, config): - stream = get_stream_by_name("users", config) - response = {"metadata": {"paginfffg": {"next_pagaae": 2}}} - requests_mock.post("https://accounts.salesloft.com/oauth/token", json={"access_token": "token", "expires_in": 7200}) - requests_mock.get("https://api.salesloft.com/v2/users", status_code=200, json=response) - inputs = {"response": requests.get("https://api.salesloft.com/v2/users")} - with pytest.raises(AttributeError) as ex: - stream.retriever._next_page_token(**inputs).get("next_page_token") - assert isinstance(ex.value, AttributeError) - - -def test_get_updated_state(config): - stream = get_stream_by_name("accounts", config) - inputs = {"current_stream_state": {}, "latest_record": {}} - expected_state = {} - assert stream.get_updated_state(**inputs) == expected_state - - -@pytest.mark.parametrize( - "return_value, expected_records", (({"metadata": {}}, []), ({"data": [{"id": 1}, {"id": 2}], "metadata": {}}, [{"id": 1}, {"id": 2}])) -) -def test_parse_response(requests_mock, config, return_value, expected_records): - stream = get_stream_by_name("users", config) - requests_mock.post("https://accounts.salesloft.com/oauth/token", json={"access_token": "token", "expires_in": 7200}) - requests_mock.get("https://api.salesloft.com/v2/users", status_code=200, json=return_value) - records = [] - for stream_slice in stream.stream_slices(sync_mode=SyncMode.full_refresh): - records.extend(list(stream.read_records(sync_mode=SyncMode.full_refresh, stream_slice=stream_slice))) - assert len(records) == len(expected_records) - for i in range(len(records)): - assert records[i].keys() == expected_records[i].keys() - - -def test_stream_has_path(config): - for stream in SourceSalesloft().streams(config): - assert stream.retriever.requester.path diff --git a/airbyte-integrations/connectors/source-sap-fieldglass/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-sap-fieldglass/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-sap-fieldglass/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-sap-fieldglass/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-sap-fieldglass/metadata.yaml b/airbyte-integrations/connectors/source-sap-fieldglass/metadata.yaml index 240088f977db..5c82a93d82c9 100644 --- a/airbyte-integrations/connectors/source-sap-fieldglass/metadata.yaml +++ b/airbyte-integrations/connectors/source-sap-fieldglass/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: ec5f3102-fb31-4916-99ae-864faf8e7e25 - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-sap-fieldglass githubIssueLabel: source-sap-fieldglass icon: sapfieldglass.svg @@ -39,5 +39,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-savvycal/metadata.yaml b/airbyte-integrations/connectors/source-savvycal/metadata.yaml index dd1140887566..0051c8432afb 100644 --- a/airbyte-integrations/connectors/source-savvycal/metadata.yaml +++ b/airbyte-integrations/connectors/source-savvycal/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-savvycal connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: a554ed06-74e2-4c60-9510-d63f7dc463b6 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-savvycal githubIssueLabel: source-savvycal icon: icon.svg diff --git a/airbyte-integrations/connectors/source-scaffold-java-jdbc/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-scaffold-java-jdbc/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-scaffold-java-jdbc/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-scaffold-java-jdbc/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-scryfall/metadata.yaml b/airbyte-integrations/connectors/source-scryfall/metadata.yaml index 5f371b638300..6fb1fbf10c15 100644 --- a/airbyte-integrations/connectors/source-scryfall/metadata.yaml +++ b/airbyte-integrations/connectors/source-scryfall/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-scryfall connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: f76b7649-322b-44a0-8cef-23aeaae89c42 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-scryfall githubIssueLabel: source-scryfall icon: icon.svg diff --git a/airbyte-integrations/connectors/source-secoda/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-secoda/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-secoda/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-secoda/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-secoda/metadata.yaml b/airbyte-integrations/connectors/source-secoda/metadata.yaml index d0e65a917578..2ecd4fa3740c 100644 --- a/airbyte-integrations/connectors/source-secoda/metadata.yaml +++ b/airbyte-integrations/connectors/source-secoda/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: da9fc6b9-8059-4be0-b204-f56e22e4d52d - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.10 dockerRepository: airbyte/source-secoda githubIssueLabel: source-secoda icon: secoda.svg @@ -42,5 +42,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-segment/metadata.yaml b/airbyte-integrations/connectors/source-segment/metadata.yaml index 6694baaa4bca..a0192dd2f096 100644 --- a/airbyte-integrations/connectors/source-segment/metadata.yaml +++ b/airbyte-integrations/connectors/source-segment/metadata.yaml @@ -14,11 +14,11 @@ data: enabled: false packageName: airbyte-source-segment connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: b17132d0-4108-4a76-ae5e-639c15beae47 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-segment githubIssueLabel: source-segment icon: icon.svg diff --git a/airbyte-integrations/connectors/source-sendgrid/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-sendgrid/integration_tests/acceptance.py index 43ce950d77ca..72132012aaed 100644 --- a/airbyte-integrations/connectors/source-sendgrid/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-sendgrid/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-sendinblue/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-sendinblue/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-sendinblue/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-sendinblue/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-sendowl/README.md b/airbyte-integrations/connectors/source-sendowl/README.md new file mode 100644 index 000000000000..2d3b79b11292 --- /dev/null +++ b/airbyte-integrations/connectors/source-sendowl/README.md @@ -0,0 +1,35 @@ +# Sendowl +This directory contains the manifest-only connector for `source-sendowl`. + +Sendowl is an All-in-One Digital Commerce Platform. +Using this connector we can extract data from products , packages , orders , discounts and subscriptions streams. +Docs : https://dashboard.sendowl.com/developers/api/introduction + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-sendowl:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-sendowl build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-sendowl test +``` + diff --git a/airbyte-integrations/connectors/source-sendowl/acceptance-test-config.yml b/airbyte-integrations/connectors/source-sendowl/acceptance-test-config.yml new file mode 100644 index 000000000000..864ddf3f04e6 --- /dev/null +++ b/airbyte-integrations/connectors/source-sendowl/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-sendowl:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-sendowl/icon.svg b/airbyte-integrations/connectors/source-sendowl/icon.svg new file mode 100644 index 000000000000..d870c70f07c7 --- /dev/null +++ b/airbyte-integrations/connectors/source-sendowl/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-sendowl/manifest.yaml b/airbyte-integrations/connectors/source-sendowl/manifest.yaml new file mode 100644 index 000000000000..4d7c80d2dfc9 --- /dev/null +++ b/airbyte-integrations/connectors/source-sendowl/manifest.yaml @@ -0,0 +1,721 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Sendowl is an All-in-One Digital Commerce Platform. + + Using this connector we can extract data from products , packages , orders , + discounts and subscriptions streams. + + Docs : https://dashboard.sendowl.com/developers/api/introduction + +check: + type: CheckStream + stream_names: + - products + +definitions: + streams: + products: + type: DeclarativeStream + name: products + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: products + http_method: GET + request_headers: + Accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - product + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + packages: + type: DeclarativeStream + name: packages + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: packages + http_method: GET + request_headers: + Accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - package + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/packages" + orders: + type: DeclarativeStream + name: orders + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: orders + http_method: GET + request_headers: + Accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - order + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: created_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: from + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: to + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/orders" + subscriptions: + type: DeclarativeStream + name: subscriptions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: subscriptions + http_method: GET + request_headers: + Accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - subscription + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/subscriptions" + base_requester: + type: HttpRequester + url_base: https://www.sendowl.com/api/v1/ + authenticator: + type: BasicHttpAuthenticator + password: "{{ config[\"password\"] }}" + username: "{{ config[\"username\"] }}" + +streams: + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/packages" + - $ref: "#/definitions/streams/orders" + - $ref: "#/definitions/streams/subscriptions" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - username + - start_date + properties: + username: + type: string + description: Enter you API Key + order: 0 + title: Username + password: + type: string + description: Enter your API secret + order: 1 + title: Password + always_show: true + airbyte_secret: true + start_date: + type: string + order: 2 + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + additionalProperties: true + +metadata: + autoImportSchema: + products: true + packages: true + orders: true + subscriptions: true + testedStreams: + products: + streamHash: 63213ed0bc54ab096345046384928c62a54a2fae + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + packages: + streamHash: 1cdb9d767bf538ee55a02c16560436c0d0e98d4c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + orders: + streamHash: 7e961e529e6132f752ef43f7e41942ea8ca634ea + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + subscriptions: + streamHash: 30bb1f21d6fabde3a2008adad9c55d3253a05045 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + add_to_cart_url: + type: + - string + - "null" + affiliate_sellable: + type: + - boolean + - "null" + attachment: + type: + - object + - "null" + properties: + filename: + type: + - string + - "null" + size: + type: + - number + - "null" + category: + type: + - string + - "null" + created_at: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + id: + type: number + instant_buy_url: + type: + - string + - "null" + limit_to_single_qty_in_cart: + type: + - boolean + - "null" + name: + type: + - string + - "null" + pdf_stamping: + type: + - boolean + - "null" + price: + type: + - string + - "null" + price_is_minimum: + type: + - boolean + - "null" + product_image_url: + type: + - string + - "null" + product_type: + type: + - string + - "null" + sales_limit: + type: + - number + - "null" + sales_page_url: + type: + - string + - "null" + self_hosted_url: + type: + - string + - "null" + subcategory: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + packages: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + add_to_cart_url: + type: + - string + - "null" + affiliate_sellable: + type: + - boolean + - "null" + category: + type: + - string + - "null" + components: + type: + - object + - "null" + properties: + product_ids: + type: + - array + - "null" + items: + type: + - number + - "null" + created_at: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + id: + type: number + instant_buy_url: + type: + - string + - "null" + limit_to_single_qty_in_cart: + type: + - boolean + - "null" + name: + type: + - string + - "null" + price: + type: + - string + - "null" + price_is_minimum: + type: + - boolean + - "null" + sales_page_url: + type: + - string + - "null" + subcategory: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id + orders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + access_allowed: + type: + - boolean + - "null" + buyer_email: + type: + - string + - "null" + buyer_name: + type: + - string + - "null" + can_market_to_buyer: + type: + - boolean + - "null" + cart: + type: + - object + - "null" + properties: + cart_items: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + cart_item: + type: + - object + - "null" + properties: + download_attempts: + type: + - number + - "null" + price_at_checkout: + type: + - string + - "null" + product_id: + type: + - number + - "null" + quantity: + type: + - number + - "null" + completed_checkout_at: + type: + - string + - "null" + started_checkout_at: + type: + - string + - "null" + state: + type: + - string + - "null" + created_at: + type: string + download_items: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + download_item: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + accessible: + type: + - boolean + - "null" + downloadable: + type: + - boolean + - "null" + name: + type: + - string + - "null" + url: + type: + - string + - "null" + download_url: + type: + - string + - "null" + gateway: + type: + - string + - "null" + gateway_transaction_ids: + type: + - array + - "null" + items: + type: + - string + - "null" + id: + type: number + order_custom_checkout_fields: + type: + - array + - "null" + price_at_checkout: + type: + - string + - "null" + settled_currency: + type: + - string + - "null" + settled_gateway_fee: + type: + - string + - "null" + settled_gross: + type: + - string + - "null" + state: + type: + - string + - "null" + subscription_id: + type: + - number + - "null" + updated_at: + type: + - string + - "null" + required: + - id + - created_at + subscriptions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + access_all_products: + type: + - boolean + - "null" + access_subset_products: + type: + - boolean + - "null" + affiliate_sellable: + type: + - boolean + - "null" + category: + type: + - string + - "null" + commission_rate: + type: + - number + - "null" + components: + type: + - object + - "null" + properties: + product_ids: + type: + - array + - "null" + items: + type: + - number + - "null" + created_at: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + custom_field: + type: + - string + - "null" + drip_items: + type: + - array + - "null" + frequency: + type: + - string + - "null" + frequency_interval: + type: + - string + - "null" + frequency_value: + type: + - number + - "null" + id: + type: number + instant_buy_url: + type: + - string + - "null" + name: + type: + - string + - "null" + perform_redirect: + type: + - boolean + - "null" + product_image_url: + type: + - string + - "null" + recurring_price: + type: + - string + - "null" + recurring_type: + type: + - string + - "null" + sales_page_url: + type: + - string + - "null" + sell_service: + type: + - boolean + - "null" + sell_tangible_product: + type: + - boolean + - "null" + subcategory: + type: + - string + - "null" + trial_frequency: + type: + - string + - "null" + trial_no_of_occurrences: + type: + - number + - "null" + trial_price: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-sendowl/metadata.yaml b/airbyte-integrations/connectors/source-sendowl/metadata.yaml new file mode 100644 index 000000000000..d100c3da839f --- /dev/null +++ b/airbyte-integrations/connectors/source-sendowl/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "sendowl.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-sendowl + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 8333cbf3-03bd-4b90-a698-1b33c14d9e00 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-sendowl + githubIssueLabel: source-sendowl + icon: icon.svg + license: MIT + name: Sendowl + releaseDate: 2024-11-09 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/sendowl + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-sendpulse/README.md b/airbyte-integrations/connectors/source-sendpulse/README.md new file mode 100644 index 000000000000..23270dc780aa --- /dev/null +++ b/airbyte-integrations/connectors/source-sendpulse/README.md @@ -0,0 +1,33 @@ +# SendPulse +This directory contains the manifest-only connector for `source-sendpulse`. + +Airbyte connector for [SendPulse](https://sendpulse.com/) allows you to seamlessly sync data from SendPulse to your data warehouse. It retrieves essential information from various SendPulse streams, including mailing lists, campaigns, templates, senders, webhooks, balance details, and balance. This enables you to analyze and manage your SendPulse email marketing and communication efforts effectively in a centralized location. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-sendpulse:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-sendpulse build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-sendpulse test +``` + diff --git a/airbyte-integrations/connectors/source-sendpulse/acceptance-test-config.yml b/airbyte-integrations/connectors/source-sendpulse/acceptance-test-config.yml new file mode 100644 index 000000000000..f53e63b287c4 --- /dev/null +++ b/airbyte-integrations/connectors/source-sendpulse/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-sendpulse:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-sendpulse/icon.svg b/airbyte-integrations/connectors/source-sendpulse/icon.svg new file mode 100644 index 000000000000..f2585dd71825 --- /dev/null +++ b/airbyte-integrations/connectors/source-sendpulse/icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/airbyte-integrations/connectors/source-sendpulse/manifest.yaml b/airbyte-integrations/connectors/source-sendpulse/manifest.yaml new file mode 100644 index 000000000000..7acffd7858cb --- /dev/null +++ b/airbyte-integrations/connectors/source-sendpulse/manifest.yaml @@ -0,0 +1,740 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Airbyte connector for [SendPulse](https://sendpulse.com/) allows you to + seamlessly sync data from SendPulse to your data warehouse. It retrieves + essential information from various SendPulse streams, including mailing lists, + campaigns, templates, senders, webhooks, balance details, and balance. This + enables you to analyze and manage your SendPulse email marketing and + communication efforts effectively in a centralized location. + +check: + type: CheckStream + stream_names: + - mailing_lists + +definitions: + streams: + mailing_lists: + type: DeclarativeStream + name: mailing_lists + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /addressbooks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/mailing_lists" + campaigns: + type: DeclarativeStream + name: campaigns + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /campaigns + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/campaigns" + templates: + type: DeclarativeStream + name: templates + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /templates + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/templates" + senders: + type: DeclarativeStream + name: senders + primary_key: + - email + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /senders + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/senders" + webhooks: + type: DeclarativeStream + name: webhooks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/email-service/webhook + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/webhooks" + balance_details: + type: DeclarativeStream + name: balance_details + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /user/balance/detail + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/balance_details" + balance: + type: DeclarativeStream + name: balance + primary_key: + - currency + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /balance + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + transformations: + - type: AddFields + fields: + - path: + - datetime + value: "{{ now_utc() }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/balance" + base_requester: + type: HttpRequester + url_base: https://api.sendpulse.com + authenticator: + type: OAuthAuthenticator + client_id: "{{ config[\"client_id\"] }}" + grant_type: client_credentials + client_secret: "{{ config[\"client_secret\"] }}" + expires_in_name: expires_in + access_token_name: access_token + refresh_request_body: {} + token_refresh_endpoint: https://api.sendpulse.com/oauth/access_token + +streams: + - $ref: "#/definitions/streams/mailing_lists" + - $ref: "#/definitions/streams/campaigns" + - $ref: "#/definitions/streams/templates" + - $ref: "#/definitions/streams/senders" + - $ref: "#/definitions/streams/webhooks" + - $ref: "#/definitions/streams/balance_details" + - $ref: "#/definitions/streams/balance" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - client_id + - client_secret + properties: + client_id: + type: string + name: client_id + order: 0 + title: OAuth Client ID + airbyte_secret: true + client_secret: + type: string + name: client_secret + order: 1 + title: OAuth Client Secret + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + mailing_lists: true + campaigns: true + templates: true + senders: true + webhooks: true + balance_details: true + balance: true + testedStreams: + mailing_lists: + streamHash: 94deb8cdf6a5627bf44c8fe39cf3e0aa183184a3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + campaigns: + streamHash: 3ca300e8a792ec17b4154bca202122028bfbb672 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + templates: + streamHash: 248f143b8ac05c88695bfda1fbb78aa332dc78e1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + senders: + streamHash: 9fa00e085af9f89d6fa8fea75cd2f7c99b7c36ff + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + webhooks: + streamHash: 1bf46a2ea368a7057b227be76df1b0cf37411cfa + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + balance_details: + streamHash: c09fa8c41b04a121d5bb71a49da8ed1a0332de50 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + balance: + streamHash: ad1a47782c97f7dc55182808d5a147cfb4f87bf0 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://sendpulse.com/tr/integrations/api + +schemas: + mailing_lists: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active_email_qty: + type: + - number + - "null" + active_phones_quantity: + type: + - number + - "null" + all_email_qty: + type: + - number + - "null" + creationdate: + type: + - string + - "null" + exc_phones_quantity: + type: + - number + - "null" + id: + type: number + inactive_email_qty: + type: + - number + - "null" + name: + type: + - string + - "null" + new_phones_quantity: + type: + - number + - "null" + status: + type: + - number + - "null" + status_explain: + type: + - string + - "null" + required: + - id + campaigns: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + all_email_qty: + type: + - number + - "null" + company_price: + type: + - string + - "null" + id: + type: number + is_sms: + type: + - boolean + - "null" + is_viber: + type: + - boolean + - "null" + message: + type: + - object + - "null" + properties: + attachments: + type: + - string + - "null" + list_id: + type: + - number + - "null" + sender_email: + type: + - string + - "null" + sender_name: + type: + - string + - "null" + subject: + type: + - string + - "null" + name: + type: + - string + - "null" + overdraft_currency: + type: + - string + - "null" + overdraft_price: + type: + - number + - "null" + paid_email_qty: + type: + - number + - "null" + send_date: + type: + - string + - "null" + statistics: + type: + - object + - "null" + properties: + delivered: + type: + - number + - "null" + error: + type: + - number + - "null" + link_redirected: + type: + - number + - "null" + opening: + type: + - number + - "null" + sent: + type: + - number + - "null" + unsubscribe: + type: + - number + - "null" + status: + type: + - number + - "null" + tariff_email_qty: + type: + - number + - "null" + required: + - id + templates: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + category: + type: + - string + - "null" + category_info: + anyOf: + - type: array + - type: object + properties: + code: + type: string + full_description: + type: string + id: + type: number + meta_description: + type: string + name: + type: string + sort: + type: number + created: + type: + - string + - "null" + full_description: + type: + - string + - "null" + id: + type: string + is_structure: + type: + - boolean + - "null" + lang: + type: + - string + - "null" + name: + type: + - string + - "null" + name_slug: + type: + - string + - "null" + owner: + type: + - string + - "null" + preview: + type: + - string + - "null" + real_id: + type: + - number + - "null" + tags: + anyOf: + - type: array + - type: object + properties: + abandonedcart: + type: string + blackfriday: + type: string + blog: + type: string + businessman: + type: string + christmas: + type: string + courses: + type: string + digest: + type: string + discount: + type: string + ecommerce: + type: string + education: + type: string + exhibition: + type: string + feedback: + type: string + food: + type: string + halloween: + type: string + hotel: + type: string + invite: + type: string + leadmagnet: + type: string + marketing: + type: string + meat: + type: string + mothersday: + type: string + museum: + type: string + newyear: + type: string + offline-event: + type: string + offlineevent: + type: string + online-event: + type: string + onlineshop: + type: string + photo: + type: string + photographer: + type: string + pizzeria: + type: string + product: + type: string + promo: + type: string + realestate: + type: string + registrationfortheprocedure: + type: string + sale: + type: string + shoes: + type: string + smm: + type: string + study: + type: string + subscribing: + type: string + tourist: + type: string + travel: + type: string + triggeremail: + type: string + valentine: + type: string + valentinesday: + type: string + video: + type: string + webinar: + type: string + womensday: + type: string + required: + - id + senders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + email: + type: string + is_allowed_for_smtp: + type: + - boolean + - "null" + name: + type: + - string + - "null" + status: + type: + - string + - "null" + required: + - email + webhooks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + action: + type: + - string + - "null" + id: + type: number + url: + type: + - string + - "null" + user_id: + type: + - number + - "null" + required: + - id + balance_details: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + balance: + type: + - object + - "null" + properties: + bonus: + type: + - string + - "null" + currency: + type: + - string + - "null" + main: + type: + - string + - "null" + email: + type: + - object + - "null" + properties: + current_subscribers: + type: + - number + - "null" + finished_time: + type: + - string + - "null" + is_unique_type: + type: + - boolean + - "null" + maximum_subscribers: + type: + - number + - "null" + tariff_name: + type: + - string + - "null" + push: + type: + - object + - "null" + properties: + auto_renew: + type: + - number + - "null" + end_date: + type: + - string + - "null" + tariff_name: + type: + - string + - "null" + balance: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + balance_currency: + type: + - number + - "null" + currency: + type: string + datetime: + type: + - string + - "null" + required: + - currency diff --git a/airbyte-integrations/connectors/source-sendpulse/metadata.yaml b/airbyte-integrations/connectors/source-sendpulse/metadata.yaml new file mode 100644 index 000000000000..2543d59b68db --- /dev/null +++ b/airbyte-integrations/connectors/source-sendpulse/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.sendpulse.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-sendpulse + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: ae2d64c4-8282-4a44-9e0d-be29c42e558c + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-sendpulse + githubIssueLabel: source-sendpulse + icon: icon.svg + license: MIT + name: SendPulse + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/sendpulse + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-senseforce/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-senseforce/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-senseforce/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-senseforce/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-senseforce/metadata.yaml b/airbyte-integrations/connectors/source-senseforce/metadata.yaml index a918cfc8f411..d2d42253e3ab 100644 --- a/airbyte-integrations/connectors/source-senseforce/metadata.yaml +++ b/airbyte-integrations/connectors/source-senseforce/metadata.yaml @@ -6,7 +6,7 @@ data: connectorSubtype: api connectorType: source definitionId: 39de93cb-1511-473e-a673-5cbedb9436af - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.9 dockerRepository: airbyte/source-senseforce githubIssueLabel: source-senseforce icon: senseforce.svg @@ -47,5 +47,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-sentry/acceptance-test-config.yml b/airbyte-integrations/connectors/source-sentry/acceptance-test-config.yml index aa5b998b91cb..1f9a05396f96 100644 --- a/airbyte-integrations/connectors/source-sentry/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-sentry/acceptance-test-config.yml @@ -32,7 +32,7 @@ acceptance_tests: skip_comprehensive_incremental_tests: true configured_catalog_path: integration_tests/configured_catalog.json future_state: - future_state_path: integration_tests/abnormal_state.json + bypass_reason: "Concurrent incremental streams emit a state with the most recent record or the lower boundary instead of the incoming abnormal state value" missing_streams: - name: issues bypass_reason: "Project issues are not being returned by the Sentry API." diff --git a/airbyte-integrations/connectors/source-sentry/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-sentry/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-sentry/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-sentry/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-sentry/main.py b/airbyte-integrations/connectors/source-sentry/main.py index 1c7adc746e97..c5f41c2a4502 100644 --- a/airbyte-integrations/connectors/source-sentry/main.py +++ b/airbyte-integrations/connectors/source-sentry/main.py @@ -4,5 +4,6 @@ from source_sentry.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-sentry/metadata.yaml b/airbyte-integrations/connectors/source-sentry/metadata.yaml index 3c8962d4a96e..914209c700e0 100644 --- a/airbyte-integrations/connectors/source-sentry/metadata.yaml +++ b/airbyte-integrations/connectors/source-sentry/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - "*" connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:1.2.2@sha256:57703de3b4c4204bd68a7b13c9300f8e03c0189bffddaffc796f1da25d2dbea0 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: cdaf146a-9b75-49fd-9dd2-9d64a0bb4781 - dockerImageTag: 0.5.3 + dockerImageTag: 0.6.4 dockerRepository: airbyte/source-sentry documentationUrl: https://docs.airbyte.com/integrations/sources/sentry githubIssueLabel: source-sentry diff --git a/airbyte-integrations/connectors/source-sentry/poetry.lock b/airbyte-integrations/connectors/source-sentry/poetry.lock index 9dfda269267a..14af1c1da89e 100644 --- a/airbyte-integrations/connectors/source-sentry/poetry.lock +++ b/airbyte-integrations/connectors/source-sentry/poetry.lock @@ -1,54 +1,98 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "airbyte-cdk" -version = "0.78.3" +version = "6.12.4" description = "A framework for writing Airbyte Connectors." optional = false -python-versions = "<4.0,>=3.9" +python-versions = "<3.13,>=3.10" files = [ - {file = "airbyte_cdk-0.78.3-py3-none-any.whl", hash = "sha256:699d61ace9f8ca4477e06af3ff1bc56856e955a444081a1701c41d94629dcd74"}, - {file = "airbyte_cdk-0.78.3.tar.gz", hash = "sha256:192c2594d0e93140a7ec635fea3d4644318faada6aa986805752adf4caf9b126"}, + {file = "airbyte_cdk-6.12.4-py3-none-any.whl", hash = "sha256:903f2c2d3be4d6595bc6c50a4625e2551308d2ca90e021bf489e0a82cf0f965d"}, + {file = "airbyte_cdk-6.12.4.tar.gz", hash = "sha256:f9f39746dec5e01a9d37255cfb45a753953227b7aafebf8f5603a6e9f943b182"}, ] [package.dependencies] -airbyte-protocol-models = "0.5.1" +airbyte-protocol-models-dataclasses = ">=0.14,<0.15" backoff = "*" cachetools = "*" -Deprecated = ">=1.2,<1.3" -dpath = ">=2.0.1,<2.1.0" -genson = "1.2.2" +cryptography = ">=42.0.5,<44.0.0" +dpath = ">=2.1.6,<3.0.0" +dunamai = ">=1.22.0,<2.0.0" +genson = "1.3.0" isodate = ">=0.6.1,<0.7.0" Jinja2 = ">=3.1.2,<3.2.0" jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" +jsonschema = ">=4.17.3,<4.18.0" +langchain_core = "0.1.42" +nltk = "3.9.1" +numpy = "<2" +orjson = ">=3.10.7,<4.0.0" +pandas = "2.2.2" pendulum = "<3.0.0" -pydantic = ">=1.10.8,<2.0.0" +psutil = "6.1.0" +pydantic = ">=2.7,<3.0" +pyjwt = ">=2.8.0,<3.0.0" pyrate-limiter = ">=3.1.0,<3.2.0" python-dateutil = "*" +python-ulid = ">=3.0.0,<4.0.0" +pytz = "2024.2" PyYAML = ">=6.0.1,<7.0.0" +rapidfuzz = ">=3.10.1,<4.0.0" requests = "*" requests_cache = "*" -wcmatch = "8.4" +serpyco-rs = ">=1.10.2,<2.0.0" +Unidecode = ">=1.3,<2.0" +wcmatch = "10.0" +xmltodict = ">=0.13.0,<0.14.0" [package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.0.271)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] +file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "python-snappy (==0.7.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] +sql = ["sqlalchemy (>=2.0,!=2.0.36,<3.0)"] +vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.8.0)"] [[package]] -name = "airbyte-protocol-models" -version = "0.5.1" -description = "Declares the Airbyte Protocol." +name = "airbyte-protocol-models-dataclasses" +version = "0.14.1" +description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.5.1-py3-none-any.whl", hash = "sha256:dfe84e130e51ce2ae81a06d5aa36f6c5ce3152b9e36e6f0195fad6c3dab0927e"}, - {file = "airbyte_protocol_models-0.5.1.tar.gz", hash = "sha256:7c8b16c7c1c7956b1996052e40585a3a93b1e44cb509c4e97c1ee4fe507ea086"}, + {file = "airbyte_protocol_models_dataclasses-0.14.1-py3-none-any.whl", hash = "sha256:dfe10b32ee09e6ba9b4f17bd309e841b61cbd61ec8f80b1937ff104efd6209a9"}, + {file = "airbyte_protocol_models_dataclasses-0.14.1.tar.gz", hash = "sha256:f62a46556b82ea0d55de144983141639e8049d836dd4e0a9d7234c5b2e103c08"}, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + +[[package]] +name = "anyio" +version = "4.7.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.9" +files = [ + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] -pydantic = ">=1.9.2,<2.0.0" +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} +idna = ">=2.8" +sniffio = ">=1.1" +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} + +[package.extras] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] +trio = ["trio (>=0.26.1)"] [[package]] name = "atomicwrites" @@ -60,24 +104,35 @@ files = [ {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, ] +[[package]] +name = "attributes-doc" +version = "0.4.0" +description = "PEP 224 implementation" +optional = false +python-versions = ">=3.8" +files = [ + {file = "attributes-doc-0.4.0.tar.gz", hash = "sha256:b1576c94a714e9fc2c65c47cf10d0c8e1a5f7c4f5ae7f69006be108d95cbfbfb"}, + {file = "attributes_doc-0.4.0-py2.py3-none-any.whl", hash = "sha256:4c3007d9e58f3a6cb4b9c614c4d4ce2d92161581f28e594ddd8241cc3a113bdd"}, +] + [[package]] name = "attrs" -version = "23.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, - {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] -tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "backoff" @@ -92,35 +147,35 @@ files = [ [[package]] name = "bracex" -version = "2.4" +version = "2.5.post1" description = "Bash style brace expander." optional = false python-versions = ">=3.8" files = [ - {file = "bracex-2.4-py3-none-any.whl", hash = "sha256:efdc71eff95eaff5e0f8cfebe7d01adf2c8637c8c92edaf63ef348c241a82418"}, - {file = "bracex-2.4.tar.gz", hash = "sha256:a27eaf1df42cf561fed58b7a8f3fdf129d1ea16a81e1fadd1d17989bc6384beb"}, + {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, + {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, ] [[package]] name = "cachetools" -version = "5.3.3" +version = "5.5.0" description = "Extensible memoizing collections and decorators" optional = false python-versions = ">=3.7" files = [ - {file = "cachetools-5.3.3-py3-none-any.whl", hash = "sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945"}, - {file = "cachetools-5.3.3.tar.gz", hash = "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"}, + {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, + {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, ] [[package]] name = "cattrs" -version = "23.2.3" +version = "24.1.2" description = "Composable complex class support for attrs and dataclasses." optional = false python-versions = ">=3.8" files = [ - {file = "cattrs-23.2.3-py3-none-any.whl", hash = "sha256:0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108"}, - {file = "cattrs-23.2.3.tar.gz", hash = "sha256:a934090d95abaa9e911dac357e3a8699e0b4b14f8529bcc7d2b1ad9d51672b9f"}, + {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, + {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, ] [package.dependencies] @@ -132,6 +187,7 @@ typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_ver bson = ["pymongo (>=4.4.0)"] cbor2 = ["cbor2 (>=5.4.6)"] msgpack = ["msgpack (>=1.0.5)"] +msgspec = ["msgspec (>=0.18.5)"] orjson = ["orjson (>=3.9.2)"] pyyaml = ["pyyaml (>=6.0)"] tomlkit = ["tomlkit (>=0.11.8)"] @@ -139,114 +195,209 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.2.2" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, - {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] +[[package]] +name = "cffi" +version = "1.17.1" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, + {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, + {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, + {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, + {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, +] + +[package.dependencies] +pycparser = "*" + [[package]] name = "charset-normalizer" -version = "3.3.2" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] +[[package]] +name = "click" +version = "8.1.8" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + [[package]] name = "colorama" version = "0.4.6" @@ -259,42 +410,88 @@ files = [ ] [[package]] -name = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." +name = "cryptography" +version = "43.0.3" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, + {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, + {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, + {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, + {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, + {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, + {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, ] [package.dependencies] -wrapt = ">=1.10,<2" +cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] +nox = ["nox"] +pep8test = ["check-sdist", "click", "mypy", "ruff"] +sdist = ["build"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] [[package]] name = "dpath" -version = "2.0.8" +version = "2.2.0" description = "Filesystem-like pathing and searching for dictionaries" optional = false python-versions = ">=3.7" files = [ - {file = "dpath-2.0.8-py3-none-any.whl", hash = "sha256:f92f595214dd93a00558d75d4b858beee519f4cffca87f02616ad6cd013f3436"}, - {file = "dpath-2.0.8.tar.gz", hash = "sha256:a3440157ebe80d0a3ad794f1b61c571bef125214800ffdb9afc9424e8250fe9b"}, + {file = "dpath-2.2.0-py3-none-any.whl", hash = "sha256:b330a375ded0a0d2ed404440f6c6a715deae5313af40bbb01c8a41d891900576"}, + {file = "dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e"}, ] +[[package]] +name = "dunamai" +version = "1.23.0" +description = "Dynamic version generation" +optional = false +python-versions = ">=3.5" +files = [ + {file = "dunamai-1.23.0-py3-none-any.whl", hash = "sha256:a0906d876e92441793c6a423e16a4802752e723e9c9a5aabdc5535df02dbe041"}, + {file = "dunamai-1.23.0.tar.gz", hash = "sha256:a163746de7ea5acb6dacdab3a6ad621ebc612ed1e528aaa8beedb8887fccd2c4"}, +] + +[package.dependencies] +packaging = ">=20.9" + [[package]] name = "exceptiongroup" -version = "1.2.0" +version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, - {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, ] [package.extras] @@ -302,25 +499,85 @@ test = ["pytest (>=6)"] [[package]] name = "genson" -version = "1.2.2" +version = "1.3.0" description = "GenSON is a powerful, user-friendly JSON Schema generator." optional = false python-versions = "*" files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, + {file = "genson-1.3.0-py3-none-any.whl", hash = "sha256:468feccd00274cc7e4c09e84b08704270ba8d95232aa280f65b986139cec67f7"}, + {file = "genson-1.3.0.tar.gz", hash = "sha256:e02db9ac2e3fd29e65b5286f7135762e2cd8a986537c075b06fc5f1517308e37"}, ] +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.7" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<1.0)"] + +[[package]] +name = "httpx" +version = "0.28.1" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +zstd = ["zstandard (>=0.18.0)"] + [[package]] name = "idna" -version = "3.6" +version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, - {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, ] +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -348,13 +605,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.3" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, - {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -363,6 +620,42 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "joblib" +version = "1.4.2" +description = "Lightweight pipelining with Python functions" +optional = false +python-versions = ">=3.8" +files = [ + {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, + {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, +] + +[[package]] +name = "jsonpatch" +version = "1.33" +description = "Apply JSON-Patches (RFC 6902)" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +files = [ + {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, + {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, +] + +[package.dependencies] +jsonpointer = ">=1.9" + +[[package]] +name = "jsonpointer" +version = "3.0.0" +description = "Identify specific nodes in a JSON document (RFC 6901)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, + {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, +] + [[package]] name = "jsonref" version = "0.2" @@ -376,104 +669,372 @@ files = [ [[package]] name = "jsonschema" -version = "3.2.0" +version = "4.17.3" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, ] [package.dependencies] attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" [package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] + +[[package]] +name = "langchain-core" +version = "0.1.42" +description = "Building applications with LLMs through composability" +optional = false +python-versions = "<4.0,>=3.8.1" +files = [ + {file = "langchain_core-0.1.42-py3-none-any.whl", hash = "sha256:c5653ffa08a44f740295c157a24c0def4a753333f6a2c41f76bf431cd00be8b5"}, + {file = "langchain_core-0.1.42.tar.gz", hash = "sha256:40751bf60ea5d8e2b2efe65290db434717ee3834870c002e40e2811f09d814e6"}, +] + +[package.dependencies] +jsonpatch = ">=1.33,<2.0" +langsmith = ">=0.1.0,<0.2.0" +packaging = ">=23.2,<24.0" +pydantic = ">=1,<3" +PyYAML = ">=5.3" +tenacity = ">=8.1.0,<9.0.0" + +[package.extras] +extended-testing = ["jinja2 (>=3,<4)"] + +[[package]] +name = "langsmith" +version = "0.1.147" +description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." +optional = false +python-versions = "<4.0,>=3.8.1" +files = [ + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, +] + +[package.dependencies] +httpx = ">=0.23.0,<1" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} +pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} +requests = ">=2,<3" +requests-toolbelt = ">=1.0.0,<2.0.0" + +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] [[package]] name = "markupsafe" -version = "2.1.5" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" +files = [ + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, +] + +[[package]] +name = "nltk" +version = "3.9.1" +description = "Natural Language Toolkit" +optional = false +python-versions = ">=3.8" +files = [ + {file = "nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1"}, + {file = "nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868"}, +] + +[package.dependencies] +click = "*" +joblib = "*" +regex = ">=2021.8.3" +tqdm = "*" + +[package.extras] +all = ["matplotlib", "numpy", "pyparsing", "python-crfsuite", "requests", "scikit-learn", "scipy", "twython"] +corenlp = ["requests"] +machine-learning = ["numpy", "python-crfsuite", "scikit-learn", "scipy"] +plot = ["matplotlib"] +tgrep = ["pyparsing"] +twitter = ["twython"] + +[[package]] +name = "numpy" +version = "1.26.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, +] + +[[package]] +name = "orjson" +version = "3.10.13" +description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" +optional = false +python-versions = ">=3.8" +files = [ + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] name = "packaging" -version = "24.0" +version = "23.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] + +[[package]] +name = "pandas" +version = "2.2.2" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, ] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] [[package]] name = "pendulum" @@ -511,34 +1072,65 @@ pytzdata = ">=2020.1" [[package]] name = "platformdirs" -version = "4.2.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +version = "4.3.6" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, - {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "pluggy" -version = "1.4.0" +version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" files = [ - {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, - {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "psutil" +version = "6.1.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, +] + +[package.extras] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + [[package]] name = "py" version = "1.11.0" @@ -550,57 +1142,165 @@ files = [ {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] +[[package]] +name = "pycparser" +version = "2.22" +description = "C parser in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + [[package]] name = "pydantic" -version = "1.10.14" -description = "Data validation and settings management using python type hints" +version = "2.10.4" +description = "Data validation using Python type hints" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic-1.10.14-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f4fcec873f90537c382840f330b90f4715eebc2bc9925f04cb92de593eae054"}, - {file = "pydantic-1.10.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e3a76f571970fcd3c43ad982daf936ae39b3e90b8a2e96c04113a369869dc87"}, - {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d886bd3c3fbeaa963692ef6b643159ccb4b4cefaf7ff1617720cbead04fd1d"}, - {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:798a3d05ee3b71967844a1164fd5bdb8c22c6d674f26274e78b9f29d81770c4e"}, - {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:23d47a4b57a38e8652bcab15a658fdb13c785b9ce217cc3a729504ab4e1d6bc9"}, - {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f9f674b5c3bebc2eba401de64f29948ae1e646ba2735f884d1594c5f675d6f2a"}, - {file = "pydantic-1.10.14-cp310-cp310-win_amd64.whl", hash = "sha256:24a7679fab2e0eeedb5a8924fc4a694b3bcaac7d305aeeac72dd7d4e05ecbebf"}, - {file = "pydantic-1.10.14-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d578ac4bf7fdf10ce14caba6f734c178379bd35c486c6deb6f49006e1ba78a7"}, - {file = "pydantic-1.10.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa7790e94c60f809c95602a26d906eba01a0abee9cc24150e4ce2189352deb1b"}, - {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad4e10efa5474ed1a611b6d7f0d130f4aafadceb73c11d9e72823e8f508e663"}, - {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1245f4f61f467cb3dfeced2b119afef3db386aec3d24a22a1de08c65038b255f"}, - {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:21efacc678a11114c765eb52ec0db62edffa89e9a562a94cbf8fa10b5db5c046"}, - {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:412ab4a3f6dbd2bf18aefa9f79c7cca23744846b31f1d6555c2ee2b05a2e14ca"}, - {file = "pydantic-1.10.14-cp311-cp311-win_amd64.whl", hash = "sha256:e897c9f35281f7889873a3e6d6b69aa1447ceb024e8495a5f0d02ecd17742a7f"}, - {file = "pydantic-1.10.14-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d604be0f0b44d473e54fdcb12302495fe0467c56509a2f80483476f3ba92b33c"}, - {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42c7d17706911199798d4c464b352e640cab4351efe69c2267823d619a937e5"}, - {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:596f12a1085e38dbda5cbb874d0973303e34227b400b6414782bf205cc14940c"}, - {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bfb113860e9288d0886e3b9e49d9cf4a9d48b441f52ded7d96db7819028514cc"}, - {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bc3ed06ab13660b565eed80887fcfbc0070f0aa0691fbb351657041d3e874efe"}, - {file = "pydantic-1.10.14-cp37-cp37m-win_amd64.whl", hash = "sha256:ad8c2bc677ae5f6dbd3cf92f2c7dc613507eafe8f71719727cbc0a7dec9a8c01"}, - {file = "pydantic-1.10.14-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c37c28449752bb1f47975d22ef2882d70513c546f8f37201e0fec3a97b816eee"}, - {file = "pydantic-1.10.14-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49a46a0994dd551ec051986806122767cf144b9702e31d47f6d493c336462597"}, - {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53e3819bd20a42470d6dd0fe7fc1c121c92247bca104ce608e609b59bc7a77ee"}, - {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbb503bbbbab0c588ed3cd21975a1d0d4163b87e360fec17a792f7d8c4ff29f"}, - {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:336709883c15c050b9c55a63d6c7ff09be883dbc17805d2b063395dd9d9d0022"}, - {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4ae57b4d8e3312d486e2498d42aed3ece7b51848336964e43abbf9671584e67f"}, - {file = "pydantic-1.10.14-cp38-cp38-win_amd64.whl", hash = "sha256:dba49d52500c35cfec0b28aa8b3ea5c37c9df183ffc7210b10ff2a415c125c4a"}, - {file = "pydantic-1.10.14-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c66609e138c31cba607d8e2a7b6a5dc38979a06c900815495b2d90ce6ded35b4"}, - {file = "pydantic-1.10.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d986e115e0b39604b9eee3507987368ff8148222da213cd38c359f6f57b3b347"}, - {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:646b2b12df4295b4c3148850c85bff29ef6d0d9621a8d091e98094871a62e5c7"}, - {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282613a5969c47c83a8710cc8bfd1e70c9223feb76566f74683af889faadc0ea"}, - {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:466669501d08ad8eb3c4fecd991c5e793c4e0bbd62299d05111d4f827cded64f"}, - {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:13e86a19dca96373dcf3190fcb8797d40a6f12f154a244a8d1e8e03b8f280593"}, - {file = "pydantic-1.10.14-cp39-cp39-win_amd64.whl", hash = "sha256:08b6ec0917c30861e3fe71a93be1648a2aa4f62f866142ba21670b24444d7fd8"}, - {file = "pydantic-1.10.14-py3-none-any.whl", hash = "sha256:8ee853cd12ac2ddbf0ecbac1c289f95882b2d4482258048079d13be700aa114c"}, - {file = "pydantic-1.10.14.tar.gz", hash = "sha256:46f17b832fe27de7850896f3afee50ea682220dd218f7e9c88d436788419dca6"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] -typing-extensions = ">=4.2.0" +annotated-types = ">=0.6.0" +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] +email = ["email-validator (>=2.0.0)"] +timezone = ["tzdata"] + +[[package]] +name = "pydantic-core" +version = "2.27.2" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" + +[[package]] +name = "pyjwt" +version = "2.10.1" +description = "JSON Web Token implementation in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, +] + +[package.extras] +crypto = ["cryptography (>=3.4.0)"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] +docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] [[package]] name = "pyrate-limiter" @@ -713,6 +1413,31 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "python-ulid" +version = "3.0.0" +description = "Universally unique lexicographically sortable identifier" +optional = false +python-versions = ">=3.9" +files = [ + {file = "python_ulid-3.0.0-py3-none-any.whl", hash = "sha256:e4c4942ff50dbd79167ad01ac725ec58f924b4018025ce22c858bfcff99a5e31"}, + {file = "python_ulid-3.0.0.tar.gz", hash = "sha256:e50296a47dc8209d28629a22fc81ca26c00982c78934bd7766377ba37ea49a9f"}, +] + +[package.extras] +pydantic = ["pydantic (>=2.0)"] + +[[package]] +name = "pytz" +version = "2024.2" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, + {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, +] + [[package]] name = "pytzdata" version = "2020.1" @@ -726,73 +1451,278 @@ files = [ [[package]] name = "pyyaml" -version = "6.0.1" +version = "6.0.2" description = "YAML parser and emitter for Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, +] + +[[package]] +name = "rapidfuzz" +version = "3.11.0" +description = "rapid fuzzy string matching" +optional = false +python-versions = ">=3.9" +files = [ + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eb8a54543d16ab1b69e2c5ed96cabbff16db044a50eddfc028000138ca9ddf33"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:231c8b2efbd7f8d2ecd1ae900363ba168b8870644bb8f2b5aa96e4a7573bde19"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54e7f442fb9cca81e9df32333fb075ef729052bcabe05b0afc0441f462299114"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:906f1f2a1b91c06599b3dd1be207449c5d4fc7bd1e1fa2f6aef161ea6223f165"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed59044aea9eb6c663112170f2399b040d5d7b162828b141f2673e822093fa8"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cb1965a28b0fa64abdee130c788a0bc0bb3cf9ef7e3a70bf055c086c14a3d7e"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b488b244931d0291412917e6e46ee9f6a14376625e150056fe7c4426ef28225"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f0ba13557fec9d5ffc0a22826754a7457cc77f1b25145be10b7bb1d143ce84c6"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3871fa7dfcef00bad3c7e8ae8d8fd58089bad6fb21f608d2bf42832267ca9663"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b2669eafee38c5884a6e7cc9769d25c19428549dcdf57de8541cf9e82822e7db"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ffa1bb0e26297b0f22881b219ffc82a33a3c84ce6174a9d69406239b14575bd5"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:45b15b8a118856ac9caac6877f70f38b8a0d310475d50bc814698659eabc1cdb"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win32.whl", hash = "sha256:22033677982b9c4c49676f215b794b0404073f8974f98739cb7234e4a9ade9ad"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:be15496e7244361ff0efcd86e52559bacda9cd975eccf19426a0025f9547c792"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_arm64.whl", hash = "sha256:714a7ba31ba46b64d30fccfe95f8013ea41a2e6237ba11a805a27cdd3bce2573"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8724a978f8af7059c5323d523870bf272a097478e1471295511cf58b2642ff83"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b63cb1f2eb371ef20fb155e95efd96e060147bdd4ab9fc400c97325dfee9fe1"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82497f244aac10b20710448645f347d862364cc4f7d8b9ba14bd66b5ce4dec18"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:339607394941801e6e3f6c1ecd413a36e18454e7136ed1161388de674f47f9d9"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84819390a36d6166cec706b9d8f0941f115f700b7faecab5a7e22fc367408bc3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eea8d9e20632d68f653455265b18c35f90965e26f30d4d92f831899d6682149b"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b659e1e2ea2784a9a397075a7fc395bfa4fe66424042161c4bcaf6e4f637b38"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1315cd2a351144572e31fe3df68340d4b83ddec0af8b2e207cd32930c6acd037"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a7743cca45b4684c54407e8638f6d07b910d8d811347b9d42ff21262c7c23245"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:5bb636b0150daa6d3331b738f7c0f8b25eadc47f04a40e5c23c4bfb4c4e20ae3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:42f4dd264ada7a9aa0805ea0da776dc063533917773cf2df5217f14eb4429eae"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:51f24cb39e64256221e6952f22545b8ce21cacd59c0d3e367225da8fc4b868d8"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win32.whl", hash = "sha256:aaf391fb6715866bc14681c76dc0308f46877f7c06f61d62cc993b79fc3c4a2a"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:ebadd5b8624d8ad503e505a99b8eb26fe3ea9f8e9c2234e805a27b269e585842"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:d895998fec712544c13cfe833890e0226585cf0391dd3948412441d5d68a2b8c"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f382fec4a7891d66fb7163c90754454030bb9200a13f82ee7860b6359f3f2fa8"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dfaefe08af2a928e72344c800dcbaf6508e86a4ed481e28355e8d4b6a6a5230e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92ebb7c12f682b5906ed98429f48a3dd80dd0f9721de30c97a01473d1a346576"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a1b3ebc62d4bcdfdeba110944a25ab40916d5383c5e57e7c4a8dc0b6c17211a"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c6d7fea39cb33e71de86397d38bf7ff1a6273e40367f31d05761662ffda49e4"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99aebef8268f2bc0b445b5640fd3312e080bd17efd3fbae4486b20ac00466308"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4469307f464ae3089acf3210b8fc279110d26d10f79e576f385a98f4429f7d97"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:eb97c53112b593f89a90b4f6218635a9d1eea1d7f9521a3b7d24864228bbc0aa"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef8937dae823b889c0273dfa0f0f6c46a3658ac0d851349c464d1b00e7ff4252"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d95f9e9f3777b96241d8a00d6377cc9c716981d828b5091082d0fe3a2924b43e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:b1d67d67f89e4e013a5295e7523bc34a7a96f2dba5dd812c7c8cb65d113cbf28"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d994cf27e2f874069884d9bddf0864f9b90ad201fcc9cb2f5b82bacc17c8d5f2"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win32.whl", hash = "sha256:ba26d87fe7fcb56c4a53b549a9e0e9143f6b0df56d35fe6ad800c902447acd5b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:b1f7efdd7b7adb32102c2fa481ad6f11923e2deb191f651274be559d56fc913b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:ed78c8e94f57b44292c1a0350f580e18d3a3c5c0800e253f1583580c1b417ad2"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e60814edd0c9b511b5f377d48b9782b88cfe8be07a98f99973669299c8bb318a"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f28952da055dbfe75828891cd3c9abf0984edc8640573c18b48c14c68ca5e06"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e8f93bc736020351a6f8e71666e1f486bb8bd5ce8112c443a30c77bfde0eb68"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76a4a11ba8f678c9e5876a7d465ab86def047a4fcc043617578368755d63a1bc"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc0e0d41ad8a056a9886bac91ff9d9978e54a244deb61c2972cc76b66752de9c"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e8ea35f2419c7d56b3e75fbde2698766daedb374f20eea28ac9b1f668ef4f74"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd340bbd025302276b5aa221dccfe43040c7babfc32f107c36ad783f2ffd8775"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:494eef2c68305ab75139034ea25328a04a548d297712d9cf887bf27c158c388b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5a167344c1d6db06915fb0225592afdc24d8bafaaf02de07d4788ddd37f4bc2f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8c7af25bda96ac799378ac8aba54a8ece732835c7b74cfc201b688a87ed11152"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d2a0f7e17f33e7890257367a1662b05fecaf56625f7dbb6446227aaa2b86448b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4d0d26c7172bdb64f86ee0765c5b26ea1dc45c52389175888ec073b9b28f4305"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win32.whl", hash = "sha256:6ad02bab756751c90fa27f3069d7b12146613061341459abf55f8190d899649f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:b1472986fd9c5d318399a01a0881f4a0bf4950264131bb8e2deba9df6d8c362b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:c408f09649cbff8da76f8d3ad878b64ba7f7abdad1471efb293d2c075e80c822"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1bac4873f6186f5233b0084b266bfb459e997f4c21fc9f029918f44a9eccd304"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f9f12c2d0aa52b86206d2059916153876a9b1cf9dfb3cf2f344913167f1c3d4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd501de6f7a8f83557d20613b58734d1cb5f0be78d794cde64fe43cfc63f5f2"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4416ca69af933d4a8ad30910149d3db6d084781d5c5fdedb713205389f535385"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f0821b9bdf18c5b7d51722b906b233a39b17f602501a966cfbd9b285f8ab83cd"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0edecc3f90c2653298d380f6ea73b536944b767520c2179ec5d40b9145e47aa"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4513dd01cee11e354c31b75f652d4d466c9440b6859f84e600bdebfccb17735a"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d9727b85511b912571a76ce53c7640ba2c44c364e71cef6d7359b5412739c570"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ab9eab33ee3213f7751dc07a1a61b8d9a3d748ca4458fffddd9defa6f0493c16"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:6b01c1ddbb054283797967ddc5433d5c108d680e8fa2684cf368be05407b07e4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:3857e335f97058c4b46fa39ca831290b70de554a5c5af0323d2f163b19c5f2a6"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d98a46cf07c0c875d27e8a7ed50f304d83063e49b9ab63f21c19c154b4c0d08d"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win32.whl", hash = "sha256:c36539ed2c0173b053dafb221458812e178cfa3224ade0960599bec194637048"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:ec8d7d8567e14af34a7911c98f5ac74a3d4a743cd848643341fc92b12b3784ff"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_arm64.whl", hash = "sha256:62171b270ecc4071be1c1f99960317db261d4c8c83c169e7f8ad119211fe7397"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f06e3c4c0a8badfc4910b9fd15beb1ad8f3b8fafa8ea82c023e5e607b66a78e4"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fe7aaf5a54821d340d21412f7f6e6272a9b17a0cbafc1d68f77f2fc11009dcd5"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25398d9ac7294e99876a3027ffc52c6bebeb2d702b1895af6ae9c541ee676702"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a52eea839e4bdc72c5e60a444d26004da00bb5bc6301e99b3dde18212e41465"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c87319b0ab9d269ab84f6453601fd49b35d9e4a601bbaef43743f26fabf496c"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3048c6ed29d693fba7d2a7caf165f5e0bb2b9743a0989012a98a47b975355cca"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b04f29735bad9f06bb731c214f27253bd8bedb248ef9b8a1b4c5bde65b838454"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7864e80a0d4e23eb6194254a81ee1216abdc53f9dc85b7f4d56668eced022eb8"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3794df87313dfb56fafd679b962e0613c88a293fd9bd5dd5c2793d66bf06a101"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d71da0012face6f45432a11bc59af19e62fac5a41f8ce489e80c0add8153c3d1"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff38378346b7018f42cbc1f6d1d3778e36e16d8595f79a312b31e7c25c50bd08"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6668321f90aa02a5a789d4e16058f2e4f2692c5230252425c3532a8a62bc3424"}, + {file = "rapidfuzz-3.11.0.tar.gz", hash = "sha256:a53ca4d3f52f00b393fab9b5913c5bafb9afc27d030c8a1db1283da6917a860f"}, +] + +[package.extras] +all = ["numpy"] + +[[package]] +name = "regex" +version = "2024.11.6" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.8" +files = [ + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] name = "requests" -version = "2.31.0" +version = "2.32.3" description = "Python HTTP for Humans." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, ] [package.dependencies] @@ -807,13 +1737,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "requests-cache" -version = "1.2.0" +version = "1.2.1" description = "A persistent cache for python requests" optional = false python-versions = ">=3.8" files = [ - {file = "requests_cache-1.2.0-py3-none-any.whl", hash = "sha256:490324301bf0cb924ff4e6324bd2613453e7e1f847353928b08adb0fdfb7f722"}, - {file = "requests_cache-1.2.0.tar.gz", hash = "sha256:db1c709ca343cc1cd5b6c8b1a5387298eceed02306a6040760db538c885e3838"}, + {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, + {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, ] [package.dependencies] @@ -853,32 +1783,110 @@ requests = ">=2.22,<3" fixture = ["fixtures"] [[package]] -name = "setuptools" -version = "69.2.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" +name = "requests-toolbelt" +version = "1.0.0" +description = "A utility belt for advanced users of python-requests" optional = false -python-versions = ">=3.8" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ - {file = "setuptools-69.2.0-py3-none-any.whl", hash = "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c"}, - {file = "setuptools-69.2.0.tar.gz", hash = "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e"}, + {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, + {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, ] -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + +[[package]] +name = "serpyco-rs" +version = "1.11.0" +description = "" +optional = false +python-versions = ">=3.9" +files = [ + {file = "serpyco_rs-1.11.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4b2bd933539bd8c84315e2fb5ae52ef7a58ace5a6dfe3f8b73f74dc71216779e"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:627f957889ff73c4d2269fc7b6bba93212381befe03633e7cb5495de66ba9a33"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b0933620abc01434023e0e3e22255b7e4ab9b427b5a9a5ee00834656d792377a"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9ce46683d92e34abb20304817fc5ac6cb141a06fc7468dedb1d8865a8a9682f6"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bda437d86e8859bf91c189c1f4650899822f6d6d7b02b48f5729da904eb7bb7d"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a72bfbd282af17ebe76d122639013e802c09902543fdbbd828fb2159ec9755e"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d4808df5384e3e8581e31a90ba7a1fa501c0837b1f174284bb8a4555b6864ea"}, + {file = "serpyco_rs-1.11.0-cp310-none-win_amd64.whl", hash = "sha256:c7b60aef4c16d68efb0d6241f05d0a434d873d98449cbb4366b0d385f0a7172b"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d47ee577cf4d69b53917615cb031ad8708eb2f59fe78194b1968c13130fc2f7"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6090d9a1487237cdd4e9362a823eede23249602019b917e7bd57846179286e79"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7192eb3df576386fefd595ea31ae25c62522841ffec7e7aeb37a80b55bdc3213"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b52ef8affb7e71b9b98a7d5216d6a7ad03b04e990acb147cd9211c8b931c5487"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3480e09e473560c60e74aaa789e6b4d079637371aae0a98235440111464bbba7"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c92e36b0ab6fe866601c2331f7e99c809a126d21963c03d8a5c29331526deed"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84f497361952d4566bc1f77e9e15a84a2614f593cc671fbf0a0fa80046f9c3d7"}, + {file = "serpyco_rs-1.11.0-cp311-none-win_amd64.whl", hash = "sha256:37fc1cf192bef9784fbf1f4e03cec21750b9e704bef55cc0442f71a715eee920"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3ea93d485f03dc8b0cfb0d477f0ad2e86e78f0461b53010656ab5b4db1b41fb0"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7772410d15694b03f9c5500a2c47d62eed76e191bea4087ad042250346b1a38e"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42118463c1679846cffd2f06f47744c9b9eb33c5d0448afd88ea19e1a81a8ddd"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:79481a455b76cc56021dc55bb6d5bdda1b2b32bcb6a1ee711b597140d112e9b1"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8fd79051f9af9591fc03cf7d3033ff180416301f6a4fd3d1e3d92ebd2d68697"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d29c8f9aeed734a3b51f7349d04ec9063516ffa4e10b632d75e9b1309e4930e4"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15609158b0d9591ffa118302cd9d0039970cb3faf91dce32975f7d276e7411d5"}, + {file = "serpyco_rs-1.11.0-cp312-none-win_amd64.whl", hash = "sha256:00081eae77fbf4c5d88371c5586317ab02ccb293a330b460869a283edf2b7b69"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3028893366a1985adcedb13fa8f6f98c087c185efc427f94c2ccdafa40f45832"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c18bf511316f3abf648a68ee62ef88617bec57d3fcde69466b4361102715ae5"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7dde9ef09cdfaf7c62378186b9e29f54ec76114be4c347be6a06dd559c5681e"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:18500ebc5e75285841e35585a238629a990b709e14f68933233640d15ca17d5f"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47c23132d4e03982703a7630aa09877b41e499722142f76b6153f6619b612f3"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5f8e6ba499f6a0825bee0d8f8764569d367af871b563fc6512c171474e8e5383"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15438a076047c34cff6601a977df54948e8d39d1a86f89d05c48bc60f4c12a61"}, + {file = "serpyco_rs-1.11.0-cp313-none-win_amd64.whl", hash = "sha256:84ee2c109415bd81904fc9abb9aec86a5dd13166808c21142cf23ec639f683bd"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5c97c16c865261577fac4effeccc7ef5e0a1e8e35e7a3ee6c90c77c3a4cd7ff9"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47825e70f86fd6ef7c4a835dea3d6e8eef4fee354ed7b39ced99f31aba74a86e"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24d220220365110edba2f778f41ab3cf396883da0f26e1361a3ada9bd0227f73"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3a46f334af5a9d77acc6e1e58f355ae497900a2798929371f0545e274f6e6166"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d72b748acce4b4e3c7c9724e1eb33d033a1c26b08a698b393e0288060e0901"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2b8b6f205e8cc038d4d30dd0e70eece7bbecc816eb2f3787c330dc2218e232d"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:038d748bfff31f150f0c3edab2766b8843edb952cb1bd3bf547886beb0912dae"}, + {file = "serpyco_rs-1.11.0-cp39-none-win_amd64.whl", hash = "sha256:0fee1c89ec2cb013dc232e4ebef88e2844357ce8631063b56639dbfb83762f20"}, + {file = "serpyco_rs-1.11.0.tar.gz", hash = "sha256:70a844615ffb229e6e89c204b3ab7404aacaf2838911814c7d847969b8da2e3a"}, +] + +[package.dependencies] +attributes-doc = "*" +typing-extensions = "*" [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, +] + +[[package]] +name = "tenacity" +version = "8.5.0" +description = "Retry code until it succeeds" +optional = false +python-versions = ">=3.8" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, + {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, ] +[package.extras] +doc = ["reno", "sphinx"] +test = ["pytest", "tornado (>=4.5)", "typeguard"] + [[package]] name = "toml" version = "0.10.2" @@ -890,15 +1898,58 @@ files = [ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] +[[package]] +name = "tqdm" +version = "4.67.1" +description = "Fast, Extensible Progress Meter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + [[package]] name = "typing-extensions" -version = "4.10.0" +version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, - {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + +[[package]] +name = "tzdata" +version = "2024.2" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, + {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, +] + +[[package]] +name = "unidecode" +version = "1.3.8" +description = "ASCII transliterations of Unicode text" +optional = false +python-versions = ">=3.5" +files = [ + {file = "Unidecode-1.3.8-py3-none-any.whl", hash = "sha256:d130a61ce6696f8148a3bd8fe779c99adeb4b870584eeb9526584e9aa091fd39"}, + {file = "Unidecode-1.3.8.tar.gz", hash = "sha256:cfdb349d46ed3873ece4586b96aa75258726e2fa8ec21d6f00a591d98806c2f4"}, ] [[package]] @@ -917,13 +1968,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.1" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -934,98 +1985,30 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "wcmatch" -version = "8.4" +version = "10.0" description = "Wildcard/glob file name matcher." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, + {file = "wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a"}, + {file = "wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a"}, ] [package.dependencies] bracex = ">=2.1.1" [[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." +name = "xmltodict" +version = "0.13.0" +description = "Makes working with XML feel like you are working with JSON" optional = false -python-versions = ">=3.6" +python-versions = ">=3.4" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "xmltodict-0.13.0-py2.py3-none-any.whl", hash = "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"}, + {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"}, ] [metadata] lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "25d79195c052c9654e64e6cd73809188b3aa16bd228841f214ff871a895c9c6c" +python-versions = "^3.10,<3.12" +content-hash = "07010436127ce767440418c5c4187d7e49be131770e2796fa5abb5ba0c8d5809" diff --git a/airbyte-integrations/connectors/source-sentry/pyproject.toml b/airbyte-integrations/connectors/source-sentry/pyproject.toml index 524f710a9fbd..739f9fd8a234 100644 --- a/airbyte-integrations/connectors/source-sentry/pyproject.toml +++ b/airbyte-integrations/connectors/source-sentry/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.5.3" +version = "0.6.4" name = "source-sentry" description = "Source implementation for Sentry." authors = [ "Airbyte ",] @@ -16,8 +16,8 @@ repository = "https://github.com/airbytehq/airbyte" include = "source_sentry" [tool.poetry.dependencies] -python = "^3.9,<3.12" -airbyte-cdk = "^0" +python = "^3.10,<3.12" +airbyte-cdk = "^6" [tool.poetry.scripts] source-sentry = "source_sentry.run:run" diff --git a/airbyte-integrations/connectors/source-sentry/source_sentry/manifest.yaml b/airbyte-integrations/connectors/source-sentry/source_sentry/manifest.yaml index bf50ecd2b607..ec9034998c39 100644 --- a/airbyte-integrations/connectors/source-sentry/source_sentry/manifest.yaml +++ b/airbyte-integrations/connectors/source-sentry/source_sentry/manifest.yaml @@ -51,7 +51,7 @@ definitions: record_selector: $ref: "#/definitions/record_selector" record_filter: - condition: "{{ record[parameters['cursor_field']] > stream_state.get(parameters['cursor_field'], '') }}" + condition: "{{ record[parameters['cursor_field']] > stream_interval.get('start_time', '') }}" paginator: $ref: "#/definitions/paginator" partition_router: [] @@ -62,7 +62,7 @@ definitions: - "%Y-%m-%dT%H:%M:%SZ" - "%Y-%m-%dT%H:%M:%S.%f%z" - "%Y-%m-%dT%H:%M:%S%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" start_datetime: type: MinMaxDatetime datetime: "1900-01-01T00:00:00.0Z" @@ -98,11 +98,12 @@ definitions: record_selector: $ref: "#/definitions/record_selector" record_filter: - condition: "{{ record[parameters['cursor_field']] > stream_state.get(parameters['cursor_field'], '') }}" + condition: "{{ record[parameters['cursor_field']] > stream_interval.get('start_time', '') }}" paginator: $ref: "#/definitions/paginator" incremental_sync: $ref: "#/definitions/incremental_sync" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" # Stream Issues https://docs.sentry.io/api/events/list-a-projects-issues/ issues: @@ -117,7 +118,7 @@ definitions: requester: $ref: "#/definitions/requester" request_parameters: - query: "lastSeen:>{{ stream_state.get(parameters['cursor_field']) or '1900-01-01T00:00:00.0Z' if stream_state else '1900-01-01T00:00:00.0Z' }}" + query: "lastSeen:>{{ stream_interval.get('start_time', '') or '1900-01-01T00:00:00.0Z' if stream_interval else '1900-01-01T00:00:00.0Z' }}" record_selector: $ref: "#/definitions/record_selector" paginator: @@ -166,6 +167,12 @@ check: stream_names: - project_detail +# Sentry currently supports 5 streams and each operates as descending data feed that can only run in +# parallel with each other. This number can increase if we add more streams +concurrency_level: + type: ConcurrencyLevel + default_concurrency: 5 + metadata: autoImportSchema: events: true diff --git a/airbyte-integrations/connectors/source-sentry/source_sentry/run.py b/airbyte-integrations/connectors/source-sentry/source_sentry/run.py index acf82b00a03d..44ad79700b2f 100644 --- a/airbyte-integrations/connectors/source-sentry/source_sentry/run.py +++ b/airbyte-integrations/connectors/source-sentry/source_sentry/run.py @@ -4,11 +4,50 @@ import sys +import traceback +from datetime import datetime +from typing import List -from airbyte_cdk.entrypoint import launch +from orjson import orjson + +from airbyte_cdk.entrypoint import AirbyteEntrypoint, launch +from airbyte_cdk.models import AirbyteErrorTraceMessage, AirbyteMessage, AirbyteMessageSerializer, AirbyteTraceMessage, TraceType, Type from source_sentry import SourceSentry +def _get_source(args: List[str]): + catalog_path = AirbyteEntrypoint.extract_catalog(args) + config_path = AirbyteEntrypoint.extract_config(args) + state_path = AirbyteEntrypoint.extract_state(args) + try: + return SourceSentry( + SourceSentry.read_catalog(catalog_path) if catalog_path else None, + SourceSentry.read_config(config_path) if config_path else None, + SourceSentry.read_state(state_path) if state_path else None, + ) + except Exception as error: + print( + orjson.dumps( + AirbyteMessageSerializer.dump( + AirbyteMessage( + type=Type.TRACE, + trace=AirbyteTraceMessage( + type=TraceType.ERROR, + emitted_at=int(datetime.now().timestamp() * 1000), + error=AirbyteErrorTraceMessage( + message=f"Error starting the sync. This could be due to an invalid configuration or catalog. Please contact Support for assistance. Error: {error}", + stack_trace=traceback.format_exc(), + ), + ), + ) + ) + ).decode() + ) + return None + + def run(): - source = SourceSentry() - launch(source, sys.argv[1:]) + _args = sys.argv[1:] + source = _get_source(_args) + if source: + launch(source, _args) diff --git a/airbyte-integrations/connectors/source-sentry/source_sentry/source.py b/airbyte-integrations/connectors/source-sentry/source_sentry/source.py index 5f86fd62dd08..f1f2166b624e 100644 --- a/airbyte-integrations/connectors/source-sentry/source_sentry/source.py +++ b/airbyte-integrations/connectors/source-sentry/source_sentry/source.py @@ -2,9 +2,13 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # +from typing import Any, Mapping, Optional + +from airbyte_cdk.models import ConfiguredAirbyteCatalog from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource +from airbyte_cdk.sources.source import TState class SourceSentry(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) + def __init__(self, catalog: Optional[ConfiguredAirbyteCatalog], config: Optional[Mapping[str, Any]], state: TState, **kwargs): + super().__init__(catalog=catalog, config=config, state=state, **{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-sentry/unit_tests/integration/config_builder.py b/airbyte-integrations/connectors/source-sentry/unit_tests/integration/config_builder.py index 0c5af692c5af..ab243cf755d6 100644 --- a/airbyte-integrations/connectors/source-sentry/unit_tests/integration/config_builder.py +++ b/airbyte-integrations/connectors/source-sentry/unit_tests/integration/config_builder.py @@ -10,7 +10,7 @@ def __init__(self) -> None: "auth_token": "test token", "organization": "test organization", "project": "test project", - "hostname": "sentry.io" + "hostname": "sentry.io", } def build(self) -> Dict[str, Any]: diff --git a/airbyte-integrations/connectors/source-sentry/unit_tests/integration/test_events_stream.py b/airbyte-integrations/connectors/source-sentry/unit_tests/integration/test_events_stream.py index 7e13aabbab22..3c29f713d5dd 100644 --- a/airbyte-integrations/connectors/source-sentry/unit_tests/integration/test_events_stream.py +++ b/airbyte-integrations/connectors/source-sentry/unit_tests/integration/test_events_stream.py @@ -3,14 +3,15 @@ import json from unittest import TestCase +from config_builder import ConfigBuilder +from source_sentry.source import SourceSentry + +from airbyte_cdk.models import SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import read from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse from airbyte_cdk.test.mock_http.response_builder import find_template from airbyte_cdk.test.state_builder import StateBuilder -from airbyte_protocol.models import SyncMode -from config_builder import ConfigBuilder -from source_sentry.source import SourceSentry class TestEvents(TestCase): @@ -29,25 +30,28 @@ def state(self): @HttpMocker() def test_read(self, http_mocker: HttpMocker): http_mocker.get( - HttpRequest( - url="https://sentry.io/api/0/projects/test%20organization/test%20project/events/", - query_params={"full": "true"} - ), - HttpResponse(body=json.dumps(find_template(self.fr_read_file, __file__)), status_code=200) - + HttpRequest(url="https://sentry.io/api/0/projects/test%20organization/test%20project/events/", query_params={"full": "true"}), + HttpResponse(body=json.dumps(find_template(self.fr_read_file, __file__)), status_code=200), ) - output = read(SourceSentry(), self.config(), self.catalog()) + config = self.config() + catalog = self.catalog() + source = SourceSentry(config=config, catalog=catalog, state=None) + + output = read(source=source, config=config, catalog=catalog) + assert len(output.records) == 1 @HttpMocker() def test_read_incremental(self, http_mocker: HttpMocker): http_mocker.get( - HttpRequest( - url="https://sentry.io/api/0/projects/test%20organization/test%20project/events/", - query_params={"full": "true"} - ), - HttpResponse(body=json.dumps(find_template(self.inc_read_file, __file__)), status_code=200) - + HttpRequest(url="https://sentry.io/api/0/projects/test%20organization/test%20project/events/", query_params={"full": "true"}), + HttpResponse(body=json.dumps(find_template(self.inc_read_file, __file__)), status_code=200), ) - output = read(SourceSentry(), self.config(), self.catalog(SyncMode.incremental), self.state()) + config = self.config() + catalog = self.catalog() + state = self.state() + source = SourceSentry(config=config, catalog=catalog, state=state) + + output = read(source=source, config=config, catalog=catalog, state=state) + assert len(output.records) == 2 diff --git a/airbyte-integrations/connectors/source-sentry/unit_tests/integration/test_issues_stream.py b/airbyte-integrations/connectors/source-sentry/unit_tests/integration/test_issues_stream.py index e9665a7854bb..40c869236242 100644 --- a/airbyte-integrations/connectors/source-sentry/unit_tests/integration/test_issues_stream.py +++ b/airbyte-integrations/connectors/source-sentry/unit_tests/integration/test_issues_stream.py @@ -3,14 +3,15 @@ import json from unittest import TestCase +from config_builder import ConfigBuilder +from source_sentry.source import SourceSentry + +from airbyte_cdk.models import SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import read from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse from airbyte_cdk.test.mock_http.response_builder import find_template from airbyte_cdk.test.state_builder import StateBuilder -from airbyte_protocol.models import SyncMode -from config_builder import ConfigBuilder -from source_sentry.source import SourceSentry class TestEvents(TestCase): @@ -31,13 +32,17 @@ def test_read(self, http_mocker: HttpMocker): http_mocker.get( HttpRequest( url="https://sentry.io/api/0/projects/test%20organization/test%20project/issues/", - query_params={"query": "lastSeen:>1900-01-01T00:00:00.0Z"} + query_params={"query": "lastSeen:>1900-01-01T00:00:00.000000Z"}, ), - HttpResponse(body=json.dumps(find_template(self.fr_read_file, __file__)), status_code=200) - + HttpResponse(body=json.dumps(find_template(self.fr_read_file, __file__)), status_code=200), ) # https://sentry.io/api/1/projects/airbyte-09/airbyte-09/issues/?query=lastSeen%3A%3E2022-01-01T00%3A00%3A00.0Z - output = read(SourceSentry(), self.config(), self.catalog()) + config = self.config() + catalog = self.catalog() + source = SourceSentry(config=config, catalog=catalog, state=None) + + output = read(source=source, config=config, catalog=catalog) + assert len(output.records) == 1 @HttpMocker() @@ -45,10 +50,15 @@ def test_read_incremental(self, http_mocker: HttpMocker): http_mocker.get( HttpRequest( url="https://sentry.io/api/0/projects/test%20organization/test%20project/issues/", - query_params={"query": "lastSeen:>2023-01-01T00:00:00.0Z"} + query_params={"query": "lastSeen:>2023-01-01T00:00:00.000000Z"}, ), - HttpResponse(body=json.dumps(find_template(self.inc_read_file, __file__)), status_code=200) - + HttpResponse(body=json.dumps(find_template(self.inc_read_file, __file__)), status_code=200), ) - output = read(SourceSentry(), self.config(), self.catalog(SyncMode.incremental), self.state()) + config = self.config() + catalog = self.catalog() + state = self.state() + source = SourceSentry(config=config, catalog=catalog, state=state) + + output = read(source=source, config=config, catalog=catalog, state=state) + assert len(output.records) == 2 diff --git a/airbyte-integrations/connectors/source-sentry/unit_tests/test_source.py b/airbyte-integrations/connectors/source-sentry/unit_tests/test_source.py index 388ce946300e..f88267bc0848 100644 --- a/airbyte-integrations/connectors/source-sentry/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-sentry/unit_tests/test_source.py @@ -9,25 +9,28 @@ def test_source_wrong_credentials(requests_mock): - source = SourceSentry() - status, error = source.check_connection(logger=logging.getLogger("airbyte"), config={"auth_token": "test_auth_token"}) + config = {"auth_token": "test_auth_token"} + source = SourceSentry(config=config, catalog=None, state={}) + status, error = source.check_connection(logger=logging.getLogger("airbyte"), config=config) assert not status def test_check_connection(requests_mock): - source = SourceSentry() + config = {"auth_token": "token", "organization": "test-org", "project": "test-project", "hostname": "sentry.io"} + source = SourceSentry(config=config, catalog=None, state=None) logger_mock = MagicMock() requests_mock.get(url="https://sentry.io/api/0/projects/test-org/test-project/", json={"id": "id", "name": "test-project"}) - config = {"auth_token": "token", "organization": "test-org", "project": "test-project", "hostname": "sentry.io"} assert source.check_connection(logger_mock, config) == (True, None) def test_streams(mocker): - source = SourceSentry() config_mock = MagicMock() config_mock["auth_token"] = "test-token" config_mock["organization"] = "test-organization" config_mock["project"] = "test-project" + + source = SourceSentry(config=config_mock, catalog=None, state=None) streams = source.streams(config_mock) + expected_streams_number = 5 assert len(streams) == expected_streams_number diff --git a/airbyte-integrations/connectors/source-sentry/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-sentry/unit_tests/test_streams.py index 4f41688c2990..0bab2123c0fd 100644 --- a/airbyte-integrations/connectors/source-sentry/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-sentry/unit_tests/test_streams.py @@ -5,14 +5,16 @@ from unittest.mock import MagicMock import pytest -from airbyte_protocol.models import SyncMode from source_sentry import SourceSentry +from airbyte_cdk.models import SyncMode + + INIT_ARGS = {"hostname": "sentry.io", "organization": "test-org", "project": "test-project"} def get_stream_by_name(stream_name): - streams = SourceSentry().streams(config=INIT_ARGS) + streams = SourceSentry(config={}, catalog=None, state={}).streams(config=INIT_ARGS) for stream in streams: if stream.name == stream_name: return stream @@ -24,7 +26,10 @@ def test_next_page_token(): response_mock = MagicMock() response_mock.headers = {} response_mock.links = {"next": {"cursor": "next-page"}} - assert stream.retriever.paginator.pagination_strategy.next_page_token(response=response_mock, last_records=[]) == "next-page" + assert ( + stream.retriever.paginator.pagination_strategy.next_page_token(response=response_mock, last_page_size=0, last_record=None) + == "next-page" + ) def test_next_page_token_is_none(): @@ -33,7 +38,9 @@ def test_next_page_token_is_none(): response_mock.headers = {} # stop condition: "results": "false" response_mock.links = {"next": {"cursor": "", "results": "false"}} - assert stream.retriever.paginator.pagination_strategy.next_page_token(response=response_mock, last_records=[]) is None + assert ( + stream.retriever.paginator.pagination_strategy.next_page_token(response=response_mock, last_page_size=0, last_record=None) is None + ) def test_events_path(): @@ -77,7 +84,10 @@ def test_projects_request_params(): response_mock = MagicMock() response_mock.headers = {} response_mock.links = {"next": {"cursor": expected}} - assert stream.retriever.paginator.pagination_strategy.next_page_token(response=response_mock, last_records=[]) == expected + assert ( + stream.retriever.paginator.pagination_strategy.next_page_token(response=response_mock, last_page_size=0, last_record=None) + == expected + ) def test_project_detail_request_params(): @@ -89,10 +99,7 @@ def test_project_detail_request_params(): def test_project_detail_parse_response(requests_mock): expected = {"id": "1", "name": "test project"} stream = get_stream_by_name("project_detail") - requests_mock.get( - "https://sentry.io/api/0/projects/test-org/test-project/", - json=expected - ) + requests_mock.get("https://sentry.io/api/0/projects/test-org/test-project/", json=expected) result = list(stream.read_records(sync_mode=SyncMode.full_refresh))[0] assert expected == result.data @@ -137,4 +144,3 @@ def test_issues_validate_state_value(state, expected): stream = get_stream_by_name("issues") stream.retriever.state = state assert stream.state.get(stream.cursor_field) == expected - diff --git a/airbyte-integrations/connectors/source-serpstat/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-serpstat/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-serpstat/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-serpstat/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-serpstat/metadata.yaml b/airbyte-integrations/connectors/source-serpstat/metadata.yaml index 516c88f3ceb6..fd6a6283d89e 100644 --- a/airbyte-integrations/connectors/source-serpstat/metadata.yaml +++ b/airbyte-integrations/connectors/source-serpstat/metadata.yaml @@ -13,11 +13,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 3b2e8fb2-9137-41ff-a1e1-83ecb39e26c8 - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-serpstat githubIssueLabel: source-serpstat icon: serpstat.svg diff --git a/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/acceptance.py index d2f090c60286..75e813d64e9a 100644 --- a/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/acceptance.py @@ -11,6 +11,7 @@ import docker import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) TMP_FOLDER = "/tmp/test_sftp_source" diff --git a/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/configs/config_use_all_files_transfer.json b/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/configs/config_use_all_files_transfer.json new file mode 100644 index 000000000000..a97a52dd5a8a --- /dev/null +++ b/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/configs/config_use_all_files_transfer.json @@ -0,0 +1,61 @@ +{ + "delivery_method": { "delivery_type": "use_file_transfer" }, + "host": "localhost", + "port": 2222, + "username": "foo", + "credentials": { + "auth_type": "password", + "password": "pass" + }, + "file_type": "json", + "start_date": "2021-01-01T00:00:00.000000Z", + "folder_path": "/files", + "streams": [ + { + "name": "test_stream", + "file_type": "csv", + "globs": [ + "**/file_transfer_1.csv", + "**/file_transfer_2.csv", + "**/file_transfer_3.csv", + "**/file_transfer_4.csv", + "**/file_transfer_5.csv" + ], + "legacy_prefix": "", + "validation_policy": "Emit Record", + "format": { + "filetype": "csv", + "delimiter": ",", + "quote_char": "\"", + "double_quote": true, + "null_values": [ + "", + "#N/A", + "#N/A N/A", + "#NA", + "-1.#IND", + "-1.#QNAN", + "-NaN", + "-nan", + "1.#IND", + "1.#QNAN", + "N/A", + "NA", + "NULL", + "NaN", + "n/a", + "nan", + "null" + ], + "true_values": ["1", "True", "TRUE", "true"], + "false_values": ["0", "False", "FALSE", "false"], + "inference_type": "Primitive Types Only", + "strings_can_be_null": false, + "encoding": "utf8", + "header_definition": { + "header_definition_type": "From CSV" + } + } + } + ] +} diff --git a/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/configs/config_use_file_transfer.json b/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/configs/config_use_file_transfer.json new file mode 100644 index 000000000000..7ad79493635d --- /dev/null +++ b/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/configs/config_use_file_transfer.json @@ -0,0 +1,55 @@ +{ + "delivery_method": { "delivery_type": "use_file_transfer" }, + "host": "localhost", + "port": 2222, + "username": "foo", + "credentials": { + "auth_type": "password", + "password": "pass" + }, + "file_type": "json", + "start_date": "2021-01-01T00:00:00.000000Z", + "folder_path": "/files", + "streams": [ + { + "name": "test_stream", + "file_type": "csv", + "globs": ["**/file_transfer_1.csv"], + "legacy_prefix": "", + "validation_policy": "Emit Record", + "format": { + "filetype": "csv", + "delimiter": ",", + "quote_char": "\"", + "double_quote": true, + "null_values": [ + "", + "#N/A", + "#N/A N/A", + "#NA", + "-1.#IND", + "-1.#QNAN", + "-NaN", + "-nan", + "1.#IND", + "1.#QNAN", + "N/A", + "NA", + "NULL", + "NaN", + "n/a", + "nan", + "null" + ], + "true_values": ["1", "True", "TRUE", "true"], + "false_values": ["0", "False", "FALSE", "false"], + "inference_type": "Primitive Types Only", + "strings_can_be_null": false, + "encoding": "utf8", + "header_definition": { + "header_definition_type": "From CSV" + } + } + } + ] +} diff --git a/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/conftest.py b/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/conftest.py index 9096df7aeeab..fb90225ddeb1 100644 --- a/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/conftest.py +++ b/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/conftest.py @@ -6,16 +6,20 @@ import shutil import time import uuid +import zipfile from io import StringIO +from pathlib import Path from typing import Any, Mapping, Tuple import docker import paramiko import pytest + from airbyte_cdk import AirbyteStream, ConfiguredAirbyteCatalog, ConfiguredAirbyteStream, DestinationSyncMode, SyncMode from .utils import get_docker_ip, load_config + logger = logging.getLogger("airbyte") PRIVATE_KEY = str() @@ -36,6 +40,33 @@ def docker_client() -> docker.client.DockerClient: return docker.from_env() +def prepare_test_files(tmp_path: str | Path): + """ + Fixture to prepare test files by unzipping a base CSV file and replicating it with different names. + """ + tmp_path = Path(tmp_path) + base_zip_path = tmp_path / "file_transfer/file_transfer_base.csv.zip" # Path to the pre-created ZIP file + extracted_path = tmp_path / "file_transfer" + os.makedirs(extracted_path, exist_ok=True) + + # Step 1: Extract the base CSV file from the ZIP archive + with zipfile.ZipFile(base_zip_path, "r") as zip_ref: + zip_ref.extractall(extracted_path) + + base_file_path = extracted_path / "file_transfer_base.csv" + file_names = [ + "file_transfer_1.csv", + "file_transfer_2.csv", + "file_transfer_3.csv", + "file_transfer_4.csv", + "file_transfer_5.csv", + ] + + # Step 2: Create duplicates with different names + for file_name in file_names: + shutil.copy(base_file_path, extracted_path / file_name) + + @pytest.fixture(scope="session", autouse=True) def connector_setup_fixture(docker_client) -> None: ssh_path = TMP_FOLDER + "/ssh" @@ -44,6 +75,7 @@ def connector_setup_fixture(docker_client) -> None: shutil.rmtree(TMP_FOLDER) shutil.copytree(f"{dir_path}/files", TMP_FOLDER) + prepare_test_files(TMP_FOLDER) os.makedirs(ssh_path) private_key, public_key = generate_ssh_keys() global PRIVATE_KEY @@ -78,6 +110,20 @@ def config_fixture(docker_client) -> Mapping[str, Any]: yield config +@pytest.fixture(name="config_fixture_use_file_transfer", scope="session") +def config_fixture_use_file_transfer(docker_client) -> Mapping[str, Any]: + config = load_config("config_use_file_transfer.json") + config["host"] = get_docker_ip() + yield config + + +@pytest.fixture(name="config_fixture_use_all_files_transfer", scope="session") +def config_fixture_use_all_files_transfer(docker_client) -> Mapping[str, Any]: + config = load_config("config_use_all_files_transfer.json") + config["host"] = get_docker_ip() + yield config + + @pytest.fixture(name="config_private_key", scope="session") def config_fixture_private_key(docker_client) -> Mapping[str, Any]: config = load_config("config_private_key.json") | { diff --git a/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/files/file_transfer/file_transfer_base.csv.zip b/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/files/file_transfer/file_transfer_base.csv.zip new file mode 100644 index 000000000000..68572d6e1f42 Binary files /dev/null and b/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/files/file_transfer/file_transfer_base.csv.zip differ diff --git a/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/integration_test.py b/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/integration_test.py index 457c91552c75..1eb360614d76 100644 --- a/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/integration_test.py +++ b/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/integration_test.py @@ -4,14 +4,18 @@ import logging +import os from copy import deepcopy from typing import Any, Mapping +from unittest.mock import ANY import pytest +from source_sftp_bulk import SourceSFTPBulk + from airbyte_cdk import AirbyteTracedException, ConfiguredAirbyteCatalog, Status from airbyte_cdk.sources.declarative.models import FailureType from airbyte_cdk.test.entrypoint_wrapper import read -from source_sftp_bulk import SourceSFTPBulk + logger = logging.getLogger("airbyte") @@ -90,3 +94,42 @@ def test_get_files_empty_files(configured_catalog: ConfiguredAirbyteCatalog, con source = SourceSFTPBulk(catalog=configured_catalog, config=config_with_wrong_glob_pattern, state=None) output = read(source=source, config=config_with_wrong_glob_pattern, catalog=configured_catalog) assert len(output.records) == 0 + + +@pytest.mark.slow +@pytest.mark.limit_memory("10 MB") +def test_get_file_csv_file_transfer(configured_catalog: ConfiguredAirbyteCatalog, config_fixture_use_file_transfer: Mapping[str, Any]): + source = SourceSFTPBulk(catalog=configured_catalog, config=config_fixture_use_file_transfer, state=None) + output = read(source=source, config=config_fixture_use_file_transfer, catalog=configured_catalog) + expected_file_data = { + "bytes": 46_754_266, + "file_relative_path": "files/file_transfer/file_transfer_1.csv", + "file_url": "/tmp/airbyte-file-transfer/files/file_transfer/file_transfer_1.csv", + "modified": ANY, + "source_file_url": "/files/file_transfer/file_transfer_1.csv", + } + assert len(output.records) == 1 + assert list(map(lambda record: record.record.file, output.records)) == [expected_file_data] + + # Additional assertion to check if the file exists at the file_url path + file_path = expected_file_data["file_url"] + assert os.path.exists(file_path), f"File not found at path: {file_path}" + + +@pytest.mark.slow +@pytest.mark.limit_memory("10 MB") +def test_get_all_file_csv_file_transfer( + configured_catalog: ConfiguredAirbyteCatalog, config_fixture_use_all_files_transfer: Mapping[str, Any] +): + """ + - The Paramiko dependency `get` method uses requests parallelization for efficiency, which may slightly increase memory usage. + - The test asserts that this memory increase remains below the files sizes being transferred. + """ + source = SourceSFTPBulk(catalog=configured_catalog, config=config_fixture_use_all_files_transfer, state=None) + output = read(source=source, config=config_fixture_use_all_files_transfer, catalog=configured_catalog) + assert len(output.records) == 5 + total_bytes = sum(list(map(lambda record: record.record.file["bytes"], output.records))) + files_paths = list(map(lambda record: record.record.file["file_url"], output.records)) + for file_path in files_paths: + assert os.path.exists(file_path), f"File not found at path: {file_path}" + assert total_bytes == 233_771_330 diff --git a/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/spec.json b/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/spec.json index 3ef3def86065..eef7da5cce32 100644 --- a/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/spec.json +++ b/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/spec.json @@ -430,6 +430,46 @@ "required": ["name", "format"] } }, + "delivery_method": { + "title": "Delivery Method", + "default": "use_records_transfer", + "type": "object", + "order": 7, + "display_type": "radio", + "group": "advanced", + "oneOf": [ + { + "title": "Replicate Records", + "type": "object", + "properties": { + "delivery_type": { + "title": "Delivery Type", + "default": "use_records_transfer", + "const": "use_records_transfer", + "enum": ["use_records_transfer"], + "type": "string" + } + }, + "description": "Recommended - Extract and load structured records into your destination of choice. This is the classic method of moving data in Airbyte. It allows for blocking and hashing individual fields or files from a structured schema. Data can be flattened, typed and deduped depending on the destination.", + "required": ["delivery_type"] + }, + { + "title": "Copy Raw Files", + "type": "object", + "properties": { + "delivery_type": { + "title": "Delivery Type", + "default": "use_file_transfer", + "const": "use_file_transfer", + "enum": ["use_file_transfer"], + "type": "string" + } + }, + "description": "Copy raw files without parsing their contents. Bits are copied into the destination exactly as they appeared in the source. Recommended for use with unstructured text data, non-text and compressed files.", + "required": ["delivery_type"] + } + ] + }, "host": { "title": "Host Address", "description": "The server host address", @@ -484,6 +524,7 @@ "private_key": { "title": "Private key", "description": "The Private key", + "airbyte_secret": true, "multiline": true, "order": 4, "type": "string" diff --git a/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/utils.py b/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/utils.py index db92623c2998..390cb801cdb7 100644 --- a/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/utils.py +++ b/airbyte-integrations/connectors/source-sftp-bulk/integration_tests/utils.py @@ -7,6 +7,7 @@ import re from typing import Any, Mapping, Union + logger = logging.getLogger("airbyte") TMP_FOLDER = "/tmp/test_sftp_source" diff --git a/airbyte-integrations/connectors/source-sftp-bulk/main.py b/airbyte-integrations/connectors/source-sftp-bulk/main.py index 9129b1995968..f2799e1acdf7 100644 --- a/airbyte-integrations/connectors/source-sftp-bulk/main.py +++ b/airbyte-integrations/connectors/source-sftp-bulk/main.py @@ -5,5 +5,6 @@ from source_sftp_bulk.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-sftp-bulk/metadata.yaml b/airbyte-integrations/connectors/source-sftp-bulk/metadata.yaml index 0ad31fa8aed1..42babf16651e 100644 --- a/airbyte-integrations/connectors/source-sftp-bulk/metadata.yaml +++ b/airbyte-integrations/connectors/source-sftp-bulk/metadata.yaml @@ -7,7 +7,7 @@ data: connectorSubtype: file connectorType: source definitionId: 31e3242f-dee7-4cdc-a4b8-8e06c5458517 - dockerImageTag: 1.2.0 + dockerImageTag: 1.6.0 dockerRepository: airbyte/source-sftp-bulk documentationUrl: https://docs.airbyte.com/integrations/sources/sftp-bulk githubIssueLabel: source-sftp-bulk @@ -30,6 +30,7 @@ data: message: "This upgrade migrates the SFTP Bulk source to the Airbyte file-based CDK. This is the first necessary step of transitioning a file connector from community to Airbyte maintained." upgradeDeadline: "2024-04-30" supportLevel: community + supportsFileTransfer: true tags: - language:python - cdk:python-file-based diff --git a/airbyte-integrations/connectors/source-sftp-bulk/poetry.lock b/airbyte-integrations/connectors/source-sftp-bulk/poetry.lock index 590621de9985..916a10f15d87 100644 --- a/airbyte-integrations/connectors/source-sftp-bulk/poetry.lock +++ b/airbyte-integrations/connectors/source-sftp-bulk/poetry.lock @@ -2,13 +2,13 @@ [[package]] name = "airbyte-cdk" -version = "5.10.1" +version = "6.6.7" description = "A framework for writing Airbyte Connectors." optional = false -python-versions = "<4.0,>=3.10" +python-versions = "<3.13,>=3.10" files = [ - {file = "airbyte_cdk-5.10.1-py3-none-any.whl", hash = "sha256:b965f38b28b303a8c85da29f80d9669c086cf0c502b919793b5cf66300d81997"}, - {file = "airbyte_cdk-5.10.1.tar.gz", hash = "sha256:9f100bf3da49aa087f11c9e42d9cc16801d232823a0c587eaf497e9fc7946c5a"}, + {file = "airbyte_cdk-6.6.7-py3-none-any.whl", hash = "sha256:4f6ffe4ff06f6b6aa35684ba662b3a43f28c307a692f06bd0425fd78afdf2920"}, + {file = "airbyte_cdk-6.6.7.tar.gz", hash = "sha256:fe275743460734d2a1c88af3013abcad2d5f484a8db5dd423ffbdee8154e4daf"}, ] [package.dependencies] @@ -16,23 +16,26 @@ airbyte-protocol-models-dataclasses = ">=0.13,<0.14" avro = {version = ">=1.11.2,<1.12.0", optional = true, markers = "extra == \"file-based\""} backoff = "*" cachetools = "*" -cryptography = ">=42.0.5,<43.0.0" +cryptography = ">=42.0.5,<44.0.0" Deprecated = ">=1.2,<1.3" dpath = ">=2.1.6,<3.0.0" +dunamai = ">=1.22.0,<2.0.0" fastavro = {version = ">=1.8.0,<1.9.0", optional = true, markers = "extra == \"file-based\""} -genson = "1.2.2" +genson = "1.3.0" isodate = ">=0.6.1,<0.7.0" Jinja2 = ">=3.1.2,<3.2.0" jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" +jsonschema = ">=4.17.3,<4.18.0" langchain_core = "0.1.42" markdown = {version = "*", optional = true, markers = "extra == \"file-based\""} -nltk = "3.8.1" +nltk = "3.9.1" +numpy = "<2" orjson = ">=3.10.7,<4.0.0" pandas = "2.2.2" pdf2image = {version = "1.16.3", optional = true, markers = "extra == \"file-based\""} "pdfminer.six" = {version = "20221105", optional = true, markers = "extra == \"file-based\""} pendulum = "<3.0.0" +psutil = "6.1.0" pyarrow = {version = ">=15.0.0,<15.1.0", optional = true, markers = "extra == \"file-based\""} pydantic = ">=2.7,<3.0" pyjwt = ">=2.8.0,<3.0.0" @@ -41,29 +44,33 @@ pytesseract = {version = "0.3.10", optional = true, markers = "extra == \"file-b python-calamine = {version = "0.2.3", optional = true, markers = "extra == \"file-based\""} python-dateutil = "*" python-snappy = {version = "0.7.3", optional = true, markers = "extra == \"file-based\""} +python-ulid = ">=3.0.0,<4.0.0" pytz = "2024.1" PyYAML = ">=6.0.1,<7.0.0" +rapidfuzz = ">=3.10.1,<4.0.0" requests = "*" requests_cache = "*" serpyco-rs = ">=1.10.2,<2.0.0" unstructured = {version = "0.10.27", extras = ["docx", "pptx"], optional = true, markers = "extra == \"file-based\""} "unstructured.pytesseract" = {version = ">=0.3.12", optional = true, markers = "extra == \"file-based\""} -wcmatch = "8.4" +wcmatch = "10.0" +xmltodict = ">=0.13.0,<0.14.0" [package.extras] file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "python-snappy (==0.7.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] +sql = ["sqlalchemy (>=2.0,!=2.0.36,<3.0)"] +vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.8.0)"] [[package]] name = "airbyte-protocol-models-dataclasses" -version = "0.13.0" +version = "0.13.1" description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models_dataclasses-0.13.0-py3-none-any.whl", hash = "sha256:0aedb99ffc4f9aab0ce91bba2c292fa17cd8fd4b42eeba196d6a16c20bbbd7a5"}, - {file = "airbyte_protocol_models_dataclasses-0.13.0.tar.gz", hash = "sha256:72e67850d661e2808406aec5839b3158ebb94d3553b798dbdae1b4a278548d2f"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1-py3-none-any.whl", hash = "sha256:20a734b7b1c3479a643777830db6a2e0a34428f33d16abcfd320552576fabe5a"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1.tar.gz", hash = "sha256:ec6a0fb6b16267bde910f52279445d06c8e1a3e4ed82ac2937b405ab280449d5"}, ] [[package]] @@ -79,13 +86,13 @@ files = [ [[package]] name = "anyio" -version = "4.6.0" +version = "4.6.2.post1" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.0-py3-none-any.whl", hash = "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a"}, - {file = "anyio-4.6.0.tar.gz", hash = "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb"}, + {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, + {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, ] [package.dependencies] @@ -96,19 +103,9 @@ typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} [package.extras] doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.21.0b1)"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] trio = ["trio (>=0.26.1)"] -[[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, -] - [[package]] name = "attributes-doc" version = "0.4.0" @@ -166,38 +163,36 @@ files = [ [[package]] name = "bcrypt" -version = "4.2.0" +version = "4.2.1" description = "Modern password hashing for your software and your servers" optional = false python-versions = ">=3.7" files = [ - {file = "bcrypt-4.2.0-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:096a15d26ed6ce37a14c1ac1e48119660f21b24cba457f160a4b830f3fe6b5cb"}, - {file = "bcrypt-4.2.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c02d944ca89d9b1922ceb8a46460dd17df1ba37ab66feac4870f6862a1533c00"}, - {file = "bcrypt-4.2.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d84cf6d877918620b687b8fd1bf7781d11e8a0998f576c7aa939776b512b98d"}, - {file = "bcrypt-4.2.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:1bb429fedbe0249465cdd85a58e8376f31bb315e484f16e68ca4c786dcc04291"}, - {file = "bcrypt-4.2.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:655ea221910bcac76ea08aaa76df427ef8625f92e55a8ee44fbf7753dbabb328"}, - {file = "bcrypt-4.2.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:1ee38e858bf5d0287c39b7a1fc59eec64bbf880c7d504d3a06a96c16e14058e7"}, - {file = "bcrypt-4.2.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:0da52759f7f30e83f1e30a888d9163a81353ef224d82dc58eb5bb52efcabc399"}, - {file = "bcrypt-4.2.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3698393a1b1f1fd5714524193849d0c6d524d33523acca37cd28f02899285060"}, - {file = "bcrypt-4.2.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:762a2c5fb35f89606a9fde5e51392dad0cd1ab7ae64149a8b935fe8d79dd5ed7"}, - {file = "bcrypt-4.2.0-cp37-abi3-win32.whl", hash = "sha256:5a1e8aa9b28ae28020a3ac4b053117fb51c57a010b9f969603ed885f23841458"}, - {file = "bcrypt-4.2.0-cp37-abi3-win_amd64.whl", hash = "sha256:8f6ede91359e5df88d1f5c1ef47428a4420136f3ce97763e31b86dd8280fbdf5"}, - {file = "bcrypt-4.2.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:c52aac18ea1f4a4f65963ea4f9530c306b56ccd0c6f8c8da0c06976e34a6e841"}, - {file = "bcrypt-4.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3bbbfb2734f0e4f37c5136130405332640a1e46e6b23e000eeff2ba8d005da68"}, - {file = "bcrypt-4.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3413bd60460f76097ee2e0a493ccebe4a7601918219c02f503984f0a7ee0aebe"}, - {file = "bcrypt-4.2.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:8d7bb9c42801035e61c109c345a28ed7e84426ae4865511eb82e913df18f58c2"}, - {file = "bcrypt-4.2.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3d3a6d28cb2305b43feac298774b997e372e56c7c7afd90a12b3dc49b189151c"}, - {file = "bcrypt-4.2.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:9c1c4ad86351339c5f320ca372dfba6cb6beb25e8efc659bedd918d921956bae"}, - {file = "bcrypt-4.2.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:27fe0f57bb5573104b5a6de5e4153c60814c711b29364c10a75a54bb6d7ff48d"}, - {file = "bcrypt-4.2.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:8ac68872c82f1add6a20bd489870c71b00ebacd2e9134a8aa3f98a0052ab4b0e"}, - {file = "bcrypt-4.2.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:cb2a8ec2bc07d3553ccebf0746bbf3d19426d1c6d1adbd4fa48925f66af7b9e8"}, - {file = "bcrypt-4.2.0-cp39-abi3-win32.whl", hash = "sha256:77800b7147c9dc905db1cba26abe31e504d8247ac73580b4aa179f98e6608f34"}, - {file = "bcrypt-4.2.0-cp39-abi3-win_amd64.whl", hash = "sha256:61ed14326ee023917ecd093ee6ef422a72f3aec6f07e21ea5f10622b735538a9"}, - {file = "bcrypt-4.2.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:39e1d30c7233cfc54f5c3f2c825156fe044efdd3e0b9d309512cc514a263ec2a"}, - {file = "bcrypt-4.2.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f4f4acf526fcd1c34e7ce851147deedd4e26e6402369304220250598b26448db"}, - {file = "bcrypt-4.2.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:1ff39b78a52cf03fdf902635e4c81e544714861ba3f0efc56558979dd4f09170"}, - {file = "bcrypt-4.2.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:373db9abe198e8e2c70d12b479464e0d5092cc122b20ec504097b5f2297ed184"}, - {file = "bcrypt-4.2.0.tar.gz", hash = "sha256:cf69eaf5185fd58f268f805b505ce31f9b9fc2d64b376642164e9244540c1221"}, + {file = "bcrypt-4.2.1-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:1340411a0894b7d3ef562fb233e4b6ed58add185228650942bdc885362f32c17"}, + {file = "bcrypt-4.2.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ee315739bc8387aa36ff127afc99120ee452924e0df517a8f3e4c0187a0f5f"}, + {file = "bcrypt-4.2.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dbd0747208912b1e4ce730c6725cb56c07ac734b3629b60d4398f082ea718ad"}, + {file = "bcrypt-4.2.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:aaa2e285be097050dba798d537b6efd9b698aa88eef52ec98d23dcd6d7cf6fea"}, + {file = "bcrypt-4.2.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:76d3e352b32f4eeb34703370e370997065d28a561e4a18afe4fef07249cb4396"}, + {file = "bcrypt-4.2.1-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:b7703ede632dc945ed1172d6f24e9f30f27b1b1a067f32f68bf169c5f08d0425"}, + {file = "bcrypt-4.2.1-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:89df2aea2c43be1e1fa066df5f86c8ce822ab70a30e4c210968669565c0f4685"}, + {file = "bcrypt-4.2.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:04e56e3fe8308a88b77e0afd20bec516f74aecf391cdd6e374f15cbed32783d6"}, + {file = "bcrypt-4.2.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:cfdf3d7530c790432046c40cda41dfee8c83e29482e6a604f8930b9930e94139"}, + {file = "bcrypt-4.2.1-cp37-abi3-win32.whl", hash = "sha256:adadd36274510a01f33e6dc08f5824b97c9580583bd4487c564fc4617b328005"}, + {file = "bcrypt-4.2.1-cp37-abi3-win_amd64.whl", hash = "sha256:8c458cd103e6c5d1d85cf600e546a639f234964d0228909d8f8dbeebff82d526"}, + {file = "bcrypt-4.2.1-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:8ad2f4528cbf0febe80e5a3a57d7a74e6635e41af1ea5675282a33d769fba413"}, + {file = "bcrypt-4.2.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:909faa1027900f2252a9ca5dfebd25fc0ef1417943824783d1c8418dd7d6df4a"}, + {file = "bcrypt-4.2.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cde78d385d5e93ece5479a0a87f73cd6fa26b171c786a884f955e165032b262c"}, + {file = "bcrypt-4.2.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:533e7f3bcf2f07caee7ad98124fab7499cb3333ba2274f7a36cf1daee7409d99"}, + {file = "bcrypt-4.2.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:687cf30e6681eeda39548a93ce9bfbb300e48b4d445a43db4298d2474d2a1e54"}, + {file = "bcrypt-4.2.1-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:041fa0155c9004eb98a232d54da05c0b41d4b8e66b6fc3cb71b4b3f6144ba837"}, + {file = "bcrypt-4.2.1-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f85b1ffa09240c89aa2e1ae9f3b1c687104f7b2b9d2098da4e923f1b7082d331"}, + {file = "bcrypt-4.2.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c6f5fa3775966cca251848d4d5393ab016b3afed251163c1436fefdec3b02c84"}, + {file = "bcrypt-4.2.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:807261df60a8b1ccd13e6599c779014a362ae4e795f5c59747f60208daddd96d"}, + {file = "bcrypt-4.2.1-cp39-abi3-win32.whl", hash = "sha256:b588af02b89d9fad33e5f98f7838bf590d6d692df7153647724a7f20c186f6bf"}, + {file = "bcrypt-4.2.1-cp39-abi3-win_amd64.whl", hash = "sha256:e84e0e6f8e40a242b11bce56c313edc2be121cec3e0ec2d76fce01f6af33c07c"}, + {file = "bcrypt-4.2.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:76132c176a6d9953cdc83c296aeaed65e1a708485fd55abf163e0d9f8f16ce0e"}, + {file = "bcrypt-4.2.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e158009a54c4c8bc91d5e0da80920d048f918c61a581f0a63e4e93bb556d362f"}, + {file = "bcrypt-4.2.1.tar.gz", hash = "sha256:6765386e3ab87f569b276988742039baab087b2cdb01e809d74e74503c2faafe"}, ] [package.extras] @@ -376,101 +371,116 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.3.2" +version = "3.4.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, + {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, + {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, ] [[package]] @@ -500,101 +510,101 @@ files = [ [[package]] name = "cramjam" -version = "2.8.4" +version = "2.9.0" description = "Thin Python bindings to de/compression algorithms in Rust" optional = false python-versions = ">=3.8" files = [ - {file = "cramjam-2.8.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:e9e112514363261a896f85948d5d055dccaab2a1fa77d440f55030464118a95a"}, - {file = "cramjam-2.8.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ee2441028e813ecc1d10b90640dd2b9649cdefdfe80af1d838cf00fd935ee5e7"}, - {file = "cramjam-2.8.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:86a3e0f91176eacd23f8d63b01139a63687cb3fa9670996b3bfa7c38eac6cb7e"}, - {file = "cramjam-2.8.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e34aa083a10079c8814091c0fe9080238a82569fa08058cf79d12b3f9710fc5"}, - {file = "cramjam-2.8.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:465ccf470536e065822daa2a083dedf18df8133278e9132b147bd1721211d707"}, - {file = "cramjam-2.8.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30aba9e9c737c986d26a809b9e36628452c075234a5e835b085ab7c2b9574dc"}, - {file = "cramjam-2.8.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:52f710bd7fa9b5a374e2e2281d7d672f9eb89263c531643f95fab93e98200c68"}, - {file = "cramjam-2.8.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6622095ffa6cae77c9e8036a39757fdb1d3cabc3444ad892e5a705882ed06c8d"}, - {file = "cramjam-2.8.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bc618c018594c20696a42faf8a144e1508b8a4312e0d8697f6c64b337e37e5d9"}, - {file = "cramjam-2.8.4-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:30c75259f58583f96ad9cef7202c70cd6604a9dabf9834211df48a27ec85f84a"}, - {file = "cramjam-2.8.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:2b9b4bbe7ef3318b2f2aed2a8a658b401a9ad9314d50372f9bb97cdef093f326"}, - {file = "cramjam-2.8.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d7a7c10fb2602d7c8c4dbe4eeacf352477cc1af939fd3537f4e1cd42526855b8"}, - {file = "cramjam-2.8.4-cp310-none-win32.whl", hash = "sha256:831ee2424b095f51c9719b0479d9b413bc849e47160b904a7a8e4a8dcf41d2f7"}, - {file = "cramjam-2.8.4-cp310-none-win_amd64.whl", hash = "sha256:4f6bf5752a0322cc63f955343c390253034b609d167930584bb392bf4179c444"}, - {file = "cramjam-2.8.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d48fd69224a2f4df187856021f545a65486575cba92bb32a14ccad1ce54584a9"}, - {file = "cramjam-2.8.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c53d8dce609607370f01a5db65c79db75db08e9e89cbb9c2a2212b7a3c0b8af3"}, - {file = "cramjam-2.8.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d08b8ff282545ab3a414db845e430320555ff7a7eb90517b2c9554e24ca0d763"}, - {file = "cramjam-2.8.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac5fb30cf6c03f72397ead8584592dc071f486c76199c46c28e7de619174ba1f"}, - {file = "cramjam-2.8.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0d86cfb2b457a337db4b7c8cf6a9dafc018806750f28b3c27d71b94e2d4379d0"}, - {file = "cramjam-2.8.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59565a16ce0c71993d3947bdf9301e0d69866c15f37d67d2875809eca998d841"}, - {file = "cramjam-2.8.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6741544b372ba3e6c65db1c44b1a75e48743d091b76a09d7d832b1fb0a0ef518"}, - {file = "cramjam-2.8.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5f486bacd46f364137f5b164a879821115118d7f866a838429eb10aee59a14b"}, - {file = "cramjam-2.8.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4e02081bfb9998f5ff816f3e984a62ca91835e3483c578812374aaf5cb6ed921"}, - {file = "cramjam-2.8.4-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:1c63e856727726a1ee2a77a12bfccfcd70ee3e5bbe9e6d07bd00be5a1eb6ec10"}, - {file = "cramjam-2.8.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:74fb59137946b691e8987349e9117e2897f3b0484116ad6e2b1b4de0d082430f"}, - {file = "cramjam-2.8.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c7952e0cd6f37a04983cb027175f91f225d7c30625038b8930b6fd3f00619350"}, - {file = "cramjam-2.8.4-cp311-none-win32.whl", hash = "sha256:2bfd5c442e6031b146a93b1cc37d42c04b6d01bb652c9f123338c482c3943038"}, - {file = "cramjam-2.8.4-cp311-none-win_amd64.whl", hash = "sha256:73c95cae138bc8f5604bbbc97860f158c4f77e046304dd4f9c9838021d64217a"}, - {file = "cramjam-2.8.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:5056f476917d31c69719883bbe12272288b77ab5ea5ee55fbcbb6c0dd10e52da"}, - {file = "cramjam-2.8.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8359d31dca4bd8286e031f1a21f20f62f4e7a4586c407e916fd2de101c719a8b"}, - {file = "cramjam-2.8.4-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a1aee32556b9f7ecc61c6c4675798153ac511b5b72db9f56d2a8c20c1fa6d563"}, - {file = "cramjam-2.8.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:005bfe79ae38ea1df67fd3079089287640c780bf112aab4b6a3a9f12f0bf3c91"}, - {file = "cramjam-2.8.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51662c79c5a2256824f3acca9ccdbeaad3626c90ae46a19ef25f186d70a9ac69"}, - {file = "cramjam-2.8.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c744148e33002cefd4aaa3641800c0008fa177c8c09230c09d30d6e7ab473a4"}, - {file = "cramjam-2.8.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c897d2443cf9f3685a51ecc28c669aad95b6a610de7883647fe450cc742e2ea7"}, - {file = "cramjam-2.8.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:741b0c29d701d470243b9cad09a3e21c2ab83190710df680fd84baea1b262089"}, - {file = "cramjam-2.8.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4cfc6d838afb90a59d2c721fe8d78c2a333edf5c370b3ce8f9823c49bc52e5d0"}, - {file = "cramjam-2.8.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:977e380a567f1bcdb0f1156820fedc57727c6c639769b846b39ad7fc1be5563b"}, - {file = "cramjam-2.8.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3f16dea7f430bb8a5cf2e2a8eece5fa7a6e58bffae3913083f6c20de50ce85bd"}, - {file = "cramjam-2.8.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d25c2ff722e66a55c58b6c325985b2bf342a6592db084557c2956a07d7179d7"}, - {file = "cramjam-2.8.4-cp312-none-win32.whl", hash = "sha256:b63bcf4e5f9c6ee027947a22862d054e8ce0fa189a33ccdb07e66ef09291252c"}, - {file = "cramjam-2.8.4-cp312-none-win_amd64.whl", hash = "sha256:72b9d4c29a51a8656690df2ef6f7823fa27ebc35e051182b6ebef5fef180876f"}, - {file = "cramjam-2.8.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:9b00949104594eb2b6daf9ec72f1a6dfc93968bc0ffbdbfee936c359fc782186"}, - {file = "cramjam-2.8.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:24b29d805e860d22499e6f5d004582477f3c8309e2a899e0c86c1530a94e6092"}, - {file = "cramjam-2.8.4-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f9454207624a701cb518fbef137e2eb6088aaf5606679aa6ab28d2dd06d72702"}, - {file = "cramjam-2.8.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ee580acb4b6af5ae211b80b679aa377ffa9f9ff74a1e9de458c09d19bce4433"}, - {file = "cramjam-2.8.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:157c36731e430670be44ba490b8a0e4fc04ebdd78c3ea19339ba4ac24d73ad25"}, - {file = "cramjam-2.8.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30a12b1437e28b5e72ab10642d214e9b42220e8c5be2948ac6916aca203f69b0"}, - {file = "cramjam-2.8.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:553e2cd4c2614510770ff3a8bf6b72957a86985b1ae2b8fcdc6d04848857313f"}, - {file = "cramjam-2.8.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e40e448d50fa7c2b79c06d99459ad4a77d58d9cfb3f0549a63b91179a5e57c0b"}, - {file = "cramjam-2.8.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:769995dfc7fd042ce123f25e7659977ed4aa4d5d6aad976970b12b9b4019c116"}, - {file = "cramjam-2.8.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:1ba26f563d9e5be588c8e5f5523b4cdb5b63e3ac3fb28857af9611eb5ea51416"}, - {file = "cramjam-2.8.4-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:5cbfd6c44c85216b3535095258b506f6e246c6fbf1438a79f71bcff4d98f7e3f"}, - {file = "cramjam-2.8.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:4bf4e8711b27604b3ca7e7c224a70f5abe94f5bf05a183bd97677e9cffd2be04"}, - {file = "cramjam-2.8.4-cp313-none-win32.whl", hash = "sha256:7c9ca8e6c33c06c08e9945a20fe0f64a2bcd363554e359a2936b3a469883630a"}, - {file = "cramjam-2.8.4-cp313-none-win_amd64.whl", hash = "sha256:ee92df7e66b7cbdb05b18687a42696bc729bacaad0d68f5549e30cbfa1eb0ca8"}, - {file = "cramjam-2.8.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:386eb0fe9567ae3c06e2053205e19e671e4170f3a0deb68dd103e4c651a3ff8b"}, - {file = "cramjam-2.8.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:64e22027874ce429ce04c0c9d19e6bed5bf6425ecc3e68752211b8509915c57c"}, - {file = "cramjam-2.8.4-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b74470fb215a3ac2e6ed968f671286456030882aa25616b969b1a52ebda4f29d"}, - {file = "cramjam-2.8.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c41d4542cc2c7238017caebc161b0866b3fb5e85e59727ab623f95e07abc453"}, - {file = "cramjam-2.8.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:14b6f2f883068873bd2b5c31fbf7c4223c0452b8bff662bec02d7973a095c46b"}, - {file = "cramjam-2.8.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d5921c4521d41fb125d31ce1fe9e5bfba24a2577bc8727289baae9afbebc8409"}, - {file = "cramjam-2.8.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb62855f17be5d1bec0d3cef89d8d54582137529c7ea96480c40ebb4a8c92c4b"}, - {file = "cramjam-2.8.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91cd4b28fc75680616bd22db5a56802ce7ce406052c58e72fd583a16746a1010"}, - {file = "cramjam-2.8.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f03502eaf1a0a95cdcbf4c6ebba5edfaa68d356f487ec8485ae651772c9426f9"}, - {file = "cramjam-2.8.4-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:bb5e23c1f8dc2b4cddc7982da60d2f7a9719920539c26e7b754f2272f510fc0c"}, - {file = "cramjam-2.8.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ef6b0d4c83b173d18398713522bff1db1e4e73ec3b3da6495afc5628767d6c85"}, - {file = "cramjam-2.8.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b2253287a08759cefb75ef46ebaa0f993a2890a31fe9bba94363ca245f42d821"}, - {file = "cramjam-2.8.4-cp38-none-win32.whl", hash = "sha256:8375090e54978ccbb1d90e494d73d09e36477e0d695ddadf2d13627168862950"}, - {file = "cramjam-2.8.4-cp38-none-win_amd64.whl", hash = "sha256:12100dd3ed6969365d1952832e39c017d97c85eeb517ae468092f67aa4d89568"}, - {file = "cramjam-2.8.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:47c1594346dceb0d363d479ddac1e9ff87596c92e5258b389118ae6e30599145"}, - {file = "cramjam-2.8.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5472f9c6db34046c7ab2f0c4be5a4be677dba98bf78cc0eb03f9812e5774f14d"}, - {file = "cramjam-2.8.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9bfa940e016bfeea2b93115abf9e4e455a6325dd85a3fa6af55c6052f070ba25"}, - {file = "cramjam-2.8.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24e738a92ac520b26b952bfc48b1ba6453ea455e20167f08f6ee3df5c7d22cd4"}, - {file = "cramjam-2.8.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:78ded70e85722a6dcd0c436193af58a43083f0ece35c1f74227782a28e517aa0"}, - {file = "cramjam-2.8.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99b024a9912a5fd3b4e6b949b83b291e2828775edc0595ef8b94c491e904287b"}, - {file = "cramjam-2.8.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:673dc6395fed94db59fb75a7657d8b061bd575332d8f15025e7b1a4feaba0a3f"}, - {file = "cramjam-2.8.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4b8f83c5a98fecf44c6d852a9bd30ab1508e51d910dc9c8e636863d131fd5eb"}, - {file = "cramjam-2.8.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:85eada9385a706d8d0f6cb1d51995f5eef16d3cade7e68150d6e441fd26406da"}, - {file = "cramjam-2.8.4-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:2429134bb2ee8fffe28f41e3f5390be9c539ac1e2c453034ea63542d7aacc5cc"}, - {file = "cramjam-2.8.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e90003b2ce00358ee669afa0710bf52dee6827460b80ce4a7a9f906551ab703a"}, - {file = "cramjam-2.8.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d0619af45310cceeab9a2410d4a14445743e494015d85584b974847bfb2a2011"}, - {file = "cramjam-2.8.4-cp39-none-win32.whl", hash = "sha256:a30d68094462076655259feee1187237af846969007e5341a96c79b447c47ab3"}, - {file = "cramjam-2.8.4-cp39-none-win_amd64.whl", hash = "sha256:f24e375dfb31f0953e236f2cc4af1b03b80d40aec2bc558df48d507d8e7c8d96"}, - {file = "cramjam-2.8.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3536362f777d817c4994d6eaa42e00e705092c5660fd3d9984f3b0cc6164d327"}, - {file = "cramjam-2.8.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:0d52eabd20a694636f5b0197daa64db497ea518e057935a7c61ec71e92d3ccd6"}, - {file = "cramjam-2.8.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cf69f19ebd546fc155ec3098603de51f52bf620a23597810cb5b34d6aff116d"}, - {file = "cramjam-2.8.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:364258057d579c772e23e1f666fd7efec4f63ea2e791889bb18263c9e9e6aa91"}, - {file = "cramjam-2.8.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:98a2e2c3132b454ae47b194164bb8860464ed410fbbffc0d1de19452cc7cb402"}, - {file = "cramjam-2.8.4.tar.gz", hash = "sha256:ad8bec85b46283330214f4367805e6f56e04ce25a030a2c6a4b127437d006fcf"}, + {file = "cramjam-2.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:eb16d995e454b0155b166f6e6da7df4ac812d44e0f3b6dc0f344a934609fd5bc"}, + {file = "cramjam-2.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cb1e86bfea656b51f2e75f2cedb17fc08b552d105b814d19b595294ecbe94d8d"}, + {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4bd76b654275736fd4f55521981b73751c34dacf70a1dbce96e454a39d43201f"}, + {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21569f19d5848606b85ac0dde0dc3639319d26fed8522c7103515df875bcb300"}, + {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b8f8b1117b4e697d39950ecab01700ce0aef66541e4478eb4d7b3ade8703347b"}, + {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3464d0042a03e8ef38a2b774ef23163cf3c0cdc41b8dfbf7c4aadf93e40b459"}, + {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0711c776750e243ae347d6609c975f0ff4be9ae65b2764d29e4bbdad8e574c3a"}, + {file = "cramjam-2.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00d96f798bc980b29f8e1c3ed7d554050e05d4cde23d1633ffed4cd63110024a"}, + {file = "cramjam-2.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fc49b6575e3cb15da3180c5a3926ec81db33b109e48530708da76614b306904b"}, + {file = "cramjam-2.9.0-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:c4fa6c23e56d48df18f534af921ec936c812743a8972ecdd5e5ff47b464fea00"}, + {file = "cramjam-2.9.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b4b8d8160685c11ffb4e8e6daaab79cb351a1c54ceec41cc18a0a62c89309fe0"}, + {file = "cramjam-2.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0ed6362cb6c964f8d0c6e7f790e8961b9242cd3acd87c56169ca14d642653707"}, + {file = "cramjam-2.9.0-cp310-none-win32.whl", hash = "sha256:fe9af350dfbdc7ed4c93a8016a8ad7b5492fc116e7197cad7cbce99b434d3fe1"}, + {file = "cramjam-2.9.0-cp310-none-win_amd64.whl", hash = "sha256:37054c73704a3183b60869e7fec1614648752c31d89f44de1ffe1f01ad4d20d5"}, + {file = "cramjam-2.9.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:170a50407f9400073621cc1d5f3200ca3ad9de3000831e3e86f5561ca8048a08"}, + {file = "cramjam-2.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:912c94781c8ff318a4d3f3306f8d94d41ae5aa7b9760c4bb0476b01142084845"}, + {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:df089639983a03070be6eabc60317aa1ffbf2c5409023b57a5fc2e4975163bc4"}, + {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ca28a8f6ab5fca35f163fd7d7a970880ce4fc1a0bead1249ecdaa96ec9ac1f4"}, + {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:abd8bf9a94e3866215ac181a7dbcfa1ddbedca4f8048494a79934febe88537df"}, + {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7de19a382bcab93cd4d028d51f6f581920a3b79659a384775188135b7fc64f15"}, + {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a4156fcefa1dfaa65d35ff82c252d1e32be12820f26d04748be6cd3b461cf85f"}, + {file = "cramjam-2.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4a3104022129d7463100dfaf12efd398ebfa4b7e4e50832ccc596754f7c26df"}, + {file = "cramjam-2.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6ebee5f5d7e2b9277895ea4fd94646b72075fe9cfc0e8f4770b65c9e72b1fec1"}, + {file = "cramjam-2.9.0-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:8e33ebe4d709b21bc15e7ddf485ac6b30d7fdc7ed7c3c65130654c007f50c183"}, + {file = "cramjam-2.9.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4d5a39118008bb9f2fba36a0ceea6c41fbd0b55d2647b043ba51a868e5f6de92"}, + {file = "cramjam-2.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7f6ef35eba883927af2678b561cc4407e0b3b0d58a251c863bec4b3d8258cc2f"}, + {file = "cramjam-2.9.0-cp311-none-win32.whl", hash = "sha256:b21e55b5cfdaff96eae1f323ae9a0d36e86852cdf62fe23b60a2481d2fed5571"}, + {file = "cramjam-2.9.0-cp311-none-win_amd64.whl", hash = "sha256:9f685fe4e49b2f3e233548e3397b3f9189d71a265718ec631d13eca3d5718ddb"}, + {file = "cramjam-2.9.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:34578e4c1518b10dad5e0ba40c721e529ef13e7742a528843b40e1f20dd6078c"}, + {file = "cramjam-2.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1d5b5512dc61ea78f32e021e88a5fd5b46a821409479e6657d33614fc9e45677"}, + {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0b4f1b5e33915ed591c0c19b8c3bbdd7aa0f6a9bfe2b7246b475d497bda15f18"}, + {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad301801afa0eecdacabf353a2802df5e6770f9bfb0a559d6c069813d83cfd42"}, + {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:399baf80fea574e3870f233e12e6a12f02c53b054e13d792348b272b0614370a"}, + {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3121e2fbec58907fa70636adaeaf30c27614c867e08a7a5bd2887b33786ff790"}, + {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd04205b2a87087ffc2257c3ad33f11daabc053956f64ac1ec7bae299cac3f2f"}, + {file = "cramjam-2.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddb9c4db36188a8f08c2303100a83100f26a8572803ae35eadff359bebd3d204"}, + {file = "cramjam-2.9.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ef553d4080368006817c1a935ed619c71987cf10417a32386acc00c5418a2934"}, + {file = "cramjam-2.9.0-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:9862ca8ead80857ecfb9b07f02f577733261e981346f31585fe118975eabb738"}, + {file = "cramjam-2.9.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4714e1ea0c3329368b83fe5ad6e831d5ca11fb794ca7cf491622eb6b2d420d2f"}, + {file = "cramjam-2.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1b4ca30c9f27e3b88bc082d4637e7648f93da5cb69a2dbe0c0300bc51353c820"}, + {file = "cramjam-2.9.0-cp312-none-win32.whl", hash = "sha256:0ed2fef010d1caca9ea63814e9cb5b1d47d907b80302b8cc0b3a1e116ea241e2"}, + {file = "cramjam-2.9.0-cp312-none-win_amd64.whl", hash = "sha256:bd26d71939de5dcf169d479fbc7fcfed21e6675bab33e7f7e9f8405f19711c71"}, + {file = "cramjam-2.9.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:dd70ea5d7b2c5e479e04ac3a00d8bc3deca146d2b5dbfbe3d7b42ed136e19de4"}, + {file = "cramjam-2.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b1410e68c464666473a89cade17483b94bb4639d9161c440ee54ee1e0eca583"}, + {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b0078727fe8c28ef1695e5d04aae5c41ac697eb087cba387c6a02b825f9071c0"}, + {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a63c4e63319bf7dfc3ab46c06afb76d3d9cc1c94369b609dde480e5cc78e4de"}, + {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47d7253b5a10c201cc65aecfb517dfa1c0b5831b2524ac32dd2964fceafc0dc4"}, + {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05970fb640f236767003e62c256a085754536169bac863f4a3502ecb59cbf197"}, + {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0b062d261fa3fac00146cf801896c8cfafe1e41332eb047aa0a36558299daa6"}, + {file = "cramjam-2.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:017b7066f18b7b676068f51b1dbdecc02d76d9af10092252b22dcbd03a78ed33"}, + {file = "cramjam-2.9.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:9de33ef3bc006c11fbad1dc8b15341dcc78430df2c5ce1e790dfb729b11ab593"}, + {file = "cramjam-2.9.0-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:b99efaf81be8e381de1cde6574e2c89030ed53994e73b0e75b62d6e232f491c5"}, + {file = "cramjam-2.9.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:36426e3f1920f6aa4c644d007bf9cfad06dd9f1a30cd0a921d72b010492d8447"}, + {file = "cramjam-2.9.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ea9bcaff298f5d35ef67346d474fca388c5cf6d4edab1d06b84868800f88bd36"}, + {file = "cramjam-2.9.0-cp313-none-win32.whl", hash = "sha256:c48da60a5eb481b412e5e462b81ad307fb2203178a2840a743f0a7c5fc1718c9"}, + {file = "cramjam-2.9.0-cp313-none-win_amd64.whl", hash = "sha256:97a6311bd32f301ff1b922bc9de62ace3d9fd845e20efc0f71b4d0239a45b8d2"}, + {file = "cramjam-2.9.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:78e7349f945a83bc48855fb042873092a69b155a088b8c11942eb76418b32705"}, + {file = "cramjam-2.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:65a097ea765dd4ef2fb868b5b0959d7c93a64c250b2c52f462898c823ae4b950"}, + {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:35cad507eb02c775e6c5444312f98b28dd8bf122425677ae199484996e838673"}, + {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8982925d179b940efa860513a31b839bb06343501077cca3e67f7a2f7360d355"}, + {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ba7e2d33e1d092dffd0a3ff4bd1b86177594aa3c2901fd478e78e1fb2aee8ed3"}, + {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:904be92e3bc25e78343ee52aa0fd5fba3a31d11d474e8af4623a9d00baa84bc2"}, + {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9221297c547d702e1431e96705fce26c6a87df34a681a6b97fe63b536d09c1d8"}, + {file = "cramjam-2.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e98a18c22a85f321091cc8db6694af1d713a369c2d60ec611c10ccfe24ab103a"}, + {file = "cramjam-2.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e248510f8e2dbc71fa99f86238c9023365dbe1a4520eb40e33d73416527349f2"}, + {file = "cramjam-2.9.0-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:dc07376aa33b6004ea372ac9b0ba0ed3455aa2fc4e18727414142ecb46b176b8"}, + {file = "cramjam-2.9.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e94021c541eb2a199b5a2ffae0ea84fb8b99863dab99a5b154b00bc7a44b5c48"}, + {file = "cramjam-2.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4adbf4366f8dc29b7c5c731c800cf633be76c9911e928daeb606827d6ae7c599"}, + {file = "cramjam-2.9.0-cp38-none-win32.whl", hash = "sha256:ca880f555c8db40942acc8a50722c33e229b6be90e598acc1a201f36487b917d"}, + {file = "cramjam-2.9.0-cp38-none-win_amd64.whl", hash = "sha256:ab17a429a92db90bf40115efb97d10e71b94b0dcacf30cf724552df2794a58fb"}, + {file = "cramjam-2.9.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ed7fd7bc2b86ec3161fe0cc49f5f392e6efa55c91a95397d5047820c38117660"}, + {file = "cramjam-2.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a0f654c739a6bc4a69a2aaf31463328a208757ed780ff886234532f78e06a864"}, + {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cd4d4ab9deb5846af0ac6cf1fa139cfa40291ad14d073efa8b8e20c8d1aa90bd"}, + {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bafc32f01d4ab64f83fdbc29bc5bd25a920b59c751c12e06e6f4b1e379be7600"}, + {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0fb5ea631dbf998f667766a9e485e757817d66ed559916ba553a0ec2f902d788"}, + {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c902e56e60c48f5f15e55257aaa1c2678323df5f18a1b839e8d05cac1107576c"}, + {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:441d3875cdffe5df9294b93ef570058837732dd727cd9d18efa0f089f1c2687a"}, + {file = "cramjam-2.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed486e57a79ccc7aebaa2ec12517d891fdc5d2fde16915e3db705b8a47570981"}, + {file = "cramjam-2.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:013cb872205641c6e5269f530ed40aaaa5640d84e0d8f33b89f5a1bf7f655527"}, + {file = "cramjam-2.9.0-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:a41b4b10a381be1d42a1a7dd07b8c3faccd3d12c7e98e973a6ec558fd040a607"}, + {file = "cramjam-2.9.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:598eac1713ddbe69c3b30dcc890d69b206ce08903fc3aed58149aae87c61973a"}, + {file = "cramjam-2.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:72e9ebc27c557706a3c9964c1d1b4522857760dbd60c105a4f5421f3b66e31a2"}, + {file = "cramjam-2.9.0-cp39-none-win32.whl", hash = "sha256:dbbd6fba677e1cbc9d6bd4ebbe3e8b3667d0295f1731489db2a971c95f0ceca0"}, + {file = "cramjam-2.9.0-cp39-none-win_amd64.whl", hash = "sha256:7f33a83969fa94ee8e0c1f0aef8eb303ead3e9142338dc543abeb7e1a28734ab"}, + {file = "cramjam-2.9.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:132db7d3346ea21ba44e7ee23ec73bd6fa9eb1e77133ca6dfe1f7449a69999af"}, + {file = "cramjam-2.9.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2addf801c88bead21256ccd87dc97cffead03758c4a4947fad8e454f4abfda0a"}, + {file = "cramjam-2.9.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24afad3ba62774abbb150dc25aab21b047ab999c4143c7a8d96577848baf7af6"}, + {file = "cramjam-2.9.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:604c16052cf29d0c796927ed7e107f65429d2036c82c9a8009bd453c94e5e4f0"}, + {file = "cramjam-2.9.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:65bded20fd2cef17b22246c336ddd67fac842341ee311042b4a70e65dc745aa7"}, + {file = "cramjam-2.9.0.tar.gz", hash = "sha256:f103e648aa3ebe9b8e2c1a3a92719288d8f3f41007c319ad298cdce2d0c28641"}, ] [package.extras] @@ -602,43 +612,38 @@ dev = ["black (==22.3.0)", "hypothesis", "numpy", "pytest (>=5.30)", "pytest-ben [[package]] name = "cryptography" -version = "42.0.8" +version = "43.0.3" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, + {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, + {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, + {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, + {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, + {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, + {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, + {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, ] [package.dependencies] @@ -651,7 +656,7 @@ nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] [[package]] @@ -671,20 +676,20 @@ typing-inspect = ">=0.4.0,<1" [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "docker" @@ -719,15 +724,29 @@ files = [ {file = "dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e"}, ] +[[package]] +name = "dunamai" +version = "1.23.0" +description = "Dynamic version generation" +optional = false +python-versions = ">=3.5" +files = [ + {file = "dunamai-1.23.0-py3-none-any.whl", hash = "sha256:a0906d876e92441793c6a423e16a4802752e723e9c9a5aabdc5535df02dbe041"}, + {file = "dunamai-1.23.0.tar.gz", hash = "sha256:a163746de7ea5acb6dacdab3a6ad621ebc612ed1e528aaa8beedb8887fccd2c4"}, +] + +[package.dependencies] +packaging = ">=20.9" + [[package]] name = "emoji" -version = "2.13.2" +version = "2.14.0" description = "Emoji for Python" optional = false python-versions = ">=3.7" files = [ - {file = "emoji-2.13.2-py3-none-any.whl", hash = "sha256:ef6f2ee63b245e934c763b1a9a0637713955aa3d9e322432e036bb60559de4d6"}, - {file = "emoji-2.13.2.tar.gz", hash = "sha256:f95d10d96c5f21299ed2c4b32511611ba890b8c07f5f2bf5b04d5d3eee91fd19"}, + {file = "emoji-2.14.0-py3-none-any.whl", hash = "sha256:fcc936bf374b1aec67dda5303ae99710ba88cc9cdce2d1a71c5f2204e6d78799"}, + {file = "emoji-2.14.0.tar.gz", hash = "sha256:f68ac28915a2221667cddb3e6c589303c3c6954c6c5af6fefaec7f9bdf72fdca"}, ] [package.extras] @@ -820,12 +839,13 @@ python-dateutil = ">=2.7" [[package]] name = "genson" -version = "1.2.2" +version = "1.3.0" description = "GenSON is a powerful, user-friendly JSON Schema generator." optional = false python-versions = "*" files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, + {file = "genson-1.3.0-py3-none-any.whl", hash = "sha256:468feccd00274cc7e4c09e84b08704270ba8d95232aa280f65b986139cec67f7"}, + {file = "genson-1.3.0.tar.gz", hash = "sha256:e02db9ac2e3fd29e65b5286f7135762e2cd8a986537c075b06fc5f1517308e37"}, ] [[package]] @@ -841,13 +861,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -990,24 +1010,22 @@ files = [ [[package]] name = "jsonschema" -version = "3.2.0" +version = "4.17.3" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, ] [package.dependencies] attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" [package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] [[package]] name = "langchain-core" @@ -1047,22 +1065,42 @@ six = "*" [[package]] name = "langsmith" -version = "0.1.130" +version = "0.1.145" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.130-py3-none-any.whl", hash = "sha256:acf27d77e699d84b03045f3f226e78be1dffb3e756aa1a085f9993a45380e8b2"}, - {file = "langsmith-0.1.130.tar.gz", hash = "sha256:3e43f87655a86395133e3a745d5968667d4d05dc9a24c617f89224c8cbf54dce"}, + {file = "langsmith-0.1.145-py3-none-any.whl", hash = "sha256:bd3001fc6738ad9061a2709d60f62a6bdf4892a17e63c7751f73a6f32a100729"}, + {file = "langsmith-0.1.145.tar.gz", hash = "sha256:b6e53f7b1624846f03769a1fce673baf2a0a262b4f4129b1f6bd127a1f44f8fd"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[[package]] +name = "linkify-it-py" +version = "2.0.3" +description = "Links recognition library with FULL unicode support." +optional = false +python-versions = ">=3.7" +files = [ + {file = "linkify-it-py-2.0.3.tar.gz", hash = "sha256:68cda27e162e9215c17d786649d1da0021a451bdc436ef9e0fa0ba5234b9b048"}, + {file = "linkify_it_py-2.0.3-py3-none-any.whl", hash = "sha256:6bcbc417b0ac14323382aef5c5192c0075bf8a9d6b41820a2b66371eac6b6d79"}, +] + +[package.dependencies] +uc-micro-py = "*" + +[package.extras] +benchmark = ["pytest", "pytest-benchmark"] +dev = ["black", "flake8", "isort", "pre-commit", "pyproject-flake8"] +doc = ["myst-parser", "sphinx", "sphinx-book-theme"] +test = ["coverage", "pytest", "pytest-cov"] + [[package]] name = "lxml" version = "5.3.0" @@ -1232,93 +1270,214 @@ files = [ docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] testing = ["coverage", "pyyaml"] +[[package]] +name = "markdown-it-py" +version = "3.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.8" +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[package.dependencies] +linkify-it-py = {version = ">=1,<3", optional = true, markers = "extra == \"linkify\""} +mdit-py-plugins = {version = "*", optional = true, markers = "extra == \"plugins\""} +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + [[package]] name = "markupsafe" -version = "2.1.5" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] name = "marshmallow" -version = "3.22.0" +version = "3.23.1" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "marshmallow-3.22.0-py3-none-any.whl", hash = "sha256:71a2dce49ef901c3f97ed296ae5051135fd3febd2bf43afe0ae9a82143a494d9"}, - {file = "marshmallow-3.22.0.tar.gz", hash = "sha256:4972f529104a220bb8637d595aa4c9762afbe7f7a77d82dc58c1615d70c5823e"}, + {file = "marshmallow-3.23.1-py3-none-any.whl", hash = "sha256:fece2eb2c941180ea1b7fcbd4a83c51bfdd50093fdd3ad2585ee5e1df2508491"}, + {file = "marshmallow-3.23.1.tar.gz", hash = "sha256:3a8dfda6edd8dcdbf216c0ede1d1e78d230a6dc9c5a088f58c4083b974a0d468"}, ] [package.dependencies] packaging = ">=17.0" [package.extras] -dev = ["marshmallow[tests]", "pre-commit (>=3.5,<4.0)", "tox"] -docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.13)", "sphinx (==8.0.2)", "sphinx-issues (==4.1.0)", "sphinx-version-warning (==1.1.2)"] -tests = ["pytest", "pytz", "simplejson"] +dev = ["marshmallow[tests]", "pre-commit (>=3.5,<5.0)", "tox"] +docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.14)", "sphinx (==8.1.3)", "sphinx-issues (==5.0.0)", "sphinx-version-warning (==1.1.2)"] +tests = ["pytest", "simplejson"] + +[[package]] +name = "mdit-py-plugins" +version = "0.4.2" +description = "Collection of plugins for markdown-it-py" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mdit_py_plugins-0.4.2-py3-none-any.whl", hash = "sha256:0c673c3f889399a33b95e88d2f0d111b4447bdfea7f237dab2d488f459835636"}, + {file = "mdit_py_plugins-0.4.2.tar.gz", hash = "sha256:5f2cd1fdb606ddf152d37ec30e46101a60512bc0e5fa1a7002c36647b09e26b5"}, +] + +[package.dependencies] +markdown-it-py = ">=1.0.0,<4.0.0" + +[package.extras] +code-style = ["pre-commit"] +rtd = ["myst-parser", "sphinx-book-theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + +[[package]] +name = "memray" +version = "1.14.0" +description = "A memory profiler for Python applications" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "memray-1.14.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:745d9014cb662065501441a7b534c29914fe2b68398b37385aba9f4a1c51c723"}, + {file = "memray-1.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f62a402ca1a7126f749544c3d6493672d6330ffd37d59ba230bc73e5143b3bc2"}, + {file = "memray-1.14.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:36840f39277b1871ecb5a9592dd1aa517a17b9f855f4e3ff08aa328a9d305e69"}, + {file = "memray-1.14.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3c7933ca70c0d59d0ce9b1064a6eda86231248759b46ed6dabedf489039d1aa1"}, + {file = "memray-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75a5907345ff845652e709ddce3171a9ba2d65c62e8bd49a99131066e2a7ce3b"}, + {file = "memray-1.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:88c89c3797834eec177a89ad528699c75b94e2ed08c00754141eae69c520b894"}, + {file = "memray-1.14.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:d6087f291fd68acdf0a833efb57bc0f192c98ae89b4377c690c28313e78d029c"}, + {file = "memray-1.14.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e6ba7bff9dfa37bf3b80a5b83b50eadf20afb1f0e8de4a0139019154086d6bed"}, + {file = "memray-1.14.0-cp311-cp311-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9bb0cfe1b755a860435cd52047b2e3f4f7b0c3887e0c1bf98da7127948284a91"}, + {file = "memray-1.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:638ba74e1735a40b6595fee7f37b426b9a95d244091a1f5df3dc5d98df1cbd4b"}, + {file = "memray-1.14.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7227ebf024cb0688a68ed91ed3e05c61a13751a9e875807195076b827bfde464"}, + {file = "memray-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:248dea8cfb5a615345e28b7e25c94377a8d198da3b6957ee443afa6f4ff1b733"}, + {file = "memray-1.14.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7d03f6be66aa259df7fa50082876fbe6461108d77d46c1f720c46067d60685d4"}, + {file = "memray-1.14.0-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:9af9d30b1e484fd8591c9a7f322fd50b9192a2bce660be92385a01555af9968b"}, + {file = "memray-1.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c4088b391c04796c888ac751b5d387f6e8212b3515d4c53ba540c65a6efe4bda"}, + {file = "memray-1.14.0-cp312-cp312-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:af8aee7e8e5cac1e4130f1184b3e03b6bb08264e4ba1696551791ed3f8fb824e"}, + {file = "memray-1.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4352f9e85957f2cbe45a9e1c87dfc19d2df77e93dcd8a558794a683eeee57b7b"}, + {file = "memray-1.14.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5953f0d2aa31b23d4cce20236a03d90b7c71903709a57b456d6494bfe6f470b7"}, + {file = "memray-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e4ccaca04365efcda51036fe2add980030e33cfc4f3a194a01f530a5c923c65"}, + {file = "memray-1.14.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f85a27eb8a65c810161bb992116a66d328546f78a4a4c7c1868949651b917c08"}, + {file = "memray-1.14.0-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:958d57f7149b8fa4831785394f2a7ace93dbc2be6c49a1c07987a8972986474a"}, + {file = "memray-1.14.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287a01953bc44dd0a32549a23bdacb5f9734e345ca289fa3923867c637715056"}, + {file = "memray-1.14.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfc17cba35d98e3d2ca20ab995f17eec3edba7138b062cbc1aa36d53d9d2d955"}, + {file = "memray-1.14.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c82342cead930ca50235f59740ca238808f9c33ef31d994712972966beb6226e"}, + {file = "memray-1.14.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a22a826b4047e839310514f4889c24e45a66ea222fca19ac0ae7b2f89bbb0281"}, + {file = "memray-1.14.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:344f3c73b97ffc8f1666b404deafbc31a19e6b2881341b706aa7ec20afb0e8b1"}, + {file = "memray-1.14.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a43455233d534e9c0e8dabe827d451124874a6455b2afcbcd60b823241ea5843"}, + {file = "memray-1.14.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e05a3b6bc82ef01821beaee98e86bd8de2ada06cb8781add9c40a3ae4a040383"}, + {file = "memray-1.14.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3bc27e5483c70236c9379b99277b4ea8fa4b3f73a99e37af81190649bd877881"}, + {file = "memray-1.14.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a7e5604448b2a78e329addfb099384515d3f973a03711c4e2a7b6c9f7f34f53"}, + {file = "memray-1.14.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:443885a96ab9f67d46288240e2593b5c3ecb2c507ddb4e3b10695e104403d001"}, + {file = "memray-1.14.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:52a45d96ed717d8efb645e99646a92dd21a2ca38bdb823fe22e38c429cba9513"}, + {file = "memray-1.14.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:72febec7b287667e8ea9ee3e879a4da19a4318bc47e211da815be74acd961994"}, + {file = "memray-1.14.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e07bdc3a4979b335c2b6b93a81b807d5aacd8dbbea56c41c6899a8bc0d2beb3"}, + {file = "memray-1.14.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b5e729d03caf426dc45a258270537a603794ecc067ccfd92f9c67ba9332e788"}, + {file = "memray-1.14.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:1d0a1397b5387b75dc9d9759beb022cb360948584840e850474d7d39ad267f85"}, + {file = "memray-1.14.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:c119b600e7c665e0713f09e25f9ee09733a98035688ecc1ec8fd168fa37a77f6"}, + {file = "memray-1.14.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:29a2e7d84d1652ef4664bcceb155630979b4797180b70da35525d963a4ca707f"}, + {file = "memray-1.14.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b3b8d46b6447cdecba3ba100d47c62e78cdad58b00b2d6ba004d6bad318c8668"}, + {file = "memray-1.14.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:57f9bf3f1c648f1ea877a84c21c449fdafd8cc105763ada6023e36bae9b45eb8"}, + {file = "memray-1.14.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b7a59346d242fc39041d87a71cb6cf45baf492ffbb69da9690de49346be64a8"}, + {file = "memray-1.14.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:11fb00105572b70f2aca8b787ce9748b0c94672fbb6334f1604f7f813ca3dca6"}, + {file = "memray-1.14.0.tar.gz", hash = "sha256:b5d8874b7b215551f0ae9fa8aef3f2f52321a6460dc0141aaf9374709e6b0eb7"}, +] + +[package.dependencies] +jinja2 = ">=2.9" +rich = ">=11.2.0" +textual = ">=0.41.0" + +[package.extras] +benchmark = ["asv"] +dev = ["Cython", "asv", "black", "bump2version", "check-manifest", "flake8", "furo", "greenlet", "ipython", "isort", "mypy", "packaging", "pytest", "pytest-cov", "pytest-textual-snapshot", "setuptools", "sphinx", "sphinx-argparse", "textual (>=0.43,!=0.65.2,!=0.66)", "towncrier"] +docs = ["IPython", "bump2version", "furo", "sphinx", "sphinx-argparse", "towncrier"] +lint = ["black", "check-manifest", "flake8", "isort", "mypy"] +test = ["Cython", "greenlet", "ipython", "packaging", "pytest", "pytest-cov", "pytest-textual-snapshot", "setuptools", "textual (>=0.43,!=0.65.2,!=0.66)"] [[package]] name = "mypy-extensions" @@ -1333,13 +1492,13 @@ files = [ [[package]] name = "nltk" -version = "3.8.1" +version = "3.9.1" description = "Natural Language Toolkit" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "nltk-3.8.1-py3-none-any.whl", hash = "sha256:fd5c9109f976fa86bcadba8f91e47f5e9293bd034474752e92a520f81c93dda5"}, - {file = "nltk-3.8.1.zip", hash = "sha256:1834da3d0682cba4f2cede2f9aad6b0fafb6461ba451db0efb6f9c39798d64d3"}, + {file = "nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1"}, + {file = "nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868"}, ] [package.dependencies] @@ -1403,68 +1562,86 @@ files = [ [[package]] name = "orjson" -version = "3.10.7" +version = "3.10.12" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:74f4544f5a6405b90da8ea724d15ac9c36da4d72a738c64685003337401f5c12"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34a566f22c28222b08875b18b0dfbf8a947e69df21a9ed5c51a6bf91cfb944ac"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf6ba8ebc8ef5792e2337fb0419f8009729335bb400ece005606336b7fd7bab7"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac7cf6222b29fbda9e3a472b41e6a5538b48f2c8f99261eecd60aafbdb60690c"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de817e2f5fc75a9e7dd350c4b0f54617b280e26d1631811a43e7e968fa71e3e9"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:348bdd16b32556cf8d7257b17cf2bdb7ab7976af4af41ebe79f9796c218f7e91"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:479fd0844ddc3ca77e0fd99644c7fe2de8e8be1efcd57705b5c92e5186e8a250"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fdf5197a21dd660cf19dfd2a3ce79574588f8f5e2dbf21bda9ee2d2b46924d84"}, - {file = "orjson-3.10.7-cp310-none-win32.whl", hash = "sha256:d374d36726746c81a49f3ff8daa2898dccab6596864ebe43d50733275c629175"}, - {file = "orjson-3.10.7-cp310-none-win_amd64.whl", hash = "sha256:cb61938aec8b0ffb6eef484d480188a1777e67b05d58e41b435c74b9d84e0b9c"}, - {file = "orjson-3.10.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0"}, - {file = "orjson-3.10.7-cp311-none-win32.whl", hash = "sha256:82763b46053727a7168d29c772ed5c870fdae2f61aa8a25994c7984a19b1021f"}, - {file = "orjson-3.10.7-cp311-none-win_amd64.whl", hash = "sha256:eb8d384a24778abf29afb8e41d68fdd9a156cf6e5390c04cc07bbc24b89e98b5"}, - {file = "orjson-3.10.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44a96f2d4c3af51bfac6bc4ef7b182aa33f2f054fd7f34cc0ee9a320d051d41f"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ac14cd57df0572453543f8f2575e2d01ae9e790c21f57627803f5e79b0d3c3"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bdbb61dcc365dd9be94e8f7df91975edc9364d6a78c8f7adb69c1cdff318ec93"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b48b3db6bb6e0a08fa8c83b47bc169623f801e5cc4f24442ab2b6617da3b5313"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23820a1563a1d386414fef15c249040042b8e5d07b40ab3fe3efbfbbcbcb8864"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0c6a008e91d10a2564edbb6ee5069a9e66df3fbe11c9a005cb411f441fd2c09"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d352ee8ac1926d6193f602cbe36b1643bbd1bbcb25e3c1a657a4390f3000c9a5"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b"}, - {file = "orjson-3.10.7-cp312-none-win32.whl", hash = "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb"}, - {file = "orjson-3.10.7-cp312-none-win_amd64.whl", hash = "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1"}, - {file = "orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149"}, - {file = "orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad"}, - {file = "orjson-3.10.7-cp313-none-win32.whl", hash = "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2"}, - {file = "orjson-3.10.7-cp313-none-win_amd64.whl", hash = "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024"}, - {file = "orjson-3.10.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6ea2b2258eff652c82652d5e0f02bd5e0463a6a52abb78e49ac288827aaa1469"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:430ee4d85841e1483d487e7b81401785a5dfd69db5de01314538f31f8fbf7ee1"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b6146e439af4c2472c56f8540d799a67a81226e11992008cb47e1267a9b3225"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:084e537806b458911137f76097e53ce7bf5806dda33ddf6aaa66a028f8d43a23"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829cf2195838e3f93b70fd3b4292156fc5e097aac3739859ac0dcc722b27ac0"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1193b2416cbad1a769f868b1749535d5da47626ac29445803dae7cc64b3f5c98"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4e6c3da13e5a57e4b3dca2de059f243ebec705857522f188f0180ae88badd354"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c31008598424dfbe52ce8c5b47e0752dca918a4fdc4a2a32004efd9fab41d866"}, - {file = "orjson-3.10.7-cp38-none-win32.whl", hash = "sha256:7122a99831f9e7fe977dc45784d3b2edc821c172d545e6420c375e5a935f5a1c"}, - {file = "orjson-3.10.7-cp38-none-win_amd64.whl", hash = "sha256:a763bc0e58504cc803739e7df040685816145a6f3c8a589787084b54ebc9f16e"}, - {file = "orjson-3.10.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e76be12658a6fa376fcd331b1ea4e58f5a06fd0220653450f0d415b8fd0fbe20"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed350d6978d28b92939bfeb1a0570c523f6170efc3f0a0ef1f1df287cd4f4960"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144888c76f8520e39bfa121b31fd637e18d4cc2f115727865fdf9fa325b10412"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09b2d92fd95ad2402188cf51573acde57eb269eddabaa60f69ea0d733e789fe9"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b24a579123fa884f3a3caadaed7b75eb5715ee2b17ab5c66ac97d29b18fe57f"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591bcfe7512353bd609875ab38050efe3d55e18934e2f18950c108334b4ff"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f4db56635b58cd1a200b0a23744ff44206ee6aa428185e2b6c4a65b3197abdcd"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0fa5886854673222618638c6df7718ea7fe2f3f2384c452c9ccedc70b4a510a5"}, - {file = "orjson-3.10.7-cp39-none-win32.whl", hash = "sha256:8272527d08450ab16eb405f47e0f4ef0e5ff5981c3d82afe0efd25dcbef2bcd2"}, - {file = "orjson-3.10.7-cp39-none-win_amd64.whl", hash = "sha256:974683d4618c0c7dbf4f69c95a979734bf183d0658611760017f6e70a145af58"}, - {file = "orjson-3.10.7.tar.gz", hash = "sha256:75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3"}, + {file = "orjson-3.10.12-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ece01a7ec71d9940cc654c482907a6b65df27251255097629d0dea781f255c6d"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c34ec9aebc04f11f4b978dd6caf697a2df2dd9b47d35aa4cc606cabcb9df69d7"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd6ec8658da3480939c79b9e9e27e0db31dffcd4ba69c334e98c9976ac29140e"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f17e6baf4cf01534c9de8a16c0c611f3d94925d1701bf5f4aff17003677d8ced"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6402ebb74a14ef96f94a868569f5dccf70d791de49feb73180eb3c6fda2ade56"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0000758ae7c7853e0a4a6063f534c61656ebff644391e1f81698c1b2d2fc8cd2"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:888442dcee99fd1e5bd37a4abb94930915ca6af4db50e23e746cdf4d1e63db13"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c1f7a3ce79246aa0e92f5458d86c54f257fb5dfdc14a192651ba7ec2c00f8a05"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:802a3935f45605c66fb4a586488a38af63cb37aaad1c1d94c982c40dcc452e85"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1da1ef0113a2be19bb6c557fb0ec2d79c92ebd2fed4cfb1b26bab93f021fb885"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a3273e99f367f137d5b3fecb5e9f45bcdbfac2a8b2f32fbc72129bbd48789c2"}, + {file = "orjson-3.10.12-cp310-none-win32.whl", hash = "sha256:475661bf249fd7907d9b0a2a2421b4e684355a77ceef85b8352439a9163418c3"}, + {file = "orjson-3.10.12-cp310-none-win_amd64.whl", hash = "sha256:87251dc1fb2b9e5ab91ce65d8f4caf21910d99ba8fb24b49fd0c118b2362d509"}, + {file = "orjson-3.10.12-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a734c62efa42e7df94926d70fe7d37621c783dea9f707a98cdea796964d4cf74"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:750f8b27259d3409eda8350c2919a58b0cfcd2054ddc1bd317a643afc646ef23"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb52c22bfffe2857e7aa13b4622afd0dd9d16ea7cc65fd2bf318d3223b1b6252"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:440d9a337ac8c199ff8251e100c62e9488924c92852362cd27af0e67308c16ef"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9e15c06491c69997dfa067369baab3bf094ecb74be9912bdc4339972323f252"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:362d204ad4b0b8724cf370d0cd917bb2dc913c394030da748a3bb632445ce7c4"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2b57cbb4031153db37b41622eac67329c7810e5f480fda4cfd30542186f006ae"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:165c89b53ef03ce0d7c59ca5c82fa65fe13ddf52eeb22e859e58c237d4e33b9b"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5dee91b8dfd54557c1a1596eb90bcd47dbcd26b0baaed919e6861f076583e9da"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77a4e1cfb72de6f905bdff061172adfb3caf7a4578ebf481d8f0530879476c07"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:038d42c7bc0606443459b8fe2d1f121db474c49067d8d14c6a075bbea8bf14dd"}, + {file = "orjson-3.10.12-cp311-none-win32.whl", hash = "sha256:03b553c02ab39bed249bedd4abe37b2118324d1674e639b33fab3d1dafdf4d79"}, + {file = "orjson-3.10.12-cp311-none-win_amd64.whl", hash = "sha256:8b8713b9e46a45b2af6b96f559bfb13b1e02006f4242c156cbadef27800a55a8"}, + {file = "orjson-3.10.12-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:53206d72eb656ca5ac7d3a7141e83c5bbd3ac30d5eccfe019409177a57634b0d"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac8010afc2150d417ebda810e8df08dd3f544e0dd2acab5370cfa6bcc0662f8f"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed459b46012ae950dd2e17150e838ab08215421487371fa79d0eced8d1461d70"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dcb9673f108a93c1b52bfc51b0af422c2d08d4fc710ce9c839faad25020bb69"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22a51ae77680c5c4652ebc63a83d5255ac7d65582891d9424b566fb3b5375ee9"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910fdf2ac0637b9a77d1aad65f803bac414f0b06f720073438a7bd8906298192"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:24ce85f7100160936bc2116c09d1a8492639418633119a2224114f67f63a4559"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a76ba5fc8dd9c913640292df27bff80a685bed3a3c990d59aa6ce24c352f8fc"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ff70ef093895fd53f4055ca75f93f047e088d1430888ca1229393a7c0521100f"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f4244b7018b5753ecd10a6d324ec1f347da130c953a9c88432c7fbc8875d13be"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:16135ccca03445f37921fa4b585cff9a58aa8d81ebcb27622e69bfadd220b32c"}, + {file = "orjson-3.10.12-cp312-none-win32.whl", hash = "sha256:2d879c81172d583e34153d524fcba5d4adafbab8349a7b9f16ae511c2cee8708"}, + {file = "orjson-3.10.12-cp312-none-win_amd64.whl", hash = "sha256:fc23f691fa0f5c140576b8c365bc942d577d861a9ee1142e4db468e4e17094fb"}, + {file = "orjson-3.10.12-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:47962841b2a8aa9a258b377f5188db31ba49af47d4003a32f55d6f8b19006543"}, + {file = "orjson-3.10.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6334730e2532e77b6054e87ca84f3072bee308a45a452ea0bffbbbc40a67e296"}, + {file = "orjson-3.10.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:accfe93f42713c899fdac2747e8d0d5c659592df2792888c6c5f829472e4f85e"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a7974c490c014c48810d1dede6c754c3cc46598da758c25ca3b4001ac45b703f"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3f250ce7727b0b2682f834a3facff88e310f52f07a5dcfd852d99637d386e79e"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f31422ff9486ae484f10ffc51b5ab2a60359e92d0716fcce1b3593d7bb8a9af6"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5f29c5d282bb2d577c2a6bbde88d8fdcc4919c593f806aac50133f01b733846e"}, + {file = "orjson-3.10.12-cp313-none-win32.whl", hash = "sha256:f45653775f38f63dc0e6cd4f14323984c3149c05d6007b58cb154dd080ddc0dc"}, + {file = "orjson-3.10.12-cp313-none-win_amd64.whl", hash = "sha256:229994d0c376d5bdc91d92b3c9e6be2f1fbabd4cc1b59daae1443a46ee5e9825"}, + {file = "orjson-3.10.12-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7d69af5b54617a5fac5c8e5ed0859eb798e2ce8913262eb522590239db6c6763"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ed119ea7d2953365724a7059231a44830eb6bbb0cfead33fcbc562f5fd8f935"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9c5fc1238ef197e7cad5c91415f524aaa51e004be5a9b35a1b8a84ade196f73f"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43509843990439b05f848539d6f6198d4ac86ff01dd024b2f9a795c0daeeab60"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f72e27a62041cfb37a3de512247ece9f240a561e6c8662276beaf4d53d406db4"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a904f9572092bb6742ab7c16c623f0cdccbad9eeb2d14d4aa06284867bddd31"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:855c0833999ed5dc62f64552db26f9be767434917d8348d77bacaab84f787d7b"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:897830244e2320f6184699f598df7fb9db9f5087d6f3f03666ae89d607e4f8ed"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0b32652eaa4a7539f6f04abc6243619c56f8530c53bf9b023e1269df5f7816dd"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:36b4aa31e0f6a1aeeb6f8377769ca5d125db000f05c20e54163aef1d3fe8e833"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5535163054d6cbf2796f93e4f0dbc800f61914c0e3c4ed8499cf6ece22b4a3da"}, + {file = "orjson-3.10.12-cp38-none-win32.whl", hash = "sha256:90a5551f6f5a5fa07010bf3d0b4ca2de21adafbbc0af6cb700b63cd767266cb9"}, + {file = "orjson-3.10.12-cp38-none-win_amd64.whl", hash = "sha256:703a2fb35a06cdd45adf5d733cf613cbc0cb3ae57643472b16bc22d325b5fb6c"}, + {file = "orjson-3.10.12-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f29de3ef71a42a5822765def1febfb36e0859d33abf5c2ad240acad5c6a1b78d"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de365a42acc65d74953f05e4772c974dad6c51cfc13c3240899f534d611be967"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:91a5a0158648a67ff0004cb0df5df7dcc55bfc9ca154d9c01597a23ad54c8d0c"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c47ce6b8d90fe9646a25b6fb52284a14ff215c9595914af63a5933a49972ce36"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0eee4c2c5bfb5c1b47a5db80d2ac7aaa7e938956ae88089f098aff2c0f35d5d8"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35d3081bbe8b86587eb5c98a73b97f13d8f9fea685cf91a579beddacc0d10566"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73c23a6e90383884068bc2dba83d5222c9fcc3b99a0ed2411d38150734236755"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5472be7dc3269b4b52acba1433dac239215366f89dc1d8d0e64029abac4e714e"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:7319cda750fca96ae5973efb31b17d97a5c5225ae0bc79bf5bf84df9e1ec2ab6"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:74d5ca5a255bf20b8def6a2b96b1e18ad37b4a122d59b154c458ee9494377f80"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ff31d22ecc5fb85ef62c7d4afe8301d10c558d00dd24274d4bbe464380d3cd69"}, + {file = "orjson-3.10.12-cp39-none-win32.whl", hash = "sha256:c22c3ea6fba91d84fcb4cda30e64aff548fcf0c44c876e681f47d61d24b12e6b"}, + {file = "orjson-3.10.12-cp39-none-win_amd64.whl", hash = "sha256:be604f60d45ace6b0b33dd990a66b4526f1a7a186ac411c942674625456ca548"}, + {file = "orjson-3.10.12.tar.gz", hash = "sha256:0a78bbda3aea0f9f079057ee1ee8a1ecf790d4f1af88dd67493c6b8ee52506ff"}, ] [[package]] @@ -1641,95 +1818,90 @@ pytzdata = ">=2020.1" [[package]] name = "pillow" -version = "10.4.0" +version = "11.0.0" description = "Python Imaging Library (Fork)" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, - {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, - {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, - {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, - {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, - {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, - {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, - {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, - {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, - {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, - {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, - {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, - {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, - {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, - {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, - {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, - {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, - {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, - {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, - {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, - {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, - {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, - {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, - {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, - {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, - {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, - {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, - {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, - {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, - {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, - {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, - {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, - {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, - {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, - {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, - {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, - {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, - {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, - {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, - {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, - {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, - {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, + {file = "pillow-11.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947"}, + {file = "pillow-11.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f"}, + {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb"}, + {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97"}, + {file = "pillow-11.0.0-cp310-cp310-win32.whl", hash = "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50"}, + {file = "pillow-11.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c"}, + {file = "pillow-11.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1"}, + {file = "pillow-11.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc"}, + {file = "pillow-11.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a"}, + {file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3"}, + {file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5"}, + {file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b"}, + {file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa"}, + {file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306"}, + {file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9"}, + {file = "pillow-11.0.0-cp311-cp311-win32.whl", hash = "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5"}, + {file = "pillow-11.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291"}, + {file = "pillow-11.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9"}, + {file = "pillow-11.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923"}, + {file = "pillow-11.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903"}, + {file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4"}, + {file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f"}, + {file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9"}, + {file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7"}, + {file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6"}, + {file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc"}, + {file = "pillow-11.0.0-cp312-cp312-win32.whl", hash = "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6"}, + {file = "pillow-11.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47"}, + {file = "pillow-11.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25"}, + {file = "pillow-11.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcd1fb5bb7b07f64c15618c89efcc2cfa3e95f0e3bcdbaf4642509de1942a699"}, + {file = "pillow-11.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e038b0745997c7dcaae350d35859c9715c71e92ffb7e0f4a8e8a16732150f38"}, + {file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ae08bd8ffc41aebf578c2af2f9d8749d91f448b3bfd41d7d9ff573d74f2a6b2"}, + {file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d69bfd8ec3219ae71bcde1f942b728903cad25fafe3100ba2258b973bd2bc1b2"}, + {file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:61b887f9ddba63ddf62fd02a3ba7add935d053b6dd7d58998c630e6dbade8527"}, + {file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:c6a660307ca9d4867caa8d9ca2c2658ab685de83792d1876274991adec7b93fa"}, + {file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:73e3a0200cdda995c7e43dd47436c1548f87a30bb27fb871f352a22ab8dcf45f"}, + {file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fba162b8872d30fea8c52b258a542c5dfd7b235fb5cb352240c8d63b414013eb"}, + {file = "pillow-11.0.0-cp313-cp313-win32.whl", hash = "sha256:f1b82c27e89fffc6da125d5eb0ca6e68017faf5efc078128cfaa42cf5cb38798"}, + {file = "pillow-11.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ba470552b48e5835f1d23ecb936bb7f71d206f9dfeee64245f30c3270b994de"}, + {file = "pillow-11.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:846e193e103b41e984ac921b335df59195356ce3f71dcfd155aa79c603873b84"}, + {file = "pillow-11.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4ad70c4214f67d7466bea6a08061eba35c01b1b89eaa098040a35272a8efb22b"}, + {file = "pillow-11.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6ec0d5af64f2e3d64a165f490d96368bb5dea8b8f9ad04487f9ab60dc4bb6003"}, + {file = "pillow-11.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c809a70e43c7977c4a42aefd62f0131823ebf7dd73556fa5d5950f5b354087e2"}, + {file = "pillow-11.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:4b60c9520f7207aaf2e1d94de026682fc227806c6e1f55bba7606d1c94dd623a"}, + {file = "pillow-11.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1e2688958a840c822279fda0086fec1fdab2f95bf2b717b66871c4ad9859d7e8"}, + {file = "pillow-11.0.0-cp313-cp313t-win32.whl", hash = "sha256:607bbe123c74e272e381a8d1957083a9463401f7bd01287f50521ecb05a313f8"}, + {file = "pillow-11.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c39ed17edea3bc69c743a8dd3e9853b7509625c2462532e62baa0732163a904"}, + {file = "pillow-11.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3"}, + {file = "pillow-11.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2e46773dc9f35a1dd28bd6981332fd7f27bec001a918a72a79b4133cf5291dba"}, + {file = "pillow-11.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2679d2258b7f1192b378e2893a8a0a0ca472234d4c2c0e6bdd3380e8dfa21b6a"}, + {file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eda2616eb2313cbb3eebbe51f19362eb434b18e3bb599466a1ffa76a033fb916"}, + {file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ec184af98a121fb2da42642dea8a29ec80fc3efbaefb86d8fdd2606619045d"}, + {file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:8594f42df584e5b4bb9281799698403f7af489fba84c34d53d1c4bfb71b7c4e7"}, + {file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:c12b5ae868897c7338519c03049a806af85b9b8c237b7d675b8c5e089e4a618e"}, + {file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:70fbbdacd1d271b77b7721fe3cdd2d537bbbd75d29e6300c672ec6bb38d9672f"}, + {file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5178952973e588b3f1360868847334e9e3bf49d19e169bbbdfaf8398002419ae"}, + {file = "pillow-11.0.0-cp39-cp39-win32.whl", hash = "sha256:8c676b587da5673d3c75bd67dd2a8cdfeb282ca38a30f37950511766b26858c4"}, + {file = "pillow-11.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:94f3e1780abb45062287b4614a5bc0874519c86a777d4a7ad34978e86428b8dd"}, + {file = "pillow-11.0.0-cp39-cp39-win_arm64.whl", hash = "sha256:290f2cc809f9da7d6d622550bbf4c1e57518212da51b6a30fe8e0a270a5b78bd"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316"}, + {file = "pillow-11.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5bd2d3bdb846d757055910f0a59792d33b555800813c3b39ada1829c372ccb06"}, + {file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:375b8dd15a1f5d2feafff536d47e22f69625c1aa92f12b339ec0b2ca40263273"}, + {file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:daffdf51ee5db69a82dd127eabecce20729e21f7a3680cf7cbb23f0829189790"}, + {file = "pillow-11.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7326a1787e3c7b0429659e0a944725e1b03eeaa10edd945a86dead1913383944"}, + {file = "pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739"}, ] [package.extras] -docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +docs = ["furo", "olefile", "sphinx (>=8.1)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] fpx = ["olefile"] mic = ["olefile"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] @@ -1768,16 +1940,35 @@ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] [[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" +name = "psutil" +version = "6.1.0" +description = "Cross-platform lib for process and system monitoring in Python." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, ] +[package.extras] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + [[package]] name = "pyarrow" version = "15.0.2" @@ -1839,19 +2030,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.1" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.1-py3-none-any.whl", hash = "sha256:a8d20db84de64cf4a7d59e899c2caf0fe9d660c7cfc482528e7020d7dd189a7e"}, + {file = "pydantic-2.10.1.tar.gz", hash = "sha256:a4daca2dc0aa429555e0656d6bf94873a7dc5f54ee42b1f5873d666fb3f35560"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.1" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1859,114 +2050,139 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.1" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206"}, + {file = "pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c"}, + {file = "pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc"}, + {file = "pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9"}, + {file = "pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5"}, + {file = "pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae"}, + {file = "pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c"}, + {file = "pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16"}, + {file = "pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23"}, + {file = "pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05"}, + {file = "pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337"}, + {file = "pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:5897bec80a09b4084aee23f9b73a9477a46c3304ad1d2d07acca19723fb1de62"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d0165ab2914379bd56908c02294ed8405c252250668ebcb438a55494c69f44ab"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b9af86e1d8e4cfc82c2022bfaa6f459381a50b94a29e95dcdda8442d6d83864"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f6c8a66741c5f5447e047ab0ba7a1c61d1e95580d64bce852e3df1f895c4067"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a42d6a8156ff78981f8aa56eb6394114e0dedb217cf8b729f438f643608cbcd"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64c65f40b4cd8b0e049a8edde07e38b476da7e3aaebe63287c899d2cff253fa5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdcf339322a3fae5cbd504edcefddd5a50d9ee00d968696846f089b4432cf78"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf99c8404f008750c846cb4ac4667b798a9f7de673ff719d705d9b2d6de49c5f"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f1edcea27918d748c7e5e4d917297b2a0ab80cad10f86631e488b7cddf76a36"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:159cac0a3d096f79ab6a44d77a961917219707e2a130739c64d4dd46281f5c2a"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:029d9757eb621cc6e1848fa0b0310310de7301057f623985698ed7ebb014391b"}, + {file = "pydantic_core-2.27.1-cp38-none-win32.whl", hash = "sha256:a28af0695a45f7060e6f9b7092558a928a28553366519f64083c63a44f70e618"}, + {file = "pydantic_core-2.27.1-cp38-none-win_amd64.whl", hash = "sha256:2d4567c850905d5eaaed2f7a404e61012a51caf288292e016360aa2b96ff38d4"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:e9386266798d64eeb19dd3677051f5705bf873e98e15897ddb7d76f477131967"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4228b5b646caa73f119b1ae756216b59cc6e2267201c27d3912b592c5e323b60"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3dfe500de26c52abe0477dde16192ac39c98f05bf2d80e76102d394bd13854"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aee66be87825cdf72ac64cb03ad4c15ffef4143dbf5c113f64a5ff4f81477bf9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b748c44bb9f53031c8cbc99a8a061bc181c1000c60a30f55393b6e9c45cc5bd"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ca038c7f6a0afd0b2448941b6ef9d5e1949e999f9e5517692eb6da58e9d44be"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e0bd57539da59a3e4671b90a502da9a28c72322a4f17866ba3ac63a82c4498e"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac6c2c45c847bbf8f91930d88716a0fb924b51e0c6dad329b793d670ec5db792"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b94d4ba43739bbe8b0ce4262bcc3b7b9f31459ad120fb595627eaeb7f9b9ca01"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:00e6424f4b26fe82d44577b4c842d7df97c20be6439e8e685d0d715feceb9fb9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:38de0a70160dd97540335b7ad3a74571b24f1dc3ed33f815f0880682e6880131"}, + {file = "pydantic_core-2.27.1-cp39-none-win32.whl", hash = "sha256:7ccebf51efc61634f6c2344da73e366c75e735960b5654b63d7e6f69a5885fa3"}, + {file = "pydantic_core-2.27.1-cp39-none-win_amd64.whl", hash = "sha256:a57847b090d7892f123726202b7daa20df6694cbd583b67a592e856bff603d6c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5fde892e6c697ce3e30c61b239330fc5d569a71fefd4eb6512fc6caec9dd9e2f"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:816f5aa087094099fff7edabb5e01cc370eb21aa1a1d44fe2d2aefdfb5599b31"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c10c309e18e443ddb108f0ef64e8729363adbfd92d6d57beec680f6261556f3"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98476c98b02c8e9b2eec76ac4156fd006628b1b2d0ef27e548ffa978393fd154"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c3027001c28434e7ca5a6e1e527487051136aa81803ac812be51802150d880dd"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7699b1df36a48169cdebda7ab5a2bac265204003f153b4bd17276153d997670a"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1c39b07d90be6b48968ddc8c19e7585052088fd7ec8d568bb31ff64c70ae3c97"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:46ccfe3032b3915586e469d4972973f893c0a2bb65669194a5bdea9bacc088c2"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:62ba45e21cf6571d7f716d903b5b7b6d2617e2d5d67c0923dc47b9d41369f840"}, + {file = "pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235"}, ] [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" +[[package]] +name = "pygments" +version = "2.18.0" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.0" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.0-py3-none-any.whl", hash = "sha256:543b77207db656de204372350926bed5a86201c4cbff159f623f79c7bb487a15"}, + {file = "pyjwt-2.10.0.tar.gz", hash = "sha256:7628a7eb7938959ac1b26e819a1df0fd3259505627b575e4bad6d08f76db695c"}, ] [package.extras] @@ -2074,27 +2290,45 @@ Pillow = ">=8.0.0" [[package]] name = "pytest" -version = "6.2.5" +version = "7.4.4" description = "pytest: simple powerful testing with Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, ] [package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" +tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} + +[package.extras] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-memray" +version = "1.7.0" +description = "A simple plugin to use with pytest" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest_memray-1.7.0-py3-none-any.whl", hash = "sha256:b896718c1adf6d0cd339dfaaaa5620f035c9919e1199a79b3453804a1254306f"}, + {file = "pytest_memray-1.7.0.tar.gz", hash = "sha256:c18fa907d2210b42f4096c093e2d3416dfc002dcaa450ef3f9ba819bc3dd8f5f"}, +] + +[package.dependencies] +memray = ">=1.12" +pytest = ">=7.2" [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +docs = ["furo (>=2022.12.7)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinx-inline-tabs (>=2022.1.2b11)", "sphinxcontrib-programoutput (>=0.17)", "towncrier (>=22.12)"] +lint = ["black (==22.12)", "isort (==5.11.4)", "mypy (==0.991)", "ruff (==0.0.272)"] +test = ["anyio (>=4.4.0)", "covdefaults (>=2.2.2)", "coverage (>=7.0.5)", "flaky (>=3.7)", "pytest (>=7.2)", "pytest-xdist (>=3.1)"] [[package]] name = "pytest-mock" @@ -2253,17 +2487,17 @@ typing-extensions = ">=4.9.0" [[package]] name = "python-iso639" -version = "2024.4.27" +version = "2024.10.22" description = "ISO 639 language codes, names, and other associated information" optional = false python-versions = ">=3.8" files = [ - {file = "python_iso639-2024.4.27-py3-none-any.whl", hash = "sha256:27526a84cebc4c4d53fea9d1ebbc7209c8d279bebaa343e6765a1fc8780565ab"}, - {file = "python_iso639-2024.4.27.tar.gz", hash = "sha256:97e63b5603e085c6a56a12a95740010e75d9134e0aab767e0978b53fd8824f13"}, + {file = "python_iso639-2024.10.22-py3-none-any.whl", hash = "sha256:02d3ce2e01c6896b30b9cbbd3e1c8ee0d7221250b5d63ea9803e0d2a81fd1047"}, + {file = "python_iso639-2024.10.22.tar.gz", hash = "sha256:750f21b6a0bc6baa24253a3d8aae92b582bf93aa40988361cd96852c2c6d9a52"}, ] [package.extras] -dev = ["black (==24.4.2)", "build (==1.2.1)", "flake8 (==7.0.0)", "pytest (==8.1.2)", "requests (==2.31.0)", "twine (==5.0.0)"] +dev = ["black (==24.10.0)", "build (==1.2.1)", "flake8 (==7.1.1)", "pytest (==8.3.3)", "requests (==2.32.3)", "twine (==5.1.1)"] [[package]] name = "python-magic" @@ -2305,6 +2539,20 @@ files = [ [package.dependencies] cramjam = "*" +[[package]] +name = "python-ulid" +version = "3.0.0" +description = "Universally unique lexicographically sortable identifier" +optional = false +python-versions = ">=3.9" +files = [ + {file = "python_ulid-3.0.0-py3-none-any.whl", hash = "sha256:e4c4942ff50dbd79167ad01ac725ec58f924b4018025ce22c858bfcff99a5e31"}, + {file = "python_ulid-3.0.0.tar.gz", hash = "sha256:e50296a47dc8209d28629a22fc81ca26c00982c78934bd7766377ba37ea49a9f"}, +] + +[package.extras] +pydantic = ["pydantic (>=2.0)"] + [[package]] name = "pytz" version = "2024.1" @@ -2329,25 +2577,29 @@ files = [ [[package]] name = "pywin32" -version = "306" +version = "308" description = "Python for Window Extensions" optional = false python-versions = "*" files = [ - {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, - {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, - {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, - {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, - {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, - {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, - {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, - {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, - {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, - {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, - {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, - {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, - {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, - {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, + {file = "pywin32-308-cp310-cp310-win32.whl", hash = "sha256:796ff4426437896550d2981b9c2ac0ffd75238ad9ea2d3bfa67a1abd546d262e"}, + {file = "pywin32-308-cp310-cp310-win_amd64.whl", hash = "sha256:4fc888c59b3c0bef905ce7eb7e2106a07712015ea1c8234b703a088d46110e8e"}, + {file = "pywin32-308-cp310-cp310-win_arm64.whl", hash = "sha256:a5ab5381813b40f264fa3495b98af850098f814a25a63589a8e9eb12560f450c"}, + {file = "pywin32-308-cp311-cp311-win32.whl", hash = "sha256:5d8c8015b24a7d6855b1550d8e660d8daa09983c80e5daf89a273e5c6fb5095a"}, + {file = "pywin32-308-cp311-cp311-win_amd64.whl", hash = "sha256:575621b90f0dc2695fec346b2d6302faebd4f0f45c05ea29404cefe35d89442b"}, + {file = "pywin32-308-cp311-cp311-win_arm64.whl", hash = "sha256:100a5442b7332070983c4cd03f2e906a5648a5104b8a7f50175f7906efd16bb6"}, + {file = "pywin32-308-cp312-cp312-win32.whl", hash = "sha256:587f3e19696f4bf96fde9d8a57cec74a57021ad5f204c9e627e15c33ff568897"}, + {file = "pywin32-308-cp312-cp312-win_amd64.whl", hash = "sha256:00b3e11ef09ede56c6a43c71f2d31857cf7c54b0ab6e78ac659497abd2834f47"}, + {file = "pywin32-308-cp312-cp312-win_arm64.whl", hash = "sha256:9b4de86c8d909aed15b7011182c8cab38c8850de36e6afb1f0db22b8959e3091"}, + {file = "pywin32-308-cp313-cp313-win32.whl", hash = "sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed"}, + {file = "pywin32-308-cp313-cp313-win_amd64.whl", hash = "sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4"}, + {file = "pywin32-308-cp313-cp313-win_arm64.whl", hash = "sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd"}, + {file = "pywin32-308-cp37-cp37m-win32.whl", hash = "sha256:1f696ab352a2ddd63bd07430080dd598e6369152ea13a25ebcdd2f503a38f1ff"}, + {file = "pywin32-308-cp37-cp37m-win_amd64.whl", hash = "sha256:13dcb914ed4347019fbec6697a01a0aec61019c1046c2b905410d197856326a6"}, + {file = "pywin32-308-cp38-cp38-win32.whl", hash = "sha256:5794e764ebcabf4ff08c555b31bd348c9025929371763b2183172ff4708152f0"}, + {file = "pywin32-308-cp38-cp38-win_amd64.whl", hash = "sha256:3b92622e29d651c6b783e368ba7d6722b1634b8e70bd376fd7610fe1992e19de"}, + {file = "pywin32-308-cp39-cp39-win32.whl", hash = "sha256:7873ca4dc60ab3287919881a7d4f88baee4a6e639aa6962de25a98ba6b193341"}, + {file = "pywin32-308-cp39-cp39-win_amd64.whl", hash = "sha256:71b3322d949b4cc20776436a9c9ba0eeedcbc9c650daa536df63f0ff111bb920"}, ] [[package]] @@ -2414,99 +2666,99 @@ files = [ [[package]] name = "rapidfuzz" -version = "3.10.0" +version = "3.10.1" description = "rapid fuzzy string matching" optional = false python-versions = ">=3.9" files = [ - {file = "rapidfuzz-3.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:884453860de029380dded8f3c1918af2d8eb5adf8010261645c7e5c88c2b5428"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718c9bd369288aca5fa929df6dbf66fdbe9768d90940a940c0b5cdc96ade4309"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a68e3724b7dab761c01816aaa64b0903734d999d5589daf97c14ef5cc0629a8e"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1af60988d47534246d9525f77288fdd9de652608a4842815d9018570b959acc6"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3084161fc3e963056232ef8d937449a2943852e07101f5a136c8f3cfa4119217"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6cd67d3d017296d98ff505529104299f78433e4b8af31b55003d901a62bbebe9"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b11a127ac590fc991e8a02c2d7e1ac86e8141c92f78546f18b5c904064a0552c"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aadce42147fc09dcef1afa892485311e824c050352e1aa6e47f56b9b27af4cf0"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b54853c2371bf0e38d67da379519deb6fbe70055efb32f6607081641af3dc752"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ce19887268e90ee81a3957eef5e46a70ecc000713796639f83828b950343f49e"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f39a2a5ded23b9b9194ec45740dce57177b80f86c6d8eba953d3ff1a25c97766"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0ec338d5f4ad8d9339a88a08db5c23e7f7a52c2b2a10510c48a0cef1fb3f0ddc"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-win32.whl", hash = "sha256:56fd15ea8f4c948864fa5ebd9261c67cf7b89a1c517a0caef4df75446a7af18c"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:43dfc5e733808962a822ff6d9c29f3039a3cfb3620706f5953e17cfe4496724c"}, - {file = "rapidfuzz-3.10.0-cp310-cp310-win_arm64.whl", hash = "sha256:ae7966f205b5a7fde93b44ca8fed37c1c8539328d7f179b1197de34eceaceb5f"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bb0013795b40db5cf361e6f21ee7cda09627cf294977149b50e217d7fe9a2f03"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:69ef5b363afff7150a1fbe788007e307b9802a2eb6ad92ed51ab94e6ad2674c6"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c582c46b1bb0b19f1a5f4c1312f1b640c21d78c371a6615c34025b16ee56369b"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:288f6f6e7410cacb115fb851f3f18bf0e4231eb3f6cb5bd1cec0e7b25c4d039d"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9e29a13d2fd9be3e7d8c26c7ef4ba60b5bc7efbc9dbdf24454c7e9ebba31768"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea2da0459b951ee461bd4e02b8904890bd1c4263999d291c5cd01e6620177ad4"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:457827ba82261aa2ae6ac06a46d0043ab12ba7216b82d87ae1434ec0f29736d6"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5d350864269d56f51ab81ab750c9259ae5cad3152c0680baef143dcec92206a1"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a9b8f51e08c3f983d857c3889930af9ddecc768453822076683664772d87e374"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7f3a6aa6e70fc27e4ff5c479f13cc9fc26a56347610f5f8b50396a0d344c5f55"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:803f255f10d63420979b1909ef976e7d30dec42025c9b067fc1d2040cc365a7e"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2026651761bf83a0f31495cc0f70840d5c0d54388f41316e3f9cb51bd85e49a5"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-win32.whl", hash = "sha256:4df75b3ebbb8cfdb9bf8b213b168620b88fd92d0c16a8bc9f9234630b282db59"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:f9f0bbfb6787b97c51516f3ccf97737d504db5d239ad44527673b81f598b84ab"}, - {file = "rapidfuzz-3.10.0-cp311-cp311-win_arm64.whl", hash = "sha256:10fdad800441b9c97d471a937ba7d42625f1b530db05e572f1cb7d401d95c893"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7dc87073ba3a40dd65591a2100aa71602107443bf10770579ff9c8a3242edb94"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a425a0a868cf8e9c6e93e1cda4b758cdfd314bb9a4fc916c5742c934e3613480"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a86d5d1d75e61df060c1e56596b6b0a4422a929dff19cc3dbfd5eee762c86b61"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34f213d59219a9c3ca14e94a825f585811a68ac56b4118b4dc388b5b14afc108"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96ad46f5f56f70fab2be9e5f3165a21be58d633b90bf6e67fc52a856695e4bcf"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9178277f72d144a6c7704d7ae7fa15b7b86f0f0796f0e1049c7b4ef748a662ef"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76a35e9e19a7c883c422ffa378e9a04bc98cb3b29648c5831596401298ee51e6"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a6405d34c394c65e4f73a1d300c001f304f08e529d2ed6413b46ee3037956eb"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bd393683129f446a75d8634306aed7e377627098a1286ff3af2a4f1736742820"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b0445fa9880ead81f5a7d0efc0b9c977a947d8052c43519aceeaf56eabaf6843"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:c50bc308fa29767ed8f53a8d33b7633a9e14718ced038ed89d41b886e301da32"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e89605afebbd2d4b045bccfdc12a14b16fe8ccbae05f64b4b4c64a97dad1c891"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-win32.whl", hash = "sha256:2db9187f3acf3cd33424ecdbaad75414c298ecd1513470df7bda885dcb68cc15"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:50e3d0c72ea15391ba9531ead7f2068a67c5b18a6a365fef3127583aaadd1725"}, - {file = "rapidfuzz-3.10.0-cp312-cp312-win_arm64.whl", hash = "sha256:9eac95b4278bd53115903d89118a2c908398ee8bdfd977ae844f1bd2b02b917c"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fe5231e8afd069c742ac5b4f96344a0fe4aff52df8e53ef87faebf77f827822c"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:886882367dbc985f5736356105798f2ae6e794e671fc605476cbe2e73838a9bb"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b33e13e537e3afd1627d421a142a12bbbe601543558a391a6fae593356842f6e"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:094c26116d55bf9c53abd840d08422f20da78ec4c4723e5024322321caedca48"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:545fc04f2d592e4350f59deb0818886c1b444ffba3bec535b4fbb97191aaf769"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:916a6abf3632e592b937c3d04c00a6efadd8fd30539cdcd4e6e4d92be7ca5d90"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb6ec40cef63b1922083d33bfef2f91fc0b0bc07b5b09bfee0b0f1717d558292"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c77a7330dd15c7eb5fd3631dc646fc96327f98db8181138766bd14d3e905f0ba"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:949b5e9eeaa4ecb4c7e9c2a4689dddce60929dd1ff9c76a889cdbabe8bbf2171"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b5363932a5aab67010ae1a6205c567d1ef256fb333bc23c27582481606be480c"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5dd6eec15b13329abe66cc241b484002ecb0e17d694491c944a22410a6a9e5e2"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79e7f98525b60b3c14524e0a4e1fedf7654657b6e02eb25f1be897ab097706f3"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-win32.whl", hash = "sha256:d29d1b9857c65f8cb3a29270732e1591b9bacf89de9d13fa764f79f07d8f1fd2"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:fa9720e56663cc3649d62b4b5f3145e94b8f5611e8a8e1b46507777249d46aad"}, - {file = "rapidfuzz-3.10.0-cp313-cp313-win_arm64.whl", hash = "sha256:eda4c661e68dddd56c8fbfe1ca35e40dd2afd973f7ebb1605f4d151edc63dff8"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cffbc50e0767396ed483900900dd58ce4351bc0d40e64bced8694bd41864cc71"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c038b9939da3035afb6cb2f465f18163e8f070aba0482923ecff9443def67178"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca366c2e2a54e2f663f4529b189fdeb6e14d419b1c78b754ec1744f3c01070d4"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c4c82b1689b23b1b5e6a603164ed2be41b6f6de292a698b98ba2381e889eb9d"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98f6ebe28831a482981ecfeedc8237047878424ad0c1add2c7f366ba44a20452"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4bd1a7676ee2a4c8e2f7f2550bece994f9f89e58afb96088964145a83af7408b"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec9139baa3f85b65adc700eafa03ed04995ca8533dd56c924f0e458ffec044ab"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:26de93e6495078b6af4c4d93a42ca067b16cc0e95699526c82ab7d1025b4d3bf"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f3a0bda83c18195c361b5500377d0767749f128564ca95b42c8849fd475bb327"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:63e4c175cbce8c3adc22dca5e6154588ae673f6c55374d156f3dac732c88d7de"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4dd3d8443970eaa02ab5ae45ce584b061f2799cd9f7e875190e2617440c1f9d4"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e5ddb2388610799fc46abe389600625058f2a73867e63e20107c5ad5ffa57c47"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-win32.whl", hash = "sha256:2e9be5d05cd960914024412b5406fb75a82f8562f45912ff86255acbfdbfb78e"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:47aca565a39c9a6067927871973ca827023e8b65ba6c5747f4c228c8d7ddc04f"}, - {file = "rapidfuzz-3.10.0-cp39-cp39-win_arm64.whl", hash = "sha256:b0732343cdc4273b5921268026dd7266f75466eb21873cb7635a200d9d9c3fac"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f744b5eb1469bf92dd143d36570d2bdbbdc88fe5cb0b5405e53dd34f479cbd8a"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b67cc21a14327a0eb0f47bc3d7e59ec08031c7c55220ece672f9476e7a8068d3"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fe5783676f0afba4a522c80b15e99dbf4e393c149ab610308a8ef1f04c6bcc8"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4688862f957c8629d557d084f20b2d803f8738b6c4066802a0b1cc472e088d9"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20bd153aacc244e4c907d772c703fea82754c4db14f8aa64d75ff81b7b8ab92d"}, - {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:50484d563f8bfa723c74c944b0bb15b9e054db9c889348c8c307abcbee75ab92"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5897242d455461f2c5b82d7397b29341fd11e85bf3608a522177071044784ee8"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:116c71a81e046ba56551d8ab68067ca7034d94b617545316d460a452c5c3c289"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0a547e4350d1fa32624d3eab51eff8cf329f4cae110b4ea0402486b1da8be40"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:399b9b79ccfcf50ca3bad7692bc098bb8eade88d7d5e15773b7f866c91156d0c"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7947a425d1be3e744707ee58c6cb318b93a56e08f080722dcc0347e0b7a1bb9a"}, - {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:94c48b4a2a4b1d22246f48e2b11cae01ec7d23f0c9123f8bb822839ad79d0a88"}, - {file = "rapidfuzz-3.10.0.tar.gz", hash = "sha256:6b62af27e65bb39276a66533655a2fa3c60a487b03935721c45b7809527979be"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f17d9f21bf2f2f785d74f7b0d407805468b4c173fa3e52c86ec94436b338e74a"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b31f358a70efc143909fb3d75ac6cd3c139cd41339aa8f2a3a0ead8315731f2b"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f4f43f2204b56a61448ec2dd061e26fd344c404da99fb19f3458200c5874ba2"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d81bf186a453a2757472133b24915768abc7c3964194406ed93e170e16c21cb"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3611c8f45379a12063d70075c75134f2a8bd2e4e9b8a7995112ddae95ca1c982"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c3b537b97ac30da4b73930fa8a4fe2f79c6d1c10ad535c5c09726612cd6bed9"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:231ef1ec9cf7b59809ce3301006500b9d564ddb324635f4ea8f16b3e2a1780da"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ed4f3adc1294834955b7e74edd3c6bd1aad5831c007f2d91ea839e76461a5879"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:7b6015da2e707bf632a71772a2dbf0703cff6525732c005ad24987fe86e8ec32"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1b35a118d61d6f008e8e3fb3a77674d10806a8972c7b8be433d6598df4d60b01"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:bc308d79a7e877226f36bdf4e149e3ed398d8277c140be5c1fd892ec41739e6d"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f017dbfecc172e2d0c37cf9e3d519179d71a7f16094b57430dffc496a098aa17"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-win32.whl", hash = "sha256:36c0e1483e21f918d0f2f26799fe5ac91c7b0c34220b73007301c4f831a9c4c7"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:10746c1d4c8cd8881c28a87fd7ba0c9c102346dfe7ff1b0d021cdf093e9adbff"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-win_arm64.whl", hash = "sha256:dfa64b89dcb906835e275187569e51aa9d546a444489e97aaf2cc84011565fbe"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:92958ae075c87fef393f835ed02d4fe8d5ee2059a0934c6c447ea3417dfbf0e8"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ba7521e072c53e33c384e78615d0718e645cab3c366ecd3cc8cb732befd94967"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d02cbd75d283c287471b5b3738b3e05c9096150f93f2d2dfa10b3d700f2db9"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:efa1582a397da038e2f2576c9cd49b842f56fde37d84a6b0200ffebc08d82350"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f12912acee1f506f974f58de9fdc2e62eea5667377a7e9156de53241c05fdba8"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666d5d8b17becc3f53447bcb2b6b33ce6c2df78792495d1fa82b2924cd48701a"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26f71582c0d62445067ee338ddad99b655a8f4e4ed517a90dcbfbb7d19310474"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8a2ef08b27167bcff230ffbfeedd4c4fa6353563d6aaa015d725dd3632fc3de7"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:365e4fc1a2b95082c890f5e98489b894e6bf8c338c6ac89bb6523c2ca6e9f086"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1996feb7a61609fa842e6b5e0c549983222ffdedaf29644cc67e479902846dfe"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:cf654702f144beaa093103841a2ea6910d617d0bb3fccb1d1fd63c54dde2cd49"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec108bf25de674781d0a9a935030ba090c78d49def3d60f8724f3fc1e8e75024"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-win32.whl", hash = "sha256:031f8b367e5d92f7a1e27f7322012f3c321c3110137b43cc3bf678505583ef48"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:f98f36c6a1bb9a6c8bbec99ad87c8c0e364f34761739b5ea9adf7b48129ae8cf"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-win_arm64.whl", hash = "sha256:f1da2028cb4e41be55ee797a82d6c1cf589442504244249dfeb32efc608edee7"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1340b56340896bede246f612b6ecf685f661a56aabef3d2512481bfe23ac5835"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2316515169b7b5a453f0ce3adbc46c42aa332cae9f2edb668e24d1fc92b2f2bb"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e06fe6a12241ec1b72c0566c6b28cda714d61965d86569595ad24793d1ab259"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d99c1cd9443b19164ec185a7d752f4b4db19c066c136f028991a480720472e23"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1d9aa156ed52d3446388ba4c2f335e312191d1ca9d1f5762ee983cf23e4ecf6"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:54bcf4efaaee8e015822be0c2c28214815f4f6b4f70d8362cfecbd58a71188ac"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0c955e32afdbfdf6e9ee663d24afb25210152d98c26d22d399712d29a9b976b"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:191633722203f5b7717efcb73a14f76f3b124877d0608c070b827c5226d0b972"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:195baad28057ec9609e40385991004e470af9ef87401e24ebe72c064431524ab"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0fff4a6b87c07366662b62ae994ffbeadc472e72f725923f94b72a3db49f4671"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4ffed25f9fdc0b287f30a98467493d1e1ce5b583f6317f70ec0263b3c97dbba6"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d02cf8e5af89a9ac8f53c438ddff6d773f62c25c6619b29db96f4aae248177c0"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-win32.whl", hash = "sha256:f3bb81d4fe6a5d20650f8c0afcc8f6e1941f6fecdb434f11b874c42467baded0"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:aaf83e9170cb1338922ae42d320699dccbbdca8ffed07faeb0b9257822c26e24"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-win_arm64.whl", hash = "sha256:c5da802a0d085ad81b0f62828fb55557996c497b2d0b551bbdfeafd6d447892f"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fc22d69a1c9cccd560a5c434c0371b2df0f47c309c635a01a913e03bbf183710"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38b0dac2c8e057562b8f0d8ae5b663d2d6a28c5ab624de5b73cef9abb6129a24"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fde3bbb14e92ce8fcb5c2edfff72e474d0080cadda1c97785bf4822f037a309"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9141fb0592e55f98fe9ac0f3ce883199b9c13e262e0bf40c5b18cdf926109d16"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:237bec5dd1bfc9b40bbd786cd27949ef0c0eb5fab5eb491904c6b5df59d39d3c"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18123168cba156ab5794ea6de66db50f21bb3c66ae748d03316e71b27d907b95"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b75fe506c8e02769cc47f5ab21ce3e09b6211d3edaa8f8f27331cb6988779be"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9da82aa4b46973aaf9e03bb4c3d6977004648c8638febfc0f9d237e865761270"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c34c022d5ad564f1a5a57a4a89793bd70d7bad428150fb8ff2760b223407cdcf"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1e96c84d6c2a0ca94e15acb5399118fff669f4306beb98a6d8ec6f5dccab4412"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e8e154b84a311263e1aca86818c962e1fa9eefdd643d1d5d197fcd2738f88cb9"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:335fee93188f8cd585552bb8057228ce0111bd227fa81bfd40b7df6b75def8ab"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-win32.whl", hash = "sha256:6729b856166a9e95c278410f73683957ea6100c8a9d0a8dbe434c49663689255"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-win_amd64.whl", hash = "sha256:0e06d99ad1ad97cb2ef7f51ec6b1fedd74a3a700e4949353871cf331d07b382a"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-win_arm64.whl", hash = "sha256:8d1b7082104d596a3eb012e0549b2634ed15015b569f48879701e9d8db959dbb"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:779027d3307e1a2b1dc0c03c34df87a470a368a1a0840a9d2908baf2d4067956"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:440b5608ab12650d0390128d6858bc839ae77ffe5edf0b33a1551f2fa9860651"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cac41a411e07a6f3dc80dfbd33f6be70ea0abd72e99c59310819d09f07d945"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:958473c9f0bca250590200fd520b75be0dbdbc4a7327dc87a55b6d7dc8d68552"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ef60dfa73749ef91cb6073be1a3e135f4846ec809cc115f3cbfc6fe283a5584"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7fbac18f2c19fc983838a60611e67e3262e36859994c26f2ee85bb268de2355"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a0d519ff39db887cd73f4e297922786d548f5c05d6b51f4e6754f452a7f4296"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bebb7bc6aeb91cc57e4881b222484c26759ca865794187217c9dcea6c33adae6"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fe07f8b9c3bb5c5ad1d2c66884253e03800f4189a60eb6acd6119ebaf3eb9894"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:bfa48a4a2d45a41457f0840c48e579db157a927f4e97acf6e20df8fc521c79de"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2cf44d01bfe8ee605b7eaeecbc2b9ca64fc55765f17b304b40ed8995f69d7716"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e6bbca9246d9eedaa1c84e04a7f555493ba324d52ae4d9f3d9ddd1b740dcd87"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-win32.whl", hash = "sha256:567f88180f2c1423b4fe3f3ad6e6310fc97b85bdba574801548597287fc07028"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:6b2cd7c29d6ecdf0b780deb587198f13213ac01c430ada6913452fd0c40190fc"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-win_arm64.whl", hash = "sha256:9f912d459e46607ce276128f52bea21ebc3e9a5ccf4cccfef30dd5bddcf47be8"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ac4452f182243cfab30ba4668ef2de101effaedc30f9faabb06a095a8c90fd16"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:565c2bd4f7d23c32834652b27b51dd711814ab614b4e12add8476be4e20d1cf5"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:187d9747149321607be4ccd6f9f366730078bed806178ec3eeb31d05545e9e8f"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:616290fb9a8fa87e48cb0326d26f98d4e29f17c3b762c2d586f2b35c1fd2034b"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:073a5b107e17ebd264198b78614c0206fa438cce749692af5bc5f8f484883f50"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:39c4983e2e2ccb9732f3ac7d81617088822f4a12291d416b09b8a1eadebb3e29"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ac7adee6bcf0c6fee495d877edad1540a7e0f5fc208da03ccb64734b43522d7a"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:425f4ac80b22153d391ee3f94bc854668a0c6c129f05cf2eaf5ee74474ddb69e"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65a2fa13e8a219f9b5dcb9e74abe3ced5838a7327e629f426d333dfc8c5a6e66"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75561f3df9a906aaa23787e9992b228b1ab69007932dc42070f747103e177ba8"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:edd062490537e97ca125bc6c7f2b7331c2b73d21dc304615afe61ad1691e15d5"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfcc8feccf63245a22dfdd16e222f1a39771a44b870beb748117a0e09cbb4a62"}, + {file = "rapidfuzz-3.10.1.tar.gz", hash = "sha256:5a15546d847a915b3f42dc79ef9b0c78b998b4e2c53b252e7166284066585979"}, ] [package.extras] @@ -2514,105 +2766,105 @@ all = ["numpy"] [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -2680,6 +2932,25 @@ files = [ [package.dependencies] requests = ">=2.0.1,<3.0.0" +[[package]] +name = "rich" +version = "13.9.4" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"}, + {file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" +typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.11\""} + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + [[package]] name = "serpyco-rs" version = "1.11.0" @@ -2734,26 +3005,6 @@ files = [ attributes-doc = "*" typing-extensions = "*" -[[package]] -name = "setuptools" -version = "75.1.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"}, - {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] - [[package]] name = "six" version = "1.16.0" @@ -2817,32 +3068,53 @@ doc = ["reno", "sphinx"] test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" +name = "textual" +version = "0.87.1" +description = "Modern Text User Interface framework" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "<4.0.0,>=3.8.1" +files = [ + {file = "textual-0.87.1-py3-none-any.whl", hash = "sha256:026d1368cd10610a72a9d3de7a56692a17e7e8dffa0468147eb8e186ba0ff0c0"}, + {file = "textual-0.87.1.tar.gz", hash = "sha256:daf4e248ba3d890831ff2617099535eb835863a2e3609c8ce00af0f6d55ed123"}, +] + +[package.dependencies] +markdown-it-py = {version = ">=2.1.0", extras = ["linkify", "plugins"]} +platformdirs = ">=3.6.0,<5" +rich = ">=13.3.3" +typing-extensions = ">=4.4.0,<5.0.0" + +[package.extras] +syntax = ["tree-sitter (>=0.20.1,<0.21.0)", "tree-sitter-languages (==1.10.2)"] + +[[package]] +name = "tomli" +version = "2.1.0" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.8" files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, + {file = "tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391"}, + {file = "tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8"}, ] [[package]] name = "tqdm" -version = "4.66.5" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd"}, - {file = "tqdm-4.66.5.tar.gz", hash = "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -2884,6 +3156,20 @@ files = [ {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, ] +[[package]] +name = "uc-micro-py" +version = "1.0.3" +description = "Micro subset of unicode data files for linkify-it-py projects." +optional = false +python-versions = ">=3.7" +files = [ + {file = "uc-micro-py-1.0.3.tar.gz", hash = "sha256:d321b92cff673ec58027c04015fcaa8bb1e005478643ff4a500882eaab88c48a"}, + {file = "uc_micro_py-1.0.3-py3-none-any.whl", hash = "sha256:db1dffff340817673d7b466ec86114a9dc0e9d4d9b5ba229d9d60e5c12600cd5"}, +] + +[package.extras] +test = ["coverage", "pytest", "pytest-cov"] + [[package]] name = "unstructured" version = "0.10.27" @@ -3012,13 +3298,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "wcmatch" -version = "8.4" +version = "10.0" description = "Wildcard/glob file name matcher." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, + {file = "wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a"}, + {file = "wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a"}, ] [package.dependencies] @@ -3026,81 +3312,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [[package]] @@ -3114,7 +3395,18 @@ files = [ {file = "XlsxWriter-3.2.0.tar.gz", hash = "sha256:9977d0c661a72866a61f9f7a809e25ebbb0fb7036baa3b9fe74afcfca6b3cb8c"}, ] +[[package]] +name = "xmltodict" +version = "0.13.0" +description = "Makes working with XML feel like you are working with JSON" +optional = false +python-versions = ">=3.4" +files = [ + {file = "xmltodict-0.13.0-py2.py3-none-any.whl", hash = "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"}, + {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"}, +] + [metadata] lock-version = "2.0" python-versions = "^3.10,<3.12" -content-hash = "0eeab97d0a9cfff069ed060c693f3f96b61b4e63877abf70396e2012ba6e0330" +content-hash = "74a2c478a4e678485600cc9a1f6affa8090708d71b7ce6eb8d06216ed37165a3" diff --git a/airbyte-integrations/connectors/source-sftp-bulk/pyproject.toml b/airbyte-integrations/connectors/source-sftp-bulk/pyproject.toml index a1c1340654db..88a8b2a1197c 100644 --- a/airbyte-integrations/connectors/source-sftp-bulk/pyproject.toml +++ b/airbyte-integrations/connectors/source-sftp-bulk/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "1.2.0" +version = "1.6.0" name = "source-sftp-bulk" description = "Source implementation for SFTP Bulk." authors = [ "Airbyte ",] @@ -17,7 +17,7 @@ include = "source_sftp_bulk" [tool.poetry.dependencies] python = "^3.10,<3.12" -airbyte-cdk = {version = "^5", extras = ["file-based"]} +airbyte-cdk = {version = "^6.5.2", extras = ["file-based"]} paramiko = "3.4.0" [tool.poetry.scripts] @@ -27,4 +27,5 @@ source-sftp-bulk = "source_sftp_bulk.run:run" docker = "^7.0.0" freezegun = "^1.4.0" pytest-mock = "^3.6.1" -pytest = "^6.1" +pytest = "^7" +pytest-memray = "^1.6.0" diff --git a/airbyte-integrations/connectors/source-sftp-bulk/source_sftp_bulk/client.py b/airbyte-integrations/connectors/source-sftp-bulk/source_sftp_bulk/client.py index 8a18fac42f1e..1f6e04360fc1 100644 --- a/airbyte-integrations/connectors/source-sftp-bulk/source_sftp_bulk/client.py +++ b/airbyte-integrations/connectors/source-sftp-bulk/source_sftp_bulk/client.py @@ -9,9 +9,11 @@ import backoff import paramiko -from airbyte_cdk import AirbyteTracedException, FailureType from paramiko.ssh_exception import AuthenticationException +from airbyte_cdk import AirbyteTracedException, FailureType + + # set default timeout to 300 seconds REQUEST_TIMEOUT = 300 diff --git a/airbyte-integrations/connectors/source-sftp-bulk/source_sftp_bulk/source.py b/airbyte-integrations/connectors/source-sftp-bulk/source_sftp_bulk/source.py index 96b84eda4c94..5a10c33cfc9d 100644 --- a/airbyte-integrations/connectors/source-sftp-bulk/source_sftp_bulk/source.py +++ b/airbyte-integrations/connectors/source-sftp-bulk/source_sftp_bulk/source.py @@ -12,6 +12,7 @@ from source_sftp_bulk.spec import SourceSFTPBulkSpec from source_sftp_bulk.stream_reader import SourceSFTPBulkStreamReader + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-sftp-bulk/source_sftp_bulk/spec.py b/airbyte-integrations/connectors/source-sftp-bulk/source_sftp_bulk/spec.py index 0490b8bd98c4..23edbcf1ebf0 100644 --- a/airbyte-integrations/connectors/source-sftp-bulk/source_sftp_bulk/spec.py +++ b/airbyte-integrations/connectors/source-sftp-bulk/source_sftp_bulk/spec.py @@ -3,10 +3,11 @@ from typing import Literal, Optional, Union -from airbyte_cdk import OneOfOptionConfig -from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec from pydantic.v1 import BaseModel, Field +from airbyte_cdk import OneOfOptionConfig +from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec, DeliverRawFiles, DeliverRecords + class PasswordCredentials(BaseModel): class Config(OneOfOptionConfig): @@ -23,7 +24,7 @@ class Config(OneOfOptionConfig): discriminator = "auth_type" auth_type: Literal["private_key"] = Field("private_key", const=True) - private_key: str = Field(title="Private key", description="The Private key", multiline=True, order=4) + private_key: str = Field(title="Private key", description="The Private key", multiline=True, order=4, airbyte_secret=True) class SourceSFTPBulkSpec(AbstractFileBasedSpec): @@ -49,6 +50,16 @@ class Config: pattern_descriptor="/folder_to_sync", ) + delivery_method: Union[DeliverRecords, DeliverRawFiles] = Field( + title="Delivery Method", + discriminator="delivery_type", + type="object", + order=7, + display_type="radio", + group="advanced", + default="use_records_transfer", + ) + @classmethod def documentation_url(cls) -> str: return "https://docs.airbyte.com/integrations/sources/sftp-bulk" diff --git a/airbyte-integrations/connectors/source-sftp-bulk/source_sftp_bulk/stream_reader.py b/airbyte-integrations/connectors/source-sftp-bulk/source_sftp_bulk/stream_reader.py index a6283ba5ca3f..d3f0ae7c525a 100644 --- a/airbyte-integrations/connectors/source-sftp-bulk/source_sftp_bulk/stream_reader.py +++ b/airbyte-integrations/connectors/source-sftp-bulk/source_sftp_bulk/stream_reader.py @@ -4,9 +4,15 @@ import datetime import logging import stat +import time from io import IOBase -from typing import Iterable, List, Optional +from typing import Dict, Iterable, List, Optional +import psutil +from typing_extensions import override + +from airbyte_cdk import FailureType +from airbyte_cdk.sources.file_based.exceptions import FileSizeLimitError from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode from airbyte_cdk.sources.file_based.remote_file import RemoteFile from source_sftp_bulk.client import SFTPClient @@ -14,6 +20,8 @@ class SourceSFTPBulkStreamReader(AbstractFileBasedStreamReader): + FILE_SIZE_LIMIT = 1_500_000_000 + def __init__(self): super().__init__() self._sftp_client = None @@ -81,3 +89,90 @@ def get_matching_files( def open_file(self, file: RemoteFile, mode: FileReadMode, encoding: Optional[str], logger: logging.Logger) -> IOBase: remote_file = self.sftp_client.sftp_connection.open(file.uri, mode=mode.value) return remote_file + + @staticmethod + def create_progress_handler(local_file_path: str, logger: logging.Logger): + previous_bytes_copied = 0 + + def progress_handler(bytes_copied, total_bytes): + nonlocal previous_bytes_copied + if bytes_copied - previous_bytes_copied >= 100 * 1024 * 1024: + logger.info( + f"{bytes_copied / (1024 * 1024):,.2f} MB ({bytes_copied / (1024 * 1024 * 1024):.2f} GB) " + f"of {total_bytes / (1024 * 1024):,.2f} MB ({total_bytes / (1024 * 1024 * 1024):.2f} GB) " + f"written to {local_file_path}" + ) + previous_bytes_copied = bytes_copied + + # Get available disk space + disk_usage = psutil.disk_usage("/") + available_disk_space = disk_usage.free + + # Get available memory + memory_info = psutil.virtual_memory() + available_memory = memory_info.available + logger.info( + f"Available disk space: {available_disk_space / (1024 * 1024):,.2f} MB ({available_disk_space / (1024 * 1024 * 1024):.2f} GB), " + f"available memory: {available_memory / (1024 * 1024):,.2f} MB ({available_memory / (1024 * 1024 * 1024):.2f} GB)." + ) + + return progress_handler + + @override + def get_file(self, file: RemoteFile, local_directory: str, logger: logging.Logger) -> Dict[str, str | int]: + """ + Downloads a file from SFTP server to a specified local directory. + + Args: + file (RemoteFile): The remote file object containing URI and metadata. + local_directory (str): The local directory path where the file will be downloaded. + logger (logging.Logger): Logger for logging information and errors. + + Returns: + dict: A dictionary containing the following: + - "file_url" (str): The absolute path of the downloaded file. + - "bytes" (int): The file size in bytes. + - "file_relative_path" (str): The relative path of the file for local storage. Is relative to local_directory as + this a mounted volume in the pod container. + + Raises: + FileSizeLimitError: If the file size exceeds the predefined limit (1 GB). + """ + file_size = self.file_size(file) + # I'm putting this check here so we can remove the safety wheels per connector when ready. + if file_size > self.FILE_SIZE_LIMIT: + message = "File size exceeds the 1 GB limit." + raise FileSizeLimitError(message=message, internal_message=message, failure_type=FailureType.config_error) + + file_relative_path, local_file_path, absolute_file_path = self._get_file_transfer_paths(file, local_directory) + + # Get available disk space + disk_usage = psutil.disk_usage("/") + available_disk_space = disk_usage.free + + # Get available memory + memory_info = psutil.virtual_memory() + available_memory = memory_info.available + + # Log file size, available disk space, and memory + logger.info( + f"Starting to download the file {file.uri} with size: {file_size / (1024 * 1024):,.2f} MB ({file_size / (1024 * 1024 * 1024):.2f} GB) " + f"to '{local_file_path}' " + f"with size: {file_size / (1024 * 1024):,.2f} MB ({file_size / (1024 * 1024 * 1024):.2f} GB), " + f"available disk space: {available_disk_space / (1024 * 1024):,.2f} MB ({available_disk_space / (1024 * 1024 * 1024):.2f} GB)," + f"available memory: {available_memory / (1024 * 1024):,.2f} MB ({available_memory / (1024 * 1024 * 1024):.2f} GB)." + ) + progress_handler = self.create_progress_handler(local_file_path, logger) + start_download_time = time.time() + # Copy a remote file in remote path from the SFTP server to the local host as local path. + self.sftp_client.sftp_connection.get(file.uri, local_file_path, callback=progress_handler) + + download_duration = time.time() - start_download_time + logger.info(f"Time taken to download the file {file.uri}: {download_duration:,.2f} seconds.") + logger.info(f"File {file_relative_path} successfully written to {local_directory}.") + + return {"file_url": absolute_file_path, "bytes": file_size, "file_relative_path": file_relative_path} + + def file_size(self, file: RemoteFile): + file_size = self.sftp_client.sftp_connection.stat(file.uri).st_size + return file_size diff --git a/airbyte-integrations/connectors/source-sftp-bulk/unit_tests/stream_reader_test.py b/airbyte-integrations/connectors/source-sftp-bulk/unit_tests/stream_reader_test.py index 1fa424d9d1a8..92c81a790b04 100644 --- a/airbyte-integrations/connectors/source-sftp-bulk/unit_tests/stream_reader_test.py +++ b/airbyte-integrations/connectors/source-sftp-bulk/unit_tests/stream_reader_test.py @@ -10,6 +10,7 @@ from source_sftp_bulk.spec import SourceSFTPBulkSpec from source_sftp_bulk.stream_reader import SourceSFTPBulkStreamReader + logger = logging.Logger("") diff --git a/airbyte-integrations/connectors/source-sftp/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-sftp/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-sftp/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-sftp/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-sharetribe/metadata.yaml b/airbyte-integrations/connectors/source-sharetribe/metadata.yaml index ebe3b8a2f029..ea50896331d4 100644 --- a/airbyte-integrations/connectors/source-sharetribe/metadata.yaml +++ b/airbyte-integrations/connectors/source-sharetribe/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-sharetribe connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.10.2@sha256:81db4f78a92d199f33c38c17f5b63fc87c56739f14dc10276ddec86c7b707b7a + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: efe368ce-cd19-4be4-a2b1-11c69dc6bffb - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-sharetribe githubIssueLabel: source-sharetribe icon: icon.svg diff --git a/airbyte-integrations/connectors/source-shippo/README.md b/airbyte-integrations/connectors/source-shippo/README.md new file mode 100644 index 000000000000..bd52fb172d2d --- /dev/null +++ b/airbyte-integrations/connectors/source-shippo/README.md @@ -0,0 +1,37 @@ +# Shippo +This directory contains the manifest-only connector for `source-shippo`. + +This is the Shippo source for ingesting data using the Shippo API. + +Shippo is your one-stop solution for shipping labels. Whether you use our app to ship or API to power your logistics workflow, Shippo gives you scalable shipping tools, the best rates, and world-class support https://goshippo.com/ + +In order to use this source, you must first create a Shippo account. Once logged in, head over to Settings -> Advanced -> API and click on generate new token. You can learn more about the API here https://docs.goshippo.com/shippoapi/public-api/#tag/Overview + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-shippo:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-shippo build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-shippo test +``` + diff --git a/airbyte-integrations/connectors/source-shippo/acceptance-test-config.yml b/airbyte-integrations/connectors/source-shippo/acceptance-test-config.yml new file mode 100644 index 000000000000..0cfe1d0e6190 --- /dev/null +++ b/airbyte-integrations/connectors/source-shippo/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-shippo:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-shippo/icon.svg b/airbyte-integrations/connectors/source-shippo/icon.svg new file mode 100644 index 000000000000..d011ec476ea5 --- /dev/null +++ b/airbyte-integrations/connectors/source-shippo/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-shippo/manifest.yaml b/airbyte-integrations/connectors/source-shippo/manifest.yaml new file mode 100644 index 000000000000..8d6fca2ec52b --- /dev/null +++ b/airbyte-integrations/connectors/source-shippo/manifest.yaml @@ -0,0 +1,1748 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + This is the Shippo source for ingesting data using the Shippo API. + + + Shippo is your one-stop solution for shipping labels. Whether you use our app + to ship or API to power your logistics workflow, Shippo gives you scalable + shipping tools, the best rates, and world-class support https://goshippo.com/ + + + In order to use this source, you must first create a Shippo account. Once + logged in, head over to Settings -> Advanced -> API and click on generate new + token. You can learn more about the API here + https://docs.goshippo.com/shippoapi/public-api/#tag/Overview + +check: + type: CheckStream + stream_names: + - addresses + +definitions: + streams: + addresses: + type: DeclarativeStream + name: addresses + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/addresses + http_method: GET + request_headers: + Authorization: ShippoToken {{ config["shippo_token"] }} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/addresses" + parcels: + type: DeclarativeStream + name: parcels + primary_key: + - object_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /parcels + http_method: GET + request_headers: + Authorization: ShippoToken {{ config["shippo_token"] }} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: results + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/parcels" + custom_items: + type: DeclarativeStream + name: custom_items + primary_key: + - object_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /customs/items + http_method: GET + request_headers: + Authorization: ShippoToken {{ config["shippo_token"] }} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: results + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/custom_items" + accounts: + type: DeclarativeStream + name: accounts + primary_key: + - object_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /shippo-accounts + http_method: GET + request_headers: + Authorization: ShippoToken {{ config["shippo_token"] }} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: results + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounts" + carrier_acounts: + type: DeclarativeStream + name: carrier_acounts + primary_key: + - object_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /carrier_accounts + http_method: GET + request_headers: + Authorization: ShippoToken {{ config["shippo_token"] }} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: results + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/carrier_acounts" + shipments: + type: DeclarativeStream + name: shipments + primary_key: + - object_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /shipments + http_method: GET + request_headers: + Authorization: ShippoToken {{ config["shippo_token"] }} + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: results + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + incremental_sync: + type: DatetimeBasedCursor + cursor_field: object_updated + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%fZ" + datetime_format: "%Y-%m-%dT%H:%M:%S.%fZ" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: object_created_gt + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/shipments" + base_requester: + type: HttpRequester + url_base: https://api.goshippo.com + +streams: + - $ref: "#/definitions/streams/addresses" + - $ref: "#/definitions/streams/parcels" + - $ref: "#/definitions/streams/custom_items" + - $ref: "#/definitions/streams/accounts" + - $ref: "#/definitions/streams/carrier_acounts" + - $ref: "#/definitions/streams/shipments" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - shippo_token + - start_date + properties: + shippo_token: + type: string + description: The bearer token used for making requests + title: Shippo Token + order: 0 + start_date: + type: string + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + order: 1 + additionalProperties: true + +metadata: + autoImportSchema: + addresses: true + parcels: true + custom_items: true + accounts: true + carrier_acounts: true + shipments: true + testedStreams: + addresses: + streamHash: c2a5943c1cc3c14e6f43ea454bdff5b2627cfc4b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + parcels: + streamHash: 9d088b7ef340fbe88c91a131f51eb872a5348cd1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + custom_items: + streamHash: 21c2e781324ebf7429927cedb992834eb107142a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + accounts: + streamHash: ff3113723dffb561047ec7348ba6e637c7068376 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + carrier_acounts: + streamHash: 17b1fc52b7f21c14dc6587530013aea90327a886 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + shipments: + streamHash: 4e50c91f3910aeb19cb1bb3270663c88d7efb3bd + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + addresses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address: + type: + - object + - "null" + properties: + address_line_1: + type: + - string + - "null" + address_line_2: + type: + - string + - "null" + address_type: + type: + - string + - "null" + city_locality: + type: + - string + - "null" + country_code: + type: + - string + - "null" + email: + type: + - string + - "null" + name: + type: + - string + - "null" + organization: + type: + - string + - "null" + phone: + type: + - string + - "null" + postal_code: + type: + - string + - "null" + state_province: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: string + updated_at: + type: + - string + - "null" + required: + - id + parcels: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + metadata: + type: + - string + - "null" + distance_unit: + type: + - string + - "null" + extra: + type: + - object + - "null" + properties: + COD: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + currency: + type: + - string + - "null" + payment_method: + type: + - string + - "null" + insurance: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + content: + type: + - string + - "null" + currency: + type: + - string + - "null" + provider: + type: + - string + - "null" + reference_1: + type: + - string + - "null" + reference_2: + type: + - string + - "null" + height: + type: + - string + - "null" + length: + type: + - string + - "null" + line_items: + type: + - array + - "null" + mass_unit: + type: + - string + - "null" + object_created: + type: + - string + - "null" + object_id: + type: string + object_owner: + type: + - string + - "null" + object_state: + type: + - string + - "null" + object_updated: + type: + - string + - "null" + test: + type: + - boolean + - "null" + weight: + type: + - string + - "null" + width: + type: + - string + - "null" + required: + - object_id + custom_items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + metadata: + type: + - string + - "null" + eccn_ear99: + type: + - string + - "null" + hs_code: + type: + - string + - "null" + mass_unit: + type: + - string + - "null" + net_weight: + type: + - string + - "null" + object_created: + type: + - string + - "null" + object_id: + type: string + object_owner: + type: + - string + - "null" + object_state: + type: + - string + - "null" + object_updated: + type: + - string + - "null" + origin_country: + type: + - string + - "null" + quantity: + type: + - number + - "null" + sku_code: + type: + - string + - "null" + tariff_number: + type: + - string + - "null" + test: + type: + - boolean + - "null" + value_amount: + type: + - string + - "null" + value_currency: + type: + - string + - "null" + required: + - object_id + accounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + last_name: + type: + - string + - "null" + object_created: + type: + - string + - "null" + object_id: + type: string + object_updated: + type: + - string + - "null" + required: + - object_id + carrier_acounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + metadata: + type: + - string + - "null" + account_id: + type: + - string + - "null" + active: + type: + - boolean + - "null" + carrier: + type: + - string + - "null" + carrier_images: + type: + - object + - "null" + properties: + "75": + type: + - string + - "null" + "200": + type: + - string + - "null" + carrier_name: + type: + - string + - "null" + is_shippo_account: + type: + - boolean + - "null" + object_id: + type: string + object_info: + type: + - object + - "null" + properties: + authentication: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + object_owner: + type: + - string + - "null" + parameters: + type: + - object + - "null" + properties: + expresslink_password: + type: + - string + - "null" + is_commercial: + type: + - string + - "null" + test: + type: + - boolean + - "null" + required: + - object_id + shipments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + metadata: + type: + - string + - "null" + address_from: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + company: + type: + - string + - "null" + country: + type: + - string + - "null" + email: + type: + - string + - "null" + is_complete: + type: + - boolean + - "null" + is_residential: + type: + - boolean + - "null" + name: + type: + - string + - "null" + object_id: + type: + - string + - "null" + phone: + type: + - string + - "null" + state: + type: + - string + - "null" + street1: + type: + - string + - "null" + street2: + type: + - string + - "null" + street3: + type: + - string + - "null" + street_no: + type: + - string + - "null" + test: + type: + - boolean + - "null" + validation_results: + type: + - object + - "null" + properties: + is_valid: + type: + - boolean + - "null" + messages: + type: + - array + - "null" + zip: + type: + - string + - "null" + address_return: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + company: + type: + - string + - "null" + country: + type: + - string + - "null" + email: + type: + - string + - "null" + is_complete: + type: + - boolean + - "null" + is_residential: + type: + - boolean + - "null" + name: + type: + - string + - "null" + object_id: + type: + - string + - "null" + phone: + type: + - string + - "null" + state: + type: + - string + - "null" + street1: + type: + - string + - "null" + street2: + type: + - string + - "null" + street3: + type: + - string + - "null" + street_no: + type: + - string + - "null" + test: + type: + - boolean + - "null" + validation_results: + type: + - object + - "null" + properties: + is_valid: + type: + - boolean + - "null" + messages: + type: + - array + - "null" + zip: + type: + - string + - "null" + address_to: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + company: + type: + - string + - "null" + country: + type: + - string + - "null" + email: + type: + - string + - "null" + is_complete: + type: + - boolean + - "null" + name: + type: + - string + - "null" + object_id: + type: + - string + - "null" + phone: + type: + - string + - "null" + state: + type: + - string + - "null" + street1: + type: + - string + - "null" + street2: + type: + - string + - "null" + street3: + type: + - string + - "null" + street_no: + type: + - string + - "null" + test: + type: + - boolean + - "null" + validation_results: + type: + - object + - "null" + properties: + is_valid: + type: + - boolean + - "null" + messages: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + code: + type: + - string + - "null" + source: + type: + - string + - "null" + text: + type: + - string + - "null" + zip: + type: + - string + - "null" + carrier_accounts: + type: + - array + - "null" + items: + type: + - string + - "null" + customs_declaration: + type: + - object + - "null" + properties: + metadata: + type: + - string + - "null" + address_importer: + type: + - string + - "null" + aes_itn: + type: + - string + - "null" + b13a_filing_option: + type: + - string + - "null" + b13a_number: + type: + - string + - "null" + certificate: + type: + - string + - "null" + certify: + type: + - boolean + - "null" + certify_signer: + type: + - string + - "null" + commercial_invoice: + type: + - boolean + - "null" + contents_explanation: + type: + - string + - "null" + contents_type: + type: + - string + - "null" + disclaimer: + type: + - string + - "null" + duties_payor: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + account: + type: + - string + - "null" + address: + type: + - object + - "null" + properties: + country: + type: + - string + - "null" + name: + type: + - string + - "null" + zip: + type: + - string + - "null" + object_created: + type: + - string + - "null" + object_updated: + type: + - string + - "null" + eel_pfc: + type: + - string + - "null" + exporter_identification: + type: + - object + - "null" + properties: + eori_number: + type: + - string + - "null" + tax_id: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + number: + type: + - string + - "null" + exporter_reference: + type: + - string + - "null" + importer_reference: + type: + - string + - "null" + incoterm: + type: + - string + - "null" + invoice: + type: + - string + - "null" + is_vat_collected: + type: + - boolean + - "null" + items: + type: + - array + - "null" + items: + type: + - string + - "null" + license: + type: + - string + - "null" + non_delivery_option: + type: + - string + - "null" + notes: + type: + - string + - "null" + object_created: + type: + - string + - "null" + object_id: + type: + - string + - "null" + object_owner: + type: + - string + - "null" + object_state: + type: + - string + - "null" + object_updated: + type: + - string + - "null" + test: + type: + - boolean + - "null" + extra: + type: + - object + - "null" + properties: + COD: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + currency: + type: + - string + - "null" + payment_method: + type: + - string + - "null" + accounts_receivable_customer_account: + type: + - object + - "null" + properties: + prefix: + type: + - string + - "null" + ref_sort: + type: + - number + - "null" + value: + type: + - string + - "null" + billing: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + account: + type: + - string + - "null" + country: + type: + - string + - "null" + participation_code: + type: + - string + - "null" + zip: + type: + - string + - "null" + bypass_address_validation: + type: + - boolean + - "null" + carbon_neutral: + type: + - boolean + - "null" + carrier_hub_id: + type: + - string + - "null" + carrier_hub_travel_time: + type: + - number + - "null" + cod_number: + type: + - object + - "null" + properties: + prefix: + type: + - string + - "null" + ref_sort: + type: + - number + - "null" + value: + type: + - string + - "null" + delivery_instructions: + type: + - string + - "null" + dept_number: + type: + - object + - "null" + properties: + prefix: + type: + - string + - "null" + ref_sort: + type: + - number + - "null" + value: + type: + - string + - "null" + dry_ice: + type: + - object + - "null" + properties: + contains_dry_ice: + type: + - boolean + - "null" + weight: + type: + - string + - "null" + fda_product_code: + type: + - object + - "null" + properties: + prefix: + type: + - string + - "null" + ref_sort: + type: + - number + - "null" + value: + type: + - string + - "null" + fulfillment_center: + type: + - string + - "null" + insurance: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + content: + type: + - string + - "null" + currency: + type: + - string + - "null" + provider: + type: + - string + - "null" + invoice_number: + type: + - object + - "null" + properties: + prefix: + type: + - string + - "null" + ref_sort: + type: + - number + - "null" + value: + type: + - string + - "null" + is_return: + type: + - boolean + - "null" + lasership_attrs: + type: + - array + - "null" + items: + type: + - string + - "null" + lasership_declared_value: + type: + - string + - "null" + manifest_number: + type: + - object + - "null" + properties: + prefix: + type: + - string + - "null" + ref_sort: + type: + - number + - "null" + value: + type: + - string + - "null" + model_number: + type: + - object + - "null" + properties: + prefix: + type: + - string + - "null" + ref_sort: + type: + - number + - "null" + value: + type: + - string + - "null" + part_number: + type: + - object + - "null" + properties: + prefix: + type: + - string + - "null" + ref_sort: + type: + - number + - "null" + value: + type: + - string + - "null" + po_number: + type: + - object + - "null" + properties: + prefix: + type: + - string + - "null" + ref_sort: + type: + - number + - "null" + value: + type: + - string + - "null" + preferred_delivery_timeframe: + type: + - string + - "null" + premium: + type: + - boolean + - "null" + production_code: + type: + - object + - "null" + properties: + prefix: + type: + - string + - "null" + ref_sort: + type: + - number + - "null" + value: + type: + - string + - "null" + purchase_request_number: + type: + - object + - "null" + properties: + prefix: + type: + - string + - "null" + ref_sort: + type: + - number + - "null" + value: + type: + - string + - "null" + qr_code_requested: + type: + - boolean + - "null" + reference_1: + type: + - string + - "null" + reference_2: + type: + - string + - "null" + request_retail_rates: + type: + - boolean + - "null" + return_service_type: + type: + - string + - "null" + rma_number: + type: + - object + - "null" + properties: + prefix: + type: + - string + - "null" + ref_sort: + type: + - number + - "null" + value: + type: + - string + - "null" + salesperson_number: + type: + - object + - "null" + properties: + prefix: + type: + - string + - "null" + ref_sort: + type: + - number + - "null" + value: + type: + - string + - "null" + saturday_delivery: + type: + - boolean + - "null" + serial_number: + type: + - object + - "null" + properties: + prefix: + type: + - string + - "null" + ref_sort: + type: + - number + - "null" + value: + type: + - string + - "null" + signature_confirmation: + type: + - string + - "null" + store_number: + type: + - object + - "null" + properties: + prefix: + type: + - string + - "null" + ref_sort: + type: + - number + - "null" + value: + type: + - string + - "null" + transaction_reference_number: + type: + - object + - "null" + properties: + prefix: + type: + - string + - "null" + ref_sort: + type: + - number + - "null" + value: + type: + - string + - "null" + messages: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + code: + type: + - string + - "null" + source: + type: + - string + - "null" + text: + type: + - string + - "null" + object_created: + type: + - string + - "null" + object_id: + type: string + object_owner: + type: + - string + - "null" + object_updated: + type: string + parcels: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + metadata: + type: + - string + - "null" + distance_unit: + type: + - string + - "null" + extra: + type: + - object + - "null" + properties: + COD: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + currency: + type: + - string + - "null" + payment_method: + type: + - string + - "null" + height: + type: + - string + - "null" + length: + type: + - string + - "null" + line_items: + type: + - array + - "null" + mass_unit: + type: + - string + - "null" + object_created: + type: + - string + - "null" + object_id: + type: + - string + - "null" + object_owner: + type: + - string + - "null" + object_state: + type: + - string + - "null" + object_updated: + type: + - string + - "null" + test: + type: + - boolean + - "null" + weight: + type: + - string + - "null" + width: + type: + - string + - "null" + rates: + type: + - array + - "null" + shipment_date: + type: + - string + - "null" + status: + type: + - string + - "null" + test: + type: + - boolean + - "null" + required: + - object_id + - object_updated diff --git a/airbyte-integrations/connectors/source-shippo/metadata.yaml b/airbyte-integrations/connectors/source-shippo/metadata.yaml new file mode 100644 index 000000000000..badaa4db4fa2 --- /dev/null +++ b/airbyte-integrations/connectors/source-shippo/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.goshippo.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-shippo + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: e809021f-7258-42c0-8aa6-4bc563b27837 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-shippo + githubIssueLabel: source-shippo + icon: icon.svg + license: MIT + name: Shippo + releaseDate: 2024-10-28 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/shippo + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-shipstation/README.md b/airbyte-integrations/connectors/source-shipstation/README.md new file mode 100644 index 000000000000..66d8a5d24b84 --- /dev/null +++ b/airbyte-integrations/connectors/source-shipstation/README.md @@ -0,0 +1,54 @@ +# Shipstation +This directory contains the manifest-only connector for `source-shipstation`. + +This page contains the setup guide and reference information for Shipstation source connector. + +Documentation reference: +Visit https://www.shipstation.com/docs/api/ for API documentation + +Authentication setup + +To get your API key and secret in ShipStation: + +↳ Go to Account Settings. + +↳ Select Account from the side navigation, then choose API Settings. + +↳ Click "Generate New API Keys" if no key and secret are listed yet. + +** IMPORTANT ** +↳If you've already generated your API keys, the existing API keys will be displayed here and the button will read Regenerate API Keys. + +If you already have API keys, do NOT generate new ones. Instead, copy your existing key and secret. + +Copy your key and secret and paste them into the respective fields. + + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-shipstation:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-shipstation build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-shipstation test +``` + diff --git a/airbyte-integrations/connectors/source-shipstation/acceptance-test-config.yml b/airbyte-integrations/connectors/source-shipstation/acceptance-test-config.yml new file mode 100644 index 000000000000..dcd1939221ce --- /dev/null +++ b/airbyte-integrations/connectors/source-shipstation/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-shipstation:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-shipstation/icon.svg b/airbyte-integrations/connectors/source-shipstation/icon.svg new file mode 100644 index 000000000000..f30acc07307c --- /dev/null +++ b/airbyte-integrations/connectors/source-shipstation/icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/airbyte-integrations/connectors/source-shipstation/manifest.yaml b/airbyte-integrations/connectors/source-shipstation/manifest.yaml new file mode 100644 index 000000000000..192d91fc9599 --- /dev/null +++ b/airbyte-integrations/connectors/source-shipstation/manifest.yaml @@ -0,0 +1,1621 @@ +version: 6.5.2 + +type: DeclarativeSource + +description: > + This page contains the setup guide and reference information for Shipstation + source connector. + + + Documentation reference: + + Visit https://www.shipstation.com/docs/api/ for API documentation + + + Authentication setup + + + To get your API key and secret in ShipStation: + + + ↳ Go to Account Settings. + + + ↳ Select Account from the side navigation, then choose API Settings. + + + ↳ Click "Generate New API Keys" if no key and secret are listed yet. + + + ** IMPORTANT ** + + ↳If you've already generated your API keys, the existing API keys will be + displayed here and the button will read Regenerate API Keys. + + + If you already have API keys, do NOT generate new ones. Instead, copy your + existing key and secret. + + + Copy your key and secret and paste them into the respective fields. + +check: + type: CheckStream + stream_names: + - carriers + +definitions: + streams: + carriers: + type: DeclarativeStream + name: carriers + primary_key: + - shippingProviderId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: carriers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/carriers" + customers: + type: DeclarativeStream + name: customers + primary_key: + - customerId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: customers + http_method: GET + request_parameters: + sortBy: CreateDate + sortDir: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - customers + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: pageSize + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 500 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers" + fulfillments: + type: DeclarativeStream + name: fulfillments + primary_key: + - fulfillmentId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: fulfillments + http_method: GET + request_parameters: + sortBy: CreateDate + sortDir: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - fulfillments + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: pageSize + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 500 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/fulfillments" + orders: + type: DeclarativeStream + name: orders + primary_key: + - orderId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: orders + http_method: GET + request_parameters: + sortBy: CreateDate + sortDir: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - orders + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: pageSize + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 500 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/orders" + products: + type: DeclarativeStream + name: products + primary_key: + - productId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: products + http_method: GET + request_parameters: + sortBy: CreateDate + sortDir: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - products + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: pageSize + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 500 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + shipments: + type: DeclarativeStream + name: shipments + primary_key: + - shipmentId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: shipments + http_method: GET + request_parameters: + sortBy: CreateDate + sortDir: ASC + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - shipments + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: pageSize + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 500 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/shipments" + marketplaces: + type: DeclarativeStream + name: marketplaces + primary_key: + - name + - marketplaceId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: stores/marketplaces + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/marketplaces" + stores: + type: DeclarativeStream + name: stores + primary_key: + - storeId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: stores + http_method: GET + request_parameters: + showInactive: "true" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/stores" + users: + type: DeclarativeStream + name: users + primary_key: + - userId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: users + http_method: GET + request_parameters: + showInactive: "true" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + warehouses: + type: DeclarativeStream + name: warehouses + primary_key: + - warehouseId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: warehouses + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/warehouses" + webhooks: + type: DeclarativeStream + name: webhooks + primary_key: + - WebHookID + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: webhooks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - webhooks + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/webhooks" + base_requester: + type: HttpRequester + url_base: https://ssapi.shipstation.com/ + authenticator: + type: BasicHttpAuthenticator + password: "{{ config[\"password\"] }}" + username: "{{ config[\"username\"] }}" + +streams: + - $ref: "#/definitions/streams/carriers" + - $ref: "#/definitions/streams/customers" + - $ref: "#/definitions/streams/fulfillments" + - $ref: "#/definitions/streams/orders" + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/shipments" + - $ref: "#/definitions/streams/marketplaces" + - $ref: "#/definitions/streams/stores" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/warehouses" + - $ref: "#/definitions/streams/webhooks" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - username + properties: + username: + type: string + order: 0 + title: API Key + password: + type: string + order: 1 + title: API Secret + always_show: true + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + carriers: true + customers: true + fulfillments: true + orders: true + products: true + shipments: true + marketplaces: true + stores: true + users: true + warehouses: true + webhooks: true + testedStreams: + carriers: + hasRecords: true + streamHash: e365e82d0239da73f190b402ee7cfe13f8fe58ef + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + customers: + hasRecords: true + streamHash: e8cbba0585b48a12cabb6313cdfd050fef6c4c51 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + fulfillments: + hasRecords: true + streamHash: b68f160d28ffc12b752300c1feccdd7a2e8b66f4 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + orders: + hasRecords: true + streamHash: 3adbe3ee45da8c8700cea208472e17db81bbee00 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + products: + hasRecords: true + streamHash: d6f4c42c64de31036fd0b00e7071d5692957681a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + shipments: + hasRecords: true + streamHash: 627deb767611e61857e3123c4493fdfc0da3c950 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + marketplaces: + hasRecords: true + streamHash: 060465f8f4ec23444675c486fd49a4a1b65280ac + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + stores: + hasRecords: true + streamHash: 2d9578ddd41be28bb1ecddb8f01cdcbb22883224 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + users: + hasRecords: true + streamHash: 540b75b8772f77bee87fc03c27df87537e4b3f47 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + warehouses: + hasRecords: true + streamHash: 547e90797b9e2c7a9be2ea9192fa332d025e2193 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + webhooks: + hasRecords: true + streamHash: 815e1dc0e79c1e285234c61a28c06942700c8c42 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: {} + +schemas: + carriers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accountNumber: + type: + - string + - "null" + balance: + type: + - number + - "null" + code: + type: + - string + - "null" + name: + type: + - string + - "null" + nickname: + type: + - string + - "null" + primary: + type: + - boolean + - "null" + requiresFundedAccount: + type: + - boolean + - "null" + shippingProviderId: + type: number + required: + - shippingProviderId + customers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + addressVerified: + type: + - string + - "null" + city: + type: + - string + - "null" + company: + type: + - string + - "null" + countryCode: + type: + - string + - "null" + createDate: + type: + - string + - "null" + customerId: + type: number + email: + type: + - string + - "null" + marketplaceUsernames: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + createDate: + type: + - string + - "null" + customerId: + type: + - number + - "null" + customerUserId: + type: + - number + - "null" + marketplace: + type: + - string + - "null" + marketplaceId: + type: + - number + - "null" + modifyDate: + type: + - string + - "null" + username: + type: + - string + - "null" + modifyDate: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + state: + type: + - string + - "null" + street1: + type: + - string + - "null" + street2: + type: + - string + - "null" + required: + - customerId + fulfillments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + carrierCode: + type: + - string + - "null" + createDate: + type: + - string + - "null" + customerEmail: + type: + - string + - "null" + fulfillmentFee: + type: + - number + - "null" + fulfillmentId: + type: number + marketplaceNotified: + type: + - boolean + - "null" + orderId: + type: + - number + - "null" + orderNumber: + type: + - string + - "null" + shipDate: + type: + - string + - "null" + shipTo: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + company: + type: + - string + - "null" + country: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + state: + type: + - string + - "null" + street1: + type: + - string + - "null" + street2: + type: + - string + - "null" + trackingNumber: + type: + - string + - "null" + userId: + type: + - string + - "null" + voidRequested: + type: + - boolean + - "null" + voided: + type: + - boolean + - "null" + required: + - fulfillmentId + orders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + advancedOptions: + type: + - object + - "null" + properties: + billToCountryCode: + type: + - string + - "null" + billToMyOtherAccount: + type: + - number + - "null" + billToParty: + type: + - string + - "null" + containsAlcohol: + type: + - boolean + - "null" + mergedIds: + type: + - array + - "null" + mergedOrSplit: + type: + - boolean + - "null" + nonMachinable: + type: + - boolean + - "null" + saturdayDelivery: + type: + - boolean + - "null" + storeId: + type: + - number + - "null" + warehouseId: + type: + - number + - "null" + amountPaid: + type: + - number + - "null" + billTo: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + country: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + street1: + type: + - string + - "null" + carrierCode: + type: + - string + - "null" + confirmation: + type: + - string + - "null" + createDate: + type: + - string + - "null" + customerEmail: + type: + - string + - "null" + customerId: + type: + - number + - "null" + customerUsername: + type: + - string + - "null" + dimensions: + type: + - object + - "null" + properties: + height: + type: + - number + - "null" + length: + type: + - number + - "null" + units: + type: + - string + - "null" + width: + type: + - number + - "null" + externallyFulfilled: + type: + - boolean + - "null" + externallyFulfilledBy: + type: + - string + - "null" + gift: + type: + - boolean + - "null" + insuranceOptions: + type: + - object + - "null" + properties: + insureShipment: + type: + - boolean + - "null" + insuredValue: + type: + - number + - "null" + provider: + type: + - string + - "null" + internationalOptions: + type: + - object + - "null" + properties: + contents: + type: + - string + - "null" + customsItems: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + countryOfOrigin: + type: + - string + - "null" + customsItemId: + type: + - number + - "null" + harmonizedTariffCode: + type: + - string + - "null" + quantity: + type: + - number + - "null" + value: + type: + - number + - "null" + nonDelivery: + type: + - string + - "null" + items: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + adjustment: + type: + - boolean + - "null" + createDate: + type: + - string + - "null" + modifyDate: + type: + - string + - "null" + name: + type: + - string + - "null" + options: + type: + - array + - "null" + orderItemId: + type: + - number + - "null" + productId: + type: + - number + - "null" + quantity: + type: + - number + - "null" + sku: + type: + - string + - "null" + unitPrice: + type: + - number + - "null" + modifyDate: + type: + - string + - "null" + orderDate: + type: + - string + - "null" + orderId: + type: number + orderKey: + type: + - string + - "null" + orderNumber: + type: + - string + - "null" + orderStatus: + type: + - string + - "null" + orderTotal: + type: + - number + - "null" + packageCode: + type: + - string + - "null" + paymentDate: + type: + - string + - "null" + serviceCode: + type: + - string + - "null" + shipByDate: + type: + - string + - "null" + shipDate: + type: + - string + - "null" + shipTo: + type: + - object + - "null" + properties: + addressVerified: + type: + - string + - "null" + city: + type: + - string + - "null" + company: + type: + - string + - "null" + country: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + residential: + type: + - boolean + - "null" + state: + type: + - string + - "null" + street1: + type: + - string + - "null" + street2: + type: + - string + - "null" + street3: + type: + - string + - "null" + shippingAmount: + type: + - number + - "null" + taxAmount: + type: + - number + - "null" + weight: + type: + - object + - "null" + properties: + WeightUnits: + type: + - number + - "null" + units: + type: + - string + - "null" + value: + type: + - number + - "null" + required: + - orderId + products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active: + type: + - boolean + - "null" + createDate: + type: + - string + - "null" + name: + type: + - string + - "null" + price: + type: + - number + - "null" + productId: + type: number + sku: + type: + - string + - "null" + required: + - productId + shipments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + advancedOptions: + type: + - object + - "null" + properties: + storeId: + type: + - number + - "null" + batchNumber: + type: + - string + - "null" + carrierCode: + type: + - string + - "null" + confirmation: + type: + - string + - "null" + createDate: + type: + - string + - "null" + customerEmail: + type: + - string + - "null" + dimensions: + type: + - object + - "null" + properties: + height: + type: + - number + - "null" + length: + type: + - number + - "null" + units: + type: + - string + - "null" + width: + type: + - number + - "null" + insuranceCost: + type: + - number + - "null" + insuranceOptions: + type: + - object + - "null" + properties: + insureShipment: + type: + - boolean + - "null" + insuredValue: + type: + - number + - "null" + isReturnLabel: + type: + - boolean + - "null" + marketplaceNotified: + type: + - boolean + - "null" + orderId: + type: + - number + - "null" + orderKey: + type: + - string + - "null" + orderNumber: + type: + - string + - "null" + packageCode: + type: + - string + - "null" + serviceCode: + type: + - string + - "null" + shipDate: + type: + - string + - "null" + shipTo: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + company: + type: + - string + - "null" + country: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + state: + type: + - string + - "null" + street1: + type: + - string + - "null" + street2: + type: + - string + - "null" + shipmentCost: + type: + - number + - "null" + shipmentId: + type: number + trackingNumber: + type: + - string + - "null" + userId: + type: + - string + - "null" + voidDate: + type: + - string + - "null" + voided: + type: + - boolean + - "null" + warehouseId: + type: + - number + - "null" + weight: + type: + - object + - "null" + properties: + WeightUnits: + type: + - number + - "null" + units: + type: + - string + - "null" + value: + type: + - number + - "null" + required: + - shipmentId + marketplaces: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + canConfirmShipments: + type: + - boolean + - "null" + canRefresh: + type: + - boolean + - "null" + marketplaceId: + type: number + name: + type: string + supportsCustomMappings: + type: + - boolean + - "null" + supportsCustomStatuses: + type: + - boolean + - "null" + required: + - name + - marketplaceId + stores: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accountName: + type: + - string + - "null" + active: + type: + - boolean + - "null" + autoRefresh: + type: + - boolean + - "null" + companyName: + type: + - string + - "null" + createDate: + type: + - string + - "null" + integrationUrl: + type: + - string + - "null" + lastRefreshAttempt: + type: + - string + - "null" + marketplaceId: + type: + - number + - "null" + marketplaceName: + type: + - string + - "null" + modifyDate: + type: + - string + - "null" + phone: + type: + - string + - "null" + publicEmail: + type: + - string + - "null" + refreshDate: + type: + - string + - "null" + statusMappings: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + orderStatus: + type: + - string + - "null" + statusKey: + type: + - string + - "null" + storeId: + type: number + storeName: + type: + - string + - "null" + website: + type: + - string + - "null" + required: + - storeId + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + name: + type: + - string + - "null" + userId: + type: string + userName: + type: + - string + - "null" + required: + - userId + warehouses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createDate: + type: + - string + - "null" + isDefault: + type: + - boolean + - "null" + originAddress: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + company: + type: + - string + - "null" + country: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + residential: + type: + - boolean + - "null" + state: + type: + - string + - "null" + street1: + type: + - string + - "null" + street2: + type: + - string + - "null" + street3: + type: + - string + - "null" + returnAddress: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + company: + type: + - string + - "null" + country: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + state: + type: + - string + - "null" + street1: + type: + - string + - "null" + street2: + type: + - string + - "null" + street3: + type: + - string + - "null" + warehouseId: + type: number + warehouseName: + type: + - string + - "null" + required: + - warehouseId + webhooks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Active: + type: + - boolean + - "null" + HookType: + type: + - string + - "null" + IsLabelAPIHook: + type: + - boolean + - "null" + MessageFormat: + type: + - string + - "null" + Name: + type: + - string + - "null" + SellerID: + type: + - number + - "null" + Url: + type: + - string + - "null" + WebHookID: + type: number + WebhookLogs: + type: + - array + - "null" + required: + - WebHookID diff --git a/airbyte-integrations/connectors/source-shipstation/metadata.yaml b/airbyte-integrations/connectors/source-shipstation/metadata.yaml new file mode 100644 index 000000000000..b9a13b293fad --- /dev/null +++ b/airbyte-integrations/connectors/source-shipstation/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "ssapi.shipstation.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-shipstation + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: c5a0d24d-5587-4425-ab28-b8b3fe741c78 + dockerImageTag: 0.0.2 + dockerRepository: airbyte/source-shipstation + githubIssueLabel: source-shipstation + icon: icon.svg + license: MIT + name: Shipstation + releaseDate: 2024-12-21 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/shipstation + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-shopify/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-shopify/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-shopify/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-shopify/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-shopify/main.py b/airbyte-integrations/connectors/source-shopify/main.py index aca13eebbb25..2bfe3cb0cfe9 100644 --- a/airbyte-integrations/connectors/source-shopify/main.py +++ b/airbyte-integrations/connectors/source-shopify/main.py @@ -5,5 +5,6 @@ from source_shopify.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-shopify/metadata.yaml b/airbyte-integrations/connectors/source-shopify/metadata.yaml index 77118ad4ebc2..a2f4dbe498b5 100644 --- a/airbyte-integrations/connectors/source-shopify/metadata.yaml +++ b/airbyte-integrations/connectors/source-shopify/metadata.yaml @@ -7,11 +7,11 @@ data: - ${shop}.myshopify.com - shopify.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 9da77001-af33-4bcd-be46-6252bf9342b9 - dockerImageTag: 2.5.9 + dockerImageTag: 2.5.17 dockerRepository: airbyte/source-shopify documentationUrl: https://docs.airbyte.com/integrations/sources/shopify erdUrl: https://dbdocs.io/airbyteio/source-shopify?view=relationships diff --git a/airbyte-integrations/connectors/source-shopify/poetry.lock b/airbyte-integrations/connectors/source-shopify/poetry.lock index 1726a966fd79..9c4c5854384d 100644 --- a/airbyte-integrations/connectors/source-shopify/poetry.lock +++ b/airbyte-integrations/connectors/source-shopify/poetry.lock @@ -1,60 +1,64 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "airbyte-cdk" -version = "5.17.0" +version = "6.12.4" description = "A framework for writing Airbyte Connectors." optional = false -python-versions = "<4.0,>=3.10" +python-versions = "<3.13,>=3.10" files = [ - {file = "airbyte_cdk-5.17.0-py3-none-any.whl", hash = "sha256:135a8fc43b00a92169dfcdc43c1d7c629aba871a0b471f950ca5d76d3741fc92"}, - {file = "airbyte_cdk-5.17.0.tar.gz", hash = "sha256:5db70cbacec80ba3beabe4253480ab9a3947a450e8d0e39af4a91638b317b32a"}, + {file = "airbyte_cdk-6.12.4-py3-none-any.whl", hash = "sha256:903f2c2d3be4d6595bc6c50a4625e2551308d2ca90e021bf489e0a82cf0f965d"}, + {file = "airbyte_cdk-6.12.4.tar.gz", hash = "sha256:f9f39746dec5e01a9d37255cfb45a753953227b7aafebf8f5603a6e9f943b182"}, ] [package.dependencies] -airbyte-protocol-models-dataclasses = ">=0.13,<0.14" +airbyte-protocol-models-dataclasses = ">=0.14,<0.15" backoff = "*" cachetools = "*" -cryptography = ">=42.0.5,<43.0.0" -Deprecated = ">=1.2,<1.3" +cryptography = ">=42.0.5,<44.0.0" dpath = ">=2.1.6,<3.0.0" -genson = "1.2.2" +dunamai = ">=1.22.0,<2.0.0" +genson = "1.3.0" isodate = ">=0.6.1,<0.7.0" Jinja2 = ">=3.1.2,<3.2.0" jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" +jsonschema = ">=4.17.3,<4.18.0" langchain_core = "0.1.42" -nltk = "3.8.1" +nltk = "3.9.1" +numpy = "<2" orjson = ">=3.10.7,<4.0.0" pandas = "2.2.2" pendulum = "<3.0.0" +psutil = "6.1.0" pydantic = ">=2.7,<3.0" pyjwt = ">=2.8.0,<3.0.0" pyrate-limiter = ">=3.1.0,<3.2.0" python-dateutil = "*" -pytz = "2024.1" +python-ulid = ">=3.0.0,<4.0.0" +pytz = "2024.2" PyYAML = ">=6.0.1,<7.0.0" +rapidfuzz = ">=3.10.1,<4.0.0" requests = "*" requests_cache = "*" serpyco-rs = ">=1.10.2,<2.0.0" -wcmatch = "8.4" +Unidecode = ">=1.3,<2.0" +wcmatch = "10.0" xmltodict = ">=0.13.0,<0.14.0" [package.extras] file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "python-snappy (==0.7.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] sql = ["sqlalchemy (>=2.0,!=2.0.36,<3.0)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] +vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.8.0)"] [[package]] name = "airbyte-protocol-models-dataclasses" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models_dataclasses-0.13.0-py3-none-any.whl", hash = "sha256:0aedb99ffc4f9aab0ce91bba2c292fa17cd8fd4b42eeba196d6a16c20bbbd7a5"}, - {file = "airbyte_protocol_models_dataclasses-0.13.0.tar.gz", hash = "sha256:72e67850d661e2808406aec5839b3158ebb94d3553b798dbdae1b4a278548d2f"}, + {file = "airbyte_protocol_models_dataclasses-0.14.1-py3-none-any.whl", hash = "sha256:dfe10b32ee09e6ba9b4f17bd309e841b61cbd61ec8f80b1937ff104efd6209a9"}, + {file = "airbyte_protocol_models_dataclasses-0.14.1.tar.gz", hash = "sha256:f62a46556b82ea0d55de144983141639e8049d836dd4e0a9d7234c5b2e103c08"}, ] [[package]] @@ -70,24 +74,24 @@ files = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -103,19 +107,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -181,13 +185,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -271,127 +275,114 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -410,43 +401,38 @@ files = [ [[package]] name = "cryptography" -version = "42.0.8" +version = "43.0.3" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, + {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, + {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, + {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, + {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, + {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, + {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, + {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, ] [package.dependencies] @@ -459,26 +445,9 @@ nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] -[[package]] -name = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - [[package]] name = "dpath" version = "2.2.0" @@ -490,6 +459,20 @@ files = [ {file = "dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e"}, ] +[[package]] +name = "dunamai" +version = "1.23.0" +description = "Dynamic version generation" +optional = false +python-versions = ">=3.5" +files = [ + {file = "dunamai-1.23.0-py3-none-any.whl", hash = "sha256:a0906d876e92441793c6a423e16a4802752e723e9c9a5aabdc5535df02dbe041"}, + {file = "dunamai-1.23.0.tar.gz", hash = "sha256:a163746de7ea5acb6dacdab3a6ad621ebc612ed1e528aaa8beedb8887fccd2c4"}, +] + +[package.dependencies] +packaging = ">=20.9" + [[package]] name = "exceptiongroup" version = "1.2.2" @@ -520,12 +503,13 @@ python-dateutil = ">=2.7" [[package]] name = "genson" -version = "1.2.2" +version = "1.3.0" description = "GenSON is a powerful, user-friendly JSON Schema generator." optional = false python-versions = "*" files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, + {file = "genson-1.3.0-py3-none-any.whl", hash = "sha256:468feccd00274cc7e4c09e84b08704270ba8d95232aa280f65b986139cec67f7"}, + {file = "genson-1.3.0.tar.gz", hash = "sha256:e02db9ac2e3fd29e65b5286f7135762e2cd8a986537c075b06fc5f1517308e37"}, ] [[package]] @@ -572,13 +556,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -593,13 +577,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -607,7 +591,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -657,13 +640,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -721,24 +704,22 @@ files = [ [[package]] name = "jsonschema" -version = "3.2.0" +version = "4.17.3" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, ] [package.dependencies] attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" [package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] [[package]] name = "langchain-core" @@ -764,22 +745,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -852,13 +836,13 @@ files = [ [[package]] name = "nltk" -version = "3.8.1" +version = "3.9.1" description = "Natural Language Toolkit" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "nltk-3.8.1-py3-none-any.whl", hash = "sha256:fd5c9109f976fa86bcadba8f91e47f5e9293bd034474752e92a520f81c93dda5"}, - {file = "nltk-3.8.1.zip", hash = "sha256:1834da3d0682cba4f2cede2f9aad6b0fafb6461ba451db0efb6f9c39798d64d3"}, + {file = "nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1"}, + {file = "nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868"}, ] [package.dependencies] @@ -877,131 +861,131 @@ twitter = ["twython"] [[package]] name = "numpy" -version = "2.1.2" +version = "1.26.4" description = "Fundamental package for array computing in Python" optional = false -python-versions = ">=3.10" -files = [ - {file = "numpy-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466"}, - {file = "numpy-2.1.2-cp310-cp310-win32.whl", hash = "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb"}, - {file = "numpy-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146"}, - {file = "numpy-2.1.2-cp311-cp311-win32.whl", hash = "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c"}, - {file = "numpy-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142"}, - {file = "numpy-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550"}, - {file = "numpy-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe"}, - {file = "numpy-2.1.2-cp313-cp313-win32.whl", hash = "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a"}, - {file = "numpy-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e"}, - {file = "numpy-2.1.2.tar.gz", hash = "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c"}, +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, ] [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -1152,6 +1136,36 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "psutil" +version = "6.1.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, +] + +[package.extras] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + [[package]] name = "pycparser" version = "2.22" @@ -1165,19 +1179,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.4" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, + {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} +pydantic-core = "2.27.2" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -1185,100 +1199,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, + {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a"}, + {file = "pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9"}, + {file = "pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4"}, + {file = "pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048"}, + {file = "pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474"}, + {file = "pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc"}, + {file = "pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b"}, + {file = "pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e"}, + {file = "pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee"}, + {file = "pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506"}, + {file = "pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5"}, + {file = "pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9"}, + {file = "pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b"}, + {file = "pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993"}, + {file = "pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630"}, + {file = "pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362"}, + {file = "pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e"}, + {file = "pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9"}, + {file = "pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2"}, + {file = "pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [package.dependencies] @@ -1286,13 +1311,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1359,13 +1384,13 @@ files = [ [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] @@ -1410,15 +1435,29 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "python-ulid" +version = "3.0.0" +description = "Universally unique lexicographically sortable identifier" +optional = false +python-versions = ">=3.9" +files = [ + {file = "python_ulid-3.0.0-py3-none-any.whl", hash = "sha256:e4c4942ff50dbd79167ad01ac725ec58f924b4018025ce22c858bfcff99a5e31"}, + {file = "python_ulid-3.0.0.tar.gz", hash = "sha256:e50296a47dc8209d28629a22fc81ca26c00982c78934bd7766377ba37ea49a9f"}, +] + +[package.extras] +pydantic = ["pydantic (>=2.0)"] + [[package]] name = "pytz" -version = "2024.1" +version = "2024.2" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, + {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, + {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, ] [[package]] @@ -1494,107 +1533,207 @@ files = [ {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] +[[package]] +name = "rapidfuzz" +version = "3.11.0" +description = "rapid fuzzy string matching" +optional = false +python-versions = ">=3.9" +files = [ + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eb8a54543d16ab1b69e2c5ed96cabbff16db044a50eddfc028000138ca9ddf33"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:231c8b2efbd7f8d2ecd1ae900363ba168b8870644bb8f2b5aa96e4a7573bde19"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54e7f442fb9cca81e9df32333fb075ef729052bcabe05b0afc0441f462299114"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:906f1f2a1b91c06599b3dd1be207449c5d4fc7bd1e1fa2f6aef161ea6223f165"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed59044aea9eb6c663112170f2399b040d5d7b162828b141f2673e822093fa8"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cb1965a28b0fa64abdee130c788a0bc0bb3cf9ef7e3a70bf055c086c14a3d7e"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b488b244931d0291412917e6e46ee9f6a14376625e150056fe7c4426ef28225"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f0ba13557fec9d5ffc0a22826754a7457cc77f1b25145be10b7bb1d143ce84c6"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3871fa7dfcef00bad3c7e8ae8d8fd58089bad6fb21f608d2bf42832267ca9663"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b2669eafee38c5884a6e7cc9769d25c19428549dcdf57de8541cf9e82822e7db"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ffa1bb0e26297b0f22881b219ffc82a33a3c84ce6174a9d69406239b14575bd5"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:45b15b8a118856ac9caac6877f70f38b8a0d310475d50bc814698659eabc1cdb"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win32.whl", hash = "sha256:22033677982b9c4c49676f215b794b0404073f8974f98739cb7234e4a9ade9ad"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:be15496e7244361ff0efcd86e52559bacda9cd975eccf19426a0025f9547c792"}, + {file = "rapidfuzz-3.11.0-cp310-cp310-win_arm64.whl", hash = "sha256:714a7ba31ba46b64d30fccfe95f8013ea41a2e6237ba11a805a27cdd3bce2573"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8724a978f8af7059c5323d523870bf272a097478e1471295511cf58b2642ff83"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b63cb1f2eb371ef20fb155e95efd96e060147bdd4ab9fc400c97325dfee9fe1"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82497f244aac10b20710448645f347d862364cc4f7d8b9ba14bd66b5ce4dec18"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:339607394941801e6e3f6c1ecd413a36e18454e7136ed1161388de674f47f9d9"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84819390a36d6166cec706b9d8f0941f115f700b7faecab5a7e22fc367408bc3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eea8d9e20632d68f653455265b18c35f90965e26f30d4d92f831899d6682149b"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b659e1e2ea2784a9a397075a7fc395bfa4fe66424042161c4bcaf6e4f637b38"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1315cd2a351144572e31fe3df68340d4b83ddec0af8b2e207cd32930c6acd037"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a7743cca45b4684c54407e8638f6d07b910d8d811347b9d42ff21262c7c23245"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:5bb636b0150daa6d3331b738f7c0f8b25eadc47f04a40e5c23c4bfb4c4e20ae3"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:42f4dd264ada7a9aa0805ea0da776dc063533917773cf2df5217f14eb4429eae"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:51f24cb39e64256221e6952f22545b8ce21cacd59c0d3e367225da8fc4b868d8"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win32.whl", hash = "sha256:aaf391fb6715866bc14681c76dc0308f46877f7c06f61d62cc993b79fc3c4a2a"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:ebadd5b8624d8ad503e505a99b8eb26fe3ea9f8e9c2234e805a27b269e585842"}, + {file = "rapidfuzz-3.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:d895998fec712544c13cfe833890e0226585cf0391dd3948412441d5d68a2b8c"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f382fec4a7891d66fb7163c90754454030bb9200a13f82ee7860b6359f3f2fa8"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dfaefe08af2a928e72344c800dcbaf6508e86a4ed481e28355e8d4b6a6a5230e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92ebb7c12f682b5906ed98429f48a3dd80dd0f9721de30c97a01473d1a346576"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a1b3ebc62d4bcdfdeba110944a25ab40916d5383c5e57e7c4a8dc0b6c17211a"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c6d7fea39cb33e71de86397d38bf7ff1a6273e40367f31d05761662ffda49e4"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99aebef8268f2bc0b445b5640fd3312e080bd17efd3fbae4486b20ac00466308"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4469307f464ae3089acf3210b8fc279110d26d10f79e576f385a98f4429f7d97"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:eb97c53112b593f89a90b4f6218635a9d1eea1d7f9521a3b7d24864228bbc0aa"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef8937dae823b889c0273dfa0f0f6c46a3658ac0d851349c464d1b00e7ff4252"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d95f9e9f3777b96241d8a00d6377cc9c716981d828b5091082d0fe3a2924b43e"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:b1d67d67f89e4e013a5295e7523bc34a7a96f2dba5dd812c7c8cb65d113cbf28"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d994cf27e2f874069884d9bddf0864f9b90ad201fcc9cb2f5b82bacc17c8d5f2"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win32.whl", hash = "sha256:ba26d87fe7fcb56c4a53b549a9e0e9143f6b0df56d35fe6ad800c902447acd5b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:b1f7efdd7b7adb32102c2fa481ad6f11923e2deb191f651274be559d56fc913b"}, + {file = "rapidfuzz-3.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:ed78c8e94f57b44292c1a0350f580e18d3a3c5c0800e253f1583580c1b417ad2"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e60814edd0c9b511b5f377d48b9782b88cfe8be07a98f99973669299c8bb318a"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f28952da055dbfe75828891cd3c9abf0984edc8640573c18b48c14c68ca5e06"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e8f93bc736020351a6f8e71666e1f486bb8bd5ce8112c443a30c77bfde0eb68"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76a4a11ba8f678c9e5876a7d465ab86def047a4fcc043617578368755d63a1bc"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc0e0d41ad8a056a9886bac91ff9d9978e54a244deb61c2972cc76b66752de9c"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e8ea35f2419c7d56b3e75fbde2698766daedb374f20eea28ac9b1f668ef4f74"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd340bbd025302276b5aa221dccfe43040c7babfc32f107c36ad783f2ffd8775"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:494eef2c68305ab75139034ea25328a04a548d297712d9cf887bf27c158c388b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5a167344c1d6db06915fb0225592afdc24d8bafaaf02de07d4788ddd37f4bc2f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8c7af25bda96ac799378ac8aba54a8ece732835c7b74cfc201b688a87ed11152"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d2a0f7e17f33e7890257367a1662b05fecaf56625f7dbb6446227aaa2b86448b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4d0d26c7172bdb64f86ee0765c5b26ea1dc45c52389175888ec073b9b28f4305"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win32.whl", hash = "sha256:6ad02bab756751c90fa27f3069d7b12146613061341459abf55f8190d899649f"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:b1472986fd9c5d318399a01a0881f4a0bf4950264131bb8e2deba9df6d8c362b"}, + {file = "rapidfuzz-3.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:c408f09649cbff8da76f8d3ad878b64ba7f7abdad1471efb293d2c075e80c822"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1bac4873f6186f5233b0084b266bfb459e997f4c21fc9f029918f44a9eccd304"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f9f12c2d0aa52b86206d2059916153876a9b1cf9dfb3cf2f344913167f1c3d4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd501de6f7a8f83557d20613b58734d1cb5f0be78d794cde64fe43cfc63f5f2"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4416ca69af933d4a8ad30910149d3db6d084781d5c5fdedb713205389f535385"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f0821b9bdf18c5b7d51722b906b233a39b17f602501a966cfbd9b285f8ab83cd"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0edecc3f90c2653298d380f6ea73b536944b767520c2179ec5d40b9145e47aa"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4513dd01cee11e354c31b75f652d4d466c9440b6859f84e600bdebfccb17735a"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d9727b85511b912571a76ce53c7640ba2c44c364e71cef6d7359b5412739c570"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ab9eab33ee3213f7751dc07a1a61b8d9a3d748ca4458fffddd9defa6f0493c16"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:6b01c1ddbb054283797967ddc5433d5c108d680e8fa2684cf368be05407b07e4"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:3857e335f97058c4b46fa39ca831290b70de554a5c5af0323d2f163b19c5f2a6"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d98a46cf07c0c875d27e8a7ed50f304d83063e49b9ab63f21c19c154b4c0d08d"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win32.whl", hash = "sha256:c36539ed2c0173b053dafb221458812e178cfa3224ade0960599bec194637048"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:ec8d7d8567e14af34a7911c98f5ac74a3d4a743cd848643341fc92b12b3784ff"}, + {file = "rapidfuzz-3.11.0-cp39-cp39-win_arm64.whl", hash = "sha256:62171b270ecc4071be1c1f99960317db261d4c8c83c169e7f8ad119211fe7397"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f06e3c4c0a8badfc4910b9fd15beb1ad8f3b8fafa8ea82c023e5e607b66a78e4"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fe7aaf5a54821d340d21412f7f6e6272a9b17a0cbafc1d68f77f2fc11009dcd5"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25398d9ac7294e99876a3027ffc52c6bebeb2d702b1895af6ae9c541ee676702"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a52eea839e4bdc72c5e60a444d26004da00bb5bc6301e99b3dde18212e41465"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c87319b0ab9d269ab84f6453601fd49b35d9e4a601bbaef43743f26fabf496c"}, + {file = "rapidfuzz-3.11.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3048c6ed29d693fba7d2a7caf165f5e0bb2b9743a0989012a98a47b975355cca"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b04f29735bad9f06bb731c214f27253bd8bedb248ef9b8a1b4c5bde65b838454"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7864e80a0d4e23eb6194254a81ee1216abdc53f9dc85b7f4d56668eced022eb8"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3794df87313dfb56fafd679b962e0613c88a293fd9bd5dd5c2793d66bf06a101"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d71da0012face6f45432a11bc59af19e62fac5a41f8ce489e80c0add8153c3d1"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff38378346b7018f42cbc1f6d1d3778e36e16d8595f79a312b31e7c25c50bd08"}, + {file = "rapidfuzz-3.11.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6668321f90aa02a5a789d4e16058f2e4f2692c5230252425c3532a8a62bc3424"}, + {file = "rapidfuzz-3.11.0.tar.gz", hash = "sha256:a53ca4d3f52f00b393fab9b5913c5bafb9afc27d030c8a1db1283da6917a860f"}, +] + +[package.extras] +all = ["numpy"] + [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -1733,26 +1872,6 @@ files = [ attributes-doc = "*" typing-extensions = "*" -[[package]] -name = "setuptools" -version = "75.3.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] - [[package]] name = "sgqlc" version = "16.3" @@ -1773,13 +1892,13 @@ websocket = ["websocket-client"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1810,31 +1929,62 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "tomli" -version = "2.0.2" +version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] [[package]] name = "tqdm" -version = "4.66.6" +version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63"}, - {file = "tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090"}, + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -1861,6 +2011,17 @@ files = [ {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, ] +[[package]] +name = "unidecode" +version = "1.3.8" +description = "ASCII transliterations of Unicode text" +optional = false +python-versions = ">=3.5" +files = [ + {file = "Unidecode-1.3.8-py3-none-any.whl", hash = "sha256:d130a61ce6696f8148a3bd8fe779c99adeb4b870584eeb9526584e9aa091fd39"}, + {file = "Unidecode-1.3.8.tar.gz", hash = "sha256:cfdb349d46ed3873ece4586b96aa75258726e2fa8ec21d6f00a591d98806c2f4"}, +] + [[package]] name = "url-normalize" version = "1.4.3" @@ -1877,13 +2038,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1894,97 +2055,18 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "wcmatch" -version = "8.4" +version = "10.0" description = "Wildcard/glob file name matcher." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, + {file = "wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a"}, + {file = "wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a"}, ] [package.dependencies] bracex = ">=2.1.1" -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - [[package]] name = "xmltodict" version = "0.13.0" @@ -1999,4 +2081,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.10,<3.12" -content-hash = "80b2d8d446f5f5c2ca2ed3f490a3df9ab4ffeeef4f21535abbd0b4598f7f6538" +content-hash = "553c270bd56678cca6961b52352173d306c3596d1336dae759af74c0579c4951" diff --git a/airbyte-integrations/connectors/source-shopify/pyproject.toml b/airbyte-integrations/connectors/source-shopify/pyproject.toml index 26496f2586c5..99f5f8838471 100644 --- a/airbyte-integrations/connectors/source-shopify/pyproject.toml +++ b/airbyte-integrations/connectors/source-shopify/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "2.5.9" +version = "2.5.17" name = "source-shopify" description = "Source CDK implementation for Shopify." authors = [ "Airbyte ",] @@ -17,7 +17,7 @@ include = "source_shopify" [tool.poetry.dependencies] python = "^3.10,<3.12" -airbyte-cdk = "^5" +airbyte-cdk = "^6" sgqlc = "==16.3" graphql-query = "^1" diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/auth.py b/airbyte-integrations/connectors/source-shopify/source_shopify/auth.py index 6d53197ff18a..3d955fd8b5ec 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/auth.py +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/auth.py @@ -25,7 +25,6 @@ def __init__(self, auth_method: str = None): class ShopifyAuthenticator(TokenAuthenticator): - """ Making Authenticator to be able to accept Header-Based authentication. """ diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/config_migrations.py b/airbyte-integrations/connectors/source-shopify/source_shopify/config_migrations.py index eba59a079355..412c0e3b05a3 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/config_migrations.py +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/config_migrations.py @@ -5,12 +5,13 @@ from typing import Any, List, Mapping +from orjson import orjson + from airbyte_cdk.config_observation import create_connector_config_control_message from airbyte_cdk.entrypoint import AirbyteEntrypoint from airbyte_cdk.models import AirbyteMessageSerializer from airbyte_cdk.sources import Source from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository -from orjson import orjson class MigrateConfig: diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/http_request.py b/airbyte-integrations/connectors/source-shopify/source_shopify/http_request.py index d4e4f6b728dc..873432ef3084 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/http_request.py +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/http_request.py @@ -3,9 +3,11 @@ from typing import Optional, Union import requests +from requests import exceptions + from airbyte_cdk.models import FailureType from airbyte_cdk.sources.streams.http.error_handlers import ErrorHandler, ErrorResolution, ResponseAction -from requests import exceptions + RESPONSE_CONSUMPTION_EXCEPTIONS = ( exceptions.ChunkedEncodingError, diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/schemas/customer_journey_summary.json b/airbyte-integrations/connectors/source-shopify/source_shopify/schemas/customer_journey_summary.json index f4eaf90ffce5..df3aad9bc251 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/schemas/customer_journey_summary.json +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/schemas/customer_journey_summary.json @@ -191,6 +191,82 @@ "type": ["null", "string"] } } + }, + "moments": { + "description": "The events preceding a customer's order, such as shop sessions.", + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "properties": { + "id": { + "description": "A globally-unique ID.", + "type": ["null", "integer"] + }, + "landing_page": { + "description": "URL of the first page the customer landed on for the session.", + "type": ["null", "string"] + }, + "landing_page_html": { + "description": "Landing page information with URL linked in HTML. For example, the first page the customer visited was", + "type": ["null", "string"] + }, + "occurred_at": { + "description": "The date and time when the customer's session occurred.", + "type": ["null", "string"], + "format": "date-time" + }, + "referral_code": { + "description": "Marketing referral code from the link that the customer clicked to visit the store.", + "type": ["null", "string"] + }, + "referrer_url": { + "description": "Webpage where the customer clicked a link that sent them to the online store.", + "type": ["null", "string"] + }, + "source": { + "description": "Source from which the customer visited the store, such as a platform (Facebook, Google), email, direct, a website domain, QR code, or unknown.", + "type": ["null", "string"] + }, + "source_type": { + "description": "Type of marketing tactic.", + "type": ["null", "string"] + }, + "source_description": { + "description": "Describes the source explicitly for first or last session.", + "type": ["null", "string"] + }, + "utm_parameters": { + "description": "A set of UTM parameters gathered from the URL parameters of the referrer.", + "type": ["null", "object"], + "properties": { + "campaign": { + "description": "The name of a marketing campaign.", + "type": ["null", "string"] + }, + "content": { + "description": "Identifies specific content in a marketing campaign. Used to differentiate between similar content or links in a marketing campaign to determine which is the most effective.", + "type": ["null", "string"] + }, + "medium": { + "description": "The medium of a marketing campaign, such as a banner or email newsletter.", + "type": ["null", "string"] + }, + "source": { + "description": "The source of traffic to the merchant's store, such as Google or an email newsletter.", + "type": ["null", "string"] + }, + "term": { + "description": "Paid search terms used by a marketing campaign.", + "type": ["null", "string"] + } + } + }, + "admin_graphql_api_id": { + "description": "Unique identifier for the customer in the Admin GraphQL API.", + "type": ["null", "string"] + } + } + } } } }, diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/schemas/product_variants.json b/airbyte-integrations/connectors/source-shopify/source_shopify/schemas/product_variants.json index dafdfabe5c9d..cca54b806556 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/schemas/product_variants.json +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/schemas/product_variants.json @@ -99,6 +99,20 @@ "id": { "description": "A globally-unique ID of an image representation of the swatch.", "type": ["null", "string"] + }, + "image": { + "description": "An image associated with the product variant.", + "type": ["null", "object"], + "properties": { + "src": { + "description": "The location of the image as URL associated with the product variant option.", + "type": ["null", "string"] + }, + "url": { + "description": "The image URL associated with the product variant option.", + "type": ["null", "string"] + } + } } } } @@ -135,6 +149,14 @@ "description": "The unique identifier for the image associated with the variant", "type": ["null", "integer"] }, + "image_src": { + "description": "The location of the image as URL.", + "type": ["null", "string"] + }, + "image_url": { + "description": "The location of the image as URL.", + "type": ["null", "string"] + }, "weight": { "description": "The weight of the variant", "type": ["null", "number"] diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/scopes.py b/airbyte-integrations/connectors/source-shopify/source_shopify/scopes.py index 1a493119b901..33c1340133c4 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/scopes.py +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/scopes.py @@ -7,12 +7,14 @@ from typing import Any, Iterable, List, Mapping, Optional import requests -from airbyte_cdk.sources.streams.http import HttpClient from requests.exceptions import InvalidURL, JSONDecodeError +from airbyte_cdk.sources.streams.http import HttpClient + from .http_request import ShopifyErrorHandler from .utils import ShopifyAccessScopesError, ShopifyBadJsonError, ShopifyWrongShopNameError + SCOPES_MAPPING: Mapping[str, set[str]] = { # SCOPE: read_customers "Customers": ("read_customers",), @@ -82,7 +84,6 @@ class ShopifyScopes: - # define default logger logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/exceptions.py b/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/exceptions.py index a24117fdcf91..ed00906a9374 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/exceptions.py +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/exceptions.py @@ -52,6 +52,11 @@ class BulkJobCreationFailedConcurrentError(BaseBulkException): failure_type: FailureType = FailureType.transient_error + class BulkJobCheckpointCollisionError(BaseBulkException): + """Raised when an attempt to create a job using the `checkpointed cursor` value goes into inf.loop.""" + + failure_type: FailureType = FailureType.transient_error + class BulkJobRedirectToOtherShopError(BaseBulkException): """Raised when the response contains another shop name""" diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/job.py b/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/job.py index 0860de22b863..0034d87ae20b 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/job.py +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/job.py @@ -9,11 +9,12 @@ import pendulum as pdm import requests -from airbyte_cdk.sources.streams.http import HttpClient from requests.exceptions import JSONDecodeError from source_shopify.utils import LOGGER, ApiTypeEnum from source_shopify.utils import ShopifyRateLimiter as limiter +from airbyte_cdk.sources.streams.http import HttpClient + from .exceptions import AirbyteTracedException, ShopifyBulkExceptions from .query import ShopifyBulkQuery, ShopifyBulkTemplates from .record import ShopifyBulkRecord @@ -53,7 +54,7 @@ class ShopifyBulkManager: # currents: _job_id, _job_state, _job_created_at, _job_self_canceled _job_id: Optional[str] = field(init=False, default=None) - _job_state: str = field(init=False, default=None) # this string is based on ShopifyBulkJobStatus + _job_state: str | None = field(init=False, default=None) # this string is based on ShopifyBulkJobStatus # completed and saved Bulk Job result filename _job_result_filename: Optional[str] = field(init=False, default=None) # date-time when the Bulk Job was created on the server @@ -70,6 +71,8 @@ class ShopifyBulkManager: _job_last_rec_count: int = field(init=False, default=0) # the flag to adjust the next slice from the checkpointed cursor vaue _job_adjust_slice_from_checkpoint: bool = field(init=False, default=False) + # keeps the last checkpointed cursor value for supported streams + _job_last_checkpoint_cursor_value: str | None = field(init=False, default=None) # expand slice factor _job_size_expand_factor: int = field(init=False, default=2) @@ -209,6 +212,27 @@ def _reset_checkpointing(self) -> None: # reseting the checkpoint flag, if bulk job has completed normally self._job_adjust_slice_from_checkpoint = False + def _set_last_checkpoint_cursor_value(self, checkpointed_cursor: str) -> None: + """ + Sets the last checkpoint cursor value. + + Args: + checkpointed_cursor (str): The cursor value to set as the last checkpoint. Defaults to None. + """ + self._job_last_checkpoint_cursor_value = checkpointed_cursor + + def _checkpoint_cursor_has_collision(self, checkpointed_cursor: str) -> bool: + """ + Checks if the provided checkpointed cursor collides with the last checkpointed cursor value. + + Args: + checkpointed_cursor (str): The cursor value to check for collision. Defaults to None. + + Returns: + bool: True if the provided cursor collides with the last checkpointed cursor value, False otherwise. + """ + return self._job_last_checkpoint_cursor_value == checkpointed_cursor + def _job_completed(self) -> bool: return self._job_state == ShopifyBulkJobStatus.COMPLETED.value @@ -329,7 +353,7 @@ def _on_running_job(self, **kwargs) -> None: def _on_completed_job(self, response: Optional[requests.Response] = None) -> None: self._job_result_filename = self._job_get_result(response) - def _on_failed_job(self, response: requests.Response) -> AirbyteTracedException: + def _on_failed_job(self, response: requests.Response) -> AirbyteTracedException | None: if not self._supports_checkpointing: raise ShopifyBulkExceptions.BulkJobFailed( f"The BULK Job: `{self._job_id}` exited with {self._job_state}, details: {response.text}", @@ -485,7 +509,7 @@ def _job_process_created(self, response: requests.Response) -> None: self._job_state = ShopifyBulkJobStatus.CREATED.value LOGGER.info(f"Stream: `{self.http_client.name}`, the BULK Job: `{self._job_id}` is {ShopifyBulkJobStatus.CREATED.value}") - def job_size_normalize(self, start: datetime, end: datetime) -> datetime: + def job_size_normalize(self, start: datetime, end: datetime) -> None: # adjust slice size when it's bigger than the loop point when it should end, # to preserve correct job size adjustments when this is the only job we need to run, based on STATE provided requested_slice_size = (end - start).total_days() @@ -498,8 +522,20 @@ def get_adjusted_job_start(self, slice_start: datetime) -> datetime: def _adjust_slice_end(self, slice_end: datetime, checkpointed_cursor: Optional[str] = None) -> datetime: """ Choose between the existing `slice_end` value or `checkpointed_cursor` value, if provided. + + Optionally: raises the `transient` error if the checkpoint collision occurs. """ - return pdm.parse(checkpointed_cursor) if checkpointed_cursor else slice_end + + if checkpointed_cursor: + if self._checkpoint_cursor_has_collision(checkpointed_cursor): + raise ShopifyBulkExceptions.BulkJobCheckpointCollisionError( + f"The stream: `{self.http_client.name}` checkpoint collision is detected. Try to increase the `BULK Job checkpoint (rows collected)` to the bigger value. The stream will be synced again during the next sync attempt." + ) + # set the checkpointed cursor value + self._set_last_checkpoint_cursor_value(checkpointed_cursor) + return pdm.parse(checkpointed_cursor) + + return slice_end def get_adjusted_job_end(self, slice_start: datetime, slice_end: datetime, checkpointed_cursor: Optional[str] = None) -> datetime: if self._job_adjust_slice_from_checkpoint: diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/query.py b/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/query.py index 55cf4fd97498..c12d8c244cce 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/query.py +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/query.py @@ -1105,6 +1105,29 @@ class CustomerJourney(ShopifyBulkQuery): term } } + customerJourney { + moments { + ... on CustomerVisit { + id + landingPage + landingPageHtml + occurredAt + referralCode + referralInfoHtml + referrerUrl + source + sourceDescription + sourceType + utmParameters { + campaign + content + medium + source + term + } + } + } + } } } } @@ -1127,6 +1150,16 @@ class CustomerJourney(ShopifyBulkQuery): "sourceDescription", Field(name="utmParameters", fields=["campaign", "content", "medium", "source", "term"]), ] + + customer_visit_fragment: List[InlineFragment] = [ + InlineFragment(type="CustomerVisit", fields=visit_fields), + ] + + # # use this in the next version + # moments_fields: List[Field] = [ + # Field(name="edges", fields=[Field(name="node", fields=customer_visit_fragment)]), + # ] + customer_journey_summary_fields: List[Field] = [ "ready", Field(name="momentsCount", fields=["count", "precision"]), @@ -1134,6 +1167,8 @@ class CustomerJourney(ShopifyBulkQuery): "daysToConversion", Field(name="firstVisit", fields=visit_fields), Field(name="lastVisit", fields=visit_fields), + # # use this in the next version + # Field(name="moments", fields=moments_fields), ] query_nodes: List[Field] = [ @@ -1142,6 +1177,12 @@ class CustomerJourney(ShopifyBulkQuery): "createdAt", "updatedAt", Field(name="customerJourneySummary", fields=customer_journey_summary_fields), + Field( + name="customerJourney", + fields=[ + Field(name="moments", fields=customer_visit_fragment), + ], + ), ] record_composition = { @@ -1152,6 +1193,9 @@ def process_visit( self, visit_data: Mapping[str, Any], ) -> MutableMapping[str, Any]: + if not visit_data: + return {} + # save the id before it's resolved visit_data["admin_graphql_api_id"] = visit_data.get("id") # resolve the order_id to str @@ -1162,14 +1206,24 @@ def process_visit( visit_data = self.tools.fields_names_to_snake_case(visit_data) return visit_data + def process_moments(self, entity: List[Mapping[str, Any]]) -> List[MutableMapping[str, Any]]: + moments = [] + for item in entity: + moments.append(self.process_visit(item)) + return moments + def process_customer_journey(self, record: MutableMapping[str, Any]) -> MutableMapping[str, Any]: customer_journey_summary = record.get("customerJourneySummary", {}) if customer_journey_summary: # process first, last visit data - first_visit = customer_journey_summary.get("firstVisit", {}) - last_visit = customer_journey_summary.get("lastVisit", {}) - customer_journey_summary["firstVisit"] = self.process_visit(first_visit) if first_visit else {} - customer_journey_summary["lastVisit"] = self.process_visit(last_visit) if last_visit else {} + customer_journey_summary["firstVisit"] = self.process_visit(customer_journey_summary.get("firstVisit")) + customer_journey_summary["lastVisit"] = self.process_visit(customer_journey_summary.get("lastVisit")) + + # # this will be a part of summary in the next api version + if customer_journey := record.get("customerJourney", {}): + moments = customer_journey.get("moments", []) + customer_journey_summary["moments"] = self.process_moments(moments) + # cast field names to snake_case customer_journey_summary = self.tools.fields_names_to_snake_case(customer_journey_summary) return customer_journey_summary @@ -2510,6 +2564,10 @@ class ProductVariant(ShopifyBulkQuery): color image { id + image { + src + url + } } } } @@ -2517,6 +2575,8 @@ class ProductVariant(ShopifyBulkQuery): grams: weight image { image_id: id + image_src: src + image_url: url } old_inventory_quantity: inventoryQuantity product { @@ -2556,7 +2616,6 @@ def _should_include_presentment_prices(self) -> bool: @property def query_nodes(self) -> Optional[Union[List[Field], List[str]]]: - prices_fields: List[str] = ["amount", "currencyCode"] presentment_prices_fields: List[Field] = [ Field( @@ -2577,7 +2636,7 @@ def query_nodes(self) -> Optional[Union[List[Field], List[str]]]: "id", "name", Field(name="hasVariants", alias="has_variants"), - Field(name="swatch", fields=["color", Field(name="image", fields=["id"])]), + Field(name="swatch", fields=["color", Field(name="image", fields=["id", Field(name="image", fields=["src", "url"])])]), ] option_fields: List[Field] = [ "name", @@ -2588,6 +2647,12 @@ def query_nodes(self) -> Optional[Union[List[Field], List[str]]]: [Field(name="presentmentPrices", fields=presentment_prices_fields)] if self._should_include_presentment_prices else [] ) + image_fields = [ + Field(name="id", alias="image_id"), + Field(name="src", alias="image_src"), + Field(name="url", alias="image_url"), + ] + query_nodes: List[Field] = [ "__typename", "id", @@ -2611,7 +2676,7 @@ def query_nodes(self) -> Optional[Union[List[Field], List[str]]]: "taxCode", Field(name="selectedOptions", alias="options", fields=option_fields), Field(name="weight", alias="grams"), - Field(name="image", fields=[Field(name="id", alias="image_id")]), + Field(name="image", fields=image_fields), Field(name="inventoryQuantity", alias="old_inventory_quantity"), Field(name="product", fields=[Field(name="id", alias="product_id")]), Field(name="fulfillmentService", fields=[Field(name="handle", alias="fulfillment_service")]), @@ -2677,6 +2742,9 @@ def record_process_components(self, record: MutableMapping[str, Any]) -> Iterabl record["product_id"] = self._unnest_and_resolve_id(record, "product", "product_id") record["inventory_item_id"] = self._unnest_and_resolve_id(record, "inventoryItem", "inventory_item_id") record["image_id"] = self._unnest_and_resolve_id(record, "image", "image_id") + image = record.get("image", {}) + record["image_src"] = image.get("image_src") if image else None + record["image_url"] = image.get("image_url") if image else None # unnest `fulfillment_service` from `fulfillmentService` record["fulfillment_service"] = record.get("fulfillmentService", {}).get("fulfillment_service") # cast the `price` to number, could be literally `None` diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/retry.py b/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/retry.py index 61e80937a354..ffa0852de799 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/retry.py +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/retry.py @@ -8,6 +8,7 @@ from .exceptions import ShopifyBulkExceptions + BULK_RETRY_ERRORS: Final[Tuple] = ( ShopifyBulkExceptions.BulkJobBadResponse, ShopifyBulkExceptions.BulkJobError, diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/tools.py b/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/tools.py index dfa3fafdd0c6..40fa1e8b2733 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/tools.py +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/tools.py @@ -11,6 +11,7 @@ from .exceptions import ShopifyBulkExceptions + # default end line tag END_OF_FILE: str = "" BULK_PARENT_KEY: str = "__parentId" diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/graphql.py b/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/graphql.py index 462ad3ea3aa8..d7a7f6b4a76e 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/graphql.py +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/graphql.py @@ -9,6 +9,7 @@ from . import schema + _schema = schema _schema_root = _schema.shopify_schema diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/schema.py b/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/schema.py index d3647a562084..fb24170f11be 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/schema.py +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/schema.py @@ -7,6 +7,7 @@ import sgqlc.types.datetime import sgqlc.types.relay + shopify_schema = sgqlc.types.Schema() diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/source.py b/airbyte-integrations/connectors/source-shopify/source_shopify/source.py index 3d420b331891..76a2e27f83c1 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/source.py +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/source.py @@ -6,11 +6,12 @@ import logging from typing import Any, List, Mapping, Tuple +from requests.exceptions import ConnectionError, RequestException, SSLError + from airbyte_cdk.models import FailureType, SyncMode from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.utils import AirbyteTracedException -from requests.exceptions import ConnectionError, RequestException, SSLError from .auth import MissingAccessTokenError, ShopifyAuthenticator from .scopes import ShopifyScopes diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/spec.json b/airbyte-integrations/connectors/source-shopify/source_shopify/spec.json index af70d2ce01fe..0410417a7e9a 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/spec.json +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/spec.json @@ -115,10 +115,10 @@ "job_checkpoint_interval": { "type": "integer", "title": "BULK Job checkpoint (rows collected)", - "description": "The threshold, after which the single BULK Job should be checkpointed.", + "description": "The threshold, after which the single BULK Job should be checkpointed (min: 15k, max: 1M)", "default": 100000, "minimum": 15000, - "maximum": 200000 + "maximum": 1000000 } } }, diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/streams/base_streams.py b/airbyte-integrations/connectors/source-shopify/source_shopify/streams/base_streams.py index 3837212ad9f2..fc5ead602a7c 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/streams/base_streams.py +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/streams/base_streams.py @@ -12,11 +12,6 @@ import pendulum as pdm import requests -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.streams.core import StreamData -from airbyte_cdk.sources.streams.http import HttpClient, HttpStream -from airbyte_cdk.sources.streams.http.error_handlers import ErrorHandler, HttpStatusErrorHandler -from airbyte_cdk.sources.streams.http.error_handlers.default_error_mapping import DEFAULT_ERROR_MAPPING from requests.exceptions import RequestException from source_shopify.http_request import ShopifyErrorHandler from source_shopify.shopify_graphql.bulk.job import ShopifyBulkManager @@ -26,6 +21,12 @@ from source_shopify.utils import ShopifyNonRetryableErrors from source_shopify.utils import ShopifyRateLimiter as limiter +from airbyte_cdk.models import SyncMode +from airbyte_cdk.sources.streams.core import StreamData +from airbyte_cdk.sources.streams.http import HttpClient, HttpStream +from airbyte_cdk.sources.streams.http.error_handlers import ErrorHandler, HttpStatusErrorHandler +from airbyte_cdk.sources.streams.http.error_handlers.default_error_mapping import DEFAULT_ERROR_MAPPING + class ShopifyStream(HttpStream, ABC): # define default logger diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/streams/streams.py b/airbyte-integrations/connectors/source-shopify/source_shopify/streams/streams.py index 2751a3ab9756..58f4986221c6 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/streams/streams.py +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/streams/streams.py @@ -6,8 +6,6 @@ from typing import Any, Iterable, Mapping, MutableMapping, Optional import requests -from airbyte_cdk.sources.streams.core import package_name_from_class -from airbyte_cdk.sources.utils.schema_helpers import ResourceSchemaLoader from requests.exceptions import RequestException from source_shopify.shopify_graphql.bulk.query import ( Collection, @@ -36,6 +34,9 @@ from source_shopify.utils import ApiTypeEnum from source_shopify.utils import ShopifyRateLimiter as limiter +from airbyte_cdk.sources.streams.core import package_name_from_class +from airbyte_cdk.sources.utils.schema_helpers import ResourceSchemaLoader + from .base_streams import ( IncrementalShopifyGraphQlBulkStream, IncrementalShopifyNestedStream, @@ -249,7 +250,6 @@ class MetafieldCollections(IncrementalShopifyGraphQlBulkStream): class BalanceTransactions(IncrementalShopifyStream): - """ PaymentsTransactions stream does not support Incremental Refresh based on datetime fields, only `since_id` is supported: https://shopify.dev/api/admin-rest/2021-07/resources/transactions diff --git a/airbyte-integrations/connectors/source-shopify/source_shopify/utils.py b/airbyte-integrations/connectors/source-shopify/source_shopify/utils.py index d7fd17a42846..fa510b87ba91 100644 --- a/airbyte-integrations/connectors/source-shopify/source_shopify/utils.py +++ b/airbyte-integrations/connectors/source-shopify/source_shopify/utils.py @@ -10,10 +10,12 @@ from typing import Any, Callable, Dict, Final, List, Mapping, Optional import requests + from airbyte_cdk.models import FailureType from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, ResponseAction from airbyte_cdk.utils import AirbyteTracedException + # default logger instance LOGGER: Final[logging.Logger] = logging.getLogger("airbyte") @@ -47,7 +49,7 @@ def __new__(self, stream: str) -> Mapping[str, Any]: response_action=ResponseAction.IGNORE, failure_type=FailureType.config_error, error_message=f"Stream `{stream}`. Entity might not be available or missing.", - ) + ), # extend the mapping with more handable errors, if needed. } diff --git a/airbyte-integrations/connectors/source-shopify/unit_tests/conftest.py b/airbyte-integrations/connectors/source-shopify/unit_tests/conftest.py index 78842454a757..4dbba74a333b 100644 --- a/airbyte-integrations/connectors/source-shopify/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-shopify/unit_tests/conftest.py @@ -9,8 +9,10 @@ import pytest import requests + from airbyte_cdk.models import AirbyteStream, ConfiguredAirbyteCatalog, ConfiguredAirbyteStream, DestinationSyncMode, SyncMode + os.environ["REQUEST_CACHE_PATH"] = "REQUEST_CACHE_PATH" @@ -39,7 +41,7 @@ def logger(): @pytest.fixture def basic_config(): return { - "shop": "test_shop", + "shop": "test_shop", "credentials": {"auth_method": "api_password", "api_password": "api_password"}, "shop_id": 0, } @@ -52,7 +54,6 @@ def auth_config(): "start_date": "2023-01-01", "credentials": {"auth_method": "api_password", "api_password": "api_password"}, "authenticator": None, - } @@ -358,7 +359,7 @@ def bulk_job_failed_response(): }, } - + @pytest.fixture def bulk_job_failed_with_partial_url_response(): return { @@ -371,20 +372,16 @@ def bulk_job_failed_with_partial_url_response(): "fileSize": None, "url": None, "partialDataUrl": 'https://some_url?response-content-disposition=attachment;+filename="bulk-123456789.jsonl";+filename*=UTF-8' - "bulk-123456789.jsonl&response-content-type=application/jsonl" + "bulk-123456789.jsonl&response-content-type=application/jsonl", } }, "extensions": { "cost": { "requestedQueryCost": 1, "actualQueryCost": 1, - "throttleStatus": { - "maximumAvailable": 20000.0, - "currentlyAvailable": 19999, - "restoreRate": 1000.0 - } + "throttleStatus": {"maximumAvailable": 20000.0, "currentlyAvailable": 19999, "restoreRate": 1000.0}, } - } + }, } @@ -442,8 +439,8 @@ def bulk_job_running_response(): } }, } - - + + @pytest.fixture def bulk_job_running_with_object_count_and_url_response(): return { @@ -995,6 +992,8 @@ def product_variants_response_expected_result(): "product_id": 6796220989629, "inventory_item_id": 43653682495677, "image_id": None, + "image_src": None, + "image_url": None, "shop_url": "test_shop", }, { @@ -1025,6 +1024,8 @@ def product_variants_response_expected_result(): "product_id": 6796825198781, "inventory_item_id": 42186366255293, "image_id": None, + "image_src": None, + "image_url": None, "shop_url": "test_shop", }, ] diff --git a/airbyte-integrations/connectors/source-shopify/unit_tests/graphql_bulk/test_job.py b/airbyte-integrations/connectors/source-shopify/unit_tests/graphql_bulk/test_job.py index 90eb6faaf67d..afce4d33ab18 100644 --- a/airbyte-integrations/connectors/source-shopify/unit_tests/graphql_bulk/test_job.py +++ b/airbyte-integrations/connectors/source-shopify/unit_tests/graphql_bulk/test_job.py @@ -7,7 +7,6 @@ import pytest import requests -from airbyte_cdk.models import SyncMode from source_shopify.shopify_graphql.bulk.exceptions import ShopifyBulkExceptions from source_shopify.shopify_graphql.bulk.status import ShopifyBulkJobStatus from source_shopify.streams.streams import ( @@ -25,15 +24,18 @@ TransactionsGraphql, ) +from airbyte_cdk.models import SyncMode + + _ANY_SLICE = {} _ANY_FILTER_FIELD = "any_filter_field" def test_job_manager_default_values(auth_config) -> None: stream = Products(auth_config) - + # 10Mb chunk size to save the file - assert stream.job_manager._retrieve_chunk_size == 10485760 # 1024 * 1024 * 10 + assert stream.job_manager._retrieve_chunk_size == 10485760 # 1024 * 1024 * 10 assert stream.job_manager._job_max_retries == 6 assert stream.job_manager._job_backoff_time == 5 # running job logger constrain, every 100-ish message will be printed @@ -48,7 +50,7 @@ def test_job_manager_default_values(auth_config) -> None: # currents: _job_id, _job_state, _job_created_at, _job_self_canceled assert not stream.job_manager._job_id # this string is based on ShopifyBulkJobStatus - assert not stream.job_manager._job_state + assert not stream.job_manager._job_state # completed and saved Bulk Job result filename assert not stream.job_manager._job_result_filename # date-time when the Bulk Job was created on the server @@ -56,7 +58,7 @@ def test_job_manager_default_values(auth_config) -> None: # indicated whether or not we manually force-cancel the current job assert not stream.job_manager._job_self_canceled # time between job status checks - assert stream.job_manager. _job_check_interval == 3 + assert stream.job_manager._job_check_interval == 3 # 0.1 ~= P2H, default value, lower boundary for slice size assert stream.job_manager._job_size_min == 0.1 # last running job object count @@ -99,8 +101,9 @@ def test_retry_on_concurrent_job(request, requests_mock, auth_config) -> None: {"json": request.getfixturevalue("bulk_error_with_concurrent_job")}, # concurrent request has finished {"json": request.getfixturevalue("bulk_successful_response")}, - ]) - + ], + ) + stream.job_manager.create_job(_ANY_SLICE, _ANY_FILTER_FIELD) # call count should be 4 (3 retries, 1 - succeeded) assert requests_mock.call_count == 4 @@ -119,14 +122,16 @@ def test_retry_on_concurrent_job(request, requests_mock, auth_config) -> None: ], ids=[ "max attempt reached", - ] + ], ) -def test_job_retry_on_concurrency(request, requests_mock, bulk_job_response, concurrent_max_retry, error_type, auth_config, expected) -> None: +def test_job_retry_on_concurrency( + request, requests_mock, bulk_job_response, concurrent_max_retry, error_type, auth_config, expected +) -> None: stream = MetafieldOrders(auth_config) # patching concurrent settings stream.job_manager._concurrent_max_retry = concurrent_max_retry stream.job_manager._concurrent_interval = 1 - + requests_mock.post(stream.job_manager.base_url, json=request.getfixturevalue(bulk_job_response)) if error_type: @@ -200,8 +205,8 @@ def test_job_check_for_completion(mocker, request, requests_mock, job_response, mocker.patch("source_shopify.shopify_graphql.bulk.record.ShopifyBulkRecord.read_file", return_value=[]) stream.job_manager._job_check_state() assert expected == stream.job_manager._job_result_filename - - + + @pytest.mark.parametrize( "job_response, error_type, expected", [ @@ -211,7 +216,9 @@ def test_job_check_for_completion(mocker, request, requests_mock, job_response, "failed", ], ) -def test_job_failed_for_stream_with_no_bulk_checkpointing(mocker, request, requests_mock, job_response, error_type, expected, auth_config) -> None: +def test_job_failed_for_stream_with_no_bulk_checkpointing( + mocker, request, requests_mock, job_response, error_type, expected, auth_config +) -> None: stream = InventoryLevels(auth_config) # modify the sleep time for the test stream.job_manager._concurrent_max_retry = 1 @@ -253,26 +260,28 @@ def test_job_failed_for_stream_with_no_bulk_checkpointing(mocker, request, reque "BulkJobBadResponse", ], ) -def test_retry_on_job_creation_exception(request, requests_mock, auth_config, job_response, job_state, error_type, max_retry, call_count_expected, expected_msg) -> None: +def test_retry_on_job_creation_exception( + request, requests_mock, auth_config, job_response, job_state, error_type, max_retry, call_count_expected, expected_msg +) -> None: stream = MetafieldOrders(auth_config) stream.job_manager._job_backoff_time = 0 stream.job_manager._job_max_retries = max_retry # patching the method to get the right ID checks if job_response: stream.job_manager._job_id = request.getfixturevalue(job_response).get("data", {}).get("node", {}).get("id") - + if job_state: # setting job_state to simulate the error-in-the-middle stream.job_manager._job_state = request.getfixturevalue(job_response).get("data", {}).get("node", {}).get("status") - + # mocking the response for STATUS CHECKS json_mock_response = request.getfixturevalue(job_response) if job_response else None requests_mock.post(stream.job_manager.base_url, json=json_mock_response) - + # testing raised exception and backoff with pytest.raises(error_type) as error: stream.job_manager.create_job(_ANY_SLICE, _ANY_FILTER_FIELD) - + # we expect different call_count, because we set the different max_retries assert expected_msg in repr(error.value) and requests_mock.call_count == call_count_expected @@ -302,11 +311,11 @@ def test_job_check_with_running_scenario(request, requests_mock, job_response, a job_result_url = test_job_status_response.json().get("data", {}).get("node", {}).get("url") # test the state of the job isn't assigned assert stream.job_manager._job_state == None - + # mocking the nested request call to retrieve the data from result URL stream.job_manager._job_id = job_id requests_mock.get(job_result_url, json=request.getfixturevalue(job_response)) - + # calling the sceario processing stream.job_manager._job_track_running() assert stream.job_manager._job_state == expected @@ -316,13 +325,13 @@ def test_job_check_with_running_scenario(request, requests_mock, job_response, a "running_job_response, canceled_job_response, expected", [ ( - "bulk_job_running_with_object_count_and_url_response", - "bulk_job_canceled_with_object_count_and_url_response", + "bulk_job_running_with_object_count_and_url_response", + "bulk_job_canceled_with_object_count_and_url_response", "bulk-123456789.jsonl", ), ( - "bulk_job_running_with_object_count_no_url_response", - "bulk_job_canceled_with_object_count_no_url_response", + "bulk_job_running_with_object_count_no_url_response", + "bulk_job_canceled_with_object_count_no_url_response", None, ), ], @@ -331,7 +340,9 @@ def test_job_check_with_running_scenario(request, requests_mock, job_response, a "self-canceled with no url", ], ) -def test_job_running_with_canceled_scenario(mocker, request, requests_mock, running_job_response, canceled_job_response, auth_config, expected) -> None: +def test_job_running_with_canceled_scenario( + mocker, request, requests_mock, running_job_response, canceled_job_response, auth_config, expected +) -> None: stream = MetafieldOrders(auth_config) # modify the sleep time for the test stream.job_manager._job_check_interval = 0 @@ -339,7 +350,7 @@ def test_job_running_with_canceled_scenario(mocker, request, requests_mock, runn job_id = request.getfixturevalue(running_job_response).get("data", {}).get("node", {}).get("id") # mocking the response for STATUS CHECKS requests_mock.post( - stream.job_manager.base_url, + stream.job_manager.base_url, [ {"json": request.getfixturevalue(running_job_response)}, {"json": request.getfixturevalue(canceled_job_response)}, @@ -348,7 +359,7 @@ def test_job_running_with_canceled_scenario(mocker, request, requests_mock, runn job_result_url = request.getfixturevalue(canceled_job_response).get("data", {}).get("node", {}).get("url") # test the state of the job isn't assigned assert stream.job_manager._job_state == None - + stream.job_manager._job_id = job_id stream.job_manager._job_checkpoint_interval = 5 # faking self-canceled job @@ -448,9 +459,9 @@ def test_bulk_stream_parse_response( ) def test_stream_slices( auth_config, - stream, - stream_state, - with_start_date, + stream, + stream_state, + with_start_date, expected_start, ) -> None: # simulating `None` for `start_date` and `config migration` @@ -462,7 +473,7 @@ def test_stream_slices( test_result = list(stream.stream_slices(stream_state=stream_state)) assert test_result[0].get("start") == expected_start - + @pytest.mark.parametrize( "stream, json_content_example, last_job_elapsed_time, previous_slice_size, adjusted_slice_size", [ @@ -471,7 +482,7 @@ def test_stream_slices( ids=[ "Expand Slice Size", ], -) +) def test_expand_stream_slices_job_size( request, requests_mock, @@ -483,7 +494,6 @@ def test_expand_stream_slices_job_size( adjusted_slice_size, auth_config, ) -> None: - stream = stream(auth_config) # get the mocked job_result_url test_result_url = bulk_job_completed_response.get("data").get("node").get("url") @@ -495,7 +505,7 @@ def test_expand_stream_slices_job_size( # for the sake of simplicity we fake some parts to simulate the `current_job_time_elapsed` # fake current slice interval value stream.job_manager._job_size = previous_slice_size - # fake `last job elapsed time` + # fake `last job elapsed time` if last_job_elapsed_time: stream.job_manager._job_last_elapsed_time = last_job_elapsed_time diff --git a/airbyte-integrations/connectors/source-shopify/unit_tests/graphql_bulk/test_query.py b/airbyte-integrations/connectors/source-shopify/unit_tests/graphql_bulk/test_query.py index 8a5d7012d38b..cf586b159ae1 100644 --- a/airbyte-integrations/connectors/source-shopify/unit_tests/graphql_bulk/test_query.py +++ b/airbyte-integrations/connectors/source-shopify/unit_tests/graphql_bulk/test_query.py @@ -30,12 +30,12 @@ def test_query_status() -> None: } } }""" - + input_job_id = "gid://shopify/BulkOperation/4047052112061" template = ShopifyBulkTemplates.status(input_job_id) assert repr(template) == repr(expected) - - + + def test_bulk_query_prepare() -> None: expected = '''mutation { bulkOperationRunQuery( @@ -54,14 +54,14 @@ def test_bulk_query_prepare() -> None: } } }''' - + input_query_from_slice = "{some_query}" template = ShopifyBulkTemplates.prepare(input_query_from_slice) assert repr(template) == repr(expected) - - + + def test_bulk_query_cancel() -> None: - expected = '''mutation { + expected = """mutation { bulkOperationCancel(id: "gid://shopify/BulkOperation/4047052112061") { bulkOperation { id @@ -73,32 +73,32 @@ def test_bulk_query_cancel() -> None: message } } - }''' - + }""" + input_job_id = "gid://shopify/BulkOperation/4047052112061" template = ShopifyBulkTemplates.cancel(input_job_id) assert repr(template) == repr(expected) - + @pytest.mark.parametrize( "query_name, fields, filter_field, start, end, expected", [ ( - "test_root", - ["test_field1", "test_field2"], + "test_root", + ["test_field1", "test_field2"], "updated_at", "2023-01-01", - "2023-01-02", + "2023-01-02", Query( - name='test_root', + name="test_root", arguments=[ - Argument(name="query", value=f"\"updated_at:>'2023-01-01' AND updated_at:<='2023-01-02'\""), - ], - fields=[Field(name='edges', fields=[Field(name='node', fields=["test_field1", "test_field2"])])] - ) + Argument(name="query", value=f"\"updated_at:>'2023-01-01' AND updated_at:<='2023-01-02'\""), + ], + fields=[Field(name="edges", fields=[Field(name="node", fields=["test_field1", "test_field2"])])], + ), ) ], - ids=["simple query with filter and sort"] + ids=["simple query with filter and sort"], ) def test_base_build_query(basic_config, query_name, fields, filter_field, start, end, expected) -> None: """ @@ -116,7 +116,7 @@ def test_base_build_query(basic_config, query_name, fields, filter_field, start, } ''' """ - + builder = ShopifyBulkQuery(basic_config) filter_query = f"{filter_field}:>'{start}' AND {filter_field}:<='{end}'" built_query = builder.build(query_name, fields, filter_query) @@ -136,14 +136,52 @@ def test_base_build_query(basic_config, query_name, fields, filter_field, start, type="", queries=[ Query( - name='customers', + name="customers", arguments=[ Argument(name="query", value=f"\"updated_at:>='2023-01-01' AND updated_at:<='2023-01-02'\""), - Argument(name="sortKey", value="UPDATED_AT"), - ], - fields=[Field(name='edges', fields=[Field(name='node', fields=['__typename', 'id', Field(name="updatedAt", alias="customers_updated_at"), Field(name="metafields", fields=[Field(name="edges", fields=[Field(name="node", fields=["__typename", "id", "namespace", "value", "key", "description", "createdAt", "updatedAt", "type"])])])])])] + Argument(name="sortKey", value="UPDATED_AT"), + ], + fields=[ + Field( + name="edges", + fields=[ + Field( + name="node", + fields=[ + "__typename", + "id", + Field(name="updatedAt", alias="customers_updated_at"), + Field( + name="metafields", + fields=[ + Field( + name="edges", + fields=[ + Field( + name="node", + fields=[ + "__typename", + "id", + "namespace", + "value", + "key", + "description", + "createdAt", + "updatedAt", + "type", + ], + ) + ], + ) + ], + ), + ], + ) + ], + ) + ], ) - ] + ], ), ), ( @@ -206,28 +244,28 @@ def test_base_build_query(basic_config, query_name, fields, filter_field, start, "createdAt", "updatedAt", "type", - ] + ], ) - ] + ], ) - ] + ], ) - ] - ) - ] + ], + ), + ], ) - ] + ], ) - ] - ) - ] + ], + ), + ], ) - ] + ], ) - ] + ], ) - ] - ) + ], + ), ), ( InventoryLevel, @@ -239,64 +277,91 @@ def test_base_build_query(basic_config, query_name, fields, filter_field, start, type="", queries=[ Query( - name='locations', + name="locations", arguments=[ Argument(name="includeLegacy", value="true"), Argument(name="includeInactive", value="true"), - ], + ], fields=[ Field( - name='edges', + name="edges", fields=[ Field( - name='node', + name="node", fields=[ - '__typename', - 'id', + "__typename", + "id", Field( - name="inventoryLevels", + name="inventoryLevels", arguments=[ - Argument(name="query", value=f"\"updated_at:>='2023-01-01' AND updated_at:<='2023-01-02'\""), - ], + Argument( + name="query", value=f"\"updated_at:>='2023-01-01' AND updated_at:<='2023-01-02'\"" + ), + ], fields=[ Field( - name="edges", + name="edges", fields=[ Field( - name="node", + name="node", fields=[ - "__typename", - "id", - "canDeactivate", - "createdAt", - "deactivationAlert", - "updatedAt", - Field(name="item", fields=[Field(name="inventoryHistoryUrl", alias="inventory_history_url"), Field(name="id", alias="inventory_item_id"), Field(name="locationsCount", alias="locations_count", fields=["count"])]), - Field( - name="quantities", + "__typename", + "id", + "canDeactivate", + "createdAt", + "deactivationAlert", + "updatedAt", + Field( + name="item", + fields=[ + Field( + name="inventoryHistoryUrl", alias="inventory_history_url" + ), + Field(name="id", alias="inventory_item_id"), + Field( + name="locationsCount", + alias="locations_count", + fields=["count"], + ), + ], + ), + Field( + name="quantities", arguments=[ - Argument(name="names", value=['"available"', '"incoming"', '"committed"', '"damaged"', '"on_hand"', '"quality_control"', '"reserved"', '"safety_stock"']) - ], + Argument( + name="names", + value=[ + '"available"', + '"incoming"', + '"committed"', + '"damaged"', + '"on_hand"', + '"quality_control"', + '"reserved"', + '"safety_stock"', + ], + ) + ], fields=[ "id", "name", "quantity", "updatedAt", ], - ) - ] + ), + ], ) - ] + ], ) - ] - ) - ] + ], + ), + ], ) - ] + ], ) - ] + ], ) - ] + ], ), ), ], @@ -304,7 +369,7 @@ def test_base_build_query(basic_config, query_name, fields, filter_field, start, "MetafieldCustomers query with 1 query_path(str)", "MetafieldProductImages query with composite quey_path(List[2])", "InventoryLevel query", - ] + ], ) def test_bulk_query(auth_config, query_class, filter_field, start, end, parent_stream_class, expected) -> None: if parent_stream_class: @@ -314,4 +379,4 @@ def test_bulk_query(auth_config, query_class, filter_field, start, end, parent_s else: stream_query = query_class(auth_config) - assert stream_query.get(filter_field, start, end) == expected.render() \ No newline at end of file + assert stream_query.get(filter_field, start, end) == expected.render() diff --git a/airbyte-integrations/connectors/source-shopify/unit_tests/graphql_bulk/test_record.py b/airbyte-integrations/connectors/source-shopify/unit_tests/graphql_bulk/test_record.py index dff60ea605d5..85c48ce6d13b 100644 --- a/airbyte-integrations/connectors/source-shopify/unit_tests/graphql_bulk/test_record.py +++ b/airbyte-integrations/connectors/source-shopify/unit_tests/graphql_bulk/test_record.py @@ -58,7 +58,7 @@ def test_check_type(basic_config, record, types, expected) -> None: "alias_to_id_field": "gid://shopify/Metafield/123", "__parentId": "gid://shopify/Order/102030", }, - ) + ), ], ) def test_record_resolver(basic_config, record, expected) -> None: diff --git a/airbyte-integrations/connectors/source-shopify/unit_tests/integration/api/authentication.py b/airbyte-integrations/connectors/source-shopify/unit_tests/integration/api/authentication.py index df16077abc14..d878a1c4e9a4 100644 --- a/airbyte-integrations/connectors/source-shopify/unit_tests/integration/api/authentication.py +++ b/airbyte-integrations/connectors/source-shopify/unit_tests/integration/api/authentication.py @@ -2,11 +2,13 @@ import json +from source_shopify.scopes import SCOPES_MAPPING +from source_shopify.streams.base_streams import ShopifyStream + from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse from airbyte_cdk.test.mock_http.request import ANY_QUERY_PARAMS from airbyte_cdk.test.mock_http.response_builder import find_template -from source_shopify.scopes import SCOPES_MAPPING -from source_shopify.streams.base_streams import ShopifyStream + _ALL_SCOPES = [scope for stream_scopes in SCOPES_MAPPING.values() for scope in stream_scopes] diff --git a/airbyte-integrations/connectors/source-shopify/unit_tests/integration/api/bulk.py b/airbyte-integrations/connectors/source-shopify/unit_tests/integration/api/bulk.py index 548e8c6e3e14..29ae2d9ae93e 100644 --- a/airbyte-integrations/connectors/source-shopify/unit_tests/integration/api/bulk.py +++ b/airbyte-integrations/connectors/source-shopify/unit_tests/integration/api/bulk.py @@ -4,10 +4,11 @@ from datetime import datetime from random import randint -from airbyte_cdk.test.mock_http import HttpRequest, HttpResponse from source_shopify.shopify_graphql.bulk.query import ShopifyBulkTemplates from source_shopify.streams.base_streams import ShopifyStream +from airbyte_cdk.test.mock_http import HttpRequest, HttpResponse + def _create_job_url(shop_name: str) -> str: return f"https://{shop_name}.myshopify.com/admin/api/{ShopifyStream.api_version}/graphql.json" @@ -42,16 +43,15 @@ def create_job_creation_body(lower_boundary: datetime, upper_boundary: datetime) } } }""" - query = query.replace("%LOWER_BOUNDARY_TOKEN%", lower_boundary.isoformat()).replace("%UPPER_BOUNDARY_TOKEN%", upper_boundary.isoformat()) + query = query.replace("%LOWER_BOUNDARY_TOKEN%", lower_boundary.isoformat()).replace( + "%UPPER_BOUNDARY_TOKEN%", upper_boundary.isoformat() + ) prepared_query = ShopifyBulkTemplates.prepare(query) return json.dumps({"query": prepared_query}) def create_job_creation_request(shop_name: str, lower_boundary: datetime, upper_boundary: datetime) -> HttpRequest: - return HttpRequest( - url=_create_job_url(shop_name), - body=create_job_creation_body(lower_boundary, upper_boundary) - ) + return HttpRequest(url=_create_job_url(shop_name), body=create_job_creation_body(lower_boundary, upper_boundary)) def create_job_status_request(shop_name: str, job_id: str) -> HttpRequest: @@ -70,34 +70,45 @@ def create_job_status_request(shop_name: str, job_id: str) -> HttpRequest: partialDataUrl }} }} - }}""" + }}""", + ) + + +def create_job_cancel_request(shop_name: str, job_id: str) -> HttpRequest: + return HttpRequest( + url=_create_job_url(shop_name), + body=f"""mutation {{ + bulkOperationCancel(id: "{job_id}") {{ + bulkOperation {{ + id + status + createdAt + }} + userErrors {{ + field + message + }} + }} + }}""", ) class JobCreationResponseBuilder: - def __init__(self) -> None: + def __init__(self, job_created_at: str = "2024-05-05T02:00:00Z") -> None: self._template = { "data": { "bulkOperationRunQuery": { - "bulkOperation": { - "id": "gid://shopify/BulkOperation/0", - "status": "CREATED", - "createdAt": "2024-05-05T02:00:00Z" - }, - "userErrors": [] + "bulkOperation": {"id": "gid://shopify/BulkOperation/0", "status": "CREATED", "createdAt": f"{job_created_at}"}, + "userErrors": [], } }, "extensions": { "cost": { "requestedQueryCost": 10, "actualQueryCost": 10, - "throttleStatus": { - "maximumAvailable": 2000.0, - "currentlyAvailable": 1990, - "restoreRate": 100.0 - } + "throttleStatus": {"maximumAvailable": 2000.0, "currentlyAvailable": 1990, "restoreRate": 100.0}, } - } + }, } def with_bulk_operation_id(self, bulk_operation_id: str) -> "JobCreationResponseBuilder": @@ -117,39 +128,48 @@ def __init__(self) -> None: "cost": { "requestedQueryCost": 1, "actualQueryCost": 1, - "throttleStatus": { - "maximumAvailable": 2000.0, - "currentlyAvailable": 1999, - "restoreRate": 100.0 - } + "throttleStatus": {"maximumAvailable": 2000.0, "currentlyAvailable": 1999, "restoreRate": 100.0}, } - } + }, } } - def with_running_status(self, bulk_operation_id: str) -> "JobStatusResponseBuilder": + def with_running_status(self, bulk_operation_id: str, object_count: str = "10") -> "JobStatusResponseBuilder": self._template["data"]["node"] = { - "id": bulk_operation_id, - "status": "RUNNING", - "errorCode": None, - "createdAt": "2024-05-28T18:57:54Z", - "objectCount": "10", - "fileSize": None, - "url": None, - "partialDataUrl": None, + "id": bulk_operation_id, + "status": "RUNNING", + "errorCode": None, + "createdAt": "2024-05-28T18:57:54Z", + "objectCount": object_count, + "fileSize": None, + "url": None, + "partialDataUrl": None, } return self - def with_completed_status(self, bulk_operation_id: str, job_result_url: str) -> "JobStatusResponseBuilder": + def with_completed_status(self, bulk_operation_id: str, job_result_url: str, object_count: str = "4") -> "JobStatusResponseBuilder": self._template["data"]["node"] = { "id": bulk_operation_id, "status": "COMPLETED", "errorCode": None, "createdAt": "2024-05-05T00:45:48Z", - "objectCount": "4", + "objectCount": object_count, "fileSize": "774", "url": job_result_url, - "partialDataUrl": None + "partialDataUrl": None, + } + return self + + def with_canceled_status(self, bulk_operation_id: str, job_result_url: str, object_count: str = "4") -> "JobStatusResponseBuilder": + self._template["data"]["node"] = { + "id": bulk_operation_id, + "status": "CANCELED", + "errorCode": None, + "createdAt": "2024-05-05T00:45:48Z", + "objectCount": object_count, + "fileSize": "774", + "url": job_result_url, + "partialDataUrl": None, } return self @@ -161,16 +181,15 @@ class MetafieldOrdersJobResponseBuilder: def __init__(self) -> None: self._records = [] - def _any_record(self) -> str: + def _any_record(self, updated_at: str = "2024-05-05T01:09:50Z") -> str: an_id = str(randint(1000000000000, 9999999999999)) a_parent_id = str(randint(1000000000000, 9999999999999)) return f"""{{"__typename":"Order","id":"gid:\/\/shopify\/Order\/{a_parent_id}"}} -{{"__typename":"Metafield","id":"gid:\/\/shopify\/Metafield\/{an_id}","namespace":"my_fields","value":"asdfasdf","key":"purchase_order","description":null,"createdAt":"2023-04-13T12:09:50Z","updatedAt":"2024-05-05T01:09:50Z","type":"single_line_text_field","__parentId":"gid:\/\/shopify\/Order\/{a_parent_id}"}} +{{"__typename":"Metafield","id":"gid:\/\/shopify\/Metafield\/{an_id}","namespace":"my_fields","value":"asdfasdf","key":"purchase_order","description":null,"createdAt":"2023-04-13T12:09:50Z","updatedAt":"{updated_at}","type":"single_line_text_field","__parentId":"gid:\/\/shopify\/Order\/{a_parent_id}"}} """ - - def with_record(self) -> "MetafieldOrdersJobResponseBuilder": - self._records.append(self._any_record()) + def with_record(self, updated_at: str = "2024-05-05T01:09:50Z") -> "MetafieldOrdersJobResponseBuilder": + self._records.append(self._any_record(updated_at=updated_at)) return self def build(self) -> HttpResponse: diff --git a/airbyte-integrations/connectors/source-shopify/unit_tests/integration/test_bulk_stream.py b/airbyte-integrations/connectors/source-shopify/unit_tests/integration/test_bulk_stream.py index 0db012f23a95..ad8d1e31fb37 100644 --- a/airbyte-integrations/connectors/source-shopify/unit_tests/integration/test_bulk_stream.py +++ b/airbyte-integrations/connectors/source-shopify/unit_tests/integration/test_bulk_stream.py @@ -1,28 +1,36 @@ # Copyright (c) 2024 Airbyte, Inc., all rights reserved. import json from datetime import datetime, timedelta -from typing import Any, Dict +from typing import Any, Dict, List, Optional from unittest import TestCase +import pytest + from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import read from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse + _AN_ERROR_RESPONSE = HttpResponse(json.dumps({"errors": ["an error"]})) -from airbyte_cdk.models import SyncMode +_SERVICE_UNAVAILABLE_ERROR_RESPONSE = HttpResponse(json.dumps({"errors": ["Service unavailable"]}), status_code=503) from freezegun import freeze_time from requests.exceptions import ConnectionError from source_shopify import SourceShopify + +from airbyte_cdk.models import AirbyteStateMessage, SyncMode +from airbyte_cdk.test.state_builder import StateBuilder from unit_tests.integration.api.authentication import grant_all_scopes, set_up_shop from unit_tests.integration.api.bulk import ( JobCreationResponseBuilder, JobStatusResponseBuilder, MetafieldOrdersJobResponseBuilder, + create_job_cancel_request, create_job_creation_body, create_job_creation_request, create_job_status_request, ) + _BULK_OPERATION_ID = "gid://shopify/BulkOperation/4472588009661" _BULK_STREAM = "metafield_orders" _SHOP_NAME = "airbyte-integration-test" @@ -33,8 +41,12 @@ _URL_GRAPHQL = f"https://{_SHOP_NAME}.myshopify.com/admin/api/2024-04/graphql.json" _JOB_RESULT_URL = "https://storage.googleapis.com/shopify-tiers-assets-prod-us-east1/bulk-operation-outputs/l6lersgk4i81iqc3n6iisywwtipb-final?GoogleAccessId=assets-us-prod%40shopify-tiers.iam.gserviceaccount.com&Expires=1715633149&Signature=oMjQelfAzUW%2FdulC3HbuBapbUriUJ%2Bc9%2FKpIIf954VTxBqKChJAdoTmWT9ymh%2FnCiHdM%2BeM%2FADz5siAC%2BXtHBWkJfvs%2F0cYpse0ueiQsw6R8gW5JpeSbizyGWcBBWkv5j8GncAnZOUVYDxRIgfxcPb8BlFxBfC3wsx%2F00v9D6EHbPpkIMTbCOAhheJdw9GmVa%2BOMqHGHlmiADM34RDeBPrvSo65f%2FakpV2LBQTEV%2BhDt0ndaREQ0MrpNwhKnc3vZPzA%2BliOGM0wyiYr9qVwByynHq8c%2FaJPPgI5eGEfQcyepgWZTRW5S0DbmBIFxZJLN6Nq6bJ2bIZWrVriUhNGx2g%3D%3D&response-content-disposition=attachment%3B+filename%3D%22bulk-4476008693949.jsonl%22%3B+filename%2A%3DUTF-8%27%27bulk-4476008693949.jsonl&response-content-type=application%2Fjsonl" +_INCREMENTAL_JOB_START_DATE_ISO = "2024-05-05T00:00:00+00:00" +_INCREMENTAL_JOB_START_DATE = datetime.fromisoformat(_INCREMENTAL_JOB_START_DATE_ISO) +_INCREMENTAL_JOB_END_DATE = _INCREMENTAL_JOB_START_DATE + timedelta(hours=24, minutes=0) + -def _get_config(start_date: datetime, bulk_window: int = 1) -> Dict[str, Any]: +def _get_config(start_date: datetime, bulk_window: int = 1, job_checkpoint_interval=200000) -> Dict[str, Any]: return { "start_date": start_date.strftime("%Y-%m-%d"), "shop": _SHOP_NAME, @@ -42,13 +54,13 @@ def _get_config(start_date: datetime, bulk_window: int = 1) -> Dict[str, Any]: "auth_method": "api_password", "api_password": "api_password", }, - "bulk_window_in_days": bulk_window + "bulk_window_in_days": bulk_window, + "job_checkpoint_interval": job_checkpoint_interval, } @freeze_time(_JOB_END_DATE) class GraphQlBulkStreamTest(TestCase): - def setUp(self) -> None: self._http_mocker = HttpMocker() self._http_mocker.__enter__() @@ -95,8 +107,10 @@ def test_given_response_is_not_json_on_job_creation_when_read_then_retry(self) - job_creation_request, [ HttpResponse("This is not json"), - JobCreationResponseBuilder().with_bulk_operation_id(_BULK_OPERATION_ID).build(), # This will never get called (see assertion below) - ] + JobCreationResponseBuilder() + .with_bulk_operation_id(_BULK_OPERATION_ID) + .build(), # This will never get called (see assertion below) + ], ) self._http_mocker.post( @@ -118,8 +132,11 @@ def test_given_connection_error_on_job_creation_when_read_then_retry_job_creatio inner_mocker.register_uri( # TODO the testing library should have the ability to generate ConnectionError. As this might not be trivial, we will wait for another case before implementing "POST", _URL_GRAPHQL, - [{"exc": ConnectionError("ConnectionError")}, {"text": JobCreationResponseBuilder().with_bulk_operation_id(_BULK_OPERATION_ID).build().body, "status_code": 200}], - additional_matcher=lambda request: request.text == create_job_creation_body(_JOB_START_DATE, _JOB_END_DATE) + [ + {"exc": ConnectionError("ConnectionError")}, + {"text": JobCreationResponseBuilder().with_bulk_operation_id(_BULK_OPERATION_ID).build().body, "status_code": 200}, + ], + additional_matcher=lambda request: request.text == create_job_creation_body(_JOB_START_DATE, _JOB_END_DATE), ) self._http_mocker.post( create_job_status_request(_SHOP_NAME, _BULK_OPERATION_ID), @@ -144,7 +161,7 @@ def test_given_retryable_error_on_first_get_job_status_when_read_then_retry(self [ _AN_ERROR_RESPONSE, JobStatusResponseBuilder().with_completed_status(_BULK_OPERATION_ID, _JOB_RESULT_URL).build(), - ] + ], ) self._http_mocker.get( HttpRequest(_JOB_RESULT_URL), @@ -167,7 +184,7 @@ def test_given_retryable_error_on_get_job_status_when_read_then_retry(self) -> N JobStatusResponseBuilder().with_running_status(_BULK_OPERATION_ID).build(), HttpResponse(json.dumps({"errors": ["an error"]})), JobStatusResponseBuilder().with_completed_status(_BULK_OPERATION_ID, _JOB_RESULT_URL).build(), - ] + ], ) self._http_mocker.get( HttpRequest(_JOB_RESULT_URL), @@ -183,3 +200,202 @@ def _read(self, config): catalog = CatalogBuilder().with_stream(_BULK_STREAM, SyncMode.full_refresh).build() output = read(SourceShopify(), config, catalog) return output + + +@freeze_time(_INCREMENTAL_JOB_END_DATE) +class GraphQlBulkStreamIncrementalTest(TestCase): + def setUp(self) -> None: + self._http_mocker = HttpMocker() + self._http_mocker.__enter__() + + set_up_shop(self._http_mocker, _SHOP_NAME) + grant_all_scopes(self._http_mocker, _SHOP_NAME) + + def tearDown(self) -> None: + self._http_mocker.__exit__(None, None, None) + + def test_when_read_then_extract_records(self) -> None: + job_created_at = _INCREMENTAL_JOB_END_DATE - timedelta(minutes=5) + self._http_mocker.post( + create_job_creation_request(_SHOP_NAME, _INCREMENTAL_JOB_START_DATE, _INCREMENTAL_JOB_END_DATE), + JobCreationResponseBuilder(job_created_at=job_created_at.strftime("%Y-%m-%dT%H:%M:%SZ")) + .with_bulk_operation_id(_BULK_OPERATION_ID) + .build(), + ) + self._http_mocker.post( + create_job_status_request(_SHOP_NAME, _BULK_OPERATION_ID), + JobStatusResponseBuilder().with_completed_status(_BULK_OPERATION_ID, _JOB_RESULT_URL).build(), + ) + self._http_mocker.get( + HttpRequest(_JOB_RESULT_URL), + MetafieldOrdersJobResponseBuilder().with_record().with_record().build(), + ) + # expectation is job start date should be the updated_at in orders + metafield_orders_orders_state = { + "orders": {"updated_at": _INCREMENTAL_JOB_START_DATE_ISO, "deleted": {"deleted_at": ""}}, + "updated_at": _INCREMENTAL_JOB_START_DATE_ISO, + } + stream_state = StateBuilder().with_stream_state(_BULK_STREAM, metafield_orders_orders_state).build() + + # we are passing to config a start date let's set something "old" as happen in many sources like 2 years ago + config_start_date = _INCREMENTAL_JOB_START_DATE - timedelta(weeks=104) + output = self._read(_get_config(config_start_date), sync_mode=SyncMode.incremental, state=stream_state) + + assert output.errors == [] + assert len(output.records) == 2 + + def test_when_read_with_updated_at_field_before_bulk_request_window_start_date(self) -> None: + """ " + The motivation of this test is https://github.com/airbytehq/oncall/issues/6874 + + In this scenario we end having stream_slices method to generate same slice N times. + Our checkpointing logic will trigger when job_checkpoint_interval is passed, but there may be the case that such checkpoint + has the same value as the current slice start date so we would end requesting same job. + + In this test: + 1. First job requires to checkpoint as we pass the 1500 limit, it cancels the bulk job and checkpoints from last cursor value. + 2. Next job just goes "fine". + 3. Now in the third and N job is where the behavior described above occurs, I just set it to happen a fixed N times as the + test depends on we keep feeding responses in the order of status running/canceled, but you can observe the repeated slices in the + logging. + + e.g. + + {"type":"LOG","log":{"level":"INFO","message":"Stream: `metafield_orders` requesting BULK Job for period: 2024-05-02T17:30:00+00:00 -- 2024-05-03T17:30:00+00:00. Slice size: `P1D`. The BULK checkpoint after `15000` lines."}} + ... + {"type":"LOG","log":{"level":"INFO","message":"Stream metafield_orders, continue from checkpoint: `2024-05-02T17:30:00+00:00`."}} + {"type":"LOG","log":{"level":"INFO","message":"Stream: `metafield_orders` requesting BULK Job for period: 2024-05-02T17:30:00+00:00 -- 2024-05-03T17:30:00+00:00. Slice size: `P1D`. The BULK checkpoint after `15000` lines."}} + {"type":"LOG","log":{"level":"INFO","message":"Stream: `metafield_orders`, the BULK Job: `gid://shopify/BulkOperation/4472588009771` is CREATED"}} + ... + """ + + def add_n_records(builder, n, record_date: Optional[str] = None): + for _ in range(n): + builder = builder.with_record(updated_at=record_date) + return builder + + # *************** 1st bulk job *************************** + job_created_at = _INCREMENTAL_JOB_END_DATE - timedelta(minutes=5) + # create a job request + self._http_mocker.post( + create_job_creation_request(_SHOP_NAME, _INCREMENTAL_JOB_START_DATE, _INCREMENTAL_JOB_END_DATE), + JobCreationResponseBuilder(job_created_at=job_created_at.strftime("%Y-%m-%dT%H:%M:%SZ")) + .with_bulk_operation_id(_BULK_OPERATION_ID) + .build(), + ) + # get job status + self._http_mocker.post( + create_job_status_request(_SHOP_NAME, _BULK_OPERATION_ID), + [ + JobStatusResponseBuilder().with_running_status(_BULK_OPERATION_ID, object_count="500").build(), + # this should make the job get canceled as it gets over 15000 rows + JobStatusResponseBuilder().with_running_status(_BULK_OPERATION_ID, object_count="16000").build(), + # this will complete the job + JobStatusResponseBuilder().with_canceled_status(_BULK_OPERATION_ID, _JOB_RESULT_URL, object_count="1700").build(), + ], + ) + # mock the cancel operation request as we passed the 15000 rows + self._http_mocker.post(create_job_cancel_request(_SHOP_NAME, _BULK_OPERATION_ID), [HttpResponse(json.dumps({}), status_code=200)]) + # get results for the request that got cancelled + adjusted_checkpoint_start_date = _INCREMENTAL_JOB_START_DATE - timedelta(days=2, hours=6, minutes=30) + adjusted_record_date = adjusted_checkpoint_start_date.strftime("%Y-%m-%dT%H:%M:%SZ") + self._http_mocker.get( + HttpRequest(_JOB_RESULT_URL), + # MetafieldOrdersJobResponseBuilder().with_record().with_record().build(), + add_n_records(MetafieldOrdersJobResponseBuilder(), 80, adjusted_record_date).build(), + ) + + # *************** 2nd bulk job *************************** + # create a job request for a new job with checkpoint date + # that will be the adjusted_record_date + 1 day + next_bulk_operation_id = "gid://shopify/BulkOperation/4472588009771" + adjusted_checkpoint_end_date = adjusted_checkpoint_start_date + timedelta(days=1) + job_created_at = _INCREMENTAL_JOB_END_DATE - timedelta(minutes=4) + self._http_mocker.post( + # The start date is caused by record date in previous iteration + create_job_creation_request(_SHOP_NAME, adjusted_checkpoint_start_date, adjusted_checkpoint_end_date), + JobCreationResponseBuilder(job_created_at=job_created_at.strftime("%Y-%m-%dT%H:%M:%SZ")) + .with_bulk_operation_id(next_bulk_operation_id) + .build(), + ) + # get job status + next_job_result_url = "https://storage.googleapis.com/shopify-tiers-assets-prod-us-east1/bulk-operation-outputs/l6lersgk4i81iqc3n6iisywwtipb-final?GoogleAccessId=assets-us-prod%40shopify-tiers.iam.gserviceaccount.com&Expires=1715633149&Signature=oMjQelfAzUW%2FdulC3HbuBapbUriUJ%2Bc9%2FKpIIf954VTxBqKChJAdoTmWT9ymh%2FnCiHdM%2BeM%2FADz5siAC%2BXtHBWkJfvs%2F0cYpse0ueiQsw6R8gW5JpeSbizyGWcBBWkv5j8GncAnZOUVYDxRIgfxcPb8BlFxBfC3wsx%2F00v9D6EHbPpkIMTbCOAhheJdw9GmVa%2BOMqHGHlmiADM34RDeBPrvSo65f%2FakpV2LBQTEV%2BhDt0ndaREQ0MrpNwhKnc3vZPzA%2BliOGM0wyiYr9qVwByynHq8c%2FaJPPgI5eGEfQcyepgWZTRW5S0DbmBIFxZJLN6Nq6bJ2bIZWrVriUhNGx2g%3D%3D&response-content-disposition=attachment%3B+filename%3D%22bulk-4476008693950.jsonl%22%3B+filename%2A%3DUTF-8%27%27bulk-4476008693950.jsonl&response-content-type=application%2Fjsonl" + self._http_mocker.post( + create_job_status_request(_SHOP_NAME, next_bulk_operation_id), + [ + # this will output the job is running + JobStatusResponseBuilder().with_completed_status(next_bulk_operation_id, next_job_result_url).build(), + ], + ) + # get results for the request that got cancelled + self._http_mocker.get( + HttpRequest(next_job_result_url), + # MetafieldOrdersJobResponseBuilder().with_record().with_record().build(), + add_n_records(MetafieldOrdersJobResponseBuilder(), 90, adjusted_record_date).build(), + ) + + # *************** 3rd and n+ bulk job *************************** + next_bulk_operation_id = "gid://shopify/BulkOperation/4472588009881" + adjusted_checkpoint_start_date = adjusted_checkpoint_end_date + adjusted_checkpoint_end_date = adjusted_checkpoint_start_date + timedelta(days=1) + job_created_at = _INCREMENTAL_JOB_END_DATE - timedelta(minutes=4) + create_job_request = create_job_creation_request(_SHOP_NAME, adjusted_checkpoint_start_date, adjusted_checkpoint_end_date) + + self._http_mocker.post( + create_job_request, + JobCreationResponseBuilder(job_created_at=job_created_at.strftime("%Y-%m-%dT%H:%M:%SZ")) + .with_bulk_operation_id(next_bulk_operation_id) + .build(), + ) + + base_status_responses = [ + JobStatusResponseBuilder().with_running_status(next_bulk_operation_id, object_count="500").build(), + # this should make the job get canceled as it gets over 15000 rows + JobStatusResponseBuilder().with_running_status(next_bulk_operation_id, object_count="16000").build(), + # this will complete the job + JobStatusResponseBuilder().with_canceled_status(next_bulk_operation_id, next_job_result_url, object_count="1700").build(), + ] + + n_times_to_loop = 4 + responses_in_loop = base_status_responses * n_times_to_loop + # get job status + next_job_result_url = "https://storage.googleapis.com/shopify-tiers-assets-prod-us-east1/bulk-operation-outputs/l6lersgk4i81iqc3n6iisywwtipb-final?GoogleAccessId=assets-us-prod%40shopify-tiers.iam.gserviceaccount.com&Expires=1715633149&Signature=oMjQelfAzUW%2FdulC3HbuBapbUriUJ%2Bc9%2FKpIIf954VTxBqKChJAdoTmWT9ymh%2FnCiHdM%2BeM%2FADz5siAC%2BXtHBWkJfvs%2F0cYpse0ueiQsw6R8gW5JpeSbizyGWcBBWkv5j8GncAnZOUVYDxRIgfxcPb8BlFxBfC3wsx%2F00v9D6EHbPpkIMTbCOAhheJdw9GmVa%2BOMqHGHlmiADM34RDeBPrvSo65f%2FakpV2LBQTEV%2BhDt0ndaREQ0MrpNwhKnc3vZPzA%2BliOGM0wyiYr9qVwByynHq8c%2FaJPPgI5eGEfQcyepgWZTRW5S0DbmBIFxZJLN6Nq6bJ2bIZWrVriUhNGx2g%3D%3D&response-content-disposition=attachment%3B+filename%3D%22bulk-4476008693960.jsonl%22%3B+filename%2A%3DUTF-8%27%27bulk-4476008693960.jsonl&response-content-type=application%2Fjsonl" + + self._http_mocker.post(create_job_status_request(_SHOP_NAME, next_bulk_operation_id), responses_in_loop) + + # mock the cancel operation request as we passed the 15000 rows + self._http_mocker.post( + create_job_cancel_request(_SHOP_NAME, next_bulk_operation_id), [HttpResponse(json.dumps({}), status_code=200)] + ) + + # get results + adjusted_record_date = adjusted_checkpoint_start_date.strftime("%Y-%m-%dT%H:%M:%SZ") + self._http_mocker.get( + HttpRequest(next_job_result_url), + add_n_records(MetafieldOrdersJobResponseBuilder(), 80, adjusted_record_date).build(), + ) + + # ********* end of request mocking ************* + + metafield_orders_orders_state = { + "orders": {"updated_at": _INCREMENTAL_JOB_START_DATE_ISO, "deleted": {"deleted_at": ""}}, + "updated_at": _INCREMENTAL_JOB_START_DATE_ISO, + } + stream_state = StateBuilder().with_stream_state(_BULK_STREAM, metafield_orders_orders_state).build() + + # we are passing to config a start date let's set something "old" as happen in many sources like 2 years ago + config_start_date = _INCREMENTAL_JOB_START_DATE - timedelta(weeks=104) + output = self._read( + _get_config(config_start_date, job_checkpoint_interval=15000), sync_mode=SyncMode.incremental, state=stream_state + ) + + expected_error_message = "The stream: `metafield_orders` checkpoint collision is detected." + result = output.errors[0].trace.error.internal_message + + # The result of the test should be the `ShopifyBulkExceptions.BulkJobCheckpointCollisionError` + assert result is not None and expected_error_message in result + + def _read(self, config, sync_mode=SyncMode.full_refresh, state: Optional[List[AirbyteStateMessage]] = None): + catalog = CatalogBuilder().with_stream(_BULK_STREAM, sync_mode).build() + output = read(SourceShopify(), config, catalog, state=state) + return output diff --git a/airbyte-integrations/connectors/source-shopify/unit_tests/test_auth.py b/airbyte-integrations/connectors/source-shopify/unit_tests/test_auth.py index ee1ae56a74a1..932fc7a33fa7 100644 --- a/airbyte-integrations/connectors/source-shopify/unit_tests/test_auth.py +++ b/airbyte-integrations/connectors/source-shopify/unit_tests/test_auth.py @@ -7,6 +7,7 @@ from source_shopify.auth import NotImplementedAuth, ShopifyAuthenticator from source_shopify.source import ConnectionCheckTest + TEST_ACCESS_TOKEN = "test_access_token" TEST_API_PASSWORD = "test_api_password" diff --git a/airbyte-integrations/connectors/source-shopify/unit_tests/test_cached_stream_state.py b/airbyte-integrations/connectors/source-shopify/unit_tests/test_cached_stream_state.py index 80cc6115c449..718ebb2537c2 100644 --- a/airbyte-integrations/connectors/source-shopify/unit_tests/test_cached_stream_state.py +++ b/airbyte-integrations/connectors/source-shopify/unit_tests/test_cached_stream_state.py @@ -7,6 +7,7 @@ from source_shopify.streams.streams import OrderRefunds, Orders from source_shopify.utils import EagerlyCachedStreamState as stream_state_cache + # Define the Stream instances for the tests SHOPIFY_STREAM = Orders(config={"authenticator": None}) SHOPIFY_SUB_STREAM = OrderRefunds(config={"authenticator": None}) diff --git a/airbyte-integrations/connectors/source-shopify/unit_tests/test_control_rate_limit.py b/airbyte-integrations/connectors/source-shopify/unit_tests/test_control_rate_limit.py index 49850a1ef8a1..daedb2a89a9d 100644 --- a/airbyte-integrations/connectors/source-shopify/unit_tests/test_control_rate_limit.py +++ b/airbyte-integrations/connectors/source-shopify/unit_tests/test_control_rate_limit.py @@ -6,6 +6,7 @@ import requests from source_shopify.utils import ShopifyRateLimiter as limiter + TEST_DATA_FIELD = "some_data_field" TEST_RATE_LIMIT_HEADER = "X-Shopify-Shop-Api-Call-Limit" TEST_THRESHOLD = 0.9 diff --git a/airbyte-integrations/connectors/source-shopify/unit_tests/test_deleted_events_stream.py b/airbyte-integrations/connectors/source-shopify/unit_tests/test_deleted_events_stream.py index 3d599ce770b1..ea902f0be567 100644 --- a/airbyte-integrations/connectors/source-shopify/unit_tests/test_deleted_events_stream.py +++ b/airbyte-integrations/connectors/source-shopify/unit_tests/test_deleted_events_stream.py @@ -108,7 +108,9 @@ def test_read_deleted_records(stream, requests_mock, deleted_records_json, expec stream = stream(config) deleted_records_url = stream.url_base + stream.deleted_events.path() requests_mock.get(deleted_records_url, json=deleted_records_json) - mocker.patch("source_shopify.streams.base_streams.IncrementalShopifyStreamWithDeletedEvents.read_records", return_value=deleted_records_json) + mocker.patch( + "source_shopify.streams.base_streams.IncrementalShopifyStreamWithDeletedEvents.read_records", return_value=deleted_records_json + ) assert list(stream.read_records(sync_mode=None)) == expected diff --git a/airbyte-integrations/connectors/source-shopify/unit_tests/test_graphql_products.py b/airbyte-integrations/connectors/source-shopify/unit_tests/test_graphql_products.py index a6c99f9c3c44..285b816734ed 100644 --- a/airbyte-integrations/connectors/source-shopify/unit_tests/test_graphql_products.py +++ b/airbyte-integrations/connectors/source-shopify/unit_tests/test_graphql_products.py @@ -7,10 +7,25 @@ @pytest.mark.parametrize( "page_size, filter_value, next_page_token, expected_query", [ - (100, None, None, 'query {\n products(first: 100, query: null, after: null) {\n nodes {\n id\n title\n updatedAt\n createdAt\n publishedAt\n status\n vendor\n productType\n tags\n options {\n id\n name\n position\n values\n }\n handle\n description\n tracksInventory\n totalInventory\n totalVariants\n onlineStoreUrl\n onlineStorePreviewUrl\n descriptionHtml\n isGiftCard\n legacyResourceId\n mediaCount\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}'), - (200, "2027-07-11T13:07:45-07:00", None, 'query {\n products(first: 200, query: "updated_at:>\'2027-07-11T13:07:45-07:00\'", after: null) {\n nodes {\n id\n title\n updatedAt\n createdAt\n publishedAt\n status\n vendor\n productType\n tags\n options {\n id\n name\n position\n values\n }\n handle\n description\n tracksInventory\n totalInventory\n totalVariants\n onlineStoreUrl\n onlineStorePreviewUrl\n descriptionHtml\n isGiftCard\n legacyResourceId\n mediaCount\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}'), - (250, "2027-07-11T13:07:45-07:00", "end_cursor_value", 'query {\n products(first: 250, query: "updated_at:>\'2027-07-11T13:07:45-07:00\'", after: "end_cursor_value") {\n nodes {\n id\n title\n updatedAt\n createdAt\n publishedAt\n status\n vendor\n productType\n tags\n options {\n id\n name\n position\n values\n }\n handle\n description\n tracksInventory\n totalInventory\n totalVariants\n onlineStoreUrl\n onlineStorePreviewUrl\n descriptionHtml\n isGiftCard\n legacyResourceId\n mediaCount\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}'), + ( + 100, + None, + None, + "query {\n products(first: 100, query: null, after: null) {\n nodes {\n id\n title\n updatedAt\n createdAt\n publishedAt\n status\n vendor\n productType\n tags\n options {\n id\n name\n position\n values\n }\n handle\n description\n tracksInventory\n totalInventory\n totalVariants\n onlineStoreUrl\n onlineStorePreviewUrl\n descriptionHtml\n isGiftCard\n legacyResourceId\n mediaCount\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}", + ), + ( + 200, + "2027-07-11T13:07:45-07:00", + None, + "query {\n products(first: 200, query: \"updated_at:>'2027-07-11T13:07:45-07:00'\", after: null) {\n nodes {\n id\n title\n updatedAt\n createdAt\n publishedAt\n status\n vendor\n productType\n tags\n options {\n id\n name\n position\n values\n }\n handle\n description\n tracksInventory\n totalInventory\n totalVariants\n onlineStoreUrl\n onlineStorePreviewUrl\n descriptionHtml\n isGiftCard\n legacyResourceId\n mediaCount\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}", + ), + ( + 250, + "2027-07-11T13:07:45-07:00", + "end_cursor_value", + 'query {\n products(first: 250, query: "updated_at:>\'2027-07-11T13:07:45-07:00\'", after: "end_cursor_value") {\n nodes {\n id\n title\n updatedAt\n createdAt\n publishedAt\n status\n vendor\n productType\n tags\n options {\n id\n name\n position\n values\n }\n handle\n description\n tracksInventory\n totalInventory\n totalVariants\n onlineStoreUrl\n onlineStorePreviewUrl\n descriptionHtml\n isGiftCard\n legacyResourceId\n mediaCount\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}', + ), ], ) def test_get_query_products(page_size, filter_value, next_page_token, expected_query): - assert get_query_products(page_size, 'updatedAt', filter_value, next_page_token) == expected_query + assert get_query_products(page_size, "updatedAt", filter_value, next_page_token) == expected_query diff --git a/airbyte-integrations/connectors/source-shopify/unit_tests/test_migrations/test_config_migrations.py b/airbyte-integrations/connectors/source-shopify/unit_tests/test_migrations/test_config_migrations.py index de54e242294a..c90b81052dda 100644 --- a/airbyte-integrations/connectors/source-shopify/unit_tests/test_migrations/test_config_migrations.py +++ b/airbyte-integrations/connectors/source-shopify/unit_tests/test_migrations/test_config_migrations.py @@ -6,11 +6,13 @@ import json from typing import Any, Mapping -from airbyte_cdk.models import OrchestratorType, Type -from airbyte_cdk.sources import Source from source_shopify.config_migrations import MigrateConfig from source_shopify.source import SourceShopify +from airbyte_cdk.models import OrchestratorType, Type +from airbyte_cdk.sources import Source + + # BASE ARGS CMD = "check" TEST_CONFIG_PATH = "unit_tests/test_migrations/test_config.json" diff --git a/airbyte-integrations/connectors/source-shopify/unit_tests/test_source.py b/airbyte-integrations/connectors/source-shopify/unit_tests/test_source.py index f9ef2ba2f7ca..797be1e385f4 100644 --- a/airbyte-integrations/connectors/source-shopify/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-shopify/unit_tests/test_source.py @@ -7,7 +7,6 @@ from unittest.mock import MagicMock, patch import pytest -from airbyte_cdk.utils import AirbyteTracedException from source_shopify.auth import ShopifyAuthenticator from source_shopify.source import ConnectionCheckTest, SourceShopify from source_shopify.streams.streams import ( @@ -49,6 +48,8 @@ TransactionsGraphql, ) +from airbyte_cdk.utils import AirbyteTracedException + from .conftest import records_per_slice @@ -126,13 +127,13 @@ def test_path_with_stream_slice_param(stream, stream_slice, expected_path, confi else: result = stream.path() assert result == expected_path - - + + @pytest.mark.parametrize( "stream, parent_records, state_checkpoint_interval", [ ( - OrderRefunds, + OrderRefunds, [ {"id": 1, "refunds": [{"created_at": "2021-01-01T00:00:00+00:00"}]}, {"id": 2, "refunds": [{"created_at": "2021-02-01T00:00:00+00:00"}]}, @@ -145,10 +146,10 @@ def test_path_with_stream_slice_param(stream, stream_slice, expected_path, confi ], ) def test_stream_slice_nested_substream_buffering( - mocker, - config, - stream, - parent_records, + mocker, + config, + stream, + parent_records, state_checkpoint_interval, ) -> None: # making the stream instance @@ -156,7 +157,7 @@ def test_stream_slice_nested_substream_buffering( stream.state_checkpoint_interval = state_checkpoint_interval # simulating `read_records` for the `parent_stream` mocker.patch( - "source_shopify.streams.base_streams.IncrementalShopifyStreamWithDeletedEvents.read_records", + "source_shopify.streams.base_streams.IncrementalShopifyStreamWithDeletedEvents.read_records", return_value=parent_records, ) # count how many slices we expect, based on the number of parent_records @@ -173,7 +174,7 @@ def test_stream_slice_nested_substream_buffering( # count total slices total_slices += 1 # check we have emitted complete number of slices - assert total_slices == total_slices_expected + assert total_slices == total_slices_expected def test_check_connection(config, mocker) -> None: @@ -212,11 +213,23 @@ def test_request_params(config, stream, expected) -> None: "last_record, current_state, expected", [ # no init state - ({"created_at": "2022-10-10T06:21:53-07:00"}, {}, {"created_at": "2022-10-10T06:21:53-07:00", "orders": {"updated_at": "", "deleted": {"deleted_at": ""}}}), + ( + {"created_at": "2022-10-10T06:21:53-07:00"}, + {}, + {"created_at": "2022-10-10T06:21:53-07:00", "orders": {"updated_at": "", "deleted": {"deleted_at": ""}}}, + ), # state is empty str - ({"created_at": "2022-10-10T06:21:53-07:00"}, {"created_at": ""}, {"created_at": "2022-10-10T06:21:53-07:00", "orders": {"updated_at": "", "deleted": {"deleted_at": ""}}}), + ( + {"created_at": "2022-10-10T06:21:53-07:00"}, + {"created_at": ""}, + {"created_at": "2022-10-10T06:21:53-07:00", "orders": {"updated_at": "", "deleted": {"deleted_at": ""}}}, + ), # state is None - ({"created_at": "2022-10-10T06:21:53-07:00"}, {"created_at": None}, {"created_at": "2022-10-10T06:21:53-07:00", "orders": {"updated_at": "", "deleted": {"deleted_at": ""}}}), + ( + {"created_at": "2022-10-10T06:21:53-07:00"}, + {"created_at": None}, + {"created_at": "2022-10-10T06:21:53-07:00", "orders": {"updated_at": "", "deleted": {"deleted_at": ""}}}, + ), # last rec cursor is None ({"created_at": None}, {"created_at": None}, {"created_at": "", "orders": {"updated_at": "", "deleted": {"deleted_at": ""}}}), # last rec cursor is empty str @@ -257,21 +270,19 @@ def test_get_shop_name(config, shop, expected) -> None: actual = source.get_shop_name(config) assert actual == expected + @pytest.mark.parametrize( "config, expected_stream_class", [ ({"fetch_transactions_user_id": False}, TransactionsGraphql), ({"fetch_transactions_user_id": True}, Transactions), ({}, TransactionsGraphql), - ], + ], ids=["don't fetch user_id", "fetch user id", "unset config value shouldn't fetch user_id"], ) def test_select_transactions_stream(config, expected_stream_class): config["shop"] = "test-store" - config["credentials"] = { - "auth_method": "api_password", - "api_password": "shppa_123" - } + config["credentials"] = {"auth_method": "api_password", "api_password": "shppa_123"} config["authenticator"] = ShopifyAuthenticator(config) source = SourceShopify() @@ -284,7 +295,7 @@ def test_select_transactions_stream(config, expected_stream_class): [ pytest.param([{"id": "12345"}], "12345", None, id="test_shop_name_exists"), pytest.param([], None, AirbyteTracedException, id="test_shop_name_does_not_exist"), - ], + ], ) def test_get_shop_id(config, read_records, expected_shop_id, expected_error): check_test = ConnectionCheckTest(config) diff --git a/airbyte-integrations/connectors/source-shopify/unit_tests/unit_test.py b/airbyte-integrations/connectors/source-shopify/unit_tests/unit_test.py index ca9e306e6698..649e409e7056 100644 --- a/airbyte-integrations/connectors/source-shopify/unit_tests/unit_test.py +++ b/airbyte-integrations/connectors/source-shopify/unit_tests/unit_test.py @@ -100,8 +100,9 @@ def test_privileges_validation(requests_mock, fetch_transactions_user_id, basic_ "Internal Server Error for slice (500)", ], ) -def test_unavailable_stream(requests_mock, auth_config, stream, slice: Optional[Mapping[str, Any]], status_code: int, - json_response: Mapping[str, Any]): +def test_unavailable_stream( + requests_mock, auth_config, stream, slice: Optional[Mapping[str, Any]], status_code: int, json_response: Mapping[str, Any] +): stream = stream(auth_config) url = stream.url_base + stream.path(stream_slice=slice) requests_mock.get(url=url, json=json_response, status_code=status_code) diff --git a/airbyte-integrations/connectors/source-shortcut/metadata.yaml b/airbyte-integrations/connectors/source-shortcut/metadata.yaml index 4ea80c92bf5f..12d8f78a6b35 100644 --- a/airbyte-integrations/connectors/source-shortcut/metadata.yaml +++ b/airbyte-integrations/connectors/source-shortcut/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-shortcut connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.6.2@sha256:f5fcd3d4703b7590b6166a7853c5ed1686731607cd30a159a8c24e2fe2c1ee98 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 72b4b6ad-bf46-4113-a97e-c8e2666f7230 - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-shortcut githubIssueLabel: source-shortcut icon: icon.svg diff --git a/airbyte-integrations/connectors/source-shortio/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-shortio/integration_tests/acceptance.py index d49b55882333..a9256a533972 100644 --- a/airbyte-integrations/connectors/source-shortio/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-shortio/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-shortio/metadata.yaml b/airbyte-integrations/connectors/source-shortio/metadata.yaml index e33a1802934d..b1f1eb3df6ef 100644 --- a/airbyte-integrations/connectors/source-shortio/metadata.yaml +++ b/airbyte-integrations/connectors/source-shortio/metadata.yaml @@ -4,7 +4,7 @@ data: - https://api.short.io - https://api-v2.short.cm connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc remoteRegistries: pypi: enabled: false @@ -17,7 +17,7 @@ data: connectorSubtype: api connectorType: source definitionId: 2fed2292-5586-480c-af92-9944e39fe12d - dockerImageTag: 0.3.3 + dockerImageTag: 0.3.8 dockerRepository: airbyte/source-shortio githubIssueLabel: source-shortio icon: shortio.svg diff --git a/airbyte-integrations/connectors/source-sigma-computing/metadata.yaml b/airbyte-integrations/connectors/source-sigma-computing/metadata.yaml index 4434a1c6d40f..9f3e8ef89cb4 100644 --- a/airbyte-integrations/connectors/source-sigma-computing/metadata.yaml +++ b/airbyte-integrations/connectors/source-sigma-computing/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-sigma-computing connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 40fed53b-3a55-4ce3-a25f-93af5b5379b0 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-sigma-computing githubIssueLabel: source-sigma-computing icon: icon.svg diff --git a/airbyte-integrations/connectors/source-simfin/README.md b/airbyte-integrations/connectors/source-simfin/README.md new file mode 100644 index 000000000000..ecebcf52b60f --- /dev/null +++ b/airbyte-integrations/connectors/source-simfin/README.md @@ -0,0 +1,35 @@ +# SimFin +This directory contains the manifest-only connector for `source-simfin`. + +Simfin provides financial data . +With this connector we can extract data from price data , financial statements and company info streams . +Docs https://simfin.readme.io/reference/getting-started-1 + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-simfin:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-simfin build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-simfin test +``` + diff --git a/airbyte-integrations/connectors/source-simfin/acceptance-test-config.yml b/airbyte-integrations/connectors/source-simfin/acceptance-test-config.yml new file mode 100644 index 000000000000..42ac2a90c655 --- /dev/null +++ b/airbyte-integrations/connectors/source-simfin/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-simfin:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-simfin/icon.svg b/airbyte-integrations/connectors/source-simfin/icon.svg new file mode 100644 index 000000000000..5b4c460322cb --- /dev/null +++ b/airbyte-integrations/connectors/source-simfin/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-simfin/manifest.yaml b/airbyte-integrations/connectors/source-simfin/manifest.yaml new file mode 100644 index 000000000000..bc3052e21f5f --- /dev/null +++ b/airbyte-integrations/connectors/source-simfin/manifest.yaml @@ -0,0 +1,1340 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + Simfin provides financial data . + + With this connector we can extract data from price data , financial statements + and company info streams . + + Docs https://simfin.readme.io/reference/getting-started-1 + +check: + type: CheckStream + stream_names: + - "Company Info " + +definitions: + streams: + "Company Info ": + type: DeclarativeStream + name: "Company Info " + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: companies/general/verbose + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/Company Info " + Financial Statements: + type: DeclarativeStream + name: Financial Statements + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: companies/statements/verbose + http_method: GET + request_parameters: + id: "{{ stream_partition.id }}" + statements: pl,bs,cf,derived + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - statements + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: id + stream: + $ref: "#/definitions/streams/Company Info " + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/Financial Statements" + Price Data: + type: DeclarativeStream + name: Price Data + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: companies/prices/verbose + http_method: GET + request_parameters: + id: "{{ stream_partition.id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: id + stream: + $ref: "#/definitions/streams/Company Info " + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/Price Data" + companies: + type: DeclarativeStream + name: companies + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: companies/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/companies" + common_shares_outstanding: + type: DeclarativeStream + name: common_shares_outstanding + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: companies/common-shares-outstanding + http_method: GET + request_parameters: + id: "{{ stream_partition.id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: id + stream: + $ref: "#/definitions/streams/companies" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/common_shares_outstanding" + weighted_shares_outstanding: + type: DeclarativeStream + name: weighted_shares_outstanding + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: companies/weighted-shares-outstanding + http_method: GET + request_parameters: + id: "{{ stream_partition.id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: id + stream: + $ref: "#/definitions/streams/companies" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/weighted_shares_outstanding" + filings_by_company: + type: DeclarativeStream + name: filings_by_company + primary_key: + - filingIdentifier + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: filings/by-company + http_method: GET + request_parameters: + id: "{{ stream_partition.id }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: id + stream: + $ref: "#/definitions/streams/companies" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/filings_by_company" + filings_list: + type: DeclarativeStream + name: filings_list + primary_key: + - filingIdentifier + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: filings/list + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - contents + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: per-page + pagination_strategy: + type: PageIncrement + start_from_page: 0 + page_size: 1000 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/filings_list" + base_requester: + type: HttpRequester + url_base: https://backend.simfin.com/api/v3/ + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: Authorization + inject_into: header + +streams: + - $ref: "#/definitions/streams/Company Info " + - $ref: "#/definitions/streams/Financial Statements" + - $ref: "#/definitions/streams/Price Data" + - $ref: "#/definitions/streams/companies" + - $ref: "#/definitions/streams/common_shares_outstanding" + - $ref: "#/definitions/streams/weighted_shares_outstanding" + - $ref: "#/definitions/streams/filings_by_company" + - $ref: "#/definitions/streams/filings_list" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + order: 0 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + "Company Info ": true + Financial Statements: true + Price Data: true + companies: true + common_shares_outstanding: true + weighted_shares_outstanding: true + filings_by_company: true + filings_list: true + testedStreams: + "Company Info ": + hasRecords: true + streamHash: 9e726c6019d4e63cb31fbfe032148c1fc2c10686 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + Financial Statements: + hasRecords: true + streamHash: 357824c43d7efbc949979761302521bde147930e + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + Price Data: + hasRecords: true + streamHash: 71296e2297941f727e87526862586d1ebcdf86fd + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + companies: + streamHash: 20ea91a757a266dd3d6d43000d3d2f20aa9a39ed + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + common_shares_outstanding: + streamHash: 2ad66097feb064e4b52190d057083a791a238a20 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + weighted_shares_outstanding: + streamHash: e5dc0ebf850f05a23a3d4557f6a5c00fd976125d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + filings_by_company: + streamHash: 3478504d337269c01e6ebdf9c2902849216949f5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + filings_list: + streamHash: 42b5d87568d79b3a55a518f9e3ed0997405bd482 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + "Company Info ": + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + companyDescription: + type: + - string + - "null" + endFy: + type: + - number + - "null" + id: + type: number + industryName: + type: + - string + - "null" + isin: + type: + - string + - "null" + market: + type: + - string + - "null" + name: + type: + - string + - "null" + numEmployees: + type: + - number + - "null" + sectorCode: + type: + - number + - "null" + sectorName: + type: + - string + - "null" + ticker: + type: + - string + - "null" + required: + - id + Financial Statements: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + checks: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + dataModel: + type: + - number + - "null" + includedInBulkDownload: + type: + - boolean + - "null" + valueCheck: + type: + - boolean + - "null" + data: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + Abnormal Gains (Losses): + type: + - number + - "null" + Accounts & Notes Receivable: + type: + - number + - "null" + Accounts Payable: + type: + - number + - "null" + Accounts Receivable, Net: + type: + - number + - "null" + Accrued Taxes: + type: + - number + - "null" + Acquisition of Fixed Assets & Intangibles: + type: + - number + - "null" + Additional Paid in Capital: + type: + - number + - "null" + Cash & Cash Equivalents: + type: + - number + - "null" + Cash From (Repayment of) Debt: + type: + - number + - "null" + Cash From (Repurchase of) Equity: + type: + - number + - "null" + Cash Return On Invested Capital: + type: + - number + - "null" + Cash from Financing Activities: + type: + - number + - "null" + Cash from Investing Activities: + type: + - number + - "null" + Cash from Operating Activities: + type: + - number + - "null" + Cash, Cash Equivalents & Short Term Investments: + type: + - number + - "null" + Change in Fixed Assets & Intangibles: + type: + - number + - "null" + Change in Working Capital: + type: + - number + - "null" + Commissions & Fees Earned: + type: + - number + - "null" + Commissions & Fees Paid: + type: + - number + - "null" + Common Stock: + type: + - number + - "null" + Cost of revenue: + type: + - number + - "null" + Current Ratio: + type: + - number + - "null" + Customer Acceptances & Liabilities: + type: + - number + - "null" + Data Model: + type: + - number + - "null" + Debt Ratio: + type: + - number + - "null" + Deferred Revenue (Long Term): + type: + - number + - "null" + Deferred Revenue (Short Term): + type: + - number + - "null" + Deferred Tax Assets (Long Term): + type: + - number + - "null" + Deferred Tax Assets (Short Term): + type: + - number + - "null" + Deferred Tax Liabilities (Long Term): + type: + - number + - "null" + Deferred Tax Liabilities (Short Term): + type: + - number + - "null" + Depreciation & Amortization: + type: + - number + - "null" + Derivative & Hedging Assets (Short Term): + type: + - number + - "null" + Dividend Payout Ratio: + type: + - number + - "null" + Dividends Paid: + type: + - number + - "null" + Dividends Per Share: + type: + - number + - "null" + EBITDA: + type: + - number + - "null" + Earnings Per Share, Basic: + type: + - number + - "null" + Earnings Per Share, Diluted: + type: + - number + - "null" + Effect of Foreign Exchange Rates: + type: + - number + - "null" + Equity Before Minority Interest: + type: + - number + - "null" + Equity Per Share: + type: + - number + - "null" + Fiscal Period: + type: + - string + - "null" + Fiscal Year: + type: + - number + - "null" + Foreign Exchange Gain (Loss): + type: + - number + - "null" + Free Cash Flow: + type: + - number + - "null" + Free Cash Flow Per Share: + type: + - number + - "null" + Free Cash Flow to Net Income: + type: + - number + - "null" + Free Cash Flow to Net Income (Adjusted): + type: + - number + - "null" + General & Administrative: + type: + - number + - "null" + Goodwill: + type: + - number + - "null" + Gross Profit: + type: + - number + - "null" + Gross Profit Margin: + type: + - number + - "null" + Income (Loss) Including Minority Interest: + type: + - number + - "null" + Income (Loss) from Continuing Operations: + type: + - number + - "null" + Income Tax (Expense) Benefit, net: + type: + - number + - "null" + Income Taxes Receivable: + type: + - number + - "null" + Increase in Capital Stock: + type: + - number + - "null" + Intangible Assets: + type: + - number + - "null" + Interest Expense, net: + type: + - number + - "null" + Interest Income: + type: + - number + - "null" + Investment Income (Loss): + type: + - number + - "null" + Liabilities from Derivatives & Hedging (Short Term): + type: + - number + - "null" + Liabilities to Equity Ratio: + type: + - number + - "null" + Long Term Capital Leases: + type: + - number + - "null" + Long Term Debt: + type: + - number + - "null" + Long Term Investments & Receivables: + type: + - number + - "null" + Minority Interest: + type: + - number + - "null" + Miscellaneous Long Term Assets: + type: + - number + - "null" + Miscellaneous Long Term Liabilities: + type: + - number + - "null" + Miscellaneous Short Term Assets: + type: + - number + - "null" + Miscellaneous Short Term Liabilities: + type: + - number + - "null" + Net Cash Before Disc. Operations and FX: + type: + - number + - "null" + Net Cash Before FX: + type: + - number + - "null" + Net Cash From Acquisitions & Divestitures: + type: + - number + - "null" + Net Cash From Discontinued Operations (financing): + type: + - number + - "null" + Net Change In Deposits: + type: + - number + - "null" + Net Change in Investments: + type: + - number + - "null" + Net Change in Loans & Interbank: + type: + - number + - "null" + Net Change in Long Term Investment: + type: + - number + - "null" + Net Change in Operating Capital: + type: + - number + - "null" + Net Changes in Cash: + type: + - number + - "null" + Net Debt / EBIT: + type: + - number + - "null" + Net Debt / EBITDA: + type: + - number + - "null" + Net Fixed Assets: + type: + - number + - "null" + Net Income: + type: + - number + - "null" + Net Income (Adjusted): + type: + - number + - "null" + Net Income Available to Common Shareholders: + type: + - number + - "null" + Net Income/Starting Line: + type: + - number + - "null" + Net Loans: + type: + - number + - "null" + Net Profit Margin: + type: + - number + - "null" + Net Profit Margin (Adjusted): + type: + - number + - "null" + Net Revenue: + type: + - number + - "null" + Net Revenue after Provisions: + type: + - number + - "null" + Net interest income: + type: + - number + - "null" + Non-Cash Items: + type: + - number + - "null" + Non-Operating Income (Loss): + type: + - number + - "null" + Operating Expenses: + type: + - number + - "null" + Operating Income (Loss): + type: + - number + - "null" + Operating Margin: + type: + - number + - "null" + Other Assets: + type: + - number + - "null" + Other Equity: + type: + - number + - "null" + Other Financing Activities: + type: + - number + - "null" + Other Investing Activities: + type: + - number + - "null" + Other Liabilities: + type: + - number + - "null" + Other Long Term Assets: + type: + - number + - "null" + Other Long Term Liabilities: + type: + - number + - "null" + Other Non-Cash Adjustments: + type: + - number + - "null" + Other Non-Interest Income: + type: + - number + - "null" + Other Non-Operating Income (Loss): + type: + - number + - "null" + Other Operating Expense: + type: + - number + - "null" + Other Payables & Accruals: + type: + - number + - "null" + Other Short Term Assets: + type: + - number + - "null" + Other Short Term Liabilities: + type: + - number + - "null" + Payables & Accruals: + type: + - number + - "null" + Pension Liabilities: + type: + - number + - "null" + Preferred Dividends: + type: + - number + - "null" + Prepaid Expenses: + type: + - number + - "null" + Pretax Income (Loss): + type: + - number + - "null" + Pretax Income (Loss), Adjusted: + type: + - number + - "null" + Property, Plant & Equipment: + type: + - number + - "null" + Property, Plant & Equipment, Net: + type: + - number + - "null" + Provision for Loan Losses: + type: + - number + - "null" + Publish Date: + type: + - string + - "null" + Repayments of Long Term Debt: + type: + - number + - "null" + Report Date: + type: + - string + - "null" + Research & Development: + type: + - number + - "null" + Reserve for Loan Losses: + type: + - number + - "null" + Restated: + type: + - number + - "null" + Retained Earnings: + type: + - number + - "null" + Return On Invested Capital: + type: + - number + - "null" + Return On Invested Capital (Adjusted): + type: + - number + - "null" + Return on Assets: + type: + - number + - "null" + Return on Assets (Adjusted): + type: + - number + - "null" + Return on Equity: + type: + - number + - "null" + Return on Equity (Adjusted): + type: + - number + - "null" + Revenue: + type: + - number + - "null" + Sales Per Share: + type: + - number + - "null" + Selling & Marketing: + type: + - number + - "null" + Selling, General & Administrative: + type: + - number + - "null" + Share Capital & Additional Paid-In Capital: + type: + - number + - "null" + Short Term Borrowings & Repos: + type: + - number + - "null" + Short Term Capital Leases: + type: + - number + - "null" + Short Term Debt: + type: + - number + - "null" + Short Term Investments: + type: + - number + - "null" + Short and Long Term Investments: + type: + - number + - "null" + Source: + type: + - string + - "null" + Stock-Based Compensation: + type: + - number + - "null" + TTM: + type: + - number + - "null" + Total Assets: + type: + - number + - "null" + Total Current Assets: + type: + - number + - "null" + Total Current Liabilities: + type: + - number + - "null" + Total Debt: + type: + - number + - "null" + Total Deposits: + type: + - number + - "null" + Total Equity: + type: + - number + - "null" + Total Interest Expense: + type: + - number + - "null" + Total Interest Income: + type: + - number + - "null" + Total Liabilities: + type: + - number + - "null" + Total Liabilities & Equity: + type: + - number + - "null" + Total Loans: + type: + - number + - "null" + Total Non-Interest Expense: + type: + - number + - "null" + Total Non-Interest Income: + type: + - number + - "null" + Total Noncurrent Assets: + type: + - number + - "null" + Total Noncurrent Liabilities: + type: + - number + - "null" + Treasury Stock: + type: + - number + - "null" + Value Check: + type: + - number + - "null" + statement: + type: + - string + - "null" + Price Data: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Adjusted Closing Price: + type: + - number + - "null" + Common Shares Outstanding: + type: + - number + - "null" + Date: + type: + - string + - "null" + Dividend Paid: + type: + - number + - "null" + Highest Price: + type: + - number + - "null" + Last Closing Price: + type: + - number + - "null" + Lowest Price: + type: + - number + - "null" + Opening Price: + type: + - number + - "null" + Trading Volume: + type: + - number + - "null" + companies: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: + - number + - "null" + industryName: + type: + - string + - "null" + isin: + type: + - string + - "null" + name: + type: + - string + - "null" + sectorCode: + type: + - number + - "null" + sectorName: + type: + - string + - "null" + ticker: + type: + - string + - "null" + common_shares_outstanding: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + endDate: + type: + - string + - "null" + pid: + type: + - number + - "null" + value: + type: + - number + - "null" + weighted_shares_outstanding: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + basic: + type: + - number + - "null" + diluted: + type: + - number + - "null" + endDate: + type: + - string + - "null" + fyear: + type: + - number + - "null" + period: + type: + - string + - "null" + pid: + type: + - number + - "null" + filings_by_company: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + company: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + industryName: + type: + - string + - "null" + isin: + type: + - string + - "null" + name: + type: + - string + - "null" + sectorCode: + type: + - number + - "null" + sectorName: + type: + - string + - "null" + ticker: + type: + - string + - "null" + filingDate: + type: + - string + - "null" + filingIdentifier: + type: string + filingType: + type: + - string + - "null" + fyear: + type: + - number + - "null" + period: + type: + - string + - "null" + sourceLink: + type: + - string + - "null" + required: + - filingIdentifier + filings_list: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + company: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + industryName: + type: + - string + - "null" + isin: + type: + - string + - "null" + name: + type: + - string + - "null" + sectorCode: + type: + - number + - "null" + sectorName: + type: + - string + - "null" + ticker: + type: + - string + - "null" + filingDate: + type: + - string + - "null" + filingIdentifier: + type: string + filingType: + type: + - string + - "null" + fyear: + type: + - number + - "null" + period: + type: + - string + - "null" + sourceLink: + type: + - string + - "null" + required: + - filingIdentifier diff --git a/airbyte-integrations/connectors/source-simfin/metadata.yaml b/airbyte-integrations/connectors/source-simfin/metadata.yaml new file mode 100644 index 000000000000..91d90db05b24 --- /dev/null +++ b/airbyte-integrations/connectors/source-simfin/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "backend.simfin.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-simfin + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: f00b4899-1154-477e-8508-3d7f33ffb28c + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-simfin + githubIssueLabel: source-simfin + icon: icon.svg + license: MIT + name: SimFin + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/simfin + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-simplecast/metadata.yaml b/airbyte-integrations/connectors/source-simplecast/metadata.yaml index 7e002aceb295..96698ef2ccf4 100644 --- a/airbyte-integrations/connectors/source-simplecast/metadata.yaml +++ b/airbyte-integrations/connectors/source-simplecast/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-simplecast connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 776ca64c-95eb-47ec-a54d-9db3d16435d0 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-simplecast githubIssueLabel: source-simplecast icon: icon.svg diff --git a/airbyte-integrations/connectors/source-simplesat/metadata.yaml b/airbyte-integrations/connectors/source-simplesat/metadata.yaml index cef43a159af0..13a8adc84eeb 100644 --- a/airbyte-integrations/connectors/source-simplesat/metadata.yaml +++ b/airbyte-integrations/connectors/source-simplesat/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-simplesat connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: c2dd8b7e-3e5b-45cb-9522-3d3025ac5796 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-simplesat githubIssueLabel: source-simplesat icon: icon.svg diff --git a/airbyte-integrations/connectors/source-singlestore/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-singlestore/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-singlestore/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-singlestore/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-singlestore/metadata.yaml b/airbyte-integrations/connectors/source-singlestore/metadata.yaml index 57ddcd9b694b..e21223e7d464 100644 --- a/airbyte-integrations/connectors/source-singlestore/metadata.yaml +++ b/airbyte-integrations/connectors/source-singlestore/metadata.yaml @@ -2,24 +2,26 @@ data: allowedHosts: hosts: - ${host} - registryOverrides: - oss: - enabled: true - cloud: - enabled: false + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a connectorSubtype: database connectorType: source definitionId: 2e8ae725-0069-4452-afa0-d1848cf69676 - dockerImageTag: 0.1.0 + dockerImageTag: 0.1.1 dockerRepository: airbyte/source-singlestore + documentationUrl: https://docs.airbyte.com/integrations/sources/singlestore githubIssueLabel: source-singlestore icon: singlestore.svg license: MIT name: SingleStore - releaseDate: - supportLevel: community + registryOverrides: + cloud: + enabled: false + oss: + enabled: true + releaseDate: null releaseStage: alpha - documentationUrl: https://docs.airbyte.com/integrations/sources/singlestore + supportLevel: community tags: - language:java metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-slack/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-slack/integration_tests/acceptance.py index 43ce950d77ca..72132012aaed 100644 --- a/airbyte-integrations/connectors/source-slack/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-slack/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-slack/main.py b/airbyte-integrations/connectors/source-slack/main.py index b2ff9c851163..f80fc7bb2ca1 100644 --- a/airbyte-integrations/connectors/source-slack/main.py +++ b/airbyte-integrations/connectors/source-slack/main.py @@ -4,5 +4,6 @@ from source_slack.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-slack/source_slack/components/channel_members_extractor.py b/airbyte-integrations/connectors/source-slack/source_slack/components/channel_members_extractor.py index 9dbb401a07e9..0ee57c4d76ad 100644 --- a/airbyte-integrations/connectors/source-slack/source_slack/components/channel_members_extractor.py +++ b/airbyte-integrations/connectors/source-slack/source_slack/components/channel_members_extractor.py @@ -4,6 +4,7 @@ from typing import List import requests + from airbyte_cdk.sources.declarative.extractors import DpathExtractor from airbyte_cdk.sources.declarative.types import Record diff --git a/airbyte-integrations/connectors/source-slack/source_slack/components/join_channels.py b/airbyte-integrations/connectors/source-slack/source_slack/components/join_channels.py index 02bd7ee30866..ec353d4921a1 100644 --- a/airbyte-integrations/connectors/source-slack/source_slack/components/join_channels.py +++ b/airbyte-integrations/connectors/source-slack/source_slack/components/join_channels.py @@ -5,6 +5,7 @@ from typing import Any, Iterable, List, Mapping, Optional import requests + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.declarative.partition_routers import SinglePartitionRouter from airbyte_cdk.sources.declarative.retrievers import SimpleRetriever @@ -13,6 +14,7 @@ from airbyte_cdk.sources.streams.http import HttpStream from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator + LOGGER = logging.getLogger("airbyte_logger") diff --git a/airbyte-integrations/connectors/source-slack/source_slack/components/slack_backoff_strategy.py b/airbyte-integrations/connectors/source-slack/source_slack/components/slack_backoff_strategy.py index 0db32e4bce13..cba204c928bd 100644 --- a/airbyte-integrations/connectors/source-slack/source_slack/components/slack_backoff_strategy.py +++ b/airbyte-integrations/connectors/source-slack/source_slack/components/slack_backoff_strategy.py @@ -4,9 +4,10 @@ import logging from typing import Optional, Union -from airbyte_cdk.sources.streams.http.error_handlers import BackoffStrategy from requests import RequestException, Response +from airbyte_cdk.sources.streams.http.error_handlers import BackoffStrategy + class SlackBackoffStrategy(BackoffStrategy): def __init__(self, logger: logging.Logger): diff --git a/airbyte-integrations/connectors/source-slack/source_slack/config_migrations.py b/airbyte-integrations/connectors/source-slack/source_slack/config_migrations.py index cc6d9cd03607..aabfeadd3c7e 100644 --- a/airbyte-integrations/connectors/source-slack/source_slack/config_migrations.py +++ b/airbyte-integrations/connectors/source-slack/source_slack/config_migrations.py @@ -8,6 +8,7 @@ from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository from source_slack import SourceSlack + logger = logging.getLogger("airbyte_logger") diff --git a/airbyte-integrations/connectors/source-slack/source_slack/source.py b/airbyte-integrations/connectors/source-slack/source_slack/source.py index 5328556a1624..bf600c7a6bc9 100644 --- a/airbyte-integrations/connectors/source-slack/source_slack/source.py +++ b/airbyte-integrations/connectors/source-slack/source_slack/source.py @@ -5,6 +5,7 @@ from typing import Any, List, Mapping import pendulum + from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http import HttpStream diff --git a/airbyte-integrations/connectors/source-slack/source_slack/streams.py b/airbyte-integrations/connectors/source-slack/source_slack/streams.py index 1530c74a0ae5..8623af137fef 100644 --- a/airbyte-integrations/connectors/source-slack/source_slack/streams.py +++ b/airbyte-integrations/connectors/source-slack/source_slack/streams.py @@ -8,12 +8,13 @@ import pendulum import requests +from pendulum import DateTime + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.streams.core import CheckpointMixin from airbyte_cdk.sources.streams.http import HttpStream, HttpSubStream from airbyte_cdk.sources.streams.http.error_handlers import BackoffStrategy, ErrorHandler, HttpStatusErrorHandler from airbyte_cdk.sources.streams.http.error_handlers.default_error_mapping import DEFAULT_ERROR_MAPPING -from pendulum import DateTime from source_slack.components.slack_backoff_strategy import SlackBackoffStrategy from .components.join_channels import JoinChannelsStream diff --git a/airbyte-integrations/connectors/source-slack/unit_tests/conftest.py b/airbyte-integrations/connectors/source-slack/unit_tests/conftest.py index 002a9ec96779..3d03f4755646 100644 --- a/airbyte-integrations/connectors/source-slack/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-slack/unit_tests/conftest.py @@ -8,6 +8,7 @@ import pytest + os.environ["REQUEST_CACHE_PATH"] = "REQUEST_CACHE_PATH" @@ -16,13 +17,10 @@ def conversations_list(requests_mock): return requests_mock.register_uri( "GET", "https://slack.com/api/conversations.list?limit=1000&types=public_channel", - json={ - "channels": [ - {"id": "airbyte-for-beginners", "is_member": True}, - {"id": "good-reads", "is_member": True}] - }, + json={"channels": [{"id": "airbyte-for-beginners", "is_member": True}, {"id": "good-reads", "is_member": True}]}, ) + def base_config() -> MutableMapping: return copy.deepcopy( { @@ -98,11 +96,27 @@ def invalid_config() -> MutableMapping: @pytest.fixture def joined_channel(): - return {"id": "C061EG9SL", "name": "general", "is_channel": True, "is_group": False, "is_im": False, - "created": 1449252889, - "creator": "U061F7AUR", "is_archived": False, "is_general": True, "unlinked": 0, "name_normalized": "general", - "is_shared": False, - "is_ext_shared": False, "is_org_shared": False, "pending_shared": [], "is_pending_ext_shared": False, - "is_member": True, "is_private": False, "is_mpim": False, - "topic": {"value": "Which widget do you worry about?", "creator": "", "last_set": 0}, - "purpose": {"value": "For widget discussion", "creator": "", "last_set": 0}, "previous_names": []} + return { + "id": "C061EG9SL", + "name": "general", + "is_channel": True, + "is_group": False, + "is_im": False, + "created": 1449252889, + "creator": "U061F7AUR", + "is_archived": False, + "is_general": True, + "unlinked": 0, + "name_normalized": "general", + "is_shared": False, + "is_ext_shared": False, + "is_org_shared": False, + "pending_shared": [], + "is_pending_ext_shared": False, + "is_member": True, + "is_private": False, + "is_mpim": False, + "topic": {"value": "Which widget do you worry about?", "creator": "", "last_set": 0}, + "purpose": {"value": "For widget discussion", "creator": "", "last_set": 0}, + "previous_names": [], + } diff --git a/airbyte-integrations/connectors/source-slack/unit_tests/test_components.py b/airbyte-integrations/connectors/source-slack/unit_tests/test_components.py index dc21220a0139..d0068d1f4aa9 100644 --- a/airbyte-integrations/connectors/source-slack/unit_tests/test_components.py +++ b/airbyte-integrations/connectors/source-slack/unit_tests/test_components.py @@ -4,13 +4,14 @@ import pendulum import pytest +from source_slack import SourceSlack +from source_slack.components.channel_members_extractor import ChannelMembersExtractor +from source_slack.components.join_channels import ChannelsRetriever, JoinChannelsStream + from airbyte_cdk.sources.declarative.extractors import DpathExtractor, RecordSelector from airbyte_cdk.sources.declarative.requesters import HttpRequester from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator from airbyte_protocol.models import SyncMode -from source_slack import SourceSlack -from source_slack.components.channel_members_extractor import ChannelMembersExtractor -from source_slack.components.join_channels import ChannelsRetriever, JoinChannelsStream def get_stream_by_name(stream_name, config): @@ -23,22 +24,13 @@ def get_stream_by_name(stream_name, config): def test_channel_members_extractor(token_config): response_mock = MagicMock() - response_mock.json.return_value = {"members": [ - "U023BECGF", - "U061F7AUR", - "W012A3CDE" - ]} + response_mock.json.return_value = {"members": ["U023BECGF", "U061F7AUR", "W012A3CDE"]} records = ChannelMembersExtractor(config=token_config, parameters={}, field_path=["members"]).extract_records(response=response_mock) - assert records == [{"member_id": "U023BECGF"}, - {"member_id": "U061F7AUR"}, - {"member_id": "W012A3CDE"}] + assert records == [{"member_id": "U023BECGF"}, {"member_id": "U061F7AUR"}, {"member_id": "W012A3CDE"}] def test_join_channels(token_config, requests_mock, joined_channel): - mocked_request = requests_mock.post( - url="https://slack.com/api/conversations.join", - json={"ok": True, "channel": joined_channel} - ) + mocked_request = requests_mock.post(url="https://slack.com/api/conversations.join", json={"ok": True, "channel": joined_channel}) token = token_config["credentials"]["api_token"] authenticator = TokenAuthenticator(token) channel_filter = token_config["channel_filter"] @@ -51,13 +43,16 @@ def test_join_channels(token_config, requests_mock, joined_channel): def get_channels_retriever_instance(token_config): return ChannelsRetriever( config=token_config, - requester=HttpRequester(name="channels", path="conversations.list", url_base="https://slack.com/api/", config=token_config, - parameters={}), + requester=HttpRequester( + name="channels", path="conversations.list", url_base="https://slack.com/api/", config=token_config, parameters={} + ), record_selector=RecordSelector( extractor=DpathExtractor(field_path=["channels"], config=token_config, parameters={}), - config=token_config, parameters={}, - schema_normalization=None), - parameters={} + config=token_config, + parameters={}, + schema_normalization=None, + ), + parameters={}, ) @@ -76,20 +71,22 @@ def test_join_channels_make_join_channel_slice(token_config): @pytest.mark.parametrize( "join_response, log_message", ( - ({"ok": True, "channel": {"is_member": True, "id": "channel 2", "name": "test channel"}}, "Successfully joined channel: test channel"), - ({"ok": False, "error": "missing_scope", "needed": "channels:write"}, - "Unable to joined channel: test channel. Reason: {'ok': False, 'error': " "'missing_scope', 'needed': 'channels:write'}"), + ( + {"ok": True, "channel": {"is_member": True, "id": "channel 2", "name": "test channel"}}, + "Successfully joined channel: test channel", + ), + ( + {"ok": False, "error": "missing_scope", "needed": "channels:write"}, + "Unable to joined channel: test channel. Reason: {'ok': False, 'error': " "'missing_scope', 'needed': 'channels:write'}", + ), ), - ids=["successful_join_to_channel", "failed_join_to_channel"] + ids=["successful_join_to_channel", "failed_join_to_channel"], ) def test_join_channel_read(requests_mock, token_config, joined_channel, caplog, join_response, log_message): - mocked_request = requests_mock.post( - url="https://slack.com/api/conversations.join", - json=join_response - ) + mocked_request = requests_mock.post(url="https://slack.com/api/conversations.join", json=join_response) requests_mock.get( url="https://slack.com/api/conversations.list", - json={"channels": [{"is_member": True, "id": "channel 1"}, {"is_member": False, "id": "channel 2", "name": "test channel"}]} + json={"channels": [{"is_member": True, "id": "channel 1"}, {"is_member": False, "id": "channel 2", "name": "test channel"}]}, ) retriever = get_channels_retriever_instance(token_config) diff --git a/airbyte-integrations/connectors/source-slack/unit_tests/test_config_migrations.py b/airbyte-integrations/connectors/source-slack/unit_tests/test_config_migrations.py index 761597a66fc2..7ceae8c61119 100644 --- a/airbyte-integrations/connectors/source-slack/unit_tests/test_config_migrations.py +++ b/airbyte-integrations/connectors/source-slack/unit_tests/test_config_migrations.py @@ -7,6 +7,7 @@ from source_slack import SourceSlack from source_slack.config_migrations import MigrateLegacyConfig + CMD = "check" TEST_CONFIG_LEGACY_PATH = f"{os.path.dirname(__file__)}/configs/legacy_config.json" TEST_CONFIG_ACTUAL_PATH = f"{os.path.dirname(__file__)}/configs/actual_config.json" diff --git a/airbyte-integrations/connectors/source-slack/unit_tests/test_source.py b/airbyte-integrations/connectors/source-slack/unit_tests/test_source.py index ae1a58922797..90f6531ca258 100644 --- a/airbyte-integrations/connectors/source-slack/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-slack/unit_tests/test_source.py @@ -17,6 +17,7 @@ def get_stream_by_name(stream_name, config): return stream raise ValueError(f"Stream {stream_name} not found") + @parametrized_configs def test_streams(conversations_list, config, is_valid): source = SourceSlack() diff --git a/airbyte-integrations/connectors/source-slack/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-slack/unit_tests/test_streams.py index b9966eb3594c..4ec3b24c517a 100644 --- a/airbyte-integrations/connectors/source-slack/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-slack/unit_tests/test_streams.py @@ -6,12 +6,13 @@ import pendulum import pytest -from airbyte_cdk.sources.streams.http.error_handlers import ResponseAction -from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator from requests import Response from source_slack import SourceSlack from source_slack.streams import Channels, JoinChannelsStream, Threads +from airbyte_cdk.sources.streams.http.error_handlers import ResponseAction +from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator + @pytest.fixture def authenticator(token_config): @@ -36,10 +37,10 @@ def get_stream_by_name(stream_name, config): {}, [ # two messages per each channel - {'channel': 'airbyte-for-beginners', 'ts': 1577866844}, - {'channel': 'airbyte-for-beginners', 'ts': 1577877406}, - {'channel': 'good-reads', 'ts': 1577866844}, - {'channel': 'good-reads', 'ts': 1577877406}, + {"channel": "airbyte-for-beginners", "ts": 1577866844}, + {"channel": "airbyte-for-beginners", "ts": 1577877406}, + {"channel": "good-reads", "ts": 1577866844}, + {"channel": "good-reads", "ts": 1577877406}, ], ), ("2020-01-02T00:00:00Z", "2020-01-01T00:00:00Z", [], {}, [{}]), @@ -55,18 +56,18 @@ def get_stream_by_name(stream_name, config): ), ), ) -def test_threads_stream_slices( - requests_mock, authenticator, token_config, start_date, end_date, messages, stream_state, expected_result -): +def test_threads_stream_slices(requests_mock, authenticator, token_config, start_date, end_date, messages, stream_state, expected_result): token_config["channel_filter"] = [] requests_mock.register_uri( - "GET", "https://slack.com/api/conversations.history?limit=1000&channel=airbyte-for-beginners", - [{"json": {"messages": messages}}, {"json": {"messages": []}}] + "GET", + "https://slack.com/api/conversations.history?limit=1000&channel=airbyte-for-beginners", + [{"json": {"messages": messages}}, {"json": {"messages": []}}], ) requests_mock.register_uri( - "GET", "https://slack.com/api/conversations.history?limit=1000&channel=good-reads", - [{"json": {"messages": messages}}, {"json": {"messages": []}}] + "GET", + "https://slack.com/api/conversations.history?limit=1000&channel=good-reads", + [{"json": {"messages": messages}}, {"json": {"messages": []}}], ) start_date = pendulum.parse(start_date) @@ -76,7 +77,7 @@ def test_threads_stream_slices( authenticator=authenticator, default_start_date=start_date, end_date=end_date, - lookback_window=pendulum.Duration(days=token_config["lookback_window"]) + lookback_window=pendulum.Duration(days=token_config["lookback_window"]), ) slices = list(stream.stream_slices(stream_state=stream_state)) assert slices == expected_result @@ -92,11 +93,10 @@ def test_threads_stream_slices( ), ) def test_get_updated_state(authenticator, token_config, current_state, latest_record, expected_state): - stream = Threads( authenticator=authenticator, default_start_date=pendulum.parse(token_config["start_date"]), - lookback_window=token_config["lookback_window"] + lookback_window=token_config["lookback_window"], ) assert stream._get_updated_state(current_stream_state=current_state, latest_record=latest_record) == expected_state @@ -105,10 +105,10 @@ def test_threads_request_params(authenticator, token_config): stream = Threads( authenticator=authenticator, default_start_date=pendulum.parse(token_config["start_date"]), - lookback_window=token_config["lookback_window"] + lookback_window=token_config["lookback_window"], ) - threads_slice = {'channel': 'airbyte-for-beginners', 'ts': 1577866844} - expected = {'channel': 'airbyte-for-beginners', 'limit': 1000, 'ts': 1577866844} + threads_slice = {"channel": "airbyte-for-beginners", "ts": 1577866844} + expected = {"channel": "airbyte-for-beginners", "limit": 1000, "ts": 1577866844} assert stream.request_params(stream_slice=threads_slice, stream_state={}) == expected @@ -116,7 +116,7 @@ def test_threads_parse_response(mocker, authenticator, token_config): stream = Threads( authenticator=authenticator, default_start_date=pendulum.parse(token_config["start_date"]), - lookback_window=token_config["lookback_window"] + lookback_window=token_config["lookback_window"], ) resp = { "messages": [ @@ -129,14 +129,14 @@ def test_threads_parse_response(mocker, authenticator, token_config): "subscribed": True, "last_read": "1484678597.521003", "unread_count": 0, - "ts": "1482960137.003543" + "ts": "1482960137.003543", } ] } resp_mock = mocker.Mock() resp_mock.json.return_value = resp - threads_slice = {'channel': 'airbyte-for-beginners', 'ts': 1577866844} - actual_response = list(stream.parse_response(response=resp_mock,stream_slice=threads_slice)) + threads_slice = {"channel": "airbyte-for-beginners", "ts": 1577866844} + actual_response = list(stream.parse_response(response=resp_mock, stream_slice=threads_slice)) assert len(actual_response) == 1 assert actual_response[0]["float_ts"] == 1482960137.003543 assert actual_response[0]["channel_id"] == "airbyte-for-beginners" @@ -147,7 +147,7 @@ def test_backoff(token_config, authenticator, headers, expected_result): stream = Threads( authenticator=authenticator, default_start_date=pendulum.parse(token_config["start_date"]), - lookback_window=token_config["lookback_window"] + lookback_window=token_config["lookback_window"], ) mocked_response = MagicMock(spec=Response, headers=headers) assert stream.get_backoff_strategy().backoff_time(mocked_response) == expected_result @@ -157,10 +157,7 @@ def test_channels_stream_with_autojoin(authenticator) -> None: """ The test uses the `conversations_list` fixture(autouse=true) as API mocker. """ - expected = [ - {'id': 'airbyte-for-beginners', 'is_member': True}, - {'id': 'good-reads', 'is_member': True} - ] + expected = [{"id": "airbyte-for-beginners", "is_member": True}, {"id": "good-reads", "is_member": True}] stream = Channels(channel_filter=[], join_channels=True, authenticator=authenticator) assert list(stream.read_records(None)) == expected @@ -169,7 +166,7 @@ def test_next_page_token(authenticator, token_config): stream = Threads( authenticator=authenticator, default_start_date=pendulum.parse(token_config["start_date"]), - lookback_window=token_config["lookback_window"] + lookback_window=token_config["lookback_window"], ) mocked_response = Mock() mocked_response.json.return_value = {"response_metadata": {"next_cursor": "next page"}} @@ -189,22 +186,24 @@ def test_should_retry(authenticator, token_config, status_code, expected): stream = Threads( authenticator=authenticator, default_start_date=pendulum.parse(token_config["start_date"]), - lookback_window=token_config["lookback_window"] + lookback_window=token_config["lookback_window"], ) mocked_response = MagicMock(spec=Response, status_code=status_code) mocked_response.ok = status_code == 200 assert stream.get_error_handler().interpret_response(mocked_response).response_action == expected + def test_channels_stream_with_include_private_channels_false(authenticator) -> None: stream = Channels(channel_filter=[], include_private_channels=False, authenticator=authenticator) params = stream.request_params(stream_slice={}, stream_state={}) - assert params.get("types") == 'public_channel' + assert params.get("types") == "public_channel" + def test_channels_stream_with_include_private_channels(authenticator) -> None: stream = Channels(channel_filter=[], include_private_channels=True, authenticator=authenticator) params = stream.request_params(stream_slice={}, stream_state={}) - assert params.get("types") == 'public_channel,private_channel' + assert params.get("types") == "public_channel,private_channel" diff --git a/airbyte-integrations/connectors/source-smaily/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-smaily/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-smaily/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-smaily/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-smaily/metadata.yaml b/airbyte-integrations/connectors/source-smaily/metadata.yaml index 779af820ac1e..290a9b489a6b 100644 --- a/airbyte-integrations/connectors/source-smaily/metadata.yaml +++ b/airbyte-integrations/connectors/source-smaily/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 781f8b1d-4e20-4842-a2c3-cd9b119d65fa - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-smaily githubIssueLabel: source-smaily icon: smaily.svg @@ -39,5 +39,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.4.3@sha256:8937b693c7e01087f6e86e683826ac20f160f7952b8f0a13cbf4f9bfdd7af570 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-smartengage/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-smartengage/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-smartengage/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-smartengage/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-smartengage/metadata.yaml b/airbyte-integrations/connectors/source-smartengage/metadata.yaml index 873140360d8f..11250a5beed6 100644 --- a/airbyte-integrations/connectors/source-smartengage/metadata.yaml +++ b/airbyte-integrations/connectors/source-smartengage/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 21cc4a17-a011-4485-8a3e-e2341a91ab9f - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-smartengage documentationUrl: https://docs.airbyte.com/integrations/sources/smartengage githubIssueLabel: source-smartengage diff --git a/airbyte-integrations/connectors/source-smartreach/README.md b/airbyte-integrations/connectors/source-smartreach/README.md new file mode 100644 index 000000000000..ed0f3cfd0a48 --- /dev/null +++ b/airbyte-integrations/connectors/source-smartreach/README.md @@ -0,0 +1,35 @@ +# Smartreach +This directory contains the manifest-only connector for `source-smartreach`. + +Smartreach is a sales engagement platform. +Using this connector we extract data from two streams : campaigns and prospects. +Docs : https://smartreach.io/api_docs#smartreach-api + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-smartreach:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-smartreach build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-smartreach test +``` + diff --git a/airbyte-integrations/connectors/source-smartreach/acceptance-test-config.yml b/airbyte-integrations/connectors/source-smartreach/acceptance-test-config.yml new file mode 100644 index 000000000000..40099b9cb7fe --- /dev/null +++ b/airbyte-integrations/connectors/source-smartreach/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-smartreach:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-smartreach/icon.svg b/airbyte-integrations/connectors/source-smartreach/icon.svg new file mode 100644 index 000000000000..cbccccb1bf46 --- /dev/null +++ b/airbyte-integrations/connectors/source-smartreach/icon.svg @@ -0,0 +1,30 @@ + + + + Logo + Created with Sketch. + + + + + + + diff --git a/airbyte-integrations/connectors/source-smartreach/manifest.yaml b/airbyte-integrations/connectors/source-smartreach/manifest.yaml new file mode 100644 index 000000000000..2dc13748d802 --- /dev/null +++ b/airbyte-integrations/connectors/source-smartreach/manifest.yaml @@ -0,0 +1,290 @@ +version: 6.1.0 + +type: DeclarativeSource + +description: >- + Smartreach is a sales engagement platform. + + Using this connector we extract data from two streams : campaigns and + prospects. + + Docs : https://smartreach.io/api_docs#smartreach-api + +check: + type: CheckStream + stream_names: + - campaigns + +definitions: + streams: + campaigns: + type: DeclarativeStream + name: campaigns + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: campaigns + http_method: GET + request_parameters: + team_id: "{{ config['teamid'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - campaigns + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/campaigns" + prospects: + type: DeclarativeStream + name: prospects + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: prospects + http_method: GET + request_parameters: + team_id: "{{ config['teamid'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/prospects" + base_requester: + type: HttpRequester + url_base: https://api.smartreach.io/api/v1/ + authenticator: + type: ApiKeyAuthenticator + inject_into: + type: RequestOption + inject_into: header + field_name: X-API-KEY + api_token: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/campaigns" + - $ref: "#/definitions/streams/prospects" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - teamid + properties: + api_key: + type: string + title: API Key + airbyte_secret: true + order: 0 + teamid: + type: number + title: TeamID + order: 1 + additionalProperties: true + +metadata: + autoImportSchema: + campaigns: true + prospects: true + testedStreams: + campaigns: + streamHash: e79838138dfc56f5c6cdf2f220baef899bf1de36 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + prospects: + streamHash: a85b47cda313055ad0fae59d8f625fd7814ea6a2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + campaigns: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + owner_id: + type: + - number + - "null" + stats: + type: + - object + - "null" + properties: + total_clicked: + type: + - number + - "null" + total_opened: + type: + - number + - "null" + total_replied: + type: + - number + - "null" + total_sent: + type: + - number + - "null" + status: + type: + - string + - "null" + required: + - id + prospects: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + data: + type: + - object + - "null" + properties: + prospects: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + city: + type: + - string + - "null" + company: + type: + - string + - "null" + country: + type: + - string + - "null" + created_at: + type: + - string + - "null" + custom_fields: + type: + - object + - "null" + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + id: + type: + - number + - "null" + job_title: + type: + - string + - "null" + last_name: + type: + - string + - "null" + linkedin_url: + type: + - string + - "null" + list: + type: + - string + - "null" + object: + type: + - string + - "null" + owner_id: + type: + - number + - "null" + owner_uuid: + type: + - string + - "null" + phone: + type: + - string + - "null" + prospect_category: + type: + - string + - "null" + prospect_uuid: + type: + - string + - "null" + state: + type: + - string + - "null" + team_id: + type: + - number + - "null" + timezone: + type: + - string + - "null" + updated_at: + type: + - string + - "null" + message: + type: + - string + - "null" + status: + type: + - string + - "null" diff --git a/airbyte-integrations/connectors/source-smartreach/metadata.yaml b/airbyte-integrations/connectors/source-smartreach/metadata.yaml new file mode 100644 index 000000000000..b143de188bb8 --- /dev/null +++ b/airbyte-integrations/connectors/source-smartreach/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.smartreach.io" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-smartreach + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 896dc0b3-9b46-4ff4-8ba6-cfd7460a3895 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-smartreach + githubIssueLabel: source-smartreach + icon: icon.svg + license: MIT + name: Smartreach + releaseDate: 2024-11-01 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/smartreach + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-smartsheets/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-smartsheets/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-smartsheets/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-smartsheets/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-smartsheets/main.py b/airbyte-integrations/connectors/source-smartsheets/main.py index 62f5650b92ea..deabf33cba73 100644 --- a/airbyte-integrations/connectors/source-smartsheets/main.py +++ b/airbyte-integrations/connectors/source-smartsheets/main.py @@ -4,5 +4,6 @@ from source_smartsheets.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-smartsheets/metadata.yaml b/airbyte-integrations/connectors/source-smartsheets/metadata.yaml index 9000aa9dd982..b067bc62263a 100644 --- a/airbyte-integrations/connectors/source-smartsheets/metadata.yaml +++ b/airbyte-integrations/connectors/source-smartsheets/metadata.yaml @@ -9,7 +9,7 @@ data: connectorSubtype: api connectorType: source definitionId: 374ebc65-6636-4ea0-925c-7d35999a8ffc - dockerImageTag: 1.1.24 + dockerImageTag: 1.1.29 dockerRepository: airbyte/source-smartsheets documentationUrl: https://docs.airbyte.com/integrations/sources/smartsheets githubIssueLabel: source-smartsheets @@ -51,5 +51,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-smartsheets/poetry.lock b/airbyte-integrations/connectors/source-smartsheets/poetry.lock index 4bd15a1c6b4a..a21db37fdafa 100644 --- a/airbyte-integrations/connectors/source-smartsheets/poetry.lock +++ b/airbyte-integrations/connectors/source-smartsheets/poetry.lock @@ -52,19 +52,19 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -130,127 +130,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -266,20 +253,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -357,13 +344,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -476,13 +463,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -552,54 +539,54 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -667,13 +654,13 @@ files = [ [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] @@ -875,33 +862,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -928,13 +915,43 @@ test = ["coverage", "coveralls", "pytest"] [[package]] name = "tomli" -version = "2.0.2" +version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] [[package]] @@ -994,81 +1011,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-smartsheets/pyproject.toml b/airbyte-integrations/connectors/source-smartsheets/pyproject.toml index 027d94fe3185..d6bd5b4e6639 100644 --- a/airbyte-integrations/connectors/source-smartsheets/pyproject.toml +++ b/airbyte-integrations/connectors/source-smartsheets/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "1.1.24" +version = "1.1.29" name = "source-smartsheets" description = "Source implementation for Smartsheets." authors = [ "Nate Nowack ",] diff --git a/airbyte-integrations/connectors/source-smartsheets/source_smartsheets/sheet.py b/airbyte-integrations/connectors/source-smartsheets/source_smartsheets/sheet.py index ac0c398907e0..f21e72409f4a 100644 --- a/airbyte-integrations/connectors/source-smartsheets/source_smartsheets/sheet.py +++ b/airbyte-integrations/connectors/source-smartsheets/source_smartsheets/sheet.py @@ -8,6 +8,7 @@ from typing import Any, Dict, Iterable, Mapping, Optional, Tuple import smartsheet + from airbyte_cdk.sources.streams.http.requests_native_auth import SingleUseRefreshTokenOauth2Authenticator diff --git a/airbyte-integrations/connectors/source-smartsheets/unit_tests/conftest.py b/airbyte-integrations/connectors/source-smartsheets/unit_tests/conftest.py index 54e3bb226ee5..285e1da0e19b 100644 --- a/airbyte-integrations/connectors/source-smartsheets/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-smartsheets/unit_tests/conftest.py @@ -9,6 +9,7 @@ import pytest from smartsheet.models import Sheet + HERE = Path(__file__).parent.absolute() diff --git a/airbyte-integrations/connectors/source-smartsheets/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-smartsheets/unit_tests/test_streams.py index 0e9fd35ce43d..498fd9fb8192 100644 --- a/airbyte-integrations/connectors/source-smartsheets/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-smartsheets/unit_tests/test_streams.py @@ -5,9 +5,10 @@ import datetime from unittest.mock import Mock -from airbyte_cdk.models import SyncMode from source_smartsheets.streams import SmartsheetStream +from airbyte_cdk.models import SyncMode + def test_state_saved_after_each_record(config, get_sheet_mocker): today_dt = datetime.datetime.now(datetime.timezone.utc) diff --git a/airbyte-integrations/connectors/source-smartwaiver/metadata.yaml b/airbyte-integrations/connectors/source-smartwaiver/metadata.yaml index 415757e4be55..837590b7a5bf 100644 --- a/airbyte-integrations/connectors/source-smartwaiver/metadata.yaml +++ b/airbyte-integrations/connectors/source-smartwaiver/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-smartwaiver connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 878608e5-4086-4cd2-8b23-32d839616687 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-smartwaiver githubIssueLabel: source-smartwaiver icon: icon.svg diff --git a/airbyte-integrations/connectors/source-snapchat-marketing/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-snapchat-marketing/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-snapchat-marketing/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-snapchat-marketing/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-snapchat-marketing/manifest.yaml b/airbyte-integrations/connectors/source-snapchat-marketing/manifest.yaml index b51f2e62a770..20e3b335977d 100644 --- a/airbyte-integrations/connectors/source-snapchat-marketing/manifest.yaml +++ b/airbyte-integrations/connectors/source-snapchat-marketing/manifest.yaml @@ -4951,6 +4951,40 @@ spec: title: View Attribution Window default: 1_DAY additionalProperties: true + advanced_auth: + auth_flow_type: "oauth2.0" + oauth_config_specification: + oauth_user_input_from_connector_config_specification: + type: object + properties: + client_id: + type: string + path_in_connector_config: ["client_id"] + client_secret: + type: string + path_in_connector_config: ["client_secret"] + complete_oauth_output_specification: + type: object + properties: + refresh_token: + type: string + path_in_connector_config: ["refresh_token"] + complete_oauth_server_input_specification: + type: object + properties: + client_id: + type: string + client_secret: + type: string + complete_oauth_server_output_specification: + type: object + properties: + client_id: + type: string + path_in_connector_config: ["client_id"] + client_secret: + type: string + path_in_connector_config: ["client_secret"] metadata: autoImportSchema: diff --git a/airbyte-integrations/connectors/source-snapchat-marketing/metadata.yaml b/airbyte-integrations/connectors/source-snapchat-marketing/metadata.yaml index 9a42dca064e4..6ddcbe0ec03b 100644 --- a/airbyte-integrations/connectors/source-snapchat-marketing/metadata.yaml +++ b/airbyte-integrations/connectors/source-snapchat-marketing/metadata.yaml @@ -4,11 +4,11 @@ data: - accounts.snapchat.com - adsapi.snapchat.com connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 200330b2-ea62-4d11-ac6d-cfe3e3f8ab2b - dockerImageTag: 1.3.1 + dockerImageTag: 1.3.5 dockerRepository: airbyte/source-snapchat-marketing githubIssueLabel: source-snapchat-marketing icon: snapchat.svg diff --git a/airbyte-integrations/connectors/source-snowflake/build.gradle b/airbyte-integrations/connectors/source-snowflake/build.gradle index a49ec3ff0ac8..e4e53038c7dd 100644 --- a/airbyte-integrations/connectors/source-snowflake/build.gradle +++ b/airbyte-integrations/connectors/source-snowflake/build.gradle @@ -14,7 +14,7 @@ application { } dependencies { - implementation group: 'net.snowflake', name: 'snowflake-jdbc', version: '3.14.1' + implementation group: 'net.snowflake', name: 'snowflake-jdbc', version: '3.20.0' testImplementation 'org.testcontainers:jdbc:1.19.4' testImplementation 'org.hamcrest:hamcrest-all:1.3' diff --git a/airbyte-integrations/connectors/source-snowflake/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-snowflake/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-snowflake/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-snowflake/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-snowflake/metadata.yaml b/airbyte-integrations/connectors/source-snowflake/metadata.yaml index 0458c98a0afb..711b9b1c70b6 100644 --- a/airbyte-integrations/connectors/source-snowflake/metadata.yaml +++ b/airbyte-integrations/connectors/source-snowflake/metadata.yaml @@ -5,10 +5,38 @@ data: allowedHosts: hosts: - ${host} + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a connectorSubtype: database + connectorTestSuitesOptions: + - suite: unitTests + - suite: integrationTests + testSecrets: + - fileName: config_auth.json + name: SECRET_SOURCE-SNOWFLAKE_OAUTH__CREDS + secretStore: + alias: airbyte-connector-testing-secret-store + type: GSM + - fileName: config.json + name: SECRET_SOURCE-SNOWFLAKE__CREDS + secretStore: + alias: airbyte-connector-testing-secret-store + type: GSM + - suite: acceptanceTests + testSecrets: + - fileName: config_auth.json + name: SECRET_SOURCE-SNOWFLAKE_OAUTH__CREDS + secretStore: + alias: airbyte-connector-testing-secret-store + type: GSM + - fileName: config.json + name: SECRET_SOURCE-SNOWFLAKE__CREDS + secretStore: + alias: airbyte-connector-testing-secret-store + type: GSM connectorType: source definitionId: e2d65910-8c8b-40a1-ae7d-ee2416b2bfa2 - dockerImageTag: 0.3.3 + dockerImageTag: 0.3.5 dockerRepository: airbyte/source-snowflake documentationUrl: https://docs.airbyte.com/integrations/sources/snowflake githubIssueLabel: source-snowflake @@ -24,30 +52,4 @@ data: supportLevel: community tags: - language:java - connectorTestSuitesOptions: - - suite: unitTests - - suite: integrationTests - testSecrets: - - name: SECRET_SOURCE-SNOWFLAKE_OAUTH__CREDS - fileName: config_auth.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store - - name: SECRET_SOURCE-SNOWFLAKE__CREDS - fileName: config.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store - - suite: acceptanceTests - testSecrets: - - name: SECRET_SOURCE-SNOWFLAKE_OAUTH__CREDS - fileName: config_auth.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store - - name: SECRET_SOURCE-SNOWFLAKE__CREDS - fileName: config.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-solarwinds-service-desk/metadata.yaml b/airbyte-integrations/connectors/source-solarwinds-service-desk/metadata.yaml index 6e818217b7f4..23d183482a31 100644 --- a/airbyte-integrations/connectors/source-solarwinds-service-desk/metadata.yaml +++ b/airbyte-integrations/connectors/source-solarwinds-service-desk/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-solarwinds-service-desk connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 7fc8e411-25e6-4c8a-aab0-0b662a833c8c - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-solarwinds-service-desk githubIssueLabel: source-solarwinds-service-desk icon: icon.svg diff --git a/airbyte-integrations/connectors/source-sonar-cloud/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-sonar-cloud/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-sonar-cloud/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-sonar-cloud/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-sonar-cloud/metadata.yaml b/airbyte-integrations/connectors/source-sonar-cloud/metadata.yaml index 9bd60b1ba3a7..882ea5b30901 100644 --- a/airbyte-integrations/connectors/source-sonar-cloud/metadata.yaml +++ b/airbyte-integrations/connectors/source-sonar-cloud/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - sonarcloud.io connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 3ab1d7d0-1577-4ab9-bcc4-1ff6a4c2c9f2 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.5 dockerRepository: airbyte/source-sonar-cloud documentationUrl: https://docs.airbyte.com/integrations/sources/sonar-cloud githubIssueLabel: source-sonar-cloud diff --git a/airbyte-integrations/connectors/source-spacex-api/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-spacex-api/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-spacex-api/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-spacex-api/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-spacex-api/metadata.yaml b/airbyte-integrations/connectors/source-spacex-api/metadata.yaml index 7dd00606c5ef..27ea7a915596 100644 --- a/airbyte-integrations/connectors/source-spacex-api/metadata.yaml +++ b/airbyte-integrations/connectors/source-spacex-api/metadata.yaml @@ -6,11 +6,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 62235e65-af7a-4138-9130-0bda954eb6a8 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-spacex-api githubIssueLabel: source-spacex-api icon: spacex.svg diff --git a/airbyte-integrations/connectors/source-sparkpost/metadata.yaml b/airbyte-integrations/connectors/source-sparkpost/metadata.yaml index 4c5361f1bac4..75f171440e43 100644 --- a/airbyte-integrations/connectors/source-sparkpost/metadata.yaml +++ b/airbyte-integrations/connectors/source-sparkpost/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-sparkpost connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 5f3256c6-4247-4b6d-a8e4-1df61dc9322c - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-sparkpost githubIssueLabel: source-sparkpost icon: icon.svg diff --git a/airbyte-integrations/connectors/source-split-io/metadata.yaml b/airbyte-integrations/connectors/source-split-io/metadata.yaml index 4391eb01fbd4..db4daf344fea 100644 --- a/airbyte-integrations/connectors/source-split-io/metadata.yaml +++ b/airbyte-integrations/connectors/source-split-io/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-split-io connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.6.2@sha256:f5fcd3d4703b7590b6166a7853c5ed1686731607cd30a159a8c24e2fe2c1ee98 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: fa1994b2-d0b2-451d-807e-a9ceff9377cc - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.5 dockerRepository: airbyte/source-split-io githubIssueLabel: source-split-io icon: icon.svg diff --git a/airbyte-integrations/connectors/source-spotlercrm/README.md b/airbyte-integrations/connectors/source-spotlercrm/README.md new file mode 100644 index 000000000000..ab4a122fbfa4 --- /dev/null +++ b/airbyte-integrations/connectors/source-spotlercrm/README.md @@ -0,0 +1,33 @@ +# SpotlerCRM +This directory contains the manifest-only connector for `source-spotlercrm`. + +The Airbyte connector for [Spotler CRM](https://spotler.com/) enables seamless data integration, allowing users to sync customer data from Spotler CRM into their data warehouses or other tools. It supports automated data extraction from Spotler CRM, making it easier to analyze and leverage customer insights across multiple platforms. With this connector, businesses can efficiently streamline their customer relationship data and maintain up-to-date records for improved decision-making and marketing efforts. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-spotlercrm:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-spotlercrm build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-spotlercrm test +``` + diff --git a/airbyte-integrations/connectors/source-spotlercrm/acceptance-test-config.yml b/airbyte-integrations/connectors/source-spotlercrm/acceptance-test-config.yml new file mode 100644 index 000000000000..bada5a52b499 --- /dev/null +++ b/airbyte-integrations/connectors/source-spotlercrm/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-spotlercrm:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-spotlercrm/icon.svg b/airbyte-integrations/connectors/source-spotlercrm/icon.svg new file mode 100644 index 000000000000..aac96aebb030 --- /dev/null +++ b/airbyte-integrations/connectors/source-spotlercrm/icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/airbyte-integrations/connectors/source-spotlercrm/manifest.yaml b/airbyte-integrations/connectors/source-spotlercrm/manifest.yaml new file mode 100644 index 000000000000..8f061c813c47 --- /dev/null +++ b/airbyte-integrations/connectors/source-spotlercrm/manifest.yaml @@ -0,0 +1,950 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + The Airbyte connector for [Spotler CRM](https://spotler.com/) enables seamless + data integration, allowing users to sync customer data from Spotler CRM into + their data warehouses or other tools. It supports automated data extraction + from Spotler CRM, making it easier to analyze and leverage customer insights + across multiple platforms. With this connector, businesses can efficiently + streamline their customer relationship data and maintain up-to-date records + for improved decision-making and marketing efforts. + +check: + type: CheckStream + stream_names: + - accounts + +definitions: + streams: + accounts: + type: DeclarativeStream + name: accounts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - list + - "*" + - record + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounts" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - list + - "*" + - record + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + opportunities: + type: DeclarativeStream + name: opportunities + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /opportunities + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - list + - "*" + - record + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/opportunities" + documents: + type: DeclarativeStream + name: documents + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /opportunity_lines + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - list + - "*" + - record + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/documents" + campaigns: + type: DeclarativeStream + name: campaigns + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /campaigns + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - list + - "*" + - record + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/campaigns" + " cases": + type: DeclarativeStream + name: " cases" + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /cases + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - list + - "*" + - record + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/ cases" + activities: + type: DeclarativeStream + name: activities + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /activities + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - list + - "*" + - record + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/activities" + opportunity_histories: + type: DeclarativeStream + name: opportunity_histories + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /opportunityhistories + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - list + - "*" + - record + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/opportunity_histories" + opportunity_lines: + type: DeclarativeStream + name: opportunity_lines + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /opportunity_lines + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - list + - "*" + - record + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/opportunity_lines" + base_requester: + type: HttpRequester + url_base: https://apiv4.reallysimplesystems.com + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"access_token\"] }}" + +streams: + - $ref: "#/definitions/streams/accounts" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/opportunities" + - $ref: "#/definitions/streams/documents" + - $ref: "#/definitions/streams/campaigns" + - $ref: "#/definitions/streams/ cases" + - $ref: "#/definitions/streams/activities" + - $ref: "#/definitions/streams/opportunity_histories" + - $ref: "#/definitions/streams/opportunity_lines" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - access_token + properties: + access_token: + type: string + description: >- + Access Token to authenticate API requests. Generate it by logging into + your CRM system, navigating to Settings / Integrations / API V4, and + clicking 'generate new key'. + name: access_token + order: 0 + title: Access Token + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + accounts: true + contacts: false + opportunities: false + documents: true + campaigns: true + " cases": true + activities: true + opportunity_histories: true + opportunity_lines: true + testedStreams: + accounts: + streamHash: 228e48ed130b9347bbe207f40fc5e69cf803658c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contacts: + streamHash: 4b40d70440c4fb24646635e55db0e9b932d50520 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + opportunities: + streamHash: 63348e089a396613fc2a32f9bebcee6d644c7949 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + documents: + streamHash: a6a65a975319144846413cc54a1bfee75b2f112c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + campaigns: + streamHash: 2416e1340a7d1f01da2fef06bf5f90525632e820 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + " cases": + streamHash: 68481fbb96d90a65d9b2fc8fdaa06cc06485899b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + activities: + streamHash: d651211072bd9a8f413d7bd4645ef294fe2f2115 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + opportunity_histories: + streamHash: 058ddbd93020908110d973c15e3da1161f4ba1b4 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + opportunity_lines: + streamHash: 20e98bbf72fc0e49eab8ee812677571b6312b7b1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://support.reallysimplesystems.com/api-v4/ + +schemas: + accounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + addresscity: + type: + - string + - "null" + addresscountry: + type: + - string + - "null" + addresscounty/state: + type: + - string + - "null" + addressline: + type: + - string + - "null" + addresspostcode/zip: + type: + - string + - "null" + createdby: + type: + - number + - "null" + createddate: + type: + - string + - "null" + id: + type: number + modifiedby: + type: + - number + - "null" + modifieddate: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + ownerid: + type: + - number + - "null" + phone: + type: + - string + - "null" + sector: + type: + - string + - "null" + slaid: + type: + - number + - "null" + source: + type: + - string + - "null" + website: + type: + - string + - "null" + required: + - id + contacts: + type: object + $schema: http://json-schema.org/schema# + properties: + accountid: + type: + - number + - "null" + addresscity: + type: + - string + - "null" + addresscountry: + type: + - string + - "null" + addresscounty/state: + type: + - string + - "null" + addresspostcode/zip: + type: + - string + - "null" + createdby: + type: + - number + - "null" + createddate: + type: + - string + - "null" + decisionmaker: + type: + - number + - "null" + email: + type: + - string + - "null" + first: + type: + - string + - "null" + hold: + type: + - number + - "null" + id: + type: number + jobtitle: + type: + - string + - "null" + last: + type: + - string + - "null" + leadscore: + type: + - number + - "null" + middle: + type: + - string + - "null" + modifiedby: + type: + - number + - "null" + modifieddate: + type: + - string + - "null" + phone: + type: + - string + - "null" + salutation: + type: + - string + - "null" + required: + - id + additionalProperties: true + opportunities: + type: object + $schema: http://json-schema.org/schema# + properties: + accountid: + type: + - number + - "null" + closedate: + type: + - string + - "null" + createdby: + type: + - number + - "null" + createddate: + type: + - string + - "null" + forecast: + type: + - string + - "null" + id: + type: number + modifiedby: + type: + - number + - "null" + modifieddate: + type: + - string + - "null" + name: + type: + - string + - "null" + nextstep: + type: + - string + - "null" + probability: + type: + - number + - "null" + repeat: + type: + - string + - "null" + source: + type: + - string + - "null" + status: + type: + - string + - "null" + required: + - id + additionalProperties: true + documents: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdby: + type: + - number + - "null" + id: + type: + - number + - "null" + modifiedby: + type: + - number + - "null" + opportunityid: + type: + - number + - "null" + product: + type: + - string + - "null" + quantity: + type: + - number + - "null" + unitprice: + type: + - number + - "null" + campaigns: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + active: + type: + - number + - "null" + dripfeed: + type: + - number + - "null" + id: + type: number + members: + type: + - number + - "null" + name: + type: + - string + - "null" + opportunities: + type: + - number + - "null" + ownerid: + type: + - number + - "null" + sales: + type: + - number + - "null" + status: + type: + - string + - "null" + required: + - id + " cases": + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + accountid: + type: + - number + - "null" + caselevelid: + type: + - number + - "null" + createdby: + type: + - number + - "null" + createddate: + type: + - string + - "null" + id: + type: number + modifiedby: + type: + - number + - "null" + modifieddate: + type: + - string + - "null" + opened: + type: + - string + - "null" + ownerid: + type: + - number + - "null" + status: + type: + - string + - "null" + subject: + type: + - string + - "null" + required: + - id + activities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + accountid: + type: + - number + - "null" + allday: + type: + - number + - "null" + caseid: + type: + - number + - "null" + contactid: + type: + - number + - "null" + createddate: + type: + - string + - "null" + date: + type: + - string + - "null" + id: + type: number + modifieddate: + type: + - string + - "null" + priority: + type: + - number + - "null" + status: + type: + - string + - "null" + required: + - id + opportunity_histories: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + closedate: + type: + - string + - "null" + forecast: + type: + - string + - "null" + id: + type: number + modifiedby: + type: + - number + - "null" + modifieddate: + type: + - string + - "null" + opportunitystatus: + type: + - string + - "null" + probability: + type: + - number + - "null" + value: + type: + - number + - "null" + required: + - id + opportunity_lines: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdby: + type: + - number + - "null" + id: + type: number + modifiedby: + type: + - number + - "null" + opportunityid: + type: + - number + - "null" + product: + type: + - string + - "null" + quantity: + type: + - number + - "null" + unitprice: + type: + - number + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-spotlercrm/metadata.yaml b/airbyte-integrations/connectors/source-spotlercrm/metadata.yaml new file mode 100644 index 000000000000..44df9608ab1e --- /dev/null +++ b/airbyte-integrations/connectors/source-spotlercrm/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "apiv4.reallysimplesystems.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-spotlercrm + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 039127b5-9ff5-433e-950c-ae8d0a8912d4 + dockerImageTag: 0.0.4 + dockerRepository: airbyte/source-spotlercrm + githubIssueLabel: source-spotlercrm + icon: icon.svg + license: MIT + name: SpotlerCRM + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/spotlercrm + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-square/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-square/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-square/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-square/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-squarespace/metadata.yaml b/airbyte-integrations/connectors/source-squarespace/metadata.yaml index 428b14bcd3ed..23d24bcb51bd 100644 --- a/airbyte-integrations/connectors/source-squarespace/metadata.yaml +++ b/airbyte-integrations/connectors/source-squarespace/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-squarespace connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 861e1bde-0d7c-4f15-9f96-e845df8d3544 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-squarespace githubIssueLabel: source-squarespace icon: icon.svg diff --git a/airbyte-integrations/connectors/source-statsig/metadata.yaml b/airbyte-integrations/connectors/source-statsig/metadata.yaml index 7ba2cb620598..729fafc5ca16 100644 --- a/airbyte-integrations/connectors/source-statsig/metadata.yaml +++ b/airbyte-integrations/connectors/source-statsig/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-statsig connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: c8f77358-755a-4778-a1fc-c23c3cee7d83 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-statsig githubIssueLabel: source-statsig icon: icon.svg diff --git a/airbyte-integrations/connectors/source-statuspage/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-statuspage/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-statuspage/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-statuspage/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-statuspage/metadata.yaml b/airbyte-integrations/connectors/source-statuspage/metadata.yaml index 35b7c3a5b3a3..8ca14577d0fd 100644 --- a/airbyte-integrations/connectors/source-statuspage/metadata.yaml +++ b/airbyte-integrations/connectors/source-statuspage/metadata.yaml @@ -12,11 +12,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:4.4.3@sha256:8937b693c7e01087f6e86e683826ac20f160f7952b8f0a13cbf4f9bfdd7af570 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 74cbd708-46c3-4512-9c93-abd5c3e9a94d - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.5 dockerRepository: airbyte/source-statuspage githubIssueLabel: source-statuspage icon: statuspage.svg diff --git a/airbyte-integrations/connectors/source-stockdata/README.md b/airbyte-integrations/connectors/source-stockdata/README.md new file mode 100644 index 000000000000..022e6a373767 --- /dev/null +++ b/airbyte-integrations/connectors/source-stockdata/README.md @@ -0,0 +1,38 @@ +# StockData +This directory contains the manifest-only connector for `source-stockdata`. + +Stockdata provides access to market news for global exchanges, and trading data for US stocks. +With this connector we can extract data from EOD , Intraday and news feeds streams + + + + + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-stockdata:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-stockdata build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-stockdata test +``` + diff --git a/airbyte-integrations/connectors/source-stockdata/acceptance-test-config.yml b/airbyte-integrations/connectors/source-stockdata/acceptance-test-config.yml new file mode 100644 index 000000000000..d4d606678c8a --- /dev/null +++ b/airbyte-integrations/connectors/source-stockdata/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-stockdata:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-stockdata/icon.svg b/airbyte-integrations/connectors/source-stockdata/icon.svg new file mode 100644 index 000000000000..11db3c73acdb --- /dev/null +++ b/airbyte-integrations/connectors/source-stockdata/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-stockdata/manifest.yaml b/airbyte-integrations/connectors/source-stockdata/manifest.yaml new file mode 100644 index 000000000000..eec0d253a4cf --- /dev/null +++ b/airbyte-integrations/connectors/source-stockdata/manifest.yaml @@ -0,0 +1,635 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >+ + Stockdata provides access to market news for global exchanges, and trading + data for US stocks. + + With this connector we can extract data from EOD , Intraday and news feeds + streams + + +check: + type: CheckStream + stream_names: + - news_feeds_per_symbols + +definitions: + streams: + news_feeds_per_symbols: + type: DeclarativeStream + name: news_feeds_per_symbols + primary_key: + - uuid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: news/all + http_method: GET + request_parameters: + symbols: "{{ stream_partition.symb }}" + language: en + filter_entities: "{{ config['filter_entities'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: ListPartitionRouter + values: "{{ config[\"symbols\"] }}" + cursor_field: symb + incremental_sync: + type: DatetimeBasedCursor + cursor_field: published_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%fZ" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: published_after + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: published_before + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/news_feeds_per_symbols" + eod_data: + type: DeclarativeStream + name: eod_data + primary_key: + - date + - ticker + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: data/eod + http_method: GET + request_parameters: + symbols: "{{ stream_partition.symb }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: ListPartitionRouter + values: "{{ config[\"symbols\"] }}" + cursor_field: symb + incremental_sync: + type: DatetimeBasedCursor + cursor_field: date + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%fZ" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: date_from + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: date_to + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + transformations: + - type: AddFields + fields: + - path: + - ticker + value: "{{ stream_partition.symb }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/eod_data" + intraday_unadjusted_data: + type: DeclarativeStream + name: intraday_unadjusted_data + primary_key: + - date + - ticker + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: data/intraday + http_method: GET + request_parameters: + symbols: "{{ stream_partition.symb }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: ListPartitionRouter + values: "{{ config[\"symbols\"] }}" + cursor_field: symb + incremental_sync: + type: DatetimeBasedCursor + cursor_field: date + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%fZ" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: date_from + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: date_to + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/intraday_unadjusted_data" + news_feeds_per_industry: + type: DeclarativeStream + name: news_feeds_per_industry + primary_key: + - uuid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: news/all + http_method: GET + request_parameters: + language: en + industries: "{{ stream_partition.indus }}" + filter_entities: "{{ config['filter_entities'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 50 + start_from_page: 1 + inject_on_first_request: true + partition_router: + type: ListPartitionRouter + values: "{{ config[\"industries\"] }}" + cursor_field: indus + incremental_sync: + type: DatetimeBasedCursor + cursor_field: published_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%fZ" + datetime_format: "%Y-%m-%d" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: published_after + inject_into: request_parameter + end_time_option: + type: RequestOption + field_name: published_before + inject_into: request_parameter + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/news_feeds_per_industry" + base_requester: + type: HttpRequester + url_base: https://api.stockdata.org/v1/ + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: api_token + inject_into: request_parameter + +streams: + - $ref: "#/definitions/streams/news_feeds_per_symbols" + - $ref: "#/definitions/streams/eod_data" + - $ref: "#/definitions/streams/intraday_unadjusted_data" + - $ref: "#/definitions/streams/news_feeds_per_industry" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - start_date + properties: + api_key: + type: string + order: 0 + title: API Key + airbyte_secret: true + symbols: + type: array + order: 1 + title: Symbols + industries: + type: array + description: >- + Specify the industries of entities which have been identified within + the article. + order: 2 + title: Industries + filter_entities: + type: boolean + order: 3 + title: Entities + default: false + start_date: + type: string + order: 4 + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + additionalProperties: true + +metadata: + autoImportSchema: + news_feeds_per_symbols: true + eod_data: true + intraday_unadjusted_data: true + news_feeds_per_industry: true + testedStreams: + news_feeds_per_symbols: + streamHash: e53e9e50fdf2746af0e5a23b0be08d09aea895f4 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + eod_data: + streamHash: 4177c0e0275183087a9b6870657b0cb9fb5f194c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + intraday_unadjusted_data: + streamHash: ce637107641776943a13289a12f092c8be3eb845 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + news_feeds_per_industry: + streamHash: 29f3c6a8064a076a4d878ec6fcec8c9d62b059b8 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + news_feeds_per_symbols: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + entities: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + country: + type: + - string + - "null" + highlights: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + highlight: + type: + - string + - "null" + highlighted_in: + type: + - string + - "null" + sentiment: + type: + - number + - "null" + industry: + type: + - string + - "null" + match_score: + type: + - number + - "null" + name: + type: + - string + - "null" + sentiment_score: + type: + - number + - "null" + symbol: + type: + - string + - "null" + image_url: + type: + - string + - "null" + keywords: + type: + - string + - "null" + language: + type: + - string + - "null" + published_at: + type: string + similar: + type: + - array + - "null" + snippet: + type: + - string + - "null" + source: + type: + - string + - "null" + title: + type: + - string + - "null" + url: + type: + - string + - "null" + uuid: + type: string + required: + - uuid + - published_at + eod_data: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + close: + type: + - number + - "null" + date: + type: string + high: + type: + - number + - "null" + low: + type: + - number + - "null" + open: + type: + - number + - "null" + symbol: + type: string + volume: + type: + - number + - "null" + required: + - date + - symbol + intraday_unadjusted_data: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + data: + type: + - object + - "null" + properties: + close: + type: + - number + - "null" + high: + type: + - number + - "null" + is_extended_hours: + type: + - boolean + - "null" + low: + type: + - number + - "null" + open: + type: + - number + - "null" + volume: + type: + - number + - "null" + date: + type: string + ticker: + type: string + required: + - date + - ticker + news_feeds_per_industry: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + entities: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + country: + type: + - string + - "null" + highlights: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + highlight: + type: + - string + - "null" + highlighted_in: + type: + - string + - "null" + sentiment: + type: + - number + - "null" + industry: + type: + - string + - "null" + match_score: + type: + - number + - "null" + name: + type: + - string + - "null" + sentiment_score: + type: + - number + - "null" + symbol: + type: + - string + - "null" + image_url: + type: + - string + - "null" + keywords: + type: + - string + - "null" + language: + type: + - string + - "null" + published_at: + type: string + similar: + type: + - array + - "null" + snippet: + type: + - string + - "null" + source: + type: + - string + - "null" + title: + type: + - string + - "null" + url: + type: + - string + - "null" + uuid: + type: string + required: + - uuid + - published_at diff --git a/airbyte-integrations/connectors/source-stockdata/metadata.yaml b/airbyte-integrations/connectors/source-stockdata/metadata.yaml new file mode 100644 index 000000000000..db99f5c45d44 --- /dev/null +++ b/airbyte-integrations/connectors/source-stockdata/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.stockdata.org" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-stockdata + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: ca58f75d-3929-4fd3-a5b0-4dd92d275c8d + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-stockdata + githubIssueLabel: source-stockdata + icon: icon.svg + license: MIT + name: StockData + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/stockdata + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-strava/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-strava/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-strava/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-strava/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-strava/metadata.yaml b/airbyte-integrations/connectors/source-strava/metadata.yaml index 8f86a365d9fb..2a4060027689 100644 --- a/airbyte-integrations/connectors/source-strava/metadata.yaml +++ b/airbyte-integrations/connectors/source-strava/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - strava.com connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 7a4327c4-315a-11ec-8d3d-0242ac130003 - dockerImageTag: 0.3.1 + dockerImageTag: 0.3.5 dockerRepository: airbyte/source-strava documentationUrl: https://docs.airbyte.com/integrations/sources/strava githubIssueLabel: source-strava diff --git a/airbyte-integrations/connectors/source-stripe/acceptance-test-config.yml b/airbyte-integrations/connectors/source-stripe/acceptance-test-config.yml index 990c6081d931..8fccd1f0d327 100644 --- a/airbyte-integrations/connectors/source-stripe/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-stripe/acceptance-test-config.yml @@ -49,8 +49,12 @@ acceptance_tests: bypass_reason: "Data expires every 30 days." - name: "subscriptions" bypass_reason: "Data appears to have expired and since we can't access our test account we cannot re-seed or verify this" + - name: "subscription_schedule" + bypass_reason: "Since we don't have subscriptions anymore, we can't get child records of subscriptions" - name: "subscription_items" bypass_reason: "Since we don't have subscriptions anymore, we can't get child records of subscriptions" + - name: "subscription_schedule" + bypass_reason: "Since we don't have subscriptions anymore, we can't get child records of subscriptions" - name: "usage_records" bypass_reason: "Since we don't have subscriptions_items anymore which depend on subscriptions, we can't get child records for usage_records" expect_records: diff --git a/airbyte-integrations/connectors/source-stripe/erd/discovered_catalog.json b/airbyte-integrations/connectors/source-stripe/erd/discovered_catalog.json index e5fbaa858fdb..230c8b9161cf 100644 --- a/airbyte-integrations/connectors/source-stripe/erd/discovered_catalog.json +++ b/airbyte-integrations/connectors/source-stripe/erd/discovered_catalog.json @@ -889,7 +889,9 @@ } } }, - "supported_sync_modes": ["full_refresh"], + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["created"], "source_defined_primary_key": [["id"]], "is_resumable": true }, @@ -3289,6 +3291,10 @@ "description": "The timestamp when the account was created.", "type": ["null", "integer"] }, + "updated": { + "description": "The timestamp when the account was updated.", + "type": ["null", "integer"] + }, "default_currency": { "description": "The default currency used for transactions.", "type": ["null", "string"] @@ -3839,9 +3845,10 @@ } } }, - "supported_sync_modes": ["full_refresh"], - "source_defined_primary_key": [["id"]], - "is_resumable": true + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated"], + "source_defined_primary_key": [["id"]] }, { "name": "shipping_rates", @@ -3966,6 +3973,48 @@ "default_cursor_field": ["created"], "source_defined_primary_key": [["id"]] }, + { + "name": "payout_balance_transactions", + "json_schema": { + "type": ["null", "object"], + "properties": { + "fee": { "type": ["null", "integer"] }, + "currency": { "type": ["null", "string"] }, + "source": { "type": ["null", "string"] }, + "fee_details": { + "type": ["null", "array"], + "items": { + "properties": { + "application": { "type": ["null", "string"] }, + "type": { "type": ["null", "string"] }, + "description": { "type": ["null", "string"] }, + "amount": { "type": ["null", "integer"] }, + "currency": { "type": ["null", "string"] } + }, + "type": ["null", "object"] + } + }, + "available_on": { "type": ["null", "integer"] }, + "status": { "type": ["null", "string"] }, + "description": { "type": ["null", "string"] }, + "net": { "type": ["null", "integer"] }, + "exchange_rate": { "type": ["null", "number"] }, + "type": { "type": ["null", "string"] }, + "id": { "type": ["null", "string"] }, + "object": { "type": ["null", "string"] }, + "created": { "type": ["null", "integer"] }, + "updated": { "type": ["null", "integer"] }, + "amount": { "type": ["null", "integer"] }, + "reporting_category": { "type": ["null", "string"] }, + "payout": { "type": ["null", "string"] } + } + }, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated"], + "source_defined_primary_key": [["payout"], ["id"]], + "user_defined_primary_key": [["payout"], ["id"]] + }, { "name": "files", "json_schema": { @@ -12503,12 +12552,22 @@ } } } + }, + "created": { + "description": "Timestamp for when the parent invoice was created", + "type": ["null", "integer"] + }, + "updated": { + "description": "Timestamp for when the parent invoice was last updated", + "type": ["null", "integer"] } } }, - "supported_sync_modes": ["full_refresh"], + "supported_sync_modes": ["full_refresh", "incremental"], "source_defined_primary_key": [["id"]], - "is_resumable": false + "source_defined_cursor": true, + "default_cursor_field": ["updated"], + "is_resumable": true }, { "name": "subscription_items", @@ -12796,12 +12855,18 @@ "unit_amount": { "type": ["null", "integer"] }, "unit_amount_decimal": { "type": ["null", "string"] } } + }, + "updated": { + "description": "Timestamp for when the parent subscription was last updated", + "type": ["null", "integer"] } } }, - "supported_sync_modes": ["full_refresh"], + "supported_sync_modes": ["full_refresh", "incremental"], "source_defined_primary_key": [["id"]], - "is_resumable": false + "source_defined_cursor": true, + "default_cursor_field": ["updated"], + "is_resumable": true }, { "name": "transfer_reversals", @@ -12854,9 +12919,11 @@ } } }, - "supported_sync_modes": ["full_refresh"], + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["created"], "source_defined_primary_key": [["id"]], - "is_resumable": false + "is_resumable": true }, { "name": "usage_records", diff --git a/airbyte-integrations/connectors/source-stripe/erd/source.dbml b/airbyte-integrations/connectors/source-stripe/erd/source.dbml index 858be7ba445f..53bc467b87b7 100644 --- a/airbyte-integrations/connectors/source-stripe/erd/source.dbml +++ b/airbyte-integrations/connectors/source-stripe/erd/source.dbml @@ -186,6 +186,7 @@ Table "accounts" { "company" object "country" string "created" integer + "updated" integer "default_currency" string "details_submitted" boolean "email" string @@ -237,6 +238,30 @@ Table "balance_transactions" { "reporting_category" string } +Table "payout_balance_transactions" { + "payout" string + "fee" integer + "currency" string + "source" string + "fee_details" array + "available_on" integer + "status" string + "description" string + "net" integer + "exchange_rate" number + "type" string + "id" string + "object" string + "created" integer + "updated" integer + "amount" integer + "reporting_category" string + + indexes { + (payout, id) [pk] + } +} + Table "files" { "id" string [pk] "purpose" string @@ -1141,6 +1166,8 @@ Table "invoice_line_items" { "discounts" array "tax_rates" array "tax_amounts" array + "created" integer + "updated" integer } Table "subscription_items" { @@ -1167,6 +1194,7 @@ Table "subscription_items" { "billing_thresholds" object "tax_rates" array "price" object + "updated" integer } Table "transfer_reversals" { @@ -1634,4 +1662,4 @@ Ref { Ref { "usage_records"."subscription_item" <> "subscription_items"."id" -} \ No newline at end of file +} diff --git a/airbyte-integrations/connectors/source-stripe/integration_tests/abnormal_state.json b/airbyte-integrations/connectors/source-stripe/integration_tests/abnormal_state.json index 25ed63a5777f..2f1fc983ccb8 100644 --- a/airbyte-integrations/connectors/source-stripe/integration_tests/abnormal_state.json +++ b/airbyte-integrations/connectors/source-stripe/integration_tests/abnormal_state.json @@ -34,6 +34,20 @@ "stream_descriptor": { "name": "charges" } } }, + { + "type": "STREAM", + "stream": { + "stream_state": { "invoice_updated": 10000000000 }, + "stream_descriptor": { "name": "invoice_line_items" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "subscription_updated": 10000000000 }, + "stream_descriptor": { "name": "subscription_items" } + } + }, { "type": "STREAM", "stream": { @@ -278,5 +292,33 @@ "stream_state": { "updated": 10000000000 }, "stream_descriptor": { "name": "persons" } } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "created": 10000000000 }, + "stream_descriptor": { "name": "customer_balance_transactions" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "updated": 10000000000 }, + "stream_descriptor": { "name": "accounts" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "created": 10000000000 }, + "stream_descriptor": { "name": "transfer_reversals" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "updated": 10000000000 }, + "stream_descriptor": { "name": "payout_balance_transactions" } + } } ] diff --git a/airbyte-integrations/connectors/source-stripe/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-stripe/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-stripe/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-stripe/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-stripe/integration_tests/configured_catalog.json b/airbyte-integrations/connectors/source-stripe/integration_tests/configured_catalog.json index 281642987467..da8999b4a344 100644 --- a/airbyte-integrations/connectors/source-stripe/integration_tests/configured_catalog.json +++ b/airbyte-integrations/connectors/source-stripe/integration_tests/configured_catalog.json @@ -4,10 +4,12 @@ "stream": { "name": "accounts", "json_schema": {}, - "supported_sync_modes": ["full_refresh"], + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, "source_defined_primary_key": [["id"]] }, "primary_key": [["id"]], + "cursor_field": ["updated"], "sync_mode": "full_refresh", "destination_sync_mode": "overwrite" }, @@ -183,7 +185,9 @@ "stream": { "name": "customer_balance_transactions", "json_schema": {}, - "supported_sync_modes": ["full_refresh"], + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["created"], "source_defined_primary_key": [["id"]] }, "primary_key": [["id"]], @@ -320,10 +324,13 @@ "stream": { "name": "invoice_line_items", "json_schema": {}, - "supported_sync_modes": ["full_refresh"], + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated"], "source_defined_primary_key": [["id"]] }, "primary_key": [["id"]], + "cursor_field": ["updated"], "sync_mode": "full_refresh", "destination_sync_mode": "overwrite" }, @@ -369,6 +376,20 @@ "sync_mode": "full_refresh", "destination_sync_mode": "overwrite" }, + { + "stream": { + "name": "payout_balance_transactions", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated"], + "source_defined_primary_key": [["id"]] + }, + "primary_key": [["id"]], + "cursor_field": ["updated"], + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, { "stream": { "name": "payouts", @@ -527,10 +548,13 @@ "stream": { "name": "subscription_items", "json_schema": {}, - "supported_sync_modes": ["full_refresh"], + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated"], "source_defined_primary_key": [["id"]] }, "primary_key": [["id"]], + "cursor_field": ["updated"], "sync_mode": "full_refresh", "destination_sync_mode": "overwrite" }, @@ -594,10 +618,13 @@ "stream": { "name": "transfer_reversals", "json_schema": {}, - "supported_sync_modes": ["full_refresh"], + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["created"], "source_defined_primary_key": [["id"]] }, "primary_key": [["id"]], + "cursor_field": ["created"], "sync_mode": "full_refresh", "destination_sync_mode": "overwrite" }, diff --git a/airbyte-integrations/connectors/source-stripe/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-stripe/integration_tests/expected_records.jsonl index 74b5b36fe2ee..87f54ffd035c 100644 --- a/airbyte-integrations/connectors/source-stripe/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-stripe/integration_tests/expected_records.jsonl @@ -49,7 +49,6 @@ {"stream": "products", "data": {"id": "prod_KouQ5ez86yREmB", "object": "product", "active": true, "attributes": [], "created": 1640124902, "default_price": "price_1K9GbqEcXtiJtvvhJ3lZe4i5", "description": null, "features": [], "images": [], "livemode": false, "metadata": {}, "name": "edgao-test-product", "package_dimensions": null, "shippable": null, "statement_descriptor": null, "tax_code": "txcd_10000000", "type": "service", "unit_label": null, "updated": 1696839715, "url": null}, "emitted_at": 1697627307635} {"stream": "products", "data": {"id": "prod_NHcKselSHfKdfc", "object": "product", "active": true, "attributes": [], "created": 1675345504, "default_price": "price_1MX364EcXtiJtvvhE3WgTl4O", "description": "Test Product 1 description", "features": [], "images": ["https://files.stripe.com/links/MDB8YWNjdF8xSndub2lFY1h0aUp0dnZofGZsX3Rlc3RfdjBOT09UaHRiNVl2WmJ6clNYRUlmcFFD00cCBRNHnV"], "livemode": false, "metadata": {}, "name": "Test Product 1", "package_dimensions": null, "shippable": null, "statement_descriptor": null, "tax_code": "txcd_10301000", "type": "service", "unit_label": null, "updated": 1696839789, "url": null}, "emitted_at": 1697627307877} {"stream": "products", "data": {"id": "prod_NCgx1XP2IFQyKF", "object": "product", "active": true, "attributes": [], "created": 1674209524, "default_price": null, "description": null, "features": [], "images": [], "livemode": false, "metadata": {}, "name": "tu", "package_dimensions": null, "shippable": null, "statement_descriptor": null, "tax_code": "txcd_10000000", "type": "service", "unit_label": null, "updated": 1696839225, "url": null}, "emitted_at": 1697627307879} -{"stream":"subscription_schedule","data":{"id":"sub_sched_1PVzF9EcXtiJtvvhbyFup9qG","object":"subscription_schedule","application":null,"canceled_at":null,"completed_at":null,"created":1719421371,"current_phase":null,"customer":"cus_OV79K86ov5FMFM","default_settings":{"application_fee_percent":null,"automatic_tax":{"enabled":false,"liability":null},"billing_cycle_anchor":"automatic","billing_thresholds":null,"collection_method":"charge_automatically","default_payment_method":null,"default_source":null,"description":null,"invoice_settings":"{'account_tax_ids': None, 'days_until_due': None, 'issuer': {'type': 'self'}}","on_behalf_of":null,"transfer_data":null},"end_behavior":"cancel","livemode":false,"metadata":{},"phases":[{"add_invoice_items":[],"application_fee_percent":null,"billing_cycle_anchor":null,"billing_thresholds":null,"collection_method":null,"coupon":"4SUEGKZg","currency":"usd","default_payment_method":null,"default_tax_rates":[],"description":null,"discounts":[{"coupon":"4SUEGKZg","discount":null,"promotion_code":null}],"end_date":1727654400,"invoice_settings":"{'account_tax_ids': None, 'days_until_due': None, 'issuer': None}","items":[{"billing_thresholds":null,"discounts":[],"metadata":{},"plan":"price_1MSHZoEcXtiJtvvh6O8TYD8T","price":"price_1MSHZoEcXtiJtvvh6O8TYD8T","quantity":1,"tax_rates":[]}],"metadata":{},"on_behalf_of":null,"proration_behavior":"none","start_date":1724976000,"transfer_data":null,"trial_end":null}],"released_at":null,"released_subscription":null,"renewal_interval":null,"status":"not_started","subscription":null,"test_clock":null,"updated":1719421371},"emitted_at":1720516126323} {"stream": "transfers", "data": {"id": "tr_1NH18zEcXtiJtvvhnd827cNO", "object": "transfer", "amount": 10000, "amount_reversed": 0, "balance_transaction": "txn_1NH190EcXtiJtvvhBO3PeR7p", "created": 1686301085, "currency": "usd", "description": null, "destination": "acct_1Jx8unEYmRTj5on1", "destination_payment": "py_1NH18zEYmRTj5on1GkCCsqLK", "livemode": false, "metadata": {}, "reversals": {"object": "list", "data": [], "has_more": false, "total_count": 0.0, "url": "/v1/transfers/tr_1NH18zEcXtiJtvvhnd827cNO/reversals"}, "reversed": false, "source_transaction": null, "source_type": "card", "transfer_group": null, "updated": 1686301085}, "emitted_at": 1697627313262} {"stream": "transfers", "data": {"id": "tr_1NGoaCEcXtiJtvvhjmHtOGOm", "object": "transfer", "amount": 100, "amount_reversed": 100, "balance_transaction": "txn_1NGoaDEcXtiJtvvhsZrNMsdJ", "created": 1686252800, "currency": "usd", "description": null, "destination": "acct_1Jx8unEYmRTj5on1", "destination_payment": "py_1NGoaCEYmRTj5on1LAlAIG3a", "livemode": false, "metadata": {}, "reversals": {"object": "list", "data": [{"id": "trr_1NGolCEcXtiJtvvhOYPck3CP", "object": "transfer_reversal", "amount": 100, "balance_transaction": "txn_1NGolCEcXtiJtvvhZRy4Kd5S", "created": 1686253482, "currency": "usd", "destination_payment_refund": "pyr_1NGolBEYmRTj5on1STal3rmp", "metadata": {}, "source_refund": null, "transfer": "tr_1NGoaCEcXtiJtvvhjmHtOGOm"}], "has_more": false, "total_count": 1.0, "url": "/v1/transfers/tr_1NGoaCEcXtiJtvvhjmHtOGOm/reversals"}, "reversed": true, "source_transaction": null, "source_type": "card", "transfer_group": "ORDER10", "updated": 1686252800}, "emitted_at": 1697627313264} {"stream": "refunds", "data": {"id": "re_3MVuZyEcXtiJtvvh0A6rSbeJ", "object": "refund", "amount": 200000, "balance_transaction": "txn_3MVuZyEcXtiJtvvh0v0QyAMx", "charge": "ch_3MVuZyEcXtiJtvvh0tiVC7DI", "created": 1675074488, "currency": "usd", "destination_details": {"card": {"reference": "5871771120000631", "reference_status": "available", "reference_type": "acquirer_reference_number", "type": "refund"}, "type": "card"}, "metadata": {}, "payment_intent": "pi_3MVuZyEcXtiJtvvh07Ehi4cx", "reason": "fraudulent", "receipt_number": "3278-5368", "source_transfer_reversal": null, "status": "succeeded", "transfer_reversal": null}, "emitted_at": 1701882752716} @@ -58,6 +57,8 @@ {"stream": "payment_intents", "data": {"id": "pi_3K9FSOEcXtiJtvvh0AEIFllC", "object": "payment_intent", "amount": 5300, "amount_capturable": 0, "amount_details": {"tip": {}}, "amount_received": 5300, "application": null, "application_fee_amount": null, "automatic_payment_methods": null, "canceled_at": null, "cancellation_reason": null, "capture_method": "automatic", "client_secret": "pi_3K9FSOEcXtiJtvvh0AEIFllC_secret_uPUtIaSltgtW0qK7mLD0uF2Mr", "confirmation_method": "automatic", "created": 1640120472, "currency": "usd", "customer": null, "description": null, "invoice": null, "last_payment_error": null, "latest_charge": "ch_3K9FSOEcXtiJtvvh0zxb7clc", "livemode": false, "metadata": {}, "next_action": null, "on_behalf_of": null, "payment_method": null, "payment_method_configuration_details": null, "payment_method_options": {"card": {"installments": null, "mandate_options": null, "network": null, "request_three_d_secure": "automatic"}}, "payment_method_types": ["card"], "processing": null, "receipt_email": null, "review": null, "setup_future_usage": null, "shipping": null, "source": "src_1K9FSOEcXtiJtvvhHGu1qtOx", "statement_descriptor": "airbyte.io", "statement_descriptor_suffix": null, "status": "succeeded", "transfer_data": null, "transfer_group": null, "updated": 1640120472}, "emitted_at": 1697627315508} {"stream": "payment_intents", "data": {"id": "pi_3K9F5DEcXtiJtvvh16scJMp6", "object": "payment_intent", "amount": 4200, "amount_capturable": 0, "amount_details": {"tip": {}}, "amount_received": 4200, "application": null, "application_fee_amount": null, "automatic_payment_methods": null, "canceled_at": null, "cancellation_reason": null, "capture_method": "automatic", "client_secret": "pi_3K9F5DEcXtiJtvvh16scJMp6_secret_YwhzCTpXtfcKYeklXnPnysRRi", "confirmation_method": "automatic", "created": 1640119035, "currency": "usd", "customer": null, "description": "edgao test", "invoice": null, "last_payment_error": null, "latest_charge": "ch_3K9F5DEcXtiJtvvh1w2MaTpj", "livemode": false, "metadata": {}, "next_action": null, "on_behalf_of": null, "payment_method": null, "payment_method_configuration_details": null, "payment_method_options": {"card": {"installments": null, "mandate_options": null, "network": null, "request_three_d_secure": "automatic"}}, "payment_method_types": ["card"], "processing": null, "receipt_email": null, "review": null, "setup_future_usage": null, "shipping": null, "source": "src_1K9F5CEcXtiJtvvhrsZdur8Y", "statement_descriptor": "airbyte.io", "statement_descriptor_suffix": null, "status": "succeeded", "transfer_data": null, "transfer_group": null, "updated": 1640119035}, "emitted_at": 1697627315511} {"stream": "payment_intents", "data": {"id": "pi_3K9F4mEcXtiJtvvh18NKhEuo", "object": "payment_intent", "amount": 4200, "amount_capturable": 0, "amount_details": {"tip": {}}, "amount_received": 0, "application": null, "application_fee_amount": null, "automatic_payment_methods": null, "canceled_at": null, "cancellation_reason": null, "capture_method": "automatic", "client_secret": "pi_3K9F4mEcXtiJtvvh18NKhEuo_secret_pfUt7CTkPjVdJacycm0bMpdLt", "confirmation_method": "automatic", "created": 1640119008, "currency": "usd", "customer": null, "description": "edgao test", "invoice": null, "last_payment_error": {"charge": "ch_3K9F4mEcXtiJtvvh1kUzxjwN", "code": "card_declined", "decline_code": "test_mode_live_card", "doc_url": "https://stripe.com/docs/error-codes/card-declined", "message": "Your card was declined. Your request was in test mode, but used a non test (live) card. For a list of valid test cards, visit: https://stripe.com/docs/testing.", "source": {"id": "src_1K9F4hEcXtiJtvvhrUEwvCyi", "object": "source", "amount": null, "card": {"address_line1_check": null, "address_zip_check": null, "brand": "Visa", "country": "US", "cvc_check": "unchecked", "dynamic_last4": null, "exp_month": 9, "exp_year": 2028, "fingerprint": "Re3p4j8issXA77iI", "funding": "credit", "last4": "8097", "name": null, "three_d_secure": "optional", "tokenization_method": null}, "client_secret": "src_client_secret_b3v8YqNMLGykB120fqv2Tjhq", "created": 1640119003, "currency": null, "flow": "none", "livemode": false, "metadata": {}, "owner": {"address": null, "email": null, "name": null, "phone": null, "verified_address": null, "verified_email": null, "verified_name": null, "verified_phone": null}, "statement_descriptor": null, "status": "consumed", "type": "card", "usage": "reusable"}, "type": "card_error"}, "latest_charge": "ch_3K9F4mEcXtiJtvvh1kUzxjwN", "livemode": false, "metadata": {}, "next_action": null, "on_behalf_of": null, "payment_method": null, "payment_method_configuration_details": null, "payment_method_options": {"card": {"installments": null, "mandate_options": null, "network": null, "request_three_d_secure": "automatic"}}, "payment_method_types": ["card"], "processing": null, "receipt_email": null, "review": null, "setup_future_usage": null, "shipping": null, "source": null, "statement_descriptor": "airbyte.io", "statement_descriptor_suffix": null, "status": "requires_payment_method", "transfer_data": null, "transfer_group": null, "updated": 1640119008}, "emitted_at": 1697627315513} +{"stream":"payout_balance_transactions","data":{"payout":"po_1MTErVEcXtiJtvvhPP5x9VRX","updated":1674437417,"id":"txn_1MSI78EcXtiJtvvhAGjxP1UM","object":"balance_transaction","amount":-700,"available_on":1674518400,"created":1674211590,"currency":"usd","description":"Chargeback withdrawal for ch_3MSI77EcXtiJtvvh1GzoukUC","fee":1500,"fee_details":[{"amount":1500,"application":null,"currency":"usd","description":"Dispute fee","type":"stripe_fee"}],"net":-2200,"reporting_category":"dispute","source":"dp_1MSI78EcXtiJtvvhxC77m2kh","status":"available","type":"adjustment"},"emitted_at":1734032137962} +{"stream":"payout_balance_transactions","data":{"payout":"po_1MTErVEcXtiJtvvhPP5x9VRX","updated":1674437417,"id":"txn_3MSI77EcXtiJtvvh1vvRye5q","object":"balance_transaction","amount":700,"available_on":1674518400,"created":1674211589,"currency":"usd","description":"Test","fee":54,"fee_details":[{"amount":54,"application":null,"currency":"usd","description":"Stripe processing fees","type":"stripe_fee"}],"net":646,"reporting_category":"charge","source":"ch_3MSI77EcXtiJtvvh1GzoukUC","status":"available","type":"charge"},"emitted_at":1734032137962} {"stream": "promotion_codes", "data": {"id": "promo_1MVtmyEcXtiJtvvhkV5jPFPU", "object": "promotion_code", "active": true, "code": "g20", "coupon": {"id": "iJ6qlwM5", "object": "coupon", "amount_off": null, "created": 1674208993, "currency": null, "duration": "forever", "duration_in_months": null, "livemode": false, "max_redemptions": null, "metadata": {}, "name": "\u0415\u0443\u0456\u0435", "percent_off": 10.0, "redeem_by": null, "times_redeemed": 3, "valid": true}, "created": 1675071396, "customer": null, "expires_at": null, "livemode": false, "max_redemptions": null, "metadata": {}, "restrictions": {"first_time_transaction": false, "minimum_amount": null, "minimum_amount_currency": null}, "times_redeemed": 0, "updated": 1675071396}, "emitted_at": 1697627317910} {"stream": "promotion_codes", "data": {"id": "promo_1MVtmkEcXtiJtvvht0RA3MKg", "object": "promotion_code", "active": true, "code": "FRIENDS20", "coupon": {"id": "iJ6qlwM5", "object": "coupon", "amount_off": null, "created": 1674208993, "currency": null, "duration": "forever", "duration_in_months": null, "livemode": false, "max_redemptions": null, "metadata": {}, "name": "\u0415\u0443\u0456\u0435", "percent_off": 10.0, "redeem_by": null, "times_redeemed": 3, "valid": true}, "created": 1675071382, "customer": null, "expires_at": null, "livemode": false, "max_redemptions": null, "metadata": {}, "restrictions": {"first_time_transaction": true, "minimum_amount": 10000, "minimum_amount_currency": "usd"}, "times_redeemed": 0, "updated": 1675071382}, "emitted_at": 1697627317911} {"stream": "setup_intents", "data": {"id": "seti_1KnfIjEcXtiJtvvhPw5znVKY", "object": "setup_intent", "application": null, "automatic_payment_methods": null, "cancellation_reason": null, "client_secret": "seti_1KnfIjEcXtiJtvvhPw5znVKY_secret_LUebPsqMz6AF4ivxIg4LMaAT0OdZF5L", "created": 1649752937, "customer": null, "description": null, "flow_directions": null, "last_setup_error": null, "latest_attempt": "setatt_1KnfIjEcXtiJtvvhqDfSlpM4", "livemode": false, "mandate": null, "metadata": {}, "next_action": null, "on_behalf_of": null, "payment_method": "pm_1KnfIj2eZvKYlo2CAlv2Vhqc", "payment_method_configuration_details": null, "payment_method_options": {"acss_debit": {"currency": "cad", "mandate_options": {"interval_description": "First day of every month", "payment_schedule": "interval", "transaction_type": "personal"}, "verification_method": "automatic"}}, "payment_method_types": ["acss_debit"], "single_use_mandate": null, "status": "succeeded", "usage": "off_session", "updated": 1649752937}, "emitted_at": 1697627319186} diff --git a/airbyte-integrations/connectors/source-stripe/main.py b/airbyte-integrations/connectors/source-stripe/main.py index 971f33a69dd1..e81b1f8f0da5 100644 --- a/airbyte-integrations/connectors/source-stripe/main.py +++ b/airbyte-integrations/connectors/source-stripe/main.py @@ -5,5 +5,6 @@ from source_stripe.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-stripe/metadata.yaml b/airbyte-integrations/connectors/source-stripe/metadata.yaml index 6b9716d12846..d823cbea97bf 100644 --- a/airbyte-integrations/connectors/source-stripe/metadata.yaml +++ b/airbyte-integrations/connectors/source-stripe/metadata.yaml @@ -10,7 +10,7 @@ data: connectorSubtype: api connectorType: source definitionId: e094cb9a-26de-4645-8761-65c0c425d1de - dockerImageTag: 5.6.2 + dockerImageTag: 5.8.2 dockerRepository: airbyte/source-stripe documentationUrl: https://docs.airbyte.com/integrations/sources/stripe erdUrl: https://dbdocs.io/airbyteio/source-stripe?view=relationships diff --git a/airbyte-integrations/connectors/source-stripe/pyproject.toml b/airbyte-integrations/connectors/source-stripe/pyproject.toml index 67531a49f17b..86b794867c91 100644 --- a/airbyte-integrations/connectors/source-stripe/pyproject.toml +++ b/airbyte-integrations/connectors/source-stripe/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "5.6.2" +version = "5.8.2" name = "source-stripe" description = "Source implementation for Stripe." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-stripe/sample_files/state.json b/airbyte-integrations/connectors/source-stripe/sample_files/state.json index a3d34d59ba76..ec0445b17365 100644 --- a/airbyte-integrations/connectors/source-stripe/sample_files/state.json +++ b/airbyte-integrations/connectors/source-stripe/sample_files/state.json @@ -14,5 +14,7 @@ "payouts": { "created": 1617067556 }, "disputes": { "created": 1610996305 }, "products": { "created": 1585511341 }, - "refunds": { "created": 1619595629 } + "refunds": { "created": 1619595629 }, + "invoice_line_items": { "created": 1619595629 }, + "subscription_items": { "created": 1619595629 } } diff --git a/airbyte-integrations/connectors/source-stripe/source_stripe/error_handlers/parent_incremental_stripe_sub_stream_error_handler.py b/airbyte-integrations/connectors/source-stripe/source_stripe/error_handlers/parent_incremental_stripe_sub_stream_error_handler.py index 7365b5902b93..c909371d1ede 100644 --- a/airbyte-integrations/connectors/source-stripe/source_stripe/error_handlers/parent_incremental_stripe_sub_stream_error_handler.py +++ b/airbyte-integrations/connectors/source-stripe/source_stripe/error_handlers/parent_incremental_stripe_sub_stream_error_handler.py @@ -5,6 +5,7 @@ from typing import Optional, Union import requests + from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution from source_stripe.error_handlers.stripe_error_handler import StripeErrorHandler diff --git a/airbyte-integrations/connectors/source-stripe/source_stripe/error_handlers/stripe_error_handler.py b/airbyte-integrations/connectors/source-stripe/source_stripe/error_handlers/stripe_error_handler.py index a9fc2f3e9307..315b03c9dbde 100644 --- a/airbyte-integrations/connectors/source-stripe/source_stripe/error_handlers/stripe_error_handler.py +++ b/airbyte-integrations/connectors/source-stripe/source_stripe/error_handlers/stripe_error_handler.py @@ -6,11 +6,13 @@ from typing import Optional, Union import requests + from airbyte_cdk.models import FailureType from airbyte_cdk.sources.streams.http import HttpStream from airbyte_cdk.sources.streams.http.error_handlers import HttpStatusErrorHandler from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, ResponseAction + STRIPE_ERROR_CODES = { "more_permissions_required": "This is most likely due to insufficient permissions on the credentials in use. " "Try to grant required permissions/scopes or re-authenticate", diff --git a/airbyte-integrations/connectors/source-stripe/source_stripe/error_mappings/parent_incremental_stripe_sub_stream_error_mapping.py b/airbyte-integrations/connectors/source-stripe/source_stripe/error_mappings/parent_incremental_stripe_sub_stream_error_mapping.py index 732ac748556d..70cb8d1d425e 100644 --- a/airbyte-integrations/connectors/source-stripe/source_stripe/error_mappings/parent_incremental_stripe_sub_stream_error_mapping.py +++ b/airbyte-integrations/connectors/source-stripe/source_stripe/error_mappings/parent_incremental_stripe_sub_stream_error_mapping.py @@ -5,6 +5,7 @@ from airbyte_cdk.sources.streams.http.error_handlers.default_error_mapping import DEFAULT_ERROR_MAPPING from airbyte_cdk.sources.streams.http.error_handlers.response_models import ErrorResolution, ResponseAction + PARENT_INCREMENTAL_STRIPE_SUB_STREAM_ERROR_MAPPING = DEFAULT_ERROR_MAPPING | { 404: ErrorResolution( response_action=ResponseAction.IGNORE, diff --git a/airbyte-integrations/connectors/source-stripe/source_stripe/run.py b/airbyte-integrations/connectors/source-stripe/source_stripe/run.py index 37263eabb998..e6878a153f19 100644 --- a/airbyte-integrations/connectors/source-stripe/source_stripe/run.py +++ b/airbyte-integrations/connectors/source-stripe/source_stripe/run.py @@ -8,9 +8,10 @@ from datetime import datetime from typing import List +from orjson import orjson + from airbyte_cdk.entrypoint import AirbyteEntrypoint, launch from airbyte_cdk.models import AirbyteErrorTraceMessage, AirbyteMessage, AirbyteMessageSerializer, AirbyteTraceMessage, TraceType, Type -from orjson import orjson from source_stripe import SourceStripe diff --git a/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/accounts.json b/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/accounts.json index c9ddccdfefb7..8b2cf5bb4a81 100644 --- a/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/accounts.json +++ b/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/accounts.json @@ -332,6 +332,10 @@ "description": "The timestamp when the account was created.", "type": ["null", "integer"] }, + "updated": { + "description": "The timestamp when the account was updated.", + "type": ["null", "integer"] + }, "default_currency": { "description": "The default currency used for transactions.", "type": ["null", "string"] diff --git a/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/customer_balance_transactions.json b/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/customer_balance_transactions.json index 65184e73ae42..fd0691a251ef 100644 --- a/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/customer_balance_transactions.json +++ b/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/customer_balance_transactions.json @@ -18,6 +18,10 @@ "description": "The date and time when the transaction was created", "type": ["null", "integer"] }, + "updated": { + "description": "The date and time when the transaction was created", + "type": ["null", "integer"] + }, "credit_note": { "description": "Credit note related to the balance transaction", "type": ["null", "string"] diff --git a/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/invoice_line_items.json b/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/invoice_line_items.json index 39257d3c25e0..40dcbca50258 100644 --- a/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/invoice_line_items.json +++ b/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/invoice_line_items.json @@ -297,6 +297,14 @@ } } } + }, + "invoice_created": { + "description": "Timestamp for when the parent invoice was created", + "type": ["null", "integer"] + }, + "invoice_updated": { + "description": "Timestamp for when the parent invoice was last updated", + "type": ["null", "integer"] } } } diff --git a/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/payout_balance_transactions.json b/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/payout_balance_transactions.json new file mode 100644 index 000000000000..6e33b8c2bd48 --- /dev/null +++ b/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/payout_balance_transactions.json @@ -0,0 +1,78 @@ +{ + "$schema": "https://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "type": ["object", "null"], + "properties": { + "payout": { + "type": ["null", "string"] + }, + "fee": { + "type": ["null", "integer"] + }, + "currency": { + "type": ["null", "string"] + }, + "source": { + "type": ["null", "string"] + }, + "fee_details": { + "type": ["null", "array"], + "items": { + "properties": { + "application": { + "type": ["null", "string"] + }, + "type": { + "type": ["null", "string"] + }, + "description": { + "type": ["null", "string"] + }, + "amount": { + "type": ["null", "integer"] + }, + "currency": { + "type": ["null", "string"] + } + }, + "type": ["null", "object"] + } + }, + "available_on": { + "type": ["null", "integer"] + }, + "status": { + "type": ["null", "string"] + }, + "description": { + "type": ["null", "string"] + }, + "net": { + "type": ["null", "integer"] + }, + "exchange_rate": { + "type": ["null", "number"] + }, + "type": { + "type": ["null", "string"] + }, + "id": { + "type": ["null", "string"] + }, + "object": { + "type": ["null", "string"] + }, + "created": { + "type": ["null", "integer"] + }, + "updated": { + "type": ["null", "integer"] + }, + "amount": { + "type": ["null", "integer"] + }, + "reporting_category": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/subscription_items.json b/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/subscription_items.json index caa665b79a0b..2258a02b828e 100644 --- a/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/subscription_items.json +++ b/airbyte-integrations/connectors/source-stripe/source_stripe/schemas/subscription_items.json @@ -217,6 +217,10 @@ "price": { "description": "Price of the subscription item.", "$ref": "price.json" + }, + "subscription_updated": { + "description": "The timestamp at which the subscription was last updated.", + "type": ["null", "integer"] } } } diff --git a/airbyte-integrations/connectors/source-stripe/source_stripe/source.py b/airbyte-integrations/connectors/source-stripe/source_stripe/source.py index 14aa19ff31a5..7002a36f5a4a 100644 --- a/airbyte-integrations/connectors/source-stripe/source_stripe/source.py +++ b/airbyte-integrations/connectors/source-stripe/source_stripe/source.py @@ -8,6 +8,7 @@ from typing import Any, List, Mapping, MutableMapping, Optional, Tuple import pendulum + from airbyte_cdk.entrypoint import logger as entrypoint_logger from airbyte_cdk.models import ConfiguredAirbyteCatalog, FailureType, SyncMode from airbyte_cdk.sources.concurrent_source.concurrent_source import ConcurrentSource @@ -24,10 +25,9 @@ from airbyte_cdk.utils.traced_exception import AirbyteTracedException from source_stripe.streams import ( CreatedCursorIncrementalStripeStream, - CustomerBalanceTransactions, Events, IncrementalStripeStream, - ParentIncrementalStipeSubStream, + ParentIncrementalStripeSubStream, SetupAttempts, StripeLazySubStream, StripeStream, @@ -37,6 +37,7 @@ UpdatedCursorIncrementalStripeSubStream, ) + logger = logging.getLogger("airbyte") _MAX_CONCURRENCY = 20 @@ -47,7 +48,6 @@ class SourceStripe(ConcurrentSourceAdapter): - message_repository = InMemoryMessageRepository(entrypoint_logger.level) _SLICE_BOUNDARY_FIELDS_BY_IMPLEMENTATION = { Events: ("created[gte]", "created[lte]"), @@ -206,13 +206,19 @@ def streams(self, config: MutableMapping[str, Any]) -> List[Stream]: ], **args, ) - subscription_items = StripeLazySubStream( + subscription_items = UpdatedCursorIncrementalStripeLazySubStream( name="subscription_items", path="subscription_items", - extra_request_params=lambda self, stream_slice, *args, **kwargs: {"subscription": stream_slice["parent"]["id"]}, parent=subscriptions, + extra_request_params=lambda self, stream_slice, *args, **kwargs: {"subscription": stream_slice["parent"]["id"]}, + slice_data_retriever=lambda record, stream_slice: { + **record, + "subscription_updated": stream_slice["parent"]["updated"], + }, + cursor_field="subscription_updated", use_cache=USE_CACHE, sub_items_attr="items", + event_types=["customer.subscription.created", "customer.subscription.updated"], **args, ) transfers = IncrementalStripeStream( @@ -269,9 +275,22 @@ def streams(self, config: MutableMapping[str, Any]) -> List[Stream]: **args, ) + payouts = IncrementalStripeStream( + name="payouts", + path="payouts", + event_types=[ + "payout.canceled", + "payout.created", + "payout.failed", + "payout.paid", + "payout.reconciliation_completed", + "payout.updated", + ], + **args, + ) + streams = [ checkout_sessions, - CustomerBalanceTransactions(**args), Events(**incremental_args), UpdatedCursorIncrementalStripeStream( name="external_account_cards", @@ -299,7 +318,19 @@ def streams(self, config: MutableMapping[str, Any]) -> List[Stream]: **args, ), SetupAttempts(**incremental_args), - StripeStream(name="accounts", path="accounts", use_cache=USE_CACHE, **args), + UpdatedCursorIncrementalStripeStream( + name="accounts", + path="accounts", + legacy_cursor_field="created", + event_types=[ + "account.updated", + "account.external_account.created", + "account.external_account.updated", + "account.external_account.deleted", + ], + use_cache=USE_CACHE, + **args, + ), CreatedCursorIncrementalStripeStream(name="shipping_rates", path="shipping_rates", **incremental_args), CreatedCursorIncrementalStripeStream(name="balance_transactions", path="balance_transactions", **incremental_args), CreatedCursorIncrementalStripeStream(name="files", path="files", **incremental_args), @@ -384,17 +415,18 @@ def streams(self, config: MutableMapping[str, Any]) -> List[Stream]: ], **args, ), - IncrementalStripeStream( - name="payouts", - path="payouts", - event_types=[ - "payout.canceled", - "payout.created", - "payout.failed", - "payout.paid", - "payout.reconciliation_completed", - "payout.updated", - ], + payouts, + ParentIncrementalStripeSubStream( + name="payout_balance_transactions", + path=lambda self, stream_slice, *args, **kwargs: "balance_transactions", + parent=payouts, + cursor_field="updated", + slice_data_retriever=lambda record, stream_slice: { + "payout": stream_slice["parent"]["id"], + "updated": stream_slice["parent"]["updated"], + **record, + }, + extra_request_params=lambda self, stream_slice, *args, **kwargs: {"payout": f"{stream_slice['parent']['id']}"}, **args, ), IncrementalStripeStream( @@ -473,6 +505,13 @@ def streams(self, config: MutableMapping[str, Any]) -> List[Stream]: event_types=["topup.canceled", "topup.created", "topup.failed", "topup.reversed", "topup.succeeded"], **args, ), + ParentIncrementalStripeSubStream( + name="customer_balance_transactions", + path=lambda self, stream_slice, *args, **kwargs: f"customers/{stream_slice['parent']['id']}/balance_transactions", + parent=self.customers(**args), + cursor_field="created", + **args, + ), UpdatedCursorIncrementalStripeLazySubStream( name="application_fees_refunds", path=lambda self, stream_slice, *args, **kwargs: f"application_fees/{stream_slice['parent']['id']}/refunds", @@ -498,7 +537,7 @@ def streams(self, config: MutableMapping[str, Any]) -> List[Stream]: response_filter=lambda record: record["object"] == "bank_account", **args, ), - ParentIncrementalStipeSubStream( + ParentIncrementalStripeSubStream( name="checkout_sessions_line_items", path=lambda self, stream_slice, *args, **kwargs: f"checkout/sessions/{stream_slice['parent']['id']}/line_items", parent=checkout_sessions, @@ -513,24 +552,42 @@ def streams(self, config: MutableMapping[str, Any]) -> List[Stream]: }, **args, ), - StripeLazySubStream( + UpdatedCursorIncrementalStripeLazySubStream( name="invoice_line_items", path=lambda self, stream_slice, *args, **kwargs: f"invoices/{stream_slice['parent']['id']}/lines", parent=invoices, + cursor_field="invoice_updated", + event_types=[ + "invoice.created", + "invoice.deleted", + "invoice.updated", + # the event type = "invoice.upcoming" doesn't contain the `primary_key = `id` field, + # thus isn't used, see the doc: https://docs.stripe.com/api/invoices/object#invoice_object-id + # reference issue: https://github.com/airbytehq/oncall/issues/5560 + ], sub_items_attr="lines", - slice_data_retriever=lambda record, stream_slice: {"invoice_id": stream_slice["parent"]["id"], **record}, + slice_data_retriever=lambda record, stream_slice: { + "invoice_id": stream_slice["parent"]["id"], + "invoice_created": stream_slice["parent"]["created"], + "invoice_updated": stream_slice["parent"]["updated"], + **record, + }, **args, ), subscription_items, - StripeSubStream( + ParentIncrementalStripeSubStream( name="transfer_reversals", path=lambda self, stream_slice, *args, **kwargs: f"transfers/{stream_slice['parent']['id']}/reversals", parent=transfers, + cursor_field="created", **args, ), StripeSubStream( name="usage_records", - path=lambda self, stream_slice, *args, **kwargs: f"subscription_items/{stream_slice['parent']['id']}/usage_record_summaries", + path=lambda self, + stream_slice, + *args, + **kwargs: f"subscription_items/{stream_slice['parent']['id']}/usage_record_summaries", parent=subscription_items, primary_key=None, **args, diff --git a/airbyte-integrations/connectors/source-stripe/source_stripe/streams.py b/airbyte-integrations/connectors/source-stripe/source_stripe/streams.py index 199fa0135cf6..3f1ca33aefea 100644 --- a/airbyte-integrations/connectors/source-stripe/source_stripe/streams.py +++ b/airbyte-integrations/connectors/source-stripe/source_stripe/streams.py @@ -11,6 +11,7 @@ import pendulum import requests + from airbyte_cdk import BackoffStrategy from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.declarative.requesters.error_handlers.backoff_strategies import ExponentialBackoffStrategy @@ -24,6 +25,7 @@ from source_stripe.error_handlers import ParentIncrementalStripeSubStreamErrorHandler, StripeErrorHandler from source_stripe.error_mappings import PARENT_INCREMENTAL_STRIPE_SUB_STREAM_ERROR_MAPPING + STRIPE_API_VERSION = "2022-11-15" CACHE_DISABLED = os.environ.get("CACHE_DISABLED") IS_TESTING = os.environ.get("DEPLOYMENT_MODE") == "testing" @@ -84,7 +86,6 @@ def extract_records( if self.cursor_field in record: yield record continue # Skip the rest of the loop iteration - # fetch legacy_cursor_field from record; default to current timestamp for initial syncs without an any cursor. current_cursor_value = record.get(self.legacy_cursor_field, pendulum.now().int_timestamp) @@ -523,40 +524,6 @@ def read_records( yield from self.parent_stream.read_records(sync_mode, cursor_field, stream_slice, stream_state) -class CustomerBalanceTransactions(StripeStream): - """ - API docs: https://stripe.com/docs/api/customer_balance_transactions/list - """ - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.parent = IncrementalStripeStream( - name="customers", - path="customers", - use_cache=USE_CACHE, - event_types=["customer.created", "customer.updated", "customer.deleted"], - authenticator=kwargs.get("authenticator"), - account_id=self.account_id, - start_date=self.start_date, - ) - - def path(self, stream_slice: Mapping[str, Any] = None, **kwargs): - return f"customers/{stream_slice['id']}/balance_transactions" - - def stream_slices( - self, sync_mode: SyncMode, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None - ) -> Iterable[Optional[Mapping[str, Any]]]: - slices = self.parent.stream_slices(sync_mode=SyncMode.full_refresh) - for _slice in slices: - for customer in self.parent.read_records(sync_mode=SyncMode.full_refresh, stream_slice=_slice): - # we use `get` here because some attributes may not be returned by some API versions - if customer.get("next_invoice_sequence") == 1 and customer.get("balance") == 0: - # We're making this check in order to speed up a sync. if a customer's balance is 0 and there are no - # associated invoices, he shouldn't have any balance transactions. So we're saving time of one API call per customer. - continue - yield customer - - class SetupAttempts(CreatedCursorIncrementalStripeStream, HttpSubStream): """ Docs: https://stripe.com/docs/api/setup_attempts/list @@ -738,7 +705,10 @@ def __init__( parent=parent, sub_items_attr=sub_items_attr, record_extractor=UpdatedCursorIncrementalRecordExtractor( - cursor_field=cursor_field, legacy_cursor_field=legacy_cursor_field, response_filter=response_filter + cursor_field=cursor_field, + legacy_cursor_field=legacy_cursor_field, + response_filter=response_filter, + slice_data_retriever=kwargs.get("slice_data_retriever"), ), **kwargs, ) @@ -779,7 +749,7 @@ def read_records( ) -class ParentIncrementalStipeSubStream(StripeSubStream): +class ParentIncrementalStripeSubStream(StripeSubStream): is_resumable = True """ This stream differs from others in that it runs parent stream in exactly same sync mode it is run itself to generate stream slices. diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/conftest.py b/airbyte-integrations/connectors/source-stripe/unit_tests/conftest.py index f0bcd0cb9e71..da3a15fd2e0f 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/conftest.py @@ -5,10 +5,12 @@ import os import pytest + from airbyte_cdk.sources.streams.concurrent.adapters import StreamFacade from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator from airbyte_cdk.test.state_builder import StateBuilder + os.environ["CACHE_DISABLED"] = "true" os.environ["DEPLOYMENT_MODE"] = "testing" diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/request_builder.py b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/request_builder.py index d45ab6e3b5b2..336179ea05b3 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/request_builder.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/request_builder.py @@ -20,6 +20,10 @@ def application_fees_endpoint(cls, account_id: str, client_secret: str) -> "Stri def application_fees_refunds_endpoint(cls, application_fee_id: str, account_id: str, client_secret: str) -> "StripeRequestBuilder": return cls(f"application_fees/{application_fee_id}/refunds", account_id, client_secret) + @classmethod + def balance_transactions_endpoint(cls, account_id: str, client_secret: str) -> "StripeRequestBuilder": + return cls("balance_transactions", account_id, client_secret) + @classmethod def customers_endpoint(cls, account_id: str, client_secret: str) -> "StripeRequestBuilder": return cls("customers", account_id, client_secret) @@ -52,6 +56,10 @@ def issuing_transactions_endpoint(cls, account_id: str, client_secret: str) -> " def payment_methods_endpoint(cls, customer_id: str, account_id: str, client_secret: str) -> "StripeRequestBuilder": return cls(f"customers/{customer_id}/payment_methods", account_id, client_secret) + @classmethod + def payouts_endpoint(cls, account_id: str, client_secret: str) -> "StripeRequestBuilder": + return cls("payouts", account_id, client_secret) + @classmethod def persons_endpoint( cls, @@ -82,6 +90,7 @@ def __init__(self, resource: str, account_id: str, client_secret: str) -> None: self._created_lte: Optional[datetime] = None self._limit: Optional[int] = None self._object: Optional[str] = None + self._payout: Optional[str] = None self._starting_after_id: Optional[str] = None self._types: List[str] = [] self._expands: List[str] = [] @@ -118,6 +127,10 @@ def with_expands(self, expands: List[str]) -> "StripeRequestBuilder": self._expands = expands return self + def with_payout(self, payout: str) -> "StripeRequestBuilder": + self._payout = payout + return self + def build(self) -> HttpRequest: query_params = {} if self._created_gte: @@ -135,6 +148,8 @@ def build(self) -> HttpRequest: query_params["type"] = self._types if self._object: query_params["object"] = self._object + if self._payout: + query_params["payout"] = self._payout if self._expands: query_params["expand[]"] = self._expands diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_accounts.py b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_accounts.py index 35c72a193874..ce2e72a67d48 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_accounts.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_accounts.py @@ -4,6 +4,8 @@ from unittest import TestCase import freezegun +from source_stripe import SourceStripe + from airbyte_cdk.models import ConfiguredAirbyteCatalog, SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import read @@ -20,7 +22,7 @@ from integration.config import ConfigBuilder from integration.pagination import StripePaginationStrategy from integration.request_builder import StripeRequestBuilder -from source_stripe import SourceStripe + _STREAM_NAME = "accounts" _ACCOUNT_ID = "acct_1G9HZLIEn49ers" diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_application_fees.py b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_application_fees.py index 9e8ca1c2628c..dd7a36ebd56a 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_application_fees.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_application_fees.py @@ -6,6 +6,8 @@ from unittest.mock import patch import freezegun +from source_stripe import SourceStripe + from airbyte_cdk.models import AirbyteStateBlob, AirbyteStateMessage, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.sources.streams.http.error_handlers.http_status_error_handler import HttpStatusErrorHandler from airbyte_cdk.test.catalog_builder import CatalogBuilder @@ -26,7 +28,7 @@ from integration.pagination import StripePaginationStrategy from integration.request_builder import StripeRequestBuilder from integration.response_builder import a_response_with_status -from source_stripe import SourceStripe + _EVENT_TYPES = ["application_fee.created", "application_fee.refunded"] diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_application_fees_refunds.py b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_application_fees_refunds.py index 1e8b500ea988..8581688de825 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_application_fees_refunds.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_application_fees_refunds.py @@ -8,6 +8,8 @@ from unittest.mock import patch import freezegun +from source_stripe import SourceStripe + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.sources.source import TState from airbyte_cdk.sources.streams.http.error_handlers.http_status_error_handler import HttpStatusErrorHandler @@ -29,7 +31,7 @@ from integration.pagination import StripePaginationStrategy from integration.request_builder import StripeRequestBuilder from integration.response_builder import a_response_with_status -from source_stripe import SourceStripe + _EVENT_TYPES = ["application_fee.refund.updated"] diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_authorizations.py b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_authorizations.py index cdb0da90e26a..c4a29d2d42d6 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_authorizations.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_authorizations.py @@ -6,6 +6,8 @@ from unittest.mock import patch import freezegun +from source_stripe import SourceStripe + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.sources.source import TState from airbyte_cdk.sources.streams.http.error_handlers.http_status_error_handler import HttpStatusErrorHandler @@ -27,7 +29,7 @@ from integration.pagination import StripePaginationStrategy from integration.request_builder import StripeRequestBuilder from integration.response_builder import a_response_with_status -from source_stripe import SourceStripe + _EVENT_TYPES = ["issuing_authorization.created", "issuing_authorization.request", "issuing_authorization.updated"] diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_bank_accounts.py b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_bank_accounts.py index bafb8da0bb45..92abc3a33af2 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_bank_accounts.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_bank_accounts.py @@ -8,6 +8,8 @@ from unittest.mock import patch import freezegun +from source_stripe import SourceStripe + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.sources.source import TState from airbyte_cdk.sources.streams.http.error_handlers.http_status_error_handler import HttpStatusErrorHandler @@ -29,7 +31,7 @@ from integration.pagination import StripePaginationStrategy from integration.request_builder import StripeRequestBuilder from integration.response_builder import a_response_with_status -from source_stripe import SourceStripe + _EVENT_TYPES = ["customer.source.created", "customer.source.expiring", "customer.source.updated", "customer.source.deleted"] diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_cards.py b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_cards.py index 660564ea9620..d1c037ea9e65 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_cards.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_cards.py @@ -6,6 +6,8 @@ from unittest.mock import patch import freezegun +from source_stripe import SourceStripe + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.sources.source import TState from airbyte_cdk.sources.streams.http.error_handlers.http_status_error_handler import HttpStatusErrorHandler @@ -27,7 +29,7 @@ from integration.pagination import StripePaginationStrategy from integration.request_builder import StripeRequestBuilder from integration.response_builder import a_response_with_status -from source_stripe import SourceStripe + _EVENT_TYPES = ["issuing_card.created", "issuing_card.updated"] diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_early_fraud_warnings.py b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_early_fraud_warnings.py index b64ba61d6db8..7e0c41a080f4 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_early_fraud_warnings.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_early_fraud_warnings.py @@ -6,6 +6,8 @@ from unittest.mock import patch import freezegun +from source_stripe import SourceStripe + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.sources.source import TState from airbyte_cdk.sources.streams.http.error_handlers.http_status_error_handler import HttpStatusErrorHandler @@ -27,7 +29,7 @@ from integration.pagination import StripePaginationStrategy from integration.request_builder import StripeRequestBuilder from integration.response_builder import a_response_with_status -from source_stripe import SourceStripe + _EVENT_TYPES = ["radar.early_fraud_warning.created", "radar.early_fraud_warning.updated"] diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_events.py b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_events.py index 87c5494b755e..4215ead25260 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_events.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_events.py @@ -6,6 +6,8 @@ from unittest.mock import patch import freezegun +from source_stripe import SourceStripe + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.sources.source import TState from airbyte_cdk.sources.streams.http.error_handlers.http_status_error_handler import HttpStatusErrorHandler @@ -26,7 +28,7 @@ from integration.pagination import StripePaginationStrategy from integration.request_builder import StripeRequestBuilder from integration.response_builder import a_response_with_status -from source_stripe import SourceStripe + _STREAM_NAME = "events" _NOW = datetime.now(timezone.utc) diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_external_account_bank_accounts.py b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_external_account_bank_accounts.py index c9f7142af059..95ae64e494a7 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_external_account_bank_accounts.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_external_account_bank_accounts.py @@ -6,6 +6,8 @@ from unittest.mock import patch import freezegun +from source_stripe import SourceStripe + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.sources.source import TState from airbyte_cdk.sources.streams.http.error_handlers.http_status_error_handler import HttpStatusErrorHandler @@ -27,7 +29,7 @@ from integration.pagination import StripePaginationStrategy from integration.request_builder import StripeRequestBuilder from integration.response_builder import a_response_with_status -from source_stripe import SourceStripe + _EVENT_TYPES = ["account.external_account.created", "account.external_account.updated", "account.external_account.deleted"] diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_external_account_cards.py b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_external_account_cards.py index 918cab91a40d..3e4f6c2adfa7 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_external_account_cards.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_external_account_cards.py @@ -6,6 +6,8 @@ from unittest.mock import patch import freezegun +from source_stripe import SourceStripe + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.sources.source import TState from airbyte_cdk.sources.streams.http.error_handlers.http_status_error_handler import HttpStatusErrorHandler @@ -27,7 +29,7 @@ from integration.pagination import StripePaginationStrategy from integration.request_builder import StripeRequestBuilder from integration.response_builder import a_response_with_status -from source_stripe import SourceStripe + _EVENT_TYPES = ["account.external_account.created", "account.external_account.updated", "account.external_account.deleted"] diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_payment_methods.py b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_payment_methods.py index f41f2efbbbf5..1c9bb3a5e2af 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_payment_methods.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_payment_methods.py @@ -6,6 +6,8 @@ from unittest.mock import patch import freezegun +from source_stripe import SourceStripe + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.sources.source import TState from airbyte_cdk.sources.streams.http.error_handlers.http_status_error_handler import HttpStatusErrorHandler @@ -28,7 +30,7 @@ from integration.request_builder import StripeRequestBuilder from integration.response_builder import a_response_with_status from integration.test_bank_accounts import _a_customer, _customers_response -from source_stripe import SourceStripe + _EVENT_TYPES = ["payment_method.*"] @@ -105,12 +107,7 @@ class FullRefreshTest(TestCase): def test_given_one_page_when_read_then_return_records(self, http_mocker: HttpMocker) -> None: http_mocker.get( StripeRequestBuilder.customers_endpoint(_ACCOUNT_ID, _CLIENT_SECRET).with_any_query_params().build(), - _customers_response() - .with_record( - _a_customer() - .with_id("parent_id") - ) - .build(), + _customers_response().with_record(_a_customer().with_id("parent_id")).build(), ) http_mocker.get( _payment_methods_request("parent_id").with_limit(100).build(), @@ -125,12 +122,7 @@ def test_given_one_page_when_read_then_return_records(self, http_mocker: HttpMoc def test_given_two_pages_when_read_then_return_records(self, http_mocker: HttpMocker) -> None: http_mocker.get( StripeRequestBuilder.customers_endpoint(_ACCOUNT_ID, _CLIENT_SECRET).with_any_query_params().build(), - _customers_response() - .with_record( - _a_customer() - .with_id("parent_id") - ) - .build(), + _customers_response().with_record(_a_customer().with_id("parent_id")).build(), ) http_mocker.get( _payment_methods_request("parent_id").with_limit(100).build(), @@ -152,12 +144,7 @@ def test_given_two_pages_when_read_then_return_records(self, http_mocker: HttpMo def test_when_read_then_add_cursor_field(self, http_mocker: HttpMocker) -> None: http_mocker.get( StripeRequestBuilder.customers_endpoint(_ACCOUNT_ID, _CLIENT_SECRET).with_any_query_params().build(), - _customers_response() - .with_record( - _a_customer() - .with_id("parent_id") - ) - .build(), + _customers_response().with_record(_a_customer().with_id("parent_id")).build(), ) http_mocker.get( _payment_methods_request("parent_id").with_limit(100).build(), @@ -172,12 +159,7 @@ def test_when_read_then_add_cursor_field(self, http_mocker: HttpMocker) -> None: def test_given_http_status_400_when_read_then_stream_did_not_run(self, http_mocker: HttpMocker) -> None: http_mocker.get( StripeRequestBuilder.customers_endpoint(_ACCOUNT_ID, _CLIENT_SECRET).with_any_query_params().build(), - _customers_response() - .with_record( - _a_customer() - .with_id("parent_id") - ) - .build(), + _customers_response().with_record(_a_customer().with_id("parent_id")).build(), ) http_mocker.get( _payment_methods_request("parent_id").with_any_query_params().build(), @@ -190,12 +172,7 @@ def test_given_http_status_400_when_read_then_stream_did_not_run(self, http_mock def test_given_http_status_401_when_read_then_config_error(self, http_mocker: HttpMocker) -> None: http_mocker.get( StripeRequestBuilder.customers_endpoint(_ACCOUNT_ID, _CLIENT_SECRET).with_any_query_params().build(), - _customers_response() - .with_record( - _a_customer() - .with_id("parent_id") - ) - .build(), + _customers_response().with_record(_a_customer().with_id("parent_id")).build(), ) http_mocker.get( _payment_methods_request("parent_id").with_any_query_params().build(), @@ -208,12 +185,7 @@ def test_given_http_status_401_when_read_then_config_error(self, http_mocker: Ht def test_given_rate_limited_when_read_then_retry_and_return_records(self, http_mocker: HttpMocker) -> None: http_mocker.get( StripeRequestBuilder.customers_endpoint(_ACCOUNT_ID, _CLIENT_SECRET).with_any_query_params().build(), - _customers_response() - .with_record( - _a_customer() - .with_id("parent_id") - ) - .build(), + _customers_response().with_record(_a_customer().with_id("parent_id")).build(), ) http_mocker.get( _payment_methods_request("parent_id").with_any_query_params().build(), @@ -229,12 +201,7 @@ def test_given_rate_limited_when_read_then_retry_and_return_records(self, http_m def test_given_http_status_500_once_before_200_when_read_then_retry_and_return_records(self, http_mocker: HttpMocker) -> None: http_mocker.get( StripeRequestBuilder.customers_endpoint(_ACCOUNT_ID, _CLIENT_SECRET).with_any_query_params().build(), - _customers_response() - .with_record( - _a_customer() - .with_id("parent_id") - ) - .build(), + _customers_response().with_record(_a_customer().with_id("parent_id")).build(), ) http_mocker.get( _payment_methods_request("parent_id").with_any_query_params().build(), @@ -247,12 +214,7 @@ def test_given_http_status_500_once_before_200_when_read_then_retry_and_return_r def test_given_http_status_500_when_read_then_raise_config_error(self, http_mocker: HttpMocker) -> None: http_mocker.get( StripeRequestBuilder.customers_endpoint(_ACCOUNT_ID, _CLIENT_SECRET).with_any_query_params().build(), - _customers_response() - .with_record( - _a_customer() - .with_id("parent_id") - ) - .build(), + _customers_response().with_record(_a_customer().with_id("parent_id")).build(), ) http_mocker.get( _payment_methods_request("parent_id").with_any_query_params().build(), @@ -272,12 +234,7 @@ class IncrementalTest(TestCase): def test_given_no_state_when_read_then_use_payment_methods_endpoint(self, http_mocker: HttpMocker) -> None: http_mocker.get( StripeRequestBuilder.customers_endpoint(_ACCOUNT_ID, _CLIENT_SECRET).with_any_query_params().build(), - _customers_response() - .with_record( - _a_customer() - .with_id("parent_id") - ) - .build(), + _customers_response().with_record(_a_customer().with_id("parent_id")).build(), ) cursor_value = int(_A_START_DATE.timestamp()) + 1 http_mocker.get( diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_payout_balance_transactions.py b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_payout_balance_transactions.py new file mode 100644 index 000000000000..58a3b355ebd6 --- /dev/null +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_payout_balance_transactions.py @@ -0,0 +1,186 @@ +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. + +from datetime import datetime, timedelta, timezone +from unittest import TestCase + +import freezegun +from source_stripe import SourceStripe + +from airbyte_cdk.models import ConfiguredAirbyteCatalog, SyncMode +from airbyte_cdk.test.catalog_builder import CatalogBuilder +from airbyte_cdk.test.entrypoint_wrapper import read +from airbyte_cdk.test.mock_http import HttpMocker +from airbyte_cdk.test.mock_http.response_builder import ( + FieldPath, + HttpResponseBuilder, + NestedPath, + RecordBuilder, + create_record_builder, + create_response_builder, + find_template, +) +from airbyte_cdk.test.state_builder import StateBuilder +from integration.config import ConfigBuilder +from integration.pagination import StripePaginationStrategy +from integration.request_builder import StripeRequestBuilder + + +_STREAM_NAME = "payout_balance_transactions" +_A_PAYOUT_ID = "a_payout_id" +_ANOTHER_PAYOUT_ID = "another_payout_id" +_ACCOUNT_ID = "acct_1G9HZLIEn49ers" +_AVOIDING_INCLUSIVE_BOUNDARIES = timedelta(seconds=1) +_CLIENT_SECRET = "ConfigBuilder default client secret" +_NOW = datetime.now(timezone.utc) +_START_DATE = _NOW - timedelta(days=75) +_STATE_DATE = _NOW - timedelta(days=10) +_NO_STATE = StateBuilder().build() +_AVOIDING_INCLUSIVE_BOUNDARIES = timedelta(seconds=1) + +_DATA_FIELD = NestedPath(["data", "object"]) +_EVENT_TYPES = [ + "payout.canceled", + "payout.created", + "payout.failed", + "payout.paid", + "payout.reconciliation_completed", + "payout.updated", +] + + +def _config() -> ConfigBuilder: + return ConfigBuilder().with_account_id(_ACCOUNT_ID).with_client_secret(_CLIENT_SECRET) + + +def _create_catalog(sync_mode: SyncMode = SyncMode.full_refresh) -> ConfiguredAirbyteCatalog: + return CatalogBuilder().with_stream(name=_STREAM_NAME, sync_mode=sync_mode).build() + + +def _balance_transactions_request() -> StripeRequestBuilder: + return StripeRequestBuilder.balance_transactions_endpoint(_ACCOUNT_ID, _CLIENT_SECRET) + + +def _events_request() -> StripeRequestBuilder: + return StripeRequestBuilder.events_endpoint(_ACCOUNT_ID, _CLIENT_SECRET) + + +def _payouts_request() -> StripeRequestBuilder: + return StripeRequestBuilder.payouts_endpoint(_ACCOUNT_ID, _CLIENT_SECRET) + + +def _balance_transaction_record() -> RecordBuilder: + return create_record_builder( + find_template("balance_transactions", __file__), + FieldPath("data"), + record_id_path=FieldPath("id"), + ) + + +def _balance_transactions_response() -> HttpResponseBuilder: + return create_response_builder( + response_template=find_template("balance_transactions", __file__), + records_path=FieldPath("data"), + pagination_strategy=StripePaginationStrategy(), + ) + + +def _event_record() -> RecordBuilder: + return create_record_builder( + find_template("events", __file__), + FieldPath("data"), + record_id_path=FieldPath("id"), + record_cursor_path=FieldPath("created"), + ) + + +def _events_response() -> HttpResponseBuilder: + return create_response_builder(find_template("events", __file__), FieldPath("data"), pagination_strategy=StripePaginationStrategy()) + + +def _create_payout_record() -> RecordBuilder: + return create_record_builder( + find_template("payouts", __file__), + FieldPath("data"), + record_id_path=FieldPath("id"), + ) + + +def _payouts_response() -> HttpResponseBuilder: + return create_response_builder( + response_template=find_template("payouts", __file__), + records_path=FieldPath("data"), + pagination_strategy=StripePaginationStrategy(), + ) + + +@freezegun.freeze_time(_NOW.isoformat()) +class PayoutBalanceTransactionsFullRefreshTest(TestCase): + @HttpMocker() + def test_given_multiple_parents_when_read_then_extract_from_all_children(self, http_mocker: HttpMocker) -> None: + config = _config().with_start_date(_START_DATE).build() + http_mocker.get( + _payouts_request().with_created_gte(_START_DATE).with_created_lte(_NOW).with_limit(100).build(), + _payouts_response() + .with_record(_create_payout_record().with_id(_A_PAYOUT_ID)) + .with_record(_create_payout_record().with_id(_ANOTHER_PAYOUT_ID)) + .build(), + ) + http_mocker.get( + _balance_transactions_request().with_limit(100).with_payout(_A_PAYOUT_ID).build(), + _balance_transactions_response().with_record(_balance_transaction_record()).build(), + ) + http_mocker.get( + _balance_transactions_request().with_limit(100).with_payout(_ANOTHER_PAYOUT_ID).build(), + _balance_transactions_response().with_record(_balance_transaction_record()).with_record(_balance_transaction_record()).build(), + ) + + source = SourceStripe(config=config, catalog=_create_catalog(), state=_NO_STATE) + output = read(source, config=config, catalog=_create_catalog()) + + assert len(output.records) == 3 + + @HttpMocker() + def test_when_read_then_add_payout_field(self, http_mocker: HttpMocker) -> None: + config = _config().with_start_date(_START_DATE).build() + http_mocker.get( + _payouts_request().with_created_gte(_START_DATE).with_created_lte(_NOW).with_limit(100).build(), + _payouts_response().with_record(_create_payout_record().with_id(_A_PAYOUT_ID)).build(), + ) + http_mocker.get( + _balance_transactions_request().with_limit(100).with_payout(_A_PAYOUT_ID).build(), + _balance_transactions_response().with_record(_balance_transaction_record()).build(), + ) + + source = SourceStripe(config=config, catalog=_create_catalog(), state=_NO_STATE) + output = read(source, config=config, catalog=_create_catalog()) + + assert output.records[0].record.data["payout"] + + +@freezegun.freeze_time(_NOW.isoformat()) +class PayoutBalanceTransactionsIncrementalTest(TestCase): + @HttpMocker() + def test_when_read_then_fetch_from_updated_payouts(self, http_mocker: HttpMocker) -> None: + config = _config().with_start_date(_START_DATE).build() + state = StateBuilder().with_stream_state(_STREAM_NAME, {"updated": int(_STATE_DATE.timestamp())}).build() + catalog = _create_catalog(SyncMode.incremental) + http_mocker.get( + _events_request() + .with_created_gte(_STATE_DATE + _AVOIDING_INCLUSIVE_BOUNDARIES) + .with_created_lte(_NOW) + .with_limit(100) + .with_types(_EVENT_TYPES) + .build(), + _events_response() + .with_record(_event_record().with_field(_DATA_FIELD, _create_payout_record().with_id(_A_PAYOUT_ID).build())) + .build(), + ) + http_mocker.get( + _balance_transactions_request().with_limit(100).with_payout(_A_PAYOUT_ID).build(), + _balance_transactions_response().with_record(_balance_transaction_record()).build(), + ) + + source = SourceStripe(config=config, catalog=catalog, state=state) + output = read(source, config=config, catalog=catalog, state=state) + + assert len(output.records) == 1 diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_persons.py b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_persons.py index 7779b39bcd03..de4dd3d3126b 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_persons.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_persons.py @@ -6,6 +6,8 @@ from unittest.mock import patch import freezegun +from source_stripe import SourceStripe + from airbyte_cdk.models import AirbyteStateBlob, AirbyteStreamStatus, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.sources.streams.http.error_handlers.http_status_error_handler import HttpStatusErrorHandler from airbyte_cdk.test.catalog_builder import CatalogBuilder @@ -26,7 +28,7 @@ from integration.pagination import StripePaginationStrategy from integration.request_builder import StripeRequestBuilder from integration.response_builder import a_response_with_status -from source_stripe import SourceStripe + _STREAM_NAME = "persons" _ACCOUNT_ID = "acct_1G9HZLIEn49ers" diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_reviews.py b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_reviews.py index 13da98982181..7bc0c7f3d329 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_reviews.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_reviews.py @@ -6,6 +6,8 @@ from unittest.mock import patch import freezegun +from source_stripe import SourceStripe + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.sources.source import TState from airbyte_cdk.sources.streams.http.error_handlers.http_status_error_handler import HttpStatusErrorHandler @@ -27,7 +29,7 @@ from integration.pagination import StripePaginationStrategy from integration.request_builder import StripeRequestBuilder from integration.response_builder import a_response_with_status -from source_stripe import SourceStripe + _EVENT_TYPES = ["review.closed", "review.opened"] diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_transactions.py b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_transactions.py index cf5b850124d0..280df5218352 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_transactions.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/integration/test_transactions.py @@ -6,6 +6,8 @@ from unittest.mock import patch import freezegun +from source_stripe import SourceStripe + from airbyte_cdk.models import AirbyteStateBlob, ConfiguredAirbyteCatalog, FailureType, StreamDescriptor, SyncMode from airbyte_cdk.sources.source import TState from airbyte_cdk.sources.streams.http.error_handlers.http_status_error_handler import HttpStatusErrorHandler @@ -27,7 +29,7 @@ from integration.pagination import StripePaginationStrategy from integration.request_builder import StripeRequestBuilder from integration.response_builder import a_response_with_status -from source_stripe import SourceStripe + _EVENT_TYPES = ["issuing_transaction.created", "issuing_transaction.updated"] diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/resource/http/response/balance_transactions.json b/airbyte-integrations/connectors/source-stripe/unit_tests/resource/http/response/balance_transactions.json new file mode 100644 index 000000000000..c0b625098640 --- /dev/null +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/resource/http/response/balance_transactions.json @@ -0,0 +1,24 @@ +{ + "object": "list", + "url": "/v1/balance_transactions", + "has_more": false, + "data": [ + { + "id": "txn_1MiN3gLkdIwHu7ixxapQrznl", + "object": "balance_transaction", + "amount": -400, + "available_on": 1678043844, + "created": 1678043844, + "currency": "usd", + "description": null, + "exchange_rate": null, + "fee": 0, + "fee_details": [], + "net": -400, + "reporting_category": "transfer", + "source": "tr_1MiN3gLkdIwHu7ixNCZvFdgA", + "status": "available", + "type": "transfer" + } + ] +} diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/resource/http/response/payouts.json b/airbyte-integrations/connectors/source-stripe/unit_tests/resource/http/response/payouts.json new file mode 100644 index 000000000000..f4bb44a3ed7e --- /dev/null +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/resource/http/response/payouts.json @@ -0,0 +1,32 @@ +{ + "object": "list", + "url": "/v1/payouts", + "has_more": false, + "data": [ + { + "id": "po_1OaFDbEcg9tTZuTgNYmX0PKB", + "object": "payout", + "amount": 1100, + "arrival_date": 1680652800, + "automatic": false, + "balance_transaction": "txn_1OaFDcEcg9tTZuTgYMR25tSe", + "created": 1680648691, + "currency": "usd", + "description": null, + "destination": "ba_1MtIhL2eZvKYlo2CAElKwKu2", + "failure_balance_transaction": null, + "failure_code": null, + "failure_message": null, + "livemode": false, + "metadata": {}, + "method": "standard", + "original_payout": null, + "reconciliation_status": "not_applicable", + "reversed_by": null, + "source_type": "card", + "statement_descriptor": null, + "status": "pending", + "type": "bank_account" + } + ] +} diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/test_source.py b/airbyte-integrations/connectors/source-stripe/unit_tests/test_source.py index f386415db130..98128124534e 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/test_source.py @@ -6,12 +6,14 @@ from contextlib import nullcontext as does_not_raise import pytest +from source_stripe import SourceStripe + from airbyte_cdk.models import ConfiguredAirbyteCatalog, ConfiguredAirbyteCatalogSerializer, SyncMode from airbyte_cdk.sources.streams.call_rate import CachedLimiterSession, LimiterSession, Rate from airbyte_cdk.sources.streams.concurrent.adapters import StreamFacade from airbyte_cdk.test.state_builder import StateBuilder from airbyte_cdk.utils import AirbyteTracedException -from source_stripe import SourceStripe + logger = logging.getLogger("airbyte") _ANY_CATALOG = ConfiguredAirbyteCatalogSerializer.load({"streams": []}) @@ -49,7 +51,7 @@ def _a_valid_config(): def test_streams_are_unique(config): stream_names = [s.name for s in SourceStripe(_ANY_CATALOG, _ANY_CONFIG, _NO_STATE).streams(config=config)] - assert len(stream_names) == len(set(stream_names)) == 46 + assert len(stream_names) == len(set(stream_names)) == 47 @pytest.mark.parametrize( diff --git a/airbyte-integrations/connectors/source-stripe/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-stripe/unit_tests/test_streams.py index 75a8f884f77a..666dcb9e961f 100644 --- a/airbyte-integrations/connectors/source-stripe/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-stripe/unit_tests/test_streams.py @@ -7,7 +7,7 @@ import freezegun import pendulum import pytest -from source_stripe.streams import CustomerBalanceTransactions, SetupAttempts, StripeStream, UpdatedCursorIncrementalStripeSubStream +from source_stripe.streams import SetupAttempts, StripeStream, UpdatedCursorIncrementalStripeSubStream def read_from_stream(stream, sync_mode, state): @@ -133,7 +133,6 @@ def test_lazy_substream_data_cursor_value_is_populated( def test_lazy_substream_data_is_expanded( requests_mock, stream_by_name, config, requests_mock_map, stream_cls, expected_records, sync_mode, state ): - config["start_date"] = str(pendulum.today().subtract(days=3)) stream = stream_by_name("bank_accounts", config) for url, body in requests_mock_map.items(): @@ -524,25 +523,6 @@ def test_updated_cursor_incremental_stream_read_w_state(requests_mock, stream_by assert records == [{"object": "credit_note", "invoice": "in_1K9GK0EcXtiJtvvhSo2LvGqT", "created": 1653341716, "updated": 1691629292}] -def test_customer_balance_transactions_stream_slices(requests_mock, stream_args): - stream_args["start_date"] = pendulum.now().subtract(days=1).int_timestamp - requests_mock.get( - "/v1/customers", - json={ - "data": [ - {"id": 1, "next_invoice_sequence": 1, "balance": 0, "created": 1653341716}, - {"id": 2, "created": 1653341000}, - {"id": 3, "next_invoice_sequence": 13, "balance": 343.43, "created": 1651716334}, - ] - }, - ) - stream = CustomerBalanceTransactions(**stream_args) - assert list(stream.stream_slices("full_refresh")) == [ - {"id": 2, "created": 1653341000, "updated": 1653341000}, - {"id": 3, "next_invoice_sequence": 13, "balance": 343.43, "created": 1651716334, "updated": 1651716334}, - ] - - @freezegun.freeze_time("2023-08-23T15:00:15Z") def test_setup_attempts(requests_mock, incremental_stream_args): requests_mock.get( @@ -603,12 +583,12 @@ def test_setup_attempts(requests_mock, incremental_stream_args): def test_persons_wo_state(requests_mock, stream_args): requests_mock.get("/v1/accounts", json={"data": [{"id": 1, "object": "account", "created": 111}]}) stream = UpdatedCursorIncrementalStripeSubStream( - name="persons", - path=lambda self, stream_slice, *args, **kwargs: f"accounts/{stream_slice['parent']['id']}/persons", - parent=StripeStream(name="accounts", path="accounts", use_cache=False, **stream_args), - event_types=["person.created", "person.updated", "person.deleted"], - **stream_args, - ) + name="persons", + path=lambda self, stream_slice, *args, **kwargs: f"accounts/{stream_slice['parent']['id']}/persons", + parent=StripeStream(name="accounts", path="accounts", use_cache=False, **stream_args), + event_types=["person.created", "person.updated", "person.deleted"], + **stream_args, + ) slices = list(stream.stream_slices("full_refresh")) assert slices == [{"parent": {"id": 1, "object": "account", "created": 111}}] requests_mock.get("/v1/accounts/1/persons", json={"data": [{"id": 11, "object": "person", "created": 222}]}) @@ -638,12 +618,12 @@ def test_persons_w_state(requests_mock, stream_args): }, ) stream = UpdatedCursorIncrementalStripeSubStream( - name="persons", - path=lambda self, stream_slice, *args, **kwargs: f"accounts/{stream_slice['parent']['id']}/persons", - parent=StripeStream(name="accounts", path="accounts", use_cache=False, **stream_args), - event_types=["person.created", "person.updated", "person.deleted"], - **stream_args, - ) + name="persons", + path=lambda self, stream_slice, *args, **kwargs: f"accounts/{stream_slice['parent']['id']}/persons", + parent=StripeStream(name="accounts", path="accounts", use_cache=False, **stream_args), + event_types=["person.created", "person.updated", "person.deleted"], + **stream_args, + ) slices = list(stream.stream_slices("incremental", stream_state={"updated": pendulum.parse("2023-08-20T00:00:00").int_timestamp})) assert slices == [{}] records = [ @@ -822,6 +802,7 @@ def test_subscription_items_extra_request_params(requests_mock, stream_by_name, "created": 1699603175, "quantity": 1, "subscription": "sub_1OApco2eZvKYlo2CEDCzwLrE", + "subscription_updated": 1699603174, # 1699603175 }, { "id": "si_OynPdzMZykmCWm", @@ -829,6 +810,7 @@ def test_subscription_items_extra_request_params(requests_mock, stream_by_name, "created": 1699603884, "quantity": 2, "subscription": "sub_1OApco2eZvKYlo2CEDCzwLrE", + "subscription_updated": 1699603174, }, ] assert len(requests_mock.request_history) == 2 diff --git a/airbyte-integrations/connectors/source-survey-sparrow/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-survey-sparrow/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-survey-sparrow/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-survey-sparrow/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-survey-sparrow/metadata.yaml b/airbyte-integrations/connectors/source-survey-sparrow/metadata.yaml index 9a8c6edac6cf..8c36984206f7 100644 --- a/airbyte-integrations/connectors/source-survey-sparrow/metadata.yaml +++ b/airbyte-integrations/connectors/source-survey-sparrow/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 4a4d887b-0f2d-4b33-ab7f-9b01b9072804 - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.6 dockerRepository: airbyte/source-survey-sparrow documentationUrl: https://docs.airbyte.com/integrations/sources/survey-sparrow githubIssueLabel: source-survey-sparrow diff --git a/airbyte-integrations/connectors/source-surveycto/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-surveycto/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-surveycto/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-surveycto/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-surveycto/main.py b/airbyte-integrations/connectors/source-surveycto/main.py index 9f282dbc2ecd..7bd10098aad5 100644 --- a/airbyte-integrations/connectors/source-surveycto/main.py +++ b/airbyte-integrations/connectors/source-surveycto/main.py @@ -4,5 +4,6 @@ from source_surveycto.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-surveycto/metadata.yaml b/airbyte-integrations/connectors/source-surveycto/metadata.yaml index 3d7688105277..d4e39e2d1298 100644 --- a/airbyte-integrations/connectors/source-surveycto/metadata.yaml +++ b/airbyte-integrations/connectors/source-surveycto/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: dd4632f4-15e0-4649-9b71-41719fb1fdee - dockerImageTag: 0.1.26 + dockerImageTag: 0.1.31 dockerRepository: airbyte/source-surveycto githubIssueLabel: source-surveycto icon: surveycto.svg @@ -40,5 +40,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-surveycto/poetry.lock b/airbyte-integrations/connectors/source-surveycto/poetry.lock index c3ef8cec0bf8..58ad7353bea2 100644 --- a/airbyte-integrations/connectors/source-surveycto/poetry.lock +++ b/airbyte-integrations/connectors/source-surveycto/poetry.lock @@ -62,19 +62,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -150,127 +150,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -286,20 +273,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -328,13 +315,13 @@ test = ["pytest (>=6)"] [[package]] name = "fastjsonschema" -version = "2.20.0" +version = "2.21.1" description = "Fastest Python implementation of JSON schema" optional = false python-versions = "*" files = [ - {file = "fastjsonschema-2.20.0-py3-none-any.whl", hash = "sha256:5875f0b0fa7a0043a91e93a9b8f793bcbbba9691e7fd83dca95c28ba26d21f0a"}, - {file = "fastjsonschema-2.20.0.tar.gz", hash = "sha256:3d48fc5300ee96f5d116f10fe6f28d938e6008f59a6a025c2649475b87f76a23"}, + {file = "fastjsonschema-2.21.1-py3-none-any.whl", hash = "sha256:c9e5b7e908310918cf494a434eeb31384dd84a98b57a30bcb1f535015b554667"}, + {file = "fastjsonschema-2.21.1.tar.gz", hash = "sha256:794d4f0a58f848961ba16af7b9c85a3e88cd360df008c59aac6fc5ae9323b5d4"}, ] [package.extras] @@ -367,13 +354,13 @@ files = [ [[package]] name = "google-api-core" -version = "2.22.0" +version = "2.24.0" description = "Google API client core library" optional = false python-versions = ">=3.7" files = [ - {file = "google_api_core-2.22.0-py3-none-any.whl", hash = "sha256:a6652b6bd51303902494998626653671703c420f6f4c88cfd3f50ed723e9d021"}, - {file = "google_api_core-2.22.0.tar.gz", hash = "sha256:26f8d76b96477db42b55fd02a33aae4a42ec8b86b98b94969b7333a2c828bf35"}, + {file = "google_api_core-2.24.0-py3-none-any.whl", hash = "sha256:10d82ac0fca69c82a25b3efdeefccf6f28e02ebb97925a8cce8edbfe379929d9"}, + {file = "google_api_core-2.24.0.tar.gz", hash = "sha256:e255640547a597a4da010876d333208ddac417d60add22b6851a0c66a831fcaf"}, ] [package.dependencies] @@ -399,13 +386,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] [[package]] name = "google-auth" -version = "2.35.0" +version = "2.37.0" description = "Google Authentication Library" optional = false python-versions = ">=3.7" files = [ - {file = "google_auth-2.35.0-py2.py3-none-any.whl", hash = "sha256:25df55f327ef021de8be50bad0dfd4a916ad0de96da86cd05661c9297723ad3f"}, - {file = "google_auth-2.35.0.tar.gz", hash = "sha256:f4c64ed4e01e8e8b646ef34c018f8bf3338df0c8e37d8b3bba40e7f574a3278a"}, + {file = "google_auth-2.37.0-py2.py3-none-any.whl", hash = "sha256:42664f18290a6be591be5329a96fe30184be1a1badb7292a7f686a9659de9ca0"}, + {file = "google_auth-2.37.0.tar.gz", hash = "sha256:0054623abf1f9c83492c63d3f47e77f0a544caa3d40b2d98e099a611c2dd5d00"}, ] [package.dependencies] @@ -416,19 +403,20 @@ rsa = ">=3.1.4,<5" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0.dev0)", "requests (>=2.20.0,<3.0.0.dev0)"] enterprise-cert = ["cryptography", "pyopenssl"] +pyjwt = ["cryptography (>=38.0.3)", "pyjwt (>=2.0)"] pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0.dev0)"] [[package]] name = "google-cloud-bigquery" -version = "3.26.0" +version = "3.27.0" description = "Google BigQuery API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google_cloud_bigquery-3.26.0-py2.py3-none-any.whl", hash = "sha256:e0e9ad28afa67a18696e624cbccab284bf2c0a3f6eeb9eeb0426c69b943793a8"}, - {file = "google_cloud_bigquery-3.26.0.tar.gz", hash = "sha256:edbdc788beea659e04c0af7fe4dcd6d9155344b98951a0d5055bd2f15da4ba23"}, + {file = "google_cloud_bigquery-3.27.0-py2.py3-none-any.whl", hash = "sha256:b53b0431e5ba362976a4cd8acce72194b4116cdf8115030c7b339b884603fcc3"}, + {file = "google_cloud_bigquery-3.27.0.tar.gz", hash = "sha256:379c524054d7b090fa56d0c22662cc6e6458a6229b6754c0e7177e3a73421d2c"}, ] [package.dependencies] @@ -528,13 +516,13 @@ requests = ["requests (>=2.18.0,<3.0.0dev)"] [[package]] name = "googleapis-common-protos" -version = "1.65.0" +version = "1.66.0" description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" files = [ - {file = "googleapis_common_protos-1.65.0-py2.py3-none-any.whl", hash = "sha256:2972e6c496f435b92590fd54045060867f3fe9be2c82ab148fc8885035479a63"}, - {file = "googleapis_common_protos-1.65.0.tar.gz", hash = "sha256:334a29d07cddc3aa01dee4988f9afd9b2916ee2ff49d6b757155dc0d197852c0"}, + {file = "googleapis_common_protos-1.66.0-py2.py3-none-any.whl", hash = "sha256:d7abcd75fabb2e0ec9f74466401f6c119a0b498e27370e9be4c94cb7e382b8ed"}, + {file = "googleapis_common_protos-1.66.0.tar.gz", hash = "sha256:c3e7b33d15fdca5374cc0a7346dd92ffa847425cc4ea941d970f13680052ec8c"}, ] [package.dependencies] @@ -545,85 +533,85 @@ grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] [[package]] name = "grpcio" -version = "1.67.1" +version = "1.68.1" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.8" files = [ - {file = "grpcio-1.67.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:8b0341d66a57f8a3119b77ab32207072be60c9bf79760fa609c5609f2deb1f3f"}, - {file = "grpcio-1.67.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:f5a27dddefe0e2357d3e617b9079b4bfdc91341a91565111a21ed6ebbc51b22d"}, - {file = "grpcio-1.67.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:43112046864317498a33bdc4797ae6a268c36345a910de9b9c17159d8346602f"}, - {file = "grpcio-1.67.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9b929f13677b10f63124c1a410994a401cdd85214ad83ab67cc077fc7e480f0"}, - {file = "grpcio-1.67.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7d1797a8a3845437d327145959a2c0c47c05947c9eef5ff1a4c80e499dcc6fa"}, - {file = "grpcio-1.67.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0489063974d1452436139501bf6b180f63d4977223ee87488fe36858c5725292"}, - {file = "grpcio-1.67.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9fd042de4a82e3e7aca44008ee2fb5da01b3e5adb316348c21980f7f58adc311"}, - {file = "grpcio-1.67.1-cp310-cp310-win32.whl", hash = "sha256:638354e698fd0c6c76b04540a850bf1db27b4d2515a19fcd5cf645c48d3eb1ed"}, - {file = "grpcio-1.67.1-cp310-cp310-win_amd64.whl", hash = "sha256:608d87d1bdabf9e2868b12338cd38a79969eaf920c89d698ead08f48de9c0f9e"}, - {file = "grpcio-1.67.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:7818c0454027ae3384235a65210bbf5464bd715450e30a3d40385453a85a70cb"}, - {file = "grpcio-1.67.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ea33986b70f83844cd00814cee4451055cd8cab36f00ac64a31f5bb09b31919e"}, - {file = "grpcio-1.67.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:c7a01337407dd89005527623a4a72c5c8e2894d22bead0895306b23c6695698f"}, - {file = "grpcio-1.67.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80b866f73224b0634f4312a4674c1be21b2b4afa73cb20953cbbb73a6b36c3cc"}, - {file = "grpcio-1.67.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9fff78ba10d4250bfc07a01bd6254a6d87dc67f9627adece85c0b2ed754fa96"}, - {file = "grpcio-1.67.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8a23cbcc5bb11ea7dc6163078be36c065db68d915c24f5faa4f872c573bb400f"}, - {file = "grpcio-1.67.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1a65b503d008f066e994f34f456e0647e5ceb34cfcec5ad180b1b44020ad4970"}, - {file = "grpcio-1.67.1-cp311-cp311-win32.whl", hash = "sha256:e29ca27bec8e163dca0c98084040edec3bc49afd10f18b412f483cc68c712744"}, - {file = "grpcio-1.67.1-cp311-cp311-win_amd64.whl", hash = "sha256:786a5b18544622bfb1e25cc08402bd44ea83edfb04b93798d85dca4d1a0b5be5"}, - {file = "grpcio-1.67.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:267d1745894200e4c604958da5f856da6293f063327cb049a51fe67348e4f953"}, - {file = "grpcio-1.67.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:85f69fdc1d28ce7cff8de3f9c67db2b0ca9ba4449644488c1e0303c146135ddb"}, - {file = "grpcio-1.67.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:f26b0b547eb8d00e195274cdfc63ce64c8fc2d3e2d00b12bf468ece41a0423a0"}, - {file = "grpcio-1.67.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4422581cdc628f77302270ff839a44f4c24fdc57887dc2a45b7e53d8fc2376af"}, - {file = "grpcio-1.67.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d7616d2ded471231c701489190379e0c311ee0a6c756f3c03e6a62b95a7146e"}, - {file = "grpcio-1.67.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8a00efecde9d6fcc3ab00c13f816313c040a28450e5e25739c24f432fc6d3c75"}, - {file = "grpcio-1.67.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:699e964923b70f3101393710793289e42845791ea07565654ada0969522d0a38"}, - {file = "grpcio-1.67.1-cp312-cp312-win32.whl", hash = "sha256:4e7b904484a634a0fff132958dabdb10d63e0927398273917da3ee103e8d1f78"}, - {file = "grpcio-1.67.1-cp312-cp312-win_amd64.whl", hash = "sha256:5721e66a594a6c4204458004852719b38f3d5522082be9061d6510b455c90afc"}, - {file = "grpcio-1.67.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:aa0162e56fd10a5547fac8774c4899fc3e18c1aa4a4759d0ce2cd00d3696ea6b"}, - {file = "grpcio-1.67.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:beee96c8c0b1a75d556fe57b92b58b4347c77a65781ee2ac749d550f2a365dc1"}, - {file = "grpcio-1.67.1-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:a93deda571a1bf94ec1f6fcda2872dad3ae538700d94dc283c672a3b508ba3af"}, - {file = "grpcio-1.67.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e6f255980afef598a9e64a24efce87b625e3e3c80a45162d111a461a9f92955"}, - {file = "grpcio-1.67.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e838cad2176ebd5d4a8bb03955138d6589ce9e2ce5d51c3ada34396dbd2dba8"}, - {file = "grpcio-1.67.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:a6703916c43b1d468d0756c8077b12017a9fcb6a1ef13faf49e67d20d7ebda62"}, - {file = "grpcio-1.67.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:917e8d8994eed1d86b907ba2a61b9f0aef27a2155bca6cbb322430fc7135b7bb"}, - {file = "grpcio-1.67.1-cp313-cp313-win32.whl", hash = "sha256:e279330bef1744040db8fc432becc8a727b84f456ab62b744d3fdb83f327e121"}, - {file = "grpcio-1.67.1-cp313-cp313-win_amd64.whl", hash = "sha256:fa0c739ad8b1996bd24823950e3cb5152ae91fca1c09cc791190bf1627ffefba"}, - {file = "grpcio-1.67.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:178f5db771c4f9a9facb2ab37a434c46cb9be1a75e820f187ee3d1e7805c4f65"}, - {file = "grpcio-1.67.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0f3e49c738396e93b7ba9016e153eb09e0778e776df6090c1b8c91877cc1c426"}, - {file = "grpcio-1.67.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:24e8a26dbfc5274d7474c27759b54486b8de23c709d76695237515bc8b5baeab"}, - {file = "grpcio-1.67.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b6c16489326d79ead41689c4b84bc40d522c9a7617219f4ad94bc7f448c5085"}, - {file = "grpcio-1.67.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60e6a4dcf5af7bbc36fd9f81c9f372e8ae580870a9e4b6eafe948cd334b81cf3"}, - {file = "grpcio-1.67.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:95b5f2b857856ed78d72da93cd7d09b6db8ef30102e5e7fe0961fe4d9f7d48e8"}, - {file = "grpcio-1.67.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b49359977c6ec9f5d0573ea4e0071ad278ef905aa74e420acc73fd28ce39e9ce"}, - {file = "grpcio-1.67.1-cp38-cp38-win32.whl", hash = "sha256:f5b76ff64aaac53fede0cc93abf57894ab2a7362986ba22243d06218b93efe46"}, - {file = "grpcio-1.67.1-cp38-cp38-win_amd64.whl", hash = "sha256:804c6457c3cd3ec04fe6006c739579b8d35c86ae3298ffca8de57b493524b771"}, - {file = "grpcio-1.67.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:a25bdea92b13ff4d7790962190bf6bf5c4639876e01c0f3dda70fc2769616335"}, - {file = "grpcio-1.67.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cdc491ae35a13535fd9196acb5afe1af37c8237df2e54427be3eecda3653127e"}, - {file = "grpcio-1.67.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:85f862069b86a305497e74d0dc43c02de3d1d184fc2c180993aa8aa86fbd19b8"}, - {file = "grpcio-1.67.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec74ef02010186185de82cc594058a3ccd8d86821842bbac9873fd4a2cf8be8d"}, - {file = "grpcio-1.67.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01f616a964e540638af5130469451cf580ba8c7329f45ca998ab66e0c7dcdb04"}, - {file = "grpcio-1.67.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:299b3d8c4f790c6bcca485f9963b4846dd92cf6f1b65d3697145d005c80f9fe8"}, - {file = "grpcio-1.67.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:60336bff760fbb47d7e86165408126f1dded184448e9a4c892189eb7c9d3f90f"}, - {file = "grpcio-1.67.1-cp39-cp39-win32.whl", hash = "sha256:5ed601c4c6008429e3d247ddb367fe8c7259c355757448d7c1ef7bd4a6739e8e"}, - {file = "grpcio-1.67.1-cp39-cp39-win_amd64.whl", hash = "sha256:5db70d32d6703b89912af16d6d45d78406374a8b8ef0d28140351dd0ec610e98"}, - {file = "grpcio-1.67.1.tar.gz", hash = "sha256:3dc2ed4cabea4dc14d5e708c2b426205956077cc5de419b4d4079315017e9732"}, + {file = "grpcio-1.68.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:d35740e3f45f60f3c37b1e6f2f4702c23867b9ce21c6410254c9c682237da68d"}, + {file = "grpcio-1.68.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:d99abcd61760ebb34bdff37e5a3ba333c5cc09feda8c1ad42547bea0416ada78"}, + {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:f8261fa2a5f679abeb2a0a93ad056d765cdca1c47745eda3f2d87f874ff4b8c9"}, + {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0feb02205a27caca128627bd1df4ee7212db051019a9afa76f4bb6a1a80ca95e"}, + {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:919d7f18f63bcad3a0f81146188e90274fde800a94e35d42ffe9eadf6a9a6330"}, + {file = "grpcio-1.68.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:963cc8d7d79b12c56008aabd8b457f400952dbea8997dd185f155e2f228db079"}, + {file = "grpcio-1.68.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ccf2ebd2de2d6661e2520dae293298a3803a98ebfc099275f113ce1f6c2a80f1"}, + {file = "grpcio-1.68.1-cp310-cp310-win32.whl", hash = "sha256:2cc1fd04af8399971bcd4f43bd98c22d01029ea2e56e69c34daf2bf8470e47f5"}, + {file = "grpcio-1.68.1-cp310-cp310-win_amd64.whl", hash = "sha256:ee2e743e51cb964b4975de572aa8fb95b633f496f9fcb5e257893df3be854746"}, + {file = "grpcio-1.68.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:55857c71641064f01ff0541a1776bfe04a59db5558e82897d35a7793e525774c"}, + {file = "grpcio-1.68.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4b177f5547f1b995826ef529d2eef89cca2f830dd8b2c99ffd5fde4da734ba73"}, + {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:3522c77d7e6606d6665ec8d50e867f13f946a4e00c7df46768f1c85089eae515"}, + {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d1fae6bbf0816415b81db1e82fb3bf56f7857273c84dcbe68cbe046e58e1ccd"}, + {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:298ee7f80e26f9483f0b6f94cc0a046caf54400a11b644713bb5b3d8eb387600"}, + {file = "grpcio-1.68.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cbb5780e2e740b6b4f2d208e90453591036ff80c02cc605fea1af8e6fc6b1bbe"}, + {file = "grpcio-1.68.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ddda1aa22495d8acd9dfbafff2866438d12faec4d024ebc2e656784d96328ad0"}, + {file = "grpcio-1.68.1-cp311-cp311-win32.whl", hash = "sha256:b33bd114fa5a83f03ec6b7b262ef9f5cac549d4126f1dc702078767b10c46ed9"}, + {file = "grpcio-1.68.1-cp311-cp311-win_amd64.whl", hash = "sha256:7f20ebec257af55694d8f993e162ddf0d36bd82d4e57f74b31c67b3c6d63d8b2"}, + {file = "grpcio-1.68.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:8829924fffb25386995a31998ccbbeaa7367223e647e0122043dfc485a87c666"}, + {file = "grpcio-1.68.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3aed6544e4d523cd6b3119b0916cef3d15ef2da51e088211e4d1eb91a6c7f4f1"}, + {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:4efac5481c696d5cb124ff1c119a78bddbfdd13fc499e3bc0ca81e95fc573684"}, + {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ab2d912ca39c51f46baf2a0d92aa265aa96b2443266fc50d234fa88bf877d8e"}, + {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c87ce2a97434dffe7327a4071839ab8e8bffd0054cc74cbe971fba98aedd60"}, + {file = "grpcio-1.68.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e4842e4872ae4ae0f5497bf60a0498fa778c192cc7a9e87877abd2814aca9475"}, + {file = "grpcio-1.68.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:255b1635b0ed81e9f91da4fcc8d43b7ea5520090b9a9ad9340d147066d1d3613"}, + {file = "grpcio-1.68.1-cp312-cp312-win32.whl", hash = "sha256:7dfc914cc31c906297b30463dde0b9be48e36939575eaf2a0a22a8096e69afe5"}, + {file = "grpcio-1.68.1-cp312-cp312-win_amd64.whl", hash = "sha256:a0c8ddabef9c8f41617f213e527254c41e8b96ea9d387c632af878d05db9229c"}, + {file = "grpcio-1.68.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:a47faedc9ea2e7a3b6569795c040aae5895a19dde0c728a48d3c5d7995fda385"}, + {file = "grpcio-1.68.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:390eee4225a661c5cd133c09f5da1ee3c84498dc265fd292a6912b65c421c78c"}, + {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:66a24f3d45c33550703f0abb8b656515b0ab777970fa275693a2f6dc8e35f1c1"}, + {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c08079b4934b0bf0a8847f42c197b1d12cba6495a3d43febd7e99ecd1cdc8d54"}, + {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8720c25cd9ac25dd04ee02b69256d0ce35bf8a0f29e20577427355272230965a"}, + {file = "grpcio-1.68.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:04cfd68bf4f38f5bb959ee2361a7546916bd9a50f78617a346b3aeb2b42e2161"}, + {file = "grpcio-1.68.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c28848761a6520c5c6071d2904a18d339a796ebe6b800adc8b3f474c5ce3c3ad"}, + {file = "grpcio-1.68.1-cp313-cp313-win32.whl", hash = "sha256:77d65165fc35cff6e954e7fd4229e05ec76102d4406d4576528d3a3635fc6172"}, + {file = "grpcio-1.68.1-cp313-cp313-win_amd64.whl", hash = "sha256:a8040f85dcb9830d8bbb033ae66d272614cec6faceee88d37a88a9bd1a7a704e"}, + {file = "grpcio-1.68.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:eeb38ff04ab6e5756a2aef6ad8d94e89bb4a51ef96e20f45c44ba190fa0bcaad"}, + {file = "grpcio-1.68.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8a3869a6661ec8f81d93f4597da50336718bde9eb13267a699ac7e0a1d6d0bea"}, + {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:2c4cec6177bf325eb6faa6bd834d2ff6aa8bb3b29012cceb4937b86f8b74323c"}, + {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12941d533f3cd45d46f202e3667be8ebf6bcb3573629c7ec12c3e211d99cfccf"}, + {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80af6f1e69c5e68a2be529990684abdd31ed6622e988bf18850075c81bb1ad6e"}, + {file = "grpcio-1.68.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e8dbe3e00771bfe3d04feed8210fc6617006d06d9a2679b74605b9fed3e8362c"}, + {file = "grpcio-1.68.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:83bbf5807dc3ee94ce1de2dfe8a356e1d74101e4b9d7aa8c720cc4818a34aded"}, + {file = "grpcio-1.68.1-cp38-cp38-win32.whl", hash = "sha256:8cb620037a2fd9eeee97b4531880e439ebfcd6d7d78f2e7dcc3726428ab5ef63"}, + {file = "grpcio-1.68.1-cp38-cp38-win_amd64.whl", hash = "sha256:52fbf85aa71263380d330f4fce9f013c0798242e31ede05fcee7fbe40ccfc20d"}, + {file = "grpcio-1.68.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:cb400138e73969eb5e0535d1d06cae6a6f7a15f2cc74add320e2130b8179211a"}, + {file = "grpcio-1.68.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a1b988b40f2fd9de5c820f3a701a43339d8dcf2cb2f1ca137e2c02671cc83ac1"}, + {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:96f473cdacfdd506008a5d7579c9f6a7ff245a9ade92c3c0265eb76cc591914f"}, + {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:37ea3be171f3cf3e7b7e412a98b77685eba9d4fd67421f4a34686a63a65d99f9"}, + {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ceb56c4285754e33bb3c2fa777d055e96e6932351a3082ce3559be47f8024f0"}, + {file = "grpcio-1.68.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:dffd29a2961f3263a16d73945b57cd44a8fd0b235740cb14056f0612329b345e"}, + {file = "grpcio-1.68.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:025f790c056815b3bf53da850dd70ebb849fd755a4b1ac822cb65cd631e37d43"}, + {file = "grpcio-1.68.1-cp39-cp39-win32.whl", hash = "sha256:1098f03dedc3b9810810568060dea4ac0822b4062f537b0f53aa015269be0a76"}, + {file = "grpcio-1.68.1-cp39-cp39-win_amd64.whl", hash = "sha256:334ab917792904245a028f10e803fcd5b6f36a7b2173a820c0b5b076555825e1"}, + {file = "grpcio-1.68.1.tar.gz", hash = "sha256:44a8502dd5de653ae6a73e2de50a401d84184f0331d0ac3daeb044e66d5c5054"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.67.1)"] +protobuf = ["grpcio-tools (>=1.68.1)"] [[package]] name = "grpcio-status" -version = "1.67.1" +version = "1.68.1" description = "Status proto mapping for gRPC" optional = false python-versions = ">=3.8" files = [ - {file = "grpcio_status-1.67.1-py3-none-any.whl", hash = "sha256:16e6c085950bdacac97c779e6a502ea671232385e6e37f258884d6883392c2bd"}, - {file = "grpcio_status-1.67.1.tar.gz", hash = "sha256:2bf38395e028ceeecfd8866b081f61628114b384da7d51ae064ddc8d766a5d11"}, + {file = "grpcio_status-1.68.1-py3-none-any.whl", hash = "sha256:66f3d8847f665acfd56221333d66f7ad8927903d87242a482996bdb45e8d28fd"}, + {file = "grpcio_status-1.68.1.tar.gz", hash = "sha256:e1378d036c81a1610d7b4c7a146cd663dd13fcc915cf4d7d053929dba5bbb6e1"}, ] [package.dependencies] googleapis-common-protos = ">=1.5.5" -grpcio = ">=1.67.1" +grpcio = ">=1.68.1" protobuf = ">=5.26.1,<6.0dev" [[package]] @@ -667,13 +655,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -786,13 +774,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -879,22 +867,22 @@ testing = ["google-api-core (>=1.31.5)"] [[package]] name = "protobuf" -version = "5.28.3" +version = "5.29.2" description = "" optional = false python-versions = ">=3.8" files = [ - {file = "protobuf-5.28.3-cp310-abi3-win32.whl", hash = "sha256:0c4eec6f987338617072592b97943fdbe30d019c56126493111cf24344c1cc24"}, - {file = "protobuf-5.28.3-cp310-abi3-win_amd64.whl", hash = "sha256:91fba8f445723fcf400fdbe9ca796b19d3b1242cd873907979b9ed71e4afe868"}, - {file = "protobuf-5.28.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a3f6857551e53ce35e60b403b8a27b0295f7d6eb63d10484f12bc6879c715687"}, - {file = "protobuf-5.28.3-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:3fa2de6b8b29d12c61911505d893afe7320ce7ccba4df913e2971461fa36d584"}, - {file = "protobuf-5.28.3-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:712319fbdddb46f21abb66cd33cb9e491a5763b2febd8f228251add221981135"}, - {file = "protobuf-5.28.3-cp38-cp38-win32.whl", hash = "sha256:3e6101d095dfd119513cde7259aa703d16c6bbdfae2554dfe5cfdbe94e32d548"}, - {file = "protobuf-5.28.3-cp38-cp38-win_amd64.whl", hash = "sha256:27b246b3723692bf1068d5734ddaf2fccc2cdd6e0c9b47fe099244d80200593b"}, - {file = "protobuf-5.28.3-cp39-cp39-win32.whl", hash = "sha256:135658402f71bbd49500322c0f736145731b16fc79dc8f367ab544a17eab4535"}, - {file = "protobuf-5.28.3-cp39-cp39-win_amd64.whl", hash = "sha256:70585a70fc2dd4818c51287ceef5bdba6387f88a578c86d47bb34669b5552c36"}, - {file = "protobuf-5.28.3-py3-none-any.whl", hash = "sha256:cee1757663fa32a1ee673434fcf3bf24dd54763c79690201208bafec62f19eed"}, - {file = "protobuf-5.28.3.tar.gz", hash = "sha256:64badbc49180a5e401f373f9ce7ab1d18b63f7dd4a9cdc43c92b9f0b481cef7b"}, + {file = "protobuf-5.29.2-cp310-abi3-win32.whl", hash = "sha256:c12ba8249f5624300cf51c3d0bfe5be71a60c63e4dcf51ffe9a68771d958c851"}, + {file = "protobuf-5.29.2-cp310-abi3-win_amd64.whl", hash = "sha256:842de6d9241134a973aab719ab42b008a18a90f9f07f06ba480df268f86432f9"}, + {file = "protobuf-5.29.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a0c53d78383c851bfa97eb42e3703aefdc96d2036a41482ffd55dc5f529466eb"}, + {file = "protobuf-5.29.2-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:494229ecd8c9009dd71eda5fd57528395d1eacdf307dbece6c12ad0dd09e912e"}, + {file = "protobuf-5.29.2-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:b6b0d416bbbb9d4fbf9d0561dbfc4e324fd522f61f7af0fe0f282ab67b22477e"}, + {file = "protobuf-5.29.2-cp38-cp38-win32.whl", hash = "sha256:e621a98c0201a7c8afe89d9646859859be97cb22b8bf1d8eacfd90d5bda2eb19"}, + {file = "protobuf-5.29.2-cp38-cp38-win_amd64.whl", hash = "sha256:13d6d617a2a9e0e82a88113d7191a1baa1e42c2cc6f5f1398d3b054c8e7e714a"}, + {file = "protobuf-5.29.2-cp39-cp39-win32.whl", hash = "sha256:36000f97ea1e76e8398a3f02936aac2a5d2b111aae9920ec1b769fc4a222c4d9"}, + {file = "protobuf-5.29.2-cp39-cp39-win_amd64.whl", hash = "sha256:2d2e674c58a06311c8e99e74be43e7f3a8d1e2b2fdf845eaa347fbd866f23355"}, + {file = "protobuf-5.29.2-py3-none-any.whl", hash = "sha256:fde4554c0e578a5a0bcc9a276339594848d1e89f9ea47b4427c80e5d72f90181"}, + {file = "protobuf-5.29.2.tar.gz", hash = "sha256:b2cc8e8bb7c9326996f0e160137b0861f1a82162502658df2951209d0cb0309e"}, ] [[package]] @@ -935,54 +923,54 @@ pyasn1 = ">=0.4.6,<0.7.0" [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -1260,33 +1248,33 @@ pyasn1 = ">=0.1.3" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1327,13 +1315,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1358,81 +1346,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-surveycto/pyproject.toml b/airbyte-integrations/connectors/source-surveycto/pyproject.toml index 3544666da762..0643882d2649 100644 --- a/airbyte-integrations/connectors/source-surveycto/pyproject.toml +++ b/airbyte-integrations/connectors/source-surveycto/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.26" +version = "0.1.31" name = "source-surveycto" description = "Source implementation for Surveycto." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-surveycto/source_surveycto/source.py b/airbyte-integrations/connectors/source-surveycto/source_surveycto/source.py index 816b0dad755e..f0ff2adbb409 100644 --- a/airbyte-integrations/connectors/source-surveycto/source_surveycto/source.py +++ b/airbyte-integrations/connectors/source-surveycto/source_surveycto/source.py @@ -8,6 +8,7 @@ from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Tuple import requests + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import IncrementalMixin, Stream @@ -111,7 +112,6 @@ def read_records(self, *args, **kwargs) -> Iterable[Mapping[str, Any]]: # Source class SourceSurveycto(AbstractSource): def check_connection(self, logger, config) -> Tuple[bool, Any]: - form_ids = config["form_id"] try: diff --git a/airbyte-integrations/connectors/source-surveycto/unit_tests/test_source.py b/airbyte-integrations/connectors/source-surveycto/unit_tests/test_source.py index 77ebfa14f624..863aa11f2b76 100644 --- a/airbyte-integrations/connectors/source-surveycto/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-surveycto/unit_tests/test_source.py @@ -26,9 +26,11 @@ def source_fixture(): @pytest.fixture(name="mock_survey_cto") def mock_survey_cto_fixture(): - with patch("source_surveycto.source.Helpers.call_survey_cto", return_value="value") as mock_call_survey_cto, patch( - "source_surveycto.source.Helpers.get_filter_data", return_value="value" - ) as mock_filter_data, patch("source_surveycto.source.Helpers.get_json_schema", return_value="value") as mock_json_schema: + with ( + patch("source_surveycto.source.Helpers.call_survey_cto", return_value="value") as mock_call_survey_cto, + patch("source_surveycto.source.Helpers.get_filter_data", return_value="value") as mock_filter_data, + patch("source_surveycto.source.Helpers.get_json_schema", return_value="value") as mock_json_schema, + ): yield mock_call_survey_cto, mock_filter_data, mock_json_schema diff --git a/airbyte-integrations/connectors/source-surveymonkey/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-surveymonkey/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-surveymonkey/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-surveymonkey/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-surveymonkey/main.py b/airbyte-integrations/connectors/source-surveymonkey/main.py index bf4f900ad377..4daa260e708e 100644 --- a/airbyte-integrations/connectors/source-surveymonkey/main.py +++ b/airbyte-integrations/connectors/source-surveymonkey/main.py @@ -4,5 +4,6 @@ from source_surveymonkey.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-surveymonkey/metadata.yaml b/airbyte-integrations/connectors/source-surveymonkey/metadata.yaml index aeb153b6fd41..615041b8f6a4 100644 --- a/airbyte-integrations/connectors/source-surveymonkey/metadata.yaml +++ b/airbyte-integrations/connectors/source-surveymonkey/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - api.surveymonkey.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: badc5925-0485-42be-8caa-b34096cb71b5 - dockerImageTag: 0.3.28 + dockerImageTag: 0.3.33 dockerRepository: airbyte/source-surveymonkey documentationUrl: https://docs.airbyte.com/integrations/sources/surveymonkey githubIssueLabel: source-surveymonkey diff --git a/airbyte-integrations/connectors/source-surveymonkey/poetry.lock b/airbyte-integrations/connectors/source-surveymonkey/poetry.lock index 79d4eda2bdc7..c3c443f26398 100644 --- a/airbyte-integrations/connectors/source-surveymonkey/poetry.lock +++ b/airbyte-integrations/connectors/source-surveymonkey/poetry.lock @@ -42,13 +42,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] @@ -56,41 +56,41 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -156,13 +156,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -246,116 +246,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -425,20 +412,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -488,13 +475,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -509,13 +496,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -523,7 +510,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -573,13 +559,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -669,22 +655,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -861,69 +850,86 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""} [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -1004,109 +1010,93 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "propcache" -version = "0.2.0" +version = "0.2.1" description = "Accelerated property cache" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"}, - {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"}, - {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"}, - {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"}, - {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, - {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, - {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544"}, - {file = "propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032"}, - {file = "propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed"}, - {file = "propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d"}, - {file = "propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798"}, - {file = "propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9"}, - {file = "propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df"}, - {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, - {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6445804cf4ec763dc70de65a3b0d9954e868609e83850a47ca4f0cb64bd79fea"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9479aa06a793c5aeba49ce5c5692ffb51fcd9a7016e017d555d5e2b0045d212"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9631c5e8b5b3a0fda99cb0d29c18133bca1e18aea9effe55adb3da1adef80d3"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3156628250f46a0895f1f36e1d4fbe062a1af8718ec3ebeb746f1d23f0c5dc4d"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b6fb63ae352e13748289f04f37868099e69dba4c2b3e271c46061e82c745634"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:887d9b0a65404929641a9fabb6452b07fe4572b269d901d622d8a34a4e9043b2"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a96dc1fa45bd8c407a0af03b2d5218392729e1822b0c32e62c5bf7eeb5fb3958"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a7e65eb5c003a303b94aa2c3852ef130230ec79e349632d030e9571b87c4698c"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:999779addc413181912e984b942fbcc951be1f5b3663cd80b2687758f434c583"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:19a0f89a7bb9d8048d9c4370c9c543c396e894c76be5525f5e1ad287f1750ddf"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1ac2f5fe02fa75f56e1ad473f1175e11f475606ec9bd0be2e78e4734ad575034"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:574faa3b79e8ebac7cb1d7930f51184ba1ccf69adfdec53a12f319a06030a68b"}, + {file = "propcache-0.2.1-cp310-cp310-win32.whl", hash = "sha256:03ff9d3f665769b2a85e6157ac8b439644f2d7fd17615a82fa55739bc97863f4"}, + {file = "propcache-0.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:2d3af2e79991102678f53e0dbf4c35de99b6b8b58f29a27ca0325816364caaba"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e"}, + {file = "propcache-0.2.1-cp311-cp311-win32.whl", hash = "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034"}, + {file = "propcache-0.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518"}, + {file = "propcache-0.2.1-cp312-cp312-win32.whl", hash = "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246"}, + {file = "propcache-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30"}, + {file = "propcache-0.2.1-cp313-cp313-win32.whl", hash = "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6"}, + {file = "propcache-0.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6a9a8c34fb7bb609419a211e59da8887eeca40d300b5ea8e56af98f6fbbb1541"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae1aa1cd222c6d205853b3013c69cd04515f9d6ab6de4b0603e2e1c33221303e"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:accb6150ce61c9c4b7738d45550806aa2b71c7668c6942f17b0ac182b6142fd4"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5eee736daafa7af6d0a2dc15cc75e05c64f37fc37bafef2e00d77c14171c2097"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7a31fc1e1bd362874863fdeed71aed92d348f5336fd84f2197ba40c59f061bd"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba4cfa1052819d16699e1d55d18c92b6e094d4517c41dd231a8b9f87b6fa681"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f089118d584e859c62b3da0892b88a83d611c2033ac410e929cb6754eec0ed16"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:781e65134efaf88feb447e8c97a51772aa75e48b794352f94cb7ea717dedda0d"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31f5af773530fd3c658b32b6bdc2d0838543de70eb9a2156c03e410f7b0d3aae"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:a7a078f5d37bee6690959c813977da5291b24286e7b962e62a94cec31aa5188b"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:cea7daf9fc7ae6687cf1e2c049752f19f146fdc37c2cc376e7d0032cf4f25347"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:8b3489ff1ed1e8315674d0775dc7d2195fb13ca17b3808721b54dbe9fd020faf"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9403db39be1393618dd80c746cb22ccda168efce239c73af13c3763ef56ffc04"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5d97151bc92d2b2578ff7ce779cdb9174337390a535953cbb9452fb65164c587"}, + {file = "propcache-0.2.1-cp39-cp39-win32.whl", hash = "sha256:9caac6b54914bdf41bcc91e7eb9147d331d29235a7c967c150ef5df6464fd1bb"}, + {file = "propcache-0.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:92fc4500fcb33899b05ba73276dfb684a20d31caa567b7cb5252d48f896a91b1"}, + {file = "propcache-0.2.1-py3-none-any.whl", hash = "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54"}, + {file = "propcache-0.2.1.tar.gz", hash = "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64"}, ] [[package]] @@ -1122,54 +1112,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -1181,13 +1171,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1254,13 +1244,13 @@ files = [ [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] @@ -1473,33 +1463,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1530,13 +1520,43 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "tomli" -version = "2.0.2" +version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38"}, - {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] [[package]] @@ -1613,172 +1633,167 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [[package]] name = "yarl" -version = "1.17.0" +version = "1.18.3" description = "Yet another URL library" optional = false python-versions = ">=3.9" files = [ - {file = "yarl-1.17.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2d8715edfe12eee6f27f32a3655f38d6c7410deb482158c0b7d4b7fad5d07628"}, - {file = "yarl-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1803bf2a7a782e02db746d8bd18f2384801bc1d108723840b25e065b116ad726"}, - {file = "yarl-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e66589110e20c2951221a938fa200c7aa134a8bdf4e4dc97e6b21539ff026d4"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7069d411cfccf868e812497e0ec4acb7c7bf8d684e93caa6c872f1e6f5d1664d"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cbf70ba16118db3e4b0da69dcde9d4d4095d383c32a15530564c283fa38a7c52"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0bc53cc349675b32ead83339a8de79eaf13b88f2669c09d4962322bb0f064cbc"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6aa18a402d1c80193ce97c8729871f17fd3e822037fbd7d9b719864018df746"}, - {file = "yarl-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d89c5bc701861cfab357aa0cd039bc905fe919997b8c312b4b0c358619c38d4d"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b728bdf38ca58f2da1d583e4af4ba7d4cd1a58b31a363a3137a8159395e7ecc7"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:5542e57dc15d5473da5a39fbde14684b0cc4301412ee53cbab677925e8497c11"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e564b57e5009fb150cb513804d7e9e9912fee2e48835638f4f47977f88b4a39c"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:eb3c4cff524b4c1c1dba3a6da905edb1dfd2baf6f55f18a58914bbb2d26b59e1"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:05e13f389038842da930d439fbed63bdce3f7644902714cb68cf527c971af804"}, - {file = "yarl-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:153c38ee2b4abba136385af4467459c62d50f2a3f4bde38c7b99d43a20c143ef"}, - {file = "yarl-1.17.0-cp310-cp310-win32.whl", hash = "sha256:4065b4259d1ae6f70fd9708ffd61e1c9c27516f5b4fae273c41028afcbe3a094"}, - {file = "yarl-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:abf366391a02a8335c5c26163b5fe6f514cc1d79e74d8bf3ffab13572282368e"}, - {file = "yarl-1.17.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:19a4fe0279626c6295c5b0c8c2bb7228319d2e985883621a6e87b344062d8135"}, - {file = "yarl-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cadd0113f4db3c6b56868d6a19ca6286f5ccfa7bc08c27982cf92e5ed31b489a"}, - {file = "yarl-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:60d6693eef43215b1ccfb1df3f6eae8db30a9ff1e7989fb6b2a6f0b468930ee8"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb8bf3843e1fa8cf3fe77813c512818e57368afab7ebe9ef02446fe1a10b492"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d2a5b35fd1d8d90443e061d0c8669ac7600eec5c14c4a51f619e9e105b136715"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5bf17b32f392df20ab5c3a69d37b26d10efaa018b4f4e5643c7520d8eee7ac7"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48f51b529b958cd06e78158ff297a8bf57b4021243c179ee03695b5dbf9cb6e1"}, - {file = "yarl-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fcaa06bf788e19f913d315d9c99a69e196a40277dc2c23741a1d08c93f4d430"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:32f3ee19ff0f18a7a522d44e869e1ebc8218ad3ae4ebb7020445f59b4bbe5897"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:a4fb69a81ae2ec2b609574ae35420cf5647d227e4d0475c16aa861dd24e840b0"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7bacc8b77670322132a1b2522c50a1f62991e2f95591977455fd9a398b4e678d"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:437bf6eb47a2d20baaf7f6739895cb049e56896a5ffdea61a4b25da781966e8b"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:30534a03c87484092080e3b6e789140bd277e40f453358900ad1f0f2e61fc8ec"}, - {file = "yarl-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b30df4ff98703649915144be6f0df3b16fd4870ac38a09c56d5d9e54ff2d5f96"}, - {file = "yarl-1.17.0-cp311-cp311-win32.whl", hash = "sha256:263b487246858e874ab53e148e2a9a0de8465341b607678106829a81d81418c6"}, - {file = "yarl-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:07055a9e8b647a362e7d4810fe99d8f98421575e7d2eede32e008c89a65a17bd"}, - {file = "yarl-1.17.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:84095ab25ba69a8fa3fb4936e14df631b8a71193fe18bd38be7ecbe34d0f5512"}, - {file = "yarl-1.17.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:02608fb3f6df87039212fc746017455ccc2a5fc96555ee247c45d1e9f21f1d7b"}, - {file = "yarl-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13468d291fe8c12162b7cf2cdb406fe85881c53c9e03053ecb8c5d3523822cd9"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8da3f8f368fb7e2f052fded06d5672260c50b5472c956a5f1bd7bf474ae504ab"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ec0507ab6523980bed050137007c76883d941b519aca0e26d4c1ec1f297dd646"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08fc76df7fd8360e9ff30e6ccc3ee85b8dbd6ed5d3a295e6ec62bcae7601b932"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d522f390686acb6bab2b917dd9ca06740c5080cd2eaa5aef8827b97e967319d"}, - {file = "yarl-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:147c527a80bb45b3dcd6e63401af8ac574125d8d120e6afe9901049286ff64ef"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:24cf43bcd17a0a1f72284e47774f9c60e0bf0d2484d5851f4ddf24ded49f33c6"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:c28a44b9e0fba49c3857360e7ad1473fc18bc7f6659ca08ed4f4f2b9a52c75fa"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:350cacb2d589bc07d230eb995d88fcc646caad50a71ed2d86df533a465a4e6e1"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:fd1ab1373274dea1c6448aee420d7b38af163b5c4732057cd7ee9f5454efc8b1"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4934e0f96dadc567edc76d9c08181633c89c908ab5a3b8f698560124167d9488"}, - {file = "yarl-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8d0a278170d75c88e435a1ce76557af6758bfebc338435b2eba959df2552163e"}, - {file = "yarl-1.17.0-cp312-cp312-win32.whl", hash = "sha256:61584f33196575a08785bb56db6b453682c88f009cd9c6f338a10f6737ce419f"}, - {file = "yarl-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:9987a439ad33a7712bd5bbd073f09ad10d38640425fa498ecc99d8aa064f8fc4"}, - {file = "yarl-1.17.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8deda7b8eb15a52db94c2014acdc7bdd14cb59ec4b82ac65d2ad16dc234a109e"}, - {file = "yarl-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56294218b348dcbd3d7fce0ffd79dd0b6c356cb2a813a1181af730b7c40de9e7"}, - {file = "yarl-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1fab91292f51c884b290ebec0b309a64a5318860ccda0c4940e740425a67b6b7"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cf93fa61ff4d9c7d40482ce1a2c9916ca435e34a1b8451e17f295781ccc034f"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:261be774a0d71908c8830c33bacc89eef15c198433a8cc73767c10eeeb35a7d0"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deec9693b67f6af856a733b8a3e465553ef09e5e8ead792f52c25b699b8f9e6e"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c804b07622ba50a765ca7fb8145512836ab65956de01307541def869e4a456c9"}, - {file = "yarl-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d013a7c9574e98c14831a8f22d27277688ec3b2741d0188ac01a910b009987a"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e2cfcba719bd494c7413dcf0caafb51772dec168c7c946e094f710d6aa70494e"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:c068aba9fc5b94dfae8ea1cedcbf3041cd4c64644021362ffb750f79837e881f"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3616df510ffac0df3c9fa851a40b76087c6c89cbcea2de33a835fc80f9faac24"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:755d6176b442fba9928a4df787591a6a3d62d4969f05c406cad83d296c5d4e05"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c18f6e708d1cf9ff5b1af026e697ac73bea9cb70ee26a2b045b112548579bed2"}, - {file = "yarl-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5b937c216b6dee8b858c6afea958de03c5ff28406257d22b55c24962a2baf6fd"}, - {file = "yarl-1.17.0-cp313-cp313-win32.whl", hash = "sha256:d0131b14cb545c1a7bd98f4565a3e9bdf25a1bd65c83fc156ee5d8a8499ec4a3"}, - {file = "yarl-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:01c96efa4313c01329e88b7e9e9e1b2fc671580270ddefdd41129fa8d0db7696"}, - {file = "yarl-1.17.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0d44f67e193f0a7acdf552ecb4d1956a3a276c68e7952471add9f93093d1c30d"}, - {file = "yarl-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:16ea0aa5f890cdcb7ae700dffa0397ed6c280840f637cd07bffcbe4b8d68b985"}, - {file = "yarl-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cf5469dc7dcfa65edf5cc3a6add9f84c5529c6b556729b098e81a09a92e60e51"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e662bf2f6e90b73cf2095f844e2bc1fda39826472a2aa1959258c3f2a8500a2f"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8260e88f1446904ba20b558fa8ce5d0ab9102747238e82343e46d056d7304d7e"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dc16477a4a2c71e64c5d3d15d7ae3d3a6bb1e8b955288a9f73c60d2a391282f"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46027e326cecd55e5950184ec9d86c803f4f6fe4ba6af9944a0e537d643cdbe0"}, - {file = "yarl-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc95e46c92a2b6f22e70afe07e34dbc03a4acd07d820204a6938798b16f4014f"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:16ca76c7ac9515320cd09d6cc083d8d13d1803f6ebe212b06ea2505fd66ecff8"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:eb1a5b97388f2613f9305d78a3473cdf8d80c7034e554d8199d96dcf80c62ac4"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:41fd5498975418cdc34944060b8fbeec0d48b2741068077222564bea68daf5a6"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:146ca582ed04a5664ad04b0e0603934281eaab5c0115a5a46cce0b3c061a56a1"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:6abb8c06107dbec97481b2392dafc41aac091a5d162edf6ed7d624fe7da0587a"}, - {file = "yarl-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4d14be4613dd4f96c25feb4bd8c0d8ce0f529ab0ae555a17df5789e69d8ec0c5"}, - {file = "yarl-1.17.0-cp39-cp39-win32.whl", hash = "sha256:174d6a6cad1068f7850702aad0c7b1bca03bcac199ca6026f84531335dfc2646"}, - {file = "yarl-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:6af417ca2c7349b101d3fd557ad96b4cd439fdb6ab0d288e3f64a068eea394d0"}, - {file = "yarl-1.17.0-py3-none-any.whl", hash = "sha256:62dd42bb0e49423f4dd58836a04fcf09c80237836796025211bbe913f1524993"}, - {file = "yarl-1.17.0.tar.gz", hash = "sha256:d3f13583f378930377e02002b4085a3d025b00402d5a80911726d43a67911cd9"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:602d98f2c2d929f8e697ed274fbadc09902c4025c5a9963bf4e9edfc3ab6f7ed"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c654d5207c78e0bd6d749f6dae1dcbbfde3403ad3a4b11f3c5544d9906969dde"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5094d9206c64181d0f6e76ebd8fb2f8fe274950a63890ee9e0ebfd58bf9d787b"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35098b24e0327fc4ebdc8ffe336cee0a87a700c24ffed13161af80124b7dc8e5"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3236da9272872443f81fedc389bace88408f64f89f75d1bdb2256069a8730ccc"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c08cc9b16f4f4bc522771d96734c7901e7ebef70c6c5c35dd0f10845270bcd"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80316a8bd5109320d38eef8833ccf5f89608c9107d02d2a7f985f98ed6876990"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1e1cc06da1491e6734f0ea1e6294ce00792193c463350626571c287c9a704db"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fea09ca13323376a2fdfb353a5fa2e59f90cd18d7ca4eaa1fd31f0a8b4f91e62"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e3b9fd71836999aad54084906f8663dffcd2a7fb5cdafd6c37713b2e72be1760"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:757e81cae69244257d125ff31663249b3013b5dc0a8520d73694aed497fb195b"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b1771de9944d875f1b98a745bc547e684b863abf8f8287da8466cf470ef52690"}, + {file = "yarl-1.18.3-cp310-cp310-win32.whl", hash = "sha256:8874027a53e3aea659a6d62751800cf6e63314c160fd607489ba5c2edd753cf6"}, + {file = "yarl-1.18.3-cp310-cp310-win_amd64.whl", hash = "sha256:93b2e109287f93db79210f86deb6b9bbb81ac32fc97236b16f7433db7fc437d8"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8503ad47387b8ebd39cbbbdf0bf113e17330ffd339ba1144074da24c545f0069"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02ddb6756f8f4517a2d5e99d8b2f272488e18dd0bfbc802f31c16c6c20f22193"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67a283dd2882ac98cc6318384f565bffc751ab564605959df4752d42483ad889"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d980e0325b6eddc81331d3f4551e2a333999fb176fd153e075c6d1c2530aa8a8"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b643562c12680b01e17239be267bc306bbc6aac1f34f6444d1bded0c5ce438ca"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c017a3b6df3a1bd45b9fa49a0f54005e53fbcad16633870104b66fa1a30a29d8"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75674776d96d7b851b6498f17824ba17849d790a44d282929c42dbb77d4f17ae"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccaa3a4b521b780a7e771cc336a2dba389a0861592bbce09a476190bb0c8b4b3"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d06d3005e668744e11ed80812e61efd77d70bb7f03e33c1598c301eea20efbb"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:9d41beda9dc97ca9ab0b9888cb71f7539124bc05df02c0cff6e5acc5a19dcc6e"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ba23302c0c61a9999784e73809427c9dbedd79f66a13d84ad1b1943802eaaf59"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6748dbf9bfa5ba1afcc7556b71cda0d7ce5f24768043a02a58846e4a443d808d"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0b0cad37311123211dc91eadcb322ef4d4a66008d3e1bdc404808992260e1a0e"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0fb2171a4486bb075316ee754c6d8382ea6eb8b399d4ec62fde2b591f879778a"}, + {file = "yarl-1.18.3-cp311-cp311-win32.whl", hash = "sha256:61b1a825a13bef4a5f10b1885245377d3cd0bf87cba068e1d9a88c2ae36880e1"}, + {file = "yarl-1.18.3-cp311-cp311-win_amd64.whl", hash = "sha256:b9d60031cf568c627d028239693fd718025719c02c9f55df0a53e587aab951b5"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285"}, + {file = "yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2"}, + {file = "yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:90adb47ad432332d4f0bc28f83a5963f426ce9a1a8809f5e584e704b82685dcb"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:913829534200eb0f789d45349e55203a091f45c37a2674678744ae52fae23efa"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ef9f7768395923c3039055c14334ba4d926f3baf7b776c923c93d80195624782"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a19f62ff30117e706ebc9090b8ecc79aeb77d0b1f5ec10d2d27a12bc9f66d0"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e17c9361d46a4d5addf777c6dd5eab0715a7684c2f11b88c67ac37edfba6c482"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a74a13a4c857a84a845505fd2d68e54826a2cd01935a96efb1e9d86c728e186"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41f7ce59d6ee7741af71d82020346af364949314ed3d87553763a2df1829cc58"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f52a265001d830bc425f82ca9eabda94a64a4d753b07d623a9f2863fde532b53"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:82123d0c954dc58db301f5021a01854a85bf1f3bb7d12ae0c01afc414a882ca2"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2ec9bbba33b2d00999af4631a3397d1fd78290c48e2a3e52d8dd72db3a067ac8"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbd6748e8ab9b41171bb95c6142faf068f5ef1511935a0aa07025438dd9a9bc1"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:877d209b6aebeb5b16c42cbb377f5f94d9e556626b1bfff66d7b0d115be88d0a"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b464c4ab4bfcb41e3bfd3f1c26600d038376c2de3297760dfe064d2cb7ea8e10"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8d39d351e7faf01483cc7ff7c0213c412e38e5a340238826be7e0e4da450fdc8"}, + {file = "yarl-1.18.3-cp313-cp313-win32.whl", hash = "sha256:61ee62ead9b68b9123ec24bc866cbef297dd266175d53296e2db5e7f797f902d"}, + {file = "yarl-1.18.3-cp313-cp313-win_amd64.whl", hash = "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:61e5e68cb65ac8f547f6b5ef933f510134a6bf31bb178be428994b0cb46c2a04"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe57328fbc1bfd0bd0514470ac692630f3901c0ee39052ae47acd1d90a436719"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a440a2a624683108a1b454705ecd7afc1c3438a08e890a1513d468671d90a04e"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09c7907c8548bcd6ab860e5f513e727c53b4a714f459b084f6580b49fa1b9cee"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4f6450109834af88cb4cc5ecddfc5380ebb9c228695afc11915a0bf82116789"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9ca04806f3be0ac6d558fffc2fdf8fcef767e0489d2684a21912cc4ed0cd1b8"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77a6e85b90a7641d2e07184df5557132a337f136250caafc9ccaa4a2a998ca2c"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6333c5a377c8e2f5fae35e7b8f145c617b02c939d04110c76f29ee3676b5f9a5"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0b3c92fa08759dbf12b3a59579a4096ba9af8dd344d9a813fc7f5070d86bbab1"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4ac515b860c36becb81bb84b667466885096b5fc85596948548b667da3bf9f24"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:045b8482ce9483ada4f3f23b3774f4e1bf4f23a2d5c912ed5170f68efb053318"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:a4bb030cf46a434ec0225bddbebd4b89e6471814ca851abb8696170adb163985"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:54d6921f07555713b9300bee9c50fb46e57e2e639027089b1d795ecd9f7fa910"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1d407181cfa6e70077df3377938c08012d18893f9f20e92f7d2f314a437c30b1"}, + {file = "yarl-1.18.3-cp39-cp39-win32.whl", hash = "sha256:ac36703a585e0929b032fbaab0707b75dc12703766d0b53486eabd5139ebadd5"}, + {file = "yarl-1.18.3-cp39-cp39-win_amd64.whl", hash = "sha256:ba87babd629f8af77f557b61e49e7c7cac36f22f871156b91e10a6e9d4f829e9"}, + {file = "yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b"}, + {file = "yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1"}, ] [package.dependencies] diff --git a/airbyte-integrations/connectors/source-surveymonkey/pyproject.toml b/airbyte-integrations/connectors/source-surveymonkey/pyproject.toml index 1354d3720414..5eda811a5495 100644 --- a/airbyte-integrations/connectors/source-surveymonkey/pyproject.toml +++ b/airbyte-integrations/connectors/source-surveymonkey/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.3.28" +version = "0.3.33" name = "source-surveymonkey" description = "Source implementation for Surveymonkey." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-surveymonkey/source_surveymonkey/config_migrations.py b/airbyte-integrations/connectors/source-surveymonkey/source_surveymonkey/config_migrations.py index 98709c3e5f93..8c96e04e6453 100644 --- a/airbyte-integrations/connectors/source-surveymonkey/source_surveymonkey/config_migrations.py +++ b/airbyte-integrations/connectors/source-surveymonkey/source_surveymonkey/config_migrations.py @@ -11,6 +11,7 @@ from airbyte_cdk.sources import Source from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository + logger = logging.getLogger("airbyte_logger") diff --git a/airbyte-integrations/connectors/source-surveymonkey/source_surveymonkey/source.py b/airbyte-integrations/connectors/source-surveymonkey/source_surveymonkey/source.py index 18dcacd06ea2..f2951a5f1903 100644 --- a/airbyte-integrations/connectors/source-surveymonkey/source_surveymonkey/source.py +++ b/airbyte-integrations/connectors/source-surveymonkey/source_surveymonkey/source.py @@ -7,12 +7,14 @@ import pendulum import requests + from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator from .streams import Surveys + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-surveymonkey/source_surveymonkey/streams.py b/airbyte-integrations/connectors/source-surveymonkey/source_surveymonkey/streams.py index 33f1740a68e4..ff46c119e1ef 100644 --- a/airbyte-integrations/connectors/source-surveymonkey/source_surveymonkey/streams.py +++ b/airbyte-integrations/connectors/source-surveymonkey/source_surveymonkey/streams.py @@ -10,11 +10,13 @@ import pendulum import requests import vcr + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.streams.availability_strategy import AvailabilityStrategy from airbyte_cdk.sources.streams.core import CheckpointMixin from airbyte_cdk.sources.streams.http import HttpStream + cache_file = tempfile.NamedTemporaryFile() diff --git a/airbyte-integrations/connectors/source-surveymonkey/unit_tests/conftest.py b/airbyte-integrations/connectors/source-surveymonkey/unit_tests/conftest.py index 74c9ae98ad01..0d1451270f99 100644 --- a/airbyte-integrations/connectors/source-surveymonkey/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-surveymonkey/unit_tests/conftest.py @@ -6,37 +6,37 @@ import pendulum import pytest +from source_surveymonkey.source import SourceSurveymonkey + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.declarative.incremental.per_partition_cursor import StreamSlice -from source_surveymonkey.source import SourceSurveymonkey -@pytest.fixture(name='read_json') +@pytest.fixture(name="read_json") def read_json_fixture(request): def read_json(file_name, skip_folder=False): if not skip_folder: - folder_name = request.node.fspath.basename.split('.')[0] + folder_name = request.node.fspath.basename.split(".")[0] with open("unit_tests/" + folder_name + "/" + file_name) as f: return json.load(f) + return read_json -@pytest.fixture(name='read_records') + +@pytest.fixture(name="read_records") def read_records_fixture(config): def read_records(stream_name, slice=StreamSlice(partition={"survey_id": "307785415"}, cursor_slice={})): stream = next(filter(lambda x: x.name == stream_name, SourceSurveymonkey().streams(config=config))) - records = list( - map(lambda record: record.data, stream.read_records(sync_mode=SyncMode.full_refresh, stream_slice=slice))) + records = list(map(lambda record: record.data, stream.read_records(sync_mode=SyncMode.full_refresh, stream_slice=slice))) return records + return read_records @pytest.fixture def args_mock(): - return { - "authenticator": None, - "start_date": pendulum.parse("2000-01-01"), - "survey_ids": [] - } + return {"authenticator": None, "start_date": pendulum.parse("2000-01-01"), "survey_ids": []} + @pytest.fixture def config(args_mock): @@ -44,5 +44,5 @@ def config(args_mock): **args_mock, "survey_ids": ["307785415"], "credentials": {"access_token": "access_token"}, - "start_date": args_mock["start_date"].to_iso8601_string() + "start_date": args_mock["start_date"].to_iso8601_string(), } diff --git a/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_config_migrations.py b/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_config_migrations.py index 4e4fde8edf32..8f42734f7fd0 100644 --- a/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_config_migrations.py +++ b/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_config_migrations.py @@ -8,6 +8,7 @@ from source_surveymonkey.config_migrations import MigrateAccessTokenToCredentials from source_surveymonkey.source import SourceSurveymonkey + TEST_CONFIG = "test_old_config.json" NEW_TEST_CONFIG = "test_new_config.json" UPGRADED_TEST_CONFIG = "test_upgraded_config.json" diff --git a/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_custom_router.py b/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_custom_router.py index eaa7b4d15176..5af6707b9a7b 100644 --- a/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_custom_router.py +++ b/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_custom_router.py @@ -6,9 +6,11 @@ from unittest.mock import Mock import pytest -from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig from source_surveymonkey.components import SurveyIdPartitionRouter +from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig + + # test cases as a list of tuples (survey_ids, parent_stream_configs, expected_slices) test_cases = [ ( diff --git a/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_for_updated_state.py b/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_for_updated_state.py index 32ef91a401c6..9800cc794fd7 100644 --- a/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_for_updated_state.py +++ b/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_for_updated_state.py @@ -4,9 +4,10 @@ import pendulum import pytest -from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator from source_surveymonkey.streams import Surveys +from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator + class TestSurveymonkeySource: @staticmethod diff --git a/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_source.py b/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_source.py index a397163a108b..69850063503b 100644 --- a/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_source.py @@ -4,6 +4,7 @@ from source_surveymonkey.source import SourceSurveymonkey + source_config = {"start_date": "2021-01-01T00:00:00", "access_token": "something"} new_source_config = { "start_date": "2021-01-01T00:00:00", diff --git a/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_streams.py index 24a60bc08d95..66a14003d899 100644 --- a/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-surveymonkey/unit_tests/test_streams.py @@ -5,14 +5,15 @@ from unittest.mock import Mock import pytest -from airbyte_cdk.models import SyncMode from source_surveymonkey.streams import SurveyIds, Surveys +from airbyte_cdk.models import SyncMode + -@pytest.mark.parametrize("stream, expected_records_file, stream_slice", [ - (SurveyIds, "records_survey_ids.json", None), - (Surveys, "records_surveys.json", {"survey_id": "307785415"}) -]) +@pytest.mark.parametrize( + "stream, expected_records_file, stream_slice", + [(SurveyIds, "records_survey_ids.json", None), (Surveys, "records_surveys.json", {"survey_id": "307785415"})], +) def test_survey_stream_read_records(requests_mock, args_mock, read_json, stream, expected_records_file, stream_slice): requests_mock.get( "https://api.surveymonkey.com/v3/surveys", @@ -30,8 +31,11 @@ def test_survey_stream_read_records(requests_mock, args_mock, read_json, stream, } }, }, - {"status_code": 200, "headers": {"X-Ratelimit-App-Global-Minute-Remaining": "100"}, - "json": read_json("response_survey_ids.json")}, + { + "status_code": 200, + "headers": {"X-Ratelimit-App-Global-Minute-Remaining": "100"}, + "json": read_json("response_survey_ids.json"), + }, ], ) requests_mock.get("https://api.surveymonkey.com/v3/surveys/307785415/details", json=read_json("response_survey_details.json")) @@ -42,10 +46,10 @@ def test_survey_stream_read_records(requests_mock, args_mock, read_json, stream, assert list(records) == expected_records -@pytest.mark.parametrize("additional_arguments, expected_slices", [ - ({}, [{"survey_id": "307785415"}, {"survey_id": "307785388"}]), - ({"survey_ids": ["307785415"]}, [{"survey_id": "307785415"}]) -]) +@pytest.mark.parametrize( + "additional_arguments, expected_slices", + [({}, [{"survey_id": "307785415"}, {"survey_id": "307785388"}]), ({"survey_ids": ["307785415"]}, [{"survey_id": "307785415"}])], +) def test_survey_slices(requests_mock, args_mock, read_json, additional_arguments, expected_slices): if not additional_arguments: requests_mock.get("https://api.surveymonkey.com/v3/surveys", json=read_json("response_survey_ids.json")) @@ -54,11 +58,14 @@ def test_survey_slices(requests_mock, args_mock, read_json, additional_arguments assert list(stream_slices) == expected_slices -@pytest.mark.parametrize("endpoint, records_filename", [ - ("survey_pages", "records_survey_pages.json"), - ("survey_questions", "records_survey_questions.json"), - ("survey_collectors", "records_survey_collectors.json") -]) +@pytest.mark.parametrize( + "endpoint, records_filename", + [ + ("survey_pages", "records_survey_pages.json"), + ("survey_questions", "records_survey_questions.json"), + ("survey_collectors", "records_survey_collectors.json"), + ], +) def test_survey_data(requests_mock, read_records, read_json, endpoint, records_filename): requests_mock.get("https://api.surveymonkey.com/v3/surveys/307785415/details", json=read_json("response_survey_details.json")) requests_mock.get("https://api.surveymonkey.com/v3/surveys/307785415/collectors", json=read_json("response_survey_collectors.json")) diff --git a/airbyte-integrations/connectors/source-survicate/metadata.yaml b/airbyte-integrations/connectors/source-survicate/metadata.yaml index a9689f274b96..c86c149f7537 100644 --- a/airbyte-integrations/connectors/source-survicate/metadata.yaml +++ b/airbyte-integrations/connectors/source-survicate/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-survicate connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 5770c58b-3288-4fa0-a968-bb8a6607fae1 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-survicate githubIssueLabel: source-survicate icon: icon.svg diff --git a/airbyte-integrations/connectors/source-systeme/README.md b/airbyte-integrations/connectors/source-systeme/README.md new file mode 100644 index 000000000000..a571fe472b31 --- /dev/null +++ b/airbyte-integrations/connectors/source-systeme/README.md @@ -0,0 +1,35 @@ +# Systeme +This directory contains the manifest-only connector for `source-systeme`. + +Systeme is an all in one marketing platform. +Using this connector we can extarct records from communities , contacts , tags , contact fields and course resources streams. +Docs : https://developer.systeme.io/reference/api + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-systeme:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-systeme build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-systeme test +``` + diff --git a/airbyte-integrations/connectors/source-systeme/acceptance-test-config.yml b/airbyte-integrations/connectors/source-systeme/acceptance-test-config.yml new file mode 100644 index 000000000000..e61deab32ea6 --- /dev/null +++ b/airbyte-integrations/connectors/source-systeme/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-systeme:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-systeme/icon.svg b/airbyte-integrations/connectors/source-systeme/icon.svg new file mode 100644 index 000000000000..f71de06c9006 --- /dev/null +++ b/airbyte-integrations/connectors/source-systeme/icon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-systeme/manifest.yaml b/airbyte-integrations/connectors/source-systeme/manifest.yaml new file mode 100644 index 000000000000..ab4bbb3b999c --- /dev/null +++ b/airbyte-integrations/connectors/source-systeme/manifest.yaml @@ -0,0 +1,451 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + Systeme is an all in one marketing platform. + + Using this connector we can extarct records from communities, contacts, tags, contact fields and course resources streams. + + Docs : https://developer.systeme.io/reference/api + +check: + type: CheckStream + stream_names: + - communities + +definitions: + streams: + communities: + type: DeclarativeStream + name: communities + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: community/communities + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ response.hasMore is false }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/communities" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: contacts + http_method: GET + request_headers: + accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ response.hasMore is false }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + tags: + type: DeclarativeStream + name: tags + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: tags + http_method: GET + request_headers: + accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ response.hasMore is false }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tags" + contact_fields: + type: DeclarativeStream + name: contact_fields + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: contact_fields + http_method: GET + request_headers: + accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ response.hasMore is false }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contact_fields" + course_resources: + type: DeclarativeStream + name: course_resources + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: school/courses + http_method: GET + request_headers: + accept: application/json + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: startingAfter + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ response.hasMore is false }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/course_resources" + base_requester: + type: HttpRequester + url_base: https://api.systeme.io/api/ + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: X-API-Key + inject_into: header + +streams: + - $ref: "#/definitions/streams/communities" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/tags" + - $ref: "#/definitions/streams/contact_fields" + - $ref: "#/definitions/streams/course_resources" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + order: 0 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + communities: true + contacts: true + tags: true + contact_fields: true + course_resources: true + testedStreams: + communities: + streamHash: c1225da50424eadc73af707657a9da51738a86b7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contacts: + streamHash: 5468020d1e37baf53374c70b0d21406bd71bc353 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tags: + streamHash: 4e3483527bfbd9a63d8750528650257407a38b69 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contact_fields: + streamHash: b5735729e7b2c7ddcc3f2b1f76f242dbbc73c742 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + course_resources: + hasRecords: true + streamHash: 9191f05b35d42891f54aa2d0963952240aac1053 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: {} + +schemas: + communities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + domainName: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + path: + type: + - string + - "null" + required: + - id + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + bounced: + type: + - boolean + - "null" + email: + type: + - string + - "null" + fields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + fieldName: + type: + - string + - "null" + slug: + type: + - string + - "null" + value: + type: + - string + - "null" + id: + type: number + locale: + type: + - string + - "null" + needsConfirmation: + type: + - boolean + - "null" + registeredAt: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + unsubscribed: + type: + - boolean + - "null" + required: + - id + tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + required: + - id + contact_fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + fieldName: + type: + - string + - "null" + slug: + type: + - string + - "null" + course_resources: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active: + type: + - boolean + - "null" + domainName: + type: + - string + - "null" + id: + type: number + locale: + type: + - string + - "null" + modules: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + name: + type: + - string + - "null" + path: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-systeme/metadata.yaml b/airbyte-integrations/connectors/source-systeme/metadata.yaml new file mode 100644 index 000000000000..c99922927bb4 --- /dev/null +++ b/airbyte-integrations/connectors/source-systeme/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.systeme.io" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-systeme + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 2e731a08-e503-4caf-998a-92bd4afd80c1 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-systeme + githubIssueLabel: source-systeme + icon: icon.svg + license: MIT + name: Systeme + releaseDate: 2024-10-30 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/systeme + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-taboola/README.md b/airbyte-integrations/connectors/source-taboola/README.md new file mode 100644 index 000000000000..e4d4de6d6a28 --- /dev/null +++ b/airbyte-integrations/connectors/source-taboola/README.md @@ -0,0 +1,39 @@ +# Taboola +This directory contains the manifest-only connector for `source-taboola`. + +This is the Taboola source that ingests data from the Taboola API. + +Taboola helps you reach customers that convert. Drive business results by reaching people genuinely, effectively at just the right moment https://www.taboola.com/ + +In order to use this source, you must first create an account. Once logged in you can contact Taboola support to provide you with a Client ID, Client Secret and Account ID. Once these credentials have been obtained, you can input them into the appropriate fields. + +You can learn more about the API here https://developers.taboola.com/backstage-api/reference + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-taboola:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-taboola build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-taboola test +``` + diff --git a/airbyte-integrations/connectors/source-taboola/acceptance-test-config.yml b/airbyte-integrations/connectors/source-taboola/acceptance-test-config.yml new file mode 100644 index 000000000000..982a88d91231 --- /dev/null +++ b/airbyte-integrations/connectors/source-taboola/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-taboola:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-taboola/icon.svg b/airbyte-integrations/connectors/source-taboola/icon.svg new file mode 100644 index 000000000000..ea523afea87b --- /dev/null +++ b/airbyte-integrations/connectors/source-taboola/icon.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-taboola/manifest.yaml b/airbyte-integrations/connectors/source-taboola/manifest.yaml new file mode 100644 index 000000000000..7f689ccd34d9 --- /dev/null +++ b/airbyte-integrations/connectors/source-taboola/manifest.yaml @@ -0,0 +1,1260 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + This is the Taboola source that ingests data from the Taboola API. + + + Taboola helps you reach customers that convert. Drive business results by + reaching people genuinely, effectively at just the right moment + https://www.taboola.com/ + + + In order to use this source, you must first create an account. Once logged in + you can contact Taboola support to provide you with a Client ID, Client Secret + and Account ID. Once these credentials have been obtained, you can input them + into the appropriate fields. + + + You can learn more about the API here + https://developers.taboola.com/backstage-api/reference + +check: + type: CheckStream + stream_names: + - account + +definitions: + streams: + account: + type: DeclarativeStream + name: account + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: backstage/api/1.0/users/current/allowed-accounts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/account" + audiences: + type: DeclarativeStream + name: audiences + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + backstage/api/1.0/{{ + config["account_id"]}}/combined_audiences/resources/audiences + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/audiences" + campaigns: + type: DeclarativeStream + name: campaigns + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /backstage/api/1.0/{{ config["account_id"] }}/campaigns/ + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/campaigns" + motion_ads: + type: DeclarativeStream + name: motion_ads + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /backstage/api/1.0/{{ config["account_id"] }}/campaigns/{{ + stream_partition.parent_id }}/performance-video/items/ + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: + $ref: "#/definitions/streams/campaigns" + parent_key: id + partition_field: parent_id + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/motion_ads" + audience_rules: + type: DeclarativeStream + name: audience_rules + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /backstage/api/1.0/{{ config["account_id"] + }}/universal_pixel/custom_audience_rule + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/audience_rules" + campaign_items: + type: DeclarativeStream + name: campaign_items + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /backstage/api/1.0/{{ config["account_id"] }}/campaigns/{{ + stream_partition.parent_id }}/items/ + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: + $ref: "#/definitions/streams/campaigns" + parent_key: id + partition_field: parent_id + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/campaign_items" + conversion_rules: + type: DeclarativeStream + name: conversion_rules + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /backstage/api/1.0/{{ config["account_id"] + }}/universal_pixel/conversion_rule + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/conversion_rules" + base_requester: + type: HttpRequester + url_base: https://backstage.taboola.com + authenticator: + type: OAuthAuthenticator + client_id: "{{ config[\"client_id\"] }}" + grant_type: client_credentials + client_secret: "{{ config[\"client_secret\"] }}" + access_token_name: access_token + refresh_request_body: {} + token_refresh_endpoint: https://backstage.taboola.com/backstage/oauth/token + +streams: + - $ref: "#/definitions/streams/account" + - $ref: "#/definitions/streams/campaigns" + - $ref: "#/definitions/streams/campaign_items" + - $ref: "#/definitions/streams/audience_rules" + - $ref: "#/definitions/streams/conversion_rules" + - $ref: "#/definitions/streams/motion_ads" + - $ref: "#/definitions/streams/audiences" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - client_id + - client_secret + - account_id + properties: + client_id: + type: string + order: 0 + title: Client ID + airbyte_secret: true + account_id: + type: string + description: The ID associated with your taboola account + order: 2 + title: Account ID + client_secret: + type: string + order: 1 + title: Client secret + airbyte_secret: true + additionalProperties: true + +metadata: + assist: {} + testedStreams: + account: + hasRecords: true + streamHash: c0e4963d6cadfe3fa143ae49734e5d9cc889684b + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + audiences: + hasRecords: true + streamHash: 082a5eaa73d4b0c8760b6ddb088d52d34a9c77db + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + campaigns: + hasRecords: true + streamHash: d966feac19f7d299089c2544174b780b40dbda8a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + motion_ads: + hasRecords: true + streamHash: c2a2b9778f2a76a1e82d96247b87a05aaff86ca1 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + audience_rules: + hasRecords: true + streamHash: c5d52d8fd716911fef81d1e65dd291e4b6332464 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + campaign_items: + hasRecords: true + streamHash: 8baabb3aa0e3b9f19901b527bb844fff967d9b40 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + conversion_rules: + hasRecords: true + streamHash: b00c3d15be83f431de7e5ec6696e6593e1afb9da + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + autoImportSchema: + account: true + audiences: true + campaigns: true + motion_ads: true + audience_rules: true + campaign_items: true + conversion_rules: true + +schemas: + account: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + type: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + is_fla: + type: + - boolean + - "null" + country: + type: + - string + - "null" + currency: + type: + - string + - "null" + language: + type: + - string + - "null" + is_active: + type: + - boolean + - "null" + account_id: + type: + - string + - "null" + partner_types: + type: + - array + - "null" + items: + type: + - string + - "null" + campaign_types: + type: + - array + - "null" + items: + type: + - string + - "null" + time_zone_name: + type: + - string + - "null" + default_platform: + type: + - string + - "null" + additionalProperties: true + audiences: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + description: + type: + - string + - "null" + id: + type: number + size: + type: + - number + - "null" + provider: + type: + - string + - "null" + data_type: + type: + - string + - "null" + is_archived: + type: + - boolean + - "null" + audience_name: + type: + - string + - "null" + exclude_from_campaigns: + type: + - boolean + - "null" + additionalProperties: true + campaigns: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + type: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + spent: + type: + - number + - "null" + status: + type: + - string + - "null" + bid_type: + type: + - string + - "null" + comments: + type: + - string + - "null" + cpa_goal: + type: + - number + - "null" + end_date: + type: + - string + - "null" + daily_cap: + type: + - number + - "null" + is_active: + type: + - boolean + - "null" + start_date: + type: + - string + - "null" + bid_strategy: + type: + - string + - "null" + os_targeting: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - array + - "null" + advertiser_id: + type: + - string + - "null" + branding_text: + type: + - string + - "null" + policy_review: + type: + - object + - "null" + properties: {} + pricing_model: + type: + - string + - "null" + safety_rating: + type: + - string + - "null" + tracking_code: + type: + - string + - "null" + approval_state: + type: + - string + - "null" + city_targeting: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - array + - "null" + spending_limit: + type: + - number + - "null" + end_date_in_utc: + type: + - string + - "null" + conversion_rules: + type: + - object + - "null" + properties: + rules: + type: + - array + - "null" + activity_schedule: + type: + - object + - "null" + properties: + mode: + type: + - string + - "null" + rules: + type: + - array + - "null" + time_zone: + type: + - string + - "null" + browser_targeting: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - array + - "null" + country_targeting: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - array + - "null" + start_date_in_utc: + type: + - string + - "null" + campaign_item_type: + type: + - string + - "null" + platform_targeting: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - array + - "null" + items: + type: + - string + - "null" + segments_targeting: + type: + - object + - "null" + properties: + AGE: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + href: + type: + - string + - "null" + value: + type: + - array + - "null" + GENDER: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + href: + type: + - string + - "null" + value: + type: + - array + - "null" + audiences_targeting: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + state: + type: + - string + - "null" + marketing_objective: + type: + - string + - "null" + publisher_targeting: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - array + - "null" + contextual_targeting: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - array + - "null" + performance_rule_ids: + type: + - array + - "null" + spending_limit_model: + type: + - string + - "null" + day_time_bid_modifier: + type: + - object + - "null" + properties: + values: + type: + - array + - "null" + dma_country_targeting: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - array + - "null" + external_brand_safety: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + values: + type: + - array + - "null" + is_spend_guard_active: + type: + - string + - "null" + platform_bid_modifier: + type: + - object + - "null" + properties: + values: + type: + - array + - "null" + postal_code_targeting: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + href: + type: + - string + - "null" + sub_country_targeting: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - array + - "null" + publisher_bid_modifier: + type: + - object + - "null" + properties: + values: + type: + - array + - "null" + daily_ad_delivery_model: + type: + - string + - "null" + traffic_allocation_mode: + type: + - string + - "null" + auto_publisher_targeting: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - array + - "null" + region_country_targeting: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - array + - "null" + connection_type_targeting: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + value: + type: + - array + - "null" + custom_audience_targeting: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + state: + type: + - string + - "null" + custom_contextual_targeting: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + state: + type: + - string + - "null" + lookalike_audience_targeting: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + state: + type: + - string + - "null" + predefined_targeting_options: + type: + - object + - "null" + properties: + predefined_supply_targeting: + type: + - string + - "null" + contextual_segments_targeting: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + state: + type: + - string + - "null" + marking_label_multi_targeting: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + state: + type: + - string + - "null" + publisher_platform_bid_modifier: + type: + - object + - "null" + properties: + values: + type: + - array + - "null" + publisher_bid_strategy_modifiers: + type: + - object + - "null" + properties: + values: + type: + - array + - "null" + audience_segments_multi_targeting: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + state: + type: + - string + - "null" + additionalProperties: true + motion_ads: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + description: + type: + - string + - "null" + id: + type: string + url: + type: + - string + - "null" + title: + type: + - string + - "null" + status: + type: + - string + - "null" + gif_url: + type: + - string + - "null" + is_active: + type: + - boolean + - "null" + video_url: + type: + - string + - "null" + campaign_id: + type: + - string + - "null" + custom_data: + type: + - object + - "null" + properties: + custom_id: + type: + - string + - "null" + creative_name: + type: + - string + - "null" + fallback_url: + type: + - string + - "null" + policy_review: + type: + - object + - "null" + properties: {} + approval_state: + type: + - string + - "null" + motion_ads_studio: + type: + - object + - "null" + properties: + vendor_video_id: + type: + - string + - "null" + vendor_template_type: + type: + - string + - "null" + media_upload_source: + type: + - string + - "null" + recommended_fbimage: + type: + - string + - "null" + additionalProperties: true + audience_rules: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + type: + type: + - string + - "null" + id: + type: number + status: + type: + - string + - "null" + category: + type: + - string + - "null" + condition: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + children: + type: + - array + - "null" + property: + type: + - string + - "null" + predicate: + type: + - string + - "null" + event_name: + type: + - string + - "null" + display_name: + type: + - string + - "null" + advertiser_id: + type: + - string + - "null" + audience_size: + type: + - number + - "null" + last_modified_at: + type: + - string + - "null" + last_modified_by: + type: + - string + - "null" + look_back_window: + type: + - number + - "null" + exclude_from_campaigns: + type: + - boolean + - "null" + additionalProperties: true + campaign_items: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + id: + type: string + url: + type: + - string + - "null" + title: + type: + - string + - "null" + status: + type: + - string + - "null" + is_active: + type: + - boolean + - "null" + campaign_id: + type: + - string + - "null" + custom_data: + type: + - object + - "null" + properties: + custom_id: + type: + - string + - "null" + creative_name: + type: + - string + - "null" + policy_review: + type: + - object + - "null" + properties: {} + thumbnail_url: + type: + - string + - "null" + approval_state: + type: + - string + - "null" + creative_focus: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + additionalProperties: true + conversion_rules: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + type: + type: + - string + - "null" + id: + type: number + status: + type: + - string + - "null" + effects: + type: + - array + - "null" + category: + type: + - string + - "null" + condition: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + children: + type: + - array + - "null" + property: + type: + - string + - "null" + predicate: + type: + - string + - "null" + event_name: + type: + - string + - "null" + display_name: + type: + - string + - "null" + advertiser_id: + type: + - string + - "null" + aggregation_type: + type: + - string + - "null" + last_modified_at: + type: + - string + - "null" + last_modified_by: + type: + - string + - "null" + look_back_window: + type: + - number + - "null" + exclude_from_campaigns: + type: + - boolean + - "null" + include_in_total_value: + type: + - boolean + - "null" + include_in_total_conversions: + type: + - boolean + - "null" + view_through_look_back_window: + type: + - number + - "null" + additionalProperties: true diff --git a/airbyte-integrations/connectors/source-taboola/metadata.yaml b/airbyte-integrations/connectors/source-taboola/metadata.yaml new file mode 100644 index 000000000000..6d486ca4b804 --- /dev/null +++ b/airbyte-integrations/connectors/source-taboola/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "backstage.taboola.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-taboola + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 40bb20de-e03c-4aa2-80bc-72234598380f + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-taboola + githubIssueLabel: source-taboola + icon: icon.svg + license: MIT + name: Taboola + releaseDate: 2024-10-28 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/taboola + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-teamtailor/metadata.yaml b/airbyte-integrations/connectors/source-teamtailor/metadata.yaml index c2e3c5b34681..c6a9eaee5694 100644 --- a/airbyte-integrations/connectors/source-teamtailor/metadata.yaml +++ b/airbyte-integrations/connectors/source-teamtailor/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-teamtailor connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 6d811b1b-5b94-4d5a-a74a-c2e46e5cb87c - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-teamtailor githubIssueLabel: source-teamtailor icon: icon.svg diff --git a/airbyte-integrations/connectors/source-teamwork/metadata.yaml b/airbyte-integrations/connectors/source-teamwork/metadata.yaml index b8df2dab5ee5..d34c2f3a146d 100644 --- a/airbyte-integrations/connectors/source-teamwork/metadata.yaml +++ b/airbyte-integrations/connectors/source-teamwork/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-teamwork connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 7fcd456d-2c13-4437-a05b-cf436699a519 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-teamwork githubIssueLabel: source-teamwork icon: icon.svg diff --git a/airbyte-integrations/connectors/source-tempo/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-tempo/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-tempo/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-tempo/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-tempo/metadata.yaml b/airbyte-integrations/connectors/source-tempo/metadata.yaml index 0b23aaffe547..9569ed167e01 100644 --- a/airbyte-integrations/connectors/source-tempo/metadata.yaml +++ b/airbyte-integrations/connectors/source-tempo/metadata.yaml @@ -8,7 +8,7 @@ data: connectorSubtype: api connectorType: source definitionId: d1aa448b-7c54-498e-ad95-263cbebcd2db - dockerImageTag: 0.4.1 + dockerImageTag: 0.4.6 dockerRepository: airbyte/source-tempo documentationUrl: https://docs.airbyte.com/integrations/sources/tempo githubIssueLabel: source-tempo @@ -50,5 +50,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.4.3@sha256:8937b693c7e01087f6e86e683826ac20f160f7952b8f0a13cbf4f9bfdd7af570 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-teradata/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-teradata/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-teradata/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-teradata/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-teradata/metadata.yaml b/airbyte-integrations/connectors/source-teradata/metadata.yaml index 4efefa79b12e..6945108c0956 100644 --- a/airbyte-integrations/connectors/source-teradata/metadata.yaml +++ b/airbyte-integrations/connectors/source-teradata/metadata.yaml @@ -1,12 +1,27 @@ data: + ab_internal: + ql: 100 + sl: 100 allowedHosts: hosts: - ${host} + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a connectorSubtype: database + connectorTestSuitesOptions: + - suite: unitTests + - suite: integrationTests + testSecrets: + - fileName: config.json + name: SECRET_SOURCE-TERADATA__CREDS + secretStore: + alias: airbyte-connector-testing-secret-store + type: GSM connectorType: source definitionId: aa8ba6fd-4875-d94e-fc8d-4e1e09aa2503 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.4 dockerRepository: airbyte/source-teradata + documentationUrl: https://docs.airbyte.com/integrations/sources/teradata githubIssueLabel: source-teradata icon: teradata.svg license: MIT @@ -17,20 +32,7 @@ data: oss: enabled: true releaseStage: alpha - documentationUrl: https://docs.airbyte.com/integrations/sources/teradata + supportLevel: community tags: - language:java - ab_internal: - sl: 100 - ql: 100 - supportLevel: community - connectorTestSuitesOptions: - - suite: unitTests - - suite: integrationTests - testSecrets: - - name: SECRET_SOURCE-TERADATA__CREDS - fileName: config.json - secretStore: - type: GSM - alias: airbyte-connector-testing-secret-store metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-teradata/src/main/java/io/airbyte/integrations/source/teradata/TeradataSource.java b/airbyte-integrations/connectors/source-teradata/src/main/java/io/airbyte/integrations/source/teradata/TeradataSource.java index d9410b75cdd1..e61a12a1bcf7 100644 --- a/airbyte-integrations/connectors/source-teradata/src/main/java/io/airbyte/integrations/source/teradata/TeradataSource.java +++ b/airbyte-integrations/connectors/source-teradata/src/main/java/io/airbyte/integrations/source/teradata/TeradataSource.java @@ -65,8 +65,9 @@ public static void main(final String[] args) throws Exception { public JsonNode toDatabaseConfig(final JsonNode config) { final String schema = config.get(JdbcUtils.DATABASE_KEY).asText(); - final String host = config.has(JdbcUtils.PORT_KEY) ? config.get(JdbcUtils.HOST_KEY).asText() + ":" + config.get(JdbcUtils.PORT_KEY).asInt() - : config.get(JdbcUtils.HOST_KEY).asText(); + final String host = + config.has(JdbcUtils.PORT_KEY) ? config.get(JdbcUtils.HOST_KEY).asText() + "DBS_PORT=" + config.get(JdbcUtils.PORT_KEY).asInt() + : config.get(JdbcUtils.HOST_KEY).asText(); final String jdbcUrl = String.format("jdbc:teradata://%s/", host); diff --git a/airbyte-integrations/connectors/source-teradata/src/main/resources/spec.json b/airbyte-integrations/connectors/source-teradata/src/main/resources/spec.json index 82eaaeda13cf..0fdc2d80e58d 100644 --- a/airbyte-integrations/connectors/source-teradata/src/main/resources/spec.json +++ b/airbyte-integrations/connectors/source-teradata/src/main/resources/spec.json @@ -18,8 +18,8 @@ "type": "integer", "minimum": 0, "maximum": 65536, - "default": 3306, - "examples": ["3306"], + "default": 1025, + "examples": ["1025"], "order": 1 }, "database": { diff --git a/airbyte-integrations/connectors/source-testrail/metadata.yaml b/airbyte-integrations/connectors/source-testrail/metadata.yaml index ccaaa5ecbf53..7203aa4a0e56 100644 --- a/airbyte-integrations/connectors/source-testrail/metadata.yaml +++ b/airbyte-integrations/connectors/source-testrail/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-testrail connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: ab49ae02-a22d-4c9a-b0be-f260e61a4011 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-testrail githubIssueLabel: source-testrail icon: icon.svg diff --git a/airbyte-integrations/connectors/source-the-guardian-api/components.py b/airbyte-integrations/connectors/source-the-guardian-api/components.py index 998187314780..8d54333154f2 100644 --- a/airbyte-integrations/connectors/source-the-guardian-api/components.py +++ b/airbyte-integrations/connectors/source-the-guardian-api/components.py @@ -6,6 +6,7 @@ from typing import Any, List, Mapping, Optional import requests + from airbyte_cdk.sources.declarative.requesters.paginators.strategies.page_increment import PageIncrement diff --git a/airbyte-integrations/connectors/source-the-guardian-api/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-the-guardian-api/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-the-guardian-api/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-the-guardian-api/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-the-guardian-api/metadata.yaml b/airbyte-integrations/connectors/source-the-guardian-api/metadata.yaml index a40bacaa082c..d3576c907d60 100644 --- a/airbyte-integrations/connectors/source-the-guardian-api/metadata.yaml +++ b/airbyte-integrations/connectors/source-the-guardian-api/metadata.yaml @@ -3,9 +3,10 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorTestSuitesOptions: + - suite: unitTests - suite: liveTests testConnections: - name: the-guardian-api_config_dev_null @@ -19,7 +20,7 @@ data: type: GSM connectorType: source definitionId: d42bd69f-6bf0-4d0b-9209-16231af07a92 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.8 dockerRepository: airbyte/source-the-guardian-api documentationUrl: https://docs.airbyte.com/integrations/sources/the-guardian-api githubIssueLabel: source-the-guardian-api diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/state_converters/__init__.py b/airbyte-integrations/connectors/source-the-guardian-api/unit_tests/__init__.py similarity index 100% rename from airbyte-cdk/python/airbyte_cdk/sources/streams/concurrent/state_converters/__init__.py rename to airbyte-integrations/connectors/source-the-guardian-api/unit_tests/__init__.py diff --git a/airbyte-integrations/connectors/source-the-guardian-api/unit_tests/conftest.py b/airbyte-integrations/connectors/source-the-guardian-api/unit_tests/conftest.py new file mode 100644 index 000000000000..d3826f66680c --- /dev/null +++ b/airbyte-integrations/connectors/source-the-guardian-api/unit_tests/conftest.py @@ -0,0 +1,3 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + +pytest_plugins = ["airbyte_cdk.test.utils.manifest_only_fixtures"] diff --git a/airbyte-integrations/connectors/source-the-guardian-api/unit_tests/poetry.lock b/airbyte-integrations/connectors/source-the-guardian-api/unit_tests/poetry.lock new file mode 100644 index 000000000000..e9552c514219 --- /dev/null +++ b/airbyte-integrations/connectors/source-the-guardian-api/unit_tests/poetry.lock @@ -0,0 +1,1992 @@ +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. + +[[package]] +name = "airbyte-cdk" +version = "6.9.3rc1" +description = "A framework for writing Airbyte Connectors." +optional = false +python-versions = "<3.13,>=3.10" +files = [ + {file = "airbyte_cdk-6.9.3rc1-py3-none-any.whl", hash = "sha256:4219f4fdd6bcd24876414369faad5bc1965deee2d42c766d3c04631877d1554c"}, + {file = "airbyte_cdk-6.9.3rc1.tar.gz", hash = "sha256:3a7c5e051906c93d62f4cfda5df5544ba0d2586ec105a03ed191380d27fb3dbe"}, +] + +[package.dependencies] +airbyte-protocol-models-dataclasses = ">=0.14,<0.15" +backoff = "*" +cachetools = "*" +cryptography = ">=42.0.5,<44.0.0" +dpath = ">=2.1.6,<3.0.0" +dunamai = ">=1.22.0,<2.0.0" +genson = "1.3.0" +isodate = ">=0.6.1,<0.7.0" +Jinja2 = ">=3.1.2,<3.2.0" +jsonref = ">=0.2,<0.3" +jsonschema = ">=4.17.3,<4.18.0" +langchain_core = "0.1.42" +nltk = "3.9.1" +numpy = "<2" +orjson = ">=3.10.7,<4.0.0" +pandas = "2.2.2" +pendulum = "<3.0.0" +psutil = "6.1.0" +pydantic = ">=2.7,<3.0" +pyjwt = ">=2.8.0,<3.0.0" +pyrate-limiter = ">=3.1.0,<3.2.0" +python-dateutil = "*" +python-ulid = ">=3.0.0,<4.0.0" +pytz = "2024.1" +PyYAML = ">=6.0.1,<7.0.0" +rapidfuzz = ">=3.10.1,<4.0.0" +requests = "*" +requests_cache = "*" +serpyco-rs = ">=1.10.2,<2.0.0" +wcmatch = "10.0" +xmltodict = ">=0.13.0,<0.14.0" + +[package.extras] +file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "python-calamine (==0.2.3)", "python-snappy (==0.7.3)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] +sql = ["sqlalchemy (>=2.0,!=2.0.36,<3.0)"] +vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.8.0)"] + +[[package]] +name = "airbyte-protocol-models-dataclasses" +version = "0.14.1" +description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" +optional = false +python-versions = ">=3.8" +files = [ + {file = "airbyte_protocol_models_dataclasses-0.14.1-py3-none-any.whl", hash = "sha256:dfe10b32ee09e6ba9b4f17bd309e841b61cbd61ec8f80b1937ff104efd6209a9"}, + {file = "airbyte_protocol_models_dataclasses-0.14.1.tar.gz", hash = "sha256:f62a46556b82ea0d55de144983141639e8049d836dd4e0a9d7234c5b2e103c08"}, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + +[[package]] +name = "anyio" +version = "4.7.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.9" +files = [ + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, +] + +[package.dependencies] +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} +idna = ">=2.8" +sniffio = ">=1.1" +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} + +[package.extras] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] +trio = ["trio (>=0.26.1)"] + +[[package]] +name = "attributes-doc" +version = "0.4.0" +description = "PEP 224 implementation" +optional = false +python-versions = ">=3.8" +files = [ + {file = "attributes-doc-0.4.0.tar.gz", hash = "sha256:b1576c94a714e9fc2c65c47cf10d0c8e1a5f7c4f5ae7f69006be108d95cbfbfb"}, + {file = "attributes_doc-0.4.0-py2.py3-none-any.whl", hash = "sha256:4c3007d9e58f3a6cb4b9c614c4d4ce2d92161581f28e594ddd8241cc3a113bdd"}, +] + +[[package]] +name = "attrs" +version = "24.2.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, +] + +[package.extras] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] + +[[package]] +name = "backoff" +version = "2.2.1" +description = "Function decoration for backoff and retry" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, + {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, +] + +[[package]] +name = "bracex" +version = "2.5.post1" +description = "Bash style brace expander." +optional = false +python-versions = ">=3.8" +files = [ + {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, + {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, +] + +[[package]] +name = "cachetools" +version = "5.5.0" +description = "Extensible memoizing collections and decorators" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, + {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, +] + +[[package]] +name = "cattrs" +version = "24.1.2" +description = "Composable complex class support for attrs and dataclasses." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, + {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, +] + +[package.dependencies] +attrs = ">=23.1.0" +exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} + +[package.extras] +bson = ["pymongo (>=4.4.0)"] +cbor2 = ["cbor2 (>=5.4.6)"] +msgpack = ["msgpack (>=1.0.5)"] +msgspec = ["msgspec (>=0.18.5)"] +orjson = ["orjson (>=3.9.2)"] +pyyaml = ["pyyaml (>=6.0)"] +tomlkit = ["tomlkit (>=0.11.8)"] +ujson = ["ujson (>=5.7.0)"] + +[[package]] +name = "certifi" +version = "2024.8.30" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, +] + +[[package]] +name = "cffi" +version = "1.17.1" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, + {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, + {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, + {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, + {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, +] + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "charset-normalizer" +version = "3.4.0" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, + {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, + {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +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 = "cryptography" +version = "43.0.3" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = ">=3.7" +files = [ + {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, + {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, + {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, + {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, + {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, + {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, + {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, +] + +[package.dependencies] +cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] +nox = ["nox"] +pep8test = ["check-sdist", "click", "mypy", "ruff"] +sdist = ["build"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] + +[[package]] +name = "dpath" +version = "2.2.0" +description = "Filesystem-like pathing and searching for dictionaries" +optional = false +python-versions = ">=3.7" +files = [ + {file = "dpath-2.2.0-py3-none-any.whl", hash = "sha256:b330a375ded0a0d2ed404440f6c6a715deae5313af40bbb01c8a41d891900576"}, + {file = "dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e"}, +] + +[[package]] +name = "dunamai" +version = "1.23.0" +description = "Dynamic version generation" +optional = false +python-versions = ">=3.5" +files = [ + {file = "dunamai-1.23.0-py3-none-any.whl", hash = "sha256:a0906d876e92441793c6a423e16a4802752e723e9c9a5aabdc5535df02dbe041"}, + {file = "dunamai-1.23.0.tar.gz", hash = "sha256:a163746de7ea5acb6dacdab3a6ad621ebc612ed1e528aaa8beedb8887fccd2c4"}, +] + +[package.dependencies] +packaging = ">=20.9" + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "genson" +version = "1.3.0" +description = "GenSON is a powerful, user-friendly JSON Schema generator." +optional = false +python-versions = "*" +files = [ + {file = "genson-1.3.0-py3-none-any.whl", hash = "sha256:468feccd00274cc7e4c09e84b08704270ba8d95232aa280f65b986139cec67f7"}, + {file = "genson-1.3.0.tar.gz", hash = "sha256:e02db9ac2e3fd29e65b5286f7135762e2cd8a986537c075b06fc5f1517308e37"}, +] + +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.7" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<1.0)"] + +[[package]] +name = "httpx" +version = "0.28.1" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "idna" +version = "3.10" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.6" +files = [ + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "isodate" +version = "0.6.1" +description = "An ISO 8601 date/time/duration parser and formatter" +optional = false +python-versions = "*" +files = [ + {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, + {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "jinja2" +version = "3.1.4" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "joblib" +version = "1.4.2" +description = "Lightweight pipelining with Python functions" +optional = false +python-versions = ">=3.8" +files = [ + {file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"}, + {file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"}, +] + +[[package]] +name = "jsonpatch" +version = "1.33" +description = "Apply JSON-Patches (RFC 6902)" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +files = [ + {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, + {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, +] + +[package.dependencies] +jsonpointer = ">=1.9" + +[[package]] +name = "jsonpointer" +version = "3.0.0" +description = "Identify specific nodes in a JSON document (RFC 6901)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, + {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, +] + +[[package]] +name = "jsonref" +version = "0.2" +description = "An implementation of JSON Reference for Python" +optional = false +python-versions = "*" +files = [ + {file = "jsonref-0.2-py3-none-any.whl", hash = "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f"}, + {file = "jsonref-0.2.tar.gz", hash = "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697"}, +] + +[[package]] +name = "jsonschema" +version = "4.17.3" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, +] + +[package.dependencies] +attrs = ">=17.4.0" +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] + +[[package]] +name = "langchain-core" +version = "0.1.42" +description = "Building applications with LLMs through composability" +optional = false +python-versions = "<4.0,>=3.8.1" +files = [ + {file = "langchain_core-0.1.42-py3-none-any.whl", hash = "sha256:c5653ffa08a44f740295c157a24c0def4a753333f6a2c41f76bf431cd00be8b5"}, + {file = "langchain_core-0.1.42.tar.gz", hash = "sha256:40751bf60ea5d8e2b2efe65290db434717ee3834870c002e40e2811f09d814e6"}, +] + +[package.dependencies] +jsonpatch = ">=1.33,<2.0" +langsmith = ">=0.1.0,<0.2.0" +packaging = ">=23.2,<24.0" +pydantic = ">=1,<3" +PyYAML = ">=5.3" +tenacity = ">=8.1.0,<9.0.0" + +[package.extras] +extended-testing = ["jinja2 (>=3,<4)"] + +[[package]] +name = "langsmith" +version = "0.1.147" +description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." +optional = false +python-versions = "<4.0,>=3.8.1" +files = [ + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, +] + +[package.dependencies] +httpx = ">=0.23.0,<1" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} +pydantic = [ + {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""}, + {version = ">=2.7.4,<3.0.0", markers = "python_full_version >= \"3.12.4\""}, +] +requests = ">=2,<3" +requests-toolbelt = ">=1.0.0,<2.0.0" + +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + +[[package]] +name = "markupsafe" +version = "3.0.2" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.9" +files = [ + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, +] + +[[package]] +name = "nltk" +version = "3.9.1" +description = "Natural Language Toolkit" +optional = false +python-versions = ">=3.8" +files = [ + {file = "nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1"}, + {file = "nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868"}, +] + +[package.dependencies] +click = "*" +joblib = "*" +regex = ">=2021.8.3" +tqdm = "*" + +[package.extras] +all = ["matplotlib", "numpy", "pyparsing", "python-crfsuite", "requests", "scikit-learn", "scipy", "twython"] +corenlp = ["requests"] +machine-learning = ["numpy", "python-crfsuite", "scikit-learn", "scipy"] +plot = ["matplotlib"] +tgrep = ["pyparsing"] +twitter = ["twython"] + +[[package]] +name = "numpy" +version = "1.26.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, +] + +[[package]] +name = "orjson" +version = "3.10.12" +description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" +optional = false +python-versions = ">=3.8" +files = [ + {file = "orjson-3.10.12-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ece01a7ec71d9940cc654c482907a6b65df27251255097629d0dea781f255c6d"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c34ec9aebc04f11f4b978dd6caf697a2df2dd9b47d35aa4cc606cabcb9df69d7"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd6ec8658da3480939c79b9e9e27e0db31dffcd4ba69c334e98c9976ac29140e"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f17e6baf4cf01534c9de8a16c0c611f3d94925d1701bf5f4aff17003677d8ced"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6402ebb74a14ef96f94a868569f5dccf70d791de49feb73180eb3c6fda2ade56"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0000758ae7c7853e0a4a6063f534c61656ebff644391e1f81698c1b2d2fc8cd2"}, + {file = "orjson-3.10.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:888442dcee99fd1e5bd37a4abb94930915ca6af4db50e23e746cdf4d1e63db13"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c1f7a3ce79246aa0e92f5458d86c54f257fb5dfdc14a192651ba7ec2c00f8a05"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:802a3935f45605c66fb4a586488a38af63cb37aaad1c1d94c982c40dcc452e85"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1da1ef0113a2be19bb6c557fb0ec2d79c92ebd2fed4cfb1b26bab93f021fb885"}, + {file = "orjson-3.10.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a3273e99f367f137d5b3fecb5e9f45bcdbfac2a8b2f32fbc72129bbd48789c2"}, + {file = "orjson-3.10.12-cp310-none-win32.whl", hash = "sha256:475661bf249fd7907d9b0a2a2421b4e684355a77ceef85b8352439a9163418c3"}, + {file = "orjson-3.10.12-cp310-none-win_amd64.whl", hash = "sha256:87251dc1fb2b9e5ab91ce65d8f4caf21910d99ba8fb24b49fd0c118b2362d509"}, + {file = "orjson-3.10.12-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a734c62efa42e7df94926d70fe7d37621c783dea9f707a98cdea796964d4cf74"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:750f8b27259d3409eda8350c2919a58b0cfcd2054ddc1bd317a643afc646ef23"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb52c22bfffe2857e7aa13b4622afd0dd9d16ea7cc65fd2bf318d3223b1b6252"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:440d9a337ac8c199ff8251e100c62e9488924c92852362cd27af0e67308c16ef"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9e15c06491c69997dfa067369baab3bf094ecb74be9912bdc4339972323f252"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:362d204ad4b0b8724cf370d0cd917bb2dc913c394030da748a3bb632445ce7c4"}, + {file = "orjson-3.10.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2b57cbb4031153db37b41622eac67329c7810e5f480fda4cfd30542186f006ae"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:165c89b53ef03ce0d7c59ca5c82fa65fe13ddf52eeb22e859e58c237d4e33b9b"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5dee91b8dfd54557c1a1596eb90bcd47dbcd26b0baaed919e6861f076583e9da"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77a4e1cfb72de6f905bdff061172adfb3caf7a4578ebf481d8f0530879476c07"}, + {file = "orjson-3.10.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:038d42c7bc0606443459b8fe2d1f121db474c49067d8d14c6a075bbea8bf14dd"}, + {file = "orjson-3.10.12-cp311-none-win32.whl", hash = "sha256:03b553c02ab39bed249bedd4abe37b2118324d1674e639b33fab3d1dafdf4d79"}, + {file = "orjson-3.10.12-cp311-none-win_amd64.whl", hash = "sha256:8b8713b9e46a45b2af6b96f559bfb13b1e02006f4242c156cbadef27800a55a8"}, + {file = "orjson-3.10.12-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:53206d72eb656ca5ac7d3a7141e83c5bbd3ac30d5eccfe019409177a57634b0d"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac8010afc2150d417ebda810e8df08dd3f544e0dd2acab5370cfa6bcc0662f8f"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed459b46012ae950dd2e17150e838ab08215421487371fa79d0eced8d1461d70"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dcb9673f108a93c1b52bfc51b0af422c2d08d4fc710ce9c839faad25020bb69"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22a51ae77680c5c4652ebc63a83d5255ac7d65582891d9424b566fb3b5375ee9"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910fdf2ac0637b9a77d1aad65f803bac414f0b06f720073438a7bd8906298192"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:24ce85f7100160936bc2116c09d1a8492639418633119a2224114f67f63a4559"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a76ba5fc8dd9c913640292df27bff80a685bed3a3c990d59aa6ce24c352f8fc"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ff70ef093895fd53f4055ca75f93f047e088d1430888ca1229393a7c0521100f"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f4244b7018b5753ecd10a6d324ec1f347da130c953a9c88432c7fbc8875d13be"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:16135ccca03445f37921fa4b585cff9a58aa8d81ebcb27622e69bfadd220b32c"}, + {file = "orjson-3.10.12-cp312-none-win32.whl", hash = "sha256:2d879c81172d583e34153d524fcba5d4adafbab8349a7b9f16ae511c2cee8708"}, + {file = "orjson-3.10.12-cp312-none-win_amd64.whl", hash = "sha256:fc23f691fa0f5c140576b8c365bc942d577d861a9ee1142e4db468e4e17094fb"}, + {file = "orjson-3.10.12-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:47962841b2a8aa9a258b377f5188db31ba49af47d4003a32f55d6f8b19006543"}, + {file = "orjson-3.10.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6334730e2532e77b6054e87ca84f3072bee308a45a452ea0bffbbbc40a67e296"}, + {file = "orjson-3.10.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:accfe93f42713c899fdac2747e8d0d5c659592df2792888c6c5f829472e4f85e"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a7974c490c014c48810d1dede6c754c3cc46598da758c25ca3b4001ac45b703f"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3f250ce7727b0b2682f834a3facff88e310f52f07a5dcfd852d99637d386e79e"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f31422ff9486ae484f10ffc51b5ab2a60359e92d0716fcce1b3593d7bb8a9af6"}, + {file = "orjson-3.10.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5f29c5d282bb2d577c2a6bbde88d8fdcc4919c593f806aac50133f01b733846e"}, + {file = "orjson-3.10.12-cp313-none-win32.whl", hash = "sha256:f45653775f38f63dc0e6cd4f14323984c3149c05d6007b58cb154dd080ddc0dc"}, + {file = "orjson-3.10.12-cp313-none-win_amd64.whl", hash = "sha256:229994d0c376d5bdc91d92b3c9e6be2f1fbabd4cc1b59daae1443a46ee5e9825"}, + {file = "orjson-3.10.12-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7d69af5b54617a5fac5c8e5ed0859eb798e2ce8913262eb522590239db6c6763"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ed119ea7d2953365724a7059231a44830eb6bbb0cfead33fcbc562f5fd8f935"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9c5fc1238ef197e7cad5c91415f524aaa51e004be5a9b35a1b8a84ade196f73f"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43509843990439b05f848539d6f6198d4ac86ff01dd024b2f9a795c0daeeab60"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f72e27a62041cfb37a3de512247ece9f240a561e6c8662276beaf4d53d406db4"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a904f9572092bb6742ab7c16c623f0cdccbad9eeb2d14d4aa06284867bddd31"}, + {file = "orjson-3.10.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:855c0833999ed5dc62f64552db26f9be767434917d8348d77bacaab84f787d7b"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:897830244e2320f6184699f598df7fb9db9f5087d6f3f03666ae89d607e4f8ed"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0b32652eaa4a7539f6f04abc6243619c56f8530c53bf9b023e1269df5f7816dd"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:36b4aa31e0f6a1aeeb6f8377769ca5d125db000f05c20e54163aef1d3fe8e833"}, + {file = "orjson-3.10.12-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5535163054d6cbf2796f93e4f0dbc800f61914c0e3c4ed8499cf6ece22b4a3da"}, + {file = "orjson-3.10.12-cp38-none-win32.whl", hash = "sha256:90a5551f6f5a5fa07010bf3d0b4ca2de21adafbbc0af6cb700b63cd767266cb9"}, + {file = "orjson-3.10.12-cp38-none-win_amd64.whl", hash = "sha256:703a2fb35a06cdd45adf5d733cf613cbc0cb3ae57643472b16bc22d325b5fb6c"}, + {file = "orjson-3.10.12-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f29de3ef71a42a5822765def1febfb36e0859d33abf5c2ad240acad5c6a1b78d"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de365a42acc65d74953f05e4772c974dad6c51cfc13c3240899f534d611be967"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:91a5a0158648a67ff0004cb0df5df7dcc55bfc9ca154d9c01597a23ad54c8d0c"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c47ce6b8d90fe9646a25b6fb52284a14ff215c9595914af63a5933a49972ce36"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0eee4c2c5bfb5c1b47a5db80d2ac7aaa7e938956ae88089f098aff2c0f35d5d8"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35d3081bbe8b86587eb5c98a73b97f13d8f9fea685cf91a579beddacc0d10566"}, + {file = "orjson-3.10.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73c23a6e90383884068bc2dba83d5222c9fcc3b99a0ed2411d38150734236755"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5472be7dc3269b4b52acba1433dac239215366f89dc1d8d0e64029abac4e714e"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:7319cda750fca96ae5973efb31b17d97a5c5225ae0bc79bf5bf84df9e1ec2ab6"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:74d5ca5a255bf20b8def6a2b96b1e18ad37b4a122d59b154c458ee9494377f80"}, + {file = "orjson-3.10.12-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ff31d22ecc5fb85ef62c7d4afe8301d10c558d00dd24274d4bbe464380d3cd69"}, + {file = "orjson-3.10.12-cp39-none-win32.whl", hash = "sha256:c22c3ea6fba91d84fcb4cda30e64aff548fcf0c44c876e681f47d61d24b12e6b"}, + {file = "orjson-3.10.12-cp39-none-win_amd64.whl", hash = "sha256:be604f60d45ace6b0b33dd990a66b4526f1a7a186ac411c942674625456ca548"}, + {file = "orjson-3.10.12.tar.gz", hash = "sha256:0a78bbda3aea0f9f079057ee1ee8a1ecf790d4f1af88dd67493c6b8ee52506ff"}, +] + +[[package]] +name = "packaging" +version = "23.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] + +[[package]] +name = "pandas" +version = "2.2.2" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + +[[package]] +name = "pendulum" +version = "2.1.2" +description = "Python datetimes made easy" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, + {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, + {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, + {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, + {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, + {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, + {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, + {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, + {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, + {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, + {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, + {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, + {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, + {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, + {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, + {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, + {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, + {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, + {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, + {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, + {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, +] + +[package.dependencies] +python-dateutil = ">=2.6,<3.0" +pytzdata = ">=2020.1" + +[[package]] +name = "platformdirs" +version = "4.3.6" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, +] + +[package.extras] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] + +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "psutil" +version = "6.1.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, +] + +[package.extras] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + +[[package]] +name = "pycparser" +version = "2.22" +description = "C parser in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + +[[package]] +name = "pydantic" +version = "2.10.3" +description = "Data validation using Python type hints" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic-2.10.3-py3-none-any.whl", hash = "sha256:be04d85bbc7b65651c5f8e6b9976ed9c6f41782a55524cef079a34a0bb82144d"}, + {file = "pydantic-2.10.3.tar.gz", hash = "sha256:cb5ac360ce894ceacd69c403187900a02c4b20b693a9dd1d643e1effab9eadf9"}, +] + +[package.dependencies] +annotated-types = ">=0.6.0" +pydantic-core = "2.27.1" +typing-extensions = ">=4.12.2" + +[package.extras] +email = ["email-validator (>=2.0.0)"] +timezone = ["tzdata"] + +[[package]] +name = "pydantic-core" +version = "2.27.1" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206"}, + {file = "pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c"}, + {file = "pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc"}, + {file = "pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9"}, + {file = "pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5"}, + {file = "pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae"}, + {file = "pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c"}, + {file = "pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16"}, + {file = "pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23"}, + {file = "pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05"}, + {file = "pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337"}, + {file = "pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:5897bec80a09b4084aee23f9b73a9477a46c3304ad1d2d07acca19723fb1de62"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d0165ab2914379bd56908c02294ed8405c252250668ebcb438a55494c69f44ab"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b9af86e1d8e4cfc82c2022bfaa6f459381a50b94a29e95dcdda8442d6d83864"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f6c8a66741c5f5447e047ab0ba7a1c61d1e95580d64bce852e3df1f895c4067"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a42d6a8156ff78981f8aa56eb6394114e0dedb217cf8b729f438f643608cbcd"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64c65f40b4cd8b0e049a8edde07e38b476da7e3aaebe63287c899d2cff253fa5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdcf339322a3fae5cbd504edcefddd5a50d9ee00d968696846f089b4432cf78"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf99c8404f008750c846cb4ac4667b798a9f7de673ff719d705d9b2d6de49c5f"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f1edcea27918d748c7e5e4d917297b2a0ab80cad10f86631e488b7cddf76a36"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:159cac0a3d096f79ab6a44d77a961917219707e2a130739c64d4dd46281f5c2a"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:029d9757eb621cc6e1848fa0b0310310de7301057f623985698ed7ebb014391b"}, + {file = "pydantic_core-2.27.1-cp38-none-win32.whl", hash = "sha256:a28af0695a45f7060e6f9b7092558a928a28553366519f64083c63a44f70e618"}, + {file = "pydantic_core-2.27.1-cp38-none-win_amd64.whl", hash = "sha256:2d4567c850905d5eaaed2f7a404e61012a51caf288292e016360aa2b96ff38d4"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:e9386266798d64eeb19dd3677051f5705bf873e98e15897ddb7d76f477131967"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4228b5b646caa73f119b1ae756216b59cc6e2267201c27d3912b592c5e323b60"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3dfe500de26c52abe0477dde16192ac39c98f05bf2d80e76102d394bd13854"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aee66be87825cdf72ac64cb03ad4c15ffef4143dbf5c113f64a5ff4f81477bf9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b748c44bb9f53031c8cbc99a8a061bc181c1000c60a30f55393b6e9c45cc5bd"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ca038c7f6a0afd0b2448941b6ef9d5e1949e999f9e5517692eb6da58e9d44be"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e0bd57539da59a3e4671b90a502da9a28c72322a4f17866ba3ac63a82c4498e"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac6c2c45c847bbf8f91930d88716a0fb924b51e0c6dad329b793d670ec5db792"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b94d4ba43739bbe8b0ce4262bcc3b7b9f31459ad120fb595627eaeb7f9b9ca01"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:00e6424f4b26fe82d44577b4c842d7df97c20be6439e8e685d0d715feceb9fb9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:38de0a70160dd97540335b7ad3a74571b24f1dc3ed33f815f0880682e6880131"}, + {file = "pydantic_core-2.27.1-cp39-none-win32.whl", hash = "sha256:7ccebf51efc61634f6c2344da73e366c75e735960b5654b63d7e6f69a5885fa3"}, + {file = "pydantic_core-2.27.1-cp39-none-win_amd64.whl", hash = "sha256:a57847b090d7892f123726202b7daa20df6694cbd583b67a592e856bff603d6c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5fde892e6c697ce3e30c61b239330fc5d569a71fefd4eb6512fc6caec9dd9e2f"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:816f5aa087094099fff7edabb5e01cc370eb21aa1a1d44fe2d2aefdfb5599b31"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c10c309e18e443ddb108f0ef64e8729363adbfd92d6d57beec680f6261556f3"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98476c98b02c8e9b2eec76ac4156fd006628b1b2d0ef27e548ffa978393fd154"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c3027001c28434e7ca5a6e1e527487051136aa81803ac812be51802150d880dd"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7699b1df36a48169cdebda7ab5a2bac265204003f153b4bd17276153d997670a"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1c39b07d90be6b48968ddc8c19e7585052088fd7ec8d568bb31ff64c70ae3c97"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:46ccfe3032b3915586e469d4972973f893c0a2bb65669194a5bdea9bacc088c2"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:62ba45e21cf6571d7f716d903b5b7b6d2617e2d5d67c0923dc47b9d41369f840"}, + {file = "pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" + +[[package]] +name = "pyjwt" +version = "2.10.1" +description = "JSON Web Token implementation in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, +] + +[package.extras] +crypto = ["cryptography (>=3.4.0)"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] +docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] + +[[package]] +name = "pyrate-limiter" +version = "3.1.1" +description = "Python Rate-Limiter using Leaky-Bucket Algorithm" +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, + {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, +] + +[package.extras] +all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] +docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] + +[[package]] +name = "pyrsistent" +version = "0.20.0" +description = "Persistent/Functional/Immutable data structures" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, + {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, + {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34"}, + {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b"}, + {file = "pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f"}, + {file = "pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7"}, + {file = "pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958"}, + {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8"}, + {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a"}, + {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224"}, + {file = "pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656"}, + {file = "pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee"}, + {file = "pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e"}, + {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e"}, + {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3"}, + {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d"}, + {file = "pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174"}, + {file = "pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d"}, + {file = "pyrsistent-0.20.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054"}, + {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98"}, + {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714"}, + {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86"}, + {file = "pyrsistent-0.20.0-cp38-cp38-win32.whl", hash = "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423"}, + {file = "pyrsistent-0.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d"}, + {file = "pyrsistent-0.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce"}, + {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0"}, + {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022"}, + {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca"}, + {file = "pyrsistent-0.20.0-cp39-cp39-win32.whl", hash = "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f"}, + {file = "pyrsistent-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf"}, + {file = "pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b"}, + {file = "pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4"}, +] + +[[package]] +name = "pytest" +version = "8.3.4" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-ulid" +version = "3.0.0" +description = "Universally unique lexicographically sortable identifier" +optional = false +python-versions = ">=3.9" +files = [ + {file = "python_ulid-3.0.0-py3-none-any.whl", hash = "sha256:e4c4942ff50dbd79167ad01ac725ec58f924b4018025ce22c858bfcff99a5e31"}, + {file = "python_ulid-3.0.0.tar.gz", hash = "sha256:e50296a47dc8209d28629a22fc81ca26c00982c78934bd7766377ba37ea49a9f"}, +] + +[package.extras] +pydantic = ["pydantic (>=2.0)"] + +[[package]] +name = "pytz" +version = "2024.1" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, +] + +[[package]] +name = "pytzdata" +version = "2020.1" +description = "The Olson timezone database for Python." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, + {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, +] + +[[package]] +name = "rapidfuzz" +version = "3.10.1" +description = "rapid fuzzy string matching" +optional = false +python-versions = ">=3.9" +files = [ + {file = "rapidfuzz-3.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f17d9f21bf2f2f785d74f7b0d407805468b4c173fa3e52c86ec94436b338e74a"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b31f358a70efc143909fb3d75ac6cd3c139cd41339aa8f2a3a0ead8315731f2b"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f4f43f2204b56a61448ec2dd061e26fd344c404da99fb19f3458200c5874ba2"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d81bf186a453a2757472133b24915768abc7c3964194406ed93e170e16c21cb"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3611c8f45379a12063d70075c75134f2a8bd2e4e9b8a7995112ddae95ca1c982"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c3b537b97ac30da4b73930fa8a4fe2f79c6d1c10ad535c5c09726612cd6bed9"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:231ef1ec9cf7b59809ce3301006500b9d564ddb324635f4ea8f16b3e2a1780da"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ed4f3adc1294834955b7e74edd3c6bd1aad5831c007f2d91ea839e76461a5879"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:7b6015da2e707bf632a71772a2dbf0703cff6525732c005ad24987fe86e8ec32"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1b35a118d61d6f008e8e3fb3a77674d10806a8972c7b8be433d6598df4d60b01"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:bc308d79a7e877226f36bdf4e149e3ed398d8277c140be5c1fd892ec41739e6d"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f017dbfecc172e2d0c37cf9e3d519179d71a7f16094b57430dffc496a098aa17"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-win32.whl", hash = "sha256:36c0e1483e21f918d0f2f26799fe5ac91c7b0c34220b73007301c4f831a9c4c7"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:10746c1d4c8cd8881c28a87fd7ba0c9c102346dfe7ff1b0d021cdf093e9adbff"}, + {file = "rapidfuzz-3.10.1-cp310-cp310-win_arm64.whl", hash = "sha256:dfa64b89dcb906835e275187569e51aa9d546a444489e97aaf2cc84011565fbe"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:92958ae075c87fef393f835ed02d4fe8d5ee2059a0934c6c447ea3417dfbf0e8"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ba7521e072c53e33c384e78615d0718e645cab3c366ecd3cc8cb732befd94967"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d02cbd75d283c287471b5b3738b3e05c9096150f93f2d2dfa10b3d700f2db9"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:efa1582a397da038e2f2576c9cd49b842f56fde37d84a6b0200ffebc08d82350"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f12912acee1f506f974f58de9fdc2e62eea5667377a7e9156de53241c05fdba8"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666d5d8b17becc3f53447bcb2b6b33ce6c2df78792495d1fa82b2924cd48701a"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26f71582c0d62445067ee338ddad99b655a8f4e4ed517a90dcbfbb7d19310474"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8a2ef08b27167bcff230ffbfeedd4c4fa6353563d6aaa015d725dd3632fc3de7"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:365e4fc1a2b95082c890f5e98489b894e6bf8c338c6ac89bb6523c2ca6e9f086"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1996feb7a61609fa842e6b5e0c549983222ffdedaf29644cc67e479902846dfe"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:cf654702f144beaa093103841a2ea6910d617d0bb3fccb1d1fd63c54dde2cd49"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec108bf25de674781d0a9a935030ba090c78d49def3d60f8724f3fc1e8e75024"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-win32.whl", hash = "sha256:031f8b367e5d92f7a1e27f7322012f3c321c3110137b43cc3bf678505583ef48"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:f98f36c6a1bb9a6c8bbec99ad87c8c0e364f34761739b5ea9adf7b48129ae8cf"}, + {file = "rapidfuzz-3.10.1-cp311-cp311-win_arm64.whl", hash = "sha256:f1da2028cb4e41be55ee797a82d6c1cf589442504244249dfeb32efc608edee7"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1340b56340896bede246f612b6ecf685f661a56aabef3d2512481bfe23ac5835"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2316515169b7b5a453f0ce3adbc46c42aa332cae9f2edb668e24d1fc92b2f2bb"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e06fe6a12241ec1b72c0566c6b28cda714d61965d86569595ad24793d1ab259"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d99c1cd9443b19164ec185a7d752f4b4db19c066c136f028991a480720472e23"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1d9aa156ed52d3446388ba4c2f335e312191d1ca9d1f5762ee983cf23e4ecf6"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:54bcf4efaaee8e015822be0c2c28214815f4f6b4f70d8362cfecbd58a71188ac"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0c955e32afdbfdf6e9ee663d24afb25210152d98c26d22d399712d29a9b976b"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:191633722203f5b7717efcb73a14f76f3b124877d0608c070b827c5226d0b972"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:195baad28057ec9609e40385991004e470af9ef87401e24ebe72c064431524ab"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0fff4a6b87c07366662b62ae994ffbeadc472e72f725923f94b72a3db49f4671"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4ffed25f9fdc0b287f30a98467493d1e1ce5b583f6317f70ec0263b3c97dbba6"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d02cf8e5af89a9ac8f53c438ddff6d773f62c25c6619b29db96f4aae248177c0"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-win32.whl", hash = "sha256:f3bb81d4fe6a5d20650f8c0afcc8f6e1941f6fecdb434f11b874c42467baded0"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:aaf83e9170cb1338922ae42d320699dccbbdca8ffed07faeb0b9257822c26e24"}, + {file = "rapidfuzz-3.10.1-cp312-cp312-win_arm64.whl", hash = "sha256:c5da802a0d085ad81b0f62828fb55557996c497b2d0b551bbdfeafd6d447892f"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fc22d69a1c9cccd560a5c434c0371b2df0f47c309c635a01a913e03bbf183710"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38b0dac2c8e057562b8f0d8ae5b663d2d6a28c5ab624de5b73cef9abb6129a24"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fde3bbb14e92ce8fcb5c2edfff72e474d0080cadda1c97785bf4822f037a309"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9141fb0592e55f98fe9ac0f3ce883199b9c13e262e0bf40c5b18cdf926109d16"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:237bec5dd1bfc9b40bbd786cd27949ef0c0eb5fab5eb491904c6b5df59d39d3c"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18123168cba156ab5794ea6de66db50f21bb3c66ae748d03316e71b27d907b95"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b75fe506c8e02769cc47f5ab21ce3e09b6211d3edaa8f8f27331cb6988779be"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9da82aa4b46973aaf9e03bb4c3d6977004648c8638febfc0f9d237e865761270"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c34c022d5ad564f1a5a57a4a89793bd70d7bad428150fb8ff2760b223407cdcf"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1e96c84d6c2a0ca94e15acb5399118fff669f4306beb98a6d8ec6f5dccab4412"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e8e154b84a311263e1aca86818c962e1fa9eefdd643d1d5d197fcd2738f88cb9"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:335fee93188f8cd585552bb8057228ce0111bd227fa81bfd40b7df6b75def8ab"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-win32.whl", hash = "sha256:6729b856166a9e95c278410f73683957ea6100c8a9d0a8dbe434c49663689255"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-win_amd64.whl", hash = "sha256:0e06d99ad1ad97cb2ef7f51ec6b1fedd74a3a700e4949353871cf331d07b382a"}, + {file = "rapidfuzz-3.10.1-cp313-cp313-win_arm64.whl", hash = "sha256:8d1b7082104d596a3eb012e0549b2634ed15015b569f48879701e9d8db959dbb"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:779027d3307e1a2b1dc0c03c34df87a470a368a1a0840a9d2908baf2d4067956"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:440b5608ab12650d0390128d6858bc839ae77ffe5edf0b33a1551f2fa9860651"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cac41a411e07a6f3dc80dfbd33f6be70ea0abd72e99c59310819d09f07d945"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:958473c9f0bca250590200fd520b75be0dbdbc4a7327dc87a55b6d7dc8d68552"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ef60dfa73749ef91cb6073be1a3e135f4846ec809cc115f3cbfc6fe283a5584"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7fbac18f2c19fc983838a60611e67e3262e36859994c26f2ee85bb268de2355"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a0d519ff39db887cd73f4e297922786d548f5c05d6b51f4e6754f452a7f4296"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bebb7bc6aeb91cc57e4881b222484c26759ca865794187217c9dcea6c33adae6"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fe07f8b9c3bb5c5ad1d2c66884253e03800f4189a60eb6acd6119ebaf3eb9894"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:bfa48a4a2d45a41457f0840c48e579db157a927f4e97acf6e20df8fc521c79de"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2cf44d01bfe8ee605b7eaeecbc2b9ca64fc55765f17b304b40ed8995f69d7716"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e6bbca9246d9eedaa1c84e04a7f555493ba324d52ae4d9f3d9ddd1b740dcd87"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-win32.whl", hash = "sha256:567f88180f2c1423b4fe3f3ad6e6310fc97b85bdba574801548597287fc07028"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:6b2cd7c29d6ecdf0b780deb587198f13213ac01c430ada6913452fd0c40190fc"}, + {file = "rapidfuzz-3.10.1-cp39-cp39-win_arm64.whl", hash = "sha256:9f912d459e46607ce276128f52bea21ebc3e9a5ccf4cccfef30dd5bddcf47be8"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ac4452f182243cfab30ba4668ef2de101effaedc30f9faabb06a095a8c90fd16"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:565c2bd4f7d23c32834652b27b51dd711814ab614b4e12add8476be4e20d1cf5"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:187d9747149321607be4ccd6f9f366730078bed806178ec3eeb31d05545e9e8f"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:616290fb9a8fa87e48cb0326d26f98d4e29f17c3b762c2d586f2b35c1fd2034b"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:073a5b107e17ebd264198b78614c0206fa438cce749692af5bc5f8f484883f50"}, + {file = "rapidfuzz-3.10.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:39c4983e2e2ccb9732f3ac7d81617088822f4a12291d416b09b8a1eadebb3e29"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ac7adee6bcf0c6fee495d877edad1540a7e0f5fc208da03ccb64734b43522d7a"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:425f4ac80b22153d391ee3f94bc854668a0c6c129f05cf2eaf5ee74474ddb69e"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65a2fa13e8a219f9b5dcb9e74abe3ced5838a7327e629f426d333dfc8c5a6e66"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75561f3df9a906aaa23787e9992b228b1ab69007932dc42070f747103e177ba8"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:edd062490537e97ca125bc6c7f2b7331c2b73d21dc304615afe61ad1691e15d5"}, + {file = "rapidfuzz-3.10.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfcc8feccf63245a22dfdd16e222f1a39771a44b870beb748117a0e09cbb4a62"}, + {file = "rapidfuzz-3.10.1.tar.gz", hash = "sha256:5a15546d847a915b3f42dc79ef9b0c78b998b4e2c53b252e7166284066585979"}, +] + +[package.extras] +all = ["numpy"] + +[[package]] +name = "regex" +version = "2024.11.6" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.8" +files = [ + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, +] + +[[package]] +name = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-cache" +version = "1.2.1" +description = "A persistent cache for python requests" +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, + {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, +] + +[package.dependencies] +attrs = ">=21.2" +cattrs = ">=22.2" +platformdirs = ">=2.5" +requests = ">=2.22" +url-normalize = ">=1.4" +urllib3 = ">=1.25.5" + +[package.extras] +all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] +bson = ["bson (>=0.5)"] +docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] +dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] +json = ["ujson (>=5.4)"] +mongodb = ["pymongo (>=3)"] +redis = ["redis (>=3)"] +security = ["itsdangerous (>=2.0)"] +yaml = ["pyyaml (>=6.0.1)"] + +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +description = "A utility belt for advanced users of python-requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, + {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, +] + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + +[[package]] +name = "serpyco-rs" +version = "1.11.0" +description = "" +optional = false +python-versions = ">=3.9" +files = [ + {file = "serpyco_rs-1.11.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4b2bd933539bd8c84315e2fb5ae52ef7a58ace5a6dfe3f8b73f74dc71216779e"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:627f957889ff73c4d2269fc7b6bba93212381befe03633e7cb5495de66ba9a33"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b0933620abc01434023e0e3e22255b7e4ab9b427b5a9a5ee00834656d792377a"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9ce46683d92e34abb20304817fc5ac6cb141a06fc7468dedb1d8865a8a9682f6"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bda437d86e8859bf91c189c1f4650899822f6d6d7b02b48f5729da904eb7bb7d"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a72bfbd282af17ebe76d122639013e802c09902543fdbbd828fb2159ec9755e"}, + {file = "serpyco_rs-1.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d4808df5384e3e8581e31a90ba7a1fa501c0837b1f174284bb8a4555b6864ea"}, + {file = "serpyco_rs-1.11.0-cp310-none-win_amd64.whl", hash = "sha256:c7b60aef4c16d68efb0d6241f05d0a434d873d98449cbb4366b0d385f0a7172b"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d47ee577cf4d69b53917615cb031ad8708eb2f59fe78194b1968c13130fc2f7"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6090d9a1487237cdd4e9362a823eede23249602019b917e7bd57846179286e79"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7192eb3df576386fefd595ea31ae25c62522841ffec7e7aeb37a80b55bdc3213"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b52ef8affb7e71b9b98a7d5216d6a7ad03b04e990acb147cd9211c8b931c5487"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3480e09e473560c60e74aaa789e6b4d079637371aae0a98235440111464bbba7"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c92e36b0ab6fe866601c2331f7e99c809a126d21963c03d8a5c29331526deed"}, + {file = "serpyco_rs-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84f497361952d4566bc1f77e9e15a84a2614f593cc671fbf0a0fa80046f9c3d7"}, + {file = "serpyco_rs-1.11.0-cp311-none-win_amd64.whl", hash = "sha256:37fc1cf192bef9784fbf1f4e03cec21750b9e704bef55cc0442f71a715eee920"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3ea93d485f03dc8b0cfb0d477f0ad2e86e78f0461b53010656ab5b4db1b41fb0"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7772410d15694b03f9c5500a2c47d62eed76e191bea4087ad042250346b1a38e"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42118463c1679846cffd2f06f47744c9b9eb33c5d0448afd88ea19e1a81a8ddd"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:79481a455b76cc56021dc55bb6d5bdda1b2b32bcb6a1ee711b597140d112e9b1"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8fd79051f9af9591fc03cf7d3033ff180416301f6a4fd3d1e3d92ebd2d68697"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d29c8f9aeed734a3b51f7349d04ec9063516ffa4e10b632d75e9b1309e4930e4"}, + {file = "serpyco_rs-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15609158b0d9591ffa118302cd9d0039970cb3faf91dce32975f7d276e7411d5"}, + {file = "serpyco_rs-1.11.0-cp312-none-win_amd64.whl", hash = "sha256:00081eae77fbf4c5d88371c5586317ab02ccb293a330b460869a283edf2b7b69"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3028893366a1985adcedb13fa8f6f98c087c185efc427f94c2ccdafa40f45832"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c18bf511316f3abf648a68ee62ef88617bec57d3fcde69466b4361102715ae5"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7dde9ef09cdfaf7c62378186b9e29f54ec76114be4c347be6a06dd559c5681e"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:18500ebc5e75285841e35585a238629a990b709e14f68933233640d15ca17d5f"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47c23132d4e03982703a7630aa09877b41e499722142f76b6153f6619b612f3"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5f8e6ba499f6a0825bee0d8f8764569d367af871b563fc6512c171474e8e5383"}, + {file = "serpyco_rs-1.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15438a076047c34cff6601a977df54948e8d39d1a86f89d05c48bc60f4c12a61"}, + {file = "serpyco_rs-1.11.0-cp313-none-win_amd64.whl", hash = "sha256:84ee2c109415bd81904fc9abb9aec86a5dd13166808c21142cf23ec639f683bd"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5c97c16c865261577fac4effeccc7ef5e0a1e8e35e7a3ee6c90c77c3a4cd7ff9"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47825e70f86fd6ef7c4a835dea3d6e8eef4fee354ed7b39ced99f31aba74a86e"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24d220220365110edba2f778f41ab3cf396883da0f26e1361a3ada9bd0227f73"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3a46f334af5a9d77acc6e1e58f355ae497900a2798929371f0545e274f6e6166"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d72b748acce4b4e3c7c9724e1eb33d033a1c26b08a698b393e0288060e0901"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2b8b6f205e8cc038d4d30dd0e70eece7bbecc816eb2f3787c330dc2218e232d"}, + {file = "serpyco_rs-1.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:038d748bfff31f150f0c3edab2766b8843edb952cb1bd3bf547886beb0912dae"}, + {file = "serpyco_rs-1.11.0-cp39-none-win_amd64.whl", hash = "sha256:0fee1c89ec2cb013dc232e4ebef88e2844357ce8631063b56639dbfb83762f20"}, + {file = "serpyco_rs-1.11.0.tar.gz", hash = "sha256:70a844615ffb229e6e89c204b3ab7404aacaf2838911814c7d847969b8da2e3a"}, +] + +[package.dependencies] +attributes-doc = "*" +typing-extensions = "*" + +[[package]] +name = "six" +version = "1.17.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, +] + +[[package]] +name = "tenacity" +version = "8.5.0" +description = "Retry code until it succeeds" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, + {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, +] + +[package.extras] +doc = ["reno", "sphinx"] +test = ["pytest", "tornado (>=4.5)", "typeguard"] + +[[package]] +name = "tomli" +version = "2.2.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, +] + +[[package]] +name = "tqdm" +version = "4.67.1" +description = "Fast, Extensible Progress Meter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + +[[package]] +name = "tzdata" +version = "2024.2" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, + {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, +] + +[[package]] +name = "url-normalize" +version = "1.4.3" +description = "URL normalization for Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, + {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "urllib3" +version = "2.2.3" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, + {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "wcmatch" +version = "10.0" +description = "Wildcard/glob file name matcher." +optional = false +python-versions = ">=3.8" +files = [ + {file = "wcmatch-10.0-py3-none-any.whl", hash = "sha256:0dd927072d03c0a6527a20d2e6ad5ba8d0380e60870c383bc533b71744df7b7a"}, + {file = "wcmatch-10.0.tar.gz", hash = "sha256:e72f0de09bba6a04e0de70937b0cf06e55f36f37b3deb422dfaf854b867b840a"}, +] + +[package.dependencies] +bracex = ">=2.1.1" + +[[package]] +name = "xmltodict" +version = "0.13.0" +description = "Makes working with XML feel like you are working with JSON" +optional = false +python-versions = ">=3.4" +files = [ + {file = "xmltodict-0.13.0-py2.py3-none-any.whl", hash = "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"}, + {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.10,<3.13" +content-hash = "c503ad9a60d0c1ac805f40db31e35c342d913a6cc5cf34404b8598c2bcd72e11" diff --git a/airbyte-integrations/connectors/source-the-guardian-api/unit_tests/pyproject.toml b/airbyte-integrations/connectors/source-the-guardian-api/unit_tests/pyproject.toml new file mode 100644 index 000000000000..f7f8d415a32a --- /dev/null +++ b/airbyte-integrations/connectors/source-the-guardian-api/unit_tests/pyproject.toml @@ -0,0 +1,19 @@ +[build-system] +requires = [ "poetry-core>=1.0.0",] +build-backend = "poetry.core.masonry.api" + +[tool.poetry] +name = "source-the-guardian-api-tests" +version = "0.0.0" +description = "Unit tests for source-the-guardian-api" +authors = ["Airbyte "] + +[tool.poetry.dependencies] +python = "^3.10,<3.13" +airbyte-cdk = "6.10.0" +pytest = "^8" + +[tool.pytest.ini_options] +filterwarnings = [ + "ignore:This class is experimental*" +] diff --git a/airbyte-integrations/connectors/source-the-guardian-api/unit_tests/test_paginator.py b/airbyte-integrations/connectors/source-the-guardian-api/unit_tests/test_paginator.py new file mode 100644 index 000000000000..1e2ca8425a3f --- /dev/null +++ b/airbyte-integrations/connectors/source-the-guardian-api/unit_tests/test_paginator.py @@ -0,0 +1,65 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + +from unittest.mock import MagicMock + +import pytest +import requests + + +def create_response(current_page: int, total_pages: int) -> requests.Response: + """Helper function to create mock responses""" + response = MagicMock(spec=requests.Response) + response.json.return_value = {"response": {"currentPage": current_page, "pages": total_pages}} + return response + + +@pytest.mark.parametrize( + "current_page,total_pages,expected_next_page", + [ + (1, 5, 2), # First page + (2, 5, 3), # Middle page + (4, 5, 5), # Second to last page + (5, 5, None), # Last page + (1, 1, None), # Single page + ], + ids=["First page", "Middle page", "Penultimate page", "Last page", "Single page"], +) +def test_page_increment(connector_dir, components_module, current_page, total_pages, expected_next_page): + """Test the CustomPageIncrement pagination for various page combinations""" + + CustomPageIncrement = components_module.CustomPageIncrement + + config = {} + page_size = 10 + parameters = {} + paginator = CustomPageIncrement(config, page_size, parameters) + + # Set internal page counter to match current_page + paginator._page = current_page + + mock_response = create_response(current_page, total_pages) + next_page = paginator.next_page_token(mock_response) + assert next_page == expected_next_page, f"Page {current_page} of {total_pages} should get next_page={expected_next_page}" + + +def test_reset_functionality(components_module): + """Test the reset behavior of CustomPageIncrement""" + CustomPageIncrement = components_module.CustomPageIncrement + + config = {} + page_size = 10 + parameters = {} + paginator = CustomPageIncrement(config, page_size, parameters) + + # Advance a few pages + mock_response = create_response(current_page=1, total_pages=5) + paginator.next_page_token(mock_response) + paginator.next_page_token(create_response(current_page=2, total_pages=5)) + + # Test reset + paginator.reset() + assert paginator._page == 1, "Reset should set page back to 1" + + # Verify pagination works after reset + next_page = paginator.next_page_token(mock_response) + assert next_page == 2, "Should increment to page 2 after reset" diff --git a/airbyte-integrations/connectors/source-thinkific/metadata.yaml b/airbyte-integrations/connectors/source-thinkific/metadata.yaml index d46459891f05..24653042ed32 100644 --- a/airbyte-integrations/connectors/source-thinkific/metadata.yaml +++ b/airbyte-integrations/connectors/source-thinkific/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-thinkific connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 80e5803c-7013-4ecc-a3b1-2344ce43e054 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-thinkific githubIssueLabel: source-thinkific icon: icon.svg diff --git a/airbyte-integrations/connectors/source-ticketmaster/metadata.yaml b/airbyte-integrations/connectors/source-ticketmaster/metadata.yaml index 2ee4f84c3774..7218ee737239 100644 --- a/airbyte-integrations/connectors/source-ticketmaster/metadata.yaml +++ b/airbyte-integrations/connectors/source-ticketmaster/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-ticketmaster connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.14.0@sha256:accdf6c1bbcabd45b40f836692e4f3b1a1e1f0b28267973802ee212cd9c2c16a + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 053eb2fe-5c44-49fc-a1e4-2dc82b09318e - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-ticketmaster githubIssueLabel: source-ticketmaster icon: icon.svg diff --git a/airbyte-integrations/connectors/source-tickettailor/README.md b/airbyte-integrations/connectors/source-tickettailor/README.md new file mode 100644 index 000000000000..a4e020b98801 --- /dev/null +++ b/airbyte-integrations/connectors/source-tickettailor/README.md @@ -0,0 +1,33 @@ +# TicketTailor +This directory contains the manifest-only connector for `source-tickettailor`. + +The Airbyte connector for [TicketTailor](https://tickettailor.com) enables seamless extraction of key event data, including details on events, products, vouchers, discounts, check-ins, issued tickets, orders, and waitlists. This integration allows businesses to analyze ticket sales, attendance, and customer interactions, streamlining event management insights. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-tickettailor:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-tickettailor build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-tickettailor test +``` + diff --git a/airbyte-integrations/connectors/source-tickettailor/acceptance-test-config.yml b/airbyte-integrations/connectors/source-tickettailor/acceptance-test-config.yml new file mode 100644 index 000000000000..9131f5950ca5 --- /dev/null +++ b/airbyte-integrations/connectors/source-tickettailor/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-tickettailor:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-tickettailor/icon.svg b/airbyte-integrations/connectors/source-tickettailor/icon.svg new file mode 100644 index 000000000000..fcbbe13696f6 --- /dev/null +++ b/airbyte-integrations/connectors/source-tickettailor/icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/airbyte-integrations/connectors/source-tickettailor/manifest.yaml b/airbyte-integrations/connectors/source-tickettailor/manifest.yaml new file mode 100644 index 000000000000..2c6841469529 --- /dev/null +++ b/airbyte-integrations/connectors/source-tickettailor/manifest.yaml @@ -0,0 +1,1702 @@ +version: 6.1.0 + +type: DeclarativeSource + +description: >- + The Airbyte connector for [TicketTailor](https://tickettailor.com) enables + seamless extraction of key event data, including details on events, products, + vouchers, discounts, check-ins, issued tickets, orders, and waitlists. This + integration allows businesses to analyze ticket sales, attendance, and + customer interactions, streamlining event management insights. + +check: + type: CheckStream + stream_names: + - events_series + +definitions: + streams: + events: + type: DeclarativeStream + name: events + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: starting_after + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ response.links.next is none }}" + requester: + $ref: "#/definitions/base_requester" + path: /event_series/{{ stream_partition.event_series_id }}/events + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: + $ref: "#/definitions/streams/events_series" + parent_key: id + partition_field: event_series_id + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/events" + orders: + type: DeclarativeStream + name: orders + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: starting_after + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ response.links.next is none }}" + requester: + $ref: "#/definitions/base_requester" + path: /orders + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/orders" + products: + type: DeclarativeStream + name: products + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: starting_after + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ response.links.next is none }}" + requester: + $ref: "#/definitions/base_requester" + path: /products + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + vouchers: + type: DeclarativeStream + name: vouchers + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: starting_after + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ response.links.next is none }}" + requester: + $ref: "#/definitions/base_requester" + path: /vouchers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/vouchers" + check_ins: + type: DeclarativeStream + name: check_ins + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: starting_after + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ response.links.next is none }}" + requester: + $ref: "#/definitions/base_requester" + path: /check_ins + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/check_ins" + discounts: + type: DeclarativeStream + name: discounts + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: starting_after + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ response.links.next is none }}" + requester: + $ref: "#/definitions/base_requester" + path: /discounts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/discounts" + waitlists: + type: DeclarativeStream + name: waitlists + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: starting_after + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ response.links.next is none }}" + requester: + $ref: "#/definitions/base_requester" + path: >- + /event_series/{{ stream_partition.event_series_id + }}/waitlist_signups + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: + $ref: "#/definitions/streams/events_series" + parent_key: id + partition_field: event_series_id + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/waitlists" + events_series: + type: DeclarativeStream + name: events_series + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: starting_after + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ response.links.next is none }}" + requester: + $ref: "#/definitions/base_requester" + path: /event_series + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/events_series" + issued_tickets: + type: DeclarativeStream + name: issued_tickets + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: starting_after + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ response.links.next is none }}" + requester: + $ref: "#/definitions/base_requester" + path: /issued_tickets + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/issued_tickets" + vouchers_codes: + type: DeclarativeStream + name: vouchers_codes + retriever: + type: SimpleRetriever + paginator: + type: DefaultPaginator + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + page_token_option: + type: RequestOption + field_name: starting_after + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ last_record['id'] }}" + stop_condition: "{{ response.links.next is none }}" + requester: + $ref: "#/definitions/base_requester" + path: /vouchers/{{ stream_partition.voucher_id }}/codes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + stream: + $ref: "#/definitions/streams/vouchers" + parent_key: id + partition_field: voucher_id + primary_key: + - id + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/vouchers_codes" + base_requester: + type: HttpRequester + url_base: https://api.tickettailor.com/v1 + authenticator: + type: BasicHttpAuthenticator + username: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/events_series" + - $ref: "#/definitions/streams/events" + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/vouchers" + - $ref: "#/definitions/streams/discounts" + - $ref: "#/definitions/streams/check_ins" + - $ref: "#/definitions/streams/issued_tickets" + - $ref: "#/definitions/streams/orders" + - $ref: "#/definitions/streams/waitlists" + - $ref: "#/definitions/streams/vouchers_codes" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + description: API key to use. Find it at https://www.getdrip.com/user/edit + name: api_key + order: 0 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + assist: + docsUrl: https://developers.tickettailor.com/ + testedStreams: + events: + hasRecords: true + streamHash: 4c7e6383c411206fda1cd6fb8b3f1907af4ac154 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + orders: + hasRecords: true + streamHash: 22469a462b78e7c6bec358fbda0b953ee34c61e2 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + products: + hasRecords: true + streamHash: 5c343c5681138d3959a81f5150fd053edc381c83 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + vouchers: + hasRecords: true + streamHash: 46718e9c71f7dcd6d5b5c9e8de5fcf0a76bd14a9 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + check_ins: + hasRecords: true + streamHash: b77c3fb88b9fb6929fae8929e7cb269e50cf4b5e + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + discounts: + hasRecords: true + streamHash: 00b8b496bee85bb5d2c21f3879830d73b0ce5d01 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + waitlists: + hasRecords: true + streamHash: a6980ff5fc3e0602c1f89e98149d3c066a74e5ac + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + events_series: + hasRecords: true + streamHash: 8edc6149c41ac5f309b997d506e5a331bb215a65 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + issued_tickets: + hasRecords: true + streamHash: 1790e3cd3a801aeabd8fe92cbeefca72505ee4a3 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + vouchers_codes: + hasRecords: true + streamHash: b20f977fbefd70df0ded312917929285c04800b4 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + yamlComponents: + global: + - authenticator + autoImportSchema: + events: false + orders: true + products: true + vouchers: true + check_ins: true + discounts: true + waitlists: true + events_series: false + issued_tickets: false + vouchers_codes: true + +schemas: + events: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + chk: + type: + - string + - "null" + end: + type: + - object + - "null" + properties: + iso: + type: + - string + - "null" + date: + type: + - string + - "null" + time: + type: + - string + - "null" + unix: + type: + - number + - "null" + timezone: + type: + - string + - "null" + formatted: + type: + - string + - "null" + start: + type: + - object + - "null" + properties: + iso: + type: + - string + - "null" + date: + type: + - string + - "null" + time: + type: + - string + - "null" + unix: + type: + - number + - "null" + timezone: + type: + - string + - "null" + formatted: + type: + - string + - "null" + hidden: + type: + - string + - "null" + object: + type: + - string + - "null" + bundles: + type: + - array + - "null" + revenue: + type: + - number + - "null" + currency: + type: + - string + - "null" + unavailable: + type: + - string + - "null" + ticket_types: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + price: + type: + - number + - "null" + object: + type: + - string + - "null" + status: + type: + - string + - "null" + quantity: + type: + - number + - "null" + sort_order: + type: + - number + - "null" + booking_fee: + type: + - number + - "null" + has_overrides: + type: + - string + - "null" + max_per_order: + type: + - number + - "null" + min_per_order: + type: + - number + - "null" + quantity_held: + type: + - number + - "null" + quantity_total: + type: + - number + - "null" + quantity_issued: + type: + - number + - "null" + ticket_groups: + type: + - array + - "null" + event_series_id: + type: + - string + - "null" + tickets_available: + type: + - string + - "null" + total_issued_tickets: + type: + - number + - "null" + additionalProperties: true + orders: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + tax: + type: + - number + - "null" + total: + type: + - number + - "null" + object: + type: + - string + - "null" + status: + type: + - string + - "null" + txn_id: + type: + - string + - "null" + currency: + type: + - object + - "null" + properties: + code: + type: + - string + - "null" + base_multiplier: + type: + - number + - "null" + subtotal: + type: + - number + - "null" + meta_data: + type: + - array + - "null" + created_at: + type: + - number + - "null" + line_items: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + id: + type: + - string + - "null" + total: + type: + - number + - "null" + value: + type: + - number + - "null" + object: + type: + - string + - "null" + item_id: + type: + - string + - "null" + quantity: + type: + - number + - "null" + booking_fee: + type: + - number + - "null" + total_paid: + type: + - number + - "null" + buyer_details: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + email: + type: + - string + - "null" + phone: + type: + - string + - "null" + address: + type: + - object + - "null" + properties: + address_1: + type: + - string + - "null" + address_2: + type: + - string + - "null" + address_3: + type: + - string + - "null" + postal_code: + type: + - string + - "null" + last_name: + type: + - string + - "null" + first_name: + type: + - string + - "null" + custom_questions: + type: + - array + - "null" + event_summary: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + venue: + type: + - object + - "null" + properties: + postal_code: + type: + - string + - "null" + end_date: + type: + - object + - "null" + properties: + iso: + type: + - string + - "null" + date: + type: + - string + - "null" + time: + type: + - string + - "null" + unix: + type: + - number + - "null" + timezone: + type: + - string + - "null" + formatted: + type: + - string + - "null" + event_id: + type: + - string + - "null" + start_date: + type: + - object + - "null" + properties: + iso: + type: + - string + - "null" + date: + type: + - string + - "null" + time: + type: + - string + - "null" + unix: + type: + - number + - "null" + timezone: + type: + - string + - "null" + formatted: + type: + - string + - "null" + event_series_id: + type: + - string + - "null" + refund_amount: + type: + - number + - "null" + tax_treatment: + type: + - string + - "null" + issued_tickets: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + id: + type: + - string + - "null" + email: + type: + - string + - "null" + object: + type: + - string + - "null" + source: + type: + - string + - "null" + status: + type: + - string + - "null" + barcode: + type: + - string + - "null" + event_id: + type: + - string + - "null" + order_id: + type: + - string + - "null" + checked_in: + type: + - string + - "null" + created_at: + type: + - number + - "null" + updated_at: + type: + - number + - "null" + barcode_url: + type: + - string + - "null" + qr_code_url: + type: + - string + - "null" + ticket_type_id: + type: + - string + - "null" + event_series_id: + type: + - string + - "null" + custom_questions: + type: + - array + - "null" + payment_method: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + credited_out_amount: + type: + - number + - "null" + additionalProperties: true + products: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + name: + type: + - string + - "null" + price: + type: + - number + - "null" + object: + type: + - string + - "null" + status: + type: + - string + - "null" + currency: + type: + - string + - "null" + created_at: + type: + - object + - "null" + properties: + iso: + type: + - string + - "null" + date: + type: + - string + - "null" + time: + type: + - string + - "null" + unix: + type: + - number + - "null" + timezone: + type: + - string + - "null" + formatted: + type: + - string + - "null" + updated_at: + type: + - object + - "null" + properties: + iso: + type: + - string + - "null" + date: + type: + - string + - "null" + time: + type: + - string + - "null" + unix: + type: + - number + - "null" + timezone: + type: + - string + - "null" + formatted: + type: + - string + - "null" + fulfilment_type: + type: + - string + - "null" + linked_to_all_event_series: + type: + - string + - "null" + additionalProperties: true + vouchers: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + type: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + value: + type: + - number + - "null" + expiry: + type: + - object + - "null" + properties: + iso: + type: + - string + - "null" + date: + type: + - string + - "null" + time: + type: + - string + - "null" + unix: + type: + - number + - "null" + timezone: + type: + - string + - "null" + formatted: + type: + - string + - "null" + object: + type: + - string + - "null" + currency: + type: + - string + - "null" + total_codes: + type: + - number + - "null" + available_codes: + type: + - number + - "null" + event_series_ids: + type: + - array + - "null" + partial_redemption: + type: + - string + - "null" + usable_on_any_event: + type: + - string + - "null" + additionalProperties: true + check_ins: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + object: + type: + - string + - "null" + event_id: + type: + - string + - "null" + quantity: + type: + - number + - "null" + created_at: + type: + - number + - "null" + check_in_at: + type: + - number + - "null" + event_series_id: + type: + - string + - "null" + issued_ticket_id: + type: + - string + - "null" + additionalProperties: true + discounts: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + type: + type: + - string + - "null" + id: + type: string + code: + type: + - string + - "null" + name: + type: + - string + - "null" + object: + type: + - string + - "null" + products: + type: + - array + - "null" + items: + type: + - string + - "null" + ticket_types: + type: + - array + - "null" + items: + type: + - string + - "null" + face_value_amount: + type: + - number + - "null" + booking_fee_amount: + type: + - number + - "null" + additionalProperties: true + waitlists: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + email: + type: + - string + - "null" + object: + type: + - string + - "null" + event_id: + type: + - string + - "null" + created_at: + type: + - object + - "null" + properties: + iso: + type: + - string + - "null" + date: + type: + - string + - "null" + time: + type: + - string + - "null" + unix: + type: + - number + - "null" + timezone: + type: + - string + - "null" + formatted: + type: + - string + - "null" + additionalProperties: true + events_series: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + url: + type: + - string + - "null" + name: + type: + - string + - "null" + venue: + type: + - object + - "null" + properties: + postal_code: + type: + - string + - "null" + images: + type: + - object + - "null" + properties: + header: + type: + - string + - "null" + thumbnail: + type: + - string + - "null" + object: + type: + - string + - "null" + status: + type: + - string + - "null" + add_ons: + type: + - array + - "null" + bundles: + type: + - array + - "null" + private: + type: + - string + - "null" + revenue: + type: + - number + - "null" + currency: + type: + - string + - "null" + timezone: + type: + - string + - "null" + created_at: + type: + - number + - "null" + voucher_ids: + type: + - array + - "null" + online_event: + type: + - string + - "null" + call_to_action: + type: + - string + - "null" + payment_methods: + type: + - array + - "null" + total_occurrences: + type: + - number + - "null" + default_ticket_types: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + price: + type: + - number + - "null" + object: + type: + - string + - "null" + status: + type: + - string + - "null" + quantity: + type: + - number + - "null" + sort_order: + type: + - number + - "null" + booking_fee: + type: + - number + - "null" + has_overrides: + type: + - string + - "null" + max_per_order: + type: + - number + - "null" + min_per_order: + type: + - number + - "null" + quantity_held: + type: + - number + - "null" + quantity_total: + type: + - number + - "null" + quantity_issued: + type: + - number + - "null" + next_occurrence_date: + type: + - object + - "null" + properties: + iso: + type: + - string + - "null" + date: + type: + - string + - "null" + time: + type: + - string + - "null" + unix: + type: + - number + - "null" + timezone: + type: + - string + - "null" + formatted: + type: + - string + - "null" + total_issued_tickets: + type: + - number + - "null" + upcoming_occurrences: + type: + - number + - "null" + default_ticket_groups: + type: + - array + - "null" + additionalProperties: true + issued_tickets: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + description: + type: + - string + - "null" + id: + type: string + email: + type: + - string + - "null" + object: + type: + - string + - "null" + source: + type: + - string + - "null" + status: + type: + - string + - "null" + barcode: + type: + - string + - "null" + event_id: + type: + - string + - "null" + order_id: + type: + - string + - "null" + full_name: + type: + - string + - "null" + last_name: + type: + - string + - "null" + checked_in: + type: + - string + - "null" + created_at: + type: + - number + - "null" + first_name: + type: + - string + - "null" + updated_at: + type: + - number + - "null" + barcode_url: + type: + - string + - "null" + qr_code_url: + type: + - string + - "null" + ticket_type_id: + type: + - string + - "null" + event_series_id: + type: + - string + - "null" + custom_questions: + type: + - array + - "null" + additionalProperties: true + vouchers_codes: + type: object + $schema: http://json-schema.org/schema# + required: + - id + properties: + id: + type: string + code: + type: + - string + - "null" + value: + type: + - number + - "null" + expiry: + type: + - object + - "null" + properties: + iso: + type: + - string + - "null" + date: + type: + - string + - "null" + time: + type: + - string + - "null" + unix: + type: + - number + - "null" + timezone: + type: + - string + - "null" + formatted: + type: + - string + - "null" + object: + type: + - string + - "null" + voucher_id: + type: + - string + - "null" + additionalProperties: true diff --git a/airbyte-integrations/connectors/source-tickettailor/metadata.yaml b/airbyte-integrations/connectors/source-tickettailor/metadata.yaml new file mode 100644 index 000000000000..3e40b4671af0 --- /dev/null +++ b/airbyte-integrations/connectors/source-tickettailor/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.tickettailor.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-tickettailor + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: e5f3b2f5-5782-46d6-8c6a-980d82686ff6 + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-tickettailor + githubIssueLabel: source-tickettailor + icon: icon.svg + license: MIT + name: TicketTailor + releaseDate: 2024-11-06 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/tickettailor + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-tidb/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-tidb/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-tidb/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-tidb/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-tidb/metadata.yaml b/airbyte-integrations/connectors/source-tidb/metadata.yaml index 99305b6e9427..79bcacabb3e0 100644 --- a/airbyte-integrations/connectors/source-tidb/metadata.yaml +++ b/airbyte-integrations/connectors/source-tidb/metadata.yaml @@ -1,13 +1,22 @@ data: + ab_internal: + ql: 100 + sl: 100 allowedHosts: hosts: - ${host} - ${tunnel_method.tunnel_host} + connectorBuildOptions: + baseImage: docker.io/airbyte/java-connector-base:1.0.0@sha256:be86e5684e1e6d9280512d3d8071b47153698fe08ad990949c8eeff02803201a connectorSubtype: database + connectorTestSuitesOptions: + - suite: unitTests + - suite: integrationTests connectorType: source definitionId: 0dad1a35-ccf8-4d03-b73e-6788c00b13ae - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.3 dockerRepository: airbyte/source-tidb + documentationUrl: https://docs.airbyte.com/integrations/sources/tidb githubIssueLabel: source-tidb icon: tidb.svg license: MIT @@ -18,14 +27,7 @@ data: oss: enabled: true releaseStage: alpha - documentationUrl: https://docs.airbyte.com/integrations/sources/tidb + supportLevel: community tags: - language:java - ab_internal: - sl: 100 - ql: 100 - supportLevel: community - connectorTestSuitesOptions: - - suite: unitTests - - suite: integrationTests metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-tiktok-marketing/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-tiktok-marketing/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-tiktok-marketing/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-tiktok-marketing/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-tiktok-marketing/main.py b/airbyte-integrations/connectors/source-tiktok-marketing/main.py index b523ea1b0fdd..cc7653e249d5 100644 --- a/airbyte-integrations/connectors/source-tiktok-marketing/main.py +++ b/airbyte-integrations/connectors/source-tiktok-marketing/main.py @@ -4,5 +4,6 @@ from source_tiktok_marketing.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-tiktok-marketing/source_tiktok_marketing/components/advertiser_ids_partition_router.py b/airbyte-integrations/connectors/source-tiktok-marketing/source_tiktok_marketing/components/advertiser_ids_partition_router.py index f74710d7d2ff..d7ad3129553a 100644 --- a/airbyte-integrations/connectors/source-tiktok-marketing/source_tiktok_marketing/components/advertiser_ids_partition_router.py +++ b/airbyte-integrations/connectors/source-tiktok-marketing/source_tiktok_marketing/components/advertiser_ids_partition_router.py @@ -4,6 +4,7 @@ from typing import Any, Iterable, Mapping import dpath.util + from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import SubstreamPartitionRouter from airbyte_cdk.sources.declarative.types import StreamSlice diff --git a/airbyte-integrations/connectors/source-tiktok-marketing/source_tiktok_marketing/components/semi_incremental_record_filter.py b/airbyte-integrations/connectors/source-tiktok-marketing/source_tiktok_marketing/components/semi_incremental_record_filter.py index 628a57a7a89f..21b5ae6eccea 100644 --- a/airbyte-integrations/connectors/source-tiktok-marketing/source_tiktok_marketing/components/semi_incremental_record_filter.py +++ b/airbyte-integrations/connectors/source-tiktok-marketing/source_tiktok_marketing/components/semi_incremental_record_filter.py @@ -7,7 +7,6 @@ class PerPartitionRecordFilter(RecordFilter): - """ Prepares per partition stream state to be used in the Record Filter condition. Gets current stream state cursor value for stream slice and passes it to condition. diff --git a/airbyte-integrations/connectors/source-tiktok-marketing/source_tiktok_marketing/components/transformations.py b/airbyte-integrations/connectors/source-tiktok-marketing/source_tiktok_marketing/components/transformations.py index 0b6883e6d13d..ece17f12fc70 100644 --- a/airbyte-integrations/connectors/source-tiktok-marketing/source_tiktok_marketing/components/transformations.py +++ b/airbyte-integrations/connectors/source-tiktok-marketing/source_tiktok_marketing/components/transformations.py @@ -18,7 +18,6 @@ def transform( stream_state: Optional[StreamState] = None, stream_slice: Optional[StreamSlice] = None, ) -> Mapping[str, Any]: - for metric_key, metric_value in record.get("metrics", {}).items(): if metric_value == self.empty_value: record["metrics"][metric_key] = None diff --git a/airbyte-integrations/connectors/source-tiktok-marketing/source_tiktok_marketing/source.py b/airbyte-integrations/connectors/source-tiktok-marketing/source_tiktok_marketing/source.py index 8d0b1f1afcc2..6d2655f5ccfb 100644 --- a/airbyte-integrations/connectors/source-tiktok-marketing/source_tiktok_marketing/source.py +++ b/airbyte-integrations/connectors/source-tiktok-marketing/source_tiktok_marketing/source.py @@ -7,6 +7,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource from airbyte_cdk.sources.streams import Stream + logger = logging.getLogger("airbyte") DOCUMENTATION_URL = "https://docs.airbyte.com/integrations/sources/tiktok-marketing" SANDBOX_STREAM_NAMES = [ diff --git a/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/advetiser_slices.py b/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/advetiser_slices.py index 9a0abf1bc253..dba9ba324d68 100644 --- a/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/advetiser_slices.py +++ b/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/advetiser_slices.py @@ -5,6 +5,7 @@ from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse from airbyte_cdk.test.mock_http.response_builder import find_template + ADVERTISERS_FILE = "advertisers" diff --git a/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/config_builder.py b/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/config_builder.py index 5c32c0b9ea7d..c01481cb119e 100644 --- a/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/config_builder.py +++ b/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/config_builder.py @@ -7,14 +7,9 @@ class ConfigBuilder: def __init__(self) -> None: self._config: Dict[str, Any] = { - "credentials": { - "auth_type": "oauth2.0", - "access_token": "access token", - "app_id": "11111111111111111111", - "secret": "secret" - }, + "credentials": {"auth_type": "oauth2.0", "access_token": "access token", "app_id": "11111111111111111111", "secret": "secret"}, "start_date": "2024-01-01", - "include_deleted": False + "include_deleted": False, } def with_include_deleted(self) -> "ConfigBuilder": diff --git a/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/test_creative_assets_music.py b/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/test_creative_assets_music.py index f3f40d4f3e6e..501f144efcc7 100644 --- a/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/test_creative_assets_music.py +++ b/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/test_creative_assets_music.py @@ -4,13 +4,14 @@ from unittest import TestCase from advetiser_slices import mock_advertisers_slices +from config_builder import ConfigBuilder +from source_tiktok_marketing import SourceTiktokMarketing + from airbyte_cdk.models import SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import read from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse from airbyte_cdk.test.mock_http.response_builder import find_template -from config_builder import ConfigBuilder -from source_tiktok_marketing import SourceTiktokMarketing class TestCreativeAssetsMusic(TestCase): diff --git a/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/test_creative_assets_portfolios.py b/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/test_creative_assets_portfolios.py index 19a875a648ef..10dd031fecf4 100644 --- a/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/test_creative_assets_portfolios.py +++ b/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/test_creative_assets_portfolios.py @@ -4,13 +4,14 @@ from unittest import TestCase from advetiser_slices import mock_advertisers_slices +from config_builder import ConfigBuilder +from source_tiktok_marketing import SourceTiktokMarketing + from airbyte_cdk.models import SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import read from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse from airbyte_cdk.test.mock_http.response_builder import find_template -from config_builder import ConfigBuilder -from source_tiktok_marketing import SourceTiktokMarketing class TestCreativeAssetsPortfolios(TestCase): diff --git a/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/test_reports_hourly.py b/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/test_reports_hourly.py index b0a8f102ce3d..0f72549ef59c 100644 --- a/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/test_reports_hourly.py +++ b/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/integration/test_reports_hourly.py @@ -4,14 +4,16 @@ from unittest import TestCase from advetiser_slices import mock_advertisers_slices +from config_builder import ConfigBuilder +from source_tiktok_marketing import SourceTiktokMarketing + from airbyte_cdk.models import SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import read from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse from airbyte_cdk.test.mock_http.response_builder import find_template from airbyte_cdk.test.state_builder import StateBuilder -from config_builder import ConfigBuilder -from source_tiktok_marketing import SourceTiktokMarketing + EMPTY_LIST_RESPONSE = {"code": 0, "message": "ok", "data": {"list": []}} @@ -88,10 +90,11 @@ class TestAdsReportHourly(TestCase): "real_time_app_install_cost", "app_install", ] + def catalog(self, sync_mode: SyncMode = SyncMode.full_refresh): return CatalogBuilder().with_stream(name=self.stream_name, sync_mode=sync_mode).build() - def config(self, include_deleted:bool=False): + def config(self, include_deleted: bool = False): config_to_build = ConfigBuilder().with_end_date("2024-01-02") if include_deleted: config_to_build = config_to_build.with_include_deleted() @@ -113,16 +116,16 @@ def state(self): def mock_response(self, http_mocker: HttpMocker, include_deleted=False): query_params = { - "service_type": "AUCTION", - "report_type": "BASIC", - "data_level": "AUCTION_AD", - "dimensions": '["ad_id", "stat_time_hour"]', - "metrics": str(self.metrics).replace("'", '"'), - "start_date": self.config()["start_date"], - "end_date": self.config()["start_date"], - "page_size": 1000, - "advertiser_id": self.advertiser_id, - } + "service_type": "AUCTION", + "report_type": "BASIC", + "data_level": "AUCTION_AD", + "dimensions": '["ad_id", "stat_time_hour"]', + "metrics": str(self.metrics).replace("'", '"'), + "start_date": self.config()["start_date"], + "end_date": self.config()["start_date"], + "page_size": 1000, + "advertiser_id": self.advertiser_id, + } if include_deleted: query_params["filtering"] = '[{"field_name": "ad_status", "filter_type": "IN", "filter_value": "[\\"STATUS_ALL\\"]"}]' http_mocker.get( @@ -132,7 +135,7 @@ def mock_response(self, http_mocker: HttpMocker, include_deleted=False): ), HttpResponse(body=json.dumps(find_template(self.stream_name, __file__)), status_code=200), ) - query_params["start_date"] = query_params["end_date"] = self.config()["end_date"] + query_params["start_date"] = query_params["end_date"] = self.config()["end_date"] http_mocker.get( HttpRequest( @@ -239,7 +242,7 @@ class TestAdGroupsReportsHourly(TestCase): def catalog(self, sync_mode: SyncMode = SyncMode.full_refresh): return CatalogBuilder().with_stream(name=self.stream_name, sync_mode=sync_mode).build() - def config(self, include_deleted:bool=False): + def config(self, include_deleted: bool = False): config_to_build = ConfigBuilder().with_end_date("2024-01-02") if include_deleted: config_to_build = config_to_build.with_include_deleted() @@ -263,16 +266,16 @@ def state(self): def test_basic_read(self, http_mocker: HttpMocker): mock_advertisers_slices(http_mocker, self.config()) query_params = { - "service_type": "AUCTION", - "report_type": "BASIC", - "data_level": "AUCTION_ADGROUP", - "dimensions": '["adgroup_id", "stat_time_hour"]', - "metrics": str(self.metrics).replace("'", '"'), - "start_date": self.config()["start_date"], - "end_date": self.config()["start_date"], - "page_size": 1000, - "advertiser_id": self.advertiser_id, - } + "service_type": "AUCTION", + "report_type": "BASIC", + "data_level": "AUCTION_ADGROUP", + "dimensions": '["adgroup_id", "stat_time_hour"]', + "metrics": str(self.metrics).replace("'", '"'), + "start_date": self.config()["start_date"], + "end_date": self.config()["start_date"], + "page_size": 1000, + "advertiser_id": self.advertiser_id, + } http_mocker.get( HttpRequest( url=f"https://business-api.tiktok.com/open_api/v1.3/report/integrated/get/", @@ -348,17 +351,17 @@ def test_read_with_include_deleted(self, http_mocker: HttpMocker): mock_advertisers_slices(http_mocker, self.config()) filtering = '[{"field_name": "adgroup_status", "filter_type": "IN", "filter_value": "[\\"STATUS_ALL\\"]"}]' query_params = { - "service_type": "AUCTION", - "report_type": "BASIC", - "data_level": "AUCTION_ADGROUP", - "dimensions": '["adgroup_id", "stat_time_hour"]', - "metrics": str(self.metrics).replace("'", '"'), - "start_date": self.config()["start_date"], - "end_date": self.config()["start_date"], - "page_size": 1000, - "advertiser_id": self.advertiser_id, - "filtering": filtering, - } + "service_type": "AUCTION", + "report_type": "BASIC", + "data_level": "AUCTION_ADGROUP", + "dimensions": '["adgroup_id", "stat_time_hour"]', + "metrics": str(self.metrics).replace("'", '"'), + "start_date": self.config()["start_date"], + "end_date": self.config()["start_date"], + "page_size": 1000, + "advertiser_id": self.advertiser_id, + "filtering": filtering, + } http_mocker.get( HttpRequest( url=f"https://business-api.tiktok.com/open_api/v1.3/report/integrated/get/", @@ -380,6 +383,7 @@ def test_read_with_include_deleted(self, http_mocker: HttpMocker): assert output.records[0].record.data.get("adgroup_id") is not None assert output.records[0].record.data.get("stat_time_hour") is not None + class TestAdvertisersReportsHourly(TestCase): stream_name = "advertisers_reports_hourly" advertiser_id = "872746382648" @@ -536,7 +540,7 @@ class TestCampaignsReportsHourly(TestCase): def catalog(self, sync_mode: SyncMode = SyncMode.full_refresh): return CatalogBuilder().with_stream(name=self.stream_name, sync_mode=sync_mode).build() - def config(self, include_deleted:bool=False): + def config(self, include_deleted: bool = False): config_to_build = ConfigBuilder().with_end_date("2024-01-02") if include_deleted: config_to_build = config_to_build.with_include_deleted() @@ -556,18 +560,18 @@ def state(self): .build() ) - def mock_response(self, http_mocker: HttpMocker, include_deleted:bool=False): + def mock_response(self, http_mocker: HttpMocker, include_deleted: bool = False): query_params = { - "service_type": "AUCTION", - "report_type": "BASIC", - "data_level": "AUCTION_CAMPAIGN", - "dimensions": '["campaign_id", "stat_time_hour"]', - "metrics": str(self.metrics).replace("'", '"'), - "start_date": self.config()["start_date"], - "end_date": self.config()["start_date"], - "page_size": 1000, - "advertiser_id": self.advertiser_id, - } + "service_type": "AUCTION", + "report_type": "BASIC", + "data_level": "AUCTION_CAMPAIGN", + "dimensions": '["campaign_id", "stat_time_hour"]', + "metrics": str(self.metrics).replace("'", '"'), + "start_date": self.config()["start_date"], + "end_date": self.config()["start_date"], + "page_size": 1000, + "advertiser_id": self.advertiser_id, + } if include_deleted: query_params["filtering"] = '[{"field_name": "campaign_status", "filter_type": "IN", "filter_value": "[\\"STATUS_ALL\\"]"}]' http_mocker.get( diff --git a/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/test_components.py b/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/test_components.py index 1825fa49d955..ce1e6432c576 100644 --- a/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/test_components.py +++ b/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/test_components.py @@ -3,9 +3,6 @@ from unittest.mock import MagicMock import pytest -from airbyte_cdk.sources.declarative.datetime.min_max_datetime import MinMaxDatetime -from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig -from airbyte_cdk.sources.declarative.types import StreamSlice from source_tiktok_marketing import SourceTiktokMarketing from source_tiktok_marketing.components.advertiser_ids_partition_router import ( MultipleAdvertiserIdsPerPartition, @@ -15,13 +12,17 @@ from source_tiktok_marketing.components.semi_incremental_record_filter import PerPartitionRecordFilter from source_tiktok_marketing.components.transformations import TransformEmptyMetrics +from airbyte_cdk.sources.declarative.datetime.min_max_datetime import MinMaxDatetime +from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig +from airbyte_cdk.sources.declarative.types import StreamSlice + @pytest.mark.parametrize( "config, expected", [ ({"credentials": {"advertiser_id": "11111111111"}}, "11111111111"), ({"environment": {"advertiser_id": "2222222222"}}, "2222222222"), - ({"credentials": {"access_token": "access_token"}}, None) + ({"credentials": {"access_token": "access_token"}}, None), ], ) def test_get_partition_value_from_config(config, expected): @@ -29,8 +30,9 @@ def test_get_partition_value_from_config(config, expected): parent_stream_configs=[MagicMock()], config=config, parameters={ - "path_in_config": [["credentials", "advertiser_id"], ["environment", "advertiser_id"]], "partition_field": "advertiser_id" - } + "path_in_config": [["credentials", "advertiser_id"], ["environment", "advertiser_id"]], + "partition_field": "advertiser_id", + }, ) actual = router.get_partition_value_from_config() assert actual == expected @@ -39,17 +41,26 @@ def test_get_partition_value_from_config(config, expected): @pytest.mark.parametrize( "config, expected, json_data", [ - ({"credentials": {"auth_type": "oauth2.0", "advertiser_id": "11111111111"}}, - [{"advertiser_ids": '["11111111111"]', "parent_slice": {}}], None), + ( + {"credentials": {"auth_type": "oauth2.0", "advertiser_id": "11111111111"}}, + [{"advertiser_ids": '["11111111111"]', "parent_slice": {}}], + None, + ), ({"environment": {"advertiser_id": "2222222222"}}, [{"advertiser_ids": '["2222222222"]', "parent_slice": {}}], None), ( - {"credentials": {"auth_type": "oauth2.0", "access_token": "access_token"}}, - [{"advertiser_ids": '["11111111", "22222222"]', "parent_slice": {}}], - {"code": 0, "message": "ok", "data": - {"list": [{"advertiser_id": "11111111", "advertiser_name": "name"}, - {"advertiser_id": "22222222", "advertiser_name": "name"}]} - } - ) + {"credentials": {"auth_type": "oauth2.0", "access_token": "access_token"}}, + [{"advertiser_ids": '["11111111", "22222222"]', "parent_slice": {}}], + { + "code": 0, + "message": "ok", + "data": { + "list": [ + {"advertiser_id": "11111111", "advertiser_name": "name"}, + {"advertiser_id": "22222222", "advertiser_name": "name"}, + ] + }, + }, + ), ], ) def test_stream_slices_multiple(config, expected, requests_mock, json_data): @@ -57,23 +68,19 @@ def test_stream_slices_multiple(config, expected, requests_mock, json_data): advertiser_ids_stream = advertiser_ids_stream[0] if advertiser_ids_stream else MagicMock() router = MultipleAdvertiserIdsPerPartition( - parent_stream_configs=[ParentStreamConfig( - partition_field="advertiser_ids", - config=config, - parent_key="advertiser_id", - stream=advertiser_ids_stream, - parameters={} - )], + parent_stream_configs=[ + ParentStreamConfig( + partition_field="advertiser_ids", config=config, parent_key="advertiser_id", stream=advertiser_ids_stream, parameters={} + ) + ], config=config, parameters={ - "path_in_config": [["credentials", "advertiser_id"], ["environment", "advertiser_id"]], "partition_field": "advertiser_ids" - } + "path_in_config": [["credentials", "advertiser_id"], ["environment", "advertiser_id"]], + "partition_field": "advertiser_ids", + }, ) if json_data: - requests_mock.get( - "https://business-api.tiktok.com/open_api/v1.3/oauth2/advertiser/get/", - json=json_data - ) + requests_mock.get("https://business-api.tiktok.com/open_api/v1.3/oauth2/advertiser/get/", json=json_data) actual = list(router.stream_slices()) assert actual == expected @@ -81,19 +88,26 @@ def test_stream_slices_multiple(config, expected, requests_mock, json_data): @pytest.mark.parametrize( "config, expected, json_data", [ - ({"credentials": {"auth_type": "oauth2.0", "advertiser_id": "11111111111"}}, [{"advertiser_id": "11111111111", "parent_slice": {}}], - None), + ( + {"credentials": {"auth_type": "oauth2.0", "advertiser_id": "11111111111"}}, + [{"advertiser_id": "11111111111", "parent_slice": {}}], + None, + ), ({"environment": {"advertiser_id": "2222222222"}}, [{"advertiser_id": "2222222222", "parent_slice": {}}], None), ( - {"credentials": {"auth_type": "oauth2.0", "access_token": "access_token"}}, - [{"advertiser_id": "11111111", "parent_slice": {}}, - {"advertiser_id": "22222222", "parent_slice": {}}], - {"code": 0, "message": "ok", - "data": {"list": [ - {"advertiser_id": "11111111", "advertiser_name": "name"}, - {"advertiser_id": "22222222", "advertiser_name": "name"}]} - } - ) + {"credentials": {"auth_type": "oauth2.0", "access_token": "access_token"}}, + [{"advertiser_id": "11111111", "parent_slice": {}}, {"advertiser_id": "22222222", "parent_slice": {}}], + { + "code": 0, + "message": "ok", + "data": { + "list": [ + {"advertiser_id": "11111111", "advertiser_name": "name"}, + {"advertiser_id": "22222222", "advertiser_name": "name"}, + ] + }, + }, + ), ], ) def test_stream_slices_single(config, expected, requests_mock, json_data): @@ -101,23 +115,19 @@ def test_stream_slices_single(config, expected, requests_mock, json_data): advertiser_ids_stream = advertiser_ids_stream[0] if advertiser_ids_stream else MagicMock() router = SingleAdvertiserIdPerPartition( - parent_stream_configs=[ParentStreamConfig( - partition_field="advertiser_id", - config=config, - parent_key="advertiser_id", - stream=advertiser_ids_stream, - parameters={} - )], + parent_stream_configs=[ + ParentStreamConfig( + partition_field="advertiser_id", config=config, parent_key="advertiser_id", stream=advertiser_ids_stream, parameters={} + ) + ], config=config, parameters={ - "path_in_config": [["credentials", "advertiser_id"], ["environment", "advertiser_id"]], "partition_field": "advertiser_id" - } + "path_in_config": [["credentials", "advertiser_id"], ["environment", "advertiser_id"]], + "partition_field": "advertiser_id", + }, ) if json_data: - requests_mock.get( - "https://business-api.tiktok.com/open_api/v1.3/oauth2/advertiser/get/", - json=json_data - ) + requests_mock.get("https://business-api.tiktok.com/open_api/v1.3/oauth2/advertiser/get/", json=json_data) actual = list(router.stream_slices()) assert actual == expected @@ -126,22 +136,22 @@ def test_stream_slices_single(config, expected, requests_mock, json_data): "records, state, slice, expected", [ ( - [{"id": 1, "start_time": "2024-01-01"}, {"id": 2, "start_time": "2024-01-01"}], - {}, - {}, - [{"id": 1, "start_time": "2024-01-01"}, {"id": 2, "start_time": "2024-01-01"}] + [{"id": 1, "start_time": "2024-01-01"}, {"id": 2, "start_time": "2024-01-01"}], + {}, + {}, + [{"id": 1, "start_time": "2024-01-01"}, {"id": 2, "start_time": "2024-01-01"}], ), ( - [{"advertiser_id": 1, "start_time": "2022-01-01"}, {"advertiser_id": 1, "start_time": "2024-01-02"}], - {"states": [{"partition": {"advertiser_id": 1, "parent_slice": {}}, "cursor": {"start_time": "2023-12-31"}}]}, - {"advertiser_id": 1}, - [{"advertiser_id": 1, "start_time": "2024-01-02"}] + [{"advertiser_id": 1, "start_time": "2022-01-01"}, {"advertiser_id": 1, "start_time": "2024-01-02"}], + {"states": [{"partition": {"advertiser_id": 1, "parent_slice": {}}, "cursor": {"start_time": "2023-12-31"}}]}, + {"advertiser_id": 1}, + [{"advertiser_id": 1, "start_time": "2024-01-02"}], ), ( - [{"advertiser_id": 2, "start_time": "2022-01-01"}, {"advertiser_id": 2, "start_time": "2024-01-02"}], - {"states": [{"partition": {"advertiser_id": 1, "parent_slice": {}}, "cursor": {"start_time": "2023-12-31"}}]}, - {"advertiser_id": 2}, - [{"advertiser_id": 2, "start_time": "2022-01-01"}, {"advertiser_id": 2, "start_time": "2024-01-02"}], + [{"advertiser_id": 2, "start_time": "2022-01-01"}, {"advertiser_id": 2, "start_time": "2024-01-02"}], + {"states": [{"partition": {"advertiser_id": 1, "parent_slice": {}}, "cursor": {"start_time": "2023-12-31"}}]}, + {"advertiser_id": 2}, + [{"advertiser_id": 2, "start_time": "2022-01-01"}, {"advertiser_id": 2, "start_time": "2024-01-02"}], ), ], ) @@ -150,18 +160,20 @@ def test_record_filter(records, state, slice, expected): record_filter = PerPartitionRecordFilter( config=config, parameters={"partition_field": "advertiser_id"}, - condition="{{ record['start_time'] >= stream_state.get('start_time', config.get('start_date', '')) }}" + condition="{{ record['start_time'] >= stream_state.get('start_time', config.get('start_date', '')) }}", + ) + filtered_records = list( + record_filter.filter_records(records=records, stream_state=state, stream_slice=StreamSlice(partition=slice, cursor_slice={})) ) - filtered_records = list(record_filter.filter_records( - records=records, - stream_state=state, - stream_slice=StreamSlice(partition=slice, cursor_slice={}) - )) assert filtered_records == expected def test_hourly_datetime_based_cursor(): - config = {"credentials": {"auth_type": "oauth2.0", "advertiser_id": "11111111111"}, "start_date": "2022-01-01", "end_date": "2022-01-02"} + config = { + "credentials": {"auth_type": "oauth2.0", "advertiser_id": "11111111111"}, + "start_date": "2022-01-01", + "end_date": "2022-01-02", + } cursor = HourlyDatetimeBasedCursor( start_datetime=MinMaxDatetime(datetime="{{ config.get('start_date', '2016-09-01') }}", datetime_format="%Y-%m-%d", parameters={}), @@ -172,42 +184,33 @@ def test_hourly_datetime_based_cursor(): cursor_field="stat_time_hour", datetime_format="%Y-%m-%d", cursor_datetime_formats=["%Y-%m-%d %H:%M:%S", "%Y-%m-%dT%H:%M:%SZ"], - parameters={} + parameters={}, ) cursor._cursor = "2022-01-01 00:00:00" partition_daterange = list(cursor.stream_slices()) assert partition_daterange == [ {"start_time": "2022-01-01", "end_time": "2022-01-01"}, - {"start_time": "2022-01-02", "end_time": "2022-01-02"} + {"start_time": "2022-01-02", "end_time": "2022-01-02"}, ] cursor._cursor = "2022-01-01 10:00:00" partition_daterange = list(cursor.stream_slices()) assert partition_daterange == [ {"start_time": "2022-01-01", "end_time": "2022-01-01"}, - {"start_time": "2022-01-02", "end_time": "2022-01-02"} + {"start_time": "2022-01-02", "end_time": "2022-01-02"}, ] @pytest.mark.parametrize( "record, expected", [ + ({"metrics": {"metric_1": "not empty", "metric_2": "-"}}, {"metrics": {"metric_1": "not empty", "metric_2": None}}), + ({"metrics": {"metric_1": "not empty", "metric_2": "not empty"}}, {"metrics": {"metric_1": "not empty", "metric_2": "not empty"}}), ( - {"metrics": {"metric_1": "not empty", "metric_2": "-"}}, - {"metrics": {"metric_1": "not empty", "metric_2": None}} - ), - ( - {"metrics": {"metric_1": "not empty", "metric_2": "not empty"}}, - {"metrics": {"metric_1": "not empty", "metric_2": "not empty"}} - ), - ( - {"dimensions": {"dimension_1": "not empty", "dimension_2": "not empty"}}, - {"dimensions": {"dimension_1": "not empty", "dimension_2": "not empty"}} - ), - ( - {}, - {} + {"dimensions": {"dimension_1": "not empty", "dimension_2": "not empty"}}, + {"dimensions": {"dimension_1": "not empty", "dimension_2": "not empty"}}, ), + ({}, {}), ], ) def test_transform_empty_metrics(record, expected): diff --git a/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/test_source.py b/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/test_source.py index 44db480d1000..f04efc33e7c1 100644 --- a/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-tiktok-marketing/unit_tests/test_source.py @@ -6,17 +6,34 @@ from unittest.mock import MagicMock import pytest -from airbyte_cdk.models import ConnectorSpecification from source_tiktok_marketing import SourceTiktokMarketing +from airbyte_cdk.models import ConnectorSpecification + @pytest.mark.parametrize( "config, stream_len", [ ({"access_token": "token", "environment": {"app_id": "1111", "secret": "secret"}, "start_date": "2021-04-01"}, 36), ({"access_token": "token", "start_date": "2021-01-01", "environment": {"advertiser_id": "1111"}}, 28), - ({"access_token": "token", "environment": {"app_id": "1111", "secret": "secret"}, "start_date": "2021-04-01", "report_granularity": "LIFETIME"}, 15), - ({"access_token": "token", "environment": {"app_id": "1111", "secret": "secret"}, "start_date": "2021-04-01", "report_granularity": "DAY"}, 27), + ( + { + "access_token": "token", + "environment": {"app_id": "1111", "secret": "secret"}, + "start_date": "2021-04-01", + "report_granularity": "LIFETIME", + }, + 15, + ), + ( + { + "access_token": "token", + "environment": {"app_id": "1111", "secret": "secret"}, + "start_date": "2021-04-01", + "report_granularity": "DAY", + }, + 27, + ), ], ) def test_source_streams(config, stream_len): @@ -43,11 +60,27 @@ def config_fixture(): def test_source_check_connection_ok(config, requests_mock): requests_mock.get( "https://business-api.tiktok.com/open_api/v1.3/oauth2/advertiser/get/", - json={"code": 0, "message": "ok", "data": {"list": [{"advertiser_id": "917429327", "advertiser_name": "name"}, ]}} + json={ + "code": 0, + "message": "ok", + "data": { + "list": [ + {"advertiser_id": "917429327", "advertiser_name": "name"}, + ] + }, + }, ) requests_mock.get( "https://business-api.tiktok.com/open_api/v1.3/advertiser/info/?page_size=100&advertiser_ids=%5B%22917429327%22%5D", - json={"code": 0, "message": "ok", "data": {"list": [{"advertiser_id": "917429327", "advertiser_name": "name"}, ]}} + json={ + "code": 0, + "message": "ok", + "data": { + "list": [ + {"advertiser_id": "917429327", "advertiser_name": "name"}, + ] + }, + }, ) logger_mock = MagicMock() assert SourceTiktokMarketing().check_connection(logger_mock, config) == (True, None) @@ -56,20 +89,17 @@ def test_source_check_connection_ok(config, requests_mock): @pytest.mark.parametrize( "json_response, expected_result, expected_message", [ - ({"code": 40105, "message": "Access token is incorrect or has been revoked."}, - (False, "Access token is incorrect or has been revoked."), - None), - ({"code": 40100, "message": "App reaches the QPS limit."}, - None, - 38) - ] + ( + {"code": 40105, "message": "Access token is incorrect or has been revoked."}, + (False, "Access token is incorrect or has been revoked."), + None, + ), + ({"code": 40100, "message": "App reaches the QPS limit."}, None, 38), + ], ) @pytest.mark.usefixtures("mock_sleep") def test_source_check_connection_failed(config, requests_mock, capsys, json_response, expected_result, expected_message): - requests_mock.get( - "https://business-api.tiktok.com/open_api/v1.3/oauth2/advertiser/get/", - json=json_response - ) + requests_mock.get("https://business-api.tiktok.com/open_api/v1.3/oauth2/advertiser/get/", json=json_response) logger_mock = MagicMock() result = SourceTiktokMarketing().check_connection(logger_mock, config) diff --git a/airbyte-integrations/connectors/source-timely/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-timely/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-timely/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-timely/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-timely/metadata.yaml b/airbyte-integrations/connectors/source-timely/metadata.yaml index 945e33ef4f46..7795e0f48ede 100644 --- a/airbyte-integrations/connectors/source-timely/metadata.yaml +++ b/airbyte-integrations/connectors/source-timely/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - api.timelyapp.com connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: bc617b5f-1b9e-4a2d-bebe-782fd454a771 - dockerImageTag: 0.4.3 + dockerImageTag: 0.4.8 dockerRepository: airbyte/source-timely documentationUrl: https://docs.airbyte.com/integrations/sources/timely githubIssueLabel: source-timely diff --git a/airbyte-integrations/connectors/source-tinyemail/README.md b/airbyte-integrations/connectors/source-tinyemail/README.md new file mode 100644 index 000000000000..ade5e7158488 --- /dev/null +++ b/airbyte-integrations/connectors/source-tinyemail/README.md @@ -0,0 +1,35 @@ +# Tinyemail +This directory contains the manifest-only connector for `source-tinyemail`. + +Tinyemail is an email marketing tool. +We can extract data from campaigns and contacts streams using this connector. +Docs : https://docs.tinyemail.com/docs/tiny-email/tinyemail + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-tinyemail:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-tinyemail build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-tinyemail test +``` + diff --git a/airbyte-integrations/connectors/source-tinyemail/acceptance-test-config.yml b/airbyte-integrations/connectors/source-tinyemail/acceptance-test-config.yml new file mode 100644 index 000000000000..75fd03460227 --- /dev/null +++ b/airbyte-integrations/connectors/source-tinyemail/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-tinyemail:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-tinyemail/icon.svg b/airbyte-integrations/connectors/source-tinyemail/icon.svg new file mode 100644 index 000000000000..c76c0b9f65ef --- /dev/null +++ b/airbyte-integrations/connectors/source-tinyemail/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-tinyemail/manifest.yaml b/airbyte-integrations/connectors/source-tinyemail/manifest.yaml new file mode 100644 index 000000000000..a3322bb9215b --- /dev/null +++ b/airbyte-integrations/connectors/source-tinyemail/manifest.yaml @@ -0,0 +1,470 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: |- + Tinyemail is an email marketing tool. + We can extract data from campaigns and contacts streams using this connector. + [API Docs](https://docs.tinyemail.com/docs/tiny-email/tinyemail) + +check: + type: CheckStream + stream_names: + - campaigns + +definitions: + streams: + campaigns: + type: DeclarativeStream + name: campaigns + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: campaign + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - campaigns + - content + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 20 + start_from_page: 0 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/campaigns" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - contacts + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + sender_details: + type: DeclarativeStream + name: sender_details + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: sender-details + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - senderDetailses + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sender_details" + contact_members: + type: DeclarativeStream + name: contact_members + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: contacts/{{ stream_partition.id }}/members + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - members + - content + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: size + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: id + stream: + $ref: "#/definitions/streams/contacts" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contact_members" + base_requester: + type: HttpRequester + url_base: https://api.tinyemail.com/v1/ + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: X-API-KEY + inject_into: header + +streams: + - $ref: "#/definitions/streams/campaigns" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/sender_details" + - $ref: "#/definitions/streams/contact_members" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + properties: + api_key: + type: string + order: 0 + title: API Key + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + campaigns: true + contacts: true + sender_details: true + contact_members: true + testedStreams: + campaigns: + hasRecords: true + streamHash: 87f4bfbafbdd839a4aa610151245f01bea2cdacb + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + contacts: + hasRecords: true + streamHash: abece08aa245b26686fd883cc3320886c9e78990 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + sender_details: + streamHash: ed2c5285bbe1dc8db23db6e1d0cf87827099194e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contact_members: + streamHash: 3a6a387655eeeacce156e1e7f59f4df17b28a1d9 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: {} + +schemas: + campaigns: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + bounced: + type: + - number + - "null" + bouncedProgress: + type: + - number + - "null" + campaign: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + previewText: + type: + - string + - "null" + subject: + type: + - string + - "null" + clicked: + type: + - number + - "null" + clickedProgress: + type: + - number + - "null" + contactIds: + type: + - array + - "null" + items: + type: + - string + - "null" + delivered: + type: + - number + - "null" + deliveredProgress: + type: + - number + - "null" + id: + type: string + open: + type: + - number + - "null" + openProgress: + type: + - number + - "null" + requests: + type: + - number + - "null" + schedule: + type: + - object + - "null" + properties: + dateTime: + type: + - string + - "null" + senderId: + type: + - string + - "null" + sent: + type: + - number + - "null" + spam: + type: + - number + - "null" + spamProgress: + type: + - number + - "null" + status: + type: + - string + - "null" + template: + type: + - object + - "null" + properties: + html: + type: + - string + - "null" + totalClicked: + type: + - number + - "null" + totalClickedProgress: + type: + - number + - "null" + totalOpen: + type: + - number + - "null" + totalOpenProgress: + type: + - number + - "null" + unsubscribed: + type: + - number + - "null" + unsubscribedProgress: + type: + - number + - "null" + required: + - id + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: string + name: + type: + - string + - "null" + numberOfMembers: + type: + - number + - "null" + required: + - id + sender_details: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + defaults: + type: + - boolean + - "null" + dkimSigned: + type: + - boolean + - "null" + email: + type: + - string + - "null" + emailConfirmed: + type: + - boolean + - "null" + id: + type: string + name: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + region: + type: + - string + - "null" + required: + - id + contact_members: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address1: + type: + - string + - "null" + address2: + type: + - string + - "null" + birthday: + type: + - string + - "null" + city: + type: + - string + - "null" + company: + type: + - string + - "null" + country: + type: + - string + - "null" + currency: + type: + - string + - "null" + email: + type: + - string + - "null" + firstName: + type: + - string + - "null" + lastName: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + province: + type: + - string + - "null" + source: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - string + - "null" diff --git a/airbyte-integrations/connectors/source-tinyemail/metadata.yaml b/airbyte-integrations/connectors/source-tinyemail/metadata.yaml new file mode 100644 index 000000000000..33f426c336d3 --- /dev/null +++ b/airbyte-integrations/connectors/source-tinyemail/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.tinyemail.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-tinyemail + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 30ccdb61-445d-480b-8b76-8f09348f8bb9 + dockerImageTag: 0.0.5 + dockerRepository: airbyte/source-tinyemail + githubIssueLabel: source-tinyemail + icon: icon.svg + license: MIT + name: Tinyemail + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/tinyemail + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-tmdb/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-tmdb/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-tmdb/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-tmdb/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-tmdb/metadata.yaml b/airbyte-integrations/connectors/source-tmdb/metadata.yaml index f3757da7bd85..231d6354e9dd 100644 --- a/airbyte-integrations/connectors/source-tmdb/metadata.yaml +++ b/airbyte-integrations/connectors/source-tmdb/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 6240848f-f795-45eb-8f5e-c7542822fc03 - dockerImageTag: 1.1.2 + dockerImageTag: 1.1.6 dockerRepository: airbyte/source-tmdb githubIssueLabel: source-tmdb icon: tmdb.svg @@ -42,5 +42,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-todoist/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-todoist/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-todoist/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-todoist/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-todoist/metadata.yaml b/airbyte-integrations/connectors/source-todoist/metadata.yaml index 9dbebfb75c96..8913e6546750 100644 --- a/airbyte-integrations/connectors/source-todoist/metadata.yaml +++ b/airbyte-integrations/connectors/source-todoist/metadata.yaml @@ -15,11 +15,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 1a3d38e4-dc6b-4154-b56b-582f9e978ecd - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.5 dockerRepository: airbyte/source-todoist githubIssueLabel: source-todoist icon: todoist.svg diff --git a/airbyte-integrations/connectors/source-toggl/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-toggl/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-toggl/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-toggl/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-toggl/metadata.yaml b/airbyte-integrations/connectors/source-toggl/metadata.yaml index bfab2051adce..ed196686102b 100644 --- a/airbyte-integrations/connectors/source-toggl/metadata.yaml +++ b/airbyte-integrations/connectors/source-toggl/metadata.yaml @@ -11,7 +11,7 @@ data: connectorSubtype: api connectorType: source definitionId: 7e7c844f-2300-4342-b7d3-6dd7992593cd - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-toggl githubIssueLabel: source-toggl icon: toggl.svg @@ -40,5 +40,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-tplcentral/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-tplcentral/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-tplcentral/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-tplcentral/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-tplcentral/main.py b/airbyte-integrations/connectors/source-tplcentral/main.py index c5e7b8a95ec4..fb91c7bd8e63 100644 --- a/airbyte-integrations/connectors/source-tplcentral/main.py +++ b/airbyte-integrations/connectors/source-tplcentral/main.py @@ -4,5 +4,6 @@ from source_tplcentral.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-tplcentral/metadata.yaml b/airbyte-integrations/connectors/source-tplcentral/metadata.yaml index 78b7bc32602b..8b3db92cfeb8 100644 --- a/airbyte-integrations/connectors/source-tplcentral/metadata.yaml +++ b/airbyte-integrations/connectors/source-tplcentral/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: f9b6c538-ee12-42fe-8d4b-0c10f5955417 - dockerImageTag: 0.1.25 + dockerImageTag: 0.1.30 dockerRepository: airbyte/source-tplcentral githubIssueLabel: source-tplcentral icon: tplcentral.svg @@ -29,5 +29,5 @@ data: connectorTestSuitesOptions: - suite: unitTests connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-tplcentral/poetry.lock b/airbyte-integrations/connectors/source-tplcentral/poetry.lock index 8d0245990452..ec22c8cf73e4 100644 --- a/airbyte-integrations/connectors/source-tplcentral/poetry.lock +++ b/airbyte-integrations/connectors/source-tplcentral/poetry.lock @@ -76,19 +76,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -154,127 +154,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -290,20 +277,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -381,13 +368,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -500,13 +487,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -587,54 +574,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -898,33 +885,33 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -965,13 +952,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -996,81 +983,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-tplcentral/pyproject.toml b/airbyte-integrations/connectors/source-tplcentral/pyproject.toml index 556fd2b225a8..a5b1a8e309b1 100644 --- a/airbyte-integrations/connectors/source-tplcentral/pyproject.toml +++ b/airbyte-integrations/connectors/source-tplcentral/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.25" +version = "0.1.30" name = "source-tplcentral" description = "Source implementation for Tplcentral." authors = [ "Labanoras Tech ",] diff --git a/airbyte-integrations/connectors/source-tplcentral/source_tplcentral/source.py b/airbyte-integrations/connectors/source-tplcentral/source_tplcentral/source.py index a20a1c20c81d..40bd46bfe85f 100644 --- a/airbyte-integrations/connectors/source-tplcentral/source_tplcentral/source.py +++ b/airbyte-integrations/connectors/source-tplcentral/source_tplcentral/source.py @@ -7,10 +7,11 @@ from typing import Any, List, Mapping, MutableMapping, Tuple import requests +from requests.auth import HTTPBasicAuth + from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http.requests_native_auth import Oauth2Authenticator -from requests.auth import HTTPBasicAuth from source_tplcentral.streams import Customers, Inventory, Items, Orders, StockDetails, StockSummaries diff --git a/airbyte-integrations/connectors/source-tplcentral/source_tplcentral/streams.py b/airbyte-integrations/connectors/source-tplcentral/source_tplcentral/streams.py index 97e696a6da7f..15a328c51c51 100644 --- a/airbyte-integrations/connectors/source-tplcentral/source_tplcentral/streams.py +++ b/airbyte-integrations/connectors/source-tplcentral/source_tplcentral/streams.py @@ -8,6 +8,7 @@ import arrow import requests + from airbyte_cdk.sources.streams.http import HttpStream from source_tplcentral.util import deep_get, normalize diff --git a/airbyte-integrations/connectors/source-tplcentral/unit_tests/test_incremental_streams.py b/airbyte-integrations/connectors/source-tplcentral/unit_tests/test_incremental_streams.py index b31950e75404..2a116bd8e350 100644 --- a/airbyte-integrations/connectors/source-tplcentral/unit_tests/test_incremental_streams.py +++ b/airbyte-integrations/connectors/source-tplcentral/unit_tests/test_incremental_streams.py @@ -3,9 +3,10 @@ # import pytest -from airbyte_cdk.models import SyncMode from source_tplcentral.streams import IncrementalTplcentralStream +from airbyte_cdk.models import SyncMode + @pytest.fixture def config(): diff --git a/airbyte-integrations/connectors/source-track-pms/README.md b/airbyte-integrations/connectors/source-track-pms/README.md new file mode 100644 index 000000000000..135e9bf3ecd0 --- /dev/null +++ b/airbyte-integrations/connectors/source-track-pms/README.md @@ -0,0 +1,38 @@ +# Track PMS +This directory contains the manifest-only connector for `source-track-pms`. + +An Airbyte source for the Track Property Management System (PMS) +Enterprise-class property management solutions for vacation rental companies + +Website: https://tnsinc.com +API Docs: https://developer.trackhs.com +Authentication Docs: https://developer.trackhs.com/docs/authentication#authentication + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-track-pms:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-track-pms build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-track-pms test +``` + diff --git a/airbyte-integrations/connectors/source-track-pms/acceptance-test-config.yml b/airbyte-integrations/connectors/source-track-pms/acceptance-test-config.yml new file mode 100644 index 000000000000..73670fad6ef1 --- /dev/null +++ b/airbyte-integrations/connectors/source-track-pms/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-track-pms:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-track-pms/icon.svg b/airbyte-integrations/connectors/source-track-pms/icon.svg new file mode 100644 index 000000000000..6938bff3add7 --- /dev/null +++ b/airbyte-integrations/connectors/source-track-pms/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-track-pms/manifest.yaml b/airbyte-integrations/connectors/source-track-pms/manifest.yaml new file mode 100644 index 000000000000..9c0fa6006ea9 --- /dev/null +++ b/airbyte-integrations/connectors/source-track-pms/manifest.yaml @@ -0,0 +1,29224 @@ +version: 5.7.5 + +type: DeclarativeSource + +description: >- + An Airbyte source for the Track Property Management System (PMS) + + Enterprise-class property management solutions for vacation rental companies + + + Website: https://tnsinc.com/ + + API Docs: https://developer.trackhs.com + + Authentication Docs: + https://developer.trackhs.com/docs/authentication#authentication + +check: + type: CheckStream + stream_names: + - units + +definitions: + streams: + units: + type: DeclarativeStream + name: units + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/units + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - units + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + start_datetime: + type: MinMaxDatetime + datetime: "1900-01-01T00:00:00Z" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: contentUpdatedSince + inject_into: request_parameter + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - node + - type: RemoveFields + field_pointers: + - - _embedded + - parent + - type: RemoveFields + field_pointers: + - - _embedded + - type + - type: RemoveFields + field_pointers: + - - _embedded + - lodgingType + - type: RemoveFields + field_pointers: + - - _embedded + - taxDistrict + - type: RemoveFields + field_pointers: + - - _embedded + - localOffice + - type: RemoveFields + field_pointers: + - - _embedded + - travelInsuranceProduct + - type: RemoveFields + field_pointers: + - - _embedded + - cleanStatus + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/units" + owners: + type: DeclarativeStream + name: owners + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/owners + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - owners + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + start_datetime: + type: MinMaxDatetime + datetime: "1900-01-01T00:00:00Z" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: updatedSince + inject_into: request_parameter + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/owners" + fractionals: + type: DeclarativeStream + name: fractionals + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/owners/fractionals + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - fractionalGroups + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - unit + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/fractionals" + unit-blocks: + type: DeclarativeStream + name: unit-blocks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/unit-blocks + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - unitBlocks + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _embedded + - unit + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - reason + - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/unit-blocks" + folios: + type: DeclarativeStream + name: folios + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/folios + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - folios + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - reservation + - type: RemoveFields + field_pointers: + - - _embedded + - account + - type: RemoveFields + field_pointers: + - - _embedded + - contact + - type: RemoveFields + field_pointers: + - - _embedded + - company + - type: RemoveFields + field_pointers: + - - _embedded + - travelAgent + - type: RemoveFields + field_pointers: + - - _embedded + - masterFolio + - type: RemoveFields + field_pointers: + - - _embedded + - masterFolioRule + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/folios" + nodes: + type: DeclarativeStream + name: nodes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/nodes + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - nodes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - parent + - type: RemoveFields + field_pointers: + - - _embedded + - taxDistrict + - type: RemoveFields + field_pointers: + - - _embedded + - localOffice + - type: RemoveFields + field_pointers: + - - _embedded + - type + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/nodes" + units-amenities: + type: DeclarativeStream + name: units-amenities + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/units/amenities + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - amenities + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/units-amenities" + quotes: + type: DeclarativeStream + name: quotes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/pms/quotes + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - quotes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/quotes" + reservations_v2: + type: DeclarativeStream + name: reservations_v2 + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/pms/reservations + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - reservations + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + start_datetime: + type: MinMaxDatetime + datetime: "1900-01-01T00:00:00Z" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: updatedSince + inject_into: request_parameter + transformations: + - type: RemoveFields + field_pointers: + - - _embedded + - unit + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - links + - type: RemoveFields + field_pointers: + - - _embedded + - guaranteePolicy + - type: RemoveFields + field_pointers: + - - _embedded + - contact + - type: RemoveFields + field_pointers: + - - _embedded + - cancellationPolicy + - type: RemoveFields + field_pointers: + - - _embedded + - cancellationReason + - type: RemoveFields + field_pointers: + - - _embedded + - user + - type: RemoveFields + field_pointers: + - - _embedded + - type + - type: RemoveFields + field_pointers: + - - _embedded + - rateType + - type: RemoveFields + field_pointers: + - - _embedded + - cancelledBy + - type: RemoveFields + field_pointers: + - - _embedded + - paymentMethod + - type: RemoveFields + field_pointers: + - - guestBreakdown + - rates + - type: RemoveFields + field_pointers: + - - _embedded + - channel + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/reservations_v2" + reservation-types: + type: DeclarativeStream + name: reservation-types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/reservations/types + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - reservationTypes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/reservation-types" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: crm/contacts + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - contacts + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + start_datetime: + type: MinMaxDatetime + datetime: "1900-01-01T00:00:00Z" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: updatedSince + inject_into: request_parameter + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + tags: + type: DeclarativeStream + name: tags + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: tags + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - tags + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tags" + unit-types: + type: DeclarativeStream + name: unit-types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/units/types + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - unitTypes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - lodgingType + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/unit-types" + lodging-types: + type: DeclarativeStream + name: lodging-types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/units/lodging-types + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - lodgingTypes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - node + - type: RemoveFields + field_pointers: + - - _embedded + - parent + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/lodging-types" + tax-districts: + type: DeclarativeStream + name: tax-districts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/tax-districts + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - taxdistricts + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - shortTermPolicy + - type: RemoveFields + field_pointers: + - - _embedded + - longTermPolicy + - type: RemoveFields + field_pointers: + - - _embedded + - salesTaxPolicy + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tax-districts" + tax-policies: + type: DeclarativeStream + name: tax-policies + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/tax-policies + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - taxpolicies + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - taxes + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tax-policies" + taxes: + type: DeclarativeStream + name: taxes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/taxes + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - taxes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - account + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/taxes" + travel-insurance-products: + type: DeclarativeStream + name: travel-insurance-products + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/reservations/travel-insurance-products + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - travelInsuranceProviders + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/travel-insurance-products" + companies: + type: DeclarativeStream + name: companies + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: crm/companies + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - companies + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + start_datetime: + type: MinMaxDatetime + datetime: "1900-01-01T00:00:00Z" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: updatedSince + inject_into: request_parameter + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/companies" + contracts: + type: DeclarativeStream + name: contracts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/owners/contracts + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - contracts + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contracts" + fractionals_inventory: + type: DeclarativeStream + name: fractionals_inventory + primary_key: + - fraction_id + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/owners/fractionals/{{ stream_partition.fraction_id }}/inventory + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - inventory + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: fraction_id + stream: + $ref: "#/definitions/streams/fractionals" + incremental_dependency: true + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - owner + - type: AddFields + fields: + - path: + - fraction_id + value: "{{ stream_partition.fraction_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/fractionals_inventory" + fractionals_owners: + type: DeclarativeStream + name: fractionals_owners + primary_key: + - fraction_id + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/owners/fractionals/{{ stream_partition.fraction_id }}/owners + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - owners + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: fraction_id + stream: + $ref: "#/definitions/streams/fractionals" + incremental_dependency: true + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - fractional + - type: RemoveFields + field_pointers: + - - _embedded + - owner + - type: RemoveFields + field_pointers: + - - _embedded + - contract + - type: AddFields + fields: + - path: + - fraction_id + value: "{{ stream_partition.fraction_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/fractionals_owners" + unit_type_daily_pricing_v2: + type: DeclarativeStream + name: unit_type_daily_pricing_v2 + primary_key: + - unit_type_id + - rateTypeId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/pms/units/types/{{ stream_partition.unit_type_id }}/daily-pricing + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: unit_type_id + stream: + $ref: "#/definitions/streams/unit_types_pricing_parent" + transformations: + - type: AddFields + fields: + - path: + - unit_type_id + value: "{{ stream_partition.unit_type_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/unit_type_daily_pricing_v2" + unit_daily_pricing_v2: + type: DeclarativeStream + name: unit_daily_pricing_v2 + primary_key: + - unit_id + - rateTypeId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/pms/units/{{ stream_partition.unit_id }}/daily-pricing + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: unit_id + stream: + $ref: "#/definitions/streams/units_pricing_parent" + incremental_dependency: true + transformations: + - type: AddFields + fields: + - path: + - unit_id + value: "{{ stream_partition.unit_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/unit_daily_pricing_v2" + unit_taxes: + type: DeclarativeStream + name: unit_taxes + primary_key: + - unit_id + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/units/{{ stream_partition.unit_id }}/taxes + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - unitTaxes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: unit_id + stream: + $ref: "#/definitions/streams/unit_taxes_parent" + incremental_dependency: true + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: AddFields + fields: + - path: + - unit_id + value: "{{ stream_interval.unit_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/unit_taxes" + accounting-items: + type: DeclarativeStream + name: accounting-items + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/accounting/items + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - revenueAccount + - type: RemoveFields + field_pointers: + - - revenueAccounts + - type: RemoveFields + field_pointers: + - - _embedded + - revenueAccount + - type: RemoveFields + field_pointers: + - - _embedded + - taxPolicy + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounting-items" + accounting-accounts: + type: DeclarativeStream + name: accounting-accounts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/accounting/accounts + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - accounts + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - parent + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounting-accounts" + accounting-transactions: + type: DeclarativeStream + name: accounting-transactions + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/accounting/transactions + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - blocks + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - unit + - type: RemoveFields + field_pointers: + - - _embedded + - transaction + - _embedded + - type: RemoveFields + field_pointers: + - - _embedded + - transaction + - reservation + - type: RemoveFields + field_pointers: + - - _embedded + - transaction + - _links + - type: RemoveFields + field_pointers: + - - _embedded + - reservation + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounting-transactions" + accounting-bills: + type: DeclarativeStream + name: accounting-bills + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/accounting/bills + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - bills + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - lines + - "*" + - billCharges + - type: RemoveFields + field_pointers: + - - _embedded + - vendor + - type: RemoveFields + field_pointers: + - - _embedded + - APAccount + - type: RemoveFields + field_pointers: + - - lines + - "*" + - _links + - type: RemoveFields + field_pointers: + - - _embedded + - workOrder + - type: RemoveFields + field_pointers: + - - _embedded + - children + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounting-bills" + accounting-charges: + type: DeclarativeStream + name: accounting-charges + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/accounting/charges + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - charges + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - unit + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounting-charges" + maintenance-work-orders: + type: DeclarativeStream + name: maintenance-work-orders + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/maintenance/work-orders + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - workOrders + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + start_datetime: + type: MinMaxDatetime + datetime: "1900-01-01T00:00:00Z" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: updatedSince + inject_into: request_parameter + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - lines + - "*" + - billCharges + - type: RemoveFields + field_pointers: + - - _embedded + - vendor + - type: RemoveFields + field_pointers: + - - _embedded + - APAccount + - type: RemoveFields + field_pointers: + - - lines + - "*" + - _links + - type: RemoveFields + field_pointers: + - - _embedded + - owner + - type: RemoveFields + field_pointers: + - - _embedded + - unit + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/maintenance-work-orders" + unit_taxes_parent: + type: DeclarativeStream + name: unit_taxes_parent + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/units + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - units + record_filter: + type: RecordFilter + condition: "{{ record['taxId'] not in [None] }}" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + start_datetime: + type: MinMaxDatetime + datetime: "1900-01-01T00:00:00Z" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: contentUpdatedSince + inject_into: request_parameter + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - node + - type: RemoveFields + field_pointers: + - - _embedded + - parent + - type: RemoveFields + field_pointers: + - - _embedded + - type + - type: RemoveFields + field_pointers: + - - _embedded + - lodgingType + - type: RemoveFields + field_pointers: + - - _embedded + - taxDistrict + - type: RemoveFields + field_pointers: + - - _embedded + - localOffice + - type: RemoveFields + field_pointers: + - - _embedded + - travelInsuranceProduct + - type: RemoveFields + field_pointers: + - - _embedded + - cleanStatus + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/unit_taxes_parent" + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: users + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - users + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - vendor + - type: RemoveFields + field_pointers: + - - _embedded + - role + - type: RemoveFields + field_pointers: + - - _embedded + - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + roles: + type: DeclarativeStream + name: roles + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: roles + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - roles + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/roles" + crm_company_attachment: + type: DeclarativeStream + name: crm_company_attachment + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: crm/companies/{{ stream_interval.company_id }}/attachments + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - attachments + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: company_id + stream: + $ref: "#/definitions/streams/companies" + incremental_dependency: true + transformations: + - type: AddFields + fields: + - path: + - company_id + value: "{{ stream_partition.company_id }}" + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/crm_company_attachment" + crm-tasks: + type: DeclarativeStream + name: crm-tasks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: crm/tasks + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - tasks + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - user + - type: RemoveFields + field_pointers: + - - _embedded + - unit + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/crm-tasks" + units-amenity-groups: + type: DeclarativeStream + name: units-amenity-groups + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/units/amenity-groups + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - amenitiesCategory + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/units-amenity-groups" + nodes-types: + type: DeclarativeStream + name: nodes-types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/nodes/types + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - nodeTypes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/nodes-types" + charges: + type: DeclarativeStream + name: charges + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/charges + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - charges + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - item + - revenueAccounts + - type: RemoveFields + field_pointers: + - - _embedded + - item + - _embedded + - revenueAccount + - type: RemoveFields + field_pointers: + - - _embedded + - item + - _links + - type: RemoveFields + field_pointers: + - - _embedded + - item + - _embedded + - taxPolicy + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/charges" + date-groups: + type: DeclarativeStream + name: date-groups + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/date-groups + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - dateGroups + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/date-groups" + documents: + type: DeclarativeStream + name: documents + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/documents + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - documents + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/documents" + folios-rules: + type: DeclarativeStream + name: folios-rules + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/folios/rules + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - rules + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/folios-rules" + folio_logs: + type: DeclarativeStream + name: folio_logs + primary_key: + - folio_id + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/folios/{{ stream_interval.folio_id }}/logs + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - logs + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: folio_id + stream: + $ref: "#/definitions/streams/folios" + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: AddFields + fields: + - path: + - folio_id + value: "{{ stream_interval.folio_id }}" + - type: RemoveFields + field_pointers: + - - params + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/folio_logs" + maintenance-problems: + type: DeclarativeStream + name: maintenance-problems + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/maintenance/problems + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - maintenanceProblems + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/maintenance-problems" + owners_units: + type: DeclarativeStream + name: owners_units + primary_key: + - ownerId + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/owners/{{ stream_partition.owner_id }}/units + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - ownerUnits + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: owner_id + stream: + $ref: "#/definitions/streams/owners" + incremental_dependency: true + transformations: + - type: RemoveFields + field_pointers: + - - _embedded + - owner + - type: RemoveFields + field_pointers: + - - _embedded + - unit + - type: RemoveFields + field_pointers: + - - _embedded + - contract + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/owners_units" + owners-contracts: + type: DeclarativeStream + name: owners-contracts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/owners/contracts + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - contracts + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/owners-contracts" + owner-statements: + type: DeclarativeStream + name: owner-statements + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/owners/statements + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - statements + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _embedded + - owner + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/owner-statements" + owner_statement_transactions: + type: DeclarativeStream + name: owner_statement_transactions + primary_key: + - statement_id + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + pms/owners/statements/{{ stream_interval.statement_id + }}/transactions + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - transactions + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: statement_id + stream: + $ref: "#/definitions/streams/owner-statements" + transformations: + - type: RemoveFields + field_pointers: + - - _embedded + - owner + - type: RemoveFields + field_pointers: + - - _links + - type: AddFields + fields: + - path: + - statement_id + value: "{{ stream_interval.statement_id }}" + - type: RemoveFields + field_pointers: + - - _embedded + - unit + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/owner_statement_transactions" + promo-codes: + type: DeclarativeStream + name: promo-codes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: v2/pms/promo-codes + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - promoCodes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/promo-codes" + reservations-cancellation-policies: + type: DeclarativeStream + name: reservations-cancellation-policies + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/reservations/cancellation-policies + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - policies + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/reservations-cancellation-policies" + reservations-guarantee-policies: + type: DeclarativeStream + name: reservations-guarantee-policies + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/reservations/policies/guarantees + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - guaranteePolicies + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - dateGroup + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/reservations-guarantee-policies" + reservation-cancellation-reasons: + type: DeclarativeStream + name: reservation-cancellation-reasons + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/reservations/cancellation-reasons + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - cancellationReasons + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/reservation-cancellation-reasons" + reservation-discount-reasons: + type: DeclarativeStream + name: reservation-discount-reasons + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/reservations/discount-reasons + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - discountReasons + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/reservation-discount-reasons" + units-bed-types: + type: DeclarativeStream + name: units-bed-types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/units/bed-types + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - bedTypes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/units-bed-types" + custom-fields: + type: DeclarativeStream + name: custom-fields + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: custom-fields + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - customFields + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/custom-fields" + groups: + type: DeclarativeStream + name: groups + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/groups + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - groups + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - account + - type: RemoveFields + field_pointers: + - - _embedded + - company + - type: RemoveFields + field_pointers: + - - _embedded + - rateType + - type: RemoveFields + field_pointers: + - - _embedded + - reservationType + - type: RemoveFields + field_pointers: + - - _embedded + - travelAgent + - type: RemoveFields + field_pointers: + - - _embedded + - promoCode + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/groups" + rate-types: + type: DeclarativeStream + name: rate-types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/rates/types + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - rateTypes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - parentRate + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/rate-types" + group_blocks: + type: DeclarativeStream + name: group_blocks + primary_key: + - group_id + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/groups/{{ stream_partition.group_id }}/blocks + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - blocks + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: group_id + stream: + $ref: "#/definitions/streams/groups" + transformations: + - type: AddFields + fields: + - path: + - group_id + value: "{{ stream_partition.group_id }}" + - type: RemoveFields + field_pointers: + - - _embedded + - unit + - type: RemoveFields + field_pointers: + - - _embedded + - reservation + - type: RemoveFields + field_pointers: + - - _embedded + - folioBreakdown + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/group_blocks" + group_tags: + type: DeclarativeStream + name: group_tags + primary_key: + - group_id + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/groups/{{ stream_partition.group_id }}/tags + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - tags + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: group_id + stream: + $ref: "#/definitions/streams/groups" + transformations: + - type: AddFields + fields: + - path: + - group_id + value: "{{ stream_partition.group_id }}" + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/group_tags" + group_breakdown: + type: DeclarativeStream + name: group_breakdown + primary_key: + - group_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/groups/{{ stream_partition.group_id }}/breakdown + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - breakdown + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: group_id + stream: + $ref: "#/definitions/streams/groups" + transformations: + - type: AddFields + fields: + - path: + - group_id + value: "{{ stream_partition.group_id }}" + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/group_breakdown" + suspend-code-reasons: + type: DeclarativeStream + name: suspend-code-reasons + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/suspend-code-reasons + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - suspendCodeReasons + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/suspend-code-reasons" + units_channel: + type: DeclarativeStream + name: units_channel + primary_key: + - unit_id + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/units/{{ stream_interval.unit_id }}/channels + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - channels + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: unit_id + stream: + $ref: "#/definitions/streams/units" + incremental_dependency: true + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: AddFields + fields: + - path: + - unit_id + value: "{{ stream_interval.unit_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/units_channel" + housekeeping-work-orders: + type: DeclarativeStream + name: housekeeping-work-orders + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/housekeeping/work-orders + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - workOrders + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + start_datetime: + type: MinMaxDatetime + datetime: "1900-01-01T00:00:00Z" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: contentUpdatedSince + inject_into: request_parameter + transformations: + - type: RemoveFields + field_pointers: + - - _embedded + - unit + - type: RemoveFields + field_pointers: + - - _embedded + - user + - type: RemoveFields + field_pointers: + - - _embedded + - cleanType + - type: RemoveFields + field_pointers: + - - _embedded + - vendor + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - reservation + - type: RemoveFields + field_pointers: + - - _embedded + - nextReservation + - type: RemoveFields + field_pointers: + - - assignees + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/housekeeping-work-orders" + housekeeping-clean-types: + type: DeclarativeStream + name: housekeeping-clean-types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/housekeeping/clean-types + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - cleanTypes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - expenseAccount + - type: RemoveFields + field_pointers: + - - _embedded + - taskList + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/housekeeping-clean-types" + housekeeping-task-list: + type: DeclarativeStream + name: housekeeping-task-list + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/task-lists + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - taskLists + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - tasks + - "*" + - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/housekeeping-task-list" + folios-master-rules: + type: DeclarativeStream + name: folios-master-rules + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/folios/rules + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - rules + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/folios-master-rules" + contact_companies: + type: DeclarativeStream + name: contact_companies + primary_key: + - contactId + - companyId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: crm/contacts/{{ stream_partition.contact_id }}/companies + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - companies + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: contact_id + stream: + $ref: "#/definitions/streams/contacts" + incremental_dependency: true + transformations: + - type: RemoveFields + field_pointers: + - - _embedded + - contact + - type: RemoveFields + field_pointers: + - - _embedded + - company + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contact_companies" + reviews: + type: DeclarativeStream + name: reviews + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: channel-management/channel/reviews + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - channel_reviews + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/reviews" + accounting-deposits: + type: DeclarativeStream + name: accounting-deposits + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/accounting/deposits + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - deposits + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - bankAccount + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounting-deposits" + accounting-deposits-payments: + type: DeclarativeStream + name: accounting-deposits-payments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/accounting/deposits/payments + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accounting-deposits-payments" + units_pricing_parent: + type: DeclarativeStream + name: units_pricing_parent + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/units + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - units + record_filter: + type: RecordFilter + condition: "{{ record['lodgingTypeId'] != None }}" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + start_datetime: + type: MinMaxDatetime + datetime: "1900-01-01T00:00:00Z" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: contentUpdatedSince + inject_into: request_parameter + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - node + - type: RemoveFields + field_pointers: + - - _embedded + - parent + - type: RemoveFields + field_pointers: + - - _embedded + - type + - type: RemoveFields + field_pointers: + - - _embedded + - lodgingType + - type: RemoveFields + field_pointers: + - - _embedded + - taxDistrict + - type: RemoveFields + field_pointers: + - - _embedded + - localOffice + - type: RemoveFields + field_pointers: + - - _embedded + - travelInsuranceProduct + - type: RemoveFields + field_pointers: + - - _embedded + - cleanStatus + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/units_pricing_parent" + unit_types_pricing_parent: + type: DeclarativeStream + name: unit_types_pricing_parent + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/units/types + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - unitTypes + record_filter: + type: RecordFilter + condition: "{{ record['lodgingTypeId'] != None }}" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - lodgingType + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/unit_types_pricing_parent" + unit_charge_pricing_parent: + type: DeclarativeStream + name: unit_charge_pricing_parent + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/charges + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - charges + record_filter: + type: RecordFilter + condition: "{{ record['hasUnitPricing'] == true }}" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - item + - revenueAccounts + - type: RemoveFields + field_pointers: + - - _embedded + - item + - _embedded + - revenueAccount + - type: RemoveFields + field_pointers: + - - _embedded + - item + - _links + - type: RemoveFields + field_pointers: + - - _embedded + - item + - _embedded + - taxPolicy + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/unit_charge_pricing_parent" + owners-pii-redacted: + type: DeclarativeStream + name: owners-pii-redacted + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: pms/owners + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - owners + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + start_datetime: + type: MinMaxDatetime + datetime: "1900-01-01T00:00:00Z" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: updatedSince + inject_into: request_parameter + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: AddFields + fields: + - path: + - name + value: "{{ record['name'] | hash('md5') }}" + - type: AddFields + fields: + - path: + - streetAddress + value: "{{ record['streetAddress'] | hash('md5') }}" + - type: AddFields + fields: + - path: + - phone + value: "{{ record['phone'] | hash('md5') }}" + - type: AddFields + fields: + - path: + - email + value: "{{ record['email'] | hash('md5') }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/owners-pii-redacted" + contacts-pii-redacted: + type: DeclarativeStream + name: contacts-pii-redacted + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: crm/contacts + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - contacts + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S%z" + datetime_format: "%Y-%m-%dT%H:%M:%S%z" + start_datetime: + type: MinMaxDatetime + datetime: "1900-01-01T00:00:00Z" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: updatedSince + inject_into: request_parameter + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: AddFields + fields: + - path: + - firstName + value: "{{ record['firstName'] | hash('md5') }}" + - type: AddFields + fields: + - path: + - lastName + value: "{{ record['lastName'] | hash('md5') }}" + - type: AddFields + fields: + - path: + - name + value: "{{ record['name'] | hash('md5') }}" + - type: AddFields + fields: + - path: + - primaryEmail + value: "{{ record['primaryEmail'] | hash('md5') }}" + - type: AddFields + fields: + - path: + - streetAddress + value: "{{ record['streetAddress'] | hash('md5') }}" + - type: AddFields + fields: + - path: + - cellPhone + value: "{{ record['cellPhone'] | hash('md5') }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts-pii-redacted" + owner_statement_transactions_pii_redacted: + type: DeclarativeStream + name: owner_statement_transactions_pii_redacted + primary_key: + - statement_id + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + pms/owners/statements/{{ stream_interval.statement_id + }}/transactions + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - transactions + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: statement_id + stream: + $ref: "#/definitions/streams/owner-statements" + transformations: + - type: RemoveFields + field_pointers: + - - _embedded + - owner + - type: RemoveFields + field_pointers: + - - _links + - type: AddFields + fields: + - path: + - statement_id + value: "{{ stream_interval.statement_id }}" + - type: RemoveFields + field_pointers: + - - _embedded + - unit + - type: RemoveFields + field_pointers: + - - lines + - "*" + - description + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/owner_statement_transactions_pii_redacted" + users-pii-redacted: + type: DeclarativeStream + name: users-pii-redacted + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: users + http_method: GET + request_headers: + accept: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + max_retries: 5 + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 305 + response_filters: + - type: HttpResponseFilter + action: RATE_LIMITED + http_codes: + - 429 + error_message: >- + Track rate limit (1000 requests per 5 minutes) met, + waiting 5 minutes to reset. + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - _embedded + - users + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: size + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + transformations: + - type: RemoveFields + field_pointers: + - - _links + - type: RemoveFields + field_pointers: + - - _embedded + - vendor + - type: RemoveFields + field_pointers: + - - _embedded + - role + - type: RemoveFields + field_pointers: + - - _embedded + - _links + - type: AddFields + fields: + - path: + - name + value: "{{ record['name'] | hash('md5') }}" + - type: AddFields + fields: + - path: + - email + value: "{{ record['name'] | hash('md5') }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users-pii-redacted" + base_requester: + type: HttpRequester + url_base: https://{{ config.customer_domain }}/api/ + authenticator: + type: BasicHttpAuthenticator + password: "{{ config[\"api_secret\"] }}" + username: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/units" + - $ref: "#/definitions/streams/owners" + - $ref: "#/definitions/streams/fractionals" + - $ref: "#/definitions/streams/unit-blocks" + - $ref: "#/definitions/streams/folios" + - $ref: "#/definitions/streams/nodes" + - $ref: "#/definitions/streams/units-amenities" + - $ref: "#/definitions/streams/quotes" + - $ref: "#/definitions/streams/reservations_v2" + - $ref: "#/definitions/streams/reservation-types" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/tags" + - $ref: "#/definitions/streams/unit-types" + - $ref: "#/definitions/streams/lodging-types" + - $ref: "#/definitions/streams/tax-districts" + - $ref: "#/definitions/streams/tax-policies" + - $ref: "#/definitions/streams/taxes" + - $ref: "#/definitions/streams/travel-insurance-products" + - $ref: "#/definitions/streams/companies" + - $ref: "#/definitions/streams/contracts" + - $ref: "#/definitions/streams/fractionals_inventory" + - $ref: "#/definitions/streams/fractionals_owners" + - $ref: "#/definitions/streams/unit_type_daily_pricing_v2" + - $ref: "#/definitions/streams/unit_daily_pricing_v2" + - $ref: "#/definitions/streams/unit_taxes" + - $ref: "#/definitions/streams/accounting-items" + - $ref: "#/definitions/streams/accounting-accounts" + - $ref: "#/definitions/streams/accounting-transactions" + - $ref: "#/definitions/streams/accounting-bills" + - $ref: "#/definitions/streams/accounting-charges" + - $ref: "#/definitions/streams/maintenance-work-orders" + - $ref: "#/definitions/streams/unit_taxes_parent" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/roles" + - $ref: "#/definitions/streams/crm_company_attachment" + - $ref: "#/definitions/streams/crm-tasks" + - $ref: "#/definitions/streams/units-amenity-groups" + - $ref: "#/definitions/streams/nodes-types" + - $ref: "#/definitions/streams/charges" + - $ref: "#/definitions/streams/date-groups" + - $ref: "#/definitions/streams/documents" + - $ref: "#/definitions/streams/folios-rules" + - $ref: "#/definitions/streams/folio_logs" + - $ref: "#/definitions/streams/maintenance-problems" + - $ref: "#/definitions/streams/owners_units" + - $ref: "#/definitions/streams/owners-contracts" + - $ref: "#/definitions/streams/owner-statements" + - $ref: "#/definitions/streams/owner_statement_transactions" + - $ref: "#/definitions/streams/promo-codes" + - $ref: "#/definitions/streams/reservations-cancellation-policies" + - $ref: "#/definitions/streams/reservations-guarantee-policies" + - $ref: "#/definitions/streams/reservation-cancellation-reasons" + - $ref: "#/definitions/streams/reservation-discount-reasons" + - $ref: "#/definitions/streams/units-bed-types" + - $ref: "#/definitions/streams/custom-fields" + - $ref: "#/definitions/streams/groups" + - $ref: "#/definitions/streams/rate-types" + - $ref: "#/definitions/streams/group_blocks" + - $ref: "#/definitions/streams/group_tags" + - $ref: "#/definitions/streams/group_breakdown" + - $ref: "#/definitions/streams/suspend-code-reasons" + - $ref: "#/definitions/streams/units_channel" + - $ref: "#/definitions/streams/housekeeping-work-orders" + - $ref: "#/definitions/streams/housekeeping-clean-types" + - $ref: "#/definitions/streams/housekeeping-task-list" + - $ref: "#/definitions/streams/folios-master-rules" + - $ref: "#/definitions/streams/contact_companies" + - $ref: "#/definitions/streams/reviews" + - $ref: "#/definitions/streams/accounting-deposits" + - $ref: "#/definitions/streams/accounting-deposits-payments" + - $ref: "#/definitions/streams/units_pricing_parent" + - $ref: "#/definitions/streams/unit_types_pricing_parent" + - $ref: "#/definitions/streams/unit_charge_pricing_parent" + - $ref: "#/definitions/streams/owners-pii-redacted" + - $ref: "#/definitions/streams/contacts-pii-redacted" + - $ref: "#/definitions/streams/owner_statement_transactions_pii_redacted" + - $ref: "#/definitions/streams/users-pii-redacted" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - customer_domain + - api_key + properties: + customer_domain: + type: string + order: 0 + title: Customer Domain + api_key: + type: string + order: 1 + title: API Key + api_secret: + type: string + order: 2 + title: API Secret + always_show: true + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + units: true + owners: true + fractionals: true + unit-blocks: true + folios: true + nodes: true + units-amenities: true + quotes: true + reservations_v2: true + reservation-types: true + contacts: true + tags: true + unit-types: true + lodging-types: true + tax-districts: true + tax-policies: true + taxes: true + travel-insurance-products: true + companies: true + contracts: true + fractionals_inventory: true + fractionals_owners: true + unit_type_daily_pricing_v2: true + unit_daily_pricing_v2: true + unit_taxes: true + accounting-items: true + accounting-accounts: true + accounting-transactions: true + accounting-bills: true + accounting-charges: true + maintenance-work-orders: true + unit_taxes_parent: true + users: true + roles: true + crm_company_attachment: true + crm-tasks: true + units-amenity-groups: true + nodes-types: true + charges: true + date-groups: true + documents: true + folios-rules: true + folio_logs: true + maintenance-problems: true + owners_units: true + owners-contracts: true + owner-statements: true + owner_statement_transactions: true + promo-codes: true + reservations-cancellation-policies: true + reservations-guarantee-policies: true + reservation-cancellation-reasons: true + reservation-discount-reasons: true + units-bed-types: true + custom-fields: true + groups: true + rate-types: true + group_blocks: true + group_tags: true + group_breakdown: true + suspend-code-reasons: true + units_channel: true + housekeeping-work-orders: true + housekeeping-clean-types: true + housekeeping-task-list: true + folios-master-rules: true + contact_companies: true + reviews: true + accounting-deposits: true + accounting-deposits-payments: true + units_pricing_parent: true + unit_types_pricing_parent: true + unit_charge_pricing_parent: true + owners-pii-redacted: true + contacts-pii-redacted: true + owner_statement_transactions_pii_redacted: true + users-pii-redacted: true + yamlComponents: + global: + - authenticator + testedStreams: + units: + streamHash: c89a201c91742578d8e627b2403e36525a3e1902 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + owners: + streamHash: 28796c10f42e6d72ad93702ec19e20da03b292f3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + fractionals: + streamHash: b3747b8ad66870acc2ee7688c063443c27546739 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + unit-blocks: + streamHash: 47ebdc1240de86de8a2c8401704471bb05c314f1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + folios: + streamHash: 3f04a63c33ccb57948c432814431427660d79225 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + nodes: + streamHash: f17310fbd7e1096ae67a779e7293958cb7aba285 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + units-amenities: + streamHash: 1d1e00d655f83717ceef52388d9ac82504eccd6b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + quotes: + streamHash: 15e3450c63d1aa9d77a521f9d217d327648fe7e4 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + reservations_v2: + streamHash: 32f15fa8df4fb1d646d55af54cf95c33ebfb6458 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + reservation-types: + streamHash: 9761fc939cdd6669a5f4ebbf9b9fa0529dfc7866 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contacts: + streamHash: 7ecd4a82173d07f0e519d4f6e576ce2878ce3ba5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tags: + streamHash: 8701e2c85e828a867447716905010fc896cf84a2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + unit-types: + streamHash: 15c750173b1db5d356d9e6637dcf32d046a345fd + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + lodging-types: + streamHash: 7ef0e94bae2b2adcadfa858f8bc0aa6cbbe24da0 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tax-districts: + streamHash: 7baba1225027e154006bfa9c149cd8f74d5c6c9b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tax-policies: + streamHash: 09506c145697496a1425990e6c55625cf97ad728 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + taxes: + streamHash: 0f75ca1e64ca942aee8273f56867cb167472b6f4 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + travel-insurance-products: + streamHash: 78ed39ed63b032bcefffe973eb2e792fe64e38b1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + companies: + streamHash: f60ba93f9669b3da5cd05161a448f7dd7c0b43a0 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contracts: + streamHash: b0fc439ca49458afabb050b79ffadcc72d505454 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + fractionals_inventory: + streamHash: fa55f1fb8b08a243cf91bca6fd98f372f78fde51 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + fractionals_owners: + streamHash: 4a8370fe246c2e8c734345d46ddf3f5d49179527 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + unit_type_daily_pricing_v2: + streamHash: aee24eda1a4549960320805577018acca1be7da6 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + unit_daily_pricing_v2: + streamHash: 226f2fe092e9c5b5d41a912e4813ae1e013c122f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + unit_taxes: + streamHash: 0e289eb665ddf3a9fda176e7a7d78f8a89a477da + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + accounting-items: + streamHash: cc2f90eb2418f153d025e1c9f8d1ba8bc8e9e244 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + accounting-accounts: + streamHash: 876b2be2737b163fa6058c14dfc4262aece9c259 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + accounting-transactions: + streamHash: a5213cf62ebb0f88ce2dc3186de5bfc98f72f274 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + accounting-bills: + streamHash: 50576de7b8c4eb81bfa287fa2ef1c017213aa49e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + accounting-charges: + streamHash: 2cd28b84cac8778755581fcbf69a8349ed7244ce + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + maintenance-work-orders: + streamHash: 8b0a69d6edf02350cb9f4a6369127351c5723257 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + unit_taxes_parent: + streamHash: 5229c58074fd6c54091bf742ccf09664dcf315f0 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + users: + streamHash: 6149120dd59889e76dca7e5c44cfefc2947c2c90 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + roles: + streamHash: 5d1faa2ecf76a7ecefd31f47c0dfff3adf4c131e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + crm_company_attachment: + streamHash: aa20f14f1ebc7e1a0f5b757537d84081b5f7f72d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + crm-tasks: + streamHash: 407bd3d0d8e413af524c0268efe401015a87f8ab + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + units-amenity-groups: + streamHash: 16dc9f5846d55d04b9aa54ac16c4284fc2ddebb1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + nodes-types: + streamHash: 8a260170f9880bedbbf2efb333807374f082d02b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + charges: + streamHash: 313ec9da3ee600e7a922bf6ab999a8f169b6e6d3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + date-groups: + streamHash: 450d5acbc509df7342c3c8a18df3261a7b825f4a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + documents: + streamHash: 8297924bdb35909ea029ae7b00e24b0b1cd11bd6 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + folios-rules: + streamHash: 615d6eef67f230b1f6b98a383ea0456a1b4a9414 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + folio_logs: + streamHash: dada7f099622c48295b9efd35838fe9e3cfe55be + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + maintenance-problems: + hasRecords: true + streamHash: 1eb145811a9e0347cba3021b6306250a3f803b36 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + owners_units: + hasRecords: true + streamHash: 8fc8f50cca63f9b70dc1c8cd489b80e9af7e9f57 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + owners-contracts: + hasRecords: true + streamHash: e17450fdbea5ba87f8b76bf6332ee2047ae45d77 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + owner-statements: + hasRecords: true + streamHash: b4eeb0d0978f8e4b04eba1ef16517d067f52186e + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + owner_statement_transactions: + hasRecords: true + streamHash: 951e696ccdf2681d6e9934b6b9da355160d00f01 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + promo-codes: + hasRecords: true + streamHash: f8307a605f8d8650fd32e9caccd9a9397bb4a0f5 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + reservations-cancellation-policies: + hasRecords: true + streamHash: 3c41cd838bc24de0e62bb58e30c7a15c59f054b6 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + reservations-guarantee-policies: + hasRecords: true + streamHash: 7f428ecaa1aad1e0782d04d0045e1957baf0bcd3 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + reservation-cancellation-reasons: + hasRecords: true + streamHash: 7c118d1e0245e16af327b0b3ed04806ffb9ac599 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + reservation-discount-reasons: + hasRecords: true + streamHash: ef134c808c84933519a5f72586308b37b9820546 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + units-bed-types: + hasRecords: true + streamHash: 52813a51c10496d789dc5a5fdf44ed35acab0987 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + custom-fields: + hasRecords: true + streamHash: 2b8ce62af9419f47f47b72a614f65ae5fa7107fb + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + groups: + hasRecords: true + streamHash: ada74a1ba89bfdb3672fc9e226ab4af121967c3d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + rate-types: + hasRecords: true + streamHash: 1af288d275140b32a94952b57aebe1d9e68fec2b + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + group_blocks: + hasRecords: true + streamHash: ded9577521f4b4a937f4dc7e1c3a1c593d4048e5 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + group_tags: + hasRecords: true + streamHash: e18121b696ab8b8bfbbf3e733ee0d59899553757 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + group_breakdown: + hasRecords: true + streamHash: 24271b91fc84640c0beabfc6a458186189855331 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + suspend-code-reasons: + hasRecords: true + streamHash: a374fd1817431062d21e39ad1b076833bcb74fb0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + units_channel: + hasRecords: true + streamHash: ac621ae8ff09b932508f4e7788c3ef47840363d6 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + housekeeping-work-orders: + hasRecords: true + streamHash: c3429d0fc4210db6a5267ef6bf15cbe7b4fe7fe4 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + housekeeping-clean-types: + hasRecords: true + streamHash: 3e55b9c05825ef55f2d2cfc2e4957c879d159c69 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + housekeeping-task-list: + hasRecords: true + streamHash: 9f7710a220ab1c23c965334bc33de1af953c1a4c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + folios-master-rules: + hasRecords: true + streamHash: cee6ba4b60d523a9d1d56e895c00ebf0b4e62e9d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + contact_companies: + hasRecords: true + streamHash: 0880ebcc41fcc573a008e79b545bd93cda412ca0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + reviews: + hasRecords: true + streamHash: a139a01ceb13bba07bc8fd5a075b2d601959e8f7 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + accounting-deposits: + hasRecords: true + streamHash: 94a00cd4237fbe84a6edf90c71239e958c09de8a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + accounting-deposits-payments: + hasRecords: true + streamHash: a65ca0ee692c53020c8a4357c943d7514d933feb + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + units_pricing_parent: + hasRecords: true + streamHash: a8ceaaf479ebc4e7a2f2492d0497cf0fe124d3f8 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + unit_types_pricing_parent: + hasRecords: true + streamHash: 18e8e4f4123d8a44e83bed3c11dbe251f9535fc5 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + unit_charge_pricing_parent: + hasRecords: true + streamHash: 3cdbaab68ff18333d9e3ebfcf362e3a364d6fdb2 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + owners-pii-redacted: + hasRecords: true + streamHash: 432d7330c433a60cfff554e14c4769cb731a175a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + contacts-pii-redacted: + hasRecords: true + streamHash: 4f4bf8cca331936fdbafa8330a3ae1f3ae54ac8f + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + owner_statement_transactions_pii_redacted: + hasRecords: true + streamHash: 18e925c3b3d1844334fc97340653b3b51b23aa22 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + users-pii-redacted: + hasRecords: true + streamHash: 3d90d9c1a1703a678f654fab4a3b1377fb121fe0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: {} + +schemas: + units: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + amenitiesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + area: + type: + - number + - "null" + availabilityOrder: + type: + - number + - "null" + bedTypes: + type: + - array + - "null" + bedrooms: + type: + - number + - "null" + cancellationPoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + checkinTime: + type: + - string + - "null" + checkoutTime: + type: + - string + - "null" + childrenAllowed: + type: + - boolean + - "null" + cleanStatusId: + type: + - number + - "null" + cleanStatusType: + type: + - string + - "null" + composites: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + unitId: + type: + - number + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + pms_units_owner_notes: + type: + - string + - "null" + pms_units_source_unit_id: + type: + - string + - "null" + pms_units_wifi_information: + type: + - string + - "null" + documentsIds: + type: + - array + - "null" + items: + type: + - number + - "null" + earlyCheckinTime: + type: + - string + - "null" + eventsAllowed: + type: + - boolean + - "null" + extendedAddress: + type: + - string + - "null" + floors: + type: + - number + - "null" + folioException: + type: + - boolean + - "null" + fullBathrooms: + type: + - number + - "null" + gatewaysIds: + type: + - array + - "null" + items: + type: + - number + - "null" + guaranteePoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + halfBathrooms: + type: + - number + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + housekeepingMessage: + type: + - string + - "null" + housekeepingNotes: + type: + - string + - "null" + id: + type: number + isAccessible: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isBookable: + type: + - boolean + - "null" + isLimited: + type: + - boolean + - "null" + isOccupied: + type: + - boolean + - "null" + lateCheckoutTime: + type: + - string + - "null" + latitude: + type: + - string + - "null" + localOfficeId: + type: + - number + - "null" + locality: + type: + - string + - "null" + lodgingTypeId: + type: + - number + - "null" + longitude: + type: + - string + - "null" + maintenanceMessage: + type: + - string + - "null" + maxOccupancy: + type: + - number + - "null" + minimumAgeLimit: + type: + - number + - "null" + name: + type: + - string + - "null" + nodeId: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + region: + type: + - string + - "null" + roles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + roleId: + type: + - number + - "null" + userId: + type: + - number + - "null" + securityDeposit: + type: + - string + - "null" + shortName: + type: + - string + - "null" + smokingAllowed: + type: + - boolean + - "null" + streetAddress: + type: + - string + - "null" + taxDistrictId: + type: + - number + - "null" + taxId: + type: + - string + - "null" + threeQuarterBathrooms: + type: + - number + - "null" + timezone: + type: + - string + - "null" + travelInsuranceProductId: + type: + - number + - "null" + typeId: + type: + - number + - "null" + unitCode: + type: + - string + - "null" + updatedAt: + type: string + updatedBy: + type: + - string + - "null" + useBedTypes: + type: + - boolean + - "null" + useRoomConfiguration: + type: + - boolean + - "null" + websiteUrl: + type: + - string + - "null" + required: + - id + - updatedAt + owners: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + achAccountNumber: + type: + - string + - "null" + achAccountType: + type: + - string + - "null" + achRoutingNumber: + type: + - string + - "null" + activeUnitCount: + type: + - number + - "null" + agentCommission: + type: + - string + - "null" + alwaysShowInStatements: + type: + - boolean + - "null" + companyId: + type: + - number + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currentBalance: + type: + - string + - "null" + deferredBalance: + type: + - string + - "null" + email: + type: + - string + - "null" + extendedAddress: + type: + - string + - "null" + fax: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + locality: + type: + - string + - "null" + minimumBalance: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + paymentType: + type: + - string + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + region: + type: + - string + - "null" + splitWithContacts: + type: + - boolean + - "null" + streetAddress: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + taxCountry: + type: + - string + - "null" + taxExtendedAddress: + type: + - string + - "null" + taxId: + type: + - string + - "null" + taxLocality: + type: + - string + - "null" + taxName: + type: + - string + - "null" + taxPostalCode: + type: + - string + - "null" + taxRegion: + type: + - string + - "null" + taxStreetAddress: + type: + - string + - "null" + taxType: + type: + - string + - "null" + updatedAt: + type: string + updatedBy: + type: + - string + - "null" + website: + type: + - string + - "null" + required: + - id + - updatedAt + fractionals: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + futureInventoryTimePeriods: + type: + - number + - "null" + id: + type: number + name: + type: + - string + - "null" + reservationTypeId: + type: + - number + - "null" + scheduleFutureInventory: + type: + - boolean + - "null" + startDate: + type: + - string + - "null" + startDayOfWeek: + type: + - number + - "null" + timeUnit: + type: + - string + - "null" + totalShares: + type: + - number + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + unit-blocks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + properties: + cleanType: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + expenseAccount: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + taskList: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + chargeOwner: + type: + - boolean + - "null" + chargeOwnerDefaultAmount: + type: + - string + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + expenseAccountId: + type: + - number + - "null" + generateLinenTicket: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + taskListId: + type: + - number + - "null" + timeEstimate: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + reason: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + blockNotes: + type: + - string + - "null" + blockReasonId: + type: + - number + - "null" + blockReasonInline: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + chargeOwner: + type: + - boolean + - "null" + cleanTypeId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + endDate: + type: + - string + - "null" + id: + type: number + isArchived: + type: + - boolean + - "null" + notes: + type: + - string + - "null" + reasonId: + type: + - number + - "null" + startDate: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + folios: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + accountId: + type: + - number + - "null" + agentCommission: + type: + - string + - "null" + checkInDate: + type: + - string + - "null" + checkOutDate: + type: + - string + - "null" + closedDate: + type: + - string + - "null" + companyId: + type: + - number + - "null" + contactId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currentBalance: + type: + - string + - "null" + endDate: + type: + - string + - "null" + generatedName: + type: + - string + - "null" + hasException: + type: + - boolean + - "null" + id: + type: number + masterFolioId: + type: + - number + - "null" + masterFolioRuleId: + type: + - number + - "null" + name: + type: + - string + - "null" + ownerCommission: + type: + - string + - "null" + ownerRevenue: + type: + - string + - "null" + posAllow: + type: + - boolean + - "null" + posLimit: + type: + - string + - "null" + realizedBalance: + type: + - string + - "null" + reservationId: + type: + - number + - "null" + startDate: + type: + - string + - "null" + status: + type: + - string + - "null" + taxExempt: + type: + - boolean + - "null" + travelAgentId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + nodes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + amenitiesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + cancellationPoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + checkinTime: + type: + - string + - "null" + checkoutTime: + type: + - string + - "null" + childrenAllowed: + type: + - boolean + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + pms_nodes_pre_arrival_information: + type: + - string + - "null" + documentsIds: + type: + - array + - "null" + items: + type: + - number + - "null" + earlyCheckinTime: + type: + - string + - "null" + eventsAllowed: + type: + - boolean + - "null" + gatewaysIds: + type: + - array + - "null" + items: + type: + - number + - "null" + guaranteePoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + id: + type: number + isAccessible: + type: + - boolean + - "null" + lateCheckoutTime: + type: + - string + - "null" + localOfficeId: + type: + - number + - "null" + locality: + type: + - string + - "null" + minimumAgeLimit: + type: + - number + - "null" + name: + type: + - string + - "null" + parentId: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + region: + type: + - string + - "null" + roles: + type: + - array + - "null" + smokingAllowed: + type: + - boolean + - "null" + taxDistrictId: + type: + - number + - "null" + timezone: + type: + - string + - "null" + typeId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + units-amenities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + airbnbType: + type: + - string + - "null" + bookingDotComAccommodationType: + type: + - string + - "null" + bookingDotComPropertyType: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + group: + type: + - object + - "null" + properties: + name: + type: + - string + - "null" + groupId: + type: + - number + - "null" + homeawayType: + type: + - string + - "null" + id: + type: number + isFilterable: + type: + - boolean + - "null" + isPublic: + type: + - boolean + - "null" + marriottType: + type: + - string + - "null" + name: + type: + - string + - "null" + publicSearchable: + type: + - boolean + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + quotes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + properties: + type: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + autoSelect: + type: + - boolean + - "null" + chargeRates: + type: + - boolean + - "null" + chargeRent: + type: + - string + - "null" + cleaningOptionsId: + type: + - number + - "null" + code: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + deferDisbursement: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + isCommissionable: + type: + - boolean + - "null" + isDefault: + type: + - boolean + - "null" + isLocked: + type: + - boolean + - "null" + isOwner: + type: + - boolean + - "null" + name: + type: + - string + - "null" + ownerStay: + type: + - boolean + - "null" + personalUse: + type: + - boolean + - "null" + portalReservationBreakdown: + type: + - boolean + - "null" + posDefaultAllow: + type: + - boolean + - "null" + posDefaultLimit: + type: + - string + - "null" + publicName: + type: + - string + - "null" + realizeRates: + type: + - string + - "null" + rentEarned: + type: + - string + - "null" + requirePayment: + type: + - boolean + - "null" + requiresAgreement: + type: + - boolean + - "null" + schedulePercentage1: + type: + - number + - "null" + schedulePercentage2: + type: + - number + - "null" + sendPortalInvites: + type: + - boolean + - "null" + showFolioTransactions: + type: + - boolean + - "null" + typeColor: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + cancellationPolicy: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + dateGroup: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + breakpoints: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + id: + type: + - number + - "null" + nonCancelable: + type: + - boolean + - "null" + nonRefundable: + type: + - boolean + - "null" + penaltyFlat: + type: + - string + - "null" + penaltyNights: + type: + - number + - "null" + penaltyPercent: + type: + - string + - "null" + rangeEnd: + type: + - number + - "null" + rangeStart: + type: + - number + - "null" + canExceedBalance: + type: + - boolean + - "null" + cancelTime: + type: + - string + - "null" + cancelTimezone: + type: + - string + - "null" + chargeAs: + type: + - string + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + dateGroupId: + type: + - number + - "null" + dateRangeType: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + isDefault: + type: + - boolean + - "null" + name: + type: + - string + - "null" + postDate: + type: + - string + - "null" + priority: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + contact: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + cellPhone: + type: + - string + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + custom_5: + type: + - string + - "null" + custom_6: + type: + - string + - "null" + extendedAddress: + type: + - string + - "null" + firstName: + type: + - string + - "null" + homePhone: + type: + - string + - "null" + id: + type: + - number + - "null" + isBlacklist: + type: + - boolean + - "null" + isDNR: + type: + - boolean + - "null" + isOwnerContact: + type: + - boolean + - "null" + isVip: + type: + - boolean + - "null" + lastName: + type: + - string + - "null" + locality: + type: + - string + - "null" + name: + type: + - string + - "null" + noIdentity: + type: + - boolean + - "null" + notes: + type: + - string + - "null" + otherPhone: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + primaryEmail: + type: + - string + - "null" + quoteCount: + type: + - string + - "null" + references: + type: + - array + - "null" + region: + type: + - string + - "null" + secondaryEmail: + type: + - string + - "null" + streetAddress: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + workPhone: + type: + - string + - "null" + guaranteePolicy: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + dateGroup: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + amount: + type: + - string + - "null" + beforeArrivalEnd: + type: + - number + - "null" + beforeArrivalStart: + type: + - number + - "null" + breakpoints: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + amountOverrides: + type: + - array + - "null" + dueType: + type: + - string + - "null" + id: + type: + - number + - "null" + isRemaining: + type: + - boolean + - "null" + percent: + type: + - number + - "null" + stop: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + dateGroupId: + type: + - number + - "null" + dateRangeType: + type: + - string + - "null" + depositType: + type: + - string + - "null" + hasPaymentSchedule: + type: + - boolean + - "null" + holdLimit: + type: + - number + - "null" + holdLimitMinutes: + type: + - number + - "null" + id: + type: + - number + - "null" + includeFees: + type: + - boolean + - "null" + includeFolioCharges: + type: + - boolean + - "null" + includeTax: + type: + - boolean + - "null" + includeTravelInsurance: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isAutomaticCancel: + type: + - boolean + - "null" + isDefault: + type: + - boolean + - "null" + name: + type: + - string + - "null" + priority: + type: + - number + - "null" + travelInsuranceWithFirstPayment: + type: + - boolean + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + promoCode: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + bookingEndDate: + type: + - string + - "null" + bookingStartDate: + type: + - string + - "null" + code: + type: + - string + - "null" + constraintMaxNights: + type: + - number + - "null" + constraintMinDaysPriorArrival: + type: + - number + - "null" + constraintMinNights: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + customBlackoutDatesConstraint: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + end: + type: + - string + - "null" + start: + type: + - string + - "null" + customDatesConstraint: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + end: + type: + - string + - "null" + start: + type: + - string + - "null" + dateConstraintType: + type: + - string + - "null" + dateConstraints: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + dateGroup: + type: + - object + - "null" + properties: + dates: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + end: + type: + - string + - "null" + id: + type: + - number + - "null" + start: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + id: + type: + - number + - "null" + isBlackoutDates: + type: + - boolean + - "null" + discountType: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + isPublic: + type: + - boolean + - "null" + name: + type: + - string + - "null" + stayDatesConstraintType: + type: + - string + - "null" + unitConstraints: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + field: + type: + - string + - "null" + id: + type: + - number + - "null" + operand: + type: + - string + - "null" + params: + type: + - object + - "null" + properties: + operator: + type: + - string + - "null" + values: + type: + - array + - "null" + items: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + valueAdjustments: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + adjustmentNights: + type: + - string + - "null" + discountConstraint: + type: + - string + - "null" + discountConstraintAmount: + type: + - string + - "null" + numberOfStays: + type: + - number + - "null" + value: + type: + - string + - "null" + rateType: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + parentRate: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + channelId: + type: + - array + - "null" + items: + type: + - number + - "null" + code: + type: + - string + - "null" + conditions: + type: + - object + - "null" + properties: + in: + type: + - object + - "null" + properties: + unitType: + type: + - array + - "null" + items: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + cta: + type: + - object + - "null" + properties: + friday: + type: + - boolean + - "null" + monday: + type: + - boolean + - "null" + saturday: + type: + - boolean + - "null" + sunday: + type: + - boolean + - "null" + thursday: + type: + - boolean + - "null" + tuesday: + type: + - boolean + - "null" + wednesday: + type: + - boolean + - "null" + ctaOverride: + type: + - boolean + - "null" + ctd: + type: + - object + - "null" + properties: + friday: + type: + - boolean + - "null" + monday: + type: + - boolean + - "null" + saturday: + type: + - boolean + - "null" + sunday: + type: + - boolean + - "null" + thursday: + type: + - boolean + - "null" + tuesday: + type: + - boolean + - "null" + wednesday: + type: + - boolean + - "null" + ctdOverride: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + isAllChannels: + type: + - boolean + - "null" + isAllUnits: + type: + - boolean + - "null" + isAutoSelect: + type: + - boolean + - "null" + maxLosAmount: + type: + - number + - "null" + maxLosType: + type: + - string + - "null" + minLosAmount: + type: + - number + - "null" + minLosType: + type: + - string + - "null" + name: + type: + - string + - "null" + occupancyPricingByType: + type: + - boolean + - "null" + overrides: + type: + - array + - "null" + parentRateId: + type: + - number + - "null" + rentAmount: + type: + - string + - "null" + rentType: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + unit: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + type: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + cleanStatus: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + localOffice: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + lodgingType: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + node: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + taxDistrict: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + travelInsuranceProduct: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + amenitiesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + area: + type: + - number + - "null" + availabilityOrder: + type: + - number + - "null" + bedTypes: + type: + - array + - "null" + bedrooms: + type: + - number + - "null" + cancellationPoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + checkinTime: + type: + - string + - "null" + checkoutTime: + type: + - string + - "null" + childrenAllowed: + type: + - boolean + - "null" + cleanStatusId: + type: + - number + - "null" + cleanStatusType: + type: + - string + - "null" + composites: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + unitId: + type: + - number + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + pms_units_owner_notes: + type: + - string + - "null" + pms_units_source_unit_id: + type: + - string + - "null" + pms_units_wifi_information: + type: + - string + - "null" + documentsIds: + type: + - array + - "null" + items: + type: + - number + - "null" + earlyCheckinTime: + type: + - string + - "null" + eventsAllowed: + type: + - boolean + - "null" + extendedAddress: + type: + - string + - "null" + floors: + type: + - number + - "null" + folioException: + type: + - boolean + - "null" + fullBathrooms: + type: + - number + - "null" + gatewaysIds: + type: + - array + - "null" + items: + type: + - number + - "null" + guaranteePoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + halfBathrooms: + type: + - number + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + housekeepingMessage: + type: + - string + - "null" + housekeepingNotes: + type: + - string + - "null" + id: + type: + - number + - "null" + isAccessible: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isBookable: + type: + - boolean + - "null" + isLimited: + type: + - boolean + - "null" + isOccupied: + type: + - boolean + - "null" + lateCheckoutTime: + type: + - string + - "null" + latitude: + type: + - string + - "null" + localOfficeId: + type: + - number + - "null" + locality: + type: + - string + - "null" + lodgingTypeId: + type: + - number + - "null" + longitude: + type: + - string + - "null" + maintenanceMessage: + type: + - string + - "null" + maxOccupancy: + type: + - number + - "null" + minimumAgeLimit: + type: + - number + - "null" + name: + type: + - string + - "null" + nodeId: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + region: + type: + - string + - "null" + roles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + roleId: + type: + - number + - "null" + userId: + type: + - number + - "null" + securityDeposit: + type: + - string + - "null" + shortName: + type: + - string + - "null" + smokingAllowed: + type: + - boolean + - "null" + streetAddress: + type: + - string + - "null" + taxDistrictId: + type: + - number + - "null" + taxId: + type: + - string + - "null" + threeQuarterBathrooms: + type: + - number + - "null" + timezone: + type: + - string + - "null" + travelInsuranceProductId: + type: + - number + - "null" + typeId: + type: + - number + - "null" + unitCode: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + useBedTypes: + type: + - boolean + - "null" + useRoomConfiguration: + type: + - boolean + - "null" + websiteUrl: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + actualAdr: + type: + - string + - "null" + arrivalDate: + type: + - string + - "null" + cancellationPolicyId: + type: + - number + - "null" + contactId: + type: + - number + - "null" + departureDate: + type: + - string + - "null" + discountTotal: + type: + - string + - "null" + expiresAt: + type: + - string + - "null" + grossRent: + type: + - string + - "null" + guaranteePolicyId: + type: + - number + - "null" + guestAdr: + type: + - string + - "null" + guestFees: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + allowFeeEdit: + type: + - boolean + - "null" + allowFeeRemoval: + type: + - boolean + - "null" + displayAs: + type: + - string + - "null" + displayName: + type: + - string + - "null" + estimatedTax: + type: + - string + - "null" + id: + type: + - number + - "null" + isRequired: + type: + - boolean + - "null" + isSuggested: + type: + - boolean + - "null" + isTaxable: + type: + - boolean + - "null" + maxQuantity: + type: + - number + - "null" + name: + type: + - string + - "null" + quantity: + type: + - string + - "null" + unitValue: + type: + - string + - "null" + value: + type: + - string + - "null" + guestGrossDisplayRent: + type: + - string + - "null" + guestIntendsInsurance: + type: + - boolean + - "null" + guestIntendsWaiver: + type: + - boolean + - "null" + guestNetDisplayRent: + type: + - string + - "null" + id: + type: number + isAvailable: + type: + - boolean + - "null" + netRent: + type: + - string + - "null" + occupants: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + extraQuantity: + type: + - number + - "null" + handle: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + quantity: + type: + - number + - "null" + ratePerPersonPerStay: + type: + - string + - "null" + ratePerStay: + type: + - string + - "null" + promoCodeId: + type: + - number + - "null" + promoValue: + type: + - string + - "null" + rateTypeId: + type: + - number + - "null" + rates: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + date: + type: + - string + - "null" + nights: + type: + - number + - "null" + occupantRate: + type: + - string + - "null" + rate: + type: + - string + - "null" + securityDeposit: + type: + - number + - "null" + source: + type: + - string + - "null" + taxExempt: + type: + - boolean + - "null" + taxes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + rate: + type: + - string + - "null" + value: + type: + - string + - "null" + total: + type: + - string + - "null" + totalFeeTaxes: + type: + - string + - "null" + totalGuestFeeTaxes: + type: + - string + - "null" + totalGuestFees: + type: + - string + - "null" + totalGuestRentTaxes: + type: + - string + - "null" + totalItemizedFees: + type: + - string + - "null" + totalRentFees: + type: + - string + - "null" + totalRentTaxes: + type: + - string + - "null" + totalServiceFees: + type: + - string + - "null" + totalTaxFees: + type: + - string + - "null" + totalTaxes: + type: + - string + - "null" + typeId: + type: + - number + - "null" + unitId: + type: + - number + - "null" + uuid: + type: + - string + - "null" + required: + - id + reservations_v2: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + properties: + campaign: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + disableRecording: + type: + - boolean + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + tags: + type: + - array + - "null" + token: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + url: + type: + - string + - "null" + discountReason: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + group: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + account: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + company: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + promoCode: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + rateType: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + reservationType: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + travelAgent: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + accountId: + type: + - number + - "null" + closedDate: + type: + - string + - "null" + code: + type: + - string + - "null" + companyId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currentBalance: + type: + - string + - "null" + endDate: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + posAllow: + type: + - boolean + - "null" + promoCodeId: + type: + - number + - "null" + rateTypeId: + type: + - number + - "null" + realizedBalance: + type: + - string + - "null" + reservationTypeId: + type: + - number + - "null" + startDate: + type: + - string + - "null" + status: + type: + - string + - "null" + taxExempt: + type: + - boolean + - "null" + travelAgentId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + promoCode: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + bookingEndDate: + type: + - string + - "null" + bookingStartDate: + type: + - string + - "null" + code: + type: + - string + - "null" + constraintMaxNights: + type: + - number + - "null" + constraintMinDaysPriorArrival: + type: + - number + - "null" + constraintMinNights: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + customBlackoutDatesConstraint: + type: + - array + - "null" + customDatesConstraint: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + end: + type: + - string + - "null" + start: + type: + - string + - "null" + dateConstraintType: + type: + - string + - "null" + dateConstraints: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + dateGroup: + type: + - object + - "null" + properties: + dates: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + end: + type: + - string + - "null" + id: + type: + - number + - "null" + start: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + id: + type: + - number + - "null" + isBlackoutDates: + type: + - boolean + - "null" + discountType: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + isPublic: + type: + - boolean + - "null" + name: + type: + - string + - "null" + stayDatesConstraintType: + type: + - string + - "null" + unitConstraints: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + field: + type: + - string + - "null" + id: + type: + - number + - "null" + operand: + type: + - string + - "null" + params: + type: + - object + - "null" + properties: + operator: + type: + - string + - "null" + values: + type: + - array + - "null" + items: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + valueAdjustments: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + adjustmentNights: + type: + - string + - "null" + discountConstraint: + type: + - string + - "null" + discountConstraintAmount: + type: + - string + - "null" + numberOfStays: + type: + - number + - "null" + value: + type: + - string + - "null" + travelAgent: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + achAccountNumber: + type: + - string + - "null" + achAccountType: + type: + - string + - "null" + achRoutingNumber: + type: + - string + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + email: + type: + - string + - "null" + extendedAddress: + type: + - string + - "null" + fax: + type: + - string + - "null" + glInsurancePolicy: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + locality: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + paymentType: + type: + - string + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + region: + type: + - string + - "null" + streetAddress: + type: + - string + - "null" + tags: + type: + - array + - "null" + taxId: + type: + - string + - "null" + taxName: + type: + - string + - "null" + taxType: + type: + - string + - "null" + travelAgentCommission: + type: + - number + - "null" + travelAgentDeductCommission: + type: + - boolean + - "null" + travelAgentIataNumber: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + wcInsurancePolicy: + type: + - string + - "null" + website: + type: + - string + - "null" + agreementStatus: + type: + - string + - "null" + alternates: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - string + - "null" + arrivalDate: + type: + - string + - "null" + arrivalTime: + type: + - string + - "null" + autoCheckinAttempts: + type: + - number + - "null" + automatePayment: + type: + - boolean + - "null" + bookedAt: + type: + - string + - "null" + campaignId: + type: + - number + - "null" + cancellationPolicyId: + type: + - number + - "null" + cancellationReasonId: + type: + - number + - "null" + cancelledAt: + type: + - string + - "null" + cancelledById: + type: + - number + - "null" + channelId: + type: + - number + - "null" + contactId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currency: + type: + - string + - "null" + departureDate: + type: + - string + - "null" + departureTime: + type: + - string + - "null" + discountNotes: + type: + - string + - "null" + discountReasonId: + type: + - number + - "null" + earlyArrival: + type: + - boolean + - "null" + folioId: + type: + - number + - "null" + groupId: + type: + - number + - "null" + guaranteePolicyId: + type: + - number + - "null" + guestBreakdown: + type: + - object + - "null" + properties: + actualAdr: + type: + - string + - "null" + balance: + type: + - string + - "null" + discount: + type: + - string + - "null" + discountTotal: + type: + - string + - "null" + folioCharges: + type: + - string + - "null" + grandTotal: + type: + - string + - "null" + grossRent: + type: + - string + - "null" + guestAdr: + type: + - string + - "null" + guestFees: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + displayAs: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + quantity: + type: + - number + - "null" + unitValue: + type: + - string + - "null" + value: + type: + - string + - "null" + guestGrossDisplayRent: + type: + - string + - "null" + guestNetDisplayRent: + type: + - string + - "null" + guestSubtotal: + type: + - string + - "null" + netPayments: + type: + - string + - "null" + netRent: + type: + - string + - "null" + netTransfers: + type: + - string + - "null" + payments: + type: + - string + - "null" + promoValue: + type: + - string + - "null" + refunds: + type: + - string + - "null" + subtotal: + type: + - string + - "null" + taxes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + id: + type: + - number + - string + - "null" + name: + type: + - string + - "null" + total: + type: + - string + - "null" + totalGuestFees: + type: + - string + - "null" + totalGuestTaxes: + type: + - string + - "null" + totalItemizedFees: + type: + - string + - "null" + totalRentFees: + type: + - string + - "null" + totalServiceFees: + type: + - string + - "null" + totalTaxFees: + type: + - string + - "null" + totalTaxes: + type: + - string + - "null" + holdExpiresAt: + type: + - string + - "null" + id: + type: number + inviteUuid: + type: + - string + - "null" + isChannelLocked: + type: + - boolean + - "null" + isTaxable: + type: + - boolean + - "null" + isUnitAssigned: + type: + - boolean + - "null" + isUnitLocked: + type: + - boolean + - "null" + isUnitTypeLocked: + type: + - boolean + - "null" + lateDeparture: + type: + - boolean + - "null" + nights: + type: + - number + - "null" + occupants: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + extraQuantity: + type: + - number + - "null" + handle: + type: + - string + - "null" + included: + type: + - number + - "null" + name: + type: + - string + - "null" + quantity: + type: + - number + - "null" + ratePerPersonPerStay: + type: + - string + - "null" + ratePerStay: + type: + - string + - "null" + typeId: + type: + - number + - "null" + ownerBreakdown: + type: + - object + - "null" + properties: + agentCommission: + type: + - string + - "null" + feeRevenue: + type: + - string + - "null" + grossRent: + type: + - string + - "null" + grossRevenue: + type: + - string + - "null" + managerCommission: + type: + - string + - "null" + netRevenue: + type: + - string + - "null" + ownerFees: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + displayAs: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + quantity: + type: + - number + - "null" + unitValue: + type: + - string + - "null" + value: + type: + - string + - "null" + paymentMethodId: + type: + - number + - "null" + promoCodeId: + type: + - number + - "null" + rateTypeId: + type: + - number + - "null" + revenueRealizedMethod: + type: + - string + - "null" + schedulePercentage1: + type: + - number + - "null" + schedulePercentage2: + type: + - number + - "null" + securityDeposit: + type: + - object + - "null" + properties: + remaining: + type: + - number + - "null" + required: + type: + - string + - "null" + source: + type: + - string + - "null" + status: + type: + - string + - "null" + travelAgentId: + type: + - number + - "null" + typeId: + type: + - number + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: string + updatedBy: + type: + - string + - "null" + userId: + type: + - number + - "null" + uuid: + type: + - string + - "null" + required: + - id + - updatedAt + reservation-types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + autoSelect: + type: + - boolean + - "null" + chargeRates: + type: + - boolean + - "null" + chargeRent: + type: + - string + - "null" + cleaningOptionsId: + type: + - number + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + deferDisbursement: + type: + - boolean + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + isCommissionable: + type: + - boolean + - "null" + isDefault: + type: + - boolean + - "null" + isLocked: + type: + - boolean + - "null" + isOwner: + type: + - boolean + - "null" + midStayServiceScheduleId: + type: + - number + - "null" + name: + type: + - string + - "null" + ownerStay: + type: + - boolean + - "null" + personalUse: + type: + - boolean + - "null" + portalReservationBreakdown: + type: + - boolean + - "null" + posDefaultAllow: + type: + - boolean + - "null" + posDefaultLimit: + type: + - string + - "null" + publicName: + type: + - string + - "null" + realizeRates: + type: + - string + - "null" + rentEarned: + type: + - string + - "null" + requirePayment: + type: + - boolean + - "null" + requiresAgreement: + type: + - boolean + - "null" + schedulePercentage1: + type: + - number + - "null" + schedulePercentage2: + type: + - number + - "null" + sendPortalInvites: + type: + - boolean + - "null" + showFolioTransactions: + type: + - boolean + - "null" + typeColor: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + achAccountNumber: + type: + - string + - "null" + achAccountType: + type: + - string + - "null" + achRoutingNumber: + type: + - string + - "null" + cellPhone: + type: + - string + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + custom_5: + type: + - string + - "null" + custom_6: + type: + - string + - "null" + extendedAddress: + type: + - string + - "null" + firstName: + type: + - string + - "null" + homePhone: + type: + - string + - "null" + id: + type: number + isBlacklist: + type: + - boolean + - "null" + isDNR: + type: + - boolean + - "null" + isOwnerContact: + type: + - boolean + - "null" + isVip: + type: + - boolean + - "null" + lastName: + type: + - string + - "null" + locality: + type: + - string + - "null" + name: + type: + - string + - "null" + noIdentity: + type: + - boolean + - "null" + notes: + type: + - string + - "null" + otherPhone: + type: + - string + - "null" + paymentType: + type: + - string + - "null" + portalInviteStatus: + type: + - string + - "null" + portalLastLogin: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + primaryEmail: + type: + - string + - "null" + quoteCount: + type: + - string + - "null" + references: + type: + - array + - "null" + region: + type: + - string + - "null" + secondaryEmail: + type: + - string + - "null" + streetAddress: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + taxId: + type: + - string + - "null" + updatedAt: + type: string + updatedBy: + type: + - string + - "null" + workPhone: + type: + - string + - "null" + required: + - id + - updatedAt + tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + color: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + relatedTo: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + unit-types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + properties: + calendarGroup: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + allowOversell: + type: + - boolean + - "null" + allowUnitRates: + type: + - boolean + - "null" + amenitiesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + bedTypes: + type: + - array + - "null" + calendarGroupId: + type: + - number + - "null" + cancellationPoliciesIds: + type: + - array + - "null" + childrenAllowed: + type: + - boolean + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + pms_unit_types_pre_arrival_info: + type: + - string + - "null" + documentsIds: + type: + - array + - "null" + eventsAllowed: + type: + - boolean + - "null" + folioException: + type: + - boolean + - "null" + gatewaysIds: + type: + - array + - "null" + guaranteePoliciesIds: + type: + - array + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + id: + type: number + isAccessible: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isBookable: + type: + - boolean + - "null" + lodgingTypeId: + type: + - number + - "null" + name: + type: + - string + - "null" + oversellLimit: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + roles: + type: + - array + - "null" + securityDeposit: + type: + - string + - "null" + shortName: + type: + - string + - "null" + smokingAllowed: + type: + - boolean + - "null" + typeCode: + type: + - string + - "null" + updated: + type: + - object + - "null" + properties: + availability: + type: + - string + - "null" + content: + type: + - string + - "null" + pricing: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + useBedTypes: + type: + - boolean + - "null" + useRoomConfiguration: + type: + - boolean + - "null" + required: + - id + lodging-types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + airbnbRoomType: + type: + - string + - "null" + airbnbTypeCategory: + type: + - string + - "null" + airbnbTypeGroup: + type: + - string + - "null" + bookingDotComType: + type: + - number + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + homeawayType: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + marriottType: + type: + - string + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + tax-districts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + breakpoint: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + hasBreakpoint: + type: + - boolean + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + longTermPolicyId: + type: + - number + - "null" + name: + type: + - string + - "null" + salesTaxPolicyId: + type: + - number + - "null" + shortTermPolicyId: + type: + - number + - "null" + taxMarkup: + type: + - boolean + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + tax-policies: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + taxIds: + type: + - array + - "null" + items: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + taxes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + accountId: + type: + - number + - "null" + airbnbTaxType: + type: + - string + - "null" + bookingDotComTaxType: + type: + - string + - "null" + businessTaxId: + type: + - string + - "null" + channelTaxRemittance: + type: + - array + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + isExemptible: + type: + - boolean + - "null" + name: + type: + - string + - "null" + noBusinessTaxId: + type: + - string + - "null" + noTotRegistrationId: + type: + - string + - "null" + rateType: + type: + - string + - "null" + rentType: + type: + - string + - "null" + startDate: + type: + - string + - "null" + tax: + type: + - string + - "null" + totRegistrationId: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + travel-insurance-products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + allowCancelOverride: + type: + - boolean + - "null" + allowExternalNotification: + type: + - boolean + - "null" + changeMode: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + declineMessage: + type: + - string + - "null" + enableReporting: + type: + - boolean + - "null" + id: + type: number + insuranceType: + type: + - string + - "null" + irmEnabled: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + optOutWindow: + type: + - number + - "null" + payableAccountId: + type: + - number + - "null" + percent: + type: + - string + - "null" + producerCode: + type: + - string + - "null" + productClass: + type: + - string + - "null" + provider: + type: + - string + - "null" + realizeAfterWindow: + type: + - boolean + - "null" + revenueAccountId: + type: + - number + - "null" + selectedByDefault: + type: + - boolean + - "null" + split: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + companies: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + achAccountNumber: + type: + - string + - "null" + achAccountType: + type: + - string + - "null" + achRoutingNumber: + type: + - string + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + email: + type: + - string + - "null" + enableWorkOrderApproval: + type: + - boolean + - "null" + extendedAddress: + type: + - string + - "null" + fax: + type: + - string + - "null" + glInsurancePolicy: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + locality: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + paymentType: + type: + - string + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + region: + type: + - string + - "null" + streetAddress: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + taxId: + type: + - string + - "null" + taxName: + type: + - string + - "null" + taxType: + type: + - string + - "null" + travelAgentCommission: + type: + - number + - "null" + travelAgentDeductCommission: + type: + - boolean + - "null" + travelAgentIataNumber: + type: + - string + - "null" + updatedAt: + type: string + updatedBy: + type: + - string + - "null" + wcInsurancePolicy: + type: + - string + - "null" + website: + type: + - string + - "null" + required: + - id + - updatedAt + contracts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + code: + type: + - string + - "null" + commissionValues: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + commission: + type: + - string + - "null" + hasOverrides: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + overrides: + type: + - array + - "null" + typeId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + defaultCommission: + type: + - string + - "null" + defaultMarkup: + type: + - string + - "null" + hasPaymentFee: + type: + - boolean + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + items: + type: + - array + - "null" + maximumMarkup: + type: + - string + - "null" + minLosOwnerOverride: + type: + - boolean + - "null" + name: + type: + - string + - "null" + overrideType: + type: + - string + - "null" + paymentFee: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + fractionals_inventory: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + endDate: + type: + - string + - "null" + fraction_id: + type: number + id: + type: number + ownerId: + type: + - number + - "null" + startDate: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - fraction_id + - id + fractionals_owners: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + contractId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + fraction_id: + type: number + fractionalId: + type: + - number + - "null" + generateReservation: + type: + - boolean + - "null" + id: + type: number + ownerId: + type: + - number + - "null" + shares: + type: + - number + - "null" + startDate: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - fraction_id + - id + unit_type_daily_pricing_v2: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + rateTypeId: + type: number + rates: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + closed: + type: + - object + - "null" + properties: + arrival: + type: + - boolean + - "null" + date: + type: + - string + - "null" + occupancy: + type: + - array + - "null" + rate: + type: + - string + - "null" + stay: + type: + - object + - "null" + properties: + max: + type: + - number + - "null" + min: + type: + - number + - "null" + unit_type_id: + type: number + required: + - unit_type_id + - rateTypeId + unit_daily_pricing_v2: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + rateTypeId: + type: number + rates: + type: + - array + - "null" + unit_id: + type: number + required: + - unit_id + - rateTypeId + unit_taxes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + businessTaxId: + type: + - string + - "null" + id: + type: number + taxId: + type: + - number + - "null" + totRegistrationId: + type: + - string + - "null" + unitId: + type: + - number + - "null" + unit_id: + type: number + required: + - unit_id + - id + accounting-items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + isDeferExempted: + type: + - boolean + - "null" + isTaxable: + type: + - boolean + - "null" + itemCategories: + type: + - array + - "null" + items: + type: + - string + - "null" + name: + type: + - string + - "null" + revenueAccountId: + type: + - number + - "null" + taxPolicyId: + type: + - number + - "null" + taxPolicyType: + type: + - string + - "null" + unitPrice: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + accounting-accounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + stakeholder: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + achAccountNumber: + type: + - string + - "null" + achAccountType: + type: + - string + - "null" + achRoutingNumber: + type: + - string + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + email: + type: + - string + - "null" + enableWorkOrderApproval: + type: + - boolean + - "null" + extendedAddress: + type: + - string + - "null" + fax: + type: + - string + - "null" + glInsurancePolicy: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + locality: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + paymentType: + type: + - string + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + region: + type: + - string + - "null" + streetAddress: + type: + - string + - "null" + tags: + type: + - array + - "null" + taxId: + type: + - string + - "null" + taxName: + type: + - string + - "null" + taxType: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + wcInsurancePolicy: + type: + - string + - "null" + website: + type: + - string + - "null" + accountNumber: + type: + - string + - "null" + accountType: + type: + - string + - "null" + achEnabled: + type: + - boolean + - "null" + achOriginId: + type: + - string + - "null" + allowOwnerPayments: + type: + - boolean + - "null" + bankName: + type: + - string + - "null" + category: + type: + - string + - "null" + code: + type: + - string + - "null" + companyIdentification: + type: + - string + - "null" + companyName: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currentBalance: + type: + - string + - "null" + defaultRefundAccount: + type: + - boolean + - "null" + enableRefunds: + type: + - boolean + - "null" + id: + type: number + immediateDestination: + type: + - string + - "null" + immediateDestinationName: + type: + - string + - "null" + immediateOriginName: + type: + - string + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + parentId: + type: + - number + - "null" + recursiveBalance: + type: + - string + - "null" + routingNumber: + type: + - string + - "null" + stakeholderId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + accounting-transactions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + children: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + parent: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + reservation: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + unit: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + amount: + type: + - string + - "null" + companyId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currency: + type: + - string + - "null" + folioTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + folioId: + type: + - number + - "null" + id: + type: + - number + - "null" + isManual: + type: + - boolean + - "null" + isSecurityDeposit: + type: + - boolean + - "null" + securityDepositResolved: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isDeferred: + type: + - boolean + - "null" + isPending: + type: + - boolean + - "null" + isVoided: + type: + - boolean + - "null" + lines: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + account: + type: + - string + - "null" + accountId: + type: + - number + - "null" + amount: + type: + - string + - "null" + id: + type: + - number + - "null" + itemId: + type: + - number + - "null" + netAmount: + type: + - string + - "null" + quantity: + type: + - string + - "null" + remittanceBillId: + type: + - number + - "null" + taxAmount: + type: + - string + - "null" + taxOnMarkUp: + type: + - boolean + - "null" + unitAmount: + type: + - string + - "null" + unitId: + type: + - number + - "null" + unitName: + type: + - string + - "null" + memo: + type: + - string + - "null" + ownerTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + folioId: + type: + - number + - "null" + id: + type: + - number + - "null" + ownerId: + type: + - number + - "null" + statementId: + type: + - number + - "null" + parentId: + type: + - number + - "null" + subTotal: + type: + - string + - "null" + taxAmount: + type: + - string + - "null" + taxExempt: + type: + - boolean + - "null" + txnDate: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + parent: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + children: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + paymentType: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + account: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + commissionAccount: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + accountId: + type: + - number + - "null" + commissionAccountId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + handle: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + label: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + reservation: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + unit: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + altConf: + type: + - string + - "null" + arrivalDate: + type: + - string + - "null" + arrivalTime: + type: + - string + - "null" + departureDate: + type: + - string + - "null" + departureTime: + type: + - string + - "null" + earlyArrival: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isUnitAssigned: + type: + - boolean + - "null" + isUnitLocked: + type: + - boolean + - "null" + isUnitTypeLocked: + type: + - boolean + - "null" + lateDeparture: + type: + - boolean + - "null" + nights: + type: + - number + - "null" + occupants: + type: + - object + - "null" + properties: + "1": + type: + - number + - "null" + "2": + type: + - number + - "null" + "3": + type: + - number + - "null" + remainingSecurityDeposit: + type: + - number + - "null" + requiredSecurityDeposit: + type: + - number + - string + - "null" + softEnd: + type: + - string + - "null" + softStart: + type: + - string + - "null" + status: + type: + - string + - "null" + unitId: + type: + - number + - "null" + unit: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + type: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + cleanStatus: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + localOffice: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + lodgingType: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + node: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + taxDistrict: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + travelInsuranceProduct: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + amenitiesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + area: + type: + - number + - "null" + availabilityOrder: + type: + - number + - "null" + bedTypes: + type: + - array + - "null" + bedrooms: + type: + - number + - "null" + cancellationPoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + checkinTime: + type: + - string + - "null" + checkoutTime: + type: + - string + - "null" + childrenAllowed: + type: + - boolean + - "null" + cleanStatusId: + type: + - number + - "null" + cleanStatusType: + type: + - string + - "null" + composites: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + unitId: + type: + - number + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + pms_units_source_unit_id: + type: + - string + - "null" + pms_units_wifi_information: + type: + - string + - "null" + documentsIds: + type: + - array + - "null" + items: + type: + - number + - "null" + earlyCheckinTime: + type: + - string + - "null" + eventsAllowed: + type: + - boolean + - "null" + extendedAddress: + type: + - string + - "null" + folioException: + type: + - boolean + - "null" + fullBathrooms: + type: + - number + - "null" + gatewaysIds: + type: + - array + - "null" + items: + type: + - number + - "null" + guaranteePoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + halfBathrooms: + type: + - number + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + housekeepingMessage: + type: + - string + - "null" + housekeepingNotes: + type: + - string + - "null" + id: + type: + - number + - "null" + isAccessible: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isBookable: + type: + - boolean + - "null" + isLimited: + type: + - boolean + - "null" + isOccupied: + type: + - boolean + - "null" + lateCheckoutTime: + type: + - string + - "null" + latitude: + type: + - string + - "null" + localOfficeId: + type: + - number + - "null" + locality: + type: + - string + - "null" + lodgingTypeId: + type: + - number + - "null" + longitude: + type: + - string + - "null" + maxOccupancy: + type: + - number + - "null" + minimumAgeLimit: + type: + - number + - "null" + name: + type: + - string + - "null" + nodeId: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + region: + type: + - string + - "null" + roles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + roleId: + type: + - number + - "null" + userId: + type: + - number + - "null" + securityDeposit: + type: + - string + - "null" + shortName: + type: + - string + - "null" + smokingAllowed: + type: + - boolean + - "null" + streetAddress: + type: + - string + - "null" + taxDistrictId: + type: + - number + - "null" + taxId: + type: + - string + - "null" + threeQuarterBathrooms: + type: + - number + - "null" + timezone: + type: + - string + - "null" + travelInsuranceProductId: + type: + - number + - "null" + typeId: + type: + - number + - "null" + unitCode: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + useBedTypes: + type: + - boolean + - "null" + useRoomConfiguration: + type: + - boolean + - "null" + websiteUrl: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + amount: + type: + - string + - "null" + contactId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currency: + type: + - string + - "null" + depositId: + type: + - number + - "null" + folioTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + folioId: + type: + - number + - "null" + id: + type: + - number + - "null" + isManual: + type: + - boolean + - "null" + isSecurityDeposit: + type: + - boolean + - "null" + nights: + type: + - number + - "null" + roomNight: + type: + - string + - "null" + securityDepositResolved: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isAuthOnly: + type: + - boolean + - "null" + isDeferred: + type: + - boolean + - "null" + isPending: + type: + - boolean + - "null" + isVoided: + type: + - boolean + - "null" + lines: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + account: + type: + - string + - "null" + accountId: + type: + - number + - "null" + amount: + type: + - string + - "null" + id: + type: + - number + - "null" + itemId: + type: + - number + - "null" + netAmount: + type: + - string + - "null" + quantity: + type: + - string + - "null" + remittanceBillId: + type: + - number + - "null" + taxAmount: + type: + - string + - "null" + taxOnMarkUp: + type: + - boolean + - "null" + unitAmount: + type: + - string + - "null" + unitId: + type: + - number + - "null" + unitName: + type: + - string + - "null" + memo: + type: + - string + - "null" + ownerTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + folioId: + type: + - number + - "null" + id: + type: + - number + - "null" + ownerId: + type: + - number + - "null" + statementId: + type: + - number + - "null" + paymentTypeId: + type: + - number + - "null" + reference: + type: + - string + - "null" + subTotal: + type: + - string + - "null" + taxAmount: + type: + - string + - "null" + taxExempt: + type: + - boolean + - "null" + txnDate: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + vaultToken: + type: + - string + - "null" + paymentType: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + account: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + accountType: + type: + - string + - "null" + achEnabled: + type: + - boolean + - "null" + allowOwnerPayments: + type: + - boolean + - "null" + category: + type: + - string + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currentBalance: + type: + - string + - "null" + defaultRefundAccount: + type: + - boolean + - "null" + enableRefunds: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + recursiveBalance: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + commissionAccount: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + parent: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + stakeholder: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + accountType: + type: + - string + - "null" + achEnabled: + type: + - boolean + - "null" + allowOwnerPayments: + type: + - boolean + - "null" + category: + type: + - string + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currentBalance: + type: + - string + - "null" + defaultRefundAccount: + type: + - boolean + - "null" + enableRefunds: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + parentId: + type: + - number + - "null" + recursiveBalance: + type: + - string + - "null" + stakeholderId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + accountId: + type: + - number + - "null" + commissionAccountId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + handle: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + label: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + transaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + amount: + type: + - string + - "null" + contactId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currency: + type: + - string + - "null" + folioTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + folioId: + type: + - number + - "null" + id: + type: + - number + - "null" + isManual: + type: + - boolean + - "null" + isSecurityDeposit: + type: + - boolean + - "null" + securityDepositResolved: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isAuthOnly: + type: + - boolean + - "null" + isDeferred: + type: + - boolean + - "null" + isPending: + type: + - boolean + - "null" + isVoided: + type: + - boolean + - "null" + lines: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + account: + type: + - string + - "null" + accountId: + type: + - number + - "null" + amount: + type: + - string + - "null" + id: + type: + - number + - "null" + itemId: + type: + - number + - "null" + netAmount: + type: + - string + - "null" + quantity: + type: + - string + - "null" + remittanceBillId: + type: + - number + - "null" + taxAmount: + type: + - string + - "null" + taxOnMarkUp: + type: + - boolean + - "null" + unitAmount: + type: + - string + - "null" + unitId: + type: + - number + - "null" + unitName: + type: + - string + - "null" + memo: + type: + - string + - "null" + paymentTypeId: + type: + - number + - "null" + reference: + type: + - string + - "null" + subTotal: + type: + - string + - "null" + taxAmount: + type: + - string + - "null" + taxExempt: + type: + - boolean + - "null" + txnDate: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + workOrder: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + owner: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + achAccountNumber: + type: + - string + - "null" + achAccountType: + type: + - string + - "null" + achRoutingNumber: + type: + - string + - "null" + activeUnitCount: + type: + - number + - "null" + agentCommission: + type: + - string + - "null" + alwaysShowInStatements: + type: + - boolean + - "null" + companyId: + type: + - number + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currentBalance: + type: + - string + - "null" + deferredBalance: + type: + - string + - "null" + email: + type: + - string + - "null" + extendedAddress: + type: + - string + - "null" + fax: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + locality: + type: + - string + - "null" + minimumBalance: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + paymentType: + type: + - string + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + region: + type: + - string + - "null" + splitWithContacts: + type: + - boolean + - "null" + streetAddress: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + taxCountry: + type: + - string + - "null" + taxExtendedAddress: + type: + - string + - "null" + taxId: + type: + - string + - "null" + taxLocality: + type: + - string + - "null" + taxName: + type: + - string + - "null" + taxPostalCode: + type: + - string + - "null" + taxRegion: + type: + - string + - "null" + taxStreetAddress: + type: + - string + - "null" + taxType: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + website: + type: + - string + - "null" + unit: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + cleanStatus: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + area: + type: + - number + - "null" + availabilityOrder: + type: + - number + - "null" + bedTypes: + type: + - array + - "null" + bedrooms: + type: + - number + - "null" + checkinTime: + type: + - string + - "null" + checkoutTime: + type: + - string + - "null" + childrenAllowed: + type: + - boolean + - "null" + cleanStatusId: + type: + - number + - "null" + cleanStatusType: + type: + - string + - "null" + composites: + type: + - array + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + pms_units_owner_notes: + type: + - string + - "null" + pms_units_source_unit_id: + type: + - string + - "null" + pms_units_wifi_information: + type: + - string + - "null" + earlyCheckinTime: + type: + - string + - "null" + eventsAllowed: + type: + - boolean + - "null" + extendedAddress: + type: + - string + - "null" + floors: + type: + - number + - "null" + folioException: + type: + - boolean + - "null" + fullBathrooms: + type: + - number + - "null" + halfBathrooms: + type: + - number + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + housekeepingMessage: + type: + - string + - "null" + housekeepingNotes: + type: + - string + - "null" + id: + type: + - number + - "null" + isAccessible: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isBookable: + type: + - boolean + - "null" + isLimited: + type: + - boolean + - "null" + isOccupied: + type: + - boolean + - "null" + lateCheckoutTime: + type: + - string + - "null" + latitude: + type: + - string + - "null" + localOfficeId: + type: + - number + - "null" + locality: + type: + - string + - "null" + lodgingTypeId: + type: + - number + - "null" + longitude: + type: + - string + - "null" + maintenanceMessage: + type: + - string + - "null" + maxOccupancy: + type: + - number + - "null" + minimumAgeLimit: + type: + - number + - "null" + name: + type: + - string + - "null" + nodeId: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + region: + type: + - string + - "null" + roles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + roleId: + type: + - number + - "null" + userId: + type: + - number + - "null" + securityDeposit: + type: + - string + - "null" + shortName: + type: + - string + - "null" + smokingAllowed: + type: + - boolean + - "null" + streetAddress: + type: + - string + - "null" + taxDistrictId: + type: + - number + - "null" + taxId: + type: + - string + - "null" + threeQuarterBathrooms: + type: + - number + - "null" + timezone: + type: + - string + - "null" + travelInsuranceProductId: + type: + - number + - "null" + typeId: + type: + - number + - "null" + unitCode: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + useBedTypes: + type: + - boolean + - "null" + useRoomConfiguration: + type: + - boolean + - "null" + websiteUrl: + type: + - string + - "null" + user: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + vendor: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + achAccountNumber: + type: + - string + - "null" + achAccountType: + type: + - string + - "null" + achRoutingNumber: + type: + - string + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + email: + type: + - string + - "null" + enableWorkOrderApproval: + type: + - boolean + - "null" + extendedAddress: + type: + - string + - "null" + fax: + type: + - string + - "null" + glInsurancePolicy: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + locality: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + paymentType: + type: + - string + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + region: + type: + - string + - "null" + streetAddress: + type: + - string + - "null" + tags: + type: + - array + - "null" + taxId: + type: + - string + - "null" + taxName: + type: + - string + - "null" + taxType: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + wcInsurancePolicy: + type: + - string + - "null" + website: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + actualTime: + type: + - number + - "null" + assignees: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + assignable: + type: + - array + - "null" + items: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + isLead: + type: + - boolean + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + role: + type: + - object + - "null" + properties: + __cloner__: + type: + - object + - "null" + __initializer__: + type: + - object + - "null" + __isInitialized__: + type: + - boolean + - "null" + updatedBy: + type: + - string + - "null" + username: + type: + - string + - "null" + vendorId: + type: + - number + - "null" + blockCheckin: + type: + - boolean + - "null" + completedById: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + dateCompleted: + type: + - string + - "null" + dateProcessed: + type: + - string + - "null" + dateReceived: + type: + - string + - "null" + dateScheduled: + type: + - string + - "null" + id: + type: + - number + - "null" + ownerId: + type: + - number + - "null" + priority: + type: + - number + - "null" + problems: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + processedById: + type: + - number + - "null" + referenceNumber: + type: + - string + - "null" + source: + type: + - string + - "null" + sourceName: + type: + - string + - "null" + sourcePhone: + type: + - string + - "null" + status: + type: + - string + - "null" + summary: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + userId: + type: + - number + - "null" + vendorId: + type: + - number + - "null" + workPerformed: + type: + - string + - "null" + amount: + type: + - string + - "null" + companyId: + type: + - number + - "null" + contactId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currency: + type: + - string + - "null" + depositId: + type: + - number + - "null" + folioTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + chargeId: + type: + - number + - "null" + folioId: + type: + - number + - "null" + id: + type: + - number + - "null" + isManual: + type: + - boolean + - "null" + isSecurityDeposit: + type: + - boolean + - "null" + nights: + type: + - number + - "null" + reservationFeeId: + type: + - number + - "null" + roomNight: + type: + - string + - "null" + securityDepositResolved: + type: + - boolean + - "null" + id: + type: number + isAuthOnly: + type: + - boolean + - "null" + isDeferred: + type: + - boolean + - "null" + isPending: + type: + - boolean + - "null" + isVoided: + type: + - boolean + - "null" + lines: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + account: + type: + - string + - "null" + accountId: + type: + - number + - "null" + amount: + type: + - string + - "null" + id: + type: + - number + - "null" + itemId: + type: + - number + - "null" + netAmount: + type: + - string + - "null" + quantity: + type: + - string + - "null" + remittanceBillId: + type: + - number + - "null" + taxAmount: + type: + - string + - "null" + taxOnMarkUp: + type: + - boolean + - "null" + unitAmount: + type: + - string + - "null" + unitId: + type: + - number + - "null" + unitName: + type: + - string + - "null" + memo: + type: + - string + - "null" + ownerTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + folioId: + type: + - number + - "null" + id: + type: + - number + - "null" + ownerId: + type: + - number + - "null" + reservationFeeId: + type: + - number + - "null" + statementId: + type: + - number + - "null" + parentId: + type: + - number + - "null" + paymentTypeId: + type: + - number + - "null" + publicMemo: + type: + - string + - "null" + reference: + type: + - string + - "null" + subTotal: + type: + - string + - "null" + taxAmount: + type: + - string + - "null" + taxExempt: + type: + - boolean + - "null" + transactionId: + type: + - number + - "null" + txnDate: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + vaultToken: + type: + - string + - "null" + voidReason: + type: + - string + - "null" + workOrderId: + type: + - number + - "null" + required: + - id + accounting-bills: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + APAccountId: + type: + - number + - "null" + _embedded: + type: + - object + - "null" + amount: + type: + - string + - "null" + balance: + type: + - string + - "null" + billType: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currency: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + id: + type: number + invoiceNumber: + type: + - string + - "null" + isDeferred: + type: + - boolean + - "null" + isPending: + type: + - boolean + - "null" + isVoided: + type: + - boolean + - "null" + lines: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + account: + type: + - string + - "null" + accountId: + type: + - number + - "null" + amount: + type: + - string + - "null" + id: + type: + - number + - "null" + markup: + type: + - string + - "null" + remittanceBillId: + type: + - number + - "null" + taxOnMarkUp: + type: + - boolean + - "null" + unitAmount: + type: + - string + - "null" + unitId: + type: + - number + - "null" + unitName: + type: + - string + - "null" + memo: + type: + - string + - "null" + terms: + type: + - string + - "null" + txnDate: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + vendorId: + type: + - number + - "null" + vendorName: + type: + - string + - "null" + workOrderId: + type: + - number + - "null" + required: + - id + accounting-charges: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + children: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + parent: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + children: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + reservation: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + unit: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + amount: + type: + - string + - "null" + contactId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currency: + type: + - string + - "null" + folioTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + folioId: + type: + - number + - "null" + id: + type: + - number + - "null" + isManual: + type: + - boolean + - "null" + isSecurityDeposit: + type: + - boolean + - "null" + nights: + type: + - number + - "null" + roomNight: + type: + - string + - "null" + securityDepositResolved: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isDeferred: + type: + - boolean + - "null" + isPending: + type: + - boolean + - "null" + isVoided: + type: + - boolean + - "null" + lines: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + account: + type: + - string + - "null" + accountId: + type: + - number + - "null" + amount: + type: + - string + - "null" + id: + type: + - number + - "null" + itemId: + type: + - number + - "null" + netAmount: + type: + - string + - "null" + quantity: + type: + - string + - "null" + remittanceBillId: + type: + - number + - "null" + taxAmount: + type: + - string + - "null" + taxOnMarkUp: + type: + - boolean + - "null" + unitAmount: + type: + - string + - "null" + unitId: + type: + - number + - "null" + unitName: + type: + - string + - "null" + memo: + type: + - string + - "null" + ownerTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + folioId: + type: + - number + - "null" + id: + type: + - number + - "null" + ownerId: + type: + - number + - "null" + statementId: + type: + - number + - "null" + subTotal: + type: + - string + - "null" + taxAmount: + type: + - string + - "null" + taxExempt: + type: + - boolean + - "null" + txnDate: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + reservation: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + unit: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + altConf: + type: + - string + - "null" + arrivalDate: + type: + - string + - "null" + arrivalTime: + type: + - string + - "null" + departureDate: + type: + - string + - "null" + departureTime: + type: + - string + - "null" + earlyArrival: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isUnitAssigned: + type: + - boolean + - "null" + isUnitLocked: + type: + - boolean + - "null" + isUnitTypeLocked: + type: + - boolean + - "null" + lateDeparture: + type: + - boolean + - "null" + nights: + type: + - number + - "null" + occupants: + type: + - object + - "null" + properties: + "1": + type: + - number + - "null" + "2": + type: + - number + - "null" + "3": + type: + - number + - "null" + remainingSecurityDeposit: + type: + - number + - "null" + requiredSecurityDeposit: + type: + - number + - string + - "null" + softEnd: + type: + - string + - "null" + softStart: + type: + - string + - "null" + status: + type: + - string + - "null" + unitId: + type: + - number + - "null" + unit: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + type: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + cleanStatus: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + localOffice: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + lodgingType: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + node: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + taxDistrict: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + travelInsuranceProduct: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + amenitiesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + area: + type: + - number + - "null" + availabilityOrder: + type: + - number + - "null" + bedTypes: + type: + - array + - "null" + bedrooms: + type: + - number + - "null" + cancellationPoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + checkinTime: + type: + - string + - "null" + checkoutTime: + type: + - string + - "null" + childrenAllowed: + type: + - boolean + - "null" + cleanStatusId: + type: + - number + - "null" + cleanStatusType: + type: + - string + - "null" + composites: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + unitId: + type: + - number + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + pms_units_owner_notes: + type: + - string + - "null" + pms_units_source_unit_id: + type: + - string + - "null" + pms_units_wifi_information: + type: + - string + - "null" + documentsIds: + type: + - array + - "null" + items: + type: + - number + - "null" + earlyCheckinTime: + type: + - string + - "null" + eventsAllowed: + type: + - boolean + - "null" + extendedAddress: + type: + - string + - "null" + folioException: + type: + - boolean + - "null" + fullBathrooms: + type: + - number + - "null" + gatewaysIds: + type: + - array + - "null" + items: + type: + - number + - "null" + guaranteePoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + halfBathrooms: + type: + - number + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + housekeepingMessage: + type: + - string + - "null" + housekeepingNotes: + type: + - string + - "null" + id: + type: + - number + - "null" + isAccessible: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isBookable: + type: + - boolean + - "null" + isLimited: + type: + - boolean + - "null" + isOccupied: + type: + - boolean + - "null" + lateCheckoutTime: + type: + - string + - "null" + latitude: + type: + - string + - "null" + localOfficeId: + type: + - number + - "null" + locality: + type: + - string + - "null" + lodgingTypeId: + type: + - number + - "null" + longitude: + type: + - string + - "null" + maxOccupancy: + type: + - number + - "null" + minimumAgeLimit: + type: + - number + - "null" + name: + type: + - string + - "null" + nodeId: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + region: + type: + - string + - "null" + roles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + roleId: + type: + - number + - "null" + userId: + type: + - number + - "null" + securityDeposit: + type: + - string + - "null" + shortName: + type: + - string + - "null" + smokingAllowed: + type: + - boolean + - "null" + streetAddress: + type: + - string + - "null" + taxDistrictId: + type: + - number + - "null" + taxId: + type: + - string + - "null" + threeQuarterBathrooms: + type: + - number + - "null" + timezone: + type: + - string + - "null" + travelInsuranceProductId: + type: + - number + - "null" + typeId: + type: + - number + - "null" + unitCode: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + useBedTypes: + type: + - boolean + - "null" + useRoomConfiguration: + type: + - boolean + - "null" + websiteUrl: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + amount: + type: + - string + - "null" + companyId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currency: + type: + - string + - "null" + id: + type: + - number + - "null" + isDeferred: + type: + - boolean + - "null" + isPending: + type: + - boolean + - "null" + isVoided: + type: + - boolean + - "null" + lines: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + account: + type: + - string + - "null" + accountId: + type: + - number + - "null" + amount: + type: + - string + - "null" + id: + type: + - number + - "null" + itemId: + type: + - number + - "null" + netAmount: + type: + - string + - "null" + quantity: + type: + - string + - "null" + remittanceBillId: + type: + - number + - "null" + taxAmount: + type: + - string + - "null" + taxOnMarkUp: + type: + - boolean + - "null" + unitAmount: + type: + - string + - "null" + unitId: + type: + - number + - "null" + unitName: + type: + - string + - "null" + ownerTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + folioId: + type: + - number + - "null" + id: + type: + - number + - "null" + ownerId: + type: + - number + - "null" + statementId: + type: + - number + - "null" + parentId: + type: + - number + - "null" + subTotal: + type: + - string + - "null" + taxAmount: + type: + - string + - "null" + taxExempt: + type: + - boolean + - "null" + txnDate: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + parent: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + children: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + parent: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + reservation: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + unit: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + amount: + type: + - string + - "null" + companyId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currency: + type: + - string + - "null" + id: + type: + - number + - "null" + isDeferred: + type: + - boolean + - "null" + isPending: + type: + - boolean + - "null" + isVoided: + type: + - boolean + - "null" + lines: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + account: + type: + - string + - "null" + accountId: + type: + - number + - "null" + amount: + type: + - string + - "null" + id: + type: + - number + - "null" + itemId: + type: + - number + - "null" + netAmount: + type: + - string + - "null" + quantity: + type: + - string + - "null" + remittanceBillId: + type: + - number + - "null" + taxAmount: + type: + - string + - "null" + taxOnMarkUp: + type: + - boolean + - "null" + unitAmount: + type: + - string + - "null" + unitId: + type: + - number + - "null" + unitName: + type: + - string + - "null" + memo: + type: + - string + - "null" + ownerTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + folioId: + type: + - number + - "null" + id: + type: + - number + - "null" + ownerId: + type: + - number + - "null" + statementId: + type: + - number + - "null" + parentId: + type: + - number + - "null" + subTotal: + type: + - string + - "null" + taxAmount: + type: + - string + - "null" + taxExempt: + type: + - boolean + - "null" + txnDate: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + paymentType: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + account: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + accountType: + type: + - string + - "null" + achEnabled: + type: + - boolean + - "null" + allowOwnerPayments: + type: + - boolean + - "null" + category: + type: + - string + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currentBalance: + type: + - string + - "null" + defaultRefundAccount: + type: + - boolean + - "null" + enableRefunds: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + recursiveBalance: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + commissionAccount: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + parent: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + stakeholder: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + accountType: + type: + - string + - "null" + achEnabled: + type: + - boolean + - "null" + allowOwnerPayments: + type: + - boolean + - "null" + category: + type: + - string + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currentBalance: + type: + - string + - "null" + defaultRefundAccount: + type: + - boolean + - "null" + enableRefunds: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + parentId: + type: + - number + - "null" + recursiveBalance: + type: + - string + - "null" + stakeholderId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + accountId: + type: + - number + - "null" + commissionAccountId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + handle: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + label: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + reservation: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + unit: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + type: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + cleanStatus: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + localOffice: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + lodgingType: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + node: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + taxDistrict: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + travelInsuranceProduct: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + amenitiesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + area: + type: + - number + - "null" + availabilityOrder: + type: + - number + - "null" + bedTypes: + type: + - array + - "null" + bedrooms: + type: + - number + - "null" + cancellationPoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + checkinTime: + type: + - string + - "null" + checkoutTime: + type: + - string + - "null" + childrenAllowed: + type: + - boolean + - "null" + cleanStatusId: + type: + - number + - "null" + cleanStatusType: + type: + - string + - "null" + composites: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + unitId: + type: + - number + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + pms_units_owner_notes: + type: + - string + - "null" + pms_units_source_unit_id: + type: + - string + - "null" + pms_units_wifi_information: + type: + - string + - "null" + documentsIds: + type: + - array + - "null" + items: + type: + - number + - "null" + earlyCheckinTime: + type: + - string + - "null" + eventsAllowed: + type: + - boolean + - "null" + extendedAddress: + type: + - string + - "null" + folioException: + type: + - boolean + - "null" + fullBathrooms: + type: + - number + - "null" + gatewaysIds: + type: + - array + - "null" + items: + type: + - number + - "null" + guaranteePoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + halfBathrooms: + type: + - number + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + housekeepingMessage: + type: + - string + - "null" + housekeepingNotes: + type: + - string + - "null" + id: + type: + - number + - "null" + isAccessible: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isBookable: + type: + - boolean + - "null" + isLimited: + type: + - boolean + - "null" + isOccupied: + type: + - boolean + - "null" + lateCheckoutTime: + type: + - string + - "null" + latitude: + type: + - string + - "null" + localOfficeId: + type: + - number + - "null" + locality: + type: + - string + - "null" + lodgingTypeId: + type: + - number + - "null" + longitude: + type: + - string + - "null" + maxOccupancy: + type: + - number + - "null" + minimumAgeLimit: + type: + - number + - "null" + name: + type: + - string + - "null" + nodeId: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + region: + type: + - string + - "null" + roles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + roleId: + type: + - number + - "null" + userId: + type: + - number + - "null" + securityDeposit: + type: + - string + - "null" + shortName: + type: + - string + - "null" + smokingAllowed: + type: + - boolean + - "null" + streetAddress: + type: + - string + - "null" + taxDistrictId: + type: + - number + - "null" + taxId: + type: + - string + - "null" + threeQuarterBathrooms: + type: + - number + - "null" + timezone: + type: + - string + - "null" + travelInsuranceProductId: + type: + - number + - "null" + typeId: + type: + - number + - "null" + unitCode: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + useBedTypes: + type: + - boolean + - "null" + useRoomConfiguration: + type: + - boolean + - "null" + websiteUrl: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + altConf: + type: + - string + - "null" + arrivalDate: + type: + - string + - "null" + arrivalTime: + type: + - string + - "null" + cancelledAt: + type: + - string + - "null" + departureDate: + type: + - string + - "null" + departureTime: + type: + - string + - "null" + earlyArrival: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isUnitAssigned: + type: + - boolean + - "null" + isUnitLocked: + type: + - boolean + - "null" + isUnitTypeLocked: + type: + - boolean + - "null" + lateDeparture: + type: + - boolean + - "null" + nights: + type: + - number + - "null" + occupants: + type: + - object + - "null" + properties: + "1": + type: + - number + - "null" + "2": + type: + - number + - "null" + "3": + type: + - number + - "null" + remainingSecurityDeposit: + type: + - number + - "null" + requiredSecurityDeposit: + type: + - number + - string + - "null" + softEnd: + type: + - string + - "null" + softStart: + type: + - string + - "null" + status: + type: + - string + - "null" + unitId: + type: + - number + - "null" + unit: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + type: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + calendarGroup: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + lodgingType: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + allowOversell: + type: + - boolean + - "null" + allowUnitRates: + type: + - boolean + - "null" + amenitiesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + bedTypes: + type: + - array + - "null" + calendarGroupId: + type: + - number + - "null" + cancellationPoliciesIds: + type: + - array + - "null" + childrenAllowed: + type: + - boolean + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + pms_unit_types_pre_arrival_info: + type: + - string + - "null" + documentsIds: + type: + - array + - "null" + eventsAllowed: + type: + - boolean + - "null" + folioException: + type: + - boolean + - "null" + gatewaysIds: + type: + - array + - "null" + guaranteePoliciesIds: + type: + - array + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isAccessible: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isBookable: + type: + - boolean + - "null" + lodgingTypeId: + type: + - number + - "null" + name: + type: + - string + - "null" + oversellLimit: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + roles: + type: + - array + - "null" + securityDeposit: + type: + - string + - "null" + shortName: + type: + - string + - "null" + smokingAllowed: + type: + - boolean + - "null" + typeCode: + type: + - string + - "null" + updated: + type: + - object + - "null" + properties: + availability: + type: + - string + - "null" + content: + type: + - string + - "null" + pricing: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + useBedTypes: + type: + - boolean + - "null" + useRoomConfiguration: + type: + - boolean + - "null" + cleanStatus: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + localOffice: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + directions: + type: + - string + - "null" + email: + type: + - string + - "null" + extendedAddress: + type: + - string + - "null" + id: + type: + - number + - "null" + latitude: + type: + - string + - "null" + locality: + type: + - string + - "null" + longitude: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + region: + type: + - string + - "null" + streetAddress: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + lodgingType: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + airbnbRoomType: + type: + - string + - "null" + airbnbTypeCategory: + type: + - string + - "null" + airbnbTypeGroup: + type: + - string + - "null" + bookingDotComType: + type: + - number + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + homeawayType: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + marriottType: + type: + - string + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + node: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + type: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + localOffice: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + parent: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + taxDistrict: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + amenitiesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + cancellationPoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + checkinTime: + type: + - string + - "null" + checkoutTime: + type: + - string + - "null" + childrenAllowed: + type: + - boolean + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: {} + documentsIds: + type: + - array + - "null" + items: + type: + - number + - "null" + earlyCheckinTime: + type: + - string + - "null" + eventsAllowed: + type: + - boolean + - "null" + gatewaysIds: + type: + - array + - "null" + items: + type: + - number + - "null" + guaranteePoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isAccessible: + type: + - boolean + - "null" + lateCheckoutTime: + type: + - string + - "null" + localOfficeId: + type: + - number + - "null" + locality: + type: + - string + - "null" + minimumAgeLimit: + type: + - number + - "null" + name: + type: + - string + - "null" + parentId: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + region: + type: + - string + - "null" + roles: + type: + - array + - "null" + smokingAllowed: + type: + - boolean + - "null" + taxDistrictId: + type: + - number + - "null" + timezone: + type: + - string + - "null" + typeId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + taxDistrict: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + longTermPolicy: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + salesTaxPolicy: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + shortTermPolicy: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + breakpoint: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + hasBreakpoint: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + longTermPolicyId: + type: + - number + - "null" + name: + type: + - string + - "null" + salesTaxPolicyId: + type: + - number + - "null" + shortTermPolicyId: + type: + - number + - "null" + taxMarkup: + type: + - boolean + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + travelInsuranceProduct: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + allowCancelOverride: + type: + - boolean + - "null" + allowExternalNotification: + type: + - boolean + - "null" + changeMode: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + declineMessage: + type: + - string + - "null" + enableReporting: + type: + - boolean + - "null" + id: + type: + - number + - "null" + insuranceType: + type: + - string + - "null" + irmEnabled: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + optOutWindow: + type: + - number + - "null" + payableAccountId: + type: + - number + - "null" + percent: + type: + - string + - "null" + producerCode: + type: + - string + - "null" + productClass: + type: + - string + - "null" + provider: + type: + - string + - "null" + realizeAfterWindow: + type: + - boolean + - "null" + revenueAccountId: + type: + - number + - "null" + selectedByDefault: + type: + - boolean + - "null" + split: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + amenitiesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + area: + type: + - number + - "null" + availabilityOrder: + type: + - number + - "null" + bedTypes: + type: + - array + - "null" + bedrooms: + type: + - number + - "null" + cancellationPoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + checkinTime: + type: + - string + - "null" + checkoutTime: + type: + - string + - "null" + childrenAllowed: + type: + - boolean + - "null" + cleanStatusId: + type: + - number + - "null" + cleanStatusType: + type: + - string + - "null" + composites: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + unitId: + type: + - number + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + pms_units_owner_notes: + type: + - string + - "null" + pms_units_source_unit_id: + type: + - string + - "null" + pms_units_wifi_information: + type: + - string + - "null" + documentsIds: + type: + - array + - "null" + items: + type: + - number + - "null" + earlyCheckinTime: + type: + - string + - "null" + eventsAllowed: + type: + - boolean + - "null" + extendedAddress: + type: + - string + - "null" + folioException: + type: + - boolean + - "null" + fullBathrooms: + type: + - number + - "null" + gatewaysIds: + type: + - array + - "null" + items: + type: + - number + - "null" + guaranteePoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + halfBathrooms: + type: + - number + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + housekeepingMessage: + type: + - string + - "null" + housekeepingNotes: + type: + - string + - "null" + id: + type: + - number + - "null" + isAccessible: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isBookable: + type: + - boolean + - "null" + isLimited: + type: + - boolean + - "null" + isOccupied: + type: + - boolean + - "null" + lateCheckoutTime: + type: + - string + - "null" + latitude: + type: + - string + - "null" + localOfficeId: + type: + - number + - "null" + locality: + type: + - string + - "null" + lodgingTypeId: + type: + - number + - "null" + longitude: + type: + - string + - "null" + maxOccupancy: + type: + - number + - "null" + minimumAgeLimit: + type: + - number + - "null" + name: + type: + - string + - "null" + nodeId: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + region: + type: + - string + - "null" + roles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + roleId: + type: + - number + - "null" + userId: + type: + - number + - "null" + securityDeposit: + type: + - string + - "null" + shortName: + type: + - string + - "null" + smokingAllowed: + type: + - boolean + - "null" + streetAddress: + type: + - string + - "null" + taxDistrictId: + type: + - number + - "null" + taxId: + type: + - string + - "null" + threeQuarterBathrooms: + type: + - number + - "null" + timezone: + type: + - string + - "null" + travelInsuranceProductId: + type: + - number + - "null" + typeId: + type: + - number + - "null" + unitCode: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + useBedTypes: + type: + - boolean + - "null" + useRoomConfiguration: + type: + - boolean + - "null" + websiteUrl: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + amount: + type: + - string + - "null" + contactId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currency: + type: + - string + - "null" + depositId: + type: + - number + - "null" + folioTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + folioId: + type: + - number + - "null" + id: + type: + - number + - "null" + isManual: + type: + - boolean + - "null" + isSecurityDeposit: + type: + - boolean + - "null" + nights: + type: + - number + - "null" + roomNight: + type: + - string + - "null" + securityDepositResolved: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isAuthOnly: + type: + - boolean + - "null" + isDeferred: + type: + - boolean + - "null" + isPending: + type: + - boolean + - "null" + isVoided: + type: + - boolean + - "null" + lines: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + account: + type: + - string + - "null" + accountId: + type: + - number + - "null" + amount: + type: + - string + - "null" + id: + type: + - number + - "null" + itemId: + type: + - number + - "null" + netAmount: + type: + - string + - "null" + quantity: + type: + - string + - "null" + remittanceBillId: + type: + - number + - "null" + taxAmount: + type: + - string + - "null" + taxOnMarkUp: + type: + - boolean + - "null" + unitAmount: + type: + - string + - "null" + unitId: + type: + - number + - "null" + unitName: + type: + - string + - "null" + memo: + type: + - string + - "null" + ownerTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + folioId: + type: + - number + - "null" + id: + type: + - number + - "null" + ownerId: + type: + - number + - "null" + statementId: + type: + - number + - "null" + paymentTypeId: + type: + - number + - "null" + reference: + type: + - string + - "null" + subTotal: + type: + - string + - "null" + taxAmount: + type: + - string + - "null" + taxExempt: + type: + - boolean + - "null" + txnDate: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + vaultToken: + type: + - string + - "null" + reservation: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + unit: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + type: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + calendarGroup: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + lodgingType: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + allowOversell: + type: + - boolean + - "null" + allowUnitRates: + type: + - boolean + - "null" + amenitiesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + bedTypes: + type: + - array + - "null" + calendarGroupId: + type: + - number + - "null" + cancellationPoliciesIds: + type: + - array + - "null" + childrenAllowed: + type: + - boolean + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + pms_unit_types_pre_arrival_info: + type: + - string + - "null" + documentsIds: + type: + - array + - "null" + eventsAllowed: + type: + - boolean + - "null" + folioException: + type: + - boolean + - "null" + gatewaysIds: + type: + - array + - "null" + guaranteePoliciesIds: + type: + - array + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isAccessible: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isBookable: + type: + - boolean + - "null" + lodgingTypeId: + type: + - number + - "null" + name: + type: + - string + - "null" + oversellLimit: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + roles: + type: + - array + - "null" + securityDeposit: + type: + - string + - "null" + shortName: + type: + - string + - "null" + smokingAllowed: + type: + - boolean + - "null" + typeCode: + type: + - string + - "null" + updated: + type: + - object + - "null" + properties: + availability: + type: + - string + - "null" + content: + type: + - string + - "null" + pricing: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + useBedTypes: + type: + - boolean + - "null" + useRoomConfiguration: + type: + - boolean + - "null" + cleanStatus: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + localOffice: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + directions: + type: + - string + - "null" + email: + type: + - string + - "null" + extendedAddress: + type: + - string + - "null" + id: + type: + - number + - "null" + latitude: + type: + - string + - "null" + locality: + type: + - string + - "null" + longitude: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + region: + type: + - string + - "null" + streetAddress: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + lodgingType: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + airbnbRoomType: + type: + - string + - "null" + airbnbTypeCategory: + type: + - string + - "null" + airbnbTypeGroup: + type: + - string + - "null" + bookingDotComType: + type: + - number + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + homeawayType: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + marriottType: + type: + - string + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + node: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + type: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + localOffice: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + parent: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + taxDistrict: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + amenitiesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + cancellationPoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + checkinTime: + type: + - string + - "null" + checkoutTime: + type: + - string + - "null" + childrenAllowed: + type: + - boolean + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: {} + documentsIds: + type: + - array + - "null" + items: + type: + - number + - "null" + earlyCheckinTime: + type: + - string + - "null" + eventsAllowed: + type: + - boolean + - "null" + gatewaysIds: + type: + - array + - "null" + items: + type: + - number + - "null" + guaranteePoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isAccessible: + type: + - boolean + - "null" + lateCheckoutTime: + type: + - string + - "null" + localOfficeId: + type: + - number + - "null" + locality: + type: + - string + - "null" + minimumAgeLimit: + type: + - number + - "null" + name: + type: + - string + - "null" + parentId: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + region: + type: + - string + - "null" + roles: + type: + - array + - "null" + smokingAllowed: + type: + - boolean + - "null" + taxDistrictId: + type: + - number + - "null" + timezone: + type: + - string + - "null" + typeId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + taxDistrict: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + longTermPolicy: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + salesTaxPolicy: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + shortTermPolicy: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + breakpoint: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + hasBreakpoint: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + longTermPolicyId: + type: + - number + - "null" + name: + type: + - string + - "null" + salesTaxPolicyId: + type: + - number + - "null" + shortTermPolicyId: + type: + - number + - "null" + taxMarkup: + type: + - boolean + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + travelInsuranceProduct: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + allowCancelOverride: + type: + - boolean + - "null" + allowExternalNotification: + type: + - boolean + - "null" + changeMode: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + declineMessage: + type: + - string + - "null" + enableReporting: + type: + - boolean + - "null" + id: + type: + - number + - "null" + insuranceType: + type: + - string + - "null" + irmEnabled: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + optOutWindow: + type: + - number + - "null" + payableAccountId: + type: + - number + - "null" + percent: + type: + - string + - "null" + producerCode: + type: + - string + - "null" + productClass: + type: + - string + - "null" + provider: + type: + - string + - "null" + realizeAfterWindow: + type: + - boolean + - "null" + revenueAccountId: + type: + - number + - "null" + selectedByDefault: + type: + - boolean + - "null" + split: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + amenitiesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + area: + type: + - number + - "null" + availabilityOrder: + type: + - number + - "null" + bedTypes: + type: + - array + - "null" + bedrooms: + type: + - number + - "null" + cancellationPoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + checkinTime: + type: + - string + - "null" + checkoutTime: + type: + - string + - "null" + childrenAllowed: + type: + - boolean + - "null" + cleanStatusId: + type: + - number + - "null" + cleanStatusType: + type: + - string + - "null" + composites: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + unitId: + type: + - number + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + pms_units_owner_notes: + type: + - string + - "null" + pms_units_source_unit_id: + type: + - string + - "null" + pms_units_wifi_information: + type: + - string + - "null" + documentsIds: + type: + - array + - "null" + items: + type: + - number + - "null" + earlyCheckinTime: + type: + - string + - "null" + eventsAllowed: + type: + - boolean + - "null" + extendedAddress: + type: + - string + - "null" + folioException: + type: + - boolean + - "null" + fullBathrooms: + type: + - number + - "null" + gatewaysIds: + type: + - array + - "null" + items: + type: + - number + - "null" + guaranteePoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + halfBathrooms: + type: + - number + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + housekeepingMessage: + type: + - string + - "null" + housekeepingNotes: + type: + - string + - "null" + id: + type: + - number + - "null" + isAccessible: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isBookable: + type: + - boolean + - "null" + isLimited: + type: + - boolean + - "null" + isOccupied: + type: + - boolean + - "null" + lateCheckoutTime: + type: + - string + - "null" + latitude: + type: + - string + - "null" + localOfficeId: + type: + - number + - "null" + locality: + type: + - string + - "null" + lodgingTypeId: + type: + - number + - "null" + longitude: + type: + - string + - "null" + maintenanceMessage: + type: + - string + - "null" + maxOccupancy: + type: + - number + - "null" + minimumAgeLimit: + type: + - number + - "null" + name: + type: + - string + - "null" + nodeId: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + region: + type: + - string + - "null" + roles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + roleId: + type: + - number + - "null" + userId: + type: + - number + - "null" + securityDeposit: + type: + - string + - "null" + shortName: + type: + - string + - "null" + smokingAllowed: + type: + - boolean + - "null" + streetAddress: + type: + - string + - "null" + taxDistrictId: + type: + - number + - "null" + taxId: + type: + - string + - "null" + threeQuarterBathrooms: + type: + - number + - "null" + timezone: + type: + - string + - "null" + travelInsuranceProductId: + type: + - number + - "null" + typeId: + type: + - number + - "null" + unitCode: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + useBedTypes: + type: + - boolean + - "null" + useRoomConfiguration: + type: + - boolean + - "null" + websiteUrl: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + altConf: + type: + - string + - "null" + arrivalDate: + type: + - string + - "null" + arrivalTime: + type: + - string + - "null" + cancelledAt: + type: + - string + - "null" + departureDate: + type: + - string + - "null" + departureTime: + type: + - string + - "null" + earlyArrival: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isUnitAssigned: + type: + - boolean + - "null" + isUnitLocked: + type: + - boolean + - "null" + isUnitTypeLocked: + type: + - boolean + - "null" + lateDeparture: + type: + - boolean + - "null" + nights: + type: + - number + - "null" + occupants: + type: + - object + - "null" + properties: + "1": + type: + - number + - "null" + "2": + type: + - number + - "null" + "3": + type: + - number + - "null" + remainingSecurityDeposit: + type: + - number + - "null" + requiredSecurityDeposit: + type: + - number + - string + - "null" + softEnd: + type: + - string + - "null" + softStart: + type: + - string + - "null" + status: + type: + - string + - "null" + unitId: + type: + - number + - "null" + workOrder: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + owner: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + achAccountNumber: + type: + - string + - "null" + achAccountType: + type: + - string + - "null" + achRoutingNumber: + type: + - string + - "null" + activeUnitCount: + type: + - number + - "null" + agentCommission: + type: + - string + - "null" + alwaysShowInStatements: + type: + - boolean + - "null" + companyId: + type: + - number + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currentBalance: + type: + - string + - "null" + deferredBalance: + type: + - string + - "null" + email: + type: + - string + - "null" + extendedAddress: + type: + - string + - "null" + fax: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + locality: + type: + - string + - "null" + minimumBalance: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + paymentType: + type: + - string + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + region: + type: + - string + - "null" + splitWithContacts: + type: + - boolean + - "null" + streetAddress: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + taxCountry: + type: + - string + - "null" + taxExtendedAddress: + type: + - string + - "null" + taxId: + type: + - string + - "null" + taxLocality: + type: + - string + - "null" + taxName: + type: + - string + - "null" + taxPostalCode: + type: + - string + - "null" + taxRegion: + type: + - string + - "null" + taxStreetAddress: + type: + - string + - "null" + taxType: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + website: + type: + - string + - "null" + unit: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + cleanStatus: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + area: + type: + - number + - "null" + availabilityOrder: + type: + - number + - "null" + bedTypes: + type: + - array + - "null" + bedrooms: + type: + - number + - "null" + checkinTime: + type: + - string + - "null" + checkoutTime: + type: + - string + - "null" + childrenAllowed: + type: + - boolean + - "null" + cleanStatusId: + type: + - number + - "null" + cleanStatusType: + type: + - string + - "null" + composites: + type: + - array + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + pms_units_owner_notes: + type: + - string + - "null" + pms_units_source_unit_id: + type: + - string + - "null" + pms_units_wifi_information: + type: + - string + - "null" + earlyCheckinTime: + type: + - string + - "null" + eventsAllowed: + type: + - boolean + - "null" + extendedAddress: + type: + - string + - "null" + floors: + type: + - number + - "null" + folioException: + type: + - boolean + - "null" + fullBathrooms: + type: + - number + - "null" + halfBathrooms: + type: + - number + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + housekeepingMessage: + type: + - string + - "null" + housekeepingNotes: + type: + - string + - "null" + id: + type: + - number + - "null" + isAccessible: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isBookable: + type: + - boolean + - "null" + isLimited: + type: + - boolean + - "null" + isOccupied: + type: + - boolean + - "null" + lateCheckoutTime: + type: + - string + - "null" + latitude: + type: + - string + - "null" + localOfficeId: + type: + - number + - "null" + locality: + type: + - string + - "null" + lodgingTypeId: + type: + - number + - "null" + longitude: + type: + - string + - "null" + maintenanceMessage: + type: + - string + - "null" + maxOccupancy: + type: + - number + - "null" + minimumAgeLimit: + type: + - number + - "null" + name: + type: + - string + - "null" + nodeId: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + region: + type: + - string + - "null" + roles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + roleId: + type: + - number + - "null" + userId: + type: + - number + - "null" + securityDeposit: + type: + - string + - "null" + shortName: + type: + - string + - "null" + smokingAllowed: + type: + - boolean + - "null" + streetAddress: + type: + - string + - "null" + taxDistrictId: + type: + - number + - "null" + taxId: + type: + - string + - "null" + threeQuarterBathrooms: + type: + - number + - "null" + timezone: + type: + - string + - "null" + travelInsuranceProductId: + type: + - number + - "null" + typeId: + type: + - number + - "null" + unitCode: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + useBedTypes: + type: + - boolean + - "null" + useRoomConfiguration: + type: + - boolean + - "null" + websiteUrl: + type: + - string + - "null" + user: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + vendor: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + achAccountNumber: + type: + - string + - "null" + achAccountType: + type: + - string + - "null" + achRoutingNumber: + type: + - string + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + email: + type: + - string + - "null" + enableWorkOrderApproval: + type: + - boolean + - "null" + extendedAddress: + type: + - string + - "null" + fax: + type: + - string + - "null" + glInsurancePolicy: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + locality: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + paymentType: + type: + - string + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + region: + type: + - string + - "null" + streetAddress: + type: + - string + - "null" + tags: + type: + - array + - "null" + taxId: + type: + - string + - "null" + taxName: + type: + - string + - "null" + taxType: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + wcInsurancePolicy: + type: + - string + - "null" + website: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + actualTime: + type: + - number + - "null" + assignees: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + assignable: + type: + - array + - "null" + items: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + isLead: + type: + - boolean + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + role: + type: + - object + - "null" + properties: + __cloner__: + type: + - object + - "null" + __initializer__: + type: + - object + - "null" + __isInitialized__: + type: + - boolean + - "null" + updatedBy: + type: + - string + - "null" + username: + type: + - string + - "null" + vendorId: + type: + - number + - "null" + blockCheckin: + type: + - boolean + - "null" + completedById: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + dateCompleted: + type: + - string + - "null" + dateProcessed: + type: + - string + - "null" + dateReceived: + type: + - string + - "null" + dateScheduled: + type: + - string + - "null" + id: + type: + - number + - "null" + ownerId: + type: + - number + - "null" + priority: + type: + - number + - "null" + problems: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + processedById: + type: + - number + - "null" + referenceNumber: + type: + - string + - "null" + source: + type: + - string + - "null" + sourceName: + type: + - string + - "null" + sourcePhone: + type: + - string + - "null" + status: + type: + - string + - "null" + summary: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + userId: + type: + - number + - "null" + vendorId: + type: + - number + - "null" + workPerformed: + type: + - string + - "null" + amount: + type: + - string + - "null" + companyId: + type: + - number + - "null" + contactId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currency: + type: + - string + - "null" + folioTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + chargeId: + type: + - number + - "null" + folioId: + type: + - number + - "null" + id: + type: + - number + - "null" + isManual: + type: + - boolean + - "null" + isSecurityDeposit: + type: + - boolean + - "null" + nights: + type: + - number + - "null" + reservationFeeId: + type: + - number + - "null" + roomNight: + type: + - string + - "null" + securityDepositResolved: + type: + - boolean + - "null" + id: + type: number + isDeferred: + type: + - boolean + - "null" + isPending: + type: + - boolean + - "null" + isVoided: + type: + - boolean + - "null" + lines: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + account: + type: + - string + - "null" + accountId: + type: + - number + - "null" + amount: + type: + - string + - "null" + id: + type: + - number + - "null" + itemId: + type: + - number + - "null" + netAmount: + type: + - string + - "null" + quantity: + type: + - string + - "null" + remittanceBillId: + type: + - number + - "null" + taxAmount: + type: + - string + - "null" + taxOnMarkUp: + type: + - boolean + - "null" + unitAmount: + type: + - string + - "null" + unitId: + type: + - number + - "null" + unitName: + type: + - string + - "null" + memo: + type: + - string + - "null" + ownerTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + folioId: + type: + - number + - "null" + id: + type: + - number + - "null" + ownerId: + type: + - number + - "null" + reservationFeeId: + type: + - number + - "null" + statementId: + type: + - number + - "null" + parentId: + type: + - number + - "null" + publicMemo: + type: + - string + - "null" + subTotal: + type: + - string + - "null" + taxAmount: + type: + - string + - "null" + taxExempt: + type: + - boolean + - "null" + txnDate: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + workOrderId: + type: + - number + - "null" + required: + - id + maintenance-work-orders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + user: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + actualTime: + type: + - number + - "null" + assignees: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + assignable: + type: + - array + - "null" + items: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + isLead: + type: + - boolean + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + role: + type: + - object + - "null" + properties: + __cloner__: + type: + - object + - "null" + __initializer__: + type: + - object + - "null" + __isInitialized__: + type: + - boolean + - "null" + updatedBy: + type: + - string + - "null" + username: + type: + - string + - "null" + vendorId: + type: + - number + - "null" + blockCheckin: + type: + - boolean + - "null" + completedById: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + dateCompleted: + type: + - string + - "null" + dateProcessed: + type: + - string + - "null" + dateReceived: + type: + - string + - "null" + dateScheduled: + type: + - string + - "null" + estimatedCost: + type: + - string + - "null" + estimatedTime: + type: + - number + - "null" + id: + type: number + ownerId: + type: + - number + - "null" + priority: + type: + - number + - "null" + problems: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + processedById: + type: + - number + - "null" + referenceNumber: + type: + - string + - "null" + source: + type: + - string + - "null" + sourceName: + type: + - string + - "null" + sourcePhone: + type: + - string + - "null" + status: + type: + - string + - "null" + summary: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: string + updatedBy: + type: + - string + - "null" + userId: + type: + - number + - "null" + vendorId: + type: + - number + - "null" + workPerformed: + type: + - string + - "null" + required: + - id + - updatedAt + unit_taxes_parent: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + amenitiesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + area: + type: + - number + - "null" + availabilityOrder: + type: + - number + - "null" + bedTypes: + type: + - array + - "null" + bedrooms: + type: + - number + - "null" + cancellationPoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + checkinTime: + type: + - string + - "null" + checkoutTime: + type: + - string + - "null" + childrenAllowed: + type: + - boolean + - "null" + cleanStatusId: + type: + - number + - "null" + cleanStatusType: + type: + - string + - "null" + composites: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + unitId: + type: + - number + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + pms_units_owner_notes: + type: + - string + - "null" + pms_units_source_unit_id: + type: + - string + - "null" + pms_units_wifi_information: + type: + - string + - "null" + documentsIds: + type: + - array + - "null" + items: + type: + - number + - "null" + earlyCheckinTime: + type: + - string + - "null" + eventsAllowed: + type: + - boolean + - "null" + extendedAddress: + type: + - string + - "null" + folioException: + type: + - boolean + - "null" + fullBathrooms: + type: + - number + - "null" + gatewaysIds: + type: + - array + - "null" + items: + type: + - number + - "null" + guaranteePoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + halfBathrooms: + type: + - number + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + housekeepingMessage: + type: + - string + - "null" + housekeepingNotes: + type: + - string + - "null" + id: + type: number + isAccessible: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isBookable: + type: + - boolean + - "null" + isLimited: + type: + - boolean + - "null" + isOccupied: + type: + - boolean + - "null" + lateCheckoutTime: + type: + - string + - "null" + latitude: + type: + - string + - "null" + localOfficeId: + type: + - number + - "null" + locality: + type: + - string + - "null" + lodgingTypeId: + type: + - number + - "null" + longitude: + type: + - string + - "null" + maintenanceMessage: + type: + - string + - "null" + maxOccupancy: + type: + - number + - "null" + minimumAgeLimit: + type: + - number + - "null" + name: + type: + - string + - "null" + nodeId: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + region: + type: + - string + - "null" + roles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + roleId: + type: + - number + - "null" + userId: + type: + - number + - "null" + securityDeposit: + type: + - string + - "null" + shortName: + type: + - string + - "null" + smokingAllowed: + type: + - boolean + - "null" + streetAddress: + type: + - string + - "null" + taxDistrictId: + type: + - number + - "null" + taxId: + type: + - string + - "null" + threeQuarterBathrooms: + type: + - number + - "null" + timezone: + type: + - string + - "null" + travelInsuranceProductId: + type: + - number + - "null" + typeId: + type: + - number + - "null" + unitCode: + type: + - string + - "null" + updatedAt: + type: string + updatedBy: + type: + - string + - "null" + useBedTypes: + type: + - boolean + - "null" + useRoomConfiguration: + type: + - boolean + - "null" + websiteUrl: + type: + - string + - "null" + required: + - id + - updatedAt + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + assignable: + type: + - array + - "null" + items: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + username: + type: + - string + - "null" + vendorId: + type: + - number + - "null" + required: + - id + roles: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: number + isSuperUser: + type: + - boolean + - "null" + isSystem: + type: + - boolean + - "null" + name: + type: + - string + - "null" + privileges: + type: + - object + - "null" + properties: + accounting: + type: + - object + - "null" + properties: + access: + type: + - boolean + - "null" + achbatch: + type: + - boolean + - "null" + billpayments: + type: + - boolean + - "null" + bills: + type: + - boolean + - "null" + changedate: + type: + - boolean + - "null" + charges: + type: + - boolean + - "null" + chartofaccounts: + type: + - boolean + - "null" + checksetup: + type: + - boolean + - "null" + cityaccounts: + type: + - boolean + - "null" + creditlimit: + type: + - boolean + - "null" + deferred: + type: + - boolean + - "null" + deposits: + type: + - boolean + - "null" + expense: + type: + - boolean + - "null" + journal: + type: + - boolean + - "null" + overridesoftlock: + type: + - boolean + - "null" + printcheck: + type: + - boolean + - "null" + reconcile: + type: + - boolean + - "null" + recurring-bill: + type: + - boolean + - "null" + refunds: + type: + - boolean + - "null" + reversalreason: + type: + - boolean + - "null" + taxforms: + type: + - boolean + - "null" + transfer: + type: + - boolean + - "null" + yearend: + type: + - boolean + - "null" + automations: + type: + - object + - "null" + properties: + access: + type: + - boolean + - "null" + change_detection: + type: + - boolean + - "null" + config: + type: + - object + - "null" + properties: + access: + type: + - boolean + - "null" + accesscontrol: + type: + - boolean + - "null" + accounting_period_locking: + type: + - boolean + - "null" + amenities: + type: + - boolean + - "null" + apikey: + type: + - boolean + - "null" + block_unit_types: + type: + - boolean + - "null" + booking_fees: + type: + - boolean + - "null" + brands: + type: + - boolean + - "null" + cancellation: + type: + - boolean + - "null" + card_gateways: + type: + - boolean + - "null" + channel_billing: + type: + - boolean + - "null" + channel_taxes: + type: + - boolean + - "null" + channels: + type: + - boolean + - "null" + commission: + type: + - boolean + - "null" + commission_codes: + type: + - boolean + - "null" + company_logos: + type: + - boolean + - "null" + configuration: + type: + - boolean + - "null" + custom-fields: + type: + - boolean + - "null" + date_groups: + type: + - boolean + - "null" + discount_reasons: + type: + - boolean + - "null" + extra_persons: + type: + - boolean + - "null" + folio-items: + type: + - boolean + - "null" + gap-rules: + type: + - boolean + - "null" + import_charges: + type: + - boolean + - "null" + items: + type: + - boolean + - "null" + lead_statuses: + type: + - boolean + - "null" + lodging_types: + type: + - boolean + - "null" + office_locations: + type: + - boolean + - "null" + payment_methods: + type: + - boolean + - "null" + pms_company: + type: + - boolean + - "null" + point_of_sale: + type: + - boolean + - "null" + reservation_documents: + type: + - boolean + - "null" + reservation_types: + type: + - boolean + - "null" + schedules: + type: + - boolean + - "null" + security_codes: + type: + - boolean + - "null" + task_manager: + type: + - boolean + - "null" + tax_setup: + type: + - boolean + - "null" + topic-notifications: + type: + - boolean + - "null" + crm: + type: + - object + - "null" + properties: + automated-tags: + type: + - boolean + - "null" + campaigns: + type: + - boolean + - "null" + company: + type: + - boolean + - "null" + company-attachment-delete: + type: + - boolean + - "null" + company-delete: + type: + - boolean + - "null" + confidential: + type: + - boolean + - "null" + contact-exception: + type: + - boolean + - "null" + contacts: + type: + - boolean + - "null" + contacts-delete: + type: + - boolean + - "null" + contacts-export: + type: + - boolean + - "null" + contacts-import: + type: + - boolean + - "null" + email-delete: + type: + - boolean + - "null" + email-view: + type: + - boolean + - "null" + inbox-configuration: + type: + - boolean + - "null" + inquiry: + type: + - boolean + - "null" + inquiry-configuration: + type: + - boolean + - "null" + inquiry-delete: + type: + - boolean + - "null" + lead-preferences: + type: + - boolean + - "null" + leadautoclose: + type: + - boolean + - "null" + leads: + type: + - boolean + - "null" + leads-delete: + type: + - boolean + - "null" + leads-export: + type: + - boolean + - "null" + leads-notifications: + type: + - boolean + - "null" + leads-status: + type: + - boolean + - "null" + leads-type: + type: + - boolean + - "null" + lostreasons: + type: + - boolean + - "null" + outbound-email: + type: + - boolean + - "null" + reopenleads: + type: + - boolean + - "null" + sales: + type: + - boolean + - "null" + sales-edit-delete: + type: + - boolean + - "null" + sales-export: + type: + - boolean + - "null" + sales-import: + type: + - boolean + - "null" + saleslink: + type: + - boolean + - "null" + tags: + type: + - boolean + - "null" + tasks-delete: + type: + - boolean + - "null" + tasks-view-all: + type: + - boolean + - "null" + templates: + type: + - boolean + - "null" + text: + type: + - boolean + - "null" + text-delete: + type: + - boolean + - "null" + dashboard: + type: + - object + - "null" + properties: + company: + type: + - boolean + - "null" + file: + type: + - object + - "null" + properties: + add-to-library: + type: + - boolean + - "null" + delete-file: + type: + - boolean + - "null" + folio: + type: + - object + - "null" + properties: + audit_trail: + type: + - boolean + - "null" + guest-sub-folio-create: + type: + - boolean + - "null" + guestfolio: + type: + - boolean + - "null" + masterfolio: + type: + - boolean + - "null" + rules: + type: + - boolean + - "null" + securitydepositfolio-create: + type: + - boolean + - "null" + fractional: + type: + - object + - "null" + properties: + access: + type: + - boolean + - "null" + front_desk: + type: + - object + - "null" + properties: + access: + type: + - boolean + - "null" + block_units: + type: + - boolean + - "null" + mass_check_in: + type: + - boolean + - "null" + tapechart: + type: + - boolean + - "null" + guest: + type: + - object + - "null" + properties: + access: + type: + - boolean + - "null" + configuration: + type: + - boolean + - "null" + content: + type: + - boolean + - "null" + deal: + type: + - boolean + - "null" + login: + type: + - boolean + - "null" + place: + type: + - boolean + - "null" + request: + type: + - boolean + - "null" + request_delete: + type: + - boolean + - "null" + housekeeping: + type: + - object + - "null" + properties: + access: + type: + - boolean + - "null" + assignment: + type: + - boolean + - "null" + hk_grid: + type: + - boolean + - "null" + service_schedule: + type: + - boolean + - "null" + time_tracking: + type: + - boolean + - "null" + unit_status_list: + type: + - boolean + - "null" + work-order: + type: + - boolean + - "null" + work-order-delete: + type: + - boolean + - "null" + work-order-edit-processed: + type: + - boolean + - "null" + work-order-processed: + type: + - boolean + - "null" + workorder-workflow-override: + type: + - boolean + - "null" + leads: + type: + - object + - "null" + properties: + assignable: + type: + - boolean + - "null" + maintenance: + type: + - object + - "null" + properties: + access: + type: + - boolean + - "null" + recurring-work-order: + type: + - boolean + - "null" + time_tracking: + type: + - boolean + - "null" + work-order: + type: + - boolean + - "null" + work-order-cancel: + type: + - boolean + - "null" + work-order-delete: + type: + - boolean + - "null" + work-order-edit-processed: + type: + - boolean + - "null" + work-order-problems: + type: + - boolean + - "null" + work-order-processed: + type: + - boolean + - "null" + work-order-templates: + type: + - boolean + - "null" + owner_communications: + type: + - object + - "null" + properties: + broadcast: + type: + - boolean + - "null" + messages-send: + type: + - boolean + - "null" + messages-view: + type: + - boolean + - "null" + messages-view-all: + type: + - boolean + - "null" + topics: + type: + - boolean + - "null" + owners: + type: + - object + - "null" + properties: + access: + type: + - boolean + - "null" + accounting: + type: + - boolean + - "null" + login: + type: + - boolean + - "null" + profile: + type: + - boolean + - "null" + statements: + type: + - boolean + - "null" + statements-delete: + type: + - boolean + - "null" + statements-generate: + type: + - boolean + - "null" + transactions: + type: + - boolean + - "null" + unit-popup: + type: + - boolean + - "null" + units: + type: + - boolean + - "null" + workorders: + type: + - boolean + - "null" + promo_code: + type: + - object + - "null" + properties: + access: + type: + - boolean + - "null" + properties_accommodation: + type: + - object + - "null" + properties: + properties_accommodation_manage: + type: + - boolean + - "null" + properties_accommodation_view: + type: + - boolean + - "null" + property_management: + type: + - object + - "null" + properties: + channel-inventory: + type: + - boolean + - "null" + daily-pricing: + type: + - boolean + - "null" + distribution_engine: + type: + - boolean + - "null" + rate_types: + type: + - boolean + - "null" + reservation_charges: + type: + - boolean + - "null" + season_rates: + type: + - boolean + - "null" + suspend_code_reasons: + type: + - boolean + - "null" + unit_fee_pricing: + type: + - boolean + - "null" + pulse: + type: + - object + - "null" + properties: + access: + type: + - boolean + - "null" + activitytopic: + type: + - boolean + - "null" + agent: + type: + - boolean + - "null" + call-export: + type: + - boolean + - "null" + callplan: + type: + - boolean + - "null" + callresult: + type: + - boolean + - "null" + calls: + type: + - boolean + - "null" + callscore: + type: + - boolean + - "null" + chat-admin: + type: + - boolean + - "null" + chat-log: + type: + - boolean + - "null" + coach: + type: + - boolean + - "null" + dashboard: + type: + - boolean + - "null" + destinations: + type: + - boolean + - "null" + directory: + type: + - boolean + - "null" + goals: + type: + - boolean + - "null" + groups: + type: + - boolean + - "null" + menu: + type: + - boolean + - "null" + messages: + type: + - boolean + - "null" + messages-delete: + type: + - boolean + - "null" + mycallscore: + type: + - boolean + - "null" + numbers: + type: + - boolean + - "null" + preferences: + type: + - boolean + - "null" + queue: + type: + - boolean + - "null" + recording: + type: + - boolean + - "null" + scoretemplate: + type: + - boolean + - "null" + status: + type: + - boolean + - "null" + statusboard: + type: + - boolean + - "null" + tracking: + type: + - boolean + - "null" + verifycaller: + type: + - boolean + - "null" + voicemail: + type: + - boolean + - "null" + quotes: + type: + - object + - "null" + properties: + send-config: + type: + - boolean + - "null" + reports: + type: + - object + - "null" + properties: + access: + type: + - boolean + - "null" + accounting: + type: + - boolean + - "null" + businesstax: + type: + - boolean + - "null" + crm: + type: + - boolean + - "null" + frontdesk: + type: + - boolean + - "null" + guest: + type: + - boolean + - "null" + housekeeping: + type: + - boolean + - "null" + maintenance: + type: + - boolean + - "null" + operational: + type: + - boolean + - "null" + owner: + type: + - boolean + - "null" + pulseagent: + type: + - boolean + - "null" + pulseagentproductivity: + type: + - boolean + - "null" + pulsebasic: + type: + - boolean + - "null" + pulsecampaign: + type: + - boolean + - "null" + salestax: + type: + - boolean + - "null" + statistics: + type: + - boolean + - "null" + system: + type: + - boolean + - "null" + travelagent: + type: + - boolean + - "null" + travelinsurance: + type: + - boolean + - "null" + unitrates: + type: + - boolean + - "null" + units: + type: + - boolean + - "null" + reputation_management: + type: + - object + - "null" + properties: + automated_host_reviews: + type: + - boolean + - "null" + automated_host_reviews_preferences: + type: + - boolean + - "null" + reputation_management_manage: + type: + - boolean + - "null" + reputation_management_view: + type: + - boolean + - "null" + saved_response: + type: + - boolean + - "null" + reservations: + type: + - object + - "null" + properties: + access: + type: + - boolean + - "null" + accounting: + type: + - boolean + - "null" + assignment: + type: + - boolean + - "null" + attachment-delete: + type: + - boolean + - "null" + attachments: + type: + - boolean + - "null" + audit_log: + type: + - boolean + - "null" + booking_fees: + type: + - boolean + - "null" + bulk-update: + type: + - boolean + - "null" + cancellationpolicy: + type: + - boolean + - "null" + change_agent: + type: + - boolean + - "null" + change_type: + type: + - boolean + - "null" + channel-unlock: + type: + - boolean + - "null" + discount: + type: + - boolean + - "null" + documents: + type: + - boolean + - "null" + e_sign: + type: + - boolean + - "null" + fees_edit: + type: + - boolean + - "null" + groups: + type: + - boolean + - "null" + guaranteepolicy: + type: + - boolean + - "null" + guest-communications: + type: + - boolean + - "null" + housekeeping: + type: + - boolean + - "null" + ignore-restrictions: + type: + - boolean + - "null" + move-reasons: + type: + - boolean + - "null" + new_reservation: + type: + - boolean + - "null" + new_reservation_process: + type: + - boolean + - "null" + notes: + type: + - boolean + - "null" + occupants: + type: + - boolean + - "null" + rates: + type: + - boolean + - "null" + stay: + type: + - boolean + - "null" + tapechart: + type: + - boolean + - "null" + unlock-unit-type-reservation: + type: + - boolean + - "null" + revenue_management: + type: + - object + - "null" + properties: + preferences: + type: + - boolean + - "null" + rules: + type: + - boolean + - "null" + survey: + type: + - object + - "null" + properties: + configuration: + type: + - boolean + - "null" + responses: + type: + - boolean + - "null" + system: + type: + - object + - "null" + properties: + global-presets: + type: + - boolean + - "null" + queue-log: + type: + - boolean + - "null" + time_tracking: + type: + - object + - "null" + properties: + access: + type: + - boolean + - "null" + units: + type: + - object + - "null" + properties: + access: + type: + - boolean + - "null" + inventory: + type: + - boolean + - "null" + nodetype: + type: + - boolean + - "null" + profiles: + type: + - boolean + - "null" + unittype: + type: + - boolean + - "null" + zones: + type: + - boolean + - "null" + users: + type: + - object + - "null" + properties: + role: + type: + - boolean + - "null" + settings: + type: + - boolean + - "null" + team: + type: + - boolean + - "null" + users: + type: + - boolean + - "null" + required: + - id + crm_company_attachment: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + company_id: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + fileType: + type: + - string + - "null" + fileUrl: + type: + - string + - "null" + id: + type: + - number + - "null" + isPublic: + type: + - boolean + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + crm-tasks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + completedAt: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + dueAt: + type: + - string + - "null" + id: + type: number + priority: + type: + - number + - "null" + title: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + userId: + type: + - number + - "null" + required: + - id + units-amenity-groups: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + nodes-types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + isHousekeeping: + type: + - boolean + - "null" + isMaintenance: + type: + - boolean + - "null" + isOnline: + type: + - boolean + - "null" + isOwners: + type: + - boolean + - "null" + isReport: + type: + - boolean + - "null" + isReservations: + type: + - boolean + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + charges: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + item: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + isDeferExempted: + type: + - boolean + - "null" + isTaxable: + type: + - boolean + - "null" + itemCategories: + type: + - array + - "null" + items: + type: + - string + - "null" + name: + type: + - string + - "null" + revenueAccountId: + type: + - number + - "null" + taxPolicyId: + type: + - number + - "null" + taxPolicyType: + type: + - string + - "null" + unitPrice: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + airbnbProductCode: + type: + - string + - "null" + allowFeeEdit: + type: + - boolean + - "null" + allowFeeRemoval: + type: + - boolean + - "null" + amount: + type: + - string + - "null" + applyUnitTaxes: + type: + - boolean + - "null" + bookingDotComProductCode: + type: + - string + - "null" + channelStackedFees: + type: + - boolean + - "null" + chargeOwner: + type: + - boolean + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + dateRangeType: + type: + - string + - "null" + defaultQuantity: + type: + - number + - "null" + displayAs: + type: + - string + - "null" + displayName: + type: + - string + - "null" + excludeFromInsurance: + type: + - boolean + - "null" + feeType: + type: + - string + - "null" + frequency: + type: + - string + - "null" + hasUnitPricing: + type: + - boolean + - "null" + homeawayProductCode: + type: + - string + - "null" + id: + type: number + includeAllResTypes: + type: + - boolean + - "null" + includeInSubtotal: + type: + - boolean + - "null" + irmEnabled: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isDeferExempted: + type: + - boolean + - "null" + isStacked: + type: + - boolean + - "null" + itemId: + type: + - number + - "null" + managementCommission: + type: + - string + - "null" + marriottProductCode: + type: + - string + - "null" + maxQuantity: + type: + - number + - "null" + maxStayLength: + type: + - number + - "null" + maximumAmount: + type: + - string + - "null" + minStayLength: + type: + - number + - "null" + minimumAmount: + type: + - string + - "null" + name: + type: + - string + - "null" + postDate: + type: + - string + - "null" + rateType: + type: + - string + - "null" + requireFunding: + type: + - boolean + - "null" + reservationTypeIds: + type: + - array + - "null" + items: + type: + - number + - "null" + splitWithOwner: + type: + - boolean + - "null" + taxPolicyType: + type: + - string + - "null" + template: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + date-groups: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + dates: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + end: + type: + - string + - "null" + start: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + documents: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + autoSend: + type: + - boolean + - "null" + content: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + esignIntro: + type: + - string + - "null" + esignTemplate: + type: + - string + - "null" + fromAddress: + type: + - string + - "null" + fromName: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + pdfSystemVersion: + type: + - number + - "null" + subject: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + useLayout: + type: + - boolean + - "null" + required: + - id + folios-rules: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + breakdownChargesIncludeTax: + type: + - boolean + - "null" + breakdownChargesMode: + type: + - string + - "null" + breakdownChargesPercent: + type: + - string + - "null" + breakdownFeeIncludeTax: + type: + - boolean + - "null" + breakdownFeeMode: + type: + - string + - "null" + breakdownFeePercent: + type: + - string + - "null" + breakdownRentIncludeTax: + type: + - boolean + - "null" + breakdownRentMode: + type: + - string + - "null" + breakdownRentPercent: + type: + - string + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + percentAmount: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + folio_logs: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + folio_id: + type: number + id: + type: number + message: + type: + - string + - "null" + typeLabel: + type: + - string + - "null" + required: + - folio_id + - id + maintenance-problems: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: number + name: + type: + - string + - "null" + required: + - id + owners_units: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + contractId: + type: + - number + - "null" + contractType: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + endDate: + type: + - string + - "null" + id: + type: number + ownerId: + type: number + startDate: + type: + - string + - "null" + taxMode: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - ownerId + - id + owners-contracts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + code: + type: + - string + - "null" + commissionValues: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + commission: + type: + - string + - "null" + hasOverrides: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + overrides: + type: + - array + - "null" + typeId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + defaultCommission: + type: + - string + - "null" + defaultMarkup: + type: + - string + - "null" + hasPaymentFee: + type: + - boolean + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + items: + type: + - array + - "null" + maximumMarkup: + type: + - string + - "null" + minLosOwnerOverride: + type: + - boolean + - "null" + name: + type: + - string + - "null" + overrideType: + type: + - string + - "null" + paymentFee: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + owner-statements: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + balanceForward: + type: + - string + - "null" + charges: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + dueByOwner: + type: + - string + - "null" + dueToOwner: + type: + - string + - "null" + endingBalances: + type: + - string + - "null" + id: + type: number + isAnnual: + type: + - boolean + - "null" + isPublished: + type: + - boolean + - "null" + minBalance: + type: + - string + - "null" + net: + type: + - string + - "null" + ownerId: + type: + - number + - "null" + paidIn: + type: + - string + - "null" + paidOut: + type: + - string + - "null" + period: + type: + - number + - "null" + revenue: + type: + - string + - "null" + splits: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + charges: + type: + - string + - "null" + dueByOwner: + type: + - string + - "null" + dueToOwner: + type: + - string + - "null" + journalId: + type: + - number + - "null" + paidIn: + type: + - string + - "null" + paidOut: + type: + - string + - "null" + revenue: + type: + - string + - "null" + split: + type: + - string + - "null" + statementDate: + type: + - string + - "null" + trustAccountBalance: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + year: + type: + - number + - "null" + required: + - id + owner_statement_transactions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currency: + type: + - string + - "null" + id: + type: number + isDeferred: + type: + - boolean + - "null" + isPending: + type: + - boolean + - "null" + isVoided: + type: + - boolean + - "null" + lines: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + account: + type: + - string + - "null" + accountId: + type: + - number + - "null" + amount: + type: + - string + - "null" + id: + type: + - number + - "null" + reconcile: + type: + - string + - "null" + statementId: + type: + - number + - "null" + taxOnMarkUp: + type: + - boolean + - "null" + unitAmount: + type: + - string + - "null" + unitId: + type: + - number + - "null" + unitName: + type: + - string + - "null" + memo: + type: + - string + - "null" + ownerTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + ownerId: + type: + - number + - "null" + statementId: + type: + - number + - "null" + reference: + type: + - string + - "null" + statement_id: + type: number + txnDate: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - statement_id + - id + promo-codes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + bookingEndDate: + type: + - string + - "null" + bookingStartDate: + type: + - string + - "null" + code: + type: + - string + - "null" + constraintMaxNights: + type: + - number + - "null" + constraintMinDaysPriorArrival: + type: + - number + - "null" + constraintMinNights: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + customBlackoutDatesConstraint: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + end: + type: + - string + - "null" + start: + type: + - string + - "null" + customDatesConstraint: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + end: + type: + - string + - "null" + start: + type: + - string + - "null" + dateConstraintType: + type: + - string + - "null" + dateConstraints: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + dateGroup: + type: + - object + - "null" + properties: + dates: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + end: + type: + - string + - "null" + id: + type: + - number + - "null" + start: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + id: + type: + - number + - "null" + isBlackoutDates: + type: + - boolean + - "null" + discountType: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + isPublic: + type: + - boolean + - "null" + name: + type: + - string + - "null" + stayDatesConstraintType: + type: + - string + - "null" + unitConstraints: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + field: + type: + - string + - "null" + id: + type: + - number + - "null" + operand: + type: + - string + - "null" + params: + type: + - object + - "null" + properties: + operator: + type: + - string + - "null" + values: + type: + - array + - "null" + items: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + valueAdjustments: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + adjustmentNights: + type: + - string + - "null" + discountConstraint: + type: + - string + - "null" + discountConstraintAmount: + type: + - string + - "null" + numberOfStays: + type: + - number + - "null" + value: + type: + - string + - "null" + required: + - id + reservations-cancellation-policies: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + properties: + dateGroup: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + dates: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + end: + type: + - string + - "null" + start: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + airbnbType: + type: + - string + - "null" + bookingDotComType: + type: + - number + - "null" + breakpoints: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + id: + type: + - number + - "null" + nonCancelable: + type: + - boolean + - "null" + nonRefundable: + type: + - boolean + - "null" + penaltyFlat: + type: + - string + - "null" + penaltyNights: + type: + - number + - "null" + penaltyPercent: + type: + - string + - "null" + rangeEnd: + type: + - number + - "null" + rangeStart: + type: + - number + - "null" + canExceedBalance: + type: + - boolean + - "null" + cancelTime: + type: + - string + - "null" + cancelTimezone: + type: + - string + - "null" + chargeAs: + type: + - string + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + dateGroupId: + type: + - number + - "null" + dateRangeType: + type: + - string + - "null" + homeawayType: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + isDefault: + type: + - boolean + - "null" + marriottCategory: + type: + - string + - "null" + name: + type: + - string + - "null" + postDate: + type: + - string + - "null" + priority: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + reservations-guarantee-policies: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + amount: + type: + - string + - "null" + beforeArrivalEnd: + type: + - number + - "null" + beforeArrivalStart: + type: + - number + - "null" + breakpoints: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + amount: + type: + - string + - "null" + amountOverrides: + type: + - array + - "null" + dueType: + type: + - string + - "null" + id: + type: + - number + - "null" + isRemaining: + type: + - boolean + - "null" + percent: + type: + - number + - "null" + stop: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + dateGroupId: + type: + - number + - "null" + dateRangeType: + type: + - string + - "null" + depositType: + type: + - string + - "null" + hasPaymentSchedule: + type: + - boolean + - "null" + holdLimit: + type: + - number + - "null" + holdLimitMinutes: + type: + - number + - "null" + id: + type: number + includeFees: + type: + - boolean + - "null" + includeFolioCharges: + type: + - boolean + - "null" + includeTax: + type: + - boolean + - "null" + includeTravelInsurance: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isAutomaticCancel: + type: + - boolean + - "null" + isDefault: + type: + - boolean + - "null" + name: + type: + - string + - "null" + priority: + type: + - number + - "null" + travelInsuranceWithFirstPayment: + type: + - boolean + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + reservation-cancellation-reasons: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + airbnbCancelType: + type: + - string + - "null" + airbnbType: + type: + - string + - "null" + cancelledByGuest: + type: + - boolean + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + handle: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + marriottCategory: + type: + - string + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + reservation-discount-reasons: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + handle: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + units-bed-types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + airbnbType: + type: + - string + - "null" + bookingDotComType: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + homeawayType: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + isFilterable: + type: + - boolean + - "null" + marriottType: + type: + - string + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + custom-fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + additionalProperties: + anyOf: + - type: array + - type: object + properties: + allowRichText: + type: boolean + changeDetection: + type: + - boolean + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + defaultValue: + type: + - string + - "null" + displayOrder: + type: + - number + - "null" + entity: + type: + - string + - "null" + id: + type: number + isCondition: + type: + - boolean + - "null" + isEditable: + type: + - boolean + - "null" + isExportable: + type: + - boolean + - "null" + isMergeField: + type: + - boolean + - "null" + isRequired: + type: + - boolean + - "null" + isVisible: + type: + - boolean + - "null" + name: + type: + - string + - "null" + reference: + type: + - string + - "null" + subType: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + groups: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + accountId: + type: + - number + - "null" + closedDate: + type: + - string + - "null" + code: + type: + - string + - "null" + companyId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currentBalance: + type: + - string + - "null" + endDate: + type: + - string + - "null" + id: + type: number + name: + type: + - string + - "null" + posAllow: + type: + - boolean + - "null" + promoCodeId: + type: + - number + - "null" + rateTypeId: + type: + - number + - "null" + realizedBalance: + type: + - string + - "null" + reservationTypeId: + type: + - number + - "null" + startDate: + type: + - string + - "null" + status: + type: + - string + - "null" + taxExempt: + type: + - boolean + - "null" + travelAgentId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + rate-types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + allowExtraNights: + type: + - boolean + - "null" + calculateMethod: + type: + - string + - "null" + channelId: + type: + - array + - "null" + items: + type: + - number + - "null" + code: + type: + - string + - "null" + conditions: + type: + - object + - "null" + properties: + in: + type: + - object + - "null" + properties: + unitType: + type: + - array + - "null" + items: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + cta: + type: + - object + - "null" + properties: + friday: + type: + - boolean + - "null" + monday: + type: + - boolean + - "null" + saturday: + type: + - boolean + - "null" + sunday: + type: + - boolean + - "null" + thursday: + type: + - boolean + - "null" + tuesday: + type: + - boolean + - "null" + wednesday: + type: + - boolean + - "null" + ctaOverride: + type: + - boolean + - "null" + ctd: + type: + - object + - "null" + properties: + friday: + type: + - boolean + - "null" + monday: + type: + - boolean + - "null" + saturday: + type: + - boolean + - "null" + sunday: + type: + - boolean + - "null" + thursday: + type: + - boolean + - "null" + tuesday: + type: + - boolean + - "null" + wednesday: + type: + - boolean + - "null" + ctdOverride: + type: + - boolean + - "null" + extraNightsPricing: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + isAllChannels: + type: + - boolean + - "null" + isAllUnits: + type: + - boolean + - "null" + isAutoSelect: + type: + - boolean + - "null" + maxLosAmount: + type: + - number + - "null" + maxLosType: + type: + - string + - "null" + minLosAmount: + type: + - number + - "null" + minLosType: + type: + - string + - "null" + name: + type: + - string + - "null" + nights: + type: + - number + - "null" + occupancyPricingByType: + type: + - boolean + - "null" + overrides: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + end: + type: + - string + - "null" + maxLosAmount: + type: + - number + - "null" + maxLosType: + type: + - string + - "null" + minLosAmount: + type: + - number + - "null" + minLosType: + type: + - string + - "null" + rentAmount: + type: + - string + - "null" + rentType: + type: + - string + - "null" + start: + type: + - string + - "null" + parentRateId: + type: + - number + - "null" + rentAmount: + type: + - string + - "null" + rentType: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + group_blocks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + endDate: + type: + - string + - "null" + estimate: + type: + - string + - "null" + group_id: + type: number + id: + type: number + reservationId: + type: + - number + - "null" + startDate: + type: + - string + - "null" + unitId: + type: + - number + - "null" + required: + - group_id + - id + group_tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + color: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + group_id: + type: number + id: + type: number + name: + type: + - string + - "null" + relatedTo: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - group_id + - id + group_breakdown: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + currency: + type: + - string + - "null" + estimate: + type: + - string + - "null" + fee: + type: + - string + - "null" + folioBalance: + type: + - string + - "null" + group_id: + type: number + rent: + type: + - string + - "null" + tax: + type: + - string + - "null" + total: + type: + - string + - "null" + unitTypes: + anyOf: + - type: array + - type: object + properties: + Great Bear 4 Bedroom Platinum: + type: number + Village 1 Bedroom: + type: number + Village 3 Bedroom: + type: number + Village 3 Bedroom Platinum: + type: number + required: + - group_id + suspend-code-reasons: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + allowRemoval: + type: + - boolean + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + reason: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + units_channel: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + properties: + channel: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + campaign: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + disableRecording: + type: + - boolean + - "null" + email: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + tags: + type: + - array + - "null" + token: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + url: + type: + - string + - "null" + reservationType: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + autoSelect: + type: + - boolean + - "null" + chargeRates: + type: + - boolean + - "null" + chargeRent: + type: + - string + - "null" + cleaningOptionsId: + type: + - number + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + deferDisbursement: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + isCommissionable: + type: + - boolean + - "null" + isDefault: + type: + - boolean + - "null" + isLocked: + type: + - boolean + - "null" + isOwner: + type: + - boolean + - "null" + name: + type: + - string + - "null" + ownerStay: + type: + - boolean + - "null" + personalUse: + type: + - boolean + - "null" + portalReservationBreakdown: + type: + - boolean + - "null" + posDefaultAllow: + type: + - boolean + - "null" + posDefaultLimit: + type: + - string + - "null" + publicName: + type: + - string + - "null" + realizeRates: + type: + - string + - "null" + rentEarned: + type: + - string + - "null" + requirePayment: + type: + - boolean + - "null" + requiresAgreement: + type: + - boolean + - "null" + schedulePercentage1: + type: + - number + - "null" + schedulePercentage2: + type: + - number + - "null" + sendPortalInvites: + type: + - boolean + - "null" + showFolioTransactions: + type: + - boolean + - "null" + typeColor: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + travelAgent: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + achAccountNumber: + type: + - string + - "null" + achAccountType: + type: + - string + - "null" + achRoutingNumber: + type: + - string + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + email: + type: + - string + - "null" + extendedAddress: + type: + - string + - "null" + fax: + type: + - string + - "null" + glInsurancePolicy: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + locality: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + paymentType: + type: + - string + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + region: + type: + - string + - "null" + streetAddress: + type: + - string + - "null" + tags: + type: + - array + - "null" + taxId: + type: + - string + - "null" + taxName: + type: + - string + - "null" + taxType: + type: + - string + - "null" + travelAgentCommission: + type: + - number + - "null" + travelAgentDeductCommission: + type: + - boolean + - "null" + travelAgentIataNumber: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + wcInsurancePolicy: + type: + - string + - "null" + website: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + airbnbTaxAttestation: + type: + - boolean + - "null" + allReservationsApi: + type: + - boolean + - "null" + allUnitsApi: + type: + - boolean + - "null" + allowAboveMaxNights: + type: + - boolean + - "null" + campaignId: + type: + - number + - "null" + channelData: + type: + - object + - "null" + confirmationEmail: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + customPricing: + type: + - boolean + - "null" + enableConfirmationEmail: + type: + - boolean + - "null" + enableNodesApi: + type: + - boolean + - "null" + id: + type: + - number + - "null" + includeContact: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isChannelInventoryEnabled: + type: + - boolean + - "null" + masterChannelId: + type: + - number + - "null" + maxBookingPeriod: + type: + - number + - "null" + minArrival: + type: + - number + - "null" + name: + type: + - string + - "null" + paymentMethodId: + type: + - number + - "null" + paymentsAccepted: + type: + - string + - "null" + petReservationMode: + type: + - boolean + - "null" + processingLimit: + type: + - number + - "null" + requestEmail: + type: + - string + - "null" + reservationMode: + type: + - string + - "null" + reservationTypeId: + type: + - number + - "null" + retainOnPaymentFailure: + type: + - boolean + - "null" + travelAgentId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + useLosPricing: + type: + - boolean + - "null" + channelId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + enableChannel: + type: + - boolean + - "null" + id: + type: number + metaData: + type: + - object + - "null" + unit_id: + type: number + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - unit_id + - id + housekeeping-work-orders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + properties: + unitBlock: + type: + - object + - "null" + properties: + _embedded: + type: + - object + - "null" + properties: + cleanType: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + reason: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + unit: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + blockNotes: + type: + - string + - "null" + blockReasonId: + type: + - number + - "null" + blockReasonInline: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + chargeOwner: + type: + - boolean + - "null" + cleanTypeId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + endDate: + type: + - string + - "null" + id: + type: + - number + - "null" + isArchived: + type: + - boolean + - "null" + notes: + type: + - string + - "null" + reasonId: + type: + - number + - "null" + startDate: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + actualTime: + type: + - number + - "null" + chargeOwner: + type: + - boolean + - "null" + cleanTypeId: + type: + - number + - "null" + comments: + type: + - string + - "null" + completedAt: + type: + - string + - "null" + completedById: + type: + - number + - "null" + cost: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: number + isInspection: + type: + - boolean + - "null" + isManual: + type: + - boolean + - "null" + isTurn: + type: + - boolean + - "null" + nextReservationId: + type: + - number + - "null" + originalScheduledAt: + type: + - string + - "null" + ownerId: + type: + - number + - "null" + processedAt: + type: + - string + - "null" + processedById: + type: + - number + - "null" + reservationId: + type: + - number + - "null" + scheduledAt: + type: + - string + - "null" + status: + type: + - string + - "null" + timeEstimate: + type: + - number + - "null" + unitBlockId: + type: + - number + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: string + updatedBy: + type: + - string + - "null" + userId: + type: + - number + - "null" + vendorId: + type: + - number + - "null" + required: + - id + - updatedAt + housekeeping-clean-types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + item: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + revenueAccount: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + isDeferExempted: + type: + - boolean + - "null" + isTaxable: + type: + - boolean + - "null" + itemCategories: + type: + - array + - "null" + name: + type: + - string + - "null" + revenueAccountId: + type: + - number + - "null" + revenueAccounts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + account: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + accountType: + type: + - string + - "null" + achEnabled: + type: + - boolean + - "null" + allowOwnerPayments: + type: + - boolean + - "null" + category: + type: + - string + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currentBalance: + type: + - string + - "null" + defaultRefundAccount: + type: + - boolean + - "null" + enableRefunds: + type: + - boolean + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + parentId: + type: + - number + - "null" + recursiveBalance: + type: + - string + - "null" + stakeholderId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + accountId: + type: + - number + - "null" + accountSplit: + type: + - string + - "null" + taxPolicyType: + type: + - string + - "null" + unitPrice: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + chargeOwner: + type: + - boolean + - "null" + chargeOwnerDefaultAmount: + type: + - string + - "null" + chargeOwnerItemId: + type: + - number + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + expenseAccountId: + type: + - number + - "null" + generateLinenTicket: + type: + - boolean + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + taskListId: + type: + - number + - "null" + timeEstimate: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + housekeeping-task-list: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + tasks: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + sortOrder: + type: + - number + - "null" + task: + type: + - string + - "null" + taskTemplateId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + folios-master-rules: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + breakdownChargesIncludeTax: + type: + - boolean + - "null" + breakdownChargesMode: + type: + - string + - "null" + breakdownChargesPercent: + type: + - string + - "null" + breakdownFeeIncludeTax: + type: + - boolean + - "null" + breakdownFeeMode: + type: + - string + - "null" + breakdownFeePercent: + type: + - string + - "null" + breakdownRentIncludeTax: + type: + - boolean + - "null" + breakdownRentMode: + type: + - string + - "null" + breakdownRentPercent: + type: + - string + - "null" + code: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + percentAmount: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + contact_companies: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + companyId: + type: number + contactId: + type: number + isPrimaryContact: + type: + - boolean + - "null" + ownerSplit: + type: + - string + - "null" + ownerType: + type: + - string + - "null" + required: + - contactId + - companyId + reviews: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + autoReview: + type: + - number + - "null" + autoReviewDate: + type: + - string + - "null" + autoReviewPreference: + type: + - boolean + - "null" + channelId: + type: + - number + - "null" + channelListingId: + type: + - string + - "null" + channelName: + type: + - string + - "null" + channelReviewResponse: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + hostRespondAtDate: + type: + - string + - "null" + hostResponse: + type: + - string + - "null" + channelReviews: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + privateFeedback: + type: + - string + - "null" + publicReview: + type: + - string + - "null" + reviewCreatedAt: + type: + - string + - "null" + reviewRatings: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + category: + type: + - string + - "null" + id: + type: + - number + - "null" + rating: + type: + - string + - "null" + reviewStatus: + type: + - string + - "null" + reviewerRole: + type: + - string + - "null" + reviewerSubmittedAt: + type: + - string + - "null" + channelUnitId: + type: + - number + - "null" + checkInDate: + type: + - string + - "null" + checkOutDate: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + guestName: + type: + - string + - "null" + handle: + type: + - string + - "null" + hostResponseExpiresAt: + type: + - string + - "null" + hostResponseStatus: + type: + - string + - "null" + hostReviewExpiresAt: + type: + - string + - "null" + hostReviewStatus: + type: + - string + - "null" + id: + type: number + lengthOfStay: + type: + - number + - "null" + overAllRating: + type: + - string + - "null" + reservationConfirmationCode: + type: + - string + - "null" + reservationId: + type: + - number + - "null" + trackReservationNumber: + type: + - number + - "null" + unitId: + type: + - number + - "null" + unitImageUrl: + type: + - string + - "null" + unitName: + type: + - string + - "null" + required: + - id + accounting-deposits: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + amount: + type: + - string + - "null" + bankAccountId: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + depositType: + type: + - string + - "null" + id: + type: number + memo: + type: + - string + - "null" + token: + type: + - string + - "null" + transactionIds: + type: + - array + - "null" + items: + type: + - number + - "null" + txnDate: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + accounting-deposits-payments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + accountType: + type: + - string + - "null" + amount: + type: + - string + - "null" + date: + type: + - string + - "null" + folioId: + type: + - string + - "null" + id: + type: string + isPending: + type: + - string + - "null" + reference: + type: + - string + - "null" + transactionType: + type: + - string + - "null" + required: + - id + units_pricing_parent: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + amenitiesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + area: + type: + - number + - "null" + availabilityOrder: + type: + - number + - "null" + bedTypes: + type: + - array + - "null" + bedrooms: + type: + - number + - "null" + cancellationPoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + checkinTime: + type: + - string + - "null" + checkoutTime: + type: + - string + - "null" + childrenAllowed: + type: + - boolean + - "null" + cleanStatusId: + type: + - number + - "null" + cleanStatusType: + type: + - string + - "null" + composites: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + unitId: + type: + - number + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + pms_units_owner_notes: + type: + - string + - "null" + pms_units_source_unit_id: + type: + - string + - "null" + pms_units_wifi_information: + type: + - string + - "null" + documentsIds: + type: + - array + - "null" + items: + type: + - number + - "null" + earlyCheckinTime: + type: + - string + - "null" + eventsAllowed: + type: + - boolean + - "null" + extendedAddress: + type: + - string + - "null" + folioException: + type: + - boolean + - "null" + fullBathrooms: + type: + - number + - "null" + gatewaysIds: + type: + - array + - "null" + items: + type: + - number + - "null" + guaranteePoliciesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + halfBathrooms: + type: + - number + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + housekeepingMessage: + type: + - string + - "null" + housekeepingNotes: + type: + - string + - "null" + id: + type: number + isAccessible: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isBookable: + type: + - boolean + - "null" + isLimited: + type: + - boolean + - "null" + isOccupied: + type: + - boolean + - "null" + lateCheckoutTime: + type: + - string + - "null" + latitude: + type: + - string + - "null" + localOfficeId: + type: + - number + - "null" + locality: + type: + - string + - "null" + lodgingTypeId: + type: + - number + - "null" + longitude: + type: + - string + - "null" + maintenanceMessage: + type: + - string + - "null" + maxOccupancy: + type: + - number + - "null" + minimumAgeLimit: + type: + - number + - "null" + name: + type: + - string + - "null" + nodeId: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + region: + type: + - string + - "null" + roles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + roleId: + type: + - number + - "null" + userId: + type: + - number + - "null" + securityDeposit: + type: + - string + - "null" + shortName: + type: + - string + - "null" + smokingAllowed: + type: + - boolean + - "null" + streetAddress: + type: + - string + - "null" + taxDistrictId: + type: + - number + - "null" + taxId: + type: + - string + - "null" + threeQuarterBathrooms: + type: + - number + - "null" + timezone: + type: + - string + - "null" + travelInsuranceProductId: + type: + - number + - "null" + typeId: + type: + - number + - "null" + unitCode: + type: + - string + - "null" + updatedAt: + type: string + updatedBy: + type: + - string + - "null" + useBedTypes: + type: + - boolean + - "null" + useRoomConfiguration: + type: + - boolean + - "null" + websiteUrl: + type: + - string + - "null" + required: + - id + - updatedAt + unit_types_pricing_parent: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + properties: + calendarGroup: + type: + - object + - "null" + properties: + _links: + type: + - object + - "null" + properties: + self: + type: + - object + - "null" + properties: + href: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: + - number + - "null" + name: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + allowOversell: + type: + - boolean + - "null" + allowUnitRates: + type: + - boolean + - "null" + amenitiesIds: + type: + - array + - "null" + items: + type: + - number + - "null" + bedTypes: + type: + - array + - "null" + calendarGroupId: + type: + - number + - "null" + cancellationPoliciesIds: + type: + - array + - "null" + childrenAllowed: + type: + - boolean + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + pms_unit_types_pre_arrival_info: + type: + - string + - "null" + documentsIds: + type: + - array + - "null" + eventsAllowed: + type: + - boolean + - "null" + folioException: + type: + - boolean + - "null" + gatewaysIds: + type: + - array + - "null" + guaranteePoliciesIds: + type: + - array + - "null" + hasEarlyCheckin: + type: + - boolean + - "null" + hasLateCheckout: + type: + - boolean + - "null" + id: + type: number + isAccessible: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isBookable: + type: + - boolean + - "null" + lodgingTypeId: + type: + - number + - "null" + name: + type: + - string + - "null" + oversellLimit: + type: + - number + - "null" + petFriendly: + type: + - boolean + - "null" + quickCheckin: + type: + - boolean + - "null" + quickCheckout: + type: + - boolean + - "null" + roles: + type: + - array + - "null" + securityDeposit: + type: + - string + - "null" + shortName: + type: + - string + - "null" + smokingAllowed: + type: + - boolean + - "null" + typeCode: + type: + - string + - "null" + updated: + type: + - object + - "null" + properties: + availability: + type: + - string + - "null" + content: + type: + - string + - "null" + pricing: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + useBedTypes: + type: + - boolean + - "null" + useRoomConfiguration: + type: + - boolean + - "null" + required: + - id + unit_charge_pricing_parent: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + properties: + item: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + id: + type: + - number + - "null" + isActive: + type: + - boolean + - "null" + isDeferExempted: + type: + - boolean + - "null" + isTaxable: + type: + - boolean + - "null" + itemCategories: + type: + - array + - "null" + items: + type: + - string + - "null" + name: + type: + - string + - "null" + revenueAccountId: + type: + - number + - "null" + taxPolicyId: + type: + - number + - "null" + taxPolicyType: + type: + - string + - "null" + unitPrice: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + airbnbProductCode: + type: + - string + - "null" + allowFeeEdit: + type: + - boolean + - "null" + allowFeeRemoval: + type: + - boolean + - "null" + amount: + type: + - string + - "null" + applyUnitTaxes: + type: + - boolean + - "null" + bookingDotComProductCode: + type: + - string + - "null" + channelStackedFees: + type: + - boolean + - "null" + chargeOwner: + type: + - boolean + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + dateRangeType: + type: + - string + - "null" + defaultQuantity: + type: + - number + - "null" + displayAs: + type: + - string + - "null" + displayName: + type: + - string + - "null" + excludeFromInsurance: + type: + - boolean + - "null" + feeType: + type: + - string + - "null" + frequency: + type: + - string + - "null" + hasUnitPricing: + type: + - boolean + - "null" + homeawayProductCode: + type: + - string + - "null" + id: + type: number + includeAllResTypes: + type: + - boolean + - "null" + includeInSubtotal: + type: + - boolean + - "null" + irmEnabled: + type: + - boolean + - "null" + isActive: + type: + - boolean + - "null" + isDeferExempted: + type: + - boolean + - "null" + isStacked: + type: + - boolean + - "null" + itemId: + type: + - number + - "null" + marriottProductCode: + type: + - string + - "null" + maxQuantity: + type: + - number + - "null" + minStayLength: + type: + - number + - "null" + minimumAmount: + type: + - string + - "null" + name: + type: + - string + - "null" + postDate: + type: + - string + - "null" + rateType: + type: + - string + - "null" + requireFunding: + type: + - boolean + - "null" + reservationTypeIds: + type: + - array + - "null" + items: + type: + - number + - "null" + splitWithOwner: + type: + - boolean + - "null" + taxPolicyType: + type: + - string + - "null" + template: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - id + owners-pii-redacted: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + achAccountNumber: + type: + - string + - "null" + achAccountType: + type: + - string + - "null" + achRoutingNumber: + type: + - string + - "null" + activeUnitCount: + type: + - number + - "null" + agentCommission: + type: + - string + - "null" + alwaysShowInStatements: + type: + - boolean + - "null" + companyId: + type: + - number + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currentBalance: + type: + - string + - "null" + deferredBalance: + type: + - string + - "null" + email: + type: + - string + - "null" + extendedAddress: + type: + - string + - "null" + fax: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + locality: + type: + - string + - "null" + minimumBalance: + type: + - string + - "null" + name: + type: + - string + - "null" + notes: + type: + - string + - "null" + paymentType: + type: + - string + - "null" + phone: + type: + - string + - "null" + postal: + type: + - string + - "null" + region: + type: + - string + - "null" + splitWithContacts: + type: + - boolean + - "null" + streetAddress: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + taxCountry: + type: + - string + - "null" + taxExtendedAddress: + type: + - string + - "null" + taxId: + type: + - string + - "null" + taxLocality: + type: + - string + - "null" + taxName: + type: + - string + - "null" + taxPostalCode: + type: + - string + - "null" + taxRegion: + type: + - string + - "null" + taxStreetAddress: + type: + - string + - "null" + taxType: + type: + - string + - "null" + updatedAt: + type: string + updatedBy: + type: + - string + - "null" + website: + type: + - string + - "null" + required: + - id + - updatedAt + contacts-pii-redacted: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + achAccountNumber: + type: + - string + - "null" + achAccountType: + type: + - string + - "null" + achRoutingNumber: + type: + - string + - "null" + cellPhone: + type: + - string + - "null" + country: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + custom: + type: + - object + - "null" + properties: + custom_5: + type: + - string + - "null" + custom_6: + type: + - string + - "null" + extendedAddress: + type: + - string + - "null" + firstName: + type: + - string + - "null" + homePhone: + type: + - string + - "null" + id: + type: number + isBlacklist: + type: + - boolean + - "null" + isDNR: + type: + - boolean + - "null" + isOwnerContact: + type: + - boolean + - "null" + isVip: + type: + - boolean + - "null" + lastName: + type: + - string + - "null" + locality: + type: + - string + - "null" + name: + type: + - string + - "null" + noIdentity: + type: + - boolean + - "null" + notes: + type: + - string + - "null" + otherPhone: + type: + - string + - "null" + paymentType: + type: + - string + - "null" + portalInviteStatus: + type: + - string + - "null" + portalLastLogin: + type: + - string + - "null" + postalCode: + type: + - string + - "null" + primaryEmail: + type: + - string + - "null" + quoteCount: + type: + - string + - "null" + references: + type: + - array + - "null" + region: + type: + - string + - "null" + secondaryEmail: + type: + - string + - "null" + streetAddress: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - number + - "null" + name: + type: + - string + - "null" + taxId: + type: + - string + - "null" + updatedAt: + type: string + updatedBy: + type: + - string + - "null" + workPhone: + type: + - string + - "null" + required: + - id + - updatedAt + owner_statement_transactions_pii_redacted: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + _embedded: + type: + - object + - "null" + createdAt: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + currency: + type: + - string + - "null" + id: + type: number + isDeferred: + type: + - boolean + - "null" + isPending: + type: + - boolean + - "null" + isVoided: + type: + - boolean + - "null" + lines: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + account: + type: + - string + - "null" + accountId: + type: + - number + - "null" + amount: + type: + - string + - "null" + id: + type: + - number + - "null" + reconcile: + type: + - string + - "null" + statementId: + type: + - number + - "null" + taxOnMarkUp: + type: + - boolean + - "null" + unitAmount: + type: + - string + - "null" + unitId: + type: + - number + - "null" + unitName: + type: + - string + - "null" + memo: + type: + - string + - "null" + ownerTransaction: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + id: + type: + - number + - "null" + ownerId: + type: + - number + - "null" + statementId: + type: + - number + - "null" + reference: + type: + - string + - "null" + statement_id: + type: number + txnDate: + type: + - string + - "null" + unitId: + type: + - number + - "null" + updatedAt: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + required: + - statement_id + - id + users-pii-redacted: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _embedded: + type: + - object + - "null" + assignable: + type: + - array + - "null" + items: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: number + isActive: + type: + - boolean + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + updatedBy: + type: + - string + - "null" + username: + type: + - string + - "null" + vendorId: + type: + - number + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-track-pms/metadata.yaml b/airbyte-integrations/connectors/source-track-pms/metadata.yaml new file mode 100644 index 000000000000..1ca0493e549d --- /dev/null +++ b/airbyte-integrations/connectors/source-track-pms/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "*" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-track-pms + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:5.14.0@sha256:accdf6c1bbcabd45b40f836692e4f3b1a1e1f0b28267973802ee212cd9c2c16a + connectorSubtype: api + connectorType: source + definitionId: aa0373c1-a7a6-48ff-8277-e5fe6cecff75 + dockerImageTag: 0.0.1 + dockerRepository: airbyte/source-track-pms + githubIssueLabel: source-track-pms + icon: icon.svg + license: MIT + name: Track PMS + releaseDate: 2024-10-18 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/track-pms + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-trello/components.py b/airbyte-integrations/connectors/source-trello/components.py index dfcb6799f92b..31c67c6ad62e 100644 --- a/airbyte-integrations/connectors/source-trello/components.py +++ b/airbyte-integrations/connectors/source-trello/components.py @@ -14,7 +14,6 @@ @dataclass class OrderIdsPartitionRouter(SubstreamPartitionRouter): def stream_slices(self) -> Iterable[StreamSlice]: - stream_map = {stream_config.stream.name: stream_config.stream for stream_config in self.parent_stream_configs} board_ids = set(self.config.get("board_ids", [])) diff --git a/airbyte-integrations/connectors/source-trello/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-trello/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-trello/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-trello/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-trello/unit_tests/test_order_ids_partition_router.py b/airbyte-integrations/connectors/source-trello/unit_tests/test_order_ids_partition_router.py index 439e5148ef2b..6cc39f099c5d 100644 --- a/airbyte-integrations/connectors/source-trello/unit_tests/test_order_ids_partition_router.py +++ b/airbyte-integrations/connectors/source-trello/unit_tests/test_order_ids_partition_router.py @@ -4,9 +4,10 @@ import pytest -from airbyte_cdk.sources.streams.core import Stream from source_trello.components import OrderIdsPartitionRouter +from airbyte_cdk.sources.streams.core import Stream + class MockStream(Stream): def __init__(self, records): diff --git a/airbyte-integrations/connectors/source-tremendous/README.md b/airbyte-integrations/connectors/source-tremendous/README.md new file mode 100644 index 000000000000..5185190f0fe9 --- /dev/null +++ b/airbyte-integrations/connectors/source-tremendous/README.md @@ -0,0 +1,33 @@ +# Tremendous +This directory contains the manifest-only connector for `source-tremendous`. + +Tremendous connector enables seamless integration with Tremendous API. This connector allows organizations to automate and sync reward, incentive, and payout data, tapping into 2000+ payout methods, including ACH, gift cards, PayPal, and prepaid cards, all from a single platform. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-tremendous:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-tremendous build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-tremendous test +``` + diff --git a/airbyte-integrations/connectors/source-tremendous/acceptance-test-config.yml b/airbyte-integrations/connectors/source-tremendous/acceptance-test-config.yml new file mode 100644 index 000000000000..ed2d47e4740e --- /dev/null +++ b/airbyte-integrations/connectors/source-tremendous/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-tremendous:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-tremendous/icon.svg b/airbyte-integrations/connectors/source-tremendous/icon.svg new file mode 100644 index 000000000000..f1458bdd973e --- /dev/null +++ b/airbyte-integrations/connectors/source-tremendous/icon.svg @@ -0,0 +1,276 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-tremendous/manifest.yaml b/airbyte-integrations/connectors/source-tremendous/manifest.yaml new file mode 100644 index 000000000000..b54510f646a0 --- /dev/null +++ b/airbyte-integrations/connectors/source-tremendous/manifest.yaml @@ -0,0 +1,954 @@ +version: 5.17.0 + +type: DeclarativeSource + +description: >- + Tremendous connector enables seamless integration with Tremendous API. This + connector allows organizations to automate and sync reward, incentive, and + payout data, tapping into 2000+ payout methods, including ACH, gift cards, + PayPal, and prepaid cards, all from a single platform. + +check: + type: CheckStream + stream_names: + - orders + +definitions: + streams: + orders: + type: DeclarativeStream + name: orders + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/orders + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - orders + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: false + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/orders" + products: + type: DeclarativeStream + name: products + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/products + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - products + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + pagination_strategy: + type: OffsetIncrement + inject_on_first_request: false + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + funding_sources: + type: DeclarativeStream + name: funding_sources + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/funding_sources + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - funding_sources + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + pagination_strategy: + type: OffsetIncrement + page_size: 10 + inject_on_first_request: false + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/funding_sources" + account_members: + type: DeclarativeStream + name: account_members + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/members + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - members + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + pagination_strategy: + type: OffsetIncrement + page_size: 10 + inject_on_first_request: false + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/account_members" + campaigns: + type: DeclarativeStream + name: campaigns + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/campaigns + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - campaigns + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + pagination_strategy: + type: OffsetIncrement + page_size: 10 + inject_on_first_request: false + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/campaigns" + organizations: + type: DeclarativeStream + name: organizations + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/organizations + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - organizations + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + pagination_strategy: + type: OffsetIncrement + page_size: 10 + inject_on_first_request: false + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/organizations" + balance_transactions: + type: DeclarativeStream + name: balance_transactions + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/balance_transactions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - transactions + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + pagination_strategy: + type: OffsetIncrement + page_size: 10 + inject_on_first_request: false + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/balance_transactions" + rewards: + type: DeclarativeStream + name: rewards + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/rewards + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - rewards + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + pagination_strategy: + type: OffsetIncrement + page_size: 10 + inject_on_first_request: false + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/rewards" + members: + type: DeclarativeStream + name: members + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/members + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - members + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: false + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/members" + invoices: + type: DeclarativeStream + name: invoices + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2/invoices + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - invoices + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: offset + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: false + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/invoices" + base_requester: + type: HttpRequester + url_base: https://{{ config["environment"] }}.tremendous.com + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/orders" + - $ref: "#/definitions/streams/products" + - $ref: "#/definitions/streams/funding_sources" + - $ref: "#/definitions/streams/account_members" + - $ref: "#/definitions/streams/campaigns" + - $ref: "#/definitions/streams/organizations" + - $ref: "#/definitions/streams/balance_transactions" + - $ref: "#/definitions/streams/rewards" + - $ref: "#/definitions/streams/members" + - $ref: "#/definitions/streams/invoices" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - environment + properties: + api_key: + type: string + description: >- + API key to use. You can generate an API key through the Tremendous + dashboard under Team Settings > Developers. Save the key once you’ve + generated it. + name: api_key + order: 0 + title: API Key + airbyte_secret: true + environment: + type: string + enum: + - api + - testflight + order: 1 + title: Environment + additionalProperties: true + +metadata: + autoImportSchema: + orders: true + products: true + funding_sources: true + account_members: true + campaigns: true + organizations: true + balance_transactions: true + rewards: true + members: true + invoices: true + testedStreams: + orders: + hasRecords: true + streamHash: dd9ac3e7308d44dfed6de40252f859c99e04c1c8 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + products: + hasRecords: true + streamHash: c6cb16800a3e12c9eebc9c9fbd449f959d7ebec1 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + funding_sources: + hasRecords: true + streamHash: 06dcd4a04c1ebd97832ba7c747bfbadb3f6cdb1e + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + account_members: + hasRecords: true + streamHash: 371cc88527067daa1f8b1752d31f516a2c676da7 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + campaigns: + hasRecords: true + streamHash: 15fed638e51342240d46f6efb8f3cb8e384db2aa + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + organizations: + hasRecords: true + streamHash: c1ab194ed5a9d57adf721f9d3d66ef97702cdbd3 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + balance_transactions: + hasRecords: true + streamHash: dae4c687de6c466303e9dae084c6249dbb9e7cab + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + rewards: + hasRecords: true + streamHash: 30f243c223daae7ffb4d35b4acfc8e6774daa11b + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + members: + streamHash: efe28ca3fd698fd3e3b911c2691cf3552f887a01 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + invoices: + streamHash: e889a596aaf7abae9f180dfe83617f44b71acfe3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: false + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://developers.tremendous.com/docs/introduction + +schemas: + orders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + campaign_id: + type: + - string + - "null" + channel: + type: + - string + - "null" + created_at: + type: + - string + - "null" + id: + type: string + payment: + type: + - object + - "null" + properties: + discount: + type: + - number + - "null" + fees: + type: + - number + - "null" + subtotal: + type: + - number + - "null" + total: + type: + - number + - "null" + rewards: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + created_at: + type: + - string + - "null" + delivery: + type: + - object + - "null" + properties: + method: + type: + - string + - "null" + status: + type: + - string + - "null" + id: + type: + - string + - "null" + order_id: + type: + - string + - "null" + recipient: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + value: + type: + - object + - "null" + properties: + currency_code: + type: + - string + - "null" + denomination: + type: + - number + - "null" + status: + type: + - string + - "null" + required: + - id + products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + category: + type: + - string + - "null" + countries: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + abbr: + type: + - string + - "null" + currency_codes: + type: + - array + - "null" + items: + type: + - string + - "null" + disclosure: + type: + - string + - "null" + id: + type: + - string + - "null" + images: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + src: + type: + - string + - "null" + name: + type: + - string + - "null" + skus: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + max: + type: + - number + - "null" + min: + type: + - number + - "null" + funding_sources: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: string + meta: + type: + - object + - "null" + properties: + available_cents: + type: + - number + - "null" + pending_cents: + type: + - number + - "null" + method: + type: + - string + - "null" + required: + - id + account_members: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + role: + type: + - string + - "null" + status: + type: + - string + - "null" + required: + - id + campaigns: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + email_style: + type: + - object + - "null" + properties: + sender_name: + type: + - string + - "null" + subject_line: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + products: + type: + - array + - "null" + items: + type: + - string + - "null" + webpage_style: + type: + - object + - "null" + properties: + background_color: + type: + - string + - "null" + headline: + type: + - string + - "null" + logo_background_color: + type: + - string + - "null" + logo_image_height_px: + type: + - number + - "null" + logo_image_url: + type: + - string + - "null" + message: + type: + - string + - "null" + required: + - id + organizations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: string + name: + type: + - string + - "null" + status: + type: + - string + - "null" + website: + type: + - string + - "null" + required: + - id + balance_transactions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + action: + type: + - string + - "null" + amount: + type: + - number + - "null" + balance: + type: + - number + - "null" + created_at: + type: + - string + - "null" + order: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + payment: + type: + - object + - "null" + properties: + discount: + type: + - number + - "null" + fees: + type: + - number + - "null" + subtotal: + type: + - number + - "null" + total: + type: + - number + - "null" + rewards: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_at: + type: + - string + - "null" + delivery: + type: + - object + - "null" + properties: + method: + type: + - string + - "null" + status: + type: + - string + - "null" + id: + type: string + order_id: + type: + - string + - "null" + recipient: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + value: + type: + - object + - "null" + properties: + currency_code: + type: + - string + - "null" + denomination: + type: + - number + - "null" + required: + - id + members: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + active: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + role: + type: + - string + - "null" + status: + type: + - string + - "null" + required: + - id + invoices: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: {} diff --git a/airbyte-integrations/connectors/source-tremendous/metadata.yaml b/airbyte-integrations/connectors/source-tremendous/metadata.yaml new file mode 100644 index 000000000000..1e44d14a7994 --- /dev/null +++ b/airbyte-integrations/connectors/source-tremendous/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "https:" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-tremendous + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 6a91b109-0286-40a0-801b-ac86933a44d4 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-tremendous + githubIssueLabel: source-tremendous + icon: icon.svg + license: MIT + name: Tremendous + releaseDate: 2024-10-29 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/tremendous + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-trustpilot/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-trustpilot/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-trustpilot/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-trustpilot/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-trustpilot/metadata.yaml b/airbyte-integrations/connectors/source-trustpilot/metadata.yaml index 56b273e52d13..a6a6306c8a51 100644 --- a/airbyte-integrations/connectors/source-trustpilot/metadata.yaml +++ b/airbyte-integrations/connectors/source-trustpilot/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: d7e23ea6-d741-4314-9209-a33c91a2e945 - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.6 dockerRepository: airbyte/source-trustpilot githubIssueLabel: source-trustpilot icon: trustpilot.svg @@ -40,5 +40,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-tvmaze-schedule/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-tvmaze-schedule/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-tvmaze-schedule/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-tvmaze-schedule/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-tvmaze-schedule/metadata.yaml b/airbyte-integrations/connectors/source-tvmaze-schedule/metadata.yaml index 6863545c6c85..cf05646ed095 100644 --- a/airbyte-integrations/connectors/source-tvmaze-schedule/metadata.yaml +++ b/airbyte-integrations/connectors/source-tvmaze-schedule/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: bd14b08f-9f43-400f-b2b6-7248b5c72561 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-tvmaze-schedule githubIssueLabel: source-tvmaze-schedule icon: tvmazeschedule.svg @@ -42,5 +42,5 @@ data: # type: GSM # alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-twelve-data/metadata.yaml b/airbyte-integrations/connectors/source-twelve-data/metadata.yaml index ff28af0008b5..ef649512ae05 100644 --- a/airbyte-integrations/connectors/source-twelve-data/metadata.yaml +++ b/airbyte-integrations/connectors/source-twelve-data/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-twelve-data connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.14.0@sha256:accdf6c1bbcabd45b40f836692e4f3b1a1e1f0b28267973802ee212cd9c2c16a + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 162f084d-3a9f-42c0-8785-81aa18abf339 - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-twelve-data githubIssueLabel: source-twelve-data icon: icon.svg diff --git a/airbyte-integrations/connectors/source-twilio-taskrouter/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-twilio-taskrouter/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-twilio-taskrouter/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-twilio-taskrouter/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-twilio-taskrouter/metadata.yaml b/airbyte-integrations/connectors/source-twilio-taskrouter/metadata.yaml index 18dd34cb175a..dc53b8b44f0b 100644 --- a/airbyte-integrations/connectors/source-twilio-taskrouter/metadata.yaml +++ b/airbyte-integrations/connectors/source-twilio-taskrouter/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 2446953b-b794-429b-a9b3-c821ba992a48 - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.4 dockerRepository: airbyte/source-twilio-taskrouter documentationUrl: https://docs.airbyte.com/integrations/sources/twilio-taskrouter githubIssueLabel: source-twilio-taskrouter diff --git a/airbyte-integrations/connectors/source-twilio/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-twilio/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-twilio/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-twilio/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-twilio/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-twilio/integration_tests/expected_records.jsonl index 65bb012b98d0..891e811a1f0a 100644 --- a/airbyte-integrations/connectors/source-twilio/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-twilio/integration_tests/expected_records.jsonl @@ -22,10 +22,10 @@ {"stream": "incoming_phone_numbers", "data": {"origin": "twilio", "status": "in-use", "address_requirements": "none", "date_updated": "2023-03-27T07:57:03Z", "voice_url": "https://handler.twilio.com/twiml/EH5793263d703ad674bbcdeb31ac80e359", "sms_application_sid": "", "voice_fallback_method": "POST", "emergency_address_status": "unregistered", "identity_sid": null, "emergency_status": "Active", "voice_application_sid": "", "capabilities": {"fax": false, "voice": true, "sms": true, "mms": true}, "api_version": "2010-04-01", "sid": "PNf2eb05a16e73094f891b01076b830a6a", "status_callback_method": "POST", "voice_fallback_url": "", "phone_number": "+16508997708", "emergency_address_sid": null, "beta": false, "address_sid": "AD07820b628d536f40af85140c67e108f0", "sms_url": "https://webhooks.twilio.com/v1/Accounts/ACdade166c12e160e9ed0a6088226718fb/Flows/FWbd726b7110b21294a9f27a47f4ab0080", "voice_method": "POST", "voice_caller_id_lookup": false, "friendly_name": "Test phone number 8", "uri": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/IncomingPhoneNumbers/PNf2eb05a16e73094f891b01076b830a6a.json", "sms_fallback_url": "", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "sms_method": "POST", "trunk_sid": null, "sms_fallback_method": "POST", "date_created": "2023-02-16T14:31:29Z", "bundle_sid": null, "status_callback": "", "subresource_uris": {"assigned_add_ons": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/IncomingPhoneNumbers/PNf2eb05a16e73094f891b01076b830a6a/AssignedAddOns.json"}}, "emitted_at": 1691419867845} {"stream": "incoming_phone_numbers", "data": {"origin": "twilio", "status": "in-use", "address_requirements": "none", "date_updated": "2023-03-27T07:58:14Z", "voice_url": "https://handler.twilio.com/twiml/EHb6471af720e8b66baa14e7226227893b", "sms_application_sid": "", "voice_fallback_method": "POST", "emergency_address_status": "unregistered", "identity_sid": null, "emergency_status": "Active", "voice_application_sid": "", "capabilities": {"fax": false, "voice": true, "sms": true, "mms": true}, "api_version": "2010-04-01", "sid": "PNd74715bab1be123cc9004f03b85bb067", "status_callback_method": "POST", "voice_fallback_url": "", "phone_number": "+14246220939", "emergency_address_sid": null, "beta": false, "address_sid": "AD0164001bc0f84d9bc29e17378fe47c20", "sms_url": "https://webhooks.twilio.com/v1/Accounts/ACdade166c12e160e9ed0a6088226718fb/Flows/FWbd726b7110b21294a9f27a47f4ab0080", "voice_method": "POST", "voice_caller_id_lookup": false, "friendly_name": "Test phone number 9", "uri": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/IncomingPhoneNumbers/PNd74715bab1be123cc9004f03b85bb067.json", "sms_fallback_url": "", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "sms_method": "POST", "trunk_sid": null, "sms_fallback_method": "POST", "date_created": "2023-02-16T14:34:00Z", "bundle_sid": null, "status_callback": "", "subresource_uris": {"assigned_add_ons": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/IncomingPhoneNumbers/PNd74715bab1be123cc9004f03b85bb067/AssignedAddOns.json"}}, "emitted_at": 1691419867848} {"stream": "incoming_phone_numbers", "data": {"origin": "twilio", "status": "in-use", "address_requirements": "none", "date_updated": "2023-03-27T07:58:40Z", "voice_url": "https://handler.twilio.com/twiml/EHb77bc7c1f889b6c9fe5202d0463edfc4", "sms_application_sid": "", "voice_fallback_method": "POST", "emergency_address_status": "unregistered", "identity_sid": null, "emergency_status": "Active", "voice_application_sid": "", "capabilities": {"fax": false, "voice": true, "sms": true, "mms": true}, "api_version": "2010-04-01", "sid": "PN99400a65bf5a4305d5420060842d4d2c", "status_callback_method": "POST", "voice_fallback_url": "", "phone_number": "+19125901057", "emergency_address_sid": null, "beta": false, "address_sid": "AD0e69bf9110f766787a88f99b507c9eeb", "sms_url": "https://webhooks.twilio.com/v1/Accounts/ACdade166c12e160e9ed0a6088226718fb/Flows/FWbd726b7110b21294a9f27a47f4ab0080", "voice_method": "POST", "voice_caller_id_lookup": false, "friendly_name": "Test phone number 2", "uri": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/IncomingPhoneNumbers/PN99400a65bf5a4305d5420060842d4d2c.json", "sms_fallback_url": "", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "sms_method": "POST", "trunk_sid": null, "sms_fallback_method": "POST", "date_created": "2023-02-15T09:31:24Z", "bundle_sid": null, "status_callback": "", "subresource_uris": {"assigned_add_ons": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/IncomingPhoneNumbers/PN99400a65bf5a4305d5420060842d4d2c/AssignedAddOns.json"}}, "emitted_at": 1691419867849} -{"stream": "message_media", "data": {"sid": "ME66ee8039997ee13231f5bd4a9121162c", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "parent_sid": "MMf491b7a98d00cdf54afc20b1839cea4e", "content_type": "image/png", "date_created": "2023-07-19T07:03:14Z", "date_updated": "2023-07-19T07:03:14Z", "uri": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/MMf491b7a98d00cdf54afc20b1839cea4e/Media/ME66ee8039997ee13231f5bd4a9121162c.json"}, "emitted_at": 1691419887396} -{"stream": "messages", "data": {"body": "Bring your ass..let's get it now", "num_segments": 1, "direction": "inbound", "from": "+12052003153", "date_updated": "2023-07-01T18:57:02Z", "price": -0.01, "error_message": null, "uri": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/MMb241f4a1fc983b30c085c70e5ddcb6b9.json", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "num_media": 0, "to": "+12056561170", "date_created": "2023-07-01T18:57:02Z", "status": "received", "sid": "MMb241f4a1fc983b30c085c70e5ddcb6b9", "date_sent": "2023-07-01T18:57:02Z", "messaging_service_sid": null, "error_code": null, "price_unit": "USD", "api_version": "2010-04-01", "subresource_uris": {"media": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/MMb241f4a1fc983b30c085c70e5ddcb6b9/Media.json", "feedback": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/MMb241f4a1fc983b30c085c70e5ddcb6b9/Feedback.json"}}, "emitted_at": 1710946751761} -{"stream": "messages", "data": {"body": "Hi there, Test 1!", "num_segments": 1, "direction": "outbound-api", "from": "+12056561170", "date_updated": "2023-07-24T07:03:18Z", "price": -0.02, "error_message": "Unknown error", "uri": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/MMf491b7a98d00cdf54afc20b1839cea4e.json", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "num_media": 1, "to": "+14156236785", "date_created": "2023-07-19T07:03:14Z", "status": "undelivered", "sid": "MMf491b7a98d00cdf54afc20b1839cea4e", "date_sent": "2023-07-19T07:03:15Z", "messaging_service_sid": null, "error_code": "30008", "price_unit": "USD", "api_version": "2010-04-01", "subresource_uris": {"media": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/MMf491b7a98d00cdf54afc20b1839cea4e/Media.json", "feedback": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/MMf491b7a98d00cdf54afc20b1839cea4e/Feedback.json"}}, "emitted_at": 1710946751939} -{"stream": "messages", "data": {"account_sid": "ACdade166c12e160e9ed0a6088226718fb", "api_version": "2010-04-01", "body": "That $200 didn't go through! Owe me $400 now ", "date_created": "2024-01-19T13:05:18Z", "date_sent": "2024-01-19T13:05:18Z", "date_updated": "2024-01-19T13:05:18Z", "direction": "inbound", "error_code": null, "error_message": null, "from": "+12058267189", "messaging_service_sid": null, "num_media": 0, "num_segments": 1, "price": -0.0079, "price_unit": "USD", "sid": "SM8cfbddf906bdb372750e9f1569d4f63c", "status": "received", "subresource_uris": {"feedback": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/SM8cfbddf906bdb372750e9f1569d4f63c/Feedback.json", "media": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/SM8cfbddf906bdb372750e9f1569d4f63c/Media.json"}, "to": "+12056561170", "uri": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/SM8cfbddf906bdb372750e9f1569d4f63c.json"}, "emitted_at": 1710946753193} +{"stream": "message_media", "data": {"sid": "MEf98ec83a32bb2af365047576bc761b59", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "parent_sid": "MM59e7b51de3cd19f8d66418c67764953f", "content_type": "image/png", "date_created": "2024-09-24T10:38:46Z", "date_updated": "2024-09-24T10:38:46Z", "uri": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/MM59e7b51de3cd19f8d66418c67764953f/Media/MEf98ec83a32bb2af365047576bc761b59.json"}, "emitted_at": 1731494448186} +{"stream": "messages", "data": {"account_sid": "ACdade166c12e160e9ed0a6088226718fb", "api_version": "2010-04-01", "body": "ParkMobile here! Your parking session has started at zone # 95355, space # n/a.You can park for 3 hours, 3 minutes until 5:28 PM,5/8/2024 with vehicle YLWSNO.", "date_created": "2024-05-08T20:26:00Z", "date_sent": "2024-05-08T20:26:00Z", "date_updated": "2024-05-08T20:26:00Z", "direction": "inbound", "error_code": null, "error_message": null, "from": "+16789169446", "messaging_service_sid": null, "num_media": 0, "num_segments": 1, "price": -0.0079, "price_unit": "USD", "sid": "SM9fdd0a280ff7daf063acc6d76cf25d15", "status": "received", "subresource_uris": {"feedback": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/SM9fdd0a280ff7daf063acc6d76cf25d15/Feedback.json", "media": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/SM9fdd0a280ff7daf063acc6d76cf25d15/Media.json"}, "to": "+19704017747", "uri": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/SM9fdd0a280ff7daf063acc6d76cf25d15.json"}, "emitted_at": 1731495703886} +{"stream": "messages", "data": {"account_sid": "ACdade166c12e160e9ed0a6088226718fb", "api_version": "2010-04-01", "body": "ParkMobile again! Your parking session for vehicle YLWSNO at zone # 95355, space # n/a will end at 5:28 PM,5/8/2024.", "date_created": "2024-05-08T23:13:11Z", "date_sent": "2024-05-08T23:13:12Z", "date_updated": "2024-05-08T23:13:12Z", "direction": "inbound", "error_code": null, "error_message": null, "from": "+16789740670", "messaging_service_sid": null, "num_media": 0, "num_segments": 1, "price": -0.0079, "price_unit": "USD", "sid": "SM07cfdcf8bb2440a66b26b3d4f7e5d5b5", "status": "received", "subresource_uris": {"feedback": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/SM07cfdcf8bb2440a66b26b3d4f7e5d5b5/Feedback.json", "media": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/SM07cfdcf8bb2440a66b26b3d4f7e5d5b5/Media.json"}, "to": "+19704017747", "uri": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/SM07cfdcf8bb2440a66b26b3d4f7e5d5b5.json"}, "emitted_at": 1731495703890} +{"stream": "messages", "data": {"account_sid": "ACdade166c12e160e9ed0a6088226718fb", "api_version": "2010-04-01", "body": "Your parking session for vehicle YLWSNO at zone # 95355, space # n/a has ended. You've been charged $7.00 by ParkMobile.", "date_created": "2024-05-08T23:28:11Z", "date_sent": "2024-05-08T23:28:12Z", "date_updated": "2024-05-08T23:28:12Z", "direction": "inbound", "error_code": null, "error_message": null, "from": "+16782646201", "messaging_service_sid": null, "num_media": 0, "num_segments": 1, "price": -0.0079, "price_unit": "USD", "sid": "SM692b80963e0d0ad2a8bd70e2d1f51edb", "status": "received", "subresource_uris": {"feedback": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/SM692b80963e0d0ad2a8bd70e2d1f51edb/Feedback.json", "media": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/SM692b80963e0d0ad2a8bd70e2d1f51edb/Media.json"}, "to": "+19704017747", "uri": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Messages/SM692b80963e0d0ad2a8bd70e2d1f51edb.json"}, "emitted_at": 1731495703894} {"stream": "outgoing_caller_ids", "data": {"phone_number": "+14153597503", "date_updated": "2020-11-17T04:17:37Z", "friendly_name": "(415) 359-7503", "uri": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/OutgoingCallerIds/PN16ba111c0df5756cfe37044ed0ee3136.json", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "sid": "PN16ba111c0df5756cfe37044ed0ee3136", "date_created": "2020-11-17T04:17:37Z"}, "emitted_at": 1691419960444} {"stream": "outgoing_caller_ids", "data": {"phone_number": "+18023494963", "date_updated": "2020-12-11T04:28:02Z", "friendly_name": "(802) 349-4963", "uri": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/OutgoingCallerIds/PN726d635f970c30193cd12e7b994510a1.json", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "sid": "PN726d635f970c30193cd12e7b994510a1", "date_created": "2020-12-11T04:28:02Z"}, "emitted_at": 1691419960446} {"stream": "outgoing_caller_ids", "data": {"phone_number": "+14156236785", "date_updated": "2023-02-15T15:33:09Z", "friendly_name": "Slack sms channel", "uri": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/OutgoingCallerIds/PNbb9c658169cfd057a46cdce9dc00afa3.json", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "sid": "PNbb9c658169cfd057a46cdce9dc00afa3", "date_created": "2023-02-14T12:11:53Z"}, "emitted_at": 1691419960447} diff --git a/airbyte-integrations/connectors/source-twilio/main.py b/airbyte-integrations/connectors/source-twilio/main.py index 0999d1e67f26..972b1826fb0a 100644 --- a/airbyte-integrations/connectors/source-twilio/main.py +++ b/airbyte-integrations/connectors/source-twilio/main.py @@ -4,5 +4,6 @@ from source_twilio.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-twilio/metadata.yaml b/airbyte-integrations/connectors/source-twilio/metadata.yaml index 6d1de6352e21..c4efa208b0a9 100644 --- a/airbyte-integrations/connectors/source-twilio/metadata.yaml +++ b/airbyte-integrations/connectors/source-twilio/metadata.yaml @@ -9,11 +9,11 @@ data: - chat.twilio.com - trunking.twilio.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: b9dc6155-672e-42ea-b10d-9f1f1fb95ab1 - dockerImageTag: 0.11.12 + dockerImageTag: 0.11.14 dockerRepository: airbyte/source-twilio documentationUrl: https://docs.airbyte.com/integrations/sources/twilio githubIssueLabel: source-twilio diff --git a/airbyte-integrations/connectors/source-twilio/poetry.lock b/airbyte-integrations/connectors/source-twilio/poetry.lock index 05e7ea30ccc1..b441df293541 100644 --- a/airbyte-integrations/connectors/source-twilio/poetry.lock +++ b/airbyte-integrations/connectors/source-twilio/poetry.lock @@ -62,22 +62,22 @@ files = [ [[package]] name = "attrs" -version = "23.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, - {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] -tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "backoff" @@ -92,35 +92,35 @@ files = [ [[package]] name = "bracex" -version = "2.5" +version = "2.5.post1" description = "Bash style brace expander." optional = false python-versions = ">=3.8" files = [ - {file = "bracex-2.5-py3-none-any.whl", hash = "sha256:d2fcf4b606a82ac325471affe1706dd9bbaa3536c91ef86a31f6b766f3dad1d0"}, - {file = "bracex-2.5.tar.gz", hash = "sha256:0725da5045e8d37ea9592ab3614d8b561e22c3c5fde3964699be672e072ab611"}, + {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, + {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, ] [[package]] name = "cachetools" -version = "5.4.0" +version = "5.5.0" description = "Extensible memoizing collections and decorators" optional = false python-versions = ">=3.7" files = [ - {file = "cachetools-5.4.0-py3-none-any.whl", hash = "sha256:3ae3b49a3d5e28a77a0be2b37dbcb89005058959cb2323858c2657c4a8cab474"}, - {file = "cachetools-5.4.0.tar.gz", hash = "sha256:b8adc2e7c07f105ced7bc56dbb6dfbe7c4a00acce20e2227b3f355be89bc6827"}, + {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, + {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, ] [[package]] name = "cattrs" -version = "23.2.3" +version = "24.1.2" description = "Composable complex class support for attrs and dataclasses." optional = false python-versions = ">=3.8" files = [ - {file = "cattrs-23.2.3-py3-none-any.whl", hash = "sha256:0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108"}, - {file = "cattrs-23.2.3.tar.gz", hash = "sha256:a934090d95abaa9e911dac357e3a8699e0b4b14f8529bcc7d2b1ad9d51672b9f"}, + {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, + {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, ] [package.dependencies] @@ -132,6 +132,7 @@ typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_ver bson = ["pymongo (>=4.4.0)"] cbor2 = ["cbor2 (>=5.4.6)"] msgpack = ["msgpack (>=1.0.5)"] +msgspec = ["msgspec (>=0.18.5)"] orjson = ["orjson (>=3.9.2)"] pyyaml = ["pyyaml (>=6.0)"] tomlkit = ["tomlkit (>=0.11.8)"] @@ -139,112 +140,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.7.4" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.3.2" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -260,20 +263,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -326,15 +329,18 @@ files = [ [[package]] name = "idna" -version = "3.7" +version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, ] +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -362,13 +368,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -411,82 +417,83 @@ format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-va [[package]] name = "markupsafe" -version = "2.1.5" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -525,19 +532,19 @@ pytzdata = ">=2020.1" [[package]] name = "platformdirs" -version = "4.2.2" +version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, - {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "pluggy" @@ -567,54 +574,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.17" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.17-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fa51175313cc30097660b10eec8ca55ed08bfa07acbfe02f7a42f6c242e9a4b"}, - {file = "pydantic-1.10.17-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7e8988bb16988890c985bd2093df9dd731bfb9d5e0860db054c23034fab8f7a"}, - {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:371dcf1831f87c9e217e2b6a0c66842879a14873114ebb9d0861ab22e3b5bb1e"}, - {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4866a1579c0c3ca2c40575398a24d805d4db6cb353ee74df75ddeee3c657f9a7"}, - {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:543da3c6914795b37785703ffc74ba4d660418620cc273490d42c53949eeeca6"}, - {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7623b59876f49e61c2e283551cc3647616d2fbdc0b4d36d3d638aae8547ea681"}, - {file = "pydantic-1.10.17-cp310-cp310-win_amd64.whl", hash = "sha256:409b2b36d7d7d19cd8310b97a4ce6b1755ef8bd45b9a2ec5ec2b124db0a0d8f3"}, - {file = "pydantic-1.10.17-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fa43f362b46741df8f201bf3e7dff3569fa92069bcc7b4a740dea3602e27ab7a"}, - {file = "pydantic-1.10.17-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2a72d2a5ff86a3075ed81ca031eac86923d44bc5d42e719d585a8eb547bf0c9b"}, - {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4ad32aed3bf5eea5ca5decc3d1bbc3d0ec5d4fbcd72a03cdad849458decbc63"}, - {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb4e741782e236ee7dc1fb11ad94dc56aabaf02d21df0e79e0c21fe07c95741"}, - {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d2f89a719411cb234105735a520b7c077158a81e0fe1cb05a79c01fc5eb59d3c"}, - {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db3b48d9283d80a314f7a682f7acae8422386de659fffaba454b77a083c3937d"}, - {file = "pydantic-1.10.17-cp311-cp311-win_amd64.whl", hash = "sha256:9c803a5113cfab7bbb912f75faa4fc1e4acff43e452c82560349fff64f852e1b"}, - {file = "pydantic-1.10.17-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:820ae12a390c9cbb26bb44913c87fa2ff431a029a785642c1ff11fed0a095fcb"}, - {file = "pydantic-1.10.17-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c1e51d1af306641b7d1574d6d3307eaa10a4991542ca324f0feb134fee259815"}, - {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e53fb834aae96e7b0dadd6e92c66e7dd9cdf08965340ed04c16813102a47fab"}, - {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e2495309b1266e81d259a570dd199916ff34f7f51f1b549a0d37a6d9b17b4dc"}, - {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:098ad8de840c92ea586bf8efd9e2e90c6339d33ab5c1cfbb85be66e4ecf8213f"}, - {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:525bbef620dac93c430d5d6bdbc91bdb5521698d434adf4434a7ef6ffd5c4b7f"}, - {file = "pydantic-1.10.17-cp312-cp312-win_amd64.whl", hash = "sha256:6654028d1144df451e1da69a670083c27117d493f16cf83da81e1e50edce72ad"}, - {file = "pydantic-1.10.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c87cedb4680d1614f1d59d13fea353faf3afd41ba5c906a266f3f2e8c245d655"}, - {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11289fa895bcbc8f18704efa1d8020bb9a86314da435348f59745473eb042e6b"}, - {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94833612d6fd18b57c359a127cbfd932d9150c1b72fea7c86ab58c2a77edd7c7"}, - {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d4ecb515fa7cb0e46e163ecd9d52f9147ba57bc3633dca0e586cdb7a232db9e3"}, - {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7017971ffa7fd7808146880aa41b266e06c1e6e12261768a28b8b41ba55c8076"}, - {file = "pydantic-1.10.17-cp37-cp37m-win_amd64.whl", hash = "sha256:e840e6b2026920fc3f250ea8ebfdedf6ea7a25b77bf04c6576178e681942ae0f"}, - {file = "pydantic-1.10.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bfbb18b616abc4df70591b8c1ff1b3eabd234ddcddb86b7cac82657ab9017e33"}, - {file = "pydantic-1.10.17-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebb249096d873593e014535ab07145498957091aa6ae92759a32d40cb9998e2e"}, - {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8c209af63ccd7b22fba94b9024e8b7fd07feffee0001efae50dd99316b27768"}, - {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b40c9e13a0b61583e5599e7950490c700297b4a375b55b2b592774332798b7"}, - {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c31d281c7485223caf6474fc2b7cf21456289dbaa31401844069b77160cab9c7"}, - {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae5184e99a060a5c80010a2d53c99aee76a3b0ad683d493e5f0620b5d86eeb75"}, - {file = "pydantic-1.10.17-cp38-cp38-win_amd64.whl", hash = "sha256:ad1e33dc6b9787a6f0f3fd132859aa75626528b49cc1f9e429cdacb2608ad5f0"}, - {file = "pydantic-1.10.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7e17c0ee7192e54a10943f245dc79e36d9fe282418ea05b886e1c666063a7b54"}, - {file = "pydantic-1.10.17-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cafb9c938f61d1b182dfc7d44a7021326547b7b9cf695db5b68ec7b590214773"}, - {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95ef534e3c22e5abbdbdd6f66b6ea9dac3ca3e34c5c632894f8625d13d084cbe"}, - {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d96b8799ae3d782df7ec9615cb59fc32c32e1ed6afa1b231b0595f6516e8ab"}, - {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ab2f976336808fd5d539fdc26eb51f9aafc1f4b638e212ef6b6f05e753c8011d"}, - {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8ad363330557beac73159acfbeed220d5f1bfcd6b930302a987a375e02f74fd"}, - {file = "pydantic-1.10.17-cp39-cp39-win_amd64.whl", hash = "sha256:48db882e48575ce4b39659558b2f9f37c25b8d348e37a2b4e32971dd5a7d6227"}, - {file = "pydantic-1.10.17-py3-none-any.whl", hash = "sha256:e41b5b973e5c64f674b3b4720286ded184dcc26a691dd55f34391c62c6934688"}, - {file = "pydantic-1.10.17.tar.gz", hash = "sha256:f434160fb14b353caf634149baaf847206406471ba70e64657c1e8330277a991"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -748,62 +755,64 @@ files = [ [[package]] name = "pyyaml" -version = "6.0.1" +version = "6.0.2" description = "YAML parser and emitter for Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] [[package]] @@ -876,29 +885,33 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "72.1.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-72.1.0-py3-none-any.whl", hash = "sha256:5a03e1860cf56bb6ef48ce186b0e557fdba433237481a9a625176c2831be15d1"}, - {file = "setuptools-72.1.0.tar.gz", hash = "sha256:8d243eff56d095e5817f796ede6ae32941278f542e0f941867cc05ae52b162ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -939,13 +952,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.2" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, - {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -970,81 +983,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-twilio/pyproject.toml b/airbyte-integrations/connectors/source-twilio/pyproject.toml index 751d4ae3dcdb..48598749ee71 100644 --- a/airbyte-integrations/connectors/source-twilio/pyproject.toml +++ b/airbyte-integrations/connectors/source-twilio/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.11.12" +version = "0.11.14" name = "source-twilio" description = "Source implementation for Twilio." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-twilio/source_twilio/source.py b/airbyte-integrations/connectors/source-twilio/source_twilio/source.py index 26c2269b16af..b2bccf6832de 100644 --- a/airbyte-integrations/connectors/source-twilio/source_twilio/source.py +++ b/airbyte-integrations/connectors/source-twilio/source_twilio/source.py @@ -7,6 +7,7 @@ from typing import Any, List, Mapping, Tuple import pendulum + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream @@ -48,6 +49,7 @@ VerifyServices, ) + RETENTION_WINDOW_LIMIT = 400 diff --git a/airbyte-integrations/connectors/source-twilio/source_twilio/streams.py b/airbyte-integrations/connectors/source-twilio/source_twilio/streams.py index 2e82d6639452..415fb3358917 100644 --- a/airbyte-integrations/connectors/source-twilio/source_twilio/streams.py +++ b/airbyte-integrations/connectors/source-twilio/source_twilio/streams.py @@ -10,13 +10,15 @@ import pendulum import requests +from pendulum.datetime import DateTime +from requests.auth import AuthBase + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources.streams import IncrementalMixin from airbyte_cdk.sources.streams.availability_strategy import AvailabilityStrategy from airbyte_cdk.sources.streams.http import HttpStream from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer -from pendulum.datetime import DateTime -from requests.auth import AuthBase + TWILIO_CHAT_BASE = "https://chat.twilio.com/v2/" TWILIO_CONVERSATION_BASE = "https://conversations.twilio.com/v1/" diff --git a/airbyte-integrations/connectors/source-twilio/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-twilio/unit_tests/test_streams.py index 309355222b86..4c365be55842 100644 --- a/airbyte-integrations/connectors/source-twilio/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-twilio/unit_tests/test_streams.py @@ -8,7 +8,6 @@ import pendulum import pytest import requests -from airbyte_cdk.sources.streams.http import HttpStream from freezegun import freeze_time from source_twilio.auth import HttpBasicAuthenticator from source_twilio.source import SourceTwilio @@ -27,6 +26,9 @@ UsageTriggers, ) +from airbyte_cdk.sources.streams.http import HttpStream + + TEST_CONFIG = { "account_sid": "airbyte.io", "auth_token": "secret", @@ -43,7 +45,6 @@ class TestTwilioStream: - CONFIG = {"authenticator": TEST_CONFIG.get("authenticator")} @pytest.mark.parametrize( @@ -60,14 +61,14 @@ def test_data_field(self, stream_cls, expected): @pytest.mark.parametrize( "stream_cls, expected", [ - (Accounts, ['name']), + (Accounts, ["name"]), ], ) def test_changeable_fields(self, stream_cls, expected): - with patch.object(Accounts, "changeable_fields", ['name']): - stream = stream_cls(**self.CONFIG) - result = stream.changeable_fields - assert result == expected + with patch.object(Accounts, "changeable_fields", ["name"]): + stream = stream_cls(**self.CONFIG) + result = stream.changeable_fields + assert result == expected @pytest.mark.parametrize( "stream_cls, expected", @@ -108,12 +109,12 @@ def test_next_page_token(self, requests_mock, stream_cls, test_response, expecte ) def test_parse_response(self, requests_mock, stream_cls, test_response, expected): with patch.object(TwilioStream, "changeable_fields", ["name"]): - stream = stream_cls(**self.CONFIG) - url = f"{stream.url_base}{stream.path()}" - requests_mock.get(url, json=test_response) - response = requests.get(url) - result = list(stream.parse_response(response)) - assert result[0]['id'] == expected[0]['id'] + stream = stream_cls(**self.CONFIG) + url = f"{stream.url_base}{stream.path()}" + requests_mock.get(url, json=test_response) + response = requests.get(url) + result = list(stream.parse_response(response)) + assert result[0]["id"] == expected[0]["id"] @pytest.mark.parametrize( "stream_cls, expected", @@ -151,14 +152,13 @@ def test_request_params(self, stream_cls, next_page_token, expected): ("Fri, 11 Dec 2020 04:28:40 +0000", {"format": "date-time"}, "2020-12-11T04:28:40Z"), ("2020-12-11T04:28:40Z", {"format": "date-time"}, "2020-12-11T04:28:40Z"), ("some_string", {}, "some_string"), - ] + ], ) def test_transform_function(self, original_value, field_schema, expected_value): assert Accounts.custom_transform_function(original_value, field_schema) == expected_value class TestIncrementalTwilioStream: - CONFIG = TEST_CONFIG CONFIG.pop("account_sid") CONFIG.pop("auth_token") @@ -256,7 +256,6 @@ def test_generate_dt_ranges(self, stream_cls, state, expected_dt_ranges): class TestTwilioNestedStream: - CONFIG = {"authenticator": TEST_CONFIG.get("authenticator")} @pytest.mark.parametrize( @@ -299,7 +298,6 @@ def test_stream_slices(self, stream_cls, parent_stream, record, expected): class TestUsageNestedStream: - CONFIG = {"authenticator": TEST_CONFIG.get("authenticator")} @pytest.mark.parametrize( diff --git a/airbyte-integrations/connectors/source-twitter/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-twitter/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-twitter/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-twitter/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-twitter/metadata.yaml b/airbyte-integrations/connectors/source-twitter/metadata.yaml index 9577fc4b1b99..7133c02730ac 100644 --- a/airbyte-integrations/connectors/source-twitter/metadata.yaml +++ b/airbyte-integrations/connectors/source-twitter/metadata.yaml @@ -8,7 +8,7 @@ data: connectorSubtype: api connectorType: source definitionId: d7fd4f40-5e5a-4b8b-918f-a73077f8c131 - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.3 dockerRepository: airbyte/source-twitter documentationUrl: https://docs.airbyte.com/integrations/sources/twitter githubIssueLabel: source-twitter @@ -42,5 +42,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-tyntec-sms/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-tyntec-sms/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-tyntec-sms/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-tyntec-sms/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-tyntec-sms/metadata.yaml b/airbyte-integrations/connectors/source-tyntec-sms/metadata.yaml index a20bcc97a11b..4d8e003668e2 100644 --- a/airbyte-integrations/connectors/source-tyntec-sms/metadata.yaml +++ b/airbyte-integrations/connectors/source-tyntec-sms/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 3c0c3cd1-b3e0-464a-9090-d3ceb5f92346 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.8 dockerRepository: airbyte/source-tyntec-sms githubIssueLabel: source-tyntec-sms icon: tyntec.svg @@ -27,5 +27,5 @@ data: ql: 100 supportLevel: community connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-typeform/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-typeform/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-typeform/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-typeform/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-typeform/main.py b/airbyte-integrations/connectors/source-typeform/main.py index 126dc556ff7d..a28ee8adc4c0 100644 --- a/airbyte-integrations/connectors/source-typeform/main.py +++ b/airbyte-integrations/connectors/source-typeform/main.py @@ -4,5 +4,6 @@ from source_typeform.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-typeform/metadata.yaml b/airbyte-integrations/connectors/source-typeform/metadata.yaml index 33a7a531486c..8fe8f1dfef20 100644 --- a/airbyte-integrations/connectors/source-typeform/metadata.yaml +++ b/airbyte-integrations/connectors/source-typeform/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - api.typeform.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: e7eff203-90bf-43e5-a240-19ea3056c474 - dockerImageTag: 1.3.18 + dockerImageTag: 1.3.24 dockerRepository: airbyte/source-typeform documentationUrl: https://docs.airbyte.com/integrations/sources/typeform githubIssueLabel: source-typeform diff --git a/airbyte-integrations/connectors/source-typeform/poetry.lock b/airbyte-integrations/connectors/source-typeform/poetry.lock index f2423c808fe3..0da29cedec27 100644 --- a/airbyte-integrations/connectors/source-typeform/poetry.lock +++ b/airbyte-integrations/connectors/source-typeform/poetry.lock @@ -41,13 +41,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models" -version = "0.13.0" +version = "0.14.1" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.13.0-py3-none-any.whl", hash = "sha256:fa8b7e1a85f9ae171c50b30d23b317da1740d051994fd3ed648f9dfba00250e2"}, - {file = "airbyte_protocol_models-0.13.0.tar.gz", hash = "sha256:09d8900ba8674a9315fa1799d17026f6b38d2187c08160449540ee93331ed2e7"}, + {file = "airbyte_protocol_models-0.14.1-py3-none-any.whl", hash = "sha256:851a9a7864191a05f7f0942e05eb7b0e36e3395be8db074f75a43b9098186089"}, + {file = "airbyte_protocol_models-0.14.1.tar.gz", hash = "sha256:bcb31493081fc7a2cb923b975eb6a46bc471fe1d82ac645ca5e551bb63731ffa"}, ] [package.dependencies] @@ -55,24 +55,24 @@ pydantic = ">=1.9.2,<2.0.0" [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -87,19 +87,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -165,13 +165,13 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] @@ -255,116 +255,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -434,20 +421,20 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -497,13 +484,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, ] [package.dependencies] @@ -518,13 +505,13 @@ trio = ["trio (>=0.22.0,<1.0)"] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, ] [package.dependencies] @@ -532,7 +519,6 @@ anyio = "*" certifi = "*" httpcore = "==1.*" idna = "*" -sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] @@ -582,13 +568,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -678,22 +664,25 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.147" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.147-py3-none-any.whl", hash = "sha256:7166fc23b965ccf839d64945a78e9f1157757add228b086141eb03a60d699a15"}, + {file = "langsmith-0.1.147.tar.gz", hash = "sha256:2e933220318a4e73034657103b3b1a3a6109cc5db3566a7e8e03be8d6d7def7a"}, ] [package.dependencies] httpx = ">=0.23.0,<1" -orjson = ">=3.9.14,<4.0.0" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} pydantic = {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""} requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -766,69 +755,86 @@ files = [ [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, + {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, + {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, + {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, + {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, + {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, + {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, + {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, + {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, + {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, + {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, + {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, + {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, + {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, + {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, + {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, + {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, + {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, + {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, + {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, + {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, + {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, + {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, + {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, + {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, + {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, + {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, + {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, + {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, + {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, + {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] @@ -931,54 +937,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -990,13 +996,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1273,33 +1279,33 @@ requests = ">=2.0.1,<3.0.0" [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -1366,13 +1372,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1397,81 +1403,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-typeform/pyproject.toml b/airbyte-integrations/connectors/source-typeform/pyproject.toml index 27d7e0adc73d..9bf4717cd88c 100644 --- a/airbyte-integrations/connectors/source-typeform/pyproject.toml +++ b/airbyte-integrations/connectors/source-typeform/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "1.3.18" +version = "1.3.24" name = "source-typeform" description = "Source implementation for Typeform." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-typeform/source_typeform/run.py b/airbyte-integrations/connectors/source-typeform/source_typeform/run.py index 2ebf804b4940..c5698a824168 100644 --- a/airbyte-integrations/connectors/source-typeform/source_typeform/run.py +++ b/airbyte-integrations/connectors/source-typeform/source_typeform/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_typeform import SourceTypeform +from airbyte_cdk.entrypoint import launch + def run(): source = SourceTypeform() diff --git a/airbyte-integrations/connectors/source-typeform/source_typeform/source.py b/airbyte-integrations/connectors/source-typeform/source_typeform/source.py index 58ec8391d7d7..8bcf7525d561 100644 --- a/airbyte-integrations/connectors/source-typeform/source_typeform/source.py +++ b/airbyte-integrations/connectors/source-typeform/source_typeform/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-typeform/unit_tests/test_authenticator.py b/airbyte-integrations/connectors/source-typeform/unit_tests/test_authenticator.py index a841b1d266cf..ee22158b1c58 100644 --- a/airbyte-integrations/connectors/source-typeform/unit_tests/test_authenticator.py +++ b/airbyte-integrations/connectors/source-typeform/unit_tests/test_authenticator.py @@ -1,13 +1,16 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. +from source_typeform.components import TypeformAuthenticator + from airbyte_cdk.sources.declarative.auth.oauth import DeclarativeSingleUseRefreshTokenOauth2Authenticator from airbyte_cdk.sources.declarative.auth.token import BearerAuthenticator -from source_typeform.components import TypeformAuthenticator def test_typeform_authenticator(): config = {"credentials": {"auth_type": "access_token", "access_token": "access_token"}} - oauth_config = {"credentials": {"auth_type": "oauth2.0", "access_token": None, "client_id": "client_id", "client_secret": "client_secret"}} + oauth_config = { + "credentials": {"auth_type": "oauth2.0", "access_token": None, "client_id": "client_id", "client_secret": "client_secret"} + } class TokenProvider: def get_token(self) -> str: @@ -16,13 +19,13 @@ def get_token(self) -> str: auth = TypeformAuthenticator( token_auth=BearerAuthenticator(config=config, token_provider=TokenProvider(), parameters={}), config=config, - oauth2=DeclarativeSingleUseRefreshTokenOauth2Authenticator(connector_config=oauth_config, token_refresh_endpoint="/new_token") + oauth2=DeclarativeSingleUseRefreshTokenOauth2Authenticator(connector_config=oauth_config, token_refresh_endpoint="/new_token"), ) assert isinstance(auth, BearerAuthenticator) oauth = TypeformAuthenticator( token_auth=BearerAuthenticator(config=config, token_provider=TokenProvider(), parameters={}), config=oauth_config, - oauth2=DeclarativeSingleUseRefreshTokenOauth2Authenticator(connector_config=oauth_config, token_refresh_endpoint="/new_token") + oauth2=DeclarativeSingleUseRefreshTokenOauth2Authenticator(connector_config=oauth_config, token_refresh_endpoint="/new_token"), ) assert isinstance(oauth, DeclarativeSingleUseRefreshTokenOauth2Authenticator) diff --git a/airbyte-integrations/connectors/source-typeform/unit_tests/test_form_id_partition_router.py b/airbyte-integrations/connectors/source-typeform/unit_tests/test_form_id_partition_router.py index c5c3f1508e76..f8f11245c5c3 100644 --- a/airbyte-integrations/connectors/source-typeform/unit_tests/test_form_id_partition_router.py +++ b/airbyte-integrations/connectors/source-typeform/unit_tests/test_form_id_partition_router.py @@ -6,9 +6,11 @@ from unittest.mock import Mock import pytest -from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig from source_typeform.components import FormIdPartitionRouter, TypeformAuthenticator +from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig + + # test cases as a list of tuples (form_ids, parent_stream_configs, expected_slices) test_cases = [ ( diff --git a/airbyte-integrations/connectors/source-ubidots/README.md b/airbyte-integrations/connectors/source-ubidots/README.md new file mode 100644 index 000000000000..38cb0e07617e --- /dev/null +++ b/airbyte-integrations/connectors/source-ubidots/README.md @@ -0,0 +1,33 @@ +# Ubidots +This directory contains the manifest-only connector for `source-ubidots`. + +The Ubidots Connector facilitates easy integration with the Ubidots IoT platform, enabling users to fetch, sync, and analyze real-time sensor data. This connector helps streamline IoT workflows by connecting Ubidots with other tools for seamless data processing and insights. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-ubidots:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-ubidots build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-ubidots test +``` + diff --git a/airbyte-integrations/connectors/source-ubidots/acceptance-test-config.yml b/airbyte-integrations/connectors/source-ubidots/acceptance-test-config.yml new file mode 100644 index 000000000000..f78e0be71fe8 --- /dev/null +++ b/airbyte-integrations/connectors/source-ubidots/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-ubidots:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-ubidots/icon.svg b/airbyte-integrations/connectors/source-ubidots/icon.svg new file mode 100644 index 000000000000..c07174f92fe2 --- /dev/null +++ b/airbyte-integrations/connectors/source-ubidots/icon.svg @@ -0,0 +1,149 @@ + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-ubidots/manifest.yaml b/airbyte-integrations/connectors/source-ubidots/manifest.yaml new file mode 100644 index 000000000000..02b4e0c87893 --- /dev/null +++ b/airbyte-integrations/connectors/source-ubidots/manifest.yaml @@ -0,0 +1,1082 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + The Ubidots Connector facilitates easy integration with the Ubidots IoT + platform, enabling users to fetch, sync, and analyze real-time sensor data. + This connector helps streamline IoT workflows by connecting Ubidots with other + tools for seamless data processing and insights. + +check: + type: CheckStream + stream_names: + - devices + +definitions: + streams: + devices: + type: DeclarativeStream + name: devices + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2.0/devices/ + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: per_page + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next | regex_search(\"page=(\\d+)\") }}" + stop_condition: "{{ response.next is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/devices" + events: + type: DeclarativeStream + name: events + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2.0/events/ + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: per_page + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next | regex_search(\"page=(\\d+)\") }}" + stop_condition: "{{ response.next is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/events" + dashboards: + type: DeclarativeStream + name: dashboards + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2.0/dashboards/ + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: per_page + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.next | regex_search(\"page=(\\d+)\") }}" + stop_condition: "{{ response.next is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/dashboards" + variables: + type: DeclarativeStream + name: variables + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2.0/variables/ + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.next | regex_search(\"page=(\\d+)\") }}" + stop_condition: "{{ response.next is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/variables" + device_groups: + type: DeclarativeStream + name: device_groups + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2.0/device_groups/ + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.next | regex_search(\"page=(\\d+)\") }}" + stop_condition: "{{ response.next is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/device_groups" + device_types: + type: DeclarativeStream + name: device_types + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v2.0/device_types/ + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - results + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.next | regex_search(\"page=(\\d+)\") }}" + stop_condition: "{{ response.next is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/device_types" + base_requester: + type: HttpRequester + url_base: https://industrial.api.ubidots.com + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_token\"] }}" + inject_into: + type: RequestOption + field_name: X-Auth-Token + inject_into: header + +streams: + - $ref: "#/definitions/streams/devices" + - $ref: "#/definitions/streams/events" + - $ref: "#/definitions/streams/dashboards" + - $ref: "#/definitions/streams/variables" + - $ref: "#/definitions/streams/device_groups" + - $ref: "#/definitions/streams/device_types" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_token + properties: + api_token: + type: string + description: >- + API token to use for authentication. Obtain it from your Ubidots + account. + name: api_token + order: 0 + title: API Token + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + devices: true + events: true + dashboards: true + variables: true + device_groups: true + device_types: true + testedStreams: + devices: + streamHash: 06eeff18f7efcbef9a6e9bed6be6d1b4b53effbf + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + events: + streamHash: 6ea9b8b12ca41339f2b08b16e392131bf751dc9f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + dashboards: + streamHash: bebeb0bbd2ee18ce571f7d72b25fe51beae34e6f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + variables: + streamHash: 71b9f4fe4b5d3769183168758938c4c8d6a7a28d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + device_groups: + streamHash: 01a7589941aef02911e882e36fbd7c6efa79d8ee + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + device_types: + streamHash: 569cd7a935ee204a3375d2552b89a471d4412236 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://docs.ubidots.com/reference/authentication + +schemas: + devices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + id: + type: string + isActive: + type: + - boolean + - "null" + label: + type: + - string + - "null" + lastActivity: + type: + - number + - "null" + name: + type: + - string + - "null" + properties: + type: + - object + - "null" + properties: + _color: + type: + - string + - "null" + _icon: + type: + - string + - "null" + _location_fixed: + type: + - object + - "null" + properties: + lat: + type: + - number + - "null" + lng: + type: + - number + - "null" + _location_type: + type: + - string + - "null" + tags: + type: + - array + - "null" + url: + type: + - string + - "null" + variables: + type: + - string + - "null" + variablesCount: + type: + - number + - "null" + required: + - id + events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + actions: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + back_to_normal: + type: + - boolean + - "null" + data: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + context: + type: + - object + - "null" + value: + type: + - string + - "null" + variables: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + idGroupAction: + type: + - string + - "null" + name: + type: + - string + - "null" + activeDates: + type: + - object + - "null" + properties: + dates: + type: + - array + - "null" + items: + type: + - array + - "null" + items: + type: + - array + - "null" + items: + type: + - string + - "null" + timezone: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + id: + type: string + isActive: + type: + - boolean + - "null" + isGlobalEvent: + type: + - boolean + - "null" + label: + type: + - string + - "null" + name: + type: + - string + - "null" + tags: + type: + - array + - "null" + triggers: + type: + - array + - "null" + items: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + condition: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + delay: + type: + - number + - "null" + operator: + type: + - string + - "null" + value: + type: + - number + - "null" + entity: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + operator: + type: + - string + - "null" + value: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + url: + type: + - string + - "null" + required: + - id + dashboards: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + context: + type: + - object + - "null" + properties: + __customStyle: + type: + - object + - "null" + properties: + contextBar: + type: + - object + - "null" + properties: + backgroundColor: + type: + - string + - "null" + color: + type: + - string + - "null" + fontSize: + type: + - number + - "null" + title: + type: + - object + - "null" + properties: + fontSize: + type: + - number + - "null" + dashboard: + type: + - object + - "null" + properties: + backgroundColor: + type: + - string + - "null" + color: + type: + - string + - "null" + widget: + type: + - object + - "null" + properties: + backgroundColor: + type: + - string + - "null" + borderColor: + type: + - string + - "null" + borderRadius: + type: + - number + - "null" + borderStyle: + type: + - string + - "null" + borderWidth: + type: + - number + - "null" + boxShadow: + type: + - string + - "null" + color: + type: + - string + - "null" + fontSize: + type: + - number + - "null" + header: + type: + - object + - "null" + properties: + backgroundColor: + type: + - string + - "null" + borderColor: + type: + - string + - "null" + borderStyle: + type: + - string + - "null" + borderWidth: + type: + - number + - "null" + color: + type: + - string + - "null" + alignment: + type: + - string + - "null" + dashboardType: + type: + - string + - "null" + defaultDevice: + type: + - string + - "null" + deviceFilterType: + type: + - string + - "null" + displayName: + type: + - string + - "null" + filterSettings: + type: + - object + - "null" + floatingWidgets: + type: + - boolean + - "null" + hasBackground: + type: + - boolean + - "null" + hideDatePicker: + type: + - boolean + - "null" + hideHeaderFooterWidgets: + type: + - boolean + - "null" + imageSettings: + type: + - object + - "null" + properties: + isUrlValue: + type: + - boolean + - "null" + isDynamic: + type: + - boolean + - "null" + prospector_is_filters_last_value_alt: + type: + - boolean + - "null" + size: + type: + - object + - "null" + properties: + width: + type: + - string + - "null" + temporalxaxis: + type: + - string + - "null" + timestampFormat: + type: + - string + - "null" + widgetHorizontalSpacing: + type: + - string + - "null" + widgetVerticalSpacing: + type: + - string + - "null" + widgetsOpacity: + type: + - number + - "null" + createdAt: + type: + - string + - "null" + id: + type: string + isActive: + type: + - boolean + - "null" + isEditable: + type: + - boolean + - "null" + label: + type: + - string + - "null" + name: + type: + - string + - "null" + order: + type: + - number + - "null" + tags: + type: + - array + - "null" + timeframe: + type: + - object + - "null" + properties: + endDate: + type: + - string + - "null" + startDate: + type: + - string + - "null" + url: + type: + - string + - "null" + widgets: + type: + - string + - "null" + widgetsNumber: + type: + - number + - "null" + required: + - id + variables: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + device: + type: + - object + - "null" + properties: + createdAt: + type: + - string + - "null" + id: + type: + - string + - "null" + label: + type: + - string + - "null" + name: + type: + - string + - "null" + url: + type: + - string + - "null" + id: + type: string + label: + type: + - string + - "null" + lastActivity: + type: + - number + - "null" + lastValue: + type: + - object + - "null" + properties: + context: + type: + - object + - "null" + created_at: + type: + - number + - "null" + timestamp: + type: + - number + - "null" + value: + type: + - number + - "null" + name: + type: + - string + - "null" + properties: + type: + - object + - "null" + properties: + _previous_variable_label: + type: + - string + - "null" + syntheticExpression: + type: + - string + - "null" + tags: + type: + - array + - "null" + url: + type: + - string + - "null" + valuesUrl: + type: + - string + - "null" + required: + - id + device_groups: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdAt: + type: + - string + - "null" + devices: + type: + - string + - "null" + devicesCount: + type: + - number + - "null" + id: + type: string + label: + type: + - string + - "null" + name: + type: + - string + - "null" + tags: + type: + - array + - "null" + url: + type: + - string + - "null" + required: + - id + device_types: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + createdAt: + type: + - string + - "null" + deviceColor: + type: + - string + - "null" + deviceIcon: + type: + - string + - "null" + id: + type: string + label: + type: + - string + - "null" + name: + type: + - string + - "null" + properties: + type: + - array + - "null" + tags: + type: + - array + - "null" + tasks: + type: + - array + - "null" + url: + type: + - string + - "null" + variableColor: + type: + - string + - "null" + variables: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - number + - "null" + description: + type: + - string + - "null" + label: + type: + - string + - "null" + name: + type: + - string + - "null" + properties: + type: + - object + - "null" + properties: + _color: + type: + - string + - "null" + _icon: + type: + - string + - "null" + hidden: + type: + - boolean + - "null" + isLocationVariable: + type: + - boolean + - "null" + unit: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-ubidots/metadata.yaml b/airbyte-integrations/connectors/source-ubidots/metadata.yaml new file mode 100644 index 000000000000..1fa28ec2b87b --- /dev/null +++ b/airbyte-integrations/connectors/source-ubidots/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "industrial.api.ubidots.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-ubidots + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 8614fab8-aa3e-4dbe-8728-6d6c8a1d3514 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-ubidots + githubIssueLabel: source-ubidots + icon: icon.svg + license: MIT + name: Ubidots + releaseDate: 2024-10-24 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/ubidots + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-unleash/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-unleash/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-unleash/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-unleash/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-unleash/metadata.yaml b/airbyte-integrations/connectors/source-unleash/metadata.yaml index dc71a123754f..ad4298bda9cd 100644 --- a/airbyte-integrations/connectors/source-unleash/metadata.yaml +++ b/airbyte-integrations/connectors/source-unleash/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: f77914a1-442b-4195-9355-8810a1f4ed3f - dockerImageTag: 0.2.0 + dockerImageTag: 0.2.5 dockerRepository: airbyte/source-unleash githubIssueLabel: source-unleash icon: unleash.svg @@ -35,5 +35,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.10.2@sha256:81db4f78a92d199f33c38c17f5b63fc87c56739f14dc10276ddec86c7b707b7a + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-uppromote/metadata.yaml b/airbyte-integrations/connectors/source-uppromote/metadata.yaml index 8eb122d54e89..cff104d24934 100644 --- a/airbyte-integrations/connectors/source-uppromote/metadata.yaml +++ b/airbyte-integrations/connectors/source-uppromote/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-uppromote connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: d75a7792-e5db-4645-93c3-b4a16ad62ab0 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-uppromote githubIssueLabel: source-uppromote icon: icon.svg diff --git a/airbyte-integrations/connectors/source-us-census/components.py b/airbyte-integrations/connectors/source-us-census/components.py index 431d0794f7ad..73087fa6c63a 100644 --- a/airbyte-integrations/connectors/source-us-census/components.py +++ b/airbyte-integrations/connectors/source-us-census/components.py @@ -7,6 +7,7 @@ from typing import Any, List, Mapping, Optional, Union import requests + from airbyte_cdk.models import FailureType from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor from airbyte_cdk.sources.declarative.requesters.error_handlers import DefaultErrorHandler @@ -116,7 +117,6 @@ class USCensusErrorHandler(DefaultErrorHandler): """ def interpret_response(self, response_or_exception: Optional[Union[requests.Response, Exception]]) -> ErrorResolution: - if self.response_filters: for response_filter in self.response_filters: matched_error_resolution = response_filter.matches(response_or_exception=response_or_exception) diff --git a/airbyte-integrations/connectors/source-us-census/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-us-census/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-us-census/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-us-census/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-us-census/metadata.yaml b/airbyte-integrations/connectors/source-us-census/metadata.yaml index acbc2c270075..8d7c69536dc7 100644 --- a/airbyte-integrations/connectors/source-us-census/metadata.yaml +++ b/airbyte-integrations/connectors/source-us-census/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: c4cfaeda-c757-489a-8aba-859fb08b6970 - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.5 dockerRepository: airbyte/source-us-census githubIssueLabel: source-us-census icon: uscensus.svg @@ -47,5 +47,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-uservoice/metadata.yaml b/airbyte-integrations/connectors/source-uservoice/metadata.yaml index 91ef46417888..d735d7ce4af3 100644 --- a/airbyte-integrations/connectors/source-uservoice/metadata.yaml +++ b/airbyte-integrations/connectors/source-uservoice/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-uservoice connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 6ad41bae-c3a3-4a8e-abfd-c75b8604c083 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-uservoice githubIssueLabel: source-uservoice icon: icon.svg diff --git a/airbyte-integrations/connectors/source-vantage/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-vantage/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-vantage/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-vantage/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-vantage/metadata.yaml b/airbyte-integrations/connectors/source-vantage/metadata.yaml index 1bf3dcd01efe..b57c5a4c062b 100644 --- a/airbyte-integrations/connectors/source-vantage/metadata.yaml +++ b/airbyte-integrations/connectors/source-vantage/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 28ce1fbd-1e15-453f-aa9f-da6c4d928e92 - dockerImageTag: 0.2.2 + dockerImageTag: 0.2.5 dockerRepository: airbyte/source-vantage githubIssueLabel: source-vantage icon: vantage.svg @@ -39,5 +39,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-veeqo/metadata.yaml b/airbyte-integrations/connectors/source-veeqo/metadata.yaml index 0ab7f6eebef5..0442556d7baa 100644 --- a/airbyte-integrations/connectors/source-veeqo/metadata.yaml +++ b/airbyte-integrations/connectors/source-veeqo/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-veeqo connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: ae647c65-da81-4ae5-958a-86490ce53a5e - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.8 dockerRepository: airbyte/source-veeqo githubIssueLabel: source-veeqo icon: icon.svg diff --git a/airbyte-integrations/connectors/source-vercel/README.md b/airbyte-integrations/connectors/source-vercel/README.md new file mode 100644 index 000000000000..5c83d56b87d9 --- /dev/null +++ b/airbyte-integrations/connectors/source-vercel/README.md @@ -0,0 +1,33 @@ +# Vercel +This directory contains the manifest-only connector for `source-vercel`. + + Vercel connector enables seamless data sync between Vercel projects and various destinations. This integration simplifies real-time deployments, analytics, and automated workflows by bridging data from Vercel to your destination. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-vercel:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-vercel build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-vercel test +``` + diff --git a/airbyte-integrations/connectors/source-vercel/acceptance-test-config.yml b/airbyte-integrations/connectors/source-vercel/acceptance-test-config.yml new file mode 100644 index 000000000000..071483f3aacc --- /dev/null +++ b/airbyte-integrations/connectors/source-vercel/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-vercel:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-vercel/icon.svg b/airbyte-integrations/connectors/source-vercel/icon.svg new file mode 100644 index 000000000000..89312dceed80 --- /dev/null +++ b/airbyte-integrations/connectors/source-vercel/icon.svg @@ -0,0 +1,2 @@ + + diff --git a/airbyte-integrations/connectors/source-vercel/manifest.yaml b/airbyte-integrations/connectors/source-vercel/manifest.yaml new file mode 100644 index 000000000000..c7d6b17b6d9e --- /dev/null +++ b/airbyte-integrations/connectors/source-vercel/manifest.yaml @@ -0,0 +1,1884 @@ +version: 5.14.0 + +type: DeclarativeSource + +description: " Vercel connector enables seamless data sync between Vercel projects and various destinations. This integration simplifies real-time deployments, analytics, and automated workflows by bridging data from Vercel to your destination." + +check: + type: CheckStream + stream_names: + - projects + +definitions: + streams: + projects: + type: DeclarativeStream + name: projects + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v9/projects + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - projects + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: until + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('pagination', {}).get('next') }}" + stop_condition: "{{ response.get('pagination', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/projects" + teams: + type: DeclarativeStream + name: teams + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/teams + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - teams + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: until + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('pagination', {}).get('next') }}" + stop_condition: "{{ response.get('pagination', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/teams" + user: + type: DeclarativeStream + name: user + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/user + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - user + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: until + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('pagination', {}).get('next') }}" + stop_condition: "{{ response.get('pagination', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/user" + deployments: + type: DeclarativeStream + name: deployments + primary_key: + - uid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v6/deployments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - deployments + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: until + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('pagination', {}).get('next') }}" + stop_condition: "{{ response.get('pagination', {}).get('next') is none }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: createdAt + cursor_datetime_formats: + - "%ms" + datetime_format: "%ms" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + inject_into: request_parameter + field_name: since + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/deployments" + environments: + type: DeclarativeStream + name: environments + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v9/projects/{{ stream_partition.project }}/env + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - envs + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: until + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('pagination', {}).get('next') }}" + stop_condition: "{{ response.get('pagination', {}).get('next') is none }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: project + stream: + $ref: "#/definitions/streams/projects" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/environments" + auth_tokens: + type: DeclarativeStream + name: auth_tokens + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v5/user/tokens + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - tokens + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: until + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('pagination', {}).get('next') }}" + stop_condition: "{{ response.get('pagination', {}).get('next') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/auth_tokens" + aliases: + type: DeclarativeStream + name: aliases + primary_key: + - uid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v4/aliases + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - aliases + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: until + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('pagination', {}).get('next') }}" + stop_condition: "{{ response.get('pagination', {}).get('next') is none }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updatedAt + cursor_datetime_formats: + - "%ms" + datetime_format: "%ms" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: since + inject_into: request_parameter + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/aliases" + deployment_events: + type: DeclarativeStream + name: deployment_events + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v3/deployments/{{ stream_partition.deployment }}/events + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: until + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('pagination', {}).get('next') }}" + stop_condition: "{{ response.get('pagination', {}).get('next') is none }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: uid + partition_field: deployment + stream: + $ref: "#/definitions/streams/deployments" + incremental_dependency: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/deployment_events" + teams_member: + type: DeclarativeStream + name: teams_member + primary_key: + - uid + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /v2/teams/{{stream_slice.team_id}}/members + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - members + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: until + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get('pagination', {}).get('next') }}" + stop_condition: "{{ response.get('pagination', {}).get('next') is none }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: team_id + stream: + $ref: "#/definitions/streams/teams" + transformations: + - type: AddFields + fields: + - path: + - team_id + value: "{{ stream_slice.team_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/teams_member" + base_requester: + type: HttpRequester + url_base: https://api.vercel.com + authenticator: + type: BearerAuthenticator + api_token: "{{ config[\"access_token\"] }}" + +streams: + - $ref: "#/definitions/streams/projects" + - $ref: "#/definitions/streams/teams" + - $ref: "#/definitions/streams/user" + - $ref: "#/definitions/streams/deployments" + - $ref: "#/definitions/streams/environments" + - $ref: "#/definitions/streams/auth_tokens" + - $ref: "#/definitions/streams/aliases" + - $ref: "#/definitions/streams/deployment_events" + - $ref: "#/definitions/streams/teams_member" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - access_token + - start_date + properties: + access_token: + type: string + description: >- + Access token to authenticate with the Vercel API. Create and manage + tokens in your Vercel account settings. + name: access_token + order: 0 + title: Access Token + airbyte_secret: true + start_date: + type: string + order: 1 + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + additionalProperties: true + +metadata: + autoImportSchema: + projects: true + teams: true + user: true + deployments: true + environments: true + auth_tokens: true + aliases: true + deployment_events: true + teams_member: true + testedStreams: + projects: + streamHash: 08d4d0f635315501525b1c7d058f34870a134971 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + teams: + streamHash: f6df1fdcb85c0e373936f42ee426fb398d4d3c52 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + user: + streamHash: fe64729451ad60d075bea483cc3928f4aa28b78e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + deployments: + streamHash: a3e87fc94c169653383c09af49917e74853e8475 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + environments: + streamHash: c6f89da72bc1d7d4b6c75a6d4c7fe32b83477574 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + auth_tokens: + streamHash: 8aff4e26dd5e62214e25d42b7883b81e4396da8a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + aliases: + streamHash: a0c3ba26db1e77b73f5ca19163b0094560ea58b5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + deployment_events: + streamHash: c98259fe5ba16f73291e8ed24022a5ceb9c42bd7 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + teams_member: + streamHash: b674b20a696a1b8e71ae80a30373b3827a07e66e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://vercel.com/docs/rest-api + +schemas: + projects: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accountId: + type: + - string + - "null" + autoAssignCustomDomains: + type: + - boolean + - "null" + autoAssignCustomDomainsUpdatedBy: + type: + - string + - "null" + autoExposeSystemEnvs: + type: + - boolean + - "null" + createdAt: + type: + - number + - "null" + crons: + type: + - object + - "null" + properties: + definitions: + type: + - array + - "null" + deploymentId: + type: + - string + - "null" + enabledAt: + type: + - number + - "null" + updatedAt: + type: + - number + - "null" + directoryListing: + type: + - boolean + - "null" + env: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + comment: + type: + - string + - "null" + createdAt: + type: + - number + - "null" + createdBy: + type: + - string + - "null" + id: + type: + - string + - "null" + key: + type: + - string + - "null" + target: + type: + - array + - "null" + items: + type: + - string + - "null" + updatedAt: + type: + - number + - "null" + value: + type: + - string + - "null" + framework: + type: + - string + - "null" + gitComments: + type: + - object + - "null" + properties: + onCommit: + type: + - boolean + - "null" + onPullRequest: + type: + - boolean + - "null" + gitForkProtection: + type: + - boolean + - "null" + gitLFS: + type: + - boolean + - "null" + id: + type: string + latestDeployments: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + alias: + type: + - array + - "null" + items: + type: + - string + - "null" + aliasAssigned: + type: + - number + - "null" + automaticAliases: + type: + - array + - "null" + items: + type: + - string + - "null" + buildingAt: + type: + - number + - "null" + builds: + type: + - array + - "null" + createdAt: + type: + - number + - "null" + createdIn: + type: + - string + - "null" + creator: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + githubLogin: + type: + - string + - "null" + uid: + type: + - string + - "null" + username: + type: + - string + - "null" + deploymentHostname: + type: + - string + - "null" + forced: + type: + - boolean + - "null" + id: + type: + - string + - "null" + meta: + type: + - object + - "null" + properties: + branchAlias: + type: + - string + - "null" + githubCommitAuthorLogin: + type: + - string + - "null" + githubCommitAuthorName: + type: + - string + - "null" + githubCommitMessage: + type: + - string + - "null" + githubCommitOrg: + type: + - string + - "null" + githubCommitRef: + type: + - string + - "null" + githubCommitRepo: + type: + - string + - "null" + githubCommitRepoId: + type: + - string + - "null" + githubCommitSha: + type: + - string + - "null" + githubDeployment: + type: + - string + - "null" + githubOrg: + type: + - string + - "null" + githubRepo: + type: + - string + - "null" + githubRepoId: + type: + - string + - "null" + githubRepoOwnerType: + type: + - string + - "null" + githubRepoVisibility: + type: + - string + - "null" + name: + type: + - string + - "null" + plan: + type: + - string + - "null" + previewCommentsEnabled: + type: + - boolean + - "null" + private: + type: + - boolean + - "null" + readyAt: + type: + - number + - "null" + readyState: + type: + - string + - "null" + readySubstate: + type: + - string + - "null" + target: + type: + - string + - "null" + teamId: + type: + - string + - "null" + url: + type: + - string + - "null" + userId: + type: + - string + - "null" + withCache: + type: + - boolean + - "null" + link: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + createdAt: + type: + - number + - "null" + deployHooks: + type: + - array + - "null" + gitCredentialId: + type: + - string + - "null" + org: + type: + - string + - "null" + productionBranch: + type: + - string + - "null" + repo: + type: + - string + - "null" + repoId: + type: + - number + - "null" + repoOwnerId: + type: + - number + - "null" + sourceless: + type: + - boolean + - "null" + updatedAt: + type: + - number + - "null" + live: + type: + - boolean + - "null" + name: + type: + - string + - "null" + nodeVersion: + type: + - string + - "null" + resourceConfig: + type: + - object + - "null" + properties: + functionDefaultMemoryType: + type: + - string + - "null" + serverlessFunctionRegion: + type: + - string + - "null" + sourceFilesOutsideRootDirectory: + type: + - boolean + - "null" + speedInsights: + type: + - object + - "null" + properties: + hasData: + type: + - boolean + - "null" + id: + type: + - string + - "null" + ssoProtection: + type: + - object + - "null" + properties: + deploymentType: + type: + - string + - "null" + targets: + type: + - object + - "null" + properties: + production: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + alias: + type: + - array + - "null" + items: + type: + - string + - "null" + aliasAssigned: + type: + - number + - "null" + automaticAliases: + type: + - array + - "null" + items: + type: + - string + - "null" + buildingAt: + type: + - number + - "null" + builds: + type: + - array + - "null" + createdAt: + type: + - number + - "null" + createdIn: + type: + - string + - "null" + creator: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + githubLogin: + type: + - string + - "null" + uid: + type: + - string + - "null" + username: + type: + - string + - "null" + deploymentHostname: + type: + - string + - "null" + forced: + type: + - boolean + - "null" + id: + type: + - string + - "null" + meta: + type: + - object + - "null" + properties: + branchAlias: + type: + - string + - "null" + githubCommitAuthorLogin: + type: + - string + - "null" + githubCommitAuthorName: + type: + - string + - "null" + githubCommitMessage: + type: + - string + - "null" + githubCommitOrg: + type: + - string + - "null" + githubCommitRef: + type: + - string + - "null" + githubCommitRepo: + type: + - string + - "null" + githubCommitRepoId: + type: + - string + - "null" + githubCommitSha: + type: + - string + - "null" + githubDeployment: + type: + - string + - "null" + githubOrg: + type: + - string + - "null" + githubRepo: + type: + - string + - "null" + githubRepoId: + type: + - string + - "null" + githubRepoOwnerType: + type: + - string + - "null" + githubRepoVisibility: + type: + - string + - "null" + name: + type: + - string + - "null" + plan: + type: + - string + - "null" + previewCommentsEnabled: + type: + - boolean + - "null" + private: + type: + - boolean + - "null" + readyAt: + type: + - number + - "null" + readyState: + type: + - string + - "null" + readySubstate: + type: + - string + - "null" + target: + type: + - string + - "null" + teamId: + type: + - string + - "null" + url: + type: + - string + - "null" + userId: + type: + - string + - "null" + withCache: + type: + - boolean + - "null" + updatedAt: + type: + - number + - "null" + webAnalytics: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + required: + - id + teams: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + billing: + type: + - object + - "null" + properties: + billingVersion: + type: + - number + - "null" + currency: + type: + - string + - "null" + email: + type: + - string + - "null" + name: + type: + - string + - "null" + plan: + type: + - string + - "null" + planIteration: + type: + - string + - "null" + platform: + type: + - string + - "null" + status: + type: + - string + - "null" + created: + type: + - string + - "null" + createdAt: + type: + - number + - "null" + createdDirectToHobby: + type: + - boolean + - "null" + creatorId: + type: + - string + - "null" + enabledInvoiceItems: + type: + - object + - "null" + properties: + vercelMarketplace: + type: + - object + - "null" + properties: + enabled: + type: + - boolean + - "null" + featureBlocks: + type: + - object + - "null" + id: + type: string + isMigratingToSensitiveEnvVars: + type: + - boolean + - "null" + membership: + type: + - object + - "null" + properties: + confirmed: + type: + - boolean + - "null" + created: + type: + - number + - "null" + createdAt: + type: + - number + - "null" + role: + type: + - string + - "null" + teamId: + type: + - string + - "null" + updatedAt: + type: + - number + - "null" + name: + type: + - string + - "null" + profiles: + type: + - array + - "null" + remoteCaching: + type: + - object + - "null" + properties: + enabled: + type: + - boolean + - "null" + resourceConfig: + type: + - object + - "null" + properties: + concurrentBuilds: + type: + - number + - "null" + sensitiveEnvironmentVariablePolicy: + type: + - string + - "null" + slug: + type: + - string + - "null" + spaces: + type: + - object + - "null" + properties: + enabled: + type: + - boolean + - "null" + stagingPrefix: + type: + - string + - "null" + updatedAt: + type: + - number + - "null" + required: + - id + user: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - string + - "null" + billing: + type: + - object + - "null" + properties: + currency: + type: + - string + - "null" + plan: + type: + - string + - "null" + platform: + type: + - string + - "null" + status: + type: + - string + - "null" + createdAt: + type: + - number + - "null" + dataCache: + type: + - object + - "null" + properties: + excessBillingEnabled: + type: + - boolean + - "null" + defaultTeamId: + type: + - string + - "null" + dismissedToasts: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + dismissals: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + createdAt: + type: + - number + - "null" + scopeId: + type: + - string + - "null" + name: + type: + - string + - "null" + email: + type: + - string + - "null" + featureBlocks: + type: + - object + - "null" + hasTrialAvailable: + type: + - boolean + - "null" + id: + type: + - string + - "null" + importFlowGitNamespaceId: + type: + - number + - "null" + importFlowGitProvider: + type: + - string + - "null" + remoteCaching: + type: + - object + - "null" + properties: + enabled: + type: + - boolean + - "null" + resourceConfig: + type: + - object + - "null" + properties: + concurrentBuilds: + type: + - number + - "null" + stagingPrefix: + type: + - string + - "null" + username: + type: + - string + - "null" + deployments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + aliasAssigned: + type: + - number + - "null" + buildingAt: + type: + - number + - "null" + created: + type: + - number + - "null" + createdAt: + type: number + creator: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + githubLogin: + type: + - string + - "null" + uid: + type: + - string + - "null" + username: + type: + - string + - "null" + inspectorUrl: + type: + - string + - "null" + isRollbackCandidate: + type: + - boolean + - "null" + meta: + type: + - object + - "null" + properties: + action: + type: + - string + - "null" + branchAlias: + type: + - string + - "null" + githubCommitAuthorLogin: + type: + - string + - "null" + githubCommitAuthorName: + type: + - string + - "null" + githubCommitMessage: + type: + - string + - "null" + githubCommitOrg: + type: + - string + - "null" + githubCommitRef: + type: + - string + - "null" + githubCommitRepo: + type: + - string + - "null" + githubCommitRepoId: + type: + - string + - "null" + githubCommitSha: + type: + - string + - "null" + githubDeployment: + type: + - string + - "null" + githubOrg: + type: + - string + - "null" + githubRepo: + type: + - string + - "null" + githubRepoId: + type: + - string + - "null" + githubRepoOwnerType: + type: + - string + - "null" + githubRepoVisibility: + type: + - string + - "null" + originalDeploymentId: + type: + - string + - "null" + name: + type: + - string + - "null" + projectSettings: + type: + - object + - "null" + properties: {} + ready: + type: + - number + - "null" + readyState: + type: + - string + - "null" + readySubstate: + type: + - string + - "null" + source: + type: + - string + - "null" + state: + type: + - string + - "null" + target: + type: + - string + - "null" + uid: + type: string + url: + type: + - string + - "null" + required: + - uid + - createdAt + environments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + comment: + type: + - string + - "null" + createdAt: + type: + - number + - "null" + createdBy: + type: + - string + - "null" + decrypted: + type: + - boolean + - "null" + id: + type: + - string + - "null" + key: + type: + - string + - "null" + lastEditedByDisplayName: + type: + - string + - "null" + target: + type: + - array + - "null" + items: + type: + - string + - "null" + updatedAt: + type: + - number + - "null" + value: + type: + - string + - "null" + vsmValue: + type: + - string + - "null" + auth_tokens: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + activeAt: + type: + - number + - "null" + createdAt: + type: + - number + - "null" + expiresAt: + type: + - number + - "null" + id: + type: string + name: + type: + - string + - "null" + origin: + type: + - string + - "null" + scopes: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + createdAt: + type: + - number + - "null" + expiresAt: + type: + - number + - "null" + origin: + type: + - string + - "null" + teamId: + type: + - string + - "null" + teamId: + type: + - string + - "null" + required: + - id + aliases: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + alias: + type: + - string + - "null" + created: + type: + - string + - "null" + createdAt: + type: + - number + - "null" + creator: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + uid: + type: + - string + - "null" + username: + type: + - string + - "null" + deployment: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + url: + type: + - string + - "null" + deploymentId: + type: + - string + - "null" + projectId: + type: + - string + - "null" + uid: + type: string + updatedAt: + type: number + required: + - uid + - updatedAt + deployment_events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + created: + type: + - number + - "null" + date: + type: + - number + - "null" + deploymentId: + type: + - string + - "null" + id: + type: string + info: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + entrypoint: + type: + - string + - "null" + name: + type: + - string + - "null" + level: + type: + - string + - "null" + serial: + type: + - string + - "null" + text: + type: + - string + - "null" + required: + - id + teams_member: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accessGroups: + type: + - array + - "null" + confirmed: + type: + - boolean + - "null" + createdAt: + type: + - number + - "null" + email: + type: + - string + - "null" + github: + type: + - object + - "null" + properties: + login: + type: + - string + - "null" + role: + type: + - string + - "null" + team_id: + type: + - string + - "null" + uid: + type: string + username: + type: + - string + - "null" + required: + - uid diff --git a/airbyte-integrations/connectors/source-vercel/metadata.yaml b/airbyte-integrations/connectors/source-vercel/metadata.yaml new file mode 100644 index 000000000000..063e70e89487 --- /dev/null +++ b/airbyte-integrations/connectors/source-vercel/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.vercel.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-vercel + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 7de74599-7bbe-4610-8635-00c76885e51d + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-vercel + githubIssueLabel: source-vercel + icon: icon.svg + license: MIT + name: Vercel + releaseDate: 2024-10-22 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/vercel + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-visma-economic/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-visma-economic/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-visma-economic/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-visma-economic/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-visma-economic/metadata.yaml b/airbyte-integrations/connectors/source-visma-economic/metadata.yaml index ce6f5957b2ba..ce481105cfe7 100644 --- a/airbyte-integrations/connectors/source-visma-economic/metadata.yaml +++ b/airbyte-integrations/connectors/source-visma-economic/metadata.yaml @@ -3,11 +3,11 @@ data: hosts: - restapi.e-conomic.com connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 42495935-95de-4f5c-ae08-8fac00f6b308 - dockerImageTag: 0.3.3 + dockerImageTag: 0.3.7 dockerRepository: airbyte/source-visma-economic documentationUrl: https://docs.airbyte.com/integrations/sources/visma-economic githubIssueLabel: source-visma-economic diff --git a/airbyte-integrations/connectors/source-vitally/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-vitally/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-vitally/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-vitally/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-vwo/metadata.yaml b/airbyte-integrations/connectors/source-vwo/metadata.yaml index f0c82186fca3..72b2417a571d 100644 --- a/airbyte-integrations/connectors/source-vwo/metadata.yaml +++ b/airbyte-integrations/connectors/source-vwo/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-vwo connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: c739daf4-71c9-4dde-b115-269bcd1b87d6 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-vwo githubIssueLabel: source-vwo icon: icon.svg diff --git a/airbyte-integrations/connectors/source-waiteraid/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-waiteraid/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-waiteraid/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-waiteraid/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-waiteraid/metadata.yaml b/airbyte-integrations/connectors/source-waiteraid/metadata.yaml index 5ae078fe1278..e39a853573b4 100644 --- a/airbyte-integrations/connectors/source-waiteraid/metadata.yaml +++ b/airbyte-integrations/connectors/source-waiteraid/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 03a53b13-794a-4d6b-8544-3b36ed8f3ce4 - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-waiteraid githubIssueLabel: source-waiteraid icon: waiteraid.svg @@ -27,5 +27,5 @@ data: ql: 100 supportLevel: community connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-weatherstack/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-weatherstack/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-weatherstack/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-weatherstack/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-web-scrapper/README.md b/airbyte-integrations/connectors/source-web-scrapper/README.md new file mode 100644 index 000000000000..c7f39aafa4a6 --- /dev/null +++ b/airbyte-integrations/connectors/source-web-scrapper/README.md @@ -0,0 +1,33 @@ +# Web Scrapper +This directory contains the manifest-only connector for `source-web-scrapper`. + +Web Scrapper connector enables data synchronization from Web Scrapper source to various data destination. It gives information about sitemaps, users, scraping jobs etc. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-web-scrapper:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-web-scrapper build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-web-scrapper test +``` + diff --git a/airbyte-integrations/connectors/source-web-scrapper/acceptance-test-config.yml b/airbyte-integrations/connectors/source-web-scrapper/acceptance-test-config.yml new file mode 100644 index 000000000000..247bb48c4903 --- /dev/null +++ b/airbyte-integrations/connectors/source-web-scrapper/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-web-scrapper:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-web-scrapper/icon.svg b/airbyte-integrations/connectors/source-web-scrapper/icon.svg new file mode 100644 index 000000000000..4caf78b9bebc --- /dev/null +++ b/airbyte-integrations/connectors/source-web-scrapper/icon.svg @@ -0,0 +1,321 @@ + + + + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-web-scrapper/manifest.yaml b/airbyte-integrations/connectors/source-web-scrapper/manifest.yaml new file mode 100644 index 000000000000..98ac831ce009 --- /dev/null +++ b/airbyte-integrations/connectors/source-web-scrapper/manifest.yaml @@ -0,0 +1,658 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: >- + Web Scrapper connector enables data synchronization from Web Scrapper source + to various data destination. It gives information about sitemaps, users, + scraping jobs etc. + +check: + type: CheckStream + stream_names: + - sitemap_list + +definitions: + streams: + sitemap_list: + type: DeclarativeStream + name: sitemap_list + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/sitemaps + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + page_size: 100 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sitemap_list" + users: + type: DeclarativeStream + name: users + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/account + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + scraping_jobs: + type: DeclarativeStream + name: scraping_jobs + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/scraping-jobs + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + pagination_strategy: + type: PageIncrement + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/scraping_jobs" + scraping_job_data_quality: + type: DeclarativeStream + name: scraping_job_data_quality + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: >- + /api/v1/scraping-job/{{ stream_partition.scraping_job + }}/data-quality + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: scraping_job + stream: + $ref: "#/definitions/streams/scraping_jobs" + transformations: + - type: AddFields + fields: + - path: + - scraping_job + value: "{{ stream_slice.scraping_job }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/scraping_job_data_quality" + sitemap_detail: + type: DeclarativeStream + name: sitemap_detail + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /api/v1/sitemap/{{stream_partition.sitemap_id}} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: sitemap_id + stream: + $ref: "#/definitions/streams/sitemap_list" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/sitemap_detail" + base_requester: + type: HttpRequester + url_base: https://api.webscraper.io + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_token\"] }}" + inject_into: + type: RequestOption + field_name: api_token + inject_into: request_parameter + +streams: + - $ref: "#/definitions/streams/sitemap_list" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/scraping_jobs" + - $ref: "#/definitions/streams/scraping_job_data_quality" + - $ref: "#/definitions/streams/sitemap_detail" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_token + properties: + api_token: + type: string + description: API token to use. Find it at https://cloud.webscraper.io/api + name: api_token + order: 0 + title: API Token + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + sitemap_list: true + users: true + scraping_jobs: true + scraping_job_data_quality: true + sitemap_detail: true + testedStreams: + sitemap_list: + streamHash: 3f486ff4a4f9b6d42e2c357a47b4e129841f618c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + users: + streamHash: bbdcf3fa16b1f9418d8de88104cf767f80a6605f + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + scraping_jobs: + streamHash: 3bf27ee2242c4556a1261ece0ea757b1dd9859e5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + scraping_job_data_quality: + streamHash: c2e39750e0e2fa0b30ccf392c7b1a613a0878a50 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + sitemap_detail: + streamHash: 69d02ba9a400cbda2f01accffc1248cdb41eee20 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://webscraper.io/documentation/web-scraper-cloud/api + +schemas: + sitemap_list: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: number + name: + type: + - string + - "null" + required: + - id + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + email: + type: + - string + - "null" + firstname: + type: + - string + - "null" + lastname: + type: + - string + - "null" + page_credits: + type: + - number + - "null" + scraping_jobs: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + driver: + type: + - string + - "null" + id: + type: number + jobs_empty: + type: + - number + - "null" + jobs_executed: + type: + - number + - "null" + jobs_failed: + type: + - number + - "null" + jobs_no_value: + type: + - number + - "null" + jobs_scheduled: + type: + - number + - "null" + page_load_delay: + type: + - number + - "null" + request_interval: + type: + - number + - "null" + scheduled: + type: + - number + - "null" + scraping_duration: + type: + - number + - "null" + sitemap_id: + type: + - number + - "null" + sitemap_name: + type: + - string + - "null" + status: + type: + - string + - "null" + stored_record_count: + type: + - number + - "null" + test_run: + type: + - number + - "null" + time_created: + type: + - number + - "null" + required: + - id + scraping_job_data_quality: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + max_empty_pages_percent: + type: + - object + - "null" + properties: + expected: + type: + - number + - "null" + got: + type: + - number + - "null" + success: + type: + - boolean + - "null" + max_failed_pages_percent: + type: + - object + - "null" + properties: + expected: + type: + - number + - "null" + got: + type: + - number + - "null" + success: + type: + - boolean + - "null" + max_no_value_pages_percent: + type: + - object + - "null" + properties: + expected: + type: + - number + - "null" + got: + type: + - number + - "null" + success: + type: + - boolean + - "null" + min_column_records: + type: + - object + - "null" + properties: + description: + type: + - object + - "null" + properties: + expected: + type: + - number + - "null" + got: + type: + - number + - "null" + success: + type: + - boolean + - "null" + category-link: + type: + - object + - "null" + properties: + expected: + type: + - number + - "null" + got: + type: + - number + - "null" + success: + type: + - boolean + - "null" + category-link-href: + type: + - object + - "null" + properties: + expected: + type: + - number + - "null" + got: + type: + - number + - "null" + success: + type: + - boolean + - "null" + name: + type: + - object + - "null" + properties: + expected: + type: + - number + - "null" + got: + type: + - number + - "null" + success: + type: + - boolean + - "null" + pagination: + type: + - object + - "null" + properties: + expected: + type: + - number + - "null" + got: + type: + - number + - "null" + success: + type: + - boolean + - "null" + pagination-href: + type: + - object + - "null" + properties: + expected: + type: + - number + - "null" + got: + type: + - number + - "null" + success: + type: + - boolean + - "null" + price: + type: + - object + - "null" + properties: + expected: + type: + - number + - "null" + got: + type: + - number + - "null" + success: + type: + - boolean + - "null" + product-link: + type: + - object + - "null" + properties: + expected: + type: + - number + - "null" + got: + type: + - number + - "null" + success: + type: + - boolean + - "null" + product-link-href: + type: + - object + - "null" + properties: + expected: + type: + - number + - "null" + got: + type: + - number + - "null" + success: + type: + - boolean + - "null" + reviews: + type: + - object + - "null" + properties: + expected: + type: + - number + - "null" + got: + type: + - number + - "null" + success: + type: + - boolean + - "null" + subcategory-link: + type: + - object + - "null" + properties: + expected: + type: + - number + - "null" + got: + type: + - number + - "null" + success: + type: + - boolean + - "null" + subcategory-link-href: + type: + - object + - "null" + properties: + expected: + type: + - number + - "null" + got: + type: + - number + - "null" + success: + type: + - boolean + - "null" + min_record_count: + type: + - object + - "null" + properties: + expected: + type: + - number + - "null" + got: + type: + - number + - "null" + success: + type: + - boolean + - "null" + overall_data_quality_success: + type: + - boolean + - "null" + scraping_job: + type: + - number + - "null" + sitemap_detail: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: number + name: + type: + - string + - "null" + sitemap: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-web-scrapper/metadata.yaml b/airbyte-integrations/connectors/source-web-scrapper/metadata.yaml new file mode 100644 index 000000000000..f6433cb9fffa --- /dev/null +++ b/airbyte-integrations/connectors/source-web-scrapper/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "api.webscraper.io" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-web-scrapper + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 2f87b960-0220-4b76-9ab3-fba67ca4c959 + dockerImageTag: 0.0.7 + dockerRepository: airbyte/source-web-scrapper + githubIssueLabel: source-web-scrapper + icon: icon.svg + license: MIT + name: Web Scrapper + releaseDate: 2024-10-29 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/web-scrapper + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-webflow/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-webflow/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-webflow/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-webflow/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-webflow/main.py b/airbyte-integrations/connectors/source-webflow/main.py index 4d481e07151b..5f67a19aa9a7 100644 --- a/airbyte-integrations/connectors/source-webflow/main.py +++ b/airbyte-integrations/connectors/source-webflow/main.py @@ -4,5 +4,6 @@ from source_webflow.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-webflow/metadata.yaml b/airbyte-integrations/connectors/source-webflow/metadata.yaml index 809980bb5ff0..2c60c1ec0b3c 100644 --- a/airbyte-integrations/connectors/source-webflow/metadata.yaml +++ b/airbyte-integrations/connectors/source-webflow/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: ef580275-d9a9-48bb-af5e-db0f5855be04 - dockerImageTag: 0.1.26 + dockerImageTag: 0.1.31 dockerRepository: airbyte/source-webflow githubIssueLabel: source-webflow icon: webflow.svg @@ -40,5 +40,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-webflow/poetry.lock b/airbyte-integrations/connectors/source-webflow/poetry.lock index 7a6a3934921d..1077e5f93884 100644 --- a/airbyte-integrations/connectors/source-webflow/poetry.lock +++ b/airbyte-integrations/connectors/source-webflow/poetry.lock @@ -62,19 +62,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -140,127 +140,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -276,20 +263,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -367,13 +354,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -486,13 +473,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -573,54 +560,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -884,33 +871,33 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "75.3.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -951,13 +938,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -982,81 +969,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-webflow/pyproject.toml b/airbyte-integrations/connectors/source-webflow/pyproject.toml index 651e49ce031f..f81045b64dc2 100644 --- a/airbyte-integrations/connectors/source-webflow/pyproject.toml +++ b/airbyte-integrations/connectors/source-webflow/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.26" +version = "0.1.31" name = "source-webflow" description = "Source implementation for Webflow." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-webflow/source_webflow/source.py b/airbyte-integrations/connectors/source-webflow/source_webflow/source.py index f7e3daa64937..4eacbe1bfcd8 100644 --- a/airbyte-integrations/connectors/source-webflow/source_webflow/source.py +++ b/airbyte-integrations/connectors/source-webflow/source_webflow/source.py @@ -8,6 +8,7 @@ from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Tuple import requests + from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http import HttpStream @@ -15,6 +16,7 @@ from .auth import WebflowTokenAuthenticator from .webflow_to_airbyte_mapping import WebflowToAirbyteMapping + """ This module is used for pulling the contents of "collections" out of Webflow, which is a CMS for hosting websites. A Webflow collection may be a group of items such as "Blog Posts", "Blog Authors", etc. @@ -201,7 +203,6 @@ def request_params( stream_slice: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None, ) -> MutableMapping[str, Any]: - # Webflow default pagination is 100, for debugging pagination we set this to a low value. # This should be set back to 100 for production params = {"limit": 100} @@ -256,7 +257,6 @@ def get_json_schema(self) -> Mapping[str, Any]: class SourceWebflow(AbstractSource): - """This is the main class that defines the methods that will be called by Airbyte infrastructure""" @staticmethod diff --git a/airbyte-integrations/connectors/source-webflow/source_webflow/webflow_to_airbyte_mapping.py b/airbyte-integrations/connectors/source-webflow/source_webflow/webflow_to_airbyte_mapping.py index ea40dc0ab320..4b6061984649 100644 --- a/airbyte-integrations/connectors/source-webflow/source_webflow/webflow_to_airbyte_mapping.py +++ b/airbyte-integrations/connectors/source-webflow/source_webflow/webflow_to_airbyte_mapping.py @@ -4,7 +4,6 @@ class WebflowToAirbyteMapping: - """ The following disctionary is used for dynamically pulling the schema from Webflow, and mapping it to an Airbyte-compatible json-schema Webflow: https://developers.webflow.com/#get-collection-with-full-schema diff --git a/airbyte-integrations/connectors/source-when-i-work/metadata.yaml b/airbyte-integrations/connectors/source-when-i-work/metadata.yaml index eb1dd5a0717d..ef6f810f20da 100644 --- a/airbyte-integrations/connectors/source-when-i-work/metadata.yaml +++ b/airbyte-integrations/connectors/source-when-i-work/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-when-i-work connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 81ee3b58-ae1e-4727-be23-30248fa27a0a - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-when-i-work githubIssueLabel: source-when-i-work icon: icon.svg diff --git a/airbyte-integrations/connectors/source-whisky-hunter/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-whisky-hunter/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-whisky-hunter/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-whisky-hunter/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-whisky-hunter/metadata.yaml b/airbyte-integrations/connectors/source-whisky-hunter/metadata.yaml index 8c00cdbe34c2..57f5df4cae87 100644 --- a/airbyte-integrations/connectors/source-whisky-hunter/metadata.yaml +++ b/airbyte-integrations/connectors/source-whisky-hunter/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: e65f84c0-7598-458a-bfac-f770c381ff5d - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.9 dockerRepository: airbyte/source-whisky-hunter githubIssueLabel: source-whisky-hunter icon: whiskyhunter.svg @@ -39,5 +39,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-wikipedia-pageviews/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-wikipedia-pageviews/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-wikipedia-pageviews/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-wikipedia-pageviews/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-wikipedia-pageviews/metadata.yaml b/airbyte-integrations/connectors/source-wikipedia-pageviews/metadata.yaml index 4ad402cf3d52..f7afeaf0d4fd 100644 --- a/airbyte-integrations/connectors/source-wikipedia-pageviews/metadata.yaml +++ b/airbyte-integrations/connectors/source-wikipedia-pageviews/metadata.yaml @@ -6,11 +6,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 87c58f70-6f7a-4f70-aba5-bab1a458f5ba - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.5 dockerRepository: airbyte/source-wikipedia-pageviews githubIssueLabel: source-wikipedia-pageviews icon: wikipedia-pageviews.svg diff --git a/airbyte-integrations/connectors/source-woocommerce/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-woocommerce/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-woocommerce/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-woocommerce/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-woocommerce/metadata.yaml b/airbyte-integrations/connectors/source-woocommerce/metadata.yaml index f6ec0087e55b..b0a716e4d281 100644 --- a/airbyte-integrations/connectors/source-woocommerce/metadata.yaml +++ b/airbyte-integrations/connectors/source-woocommerce/metadata.yaml @@ -8,7 +8,7 @@ data: connectorSubtype: api connectorType: source definitionId: 2a2552ca-9f78-4c1c-9eb7-4d0dc66d72df - dockerImageTag: 0.5.0 + dockerImageTag: 0.5.4 dockerRepository: airbyte/source-woocommerce documentationUrl: https://docs.airbyte.com/integrations/sources/woocommerce githubIssueLabel: source-woocommerce @@ -46,5 +46,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.11.1@sha256:f48a7ddc1f3acecbd8eb6a10a3146e8d0396e9a4dede77beafb76924f416df65 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-wordpress/metadata.yaml b/airbyte-integrations/connectors/source-wordpress/metadata.yaml index 7927a3200256..ef7e9e6209de 100644 --- a/airbyte-integrations/connectors/source-wordpress/metadata.yaml +++ b/airbyte-integrations/connectors/source-wordpress/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-wordpress connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.14.0@sha256:accdf6c1bbcabd45b40f836692e4f3b1a1e1f0b28267973802ee212cd9c2c16a + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: c71d6f95-a912-432b-ad96-73ded4be7b9c - dockerImageTag: 0.0.1 + dockerImageTag: 0.0.5 dockerRepository: airbyte/source-wordpress githubIssueLabel: source-wordpress icon: icon.svg diff --git a/airbyte-integrations/connectors/source-workable/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-workable/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-workable/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-workable/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-workflowmax/metadata.yaml b/airbyte-integrations/connectors/source-workflowmax/metadata.yaml index aa3a1dc2dfa3..c53d0c6a1f26 100644 --- a/airbyte-integrations/connectors/source-workflowmax/metadata.yaml +++ b/airbyte-integrations/connectors/source-workflowmax/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-workflowmax connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: a3eb6410-f3c3-48ba-8b27-29a56de1e9db - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.5 dockerRepository: airbyte/source-workflowmax githubIssueLabel: source-workflowmax icon: icon.svg diff --git a/airbyte-integrations/connectors/source-workramp/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-workramp/integration_tests/acceptance.py index aaeb7f6c2529..a56a495fcd92 100644 --- a/airbyte-integrations/connectors/source-workramp/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-workramp/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-workramp/metadata.yaml b/airbyte-integrations/connectors/source-workramp/metadata.yaml index 0dd3e85a3d0c..2457c6edbac4 100644 --- a/airbyte-integrations/connectors/source-workramp/metadata.yaml +++ b/airbyte-integrations/connectors/source-workramp/metadata.yaml @@ -12,11 +12,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:4.4.3@sha256:8937b693c7e01087f6e86e683826ac20f160f7952b8f0a13cbf4f9bfdd7af570 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 05b0bce2-4ec4-4534-bb1a-5d0127bd91b7 - dockerImageTag: 0.2.1 + dockerImageTag: 0.2.6 dockerRepository: airbyte/source-workramp githubIssueLabel: source-workramp icon: workramp.svg diff --git a/airbyte-integrations/connectors/source-wrike/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-wrike/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-wrike/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-wrike/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-wrike/metadata.yaml b/airbyte-integrations/connectors/source-wrike/metadata.yaml index 7b9488d276b4..97d8a8659e1e 100644 --- a/airbyte-integrations/connectors/source-wrike/metadata.yaml +++ b/airbyte-integrations/connectors/source-wrike/metadata.yaml @@ -5,7 +5,7 @@ data: - app-eu*.wrike.com - www.wrike.com connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc remoteRegistries: pypi: enabled: false @@ -18,7 +18,7 @@ data: connectorSubtype: api connectorType: source definitionId: 9c13f986-a13b-4988-b808-4705badf71c2 - dockerImageTag: 0.3.4 + dockerImageTag: 0.3.8 dockerRepository: airbyte/source-wrike githubIssueLabel: source-wrike icon: wrike.svg diff --git a/airbyte-integrations/connectors/source-wufoo/README.md b/airbyte-integrations/connectors/source-wufoo/README.md new file mode 100644 index 000000000000..bc3a60f0e6d0 --- /dev/null +++ b/airbyte-integrations/connectors/source-wufoo/README.md @@ -0,0 +1,33 @@ +# Wufoo +This directory contains the manifest-only connector for `source-wufoo`. + +The Airbyte connector for [Wufoo](https://www.wufoo.com/) enables seamless data integration between Wufoo and various destinations. It extracts form entries, form metadata, and user information from Wufoo via the Wufoo API. This connector helps automate the synchronization of survey and form data with your chosen data warehouse or analytical tools, simplifying data-driven insights and reporting. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-wufoo:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-wufoo build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-wufoo test +``` + diff --git a/airbyte-integrations/connectors/source-wufoo/acceptance-test-config.yml b/airbyte-integrations/connectors/source-wufoo/acceptance-test-config.yml new file mode 100644 index 000000000000..76f8777701f9 --- /dev/null +++ b/airbyte-integrations/connectors/source-wufoo/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-wufoo:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-wufoo/icon.svg b/airbyte-integrations/connectors/source-wufoo/icon.svg new file mode 100644 index 000000000000..ff74bc896c23 --- /dev/null +++ b/airbyte-integrations/connectors/source-wufoo/icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/airbyte-integrations/connectors/source-wufoo/manifest.yaml b/airbyte-integrations/connectors/source-wufoo/manifest.yaml new file mode 100644 index 000000000000..6f2f41e06a70 --- /dev/null +++ b/airbyte-integrations/connectors/source-wufoo/manifest.yaml @@ -0,0 +1,932 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + The Airbyte connector for [Wufoo](https://www.wufoo.com/) enables seamless + data integration between Wufoo and various destinations. It extracts form + entries, form metadata, and user information from Wufoo via the Wufoo API. + This connector helps automate the synchronization of survey and form data with + your chosen data warehouse or analytical tools, simplifying data-driven + insights and reporting. + +check: + type: CheckStream + stream_names: + - forms + +definitions: + streams: + forms: + type: DeclarativeStream + name: forms + primary_key: + - Hash + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /forms.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Forms + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/forms" + form_comments: + type: DeclarativeStream + name: form_comments + primary_key: + - CommentId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /forms/{{ stream_partition.form_identifier }}/comments.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Comments + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageStart + page_size_option: + type: RequestOption + field_name: pageSize + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: Hash + partition_field: form_identifier + stream: + $ref: "#/definitions/streams/forms" + transformations: + - type: AddFields + fields: + - path: + - Hash + value: "{{ stream_slice.form_identifier }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/form_comments" + form_fields: + type: DeclarativeStream + name: form_fields + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /forms/{{ stream_partition.form_identifier }}/fields.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Fields + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: Hash + partition_field: form_identifier + stream: + $ref: "#/definitions/streams/forms" + transformations: + - type: AddFields + fields: + - path: + - Hash + value: "{{ stream_slice.form_identifier }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/form_fields" + form_entries: + type: DeclarativeStream + name: form_entries + primary_key: + - EntryId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /forms/{{ stream_partition.form_identifier }}/entries.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Entries + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageStart + page_size_option: + type: RequestOption + field_name: pageSize + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: Hash + partition_field: form_identifier + stream: + $ref: "#/definitions/streams/forms" + transformations: + - type: AddFields + fields: + - path: + - Hash + value: "{{ stream_slice.form_identifier }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/form_entries" + reports: + type: DeclarativeStream + name: reports + primary_key: + - Hash + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /reports.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Reports + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/reports" + report_entries: + type: DeclarativeStream + name: report_entries + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /reports/{{ stream_partition.report_identifier }}/entries.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Entries + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: Hash + partition_field: report_identifier + stream: + $ref: "#/definitions/streams/reports" + transformations: + - type: AddFields + fields: + - path: + - Hash + value: "{{ stream_slice.form_identifier }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/report_entries" + report_fields: + type: DeclarativeStream + name: report_fields + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /reports/{{ stream_partition.report_identifier }}/fields.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Fields + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: Hash + partition_field: report_identifier + stream: + $ref: "#/definitions/streams/reports" + transformations: + - type: AddFields + fields: + - path: + - Hash + value: "{{ stream_slice.form_identifier }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/report_fields" + report_widgets: + type: DeclarativeStream + name: report_widgets + primary_key: + - Hash + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /reports/{{ stream_partition.report_identifier }}/widgets.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Widgets + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: Hash + partition_field: report_identifier + stream: + $ref: "#/definitions/streams/reports" + transformations: + - type: AddFields + fields: + - path: + - ParentHash + value: "{{ stream_slice.form_identifier }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/report_widgets" + users: + type: DeclarativeStream + name: users + primary_key: + - Hash + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /users.json + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - Users + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + base_requester: + type: HttpRequester + url_base: https://{{ config['subdomain'] }}.wufoo.com/api/v3 + authenticator: + type: BasicHttpAuthenticator + username: "{{ config[\"api_key\"] }}" + +streams: + - $ref: "#/definitions/streams/forms" + - $ref: "#/definitions/streams/form_comments" + - $ref: "#/definitions/streams/form_fields" + - $ref: "#/definitions/streams/form_entries" + - $ref: "#/definitions/streams/reports" + - $ref: "#/definitions/streams/report_entries" + - $ref: "#/definitions/streams/report_fields" + - $ref: "#/definitions/streams/report_widgets" + - $ref: "#/definitions/streams/users" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - subdomain + properties: + api_key: + type: string + description: >- + Your Wufoo API Key. You can find it by logging into your Wufoo + account, selecting 'API Information' from the 'More' dropdown on any + form, and locating the 16-digit code. + name: api_key + order: 0 + title: API Key + airbyte_secret: true + subdomain: + type: string + description: Your account subdomain/username for Wufoo. + name: subdomain + order: 1 + title: Subdomain + additionalProperties: true + +metadata: + autoImportSchema: + forms: true + form_comments: false + form_fields: false + form_entries: false + reports: true + report_entries: false + report_fields: false + report_widgets: false + users: true + yamlComponents: + global: + - authenticator + testedStreams: + forms: + streamHash: 3e8a6c437d8154adbcecb09841f9623e0a65cd38 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + form_comments: + streamHash: 03ff538dbd33b1edfcf0b62861316237f817a447 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + form_fields: + streamHash: 5928b041e2194511ad00a496dbcde128f6c4f55c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + form_entries: + streamHash: 152a88ebaadc7f666d5429092429ebcf98b655cf + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + reports: + streamHash: 95a82666ed200e648e146026c10cba4c126b0f37 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + report_entries: + streamHash: 5a4d509e27dc231dae639e6a74949a2dac566122 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + report_fields: + streamHash: 28bbb9e5e6dcba068d2aa948829100d1b1e4d7d8 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + report_widgets: + streamHash: 02aabea6a27fac4a9ea692aaea2285dad51c451e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + users: + hasRecords: true + streamHash: 43d9b0a10663cec6591ef6f5672fc6100aea09fb + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://wufoo.github.io/docs/ + +schemas: + forms: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + DateCreated: + type: + - string + - "null" + DateUpdated: + type: + - string + - "null" + Email: + type: + - string + - "null" + EndDate: + type: + - string + - "null" + EntryLimit: + type: + - string + - "null" + Hash: + type: string + IsPublic: + type: + - string + - "null" + Language: + type: + - string + - "null" + LinkEntries: + type: + - string + - "null" + LinkEntriesCount: + type: + - string + - "null" + LinkFields: + type: + - string + - "null" + Name: + type: + - string + - "null" + RedirectMessage: + type: + - string + - "null" + StartDate: + type: + - string + - "null" + Url: + type: + - string + - "null" + required: + - Hash + form_comments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + CommentId: + type: number + CommentedBy: + type: + - string + - "null" + DateCreated: + type: + - string + - "null" + EntryId: + type: + - number + - "null" + Text: + type: + - string + - "null" + required: + - CommentId + form_fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Choices: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + Label: + type: + - string + - "null" + Score: + type: + - number + - "null" + ClassNames: + type: + - string + - "null" + DefaultVal: + type: + - string + - "null" + HasOtherField: + type: + - boolean + - "null" + ID: + type: + - string + - "null" + Instructions: + type: + - string + - "null" + IsRequired: + type: + - string + - "null" + Page: + type: + - string + - "null" + SubFields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + DefaultVal: + type: + - string + - "null" + ID: + type: + - string + - "null" + Label: + type: + - string + - "null" + Title: + type: + - string + - "null" + Type: + type: + - string + - "null" + form_entries: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + CreatedBy: + type: + - string + - "null" + DateCreated: + type: + - string + - "null" + DateUpdated: + type: + - string + - "null" + EntryId: + type: string + Field1: + type: + - string + - "null" + Field10: + type: + - string + - "null" + Field11: + type: + - string + - "null" + Field12: + type: + - string + - "null" + Field13: + type: + - string + - "null" + Field14: + type: + - string + - "null" + Field15: + type: + - string + - "null" + Field16: + type: + - string + - "null" + Field17: + type: + - string + - "null" + Field18: + type: + - string + - "null" + Field19: + type: + - string + - "null" + Field2: + type: + - string + - "null" + Field20: + type: + - string + - "null" + Field21: + type: + - string + - "null" + Field22: + type: + - string + - "null" + Field3: + type: + - string + - "null" + Field4: + type: + - string + - "null" + Field5: + type: + - string + - "null" + Field6: + type: + - string + - "null" + Field7: + type: + - string + - "null" + Field8: + type: + - string + - "null" + Field9: + type: + - string + - "null" + required: + - EntryId + reports: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + DateCreated: + type: + - string + - "null" + DateUpdated: + type: + - string + - "null" + Description: + type: + - string + - "null" + Hash: + type: string + IsPublic: + type: + - string + - "null" + LinkEntries: + type: + - string + - "null" + LinkEntriesCount: + type: + - string + - "null" + LinkFields: + type: + - string + - "null" + LinkWidgets: + type: + - string + - "null" + Name: + type: + - string + - "null" + Url: + type: + - string + - "null" + required: + - Hash + report_entries: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + CreatedBy: + type: + - string + - "null" + DateCreated: + type: + - string + - "null" + DateUpdated: + type: + - string + - "null" + EntryId: + type: string + Field1: + type: + - string + - "null" + Field2: + type: + - string + - "null" + required: + - EntryId + report_fields: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + ClassNames: + type: + - string + - "null" + DefaultVal: + type: + - string + - "null" + ID: + type: + - string + - "null" + Instructions: + type: + - string + - "null" + IsRequired: + type: + - string + - "null" + Page: + type: + - string + - "null" + Title: + type: + - string + - "null" + Type: + type: + - string + - "null" + report_widgets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Hash: + type: string + Name: + type: + - string + - "null" + Size: + type: + - string + - "null" + Type: + type: + - string + - "null" + TypeDesc: + type: + - string + - "null" + required: + - Hash + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + AdminAccess: + type: + - string + - "null" + ApiKey: + type: + - string + - "null" + Company: + type: + - string + - "null" + CreateForms: + type: + - string + - "null" + CreateReports: + type: + - string + - "null" + CreateThemes: + type: + - string + - "null" + Email: + type: + - string + - "null" + Hash: + type: string + HttpsEnabled: + type: + - string + - "null" + Image: + type: + - string + - "null" + ImageUrlBig: + type: + - string + - "null" + ImageUrlSmall: + type: + - string + - "null" + IsAccountOwner: + type: + - string + - "null" + LinkForms: + type: + - string + - "null" + LinkReports: + type: + - string + - "null" + TimeZone: + type: + - string + - "null" + User: + type: + - string + - "null" + required: + - Hash diff --git a/airbyte-integrations/connectors/source-wufoo/metadata.yaml b/airbyte-integrations/connectors/source-wufoo/metadata.yaml new file mode 100644 index 000000000000..aeb34d21810f --- /dev/null +++ b/airbyte-integrations/connectors/source-wufoo/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "https://*.wufoo.com/api/v3" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-wufoo + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 2e5fb207-5215-43ee-8b4f-88f6490e204e + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-wufoo + githubIssueLabel: source-wufoo + icon: icon.svg + license: MIT + name: Wufoo + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/wufoo + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-xero/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-xero/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-xero/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-xero/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-xero/main.py b/airbyte-integrations/connectors/source-xero/main.py index d765f10d2093..40c719373836 100644 --- a/airbyte-integrations/connectors/source-xero/main.py +++ b/airbyte-integrations/connectors/source-xero/main.py @@ -4,5 +4,6 @@ from source_xero.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-xero/source_xero/components.py b/airbyte-integrations/connectors/source-xero/source_xero/components.py index 2294372e6ab5..a9e4a6655cd3 100644 --- a/airbyte-integrations/connectors/source-xero/source_xero/components.py +++ b/airbyte-integrations/connectors/source-xero/source_xero/components.py @@ -9,6 +9,7 @@ import dpath.util import requests + from airbyte_cdk.sources.declarative.decoders.decoder import Decoder from airbyte_cdk.sources.declarative.decoders.json_decoder import JsonDecoder from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor diff --git a/airbyte-integrations/connectors/source-xero/source_xero/run.py b/airbyte-integrations/connectors/source-xero/source_xero/run.py index fb8d5955af03..99bb37a63595 100644 --- a/airbyte-integrations/connectors/source-xero/source_xero/run.py +++ b/airbyte-integrations/connectors/source-xero/source_xero/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_xero import SourceXero +from airbyte_cdk.entrypoint import launch + def run(): source = SourceXero() diff --git a/airbyte-integrations/connectors/source-xero/source_xero/source.py b/airbyte-integrations/connectors/source-xero/source_xero/source.py index 3209646cb044..7da885250cc5 100644 --- a/airbyte-integrations/connectors/source-xero/source_xero/source.py +++ b/airbyte-integrations/connectors/source-xero/source_xero/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-xero/unit_tests/conftest.py b/airbyte-integrations/connectors/source-xero/unit_tests/conftest.py index a2dcb6a4541a..1f8b9a330d54 100644 --- a/airbyte-integrations/connectors/source-xero/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-xero/unit_tests/conftest.py @@ -4,10 +4,11 @@ from typing import Any, Mapping -from airbyte_cdk.sources.streams import Stream from pytest import fixture from source_xero.source import SourceXero +from airbyte_cdk.sources.streams import Stream + @fixture(name="config_pass") def config_fixture(): diff --git a/airbyte-integrations/connectors/source-xero/unit_tests/test_custom_parsing.py b/airbyte-integrations/connectors/source-xero/unit_tests/test_custom_parsing.py index 13e3b37c9f12..17795ec5716f 100644 --- a/airbyte-integrations/connectors/source-xero/unit_tests/test_custom_parsing.py +++ b/airbyte-integrations/connectors/source-xero/unit_tests/test_custom_parsing.py @@ -4,13 +4,16 @@ import datetime -from airbyte_cdk.models import SyncMode from conftest import get_stream_by_name from source_xero.components import ParseDates +from airbyte_cdk.models import SyncMode + def test_parsed_result(requests_mock, config_pass, mock_bank_transaction_response): - requests_mock.get(url="https://api.xero.com/api.xro/2.0/BankTransactions", status_code=200, json=mock_bank_transaction_response["BankTransactions"]) + requests_mock.get( + url="https://api.xero.com/api.xro/2.0/BankTransactions", status_code=200, json=mock_bank_transaction_response["BankTransactions"] + ) stream = get_stream_by_name("bank_transactions", config_pass) expected_record = mock_bank_transaction_response["BankTransactions"] for stream_slice in stream.stream_slices(sync_mode=SyncMode.full_refresh): @@ -22,7 +25,9 @@ def test_parse_date(): # 11/10/2020 00:00:00 +3 (11/10/2020 21:00:00 GMT/UTC) assert ParseDates.parse_date("/Date(1602363600000+0300)/") == datetime.datetime(2020, 10, 11, 0, 0, tzinfo=datetime.timezone.utc) # 02/02/2020 10:31:51.5 +3 (02/02/2020 07:31:51.5 GMT/UTC) - assert ParseDates.parse_date("/Date(1580628711500+0300)/") == datetime.datetime(2020, 2, 2, 10, 31, 51, 500000, tzinfo=datetime.timezone.utc) + assert ParseDates.parse_date("/Date(1580628711500+0300)/") == datetime.datetime( + 2020, 2, 2, 10, 31, 51, 500000, tzinfo=datetime.timezone.utc + ) # 07/02/2022 20:12:55 GMT/UTC assert ParseDates.parse_date("/Date(1656792775000)/") == datetime.datetime(2022, 7, 2, 20, 12, 55, tzinfo=datetime.timezone.utc) # Not a date diff --git a/airbyte-integrations/connectors/source-xero/unit_tests/test_source.py b/airbyte-integrations/connectors/source-xero/unit_tests/test_source.py index ee4687b936ef..3765b99482f8 100644 --- a/airbyte-integrations/connectors/source-xero/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-xero/unit_tests/test_source.py @@ -22,6 +22,7 @@ def test_check_connection_failed(bad_config, requests_mock): assert check_succeeded is False assert error == "" or "none" in error.lower() + def test_streams_count(config_pass): source = SourceXero() streams = source.streams(config_pass) diff --git a/airbyte-integrations/connectors/source-xero/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-xero/unit_tests/test_streams.py index a0bdf0e11610..6dffe0aeb3d2 100644 --- a/airbyte-integrations/connectors/source-xero/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-xero/unit_tests/test_streams.py @@ -4,13 +4,16 @@ import datetime -from airbyte_cdk.models import SyncMode from conftest import get_stream_by_name from source_xero.components import ParseDates +from airbyte_cdk.models import SyncMode + def test_parsed_result(requests_mock, config_pass, mock_bank_transaction_response): - requests_mock.get(url="https://api.xero.com/api.xro/2.0/BankTransactions", status_code=200, json=mock_bank_transaction_response["BankTransactions"]) + requests_mock.get( + url="https://api.xero.com/api.xro/2.0/BankTransactions", status_code=200, json=mock_bank_transaction_response["BankTransactions"] + ) stream = get_stream_by_name("bank_transactions", config_pass) expected_record = mock_bank_transaction_response["BankTransactions"] for stream_slice in stream.stream_slices(sync_mode=SyncMode.full_refresh): @@ -26,8 +29,8 @@ def test_request_params(config_pass): def test_request_headers(config_pass): bank_transactions = get_stream_by_name("bank_transactions", config_pass) - expected_headers = {'Xero-Tenant-Id': 'goodone', 'Accept': 'application/json'} - assert bank_transactions.retriever.requester.get_request_headers() == expected_headers + expected_headers = {"Xero-Tenant-Id": "goodone", "Accept": "application/json"} + assert bank_transactions.retriever.requester.get_request_headers() == expected_headers def test_http_method(config_pass): @@ -38,7 +41,7 @@ def test_http_method(config_pass): def test_ignore_forbidden(requests_mock, config_pass): - requests_mock.get(url="https://api.xero.com/api.xro/2.0/BankTransactions", status_code=403, json=[{ "message": "Forbidden resource"}]) + requests_mock.get(url="https://api.xero.com/api.xro/2.0/BankTransactions", status_code=403, json=[{"message": "Forbidden resource"}]) stream = get_stream_by_name("bank_transactions", config_pass) records = [] @@ -52,7 +55,9 @@ def test_parse_date(): # 11/10/2020 00:00:00 +3 (11/10/2020 21:00:00 GMT/UTC) assert ParseDates.parse_date("/Date(1602363600000+0300)/") == datetime.datetime(2020, 10, 11, 0, 0, tzinfo=datetime.timezone.utc) # 02/02/2020 10:31:51.5 +3 (02/02/2020 07:31:51.5 GMT/UTC) - assert ParseDates.parse_date("/Date(1580628711500+0300)/") == datetime.datetime(2020, 2, 2, 10, 31, 51, 500000, tzinfo=datetime.timezone.utc) + assert ParseDates.parse_date("/Date(1580628711500+0300)/") == datetime.datetime( + 2020, 2, 2, 10, 31, 51, 500000, tzinfo=datetime.timezone.utc + ) # 07/02/2022 20:12:55 GMT/UTC assert ParseDates.parse_date("/Date(1656792775000)/") == datetime.datetime(2022, 7, 2, 20, 12, 55, tzinfo=datetime.timezone.utc) # Not a date diff --git a/airbyte-integrations/connectors/source-xsolla/metadata.yaml b/airbyte-integrations/connectors/source-xsolla/metadata.yaml index ca88d21af590..1a183bf301cf 100644 --- a/airbyte-integrations/connectors/source-xsolla/metadata.yaml +++ b/airbyte-integrations/connectors/source-xsolla/metadata.yaml @@ -13,10 +13,10 @@ data: enabled: false packageName: airbyte-source-xsolla connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorType: source definitionId: 6ff73a16-05a8-4f7e-8771-5433764678f1 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-xsolla githubIssueLabel: source-xsolla icon: icon.svg diff --git a/airbyte-integrations/connectors/source-yahoo-finance-price/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-yahoo-finance-price/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-yahoo-finance-price/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-yahoo-finance-price/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-yahoo-finance-price/metadata.yaml b/airbyte-integrations/connectors/source-yahoo-finance-price/metadata.yaml index cf6ad2c3e668..7d4bb6284f7f 100644 --- a/airbyte-integrations/connectors/source-yahoo-finance-price/metadata.yaml +++ b/airbyte-integrations/connectors/source-yahoo-finance-price/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 09a517d3-803f-448d-97bf-0b1ee64b90ef - dockerImageTag: 0.3.2 + dockerImageTag: 0.3.6 dockerRepository: airbyte/source-yahoo-finance-price documentationUrl: https://docs.airbyte.com/integrations/sources/yahoo-finance-price githubIssueLabel: source-yahoo-finance-price diff --git a/airbyte-integrations/connectors/source-yandex-metrica/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-yandex-metrica/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-yandex-metrica/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-yandex-metrica/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-yandex-metrica/main.py b/airbyte-integrations/connectors/source-yandex-metrica/main.py index a84b23e0a261..ad216843240a 100644 --- a/airbyte-integrations/connectors/source-yandex-metrica/main.py +++ b/airbyte-integrations/connectors/source-yandex-metrica/main.py @@ -4,5 +4,6 @@ from source_yandex_metrica.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-yandex-metrica/metadata.yaml b/airbyte-integrations/connectors/source-yandex-metrica/metadata.yaml index 068c2f43ee15..b6138588eaff 100644 --- a/airbyte-integrations/connectors/source-yandex-metrica/metadata.yaml +++ b/airbyte-integrations/connectors/source-yandex-metrica/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - api-metrica.yandex.net connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: 7865dce4-2211-4f6a-88e5-9d0fe161afe7 - dockerImageTag: 1.0.22 + dockerImageTag: 1.0.27 dockerRepository: airbyte/source-yandex-metrica documentationUrl: https://docs.airbyte.com/integrations/sources/yandex-metrica githubIssueLabel: source-yandex-metrica diff --git a/airbyte-integrations/connectors/source-yandex-metrica/poetry.lock b/airbyte-integrations/connectors/source-yandex-metrica/poetry.lock index 4305e40b0b10..5a3986829f37 100644 --- a/airbyte-integrations/connectors/source-yandex-metrica/poetry.lock +++ b/airbyte-integrations/connectors/source-yandex-metrica/poetry.lock @@ -62,19 +62,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -140,127 +140,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -276,20 +263,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -381,13 +368,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -500,13 +487,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -587,54 +574,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -898,33 +885,33 @@ fixture = ["fixtures"] [[package]] name = "setuptools" -version = "75.2.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -965,13 +952,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -996,81 +983,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-yandex-metrica/pyproject.toml b/airbyte-integrations/connectors/source-yandex-metrica/pyproject.toml index 27b7d6573238..d83ba854bedc 100644 --- a/airbyte-integrations/connectors/source-yandex-metrica/pyproject.toml +++ b/airbyte-integrations/connectors/source-yandex-metrica/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "1.0.22" +version = "1.0.27" name = "source-yandex-metrica" description = "Source implementation for Yandex Metrica." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-yandex-metrica/source_yandex_metrica/source.py b/airbyte-integrations/connectors/source-yandex-metrica/source_yandex_metrica/source.py index 874910073f0e..e917e2fa28ed 100644 --- a/airbyte-integrations/connectors/source-yandex-metrica/source_yandex_metrica/source.py +++ b/airbyte-integrations/connectors/source-yandex-metrica/source_yandex_metrica/source.py @@ -6,11 +6,13 @@ from typing import Any, List, Mapping, Optional, Tuple import pendulum + from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams.http.auth import TokenAuthenticator from .streams import Sessions, Views, YandexMetricaStream + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-yandex-metrica/source_yandex_metrica/streams.py b/airbyte-integrations/connectors/source-yandex-metrica/source_yandex_metrica/streams.py index 957030f23f9d..65592bdb7154 100644 --- a/airbyte-integrations/connectors/source-yandex-metrica/source_yandex_metrica/streams.py +++ b/airbyte-integrations/connectors/source-yandex-metrica/source_yandex_metrica/streams.py @@ -12,11 +12,13 @@ import pendulum import requests +from pendulum import DateTime + from airbyte_cdk.models import SyncMode from airbyte_cdk.sources import Source from airbyte_cdk.sources.streams.core import IncrementalMixin, StreamData from airbyte_cdk.sources.streams.http import HttpStream -from pendulum import DateTime + logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-yandex-metrica/unit_tests/test_source.py b/airbyte-integrations/connectors/source-yandex-metrica/unit_tests/test_source.py index 3993932b1c69..bf5adface5a2 100644 --- a/airbyte-integrations/connectors/source-yandex-metrica/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-yandex-metrica/unit_tests/test_source.py @@ -8,6 +8,7 @@ import pytest from source_yandex_metrica.source import SourceYandexMetrica + logger = logging.getLogger("test_source") diff --git a/airbyte-integrations/connectors/source-yandex-metrica/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-yandex-metrica/unit_tests/test_streams.py index afd233b11790..cec63d87d2d2 100644 --- a/airbyte-integrations/connectors/source-yandex-metrica/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-yandex-metrica/unit_tests/test_streams.py @@ -3,9 +3,11 @@ # -from airbyte_cdk.models import SyncMode from source_yandex_metrica.streams import Sessions +from airbyte_cdk.models import SyncMode + + EXPECTED_RECORDS = [ {"watchID": "00000000", "dateTime": "2022-09-01T12:00:00+00:00"}, {"watchID": "00000001", "dateTime": "2022-08-01T12:00:10+00:00"}, diff --git a/airbyte-integrations/connectors/source-yotpo/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-yotpo/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-yotpo/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-yotpo/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-you-need-a-budget-ynab/metadata.yaml b/airbyte-integrations/connectors/source-you-need-a-budget-ynab/metadata.yaml index 1e698debcbb9..a7ed0f91953f 100644 --- a/airbyte-integrations/connectors/source-you-need-a-budget-ynab/metadata.yaml +++ b/airbyte-integrations/connectors/source-you-need-a-budget-ynab/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-you-need-a-budget-ynab connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: a60d9f16-e0bd-459f-9419-fd47f9788be1 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.7 dockerRepository: airbyte/source-you-need-a-budget-ynab githubIssueLabel: source-you-need-a-budget-ynab icon: icon.svg diff --git a/airbyte-integrations/connectors/source-younium/components.py b/airbyte-integrations/connectors/source-younium/components.py index 7b9bcaa42a5f..f202ba2a73ec 100644 --- a/airbyte-integrations/connectors/source-younium/components.py +++ b/airbyte-integrations/connectors/source-younium/components.py @@ -7,10 +7,12 @@ from typing import Any, Mapping, Union import requests +from requests import HTTPError + from airbyte_cdk.sources.declarative.auth.declarative_authenticator import NoAuth from airbyte_cdk.sources.declarative.interpolation import InterpolatedString from airbyte_cdk.sources.declarative.types import Config -from requests import HTTPError + # https://developers.zoom.us/docs/internal-apps/s2s-oauth/#successful-response # The Bearer token generated by server-to-server token will expire in one hour diff --git a/airbyte-integrations/connectors/source-younium/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-younium/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-younium/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-younium/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-younium/metadata.yaml b/airbyte-integrations/connectors/source-younium/metadata.yaml index ff7c34bbb57e..2ab39eb54b79 100644 --- a/airbyte-integrations/connectors/source-younium/metadata.yaml +++ b/airbyte-integrations/connectors/source-younium/metadata.yaml @@ -12,11 +12,11 @@ data: # Please update to the latest version of the connector base image. # https://hub.docker.com/r/airbyte/python-connector-base # Please use the full address with sha256 hash to guarantee build reproducibility. - baseImage: docker.io/airbyte/source-declarative-manifest:5.15.0@sha256:09a84e0622f36393077332faf11cc239e77083fae5fa500592c049dca25888a7 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 9c74c2d7-531a-4ebf-b6d8-6181f805ecdc - dockerImageTag: 0.4.0 + dockerImageTag: 0.4.3 dockerRepository: airbyte/source-younium githubIssueLabel: source-younium icon: younium.svg diff --git a/airbyte-integrations/connectors/source-youtube-analytics/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-youtube-analytics/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-youtube-analytics/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-youtube-analytics/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-youtube-analytics/main.py b/airbyte-integrations/connectors/source-youtube-analytics/main.py index f2542cccc965..959f6b271454 100644 --- a/airbyte-integrations/connectors/source-youtube-analytics/main.py +++ b/airbyte-integrations/connectors/source-youtube-analytics/main.py @@ -4,5 +4,6 @@ from source_youtube_analytics.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-youtube-analytics/source_youtube_analytics/source.py b/airbyte-integrations/connectors/source-youtube-analytics/source_youtube_analytics/source.py index 4a9041f1f078..cd6af9e03d9b 100644 --- a/airbyte-integrations/connectors/source-youtube-analytics/source_youtube_analytics/source.py +++ b/airbyte-integrations/connectors/source-youtube-analytics/source_youtube_analytics/source.py @@ -12,6 +12,7 @@ import pendulum import requests + from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http import HttpStream, HttpSubStream diff --git a/airbyte-integrations/connectors/source-youtube-analytics/unit_tests/test_source.py b/airbyte-integrations/connectors/source-youtube-analytics/unit_tests/test_source.py index dcac2eb7e98a..9744592d3ba5 100644 --- a/airbyte-integrations/connectors/source-youtube-analytics/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-youtube-analytics/unit_tests/test_source.py @@ -6,9 +6,10 @@ import os from unittest.mock import MagicMock -from airbyte_cdk.sources.streams.http.auth.core import NoAuth from source_youtube_analytics.source import SourceYoutubeAnalytics +from airbyte_cdk.sources.streams.http.auth.core import NoAuth + def test_check_connection(requests_mock): access_token = "token" diff --git a/airbyte-integrations/connectors/source-youtube-data/README.md b/airbyte-integrations/connectors/source-youtube-data/README.md new file mode 100644 index 000000000000..c8252c1d6de1 --- /dev/null +++ b/airbyte-integrations/connectors/source-youtube-data/README.md @@ -0,0 +1,33 @@ +# Youtube Data +This directory contains the manifest-only connector for `source-youtube-data`. + +Youtube Data + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-youtube-data:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-youtube-data build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-youtube-data test +``` + diff --git a/airbyte-integrations/connectors/source-youtube-data/acceptance-test-config.yml b/airbyte-integrations/connectors/source-youtube-data/acceptance-test-config.yml new file mode 100644 index 000000000000..bfa5088005af --- /dev/null +++ b/airbyte-integrations/connectors/source-youtube-data/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-youtube-data:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-youtube-data/icon.svg b/airbyte-integrations/connectors/source-youtube-data/icon.svg new file mode 100644 index 000000000000..b279efdfe70a --- /dev/null +++ b/airbyte-integrations/connectors/source-youtube-data/icon.svg @@ -0,0 +1,11 @@ + + + + + + + diff --git a/airbyte-integrations/connectors/source-youtube-data/manifest.yaml b/airbyte-integrations/connectors/source-youtube-data/manifest.yaml new file mode 100644 index 000000000000..20ee9bcf2de9 --- /dev/null +++ b/airbyte-integrations/connectors/source-youtube-data/manifest.yaml @@ -0,0 +1,856 @@ +version: 6.4.0 + +type: DeclarativeSource + +description: >- + The YouTube Data API v3 is an API that provides access to YouTube data, such as videos, playlists, channels, comments and simple stats. + This is a simpler version of Youtube connector, if you need more detailed reports from your channel please check + the [Youtube Analytics Connector](https://docs.airbyte.com/integrations/sources/youtube-analytics) + +check: + type: CheckStream + stream_names: + - video + +definitions: + streams: + video: + type: DeclarativeStream + name: video + primary_key: + - videoId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: videos + http_method: GET + request_parameters: + part: snippet,contentDetails,statistics + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + - "*" + - snippet + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('nextPageToken', '') }}" + stop_condition: "{{ response.get('nextPageToken') is none }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: videoId + request_option: + type: RequestOption + inject_into: request_parameter + field_name: id + partition_field: id + stream: + $ref: "#/definitions/streams/videos" + transformations: + - type: AddFields + fields: + - path: + - datetime + value: "{{ now_utc() }}" + - type: AddFields + fields: + - path: + - videoId + value: "{{ stream_slice.id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/video" + channels: + type: DeclarativeStream + name: channels + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: channels + http_method: GET + request_parameters: + part: snippet,contentDetails,statistics + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + - "*" + - snippet + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('nextPageToken', '') }}" + stop_condition: "{{ response.get('nextPageToken') is none }}" + partition_router: + type: ListPartitionRouter + values: "{{ config.channel_ids }}" + cursor_field: channel_id + request_option: + type: RequestOption + inject_into: request_parameter + field_name: id + transformations: + - type: AddFields + fields: + - path: + - id + value: "{{ stream_partition.channel_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/channels" + comments: + type: DeclarativeStream + name: comments + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: commentThreads + http_method: GET + request_parameters: + part: snippet,replies + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + - "*" + - snippet + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('nextPageToken', '') }}" + stop_condition: "{{ response.get('nextPageToken') is none }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: videoId + request_option: + type: RequestOption + inject_into: request_parameter + field_name: videoId + partition_field: id + stream: + $ref: "#/definitions/streams/videos" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/comments" + videos: + type: DeclarativeStream + name: videos + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: search + http_method: GET + request_parameters: + channelId: "{{ config.channel_ids }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + - "*" + - id + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: maxResults + pagination_strategy: + type: CursorPagination + page_size: 50 + cursor_value: "{{ response.nextPageToken }}" + stop_condition: "{{ not response.get('nextPageToken') }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/videos" + channel_comments: + type: DeclarativeStream + name: channel_comments + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: commentThreads + http_method: GET + request_parameters: + part: snippet,replies + allThreadsRelatedToChannelId: "{{ config.channel_ids }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + - "*" + - snippet + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: pageToken + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('nextPageToken', '') }}" + stop_condition: "{{ response.get('nextPageToken') is none }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/channel_comments" + base_requester: + type: HttpRequester + url_base: https://www.googleapis.com/youtube/v3/ + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"api_key\"] }}" + inject_into: + type: RequestOption + field_name: key + inject_into: request_parameter + +streams: + - $ref: "#/definitions/streams/video" + - $ref: "#/definitions/streams/channels" + - $ref: "#/definitions/streams/comments" + - $ref: "#/definitions/streams/videos" + - $ref: "#/definitions/streams/channel_comments" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - api_key + - channel_ids + properties: + api_key: + type: string + order: 0 + title: API Key + airbyte_secret: true + channel_ids: + type: array + order: 1 + title: Channel IDs + additionalProperties: true + +metadata: + autoImportSchema: + video: true + channels: false + comments: true + videos: true + channel_comments: true + testedStreams: + video: + streamHash: a3f8831f5f8a0ca3efed0972cab191cc181d2b4e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + channels: + streamHash: 343ca32364dc855bd2f38aa2eb633c05100b5fd1 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + comments: + streamHash: 8d2176a881a0bca19e00ec1d0cfe70a823e4de85 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + videos: + streamHash: 9f29c51ff5dbe597fbbd7ebfab42300eb29860f8 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + channel_comments: + streamHash: 958a9f915e04312572380361e2b97c730c37ad29 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://developers.google.com/youtube/v3/guides/implementation + +schemas: + video: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + categoryId: + type: + - string + - "null" + channelId: + type: + - string + - "null" + channelTitle: + type: + - string + - "null" + datetime: + type: + - string + - "null" + defaultAudioLanguage: + type: + - string + - "null" + defaultLanguage: + type: + - string + - "null" + liveBroadcastContent: + type: + - string + - "null" + localized: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + title: + type: + - string + - "null" + publishedAt: + type: + - string + - "null" + tags: + type: + - array + - "null" + items: + type: + - string + - "null" + thumbnails: + type: + - object + - "null" + properties: + default: + type: + - object + - "null" + properties: + height: + type: + - number + - "null" + url: + type: + - string + - "null" + width: + type: + - number + - "null" + high: + type: + - object + - "null" + properties: + height: + type: + - number + - "null" + url: + type: + - string + - "null" + width: + type: + - number + - "null" + maxres: + type: + - object + - "null" + properties: + height: + type: + - number + - "null" + url: + type: + - string + - "null" + width: + type: + - number + - "null" + medium: + type: + - object + - "null" + properties: + height: + type: + - number + - "null" + url: + type: + - string + - "null" + width: + type: + - number + - "null" + standard: + type: + - object + - "null" + properties: + height: + type: + - number + - "null" + url: + type: + - string + - "null" + width: + type: + - number + - "null" + title: + type: + - string + - "null" + videoId: + type: string + required: + - videoId + channels: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + contentDetails: + type: + - object + - "null" + properties: + relatedPlaylists: + type: + - object + - "null" + properties: + likes: + type: + - string + - "null" + uploads: + type: + - string + - "null" + etag: + type: + - string + - "null" + id: + type: string + kind: + type: + - string + - "null" + snippet: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + country: + type: + - string + - "null" + customUrl: + type: + - string + - "null" + localized: + type: + - object + - "null" + properties: + description: + type: + - string + - "null" + title: + type: + - string + - "null" + publishedAt: + type: + - string + - "null" + thumbnails: + type: + - object + - "null" + properties: + default: + type: + - object + - "null" + properties: + height: + type: + - number + - "null" + url: + type: + - string + - "null" + width: + type: + - number + - "null" + high: + type: + - object + - "null" + properties: + height: + type: + - number + - "null" + url: + type: + - string + - "null" + width: + type: + - number + - "null" + medium: + type: + - object + - "null" + properties: + height: + type: + - number + - "null" + url: + type: + - string + - "null" + width: + type: + - number + - "null" + title: + type: + - string + - "null" + statistics: + type: + - object + - "null" + properties: + hiddenSubscriberCount: + type: + - boolean + - "null" + subscriberCount: + type: + - string + - "null" + videoCount: + type: + - string + - "null" + viewCount: + type: + - string + - "null" + required: + - id + comments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + canReply: + type: + - boolean + - "null" + channelId: + type: + - string + - "null" + isPublic: + type: + - boolean + - "null" + topLevelComment: + type: + - object + - "null" + properties: + etag: + type: + - string + - "null" + id: + type: + - string + - "null" + kind: + type: + - string + - "null" + snippet: + type: + - object + - "null" + properties: + authorChannelId: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + authorChannelUrl: + type: + - string + - "null" + authorDisplayName: + type: + - string + - "null" + authorProfileImageUrl: + type: + - string + - "null" + canRate: + type: + - boolean + - "null" + channelId: + type: + - string + - "null" + likeCount: + type: + - number + - "null" + publishedAt: + type: + - string + - "null" + textDisplay: + type: + - string + - "null" + textOriginal: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + videoId: + type: + - string + - "null" + viewerRating: + type: + - string + - "null" + totalReplyCount: + type: + - number + - "null" + videoId: + type: + - string + - "null" + videos: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + kind: + type: + - string + - "null" + videoId: + type: + - string + - "null" + channel_comments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + canReply: + type: + - boolean + - "null" + channelId: + type: + - string + - "null" + isPublic: + type: + - boolean + - "null" + topLevelComment: + type: + - object + - "null" + properties: + etag: + type: + - string + - "null" + id: + type: + - string + - "null" + kind: + type: + - string + - "null" + snippet: + type: + - object + - "null" + properties: + authorChannelId: + type: + - object + - "null" + properties: + value: + type: + - string + - "null" + authorChannelUrl: + type: + - string + - "null" + authorDisplayName: + type: + - string + - "null" + authorProfileImageUrl: + type: + - string + - "null" + canRate: + type: + - boolean + - "null" + channelId: + type: + - string + - "null" + likeCount: + type: + - number + - "null" + publishedAt: + type: + - string + - "null" + textDisplay: + type: + - string + - "null" + textOriginal: + type: + - string + - "null" + updatedAt: + type: + - string + - "null" + videoId: + type: + - string + - "null" + viewerRating: + type: + - string + - "null" + totalReplyCount: + type: + - number + - "null" + videoId: + type: + - string + - "null" diff --git a/airbyte-integrations/connectors/source-youtube-data/metadata.yaml b/airbyte-integrations/connectors/source-youtube-data/metadata.yaml new file mode 100644 index 000000000000..ba25194932c8 --- /dev/null +++ b/airbyte-integrations/connectors/source-youtube-data/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "googleapis.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-youtube-data + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 743a2a44-fd13-4109-a8fe-fb0e68f467f5 + dockerImageTag: 0.0.6 + dockerRepository: airbyte/source-youtube-data + githubIssueLabel: source-youtube-data + icon: icon.svg + license: MIT + name: Youtube Data + releaseDate: 2024-11-08 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/youtube-data + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-zapier-supported-storage/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-zapier-supported-storage/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-zapier-supported-storage/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-zapier-supported-storage/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-zapier-supported-storage/metadata.yaml b/airbyte-integrations/connectors/source-zapier-supported-storage/metadata.yaml index c364bfef73d8..b40d100d8f5e 100644 --- a/airbyte-integrations/connectors/source-zapier-supported-storage/metadata.yaml +++ b/airbyte-integrations/connectors/source-zapier-supported-storage/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 100 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: b8c917bc-7d1b-4828-995f-6726820266d0 - dockerImageTag: 0.2.3 + dockerImageTag: 0.2.7 dockerRepository: airbyte/source-zapier-supported-storage documentationUrl: https://docs.airbyte.com/integrations/sources/zapier-supported-storage githubIssueLabel: source-zapier-supported-storage diff --git a/airbyte-integrations/connectors/source-zendesk-chat/build_customization.py b/airbyte-integrations/connectors/source-zendesk-chat/build_customization.py index 13626e17bbbc..bbcb318d24a8 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/build_customization.py +++ b/airbyte-integrations/connectors/source-zendesk-chat/build_customization.py @@ -5,6 +5,7 @@ from typing import TYPE_CHECKING + if TYPE_CHECKING: from dagger import Container diff --git a/airbyte-integrations/connectors/source-zendesk-chat/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-zendesk-chat/integration_tests/acceptance.py index 43ce950d77ca..72132012aaed 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-zendesk-chat/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-zendesk-chat/main.py b/airbyte-integrations/connectors/source-zendesk-chat/main.py index c2c8d74d092a..4548150f4115 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/main.py +++ b/airbyte-integrations/connectors/source-zendesk-chat/main.py @@ -4,5 +4,6 @@ from source_zendesk_chat.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-zendesk-chat/metadata.yaml b/airbyte-integrations/connectors/source-zendesk-chat/metadata.yaml index da1ec249e31b..20a0fff21aaf 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/metadata.yaml +++ b/airbyte-integrations/connectors/source-zendesk-chat/metadata.yaml @@ -4,13 +4,13 @@ data: sl: 200 allowedHosts: hosts: - - zopim.com + - "*.zendesk.com" connectorBuildOptions: baseImage: docker.io/airbyte/python-connector-base:1.2.2@sha256:57703de3b4c4204bd68a7b13c9300f8e03c0189bffddaffc796f1da25d2dbea0 connectorSubtype: api connectorType: source definitionId: 40d24d0f-b8f9-4fe0-9e6c-b06c0f3f45e4 - dockerImageTag: 0.3.1 + dockerImageTag: 1.0.0 dockerRepository: airbyte/source-zendesk-chat documentationUrl: https://docs.airbyte.com/integrations/sources/zendesk-chat githubIssueLabel: source-zendesk-chat @@ -28,6 +28,11 @@ data: oss: enabled: true releaseStage: generally_available + releases: + breakingChanges: + 1.0.0: + message: "The subdomain configuration field is now required following a Live Chat API update." + upgradeDeadline: "2024-11-12" supportLevel: certified tags: - language:python diff --git a/airbyte-integrations/connectors/source-zendesk-chat/pyproject.toml b/airbyte-integrations/connectors/source-zendesk-chat/pyproject.toml index 7f13a34bfe31..133b224eedda 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/pyproject.toml +++ b/airbyte-integrations/connectors/source-zendesk-chat/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.3.1" +version = "1.0.0" name = "source-zendesk-chat" description = "Source implementation for Zendesk Chat." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/components/bans_record_extractor.py b/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/components/bans_record_extractor.py index 2dffe978edfb..28e6de3dd4fc 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/components/bans_record_extractor.py +++ b/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/components/bans_record_extractor.py @@ -8,6 +8,7 @@ import pendulum import requests + from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor from airbyte_cdk.sources.declarative.types import Record diff --git a/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/components/id_offset_pagination.py b/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/components/id_offset_pagination.py index 9c3eb3109f52..cce977551ac7 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/components/id_offset_pagination.py +++ b/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/components/id_offset_pagination.py @@ -6,6 +6,7 @@ from typing import Any, List, Mapping, Optional, Union import requests + from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString from airbyte_cdk.sources.declarative.requesters.paginators.strategies import OffsetIncrement diff --git a/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/components/time_offset_pagination.py b/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/components/time_offset_pagination.py index 284325c12e3b..6cbdc2694790 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/components/time_offset_pagination.py +++ b/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/components/time_offset_pagination.py @@ -6,6 +6,7 @@ from typing import Any, List, Mapping, Optional, Union import requests + from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString from airbyte_cdk.sources.declarative.requesters.paginators.strategies import OffsetIncrement diff --git a/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/manifest.yaml b/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/manifest.yaml index 5a5ff833c1e7..376591e01d96 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/manifest.yaml +++ b/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/manifest.yaml @@ -68,7 +68,7 @@ definitions: description: >- Default Base Requester for Full Refresh streams type: HttpRequester - url_base: https://www.zopim.com/api/v2/ + url_base: "https://{{ config['subdomain'] }}.zendesk.com/api/v2/chat/" path: "{{ parameters['path'] }}" http_method: GET authenticator: diff --git a/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/source.py b/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/source.py index 2b0540f7cd8f..bbaafa375146 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/source.py +++ b/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/spec.json b/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/spec.json index 9fd0bba8d7a8..61150ec15c33 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/spec.json +++ b/airbyte-integrations/connectors/source-zendesk-chat/source_zendesk_chat/spec.json @@ -4,7 +4,7 @@ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Zendesk Chat Spec", "type": "object", - "required": ["start_date"], + "required": ["subdomain", "start_date"], "additionalProperties": true, "properties": { "start_date": { @@ -18,7 +18,9 @@ "subdomain": { "type": "string", "title": "Subdomain", - "description": "Required if you access Zendesk Chat from a Zendesk Support subdomain.", + "description": "The unique subdomain of your Zendesk account (without https://). See the Zendesk docs to find your subdomain", + "pattern": "^(?!https://)", + "examples": ["myzendeskchat"], "default": "" }, "credentials": { diff --git a/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/conftest.py b/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/conftest.py index c48196cfa1ed..8083a1cc5e0d 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/conftest.py +++ b/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/conftest.py @@ -12,25 +12,14 @@ def config() -> Mapping[str, Any]: return { "start_date": "2020-10-01T00:00:00Z", "subdomain": "", - "credentials": { - "credentials": "access_token", - "access_token": "__access_token__" - } + "credentials": {"credentials": "access_token", "access_token": "__access_token__"}, } @pytest.fixture def bans_stream_record() -> Mapping[str, Any]: return { - "ip_address": [ - { - "reason": "test", - "type": "ip_address", - "id": 1234, - "created_at": "2021-04-21T14:42:46Z", - "ip_address": "0.0.0.0" - } - ], + "ip_address": [{"reason": "test", "type": "ip_address", "id": 1234, "created_at": "2021-04-21T14:42:46Z", "ip_address": "0.0.0.0"}], "visitor": [ { "type": "visitor", @@ -38,28 +27,22 @@ def bans_stream_record() -> Mapping[str, Any]: "visitor_name": "Visitor 4444", "visitor_id": "visitor_id", "reason": "test", - "created_at": "2021-04-27T13:25:01Z" + "created_at": "2021-04-27T13:25:01Z", } - ] + ], } @pytest.fixture def bans_stream_record_extractor_expected_output() -> List[Mapping[str, Any]]: return [ - { - "reason": "test", - "type": "ip_address", - "id": 1234, - "created_at": "2021-04-21T14:42:46Z", - "ip_address": "0.0.0.0" - }, + {"reason": "test", "type": "ip_address", "id": 1234, "created_at": "2021-04-21T14:42:46Z", "ip_address": "0.0.0.0"}, { "type": "visitor", "id": 4444, "visitor_name": "Visitor 4444", "visitor_id": "visitor_id", "reason": "test", - "created_at": "2021-04-27T13:25:01Z" + "created_at": "2021-04-27T13:25:01Z", }, ] diff --git a/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_bans_record_extractor.py b/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_bans_record_extractor.py index 446bcc8f63de..d33b2302e161 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_bans_record_extractor.py +++ b/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_bans_record_extractor.py @@ -7,11 +7,12 @@ def test_bans_stream_record_extractor( - requests_mock, - bans_stream_record, + config, + requests_mock, + bans_stream_record, bans_stream_record_extractor_expected_output, ) -> None: - test_url = "https://www.zopim.com/api/v2/bans" + test_url = f"https://{config['subdomain']}.zendesk.com/api/v2/chat/bans" requests_mock.get(test_url, json=bans_stream_record) test_response = requests.get(test_url) assert ZendeskChatBansRecordExtractor().extract_records(test_response) == bans_stream_record_extractor_expected_output diff --git a/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_id_incremental_cursor.py b/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_id_incremental_cursor.py index 9557a312b635..75dad4a8f0d5 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_id_incremental_cursor.py +++ b/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_id_incremental_cursor.py @@ -9,26 +9,24 @@ def _get_cursor(config) -> ZendeskChatIdIncrementalCursor: return ZendeskChatIdIncrementalCursor( - config = config, - cursor_field = "id", - field_name = "since_id", - parameters = {}, + config=config, + cursor_field="id", + field_name="since_id", + parameters={}, ) @pytest.mark.parametrize( "stream_state, expected_cursor_value, expected_state_value", [ - ({"id": 10}, 10, {'id': 10}), + ({"id": 10}, 10, {"id": 10}), ], - ids=[ - "SET Initial State and GET State" - ] + ids=["SET Initial State and GET State"], ) def test_id_incremental_cursor_set_initial_state_and_get_stream_state( - config, + config, stream_state, - expected_cursor_value, + expected_cursor_value, expected_state_value, ) -> None: cursor = _get_cursor(config) @@ -44,17 +42,14 @@ def test_id_incremental_cursor_set_initial_state_and_get_stream_state( ({"id": 123}, 123), ({"id": 456}, 456), ], - ids=[ - "first", - "second" - ] + ids=["first", "second"], ) def test_id_incremental_cursor_close_slice(config, test_record, expected) -> None: cursor = _get_cursor(config) cursor.observe(stream_slice={}, record=test_record) cursor.close_slice(stream_slice={}) assert cursor._cursor == expected - + @pytest.mark.parametrize( "stream_state, input_slice, expected", @@ -62,17 +57,14 @@ def test_id_incremental_cursor_close_slice(config, test_record, expected) -> Non ({}, {"id": 1}, {}), ({"id": 2}, {"id": 1}, {"since_id": 2}), ], - ids=[ - "No State", - "With State" - ] + ids=["No State", "With State"], ) def test_id_incremental_cursor_get_request_params(config, stream_state, input_slice, expected) -> None: cursor = _get_cursor(config) if stream_state: cursor.set_initial_state(stream_state) assert cursor.get_request_params(stream_slice=input_slice) == expected - + @pytest.mark.parametrize( "stream_state, record, expected", @@ -85,7 +77,7 @@ def test_id_incremental_cursor_get_request_params(config, stream_state, input_sl "No State", "With State > Record value", "With State < Record value", - ] + ], ) def test_id_incremental_cursor_should_be_synced(config, stream_state, record, expected) -> None: cursor = _get_cursor(config) @@ -107,7 +99,7 @@ def test_id_incremental_cursor_should_be_synced(config, stream_state, record, ex "First < Second - should not be synced", "Has First but no Second - should be synced", "Has no First and has no Second - should not be synced", - ] + ], ) def test_id_incremental_cursor_is_greater_than_or_equal(config, first_record, second_record, expected) -> None: cursor = _get_cursor(config) diff --git a/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_id_offset_pagination.py b/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_id_offset_pagination.py index 5c5f4dd46b1a..48f06329adbd 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_id_offset_pagination.py +++ b/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_id_offset_pagination.py @@ -10,23 +10,20 @@ def _get_paginator(config, id_field) -> ZendeskChatIdOffsetIncrementPaginationStrategy: return ZendeskChatIdOffsetIncrementPaginationStrategy( - config = config, - page_size = 1, - id_field = id_field, - parameters = {}, + config=config, + page_size=1, + id_field=id_field, + parameters={}, ) @pytest.mark.parametrize( "id_field, last_records, expected", - [ - ("id", [{"id": 1}], 2), - ("id", [], None) - ], + [("id", [{"id": 1}], 2), ("id", [], None)], ) def test_id_offset_increment_pagination_next_page_token(requests_mock, config, id_field, last_records, expected) -> None: paginator = _get_paginator(config, id_field) - test_url = "https://www.zopim.com/api/v2/agents" + test_url = f"https://{config['subdomain']}.zendesk.com/api/v2/chat/agents" requests_mock.get(test_url, json=last_records) test_response = requests.get(test_url) assert paginator.next_page_token(test_response, last_records) == expected diff --git a/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_time_offset_pagination.py b/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_time_offset_pagination.py index 086ea195fac2..10838351b5c5 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_time_offset_pagination.py +++ b/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_time_offset_pagination.py @@ -10,23 +10,23 @@ def _get_paginator(config, time_field_name) -> ZendeskChatTimeOffsetIncrementPaginationStrategy: return ZendeskChatTimeOffsetIncrementPaginationStrategy( - config = config, - page_size = 1, - time_field_name = time_field_name, - parameters = {}, + config=config, + page_size=1, + time_field_name=time_field_name, + parameters={}, ) @pytest.mark.parametrize( "time_field_name, response, last_records, expected", [ - ("end_time", {"chats":[{"update_timestamp": 1}], "end_time": 2}, [{"update_timestamp": 1}], 2), - ("end_time", {"chats":[], "end_time": 3}, [], None), + ("end_time", {"chats": [{"update_timestamp": 1}], "end_time": 2}, [{"update_timestamp": 1}], 2), + ("end_time", {"chats": [], "end_time": 3}, [], None), ], ) def test_time_offset_increment_pagination_next_page_token(requests_mock, config, time_field_name, response, last_records, expected) -> None: paginator = _get_paginator(config, time_field_name) - test_url = "https://www.zopim.com/api/v2/chats" + test_url = f"https://{config['subdomain']}.zendesk.com/api/v2/chat/chats" requests_mock.get(test_url, json=response) test_response = requests.get(test_url) assert paginator.next_page_token(test_response, last_records) == expected diff --git a/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_timestamp_based_cursor.py b/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_timestamp_based_cursor.py index a98cc8283e93..2528f7a5db7e 100644 --- a/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_timestamp_based_cursor.py +++ b/airbyte-integrations/connectors/source-zendesk-chat/unit_tests/components/test_timestamp_based_cursor.py @@ -4,23 +4,24 @@ import pytest -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType from source_zendesk_chat.components.timestamp_based_cursor import ZendeskChatTimestampCursor +from airbyte_cdk.sources.declarative.requesters.request_option import RequestOption, RequestOptionType + def _get_cursor(config, cursor_field, use_microseconds) -> ZendeskChatTimestampCursor: cursor = ZendeskChatTimestampCursor( - start_datetime = "2020-10-01T00:00:00Z", - cursor_field = cursor_field, - datetime_format = "%s", - config = config, - parameters = {}, - use_microseconds = f"{{{ {use_microseconds} }}}", + start_datetime="2020-10-01T00:00:00Z", + cursor_field=cursor_field, + datetime_format="%s", + config=config, + parameters={}, + use_microseconds=f"{{{ {use_microseconds} }}}", ) # patching missing parts cursor.start_time_option = RequestOption( - field_name = cursor_field, - inject_into = RequestOptionType.request_parameter, + field_name=cursor_field, + inject_into=RequestOptionType.request_parameter, parameters={}, ) return cursor @@ -29,25 +30,25 @@ def _get_cursor(config, cursor_field, use_microseconds) -> ZendeskChatTimestampC @pytest.mark.parametrize( "use_microseconds, input_slice, expected", [ - (True, {"start_time": 1}, {'start_time': 1000000}), + (True, {"start_time": 1}, {"start_time": 1000000}), ], ) def test_timestamp_based_cursor_add_microseconds(config, use_microseconds, input_slice, expected) -> None: cursor = _get_cursor(config, "start_time", use_microseconds) test_result = cursor.add_microseconds({}, input_slice) assert test_result == expected - + @pytest.mark.parametrize( "use_microseconds, input_slice, expected", [ - (True, {"start_time": 1}, {'start_time': 1000000}), - (False, {"start_time": 1}, {'start_time': 1}), + (True, {"start_time": 1}, {"start_time": 1000000}), + (False, {"start_time": 1}, {"start_time": 1}), ], ids=[ "WITH `use_microseconds`", "WITHOUT `use_microseconds`", - ] + ], ) def test_timestamp_based_cursor_get_request_params(config, use_microseconds, input_slice, expected) -> None: cursor = _get_cursor(config, "start_time", use_microseconds) diff --git a/airbyte-integrations/connectors/source-zendesk-sell/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-zendesk-sell/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-zendesk-sell/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-zendesk-sell/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-zendesk-sell/metadata.yaml b/airbyte-integrations/connectors/source-zendesk-sell/metadata.yaml index 67d00783f20b..9b53ae688813 100644 --- a/airbyte-integrations/connectors/source-zendesk-sell/metadata.yaml +++ b/airbyte-integrations/connectors/source-zendesk-sell/metadata.yaml @@ -14,7 +14,7 @@ data: connectorSubtype: api connectorType: source definitionId: 982eaa4c-bba1-4cce-a971-06a41f700b8c - dockerImageTag: 0.3.1 + dockerImageTag: 0.3.5 dockerRepository: airbyte/source-zendesk-sell githubIssueLabel: source-zendesk-sell icon: zendesk.svg @@ -42,5 +42,5 @@ data: type: GSM alias: airbyte-connector-testing-secret-store connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-zendesk-sunshine/README.md b/airbyte-integrations/connectors/source-zendesk-sunshine/README.md index 3317f4ae0a62..852f7bd68d7c 100644 --- a/airbyte-integrations/connectors/source-zendesk-sunshine/README.md +++ b/airbyte-integrations/connectors/source-zendesk-sunshine/README.md @@ -1,49 +1,22 @@ -# Zendesk-Sunshine source connector +# Zendesk sunshine source connector -This is the repository for the Zendesk-Sunshine source connector, written in Python. -For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.com/integrations/sources/zendesk-sunshine). +This directory contains the manifest-only connector for `source-zendesk-sunshine`. +This _manifest-only_ connector is not a Python package on its own, as it runs inside of the base `source-declarative-manifest` image. -## Local development - -### Prerequisites - -- Python (~=3.9) -- Poetry (~=1.7) - installation instructions [here](https://python-poetry.org/docs/#installation) - -### Installing the connector - -From this connector directory, run: - -```bash -poetry install --with dev -``` - -### Create credentials +For information about how to configure and use this connector within Airbyte, see [the connector's full documentation](https://docs.airbyte.com/integrations/sources/zendesk-sunshine). -**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/zendesk-sunshine) -to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_zendesk_sunshine/spec.yaml` file. -Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. -See `sample_files/sample_config.json` for a sample config file. - -### Locally running the connector - -``` -poetry run source-zendesk-sunshine spec -poetry run source-zendesk-sunshine check --config secrets/config.json -poetry run source-zendesk-sunshine discover --config secrets/config.json -poetry run source-zendesk-sunshine read --config secrets/config.json --catalog sample_files/configured_catalog.json -``` +## Local development -### Running unit tests +We recommend using the Connector Builder to edit this connector. +Using either Airbyte Cloud or your local Airbyte OSS instance, navigate to the **Builder** tab and select **Import a YAML**. +Then select the connector's `manifest.yaml` file to load the connector into the Builder. You're now ready to make changes to the connector! -To run unit tests locally, from the connector directory run: - -``` -poetry run pytest unit_tests -``` +If you prefer to develop locally, you can follow the instructions below. ### Building the docker image +You can build any manifest-only connector with `airbyte-ci`: + 1. Install [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md) 2. Run the following command to build the docker image: @@ -53,18 +26,24 @@ airbyte-ci connectors --name=source-zendesk-sunshine build An image will be available on your host with the tag `airbyte/source-zendesk-sunshine:dev`. +### Creating credentials + +**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/zendesk-sunshine) +to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `spec` object in the connector's `manifest.yaml` file. +Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. + ### Running as a docker container -Then run any of the connector commands as follows: +Then run any of the standard source connector commands: -``` +```bash docker run --rm airbyte/source-zendesk-sunshine:dev spec docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-zendesk-sunshine:dev check --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-zendesk-sunshine:dev discover --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-zendesk-sunshine:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json ``` -### Running our CI test suite +### Running the CI test suite You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): @@ -72,33 +51,15 @@ You can run our full test suite locally using [`airbyte-ci`](https://github.com/ airbyte-ci connectors --name=source-zendesk-sunshine test ``` -### Customizing acceptance Tests - -Customize `acceptance-test-config.yml` file to configure acceptance tests. See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) for more information. -If your connector requires to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py. - -### Dependency Management - -All of your dependencies should be managed via Poetry. -To add a new dependency, run: - -```bash -poetry add -``` - -Please commit the changes to `pyproject.toml` and `poetry.lock` files. - ## Publishing a new version of the connector -You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what? - -1. Make sure your changes are passing our test suite: `airbyte-ci connectors --name=source-zendesk-sunshine test` -2. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): - - bump the `dockerImageTag` value in in `metadata.yaml` - - bump the `version` value in `pyproject.toml` -3. Make sure the `metadata.yaml` content is up to date. +If you want to contribute changes to `source-zendesk-sunshine`, here's how you can do that: +1. Make your changes locally, or load the connector's manifest into Connector Builder and make changes there. +2. Make sure your changes are passing our test suite with `airbyte-ci connectors --name=source-zendesk-sunshine test` +3. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): + - bump the `dockerImageTag` value in in `metadata.yaml` 4. Make sure the connector documentation and its changelog is up to date (`docs/integrations/sources/zendesk-sunshine.md`). 5. Create a Pull Request: use [our PR naming conventions](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#pull-request-title-convention). 6. Pat yourself on the back for being an awesome contributor. 7. Someone from Airbyte will take a look at your PR and iterate with you to merge it into master. -8. Once your PR is merged, the new version of the connector will be automatically published to Docker Hub and our connector registry. +8. Once your PR is merged, the new version of the connector will be automatically published to Docker Hub and our connector registry. \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-zendesk-sunshine/__init__.py b/airbyte-integrations/connectors/source-zendesk-sunshine/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-sunshine/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-integrations/connectors/source-zendesk-sunshine/acceptance-test-config.yml b/airbyte-integrations/connectors/source-zendesk-sunshine/acceptance-test-config.yml index c418358b0f89..ee0bf9c52ed7 100644 --- a/airbyte-integrations/connectors/source-zendesk-sunshine/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-zendesk-sunshine/acceptance-test-config.yml @@ -3,6 +3,9 @@ connector_image: airbyte/source-zendesk-sunshine:dev test_strictness_level: low acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" connection: tests: - config_path: "secrets/config_oauth.json" diff --git a/airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/components.py b/airbyte-integrations/connectors/source-zendesk-sunshine/components.py similarity index 100% rename from airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/components.py rename to airbyte-integrations/connectors/source-zendesk-sunshine/components.py diff --git a/airbyte-integrations/connectors/source-zendesk-sunshine/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-zendesk-sunshine/integration_tests/acceptance.py index 9e6409236281..a612c74fc689 100644 --- a/airbyte-integrations/connectors/source-zendesk-sunshine/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-zendesk-sunshine/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-zendesk-sunshine/main.py b/airbyte-integrations/connectors/source-zendesk-sunshine/main.py deleted file mode 100644 index 4b7507ee396c..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-sunshine/main.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from source_zendesk_sunshine.run import run - -if __name__ == "__main__": - run() diff --git a/airbyte-integrations/connectors/source-zendesk-sunshine/manifest.yaml b/airbyte-integrations/connectors/source-zendesk-sunshine/manifest.yaml new file mode 100644 index 000000000000..4c214b38819b --- /dev/null +++ b/airbyte-integrations/connectors/source-zendesk-sunshine/manifest.yaml @@ -0,0 +1,695 @@ +version: 5.15.0 + +type: DeclarativeSource + +check: + type: CheckStream + stream_names: + - limits + +definitions: + streams: + limits: + type: DeclarativeStream + name: limits + primary_key: + - key + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: limits + http_method: GET + request_headers: + Content-Type: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"links\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"links\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/limits" + object_types: + type: DeclarativeStream + name: object_types + primary_key: + - key + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: objects/types + http_method: GET + request_headers: + Content-Type: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"links\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"links\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/object_types" + object_records: + type: DeclarativeStream + name: object_records + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: objects/query + http_method: POST + request_headers: + Content-Type: application/json + request_body_json: + query: + _type: + $eq: "{{ stream_partition.type }}" + sort_by: _updated_at asc + _updated_at: + start: >- + {{ stream_interval.start_time.strftime('%Y-%m-%d + %H:%M:%s.%f')[:-3] }} + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"links\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"links\", {}).get(\"next\", {}) }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: key + partition_field: type + stream: + $ref: "#/definitions/streams/object_types" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%S.%f%z" + datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/object_records" + object_type_policies: + type: DeclarativeStream + name: object_type_policies + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: objects/types/{{ stream_partition.type }}/permissions + http_method: GET + request_headers: + Content-Type: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"links\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"links\", {}).get(\"next\", {}) }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: key + partition_field: type + stream: + $ref: "#/definitions/streams/object_types" + transformations: + - type: AddFields + fields: + - path: + - object_type + value: "{{ stream_partition.type }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/object_type_policies" + relationship_types: + type: DeclarativeStream + name: relationship_types + primary_key: + - key + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: relationships/types + http_method: GET + request_headers: + Content-Type: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"links\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"links\", {}).get(\"next\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/relationship_types" + relationship_records: + type: DeclarativeStream + name: relationship_records + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: relationships/records + http_method: GET + request_parameters: + type: "{{ stream_partition.type }}" + request_headers: + Content-Type: application/json + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: CursorPagination + page_size: 100 + cursor_value: "{{ response.get(\"links\", {}).get(\"next\", {}) }}" + stop_condition: "{{ not response.get(\"links\", {}).get(\"next\", {}) }}" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: key + partition_field: type + stream: + $ref: "#/definitions/streams/relationship_types" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/relationship_records" + base_requester: + type: HttpRequester + url_base: https://{{ config['subdomain'] }}.zendesk.com/api/sunshine/ + authenticator: + type: CustomAuthenticator + class_name: source_declarative_manifest.components.AuthenticatorZendeskSunshine + basic_auth: + type: BasicHttpAuthenticator + password: "{{ config['credentials']['api_token'] }}" + username: "{{ config['credentials']['email'] }}/token" + oauth2: + type: BearerAuthenticator + api_token: "{{ config['credentials']['access_token'] }}" + +streams: + - $ref: "#/definitions/streams/limits" + - $ref: "#/definitions/streams/object_types" + - $ref: "#/definitions/streams/object_records" + - $ref: "#/definitions/streams/object_type_policies" + - $ref: "#/definitions/streams/relationship_types" + - $ref: "#/definitions/streams/relationship_records" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - subdomain + - start_date + properties: + subdomain: + type: string + description: The subdomain for your Zendesk Account. + order: 0 + title: Subdomain + start_date: + type: string + description: >- + The date from which you'd like to replicate data for Zendesk Sunshine + API, in the format YYYY-MM-DDT00:00:00Z. + title: Start date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + examples: + - "2021-01-01T00:00:00Z" + order: 1 + credentials: + type: object + title: Authorization Method + oneOf: + - type: object + title: OAuth2.0 + required: + - auth_method + - client_id + - client_secret + - access_token + properties: + auth_method: + type: string + const: oauth2.0 + enum: + - oauth2.0 + default: oauth2.0 + order: 0 + client_id: + type: string + description: The Client ID of your OAuth application. + title: Client ID + airbyte_secret: true + client_secret: + type: string + description: The Client Secret of your OAuth application. + title: Client Secret + airbyte_secret: true + access_token: + type: string + description: Long-term access Token for making authenticated requests. + title: Access Token + airbyte_secret: true + - type: object + title: API Token + required: + - auth_method + - api_token + - email + properties: + auth_method: + type: string + const: api_token + enum: + - api_token + default: api_token + order: 1 + api_token: + type: string + description: >- + API Token. See the docs + for information on how to generate this key. + title: API Token + airbyte_secret: true + email: + type: string + description: The user email for your Zendesk account + title: Email + order: 2 + additionalProperties: true + +metadata: + autoImportSchema: + limits: false + object_types: false + object_records: false + object_type_policies: false + relationship_types: false + relationship_records: false + +schemas: + limits: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + count: + type: + - "null" + - integer + description: The total count of the data records fetched + key: + type: + - "null" + - string + description: The identifier key for the fetched data records + limit: + type: + - "null" + - integer + description: >- + The maximum limit allowed for fetching data records in a single + request + object_types: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + created_at: + type: + - "null" + - string + description: The date and time when the object type was created. + key: + type: + - "null" + - string + description: The unique identifier for the object type. + schema: + type: + - "null" + - object + description: The schema definition for the object type properties and requirements. + additionalProperties: true + properties: + properties: + type: + - "null" + - object + description: The defined properties for the object type. + additionalProperties: true + required: + type: + - "null" + - array + description: An array specifying the required properties for the object type. + items: + type: + - "null" + - string + description: The name of a required property. + updated_at: + type: + - "null" + - string + description: The date and time when the object type was last updated. + object_records: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + type: + type: + - "null" + - string + description: The type or category of the object record. + attributes: + type: + - "null" + - object + description: Custom data attributes associated with the object record. + additionalProperties: true + created_at: + type: + - "null" + - string + description: The timestamp indicating when the object record was created. + external_id: + type: + - string + - "null" + description: The unique identifier for the object record in an external system. + id: + type: + - "null" + - string + description: >- + The unique identifier for the object record in the Zendesk Sunshine + platform. + updated_at: + type: + - "null" + - string + description: The timestamp indicating when the object record was last updated. + object_type_policies: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + object_type: + type: + - "null" + - string + description: The type of object for which the permissions are being defined. + rbac: + type: + - "null" + - object + description: Access control policies related to role-based access control. + additionalProperties: true + properties: + admin: + type: + - "null" + - object + description: Permissions for administrators. + additionalProperties: true + properties: + create: + type: + - "null" + - boolean + description: Permission to create new objects of this type. + delete: + type: + - "null" + - boolean + description: Permission to delete objects of this type. + read: + type: + - "null" + - boolean + description: Permission to read/view objects of this type. + update: + type: + - "null" + - boolean + description: Permission to update/edit objects of this type. + agent: + type: + - "null" + - object + description: Permissions for agents. + additionalProperties: true + properties: + create: + type: + - "null" + - boolean + description: Permission to create new objects of this type. + delete: + type: + - "null" + - boolean + description: Permission to delete objects of this type. + read: + type: + - "null" + - boolean + description: Permission to read/view objects of this type. + update: + type: + - "null" + - boolean + description: Permission to update/edit objects of this type. + end_user: + type: + - "null" + - object + description: Permissions for end users. + additionalProperties: true + properties: + create: + type: + - "null" + - boolean + description: Permission to create new objects of this type. + delete: + type: + - "null" + - boolean + description: Permission to delete objects of this type. + read: + type: + - "null" + - boolean + description: Permission to read/view objects of this type. + update: + type: + - "null" + - boolean + description: Permission to update/edit objects of this type. + relationship_types: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + created_at: + type: + - "null" + - string + description: The timestamp representing when the relationship type was created. + key: + type: + - "null" + - string + description: A unique identifier for the relationship type. + source: + type: + - "null" + - string + description: The entity that is the source of the relationship. + target: + type: + - "null" + - string + description: The entity that is the target of the relationship. + updated_at: + type: + - "null" + - string + description: >- + The timestamp representing when the relationship type was last + updated. + relationship_records: + type: object + $schema: http://json-schema.org/draft-07/schema# + additionalProperties: true + properties: + created_at: + type: string + description: The timestamp indicating when the relationship record was created. + id: + type: string + description: The unique identifier for the relationship record. + relationship_type: + type: string + description: The type of relationship between the source and target entities. + source: + type: string + description: The entity that initiated the relationship. + target: + type: string + description: The entity that is the target of the relationship. diff --git a/airbyte-integrations/connectors/source-zendesk-sunshine/metadata.yaml b/airbyte-integrations/connectors/source-zendesk-sunshine/metadata.yaml index b256f0f5a1e9..da52e592f479 100644 --- a/airbyte-integrations/connectors/source-zendesk-sunshine/metadata.yaml +++ b/airbyte-integrations/connectors/source-zendesk-sunshine/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - ${subdomain}.zendesk.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 325e0640-e7b3-4e24-b823-3361008f603f - dockerImageTag: 0.2.26 + dockerImageTag: 0.3.3 dockerRepository: airbyte/source-zendesk-sunshine documentationUrl: https://docs.airbyte.com/integrations/sources/zendesk-sunshine githubIssueLabel: source-zendesk-sunshine @@ -26,11 +26,11 @@ data: releaseStage: alpha remoteRegistries: pypi: - enabled: true + enabled: false packageName: airbyte-source-zendesk-sunshine supportLevel: community tags: - - language:python + - language:manifest-only - cdk:low-code connectorTestSuitesOptions: - suite: liveTests diff --git a/airbyte-integrations/connectors/source-zendesk-sunshine/poetry.lock b/airbyte-integrations/connectors/source-zendesk-sunshine/poetry.lock deleted file mode 100644 index 43a15cee8460..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-sunshine/poetry.lock +++ /dev/null @@ -1,1065 +0,0 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. - -[[package]] -name = "airbyte-cdk" -version = "0.80.0" -description = "A framework for writing Airbyte Connectors." -optional = false -python-versions = "<4.0,>=3.9" -files = [ - {file = "airbyte_cdk-0.80.0-py3-none-any.whl", hash = "sha256:060e92323a73674fa4e9e2e4a1eb312b9b9d072c9bbe5fa28f54ef21cb4974f3"}, - {file = "airbyte_cdk-0.80.0.tar.gz", hash = "sha256:1383512a83917fecca5b24cea4c72aa5c561cf96dd464485fbcefda48fe574c5"}, -] - -[package.dependencies] -airbyte-protocol-models = "0.5.1" -backoff = "*" -cachetools = "*" -Deprecated = ">=1.2,<1.3" -dpath = ">=2.0.1,<2.1.0" -genson = "1.2.2" -isodate = ">=0.6.1,<0.7.0" -Jinja2 = ">=3.1.2,<3.2.0" -jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" -pendulum = "<3.0.0" -pydantic = ">=1.10.8,<2.0.0" -pyrate-limiter = ">=3.1.0,<3.2.0" -python-dateutil = "*" -PyYAML = ">=6.0.1,<7.0.0" -requests = "*" -requests_cache = "*" -wcmatch = "8.4" - -[package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.0.271)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] - -[[package]] -name = "airbyte-protocol-models" -version = "0.5.1" -description = "Declares the Airbyte Protocol." -optional = false -python-versions = ">=3.8" -files = [ - {file = "airbyte_protocol_models-0.5.1-py3-none-any.whl", hash = "sha256:dfe84e130e51ce2ae81a06d5aa36f6c5ce3152b9e36e6f0195fad6c3dab0927e"}, - {file = "airbyte_protocol_models-0.5.1.tar.gz", hash = "sha256:7c8b16c7c1c7956b1996052e40585a3a93b1e44cb509c4e97c1ee4fe507ea086"}, -] - -[package.dependencies] -pydantic = ">=1.9.2,<2.0.0" - -[[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, -] - -[[package]] -name = "attrs" -version = "24.2.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" -files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, -] - -[package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] - -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "bracex" -version = "2.5.post1" -description = "Bash style brace expander." -optional = false -python-versions = ">=3.8" -files = [ - {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, - {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, -] - -[[package]] -name = "cachetools" -version = "5.5.0" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, - {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, -] - -[[package]] -name = "cattrs" -version = "24.1.2" -description = "Composable complex class support for attrs and dataclasses." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, - {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, -] - -[package.dependencies] -attrs = ">=23.1.0" -exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} - -[package.extras] -bson = ["pymongo (>=4.4.0)"] -cbor2 = ["cbor2 (>=5.4.6)"] -msgpack = ["msgpack (>=1.0.5)"] -msgspec = ["msgspec (>=0.18.5)"] -orjson = ["orjson (>=3.9.2)"] -pyyaml = ["pyyaml (>=6.0)"] -tomlkit = ["tomlkit (>=0.11.8)"] -ujson = ["ujson (>=5.7.0)"] - -[[package]] -name = "certifi" -version = "2024.8.30" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.0" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -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 = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - -[[package]] -name = "dpath" -version = "2.0.8" -description = "Filesystem-like pathing and searching for dictionaries" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dpath-2.0.8-py3-none-any.whl", hash = "sha256:f92f595214dd93a00558d75d4b858beee519f4cffca87f02616ad6cd013f3436"}, - {file = "dpath-2.0.8.tar.gz", hash = "sha256:a3440157ebe80d0a3ad794f1b61c571bef125214800ffdb9afc9424e8250fe9b"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "genson" -version = "1.2.2" -description = "GenSON is a powerful, user-friendly JSON Schema generator." -optional = false -python-versions = "*" -files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, -] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isodate" -version = "0.6.1" -description = "An ISO 8601 date/time/duration parser and formatter" -optional = false -python-versions = "*" -files = [ - {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, - {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "jinja2" -version = "3.1.4" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "jsonref" -version = "0.2" -description = "An implementation of JSON Reference for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonref-0.2-py3-none-any.whl", hash = "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f"}, - {file = "jsonref-0.2.tar.gz", hash = "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697"}, -] - -[[package]] -name = "jsonschema" -version = "3.2.0" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, -] - -[package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" - -[package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] - -[[package]] -name = "markupsafe" -version = "3.0.2" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -files = [ - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, - {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, -] - -[[package]] -name = "packaging" -version = "24.1" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, -] - -[[package]] -name = "pendulum" -version = "2.1.2" -description = "Python datetimes made easy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, - {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, - {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, - {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, - {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, - {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, - {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, - {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, - {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, - {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, - {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, -] - -[package.dependencies] -python-dateutil = ">=2.6,<3.0" -pytzdata = ">=2020.1" - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] - -[[package]] -name = "pydantic" -version = "1.10.18" -description = "Data validation and settings management using python type hints" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, -] - -[package.dependencies] -typing-extensions = ">=4.2.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] - -[[package]] -name = "pyrate-limiter" -version = "3.1.1" -description = "Python Rate-Limiter using Leaky-Bucket Algorithm" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, - {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, -] - -[package.extras] -all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] -docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] - -[[package]] -name = "pyrsistent" -version = "0.20.0" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7"}, - {file = "pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee"}, - {file = "pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d"}, - {file = "pyrsistent-0.20.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win32.whl", hash = "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d"}, - {file = "pyrsistent-0.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win32.whl", hash = "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf"}, - {file = "pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b"}, - {file = "pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4"}, -] - -[[package]] -name = "pytest" -version = "6.2.5" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, -] - -[package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] - -[[package]] -name = "pytest-mock" -version = "3.14.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, -] - -[package.dependencies] -pytest = ">=6.2.5" - -[package.extras] -dev = ["pre-commit", "pytest-asyncio", "tox"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytzdata" -version = "2020.1" -description = "The Olson timezone database for Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, - {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-cache" -version = "1.2.1" -description = "A persistent cache for python requests" -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, - {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, -] - -[package.dependencies] -attrs = ">=21.2" -cattrs = ">=22.2" -platformdirs = ">=2.5" -requests = ">=2.22" -url-normalize = ">=1.4" -urllib3 = ">=1.25.5" - -[package.extras] -all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] -bson = ["bson (>=0.5)"] -docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] -dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] -json = ["ujson (>=5.4)"] -mongodb = ["pymongo (>=3)"] -redis = ["redis (>=3)"] -security = ["itsdangerous (>=2.0)"] -yaml = ["pyyaml (>=6.0.1)"] - -[[package]] -name = "requests-mock" -version = "1.12.1" -description = "Mock out responses from the requests package" -optional = false -python-versions = ">=3.5" -files = [ - {file = "requests-mock-1.12.1.tar.gz", hash = "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401"}, - {file = "requests_mock-1.12.1-py2.py3-none-any.whl", hash = "sha256:b1e37054004cdd5e56c84454cc7df12b25f90f382159087f4b6915aaeef39563"}, -] - -[package.dependencies] -requests = ">=2.22,<3" - -[package.extras] -fixture = ["fixtures"] - -[[package]] -name = "setuptools" -version = "75.3.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "url-normalize" -version = "1.4.3" -description = "URL normalization for Python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, - {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "urllib3" -version = "2.2.3" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "wcmatch" -version = "8.4" -description = "Wildcard/glob file name matcher." -optional = false -python-versions = ">=3.7" -files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, -] - -[package.dependencies] -bracex = ">=2.1.1" - -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "990042bd8aff2361370f7cea38b2dffbadb5bd28397a241166061ec2619f6426" diff --git a/airbyte-integrations/connectors/source-zendesk-sunshine/pyproject.toml b/airbyte-integrations/connectors/source-zendesk-sunshine/pyproject.toml deleted file mode 100644 index 272f3551409b..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-sunshine/pyproject.toml +++ /dev/null @@ -1,28 +0,0 @@ -[build-system] -requires = [ "poetry-core>=1.0.0",] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -version = "0.2.26" -name = "source-zendesk-sunshine" -description = "Source implementation for Zendesk Sunshine." -authors = [ "Airbyte ",] -license = "MIT" -readme = "README.md" -documentation = "https://docs.airbyte.com/integrations/sources/zendesk-sunshine" -homepage = "https://airbyte.com" -repository = "https://github.com/airbytehq/airbyte" -[[tool.poetry.packages]] -include = "source_zendesk_sunshine" - -[tool.poetry.dependencies] -python = "^3.9,<3.12" -airbyte-cdk = "0.80.0" - -[tool.poetry.scripts] -source-zendesk-sunshine = "source_zendesk_sunshine.run:run" - -[tool.poetry.group.dev.dependencies] -pytest = "^6.2" -requests-mock = "^1.9.3" -pytest-mock = "^3.6.1" diff --git a/airbyte-integrations/connectors/source-zendesk-sunshine/sample_files/state.json b/airbyte-integrations/connectors/source-zendesk-sunshine/sample_files/state.json deleted file mode 100644 index 5915164004e8..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-sunshine/sample_files/state.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "object_records": { - "s1tfq4tjlyaw": { - "updated_at": "2021-06-24T10:50:39.772Z" - } - } -} diff --git a/airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/__init__.py b/airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/__init__.py deleted file mode 100644 index d6f54ad6589f..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from .source import SourceZendeskSunshine - -__all__ = ["SourceZendeskSunshine"] diff --git a/airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/manifest.yaml b/airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/manifest.yaml deleted file mode 100644 index a4e442ad1231..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/manifest.yaml +++ /dev/null @@ -1,593 +0,0 @@ -version: 0.50.2 -type: DeclarativeSource - -check: - type: CheckStream - stream_names: - - limits - -definitions: - selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - data - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - page_size_option: - type: RequestOption - field_name: per_page - inject_into: request_parameter - pagination_strategy: - type: CursorPagination - page_size: 100 - cursor_value: '{{ response.get("links", {}).get("next", {}) }}' - stop_condition: '{{ not response.get("links", {}).get("next", {}) }}' - basic_authenticator: - type: BasicHttpAuthenticator - password: "{{ config['credentials']['api_token'] }}" - username: "{{ config['credentials']['email'] }}/token" - oauth2_authenticator: - type: BearerAuthenticator - api_token: "{{ config['credentials']['access_token'] }}" - requester: - type: HttpRequester - url_base: https://{{ config['subdomain'] }}.zendesk.com/api/sunshine/ - http_method: GET - request_headers: - Content-Type: application/json - authenticator: - class_name: source_zendesk_sunshine.components.AuthenticatorZendeskSunshine - basic_auth: "#/definitions/basic_authenticator" - oauth2: "#/definitions/oauth2_authenticator" - error_handler: - type: CompositeErrorHandler - error_handlers: - - type: DefaultErrorHandler - backoff_strategies: - - type: WaitTimeFromHeader - header: Retry-After - request_body_json: {} - base_stream: - type: DeclarativeStream - primary_key: key - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: "{{ parameters.path }}" - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator" - limits_stream: - $ref: "#/definitions/base_stream" - name: limits - $parameters: - path: limits - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - key: - description: The identifier key for the fetched data records - type: - - "null" - - string - limit: - description: - The maximum limit allowed for fetching data records in a - single request - type: - - "null" - - integer - count: - description: The total count of the data records fetched - type: - - "null" - - integer - relationship_types_stream: - $ref: "#/definitions/base_stream" - name: relationship_types - $parameters: - path: relationships/types - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - key: - description: A unique identifier for the relationship type. - type: - - "null" - - string - source: - description: The entity that is the source of the relationship. - type: - - "null" - - string - target: - description: The entity that is the target of the relationship. - type: - - "null" - - string - created_at: - description: - The timestamp representing when the relationship type was - created. - type: - - "null" - - string - updated_at: - description: - The timestamp representing when the relationship type was - last updated. - type: - - "null" - - string - object_types_stream: - $ref: "#/definitions/base_stream" - name: object_types - $parameters: - path: objects/types - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - key: - description: The unique identifier for the object type. - type: - - "null" - - string - schema: - description: - The schema definition for the object type properties and - requirements. - type: - - "null" - - object - additionalProperties: true - properties: - properties: - description: The defined properties for the object type. - type: - - "null" - - object - additionalProperties: true - required: - description: - An array specifying the required properties for the object - type. - type: - - "null" - - array - items: - description: The name of a required property. - type: - - "null" - - string - created_at: - description: The date and time when the object type was created. - type: - - "null" - - string - updated_at: - description: The date and time when the object type was last updated. - type: - - "null" - - string - object_records_stream: - type: DeclarativeStream - name: object_records - primary_key: id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: objects/query - http_method: POST - request_body_json: - query: - _type: - $eq: "{{ stream_partition.type }}" - sort_by: _updated_at asc - _updated_at: - start: - "{{ stream_interval.start_time.strftime('%Y-%m-%d %H:%M:%s.%f')[:-3] - }}" - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator" - partition_router: - - type: SubstreamPartitionRouter - parent_stream_configs: - - type: ParentStreamConfig - parent_key: key - partition_field: type - stream: - $ref: "#/definitions/object_types_stream" - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%S.%f%z" - datetime_format: "%Y-%m-%dT%H:%M:%S.%f%z" - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - end_datetime: - type: MinMaxDatetime - datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - type: - description: The type or category of the object record. - type: - - "null" - - string - id: - description: - The unique identifier for the object record in the Zendesk - Sunshine platform. - type: - - "null" - - string - external_id: - description: - The unique identifier for the object record in an external - system. - type: - - string - - "null" - attributes: - description: Custom data attributes associated with the object record. - type: - - "null" - - object - additionalProperties: true - created_at: - description: The timestamp indicating when the object record was created. - type: - - "null" - - string - updated_at: - description: - The timestamp indicating when the object record was last - updated. - type: - - "null" - - string - object_type_policies_stream: - type: DeclarativeStream - name: object_type_policies - primary_key: [] - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: objects/types/{{ stream_partition.type }}/permissions - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator" - partition_router: - - type: SubstreamPartitionRouter - parent_stream_configs: - - type: ParentStreamConfig - parent_key: key - partition_field: type - stream: - $ref: "#/definitions/object_types_stream" - transformations: - - type: AddFields - fields: - - path: - - object_type - value: "{{ stream_partition.type }}" - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - object_type: - description: The type of object for which the permissions are being defined. - type: - - "null" - - string - rbac: - description: Access control policies related to role-based access control. - type: - - "null" - - object - additionalProperties: true - properties: - admin: - description: Permissions for administrators. - type: - - "null" - - object - additionalProperties: true - properties: - create: - description: Permission to create new objects of this type. - type: - - "null" - - boolean - read: - description: Permission to read/view objects of this type. - type: - - "null" - - boolean - update: - description: Permission to update/edit objects of this type. - type: - - "null" - - boolean - delete: - description: Permission to delete objects of this type. - type: - - "null" - - boolean - agent: - description: Permissions for agents. - type: - - "null" - - object - additionalProperties: true - properties: - create: - description: Permission to create new objects of this type. - type: - - "null" - - boolean - read: - description: Permission to read/view objects of this type. - type: - - "null" - - boolean - update: - description: Permission to update/edit objects of this type. - type: - - "null" - - boolean - delete: - description: Permission to delete objects of this type. - type: - - "null" - - boolean - end_user: - description: Permissions for end users. - type: - - "null" - - object - additionalProperties: true - properties: - create: - description: Permission to create new objects of this type. - type: - - "null" - - boolean - read: - description: Permission to read/view objects of this type. - type: - - "null" - - boolean - update: - description: Permission to update/edit objects of this type. - type: - - "null" - - boolean - delete: - description: Permission to delete objects of this type. - type: - - "null" - - boolean - relationship_records_stream: - type: DeclarativeStream - name: relationship_records - primary_key: id - retriever: - type: SimpleRetriever - requester: - $ref: "#/definitions/requester" - path: relationships/records - request_parameters: - type: "{{ stream_partition.type }}" - record_selector: - $ref: "#/definitions/selector" - paginator: - $ref: "#/definitions/paginator" - partition_router: - - type: SubstreamPartitionRouter - parent_stream_configs: - - type: ParentStreamConfig - parent_key: key - partition_field: type - stream: - $ref: "#/definitions/relationship_types_stream" - - schema_loader: - type: InlineSchemaLoader - schema: - $schema: http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - properties: - id: - description: The unique identifier for the relationship record. - type: string - relationship_type: - description: The type of relationship between the source and target entities. - type: string - source: - description: The entity that initiated the relationship. - type: string - target: - description: The entity that is the target of the relationship. - type: string - created_at: - description: - The timestamp indicating when the relationship record was - created. - type: string -streams: - - "#/definitions/limits_stream" - - "#/definitions/object_types_stream" - - "#/definitions/object_records_stream" - - "#/definitions/object_type_policies_stream" - - "#/definitions/relationship_types_stream" - - "#/definitions/relationship_records_stream" - -spec: - documentation_url: https://docs.airbyte.com/integrations/sources/zendesk_sunshine - type: Spec - connection_specification: - $schema: http://json-schema.org/draft-07/schema# - type: object - additionalProperties: true - required: - - start_date - - subdomain - properties: - subdomain: - type: string - order: 0 - title: Subdomain - description: The subdomain for your Zendesk Account. - start_date: - type: string - title: Start date - format: date-time - description: - The date from which you'd like to replicate data for Zendesk - Sunshine API, in the format YYYY-MM-DDT00:00:00Z. - pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ - examples: - - "2021-01-01T00:00:00Z" - order: 1 - credentials: - title: Authorization Method - type: object - oneOf: - - type: object - title: OAuth2.0 - required: - - auth_method - - client_id - - client_secret - - access_token - properties: - auth_method: - type: string - const: oauth2.0 - enum: - - oauth2.0 - default: oauth2.0 - order: 0 - client_id: - type: string - title: Client ID - description: The Client ID of your OAuth application. - airbyte_secret: true - client_secret: - type: string - title: Client Secret - description: The Client Secret of your OAuth application. - airbyte_secret: true - access_token: - type: string - title: Access Token - description: Long-term access Token for making authenticated requests. - airbyte_secret: true - - type: object - title: API Token - required: - - auth_method - - api_token - - email - properties: - auth_method: - type: string - const: api_token - enum: - - api_token - default: api_token - order: 1 - api_token: - type: string - title: API Token - description: - API Token. See the docs - for information on how to generate this key. - airbyte_secret: true - email: - type: string - title: Email - description: The user email for your Zendesk account - advanced_auth: - auth_flow_type: oauth2.0 - predicate_key: - - credentials - - auth_method - predicate_value: oauth2.0 - oauth_config_specification: - complete_oauth_output_specification: - type: object - additionalProperties: false - properties: - access_token: - type: string - path_in_connector_config: - - credentials - - access_token - complete_oauth_server_input_specification: - type: object - additionalProperties: false - properties: - client_id: - type: string - client_secret: - type: string - complete_oauth_server_output_specification: - type: object - additionalProperties: false - properties: - client_id: - type: string - path_in_connector_config: - - credentials - - client_id - client_secret: - type: string - path_in_connector_config: - - credentials - - client_secret - oauth_user_input_from_connector_config_specification: - type: object - additionalProperties: false - properties: - subdomain: - type: string - path_in_connector_config: - - subdomain diff --git a/airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/run.py b/airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/run.py deleted file mode 100644 index be323283bc95..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/run.py +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import sys - -from airbyte_cdk.entrypoint import launch -from source_zendesk_sunshine import SourceZendeskSunshine - - -def run(): - source = SourceZendeskSunshine() - launch(source, sys.argv[1:]) diff --git a/airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/schemas/jobs.json b/airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/schemas/jobs.json deleted file mode 100644 index 920452d10ba2..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/schemas/jobs.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "additionalProperties": true, - "properties": { - "id": { - "description": "The unique identifier for the job", - "type": ["null", "string"] - }, - "job_status": { - "description": "The status of the job (e.g., pending, processing, completed)", - "type": ["null", "string"] - }, - "created_at": { - "description": "The timestamp when the job was created", - "type": ["null", "string"] - }, - "updated_at": { - "description": "The timestamp when the job was last updated", - "type": ["null", "string"] - }, - "completed_at": { - "description": "The timestamp when the job was completed", - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/source.py b/airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/source.py deleted file mode 100644 index aac70fbfffcb..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-sunshine/source_zendesk_sunshine/source.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource - -""" -This file provides the necessary constructs to interpret a provided declarative YAML configuration file into -source connector. - -WARNING: Do not modify this file. -""" - - -# Declarative Source -class SourceZendeskSunshine(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-zendesk-support/.coveragerc b/airbyte-integrations/connectors/source-zendesk-support/.coveragerc new file mode 100644 index 000000000000..db3aff5a53fb --- /dev/null +++ b/airbyte-integrations/connectors/source-zendesk-support/.coveragerc @@ -0,0 +1,3 @@ +[run] +omit = + source_zendesk_support/run.py diff --git a/airbyte-integrations/connectors/source-zendesk-support/acceptance-test-config.yml b/airbyte-integrations/connectors/source-zendesk-support/acceptance-test-config.yml index 3e294d35872b..dd0de8040a42 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-zendesk-support/acceptance-test-config.yml @@ -39,7 +39,7 @@ acceptance_tests: - config_path: "secrets/config.json" configured_catalog_path: "integration_tests/incremental_catalog.json" future_state: - future_state_path: "integration_tests/abnormal_state.json" + bypass_reason: "This test does not make sense using Concurrent CDK" timeout_seconds: 3600 full_refresh: tests: diff --git a/airbyte-integrations/connectors/source-zendesk-support/integration_tests/abnormal_state.json b/airbyte-integrations/connectors/source-zendesk-support/integration_tests/abnormal_state.json deleted file mode 100644 index 5917f69152f7..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-support/integration_tests/abnormal_state.json +++ /dev/null @@ -1,198 +0,0 @@ -[ - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-07-19T22:21:37Z" }, - "stream_descriptor": { "name": "users" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-07-15T22:19:01Z" }, - "stream_descriptor": { "name": "groups" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-07-15T19:29:14Z" }, - "stream_descriptor": { "name": "organizations" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-07-20T10:05:18Z" }, - "stream_descriptor": { "name": "satisfaction_ratings" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "generated_timestamp": 7969616486 }, - "stream_descriptor": { "name": "tickets" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-04-23T15:34:20Z" }, - "stream_descriptor": { "name": "group_memberships" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-12-11T19:34:05Z" }, - "stream_descriptor": { "name": "ticket_fields" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-12-11T20:34:37Z" }, - "stream_descriptor": { "name": "ticket_forms" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "_ab_updated_at": 7969616486 }, - "stream_descriptor": { "name": "ticket_metrics" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "time": "2222-07-19T22:21:26Z" }, - "stream_descriptor": { "name": "ticket_metric_events" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-12-11T19:34:06Z" }, - "stream_descriptor": { "name": "macros" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "created_at": "2222-07-19T22:21:26Z" }, - "stream_descriptor": { "name": "ticket_comments" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "created_at": "2222-07-19T22:21:26Z" }, - "stream_descriptor": { "name": "ticket_audits" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "created_at": "2222-07-19T22:21:26Z" }, - "stream_descriptor": { "name": "audit_logs" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-12-11T19:34:06Z" }, - "stream_descriptor": { "name": "posts" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-12-11T19:34:06Z" }, - "stream_descriptor": { "name": "topics" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-07-19T22:21:26Z" }, - "stream_descriptor": { "name": "organization_memberships" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-07-19T22:21:26Z" }, - "stream_descriptor": { "name": "ticket_skips" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-07-19T22:21:26Z" }, - "stream_descriptor": { "name": "custom_roles" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-07-19T22:21:26Z" }, - "stream_descriptor": { "name": "schedules" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-07-19T22:21:26Z" }, - "stream_descriptor": { "name": "sla_policies" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-07-19T22:21:26Z" }, - "stream_descriptor": { "name": "post_votes" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-07-19T22:21:26Z" }, - "stream_descriptor": { "name": "post_comments" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-07-19T22:21:26Z" }, - "stream_descriptor": { "name": "post_comment_votes" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-07-19T22:21:26Z" }, - "stream_descriptor": { "name": "articles" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-07-19T22:21:26Z" }, - "stream_descriptor": { "name": "article_votes" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-07-19T22:21:26Z" }, - "stream_descriptor": { "name": "article_comments" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "updated_at": "2222-07-19T22:21:26Z" }, - "stream_descriptor": { "name": "article_comment_votes" } - } - } -] diff --git a/airbyte-integrations/connectors/source-zendesk-support/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-zendesk-support/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-zendesk-support/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-zendesk-support/main.py b/airbyte-integrations/connectors/source-zendesk-support/main.py index 88eed5ec56af..4577f470a2dc 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/main.py +++ b/airbyte-integrations/connectors/source-zendesk-support/main.py @@ -4,5 +4,6 @@ from source_zendesk_support.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-zendesk-support/metadata.yaml b/airbyte-integrations/connectors/source-zendesk-support/metadata.yaml index 9bf90724d24a..85570a016627 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/metadata.yaml +++ b/airbyte-integrations/connectors/source-zendesk-support/metadata.yaml @@ -11,7 +11,7 @@ data: connectorSubtype: api connectorType: source definitionId: 79c1aa37-dae3-42ae-b333-d1c105477715 - dockerImageTag: 4.3.3 + dockerImageTag: 4.4.1 dockerRepository: airbyte/source-zendesk-support documentationUrl: https://docs.airbyte.com/integrations/sources/zendesk-support githubIssueLabel: source-zendesk-support diff --git a/airbyte-integrations/connectors/source-zendesk-support/poetry.lock b/airbyte-integrations/connectors/source-zendesk-support/poetry.lock index 16b3c58e5dea..a4f6613dcfa7 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/poetry.lock +++ b/airbyte-integrations/connectors/source-zendesk-support/poetry.lock @@ -1,14 +1,14 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "airbyte-cdk" -version = "5.17.0" +version = "6.4.0" description = "A framework for writing Airbyte Connectors." optional = false python-versions = "<4.0,>=3.10" files = [ - {file = "airbyte_cdk-5.17.0-py3-none-any.whl", hash = "sha256:135a8fc43b00a92169dfcdc43c1d7c629aba871a0b471f950ca5d76d3741fc92"}, - {file = "airbyte_cdk-5.17.0.tar.gz", hash = "sha256:5db70cbacec80ba3beabe4253480ab9a3947a450e8d0e39af4a91638b317b32a"}, + {file = "airbyte_cdk-6.4.0-py3-none-any.whl", hash = "sha256:61d9fc7717b615300fc74e22cebf8d3ddce8209cc918cfe6871c267db045f835"}, + {file = "airbyte_cdk-6.4.0.tar.gz", hash = "sha256:9edea7e8acc440886b120fbf1ee6b7019b5195e910fa8bee31ca3b22e9e3814b"}, ] [package.dependencies] @@ -25,9 +25,11 @@ jsonref = ">=0.2,<0.3" jsonschema = ">=3.2.0,<3.3.0" langchain_core = "0.1.42" nltk = "3.8.1" +numpy = "<2" orjson = ">=3.10.7,<4.0.0" pandas = "2.2.2" pendulum = "<3.0.0" +psutil = "6.1.0" pydantic = ">=2.7,<3.0" pyjwt = ">=2.8.0,<3.0.0" pyrate-limiter = ">=3.1.0,<3.2.0" @@ -48,13 +50,13 @@ vector-db-based = ["cohere (==4.21)", "langchain (==0.1.16)", "openai[embeddings [[package]] name = "airbyte-protocol-models-dataclasses" -version = "0.13.0" +version = "0.13.1" description = "Declares the Airbyte Protocol using Python Dataclasses. Dataclasses in Python have less performance overhead compared to Pydantic models, making them a more efficient choice for scenarios where speed and memory usage are critical" optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models_dataclasses-0.13.0-py3-none-any.whl", hash = "sha256:0aedb99ffc4f9aab0ce91bba2c292fa17cd8fd4b42eeba196d6a16c20bbbd7a5"}, - {file = "airbyte_protocol_models_dataclasses-0.13.0.tar.gz", hash = "sha256:72e67850d661e2808406aec5839b3158ebb94d3553b798dbdae1b4a278548d2f"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1-py3-none-any.whl", hash = "sha256:20a734b7b1c3479a643777830db6a2e0a34428f33d16abcfd320552576fabe5a"}, + {file = "airbyte_protocol_models_dataclasses-0.13.1.tar.gz", hash = "sha256:ec6a0fb6b16267bde910f52279445d06c8e1a3e4ed82ac2937b405ab280449d5"}, ] [[package]] @@ -743,13 +745,13 @@ extended-testing = ["jinja2 (>=3,<4)"] [[package]] name = "langsmith" -version = "0.1.137" +version = "0.1.140" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, - {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, + {file = "langsmith-0.1.140-py3-none-any.whl", hash = "sha256:3de70183ae19a4ada4d77a8a9f336ff95ca0ead98215771033ee889a2889fe19"}, + {file = "langsmith-0.1.140.tar.gz", hash = "sha256:cb0a717d7b9e6d3145285d7ca0ab216e064cbe7a1ca4139fc04af57fb2315e70"}, ] [package.dependencies] @@ -856,131 +858,114 @@ twitter = ["twython"] [[package]] name = "numpy" -version = "2.1.2" +version = "1.26.4" description = "Fundamental package for array computing in Python" optional = false -python-versions = ">=3.10" -files = [ - {file = "numpy-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466"}, - {file = "numpy-2.1.2-cp310-cp310-win32.whl", hash = "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb"}, - {file = "numpy-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146"}, - {file = "numpy-2.1.2-cp311-cp311-win32.whl", hash = "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c"}, - {file = "numpy-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142"}, - {file = "numpy-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550"}, - {file = "numpy-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe"}, - {file = "numpy-2.1.2-cp313-cp313-win32.whl", hash = "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a"}, - {file = "numpy-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e"}, - {file = "numpy-2.1.2.tar.gz", hash = "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c"}, +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, ] [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.11" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, - {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, - {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, - {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, - {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, - {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, - {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, - {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, - {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, - {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, - {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, - {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, - {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, - {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, - {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, - {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, - {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, - {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, - {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, - {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, - {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, - {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, - {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, - {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.11-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6dade64687f2bd7c090281652fe18f1151292d567a9302b34c2dbb92a3872f1f"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82f07c550a6ccd2b9290849b22316a609023ed851a87ea888c0456485a7d196a"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd9a187742d3ead9df2e49240234d728c67c356516cf4db018833a86f20ec18c"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77b0fed6f209d76c1c39f032a70df2d7acf24b1812ca3e6078fd04e8972685a3"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63fc9d5fe1d4e8868f6aae547a7b8ba0a2e592929245fff61d633f4caccdcdd6"}, + {file = "orjson-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65cd3e3bb4fbb4eddc3c1e8dce10dc0b73e808fcb875f9fab40c81903dd9323e"}, + {file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6f67c570602300c4befbda12d153113b8974a3340fdcf3d6de095ede86c06d92"}, + {file = "orjson-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1f39728c7f7d766f1f5a769ce4d54b5aaa4c3f92d5b84817053cc9995b977acc"}, + {file = "orjson-3.10.11-cp310-none-win32.whl", hash = "sha256:1789d9db7968d805f3d94aae2c25d04014aae3a2fa65b1443117cd462c6da647"}, + {file = "orjson-3.10.11-cp310-none-win_amd64.whl", hash = "sha256:5576b1e5a53a5ba8f8df81872bb0878a112b3ebb1d392155f00f54dd86c83ff6"}, + {file = "orjson-3.10.11-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1444f9cb7c14055d595de1036f74ecd6ce15f04a715e73f33bb6326c9cef01b6"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdec57fe3b4bdebcc08a946db3365630332dbe575125ff3d80a3272ebd0ddafe"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4eed32f33a0ea6ef36ccc1d37f8d17f28a1d6e8eefae5928f76aff8f1df85e67"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80df27dd8697242b904f4ea54820e2d98d3f51f91e97e358fc13359721233e4b"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:705f03cee0cb797256d54de6695ef219e5bc8c8120b6654dd460848d57a9af3d"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03246774131701de8e7059b2e382597da43144a9a7400f178b2a32feafc54bd5"}, + {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8b5759063a6c940a69c728ea70d7c33583991c6982915a839c8da5f957e0103a"}, + {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:677f23e32491520eebb19c99bb34675daf5410c449c13416f7f0d93e2cf5f981"}, + {file = "orjson-3.10.11-cp311-none-win32.whl", hash = "sha256:a11225d7b30468dcb099498296ffac36b4673a8398ca30fdaec1e6c20df6aa55"}, + {file = "orjson-3.10.11-cp311-none-win_amd64.whl", hash = "sha256:df8c677df2f9f385fcc85ab859704045fa88d4668bc9991a527c86e710392bec"}, + {file = "orjson-3.10.11-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:360a4e2c0943da7c21505e47cf6bd725588962ff1d739b99b14e2f7f3545ba51"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:496e2cb45de21c369079ef2d662670a4892c81573bcc143c4205cae98282ba97"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7dfa8db55c9792d53c5952900c6a919cfa377b4f4534c7a786484a6a4a350c19"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:51f3382415747e0dbda9dade6f1e1a01a9d37f630d8c9049a8ed0e385b7a90c0"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f35a1b9f50a219f470e0e497ca30b285c9f34948d3c8160d5ad3a755d9299433"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f3b7c5803138e67028dde33450e054c87e0703afbe730c105f1fcd873496d5"}, + {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f91d9eb554310472bd09f5347950b24442600594c2edc1421403d7610a0998fd"}, + {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dfbb2d460a855c9744bbc8e36f9c3a997c4b27d842f3d5559ed54326e6911f9b"}, + {file = "orjson-3.10.11-cp312-none-win32.whl", hash = "sha256:d4a62c49c506d4d73f59514986cadebb7e8d186ad510c518f439176cf8d5359d"}, + {file = "orjson-3.10.11-cp312-none-win_amd64.whl", hash = "sha256:f1eec3421a558ff7a9b010a6c7effcfa0ade65327a71bb9b02a1c3b77a247284"}, + {file = "orjson-3.10.11-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c46294faa4e4d0eb73ab68f1a794d2cbf7bab33b1dda2ac2959ffb7c61591899"}, + {file = "orjson-3.10.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52e5834d7d6e58a36846e059d00559cb9ed20410664f3ad156cd2cc239a11230"}, + {file = "orjson-3.10.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2fc947e5350fdce548bfc94f434e8760d5cafa97fb9c495d2fef6757aa02ec0"}, + {file = "orjson-3.10.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0efabbf839388a1dab5b72b5d3baedbd6039ac83f3b55736eb9934ea5494d258"}, + {file = "orjson-3.10.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3f29634260708c200c4fe148e42b4aae97d7b9fee417fbdd74f8cfc265f15b0"}, + {file = "orjson-3.10.11-cp313-none-win32.whl", hash = "sha256:1a1222ffcee8a09476bbdd5d4f6f33d06d0d6642df2a3d78b7a195ca880d669b"}, + {file = "orjson-3.10.11-cp313-none-win_amd64.whl", hash = "sha256:bc274ac261cc69260913b2d1610760e55d3c0801bb3457ba7b9004420b6b4270"}, + {file = "orjson-3.10.11-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:19b3763e8bbf8ad797df6b6b5e0fc7c843ec2e2fc0621398534e0c6400098f87"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1be83a13312e5e58d633580c5eb8d0495ae61f180da2722f20562974188af205"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:afacfd1ab81f46dedd7f6001b6d4e8de23396e4884cd3c3436bd05defb1a6446"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb4d0bea56bba596723d73f074c420aec3b2e5d7d30698bc56e6048066bd560c"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96ed1de70fcb15d5fed529a656df29f768187628727ee2788344e8a51e1c1350"}, + {file = "orjson-3.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bfb30c891b530f3f80e801e3ad82ef150b964e5c38e1fb8482441c69c35c61c"}, + {file = "orjson-3.10.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d496c74fc2b61341e3cefda7eec21b7854c5f672ee350bc55d9a4997a8a95204"}, + {file = "orjson-3.10.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:655a493bac606655db9a47fe94d3d84fc7f3ad766d894197c94ccf0c5408e7d3"}, + {file = "orjson-3.10.11-cp38-none-win32.whl", hash = "sha256:b9546b278c9fb5d45380f4809e11b4dd9844ca7aaf1134024503e134ed226161"}, + {file = "orjson-3.10.11-cp38-none-win_amd64.whl", hash = "sha256:b592597fe551d518f42c5a2eb07422eb475aa8cfdc8c51e6da7054b836b26782"}, + {file = "orjson-3.10.11-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c95f2ecafe709b4e5c733b5e2768ac569bed308623c85806c395d9cca00e08af"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80c00d4acded0c51c98754fe8218cb49cb854f0f7eb39ea4641b7f71732d2cb7"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:461311b693d3d0a060439aa669c74f3603264d4e7a08faa68c47ae5a863f352d"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52ca832f17d86a78cbab86cdc25f8c13756ebe182b6fc1a97d534051c18a08de"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c57ea78a753812f528178aa2f1c57da633754c91d2124cb28991dab4c79a54"}, + {file = "orjson-3.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7fcfc6f7ca046383fb954ba528587e0f9336828b568282b27579c49f8e16aad"}, + {file = "orjson-3.10.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:86b9dd983857970c29e4c71bb3e95ff085c07d3e83e7c46ebe959bac07ebd80b"}, + {file = "orjson-3.10.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4d83f87582d223e54efb2242a79547611ba4ebae3af8bae1e80fa9a0af83bb7f"}, + {file = "orjson-3.10.11-cp39-none-win32.whl", hash = "sha256:9fd0ad1c129bc9beb1154c2655f177620b5beaf9a11e0d10bac63ef3fce96950"}, + {file = "orjson-3.10.11-cp39-none-win_amd64.whl", hash = "sha256:10f416b2a017c8bd17f325fb9dee1fb5cdd7a54e814284896b7c3f2763faa017"}, + {file = "orjson-3.10.11.tar.gz", hash = "sha256:e35b6d730de6384d5b2dab5fd23f0d76fae8bbc8c353c2f78210aa5fa4beb3ef"}, ] [[package]] @@ -1131,6 +1116,36 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "psutil" +version = "6.1.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, +] + +[package.extras] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + [[package]] name = "py" version = "1.11.0" @@ -1488,105 +1503,105 @@ files = [ [[package]] name = "regex" -version = "2024.9.11" +version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" files = [ - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, - {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, - {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, - {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, - {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, - {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, - {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, - {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, - {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, - {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, - {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, - {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, - {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, - {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, - {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, - {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, - {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, - {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, - {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, - {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, - {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, - {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, - {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, - {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, - {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, - {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, - {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, - {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, - {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, - {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, - {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, - {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, ] [[package]] @@ -1729,23 +1744,23 @@ typing-extensions = "*" [[package]] name = "setuptools" -version = "75.2.0" +version = "75.3.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, - {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, + {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, + {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, ] [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] [[package]] name = "six" @@ -1797,13 +1812,13 @@ files = [ [[package]] name = "tqdm" -version = "4.66.6" +version = "4.67.0" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63"}, - {file = "tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090"}, + {file = "tqdm-4.67.0-py3-none-any.whl", hash = "sha256:0cd8af9d56911acab92182e88d763100d4788bdf421d251616040cc4d44863be"}, + {file = "tqdm-4.67.0.tar.gz", hash = "sha256:fe5a6f95e6fe0b9755e9469b77b9c3cf850048224ecaa8293d7d2d31f97d869a"}, ] [package.dependencies] @@ -1811,6 +1826,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +discord = ["requests"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] @@ -1975,4 +1991,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.10,<3.12" -content-hash = "6605e05cbdfd8379707277ab56130a2e45238e6135c654318e904d91c8d6470c" +content-hash = "cf6708d9dafb7ef8fe0ce59fbce7477a49ea46b1f729de171ee49a732342cbae" diff --git a/airbyte-integrations/connectors/source-zendesk-support/pyproject.toml b/airbyte-integrations/connectors/source-zendesk-support/pyproject.toml index 386ac0c56af9..20928f1debee 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/pyproject.toml +++ b/airbyte-integrations/connectors/source-zendesk-support/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "4.3.3" +version = "4.4.1" name = "source-zendesk-support" description = "Source implementation for Zendesk Support." authors = [ "Airbyte ",] @@ -17,7 +17,7 @@ include = "source_zendesk_support" [tool.poetry.dependencies] python = "^3.10,<3.12" -airbyte-cdk = "^5" +airbyte-cdk = "^6" pytz = "==2024.1" [tool.poetry.scripts] diff --git a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/components.py b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/components.py index 1f631c62a130..4d205ed5e83b 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/components.py +++ b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/components.py @@ -4,6 +4,7 @@ from typing import Any, List, Mapping, MutableMapping, Optional import requests + from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor from airbyte_cdk.sources.declarative.incremental import DatetimeBasedCursor from airbyte_cdk.sources.declarative.requesters.request_option import RequestOptionType @@ -33,7 +34,9 @@ def get_request_params( start_time = stream_slice.get(self._partition_field_start.eval(self.config)) options[self.start_time_option.field_name.eval(config=self.config)] = [start_time] # type: ignore # field_name is always casted to an interpolated string if self.end_time_option and self.end_time_option.inject_into == option_type: - options[self.end_time_option.field_name.eval(config=self.config)].append(stream_slice.get(self._partition_field_end.eval(self.config))) # type: ignore # field_name is always casted to an interpolated string + options[self.end_time_option.field_name.eval(config=self.config)].append( + stream_slice.get(self._partition_field_end.eval(self.config)) + ) # type: ignore # field_name is always casted to an interpolated string return options diff --git a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/manifest.yaml b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/manifest.yaml index 3a12f65c0549..6b4d38aee3b8 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/manifest.yaml +++ b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/manifest.yaml @@ -78,7 +78,7 @@ definitions: record_selector: $ref: "#/definitions/retriever/record_selector" record_filter: - condition: "{{ record[parameters['cursor_field']] >= stream_state.get(parameters['cursor_field'], config.get('start_date')) }}" + condition: "{{ record[parameters['cursor_field']] >= stream_interval.get('start_time', config.get('start_date')) }}" incremental_sync: type: DatetimeBasedCursor cursor_datetime_formats: @@ -87,7 +87,7 @@ definitions: datetime_format: "%Y-%m-%dT%H:%M:%SZ" cursor_field: "{{ parameters.get('cursor_field', 'updated_at') }}" start_datetime: - datetime: "{{ config.get('start_date') }}" + datetime: "{{ config.get('start_date') or day_delta(-730, '%Y-%m-%dT%H:%M:%SZ') }}" cursor_incremental_sync: type: DatetimeBasedCursor @@ -98,7 +98,7 @@ definitions: datetime_format: "%s" cursor_field: "{{ parameters.get('cursor_field', 'updated_at') }}" start_datetime: - datetime: "{{ timestamp(config.get('start_date')) | int or day_delta(-730, '%Y-%m-%dT%H:%M:%SZ') }}" + datetime: "{{ timestamp(config.get('start_date')) | int if config.get('start_date') else day_delta(-730, '%s') }}" start_time_option: inject_into: request_parameter field_name: "{{ parameters['cursor_filter'] }}" @@ -617,3 +617,16 @@ streams: - $ref: "#/definitions/ticket_skips_stream" - $ref: "#/definitions/triggers_stream" - $ref: "#/definitions/users_stream" + +# Zendesk Support offers four tiers of rate limits: +# - Team: 200 req/min (3.3 req/sec) +# - Professional: 400 req/min (6.7 req/sec) +# - Enterprise: 700 req/min (11.7 req/sec) +# - High Volume API add-on: 2500 req/min (41.7 req/sec) +# +# We use defer to a level of 3 because we assume by default that customers are on the Team tier, but +# customers can specify a higher concurrency level as needed up to the theoretical max rate limit. +concurrency_level: + type: ConcurrencyLevel + default_concurrency: "{{ config.get('num_workers', 3) }}" + max_concurrency: 40 diff --git a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/run.py b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/run.py index 95b88323a18c..d040b0f77975 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/run.py +++ b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/run.py @@ -1,14 +1,54 @@ # -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. # - import sys +import traceback +from datetime import datetime +from typing import List + +from orjson import orjson -from airbyte_cdk.entrypoint import launch +from airbyte_cdk.entrypoint import AirbyteEntrypoint, launch, logger +from airbyte_cdk.exception_handler import init_uncaught_exception_handler +from airbyte_cdk.models import AirbyteErrorTraceMessage, AirbyteMessage, AirbyteMessageSerializer, AirbyteTraceMessage, TraceType, Type from source_zendesk_support import SourceZendeskSupport -def run(): - source = SourceZendeskSupport() - launch(source, sys.argv[1:]) +def _get_source(args: List[str]): + catalog_path = AirbyteEntrypoint.extract_catalog(args) + config_path = AirbyteEntrypoint.extract_config(args) + state_path = AirbyteEntrypoint.extract_state(args) + try: + return SourceZendeskSupport( + SourceZendeskSupport.read_catalog(catalog_path) if catalog_path else None, + SourceZendeskSupport.read_config(config_path) if config_path else None, + SourceZendeskSupport.read_state(state_path) if state_path else None, + ) + except Exception as error: + print( + orjson.dumps( + AirbyteMessageSerializer.dump( + AirbyteMessage( + type=Type.TRACE, + trace=AirbyteTraceMessage( + type=TraceType.ERROR, + emitted_at=int(datetime.now().timestamp() * 1000), + error=AirbyteErrorTraceMessage( + message=f"Error starting the sync. This could be due to an invalid configuration or catalog. Please contact Support for assistance. Error: {error}", + stack_trace=traceback.format_exc(), + ), + ), + ) + ) + ).decode() + ) + return None + + +def run() -> None: + init_uncaught_exception_handler(logger) + _args = sys.argv[1:] + source = _get_source(_args) + if source: + launch(source, _args) diff --git a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/source.py b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/source.py index 3e0ebfcd7577..f7d4746facf6 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/source.py +++ b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/source.py @@ -2,15 +2,16 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # - import base64 import logging from datetime import datetime -from typing import Any, List, Mapping, Tuple +from typing import Any, List, Mapping, Optional, Tuple import pendulum -from airbyte_cdk.models import SyncMode + +from airbyte_cdk.models import ConfiguredAirbyteCatalog, SyncMode from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource +from airbyte_cdk.sources.source import TState from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator from source_zendesk_support.streams import DATETIME_FORMAT, ZendeskConfigException @@ -29,6 +30,7 @@ UserSettingsStream, ) + logger = logging.getLogger("airbyte") @@ -43,8 +45,8 @@ def __init__(self, email: str, password: str): class SourceZendeskSupport(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) + def __init__(self, catalog: Optional[ConfiguredAirbyteCatalog], config: Optional[Mapping[str, Any]], state: TState, **kwargs): + super().__init__(catalog=catalog, config=config, state=state, **{"path_to_yaml": "manifest.yaml"}) @classmethod def get_default_start_date(cls) -> str: @@ -63,11 +65,6 @@ def get_default_start_date(cls) -> str: @classmethod def get_authenticator(cls, config: Mapping[str, Any]) -> [TokenAuthenticator, BasicApiTokenAuthenticator]: - # old authentication flow support - auth_old = config.get("auth_method") - if auth_old: - if auth_old.get("auth_method") == "api_token": - return BasicApiTokenAuthenticator(config["auth_method"]["email"], config["auth_method"]["api_token"]) # new authentication flow auth = config.get("credentials") if auth: @@ -88,8 +85,8 @@ def check_connection(self, logger, config) -> Tuple[bool, any]: """ auth = self.get_authenticator(config) try: - datetime.strptime(config["start_date"], DATETIME_FORMAT) - settings = UserSettingsStream(config["subdomain"], authenticator=auth, start_date=None).get_settings() + start_date = datetime.strptime(config["start_date"], DATETIME_FORMAT) if config["start_date"] else None + settings = UserSettingsStream(config["subdomain"], authenticator=auth, start_date=start_date).get_settings() except Exception as e: return False, e active_features = [k for k, v in settings.get("active_features", {}).items() if v] @@ -113,19 +110,6 @@ def convert_config2stream_args(cls, config: Mapping[str, Any]) -> Mapping[str, A "ignore_pagination": config.get("ignore_pagination", False), } - @classmethod - def convert_config_to_declarative_stream_args(cls, config: Mapping[str, Any]) -> Mapping[str, Any]: - """Convert input configs to parameters of the future streams - This function is used by unit tests too - """ - return { - "subdomain": config["subdomain"], - "start_date": config.get("start_date", cls.get_default_start_date()), - "auth_type": config.get("auth_type"), - "credentials": config.get("credentials"), - "ignore_pagination": config.get("ignore_pagination", False), - } - def get_nested_streams(self, config: Mapping[str, Any]) -> List[Stream]: """Returns relevant a list of available streams :param config: A Mapping of the user input configuration as defined in the connector spec. @@ -172,8 +156,7 @@ def check_enterprise_streams(self, declarative_streams: List[Stream]) -> List[St return all_streams def streams(self, config: Mapping[str, Any]) -> List[Stream]: - args = self.convert_config_to_declarative_stream_args(config) - declarative_streams = super().streams(args) + declarative_streams = super().streams(config) nested_streams = self.get_nested_streams(config) declarative_streams.extend(nested_streams) diff --git a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/spec.json b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/spec.json index a90fb7bf6fc5..7d87423fef1c 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/spec.json +++ b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/spec.json @@ -92,6 +92,16 @@ "description": "Makes each stream read a single page of data.", "title": "Should the connector read the second and further pages of data.", "airbyte_hidden": true + }, + "num_workers": { + "type": "integer", + "title": "Number of concurrent workers", + "minimum": 1, + "maximum": 40, + "default": 3, + "examples": [1, 2, 3], + "description": "The number of worker threads to use for the sync. The performance upper boundary is based on the limit of your Zendesk Support plan. More info about the rate limit plan tiers can be found on Zendesk's API docs.", + "order": 3 } } }, diff --git a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/streams.py b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/streams.py index 911c090f5545..8cc0026bd99f 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/streams.py +++ b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/streams.py @@ -13,6 +13,7 @@ import pendulum import pytz import requests + from airbyte_cdk import BackoffStrategy from airbyte_cdk.models import FailureType, SyncMode from airbyte_cdk.sources.declarative.migrations.state_migration import StateMigration @@ -24,6 +25,7 @@ from airbyte_cdk.sources.utils.transform import TransformConfig, TypeTransformer from airbyte_cdk.utils import AirbyteTracedException + DATETIME_FORMAT: str = "%Y-%m-%dT%H:%M:%SZ" LAST_END_TIME_KEY: str = "_last_end_time" END_OF_STREAM_KEY: str = "end_of_stream" @@ -518,7 +520,6 @@ def migrate(self, stream_state: Optional[Mapping[str, Any]]) -> Mapping[str, Any class TicketMetrics(SourceZendeskSupportStream): - name = "ticket_metrics" cursor_field = "_ab_updated_at" should_checkpoint = False @@ -583,7 +584,6 @@ def parse_response(self, response: requests.Response, stream_state: Mapping[str, class StatelessTicketMetrics(FullRefreshZendeskSupportStream): - response_list_name: str = "ticket_metrics" cursor_field: str = "updated_at" should_checkpoint = False @@ -631,7 +631,6 @@ def _get_updated_state(self, current_stream_state: Mapping[str, Any], latest_rec class StatefulTicketMetrics(HttpSubStream, IncrementalZendeskSupportStream): - response_list_name: str = "ticket_metric" _state_cursor_field: str = "_ab_updated_at" _legacy_cursor_field: str = "generated_timestamp" diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/conftest.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/conftest.py index c3d9c1c98188..27703dc2ddbb 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/conftest.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/conftest.py @@ -2,4 +2,5 @@ import os + os.environ["REQUEST_CACHE_PATH"] = "REQUEST_CACHE_PATH" diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/helpers.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/helpers.py index d1e58cacec0e..a2f658a70079 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/helpers.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/helpers.py @@ -1,15 +1,34 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. -from typing import Optional + +import pendulum +from pendulum.datetime import DateTime from airbyte_cdk.test.mock_http import HttpMocker from airbyte_cdk.test.mock_http.response_builder import FieldPath -from pendulum.datetime import DateTime from .utils import datetime_to_string -from .zs_requests import PostsCommentsRequestBuilder, PostsRequestBuilder, TicketFormsRequestBuilder, TicketsRequestBuilder +from .zs_requests import ( + GroupsRequestBuilder, + PostsCommentsRequestBuilder, + PostsRequestBuilder, + TicketFormsRequestBuilder, + TicketsRequestBuilder, +) from .zs_requests.request_authenticators import ApiTokenAuthenticator -from .zs_responses import PostsCommentsResponseBuilder, PostsResponseBuilder, TicketFormsResponseBuilder, TicketsResponseBuilder -from .zs_responses.records import PostsCommentsRecordBuilder, PostsRecordBuilder, TicketFormsRecordBuilder, TicketsRecordBuilder +from .zs_responses import ( + GroupsResponseBuilder, + PostsCommentsResponseBuilder, + PostsResponseBuilder, + TicketFormsResponseBuilder, + TicketsResponseBuilder, +) +from .zs_responses.records import ( + GroupsRecordBuilder, + PostsCommentsRecordBuilder, + PostsRecordBuilder, + TicketFormsRecordBuilder, + TicketsRecordBuilder, +) def given_ticket_forms( @@ -63,30 +82,51 @@ def given_post_comments( ) return post_comments_record_builder + def given_tickets(http_mocker: HttpMocker, start_date: DateTime, api_token_authenticator: ApiTokenAuthenticator) -> TicketsRecordBuilder: """ Tickets requests setup """ - tickets_record_builder = TicketsRecordBuilder.tickets_record().with_field( - FieldPath("generated_timestamp"), start_date.int_timestamp - ) + tickets_record_builder = TicketsRecordBuilder.tickets_record().with_field(FieldPath("generated_timestamp"), start_date.int_timestamp) http_mocker.get( - TicketsRequestBuilder.tickets_endpoint(api_token_authenticator) - .with_start_time(start_date.int_timestamp) - .build(), + TicketsRequestBuilder.tickets_endpoint(api_token_authenticator).with_start_time(start_date.int_timestamp).build(), TicketsResponseBuilder.tickets_response().with_record(tickets_record_builder).build(), ) return tickets_record_builder -def given_tickets_with_state(http_mocker: HttpMocker, start_date: DateTime, cursor_value: DateTime, api_token_authenticator: ApiTokenAuthenticator) -> TicketsRecordBuilder: + +def given_tickets_with_state( + http_mocker: HttpMocker, start_date: DateTime, cursor_value: DateTime, api_token_authenticator: ApiTokenAuthenticator +) -> TicketsRecordBuilder: """ Tickets requests setup """ tickets_record_builder = TicketsRecordBuilder.tickets_record().with_cursor(cursor_value.int_timestamp) http_mocker.get( - TicketsRequestBuilder.tickets_endpoint(api_token_authenticator) - .with_start_time(start_date.int_timestamp) - .build(), + TicketsRequestBuilder.tickets_endpoint(api_token_authenticator).with_start_time(start_date.int_timestamp).build(), TicketsResponseBuilder.tickets_response().with_record(tickets_record_builder).build(), ) return tickets_record_builder + + +def given_groups_with_later_records( + http_mocker: HttpMocker, + updated_at_value: DateTime, + later_record_time_delta: pendulum.duration, + api_token_authenticator: ApiTokenAuthenticator, +) -> GroupsRecordBuilder: + """ + Creates two group records one with a specific cursor value and one that has a later cursor value based on the + provided timedelta. This is intended to create multiple records with different times which can be used to + test functionality like semi-incremental record filtering + """ + groups_record_builder = GroupsRecordBuilder.groups_record().with_field(FieldPath("updated_at"), datetime_to_string(updated_at_value)) + + later_groups_record_builder = GroupsRecordBuilder.groups_record().with_field( + FieldPath("updated_at"), datetime_to_string(updated_at_value + later_record_time_delta) + ) + http_mocker.get( + GroupsRequestBuilder.groups_endpoint(api_token_authenticator).with_page_size(100).build(), + GroupsResponseBuilder.groups_response().with_record(groups_record_builder).with_record(later_groups_record_builder).build(), + ) + return groups_record_builder diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_groups.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_groups.py new file mode 100644 index 000000000000..e672521e1501 --- /dev/null +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_groups.py @@ -0,0 +1,72 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + +from datetime import datetime, timezone +from unittest import TestCase + +import pendulum + +from airbyte_cdk.models import SyncMode +from airbyte_cdk.test.mock_http import HttpMocker +from airbyte_cdk.test.state_builder import StateBuilder + +from .config import ConfigBuilder +from .helpers import given_groups_with_later_records +from .utils import datetime_to_string, read_stream, string_to_datetime +from .zs_requests.request_authenticators import ApiTokenAuthenticator + + +_NOW = datetime.now(timezone.utc) + + +class TestGroupsStreamFullRefresh(TestCase): + @property + def _config(self): + return ( + ConfigBuilder() + .with_basic_auth_credentials("user@example.com", "password") + .with_subdomain("d3v-airbyte") + .with_start_date(pendulum.now(tz="UTC").subtract(years=2)) + .build() + ) + + @staticmethod + def get_authenticator(config): + return ApiTokenAuthenticator(email=config["credentials"]["email"], password=config["credentials"]["api_token"]) + + @HttpMocker() + def test_given_incoming_state_semi_incremental_groups_does_not_emit_earlier_record(self, http_mocker): + """ + Perform a semi-incremental sync where records that came before the current state are not included in the set + of records emitted + """ + api_token_authenticator = self.get_authenticator(self._config) + given_groups_with_later_records( + http_mocker, + string_to_datetime(self._config["start_date"]), + pendulum.duration(weeks=12), + api_token_authenticator, + ) + + output = read_stream("groups", SyncMode.full_refresh, self._config) + assert len(output.records) == 2 + + @HttpMocker() + def test_given_incoming_state_semi_incremental_groups_does_not_emit_earlier_record(self, http_mocker): + """ + Perform a semi-incremental sync where records that came before the current state are not included in the set + of records emitted + """ + api_token_authenticator = self.get_authenticator(self._config) + given_groups_with_later_records( + http_mocker, + string_to_datetime(self._config["start_date"]), + pendulum.duration(weeks=12), + api_token_authenticator, + ) + + state_value = {"updated_at": datetime_to_string(pendulum.now(tz="UTC").subtract(years=1, weeks=50))} + + state = StateBuilder().with_stream_state("groups", state_value).build() + + output = read_stream("groups", SyncMode.full_refresh, self._config, state=state) + assert len(output.records) == 1 diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_post_comment_votes.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_post_comment_votes.py index ffe141cdfcb4..1755a17c7f6e 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_post_comment_votes.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_post_comment_votes.py @@ -6,9 +6,9 @@ import freezegun import pendulum -from airbyte_cdk.models import AirbyteStateBlob + +from airbyte_cdk.models import AirbyteStateBlob, SyncMode from airbyte_cdk.models import Level as LogLevel -from airbyte_cdk.models import SyncMode from airbyte_cdk.test.mock_http import HttpMocker from airbyte_cdk.test.mock_http.response_builder import FieldPath from airbyte_cdk.test.state_builder import StateBuilder @@ -21,6 +21,7 @@ from .zs_responses import ErrorResponseBuilder, PostCommentVotesResponseBuilder from .zs_responses.records import PostCommentVotesRecordBuilder + _NOW = datetime.now(timezone.utc) @@ -96,7 +97,13 @@ def test_given_403_error_when_read_posts_comments_then_skip_stream(self, http_mo assert len(output.records) == 0 info_logs = get_log_messages_by_log_level(output.logs, LogLevel.INFO) - assert any(["Forbidden. Please ensure the authenticated user has access to this stream. If the issue persists, contact Zendesk support." in error for error in info_logs]) + assert any( + [ + "Forbidden. Please ensure the authenticated user has access to this stream. If the issue persists, contact Zendesk support." + in error + for error in info_logs + ] + ) @HttpMocker() def test_given_404_error_when_read_posts_comments_then_skip_stream(self, http_mocker): @@ -126,7 +133,13 @@ def test_given_404_error_when_read_posts_comments_then_skip_stream(self, http_mo assert len(output.records) == 0 info_logs = get_log_messages_by_log_level(output.logs, LogLevel.INFO) - assert any(["Not found. Please ensure the authenticated user has access to this stream. If the issue persists, contact Zendesk support." in error for error in info_logs]) + assert any( + [ + "Not found. Please ensure the authenticated user has access to this stream. If the issue persists, contact Zendesk support." + in error + for error in info_logs + ] + ) @HttpMocker() def test_given_500_error_when_read_posts_comments_then_stop_syncing(self, http_mocker): diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_post_comments.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_post_comments.py index a9d2d825c5bb..a2d140bcf2c3 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_post_comments.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_post_comments.py @@ -6,9 +6,9 @@ import freezegun import pendulum -from airbyte_cdk.models import AirbyteStateBlob + +from airbyte_cdk.models import AirbyteStateBlob, SyncMode from airbyte_cdk.models import Level as LogLevel -from airbyte_cdk.models import SyncMode from airbyte_cdk.test.mock_http import HttpMocker from airbyte_cdk.test.mock_http.response_builder import FieldPath from airbyte_cdk.test.state_builder import StateBuilder @@ -21,6 +21,7 @@ from .zs_responses import ErrorResponseBuilder, PostsCommentsResponseBuilder from .zs_responses.records import PostsCommentsRecordBuilder + _NOW = datetime.now(timezone.utc) @@ -84,7 +85,13 @@ def test_given_403_error_when_read_posts_comments_then_skip_stream(self, http_mo assert len(output.records) == 0 info_logs = get_log_messages_by_log_level(output.logs, LogLevel.INFO) - assert any(["Forbidden. Please ensure the authenticated user has access to this stream. If the issue persists, contact Zendesk support." in error for error in info_logs]) + assert any( + [ + "Forbidden. Please ensure the authenticated user has access to this stream. If the issue persists, contact Zendesk support." + in error + for error in info_logs + ] + ) @HttpMocker() def test_given_404_error_when_read_posts_comments_then_skip_stream(self, http_mocker): @@ -109,7 +116,13 @@ def test_given_404_error_when_read_posts_comments_then_skip_stream(self, http_mo assert len(output.records) == 0 info_logs = get_log_messages_by_log_level(output.logs, LogLevel.INFO) - assert any(["Not found. Please ensure the authenticated user has access to this stream. If the issue persists, contact Zendesk support." in error for error in info_logs]) + assert any( + [ + "Not found. Please ensure the authenticated user has access to this stream. If the issue persists, contact Zendesk support." + in error + for error in info_logs + ] + ) @HttpMocker() def test_given_500_error_when_read_posts_comments_then_stop_syncing(self, http_mocker): diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_post_votes.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_post_votes.py index a2617b5a07df..8ca10b18980d 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_post_votes.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_post_votes.py @@ -6,9 +6,9 @@ import freezegun import pendulum -from airbyte_cdk.models import AirbyteStateBlob + +from airbyte_cdk.models import AirbyteStateBlob, SyncMode from airbyte_cdk.models import Level as LogLevel -from airbyte_cdk.models import SyncMode from airbyte_cdk.test.mock_http import HttpMocker from airbyte_cdk.test.mock_http.response_builder import FieldPath from airbyte_cdk.test.state_builder import StateBuilder @@ -21,6 +21,7 @@ from .zs_responses import ErrorResponseBuilder, PostsVotesResponseBuilder from .zs_responses.records import PostsVotesRecordBuilder + _NOW = datetime.now(timezone.utc) @@ -84,7 +85,13 @@ def test_given_403_error_when_read_posts_comments_then_skip_stream(self, http_mo assert len(output.records) == 0 info_logs = get_log_messages_by_log_level(output.logs, LogLevel.INFO) - assert any(["Forbidden. Please ensure the authenticated user has access to this stream. If the issue persists, contact Zendesk support." in error for error in info_logs]) + assert any( + [ + "Forbidden. Please ensure the authenticated user has access to this stream. If the issue persists, contact Zendesk support." + in error + for error in info_logs + ] + ) @HttpMocker() def test_given_404_error_when_read_posts_comments_then_skip_stream(self, http_mocker): @@ -109,7 +116,13 @@ def test_given_404_error_when_read_posts_comments_then_skip_stream(self, http_mo assert len(output.records) == 0 info_logs = get_log_messages_by_log_level(output.logs, LogLevel.INFO) - assert any(["Not found. Please ensure the authenticated user has access to this stream. If the issue persists, contact Zendesk support." in error for error in info_logs]) + assert any( + [ + "Not found. Please ensure the authenticated user has access to this stream. If the issue persists, contact Zendesk support." + in error + for error in info_logs + ] + ) @HttpMocker() def test_given_500_error_when_read_posts_comments_then_stop_syncing(self, http_mocker): diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_ticket_metrics.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_ticket_metrics.py index 699d09742f5d..c5e2dda402cd 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_ticket_metrics.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/test_ticket_metrics.py @@ -4,6 +4,7 @@ import freezegun import pendulum + from airbyte_cdk.models.airbyte_protocol import AirbyteStateBlob, SyncMode from airbyte_cdk.test.mock_http import HttpMocker from airbyte_cdk.test.mock_http.response_builder import FieldPath @@ -17,20 +18,21 @@ from .zs_responses import TicketMetricsResponseBuilder from .zs_responses.records import TicketMetricsRecordBuilder + _NOW = pendulum.now(tz="UTC") _TWO_YEARS_AGO_DATETIME = _NOW.subtract(years=2) + @freezegun.freeze_time(_NOW.isoformat()) class TestTicketMetricsIncremental(TestCase): - @property def _config(self): return ( ConfigBuilder() - .with_basic_auth_credentials("user@example.com", "password") - .with_subdomain("d3v-airbyte") - .with_start_date(_TWO_YEARS_AGO_DATETIME) - .build() + .with_basic_auth_credentials("user@example.com", "password") + .with_subdomain("d3v-airbyte") + .with_start_date(_TWO_YEARS_AGO_DATETIME) + .build() ) def _get_authenticator(self, config): @@ -46,7 +48,7 @@ def test_given_no_state_and_successful_sync_when_read_then_set_state_to_most_rec http_mocker.get( TicketMetricsRequestBuilder.stateless_ticket_metrics_endpoint(api_token_authenticator).with_page_size(100).build(), - TicketMetricsResponseBuilder.stateless_ticket_metrics_response().with_record(ticket_metrics_record_builder).build() + TicketMetricsResponseBuilder.stateless_ticket_metrics_response().with_record(ticket_metrics_record_builder).build(), ) output = read_stream("ticket_metrics", SyncMode.incremental, self._config, state) @@ -55,7 +57,6 @@ def test_given_no_state_and_successful_sync_when_read_then_set_state_to_most_rec assert output.most_recent_state.stream_descriptor.name == "ticket_metrics" assert output.most_recent_state.stream_state.__dict__ == {"_ab_updated_at": pendulum.parse(record_updated_at).int_timestamp} - @HttpMocker() def test_given_state_and_successful_sync_when_read_then_return_record(self, http_mocker): api_token_authenticator = self._get_authenticator(self._config) @@ -63,16 +64,20 @@ def test_given_state_and_successful_sync_when_read_then_return_record(self, http state_cursor_value = pendulum.now(tz="UTC").subtract(days=2).int_timestamp state = StateBuilder().with_stream_state("ticket_metrics", state={"_ab_updated_at": state_cursor_value}).build() record_cursor_value = pendulum.now(tz="UTC").subtract(days=1) - tickets_records_builder = given_tickets_with_state(http_mocker, pendulum.from_timestamp(state_cursor_value), record_cursor_value,api_token_authenticator) + tickets_records_builder = given_tickets_with_state( + http_mocker, pendulum.from_timestamp(state_cursor_value), record_cursor_value, api_token_authenticator + ) ticket = tickets_records_builder.build() - ticket_metrics_first_record_builder = TicketMetricsRecordBuilder.stateful_ticket_metrics_record().with_field( - FieldPath("ticket_id"), ticket["id"] - ).with_cursor(ticket["generated_timestamp"]) + ticket_metrics_first_record_builder = ( + TicketMetricsRecordBuilder.stateful_ticket_metrics_record() + .with_field(FieldPath("ticket_id"), ticket["id"]) + .with_cursor(ticket["generated_timestamp"]) + ) http_mocker.get( TicketMetricsRequestBuilder.stateful_ticket_metrics_endpoint(api_token_authenticator, ticket["id"]).build(), - TicketMetricsResponseBuilder.stateful_ticket_metrics_response().with_record(ticket_metrics_first_record_builder).build() + TicketMetricsResponseBuilder.stateful_ticket_metrics_response().with_record(ticket_metrics_first_record_builder).build(), ) output = read_stream("ticket_metrics", SyncMode.incremental, self._config, state) diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/utils.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/utils.py index 6d78dac568ce..aa19dc6ef9ca 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/utils.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/utils.py @@ -4,20 +4,24 @@ from typing import Any, Dict, List, Optional import pendulum -from airbyte_cdk.models import AirbyteMessage +from pendulum.datetime import DateTime +from source_zendesk_support import SourceZendeskSupport + +from airbyte_cdk.models import AirbyteMessage, AirbyteStateMessage, SyncMode from airbyte_cdk.models import Level as LogLevel -from airbyte_cdk.models import SyncMode from airbyte_cdk.test.catalog_builder import CatalogBuilder from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read -from pendulum.datetime import DateTime -from source_zendesk_support import SourceZendeskSupport def read_stream( - stream_name: str, sync_mode: SyncMode, config: Dict[str, Any], state: Optional[Dict[str, Any]] = None, expecting_exception: bool = False + stream_name: str, + sync_mode: SyncMode, + config: Dict[str, Any], + state: Optional[List[AirbyteStateMessage]] = None, + expecting_exception: bool = False, ) -> EntrypointOutput: catalog = CatalogBuilder().with_stream(stream_name, sync_mode).build() - return read(SourceZendeskSupport(), config, catalog, state, expecting_exception) + return read(SourceZendeskSupport(config=config, catalog=catalog, state=state), config, catalog, state, expecting_exception) def get_log_messages_by_log_level(logs: List[AirbyteMessage], log_level: LogLevel) -> List[str]: diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_requests/__init__.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_requests/__init__.py index 173f4f0da864..e6e1364e041c 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_requests/__init__.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_requests/__init__.py @@ -1,3 +1,4 @@ +from .groups_request_builder import GroupsRequestBuilder from .post_comment_votes_request_builder import PostCommentVotesRequestBuilder from .post_comments_request_builder import PostsCommentsRequestBuilder from .post_votes_request_builder import PostsVotesRequestBuilder diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_requests/base_request_builder.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_requests/base_request_builder.py index a185dd225a2f..8d72e988f203 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_requests/base_request_builder.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_requests/base_request_builder.py @@ -30,12 +30,7 @@ def request_body(self) -> Optional[str]: """A request body""" def build(self) -> HttpRequest: - return HttpRequest( - url=self.url, - query_params=self.query_params, - headers=self.headers, - body=self.request_body - ) + return HttpRequest(url=self.url, query_params=self.query_params, headers=self.headers, body=self.request_body) class ZendeskSupportBaseRequestBuilder(ZendeskSuppportRequestBuilder): diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_requests/groups_request_builder.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_requests/groups_request_builder.py new file mode 100644 index 000000000000..f4dc2d140848 --- /dev/null +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_requests/groups_request_builder.py @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + +import calendar + +import pendulum + +from .base_request_builder import ZendeskSupportBaseRequestBuilder +from .request_authenticators.authenticator import Authenticator + + +class GroupsRequestBuilder(ZendeskSupportBaseRequestBuilder): + @classmethod + def groups_endpoint(cls, authenticator: Authenticator) -> "GroupsRequestBuilder": + return cls("d3v-airbyte", "groups").with_authenticator(authenticator) + + def __init__(self, subdomain: str, resource: str) -> None: + super().__init__(subdomain, resource) + self._page_size: int = None + + @property + def query_params(self): + params = super().query_params or {} + if self._page_size: + params["per_page"] = self._page_size + return params + + def with_page_size(self, page_size: int) -> "PostCommentVotesRequestBuilder": + self._page_size: int = page_size + return self diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_requests/post_comment_votes_request_builder.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_requests/post_comment_votes_request_builder.py index 3d224cd79456..94629bb15526 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_requests/post_comment_votes_request_builder.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_requests/post_comment_votes_request_builder.py @@ -10,7 +10,9 @@ class PostCommentVotesRequestBuilder(ZendeskSupportBaseRequestBuilder): @classmethod - def post_comment_votes_endpoint(cls, authenticator: Authenticator, post_id: int, post_comment_id: int) -> "PostCommentVotesRequestBuilder": + def post_comment_votes_endpoint( + cls, authenticator: Authenticator, post_id: int, post_comment_id: int + ) -> "PostCommentVotesRequestBuilder": return cls("d3v-airbyte", f"community/posts/{post_id}/comments/{post_comment_id}/votes").with_authenticator(authenticator) def __init__(self, subdomain: str, resource: str) -> None: diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_responses/__init__.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_responses/__init__.py index 9a9c0b2c4ce0..7d96aded7d7b 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_responses/__init__.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_responses/__init__.py @@ -1,4 +1,5 @@ from .error_response_builder import ErrorResponseBuilder +from .groups_response_builder import GroupsResponseBuilder from .post_comment_votes_response_builder import PostCommentVotesResponseBuilder from .post_comments_response_builder import PostsCommentsResponseBuilder from .post_votes_response_builder import PostsVotesResponseBuilder diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_responses/groups_response_builder.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_responses/groups_response_builder.py new file mode 100644 index 000000000000..370506ef5750 --- /dev/null +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_responses/groups_response_builder.py @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + +from airbyte_cdk.test.mock_http.response_builder import FieldPath, HttpResponseBuilder, find_template + +from .pagination_strategies import CursorBasedPaginationStrategy + + +class GroupsResponseBuilder(HttpResponseBuilder): + @classmethod + def groups_response(cls) -> "GroupsResponseBuilder": + return cls(find_template("groups", __file__), FieldPath("groups"), CursorBasedPaginationStrategy()) diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_responses/records/__init__.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_responses/records/__init__.py index 812d977bff4a..92b6f10167b7 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_responses/records/__init__.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_responses/records/__init__.py @@ -1,3 +1,4 @@ +from .groups_records_builder import GroupsRecordBuilder from .post_comment_votes_records_builder import PostCommentVotesRecordBuilder from .post_comments_records_builder import PostsCommentsRecordBuilder from .post_votes_records_builder import PostsVotesRecordBuilder diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_responses/records/groups_records_builder.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_responses/records/groups_records_builder.py new file mode 100644 index 000000000000..386ee2931e90 --- /dev/null +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/integrations/zs_responses/records/groups_records_builder.py @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Airbyte, Inc., all rights reserved. + +from airbyte_cdk.test.mock_http.response_builder import FieldPath, NestedPath + +from .records_builder import ZendeskSupportRecordBuilder + + +class GroupsRecordBuilder(ZendeskSupportRecordBuilder): + @classmethod + def groups_record(cls) -> "GroupsRecordBuilder": + record_template = cls.extract_record("groups", __file__, NestedPath(["groups", 0])) + return cls(record_template, FieldPath("id"), FieldPath("updated_at")) diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/resource/http/response/groups.json b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/resource/http/response/groups.json new file mode 100644 index 000000000000..1c6befed82c8 --- /dev/null +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/resource/http/response/groups.json @@ -0,0 +1,15 @@ +{ + "groups": [ + { + "created_at": "2024-11-20T00:00:00Z", + "default": true, + "deleted": false, + "description": "Employed", + "id": 3432, + "is_public": true, + "name": "Remote Employees", + "updated_at": "2024-11-20T00:00:00Z", + "url": "https://company.zendesk.com/api/v2/groups/3432.json" + } + ] +} diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/test_backoff_on_rate_limit.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/test_backoff_on_rate_limit.py index 29a84dd12dcc..adef1134aadb 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/test_backoff_on_rate_limit.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/test_backoff_on_rate_limit.py @@ -3,13 +3,14 @@ # -from typing import Dict +from typing import Dict, Optional import pytest import requests from source_zendesk_support.source import SourceZendeskSupport from source_zendesk_support.streams import Users + _ANY_ATTEMPT_COUNT = 10 @@ -24,7 +25,7 @@ def test_config(): def prepare_config(config: Dict): - return SourceZendeskSupport().convert_config2stream_args(config) + return SourceZendeskSupport(config=config, catalog=None, state=None).convert_config2stream_args(config) @pytest.mark.parametrize( diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/test_components.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/test_components.py index 6398c165cc46..c0b61a2d29f4 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/test_components.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/test_components.py @@ -4,13 +4,14 @@ import pytest import requests -from airbyte_cdk.sources.declarative.requesters.request_option import RequestOptionType from source_zendesk_support.components import ( ZendeskSupportAttributeDefinitionsExtractor, ZendeskSupportAuditLogsIncrementalSync, ZendeskSupportExtractorEvents, ) +from airbyte_cdk.sources.declarative.requesters.request_option import RequestOptionType + @pytest.mark.parametrize( "stream_state, stream_slice, next_page_token, expected_params", diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/unit_test.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/unit_test.py index 2d2863d5ffc1..7c84300b4d87 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/unit_test.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/unit_test.py @@ -16,8 +16,6 @@ import pytest import pytz import requests -from airbyte_cdk.models import SyncMode -from airbyte_cdk.sources.streams.http.error_handlers import ResponseAction from source_zendesk_support.source import BasicApiTokenAuthenticator, SourceZendeskSupport from source_zendesk_support.streams import ( DATETIME_FORMAT, @@ -65,6 +63,10 @@ from test_data.data import TICKET_EVENTS_STREAM_RESPONSE from utils import read_full_refresh +from airbyte_cdk.models import SyncMode +from airbyte_cdk.sources.streams.http.error_handlers import ResponseAction + + TICKET_SUBSTREAMS = [StatefulTicketMetrics] # prepared config @@ -81,13 +83,6 @@ "credentials": {"credentials": "api_token", "email": "integration-test@airbyte.io", "api_token": "api_token"}, } -# raw old config -TEST_OLD_CONFIG = { - "auth_method": {"auth_method": "api_token", "email": "integration-test@airbyte.io", "api_token": "api_token"}, - "subdomain": "sandbox", - "start_date": "2021-06-01T00:00:00Z", -} - TEST_CONFIG_WITHOUT_START_DATE = { "subdomain": "sandbox", "credentials": {"credentials": "api_token", "email": "integration-test@airbyte.io", "api_token": "api_token"}, @@ -144,13 +139,15 @@ def test_token_authenticator(): ids=["api_token", "oauth"], ) def test_convert_config2stream_args(config): - result = SourceZendeskSupport().convert_config2stream_args(config) + result = SourceZendeskSupport(config=config, catalog=None, state=None).convert_config2stream_args(config) assert "authenticator" in result @freezegun.freeze_time("2022-01-01") def test_default_start_date(): - result = SourceZendeskSupport().convert_config2stream_args(TEST_CONFIG_WITHOUT_START_DATE) + result = SourceZendeskSupport(config=TEST_CONFIG_WITHOUT_START_DATE, catalog=None, state=None).convert_config2stream_args( + TEST_CONFIG_WITHOUT_START_DATE + ) assert result["start_date"] == "2020-01-01T00:00:00Z" @@ -159,26 +156,25 @@ def test_default_start_date(): [ (TEST_CONFIG, "aW50ZWdyYXRpb24tdGVzdEBhaXJieXRlLmlvL3Rva2VuOmFwaV90b2tlbg=="), (TEST_CONFIG_OAUTH, "test_access_token"), - (TEST_OLD_CONFIG, "aW50ZWdyYXRpb24tdGVzdEBhaXJieXRlLmlvL3Rva2VuOmFwaV90b2tlbg=="), ], - ids=["api_token", "oauth", "old_config"], + ids=["api_token", "oauth"], ) def test_get_authenticator(config, expected): # we expect base64 from creds input - result = SourceZendeskSupport().get_authenticator(config=config) + result = SourceZendeskSupport(config=config, catalog=None, state=None).get_authenticator(config=config) assert result._token == expected @pytest.mark.parametrize( "response, start_date, check_passed", - [({"active_features": {"organization_access_enabled": True}}, "2020-01-01T00:00:00Z", True), ({}, "2020-01-00T00:00:00Z", False)], + [([{"active_features": {"organization_access_enabled": True}}], "2020-01-01T00:00:00Z", True), ([], "2020-01-01T00:00:00Z", False)], ids=["check_successful", "invalid_start_date"], ) def test_check(response, start_date, check_passed): config = copy.deepcopy(TEST_CONFIG) config["start_date"] = start_date - with patch.object(UserSettingsStream, "get_settings", return_value=response) as mock_method: - ok, _ = SourceZendeskSupport().check_connection(logger=logging.Logger, config=config) + with patch.object(UserSettingsStream, "read_records", return_value=response) as mock_method: + ok, _ = SourceZendeskSupport(config=config, catalog=None, state=None).check_connection(logger=logging.Logger, config=config) assert check_passed == ok if ok: mock_method.assert_called() @@ -211,7 +207,7 @@ def test_check(response, start_date, check_passed): ) def test_full_access_streams(caplog, requests_mock, ticket_forms_response, status_code, expected_n_streams, expected_warnings, reason): requests_mock.get("/api/v2/ticket_forms", status_code=status_code, text=ticket_forms_response, reason=reason) - result = SourceZendeskSupport().streams(config=TEST_CONFIG) + result = SourceZendeskSupport(config=TEST_CONFIG, catalog=None, state=None).streams(config=TEST_CONFIG) assert len(result) == expected_n_streams logged_warnings = (record for record in caplog.records if record.levelname == "WARNING") for msg in expected_warnings: @@ -285,7 +281,7 @@ class TestAllStreams: def test_ticket_forms_exception_stream(self): with patch.object(TicketForms, "read_records", return_value=[{}]) as mocked_records: mocked_records.side_effect = Exception("The error") - streams = SourceZendeskSupport().streams(TEST_CONFIG) + streams = SourceZendeskSupport(config=TEST_CONFIG, catalog=None, state=None).streams(TEST_CONFIG) assert not any([isinstance(stream, TicketForms) for stream in streams]) @pytest.mark.parametrize( @@ -1055,14 +1051,14 @@ def test_read_non_json_error(requests_mock, caplog): read_full_refresh(stream) assert expected_message in (record.message for record in caplog.records if record.levelname == "ERROR") -class TestTicketMetrics: +class TestTicketMetrics: @pytest.mark.parametrize( - "state, expected_implemented_stream", - [ - ({"_ab_updated_at": 1727334000}, StatefulTicketMetrics), - ({}, StatelessTicketMetrics), - ] + "state, expected_implemented_stream", + [ + ({"_ab_updated_at": 1727334000}, StatefulTicketMetrics), + ({}, StatelessTicketMetrics), + ], ) def test_get_implemented_stream(self, state, expected_implemented_stream): stream = get_stream_instance(TicketMetrics, STREAM_ARGS) @@ -1070,12 +1066,12 @@ def test_get_implemented_stream(self, state, expected_implemented_stream): assert isinstance(implemented_stream, expected_implemented_stream) @pytest.mark.parametrize( - "sync_mode, state, expected_implemented_stream", - [ - (SyncMode.incremental, {"_ab_updated_at": 1727334000}, StatefulTicketMetrics), - (SyncMode.full_refresh, {}, StatelessTicketMetrics), - (SyncMode.incremental, {}, StatelessTicketMetrics), - ] + "sync_mode, state, expected_implemented_stream", + [ + (SyncMode.incremental, {"_ab_updated_at": 1727334000}, StatefulTicketMetrics), + (SyncMode.full_refresh, {}, StatelessTicketMetrics), + (SyncMode.incremental, {}, StatelessTicketMetrics), + ], ) def test_stream_slices(self, sync_mode, state, expected_implemented_stream): stream = get_stream_instance(TicketMetrics, STREAM_ARGS) @@ -1089,7 +1085,12 @@ class TestStatefulTicketMetrics: [ ( {}, - {"tickets": [{"id": "13", "generated_timestamp": pendulum.parse(STREAM_ARGS["start_date"]).int_timestamp}, {"id": "80", "generated_timestamp": pendulum.parse(STREAM_ARGS["start_date"]).int_timestamp}]}, + { + "tickets": [ + {"id": "13", "generated_timestamp": pendulum.parse(STREAM_ARGS["start_date"]).int_timestamp}, + {"id": "80", "generated_timestamp": pendulum.parse(STREAM_ARGS["start_date"]).int_timestamp}, + ] + }, [ {"ticket_id": "13", "_ab_updated_at": pendulum.parse(STREAM_ARGS["start_date"]).int_timestamp}, {"ticket_id": "80", "_ab_updated_at": pendulum.parse(STREAM_ARGS["start_date"]).int_timestamp}, @@ -1116,8 +1117,7 @@ def test_stream_slices(self, requests_mock, stream_state, response, expected_sli def test_read_with_error(self, requests_mock): stream = get_stream_instance(StatefulTicketMetrics, STREAM_ARGS) requests_mock.get( - f"https://sandbox.zendesk.com/api/v2/tickets/13/metrics", - json={"error": "RecordNotFound", "description": "Not found"} + f"https://sandbox.zendesk.com/api/v2/tickets/13/metrics", json={"error": "RecordNotFound", "description": "Not found"} ) records = list(stream.read_records(sync_mode=SyncMode.full_refresh, stream_slice={"ticket_id": "13"})) @@ -1127,12 +1127,12 @@ def test_read_with_error(self, requests_mock): @pytest.mark.parametrize( "status_code, response_action", ( - (200, ResponseAction.SUCCESS), - (404, ResponseAction.IGNORE), - (403, ResponseAction.IGNORE), - (500, ResponseAction.RETRY), - (429, ResponseAction.RATE_LIMITED), - ) + (200, ResponseAction.SUCCESS), + (404, ResponseAction.IGNORE), + (403, ResponseAction.IGNORE), + (500, ResponseAction.RETRY), + (429, ResponseAction.RATE_LIMITED), + ), ) def test_should_retry(self, status_code: int, response_action: bool): stream = get_stream_instance(StatefulTicketMetrics, STREAM_ARGS) @@ -1143,37 +1143,62 @@ def test_should_retry(self, status_code: int, response_action: bool): @pytest.mark.parametrize( "current_stream_state, record_cursor_value, expected", [ - ({ "_ab_updated_at": 1727334000}, 1727420400, { "_ab_updated_at": 1727420400}), - ({ "_ab_updated_at": 1727334000}, 1700000000, { "_ab_updated_at": 1727334000}), - ] + ({"_ab_updated_at": 1727334000}, 1727420400, {"_ab_updated_at": 1727420400}), + ({"_ab_updated_at": 1727334000}, 1700000000, {"_ab_updated_at": 1727334000}), + ], ) def test_get_updated_state(self, current_stream_state, record_cursor_value, expected): stream = get_stream_instance(StatefulTicketMetrics, STREAM_ARGS) - latest_record = { "id": 1, "_ab_updated_at": record_cursor_value} + latest_record = {"id": 1, "_ab_updated_at": record_cursor_value} output_state = stream._get_updated_state(current_stream_state=current_stream_state, latest_record=latest_record) assert output_state == expected class TestStatelessTicketMetrics: @pytest.mark.parametrize( - "start_date, response, expected", - [ - ( - "2023-01-01T00:00:00Z", - { "ticket_metrics": [{"id": 1, "ticket_id": 999, "updated_at": "2023-02-01T00:00:00Z"}, {"id": 2, "ticket_id": 1000, "updated_at": "2024-02-01T00:00:00Z"}]}, - [ - {"id": 1, "ticket_id": 999, "updated_at": "2023-02-01T00:00:00Z", "_ab_updated_at": pendulum.parse("2023-02-01T00:00:00Z").int_timestamp}, - {"id": 2, "ticket_id": 1000, "updated_at": "2024-02-01T00:00:00Z", "_ab_updated_at": pendulum.parse("2024-02-01T00:00:00Z").int_timestamp} + "start_date, response, expected", + [ + ( + "2023-01-01T00:00:00Z", + { + "ticket_metrics": [ + {"id": 1, "ticket_id": 999, "updated_at": "2023-02-01T00:00:00Z"}, + {"id": 2, "ticket_id": 1000, "updated_at": "2024-02-01T00:00:00Z"}, ] - ), - ( - "2024-01-01T00:00:00Z", - { "ticket_metrics": [{"id": 1, "ticket_id": 999, "updated_at": "2023-02-01T00:00:00Z"}, {"id": 2, "ticket_id": 1000, "updated_at": "2024-02-01T00:00:00Z"}]}, - [ - {"id": 2, "ticket_id": 1000, "updated_at": "2024-02-01T00:00:00Z", "_ab_updated_at": pendulum.parse("2024-02-01T00:00:00Z").int_timestamp} + }, + [ + { + "id": 1, + "ticket_id": 999, + "updated_at": "2023-02-01T00:00:00Z", + "_ab_updated_at": pendulum.parse("2023-02-01T00:00:00Z").int_timestamp, + }, + { + "id": 2, + "ticket_id": 1000, + "updated_at": "2024-02-01T00:00:00Z", + "_ab_updated_at": pendulum.parse("2024-02-01T00:00:00Z").int_timestamp, + }, + ], + ), + ( + "2024-01-01T00:00:00Z", + { + "ticket_metrics": [ + {"id": 1, "ticket_id": 999, "updated_at": "2023-02-01T00:00:00Z"}, + {"id": 2, "ticket_id": 1000, "updated_at": "2024-02-01T00:00:00Z"}, ] - ) - ] + }, + [ + { + "id": 2, + "ticket_id": 1000, + "updated_at": "2024-02-01T00:00:00Z", + "_ab_updated_at": pendulum.parse("2024-02-01T00:00:00Z").int_timestamp, + } + ], + ), + ], ) def test_parse_response(self, requests_mock, start_date, response, expected): stream_args = copy.deepcopy(STREAM_ARGS) @@ -1184,25 +1209,24 @@ def test_parse_response(self, requests_mock, start_date, response, expected): output = list(stream.parse_response(test_response, {})) assert expected == output - @pytest.mark.parametrize( - "has_more, expected", - [ - (True, {"page[after]": "nextpagecursor"}), - (False, None) - ] - ) + @pytest.mark.parametrize("has_more, expected", [(True, {"page[after]": "nextpagecursor"}), (False, None)]) def test_next_page_token(self, mocker, has_more, expected): stream = StatelessTicketMetrics(**STREAM_ARGS) ticket_metrics_response = mocker.Mock() - ticket_metrics_response.json.return_value = {"meta": { "after_cursor": "nextpagecursor", "has_more": has_more}} + ticket_metrics_response.json.return_value = {"meta": {"after_cursor": "nextpagecursor", "has_more": has_more}} result = stream.next_page_token(response=ticket_metrics_response) assert expected == result def test_get_updated_state(self): stream = StatelessTicketMetrics(**STREAM_ARGS) - stream._most_recently_updated_record = {"id": 2, "ticket_id": 1000, "updated_at": "2024-02-01T00:00:00Z", "_ab_updated_at": pendulum.parse("2024-02-01T00:00:00Z").int_timestamp} + stream._most_recently_updated_record = { + "id": 2, + "ticket_id": 1000, + "updated_at": "2024-02-01T00:00:00Z", + "_ab_updated_at": pendulum.parse("2024-02-01T00:00:00Z").int_timestamp, + } output_state = stream._get_updated_state(current_stream_state={}, latest_record={}) - expected_state = { "_ab_updated_at": pendulum.parse("2024-02-01T00:00:00Z").int_timestamp} + expected_state = {"_ab_updated_at": pendulum.parse("2024-02-01T00:00:00Z").int_timestamp} assert output_state == expected_state @@ -1244,13 +1268,7 @@ def test_validate_response_ticket_audits_handle_empty_response(audits_response, assert stream._validate_response(response_mock, {}) == expected -@pytest.mark.parametrize( - "initial_state_cursor_field", - [ - "generated_timestamp", - "_ab_updated_at" - ] -) +@pytest.mark.parametrize("initial_state_cursor_field", ["generated_timestamp", "_ab_updated_at"]) def test_ticket_metrics_state_migrataion(initial_state_cursor_field): state_migrator = TicketMetricsStateMigration() initial_state = {initial_state_cursor_field: 1672531200} diff --git a/airbyte-integrations/connectors/source-zendesk-talk/.coveragerc b/airbyte-integrations/connectors/source-zendesk-talk/.coveragerc deleted file mode 100644 index 753140399d72..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/.coveragerc +++ /dev/null @@ -1,3 +0,0 @@ -[run] -omit = - source_zendesk_talk/run.py \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-zendesk-talk/.gitignore b/airbyte-integrations/connectors/source-zendesk-talk/.gitignore deleted file mode 100644 index 29fffc6a50cc..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/.gitignore +++ /dev/null @@ -1 +0,0 @@ -NEW_SOURCE_CHECKLIST.md diff --git a/airbyte-integrations/connectors/source-zendesk-talk/README.md b/airbyte-integrations/connectors/source-zendesk-talk/README.md index df4b0ebdf75f..52a17ad8f4ae 100644 --- a/airbyte-integrations/connectors/source-zendesk-talk/README.md +++ b/airbyte-integrations/connectors/source-zendesk-talk/README.md @@ -1,49 +1,22 @@ -# Zendesk-Talk source connector +# Zendesk Talk source connector -This is the repository for the Zendesk-Talk source connector, written in Python. -For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.com/integrations/sources/zendesk-talk). +This directory contains the manifest-only connector for `source-zendesk-talk`. +This _manifest-only_ connector is not a Python package on its own, as it runs inside of the base `source-declarative-manifest` image. -## Local development - -### Prerequisites - -- Python (~=3.9) -- Poetry (~=1.7) - installation instructions [here](https://python-poetry.org/docs/#installation) - -### Installing the connector - -From this connector directory, run: - -```bash -poetry install --with dev -``` - -### Create credentials +For information about how to configure and use this connector within Airbyte, see [the connector's full documentation](https://docs.airbyte.com/integrations/sources/zendesk-talk). -**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/zendesk-talk) -to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_zendesk_talk/spec.yaml` file. -Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. -See `sample_files/sample_config.json` for a sample config file. - -### Locally running the connector - -``` -poetry run source-zendesk-talk spec -poetry run source-zendesk-talk check --config secrets/config.json -poetry run source-zendesk-talk discover --config secrets/config.json -poetry run source-zendesk-talk read --config secrets/config.json --catalog integration_tests/configured_catalog.json -``` +## Local development -### Running unit tests +We recommend using the Connector Builder to edit this connector. +Using either Airbyte Cloud or your local Airbyte OSS instance, navigate to the **Builder** tab and select **Import a YAML**. +Then select the connector's `manifest.yaml` file to load the connector into the Builder. You're now ready to make changes to the connector! -To run unit tests locally, from the connector directory run: - -``` -poetry run pytest unit_tests -``` +If you prefer to develop locally, you can follow the instructions below. ### Building the docker image +You can build any manifest-only connector with `airbyte-ci`: + 1. Install [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md) 2. Run the following command to build the docker image: @@ -53,18 +26,24 @@ airbyte-ci connectors --name=source-zendesk-talk build An image will be available on your host with the tag `airbyte/source-zendesk-talk:dev`. +### Creating credentials + +**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/zendesk-talk) +to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `spec` object in the connector's `manifest.yaml` file. +Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. + ### Running as a docker container -Then run any of the connector commands as follows: +Then run any of the standard source connector commands: -``` +```bash docker run --rm airbyte/source-zendesk-talk:dev spec docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-zendesk-talk:dev check --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-zendesk-talk:dev discover --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-zendesk-talk:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json ``` -### Running our CI test suite +### Running the CI test suite You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): @@ -72,31 +51,13 @@ You can run our full test suite locally using [`airbyte-ci`](https://github.com/ airbyte-ci connectors --name=source-zendesk-talk test ``` -### Customizing acceptance Tests - -Customize `acceptance-test-config.yml` file to configure acceptance tests. See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) for more information. -If your connector requires to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py. - -### Dependency Management - -All of your dependencies should be managed via Poetry. -To add a new dependency, run: - -```bash -poetry add -``` - -Please commit the changes to `pyproject.toml` and `poetry.lock` files. - ## Publishing a new version of the connector -You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what? - -1. Make sure your changes are passing our test suite: `airbyte-ci connectors --name=source-zendesk-talk test` -2. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): - - bump the `dockerImageTag` value in in `metadata.yaml` - - bump the `version` value in `pyproject.toml` -3. Make sure the `metadata.yaml` content is up to date. +If you want to contribute changes to `source-zendesk-talk`, here's how you can do that: +1. Make your changes locally, or load the connector's manifest into Connector Builder and make changes there. +2. Make sure your changes are passing our test suite with `airbyte-ci connectors --name=source-zendesk-talk test` +3. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): + - bump the `dockerImageTag` value in in `metadata.yaml` 4. Make sure the connector documentation and its changelog is up to date (`docs/integrations/sources/zendesk-talk.md`). 5. Create a Pull Request: use [our PR naming conventions](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#pull-request-title-convention). 6. Pat yourself on the back for being an awesome contributor. diff --git a/airbyte-integrations/connectors/source-zendesk-talk/acceptance-test-config.yml b/airbyte-integrations/connectors/source-zendesk-talk/acceptance-test-config.yml index aa7110c4b54e..9ff2673e2e07 100644 --- a/airbyte-integrations/connectors/source-zendesk-talk/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-zendesk-talk/acceptance-test-config.yml @@ -6,7 +6,7 @@ test_strictness_level: "high" acceptance_tests: spec: tests: - - spec_path: "source_zendesk_talk/spec.json" + - spec_path: "manifest.yaml" connection: tests: - config_path: "secrets/config.json" @@ -31,11 +31,17 @@ acceptance_tests: fail_on_extra_columns: false empty_streams: - name: account_overview - bypass_reason: "The stream is not empty, but makes the test failed due to frequently changing primary key value" + bypass_reason: + "The stream is not empty, but makes the test failed due to + frequently changing primary key value" - name: agents_overview - bypass_reason: "The stream is not empty, but makes the test failed due to frequently changing primary key value" + bypass_reason: + "The stream is not empty, but makes the test failed due to + frequently changing primary key value" - name: current_queue_activity - bypass_reason: "The stream is not empty, but makes the test failed due to frequently changing primary key value" + bypass_reason: + "The stream is not empty, but makes the test failed due to + frequently changing primary key value" incremental: tests: - config_path: "secrets/config.json" diff --git a/airbyte-integrations/connectors/source-zendesk-talk/components.py b/airbyte-integrations/connectors/source-zendesk-talk/components.py new file mode 100644 index 000000000000..f9f3b12732a0 --- /dev/null +++ b/airbyte-integrations/connectors/source-zendesk-talk/components.py @@ -0,0 +1,53 @@ +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. + +from dataclasses import dataclass +from typing import Any, List, Mapping + +import requests + +from airbyte_cdk.sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator +from airbyte_cdk.sources.declarative.auth.token import BasicHttpAuthenticator, BearerAuthenticator +from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor +from airbyte_cdk.sources.declarative.types import Record + + +@dataclass +class IVRMenusRecordExtractor(RecordExtractor): + def extract_records(self, response: requests.Response) -> List[Record]: + ivrs = response.json().get("ivrs", []) + records = [] + for ivr in ivrs: + for menu in ivr.get("menus", []): + records.append({"ivr_id": ivr["id"], **menu}) + return records + + +@dataclass +class IVRRoutesRecordExtractor(RecordExtractor): + def extract_records(self, response: requests.Response) -> List[Record]: + ivrs = response.json().get("ivrs", []) + records = [] + for ivr in ivrs: + for menu in ivr.get("menus", []): + for route in menu.get("routes", []): + records.append({"ivr_id": ivr["id"], "ivr_menu_id": menu["id"], **route}) + return records + + +@dataclass +class ZendeskTalkAuthenticator(DeclarativeAuthenticator): + config: Mapping[str, Any] + legacy_basic_auth: BasicHttpAuthenticator + basic_auth: BasicHttpAuthenticator + oauth: BearerAuthenticator + + def __new__(cls, legacy_basic_auth, basic_auth, oauth, config, *args, **kwargs): + credentials = config.get("credentials", {}) + if config.get("access_token", {}) and config.get("email", {}): + return legacy_basic_auth + elif credentials["auth_type"] == "api_token": + return basic_auth + elif credentials["auth_type"] == "oauth2.0": + return oauth + else: + raise Exception(f"Missing valid authenticator for auth_type: {credentials['auth_type']}") diff --git a/airbyte-integrations/connectors/source-zendesk-talk/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-zendesk-talk/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-zendesk-talk/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-zendesk-talk/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-zendesk-talk/main.py b/airbyte-integrations/connectors/source-zendesk-talk/main.py deleted file mode 100644 index 679ec2c79a78..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/main.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from source_zendesk_talk.run import run - -if __name__ == "__main__": - run() diff --git a/airbyte-integrations/connectors/source-zendesk-talk/manifest.yaml b/airbyte-integrations/connectors/source-zendesk-talk/manifest.yaml new file mode 100644 index 000000000000..3f63886972bf --- /dev/null +++ b/airbyte-integrations/connectors/source-zendesk-talk/manifest.yaml @@ -0,0 +1,1714 @@ +version: 5.15.0 + +type: DeclarativeSource + +check: + type: CheckStream + stream_names: + - account_overview + +definitions: + streams: + addresses: + type: DeclarativeStream + name: addresses + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: addresses + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - addresses + - "*" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"next_page\", {}) }}" + stop_condition: "{{ not response.get(\"next_page\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/addresses" + agents_activity: + type: DeclarativeStream + name: agents_activity + primary_key: + - agent_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /stats/agents_activity + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - agents_activity + - "*" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"next_page\", {}) }}" + stop_condition: "{{ not response.get(\"next_page\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/agents_activity" + agents_overview: + type: DeclarativeStream + name: agents_overview + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /stats/agents_overview + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - agents_overview + transformations: + - type: AddFields + fields: + - path: + - current_timestamp + value: "{{ now_utc().strftime('%s') }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/agents_overview" + greeting_categories: + type: DeclarativeStream + name: greeting_categories + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /greeting_categories + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - greeting_categories + - "*" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"next_page\", {}) }}" + stop_condition: "{{ not response.get(\"next_page\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/greeting_categories" + greetings: + type: DeclarativeStream + name: greetings + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /greetings + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - greetings + - "*" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"next_page\", {}) }}" + stop_condition: "{{ not response.get(\"next_page\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/greetings" + phone_numbers: + type: DeclarativeStream + name: phone_numbers + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: phone_numbers + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - phone_numbers + - "*" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"next_page\", {}) }}" + stop_condition: "{{ not response.get(\"next_page\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/phone_numbers" + call_legs: + type: DeclarativeStream + retriever: + type: SimpleRetriever + ignore_stream_slicer_parameters_on_paginated_requests: true + requester: + $ref: "#/definitions/base_requester" + path: /stats/incremental/legs + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - legs + - "*" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"next_page\", {}) }}" + stop_condition: "{{ response.get(\"count\", {}) <= 1 }}" + name: call_legs + primary_key: + - id + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%s" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: start_time + inject_into: request_parameter + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/call_legs" + calls: + type: DeclarativeStream + retriever: + type: SimpleRetriever + ignore_stream_slicer_parameters_on_paginated_requests: true + requester: + $ref: "#/definitions/base_requester" + path: /stats/incremental/calls + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - calls + - "*" + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"next_page\", {}) }}" + stop_condition: "{{ response.get(\"count\", {}) <= 1 }}" + name: calls + primary_key: + - id + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%Y-%m-%dT%H:%M:%SZ" + datetime_format: "%s" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config[\"start_date\"] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + start_time_option: + type: RequestOption + field_name: start_time + inject_into: request_parameter + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/calls" + current_queue_activity: + type: DeclarativeStream + name: current_queue_activity + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /stats/current_queue_activity + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - current_queue_activity + transformations: + - type: AddFields + fields: + - path: + - current_timestamp + value: "{{ now_utc().strftime('%s') }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/current_queue_activity" + account_overview: + type: DeclarativeStream + name: account_overview + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /stats/account_overview + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - account_overview + transformations: + - type: AddFields + fields: + - path: + - current_timestamp + value: "{{ now_utc().strftime('%s') }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/account_overview" + ivrs: + type: DeclarativeStream + name: ivrs + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /ivr + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - ivrs + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"next_page\", {}) }}" + stop_condition: "{{ not response.get(\"next_page\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/ivrs" + ivr_menus: + type: DeclarativeStream + name: ivr_menus + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /ivr + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: CustomRecordExtractor + class_name: source_declarative_manifest.components.IVRMenusRecordExtractor + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"next_page\", {}) }}" + stop_condition: "{{ not response.get(\"next_page\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/ivr_menus" + ivr_routes: + type: DeclarativeStream + name: ivr_routes + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /ivr + http_method: GET + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: WaitTimeFromHeader + header: Retry-After + record_selector: + type: RecordSelector + extractor: + type: CustomRecordExtractor + class_name: source_declarative_manifest.components.IVRRoutesRecordExtractor + paginator: + type: DefaultPaginator + page_token_option: + type: RequestPath + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get(\"next_page\", {}) }}" + stop_condition: "{{ not response.get(\"next_page\", {}) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/ivr_routes" + base_requester: + type: HttpRequester + url_base: https://{{ config['subdomain'] }}.zendesk.com/api/v2/channels/voice/ + authenticator: + type: CustomAuthenticator + class_name: source_declarative_manifest.components.ZendeskTalkAuthenticator + legacy_basic_auth: + type: BasicHttpAuthenticator + password: "{{ config['access_token'] }}" + username: "{{ config['email'] }}/token" + basic_auth: + type: BasicHttpAuthenticator + password: "{{ config['credentials']['api_token'] }}" + username: "{{ config['credentials']['email'] }}/token" + oauth: + type: BearerAuthenticator + api_token: "{{ config['credentials']['access_token'] }}" + +streams: + - $ref: "#/definitions/streams/addresses" + - $ref: "#/definitions/streams/agents_activity" + - $ref: "#/definitions/streams/agents_overview" + - $ref: "#/definitions/streams/greeting_categories" + - $ref: "#/definitions/streams/greetings" + - $ref: "#/definitions/streams/phone_numbers" + - $ref: "#/definitions/streams/call_legs" + - $ref: "#/definitions/streams/calls" + - $ref: "#/definitions/streams/current_queue_activity" + - $ref: "#/definitions/streams/account_overview" + - $ref: "#/definitions/streams/ivrs" + - $ref: "#/definitions/streams/ivr_menus" + - $ref: "#/definitions/streams/ivr_routes" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - subdomain + - start_date + properties: + subdomain: + type: string + description: >- + This is your Zendesk subdomain that can be found in your account URL. + For example, in https://{MY_SUBDOMAIN}.zendesk.com/, where + MY_SUBDOMAIN is the value of your subdomain. + order: 0 + title: Subdomain + credentials: + type: object + description: >- + Zendesk service provides two authentication methods. Choose between: + `OAuth2.0` or `API token`. + title: Authentication + order: 1 + oneOf: + - type: object + title: OAuth2.0 + required: + - access_token + additionalProperties: true + properties: + auth_type: + type: string + const: oauth2.0 + order: 0 + access_token: + type: string + description: >- + The value of the API token generated. See the docs + for more information. + title: Access Token + airbyte_secret: true + client_id: + type: string + description: Client ID + title: Client ID + airbyte_secret: true + client_secret: + type: string + description: Client Secret + title: Client Secret + airbyte_secret: true + - type: object + title: API Token + required: + - email + - api_token + additionalProperties: true + properties: + auth_type: + type: string + const: api_token + email: + type: string + description: The user email for your Zendesk account. + title: Email + api_token: + type: string + description: >- + The value of the API token generated. See the docs + for more information. + title: API Token + airbyte_secret: true + start_date: + type: string + description: >- + The date from which you'd like to replicate data for Zendesk Talk API, + in the format YYYY-MM-DDT00:00:00Z. All data generated after this date + will be replicated. + order: 2 + title: Start Date + format: date-time + pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ + examples: + - "2020-10-15T00:00:00Z" + additionalProperties: true + advanced_auth: + auth_flow_type: oauth2.0 + predicate_key: + - credentials + - auth_type + predicate_value: oauth2.0 + oauth_config_specification: + complete_oauth_output_specification: + type: object + additionalProperties: false + properties: + access_token: + type: string + path_in_connector_config: + - credentials + - access_token + complete_oauth_server_input_specification: + type: object + additionalProperties: false + properties: + client_id: + type: string + client_secret: + type: string + complete_oauth_server_output_specification: + type: object + additionalProperties: false + properties: + client_id: + type: string + path_in_connector_config: + - credentials + - client_id + client_secret: + type: string + path_in_connector_config: + - credentials + - client_secret + oauth_user_input_from_connector_config_specification: + type: object + additionalProperties: false + properties: + subdomain: + type: string + path_in_connector_config: + - subdomain + +metadata: + autoImportSchema: + addresses: false + agents_activity: false + agents_overview: false + greeting_categories: false + greetings: false + phone_numbers: false + call_legs: false + calls: false + current_queue_activity: false + account_overview: false + ivrs: false + ivr_menus: false + ivr_routes: false + yamlComponents: + streams: + ivr_menus: + - recordSelector + ivr_routes: + - recordSelector + global: + - authenticator + testedStreams: {} + assist: {} + +schemas: + addresses: + type: object + $schema: http://json-schema.org/schema# + properties: + city: + type: + - "null" + - string + country_code: + type: + - "null" + - string + id: + type: + - "null" + - integer + name: + type: + - "null" + - string + provider_reference: + type: + - "null" + - string + province: + type: + - "null" + - string + state: + type: + - "null" + - string + street: + type: + - "null" + - string + zip: + type: + - "null" + - string + additionalProperties: true + agents_activity: + type: object + $schema: http://json-schema.org/schema# + properties: + accepted_third_party_conferences: + type: + - "null" + - integer + accepted_transfers: + type: + - "null" + - integer + agent_id: + type: + - "null" + - integer + agent_state: + type: + - "null" + - string + available_time: + type: + - "null" + - integer + avatar_url: + type: + - "null" + - string + average_hold_time: + type: + - "null" + - integer + average_talk_time: + type: + - "null" + - integer + average_wrap_up_time: + type: + - "null" + - integer + away_time: + type: + - "null" + - integer + call_status: + type: + - "null" + - string + calls_accepted: + type: + - "null" + - integer + calls_denied: + type: + - "null" + - integer + calls_missed: + type: + - "null" + - integer + calls_put_on_hold: + type: + - "null" + - integer + forwarding_number: + type: + - "null" + - string + name: + type: + - "null" + - string + online_time: + type: + - "null" + - integer + started_third_party_conferences: + type: + - "null" + - integer + started_transfers: + type: + - "null" + - integer + total_call_duration: + type: + - "null" + - integer + total_hold_time: + type: + - "null" + - integer + total_talk_time: + type: + - "null" + - integer + total_wrap_up_time: + type: + - "null" + - integer + transfers_only_time: + type: + - "null" + - integer + via: + type: + - "null" + - string + additionalProperties: true + agents_overview: + type: object + $schema: http://json-schema.org/schema# + properties: + average_accepted_transfers: + type: + - "null" + - integer + average_available_time: + type: + - "null" + - integer + average_away_time: + type: + - "null" + - integer + average_calls_accepted: + type: + - "null" + - integer + average_calls_denied: + type: + - "null" + - integer + average_calls_missed: + type: + - "null" + - integer + average_calls_put_on_hold: + type: + - "null" + - integer + average_hold_time: + type: + - "null" + - integer + average_online_time: + type: + - "null" + - integer + average_started_transfers: + type: + - "null" + - integer + average_talk_time: + type: + - "null" + - integer + average_transfers_only_time: + type: + - "null" + - integer + average_wrap_up_time: + type: + - "null" + - integer + current_timestamp: + type: integer + total_accepted_transfers: + type: + - "null" + - integer + total_calls_accepted: + type: + - "null" + - integer + total_calls_denied: + type: + - "null" + - integer + total_calls_missed: + type: + - "null" + - integer + total_calls_put_on_hold: + type: + - "null" + - integer + total_hold_time: + type: + - "null" + - integer + total_started_transfers: + type: + - "null" + - integer + total_talk_time: + type: + - "null" + - integer + total_wrap_up_time: + type: + - "null" + - integer + additionalProperties: true + greeting_categories: + type: object + $schema: http://json-schema.org/schema# + properties: + id: + type: + - "null" + - integer + name: + type: + - "null" + - string + additionalProperties: true + greetings: + type: object + $schema: http://json-schema.org/schema# + properties: + active: + type: + - "null" + - boolean + audio_name: + type: + - "null" + - string + audio_url: + type: + - "null" + - string + category_id: + type: + - "null" + - integer + default: + type: + - "null" + - boolean + default_lang: + type: + - "null" + - boolean + has_sub_settings: + type: + - "null" + - boolean + id: + type: + - "null" + - string + ivr_ids: + type: + - "null" + - array + items: + type: + - string + - integer + name: + type: + - "null" + - string + pending: + type: + - "null" + - boolean + phone_number_ids: + type: + - "null" + - array + items: + type: + - integer + - string + upload_id: + type: + - "null" + - integer + additionalProperties: true + phone_numbers: + type: object + $schema: http://json-schema.org/schema# + properties: + call_recording_consent: + type: + - "null" + - string + capabilities: + type: + - "null" + - object + properties: + emergency_address: + type: + - "null" + - boolean + mms: + type: + - "null" + - boolean + sms: + type: + - "null" + - boolean + voice: + type: + - "null" + - boolean + categorised_greetings: + type: + - "null" + - object + categorised_greetings_with_sub_settings: + type: + - "null" + - object + country_code: + type: + - "null" + - string + created_at: + type: + - "null" + - string + default_greeting_ids: + type: + - "null" + - array + items: + type: + - string + default_group_id: + type: + - "null" + - integer + display_number: + type: + - "null" + - string + external: + type: + - "null" + - boolean + failover_number: + type: + - "null" + - string + greeting_ids: + type: + - "null" + - array + group_ids: + type: + - "null" + - array + id: + type: + - "null" + - integer + ivr_id: + type: + - "null" + - integer + line_type: + type: + - "null" + - string + location: + type: + - "null" + - string + name: + type: + - "null" + - string + nickname: + type: + - "null" + - string + number: + type: + - "null" + - string + outbound_enabled: + type: + - "null" + - boolean + priority: + type: + - "null" + - integer + recorded: + type: + - "null" + - boolean + schedule_id: + type: + - "null" + - integer + sms_enabled: + type: + - "null" + - boolean + sms_group_id: + type: + - "null" + - integer + token: + type: + - "null" + - string + toll_free: + type: + - "null" + - boolean + transcription: + type: + - "null" + - boolean + voice_enabled: + type: + - "null" + - boolean + additionalProperties: true + call_legs: + type: object + $schema: http://json-schema.org/schema# + properties: + type: + type: + - "null" + - string + agent_id: + type: + - "null" + - integer + available_via: + type: + - "null" + - string + call_charge: + type: + - "null" + - string + call_id: + type: + - "null" + - integer + completion_status: + type: + - "null" + - string + conference_from: + type: + - "null" + - integer + conference_time: + type: + - "null" + - integer + conference_to: + type: + - "null" + - integer + consultation_from: + type: + - "null" + - integer + consultation_time: + type: + - "null" + - integer + consultation_to: + type: + - "null" + - integer + created_at: + type: + - "null" + - string + duration: + type: + - "null" + - integer + forwarded_to: + type: + - "null" + - string + hold_time: + type: + - "null" + - integer + id: + type: + - "null" + - integer + minutes_billed: + type: + - "null" + - integer + quality_issues: + type: + - "null" + - array + talk_time: + type: + - "null" + - integer + transferred_from: + type: + - "null" + - integer + transferred_to: + type: + - "null" + - integer + updated_at: + type: + - "null" + - string + format: date-time + user_id: + type: + - "null" + - integer + wrap_up_time: + type: + - "null" + - integer + additionalProperties: true + calls: + type: object + $schema: http://json-schema.org/schema# + properties: + agent_id: + type: + - integer + - "null" + call_charge: + type: + - string + - "null" + call_group_id: + type: + - integer + - "null" + call_recording_consent: + type: + - string + - "null" + call_recording_consent_action: + type: + - string + - "null" + call_recording_consent_keypress: + type: + - string + - "null" + callback: + type: + - boolean + - "null" + callback_source: + type: + - string + - "null" + completion_status: + type: + - string + - "null" + consultation_time: + type: + - integer + - "null" + created_at: + type: + - string + - "null" + customer_requested_voicemail: + type: + - boolean + - "null" + default_group: + type: + - boolean + - "null" + direction: + type: + - string + - "null" + duration: + type: + - integer + - "null" + exceeded_queue_time: + type: + - boolean + - "null" + exceeded_queue_wait_time: + type: + - boolean + - "null" + hold_time: + type: + - integer + - "null" + id: + type: + - integer + - "null" + ivr_action: + type: + - string + - "null" + ivr_destination_group_name: + type: + - string + - "null" + ivr_hops: + type: + - integer + - "null" + ivr_routed_to: + type: + - string + - "null" + ivr_time_spent: + type: + - integer + - "null" + minutes_billed: + type: + - integer + - "null" + not_recording_time: + type: + - integer + - "null" + outside_business_hours: + type: + - boolean + - "null" + overflowed: + type: + - boolean + - "null" + overflowed_to: + type: + - string + - "null" + phone_number: + type: + - string + - "null" + phone_number_id: + type: + - integer + - "null" + quality_issues: + type: + - array + - "null" + recording_control_interactions: + type: + - integer + - "null" + recording_time: + type: + - integer + - "null" + talk_time: + type: + - integer + - "null" + ticket_id: + type: + - integer + - "null" + time_to_answer: + type: + - integer + - "null" + updated_at: + type: + - string + - "null" + format: date-time + voicemail: + type: + - boolean + - "null" + wait_time: + type: + - integer + - "null" + wrap_up_time: + type: + - integer + - "null" + additionalProperties: true + current_queue_activity: + type: object + $schema: http://json-schema.org/schema# + properties: + agents_online: + type: + - integer + - "null" + average_wait_time: + type: + - integer + - "null" + callbacks_waiting: + type: + - integer + - "null" + calls_waiting: + type: + - integer + - "null" + current_timestamp: + type: integer + embeddable_callbacks_waiting: + type: + - integer + - "null" + longest_wait_time: + type: + - integer + - "null" + additionalProperties: true + account_overview: + type: object + $schema: http://json-schema.org/schema# + properties: + average_call_duration: + type: + - integer + - "null" + average_callback_wait_time: + type: + - integer + - "null" + average_hold_time: + type: + - integer + - "null" + average_queue_wait_time: + type: + - integer + - "null" + average_time_to_answer: + type: + - integer + - "null" + average_wrap_up_time: + type: + - integer + - "null" + current_timestamp: + type: integer + max_calls_waiting: + type: + - integer + - "null" + max_queue_wait_time: + type: + - integer + - "null" + total_call_duration: + type: + - integer + - "null" + total_callback_calls: + type: + - integer + - "null" + total_calls: + type: + - integer + - "null" + total_calls_abandoned_in_queue: + type: + - integer + - "null" + total_calls_outside_business_hours: + type: + - integer + - "null" + total_calls_with_exceeded_queue_wait_time: + type: + - integer + - "null" + total_calls_with_requested_voicemail: + type: + - integer + - "null" + total_embeddable_callback_calls: + type: + - integer + - "null" + total_hold_time: + type: + - integer + - "null" + total_inbound_calls: + type: + - integer + - "null" + total_outbound_calls: + type: + - integer + - "null" + total_textback_requests: + type: + - integer + - "null" + total_voicemails: + type: + - integer + - "null" + total_wrap_up_time: + type: + - integer + - "null" + additionalProperties: true + ivrs: + type: object + $schema: http://json-schema.org/schema# + properties: + id: + type: + - integer + - "null" + menus: + type: + - array + - "null" + items: + type: object + properties: + default: + type: + - boolean + - "null" + greeting_id: + type: + - integer + - "null" + id: + type: + - integer + - "null" + name: + type: + - string + - "null" + routes: + type: + - array + - "null" + items: + type: object + properties: + action: + type: + - string + - "null" + greeting: + type: + - string + - "null" + id: + type: + - integer + - "null" + keypress: + type: + - string + - "null" + option_text: + type: + - string + - "null" + options: + type: + - object + - "null" + overflow_options: + type: + - array + - "null" + name: + type: + - string + - "null" + phone_number_ids: + type: + - array + - "null" + items: + type: + - string + - integer + phone_number_names: + type: + - array + - "null" + items: + type: + - string + - integer + additionalProperties: true + ivr_menus: + type: object + $schema: http://json-schema.org/schema# + properties: + default: + type: + - boolean + - "null" + greeting_id: + type: + - "null" + - integer + id: + type: + - integer + - "null" + ivr_id: + type: + - integer + - "null" + name: + type: + - string + - "null" + additionalProperties: true + ivr_routes: + type: object + $schema: http://json-schema.org/schema# + properties: + action: + type: + - string + - "null" + greeting: + type: + - string + - "null" + id: + type: + - integer + - "null" + ivr_id: + type: + - integer + - "null" + ivr_menu_id: + type: + - integer + - "null" + keypress: + type: + - string + - "null" + option_text: + type: + - string + - "null" + options: + type: + - object + - "null" + overflow_options: + type: + - array + - "null" + additionalProperties: true diff --git a/airbyte-integrations/connectors/source-zendesk-talk/metadata.yaml b/airbyte-integrations/connectors/source-zendesk-talk/metadata.yaml index 24d34150d750..678655d44a69 100644 --- a/airbyte-integrations/connectors/source-zendesk-talk/metadata.yaml +++ b/airbyte-integrations/connectors/source-zendesk-talk/metadata.yaml @@ -7,11 +7,11 @@ data: - ${subdomain}.zendesk.com - zendesk.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/source-declarative-manifest:5.15.0@sha256:09a84e0622f36393077332faf11cc239e77083fae5fa500592c049dca25888a7 connectorSubtype: api connectorType: source definitionId: c8630570-086d-4a40-99ae-ea5b18673071 - dockerImageTag: 1.0.21 + dockerImageTag: 1.1.0-rc.1 dockerRepository: airbyte/source-zendesk-talk documentationUrl: https://docs.airbyte.com/integrations/sources/zendesk-talk githubIssueLabel: source-zendesk-talk @@ -21,7 +21,7 @@ data: name: Zendesk Talk remoteRegistries: pypi: - enabled: true + enabled: false packageName: airbyte-source-zendesk-talk registryOverrides: cloud: @@ -35,9 +35,16 @@ data: 1.0.0: upgradeDeadline: "2024-05-31" message: >- - The source Zendesk Talk connector is being migrated from the Python CDK to our declarative low-code CDK. Due to changes to the incremental stream state message format and the removal of a nonexistent field from the ivrs stream schema, this migration constitutes a breaking change. After updating, please reset your source before resuming syncs. For more information, see our migration documentation for source Zendesk Talk. + The source Zendesk Talk connector is being migrated from the Python CDK + to our declarative low-code CDK. Due to changes to the incremental stream + state message format and the removal of a nonexistent field from the ivrs + stream schema, this migration constitutes a breaking change. After updating, + please reset your source before resuming syncs. For more information, see + our migration documentation for source Zendesk Talk. + rolloutConfiguration: + enableProgressiveRollout: true tags: - - language:python + - language:manifest-only - cdk:low-code connectorTestSuitesOptions: - suite: liveTests diff --git a/airbyte-integrations/connectors/source-zendesk-talk/poetry.lock b/airbyte-integrations/connectors/source-zendesk-talk/poetry.lock deleted file mode 100644 index 75b21a1e048d..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/poetry.lock +++ /dev/null @@ -1,1065 +0,0 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. - -[[package]] -name = "airbyte-cdk" -version = "0.80.0" -description = "A framework for writing Airbyte Connectors." -optional = false -python-versions = "<4.0,>=3.9" -files = [ - {file = "airbyte_cdk-0.80.0-py3-none-any.whl", hash = "sha256:060e92323a73674fa4e9e2e4a1eb312b9b9d072c9bbe5fa28f54ef21cb4974f3"}, - {file = "airbyte_cdk-0.80.0.tar.gz", hash = "sha256:1383512a83917fecca5b24cea4c72aa5c561cf96dd464485fbcefda48fe574c5"}, -] - -[package.dependencies] -airbyte-protocol-models = "0.5.1" -backoff = "*" -cachetools = "*" -Deprecated = ">=1.2,<1.3" -dpath = ">=2.0.1,<2.1.0" -genson = "1.2.2" -isodate = ">=0.6.1,<0.7.0" -Jinja2 = ">=3.1.2,<3.2.0" -jsonref = ">=0.2,<0.3" -jsonschema = ">=3.2.0,<3.3.0" -pendulum = "<3.0.0" -pydantic = ">=1.10.8,<2.0.0" -pyrate-limiter = ">=3.1.0,<3.2.0" -python-dateutil = "*" -PyYAML = ">=6.0.1,<7.0.0" -requests = "*" -requests_cache = "*" -wcmatch = "8.4" - -[package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.0.271)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] - -[[package]] -name = "airbyte-protocol-models" -version = "0.5.1" -description = "Declares the Airbyte Protocol." -optional = false -python-versions = ">=3.8" -files = [ - {file = "airbyte_protocol_models-0.5.1-py3-none-any.whl", hash = "sha256:dfe84e130e51ce2ae81a06d5aa36f6c5ce3152b9e36e6f0195fad6c3dab0927e"}, - {file = "airbyte_protocol_models-0.5.1.tar.gz", hash = "sha256:7c8b16c7c1c7956b1996052e40585a3a93b1e44cb509c4e97c1ee4fe507ea086"}, -] - -[package.dependencies] -pydantic = ">=1.9.2,<2.0.0" - -[[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, -] - -[[package]] -name = "attrs" -version = "24.2.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" -files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, -] - -[package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] - -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "bracex" -version = "2.5.post1" -description = "Bash style brace expander." -optional = false -python-versions = ">=3.8" -files = [ - {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, - {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, -] - -[[package]] -name = "cachetools" -version = "5.5.0" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, - {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, -] - -[[package]] -name = "cattrs" -version = "24.1.2" -description = "Composable complex class support for attrs and dataclasses." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, - {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, -] - -[package.dependencies] -attrs = ">=23.1.0" -exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} - -[package.extras] -bson = ["pymongo (>=4.4.0)"] -cbor2 = ["cbor2 (>=5.4.6)"] -msgpack = ["msgpack (>=1.0.5)"] -msgspec = ["msgspec (>=0.18.5)"] -orjson = ["orjson (>=3.9.2)"] -pyyaml = ["pyyaml (>=6.0)"] -tomlkit = ["tomlkit (>=0.11.8)"] -ujson = ["ujson (>=5.7.0)"] - -[[package]] -name = "certifi" -version = "2024.8.30" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.0" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -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 = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - -[[package]] -name = "dpath" -version = "2.0.8" -description = "Filesystem-like pathing and searching for dictionaries" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dpath-2.0.8-py3-none-any.whl", hash = "sha256:f92f595214dd93a00558d75d4b858beee519f4cffca87f02616ad6cd013f3436"}, - {file = "dpath-2.0.8.tar.gz", hash = "sha256:a3440157ebe80d0a3ad794f1b61c571bef125214800ffdb9afc9424e8250fe9b"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "genson" -version = "1.2.2" -description = "GenSON is a powerful, user-friendly JSON Schema generator." -optional = false -python-versions = "*" -files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, -] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isodate" -version = "0.6.1" -description = "An ISO 8601 date/time/duration parser and formatter" -optional = false -python-versions = "*" -files = [ - {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, - {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "jinja2" -version = "3.1.4" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "jsonref" -version = "0.2" -description = "An implementation of JSON Reference for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonref-0.2-py3-none-any.whl", hash = "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f"}, - {file = "jsonref-0.2.tar.gz", hash = "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697"}, -] - -[[package]] -name = "jsonschema" -version = "3.2.0" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, -] - -[package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" - -[package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] - -[[package]] -name = "markupsafe" -version = "3.0.2" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -files = [ - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, - {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, -] - -[[package]] -name = "packaging" -version = "24.1" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, -] - -[[package]] -name = "pendulum" -version = "2.1.2" -description = "Python datetimes made easy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, - {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, - {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, - {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, - {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, - {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, - {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, - {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, - {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, - {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, - {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, -] - -[package.dependencies] -python-dateutil = ">=2.6,<3.0" -pytzdata = ">=2020.1" - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] - -[[package]] -name = "pydantic" -version = "1.10.18" -description = "Data validation and settings management using python type hints" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, -] - -[package.dependencies] -typing-extensions = ">=4.2.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] - -[[package]] -name = "pyrate-limiter" -version = "3.1.1" -description = "Python Rate-Limiter using Leaky-Bucket Algorithm" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, - {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, -] - -[package.extras] -all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] -docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] - -[[package]] -name = "pyrsistent" -version = "0.20.0" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7"}, - {file = "pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee"}, - {file = "pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d"}, - {file = "pyrsistent-0.20.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win32.whl", hash = "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d"}, - {file = "pyrsistent-0.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win32.whl", hash = "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf"}, - {file = "pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b"}, - {file = "pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4"}, -] - -[[package]] -name = "pytest" -version = "6.2.5" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, -] - -[package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] - -[[package]] -name = "pytest-mock" -version = "3.14.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, -] - -[package.dependencies] -pytest = ">=6.2.5" - -[package.extras] -dev = ["pre-commit", "pytest-asyncio", "tox"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytzdata" -version = "2020.1" -description = "The Olson timezone database for Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, - {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-cache" -version = "1.2.1" -description = "A persistent cache for python requests" -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, - {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, -] - -[package.dependencies] -attrs = ">=21.2" -cattrs = ">=22.2" -platformdirs = ">=2.5" -requests = ">=2.22" -url-normalize = ">=1.4" -urllib3 = ">=1.25.5" - -[package.extras] -all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] -bson = ["bson (>=0.5)"] -docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] -dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] -json = ["ujson (>=5.4)"] -mongodb = ["pymongo (>=3)"] -redis = ["redis (>=3)"] -security = ["itsdangerous (>=2.0)"] -yaml = ["pyyaml (>=6.0.1)"] - -[[package]] -name = "requests-mock" -version = "1.12.1" -description = "Mock out responses from the requests package" -optional = false -python-versions = ">=3.5" -files = [ - {file = "requests-mock-1.12.1.tar.gz", hash = "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401"}, - {file = "requests_mock-1.12.1-py2.py3-none-any.whl", hash = "sha256:b1e37054004cdd5e56c84454cc7df12b25f90f382159087f4b6915aaeef39563"}, -] - -[package.dependencies] -requests = ">=2.22,<3" - -[package.extras] -fixture = ["fixtures"] - -[[package]] -name = "setuptools" -version = "75.3.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "url-normalize" -version = "1.4.3" -description = "URL normalization for Python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, - {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "urllib3" -version = "2.2.3" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "wcmatch" -version = "8.4" -description = "Wildcard/glob file name matcher." -optional = false -python-versions = ">=3.7" -files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, -] - -[package.dependencies] -bracex = ">=2.1.1" - -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "93b64196fc01fe00f7c5d8479d66f4f0ea3ee8a96a646b8fae8d125c1f006ad4" diff --git a/airbyte-integrations/connectors/source-zendesk-talk/pyproject.toml b/airbyte-integrations/connectors/source-zendesk-talk/pyproject.toml deleted file mode 100644 index 1dce237a360a..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/pyproject.toml +++ /dev/null @@ -1,28 +0,0 @@ -[build-system] -requires = [ "poetry-core>=1.0.0",] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -version = "1.0.21" -name = "source-zendesk-talk" -description = "Source implementation for Zendesk Talk." -authors = [ "Airbyte ",] -license = "MIT" -readme = "README.md" -documentation = "https://docs.airbyte.com/integrations/sources/zendesk-talk" -homepage = "https://airbyte.com" -repository = "https://github.com/airbytehq/airbyte" -[[tool.poetry.packages]] -include = "source_zendesk_talk" - -[tool.poetry.dependencies] -python = "^3.9,<3.12" -airbyte-cdk = "0.80.0" - -[tool.poetry.scripts] -source-zendesk-talk = "source_zendesk_talk.run:run" - -[tool.poetry.group.dev.dependencies] -requests-mock = "^1.9.3" -pytest-mock = "^3.6" -pytest = "^6.1" diff --git a/airbyte-integrations/connectors/source-zendesk-talk/sample_files/configured_catalog_activities_overview.json b/airbyte-integrations/connectors/source-zendesk-talk/sample_files/configured_catalog_activities_overview.json deleted file mode 100644 index 7339b1a5ebb2..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/sample_files/configured_catalog_activities_overview.json +++ /dev/null @@ -1,172 +0,0 @@ -{ - "streams": [ - { - "stream": { - "name": "agents_activity", - "json_schema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "agent_id": { - "type": ["null", "string"] - }, - "agent_state": { - "type": ["null", "string"] - }, - "available_time": { - "type": ["null", "integer"] - }, - "avatar_url": { - "type": ["null", "string"] - }, - "away_time": { - "type": ["null", "integer"] - }, - "call_status": { - "type": ["null", "string"] - }, - "calls_accepted": { - "type": ["null", "integer"] - }, - "calls_denied": { - "type": ["null", "integer"] - }, - "calls_missed": { - "type": ["null", "integer"] - }, - "forwarding_number": { - "type": ["null", "string"] - }, - "name": { - "type": ["null", "string"] - }, - "online_time": { - "type": ["null", "integer"] - }, - "total_call_duration": { - "type": ["null", "integer"] - }, - "total_talk_time": { - "type": ["null", "integer"] - }, - "total_wrap_up_time": { - "type": ["null", "integer"] - }, - "via": { - "type": ["null", "string"] - }, - "accepted_third_party_conferences": { - "type": ["null", "integer"] - }, - "accepted_transfers": { - "type": ["null", "integer"] - }, - "average_hold_time": { - "type": ["null", "integer"] - }, - "average_talk_time": { - "type": ["null", "integer"] - }, - "average_wrap_up_time": { - "type": ["null", "integer"] - }, - "calls_put_on_hold": { - "type": ["null", "integer"] - }, - "started_third_party_conferences": { - "type": ["null", "integer"] - }, - "started_transfers": { - "type": ["null", "integer"] - }, - "total_hold_time": { - "type": ["null", "integer"] - } - } - }, - "supported_sync_modes": ["full_refresh"], - "source_defined_cursor": false - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "agents_overview", - "json_schema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "average_wrap_up_time": { - "type": ["null", "integer"] - }, - "total_calls_accepted": { - "type": ["null", "integer"] - }, - "total_calls_denied": { - "type": ["null", "integer"] - }, - "total_calls_missed": { - "type": ["null", "integer"] - }, - "total_talk_time": { - "type": ["null", "integer"] - }, - "total_wrap_up_time": { - "type": ["null", "integer"] - }, - "average_accepted_transfers": { - "type": ["null", "integer"] - }, - "average_available_time": { - "type": ["null", "integer"] - }, - "average_away_time": { - "type": ["null", "integer"] - }, - "average_calls_accepted": { - "type": ["null", "integer"] - }, - "average_calls_denied": { - "type": ["null", "integer"] - }, - "average_calls_missed": { - "type": ["null", "integer"] - }, - "average_calls_put_on_hold": { - "type": ["null", "integer"] - }, - "average_hold_time": { - "type": ["null", "integer"] - }, - "average_online_time": { - "type": ["null", "integer"] - }, - "average_started_transfers": { - "type": ["null", "integer"] - }, - "average_talk_time": { - "type": ["null", "integer"] - }, - "total_accepted_transfers": { - "type": ["null", "integer"] - }, - "total_calls_put_on_hold": { - "type": ["null", "integer"] - }, - "total_hold_time": { - "type": ["null", "integer"] - }, - "total_started_transfers": { - "type": ["null", "integer"] - } - } - }, - "supported_sync_modes": ["full_refresh"], - "source_defined_cursor": false - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - } - ] -} diff --git a/airbyte-integrations/connectors/source-zendesk-talk/sample_files/sample_config.json b/airbyte-integrations/connectors/source-zendesk-talk/sample_files/sample_config.json deleted file mode 100644 index b65dc32c5839..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/sample_files/sample_config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "email": "", - "api_token": "", - "subdomain": "", - "start_date": "2021-04-01T00:00:00Z" -} diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/__init__.py b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/__init__.py deleted file mode 100644 index cd0c4e4269e4..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. -# -from .source import SourceZendeskTalk - -__all__ = ["SourceZendeskTalk"] diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/components.py b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/components.py deleted file mode 100644 index d8030841afe2..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/components.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -from dataclasses import dataclass -from typing import Any, List, Mapping - -import requests -from airbyte_cdk.sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator -from airbyte_cdk.sources.declarative.auth.token import BasicHttpAuthenticator, BearerAuthenticator -from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor -from airbyte_cdk.sources.declarative.types import Record - - -@dataclass -class IVRMenusRecordExtractor(RecordExtractor): - def extract_records(self, response: requests.Response) -> List[Record]: - ivrs = response.json().get("ivrs", []) - records = [] - for ivr in ivrs: - for menu in ivr.get("menus", []): - records.append({"ivr_id": ivr["id"], **menu}) - return records - - -@dataclass -class IVRRoutesRecordExtractor(RecordExtractor): - def extract_records(self, response: requests.Response) -> List[Record]: - ivrs = response.json().get("ivrs", []) - records = [] - for ivr in ivrs: - for menu in ivr.get("menus", []): - for route in menu.get("routes", []): - records.append({"ivr_id": ivr["id"], "ivr_menu_id": menu["id"], **route}) - return records - - -@dataclass -class ZendeskTalkAuthenticator(DeclarativeAuthenticator): - config: Mapping[str, Any] - legacy_basic_auth: BasicHttpAuthenticator - basic_auth: BasicHttpAuthenticator - oauth: BearerAuthenticator - - def __new__(cls, legacy_basic_auth, basic_auth, oauth, config, *args, **kwargs): - credentials = config.get("credentials", {}) - if config.get("access_token", {}) and config.get("email", {}): - return legacy_basic_auth - elif credentials["auth_type"] == "api_token": - return basic_auth - elif credentials["auth_type"] == "oauth2.0": - return oauth - else: - raise Exception(f"Missing valid authenticator for auth_type: {credentials['auth_type']}") diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/manifest.yaml b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/manifest.yaml deleted file mode 100644 index ff67384e0a17..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/manifest.yaml +++ /dev/null @@ -1,1620 +0,0 @@ -type: DeclarativeSource - -definitions: - authenticator: - class_name: source_zendesk_talk.components.ZendeskTalkAuthenticator - legacy_basic_auth: - type: BasicHttpAuthenticator - password: "{{ config['access_token'] }}" - username: "{{ config['email'] }}/token" - basic_auth: - type: BasicHttpAuthenticator - password: "{{ config['credentials']['api_token'] }}" - username: "{{ config['credentials']['email'] }}/token" - oauth: - type: BearerAuthenticator - api_token: "{{ config['credentials']['access_token'] }}" - non_incremental_paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - pagination_strategy: - type: CursorPagination - cursor_value: '{{ response.get("next_page", {}) }}' - stop_condition: '{{ not response.get("next_page", {}) }}' - -spec: - type: Spec - documentation_url: https://docs.airbyte.com/integrations/sources/zendesk-talk - connection_specification: - type: object - $schema: http://json-schema.org/draft-07/schema# - title: Source Zendesk Talk Spec - required: - - start_date - - subdomain - properties: - subdomain: - type: string - order: 0 - title: Subdomain - description: This is your Zendesk subdomain that can be found in your account URL. For example, in https://{MY_SUBDOMAIN}.zendesk.com/, where MY_SUBDOMAIN is the value of your subdomain. - credentials: - title: Authentication - type: object - order: 1 - description: "Zendesk service provides two authentication methods. Choose between: `OAuth2.0` or `API token`." - oneOf: - - title: OAuth2.0 - type: object - required: - - access_token - additionalProperties: true - properties: - auth_type: - type: string - const: oauth2.0 - order: 0 - access_token: - type: string - title: Access Token - description: 'The value of the API token generated. See the docs for more information.' - airbyte_secret: true - client_id: - type: string - title: Client ID - description: "Client ID" - airbyte_secret: true - client_secret: - type: string - title: Client Secret - description: "Client Secret" - airbyte_secret: true - - title: API Token - type: object - required: - - email - - api_token - additionalProperties: true - properties: - auth_type: - type: string - const: api_token - email: - title: Email - type: string - description: "The user email for your Zendesk account." - api_token: - title: API Token - type: string - description: 'The value of the API token generated. See the docs for more information.' - airbyte_secret: true - start_date: - type: string - order: 2 - title: Start Date - format: "date-time" - pattern: "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$" - description: The date from which you'd like to replicate data for Zendesk Talk API, in the format YYYY-MM-DDT00:00:00Z. All data generated after this date will be replicated. - examples: - - "2020-10-15T00:00:00Z" - advanced_auth: - auth_flow_type: oauth2.0 - predicate_key: - - credentials - - auth_type - predicate_value: oauth2.0 - oauth_config_specification: - complete_oauth_output_specification: - type: object - additionalProperties: false - properties: - access_token: - type: string - path_in_connector_config: - - credentials - - access_token - complete_oauth_server_input_specification: - type: object - additionalProperties: false - properties: - client_id: - type: string - client_secret: - type: string - complete_oauth_server_output_specification: - type: object - additionalProperties: false - properties: - client_id: - type: string - path_in_connector_config: - - credentials - - client_id - client_secret: - type: string - path_in_connector_config: - - credentials - - client_secret - oauth_user_input_from_connector_config_specification: - type: object - additionalProperties: false - properties: - subdomain: - type: string - path_in_connector_config: - - subdomain - -check: - type: CheckStream - stream_names: - - account_overview - -streams: - - name: addresses - type: DeclarativeStream - retriever: - type: SimpleRetriever - paginator: "#/definitions/non_incremental_paginator" - requester: - path: addresses - type: HttpRequester - url_base: "https://{{ config['subdomain'] }}.zendesk.com/api/v2/channels/voice/" - http_method: GET - authenticator: "#/definitions/authenticator" - error_handler: - type: "DefaultErrorHandler" - backoff_strategies: - - type: WaitTimeFromHeader - header: "Retry-After" - request_headers: {} - request_body_json: {} - request_parameters: {} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - addresses - - "*" - partition_router: [] - primary_key: - - id - schema_loader: - type: InlineSchemaLoader - schema: - type: object - $schema: http://json-schema.org/schema# - properties: - id: - type: - - "null" - - integer - zip: - type: - - "null" - - string - city: - type: - - "null" - - string - name: - type: - - "null" - - string - street: - type: - - "null" - - string - province: - type: - - "null" - - string - state: - type: - - "null" - - string - country_code: - type: - - "null" - - string - provider_reference: - type: - - "null" - - string - - name: agents_activity - type: DeclarativeStream - retriever: - type: SimpleRetriever - paginator: "#/definitions/non_incremental_paginator" - requester: - path: /stats/agents_activity - type: HttpRequester - url_base: "https://{{ config['subdomain'] }}.zendesk.com/api/v2/channels/voice/" - http_method: GET - authenticator: "#/definitions/authenticator" - error_handler: - type: "DefaultErrorHandler" - backoff_strategies: - - type: WaitTimeFromHeader - header: "Retry-After" - request_headers: {} - request_body_json: {} - request_parameters: {} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - agents_activity - - "*" - partition_router: [] - primary_key: agent_id - schema_loader: - type: InlineSchemaLoader - schema: - type: object - $schema: "http://json-schema.org/schema#" - properties: - via: - type: - - "null" - - string - name: - type: - - "null" - - string - agent_id: - type: - - "null" - - integer - call_status: - type: - - "null" - - string - away_time: - type: - - "null" - - integer - avatar_url: - type: - - "null" - - string - agent_state: - type: - - "null" - - string - online_time: - type: - - "null" - - integer - calls_denied: - type: - - "null" - - integer - calls_missed: - type: - - "null" - - integer - available_time: - type: - - "null" - - integer - calls_accepted: - type: - - "null" - - integer - total_hold_time: - type: - - "null" - - integer - total_talk_time: - type: - - "null" - - integer - average_hold_time: - type: - - "null" - - integer - average_talk_time: - type: - - "null" - - integer - calls_put_on_hold: - type: - - "null" - - integer - started_transfers: - type: - - "null" - - integer - accepted_transfers: - type: - - "null" - - integer - total_wrap_up_time: - type: - - "null" - - integer - total_call_duration: - type: - - "null" - - integer - transfers_only_time: - type: - - "null" - - integer - average_wrap_up_time: - type: - - "null" - - integer - started_third_party_conferences: - type: - - "null" - - integer - accepted_third_party_conferences: - type: - - "null" - - integer - forwarding_number: - type: - - "null" - - string - - name: agents_overview - type: DeclarativeStream - retriever: - type: SimpleRetriever - paginator: - type: NoPagination - requester: - path: /stats/agents_overview - type: HttpRequester - url_base: "https://{{ config['subdomain'] }}.zendesk.com/api/v2/channels/voice/" - http_method: GET - authenticator: "#/definitions/authenticator" - error_handler: - type: "DefaultErrorHandler" - backoff_strategies: - - type: WaitTimeFromHeader - header: "Retry-After" - request_headers: {} - request_body_json: {} - request_parameters: {} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - agents_overview - partition_router: [] - transformations: - - type: AddFields - fields: - - path: - - "current_timestamp" - # the python implementation didn't normalize to utc, could cause transient problems - value: "{{ now_utc().strftime('%s') }}" - primary_key: [] - schema_loader: - type: InlineSchemaLoader - schema: - type: object - $schema: "http://json-schema.org/schema#" - properties: - total_hold_time: - type: - - "null" - - integer - total_talk_time: - type: - - "null" - - integer - average_away_time: - type: - - "null" - - integer - average_hold_time: - type: - - "null" - - integer - average_talk_time: - type: - - "null" - - integer - total_calls_denied: - type: - - "null" - - integer - total_calls_missed: - type: - - "null" - - integer - total_wrap_up_time: - type: - - "null" - - integer - average_online_time: - type: - - "null" - - integer - average_calls_denied: - type: - - "null" - - integer - average_calls_missed: - type: - - "null" - - integer - average_wrap_up_time: - type: - - "null" - - integer - total_calls_accepted: - type: - - "null" - - integer - average_available_time: - type: - - "null" - - integer - average_calls_accepted: - type: - - "null" - - integer - total_calls_put_on_hold: - type: - - "null" - - integer - total_started_transfers: - type: - - "null" - - integer - total_accepted_transfers: - type: - - "null" - - integer - average_calls_put_on_hold: - type: - - "null" - - integer - average_started_transfers: - type: - - "null" - - integer - average_accepted_transfers: - type: - - "null" - - integer - average_transfers_only_time: - type: - - "null" - - integer - current_timestamp: - type: integer - - name: greeting_categories - type: DeclarativeStream - retriever: - type: SimpleRetriever - paginator: "#/definitions/non_incremental_paginator" - requester: - path: /greeting_categories - type: HttpRequester - url_base: "https://{{ config['subdomain'] }}.zendesk.com/api/v2/channels/voice/" - http_method: GET - authenticator: "#/definitions/authenticator" - error_handler: - type: "DefaultErrorHandler" - backoff_strategies: - - type: WaitTimeFromHeader - header: "Retry-After" - request_headers: {} - request_body_json: {} - request_parameters: {} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - greeting_categories - - "*" - partition_router: [] - primary_key: - - id - schema_loader: - type: InlineSchemaLoader - schema: - type: object - $schema: "http://json-schema.org/schema#" - properties: - id: - type: - - "null" - - integer - name: - type: - - "null" - - string - - name: greetings - type: DeclarativeStream - retriever: - type: SimpleRetriever - paginator: "#/definitions/non_incremental_paginator" - requester: - path: /greetings - type: HttpRequester - url_base: "https://{{ config['subdomain'] }}.zendesk.com/api/v2/channels/voice/" - http_method: GET - authenticator: "#/definitions/authenticator" - error_handler: - type: "DefaultErrorHandler" - backoff_strategies: - - type: WaitTimeFromHeader - header: "Retry-After" - request_headers: {} - request_body_json: {} - request_parameters: {} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - greetings - - "*" - partition_router: [] - primary_key: [] - schema_loader: - type: InlineSchemaLoader - schema: - type: object - $schema: "http://json-schema.org/schema#" - properties: - id: - type: - - "null" - - string - name: - type: - - "null" - - string - active: - type: - - "null" - - boolean - default: - type: - - "null" - - boolean - ivr_ids: - type: - - "null" - - array - items: - type: - - string - - integer - pending: - type: - - "null" - - boolean - audio_url: - type: - - "null" - - string - audio_name: - type: - - "null" - - string - category_id: - type: - - "null" - - integer - default_lang: - type: - - "null" - - boolean - has_sub_settings: - type: - - "null" - - boolean - phone_number_ids: - type: - - "null" - - array - items: - type: - - integer - - string - upload_id: - type: - - "null" - - integer - - name: phone_numbers - type: DeclarativeStream - retriever: - type: SimpleRetriever - paginator: "#/definitions/non_incremental_paginator" - requester: - path: phone_numbers - type: HttpRequester - url_base: "https://{{ config['subdomain'] }}.zendesk.com/api/v2/channels/voice/" - http_method: GET - authenticator: "#/definitions/authenticator" - error_handler: - type: "DefaultErrorHandler" - backoff_strategies: - - type: WaitTimeFromHeader - header: "Retry-After" - request_headers: {} - request_body_json: {} - request_parameters: {} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - phone_numbers - - "*" - partition_router: [] - primary_key: - - id - schema_loader: - type: InlineSchemaLoader - schema: - type: object - $schema: "http://json-schema.org/schema#" - properties: - id: - type: - - "null" - - integer - name: - type: - - "null" - - string - number: - type: - - "null" - - string - external: - type: - - "null" - - boolean - location: - type: - - "null" - - string - priority: - type: - - "null" - - integer - recorded: - type: - - "null" - - boolean - group_ids: - type: - - "null" - - array - line_type: - type: - - "null" - - string - toll_free: - type: - - "null" - - boolean - created_at: - type: - - "null" - - string - sms_enabled: - type: - - "null" - - boolean - capabilities: - type: - - "null" - - object - properties: - mms: - type: - - "null" - - boolean - sms: - type: - - "null" - - boolean - voice: - type: - - "null" - - boolean - emergency_address: - type: - - "null" - - boolean - country_code: - type: - - "null" - - string - greeting_ids: - type: - - "null" - - array - transcription: - type: - - "null" - - boolean - voice_enabled: - type: - - "null" - - boolean - display_number: - type: - - "null" - - string - outbound_enabled: - type: - - "null" - - boolean - default_greeting_ids: - type: - - "null" - - array - items: - type: - - string - categorised_greetings: - type: - - "null" - - object - call_recording_consent: - type: - - "null" - - string - categorised_greetings_with_sub_settings: - type: - - "null" - - object - default_group_id: - type: - - "null" - - integer - failover_number: - type: - - "null" - - string - ivr_id: - type: - - "null" - - integer - nickname: - type: - - "null" - - string - token: - type: - - "null" - - string - schedule_id: - type: - - "null" - - integer - sms_group_id: - type: - - "null" - - integer - - name: call_legs - type: DeclarativeStream - retriever: - type: SimpleRetriever - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - pagination_strategy: - type: CursorPagination - cursor_value: '{{ response.get("next_page", {}) }}' - stop_condition: '{{ response.get("count", {}) <= 1 }}' - ignore_stream_slicer_parameters_on_paginated_requests: true - requester: - path: /stats/incremental/legs - type: HttpRequester - url_base: "https://{{ config['subdomain'] }}.zendesk.com/api/v2/channels/voice/" - http_method: GET - authenticator: "#/definitions/authenticator" - error_handler: - type: "DefaultErrorHandler" - backoff_strategies: - - type: WaitTimeFromHeader - header: "Retry-After" - request_headers: {} - request_body_json: {} - request_parameters: {} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - legs - - "*" - partition_router: [] - primary_key: - - id - schema_loader: - type: InlineSchemaLoader - schema: - type: object - $schema: "http://json-schema.org/schema#" - properties: - id: - type: - - "null" - - integer - type: - type: - - "null" - - string - call_id: - type: - - "null" - - integer - user_id: - type: - - "null" - - integer - agent_id: - type: - - "null" - - integer - duration: - type: - - "null" - - integer - hold_time: - type: - - "null" - - integer - talk_time: - type: - - "null" - - integer - created_at: - type: - - "null" - - string - updated_at: - type: - - "null" - - string - format: "date-time" - call_charge: - type: - - "null" - - string - wrap_up_time: - type: - - "null" - - integer - available_via: - type: - - "null" - - string - minutes_billed: - type: - - "null" - - integer - quality_issues: - type: - - "null" - - array - completion_status: - type: - - "null" - - string - conference_from: - type: - - "null" - - integer - conference_time: - type: - - "null" - - integer - conference_to: - type: - - "null" - - integer - consultation_from: - type: - - "null" - - integer - consultation_time: - type: - - "null" - - integer - consultation_to: - type: - - "null" - - integer - forwarded_to: - type: - - "null" - - string - transferred_from: - type: - - "null" - - integer - transferred_to: - type: - - "null" - - integer - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - datetime_format: "%s" - start_time_option: - type: RequestOption - field_name: start_time - inject_into: request_parameter - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%SZ" - - name: calls - type: DeclarativeStream - retriever: - type: SimpleRetriever - paginator: - type: DefaultPaginator - page_token_option: - type: RequestPath - pagination_strategy: - type: CursorPagination - cursor_value: '{{ response.get("next_page", {}) }}' - stop_condition: '{{ response.get("count", {}) <= 1 }}' - ignore_stream_slicer_parameters_on_paginated_requests: true - requester: - path: /stats/incremental/calls - type: HttpRequester - url_base: "https://{{ config['subdomain'] }}.zendesk.com/api/v2/channels/voice/" - http_method: GET - authenticator: "#/definitions/authenticator" - error_handler: - type: "DefaultErrorHandler" - backoff_strategies: - - type: WaitTimeFromHeader - header: "Retry-After" - request_headers: {} - request_body_json: {} - request_parameters: {} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - calls - - "*" - partition_router: [] - primary_key: - - id - schema_loader: - type: InlineSchemaLoader - schema: - type: object - $schema: "http://json-schema.org/schema#" - properties: - id: - type: - - integer - - "null" - callback: - type: - - boolean - - "null" - duration: - type: - - integer - - "null" - direction: - type: - - string - - "null" - hold_time: - type: - - integer - - "null" - talk_time: - type: - - integer - - "null" - voicemail: - type: - - boolean - - "null" - wait_time: - type: - - integer - - "null" - created_at: - type: - - string - - "null" - overflowed: - type: - - boolean - - "null" - updated_at: - type: - - string - - "null" - format: "date-time" - call_charge: - type: - - string - - "null" - phone_number: - type: - - string - - "null" - wrap_up_time: - type: - - integer - - "null" - default_group: - type: - - boolean - - "null" - minutes_billed: - type: - - integer - - "null" - quality_issues: - type: - - array - - "null" - recording_time: - type: - - integer - - "null" - phone_number_id: - type: - - integer - - "null" - completion_status: - type: - - string - - "null" - consultation_time: - type: - - integer - - "null" - not_recording_time: - type: - - integer - - "null" - call_recording_consent: - type: - - string - - "null" - outside_business_hours: - type: - - boolean - - "null" - exceeded_queue_wait_time: - type: - - boolean - - "null" - customer_requested_voicemail: - type: - - boolean - - "null" - recording_control_interactions: - type: - - integer - - "null" - agent_id: - type: - - integer - - "null" - call_group_id: - type: - - integer - - "null" - call_recording_consent_action: - type: - - string - - "null" - call_recording_consent_keypress: - type: - - string - - "null" - callback_source: - type: - - string - - "null" - exceeded_queue_time: - type: - - boolean - - "null" - ivr_action: - type: - - string - - "null" - ivr_destination_group_name: - type: - - string - - "null" - ivr_hops: - type: - - integer - - "null" - ivr_routed_to: - type: - - string - - "null" - ivr_time_spent: - type: - - integer - - "null" - overflowed_to: - type: - - string - - "null" - ticket_id: - type: - - integer - - "null" - time_to_answer: - type: - - integer - - "null" - incremental_sync: - type: DatetimeBasedCursor - cursor_field: updated_at - start_datetime: - type: MinMaxDatetime - datetime: "{{ config['start_date'] }}" - datetime_format: "%Y-%m-%dT%H:%M:%SZ" - datetime_format: "%s" - start_time_option: - type: RequestOption - field_name: start_time - inject_into: request_parameter - cursor_datetime_formats: - - "%Y-%m-%dT%H:%M:%SZ" - - name: current_queue_activity - type: DeclarativeStream - retriever: - type: SimpleRetriever - paginator: - type: NoPagination - requester: - path: /stats/current_queue_activity - type: HttpRequester - url_base: "https://{{ config['subdomain'] }}.zendesk.com/api/v2/channels/voice/" - http_method: GET - authenticator: "#/definitions/authenticator" - error_handler: - type: "DefaultErrorHandler" - backoff_strategies: - - type: WaitTimeFromHeader - header: "Retry-After" - request_headers: {} - request_body_json: {} - request_parameters: {} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - current_queue_activity - partition_router: [] - transformations: - - type: AddFields - fields: - - path: - - "current_timestamp" - # the python implementation didn't normalize to utc, could cause transient problems - value: "{{ now_utc().strftime('%s') }}" - primary_key: [] - schema_loader: - type: InlineSchemaLoader - schema: - type: object - $schema: "http://json-schema.org/schema#" - properties: - agents_online: - type: - - integer - - "null" - calls_waiting: - type: - - integer - - "null" - average_wait_time: - type: - - integer - - "null" - callbacks_waiting: - type: - - integer - - "null" - longest_wait_time: - type: - - integer - - "null" - embeddable_callbacks_waiting: - type: - - integer - - "null" - current_timestamp: - type: integer - - name: account_overview - type: DeclarativeStream - retriever: - type: SimpleRetriever - paginator: - type: NoPagination - requester: - path: /stats/account_overview - type: HttpRequester - url_base: "https://{{ config['subdomain'] }}.zendesk.com/api/v2/channels/voice/" - http_method: GET - authenticator: "#/definitions/authenticator" - error_handler: - type: "DefaultErrorHandler" - backoff_strategies: - - type: WaitTimeFromHeader - header: "Retry-After" - request_headers: {} - request_body_json: {} - request_parameters: {} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - account_overview - partition_router: [] - transformations: - - type: AddFields - fields: - - path: - - "current_timestamp" - # the python implementation didn't normalize to utc, could cause transient problems - value: "{{ now_utc().strftime('%s') }}" - primary_key: [] - schema_loader: - type: InlineSchemaLoader - schema: - type: object - $schema: "http://json-schema.org/schema#" - properties: - current_timestamp: - type: integer - total_calls: - type: - - integer - - "null" - total_hold_time: - type: - - integer - - "null" - total_voicemails: - type: - - integer - - "null" - average_hold_time: - type: - - integer - - "null" - max_calls_waiting: - type: - - integer - - "null" - total_wrap_up_time: - type: - - integer - - "null" - max_queue_wait_time: - type: - - integer - - "null" - total_call_duration: - type: - - integer - - "null" - total_inbound_calls: - type: - - integer - - "null" - average_wrap_up_time: - type: - - integer - - "null" - total_callback_calls: - type: - - integer - - "null" - total_outbound_calls: - type: - - integer - - "null" - average_call_duration: - type: - - integer - - "null" - average_time_to_answer: - type: - - integer - - "null" - average_queue_wait_time: - type: - - integer - - "null" - total_textback_requests: - type: - - integer - - "null" - average_callback_wait_time: - type: - - integer - - "null" - total_calls_abandoned_in_queue: - type: - - integer - - "null" - total_embeddable_callback_calls: - type: - - integer - - "null" - total_calls_outside_business_hours: - type: - - integer - - "null" - total_calls_with_requested_voicemail: - type: - - integer - - "null" - total_calls_with_exceeded_queue_wait_time: - type: - - integer - - "null" - - name: ivrs - type: DeclarativeStream - retriever: - type: SimpleRetriever - paginator: "#/definitions/non_incremental_paginator" - requester: - path: /ivr - type: HttpRequester - url_base: "https://{{ config['subdomain'] }}.zendesk.com/api/v2/channels/voice/" - http_method: GET - authenticator: "#/definitions/authenticator" - error_handler: - type: "DefaultErrorHandler" - backoff_strategies: - - type: WaitTimeFromHeader - header: "Retry-After" - request_headers: {} - request_body_json: {} - request_parameters: {} - record_selector: - type: RecordSelector - extractor: - type: DpathExtractor - field_path: - - ivrs - partition_router: [] - primary_key: - - id - schema_loader: - type: InlineSchemaLoader - schema: - type: object - $schema: "http://json-schema.org/schema#" - properties: - id: - type: - - integer - - "null" - name: - type: - - string - - "null" - menus: - type: - - array - - "null" - items: - type: object - properties: - id: - type: - - integer - - "null" - name: - type: - - string - - "null" - greeting_id: - type: - - integer - - "null" - routes: - type: - - array - - "null" - items: - type: object - properties: - id: - type: - - integer - - "null" - action: - type: - - string - - "null" - greeting: - type: - - string - - "null" - options: - type: - - object - - "null" - keypress: - type: - - string - - "null" - option_text: - type: - - string - - "null" - overflow_options: - type: - - array - - "null" - default: - type: - - boolean - - "null" - phone_number_ids: - type: - - array - - "null" - items: - type: - - string - - integer - phone_number_names: - type: - - array - - "null" - items: - type: - - string - - integer - - name: ivr_menus - type: DeclarativeStream - retriever: - type: SimpleRetriever - paginator: "#/definitions/non_incremental_paginator" - requester: - path: /ivr - type: HttpRequester - url_base: "https://{{ config['subdomain'] }}.zendesk.com/api/v2/channels/voice/" - http_method: GET - authenticator: "#/definitions/authenticator" - error_handler: - type: "DefaultErrorHandler" - backoff_strategies: - - type: WaitTimeFromHeader - header: "Retry-After" - request_headers: {} - request_body_json: {} - request_parameters: {} - record_selector: - type: RecordSelector - extractor: - type: CustomRecordExtractor - class_name: source_zendesk_talk.components.IVRMenusRecordExtractor - partition_router: [] - primary_key: [] - schema_loader: - type: InlineSchemaLoader - schema: - type: object - $schema: "http://json-schema.org/schema#" - properties: - id: - type: - - integer - - "null" - name: - type: - - string - - "null" - ivr_id: - type: - - integer - - "null" - greeting_id: - type: - - "null" - - integer - default: - type: - - boolean - - "null" - - name: ivr_routes - type: DeclarativeStream - retriever: - type: SimpleRetriever - paginator: "#/definitions/non_incremental_paginator" - requester: - path: /ivr - type: HttpRequester - url_base: "https://{{ config['subdomain'] }}.zendesk.com/api/v2/channels/voice/" - http_method: GET - authenticator: "#/definitions/authenticator" - error_handler: - type: "DefaultErrorHandler" - backoff_strategies: - - type: WaitTimeFromHeader - header: "Retry-After" - request_headers: {} - request_body_json: {} - request_parameters: {} - record_selector: - type: RecordSelector - extractor: - type: CustomRecordExtractor - class_name: source_zendesk_talk.components.IVRRoutesRecordExtractor - partition_router: [] - primary_key: [] - schema_loader: - type: InlineSchemaLoader - schema: - type: object - $schema: "http://json-schema.org/schema#" - properties: - action: - type: - - string - - "null" - greeting: - type: - - string - - "null" - id: - type: - - integer - - "null" - ivr_id: - type: - - integer - - "null" - ivr_menu_id: - type: - - integer - - "null" - keypress: - type: - - string - - "null" - option_text: - type: - - string - - "null" - options: - type: - - object - - "null" - overflow_options: - type: - - array - - "null" -version: 0.65.0 diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/run.py b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/run.py deleted file mode 100644 index 154690ce67d1..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/run.py +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import sys - -from airbyte_cdk.entrypoint import launch -from source_zendesk_talk import SourceZendeskTalk - - -def run(): - source = SourceZendeskTalk() - launch(source, sys.argv[1:]) diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/account_overview.json b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/account_overview.json deleted file mode 100644 index a20d6b84435e..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/account_overview.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "current_timestamp": { - "description": "Current timestamp at the time of the data retrieval", - "type": "integer" - }, - "average_call_duration": { - "description": "Average duration of calls in seconds", - "type": ["null", "integer"] - }, - "average_queue_wait_time": { - "description": "Average time callers spend waiting in the queue in seconds", - "type": ["null", "integer"] - }, - "average_wrap_up_time": { - "description": "Average time taken by agents to complete call-related work after the call ends in seconds", - "type": ["null", "integer"] - }, - "max_calls_waiting": { - "description": "Maximum number of calls waiting in the queue at a given time", - "type": ["null", "integer"] - }, - "max_queue_wait_time": { - "description": "Longest wait time experienced by a caller in the queue in seconds", - "type": ["null", "integer"] - }, - "total_call_duration": { - "description": "Total duration of all calls combined in seconds", - "type": ["null", "integer"] - }, - "total_calls": { - "description": "Total number of calls handled", - "type": ["null", "integer"] - }, - "total_voicemails": { - "description": "Total voicemails received", - "type": ["null", "integer"] - }, - "total_wrap_up_time": { - "description": "Total time taken by agents for after-call tasks across all calls in seconds", - "type": ["null", "integer"] - }, - "average_callback_wait_time": { - "description": "Average wait time before callback in seconds", - "type": ["null", "integer"] - }, - "average_hold_time": { - "description": "Average time callers are put on hold in seconds", - "type": ["null", "integer"] - }, - "average_time_to_answer": { - "description": "Average time taken to answer calls in seconds", - "type": ["null", "integer"] - }, - "total_callback_calls": { - "description": "Total number of callbacks made", - "type": ["null", "integer"] - }, - "total_calls_abandoned_in_queue": { - "description": "Total calls abandoned by callers while waiting in the queue", - "type": ["null", "integer"] - }, - "total_calls_outside_business_hours": { - "description": "Total calls received outside normal business hours", - "type": ["null", "integer"] - }, - "total_calls_with_exceeded_queue_wait_time": { - "description": "Total calls where wait time exceeded a defined threshold", - "type": ["null", "integer"] - }, - "total_calls_with_requested_voicemail": { - "description": "Total calls where callers requested a voicemail", - "type": ["null", "integer"] - }, - "total_hold_time": { - "description": "Total time callers were put on hold across all calls in seconds", - "type": ["null", "integer"] - }, - "total_inbound_calls": { - "description": "Total incoming calls received", - "type": ["null", "integer"] - }, - "total_outbound_calls": { - "description": "Total outgoing calls made", - "type": ["null", "integer"] - }, - "total_textback_requests": { - "description": "Total requests for textback responses", - "type": ["null", "integer"] - }, - "total_embeddable_callback_calls": { - "description": "Total number of calls that were callbacks from an embedded service", - "type": ["null", "integer"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/addresses.json b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/addresses.json deleted file mode 100644 index 8cb553af3cb7..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/addresses.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "city": { - "description": "The city where the address is located.", - "type": ["null", "string"] - }, - "country_code": { - "description": "The country code of the address.", - "type": ["null", "string"] - }, - "id": { - "description": "The unique identifier of the address.", - "type": ["null", "integer"] - }, - "name": { - "description": "The name associated with the address.", - "type": ["null", "string"] - }, - "provider_reference": { - "description": "Reference identifier provided by the address provider.", - "type": ["null", "string"] - }, - "province": { - "description": "The province or region of the address.", - "type": ["null", "string"] - }, - "state": { - "description": "The state of the address.", - "type": ["null", "string"] - }, - "street": { - "description": "The street name and number of the address.", - "type": ["null", "string"] - }, - "zip": { - "description": "The postal or zip code of the address.", - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/agents_activity.json b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/agents_activity.json deleted file mode 100644 index 27404ac9a7be..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/agents_activity.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "agent_id": { - "description": "Unique identifier for the agent.", - "type": ["null", "integer"] - }, - "agent_state": { - "description": "Current state of the agent (e.g., available, away).", - "type": ["null", "string"] - }, - "available_time": { - "description": "Total time the agent is available for calls.", - "type": ["null", "integer"] - }, - "avatar_url": { - "description": "URL to the agent's avatar image.", - "type": ["null", "string"] - }, - "away_time": { - "description": "Total time the agent is marked as away.", - "type": ["null", "integer"] - }, - "call_status": { - "description": "Status of current call (e.g., ongoing, ended).", - "type": ["null", "string"] - }, - "calls_accepted": { - "description": "Total number of calls accepted by the agent.", - "type": ["null", "integer"] - }, - "calls_denied": { - "description": "Total number of calls denied by the agent.", - "type": ["null", "integer"] - }, - "calls_missed": { - "description": "Total number of calls missed by the agent.", - "type": ["null", "integer"] - }, - "forwarding_number": { - "description": "Phone number calls are forwarded to.", - "type": ["null", "string"] - }, - "name": { - "description": "Name of the agent.", - "type": ["null", "string"] - }, - "online_time": { - "description": "Total time the agent is online and active.", - "type": ["null", "integer"] - }, - "total_call_duration": { - "description": "Total duration of all calls handled by the agent.", - "type": ["null", "integer"] - }, - "total_talk_time": { - "description": "Total duration of talk time for all calls handled by the agent.", - "type": ["null", "integer"] - }, - "total_wrap_up_time": { - "description": "Total time taken to wrap up calls after ending for the agent.", - "type": ["null", "integer"] - }, - "via": { - "description": "Platform or channel via which calls are received (e.g., phone, chat).", - "type": ["null", "string"] - }, - "accepted_third_party_conferences": { - "description": "Number of third-party conferences accepted by the agent.", - "type": ["null", "integer"] - }, - "accepted_transfers": { - "description": "Number of transfers accepted by the agent.", - "type": ["null", "integer"] - }, - "average_hold_time": { - "description": "Average time calls are put on hold before being resumed.", - "type": ["null", "integer"] - }, - "average_talk_time": { - "description": "Average duration of talk time for calls.", - "type": ["null", "integer"] - }, - "average_wrap_up_time": { - "description": "Average time taken to wrap up a call after ending.", - "type": ["null", "integer"] - }, - "calls_put_on_hold": { - "description": "Total number of calls put on hold by the agent.", - "type": ["null", "integer"] - }, - "started_third_party_conferences": { - "description": "Number of third-party conferences initiated by the agent.", - "type": ["null", "integer"] - }, - "started_transfers": { - "description": "Number of transfers initiated by the agent.", - "type": ["null", "integer"] - }, - "total_hold_time": { - "description": "Total time calls are put on hold by the agent.", - "type": ["null", "integer"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/agents_overview.json b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/agents_overview.json deleted file mode 100644 index 382026b7c66c..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/agents_overview.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "current_timestamp": { - "description": "The timestamp when the data was last updated.", - "type": "integer" - }, - "average_wrap_up_time": { - "description": "The average time agents take to wrap up calls.", - "type": ["null", "integer"] - }, - "total_calls_accepted": { - "description": "The total number of calls accepted by agents.", - "type": ["null", "integer"] - }, - "total_calls_denied": { - "description": "The total number of calls denied by agents.", - "type": ["null", "integer"] - }, - "total_calls_missed": { - "description": "The total number of calls missed by agents.", - "type": ["null", "integer"] - }, - "total_talk_time": { - "description": "The total time agents have spent talking on calls.", - "type": ["null", "integer"] - }, - "total_wrap_up_time": { - "description": "The total time agents have taken to wrap up all calls.", - "type": ["null", "integer"] - }, - "average_accepted_transfers": { - "description": "The average number of transfers accepted by agents.", - "type": ["null", "integer"] - }, - "average_available_time": { - "description": "The average amount of time agents are available to take calls.", - "type": ["null", "integer"] - }, - "average_away_time": { - "description": "The average time agents are away from their desks.", - "type": ["null", "integer"] - }, - "average_calls_accepted": { - "description": "The average number of calls accepted by agents.", - "type": ["null", "integer"] - }, - "average_calls_denied": { - "description": "The average number of calls denied by agents.", - "type": ["null", "integer"] - }, - "average_calls_missed": { - "description": "The average number of calls missed by agents.", - "type": ["null", "integer"] - }, - "average_calls_put_on_hold": { - "description": "The average number of calls put on hold by agents.", - "type": ["null", "integer"] - }, - "average_hold_time": { - "description": "The average time calls are put on hold by agents.", - "type": ["null", "integer"] - }, - "average_online_time": { - "description": "The average amount of time agents spend online.", - "type": ["null", "integer"] - }, - "average_started_transfers": { - "description": "The average number of transfers initiated by agents.", - "type": ["null", "integer"] - }, - "average_talk_time": { - "description": "The average time agents spend talking on calls.", - "type": ["null", "integer"] - }, - "total_accepted_transfers": { - "description": "The total number of transfers accepted by agents.", - "type": ["null", "integer"] - }, - "total_calls_put_on_hold": { - "description": "The total number of calls put on hold by agents.", - "type": ["null", "integer"] - }, - "total_hold_time": { - "description": "The total time calls are put on hold by agents.", - "type": ["null", "integer"] - }, - "total_started_transfers": { - "description": "The total number of transfers initiated by agents.", - "type": ["null", "integer"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/call_legs.json b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/call_legs.json deleted file mode 100644 index e675c288cab3..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/call_legs.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "agent_id": { - "description": "The unique identifier of the agent associated with the call leg.", - "type": ["null", "integer"] - }, - "available_via": { - "description": "The communication channel through which the call leg is available.", - "type": ["null", "string"] - }, - "call_charge": { - "description": "The charge incurred for the call leg.", - "type": ["null", "string"] - }, - "call_id": { - "description": "The unique identifier of the call that the call leg belongs to.", - "type": ["null", "integer"] - }, - "completion_status": { - "description": "The status indicating whether the call leg has been completed or not.", - "type": ["null", "string"] - }, - "conference_from": { - "description": "The party initiating the conference call.", - "type": ["null", "integer"] - }, - "conference_time": { - "description": "The time when the call enters a conference.", - "type": ["null", "integer"] - }, - "conference_to": { - "description": "The party being added to the conference call.", - "type": ["null", "integer"] - }, - "consultation_from": { - "description": "The party initiating the consultation call.", - "type": ["null", "integer"] - }, - "consultation_time": { - "description": "The time when the call enters a consultation.", - "type": ["null", "integer"] - }, - "consultation_to": { - "description": "The party being consulted during the call.", - "type": ["null", "integer"] - }, - "created_at": { - "description": "The timestamp indicating when the call leg was created.", - "type": ["null", "string"] - }, - "duration": { - "description": "The length of the call leg in seconds.", - "type": ["null", "integer"] - }, - "forwarded_to": { - "description": "The party to whom the call was forwarded.", - "type": ["null", "string"] - }, - "hold_time": { - "description": "The duration for which the call leg was on hold.", - "type": ["null", "integer"] - }, - "id": { - "description": "The unique identifier of the call leg.", - "type": ["null", "integer"] - }, - "minutes_billed": { - "description": "The minutes for which the call leg is billed.", - "type": ["null", "integer"] - }, - "quality_issues": { - "description": "Any reported quality issues during the call leg.", - "type": ["null", "array"] - }, - "talk_time": { - "description": "The actual time spent talking during the call leg.", - "type": ["null", "integer"] - }, - "transferred_from": { - "description": "The party from which the call was originally transferred.", - "type": ["null", "integer"] - }, - "transferred_to": { - "description": "The party to whom the call was transferred.", - "type": ["null", "integer"] - }, - "type": { - "description": "The type of call leg (e.g., inbound, outbound, internal).", - "type": ["null", "string"] - }, - "updated_at": { - "description": "The timestamp indicating when the call leg was last updated.", - "type": ["null", "string"], - "format": "date-time" - }, - "user_id": { - "description": "The unique identifier of the user associated with the call leg.", - "type": ["null", "integer"] - }, - "wrap_up_time": { - "description": "The time taken for wrap-up activities after the call leg ends.", - "type": ["null", "integer"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/calls.json b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/calls.json deleted file mode 100644 index 62e168e9ad67..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/calls.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "agent_id": { - "description": "The unique identifier of the agent who handled the call.", - "type": ["null", "integer"] - }, - "call_charge": { - "description": "The cost or charge associated with the call.", - "type": ["null", "string"] - }, - "call_group_id": { - "description": "The ID of the group associated with the call.", - "type": ["null", "integer"] - }, - "call_recording_consent": { - "description": "Indicates whether there is recording consent for the call.", - "type": ["null", "string"] - }, - "call_recording_consent_action": { - "description": "The action taken based on recording consent.", - "type": ["null", "string"] - }, - "call_recording_consent_keypress": { - "description": "Keypress used for call recording consent.", - "type": ["null", "string"] - }, - "callback": { - "description": "Indicates if the call is a callback.", - "type": ["null", "boolean"] - }, - "callback_source": { - "description": "Source of the callback.", - "type": ["null", "string"] - }, - "completion_status": { - "description": "Status indicating if the call was successfully completed.", - "type": ["null", "string"] - }, - "consultation_time": { - "description": "Time spent on consultation during the call.", - "type": ["null", "integer"] - }, - "created_at": { - "description": "Timestamp indicating when the call was created.", - "type": ["null", "string"] - }, - "customer_requested_voicemail": { - "description": "Indicates if the customer requested voicemail.", - "type": ["null", "boolean"] - }, - "default_group": { - "description": "Default group associated with the call.", - "type": ["null", "boolean"] - }, - "direction": { - "description": "Direction of the call (inbound/outbound).", - "type": ["null", "string"] - }, - "duration": { - "description": "Total duration of the call.", - "type": ["null", "integer"] - }, - "exceeded_queue_time": { - "description": "Indicates if the call exceeded queue waiting time.", - "type": ["null", "boolean"] - }, - "hold_time": { - "description": "Time the caller spent on hold during the call.", - "type": ["null", "integer"] - }, - "id": { - "description": "Unique identifier of the call.", - "type": ["null", "integer"] - }, - "ivr_action": { - "description": "Action taken by IVR during the call.", - "type": ["null", "string"] - }, - "ivr_destination_group_name": { - "description": "Name of the IVR destination group.", - "type": ["null", "string"] - }, - "ivr_hops": { - "description": "Number of times call was routed through IVR.", - "type": ["null", "integer"] - }, - "ivr_routed_to": { - "description": "Destination of the call after IVR routing.", - "type": ["null", "string"] - }, - "ivr_time_spent": { - "description": "Time spent on IVR interactions during the call.", - "type": ["null", "integer"] - }, - "minutes_billed": { - "description": "Minutes billed for the call.", - "type": ["null", "integer"] - }, - "not_recording_time": { - "description": "Time when call was not being recorded.", - "type": ["null", "integer"] - }, - "outside_business_hours": { - "description": "Indicates if the call occurred outside business hours.", - "type": ["null", "boolean"] - }, - "overflowed": { - "description": "Indicates if the call overflowed from a queue.", - "type": ["null", "boolean"] - }, - "overflowed_to": { - "description": "Destination where the call overflowed to.", - "type": ["null", "string"] - }, - "phone_number": { - "description": "Phone number associated with the call.", - "type": ["null", "string"] - }, - "phone_number_id": { - "description": "ID of the phone number associated with the call.", - "type": ["null", "integer"] - }, - "quality_issues": { - "description": "Indicates any quality issues during the call.", - "type": ["null", "array"] - }, - "recording_control_interactions": { - "description": "Interactions related to call recording control.", - "type": ["null", "integer"] - }, - "recording_time": { - "description": "Total time the call was recorded.", - "type": ["null", "integer"] - }, - "talk_time": { - "description": "Total talk time during the call.", - "type": ["null", "integer"] - }, - "ticket_id": { - "description": "ID of the ticket associated with the call.", - "type": ["null", "integer"] - }, - "time_to_answer": { - "description": "Time taken to answer the call.", - "type": ["null", "integer"] - }, - "updated_at": { - "description": "Timestamp indicating when the call data was last updated.", - "type": ["null", "string"], - "format": "date-time" - }, - "voicemail": { - "description": "Indicates if voicemail was left during the call.", - "type": ["null", "boolean"] - }, - "wait_time": { - "description": "Total time the caller waited before the call was answered.", - "type": ["null", "integer"] - }, - "wrap_up_time": { - "description": "Time taken for wrap-up activities after the call.", - "type": ["null", "integer"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/current_queue_activity.json b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/current_queue_activity.json deleted file mode 100644 index 9c47e2f28f9e..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/current_queue_activity.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "current_timestamp": { - "description": "The timestamp indicating the current time when the data was retrieved.", - "type": "integer" - }, - "agents_online": { - "description": "The number of agents who are currently available and online in the queue.", - "type": ["null", "integer"] - }, - "average_wait_time": { - "description": "The average amount of time callers are waiting in the queue before being connected to an agent.", - "type": ["null", "integer"] - }, - "callbacks_waiting": { - "description": "The number of callback requests that are currently in the queue, waiting for agents to be available.", - "type": ["null", "integer"] - }, - "calls_waiting": { - "description": "The number of incoming calls that are currently waiting to be answered by agents.", - "type": ["null", "integer"] - }, - "embeddable_callbacks_waiting": { - "description": "The number of callback requests that are specifically designated for embedding in a webpage or application and are waiting in the queue.", - "type": ["null", "integer"] - }, - "longest_wait_time": { - "description": "The longest amount of time a caller has been waiting in the queue before being connected to an agent.", - "type": ["null", "integer"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/greeting_categories.json b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/greeting_categories.json deleted file mode 100644 index 75645587bbf0..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/greeting_categories.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "id": { - "description": "Unique identifier for the greeting category.", - "type": ["null", "integer"] - }, - "name": { - "description": "Name of the greeting category.", - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/greetings.json b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/greetings.json deleted file mode 100644 index c38cc9ba0fc5..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/greetings.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "active": { - "description": "Indicates if the greeting is currently active or not", - "type": ["null", "boolean"] - }, - "audio_name": { - "description": "Name of the audio file for the greeting", - "type": ["null", "string"] - }, - "audio_url": { - "description": "URL to access the audio file for the greeting", - "type": ["null", "string"] - }, - "category_id": { - "description": "ID of the category to which the greeting belongs", - "type": ["null", "integer"] - }, - "default": { - "description": "Indicates if the greeting is set as the default", - "type": ["null", "boolean"] - }, - "default_lang": { - "description": "Default language for the greeting", - "type": ["null", "boolean"] - }, - "has_sub_settings": { - "description": "Indicates if the greeting has sub settings or not", - "type": ["null", "boolean"] - }, - "id": { - "description": "Unique identifier for the greeting", - "type": ["null", "string"] - }, - "ivr_ids": { - "description": "List of IVR IDs associated with the greeting", - "type": ["null", "array"], - "items": { - "description": "IVR ID", - "type": ["string", "integer"] - } - }, - "name": { - "description": "Name of the greeting", - "type": ["null", "string"] - }, - "pending": { - "description": "Indicates if the greeting is pending for approval", - "type": ["null", "boolean"] - }, - "phone_number_ids": { - "description": "List of phone number IDs linked to the greeting", - "type": ["null", "array"], - "items": { - "description": "Phone number ID", - "type": ["string", "integer"] - } - }, - "upload_id": { - "description": "ID of the uploaded audio file for the greeting", - "type": ["null", "integer"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/ivr_menus.json b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/ivr_menus.json deleted file mode 100644 index af592fd7eac6..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/ivr_menus.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "default": { - "description": "The default action or response for this IVR menu.", - "type": ["null", "boolean"] - }, - "greeting_id": { - "description": "The ID of the greeting message associated with this IVR menu.", - "type": ["null", "integer"] - }, - "id": { - "description": "The unique identifier of the IVR menu.", - "type": ["null", "integer"] - }, - "ivr_id": { - "description": "The ID of the IVR associated with this menu.", - "type": ["null", "integer"] - }, - "name": { - "description": "The name of the IVR menu.", - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/ivr_routes.json b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/ivr_routes.json deleted file mode 100644 index c4c839dd2394..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/ivr_routes.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "action": { - "description": "The action to be taken when this IVR route is triggered.", - "type": ["null", "string"] - }, - "greeting": { - "description": "The message or greeting played to the caller when this IVR route is entered.", - "type": ["null", "string"] - }, - "id": { - "description": "The unique identifier for the IVR route.", - "type": ["null", "integer"] - }, - "ivr_id": { - "description": "The ID of the IVR associated with this route.", - "type": ["null", "integer"] - }, - "ivr_menu_id": { - "description": "The ID of the IVR menu associated with this route.", - "type": ["null", "integer"] - }, - "keypress": { - "description": "The keypress required to trigger this IVR route.", - "type": ["null", "string"] - }, - "option_text": { - "description": "The text displayed for the option linked to this IVR route.", - "type": ["null", "string"] - }, - "options": { - "description": "The list of options available for this IVR route.", - "type": ["null", "object"] - }, - "overflow_options": { - "description": "The additional options presented when the IVR menu overflows.", - "type": ["null", "array"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/ivrs.json b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/ivrs.json deleted file mode 100644 index 53fb4a5dccd9..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/ivrs.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "id": { - "description": "Unique identifier of the IVR menu", - "type": ["null", "integer"] - }, - "menus": { - "description": "Collection of IVR menus", - "type": ["null", "array"], - "items": { - "description": "Individual IVR menu item", - "type": "object", - "properties": { - "default": { - "description": "Flag indicating if this menu is set as default", - "type": ["null", "boolean"] - }, - "greeting_id": { - "description": "Identifier of the greeting associated with this IVR menu", - "type": ["null", "integer"] - }, - "id": { - "description": "Unique identifier of the IVR menu item", - "type": ["null", "integer"] - }, - "ivr_id": { - "description": "Identifier of the IVR this menu belongs to", - "type": ["null", "integer"] - }, - "name": { - "description": "Name of the IVR menu item", - "type": ["null", "string"] - }, - "routes": { - "description": "List of available routes within the IVR menu", - "type": ["array", "null"], - "items": { - "description": "Individual route within the IVR menu", - "type": "object", - "properties": { - "action": { - "description": "Action to be taken when this route is selected", - "type": ["null", "string"] - }, - "greeting": { - "description": "Text or audio greeting associated with this route", - "type": ["null", "string"] - }, - "id": { - "description": "Unique identifier of the route", - "type": ["null", "integer"] - }, - "keypress": { - "description": "Keypress for selecting this route", - "type": ["null", "string"] - }, - "option_text": { - "description": "Text of the option presented to the user", - "type": ["null", "string"] - }, - "options": { - "description": "Additional options available for this route", - "type": ["null", "object"] - }, - "overflow_options": { - "description": "Options for handling overflow calls", - "type": ["null", "array"] - } - } - } - } - } - } - }, - "name": { - "description": "Name of the IVR menu", - "type": ["null", "string"] - }, - "phone_number_ids": { - "description": "List of phone number IDs associated with the IVR data", - "type": ["null", "array"], - "items": { - "description": "Identifiers of phone numbers associated with this IVR menu", - "type": ["string", "integer"] - } - }, - "phone_number_names": { - "description": "List of phone number names associated with the IVR data", - "type": ["null", "array"], - "items": { - "description": "Names of phone numbers associated with this IVR menu", - "type": ["integer", "string"] - } - } - } -} diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/phone_numbers.json b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/phone_numbers.json deleted file mode 100644 index d188daa931c3..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/schemas/phone_numbers.json +++ /dev/null @@ -1,144 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "call_recording_consent": { - "description": "Indicates whether consent for call recordings is given or not", - "type": ["null", "string"] - }, - "capabilities": { - "description": "Capabilities of the phone number", - "type": ["null", "object"], - "properties": { - "mms": { - "description": "Indicates if MMS capability is enabled", - "type": ["null", "boolean"] - }, - "sms": { - "description": "Indicates if SMS capability is enabled", - "type": ["null", "boolean"] - }, - "voice": { - "description": "Indicates if voice calling capability is enabled", - "type": ["null", "boolean"] - } - } - }, - "categorised_greetings": { - "description": "Categorized greetings for the phone number", - "type": ["null", "object"] - }, - "categorised_greetings_with_sub_settings": { - "description": "Categorized greetings with sub-settings for the phone number", - "type": ["null", "object"] - }, - "country_code": { - "description": "Country code of the phone number", - "type": ["null", "string"] - }, - "created_at": { - "description": "Date and time when the phone number was created", - "type": ["null", "string"] - }, - "default_greeting_ids": { - "description": "IDs of default greetings for the phone number", - "type": ["null", "array"], - "items": { - "description": "ID of a default greeting", - "type": "string" - } - }, - "default_group_id": { - "description": "ID of the default group assigned to the phone number", - "type": ["null", "integer"] - }, - "display_number": { - "description": "Phone number to be displayed", - "type": ["null", "string"] - }, - "external": { - "description": "Indicates if the phone number is external", - "type": ["null", "boolean"] - }, - "failover_number": { - "description": "Failover phone number", - "type": ["null", "string"] - }, - "greeting_ids": { - "description": "IDs of greetings associated with the phone number", - "type": ["null", "array"] - }, - "group_ids": { - "description": "IDs of groups associated with the phone number", - "type": ["null", "array"] - }, - "id": { - "description": "Unique identifier of the phone number", - "type": ["null", "integer"] - }, - "ivr_id": { - "description": "IVR (Interactive Voice Response) ID associated with the phone number", - "type": ["null", "integer"] - }, - "line_type": { - "description": "Type of telephone line (e.g., landline, mobile)", - "type": ["null", "string"] - }, - "location": { - "description": "Location of the phone number", - "type": ["null", "string"] - }, - "name": { - "description": "Name of the phone number", - "type": ["null", "string"] - }, - "nickname": { - "description": "Nickname of the phone number", - "type": ["null", "string"] - }, - "number": { - "description": "Actual phone number", - "type": ["null", "string"] - }, - "outbound_enabled": { - "description": "Indicates if outbound calling is enabled", - "type": ["null", "boolean"] - }, - "priority": { - "description": "Priority level of the phone number", - "type": ["null", "integer"] - }, - "recorded": { - "description": "Indicates if calls are recorded", - "type": ["null", "boolean"] - }, - "schedule_id": { - "description": "ID of the schedule associated with the phone number", - "type": ["null", "integer"] - }, - "sms_enabled": { - "description": "Indicates if SMS is enabled", - "type": ["null", "boolean"] - }, - "sms_group_id": { - "description": "ID of the group for SMS", - "type": ["null", "integer"] - }, - "token": { - "description": "Token associated with the phone number", - "type": ["null", "string"] - }, - "toll_free": { - "description": "Indicates if the phone number is a toll-free number", - "type": ["null", "boolean"] - }, - "transcription": { - "description": "Indicates if call transcription is enabled", - "type": ["null", "boolean"] - }, - "voice_enabled": { - "description": "Indicates if voice calling is enabled", - "type": ["null", "boolean"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/source.py b/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/source.py deleted file mode 100644 index 87aa38b3c918..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/source_zendesk_talk/source.py +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource - - -class SourceZendeskTalk(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-zendesk-talk/unit_tests/test_components.py b/airbyte-integrations/connectors/source-zendesk-talk/unit_tests/test_components.py deleted file mode 100644 index 6dc83fe5a28f..000000000000 --- a/airbyte-integrations/connectors/source-zendesk-talk/unit_tests/test_components.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. - -from unittest.mock import MagicMock - -import pytest -import requests -import requests_mock -from airbyte_cdk.sources.declarative.auth.token import BasicHttpAuthenticator, BearerAuthenticator -from source_zendesk_talk.components import IVRMenusRecordExtractor, IVRRoutesRecordExtractor, ZendeskTalkAuthenticator - - -@pytest.mark.parametrize( - "response_data, expected_records", - [ - # Test cases for IVRMenusRecordExtractor - ( - {"ivrs": [{"id": "ivr_1", "menus": [{"id": "menu_1a", "name": "Menu 1A"}, {"id": "menu_1b", "name": "Menu 1B"}]}, {"id": "ivr_2", "menus": [{"id": "menu_2a", "name": "Menu 2A"}]}]}, - [{"ivr_id": "ivr_1", "id": "menu_1a", "name": "Menu 1A"}, {"ivr_id": "ivr_1", "id": "menu_1b", "name": "Menu 1B"}, {"ivr_id": "ivr_2", "id": "menu_2a", "name": "Menu 2A"}] - ), - ({"ivrs": []}, []), - ({"ivrs": [{"id": "ivr_1", "menus": []}]}, []), - ] -) -def test_ivr_menus_record_extractor(response_data, expected_records): - with requests_mock.Mocker() as m: - m.get('https://not-the-real.api/ivrs', json=response_data) - response = requests.get('https://not-the-real.api/ivrs') - - extractor = IVRMenusRecordExtractor() - records = extractor.extract_records(response) - - assert records == expected_records - -@pytest.mark.parametrize( - "response_data, expected_records", - [ - # Test cases for IVRRoutesRecordExtractor - ( - {"ivrs": [{"id": "ivr_1", "menus": [{"id": "menu_1a", "routes": [{"id": "route_1a1", "name": "Route 1A1"}, {"id": "route_1a2", "name": "Route 1A2"}]}]}]}, - [{"ivr_id": "ivr_1", "ivr_menu_id": "menu_1a", "id": "route_1a1", "name": "Route 1A1"}, {"ivr_id": "ivr_1", "ivr_menu_id": "menu_1a", "id": "route_1a2", "name": "Route 1A2"}] - ), - ({"ivrs": [{"id": "ivr_1", "menus": [{"id": "menu_1a", "routes": []}]}]}, []), - ] -) -def test_ivr_routes_record_extractor(response_data, expected_records): - with requests_mock.Mocker() as m: - m.get('https://not-the-real.api/ivrs', json=response_data) - response = requests.get('https://not-the-real.api/ivrs') - - extractor = IVRRoutesRecordExtractor() - records = extractor.extract_records(response) - - assert records == expected_records - -@pytest.mark.parametrize( - "config, authenticator_type", - [ - ({"access_token": "dummy_token", "email": "dummy@example.com"}, BasicHttpAuthenticator), - ({"credentials": {"auth_type": "api_token"}}, BasicHttpAuthenticator), - ({"credentials": {"auth_type": "oauth2.0"}}, BearerAuthenticator), - ] -) -def test_zendesk_talk_authenticator(config, authenticator_type): - legacy_basic_auth = MagicMock(spec=BasicHttpAuthenticator) - basic_auth = MagicMock(spec=BasicHttpAuthenticator) - oauth = MagicMock(spec=BearerAuthenticator) - - authenticator = ZendeskTalkAuthenticator(legacy_basic_auth, basic_auth, oauth, config) - assert isinstance(authenticator, authenticator_type) - -def test_zendesk_talk_authenticator_invalid(): - with pytest.raises(Exception) as excinfo: - config = {"credentials": {"auth_type": "invalid"}} - ZendeskTalkAuthenticator(None, None, None, config) - assert "Missing valid authenticator" in str(excinfo.value) diff --git a/airbyte-integrations/connectors/source-zenefits/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-zenefits/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-zenefits/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-zenefits/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-zenefits/metadata.yaml b/airbyte-integrations/connectors/source-zenefits/metadata.yaml index 258cfb015c5a..df147ccaf2a1 100644 --- a/airbyte-integrations/connectors/source-zenefits/metadata.yaml +++ b/airbyte-integrations/connectors/source-zenefits/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - api.zenefits.com connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:4.4.3@sha256:8937b693c7e01087f6e86e683826ac20f160f7952b8f0a13cbf4f9bfdd7af570 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 8baba53d-2fe3-4e33-bc85-210d0eb62884 - dockerImageTag: 0.3.1 + dockerImageTag: 0.3.4 dockerRepository: airbyte/source-zenefits documentationUrl: https://docs.airbyte.com/integrations/sources/zenefits githubIssueLabel: source-zenefits diff --git a/airbyte-integrations/connectors/source-zenloop/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-zenloop/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-zenloop/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-zenloop/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-zenloop/main.py b/airbyte-integrations/connectors/source-zenloop/main.py index dd3a6687740e..502dfc3af95f 100644 --- a/airbyte-integrations/connectors/source-zenloop/main.py +++ b/airbyte-integrations/connectors/source-zenloop/main.py @@ -4,5 +4,6 @@ from source_zenloop.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-zenloop/metadata.yaml b/airbyte-integrations/connectors/source-zenloop/metadata.yaml index 6389134ef935..098730542114 100644 --- a/airbyte-integrations/connectors/source-zenloop/metadata.yaml +++ b/airbyte-integrations/connectors/source-zenloop/metadata.yaml @@ -6,11 +6,11 @@ data: hosts: - api.zenloop.com connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/python-connector-base:3.0.0@sha256:1a0845ff2b30eafa793c6eee4e8f4283c2e52e1bbd44eed6cb9e9abd5d34d844 connectorSubtype: api connectorType: source definitionId: f1e4c7f6-db5c-4035-981f-d35ab4998794 - dockerImageTag: 0.1.34 + dockerImageTag: 0.1.39 dockerRepository: airbyte/source-zenloop documentationUrl: https://docs.airbyte.com/integrations/sources/zenloop githubIssueLabel: source-zenloop diff --git a/airbyte-integrations/connectors/source-zenloop/poetry.lock b/airbyte-integrations/connectors/source-zenloop/poetry.lock index a3da2444447b..1925a3969e0f 100644 --- a/airbyte-integrations/connectors/source-zenloop/poetry.lock +++ b/airbyte-integrations/connectors/source-zenloop/poetry.lock @@ -62,19 +62,19 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] @@ -140,127 +140,114 @@ ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -276,20 +263,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" +version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] [[package]] name = "dpath" @@ -367,13 +354,13 @@ six = "*" [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -416,83 +403,83 @@ format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-va [[package]] name = "markupsafe" -version = "3.0.1" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" files = [ - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win32.whl", hash = "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win32.whl", hash = "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win32.whl", hash = "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win32.whl", hash = "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win32.whl", hash = "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b"}, - {file = "markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -573,54 +560,54 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.19" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a415b9e95fa602b10808113967f72b2da8722061265d6af69268c111c254832d"}, + {file = "pydantic-1.10.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:11965f421f7eb026439d4eb7464e9182fe6d69c3d4d416e464a4485d1ba61ab6"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bb81fcfc6d5bff62cd786cbd87480a11d23f16d5376ad2e057c02b3b44df96"}, + {file = "pydantic-1.10.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ee8c9916689f8e6e7d90161e6663ac876be2efd32f61fdcfa3a15e87d4e413"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0399094464ae7f28482de22383e667625e38e1516d6b213176df1acdd0c477ea"}, + {file = "pydantic-1.10.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b2cf5e26da84f2d2dee3f60a3f1782adedcee785567a19b68d0af7e1534bd1f"}, + {file = "pydantic-1.10.19-cp310-cp310-win_amd64.whl", hash = "sha256:1fc8cc264afaf47ae6a9bcbd36c018d0c6b89293835d7fb0e5e1a95898062d59"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d7a8a1dd68bac29f08f0a3147de1885f4dccec35d4ea926e6e637fac03cdb4b3"}, + {file = "pydantic-1.10.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07d00ca5ef0de65dd274005433ce2bb623730271d495a7d190a91c19c5679d34"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad57004e5d73aee36f1e25e4e73a4bc853b473a1c30f652dc8d86b0a987ffce3"}, + {file = "pydantic-1.10.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dce355fe7ae53e3090f7f5fa242423c3a7b53260747aa398b4b3aaf8b25f41c3"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0d32227ea9a3bf537a2273fd2fdb6d64ab4d9b83acd9e4e09310a777baaabb98"}, + {file = "pydantic-1.10.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e351df83d1c9cffa53d4e779009a093be70f1d5c6bb7068584086f6a19042526"}, + {file = "pydantic-1.10.19-cp311-cp311-win_amd64.whl", hash = "sha256:d8d72553d2f3f57ce547de4fa7dc8e3859927784ab2c88343f1fc1360ff17a08"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d5b5b7c6bafaef90cbb7dafcb225b763edd71d9e22489647ee7df49d6d341890"}, + {file = "pydantic-1.10.19-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:570ad0aeaf98b5e33ff41af75aba2ef6604ee25ce0431ecd734a28e74a208555"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0890fbd7fec9e151c7512941243d830b2d6076d5df159a2030952d480ab80a4e"}, + {file = "pydantic-1.10.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec5c44e6e9eac5128a9bfd21610df3b8c6b17343285cc185105686888dc81206"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6eb56074b11a696e0b66c7181da682e88c00e5cebe6570af8013fcae5e63e186"}, + {file = "pydantic-1.10.19-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9d7d48fbc5289efd23982a0d68e973a1f37d49064ccd36d86de4543aff21e086"}, + {file = "pydantic-1.10.19-cp312-cp312-win_amd64.whl", hash = "sha256:fd34012691fbd4e67bdf4accb1f0682342101015b78327eaae3543583fcd451e"}, + {file = "pydantic-1.10.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a5d5b877c7d3d9e17399571a8ab042081d22fe6904416a8b20f8af5909e6c8f"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c46f58ef2df958ed2ea7437a8be0897d5efe9ee480818405338c7da88186fb3"}, + {file = "pydantic-1.10.19-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d8a38a44bb6a15810084316ed69c854a7c06e0c99c5429f1d664ad52cec353c"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a82746c6d6e91ca17e75f7f333ed41d70fce93af520a8437821dec3ee52dfb10"}, + {file = "pydantic-1.10.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:566bebdbe6bc0ac593fa0f67d62febbad9f8be5433f686dc56401ba4aab034e3"}, + {file = "pydantic-1.10.19-cp37-cp37m-win_amd64.whl", hash = "sha256:22a1794e01591884741be56c6fba157c4e99dcc9244beb5a87bd4aa54b84ea8b"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:076c49e24b73d346c45f9282d00dbfc16eef7ae27c970583d499f11110d9e5b0"}, + {file = "pydantic-1.10.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d4320510682d5a6c88766b2a286d03b87bd3562bf8d78c73d63bab04b21e7b4"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e66aa0fa7f8aa9d0a620361834f6eb60d01d3e9cea23ca1a92cda99e6f61dac"}, + {file = "pydantic-1.10.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d216f8d0484d88ab72ab45d699ac669fe031275e3fa6553e3804e69485449fa0"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9f28a81978e936136c44e6a70c65bde7548d87f3807260f73aeffbf76fb94c2f"}, + {file = "pydantic-1.10.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3449633c207ec3d2d672eedb3edbe753e29bd4e22d2e42a37a2c1406564c20f"}, + {file = "pydantic-1.10.19-cp38-cp38-win_amd64.whl", hash = "sha256:7ea24e8614f541d69ea72759ff635df0e612b7dc9d264d43f51364df310081a3"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:573254d844f3e64093f72fcd922561d9c5696821ff0900a0db989d8c06ab0c25"}, + {file = "pydantic-1.10.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff09600cebe957ecbb4a27496fe34c1d449e7957ed20a202d5029a71a8af2e35"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4739c206bfb6bb2bdc78dcd40bfcebb2361add4ceac6d170e741bb914e9eff0f"}, + {file = "pydantic-1.10.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfb5b378b78229119d66ced6adac2e933c67a0aa1d0a7adffbe432f3ec14ce4"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f31742c95e3f9443b8c6fa07c119623e61d76603be9c0d390bcf7e888acabcb"}, + {file = "pydantic-1.10.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6444368b651a14c2ce2fb22145e1496f7ab23cbdb978590d47c8d34a7bc0289"}, + {file = "pydantic-1.10.19-cp39-cp39-win_amd64.whl", hash = "sha256:945407f4d08cd12485757a281fca0e5b41408606228612f421aa4ea1b63a095d"}, + {file = "pydantic-1.10.19-py3-none-any.whl", hash = "sha256:2206a1752d9fac011e95ca83926a269fb0ef5536f7e053966d058316e24d929f"}, + {file = "pydantic-1.10.19.tar.gz", hash = "sha256:fea36c2065b7a1d28c6819cc2e93387b43dd5d3cf5a1e82d8132ee23f36d1f10"}, ] [package.dependencies] @@ -903,33 +890,33 @@ tests = ["coverage (>=3.7.1,<6.0.0)", "flake8", "mypy", "pytest (>=4.6)", "pytes [[package]] name = "setuptools" -version = "75.1.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"}, - {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -970,13 +957,13 @@ six = "*" [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -1001,81 +988,76 @@ bracex = ">=2.1.1" [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.0" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [metadata] diff --git a/airbyte-integrations/connectors/source-zenloop/pyproject.toml b/airbyte-integrations/connectors/source-zenloop/pyproject.toml index 2ccb6021b56e..82c0f24610a7 100644 --- a/airbyte-integrations/connectors/source-zenloop/pyproject.toml +++ b/airbyte-integrations/connectors/source-zenloop/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "0.1.34" +version = "0.1.39" name = "source-zenloop" description = "Source implementation for Zenloop." authors = [ "Alexander Batoulis ",] diff --git a/airbyte-integrations/connectors/source-zenloop/source_zenloop/components.py b/airbyte-integrations/connectors/source-zenloop/source_zenloop/components.py index 2f85e4b1b8e1..a2bec3781798 100644 --- a/airbyte-integrations/connectors/source-zenloop/source_zenloop/components.py +++ b/airbyte-integrations/connectors/source-zenloop/source_zenloop/components.py @@ -12,7 +12,6 @@ @dataclass class ZenloopPartitionRouter(SubstreamPartitionRouter): - config: Config def stream_slices(self) -> Iterable[StreamSlice]: diff --git a/airbyte-integrations/connectors/source-zenloop/source_zenloop/source.py b/airbyte-integrations/connectors/source-zenloop/source_zenloop/source.py index 15a603417b4b..70f571dc0543 100644 --- a/airbyte-integrations/connectors/source-zenloop/source_zenloop/source.py +++ b/airbyte-integrations/connectors/source-zenloop/source_zenloop/source.py @@ -4,6 +4,7 @@ from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + """ This file provides the necessary constructs to interpret a provided declarative YAML configuration file into source connector. diff --git a/airbyte-integrations/connectors/source-zenloop/source_zenloop/streams.py b/airbyte-integrations/connectors/source-zenloop/source_zenloop/streams.py index 00f466edd7e3..53ece70f20ff 100644 --- a/airbyte-integrations/connectors/source-zenloop/source_zenloop/streams.py +++ b/airbyte-integrations/connectors/source-zenloop/source_zenloop/streams.py @@ -9,11 +9,11 @@ from typing import Any, Iterable, Mapping, MutableMapping, Optional import requests + from airbyte_cdk.sources.streams.http import HttpStream class ZenloopStream(HttpStream, ABC): - url_base = "https://api.zenloop.com/v1/" extra_params = None has_date_param = False @@ -58,7 +58,6 @@ def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapp class ChildStreamMixin: - parent_stream_class: Optional[ZenloopStream] = None def stream_slices(self, sync_mode, stream_state: Mapping[str, Any] = None, **kwargs) -> Iterable[Optional[Mapping[str, any]]]: diff --git a/airbyte-integrations/connectors/source-zoho-analytics-metadata-api/README.md b/airbyte-integrations/connectors/source-zoho-analytics-metadata-api/README.md new file mode 100644 index 000000000000..bf7320e7e53e --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-analytics-metadata-api/README.md @@ -0,0 +1,33 @@ +# Zoho Analytics metadata api +This directory contains the manifest-only connector for `source-zoho-analytics-metadata-api`. + +Zoho Analytics Metadata api connector enables seamless data syncing from Zoho Analytics metadata into data warehouses or BI tools. This connector automates OAuth authentication and ensures reliable data transfer, empowering businesses to streamline analytics workflows and gain deeper insights efficiently. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-zoho-analytics-metadata-api:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-zoho-analytics-metadata-api build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-zoho-analytics-metadata-api test +``` + diff --git a/airbyte-integrations/connectors/source-zoho-analytics-metadata-api/acceptance-test-config.yml b/airbyte-integrations/connectors/source-zoho-analytics-metadata-api/acceptance-test-config.yml new file mode 100644 index 000000000000..346c79194115 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-analytics-metadata-api/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-zoho-analytics-metadata-api:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-zoho-analytics-metadata-api/icon.svg b/airbyte-integrations/connectors/source-zoho-analytics-metadata-api/icon.svg new file mode 100644 index 000000000000..45638ae4a8ff --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-analytics-metadata-api/icon.svg @@ -0,0 +1,323 @@ + + + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-zoho-analytics-metadata-api/manifest.yaml b/airbyte-integrations/connectors/source-zoho-analytics-metadata-api/manifest.yaml new file mode 100644 index 000000000000..9e25c0756a4a --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-analytics-metadata-api/manifest.yaml @@ -0,0 +1,654 @@ +version: 6.1.0 + +type: DeclarativeSource + +description: >- + Zoho Analytics Metadata api connector enables seamless data syncing from Zoho + Analytics metadata into data warehouses or BI tools. This connector automates + OAuth authentication and ensures reliable data transfer, empowering businesses + to streamline analytics workflows and gain deeper insights efficiently. + +check: + type: CheckStream + stream_names: + - users + +definitions: + streams: + users: + type: DeclarativeStream + name: users + primary_key: + - emailId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /restapi/v2/users + http_method: GET + request_headers: + ZANALYTICS-ORGID: "{{ config['org_id'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - users + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + workspaces: + type: DeclarativeStream + name: workspaces + primary_key: + - workspaceId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /restapi/v2/workspaces + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - ownedWorkspaces + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/workspaces" + organizations: + type: DeclarativeStream + name: organizations + primary_key: + - orgId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /restapi/v2/orgs + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - orgs + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/organizations" + views: + type: DeclarativeStream + name: views + primary_key: + - viewId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /restapi/v2/workspaces/{{ stream_partition.workspace }}/views + http_method: GET + request_headers: + ZANALYTICS-ORGID: "{{ config[\"org_id\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - views + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: workspaceId + partition_field: workspace + stream: + $ref: "#/definitions/streams/workspaces" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/views" + dashboards: + type: DeclarativeStream + name: dashboards + primary_key: + - viewId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /restapi/v2/dashboards + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - ownedViews + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/dashboards" + trash: + type: DeclarativeStream + name: trash + primary_key: + - viewId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /restapi/v2/workspaces/{{ stream_partition.workspace }}/trash + http_method: GET + request_headers: + ZANALYTICS-ORGID: "{{ config[\"org_id\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - views + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: workspaceId + partition_field: workspace + stream: + $ref: "#/definitions/streams/workspaces" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/trash" + workspace_users: + type: DeclarativeStream + name: workspace_users + primary_key: + - emailId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /restapi/v2/workspaces/{{ stream_partition.workspace }}/users + http_method: GET + request_headers: + ZANALYTICS-ORGID: "{{ config[\"org_id\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - users + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: workspaceId + partition_field: workspace + stream: + $ref: "#/definitions/streams/workspaces" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/workspace_users" + folders: + type: DeclarativeStream + name: folders + primary_key: + - folderId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /restapi/v2/workspaces/{{ stream_partition.workspace }}/folders + http_method: GET + request_headers: + ZANALYTICS-ORGID: "{{ config[\"org_id\"] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - folders + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: workspaceId + partition_field: workspace + stream: + $ref: "#/definitions/streams/workspaces" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/folders" + base_requester: + type: HttpRequester + url_base: https://analyticsapi.zoho.{{ config["data_center"] }} + authenticator: + type: OAuthAuthenticator + client_id: "{{ config[\"client_id\"] }}" + grant_type: refresh_token + client_secret: "{{ config[\"client_secret\"] }}" + refresh_token: "{{ config[\"refresh_token\"] }}" + expires_in_name: expires_in + access_token_name: access_token + refresh_request_body: {} + token_refresh_endpoint: https://accounts.zoho.{{ config["data_center"] }}/oauth/v2/token + +streams: + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/workspaces" + - $ref: "#/definitions/streams/organizations" + - $ref: "#/definitions/streams/views" + - $ref: "#/definitions/streams/dashboards" + - $ref: "#/definitions/streams/trash" + - $ref: "#/definitions/streams/workspace_users" + - $ref: "#/definitions/streams/folders" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - client_id + - client_secret + - refresh_token + - data_center + - org_id + properties: + client_id: + type: string + name: client_id + order: 0 + title: OAuth Client ID + airbyte_secret: true + client_secret: + type: string + name: client_secret + order: 1 + title: OAuth Client Secret + airbyte_secret: true + refresh_token: + type: string + name: refresh_token + order: 2 + title: OAuth Refresh Token + airbyte_secret: true + data_center: + type: string + enum: + - com + - eu + - in + - com.au + - com.cn + - jp + order: 3 + title: Data Center + default: com + org_id: + type: number + order: 4 + title: Org Id + additionalProperties: true + +metadata: + autoImportSchema: + users: true + workspaces: true + organizations: true + views: true + dashboards: true + trash: true + workspace_users: true + folders: true + testedStreams: + users: + hasRecords: true + streamHash: 30b9674113495c708b88b03206126e121d54637b + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + workspaces: + hasRecords: true + streamHash: 412f2d3ff4d56ea7401a905def908c42a0ee450a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + organizations: + hasRecords: true + streamHash: fe29c6780e8b266bbe44d9feb13a6f0d486b425c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + views: + hasRecords: true + streamHash: 32af56a385b314e6e5c9238a605b9d0c2ad7f8b0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + dashboards: + hasRecords: true + streamHash: e13cb711a5f8a91eb42ac3f163d5a9c39f164346 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + trash: + hasRecords: true + streamHash: 0d8d1ecf9c0edad58d67d0a255234ee38278eb6c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + workspace_users: + hasRecords: true + streamHash: dc51d9f2fc5b699cf7dad3a46a5396d85cca9d5c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + folders: + hasRecords: true + streamHash: 2c74239bed086e4cd23916c4f5f450df3215db18 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://www.zoho.com/analytics/api/v2/introduction.html + +schemas: + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + emailId: + type: string + role: + type: + - string + - "null" + status: + type: + - boolean + - "null" + required: + - emailId + workspaces: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdBy: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + isDefault: + type: + - boolean + - "null" + orgId: + type: + - string + - "null" + workspaceDesc: + type: + - string + - "null" + workspaceId: + type: string + workspaceName: + type: + - string + - "null" + required: + - workspaceId + organizations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdBy: + type: + - string + - "null" + createdByZuId: + type: + - string + - "null" + isDefault: + type: + - boolean + - "null" + numberOfWorkspaces: + type: + - number + - "null" + orgDesc: + type: + - string + - "null" + orgId: + type: string + orgName: + type: + - string + - "null" + planName: + type: + - string + - "null" + role: + type: + - string + - "null" + required: + - orgId + views: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdBy: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + folderId: + type: + - string + - "null" + isFavorite: + type: + - boolean + - "null" + lastModifiedBy: + type: + - string + - "null" + lastModifiedTime: + type: + - string + - "null" + parentViewId: + type: + - string + - "null" + sharedBy: + type: + - string + - "null" + viewDesc: + type: + - string + - "null" + viewId: + type: string + viewName: + type: + - string + - "null" + viewType: + type: + - string + - "null" + required: + - viewId + dashboards: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdBy: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + folderId: + type: + - string + - "null" + isFavorite: + type: + - boolean + - "null" + lastModifiedBy: + type: + - string + - "null" + lastModifiedTime: + type: + - string + - "null" + orgId: + type: + - string + - "null" + parentViewId: + type: + - string + - "null" + sharedBy: + type: + - string + - "null" + viewDesc: + type: + - string + - "null" + viewId: + type: string + viewName: + type: + - string + - "null" + viewType: + type: + - string + - "null" + workspaceId: + type: + - string + - "null" + required: + - viewId + trash: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + deletedBy: + type: + - string + - "null" + deletedTime: + type: + - string + - "null" + viewId: + type: string + viewName: + type: + - string + - "null" + viewType: + type: + - string + - "null" + required: + - viewId + workspace_users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + emailId: + type: string + role: + type: + - string + - "null" + status: + type: + - boolean + - "null" + required: + - emailId + folders: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + folderDesc: + type: + - string + - "null" + folderId: + type: string + folderIndex: + type: + - number + - "null" + folderName: + type: + - string + - "null" + isDefault: + type: + - boolean + - "null" + parentFolderId: + type: + - string + - "null" + required: + - folderId diff --git a/airbyte-integrations/connectors/source-zoho-analytics-metadata-api/metadata.yaml b/airbyte-integrations/connectors/source-zoho-analytics-metadata-api/metadata.yaml new file mode 100644 index 000000000000..8322df86721c --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-analytics-metadata-api/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "analyticsapi.zoho." + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-zoho-analytics-metadata-api + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 63114ebf-1c0e-4e6e-bb93-28ae03332b14 + dockerImageTag: 0.0.4 + dockerRepository: airbyte/source-zoho-analytics-metadata-api + githubIssueLabel: source-zoho-analytics-metadata-api + icon: icon.svg + license: MIT + name: Zoho Analytics metadata api + releaseDate: 2024-11-07 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/zoho-analytics-metadata-api + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-zoho-bigin/README.md b/airbyte-integrations/connectors/source-zoho-bigin/README.md new file mode 100644 index 000000000000..1374efcd7c4c --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-bigin/README.md @@ -0,0 +1,33 @@ +# Zoho Bigin +This directory contains the manifest-only connector for `source-zoho-bigin`. + + Zoho Bigin connector enables seamless data sync between Zoho Bigin and other platforms. This connector automates CRM data integration, improving workflows and ensuring real-time access to customer insights across tools. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-zoho-bigin:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-zoho-bigin build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-zoho-bigin test +``` + diff --git a/airbyte-integrations/connectors/source-zoho-bigin/acceptance-test-config.yml b/airbyte-integrations/connectors/source-zoho-bigin/acceptance-test-config.yml new file mode 100644 index 000000000000..09b318895df0 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-bigin/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-zoho-bigin:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-zoho-bigin/icon.svg b/airbyte-integrations/connectors/source-zoho-bigin/icon.svg new file mode 100644 index 000000000000..38409d2e747d --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-bigin/icon.svg @@ -0,0 +1,369 @@ + + + + + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-zoho-bigin/manifest.yaml b/airbyte-integrations/connectors/source-zoho-bigin/manifest.yaml new file mode 100644 index 000000000000..e503b92d7e04 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-bigin/manifest.yaml @@ -0,0 +1,1347 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: " Zoho Bigin connector enables seamless data sync between Zoho Bigin and other platforms. This connector automates CRM data integration, improving workflows and ensuring real-time access to customer insights across tools." + +check: + type: CheckStream + stream_names: + - users + +definitions: + streams: + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - users + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: per_page + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + modules: + type: DeclarativeStream + name: modules + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /settings/modules + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - modules + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/modules" + organizations: + type: DeclarativeStream + name: organizations + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /org + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - org + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/organizations" + roles: + type: DeclarativeStream + name: roles + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /settings/roles + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - roles + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/roles" + notes: + type: DeclarativeStream + name: notes + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /Notes + http_method: GET + request_parameters: + fields: Note_Title,Note_Content,Parent_Id + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: per_page + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/notes" + tags: + type: DeclarativeStream + name: tags + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /settings/tags + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - tags + partition_router: + type: ListPartitionRouter + values: + - Contacts + - Pipelines + - Companies + - Products + - Tasks + - Events + - Calls + cursor_field: module + request_option: + type: RequestOption + inject_into: request_parameter + field_name: module + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tags" + companies: + type: DeclarativeStream + name: companies + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /Accounts + http_method: GET + request_parameters: + fields: Account_Name,Phone,Website + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page_token + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: per_page + pagination_strategy: + type: CursorPagination + page_size: 200 + cursor_value: "{{ response.get('info', {}).get('next_page_token') }}" + stop_condition: "{{ not response.get('info', {}).get('more_records', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/companies" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /Contacts + http_method: GET + request_parameters: + fields: Last_Name,Email + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page_token + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('info', {}).get('next_page_token', '') }}" + stop_condition: "{{ not response.get('info', {}).get('more_records', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + tasks: + type: DeclarativeStream + name: tasks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /Tasks + http_method: GET + request_parameters: + fields: Owner,Subject,Due Date,Remind_At + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page_token + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('info', {}).get('next_page_token', '') }}" + stop_condition: "{{ not response.get('info', {}).get('more_records', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tasks" + events: + type: DeclarativeStream + name: events + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /Events + http_method: GET + request_parameters: + fields: Owner,Event_Title,Start_DateTime,End_DateTime + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + start_from_page: 0 + page_size: 200 + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/events" + products: + type: DeclarativeStream + name: products + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /Products + http_method: GET + request_parameters: + fields: >- + Owner,Product_Name,Product_Category,Unit_Price,Description,Product_Active + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page_token + pagination_strategy: + type: CursorPagination + cursor_value: "{{ response.get('info', {}).get('next_page_token', '') }}" + stop_condition: "{{ not response.get('info', {}).get('more_records', False) }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/products" + base_requester: + type: HttpRequester + url_base: https://www.zohoapis.{{ config["data_center"] }}/bigin/v2 + authenticator: + type: OAuthAuthenticator + client_id: "{{ config[\"client_id\"] }}" + grant_type: refresh_token + client_secret: "{{ config[\"client_secret\"] }}" + refresh_token: "{{ config[\"client_refresh_token\"] }}" + expires_in_name: expires_in + access_token_name: access_token + refresh_request_body: {} + token_refresh_endpoint: https://accounts.zoho.{{ config["data_center"] }}/oauth/v2/token + +streams: + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/modules" + - $ref: "#/definitions/streams/organizations" + - $ref: "#/definitions/streams/roles" + - $ref: "#/definitions/streams/notes" + - $ref: "#/definitions/streams/tags" + - $ref: "#/definitions/streams/companies" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/tasks" + - $ref: "#/definitions/streams/events" + - $ref: "#/definitions/streams/products" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - client_id + - data_center + - client_secret + - client_refresh_token + - module_name + properties: + client_id: + type: string + name: client_id + order: 0 + title: OAuth Client ID + airbyte_secret: true + data_center: + type: string + description: The data center where the Bigin account's resources are hosted + enum: + - com + - com.au + - eu + - in + - com.cn + - jp + name: data_center + order: 1 + title: Data Center + default: com + client_secret: + type: string + name: client_secret + order: 2 + title: OAuth Client Secret + airbyte_secret: true + client_refresh_token: + type: string + order: 3 + title: Refresh token + airbyte_secret: true + module_name: + type: string + order: 4 + title: Module Name + additionalProperties: true + +metadata: + autoImportSchema: + users: true + modules: true + organizations: true + roles: true + notes: true + tags: true + companies: true + contacts: true + tasks: true + events: true + products: true + testedStreams: + users: + streamHash: f9c8fc4a62114f362eb6a984c79ba314d934be17 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + modules: + streamHash: 7027ed4afe12e9a9c1cb9528ed5f1d5bf99c8e76 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + organizations: + streamHash: 2db7dbec4301f64e9296f9d3150a26fcf9f97f3a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + roles: + streamHash: 36e98e146a92bc49dc30c62dd6ba105598e962c8 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + notes: + streamHash: 751e00f2202ac83eb64ee8ad4c2321287834f2e9 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tags: + streamHash: 1f8fce21c3a7316d352fa01f7bc49213556e74e2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + companies: + streamHash: f41b79d9489ccffd58e8de6fa8029eb8feeadeb0 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contacts: + streamHash: fb71d11b5a32e69fbcbf527c82e98bc8c3149a49 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tasks: + streamHash: f28271e7d149c1f1590199c0835fdf32831fb20b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + events: + streamHash: f96faf2540b727a7e1cf24134f8f6cbec82133e3 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + products: + hasRecords: true + streamHash: 8517b62f6a46b2eefaab27dc2a7ba6f6c7f48c9d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://www.bigin.com/developer/docs/apis/v2/modules-api.html + +schemas: + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Isonline: + type: + - boolean + - "null" + Modified_By: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + Modified_Time: + type: + - string + - "null" + category: + type: + - string + - "null" + confirm: + type: + - boolean + - "null" + country: + type: + - string + - "null" + country_locale: + type: + - string + - "null" + created_by: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + created_time: + type: + - string + - "null" + customize_info: + type: + - object + - "null" + properties: + show_detail_view: + type: + - boolean + - "null" + show_home: + type: + - boolean + - "null" + date_format: + type: + - string + - "null" + decimal_separator: + type: + - string + - "null" + default_tab_group: + type: + - string + - "null" + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + full_name: + type: + - string + - "null" + id: + type: string + language: + type: + - string + - "null" + last_name: + type: + - string + - "null" + locale: + type: + - string + - "null" + microsoft: + type: + - boolean + - "null" + name_format: + type: + - string + - "null" + number_separator: + type: + - string + - "null" + offset: + type: + - number + - "null" + personal_account: + type: + - boolean + - "null" + profile: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + role: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + sandboxDeveloper: + type: + - boolean + - "null" + sort_order_preference: + type: + - string + - "null" + state: + type: + - string + - "null" + status: + type: + - string + - "null" + theme: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + background: + type: + - string + - "null" + normal_tab: + type: + - object + - "null" + properties: + background: + type: + - string + - "null" + font_color: + type: + - string + - "null" + screen: + type: + - string + - "null" + selected_tab: + type: + - object + - "null" + properties: + background: + type: + - string + - "null" + font_color: + type: + - string + - "null" + time_format: + type: + - string + - "null" + time_zone: + type: + - string + - "null" + zuid: + type: + - string + - "null" + required: + - id + modules: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + access_type: + type: + - string + - "null" + actual_plural_label: + type: + - string + - "null" + actual_singular_label: + type: + - string + - "null" + api_name: + type: + - string + - "null" + api_supported: + type: + - boolean + - "null" + arguments: + type: + - array + - "null" + business_card_field_limit: + type: + - number + - "null" + convertable: + type: + - boolean + - "null" + creatable: + type: + - boolean + - "null" + deletable: + type: + - boolean + - "null" + editable: + type: + - boolean + - "null" + emailTemplate_support: + type: + - boolean + - "null" + email_parser_supported: + type: + - boolean + - "null" + feeds_required: + type: + - boolean + - "null" + filter_supported: + type: + - boolean + - "null" + generated_type: + type: + - string + - "null" + global_search_supported: + type: + - boolean + - "null" + has_more_profiles: + type: + - boolean + - "null" + id: + type: string + inventory_template_supported: + type: + - boolean + - "null" + isBlueprintSupported: + type: + - boolean + - "null" + modified_by: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + modified_time: + type: + - string + - "null" + module_name: + type: + - string + - "null" + parent_module: + type: + - object + - "null" + properties: + api_name: + type: + - string + - "null" + id: + type: + - string + - "null" + plural_label: + type: + - string + - "null" + presence_sub_menu: + type: + - boolean + - "null" + profile_count: + type: + - number + - "null" + profiles: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + public_fields_configured: + type: + - boolean + - "null" + quick_create: + type: + - boolean + - "null" + scoring_supported: + type: + - boolean + - "null" + sequence_number: + type: + - number + - "null" + show_as_tab: + type: + - boolean + - "null" + singular_label: + type: + - string + - "null" + triggers_supported: + type: + - boolean + - "null" + viewable: + type: + - boolean + - "null" + visibility: + type: + - number + - "null" + visible: + type: + - boolean + - "null" + webform_supported: + type: + - boolean + - "null" + required: + - id + organizations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + company_name: + type: + - string + - "null" + country_code: + type: + - string + - "null" + currency: + type: + - string + - "null" + currency_locale: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + deletable_org_account: + type: + - boolean + - "null" + domain_name: + type: + - string + - "null" + gapps_enabled: + type: + - boolean + - "null" + hierarchy_preferences: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + hipaa_compliance_enabled: + type: + - boolean + - "null" + id: + type: string + iso_code: + type: + - string + - "null" + license_details: + type: + - object + - "null" + properties: + paid: + type: + - boolean + - "null" + paid_type: + type: + - string + - "null" + portal_users_license_purchased: + type: + - number + - "null" + trial_expiry: + type: + - string + - "null" + trial_type: + type: + - string + - "null" + users_license_purchased: + type: + - number + - "null" + lite_users_enabled: + type: + - boolean + - "null" + mc_status: + type: + - boolean + - "null" + phone: + type: + - string + - "null" + primary_email: + type: + - string + - "null" + primary_zuid: + type: + - string + - "null" + privacy_settings: + type: + - boolean + - "null" + time_zone: + type: + - string + - "null" + translation_enabled: + type: + - boolean + - "null" + zgid: + type: + - string + - "null" + required: + - id + roles: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + display_label: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + reporting_to: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + share_with_peers: + type: + - boolean + - "null" + required: + - id + notes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Note_Content: + type: + - string + - "null" + Note_Title: + type: + - string + - "null" + Parent_Id: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + id: + type: string + required: + - id + tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_by: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + created_time: + type: + - string + - "null" + id: + type: string + modified_by: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + modified_time: + type: + - string + - "null" + name: + type: + - string + - "null" + required: + - id + companies: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Account_Name: + type: + - string + - "null" + Phone: + type: + - string + - "null" + Website: + type: + - string + - "null" + id: + type: string + required: + - id + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Email: + type: + - string + - "null" + Last_Name: + type: + - string + - "null" + id: + type: string + required: + - id + tasks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Owner: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + Subject: + type: + - string + - "null" + id: + type: string + required: + - id + events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + End_DateTime: + type: + - string + - "null" + Event_Title: + type: + - string + - "null" + Owner: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + Start_DateTime: + type: + - string + - "null" + id: + type: string + required: + - id + products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + Description: + type: + - string + - "null" + Owner: + type: + - object + - "null" + properties: + email: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + Product_Active: + type: + - boolean + - "null" + Product_Category: + type: + - string + - "null" + Product_Name: + type: + - string + - "null" + Unit_Price: + type: + - number + - "null" + id: + type: string + required: + - id diff --git a/airbyte-integrations/connectors/source-zoho-bigin/metadata.yaml b/airbyte-integrations/connectors/source-zoho-bigin/metadata.yaml new file mode 100644 index 000000000000..5a4029ff7c68 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-bigin/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "zohoapis." + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-zoho-bigin + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 30e47b8d-5132-4b24-a204-2493bda33c8d + dockerImageTag: 0.0.4 + dockerRepository: airbyte/source-zoho-bigin + githubIssueLabel: source-zoho-bigin + icon: icon.svg + license: MIT + name: Zoho Bigin + releaseDate: 2024-10-27 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/zoho-bigin + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-zoho-billing/README.md b/airbyte-integrations/connectors/source-zoho-billing/README.md new file mode 100644 index 000000000000..e09dd72f9f26 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-billing/README.md @@ -0,0 +1,35 @@ +# Zoho Billing +This directory contains the manifest-only connector for `source-zoho-billing`. + +Zoho Billing is a billing software used by countless organizations across the globe. +Using this connector we can extract data from various streams such as products , invoices , transactions and quotes. +Docs : https://www.zoho.com/billing/api/v1/introduction/#overview + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-zoho-billing:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-zoho-billing build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-zoho-billing test +``` + diff --git a/airbyte-integrations/connectors/source-zoho-billing/acceptance-test-config.yml b/airbyte-integrations/connectors/source-zoho-billing/acceptance-test-config.yml new file mode 100644 index 000000000000..3ff7a0b973cd --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-billing/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-zoho-billing:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-zoho-billing/icon.svg b/airbyte-integrations/connectors/source-zoho-billing/icon.svg new file mode 100644 index 000000000000..24430ab40ca9 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-billing/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-zoho-billing/manifest.yaml b/airbyte-integrations/connectors/source-zoho-billing/manifest.yaml new file mode 100644 index 000000000000..9250f9536446 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-billing/manifest.yaml @@ -0,0 +1,2092 @@ +version: 6.1.0 + +type: DeclarativeSource + +description: >- + Zoho Billing is a billing software used by countless organizations across the + globe. + + Using this connector we can extract data from various streams such as products + , invoices , transactions and quotes. + + Docs : https://www.zoho.com/billing/api/v1/introduction/#overview + +check: + type: CheckStream + stream_names: + - Products + +definitions: + streams: + Products: + type: DeclarativeStream + name: Products + primary_key: + - product_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: products + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - products + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/Products" + plans: + type: DeclarativeStream + name: plans + primary_key: + - plan_code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: plans + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - plans + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/plans" + addons: + type: DeclarativeStream + name: addons + primary_key: + - addon_code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: addons + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - addons + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/addons" + coupons: + type: DeclarativeStream + name: coupons + primary_key: + - coupon_code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: coupons + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - coupons + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/coupons" + customers: + type: DeclarativeStream + name: customers + primary_key: + - customer_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: customers + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - customers + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers" + Quotes: + type: DeclarativeStream + name: Quotes + primary_key: + - estimate_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: estimates + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - estimates + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/Quotes" + invoices: + type: DeclarativeStream + name: invoices + primary_key: + - invoice_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /invoices + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - invoices + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/invoices" + expenses: + type: DeclarativeStream + name: expenses + primary_key: + - expense_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /expenses + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - expenses + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/expenses" + subscriptions: + type: DeclarativeStream + name: subscriptions + primary_key: + - customer_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: subscriptions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - subscriptions + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/subscriptions" + taxes: + type: DeclarativeStream + name: taxes + primary_key: + - tax_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /settings/taxes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - taxes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/taxes" + transactions: + type: DeclarativeStream + name: transactions + primary_key: + - transaction_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: transactions + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - transactions + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/transactions" + recurring expenses: + type: DeclarativeStream + name: recurring expenses + primary_key: + - recurring_expense_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: recurringexpenses + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - recurring_expenses + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/recurring expenses" + base_requester: + type: HttpRequester + url_base: https://www.zohoapis.{{ config['region'] }}/billing/v1/ + authenticator: + type: OAuthAuthenticator + client_id: "{{ config[\"client_id\"] }}" + grant_type: refresh_token + client_secret: "{{ config[\"client_secret\"] }}" + refresh_token: "{{ config[\"refresh_token\"] }}" + expires_in_name: expires_in + access_token_name: access_token + refresh_request_body: {} + token_refresh_endpoint: https://accounts.zoho.{{ config['region'] }}/oauth/v2/token + +streams: + - $ref: "#/definitions/streams/Products" + - $ref: "#/definitions/streams/plans" + - $ref: "#/definitions/streams/addons" + - $ref: "#/definitions/streams/coupons" + - $ref: "#/definitions/streams/customers" + - $ref: "#/definitions/streams/Quotes" + - $ref: "#/definitions/streams/invoices" + - $ref: "#/definitions/streams/expenses" + - $ref: "#/definitions/streams/subscriptions" + - $ref: "#/definitions/streams/taxes" + - $ref: "#/definitions/streams/transactions" + - $ref: "#/definitions/streams/recurring expenses" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - region + - client_id + - client_secret + - refresh_token + properties: + region: + type: string + enum: + - com + - eu + - in + - com.cn + - com.au + - jp + - sa + - ca + name: region + order: 0 + title: Region + client_id: + type: string + name: client_id + order: 1 + title: OAuth Client ID + airbyte_secret: true + client_secret: + type: string + name: client_secret + order: 2 + title: OAuth Client Secret + airbyte_secret: true + refresh_token: + type: string + name: refresh_token + order: 3 + title: OAuth Refresh Token + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + Products: true + plans: true + addons: true + coupons: true + customers: true + Quotes: true + invoices: true + expenses: true + subscriptions: true + taxes: true + transactions: true + recurring expenses: true + testedStreams: + Products: + hasRecords: true + streamHash: 3559af1b8b9c39c808e7cc443ed39986d01c9f7b + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + plans: + hasRecords: true + streamHash: 87dcac9d871bd6f46ef14b9b5bb8bcac4b90b4c5 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + addons: + hasRecords: true + streamHash: cb5fbfeb69812236fb07c83d9790e0210e1d0221 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + coupons: + hasRecords: true + streamHash: 993ea9c3b516ff7d17af3c86fa96f84512a51016 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + customers: + hasRecords: true + streamHash: 3d9283d8772f0be0de752d03b3d965b35a1e64aa + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + Quotes: + hasRecords: true + streamHash: 8c5d61d9d1308824d4e7f3ffcfd6901f7e494599 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + invoices: + hasRecords: true + streamHash: 6581dfcf3271ee2bc74116b9caa5cff8a92509e6 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + expenses: + hasRecords: true + streamHash: dc0771255b9eda75a8d9639f479d2f617890abbc + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + subscriptions: + hasRecords: true + streamHash: 2736e2dc3555443a736220100e5d983f62a6d214 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + taxes: + hasRecords: true + streamHash: b2c6cc88453b1e57f032a4cf629477c7a22caa82 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + transactions: + hasRecords: true + streamHash: 8423da8f90714fd04ff6a8a0489b9a97bf0a1956 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + recurring expenses: + hasRecords: true + streamHash: 8a14a626e7a8035af06d5babb3360549f3741545 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://www.zoho.com/books/api/v3/introduction/#organization-id + +schemas: + Products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + addons_count: + type: + - number + - "null" + coupons_count: + type: + - number + - "null" + created_at: + type: + - string + - "null" + created_time: + type: + - string + - "null" + email_ids: + type: + - string + - "null" + name: + type: + - string + - "null" + plans_count: + type: + - number + - "null" + product_id: + type: string + redirect_url: + type: + - string + - "null" + status: + type: + - string + - "null" + updated_time: + type: + - string + - "null" + required: + - product_id + plans: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + account: + type: + - string + - "null" + account_id: + type: + - string + - "null" + addons: + type: + - array + - "null" + billing_cycles: + type: + - number + - "null" + billing_mode: + type: + - string + - "null" + created_time: + type: + - string + - "null" + created_time_formatted: + type: + - string + - "null" + custom_fields: + type: + - array + - "null" + interval: + type: + - number + - "null" + interval_unit: + type: + - string + - "null" + name: + type: + - string + - "null" + plan_code: + type: string + plan_id: + type: + - string + - "null" + price_brackets: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + price: + type: + - number + - "null" + pricing_scheme: + type: + - string + - "null" + pricing_scheme_formatted: + type: + - string + - "null" + product_id: + type: + - string + - "null" + product_type: + type: + - string + - "null" + recurring_price: + type: + - number + - "null" + setup_fee: + type: + - number + - "null" + setup_fee_account_id: + type: + - string + - "null" + setup_fee_account_name: + type: + - string + - "null" + shipping_interval: + type: + - number + - "null" + shipping_interval_unit: + type: + - string + - "null" + show_in_widget: + type: + - boolean + - "null" + status: + type: + - string + - "null" + store_description: + type: + - string + - "null" + store_markup_description: + type: + - string + - "null" + tax_id: + type: + - string + - "null" + tax_name: + type: + - string + - "null" + tax_percentage: + type: + - number + - "null" + tax_type: + type: + - string + - "null" + trial_period: + type: + - number + - "null" + unit: + type: + - string + - "null" + updated_time: + type: + - string + - "null" + updated_time_formatted: + type: + - string + - "null" + url: + type: + - string + - "null" + required: + - plan_code + addons: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + addon_code: + type: string + addon_id: + type: + - string + - "null" + applicable_to_all_plans: + type: + - boolean + - "null" + created_at: + type: + - string + - "null" + created_time: + type: + - string + - "null" + image_id: + type: + - string + - "null" + interval_unit: + type: + - string + - "null" + interval_unit_formatted: + type: + - string + - "null" + is_proration_disabled: + type: + - boolean + - "null" + name: + type: + - string + - "null" + plans: + type: + - array + - "null" + price_brackets: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + price: + type: + - number + - "null" + pricing_scheme: + type: + - string + - "null" + pricing_scheme_formatted: + type: + - string + - "null" + product_id: + type: + - string + - "null" + product_name: + type: + - string + - "null" + product_type: + type: + - string + - "null" + show_in_widget: + type: + - boolean + - "null" + status: + type: + - string + - "null" + status_formatted: + type: + - string + - "null" + store_description: + type: + - string + - "null" + store_markup_description: + type: + - string + - "null" + tax_id: + type: + - string + - "null" + tax_name: + type: + - string + - "null" + tax_percentage: + type: + - number + - "null" + tax_type: + type: + - string + - "null" + type_formatted: + type: + - string + - "null" + unit_name: + type: + - string + - "null" + updated_time: + type: + - string + - "null" + required: + - addon_code + coupons: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + apply_on: + type: + - string + - "null" + coupon_code: + type: string + coupon_id: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_time: + type: + - string + - "null" + discount_by: + type: + - string + - "null" + discount_value: + type: + - number + - "null" + duration: + type: + - number + - "null" + expiry_at: + type: + - string + - "null" + max_redemption: + type: + - number + - "null" + name: + type: + - string + - "null" + product_id: + type: + - string + - "null" + product_name: + type: + - string + - "null" + redemption_count: + type: + - number + - "null" + status: + type: + - string + - "null" + updated_time: + type: + - string + - "null" + required: + - coupon_code + customers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + company_name: + type: + - string + - "null" + contact_id: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_time: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + customer_id: + type: string + customer_name: + type: + - string + - "null" + display_name: + type: + - string + - "null" + email: + type: + - string + - "null" + first_name: + type: + - string + - "null" + has_attachment: + type: + - boolean + - "null" + is_backup_associated: + type: + - boolean + - "null" + is_gapps_customer: + type: + - boolean + - "null" + is_portal_invitation_accepted: + type: + - boolean + - "null" + is_primary_associated: + type: + - boolean + - "null" + last_name: + type: + - string + - "null" + mobile: + type: + - string + - "null" + outstanding: + type: + - number + - "null" + outstanding_receivable_amount: + type: + - number + - "null" + outstanding_receivable_amount_bcy: + type: + - number + - "null" + payment_terms: + type: + - number + - "null" + payment_terms_label: + type: + - string + - "null" + phone: + type: + - string + - "null" + status: + type: + - string + - "null" + unused_credits: + type: + - number + - "null" + unused_credits_receivable_amount_bcy: + type: + - number + - "null" + updated_time: + type: + - string + - "null" + website: + type: + - string + - "null" + required: + - customer_id + Quotes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accepted_date: + type: + - string + - "null" + client_viewed_time: + type: + - string + - "null" + color_code: + type: + - string + - "null" + company_name: + type: + - string + - "null" + created_time: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + currency_id: + type: + - string + - "null" + current_sub_status: + type: + - string + - "null" + current_sub_status_id: + type: + - string + - "null" + customer_id: + type: + - string + - "null" + customer_name: + type: + - string + - "null" + date: + type: + - string + - "null" + declined_date: + type: + - string + - "null" + estimate_id: + type: string + estimate_number: + type: + - string + - "null" + expiry_date: + type: + - string + - "null" + has_attachment: + type: + - boolean + - "null" + is_emailed: + type: + - boolean + - "null" + is_viewed_by_client: + type: + - boolean + - "null" + last_modified_time: + type: + - string + - "null" + reference_number: + type: + - string + - "null" + salesperson_id: + type: + - string + - "null" + salesperson_name: + type: + - string + - "null" + status: + type: + - string + - "null" + template_id: + type: + - string + - "null" + template_type: + type: + - string + - "null" + total: + type: + - number + - "null" + zcrm_potential_id: + type: + - string + - "null" + zcrm_potential_name: + type: + - string + - "null" + required: + - estimate_id + invoices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + ach_payment_initiated: + type: + - boolean + - "null" + balance: + type: + - number + - "null" + billing_address: + type: + - object + - "null" + properties: + attention: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + fax: + type: + - string + - "null" + phone: + type: + - string + - "null" + state: + type: + - string + - "null" + street: + type: + - string + - "null" + street2: + type: + - string + - "null" + zipcode: + type: + - string + - "null" + billing_city: + type: + - string + - "null" + billing_country: + type: + - string + - "null" + billing_phone: + type: + - string + - "null" + billing_state: + type: + - string + - "null" + billing_street: + type: + - string + - "null" + billing_street2: + type: + - string + - "null" + billing_zipcode: + type: + - string + - "null" + client_viewed_time: + type: + - string + - "null" + country: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_time: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + customer_id: + type: + - string + - "null" + customer_name: + type: + - string + - "null" + due_date: + type: + - string + - "null" + email: + type: + - string + - "null" + has_attachment: + type: + - boolean + - "null" + invoice_date: + type: + - string + - "null" + invoice_id: + type: string + invoice_number: + type: + - string + - "null" + is_viewed_by_client: + type: + - boolean + - "null" + is_viewed_in_mail: + type: + - boolean + - "null" + mail_first_viewed_time: + type: + - string + - "null" + mail_last_viewed_time: + type: + - string + - "null" + number: + type: + - string + - "null" + payment_expected_date: + type: + - string + - "null" + phone: + type: + - string + - "null" + project_name: + type: + - string + - "null" + reference_number: + type: + - string + - "null" + salesperson: + type: + - string + - "null" + salesperson_name: + type: + - string + - "null" + shipping_address: + type: + - object + - "null" + properties: + attention: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + fax: + type: + - string + - "null" + phone: + type: + - string + - "null" + state: + type: + - string + - "null" + street: + type: + - string + - "null" + street2: + type: + - string + - "null" + zipcode: + type: + - string + - "null" + shipping_city: + type: + - string + - "null" + shipping_country: + type: + - string + - "null" + shipping_phone: + type: + - string + - "null" + shipping_state: + type: + - string + - "null" + shipping_street: + type: + - string + - "null" + shipping_street2: + type: + - string + - "null" + shipping_zipcode: + type: + - string + - "null" + status: + type: + - string + - "null" + total: + type: + - number + - "null" + transaction_type: + type: + - string + - "null" + updated_time: + type: + - string + - "null" + required: + - invoice_id + expenses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + account_name: + type: + - string + - "null" + bcy_total: + type: + - number + - "null" + bcy_total_without_tax: + type: + - number + - "null" + created_time: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + currency_id: + type: + - string + - "null" + custom_fields_list: + type: + - string + - "null" + customer_id: + type: + - string + - "null" + customer_name: + type: + - string + - "null" + date: + type: + - string + - "null" + distance: + type: + - number + - "null" + end_reading: + type: + - string + - "null" + exchange_rate: + type: + - number + - "null" + expense_id: + type: string + expense_receipt_name: + type: + - string + - "null" + expense_type: + type: + - string + - "null" + has_attachment: + type: + - boolean + - "null" + is_billable: + type: + - boolean + - "null" + is_personal: + type: + - boolean + - "null" + last_modified_time: + type: + - string + - "null" + mileage_rate: + type: + - number + - "null" + mileage_type: + type: + - string + - "null" + mileage_unit: + type: + - string + - "null" + reference_number: + type: + - string + - "null" + report_id: + type: + - string + - "null" + report_name: + type: + - string + - "null" + report_number: + type: + - string + - "null" + start_reading: + type: + - string + - "null" + status: + type: + - string + - "null" + total: + type: + - number + - "null" + total_without_tax: + type: + - number + - "null" + required: + - expense_id + subscriptions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + activated_at: + type: + - string + - "null" + amount: + type: + - number + - "null" + auto_collect: + type: + - boolean + - "null" + billing_mode: + type: + - string + - "null" + coupon_duration: + type: + - string + - "null" + created_at: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_time: + type: + - string + - "null" + crm_owner_id: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + current_term_ends_at: + type: + - string + - "null" + current_term_starts_at: + type: + - string + - "null" + custom_field_hash: + type: + - object + - "null" + custom_fields: + type: + - array + - "null" + customer_id: + type: string + customer_name: + type: + - string + - "null" + email: + type: + - string + - "null" + expires_at: + type: + - string + - "null" + interval: + type: + - number + - "null" + interval_unit: + type: + - string + - "null" + is_metered_billing: + type: + - boolean + - "null" + mobile_phone: + type: + - string + - "null" + name: + type: + - string + - "null" + next_billing_at: + type: + - string + - "null" + next_shipment_at: + type: + - string + - "null" + next_shipment_day: + type: + - string + - "null" + orders_created: + type: + - string + - "null" + orders_remaining: + type: + - string + - "null" + payment_terms: + type: + - number + - "null" + payment_terms_label: + type: + - string + - "null" + phone: + type: + - string + - "null" + plan_code: + type: + - string + - "null" + plan_name: + type: + - string + - "null" + reference_id: + type: + - string + - "null" + salesperson_id: + type: + - string + - "null" + salesperson_name: + type: + - string + - "null" + scheduled_cancellation_date: + type: + - string + - "null" + shipping_interval: + type: + - number + - "null" + shipping_interval_unit: + type: + - string + - "null" + status: + type: + - string + - "null" + sub_total: + type: + - number + - "null" + subscription_id: + type: + - string + - "null" + subscription_number: + type: + - string + - "null" + total_orders: + type: + - string + - "null" + trial_ends_at: + type: + - string + - "null" + trial_remaining_days: + type: + - number + - "null" + trial_starts_at: + type: + - string + - "null" + updated_time: + type: + - string + - "null" + zcrm_potential_id: + type: + - string + - "null" + zcrm_potential_name: + type: + - string + - "null" + required: + - customer_id + taxes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + diff_rate_reason: + type: + - string + - "null" + end_date: + type: + - string + - "null" + is_default_tax: + type: + - boolean + - "null" + is_editable: + type: + - boolean + - "null" + is_inactive: + type: + - boolean + - "null" + last_modified_time: + type: + - string + - "null" + output_tax_account_name: + type: + - string + - "null" + start_date: + type: + - string + - "null" + status: + type: + - string + - "null" + tax_account_id: + type: + - string + - "null" + tax_id: + type: string + tax_name: + type: + - string + - "null" + tax_percentage: + type: + - number + - "null" + tax_specific_type: + type: + - string + - "null" + tax_specification: + type: + - string + - "null" + tax_type: + type: + - string + - "null" + required: + - tax_id + transactions: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + ach_payment_initiated: + type: + - boolean + - "null" + amount: + type: + - number + - "null" + date: + type: + - string + - "null" + reference_id: + type: + - string + - "null" + status: + type: + - string + - "null" + transaction_id: + type: string + required: + - transaction_id + recurring expenses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + account_name: + type: + - string + - "null" + created_time: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + currency_id: + type: + - string + - "null" + customer_name: + type: + - string + - "null" + is_billable: + type: + - boolean + - "null" + last_created_date: + type: + - string + - "null" + last_modified_time: + type: + - string + - "null" + next_expense_date: + type: + - string + - "null" + paid_through_account_name: + type: + - string + - "null" + recurrence_frequency: + type: + - string + - "null" + recurrence_name: + type: + - string + - "null" + recurring_expense_id: + type: string + repeat_every: + type: + - number + - "null" + status: + type: + - string + - "null" + total: + type: + - number + - "null" + vendor_name: + type: + - string + - "null" + required: + - recurring_expense_id diff --git a/airbyte-integrations/connectors/source-zoho-billing/metadata.yaml b/airbyte-integrations/connectors/source-zoho-billing/metadata.yaml new file mode 100644 index 000000000000..4ee21a75bc63 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-billing/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "zohoapis." + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-zoho-billing + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: cd0c7d19-6189-4ed2-9c9f-663d1bea7789 + dockerImageTag: 0.0.4 + dockerRepository: airbyte/source-zoho-billing + githubIssueLabel: source-zoho-billing + icon: icon.svg + license: MIT + name: Zoho Billing + releaseDate: 2024-11-05 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/zoho-billing + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-zoho-books/metadata.yaml b/airbyte-integrations/connectors/source-zoho-books/metadata.yaml index c45f81efa319..68958794f364 100644 --- a/airbyte-integrations/connectors/source-zoho-books/metadata.yaml +++ b/airbyte-integrations/connectors/source-zoho-books/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-zoho-books connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.16.0@sha256:6800f806944ee4fccf24ae01f6b8fbefb12d952c3b3da338f51f732b55de51f2 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: b67f9de8-177d-4d48-9c5c-8a767d845885 - dockerImageTag: 0.0.2 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-zoho-books githubIssueLabel: source-zoho-books icon: icon.svg diff --git a/airbyte-integrations/connectors/source-zoho-campaign/README.md b/airbyte-integrations/connectors/source-zoho-campaign/README.md new file mode 100644 index 000000000000..56b17f170d7a --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-campaign/README.md @@ -0,0 +1,33 @@ +# Zoho Campaign +This directory contains the manifest-only connector for `source-zoho-campaign`. + +The Zoho Campaigns connector enables seamless integration of mailing lists, campaign data, and subscriber management into your data workflows. Easily extract subscriber information, campaign reports, and list details to sync with your data warehouse or BI tools, automating marketing insights and analytics + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-zoho-campaign:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-zoho-campaign build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-zoho-campaign test +``` + diff --git a/airbyte-integrations/connectors/source-zoho-campaign/acceptance-test-config.yml b/airbyte-integrations/connectors/source-zoho-campaign/acceptance-test-config.yml new file mode 100644 index 000000000000..f3d3459412f2 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-campaign/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-zoho-campaign:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-zoho-campaign/icon.svg b/airbyte-integrations/connectors/source-zoho-campaign/icon.svg new file mode 100644 index 000000000000..e1657142b390 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-campaign/icon.svg @@ -0,0 +1,337 @@ + + + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-zoho-campaign/manifest.yaml b/airbyte-integrations/connectors/source-zoho-campaign/manifest.yaml new file mode 100644 index 000000000000..2f92bd5e012a --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-campaign/manifest.yaml @@ -0,0 +1,1367 @@ +version: 5.13.0 + +type: DeclarativeSource + +description: >- + The Zoho Campaigns connector enables seamless integration of mailing lists, + campaign data, and subscriber management into your data workflows. Easily + extract subscriber information, campaign reports, and list details to sync + with your data warehouse or BI tools, automating marketing insights and + analytics + +check: + type: CheckStream + stream_names: + - recent_campaigns + +definitions: + streams: + recent_campaigns: + type: DeclarativeStream + name: recent_campaigns + primary_key: + - campaign_key + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /recentcampaigns + http_method: GET + request_parameters: + resfmt: JSON + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 1800 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - recent_campaigns + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: fromindex + page_size_option: + type: RequestOption + field_name: range + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/recent_campaigns" + subscribers: + type: DeclarativeStream + name: subscribers + primary_key: + - contact_email + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /getlistsubscribers + http_method: GET + request_parameters: + resfmt: JSON + listkey: "{{ stream_partition.mailinglist }}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 1800 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - list_of_details + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: fromindex + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: range + pagination_strategy: + type: OffsetIncrement + page_size: 100 + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: listkey + partition_field: mailinglist + stream: + $ref: "#/definitions/streams/mailing_lists" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/subscribers" + campaign_recipients: + type: DeclarativeStream + name: campaign_recipients + primary_key: + - contactid + - sent_time + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /getcampaignrecipientsdata + http_method: POST + request_parameters: + resfmt: JSON + campaignkey: "{{ stream_partition.campaign }}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 1800 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - list_of_details + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: fromindex + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: range + pagination_strategy: + type: OffsetIncrement + page_size: 100 + partition_router: + - type: ListPartitionRouter + values: + - sentcontacts + - sentleads + - openedleads + - optoutleads + - spamleads + - unopenedleads + - clickedleads + - senthardbounce + - sentsoftbounce + - unsentleads + cursor_field: action + request_option: + type: RequestOption + inject_into: request_parameter + field_name: action + - type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: campaign_key + partition_field: campaign + stream: + $ref: "#/definitions/streams/recent_campaigns" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/campaign_recipients" + campaign_reports: + type: DeclarativeStream + name: campaign_reports + primary_key: + - campaign_name + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /campaignreports + http_method: GET + request_parameters: + resfmt: JSON + campaignkey: "{{ stream_partition.campaign }}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 1800 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - campaign-reports + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: campaign_key + partition_field: campaign + stream: + $ref: "#/definitions/streams/recent_campaigns" + transformations: + - type: AddFields + fields: + - path: + - campaign_id + value: "{{ stream_slice.campaign }}" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/campaign_reports" + recent_sent_campaigns: + type: DeclarativeStream + name: recent_sent_campaigns + primary_key: + - campaign_key + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /recentsentcampaigns + http_method: GET + request_parameters: + resfmt: JSON + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 1800 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - recent_sent_campaigns + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/recent_sent_campaigns" + mailing_lists: + type: DeclarativeStream + name: mailing_lists + primary_key: + - listunino + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /getmailinglists + http_method: GET + request_parameters: + resfmt: JSON + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - type: HttpResponseFilter + action: IGNORE + error_message: "{{ response.code == 2401 }}" + - type: DefaultErrorHandler + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - list_of_details + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: fromindex + page_size_option: + type: RequestOption + field_name: range + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 50 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/mailing_lists" + totalcontacts: + type: DeclarativeStream + name: totalcontacts + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /listsubscriberscount + http_method: GET + request_parameters: + resfmt: JSON + listkey: "{{ stream_partition.list }}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 1800 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/totalcontacts" + topics: + type: DeclarativeStream + name: topics + primary_key: + - topicId + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /topics + http_method: GET + request_parameters: + resfmt: JSON + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 1800 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - topicDetails + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/topics" + campaign_details: + type: DeclarativeStream + name: campaign_details + primary_key: + - campaign_name + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /getcampaigndetails + http_method: GET + request_parameters: + resfmt: JSON + campaignkey: "{{ stream_partition.campaign }}" + campaigntype: abtesting + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 1800 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - campaign-details + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: campaign_key + partition_field: campaign + stream: + $ref: "#/definitions/streams/recent_campaigns" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/campaign_details" + all_tags: + type: DeclarativeStream + name: all_tags + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /tag/getalltags + http_method: GET + request_parameters: + resfmt: JSON + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + backoff_strategies: + - type: ConstantBackoffStrategy + backoff_time_in_seconds: 1800 + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - tags + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/all_tags" + base_requester: + type: HttpRequester + url_base: https://campaigns.zoho.{{ config["data_center"] }}/api/v1.1 + authenticator: + type: OAuthAuthenticator + client_id: "{{ config[\"client_id_2\"] }}" + grant_type: refresh_token + client_secret: "{{ config[\"client_secret_2\"] }}" + refresh_token: "{{ config[\"client_refresh_token\"] }}" + refresh_request_body: {} + token_refresh_endpoint: https://accounts.zoho.{{ config["data_center"] }}/oauth/v2/token + +streams: + - $ref: "#/definitions/streams/recent_campaigns" + - $ref: "#/definitions/streams/subscribers" + - $ref: "#/definitions/streams/campaign_recipients" + - $ref: "#/definitions/streams/campaign_reports" + - $ref: "#/definitions/streams/recent_sent_campaigns" + - $ref: "#/definitions/streams/mailing_lists" + - $ref: "#/definitions/streams/totalcontacts" + - $ref: "#/definitions/streams/topics" + - $ref: "#/definitions/streams/campaign_details" + - $ref: "#/definitions/streams/all_tags" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - client_id_2 + - client_secret_2 + - client_refresh_token + - data_center + properties: + client_id_2: + type: string + order: 0 + title: Client ID + airbyte_secret: true + client_secret_2: + type: string + order: 1 + title: Client secret + airbyte_secret: true + client_refresh_token: + type: string + order: 2 + title: Refresh token + airbyte_secret: true + data_center: + type: string + enum: + - com + - eu + - in + - com.au + - .jp + - .com.cn + order: 3 + title: Data Center + additionalProperties: true + +metadata: + autoImportSchema: + recent_campaigns: true + subscribers: true + campaign_recipients: true + campaign_reports: true + recent_sent_campaigns: true + mailing_lists: true + totalcontacts: true + topics: true + campaign_details: true + all_tags: true + testedStreams: + recent_campaigns: + streamHash: 052f317ac38ff9053fcf422d6d74e98b41b6d6fb + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + subscribers: + streamHash: d3396ae328d2f89c19cd5e43ff992471f53dd2d0 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + campaign_recipients: + streamHash: 76b350a63b309d97e64422702c1819f81ac05f24 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + campaign_reports: + streamHash: 4d4771e0500c2dd6b3a00f1bc9c035a30bb89d8b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + recent_sent_campaigns: + streamHash: f725af920df289a0cd6d56f41a39125125844d5c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + mailing_lists: + streamHash: 6fb0504ab9f914cb8ffc60915f8e33256bb9b8fb + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + totalcontacts: + hasRecords: true + streamHash: 0e65a5ac5c8668c0fc525db00b39df7925f056c6 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + topics: + streamHash: cdc2bebe838eb98ad13d5c51b7484bb8a925ec82 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + campaign_details: + streamHash: 0cc0ec37e3628ed58daa3b9c91b7a7572cc35447 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + all_tags: + streamHash: 2f50415e2d6e086d57a235042080daa49c75009e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://www.zoho.com/campaigns/help/developers/access-token.html + +schemas: + recent_campaigns: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + campaign_key: + type: string + campaign_name: + type: + - string + - "null" + campaign_preview: + type: + - string + - "null" + campaign_status: + type: + - string + - "null" + campaigntype: + type: + - string + - "null" + created_date_string: + type: + - string + - "null" + created_time: + type: + - string + - "null" + created_time_gmt: + type: + - string + - "null" + folder_id: + type: + - string + - "null" + from_email: + type: + - string + - "null" + is_hybrid: + type: + - string + - "null" + reply_to: + type: + - string + - "null" + sent_date_string: + type: + - string + - "null" + sent_time: + type: + - string + - "null" + sent_time_gmt: + type: + - string + - "null" + sent_time_zone: + type: + - string + - "null" + subject: + type: + - string + - "null" + updated_date_string: + type: + - string + - "null" + updated_time: + type: + - string + - "null" + updated_time_gmt: + type: + - string + - "null" + zuid: + type: + - string + - "null" + required: + - campaign_key + subscribers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + added_time: + type: + - string + - "null" + companyname: + type: + - string + - "null" + contact_email: + type: string + firstname: + type: + - string + - "null" + lastname: + type: + - string + - "null" + phone: + type: + - string + - "null" + zuid: + type: + - string + - "null" + required: + - contact_email + campaign_recipients: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address: + type: + - string + - "null" + city: + type: + - string + - "null" + companyname: + type: + - string + - "null" + contactemailaddress: + type: + - string + - "null" + contactfn: + type: + - string + - "null" + contactid: + type: string + contactln: + type: + - string + - "null" + contactstatus: + type: + - string + - "null" + country: + type: + - string + - "null" + facebook_handle: + type: + - string + - "null" + jobtitle: + type: + - string + - "null" + linkedin_handle: + type: + - string + - "null" + mobile: + type: + - string + - "null" + note: + type: + - string + - "null" + phone: + type: + - string + - "null" + secondary_email: + type: + - string + - "null" + sent_time: + type: string + sentdate: + type: + - string + - "null" + state: + type: + - string + - "null" + timezone: + type: + - string + - "null" + title: + type: + - string + - "null" + twitter_handle: + type: + - string + - "null" + website: + type: + - string + - "null" + zipcode: + type: + - string + - "null" + required: + - contactid + - sent_time + campaign_reports: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + autoreply_count: + type: + - string + - "null" + bounce_percent: + type: + - string + - "null" + bounces_count: + type: + - string + - "null" + campaign_id: + type: + - string + - "null" + campaign_name: + type: string + clicksperopenrate: + type: + - string + - "null" + complaints_count: + type: + - string + - "null" + complaints_percent: + type: + - string + - "null" + delivered_count: + type: + - string + - "null" + delivered_percent: + type: + - string + - "null" + emails_sent_count: + type: + - string + - "null" + forward_percent: + type: + - string + - "null" + forwards_count: + type: + - string + - "null" + hardbounce_count: + type: + - string + - "null" + open_percent: + type: + - string + - "null" + opens_count: + type: + - string + - "null" + softbounce_count: + type: + - string + - "null" + spam_percent: + type: + - string + - "null" + spams_count: + type: + - string + - "null" + unique_clicked_percent: + type: + - string + - "null" + unique_clicks_count: + type: + - string + - "null" + unopened: + type: + - string + - "null" + unopened_percent: + type: + - string + - "null" + unsent_count: + type: + - string + - "null" + unsent_percent: + type: + - string + - "null" + unsub_count: + type: + - string + - "null" + unsubscribe_percent: + type: + - string + - "null" + required: + - campaign_name + recent_sent_campaigns: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + campaign_key: + type: string + campaign_name: + type: + - string + - "null" + campaign_status: + type: + - string + - "null" + campaignid: + type: + - string + - "null" + campaigntype: + type: + - string + - "null" + created_date_string: + type: + - string + - "null" + created_time: + type: + - string + - "null" + created_time_gmt: + type: + - string + - "null" + folder_id: + type: + - string + - "null" + from_name: + type: + - string + - "null" + is_hybrid: + type: + - string + - "null" + previewtype: + type: + - string + - "null" + sent_date_string: + type: + - string + - "null" + sent_time: + type: + - string + - "null" + sent_time_gmt: + type: + - string + - "null" + sent_time_zone: + type: + - string + - "null" + zuid: + type: + - string + - "null" + required: + - campaign_key + mailing_lists: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + created_time: + type: + - string + - "null" + created_time_gmt: + type: + - string + - "null" + date: + type: + - string + - "null" + deletable: + type: + - string + - "null" + editable: + type: + - string + - "null" + is_public: + type: + - string + - "null" + issmart: + type: + - string + - "null" + list_campaigns_count: + type: + - string + - "null" + list_created_date: + type: + - string + - "null" + list_created_time: + type: + - string + - "null" + listdesc: + type: + - string + - "null" + listdgs: + type: + - string + - "null" + listkey: + type: + - string + - "null" + listname: + type: + - string + - "null" + listnotifications: + type: + - string + - "null" + listtype: + type: + - string + - "null" + listunino: + type: string + lockstatus: + type: + - string + - "null" + noofbouncecnt: + type: + - string + - "null" + noofcontacts: + type: + - string + - "null" + noofunsubcnt: + type: + - string + - "null" + otherslist: + type: + - string + - "null" + owner: + type: + - string + - "null" + segments: + type: + - object + - "null" + sentcnt: + type: + - string + - "null" + servicetype: + type: + - string + - "null" + sno: + type: + - string + - "null" + updated_time_gmt: + type: + - string + - "null" + zuid: + type: + - string + - "null" + zx: + type: + - string + - "null" + required: + - listunino + totalcontacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - string + - "null" + Code: + type: + - string + - "null" + URI: + type: + - string + - "null" + message: + type: + - string + - "null" + status: + type: + - string + - "null" + topics: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + primaryList: + type: + - number + - "null" + topicDesc: + type: + - string + - "null" + topicId: + type: string + topicName: + type: + - string + - "null" + required: + - topicId + campaign_details: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + advanceTypeString: + type: + - string + - "null" + campaign_key: + type: + - string + - "null" + campaign_name: + type: string + campaign_preview: + type: + - string + - "null" + campaigntype: + type: + - string + - "null" + created_date_string: + type: + - string + - "null" + created_time: + type: + - string + - "null" + created_time_gmt: + type: + - string + - "null" + email_from: + type: + - string + - "null" + email_options: + type: + - string + - "null" + email_subject: + type: + - string + - "null" + email_type: + type: + - string + - "null" + encodeName: + type: + - string + - "null" + folder_id: + type: + - string + - "null" + isGAConfig: + type: + - string + - "null" + isReplyTrackingEnabled: + type: + - string + - "null" + isToNameConfig: + type: + - string + - "null" + isWistia: + type: + - string + - "null" + is_advance: + type: + - string + - "null" + is_hybrid: + type: + - string + - "null" + modified_time: + type: + - string + - "null" + modified_time_gmt: + type: + - string + - "null" + modifieddate: + type: + - string + - "null" + preheader: + type: + - string + - "null" + reply_to: + type: + - string + - "null" + schedule_type: + type: + - string + - "null" + sender_name: + type: + - string + - "null" + sent_date_string: + type: + - string + - "null" + sent_time: + type: + - string + - "null" + sent_time_gmt: + type: + - string + - "null" + sent_time_zone: + type: + - string + - "null" + sent_time_zone_short: + type: + - string + - "null" + topic_id: + type: + - string + - "null" + topic_name: + type: + - string + - "null" + updated_date_string: + type: + - string + - "null" + updated_time: + type: + - string + - "null" + updated_time_gmt: + type: + - string + - "null" + webAutoStatus: + type: + - string + - "null" + zuid: + type: + - string + - "null" + required: + - campaign_name + all_tags: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + "169443000000020045": + type: + - object + - "null" + properties: + is_crm_tag: + type: + - string + - "null" + tag_color: + type: + - string + - "null" + tag_created_time: + type: + - string + - "null" + tag_desc: + type: + - string + - "null" + tag_modified_time: + type: + - string + - "null" + tag_name: + type: + - string + - "null" + tagged_contact_count: + type: + - string + - "null" + tagowner: + type: + - string + - "null" + zuid: + type: + - string + - "null" diff --git a/airbyte-integrations/connectors/source-zoho-campaign/metadata.yaml b/airbyte-integrations/connectors/source-zoho-campaign/metadata.yaml new file mode 100644 index 000000000000..4150067c46db --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-campaign/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "https://campaigns.zoho.*/api/" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-zoho-campaign + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 1d0d5605-604b-401a-8a69-92f841a95a90 + dockerImageTag: 0.0.4 + dockerRepository: airbyte/source-zoho-campaign + githubIssueLabel: source-zoho-campaign + icon: icon.svg + license: MIT + name: Zoho Campaign + releaseDate: 2024-10-14 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/zoho-campaign + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-zoho-crm/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-zoho-crm/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-zoho-crm/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-zoho-crm/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-zoho-crm/integration_tests/test_stream_factory.py b/airbyte-integrations/connectors/source-zoho-crm/integration_tests/test_stream_factory.py index 472f2799e63d..76d7794113f8 100644 --- a/airbyte-integrations/connectors/source-zoho-crm/integration_tests/test_stream_factory.py +++ b/airbyte-integrations/connectors/source-zoho-crm/integration_tests/test_stream_factory.py @@ -11,6 +11,7 @@ import requests from source_zoho_crm.streams import IncrementalZohoCrmStream, ZohoStreamFactory + HERE = Path(__file__).parent diff --git a/airbyte-integrations/connectors/source-zoho-crm/main.py b/airbyte-integrations/connectors/source-zoho-crm/main.py index 2cf82bb23bf9..d04f943d86bf 100644 --- a/airbyte-integrations/connectors/source-zoho-crm/main.py +++ b/airbyte-integrations/connectors/source-zoho-crm/main.py @@ -4,5 +4,6 @@ from source_zoho_crm.run import run + if __name__ == "__main__": run() diff --git a/airbyte-integrations/connectors/source-zoho-crm/setup.py b/airbyte-integrations/connectors/source-zoho-crm/setup.py index 15425f380be4..b9ebc28e9f6a 100644 --- a/airbyte-integrations/connectors/source-zoho-crm/setup.py +++ b/airbyte-integrations/connectors/source-zoho-crm/setup.py @@ -5,6 +5,7 @@ from setuptools import find_packages, setup + MAIN_REQUIREMENTS = [ "airbyte-cdk", ] diff --git a/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/api.py b/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/api.py index edb92e2c8e5d..abaf9d55c761 100644 --- a/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/api.py +++ b/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/api.py @@ -11,6 +11,7 @@ from .auth import ZohoOauth2Authenticator + logger = logging.getLogger(__name__) diff --git a/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/auth.py b/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/auth.py index f6cde3b11210..6f47fddbee11 100644 --- a/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/auth.py +++ b/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/auth.py @@ -5,6 +5,7 @@ from typing import Any, Dict, Mapping, Tuple import requests + from airbyte_cdk.sources.streams.http.requests_native_auth import Oauth2Authenticator diff --git a/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/run.py b/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/run.py index d915dc05f2b9..05ca883b8f7e 100644 --- a/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/run.py +++ b/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/run.py @@ -5,9 +5,10 @@ import sys -from airbyte_cdk.entrypoint import launch from source_zoho_crm import SourceZohoCrm +from airbyte_cdk.entrypoint import launch + def run(): source = SourceZohoCrm() diff --git a/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/source.py b/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/source.py index d6ead32026f8..f5f4ee55e470 100644 --- a/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/source.py +++ b/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/source.py @@ -10,6 +10,7 @@ from .api import ZohoAPI from .streams import ZohoStreamFactory + if TYPE_CHECKING: # This is a workaround to avoid circular import in the future. # TYPE_CHECKING is False at runtime, but True when system performs type checking diff --git a/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/streams.py b/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/streams.py index ad6b26868396..53df5ab1e428 100644 --- a/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/streams.py +++ b/airbyte-integrations/connectors/source-zoho-crm/source_zoho_crm/streams.py @@ -11,12 +11,14 @@ from typing import Any, Dict, Iterable, List, Mapping, MutableMapping, Optional import requests + from airbyte_cdk.sources.streams.http import HttpStream from .api import ZohoAPI from .exceptions import IncompleteMetaDataException, UnknownDataTypeException from .types import FieldMeta, ModuleMeta, ZohoPickListItem + # 204 and 304 status codes are valid successful responses, # but `.json()` will fail because the response body is empty EMPTY_BODY_STATUSES = (HTTPStatus.NO_CONTENT, HTTPStatus.NOT_MODIFIED) diff --git a/airbyte-integrations/connectors/source-zoho-crm/unit_tests/parametrize.py b/airbyte-integrations/connectors/source-zoho-crm/unit_tests/parametrize.py index 31ad48a1a41c..ca796e341b23 100644 --- a/airbyte-integrations/connectors/source-zoho-crm/unit_tests/parametrize.py +++ b/airbyte-integrations/connectors/source-zoho-crm/unit_tests/parametrize.py @@ -6,6 +6,7 @@ import pytest + TestCase = namedtuple( "TestCase", ("json_type", "data_type", "length", "decimal_place", "api_name", "pick_list_values", "autonumber", "expected_values") ) diff --git a/airbyte-integrations/connectors/source-zoho-crm/unit_tests/test_auth.py b/airbyte-integrations/connectors/source-zoho-crm/unit_tests/test_auth.py index 0fea743d100d..a32f0adf2140 100644 --- a/airbyte-integrations/connectors/source-zoho-crm/unit_tests/test_auth.py +++ b/airbyte-integrations/connectors/source-zoho-crm/unit_tests/test_auth.py @@ -6,6 +6,7 @@ from source_zoho_crm.auth import ZohoOauth2Authenticator + authenticator = ZohoOauth2Authenticator("http://dummy.url/oauth/v2/token", "client_id", "client_secret", "refresh_token") diff --git a/airbyte-integrations/connectors/source-zoho-crm/unit_tests/test_incremental_streams.py b/airbyte-integrations/connectors/source-zoho-crm/unit_tests/test_incremental_streams.py index 3774064c60a2..e761736c840b 100644 --- a/airbyte-integrations/connectors/source-zoho-crm/unit_tests/test_incremental_streams.py +++ b/airbyte-integrations/connectors/source-zoho-crm/unit_tests/test_incremental_streams.py @@ -5,9 +5,10 @@ from unittest.mock import Mock import pytest -from airbyte_cdk.models import SyncMode from source_zoho_crm.streams import IncrementalZohoCrmStream as BaseIncrementalZohoCrmStream +from airbyte_cdk.models import SyncMode + @pytest.fixture def stream_factory(mocker): diff --git a/airbyte-integrations/connectors/source-zoho-desk/README.md b/airbyte-integrations/connectors/source-zoho-desk/README.md new file mode 100644 index 000000000000..01db87f261ad --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-desk/README.md @@ -0,0 +1,37 @@ +# Zoho Desk +This directory contains the manifest-only connector for `source-zoho-desk`(https://www.zoho.com/desk). + +## Documentation reference: +- Visit `https://desk.zoho.com/DeskAPIDocument#Introduction` for API documentation + +## Authentication setup +`Zoho Desk's` APIs use the industry-standard OAuth 2.0 protocol for authentication and authorization, Visit `https://desk.zoho.com/DeskAPIDocument#OauthTokens` for getting your api keys. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-zoho-desk:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-zoho-desk build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-zoho-desk test +``` + diff --git a/airbyte-integrations/connectors/source-zoho-desk/acceptance-test-config.yml b/airbyte-integrations/connectors/source-zoho-desk/acceptance-test-config.yml new file mode 100644 index 000000000000..6484f0c6bcee --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-desk/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-zoho-desk:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-zoho-desk/icon.svg b/airbyte-integrations/connectors/source-zoho-desk/icon.svg new file mode 100644 index 000000000000..d3fe704da11f --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-desk/icon.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-zoho-desk/manifest.yaml b/airbyte-integrations/connectors/source-zoho-desk/manifest.yaml new file mode 100644 index 000000000000..76854337fb35 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-desk/manifest.yaml @@ -0,0 +1,5122 @@ +version: 5.15.0 + +type: DeclarativeSource + +description: |- + Website: https://www.zoho.com/desk + API Docs: https://desk.zoho.com/DeskAPIDocument#Introduction + Auth Docs: https://desk.zoho.com/DeskAPIDocument#OauthTokens + +check: + type: CheckStream + stream_names: + - organization + +definitions: + streams: + organization: + type: DeclarativeStream + name: organization + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: organizations/{{ stream_partition.organization_id }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: organization_id + stream: + $ref: "#/definitions/streams/all_organizations" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/organization" + all_organizations: + type: DeclarativeStream + name: all_organizations + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /organizations + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/all_organizations" + accessible_organizations: + type: DeclarativeStream + name: accessible_organizations + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accessibleOrganizations + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/accessible_organizations" + agent: + type: DeclarativeStream + name: agent + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /agents/{{ stream_partition.agent_id }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: agent_id + stream: + $ref: "#/definitions/streams/list_agents" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/agent" + list_agents: + type: DeclarativeStream + name: list_agents + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /agents + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 50 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_agents" + agent_details_by_id: + type: DeclarativeStream + name: agent_details_by_id + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /agentsByIds?agentIds={{ stream_partition.agent_id }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: agent_id + stream: + $ref: "#/definitions/streams/list_agents" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/agent_details_by_id" + profiles: + type: DeclarativeStream + name: profiles + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /profiles + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/profiles" + list_roles: + type: DeclarativeStream + name: list_roles + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /roles + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 50 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_roles" + teams: + type: DeclarativeStream + name: teams + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /teams + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - teams + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/teams" + team_members: + type: DeclarativeStream + name: team_members + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /teams/{{ stream_partition.team_id }}/members + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - members + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: team_id + stream: + $ref: "#/definitions/streams/teams" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/team_members" + list_departments: + type: DeclarativeStream + name: list_departments + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /departments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 50 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_departments" + channels: + type: DeclarativeStream + name: channels + primary_key: + - code + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /channels + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/channels" + list_tickets: + type: DeclarativeStream + name: list_tickets + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /tickets + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 50 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_tickets" + list_all_threads: + type: DeclarativeStream + name: list_all_threads + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /tickets/{{ stream_partition.ticket_id }}/threads + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 50 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: ticket_id + stream: + $ref: "#/definitions/streams/list_tickets" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_all_threads" + get_latest_thread: + type: DeclarativeStream + name: get_latest_thread + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /tickets/{{ stream_partition.ticket_id }}/latestThread + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: ticket_id + stream: + $ref: "#/definitions/streams/list_tickets" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/get_latest_thread" + list_contacts: + type: DeclarativeStream + name: list_contacts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 50 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_contacts" + webhooks: + type: DeclarativeStream + name: webhooks + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /webhooks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/webhooks" + list_accounts: + type: DeclarativeStream + name: list_accounts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 50 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_accounts" + list_contracts: + type: DeclarativeStream + name: list_contracts + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /accounts/{{ stream_partition.account_id }}/contracts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 50 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: account_id + stream: + $ref: "#/definitions/streams/list_accounts" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_contracts" + list_tasks: + type: DeclarativeStream + name: list_tasks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /tasks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 50 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_tasks" + list_products: + type: DeclarativeStream + name: list_products + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /products + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 50 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_products" + list_articles: + type: DeclarativeStream + name: list_articles + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /articles + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_articles" + list_events: + type: DeclarativeStream + name: list_events + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /events + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 50 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_events" + modules: + type: DeclarativeStream + name: modules + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /organizationModules + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/modules" + list_users: + type: DeclarativeStream + name: list_users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 50 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_users" + ticket_activities: + type: DeclarativeStream + name: ticket_activities + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /tickets/{{ stream_partition.ticket_id }}/activities + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: ticket_id + stream: + $ref: "#/definitions/streams/list_tickets" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/ticket_activities" + list_attachments: + type: DeclarativeStream + name: list_attachments + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /products/{{ stream_partition.product_id }}/attachments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: product_id + stream: + $ref: "#/definitions/streams/list_products" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_attachments" + product: + type: DeclarativeStream + name: product + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /products/{{ stream_partition.product_id }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: product_id + stream: + $ref: "#/definitions/streams/list_products" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/product" + task_attachments: + type: DeclarativeStream + name: task_attachments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /tasks/{{ stream_partition.task_id }}/attachments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: task_id + stream: + $ref: "#/definitions/streams/list_tasks" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/task_attachments" + list_calls: + type: DeclarativeStream + name: list_calls + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /calls + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_calls" + call: + type: DeclarativeStream + name: call + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /calls/{{ stream_partition.call_id }} + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: call_id + stream: + $ref: "#/definitions/streams/list_calls" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/call" + list_call_comments: + type: DeclarativeStream + name: list_call_comments + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /calls/{{ stream_partition.call_id }}/comments + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 100 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: call_id + stream: + $ref: "#/definitions/streams/list_calls" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_call_comments" + dashboard_created_tickets: + type: DeclarativeStream + name: dashboard_created_tickets + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /dashboards/createdTickets + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + partition_router: + - type: ListPartitionRouter + values: + - date + - channel + - agent + cursor_field: groupBy + request_option: + type: RequestOption + field_name: groupBy + inject_into: request_parameter + - type: ListPartitionRouter + values: + - LAST_7_DAYS + cursor_field: duration + request_option: + type: RequestOption + field_name: duration + inject_into: request_parameter + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/dashboard_created_tickets" + list_user_groups: + type: DeclarativeStream + name: list_user_groups + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /users/{{ stream_partition.user_id }}/groups + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: from + page_size_option: + type: RequestOption + field_name: limit + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 50 + inject_on_first_request: true + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - type: ParentStreamConfig + parent_key: id + partition_field: user_id + stream: + $ref: "#/definitions/streams/list_users" + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/list_user_groups" + dashboard_onhold_tickets: + type: DeclarativeStream + name: dashboard_onhold_tickets + primary_key: + - value + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /dashboards/onholdTickets + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - ticketCount + partition_router: + - type: ListPartitionRouter + values: + - date + - channel + - agent + cursor_field: groupBy + request_option: + type: RequestOption + field_name: groupBy + inject_into: request_parameter + - type: ListPartitionRouter + values: + - LAST_7_DAYS + cursor_field: duration + request_option: + type: RequestOption + field_name: duration + inject_into: request_parameter + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/dashboard_onhold_tickets" + base_requester: + type: HttpRequester + url_base: https://desk.zoho.com/api/v1 + authenticator: + type: OAuthAuthenticator + client_id: "{{ config[\"client_id\"] }}" + grant_type: refresh_token + client_secret: "{{ config[\"client_secret\"] }}" + refresh_token: "{{ config[\"refresh_token\"] }}" + expires_in_name: expires_in + access_token_name: access_token + refresh_request_body: {} + token_refresh_endpoint: "{{ config[\"token_refresh_endpoint\"] }}" + +streams: + - $ref: "#/definitions/streams/organization" + - $ref: "#/definitions/streams/all_organizations" + - $ref: "#/definitions/streams/accessible_organizations" + - $ref: "#/definitions/streams/agent" + - $ref: "#/definitions/streams/list_agents" + - $ref: "#/definitions/streams/agent_details_by_id" + - $ref: "#/definitions/streams/profiles" + - $ref: "#/definitions/streams/list_roles" + - $ref: "#/definitions/streams/teams" + - $ref: "#/definitions/streams/team_members" + - $ref: "#/definitions/streams/list_departments" + - $ref: "#/definitions/streams/channels" + - $ref: "#/definitions/streams/list_tickets" + - $ref: "#/definitions/streams/list_all_threads" + - $ref: "#/definitions/streams/get_latest_thread" + - $ref: "#/definitions/streams/list_contacts" + - $ref: "#/definitions/streams/webhooks" + - $ref: "#/definitions/streams/list_accounts" + - $ref: "#/definitions/streams/list_contracts" + - $ref: "#/definitions/streams/list_tasks" + - $ref: "#/definitions/streams/list_products" + - $ref: "#/definitions/streams/list_articles" + - $ref: "#/definitions/streams/list_events" + - $ref: "#/definitions/streams/modules" + - $ref: "#/definitions/streams/list_users" + - $ref: "#/definitions/streams/ticket_activities" + - $ref: "#/definitions/streams/list_attachments" + - $ref: "#/definitions/streams/product" + - $ref: "#/definitions/streams/task_attachments" + - $ref: "#/definitions/streams/list_calls" + - $ref: "#/definitions/streams/call" + - $ref: "#/definitions/streams/list_call_comments" + - $ref: "#/definitions/streams/dashboard_created_tickets" + - $ref: "#/definitions/streams/list_user_groups" + - $ref: "#/definitions/streams/dashboard_onhold_tickets" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - client_id + - client_secret + - token_refresh_endpoint + - refresh_token + properties: + client_id: + type: string + order: 0 + title: Client ID + airbyte_secret: true + client_secret: + type: string + order: 1 + title: Client secret + airbyte_secret: true + token_refresh_endpoint: + type: string + name: token_refresh_endpoint + order: 2 + title: Token Refresh Endpoint + refresh_token: + type: string + name: refresh_token + order: 3 + title: OAuth Refresh Token + airbyte_secret: true + include_custom_domain: + type: boolean + order: 4 + title: include Custom Domain + additionalProperties: true + +metadata: + autoImportSchema: + organization: true + all_organizations: true + accessible_organizations: false + agent: false + list_agents: false + agent_details_by_id: true + profiles: true + list_roles: true + teams: true + team_members: true + list_departments: true + channels: true + list_tickets: true + list_all_threads: true + get_latest_thread: true + list_contacts: true + webhooks: true + list_accounts: true + list_contracts: true + list_tasks: true + list_products: true + list_articles: true + list_events: true + modules: true + list_users: true + ticket_activities: true + list_attachments: true + product: true + task_attachments: false + list_calls: true + call: true + list_call_comments: true + dashboard_created_tickets: true + list_user_groups: true + dashboard_onhold_tickets: true + testedStreams: + organization: + hasRecords: true + streamHash: c7474fdc181562625a167a16855f8487649920e7 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + all_organizations: + hasRecords: true + streamHash: 65331d4ff0ce0918979fa07398fc6cd189b6a8aa + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + accessible_organizations: + hasRecords: true + streamHash: 579a5a75e86b46a236f44e22399f0c2d2e2aaade + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + agent: + hasRecords: true + streamHash: f29421eb7df4101ddb3cda487aa843ff2df20824 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_agents: + hasRecords: true + streamHash: 3d7c1c2deaaf9aca63175baade6df1760c8942e0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + agent_details_by_id: + hasRecords: true + streamHash: 34c952e5f484b818dd88efe3b91906e235716ee1 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + profiles: + hasRecords: true + streamHash: 665eac4c08235e16608481cc1e06207920a1b266 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_roles: + hasRecords: true + streamHash: ea36b640fed755bea0f3b0a8478da6ad12048b02 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + teams: + hasRecords: true + streamHash: e50031af9f6d3cdfbd829e737581e72eed8a0293 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + team_members: + hasRecords: true + streamHash: 08adb08a9a2758a0b8d8878ec393c7b8f351eb53 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_departments: + hasRecords: true + streamHash: a52794803739fae526a5ea14c52730b27fce67be + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + channels: + hasRecords: true + streamHash: d9b6a1896c261d4f84327fdd15069fa77a8c1b1d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_tickets: + hasRecords: true + streamHash: 4d0886f40f123633c969d3344aa27a435bc75e2c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_all_threads: + hasRecords: true + streamHash: d49ff74630c3f0b00e6748e430acd013ee98815c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + get_latest_thread: + hasRecords: true + streamHash: 494839a05573d745a5d7f38ccbf2baaaacad70cd + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_contacts: + hasRecords: true + streamHash: 5b5d8224e5f4824af32b711faabf6e1636ff7d79 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + webhooks: + hasRecords: true + streamHash: fa1d5f9ab3643b61717ea63ba5f7d914c0d903f0 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_accounts: + hasRecords: true + streamHash: f423eacdfb8de296b15b8e72b15488ecd4c02ef6 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_contracts: + hasRecords: true + streamHash: a722a43cb1fc8466921a60eff9c622ab89094f9a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_tasks: + hasRecords: true + streamHash: d8c270148e1e7c22005a136cdea2de5347b73245 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_products: + hasRecords: true + streamHash: 38a7ca22f0eec3037f47eb7906ddf0fdd85f98eb + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_articles: + streamHash: d3b131b9cbd84461e43059802adb9bc32290d2a2 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + list_events: + hasRecords: true + streamHash: 1c50a3f32a4b9fb66c00b7fa3579eb8705e999bd + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + modules: + hasRecords: true + streamHash: 65b4ef477933db9cb4a76bcfdc51d5db8b7ce1cf + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_users: + hasRecords: true + streamHash: 453457445af4b1492c7d425fe74d80ebd38e7408 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + ticket_activities: + hasRecords: true + streamHash: 63924fcb8ee340210157fed5f0cb21d3501e1c47 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_attachments: + hasRecords: true + streamHash: 40fc06423f1035cc78f732dfb830d0b117658f0e + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + product: + hasRecords: true + streamHash: b971c0e0e97fa2ae85acdb2f935f1d05b6314eac + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + task_attachments: + hasRecords: true + streamHash: a6353a112894b0c954f4c621161a7d0b7252c083 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_calls: + hasRecords: true + streamHash: c29edb110ef142088a0fdcd7d7574024e67910a2 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + call: + hasRecords: true + streamHash: 2a0b4bd52569c5d0439fef01c208136f32b08e40 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_call_comments: + hasRecords: true + streamHash: 4ec232254a8f343213e09be088dd7be12025db28 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + dashboard_created_tickets: + hasRecords: true + streamHash: b09e6d48aca75d2f9ca5926c3c0e4e2522ae2dbd + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + list_user_groups: + hasRecords: true + streamHash: 581eb05ccdd057ca3e6fb991abc23a0842f22b3c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + dashboard_onhold_tickets: + hasRecords: true + streamHash: 88da2a446c150b77378a8fbc4d5d5edec6693e34 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://desk.zoho.com/DeskAPIDocument + +schemas: + organization: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + city: + type: + - string + - "null" + companyName: + type: + - string + - "null" + country: + type: + - string + - "null" + currencyCode: + type: + - string + - "null" + currencyLocale: + type: + - string + - "null" + currencySymbol: + type: + - string + - "null" + edition: + type: + - string + - "null" + employeeCount: + type: + - number + - "null" + faviconURL: + type: + - string + - "null" + fax: + type: + - string + - "null" + id: + type: number + isAdminInOrg: + type: + - boolean + - "null" + isDefault: + type: + - boolean + - "null" + isPayloadEncryptionEnabled: + type: + - boolean + - "null" + isSandboxPortal: + type: + - boolean + - "null" + logoURL: + type: + - string + - "null" + mobile: + type: + - string + - "null" + phoneNumber: + type: + - string + - "null" + portalName: + type: + - string + - "null" + portalURL: + type: + - string + - "null" + primaryContact: + type: + - string + - "null" + state: + type: + - string + - "null" + street: + type: + - string + - "null" + website: + type: + - string + - "null" + zip: + type: + - string + - "null" + required: + - id + all_organizations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + city: + type: + - string + - "null" + companyName: + type: + - string + - "null" + country: + type: + - string + - "null" + currencyCode: + type: + - string + - "null" + currencyLocale: + type: + - string + - "null" + currencySymbol: + type: + - string + - "null" + edition: + type: + - string + - "null" + employeeCount: + type: + - number + - "null" + faviconURL: + type: + - string + - "null" + fax: + type: + - string + - "null" + id: + type: number + isAdminInOrg: + type: + - boolean + - "null" + isDefault: + type: + - boolean + - "null" + isPayloadEncryptionEnabled: + type: + - boolean + - "null" + isSandboxPortal: + type: + - boolean + - "null" + logoURL: + type: + - string + - "null" + mobile: + type: + - string + - "null" + phoneNumber: + type: + - string + - "null" + portalName: + type: + - string + - "null" + portalURL: + type: + - string + - "null" + primaryContact: + type: + - string + - "null" + state: + type: + - string + - "null" + street: + type: + - string + - "null" + website: + type: + - string + - "null" + zip: + type: + - string + - "null" + required: + - id + accessible_organizations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + city: + type: + - string + - "null" + companyName: + type: + - string + - "null" + country: + type: + - string + - "null" + currencyCode: + type: + - string + - "null" + currencyLocale: + type: + - string + - "null" + currencySymbol: + type: + - string + - "null" + edition: + type: + - string + - "null" + employeeCount: + type: + - number + - "null" + faviconURL: + type: + - string + - "null" + fax: + type: + - string + - "null" + id: + type: + - number + - "null" + isAdminInOrg: + type: + - boolean + - "null" + isDefault: + type: + - boolean + - "null" + isPayloadEncryptionEnabled: + type: + - boolean + - "null" + isSandboxPortal: + type: + - boolean + - "null" + logoURL: + type: + - string + - "null" + mobile: + type: + - string + - "null" + phoneNumber: + type: + - string + - "null" + portalName: + type: + - string + - "null" + portalURL: + type: + - string + - "null" + primaryContact: + type: + - string + - "null" + state: + type: + - string + - "null" + street: + type: + - string + - "null" + website: + type: + - string + - "null" + zip: + type: + - string + - "null" + agent: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + aboutInfo: + type: + - string + - "null" + associatedChatDepartmentIds: + type: + - array + - "null" + associatedDepartmentIds: + type: + - array + - "null" + items: + type: + - string + - "null" + cf: + type: + - object + - "null" + channelExpert: + type: + - array + - "null" + countryCode: + type: + - string + - "null" + emailId: + type: + - string + - "null" + extn: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: + - string + - "null" + isConfirmed: + type: + - boolean + - "null" + langCode: + type: + - string + - "null" + lastName: + type: + - string + - "null" + mobile: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + profileId: + type: + - string + - "null" + roleId: + type: + - string + - "null" + rolePermissionType: + type: + - string + - "null" + status: + type: + - string + - "null" + timeZone: + type: + - string + - "null" + zuid: + type: + - string + - "null" + list_agents: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + aboutInfo: + type: + - string + - "null" + associatedChatDepartmentIds: + type: + - array + - "null" + associatedDepartmentIds: + type: + - array + - "null" + items: + type: + - string + - "null" + cf: + type: + - object + - "null" + channelExpert: + type: + - array + - "null" + countryCode: + type: + - string + - "null" + emailId: + type: + - string + - "null" + extn: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: string + isConfirmed: + type: + - boolean + - "null" + langCode: + type: + - string + - "null" + lastName: + type: + - string + - "null" + mobile: + type: + - string + - "null" + name: + type: + - string + - "null" + phone: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + profileId: + type: + - string + - "null" + roleId: + type: + - string + - "null" + rolePermissionType: + type: + - string + - "null" + status: + type: + - string + - "null" + timeZone: + type: + - string + - "null" + zuid: + type: + - string + - "null" + required: + - id + agent_details_by_id: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + aboutInfo: + type: + - string + - "null" + associatedDepartmentIds: + type: + - array + - "null" + channelExpert: + type: + - array + - "null" + emailId: + type: + - string + - "null" + extn: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: string + isConfirmed: + type: + - boolean + - "null" + lastName: + type: + - string + - "null" + mobile: + type: + - string + - "null" + phone: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + profileId: + type: + - string + - "null" + roleId: + type: + - string + - "null" + rolePermissionType: + type: + - string + - "null" + status: + type: + - string + - "null" + zuid: + type: + - string + - "null" + required: + - id + profiles: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + default: + type: + - boolean + - "null" + id: + type: string + isVisible: + type: + - boolean + - "null" + name: + type: + - string + - "null" + permissions: + type: + - object + - "null" + properties: + CommunityComment: + type: + - object + - "null" + properties: + view: + type: + - boolean + - "null" + CommunityTopic: + type: + - object + - "null" + properties: + view: + type: + - boolean + - "null" + accounts: + type: + - object + - "null" + properties: + create: + type: + - boolean + - "null" + delete: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + export: + type: + - boolean + - "null" + import: + type: + - boolean + - "null" + view: + type: + - boolean + - "null" + agents: + type: + - object + - "null" + properties: + create: + type: + - boolean + - "null" + delete: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + import: + type: + - boolean + - "null" + overview: + type: + - boolean + - "null" + viewAllFields: + type: + - boolean + - "null" + calls: + type: + - object + - "null" + properties: + create: + type: + - boolean + - "null" + delete: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + export: + type: + - boolean + - "null" + import: + type: + - boolean + - "null" + view: + type: + - boolean + - "null" + chat: + type: + - object + - "null" + properties: + view: + type: + - boolean + - "null" + comments: + type: + - object + - "null" + properties: + delete: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + community: + type: + - object + - "null" + properties: + create: + type: + - boolean + - "null" + delete: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + moderate: + type: + - boolean + - "null" + view: + type: + - boolean + - "null" + contacts: + type: + - object + - "null" + properties: + create: + type: + - boolean + - "null" + delete: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + export: + type: + - boolean + - "null" + import: + type: + - boolean + - "null" + view: + type: + - boolean + - "null" + contracts: + type: + - object + - "null" + properties: + create: + type: + - boolean + - "null" + delete: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + export: + type: + - boolean + - "null" + import: + type: + - boolean + - "null" + view: + type: + - boolean + - "null" + crmInteg: + type: + - object + - "null" + properties: + crmAccountsActivityCalls: + type: + - boolean + - "null" + crmAccountsActivityEvents: + type: + - boolean + - "null" + crmAccountsActivityTasks: + type: + - boolean + - "null" + crmAccountsInfo: + type: + - boolean + - "null" + crmAccountsNotes: + type: + - boolean + - "null" + crmAccountsPotentials: + type: + - boolean + - "null" + crmContactsActivityCalls: + type: + - boolean + - "null" + crmContactsActivityEvents: + type: + - boolean + - "null" + crmContactsActivityTasks: + type: + - boolean + - "null" + crmContactsInfo: + type: + - boolean + - "null" + crmContactsNotes: + type: + - boolean + - "null" + crmContactsPotentials: + type: + - boolean + - "null" + events: + type: + - object + - "null" + properties: + create: + type: + - boolean + - "null" + delete: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + export: + type: + - boolean + - "null" + import: + type: + - boolean + - "null" + view: + type: + - boolean + - "null" + financeInteg: + type: + - object + - "null" + properties: + createContact: + type: + - boolean + - "null" + createEstimate: + type: + - boolean + - "null" + createInvoice: + type: + - boolean + - "null" + createSalesOrder: + type: + - boolean + - "null" + sendEstimate: + type: + - boolean + - "null" + sendInvoice: + type: + - boolean + - "null" + sendSalesOrder: + type: + - boolean + - "null" + viewEstimate: + type: + - boolean + - "null" + viewInvoice: + type: + - boolean + - "null" + viewSalesOrder: + type: + - boolean + - "null" + viewSubscription: + type: + - boolean + - "null" + gc: + type: + - object + - "null" + properties: + create: + type: + - boolean + - "null" + delete: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + view: + type: + - boolean + - "null" + im: + type: + - object + - "null" + properties: + create: + type: + - boolean + - "null" + delete: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + view: + type: + - boolean + - "null" + kbCategory: + type: + - object + - "null" + properties: + admin: + type: + - boolean + - "null" + create: + type: + - boolean + - "null" + delete: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + editAllArticles: + type: + - boolean + - "null" + export: + type: + - boolean + - "null" + import: + type: + - boolean + - "null" + manageKB: + type: + - boolean + - "null" + view: + type: + - boolean + - "null" + mobileapp: + type: + - object + - "null" + properties: + deskapp: + type: + - boolean + - "null" + radar: + type: + - boolean + - "null" + products: + type: + - object + - "null" + properties: + create: + type: + - boolean + - "null" + delete: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + export: + type: + - boolean + - "null" + import: + type: + - boolean + - "null" + view: + type: + - boolean + - "null" + reports: + type: + - object + - "null" + properties: + create: + type: + - boolean + - "null" + delete: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + export: + type: + - boolean + - "null" + view: + type: + - boolean + - "null" + setup: + type: + - object + - "null" + properties: + automation: + type: + - boolean + - "null" + buttons: + type: + - boolean + - "null" + chat: + type: + - boolean + - "null" + community: + type: + - boolean + - "null" + customerHappiness: + type: + - boolean + - "null" + department: + type: + - boolean + - "null" + email: + type: + - boolean + - "null" + exportPortalUsers: + type: + - boolean + - "null" + exportUsers: + type: + - boolean + - "null" + featureConfig: + type: + - boolean + - "null" + gamification: + type: + - boolean + - "null" + googleAnalytics: + type: + - boolean + - "null" + im: + type: + - boolean + - "null" + importHistory: + type: + - boolean + - "null" + layouts: + type: + - boolean + - "null" + localization: + type: + - boolean + - "null" + manageAgents: + type: + - boolean + - "null" + manageMarketplace: + type: + - boolean + - "null" + managerDashboard: + type: + - boolean + - "null" + massReply: + type: + - boolean + - "null" + permission: + type: + - boolean + - "null" + pinnedConversations: + type: + - boolean + - "null" + portal: + type: + - boolean + - "null" + portalUsers: + type: + - boolean + - "null" + privacySettings: + type: + - boolean + - "null" + rebranding: + type: + - boolean + - "null" + recycleBin: + type: + - boolean + - "null" + sandbox: + type: + - boolean + - "null" + securitySettings: + type: + - boolean + - "null" + shareSnippet: + type: + - boolean + - "null" + signUpApproval: + type: + - boolean + - "null" + social: + type: + - boolean + - "null" + tabsAndFields: + type: + - boolean + - "null" + teams: + type: + - boolean + - "null" + telephony: + type: + - boolean + - "null" + templates: + type: + - boolean + - "null" + timeTracking: + type: + - boolean + - "null" + webForm: + type: + - boolean + - "null" + webhooks: + type: + - boolean + - "null" + social: + type: + - object + - "null" + properties: + twitterConversationReply: + type: + - boolean + - "null" + twitterPostCreate: + type: + - boolean + - "null" + twitterPostDelete: + type: + - boolean + - "null" + view: + type: + - boolean + - "null" + tasks: + type: + - object + - "null" + properties: + create: + type: + - boolean + - "null" + delete: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + export: + type: + - boolean + - "null" + import: + type: + - boolean + - "null" + view: + type: + - boolean + - "null" + tickets: + type: + - object + - "null" + properties: + addFollowers: + type: + - boolean + - "null" + changeOwner: + type: + - boolean + - "null" + closeTicket: + type: + - boolean + - "null" + create: + type: + - boolean + - "null" + delete: + type: + - boolean + - "null" + deleteTags: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + editTags: + type: + - boolean + - "null" + export: + type: + - boolean + - "null" + handleUnassigned: + type: + - boolean + - "null" + import: + type: + - boolean + - "null" + mailReview: + type: + - boolean + - "null" + mailSend: + type: + - boolean + - "null" + mergeTickets: + type: + - boolean + - "null" + revokeBlueprint: + type: + - boolean + - "null" + unassignedChangeOwner: + type: + - boolean + - "null" + view: + type: + - boolean + - "null" + timeEntry: + type: + - object + - "null" + properties: + create: + type: + - boolean + - "null" + delete: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + view: + type: + - boolean + - "null" + zia: + type: + - object + - "null" + properties: + create: + type: + - boolean + - "null" + delete: + type: + - boolean + - "null" + edit: + type: + - boolean + - "null" + view: + type: + - boolean + - "null" + required: + - id + list_roles: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + id: + type: string + immediateSubRoles: + type: + - array + - "null" + items: + type: + - string + - "null" + isDefault: + type: + - boolean + - "null" + isVisible: + type: + - boolean + - "null" + name: + type: + - string + - "null" + reportsTo: + type: + - string + - "null" + shareDataWithPeers: + type: + - boolean + - "null" + required: + - id + teams: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + agents: + type: + - array + - "null" + items: + type: + - string + - "null" + departmentId: + type: + - string + - "null" + derivedAgents: + type: + - array + - "null" + items: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + roles: + type: + - array + - "null" + rolesWithSubordinates: + type: + - array + - "null" + subTeams: + type: + - array + - "null" + required: + - id + team_members: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: string + lastName: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + profileId: + type: + - string + - "null" + roleId: + type: + - string + - "null" + zuid: + type: + - string + - "null" + required: + - id + list_departments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + data: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + chatStatus: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + creatorId: + type: + - string + - "null" + hasLogo: + type: + - boolean + - "null" + id: + type: + - string + - "null" + isAssignToTeamEnabled: + type: + - boolean + - "null" + isDefault: + type: + - boolean + - "null" + isEnabled: + type: + - boolean + - "null" + isVisibleInCustomerPortal: + type: + - boolean + - "null" + name: + type: + - string + - "null" + nameInCustomerPortal: + type: + - string + - "null" + sanitizedName: + type: + - string + - "null" + channels: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + acceptsReplies: + type: + - boolean + - "null" + code: + type: string + name: + type: + - string + - "null" + replyConfig: + type: + - object + - "null" + properties: + acceptsAttachments: + type: + - boolean + - "null" + contentTypes: + type: + - array + - "null" + items: + type: + - string + - "null" + includeQuotedMessage: + type: + - boolean + - "null" + updateRecords: + type: + - boolean + - "null" + required: + - code + list_tickets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + assigneeId: + type: + - string + - "null" + channel: + type: + - string + - "null" + commentCount: + type: + - string + - "null" + contactId: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + customerResponseTime: + type: + - string + - "null" + departmentId: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: string + isArchived: + type: + - boolean + - "null" + isSpam: + type: + - boolean + - "null" + language: + type: + - string + - "null" + lastThread: + type: + - object + - "null" + properties: + channel: + type: + - string + - "null" + direction: + type: + - string + - "null" + isDraft: + type: + - boolean + - "null" + isForward: + type: + - boolean + - "null" + layoutId: + type: + - string + - "null" + phone: + type: + - string + - "null" + productId: + type: + - string + - "null" + source: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + status: + type: + - string + - "null" + statusType: + type: + - string + - "null" + subject: + type: + - string + - "null" + threadCount: + type: + - string + - "null" + ticketNumber: + type: + - string + - "null" + webUrl: + type: + - string + - "null" + required: + - id + list_all_threads: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + actions: + type: + - array + - "null" + attachmentCount: + type: + - string + - "null" + author: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + email: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: + - string + - "null" + lastName: + type: + - string + - "null" + name: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + bcc: + type: + - string + - "null" + canReply: + type: + - boolean + - "null" + cc: + type: + - string + - "null" + channel: + type: + - string + - "null" + contentType: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + direction: + type: + - string + - "null" + fromEmailAddress: + type: + - string + - "null" + hasAttach: + type: + - boolean + - "null" + id: + type: string + isDescriptionThread: + type: + - boolean + - "null" + isForward: + type: + - boolean + - "null" + respondedIn: + type: + - string + - "null" + responderId: + type: + - string + - "null" + source: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + status: + type: + - string + - "null" + summary: + type: + - string + - "null" + to: + type: + - string + - "null" + visibility: + type: + - string + - "null" + required: + - id + get_latest_thread: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + actions: + type: + - array + - "null" + attachmentCount: + type: + - string + - "null" + attachments: + type: + - array + - "null" + author: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + email: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: + - string + - "null" + lastName: + type: + - string + - "null" + name: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + bcc: + type: + - string + - "null" + canReply: + type: + - boolean + - "null" + cc: + type: + - string + - "null" + channel: + type: + - string + - "null" + content: + type: + - string + - "null" + contentType: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + direction: + type: + - string + - "null" + fromEmailAddress: + type: + - string + - "null" + hasAttach: + type: + - boolean + - "null" + id: + type: string + isContentTruncated: + type: + - boolean + - "null" + isDescriptionThread: + type: + - boolean + - "null" + isForward: + type: + - boolean + - "null" + replyTo: + type: + - string + - "null" + responderId: + type: + - string + - "null" + source: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + status: + type: + - string + - "null" + summary: + type: + - string + - "null" + to: + type: + - string + - "null" + visibility: + type: + - string + - "null" + required: + - id + list_contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accountCount: + type: + - string + - "null" + accountId: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + customerHappiness: + type: + - object + - "null" + properties: + badPercentage: + type: + - string + - "null" + goodPercentage: + type: + - string + - "null" + okPercentage: + type: + - string + - "null" + email: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: string + isAnonymous: + type: + - boolean + - "null" + isEndUser: + type: + - boolean + - "null" + isSpam: + type: + - boolean + - "null" + lastName: + type: + - string + - "null" + mobile: + type: + - string + - "null" + ownerId: + type: + - string + - "null" + phone: + type: + - string + - "null" + webUrl: + type: + - string + - "null" + required: + - id + webhooks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + description: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + id: + type: + - string + - "null" + ignoreSourceId: + type: + - string + - "null" + isEnabled: + type: + - boolean + - "null" + modifiedTime: + type: + - string + - "null" + name: + type: + - string + - "null" + subscriptions: + type: + - object + - "null" + properties: {} + url: + type: + - string + - "null" + list_accounts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accountName: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + customerHappiness: + type: + - object + - "null" + properties: + badPercentage: + type: + - string + - "null" + goodPercentage: + type: + - string + - "null" + okPercentage: + type: + - string + - "null" + email: + type: + - string + - "null" + id: + type: string + phone: + type: + - string + - "null" + webUrl: + type: + - string + - "null" + website: + type: + - string + - "null" + required: + - id + list_contracts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accountId: + type: + - string + - "null" + associatedSLAId: + type: + - string + - "null" + contractName: + type: + - string + - "null" + contractStatus: + type: + - string + - "null" + departmentId: + type: + - string + - "null" + id: + type: string + slaName: + type: + - string + - "null" + startDate: + type: + - string + - "null" + supportPlan: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + status: + type: + - string + - "null" + supportType: + type: + - string + - "null" + required: + - id + list_tasks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + activityTime: + type: + - string + - "null" + contactId: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + creatorId: + type: + - string + - "null" + departmentId: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + id: + type: string + isCommented: + type: + - boolean + - "null" + isSpam: + type: + - boolean + - "null" + isTrashed: + type: + - boolean + - "null" + layoutId: + type: + - string + - "null" + modifiedBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: + - string + - "null" + lastName: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + modifiedTime: + type: + - string + - "null" + ownerId: + type: + - string + - "null" + priority: + type: + - string + - "null" + status: + type: + - string + - "null" + statusType: + type: + - string + - "null" + subject: + type: + - string + - "null" + ticketId: + type: + - string + - "null" + webUrl: + type: + - string + - "null" + required: + - id + list_products: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: string + productCode: + type: + - string + - "null" + productName: + type: + - string + - "null" + unitPrice: + type: + - string + - "null" + required: + - id + list_articles: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attachmentCount: + type: + - string + - "null" + author: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + status: + type: + - string + - "null" + zuid: + type: + - string + - "null" + authorId: + type: + - string + - "null" + availableLocaleTranslations: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + authorId: + type: + - string + - "null" + href: + type: + - string + - "null" + isLocked: + type: + - boolean + - "null" + isTrashed: + type: + - boolean + - "null" + latestPublishedVersion: + type: + - string + - "null" + latestVersion: + type: + - string + - "null" + latestVersionStatus: + type: + - string + - "null" + locale: + type: + - string + - "null" + status: + type: + - string + - "null" + translationId: + type: + - string + - "null" + translationState: + type: + - string + - "null" + category: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + locale: + type: + - string + - "null" + name: + type: + - string + - "null" + categoryId: + type: + - string + - "null" + commentCount: + type: + - string + - "null" + createdBy: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + status: + type: + - string + - "null" + zuid: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + creatorId: + type: + - string + - "null" + departmentId: + type: + - string + - "null" + dislikeCount: + type: + - string + - "null" + feedbackCount: + type: + - string + - "null" + id: + type: string + isLocked: + type: + - boolean + - "null" + isTrashed: + type: + - boolean + - "null" + latestPublishedVersion: + type: + - string + - "null" + latestVersion: + type: + - string + - "null" + latestVersionModifiedBy: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + status: + type: + - string + - "null" + zuid: + type: + - string + - "null" + latestVersionModifierId: + type: + - string + - "null" + latestVersionStatus: + type: + - string + - "null" + likeCount: + type: + - string + - "null" + locale: + type: + - string + - "null" + modifiedBy: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + status: + type: + - string + - "null" + zuid: + type: + - string + - "null" + modifiedTime: + type: + - string + - "null" + modifierId: + type: + - string + - "null" + owner: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + status: + type: + - string + - "null" + zuid: + type: + - string + - "null" + ownerId: + type: + - string + - "null" + permalink: + type: + - string + - "null" + permission: + type: + - string + - "null" + portalUrl: + type: + - string + - "null" + position: + type: + - string + - "null" + rootCategoryId: + type: + - string + - "null" + sourceLocale: + type: + - string + - "null" + status: + type: + - string + - "null" + summary: + type: + - string + - "null" + title: + type: + - string + - "null" + translationId: + type: + - string + - "null" + translationState: + type: + - string + - "null" + usageCount: + type: + - string + - "null" + viewCount: + type: + - string + - "null" + webUrl: + type: + - string + - "null" + required: + - id + list_events: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + activityTime: + type: + - string + - "null" + category: + type: + - string + - "null" + contactId: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + creatorId: + type: + - string + - "null" + departmentId: + type: + - string + - "null" + id: + type: string + isCommented: + type: + - boolean + - "null" + isSpam: + type: + - boolean + - "null" + isTrashed: + type: + - boolean + - "null" + layoutId: + type: + - string + - "null" + modifiedBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: + - string + - "null" + lastName: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + modifiedTime: + type: + - string + - "null" + ownerId: + type: + - string + - "null" + priority: + type: + - string + - "null" + startTime: + type: + - string + - "null" + status: + type: + - string + - "null" + statusType: + type: + - string + - "null" + subject: + type: + - string + - "null" + webUrl: + type: + - string + - "null" + required: + - id + modules: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + apiName: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + displayLabel: + type: + - string + - "null" + hasRecycleBin: + type: + - boolean + - "null" + id: + type: string + isCustomModule: + type: + - boolean + - "null" + isDeptSpecific: + type: + - boolean + - "null" + modifiedTime: + type: + - string + - "null" + nameField: + type: + - string + - "null" + pluralLabel: + type: + - string + - "null" + singularLabel: + type: + - string + - "null" + required: + - id + list_users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + emailAddress: + type: + - string + - "null" + id: + type: string + lastAccessedTime: + type: + - string + - "null" + name: + type: + - string + - "null" + status: + type: + - string + - "null" + userType: + type: + - string + - "null" + required: + - id + ticket_activities: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + activityTime: + type: + - string + - "null" + activityType: + type: + - string + - "null" + completedTime: + type: + - string + - "null" + contactId: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + creatorId: + type: + - string + - "null" + departmentId: + type: + - string + - "null" + direction: + type: + - string + - "null" + dueDate: + type: + - string + - "null" + id: + type: string + isCommented: + type: + - boolean + - "null" + isSpam: + type: + - boolean + - "null" + isTrashed: + type: + - boolean + - "null" + layoutId: + type: + - string + - "null" + modifiedBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: + - string + - "null" + lastName: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + modifiedTime: + type: + - string + - "null" + ownerId: + type: + - string + - "null" + priority: + type: + - string + - "null" + startTime: + type: + - string + - "null" + status: + type: + - string + - "null" + statusType: + type: + - string + - "null" + subject: + type: + - string + - "null" + ticketId: + type: + - string + - "null" + webUrl: + type: + - string + - "null" + required: + - id + list_attachments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + data: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + createdTime: + type: + - string + - "null" + creatorId: + type: + - string + - "null" + href: + type: + - string + - "null" + id: + type: + - string + - "null" + name: + type: + - string + - "null" + size: + type: + - string + - "null" + product: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + cf: + type: + - object + - "null" + createdBy: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + customFields: + type: + - object + - "null" + departmentIds: + type: + - array + - "null" + items: + type: + - string + - "null" + id: + type: string + isDeleted: + type: + - boolean + - "null" + layoutDetails: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + layoutName: + type: + - string + - "null" + layoutId: + type: + - string + - "null" + modifiedBy: + type: + - string + - "null" + modifiedTime: + type: + - string + - "null" + ownerId: + type: + - string + - "null" + productCategory: + type: + - string + - "null" + productCode: + type: + - string + - "null" + productName: + type: + - string + - "null" + unitPrice: + type: + - string + - "null" + required: + - id + task_attachments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + createdTime: + type: + - string + - "null" + creatorId: + type: + - string + - "null" + href: + type: + - string + - "null" + id: + type: string + name: + type: + - string + - "null" + size: + type: + - string + - "null" + required: + - id + list_calls: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + activityTime: + type: + - string + - "null" + completedTime: + type: + - string + - "null" + contactId: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + creatorId: + type: + - string + - "null" + departmentId: + type: + - string + - "null" + direction: + type: + - string + - "null" + id: + type: string + isCommented: + type: + - boolean + - "null" + isSpam: + type: + - boolean + - "null" + isTrashed: + type: + - boolean + - "null" + layoutId: + type: + - string + - "null" + modifiedBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: + - string + - "null" + lastName: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + modifiedTime: + type: + - string + - "null" + ownerId: + type: + - string + - "null" + priority: + type: + - string + - "null" + startTime: + type: + - string + - "null" + status: + type: + - string + - "null" + statusType: + type: + - string + - "null" + subject: + type: + - string + - "null" + ticketId: + type: + - string + - "null" + webUrl: + type: + - string + - "null" + required: + - id + call: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + activityTime: + type: + - string + - "null" + cf: + type: + - object + - "null" + completedTime: + type: + - string + - "null" + contactId: + type: + - string + - "null" + createdTime: + type: + - string + - "null" + creatorId: + type: + - string + - "null" + customFields: + type: + - object + - "null" + departmentId: + type: + - string + - "null" + direction: + type: + - string + - "null" + duration: + type: + - string + - "null" + id: + type: string + isSpam: + type: + - boolean + - "null" + isTrashed: + type: + - boolean + - "null" + layoutId: + type: + - string + - "null" + modifiedBy: + type: + - object + - "null" + properties: + emailId: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: + - string + - "null" + lastName: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + modifiedTime: + type: + - string + - "null" + ownerId: + type: + - string + - "null" + priority: + type: + - string + - "null" + startTime: + type: + - string + - "null" + status: + type: + - string + - "null" + statusType: + type: + - string + - "null" + subject: + type: + - string + - "null" + ticketId: + type: + - string + - "null" + webUrl: + type: + - string + - "null" + required: + - id + list_call_comments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + attachments: + type: + - array + - "null" + commentedTime: + type: + - string + - "null" + commenter: + type: + - object + - "null" + properties: + type: + type: + - string + - "null" + email: + type: + - string + - "null" + firstName: + type: + - string + - "null" + id: + type: + - string + - "null" + lastName: + type: + - string + - "null" + name: + type: + - string + - "null" + photoURL: + type: + - string + - "null" + roleName: + type: + - string + - "null" + commenterId: + type: + - string + - "null" + content: + type: + - string + - "null" + contentType: + type: + - string + - "null" + encodedContent: + type: + - string + - "null" + id: + type: string + modifiedTime: + type: + - string + - "null" + required: + - id + dashboard_created_tickets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + avg: + type: + - string + - "null" + groupedBy: + type: + - string + - "null" + ticketCount: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + count: + type: + - string + - "null" + value: + type: + - string + - "null" + totalTicketCount: + type: + - string + - "null" + list_user_groups: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + addedTime: + type: + - string + - "null" + helpCenterId: + type: + - string + - "null" + id: + type: string + logoUrl: + type: + - string + - "null" + name: + type: + - string + - "null" + status: + type: + - string + - "null" + required: + - id + dashboard_onhold_tickets: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + count: + type: + - string + - "null" + value: + type: string + required: + - value diff --git a/airbyte-integrations/connectors/source-zoho-desk/metadata.yaml b/airbyte-integrations/connectors/source-zoho-desk/metadata.yaml new file mode 100644 index 000000000000..fa190b419dde --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-desk/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "desk.zoho.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-zoho-desk + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 08164461-a3fd-49d5-8185-b83d51013585 + dockerImageTag: 0.0.4 + dockerRepository: airbyte/source-zoho-desk + githubIssueLabel: source-zoho-desk + icon: icon.svg + license: MIT + name: Zoho Desk + releaseDate: 2024-10-28 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/zoho-desk + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-zoho-expense/README.md b/airbyte-integrations/connectors/source-zoho-expense/README.md new file mode 100644 index 000000000000..2ebed0abc0a1 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-expense/README.md @@ -0,0 +1,33 @@ +# Zoho Expense +This directory contains the manifest-only connector for `source-zoho-expense`. + +Zoho Expense connector enables seamless data synchronization between Zoho Expense and various destinations. This connector automates expense tracking workflows by extracting financial data efficiently, ensuring accurate reporting and streamlined operations. + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-zoho-expense:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-zoho-expense build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-zoho-expense test +``` + diff --git a/airbyte-integrations/connectors/source-zoho-expense/acceptance-test-config.yml b/airbyte-integrations/connectors/source-zoho-expense/acceptance-test-config.yml new file mode 100644 index 000000000000..e02c43eea04b --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-expense/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-zoho-expense:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-zoho-expense/icon.svg b/airbyte-integrations/connectors/source-zoho-expense/icon.svg new file mode 100644 index 000000000000..764c698ecbc1 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-expense/icon.svg @@ -0,0 +1,319 @@ + + + + + + + + + + + + + + + + + diff --git a/airbyte-integrations/connectors/source-zoho-expense/manifest.yaml b/airbyte-integrations/connectors/source-zoho-expense/manifest.yaml new file mode 100644 index 000000000000..704651381914 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-expense/manifest.yaml @@ -0,0 +1,2240 @@ +version: 5.16.0 + +type: DeclarativeSource + +description: >- + Zoho Expense connector enables seamless data synchronization between Zoho + Expense and various destinations. This connector automates expense tracking + workflows by extracting financial data efficiently, ensuring accurate + reporting and streamlined operations. + +check: + type: CheckStream + stream_names: + - users + +definitions: + streams: + users: + type: DeclarativeStream + name: users + primary_key: + - user_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - users + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: per_page + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + trips: + type: DeclarativeStream + name: trips + primary_key: + - trip_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /trips + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - trips + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: per_page + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/trips" + expense_reports: + type: DeclarativeStream + name: expense_reports + primary_key: + - report_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /expensereports + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - expense_reports + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: per_page + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/expense_reports" + projects: + type: DeclarativeStream + name: projects + primary_key: + - project_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /projects + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - projects + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: per_page + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/projects" + customers: + type: DeclarativeStream + name: customers + primary_key: + - contact_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - contacts + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: per_page + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customers" + organizations: + type: DeclarativeStream + name: organizations + primary_key: + - organization_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /organizations + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - organizations + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: per_page + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/organizations" + expense_categories: + type: DeclarativeStream + name: expense_categories + primary_key: + - category_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /expensecategories + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - expense_accounts + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: per_page + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/expense_categories" + currencies: + type: DeclarativeStream + name: currencies + primary_key: + - currency_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /settings/currencies + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - currencies + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: per_page + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/currencies" + taxes: + type: DeclarativeStream + name: taxes + primary_key: + - tax_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /settings/taxes + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - taxes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: per_page + pagination_strategy: + type: PageIncrement + page_size: 200 + start_from_page: 1 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/taxes" + base_requester: + type: HttpRequester + url_base: https://www.zohoapis.{{ config['data_center'] }}/expense/v1 + authenticator: + type: OAuthAuthenticator + client_id: "{{ config[\"client_id\"] }}" + grant_type: refresh_token + client_secret: "{{ config[\"client_secret\"] }}" + refresh_token: "{{ config[\"refresh_token\"] }}" + expires_in_name: expires_in + access_token_name: access_token + refresh_request_body: {} + token_refresh_endpoint: https://accounts.zoho.{{ config["data_center"] }}/oauth/v2/token + +streams: + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/trips" + - $ref: "#/definitions/streams/expense_reports" + - $ref: "#/definitions/streams/projects" + - $ref: "#/definitions/streams/customers" + - $ref: "#/definitions/streams/organizations" + - $ref: "#/definitions/streams/expense_categories" + - $ref: "#/definitions/streams/currencies" + - $ref: "#/definitions/streams/taxes" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - client_id + - client_secret + - refresh_token + properties: + data_center: + type: string + description: >- + The domain suffix for the Zoho Expense API based on your data center + location (e.g., 'com', 'eu', 'in', etc.) + enum: + - com + - in + - jp + - ca + - com.cn + - sa + - com.au + - eu + name: domain + order: 0 + title: Data Center + default: com + client_id: + type: string + name: client_id + order: 1 + title: OAuth Client ID + airbyte_secret: true + client_secret: + type: string + name: client_secret + order: 2 + title: OAuth Client Secret + airbyte_secret: true + refresh_token: + type: string + name: refresh_token + order: 3 + title: OAuth Refresh Token + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + users: true + trips: true + expense_reports: true + projects: true + customers: true + organizations: true + expense_categories: true + currencies: true + taxes: true + testedStreams: + users: + streamHash: 7ebe190ed5cf36fc0eb352e4256418f7e9d82062 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + trips: + streamHash: 3006b5339f6cc116109cbe2fb8aa7029f2933813 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + expense_reports: + streamHash: 44dac027120534cf64c0f9ac9ea701178b7cd86c + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + projects: + streamHash: 5d1a97e0aead1cee724fc6686b5796628c41abd5 + hasResponse: true + responsesAreSuccessful: true + hasRecords: false + primaryKeysArePresent: true + primaryKeysAreUnique: true + customers: + streamHash: 58c100803c4f10d6389885509b2f532d2c81e529 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + organizations: + streamHash: ced9ef3dbf607306d9c45f8f70d05a757e52ae33 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + expense_categories: + streamHash: 94fa40a0885845e1586ebe063c16e460b8d8336d + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + currencies: + streamHash: 97bcca96af464e0f54335cab614c20a0336d1d4b + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + taxes: + streamHash: 9c86b3cad1cd8a0b8d065a8508387e16756ea44a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + assist: + docsUrl: https://www.zoho.com/expense/api/v1/introduction/#overview + +schemas: + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accounting_app_name: + type: + - string + - "null" + accounting_reference_id: + type: + - string + - "null" + accounting_vendor_reference_id: + type: + - string + - "null" + approval_amount_limit: + type: + - number + - "null" + approver_photo_url: + type: + - string + - "null" + approves_to_email: + type: + - string + - "null" + approves_to_id: + type: + - string + - "null" + approves_to_name: + type: + - string + - "null" + bank_name: + type: + - string + - "null" + can_approve: + type: + - boolean + - "null" + created_time: + type: + - string + - "null" + default_approver_email: + type: + - string + - "null" + default_approver_id: + type: + - string + - "null" + default_approver_name: + type: + - string + - "null" + department_id: + type: + - string + - "null" + department_name: + type: + - string + - "null" + display_name: + type: + - string + - "null" + email: + type: + - string + - "null" + employee_number: + type: + - string + - "null" + getthere_access: + type: + - string + - "null" + getthere_profile_created: + type: + - boolean + - "null" + hr_url: + type: + - string + - "null" + invitation_type: + type: + - string + - "null" + is_current_user: + type: + - boolean + - "null" + is_from_crm: + type: + - boolean + - "null" + is_from_zoho_people: + type: + - boolean + - "null" + is_super_admin: + type: + - boolean + - "null" + last_four_digits: + type: + - string + - "null" + last_modified_time: + type: + - string + - "null" + mobile: + type: + - string + - "null" + name: + type: + - string + - "null" + photo_url: + type: + - string + - "null" + policy_id: + type: + - string + - "null" + policy_name: + type: + - string + - "null" + role_id: + type: + - string + - "null" + status: + type: + - string + - "null" + submission_amount_limit: + type: + - number + - "null" + travel_policy_display_name: + type: + - string + - "null" + travel_policy_id: + type: + - string + - "null" + travel_policy_name: + type: + - string + - "null" + user_id: + type: string + user_mail_in_id: + type: + - string + - "null" + user_role: + type: + - string + - "null" + user_type: + type: + - string + - "null" + required: + - user_id + trips: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + approved_date: + type: + - string + - "null" + approver_email: + type: + - string + - "null" + approver_employee_no: + type: + - string + - "null" + approver_id: + type: + - string + - "null" + approver_name: + type: + - string + - "null" + approver_photo_url: + type: + - string + - "null" + approver_zuid: + type: + - string + - "null" + bcy_budget_amount: + type: + - number + - "null" + booking_summary: + type: + - array + - "null" + budget_amount: + type: + - number + - "null" + business_purpose: + type: + - string + - "null" + can_other_travelers_associate_report: + type: + - boolean + - "null" + created_by_email: + type: + - string + - "null" + created_by_id: + type: + - string + - "null" + created_by_name: + type: + - string + - "null" + created_date: + type: + - string + - "null" + created_time: + type: + - string + - "null" + creator_employee_no: + type: + - string + - "null" + creator_photo_url: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + currency_id: + type: + - string + - "null" + custom_fields: + type: + - array + - "null" + customer_id: + type: + - string + - "null" + customer_name: + type: + - string + - "null" + department_id: + type: + - string + - "null" + department_name: + type: + - string + - "null" + departure: + type: + - string + - "null" + destination_city: + type: + - string + - "null" + destination_country: + type: + - string + - "null" + destination_state: + type: + - string + - "null" + employee_number: + type: + - string + - "null" + end_date: + type: + - string + - "null" + exchange_rate: + type: + - number + - "null" + from_source: + type: + - string + - "null" + is_archived: + type: + - boolean + - "null" + is_billable: + type: + - boolean + - "null" + is_international: + type: + - boolean + - "null" + is_round_trip: + type: + - boolean + - "null" + is_visa_required: + type: + - boolean + - "null" + last_modified_time: + type: + - string + - "null" + last_submitted_date: + type: + - string + - "null" + meal_preference: + type: + - string + - "null" + notes: + type: + - string + - "null" + policy_display_name: + type: + - string + - "null" + policy_id: + type: + - string + - "null" + policy_name: + type: + - string + - "null" + price_precision: + type: + - number + - "null" + project_id: + type: + - string + - "null" + project_name: + type: + - string + - "null" + reports_count: + type: + - number + - "null" + seat_preference: + type: + - string + - "null" + start_date: + type: + - string + - "null" + status: + type: + - string + - "null" + sub_status: + type: + - string + - "null" + submitted_by: + type: + - number + - "null" + submitted_date: + type: + - string + - "null" + submitted_to_department_name: + type: + - string + - "null" + submitted_to_email: + type: + - string + - "null" + submitted_to_employee_no: + type: + - string + - "null" + submitted_to_id: + type: + - string + - "null" + submitted_to_name: + type: + - string + - "null" + submitter_department_name: + type: + - string + - "null" + submitter_email: + type: + - string + - "null" + submitter_employee_no: + type: + - string + - "null" + submitter_name: + type: + - string + - "null" + submitter_photo_url: + type: + - string + - "null" + submitter_zuid: + type: + - string + - "null" + trip_id: + type: string + trip_name: + type: + - string + - "null" + trip_number: + type: + - string + - "null" + user_custom_fields: + type: + - array + - "null" + user_email: + type: + - string + - "null" + user_id: + type: + - string + - "null" + user_name: + type: + - string + - "null" + required: + - trip_id + expense_reports: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + accounting_app_name: + type: + - string + - "null" + accounting_reference_id: + type: + - string + - "null" + accounting_sync_time: + type: + - string + - "null" + amount_policy_violation_count: + type: + - number + - "null" + amount_to_be_reimbursed: + type: + - number + - "null" + approved_date: + type: + - string + - "null" + approver_email: + type: + - string + - "null" + approver_employee_no: + type: + - string + - "null" + approver_id: + type: + - string + - "null" + approver_name: + type: + - string + - "null" + approver_photo_url: + type: + - string + - "null" + approver_zuid: + type: + - string + - "null" + audit_status: + type: + - string + - "null" + can_push_to_accounting_app: + type: + - boolean + - "null" + claim_type_id: + type: + - string + - "null" + claim_type_name: + type: + - string + - "null" + comments_count: + type: + - number + - "null" + created_by_id: + type: + - string + - "null" + created_by_name: + type: + - string + - "null" + created_by_zuid: + type: + - string + - "null" + created_date: + type: + - string + - "null" + created_time: + type: + - string + - "null" + creator_employee_no: + type: + - string + - "null" + creator_photo_url: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + currency_id: + type: + - string + - "null" + custom_fields: + type: + - array + - "null" + custom_policy_violation_count: + type: + - number + - "null" + customer_id: + type: + - string + - "null" + customer_name: + type: + - string + - "null" + department_id: + type: + - string + - "null" + department_name: + type: + - string + - "null" + description_policy_violation_count: + type: + - number + - "null" + due_date: + type: + - string + - "null" + due_days: + type: + - string + - "null" + employee_number: + type: + - string + - "null" + end_date: + type: + - string + - "null" + expense_count: + type: + - number + - "null" + imprest_account_id: + type: + - string + - "null" + imprest_account_name: + type: + - string + - "null" + is_ach_reimbursement: + type: + - boolean + - "null" + is_archived: + type: + - boolean + - "null" + is_international_trip: + type: + - string + - "null" + is_shared_report: + type: + - boolean + - "null" + last_modified_date: + type: + - string + - "null" + last_modified_time: + type: + - string + - "null" + last_submitted_date: + type: + - string + - "null" + non_reimbursable_total: + type: + - number + - "null" + payrun_name: + type: + - string + - "null" + policy_display_name: + type: + - string + - "null" + policy_id: + type: + - string + - "null" + policy_name: + type: + - string + - "null" + policy_violated: + type: + - boolean + - "null" + project_id: + type: + - string + - "null" + project_name: + type: + - string + - "null" + rcy_currency_code: + type: + - string + - "null" + rcy_currency_id: + type: + - string + - "null" + rcy_currency_symbol: + type: + - string + - "null" + rcy_exchange_rate: + type: + - number + - "null" + rcy_non_reimbursable_total: + type: + - number + - "null" + rcy_price_precision: + type: + - number + - "null" + rcy_reimbursable_total: + type: + - number + - "null" + rcy_total: + type: + - number + - "null" + receipt_policy_violation_count: + type: + - number + - "null" + reimbursable_total: + type: + - number + - "null" + reimbursement_date: + type: + - string + - "null" + report_id: + type: string + report_name: + type: + - string + - "null" + report_number: + type: + - string + - "null" + start_date: + type: + - string + - "null" + status: + type: + - string + - "null" + sub_status: + type: + - string + - "null" + submitted_by: + type: + - string + - "null" + submitted_date: + type: + - string + - "null" + submitted_to_email: + type: + - string + - "null" + submitted_to_employee_no: + type: + - string + - "null" + submitted_to_id: + type: + - string + - "null" + submitted_to_name: + type: + - string + - "null" + submitted_to_zuid: + type: + - string + - "null" + submitter_email: + type: + - string + - "null" + submitter_employee_no: + type: + - string + - "null" + submitter_name: + type: + - string + - "null" + submitter_photo_url: + type: + - string + - "null" + submitter_zuid: + type: + - string + - "null" + total: + type: + - number + - "null" + total_policy_violation_count: + type: + - number + - "null" + trip_budget_amount: + type: + - number + - "null" + trip_budget_amount_currency_code: + type: + - string + - "null" + trip_budget_amount_currency_id: + type: + - string + - "null" + trip_departure: + type: + - string + - "null" + trip_destination_city: + type: + - string + - "null" + trip_destination_country: + type: + - string + - "null" + trip_end_date: + type: + - string + - "null" + trip_id: + type: + - string + - "null" + trip_name: + type: + - string + - "null" + trip_number: + type: + - string + - "null" + trip_start_date: + type: + - string + - "null" + trip_status: + type: + - string + - "null" + uncategorized_expense_count: + type: + - number + - "null" + user_custom_fields: + type: + - array + - "null" + user_email: + type: + - string + - "null" + user_id: + type: + - string + - "null" + user_name: + type: + - string + - "null" + user_photo_url: + type: + - string + - "null" + zcrm_potential_id: + type: + - string + - "null" + zcrm_potential_name: + type: + - string + - "null" + required: + - report_id + projects: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + code: + type: + - number + - "null" + message: + type: + - string + - "null" + page_context: + type: + - object + - "null" + properties: + applied_filter: + type: + - string + - "null" + custom_fields: + type: + - array + - "null" + has_more_page: + type: + - boolean + - "null" + page: + type: + - number + - "null" + per_page: + type: + - number + - "null" + report_name: + type: + - string + - "null" + sort_column: + type: + - string + - "null" + sort_order: + type: + - string + - "null" + projects: + type: + - array + - "null" + customers: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + ach_supported: + type: + - boolean + - "null" + company_name: + type: + - string + - "null" + contact_id: + type: string + contact_name: + type: + - string + - "null" + contact_type: + type: + - string + - "null" + contact_type_formatted: + type: + - string + - "null" + created_time: + type: + - string + - "null" + created_time_formatted: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + currency_id: + type: + - string + - "null" + custom_field_hash: + type: + - object + - "null" + custom_fields: + type: + - array + - "null" + customer_name: + type: + - string + - "null" + customer_sub_type: + type: + - string + - "null" + email: + type: + - string + - "null" + facebook: + type: + - string + - "null" + first_name: + type: + - string + - "null" + has_attachment: + type: + - boolean + - "null" + is_linked_with_zohocrm: + type: + - boolean + - "null" + language_code: + type: + - string + - "null" + language_code_formatted: + type: + - string + - "null" + last_modified_time: + type: + - string + - "null" + last_modified_time_formatted: + type: + - string + - "null" + last_name: + type: + - string + - "null" + mobile: + type: + - string + - "null" + outstanding_payable_amount: + type: + - number + - "null" + outstanding_payable_amount_bcy: + type: + - number + - "null" + outstanding_receivable_amount: + type: + - number + - "null" + outstanding_receivable_amount_bcy: + type: + - number + - "null" + payment_terms: + type: + - number + - "null" + payment_terms_label: + type: + - string + - "null" + phone: + type: + - string + - "null" + portal_status: + type: + - string + - "null" + primary_contact_id: + type: + - string + - "null" + source: + type: + - string + - "null" + status: + type: + - string + - "null" + twitter: + type: + - string + - "null" + unused_credits_payable_amount: + type: + - number + - "null" + unused_credits_payable_amount_bcy: + type: + - number + - "null" + unused_credits_receivable_amount: + type: + - number + - "null" + unused_credits_receivable_amount_bcy: + type: + - number + - "null" + vendor_name: + type: + - string + - "null" + website: + type: + - string + - "null" + required: + - contact_id + organizations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + version: + type: + - string + - "null" + AppList: + type: + - array + - "null" + items: + type: + - string + - "null" + account_created_date: + type: + - string + - "null" + account_created_date_formatted: + type: + - string + - "null" + can_change_timezone: + type: + - boolean + - "null" + can_sign_invoice: + type: + - boolean + - "null" + contact_name: + type: + - string + - "null" + country: + type: + - string + - "null" + country_code: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + currency_format: + type: + - string + - "null" + currency_id: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + custom_field_type: + type: + - number + - "null" + custom_fields: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + index: + type: + - number + - "null" + label: + type: + - string + - "null" + value: + type: + - string + - "null" + digital_signature_mode: + type: + - string + - "null" + email: + type: + - string + - "null" + field_separator: + type: + - string + - "null" + fiscal_year_start_month: + type: + - number + - "null" + isOrgActive: + type: + - boolean + - "null" + isOrgNotSupported: + type: + - boolean + - "null" + is_advance_approval_enabled: + type: + - boolean + - "null" + is_auto_scan_allowed: + type: + - boolean + - "null" + is_default_org: + type: + - boolean + - "null" + is_designated_zone: + type: + - boolean + - "null" + is_dsign_required: + type: + - boolean + - "null" + is_export_with_payment_enabled: + type: + - boolean + - "null" + is_free_zone: + type: + - boolean + - "null" + is_gst_india_version: + type: + - boolean + - "null" + is_hsn_or_sac_enabled: + type: + - boolean + - "null" + is_international_trade_enabled: + type: + - boolean + - "null" + is_invoice_pmt_tds_allowed: + type: + - boolean + - "null" + is_org_active: + type: + - boolean + - "null" + is_quick_setup_completed: + type: + - boolean + - "null" + is_registered_for_composite_scheme: + type: + - boolean + - "null" + is_registered_for_gst: + type: + - boolean + - "null" + is_registered_for_tax: + type: + - boolean + - "null" + is_sales_inclusive_tax_enabled: + type: + - boolean + - "null" + is_sales_reverse_charge_enabled: + type: + - boolean + - "null" + is_search360_enabled: + type: + - string + - "null" + is_sku_enabled: + type: + - boolean + - "null" + is_solo_org: + type: + - boolean + - "null" + is_tax_registered: + type: + - boolean + - "null" + is_trial_expired: + type: + - boolean + - "null" + is_trial_period_extended: + type: + - boolean + - "null" + is_trip_enabled: + type: + - boolean + - "null" + is_user_dsign_mandatory: + type: + - boolean + - "null" + is_ziedition: + type: + - boolean + - "null" + is_zpayroll_grid: + type: + - boolean + - "null" + language_code: + type: + - string + - "null" + mode: + type: + - string + - "null" + name: + type: + - string + - "null" + org_action: + type: + - string + - "null" + org_created_app_source: + type: + - number + - "null" + org_joined_app_list: + type: + - array + - "null" + items: + type: + - string + - "null" + org_settings: + type: + - boolean + - "null" + org_type: + type: + - string + - "null" + organization_id: + type: string + partners_domain: + type: + - string + - "null" + phone: + type: + - string + - "null" + plan_name: + type: + - string + - "null" + plan_period: + type: + - string + - "null" + plan_type: + type: + - number + - "null" + price_precision: + type: + - number + - "null" + sales_tax_type: + type: + - string + - "null" + source: + type: + - number + - "null" + state: + type: + - string + - "null" + state_code: + type: + - string + - "null" + tax_group_enabled: + type: + - boolean + - "null" + time_zone: + type: + - string + - "null" + time_zone_formatted: + type: + - string + - "null" + user_status: + type: + - number + - "null" + user_status_formatted: + type: + - string + - "null" + version_formatted: + type: + - string + - "null" + zi_zb_client: + type: + - number + - "null" + zi_zb_edition: + type: + - number + - "null" + zoho_one_org: + type: + - string + - "null" + required: + - organization_id + expense_categories: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + attachment_file_name: + type: + - string + - "null" + can_delete: + type: + - boolean + - "null" + can_override_settings: + type: + - boolean + - "null" + can_show: + type: + - boolean + - "null" + category_hint: + type: + - string + - "null" + category_icon: + type: + - string + - "null" + category_id: + type: string + category_name: + type: + - string + - "null" + category_name_with_gl_code: + type: + - string + - "null" + category_type: + type: + - string + - "null" + child_count: + type: + - string + - "null" + depth: + type: + - number + - "null" + expense_type_id: + type: + - string + - "null" + expense_type_name: + type: + - string + - "null" + flat_amount: + type: + - number + - "null" + gl_code: + type: + - string + - "null" + is_child_present: + type: + - boolean + - "null" + is_custom: + type: + - boolean + - "null" + is_description_required: + type: + - boolean + - "null" + is_disabled_master: + type: + - boolean + - "null" + is_enabled: + type: + - boolean + - "null" + is_maximum_amount_required: + type: + - boolean + - "null" + is_mileage: + type: + - boolean + - "null" + is_perdiem_account: + type: + - boolean + - "null" + is_receipt_required: + type: + - boolean + - "null" + is_super_parent: + type: + - boolean + - "null" + maximum_allowed_amount: + type: + - number + - "null" + page_layout_id: + type: + - string + - "null" + page_layout_name: + type: + - string + - "null" + parent_account_id: + type: + - string + - "null" + parent_account_name: + type: + - string + - "null" + receipt_required_amount: + type: + - number + - "null" + status: + type: + - string + - "null" + required: + - category_id + currencies: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + currency_code: + type: + - string + - "null" + currency_format: + type: + - string + - "null" + currency_id: + type: string + currency_name: + type: + - string + - "null" + currency_name_formatted: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + effective_date: + type: + - string + - "null" + exchange_rate: + type: + - number + - "null" + is_base_currency: + type: + - boolean + - "null" + price_precision: + type: + - number + - "null" + rcy_configured_count: + type: + - number + - "null" + required: + - currency_id + taxes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + accounting_app_name: + type: + - string + - "null" + accounting_reference_id: + type: + - string + - "null" + diff_rate_reason: + type: + - string + - "null" + end_date: + type: + - string + - "null" + is_editable: + type: + - boolean + - "null" + is_inactive: + type: + - boolean + - "null" + is_value_added: + type: + - number + - "null" + last_modified_time: + type: + - string + - "null" + output_tax_account_name: + type: + - string + - "null" + start_date: + type: + - string + - "null" + status: + type: + - string + - "null" + tax_account_id: + type: + - string + - "null" + tax_id: + type: string + tax_name: + type: + - string + - "null" + tax_percentage: + type: + - number + - "null" + tax_type: + type: + - string + - "null" + required: + - tax_id diff --git a/airbyte-integrations/connectors/source-zoho-expense/metadata.yaml b/airbyte-integrations/connectors/source-zoho-expense/metadata.yaml new file mode 100644 index 000000000000..35e40a26ce23 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-expense/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "zohoapis." + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-zoho-expense + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 9acfeefc-dad6-4887-a928-6c15ce5737b6 + dockerImageTag: 0.0.4 + dockerRepository: airbyte/source-zoho-expense + githubIssueLabel: source-zoho-expense + icon: icon.svg + license: MIT + name: Zoho Expense + releaseDate: 2024-10-26 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/zoho-expense + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-zoho-inventory/metadata.yaml b/airbyte-integrations/connectors/source-zoho-inventory/metadata.yaml index 0bc31106595c..e9ba8a28cca2 100644 --- a/airbyte-integrations/connectors/source-zoho-inventory/metadata.yaml +++ b/airbyte-integrations/connectors/source-zoho-inventory/metadata.yaml @@ -13,11 +13,11 @@ data: enabled: false packageName: airbyte-source-zoho-inventory connectorBuildOptions: - baseImage: docker.io/airbyte/source-declarative-manifest:5.17.0@sha256:9c6bfd080a247b7781ce5b25687e7c44e29d31315d0bf656584b38810521bbaa + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: 757a3302-b2d5-4fb5-ae7f-b161fd619215 - dockerImageTag: 0.0.3 + dockerImageTag: 0.0.6 dockerRepository: airbyte/source-zoho-inventory githubIssueLabel: source-zoho-inventory icon: icon.svg diff --git a/airbyte-integrations/connectors/source-zoho-invoice/README.md b/airbyte-integrations/connectors/source-zoho-invoice/README.md new file mode 100644 index 000000000000..7642ae7adaf6 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-invoice/README.md @@ -0,0 +1,35 @@ +# Zoho Invoice +This directory contains the manifest-only connector for `source-zoho-invoice`. + +Zoho invoice is an invoicing software used by businesses. +With this connector we can extract data from various streams such as items , contacts and invoices streams. +Docs : https://www.zoho.com/invoice/api/v3/introduction/#overview + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-zoho-invoice:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-zoho-invoice build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-zoho-invoice test +``` + diff --git a/airbyte-integrations/connectors/source-zoho-invoice/acceptance-test-config.yml b/airbyte-integrations/connectors/source-zoho-invoice/acceptance-test-config.yml new file mode 100644 index 000000000000..e5917c672ea0 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-invoice/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-zoho-invoice:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-zoho-invoice/icon.svg b/airbyte-integrations/connectors/source-zoho-invoice/icon.svg new file mode 100644 index 000000000000..294ea2205395 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-invoice/icon.svg @@ -0,0 +1 @@ + diff --git a/airbyte-integrations/connectors/source-zoho-invoice/manifest.yaml b/airbyte-integrations/connectors/source-zoho-invoice/manifest.yaml new file mode 100644 index 000000000000..0ef01fc65076 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-invoice/manifest.yaml @@ -0,0 +1,1654 @@ +version: 6.1.0 + +type: DeclarativeSource + +description: >- + Zoho invoice is an invoicing software used by businesses. + + With this connector we can extract data from various streams such as items , + contacts and invoices streams. + + Docs : https://www.zoho.com/invoice/api/v3/introduction/#overview + +check: + type: CheckStream + stream_names: + - items + +definitions: + streams: + items: + type: DeclarativeStream + name: items + primary_key: + - item_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: items + http_method: GET + request_headers: + X-com-zoho-invoice-organizationid: "{{ config['organization_id'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - items + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 200 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/items" + users: + type: DeclarativeStream + name: users + primary_key: + - user_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: users + http_method: GET + request_headers: + X-com-zoho-invoice-organizationid: "{{ config['organization_id'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - users + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 200 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - contact_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: contacts + http_method: GET + request_headers: + X-com-zoho-invoice-organizationid: "{{ config['organization_id'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - contacts + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 200 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + invoices: + type: DeclarativeStream + name: invoices + primary_key: + - invoice_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: invoices + http_method: GET + request_headers: + X-com-zoho-invoice-organizationid: "{{ config['organization_id'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - invoices + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 200 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/invoices" + recurring_invoices: + type: DeclarativeStream + name: recurring_invoices + primary_key: + - recurring_invoice_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: recurringinvoices + http_method: GET + request_headers: + X-com-zoho-invoice-organizationid: "{{ config['organization_id'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - recurring_invoices + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 200 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/recurring_invoices" + customer_payments: + type: DeclarativeStream + name: customer_payments + primary_key: + - payment_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: customerpayments + http_method: GET + request_headers: + X-com-zoho-invoice-organizationid: "{{ config['organization_id'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - customerpayments + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 200 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/customer_payments" + credit notes: + type: DeclarativeStream + name: credit notes + primary_key: + - creditnote_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: creditnotes + http_method: GET + request_headers: + X-com-zoho-invoice-organizationid: "{{ config['organization_id'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - creditnotes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 200 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/credit notes" + expenses: + type: DeclarativeStream + name: expenses + primary_key: + - expense_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: expenses + http_method: GET + request_headers: + X-com-zoho-invoice-organizationid: "{{ config['organization_id'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - expenses + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 200 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/expenses" + taxes: + type: DeclarativeStream + name: taxes + primary_key: + - tax_id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /settings/taxes + http_method: GET + request_headers: + X-com-zoho-invoice-organizationid: "{{ config['organization_id'] }}" + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - taxes + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + field_name: per_page + inject_into: request_parameter + pagination_strategy: + type: OffsetIncrement + page_size: 200 + inject_on_first_request: false + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/taxes" + base_requester: + type: HttpRequester + url_base: https://www.zohoapis.{{ config['region'] }}/invoice/v3/ + authenticator: + type: OAuthAuthenticator + client_id: "{{ config[\"client_id\"] }}" + grant_type: refresh_token + client_secret: "{{ config[\"client_secret\"] }}" + refresh_token: "{{ config[\"client_refresh_token\"] }}" + refresh_request_body: {} + token_refresh_endpoint: https://accounts.zoho.in/oauth/v2/token + +streams: + - $ref: "#/definitions/streams/items" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/invoices" + - $ref: "#/definitions/streams/recurring_invoices" + - $ref: "#/definitions/streams/customer_payments" + - $ref: "#/definitions/streams/credit notes" + - $ref: "#/definitions/streams/expenses" + - $ref: "#/definitions/streams/taxes" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - client_id + - client_secret + - client_refresh_token + - region + properties: + client_id: + type: string + order: 0 + title: Client ID + airbyte_secret: true + client_secret: + type: string + order: 1 + title: Client secret + airbyte_secret: true + client_refresh_token: + type: string + order: 2 + title: Refresh token + airbyte_secret: true + organization_id: + type: string + description: To be provided if a user belongs to multiple organizations + order: 3 + title: Organization ID + region: + type: string + enum: + - com + - eu + - in + - com.cn + - com.au + - jp + - sa + - ca + order: 4 + title: Region + additionalProperties: true + +metadata: + autoImportSchema: + items: true + users: true + contacts: true + invoices: true + recurring_invoices: true + customer_payments: true + credit notes: true + expenses: true + taxes: true + testedStreams: + items: + streamHash: 2d6534f99c83d65519effcb14e7d119db1674f5a + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + users: + streamHash: a246106b1c4373a5105508c126c539ca69b541d6 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contacts: + hasRecords: true + streamHash: 6150e20bbb3c3b7fefae12d87efb22179139d52a + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + invoices: + hasRecords: true + streamHash: cb0cb9526e649a7522b3b2d86aa4ef5af5581a0b + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + recurring_invoices: + hasRecords: true + streamHash: 5de65fa77e81237f1fa6a6275a6dbaff59458b80 + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + customer_payments: + hasRecords: true + streamHash: 7625f6062136e947be65114ae692df425d96aa7c + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + credit notes: + hasRecords: true + streamHash: e1cf97fe81ac4aefb324072130c8946e515e802b + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + expenses: + hasRecords: true + streamHash: 147537711b05fb4a95fbb6c85c1c14c0e43f4a9d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + taxes: + hasRecords: true + streamHash: f47e68753dd13cf3fb35b455ac0ea4ef6539e27d + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: {} + +schemas: + items: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + created_time: + type: + - string + - "null" + has_attachment: + type: + - boolean + - "null" + image_document_id: + type: + - string + - "null" + image_name: + type: + - string + - "null" + image_type: + type: + - string + - "null" + is_linked_with_zohocrm: + type: + - boolean + - "null" + item_id: + type: string + item_name: + type: + - string + - "null" + last_modified_time: + type: + - string + - "null" + name: + type: + - string + - "null" + product_type: + type: + - string + - "null" + rate: + type: + - number + - "null" + sku: + type: + - string + - "null" + source: + type: + - string + - "null" + status: + type: + - string + - "null" + tax_id: + type: + - string + - "null" + tax_name: + type: + - string + - "null" + tax_percentage: + type: + - number + - "null" + unit: + type: + - string + - "null" + zcrm_product_id: + type: + - string + - "null" + required: + - item_id + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + email: + type: + - string + - "null" + invitation_type: + type: + - string + - "null" + is_current_user: + type: + - boolean + - "null" + is_customer_segmented: + type: + - boolean + - "null" + is_employee: + type: + - boolean + - "null" + is_super_admin: + type: + - boolean + - "null" + is_vendor_segmented: + type: + - boolean + - "null" + mobile: + type: + - string + - "null" + name: + type: + - string + - "null" + photo_url: + type: + - string + - "null" + role_id: + type: + - string + - "null" + status: + type: + - string + - "null" + user_id: + type: string + user_role: + type: + - string + - "null" + user_type: + type: + - string + - "null" + required: + - user_id + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + ach_supported: + type: + - boolean + - "null" + company_name: + type: + - string + - "null" + contact_id: + type: string + contact_name: + type: + - string + - "null" + contact_type: + type: + - string + - "null" + contact_type_formatted: + type: + - string + - "null" + created_time: + type: + - string + - "null" + created_time_formatted: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + currency_id: + type: + - string + - "null" + custom_field_hash: + type: + - object + - "null" + custom_fields: + type: + - array + - "null" + customer_name: + type: + - string + - "null" + customer_sub_type: + type: + - string + - "null" + email: + type: + - string + - "null" + facebook: + type: + - string + - "null" + first_name: + type: + - string + - "null" + has_attachment: + type: + - boolean + - "null" + is_linked_with_zohocrm: + type: + - boolean + - "null" + language_code: + type: + - string + - "null" + language_code_formatted: + type: + - string + - "null" + last_modified_time: + type: + - string + - "null" + last_modified_time_formatted: + type: + - string + - "null" + last_name: + type: + - string + - "null" + mobile: + type: + - string + - "null" + outstanding_receivable_amount: + type: + - number + - "null" + outstanding_receivable_amount_bcy: + type: + - number + - "null" + pan_no: + type: + - string + - "null" + payment_terms: + type: + - number + - "null" + payment_terms_label: + type: + - string + - "null" + phone: + type: + - string + - "null" + portal_status: + type: + - string + - "null" + portal_status_formatted: + type: + - string + - "null" + source: + type: + - string + - "null" + status: + type: + - string + - "null" + twitter: + type: + - string + - "null" + unused_credits_receivable_amount: + type: + - number + - "null" + unused_credits_receivable_amount_bcy: + type: + - number + - "null" + vendor_name: + type: + - string + - "null" + website: + type: + - string + - "null" + required: + - contact_id + invoices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - string + - "null" + ach_payment_initiated: + type: + - boolean + - "null" + adjustment: + type: + - number + - "null" + balance: + type: + - number + - "null" + billing_address: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + attention: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + fax: + type: + - string + - "null" + phone: + type: + - string + - "null" + state: + type: + - string + - "null" + street2: + type: + - string + - "null" + zipcode: + type: + - string + - "null" + client_viewed_time: + type: + - string + - "null" + color_code: + type: + - string + - "null" + company_name: + type: + - string + - "null" + country: + type: + - string + - "null" + created_by: + type: + - string + - "null" + created_time: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + currency_id: + type: + - string + - "null" + currency_symbol: + type: + - string + - "null" + current_sub_status: + type: + - string + - "null" + current_sub_status_id: + type: + - string + - "null" + custom_field_hash: + type: + - object + - "null" + custom_fields: + type: + - array + - "null" + customer_id: + type: + - string + - "null" + customer_name: + type: + - string + - "null" + date: + type: + - string + - "null" + documents: + type: + - string + - "null" + due_date: + type: + - string + - "null" + due_days: + type: + - string + - "null" + email: + type: + - string + - "null" + exchange_rate: + type: + - number + - "null" + has_attachment: + type: + - boolean + - "null" + invoice_id: + type: string + invoice_number: + type: + - string + - "null" + invoice_url: + type: + - string + - "null" + is_emailed: + type: + - boolean + - "null" + is_pre_gst: + type: + - boolean + - "null" + is_viewed_by_client: + type: + - boolean + - "null" + is_viewed_in_mail: + type: + - boolean + - "null" + last_modified_time: + type: + - string + - "null" + last_payment_date: + type: + - string + - "null" + last_reminder_sent_date: + type: + - string + - "null" + mail_first_viewed_time: + type: + - string + - "null" + mail_last_viewed_time: + type: + - string + - "null" + no_of_copies: + type: + - number + - "null" + payment_expected_date: + type: + - string + - "null" + phone: + type: + - string + - "null" + project_name: + type: + - string + - "null" + reference_number: + type: + - string + - "null" + reminders_sent: + type: + - number + - "null" + salesperson_id: + type: + - string + - "null" + salesperson_name: + type: + - string + - "null" + schedule_time: + type: + - string + - "null" + shipping_address: + type: + - object + - "null" + properties: + address: + type: + - string + - "null" + attention: + type: + - string + - "null" + city: + type: + - string + - "null" + country: + type: + - string + - "null" + fax: + type: + - string + - "null" + phone: + type: + - string + - "null" + state: + type: + - string + - "null" + street2: + type: + - string + - "null" + zipcode: + type: + - string + - "null" + shipping_charge: + type: + - number + - "null" + show_no_of_copies: + type: + - boolean + - "null" + status: + type: + - string + - "null" + template_id: + type: + - string + - "null" + template_type: + type: + - string + - "null" + total: + type: + - number + - "null" + transaction_type: + type: + - string + - "null" + unprocessed_payment_amount: + type: + - number + - "null" + updated_time: + type: + - string + - "null" + write_off_amount: + type: + - number + - "null" + zcrm_potential_id: + type: + - string + - "null" + zcrm_potential_name: + type: + - string + - "null" + required: + - invoice_id + recurring_invoices: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + child_entity_type: + type: + - string + - "null" + created_time: + type: + - string + - "null" + customer_id: + type: + - string + - "null" + customer_name: + type: + - string + - "null" + end_date: + type: + - string + - "null" + last_four_digits: + type: + - string + - "null" + last_modified_time: + type: + - string + - "null" + last_sent_date: + type: + - string + - "null" + next_invoice_date: + type: + - string + - "null" + recurrence_frequency: + type: + - string + - "null" + recurrence_name: + type: + - string + - "null" + recurring_invoice_id: + type: string + reference_number: + type: + - string + - "null" + repeat_every: + type: + - number + - "null" + salesperson_id: + type: + - string + - "null" + salesperson_name: + type: + - string + - "null" + start_date: + type: + - string + - "null" + status: + type: + - string + - "null" + total: + type: + - number + - "null" + required: + - recurring_invoice_id + customer_payments: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + amount: + type: + - number + - "null" + applied_invoices: + type: + - array + - "null" + bcy_amount: + type: + - number + - "null" + bcy_refunded_amount: + type: + - number + - "null" + bcy_unused_amount: + type: + - number + - "null" + created_time: + type: + - string + - "null" + custom_fields_list: + type: + - string + - "null" + customer_id: + type: + - string + - "null" + customer_name: + type: + - string + - "null" + date: + type: + - string + - "null" + documents: + type: + - string + - "null" + gateway_transaction_id: + type: + - string + - "null" + has_attachment: + type: + - boolean + - "null" + invoice_numbers: + type: + - string + - "null" + last_four_digits: + type: + - string + - "null" + last_modified_time: + type: + - string + - "null" + payment_gateway: + type: + - string + - "null" + payment_id: + type: string + payment_mode: + type: + - string + - "null" + payment_mode_formatted: + type: + - string + - "null" + payment_number: + type: + - string + - "null" + payment_status: + type: + - string + - "null" + payment_type: + type: + - string + - "null" + product_description: + type: + - string + - "null" + reference_number: + type: + - string + - "null" + settlement_status: + type: + - string + - "null" + tax_amount_withheld: + type: + - number + - "null" + unused_amount: + type: + - number + - "null" + required: + - payment_id + credit notes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + applied_invoices: + type: + - string + - "null" + balance: + type: + - number + - "null" + client_viewed_time: + type: + - string + - "null" + color_code: + type: + - string + - "null" + created_time: + type: + - string + - "null" + creditnote_id: + type: string + creditnote_number: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + currency_id: + type: + - string + - "null" + current_sub_status: + type: + - string + - "null" + current_sub_status_id: + type: + - string + - "null" + customer_id: + type: + - string + - "null" + customer_name: + type: + - string + - "null" + date: + type: + - string + - "null" + exchange_rate: + type: + - number + - "null" + has_attachment: + type: + - boolean + - "null" + is_emailed: + type: + - boolean + - "null" + is_viewed_by_client: + type: + - boolean + - "null" + last_modified_time: + type: + - string + - "null" + price_precision: + type: + - number + - "null" + reference_number: + type: + - string + - "null" + salesperson_id: + type: + - string + - "null" + salesperson_name: + type: + - string + - "null" + status: + type: + - string + - "null" + template_id: + type: + - string + - "null" + template_type: + type: + - string + - "null" + total: + type: + - number + - "null" + required: + - creditnote_id + expenses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + account_name: + type: + - string + - "null" + bcy_total: + type: + - number + - "null" + bcy_total_without_tax: + type: + - number + - "null" + created_time: + type: + - string + - "null" + currency_code: + type: + - string + - "null" + currency_id: + type: + - string + - "null" + custom_fields_list: + type: + - string + - "null" + customer_id: + type: + - string + - "null" + customer_name: + type: + - string + - "null" + date: + type: + - string + - "null" + distance: + type: + - number + - "null" + end_reading: + type: + - string + - "null" + exchange_rate: + type: + - number + - "null" + expense_id: + type: string + expense_receipt_name: + type: + - string + - "null" + expense_type: + type: + - string + - "null" + has_attachment: + type: + - boolean + - "null" + is_billable: + type: + - boolean + - "null" + is_personal: + type: + - boolean + - "null" + last_modified_time: + type: + - string + - "null" + mileage_rate: + type: + - number + - "null" + mileage_type: + type: + - string + - "null" + mileage_unit: + type: + - string + - "null" + reference_number: + type: + - string + - "null" + report_id: + type: + - string + - "null" + report_name: + type: + - string + - "null" + report_number: + type: + - string + - "null" + start_reading: + type: + - string + - "null" + status: + type: + - string + - "null" + total: + type: + - number + - "null" + total_without_tax: + type: + - number + - "null" + user_name: + type: + - string + - "null" + required: + - expense_id + taxes: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + diff_rate_reason: + type: + - string + - "null" + end_date: + type: + - string + - "null" + is_default_tax: + type: + - boolean + - "null" + is_editable: + type: + - boolean + - "null" + is_inactive: + type: + - boolean + - "null" + last_modified_time: + type: + - string + - "null" + start_date: + type: + - string + - "null" + status: + type: + - string + - "null" + tax_id: + type: string + tax_name: + type: + - string + - "null" + tax_percentage: + type: + - number + - "null" + tax_specific_type: + type: + - string + - "null" + tax_specification: + type: + - string + - "null" + tax_type: + type: + - string + - "null" + required: + - tax_id diff --git a/airbyte-integrations/connectors/source-zoho-invoice/metadata.yaml b/airbyte-integrations/connectors/source-zoho-invoice/metadata.yaml new file mode 100644 index 000000000000..2c93b51c6d79 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoho-invoice/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "zohoapis." + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-zoho-invoice + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 6ee3d92d-b081-4024-9214-2987ae114c17 + dockerImageTag: 0.0.4 + dockerRepository: airbyte/source-zoho-invoice + githubIssueLabel: source-zoho-invoice + icon: icon.svg + license: MIT + name: Zoho Invoice + releaseDate: 2024-11-05 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/zoho-invoice + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-zonka-feedback/README.md b/airbyte-integrations/connectors/source-zonka-feedback/README.md new file mode 100644 index 000000000000..32695a1e8da9 --- /dev/null +++ b/airbyte-integrations/connectors/source-zonka-feedback/README.md @@ -0,0 +1,39 @@ +# Zonka Feedback +This directory contains the manifest-only connector for `source-zonka-feedback`. + +This is the Zonka Feedback source that ingests data from the Zonka API. + +Zonka Feedback simplifies CX, allowing you to start meaningful two-way conversations with customers via powerful surveys. Design stunning surveys in minutes, gather data from all touchpoints, understand customers better with AI analytics & close the feedback loop — all within one powerful platform https://www.zonkafeedback.com/ + +To use this source, you must first create an account. Once logged in, click on Settings -> Developers -> API & Data Center. Note down your Data center and generate your auth token. + +For more information about the API visit https://apidocs.zonkafeedback.com/#intro + +## Usage +There are multiple ways to use this connector: +- You can use this connector as any other connector in Airbyte Marketplace. +- You can load this connector in `pyairbyte` using `get_source`! +- You can open this connector in Connector Builder, edit it, and publish to your workspaces. + +Please refer to the manifest-only connector documentation for more details. + +## Local Development +We recommend you use the Connector Builder to edit this connector. + +But, if you want to develop this connector locally, you can use the following steps. + +### Environment Setup +You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci). + +### Build +This will create a dev image (`source-zonka-feedback:dev`) that you can use to test the connector locally. +```bash +airbyte-ci connectors --name=source-zonka-feedback build +``` + +### Test +This will run the acceptance tests for the connector. +```bash +airbyte-ci connectors --name=source-zonka-feedback test +``` + diff --git a/airbyte-integrations/connectors/source-zonka-feedback/acceptance-test-config.yml b/airbyte-integrations/connectors/source-zonka-feedback/acceptance-test-config.yml new file mode 100644 index 000000000000..7374884ac6e5 --- /dev/null +++ b/airbyte-integrations/connectors/source-zonka-feedback/acceptance-test-config.yml @@ -0,0 +1,17 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-zonka-feedback:dev +acceptance_tests: + spec: + tests: + - spec_path: "manifest.yaml" + connection: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + discovery: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + basic_read: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + incremental: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" + full_refresh: + bypass_reason: "This is a builder contribution, and we do not have secrets at this time" diff --git a/airbyte-integrations/connectors/source-zonka-feedback/icon.svg b/airbyte-integrations/connectors/source-zonka-feedback/icon.svg new file mode 100644 index 000000000000..d7e55f2b0902 --- /dev/null +++ b/airbyte-integrations/connectors/source-zonka-feedback/icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/airbyte-integrations/connectors/source-zonka-feedback/manifest.yaml b/airbyte-integrations/connectors/source-zonka-feedback/manifest.yaml new file mode 100644 index 000000000000..b6b10a7dbba4 --- /dev/null +++ b/airbyte-integrations/connectors/source-zonka-feedback/manifest.yaml @@ -0,0 +1,995 @@ +version: 5.17.0 + +type: DeclarativeSource + +description: >- + This is the Zonka Feedback source that ingests data from the Zonka API. + + + Zonka Feedback simplifies CX, allowing you to start meaningful two-way + conversations with customers via powerful surveys. Design stunning surveys in + minutes, gather data from all touchpoints, understand customers better with AI + analytics & close the feedback loop — all within one powerful platform + https://www.zonkafeedback.com/ + + + To use this source, you must first create an account. Once logged in, click on + Settings -> Developers -> API & Data Center. Note down your Data center and + generate your auth token. + + + For more information about the API visit + https://apidocs.zonkafeedback.com/#intro + +check: + type: CheckStream + stream_names: + - responses + +definitions: + streams: + responses: + type: DeclarativeStream + name: responses + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /responses + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/responses" + workspaces: + type: DeclarativeStream + name: workspaces + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /workspaces + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/workspaces" + surveys: + type: DeclarativeStream + name: surveys + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /surveys + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/surveys" + contacts: + type: DeclarativeStream + name: contacts + primary_key: + - emailAddress + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /contacts + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: + - data + - list + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/contacts" + tasks: + type: DeclarativeStream + name: tasks + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /tasks + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/tasks" + users: + type: DeclarativeStream + name: users + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /users + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/users" + locations: + type: DeclarativeStream + name: locations + primary_key: + - id + retriever: + type: SimpleRetriever + requester: + $ref: "#/definitions/base_requester" + path: /locations + http_method: GET + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + paginator: + type: DefaultPaginator + page_token_option: + type: RequestOption + inject_into: request_parameter + field_name: page + page_size_option: + type: RequestOption + inject_into: request_parameter + field_name: limit + pagination_strategy: + type: PageIncrement + start_from_page: 1 + page_size: 100 + inject_on_first_request: true + schema_loader: + type: InlineSchemaLoader + schema: + $ref: "#/schemas/locations" + base_requester: + type: HttpRequester + url_base: https://{{ config['datacenter'] }}.apis.zonkafeedback.com + authenticator: + type: ApiKeyAuthenticator + api_token: "{{ config[\"auth_token\"] }}" + inject_into: + type: RequestOption + field_name: Z-API-TOKEN + inject_into: header + +streams: + - $ref: "#/definitions/streams/responses" + - $ref: "#/definitions/streams/workspaces" + - $ref: "#/definitions/streams/surveys" + - $ref: "#/definitions/streams/contacts" + - $ref: "#/definitions/streams/tasks" + - $ref: "#/definitions/streams/users" + - $ref: "#/definitions/streams/locations" + +spec: + type: Spec + connection_specification: + type: object + $schema: http://json-schema.org/draft-07/schema# + required: + - datacenter + - auth_token + properties: + datacenter: + type: string + description: The identifier for the data center, such as 'us1' or 'e' for EU. + enum: + - us1 + - e + name: dc_id + order: 0 + title: Data Center ID + auth_token: + type: string + description: >- + Auth token to use. Generate it by navigating to Company Settings > + Developers > API in your Zonka Feedback account. + name: auth_token + order: 1 + title: Auth Token + airbyte_secret: true + additionalProperties: true + +metadata: + autoImportSchema: + responses: true + workspaces: true + surveys: true + contacts: true + tasks: true + users: true + locations: true + testedStreams: + responses: + streamHash: 45864c9dfee8dd94b7c81f10f499cec03ad2127e + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + workspaces: + streamHash: c644d7a7709ab8218f21f01df8f1e7dc6ecbc2f6 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + surveys: + streamHash: fe999cb8cb8a1d8d883e3882c1522bfd77203288 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + contacts: + streamHash: 190251275e488fbf11a35e28457e9c9ca949ba63 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + tasks: + streamHash: 587a5b308da89877d45ce0d3470c8aadc191dc92 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + users: + streamHash: 225b8c2205b1ab9f83a2b900ddbf5a6ad14e3728 + hasResponse: true + responsesAreSuccessful: true + hasRecords: true + primaryKeysArePresent: true + primaryKeysAreUnique: true + locations: + hasRecords: true + streamHash: f79c494a0cdd71761274ad3cb8b8068cd6179fdf + hasResponse: true + primaryKeysAreUnique: true + primaryKeysArePresent: true + responsesAreSuccessful: true + assist: + docsUrl: https://apidocs.zonkafeedback.com/#intro + +schemas: + responses: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + NPS: + type: + - number + - "null" + browser: + type: + - string + - "null" + channel: + type: + - string + - "null" + contactAttributes: + type: + - array + - "null" + duration: + type: + - string + - "null" + geoLocation: + type: + - string + - "null" + hasComments: + type: + - string + - "null" + hasNotes: + type: + - string + - "null" + hasTask: + type: + - boolean + - "null" + id: + type: string + isImportant: + type: + - string + - "null" + isStarred: + type: + - string + - "null" + locationId: + type: + - string + - "null" + locationName: + type: + - string + - "null" + os: + type: + - string + - "null" + ratedUserId: + type: + - string + - "null" + ratedUserName: + type: + - string + - "null" + receivedDate: + type: + - string + - "null" + receivedDateLocal: + type: + - string + - "null" + respondentDetails: + type: + - object + - "null" + properties: + emailAddress: + type: + - string + - "null" + externalId: + type: + - string + - "null" + mobile: + type: + - string + - "null" + name: + type: + - string + - "null" + respondentId: + type: + - string + - "null" + responseAttributes: + type: + - array + - "null" + responseURL: + type: + - string + - "null" + surveyId: + type: + - string + - "null" + surveyLanguage: + type: + - string + - "null" + surveyName: + type: + - string + - "null" + surveyResponse: + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + answer: + type: + - string + - "null" + questionId: + type: + - string + - "null" + questionLabel: + type: + - string + - "null" + variableId: + type: + - string + - "null" + tags: + type: + - array + - "null" + takenByUserId: + type: + - string + - "null" + takenByUserName: + type: + - string + - "null" + taskIds: + type: + - string + - "null" + timeZone: + type: + - string + - "null" + webDevice: + type: + - string + - "null" + required: + - id + workspaces: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + id: + type: string + modifiedBy: + type: + - string + - "null" + modifiedDate: + type: + - string + - "null" + workspaceName: + type: + - string + - "null" + required: + - id + surveys: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + description: + type: + - string + - "null" + id: + type: string + isActive: + type: + - boolean + - "null" + locationId: + type: + - array + - "null" + modifiedBy: + type: + - string + - "null" + modifiedDate: + type: + - string + - "null" + name: + type: + - string + - "null" + webSurveyTitle: + type: + - string + - "null" + webSurveyURLs: + type: + - array + - "null" + items: + type: + - string + - "null" + workspaceId: + type: + - string + - "null" + workspaceName: + type: + - string + - "null" + required: + - id + contacts: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + _id: + type: + - string + - "null" + androidSessionCounts: + type: + - number + - "null" + attributes: + type: + - array + - "null" + averageNps: + type: + - number + - "null" + bounced: + type: + - boolean + - "null" + companyId: + type: + - string + - "null" + contactSource: + type: + - string + - "null" + createdBy: + type: + - string + - "null" + createdDate: + type: + - string + - "null" + emailAddress: + type: string + firstReferringSite: + type: + - string + - "null" + hasNote: + type: + - boolean + - "null" + historyImportedFromAnonymous: + type: + - boolean + - "null" + iosSessionCounts: + type: + - number + - "null" + lastEmailSurveySentDatetime: + type: + - string + - "null" + lastNps: + type: + - number + - "null" + lastPage: + type: + - string + - "null" + lastReferringSite: + type: + - string + - "null" + lastResponseDateTime: + type: + - string + - "null" + lastSurveyViewedDate: + type: + - string + - "null" + lastSurveyViewedId: + type: + - string + - "null" + lists: + type: + - array + - "null" + locations: + type: + - array + - "null" + mobile: + type: + - string + - "null" + modifiedBy: + type: + - string + - "null" + modifiedDate: + type: + - string + - "null" + name: + type: + - string + - "null" + numNotes: + type: + - number + - "null" + numPendingTasks: + type: + - number + - "null" + numTasks: + type: + - number + - "null" + pagesViewedCount: + type: + - number + - "null" + pre_mongified_id: + type: + - number + - "null" + sessionCounts: + type: + - number + - "null" + source: + type: + - string + - "null" + surveys: + type: + - array + - "null" + items: + type: + - string + - "null" + surveysVisits: + type: + - array + - "null" + items: + type: + - string + - "null" + totalResponses: + type: + - number + - "null" + uniqueId: + type: + - string + - "null" + unsubscribeEmail: + type: + - boolean + - "null" + unsubscribeSMS: + type: + - boolean + - "null" + utm_campaign: + type: + - string + - "null" + utm_content: + type: + - string + - "null" + utm_medium: + type: + - string + - "null" + utm_source: + type: + - string + - "null" + utm_term: + type: + - string + - "null" + webSessionCounts: + type: + - number + - "null" + widgetsAnswered: + type: + - array + - "null" + items: + type: + - string + - "null" + widgetsVisited: + type: + - array + - "null" + items: + type: + - string + - "null" + required: + - emailAddress + tasks: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + type: + type: + - object + - "null" + properties: + id: + type: + - string + - "null" + name: + type: + - string + - "null" + description: + type: + - string + - "null" + assignedTo: + type: + - array + - "null" + items: + type: + - string + - "null" + contactId: + type: + - string + - "null" + dueDateTime: + type: + - string + - "null" + id: + type: string + isCompleted: + type: + - boolean + - "null" + name: + type: + - string + - "null" + reminderSetting: + type: + - string + - "null" + responseId: + type: + - string + - "null" + required: + - id + users: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + designation: + type: + - string + - "null" + email: + type: + - string + - "null" + externalId: + type: + - string + - "null" + id: + type: string + isActive: + type: + - boolean + - "null" + isOwner: + type: + - boolean + - "null" + labels: + type: + - array + - "null" + lastLogin: + type: + - string + - "null" + locationId: + type: + - array + - "null" + items: + type: + - string + - "null" + mobile: + type: + - string + - "null" + name: + type: + - string + - "null" + role: + type: + - string + - "null" + required: + - id + locations: + type: object + $schema: http://json-schema.org/schema# + additionalProperties: true + properties: + address: + type: + - string + - "null" + externalId: + type: + - string + - "null" + id: + type: string + isActive: + type: + - boolean + - "null" + labels: + type: + - array + - "null" + name: + type: + - string + - "null" + required: + - id diff --git a/airbyte-integrations/connectors/source-zonka-feedback/metadata.yaml b/airbyte-integrations/connectors/source-zonka-feedback/metadata.yaml new file mode 100644 index 000000000000..a5148e367549 --- /dev/null +++ b/airbyte-integrations/connectors/source-zonka-feedback/metadata.yaml @@ -0,0 +1,35 @@ +metadataSpecVersion: "1.0" +data: + allowedHosts: + hosts: + - "https://*.apis.zonkafeedback.com" + registryOverrides: + oss: + enabled: true + cloud: + enabled: true + remoteRegistries: + pypi: + enabled: false + packageName: airbyte-source-zonka-feedback + connectorBuildOptions: + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc + connectorSubtype: api + connectorType: source + definitionId: 353443ba-1330-409e-83b5-b0a2dfc88540 + dockerImageTag: 0.0.4 + dockerRepository: airbyte/source-zonka-feedback + githubIssueLabel: source-zonka-feedback + icon: icon.svg + license: MIT + name: Zonka Feedback + releaseDate: 2024-10-29 + releaseStage: alpha + supportLevel: community + documentationUrl: https://docs.airbyte.com/integrations/sources/zonka-feedback + tags: + - language:manifest-only + - cdk:low-code + ab_internal: + ql: 100 + sl: 100 diff --git a/airbyte-integrations/connectors/source-zoom/README.md b/airbyte-integrations/connectors/source-zoom/README.md index 4b79a68fd3d6..633cc9023d00 100644 --- a/airbyte-integrations/connectors/source-zoom/README.md +++ b/airbyte-integrations/connectors/source-zoom/README.md @@ -1,105 +1,49 @@ -# Zoom Source +# Zoom source connector -This is the repository for the Zoom configuration based source connector. -For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.io/integrations/sources/zoom). +This directory contains the manifest-only connector for `source-zoom`. +This _manifest-only_ connector is not a Python package on its own, as it runs inside of the base `source-declarative-manifest` image. -## Local development +For information about how to configure and use this connector within Airbyte, see [the connector's full documentation](https://docs.airbyte.com/integrations/sources/zoom). -#### Create credentials +## Local development -**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.io/integrations/sources/zoom) -to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_survey_sparrow/spec.yaml` file. -Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. -See `integration_tests/sample_config.json` for a sample config file. +We recommend using the Connector Builder to edit this connector. +Using either Airbyte Cloud or your local Airbyte OSS instance, navigate to the **Builder** tab and select **Import a YAML**. +Then select the connector's `manifest.yaml` file to load the connector into the Builder. You're now ready to make changes to the connector! -**If you are an Airbyte core member**, copy the credentials in Lastpass under the secret name `source zoom test creds` -and place them into `secrets/config.json`. +If you prefer to develop locally, you can follow the instructions below. -### Locally running the connector docker image +### Building the docker image -#### Use `airbyte-ci` to build your connector +You can build any manifest-only connector with `airbyte-ci`: -The Airbyte way of building this connector is to use our `airbyte-ci` tool. -You can follow install instructions [here](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md#L1). -Then running the following command will build your connector: +1. Install [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md) +2. Run the following command to build the docker image: ```bash -airbyte-ci connectors --name source-zoom build -``` - -Once the command is done, you will find your connector image in your local docker registry: `airbyte/source-zoom:dev`. - -##### Customizing our build process - -When contributing on our connector you might need to customize the build process to add a system dependency or set an env var. -You can customize our build process by adding a `build_customization.py` module to your connector. -This module should contain a `pre_connector_install` and `post_connector_install` async function that will mutate the base image and the connector container respectively. -It will be imported at runtime by our build process and the functions will be called if they exist. - -Here is an example of a `build_customization.py` module: - -```python -from __future__ import annotations - -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - # Feel free to check the dagger documentation for more information on the Container object and its methods. - # https://dagger-io.readthedocs.io/en/sdk-python-v0.6.4/ - from dagger import Container - - -async def pre_connector_install(base_image_container: Container) -> Container: - return await base_image_container.with_env_variable("MY_PRE_BUILD_ENV_VAR", "my_pre_build_env_var_value") - -async def post_connector_install(connector_container: Container) -> Container: - return await connector_container.with_env_variable("MY_POST_BUILD_ENV_VAR", "my_post_build_env_var_value") +airbyte-ci connectors --name=source-zoom build ``` -#### Build your own connector image - -This connector is built using our dynamic built process in `airbyte-ci`. -The base image used to build it is defined within the metadata.yaml file under the `connectorBuildOptions`. -The build logic is defined using [Dagger](https://dagger.io/) [here](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/pipelines/builds/python_connectors.py). -It does not rely on a Dockerfile. - -If you would like to patch our connector and build your own a simple approach would be to: +An image will be available on your host with the tag `airbyte/source-zoom:dev`. -1. Create your own Dockerfile based on the latest version of the connector image. +### Creating credentials -```Dockerfile -FROM airbyte/source-zoom:latest - -COPY . ./airbyte/integration_code -RUN pip install ./airbyte/integration_code - -# The entrypoint and default env vars are already set in the base image -# ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" -# ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -``` +**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/zoom) +to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `spec` object in the connector's `manifest.yaml` file. +Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. -Please use this as an example. This is not optimized. +### Running as a docker container -2. Build your image: +Then run any of the standard source connector commands: ```bash -docker build -t airbyte/source-zoom:dev . -# Running the spec command against your patched connector -docker run airbyte/source-zoom:dev spec -``` - -#### Run - -Then run any of the connector commands as follows: - -``` docker run --rm airbyte/source-zoom:dev spec docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-zoom:dev check --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-zoom:dev discover --config /secrets/config.json docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-zoom:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json ``` -## Testing +### Running the CI test suite You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): @@ -107,27 +51,15 @@ You can run our full test suite locally using [`airbyte-ci`](https://github.com/ airbyte-ci connectors --name=source-zoom test ``` -### Customizing acceptance Tests - -Customize `acceptance-test-config.yml` file to configure tests. See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) for more information. -If your connector requires to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py. - -## Dependency Management - -All of your dependencies should go in `setup.py`, NOT `requirements.txt`. The requirements file is only used to connect internal Airbyte dependencies in the monorepo for local development. -We split dependencies between two groups, dependencies that are: - -- required for your connector to work need to go to `MAIN_REQUIREMENTS` list. -- required for the testing need to go to `TEST_REQUIREMENTS` list - -### Publishing a new version of the connector - -You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what? +## Publishing a new version of the connector -1. Make sure your changes are passing our test suite: `airbyte-ci connectors --name=source-zoom test` -2. Bump the connector version in `metadata.yaml`: increment the `dockerImageTag` value. Please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors). -3. Make sure the `metadata.yaml` content is up to date. -4. Make the connector documentation and its changelog is up to date (`docs/integrations/sources/zoom.md`). +If you want to contribute changes to `source-zoom`, here's how you can do that: +1. Make your changes locally, or load the connector's manifest into Connector Builder and make changes there. +2. Make sure your changes are passing our test suite with `airbyte-ci connectors --name=source-zoom test` +3. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): + - bump the `dockerImageTag` value in in `metadata.yaml` +4. Make sure the connector documentation and its changelog is up to date (`docs/integrations/sources/zoom.md`). 5. Create a Pull Request: use [our PR naming conventions](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#pull-request-title-convention). 6. Pat yourself on the back for being an awesome contributor. 7. Someone from Airbyte will take a look at your PR and iterate with you to merge it into master. +8. Once your PR is merged, the new version of the connector will be automatically published to Docker Hub and our connector registry. \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-zoom/__init__.py b/airbyte-integrations/connectors/source-zoom/__init__.py deleted file mode 100644 index c941b3045795..000000000000 --- a/airbyte-integrations/connectors/source-zoom/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# diff --git a/airbyte-integrations/connectors/source-zoom/acceptance-test-config.yml b/airbyte-integrations/connectors/source-zoom/acceptance-test-config.yml index 55fa9e4ac247..a632bedd3cf8 100644 --- a/airbyte-integrations/connectors/source-zoom/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-zoom/acceptance-test-config.yml @@ -4,7 +4,7 @@ connector_image: airbyte/source-zoom:dev acceptance_tests: spec: tests: - - spec_path: "source_zoom/spec.yaml" + - spec_path: "manifest.yaml" connection: tests: - config_path: "secrets/config.json" @@ -51,5 +51,7 @@ acceptance_tests: ignored_fields: meetings: - name: "start_url" - bypass_reason: "Causes sequential_read test to fail as the value is unique upon each read" + bypass_reason: + "Causes sequential_read test to fail as the value is unique + upon each read" timeout_seconds: 3600 diff --git a/airbyte-integrations/connectors/source-zoom/components.py b/airbyte-integrations/connectors/source-zoom/components.py new file mode 100644 index 000000000000..ef268f774550 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/components.py @@ -0,0 +1,87 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import base64 +import time +from dataclasses import dataclass +from http import HTTPStatus +from typing import Any, Mapping, Optional, Union + +import requests +from requests import HTTPError + +from airbyte_cdk.sources.declarative.auth.declarative_authenticator import NoAuth +from airbyte_cdk.sources.declarative.interpolation import InterpolatedString +from airbyte_cdk.sources.declarative.types import Config + + +# https://developers.zoom.us/docs/internal-apps/s2s-oauth/#successful-response +# The Bearer token generated by server-to-server token will expire in one hour +BEARER_TOKEN_EXPIRES_IN = 3590 + + +class SingletonMeta(type): + _instances = {} + + def __call__(cls, *args, **kwargs): + """ + Possible changes to the value of the `__init__` argument do not affect + the returned instance. + """ + if cls not in cls._instances: + instance = super().__call__(*args, **kwargs) + cls._instances[cls] = instance + return cls._instances[cls] + + +@dataclass +class ServerToServerOauthAuthenticator(NoAuth): + config: Config + account_id: Union[InterpolatedString, str] + client_id: Union[InterpolatedString, str] + client_secret: Union[InterpolatedString, str] + authorization_endpoint: Union[InterpolatedString, str] + + _instance = None + _generate_token_time = 0 + _access_token = None + _grant_type = "account_credentials" + + def __post_init__(self, parameters: Mapping[str, Any]): + self._account_id = InterpolatedString.create(self.account_id, parameters=parameters).eval(self.config) + self._client_id = InterpolatedString.create(self.client_id, parameters=parameters).eval(self.config) + self._client_secret = InterpolatedString.create(self.client_secret, parameters=parameters).eval(self.config) + self._authorization_endpoint = InterpolatedString.create(self.authorization_endpoint, parameters=parameters).eval(self.config) + + def __call__(self, request: requests.PreparedRequest) -> requests.PreparedRequest: + """Attach the page access token to params to authenticate on the HTTP request""" + if self._access_token is None or ((time.time() - self._generate_token_time) > BEARER_TOKEN_EXPIRES_IN): + self._generate_token_time = time.time() + self._access_token = self.generate_access_token() + headers = {"Authorization": f"Bearer {self._access_token}", "Content-type": "application/json"} + request.headers.update(headers) + + return request + + @property + def auth_header(self) -> str: + return "Authorization" + + @property + def token(self) -> Optional[str]: + return self._access_token if self._access_token else None + + def generate_access_token(self) -> str: + self._generate_token_time = time.time() + try: + token = base64.b64encode(f"{self._client_id}:{self._client_secret}".encode("ascii")).decode("utf-8") + headers = {"Authorization": f"Basic {token}", "Content-type": "application/json"} + rest = requests.post( + url=f"{self._authorization_endpoint}?grant_type={self._grant_type}&account_id={self._account_id}", headers=headers + ) + if rest.status_code != HTTPStatus.OK: + raise HTTPError(rest.text) + return rest.json().get("access_token") + except Exception as e: + raise Exception(f"Error while generating access token: {e}") from e diff --git a/airbyte-integrations/connectors/source-zoom/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-zoom/integration_tests/acceptance.py index 82823254d266..fbed37992cb4 100644 --- a/airbyte-integrations/connectors/source-zoom/integration_tests/acceptance.py +++ b/airbyte-integrations/connectors/source-zoom/integration_tests/acceptance.py @@ -5,6 +5,7 @@ import pytest + pytest_plugins = ("connector_acceptance_test.plugin",) diff --git a/airbyte-integrations/connectors/source-zoom/main.py b/airbyte-integrations/connectors/source-zoom/main.py deleted file mode 100644 index 137aea5931e6..000000000000 --- a/airbyte-integrations/connectors/source-zoom/main.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from source_zoom.run import run - -if __name__ == "__main__": - run() diff --git a/airbyte-integrations/connectors/source-zoom/manifest.yaml b/airbyte-integrations/connectors/source-zoom/manifest.yaml new file mode 100644 index 000000000000..efdb8eb14634 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/manifest.yaml @@ -0,0 +1,14184 @@ +version: 5.14.0 +definitions: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + zoom_paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + users_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + meetings_list_tmp_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/meetings" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "meetings" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + meetings_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/meetings/{{ stream_partition.parent_id }}" + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/meetings" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "meetings" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "id" + partition_field: "parent_id" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + assistant_id: + type: + - 'null' + - string + host_email: + type: + - 'null' + - string + host_id: + type: + - 'null' + - string + id: + type: + - 'null' + - number + uuid: + type: + - 'null' + - string + agenda: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + duration: + type: + - 'null' + - number + encrypted_password: + type: + - 'null' + - string + h323_password: + type: + - 'null' + - string + join_url: + type: + - 'null' + - string + chat_join_url: + type: + - 'null' + - string + occurrences: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + duration: + type: + - 'null' + - number + occurrence_id: + type: + - 'null' + - string + start_time: + type: + - 'null' + - string + status: + type: + - 'null' + - string + password: + type: + - 'null' + - string + pmi: + type: + - 'null' + - string + pre_schedule: + type: + - 'null' + - boolean + pstn_password: + type: + - 'null' + - string + recurrence: + type: + - 'null' + - object + properties: + end_date_time: + type: + - 'null' + - string + end_times: + type: + - 'null' + - number + monthly_day: + type: + - 'null' + - number + monthly_week: + type: + - 'null' + - number + monthly_week_day: + type: + - 'null' + - number + repeat_interval: + type: + - 'null' + - number + type: + type: + - 'null' + - number + weekly_days: + type: + - 'null' + - string + settings: + type: + - 'null' + - object + properties: + allow_multiple_devices: + type: + - 'null' + - boolean + alternative_hosts: + type: + - 'null' + - string + alternative_hosts_email_notification: + type: + - 'null' + - boolean + alternative_host_update_polls: + type: + - 'null' + - boolean + approval_type: + type: + - 'null' + - number + approved_or_denied_countries_or_regions: + type: + - 'null' + - object + properties: + approved_list: + type: + - 'null' + - array + items: + type: + - 'null' + - string + denied_list: + type: + - 'null' + - array + items: + type: + - 'null' + - string + enable: + type: + - 'null' + - boolean + method: + type: + - 'null' + - string + audio: + type: + - 'null' + - string + audio_conference_info: + type: + - 'null' + - string + authentication_domains: + type: + - 'null' + - string + authentication_exception: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + email: + type: + - 'null' + - string + name: + type: + - 'null' + - string + join_url: + type: + - 'null' + - string + authentication_name: + type: + - 'null' + - string + authentication_option: + type: + - 'null' + - string + auto_recording: + type: + - 'null' + - string + breakout_room: + type: + - 'null' + - object + properties: + enable: + type: + - 'null' + - boolean + rooms: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + name: + type: + - 'null' + - string + participants: + type: + - 'null' + - array + items: + type: + - 'null' + - string + calendar_type: + type: + - 'null' + - number + close_registration: + type: + - 'null' + - boolean + cn_meeting: + type: + - 'null' + - boolean + contact_email: + type: + - 'null' + - string + contact_name: + type: + - 'null' + - string + custom_keys: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + key: + type: + - 'null' + - string + value: + type: + - 'null' + - string + email_notification: + type: + - 'null' + - boolean + device_testing: + type: + - 'null' + - boolean + email_in_attendee_report: + type: + - 'null' + - boolean + enable_dedicated_group_chat: + type: + - 'null' + - boolean + encryption_type: + type: + - 'null' + - string + enforce_login: + type: + - 'null' + - boolean + enforce_login_domains: + type: + - 'null' + - string + focus_mode: + type: + - 'null' + - boolean + global_dial_in_countries: + type: + - 'null' + - array + items: + type: + - 'null' + - string + global_dial_in_numbers: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + city: + type: + - 'null' + - string + country: + type: + - 'null' + - string + country_name: + type: + - 'null' + - string + number: + type: + - 'null' + - string + type: + type: + - 'null' + - string + host_video: + type: + - 'null' + - boolean + in_meeting: + type: + - 'null' + - boolean + jbh_time: + type: + - 'null' + - number + join_before_host: + type: + - 'null' + - boolean + language_interpretation: + type: + - 'null' + - object + properties: + enable: + type: + - 'null' + - boolean + interpreters: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + email: + type: + - 'null' + - string + languages: + type: + - 'null' + - string + meeting_authentication: + type: + - 'null' + - boolean + mute_upon_entry: + type: + - 'null' + - boolean + participant_video: + type: + - 'null' + - boolean + private_meeting: + type: + - 'null' + - boolean + resources: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + resource_type: + type: + - 'null' + - string + resource_id: + type: + - 'null' + - string + permission_level: + type: + - 'null' + - string + registrants_confirmation_email: + type: + - 'null' + - boolean + registrants_email_notification: + type: + - 'null' + - boolean + registration_type: + type: + - 'null' + - number + request_permission_to_unmute_participants: + type: + - 'null' + - boolean + show_join_info: + type: + - 'null' + - boolean + show_share_button: + type: + - 'null' + - boolean + sign_language_interpretation: + type: + - 'null' + - object + additionalProperties: true + properties: + enable: + type: + - 'null' + - boolean + use_pmi: + type: + - 'null' + - boolean + waiting_room: + type: + - 'null' + - boolean + waiting_room_options: + type: + - 'null' + - object + properties: + enable: + type: + - 'null' + - boolean + admit_type: + type: + - 'null' + - number + auto_admit: + type: + - 'null' + - number + internal_user_auto_admit: + type: + - 'null' + - number + watermark: + type: + - 'null' + - boolean + host_save_video_order: + type: + - 'null' + - boolean + internal_meeting: + type: + - 'null' + - boolean + continuous_meeting_chat: + type: + - 'null' + - object + properties: + enable: + type: + - 'null' + - boolean + auto_add_invited_external_users: + type: + - 'null' + - boolean + channel_id: + type: + - 'null' + - string + participant_focused_meeting: + type: + - 'null' + - boolean + push_change_to_calendar: + type: + - 'null' + - boolean + registration_url: + type: + - 'null' + - string + resources: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + resource_type: + type: + - 'null' + - string + resource_id: + type: + - 'null' + - string + permission_level: + type: + - 'null' + - string + start_time: + type: + - 'null' + - string + start_url: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + topic: + type: + - 'null' + - string + tracking_fields: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + field: + type: + - 'null' + - string + value: + type: + - 'null' + - string + visible: + type: + - 'null' + - boolean + type: + type: + - 'null' + - number + meeting_registrants_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/meetings/{{ stream_partition.parent_id }}/registrants" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - predicate: "{{ response.code == 300 }}" + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "registrants" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/meetings" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "meetings" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "id" + partition_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: + - "meeting_id" + value: "{{ stream_partition.parent_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + meeting_id: + type: + - 'null' + - number + id: + type: + - 'null' + - string + address: + type: + - 'null' + - string + city: + type: + - 'null' + - string + comments: + type: + - 'null' + - string + country: + type: + - 'null' + - string + custom_questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + title: + type: + - 'null' + - string + value: + type: + - 'null' + - string + email: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + industry: + type: + - 'null' + - string + job_title: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + no_of_employees: + type: + - 'null' + - string + org: + type: + - 'null' + - string + phone: + type: + - 'null' + - string + purchasing_time_frame: + type: + - 'null' + - string + role_in_purchase_process: + type: + - 'null' + - string + state: + type: + - 'null' + - string + status: + type: + - 'null' + - string + zip: + type: + - 'null' + - string + create_time: + type: + - 'null' + - string + join_url: + type: + - 'null' + - string + meeting_polls_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/meetings/{{ stream_partition.parent_id }}/polls" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: + - "polls" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/meetings" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "meetings" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "id" + partition_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: + - "meeting_id" + value: "{{ stream_partition.parent_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + id: + type: + - 'null' + - string + meeting_id: + type: + - 'null' + - number + status: + type: + - 'null' + - string + anonymous: + type: + - 'null' + - boolean + poll_type: + type: + - 'null' + - number + questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + answer_max_character: + type: + - 'null' + - number + answer_min_character: + type: + - 'null' + - number + answer_required: + type: + - 'null' + - boolean + answers: + type: + - 'null' + - array + items: + type: + - 'null' + - string + case_sensitive: + type: + - 'null' + - boolean + name: + type: + - 'null' + - string + prompts: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + prompt_question: + type: + - 'null' + - string + prompt_right_answers: + type: + - 'null' + - array + items: + type: + - 'null' + - string + rating_max_label: + type: + - 'null' + - string + rating_max_value: + type: + - 'null' + - number + rating_min_label: + type: + - 'null' + - string + rating_min_value: + type: + - 'null' + - number + right_answers: + type: + - 'null' + - array + items: + type: + - 'null' + - string + show_as_dropdown: + type: + - 'null' + - boolean + type: + type: + - 'null' + - string + title: + type: + - 'null' + - string + meeting_poll_results_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/past_meetings/{{ stream_partition.parent_id }}/polls" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: + - "questions" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/meetings" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "meetings" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "id" + partition_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: + - "meeting_id" + value: "{{ stream_partition.parent_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + meeting_uuid: + type: + - 'null' + - string + meeting_id: + type: + - 'null' + - integer + email: + type: + - 'null' + - string + name: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + question_details: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + answer: + type: + - 'null' + - string + date_time: + type: + - 'null' + - string + polling_id: + type: + - 'null' + - string + question: + type: + - 'null' + - string + meeting_registration_questions_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/meetings/{{ stream_partition.parent_id }}/registrants/questions" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/meetings" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "meetings" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "id" + partition_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: + - "meeting_id" + value: "{{ stream_partition.parent_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + meeting_id: + type: + - 'null' + - integer + custom_questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + answers: + type: + - 'null' + - array + items: + type: + - 'null' + - string + required: + type: + - 'null' + - boolean + title: + type: + - 'null' + - string + type: + type: + - 'null' + - string + questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + field_name: + type: + - 'null' + - string + required: + type: + - 'null' + - boolean + webinars_list_tmp_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + webinars_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/webinars/{{ stream_partition.parent_id }}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "id" + partition_field: "parent_id" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + host_email: + type: + - 'null' + - string + host_id: + type: + - 'null' + - string + id: + type: + - 'null' + - number + uuid: + type: + - 'null' + - string + agenda: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + duration: + type: + - 'null' + - number + join_url: + type: + - 'null' + - string + occurrences: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + duration: + type: + - 'null' + - number + occurrence_id: + type: + - 'null' + - string + start_time: + type: + - 'null' + - string + status: + type: + - 'null' + - string + password: + type: + - 'null' + - string + recurrence: + type: + - 'null' + - object + properties: + end_date_time: + type: + - 'null' + - string + end_times: + type: + - 'null' + - number + monthly_day: + type: + - 'null' + - number + monthly_week: + type: + - 'null' + - number + monthly_week_day: + type: + - 'null' + - number + repeat_interval: + type: + - 'null' + - number + type: + type: + - 'null' + - number + weekly_days: + type: + - 'null' + - string + settings: + type: + - 'null' + - object + properties: + allow_multiple_devices: + type: + - 'null' + - boolean + alternative_hosts: + type: + - 'null' + - string + alternative_host_update_polls: + type: + - 'null' + - boolean + approval_type: + type: + - 'null' + - number + attendees_and_panelists_reminder_email_notification: + type: + - 'null' + - object + properties: + enable: + type: + - 'null' + - boolean + type: + type: + - 'null' + - number + audio: + type: + - 'null' + - string + authentication_domains: + type: + - 'null' + - string + authentication_name: + type: + - 'null' + - string + authentication_option: + type: + - 'null' + - string + auto_recording: + type: + - 'null' + - string + close_registration: + type: + - 'null' + - boolean + contact_email: + type: + - 'null' + - string + contact_name: + type: + - 'null' + - string + email_language: + type: + - 'null' + - string + follow_up_absentees_email_notification: + type: + - 'null' + - object + properties: + enable: + type: + - 'null' + - boolean + type: + type: + - 'null' + - number + follow_up_attendees_email_notification: + type: + - 'null' + - object + properties: + enable: + type: + - 'null' + - boolean + type: + type: + - 'null' + - number + global_dial_in_countries: + type: + - 'null' + - array + items: + type: + - 'null' + - string + hd_video: + type: + - 'null' + - boolean + hd_video_for_attendees: + type: + - 'null' + - boolean + host_video: + type: + - 'null' + - boolean + language_interpretation: + type: + - 'null' + - object + properties: + enable: + type: + - 'null' + - boolean + interpreters: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + email: + type: + - 'null' + - string + languages: + type: + - 'null' + - string + panelist_authentication: + type: + - 'null' + - boolean + meeting_authentication: + type: + - 'null' + - boolean + add_watermark: + type: + - 'null' + - boolean + add_audio_watermark: + type: + - 'null' + - boolean + notify_registrants: + type: + - 'null' + - boolean + on_demand: + type: + - 'null' + - boolean + panelists_invitation_email_notification: + type: + - 'null' + - boolean + panelists_video: + type: + - 'null' + - boolean + post_webinar_survey: + type: + - 'null' + - boolean + practice_session: + type: + - 'null' + - boolean + question_and_answer: + type: + - 'null' + - object + properties: + allow_anonymous_questions: + type: + - 'null' + - boolean + answer_questions: + type: + - 'null' + - string + attendees_can_comment: + type: + - 'null' + - boolean + attendees_can_upvote: + type: + - 'null' + - boolean + allow_auto_reply: + type: + - 'null' + - boolean + auto_reply_text: + type: + - 'null' + - string + enable: + type: + - 'null' + - boolean + registrants_confirmation_email: + type: + - 'null' + - boolean + registrants_email_notification: + type: + - 'null' + - boolean + registrants_restrict_number: + type: + - 'null' + - number + registration_type: + type: + - 'null' + - number + send_1080p_video_to_attendees: + type: + - 'null' + - boolean + show_share_button: + type: + - 'null' + - boolean + survey_url: + type: + - 'null' + - string + enable_session_branding: + type: + - 'null' + - boolean + start_time: + type: + - 'null' + - string + start_url: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + topic: + type: + - 'null' + - string + tracking_fields: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + field: + type: + - 'null' + - string + value: + type: + - 'null' + - string + type: + type: + - 'null' + - number + is_simulive: + type: + - 'null' + - boolean + record_file_id: + type: + - 'null' + - string + webinar_panelists_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/webinars/{{ stream_partition.parent_id }}/panelists" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: + - "panelists" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "id" + partition_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: + - "webinar_id" + value: "{{ stream_partition.parent_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_id: + type: + - 'null' + - number + id: + type: + - 'null' + - string + email: + type: + - 'null' + - string + name: + type: + - 'null' + - string + join_url: + type: + - 'null' + - string + virtual_background_id: + type: + - 'null' + - string + name_tag_id: + type: + - 'null' + - string + name_tag_name: + type: + - 'null' + - string + name_tag_pronouns: + type: + - 'null' + - string + name_tag_description: + type: + - 'null' + - string + webinar_registrants_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/webinars/{{ stream_partition.parent_id }}/registrants" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "registrants" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "id" + partition_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: + - "webinar_id" + value: "{{ stream_partition.parent_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_id: + type: + - 'null' + - string + id: + type: + - 'null' + - string + address: + type: + - 'null' + - string + city: + type: + - 'null' + - string + comments: + type: + - 'null' + - string + country: + type: + - 'null' + - string + custom_questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + title: + type: + - 'null' + - string + value: + type: + - 'null' + - string + email: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + industry: + type: + - 'null' + - string + job_title: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + no_of_employees: + type: + - 'null' + - string + org: + type: + - 'null' + - string + phone: + type: + - 'null' + - string + purchasing_time_frame: + type: + - 'null' + - string + role_in_purchase_process: + type: + - 'null' + - string + state: + type: + - 'null' + - string + status: + type: + - 'null' + - string + zip: + type: + - 'null' + - string + create_time: + type: + - 'null' + - string + join_url: + type: + - 'null' + - string + webinar_absentees_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/past_webinars/{{ stream_partition.parent_uuid }}/absentees" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "registrants" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "uuid" + partition_field: "parent_uuid" + transformations: + - type: AddFields + fields: + - path: + - "webinar_uuid" + value: "{{ stream_partition.parent_uuid }}" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_uuid: + type: + - 'null' + - string + id: + type: + - 'null' + - string + address: + type: + - 'null' + - string + city: + type: + - 'null' + - string + comments: + type: + - 'null' + - string + country: + type: + - 'null' + - string + custom_questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + title: + type: + - 'null' + - string + value: + type: + - 'null' + - string + email: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + industry: + type: + - 'null' + - string + job_title: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + no_of_employees: + type: + - 'null' + - string + org: + type: + - 'null' + - string + phone: + type: + - 'null' + - string + purchasing_time_frame: + type: + - 'null' + - string + role_in_purchase_process: + type: + - 'null' + - string + state: + type: + - 'null' + - string + status: + type: + - 'null' + - string + zip: + type: + - 'null' + - string + create_time: + type: + - 'null' + - string + join_url: + type: + - 'null' + - string + webinar_polls_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/webinars/{{ stream_partition.parent_id }}/polls" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: + - "polls" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "id" + partition_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: + - "webinar_id" + value: "{{ stream_partition.parent_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_id: + type: + - 'null' + - string + id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + anonymous: + type: + - 'null' + - boolean + poll_type: + type: + - 'null' + - number + questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + answer_max_character: + type: + - 'null' + - number + answer_min_character: + type: + - 'null' + - number + answer_required: + type: + - 'null' + - boolean + answers: + type: + - 'null' + - array + items: + type: + - 'null' + - string + case_sensitive: + type: + - 'null' + - boolean + name: + type: + - 'null' + - string + prompts: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + prompt_question: + type: + - 'null' + - string + prompt_right_answers: + type: + - 'null' + - array + items: + type: + - 'null' + - string + rating_max_label: + type: + - 'null' + - string + rating_max_value: + type: + - 'null' + - number + rating_min_label: + type: + - 'null' + - string + rating_min_value: + type: + - 'null' + - number + right_answers: + type: + - 'null' + - array + items: + type: + - 'null' + - string + show_as_dropdown: + type: + - 'null' + - boolean + type: + type: + - 'null' + - string + title: + type: + - 'null' + - string + webinar_poll_results_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/past_webinars/{{ stream_partition.parent_id }}/polls" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 404 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: + - "questions" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "uuid" + partition_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: + - "webinar_uuid" + value: "{{ stream_partition.parent_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_uuid: + type: + - 'null' + - string + email: + type: + - 'null' + - string + name: + type: + - 'null' + - string + question_details: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + answer: + type: + - 'null' + - string + date_time: + type: + - 'null' + - string + polling_id: + type: + - 'null' + - string + question: + type: + - 'null' + - string + webinar_registration_questions_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/webinars/{{ stream_partition.parent_id }}/registrants/questions" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "id" + partition_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: + - "webinar_id" + value: "{{ stream_partition.parent_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_id: + type: + - 'null' + - string + custom_questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + answers: + type: + - 'null' + - array + items: + type: + - 'null' + - string + required: + type: + - 'null' + - boolean + title: + type: + - 'null' + - string + type: + type: + - 'null' + - string + questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + field_name: + type: + - 'null' + - string + required: + type: + - 'null' + - boolean + webinar_tracking_sources_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/webinars/{{ stream_partition.parent_id }}/tracking_sources" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: + - "tracking_sources" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "id" + partition_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: + - "webinar_id" + value: "{{ stream_partition.parent_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_id: + type: + - 'null' + - string + id: + type: + - 'null' + - string + registration_count: + type: + - 'null' + - number + source_name: + type: + - 'null' + - string + tracking_url: + type: + - 'null' + - string + visitor_count: + type: + - 'null' + - number + webinar_qna_results_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/past_webinars/{{ stream_partition.parent_id }}/qa" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: + - "questions" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "uuid" + partition_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: + - "webinar_uuid" + value: "{{ stream_partition.parent_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_uuid: + type: + - 'null' + - string + email: + type: + - 'null' + - string + name: + type: + - 'null' + - string + question_details: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + answer: + type: + - 'null' + - string + question: + type: + - 'null' + - string + report_meetings_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/report/meetings/{{ stream_partition.parent_id }}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/meetings" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "meetings" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "id" + partition_field: "parent_id" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + meeting_uuid: + type: + - 'null' + - string + custom_keys: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + key: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + duration: + type: + - 'null' + - number + end_time: + type: + - 'null' + - string + host_id: + type: + - 'null' + - string + id: + type: + - 'null' + - number + participants_count: + type: + - 'null' + - number + start_time: + type: + - 'null' + - string + topic: + type: + - 'null' + - string + total_minutes: + type: + - 'null' + - number + tracking_fields: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + field: + type: + - 'null' + - string + value: + type: + - 'null' + - string + type: + type: + - 'null' + - number + user_email: + type: + - 'null' + - string + user_name: + type: + - 'null' + - string + uuid: + type: + - 'null' + - string + report_meeting_participants_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/report/meetings/{{ stream_partition.parent_id }}/participants" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "participants" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/meetings" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "meetings" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "id" + partition_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: + - "meeting_id" + value: "{{ stream_partition.parent_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + meeting_uuid: + type: + - 'null' + - string + meeting_id: + type: + - 'null' + - integer + customer_key: + type: + - 'null' + - string + duration: + type: + - 'null' + - number + failover: + type: + - 'null' + - boolean + id: + type: + - 'null' + - string + join_time: + type: + - 'null' + - string + leave_time: + type: + - 'null' + - string + name: + type: + - 'null' + - string + registrant_id: + type: + - 'null' + - string + user_email: + type: + - 'null' + - string + user_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + bo_mtg_id: + type: + - 'null' + - string + participant_user_id: + type: + - 'null' + - string + attentiveness_score: + type: + - 'null' + - string + report_webinars_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/report/webinars/{{ stream_partition.parent_id }}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: [] + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "uuid" + partition_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: + - "webinar_uuid" + value: "{{ stream_partition.parent_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_uuid: + type: + - 'null' + - string + custom_keys: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + key: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + duration: + type: + - 'null' + - number + end_time: + type: + - 'null' + - string + id: + type: + - 'null' + - number + participants_count: + type: + - 'null' + - number + start_time: + type: + - 'null' + - string + topic: + type: + - 'null' + - string + total_minutes: + type: + - 'null' + - number + tracking_fields: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + field: + type: + - 'null' + - string + value: + type: + - 'null' + - string + type: + type: + - 'null' + - number + user_email: + type: + - 'null' + - string + user_name: + type: + - 'null' + - string + uuid: + type: + - 'null' + - string + report_webinar_participants_stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/report/webinars/{{ stream_partition.parent_id }}/participants" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "participants" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + - type: DefaultErrorHandler + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + parent_key: "id" + partition_field: "parent_id" + parent_key: "uuid" + partition_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: + - "webinar_uuid" + value: "{{ stream_partition.parent_id }}" + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_uuid: + type: + - 'null' + - string + customer_key: + type: + - 'null' + - string + duration: + type: + - 'null' + - number + failover: + type: + - 'null' + - boolean + id: + type: + - 'null' + - string + join_time: + type: + - 'null' + - string + leave_time: + type: + - 'null' + - string + name: + type: + - 'null' + - string + registrant_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + user_email: + type: + - 'null' + - string + user_id: + type: + - 'null' + - string +streams: +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/meetings/{{ stream_partition.parent_id }}" + type: HttpRequester + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: [] + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/meetings" + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "meetings" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "meetings_list_tmp" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + assistant_id: + type: + - 'null' + - string + host_email: + type: + - 'null' + - string + host_id: + type: + - 'null' + - string + id: + type: + - 'null' + - number + uuid: + type: + - 'null' + - string + agenda: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + duration: + type: + - 'null' + - number + encrypted_password: + type: + - 'null' + - string + h323_password: + type: + - 'null' + - string + join_url: + type: + - 'null' + - string + chat_join_url: + type: + - 'null' + - string + occurrences: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + duration: + type: + - 'null' + - number + occurrence_id: + type: + - 'null' + - string + start_time: + type: + - 'null' + - string + status: + type: + - 'null' + - string + password: + type: + - 'null' + - string + pmi: + type: + - 'null' + - string + pre_schedule: + type: + - 'null' + - boolean + pstn_password: + type: + - 'null' + - string + recurrence: + type: + - 'null' + - object + properties: + end_date_time: + type: + - 'null' + - string + end_times: + type: + - 'null' + - number + monthly_day: + type: + - 'null' + - number + monthly_week: + type: + - 'null' + - number + monthly_week_day: + type: + - 'null' + - number + repeat_interval: + type: + - 'null' + - number + type: + type: + - 'null' + - number + weekly_days: + type: + - 'null' + - string + settings: + type: + - 'null' + - object + properties: + allow_multiple_devices: + type: + - 'null' + - boolean + alternative_hosts: + type: + - 'null' + - string + alternative_hosts_email_notification: + type: + - 'null' + - boolean + alternative_host_update_polls: + type: + - 'null' + - boolean + approval_type: + type: + - 'null' + - number + approved_or_denied_countries_or_regions: + type: + - 'null' + - object + properties: + approved_list: + type: + - 'null' + - array + items: + type: + - 'null' + - string + denied_list: + type: + - 'null' + - array + items: + type: + - 'null' + - string + enable: + type: + - 'null' + - boolean + method: + type: + - 'null' + - string + audio: + type: + - 'null' + - string + audio_conference_info: + type: + - 'null' + - string + authentication_domains: + type: + - 'null' + - string + authentication_exception: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + email: + type: + - 'null' + - string + name: + type: + - 'null' + - string + join_url: + type: + - 'null' + - string + authentication_name: + type: + - 'null' + - string + authentication_option: + type: + - 'null' + - string + auto_recording: + type: + - 'null' + - string + breakout_room: + type: + - 'null' + - object + properties: + enable: + type: + - 'null' + - boolean + rooms: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + name: + type: + - 'null' + - string + participants: + type: + - 'null' + - array + items: + type: + - 'null' + - string + calendar_type: + type: + - 'null' + - number + close_registration: + type: + - 'null' + - boolean + cn_meeting: + type: + - 'null' + - boolean + contact_email: + type: + - 'null' + - string + contact_name: + type: + - 'null' + - string + custom_keys: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + key: + type: + - 'null' + - string + value: + type: + - 'null' + - string + email_notification: + type: + - 'null' + - boolean + device_testing: + type: + - 'null' + - boolean + email_in_attendee_report: + type: + - 'null' + - boolean + enable_dedicated_group_chat: + type: + - 'null' + - boolean + encryption_type: + type: + - 'null' + - string + enforce_login: + type: + - 'null' + - boolean + enforce_login_domains: + type: + - 'null' + - string + focus_mode: + type: + - 'null' + - boolean + global_dial_in_countries: + type: + - 'null' + - array + items: + type: + - 'null' + - string + global_dial_in_numbers: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + city: + type: + - 'null' + - string + country: + type: + - 'null' + - string + country_name: + type: + - 'null' + - string + number: + type: + - 'null' + - string + type: + type: + - 'null' + - string + host_video: + type: + - 'null' + - boolean + in_meeting: + type: + - 'null' + - boolean + jbh_time: + type: + - 'null' + - number + join_before_host: + type: + - 'null' + - boolean + language_interpretation: + type: + - 'null' + - object + properties: + enable: + type: + - 'null' + - boolean + interpreters: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + email: + type: + - 'null' + - string + languages: + type: + - 'null' + - string + meeting_authentication: + type: + - 'null' + - boolean + mute_upon_entry: + type: + - 'null' + - boolean + participant_video: + type: + - 'null' + - boolean + private_meeting: + type: + - 'null' + - boolean + resources: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + resource_type: + type: + - 'null' + - string + resource_id: + type: + - 'null' + - string + permission_level: + type: + - 'null' + - string + registrants_confirmation_email: + type: + - 'null' + - boolean + registrants_email_notification: + type: + - 'null' + - boolean + registration_type: + type: + - 'null' + - number + request_permission_to_unmute_participants: + type: + - 'null' + - boolean + show_join_info: + type: + - 'null' + - boolean + show_share_button: + type: + - 'null' + - boolean + sign_language_interpretation: + type: + - 'null' + - object + additionalProperties: true + properties: + enable: + type: + - 'null' + - boolean + use_pmi: + type: + - 'null' + - boolean + waiting_room: + type: + - 'null' + - boolean + waiting_room_options: + type: + - 'null' + - object + properties: + enable: + type: + - 'null' + - boolean + admit_type: + type: + - 'null' + - number + auto_admit: + type: + - 'null' + - number + internal_user_auto_admit: + type: + - 'null' + - number + watermark: + type: + - 'null' + - boolean + host_save_video_order: + type: + - 'null' + - boolean + internal_meeting: + type: + - 'null' + - boolean + continuous_meeting_chat: + type: + - 'null' + - object + properties: + enable: + type: + - 'null' + - boolean + auto_add_invited_external_users: + type: + - 'null' + - boolean + channel_id: + type: + - 'null' + - string + participant_focused_meeting: + type: + - 'null' + - boolean + push_change_to_calendar: + type: + - 'null' + - boolean + registration_url: + type: + - 'null' + - string + resources: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + resource_type: + type: + - 'null' + - string + resource_id: + type: + - 'null' + - string + permission_level: + type: + - 'null' + - string + start_time: + type: + - 'null' + - string + start_url: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + topic: + type: + - 'null' + - string + tracking_fields: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + field: + type: + - 'null' + - string + value: + type: + - 'null' + - string + visible: + type: + - 'null' + - boolean + type: + type: + - 'null' + - number + type: DeclarativeStream + name: "meetings" + primary_key: "id" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/meetings/{{ stream_partition.parent_id }}/registrants" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - predicate: "{{ response.code == 300 }}" + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "registrants" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/meetings" + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "meetings" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "meetings_list_tmp" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + transformations: + - type: AddFields + fields: + - path: + - "meeting_id" + value: "{{ stream_partition.parent_id }}" + type: AddedFieldDefinition + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + meeting_id: + type: + - 'null' + - number + id: + type: + - 'null' + - string + address: + type: + - 'null' + - string + city: + type: + - 'null' + - string + comments: + type: + - 'null' + - string + country: + type: + - 'null' + - string + custom_questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + title: + type: + - 'null' + - string + value: + type: + - 'null' + - string + email: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + industry: + type: + - 'null' + - string + job_title: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + no_of_employees: + type: + - 'null' + - string + org: + type: + - 'null' + - string + phone: + type: + - 'null' + - string + purchasing_time_frame: + type: + - 'null' + - string + role_in_purchase_process: + type: + - 'null' + - string + state: + type: + - 'null' + - string + status: + type: + - 'null' + - string + zip: + type: + - 'null' + - string + create_time: + type: + - 'null' + - string + join_url: + type: + - 'null' + - string + type: DeclarativeStream + name: "meeting_registrants" + primary_key: "id" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/meetings/{{ stream_partition.parent_id }}/polls" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: + - "polls" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/meetings" + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "meetings" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "meetings_list_tmp" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + transformations: + - type: AddFields + fields: + - path: + - "meeting_id" + value: "{{ stream_partition.parent_id }}" + type: AddedFieldDefinition + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + id: + type: + - 'null' + - string + meeting_id: + type: + - 'null' + - number + status: + type: + - 'null' + - string + anonymous: + type: + - 'null' + - boolean + poll_type: + type: + - 'null' + - number + questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + answer_max_character: + type: + - 'null' + - number + answer_min_character: + type: + - 'null' + - number + answer_required: + type: + - 'null' + - boolean + answers: + type: + - 'null' + - array + items: + type: + - 'null' + - string + case_sensitive: + type: + - 'null' + - boolean + name: + type: + - 'null' + - string + prompts: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + prompt_question: + type: + - 'null' + - string + prompt_right_answers: + type: + - 'null' + - array + items: + type: + - 'null' + - string + rating_max_label: + type: + - 'null' + - string + rating_max_value: + type: + - 'null' + - number + rating_min_label: + type: + - 'null' + - string + rating_min_value: + type: + - 'null' + - number + right_answers: + type: + - 'null' + - array + items: + type: + - 'null' + - string + show_as_dropdown: + type: + - 'null' + - boolean + type: + type: + - 'null' + - string + title: + type: + - 'null' + - string + type: DeclarativeStream + name: "meeting_polls" + primary_key: "id" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/past_meetings/{{ stream_partition.parent_id }}/polls" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: + - "questions" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/meetings" + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "meetings" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "meetings_list_tmp" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + transformations: + - type: AddFields + fields: + - path: + - "meeting_id" + value: "{{ stream_partition.parent_id }}" + type: AddedFieldDefinition + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + meeting_uuid: + type: + - 'null' + - string + meeting_id: + type: + - 'null' + - integer + email: + type: + - 'null' + - string + name: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + question_details: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + answer: + type: + - 'null' + - string + date_time: + type: + - 'null' + - string + polling_id: + type: + - 'null' + - string + question: + type: + - 'null' + - string + type: DeclarativeStream + name: "meeting_poll_results" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/meetings/{{ stream_partition.parent_id }}/registrants/questions" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: [] + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/meetings" + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "meetings" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "meetings_list_tmp" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + transformations: + - type: AddFields + fields: + - path: + - "meeting_id" + value: "{{ stream_partition.parent_id }}" + type: AddedFieldDefinition + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + meeting_id: + type: + - 'null' + - integer + custom_questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + answers: + type: + - 'null' + - array + items: + type: + - 'null' + - string + required: + type: + - 'null' + - boolean + title: + type: + - 'null' + - string + type: + type: + - 'null' + - string + questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + field_name: + type: + - 'null' + - string + required: + type: + - 'null' + - boolean + type: DeclarativeStream + name: "meeting_registration_questions" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/webinars/{{ stream_partition.parent_id }}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: [] + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "webinars_list_tmp" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + host_email: + type: + - 'null' + - string + host_id: + type: + - 'null' + - string + id: + type: + - 'null' + - number + uuid: + type: + - 'null' + - string + agenda: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + duration: + type: + - 'null' + - number + join_url: + type: + - 'null' + - string + occurrences: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + duration: + type: + - 'null' + - number + occurrence_id: + type: + - 'null' + - string + start_time: + type: + - 'null' + - string + status: + type: + - 'null' + - string + password: + type: + - 'null' + - string + recurrence: + type: + - 'null' + - object + properties: + end_date_time: + type: + - 'null' + - string + end_times: + type: + - 'null' + - number + monthly_day: + type: + - 'null' + - number + monthly_week: + type: + - 'null' + - number + monthly_week_day: + type: + - 'null' + - number + repeat_interval: + type: + - 'null' + - number + type: + type: + - 'null' + - number + weekly_days: + type: + - 'null' + - string + settings: + type: + - 'null' + - object + properties: + allow_multiple_devices: + type: + - 'null' + - boolean + alternative_hosts: + type: + - 'null' + - string + alternative_host_update_polls: + type: + - 'null' + - boolean + approval_type: + type: + - 'null' + - number + attendees_and_panelists_reminder_email_notification: + type: + - 'null' + - object + properties: + enable: + type: + - 'null' + - boolean + type: + type: + - 'null' + - number + audio: + type: + - 'null' + - string + authentication_domains: + type: + - 'null' + - string + authentication_name: + type: + - 'null' + - string + authentication_option: + type: + - 'null' + - string + auto_recording: + type: + - 'null' + - string + close_registration: + type: + - 'null' + - boolean + contact_email: + type: + - 'null' + - string + contact_name: + type: + - 'null' + - string + email_language: + type: + - 'null' + - string + follow_up_absentees_email_notification: + type: + - 'null' + - object + properties: + enable: + type: + - 'null' + - boolean + type: + type: + - 'null' + - number + follow_up_attendees_email_notification: + type: + - 'null' + - object + properties: + enable: + type: + - 'null' + - boolean + type: + type: + - 'null' + - number + global_dial_in_countries: + type: + - 'null' + - array + items: + type: + - 'null' + - string + hd_video: + type: + - 'null' + - boolean + hd_video_for_attendees: + type: + - 'null' + - boolean + host_video: + type: + - 'null' + - boolean + language_interpretation: + type: + - 'null' + - object + properties: + enable: + type: + - 'null' + - boolean + interpreters: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + email: + type: + - 'null' + - string + languages: + type: + - 'null' + - string + panelist_authentication: + type: + - 'null' + - boolean + meeting_authentication: + type: + - 'null' + - boolean + add_watermark: + type: + - 'null' + - boolean + add_audio_watermark: + type: + - 'null' + - boolean + notify_registrants: + type: + - 'null' + - boolean + on_demand: + type: + - 'null' + - boolean + panelists_invitation_email_notification: + type: + - 'null' + - boolean + panelists_video: + type: + - 'null' + - boolean + post_webinar_survey: + type: + - 'null' + - boolean + practice_session: + type: + - 'null' + - boolean + question_and_answer: + type: + - 'null' + - object + properties: + allow_anonymous_questions: + type: + - 'null' + - boolean + answer_questions: + type: + - 'null' + - string + attendees_can_comment: + type: + - 'null' + - boolean + attendees_can_upvote: + type: + - 'null' + - boolean + allow_auto_reply: + type: + - 'null' + - boolean + auto_reply_text: + type: + - 'null' + - string + enable: + type: + - 'null' + - boolean + registrants_confirmation_email: + type: + - 'null' + - boolean + registrants_email_notification: + type: + - 'null' + - boolean + registrants_restrict_number: + type: + - 'null' + - number + registration_type: + type: + - 'null' + - number + send_1080p_video_to_attendees: + type: + - 'null' + - boolean + show_share_button: + type: + - 'null' + - boolean + survey_url: + type: + - 'null' + - string + enable_session_branding: + type: + - 'null' + - boolean + start_time: + type: + - 'null' + - string + start_url: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + topic: + type: + - 'null' + - string + tracking_fields: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + field: + type: + - 'null' + - string + value: + type: + - 'null' + - string + type: + type: + - 'null' + - number + is_simulive: + type: + - 'null' + - boolean + record_file_id: + type: + - 'null' + - string + type: DeclarativeStream + name: "webinars" + primary_key: "id" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/webinars/{{ stream_partition.parent_id }}/panelists" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: + - "panelists" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "webinars_list_tmp" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + transformations: + - type: AddFields + fields: + - path: + - "webinar_id" + value: "{{ stream_partition.parent_id }}" + type: AddedFieldDefinition + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_id: + type: + - 'null' + - number + id: + type: + - 'null' + - string + email: + type: + - 'null' + - string + name: + type: + - 'null' + - string + join_url: + type: + - 'null' + - string + virtual_background_id: + type: + - 'null' + - string + name_tag_id: + type: + - 'null' + - string + name_tag_name: + type: + - 'null' + - string + name_tag_pronouns: + type: + - 'null' + - string + name_tag_description: + type: + - 'null' + - string + type: DeclarativeStream + name: "webinar_panelists" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/webinars/{{ stream_partition.parent_id }}/registrants" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "registrants" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "webinars_list_tmp" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + transformations: + - type: AddFields + fields: + - path: + - "webinar_id" + value: "{{ stream_partition.parent_id }}" + type: AddedFieldDefinition + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_id: + type: + - 'null' + - string + id: + type: + - 'null' + - string + address: + type: + - 'null' + - string + city: + type: + - 'null' + - string + comments: + type: + - 'null' + - string + country: + type: + - 'null' + - string + custom_questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + title: + type: + - 'null' + - string + value: + type: + - 'null' + - string + email: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + industry: + type: + - 'null' + - string + job_title: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + no_of_employees: + type: + - 'null' + - string + org: + type: + - 'null' + - string + phone: + type: + - 'null' + - string + purchasing_time_frame: + type: + - 'null' + - string + role_in_purchase_process: + type: + - 'null' + - string + state: + type: + - 'null' + - string + status: + type: + - 'null' + - string + zip: + type: + - 'null' + - string + create_time: + type: + - 'null' + - string + join_url: + type: + - 'null' + - string + type: DeclarativeStream + name: "webinar_registrants" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/past_webinars/{{ stream_partition.parent_uuid }}/absentees" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "registrants" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "webinars_list_tmp" + primary_key: "id" + parent_key: "uuid" + partition_field: "parent_uuid" + type: ParentStreamConfig + type: SimpleRetriever + transformations: + - type: AddFields + fields: + - path: + - "webinar_uuid" + value: "{{ stream_partition.parent_uuid }}" + type: AddedFieldDefinition + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_uuid: + type: + - 'null' + - string + id: + type: + - 'null' + - string + address: + type: + - 'null' + - string + city: + type: + - 'null' + - string + comments: + type: + - 'null' + - string + country: + type: + - 'null' + - string + custom_questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + title: + type: + - 'null' + - string + value: + type: + - 'null' + - string + email: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + industry: + type: + - 'null' + - string + job_title: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + no_of_employees: + type: + - 'null' + - string + org: + type: + - 'null' + - string + phone: + type: + - 'null' + - string + purchasing_time_frame: + type: + - 'null' + - string + role_in_purchase_process: + type: + - 'null' + - string + state: + type: + - 'null' + - string + status: + type: + - 'null' + - string + zip: + type: + - 'null' + - string + create_time: + type: + - 'null' + - string + join_url: + type: + - 'null' + - string + type: DeclarativeStream + name: "webinar_absentees" + primary_key: "id" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/webinars/{{ stream_partition.parent_id }}/polls" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: + - "polls" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "webinars_list_tmp" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + transformations: + - type: AddFields + fields: + - path: + - "webinar_id" + value: "{{ stream_partition.parent_id }}" + type: AddedFieldDefinition + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_id: + type: + - 'null' + - string + id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + anonymous: + type: + - 'null' + - boolean + poll_type: + type: + - 'null' + - number + questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + answer_max_character: + type: + - 'null' + - number + answer_min_character: + type: + - 'null' + - number + answer_required: + type: + - 'null' + - boolean + answers: + type: + - 'null' + - array + items: + type: + - 'null' + - string + case_sensitive: + type: + - 'null' + - boolean + name: + type: + - 'null' + - string + prompts: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + prompt_question: + type: + - 'null' + - string + prompt_right_answers: + type: + - 'null' + - array + items: + type: + - 'null' + - string + rating_max_label: + type: + - 'null' + - string + rating_max_value: + type: + - 'null' + - number + rating_min_label: + type: + - 'null' + - string + rating_min_value: + type: + - 'null' + - number + right_answers: + type: + - 'null' + - array + items: + type: + - 'null' + - string + show_as_dropdown: + type: + - 'null' + - boolean + type: + type: + - 'null' + - string + title: + type: + - 'null' + - string + type: DeclarativeStream + name: "webinar_polls" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/past_webinars/{{ stream_partition.parent_id }}/polls" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 404 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: + - "questions" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "webinars_list_tmp" + primary_key: "id" + parent_key: "uuid" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + transformations: + - type: AddFields + fields: + - path: + - "webinar_uuid" + value: "{{ stream_partition.parent_id }}" + type: AddedFieldDefinition + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_uuid: + type: + - 'null' + - string + email: + type: + - 'null' + - string + name: + type: + - 'null' + - string + question_details: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + answer: + type: + - 'null' + - string + date_time: + type: + - 'null' + - string + polling_id: + type: + - 'null' + - string + question: + type: + - 'null' + - string + type: DeclarativeStream + name: "webinar_poll_results" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/webinars/{{ stream_partition.parent_id }}/registrants/questions" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: [] + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "webinars_list_tmp" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + transformations: + - type: AddFields + fields: + - path: + - "webinar_id" + value: "{{ stream_partition.parent_id }}" + type: AddedFieldDefinition + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_id: + type: + - 'null' + - string + custom_questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + answers: + type: + - 'null' + - array + items: + type: + - 'null' + - string + required: + type: + - 'null' + - boolean + title: + type: + - 'null' + - string + type: + type: + - 'null' + - string + questions: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + field_name: + type: + - 'null' + - string + required: + type: + - 'null' + - boolean + type: DeclarativeStream + name: "webinar_registration_questions" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/webinars/{{ stream_partition.parent_id }}/tracking_sources" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: + - "tracking_sources" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "webinars_list_tmp" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + transformations: + - type: AddFields + fields: + - path: + - "webinar_id" + value: "{{ stream_partition.parent_id }}" + type: AddedFieldDefinition + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_id: + type: + - 'null' + - string + id: + type: + - 'null' + - string + registration_count: + type: + - 'null' + - number + source_name: + type: + - 'null' + - string + tracking_url: + type: + - 'null' + - string + visitor_count: + type: + - 'null' + - number + type: DeclarativeStream + name: "webinar_tracking_sources" + primary_key: "id" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/past_webinars/{{ stream_partition.parent_id }}/qa" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: + - "questions" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "webinars_list_tmp" + primary_key: "id" + parent_key: "uuid" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + transformations: + - type: AddFields + fields: + - path: + - "webinar_uuid" + value: "{{ stream_partition.parent_id }}" + type: AddedFieldDefinition + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_uuid: + type: + - 'null' + - string + email: + type: + - 'null' + - string + name: + type: + - 'null' + - string + question_details: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + answer: + type: + - 'null' + - string + question: + type: + - 'null' + - string + type: DeclarativeStream + name: "webinar_qna_results" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/report/meetings/{{ stream_partition.parent_id }}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: [] + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/meetings" + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "meetings" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "meetings_list_tmp" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + meeting_uuid: + type: + - 'null' + - string + custom_keys: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + key: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + duration: + type: + - 'null' + - number + end_time: + type: + - 'null' + - string + host_id: + type: + - 'null' + - string + id: + type: + - 'null' + - number + participants_count: + type: + - 'null' + - number + start_time: + type: + - 'null' + - string + topic: + type: + - 'null' + - string + total_minutes: + type: + - 'null' + - number + tracking_fields: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + field: + type: + - 'null' + - string + value: + type: + - 'null' + - string + type: + type: + - 'null' + - number + user_email: + type: + - 'null' + - string + user_name: + type: + - 'null' + - string + uuid: + type: + - 'null' + - string + type: DeclarativeStream + name: "report_meetings" + primary_key: "id" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/report/meetings/{{ stream_partition.parent_id }}/participants" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + - 404 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "participants" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/meetings" + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "meetings" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "meetings_list_tmp" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + transformations: + - type: AddFields + fields: + - path: + - "meeting_id" + value: "{{ stream_partition.parent_id }}" + type: AddedFieldDefinition + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + meeting_uuid: + type: + - 'null' + - string + meeting_id: + type: + - 'null' + - integer + customer_key: + type: + - 'null' + - string + duration: + type: + - 'null' + - number + failover: + type: + - 'null' + - boolean + id: + type: + - 'null' + - string + join_time: + type: + - 'null' + - string + leave_time: + type: + - 'null' + - string + name: + type: + - 'null' + - string + registrant_id: + type: + - 'null' + - string + user_email: + type: + - 'null' + - string + user_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + bo_mtg_id: + type: + - 'null' + - string + participant_user_id: + type: + - 'null' + - string + attentiveness_score: + type: + - 'null' + - string + type: DeclarativeStream + name: "report_meeting_participants" + primary_key: "id" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/report/webinars/{{ stream_partition.parent_id }}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_path: [] + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "webinars_list_tmp" + primary_key: "id" + parent_key: "uuid" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + transformations: + - type: AddFields + fields: + - path: + - "webinar_uuid" + value: "{{ stream_partition.parent_id }}" + type: AddedFieldDefinition + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_uuid: + type: + - 'null' + - string + custom_keys: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + key: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + duration: + type: + - 'null' + - number + end_time: + type: + - 'null' + - string + id: + type: + - 'null' + - number + participants_count: + type: + - 'null' + - number + start_time: + type: + - 'null' + - string + topic: + type: + - 'null' + - string + total_minutes: + type: + - 'null' + - number + tracking_fields: + type: + - 'null' + - array + items: + type: + - 'null' + - object + properties: + field: + type: + - 'null' + - string + value: + type: + - 'null' + - string + type: + type: + - 'null' + - number + user_email: + type: + - 'null' + - string + user_name: + type: + - 'null' + - string + uuid: + type: + - 'null' + - string + type: DeclarativeStream + name: "report_webinars" +- retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/report/webinars/{{ stream_partition.parent_id }}/participants" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "participants" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] }}" + grant_type: "account_credentials" + type: CustomAuthenticator + path: "/users/{{ stream_partition.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: + - 400 + action: IGNORE + type: HttpResponseFilter + - type: DefaultErrorHandler + type: HttpRequester + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "webinars" + type: RecordSelector + partition_router: + type: SubstreamPartitionRouter + parent_stream_configs: + - stream: + retriever: + requester: + url_base: "https://api.zoom.us/v2" + http_method: "GET" + authenticator: + class_name: source_declarative_manifest.components.ServerToServerOauthAuthenticator + client_id: "{{ config['client_id'] }}" + account_id: "{{ config['account_id'] }}" + client_secret: "{{ config['client_secret'] }}" + authorization_endpoint: "{{ config['authorization_endpoint'] + }}" + grant_type: "account_credentials" + type: CustomAuthenticator + type: HttpRequester + path: "/users" + paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + type: RequestOption + page_token_option: + type: RequestOption + field_name: "next_page_token" + inject_into: "request_parameter" + record_selector: + extractor: + type: DpathExtractor + field_path: + - "users" + type: RecordSelector + type: SimpleRetriever + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + properties: + user_created_at: + type: + - 'null' + - string + created_at: + type: + - 'null' + - string + custom_attributes: + type: + - 'null' + - array + items: + type: object + properties: + key: + type: + - 'null' + - string + name: + type: + - 'null' + - string + value: + type: + - 'null' + - string + dept: + type: + - 'null' + - string + email: + type: + - 'null' + - string + employee_unique_id: + type: + - 'null' + - string + first_name: + type: + - 'null' + - string + group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + id: + type: + - 'null' + - string + im_group_ids: + type: + - 'null' + - array + items: + type: + - 'null' + - string + language: + type: + - 'null' + - string + last_client_version: + type: + - 'null' + - string + last_login_time: + type: + - 'null' + - string + last_name: + type: + - 'null' + - string + phone_number: + type: + - 'null' + - string + plan_united_type: + type: + - 'null' + - string + pmi: + type: + - 'null' + - number + role_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + timezone: + type: + - 'null' + - string + type: + type: + - 'null' + - number + verified: + type: + - 'null' + - number + display_name: + type: + - 'null' + - string + type: DeclarativeStream + name: "users" + primary_key: "id" + parent_key: "id" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + type: DeclarativeStream + name: "webinars_list_tmp" + primary_key: "id" + parent_key: "uuid" + partition_field: "parent_id" + type: ParentStreamConfig + type: SimpleRetriever + transformations: + - type: AddFields + fields: + - path: + - "webinar_uuid" + value: "{{ stream_partition.parent_id }}" + type: AddedFieldDefinition + schema_loader: + type: InlineSchemaLoader + schema: + $schema: http://json-schema.org/draft-07/schema# + type: object + properties: + webinar_uuid: + type: + - 'null' + - string + customer_key: + type: + - 'null' + - string + duration: + type: + - 'null' + - number + failover: + type: + - 'null' + - boolean + id: + type: + - 'null' + - string + join_time: + type: + - 'null' + - string + leave_time: + type: + - 'null' + - string + name: + type: + - 'null' + - string + registrant_id: + type: + - 'null' + - string + status: + type: + - 'null' + - string + user_email: + type: + - 'null' + - string + user_id: + type: + - 'null' + - string + type: DeclarativeStream + name: "report_webinar_participants" +check: + stream_names: + - "users" + type: CheckStream +type: DeclarativeSource +spec: + type: Spec + documentation_url: https://docs.airbyte.com/integrations/sources/zoom + connection_specification: + $schema: http://json-schema.org/draft-07/schema# + title: Zoom Spec + type: object + required: + - account_id + - client_id + - client_secret + - authorization_endpoint + additionalProperties: true + properties: + account_id: + type: string + order: 0 + description: 'The account ID for your Zoom account. You can find this in the + Zoom Marketplace under the "Manage" tab for your app.' + client_id: + type: string + order: 1 + description: 'The client ID for your Zoom app. You can find this in the Zoom + Marketplace under the "Manage" tab for your app.' + client_secret: + type: string + order: 2 + description: 'The client secret for your Zoom app. You can find this in the + Zoom Marketplace under the "Manage" tab for your app.' + airbyte_secret: true + authorization_endpoint: + type: string + order: 3 + default: "https://zoom.us/oauth/token" diff --git a/airbyte-integrations/connectors/source-zoom/metadata.yaml b/airbyte-integrations/connectors/source-zoom/metadata.yaml index 91392850bfd6..299508b35107 100644 --- a/airbyte-integrations/connectors/source-zoom/metadata.yaml +++ b/airbyte-integrations/connectors/source-zoom/metadata.yaml @@ -3,11 +3,11 @@ data: ql: 200 sl: 100 connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:2.0.0@sha256:c44839ba84406116e8ba68722a0f30e8f6e7056c726f447681bb9e9ece8bd916 + baseImage: docker.io/airbyte/source-declarative-manifest:6.12.4@sha256:b73460101d4ff373826b56f00ef2012b635f5eab04c429892547dd055cd779dc connectorSubtype: api connectorType: source definitionId: cbfd9856-1322-44fb-bcf1-0b39b7a8e92e - dockerImageTag: 1.1.22 + dockerImageTag: 1.2.3 dockerRepository: airbyte/source-zoom documentationUrl: https://docs.airbyte.com/integrations/sources/zoom githubIssueLabel: source-zoom @@ -23,19 +23,22 @@ data: releases: breakingChanges: 1.1.0: - message: Zoom has deprecated JWT authentication in favor of OAuth. To successfully migrate, users will need to create a new server-to-server OAuth app and update their credentials in the Airbyte UI. + message: + Zoom has deprecated JWT authentication in favor of OAuth. To successfully + migrate, users will need to create a new server-to-server OAuth app and + update their credentials in the Airbyte UI. upgradeDeadline: 2023-09-08 scopedImpact: - scopeType: stream impactedScopes: ["meeting_registration_questions"] remoteRegistries: pypi: - enabled: true + enabled: false packageName: airbyte-source-zoom supportLevel: community tags: - - language:python - cdk:low-code + - language:manifest-only connectorTestSuitesOptions: - suite: liveTests testConnections: diff --git a/airbyte-integrations/connectors/source-zoom/poetry.lock b/airbyte-integrations/connectors/source-zoom/poetry.lock deleted file mode 100644 index cb16738a481e..000000000000 --- a/airbyte-integrations/connectors/source-zoom/poetry.lock +++ /dev/null @@ -1,1066 +0,0 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. - -[[package]] -name = "airbyte-cdk" -version = "0.67.3" -description = "A framework for writing Airbyte Connectors." -optional = false -python-versions = ">=3.8" -files = [ - {file = "airbyte-cdk-0.67.3.tar.gz", hash = "sha256:ef242cf2bc461e6790811d0cd64e87aa47559af942cd0cc70b09d4f860831ce1"}, - {file = "airbyte_cdk-0.67.3-py3-none-any.whl", hash = "sha256:de2353430180bdbc852f336745c95506908dda67a2d4949fb538401d3c7fa40a"}, -] - -[package.dependencies] -airbyte-protocol-models = "0.5.1" -backoff = "*" -cachetools = "*" -Deprecated = ">=1.2,<2.0" -dpath = ">=2.0.1,<2.1.0" -genson = "1.2.2" -isodate = ">=0.6.1,<0.7.0" -Jinja2 = ">=3.1.2,<3.2.0" -jsonref = ">=0.2,<1.0" -jsonschema = ">=3.2.0,<3.3.0" -pendulum = "<3.0.0" -pydantic = ">=1.10.8,<2.0.0" -pyrate-limiter = ">=3.1.0,<3.2.0" -python-dateutil = "*" -PyYAML = ">=6.0.1" -requests = "*" -requests-cache = "*" -wcmatch = "8.4" - -[package.extras] -dev = ["avro (>=1.11.2,<1.12.0)", "cohere (==4.21)", "fastavro (>=1.8.0,<1.9.0)", "freezegun", "langchain (==0.0.271)", "markdown", "mypy", "openai[embeddings] (==0.27.9)", "pandas (==2.0.3)", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "pytest", "pytest-cov", "pytest-httpserver", "pytest-mock", "requests-mock", "tiktoken (==0.4.0)", "unstructured (==0.10.27)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured (==0.10.27)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<5.0)", "sphinx-rtd-theme (>=1.0,<2.0)"] -vector-db-based = ["cohere (==4.21)", "langchain (==0.0.271)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] - -[[package]] -name = "airbyte-protocol-models" -version = "0.5.1" -description = "Declares the Airbyte Protocol." -optional = false -python-versions = ">=3.8" -files = [ - {file = "airbyte_protocol_models-0.5.1-py3-none-any.whl", hash = "sha256:dfe84e130e51ce2ae81a06d5aa36f6c5ce3152b9e36e6f0195fad6c3dab0927e"}, - {file = "airbyte_protocol_models-0.5.1.tar.gz", hash = "sha256:7c8b16c7c1c7956b1996052e40585a3a93b1e44cb509c4e97c1ee4fe507ea086"}, -] - -[package.dependencies] -pydantic = ">=1.9.2,<2.0.0" - -[[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, -] - -[[package]] -name = "attrs" -version = "24.2.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" -files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, -] - -[package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] - -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "bracex" -version = "2.5.post1" -description = "Bash style brace expander." -optional = false -python-versions = ">=3.8" -files = [ - {file = "bracex-2.5.post1-py3-none-any.whl", hash = "sha256:13e5732fec27828d6af308628285ad358047cec36801598368cb28bc631dbaf6"}, - {file = "bracex-2.5.post1.tar.gz", hash = "sha256:12c50952415bfa773d2d9ccb8e79651b8cdb1f31a42f6091b804f6ba2b4a66b6"}, -] - -[[package]] -name = "cachetools" -version = "5.5.0" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, - {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, -] - -[[package]] -name = "cattrs" -version = "24.1.2" -description = "Composable complex class support for attrs and dataclasses." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0"}, - {file = "cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85"}, -] - -[package.dependencies] -attrs = ">=23.1.0" -exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} - -[package.extras] -bson = ["pymongo (>=4.4.0)"] -cbor2 = ["cbor2 (>=5.4.6)"] -msgpack = ["msgpack (>=1.0.5)"] -msgspec = ["msgspec (>=0.18.5)"] -orjson = ["orjson (>=3.9.2)"] -pyyaml = ["pyyaml (>=6.0)"] -tomlkit = ["tomlkit (>=0.11.8)"] -ujson = ["ujson (>=5.7.0)"] - -[[package]] -name = "certifi" -version = "2024.8.30" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.0" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -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 = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - -[[package]] -name = "dpath" -version = "2.0.8" -description = "Filesystem-like pathing and searching for dictionaries" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dpath-2.0.8-py3-none-any.whl", hash = "sha256:f92f595214dd93a00558d75d4b858beee519f4cffca87f02616ad6cd013f3436"}, - {file = "dpath-2.0.8.tar.gz", hash = "sha256:a3440157ebe80d0a3ad794f1b61c571bef125214800ffdb9afc9424e8250fe9b"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "genson" -version = "1.2.2" -description = "GenSON is a powerful, user-friendly JSON Schema generator." -optional = false -python-versions = "*" -files = [ - {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, -] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isodate" -version = "0.6.1" -description = "An ISO 8601 date/time/duration parser and formatter" -optional = false -python-versions = "*" -files = [ - {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, - {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "jinja2" -version = "3.1.4" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "jsonref" -version = "0.3.0" -description = "jsonref is a library for automatic dereferencing of JSON Reference objects for Python." -optional = false -python-versions = ">=3.3,<4.0" -files = [ - {file = "jsonref-0.3.0-py3-none-any.whl", hash = "sha256:9480ad1b500f7e795daeb0ef29f9c55ae3a9ab38fb8d6659b6f4868acb5a5bc8"}, - {file = "jsonref-0.3.0.tar.gz", hash = "sha256:68b330c6815dc0d490dbb3d65ccda265ddde9f7856fd2f3322f971d456ea7549"}, -] - -[[package]] -name = "jsonschema" -version = "3.2.0" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = "*" -files = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, -] - -[package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" - -[package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] - -[[package]] -name = "markupsafe" -version = "3.0.2" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -files = [ - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, - {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-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, -] - -[[package]] -name = "packaging" -version = "24.1" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, -] - -[[package]] -name = "pendulum" -version = "2.1.2" -description = "Python datetimes made easy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, - {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, - {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, - {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, - {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, - {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, - {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, - {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, - {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, - {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, - {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, -] - -[package.dependencies] -python-dateutil = ">=2.6,<3.0" -pytzdata = ">=2020.1" - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] - -[[package]] -name = "pydantic" -version = "1.10.18" -description = "Data validation and settings management using python type hints" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, -] - -[package.dependencies] -typing-extensions = ">=4.2.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] - -[[package]] -name = "pyrate-limiter" -version = "3.1.1" -description = "Python Rate-Limiter using Leaky-Bucket Algorithm" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, - {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, -] - -[package.extras] -all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] -docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] - -[[package]] -name = "pyrsistent" -version = "0.20.0" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34"}, - {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f"}, - {file = "pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7"}, - {file = "pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a"}, - {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656"}, - {file = "pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee"}, - {file = "pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3"}, - {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174"}, - {file = "pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d"}, - {file = "pyrsistent-0.20.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714"}, - {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win32.whl", hash = "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423"}, - {file = "pyrsistent-0.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d"}, - {file = "pyrsistent-0.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022"}, - {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win32.whl", hash = "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f"}, - {file = "pyrsistent-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf"}, - {file = "pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b"}, - {file = "pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4"}, -] - -[[package]] -name = "pytest" -version = "6.2.5" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, -] - -[package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] - -[[package]] -name = "pytest-mock" -version = "3.14.0" -description = "Thin-wrapper around the mock package for easier use with pytest" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, - {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, -] - -[package.dependencies] -pytest = ">=6.2.5" - -[package.extras] -dev = ["pre-commit", "pytest-asyncio", "tox"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytzdata" -version = "2020.1" -description = "The Olson timezone database for Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, - {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-cache" -version = "1.2.1" -description = "A persistent cache for python requests" -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, - {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, -] - -[package.dependencies] -attrs = ">=21.2" -cattrs = ">=22.2" -platformdirs = ">=2.5" -requests = ">=2.22" -url-normalize = ">=1.4" -urllib3 = ">=1.25.5" - -[package.extras] -all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] -bson = ["bson (>=0.5)"] -docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] -dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] -json = ["ujson (>=5.4)"] -mongodb = ["pymongo (>=3)"] -redis = ["redis (>=3)"] -security = ["itsdangerous (>=2.0)"] -yaml = ["pyyaml (>=6.0.1)"] - -[[package]] -name = "requests-mock" -version = "1.12.1" -description = "Mock out responses from the requests package" -optional = false -python-versions = ">=3.5" -files = [ - {file = "requests-mock-1.12.1.tar.gz", hash = "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401"}, - {file = "requests_mock-1.12.1-py2.py3-none-any.whl", hash = "sha256:b1e37054004cdd5e56c84454cc7df12b25f90f382159087f4b6915aaeef39563"}, -] - -[package.dependencies] -requests = ">=2.22,<3" - -[package.extras] -fixture = ["fixtures"] - -[[package]] -name = "setuptools" -version = "75.3.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd"}, - {file = "setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] -core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.12.*)", "pytest-mypy"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "url-normalize" -version = "1.4.3" -description = "URL normalization for Python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, - {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "urllib3" -version = "2.2.3" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "wcmatch" -version = "8.4" -description = "Wildcard/glob file name matcher." -optional = false -python-versions = ">=3.7" -files = [ - {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, - {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, -] - -[package.dependencies] -bracex = ">=2.1.1" - -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "64656b30b207f0f046c259a3688f501d0e4de944131c28d2ec60e06ff7efd57e" diff --git a/airbyte-integrations/connectors/source-zoom/pyproject.toml b/airbyte-integrations/connectors/source-zoom/pyproject.toml deleted file mode 100644 index 1649620043d0..000000000000 --- a/airbyte-integrations/connectors/source-zoom/pyproject.toml +++ /dev/null @@ -1,28 +0,0 @@ -[build-system] -requires = [ "poetry-core>=1.0.0",] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -version = "1.1.22" -name = "source-zoom" -description = "Source implementation for Zoom." -authors = [ "Airbyte ",] -license = "MIT" -readme = "README.md" -documentation = "https://docs.airbyte.com/integrations/sources/zoom" -homepage = "https://airbyte.com" -repository = "https://github.com/airbytehq/airbyte" -[[tool.poetry.packages]] -include = "source_zoom" - -[tool.poetry.dependencies] -python = "^3.9,<3.12" -airbyte-cdk = "^0.67.1" - -[tool.poetry.scripts] -source-zoom = "source_zoom.run:run" - -[tool.poetry.group.dev.dependencies] -requests-mock = "^1.9.3" -pytest-mock = "^3.6.1" -pytest = "^6.1" diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/__init__.py b/airbyte-integrations/connectors/source-zoom/source_zoom/__init__.py deleted file mode 100644 index 5d5733ca7209..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -from .source import SourceZoom - -__all__ = ["SourceZoom"] diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/components.py b/airbyte-integrations/connectors/source-zoom/source_zoom/components.py deleted file mode 100644 index 00214c737833..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/components.py +++ /dev/null @@ -1,85 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import base64 -import time -from dataclasses import dataclass -from http import HTTPStatus -from typing import Any, Mapping, Optional, Union - -import requests -from airbyte_cdk.sources.declarative.auth.declarative_authenticator import NoAuth -from airbyte_cdk.sources.declarative.interpolation import InterpolatedString -from airbyte_cdk.sources.declarative.types import Config -from requests import HTTPError - -# https://developers.zoom.us/docs/internal-apps/s2s-oauth/#successful-response -# The Bearer token generated by server-to-server token will expire in one hour -BEARER_TOKEN_EXPIRES_IN = 3590 - - -class SingletonMeta(type): - _instances = {} - - def __call__(cls, *args, **kwargs): - """ - Possible changes to the value of the `__init__` argument do not affect - the returned instance. - """ - if cls not in cls._instances: - instance = super().__call__(*args, **kwargs) - cls._instances[cls] = instance - return cls._instances[cls] - - -@dataclass -class ServerToServerOauthAuthenticator(NoAuth): - config: Config - account_id: Union[InterpolatedString, str] - client_id: Union[InterpolatedString, str] - client_secret: Union[InterpolatedString, str] - authorization_endpoint: Union[InterpolatedString, str] - - _instance = None - _generate_token_time = 0 - _access_token = None - _grant_type = "account_credentials" - - def __post_init__(self, parameters: Mapping[str, Any]): - self._account_id = InterpolatedString.create(self.account_id, parameters=parameters).eval(self.config) - self._client_id = InterpolatedString.create(self.client_id, parameters=parameters).eval(self.config) - self._client_secret = InterpolatedString.create(self.client_secret, parameters=parameters).eval(self.config) - self._authorization_endpoint = InterpolatedString.create(self.authorization_endpoint, parameters=parameters).eval(self.config) - - def __call__(self, request: requests.PreparedRequest) -> requests.PreparedRequest: - """Attach the page access token to params to authenticate on the HTTP request""" - if self._access_token is None or ((time.time() - self._generate_token_time) > BEARER_TOKEN_EXPIRES_IN): - self._generate_token_time = time.time() - self._access_token = self.generate_access_token() - headers = {"Authorization": f"Bearer {self._access_token}", "Content-type": "application/json"} - request.headers.update(headers) - - return request - - @property - def auth_header(self) -> str: - return "Authorization" - - @property - def token(self) -> Optional[str]: - return self._access_token if self._access_token else None - - def generate_access_token(self) -> str: - self._generate_token_time = time.time() - try: - token = base64.b64encode(f"{self._client_id}:{self._client_secret}".encode("ascii")).decode("utf-8") - headers = {"Authorization": f"Basic {token}", "Content-type": "application/json"} - rest = requests.post( - url=f"{self._authorization_endpoint}?grant_type={self._grant_type}&account_id={self._account_id}", headers=headers - ) - if rest.status_code != HTTPStatus.OK: - raise HTTPError(rest.text) - return rest.json().get("access_token") - except Exception as e: - raise Exception(f"Error while generating access token: {e}") from e diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/manifest.yaml b/airbyte-integrations/connectors/source-zoom/source_zoom/manifest.yaml deleted file mode 100644 index 808f4405e78f..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/manifest.yaml +++ /dev/null @@ -1,795 +0,0 @@ -version: 0.67.1 - -definitions: - # Server to Server Oauth Authenticator - requester: - url_base: "https://api.zoom.us/v2" - http_method: "GET" - authenticator: - class_name: source_zoom.components.ServerToServerOauthAuthenticator - client_id: "{{ config['client_id'] }}" - account_id: "{{ config['account_id'] }}" - client_secret: "{{ config['client_secret'] }}" - authorization_endpoint: "{{ config['authorization_endpoint'] }}" - grant_type: "account_credentials" - - zoom_paginator: - type: DefaultPaginator - pagination_strategy: - type: "CursorPagination" - cursor_value: "{{ response.next_page_token }}" - stop_condition: "{{ response.next_page_token == '' }}" - page_size: 30 - page_size_option: - field_name: "page_size" - inject_into: "request_parameter" - page_token_option: - type: RequestOption - field_name: "next_page_token" - inject_into: "request_parameter" - - retriever: - requester: - $ref: "#/definitions/requester" - - schema_loader: - type: JsonFileSchemaLoader - file_path: "./source_zoom/schemas/{{ parameters['name'] }}.json" - - users_stream: - # Endpoint docs: https://developers.zoom.us/docs/api/rest/reference/user/methods/#operation/users - schema_loader: - $ref: "#/definitions/schema_loader" - retriever: - paginator: - $ref: "#/definitions/zoom_paginator" - record_selector: - extractor: - type: DpathExtractor - field_path: ["users"] - $ref: "#/definitions/retriever" - $parameters: - name: "users" - primary_key: "id" - path: "/users" - - meetings_list_tmp_stream: - # This stream is used to fetch parent_ids for the meetings stream and all its substreams. No data is synced from this stream. - # Endpoint docs: https://developers.zoom.us/docs/api/rest/reference/zoom-api/methods/#operation/meetings - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "meetings_list_tmp" - primary_key: "id" - retriever: - paginator: - $ref: "#/definitions/zoom_paginator" - record_selector: - extractor: - type: DpathExtractor - field_path: ["meetings"] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/users/{{ stream_partition.parent_id }}/meetings" - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/users_stream" - parent_key: "id" - partition_field: "parent_id" - - meetings_stream: - # Endpoint docs: https://developers.zoom.us/docs/api/rest/reference/zoom-api/methods/#operation/meeting - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "meetings" - primary_key: "id" - retriever: - paginator: - type: NoPagination - record_selector: - extractor: - type: DpathExtractor - field_path: [] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/meetings/{{ stream_partition.parent_id }}" - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/meetings_list_tmp_stream" - parent_key: "id" - partition_field: "parent_id" - - meeting_registrants_stream: - # Endpoint docs: https://developers.zoom.us/docs/api/rest/reference/zoom-api/methods/#operation/meetingRegistrants - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "meeting_registrants" - primary_key: "id" - retriever: - paginator: - $ref: "#/definitions/zoom_paginator" - record_selector: - extractor: - type: DpathExtractor - field_path: ["registrants"] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/meetings/{{ stream_partition.parent_id }}/registrants" - error_handler: - type: CompositeErrorHandler - error_handlers: - - type: DefaultErrorHandler - response_filters: - # Meeting {meetingId} is not found or has expired. This meeting has not set registration as required: {meetingId}. - - predicate: "{{ response.code == 300 }}" - action: IGNORE - - type: DefaultErrorHandler # we're adding this DefaultErrorHandler for 429, 5XX errors etc; - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/meetings_list_tmp_stream" - parent_key: "id" - partition_field: "parent_id" - transformations: - - type: AddFields - fields: - - path: ["meeting_id"] - value: "{{ stream_partition.parent_id }}" - - meeting_polls_stream: - # Endpoint docs: https://developers.zoom.us/docs/api/rest/reference/zoom-api/methods/#operation/meetingPolls - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "meeting_polls" - primary_key: "id" - retriever: - paginator: - type: NoPagination - record_selector: - extractor: - type: DpathExtractor - field_path: ["polls"] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/meetings/{{ stream_partition.parent_id }}/polls" - error_handler: - type: CompositeErrorHandler - # ignore 400 error; We get this error if Meeting poll is not enabled for the meeting, or scheduling capabilities aren't in the account - error_handlers: - - type: DefaultErrorHandler - response_filters: - - http_codes: [400] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/meetings_list_tmp_stream" - parent_key: "id" - partition_field: "parent_id" - transformations: - - type: AddFields - fields: - - path: ["meeting_id"] - value: "{{ stream_partition.parent_id }}" - - meeting_poll_results_stream: - # Endpoint docs: https://developers.zoom.us/docs/api/rest/reference/zoom-api/methods/#operation/listPastMeetingPolls - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "meeting_poll_results" - retriever: - paginator: - type: NoPagination - record_selector: - extractor: - type: DpathExtractor - field_path: ["questions"] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/past_meetings/{{ stream_partition.parent_id }}/polls" - error_handler: - type: CompositeErrorHandler - error_handlers: - - type: DefaultErrorHandler - response_filters: - # 400 error is thrown for meetings created an year ago - # 404 error is thrown if the meeting has not enabled polls (from observation, not written in docs) - - http_codes: [400, 404] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/meetings_list_tmp_stream" - parent_key: "id" - partition_field: "parent_id" - transformations: - - type: AddFields - fields: - - path: ["meeting_id"] - value: "{{ stream_partition.parent_id }}" - - meeting_registration_questions_stream: - # Endpoint docs: https://developers.zoom.us/docs/api/rest/reference/zoom-api/methods/#operation/meetingRegistrantsQuestionsGet - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "meeting_registration_questions" - retriever: - paginator: - type: NoPagination - record_selector: - extractor: - type: DpathExtractor - field_path: [] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/meetings/{{ stream_partition.parent_id }}/registrants/questions" - error_handler: - type: CompositeErrorHandler - error_handlers: - - type: DefaultErrorHandler - response_filters: - # ignore 400 error; We get this error if Bad Request or Meeting hosting and scheduling capabilities are not allowed for your user account. - - http_codes: [400] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/meetings_list_tmp_stream" - parent_key: "id" - partition_field: "parent_id" - transformations: - - type: AddFields - fields: - - path: ["meeting_id"] - value: "{{ stream_partition.parent_id }}" - - webinars_list_tmp_stream: - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "webinars_list_tmp" - primary_key: "id" - retriever: - paginator: - $ref: "#/definitions/zoom_paginator" - record_selector: - extractor: - type: DpathExtractor - field_path: ["webinars"] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/users/{{ stream_partition.parent_id }}/webinars" - error_handler: - type: CompositeErrorHandler - # ignore 400 error; We get this error if Meeting is more than created an year ago - error_handlers: - - type: DefaultErrorHandler - response_filters: - - http_codes: [400] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/users_stream" - parent_key: "id" - partition_field: "parent_id" - - webinars_stream: - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "webinars" - primary_key: "id" - retriever: - paginator: - type: NoPagination - record_selector: - extractor: - type: DpathExtractor - field_path: [] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/webinars/{{ stream_partition.parent_id }}" - error_handler: - type: CompositeErrorHandler - # ignore 400 error - error_handlers: - - type: DefaultErrorHandler - response_filters: - # When parent stream throws error; then ideally we should have an empty array, and no /webinars/{id} should be called. But somehow we're calling it right now with None. :( - # More context: https://github.com/airbytehq/airbyte/issues/18046 - - http_codes: [400, 404] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/webinars_list_tmp_stream" - parent_key: "id" - partition_field: "parent_id" - - webinar_panelists_stream: - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "webinar_panelists" - retriever: - paginator: - type: NoPagination - record_selector: - extractor: - type: DpathExtractor - field_path: ["panelists"] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/webinars/{{ stream_partition.parent_id }}/panelists" - error_handler: - type: CompositeErrorHandler - # ignore 400 error - error_handlers: - - type: DefaultErrorHandler - response_filters: - # Same problem as "webinars_stream" for 404! and we get 400 error if the account isn't PRO. - - http_codes: [400, 404] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/webinars_list_tmp_stream" - parent_key: "id" - partition_field: "parent_id" - transformations: - - type: AddFields - fields: - - path: ["webinar_id"] - value: "{{ stream_partition.parent_id }}" - - webinar_registrants_stream: - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "webinar_registrants" - retriever: - paginator: - $ref: "#/definitions/zoom_paginator" - record_selector: - extractor: - type: DpathExtractor - field_path: ["registrants"] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/webinars/{{ stream_partition.parent_id }}/registrants" - error_handler: - type: CompositeErrorHandler - # ignore 400 error - error_handlers: - - type: DefaultErrorHandler - response_filters: - # Same problem as "webinars_stream" for 404! 400 is for non PRO accounts. - - http_codes: [400, 404] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/webinars_list_tmp_stream" - parent_key: "id" - partition_field: "parent_id" - transformations: - - type: AddFields - fields: - - path: ["webinar_id"] - value: "{{ stream_partition.parent_id }}" - - webinar_absentees_stream: - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "webinar_absentees" - primary_key: "id" - retriever: - paginator: - $ref: "#/definitions/zoom_paginator" - record_selector: - extractor: - type: DpathExtractor - field_path: ["registrants"] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/past_webinars/{{ stream_partition.parent_uuid }}/absentees" - error_handler: - type: CompositeErrorHandler - # ignore 400 error - error_handlers: - - type: DefaultErrorHandler - response_filters: - # Same problem as "webinars_stream" for 404! 400 is for non PRO accounts. - - http_codes: [400, 404] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/webinars_list_tmp_stream" - parent_key: "uuid" - partition_field: "parent_uuid" - transformations: - - type: AddFields - fields: - - path: ["webinar_uuid"] - value: "{{ stream_partition.parent_uuid }}" - - webinar_polls_stream: - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "webinar_polls" - retriever: - paginator: - type: NoPagination - record_selector: - extractor: - type: DpathExtractor - field_path: ["polls"] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/webinars/{{ stream_partition.parent_id }}/polls" - error_handler: - type: CompositeErrorHandler - # ignore 400 error; We get this error if Webinar poll is disabled - error_handlers: - - type: DefaultErrorHandler - response_filters: - # Same problem as "webinars_stream" for 404! 400 is for non PRO accounts. - - http_codes: [400, 404] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/webinars_list_tmp_stream" - parent_key: "id" - partition_field: "parent_id" - transformations: - - type: AddFields - fields: - - path: ["webinar_id"] - value: "{{ stream_partition.parent_id }}" - - webinar_poll_results_stream: - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "webinar_poll_results" - retriever: - paginator: - type: NoPagination - record_selector: - extractor: - type: DpathExtractor - field_path: ["questions"] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/past_webinars/{{ stream_partition.parent_id }}/polls" - error_handler: - type: CompositeErrorHandler - error_handlers: - - type: DefaultErrorHandler - response_filters: - - http_codes: [404] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/webinars_list_tmp_stream" - parent_key: "uuid" - partition_field: "parent_id" - transformations: - - type: AddFields - fields: - - path: ["webinar_uuid"] - value: "{{ stream_partition.parent_id }}" - - webinar_registration_questions_stream: - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "webinar_registration_questions" - retriever: - paginator: - type: NoPagination - record_selector: - extractor: - type: DpathExtractor - field_path: [] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/webinars/{{ stream_partition.parent_id }}/registrants/questions" - error_handler: - type: CompositeErrorHandler - error_handlers: - - type: DefaultErrorHandler - response_filters: - # the docs says 404 code, but that's incorrect (from observation); - - http_codes: [400] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/webinars_list_tmp_stream" - parent_key: "id" - partition_field: "parent_id" - transformations: - - type: AddFields - fields: - - path: ["webinar_id"] - value: "{{ stream_partition.parent_id }}" - - webinar_tracking_sources_stream: - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "webinar_tracking_sources" - primary_key: "id" - retriever: - paginator: - type: NoPagination - record_selector: - extractor: - type: DpathExtractor - field_path: ["tracking_sources"] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/webinars/{{ stream_partition.parent_id }}/tracking_sources" - error_handler: - type: CompositeErrorHandler - error_handlers: - - type: DefaultErrorHandler - response_filters: - - http_codes: [400] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/webinars_list_tmp_stream" - parent_key: "id" - partition_field: "parent_id" - transformations: - - type: AddFields - fields: - - path: ["webinar_id"] - value: "{{ stream_partition.parent_id }}" - - webinar_qna_results_stream: - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "webinar_qna_results" - retriever: - paginator: - type: NoPagination - record_selector: - extractor: - type: DpathExtractor - field_path: ["questions"] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/past_webinars/{{ stream_partition.parent_id }}/qa" - error_handler: - type: CompositeErrorHandler - error_handlers: - - type: DefaultErrorHandler - response_filters: - - http_codes: [400, 404] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/webinars_list_tmp_stream" - parent_key: "uuid" - partition_field: "parent_id" - transformations: - - type: AddFields - fields: - - path: ["webinar_uuid"] - value: "{{ stream_partition.parent_id }}" - - report_meetings_stream: - # Endpoint docs: https://developers.zoom.us/docs/api/rest/reference/zoom-api/methods/#operation/reportMeetingDetails - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "report_meetings" - primary_key: "id" - retriever: - paginator: - type: NoPagination - record_selector: - extractor: - type: DpathExtractor - field_path: [] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/report/meetings/{{ stream_partition.parent_id }}" - error_handler: - type: CompositeErrorHandler - error_handlers: - - type: DefaultErrorHandler - response_filters: - - http_codes: [400, 404] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/meetings_list_tmp_stream" - parent_key: "id" - partition_field: "parent_id" - - report_meeting_participants_stream: - # Endpoint docs: https://developers.zoom.us/docs/api/rest/reference/zoom-api/methods/#operation/reportMeetingParticipants - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "report_meeting_participants" - primary_key: "id" - retriever: - paginator: - $ref: "#/definitions/zoom_paginator" - record_selector: - extractor: - type: DpathExtractor - field_path: ["participants"] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/report/meetings/{{ stream_partition.parent_id }}/participants" - error_handler: - type: CompositeErrorHandler - error_handlers: - - type: DefaultErrorHandler - response_filters: - - http_codes: [400, 404] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/meetings_list_tmp_stream" - parent_key: "id" - partition_field: "parent_id" - transformations: - - type: AddFields - fields: - - path: ["meeting_id"] - value: "{{ stream_partition.parent_id }}" - - report_webinars_stream: - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "report_webinars" - retriever: - paginator: - type: NoPagination - record_selector: - extractor: - type: DpathExtractor - field_path: [] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/report/webinars/{{ stream_partition.parent_id }}" - error_handler: - type: CompositeErrorHandler - error_handlers: - - type: DefaultErrorHandler - response_filters: - - http_codes: [400] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/webinars_list_tmp_stream" - parent_key: "uuid" - partition_field: "parent_id" - transformations: - - type: AddFields - fields: - - path: ["webinar_uuid"] - value: "{{ stream_partition.parent_id }}" - - report_webinar_participants_stream: - schema_loader: - $ref: "#/definitions/schema_loader" - $parameters: - name: "report_webinar_participants" - retriever: - paginator: - $ref: "#/definitions/zoom_paginator" - record_selector: - extractor: - type: DpathExtractor - field_path: ["participants"] - $ref: "#/definitions/retriever" - requester: - $ref: "#/definitions/requester" - path: "/report/webinars/{{ stream_partition.parent_id }}/participants" - error_handler: - type: CompositeErrorHandler - error_handlers: - - type: DefaultErrorHandler - response_filters: - - http_codes: [400] - action: IGNORE - - type: DefaultErrorHandler - partition_router: - type: SubstreamPartitionRouter - parent_stream_configs: - - stream: "#/definitions/webinars_list_tmp_stream" - parent_key: "uuid" - partition_field: "parent_id" - transformations: - - type: AddFields - fields: - - path: ["webinar_uuid"] - value: "{{ stream_partition.parent_id }}" - -streams: - - "#/definitions/users_stream" - - "#/definitions/meetings_stream" - - "#/definitions/meeting_registrants_stream" - - "#/definitions/meeting_polls_stream" - - "#/definitions/meeting_poll_results_stream" - - "#/definitions/meeting_registration_questions_stream" - - "#/definitions/webinars_stream" - - "#/definitions/webinar_panelists_stream" - - "#/definitions/webinar_registrants_stream" - - "#/definitions/webinar_absentees_stream" - - "#/definitions/webinar_polls_stream" - - "#/definitions/webinar_poll_results_stream" - - "#/definitions/webinar_registration_questions_stream" - - "#/definitions/webinar_tracking_sources_stream" - - "#/definitions/webinar_qna_results_stream" - - "#/definitions/report_meetings_stream" - - "#/definitions/report_meeting_participants_stream" - - "#/definitions/report_webinars_stream" - - "#/definitions/report_webinar_participants_stream" - -check: - stream_names: - - "users" diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/run.py b/airbyte-integrations/connectors/source-zoom/source_zoom/run.py deleted file mode 100644 index e663e8441844..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/run.py +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import sys - -from airbyte_cdk.entrypoint import launch -from source_zoom import SourceZoom - - -def run(): - source = SourceZoom() - launch(source, sys.argv[1:]) diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_poll_results.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_poll_results.json deleted file mode 100644 index 3c9ea605ecd3..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_poll_results.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "meeting_uuid": { - "type": ["null", "string"] - }, - "meeting_id": { - "type": ["null", "integer"] - }, - "email": { - "type": ["null", "string"] - }, - "name": { - "type": ["null", "string"] - }, - "first_name": { - "type": ["null", "string"] - }, - "last_name": { - "type": ["null", "string"] - }, - "question_details": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "answer": { - "type": ["null", "string"] - }, - "date_time": { - "type": ["null", "string"] - }, - "polling_id": { - "type": ["null", "string"] - }, - "question": { - "type": ["null", "string"] - } - } - } - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_polls.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_polls.json deleted file mode 100644 index d9cbaccf720d..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_polls.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "id": { - "type": ["null", "string"] - }, - "meeting_id": { - "type": ["null", "number"] - }, - "status": { - "type": ["null", "string"] - }, - "anonymous": { - "type": ["null", "boolean"] - }, - "poll_type": { - "type": ["null", "number"] - }, - "questions": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "answer_max_character": { - "type": ["null", "number"] - }, - "answer_min_character": { - "type": ["null", "number"] - }, - "answer_required": { - "type": ["null", "boolean"] - }, - "answers": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "case_sensitive": { - "type": ["null", "boolean"] - }, - "name": { - "type": ["null", "string"] - }, - "prompts": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "prompt_question": { - "type": ["null", "string"] - }, - "prompt_right_answers": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - } - } - } - }, - "rating_max_label": { - "type": ["null", "string"] - }, - "rating_max_value": { - "type": ["null", "number"] - }, - "rating_min_label": { - "type": ["null", "string"] - }, - "rating_min_value": { - "type": ["null", "number"] - }, - "right_answers": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "show_as_dropdown": { - "type": ["null", "boolean"] - }, - "type": { - "type": ["null", "string"] - } - } - } - }, - "title": { - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_registrants.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_registrants.json deleted file mode 100644 index e881cb099190..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_registrants.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "meeting_id": { - "type": ["null", "number"] - }, - "id": { - "type": ["null", "string"] - }, - "address": { - "type": ["null", "string"] - }, - "city": { - "type": ["null", "string"] - }, - "comments": { - "type": ["null", "string"] - }, - "country": { - "type": ["null", "string"] - }, - "custom_questions": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "title": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - } - } - }, - "email": { - "type": ["null", "string"] - }, - "first_name": { - "type": ["null", "string"] - }, - "industry": { - "type": ["null", "string"] - }, - "job_title": { - "type": ["null", "string"] - }, - "last_name": { - "type": ["null", "string"] - }, - "no_of_employees": { - "type": ["null", "string"] - }, - "org": { - "type": ["null", "string"] - }, - "phone": { - "type": ["null", "string"] - }, - "purchasing_time_frame": { - "type": ["null", "string"] - }, - "role_in_purchase_process": { - "type": ["null", "string"] - }, - "state": { - "type": ["null", "string"] - }, - "status": { - "type": ["null", "string"] - }, - "zip": { - "type": ["null", "string"] - }, - "create_time": { - "type": ["null", "string"] - }, - "join_url": { - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_registration_questions.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_registration_questions.json deleted file mode 100644 index 39fb68f6f587..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_registration_questions.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "meeting_id": { - "type": ["null", "integer"] - }, - "custom_questions": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "answers": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "required": { - "type": ["null", "boolean"] - }, - "title": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "string"] - } - } - } - }, - "questions": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "field_name": { - "type": ["null", "string"] - }, - "required": { - "type": ["null", "boolean"] - } - } - } - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meetings.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meetings.json deleted file mode 100644 index 194f626121ba..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meetings.json +++ /dev/null @@ -1,485 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "assistant_id": { - "type": ["null", "string"] - }, - "host_email": { - "type": ["null", "string"] - }, - "host_id": { - "type": ["null", "string"] - }, - "id": { - "type": ["null", "number"] - }, - "uuid": { - "type": ["null", "string"] - }, - "agenda": { - "type": ["null", "string"] - }, - "created_at": { - "type": ["null", "string"] - }, - "duration": { - "type": ["null", "number"] - }, - "encrypted_password": { - "type": ["null", "string"] - }, - "h323_password": { - "type": ["null", "string"] - }, - "join_url": { - "type": ["null", "string"] - }, - "chat_join_url": { - "type": ["null", "string"] - }, - "occurrences": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "duration": { - "type": ["null", "number"] - }, - "occurrence_id": { - "type": ["null", "string"] - }, - "start_time": { - "type": ["null", "string"] - }, - "status": { - "type": ["null", "string"] - } - } - } - }, - "password": { - "type": ["null", "string"] - }, - "pmi": { - "type": ["null", "string"] - }, - "pre_schedule": { - "type": ["null", "boolean"] - }, - "pstn_password": { - "type": ["null", "string"] - }, - "recurrence": { - "type": ["null", "object"], - "properties": { - "end_date_time": { - "type": ["null", "string"] - }, - "end_times": { - "type": ["null", "number"] - }, - "monthly_day": { - "type": ["null", "number"] - }, - "monthly_week": { - "type": ["null", "number"] - }, - "monthly_week_day": { - "type": ["null", "number"] - }, - "repeat_interval": { - "type": ["null", "number"] - }, - "type": { - "type": ["null", "number"] - }, - "weekly_days": { - "type": ["null", "string"] - } - } - }, - "settings": { - "type": ["null", "object"], - "properties": { - "allow_multiple_devices": { - "type": ["null", "boolean"] - }, - "alternative_hosts": { - "type": ["null", "string"] - }, - "alternative_hosts_email_notification": { - "type": ["null", "boolean"] - }, - "alternative_host_update_polls": { - "type": ["null", "boolean"] - }, - "approval_type": { - "type": ["null", "number"] - }, - "approved_or_denied_countries_or_regions": { - "type": ["null", "object"], - "properties": { - "approved_list": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "denied_list": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "enable": { - "type": ["null", "boolean"] - }, - "method": { - "type": ["null", "string"] - } - } - }, - "audio": { - "type": ["null", "string"] - }, - "audio_conference_info": { - "type": ["null", "string"] - }, - "authentication_domains": { - "type": ["null", "string"] - }, - "authentication_exception": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "email": { - "type": ["null", "string"] - }, - "name": { - "type": ["null", "string"] - }, - "join_url": { - "type": ["null", "string"] - } - } - } - }, - "authentication_name": { - "type": ["null", "string"] - }, - "authentication_option": { - "type": ["null", "string"] - }, - "auto_recording": { - "type": ["null", "string"] - }, - "breakout_room": { - "type": ["null", "object"], - "properties": { - "enable": { - "type": ["null", "boolean"] - }, - "rooms": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "name": { - "type": ["null", "string"] - }, - "participants": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - } - } - } - } - } - }, - "calendar_type": { - "type": ["null", "number"] - }, - "close_registration": { - "type": ["null", "boolean"] - }, - "cn_meeting": { - "type": ["null", "boolean"] - }, - "contact_email": { - "type": ["null", "string"] - }, - "contact_name": { - "type": ["null", "string"] - }, - "custom_keys": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "key": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - } - } - }, - "email_notification": { - "type": ["null", "boolean"] - }, - "device_testing": { - "type": ["null", "boolean"] - }, - "email_in_attendee_report": { - "type": ["null", "boolean"] - }, - "enable_dedicated_group_chat": { - "type": ["null", "boolean"] - }, - "encryption_type": { - "type": ["null", "string"] - }, - "enforce_login": { - "type": ["null", "boolean"] - }, - "enforce_login_domains": { - "type": ["null", "string"] - }, - "focus_mode": { - "type": ["null", "boolean"] - }, - "global_dial_in_countries": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "global_dial_in_numbers": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "city": { - "type": ["null", "string"] - }, - "country": { - "type": ["null", "string"] - }, - "country_name": { - "type": ["null", "string"] - }, - "number": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "string"] - } - } - } - }, - "host_video": { - "type": ["null", "boolean"] - }, - "in_meeting": { - "type": ["null", "boolean"] - }, - "jbh_time": { - "type": ["null", "number"] - }, - "join_before_host": { - "type": ["null", "boolean"] - }, - "language_interpretation": { - "type": ["null", "object"], - "properties": { - "enable": { - "type": ["null", "boolean"] - }, - "interpreters": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "email": { - "type": ["null", "string"] - }, - "languages": { - "type": ["null", "string"] - } - } - } - } - } - }, - "meeting_authentication": { - "type": ["null", "boolean"] - }, - "mute_upon_entry": { - "type": ["null", "boolean"] - }, - "participant_video": { - "type": ["null", "boolean"] - }, - "private_meeting": { - "type": ["null", "boolean"] - }, - "resources": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "resource_type": { - "type": ["null", "string"] - }, - "resource_id": { - "type": ["null", "string"] - }, - "permission_level": { - "type": ["null", "string"] - } - } - } - }, - "registrants_confirmation_email": { - "type": ["null", "boolean"] - }, - "registrants_email_notification": { - "type": ["null", "boolean"] - }, - "registration_type": { - "type": ["null", "number"] - }, - "request_permission_to_unmute_participants": { - "type": ["null", "boolean"] - }, - "show_join_info": { - "type": ["null", "boolean"] - }, - "show_share_button": { - "type": ["null", "boolean"] - }, - "sign_language_interpretation": { - "type": ["null", "object"], - "additionalProperties": true, - "properties": { - "enable": { - "type": ["null", "boolean"] - } - } - }, - "use_pmi": { - "type": ["null", "boolean"] - }, - "waiting_room": { - "type": ["null", "boolean"] - }, - "waiting_room_options": { - "type": ["null", "object"], - "properties": { - "enable": { - "type": ["null", "boolean"] - }, - "admit_type": { - "type": ["null", "number"] - }, - "auto_admit": { - "type": ["null", "number"] - }, - "internal_user_auto_admit": { - "type": ["null", "number"] - } - } - }, - "watermark": { - "type": ["null", "boolean"] - }, - "host_save_video_order": { - "type": ["null", "boolean"] - }, - "internal_meeting": { - "type": ["null", "boolean"] - }, - "continuous_meeting_chat": { - "type": ["null", "object"], - "properties": { - "enable": { - "type": ["null", "boolean"] - }, - "auto_add_invited_external_users": { - "type": ["null", "boolean"] - }, - "channel_id": { - "type": ["null", "string"] - } - } - }, - "participant_focused_meeting": { - "type": ["null", "boolean"] - }, - "push_change_to_calendar": { - "type": ["null", "boolean"] - } - } - }, - "registration_url": { - "type": ["null", "string"] - }, - "resources": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "resource_type": { - "type": ["null", "string"] - }, - "resource_id": { - "type": ["null", "string"] - }, - "permission_level": { - "type": ["null", "string"] - } - } - } - }, - "start_time": { - "type": ["null", "string"] - }, - "start_url": { - "type": ["null", "string"] - }, - "status": { - "type": ["null", "string"] - }, - "timezone": { - "type": ["null", "string"] - }, - "topic": { - "type": ["null", "string"] - }, - "tracking_fields": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "field": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - }, - "visible": { - "type": ["null", "boolean"] - } - } - } - }, - "type": { - "type": ["null", "number"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meetings_list_tmp.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meetings_list_tmp.json deleted file mode 100644 index c74e6c5a5915..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meetings_list_tmp.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "additionalProperties": true -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_meeting_participants.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_meeting_participants.json deleted file mode 100644 index 6ac1210c943a..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_meeting_participants.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "meeting_uuid": { - "type": ["null", "string"] - }, - "meeting_id": { - "type": ["null", "integer"] - }, - "customer_key": { - "type": ["null", "string"] - }, - "duration": { - "type": ["null", "number"] - }, - "failover": { - "type": ["null", "boolean"] - }, - "id": { - "type": ["null", "string"] - }, - "join_time": { - "type": ["null", "string"] - }, - "leave_time": { - "type": ["null", "string"] - }, - "name": { - "type": ["null", "string"] - }, - "registrant_id": { - "type": ["null", "string"] - }, - "user_email": { - "type": ["null", "string"] - }, - "user_id": { - "type": ["null", "string"] - }, - "status": { - "type": ["null", "string"] - }, - "bo_mtg_id": { - "type": ["null", "string"] - }, - "participant_user_id": { - "type": ["null", "string"] - }, - "attentiveness_score": { - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_meetings.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_meetings.json deleted file mode 100644 index 96bb88296539..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_meetings.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "meeting_uuid": { - "type": ["null", "string"] - }, - "custom_keys": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "key": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - } - } - }, - "dept": { - "type": ["null", "string"] - }, - "duration": { - "type": ["null", "number"] - }, - "end_time": { - "type": ["null", "string"] - }, - "host_id": { - "type": ["null", "string"] - }, - "id": { - "type": ["null", "number"] - }, - "participants_count": { - "type": ["null", "number"] - }, - "start_time": { - "type": ["null", "string"] - }, - "topic": { - "type": ["null", "string"] - }, - "total_minutes": { - "type": ["null", "number"] - }, - "tracking_fields": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "field": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - } - } - }, - "type": { - "type": ["null", "number"] - }, - "user_email": { - "type": ["null", "string"] - }, - "user_name": { - "type": ["null", "string"] - }, - "uuid": { - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_webinar_participants.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_webinar_participants.json deleted file mode 100644 index 97728b61a0da..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_webinar_participants.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "webinar_uuid": { - "type": ["null", "string"] - }, - "customer_key": { - "type": ["null", "string"] - }, - "duration": { - "type": ["null", "number"] - }, - "failover": { - "type": ["null", "boolean"] - }, - "id": { - "type": ["null", "string"] - }, - "join_time": { - "type": ["null", "string"] - }, - "leave_time": { - "type": ["null", "string"] - }, - "name": { - "type": ["null", "string"] - }, - "registrant_id": { - "type": ["null", "string"] - }, - "status": { - "type": ["null", "string"] - }, - "user_email": { - "type": ["null", "string"] - }, - "user_id": { - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_webinars.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_webinars.json deleted file mode 100644 index 785c07bdc9ba..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_webinars.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "webinar_uuid": { - "type": ["null", "string"] - }, - "custom_keys": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "key": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - } - } - }, - "dept": { - "type": ["null", "string"] - }, - "duration": { - "type": ["null", "number"] - }, - "end_time": { - "type": ["null", "string"] - }, - "id": { - "type": ["null", "number"] - }, - "participants_count": { - "type": ["null", "number"] - }, - "start_time": { - "type": ["null", "string"] - }, - "topic": { - "type": ["null", "string"] - }, - "total_minutes": { - "type": ["null", "number"] - }, - "tracking_fields": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "field": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - } - } - }, - "type": { - "type": ["null", "number"] - }, - "user_email": { - "type": ["null", "string"] - }, - "user_name": { - "type": ["null", "string"] - }, - "uuid": { - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/users.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/users.json deleted file mode 100644 index a2f1fce04692..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/users.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "properties": { - "user_created_at": { - "type": ["null", "string"] - }, - "created_at": { - "type": ["null", "string"] - }, - "custom_attributes": { - "type": ["null", "array"], - "items": { - "type": "object", - "properties": { - "key": { - "type": ["null", "string"] - }, - "name": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - } - } - }, - "dept": { - "type": ["null", "string"] - }, - "email": { - "type": ["null", "string"] - }, - "employee_unique_id": { - "type": ["null", "string"] - }, - "first_name": { - "type": ["null", "string"] - }, - "group_ids": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "id": { - "type": ["null", "string"] - }, - "im_group_ids": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "language": { - "type": ["null", "string"] - }, - "last_client_version": { - "type": ["null", "string"] - }, - "last_login_time": { - "type": ["null", "string"] - }, - "last_name": { - "type": ["null", "string"] - }, - "phone_number": { - "type": ["null", "string"] - }, - "plan_united_type": { - "type": ["null", "string"] - }, - "pmi": { - "type": ["null", "number"] - }, - "role_id": { - "type": ["null", "string"] - }, - "status": { - "type": ["null", "string"] - }, - "timezone": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "number"] - }, - "verified": { - "type": ["null", "number"] - }, - "display_name": { "type": ["null", "string"] } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_absentees.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_absentees.json deleted file mode 100644 index c56de977fb97..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_absentees.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "webinar_uuid": { - "type": ["null", "string"] - }, - "id": { - "type": ["null", "string"] - }, - "address": { - "type": ["null", "string"] - }, - "city": { - "type": ["null", "string"] - }, - "comments": { - "type": ["null", "string"] - }, - "country": { - "type": ["null", "string"] - }, - "custom_questions": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "title": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - } - } - }, - "email": { - "type": ["null", "string"] - }, - "first_name": { - "type": ["null", "string"] - }, - "industry": { - "type": ["null", "string"] - }, - "job_title": { - "type": ["null", "string"] - }, - "last_name": { - "type": ["null", "string"] - }, - "no_of_employees": { - "type": ["null", "string"] - }, - "org": { - "type": ["null", "string"] - }, - "phone": { - "type": ["null", "string"] - }, - "purchasing_time_frame": { - "type": ["null", "string"] - }, - "role_in_purchase_process": { - "type": ["null", "string"] - }, - "state": { - "type": ["null", "string"] - }, - "status": { - "type": ["null", "string"] - }, - "zip": { - "type": ["null", "string"] - }, - "create_time": { - "type": ["null", "string"] - }, - "join_url": { - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_panelists.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_panelists.json deleted file mode 100644 index 65a7dbff19e2..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_panelists.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "webinar_id": { - "type": ["null", "number"] - }, - "id": { - "type": ["null", "string"] - }, - "email": { - "type": ["null", "string"] - }, - "name": { - "type": ["null", "string"] - }, - "join_url": { - "type": ["null", "string"] - }, - "virtual_background_id": { - "type": ["null", "string"] - }, - "name_tag_id": { - "type": ["null", "string"] - }, - "name_tag_name": { - "type": ["null", "string"] - }, - "name_tag_pronouns": { - "type": ["null", "string"] - }, - "name_tag_description": { - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_poll_results.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_poll_results.json deleted file mode 100644 index d405339cea2c..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_poll_results.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "webinar_uuid": { - "type": ["null", "string"] - }, - "email": { - "type": ["null", "string"] - }, - "name": { - "type": ["null", "string"] - }, - "question_details": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "answer": { - "type": ["null", "string"] - }, - "date_time": { - "type": ["null", "string"] - }, - "polling_id": { - "type": ["null", "string"] - }, - "question": { - "type": ["null", "string"] - } - } - } - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_polls.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_polls.json deleted file mode 100644 index 1c30b07f1dee..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_polls.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "webinar_id": { - "type": ["null", "string"] - }, - "id": { - "type": ["null", "string"] - }, - "status": { - "type": ["null", "string"] - }, - "anonymous": { - "type": ["null", "boolean"] - }, - "poll_type": { - "type": ["null", "number"] - }, - "questions": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "answer_max_character": { - "type": ["null", "number"] - }, - "answer_min_character": { - "type": ["null", "number"] - }, - "answer_required": { - "type": ["null", "boolean"] - }, - "answers": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "case_sensitive": { - "type": ["null", "boolean"] - }, - "name": { - "type": ["null", "string"] - }, - "prompts": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "prompt_question": { - "type": ["null", "string"] - }, - "prompt_right_answers": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - } - } - } - }, - "rating_max_label": { - "type": ["null", "string"] - }, - "rating_max_value": { - "type": ["null", "number"] - }, - "rating_min_label": { - "type": ["null", "string"] - }, - "rating_min_value": { - "type": ["null", "number"] - }, - "right_answers": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "show_as_dropdown": { - "type": ["null", "boolean"] - }, - "type": { - "type": ["null", "string"] - } - } - } - }, - "title": { - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_qna_results.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_qna_results.json deleted file mode 100644 index 175b6dcd633e..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_qna_results.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "webinar_uuid": { - "type": ["null", "string"] - }, - "email": { - "type": ["null", "string"] - }, - "name": { - "type": ["null", "string"] - }, - "question_details": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "answer": { - "type": ["null", "string"] - }, - "question": { - "type": ["null", "string"] - } - } - } - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_registrants.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_registrants.json deleted file mode 100644 index 7fda1561c4ab..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_registrants.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "webinar_id": { - "type": ["null", "string"] - }, - "id": { - "type": ["null", "string"] - }, - "address": { - "type": ["null", "string"] - }, - "city": { - "type": ["null", "string"] - }, - "comments": { - "type": ["null", "string"] - }, - "country": { - "type": ["null", "string"] - }, - "custom_questions": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "title": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - } - } - }, - "email": { - "type": ["null", "string"] - }, - "first_name": { - "type": ["null", "string"] - }, - "industry": { - "type": ["null", "string"] - }, - "job_title": { - "type": ["null", "string"] - }, - "last_name": { - "type": ["null", "string"] - }, - "no_of_employees": { - "type": ["null", "string"] - }, - "org": { - "type": ["null", "string"] - }, - "phone": { - "type": ["null", "string"] - }, - "purchasing_time_frame": { - "type": ["null", "string"] - }, - "role_in_purchase_process": { - "type": ["null", "string"] - }, - "state": { - "type": ["null", "string"] - }, - "status": { - "type": ["null", "string"] - }, - "zip": { - "type": ["null", "string"] - }, - "create_time": { - "type": ["null", "string"] - }, - "join_url": { - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_registration_questions.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_registration_questions.json deleted file mode 100644 index a7ba8b6985c5..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_registration_questions.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "webinar_id": { - "type": ["null", "string"] - }, - "custom_questions": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "answers": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "required": { - "type": ["null", "boolean"] - }, - "title": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "string"] - } - } - } - }, - "questions": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "field_name": { - "type": ["null", "string"] - }, - "required": { - "type": ["null", "boolean"] - } - } - } - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_tracking_sources.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_tracking_sources.json deleted file mode 100644 index b97d71e40147..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_tracking_sources.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "webinar_id": { - "type": ["null", "string"] - }, - "id": { - "type": ["null", "string"] - }, - "registration_count": { - "type": ["null", "number"] - }, - "source_name": { - "type": ["null", "string"] - }, - "tracking_url": { - "type": ["null", "string"] - }, - "visitor_count": { - "type": ["null", "number"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinars.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinars.json deleted file mode 100644 index 383818e6b57e..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinars.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "host_email": { - "type": ["null", "string"] - }, - "host_id": { - "type": ["null", "string"] - }, - "id": { - "type": ["null", "number"] - }, - "uuid": { - "type": ["null", "string"] - }, - "agenda": { - "type": ["null", "string"] - }, - "created_at": { - "type": ["null", "string"] - }, - "duration": { - "type": ["null", "number"] - }, - "join_url": { - "type": ["null", "string"] - }, - "occurrences": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "duration": { - "type": ["null", "number"] - }, - "occurrence_id": { - "type": ["null", "string"] - }, - "start_time": { - "type": ["null", "string"] - }, - "status": { - "type": ["null", "string"] - } - } - } - }, - "password": { - "type": ["null", "string"] - }, - "recurrence": { - "type": ["null", "object"], - "properties": { - "end_date_time": { - "type": ["null", "string"] - }, - "end_times": { - "type": ["null", "number"] - }, - "monthly_day": { - "type": ["null", "number"] - }, - "monthly_week": { - "type": ["null", "number"] - }, - "monthly_week_day": { - "type": ["null", "number"] - }, - "repeat_interval": { - "type": ["null", "number"] - }, - "type": { - "type": ["null", "number"] - }, - "weekly_days": { - "type": ["null", "string"] - } - } - }, - "settings": { - "type": ["null", "object"], - "properties": { - "allow_multiple_devices": { - "type": ["null", "boolean"] - }, - "alternative_hosts": { - "type": ["null", "string"] - }, - "alternative_host_update_polls": { - "type": ["null", "boolean"] - }, - "approval_type": { - "type": ["null", "number"] - }, - "attendees_and_panelists_reminder_email_notification": { - "type": ["null", "object"], - "properties": { - "enable": { - "type": ["null", "boolean"] - }, - "type": { - "type": ["null", "number"] - } - } - }, - "audio": { - "type": ["null", "string"] - }, - "authentication_domains": { - "type": ["null", "string"] - }, - "authentication_name": { - "type": ["null", "string"] - }, - "authentication_option": { - "type": ["null", "string"] - }, - "auto_recording": { - "type": ["null", "string"] - }, - "close_registration": { - "type": ["null", "boolean"] - }, - "contact_email": { - "type": ["null", "string"] - }, - "contact_name": { - "type": ["null", "string"] - }, - "email_language": { - "type": ["null", "string"] - }, - "follow_up_absentees_email_notification": { - "type": ["null", "object"], - "properties": { - "enable": { - "type": ["null", "boolean"] - }, - "type": { - "type": ["null", "number"] - } - } - }, - "follow_up_attendees_email_notification": { - "type": ["null", "object"], - "properties": { - "enable": { - "type": ["null", "boolean"] - }, - "type": { - "type": ["null", "number"] - } - } - }, - "global_dial_in_countries": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "hd_video": { - "type": ["null", "boolean"] - }, - "hd_video_for_attendees": { - "type": ["null", "boolean"] - }, - "host_video": { - "type": ["null", "boolean"] - }, - "language_interpretation": { - "type": ["null", "object"], - "properties": { - "enable": { - "type": ["null", "boolean"] - }, - "interpreters": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "email": { - "type": ["null", "string"] - }, - "languages": { - "type": ["null", "string"] - } - } - } - } - } - }, - "panelist_authentication": { - "type": ["null", "boolean"] - }, - "meeting_authentication": { - "type": ["null", "boolean"] - }, - "add_watermark": { - "type": ["null", "boolean"] - }, - "add_audio_watermark": { - "type": ["null", "boolean"] - }, - "notify_registrants": { - "type": ["null", "boolean"] - }, - "on_demand": { - "type": ["null", "boolean"] - }, - "panelists_invitation_email_notification": { - "type": ["null", "boolean"] - }, - "panelists_video": { - "type": ["null", "boolean"] - }, - "post_webinar_survey": { - "type": ["null", "boolean"] - }, - "practice_session": { - "type": ["null", "boolean"] - }, - "question_and_answer": { - "type": ["null", "object"], - "properties": { - "allow_anonymous_questions": { - "type": ["null", "boolean"] - }, - "answer_questions": { - "type": ["null", "string"] - }, - "attendees_can_comment": { - "type": ["null", "boolean"] - }, - "attendees_can_upvote": { - "type": ["null", "boolean"] - }, - "allow_auto_reply": { - "type": ["null", "boolean"] - }, - "auto_reply_text": { - "type": ["null", "string"] - }, - "enable": { - "type": ["null", "boolean"] - } - } - }, - "registrants_confirmation_email": { - "type": ["null", "boolean"] - }, - "registrants_email_notification": { - "type": ["null", "boolean"] - }, - "registrants_restrict_number": { - "type": ["null", "number"] - }, - "registration_type": { - "type": ["null", "number"] - }, - "send_1080p_video_to_attendees": { - "type": ["null", "boolean"] - }, - "show_share_button": { - "type": ["null", "boolean"] - }, - "survey_url": { - "type": ["null", "string"] - }, - "enable_session_branding": { - "type": ["null", "boolean"] - } - } - }, - "start_time": { - "type": ["null", "string"] - }, - "start_url": { - "type": ["null", "string"] - }, - "timezone": { - "type": ["null", "string"] - }, - "topic": { - "type": ["null", "string"] - }, - "tracking_fields": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "field": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - } - } - }, - "type": { - "type": ["null", "number"] - }, - "is_simulive": { - "type": ["null", "boolean"] - }, - "record_file_id": { - "type": ["null", "string"] - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinars_list_tmp.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinars_list_tmp.json deleted file mode 100644 index c74e6c5a5915..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinars_list_tmp.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "additionalProperties": true -} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/source.py b/airbyte-integrations/connectors/source-zoom/source_zoom/source.py deleted file mode 100644 index a851fa38c8a3..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/source.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource - -""" -This file provides the necessary constructs to interpret a provided declarative YAML configuration file into -source connector. - -WARNING: Do not modify this file. -""" - - -# Declarative Source -class SourceZoom(YamlDeclarativeSource): - def __init__(self): - super().__init__(**{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/spec.yaml b/airbyte-integrations/connectors/source-zoom/source_zoom/spec.yaml deleted file mode 100644 index d91cbe0bd6c9..000000000000 --- a/airbyte-integrations/connectors/source-zoom/source_zoom/spec.yaml +++ /dev/null @@ -1,29 +0,0 @@ -documentationUrl: https://docs.airbyte.com/integrations/sources/zoom -connectionSpecification: - $schema: http://json-schema.org/draft-07/schema# - title: Zoom Spec - type: object - required: - - account_id - - client_id - - client_secret - - authorization_endpoint - additionalProperties: true - properties: - account_id: - type: string - order: 0 - description: 'The account ID for your Zoom account. You can find this in the Zoom Marketplace under the "Manage" tab for your app.' - client_id: - type: string - order: 1 - description: 'The client ID for your Zoom app. You can find this in the Zoom Marketplace under the "Manage" tab for your app.' - client_secret: - type: string - order: 2 - description: 'The client secret for your Zoom app. You can find this in the Zoom Marketplace under the "Manage" tab for your app.' - airbyte_secret: true - authorization_endpoint: - type: string - order: 3 - default: "https://zoom.us/oauth/token" diff --git a/airbyte-integrations/connectors/source-zoom/unit_tests/test_zoom_authenticator.py b/airbyte-integrations/connectors/source-zoom/unit_tests/test_zoom_authenticator.py deleted file mode 100755 index 3e2b27319383..000000000000 --- a/airbyte-integrations/connectors/source-zoom/unit_tests/test_zoom_authenticator.py +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import base64 -import unittest -from http import HTTPStatus - -import requests -import requests_mock -from source_zoom.components import ServerToServerOauthAuthenticator - - -class TestOAuthClient(unittest.TestCase): - def test_generate_access_token(self): - except_access_token = "rc-test-token" - except_token_response = {"access_token": except_access_token} - - config = { - "account_id": "rc-asdfghjkl", - "client_id": "rc-123456789", - "client_secret": "rc-test-secret", - "authorization_endpoint": "https://example.zoom.com/oauth/token" - } - parameters = config - client = ServerToServerOauthAuthenticator( - config=config, - account_id=config["account_id"], - client_id=config["client_id"], - client_secret=config["client_secret"], - authorization_endpoint=config["authorization_endpoint"], - parameters=parameters, - ) - - # Encode the client credentials in base64 - token = base64.b64encode(f'{config.get("client_id")}:{config.get("client_secret")}'.encode("ascii")).decode("utf-8") - - # Define the headers that should be sent in the request - headers = {"Authorization": f"Basic {token}", "Content-type": "application/json"} - - # Define the URL containing the grant_type and account_id as query parameters - url = f'{config.get("authorization_endpoint")}?grant_type=account_credentials&account_id={config.get("account_id")}' - - with requests_mock.Mocker() as m: - # Mock the requests.post call with the expected URL, headers and token response - m.post(url, json=except_token_response, request_headers=headers, status_code=HTTPStatus.OK) - - # Call the generate_access_token function and assert it returns the expected access token - self.assertEqual(client.generate_access_token(), except_access_token) - - # Test case when the endpoint has some error, like a timeout - with requests_mock.Mocker() as m: - m.post(url, exc=requests.exceptions.RequestException) - with self.assertRaises(Exception) as cm: - client.generate_access_token() - self.assertIn("Error while generating access token", str(cm.exception)) - - -if __name__ == "__main__": - unittest.main() diff --git a/buildSrc/src/main/groovy/airbyte-bulk-connector.gradle b/buildSrc/src/main/groovy/airbyte-bulk-connector.gradle index 7eaf90335941..f7e1cfee923f 100644 --- a/buildSrc/src/main/groovy/airbyte-bulk-connector.gradle +++ b/buildSrc/src/main/groovy/airbyte-bulk-connector.gradle @@ -179,6 +179,11 @@ class AirbyteBulkConnectorPlugin implements Plugin { systemProperties = project.test.systemProperties maxParallelForks = project.test.maxParallelForks maxHeapSize = project.test.maxHeapSize + + testLogging() { + events 'skipped', 'started', 'passed', 'failed' + exceptionFormat 'full' + } } // For historical reasons (i.e. airbyte-ci), this task is called integrationTestJava. @@ -200,6 +205,13 @@ class AirbyteBulkConnectorPlugin implements Plugin { systemProperties = project.test.systemProperties maxParallelForks = project.test.maxParallelForks maxHeapSize = project.test.maxHeapSize + + testLogging() { + events 'skipped', 'started', 'passed', 'failed' + exceptionFormat 'full' + // Swallow the logs when running in airbyte-ci, rely on test reports instead. + showStandardStreams = !System.getenv().containsKey("RUN_IN_AIRBYTE_CI") + } } project.dependencies { diff --git a/buildSrc/src/main/groovy/airbyte-java-connector.gradle b/buildSrc/src/main/groovy/airbyte-java-connector.gradle index 0a6cbf407212..81dc5f54935e 100644 --- a/buildSrc/src/main/groovy/airbyte-java-connector.gradle +++ b/buildSrc/src/main/groovy/airbyte-java-connector.gradle @@ -205,9 +205,15 @@ class AirbyteJavaConnectorPlugin implements Plugin { } jvmArgs = project.test.jvmArgs - systemProperties = project.test.systemProperties maxParallelForks = project.test.maxParallelForks maxHeapSize = project.test.maxHeapSize + // Reduce parallelization to get tests passing + // TODO: Fix the actual issue causing concurrent tests to hang. + systemProperties = project.test.systemProperties + [ + 'junit.jupiter.execution.parallel.enabled': 'true', + 'junit.jupiter.execution.parallel.config.strategy': 'fixed', + 'junit.jupiter.execution.parallel.config.fixed.parallelism': Math.min((Runtime.runtime.availableProcessors() / 2).toInteger(), 1).toString() + ] // Tone down the JIT when running the containerized connector to improve overall performance. // The JVM default settings are optimized for long-lived processes in steady-state operation. diff --git a/docs/.gitbook/assets/airbyte_kestra_2.png b/docs/.gitbook/assets/airbyte_kestra_2.png new file mode 100644 index 000000000000..669d0537fa72 Binary files /dev/null and b/docs/.gitbook/assets/airbyte_kestra_2.png differ diff --git a/docs/.gitbook/assets/connector_pod.png b/docs/.gitbook/assets/connector_pod.png new file mode 100644 index 000000000000..1eae515a8dcf Binary files /dev/null and b/docs/.gitbook/assets/connector_pod.png differ diff --git a/docs/.gitbook/assets/replication_mono_pod.png b/docs/.gitbook/assets/replication_mono_pod.png new file mode 100644 index 000000000000..8832981853d1 Binary files /dev/null and b/docs/.gitbook/assets/replication_mono_pod.png differ diff --git a/docs/access-management/role-mapping.md b/docs/access-management/role-mapping.md index 017b4042a6c3..5d4de4c30450 100644 --- a/docs/access-management/role-mapping.md +++ b/docs/access-management/role-mapping.md @@ -41,19 +41,19 @@ Organization-wide permissions and each set of workspace permissions each count a "companyGroup1": [ { "scope": "workspace", - "scopeId": "workspace1", + "scopeId": "11111111-11111111-11111111-11111111", "permissionType": "workspace_admin" }, { "scope": "workspace", - "scopeId": "workspace2", + "scopeId": "22222222-22222222-22222222-22222222", "permissionType": "workspace_reader" } ], "companyGroup2": [ { "scope": "workspace", - "scopeId": "workspace1", + "scopeId": "33333333-33333333-33333333-33333333", "permissionType": "workspace_reader" } ] @@ -61,6 +61,7 @@ Organization-wide permissions and each set of workspace permissions each count a ``` Notes: - `scope` must be set to either 'workspace' or 'organization'. +- `scopeId` must the identifier of scope access is granted for. It is a GUID and for organization scope is always '00000000-00000000-00000000-00000000'. For workspace, refer to the UI and the output of a list workspace to identify your workspaceId. - `permissionType` must be set to a valid value, e.g. 'workspace_admin', 'workspace_reader', 'organization_admin', etc. All valid values are listed [here](https://github.com/airbytehq/airbyte-api-python-sdk/blob/main/src/airbyte_api/models/publicpermissiontype.py). ### Complete Python Script diff --git a/docs/access-management/sso-providers/azure-entra-id.md b/docs/access-management/sso-providers/azure-entra-id.md index 5b06c4e29d8a..5bbef3341258 100644 --- a/docs/access-management/sso-providers/azure-entra-id.md +++ b/docs/access-management/sso-providers/azure-entra-id.md @@ -57,9 +57,14 @@ You'll need to pass your Airbyte contact the following information of the create - **Client Secret**: as copied above - **Application (client) ID**: You'll find this in the **Essentials** section on the **Overview** page of the application you created - **OpenID Connect metadata document**: You'll find this in the **Endpoints** panel, that you can open from the top bar on the **Overview** page +- **Email Domain**: Users signing in from this domain will be required to sign in via SSO. Once we've received this information from you, We'll setup SSO for you and let you know once it's ready to be used. +:::warning +For security purposes, existing [Applications](https://reference.airbyte.com/reference/authentication) used to access the Airbyte API that were created before enabling SSO **will be disabled** once the user that owns the Application signs in via SSO for the first time. After enabling SSO, please make sure to replace any Application secrets that were previously in use. +::: + diff --git a/docs/access-management/sso-providers/okta.md b/docs/access-management/sso-providers/okta.md index 2998907ca492..e331d207a8ec 100644 --- a/docs/access-management/sso-providers/okta.md +++ b/docs/access-management/sso-providers/okta.md @@ -63,6 +63,11 @@ On the following screen you'll need to configure all parameters for your Okta ap * Your **Okta domain** (it's not specific to this application, see [Find your Okta domain](https://developer.okta.com/docs/guides/find-your-domain/main/)) * **Client ID** * **Client Secret** + * **Email Domain** (users signing in from this domain will be required to sign in via SSO) + + :::warning + For security purposes, existing [Applications](https://reference.airbyte.com/reference/authentication) used to access the Airbyte API that were created before enabling SSO **will be disabled** once the user that owns the Application signs in via SSO for the first time. After enabling SSO, please make sure to replace any Application secrets that were previously in use. + ::: diff --git a/docs/api-documentation.md b/docs/api-documentation.md index cc405f486c1d..5d5d2c3af78a 100644 --- a/docs/api-documentation.md +++ b/docs/api-documentation.md @@ -21,6 +21,6 @@ Navigate to our full API documentation to learn how to retrieve your access toke Our full API documentation is located here: [api.airbyte.com](https://reference.airbyte.com/reference/getting-started). ## Configuration API (Deprecated) -The configuration API is now deprecated and no longer supported. It is an internal API that is designed for communications between different Airbyte components ratther than managing your Airbyte workspace. +The configuration API is now deprecated and no longer supported. It is an internal API that is designed for communications between different Airbyte components rather than managing your Airbyte workspace. -Users utilize the Config API at their own risk. This API is utilized internally by the Airbyte Engineering team and may be modified in the future if the need arises. \ No newline at end of file +Users utilize the Config API at their own risk. This API is utilized internally by the Airbyte Engineering team and may be modified in the future if the need arises. diff --git a/docs/cloud/managing-airbyte-cloud/manage-airbyte-cloud-notifications.md b/docs/cloud/managing-airbyte-cloud/manage-airbyte-cloud-notifications.md index cdd81518ffe6..ec89acc0ce9f 100644 --- a/docs/cloud/managing-airbyte-cloud/manage-airbyte-cloud-notifications.md +++ b/docs/cloud/managing-airbyte-cloud/manage-airbyte-cloud-notifications.md @@ -14,8 +14,8 @@ This page provides guidance on how to manage notifications for Airbyte, allowing | **Successful Syncs** | A sync from any of your connections succeeds. Note that if sync runs frequently or if there are many syncs in the workspace these types of events can be noisy | | **Automated Connection Updates** | A connection is updated automatically (ex. a source schema is automatically updated) | | **Connection Updates Requiring Action** | A connection update requires you to take action (ex. a breaking schema change is detected) | -| **Warning - Repeated Failures** | A connection will be disabled soon due to repeated failures. It has failed 50 times consecutively or there were only failed jobs in the past 7 days | -| **Sync Disabled - Repeated Failures** | A connection was automatically disabled due to repeated failures. It will be disabled when it has failed 100 times consecutively or has been failing for 14 days in a row | +| **Warning - Repeated Failures** | A connection will be disabled soon due to repeated failures. It has failed 20 times consecutively and there were only failed jobs in the past 4 days | +| **Sync Disabled - Repeated Failures** | A connection was automatically disabled due to repeated failures. It will be disabled when it has failed 30 times consecutively and has been failing for 7 days in a row | | **Warning - Upgrade Required** (Cloud only) | A new connector version is available and requires manual upgrade | | **Sync Disabled - Upgrade Required** (Cloud only) | One or more connections were automatically disabled due to a connector upgrade deadline passing | diff --git a/docs/cloud/managing-airbyte-cloud/manage-credits.md b/docs/cloud/managing-airbyte-cloud/manage-credits.md index 453a59c90fdf..1a984ad20f27 100644 --- a/docs/cloud/managing-airbyte-cloud/manage-credits.md +++ b/docs/cloud/managing-airbyte-cloud/manage-credits.md @@ -4,12 +4,18 @@ products: cloud # Manage credits -Airbyte [credits](https://airbyte.com/pricing) are used to pay for Airbyte resources when you run a sync. - -Airbyte Cloud plans start at just $10 per month, with additional charges based on usage. +In order to manage your payment and billing information, you must be granted the **Organization Admin** role. ## What are credits? +Airbyte [credits](https://airbyte.com/pricing) are used to pay for Airbyte resources when you run a sync. Airbyte Cloud plans start at $10 per month, which includes 4 credits. Additional credits are available at $2.50 each. + +:::note +If you signed up for Airbyte Cloud on or after October 31st, 2024, you are automatically enrolled in our $10/month subscription plan. + +For those who signed up prior, we will reach out to you over the coming weeks to migrate you to the new plans, and you can continue to use Airbyte as usual in the interim. +::: + Airbyte uses credits to unify pricing across multiple types of sources. You can refer to the below table to understand how pricing differs across each source. |Source Type| Billing Type| Price| Credit Equivalent| @@ -19,8 +25,6 @@ Airbyte uses credits to unify pricing across multiple types of sources. You can |Files| GB | $10 per GB| 4 credits| |Custom sources| Rows | $15 per million rows| 6 credits| -Airbyte Cloud plans start at $10 per month, which includes 4 credits. Additional credits are available at $2.50 each. - For APIs and custom sources, most syncs will sync incrementally, so the row amount will typically be those rows added, edited, or deleted. For Full Refresh syncs, every row synced will be charged. For Databases and File sources, Airbyte measures the data volume observed by the Airbyte Platform during the sync to determine data volumes. When the data is in transit, it is serialized to Airbyte Protocol format records. This is likely to be a larger representation of your data than you would see if you were to query your database directly, and varies depending on how your database stores and compresses data. @@ -28,6 +32,8 @@ For Databases and File sources, Airbyte measures the data volume observed by the ## Start a Trial To begin a trial of Airbyte Cloud, head to https://cloud.airbyte.com/signup. Your trial will only begin after your first successful sync. Trials last 14 days or when 400 trial credits are used, whichever occurs first. +If you need additional trial credits or time to evaluate Airbyte, please reach out to our [Sales team](https://airbyte.com/company/talk-to-sales). + ## Add Payment Details To continue using Airbyte beyond your trial, we require a valid payment method on file. We currently only accept credit card. If you prefer ACH, please [Talk to Sales](https://airbyte.com/company/talk-to-sales). @@ -36,16 +42,47 @@ To add payment details, navigate to the Cloud UI. 2. Under **Organization**, click **Billing** 3. Enter **Payment Details** -Once your payment details have been saved, Airbyte will automatically charge the credit card on file at the end of each month's billing period for usage incurred. +Once your payment details have been saved, Airbyte will automatically charge the credit card on file at the end of each month's billing period for the subscription amount and any additional usage incurred. + +Once you have entered payment details, additional billing information will be shown: +- Plan +- Account Balance +- Billing Information +- Payment Method +- Invoice History + +### Review Plan +The Plan section shows the Plan you are currently enrolled in. You may reach out to [Sales](https://airbyte.com/company/talk-to-sales) to inquire about Airbyte Teams features or custom discounts. + +### Review Account Balance +In the Account Balance section, you can view: +1. **Upcoming Invoice Amount**: The amount of the upcoming invoice +2. **Invoice Date**: The date of the upcoming invoice +3. **Remaining credits**: The amount of credits that remain on the balance. The credits will be used first before we accrue an invoice amount. This is typically only relevant if you pre-purchased credits before November 2024. + +### Review Billing Information +In the Billing Information section, you can review: +1. The **Billing Email**, which we will use for any invoicing or billing notifications. +2. The **Billing Address**, which we will use to apply any applicable taxes to your invoice. + +To edit the **Billing Email** or **Billing Address**, click **Update**. You will be redirected to the Stripe portal, where you can save any updates. -## View Billing Information -Once you have entered payment details, additional billing information will be shown. On the Organization Billing page, customers can see: -1. **Remaining credits**: The amount of credits that remain on the balance. The credits will be used first before we accrue an invoice amount. -2. **Upcoming Invoice Amount**: The amount of the upcoming invoice -3. **Invoice Date**: The date of the upcoming invoice +### Review Payment Method +In the Payment Method section, you can review the saved **Payment Method** on file. This will be used for any automatic monthly subscription or overage charges. + +To edit the **Payment Method**, click **Update**. You will be redirected to the Stripe portal, where you can save any updates. + +### Review Invoice History +In the Invoices section, you can review any past invoices. All invoices will note an **Invoice Status**. The **Invoice Status** indicates whether the invoice is still awaiting payment or are already paid. + +You can view more details about an individal invoice by clicking **View Invoice**. ## Billing Notifications -Customers can enroll in billing notifications for their organization. The billing notifications available are: +By default, all customers will automatically review upcoming invoice notifications 3 and 7 days before the invoice will be finalized. All billing notifications will be sent to the **Billing Email** in the **Billing Information** section. + +Customers can also optionally enroll in billing notifications for their organization. We highly recommend enrolling in billing notifications to ensure you stay up-to-date on your upcoming invoices. + +The billing notifications available are: - Notify me when a sync consumes over $__ - Notify me when my upcoming invoice has increased __% - Notify me when my upcoming invoice is over $___ @@ -60,24 +97,10 @@ To change your existing notification thresholds, submit the form again. To unenroll, [email us](mailto:billing@airbyte.io) with your request. -## Automatic reload of credits - -You can enroll in automatic top-ups of your credit balance. - -To enroll, [email us](mailto:billing@airbyte.io) with: - -1. A link to your workspace or organization that you'd like to enable this feature for. -2. **Recharge threshold** The number under what credit balance you would like the automatic top up to occur. -3. **Recharge balance** The amount of credits you would like to refill to. - -As an example, if the recharge threshold is 10 credits and recharge balance is 30 credits, anytime your credit balance dips below 10 credits, Airbyte will automatically add enough credits to bring the balance back to 30 credits by charging the difference between your credit balance and 30 credits. - -To take a real example, if: - -1. The credit balance reached 3 credits. -2. 27 credits are automatically charged to the card on file and added to the balance. -3. The ending credit balance is 30 credits. +## Purchasing Credits -Note that the difference between the recharge credit amount and recharge threshold must be at least 20 as our minimum purchase is 20 credits. +:::note +Credits can no longer be pre-purchased. As of November 2024, Airbyte Cloud has moved to in-arrears billing invoiced monthly. +::: -If you are enrolled and want to change your limits or cancel your enrollment, [email us](mailto:billing@airbyte.io). \ No newline at end of file +Purchased credits expire after 12 months after purchase. Purchased credits are used before accruing an invoice for additional usage. Purchased credits can not be used for the monthly subscription fee. \ No newline at end of file diff --git a/docs/cloud/managing-airbyte-cloud/manage-data-residency.md b/docs/cloud/managing-airbyte-cloud/manage-data-residency.md index bbec07165edc..1564d5b27c3b 100644 --- a/docs/cloud/managing-airbyte-cloud/manage-data-residency.md +++ b/docs/cloud/managing-airbyte-cloud/manage-data-residency.md @@ -28,6 +28,10 @@ Depending on your network configuration, you may need to add [IP addresses](/ope ## Choose the data residency for a connection +:::info +As of November 2024, the option to enable a custom data residency for a connection has been deprecated from Airbyte Cloud. +::: + You can additionally choose the data residency for your connection in the connection settings. You can choose the data residency when creating a new connection, or you can set the default data residency for your workspace so that it applies for any new connections moving forward. To choose a custom data residency for your connection, click **Connections** in the Airbyte UI and then select the connection that you want to configure. Navigate to the **Settings** tab, open the **Advanced Settings**, and select the **Data residency** for the connection. @@ -37,3 +41,9 @@ To choose a custom data residency for your connection, click **Connections** in Changes to data residency will not affect any sync in progress. ::: + +## Connector Builder data residency + +The Connector Builder currently processes all data through US data planes, regardless of your workspace's default data residency settings. This limitation applies to the development and testing of connectors within the builder interface. + +If your use case requires strict data residency compliance outside the US, you can still publish a custom connector from the builder which will respect your workspace's data residency settings during syncs. However, you will be unable to verify the connector's behavior within the builder itself. diff --git a/docs/connector-development/cdk-python/basic-concepts.md b/docs/connector-development/cdk-python/basic-concepts.md index a1da6316e21c..1b94b8295c9f 100644 --- a/docs/connector-development/cdk-python/basic-concepts.md +++ b/docs/connector-development/cdk-python/basic-concepts.md @@ -42,11 +42,11 @@ Note that while this is the most flexible way to implement a source connector, i ### The `Stream` Abstract Base Class -An `AbstractSource` also owns a set of `Stream`s. This is populated via the `AbstractSource`'s `streams` [function](https://github.com/airbytehq/airbyte/blob/master/airbyte-cdk/python/airbyte_cdk/sources/abstract_source.py#L63). `Discover` and `Read` rely on this populated set. +An `AbstractSource` also owns a set of `Stream`s. This is populated via the `AbstractSource`'s `streams` [function](https://github.com/airbytehq/airbyte-python-cdk/blob/main//airbyte_cdk/sources/abstract_source.py#L63). `Discover` and `Read` rely on this populated set. -`Discover` returns an `AirbyteCatalog` representing all the distinct resources the underlying API supports. Here is the [entrypoint](https://github.com/airbytehq/airbyte/blob/master/airbyte-cdk/python/airbyte_cdk/sources/abstract_source.py#L74) for those interested in reading the code. See [schemas](https://github.com/airbytehq/airbyte/tree/21116cad97f744f936e503f9af5a59ed3ac59c38/docs/contributing-to-airbyte/python/concepts/schemas.md) for more information on how to declare the schema of a stream. +`Discover` returns an `AirbyteCatalog` representing all the distinct resources the underlying API supports. Here is the [entrypoint](https://github.com/airbytehq/airbyte-python-cdk/blob/main//airbyte_cdk/sources/abstract_source.py#L74) for those interested in reading the code. See [schemas](https://github.com/airbytehq/airbyte/tree/21116cad97f744f936e503f9af5a59ed3ac59c38/docs/contributing-to-airbyte/python/concepts/schemas.md) for more information on how to declare the schema of a stream. -`Read` creates an in-memory stream reading from each of the `AbstractSource`'s streams. Here is the [entrypoint](https://github.com/airbytehq/airbyte/blob/master/airbyte-cdk/python/airbyte_cdk/sources/abstract_source.py#L90) for those interested. +`Read` creates an in-memory stream reading from each of the `AbstractSource`'s streams. Here is the [entrypoint](https://github.com/airbytehq/airbyte-python-cdk/blob/main//airbyte_cdk/sources/abstract_source.py#L90) for those interested. As the code examples show, the `AbstractSource` delegates to the set of `Stream`s it owns to fulfill both `Discover` and `Read`. Thus, implementing `AbstractSource`'s `streams` function is required when using the CDK. diff --git a/docs/connector-development/config-based/advanced-topics.md b/docs/connector-development/config-based/advanced-topics.md index 8626826eef7f..2bd86c58dc70 100644 --- a/docs/connector-development/config-based/advanced-topics.md +++ b/docs/connector-development/config-based/advanced-topics.md @@ -17,12 +17,12 @@ will result in ``` If the component definition is a mapping with a "type" field, -the factory will lookup the [CLASS_TYPES_REGISTRY](https://github.com/airbytehq/airbyte/blob/master/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/class_types_registry.py) and replace the "type" field by "class_name" -> CLASS_TYPES_REGISTRY[type] +the factory will lookup the [CLASS_TYPES_REGISTRY](https://github.com/airbytehq/airbyte-python-cdk/blob/main//airbyte_cdk/sources/declarative/parsers/class_types_registry.py) and replace the "type" field by "class_name" -> CLASS_TYPES_REGISTRY[type] and instantiate the object from the resulting mapping If the component definition is a mapping with neither a "class_name" nor a "type" field, the factory will do a best-effort attempt at inferring the component type by looking up the parent object's constructor type hints. -If the type hint is an interface present in [DEFAULT_IMPLEMENTATIONS_REGISTRY](https://github.com/airbytehq/airbyte/blob/master/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/default_implementation_registry.py), +If the type hint is an interface present in [DEFAULT_IMPLEMENTATIONS_REGISTRY](https://github.com/airbytehq/airbyte-python-cdk/blob/main//airbyte_cdk/sources/declarative/parsers/default_implementation_registry.py), then the factory will create an object of its default implementation. If the component definition is a list, then the factory will iterate over the elements of the list, @@ -242,7 +242,7 @@ Additional information on jinja templating can be found at [https://jinja.pallet ## Component schema reference -A JSON schema representation of the relationships between the components that can be used in the YAML configuration can be found [here](../../../airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_component_schema.yaml). +A JSON schema representation of the relationships between the components that can be used in the YAML configuration can be found [here](https://github.com/airbytehq/airbyte-python-cdk/blob/main/airbyte_cdk/sources/declarative/declarative_component_schema.yaml). ## Custom components @@ -318,4 +318,4 @@ When you receive this error, you can address this by defining the missing field - [Record selector](./understanding-the-yaml-file/record-selector.md) - [Partition routers](./understanding-the-yaml-file/partition-router.md) -- [Source schema](../../../airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_component_schema.yaml) +- [Source schema](https://github.com/airbytehq/airbyte-python-cdk/blob/main/airbyte_cdk/sources/declarative/declarative_component_schema.yaml) diff --git a/docs/connector-development/config-based/low-code-cdk-overview.md b/docs/connector-development/config-based/low-code-cdk-overview.md index b0d241d80624..1b50244d46d8 100644 --- a/docs/connector-development/config-based/low-code-cdk-overview.md +++ b/docs/connector-development/config-based/low-code-cdk-overview.md @@ -129,7 +129,7 @@ For each stream, configure the following components: | Cursor field | | Field to use as stream cursor. Can either be a string, or a list of strings if the cursor is a nested field. | | Transformations | | A set of transformations to be applied on the records read from the source before emitting them to the destination | -For a deep dive into each of the components, refer to [Understanding the YAML file](./understanding-the-yaml-file/yaml-overview.md) or the [full YAML Schema definition](../../../airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_component_schema.yaml) +For a deep dive into each of the components, refer to [Understanding the YAML file](./understanding-the-yaml-file/yaml-overview.md) or the [full YAML Schema definition](https://github.com/airbytehq/airbyte-python-cdk/blob/main/airbyte_cdk/sources/declarative/declarative_component_schema.yaml) ## Tutorial @@ -153,4 +153,4 @@ For examples of production-ready config-based connectors, refer to: ## Reference -The full schema definition for the YAML file can be found [here](https://raw.githubusercontent.com/airbytehq/airbyte/master/airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_component_schema.yaml). +The full schema definition for the YAML file can be found [here](https://raw.githubusercontent.com/airbytehq/airbyte-python-cdk/main/airbyte_cdk/sources/declarative/declarative_component_schema.yaml). diff --git a/docs/connector-development/config-based/understanding-the-yaml-file/partition-router.md b/docs/connector-development/config-based/understanding-the-yaml-file/partition-router.md index 357918cbab79..f4b8891c873f 100644 --- a/docs/connector-development/config-based/understanding-the-yaml-file/partition-router.md +++ b/docs/connector-development/config-based/understanding-the-yaml-file/partition-router.md @@ -119,7 +119,7 @@ Example: ```yaml partition_router: type: SubstreamPartitionRouter - parent_streams_configs: + parent_stream_configs: - stream: "#/repositories_stream" parent_key: "id" partition_field: "repository" diff --git a/docs/connector-development/config-based/understanding-the-yaml-file/reference.md b/docs/connector-development/config-based/understanding-the-yaml-file/reference.md index d33e322444d3..6b51bf304d7f 100644 --- a/docs/connector-development/config-based/understanding-the-yaml-file/reference.md +++ b/docs/connector-development/config-based/understanding-the-yaml-file/reference.md @@ -6,7 +6,7 @@ import schema from "../../../../airbyte-cdk/python/airbyte_cdk/sources/declarati This page lists all components, interpolation variables and interpolation macros that can be used when defining a low code YAML file. -For the technical JSON schema definition that low code manifests are validated against, see [here](https://github.com/airbytehq/airbyte/blob/master/airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_component_schema.yaml). +For the technical JSON schema definition that low code manifests are validated against, see [here](https://github.com/airbytehq/airbyte-python-cdk/blob/main/airbyte_cdk/sources/declarative/declarative_component_schema.yaml). diff --git a/docs/connector-development/config-based/understanding-the-yaml-file/yaml-overview.md b/docs/connector-development/config-based/understanding-the-yaml-file/yaml-overview.md index 643249a7ba1d..4b2484a9336d 100644 --- a/docs/connector-development/config-based/understanding-the-yaml-file/yaml-overview.md +++ b/docs/connector-development/config-based/understanding-the-yaml-file/yaml-overview.md @@ -11,7 +11,7 @@ By default, the schema of a stream's data is defined as a [JSONSchema](https://j Alternately, the stream's data schema can be stored in YAML format inline in the YAML file, by including the optional `schema_loader` key. If the data schema is provided inline, any schema on disk for that stream will be ignored. -More information on how to define a stream's schema can be found [here](../../../../airbyte-cdk/python/airbyte_cdk/sources/declarative/declarative_component_schema.yaml) +More information on how to define a stream's schema can be found [here](https://github.com/airbytehq/airbyte-python-cdk/blob/main/airbyte_cdk/sources/declarative/declarative_component_schema.yaml) The stream object is represented in the YAML file as: diff --git a/docs/connector-development/tutorials/the-hard-way/build-a-connector-the-hard-way.md b/docs/connector-development/tutorials/the-hard-way/build-a-connector-the-hard-way.md index 22f4e37d012d..6e83b07730df 100644 --- a/docs/connector-development/tutorials/the-hard-way/build-a-connector-the-hard-way.md +++ b/docs/connector-development/tutorials/the-hard-way/build-a-connector-the-hard-way.md @@ -20,7 +20,7 @@ demonstrate the following concepts in action: **This tutorial is meant for those interested in learning how the Airbyte Specification works in detail, not for creating production connectors**. If you're building a real source, you should start with using the [Connector Builder](../../connector-builder-ui/overview), or the -[Connector Development Kit](https://github.com/airbytehq/airbyte/tree/master/airbyte-cdk/python/docs/tutorials). +[Connector Development Kit](../../cdk-python/). ::: diff --git a/docs/connector-development/writing-connector-docs.md b/docs/connector-development/writing-connector-docs.md new file mode 100644 index 000000000000..dd5bb4af8003 --- /dev/null +++ b/docs/connector-development/writing-connector-docs.md @@ -0,0 +1,201 @@ +# Writing Connector Documentation + +This topic guides you through writing documentation for Airbyte connectors. The systems and practices described in [Updating Documentation](../contributing-to-airbyte/writing-docs.md) apply here as well. However, there are several features and restrictions that only apply to connectors. + +## QA checks + +If you're writing docs for a new connector, your docs must pass our [QA checks](../contributing-to-airbyte/resources/qa-checks). + +## Custom Markdown extensions for connector docs + +Airbyte's connector documentation must gracefully support different contexts in a way platform documentation doesn't. + +- https://docs.airbyte.com +- In-app documentation in self-managed versions of Airbyte +- In-app documentation in the Cloud version of Airbyte + +Key details about setting up a connection may differ between Cloud and Self-Managed. We created custom Markdown extensions that can show or hide different pieces of content based on the reader's environment. This is a rudimentary form of a concept called single-sourcing: writing content once, but using it in multiple contexts. This prevents us from having to maintain multiple highly similar pools of content. + +The following features for single-sourcing are available. You can combine them to produce a more meaningful result. + +### Hide content from the Airbyte UI + +Some content is important to document, but unhelpful in Airbyte's UI. This could be: + +- Background information that helps people understand a connector but doesn't affect the configuration process +- Edge cases with complex solutions +- Context about each environment, which doesn't need to be seen if you're in that environment + +Wrapping content in `...` tags prevents Airbyte from rendering that content in-app, but https://docs.airbyte.com renders it normally. + +### Hide content from Cloud + +You can hide content from Airbyte Cloud, while still rendering it in Self-Managed and https://docs.airbyte.com. + +```md + + +Only Self-Managed builds of the Airbyte UI will render this content. + + +``` + +### Hide content from Self-Managed + +You can hide content from Airbyte Self-Managed, while still rendering it in Cloud and https://docs.airbyte.com. + +```md + + +Only Cloud builds of the Airbyte UI will render this content. + + +``` + +### Example + +Here's an example where the configuration steps are different in Cloud and Self-Managed. In this case, you want to render everything on https://docs.airbyte.com, but you want in-app content reflect only the environment the user is running. + +```markdown title="connector-doc.md" +# My connector + +This content is rendered everywhere. + + + + + +## For open source: + + + +Only self-managed builds of the Airbyte UI will render this content. + + + + + + +## For Airbyte Cloud: + + + +Only Cloud builds of the Airbyte UI will render this content. + + +``` + +### Testing your content + +To test in-app content in [a local Airbyte build](https://docs.airbyte.com/contributing-to-airbyte/developing-locally/#develop-on-airbyte-webapp), check out the `airbyte` git repository to the same branch and directory as the airbyte platform repository. Development builds fetch connector documentation from your local filesystem, so you can edit their content and view the rendered output in Airbyte. + +To test https://docs.airbyte.com content, [build Docusaurus locally](../contributing-to-airbyte/writing-docs.md#set-up-your-environment). + +## Map the UI to associated content + +Sometimes a field requires more explanation than can be provided in a tooltip. In these cases, use the `` tag to link documentation to a specific UI component. + +When a user selects that field in the UI, the in-app documentation panel automatically scrolls to the related documentation, highlighting all content contained inside the `` tag. + +The `FieldAnchor` syntax accepts a modified version of `jsonpath`, without the conventional `$.` prefix. It looks like this: + +```md title="example-a.md" +## Configuring Widgets + + + +...config-related instructions here... + + +``` + +Taking a more complex example, you can access deeper-nested fields using `jsonpath` expressions syntax: + +```md title="example-b.md" +## Configuring Unstructured Streams + + + +...config-related instructions here... + + +``` + +:::note +The `FieldAnchor` tag only affects in-app content for sources and destinations. It has no effect on https://docs.airbyte.com or any platform content. +::: + +How it works: + +- There must be blank lines between a custom tag like `FieldAnchor` the content it wraps. +- The `field` attribute must be a valid `jsonpath` expression to one of the properties nested under `connectionSpecification.properties` in that connector's `spec.json` or `spec.yaml` file. For example, if the connector spec contains a `connectionSpecification.properties.replication_method.replication_slot`, you would mark the start of the related documentation section with `` and its end with ``. +- Highlight the same section for multiple fields by separating them with commas, like this: ``. +- To highlight a section after the user picks an option from a `oneOf`: use a `field` prop like `path.to.field[value-of-selection-key]`, where the `value-of-selection-key` is the value of a `const` field nested inside that `oneOf`. + + For example, if the specification of the `oneOf` field is: + + ```json + "replication_method": { + "type": "object", + "title": "Update Method", + "oneOf": [ + { + "title": "Read Changes using Binary Log (CDC)", + "required": ["method"], + "properties": { + "method": { + "type": "string", + + "const": "CDC", + "order": 0 + }, + "initial_waiting_seconds": { + "type": "integer", + "title": "Initial Waiting Time in Seconds (Advanced)", + }, + } + }, + { + "title": "Scan Changes with User Defined Cursor", + "required": ["method"], + "properties": { + "method": { + "type": "string", + + "const": "STANDARD", + "order": 0 + } + } + } + ] + } + ``` + + The selection keys are `CDC` and `STANDARD`. Wrap a specific replication method's documentation section with a `...` tag to highlight it if the user selects CDC replication in the UI. + +### Documenting PyAirbyte usage + +PyAirbyte is a Python library that allows you to run syncs within a Python script for a subset of Airbyte's connectors. Documentation around PyAirbyte connectors is automatically generated from the connector's JSON schema spec. There are a few approaches to combine full control over the documentation with automatic generation for common cases: + +- If a connector: + + 1. Is PyAirbyte-enabled (`remoteRegistries.pypi.enabled` is set in the `metadata.yaml` file of the connector), and + 2. Has no second-level heading `Usage with PyAirbyte` in the documentation + + The documentation will be automatically generated and placed above the `Changelog` section. + +- By manually specifying a `Usage with PyAirbyte` section, this is disabled. The following is a good starting point for this section: + +```md + + +## Usage with PyAirbyte + + + + + + +``` + +The `PyAirbyteExample` component will generate a code example that can be run with PyAirbyte, excluding an auto-generated sample configuration based on the configuration schema. The `SpecSchema` component will generate a reference table with the connector's JSON schema spec, like a non-interactive version of the connector form in the UI. It can be used on any docs page. diff --git a/docs/contributing-to-airbyte/developing-locally.md b/docs/contributing-to-airbyte/developing-locally.md index 8b554fce5281..68fbc19a11ef 100644 --- a/docs/contributing-to-airbyte/developing-locally.md +++ b/docs/contributing-to-airbyte/developing-locally.md @@ -286,23 +286,21 @@ The command to run formatting varies slightly depending on which part of the cod ### Connector -We wrapped all our code formatting tools in [airbyte-ci](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md). -Follow the instructions on the `airbyte-ci` page to install `airbyte-ci`. +We wrapped our code formatting tools in [pre-commit](https://pre-commit.com). You can install this and other local dev tools by running `make tools.install`. -You can run `airbyte-ci format fix all` to format all the code your local `airbyte` repository. -We wrapped this command in a pre-push hook so that you can't push code that is not formatted. +You can run `pre-commit` to format modified files, or `pre-commit run --all-files` to format all the code your local `airbyte` repository. -To install the pre-push hook, run: +We wrapped this command in a pre-push hook which you can enable with: ```bash -make tools.pre-commit.setup +make tools.git-hooks.install ``` -This will install `airbyte-ci` and the pre-push hook. +You can also uninstall git hooks with: -The pre-push hook runs formatting on all the repo files. -If the hook attempts to format a file that is not part of your contribution, it means that formatting is also broken in -the master branch. Please open a separate PR to fix the formatting in the master branch. +```bash +make tools.git-hooks.clean +``` ### Platform diff --git a/docs/contributing-to-airbyte/resources/code-formatting.md b/docs/contributing-to-airbyte/resources/code-formatting.md index 65bb10e5aaac..c56fcd9eb98d 100644 --- a/docs/contributing-to-airbyte/resources/code-formatting.md +++ b/docs/contributing-to-airbyte/resources/code-formatting.md @@ -4,12 +4,11 @@ ### 🐍 Python -We format our Python code using: +We use [Ruff](https://docs.astral.sh) for Python code formatting and import sorting. Our Ruff configuration is in the [pyproject.toml](https://github.com/airbytehq/airbyte/blob/master/pyproject.toml) file. -- [Black](https://github.com/psf/black) for code formatting -- [isort](https://pycqa.github.io/isort/) for import sorting +Ruff is monorepo-friendly and supports nested inherited configuration; each sub-project can optionally override Ruff lint and formatting settings in their own `pyproject.toml` files, as needed per project. -Our configuration for both tools is in the [pyproject.toml](https://github.com/airbytehq/airbyte/blob/master/pyproject.toml) file. +Ruff [auto-detects the proper package classification](https://docs.astral.sh/ruff/faq/#how-does-ruff-determine-which-of-my-imports-are-first-party-third-party-etc) so that "local", "first party" and "third party" imports are sorted and grouped correctly, even within subprojects of the monorepo. ### ☕ Java @@ -20,28 +19,28 @@ Our configuration for Spotless is in the [spotless-maven-pom.xml](https://github We format our Json and Yaml files using [prettier](https://prettier.io/). -## Pre-push hooks and CI +### Local Formatting -We wrapped all our code formatting tools in [airbyte-ci](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md). -### Local formatting +We wrapped our code formatting tools in [pre-commit](https://pre-commit.com). You can install this and other local dev tools by running `make tools.install`. -You can run `airbyte-ci format fix all` to format all the code in the repository. -We wrapped this command in a pre-push hook so that you can't push code that is not formatted. +You can execute `pre-commit` to format modified files, or `pre-commit run --all-files` to format all the code your local `airbyte` repository. -To install the pre-push hook, run: +## Pre-push Git Hooks + +A pre-push git hook is available, which you can enable with: ```bash -make tools.pre-commit.setup +make tools.git-hooks.install ``` -This will install `airbyte-ci` and the pre-push hook. +You can also uninstall git hooks with: -The pre-push hook runs formatting on all the repo files. -If the hook attempts to format a file that is not part of your contribution, it means that formatting is also broken in the master branch. Please open a separate PR to fix the formatting in the master branch. +```bash +make tools.git-hooks.clean +``` -### CI checks +### CI Checks and `/format-fix` Slash Command -In the CI we run the `airbyte-ci format check all` command to check that all the code is formatted. -If it is not, the CI will fail and you will have to run `airbyte-ci format fix all` locally to fix the formatting issues. -Failure on the CI is not expected if you installed the pre-push hook. +In the CI we run the `pre-commit run --all-files` command to check that all the code is formatted. +If it is not, CI will fail and you will have to run `pre-commit run --all-files` locally to fix the formatting issues. Alternatively, maintainers with write permissions can run the `/format-fix` GitHub slash command to auto-format the entire repo and commit the result back to the open PR. diff --git a/docs/contributing-to-airbyte/resources/qa-checks.md b/docs/contributing-to-airbyte/resources/qa-checks.md index 6d0ceaeb3a82..f52e7524a411 100644 --- a/docs/contributing-to-airbyte/resources/qa-checks.md +++ b/docs/contributing-to-airbyte/resources/qa-checks.md @@ -4,27 +4,30 @@ This document is listing all the static-analysis checks that are performed on th These checks are running in our CI/CD pipeline and are used to ensure a connector is following the best practices and is respecting the Airbyte standards. Meeting these standards means that the connector will be able to be safely integrated into the Airbyte platform and released to registries (DockerHub, Pypi etc.). You can consider these checks as a set of guidelines to follow when developing a connector. -They are by no mean replacing the need for a manual review of the connector codebase and the implementation of good test suites. +They do not replace the need for a manual review of the connector codebase and the implementation of good test suites. ## 📄 Documentation -### Breaking changes must be accompanied by a migration guide +### Major version upgrades must be accompanied by a migration guide _Applies to the following connector types: source, destination_ + _Applies to the following connector languages: java, low-code, python, manifest-only_ + _Applies to connector with any support level_ -_Applies to connector with 100 internal support level_ + _Applies to connector with any Airbyte usage level_ -When a breaking change is introduced, we check that a migration guide is available. It should be stored under `./docs/integrations/s/-migrations.md`. -This document should contain a section for each breaking change, in order of the version descending. It must explain users which action to take to migrate to the new version. +When a connector experiences a major version upgrade, we check that a migration guide is available. It should be stored under `./docs/integrations/s/-migrations.md`. This document should contain a section for each major change, ordered by descending version. It must explain which action to take to migrate to the new version. ### Connectors must have user facing documentation _Applies to the following connector types: source, destination_ + _Applies to the following connector languages: java, low-code, python, manifest-only_ + _Applies to connector with any support level_ -_Applies to connector with 100 internal support level_ + _Applies to connector with any Airbyte usage level_ The user facing connector documentation should be stored under `./docs/integrations/s/.md`. @@ -32,9 +35,11 @@ The user facing connector documentation should be stored under `./docs/integrati ### Links used in connector documentation are valid _Applies to the following connector types: source_ + _Applies to the following connector languages: python, low-code_ + _Applies to connector with any support level_ -_Applies to connector with 300 internal support level_ + _Applies to connector with any Airbyte usage level_ The user facing connector documentation should update invalid links in connector documentation. For links that are used as example and return 404 status code, use `example: ` before link to skip it. @@ -42,61 +47,58 @@ The user facing connector documentation should update invalid links in connector ### Connectors documentation headers structure, naming and order follow our guidelines _Applies to the following connector types: source_ + _Applies to the following connector languages: python, low-code_ + _Applies to connector with any support level_ -_Applies to connector with 300 internal support level_ + _Applies to connector with any Airbyte usage level_ The user facing connector documentation should follow the guidelines defined in the [standard template](../../../airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/documentation/templates/template.md.j2). This check expects the following order of headers in the documentation: -```` - - - # CONNECTOR_NAME_FROM_METADATA +```md +# CONNECTOR_NAME_FROM_METADATA - ## Prerequisites +## Prerequisites - ## Setup guide +## Setup guide - ## Set up CONNECTOR_NAME_FROM_METADATA +## Set up CONNECTOR_NAME_FROM_METADATA - ### For Airbyte Cloud: +### For Airbyte Cloud: - ### For Airbyte Open Source: +### For Airbyte Open Source: - ### CONNECTOR_SPECIFIC_FEATURES +### CONNECTOR_SPECIFIC_FEATURES - ## Set up the CONNECTOR_NAME_FROM_METADATA connector in Airbyte +## Set up the CONNECTOR_NAME_FROM_METADATA connector in Airbyte - ### For Airbyte Cloud: +### For Airbyte Cloud: - ### For Airbyte Open Source: +### For Airbyte Open Source: - ## CONNECTOR_SPECIFIC_FEATURES +## CONNECTOR_SPECIFIC_FEATURES - ## Supported sync modes +## Supported sync modes - ## Supported Streams +## Supported Streams - ## CONNECTOR_SPECIFIC_FEATURES +## CONNECTOR_SPECIFIC_FEATURES - ### Performance considerations +### Performance considerations - ## Data type map +## Data type map - ## Limitations & Troubleshooting +## Limitations & Troubleshooting - ### CONNECTOR_SPECIFIC_FEATURES +### CONNECTOR_SPECIFIC_FEATURES - ### Tutorials - - ## Changelog - - -```` +### Tutorials +## Changelog +``` List of not required headers, which can be not exist in the documentation and their strict check will be skipped: @@ -120,138 +122,141 @@ List of not required headers, which can be not exist in the documentation and th ### Prerequisites section of the documentation describes all required fields from specification _Applies to the following connector types: source_ + _Applies to the following connector languages: python, low-code_ + _Applies to connector with any support level_ -_Applies to connector with 300 internal support level_ + _Applies to connector with any Airbyte usage level_ The user facing connector documentation should update `Prerequisites` section with description for all required fields from source specification. Having described all required fields in a one place helps Airbyte users easily set up the source connector. -If spec has required credentials/access_token/refresh_token etc, check searches for one of ["account", "auth", "credentials", "access", "client"] words. No need to add credentials/access_token/refresh_token etc to the section +If spec has required credentials/access_token/refresh_token etc, check searches for one of `["account", "auth", "credentials", "access", "client"]` words. No need to add credentials/access_token/refresh_token etc to the section ### Main Source Section of the documentation follows our guidelines _Applies to the following connector types: source_ + _Applies to the following connector languages: python, low-code_ + _Applies to connector with any support level_ -_Applies to connector with 300 internal support level_ + _Applies to connector with any Airbyte usage level_ The user facing connector documentation should follow the guidelines defined in the [standard template](../../../airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/documentation/templates/template.md.j2). Check verifies that CONNECTOR_NAME_FROM_METADATA header section content follows standard template: -```` - +```md This page contains the setup guide and reference information for the [CONNECTOR_NAME_FROM_METADATA]({docs_link}) source connector. - - -```` +``` ### 'For Airbyte Cloud:' section of the documentation follows our guidelines _Applies to the following connector types: source_ + _Applies to the following connector languages: python, low-code_ + _Applies to connector with any support level_ -_Applies to connector with 300 internal support level_ + _Applies to connector with any Airbyte usage level_ The user facing connector documentation should follow the guidelines defined in the [standard template](../../../airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/documentation/templates/template.md.j2). Check verifies that For Airbyte Cloud: header section content follows standard template: -```` - +```md 1. [Log into your Airbyte Cloud](https://cloud.airbyte.com/workspaces) account. 2. Click Sources and then click + New source. 3. On the Set up the source page, select CONNECTOR_NAME_FROM_METADATA from the Source type dropdown. 4. Enter a name for the CONNECTOR_NAME_FROM_METADATA connector. - ```` ### 'For Airbyte Open Source:' section of the documentation follows our guidelines _Applies to the following connector types: source_ + _Applies to the following connector languages: python, low-code_ + _Applies to connector with any support level_ -_Applies to connector with 300 internal support level_ + _Applies to connector with any Airbyte usage level_ The user facing connector documentation should follow the guidelines defined in the [standard template](../../../airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/documentation/templates/template.md.j2). Check verifies that For Airbyte Open Source: header section content follows standard template: -```` - +```md 1. Navigate to the Airbyte Open Source dashboard. - ```` ### 'Supported sync modes' section of the documentation follows our guidelines _Applies to the following connector types: source_ + _Applies to the following connector languages: python, low-code_ + _Applies to connector with any support level_ -_Applies to connector with 300 internal support level_ + _Applies to connector with any Airbyte usage level_ The user facing connector documentation should follow the guidelines defined in the [standard template](../../../airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/documentation/templates/template.md.j2). Check verifies that Supported sync modes header section content follows standard template: -```` - +```md The CONNECTOR_NAME_FROM_METADATA source connector supports the following [sync modes](https://docs.airbyte.com/cloud/core-concepts/#connection-sync-modes): - - -```` +``` ### 'Tutorials' section of the documentation follows our guidelines _Applies to the following connector types: source_ + _Applies to the following connector languages: python, low-code_ + _Applies to connector with any support level_ -_Applies to connector with 300 internal support level_ + _Applies to connector with any Airbyte usage level_ The user facing connector documentation should follow the guidelines defined in the [standard template](../../../airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/documentation/templates/template.md.j2). Check verifies that Tutorials header section content follows standard template: -```` - +```md Now that you have set up the CONNECTOR_NAME_FROM_METADATA source connector, check out the following CONNECTOR_NAME_FROM_METADATA tutorials: - - -```` +``` ### 'Changelog' section of the documentation follows our guidelines _Applies to the following connector types: source_ + _Applies to the following connector languages: python, low-code_ + _Applies to connector with any support level_ -_Applies to connector with 300 internal support level_ + _Applies to connector with any Airbyte usage level_ The user facing connector documentation should follow the guidelines defined in the [standard template](../../../airbyte-ci/connectors/connectors_qa/src/connectors_qa/checks/documentation/templates/template.md.j2). Check verifies that Changelog header section content follows standard template: -```` +```md
Expand to review
-```` +``` ### Connectors must have a changelog entry for each version _Applies to the following connector types: source, destination_ + _Applies to the following connector languages: java, low-code, python, manifest-only_ + _Applies to connector with any support level_ -_Applies to connector with 100 internal support level_ + _Applies to connector with any Airbyte usage level_ Each new version of a connector must have a changelog entry defined in the user facing documentation in `./docs/integrations/s/.md`. @@ -288,7 +293,7 @@ _Applies to connector with any Airbyte usage level_ Python connectors must have a CDK tag in their metadata. It must be set in the `tags` field in metadata.yaml. The values can be `cdk:low-code`, `cdk:python`, or `cdk:file`. -### Breaking change deadline should be a week in the future +### Major version upgrade deadline should be a week in the future _Applies to the following connector types: source, destination_ _Applies to the following connector languages: java, low-code, python, manifest-only_ @@ -296,7 +301,7 @@ _Applies to connector with any support level_ _Applies to connector with any internal support level_ _Applies to connector with any Airbyte usage level_ -If the connector version has a breaking change, the deadline field must be set to at least a week in the future. +If this is a major version upgrade, the deadline field must be set to at least a week in the future. ### Certified source connector must have a value filled out for maxSecondsBetweenMessages in metadata diff --git a/docs/contributing-to-airbyte/writing-docs.md b/docs/contributing-to-airbyte/writing-docs.md index 55a004f02581..5ebb35c4a3c5 100644 --- a/docs/contributing-to-airbyte/writing-docs.md +++ b/docs/contributing-to-airbyte/writing-docs.md @@ -1,48 +1,66 @@ import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; -# Updating Documentation +# Updating documentation -We welcome contributions to the Airbyte documentation! +Everyone is welcome to contribute to Airbyte's documentation! -Our docs are written in [Markdown](https://guides.github.com/features/mastering-markdown/) following the [Google developer documentation style guide](https://developers.google.com/style/highlights) and the files are stored in our [Github repository](https://github.com/airbytehq/airbyte/tree/master/docs). The docs are published at [docs.airbyte.com](https://docs.airbyte.com/) using [Docusaurus](https://docusaurus.io/) and [GitHub Pages](https://pages.github.com/). +Our documentation is stored in the [Airbyte repository](https://github.com/airbytehq/airbyte/tree/master/docs) on GitHub. It's published at [docs.airbyte.com](https://docs.airbyte.com/) using [GitHub Pages](https://pages.github.com/). Connector docs are also rendered within Airbyte itself when setting up new connectors. The docs are built on [Docusaurus](https://docusaurus.io/). Content is written in [Markdown](https://guides.github.com/features/mastering-markdown/) and all topics are in the `/docs` folder. Configuration files are in the `/docusaurus` folder. -## Finding good first issues +## Open source contributions welcome -Before contributing to Airbyte docs, read the Airbyte Community [Code of Conduct](../community/code-of-conduct.md). +Open source contributors are a vital part of Airbyte. Technical writers are welcome to use any content you author in your portfolio. -The Docs team maintains a list of [good first issues](https://github.com/airbytehq/airbyte/issues?q=is%3Aopen+is%3Aissue+label%3Aarea%2Fdocumentation+label%3A%22good+first+issue%22) for new contributors. +If you're interested in becoming a regular contributor, join Airbyte's [Contributor program](https://airbyte.com/community/contributor-program). We pay for high-quality work on select issues. AI-generated content isn't eligible for the contributor program. You're welcome to use AI as a research tool and editing partner, but paid submissions must be principally human-generated. -- If you're new to technical writing, start with the smaller issues (fixing typos, broken links, spelling and grammar, and so on). You can [edit the files directly on GitHub](#editing-directly-on-github). -- If you're an experienced technical writer or a developer interested in technical writing, comment on an issue that interests you to discuss it with the Docs team. Once we decide on the approach and the tasks involved, [edit the files and open a Pull Request](#editing-on-your-local-machine) for the Docs team to review. +## Before you start -:::tip -If you're new to GitHub and Markdown, complete [the First Contributions tutorial](https://github.com/firstcontributions/first-contributions) and learn [Markdown basics](https://guides.github.com/features/mastering-markdown/) before contributing to Airbyte documentation. Even if you're familiar with the basics, you may be interested in Airbyte's [custom markdown extensions for connector docs](#custom-markdown-extensions-for-connector-docs). -::: +Before you contribute, familiarize yourself with these concepts. -### Editing directly on GitHub +### Read our code of conduct -To make minor changes (example: fixing typos) or edit a single file, you can edit the file directly on GitHub: +Read the Airbyte Community [code of conduct](../community/code-of-conduct.md). -1. Click **Edit this page** at the bottom of any published document on [docs.airbyte.com](https://docs.airbyte.com/). You'll be taken to the GitHub editor. -2. [Edit the file directly on GitHub and open a Pull Request](https://docs.github.com/en/repositories/working-with-files/managing-files/editing-files). +### Learn Docusaurus basics -### Editing on your local machine +Even if you've never used it before, most developers and technical writers find Docusaurus intuitive. -#### Prerequisites +- [Markdown basics](https://guides.github.com/features/mastering-markdown/) +- [Docusaurus 5-minute tutorial](https://tutorial.docusaurus.io/) -To contribute to our documentation, please ensure following required technologies are installed on your local machine: +### Style guide -1. [`Node.js`](https://nodejs.org/en/learn/getting-started/how-to-install-nodejs) -2. [`pnpm`](https://pnpm.io/installation) +Follow the [Google developer documentation style guide](https://developers.google.com/style/highlights). It's a widely adopted style guide with good examples and easy-to-follow rules. We don't enforce these rules with automation, but might in the future. Fow now, just try to follow it to the best of your ability. + +### Find a good first issue + +The Docs team maintains a list of [good first issues](https://github.com/airbytehq/airbyte/issues?q=is%3Aopen+is%3Aissue+label%3Aarea%2Fdocumentation+label%3A%22good+first+issue%22) for new contributors. If you'd like to start a complex documentation project, create or comment on a [GitHub issue](https://github.com/airbytehq/airbyte/issues) and tag [@ian-at-airbyte](https://github.com/ian-at-airbyte) so we can decide on an approach together. -#### Setup and Making Changes +## Edit files directly on GitHub -To make complex changes or edit multiple files, edit the files on your local machine: +To make minor changes like fixing typos or editing a single file, you can edit the file directly in your browser. -1. [Fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the Airbyte [repository](https://github.com/airbytehq/airbyte). +1. Click **Edit this page** at the bottom of any page on [docs.airbyte.com](https://docs.airbyte.com/). You'll be taken to the GitHub editor. +2. Edit the file directly on GitHub and open a Pull Request ([help](https://docs.github.com/en/repositories/working-with-files/managing-files/editing-files)). -2. Clone the fork on your local machine: +## Edit files on your local machine + +If you're making substantial documentation changes, it's best to clone the repository and work locally so you can test as you work. + +### Prerequisites + +Install these tools on your local machine, first. + +1. [Node.js](https://nodejs.org/en/learn/getting-started/how-to-install-nodejs) +2. [`pnpm`](https://pnpm.io/installation) +3. A tool to work with GitHub, like [Git](https://git-scm.com/) or [GitHub Desktop](https://github.com/apps/desktop) +4. A code editor, like [Visual Studio Code](https://code.visualstudio.com/). + +### Fork and clone the repo + +1. [Fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the [Airbyte repo](https://github.com/airbytehq/airbyte). + +2. Clone the fork on your local machine. ```bash git clone git@github.com:{YOUR_USERNAME}/airbyte.git @@ -56,408 +74,230 @@ To make complex changes or edit multiple files, edit the files on your local mac cd airbyte ``` -3. Create a feature branch from which to make changes: +3. Create a feature branch. ```bash git checkout -b {YOUR_USERNAME}/{FEATURE/BUG} ``` - (e.g. `jdoe/source-stock-api-stream-fix`) - -4. Test changes locally: - - To install the docs locally, run the following commands in your terminal: + For example: ```bash - cd docusaurus - pnpm install + git checkout -b jdoe/source-stock-api-stream-fix ``` - To see changes as you make them, run: +### Set up your environment + +Open a terminal and install the docs locally. + +```bash +cd docusaurus +pnpm install +``` + +To see changes as you make them in a dev build: + +1. Run: ```bash pnpm start ``` - Then navigate to [http://localhost:3005/](http://localhost:3005/). Whenever you make and save changes, you will see them reflected in the server. You can stop the running server in OSX/Linux by pressing `Ctrl-C` in the terminal. +2. Navigate to [http://localhost:3005/](http://localhost:3005/). Whenever you make and save changes, you will see them reflected in the server. To stop the running server, press Ctrl+C in the terminal. + +To create an optimized production build that does not update automatically: - You can also build the docs locally and see the resulting changes. This is useful if you introduce changes that need to be run at build-time (e.g. adding a docs plug-in). To do so, run: +1. Run: ```bash pnpm build pnpm serve ``` - Then navigate to [http://localhost:3000/](http://localhost:3000/) to see your changes. You can stop the running server in OSX/Linux by pressing `Ctrl-C` in the terminal. +2. Navigate to [http://localhost:3000/](http://localhost:3000/) to see your changes. To stop the running server, press Ctrl+C in the terminal. -5. [Follow the GitHub workflow](https://docs.github.com/en/get-started/quickstart/contributing-to-projects/) to edit the files and create a pull request. +### Author content - :::note - Before we accept any contributions, you'll need to sign the Contributor License Agreement (CLA). By signing a CLA, we can ensure that the community is free and confident in its ability to use your contributions. You will be prompted to sign the CLA while opening a pull request. - ::: +[Follow the basic GitHub workflow](https://docs.github.com/en/get-started/quickstart/contributing-to-projects/) to update content: branch, write, commit, pull request, merge. -6. Assign `airbytehq/docs` as a Reviewer for your pull request. +## Content templates -### Custom markdown extensions for connector docs +Every page must have a purpose. Bad documentation often has origins in: -Airbyte's markdown documentation—particularly connector-specific documentation—needs to gracefully support multiple different contexts: key details may differ between open-source builds and Airbyte Cloud, and the more exhaustive explanations appropriate for https://docs.airbyte.com may bury key details when rendered as inline documentation within the Airbyte application. In order to support all these different contexts without resorting to multiple overlapping files that must be maintained in parallel, Airbyte's documentation tooling supports multiple nonstandard features. - -Please familiarize yourself with all the tools available to you when writing documentation for a connector, so that you can provide appropriately tailored information to your readers in whichever context they see it. - -:::note -As a general rule, features that introduce new behavior or prevent certain content from rendering will affect how the Airbyte UI displays markdown content, but have no impact on https://docs.airbyte.com. If you want to test out these in-app features in [a local Airbyte build](https://docs.airbyte.com/contributing-to-airbyte/developing-locally/#develop-on-airbyte-webapp), ensure that you have the `airbyte` git repository checked out to the same parent directory as the airbyte platform repository: if so, development builds will by default fetch connector documentation from your local filesystem, allowing you to freely edit their content and view the rendered output. -::: +- Poorly-defined goals, or no goal +- Failed execution of otherwise good goals +- The intimidating effect of a blank page -#### Select between mutually-exclusive content options with `` +The [Good Docs Project](https://www.thegooddocsproject.dev/) maintains a collection of open-source docs templates you can use to help you write and update articles. Here are common patterns we see at Airbyte: -Tabs are a built-in feature of Docusaurus, the tool we use to build `https://docs.airbyte.com`; please refer to [their documentation](https://docusaurus.io/docs/markdown-features/tabs) for their options and behavior in this context. For better site-agnostic documentation, and because we like the feature, we maintain a separate `Tabs` implementation with limited, one-way API compatibility: all usage options we document should behave the same in-app and on `https://docs.airbyte.com`. If you find a discrepancy or breakage, we would appreciate if you [report it as a bug](https://github.com/airbytehq/airbyte/issues/new?assignees=&labels=type%2Fenhancement%2Carea%2Fdocumentation+needs-triage&projects=&template=8-documentation.yaml)! The reverse is not necessarily true, however: Docusaurus supports many use cases besides ours, so supporting its every usage pattern is a deliberate non-goal. +| Purpose | Overview | Template | +| --------------- | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | +| Concept | Explain a concept, context, or background information about a product or its features. | [Template](https://gitlab.com/tgdp/templates/-/tree/main/concept) | +| How-to | A concise set of numbered steps to do one task with the product. | [Template](https://gitlab.com/tgdp/templates/-/tree/main/how-to) | +| Tutorial | Instructions to set up an example project intended for hands-on learning. | [Template](https://gitlab.com/tgdp/templates/-/tree/main/tutorial) | +| Troubleshooting | Common problems experienced by users, an explanation of the causes, and steps to resolve the issue. | [Template](https://gitlab.com/tgdp/templates/-/tree/main/troubleshooting) | +| Reference | Specific, in-depth details about a particular topic. | [Template](https://gitlab.com/tgdp/templates/-/tree/main/reference) | +| Release note | Communicate new features, improvements, bug fixes, and known issues about a product. | [Template](https://gitlab.com/tgdp/templates/-/tree/main/release-notes) | -:::info -Because Docusaurus uses an mdx component, you must include the following import lines in any markdown file which uses tabs: +[View all templates](https://www.thegooddocsproject.dev/template). -```js -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; -``` - -This is not optional: if these lines are missing, the documentation site will have errors. They won't show up in the rendered document, however. +:::important +These templates can only be used for platform docs. Docs for connectors have their own template. See [Write connector docs](#connector-docs) for more details. ::: -Here's an example set of tabs; note that you can put any number of `...` tags inside a ``. +## Write connector docs {#connector-docs} -```md - - +If you're writing docs for a data source or destination, there are special rules you must follow. See the [Connector Documentation Guide](../connector-development/writing-connector-docs.md). Platform documentation is less formulaic. -When configuring this hypothetical connector using basic HTTP auth, you should mind some tricky security considerations! This just a hypothetical, though, so I never bothered to come up with any. +## Common patterns and components -As the first tab, this would be shown by default if no `TabItem` were marked as `default`. +Since the docs site is based on Docusaurus, it inherits all of Docusaurus' capabilities. There are also some Airbyte-specific elements to be aware of. Most of these customizations can be combined together. - - +### Tabs -When configuring this hypothetical connector using OAuth authentication, you should do a dance. Good for you! Since it's not the first `TabItem` in its set, we had to explicitly mark this tab as `default` for it to get top billing. - - - -``` - -That renders as the following: - - - - -When configuring this hypothetical connector using basic HTTP auth, you should mind some tricky security considerations! This just a hypothetical, though, so I never bothered to come up with any. - -As the first tab, this would be shown by default if no `TabItem` were marked as `default`. - - - - -When configuring this hypothetical connector using OAuth authentication, you should do a dance. Good for you! Since it's not the first `TabItem` in its set, we had to explicitly mark this tab as `default` for it to get top billing. - - - - -- You don't need to mark any tab as `default` -- If you don't, the first tab (here, Basic HTTP) will be the initial selection instead -- You can use ordinary markdown syntax inside a `TabItem` -- **however**, due to bugs in our in-app markdown rendering library, you should be dilligent about using empty lines to separate different formatting-related things (surrounding tags and their contents, paragraphs vs lists, etc) -- You should also avoid indenting `TabItem` tags and their content according to html conventions, since text indented by four spaces (common for html nested inside two levels of tags) can be interpreted as a code block; different markdown rendering tools can handle this inconsistently. - -#### Jump to the relevant documentation section when specific connector setup inputs are focused with `` - -In the documentation, the relevant section needs to be wrapped in a `` component. When a user focuses the field identified by the `field` attribute in the connector setup UI, the documentation pane will automatically scroll to the associated section of the documentation, highlighting all content contained inside the `` tag. These are rendered as regular divs in the documentation site, so they have no effect in places other than the in-app documentation panel—however, note that there must be blank lines between a custom tag like `FieldAnchor` the content it wraps for the documentation site to render markdown syntax inside the custom tag to html. - -The `field` attribute must be a valid json path to one of the properties nested under `connectionSpecification.properties` in that connector's `spec.json` or `spec.yaml` file. For example, if the connector spec contains a `connectionSpecification.properties.replication_method.replication_slot`, you would mark the start of the related documentation section with `` and its end with ``. It's also possible to highlight the same section for multiple fields by separating them with commas, like ``. To mark a section as highlighted after the user picks an option from a `oneOf`: use a `field` prop like `path.to.field[value-of-selection-key]`, where the `value-of-selection-key` is the value of a `const` field nested inside that `oneOf`. For example, if the specification of the `oneOf` field is: - -```json -"replication_method": { - "type": "object", - "title": "Update Method", - "oneOf": [ - { - "title": "Read Changes using Binary Log (CDC)", - "required": ["method"], - "properties": { - "method": { - "type": "string", - "const": "CDC", - "order": 0 - }, - "initial_waiting_seconds": { - "type": "integer", - "title": "Initial Waiting Time in Seconds (Advanced)", - }, - } - }, - { - "title": "Scan Changes with User Defined Cursor", - "required": ["method"], - "properties": { - "method": { - "type": "string", - "const": "STANDARD", - "order": 0 - } - } - } - ] -} -``` +Use tabs to display mutually-exclusive concepts in a concise way. See [Tabs](https://docusaurus.io/docs/markdown-features/tabs). -The selection keys are `CDC` and `STANDARD`, so you can wrap a specific replication method's documentation section with a `...` tag, and it will be highlighted if the user selects CDC replication in the UI. +:::note +We maintain a separate `Tabs` implementation to support rendering tabs in Airbyte's in-app documentation. Our in-app renderer creates some additional rules that aren't necessarily true in other Docusaurus implementations: -:::tip -Because of their close connection with the connector setup form fields, `` tags are only enabled for the source and destination setup pages. +- Always use empty lines to separate different Markup elements (tags, paragraphs, lists, etc.) +- Do not indent `TabItem` tags and their content according to normal HTML conventions. Different Markdown rendering tools handle indented tags inconsistently. ::: -#### Prevent specific content from rendering in the UI with `` - -Certain content is important to document, but unhelpful in the context of the Airbyte UI's inline documentation views: - -- background information that helps users understand a connector but doesn't affect configuration -- edge cases that are unusual but time-consuming to solve -- context for readers on the documentation site about environment-specific content (see [below](#environment-specific-in-app-content-with-magic-html-comments)) - -Wrapping such content in a pair of `...` tags will prevent it from being rendered within the Airbyte UI without affecting its presentation on https://docs.airbyte.com. This allows a single markdown file to be the source of truth for both a streamlined in-app reference and a more thorough treatment on the documentation website. +### Code blocks -#### Environment-specific in-app content with magic html comments +Code blocks are used to represent sample code and command line input and output with easy-to-read syntax highlighting. See [Code blocks](https://docusaurus.io/docs/markdown-features/code-blocks). -Sometimes, there are connector setup instructions which differ between open-source Airbyte builds and Airbyte Cloud. Document both cases, but wrap each in a pair of special HTML comments: +Not all languages are turned on. If syntax highlighting doesn't work for your language, add it to `docusaurus/docusaurus.config.js`'s `module.exports.themeConfig.prism.additionalLanguages` property. Then, restart your local server to test the new language. -```md - - +### Admonitions (notes, warnings, tips, etc.) -## For open source: +Docusaurus has custom markup to create a note, warning, tip, danger, or info block. See [Admonitions](https://docusaurus.io/docs/markdown-features/admonitions). - +### Expandable details panels -Only open-source builds of the Airbyte UI will render this content. +Details panels are a great way to render content that's not relevant to everyone, or to condense long pages. See [Details](https://docusaurus.io/docs/markdown-features#details). - +### Product badges - - +Some platform features are reserved for certain Airbyte products. To avoid confusion and indicate which products a topic applies to, pages can display badges in a prominent location under the title. [This page is an example](../using-airbyte/getting-started/oss-quickstart). -## For Airbyte Cloud: +To enable badges, include `products` in the Markdown metadata. The following values are possible, and you can combine them as needed. - - -Only cloud builds of the Airbyte UI will render this content. - - - -Content outside of the magic-comment-delimited blocks will be rendered everywhere. -``` +- `all`: Self-Managed Community, Self-Managed Enterprise, and Cloud +- `oss-community`: Self-Managed Community only +- `oss-enterprise`: Self-Managed Enterprise only +- `cloud`: Cloud only +- `cloud-teams`: Cloud Teams only -Note that the documentation site will render _all_ environment-specific content, so please introduce environment-specific variants with some documentation-site-only context (like the hidden subheadings in the example above) to disambiguate. +In this example, the Self-Managed Community badge is highlighted, and Cloud and Self-Managed Enterprise badges are grayed out. -#### Contextually-styled callouts with admonition blocks - -We have added support for [Docusaurus' admonition syntax](https://docusaurus.io/docs/markdown-features/admonitions) to Airbyte's in-app markdown renderer. - -To make an admonition, wrap text with lines of three colons, with the first colons immediately followed (no space) by a tag specifying the callout's semantic styling, which will be one of `tip`, `warning`, `caution`, `danger`, `note`, or `info`. The syntax parallells a code block's, but with colons instead of backticks. - -Examples of the different admonition types: - -```md -:::note +```markdown +--- +products: oss-community +--- -A **note** with _Markdown_ `syntax`. +# This topic is only for Self-Managed Community -::: +Some text. ``` -:::note - -A **note** with _Markdown_ `syntax`. +In this example, the Self-Managed Community badge is grayed out, but the Cloud Teams and Self-Managed Enterprise badges are highlighted. -::: - -```md -:::tip +```markdown +--- +products: cloud-teams, oss-enterprise +--- -A **tip** with _Markdown_ `syntax`. +# This topic is only for Cloud Teams and Self-Managed Enterprise -::: +Some text. ``` -:::tip +### Diagrams -A **tip** with _Markdown_ `syntax`. +The [Mermaid](https://mermaid.js.org/) plugin runs on our Docusaurus instance. If possible, you should create diagrams with Mermaid, because they're easier to build, maintain, and translate. They're also more suitable for assistive technologies like screen readers. +:::warning +Connector docs do **not** support Mermaid. Mermaid can also be unsuitable for complex diagrams, where you need more visual control. If Mermaid can't meet your needs, create an SVG diagram or use Whimsical. Airbyte employees have access to a paid Whimsical account with Airbyte's color palette built in. ::: -```md -:::info +Here is an example of how to create a Mermaid diagram: -Some **info** with _Markdown_ `syntax`. +Add a code block to your Markdown and specify `mermaid` as the language. -::: +````md +```mermaid +--- +title: Order example +--- +erDiagram + CUSTOMER ||--o{ ORDER : places + ORDER ||--|{ LINE-ITEM : contains + CUSTOMER }|..|{ DELIVERY-ADDRESS : uses ``` +```` -:::info +This produces the following diagram. -Some **info** with _Markdown_ `syntax`. - -::: - -```md -:::caution - -A **caution** with _Markdown_ `syntax`. - -::: +```mermaid +--- +title: Order example +--- +erDiagram + CUSTOMER ||--o{ ORDER : places + ORDER ||--|{ LINE-ITEM : contains + CUSTOMER }|..|{ DELIVERY-ADDRESS : uses ``` -:::caution - -A **caution** with _Markdown_ `syntax`. +The [Mermaid documentation](https://mermaid.js.org/intro) goes into more depth. -::: - -```md -:::danger +### Update the sidebar -Some **dangerous** content with _Markdown_ `syntax`. +If you're adding a new file, removing a file, or moving things around, update [`docusaurus/sidebars.js`](https://github.com/airbytehq/airbyte/blob/master/docusaurus/sidebars.js) to reflect the new structure. -::: -``` +### Add a redirect -:::danger +If you're moving or renaming a page, you should add a redirect to its new location. If you're deleting a page, you should add a redirect to the most relevant new file, like a replacement topic or a parent page. -Some **dangerous** content with _Markdown_ `syntax`. +To add a redirect, open the [`docusaurus/redirects.yml`](https://github.com/airbytehq/airbyte/blob/master/docusaurus/redirects.yml) file and add an entry from which old path to which new path a redirect should happen. +:::note +Your path needs a leading slash `/` to work ::: -#### Collapsible content with `
` and `` - -```md -## Ordinary markdown content - -
- Here is an expandible section! Everything but this title is hidden by default. - Here is the dropdown content; if users expand this section, they will be able to read your valuable but perhaps nonessential content. -
- -Back to ordinary markdown content. -``` - -Eagle-eyed readers may note that _all_ markdown should support this feature since it's part of the html spec. However, it's worth special mention since these dropdowns have been styled to be a graceful visual fit within our rendered documentation in all environments. - -#### Documenting PyAirbyte usage - -PyAirbyte is a Python library that allows to run syncs within a Python script for a subset of connectors. Documentation around PyAirbyte connectors is automatically generated from the connector's JSON schema spec. There are a few approaches to combine full control over the documentation with automatic generation for common cases: - -- If a connector is PyAirbyte enabled (`remoteRegistries.pypi.enabled` set in the `metadata.yaml` file of the connector) and there is no second-level heading `Usage with PyAirbyte` in the documentation, the documentation will be automatically generated and placed above the `Changelog` section. -- By manually specifying a `Usage with PyAirbyte` section, this automatism is disabled. The following is a good starting point for this section: - -```md - - -## Usage with PyAirbyte - - - - - - -``` - -The `PyAirbyteExample` component will generate a code example that can be run with PyAirbyte, excluding an auto-generated sample configuration based on the configuration schema. The `SpecSchema` component will generate a reference table with the connector's JSON schema spec, like a non-interactive version of the connector form in the UI. It can be used on any docs page. +### Document a code module -## Additional guidelines +If you're adding a README to a code module, make sure the README has the following components: -- If you're updating a connector doc, follow the [Connector documentation template](https://hackmd.io/Bz75cgATSbm7DjrAqgl4rw) -- If you're adding a new file, update the [sidebars.js file](https://github.com/airbytehq/airbyte/blob/master/docusaurus/sidebars.js) -- If you're adding a README to a code module, make sure the README has the following components: - A brief description of the module - - Development pre-requisites (like which language or binaries are required for development) + - Development prerequisites (like which language or binaries are required for development) - How to install dependencies - - How to build and run the code locally & via Docker + - How to build and run the code locally and via Docker - Any other information needed for local iteration -## Advanced tasks - -### Adding a redirect - -To add a redirect, open the [`docusaurus/redirects.yml`](https://github.com/airbytehq/airbyte/blob/master/docusaurus/redirects.yml) file and add an entry from which old path to which new path a redirect should happen. - -:::note -Your path **needs** a leading slash `/` to work +:::tip +AI tools like ChatGPT and GitHub Copilot are good at describing code. For open-source repositories, you might find it helpful to point one to your code module and ask it to generate a first draft for you. Airbyte employees working on a proprietary repository should follow Airbyte's AI usage policies. ::: -### Deploying and reverting the documentation site +## Create a pull request -:::note -Only the Airbyte team and maintainers have permissions to deploy the documentation site. -::: +When you're ready to submit your work, create a pull request into `master`. -#### Automated documentation site deployment +### Review and approval -When `docs/` folder gets changed in `master` branch of the repository, [`Deploy docs.airbyte.com` Github workflow](https://github.com/airbytehq/airbyte/actions/workflows/deploy-docs-site.yml) steps in, builds and deploys the documentation site. This process is automatic, takes five to ten minutes, and needs no human intervention. +New pull requests with docs changes are automatically submitted to [#docs-prs](https://airbytehq-team.slack.com/archives/C075JMUK2FJ) in Airbyte's internal Slack. [@ian-at-airbyte](https://github.com/ian-at-airbyte) monitors this feed. If you want a specific person to review your work, add them as a reviewer. If not, you don't need to tag anyone, but you must wait for at least one Airbyte employee to explicitly approve your pull request before anyone can merge it. -#### Manual documentation site deployment +Vercel builds a preview of the updated docs site automatically. If you're a community contributor, someone from Airbyte must authorize that build before it proceeds. -:::note -Manual deployment is reserved for emergency cases. Please, bear in mind that automatic deployment is triggered by changes to `docs/` folder, so it needs to be disabled to avoid interference with manual deployment. +:::tip Collaboration tip +If you're not finished but want to collaborate with others, create a draft pull request. Vercel will still build your docs site, creating a preview others can see, and you can continue to work on your branch to incorporate feedback. ::: -You'll need a GitHub SSH key to deploy the documentation site using the [deployment tool](https://github.com/airbytehq/airbyte/blob/master/tools/bin/deploy_docusaurus). - -To deploy the documentation site, run: - -```bash -cd airbyte -# or cd airbyte-cloud -git checkout master -git pull -./tools/bin/deploy_docusaurus -``` - -To revert/rollback doc changes, run: - -``` -cd airbyte -git checkout -./tools/bin/deploy_docusaurus -``` - -### Adding a diagram - -We have the docusaurus [Mermaid](https://mermaid.js.org/) plugin which has a variety of diagram -types and syntaxes available. - -:::danger -The connector specific docs do **not** currently support this, only use this for general docs. +:::note +Before we accept your contribution, you need to sign the Contributor License Agreement (CLA). By signing a CLA, we can ensure that the community is free and confident in its ability to use your contributions. You will be prompted to sign the CLA while opening a pull request. ::: -Here is an example from the [Mermaid docs](https://mermaid.js.org/syntax/entityRelationshipDiagram.html) -you would add the following to your markdown wrapped in a code block. - -```md - --- - title: Order example - --- - erDiagram - CUSTOMER ||--o{ ORDER : places - ORDER ||--|{ LINE-ITEM : contains - CUSTOMER }|..|{ DELIVERY-ADDRESS : uses -``` - -which produces the following diagram - -```mermaid ---- -title: Order example ---- -erDiagram - CUSTOMER ||--o{ ORDER : places - ORDER ||--|{ LINE-ITEM : contains - CUSTOMER }|..|{ DELIVERY-ADDRESS : uses -``` +## Deploy the documentation site -check out the rest of the Mermaid documentation for its capabilities just be aware that not all -the features are available to the docusaurus plugin. +When someone merges documentation changes into the `master` branch, updated docs are deployed automatically. This takes 5-10 minutes and needs no human intervention. \ No newline at end of file diff --git a/docs/deploying-airbyte/abctl-ec2.md b/docs/deploying-airbyte/abctl-ec2.md new file mode 100644 index 000000000000..c63dd0f99483 --- /dev/null +++ b/docs/deploying-airbyte/abctl-ec2.md @@ -0,0 +1,64 @@ +--- +products: oss-community +--- + +# Using an EC2 Instance with abctl + + + +This guide will assume that you are using the Amazon Linux distribution. However. any distribution that supports a docker engine should work with `abctl`. The launching and connecting to your EC2 Instance is outside the scope of this guide. You can find more information on how to launch and connect to EC2 Instances in the [Get started with Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html) documentation from Amazon. + +1. Install the docker engine: + +```shell +sudo yum install -y docker +``` + +2. Add the ec2-user (or whatever your distros default user) to the docker group: + +```shell +sudo usermod -a -G docker ec2-user +``` + +3. Start and optionally enable (start on boot) the docker engine: + +```shell +sudo systemctl start docker +sudo systemctl enable docker +``` + +4. Exit the shell and reconnect to the ec2 instance, an example would look like: + +```shell +exit +ssh -i ec2-user-key.pem ec2-user@1.2.3.4 +``` + +5. Download the latest version of abctl and install it in your path: + +```shell +curl -LsfS https://get.airbyte.com | bash - +``` + +6. Run the `abctl` command and install Airbyte: + :::tip + By default, `abctl` only configures an ingress rule for the host `localhost`. In order to ensure that Airbyte can be accessed outside of the EC2 instance, you will need to specify the `--host` flag to the `local install` command, providing the FQDN of the host which is hosting Airbyte. For example, `abctl local install --host airbyte.company.example`. + ::: + +By default, `abctl` will listen on port 8000. If port 8000 is already in used or you require a different port, you can specify this by passing the `--port` flag to the `local install` command. For example, `abctl local install --port 6598` + +Ensure the security group configured for the EC2 Instance allows traffic in on the port (8000 by default, or whatever port was passed to `--port`) that you deploy Airbyte on. See the [Control traffic to your AWS resources using security groups](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-security-groups.html) documentation for more information. + +```shell +abctl local install --host [HOSTNAME] +``` + +## Running over HTTP + +Airbyte suggest that you secure your instance of Airbyte using TLS. Running over plain HTTP allows attackers to see your +password over clear text. If you understand the risk and would still like to run Airbyte over HTTP, you must set +Secure Cookies to false. You can do this with `abctl` by passing the `--insecure-cookies` flag to `abctl`: + +```shell +abctl local install --host [HOSTNAME] --insecure-cookies +``` diff --git a/docs/deploying-airbyte/integrations/custom-image-registries.md b/docs/deploying-airbyte/integrations/custom-image-registries.md new file mode 100644 index 000000000000..96fce1a01247 --- /dev/null +++ b/docs/deploying-airbyte/integrations/custom-image-registries.md @@ -0,0 +1,95 @@ +--- +products: oss-community, oss-enterprise +--- + +import ContainerProviders from '@site/static/_docker_image_registries.md'; + +# Custom image registry + +You can optionally configure Airbyte to pull Docker images from a custom image registry rather than [Airbyte's public Docker repository](https://hub.docker.com/u/airbyte). In this case, Airbyte pulls both platform images (e.g. `server`, `webapp`, `workload-launcher`, etc.) and connector images (e.g. Postgres Source, S3 Destination, etc.) from the configured registry. + +Implementing Airbyte this way has several advantages. + +- **Security**: Private custom image registries keep images in your network, reducing the risk of external threats. +- **Access control**: You have more control over who can access and modify images. +- **Compliance**: By keeping images in a controlled environment, it's easier to prove compliance with regulatory requirements for data storage and handling. + +## Before you start + +Set up your custom image registry. The examples in this article use GitHub, but you have many options. Here are some popular ones: + + + +## Get a list of all Airbyte images + +To get a list of Airbyte images for the latest version, use abctl. + +```bash +abctl images manifest +``` + +You should see something like this: + +```bash +airbyte/bootloader:1.3.1 +airbyte/connector-builder-server:1.3.1 +airbyte/connector-sidecar:1.3.1 +airbyte/container-orchestrator:1.3.1 +airbyte/cron:1.3.1 +airbyte/db:1.3.1 +airbyte/mc:latest +airbyte/server:1.3.1 +airbyte/webapp:1.3.1 +airbyte/worker:1.3.1 +airbyte/workload-api-server:1.3.1 +airbyte/workload-init-container:1.3.1 +airbyte/workload-launcher:1.3.1 +bitnami/kubectl:1.28.9 +busybox:1.35 +busybox:latest +curlimages/curl:8.1.1 +minio/minio:RELEASE.2023-11-20T22-40-07Z +temporalio/auto-setup:1.23.0 +``` + +## Step 1: Customize Airbyte to use your image registry + +To pull all platform and connector images from a custom image registry, add the following customization to Airbyte's `values.yaml` file, replacing the `registry` value with your own registry location. + +```yaml title="values.yaml" +global: + image: + registry: ghcr.io/NAMESPACE +``` + +If your registry requires authentication, you can create a Kubernetes secret and reference it in the Airbyte config: + +1. Create a Kubernetes secret. In this example, you create a secret called `regcred` from a config file. That file contains authentication information for a private custom image registry. [Learn more about Kubernetes secrets](https://kubernetes.io/docs/tasks/configmap-secret/). + + ```bash + kubectl create secret generic regcred \ + --from-file=.dockerconfigjson= \ + --type=kubernetes.io/dockerconfigjson + ``` + +2. Add the secret you created to your `values.yaml` file. In this example, you use your `regcred` secret to authenticate. + + ```yaml title="values.yaml" + global: + image: + registry: ghcr.io/NAMESPACE + // highlight-start + imagePullSecrets: + - name: regcred + // highlight-end + ``` + +## Step 2: Tag and push Airbyte images + +Tag and push Airbyte's images to your custom image registry. In this example, you tag all Airbyte images and push them all to GitHub. + +```bash +abctl images manifest | xargs -L1 -I{} docker tag {} ghcr.io/NAMESPACE/{} && docker push ghcr.io/NAMESPACE/{} +``` + +Now, when you install Airbyte, images will come from the custom image registry you configured. \ No newline at end of file diff --git a/docs/deploying-airbyte/integrations/secrets.md b/docs/deploying-airbyte/integrations/secrets.md index fbfbfa694097..2f42098c4403 100644 --- a/docs/deploying-airbyte/integrations/secrets.md +++ b/docs/deploying-airbyte/integrations/secrets.md @@ -126,7 +126,7 @@ global: global: secretsManager: type: azureKeyVault - secretName: "airbyte-config-secrets" # Name of your Kubernetes secret. + secretsManagerSecretName: "airbyte-config-secrets" # Name of your Kubernetes secret. azureKeyVault: vaultUrl: ## https://my-vault.vault.azure.net/ tenantId: ## 3fc863e9-4740-4871-bdd4-456903a04d4e diff --git a/docs/deploying-airbyte/integrations/storage.md b/docs/deploying-airbyte/integrations/storage.md index 9ecbdf827835..ec76ee3e3d23 100644 --- a/docs/deploying-airbyte/integrations/storage.md +++ b/docs/deploying-airbyte/integrations/storage.md @@ -58,6 +58,8 @@ stringData: +Define a Secret with an [Azure storage connection string](https://learn.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string). The connection string specifies the storage account name and the key or token for authentication. + ```yaml apiVersion: v1 kind: Secret @@ -66,7 +68,7 @@ metadata: type: Opaque stringData: # Azure Secrets - azure-blob-store-connection-string: ## DefaultEndpointsProtocol=https;AccountName=azureintegration;AccountKey=wJalrXUtnFEMI/wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY/wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY==;EndpointSuffix=core.windows.net + azure-blob-store-connection-string: ## DefaultEndpointsProtocol=https;AccountName=mystorageaccount;AccountKey=wJalrXUtnFEMI/wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY/wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY==;EndpointSuffix=core.windows.net ``` @@ -120,17 +122,19 @@ global: +Ensure you've already created a Kubernetes Secret containing the connection string to be used by the cluster. Steps to configure the secret are in the above [prerequisites](#secrets). In the Helm chart, set the secret name and the key of the connection string. Set the three destination containers within the storage account under the `bucket` map. + ```yaml global: storage: type: "Azure" secretName: airbyte-config-secrets # Name of your Kubernetes secret. - bucket: ## S3 bucket names that you've created. We recommend storing the following all in one bucket. - log: airbyte-bucket - state: airbyte-bucket - workloadOutput: airbyte-bucket + bucket: ## Name Containers that you've created. We recommend storing the following all in one Container. + log: airbyte-container + state: airbyte-container + workloadOutput: airbyte-container azure: - connectionStringSecretKey: azure-blob-store-connection-string + connectionStringSecretKey: azure-blob-store-connection-string # key of your Kubernetes secret ``` diff --git a/docs/deploying-airbyte/migrating-from-docker-compose.md b/docs/deploying-airbyte/migrating-from-docker-compose.md new file mode 100644 index 000000000000..9de1f6a685e2 --- /dev/null +++ b/docs/deploying-airbyte/migrating-from-docker-compose.md @@ -0,0 +1,41 @@ +--- +products: oss-community +--- + +# Migrating from Docker Compose + + + +:::note + +If you're using an external database or secret manager you don't need to run `--migrate` flag. +You must create the `secrets.yaml` and `values.yaml` and then run `abctl local install --values ./values.yaml --secret ./secrets.yaml`. +Please check [instructions](integrations/database.md) to setup the external database as example. + +::: + +If you have data that you would like to migrate from an existing docker compose instance follow the steps below: + +1. Make sure that you have stopped the instance running in docker compose, this may require the following command: + +``` +docker compose stop +``` + +2. Make sure that you have the latest version of abctl by running the following command: + +``` +curl -LsfS https://get.airbyte.com | bash - +``` + +3. Run abctl with the migrate flag set with the following command: + +``` +abctl local install --migrate +``` + +:::note + +If you're using a version of Airbyte that you've installed with `abctl`, you can find instructions on upgrading your Airbyte installation [here](../operator-guides/upgrading-airbyte.md#upgrading-with-abctl). + +::: \ No newline at end of file diff --git a/docs/enterprise-setup/README.md b/docs/enterprise-setup/README.md index 9372e2977860..8eb2e6e4cf35 100644 --- a/docs/enterprise-setup/README.md +++ b/docs/enterprise-setup/README.md @@ -4,7 +4,7 @@ products: oss-enterprise # Airbyte Self-Managed Enterprise -[Airbyte Self-Managed Enterprise](https://airbyte.com/product/airbyte-enterprise) is the best way to run Airbyte yourself. You get all 350+ pre-built connectors, data never leaves your environment, and Self-Managed Enterprise introduces several new governance capabilities targeted towards large organizations designed to enhance your data platform’s capabilities and security. +[Airbyte Self-Managed Enterprise](https://airbyte.com/product/airbyte-enterprise) is the best way to run Airbyte yourself. You get all 500+ pre-built connectors, data never leaves your environment, and Self-Managed Enterprise introduces several new governance capabilities targeted towards large organizations designed to enhance your data platform’s capabilities and security. | Feature | Description | diff --git a/docs/enterprise-setup/assets/enterprise-connectors/service-now-setup.png b/docs/enterprise-setup/assets/enterprise-connectors/service-now-setup.png new file mode 100644 index 000000000000..813fdffc40a3 Binary files /dev/null and b/docs/enterprise-setup/assets/enterprise-connectors/service-now-setup.png differ diff --git a/docs/enterprise-setup/assets/enterprise-connectors/workday-raas.png b/docs/enterprise-setup/assets/enterprise-connectors/workday-raas.png new file mode 100644 index 000000000000..f071ec5eaf54 Binary files /dev/null and b/docs/enterprise-setup/assets/enterprise-connectors/workday-raas.png differ diff --git a/docs/enterprise-setup/assets/enterprise-connectors/workday-rest.png b/docs/enterprise-setup/assets/enterprise-connectors/workday-rest.png new file mode 100644 index 000000000000..e8abe1eec416 Binary files /dev/null and b/docs/enterprise-setup/assets/enterprise-connectors/workday-rest.png differ diff --git a/docs/enterprise-setup/implementation-guide.md b/docs/enterprise-setup/implementation-guide.md index 3ae2a54368ce..167a04925b9c 100644 --- a/docs/enterprise-setup/implementation-guide.md +++ b/docs/enterprise-setup/implementation-guide.md @@ -4,6 +4,7 @@ products: oss-enterprise import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; +import ContainerProviders from '@site/static/_docker_image_registries.md'; # Implementation Guide @@ -101,7 +102,7 @@ stringData: license-key: ## e.g. xxxxx.yyyyy.zzzzz # Database Secrets - database-host: ## e.g. database.internla + database-host: ## e.g. database.internal database-port: ## e.g. 5432 database-name: ## e.g. airbyte database-user: ## e.g. airbyte @@ -169,7 +170,7 @@ stringData: license-key: ## e.g. xxxxx.yyyyy.zzzzz # Database Secrets - database-host: ## e.g. database.internla + database-host: ## e.g. database.internal database-port: ## e.g. 5432 database-name: ## e.g. airbyte database-user: ## e.g. airbyte @@ -561,6 +562,127 @@ Once this is complete, ensure that the value of the `webapp-url` field in your ` You may configure ingress using a load balancer or an API Gateway. We do not currently support most service meshes (such as Istio). If you are having networking issues after fully deploying Airbyte, please verify that firewalls or lacking permissions are not interfering with pod-pod communication. Please also verify that deployed pods have the right permissions to make requests to your external database. +#### (Optional) Configure a custom image registry + +You can optionally configure Airbyte to pull Docker images from a custom image registry rather than [Airbyte's public Docker repository](https://hub.docker.com/u/airbyte). In this case, Airbyte pulls both platform images (e.g. `server`, `webapp`, `workload-launcher`, etc.) and connector images (e.g. Postgres Source, S3 Destination, etc.) from the configured registry. + +Implementing Airbyte this way has several advantages. + +- **Security**: Private custom image registries keep images in your network, reducing the risk of external threats. +- **Access control**: You have more control over who can access and modify images. +- **Compliance**: By keeping images in a controlled environment, it's easier to prove compliance with regulatory requirements for data storage and handling. + +
+Before you start + +1. Set up your custom image registry. The examples in this article use GitHub, but you have many options. Here are some popular ones: + + + +2. Install `abctl`. Although abctl is typically only used to manage local installations of Airbyte, it has some helpful commands for this process. + + + + ```bash + brew tap airbytehq/tap + brew install abctl + ``` + + + ```bash + go install github.com/airbytehq/abctl@latest + ``` + + + See [GitHub releases](https://github.com/airbytehq/abctl/releases/latest). + + + +
+ +
+Get a list of all Airbyte images + +To get a list of Airbyte images for the latest version, use abctl. + +```bash +abctl images manifest +``` + +You should see something like this: + +```bash +airbyte/bootloader:1.3.1 +airbyte/connector-builder-server:1.3.1 +airbyte/connector-sidecar:1.3.1 +airbyte/container-orchestrator:1.3.1 +airbyte/cron:1.3.1 +airbyte/db:1.3.1 +airbyte/mc:latest +airbyte/server:1.3.1 +airbyte/webapp:1.3.1 +airbyte/worker:1.3.1 +airbyte/workload-api-server:1.3.1 +airbyte/workload-init-container:1.3.1 +airbyte/workload-launcher:1.3.1 +bitnami/kubectl:1.28.9 +busybox:1.35 +busybox:latest +curlimages/curl:8.1.1 +minio/minio:RELEASE.2023-11-20T22-40-07Z +temporalio/auto-setup:1.23.0 +``` + +
+ +
+Step 1: Customize Airbyte to use your image registry + +To pull all platform and connector images from a custom image registry, add the following customization to Airbyte's `values.yaml` file, replacing the `registry` value with your own registry location. + +```yaml title="values.yaml" +global: + image: + registry: ghcr.io/NAMESPACE +``` + +If your registry requires authentication, you can create a Kubernetes secret and reference it in the Airbyte config: + +1. Create a Kubernetes secret. In this example, you create a secret called `regcred` from a config file. That file contains authentication information for a private custom image registry. [Learn more about Kubernetes secrets](https://kubernetes.io/docs/tasks/configmap-secret/). + + ```bash + kubectl create secret generic regcred \ + --from-file=.dockerconfigjson= \ + --type=kubernetes.io/dockerconfigjson + ``` + +2. Add the secret you created to your `values.yaml` file. In this example, you use your `regcred` secret to authenticate. + + ```yaml title="values.yaml" + global: + image: + registry: ghcr.io/NAMESPACE + // highlight-start + imagePullSecrets: + - name: regcred + // highlight-end + ``` + +
+ +
+Step 2: Tag and push Airbyte images + +Tag and push Airbyte's images to your custom image registry. In this example, you tag all Airbyte images and push them all to GitHub. + +```bash +abctl images manifest | xargs -L1 -I{} docker tag {} ghcr.io/NAMESPACE/{} && docker push ghcr.io/NAMESPACE/{} +``` + +Now, when you install Airbyte, images will come from the custom image registry you configured. + +
+ ### Step 3: Deploy Self-Managed Enterprise Install Airbyte Self-Managed Enterprise on helm using the following command: diff --git a/docs/integrations/destinations/astra.md b/docs/integrations/destinations/astra.md index e9d3e0d4a078..e146a8599ae8 100644 --- a/docs/integrations/destinations/astra.md +++ b/docs/integrations/destinations/astra.md @@ -43,6 +43,11 @@ This page contains the setup guide and reference information for the destination | Version | Date | Pull Request | Subject | |:--------| :--------- | :----------- |:----------------------------------------------------------| +| 0.1.34 | 2025-01-04 | [50910](https://github.com/airbytehq/airbyte/pull/50910) | Update dependencies | +| 0.1.33 | 2024-12-28 | [50446](https://github.com/airbytehq/airbyte/pull/50446) | Update dependencies | +| 0.1.32 | 2024-12-21 | [50213](https://github.com/airbytehq/airbyte/pull/50213) | Update dependencies | +| 0.1.31 | 2024-12-14 | [49288](https://github.com/airbytehq/airbyte/pull/49288) | Update dependencies | +| 0.1.30 | 2024-11-25 | [48674](https://github.com/airbytehq/airbyte/pull/48674) | Update dependencies | | 0.1.29 | 2024-10-29 | [47105](https://github.com/airbytehq/airbyte/pull/47105) | Update dependencies | | 0.1.28 | 2024-10-12 | [46857](https://github.com/airbytehq/airbyte/pull/46857) | Update dependencies | | 0.1.27 | 2024-10-05 | [46402](https://github.com/airbytehq/airbyte/pull/46402) | Update dependencies | diff --git a/docs/integrations/destinations/aws-datalake.md b/docs/integrations/destinations/aws-datalake.md index 19fbb03e5fbe..799983a8310a 100644 --- a/docs/integrations/destinations/aws-datalake.md +++ b/docs/integrations/destinations/aws-datalake.md @@ -94,6 +94,12 @@ which will be translated for compatibility with the Glue Data Catalog: | Version | Date | Pull Request | Subject | |:--------| :--------- | :--------------------------------------------------------- | :--------------------------------------------------- | +| 0.1.42 | 2025-01-04 | [50914](https://github.com/airbytehq/airbyte/pull/50914) | Update dependencies | +| 0.1.41 | 2024-12-28 | [50458](https://github.com/airbytehq/airbyte/pull/50458) | Update dependencies | +| 0.1.40 | 2024-12-21 | [50220](https://github.com/airbytehq/airbyte/pull/50220) | Update dependencies | +| 0.1.39 | 2024-12-14 | [48945](https://github.com/airbytehq/airbyte/pull/48945) | Update dependencies | +| 0.1.38 | 2024-11-25 | [48671](https://github.com/airbytehq/airbyte/pull/48671) | Update dependencies | +| 0.1.37 | 2024-11-04 | [48243](https://github.com/airbytehq/airbyte/pull/48243) | Update dependencies | | 0.1.36 | 2024-10-29 | [47878](https://github.com/airbytehq/airbyte/pull/47878) | Update dependencies | | 0.1.35 | 2024-10-28 | [47590](https://github.com/airbytehq/airbyte/pull/47590) | Update dependencies | | 0.1.34 | 2024-10-22 | [47091](https://github.com/airbytehq/airbyte/pull/47091) | Update dependencies | diff --git a/docs/integrations/destinations/azure-blob-storage.md b/docs/integrations/destinations/azure-blob-storage.md index c5fa6ee3ce05..13f75aa7dadc 100644 --- a/docs/integrations/destinations/azure-blob-storage.md +++ b/docs/integrations/destinations/azure-blob-storage.md @@ -152,6 +152,7 @@ With the field `File Extension`, it is possible to save the output files with ex | Version | Date | Pull Request | Subject | |:--------|:-----------|:-----------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 0.2.3 | 2024-12-18 | [49910](https://github.com/airbytehq/airbyte/pull/49910) | Use a base image: airbyte/java-connector-base:1.0.0 | | 0.2.2 | 2024-06-12 | [\#38061](https://github.com/airbytehq/airbyte/pull/38061) | File Extensions added for the output files | | 0.2.1 | 2023-09-13 | [\#30412](https://github.com/airbytehq/airbyte/pull/30412) | Switch noisy logging to debug | | 0.2.0 | 2023-01-18 | [\#21467](https://github.com/airbytehq/airbyte/pull/21467) | Support spilling of objects exceeding configured size threshold | @@ -163,4 +164,4 @@ With the field `File Extension`, it is possible to save the output files with ex | 0.1.1 | 2021-12-29 | [\#9190](https://github.com/airbytehq/airbyte/pull/9190) | Added BufferedOutputStream wrapper to blob output stream to improve performance and fix issues with 50,000 block limit. Also disabled autoflush on PrintWriter. | | 0.1.0 | 2021-08-30 | [\#5332](https://github.com/airbytehq/airbyte/pull/5332) | Initial release with JSONL and CSV output. | -
\ No newline at end of file + diff --git a/docs/integrations/destinations/chroma.md b/docs/integrations/destinations/chroma.md index 020c33a3f289..2018178d1737 100644 --- a/docs/integrations/destinations/chroma.md +++ b/docs/integrations/destinations/chroma.md @@ -77,6 +77,12 @@ You should now have all the requirements needed to configure Chroma as a destina | Version | Date | Pull Request | Subject | |:--------|:-----------| :-------------------------------------------------------- |:-------------------------------------------------------------| +| 0.0.39 | 2025-01-04 | [50913](https://github.com/airbytehq/airbyte/pull/50913) | Update dependencies | +| 0.0.38 | 2024-12-28 | [50445](https://github.com/airbytehq/airbyte/pull/50445) | Update dependencies | +| 0.0.37 | 2024-12-21 | [50221](https://github.com/airbytehq/airbyte/pull/50221) | Update dependencies | +| 0.0.36 | 2024-12-14 | [48956](https://github.com/airbytehq/airbyte/pull/48956) | Update dependencies | +| 0.0.35 | 2024-11-25 | [48668](https://github.com/airbytehq/airbyte/pull/48668) | Update dependencies | +| 0.0.34 | 2024-11-04 | [48236](https://github.com/airbytehq/airbyte/pull/48236) | Update dependencies | | 0.0.33 | 2024-10-29 | [47053](https://github.com/airbytehq/airbyte/pull/47053) | Update dependencies | | 0.0.32 | 2024-10-12 | [46434](https://github.com/airbytehq/airbyte/pull/46434) | Update dependencies | | 0.0.31 | 2024-09-28 | [46192](https://github.com/airbytehq/airbyte/pull/46192) | Update dependencies | diff --git a/docs/integrations/destinations/csv.md b/docs/integrations/destinations/csv.md index 8206400505dd..467458b06146 100644 --- a/docs/integrations/destinations/csv.md +++ b/docs/integrations/destinations/csv.md @@ -78,25 +78,26 @@ Note: If you are running Airbyte on Windows with Docker backed by WSL2, you have | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | -| 1.0.0 | 2022-12-20 | [17998](https://github.com/airbytehq/airbyte/pull/17998) | Breaking changes: non backwards compatible. Adds delimiter dropdown. | -| 0.2.10 | 2022-06-20 | [13932](https://github.com/airbytehq/airbyte/pull/13932) | Merging published connector changes | -| 0.2.9 | 2022-02-14 | [10256](https://github.com/airbytehq/airbyte/pull/10256) | Add ExitOnOutOfMemoryError to java connectors and bump versions | -| 0.2.8 | 2021-07-21 | [3555](https://github.com/airbytehq/airbyte/pull/3555) | Checkpointing: Partial Success in BufferedStreamConsumer (Destination) | -| 0.2.7 | 2021-06-09 | [3973](https://github.com/airbytehq/airbyte/pull/3973) | add AIRBYTE_ENTRYPOINT for kubernetes support | -| 0.2.6 | 2021-05-25 | [3290](https://github.com/airbytehq/airbyte/pull/3290) | Checkpointing: Worker use destination (instead of source) for state | -| 0.2.5 | 2021-05-10 | [3327](https://github.com/airbytehq/airbyte/pull/3327) | don't split lines on LSEP unicode characters when reading lines in destinations | -| 0.2.4 | 2021-05-10 | [3289](https://github.com/airbytehq/airbyte/pull/3289) | bump all destination versions to support outputting messages | -| 0.2.3 | 2021-03-31 | [2668](https://github.com/airbytehq/airbyte/pull/2668) | Add SupportedDestinationSyncModes to destination specs objects | -| 0.2.2 | 2021-03-19 | [2460](https://github.com/airbytehq/airbyte/pull/2460) | Destinations supports destination sync mode | -| 0.2.0 | 2021-03-09 | [2238](https://github.com/airbytehq/airbyte/pull/2238) | Upgrade all connectors (0.2.0) so protocol allows future / unknown properties | -| 0.1.8 | 2021-01-29 | [1882](https://github.com/airbytehq/airbyte/pull/1882) | Local File Destinations UX change with destination paths | -| 0.1.7 | 2021-01-20 | [1737](https://github.com/airbytehq/airbyte/pull/1737) | Rename destination tables | -| 0.1.6 | 2021-01-19 | [1708](https://github.com/airbytehq/airbyte/pull/1708) | Add metadata prefix to destination internal columns | -| 0.1.5 | 2020-12-12 | [1294](https://github.com/airbytehq/airbyte/pull/1294) | Incremental CSV destination | -| 0.1.4 | 2020-11-30 | [1038](https://github.com/airbytehq/airbyte/pull/1038) | Change jdbc sources to discover more than standard schemas | -| 0.1.3 | 2020-11-20 | [1021](https://github.com/airbytehq/airbyte/pull/1021) | Incremental Docs and Data Model Update | -| 0.1.2 | 2020-11-18 | [998](https://github.com/airbytehq/airbyte/pull/998) | Adding incremental to the data model | -| 0.1.1 | 2020-11-10 | [895](https://github.com/airbytehq/airbyte/pull/895) | bump versions: all destinations and source exchange rate | -| 0.1.0 | 2020-10-21 | [676](https://github.com/airbytehq/airbyte/pull/676) | Integrations Reorganization: Connectors | - - \ No newline at end of file +| 1.0.1 | 2024-12-18 | [49864](https://github.com/airbytehq/airbyte/pull/49864) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 1.0.0 | 2022-12-20 | [17998](https://github.com/airbytehq/airbyte/pull/17998) | Breaking changes: non backwards compatible. Adds delimiter dropdown. | +| 0.2.10 | 2022-06-20 | [13932](https://github.com/airbytehq/airbyte/pull/13932) | Merging published connector changes | +| 0.2.9 | 2022-02-14 | [10256](https://github.com/airbytehq/airbyte/pull/10256) | Add ExitOnOutOfMemoryError to java connectors and bump versions | +| 0.2.8 | 2021-07-21 | [3555](https://github.com/airbytehq/airbyte/pull/3555) | Checkpointing: Partial Success in BufferedStreamConsumer (Destination) | +| 0.2.7 | 2021-06-09 | [3973](https://github.com/airbytehq/airbyte/pull/3973) | add AIRBYTE_ENTRYPOINT for kubernetes support | +| 0.2.6 | 2021-05-25 | [3290](https://github.com/airbytehq/airbyte/pull/3290) | Checkpointing: Worker use destination (instead of source) for state | +| 0.2.5 | 2021-05-10 | [3327](https://github.com/airbytehq/airbyte/pull/3327) | don't split lines on LSEP unicode characters when reading lines in destinations | +| 0.2.4 | 2021-05-10 | [3289](https://github.com/airbytehq/airbyte/pull/3289) | bump all destination versions to support outputting messages | +| 0.2.3 | 2021-03-31 | [2668](https://github.com/airbytehq/airbyte/pull/2668) | Add SupportedDestinationSyncModes to destination specs objects | +| 0.2.2 | 2021-03-19 | [2460](https://github.com/airbytehq/airbyte/pull/2460) | Destinations supports destination sync mode | +| 0.2.0 | 2021-03-09 | [2238](https://github.com/airbytehq/airbyte/pull/2238) | Upgrade all connectors (0.2.0) so protocol allows future / unknown properties | +| 0.1.8 | 2021-01-29 | [1882](https://github.com/airbytehq/airbyte/pull/1882) | Local File Destinations UX change with destination paths | +| 0.1.7 | 2021-01-20 | [1737](https://github.com/airbytehq/airbyte/pull/1737) | Rename destination tables | +| 0.1.6 | 2021-01-19 | [1708](https://github.com/airbytehq/airbyte/pull/1708) | Add metadata prefix to destination internal columns | +| 0.1.5 | 2020-12-12 | [1294](https://github.com/airbytehq/airbyte/pull/1294) | Incremental CSV destination | +| 0.1.4 | 2020-11-30 | [1038](https://github.com/airbytehq/airbyte/pull/1038) | Change jdbc sources to discover more than standard schemas | +| 0.1.3 | 2020-11-20 | [1021](https://github.com/airbytehq/airbyte/pull/1021) | Incremental Docs and Data Model Update | +| 0.1.2 | 2020-11-18 | [998](https://github.com/airbytehq/airbyte/pull/998) | Adding incremental to the data model | +| 0.1.1 | 2020-11-10 | [895](https://github.com/airbytehq/airbyte/pull/895) | bump versions: all destinations and source exchange rate | +| 0.1.0 | 2020-10-21 | [676](https://github.com/airbytehq/airbyte/pull/676) | Integrations Reorganization: Connectors | + + diff --git a/docs/integrations/destinations/cumulio.md b/docs/integrations/destinations/cumulio.md index 27ac0ac96c92..f8fe82671060 100644 --- a/docs/integrations/destinations/cumulio.md +++ b/docs/integrations/destinations/cumulio.md @@ -161,6 +161,11 @@ data less frequently** rather than _smaller amounts of data more frequently_! | Version | Date | Pull Request | Subject | |:--------| :--------- | :-------------------------------------------------------- | :-------------------------------------------------- | +| 0.1.28 | 2024-12-28 | [50504](https://github.com/airbytehq/airbyte/pull/50504) | Update dependencies | +| 0.1.27 | 2024-12-21 | [50167](https://github.com/airbytehq/airbyte/pull/50167) | Update dependencies | +| 0.1.26 | 2024-12-14 | [49302](https://github.com/airbytehq/airbyte/pull/49302) | Update dependencies | +| 0.1.25 | 2024-11-25 | [48679](https://github.com/airbytehq/airbyte/pull/48679) | Update dependencies | +| 0.1.24 | 2024-11-04 | [47029](https://github.com/airbytehq/airbyte/pull/47029) | Update dependencies | | 0.1.23 | 2024-10-12 | [46816](https://github.com/airbytehq/airbyte/pull/46816) | Update dependencies | | 0.1.22 | 2024-10-05 | [46445](https://github.com/airbytehq/airbyte/pull/46445) | Update dependencies | | 0.1.21 | 2024-09-28 | [46201](https://github.com/airbytehq/airbyte/pull/46201) | Update dependencies | diff --git a/docs/integrations/destinations/databend.md b/docs/integrations/destinations/databend.md index 3879baf392dd..21951b02de16 100644 --- a/docs/integrations/destinations/databend.md +++ b/docs/integrations/destinations/databend.md @@ -72,6 +72,12 @@ And the [Databend Cloud](https://app.databend.com/) will only support databend v | Version | Date | Pull Request | Subject | | :------------------------------------------------------- | :--------------------------------------- | :-------------------------------------------------------- | :------------------------------------------------------- | ----------- | +| 0.1.33 | 2024-12-28 | [50472](https://github.com/airbytehq/airbyte/pull/50472) | Update dependencies | +| 0.1.32 | 2024-12-21 | [50201](https://github.com/airbytehq/airbyte/pull/50201) | Update dependencies | +| 0.1.31 | 2024-12-14 | [48916](https://github.com/airbytehq/airbyte/pull/48916) | Update dependencies | +| 0.1.30 | 2024-11-25 | [48664](https://github.com/airbytehq/airbyte/pull/48664) | Update dependencies | +| 0.1.29 | 2024-10-19 | [46992](https://github.com/airbytehq/airbyte/pull/46992) | add ssl param for databend destination | +| 0.1.28 | 2024-11-04 | [48272](https://github.com/airbytehq/airbyte/pull/48272) | Update dependencies | | 0.1.27 | 2024-10-28 | [47069](https://github.com/airbytehq/airbyte/pull/47069) | Update dependencies | | 0.1.26 | 2024-10-12 | [46811](https://github.com/airbytehq/airbyte/pull/46811) | Update dependencies | | 0.1.25 | 2024-10-05 | [46418](https://github.com/airbytehq/airbyte/pull/46418) | Update dependencies | diff --git a/docs/integrations/destinations/databricks.md b/docs/integrations/destinations/databricks.md index f184171997c8..1d7c101e4c6d 100644 --- a/docs/integrations/destinations/databricks.md +++ b/docs/integrations/destinations/databricks.md @@ -91,7 +91,8 @@ with the raw tables, and their format is subject to change without notice. | Version | Date | Pull Request | Subject | |:--------|:-----------|:--------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 3.3.0 | 2024-09-18 | [#45438](https://github.com/airbytehq/airbyte/pull/45438) | upgrade all dependencies. | +| 3.3.1 | 2024-12-02 | [#48779](https://github.com/airbytehq/airbyte/pull/48779) | bump resource reqs for `check` | +| 3.3.0 | 2024-09-18 | [#45438](https://github.com/airbytehq/airbyte/pull/45438) | upgrade all dependencies. | | 3.2.5 | 2024-09-12 | [#45439](https://github.com/airbytehq/airbyte/pull/45439) | Move to integrations section. | | 3.2.4 | 2024-09-09 | [#45208](https://github.com/airbytehq/airbyte/pull/45208) | Fix CHECK to create missing namespace if not exists. | | 3.2.3 | 2024-09-03 | [#45115](https://github.com/airbytehq/airbyte/pull/45115) | Clarify Unity Catalog Name option. | diff --git a/docs/integrations/destinations/dev-null.md b/docs/integrations/destinations/dev-null.md index f9e98018a139..0426772b86f0 100644 --- a/docs/integrations/destinations/dev-null.md +++ b/docs/integrations/destinations/dev-null.md @@ -47,33 +47,43 @@ This mode throws an exception after receiving a configurable number of messages. The OSS and Cloud variants have the same version number starting from version `0.2.2`. -| Version | Date | Pull Request | Subject | -|:--------|:-----------|:---------------------------------------------------------|:---------------------------------------------------------------------------------------------------| -| 0.7.7 | 2024-10-17 | [46692](https://github.com/airbytehq/airbyte/pull/46692) | Internal code changes | -| 0.7.6 | 2024-10-08 | [46683](https://github.com/airbytehq/airbyte/pull/46683) | Bugfix: pick up checkpoint safety check fix | -| 0.7.5 | 2024-10-08 | [46683](https://github.com/airbytehq/airbyte/pull/46683) | Bugfix: checkpoints in order, all checkpoints processed before shutdown | -| 0.7.4 | 2024-10-08 | [46650](https://github.com/airbytehq/airbyte/pull/46650) | Internal code changes | -| 0.7.3 | 2024-10-01 | [46559](https://github.com/airbytehq/airbyte/pull/46559) | From load CDK: async improvements, stream incomplete, additionalProperties on state messages | -| 0.7.2 | 2024-10-01 | [45929](https://github.com/airbytehq/airbyte/pull/45929) | Internal code changes | -| 0.7.1 | 2024-09-30 | [46276](https://github.com/airbytehq/airbyte/pull/46276) | Upgrade to latest bulk CDK | -| 0.7.0 | 2024-09-20 | [45704](https://github.com/airbytehq/airbyte/pull/45704) | | -| 0.6.1 | 2024-09-20 | [45715](https://github.com/airbytehq/airbyte/pull/45715) | add destination to cloud registry | -| 0.6.0 | 2024-09-18 | [45651](https://github.com/airbytehq/airbyte/pull/45651) | merge destination-e2e(OSS) and destination-dev-null(cloud) | -| 0.5.0 | 2024-09-18 | [45650](https://github.com/airbytehq/airbyte/pull/45650) | upgrade cdk | -| 0.4.1 | 2024-09-18 | [45649](https://github.com/airbytehq/airbyte/pull/45649) | convert test code to kotlin | -| 0.4.0 | 2024-09-18 | [45648](https://github.com/airbytehq/airbyte/pull/45648) | convert production code to kotlin | -| 0.3.6 | 2024-05-09 | [38097](https://github.com/airbytehq/airbyte/pull/38097) | Support dedup | -| 0.3.5 | 2024-04-29 | [37366](https://github.com/airbytehq/airbyte/pull/37366) | Support refreshes | -| 0.3.4 | 2024-04-16 | [37366](https://github.com/airbytehq/airbyte/pull/37366) | Fix NPE | -| 0.3.3 | 2024-04-16 | [37366](https://github.com/airbytehq/airbyte/pull/37366) | Fix Log trace messages | -| 0.3.2 | 2024-02-14 | [36812](https://github.com/airbytehq/airbyte/pull/36812) | Log trace messages | -| 0.3.1 | 2024-02-14 | [35278](https://github.com/airbytehq/airbyte/pull/35278) | Adopt CDK 0.20.6 | -| 0.3.0 | 2023-05-08 | [25776](https://github.com/airbytehq/airbyte/pull/25776) | Standardize spec and change property field to non-keyword | -| 0.2.4 | 2022-06-17 | [13864](https://github.com/airbytehq/airbyte/pull/13864) | Updated stacktrace format for any trace message errors | -| 0.2.3 | 2022-02-14 | [10256](https://github.com/airbytehq/airbyte/pull/10256) | Add `-XX:+ExitOnOutOfMemoryError` JVM option | -| 0.2.2 | 2022-01-29 | [\#9745](https://github.com/airbytehq/airbyte/pull/9745) | Integrate with Sentry. | -| 0.2.1 | 2021-12-19 | [\#8824](https://github.com/airbytehq/airbyte/pull/8905) | Fix documentation URL. | -| 0.2.0 | 2021-12-16 | [\#8824](https://github.com/airbytehq/airbyte/pull/8824) | Add multiple logging modes. | -| 0.1.0 | 2021-05-25 | [\#3290](https://github.com/airbytehq/airbyte/pull/3290) | Create initial version. | +| Version | Date | Pull Request | Subject | +|:------------|:-----------|:---------------------------------------------------------|:---------------------------------------------------------------------------------------------| +| 0.7.15 | 2024-12-19 | [49899](https://github.com/airbytehq/airbyte/pull/49931) | Non-functional CDK changes | +| 0.7.14 | 2024-12-20 | [49974](https://github.com/airbytehq/airbyte/pull/49974) | Non-functional CDK changes | +| 0.7.13 | 2024-12-18 | [49899](https://github.com/airbytehq/airbyte/pull/49899) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.7.12 | 2024-12-04 | [48794](https://github.com/airbytehq/airbyte/pull/48794) | Promoting release candidate 0.7.12-rc.2 to a main version. | +| 0.7.12-rc.2 | 2024-11-26 | [48693](https://github.com/airbytehq/airbyte/pull/48693) | Update for testing progressive rollout | +| 0.7.12-rc.1 | 2024-11-25 | [48693](https://github.com/airbytehq/airbyte/pull/48693) | Update for testing progressive rollout | +| 0.7.11 | 2024-11-18 | [48468](https://github.com/airbytehq/airbyte/pull/48468) | Implement File CDk | +| 0.7.10 | 2024-11-08 | [48429](https://github.com/airbytehq/airbyte/pull/48429) | Bugfix: correctly handle state ID field | +| 0.7.9 | 2024-11-07 | [48417](https://github.com/airbytehq/airbyte/pull/48417) | Only pass through the state ID field, not all additional properties | +| 0.7.8 | 2024-11-07 | [48416](https://github.com/airbytehq/airbyte/pull/48416) | Bugfix: global state correclty sends additional properties | +| 0.7.7 | 2024-10-17 | [46692](https://github.com/airbytehq/airbyte/pull/46692) | Internal code changes | +| 0.7.6 | 2024-10-08 | [46683](https://github.com/airbytehq/airbyte/pull/46683) | Bugfix: pick up checkpoint safety check fix | +| 0.7.5 | 2024-10-08 | [46683](https://github.com/airbytehq/airbyte/pull/46683) | Bugfix: checkpoints in order, all checkpoints processed before shutdown | +| 0.7.4 | 2024-10-08 | [46650](https://github.com/airbytehq/airbyte/pull/46650) | Internal code changes | +| 0.7.3 | 2024-10-01 | [46559](https://github.com/airbytehq/airbyte/pull/46559) | From load CDK: async improvements, stream incomplete, additionalProperties on state messages | +| 0.7.2 | 2024-10-01 | [45929](https://github.com/airbytehq/airbyte/pull/45929) | Internal code changes | +| 0.7.1 | 2024-09-30 | [46276](https://github.com/airbytehq/airbyte/pull/46276) | Upgrade to latest bulk CDK | +| 0.7.0 | 2024-09-20 | [45704](https://github.com/airbytehq/airbyte/pull/45704) | | +| 0.6.1 | 2024-09-20 | [45715](https://github.com/airbytehq/airbyte/pull/45715) | add destination to cloud registry | +| 0.6.0 | 2024-09-18 | [45651](https://github.com/airbytehq/airbyte/pull/45651) | merge destination-e2e(OSS) and destination-dev-null(cloud) | +| 0.5.0 | 2024-09-18 | [45650](https://github.com/airbytehq/airbyte/pull/45650) | upgrade cdk | +| 0.4.1 | 2024-09-18 | [45649](https://github.com/airbytehq/airbyte/pull/45649) | convert test code to kotlin | +| 0.4.0 | 2024-09-18 | [45648](https://github.com/airbytehq/airbyte/pull/45648) | convert production code to kotlin | +| 0.3.6 | 2024-05-09 | [38097](https://github.com/airbytehq/airbyte/pull/38097) | Support dedup | +| 0.3.5 | 2024-04-29 | [37366](https://github.com/airbytehq/airbyte/pull/37366) | Support refreshes | +| 0.3.4 | 2024-04-16 | [37366](https://github.com/airbytehq/airbyte/pull/37366) | Fix NPE | +| 0.3.3 | 2024-04-16 | [37366](https://github.com/airbytehq/airbyte/pull/37366) | Fix Log trace messages | +| 0.3.2 | 2024-02-14 | [36812](https://github.com/airbytehq/airbyte/pull/36812) | Log trace messages | +| 0.3.1 | 2024-02-14 | [35278](https://github.com/airbytehq/airbyte/pull/35278) | Adopt CDK 0.20.6 | +| 0.3.0 | 2023-05-08 | [25776](https://github.com/airbytehq/airbyte/pull/25776) | Standardize spec and change property field to non-keyword | +| 0.2.4 | 2022-06-17 | [13864](https://github.com/airbytehq/airbyte/pull/13864) | Updated stacktrace format for any trace message errors | +| 0.2.3 | 2022-02-14 | [10256](https://github.com/airbytehq/airbyte/pull/10256) | Add `-XX:+ExitOnOutOfMemoryError` JVM option | +| 0.2.2 | 2022-01-29 | [\#9745](https://github.com/airbytehq/airbyte/pull/9745) | Integrate with Sentry. | +| 0.2.1 | 2021-12-19 | [\#8824](https://github.com/airbytehq/airbyte/pull/8905) | Fix documentation URL. | +| 0.2.0 | 2021-12-16 | [\#8824](https://github.com/airbytehq/airbyte/pull/8824) | Add multiple logging modes. | +| 0.1.0 | 2021-05-25 | [\#3290](https://github.com/airbytehq/airbyte/pull/3290) | Create initial version. | diff --git a/docs/integrations/destinations/firebolt.md b/docs/integrations/destinations/firebolt.md index a68978a297bd..b3361933302c 100644 --- a/docs/integrations/destinations/firebolt.md +++ b/docs/integrations/destinations/firebolt.md @@ -98,6 +98,7 @@ Firebolt. Each table will contain 3 columns: | Version | Date | Pull Request | Subject | |:--------| :--------- | :------------------------------------------------------- | :------------------------------------- | +| 0.2.25 | 2024-11-25 | [48672](https://github.com/airbytehq/airbyte/pull/48672) | Update dependencies | | 0.2.24 | 2024-10-29 | [47780](https://github.com/airbytehq/airbyte/pull/47780) | Update dependencies | | 0.2.23 | 2024-10-28 | [47100](https://github.com/airbytehq/airbyte/pull/47100) | Update dependencies | | 0.2.22 | 2024-10-12 | [46841](https://github.com/airbytehq/airbyte/pull/46841) | Update dependencies | diff --git a/docs/integrations/destinations/firestore.md b/docs/integrations/destinations/firestore.md index e273826285c6..777fb8ab3c33 100644 --- a/docs/integrations/destinations/firestore.md +++ b/docs/integrations/destinations/firestore.md @@ -39,6 +39,12 @@ Each stream will be output into a BigQuery table. | Version | Date | Pull Request | Subject | |:--------| :--------- | :----------------------------------------------------- | :---------------------------- | +| 0.2.7 | 2025-01-04 | [50911](https://github.com/airbytehq/airbyte/pull/50911) | Update dependencies | +| 0.2.6 | 2024-12-28 | [50507](https://github.com/airbytehq/airbyte/pull/50507) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50212](https://github.com/airbytehq/airbyte/pull/50212) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49294](https://github.com/airbytehq/airbyte/pull/49294) | Update dependencies | +| 0.2.3 | 2024-11-25 | [48681](https://github.com/airbytehq/airbyte/pull/48681) | Update dependencies | +| 0.2.2 | 2024-11-04 | [48223](https://github.com/airbytehq/airbyte/pull/48223) | Update dependencies | | 0.2.1 | 2024-10-29 | [43758](https://github.com/airbytehq/airbyte/pull/43758) | Update dependencies | | 0.2.0 | 2024-10-14 | [46874](https://github.com/airbytehq/airbyte/pull/46874) | Bump Airbyte CDK version to 5.13 | | 0.1.8 | 2024-08-22 | [44530](https://github.com/airbytehq/airbyte/pull/44530) | Update test dependencies | diff --git a/docs/integrations/destinations/gcs.md b/docs/integrations/destinations/gcs.md index 4304c7baa626..c27b45d8801c 100644 --- a/docs/integrations/destinations/gcs.md +++ b/docs/integrations/destinations/gcs.md @@ -242,8 +242,9 @@ Under the hood, an Airbyte data stream in Json schema is first converted to an A | Version | Date | Pull Request | Subject | | :------ | :--------- | :--------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------- | -| 0.4.6 | 2024-02-15 | [35285](https://github.com/airbytehq/airbyte/pull/35285) | Adopt CDK 0.20.8 | -| 0.4.5 | 2024-02-08 | [34745](https://github.com/airbytehq/airbyte/pull/34745) | Adopt CDK 0.19.0 | +| 0.4.7 | 2024-12-18 | [49884](https://github.com/airbytehq/airbyte/pull/49884) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.4.6 | 2024-02-15 | [35285](https://github.com/airbytehq/airbyte/pull/35285) | Adopt CDK 0.20.8 | +| 0.4.5 | 2024-02-08 | [34745](https://github.com/airbytehq/airbyte/pull/34745) | Adopt CDK 0.19.0 | | 0.4.4 | 2023-07-14 | [#28345](https://github.com/airbytehq/airbyte/pull/28345) | Increment patch to trigger a rebuild | | 0.4.3 | 2023-07-05 | [#27936](https://github.com/airbytehq/airbyte/pull/27936) | Internal code update | | 0.4.2 | 2023-06-30 | [#27891](https://github.com/airbytehq/airbyte/pull/27891) | Internal code update | @@ -282,4 +283,4 @@ Under the hood, an Airbyte data stream in Json schema is first converted to an A | 0.1.1 | 2021-08-26 | [\#5296](https://github.com/airbytehq/airbyte/issues/5296) | Added storing gcsCsvFileLocation property for CSV format. This is used by destination-bigquery \(GCS Staging upload type\) | | 0.1.0 | 2021-07-16 | [\#4329](https://github.com/airbytehq/airbyte/pull/4784) | Initial release. | - \ No newline at end of file + diff --git a/docs/integrations/destinations/google-sheets.md b/docs/integrations/destinations/google-sheets.md index 93102b7db1b1..d96fcc99c0d0 100644 --- a/docs/integrations/destinations/google-sheets.md +++ b/docs/integrations/destinations/google-sheets.md @@ -155,6 +155,12 @@ EXAMPLE: | Version | Date | Pull Request | Subject | |---------| ---------- | -------------------------------------------------------- | ---------------------------------------------------------- | +| 0.2.34 | 2025-01-04 | [50912](https://github.com/airbytehq/airbyte/pull/50912) | Update dependencies | +| 0.2.33 | 2024-12-28 | [50492](https://github.com/airbytehq/airbyte/pull/50492) | Update dependencies | +| 0.2.32 | 2024-12-21 | [50168](https://github.com/airbytehq/airbyte/pull/50168) | Update dependencies | +| 0.2.31 | 2024-12-14 | [48915](https://github.com/airbytehq/airbyte/pull/48915) | Update dependencies | +| 0.2.30 | 2024-11-25 | [48678](https://github.com/airbytehq/airbyte/pull/48678) | Update dependencies | +| 0.2.29 | 2024-11-04 | [48281](https://github.com/airbytehq/airbyte/pull/48281) | Update dependencies | | 0.2.28 | 2024-10-28 | [47042](https://github.com/airbytehq/airbyte/pull/47042) | Update dependencies | | 0.2.27 | 2024-10-12 | [46772](https://github.com/airbytehq/airbyte/pull/46772) | Update dependencies | | 0.2.26 | 2024-10-05 | [46464](https://github.com/airbytehq/airbyte/pull/46464) | Update dependencies | diff --git a/docs/integrations/destinations/iceberg.md b/docs/integrations/destinations/iceberg.md index f664933d8c20..a923aad86c6c 100644 --- a/docs/integrations/destinations/iceberg.md +++ b/docs/integrations/destinations/iceberg.md @@ -75,11 +75,12 @@ specify the target size of compacted Iceberg data file. | Version | Date | Pull Request | Subject | |:--------|:-----------|:----------------------------------------------------------|:---------------------------------------------------------------| -| 0.2.2 | 2024-09-23 | [45861](https://github.com/airbytehq/airbyte/pull/45861) | Keeping only S3 with Glue Catalog as config option | -| 0.2.1 | 2024-09-20 | [45711](https://github.com/airbytehq/airbyte/pull/45711) | Initial Cloud version for registry purpose [UNTESTED ON CLOUD] | -| 0.2.0 | 2024-09-20 | [45707](https://github.com/airbytehq/airbyte/pull/45707) | Add support for AWS Glue Catalog | -| 0.1.8 | 2024-09-16 | [45206](https://github.com/airbytehq/airbyte/pull/45206) | Fixing tests to work in airbyte-ci | -| 0.1.7 | 2024-05-17 | [38283](https://github.com/airbytehq/airbyte/pull/38283) | Bump Iceberg library to 1.5.2 and Spark to 3.5.1 | +| 0.2.3 | 2024-12-17 | [49841](https://github.com/airbytehq/airbyte/pull/49841) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.2.2 | 2024-09-23 | [45861](https://github.com/airbytehq/airbyte/pull/45861) | Keeping only S3 with Glue Catalog as config option | +| 0.2.1 | 2024-09-20 | [45711](https://github.com/airbytehq/airbyte/pull/45711) | Initial Cloud version for registry purpose [UNTESTED ON CLOUD] | +| 0.2.0 | 2024-09-20 | [45707](https://github.com/airbytehq/airbyte/pull/45707) | Add support for AWS Glue Catalog | +| 0.1.8 | 2024-09-16 | [45206](https://github.com/airbytehq/airbyte/pull/45206) | Fixing tests to work in airbyte-ci | +| 0.1.7 | 2024-05-17 | [38283](https://github.com/airbytehq/airbyte/pull/38283) | Bump Iceberg library to 1.5.2 and Spark to 3.5.1 | | 0.1.6 | 2024-04-04 | [#36846](https://github.com/airbytehq/airbyte/pull/36846) | Remove duplicate S3 Region | | 0.1.5 | 2024-01-03 | [#33924](https://github.com/airbytehq/airbyte/pull/33924) | Add new ap-southeast-3 AWS region | | 0.1.4 | 2023-07-20 | [28506](https://github.com/airbytehq/airbyte/pull/28506) | Support server-managed storage config | @@ -88,4 +89,4 @@ specify the target size of compacted Iceberg data file. | 0.1.1 | 2023-02-27 | [23201](https://github.com/airbytehq/airbyte/pull/23301) | Bump Iceberg library to 1.1.0 | | 0.1.0 | 2022-11-01 | [18836](https://github.com/airbytehq/airbyte/pull/18836) | Initial Commit | - \ No newline at end of file + diff --git a/docs/integrations/destinations/local-json.md b/docs/integrations/destinations/local-json.md index 9fb98373c792..721de5a7d8cb 100644 --- a/docs/integrations/destinations/local-json.md +++ b/docs/integrations/destinations/local-json.md @@ -78,6 +78,7 @@ Note: If you are running Airbyte on Windows with Docker backed by WSL2, you have | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :--------------------------- | -| 0.2.11 | 2022-02-14 | [14641](https://github.com/airbytehq/airbyte/pull/14641) | Include lifecycle management | +| 0.2.12 | 2024-12-18 | [49908](https://github.com/airbytehq/airbyte/pull/49908) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.2.11 | 2022-02-14 | [14641](https://github.com/airbytehq/airbyte/pull/14641) | Include lifecycle management | - \ No newline at end of file + diff --git a/docs/integrations/destinations/meilisearch.md b/docs/integrations/destinations/meilisearch.md index 71ee3252ff85..f0f94ef4c5b0 100644 --- a/docs/integrations/destinations/meilisearch.md +++ b/docs/integrations/destinations/meilisearch.md @@ -48,6 +48,12 @@ the MeiliSearch docs. | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :----------------------------------------------------- | +| 1.0.11 | 2025-01-04 | [50909](https://github.com/airbytehq/airbyte/pull/50909) | Update dependencies | +| 1.0.10 | 2024-12-28 | [50460](https://github.com/airbytehq/airbyte/pull/50460) | Update dependencies | +| 1.0.9 | 2024-12-21 | [50196](https://github.com/airbytehq/airbyte/pull/50196) | Update dependencies | +| 1.0.8 | 2024-12-14 | [49550](https://github.com/airbytehq/airbyte/pull/49550) | Update dependencies | +| 1.0.7 | 2024-12-11 | [49021](https://github.com/airbytehq/airbyte/pull/49021) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 1.0.6 | 2024-11-04 | [48207](https://github.com/airbytehq/airbyte/pull/48207) | Update dependencies | | 1.0.5 | 2024-10-29 | [47889](https://github.com/airbytehq/airbyte/pull/47889) | Update dependencies | | 1.0.4 | 2024-10-28 | [47646](https://github.com/airbytehq/airbyte/pull/47646) | Update dependencies | | 1.0.3 | 2024-07-08 | [#TODO](https://github.com/airbytehq/airbyte/pull/TODO) | Switching to Poetry and base image | diff --git a/docs/integrations/destinations/milvus.md b/docs/integrations/destinations/milvus.md index 95da6410152b..83970889db2c 100644 --- a/docs/integrations/destinations/milvus.md +++ b/docs/integrations/destinations/milvus.md @@ -116,6 +116,12 @@ vector_store.similarity_search("test") | Version | Date | Pull Request | Subject | |:--------| :--------- | :-------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- | +| 0.0.43 | 2025-01-04 | [50916](https://github.com/airbytehq/airbyte/pull/50916) | Update dependencies | +| 0.0.42 | 2024-12-28 | [50508](https://github.com/airbytehq/airbyte/pull/50508) | Update dependencies | +| 0.0.41 | 2024-12-21 | [50169](https://github.com/airbytehq/airbyte/pull/50169) | Update dependencies | +| 0.0.40 | 2024-12-14 | [49307](https://github.com/airbytehq/airbyte/pull/49307) | Update dependencies | +| 0.0.39 | 2024-11-25 | [48655](https://github.com/airbytehq/airbyte/pull/48655) | Update dependencies | +| 0.0.38 | 2024-11-04 | [47789](https://github.com/airbytehq/airbyte/pull/47789) | Update dependencies | | 0.0.37 | 2024-10-28 | [47505](https://github.com/airbytehq/airbyte/pull/47505) | Update dependencies | | 0.0.36 | 2024-10-23 | [47080](https://github.com/airbytehq/airbyte/pull/47080) | Update dependencies | | 0.0.35 | 2024-10-05 | [46483](https://github.com/airbytehq/airbyte/pull/46483) | Update dependencies | diff --git a/docs/integrations/destinations/motherduck.md b/docs/integrations/destinations/motherduck.md index f3cc72881ac9..b5807a2dd3c7 100644 --- a/docs/integrations/destinations/motherduck.md +++ b/docs/integrations/destinations/motherduck.md @@ -1,6 +1,5 @@ # MotherDuck - ## Overview [DuckDB](https://duckdb.org/) is an in-process SQL OLAP database management system and this destination is meant to use locally if you have multiple smaller sources such as GitHub repos, some social media and local CSVs or files you want to run analytics workloads on. This destination writes data to the [MotherDuck](https://motherduck.com) service, or to a file on the _local_ filesystem on the host running Airbyte. @@ -29,7 +28,11 @@ We do not recommend providing your API token in the `md:` connection string, as ### Authenticating to MotherDuck -For authentication, you can can provide your [MotherDuck Service Credential](https://motherduck.com/docs/authenticating-to-motherduck/#syntax) as the `motherduck_api_key` configuration option. + + +For authentication, you will use your [MotherDuck Access Token](https://motherduck.com/docs/key-tasks/authenticating-and-connecting-to-motherduck/authenticating-to-motherduck/#creating-an-access-token). + + ### Sync Overview @@ -43,15 +46,16 @@ Each table will contain at least the following columns: In addition, columns specified in the [JSON schema](https://docs.airbyte.com/connector-development/schema-reference) will also be created. - #### Features -| Feature | Supported | | -| :----------------------------- | :-------- | :-- | -| Full Refresh Sync | Yes | | -| Incremental - Append Sync | Yes | | -| Incremental - Append + Deduped | Yes | | -| Namespaces | No | | +| Feature | Supported | | +| :----------------------------------------------------------------------- | :-------- | :-- | +| Full Refresh Sync | Yes | | +| Incremental - Append Sync | Yes | | +| Incremental - Append + Deduped | Yes | | +| [Typing and Deduplication](/using-airbyte/core-concepts/typing-deduping) | Yes | | +| [Namespaces](/using-airbyte/core-concepts/namespaces) | No | | +| [Data Generations](/operator-guides/refreshes#data-generations) | No | | #### Performance consideration @@ -61,24 +65,30 @@ This integration will be constrained by the speed at which your filesystem accep This connector is primarily designed to work with MotherDuck and local DuckDB files for [Destinations V2](/release_notes/upgrading_to_destinations_v2/#what-is-destinations-v2). If you would like to work only with local DuckDB files, you may want to consider using the [DuckDB destination](https://docs.airbyte.com/integrations/destinations/duckdb). - ## Changelog
Expand to review -| Version | Date | Pull Request | Subject | -|:--------| :--------- | :-------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 0.1.10 | 2024-10-29 | [47958](https://github.com/airbytehq/airbyte/pull/47958) | Add state counts and other fixes. | -| 0.1.9 | 2024-10-29 | [47950](https://github.com/airbytehq/airbyte/pull/47950) | Fix bug: add double quotes to column names that are reserved keywords. | -| 0.1.8 | 2024-10-29 | [47952](https://github.com/airbytehq/airbyte/pull/47952) | Fix: Add max batch size for loads. | -| 0.1.7 | 2024-10-29 | [47706](https://github.com/airbytehq/airbyte/pull/47706) | Fix bug: incorrect column names were used to create new stream table when using multiple streams. | -| 0.1.6 | 2024-10-29 | [47821](https://github.com/airbytehq/airbyte/pull/47821) | Update dependencies | -| 0.1.5 | 2024-10-28 | [47694](https://github.com/airbytehq/airbyte/pull/47694) | Resolve write failures, move processor classes into the connector. | -| 0.1.4 | 2024-10-28 | [47688](https://github.com/airbytehq/airbyte/pull/47688) | Use new destination table name format, explicitly insert PyArrow table columns by name and add debug info for column mismatches. | -| 0.1.3 | 2024-10-23 | [47315](https://github.com/airbytehq/airbyte/pull/47315) | Fix bug causing MotherDuck API key to not be correctly passed to the engine. | -| 0.1.2 | 2024-10-23 | [47315](https://github.com/airbytehq/airbyte/pull/47315) | Use `saas_only` mode during connection check to reduce ram usage. | -| 0.1.1 | 2024-10-23 | [47312](https://github.com/airbytehq/airbyte/pull/47312) | Fix: generate new unique destination ID | -| 0.1.0 | 2024-10-23 | [46904](https://github.com/airbytehq/airbyte/pull/46904) | New MotherDuck destination | +| Version | Date | Pull Request | Subject | +| :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- | +| 0.1.17 | 2024-12-26 | [50425](https://github.com/airbytehq/airbyte/pull/50425) | Fix bug overwrite write method not not saving all batches | +| 0.1.16 | 2024-12-06 | [48562](https://github.com/airbytehq/airbyte/pull/48562) | Improved handling of config parameters during SQL engine creation. | +| 0.1.15 | 2024-11-07 | [48405](https://github.com/airbytehq/airbyte/pull/48405) | Updated docs and hovertext for schema, api key, and database name. | +| 0.1.14 | 2024-10-30 | [48006](https://github.com/airbytehq/airbyte/pull/48006) | Fix bug in \_flush_buffer, explicitly register dataframe before inserting | +| 0.1.13 | 2024-10-30 | [47969](https://github.com/airbytehq/airbyte/pull/47969) | Preserve Platform-generated id in state messages. | +| 0.1.12 | 2024-10-30 | [47987](https://github.com/airbytehq/airbyte/pull/47987) | Disable PyPi publish. | +| 0.1.11 | 2024-10-30 | [47979](https://github.com/airbytehq/airbyte/pull/47979) | Rename package. | +| 0.1.10 | 2024-10-29 | [47958](https://github.com/airbytehq/airbyte/pull/47958) | Add state counts and other fixes. | +| 0.1.9 | 2024-10-29 | [47950](https://github.com/airbytehq/airbyte/pull/47950) | Fix bug: add double quotes to column names that are reserved keywords. | +| 0.1.8 | 2024-10-29 | [47952](https://github.com/airbytehq/airbyte/pull/47952) | Fix: Add max batch size for loads. | +| 0.1.7 | 2024-10-29 | [47706](https://github.com/airbytehq/airbyte/pull/47706) | Fix bug: incorrect column names were used to create new stream table when using multiple streams. | +| 0.1.6 | 2024-10-29 | [47821](https://github.com/airbytehq/airbyte/pull/47821) | Update dependencies | +| 0.1.5 | 2024-10-28 | [47694](https://github.com/airbytehq/airbyte/pull/47694) | Resolve write failures, move processor classes into the connector. | +| 0.1.4 | 2024-10-28 | [47688](https://github.com/airbytehq/airbyte/pull/47688) | Use new destination table name format, explicitly insert PyArrow table columns by name and add debug info for column mismatches. | +| 0.1.3 | 2024-10-23 | [47315](https://github.com/airbytehq/airbyte/pull/47315) | Fix bug causing MotherDuck API key to not be correctly passed to the engine. | +| 0.1.2 | 2024-10-23 | [47315](https://github.com/airbytehq/airbyte/pull/47315) | Use `saas_only` mode during connection check to reduce ram usage. | +| 0.1.1 | 2024-10-23 | [47312](https://github.com/airbytehq/airbyte/pull/47312) | Fix: generate new unique destination ID | +| 0.1.0 | 2024-10-23 | [46904](https://github.com/airbytehq/airbyte/pull/46904) | New MotherDuck destination |
diff --git a/docs/integrations/destinations/mssql-v2.md b/docs/integrations/destinations/mssql-v2.md new file mode 100644 index 000000000000..b46fe57a2f66 --- /dev/null +++ b/docs/integrations/destinations/mssql-v2.md @@ -0,0 +1,13 @@ +# MSSQL (V2) + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|:--------|:-----------| :--------------------------------------------------------- |:---------------| +| 0.1.1 | 2024-12-18 | [49870](https://github.com/airbytehq/airbyte/pull/49870) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.1.0 | 2024-12-16 | [\#49460](https://github.com/airbytehq/airbyte/pull/49460) | Initial commit | + +
diff --git a/docs/integrations/destinations/mssql.md b/docs/integrations/destinations/mssql.md index dcbb1fa145a5..48c667e2bc5c 100644 --- a/docs/integrations/destinations/mssql.md +++ b/docs/integrations/destinations/mssql.md @@ -119,6 +119,8 @@ Using this feature requires additional configuration, when creating the source. | Version | Date | Pull Request | Subject | | :------ | :--------- | :--------------------------------------------------------- | :-------------------------------------------------------------------------------------------------- | +| 1.0.2 | 2024-12-18 | [49891](https://github.com/airbytehq/airbyte/pull/49891) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 1.0.1 | 2024-11-04 | [\#48134](https://github.com/airbytehq/airbyte/pull/48134) | Fix supported sync modes (destination-mssql 1.x.y does not support dedup) | | 1.0.0 | 2024-04-11 | [\#36050](https://github.com/airbytehq/airbyte/pull/36050) | Update to Dv2 Table Format and Remove normalization | | 0.2.0 | 2023-06-27 | [\#27781](https://github.com/airbytehq/airbyte/pull/27781) | License Update: Elv2 | | 0.1.25 | 2023-06-21 | [\#27555](https://github.com/airbytehq/airbyte/pull/27555) | Reduce image size | @@ -145,4 +147,4 @@ Using this feature requires additional configuration, when creating the source. | 0.1.2 | 2021-05-13 | [\#3367](https://github.com/airbytehq/airbyte/pull/3671) | Fix handle symbols unicode | | 0.1.1 | 2021-05-11 | [\#3566](https://github.com/airbytehq/airbyte/pull/3195) | MS SQL Server Destination Release! | - \ No newline at end of file + diff --git a/docs/integrations/destinations/mysql.md b/docs/integrations/destinations/mysql.md index 07d25ef7706d..c71b2acffdb0 100644 --- a/docs/integrations/destinations/mysql.md +++ b/docs/integrations/destinations/mysql.md @@ -111,20 +111,21 @@ Using this feature requires additional configuration, when creating the destinat | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :-------------------------------------------------------------------------------------------------- | -| 1.0.3 | 2024-06-26 | [40566](https://github.com/airbytehq/airbyte/pull/40566) | Remove strict-encrypt variant | -| 1.0.2 | 2024-06-26 | [40553](https://github.com/airbytehq/airbyte/pull/40553) | Convert prod code to kotlin | -| 1.0.1 | 2024-06-25 | [40513](https://github.com/airbytehq/airbyte/pull/40513) | Improve error reporting for "access denied" error | -| 1.0.0 | 2024-04-26 | [37322](https://github.com/airbytehq/airbyte/pull/37322) | Remove normalization and upgrade to DV2 output format | -| 0.3.1 | 2024-04-12 | [36926](https://github.com/airbytehq/airbyte/pull/36926) | Upgrade to Kotlin CDK | -| 0.3.0 | 2023-12-18 | [33468](https://github.com/airbytehq/airbyte/pull/33468) | Upgrade to latest Java CDK | -| 0.2.0 | 2023-06-27 | [27781](https://github.com/airbytehq/airbyte/pull/27781) | License Update: Elv2 | -| 0.1.21 | 2022-09-14 | [15668](https://github.com/airbytehq/airbyte/pull/15668) | Wrap logs in AirbyteLogMessage | -| 0.1.20 | 2022-06-17 | [13864](https://github.com/airbytehq/airbyte/pull/13864) | Updated stacktrace format for any trace message errors | -| 0.1.19 | 2022-05-17 | [12820](https://github.com/airbytehq/airbyte/pull/12820) | Improved 'check' operation performance | -| 0.1.18 | 2022-02-25 | [10421](https://github.com/airbytehq/airbyte/pull/10421) | Refactor JDBC parameters handling | -| 0.1.17 | 2022-02-16 | [10362](https://github.com/airbytehq/airbyte/pull/10362) | Add jdbc_url_params support for optional JDBC parameters | -| 0.1.16 | 2022-02-14 | [10256](https://github.com/airbytehq/airbyte/pull/10256) | Add `-XX:+ExitOnOutOfMemoryError` JVM option | -| 0.1.15 | 2021-12-01 | [8371](https://github.com/airbytehq/airbyte/pull/8371) | Fixed incorrect handling "\n" in ssh key | +| 1.0.3 | 2024-12-18 | [49865](https://github.com/airbytehq/airbyte/pull/49865) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 1.0.3 | 2024-06-26 | [40566](https://github.com/airbytehq/airbyte/pull/40566) | Remove strict-encrypt variant | +| 1.0.2 | 2024-06-26 | [40553](https://github.com/airbytehq/airbyte/pull/40553) | Convert prod code to kotlin | +| 1.0.1 | 2024-06-25 | [40513](https://github.com/airbytehq/airbyte/pull/40513) | Improve error reporting for "access denied" error | +| 1.0.0 | 2024-04-26 | [37322](https://github.com/airbytehq/airbyte/pull/37322) | Remove normalization and upgrade to DV2 output format | +| 0.3.1 | 2024-04-12 | [36926](https://github.com/airbytehq/airbyte/pull/36926) | Upgrade to Kotlin CDK | +| 0.3.0 | 2023-12-18 | [33468](https://github.com/airbytehq/airbyte/pull/33468) | Upgrade to latest Java CDK | +| 0.2.0 | 2023-06-27 | [27781](https://github.com/airbytehq/airbyte/pull/27781) | License Update: Elv2 | +| 0.1.21 | 2022-09-14 | [15668](https://github.com/airbytehq/airbyte/pull/15668) | Wrap logs in AirbyteLogMessage | +| 0.1.20 | 2022-06-17 | [13864](https://github.com/airbytehq/airbyte/pull/13864) | Updated stacktrace format for any trace message errors | +| 0.1.19 | 2022-05-17 | [12820](https://github.com/airbytehq/airbyte/pull/12820) | Improved 'check' operation performance | +| 0.1.18 | 2022-02-25 | [10421](https://github.com/airbytehq/airbyte/pull/10421) | Refactor JDBC parameters handling | +| 0.1.17 | 2022-02-16 | [10362](https://github.com/airbytehq/airbyte/pull/10362) | Add jdbc_url_params support for optional JDBC parameters | +| 0.1.16 | 2022-02-14 | [10256](https://github.com/airbytehq/airbyte/pull/10256) | Add `-XX:+ExitOnOutOfMemoryError` JVM option | +| 0.1.15 | 2021-12-01 | [8371](https://github.com/airbytehq/airbyte/pull/8371) | Fixed incorrect handling "\n" in ssh key | | 0.1.14 | 2021-11-08 | [#7719](https://github.com/airbytehq/airbyte/pull/7719) | Improve handling of wide rows by buffering records based on their byte size rather than their count | | 0.1.13 | 2021-09-28 | [\#6506](https://github.com/airbytehq/airbyte/pull/6506) | Added support for MySQL destination via TLS/SSL | | 0.1.12 | 2021-09-24 | [\#6317](https://github.com/airbytehq/airbyte/pull/6317) | Added option to connect to DB via SSH | diff --git a/docs/integrations/destinations/pinecone.md b/docs/integrations/destinations/pinecone.md index b14fa57ff858..a5808588ba98 100644 --- a/docs/integrations/destinations/pinecone.md +++ b/docs/integrations/destinations/pinecone.md @@ -79,6 +79,12 @@ OpenAI and Fake embeddings produce vectors with 1536 dimensions, and the Cohere | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------- | +| 0.1.33 | 2025-01-04 | [50904](https://github.com/airbytehq/airbyte/pull/50904) | Update dependencies | +| 0.1.32 | 2024-12-28 | [50480](https://github.com/airbytehq/airbyte/pull/50480) | Update dependencies | +| 0.1.31 | 2024-12-21 | [50203](https://github.com/airbytehq/airbyte/pull/50203) | Update dependencies | +| 0.1.30 | 2024-12-14 | [49303](https://github.com/airbytehq/airbyte/pull/49303) | Update dependencies | +| 0.1.29 | 2024-11-25 | [48654](https://github.com/airbytehq/airbyte/pull/48654) | Update dependencies | +| 0.1.28 | 2024-11-05 | [48323](https://github.com/airbytehq/airbyte/pull/48323) | Update dependencies | | 0.1.27 | 2024-10-29 | [47106](https://github.com/airbytehq/airbyte/pull/47106) | Update dependencies | | 0.1.26 | 2024-10-12 | [46782](https://github.com/airbytehq/airbyte/pull/46782) | Update dependencies | | 0.1.25 | 2024-10-05 | [46474](https://github.com/airbytehq/airbyte/pull/46474) | Update dependencies | diff --git a/docs/integrations/destinations/pubsub.md b/docs/integrations/destinations/pubsub.md index de136936dd16..b971b922fa09 100644 --- a/docs/integrations/destinations/pubsub.md +++ b/docs/integrations/destinations/pubsub.md @@ -96,6 +96,7 @@ Once you've configured PubSub as a destination, delete the Service Account Key f | Version | Date | Pull Request | Subject | | :------ | :---------------- | :------------------------------------------------------- | :--------------------------------------------------------- | +| 0.2.1 | 2024-12-18 | [49878](https://github.com/airbytehq/airbyte/pull/49878) | Use a base image: airbyte/java-connector-base:1.0.0 | | 0.2.0 | August 16, 2022 | [15705](https://github.com/airbytehq/airbyte/pull/15705) | Add configuration for Batching and Ordering | | 0.1.5 | 2022-06-17 | [13864](https://github.com/airbytehq/airbyte/pull/13864) | Updated stacktrace format for any trace message errors | | 0.1.4 | February 21, 2022 | [\#9819](https://github.com/airbytehq/airbyte/pull/9819) | Upgrade version of google-cloud-pubsub | @@ -104,4 +105,4 @@ Once you've configured PubSub as a destination, delete the Service Account Key f | 0.1.1 | August 13, 2021 | [\#4699](https://github.com/airbytehq/airbyte/pull/4699) | Added json config validator | | 0.1.0 | June 24, 2021 | [\#4339](https://github.com/airbytehq/airbyte/pull/4339) | Initial release | - \ No newline at end of file + diff --git a/docs/integrations/destinations/qdrant.md b/docs/integrations/destinations/qdrant.md index 02605c7d2519..aa0f63c278df 100644 --- a/docs/integrations/destinations/qdrant.md +++ b/docs/integrations/destinations/qdrant.md @@ -73,6 +73,12 @@ You should now have all the requirements needed to configure Qdrant as a destina | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :----------------------------------------------------------------------- | +| 0.1.25 | 2025-01-04 | [50917](https://github.com/airbytehq/airbyte/pull/50917) | Update dependencies | +| 0.1.24 | 2024-12-28 | [50459](https://github.com/airbytehq/airbyte/pull/50459) | Update dependencies | +| 0.1.23 | 2024-12-21 | [50222](https://github.com/airbytehq/airbyte/pull/50222) | Update dependencies | +| 0.1.22 | 2024-12-14 | [49290](https://github.com/airbytehq/airbyte/pull/49290) | Update dependencies | +| 0.1.21 | 2024-11-25 | [48641](https://github.com/airbytehq/airbyte/pull/48641) | Update dependencies | +| 0.1.20 | 2024-11-04 | [48191](https://github.com/airbytehq/airbyte/pull/48191) | Update dependencies | | 0.1.19 | 2024-10-29 | [47757](https://github.com/airbytehq/airbyte/pull/47757) | Update dependencies | | 0.1.18 | 2024-10-28 | [47621](https://github.com/airbytehq/airbyte/pull/47621) | Update dependencies | | 0.1.17 | 2024-10-28 | [47054](https://github.com/airbytehq/airbyte/pull/47054) | Update dependencies | diff --git a/docs/integrations/destinations/rabbitmq.md b/docs/integrations/destinations/rabbitmq.md index d0f85529e6a2..9f9aeb3e02c7 100644 --- a/docs/integrations/destinations/rabbitmq.md +++ b/docs/integrations/destinations/rabbitmq.md @@ -48,6 +48,10 @@ To use the RabbitMQ destination, you'll need: | Version | Date | Pull Request | Subject | |:--------| :--------------- | :-------------------------------------------------------- | :---------------------------------------------- | +| 0.1.29 | 2024-12-28 | [50506](https://github.com/airbytehq/airbyte/pull/50506) | Update dependencies | +| 0.1.28 | 2024-12-21 | [50180](https://github.com/airbytehq/airbyte/pull/50180) | Update dependencies | +| 0.1.27 | 2024-12-14 | [49305](https://github.com/airbytehq/airbyte/pull/49305) | Update dependencies | +| 0.1.26 | 2024-11-25 | [48642](https://github.com/airbytehq/airbyte/pull/48642) | Update dependencies | | 0.1.25 | 2024-10-29 | [47101](https://github.com/airbytehq/airbyte/pull/47101) | Update dependencies | | 0.1.24 | 2024-10-12 | [46859](https://github.com/airbytehq/airbyte/pull/46859) | Update dependencies | | 0.1.23 | 2024-10-05 | [46437](https://github.com/airbytehq/airbyte/pull/46437) | Update dependencies | diff --git a/docs/integrations/destinations/redshift.md b/docs/integrations/destinations/redshift.md index 1e176451567c..96657e0d720f 100644 --- a/docs/integrations/destinations/redshift.md +++ b/docs/integrations/destinations/redshift.md @@ -222,10 +222,11 @@ Each stream will be output into its own raw table in Redshift. Each table will c | Version | Date | Pull Request | Subject | | :------ | :--------- | :--------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 3.5.0 | 2024-09-18 | [45435](https://github.com/airbytehq/airbyte/pull/45435) | upgrade all dependencies | -| 3.4.4 | 2024-08-20 | [44476](https://github.com/airbytehq/airbyte/pull/44476) | Increase message parsing limit to 100mb | -| 3.4.3 | 2024-08-22 | [44526](https://github.com/airbytehq/airbyte/pull/44526) | Revert protocol compliance fix | -| 3.4.2 | 2024-08-15 | [42506](https://github.com/airbytehq/airbyte/pull/42506) | Fix bug in refreshes logic (already mitigated in platform, just fixing protocol compliance) | +| 3.5.1 | 2024-12-18 | [49903](https://github.com/airbytehq/airbyte/pull/49903) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 3.5.0 | 2024-09-18 | [45435](https://github.com/airbytehq/airbyte/pull/45435) | upgrade all dependencies | +| 3.4.4 | 2024-08-20 | [44476](https://github.com/airbytehq/airbyte/pull/44476) | Increase message parsing limit to 100mb | +| 3.4.3 | 2024-08-22 | [44526](https://github.com/airbytehq/airbyte/pull/44526) | Revert protocol compliance fix | +| 3.4.2 | 2024-08-15 | [42506](https://github.com/airbytehq/airbyte/pull/42506) | Fix bug in refreshes logic (already mitigated in platform, just fixing protocol compliance) | | 3.4.1 | 2024-08-13 | [xxx](https://github.com/airbytehq/airbyte/pull/xxx) | Simplify Redshift Options | | 3.4.0 | 2024-07-23 | [42445](https://github.com/airbytehq/airbyte/pull/42445) | Respect the `drop cascade` option on raw tables | | 3.3.1 | 2024-07-15 | [41968](https://github.com/airbytehq/airbyte/pull/41968) | Don't hang forever on empty stream list; shorten error message on INCOMPLETE stream status | diff --git a/docs/integrations/destinations/s3-data-lake.md b/docs/integrations/destinations/s3-data-lake.md new file mode 100644 index 000000000000..8781386e9947 --- /dev/null +++ b/docs/integrations/destinations/s3-data-lake.md @@ -0,0 +1,22 @@ +# S3 Data Lake + +:::danger + +This connector is in early access, and SHOULD NOT be used for production workloads. +This connector is subject to breaking changes **without notice**. + +We're interested in hearing about your experience! See [Github](https://github.com/airbytehq/airbyte/discussions/50404) +for more information. + +::: + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|:-----------|:-----------|:-----------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------| +| 0.2.6 | 2025-01-08 | [\#50991](https://github.com/airbytehq/airbyte/pull/50991) | Initial public release. | + +
diff --git a/docs/integrations/destinations/s3-glue.md b/docs/integrations/destinations/s3-glue.md index 548afd741028..4a8b6de508b3 100644 --- a/docs/integrations/destinations/s3-glue.md +++ b/docs/integrations/destinations/s3-glue.md @@ -306,6 +306,8 @@ the output filename will have an extra extension (GZIP: `.jsonl.gz`). | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :-------------------------------------------------------------------------------------- | +| 0.1.10 | 2024-10-29 | [#48820](https://github.com/airbytehq/airbyte/pull/48820) | revert back to CDK 0.2.0 | +| 0.1.9 | 2024-10-28 | [#47201](https://github.com/airbytehq/airbyte/pull/47201) | build against latest CDK | | 0.1.8 | 2024-01-03 | [#33924](https://github.com/airbytehq/airbyte/pull/33924) | Add new ap-southeast-3 AWS region | | 0.1.7 | 2023-05-01 | [25724](https://github.com/airbytehq/airbyte/pull/25724) | Fix decimal type creation syntax to avoid overflow | | 0.1.6 | 2023-04-13 | [25178](https://github.com/airbytehq/airbyte/pull/25178) | Fix decimal precision and scale to allow for a wider range of numeric values | diff --git a/docs/integrations/destinations/s3.md b/docs/integrations/destinations/s3.md index fabfe3eb90e9..77525f24e443 100644 --- a/docs/integrations/destinations/s3.md +++ b/docs/integrations/destinations/s3.md @@ -214,36 +214,44 @@ Use an existing or create new destination**. 3. On the destination setup page, select **S3** from the Destination type dropdown and enter a name for this connector. -4. Configure fields: _ **Access Key Id** _ See - [this](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) - on how to generate an access key. _ See - [this](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html) - on how to create a instanceprofile. _ We recommend creating an Airbyte-specific user. This user - will require - [read and write permissions](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_s3_rw-bucket.html) - to objects in the staging bucket. \_ If the Access Key and Secret Access Key are not provided, the - authentication will rely either on the Role ARN using STS Assume Role or on the instanceprofile. -5. _ **Secret Access Key** _ Corresponding key to - the above key id. _ Make sure your S3 bucket is accessible from the machine running Airbyte. _ - This depends on your networking setup. _ You can check AWS S3 documentation with a tutorial on - how to properly configure your S3's access - [here](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-overview.html). _ If - you use instance profile authentication, make sure the role has permission to read/write on the - bucket. _ The easiest way to verify if Airbyte is able to connect to your S3 bucket is via the - check connection tool in the UI. _ **S3 Bucket Name** _ See - [this](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html) to - create an S3 bucket. _ **S3 Bucket Path** _ Subdirectory under the above bucket to sync the data - into. _ **S3 Bucket Region** _ See - [here](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions) - for all region codes. _ **S3 Path Format** _ Additional string format on how to store data under - S3 Bucket Path. Default value is `${NAMESPACE}/${STREAM_NAME}/${YEAR}_${MONTH}_${DAY}_${EPOCH}_`. - _ **S3 Endpoint** _ Leave empty if using AWS S3, fill in S3 URL if using Minio S3. - - - **S3 Filename pattern** \* The pattern allows you to set the file-name format for the S3 - staging file(s), next placeholders combinations are currently supported: `{date}`, - `{date:yyyy_MM}`, `{timestamp}`, `{timestamp:millis}`, `{timestamp:micros}`, `{part_number}`, - `{sync_id}`, `{format_extension}`. Please, don't use empty space and not supportable - placeholders, as they won't recognized. +4. Configure fields: + - **Access Key Id** + - See [this](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) on how to generate an access key. + - See [this](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html) on how to create a instanceprofile. + - We recommend creating an Airbyte-specific user. This user will require [read and write permissions](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_s3_rw-bucket.html) + to objects in the staging bucket. + - If the Access Key and Secret Access Key are not provided, the + authentication will rely either on the Role ARN using STS Assume Role or on the instanceprofile. + - **Secret Access Key** + - Corresponding key to the above key id. + - Make sure your S3 bucket is accessible from the machine running Airbyte. + - This depends on your networking setup. + - You can check AWS S3 documentation with a tutorial on how to properly configure your S3's access [here](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-overview.html). + - If you use instance profile authentication, make sure the role has permission to read/write on the + bucket. + - The easiest way to verify if Airbyte is able to connect to your S3 bucket is via the + check connection tool in the UI. + - **S3 Bucket Name** + - See [this](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html) to create an S3 bucket. + - **S3 Bucket Path** + - Subdirectory under the above bucket to sync the data + into. + - **S3 Bucket Region** + - See + [here](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions) + for all region codes. + - **S3 Path Format** + - Additional string format on how to store data under + S3 Bucket Path. Default value is `${NAMESPACE}/${STREAM_NAME}/${YEAR}_${MONTH}_${DAY}_${EPOCH}_`. + - **S3 Endpoint** + - Leave empty if using AWS S3, fill in S3 URL if using Minio S3. + - **S3 Filename pattern** + - The pattern allows you to set the file-name format for the S3 + staging file(s), next placeholders combinations are currently supported: `{date}`, + `{date:yyyy_MM}`, `{timestamp}`, `{timestamp:millis}`, `{timestamp:micros}`, `{part_number}`, + `{sync_id}`, `{format_extension}`. + - Please, don't use empty space and not supportable + placeholders, as they won't recognized. 6. Click `Set up destination`. @@ -534,91 +542,96 @@ To see connector limitations, or troubleshoot your S3 connector, see more [in ou
Expand to review -| Version | Date | Pull Request | Subject | -|:--------|:-----------|:-----------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------| -| 1.3.0 | 2024-10-30 | [46281](https://github.com/airbytehq/airbyte/pull/46281) | fix tests | -| 1.2.1 | 2024-09-20 | [45700](https://github.com/airbytehq/airbyte/pull/45700) | Improve resiliency to jsonschema fields | -| 1.2.0 | 2024-09-18 | [45402](https://github.com/airbytehq/airbyte/pull/45402) | fix exception with columnless streams | -| 1.1.0 | 2024-09-18 | [45436](https://github.com/airbytehq/airbyte/pull/45436) | upgrade all dependencies | -| 1.0.5 | 2024-09-05 | [45143](https://github.com/airbytehq/airbyte/pull/45143) | don't overwrite (and delete) existing files, skip indexes instead | -| 1.0.4 | 2024-08-30 | [44933](https://github.com/airbytehq/airbyte/pull/44933) | Fix: Avro/Parquet: handle empty schemas in nested objects/lists | -| 1.0.3 | 2024-08-20 | [44476](https://github.com/airbytehq/airbyte/pull/44476) | Increase message parsing limit to 100mb | -| 1.0.2 | 2024-08-19 | [44401](https://github.com/airbytehq/airbyte/pull/44401) | Fix: S3 Avro/Parquet: handle nullable top-level schema | -| 1.0.1 | 2024-08-14 | [42579](https://github.com/airbytehq/airbyte/pull/42579) | OVERWRITE MODE: Deletes deferred until successful sync. | -| 1.0.0 | 2024-08-08 | [42409](https://github.com/airbytehq/airbyte/pull/42409) | Major breaking changes: new destination schema, change capture, Avro/Parquet improvements, bugfixes | -| 0.6.7 | 2024-08-11 | [43713](https://github.com/airbytehq/airbyte/issues/43713) | Decreased memory ratio (0.7 -> 0.5) and thread allocation (5 -> 2) for async S3 uploads. | -| 0.6.6 | 2024-08-06 | [43343](https://github.com/airbytehq/airbyte/pull/43343) | Use Kotlin 2.0.0 | -| 0.6.5 | 2024-08-01 | [42405](https://github.com/airbytehq/airbyte/pull/42405) | S3 parallelizes workloads, checkpoints, submits counts, support for generationId in metadata for refreshes. | -| 0.6.4 | 2024-04-16 | [42006](https://github.com/airbytehq/airbyte/pull/42006) | remove unnecessary zookeeper dependency | -| 0.6.3 | 2024-04-15 | [38204](https://github.com/airbytehq/airbyte/pull/38204) | convert all production code to kotlin | -| 0.6.2 | 2024-04-15 | [38204](https://github.com/airbytehq/airbyte/pull/38204) | add assume role auth | -| 0.6.1 | 2024-04-08 | [37546](https://github.com/airbytehq/airbyte/pull/37546) | Adapt to CDK 0.30.8; | -| 0.6.0 | 2024-04-08 | [36869](https://github.com/airbytehq/airbyte/pull/36869) | Adapt to CDK 0.29.8; Kotlin converted code. | -| 0.5.9 | 2024-02-22 | [35569](https://github.com/airbytehq/airbyte/pull/35569) | Fix logging bug. | -| 0.5.8 | 2024-01-03 | [#33924](https://github.com/airbytehq/airbyte/pull/33924) | Add new ap-southeast-3 AWS region | -| 0.5.7 | 2023-12-28 | [#33788](https://github.com/airbytehq/airbyte/pull/33788) | Thread-safe fix for file part names | -| 0.5.6 | 2023-12-08 | [#33263](https://github.com/airbytehq/airbyte/pull/33263) | (incorrect filename format, do not use) Adopt java CDK version 0.7.0. | -| 0.5.5 | 2023-12-08 | [#33264](https://github.com/airbytehq/airbyte/pull/33264) | Update UI options with common defaults. | -| 0.5.4 | 2023-11-06 | [#32193](https://github.com/airbytehq/airbyte/pull/32193) | (incorrect filename format, do not use) Adopt java CDK version 0.4.1. | -| 0.5.3 | 2023-11-03 | [#32050](https://github.com/airbytehq/airbyte/pull/32050) | (incorrect filename format, do not use) Adopt java CDK version 0.4.0. This updates filenames to include a UUID. | -| 0.5.1 | 2023-06-26 | [#27786](https://github.com/airbytehq/airbyte/pull/27786) | Fix build | -| 0.5.0 | 2023-06-26 | [#27725](https://github.com/airbytehq/airbyte/pull/27725) | License Update: Elv2 | -| 0.4.2 | 2023-06-21 | [#27555](https://github.com/airbytehq/airbyte/pull/27555) | Reduce image size | -| 0.4.1 | 2023-05-18 | [#26284](https://github.com/airbytehq/airbyte/pull/26284) | Fix: reenable LZO compression for Parquet output | -| 0.4.0 | 2023-04-28 | [#25570](https://github.com/airbytehq/airbyte/pull/25570) | Fix: all integer schemas should be converted to Avro longs | -| 0.3.25 | 2023-04-27 | [#25346](https://github.com/airbytehq/airbyte/pull/25346) | Internal code cleanup | -| 0.3.23 | 2023-03-30 | [#24736](https://github.com/airbytehq/airbyte/pull/24736) | Improve behavior when throttled by AWS API | -| 0.3.22 | 2023-03-17 | [#23788](https://github.com/airbytehq/airbyte/pull/23788) | S3-Parquet: added handler to process null values in arrays | -| 0.3.21 | 2023-03-10 | [#23466](https://github.com/airbytehq/airbyte/pull/23466) | Changed S3 Avro type from Int to Long | -| 0.3.20 | 2023-02-23 | [#21355](https://github.com/airbytehq/airbyte/pull/21355) | Add root level flattening option to JSONL output. | -| 0.3.19 | 2023-01-18 | [#21087](https://github.com/airbytehq/airbyte/pull/21087) | Wrap Authentication Errors as Config Exceptions | -| 0.3.18 | 2022-12-15 | [\#20088](https://github.com/airbytehq/airbyte/pull/20088) | New data type support v0/v1 | -| 0.3.17 | 2022-10-15 | [\#18031](https://github.com/airbytehq/airbyte/pull/18031) | Fix integration tests to use bucket path | -| 0.3.16 | 2022-10-03 | [\#17340](https://github.com/airbytehq/airbyte/pull/17340) | Enforced encrypted only traffic to S3 buckets and check logic | -| 0.3.15 | 2022-09-01 | [\#16243](https://github.com/airbytehq/airbyte/pull/16243) | Fix Json to Avro conversion when there is field name clash from combined restrictions (`anyOf`, `oneOf`, `allOf` fields). | -| 0.3.14 | 2022-08-24 | [\#15207](https://github.com/airbytehq/airbyte/pull/15207) | Fix S3 bucket path to be used for check. | -| 0.3.13 | 2022-08-09 | [\#15394](https://github.com/airbytehq/airbyte/pull/15394) | Added LZO compression support to Parquet format | -| 0.3.12 | 2022-08-05 | [\#14801](https://github.com/airbytehq/airbyte/pull/14801) | Fix multiple log bindings | -| 0.3.11 | 2022-07-15 | [\#14494](https://github.com/airbytehq/airbyte/pull/14494) | Make S3 output filename configurable. | -| 0.3.10 | 2022-06-30 | [\#14332](https://github.com/airbytehq/airbyte/pull/14332) | Change INSTANCE\*PROFILE to use `AWSDefaultProfileCredential`, which supports more authentications on AWS | -| 0.3.9 | 2022-06-24 | [\#14114](https://github.com/airbytehq/airbyte/pull/14114) | Remove "additionalProperties": false from specs for connectors with staging | -| 0.3.8 | 2022-06-17 | [\#13753](https://github.com/airbytehq/airbyte/pull/13753) | Deprecate and remove PART_SIZE_MB fields from connectors based on StreamTransferManager | -| 0.3.7 | 2022-06-14 | [\#13483](https://github.com/airbytehq/airbyte/pull/13483) | Added support for int, long, float data types to Avro/Parquet formats. | -| 0.3.6 | 2022-05-19 | [\#13043](https://github.com/airbytehq/airbyte/pull/13043) | Destination S3: Remove configurable part size. | -| 0.3.5 | 2022-05-12 | [\#12797](https://github.com/airbytehq/airbyte/pull/12797) | Update spec to replace markdown. | -| 0.3.4 | 2022-05-04 | [\#12578](https://github.com/airbytehq/airbyte/pull/12578) | In JSON to Avro conversion, log JSON field values that do not follow Avro schema for debugging. | -| 0.3.3 | 2022-04-20 | [\#12167](https://github.com/airbytehq/airbyte/pull/12167) | Add gzip compression option for CSV and JSONL formats. | -| 0.3.2 | 2022-04-22 | [\#11795](https://github.com/airbytehq/airbyte/pull/11795) | Fix the connection check to verify the provided bucket path. | -| 0.3.1 | 2022-04-05 | [\#11728](https://github.com/airbytehq/airbyte/pull/11728) | Properly clean-up bucket when running OVERWRITE sync mode | -| 0.3.0 | 2022-04-04 | [\#11666](https://github.com/airbytehq/airbyte/pull/11666) | 0.2.12 actually has breaking changes since files are compressed by default, this PR also fixes the naming to be more compatible with older versions. | -| 0.2.13 | 2022-03-29 | [\#11496](https://github.com/airbytehq/airbyte/pull/11496) | Fix S3 bucket path to be included with S3 bucket format | -| 0.2.12 | 2022-03-28 | [\#11294](https://github.com/airbytehq/airbyte/pull/11294) | Change to serialized buffering strategy to reduce memory consumption | -| 0.2.11 | 2022-03-23 | [\#11173](https://github.com/airbytehq/airbyte/pull/11173) | Added support for AWS Glue crawler | -| 0.2.10 | 2022-03-07 | [\#10856](https://github.com/airbytehq/airbyte/pull/10856) | `check` method now tests for listObjects permissions on the target bucket | -| 0.2.7 | 2022-02-14 | [\#10318](https://github.com/airbytehq/airbyte/pull/10318) | Prevented double slashes in S3 destination path | -| 0.2.6 | 2022-02-14 | [10256](https://github.com/airbytehq/airbyte/pull/10256) | Add `-XX:+ExitOnOutOfMemoryError` JVM option | -| 0.2.5 | 2022-01-13 | [\#9399](https://github.com/airbytehq/airbyte/pull/9399) | Use instance profile authentication if credentials are not provided | -| 0.2.4 | 2022-01-12 | [\#9415](https://github.com/airbytehq/airbyte/pull/9415) | BigQuery Destination : Fix GCS processing of Facebook data | -| 0.2.3 | 2022-01-11 | [\#9367](https://github.com/airbytehq/airbyte/pull/9367) | Avro & Parquet: support array field with unknown item type; default any improperly typed field to string. | -| 0.2.2 | 2021-12-21 | [\#8574](https://github.com/airbytehq/airbyte/pull/8574) | Added namespace to Avro and Parquet record types | -| 0.2.1 | 2021-12-20 | [\#8974](https://github.com/airbytehq/airbyte/pull/8974) | Release a new version to ensure there is no excessive logging. | -| 0.2.0 | 2021-12-15 | [\#8607](https://github.com/airbytehq/airbyte/pull/8607) | Change the output filename for CSV files - it's now `bucketPath/namespace/streamName/timestamp_epochMillis_randomUuid.csv` | -| 0.1.16 | 2021-12-10 | [\#8562](https://github.com/airbytehq/airbyte/pull/8562) | Swap dependencies with destination-jdbc. | -| 0.1.15 | 2021-12-03 | [\#8501](https://github.com/airbytehq/airbyte/pull/8501) | Remove excessive logging for Avro and Parquet invalid date strings. | -| 0.1.14 | 2021-11-09 | [\#7732](https://github.com/airbytehq/airbyte/pull/7732) | Support timestamp in Avro and Parquet | -| 0.1.13 | 2021-11-03 | [\#7288](https://github.com/airbytehq/airbyte/issues/7288) | Support Json `additionalProperties`. | -| 0.1.12 | 2021-09-13 | [\#5720](https://github.com/airbytehq/airbyte/issues/5720) | Added configurable block size for stream. Each stream is limited to 10,000 by S3 | -| 0.1.11 | 2021-09-10 | [\#5729](https://github.com/airbytehq/airbyte/pull/5729) | For field names that start with a digit, a `*` will be appended at the beginning for the`Parquet`and`Avro`formats. | -| 0.1.10 | 2021-08-17 | [\#4699](https://github.com/airbytehq/airbyte/pull/4699) | Added json config validator | -| 0.1.9 | 2021-07-12 | [\#4666](https://github.com/airbytehq/airbyte/pull/4666) | Fix MinIO output for Parquet format. | -| 0.1.8 | 2021-07-07 | [\#4613](https://github.com/airbytehq/airbyte/pull/4613) | Patched schema converter to support combined restrictions. | -| 0.1.7 | 2021-06-23 | [\#4227](https://github.com/airbytehq/airbyte/pull/4227) | Added Avro and JSONL output. | -| 0.1.6 | 2021-06-16 | [\#4130](https://github.com/airbytehq/airbyte/pull/4130) | Patched the check to verify prefix access instead of full-bucket access. | -| 0.1.5 | 2021-06-14 | [\#3908](https://github.com/airbytehq/airbyte/pull/3908) | Fixed default`max_padding_size_mb`in`spec.json`. | -| 0.1.4 | 2021-06-14 | [\#3908](https://github.com/airbytehq/airbyte/pull/3908) | Added Parquet output. | -| 0.1.3 | 2021-06-13 | [\#4038](https://github.com/airbytehq/airbyte/pull/4038) | Added support for alternative S3. | -| 0.1.2 | 2021-06-10 | [\#4029](https://github.com/airbytehq/airbyte/pull/4029) | Fixed `\_airbyte_emitted_at`field to be a UTC instead of local timestamp for consistency. | -| 0.1.1 | 2021-06-09 | [\#3973](https://github.com/airbytehq/airbyte/pull/3973) | Added`AIRBYTE_ENTRYPOINT` in base Docker image for Kubernetes support. | -| 0.1.0 | 2021-06-03 | [\#3672](https://github.com/airbytehq/airbyte/pull/3672) | Initial release with CSV output. | +| Version | Date | Pull Request | Subject | +|:-----------|:-----------|:-----------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------| +| 1.5.0-rc.4 | 2025-01-06 | [50954](https://github.com/airbytehq/airbyte/pull/50954) | Bug fix: StreamLoader::close dispatched multiple times per stream | +| 1.5.0-rc.3 | 2025-01-06 | [50949](https://github.com/airbytehq/airbyte/pull/50949) | Bug fix: parquet types/values nested in union of objects do not convert properly | +| 1.5.0-rc.2 | 2025-01-02 | [50857](https://github.com/airbytehq/airbyte/pull/50857) | Migrate to Bulk Load CDK: cost reduction, perf increase, bug fix for filename clashes | +| 1.4.0 | 2024-10-23 | [46302](https://github.com/airbytehq/airbyte/pull/46302) | add support for file transfer | +| 1.3.0 | 2024-09-30 | [46281](https://github.com/airbytehq/airbyte/pull/46281) | fix tests | +| 1.2.1 | 2024-09-20 | [45700](https://github.com/airbytehq/airbyte/pull/45700) | Improve resiliency to jsonschema fields | +| 1.2.0 | 2024-09-18 | [45402](https://github.com/airbytehq/airbyte/pull/45402) | fix exception with columnless streams | +| 1.1.0 | 2024-09-18 | [45436](https://github.com/airbytehq/airbyte/pull/45436) | upgrade all dependencies | +| 1.0.5 | 2024-09-05 | [45143](https://github.com/airbytehq/airbyte/pull/45143) | don't overwrite (and delete) existing files, skip indexes instead | +| 1.0.4 | 2024-08-30 | [44933](https://github.com/airbytehq/airbyte/pull/44933) | Fix: Avro/Parquet: handle empty schemas in nested objects/lists | +| 1.0.3 | 2024-08-20 | [44476](https://github.com/airbytehq/airbyte/pull/44476) | Increase message parsing limit to 100mb | +| 1.0.2 | 2024-08-19 | [44401](https://github.com/airbytehq/airbyte/pull/44401) | Fix: S3 Avro/Parquet: handle nullable top-level schema | +| 1.0.1 | 2024-08-14 | [42579](https://github.com/airbytehq/airbyte/pull/42579) | OVERWRITE MODE: Deletes deferred until successful sync. | +| 1.0.0 | 2024-08-08 | [42409](https://github.com/airbytehq/airbyte/pull/42409) | Major breaking changes: new destination schema, change capture, Avro/Parquet improvements, bugfixes | +| 0.1.15 | 2024-12-18 | [49879](https://github.com/airbytehq/airbyte/pull/49879) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.6.7 | 2024-08-11 | [43713](https://github.com/airbytehq/airbyte/issues/43713) | Decreased memory ratio (0.7 -> 0.5) and thread allocation (5 -> 2) for async S3 uploads. | +| 0.6.6 | 2024-08-06 | [43343](https://github.com/airbytehq/airbyte/pull/43343) | Use Kotlin 2.0.0 | +| 0.6.5 | 2024-08-01 | [42405](https://github.com/airbytehq/airbyte/pull/42405) | S3 parallelizes workloads, checkpoints, submits counts, support for generationId in metadata for refreshes. | +| 0.6.4 | 2024-04-16 | [42006](https://github.com/airbytehq/airbyte/pull/42006) | remove unnecessary zookeeper dependency | +| 0.6.3 | 2024-04-15 | [38204](https://github.com/airbytehq/airbyte/pull/38204) | convert all production code to kotlin | +| 0.6.2 | 2024-04-15 | [38204](https://github.com/airbytehq/airbyte/pull/38204) | add assume role auth | +| 0.6.1 | 2024-04-08 | [37546](https://github.com/airbytehq/airbyte/pull/37546) | Adapt to CDK 0.30.8; | +| 0.6.0 | 2024-04-08 | [36869](https://github.com/airbytehq/airbyte/pull/36869) | Adapt to CDK 0.29.8; Kotlin converted code. | +| 0.5.9 | 2024-02-22 | [35569](https://github.com/airbytehq/airbyte/pull/35569) | Fix logging bug. | +| 0.5.8 | 2024-01-03 | [#33924](https://github.com/airbytehq/airbyte/pull/33924) | Add new ap-southeast-3 AWS region | +| 0.5.7 | 2023-12-28 | [#33788](https://github.com/airbytehq/airbyte/pull/33788) | Thread-safe fix for file part names | +| 0.5.6 | 2023-12-08 | [#33263](https://github.com/airbytehq/airbyte/pull/33263) | (incorrect filename format, do not use) Adopt java CDK version 0.7.0. | +| 0.5.5 | 2023-12-08 | [#33264](https://github.com/airbytehq/airbyte/pull/33264) | Update UI options with common defaults. | +| 0.5.4 | 2023-11-06 | [#32193](https://github.com/airbytehq/airbyte/pull/32193) | (incorrect filename format, do not use) Adopt java CDK version 0.4.1. | +| 0.5.3 | 2023-11-03 | [#32050](https://github.com/airbytehq/airbyte/pull/32050) | (incorrect filename format, do not use) Adopt java CDK version 0.4.0. This updates filenames to include a UUID. | +| 0.5.1 | 2023-06-26 | [#27786](https://github.com/airbytehq/airbyte/pull/27786) | Fix build | +| 0.5.0 | 2023-06-26 | [#27725](https://github.com/airbytehq/airbyte/pull/27725) | License Update: Elv2 | +| 0.4.2 | 2023-06-21 | [#27555](https://github.com/airbytehq/airbyte/pull/27555) | Reduce image size | +| 0.4.1 | 2023-05-18 | [#26284](https://github.com/airbytehq/airbyte/pull/26284) | Fix: reenable LZO compression for Parquet output | +| 0.4.0 | 2023-04-28 | [#25570](https://github.com/airbytehq/airbyte/pull/25570) | Fix: all integer schemas should be converted to Avro longs | +| 0.3.25 | 2023-04-27 | [#25346](https://github.com/airbytehq/airbyte/pull/25346) | Internal code cleanup | +| 0.3.23 | 2023-03-30 | [#24736](https://github.com/airbytehq/airbyte/pull/24736) | Improve behavior when throttled by AWS API | +| 0.3.22 | 2023-03-17 | [#23788](https://github.com/airbytehq/airbyte/pull/23788) | S3-Parquet: added handler to process null values in arrays | +| 0.3.21 | 2023-03-10 | [#23466](https://github.com/airbytehq/airbyte/pull/23466) | Changed S3 Avro type from Int to Long | +| 0.3.20 | 2023-02-23 | [#21355](https://github.com/airbytehq/airbyte/pull/21355) | Add root level flattening option to JSONL output. | +| 0.3.19 | 2023-01-18 | [#21087](https://github.com/airbytehq/airbyte/pull/21087) | Wrap Authentication Errors as Config Exceptions | +| 0.3.18 | 2022-12-15 | [\#20088](https://github.com/airbytehq/airbyte/pull/20088) | New data type support v0/v1 | +| 0.3.17 | 2022-10-15 | [\#18031](https://github.com/airbytehq/airbyte/pull/18031) | Fix integration tests to use bucket path | +| 0.3.16 | 2022-10-03 | [\#17340](https://github.com/airbytehq/airbyte/pull/17340) | Enforced encrypted only traffic to S3 buckets and check logic | +| 0.3.15 | 2022-09-01 | [\#16243](https://github.com/airbytehq/airbyte/pull/16243) | Fix Json to Avro conversion when there is field name clash from combined restrictions (`anyOf`, `oneOf`, `allOf` fields). | +| 0.3.14 | 2022-08-24 | [\#15207](https://github.com/airbytehq/airbyte/pull/15207) | Fix S3 bucket path to be used for check. | +| 0.3.13 | 2022-08-09 | [\#15394](https://github.com/airbytehq/airbyte/pull/15394) | Added LZO compression support to Parquet format | +| 0.3.12 | 2022-08-05 | [\#14801](https://github.com/airbytehq/airbyte/pull/14801) | Fix multiple log bindings | +| 0.3.11 | 2022-07-15 | [\#14494](https://github.com/airbytehq/airbyte/pull/14494) | Make S3 output filename configurable. | +| 0.3.10 | 2022-06-30 | [\#14332](https://github.com/airbytehq/airbyte/pull/14332) | Change INSTANCE\*PROFILE to use `AWSDefaultProfileCredential`, which supports more authentications on AWS | +| 0.3.9 | 2022-06-24 | [\#14114](https://github.com/airbytehq/airbyte/pull/14114) | Remove "additionalProperties": false from specs for connectors with staging | +| 0.3.8 | 2022-06-17 | [\#13753](https://github.com/airbytehq/airbyte/pull/13753) | Deprecate and remove PART_SIZE_MB fields from connectors based on StreamTransferManager | +| 0.3.7 | 2022-06-14 | [\#13483](https://github.com/airbytehq/airbyte/pull/13483) | Added support for int, long, float data types to Avro/Parquet formats. | +| 0.3.6 | 2022-05-19 | [\#13043](https://github.com/airbytehq/airbyte/pull/13043) | Destination S3: Remove configurable part size. | +| 0.3.5 | 2022-05-12 | [\#12797](https://github.com/airbytehq/airbyte/pull/12797) | Update spec to replace markdown. | +| 0.3.4 | 2022-05-04 | [\#12578](https://github.com/airbytehq/airbyte/pull/12578) | In JSON to Avro conversion, log JSON field values that do not follow Avro schema for debugging. | +| 0.3.3 | 2022-04-20 | [\#12167](https://github.com/airbytehq/airbyte/pull/12167) | Add gzip compression option for CSV and JSONL formats. | +| 0.3.2 | 2022-04-22 | [\#11795](https://github.com/airbytehq/airbyte/pull/11795) | Fix the connection check to verify the provided bucket path. | +| 0.3.1 | 2022-04-05 | [\#11728](https://github.com/airbytehq/airbyte/pull/11728) | Properly clean-up bucket when running OVERWRITE sync mode | +| 0.3.0 | 2022-04-04 | [\#11666](https://github.com/airbytehq/airbyte/pull/11666) | 0.2.12 actually has breaking changes since files are compressed by default, this PR also fixes the naming to be more compatible with older versions. | +| 0.2.13 | 2022-03-29 | [\#11496](https://github.com/airbytehq/airbyte/pull/11496) | Fix S3 bucket path to be included with S3 bucket format | +| 0.2.12 | 2022-03-28 | [\#11294](https://github.com/airbytehq/airbyte/pull/11294) | Change to serialized buffering strategy to reduce memory consumption | +| 0.2.11 | 2022-03-23 | [\#11173](https://github.com/airbytehq/airbyte/pull/11173) | Added support for AWS Glue crawler | +| 0.2.10 | 2022-03-07 | [\#10856](https://github.com/airbytehq/airbyte/pull/10856) | `check` method now tests for listObjects permissions on the target bucket | +| 0.2.7 | 2022-02-14 | [\#10318](https://github.com/airbytehq/airbyte/pull/10318) | Prevented double slashes in S3 destination path | +| 0.2.6 | 2022-02-14 | [10256](https://github.com/airbytehq/airbyte/pull/10256) | Add `-XX:+ExitOnOutOfMemoryError` JVM option | +| 0.2.5 | 2022-01-13 | [\#9399](https://github.com/airbytehq/airbyte/pull/9399) | Use instance profile authentication if credentials are not provided | +| 0.2.4 | 2022-01-12 | [\#9415](https://github.com/airbytehq/airbyte/pull/9415) | BigQuery Destination : Fix GCS processing of Facebook data | +| 0.2.3 | 2022-01-11 | [\#9367](https://github.com/airbytehq/airbyte/pull/9367) | Avro & Parquet: support array field with unknown item type; default any improperly typed field to string. | +| 0.2.2 | 2021-12-21 | [\#8574](https://github.com/airbytehq/airbyte/pull/8574) | Added namespace to Avro and Parquet record types | +| 0.2.1 | 2021-12-20 | [\#8974](https://github.com/airbytehq/airbyte/pull/8974) | Release a new version to ensure there is no excessive logging. | +| 0.2.0 | 2021-12-15 | [\#8607](https://github.com/airbytehq/airbyte/pull/8607) | Change the output filename for CSV files - it's now `bucketPath/namespace/streamName/timestamp_epochMillis_randomUuid.csv` | +| 0.1.16 | 2021-12-10 | [\#8562](https://github.com/airbytehq/airbyte/pull/8562) | Swap dependencies with destination-jdbc. | +| 0.1.15 | 2021-12-03 | [\#8501](https://github.com/airbytehq/airbyte/pull/8501) | Remove excessive logging for Avro and Parquet invalid date strings. | +| 0.1.14 | 2021-11-09 | [\#7732](https://github.com/airbytehq/airbyte/pull/7732) | Support timestamp in Avro and Parquet | +| 0.1.13 | 2021-11-03 | [\#7288](https://github.com/airbytehq/airbyte/issues/7288) | Support Json `additionalProperties`. | +| 0.1.12 | 2021-09-13 | [\#5720](https://github.com/airbytehq/airbyte/issues/5720) | Added configurable block size for stream. Each stream is limited to 10,000 by S3 | +| 0.1.11 | 2021-09-10 | [\#5729](https://github.com/airbytehq/airbyte/pull/5729) | For field names that start with a digit, a `*` will be appended at the beginning for the`Parquet`and`Avro`formats. | +| 0.1.10 | 2021-08-17 | [\#4699](https://github.com/airbytehq/airbyte/pull/4699) | Added json config validator | +| 0.1.9 | 2021-07-12 | [\#4666](https://github.com/airbytehq/airbyte/pull/4666) | Fix MinIO output for Parquet format. | +| 0.1.8 | 2021-07-07 | [\#4613](https://github.com/airbytehq/airbyte/pull/4613) | Patched schema converter to support combined restrictions. | +| 0.1.7 | 2021-06-23 | [\#4227](https://github.com/airbytehq/airbyte/pull/4227) | Added Avro and JSONL output. | +| 0.1.6 | 2021-06-16 | [\#4130](https://github.com/airbytehq/airbyte/pull/4130) | Patched the check to verify prefix access instead of full-bucket access. | +| 0.1.5 | 2021-06-14 | [\#3908](https://github.com/airbytehq/airbyte/pull/3908) | Fixed default`max_padding_size_mb`in`spec.json`. | +| 0.1.4 | 2021-06-14 | [\#3908](https://github.com/airbytehq/airbyte/pull/3908) | Added Parquet output. | +| 0.1.3 | 2021-06-13 | [\#4038](https://github.com/airbytehq/airbyte/pull/4038) | Added support for alternative S3. | +| 0.1.2 | 2021-06-10 | [\#4029](https://github.com/airbytehq/airbyte/pull/4029) | Fixed `\_airbyte_emitted_at`field to be a UTC instead of local timestamp for consistency. | +| 0.1.1 | 2021-06-09 | [\#3973](https://github.com/airbytehq/airbyte/pull/3973) | Added`AIRBYTE_ENTRYPOINT` in base Docker image for Kubernetes support. | +| 0.1.0 | 2021-06-03 | [\#3672](https://github.com/airbytehq/airbyte/pull/3672) | Initial release with CSV output. |
diff --git a/docs/integrations/destinations/snowflake.md b/docs/integrations/destinations/snowflake.md index fe5fa3e7b036..728d47f0cfed 100644 --- a/docs/integrations/destinations/snowflake.md +++ b/docs/integrations/destinations/snowflake.md @@ -131,7 +131,7 @@ to role identifier($airbyte_role); commit; ``` -3. Run the script using the [Worksheet page](https://docs.snowflake.com/en/user-guide/ui-worksheet.html) or [Snowsight](https://docs.snowflake.com/en/user-guide/ui-snowsight-gs.html). +3. Run the script using the [Worksheet page](https://docs.snowflake.com/en/user-guide/ui-worksheet.html) or [Snowsight](https://docs.snowflake.com/en/user-guide/ui-snowsight-gs.html). Make sure to select the **All Queries** checkbox if using the Classic Console or select and highlight the entire query if you are using Snowsight. ### Step 2: Set up a data loading method @@ -266,8 +266,10 @@ desired namespace. | Version | Date | Pull Request | Subject | | :-------------- | :--------- | :--------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 3.15.0 | 2024-09-18 | [\#45437](https://github.com/airbytehq/airbyte/pull/45437) | upgrade all dependencies | -| 3.14.0 | 2024-09-18 | [\#45431](https://github.com/airbytehq/airbyte/pull/45431) | truncate large records queries | +| 3.15.2 | 2024-10-31 | [\#48070](https://github.com/airbytehq/airbyte/pull/48070) | upgrade JDBC driver to 3.20.0 | +| 3.15.1 | 2024-10-20 | [\#46989](https://github.com/airbytehq/airbyte/pull/46989) | add snowflake transaction wrapper for rollback support | +| 3.15.0 | 2024-09-18 | [\#45437](https://github.com/airbytehq/airbyte/pull/45437) | upgrade all dependencies | +| 3.14.0 | 2024-09-18 | [\#45431](https://github.com/airbytehq/airbyte/pull/45431) | truncate large records queries | | 3.13.0 | 2024-09-17 | [\#45422](https://github.com/airbytehq/airbyte/pull/45422) | speed up metadata queries | | 3.12.0 | 2024-09-17 | [\#38585](https://github.com/airbytehq/airbyte/pull/38585) | force UTF8 collation when creating schemas and tables | | 3.11.12 | 2024-09-12 | [\#45370](https://github.com/airbytehq/airbyte/pull/45370) | fix a race condition in our orphanedThreadFilter | diff --git a/docs/integrations/destinations/timeplus.md b/docs/integrations/destinations/timeplus.md index 0a95e23e88d4..b37067ebcf78 100644 --- a/docs/integrations/destinations/timeplus.md +++ b/docs/integrations/destinations/timeplus.md @@ -39,6 +39,10 @@ You'll need the following information to configure the Timeplus destination: | Version | Date | Pull Request | Subject | |:--------| :--------- | :-------------------------------------------------------- | :------------------- | +| 0.1.30 | 2025-01-04 | [50907](https://github.com/airbytehq/airbyte/pull/50907) | Update dependencies | +| 0.1.29 | 2024-12-28 | [50176](https://github.com/airbytehq/airbyte/pull/50176) | Update dependencies | +| 0.1.28 | 2024-12-14 | [48930](https://github.com/airbytehq/airbyte/pull/48930) | Update dependencies | +| 0.1.27 | 2024-11-25 | [48273](https://github.com/airbytehq/airbyte/pull/48273) | Update dependencies | | 0.1.26 | 2024-10-29 | [47059](https://github.com/airbytehq/airbyte/pull/47059) | Update dependencies | | 0.1.25 | 2024-10-12 | [46788](https://github.com/airbytehq/airbyte/pull/46788) | Update dependencies | | 0.1.24 | 2024-10-05 | [46443](https://github.com/airbytehq/airbyte/pull/46443) | Update dependencies | diff --git a/docs/integrations/destinations/typesense.md b/docs/integrations/destinations/typesense.md index b046d02f3cfc..f9c38eb80925 100644 --- a/docs/integrations/destinations/typesense.md +++ b/docs/integrations/destinations/typesense.md @@ -44,6 +44,11 @@ To connect a Typesense with HA, you can type multiple hosts on the host field us | Version | Date | Pull Request | Subject | |:--------| :--------- | :------------------------------------------------------- | :---------------------------- | +| 0.1.33 | 2024-12-28 | [50501](https://github.com/airbytehq/airbyte/pull/50501) | Update dependencies | +| 0.1.32 | 2024-12-21 | [50175](https://github.com/airbytehq/airbyte/pull/50175) | Update dependencies | +| 0.1.31 | 2024-12-14 | [49282](https://github.com/airbytehq/airbyte/pull/49282) | Update dependencies | +| 0.1.30 | 2024-11-25 | [48676](https://github.com/airbytehq/airbyte/pull/48676) | Update dependencies | +| 0.1.29 | 2024-11-04 | [47077](https://github.com/airbytehq/airbyte/pull/47077) | Update dependencies | | 0.1.28 | 2024-10-12 | [46810](https://github.com/airbytehq/airbyte/pull/46810) | Update dependencies | | 0.1.27 | 2024-10-05 | [46426](https://github.com/airbytehq/airbyte/pull/46426) | Update dependencies | | 0.1.26 | 2024-09-28 | [46119](https://github.com/airbytehq/airbyte/pull/46119) | Update dependencies | diff --git a/docs/integrations/destinations/vectara.md b/docs/integrations/destinations/vectara.md index 5db4d5c7b426..45733d18cb88 100644 --- a/docs/integrations/destinations/vectara.md +++ b/docs/integrations/destinations/vectara.md @@ -68,6 +68,8 @@ In addition, in the connector UI you define two set of fields for this connector | Version | Date | Pull Request | Subject | |:--------| :--------- | :-------------------------------------------------------- | :----------------------------------------------------------- | +| 0.2.31 | 2024-11-25 | [48659](https://github.com/airbytehq/airbyte/pull/48659) | Update dependencies | +| 0.2.30 | 2024-11-04 | [48222](https://github.com/airbytehq/airbyte/pull/48222) | Update dependencies | | 0.2.29 | 2024-10-29 | [47744](https://github.com/airbytehq/airbyte/pull/47744) | Update dependencies | | 0.2.28 | 2024-10-23 | [47084](https://github.com/airbytehq/airbyte/pull/47084) | Update dependencies | | 0.2.27 | 2024-10-12 | [46812](https://github.com/airbytehq/airbyte/pull/46812) | Update dependencies | diff --git a/docs/integrations/destinations/weaviate.md b/docs/integrations/destinations/weaviate.md index e0e011a898ba..472a2ece4de8 100644 --- a/docs/integrations/destinations/weaviate.md +++ b/docs/integrations/destinations/weaviate.md @@ -90,6 +90,12 @@ When using [multi-tenancy](https://weaviate.io/developers/weaviate/manage-data/m | Version | Date | Pull Request | Subject | |:--------| :--------- | :--------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------- | +| 0.2.48 | 2025-01-04 | [50908](https://github.com/airbytehq/airbyte/pull/50908) | Update dependencies | +| 0.2.47 | 2024-12-28 | [50444](https://github.com/airbytehq/airbyte/pull/50444) | Update dependencies | +| 0.2.46 | 2024-12-21 | [50182](https://github.com/airbytehq/airbyte/pull/50182) | Update dependencies | +| 0.2.45 | 2024-12-14 | [49317](https://github.com/airbytehq/airbyte/pull/49317) | Update dependencies | +| 0.2.44 | 2024-11-25 | [48640](https://github.com/airbytehq/airbyte/pull/48640) | Update dependencies | +| 0.2.43 | 2024-11-04 | [48244](https://github.com/airbytehq/airbyte/pull/48244) | Update dependencies | | 0.2.42 | 2024-10-29 | [47063](https://github.com/airbytehq/airbyte/pull/47063) | Update dependencies | | 0.2.41 | 2024-10-12 | [46848](https://github.com/airbytehq/airbyte/pull/46848) | Update dependencies | | 0.2.40 | 2024-10-05 | [46465](https://github.com/airbytehq/airbyte/pull/46465) | Update dependencies | diff --git a/docs/integrations/destinations/xata.md b/docs/integrations/destinations/xata.md index 5ebb3617a73d..aa937cf5102f 100644 --- a/docs/integrations/destinations/xata.md +++ b/docs/integrations/destinations/xata.md @@ -40,6 +40,12 @@ In order to connect, you need: | Version | Date | Pull Request | Subject | |:--------| :--------- | :-------------------------------------------------------- | :----------------------------- | +| 0.1.31 | 2025-01-04 | [50900](https://github.com/airbytehq/airbyte/pull/50900) | Update dependencies | +| 0.1.30 | 2024-12-28 | [50471](https://github.com/airbytehq/airbyte/pull/50471) | Update dependencies | +| 0.1.29 | 2024-12-21 | [50166](https://github.com/airbytehq/airbyte/pull/50166) | Update dependencies | +| 0.1.28 | 2024-12-14 | [49301](https://github.com/airbytehq/airbyte/pull/49301) | Update dependencies | +| 0.1.27 | 2024-11-25 | [48633](https://github.com/airbytehq/airbyte/pull/48633) | Update dependencies | +| 0.1.26 | 2024-11-04 | [48162](https://github.com/airbytehq/airbyte/pull/48162) | Update dependencies | | 0.1.25 | 2024-10-29 | [47076](https://github.com/airbytehq/airbyte/pull/47076) | Update dependencies | | 0.1.24 | 2024-10-12 | [46765](https://github.com/airbytehq/airbyte/pull/46765) | Update dependencies | | 0.1.23 | 2024-10-05 | [46467](https://github.com/airbytehq/airbyte/pull/46467) | Update dependencies | diff --git a/docs/integrations/enterprise-connectors/source-oracle.md b/docs/integrations/enterprise-connectors/source-oracle.md index a205e6851824..b9cd0549a63c 100644 --- a/docs/integrations/enterprise-connectors/source-oracle.md +++ b/docs/integrations/enterprise-connectors/source-oracle.md @@ -5,12 +5,11 @@ Airbyte Enterprise Connectors are a selection of premium connectors available ex ::: -Airbyte's incubating Oracle enterprise source connector offers the following features: +Airbyte's Oracle enterprise source connector offers the following features: - Incremental as well as Full Refresh [sync modes](https://docs.airbyte.com/cloud/core-concepts#connection-sync-modes), providing flexibility in how data is delivered to your destination. - Note that incremental syncs using [Change Data Capture (CDC)](https://docs.airbyte.com/understanding-airbyte/cdc) are not yet supported. - Reliable replication at any table size with [checkpointing](https://docs.airbyte.com/understanding-airbyte/airbyte-protocol/#state--checkpointing) and chunking of database reads. @@ -19,19 +18,17 @@ The required minimum platform version is v0.58.0 for this connector. ## Features -| Feature | Supported | Notes | -| :---------------------------- | :---------- | :----------------- | -| Full Refresh Sync | Yes | | -| Incremental Sync - Append | Yes | | -| Replicate Incremental Deletes | Coming soon | | -| CDC (Change Data Capture) | Coming soon | | -| SSL Support | Yes | | -| SSH Tunnel Connection | Yes | | -| Namespaces | Yes | Enabled by default | +| Feature | Supported | Notes | +| :---------------------------- |:----------| :----------------- | +| Full Refresh Sync | Yes | | +| Incremental Sync - Append | Yes | | +| Replicate Incremental Deletes | Yes | | +| Change Data Capture (CDC) | Yes | | +| SSL Support | Yes | | +| SSH Tunnel Connection | Yes | | +| Namespaces | Yes | Enabled by default | -The Oracle source does not alter the schema present in your database. Depending on the destination -connected to this source, however, the schema may be altered. See the destination's documentation -for more details. +From the point of view of the Oracle database instance, the Enterprise Oracle source operates strictly in a read-only fashion. ## Getting Started @@ -45,9 +42,37 @@ for more details. This is dependent on your networking setup. The easiest way to verify if Airbyte is able to connect to your Oracle instance is by testing the connection in the UI. -#### 2. Create a dedicated read-only user with access to the relevant tables (Recommended but optional) +#### 2. If using CDC, make sure your database can run LogMiner and that supplemental logging is enabled for all relevant tables -This step is optional but highly recommended to allow for better permission control and auditing. Alternatively, you can use Airbyte with an existing user in your database. +Skip this step if you don't intend to perform CDC incremental syncs. + +This connector relies on [Debezium](https://debezium.io/documentation/reference/stable/connectors/oracle.html) to perform CDC incremental syncs, and Debezium in turn relies on [Oracle LogMiner](https://docs.oracle.com/en/database/oracle/oracle-database/23/sutil/oracle-logminer-utility.html). +LogMiner is typically not enabled by default and requires some extra steps to enable. +What form these steps take depends on whether the Oracle instance is managed via Amazon RDS or not. + +In the case of an Amazon RDS instance, the steps are as follows: +1. Check that `SELECT LOG_MODE FROM V$DATABASE` returns `ARCHIVELOG`. If not, ensure that backups are enabled. +2. Execute `exec rdsadmin.rdsadmin_util.set_configuration('archivelog retention hours',24)`, possibly replacing 24 with a more suitable value depending on the intended sync frequency. For instance, if the sync is intended to be run daily, then a retention period spanning multiple days is advisable. +3. Execute `exec rdsadmin.rdsadmin_util.alter_supplemental_logging('ADD')` to enable supplemental logging on the database. + +In the case of any other Oracle instance, the steps are as follows: +1. `CONNECT ... AS SYSDBA` using [SQL Plus](https://en.wikipedia.org/wiki/SQL_Plus) or equivalent. +2. Provision the redo log files with something along the lines of `ALTER SYSTEM SET db_recovery_file_dest_size = 10G` and `ALTER SYSTEM SET db_recovery_file_dest = '/opt/oracle/oradata/recovery_area' SCOPE=SPFILE` but replacing the `10G` and directory path arguments with suitable values. Note that the directory in the path needs to exist. +3. Shut down and restart the instance with `SHUTDOWN IMMEDIATE` and `STARTUP MOUNT`. +4. `ALTER DATABASE ARCHIVELOG`, `ALTER DATABASE ADD SUPPLEMENTAL LOG DATA` and `ALTER DATABASE OPEN` to restart the database with supplemental logging enabled. + +At this point, RDS instance or not, all that remains to prepare the database for CDC incremental syncs is to enable supplemental logging on each of the relevant tables: +```sql +ALTER TABLE ... ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS; +``` + +If you need more help preparing the database, see [Preparing the database](https://debezium.io/documentation/reference/stable/connectors/oracle.html#_preparing_the_database) in Debezium's docs. + +#### 3. Create a dedicated read-only user with access to the relevant tables + +This step is optional but highly recommended to allow for better permission control and auditing. +This step is even more highly recommended when performing CDC incremental syncs, as the user will require a very specific set of database privileges. +Alternatively, you can use Airbyte with an existing user in your database. To create a dedicated database user, run the following commands against your database: @@ -69,11 +94,40 @@ GRANT SELECT ON ""."" TO airbyte; GRANT SELECT ON ""."" TO airbyte; ``` -Your database user should now be ready for use with Airbyte. +Your database user should now be ready for use with Airbyte, except for CDC incremental syncs. -#### 3. Include the schemas Airbyte should look at when configuring the Airbyte Oracle Source. +#### 4. If using CDC incremental syncs, grant your user extra permissions -Case sensitive. Defaults to the upper-cased user if empty. If the user does not have access to the configured schemas, no tables will be discovered and the connection test will fail. +Skip this step if you don't intend to perform CDC incremental syncs. + +These requirements are driven by the connector's use of [Debezium](https://debezium.io/documentation/reference/stable/connectors/oracle.html#creating-users-for-the-connector) which in turn uses [LogMiner](https://docs.oracle.com/en/database/oracle/oracle-database/23/sutil/oracle-logminer-utility.html). + +```sql +GRANT FLASHBACK ANY TABLE TO airbyte; +GRANT SELECT ANY TABLE TO airbyte; +GRANT SELECT_CATALOG_ROLE TO airbyte; +GRANT EXECUTE_CATALOG_ROLE TO airbyte; +GRANT SELECT ANY TRANSACTION TO airbyte; +GRANT LOGMINING TO airbyte; +GRANT CREATE TABLE TO airbyte; +GRANT LOCK ANY TABLE TO airbyte; +GRANT CREATE SEQUENCE TO airbyte; +``` + +If the database instance is a multitenant CDB instance, then these grant statements need to be supplemented with the `CONTAINER=ALL` clause. +Furthermore, an extra privilege is required: + +```sql +GRANT SET CONTAINER TO airbyte CONTAINER=ALL; +``` + +The exact set of permissions varies depending on the Oracle database instance version. + +#### 5. Include the schemas Airbyte should look at when configuring the Airbyte Oracle Source + +Case-sensitive. +Defaults to the upper-cased user if empty. +If the user does not have access to the configured schemas, no tables will be discovered and the connection test will fail. ### Airbyte Cloud @@ -155,69 +209,81 @@ by the `authorized_keys` file on your bastion host. The public key should be add host to whichever user you want to use with Airbyte. The private key is provided via copy-and-paste to the Airbyte connector configuration screen, so it may log in to the bastion. -## Change Data Capture (CDC) +## Change Data Capture (CDC) limitations + +The Enterprise Oracle source connector supports incremental syncs using CDC with some limitations. +Some of these are readily apparent in the database and user setup steps described above: +- CDC availability is subject to a log retention period, +- CDC requires more user privileges, +- CDC requires supplemental logging and other settings at the Oracle instance level. + +In addition to these, LogMiner, which our CDC relies on, has a few quirks: +- tables with names longer than 30 characters are simply ignored, +- columns with names longer than 30 characters are simply ignored. -We aim to support Oracle CDC soon. Please reach out to your sales engineer if you are interested in being a design partner for CDC support in Oracle. +Finally, LogMiner does not support all datatypes. +See table below for details. +If a type is not listed in the table, for instance any user-defined type such as a VARRAY, then it is not supported for CDC. ## Data type mapping Oracle data types are mapped to the following data types when synchronizing data. -| Oracle Type | Airbyte Type | Notes | -| :------------------------------- | :---------------------- | :-------------------------- | -| `BFILE` | string | base-64 encoded binary data | -| `BINARY_FLOAT` | number | | -| `BINARY_DOUBLE` | number | | -| `BLOB` | string | base-64 encoded binary data | -| `BOOL` | boolean | | -| `BOOLEAN` | boolean | | -| `CHAR` | string | | -| `CHAR VARYING` | string | | -| `CHARACTER` | string | | -| `CHARACTER VARYING` | string | | -| `CLOB` | string | | -| `DATE` | date | | -| `DEC` | number | integer when scale is 0 | -| `DECIMAL` | number | integer when scale is 0 | -| `FLOAT` | number | | -| `DOUBLE PRECISION` | number | | -| `REAL` | number | | -| `INT` | number | integer | -| `INTEGER` | number | integer | -| `INTERVAL YEAR TO MONTH` | string | | -| `INTERVAL DAY TO SECOND` | string | | -| `INTERVALDS` | string | | -| `INTERVALYM` | string | | -| `JSON` | object | | -| `LONG` | string | base-64 encoded binary data | -| `LONG RAW` | string | base-64 encoded binary data | -| `NATIONAL CHAR` | string | | -| `NATIONAL CHAR VARYING` | string | | -| `NATIONAL CHARACTER` | string | | -| `NATIONAL CHARACTER VARYING` | string | | -| `NCHAR` | string | | -| `NCHAR VARYING` | string | | -| `NCLOB` | string | | -| `NUMBER` | number | integer when scale is 0 | -| `NUMERIC` | number | integer when scale is 0 | -| `NVARCHAR2` | string | | -| `RAW` | string | base-64 encoded binary data | -| `ROWID` | string | base-64 encoded binary data | -| `SMALLINT` | number | integer | -| `TIMESTAMP` | timestamp | | -| `TIMESTAMP WITH LOCAL TIME ZONE` | timestamp | | -| `TIMESTAMP WITH LOCAL TZ` | timestamp | | -| `TIMESTAMP WITH TIME ZONE` | timestamp with timezone | | -| `TIMESTAMP WITH TZ` | timestamp with timezone | | -| `UROWID` | string | base-64 encoded binary data | -| `VARCHAR` | string | | -| `VARCHAR2` | string | | +| Oracle Type | Airbyte Type | Notes | CDC | +| :------------------------------- |:------------------------|:----------------------------|-----| +| `BFILE` | string | base-64 encoded binary data | | +| `BINARY_FLOAT` | number | | ✓ | +| `BINARY_DOUBLE` | number | | ✓ | +| `BLOB` | string | base-64 encoded binary data | | +| `BOOL` | boolean | | | +| `BOOLEAN` | boolean | | | +| `CHAR` | string | | ✓ | +| `CHAR VARYING` | string | | ✓ | +| `CHARACTER` | string | | ✓ | +| `CHARACTER VARYING` | string | | ✓ | +| `CLOB` | string | | | +| `DATE` | timestamp | surprisingly, not a date | ✓ | +| `DEC` | number | integer when scale is 0 | ✓ | +| `DECIMAL` | number | integer when scale is 0 | ✓ | +| `FLOAT` | number | | ✓ | +| `DOUBLE PRECISION` | number | | ✓ | +| `REAL` | number | | ✓ | +| `INT` | number | integer | ✓ | +| `INTEGER` | number | integer | ✓ | +| `INTERVAL YEAR TO MONTH` | string | | ✓ | +| `INTERVAL DAY TO SECOND` | string | | ✓ | +| `INTERVALDS` | string | | ✓ | +| `INTERVALYM` | string | | ✓ | +| `JSON` | object | | | +| `LONG` | string | base-64 encoded binary data | | +| `LONG RAW` | string | base-64 encoded binary data | | +| `NATIONAL CHAR` | string | | ✓ | +| `NATIONAL CHAR VARYING` | string | | ✓ | +| `NATIONAL CHARACTER` | string | | ✓ | +| `NATIONAL CHARACTER VARYING` | string | | ✓ | +| `NCHAR` | string | | ✓ | +| `NCHAR VARYING` | string | | ✓ | +| `NCLOB` | string | | | +| `NUMBER` | number | integer when scale is 0 | ✓ | +| `NUMERIC` | number | integer when scale is 0 | ✓ | +| `NVARCHAR2` | string | | ✓ | +| `RAW` | string | base-64 encoded binary data | | +| `ROWID` | string | base-64 encoded binary data | | +| `SMALLINT` | number | integer | ✓ | +| `TIMESTAMP` | timestamp | | ✓ | +| `TIMESTAMP WITH LOCAL TIME ZONE` | timestamp | | ✓ | +| `TIMESTAMP WITH LOCAL TZ` | timestamp | | ✓ | +| `TIMESTAMP WITH TIME ZONE` | timestamp with timezone | | ✓ | +| `TIMESTAMP WITH TZ` | timestamp with timezone | | ✓ | +| `UROWID` | string | base-64 encoded binary data | | +| `VARCHAR` | string | | ✓ | +| `VARCHAR2` | string | | ✓ | Varray types are mapped to the corresponding Airbyte array type. -This applies also to multiple levels of nesting, i.e. varrays of varrays, and so forth. +This applies also to multiple levels of nesting, i.e. VARRAYs of VARRAYs, and so forth. -If you do not see a type in this list, assume that it is coerced into a string. We are happy to take -feedback on preferred mappings. +If you do not see a type in this list, assume that it is coerced into a string. +We are happy to take feedback on preferred mappings. ## Changelog diff --git a/docs/integrations/enterprise-connectors/source-sap-hana.md b/docs/integrations/enterprise-connectors/source-sap-hana.md new file mode 100644 index 000000000000..ee7c4ad5f9dd --- /dev/null +++ b/docs/integrations/enterprise-connectors/source-sap-hana.md @@ -0,0 +1,8 @@ +# Source SAP HANA + +:::info +Airbyte Enterprise Connectors are a selection of premium connectors available exclusively for +Airbyte Self-Managed Enterprise and Airbyte Teams customers. These connectors, built and maintained by the Airbyte team, +provide enhanced capabilities and support for critical enterprise systems. +To learn more about enterprise connectors, please [talk to our sales team](https://airbyte.com/company/talk-to-sales). +::: diff --git a/docs/integrations/enterprise-connectors/source-service-now.md b/docs/integrations/enterprise-connectors/source-service-now.md new file mode 100644 index 000000000000..86bcf0ce46b0 --- /dev/null +++ b/docs/integrations/enterprise-connectors/source-service-now.md @@ -0,0 +1,62 @@ +# Source ServiceNow + +:::info +Airbyte Enterprise Connectors are a selection of premium connectors available exclusively for Airbyte Self-Managed Enterprise and Airbyte Teams customers. These connectors, built and maintained by the Airbyte team, provide enhanced capabilities and support for critical enterprise systems. To learn more about enterprise connectors, please [talk to our sales team](https://airbyte.com/company/talk-to-sales). +::: + +Airbyte’s incubating ServiceNow enterprise source connector currently offers Full Refresh syncs for streams that are part of Software Asset Management and Configuration Management Database applications. + +## Features + +| Feature | Supported?\(Yes/No\) | Notes | +| :---------------- | :------------------- | :---- | +| Full Refresh Sync | Yes | | +| Incremental Sync | No | | + +## Setup Guide + +1. Enter your ServiceNow environment as the Base URL. +2. Enter the username and password for a ServiceNow user account that has access to all tables that you want to include in the connection. + +![ServiceNow Connector setup with credentials](https://raw.githubusercontent.com/airbytehq/airbyte/refs/heads/master/docs/enterprise-setup/assets/enterprise-connectors/service-now-setup.png) + +## Supported streams + +### Configuration Management Database (CMDB) + +- cmdb_ci_wap_network +- cmdb_ci_ip_router +- cmdb_ci_ip_switch +- cmdb_ci_lb_bigip +- cmdb_ci_ip_firewall +- cmdb_ci_printer +- cmdb_ci_scanner +- cmdb_ci_linux_server +- cmdb_ci_comm +- cmdb_ci_win_server +- cmdb_ci_ucs_chassis +- cmdb_ci_storage_switch +- cmdb_ci_pc_hardware +- cmdb_ci_esx_server +- cmdb_ci_aix_server +- cmdb_ci_solaris_server +- cmdb_ci_chassis_server +- cmdb_ci_server +- cmdb_ci_net_app_server + +### Software Asset Management (SAM) + +- cmdb_model_category +- sam_sw_product_lifecycle +- alm_license + +## Changelog + +
+ Expand to review + +The connector is still incubating; this section exists to satisfy Airbyte's QA checks. + +- 0.1.0 + +
diff --git a/docs/integrations/enterprise-connectors/source-workday.md b/docs/integrations/enterprise-connectors/source-workday.md index 4b6fa22ad3ba..8f43311ebb7b 100644 --- a/docs/integrations/enterprise-connectors/source-workday.md +++ b/docs/integrations/enterprise-connectors/source-workday.md @@ -4,9 +4,11 @@ Airbyte Enterprise Connectors are a selection of premium connectors available exclusively for Airbyte Self-Managed Enterprise and Airbyte Teams customers. These connectors, built and maintained by the Airbyte team, provide enhanced capabilities and support for critical enterprise systems. To learn more about enterprise connectors, please [talk to our sales team](https://airbyte.com/company/talk-to-sales). ::: -Airbyte's incubating Workday enterprise source connector currently offers the following features: -* Full Refresh [sync mode](https://docs.airbyte.com/cloud/core-concepts#connection-sync-modes). This means that all records for all selected streams will be replaced with every sync. +Airbyte's [Workday](https://workday.com) enterprise source connector currently offers the following features: + +* Incremental as well as Full Refresh [sync modes](https://docs.airbyte.com/cloud/core-concepts#connection-sync-modes). Note that incremental syncs are only supported for specific streams. * Reliable replication at any size with [checkpointing](https://docs.airbyte.com/understanding-airbyte/airbyte-protocol/#state--checkpointing). +* Support for both REST API and Workday Report-as-a-Service (RaaS) streams. Each provided Report ID can be used as a separate stream with an auto-detected schema. Note that a separate Source must be created to use RaaS streams in addition to REST API streams. ## Features @@ -18,6 +20,73 @@ Airbyte's incubating Workday enterprise source connector currently offers the fo | SSL connection | Yes | | Namespaces | No | +## Prerequisites + +* Workday tenant - The Organization ID for your Workday environment. This can be found by logging into your Workday account and going to My Account > Organization ID +* Workday hostname - The endpoint for connecting into your Workday environment. This can be found by logging into your Workday instance and searching “Public Web Service” in the search bar and selecting the appropriate report. Use the ellipse (...) button to select **Web Service > View WSDL** + +* For REST API streams: + * Access token - An OAuth 2.0 access token for API client integrations. More information and instructions can be found in the Workday community documentation for your environment about creating and registering a Workday API Client. If you are using Airbyte Teams, when registering the API Client for Airbyte you can use https://cloud.airbyte.com/auth_flow for the Redirection URI field . If you are using Self-Managed Enterprise, you can use the URL of your Airbyte deployment instead. + +* For Report-as-a-Service (RaaS) streams: + * Workday username and password - A user account that has the necessary permissions to access the reports you want to sync. + * Report IDs - Each report in Workday has a unique Report ID. + +## Setup Guide + +### For REST API streams + +1. Log into your Airbyte Cloud account. +2. Click Sources and then click **+ New source**. +3. On the Set up the source page, select Workday. +4. Enter a name for the Workday connector. +5. Enter the Tenant and Hostname for your Workday environment. +6. Select the option for **REST API Streams**. +7. Enter the access token. +8. **Start Date (Optional)** is the earliest date for data that will be synced. If a date is not specified, all data from the last 2 years will be synced. +9. Click Set up source. + +![REST Setup](https://raw.githubusercontent.com/airbytehq/airbyte/refs/heads/master/docs/enterprise-setup/assets/enterprise-connectors/workday-rest.png) + + +### For RaaS streams + +1. Log into your Airbyte Cloud account. +2. Click Sources and then click **+ New source**. +3. On the Set up the source page, select Workday +4. Enter a name for the Workday connector. +5. Enter the Tenant and Hostname for your Workday environment. +6. Select the option for **Report Based Streams**. +7. Enter the username and password of the Workday account that can access your desired reports. +8. Enter the Report IDs for the reports you want to sync with this connector. +9. Click **Set up source**. + +![RaaS Setup](https://raw.githubusercontent.com/airbytehq/airbyte/refs/heads/master/docs/enterprise-setup/assets/enterprise-connectors/workday-raas.png) + +## Supported sync modes + +The Workday source connector supports the following [sync modes](https://docs.airbyte.com/cloud/core-concepts/#connection-sync-modes): + +* Full Refresh +* Incremental for the following REST API streams: + * Worker Payslips + * Worker Time Off Entries + +## Supported Streams + +The Workday connector supports the following REST API streams: + +* Jobs +* Job Families +* Job Profiles +* People +* Workers +* Workers Direct Reports +* Worker History +* Worker Payslips (Incremental) +* Worker Time Off Entries (Incremental) + + ## Changelog
@@ -25,6 +94,7 @@ Airbyte's incubating Workday enterprise source connector currently offers the fo The connector is still incubating, this section only exists to satisfy Airbyte's QA checks. +- 0.2.0 - 0.1.0
diff --git a/docs/integrations/sources/7shifts.md b/docs/integrations/sources/7shifts.md index 2a411f4945c6..4dd05ba3f0a6 100644 --- a/docs/integrations/sources/7shifts.md +++ b/docs/integrations/sources/7shifts.md @@ -33,6 +33,11 @@ Generate an Access Token by navigating to "Company Settings", then "Developer To | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.8 | 2024-12-28 | [50494](https://github.com/airbytehq/airbyte/pull/50494) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50183](https://github.com/airbytehq/airbyte/pull/50183) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49575](https://github.com/airbytehq/airbyte/pull/49575) | Update dependencies | +| 0.0.5 | 2024-12-12 | [48964](https://github.com/airbytehq/airbyte/pull/48964) | Update dependencies | +| 0.0.4 | 2024-11-04 | [48174](https://github.com/airbytehq/airbyte/pull/48174) | Update dependencies | | 0.0.3 | 2024-10-29 | [47829](https://github.com/airbytehq/airbyte/pull/47829) | Update dependencies | | 0.0.2 | 2024-10-28 | [47575](https://github.com/airbytehq/airbyte/pull/47575) | Update dependencies | | 0.0.1 | 2024-09-18 | | Initial release by [@topefolorunso](https://github.com/topefolorunso) via Connector Builder | diff --git a/docs/integrations/sources/adjust.md b/docs/integrations/sources/adjust.md index 5f1188d2428b..e5fe0dfe8aa3 100644 --- a/docs/integrations/sources/adjust.md +++ b/docs/integrations/sources/adjust.md @@ -42,6 +42,10 @@ The source connector supports the following [sync modes](https://docs.airbyte.co | Version | Date | Pull Request | Subject | |---------|------------| -------------------------------------------------------- |---------------------------------------------| +| 0.1.29 | 2025-01-04 | [50901](https://github.com/airbytehq/airbyte/pull/50901) | Update dependencies | +| 0.1.28 | 2024-12-28 | [50439](https://github.com/airbytehq/airbyte/pull/50439) | Update dependencies | +| 0.1.27 | 2024-12-21 | [50151](https://github.com/airbytehq/airbyte/pull/50151) | Update dependencies | +| 0.1.26 | 2024-12-14 | [49030](https://github.com/airbytehq/airbyte/pull/49030) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.1.25 | 2024-10-28 | [47046](https://github.com/airbytehq/airbyte/pull/47046) | Update dependencies | | 0.1.24 | 2024-10-12 | [46851](https://github.com/airbytehq/airbyte/pull/46851) | Update dependencies | | 0.1.23 | 2024-10-05 | [46411](https://github.com/airbytehq/airbyte/pull/46411) | Update dependencies | diff --git a/docs/integrations/sources/agilecrm.md b/docs/integrations/sources/agilecrm.md new file mode 100644 index 000000000000..ddf52f45741f --- /dev/null +++ b/docs/integrations/sources/agilecrm.md @@ -0,0 +1,40 @@ +# AgileCRM +The [Agile CRM](https://agilecrm.com/) Airbyte Connector allows you to sync and transfer data seamlessly from Agile CRM into your preferred data warehouse or analytics tool. With this connector, you can automate data extraction for various Agile CRM entities, such as contacts, companies, deals, and tasks, enabling easy integration and analysis of your CRM data in real-time. Ideal for businesses looking to streamline data workflows and enhance data accessibility. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `email` | `string` | Email Address. Your Agile CRM account email address. This is used as the username for authentication. | | +| `domain` | `string` | Domain. The specific subdomain for your Agile CRM account | | +| `api_key` | `string` | API Key. API key to use. Find it at Admin Settings -> API & Analytics -> API Key in your Agile CRM account. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| contacts | id | DefaultPaginator | ✅ | ❌ | +| companies | id | DefaultPaginator | ✅ | ❌ | +| deals | id | DefaultPaginator | ✅ | ❌ | +| notes | id | No pagination | ✅ | ❌ | +| tasks | id | No pagination | ✅ | ❌ | +| milestone | id | No pagination | ✅ | ❌ | +| campaigns | id | DefaultPaginator | ✅ | ❌ | +| documents | id | No pagination | ✅ | ❌ | +| ticket_filters | id | No pagination | ✅ | ❌ | +| tickets | | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50483](https://github.com/airbytehq/airbyte/pull/50483) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50157](https://github.com/airbytehq/airbyte/pull/50157) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49588](https://github.com/airbytehq/airbyte/pull/49588) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49279](https://github.com/airbytehq/airbyte/pull/49279) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49026](https://github.com/airbytehq/airbyte/pull/49026) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-08 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/aha.md b/docs/integrations/sources/aha.md index b79a856f3622..43dfb00362f3 100644 --- a/docs/integrations/sources/aha.md +++ b/docs/integrations/sources/aha.md @@ -42,6 +42,11 @@ Rate Limiting information is updated [here](https://www.aha.io/api#rate-limiting | Version | Date | Pull Request | Subject | |:--------|:-----------| :------------------------------------------------------- |:------------------------------------------------------------------------| +| 0.4.8 | 2024-12-28 | [50490](https://github.com/airbytehq/airbyte/pull/50490) | Update dependencies | +| 0.4.7 | 2024-12-21 | [50158](https://github.com/airbytehq/airbyte/pull/50158) | Update dependencies | +| 0.4.6 | 2024-12-14 | [49548](https://github.com/airbytehq/airbyte/pull/49548) | Update dependencies | +| 0.4.5 | 2024-12-12 | [49298](https://github.com/airbytehq/airbyte/pull/49298) | Update dependencies | +| 0.4.4 | 2024-12-11 | [48246](https://github.com/airbytehq/airbyte/pull/48246) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.4.3 | 2024-10-29 | [47904](https://github.com/airbytehq/airbyte/pull/47904) | Update dependencies | | 0.4.2 | 2024-10-28 | [47641](https://github.com/airbytehq/airbyte/pull/47641) | Update dependencies | | 0.4.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/akeneo.md b/docs/integrations/sources/akeneo.md new file mode 100644 index 000000000000..ffbb0a332e0f --- /dev/null +++ b/docs/integrations/sources/akeneo.md @@ -0,0 +1,42 @@ +# Akeneo +The Akeneo Airbyte connector enables seamless data synchronization between Akeneo PIM (Product Information Management) and other platforms. It allows you to easily extract, transform, and load product information from Akeneo to a desired data destination, facilitating efficient management and integration of product catalogs across systems. This connector supports bidirectional data flows, helping businesses maintain accurate and up-to-date product information for various sales channels. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `host` | `string` | Host. | | +| `api_username` | `string` | API Username. | | +| `password` | `string` | password. | | +| `client_id` | `string` | Client ID. | | +| `secret` | `string` | Secret. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| products | uuid | DefaultPaginator | ✅ | ❌ | +| categories | code | DefaultPaginator | ✅ | ❌ | +| families | code | DefaultPaginator | ✅ | ❌ | +| family_variants | code | DefaultPaginator | ✅ | ❌ | +| attributes | code | DefaultPaginator | ✅ | ❌ | +| attribute_groups | code | DefaultPaginator | ✅ | ❌ | +| association_types | code | DefaultPaginator | ✅ | ❌ | +| channels | code | DefaultPaginator | ✅ | ❌ | +| locales | | DefaultPaginator | ✅ | ❌ | +| currencies | code | DefaultPaginator | ✅ | ❌ | +| measure_families | code | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50454](https://github.com/airbytehq/airbyte/pull/50454) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50160](https://github.com/airbytehq/airbyte/pull/50160) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49558](https://github.com/airbytehq/airbyte/pull/49558) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49011](https://github.com/airbytehq/airbyte/pull/49011) | Update dependencies | +| 0.0.1 | 2024-10-28 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/algolia.md b/docs/integrations/sources/algolia.md index 714040af133b..6faa1592cf6f 100644 --- a/docs/integrations/sources/algolia.md +++ b/docs/integrations/sources/algolia.md @@ -35,6 +35,12 @@ Visit `https://www.algolia.com/doc/rest-api/search/#section/Authentication` for | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.8 | 2024-12-28 | [50499](https://github.com/airbytehq/airbyte/pull/50499) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50177](https://github.com/airbytehq/airbyte/pull/50177) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49560](https://github.com/airbytehq/airbyte/pull/49560) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49308](https://github.com/airbytehq/airbyte/pull/49308) | Update dependencies | +| 0.0.4 | 2024-12-11 | [49027](https://github.com/airbytehq/airbyte/pull/49027) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.3 | 2024-11-04 | [48182](https://github.com/airbytehq/airbyte/pull/48182) | Update dependencies | | 0.0.2 | 2024-10-29 | [47659](https://github.com/airbytehq/airbyte/pull/47659) | Update dependencies | | 0.0.1 | 2024-09-16 | [45605](https://github.com/airbytehq/airbyte/pull/45605) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/alpha-vantage.md b/docs/integrations/sources/alpha-vantage.md index 77688f7fcbbf..fb9c201d7d0d 100644 --- a/docs/integrations/sources/alpha-vantage.md +++ b/docs/integrations/sources/alpha-vantage.md @@ -61,6 +61,10 @@ The following fields are required fields for the connector to work: | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :-------------------------------- | +| 0.1.26 | 2025-01-04 | [50903](https://github.com/airbytehq/airbyte/pull/50903) | Update dependencies | +| 0.1.25 | 2024-12-28 | [50491](https://github.com/airbytehq/airbyte/pull/50491) | Update dependencies | +| 0.1.24 | 2024-12-21 | [50204](https://github.com/airbytehq/airbyte/pull/50204) | Update dependencies | +| 0.1.23 | 2024-12-14 | [47113](https://github.com/airbytehq/airbyte/pull/47113) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.1.22 | 2024-10-12 | [46820](https://github.com/airbytehq/airbyte/pull/46820) | Update dependencies | | 0.1.21 | 2024-10-05 | [46488](https://github.com/airbytehq/airbyte/pull/46488) | Update dependencies | | 0.1.20 | 2024-09-28 | [46152](https://github.com/airbytehq/airbyte/pull/46152) | Update dependencies | diff --git a/docs/integrations/sources/amazon-ads-migrations.md b/docs/integrations/sources/amazon-ads-migrations.md index ee21cb5dd341..6670d4aa2a55 100644 --- a/docs/integrations/sources/amazon-ads-migrations.md +++ b/docs/integrations/sources/amazon-ads-migrations.md @@ -1,5 +1,44 @@ # Amazon Ads Migration Guide + +## Upgrading to 6.0.0 + +The `SponsoredDisplayReportStream` stream now has an updated schema, thanks to a recent change in the Amazon Ads API. You can find more details in the [Amazon Migration Guide (metrics)](https://advertising.amazon.com/API/docs/en-us/reference/migration-guides/reporting-v2-v3#metrics). + +Please note that SponsoredBrandsReportStream and SponsoredBrandsVideoReportStream will become unavailable as a result of the deprecation of API V2. We recommend switching to SponsoredBrandsV3ReportStream as a great alternative. +see [Amazon Migration Guide (metrics)](https://advertising.amazon.com/API/docs/en-us/reference/migration-guides/reporting-v2-v3#metrics) for more info. + +Streams `SponsoredBrandsReportStream` `SponsoredBrandsVideoReportStream` will become unavailable. +It is recommended to use `SponsoredBrandsV3ReportStream` as an alternative. + +### Refresh affected schemas and reset data + +1. Select **Connections** in the main navbar. + 1. Select the connection(s) affected by the update. +2. Select the **Replication** tab. + 1. Select **Refresh source schema**. + 2. Select **OK**. + +```note +Any detected schema changes will be listed for your review. +``` + +3. Select **Save changes** at the bottom of the page. + 1. Ensure the **Reset affected streams** option is checked. + +```note +Depending on destination type you may not be prompted to reset your data. +``` + +4. Select **Save connection**. + +```note +This will reset the data in your destination and initiate a fresh sync. +``` + +For more information on resetting your data in Airbyte, see [this page](/operator-guides/clear). + + ## Upgrading to 5.0.0 The following streams have updated schemas due to a change with the Amazon Ads API: diff --git a/docs/integrations/sources/amazon-ads.md b/docs/integrations/sources/amazon-ads.md index 0383e2c4f1f8..b2c25c784fb4 100644 --- a/docs/integrations/sources/amazon-ads.md +++ b/docs/integrations/sources/amazon-ads.md @@ -115,7 +115,7 @@ This source is capable of syncing the following streams: - [Sponsored Products Targetings](https://advertising.amazon.com/API/docs/en-us/sponsored-products/2-0/openapi#/Product%20targeting) - [Brands Reports](https://advertising.amazon.com/API/docs/en-us/reference/sponsored-brands/2/reports) - [Brand Video Reports](https://advertising.amazon.com/API/docs/en-us/reference/sponsored-brands/2/reports) -- [Display Reports](https://advertising.amazon.com/API/docs/en-us/sponsored-display/3-0/openapi#/Reports) (Contextual targeting only) +- [Display Reports](https://advertising.amazon.com/API/docs/en-us/guides/reporting/v3/report-types/overview) - [Products Reports](https://advertising.amazon.com/API/docs/en-us/sponsored-products/2-0/openapi#/Reports) - [Attribution Reports](https://advertising.amazon.com/API/docs/en-us/amazon-attribution-prod-3p/#/) @@ -138,7 +138,7 @@ Information about expected report generation waiting time can be found [here](ht ### Data type map | Integration Type | Airbyte Type | -| :----------------------- | :----------- | +|:-------------------------|:-------------| | `string` | `string` | | `int`, `float`, `number` | `number` | | `date` | `date` | @@ -153,6 +153,17 @@ Information about expected report generation waiting time can be found [here](ht | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------| +| 6.2.4 | 2025-01-04 | [50902](https://github.com/airbytehq/airbyte/pull/50902) | Update dependencies | +| 6.2.3 | 2024-12-28 | [50478](https://github.com/airbytehq/airbyte/pull/50478) | Update dependencies | +| 6.2.2 | 2024-12-21 | [50202](https://github.com/airbytehq/airbyte/pull/50202) | Update dependencies | +| 6.2.1 | 2024-12-14 | [48229](https://github.com/airbytehq/airbyte/pull/48229) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 6.2.0 | 2024-11-12 | [48116](https://github.com/airbytehq/airbyte/pull/48116) | Migrate REST streams to low-code | +| 6.1.4 | 2024-11-12 | [48471](https://github.com/airbytehq/airbyte/pull/48471) | Bumped automatically in the pull request, please see PR description | +| 6.1.3 | 2024-11-05 | [48343](https://github.com/airbytehq/airbyte/pull/48343) | Set is_resumable only for FullRefresh streams | +| 6.1.2 | 2024-11-04 | [48138](https://github.com/airbytehq/airbyte/pull/48138) | Add error message for TooManyRequests exception | +| 6.1.1 | 2024-11-04 | [48128](https://github.com/airbytehq/airbyte/pull/48128) | Fix date parse in report streams | +| 6.1.0 | 2024-11-01 | [47940](https://github.com/airbytehq/airbyte/pull/47940) | Bump CDK to ^5 | +| 6.0.0 | 2024-10-28 | [47366](https://github.com/airbytehq/airbyte/pull/47366) | Migrate stream `SponsoredDisplayReportStream` to Amazon Ads Reports v3 | | 5.0.20 | 2024-10-29 | [47032](https://github.com/airbytehq/airbyte/pull/47032) | Update dependencies | | 5.0.19 | 2024-10-12 | [46860](https://github.com/airbytehq/airbyte/pull/46860) | Update dependencies | | 5.0.18 | 2024-10-05 | [46451](https://github.com/airbytehq/airbyte/pull/46451) | Update dependencies | diff --git a/docs/integrations/sources/amazon-seller-partner.md b/docs/integrations/sources/amazon-seller-partner.md index 6e8b8f6045ed..0b2d823b8aa9 100644 --- a/docs/integrations/sources/amazon-seller-partner.md +++ b/docs/integrations/sources/amazon-seller-partner.md @@ -162,8 +162,8 @@ Report options can be assigned on a per-stream basis that alter the behavior whe For the full list, refer to Amazon’s report type values [documentation](https://developer-docs.amazon.com/sp-api/docs/report-type-values). Certain report types have required parameters that must be defined. -For `GET_AMAZON_FULFILLED_SHIPMENTS_DATA_GENERAL` and `GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE` streams maximum value for `period_in_days` 30 days and 60 days. -So, for any value that exceeds the limit, the `period_in_days` will be automatically reduced to the limit for the stream. +For the `GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL`, `GET_AMAZON_FULFILLED_SHIPMENTS_DATA_GENERAL`, and `GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE` streams, the maximum allowable value for `period_in_days` is 30 days, 30 days, and 60 days, respectively. +If the specified `period_in_days` exceeds these limits, it will be automatically adjusted to the maximum value for the respective stream, or set to 365 days if not provided. For the Vendor Forecasting Report, we have two streams - `GET_VENDOR_FORECASTING_FRESH_REPORT` and `GET_VENDOR_FORECASTING_RETAIL_REPORT` which use the same `GET_VENDOR_FORECASTING_REPORT` Amazon's report, but with different options for the `sellingProgram` parameter - `FRESH` and `RETAIL` respectively. @@ -175,7 +175,7 @@ Information about rate limits you may find [here](https://developer-docs.amazon. ## Data type map | Integration Type | Airbyte Type | -| :----------------------- | :----------- | +|:-------------------------|:-------------| | `string` | `string` | | `int`, `float`, `number` | `number` | | `date` | `date` | @@ -228,22 +228,25 @@ Create a separate connection for streams which usually fail with error above "Fa | Version | Date | Pull Request | Subject | |:--------|:-----------|:----------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 4.4.4 | 2024-10-12 | [46817](https://github.com/airbytehq/airbyte/pull/46817) | Update dependencies | -| 4.4.3 | 2024-10-05 | [46473](https://github.com/airbytehq/airbyte/pull/46473) | Update dependencies | -| 4.4.2 | 2024-09-28 | [44748](https://github.com/airbytehq/airbyte/pull/44748) | Update dependencies | -| 4.4.1 | 2024-08-17 | [43739](https://github.com/airbytehq/airbyte/pull/43739) | Update dependencies | -| 4.4.0 | 2024-07-17 | [42052](https://github.com/airbytehq/airbyte/pull/42052) | Add waiting between requests logic to avoid failed report requests | -| 4.3.11 | 2024-07-13 | [41873](https://github.com/airbytehq/airbyte/pull/41873) | Update dependencies | -| 4.3.10 | 2024-07-10 | [41345](https://github.com/airbytehq/airbyte/pull/41345) | Update dependencies | -| 4.3.9 | 2024-07-09 | [41158](https://github.com/airbytehq/airbyte/pull/41158) | Update dependencies | -| 4.3.8 | 2024-07-08 | [40751](https://github.com/airbytehq/airbyte/pull/40751) | Improve error messaging and turning on alerting | -| 4.3.7 | 2024-07-06 | [40990](https://github.com/airbytehq/airbyte/pull/40990) | Update dependencies | -| 4.3.6 | 2024-07-01 | [40590](https://github.com/airbytehq/airbyte/pull/40590) | Add log message when data only accessible to seller accounts, add report id in log message for fatal report status, add check for start date. | -| 4.3.5 | 2024-06-27 | [40215](https://github.com/airbytehq/airbyte/pull/40215) | Replaced deprecated AirbyteLogger with logging.Logger | -| 4.3.4 | 2024-06-25 | [40384](https://github.com/airbytehq/airbyte/pull/40384) | Update dependencies | -| 4.3.3 | 2024-06-22 | [40008](https://github.com/airbytehq/airbyte/pull/40008) | Update dependencies | -| 4.3.2 | 2024-06-13 | [39441](https://github.com/airbytehq/airbyte/pull/39441) | Update state handling for incremental streams | -| 4.3.1 | 2024-06-04 | [38969](https://github.com/airbytehq/airbyte/pull/38969) | [autopull] Upgrade base image to v1.2.1 | +| 4.4.7 | 2024-11-14 | [47691](https://github.com/airbytehq/airbyte/pull/47691) | Fix `period_in_days` definition | +| 4.4.6 | 2024-11-25 | [48644](https://github.com/airbytehq/airbyte/pull/48644) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 4.4.5 | 2024-11-04 | [47049](https://github.com/airbytehq/airbyte/pull/47049) | Update dependencies | +| 4.4.4 | 2024-10-12 | [46817](https://github.com/airbytehq/airbyte/pull/46817) | Update dependencies | +| 4.4.3 | 2024-10-05 | [46473](https://github.com/airbytehq/airbyte/pull/46473) | Update dependencies | +| 4.4.2 | 2024-09-28 | [44748](https://github.com/airbytehq/airbyte/pull/44748) | Update dependencies | +| 4.4.1 | 2024-08-17 | [43739](https://github.com/airbytehq/airbyte/pull/43739) | Update dependencies | +| 4.4.0 | 2024-07-17 | [42052](https://github.com/airbytehq/airbyte/pull/42052) | Add waiting between requests logic to avoid failed report requests | +| 4.3.11 | 2024-07-13 | [41873](https://github.com/airbytehq/airbyte/pull/41873) | Update dependencies | +| 4.3.10 | 2024-07-10 | [41345](https://github.com/airbytehq/airbyte/pull/41345) | Update dependencies | +| 4.3.9 | 2024-07-09 | [41158](https://github.com/airbytehq/airbyte/pull/41158) | Update dependencies | +| 4.3.8 | 2024-07-08 | [40751](https://github.com/airbytehq/airbyte/pull/40751) | Improve error messaging and turning on alerting | +| 4.3.7 | 2024-07-06 | [40990](https://github.com/airbytehq/airbyte/pull/40990) | Update dependencies | +| 4.3.6 | 2024-07-01 | [40590](https://github.com/airbytehq/airbyte/pull/40590) | Add log message when data only accessible to seller accounts, add report id in log message for fatal report status, add check for start date. | +| 4.3.5 | 2024-06-27 | [40215](https://github.com/airbytehq/airbyte/pull/40215) | Replaced deprecated AirbyteLogger with logging.Logger | +| 4.3.4 | 2024-06-25 | [40384](https://github.com/airbytehq/airbyte/pull/40384) | Update dependencies | +| 4.3.3 | 2024-06-22 | [40008](https://github.com/airbytehq/airbyte/pull/40008) | Update dependencies | +| 4.3.2 | 2024-06-13 | [39441](https://github.com/airbytehq/airbyte/pull/39441) | Update state handling for incremental streams | +| 4.3.1 | 2024-06-04 | [38969](https://github.com/airbytehq/airbyte/pull/38969) | [autopull] Upgrade base image to v1.2.1 | | 4.3.0 | 2024-05-24 | [#38657](https://github.com/airbytehq/airbyte/pull/38657) | Extend the report_options spec config with a `stream_name` attribute | | 4.2.4 | 2024-05-15 | [#38210](https://github.com/airbytehq/airbyte/pull/38210) | Fix `GET_VENDOR_TRAFFIC_REPORT` stream with report option `reportPeriod=DAY` | | 4.2.3 | 2024-05-09 | [#38078](https://github.com/airbytehq/airbyte/pull/38078) | Hide OSS-only streams in report options config for cloud users | diff --git a/docs/integrations/sources/amplitude.md b/docs/integrations/sources/amplitude.md index e166b4ed7dc5..83c09f6e7c29 100644 --- a/docs/integrations/sources/amplitude.md +++ b/docs/integrations/sources/amplitude.md @@ -58,6 +58,10 @@ The Amplitude connector ideally should gracefully handle Amplitude API limitatio | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------------------- | +| 0.6.17 | 2025-01-04 | [50906](https://github.com/airbytehq/airbyte/pull/50906) | Update dependencies | +| 0.6.16 | 2024-12-28 | [50486](https://github.com/airbytehq/airbyte/pull/50486) | Update dependencies | +| 0.6.15 | 2024-12-21 | [50150](https://github.com/airbytehq/airbyte/pull/50150) | Update dependencies | +| 0.6.14 | 2024-12-14 | [49017](https://github.com/airbytehq/airbyte/pull/49017) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.6.13 | 2024-10-29 | [47097](https://github.com/airbytehq/airbyte/pull/47097) | Update dependencies | | 0.6.12 | 2024-10-12 | [46771](https://github.com/airbytehq/airbyte/pull/46771) | Update dependencies | | 0.6.11 | 2024-10-11 | [46736](https://github.com/airbytehq/airbyte/pull/46736) | Added possibility to toggle groupping by `Country` for `Active Users` stream | diff --git a/docs/integrations/sources/apify-dataset.md b/docs/integrations/sources/apify-dataset.md index 791a03ae536d..7e32db2eb216 100644 --- a/docs/integrations/sources/apify-dataset.md +++ b/docs/integrations/sources/apify-dataset.md @@ -72,7 +72,11 @@ The Apify dataset connector uses [Apify Python Client](https://docs.apify.com/ap | Version | Date | Pull Request | Subject | | :------ | :--------- | :----------------------------------------------------------- | :------------------------------------------------------------------------------ | -| 2.2.0 | 2024-10-29 | [47286](https://github.com/airbytehq/airbyte/pull/47286) | Migrate to manifest only format | +| 2.2.4 | 2024-12-28 | [50468](https://github.com/airbytehq/airbyte/pull/50468) | Update dependencies | +| 2.2.3 | 2024-12-21 | [50217](https://github.com/airbytehq/airbyte/pull/50217) | Update dependencies | +| 2.2.2 | 2024-12-14 | [49553](https://github.com/airbytehq/airbyte/pull/49553) | Update dependencies | +| 2.2.1 | 2024-12-12 | [48216](https://github.com/airbytehq/airbyte/pull/48216) | Update dependencies | +| 2.2.0 | 2024-10-29 | [47286](https://github.com/airbytehq/airbyte/pull/47286) | Migrate to manifest only format | | 2.1.27 | 2024-10-29 | [47068](https://github.com/airbytehq/airbyte/pull/47068) | Update dependencies | | 2.1.26 | 2024-10-12 | [46837](https://github.com/airbytehq/airbyte/pull/46837) | Update dependencies | | 2.1.25 | 2024-10-01 | [46373](https://github.com/airbytehq/airbyte/pull/46373) | add user-agent header to be able to track Airbyte integration on Apify | diff --git a/docs/integrations/sources/appcues.md b/docs/integrations/sources/appcues.md index ebf33618d422..f6e49168a96e 100644 --- a/docs/integrations/sources/appcues.md +++ b/docs/integrations/sources/appcues.md @@ -45,6 +45,12 @@ To set up the Appcues source connector, you'll need your Appcues [`API Key` and | Version | Date | Pull Request | Subject | | ------------------ | ------------ | ----- | ---------------- | +| 0.0.8 | 2024-12-28 | [50451](https://github.com/airbytehq/airbyte/pull/50451) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50174](https://github.com/airbytehq/airbyte/pull/50174) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49586](https://github.com/airbytehq/airbyte/pull/49586) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49277](https://github.com/airbytehq/airbyte/pull/49277) | Update dependencies | +| 0.0.4 | 2024-12-11 | [48931](https://github.com/airbytehq/airbyte/pull/48931) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.3 | 2024-11-04 | [48267](https://github.com/airbytehq/airbyte/pull/48267) | Update dependencies | | 0.0.2 | 2024-10-29 | [47771](https://github.com/airbytehq/airbyte/pull/47771) | Update dependencies | | 0.0.1 | 2024-09-03 | [45102](https://github.com/airbytehq/airbyte/pull/45102) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/appfigures.md b/docs/integrations/sources/appfigures.md index 22eb6d2a3a04..a0b1f7f52b07 100644 --- a/docs/integrations/sources/appfigures.md +++ b/docs/integrations/sources/appfigures.md @@ -39,6 +39,10 @@ Refer `https://docs.appfigures.com/api/reference/v2/authentication` for more det | Version | Date | Pull Request | Subject | | ------------------ | ------------ | -- | ---------------- | +| 0.0.6 | 2024-12-28 | [50498](https://github.com/airbytehq/airbyte/pull/50498) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50223](https://github.com/airbytehq/airbyte/pull/50223) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49549](https://github.com/airbytehq/airbyte/pull/49549) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49003](https://github.com/airbytehq/airbyte/pull/49003) | Update dependencies | | 0.0.2 | 2024-10-29 | [47661](https://github.com/airbytehq/airbyte/pull/47661) | Update dependencies | | 0.0.1 | 2024-09-08 | [45332](https://github.com/airbytehq/airbyte/pull/45332) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/appfollow.md b/docs/integrations/sources/appfollow.md index c37e9b39a3ee..eeb8cb809771 100644 --- a/docs/integrations/sources/appfollow.md +++ b/docs/integrations/sources/appfollow.md @@ -40,6 +40,10 @@ The Appfollow connector ideally should gracefully handle Appfollow API limitatio | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :-------------------------------------- | +| 1.1.4 | 2024-12-28 | [50477](https://github.com/airbytehq/airbyte/pull/50477) | Update dependencies | +| 1.1.3 | 2024-12-21 | [50186](https://github.com/airbytehq/airbyte/pull/50186) | Update dependencies | +| 1.1.2 | 2024-12-14 | [49557](https://github.com/airbytehq/airbyte/pull/49557) | Update dependencies | +| 1.1.1 | 2024-12-12 | [47742](https://github.com/airbytehq/airbyte/pull/47742) | Update dependencies | | 1.1.0 | 2024-08-23 | [44598](https://github.com/airbytehq/airbyte/pull/44598) | Refactor connector to manifest-only format | | 1.0.12 | 2024-08-17 | [44338](https://github.com/airbytehq/airbyte/pull/44338) | Update dependencies | | 1.0.11 | 2024-08-12 | [43931](https://github.com/airbytehq/airbyte/pull/43931) | Update dependencies | diff --git a/docs/integrations/sources/apple-search-ads.md b/docs/integrations/sources/apple-search-ads.md index fad6891fe51c..ada9826c3c4b 100644 --- a/docs/integrations/sources/apple-search-ads.md +++ b/docs/integrations/sources/apple-search-ads.md @@ -60,7 +60,12 @@ However, at this moment and as indicated in the stream names, the connector only | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :----------------------------------------------------------------------------------- | -| 0.2.0 | 2024-10-01 | [46288](https://github.com/airbytehq/airbyte/pull/46288) | Migrate to Manifest-only | +| 0.2.5 | 2024-12-28 | [50469](https://github.com/airbytehq/airbyte/pull/50469) | Update dependencies | +| 0.2.4 | 2024-12-21 | [50155](https://github.com/airbytehq/airbyte/pull/50155) | Update dependencies | +| 0.2.3 | 2024-12-14 | [49561](https://github.com/airbytehq/airbyte/pull/49561) | Update dependencies | +| 0.2.2 | 2024-12-12 | [47751](https://github.com/airbytehq/airbyte/pull/47751) | Update dependencies | +| 0.2.1 | 2024-11-08 | [48440](https://github.com/airbytehq/airbyte/pull/48440) | Set authentication grant_type to client_credentials | +| 0.2.0 | 2024-10-01 | [46288](https://github.com/airbytehq/airbyte/pull/46288) | Migrate to Manifest-only | | 0.1.20 | 2024-09-28 | [46153](https://github.com/airbytehq/airbyte/pull/46153) | Update dependencies | | 0.1.19 | 2024-09-21 | [45803](https://github.com/airbytehq/airbyte/pull/45803) | Update dependencies | | 0.1.18 | 2024-09-14 | [45474](https://github.com/airbytehq/airbyte/pull/45474) | Update dependencies | diff --git a/docs/integrations/sources/appsflyer.md b/docs/integrations/sources/appsflyer.md index c93ca7d1ccd5..eacc7ccda2e7 100644 --- a/docs/integrations/sources/appsflyer.md +++ b/docs/integrations/sources/appsflyer.md @@ -23,6 +23,10 @@ The Airbyte Source for [AppsFLyer](https://www.appsflyer.com/) | Version | Date | Pull Request | Subject | | :------ | :--------- | :----------------------------------------------------- | :------------------------------------------ | +| 0.2.25 | 2024-12-28 | [50438](https://github.com/airbytehq/airbyte/pull/50438) | Update dependencies | +| 0.2.24 | 2024-12-21 | [50173](https://github.com/airbytehq/airbyte/pull/50173) | Update dependencies | +| 0.2.23 | 2024-12-14 | [49296](https://github.com/airbytehq/airbyte/pull/49296) | Update dependencies | +| 0.2.22 | 2024-11-25 | [48652](https://github.com/airbytehq/airbyte/pull/48652) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.21 | 2024-10-29 | [47039](https://github.com/airbytehq/airbyte/pull/47039) | Update dependencies | | 0.2.20 | 2024-10-12 | [46823](https://github.com/airbytehq/airbyte/pull/46823) | Update dependencies | | 0.2.19 | 2024-10-05 | [46393](https://github.com/airbytehq/airbyte/pull/46393) | Update dependencies | diff --git a/docs/integrations/sources/apptivo.md b/docs/integrations/sources/apptivo.md new file mode 100644 index 000000000000..4ff80a92270f --- /dev/null +++ b/docs/integrations/sources/apptivo.md @@ -0,0 +1,33 @@ +# Apptivo +Apptivo connector seamless data integration between Apptivo and various data warehouses or databases, automating data transfer for analytics, reporting, and insights. This connector allows businesses to synchronize Apptivo CRM data, such as contacts, deals, and activities, with other systems to streamline workflows and improve data accessibility across platforms. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use. Find it in your Apptivo account under Business Settings -> API Access. | | +| `access_key` | `string` | Access Key. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| customers | customerId | DefaultPaginator | ✅ | ❌ | +| contacts | contactId | DefaultPaginator | ✅ | ❌ | +| cases | | No pagination | ✅ | ❌ | +| leads | id | DefaultPaginator | ✅ | ❌ | +| opportunities | opportunityId | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50496](https://github.com/airbytehq/airbyte/pull/50496) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50193](https://github.com/airbytehq/airbyte/pull/50193) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49544](https://github.com/airbytehq/airbyte/pull/49544) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49004](https://github.com/airbytehq/airbyte/pull/49004) | Update dependencies | +| 0.0.1 | 2024-11-09 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/asana.md b/docs/integrations/sources/asana.md index 9ac31ea0907b..5a2c7f224e1e 100644 --- a/docs/integrations/sources/asana.md +++ b/docs/integrations/sources/asana.md @@ -104,8 +104,14 @@ The connector is restricted by [Asana rate limits](https://developers.asana.com/
Expand to review -| Version | Date | Pull Request | Subject | -|:--------|:-----------|:---------------------------------------------------------|:------------------------------------------------------------------| +| Version | Date | Pull Request | Subject | +|:--------|:-----------|:---------------------------------------------------------|:------------------------------------------------------------------------------------| +| 1.3.4 | 2025-01-04 | [50915](https://github.com/airbytehq/airbyte/pull/50915) | Update dependencies | +| 1.3.3 | 2024-12-28 | [50442](https://github.com/airbytehq/airbyte/pull/50442) | Update dependencies | +| 1.3.2 | 2024-12-21 | [50195](https://github.com/airbytehq/airbyte/pull/50195) | Update dependencies | +| 1.3.1 | 2024-12-14 | [48966](https://github.com/airbytehq/airbyte/pull/48966) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 1.3.0 | 2024-12-06 | [48712](https://github.com/airbytehq/airbyte/pull/48712) | Upgrade to process full refresh and non-incremental substreams using concurrent CDK | +| 1.2.14 | 2024-11-04 | [48175](https://github.com/airbytehq/airbyte/pull/48175) | Update dependencies | | 1.2.13 | 2024-10-28 | [47026](https://github.com/airbytehq/airbyte/pull/47026) | Update dependencies | | 1.2.12 | 2024-10-12 | [46825](https://github.com/airbytehq/airbyte/pull/46825) | Update dependencies | | 1.2.11 | 2024-10-05 | [46501](https://github.com/airbytehq/airbyte/pull/46501) | Update dependencies | diff --git a/docs/integrations/sources/ashby.md b/docs/integrations/sources/ashby.md index ba4aeab9dfee..5f2a6b70bd9f 100644 --- a/docs/integrations/sources/ashby.md +++ b/docs/integrations/sources/ashby.md @@ -48,6 +48,11 @@ The Ashby connector should not run into Ashby API limitations under normal usage | Version | Date | Pull Request | Subject | |:--------| :--------- | :------------------------------------------------------- |:--------------------------------------------| +| 0.2.7 | 2024-12-28 | [50493](https://github.com/airbytehq/airbyte/pull/50493) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50207](https://github.com/airbytehq/airbyte/pull/50207) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49572](https://github.com/airbytehq/airbyte/pull/49572) | Update dependencies | +| 0.2.4 | 2024-12-12 | [49014](https://github.com/airbytehq/airbyte/pull/49014) | Update dependencies | +| 0.2.3 | 2024-11-04 | [48196](https://github.com/airbytehq/airbyte/pull/48196) | Update dependencies | | 0.2.2 | 2024-10-29 | [47729](https://github.com/airbytehq/airbyte/pull/47729) | Update dependencies | | 0.2.1 | 2024-10-28 | [47616](https://github.com/airbytehq/airbyte/pull/47616) | Update dependencies | | 0.2.0 | 2024-08-19 | [44420](https://github.com/airbytehq/airbyte/pull/44420) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/aws-cloudtrail.md b/docs/integrations/sources/aws-cloudtrail.md index 78e96a96e84b..2b2288495f0b 100644 --- a/docs/integrations/sources/aws-cloudtrail.md +++ b/docs/integrations/sources/aws-cloudtrail.md @@ -54,39 +54,40 @@ Please, follow this [steps](https://docs.aws.amazon.com/powershell/latest/usergu | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | -| 1.0.20 | 2024-10-29 | [47768](https://github.com/airbytehq/airbyte/pull/47768) | Update dependencies | -| 1.0.19 | 2024-10-28 | [47096](https://github.com/airbytehq/airbyte/pull/47096) | Update dependencies | -| 1.0.18 | 2024-10-12 | [46761](https://github.com/airbytehq/airbyte/pull/46761) | Update dependencies | -| 1.0.17 | 2024-10-05 | [46498](https://github.com/airbytehq/airbyte/pull/46498) | Update dependencies | -| 1.0.16 | 2024-09-28 | [46156](https://github.com/airbytehq/airbyte/pull/46156) | Update dependencies | -| 1.0.15 | 2024-09-21 | [45819](https://github.com/airbytehq/airbyte/pull/45819) | Update dependencies | -| 1.0.14 | 2024-09-14 | [45574](https://github.com/airbytehq/airbyte/pull/45574) | Update dependencies | -| 1.0.13 | 2024-09-07 | [45304](https://github.com/airbytehq/airbyte/pull/45304) | Update dependencies | -| 1.0.12 | 2024-08-31 | [45000](https://github.com/airbytehq/airbyte/pull/45000) | Update dependencies | -| 1.0.11 | 2024-08-24 | [44361](https://github.com/airbytehq/airbyte/pull/44361) | Update dependencies | -| 1.0.10 | 2024-08-12 | [43756](https://github.com/airbytehq/airbyte/pull/43756) | Update dependencies | -| 1.0.9 | 2024-08-10 | [43627](https://github.com/airbytehq/airbyte/pull/43627) | Update dependencies | -| 1.0.8 | 2024-08-03 | [43140](https://github.com/airbytehq/airbyte/pull/43140) | Update dependencies | -| 1.0.7 | 2024-07-27 | [42642](https://github.com/airbytehq/airbyte/pull/42642) | Update dependencies | -| 1.0.6 | 2024-07-20 | [42286](https://github.com/airbytehq/airbyte/pull/42286) | Update dependencies | -| 1.0.5 | 2024-07-13 | [41846](https://github.com/airbytehq/airbyte/pull/41846) | Update dependencies | -| 1.0.4 | 2024-07-10 | [41435](https://github.com/airbytehq/airbyte/pull/41435) | Update dependencies | -| 1.0.3 | 2024-07-09 | [41230](https://github.com/airbytehq/airbyte/pull/41230) | Update dependencies | -| 1.0.2 | 2024-07-06 | [40995](https://github.com/airbytehq/airbyte/pull/40995) | Update dependencies | -| 1.0.1 | 2024-06-26 | [40419](https://github.com/airbytehq/airbyte/pull/40419) | Update dependencies | -| 1.0.0 | 2024-07-02 | [36562](https://github.com/airbytehq/airbyte/pull/36562) | Migrate to low code CDK, Add filtering capability | -| 0.1.12 | 2024-06-22 | [39960](https://github.com/airbytehq/airbyte/pull/39960) | Update dependencies | -| 0.1.11 | 2024-06-06 | [39246](https://github.com/airbytehq/airbyte/pull/39246) | [autopull] Upgrade base image to v1.2.2 | -| 0.1.10 | 2024-06-03 | [38911](https://github.com/airbytehq/airbyte/pull/38911) | Replace AirbyteLogger with logging.Logger | -| 0.1.9 | 2024-06-03 | [38911](https://github.com/airbytehq/airbyte/pull/38911) | Replace AirbyteLogger with logging.Logger | -| 0.1.8 | 2024-05-20 | [38448](https://github.com/airbytehq/airbyte/pull/38448) | [autopull] base image + poetry + up_to_date | -| 0.1.7 | 2024-04-15 | [37122](https://github.com/airbytehq/airbyte/pull/37122) | Base image migration: remove Dockerfile and use the python-connector-base image | -| 0.1.6 | 2024-04-12 | [37122](https://github.com/airbytehq/airbyte/pull/37122) | schema descriptions | -| 0.1.5 | 2023-02-15 | [23083](https://github.com/airbytehq/airbyte/pull/23083) | Specified date formatting in specification | -| 0.1.4 | 2022-04-11 | [11763](https://github.com/airbytehq/airbyte/pull/11763) | Upgrade to Python 3.9 | -| 0.1.3 | 2021-12-23 | [8434](https://github.com/airbytehq/airbyte/pull/8434) | Update fields in source-connectors specifications | -| 0.1.2 | 2021-08-04 | [5152](https://github.com/airbytehq/airbyte/pull/5152) | Fix connector spec.json | -| 0.1.1 | 2021-07-06 | [4539](https://github.com/airbytehq/airbyte/pull/4539) | Add `AIRBYTE_ENTRYPOINT` for Kubernetes support | -| 0.1.0 | 2021-06-23 | [4122](https://github.com/airbytehq/airbyte/pull/4122) | Initial release supporting the LookupEvent API | +| 1.1.0 | 2024-10-29 | [47287](https://github.com/airbytehq/airbyte/pull/47287) | Migrate to manifest only format | +| 1.0.20 | 2024-10-29 | [47768](https://github.com/airbytehq/airbyte/pull/47768) | Update dependencies | +| 1.0.19 | 2024-10-28 | [47096](https://github.com/airbytehq/airbyte/pull/47096) | Update dependencies | +| 1.0.18 | 2024-10-12 | [46761](https://github.com/airbytehq/airbyte/pull/46761) | Update dependencies | +| 1.0.17 | 2024-10-05 | [46498](https://github.com/airbytehq/airbyte/pull/46498) | Update dependencies | +| 1.0.16 | 2024-09-28 | [46156](https://github.com/airbytehq/airbyte/pull/46156) | Update dependencies | +| 1.0.15 | 2024-09-21 | [45819](https://github.com/airbytehq/airbyte/pull/45819) | Update dependencies | +| 1.0.14 | 2024-09-14 | [45574](https://github.com/airbytehq/airbyte/pull/45574) | Update dependencies | +| 1.0.13 | 2024-09-07 | [45304](https://github.com/airbytehq/airbyte/pull/45304) | Update dependencies | +| 1.0.12 | 2024-08-31 | [45000](https://github.com/airbytehq/airbyte/pull/45000) | Update dependencies | +| 1.0.11 | 2024-08-24 | [44361](https://github.com/airbytehq/airbyte/pull/44361) | Update dependencies | +| 1.0.10 | 2024-08-12 | [43756](https://github.com/airbytehq/airbyte/pull/43756) | Update dependencies | +| 1.0.9 | 2024-08-10 | [43627](https://github.com/airbytehq/airbyte/pull/43627) | Update dependencies | +| 1.0.8 | 2024-08-03 | [43140](https://github.com/airbytehq/airbyte/pull/43140) | Update dependencies | +| 1.0.7 | 2024-07-27 | [42642](https://github.com/airbytehq/airbyte/pull/42642) | Update dependencies | +| 1.0.6 | 2024-07-20 | [42286](https://github.com/airbytehq/airbyte/pull/42286) | Update dependencies | +| 1.0.5 | 2024-07-13 | [41846](https://github.com/airbytehq/airbyte/pull/41846) | Update dependencies | +| 1.0.4 | 2024-07-10 | [41435](https://github.com/airbytehq/airbyte/pull/41435) | Update dependencies | +| 1.0.3 | 2024-07-09 | [41230](https://github.com/airbytehq/airbyte/pull/41230) | Update dependencies | +| 1.0.2 | 2024-07-06 | [40995](https://github.com/airbytehq/airbyte/pull/40995) | Update dependencies | +| 1.0.1 | 2024-06-26 | [40419](https://github.com/airbytehq/airbyte/pull/40419) | Update dependencies | +| 1.0.0 | 2024-07-02 | [36562](https://github.com/airbytehq/airbyte/pull/36562) | Migrate to low code CDK, Add filtering capability | +| 0.1.12 | 2024-06-22 | [39960](https://github.com/airbytehq/airbyte/pull/39960) | Update dependencies | +| 0.1.11 | 2024-06-06 | [39246](https://github.com/airbytehq/airbyte/pull/39246) | [autopull] Upgrade base image to v1.2.2 | +| 0.1.10 | 2024-06-03 | [38911](https://github.com/airbytehq/airbyte/pull/38911) | Replace AirbyteLogger with logging.Logger | +| 0.1.9 | 2024-06-03 | [38911](https://github.com/airbytehq/airbyte/pull/38911) | Replace AirbyteLogger with logging.Logger | +| 0.1.8 | 2024-05-20 | [38448](https://github.com/airbytehq/airbyte/pull/38448) | [autopull] base image + poetry + up_to_date | +| 0.1.7 | 2024-04-15 | [37122](https://github.com/airbytehq/airbyte/pull/37122) | Base image migration: remove Dockerfile and use the python-connector-base image | +| 0.1.6 | 2024-04-12 | [37122](https://github.com/airbytehq/airbyte/pull/37122) | schema descriptions | +| 0.1.5 | 2023-02-15 | [23083](https://github.com/airbytehq/airbyte/pull/23083) | Specified date formatting in specification | +| 0.1.4 | 2022-04-11 | [11763](https://github.com/airbytehq/airbyte/pull/11763) | Upgrade to Python 3.9 | +| 0.1.3 | 2021-12-23 | [8434](https://github.com/airbytehq/airbyte/pull/8434) | Update fields in source-connectors specifications | +| 0.1.2 | 2021-08-04 | [5152](https://github.com/airbytehq/airbyte/pull/5152) | Fix connector spec.json | +| 0.1.1 | 2021-07-06 | [4539](https://github.com/airbytehq/airbyte/pull/4539) | Add `AIRBYTE_ENTRYPOINT` for Kubernetes support | +| 0.1.0 | 2021-06-23 | [4122](https://github.com/airbytehq/airbyte/pull/4122) | Initial release supporting the LookupEvent API |
diff --git a/docs/integrations/sources/azure-blob-storage.md b/docs/integrations/sources/azure-blob-storage.md index 2d6baf9ba2d5..bb802349dcb3 100644 --- a/docs/integrations/sources/azure-blob-storage.md +++ b/docs/integrations/sources/azure-blob-storage.md @@ -2,7 +2,7 @@ -This page contains the setup guide and reference information for the [Azure Blob Storage](https://learn.microsoft.com/en-us/azure/?product=popular) source connector. +This page contains the setup guide and reference information for the [Azure Blob Storage](https://azure.microsoft.com/en-us/products/storage/blobs/) source connector. @@ -41,10 +41,10 @@ Minimum permissions (role [Storage Blob Data Reader](https://learn.microsoft.com ### Step 1: Set up Azure Blob Storage -- Create a storage account with the permissions [details](https://learn.microsoft.com/en-us/azure/storage/common/storage-account-create?tabs=azure-portal) +- Create a storage account and grant roles [details](https://learn.microsoft.com/en-us/azure/storage/common/storage-account-create?tabs=azure-portal) :::warning -To use Oauth 2.0 Authentication method, Access Control (IAM) should be setup. +To use Oauth2 or Client Credentials Authentication methods, Access Control (IAM) should be setup. It is recommended to use role [Storage Blob Data Reader](https://learn.microsoft.com/en-gb/azure/storage/blobs/assign-azure-role-data-access?tabs=portal) @@ -62,6 +62,20 @@ Follow these steps to set up an IAM role: ::: +
+ +Follow these steps to set up a Service Principal to use the Client Credentials authentication method. + + +In the Azure portal, navigate to your Service Principal's App Registration. + +Note the `Directory (tenant) ID` and `Application (client) ID` in the Overview panel. + +In the `Manage / Certificates & secrets` panel, click `Client Secrets` and create a new secret. Note the `Value` of the secret. + +
+ + ### Step 2: Set up the Azure Blob Storage connector in Airbyte @@ -93,10 +107,14 @@ Follow these steps to set up an IAM role: 2. Click Sources and then click + New source. 3. On the Set up the source page, select Azure Blob Storage from the Source type dropdown. 4. Enter a name for the Azure Blob Storage connector. -5. Enter the name of your Azure **Account**. -6. Enter your Tenant ID and Click **Authenticate your Azure Blob Storage account**. -7. Log in and authorize the Azure Blob Storage account. -8. Enter the name of the **Container** containing your files to replicate. +5. Enter the name of your Azure **Storage Account** and **container**. +6. Choose the Authentication method. + 1. If you are accessing through a Storage Account Key, choose `Authenticate via Storage Account Key` and enter the key. + 1. If you are accessing through a Service Principal, choose the `Authenticate via Client Credentials`. + 0. See [above](#step-1-set-up-azure-blob-storage) regarding setting IAM role bindings for the Service Principal and getting detail of the app registration + 1. Enter the `Directory (tenant) ID` value from app registration in Azure Portal into the `Tenant ID` field. + 2. Enter the `Application (client) ID` from Azure Portal into the `Tenant ID` field. Note this is **not** the secret ID + 3. Enter the Secret `Value` from Azure Portal into the `Client Secret` field. 9. Add a stream 1. Write the **File Type** 2. In the **Format** box, use the dropdown menu to select the format of the files you'd like to replicate. The supported formats are **CSV**, **Parquet**, **Avro** and **JSONL**. Toggling the **Optional fields** button within the **Format** box will allow you to enter additional configurations based on the selected format. For a detailed breakdown of these settings, refer to the [File Format section](#file-format-settings) below. @@ -283,6 +301,7 @@ The Azure Blob Storage connector should not encounter any [Microsoft API limitat | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:---------------------------------------------------------------------------------------------| +| 0.5.0 | 2025-01-02 | [50398](https://github.com/airbytehq/airbyte/pull/50398) | Add client_credentials auth for Azure Service Principals | | 0.4.4 | 2024-06-06 | [39275](https://github.com/airbytehq/airbyte/pull/39275) | [autopull] Upgrade base image to v1.2.2 | | 0.4.3 | 2024-05-29 | [38701](https://github.com/airbytehq/airbyte/pull/38701) | Avoid error on empty stream when running discover | | 0.4.2 | 2024-04-23 | [37504](https://github.com/airbytehq/airbyte/pull/37504) | Update specification | diff --git a/docs/integrations/sources/azure-table.md b/docs/integrations/sources/azure-table.md index 59a65ee3e324..909fa9ecf600 100644 --- a/docs/integrations/sources/azure-table.md +++ b/docs/integrations/sources/azure-table.md @@ -70,6 +70,10 @@ We recommend creating a restricted key specifically for Airbyte access. This wil | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------ | +| 0.1.32 | 2024-12-28 | [50457](https://github.com/airbytehq/airbyte/pull/50457) | Update dependencies | +| 0.1.31 | 2024-12-21 | [50179](https://github.com/airbytehq/airbyte/pull/50179) | Update dependencies | +| 0.1.30 | 2024-12-14 | [49291](https://github.com/airbytehq/airbyte/pull/49291) | Update dependencies | +| 0.1.29 | 2024-11-25 | [48663](https://github.com/airbytehq/airbyte/pull/48663) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.1.28 | 2024-10-29 | [47050](https://github.com/airbytehq/airbyte/pull/47050) | Update dependencies | | 0.1.27 | 2024-10-12 | [46763](https://github.com/airbytehq/airbyte/pull/46763) | Update dependencies | | 0.1.26 | 2024-10-05 | [46396](https://github.com/airbytehq/airbyte/pull/46396) | Update dependencies | diff --git a/docs/integrations/sources/babelforce.md b/docs/integrations/sources/babelforce.md index 5e42c861a7df..f401be325fae 100644 --- a/docs/integrations/sources/babelforce.md +++ b/docs/integrations/sources/babelforce.md @@ -49,6 +49,11 @@ Generate a API access key ID and token using the [Babelforce documentation](http | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :-------------------------- | +| 0.3.7 | 2024-12-28 | [50502](https://github.com/airbytehq/airbyte/pull/50502) | Update dependencies | +| 0.3.6 | 2024-12-21 | [50184](https://github.com/airbytehq/airbyte/pull/50184) | Update dependencies | +| 0.3.5 | 2024-12-14 | [49587](https://github.com/airbytehq/airbyte/pull/49587) | Update dependencies | +| 0.3.4 | 2024-12-12 | [49286](https://github.com/airbytehq/airbyte/pull/49286) | Update dependencies | +| 0.3.3 | 2024-12-11 | [49035](https://github.com/airbytehq/airbyte/pull/49035) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.3.2 | 2024-10-28 | [47631](https://github.com/airbytehq/airbyte/pull/47631) | Update dependencies | | 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.3.0 | 2024-08-09 | [43439](https://github.com/airbytehq/airbyte/pull/43439) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/bamboo-hr.md b/docs/integrations/sources/bamboo-hr.md index b04b47dab056..45cc19f8d7d2 100644 --- a/docs/integrations/sources/bamboo-hr.md +++ b/docs/integrations/sources/bamboo-hr.md @@ -91,7 +91,11 @@ Please [create an issue](https://github.com/airbytehq/airbyte/issues) if you see | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | -| 0.5.0 | 2024-10-28 | [47262](https://github.com/airbytehq/airbyte/pull/47262) | Migrate to Manifest-only | +| 0.5.4 | 2024-12-28 | [50440](https://github.com/airbytehq/airbyte/pull/50440) | Update dependencies | +| 0.5.3 | 2024-12-21 | [50206](https://github.com/airbytehq/airbyte/pull/50206) | Update dependencies | +| 0.5.2 | 2024-12-14 | [49543](https://github.com/airbytehq/airbyte/pull/49543) | Update dependencies | +| 0.5.1 | 2024-12-12 | [49025](https://github.com/airbytehq/airbyte/pull/49025) | Update dependencies | +| 0.5.0 | 2024-10-28 | [47262](https://github.com/airbytehq/airbyte/pull/47262) | Migrate to Manifest-only | | 0.4.14 | 2024-10-28 | [47072](https://github.com/airbytehq/airbyte/pull/47072) | Update dependencies | | 0.4.13 | 2024-10-12 | [46842](https://github.com/airbytehq/airbyte/pull/46842) | Update dependencies | | 0.4.12 | 2024-10-05 | [46500](https://github.com/airbytehq/airbyte/pull/46500) | Update dependencies | diff --git a/docs/integrations/sources/beamer.md b/docs/integrations/sources/beamer.md index 760e42750507..63e4c075ea1e 100644 --- a/docs/integrations/sources/beamer.md +++ b/docs/integrations/sources/beamer.md @@ -20,6 +20,12 @@ Beamer NPS source | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.8 | 2024-12-28 | [50467](https://github.com/airbytehq/airbyte/pull/50467) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50215](https://github.com/airbytehq/airbyte/pull/50215) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49567](https://github.com/airbytehq/airbyte/pull/49567) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49015](https://github.com/airbytehq/airbyte/pull/49015) | Update dependencies | +| 0.0.4 | 2024-11-05 | [48354](https://github.com/airbytehq/airbyte/pull/48354) | Revert to source-declarative-manifest v5.17.0 | +| 0.0.2 | 2024-11-05 | [48335](https://github.com/airbytehq/airbyte/pull/48335) | Update dependencies | | 0.0.1 | 2024-09-17 | | Initial release by [@caydenm](https://github.com/caydenm) via Connector Builder | - \ No newline at end of file + diff --git a/docs/integrations/sources/bigcommerce.md b/docs/integrations/sources/bigcommerce.md index 1a77c343ca39..20e5aa95c613 100644 --- a/docs/integrations/sources/bigcommerce.md +++ b/docs/integrations/sources/bigcommerce.md @@ -58,6 +58,13 @@ BigCommerce has some [rate limit restrictions](https://developer.bigcommerce.com | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :---------------------------------------------------------- | +| 0.3.6 | 2024-12-28 | [50464](https://github.com/airbytehq/airbyte/pull/50464) | Update dependencies | +| 0.3.5 | 2024-12-21 | [50194](https://github.com/airbytehq/airbyte/pull/50194) | Update dependencies | +| 0.3.4 | 2024-12-14 | [49568](https://github.com/airbytehq/airbyte/pull/49568) | Update dependencies | +| 0.3.3 | 2024-12-12 | [49312](https://github.com/airbytehq/airbyte/pull/49312) | Update dependencies | +| 0.3.2 | 2024-12-11 | [49016](https://github.com/airbytehq/airbyte/pull/49016) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.3.1 | 2024-11-04 | [48234](https://github.com/airbytehq/airbyte/pull/48234) | Update dependencies | +| 0.3.0 | 2024-10-30 | [47277](https://github.com/airbytehq/airbyte/pull/47277) | Migrate to Manifest-only | | 0.2.22 | 2024-10-28 | [47117](https://github.com/airbytehq/airbyte/pull/47117) | Update dependencies | | 0.2.21 | 2024-10-12 | [46840](https://github.com/airbytehq/airbyte/pull/46840) | Update dependencies | | 0.2.20 | 2024-10-05 | [46453](https://github.com/airbytehq/airbyte/pull/46453) | Update dependencies | diff --git a/docs/integrations/sources/bigmailer.md b/docs/integrations/sources/bigmailer.md new file mode 100644 index 000000000000..88cac9295fd1 --- /dev/null +++ b/docs/integrations/sources/bigmailer.md @@ -0,0 +1,38 @@ +# BigMailer +An Airbyte connector for [BigMailer](https://bigmailer.com) would facilitate seamless data syncing between BigMailer and other platforms. This connector would allow users to pull data from BigMailer, such as *brands*, *contacts*, *lists*, *fields*, *message types*, *segments*, *bulk campaigns*, *transactional campaigns*, *suppression lists*, and *users*, into various data destinations for further analysis, reporting, or automation tasks. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use. You can create and find it on the API key management page in your BigMailer account. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| brands | id | DefaultPaginator | ✅ | ❌ | +| contacts | id | DefaultPaginator | ✅ | ❌ | +| lists | id | DefaultPaginator | ✅ | ❌ | +| fields | id | DefaultPaginator | ✅ | ❌ | +| message-types | id | DefaultPaginator | ✅ | ❌ | +| segments | id | DefaultPaginator | ✅ | ❌ | +| bulk_campaigns | id | DefaultPaginator | ✅ | ❌ | +| transactional_campaigns | id | DefaultPaginator | ✅ | ❌ | +| suppression_lists | | DefaultPaginator | ✅ | ❌ | +| users | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50455](https://github.com/airbytehq/airbyte/pull/50455) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50200](https://github.com/airbytehq/airbyte/pull/50200) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49592](https://github.com/airbytehq/airbyte/pull/49592) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49287](https://github.com/airbytehq/airbyte/pull/49287) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49031](https://github.com/airbytehq/airbyte/pull/49031) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-08 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/bigquery.md b/docs/integrations/sources/bigquery.md index e21aa491a3ef..88c964579594 100644 --- a/docs/integrations/sources/bigquery.md +++ b/docs/integrations/sources/bigquery.md @@ -89,10 +89,11 @@ Once you've configured BigQuery as a source, delete the Service Account Key from | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- | -| 0.4.2 | 2024-02-22 | [35503](https://github.com/airbytehq/airbyte/pull/35503) | Source BigQuery: replicating RECORD REPEATED fields | -| 0.4.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | -| 0.4.0 | 2023-12-18 | [33484](https://github.com/airbytehq/airbyte/pull/33484) | Remove LEGACY state | -| 0.3.0 | 2023-06-26 | [27737](https://github.com/airbytehq/airbyte/pull/27737) | License Update: Elv2 | +| 0.4.3 | 2024-12-18 | [49875](https://github.com/airbytehq/airbyte/pull/49875) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.4.2 | 2024-02-22 | [35503](https://github.com/airbytehq/airbyte/pull/35503) | Source BigQuery: replicating RECORD REPEATED fields | +| 0.4.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | +| 0.4.0 | 2023-12-18 | [33484](https://github.com/airbytehq/airbyte/pull/33484) | Remove LEGACY state | +| 0.3.0 | 2023-06-26 | [27737](https://github.com/airbytehq/airbyte/pull/27737) | License Update: Elv2 | | 0.2.3 | 2022-10-13 | [15535](https://github.com/airbytehq/airbyte/pull/16238) | Update incremental query to avoid data missing when new data is inserted at the same time as a sync starts under non-CDC incremental mode | | 0.2.2 | 2022-09-22 | [16902](https://github.com/airbytehq/airbyte/pull/16902) | Source BigQuery: added user agent header | | 0.2.1 | 2022-09-14 | [15668](https://github.com/airbytehq/airbyte/pull/15668) | Wrap logs in AirbyteLogMessage | @@ -108,4 +109,4 @@ Once you've configured BigQuery as a source, delete the Service Account Key from | 0.1.1 | 2021-07-28 | [\#4981](https://github.com/airbytehq/airbyte/pull/4981) | 🐛 BigQuery source: Fix nested arrays | | 0.1.0 | 2021-07-22 | [\#4457](https://github.com/airbytehq/airbyte/pull/4457) | 🎉 New Source: Big Query. | - \ No newline at end of file + diff --git a/docs/integrations/sources/bing-ads.md b/docs/integrations/sources/bing-ads.md index dc0d1a3d2796..e0f2693a3716 100644 --- a/docs/integrations/sources/bing-ads.md +++ b/docs/integrations/sources/bing-ads.md @@ -261,6 +261,12 @@ The Bing Ads API limits the number of requests for all Microsoft Advertising cli | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------| +| 2.8.8 | 2025-01-04 | [50905](https://github.com/airbytehq/airbyte/pull/50905) | Update dependencies | +| 2.8.7 | 2024-12-28 | [50443](https://github.com/airbytehq/airbyte/pull/50443) | Update dependencies | +| 2.8.6 | 2024-12-21 | [50181](https://github.com/airbytehq/airbyte/pull/50181) | Update dependencies | +| 2.8.5 | 2024-12-14 | [49283](https://github.com/airbytehq/airbyte/pull/49283) | Update dependencies | +| 2.8.4 | 2024-11-25 | [48650](https://github.com/airbytehq/airbyte/pull/48650) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 2.8.3 | 2024-11-04 | [48169](https://github.com/airbytehq/airbyte/pull/48169) | Update dependencies | | 2.8.2 | 2024-10-29 | [47850](https://github.com/airbytehq/airbyte/pull/47850) | Update dependencies | | 2.8.1 | 2024-10-28 | [47093](https://github.com/airbytehq/airbyte/pull/47093) | Update dependencies | | 2.8.0 | 2024-10-21 | [46991](https://github.com/airbytehq/airbyte/pull/46991) | Update CDK to v5 | diff --git a/docs/integrations/sources/bitly.md b/docs/integrations/sources/bitly.md index b2429ab2a0de..8427eba8fab1 100644 --- a/docs/integrations/sources/bitly.md +++ b/docs/integrations/sources/bitly.md @@ -33,6 +33,11 @@ Generate API Key [here](https://app.bitly.com/settings/api/) or go to Settings | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.7 | 2024-12-28 | [50447](https://github.com/airbytehq/airbyte/pull/50447) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50164](https://github.com/airbytehq/airbyte/pull/50164) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49571](https://github.com/airbytehq/airbyte/pull/49571) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49005](https://github.com/airbytehq/airbyte/pull/49005) | Update dependencies | +| 0.0.3 | 2024-11-04 | [48171](https://github.com/airbytehq/airbyte/pull/48171) | Update dependencies | | 0.0.2 | 2024-10-28 | [47516](https://github.com/airbytehq/airbyte/pull/47516) | Update dependencies | | 0.0.1 | 2024-09-01 | | Initial release by [@topefolorunso](https://github.com/topefolorunso) via Connector Builder | diff --git a/docs/integrations/sources/blogger.md b/docs/integrations/sources/blogger.md new file mode 100644 index 000000000000..88fcd2fc267d --- /dev/null +++ b/docs/integrations/sources/blogger.md @@ -0,0 +1,34 @@ +# Blogger +Google Blogger is a free blogging platform by Google that allows users to create and manage their own blogs with ease. It offers customizable templates, user-friendly tools, and integration with other Google services, making it simple to publish content and reach a wide audience. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `client_id` | `string` | Client ID. | | +| `client_secret` | `string` | Client secret. | | +| `client_refresh_token` | `string` | Refresh token. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| users | id | DefaultPaginator | ✅ | ❌ | +| blogs | id | DefaultPaginator | ✅ | ❌ | +| posts | | DefaultPaginator | ✅ | ❌ | +| pages | id | DefaultPaginator | ✅ | ❌ | +| comments | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50441](https://github.com/airbytehq/airbyte/pull/50441) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50162](https://github.com/airbytehq/airbyte/pull/50162) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49578](https://github.com/airbytehq/airbyte/pull/49578) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49012](https://github.com/airbytehq/airbyte/pull/49012) | Update dependencies | +| 0.0.1 | 2024-11-09 | | Initial release by [@bala-ceg](https://github.com/bala-ceg) via Connector Builder | + +
diff --git a/docs/integrations/sources/box.md b/docs/integrations/sources/box.md new file mode 100644 index 000000000000..eff8882355dc --- /dev/null +++ b/docs/integrations/sources/box.md @@ -0,0 +1,48 @@ +# Box +The Box Connector enables seamless data extraction from Box, allowing users to list, access, and synchronize files or folders from their Box cloud storage. This connector helps automate workflows by integrating Box data with other tools, ensuring efficient file management and analysis + +## Authentication +Follow [this](https://developer.box.com/guides/authentication/client-credentials/) guide to complete authentication. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `client_id` | `string` | OAuth Client ID. | | +| `client_secret` | `string` | OAuth Client Secret. | | +| `user` | `number` | User. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| events | | DefaultPaginator | ✅ | ❌ | +| sign_templates | id | DefaultPaginator | ✅ | ❌ | +| collections | id | DefaultPaginator | ✅ | ❌ | +| collection_items | id | DefaultPaginator | ✅ | ❌ | +| sign_request | id | DefaultPaginator | ✅ | ❌ | +| admin_logs | event_id | DefaultPaginator | ✅ | ❌ | +| files | id | DefaultPaginator | ✅ | ❌ | +| file_collaborations | id | DefaultPaginator | ✅ | ❌ | +| file_comments | id | DefaultPaginator | ✅ | ❌ | +| file_tasks | id | No pagination | ✅ | ❌ | +| folders | id | DefaultPaginator | ✅ | ❌ | +| folder_collaborations | id | DefaultPaginator | ✅ | ❌ | +| recent_items | id | DefaultPaginator | ✅ | ❌ | +| trashed_items | id | DefaultPaginator | ✅ | ❌ | +| users | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50497](https://github.com/airbytehq/airbyte/pull/50497) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50209](https://github.com/airbytehq/airbyte/pull/50209) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49580](https://github.com/airbytehq/airbyte/pull/49580) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49276](https://github.com/airbytehq/airbyte/pull/49276) | Update dependencies | +| 0.0.2 | 2024-12-11 | [48933](https://github.com/airbytehq/airbyte/pull/48933) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-24 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/braintree.md b/docs/integrations/sources/braintree.md index d71b0d6ccb13..9dc2b41d0a08 100644 --- a/docs/integrations/sources/braintree.md +++ b/docs/integrations/sources/braintree.md @@ -72,6 +72,11 @@ The Braintree connector should not run into Braintree API limitations under norm | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :--------------------------------------------------- | +| 0.3.25 | 2024-12-28 | [50500](https://github.com/airbytehq/airbyte/pull/50500) | Update dependencies | +| 0.3.24 | 2024-12-21 | [50211](https://github.com/airbytehq/airbyte/pull/50211) | Update dependencies | +| 0.3.23 | 2024-12-14 | [49556](https://github.com/airbytehq/airbyte/pull/49556) | Update dependencies | +| 0.3.22 | 2024-12-12 | [49032](https://github.com/airbytehq/airbyte/pull/49032) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.3.21 | 2024-11-04 | [48212](https://github.com/airbytehq/airbyte/pull/48212) | Update dependencies | | 0.3.20 | 2024-10-21 | [47062](https://github.com/airbytehq/airbyte/pull/47062) | Update dependencies | | 0.3.19 | 2024-10-12 | [46849](https://github.com/airbytehq/airbyte/pull/46849) | Update dependencies | | 0.3.18 | 2024-10-05 | [46496](https://github.com/airbytehq/airbyte/pull/46496) | Update dependencies | diff --git a/docs/integrations/sources/breezometer.md b/docs/integrations/sources/breezometer.md index f292ce879a3f..65b75be92d92 100644 --- a/docs/integrations/sources/breezometer.md +++ b/docs/integrations/sources/breezometer.md @@ -39,6 +39,12 @@ The Breezometer connector supports full sync refresh. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------ | +| 0.2.8 | 2024-12-28 | [50488](https://github.com/airbytehq/airbyte/pull/50488) | Update dependencies | +| 0.2.7 | 2024-12-21 | [50219](https://github.com/airbytehq/airbyte/pull/50219) | Update dependencies | +| 0.2.6 | 2024-12-14 | [49559](https://github.com/airbytehq/airbyte/pull/49559) | Update dependencies | +| 0.2.5 | 2024-12-12 | [49280](https://github.com/airbytehq/airbyte/pull/49280) | Update dependencies | +| 0.2.4 | 2024-12-11 | [48902](https://github.com/airbytehq/airbyte/pull/48902) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.3 | 2024-11-04 | [48260](https://github.com/airbytehq/airbyte/pull/48260) | Update dependencies | | 0.2.2 | 2024-10-29 | [47882](https://github.com/airbytehq/airbyte/pull/47882) | Update dependencies | | 0.2.1 | 2024-10-28 | [43777](https://github.com/airbytehq/airbyte/pull/43777) | Update dependencies | | 0.2.0 | 2024-08-22 | [44563](https://github.com/airbytehq/airbyte/pull/44563) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/breezy-hr.md b/docs/integrations/sources/breezy-hr.md index 603e34b61fc7..c4a2205690b4 100644 --- a/docs/integrations/sources/breezy-hr.md +++ b/docs/integrations/sources/breezy-hr.md @@ -22,6 +22,11 @@ An Airbyte source for Breezy applicant tracking system. | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.8 | 2024-12-28 | [50481](https://github.com/airbytehq/airbyte/pull/50481) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50198](https://github.com/airbytehq/airbyte/pull/50198) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49547](https://github.com/airbytehq/airbyte/pull/49547) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49315](https://github.com/airbytehq/airbyte/pull/49315) | Update dependencies | +| 0.0.4 | 2024-12-11 | [49020](https://github.com/airbytehq/airbyte/pull/49020) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.3 | 2024-10-29 | [47750](https://github.com/airbytehq/airbyte/pull/47750) | Update dependencies | | 0.0.2 | 2024-10-28 | [47587](https://github.com/airbytehq/airbyte/pull/47587) | Update dependencies | | 0.0.1 | 2024-08-20 | | Initial release by natikgadzhi via Connector Builder | diff --git a/docs/integrations/sources/brex.md b/docs/integrations/sources/brex.md new file mode 100644 index 000000000000..7ad113d2afda --- /dev/null +++ b/docs/integrations/sources/brex.md @@ -0,0 +1,35 @@ +# Brex +Fetches data on users, expenses, transactions, vendors, and budgets from Brex API. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `user_token` | `string` | User Token. User token to authenticate API requests. Generate it from your Brex dashboard under Developer > Settings. | | +| `start_date` | `string` | Start date. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| transactions | id | DefaultPaginator | ✅ | ✅ | +| users | id | DefaultPaginator | ✅ | ❌ | +| departments | id | DefaultPaginator | ✅ | ❌ | +| vendors | id | DefaultPaginator | ✅ | ❌ | +| expenses | id | DefaultPaginator | ✅ | ✅ | +| budgets | budget_id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50465](https://github.com/airbytehq/airbyte/pull/50465) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50161](https://github.com/airbytehq/airbyte/pull/50161) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49573](https://github.com/airbytehq/airbyte/pull/49573) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49006](https://github.com/airbytehq/airbyte/pull/49006) | Update dependencies | +| 0.0.2 | 2024-12-11 | [48938](https://github.com/airbytehq/airbyte/pull/48938) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-30 | | Initial release by [@natikgadzhi](https://github.com/natikgadzhi) via Connector Builder | + +
diff --git a/docs/integrations/sources/bugsnag.md b/docs/integrations/sources/bugsnag.md index 0417e9a250a2..1b1118aec20c 100644 --- a/docs/integrations/sources/bugsnag.md +++ b/docs/integrations/sources/bugsnag.md @@ -34,6 +34,10 @@ You need to generate the `auth_token` to get started. Personal Auth Tokens can b | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50452](https://github.com/airbytehq/airbyte/pull/50452) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50163](https://github.com/airbytehq/airbyte/pull/50163) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49562](https://github.com/airbytehq/airbyte/pull/49562) | Update dependencies | +| 0.0.2 | 2024-12-12 | [48953](https://github.com/airbytehq/airbyte/pull/48953) | Update dependencies | | 0.0.1 | 2024-10-16 | | Initial release by [@topefolorunso](https://github.com/topefolorunso) via Connector Builder | diff --git a/docs/integrations/sources/buildkite.md b/docs/integrations/sources/buildkite.md index df3f663c4bd2..505abc02d957 100644 --- a/docs/integrations/sources/buildkite.md +++ b/docs/integrations/sources/buildkite.md @@ -38,6 +38,10 @@ Visit `https://buildkite.com/user/api-access-tokens` for getting your bearer tok | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.6 | 2024-12-28 | [50485](https://github.com/airbytehq/airbyte/pull/50485) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50205](https://github.com/airbytehq/airbyte/pull/50205) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49590](https://github.com/airbytehq/airbyte/pull/49590) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49010](https://github.com/airbytehq/airbyte/pull/49010) | Update dependencies | | 0.0.2 | 2024-10-29 | [47476](https://github.com/airbytehq/airbyte/pull/47476) | Update dependencies | | 0.0.1 | 2024-09-11 | [45384](https://github.com/airbytehq/airbyte/pull/45384) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/bunny-inc.md b/docs/integrations/sources/bunny-inc.md new file mode 100644 index 000000000000..ad4bc091e1be --- /dev/null +++ b/docs/integrations/sources/bunny-inc.md @@ -0,0 +1,46 @@ +# Bunny RevOps + +Bunny provides a single platform for subscription management, billing, quoting, revenue recognition, and SaaS metrics. +[API Docs](https://docs.bunny.com/developer) + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `apikey` | `string` | API Key. | | +| `subdomain` | `string` | Subdomain. The subdomain specific to your Bunny account or service. | | +| `start_date` | `string` | Start date. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| accounts | id | DefaultPaginator | ✅ | ❌ | +| accountBalances | id | DefaultPaginator | ✅ | ❌ | +| contacts | id | DefaultPaginator | ✅ | ❌ | +| entities | id | DefaultPaginator | ✅ | ❌ | +| invoices | id | DefaultPaginator | ✅ | ❌ | +| invoiceItems | id | DefaultPaginator | ✅ | ❌ | +| payments | id | DefaultPaginator | ✅ | ❌ | +| products | id | DefaultPaginator | ✅ | ❌ | +| plans | id | DefaultPaginator | ✅ | ❌ | +| quotes | id | DefaultPaginator | ✅ | ❌ | +| quote_charges | id | DefaultPaginator | ✅ | ❌ | +| subscriptions | id | DefaultPaginator | ✅ | ❌ | +| subscriptionCharges | id | DefaultPaginator | ✅ | ❌ | +| transactions | id | DefaultPaginator | ✅ | ❌ | +| tenants | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50470](https://github.com/airbytehq/airbyte/pull/50470) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50190](https://github.com/airbytehq/airbyte/pull/50190) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49555](https://github.com/airbytehq/airbyte/pull/49555) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49007](https://github.com/airbytehq/airbyte/pull/49007) | Update dependencies | +| 0.0.1 | 2024-10-29 | | Initial release by [@tbpeders](https://github.com/tbpeders) via Connector Builder | + +
diff --git a/docs/integrations/sources/buzzsprout.md b/docs/integrations/sources/buzzsprout.md index 8921b9744bcd..9b5fa44ff248 100644 --- a/docs/integrations/sources/buzzsprout.md +++ b/docs/integrations/sources/buzzsprout.md @@ -30,6 +30,12 @@ Visit `https://github.com/buzzsprout/buzzsprout-api/tree/master?tab=readme-ov-fi | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.9 | 2024-12-28 | [50479](https://github.com/airbytehq/airbyte/pull/50479) | Update dependencies | +| 0.0.8 | 2024-12-21 | [50153](https://github.com/airbytehq/airbyte/pull/50153) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49564](https://github.com/airbytehq/airbyte/pull/49564) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49278](https://github.com/airbytehq/airbyte/pull/49278) | Update dependencies | +| 0.0.5 | 2024-12-11 | [49029](https://github.com/airbytehq/airbyte/pull/49029) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-11-04 | [48228](https://github.com/airbytehq/airbyte/pull/48228) | Update dependencies | | 0.0.3 | 2024-10-29 | [47747](https://github.com/airbytehq/airbyte/pull/47747) | Update dependencies | | 0.0.2 | 2024-10-28 | [47645](https://github.com/airbytehq/airbyte/pull/47645) | Update dependencies | | 0.0.1 | 2024-09-16 | [45608](https://github.com/airbytehq/airbyte/pull/45608) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/cal-com.md b/docs/integrations/sources/cal-com.md new file mode 100644 index 000000000000..e5cc0aac1dbc --- /dev/null +++ b/docs/integrations/sources/cal-com.md @@ -0,0 +1,34 @@ +# Cal.com +The Cal.com connector enables seamless data synchronization between Cal.com’s scheduling platform and various destinations. It helps extract events, attendees, and booking details from Cal.com, making it easy to analyze scheduling data or integrate it into downstream systems like data warehouses or CRMs. This connector streamlines automated reporting and insights for time management and booking analytics + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `orgId` | `string` | Organization ID. | | +| `api_key` | `string` | API Key. API key to use. Find it at https://cal.com/account | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| event_types | id | DefaultPaginator | ✅ | ❌ | +| my_profile | id | No pagination | ✅ | ❌ | +| schedules | id | DefaultPaginator | ✅ | ❌ | +| calendars | externalId | No pagination | ✅ | ❌ | +| bookings | id | DefaultPaginator | ✅ | ❌ | +| conferencing | id | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50216](https://github.com/airbytehq/airbyte/pull/50216) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49584](https://github.com/airbytehq/airbyte/pull/49584) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49285](https://github.com/airbytehq/airbyte/pull/49285) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49023](https://github.com/airbytehq/airbyte/pull/49023) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-11 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/calendly.md b/docs/integrations/sources/calendly.md index 62b25401a85b..634af88e4d4a 100644 --- a/docs/integrations/sources/calendly.md +++ b/docs/integrations/sources/calendly.md @@ -32,6 +32,12 @@ Incremental sync in `scheduled_events` uses `start_time` as a cursor. This may l | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.8 | 2024-12-28 | [50462](https://github.com/airbytehq/airbyte/pull/50462) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50152](https://github.com/airbytehq/airbyte/pull/50152) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49551](https://github.com/airbytehq/airbyte/pull/49551) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49275](https://github.com/airbytehq/airbyte/pull/49275) | Update dependencies | +| 0.0.4 | 2024-12-11 | [49022](https://github.com/airbytehq/airbyte/pull/49022) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.3 | 2024-11-04 | [48279](https://github.com/airbytehq/airbyte/pull/48279) | Update dependencies | | 0.0.2 | 2024-10-28 | [47568](https://github.com/airbytehq/airbyte/pull/47568) | Update dependencies | | 0.0.1 | 2024-09-01 | | Initial release by [@natikgadzhi](https://github.com/natikgadzhi) via Connector Builder | diff --git a/docs/integrations/sources/campaign-monitor.md b/docs/integrations/sources/campaign-monitor.md index 1a7ca0e9ae3a..9fd82a0e811b 100644 --- a/docs/integrations/sources/campaign-monitor.md +++ b/docs/integrations/sources/campaign-monitor.md @@ -59,6 +59,11 @@ The source connector supports the following [sync modes](https://docs.airbyte.co | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50476](https://github.com/airbytehq/airbyte/pull/50476) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50185](https://github.com/airbytehq/airbyte/pull/50185) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49581](https://github.com/airbytehq/airbyte/pull/49581) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49002](https://github.com/airbytehq/airbyte/pull/49002) | Update dependencies | +| 0.0.3 | 2024-11-04 | [48232](https://github.com/airbytehq/airbyte/pull/48232) | Update dependencies | | 0.0.2 | 2024-10-28 | [47643](https://github.com/airbytehq/airbyte/pull/47643) | Update dependencies | | 0.0.1 | 2024-10-05 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | diff --git a/docs/integrations/sources/campayn.md b/docs/integrations/sources/campayn.md new file mode 100644 index 000000000000..e3cc35887772 --- /dev/null +++ b/docs/integrations/sources/campayn.md @@ -0,0 +1,34 @@ +# Campayn +The Airbyte connector for [Campayn](https://campayn.com/) enables seamless data integration between the Campayn email marketing platform and your data warehouse or analytics system. This connector automates the extraction of subscriber lists, email campaigns, performance metrics, and engagement data from Campayn, allowing businesses to centralize marketing insights, optimize email strategies, and drive data-driven decisions efficiently. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `sub_domain` | `string` | Sub Domain. | | +| `api_key` | `string` | API Key. API key to use. Find it in your Campayn account settings. Keep it secure as it grants access to your Campayn data. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| lists | id | No pagination | ✅ | ❌ | +| forms | id | No pagination | ✅ | ❌ | +| contacts | id | No pagination | ✅ | ❌ | +| emails | id | No pagination | ✅ | ❌ | +| reports | id | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50461](https://github.com/airbytehq/airbyte/pull/50461) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50208](https://github.com/airbytehq/airbyte/pull/50208) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49585](https://github.com/airbytehq/airbyte/pull/49585) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49306](https://github.com/airbytehq/airbyte/pull/49306) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49036](https://github.com/airbytehq/airbyte/pull/49036) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-31 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/canny.md b/docs/integrations/sources/canny.md index 5ae710f465e9..d5c3f9d9ae4d 100644 --- a/docs/integrations/sources/canny.md +++ b/docs/integrations/sources/canny.md @@ -28,6 +28,11 @@ A manifest only source for Canny. https://canny.io/ | Version | Date | Pull Request | Subject | |---------|------------|----------------------------------------------------------|-------------------------------------------------------------------------------------------| +| 0.0.7 | 2024-12-28 | [50489](https://github.com/airbytehq/airbyte/pull/50489) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50171](https://github.com/airbytehq/airbyte/pull/50171) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49574](https://github.com/airbytehq/airbyte/pull/49574) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49013](https://github.com/airbytehq/airbyte/pull/49013) | Update dependencies | +| 0.0.3 | 2024-11-04 | [48235](https://github.com/airbytehq/airbyte/pull/48235) | Update dependencies | | 0.0.2 | 2024-10-29 | [47727](https://github.com/airbytehq/airbyte/pull/47727) | Update dependencies | | 0.0.1 | 2024-09-15 | [45588](https://github.com/airbytehq/airbyte/pull/45588) | Initial release by [@pabloescoder](https://github.com/pabloescoder) via Connector Builder | diff --git a/docs/integrations/sources/capsule-crm.md b/docs/integrations/sources/capsule-crm.md new file mode 100644 index 000000000000..7bbfc4b4d461 --- /dev/null +++ b/docs/integrations/sources/capsule-crm.md @@ -0,0 +1,46 @@ +# Capsule CRM +Capsule CRM connector enables seamless data syncing from Capsule CRM to various data warehouses, helping businesses centralize and analyze customer data efficiently. It supports real-time data extraction of contacts, opportunities, and custom fields, making it ideal for comprehensive CRM analytics and reporting. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `bearer_token` | `string` | Bearer Token. Bearer token to authenticate API requests. Generate it from the 'My Preferences' > 'API Authentication Tokens' page in your Capsule account. | | +| `start_date` | `string` | Start date. | | +| `entity` | `string` | Entity. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| users | id | DefaultPaginator | ✅ | ❌ | +| parties | id | DefaultPaginator | ✅ | ❌ | +| tasks | id | DefaultPaginator | ✅ | ❌ | +| employees | id | DefaultPaginator | ✅ | ❌ | +| projects | id | DefaultPaginator | ✅ | ❌ | +| opportunities | id | DefaultPaginator | ✅ | ✅ | +| pipelines | id | DefaultPaginator | ✅ | ❌ | +| milestones | id | DefaultPaginator | ✅ | ❌ | +| site | | DefaultPaginator | ✅ | ❌ | +| tags | id | DefaultPaginator | ✅ | ❌ | +| custom_fields | id | DefaultPaginator | ✅ | ❌ | +| lost_reasons | id | DefaultPaginator | ✅ | ❌ | +| board | id | DefaultPaginator | ✅ | ❌ | +| categories | id | DefaultPaginator | ✅ | ❌ | +| activity_types | id | DefaultPaginator | ✅ | ❌ | +| stages | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50484](https://github.com/airbytehq/airbyte/pull/50484) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50172](https://github.com/airbytehq/airbyte/pull/50172) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49566](https://github.com/airbytehq/airbyte/pull/49566) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49314](https://github.com/airbytehq/airbyte/pull/49314) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49028](https://github.com/airbytehq/airbyte/pull/49028) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-09 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/captain-data.md b/docs/integrations/sources/captain-data.md index 7950fc64d4e8..b4900357b7c0 100644 --- a/docs/integrations/sources/captain-data.md +++ b/docs/integrations/sources/captain-data.md @@ -65,6 +65,12 @@ Captain Data [API reference](https://docs.captaindata.co/#intro) has v3 at prese | Version | Date | Pull Request | Subject | | :------ |:-----------| :------------------------------------------------------ |:--------------------------------------------| +| 0.2.7 | 2024-12-28 | [50475](https://github.com/airbytehq/airbyte/pull/50475) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50192](https://github.com/airbytehq/airbyte/pull/50192) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49569](https://github.com/airbytehq/airbyte/pull/49569) | Update dependencies | +| 0.2.4 | 2024-12-12 | [49299](https://github.com/airbytehq/airbyte/pull/49299) | Update dependencies | +| 0.2.3 | 2024-12-11 | [48900](https://github.com/airbytehq/airbyte/pull/48900) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.2 | 2024-11-04 | [48177](https://github.com/airbytehq/airbyte/pull/48177) | Update dependencies | | 0.2.1 | 2024-10-29 | [47769](https://github.com/airbytehq/airbyte/pull/47769) | Update dependencies | | 0.2.0 | 2024-08-19 | [44419](https://github.com/airbytehq/airbyte/pull/44419) | Refactor connector to manifest-only format | | 0.1.15 | 2024-08-17 | [44340](https://github.com/airbytehq/airbyte/pull/44340) | Update dependencies | diff --git a/docs/integrations/sources/care-quality-commission.md b/docs/integrations/sources/care-quality-commission.md index 26c778d054cd..ebc2edd4a4df 100644 --- a/docs/integrations/sources/care-quality-commission.md +++ b/docs/integrations/sources/care-quality-commission.md @@ -25,6 +25,12 @@ https://www.cqc.org.uk/ | Version | Date | Pull Request | Subject | |---------|------------|----------------------------------------------------------|-------------------------------------------------------------------------------------------| +| 0.0.9 | 2024-12-28 | [50495](https://github.com/airbytehq/airbyte/pull/50495) | Update dependencies | +| 0.0.8 | 2024-12-21 | [50218](https://github.com/airbytehq/airbyte/pull/50218) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49546](https://github.com/airbytehq/airbyte/pull/49546) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49008](https://github.com/airbytehq/airbyte/pull/49008) | Update dependencies | +| 0.0.5 | 2024-11-05 | [48368](https://github.com/airbytehq/airbyte/pull/48368) | Revert to source-declarative-manifest v5.17.0 | +| 0.0.4 | 2024-11-05 | [48329](https://github.com/airbytehq/airbyte/pull/48329) | Update dependencies | | 0.0.3 | 2024-10-29 | [47897](https://github.com/airbytehq/airbyte/pull/47897) | Update dependencies | | 0.0.2 | 2024-10-28 | [47671](https://github.com/airbytehq/airbyte/pull/47671) | Update dependencies | | 0.0.1 | 2024-10-02 | [46315](https://github.com/airbytehq/airbyte/pull/46315) | Initial release by [@pabloescoder](https://github.com/pabloescoder) via Connector Builder | diff --git a/docs/integrations/sources/cart.md b/docs/integrations/sources/cart.md index 338521140bca..a911eda734e8 100644 --- a/docs/integrations/sources/cart.md +++ b/docs/integrations/sources/cart.md @@ -53,6 +53,11 @@ Please follow these [steps](https://developers.cart.com/docs/rest-api/docs/READM | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------------- | +| 0.3.11 | 2024-12-28 | [50505](https://github.com/airbytehq/airbyte/pull/50505) | Update dependencies | +| 0.3.10 | 2024-12-21 | [50189](https://github.com/airbytehq/airbyte/pull/50189) | Update dependencies | +| 0.3.9 | 2024-12-14 | [49316](https://github.com/airbytehq/airbyte/pull/49316) | Update dependencies | +| 0.3.8 | 2024-11-25 | [48637](https://github.com/airbytehq/airbyte/pull/48637) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.3.7 | 2024-11-04 | [43726](https://github.com/airbytehq/airbyte/pull/43726) | Update dependencies | | 0.3.6 | 2024-06-29 | [40011](https://github.com/airbytehq/airbyte/pull/40011) | Update dependencies | | 0.3.5 | 2024-04-19 | [37131](https://github.com/airbytehq/airbyte/pull/37131) | Updating to 0.80.0 CDK | | 0.3.4 | 2024-04-18 | [37131](https://github.com/airbytehq/airbyte/pull/37131) | Manage dependencies with Poetry. | diff --git a/docs/integrations/sources/castor-edc.md b/docs/integrations/sources/castor-edc.md index f79210c2a017..5b4bfa0c3f35 100644 --- a/docs/integrations/sources/castor-edc.md +++ b/docs/integrations/sources/castor-edc.md @@ -43,6 +43,12 @@ Visit `https://YOUR_REGION.castoredc.com/account/settings` for getting your clie | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.9 | 2024-12-28 | [50456](https://github.com/airbytehq/airbyte/pull/50456) | Update dependencies | +| 0.0.8 | 2024-12-21 | [50156](https://github.com/airbytehq/airbyte/pull/50156) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49591](https://github.com/airbytehq/airbyte/pull/49591) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49289](https://github.com/airbytehq/airbyte/pull/49289) | Update dependencies | +| 0.0.5 | 2024-12-11 | [49019](https://github.com/airbytehq/airbyte/pull/49019) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-11-04 | [48298](https://github.com/airbytehq/airbyte/pull/48298) | Update dependencies | | 0.0.3 | 2024-10-29 | [47741](https://github.com/airbytehq/airbyte/pull/47741) | Update dependencies | | 0.0.2 | 2024-10-28 | [47644](https://github.com/airbytehq/airbyte/pull/47644) | Update dependencies | | 0.0.1 | 2024-10-12 | [46759](https://github.com/airbytehq/airbyte/pull/46759) | Initial release by [@gemsteam](https://github.com/gemsteam) via Connector Builder | diff --git a/docs/integrations/sources/chameleon.md b/docs/integrations/sources/chameleon.md index ee93b87f7d7a..6833a4380483 100644 --- a/docs/integrations/sources/chameleon.md +++ b/docs/integrations/sources/chameleon.md @@ -40,6 +40,11 @@ Refer `https://app.chameleon.io/settings/tokens` for getting your API key. | Version | Date | Pull Request | Subject | |------------------|------------|--------------|----------------| +| 0.1.6 | 2024-12-28 | [50450](https://github.com/airbytehq/airbyte/pull/50450) | Update dependencies | +| 0.1.5 | 2024-12-21 | [50165](https://github.com/airbytehq/airbyte/pull/50165) | Update dependencies | +| 0.1.4 | 2024-12-14 | [49577](https://github.com/airbytehq/airbyte/pull/49577) | Update dependencies | +| 0.1.3 | 2024-12-12 | [49018](https://github.com/airbytehq/airbyte/pull/49018) | Update dependencies | +| 0.1.2 | 2024-11-04 | [48250](https://github.com/airbytehq/airbyte/pull/48250) | Update dependencies | | 0.1.1 | 2024-10-29 | [47822](https://github.com/airbytehq/airbyte/pull/47822) | Update dependencies | | 0.1.0 | 2024-09-29 | [46248](https://github.com/airbytehq/airbyte/pull/46248) | Fix survey_responses stream schema and icon | | 0.0.2 | 2024-09-21 | [45708](https://github.com/airbytehq/airbyte/pull/45708) | Make end date optional | diff --git a/docs/integrations/sources/chargebee.md b/docs/integrations/sources/chargebee.md index 4f6169698e9b..225b6041335d 100644 --- a/docs/integrations/sources/chargebee.md +++ b/docs/integrations/sources/chargebee.md @@ -104,6 +104,10 @@ The Chargebee connector should not run into [Chargebee API](https://apidocs.char | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------| +| 0.7.2 | 2024-11-20 | [48510](https://github.com/airbytehq/airbyte/pull/48510) | Ensure no pagination issues on concurrent syncs | +| 0.7.1 | 2024-11-04 | [48133](https://github.com/airbytehq/airbyte/pull/48133) | Fix `error message pattern` to handle `Product 1.0` related errors | +| 0.7.0 | 2024-10-30 | [47978](https://github.com/airbytehq/airbyte/pull/47978) | Upgrade the CDK and startup files to sync incremental streams concurrently | +| 0.6.18 | 2024-10-31 | [47099](https://github.com/airbytehq/airbyte/pull/47099) | Update dependencies | | 0.6.17 | 2024-10-28 | [46846](https://github.com/airbytehq/airbyte/pull/47387) | Update CDK dependencies to yield parent records more frequently | | 0.6.16 | 2024-10-12 | [46846](https://github.com/airbytehq/airbyte/pull/46846) | Update dependencies | | 0.6.15 | 2024-10-05 | [46478](https://github.com/airbytehq/airbyte/pull/46478) | Update dependencies | diff --git a/docs/integrations/sources/chargedesk.md b/docs/integrations/sources/chargedesk.md index a548eae020d0..5bbaab4d1b13 100644 --- a/docs/integrations/sources/chargedesk.md +++ b/docs/integrations/sources/chargedesk.md @@ -30,6 +30,12 @@ You can find more about the API here https://chargedesk.com/api-docs | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.9 | 2024-12-28 | [50448](https://github.com/airbytehq/airbyte/pull/50448) | Update dependencies | +| 0.0.8 | 2024-12-21 | [50170](https://github.com/airbytehq/airbyte/pull/50170) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49554](https://github.com/airbytehq/airbyte/pull/49554) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49309](https://github.com/airbytehq/airbyte/pull/49309) | Update dependencies | +| 0.0.5 | 2024-12-11 | [49037](https://github.com/airbytehq/airbyte/pull/49037) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-11-04 | [48205](https://github.com/airbytehq/airbyte/pull/48205) | Update dependencies | | 0.0.3 | 2024-10-29 | [47832](https://github.com/airbytehq/airbyte/pull/47832) | Update dependencies | | 0.0.2 | 2024-10-28 | [47560](https://github.com/airbytehq/airbyte/pull/47560) | Update dependencies | | 0.0.1 | 2024-10-18 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | diff --git a/docs/integrations/sources/chargify.md b/docs/integrations/sources/chargify.md index f1d0d2bb1b26..4e629530b949 100644 --- a/docs/integrations/sources/chargify.md +++ b/docs/integrations/sources/chargify.md @@ -45,6 +45,11 @@ Please follow the [Chargify documentation for generating an API key](https://dev | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------ | +| 0.5.5 | 2024-12-28 | [50463](https://github.com/airbytehq/airbyte/pull/50463) | Update dependencies | +| 0.5.4 | 2024-12-21 | [50187](https://github.com/airbytehq/airbyte/pull/50187) | Update dependencies | +| 0.5.3 | 2024-12-14 | [49589](https://github.com/airbytehq/airbyte/pull/49589) | Update dependencies | +| 0.5.2 | 2024-12-12 | [49300](https://github.com/airbytehq/airbyte/pull/49300) | Update dependencies | +| 0.5.1 | 2024-12-11 | [48959](https://github.com/airbytehq/airbyte/pull/48959) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.5.0 | 2024-08-23 | [44602](https://github.com/airbytehq/airbyte/pull/44602) | Refactor connector to manifest-only format | | 0.4.15 | 2024-08-17 | [44230](https://github.com/airbytehq/airbyte/pull/44230) | Update dependencies | | 0.4.14 | 2024-08-12 | [43775](https://github.com/airbytehq/airbyte/pull/43775) | Update dependencies | diff --git a/docs/integrations/sources/chartmogul.md b/docs/integrations/sources/chartmogul.md index 214daa4f010b..cffbb666a4d2 100644 --- a/docs/integrations/sources/chartmogul.md +++ b/docs/integrations/sources/chartmogul.md @@ -65,6 +65,10 @@ The Chartmogul connector should not run into Chartmogul API limitations under no | Version | Date | Pull Request | Subject | |:--------|:-----------| :------------------------------------------------------- |:---------------------------------------------------------------------------------------------------------------------------------| +| 1.1.5 | 2024-12-28 | [50503](https://github.com/airbytehq/airbyte/pull/50503) | Update dependencies | +| 1.1.4 | 2024-12-21 | [50210](https://github.com/airbytehq/airbyte/pull/50210) | Update dependencies | +| 1.1.3 | 2024-12-14 | [49563](https://github.com/airbytehq/airbyte/pull/49563) | Update dependencies | +| 1.1.2 | 2024-12-12 | [48951](https://github.com/airbytehq/airbyte/pull/48951) | Update dependencies | | 1.1.1 | 2024-10-28 | [47637](https://github.com/airbytehq/airbyte/pull/47637) | Update dependencies | | 1.1.0 | 2024-08-19 | [44418](https://github.com/airbytehq/airbyte/pull/44418) | Refactor connector to manifest-only format | | 1.0.13 | 2024-08-17 | [44342](https://github.com/airbytehq/airbyte/pull/44342) | Update dependencies | diff --git a/docs/integrations/sources/cimis.md b/docs/integrations/sources/cimis.md index 13fcf3d8c6d8..12c00efec228 100644 --- a/docs/integrations/sources/cimis.md +++ b/docs/integrations/sources/cimis.md @@ -33,6 +33,12 @@ To get started, register and request your appKey from the [CIMIS website](https: | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.8 | 2024-12-28 | [50453](https://github.com/airbytehq/airbyte/pull/50453) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50154](https://github.com/airbytehq/airbyte/pull/50154) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49565](https://github.com/airbytehq/airbyte/pull/49565) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49281](https://github.com/airbytehq/airbyte/pull/49281) | Update dependencies | +| 0.0.4 | 2024-12-11 | [49024](https://github.com/airbytehq/airbyte/pull/49024) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.3 | 2024-11-04 | [48156](https://github.com/airbytehq/airbyte/pull/48156) | Update dependencies | | 0.0.2 | 2024-10-28 | [47556](https://github.com/airbytehq/airbyte/pull/47556) | Update dependencies | | 0.0.1 | 2024-09-18 | | Initial release by [@topefolorunso](https://github.com/topefolorunso) via Connector Builder | diff --git a/docs/integrations/sources/cin7.md b/docs/integrations/sources/cin7.md new file mode 100644 index 000000000000..1d9c8bc1530a --- /dev/null +++ b/docs/integrations/sources/cin7.md @@ -0,0 +1,49 @@ +# Cin7 Inventory API +This is the Cin7 source that ingests data from the Cin7 API. + +Cin7 (Connector Inventory Performance), If you’re a business that wants to grow, you need an inventory solution you can count on - both now and in the future. With Cin7 you get a real-time picture of your products across systems, channels, marketplaces and regions, plus NEW ForesightAI advanced inventory forecasting that empowers you to see around corners and stay three steps ahead of demand! https://www.cin7.com/ + +To use this source, you must first create an account. Once logged in, head to Integrations -> API -> Cin7 Core API. +Create an application and note down the Account Id and the API key, you will need to enter these in the input fields. You can find more information about the [API Documentation](https://dearinventory.docs.apiary.io/#reference) + + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `accountid` | `string` | AccountID. The ID associated with your account. | | +| `api_key` | `string` | API Key. The API key associated with your account. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| bank_accounts | AccountID | DefaultPaginator | ✅ | ❌ | +| attribute_sets | ID | DefaultPaginator | ✅ | ❌ | +| accounts | Code | DefaultPaginator | ✅ | ❌ | +| brands | ID | DefaultPaginator | ✅ | ❌ | +| carriers | CarrierID | DefaultPaginator | ✅ | ❌ | +| customers | ID | DefaultPaginator | ✅ | ❌ | +| deals | ID | No pagination | ✅ | ❌ | +| locations | | DefaultPaginator | ✅ | ❌ | +| products | ID | DefaultPaginator | ✅ | ❌ | +| purchases | ID | DefaultPaginator | ✅ | ❌ | +| suppliers | ID | DefaultPaginator | ✅ | ❌ | +| product_categories | ID | DefaultPaginator | ✅ | ❌ | +| sale_lists | ID | DefaultPaginator | ✅ | ❌ | +| product_families | ID | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50466](https://github.com/airbytehq/airbyte/pull/50466) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50191](https://github.com/airbytehq/airbyte/pull/50191) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49576](https://github.com/airbytehq/airbyte/pull/49576) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49284](https://github.com/airbytehq/airbyte/pull/49284) | Update dependencies | +| 0.0.2 | 2024-12-11 | [48950](https://github.com/airbytehq/airbyte/pull/48950) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-30 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | + +
diff --git a/docs/integrations/sources/circa.md b/docs/integrations/sources/circa.md new file mode 100644 index 000000000000..2792adabc25c --- /dev/null +++ b/docs/integrations/sources/circa.md @@ -0,0 +1,39 @@ +# Simple Circa +Airbyte connector for [SimpleCirca](https://www.simplecirca.com/) would enable seamless data extraction from Simple Circa's platform, facilitating automated data integration into your data warehouse or analytics systems. This connector would pull key metrics, user engagement data, and content performance insights, offering streamlined reporting and analysis workflows. Ideal for organizations looking to consolidate Circa’s data with other sources for comprehensive business intelligence. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use. Find it at https://app.circa.co/settings/integrations/api | | +| `start_date` | `string` | Start date. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| events | id | DefaultPaginator | ✅ | ✅ | +| contacts | id | DefaultPaginator | ✅ | ✅ | +| teams | id | DefaultPaginator | ✅ | ❌ | +| companies | | DefaultPaginator | ✅ | ✅ | +| company_contacts | id | DefaultPaginator | ✅ | ❌ | +| event_fields | id | No pagination | ✅ | ❌ | +| contact_fields | id | No pagination | ✅ | ❌ | +| company_fields | id | No pagination | ✅ | ❌ | +| event_contacts | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50487](https://github.com/airbytehq/airbyte/pull/50487) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50197](https://github.com/airbytehq/airbyte/pull/50197) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49545](https://github.com/airbytehq/airbyte/pull/49545) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49313](https://github.com/airbytehq/airbyte/pull/49313) | Update dependencies | +| 0.0.3 | 2024-12-11 | [49034](https://github.com/airbytehq/airbyte/pull/49034) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.2 | 2024-11-04 | [48268](https://github.com/airbytehq/airbyte/pull/48268) | Update dependencies | +| 0.0.1 | 2024-10-21 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/clarif-ai.md b/docs/integrations/sources/clarif-ai.md index 366ad168b13f..04f8eae3f7bf 100644 --- a/docs/integrations/sources/clarif-ai.md +++ b/docs/integrations/sources/clarif-ai.md @@ -31,6 +31,13 @@ API Documentation: https://docs.clarifai.com/api-guide/api-overview/helpful-api- | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.8 | 2024-12-28 | [50482](https://github.com/airbytehq/airbyte/pull/50482) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50178](https://github.com/airbytehq/airbyte/pull/50178) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49583](https://github.com/airbytehq/airbyte/pull/49583) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49295](https://github.com/airbytehq/airbyte/pull/49295) | Update dependencies | +| 0.0.4 | 2024-12-11 | [48898](https://github.com/airbytehq/airbyte/pull/48898) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.3 | 2024-11-05 | [48355](https://github.com/airbytehq/airbyte/pull/48355) | Revert to source-declarative-manifest v5.17.0 | +| 0.0.2 | 2024-11-05 | [48321](https://github.com/airbytehq/airbyte/pull/48321) | Update dependencies | | 0.0.1 | 2024-10-21 | | Initial release by [@gemsteam](https://github.com/gemsteam) via Connector Builder | diff --git a/docs/integrations/sources/clazar.md b/docs/integrations/sources/clazar.md index eaba21fd6581..695fb59207dd 100644 --- a/docs/integrations/sources/clazar.md +++ b/docs/integrations/sources/clazar.md @@ -112,6 +112,12 @@ Please [create an issue](https://github.com/airbytehq/airbyte/issues) if you see | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:--------------------------------------------------------------------------| +| 0.4.8 | 2024-12-28 | [50473](https://github.com/airbytehq/airbyte/pull/50473) | Update dependencies | +| 0.4.7 | 2024-12-21 | [50214](https://github.com/airbytehq/airbyte/pull/50214) | Update dependencies | +| 0.4.6 | 2024-12-14 | [49570](https://github.com/airbytehq/airbyte/pull/49570) | Update dependencies | +| 0.4.5 | 2024-12-12 | [49009](https://github.com/airbytehq/airbyte/pull/49009) | Update dependencies | +| 0.4.4 | 2024-11-04 | [48187](https://github.com/airbytehq/airbyte/pull/48187) | Update dependencies | +| 0.4.3 | 2024-10-30 | [46949](https://github.com/airbytehq/airbyte/pull/46949) | Updated the logo | | 0.4.2 | 2024-10-29 | [47843](https://github.com/airbytehq/airbyte/pull/47843) | Update dependencies | | 0.4.1 | 2024-10-28 | [47598](https://github.com/airbytehq/airbyte/pull/47598) | Update dependencies | | 0.4.0 | 2024-08-30 | [44855](https://github.com/airbytehq/airbyte/pull/44855) | Using incremental APIs for online data | diff --git a/docs/integrations/sources/clickhouse.md b/docs/integrations/sources/clickhouse.md index cbbedad92b5d..85039e145ef8 100644 --- a/docs/integrations/sources/clickhouse.md +++ b/docs/integrations/sources/clickhouse.md @@ -80,10 +80,11 @@ Using this feature requires additional configuration, when creating the source. | Version | Date | Pull Request | Subject | | :------ | :--------- | :--------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------- | -| 0.2.2 | 2024-02-13 | [35235](https://github.com/airbytehq/airbyte/pull/35235) | Adopt CDK 0.20.4 | -| 0.2.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | -| 0.1.17 | 2023-03-22 | [20760](https://github.com/airbytehq/airbyte/pull/20760) | Removed redundant date-time datatypes formatting | -| 0.1.16 | 2023-03-06 | [23455](https://github.com/airbytehq/airbyte/pull/23455) | For network isolation, source connector accepts a list of hosts it is allowed to connect to | +| 0.2.3 | 2024-12-18 | [49901](https://github.com/airbytehq/airbyte/pull/49901) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.2.2 | 2024-02-13 | [35235](https://github.com/airbytehq/airbyte/pull/35235) | Adopt CDK 0.20.4 | +| 0.2.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | +| 0.1.17 | 2023-03-22 | [20760](https://github.com/airbytehq/airbyte/pull/20760) | Removed redundant date-time datatypes formatting | +| 0.1.16 | 2023-03-06 | [23455](https://github.com/airbytehq/airbyte/pull/23455) | For network isolation, source connector accepts a list of hosts it is allowed to connect to | | 0.1.15 | 2022-12-14 | [20436](https://github.com/airbytehq/airbyte/pull/20346) | Consolidate date/time values mapping for JDBC sources | | 0.1.14 | 2022-09-27 | [17031](https://github.com/airbytehq/airbyte/pull/17031) | Added custom jdbc url parameters field | | 0.1.13 | 2022-09-01 | [16238](https://github.com/airbytehq/airbyte/pull/16238) | Emit state messages more frequently | @@ -121,4 +122,4 @@ Using this feature requires additional configuration, when creating the source. | 0.1.1 | 20.10.2021 | [\#7327](https://github.com/airbytehq/airbyte/pull/7327) | Added support for connection via SSH tunnel(aka Bastion server). | | 0.1.0 | 20.10.2021 | [\#7127](https://github.com/airbytehq/airbyte/pull/7127) | Added source-clickhouse-strict-encrypt that supports SSL connections only. | - \ No newline at end of file + diff --git a/docs/integrations/sources/clickup-api.md b/docs/integrations/sources/clickup-api.md index 3e15147395ae..b1c9f2ba017e 100644 --- a/docs/integrations/sources/clickup-api.md +++ b/docs/integrations/sources/clickup-api.md @@ -57,6 +57,10 @@ Here are some optional fields: | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :-------------------------------- | +| 0.3.5 | 2024-12-28 | [50474](https://github.com/airbytehq/airbyte/pull/50474) | Update dependencies | +| 0.3.4 | 2024-12-21 | [50199](https://github.com/airbytehq/airbyte/pull/50199) | Update dependencies | +| 0.3.3 | 2024-12-14 | [49579](https://github.com/airbytehq/airbyte/pull/49579) | Update dependencies | +| 0.3.2 | 2024-12-12 | [47873](https://github.com/airbytehq/airbyte/pull/47873) | Update dependencies | | 0.3.1 | 2024-10-28 | [47636](https://github.com/airbytehq/airbyte/pull/47636) | Update dependencies | | 0.3.0 | 2024-08-19 | [44430](https://github.com/airbytehq/airbyte/pull/44430) | Refactor connector to manifest-only format | | 0.2.0 | 2024-08-19 | [44180](https://github.com/airbytehq/airbyte/pull/44180) | Add `time_tracking`, `time_tracking_tags`, `team_goals`, `space_tags`, `team_custom_fields`, `list_custom_fields`, `list_comments`, Parent ids passed from responses, Add error handlers | diff --git a/docs/integrations/sources/clockify.md b/docs/integrations/sources/clockify.md index abeb2fd9fa4c..62860390b62c 100644 --- a/docs/integrations/sources/clockify.md +++ b/docs/integrations/sources/clockify.md @@ -9,7 +9,11 @@ The Airbyte Source for [Clockify](https://clockify.me) | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | -| 0.4.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | +| 0.4.5 | 2024-12-28 | [50449](https://github.com/airbytehq/airbyte/pull/50449) | Update dependencies | +| 0.4.4 | 2024-12-21 | [50188](https://github.com/airbytehq/airbyte/pull/50188) | Update dependencies | +| 0.4.3 | 2024-12-14 | [49552](https://github.com/airbytehq/airbyte/pull/49552) | Update dependencies | +| 0.4.2 | 2024-12-12 | [47651](https://github.com/airbytehq/airbyte/pull/47651) | Update dependencies | +| 0.4.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.4.0 | 2024-08-15 | [44166](https://github.com/airbytehq/airbyte/pull/44166) | Refactor connector to manifest-only format | | 0.3.13 | 2024-08-10 | [42817](https://github.com/airbytehq/airbyte/pull/42817) | Update dependencies | | 0.3.12 | 2024-07-20 | [42197](https://github.com/airbytehq/airbyte/pull/42197) | Update dependencies | diff --git a/docs/integrations/sources/clockodo.md b/docs/integrations/sources/clockodo.md new file mode 100644 index 000000000000..d4a8497d9152 --- /dev/null +++ b/docs/integrations/sources/clockodo.md @@ -0,0 +1,49 @@ +# Clockodo +The Airbyte connector for Clockodo enables seamless data integration between Clockodo and your preferred data warehouse or destination. This connector allows you to efficiently extract time tracking, project management, and reporting data from Clockodo, providing accurate insights and facilitating informed business decisions. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use. Find it in the 'Personal data' section of your Clockodo account. | | +| `email_address` | `string` | Email Address. Your Clockodo account email address. Find it in your Clockodo account settings. | | +| `external_application` | `string` | External Application Header. Identification of the calling application, including the email address of a technical contact person. Format: [name of application or company];[email address]. | Airbyte | +| `years` | `integer` | Year. | | +| `start_date` | `string` | Start Date. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| projects | id | DefaultPaginator | ✅ | ❌ | +| absences | id | No pagination | ✅ | ❌ | +| customers | id | DefaultPaginator | ✅ | ❌ | +| entries | id | DefaultPaginator | ✅ | ✅ | +| holidays_carry | id | No pagination | ✅ | ❌ | +| holidays_quota | id | No pagination | ✅ | ❌ | +| lumpsum_services | id | No pagination | ✅ | ❌ | +| non_business_days | id | No pagination | ✅ | ❌ | +| overtime_carry | id | No pagination | ✅ | ❌ | +| services | id | DefaultPaginator | ✅ | ❌ | +| surcharges | id | No pagination | ✅ | ❌ | +| target_hours | id | No pagination | ✅ | ❌ | +| teams | id | No pagination | ✅ | ❌ | +| user_reports | | No pagination | ✅ | ❌ | +| users | id | No pagination | ✅ | ❌ | +| customers_projects | user_id | No pagination | ✅ | ❌ | +| access_services | user_id | No pagination | ✅ | ❌ | +| work_times | | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50547](https://github.com/airbytehq/airbyte/pull/50547) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50067](https://github.com/airbytehq/airbyte/pull/50067) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49482](https://github.com/airbytehq/airbyte/pull/49482) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49163](https://github.com/airbytehq/airbyte/pull/49163) | Update dependencies | +| 0.0.1 | 2024-10-28 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/close-com.md b/docs/integrations/sources/close-com.md index a34c20cc4deb..2d9a71839e97 100644 --- a/docs/integrations/sources/close-com.md +++ b/docs/integrations/sources/close-com.md @@ -109,6 +109,11 @@ The Close.com connector is subject to rate limits. For more information on this | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :----------------------------------------------------------------------------------------------------- | +| 0.5.29 | 2025-01-04 | [50920](https://github.com/airbytehq/airbyte/pull/50920) | Update dependencies | +| 0.5.28 | 2024-12-28 | [50532](https://github.com/airbytehq/airbyte/pull/50532) | Update dependencies | +| 0.5.27 | 2024-12-21 | [50065](https://github.com/airbytehq/airbyte/pull/50065) | Update dependencies | +| 0.5.26 | 2024-12-14 | [48918](https://github.com/airbytehq/airbyte/pull/48918) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.5.25 | 2024-11-04 | [47933](https://github.com/airbytehq/airbyte/pull/47933) | Update dependencies | | 0.5.24 | 2024-10-21 | [47047](https://github.com/airbytehq/airbyte/pull/47047) | Update dependencies | | 0.5.23 | 2024-10-12 | [46803](https://github.com/airbytehq/airbyte/pull/46803) | Update dependencies | | 0.5.22 | 2024-10-05 | [46449](https://github.com/airbytehq/airbyte/pull/46449) | Update dependencies | diff --git a/docs/integrations/sources/cloudbeds.md b/docs/integrations/sources/cloudbeds.md new file mode 100644 index 000000000000..b7b520ac600c --- /dev/null +++ b/docs/integrations/sources/cloudbeds.md @@ -0,0 +1,39 @@ +# Cloudbeds +This is Cloudbeds source that ingests data from the Cloudbeds API. + +Cloudbeds is an unified hospitality platform https://cloudbeds.com + +In order to use this source, you must first create a cloudbeds account. Once logged in, navigate to the API credentials page for your property by clicking Account > Apps & Marketplace in the upper right corner. Use the menu on the top to navigate to the API Credentials Page. Click the New Credentials button, fill in the details and click on Create. This will create an application, then click on the API Key and provide all the required scopes as needed. + +You can learn more about the API here https://hotels.cloudbeds.com/api/v1.2/docs/ + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| guests | guestID | DefaultPaginator | ✅ | ❌ | +| hotels | | DefaultPaginator | ✅ | ❌ | +| rooms | propertyID | DefaultPaginator | ✅ | ❌ | +| reservations | reservationID | DefaultPaginator | ✅ | ❌ | +| transactions | transactionID | DefaultPaginator | ✅ | ❌ | +| packages | itemID | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50555](https://github.com/airbytehq/airbyte/pull/50555) | Update dependencies | +| 0.0.4 | 2024-12-21 | [49992](https://github.com/airbytehq/airbyte/pull/49992) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49487](https://github.com/airbytehq/airbyte/pull/49487) | Update dependencies | +| 0.0.2 | 2024-12-12 | [48925](https://github.com/airbytehq/airbyte/pull/48925) | Update dependencies | +| 0.0.1 | 2024-10-31 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | + +
diff --git a/docs/integrations/sources/coassemble.md b/docs/integrations/sources/coassemble.md index e7744cd47649..f064e8edc1f5 100644 --- a/docs/integrations/sources/coassemble.md +++ b/docs/integrations/sources/coassemble.md @@ -26,6 +26,11 @@ See the [Coassemble API docs](https://developers.coassemble.com/get-started) for | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.7 | 2024-12-28 | [50570](https://github.com/airbytehq/airbyte/pull/50570) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50025](https://github.com/airbytehq/airbyte/pull/50025) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49483](https://github.com/airbytehq/airbyte/pull/49483) | Update dependencies | +| 0.0.4 | 2024-12-12 | [48926](https://github.com/airbytehq/airbyte/pull/48926) | Update dependencies | +| 0.0.3 | 2024-11-04 | [47865](https://github.com/airbytehq/airbyte/pull/47865) | Update dependencies | | 0.0.2 | 2024-10-28 | [47526](https://github.com/airbytehq/airbyte/pull/47526) | Update dependencies | | 0.0.1 | 2024-09-19 | | Initial release by [@topefolorunso](https://github.com/topefolorunso) via Connector Builder | diff --git a/docs/integrations/sources/cockroachdb.md b/docs/integrations/sources/cockroachdb.md index 31b83d5561fc..c8592de210c9 100644 --- a/docs/integrations/sources/cockroachdb.md +++ b/docs/integrations/sources/cockroachdb.md @@ -98,12 +98,13 @@ Your database user should now be ready for use with Airbyte. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- | -| 0.2.2 | 2024-02-13 | [35234](https://github.com/airbytehq/airbyte/pull/35234) | Adopt CDK 0.20.4 | -| 0.2.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | -| 0.2.0 | 2023-12-18 | [33485](https://github.com/airbytehq/airbyte/pull/33485) | Removed LEGACY state | -| 0.1.22 | 2023-03-22 | [20760](https://github.com/airbytehq/airbyte/pull/20760) | Removed redundant date-time datatypes formatting | -| 0.1.21 | 2023-03-14 | [24000](https://github.com/airbytehq/airbyte/pull/24000) | Removed check method call on read. | -| 0.1.20 | 2023-03-06 | [23455](https://github.com/airbytehq/airbyte/pull/23455) | For network isolation, source connector accepts a list of hosts it is allowed to connect | +| 0.2.3 | 2024-12-18 | [49915](https://github.com/airbytehq/airbyte/pull/49915) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.2.2 | 2024-02-13 | [35234](https://github.com/airbytehq/airbyte/pull/35234) | Adopt CDK 0.20.4 | +| 0.2.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | +| 0.2.0 | 2023-12-18 | [33485](https://github.com/airbytehq/airbyte/pull/33485) | Removed LEGACY state | +| 0.1.22 | 2023-03-22 | [20760](https://github.com/airbytehq/airbyte/pull/20760) | Removed redundant date-time datatypes formatting | +| 0.1.21 | 2023-03-14 | [24000](https://github.com/airbytehq/airbyte/pull/24000) | Removed check method call on read. | +| 0.1.20 | 2023-03-06 | [23455](https://github.com/airbytehq/airbyte/pull/23455) | For network isolation, source connector accepts a list of hosts it is allowed to connect | | 0.1.19 | 2022-12-14 | [20436](https://github.com/airbytehq/airbyte/pull/20346) | Consolidate date/time values mapping for JDBC sources | | | 2022-10-13 | [15535](https://github.com/airbytehq/airbyte/pull/16238) | Update incremental query to avoid data missing when new data is inserted at the same time as a sync starts under non-CDC incremental mode | | 0.1.18 | 2022-09-01 | [16394](https://github.com/airbytehq/airbyte/pull/16394) | Added custom jdbc properties field | @@ -122,4 +123,4 @@ Your database user should now be ready for use with Airbyte. | 0.1.3 | 2021-10-10 | [7819](https://github.com/airbytehq/airbyte/pull/7819) | Fixed Datatype errors during Cockroach DB parsing | | 0.1.2 | 2021-08-13 | [4699](https://github.com/airbytehq/airbyte/pull/4699) | Added json config validator | - \ No newline at end of file + diff --git a/docs/integrations/sources/coda.md b/docs/integrations/sources/coda.md index 6f599cb05070..4ed4be6d55c0 100644 --- a/docs/integrations/sources/coda.md +++ b/docs/integrations/sources/coda.md @@ -67,6 +67,11 @@ The Coda source connector supports the following [sync modes](https://docs.airby | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- |:------------------------------------------------------------------------------------------------------------| +| 1.3.8 | 2024-12-28 | [50550](https://github.com/airbytehq/airbyte/pull/50550) | Update dependencies | +| 1.3.7 | 2024-12-21 | [50045](https://github.com/airbytehq/airbyte/pull/50045) | Update dependencies | +| 1.3.6 | 2024-12-14 | [49485](https://github.com/airbytehq/airbyte/pull/49485) | Update dependencies | +| 1.3.5 | 2024-12-12 | [49193](https://github.com/airbytehq/airbyte/pull/49193) | Update dependencies | +| 1.3.4 | 2024-12-11 | [48304](https://github.com/airbytehq/airbyte/pull/48304) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 1.3.3 | 2024-10-29 | [47731](https://github.com/airbytehq/airbyte/pull/47731) | Update dependencies | | 1.3.2 | 2024-10-28 | [47517](https://github.com/airbytehq/airbyte/pull/47517) | Update dependencies | | 1.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/codefresh.md b/docs/integrations/sources/codefresh.md index b8b37fdfc7d8..b80112a935d3 100644 --- a/docs/integrations/sources/codefresh.md +++ b/docs/integrations/sources/codefresh.md @@ -36,6 +36,11 @@ It provides streams like agents, builds, audit, analytics etc. | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50559](https://github.com/airbytehq/airbyte/pull/50559) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50051](https://github.com/airbytehq/airbyte/pull/50051) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49486](https://github.com/airbytehq/airbyte/pull/49486) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49182](https://github.com/airbytehq/airbyte/pull/49182) | Update dependencies | +| 0.0.3 | 2024-11-04 | [48183](https://github.com/airbytehq/airbyte/pull/48183) | Update dependencies | | 0.0.2 | 2024-10-28 | [47574](https://github.com/airbytehq/airbyte/pull/47574) | Update dependencies | | 0.0.1 | 2024-10-21 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | diff --git a/docs/integrations/sources/coin-api.md b/docs/integrations/sources/coin-api.md index 0eee90599a3c..86d4db70101c 100644 --- a/docs/integrations/sources/coin-api.md +++ b/docs/integrations/sources/coin-api.md @@ -53,6 +53,9 @@ The following fields are required fields for the connector to work: | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :------------------------------------------------------------------------------------------ | +| 0.3.5 | 2024-12-28 | [50027](https://github.com/airbytehq/airbyte/pull/50027) | Update dependencies | +| 0.3.4 | 2024-12-14 | [49503](https://github.com/airbytehq/airbyte/pull/49503) | Update dependencies | +| 0.3.3 | 2024-12-12 | [49150](https://github.com/airbytehq/airbyte/pull/49150) | Update dependencies | | 0.3.2 | 2024-10-29 | [47739](https://github.com/airbytehq/airbyte/pull/47739) | Update dependencies | | 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.3.0 | 2024-08-15 | [44164](https://github.com/airbytehq/airbyte/pull/44164) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/coingecko-coins.md b/docs/integrations/sources/coingecko-coins.md index 545b1105d933..5dee32eeb312 100644 --- a/docs/integrations/sources/coingecko-coins.md +++ b/docs/integrations/sources/coingecko-coins.md @@ -52,6 +52,13 @@ The following fields are required fields for the connector to work: | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :-------------------------------------------- | +| 0.2.9 | 2024-12-28 | [50572](https://github.com/airbytehq/airbyte/pull/50572) | Update dependencies | +| 0.2.8 | 2024-12-21 | [49995](https://github.com/airbytehq/airbyte/pull/49995) | Update dependencies | +| 0.2.7 | 2024-12-14 | [49527](https://github.com/airbytehq/airbyte/pull/49527) | Update dependencies | +| 0.2.6 | 2024-12-12 | [49208](https://github.com/airbytehq/airbyte/pull/49208) | Update dependencies | +| 0.2.5 | 2024-12-11 | [48937](https://github.com/airbytehq/airbyte/pull/48937) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.4 | 2024-11-05 | [48363](https://github.com/airbytehq/airbyte/pull/48363) | Revert to source-declarative-manifest v5.17.0 | +| 0.2.3 | 2024-11-05 | [48330](https://github.com/airbytehq/airbyte/pull/48330) | Update dependencies | | 0.2.2 | 2024-10-29 | [47804](https://github.com/airbytehq/airbyte/pull/47804) | Update dependencies | | 0.2.1 | 2024-10-28 | [47559](https://github.com/airbytehq/airbyte/pull/47559) | Update dependencies | | 0.2.0 | 2024-08-22 | [44565](https://github.com/airbytehq/airbyte/pull/44565) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/commcare.md b/docs/integrations/sources/commcare.md index 810123387273..b6756884dda5 100644 --- a/docs/integrations/sources/commcare.md +++ b/docs/integrations/sources/commcare.md @@ -40,6 +40,10 @@ The Commcare source connector supports the following streams: | Version | Date | Pull Request | Subject | | ------- | ---------- | -------------------------------------------------------- | ------------------------- | +| 0.1.26 | 2024-12-28 | [50509](https://github.com/airbytehq/airbyte/pull/50509) | Update dependencies | +| 0.1.25 | 2024-12-21 | [50064](https://github.com/airbytehq/airbyte/pull/50064) | Update dependencies | +| 0.1.24 | 2024-12-14 | [49172](https://github.com/airbytehq/airbyte/pull/49172) | Update dependencies | +| 0.1.23 | 2024-11-25 | [48645](https://github.com/airbytehq/airbyte/pull/48645) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.1.22 | 2024-10-29 | [47767](https://github.com/airbytehq/airbyte/pull/47767) | Update dependencies | | 0.1.21 | 2024-10-28 | [46795](https://github.com/airbytehq/airbyte/pull/46795) | Update dependencies | | 0.1.20 | 2024-10-05 | [46413](https://github.com/airbytehq/airbyte/pull/46413) | Update dependencies | diff --git a/docs/integrations/sources/commercetools.md b/docs/integrations/sources/commercetools.md index ee879e82ef3e..b32b56ae26ad 100644 --- a/docs/integrations/sources/commercetools.md +++ b/docs/integrations/sources/commercetools.md @@ -52,6 +52,11 @@ Commercetools has some [rate limit restrictions](https://docs.commercetools.com/ | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------ | +| 0.2.27 | 2025-01-04 | [50918](https://github.com/airbytehq/airbyte/pull/50918) | Update dependencies | +| 0.2.26 | 2024-12-28 | [50516](https://github.com/airbytehq/airbyte/pull/50516) | Update dependencies | +| 0.2.25 | 2024-12-21 | [50032](https://github.com/airbytehq/airbyte/pull/50032) | Update dependencies | +| 0.2.24 | 2024-12-12 | [49171](https://github.com/airbytehq/airbyte/pull/49171) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.23 | 2024-11-04 | [48186](https://github.com/airbytehq/airbyte/pull/48186) | Update dependencies | | 0.2.22 | 2024-10-29 | [47859](https://github.com/airbytehq/airbyte/pull/47859) | Update dependencies | | 0.2.21 | 2024-10-28 | [47112](https://github.com/airbytehq/airbyte/pull/47112) | Update dependencies | | 0.2.20 | 2024-10-12 | [46779](https://github.com/airbytehq/airbyte/pull/46779) | Update dependencies | diff --git a/docs/integrations/sources/concord.md b/docs/integrations/sources/concord.md index 9ac539a61060..687b7d88fc13 100644 --- a/docs/integrations/sources/concord.md +++ b/docs/integrations/sources/concord.md @@ -32,6 +32,12 @@ The API is accessible from two environments, sandbox and production. You can lea | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50510](https://github.com/airbytehq/airbyte/pull/50510) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50057](https://github.com/airbytehq/airbyte/pull/50057) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49475](https://github.com/airbytehq/airbyte/pull/49475) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49160](https://github.com/airbytehq/airbyte/pull/49160) | Update dependencies | +| 0.0.3 | 2024-12-11 | [48913](https://github.com/airbytehq/airbyte/pull/48913) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.2 | 2024-11-04 | [48215](https://github.com/airbytehq/airbyte/pull/48215) | Update dependencies | | 0.0.1 | 2024-10-16 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | diff --git a/docs/integrations/sources/configcat.md b/docs/integrations/sources/configcat.md index d0f8de641565..a518f6748fd7 100644 --- a/docs/integrations/sources/configcat.md +++ b/docs/integrations/sources/configcat.md @@ -37,6 +37,10 @@ Configcat APIs are under rate limits for the number of API calls allowed per API | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :------------------------------------------ | +| 0.2.6 | 2024-12-28 | [50591](https://github.com/airbytehq/airbyte/pull/50591) | Update dependencies | +| 0.2.5 | 2024-12-21 | [49996](https://github.com/airbytehq/airbyte/pull/49996) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49491](https://github.com/airbytehq/airbyte/pull/49491) | Update dependencies | +| 0.2.3 | 2024-12-12 | [48256](https://github.com/airbytehq/airbyte/pull/48256) | Update dependencies | | 0.2.2 | 2024-10-28 | [47465](https://github.com/airbytehq/airbyte/pull/47465) | Update dependencies | | 0.2.1 | 2024-10-21 | [47194](https://github.com/airbytehq/airbyte/pull/47194) | Update dependencies | | 0.2.0 | 2024-08-23 | [44594](https://github.com/airbytehq/airbyte/pull/44594) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/confluence.md b/docs/integrations/sources/confluence.md index 78762cac1ddb..e59eee30d38c 100644 --- a/docs/integrations/sources/confluence.md +++ b/docs/integrations/sources/confluence.md @@ -63,6 +63,9 @@ The Confluence connector should not run into Confluence API limitations under no | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.3.5 | 2024-12-28 | [50564](https://github.com/airbytehq/airbyte/pull/50564) | Update dependencies | +| 0.3.4 | 2024-12-21 | [49541](https://github.com/airbytehq/airbyte/pull/49541) | Update dependencies | +| 0.3.3 | 2024-12-12 | [48263](https://github.com/airbytehq/airbyte/pull/48263) | Update dependencies | | 0.3.2 | 2024-10-28 | [47553](https://github.com/airbytehq/airbyte/pull/47553) | Update dependencies | | 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.3.0 | 2024-08-15 | [44162](https://github.com/airbytehq/airbyte/pull/44162) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/convertkit.md b/docs/integrations/sources/convertkit.md index 8dfb75302ce3..010ce8161d5f 100644 --- a/docs/integrations/sources/convertkit.md +++ b/docs/integrations/sources/convertkit.md @@ -36,6 +36,11 @@ The connector has a rate limit of no more than 120 requests over a rolling 60 se | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------- | +| 0.2.8 | 2024-12-28 | [50522](https://github.com/airbytehq/airbyte/pull/50522) | Update dependencies | +| 0.2.7 | 2024-12-21 | [50066](https://github.com/airbytehq/airbyte/pull/50066) | Update dependencies | +| 0.2.6 | 2024-12-14 | [49510](https://github.com/airbytehq/airbyte/pull/49510) | Update dependencies | +| 0.2.5 | 2024-12-12 | [48958](https://github.com/airbytehq/airbyte/pull/48958) | Update dependencies | +| 0.2.4 | 2024-11-04 | [48217](https://github.com/airbytehq/airbyte/pull/48217) | Update dependencies | | 0.2.3 | 2024-10-29 | [47764](https://github.com/airbytehq/airbyte/pull/47764) | Update dependencies | | 0.2.2 | 2024-10-28 | [47619](https://github.com/airbytehq/airbyte/pull/47619) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/convex.md b/docs/integrations/sources/convex.md index 106c7c8eb8c5..7602d7281148 100644 --- a/docs/integrations/sources/convex.md +++ b/docs/integrations/sources/convex.md @@ -75,6 +75,10 @@ In the Data tab, you should see the tables and a sample of the data that will be | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :--------------------------------------------------------------- | +| 0.4.25 | 2024-12-28 | [50531](https://github.com/airbytehq/airbyte/pull/50531) | Update dependencies | +| 0.4.24 | 2024-12-21 | [50013](https://github.com/airbytehq/airbyte/pull/50013) | Update dependencies | +| 0.4.23 | 2024-12-14 | [49179](https://github.com/airbytehq/airbyte/pull/49179) | Update dependencies | +| 0.4.22 | 2024-11-25 | [48680](https://github.com/airbytehq/airbyte/pull/48680) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.4.21 | 2024-10-29 | [47081](https://github.com/airbytehq/airbyte/pull/47081) | Update dependencies | | 0.4.20 | 2024-10-12 | [46480](https://github.com/airbytehq/airbyte/pull/46480) | Update dependencies | | 0.4.19 | 2024-09-28 | [46208](https://github.com/airbytehq/airbyte/pull/46208) | Update dependencies | diff --git a/docs/integrations/sources/copper.md b/docs/integrations/sources/copper.md index 6d8b1cebb0c7..57e6530ad479 100644 --- a/docs/integrations/sources/copper.md +++ b/docs/integrations/sources/copper.md @@ -44,6 +44,7 @@ The Copper source connector supports the following [sync modes](https://docs.air | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.4.3 | 2024-11-04 | [48146](https://github.com/airbytehq/airbyte/pull/48146) | Update dependencies | | 0.4.2 | 2024-10-28 | [47660](https://github.com/airbytehq/airbyte/pull/47660) | Update dependencies | | 0.4.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.4.0 | 2024-08-15 | [44159](https://github.com/airbytehq/airbyte/pull/44159) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/countercyclical.md b/docs/integrations/sources/countercyclical.md index 7c4ee6be62cb..996c190158f2 100644 --- a/docs/integrations/sources/countercyclical.md +++ b/docs/integrations/sources/countercyclical.md @@ -21,6 +21,11 @@ Countercyclical is the fully end-to-end financial intelligence platform designed | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50539](https://github.com/airbytehq/airbyte/pull/50539) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50061](https://github.com/airbytehq/airbyte/pull/50061) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49500](https://github.com/airbytehq/airbyte/pull/49500) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49152](https://github.com/airbytehq/airbyte/pull/49152) | Update dependencies | +| 0.0.3 | 2024-11-04 | [48283](https://github.com/airbytehq/airbyte/pull/48283) | Update dependencies | | 0.0.2 | 2024-10-28 | [47557](https://github.com/airbytehq/airbyte/pull/47557) | Update dependencies | | 0.0.1 | 2024-10-06 | | Initial release by [@williamleiby](https://github.com/williamleiby) via Connector Builder | diff --git a/docs/integrations/sources/customer-io.md b/docs/integrations/sources/customer-io.md index 4cf8ec61555f..325308d19783 100644 --- a/docs/integrations/sources/customer-io.md +++ b/docs/integrations/sources/customer-io.md @@ -47,6 +47,11 @@ Please follow the [their documentation for generating an App API Key](https://cu | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------------- | :------------------------- | +| 0.3.7 | 2025-01-04 | [50582](https://github.com/airbytehq/airbyte/pull/50582) | Update dependencies | +| 0.3.6 | 2024-12-21 | [49999](https://github.com/airbytehq/airbyte/pull/49999) | Update dependencies | +| 0.3.5 | 2024-12-14 | [49490](https://github.com/airbytehq/airbyte/pull/49490) | Update dependencies | +| 0.3.4 | 2024-12-12 | [48923](https://github.com/airbytehq/airbyte/pull/48923) | Update dependencies | +| 0.3.3 | 2024-11-04 | [48225](https://github.com/airbytehq/airbyte/pull/48225) | Update dependencies | | 0.3.2 | 2024-10-28 | [47464](https://github.com/airbytehq/airbyte/pull/47464) | Update dependencies | | 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.3.0 | 2024-08-15 | [44158](https://github.com/airbytehq/airbyte/pull/44158) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/datadog-migrations.md b/docs/integrations/sources/datadog-migrations.md index 8e062936404e..dcabd2a22c0d 100644 --- a/docs/integrations/sources/datadog-migrations.md +++ b/docs/integrations/sources/datadog-migrations.md @@ -1,5 +1,10 @@ # Datadog Migration Guide +## Upgrading to 2.0.0 + +On December 13, 2024, Datadog is removing support for the `is_read_only` attribute in the Dashboards API’s. Hence, the `is_read_only` attribute will no longer be available in the dashboards stream response. Upgrade and resync to reset the schema and update the records. + ## Upgrading to 1.0.0 Starting 1.0, Datadog source will apply start and end dates to sync data incrementally. When upgrading, take a minute to set start and end date config options. + diff --git a/docs/integrations/sources/datadog.md b/docs/integrations/sources/datadog.md index aecf466199d6..e5e51a548b75 100644 --- a/docs/integrations/sources/datadog.md +++ b/docs/integrations/sources/datadog.md @@ -76,6 +76,11 @@ The Datadog source connector supports the following [sync modes](https://docs.ai | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:-----------------------------------------------------------------------------| +| 2.0.4 | 2024-12-28 | [50567](https://github.com/airbytehq/airbyte/pull/50567) | Update dependencies | +| 2.0.3 | 2024-12-21 | [49988](https://github.com/airbytehq/airbyte/pull/49988) | Update dependencies | +| 2.0.2 | 2024-12-14 | [49472](https://github.com/airbytehq/airbyte/pull/49472) | Update dependencies | +| 2.0.1 | 2024-12-12 | [48300](https://github.com/airbytehq/airbyte/pull/48300) | Update dependencies | +| 2.0.0 | 2024-12-06 | [48833](https://github.com/airbytehq/airbyte/pull/48833) | Remove `is_read_only` parameter from dashboards stream schema | | 1.1.1 | 2024-10-28 | [46502](https://github.com/airbytehq/airbyte/pull/46502) | Update dependencies | | 1.1.0 | 2023-10-04 | [46387](https://github.com/airbytehq/airbyte/pull/46387) | Migrate to manifest only | | 1.0.6 | 2024-09-28 | [46190](https://github.com/airbytehq/airbyte/pull/46190) | Update dependencies | diff --git a/docs/integrations/sources/datascope.md b/docs/integrations/sources/datascope.md index 3becaf55d61e..ebff4a068eea 100644 --- a/docs/integrations/sources/datascope.md +++ b/docs/integrations/sources/datascope.md @@ -64,6 +64,11 @@ GET https://www.mydatascope.com/api/external/locations | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :------------- | +| 0.2.8 | 2024-12-28 | [50569](https://github.com/airbytehq/airbyte/pull/50569) | Update dependencies | +| 0.2.7 | 2024-12-21 | [49542](https://github.com/airbytehq/airbyte/pull/49542) | Update dependencies | +| 0.2.6 | 2024-12-12 | [49161](https://github.com/airbytehq/airbyte/pull/49161) | Update dependencies | +| 0.2.5 | 2024-11-05 | [48357](https://github.com/airbytehq/airbyte/pull/48357) | Revert to source-declarative-manifest v5.17.0 | +| 0.2.4 | 2024-11-05 | [48336](https://github.com/airbytehq/airbyte/pull/48336) | Update dependencies | | 0.2.3 | 2024-10-29 | [47857](https://github.com/airbytehq/airbyte/pull/47857) | Update dependencies | | 0.2.2 | 2024-10-28 | [47451](https://github.com/airbytehq/airbyte/pull/47451) | Update dependencies | | 0.2.1 | 2024-10-21 | [47206](https://github.com/airbytehq/airbyte/pull/47206) | Update dependencies | diff --git a/docs/integrations/sources/db2.md b/docs/integrations/sources/db2.md index ff0170ea828f..d8fa5c0b2959 100644 --- a/docs/integrations/sources/db2.md +++ b/docs/integrations/sources/db2.md @@ -63,12 +63,13 @@ You can also enter your own password for the keystore, but if you don't, the pas | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------------------------------------------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------- | -------- | -| 0.2.2 | 2024-02-13 | [35233](https://github.com/airbytehq/airbyte/pull/35233) | Adopt CDK 0.20.4 | -| 0.2.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | -| 0.2.0 | 2023-12-18 | [33485](https://github.com/airbytehq/airbyte/pull/33485) | Remove LEGACY state | -| 0.1.20 | 2023-06-20 | [27212](https://github.com/airbytehq/airbyte/pull/27212) | Fix silent exception swallowing in StreamingJdbcDatabase | -| 0.1.19 | 2023-03-22 | [20760](https://github.com/airbytehq/airbyte/pull/20760) | Removed redundant date-time datatypes formatting | -| 0.1.18 | 2023-03-06 | [23455](https://github.com/airbytehq/airbyte/pull/23455) | For network isolation, source connector accepts a list of hosts it is allowed to connect to | +| 0.2.3 | 2024-12-18 | [49909](https://github.com/airbytehq/airbyte/pull/49909) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.2.2 | 2024-02-13 | [35233](https://github.com/airbytehq/airbyte/pull/35233) | Adopt CDK 0.20.4 | +| 0.2.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | +| 0.2.0 | 2023-12-18 | [33485](https://github.com/airbytehq/airbyte/pull/33485) | Remove LEGACY state | +| 0.1.20 | 2023-06-20 | [27212](https://github.com/airbytehq/airbyte/pull/27212) | Fix silent exception swallowing in StreamingJdbcDatabase | +| 0.1.19 | 2023-03-22 | [20760](https://github.com/airbytehq/airbyte/pull/20760) | Removed redundant date-time datatypes formatting | +| 0.1.18 | 2023-03-06 | [23455](https://github.com/airbytehq/airbyte/pull/23455) | For network isolation, source connector accepts a list of hosts it is allowed to connect to | | 0.1.17 | 2022-12-14 | [20436](https://github.com/airbytehq/airbyte/pull/20346) | Consolidate date/time values mapping for JDBC sources | | | 2022-10-13 | [15535](https://github.com/airbytehq/airbyte/pull/16238) | Update incremental query to avoid data missing when new data is inserted at the same time as a sync starts under non-CDC incremental mode | | 0.1.16 | 2022-09-06 | [16354](https://github.com/airbytehq/airbyte/pull/16354) | Add custom JDBC params | @@ -89,4 +90,4 @@ You can also enter your own password for the keystore, but if you don't, the pas | 0.1.1 | 2021-08-13 | [4699](https://github.com/airbytehq/airbyte/pull/4699) | Added json config validator | | 0.1.0 | 2021-06-22 | [4197](https://github.com/airbytehq/airbyte/pull/4197) | New Source: IBM DB2 | - \ No newline at end of file + diff --git a/docs/integrations/sources/dbt.md b/docs/integrations/sources/dbt.md index 497bd86a6ad1..0645b20e600f 100644 --- a/docs/integrations/sources/dbt.md +++ b/docs/integrations/sources/dbt.md @@ -26,6 +26,10 @@ DBT Source Connector provides streams with your DBT projects, repositories, user | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.6 | 2024-12-28 | [50556](https://github.com/airbytehq/airbyte/pull/50556) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50035](https://github.com/airbytehq/airbyte/pull/50035) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49499](https://github.com/airbytehq/airbyte/pull/49499) | Update dependencies | +| 0.0.3 | 2024-12-12 | [47748](https://github.com/airbytehq/airbyte/pull/47748) | Update dependencies | | 0.0.2 | 2024-10-28 | [47460](https://github.com/airbytehq/airbyte/pull/47460) | Update dependencies | | 0.0.1 | 2024-08-22 | | Initial release by natikgadzhi via Connector Builder | diff --git a/docs/integrations/sources/delighted.md b/docs/integrations/sources/delighted.md index 1354c9ee92d3..3a6aa7c3a91f 100644 --- a/docs/integrations/sources/delighted.md +++ b/docs/integrations/sources/delighted.md @@ -54,8 +54,12 @@ This source is capable of syncing the following core streams: | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :--------------------------------------------------------------------------------------------------- | -| 0.4.0 | 2024-09-08 | [44601](https://github.com/airbytehq/airbyte/pull/44601) | Update macro for end_date | -| 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | +| 0.4.4 | 2024-12-28 | [50562](https://github.com/airbytehq/airbyte/pull/50562) | Update dependencies | +| 0.4.3 | 2024-12-21 | [50015](https://github.com/airbytehq/airbyte/pull/50015) | Update dependencies | +| 0.4.2 | 2024-12-14 | [49493](https://github.com/airbytehq/airbyte/pull/49493) | Update dependencies | +| 0.4.1 | 2024-12-12 | [47844](https://github.com/airbytehq/airbyte/pull/47844) | Update dependencies | +| 0.4.0 | 2024-09-08 | [44601](https://github.com/airbytehq/airbyte/pull/44601) | Update macro for end_date | +| 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.3.0 | 2024-08-15 | [44156](https://github.com/airbytehq/airbyte/pull/44156) | Refactor connector to manifest-only format | | 0.2.19 | 2024-08-10 | [43583](https://github.com/airbytehq/airbyte/pull/43583) | Update dependencies | | 0.2.18 | 2024-08-03 | [43169](https://github.com/airbytehq/airbyte/pull/43169) | Update dependencies | diff --git a/docs/integrations/sources/deputy.md b/docs/integrations/sources/deputy.md new file mode 100644 index 000000000000..3e44c4fcc073 --- /dev/null +++ b/docs/integrations/sources/deputy.md @@ -0,0 +1,52 @@ +# Deputy +This is the Deputy source that ingests data from the Deputy API. + +Deputy is a software that simplifies employee scheduling, timesheets and HR in one place https://www.deputy.com/ + +In order to use this source you must first create an account on Deputy. +Once logged in, your Deputy install will have a specific URL in the structure of `https://[installname].[geo].deputy.com` - This is the same URL that will be the base API url . + +To obtain your bearer token to use the API, follow the steps shown here https://developer.deputy.com/deputy-docs/docs/the-hello-world-of-deputy +This will have you create an oauth application and create an access token. Enter the access token in the input field. + +You can learn more about the API here https://developer.deputy.com/deputy-docs/reference/getlocations + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `base_url` | `string` | Base URL. The base url for your deputy account to make API requests. Example: `https://my890.as.deputy.com` | | +| `api_key` | `string` | API Key. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| locations | Id | No pagination | ✅ | ❌ | +| employees | Id | No pagination | ✅ | ❌ | +| award_lists | AwardCode | No pagination | ✅ | ❌ | +| departments | Id | No pagination | ✅ | ❌ | +| timesheets | Id | No pagination | ✅ | ❌ | +| tasks | Id | No pagination | ✅ | ❌ | +| news_feed | Id | No pagination | ✅ | ❌ | +| addresses | Id | No pagination | ✅ | ❌ | +| categories | Id | No pagination | ✅ | ❌ | +| comments | Id | No pagination | ✅ | ❌ | +| company_periods | Id | No pagination | ✅ | ❌ | +| employee_agreements | Id | No pagination | ✅ | ❌ | +| employee | Id | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2025-01-04 | [50585](https://github.com/airbytehq/airbyte/pull/50585) | Update dependencies | +| 0.0.5 | 2024-12-21 | [49991](https://github.com/airbytehq/airbyte/pull/49991) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49534](https://github.com/airbytehq/airbyte/pull/49534) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49170](https://github.com/airbytehq/airbyte/pull/49170) | Update dependencies | +| 0.0.2 | 2024-12-11 | [48934](https://github.com/airbytehq/airbyte/pull/48934) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-27 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | + +
diff --git a/docs/integrations/sources/dixa.md b/docs/integrations/sources/dixa.md index 4e83e5eb6408..a2342e747e1d 100644 --- a/docs/integrations/sources/dixa.md +++ b/docs/integrations/sources/dixa.md @@ -54,6 +54,10 @@ When using the connector, keep in mind that increasing the `batch_size` paramete | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :-------------------------------------------------------------------- | +| 0.4.4 | 2024-12-28 | [50546](https://github.com/airbytehq/airbyte/pull/50546) | Update dependencies | +| 0.4.3 | 2024-12-21 | [50028](https://github.com/airbytehq/airbyte/pull/50028) | Update dependencies | +| 0.4.2 | 2024-12-14 | [49497](https://github.com/airbytehq/airbyte/pull/49497) | Update dependencies | +| 0.4.1 | 2024-12-12 | [49149](https://github.com/airbytehq/airbyte/pull/49149) | Update dependencies | | 0.4.0 | 2024-08-27 | [44818](https://github.com/airbytehq/airbyte/pull/44818) | Refactor connector to manifest-only format | | 0.3.14 | 2024-08-24 | [44666](https://github.com/airbytehq/airbyte/pull/44666) | Update dependencies | | 0.3.13 | 2024-08-17 | [44328](https://github.com/airbytehq/airbyte/pull/44328) | Update dependencies | diff --git a/docs/integrations/sources/dockerhub.md b/docs/integrations/sources/dockerhub.md index 81ea85367895..931aee2b4836 100644 --- a/docs/integrations/sources/dockerhub.md +++ b/docs/integrations/sources/dockerhub.md @@ -39,6 +39,11 @@ This connector has been tested for the Airbyte organization, which has 266 repos | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.3.8 | 2024-12-28 | [50541](https://github.com/airbytehq/airbyte/pull/50541) | Update dependencies | +| 0.3.7 | 2024-12-21 | [50011](https://github.com/airbytehq/airbyte/pull/50011) | Update dependencies | +| 0.3.6 | 2024-12-14 | [49515](https://github.com/airbytehq/airbyte/pull/49515) | Update dependencies | +| 0.3.5 | 2024-12-12 | [49151](https://github.com/airbytehq/airbyte/pull/49151) | Update dependencies | +| 0.3.4 | 2024-12-11 | [48306](https://github.com/airbytehq/airbyte/pull/48306) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.3.3 | 2024-10-29 | [47826](https://github.com/airbytehq/airbyte/pull/47826) | Update dependencies | | 0.3.2 | 2024-10-28 | [47664](https://github.com/airbytehq/airbyte/pull/47664) | Update dependencies | | 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/dremio.md b/docs/integrations/sources/dremio.md index 9cd89bf3ede6..eb68599e3981 100644 --- a/docs/integrations/sources/dremio.md +++ b/docs/integrations/sources/dremio.md @@ -41,6 +41,11 @@ Please read [How to get your APIs credentials](https://docs.dremio.com/software/ | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :----------------- | +| 0.2.7 | 2024-12-28 | [50558](https://github.com/airbytehq/airbyte/pull/50558) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50029](https://github.com/airbytehq/airbyte/pull/50029) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49529](https://github.com/airbytehq/airbyte/pull/49529) | Update dependencies | +| 0.2.4 | 2024-12-12 | [49194](https://github.com/airbytehq/airbyte/pull/49194) | Update dependencies | +| 0.2.3 | 2024-12-11 | [48904](https://github.com/airbytehq/airbyte/pull/48904) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.2 | 2024-10-29 | [47886](https://github.com/airbytehq/airbyte/pull/47886) | Update dependencies | | 0.2.1 | 2024-10-28 | [47633](https://github.com/airbytehq/airbyte/pull/47633) | Update dependencies | | 0.2.0 | 2024-08-19 | [44415](https://github.com/airbytehq/airbyte/pull/44415) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/drift.md b/docs/integrations/sources/drift.md index 811a45fd114b..7b1a399faa8d 100644 --- a/docs/integrations/sources/drift.md +++ b/docs/integrations/sources/drift.md @@ -56,7 +56,12 @@ The Drift connector should not run into Drift API limitations under normal usage | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | -| 0.4.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | +| 0.4.6 | 2024-12-28 | [50540](https://github.com/airbytehq/airbyte/pull/50540) | Update dependencies | +| 0.4.5 | 2024-12-21 | [50007](https://github.com/airbytehq/airbyte/pull/50007) | Update dependencies | +| 0.4.4 | 2024-12-14 | [49484](https://github.com/airbytehq/airbyte/pull/49484) | Update dependencies | +| 0.4.3 | 2024-12-12 | [49159](https://github.com/airbytehq/airbyte/pull/49159) | Update dependencies | +| 0.4.2 | 2024-12-11 | [47674](https://github.com/airbytehq/airbyte/pull/47674) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.4.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.4.0 | 2024-08-15 | [44153](https://github.com/airbytehq/airbyte/pull/44153) | Refactor connector to manifest-only format | | 0.3.17 | 2024-08-12 | [43897](https://github.com/airbytehq/airbyte/pull/43897) | Update dependencies | | 0.3.16 | 2024-08-10 | [43624](https://github.com/airbytehq/airbyte/pull/43624) | Update dependencies | diff --git a/docs/integrations/sources/drip.md b/docs/integrations/sources/drip.md index 8cf091e94954..b4b3da020da5 100644 --- a/docs/integrations/sources/drip.md +++ b/docs/integrations/sources/drip.md @@ -29,6 +29,12 @@ Integrate seamlessly with Drip using this Airbyte connector, enabling smooth dat | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.8 | 2024-12-28 | [50528](https://github.com/airbytehq/airbyte/pull/50528) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50042](https://github.com/airbytehq/airbyte/pull/50042) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49531](https://github.com/airbytehq/airbyte/pull/49531) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49204](https://github.com/airbytehq/airbyte/pull/49204) | Update dependencies | +| 0.0.4 | 2024-12-11 | [48914](https://github.com/airbytehq/airbyte/pull/48914) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.3 | 2024-11-04 | [48311](https://github.com/airbytehq/airbyte/pull/48311) | Update dependencies | | 0.0.2 | 2024-10-28 | [47446](https://github.com/airbytehq/airbyte/pull/47446) | Update dependencies | | 0.0.1 | 2024-10-08 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | diff --git a/docs/integrations/sources/dropbox-sign.md b/docs/integrations/sources/dropbox-sign.md index 79645ef76bfb..03b33084640e 100644 --- a/docs/integrations/sources/dropbox-sign.md +++ b/docs/integrations/sources/dropbox-sign.md @@ -23,6 +23,12 @@ See the [API docs](https://developers.hellosign.com/api/reference/authentication | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.8 | 2024-12-28 | [50553](https://github.com/airbytehq/airbyte/pull/50553) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50021](https://github.com/airbytehq/airbyte/pull/50021) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49528](https://github.com/airbytehq/airbyte/pull/49528) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49181](https://github.com/airbytehq/airbyte/pull/49181) | Update dependencies | +| 0.0.4 | 2024-12-11 | [48946](https://github.com/airbytehq/airbyte/pull/48946) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.3 | 2024-11-04 | [47831](https://github.com/airbytehq/airbyte/pull/47831) | Update dependencies | | 0.0.2 | 2024-10-28 | [47607](https://github.com/airbytehq/airbyte/pull/47607) | Update dependencies | | 0.0.1 | 2024-09-20 | | Initial release by [@topefolorunso](https://github.com/topefolorunso) via Connector Builder | diff --git a/docs/integrations/sources/dynamodb.md b/docs/integrations/sources/dynamodb.md index dd9173879805..3b2037d8bcc6 100644 --- a/docs/integrations/sources/dynamodb.md +++ b/docs/integrations/sources/dynamodb.md @@ -78,10 +78,11 @@ the underlying role executing the container workload in AWS. | Version | Date | Pull Request | Subject | |:--------|:-----------|:----------------------------------------------------------|:---------------------------------------------------------------------| -| 0.3.6 | 2024-07-19 | [41936](https://github.com/airbytehq/airbyte/pull/41936) | Fix incorrect type check for incremental read | -| 0.3.5 | 2024-07-23 | [42433](https://github.com/airbytehq/airbyte/pull/42433) | add PR number | -| 0.3.4 | 2024-07-23 | [*PR_NUMBER_PLACEHOLDER*](https://github.com/airbytehq/airbyte/pull/*PR_NUMBER_PLACEHOLDER*) | fix primary key fetching | -| 0.3.3 | 2024-07-22 | [*PR_NUMBER_PLACEHOLDER*](https://github.com/airbytehq/airbyte/pull/*PR_NUMBER_PLACEHOLDER*) | fix primary key fetching | +| 0.3.7 | 2024-12-18 | [49881](https://github.com/airbytehq/airbyte/pull/49881) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.3.6 | 2024-07-19 | [41936](https://github.com/airbytehq/airbyte/pull/41936) | Fix incorrect type check for incremental read | +| 0.3.5 | 2024-07-23 | [42433](https://github.com/airbytehq/airbyte/pull/42433) | add PR number | +| 0.3.4 | 2024-07-23 | [49881](https://github.com/airbytehq/airbyte/pull/49881) | fix primary key fetching | +| 0.3.3 | 2024-07-22 | [49881](https://github.com/airbytehq/airbyte/pull/49881) | fix primary key fetching | | 0.3.2 | 2024-05-01 | [27045](https://github.com/airbytehq/airbyte/pull/27045) | Fix missing scan permissions | | 0.3.1 | 2024-05-01 | [31935](https://github.com/airbytehq/airbyte/pull/31935) | Fix list more than 100 tables | | 0.3.0 | 2024-04-24 | [37530](https://github.com/airbytehq/airbyte/pull/37530) | Allow role based access | diff --git a/docs/integrations/sources/e-conomic.md b/docs/integrations/sources/e-conomic.md new file mode 100644 index 000000000000..62f23a5ccf1e --- /dev/null +++ b/docs/integrations/sources/e-conomic.md @@ -0,0 +1,61 @@ +# e-conomic +The Airbyte connector for e-conomic enables seamless integration with the e-conomic accounting platform. It allows users to efficiently extract financial data such as invoices, accounts, customers, and transactions from e-conomic and sync it to your preferred data warehouse or analytics tool. This connector simplifies data flow management, facilitating automated data extraction for comprehensive financial reporting and analysis. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `app_secret_token` | `string` | App Secret Token. Your private token that identifies your app. Find it in your e-conomic account settings. | | +| `agreement_grant_token` | `string` | Agreement Grant Token. Token that identifies the grant issued by an agreement, allowing your app to access data. Obtain it from your e-conomic account settings. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| accounts | accountNumber | DefaultPaginator | ✅ | ❌ | +| accounting_years | year | DefaultPaginator | ✅ | ❌ | +| app_roles | roleNumber | DefaultPaginator | ✅ | ❌ | +| currencies | code | DefaultPaginator | ✅ | ❌ | +| customer_groups | customerGroupNumber | DefaultPaginator | ✅ | ❌ | +| customers | customerNumber | DefaultPaginator | ✅ | ❌ | +| departmental_distributions | departmentalDistributionNumber | DefaultPaginator | ✅ | ❌ | +| departments | departmentNumber | DefaultPaginator | ✅ | ❌ | +| employees | employeeNumber | DefaultPaginator | ✅ | ❌ | +| journals | journalNumber | DefaultPaginator | ✅ | ❌ | +| payment_terms | paymentTermsNumber | DefaultPaginator | ✅ | ❌ | +| payment_types | paymentTypeNumber | DefaultPaginator | ✅ | ❌ | +| product_groups | productGroupNumber | DefaultPaginator | ✅ | ❌ | +| products | productNumber | DefaultPaginator | ✅ | ❌ | +| draft_quotes | quoteNumber | DefaultPaginator | ✅ | ❌ | +| suppliers | supplierNumber | DefaultPaginator | ✅ | ❌ | +| units | unitNumber | DefaultPaginator | ✅ | ❌ | +| vat_accounts | vatCode | DefaultPaginator | ✅ | ❌ | +| vat_types | vatTypeNumber | DefaultPaginator | ✅ | ❌ | +| vat_zones | vatZoneNumber | DefaultPaginator | ✅ | ❌ | +| sent_quotes | quoteNumber | DefaultPaginator | ✅ | ❌ | +| archived_quotes | quoteNumber | DefaultPaginator | ✅ | ❌ | +| draft_invoices | draftInvoiceNumber | DefaultPaginator | ✅ | ❌ | +| booked_invoices | bookedInvoiceNumber | DefaultPaginator | ✅ | ❌ | +| paid_invoices | bookedInvoiceNumber | DefaultPaginator | ✅ | ❌ | +| overdue_invoices | bookedInvoiceNumber | DefaultPaginator | ✅ | ❌ | +| unpaid_invoices | bookedInvoiceNumber | DefaultPaginator | ✅ | ❌ | +| not_due_invoices | bookedInvoiceNumber | DefaultPaginator | ✅ | ❌ | +| total_invoices | | DefaultPaginator | ✅ | ❌ | +| sent_invoices | id | DefaultPaginator | ✅ | ❌ | +| draft_orders | orderNumber | DefaultPaginator | ✅ | ❌ | +| sent_orders | orderNumber | DefaultPaginator | ✅ | ❌ | +| archived_orders | orderNumber | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50551](https://github.com/airbytehq/airbyte/pull/50551) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50016](https://github.com/airbytehq/airbyte/pull/50016) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49523](https://github.com/airbytehq/airbyte/pull/49523) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49165](https://github.com/airbytehq/airbyte/pull/49165) | Update dependencies | +| 0.0.1 | 2024-10-28 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/easypost.md b/docs/integrations/sources/easypost.md index d2c4a2b1b755..6b0a3dc616bb 100644 --- a/docs/integrations/sources/easypost.md +++ b/docs/integrations/sources/easypost.md @@ -34,6 +34,11 @@ This directory contains the manifest-only connector for [`source-easypost`](http | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50573](https://github.com/airbytehq/airbyte/pull/50573) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50036](https://github.com/airbytehq/airbyte/pull/50036) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49511](https://github.com/airbytehq/airbyte/pull/49511) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49184](https://github.com/airbytehq/airbyte/pull/49184) | Update dependencies | +| 0.0.2 | 2024-11-04 | [47654](https://github.com/airbytehq/airbyte/pull/47654) | Update dependencies | | 0.0.1 | 2024-10-01 | [46287](https://github.com/airbytehq/airbyte/pull/46287) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/easypromos.md b/docs/integrations/sources/easypromos.md new file mode 100644 index 000000000000..48b9a657fb1d --- /dev/null +++ b/docs/integrations/sources/easypromos.md @@ -0,0 +1,35 @@ +# Easypromos +Airbyte connector for [Easypromos](https://www.easypromosapp.com/) enables seamless data extraction from Easypromos, an online platform for running contests, giveaways, and promotions. It facilitates automatic syncing of participant information, promotion performance, and engagement metrics into data warehouses, streamlining analytics and reporting. This integration helps businesses easily analyze campaign data and optimize marketing strategies + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `bearer_token` | `string` | Bearer Token. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| promotions | id | DefaultPaginator | ✅ | ❌ | +| organizing_brands | id | DefaultPaginator | ✅ | ❌ | +| stages | id | DefaultPaginator | ✅ | ❌ | +| users | id | DefaultPaginator | ✅ | ❌ | +| participations | id | DefaultPaginator | ✅ | ❌ | +| prizes | id | DefaultPaginator | ✅ | ❌ | +| rankings | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50586](https://github.com/airbytehq/airbyte/pull/50586) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50003](https://github.com/airbytehq/airbyte/pull/50003) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49477](https://github.com/airbytehq/airbyte/pull/49477) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49180](https://github.com/airbytehq/airbyte/pull/49180) | Update dependencies | +| 0.0.2 | 2024-11-04 | [48302](https://github.com/airbytehq/airbyte/pull/48302) | Update dependencies | +| 0.0.1 | 2024-10-21 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/elasticemail.md b/docs/integrations/sources/elasticemail.md new file mode 100644 index 000000000000..7c495670ae77 --- /dev/null +++ b/docs/integrations/sources/elasticemail.md @@ -0,0 +1,41 @@ +# Elasticemail +Elasticemail is an email delivery and marketing platform. +Using this connector we extract data from streams such as campaigns , contacts , lists and statistics! +Docs : https://elasticemail.com/developers/api-documentation/rest-api + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | +| `scope_type` | `string` | scope type. | | +| `from` | `string` | From. | | +| `start_date` | `string` | Start date. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| campaigns | Name | DefaultPaginator | ✅ | ❌ | +| contacts | Email | DefaultPaginator | ✅ | ❌ | +| events | | DefaultPaginator | ✅ | ✅ | +| files | | DefaultPaginator | ✅ | ❌ | +| inboundroute | | No pagination | ✅ | ❌ | +| lists | | DefaultPaginator | ✅ | ❌ | +| segments | | DefaultPaginator | ✅ | ❌ | +| statistics | | DefaultPaginator | ✅ | ❌ | +| templates | | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50588](https://github.com/airbytehq/airbyte/pull/50588) | Update dependencies | +| 0.0.4 | 2024-12-21 | [49989](https://github.com/airbytehq/airbyte/pull/49989) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49522](https://github.com/airbytehq/airbyte/pull/49522) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49195](https://github.com/airbytehq/airbyte/pull/49195) | Update dependencies | +| 0.0.1 | 2024-11-08 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/elasticsearch.md b/docs/integrations/sources/elasticsearch.md index 13a80b695d09..86be73b0ddd6 100644 --- a/docs/integrations/sources/elasticsearch.md +++ b/docs/integrations/sources/elasticsearch.md @@ -87,9 +87,10 @@ all values in the array must be of the same data type. Hence, every field can be | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :----------------------------- | -| 0.1.2 | 2024-02-13 | [35230](https://github.com/airbytehq/airbyte/pull/35230) | Adopt CDK 0.20.4 | +| 0.1.3 | 2024-12-18 | [49863](https://github.com/airbytehq/airbyte/pull/49863) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.1.2 | 2024-02-13 | [35230](https://github.com/airbytehq/airbyte/pull/35230) | Adopt CDK 0.20.4 | | `0.1.2` | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | | `0.1.1` | 2022-12-02 | [18118](https://github.com/airbytehq/airbyte/pull/18118) | Avoid too_long_frame_exception | | `0.1.0` | 2022-07-12 | [14118](https://github.com/airbytehq/airbyte/pull/14118) | Initial Release | - \ No newline at end of file + diff --git a/docs/integrations/sources/emailoctopus.md b/docs/integrations/sources/emailoctopus.md index 7454c73c45d7..adb190b0cb9b 100644 --- a/docs/integrations/sources/emailoctopus.md +++ b/docs/integrations/sources/emailoctopus.md @@ -28,6 +28,10 @@ No documented strict rate limit. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.2.7 | 2024-12-28 | [50581](https://github.com/airbytehq/airbyte/pull/50581) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50062](https://github.com/airbytehq/airbyte/pull/50062) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49479](https://github.com/airbytehq/airbyte/pull/49479) | Update dependencies | +| 0.2.4 | 2024-12-12 | [48165](https://github.com/airbytehq/airbyte/pull/48165) | Update dependencies | | 0.2.3 | 2024-10-29 | [47896](https://github.com/airbytehq/airbyte/pull/47896) | Update dependencies | | 0.2.2 | 2024-10-28 | [47450](https://github.com/airbytehq/airbyte/pull/47450) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/employment-hero.md b/docs/integrations/sources/employment-hero.md index 6a5ce498864c..2f58f1d0f051 100644 --- a/docs/integrations/sources/employment-hero.md +++ b/docs/integrations/sources/employment-hero.md @@ -58,6 +58,11 @@ Hit Get new Access token and approve via browser, Postman will collect a new `ac | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.7 | 2024-12-28 | [50526](https://github.com/airbytehq/airbyte/pull/50526) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50024](https://github.com/airbytehq/airbyte/pull/50024) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49489](https://github.com/airbytehq/airbyte/pull/49489) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49190](https://github.com/airbytehq/airbyte/pull/49190) | Update dependencies | +| 0.0.3 | 2024-11-04 | [47819](https://github.com/airbytehq/airbyte/pull/47819) | Update dependencies | | 0.0.2 | 2024-10-28 | [47632](https://github.com/airbytehq/airbyte/pull/47632) | Update dependencies | | 0.0.1 | 2024-09-25 | [45888](https://github.com/airbytehq/airbyte/pull/45888) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/encharge.md b/docs/integrations/sources/encharge.md new file mode 100644 index 000000000000..e7c99124cbc5 --- /dev/null +++ b/docs/integrations/sources/encharge.md @@ -0,0 +1,34 @@ +# Encharge +Airbyte connector for [Encharge](https://encharge.io/) enables seamless data integration between Encharge and your data warehouse or other destinations. With this connector, you can easily sync marketing automation data from Encharge. This allows for improved data-driven decision-making and enhanced marketing insights across platforms. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. The API key to use for authentication | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| peoples | id | DefaultPaginator | ✅ | ❌ | +| accounts | accountId | No pagination | ✅ | ❌ | +| account_tags | tag | No pagination | ✅ | ❌ | +| segments | id | DefaultPaginator | ✅ | ❌ | +| segment_people | id | DefaultPaginator | ✅ | ❌ | +| fields | name | No pagination | ✅ | ❌ | +| schemas | name | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50537](https://github.com/airbytehq/airbyte/pull/50537) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50001](https://github.com/airbytehq/airbyte/pull/50001) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49509](https://github.com/airbytehq/airbyte/pull/49509) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49175](https://github.com/airbytehq/airbyte/pull/49175) | Update dependencies | +| 0.0.1 | 2024-11-08 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/eventbrite.md b/docs/integrations/sources/eventbrite.md index ab2c718eb0f6..dc2e5df6399e 100644 --- a/docs/integrations/sources/eventbrite.md +++ b/docs/integrations/sources/eventbrite.md @@ -37,6 +37,10 @@ To get a Private Token: | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.6 | 2024-12-28 | [50513](https://github.com/airbytehq/airbyte/pull/50513) | Update dependencies | +| 0.0.5 | 2024-12-21 | [49994](https://github.com/airbytehq/airbyte/pull/49994) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49494](https://github.com/airbytehq/airbyte/pull/49494) | Update dependencies | +| 0.0.3 | 2024-12-12 | [48962](https://github.com/airbytehq/airbyte/pull/48962) | Update dependencies | | 0.0.2 | 2024-10-28 | [47521](https://github.com/airbytehq/airbyte/pull/47521) | Update dependencies | | 0.0.1 | 2024-09-21 | | Initial release by [@topefolorunso](https://github.com/topefolorunso) via Connector Builder | diff --git a/docs/integrations/sources/eventee.md b/docs/integrations/sources/eventee.md new file mode 100644 index 000000000000..bf8b3a56a575 --- /dev/null +++ b/docs/integrations/sources/eventee.md @@ -0,0 +1,36 @@ +# Eventee +The Airbyte connector for Eventee enables seamless integration and automated data synchronization between Eventee, a leading event management platform, and your data destinations. It extracts and transfers event-related information such as attendee details, lectures, tracks, and more. This connector ensures real-time or scheduled data flow, helping you centralize and analyze Eventee's data effortlessly for improved event insights and reporting. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_token` | `string` | API Token. API token to use. Generate it at https://admin.eventee.co/ in 'Settings -> Features'. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| halls | id | No pagination | ✅ | ❌ | +| days | id | No pagination | ✅ | ❌ | +| lectures | id | No pagination | ✅ | ❌ | +| speakers | id | No pagination | ✅ | ❌ | +| workshops | id | No pagination | ✅ | ❌ | +| pauses | id | No pagination | ✅ | ❌ | +| tracks | id | No pagination | ✅ | ❌ | +| partners | id | No pagination | ✅ | ❌ | +| participants | email | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50554](https://github.com/airbytehq/airbyte/pull/50554) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50009](https://github.com/airbytehq/airbyte/pull/50009) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49470](https://github.com/airbytehq/airbyte/pull/49470) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49191](https://github.com/airbytehq/airbyte/pull/49191) | Update dependencies | +| 0.0.1 | 2024-10-28 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/eventzilla.md b/docs/integrations/sources/eventzilla.md new file mode 100644 index 000000000000..b032ccc91ef5 --- /dev/null +++ b/docs/integrations/sources/eventzilla.md @@ -0,0 +1,33 @@ +# Eventzilla +The Airbyte connector for Eventzilla enables seamless integration between Eventzilla and various data destinations. It automates the extraction of event management data, such as attendee details, ticket sales, and event performance metrics, and syncs it with your preferred data warehouses or analytics tools. This connector helps organizations centralize and analyze their Eventzilla data for reporting, monitoring, and strategic insights. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `x-api-key` | `string` | API Key. API key to use. Generate it by creating a new application within your Eventzilla account settings under Settings > App Management. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| events | id | DefaultPaginator | ✅ | ❌ | +| attendees | id | DefaultPaginator | ✅ | ❌ | +| categories | | DefaultPaginator | ✅ | ❌ | +| tickets | id | DefaultPaginator | ✅ | ❌ | +| users | id | DefaultPaginator | ✅ | ❌ | +| transactions | refno | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50549](https://github.com/airbytehq/airbyte/pull/50549) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50047](https://github.com/airbytehq/airbyte/pull/50047) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49488](https://github.com/airbytehq/airbyte/pull/49488) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49198](https://github.com/airbytehq/airbyte/pull/49198) | Update dependencies | +| 0.0.1 | 2024-10-23 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/everhour.md b/docs/integrations/sources/everhour.md index a60d3a36e2e4..465b21e1971f 100644 --- a/docs/integrations/sources/everhour.md +++ b/docs/integrations/sources/everhour.md @@ -28,6 +28,10 @@ This project supports the following streams: | Version | Date | Pull Request | Subject | |:--------|:-----------| :------------------------------------------------------- | :-------------- | +| 0.2.6 | 2024-12-28 | [50518](https://github.com/airbytehq/airbyte/pull/50518) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50012](https://github.com/airbytehq/airbyte/pull/50012) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49539](https://github.com/airbytehq/airbyte/pull/49539) | Update dependencies | +| 0.2.3 | 2024-12-12 | [48147](https://github.com/airbytehq/airbyte/pull/48147) | Update dependencies | | 0.2.2 | 2024-10-28 | [47508](https://github.com/airbytehq/airbyte/pull/47508) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-15 | [44151](https://github.com/airbytehq/airbyte/pull/44151) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/exchange-rates.md b/docs/integrations/sources/exchange-rates.md index 7acb0d6a2bd0..8e0b43620b9a 100644 --- a/docs/integrations/sources/exchange-rates.md +++ b/docs/integrations/sources/exchange-rates.md @@ -90,6 +90,9 @@ The Exchange Rates API has rate limits that vary per pricing plan. The free plan | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------ | +| 1.4.6 | 2024-12-28 | [49990](https://github.com/airbytehq/airbyte/pull/49990) | Update dependencies | +| 1.4.5 | 2024-12-14 | [49478](https://github.com/airbytehq/airbyte/pull/49478) | Update dependencies | +| 1.4.4 | 2024-12-12 | [49196](https://github.com/airbytehq/airbyte/pull/49196) | Update dependencies | | 1.4.3 | 2024-10-29 | [47813](https://github.com/airbytehq/airbyte/pull/47813) | Update dependencies | | 1.4.2 | 2024-10-28 | [47549](https://github.com/airbytehq/airbyte/pull/47549) | Update dependencies | | 1.4.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/ezofficeinventory.md b/docs/integrations/sources/ezofficeinventory.md index ea7a4c20dab1..33e2e9bee42c 100644 --- a/docs/integrations/sources/ezofficeinventory.md +++ b/docs/integrations/sources/ezofficeinventory.md @@ -37,6 +37,12 @@ A manifest only source for EZOfficeInventory. https://ezo.io/ezofficeinventory/ | Version | Date | Pull Request | Subject | |---------|------------|----------------------------------------------------------|-------------------------------------------------------------------------------------------| +| 0.0.9 | 2024-12-28 | [50580](https://github.com/airbytehq/airbyte/pull/50580) | Update dependencies | +| 0.0.8 | 2024-12-21 | [50054](https://github.com/airbytehq/airbyte/pull/50054) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49506](https://github.com/airbytehq/airbyte/pull/49506) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49164](https://github.com/airbytehq/airbyte/pull/49164) | Update dependencies | +| 0.0.5 | 2024-12-11 | [48932](https://github.com/airbytehq/airbyte/pull/48932) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-11-04 | [48180](https://github.com/airbytehq/airbyte/pull/48180) | Update dependencies | | 0.0.3 | 2024-10-29 | [47913](https://github.com/airbytehq/airbyte/pull/47913) | Update dependencies | | 0.0.2 | 2024-10-28 | [47535](https://github.com/airbytehq/airbyte/pull/47535) | Update dependencies | | 0.0.1 | 2024-09-15 | [45590](https://github.com/airbytehq/airbyte/pull/45590) | Initial release by [@pabloescoder](https://github.com/pabloescoder) via Connector Builder | diff --git a/docs/integrations/sources/facebook-marketing.md b/docs/integrations/sources/facebook-marketing.md index 921dca360424..15835eac7d1f 100644 --- a/docs/integrations/sources/facebook-marketing.md +++ b/docs/integrations/sources/facebook-marketing.md @@ -269,6 +269,12 @@ This response indicates that the Facebook Graph API requires you to reduce the f | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 3.3.24 | 2025-01-04 | [50922](https://github.com/airbytehq/airbyte/pull/50922) | Update dependencies | +| 3.3.23 | 2024-12-28 | [50533](https://github.com/airbytehq/airbyte/pull/50533) | Update dependencies | +| 3.3.22 | 2024-12-21 | [50014](https://github.com/airbytehq/airbyte/pull/50014) | Update dependencies | +| 3.3.21 | 2024-12-14 | [49197](https://github.com/airbytehq/airbyte/pull/49197) | Update dependencies | +| 3.3.20 | 2024-11-25 | [48632](https://github.com/airbytehq/airbyte/pull/48632) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 3.3.19 | 2024-11-04 | [48155](https://github.com/airbytehq/airbyte/pull/48155) | Update dependencies | | 3.3.18 | 2024-10-29 | [47894](https://github.com/airbytehq/airbyte/pull/47894) | Update dependencies | | 3.3.17 | 2024-10-28 | [43787](https://github.com/airbytehq/airbyte/pull/43787) | Update dependencies | | 3.3.16 | 2024-07-15 | [46546](https://github.com/airbytehq/airbyte/pull/46546) | Raise exception on missing stream | diff --git a/docs/integrations/sources/facebook-pages.md b/docs/integrations/sources/facebook-pages.md index 22d39ec7438e..f78e81ffbbcf 100644 --- a/docs/integrations/sources/facebook-pages.md +++ b/docs/integrations/sources/facebook-pages.md @@ -89,6 +89,10 @@ See Facebook's [documentation on rate limiting](https://developers.facebook.com/ | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------ | | 1.1.0 | 2024-10-23 | [47325](https://github.com/airbytehq/airbyte/pull/47325) | Migrate to Manifest-only | +| 1.0.27 | 2025-01-04 | [50923](https://github.com/airbytehq/airbyte/pull/50923) | Update dependencies | +| 1.0.26 | 2024-12-28 | [50530](https://github.com/airbytehq/airbyte/pull/50530) | Update dependencies | +| 1.0.25 | 2024-12-21 | [49997](https://github.com/airbytehq/airbyte/pull/49997) | Update dependencies | +| 1.0.24 | 2024-12-14 | [49154](https://github.com/airbytehq/airbyte/pull/49154) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 1.0.23 | 2024-10-29 | [47737](https://github.com/airbytehq/airbyte/pull/47737) | Update dependencies | | 1.0.22 | 2024-10-21 | [47025](https://github.com/airbytehq/airbyte/pull/47025) | Update dependencies | | 1.0.21 | 2024-10-12 | [46807](https://github.com/airbytehq/airbyte/pull/46807) | Update dependencies | diff --git a/docs/integrations/sources/factorial.md b/docs/integrations/sources/factorial.md index fe57a34cd2b9..db92d5273c66 100644 --- a/docs/integrations/sources/factorial.md +++ b/docs/integrations/sources/factorial.md @@ -53,6 +53,10 @@ Visit `https://apidoc.factorialhr.com/reference` for API documentation | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.6 | 2024-12-28 | [50583](https://github.com/airbytehq/airbyte/pull/50583) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50020](https://github.com/airbytehq/airbyte/pull/50020) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49514](https://github.com/airbytehq/airbyte/pull/49514) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49176](https://github.com/airbytehq/airbyte/pull/49176) | Update dependencies | | 0.0.2 | 2024-10-28 | [47512](https://github.com/airbytehq/airbyte/pull/47512) | Update dependencies | | 0.0.1 | 2024-09-24 | [45882](https://github.com/airbytehq/airbyte/pull/45882) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/faker.md b/docs/integrations/sources/faker.md index 4e4e413c13fe..289ba9d24aa6 100644 --- a/docs/integrations/sources/faker.md +++ b/docs/integrations/sources/faker.md @@ -103,7 +103,9 @@ None! Expand to review | Version | Date | Pull Request | Subject | -|:------------|:-----------| :-------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------- | +|:------------|:-----------| :-------------------------------------------------------------------------------------------------------------------- |:----------------------------------------------------------------------------------------------------------------| +| 6.2.21-rc.1 | 2024-11-13 | [48013](https://github.com/airbytehq/airbyte/pull/48013) | Update for testing. | +| 6.2.20 | 2024-10-30 | [48013](https://github.com/airbytehq/airbyte/pull/48013) | Promoting release candidate 6.2.20-rc.1 to a main version. | | 6.2.20-rc.1 | 2024-10-21 | [47221](https://github.com/airbytehq/airbyte/pull/46678) | Testing release candidate with RC suffix versioning. | | 6.2.19-rc.1 | 2024-10-21 | [47221](https://github.com/airbytehq/airbyte/pull/47221) | Testing release candidate with RC suffix versioning. | | 6.2.18-rc.1 | 2024-10-09 | [46678](https://github.com/airbytehq/airbyte/pull/46678) | Testing release candidate with RC suffix versioning. | diff --git a/docs/integrations/sources/fastbill.md b/docs/integrations/sources/fastbill.md index 65677892ab7a..858d4582450f 100644 --- a/docs/integrations/sources/fastbill.md +++ b/docs/integrations/sources/fastbill.md @@ -64,6 +64,12 @@ The Fastbill source connector supports the following [sync modes](https://docs.a | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.3.5 | 2025-01-04 | [50523](https://github.com/airbytehq/airbyte/pull/50523) | Update dependencies | +| 0.3.4 | 2024-12-21 | [50019](https://github.com/airbytehq/airbyte/pull/50019) | Update dependencies | +| 0.3.3 | 2024-12-14 | [49481](https://github.com/airbytehq/airbyte/pull/49481) | Update dependencies | +| 0.3.2 | 2024-12-12 | [48955](https://github.com/airbytehq/airbyte/pull/48955) | Update dependencies | +| 0.3.1 | 2024-12-11 | [47089](https://github.com/airbytehq/airbyte/pull/47089) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.3.0 | 2024-10-31 | [47297](https://github.com/airbytehq/airbyte/pull/47297) | Migrate to manifest only format | | 0.2.24 | 2024-10-12 | [46777](https://github.com/airbytehq/airbyte/pull/46777) | Update dependencies | | 0.2.23 | 2024-10-05 | [46505](https://github.com/airbytehq/airbyte/pull/46505) | Update dependencies | | 0.2.22 | 2024-09-28 | [46172](https://github.com/airbytehq/airbyte/pull/46172) | Update dependencies | diff --git a/docs/integrations/sources/file.md b/docs/integrations/sources/file.md index d2895ec7bfa5..71c87aef6477 100644 --- a/docs/integrations/sources/file.md +++ b/docs/integrations/sources/file.md @@ -298,6 +298,8 @@ In order to read large files from a remote location, this connector uses the [sm | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------------------------------ | +| 0.5.16 | 2024-12-10 | [48804](https://github.com/airbytehq/airbyte/pull/48804) | Added reader options: skiprows & header for Excel files | +| 0.5.15 | 2024-11-05 | [48317](https://github.com/airbytehq/airbyte/pull/48317) | Update dependencies | | 0.5.14 | 2024-10-29 | [47115](https://github.com/airbytehq/airbyte/pull/47115) | Update dependencies | | 0.5.13 | 2024-10-12 | [45795](https://github.com/airbytehq/airbyte/pull/45795) | Update dependencies | | 0.5.12 | 2024-09-14 | [45499](https://github.com/airbytehq/airbyte/pull/45499) | Update dependencies | diff --git a/docs/integrations/sources/fillout.md b/docs/integrations/sources/fillout.md new file mode 100644 index 000000000000..7af9383b4a21 --- /dev/null +++ b/docs/integrations/sources/fillout.md @@ -0,0 +1,34 @@ +# Fillout + +The Airbyte connector for Fillout.com enables seamless data synchronization between Fillout forms and various target destinations. This connector allows you to extract form submissions and related data from Fillout and transfer it to your chosen data warehouse, analytics platform, or other destinations. With this integration, you can automate workflows, perform data analysis, and centralize data management for improved insights and reporting. + +## Configuration + +| Input | Type | Description | Default Value | +| ------------ | -------- | --------------------------------------------------------------------------------------- | ------------- | +| `api_key` | `string` | API Key. API key to use. Find it in the Developer settings tab of your Fillout account. | | +| `start_date` | `string` | Start date. | | + +## Streams + +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +| ------------- | ------------ | ---------------- | ------------------ | -------------------- | +| forms | formId | DefaultPaginator | ✅ | ❌ | +| form_metadata | id | DefaultPaginator | ✅ | ❌ | +| submissions | submissionId | DefaultPaginator | ✅ | ✅ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +| ------- | ---------- | ------------ | ----------------------------------------------------------------------------------- | +| 0.2.4 | 2024-12-28 | [50515](https://github.com/airbytehq/airbyte/pull/50515) | Update dependencies | +| 0.2.3 | 2024-12-21 | [50068](https://github.com/airbytehq/airbyte/pull/50068) | Update dependencies | +| 0.2.2 | 2024-12-14 | [49530](https://github.com/airbytehq/airbyte/pull/49530) | Update dependencies | +| 0.2.1 | 2024-12-12 | [49189](https://github.com/airbytehq/airbyte/pull/49189) | Update dependencies | +| 0.2.0 | 2024-11-14 | | Add `formId` to `submissions` stream | +| 0.0.1 | 2024-10-28 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/finage.md b/docs/integrations/sources/finage.md new file mode 100644 index 000000000000..a4cbf58fc066 --- /dev/null +++ b/docs/integrations/sources/finage.md @@ -0,0 +1,53 @@ +# Finage +Real-Time Market Data Solutions for Stocks, Forex, and Crypto +This connector can be used to extract data from various APIs such as symbol-list,Aggregates,Snapshot and Technical Indicators + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | +| `symbols` | `array` | Symbols. List of symbols | | +| `tech_indicator_type` | `string` | Technical Indicator Type. One of DEMA, EMA, SMA, WMA, RSI, TEMA, Williams, ADX | SMA | +| `time` | `string` | Time Interval. | daily | +| `period` | `string` | Period. Time period. Default is 10 | | +| `time_aggregates` | `string` | Time aggregates. Size of the time | day | +| `time_period` | `string` | Time Period. Time Period for cash flow stmts | | +| `start_date` | `string` | Start date. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| market_news | | No pagination | ✅ | ❌ | +| most_active_us_stocks | symbol | No pagination | ✅ | ❌ | +| technical_indicators | | No pagination | ✅ | ❌ | +| economic_calendar | | No pagination | ✅ | ✅ | +| earning_calendar | | No pagination | ✅ | ❌ | +| delisted_companies | symbol | No pagination | ✅ | ❌ | +| ipo_calendar | symbol | No pagination | ✅ | ✅ | +| historical_stock_split | | No pagination | ✅ | ❌ | +| historical_dividends_calendar | | No pagination | ✅ | ❌ | +| cash_flow_statements | date.symbol | No pagination | ✅ | ❌ | +| balance_sheet_statements | date.symbol | No pagination | ✅ | ❌ | +| income_statement | date.symbol | No pagination | ✅ | ❌ | +| institutional_holders | holder | No pagination | ✅ | ❌ | +| mutual_fund_holder | | No pagination | ✅ | ❌ | +| most_gainers | symbol | No pagination | ✅ | ❌ | +| most_losers | symbol | No pagination | ✅ | ❌ | +| sector_performance | sector | No pagination | ✅ | ❌ | +| shares_float | | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50566](https://github.com/airbytehq/airbyte/pull/50566) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50058](https://github.com/airbytehq/airbyte/pull/50058) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49496](https://github.com/airbytehq/airbyte/pull/49496) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49202](https://github.com/airbytehq/airbyte/pull/49202) | Update dependencies | +| 0.0.1 | 2024-11-11 | | Initial release by [@marcosmarxm](https://github.com/marcosmarxm) via Connector Builder | + +
diff --git a/docs/integrations/sources/financial-modelling.md b/docs/integrations/sources/financial-modelling.md new file mode 100644 index 000000000000..cafb821758bf --- /dev/null +++ b/docs/integrations/sources/financial-modelling.md @@ -0,0 +1,52 @@ +# Financial Modelling +FMP provides financial data. +Using this connector we can extract data from various endpoints like Stocks list, ETFs list , Exchange Symbols and Historical MarketCap etc +Docs : https://site.financialmodelingprep.com/developer/docs + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | +| `exchange` | `string` | Exchange. The stock exchange : AMEX, AMS, AQS, ASX, ATH, BER, BME, BRU, BSE, BUD, BUE, BVC, CAI, CBOE, CNQ, CPH, DFM, DOH, DUS, DXE, EGX, EURONEXT, HAM, HEL, HKSE, ICE, IOB, IST, JKT, JNB, JPX, KLS, KOE, KSC, KUW, LSE, MCX, MEX, MIL, MUN, NASDAQ, NEO, NSE, NYSE, NZE, OEM, OQX, OSL, OTC, PNK, PRA, RIS, SAO, SAU, SES, SET, SGO, SHH, SHZ, SIX, STO, STU, TAI, TLV, TSX, TSXV, TWO, VIE, VSE, WSE, XETRA | NASDAQ | +| `marketcapmorethan` | `string` | marketCapMoreThan. Used in screener to filter out stocks with a market cap more than the give marketcap | | +| `marketcaplowerthan` | `string` | marketCapLowerThan. Used in screener to filter out stocks with a market cap lower than the give marketcap | | +| `start_date` | `string` | Start Date | | +| `time_frame` | `string` | Time Frame. For example 1min, 5min, 15min, 30min, 1hour, 4hour | 1hour | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| Stocks List | | No pagination | ✅ | ❌ | +| ETFs List | | No pagination | ✅ | ❌ | +| Tradable Search | | No pagination | ✅ | ❌ | +| CIK List | | No pagination | ✅ | ❌ | +| Euronext Symbols | | No pagination | ✅ | ❌ | +| Exchange Symbols | | No pagination | ✅ | ❌ | +| Available Indexes | | No pagination | ✅ | ❌ | +| Company Profile | | No pagination | ✅ | ❌ | +| Screener (Stock) | | No pagination | ✅ | ❌ | +| Historical Market Cap | | No pagination | ✅ | ✅ | +| Delisted Companies | | No pagination | ✅ | ❌ | +| Exchange Prices | | No pagination | ✅ | ❌ | +| All RealTime Full Stock Prices | | No pagination | ✅ | ❌ | +| ALL FX Prices | | No pagination | ✅ | ❌ | +| Stock Historical Price | | No pagination | ✅ | ✅ | +| Forex List | | No pagination | ✅ | ❌ | +| Cryptocurrencies List | | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50524](https://github.com/airbytehq/airbyte/pull/50524) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50060](https://github.com/airbytehq/airbyte/pull/50060) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49516](https://github.com/airbytehq/airbyte/pull/49516) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49157](https://github.com/airbytehq/airbyte/pull/49157) | Update dependencies | +| 0.0.2 | 2024-11-04 | [48299](https://github.com/airbytehq/airbyte/pull/48299) | Update dependencies | +| 0.0.1 | 2024-10-22 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/finnhub.md b/docs/integrations/sources/finnhub.md new file mode 100644 index 000000000000..c25cb7638390 --- /dev/null +++ b/docs/integrations/sources/finnhub.md @@ -0,0 +1,42 @@ +# Finnhub +Finnhub is a financial data platform that provides real-time stock market, forex, and cryptocurrency data, along with extensive fundamental data, economic indicators, and alternative data for global markets. With its powerful API, Finnhub delivers actionable insights, enabling developers, financial institutions, and traders to integrate market intelligence into their applications, build trading algorithms, and track investment performance. It supports a wide range of financial metrics, including earnings reports, company profiles, and news, making it a comprehensive solution for financial analysis and market research + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. The API key to use for authentication | | +| `symbols` | `array` | Companies. | | +| `market_news_category` | `string` | Market News Category. This parameter can be 1 of the following values general, forex, crypto, merger. | general | +| `exchange` | `string` | Exchange. More info: https://finnhub.io/docs/api/stock-symbols | US | +| `start_date_2` | `string` | Start date. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| marketnews | id | No pagination | ✅ | ❌ | +| stock_symbols | | No pagination | ✅ | ❌ | +| basic_financial_report | accessNumber | No pagination | ✅ | ✅ | +| company_profile | ticker | No pagination | ✅ | ❌ | +| sec_filings | accessNumber | No pagination | ✅ | ✅ | +| insider_transactions | | No pagination | ✅ | ✅ | +| insider_sentiment | | No pagination | ✅ | ❌ | +| company_news | | No pagination | ✅ | ✅ | +| stock_recommendations | | No pagination | ✅ | ❌ | +| earnings_surprises | symbol.period | No pagination | ✅ | ❌ | +| stock_quote | | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50590](https://github.com/airbytehq/airbyte/pull/50590) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50046](https://github.com/airbytehq/airbyte/pull/50046) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49535](https://github.com/airbytehq/airbyte/pull/49535) | Update dependencies | +| 0.0.2 | 2024-12-12 | [48957](https://github.com/airbytehq/airbyte/pull/48957) | Update dependencies | +| 0.0.1 | 2024-11-06 | | Initial release by [@marcosmarxm](https://github.com/marcosmarxm) via Connector Builder | + +
diff --git a/docs/integrations/sources/finnworlds.md b/docs/integrations/sources/finnworlds.md new file mode 100644 index 000000000000..ab64f0143759 --- /dev/null +++ b/docs/integrations/sources/finnworlds.md @@ -0,0 +1,42 @@ +# Finnworlds +Finnworlds provides data related to finance for globally traded instruments. +With this connector we can easily fetch data from various streams such as Dividends , Stock Splits , Candle Sticks etc +Docs : https://finnworlds.com/ + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `key` | `string` | API Key. | | +| `bond_type` | `array` | Bond Type. For example 10y, 5y, 2y... | | +| `countries` | `array` | Countries. brazil, united states, italia, japan | | +| `tickers` | `array` | Tickers. AAPL, T, MU, GOOG | | +| `start_date` | `string` | Start date. | | +| `commodities` | `array` | Commodities. Options Available: beef, cheese, oil, ... | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| bonds | country.datetime.type | No pagination | ✅ | ❌ | +| dividends | | No pagination | ✅ | ❌ | +| stock_splits | ticker.date | No pagination | ✅ | ❌ | +| historical_candlestick | ticker.date | No pagination | ✅ | ✅ | +| macro_calendar | | No pagination | ✅ | ❌ | +| macro_indicator | | No pagination | ✅ | ❌ | +| commodities | commodity_name.datetime | No pagination | ✅ | ❌ | +| benchmark | datetime.country.benchmark | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50519](https://github.com/airbytehq/airbyte/pull/50519) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50049](https://github.com/airbytehq/airbyte/pull/50049) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49513](https://github.com/airbytehq/airbyte/pull/49513) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49206](https://github.com/airbytehq/airbyte/pull/49206) | Update dependencies | +| 0.0.1 | 2024-11-05 | | Initial release by [@marcosmarxm](https://github.com/marcosmarxm) via Connector Builder | + +
diff --git a/docs/integrations/sources/firebase-realtime-database.md b/docs/integrations/sources/firebase-realtime-database.md index 46f72a95e7fd..d1d72b2c441c 100644 --- a/docs/integrations/sources/firebase-realtime-database.md +++ b/docs/integrations/sources/firebase-realtime-database.md @@ -79,6 +79,12 @@ Once you've configured Firebase Realtime Database as a source, delete the Servic | Version | Date | Pull Request | Subject | | :------ | :--------- | :--------------------------------------------------------- | :----------------------------------------- | +| 0.1.31 | 2025-01-04 | [50924](https://github.com/airbytehq/airbyte/pull/50924) | Update dependencies | +| 0.1.30 | 2024-12-28 | [50561](https://github.com/airbytehq/airbyte/pull/50561) | Update dependencies | +| 0.1.29 | 2024-12-21 | [50006](https://github.com/airbytehq/airbyte/pull/50006) | Update dependencies | +| 0.1.28 | 2024-12-14 | [49186](https://github.com/airbytehq/airbyte/pull/49186) | Update dependencies | +| 0.1.27 | 2024-11-25 | [48653](https://github.com/airbytehq/airbyte/pull/48653) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.1.26 | 2024-11-04 | [47041](https://github.com/airbytehq/airbyte/pull/47041) | Update dependencies | | 0.1.25 | 2024-10-12 | [46799](https://github.com/airbytehq/airbyte/pull/46799) | Update dependencies | | 0.1.24 | 2024-10-05 | [46457](https://github.com/airbytehq/airbyte/pull/46457) | Update dependencies | | 0.1.23 | 2024-09-28 | [46135](https://github.com/airbytehq/airbyte/pull/46135) | Update dependencies | diff --git a/docs/integrations/sources/firebolt.md b/docs/integrations/sources/firebolt.md index c08b4f5b92f4..8872864689b7 100644 --- a/docs/integrations/sources/firebolt.md +++ b/docs/integrations/sources/firebolt.md @@ -54,6 +54,7 @@ You can now use the Airbyte Firebolt source. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :----------------------------------------------------------- | +| 2.0.24 | 2024-11-04 | [48154](https://github.com/airbytehq/airbyte/pull/48154) | Update dependencies | | 2.0.23 | 2024-10-28 | [47109](https://github.com/airbytehq/airbyte/pull/47109) | Update dependencies | | 2.0.22 | 2024-10-12 | [46826](https://github.com/airbytehq/airbyte/pull/46826) | Update dependencies | | 2.0.21 | 2024-10-05 | [46471](https://github.com/airbytehq/airbyte/pull/46471) | Update dependencies | diff --git a/docs/integrations/sources/firehydrant.md b/docs/integrations/sources/firehydrant.md new file mode 100644 index 000000000000..c11b7613d215 --- /dev/null +++ b/docs/integrations/sources/firehydrant.md @@ -0,0 +1,66 @@ +# FireHydrant +The Airbyte connector for FireHydrant enables seamless data integration between FireHydrant and your data ecosystem. It allows you to efficiently extract incident management and reliability data from FireHydrant, empowering teams with valuable insights for post-incident analysis, reliability reporting, and proactive system monitoring. With this connector, users can automate the data flow and gain deeper visibility into incidents and response metrics, improving reliability and operational efficiency. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_token` | `string` | API Token. Bot token to use for authenticating with the FireHydrant API. You can find or create a bot token by logging into your organization and visiting the Bot users page at https://app.firehydrant.io/organizations/bots. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| enviroments | id | DefaultPaginator | ✅ | ❌ | +| services | id | DefaultPaginator | ✅ | ❌ | +| functionalities | id | DefaultPaginator | ✅ | ❌ | +| teams | id | DefaultPaginator | ✅ | ❌ | +| webhooks | id | DefaultPaginator | ✅ | ❌ | +| signals_on_call | id | DefaultPaginator | ✅ | ❌ | +| changes_events | id | DefaultPaginator | ✅ | ❌ | +| changes | id | DefaultPaginator | ✅ | ❌ | +| entitlements | slug | No pagination | ✅ | ❌ | +| incidents | id | DefaultPaginator | ✅ | ❌ | +| incident_roles | id | DefaultPaginator | ✅ | ❌ | +| incident_tags | name | DefaultPaginator | ✅ | ❌ | +| incident_types | id | DefaultPaginator | ✅ | ❌ | +| integrations | id | No pagination | ✅ | ❌ | +| users | id | DefaultPaginator | ✅ | ❌ | +| reports | bucket | No pagination | ✅ | ❌ | +| runbook_actions | id | DefaultPaginator | ✅ | ❌ | +| runbook_executions | id | DefaultPaginator | ✅ | ❌ | +| runbooks | id | DefaultPaginator | ✅ | ❌ | +| runbook_audits | id | DefaultPaginator | ✅ | ❌ | +| nunc_connections | id | DefaultPaginator | ✅ | ❌ | +| measurement_definitions | id | DefaultPaginator | ✅ | ❌ | +| phases | id | No pagination | ✅ | ❌ | +| priorities | slug | DefaultPaginator | ✅ | ❌ | +| severities | slug | DefaultPaginator | ✅ | ❌ | +| severity_matrix_conditions | id | DefaultPaginator | ✅ | ❌ | +| severity_matrix_impacts | id | DefaultPaginator | ✅ | ❌ | +| scheduled_maintenances | id | DefaultPaginator | ✅ | ❌ | +| infrastructures | id | DefaultPaginator | ✅ | ❌ | +| custom_fields_definitions | field_id | No pagination | ✅ | ❌ | +| post_mortems_reports | id | DefaultPaginator | ✅ | ❌ | +| post_mortems_questions | id | DefaultPaginator | ✅ | ❌ | +| alerts | id | DefaultPaginator | ✅ | ❌ | +| tickets | id | DefaultPaginator | ✅ | ❌ | +| ticketing_projects | id | DefaultPaginator | ✅ | ❌ | +| ticketing_priorities | id | No pagination | ✅ | ❌ | +| ticket_tags | name | DefaultPaginator | ✅ | ❌ | +| task_lists | id | DefaultPaginator | ✅ | ❌ | +| checklist_templates | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50544](https://github.com/airbytehq/airbyte/pull/50544) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50022](https://github.com/airbytehq/airbyte/pull/50022) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49520](https://github.com/airbytehq/airbyte/pull/49520) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49205](https://github.com/airbytehq/airbyte/pull/49205) | Update dependencies | +| 0.0.1 | 2024-11-08 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/fleetio.md b/docs/integrations/sources/fleetio.md index 2bdc32aff985..26fe18eb9a69 100644 --- a/docs/integrations/sources/fleetio.md +++ b/docs/integrations/sources/fleetio.md @@ -51,6 +51,12 @@ Our source connector adheres to the standard rate limiting with the Airbyte low- | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:------------------------------------------------| +| 0.2.7 | 2024-12-28 | [50576](https://github.com/airbytehq/airbyte/pull/50576) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50053](https://github.com/airbytehq/airbyte/pull/50053) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49495](https://github.com/airbytehq/airbyte/pull/49495) | Update dependencies | +| 0.2.4 | 2024-12-12 | [49162](https://github.com/airbytehq/airbyte/pull/49162) | Update dependencies | +| 0.2.3 | 2024-12-11 | [48943](https://github.com/airbytehq/airbyte/pull/48943) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.2 | 2024-11-04 | [48145](https://github.com/airbytehq/airbyte/pull/48145) | Update dependencies | | 0.2.1 | 2024-10-29 | [47932](https://github.com/airbytehq/airbyte/pull/47932) | Update dependencies | | 0.2.0 | 2024-08-22 | [44567](https://github.com/airbytehq/airbyte/pull/44567) | Refactor connector to manifest-only format | | 0.1.11 | 2024-08-17 | [44268](https://github.com/airbytehq/airbyte/pull/44268) | Update dependencies | diff --git a/docs/integrations/sources/flexmail.md b/docs/integrations/sources/flexmail.md new file mode 100644 index 000000000000..089cad9bd415 --- /dev/null +++ b/docs/integrations/sources/flexmail.md @@ -0,0 +1,34 @@ +# Flexmail +The Airbyte connector for [Flexmail](https://flexmail.be/) enables seamless data integration from Flexmail, a comprehensive email marketing platform, into various data warehouses and analytics tools. With this connector, users can efficiently synchronize Flexmail data—such as campaign details, subscriber information, and engagement metrics—allowing for unified insights and advanced reporting across platforms. Perfect for businesses aiming to centralize their marketing data for enhanced visibility and decision-making. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `account_id` | `string` | Account ID. Your Flexmail account ID. You can find it in your Flexmail account settings. | | +| `personal_access_token` | `string` | Personal Access Token. A personal access token for API authentication. Manage your tokens in Flexmail under Settings > API > Personal access tokens. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| contacts | id | DefaultPaginator | ✅ | ❌ | +| custom_fields | id | No pagination | ✅ | ❌ | +| interests | id | No pagination | ✅ | ❌ | +| segments | id | No pagination | ✅ | ❌ | +| sources | id | DefaultPaginator | ✅ | ❌ | +| webhook_events | | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50534](https://github.com/airbytehq/airbyte/pull/50534) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50059](https://github.com/airbytehq/airbyte/pull/50059) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49492](https://github.com/airbytehq/airbyte/pull/49492) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49199](https://github.com/airbytehq/airbyte/pull/49199) | Update dependencies | +| 0.0.1 | 2024-11-08 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/flexport.md b/docs/integrations/sources/flexport.md index 641bac7a6673..962c325b062c 100644 --- a/docs/integrations/sources/flexport.md +++ b/docs/integrations/sources/flexport.md @@ -49,6 +49,11 @@ Authentication uses a pre-created API token which can be [created in the UI](htt | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------ | +| 0.3.7 | 2024-12-28 | [50565](https://github.com/airbytehq/airbyte/pull/50565) | Update dependencies | +| 0.3.6 | 2024-12-21 | [50031](https://github.com/airbytehq/airbyte/pull/50031) | Update dependencies | +| 0.3.5 | 2024-12-14 | [49508](https://github.com/airbytehq/airbyte/pull/49508) | Update dependencies | +| 0.3.4 | 2024-12-12 | [49210](https://github.com/airbytehq/airbyte/pull/49210) | Update dependencies | +| 0.3.3 | 2024-11-04 | [48291](https://github.com/airbytehq/airbyte/pull/48291) | Update dependencies | | 0.3.2 | 2024-10-29 | [47898](https://github.com/airbytehq/airbyte/pull/47898) | Update dependencies | | 0.3.1 | 2024-10-28 | [47580](https://github.com/airbytehq/airbyte/pull/47580) | Update dependencies | | 0.3.0 | 2024-10-05 | [46416](https://github.com/airbytehq/airbyte/pull/46416) | Migrate to Manifest-only CDK | diff --git a/docs/integrations/sources/float.md b/docs/integrations/sources/float.md index 0b2abdeb1d08..2f78da4469ff 100644 --- a/docs/integrations/sources/float.md +++ b/docs/integrations/sources/float.md @@ -35,6 +35,10 @@ Float.com enables teams to plan and allocate resources effectively, manage team | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50552](https://github.com/airbytehq/airbyte/pull/50552) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50033](https://github.com/airbytehq/airbyte/pull/50033) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49476](https://github.com/airbytehq/airbyte/pull/49476) | Update dependencies | +| 0.0.2 | 2024-12-12 | [48211](https://github.com/airbytehq/airbyte/pull/48211) | Update dependencies | | 0.0.1 | 2024-10-23 | | Initial release by [@bala-ceg](https://github.com/bala-ceg) via Connector Builder | diff --git a/docs/integrations/sources/flowlu.md b/docs/integrations/sources/flowlu.md new file mode 100644 index 000000000000..7612a9ab94ec --- /dev/null +++ b/docs/integrations/sources/flowlu.md @@ -0,0 +1,64 @@ +# Flowlu +Flowlu connector enables seamless data integration between Flowlu, a project management and CRM platform, and various destinations supported by Airbyte. With this connector, users can automate the flow of project, finance, and CRM data into their preferred analytics or storage solutions for enhanced data analysis and reporting. This integration streamlines data syncing, reducing manual data transfer efforts and enhancing productivity. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. The API key to use for authentication | | +| `company` | `string` | Sub Domain information for the Company. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| tasks | id | DefaultPaginator | ✅ | ❌ | +| custom_fields | id | DefaultPaginator | ✅ | ❌ | +| agile_workflows | id | DefaultPaginator | ✅ | ❌ | +| st_projects_users | | DefaultPaginator | ✅ | ❌ | +| projects | id | DefaultPaginator | ✅ | ❌ | +| account | id | DefaultPaginator | ✅ | ❌ | +| agile_epics | id | DefaultPaginator | ✅ | ❌ | +| loss_reason | id | DefaultPaginator | ✅ | ❌ | +| pipeline | | DefaultPaginator | ✅ | ❌ | +| lead | id | DefaultPaginator | ✅ | ❌ | +| emails | id | DefaultPaginator | ✅ | ❌ | +| invoice | id | DefaultPaginator | ✅ | ❌ | +| customer_payment | id | DefaultPaginator | ✅ | ❌ | +| bank_account | id | DefaultPaginator | ✅ | ❌ | +| agile_stages | id | DefaultPaginator | ✅ | ❌ | +| agile_sprints | id | DefaultPaginator | ✅ | ❌ | +| agile_issues | id | DefaultPaginator | ✅ | ❌ | +| task_lists | id | DefaultPaginator | ✅ | ❌ | +| lists | id | DefaultPaginator | ✅ | ❌ | +| calendar | id | DefaultPaginator | ✅ | ❌ | +| agile_issue_relation_types | id | DefaultPaginator | ✅ | ❌ | +| agile_issue_relation_names | id | DefaultPaginator | ✅ | ❌ | +| agile_issue_type | id | DefaultPaginator | ✅ | ❌ | +| agile_categories | id | DefaultPaginator | ✅ | ❌ | +| custom_fields_field_sets | id | DefaultPaginator | ✅ | ❌ | +| product_list | id | DefaultPaginator | ✅ | ❌ | +| product_categories | id | DefaultPaginator | ✅ | ❌ | +| product_price_list | id | DefaultPaginator | ✅ | ❌ | +| product_manufacturer | id | DefaultPaginator | ✅ | ❌ | +| timesheet | id | DefaultPaginator | ✅ | ❌ | +| estimates | id | DefaultPaginator | ✅ | ❌ | +| transactions | id | DefaultPaginator | ✅ | ❌ | +| invoice_items | id | DefaultPaginator | ✅ | ❌ | +| invoice_contacts | id | DefaultPaginator | ✅ | ❌ | +| project_observers | id | DefaultPaginator | ✅ | ❌ | +| task_workflows | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50538](https://github.com/airbytehq/airbyte/pull/50538) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50034](https://github.com/airbytehq/airbyte/pull/50034) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49518](https://github.com/airbytehq/airbyte/pull/49518) | Update dependencies | +| 0.0.2 | 2024-12-12 | [48921](https://github.com/airbytehq/airbyte/pull/48921) | Update dependencies | +| 0.0.1 | 2024-11-11 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/formbricks.md b/docs/integrations/sources/formbricks.md new file mode 100644 index 000000000000..0215ba6901b9 --- /dev/null +++ b/docs/integrations/sources/formbricks.md @@ -0,0 +1,33 @@ +# Formbricks +The Airbyte connector for [Formbricks](https://www.formbricks.com/) enables seamless data integration by pulling customer feedback and form data from Formbricks directly into your data warehouse. This connector allows you to automate data syncing for enhanced analytics, providing valuable insights into user behavior and satisfaction across platforms. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use. You can generate and find it in your Postman account settings. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| surveys | id | No pagination | ✅ | ❌ | +| action_classes | id | No pagination | ✅ | ❌ | +| attribute_classes | id | No pagination | ✅ | ❌ | +| identified_peoples | id | No pagination | ✅ | ❌ | +| responses | id | DefaultPaginator | ✅ | ❌ | +| webhooks | id | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50548](https://github.com/airbytehq/airbyte/pull/50548) | Update dependencies | +| 0.0.4 | 2024-12-21 | [49993](https://github.com/airbytehq/airbyte/pull/49993) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49525](https://github.com/airbytehq/airbyte/pull/49525) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49167](https://github.com/airbytehq/airbyte/pull/49167) | Update dependencies | +| 0.0.1 | 2024-11-08 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/free-agent-connector.md b/docs/integrations/sources/free-agent-connector.md index c48b7d7f1983..6fa624aba1bc 100644 --- a/docs/integrations/sources/free-agent-connector.md +++ b/docs/integrations/sources/free-agent-connector.md @@ -53,6 +53,11 @@ Download all your data from FreeAgent, a friendly and easy to use cloud based ac | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.7 | 2024-12-28 | [50557](https://github.com/airbytehq/airbyte/pull/50557) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50043](https://github.com/airbytehq/airbyte/pull/50043) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49537](https://github.com/airbytehq/airbyte/pull/49537) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49183](https://github.com/airbytehq/airbyte/pull/49183) | Update dependencies | +| 0.0.3 | 2024-11-04 | [48277](https://github.com/airbytehq/airbyte/pull/48277) | Update dependencies | | 0.0.2 | 2024-10-29 | [47874](https://github.com/airbytehq/airbyte/pull/47874) | Update dependencies | | 0.0.1 | 2024-09-24 | | Initial release by [@craigbloodworth](https://github.com/craigbloodworth) via Connector Builder | diff --git a/docs/integrations/sources/freightview.md b/docs/integrations/sources/freightview.md new file mode 100644 index 000000000000..92166c65e7ba --- /dev/null +++ b/docs/integrations/sources/freightview.md @@ -0,0 +1,30 @@ +# Freightview +An **Airbyte connector for Freightview** enables seamless data integration by extracting and syncing shipping data from Freightview to your target data warehouses or applications. This connector automates the retrieval of essential shipping details, such as quotes, tracking, and shipment reports, allowing businesses to efficiently analyze and manage logistics operations in a centralized system. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `client_id` | `string` | Client ID. | | +| `client_secret` | `string` | Client Secret. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| shipments | shipmentId | DefaultPaginator | ✅ | ❌ | +| quotes | quoteId | No pagination | ✅ | ❌ | +| tracking | createdDate | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.4 | 2024-12-28 | [50520](https://github.com/airbytehq/airbyte/pull/50520) | Update dependencies | +| 0.0.3 | 2024-12-21 | [49502](https://github.com/airbytehq/airbyte/pull/49502) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49201](https://github.com/airbytehq/airbyte/pull/49201) | Update dependencies | +| 0.0.1 | 2024-10-28 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/freshbooks.md b/docs/integrations/sources/freshbooks.md new file mode 100644 index 000000000000..361f330944e9 --- /dev/null +++ b/docs/integrations/sources/freshbooks.md @@ -0,0 +1,47 @@ +# FreshBooks +FreshBooks connector seamlessly syncs invoicing, expenses, and client data from FreshBooks into data warehouses or analytics platforms. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `client_id` | `string` | Client ID. | | +| `client_secret` | `string` | Client secret. | | +| `redirect_uri` | `string` | Redirect Uri. | | +| `account_id` | `string` | Account Id. | | +| `client_refresh_token` | `string` | Refresh token. | | +| `oauth_access_token` | `string` | Access token. The current access token. This field might be overridden by the connector based on the token refresh endpoint response. | | +| `oauth_token_expiry_date` | `string` | Token expiry date. The date the current access token expires in. This field might be overridden by the connector based on the token refresh endpoint response. | | +| `business_uuid` | `string` | Business uuid. | | + +Read [this](https://documenter.getpostman.com/view/3322108/S1ERwwza#intro) section carefully to get your Account Id and Business UUID. + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| user | | DefaultPaginator | ✅ | ❌ | +| clients | | DefaultPaginator | ✅ | ❌ | +| invoices | id.invoiceid | DefaultPaginator | ✅ | ❌ | +| expenses | id.expenseid | DefaultPaginator | ✅ | ❌ | +| expense_summaries | | DefaultPaginator | ✅ | ❌ | +| expense_categories | id | DefaultPaginator | ✅ | ❌ | +| invoice_details | invoiceid | DefaultPaginator | ✅ | ❌ | +| expense_details | expenseid | DefaultPaginator | ✅ | ❌ | +| accounts | | DefaultPaginator | ✅ | ❌ | +| taxes | taxid | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50525](https://github.com/airbytehq/airbyte/pull/50525) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50000](https://github.com/airbytehq/airbyte/pull/50000) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49498](https://github.com/airbytehq/airbyte/pull/49498) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49209](https://github.com/airbytehq/airbyte/pull/49209) | Update dependencies | +| 0.0.2 | 2024-12-11 | [48942](https://github.com/airbytehq/airbyte/pull/48942) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-27 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/freshcaller.md b/docs/integrations/sources/freshcaller.md index e289a4a17e80..1f55d4a5c7a9 100644 --- a/docs/integrations/sources/freshcaller.md +++ b/docs/integrations/sources/freshcaller.md @@ -46,6 +46,9 @@ Please read [How to find your API key](https://support.freshdesk.com/en/support/ | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------ | +| 0.4.21 | 2025-01-04 | [50542](https://github.com/airbytehq/airbyte/pull/50542) | Update dependencies | +| 0.4.20 | 2024-12-21 | [50056](https://github.com/airbytehq/airbyte/pull/50056) | Update dependencies | +| 0.4.19 | 2024-12-11 | [48897](https://github.com/airbytehq/airbyte/pull/48897) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.4.18 | 2024-10-29 | [47808](https://github.com/airbytehq/airbyte/pull/47808) | Update dependencies | | 0.4.17 | 2024-10-23 | [47065](https://github.com/airbytehq/airbyte/pull/47065) | Update dependencies | | 0.4.16 | 2024-10-12 | [46796](https://github.com/airbytehq/airbyte/pull/46796) | Update dependencies | diff --git a/docs/integrations/sources/freshsales.md b/docs/integrations/sources/freshsales.md index 04696d3f8d88..c7f7292ab0d3 100644 --- a/docs/integrations/sources/freshsales.md +++ b/docs/integrations/sources/freshsales.md @@ -68,6 +68,10 @@ The Freshsales connector should not run into Freshsales API limitations under no | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :----------------------------------------------------------- | +| 1.1.5 | 2024-12-28 | [50527](https://github.com/airbytehq/airbyte/pull/50527) | Update dependencies | +| 1.1.4 | 2024-12-21 | [50004](https://github.com/airbytehq/airbyte/pull/50004) | Update dependencies | +| 1.1.3 | 2024-12-14 | [49473](https://github.com/airbytehq/airbyte/pull/49473) | Update dependencies | +| 1.1.2 | 2024-12-12 | [49203](https://github.com/airbytehq/airbyte/pull/49203) | Update dependencies | | 1.1.1 | 2024-10-28 | [44277](https://github.com/airbytehq/airbyte/pull/44277) | Update dependencies | | 1.1.0 | 2024-08-15 | [44149](https://github.com/airbytehq/airbyte/pull/44149) | Refactor connector to manifest-only format | | 1.0.14 | 2024-08-12 | [43904](https://github.com/airbytehq/airbyte/pull/43904) | Update dependencies | diff --git a/docs/integrations/sources/freshservice.md b/docs/integrations/sources/freshservice.md index 56bb63f2c958..e1f6db2f10e1 100644 --- a/docs/integrations/sources/freshservice.md +++ b/docs/integrations/sources/freshservice.md @@ -57,6 +57,11 @@ Please read [How to find your API key](https://api.freshservice.com/#authenticat | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- |:---------------------------------------------------------------------------------------| +| 1.4.8 | 2024-12-28 | [50574](https://github.com/airbytehq/airbyte/pull/50574) | Update dependencies | +| 1.4.7 | 2024-12-21 | [50026](https://github.com/airbytehq/airbyte/pull/50026) | Update dependencies | +| 1.4.6 | 2024-12-14 | [49519](https://github.com/airbytehq/airbyte/pull/49519) | Update dependencies | +| 1.4.5 | 2024-12-12 | [49187](https://github.com/airbytehq/airbyte/pull/49187) | Update dependencies | +| 1.4.4 | 2024-12-11 | [48939](https://github.com/airbytehq/airbyte/pull/48939) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 1.4.3 | 2024-10-29 | [47732](https://github.com/airbytehq/airbyte/pull/47732) | Update dependencies | | 1.4.2 | 2024-10-28 | [47449](https://github.com/airbytehq/airbyte/pull/47449) | Update dependencies | | 1.4.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/front.md b/docs/integrations/sources/front.md index 5666b9d069c2..fe9cd307fff3 100644 --- a/docs/integrations/sources/front.md +++ b/docs/integrations/sources/front.md @@ -62,6 +62,9 @@ Visit `https://dev.frontapp.com/docs/create-and-revoke-api-tokens` for getting y | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.5 | 2024-12-21 | [50005](https://github.com/airbytehq/airbyte/pull/50005) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49536](https://github.com/airbytehq/airbyte/pull/49536) | Update dependencies | +| 0.0.3 | 2024-12-12 | [48960](https://github.com/airbytehq/airbyte/pull/48960) | Update dependencies | | 0.0.2 | 2024-10-29 | [47759](https://github.com/airbytehq/airbyte/pull/47759) | Update dependencies | | 0.0.1 | 2024-09-11 | [45387](https://github.com/airbytehq/airbyte/pull/45387) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/fulcrum.md b/docs/integrations/sources/fulcrum.md new file mode 100644 index 000000000000..7551aa951192 --- /dev/null +++ b/docs/integrations/sources/fulcrum.md @@ -0,0 +1,47 @@ +# Fulcrum +Airbyte connector for Fulcrum would enable seamless data extraction from the Fulcrum platform, allowing users to sync survey and field data with their data warehouses or other applications. This connector would facilitate automated, scheduled transfers of structured data, improving analytics, reporting, and decision-making processes by integrating Fulcrum's powerful field data collection capabilities with a broader data ecosystem. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use. Find it at https://web.fulcrumapp.com/settings/api | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| forms | id | DefaultPaginator | ✅ | ❌ | +| users | id | DefaultPaginator | ✅ | ❌ | +| workflows | | DefaultPaginator | ✅ | ❌ | +| webhooks | id | DefaultPaginator | ✅ | ❌ | +| changesets | id | DefaultPaginator | ✅ | ❌ | +| records | id | DefaultPaginator | ✅ | ❌ | +| signatures | record_id | DefaultPaginator | ✅ | ❌ | +| projects | id | DefaultPaginator | ✅ | ❌ | +| layers | id | DefaultPaginator | ✅ | ❌ | +| classification_sets | id | DefaultPaginator | ✅ | ❌ | +| choice_lists | id | DefaultPaginator | ✅ | ❌ | +| groups | id | DefaultPaginator | ✅ | ❌ | +| memberships | id | DefaultPaginator | ✅ | ❌ | +| roles | id | DefaultPaginator | ✅ | ❌ | +| authorizations | id | DefaultPaginator | ✅ | ❌ | +| photos | record_id | DefaultPaginator | ✅ | ❌ | +| audio | record_id | DefaultPaginator | ✅ | ❌ | +| videos | record_id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50560](https://github.com/airbytehq/airbyte/pull/50560) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50038](https://github.com/airbytehq/airbyte/pull/50038) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49512](https://github.com/airbytehq/airbyte/pull/49512) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49200](https://github.com/airbytehq/airbyte/pull/49200) | Update dependencies | +| 0.0.3 | 2024-11-05 | [48358](https://github.com/airbytehq/airbyte/pull/48358) | Revert to source-declarative-manifest v5.17.0 | +| 0.0.2 | 2024-11-05 | [48333](https://github.com/airbytehq/airbyte/pull/48333) | Update dependencies | +| 0.0.1 | 2024-10-21 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/fullstory.md b/docs/integrations/sources/fullstory.md index 4ce6533b75b8..44f35edd1b10 100644 --- a/docs/integrations/sources/fullstory.md +++ b/docs/integrations/sources/fullstory.md @@ -73,6 +73,10 @@ FullStory [API reference](https://api.fullstory.com) has v1 at present. The conn | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------- | :------------- | +| 0.2.5 | 2025-01-04 | [50587](https://github.com/airbytehq/airbyte/pull/50587) | Update dependencies | +| 0.2.4 | 2024-12-21 | [50050](https://github.com/airbytehq/airbyte/pull/50050) | Update dependencies | +| 0.2.3 | 2024-12-14 | [49524](https://github.com/airbytehq/airbyte/pull/49524) | Update dependencies | +| 0.2.2 | 2024-12-12 | [49156](https://github.com/airbytehq/airbyte/pull/49156) | Update dependencies | | 0.2.1 | 2024-10-29 | [47794](https://github.com/airbytehq/airbyte/pull/47794) | Update dependencies | | 0.2.0 | 2024-08-23 | [44612](https://github.com/airbytehq/airbyte/pull/44612) | Refactor connector to manifest-only format | | 0.1.14 | 2024-08-17 | [44222](https://github.com/airbytehq/airbyte/pull/44222) | Update dependencies | diff --git a/docs/integrations/sources/gainsight-px.md b/docs/integrations/sources/gainsight-px.md index fe17f7edcdd1..735641beeb4b 100644 --- a/docs/integrations/sources/gainsight-px.md +++ b/docs/integrations/sources/gainsight-px.md @@ -74,6 +74,10 @@ Gainsight-PX-API's [API reference](https://gainsightpx.docs.apiary.io/) has v1 a | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- |:----------------------------------------| +| 0.2.6 | 2024-12-28 | [50511](https://github.com/airbytehq/airbyte/pull/50511) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50041](https://github.com/airbytehq/airbyte/pull/50041) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49533](https://github.com/airbytehq/airbyte/pull/49533) | Update dependencies | +| 0.2.3 | 2024-12-12 | [48195](https://github.com/airbytehq/airbyte/pull/48195) | Update dependencies | | 0.2.2 | 2024-10-29 | [47864](https://github.com/airbytehq/airbyte/pull/47864) | Update dependencies | | 0.2.1 | 2024-10-28 | [47626](https://github.com/airbytehq/airbyte/pull/47626) | Update dependencies | | 0.2.0 | 2024-08-19 | [44414](https://github.com/airbytehq/airbyte/pull/44414) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/gcs.md b/docs/integrations/sources/gcs.md index 08b8a9b6cc00..8734c6fe7fcc 100644 --- a/docs/integrations/sources/gcs.md +++ b/docs/integrations/sources/gcs.md @@ -236,50 +236,51 @@ Google Cloud Storage (GCS) supports following file formats: | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:------------------------------------------------------------------------| -| 0.8.1 | 2024-10-28 | [45923](https://github.com/airbytehq/airbyte/pull/45923) | Update logging | -| 0.8.0 | 2024-10-28 | [45414](https://github.com/airbytehq/airbyte/pull/45414) | Add support for OAuth authentication | -| 0.7.4 | 2024-10-12 | [46858](https://github.com/airbytehq/airbyte/pull/46858) | Update dependencies | -| 0.7.3 | 2024-10-05 | [46458](https://github.com/airbytehq/airbyte/pull/46458) | Update dependencies | -| 0.7.2 | 2024-09-28 | [46178](https://github.com/airbytehq/airbyte/pull/46178) | Update dependencies | -| 0.7.1 | 2024-09-24 | [45850](https://github.com/airbytehq/airbyte/pull/45850) | Add integration tests | -| 0.7.0 | 2024-09-24 | [45671](https://github.com/airbytehq/airbyte/pull/45671) | Add .zip files support | -| 0.6.9 | 2024-09-21 | [45798](https://github.com/airbytehq/airbyte/pull/45798) | Update dependencies | -| 0.6.8 | 2024-09-19 | [45092](https://github.com/airbytehq/airbyte/pull/45092) | Update CDK v5; Fix OSError not raised in stream_reader.open_file | -| 0.6.7 | 2024-09-14 | [45492](https://github.com/airbytehq/airbyte/pull/45492) | Update dependencies | -| 0.6.6 | 2024-09-07 | [45232](https://github.com/airbytehq/airbyte/pull/45232) | Update dependencies | -| 0.6.5 | 2024-08-31 | [45010](https://github.com/airbytehq/airbyte/pull/45010) | Update dependencies | -| 0.6.4 | 2024-08-27 | [44796](https://github.com/airbytehq/airbyte/pull/44796) | Fix empty list of globs when prefix empty | -| 0.6.3 | 2024-08-26 | [44781](https://github.com/airbytehq/airbyte/pull/44781) | Set file signature URL expiration limit default to max | -| 0.6.2 | 2024-08-24 | [44733](https://github.com/airbytehq/airbyte/pull/44733) | Update dependencies | -| 0.6.1 | 2024-08-17 | [44285](https://github.com/airbytehq/airbyte/pull/44285) | Update dependencies | -| 0.6.0 | 2024-08-15 | [44015](https://github.com/airbytehq/airbyte/pull/44015) | Add support for all FileBasedSpec file types | -| 0.5.0 | 2024-08-14 | [44070](https://github.com/airbytehq/airbyte/pull/44070) | Update CDK v4 and Python 3.10 dependencies | -| 0.4.15 | 2024-08-12 | [43733](https://github.com/airbytehq/airbyte/pull/43733) | Update dependencies | -| 0.4.14 | 2024-08-10 | [43512](https://github.com/airbytehq/airbyte/pull/43512) | Update dependencies | -| 0.4.13 | 2024-08-03 | [43236](https://github.com/airbytehq/airbyte/pull/43236) | Update dependencies | -| 0.4.12 | 2024-07-27 | [42693](https://github.com/airbytehq/airbyte/pull/42693) | Update dependencies | -| 0.4.11 | 2024-07-20 | [42312](https://github.com/airbytehq/airbyte/pull/42312) | Update dependencies | -| 0.4.10 | 2024-07-13 | [41865](https://github.com/airbytehq/airbyte/pull/41865) | Update dependencies | -| 0.4.9 | 2024-07-10 | [41430](https://github.com/airbytehq/airbyte/pull/41430) | Update dependencies | -| 0.4.8 | 2024-07-09 | [41148](https://github.com/airbytehq/airbyte/pull/41148) | Update dependencies | -| 0.4.7 | 2024-07-06 | [41015](https://github.com/airbytehq/airbyte/pull/41015) | Update dependencies | -| 0.4.6 | 2024-06-26 | [40540](https://github.com/airbytehq/airbyte/pull/40540) | Update dependencies | -| 0.4.5 | 2024-06-25 | [40391](https://github.com/airbytehq/airbyte/pull/40391) | Update dependencies | -| 0.4.4 | 2024-06-24 | [40234](https://github.com/airbytehq/airbyte/pull/40234) | Update dependencies | -| 0.4.3 | 2024-06-22 | [40089](https://github.com/airbytehq/airbyte/pull/40089) | Update dependencies | -| 0.4.2 | 2024-06-06 | [39255](https://github.com/airbytehq/airbyte/pull/39255) | [autopull] Upgrade base image to v1.2.2 | -| 0.4.1 | 2024-05-29 | [38696](https://github.com/airbytehq/airbyte/pull/38696) | Avoid error on empty stream when running discover | -| 0.4.0 | 2024-03-21 | [36373](https://github.com/airbytehq/airbyte/pull/36373) | Add Gzip and Bzip compression support. Manage dependencies with Poetry. | -| 0.3.7 | 2024-02-06 | [34936](https://github.com/airbytehq/airbyte/pull/34936) | Bump CDK version to avoid missing SyncMode errors | -| 0.3.6 | 2024-01-30 | [34681](https://github.com/airbytehq/airbyte/pull/34681) | Unpin CDK version to make compatible with the Concurrent CDK | -| 0.3.5 | 2024-01-30 | [34661](https://github.com/airbytehq/airbyte/pull/34661) | Pin CDK version until upgrade for compatibility with the Concurrent CDK | -| 0.3.4 | 2024-01-11 | [34158](https://github.com/airbytehq/airbyte/pull/34158) | Fix issue in stream reader for document file type parser | -| 0.3.3 | 2023-12-06 | [33187](https://github.com/airbytehq/airbyte/pull/33187) | Bump CDK version to hide source-defined primary key | -| 0.3.2 | 2023-11-16 | [32608](https://github.com/airbytehq/airbyte/pull/32608) | Improve document file type parser | -| 0.3.1 | 2023-11-13 | [32357](https://github.com/airbytehq/airbyte/pull/32357) | Improve spec schema | -| 0.3.0 | 2023-10-11 | [31212](https://github.com/airbytehq/airbyte/pull/31212) | Migrated to file based CDK | -| 0.2.0 | 2023-06-26 | [27725](https://github.com/airbytehq/airbyte/pull/27725) | License Update: Elv2 | -| 0.1.0 | 2023-02-16 | [23186](https://github.com/airbytehq/airbyte/pull/23186) | New Source: GCS | +| 0.8.2 | 2024-11-25 | [48647](https://github.com/airbytehq/airbyte/pull/48647) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.8.1 | 2024-10-28 | [45923](https://github.com/airbytehq/airbyte/pull/45923) | Update logging | +| 0.8.0 | 2024-10-28 | [45414](https://github.com/airbytehq/airbyte/pull/45414) | Add support for OAuth authentication | +| 0.7.4 | 2024-10-12 | [46858](https://github.com/airbytehq/airbyte/pull/46858) | Update dependencies | +| 0.7.3 | 2024-10-05 | [46458](https://github.com/airbytehq/airbyte/pull/46458) | Update dependencies | +| 0.7.2 | 2024-09-28 | [46178](https://github.com/airbytehq/airbyte/pull/46178) | Update dependencies | +| 0.7.1 | 2024-09-24 | [45850](https://github.com/airbytehq/airbyte/pull/45850) | Add integration tests | +| 0.7.0 | 2024-09-24 | [45671](https://github.com/airbytehq/airbyte/pull/45671) | Add .zip files support | +| 0.6.9 | 2024-09-21 | [45798](https://github.com/airbytehq/airbyte/pull/45798) | Update dependencies | +| 0.6.8 | 2024-09-19 | [45092](https://github.com/airbytehq/airbyte/pull/45092) | Update CDK v5; Fix OSError not raised in stream_reader.open_file | +| 0.6.7 | 2024-09-14 | [45492](https://github.com/airbytehq/airbyte/pull/45492) | Update dependencies | +| 0.6.6 | 2024-09-07 | [45232](https://github.com/airbytehq/airbyte/pull/45232) | Update dependencies | +| 0.6.5 | 2024-08-31 | [45010](https://github.com/airbytehq/airbyte/pull/45010) | Update dependencies | +| 0.6.4 | 2024-08-27 | [44796](https://github.com/airbytehq/airbyte/pull/44796) | Fix empty list of globs when prefix empty | +| 0.6.3 | 2024-08-26 | [44781](https://github.com/airbytehq/airbyte/pull/44781) | Set file signature URL expiration limit default to max | +| 0.6.2 | 2024-08-24 | [44733](https://github.com/airbytehq/airbyte/pull/44733) | Update dependencies | +| 0.6.1 | 2024-08-17 | [44285](https://github.com/airbytehq/airbyte/pull/44285) | Update dependencies | +| 0.6.0 | 2024-08-15 | [44015](https://github.com/airbytehq/airbyte/pull/44015) | Add support for all FileBasedSpec file types | +| 0.5.0 | 2024-08-14 | [44070](https://github.com/airbytehq/airbyte/pull/44070) | Update CDK v4 and Python 3.10 dependencies | +| 0.4.15 | 2024-08-12 | [43733](https://github.com/airbytehq/airbyte/pull/43733) | Update dependencies | +| 0.4.14 | 2024-08-10 | [43512](https://github.com/airbytehq/airbyte/pull/43512) | Update dependencies | +| 0.4.13 | 2024-08-03 | [43236](https://github.com/airbytehq/airbyte/pull/43236) | Update dependencies | +| 0.4.12 | 2024-07-27 | [42693](https://github.com/airbytehq/airbyte/pull/42693) | Update dependencies | +| 0.4.11 | 2024-07-20 | [42312](https://github.com/airbytehq/airbyte/pull/42312) | Update dependencies | +| 0.4.10 | 2024-07-13 | [41865](https://github.com/airbytehq/airbyte/pull/41865) | Update dependencies | +| 0.4.9 | 2024-07-10 | [41430](https://github.com/airbytehq/airbyte/pull/41430) | Update dependencies | +| 0.4.8 | 2024-07-09 | [41148](https://github.com/airbytehq/airbyte/pull/41148) | Update dependencies | +| 0.4.7 | 2024-07-06 | [41015](https://github.com/airbytehq/airbyte/pull/41015) | Update dependencies | +| 0.4.6 | 2024-06-26 | [40540](https://github.com/airbytehq/airbyte/pull/40540) | Update dependencies | +| 0.4.5 | 2024-06-25 | [40391](https://github.com/airbytehq/airbyte/pull/40391) | Update dependencies | +| 0.4.4 | 2024-06-24 | [40234](https://github.com/airbytehq/airbyte/pull/40234) | Update dependencies | +| 0.4.3 | 2024-06-22 | [40089](https://github.com/airbytehq/airbyte/pull/40089) | Update dependencies | +| 0.4.2 | 2024-06-06 | [39255](https://github.com/airbytehq/airbyte/pull/39255) | [autopull] Upgrade base image to v1.2.2 | +| 0.4.1 | 2024-05-29 | [38696](https://github.com/airbytehq/airbyte/pull/38696) | Avoid error on empty stream when running discover | +| 0.4.0 | 2024-03-21 | [36373](https://github.com/airbytehq/airbyte/pull/36373) | Add Gzip and Bzip compression support. Manage dependencies with Poetry. | +| 0.3.7 | 2024-02-06 | [34936](https://github.com/airbytehq/airbyte/pull/34936) | Bump CDK version to avoid missing SyncMode errors | +| 0.3.6 | 2024-01-30 | [34681](https://github.com/airbytehq/airbyte/pull/34681) | Unpin CDK version to make compatible with the Concurrent CDK | +| 0.3.5 | 2024-01-30 | [34661](https://github.com/airbytehq/airbyte/pull/34661) | Pin CDK version until upgrade for compatibility with the Concurrent CDK | +| 0.3.4 | 2024-01-11 | [34158](https://github.com/airbytehq/airbyte/pull/34158) | Fix issue in stream reader for document file type parser | +| 0.3.3 | 2023-12-06 | [33187](https://github.com/airbytehq/airbyte/pull/33187) | Bump CDK version to hide source-defined primary key | +| 0.3.2 | 2023-11-16 | [32608](https://github.com/airbytehq/airbyte/pull/32608) | Improve document file type parser | +| 0.3.1 | 2023-11-13 | [32357](https://github.com/airbytehq/airbyte/pull/32357) | Improve spec schema | +| 0.3.0 | 2023-10-11 | [31212](https://github.com/airbytehq/airbyte/pull/31212) | Migrated to file based CDK | +| 0.2.0 | 2023-06-26 | [27725](https://github.com/airbytehq/airbyte/pull/27725) | License Update: Elv2 | +| 0.1.0 | 2023-02-16 | [23186](https://github.com/airbytehq/airbyte/pull/23186) | New Source: GCS | diff --git a/docs/integrations/sources/genesys.md b/docs/integrations/sources/genesys.md index 37d04076ee10..98c97ecfc0eb 100644 --- a/docs/integrations/sources/genesys.md +++ b/docs/integrations/sources/genesys.md @@ -31,6 +31,11 @@ You can follow the documentation on [API credentials](https://developer.genesys. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :----------------------------- | +| 0.1.26 | 2024-12-28 | [50577](https://github.com/airbytehq/airbyte/pull/50577) | Update dependencies | +| 0.1.25 | 2024-12-21 | [50039](https://github.com/airbytehq/airbyte/pull/50039) | Update dependencies | +| 0.1.24 | 2024-12-14 | [49207](https://github.com/airbytehq/airbyte/pull/49207) | Update dependencies | +| 0.1.23 | 2024-11-25 | [48636](https://github.com/airbytehq/airbyte/pull/48636) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.1.22 | 2024-11-04 | [48221](https://github.com/airbytehq/airbyte/pull/48221) | Update dependencies | | 0.1.21 | 2024-10-28 | [47056](https://github.com/airbytehq/airbyte/pull/47056) | Update dependencies | | 0.1.20 | 2024-10-12 | [46776](https://github.com/airbytehq/airbyte/pull/46776) | Update dependencies | | 0.1.19 | 2024-10-05 | [46466](https://github.com/airbytehq/airbyte/pull/46466) | Update dependencies | diff --git a/docs/integrations/sources/getgist.md b/docs/integrations/sources/getgist.md new file mode 100644 index 000000000000..a4aaf2f84180 --- /dev/null +++ b/docs/integrations/sources/getgist.md @@ -0,0 +1,37 @@ +# GetGist +An Airbyte connector for [Gist](https://getgist.com/) would enable data syncing between Gist and various data platforms or databases. This connector could pull data from key objects like contacts, tags, segments, campaigns, forms, and subscription types, facilitating integration with other tools in a data pipeline. By automating data extraction from Gist, users can analyze customer interactions and engagement more efficiently in their preferred analytics or storage environment. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use. Find it in the Integration Settings on your Gist dashboard at https://app.getgist.com/projects/_/settings/api-key. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| contacts | id | DefaultPaginator | ✅ | ❌ | +| collections | id | DefaultPaginator | ✅ | ❌ | +| tags | id | DefaultPaginator | ✅ | ❌ | +| segments | id | DefaultPaginator | ✅ | ❌ | +| forms | id | DefaultPaginator | ✅ | ❌ | +| campaigns | id | DefaultPaginator | ✅ | ❌ | +| subscription_types | id | DefaultPaginator | ✅ | ❌ | +| teams | id | DefaultPaginator | ✅ | ❌ | +| teammates | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50512](https://github.com/airbytehq/airbyte/pull/50512) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50018](https://github.com/airbytehq/airbyte/pull/50018) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49532](https://github.com/airbytehq/airbyte/pull/49532) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49192](https://github.com/airbytehq/airbyte/pull/49192) | Update dependencies | +| 0.0.2 | 2024-12-11 | [48908](https://github.com/airbytehq/airbyte/pull/48908) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-31 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/getlago.md b/docs/integrations/sources/getlago.md index 6555cf465384..a02693554bea 100644 --- a/docs/integrations/sources/getlago.md +++ b/docs/integrations/sources/getlago.md @@ -34,6 +34,10 @@ This source can sync data from the [Lago API](https://doc.getlago.com/docs/guide | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :---------------------------------------- | +| 0.7.6 | 2024-12-28 | [50575](https://github.com/airbytehq/airbyte/pull/50575) | Update dependencies | +| 0.7.5 | 2024-12-21 | [50044](https://github.com/airbytehq/airbyte/pull/50044) | Update dependencies | +| 0.7.4 | 2024-12-14 | [49504](https://github.com/airbytehq/airbyte/pull/49504) | Update dependencies | +| 0.7.3 | 2024-12-12 | [48208](https://github.com/airbytehq/airbyte/pull/48208) | Update dependencies | | 0.7.2 | 2024-10-29 | [47730](https://github.com/airbytehq/airbyte/pull/47730) | Update dependencies | | 0.7.1 | 2024-10-28 | [47596](https://github.com/airbytehq/airbyte/pull/47596) | Update dependencies | | 0.7.0 | 2024-09-12 | [45452](https://github.com/airbytehq/airbyte/pull/45452) | Endpoint customer usage: import current from subscription and add new stream customer_usage_past | diff --git a/docs/integrations/sources/gitbook.md b/docs/integrations/sources/gitbook.md new file mode 100644 index 000000000000..9494fad719d8 --- /dev/null +++ b/docs/integrations/sources/gitbook.md @@ -0,0 +1,34 @@ +# GitBook +GitBook connector enables seamless data integration from GitBook into your data pipelines. It efficiently extracts content, such as documentation and pages, allowing teams to sync and analyze information across platforms. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `access_token` | `string` | Access Token. Personal access token for authenticating with the GitBook API. You can view and manage your access tokens in the Developer settings of your GitBook user account. | | +| `space_id` | `string` | Space Id. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| users | | DefaultPaginator | ✅ | ❌ | +| organizations | id | DefaultPaginator | ✅ | ❌ | +| insights | timestamp | DefaultPaginator | ✅ | ❌ | +| content | id | DefaultPaginator | ✅ | ❌ | +| org_members | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50563](https://github.com/airbytehq/airbyte/pull/50563) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50002](https://github.com/airbytehq/airbyte/pull/50002) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49517](https://github.com/airbytehq/airbyte/pull/49517) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49166](https://github.com/airbytehq/airbyte/pull/49166) | Update dependencies | +| 0.0.2 | 2024-12-11 | [48910](https://github.com/airbytehq/airbyte/pull/48910) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-30 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/github.md b/docs/integrations/sources/github.md index 84f41397fba6..7cc3cb670b03 100644 --- a/docs/integrations/sources/github.md +++ b/docs/integrations/sources/github.md @@ -225,6 +225,11 @@ Your token should have at least the `repo` scope. Depending on which streams you | Version | Date | Pull Request | Subject | |:--------|:-----------|:------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 1.8.20 | 2025-01-04 | [50517](https://github.com/airbytehq/airbyte/pull/50517) | Update dependencies | +| 1.8.19 | 2024-12-21 | [50055](https://github.com/airbytehq/airbyte/pull/50055) | Update dependencies | +| 1.8.18 | 2024-12-14 | [49178](https://github.com/airbytehq/airbyte/pull/49178) | Update dependencies | +| 1.8.17 | 2024-11-25 | [48631](https://github.com/airbytehq/airbyte/pull/48631) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 1.8.16 | 2024-11-05 | [48318](https://github.com/airbytehq/airbyte/pull/48318) | Update dependencies | | 1.8.15 | 2024-10-28 | [47051](https://github.com/airbytehq/airbyte/pull/47051) | Update dependencies | | 1.8.14 | 2024-10-12 | [46766](https://github.com/airbytehq/airbyte/pull/46766) | Update dependencies | | 1.8.13 | 2024-10-05 | [46415](https://github.com/airbytehq/airbyte/pull/46415) | Update dependencies | diff --git a/docs/integrations/sources/glassfrog.md b/docs/integrations/sources/glassfrog.md index f6d3de8cade2..08b9df481cd7 100644 --- a/docs/integrations/sources/glassfrog.md +++ b/docs/integrations/sources/glassfrog.md @@ -50,6 +50,10 @@ This Source is capable of syncing the following Streams: | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.3.6 | 2024-12-28 | [50543](https://github.com/airbytehq/airbyte/pull/50543) | Update dependencies | +| 0.3.5 | 2024-12-21 | [50052](https://github.com/airbytehq/airbyte/pull/50052) | Update dependencies | +| 0.3.4 | 2024-12-14 | [49471](https://github.com/airbytehq/airbyte/pull/49471) | Update dependencies | +| 0.3.3 | 2024-12-12 | [47782](https://github.com/airbytehq/airbyte/pull/47782) | Update dependencies | | 0.3.2 | 2024-10-28 | [47519](https://github.com/airbytehq/airbyte/pull/47519) | Update dependencies | | 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.3.0 | 2024-08-15 | [44146](https://github.com/airbytehq/airbyte/pull/44146) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/gmail.md b/docs/integrations/sources/gmail.md index f38006b01f47..bdfe0c16d9d0 100644 --- a/docs/integrations/sources/gmail.md +++ b/docs/integrations/sources/gmail.md @@ -33,6 +33,10 @@ Note that this connector uses the Google API OAuth2.0 for authentication. To get | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50536](https://github.com/airbytehq/airbyte/pull/50536) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50008](https://github.com/airbytehq/airbyte/pull/50008) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49474](https://github.com/airbytehq/airbyte/pull/49474) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49185](https://github.com/airbytehq/airbyte/pull/49185) | Update dependencies | | 0.0.3 | 2024-10-29 | [47852](https://github.com/airbytehq/airbyte/pull/47852) | Update dependencies | | 0.0.2 | 2024-10-28 | [47570](https://github.com/airbytehq/airbyte/pull/47570) | Update dependencies | | 0.0.1 | 2024-10-09 | | Initial release by [@topefolorunso](https://github.com/topefolorunso) via Connector Builder | diff --git a/docs/integrations/sources/gnews.md b/docs/integrations/sources/gnews.md index 19de9fdcda86..126d6cb7c880 100644 --- a/docs/integrations/sources/gnews.md +++ b/docs/integrations/sources/gnews.md @@ -40,6 +40,10 @@ Rate Limiting is based on the API Key tier subscription, get more info [here](ht | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :----------------------------------------------- | +| 0.2.6 | 2024-12-28 | [50535](https://github.com/airbytehq/airbyte/pull/50535) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50037](https://github.com/airbytehq/airbyte/pull/50037) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49521](https://github.com/airbytehq/airbyte/pull/49521) | Update dependencies | +| 0.2.3 | 2024-12-12 | [48214](https://github.com/airbytehq/airbyte/pull/48214) | Update dependencies | | 0.2.2 | 2024-10-29 | [47918](https://github.com/airbytehq/airbyte/pull/47918) | Update dependencies | | 0.2.1 | 2024-10-28 | [47499](https://github.com/airbytehq/airbyte/pull/47499) | Update dependencies | | 0.2.0 | 2024-10-17 | [46959](https://github.com/airbytehq/airbyte/pull/46959) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/gocardless.md b/docs/integrations/sources/gocardless.md index b6a98f4ea226..a947053baf66 100644 --- a/docs/integrations/sources/gocardless.md +++ b/docs/integrations/sources/gocardless.md @@ -35,6 +35,11 @@ This source is capable of syncing the following streams: | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :---------------------------------------- | +| 0.2.7 | 2024-12-28 | [50514](https://github.com/airbytehq/airbyte/pull/50514) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50023](https://github.com/airbytehq/airbyte/pull/50023) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49505](https://github.com/airbytehq/airbyte/pull/49505) | Update dependencies | +| 0.2.4 | 2024-12-12 | [49169](https://github.com/airbytehq/airbyte/pull/49169) | Update dependencies | +| 0.2.3 | 2024-11-04 | [48295](https://github.com/airbytehq/airbyte/pull/48295) | Update dependencies | | 0.2.2 | 2024-10-29 | [47772](https://github.com/airbytehq/airbyte/pull/47772) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-15 | [44145](https://github.com/airbytehq/airbyte/pull/44145) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/goldcast.md b/docs/integrations/sources/goldcast.md index b7726040a0a4..066357c04e27 100644 --- a/docs/integrations/sources/goldcast.md +++ b/docs/integrations/sources/goldcast.md @@ -96,6 +96,11 @@ This is a child stream of the events stream indicating webinars that belong to t | Version | Date | Pull Request | Subject | |:---------|:-----------|:---------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------| +| 0.2.7 | 2024-12-28 | [50571](https://github.com/airbytehq/airbyte/pull/50571) | Update dependencies | +| 0.2.6 | 2024-12-21 | [49998](https://github.com/airbytehq/airbyte/pull/49998) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49480](https://github.com/airbytehq/airbyte/pull/49480) | Update dependencies | +| 0.2.4 | 2024-12-12 | [49158](https://github.com/airbytehq/airbyte/pull/49158) | Update dependencies | +| 0.2.3 | 2024-11-04 | [48148](https://github.com/airbytehq/airbyte/pull/48148) | Update dependencies | | 0.2.2 | 2024-10-29 | [47875](https://github.com/airbytehq/airbyte/pull/47875) | Update dependencies | | 0.2.1 | 2024-10-28 | [47533](https://github.com/airbytehq/airbyte/pull/47533) | Update dependencies | | 0.2.0 | 2024-08-22 | [44568](https://github.com/airbytehq/airbyte/pull/44568) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/gong.md b/docs/integrations/sources/gong.md index e238405b18ce..95c55572e2ca 100644 --- a/docs/integrations/sources/gong.md +++ b/docs/integrations/sources/gong.md @@ -21,7 +21,7 @@ This Source is capable of syncing the following core Streams: | Feature | Supported?\(Yes/No\) | Notes | | :------------------------ | :------------------- | :---- | | Full Refresh Sync | Yes | | -| Incremental - Append Sync | No | | +| Incremental - Append Sync | Yes | | | Namespaces | No | | ### Performance considerations @@ -32,6 +32,8 @@ By default Gong limits your company's access to the service to 3 API calls per s ## Requirements - **Gong API keys**. See the [Gong docs](https://us-14321.app.gong.io/settings/api/documentation#overview) for information on how to obtain the API keys. +- **Start Date**. To fetch data from. This just applies to Incremental syncs. Default value is 90 days from today. + ## Changelog @@ -40,6 +42,11 @@ By default Gong limits your company's access to the service to 3 API calls per s | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.3.6 | 2024-12-28 | [50521](https://github.com/airbytehq/airbyte/pull/50521) | Update dependencies | +| 0.3.5 | 2024-12-21 | [50017](https://github.com/airbytehq/airbyte/pull/50017) | Update dependencies | +| 0.3.4 | 2024-12-14 | [49538](https://github.com/airbytehq/airbyte/pull/49538) | Update dependencies | +| 0.3.3 | 2024-12-12 | [49155](https://github.com/airbytehq/airbyte/pull/49155) | Update dependencies | +| 0.3.2 | 2024-11-14 | [36604](https://github.com/airbytehq/airbyte/pull/36604) | Add incremental Feature | | 0.3.1 | 2024-10-29 | [47824](https://github.com/airbytehq/airbyte/pull/47824) | Update dependencies | | 0.3.0 | 2024-09-04 | [45117](https://github.com/airbytehq/airbyte/pull/45117) | Add new stream `extensive calls` | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/google-analytics-data-api.md b/docs/integrations/sources/google-analytics-data-api.md index 80c627be74e2..5b9dbc37a451 100644 --- a/docs/integrations/sources/google-analytics-data-api.md +++ b/docs/integrations/sources/google-analytics-data-api.md @@ -272,6 +272,7 @@ The Google Analytics connector is subject to Google Analytics Data API quotas. P | Version | Date | Pull Request | Subject | |:--------|:-----------| :------------------------------------------------------- |:---------------------------------------------------------------------------------------| +| 2.6.2 | 2024-12-14 | [48649](https://github.com/airbytehq/airbyte/pull/48649) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 2.6.1 | 2024-10-29 | [47899](https://github.com/airbytehq/airbyte/pull/47899) | Update dependencies | | 2.6.0 | 2024-10-28 | [47013](https://github.com/airbytehq/airbyte/pull/47013) | Migrate to CDK v5 | | 2.5.13 | 2024-10-28 | [47061](https://github.com/airbytehq/airbyte/pull/47061) | Update dependencies | diff --git a/docs/integrations/sources/google-analytics-v4-service-account-only.md b/docs/integrations/sources/google-analytics-v4-service-account-only.md index 5ec2662043df..e771710f7ab5 100644 --- a/docs/integrations/sources/google-analytics-v4-service-account-only.md +++ b/docs/integrations/sources/google-analytics-v4-service-account-only.md @@ -274,6 +274,7 @@ The Google Analytics connector should not run into the "requests per 100 seconds | Version | Date | Pull Request | Subject | |:--------|:-----------| :------------------------------------------------------- |:-----------------------------------------| +| 0.1.2 | 2024-12-12 | [49153](https://github.com/airbytehq/airbyte/pull/49153) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.1.1 | 2024-10-29 | [47820](https://github.com/airbytehq/airbyte/pull/47820) | Update dependencies | | 0.1.0 | 2024-07-01 | [40244](https://github.com/airbytehq/airbyte/pull/40244) | Deprecate the connector | | 0.0.2 | 2024-04-19 | [37432](https://github.com/airbytehq/airbyte/pull/36267) | Fix empty response error for test stream | diff --git a/docs/integrations/sources/google-analytics-v4.md b/docs/integrations/sources/google-analytics-v4.md index 09f56216e3a5..e76ccdadf393 100644 --- a/docs/integrations/sources/google-analytics-v4.md +++ b/docs/integrations/sources/google-analytics-v4.md @@ -276,6 +276,11 @@ The Google Analytics connector should not run into the "requests per 100 seconds | Version | Date | Pull Request | Subject | |:--------| :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------------------- | +| 0.4.6 | 2025-01-04 | [50921](https://github.com/airbytehq/airbyte/pull/50921) | Update dependencies | +| 0.4.5 | 2024-12-28 | [50589](https://github.com/airbytehq/airbyte/pull/50589) | Update dependencies | +| 0.4.4 | 2024-12-21 | [50063](https://github.com/airbytehq/airbyte/pull/50063) | Update dependencies | +| 0.4.3 | 2024-12-14 | [49507](https://github.com/airbytehq/airbyte/pull/49507) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.4.2 | 2024-11-04 | [48206](https://github.com/airbytehq/airbyte/pull/48206) | Update dependencies | | 0.4.1 | 2024-10-29 | [47766](https://github.com/airbytehq/airbyte/pull/47766) | Update dependencies | | 0.4.0 | 2024-07-01 | [40244](https://github.com/airbytehq/airbyte/pull/40244) | Deprecate the connector | | 0.3.3 | 2024-06-21 | [39940](https://github.com/airbytehq/airbyte/pull/39940) | Update dependencies | diff --git a/docs/integrations/sources/google-classroom.md b/docs/integrations/sources/google-classroom.md new file mode 100644 index 000000000000..70a713f0eb9a --- /dev/null +++ b/docs/integrations/sources/google-classroom.md @@ -0,0 +1,35 @@ +# Google Classroom +Google Classroom connector enables seamless data integration between Google Classroom and various destinations. This connector facilitates the synchronization of course information, rosters, assignments empowering educators to automate reporting and streamline classroom data management efficiently. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `client_id` | `string` | OAuth Client ID. | | +| `client_secret` | `string` | OAuth Client Secret. | | +| `client_refresh_token` | `string` | Refresh token. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| courses | id | DefaultPaginator | ✅ | ❌ | +| teachers | userId | DefaultPaginator | ✅ | ❌ | +| students | userId | DefaultPaginator | ✅ | ❌ | +| announcements | id | DefaultPaginator | ✅ | ❌ | +| coursework | id | DefaultPaginator | ✅ | ❌ | +| studentsubmissions | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50545](https://github.com/airbytehq/airbyte/pull/50545) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50010](https://github.com/airbytehq/airbyte/pull/50010) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49540](https://github.com/airbytehq/airbyte/pull/49540) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49188](https://github.com/airbytehq/airbyte/pull/49188) | Update dependencies | +| 0.0.1 | 2024-10-26 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/google-directory.md b/docs/integrations/sources/google-directory.md index 2fd4b1ba77bb..e8832937d553 100644 --- a/docs/integrations/sources/google-directory.md +++ b/docs/integrations/sources/google-directory.md @@ -70,6 +70,11 @@ You should now be ready to use the Google Directory connector in Airbyte. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :----------------------------------------------------------- | +| 0.2.28 | 2025-01-04 | [50925](https://github.com/airbytehq/airbyte/pull/50925) | Update dependencies | +| 0.2.27 | 2024-12-28 | [50578](https://github.com/airbytehq/airbyte/pull/50578) | Update dependencies | +| 0.2.26 | 2024-12-21 | [49987](https://github.com/airbytehq/airbyte/pull/49987) | Update dependencies | +| 0.2.25 | 2024-12-14 | [49168](https://github.com/airbytehq/airbyte/pull/49168) | Update dependencies | +| 0.2.24 | 2024-11-25 | [48638](https://github.com/airbytehq/airbyte/pull/48638) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.23 | 2024-10-29 | [47736](https://github.com/airbytehq/airbyte/pull/47736) | Update dependencies | | 0.2.22 | 2024-10-22 | [47071](https://github.com/airbytehq/airbyte/pull/47071) | Update dependencies | | 0.2.21 | 2024-10-12 | [46785](https://github.com/airbytehq/airbyte/pull/46785) | Update dependencies | diff --git a/docs/integrations/sources/google-forms.md b/docs/integrations/sources/google-forms.md new file mode 100644 index 000000000000..da14c4ddeb8d --- /dev/null +++ b/docs/integrations/sources/google-forms.md @@ -0,0 +1,31 @@ +# Google Forms +Google Forms is a free online tool from Google that allows users to create custom surveys, quizzes, and forms. It enables easy collection and organization of data by automating responses into a connected Google Sheets spreadsheet. With Google Forms, you can design forms with various question types, share them via email or links, and track responses in real-time, making it ideal for feedback collection, event registration, or educational assessments. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `client_id` | `string` | Client ID. | | +| `client_secret` | `string` | Client secret. | | +| `client_refresh_token` | `string` | Refresh token. | | +| `form_id` | `array` | Forms IDs. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| forms | `formId` | No pagination | ✅ | ❌ | +| form_responses | `responseId` | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.4 | 2024-12-28 | [50568](https://github.com/airbytehq/airbyte/pull/50568) | Update dependencies | +| 0.0.3 | 2024-12-21 | [49501](https://github.com/airbytehq/airbyte/pull/49501) | Update dependencies | +| 0.0.2 | 2024-12-12 | [48967](https://github.com/airbytehq/airbyte/pull/48967) | Update dependencies | +| 0.0.1 | 2024-11-09 | | Initial release by [@bala-ceg](https://github.com/bala-ceg) via Connector Builder | + +
diff --git a/docs/integrations/sources/google-pagespeed-insights.md b/docs/integrations/sources/google-pagespeed-insights.md index 0482431a4c47..75483be9101d 100644 --- a/docs/integrations/sources/google-pagespeed-insights.md +++ b/docs/integrations/sources/google-pagespeed-insights.md @@ -55,7 +55,12 @@ If the connector is used with an API key, Google allows for 25.000 queries per d | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :------------------------------------------------------------------------------ | -| 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | +| 0.2.6 | 2024-12-28 | [50529](https://github.com/airbytehq/airbyte/pull/50529) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50030](https://github.com/airbytehq/airbyte/pull/50030) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49526](https://github.com/airbytehq/airbyte/pull/49526) | Update dependencies | +| 0.2.3 | 2024-12-12 | [49177](https://github.com/airbytehq/airbyte/pull/49177) | Update dependencies | +| 0.2.2 | 2024-12-11 | [47793](https://github.com/airbytehq/airbyte/pull/47793) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-15 | [44143](https://github.com/airbytehq/airbyte/pull/44143) | Refactor connector to manifest-only format | | 0.1.17 | 2024-08-10 | [43617](https://github.com/airbytehq/airbyte/pull/43617) | Update dependencies | | 0.1.16 | 2024-08-03 | [43130](https://github.com/airbytehq/airbyte/pull/43130) | Update dependencies | diff --git a/docs/integrations/sources/google-search-console.md b/docs/integrations/sources/google-search-console.md index 6c5212960893..998efe436c1a 100644 --- a/docs/integrations/sources/google-search-console.md +++ b/docs/integrations/sources/google-search-console.md @@ -230,61 +230,66 @@ Google Search Console only retains data for websites from the last 16 months. An | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------| -| 1.5.4 | 2024-09-06 | [45196](https://github.com/airbytehq/airbyte/pull/45196) | Fix request body for report streams by keyword | -| 1.5.3 | 2024-08-03 | [43067](https://github.com/airbytehq/airbyte/pull/43067) | Update dependencies | -| 1.5.2 | 2024-07-27 | [42786](https://github.com/airbytehq/airbyte/pull/42786) | Update dependencies | -| 1.5.1 | 2024-07-20 | [42142](https://github.com/airbytehq/airbyte/pull/42142) | Update dependencies | -| 1.5.0 | 2024-07-17 | [42073](https://github.com/airbytehq/airbyte/pull/42073) | Migrate to CDK v1.8.0 | -| 1.4.13 | 2024-07-13 | [41734](https://github.com/airbytehq/airbyte/pull/41734) | Update dependencies | -| 1.4.12 | 2024-07-10 | [41440](https://github.com/airbytehq/airbyte/pull/41440) | Update dependencies | -| 1.4.11 | 2024-07-09 | [41164](https://github.com/airbytehq/airbyte/pull/41164) | Update dependencies | -| 1.4.10 | 2024-07-06 | [40981](https://github.com/airbytehq/airbyte/pull/40981) | Update dependencies | -| 1.4.9 | 2024-06-27 | [40215](https://github.com/airbytehq/airbyte/pull/40215) | Replaced deprecated AirbyteLogger with logging.Logger | -| 1.4.8 | 2024-06-26 | [40532](https://github.com/airbytehq/airbyte/pull/40532) | Update dependencies | -| 1.4.7 | 2024-06-25 | [40312](https://github.com/airbytehq/airbyte/pull/40312) | Update dependencies | -| 1.4.6 | 2024-06-22 | [40077](https://github.com/airbytehq/airbyte/pull/40077) | Update dependencies | -| 1.4.5 | 2024-06-17 | [39516](https://github.com/airbytehq/airbyte/pull/39516) | Update state handling for incremental streams | -| 1.4.4 | 2024-06-04 | [39059](https://github.com/airbytehq/airbyte/pull/39059) | [autopull] Upgrade base image to v1.2.1 | -| 1.4.3 | 2024-05-24 | [38649](https://github.com/airbytehq/airbyte/pull/38649) | Update deprecated auth package | -| 1.4.2 | 2024-04-19 | [36639](https://github.com/airbytehq/airbyte/pull/36639) | Updating to 0.80.0 CDK | -| 1.4.1 | 2024-04-12 | [36639](https://github.com/airbytehq/airbyte/pull/36639) | Schema descriptions | -| 1.4.0 | 2024-03-19 | [36267](https://github.com/airbytehq/airbyte/pull/36267) | Pin airbyte-cdk version to `^0` | -| 1.3.7 | 2024-02-12 | [35163](https://github.com/airbytehq/airbyte/pull/35163) | Manage dependencies with Poetry | -| 1.3.6 | 2023-10-26 | [31863](https://github.com/airbytehq/airbyte/pull/31863) | Base image migration: remove Dockerfile and use the python-connector-base image | -| 1.3.5 | 2023-09-28 | [30822](https://github.com/airbytehq/airbyte/pull/30822) | Fix primary key for custom reports | -| 1.3.4 | 2023-09-27 | [30785](https://github.com/airbytehq/airbyte/pull/30785) | Do not migrate config for the newly created connections | -| 1.3.3 | 2023-08-29 | [29941](https://github.com/airbytehq/airbyte/pull/29941) | Added `primary key` to each stream, added `custom_report` config migration | -| 1.3.2 | 2023-08-25 | [29829](https://github.com/airbytehq/airbyte/pull/29829) | Make `Start Date` a non-required, added the `suggested streams`, corrected public docs | -| 1.3.1 | 2023-08-24 | [29329](https://github.com/airbytehq/airbyte/pull/29329) | Update tooltip descriptions | -| 1.3.0 | 2023-08-24 | [29750](https://github.com/airbytehq/airbyte/pull/29750) | Add new `Keyword-Site-Report-By-Site` stream | -| 1.2.2 | 2023-08-23 | [29741](https://github.com/airbytehq/airbyte/pull/29741) | Handle `HTTP-401`, `HTTP-403` errors | -| 1.2.1 | 2023-07-04 | [27952](https://github.com/airbytehq/airbyte/pull/27952) | Removed deprecated `searchType`, added `discover`(Discover results) and `googleNews`(Results from news.google.com, etc.) types | -| 1.2.0 | 2023-06-29 | [27831](https://github.com/airbytehq/airbyte/pull/27831) | Add new streams | -| 1.1.0 | 2023-06-26 | [27738](https://github.com/airbytehq/airbyte/pull/27738) | License Update: Elv2 | -| 1.0.2 | 2023-06-13 | [27307](https://github.com/airbytehq/airbyte/pull/27307) | Fix `data_state` config typo | -| 1.0.1 | 2023-05-30 | [26746](https://github.com/airbytehq/airbyte/pull/26746) | Remove `authSpecification` from connector spec in favour of advancedAuth | -| 1.0.0 | 2023-05-24 | [26452](https://github.com/airbytehq/airbyte/pull/26452) | Add data_state parameter to specification | -| 0.1.22 | 2023-03-20 | [22295](https://github.com/airbytehq/airbyte/pull/22295) | Update specification examples | -| 0.1.21 | 2023-02-14 | [22984](https://github.com/airbytehq/airbyte/pull/22984) | Specified date formatting in specification | -| 0.1.20 | 2023-02-02 | [22334](https://github.com/airbytehq/airbyte/pull/22334) | Turn on default HttpAvailabilityStrategy | -| 0.1.19 | 2023-01-27 | [22007](https://github.com/airbytehq/airbyte/pull/22007) | Set `AvailabilityStrategy` for streams explicitly to `None` | -| 0.1.18 | 2022-10-27 | [18568](https://github.com/airbytehq/airbyte/pull/18568) | Improved config validation: custom_reports.dimension | -| 0.1.17 | 2022-10-08 | [17751](https://github.com/airbytehq/airbyte/pull/17751) | Improved config validation: start_date, end_date, site_urls | -| 0.1.16 | 2022-09-28 | [17304](https://github.com/airbytehq/airbyte/pull/17304) | Migrate to per-stream state. | -| 0.1.15 | 2022-09-16 | [16819](https://github.com/airbytehq/airbyte/pull/16819) | Check available site urls to avoid 403 error on sync | -| 0.1.14 | 2022-09-08 | [16433](https://github.com/airbytehq/airbyte/pull/16433) | Add custom analytics stream. | -| 0.1.13 | 2022-07-21 | [14924](https://github.com/airbytehq/airbyte/pull/14924) | Remove `additionalProperties` field from specs | -| 0.1.12 | 2022-05-04 | [12482](https://github.com/airbytehq/airbyte/pull/12482) | Update input configuration copy | -| 0.1.11 | 2022-01-05 | [9186](https://github.com/airbytehq/airbyte/pull/9186) | Fix incremental sync: keep all urls in state object | -| 0.1.10 | 2021-12-23 | [9073](https://github.com/airbytehq/airbyte/pull/9073) | Add slicing by date range | -| 0.1.9 | 2021-12-22 | [9047](https://github.com/airbytehq/airbyte/pull/9047) | Add 'order' to spec.json props | -| 0.1.8 | 2021-12-21 | [8248](https://github.com/airbytehq/airbyte/pull/8248) | Enable Sentry for performance and errors tracking | -| 0.1.7 | 2021-11-26 | [7431](https://github.com/airbytehq/airbyte/pull/7431) | Add default `end_date` param value | -| 0.1.6 | 2021-09-27 | [6460](https://github.com/airbytehq/airbyte/pull/6460) | Update OAuth Spec File | -| 0.1.4 | 2021-09-23 | [6394](https://github.com/airbytehq/airbyte/pull/6394) | Update Doc link Spec File | -| 0.1.3 | 2021-09-23 | [6405](https://github.com/airbytehq/airbyte/pull/6405) | Correct Spec File | -| 0.1.2 | 2021-09-17 | [6222](https://github.com/airbytehq/airbyte/pull/6222) | Correct Spec File | -| 0.1.1 | 2021-09-22 | [6315](https://github.com/airbytehq/airbyte/pull/6315) | Verify access to all sites when performing connection check | +| 1.5.9 | 2025-01-04 | [50919](https://github.com/airbytehq/airbyte/pull/50919) | Update dependencies | +| 1.5.8 | 2024-12-28 | [50579](https://github.com/airbytehq/airbyte/pull/50579) | Update dependencies | +| 1.5.7 | 2024-12-21 | [50040](https://github.com/airbytehq/airbyte/pull/50040) | Update dependencies | +| 1.5.6 | 2024-12-14 | [49173](https://github.com/airbytehq/airbyte/pull/49173) | Update dependencies | +| 1.5.5 | 2024-11-25 | [43730](https://github.com/airbytehq/airbyte/pull/43730) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 1.5.4 | 2024-09-06 | [45196](https://github.com/airbytehq/airbyte/pull/45196) | Fix request body for report streams by keyword | +| 1.5.3 | 2024-08-03 | [43067](https://github.com/airbytehq/airbyte/pull/43067) | Update dependencies | +| 1.5.2 | 2024-07-27 | [42786](https://github.com/airbytehq/airbyte/pull/42786) | Update dependencies | +| 1.5.1 | 2024-07-20 | [42142](https://github.com/airbytehq/airbyte/pull/42142) | Update dependencies | +| 1.5.0 | 2024-07-17 | [42073](https://github.com/airbytehq/airbyte/pull/42073) | Migrate to CDK v1.8.0 | +| 1.4.13 | 2024-07-13 | [41734](https://github.com/airbytehq/airbyte/pull/41734) | Update dependencies | +| 1.4.12 | 2024-07-10 | [41440](https://github.com/airbytehq/airbyte/pull/41440) | Update dependencies | +| 1.4.11 | 2024-07-09 | [41164](https://github.com/airbytehq/airbyte/pull/41164) | Update dependencies | +| 1.4.10 | 2024-07-06 | [40981](https://github.com/airbytehq/airbyte/pull/40981) | Update dependencies | +| 1.4.9 | 2024-06-27 | [40215](https://github.com/airbytehq/airbyte/pull/40215) | Replaced deprecated AirbyteLogger with logging.Logger | +| 1.4.8 | 2024-06-26 | [40532](https://github.com/airbytehq/airbyte/pull/40532) | Update dependencies | +| 1.4.7 | 2024-06-25 | [40312](https://github.com/airbytehq/airbyte/pull/40312) | Update dependencies | +| 1.4.6 | 2024-06-22 | [40077](https://github.com/airbytehq/airbyte/pull/40077) | Update dependencies | +| 1.4.5 | 2024-06-17 | [39516](https://github.com/airbytehq/airbyte/pull/39516) | Update state handling for incremental streams | +| 1.4.4 | 2024-06-04 | [39059](https://github.com/airbytehq/airbyte/pull/39059) | [autopull] Upgrade base image to v1.2.1 | +| 1.4.3 | 2024-05-24 | [38649](https://github.com/airbytehq/airbyte/pull/38649) | Update deprecated auth package | +| 1.4.2 | 2024-04-19 | [36639](https://github.com/airbytehq/airbyte/pull/36639) | Updating to 0.80.0 CDK | +| 1.4.1 | 2024-04-12 | [36639](https://github.com/airbytehq/airbyte/pull/36639) | Schema descriptions | +| 1.4.0 | 2024-03-19 | [36267](https://github.com/airbytehq/airbyte/pull/36267) | Pin airbyte-cdk version to `^0` | +| 1.3.7 | 2024-02-12 | [35163](https://github.com/airbytehq/airbyte/pull/35163) | Manage dependencies with Poetry | +| 1.3.6 | 2023-10-26 | [31863](https://github.com/airbytehq/airbyte/pull/31863) | Base image migration: remove Dockerfile and use the python-connector-base image | +| 1.3.5 | 2023-09-28 | [30822](https://github.com/airbytehq/airbyte/pull/30822) | Fix primary key for custom reports | +| 1.3.4 | 2023-09-27 | [30785](https://github.com/airbytehq/airbyte/pull/30785) | Do not migrate config for the newly created connections | +| 1.3.3 | 2023-08-29 | [29941](https://github.com/airbytehq/airbyte/pull/29941) | Added `primary key` to each stream, added `custom_report` config migration | +| 1.3.2 | 2023-08-25 | [29829](https://github.com/airbytehq/airbyte/pull/29829) | Make `Start Date` a non-required, added the `suggested streams`, corrected public docs | +| 1.3.1 | 2023-08-24 | [29329](https://github.com/airbytehq/airbyte/pull/29329) | Update tooltip descriptions | +| 1.3.0 | 2023-08-24 | [29750](https://github.com/airbytehq/airbyte/pull/29750) | Add new `Keyword-Site-Report-By-Site` stream | +| 1.2.2 | 2023-08-23 | [29741](https://github.com/airbytehq/airbyte/pull/29741) | Handle `HTTP-401`, `HTTP-403` errors | +| 1.2.1 | 2023-07-04 | [27952](https://github.com/airbytehq/airbyte/pull/27952) | Removed deprecated `searchType`, added `discover`(Discover results) and `googleNews`(Results from news.google.com, etc.) types | +| 1.2.0 | 2023-06-29 | [27831](https://github.com/airbytehq/airbyte/pull/27831) | Add new streams | +| 1.1.0 | 2023-06-26 | [27738](https://github.com/airbytehq/airbyte/pull/27738) | License Update: Elv2 | +| 1.0.2 | 2023-06-13 | [27307](https://github.com/airbytehq/airbyte/pull/27307) | Fix `data_state` config typo | +| 1.0.1 | 2023-05-30 | [26746](https://github.com/airbytehq/airbyte/pull/26746) | Remove `authSpecification` from connector spec in favour of advancedAuth | +| 1.0.0 | 2023-05-24 | [26452](https://github.com/airbytehq/airbyte/pull/26452) | Add data_state parameter to specification | +| 0.1.22 | 2023-03-20 | [22295](https://github.com/airbytehq/airbyte/pull/22295) | Update specification examples | +| 0.1.21 | 2023-02-14 | [22984](https://github.com/airbytehq/airbyte/pull/22984) | Specified date formatting in specification | +| 0.1.20 | 2023-02-02 | [22334](https://github.com/airbytehq/airbyte/pull/22334) | Turn on default HttpAvailabilityStrategy | +| 0.1.19 | 2023-01-27 | [22007](https://github.com/airbytehq/airbyte/pull/22007) | Set `AvailabilityStrategy` for streams explicitly to `None` | +| 0.1.18 | 2022-10-27 | [18568](https://github.com/airbytehq/airbyte/pull/18568) | Improved config validation: custom_reports.dimension | +| 0.1.17 | 2022-10-08 | [17751](https://github.com/airbytehq/airbyte/pull/17751) | Improved config validation: start_date, end_date, site_urls | +| 0.1.16 | 2022-09-28 | [17304](https://github.com/airbytehq/airbyte/pull/17304) | Migrate to per-stream state. | +| 0.1.15 | 2022-09-16 | [16819](https://github.com/airbytehq/airbyte/pull/16819) | Check available site urls to avoid 403 error on sync | +| 0.1.14 | 2022-09-08 | [16433](https://github.com/airbytehq/airbyte/pull/16433) | Add custom analytics stream. | +| 0.1.13 | 2022-07-21 | [14924](https://github.com/airbytehq/airbyte/pull/14924) | Remove `additionalProperties` field from specs | +| 0.1.12 | 2022-05-04 | [12482](https://github.com/airbytehq/airbyte/pull/12482) | Update input configuration copy | +| 0.1.11 | 2022-01-05 | [9186](https://github.com/airbytehq/airbyte/pull/9186) | Fix incremental sync: keep all urls in state object | +| 0.1.10 | 2021-12-23 | [9073](https://github.com/airbytehq/airbyte/pull/9073) | Add slicing by date range | +| 0.1.9 | 2021-12-22 | [9047](https://github.com/airbytehq/airbyte/pull/9047) | Add 'order' to spec.json props | +| 0.1.8 | 2021-12-21 | [8248](https://github.com/airbytehq/airbyte/pull/8248) | Enable Sentry for performance and errors tracking | +| 0.1.7 | 2021-11-26 | [7431](https://github.com/airbytehq/airbyte/pull/7431) | Add default `end_date` param value | +| 0.1.6 | 2021-09-27 | [6460](https://github.com/airbytehq/airbyte/pull/6460) | Update OAuth Spec File | +| 0.1.4 | 2021-09-23 | [6394](https://github.com/airbytehq/airbyte/pull/6394) | Update Doc link Spec File | +| 0.1.3 | 2021-09-23 | [6405](https://github.com/airbytehq/airbyte/pull/6405) | Correct Spec File | +| 0.1.2 | 2021-09-17 | [6222](https://github.com/airbytehq/airbyte/pull/6222) | Correct Spec File | +| 0.1.1 | 2021-09-22 | [6315](https://github.com/airbytehq/airbyte/pull/6315) | Verify access to all sites when performing connection check | | 0.1.0` | 2021-09-03 | [5350](https://github.com/airbytehq/airbyte/pull/5350) | Initial Release | diff --git a/docs/integrations/sources/google-sheets.md b/docs/integrations/sources/google-sheets.md index 1baef80c9b70..d8d3751707d8 100644 --- a/docs/integrations/sources/google-sheets.md +++ b/docs/integrations/sources/google-sheets.md @@ -189,6 +189,7 @@ Airbyte batches requests to the API in order to efficiently pull data and respec | Version | Date | Pull Request | Subject | |---------|------------|----------------------------------------------------------|-----------------------------------------------------------------------------------| +| 0.8.4 | 2024-12-09 | [48835](https://github.com/airbytehq/airbyte/pull/48835) | Implementing integration tests | | 0.7.4 | 2024-09-09 | [45108](https://github.com/airbytehq/airbyte/pull/45108) | Google Sheets API errors now cause syncs to fail | | 0.7.3 | 2024-08-12 | [43921](https://github.com/airbytehq/airbyte/pull/43921) | Update dependencies | | 0.7.2 | 2024-08-10 | [43544](https://github.com/airbytehq/airbyte/pull/43544) | Update dependencies | diff --git a/docs/integrations/sources/google-tasks.md b/docs/integrations/sources/google-tasks.md index 4ed5525cba26..8f952e9fe9b6 100644 --- a/docs/integrations/sources/google-tasks.md +++ b/docs/integrations/sources/google-tasks.md @@ -43,6 +43,13 @@ Steps: | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.9 | 2024-12-28 | [50647](https://github.com/airbytehq/airbyte/pull/50647) | Update dependencies | +| 0.0.8 | 2024-12-21 | [50091](https://github.com/airbytehq/airbyte/pull/50091) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49594](https://github.com/airbytehq/airbyte/pull/49594) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49223](https://github.com/airbytehq/airbyte/pull/49223) | Update dependencies | +| 0.0.5 | 2024-12-11 | [48949](https://github.com/airbytehq/airbyte/pull/48949) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-11-05 | [48366](https://github.com/airbytehq/airbyte/pull/48366) | Revert to source-declarative-manifest v5.17.0 | +| 0.0.3 | 2024-11-05 | [47770](https://github.com/airbytehq/airbyte/pull/47770) | Update dependencies | | 0.0.2 | 2024-10-28 | [47550](https://github.com/airbytehq/airbyte/pull/47550) | Update dependencies | | 0.0.1 | 2024-09-12 | [45427](https://github.com/airbytehq/airbyte/pull/45427) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/google-webfonts.md b/docs/integrations/sources/google-webfonts.md index b7f0c5f96a20..40174f788dd3 100644 --- a/docs/integrations/sources/google-webfonts.md +++ b/docs/integrations/sources/google-webfonts.md @@ -68,6 +68,10 @@ Google Webfont's [API reference](https://developers.google.com/fonts/docs/develo | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- |:--------------------------------------------------------------------------------| +| 0.2.6 | 2024-12-28 | [50099](https://github.com/airbytehq/airbyte/pull/50099) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49616](https://github.com/airbytehq/airbyte/pull/49616) | Update dependencies | +| 0.2.4 | 2024-12-12 | [49232](https://github.com/airbytehq/airbyte/pull/49232) | Update dependencies | +| 0.2.3 | 2024-12-11 | [48141](https://github.com/airbytehq/airbyte/pull/48141) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.2 | 2024-10-29 | [47891](https://github.com/airbytehq/airbyte/pull/47891) | Update dependencies | | 0.2.1 | 2024-10-28 | [47623](https://github.com/airbytehq/airbyte/pull/47623) | Update dependencies | | 0.2.0 | 2024-08-23 | [44615](https://github.com/airbytehq/airbyte/pull/44615) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/gorgias.md b/docs/integrations/sources/gorgias.md index a56688418f0e..2ec1e28ba3c7 100644 --- a/docs/integrations/sources/gorgias.md +++ b/docs/integrations/sources/gorgias.md @@ -43,6 +43,10 @@ Visit `https://developers.gorgias.com/reference/introduction` for API documentat | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.7 | 2024-12-21 | [50123](https://github.com/airbytehq/airbyte/pull/50123) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49219](https://github.com/airbytehq/airbyte/pull/49219) | Update dependencies | +| 0.0.5 | 2024-12-11 | [48973](https://github.com/airbytehq/airbyte/pull/48973) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-11-06 | [48378](https://github.com/airbytehq/airbyte/pull/48378) | Fix incremental sync format, Auto update schema with additional fields | | 0.0.3 | 2024-10-29 | [47923](https://github.com/airbytehq/airbyte/pull/47923) | Update dependencies | | 0.0.2 | 2024-10-28 | [47459](https://github.com/airbytehq/airbyte/pull/47459) | Update dependencies | | 0.0.1 | 2024-09-29 | [46221](https://github.com/airbytehq/airbyte/pull/46221) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/greenhouse.md b/docs/integrations/sources/greenhouse.md index 0d399f898225..802c585e5661 100644 --- a/docs/integrations/sources/greenhouse.md +++ b/docs/integrations/sources/greenhouse.md @@ -74,6 +74,10 @@ The Greenhouse connector should not run into Greenhouse API limitations under no | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 0.5.29 | 2024-12-28 | [50632](https://github.com/airbytehq/airbyte/pull/50632) | Update dependencies | +| 0.5.28 | 2024-12-21 | [50109](https://github.com/airbytehq/airbyte/pull/50109) | Update dependencies | +| 0.5.27 | 2024-12-14 | [49248](https://github.com/airbytehq/airbyte/pull/49248) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.5.26 | 2024-12-12 | [48996](https://github.com/airbytehq/airbyte/pull/48996) | Update dependencies | | 0.5.25 | 2024-10-29 | [47110](https://github.com/airbytehq/airbyte/pull/47110) | Update dependencies | | 0.5.24 | 2024-10-23 | [47306](https://github.com/airbytehq/airbyte/pull/47306) | Add 'job_post_id' to applications stream scehma | | 0.5.23 | 2024-10-12 | [46828](https://github.com/airbytehq/airbyte/pull/46828) | Update dependencies | diff --git a/docs/integrations/sources/greythr.md b/docs/integrations/sources/greythr.md new file mode 100644 index 000000000000..9ac85bb08071 --- /dev/null +++ b/docs/integrations/sources/greythr.md @@ -0,0 +1,41 @@ +# GreytHr +The GreytHR Connector for Airbyte allows seamless integration with the GreytHR platform, enabling users to automate the extraction and synchronization of employee management and payroll data into their preferred destinations for reporting, analytics, or further processing. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `domain` | `string` | Host URL. Your GreytHR Host URL | | +| `base_url` | `string` | Base URL. https://api.greythr.com | | +| `password` | `string` | Password. | | +| `username` | `string` | Username. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| Employees | employeeId | DefaultPaginator | ✅ | ❌ | +| Employees Categories | employeeId | DefaultPaginator | ✅ | ❌ | +| Employees Profile | employeeId | DefaultPaginator | ✅ | ❌ | +| Employees Personal Details | employeeId | DefaultPaginator | ✅ | ❌ | +| Employees Work Details | employeeId | DefaultPaginator | ✅ | ❌ | +| Employee Separation Details | employeeId | DefaultPaginator | ✅ | ❌ | +| Employee Statutory Details | employeeId | DefaultPaginator | ✅ | ❌ | +| Employee Bank Details | employeeId | DefaultPaginator | ✅ | ❌ | +| Employee PF & ESI details | employeeId | DefaultPaginator | ✅ | ❌ | +| Employee Qualifications Details | | DefaultPaginator | ✅ | ❌ | +| Users List | | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50603](https://github.com/airbytehq/airbyte/pull/50603) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50126](https://github.com/airbytehq/airbyte/pull/50126) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49621](https://github.com/airbytehq/airbyte/pull/49621) | Update dependencies | +| 0.0.2 | 2024-12-12 | [48920](https://github.com/airbytehq/airbyte/pull/48920) | Update dependencies | +| 0.0.1 | 2024-11-29 | | Initial release by [@bhushan-dhwaniris](https://github.com/bhushan-dhwaniris) via Connector Builder | + +
diff --git a/docs/integrations/sources/gridly.md b/docs/integrations/sources/gridly.md index 30005355f0b4..e04a71229120 100644 --- a/docs/integrations/sources/gridly.md +++ b/docs/integrations/sources/gridly.md @@ -38,6 +38,10 @@ This page contains the setup guide and reference information for the Gridly sour | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :---------------------------------------------------------- | +| 0.1.26 | 2024-12-28 | [50663](https://github.com/airbytehq/airbyte/pull/50663) | Update dependencies | +| 0.1.25 | 2024-12-21 | [50085](https://github.com/airbytehq/airbyte/pull/50085) | Update dependencies | +| 0.1.24 | 2024-12-14 | [49000](https://github.com/airbytehq/airbyte/pull/49000) | Update dependencies | +| 0.1.23 | 2024-11-25 | [48675](https://github.com/airbytehq/airbyte/pull/48675) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.1.22 | 2024-10-28 | [47075](https://github.com/airbytehq/airbyte/pull/47075) | Update dependencies | | 0.1.21 | 2024-10-12 | [46476](https://github.com/airbytehq/airbyte/pull/46476) | Update dependencies | | 0.1.20 | 2024-09-28 | [46122](https://github.com/airbytehq/airbyte/pull/46122) | Update dependencies | diff --git a/docs/integrations/sources/guru.md b/docs/integrations/sources/guru.md index 92ed77ba5c46..cb1e8bab66b9 100644 --- a/docs/integrations/sources/guru.md +++ b/docs/integrations/sources/guru.md @@ -50,6 +50,12 @@ To set up the Guru source connector, you'll need the [Guru Auth keys](https://de | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.9 | 2024-12-28 | [50622](https://github.com/airbytehq/airbyte/pull/50622) | Update dependencies | +| 0.0.8 | 2024-12-21 | [50118](https://github.com/airbytehq/airbyte/pull/50118) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49622](https://github.com/airbytehq/airbyte/pull/49622) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49271](https://github.com/airbytehq/airbyte/pull/49271) | Update dependencies | +| 0.0.5 | 2024-12-11 | [48903](https://github.com/airbytehq/airbyte/pull/48903) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-11-04 | [48152](https://github.com/airbytehq/airbyte/pull/48152) | Update dependencies | | 0.0.3 | 2024-10-29 | [47830](https://github.com/airbytehq/airbyte/pull/47830) | Update dependencies | | 0.0.2 | 2024-10-28 | [47665](https://github.com/airbytehq/airbyte/pull/47665) | Update dependencies | | 0.0.1 | 2024-08-31 | [45066](https://github.com/airbytehq/airbyte/pull/45066) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/hardcoded-records.md b/docs/integrations/sources/hardcoded-records.md index d21903019251..7fc0b4c47711 100644 --- a/docs/integrations/sources/hardcoded-records.md +++ b/docs/integrations/sources/hardcoded-records.md @@ -149,6 +149,12 @@ None! | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:-------------------------| +| 0.0.23 | 2025-01-04 | [50895](https://github.com/airbytehq/airbyte/pull/50895) | Update dependencies | +| 0.0.22 | 2024-12-28 | [50626](https://github.com/airbytehq/airbyte/pull/50626) | Update dependencies | +| 0.0.21 | 2024-12-21 | [50140](https://github.com/airbytehq/airbyte/pull/50140) | Update dependencies | +| 0.0.20 | 2024-12-14 | [49653](https://github.com/airbytehq/airbyte/pull/49653) | Update dependencies | +| 0.0.19 | 2024-12-11 | [48976](https://github.com/airbytehq/airbyte/pull/48976) | Update dependencies | +| 0.0.18 | 2024-11-25 | [48669](https://github.com/airbytehq/airbyte/pull/48669) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.17 | 2024-10-28 | [47052](https://github.com/airbytehq/airbyte/pull/47052) | Update dependencies | | 0.0.16 | 2024-10-12 | [46773](https://github.com/airbytehq/airbyte/pull/46773) | Update dependencies | | 0.0.15 | 2024-10-05 | [46492](https://github.com/airbytehq/airbyte/pull/46492) | Update dependencies | diff --git a/docs/integrations/sources/harvest.md b/docs/integrations/sources/harvest.md index 8237dfcec32e..574d91bb6576 100644 --- a/docs/integrations/sources/harvest.md +++ b/docs/integrations/sources/harvest.md @@ -91,6 +91,11 @@ The connector is restricted by the [Harvest rate limits](https://help.getharvest | Version | Date | Pull Request | Subject | |:--------| :--------- | :------------------------------------------------------- |:----------------------------------------------------------------------------------------------------------------------------------| +| 1.1.7 | 2025-01-04 | [50629](https://github.com/airbytehq/airbyte/pull/50629) | Update dependencies | +| 1.1.6 | 2024-12-21 | [50081](https://github.com/airbytehq/airbyte/pull/50081) | Update dependencies | +| 1.1.5 | 2024-12-14 | [49634](https://github.com/airbytehq/airbyte/pull/49634) | Update dependencies | +| 1.1.4 | 2024-12-12 | [49213](https://github.com/airbytehq/airbyte/pull/49213) | Update dependencies | +| 1.1.3 | 2024-12-11 | [48159](https://github.com/airbytehq/airbyte/pull/48159) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 1.1.2 | 2024-10-29 | [47817](https://github.com/airbytehq/airbyte/pull/47817) | Update dependencies | | 1.1.1 | 2024-10-28 | [47670](https://github.com/airbytehq/airbyte/pull/47670) | Update dependencies | | 1.1.0 | 2024-10-14 | [46898](https://github.com/airbytehq/airbyte/pull/46898) | Promoting release candidate 1.1.0-rc1 to a main version. | diff --git a/docs/integrations/sources/height.md b/docs/integrations/sources/height.md index fca1d71b76e0..7b92290063f5 100644 --- a/docs/integrations/sources/height.md +++ b/docs/integrations/sources/height.md @@ -37,6 +37,12 @@ API Documentation: https://height.notion.site/API-documentation-643aea5bf01742de | Version | Date | Pull Request | Subject | | ------------------ | ------------ | ---- | ---------------- | +| 0.0.9 | 2024-12-28 | [50610](https://github.com/airbytehq/airbyte/pull/50610) | Update dependencies | +| 0.0.8 | 2024-12-21 | [50094](https://github.com/airbytehq/airbyte/pull/50094) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49597](https://github.com/airbytehq/airbyte/pull/49597) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49225](https://github.com/airbytehq/airbyte/pull/49225) | Update dependencies | +| 0.0.5 | 2024-12-11 | [48977](https://github.com/airbytehq/airbyte/pull/48977) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-11-04 | [48158](https://github.com/airbytehq/airbyte/pull/48158) | Update dependencies | | 0.0.3 | 2024-10-29 | [47790](https://github.com/airbytehq/airbyte/pull/47790) | Update dependencies | | 0.0.2 | 2024-10-28 | [47615](https://github.com/airbytehq/airbyte/pull/47615) | Update dependencies | | 0.0.1 | 2024-08-31 | [45065](https://github.com/airbytehq/airbyte/pull/45065) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/hellobaton.md b/docs/integrations/sources/hellobaton.md index 14fe7e431297..e230c1ff813c 100644 --- a/docs/integrations/sources/hellobaton.md +++ b/docs/integrations/sources/hellobaton.md @@ -56,6 +56,13 @@ The connector is rate limited at 1000 requests per minute per api key. If you fi | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :---------------------------------- | +| 0.3.9 | 2025-01-04 | [50657](https://github.com/airbytehq/airbyte/pull/50657) | Update dependencies | +| 0.3.8 | 2024-12-21 | [50122](https://github.com/airbytehq/airbyte/pull/50122) | Update dependencies | +| 0.3.7 | 2024-12-14 | [49643](https://github.com/airbytehq/airbyte/pull/49643) | Update dependencies | +| 0.3.6 | 2024-12-12 | [49245](https://github.com/airbytehq/airbyte/pull/49245) | Update dependencies | +| 0.3.5 | 2024-12-11 | [48981](https://github.com/airbytehq/airbyte/pull/48981) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.3.4 | 2024-11-05 | [48359](https://github.com/airbytehq/airbyte/pull/48359) | Revert to source-declarative-manifest v5.17.0 | +| 0.3.3 | 2024-11-05 | [48320](https://github.com/airbytehq/airbyte/pull/48320) | Update dependencies | | 0.3.2 | 2024-10-22 | [47236](https://github.com/airbytehq/airbyte/pull/47236) | Update dependencies | | 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.3.0 | 2024-08-15 | [44142](https://github.com/airbytehq/airbyte/pull/44142) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/hibob.md b/docs/integrations/sources/hibob.md index d904bc580da2..94266b972566 100644 --- a/docs/integrations/sources/hibob.md +++ b/docs/integrations/sources/hibob.md @@ -80,6 +80,11 @@ Link to HiBob API documentation [here](https://apidocs.hibob.com/docs/). | Version | Date | Pull Request | Subject | |:---------|:-----------|:---------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------| +| 0.2.6 | 2024-12-28 | [50628](https://github.com/airbytehq/airbyte/pull/50628) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50132](https://github.com/airbytehq/airbyte/pull/50132) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49595](https://github.com/airbytehq/airbyte/pull/49595) | Update dependencies | +| 0.2.3 | 2024-12-12 | [49240](https://github.com/airbytehq/airbyte/pull/49240) | Update dependencies | +| 0.2.2 | 2024-12-11 | [48972](https://github.com/airbytehq/airbyte/pull/48972) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.1 | 2024-10-28 | [47672](https://github.com/airbytehq/airbyte/pull/47672) | Update dependencies | | 0.2.0 | 2024-08-21 | [44542](https://github.com/airbytehq/airbyte/pull/44542) | Refactor connector to manifest-only format | | 0.1.3 | 2024-08-17 | [44298](https://github.com/airbytehq/airbyte/pull/44298) | Update dependencies | diff --git a/docs/integrations/sources/high-level.md b/docs/integrations/sources/high-level.md index 06cb1cf60b81..d9c5e2f6e0c9 100644 --- a/docs/integrations/sources/high-level.md +++ b/docs/integrations/sources/high-level.md @@ -33,6 +33,11 @@ Proxy connector for [Go High Level](https://gohighlevel.com) (Lead Connector). R | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.7 | 2024-12-28 | [50637](https://github.com/airbytehq/airbyte/pull/50637) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50093](https://github.com/airbytehq/airbyte/pull/50093) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49640](https://github.com/airbytehq/airbyte/pull/49640) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49237](https://github.com/airbytehq/airbyte/pull/49237) | Update dependencies | +| 0.0.3 | 2024-12-11 | [48901](https://github.com/airbytehq/airbyte/pull/48901) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.2 | 2024-10-28 | [47472](https://github.com/airbytehq/airbyte/pull/47472) | Update dependencies | | 0.0.1 | 2024-08-23 | | Initial release by [@Stockotaco](https://github.com/stockotaco) via Connector Builder | diff --git a/docs/integrations/sources/hoorayhr.md b/docs/integrations/sources/hoorayhr.md new file mode 100644 index 000000000000..66bc76626135 --- /dev/null +++ b/docs/integrations/sources/hoorayhr.md @@ -0,0 +1,35 @@ +# HoorayHR + +Source connector for HoorayHR (https://hoorayhr.io). The connector uses https://api.hoorayhr.io + +## Configuration + +Use the credentials of your HoorayHR account to configure the connector. Make sure MFA is disabled. Currently this is a limitation of the HoorayHR API. + +| Input | Type | Description | Default Value | +| ------------------ | -------- | ------------------ | ------------- | +| `hoorayhrusername` | `string` | HoorayHR Username. | | +| `hoorayhrpassword` | `string` | HoorayHR Password. | | + +## Streams + +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +| ----------- | ----------- | ------------- | ------------------ | -------------------- | +| sick-leaves | id | No pagination | ✅ | ❌ | +| time-off | id | No pagination | ✅ | ❌ | +| leave-types | id | No pagination | ✅ | ❌ | +| users | id | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +| ------- | ---------- | ------------ | --------------------------------------------------------------------------------------------------- | +| 0.1.2 | 2024-12-28 | [50598](https://github.com/airbytehq/airbyte/pull/50598) | Update dependencies | +| 0.1.1 | 2024-12-21 | [50110](https://github.com/airbytehq/airbyte/pull/50110) | Update dependencies | +| 0.1.0 | 2024-12-17 | | Added some more documentation and icon for HoorayHR by [@JoeriSmits](https://github.com/JoeriSmits) | +| 0.0.1 | 2024-12-17 | | Initial release by [@JoeriSmits](https://github.com/JoeriSmits) via Connector Builder | + +
diff --git a/docs/integrations/sources/hubplanner.md b/docs/integrations/sources/hubplanner.md index 4c93d74b721c..d21826a0b57e 100644 --- a/docs/integrations/sources/hubplanner.md +++ b/docs/integrations/sources/hubplanner.md @@ -44,6 +44,10 @@ The Okta source connector supports the following [sync modes](https://docs.airby | Version | Date | Pull Request | Subject | | :------ | :--- | :----------- | :------ | +| 0.3.6 | 2024-12-28 | [50623](https://github.com/airbytehq/airbyte/pull/50623) | Update dependencies | +| 0.3.5 | 2024-12-21 | [50075](https://github.com/airbytehq/airbyte/pull/50075) | Update dependencies | +| 0.3.4 | 2024-12-14 | [49617](https://github.com/airbytehq/airbyte/pull/49617) | Update dependencies | +| 0.3.3 | 2024-12-12 | [48239](https://github.com/airbytehq/airbyte/pull/48239) | Update dependencies | | 0.3.2 | 2024-10-29 | [47738](https://github.com/airbytehq/airbyte/pull/47738) | Update dependencies | | 0.3.1 | 2024-10-28 | [47511](https://github.com/airbytehq/airbyte/pull/47511) | Update dependencies | | 0.3.0 | 2024-08-22 | [44569](https://github.com/airbytehq/airbyte/pull/44569) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/hubspot.md b/docs/integrations/sources/hubspot.md index b7c3da361c9b..e2c63ee14336 100644 --- a/docs/integrations/sources/hubspot.md +++ b/docs/integrations/sources/hubspot.md @@ -75,6 +75,7 @@ To set up a Private App, you must manually configure scopes to ensure Airbyte ca | `forms` | `forms` | | `form_submissions` | `forms` | | `goals` | `crm.objects.goals.read` | +| `leads` | `crm.objects.leads.read`, `crm.schemas.leads.read` | | `line_items` | `e-commerce` | | `owners` | `crm.objects.owners.read` | | `products` | `e-commerce` | @@ -176,6 +177,7 @@ The HubSpot source connector supports the following streams: - [Forms](https://developers.hubspot.com/docs/api/marketing/forms) \(Client-Side Incremental\) - [Form Submissions](https://legacydocs.hubspot.com/docs/methods/forms/get-submissions-for-a-form) \(Client-Side Incremental\) - [Goals](https://developers.hubspot.com/docs/api/crm/goals) \(Incremental\) +- [Leads](https://developers.hubspot.com/docs/api/crm/leads) \(Incremental\) - [Line Items](https://developers.hubspot.com/docs/api/crm/line-items) \(Incremental\) - [Marketing Emails](https://legacydocs.hubspot.com/docs/methods/cms_email/get-all-marketing-email-statistics) - [Owners](https://developers.hubspot.com/docs/methods/owners/get_owners) \(Client-Side Incremental\) @@ -336,6 +338,16 @@ The connector is restricted by normal HubSpot [rate limitations](https://legacyd | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 4.4.6 | 2025-01-04 | [50898](https://github.com/airbytehq/airbyte/pull/50898) | Update dependencies | +| 4.4.5 | 2024-12-28 | [50669](https://github.com/airbytehq/airbyte/pull/50669) | Update dependencies | +| 4.4.4 | 2024-12-21 | [50138](https://github.com/airbytehq/airbyte/pull/50138) | Update dependencies | +| 4.4.3 | 2024-12-14 | [48984](https://github.com/airbytehq/airbyte/pull/48984) | Update dependencies | +| 4.4.2 | 2024-12-10 | [48480](https://github.com/airbytehq/airbyte/pull/48480) | Adds individual read scopes to LineItems Stream | +| 4.4.1 | 2024-11-25 | [48662](https://github.com/airbytehq/airbyte/pull/48662) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 4.4.0 | 2024-11-18 | [48548](https://github.com/airbytehq/airbyte/pull/48548) | Promoting release candidate 4.4.0-rc.1 to a main version. | +| 4.4.0-rc.1 | 2024-11-18 | [48472](https://github.com/airbytehq/airbyte/pull/48472) | Adds support to maintain use of legacy fields for `Contacts`, `Deals`, and `DealsArchived` streams: `hs_lifecyclestage_{stage_id}_date`, `hs_date_entered_{stage_id}`, `hs_date_exited_{stage_id}`, `hs_time_in_{stage_id}`. | +| 4.3.0 | 2024-11-15 | [44481](https://github.com/airbytehq/airbyte/pull/44481) | Add `Leads` stream | +| 4.2.26 | 2024-11-04 | [48199](https://github.com/airbytehq/airbyte/pull/48199) | Update dependencies | | 4.2.25 | 2024-10-29 | [47028](https://github.com/airbytehq/airbyte/pull/47028) | Update dependencies | | 4.2.24 | 2024-10-12 | [46827](https://github.com/airbytehq/airbyte/pull/46827) | Update dependencies | | 4.2.23 | 2024-10-05 | [46494](https://github.com/airbytehq/airbyte/pull/46494) | Update dependencies | diff --git a/docs/integrations/sources/hugging-face-datasets.md b/docs/integrations/sources/hugging-face-datasets.md new file mode 100644 index 000000000000..d080bcd1a92a --- /dev/null +++ b/docs/integrations/sources/hugging-face-datasets.md @@ -0,0 +1,33 @@ +# Hugging Face - Datasets +Imports datasets from Hugging Face ([https://huggingface.co/datasets](https://huggingface.co/datasets)) + +Only datasets with [Parquet exports](https://huggingface.co/docs/dataset-viewer/en/parquet) can be imported with this connector. +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `dataset_name` | `string` | Dataset Name. | | +| `dataset_subsets` | `array` | Dataset Subsets. Dataset Subsets to import. Will import all of them if nothing is provided (see https://huggingface.co/docs/dataset-viewer/en/configs_and_splits for more details) | | +| `dataset_splits` | `array` | Dataset Splits. Splits to import. Will import all of them if nothing is provided (see https://huggingface.co/docs/dataset-viewer/en/configs_and_splits for more details) | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| rows | | DefaultPaginator | ✅ | ❌ | +| splits | | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50621](https://github.com/airbytehq/airbyte/pull/50621) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50079](https://github.com/airbytehq/airbyte/pull/50079) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49609](https://github.com/airbytehq/airbyte/pull/49609) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49233](https://github.com/airbytehq/airbyte/pull/49233) | Update dependencies | +| 0.0.2 | 2024-12-11 | [48911](https://github.com/airbytehq/airbyte/pull/48911) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-28 | | Initial release by [@michel-tricot](https://github.com/michel-tricot) via Connector Builder | + +
diff --git a/docs/integrations/sources/humanitix.md b/docs/integrations/sources/humanitix.md new file mode 100644 index 000000000000..acdff4866b61 --- /dev/null +++ b/docs/integrations/sources/humanitix.md @@ -0,0 +1,33 @@ +# Humanitix +Humanitix is a ticketing platform. +Using this connector we can extract data from streams such as events , orders and tickets. +Docs : https://humanitix.stoplight.io/docs/humanitix-public-api/e508a657c1467-humanitix-public-api + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| events | _id | DefaultPaginator | ✅ | ❌ | +| orders | _id | DefaultPaginator | ✅ | ❌ | +| tickets | _id | DefaultPaginator | ✅ | ❌ | +| tags | _id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50646](https://github.com/airbytehq/airbyte/pull/50646) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50074](https://github.com/airbytehq/airbyte/pull/50074) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49618](https://github.com/airbytehq/airbyte/pull/49618) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49261](https://github.com/airbytehq/airbyte/pull/49261) | Update dependencies | +| 0.0.1 | 2024-10-31 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/illumina-basespace.md b/docs/integrations/sources/illumina-basespace.md index a04602b8e33c..92e576567991 100644 --- a/docs/integrations/sources/illumina-basespace.md +++ b/docs/integrations/sources/illumina-basespace.md @@ -28,6 +28,10 @@ Connector for the Basespace v1 API. This can be used to extract data on projects | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.7 | 2024-12-28 | [50142](https://github.com/airbytehq/airbyte/pull/50142) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49623](https://github.com/airbytehq/airbyte/pull/49623) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49263](https://github.com/airbytehq/airbyte/pull/49263) | Update dependencies | +| 0.0.4 | 2024-11-04 | [48276](https://github.com/airbytehq/airbyte/pull/48276) | Update dependencies | | 0.0.3 | 2024-10-29 | [47907](https://github.com/airbytehq/airbyte/pull/47907) | Update dependencies | | 0.0.2 | 2024-10-28 | [47609](https://github.com/airbytehq/airbyte/pull/47609) | Update dependencies | | 0.0.1 | 2024-09-23 | | Initial release by [@FilipeJesus](https://github.com/FilipeJesus) via Connector Builder | diff --git a/docs/integrations/sources/incident-io.md b/docs/integrations/sources/incident-io.md index 210f01d85e12..544cee5b5ed6 100644 --- a/docs/integrations/sources/incident-io.md +++ b/docs/integrations/sources/incident-io.md @@ -54,6 +54,11 @@ The source connector supports the following [sync modes](https://docs.airbyte.co | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50648](https://github.com/airbytehq/airbyte/pull/50648) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50137](https://github.com/airbytehq/airbyte/pull/50137) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49218](https://github.com/airbytehq/airbyte/pull/49218) | Update dependencies | +| 0.0.3 | 2024-12-11 | [48989](https://github.com/airbytehq/airbyte/pull/48989) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.2 | 2024-11-04 | [47842](https://github.com/airbytehq/airbyte/pull/47842) | Update dependencies | | 0.0.1 | 2024-10-03 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | diff --git a/docs/integrations/sources/inflowinventory.md b/docs/integrations/sources/inflowinventory.md new file mode 100644 index 000000000000..dc9d94cc0e61 --- /dev/null +++ b/docs/integrations/sources/inflowinventory.md @@ -0,0 +1,49 @@ +# Inflowinventory +As the name suggests , Inflowinventory is an inventory management software. +Using this connector we can extract data from various streams such as customers , productts and sales orders. +Docs : https://cloudapi.inflowinventory.com/docs/index.html#section/Overview + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | +| `companyid` | `string` | CompanyID. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| adjustment reasons | adjustmentReasonId | No pagination | ✅ | ❌ | +| categories | categoryId | No pagination | ✅ | ❌ | +| currencies | currencyId | No pagination | ✅ | ❌ | +| customers | customFieldsId | No pagination | ✅ | ❌ | +| locations | locationId | No pagination | ✅ | ❌ | +| operation types | operationTypeId | No pagination | ✅ | ❌ | +| payment terms | paymentTermsId | No pagination | ✅ | ❌ | +| pricing schemes | pricingSchemeId | No pagination | ✅ | ❌ | +| products | productId | No pagination | ✅ | ❌ | +| product cost adjustments | productCostAdjustmentId | No pagination | ✅ | ❌ | +| purchase orders | purchaseOrderId | No pagination | ✅ | ❌ | +| sales orders | salesOrderId | No pagination | ✅ | ❌ | +| stock adjustments | stockAdjustmentId | No pagination | ✅ | ❌ | +| stock counts | stockCountId | No pagination | ✅ | ❌ | +| stock transfers | stockTransferId | No pagination | ✅ | ❌ | +| tax codes | taxCodeId | No pagination | ✅ | ❌ | +| taxing schemes | taxingSchemeId | No pagination | ✅ | ❌ | +| team members | teamMemberId | No pagination | ✅ | ❌ | +| vendors | vendorId | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50660](https://github.com/airbytehq/airbyte/pull/50660) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50082](https://github.com/airbytehq/airbyte/pull/50082) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49633](https://github.com/airbytehq/airbyte/pull/49633) | Update dependencies | +| 0.0.2 | 2024-12-12 | [48961](https://github.com/airbytehq/airbyte/pull/48961) | Update dependencies | +| 0.0.1 | 2024-10-29 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/insightly.md b/docs/integrations/sources/insightly.md index b767281222b3..69b42d195aa1 100644 --- a/docs/integrations/sources/insightly.md +++ b/docs/integrations/sources/insightly.md @@ -72,6 +72,11 @@ The connector is restricted by Insightly [requests limitation](https://api.na1.i | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.3.7 | 2024-12-28 | [50631](https://github.com/airbytehq/airbyte/pull/50631) | Update dependencies | +| 0.3.6 | 2024-12-21 | [50087](https://github.com/airbytehq/airbyte/pull/50087) | Update dependencies | +| 0.3.5 | 2024-12-14 | [49646](https://github.com/airbytehq/airbyte/pull/49646) | Update dependencies | +| 0.3.4 | 2024-12-12 | [49243](https://github.com/airbytehq/airbyte/pull/49243) | Update dependencies | +| 0.3.3 | 2024-12-11 | [48288](https://github.com/airbytehq/airbyte/pull/48288) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.3.2 | 2024-10-29 | [47917](https://github.com/airbytehq/airbyte/pull/47917) | Update dependencies | | 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.3.0 | 2024-08-15 | [44140](https://github.com/airbytehq/airbyte/pull/44140) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/instatus.md b/docs/integrations/sources/instatus.md index 7c682d072aca..f8440be9ecda 100644 --- a/docs/integrations/sources/instatus.md +++ b/docs/integrations/sources/instatus.md @@ -67,6 +67,11 @@ The Instatus source connector supports the following [sync modes](https://docs.a | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :---------------------- | +| 0.1.28 | 2025-01-04 | [50887](https://github.com/airbytehq/airbyte/pull/50887) | Update dependencies | +| 0.1.27 | 2024-12-28 | [50609](https://github.com/airbytehq/airbyte/pull/50609) | Update dependencies | +| 0.1.26 | 2024-12-21 | [50076](https://github.com/airbytehq/airbyte/pull/50076) | Update dependencies | +| 0.1.25 | 2024-12-14 | [49268](https://github.com/airbytehq/airbyte/pull/49268) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.1.24 | 2024-12-12 | [49147](https://github.com/airbytehq/airbyte/pull/49147) | Update dependencies | | 0.1.23 | 2024-10-28 | [47027](https://github.com/airbytehq/airbyte/pull/47027) | Update dependencies | | 0.1.22 | 2024-10-12 | [46843](https://github.com/airbytehq/airbyte/pull/46843) | Update dependencies | | 0.1.21 | 2024-10-05 | [46484](https://github.com/airbytehq/airbyte/pull/46484) | Update dependencies | diff --git a/docs/integrations/sources/intercom.md b/docs/integrations/sources/intercom.md index 33524c765387..301f8f5cc8e9 100644 --- a/docs/integrations/sources/intercom.md +++ b/docs/integrations/sources/intercom.md @@ -96,6 +96,8 @@ The Intercom connector should not run into Intercom API limitations under normal | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------| +| 0.9.0-rc.1 | 2024-12-17 | [47240](https://github.com/airbytehq/airbyte/pull/47240) | Migrate to manifest-only format | +| 0.8.3 | 2024-12-12 | [48979](https://github.com/airbytehq/airbyte/pull/48979) | Update dependencies | | 0.8.2 | 2024-10-29 | [47919](https://github.com/airbytehq/airbyte/pull/47919) | Update dependencies | | 0.8.1 | 2024-10-28 | [47537](https://github.com/airbytehq/airbyte/pull/47537) | Update dependencies | | 0.8.0 | 2024-10-23 | [46658](https://github.com/airbytehq/airbyte/pull/46658) | Add `lookback_window` to the source specification | diff --git a/docs/integrations/sources/intruder.md b/docs/integrations/sources/intruder.md index 226dae2cad06..2793a8cd4068 100644 --- a/docs/integrations/sources/intruder.md +++ b/docs/integrations/sources/intruder.md @@ -35,6 +35,11 @@ Intruder.io APIs are under rate limits for the number of API calls allowed per A | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :-------------------------------------------- | +| 0.2.8 | 2024-12-28 | [50666](https://github.com/airbytehq/airbyte/pull/50666) | Update dependencies | +| 0.2.7 | 2024-12-21 | [50113](https://github.com/airbytehq/airbyte/pull/50113) | Update dependencies | +| 0.2.6 | 2024-12-14 | [49619](https://github.com/airbytehq/airbyte/pull/49619) | Update dependencies | +| 0.2.5 | 2024-12-12 | [49255](https://github.com/airbytehq/airbyte/pull/49255) | Update dependencies | +| 0.2.4 | 2024-12-11 | [49001](https://github.com/airbytehq/airbyte/pull/49001) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.3 | 2024-10-29 | [47784](https://github.com/airbytehq/airbyte/pull/47784) | Update dependencies | | 0.2.2 | 2024-10-28 | [47655](https://github.com/airbytehq/airbyte/pull/47655) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/invoiced.md b/docs/integrations/sources/invoiced.md index 9098bff2afd4..e8f4f85a15b7 100644 --- a/docs/integrations/sources/invoiced.md +++ b/docs/integrations/sources/invoiced.md @@ -35,6 +35,11 @@ This Airbyte connector for **Invoiced** enables seamless data integration betwee | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.8 | 2024-12-28 | [50600](https://github.com/airbytehq/airbyte/pull/50600) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50103](https://github.com/airbytehq/airbyte/pull/50103) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49650](https://github.com/airbytehq/airbyte/pull/49650) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49266](https://github.com/airbytehq/airbyte/pull/49266) | Update dependencies | +| 0.0.4 | 2024-12-11 | [48987](https://github.com/airbytehq/airbyte/pull/48987) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.3 | 2024-10-29 | [47734](https://github.com/airbytehq/airbyte/pull/47734) | Update dependencies | | 0.0.2 | 2024-10-28 | [47534](https://github.com/airbytehq/airbyte/pull/47534) | Update dependencies | | 0.0.1 | 2024-10-21 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | diff --git a/docs/integrations/sources/invoiceninja.md b/docs/integrations/sources/invoiceninja.md new file mode 100644 index 000000000000..7cd59e3614bc --- /dev/null +++ b/docs/integrations/sources/invoiceninja.md @@ -0,0 +1,44 @@ +# Invoiceninja +Invoice Ninja is an invoicing, billing, and payment management software. +With this connector we can extract data from various streams such asproducts , invoice , payments and quotes. +Docs : https://api-docs.invoicing.co/#overview--introduction + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| clients | id | DefaultPaginator | ✅ | ❌ | +| products | id | DefaultPaginator | ✅ | ❌ | +| invoices | id | DefaultPaginator | ✅ | ❌ | +| recurring invoices | id | DefaultPaginator | ✅ | ❌ | +| payments | id | DefaultPaginator | ✅ | ❌ | +| quotes | id | DefaultPaginator | ✅ | ❌ | +| credits | id | DefaultPaginator | ✅ | ❌ | +| projects | id | DefaultPaginator | ✅ | ❌ | +| tasks | id | DefaultPaginator | ✅ | ❌ | +| vendors | id | DefaultPaginator | ✅ | ❌ | +| purchase_orders | id | DefaultPaginator | ✅ | ❌ | +| expenses | id | DefaultPaginator | ✅ | ❌ | +| recurring expenses | id | DefaultPaginator | ✅ | ❌ | +| bank transactions | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50664](https://github.com/airbytehq/airbyte/pull/50664) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50134](https://github.com/airbytehq/airbyte/pull/50134) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49605](https://github.com/airbytehq/airbyte/pull/49605) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49234](https://github.com/airbytehq/airbyte/pull/49234) | Update dependencies | +| 0.0.2 | 2024-12-11 | [48917](https://github.com/airbytehq/airbyte/pull/48917) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-07 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/ip2whois.md b/docs/integrations/sources/ip2whois.md index e8ba5aac4034..3663807face4 100644 --- a/docs/integrations/sources/ip2whois.md +++ b/docs/integrations/sources/ip2whois.md @@ -32,6 +32,10 @@ Ip2whois APIs allows you to query up to 500 WHOIS domain name per month. | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.2.6 | 2024-12-28 | [50644](https://github.com/airbytehq/airbyte/pull/50644) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50069](https://github.com/airbytehq/airbyte/pull/50069) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49644](https://github.com/airbytehq/airbyte/pull/49644) | Update dependencies | +| 0.2.3 | 2024-12-12 | [47893](https://github.com/airbytehq/airbyte/pull/47893) | Update dependencies | | 0.2.2 | 2024-10-28 | [47471](https://github.com/airbytehq/airbyte/pull/47471) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-15 | [44138](https://github.com/airbytehq/airbyte/pull/44138) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/iterable.md b/docs/integrations/sources/iterable.md index c6097195cbc8..9f0979ec57f8 100644 --- a/docs/integrations/sources/iterable.md +++ b/docs/integrations/sources/iterable.md @@ -83,6 +83,12 @@ The Iterable source connector supports the following [sync modes](https://docs.a | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 0.6.23 | 2025-01-04 | [50889](https://github.com/airbytehq/airbyte/pull/50889) | Update dependencies | +| 0.6.22 | 2024-12-28 | [50608](https://github.com/airbytehq/airbyte/pull/50608) | Update dependencies | +| 0.6.21 | 2024-12-21 | [50101](https://github.com/airbytehq/airbyte/pull/50101) | Update dependencies | +| 0.6.20 | 2024-12-14 | [49211](https://github.com/airbytehq/airbyte/pull/49211) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.6.19 | 2024-12-12 | [48993](https://github.com/airbytehq/airbyte/pull/48993) | Update dependencies | +| 0.6.18 | 2024-11-04 | [48294](https://github.com/airbytehq/airbyte/pull/48294) | Update dependencies | | 0.6.17 | 2024-10-29 | [47803](https://github.com/airbytehq/airbyte/pull/47803) | Update dependencies | | 0.6.16 | 2024-10-28 | [47487](https://github.com/airbytehq/airbyte/pull/47487) | Update dependencies | | 0.6.15 | 2024-10-23 | [47057](https://github.com/airbytehq/airbyte/pull/47057) | Update dependencies | diff --git a/docs/integrations/sources/jina-ai-reader.md b/docs/integrations/sources/jina-ai-reader.md index 3aea9f742eeb..ba6742edea63 100644 --- a/docs/integrations/sources/jina-ai-reader.md +++ b/docs/integrations/sources/jina-ai-reader.md @@ -50,6 +50,12 @@ The website also provides a free bearer token for testing with its interface. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------- | +| 0.1.26 | 2025-01-04 | [50892](https://github.com/airbytehq/airbyte/pull/50892) | Update dependencies | +| 0.1.25 | 2024-12-28 | [50618](https://github.com/airbytehq/airbyte/pull/50618) | Update dependencies | +| 0.1.24 | 2024-12-21 | [50115](https://github.com/airbytehq/airbyte/pull/50115) | Update dependencies | +| 0.1.23 | 2024-12-14 | [49274](https://github.com/airbytehq/airbyte/pull/49274) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.1.22 | 2024-12-12 | [48929](https://github.com/airbytehq/airbyte/pull/48929) | Update dependencies | +| 0.1.21 | 2024-11-04 | [48170](https://github.com/airbytehq/airbyte/pull/48170) | Update dependencies | | 0.1.20 | 2024-10-28 | [47085](https://github.com/airbytehq/airbyte/pull/47085) | Update dependencies | | 0.1.19 | 2024-10-12 | [46768](https://github.com/airbytehq/airbyte/pull/46768) | Update dependencies | | 0.1.18 | 2024-10-05 | [46446](https://github.com/airbytehq/airbyte/pull/46446) | Update dependencies | diff --git a/docs/integrations/sources/jira.md b/docs/integrations/sources/jira.md index 0af7a7d11f8c..a5b48fe00d8a 100644 --- a/docs/integrations/sources/jira.md +++ b/docs/integrations/sources/jira.md @@ -126,6 +126,17 @@ This connector outputs the following incremental streams: If there are more endpoints you'd like Airbyte to support, please [create an issue.](https://github.com/airbytehq/airbyte/issues/new/choose) +### Streams on I/O Usage + +In the list above, there is a subset of streams which requires to make one HTTP request per issue. Those streams can significantly slow down that a sync given a high number of issues. If you have one or many of those streams and experience slowness, we recommend filtering the list of issues using the list of projects in the configuration or simply removing those streams from the sync. +* Issue comments +* Issue properties +* Issue remote links +* Issue transactions +* Issue votes +* Issue watchers +* Issue worklogs + ### Entity-Relationship Diagram (ERD) @@ -152,90 +163,102 @@ The Jira connector should not run into Jira API limitations under normal usage.
Expand to review -| Version | Date | Pull Request | Subject | -|:--------|:-----------|:-----------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 3.2.1 | 2024-10-12 | [44650](https://github.com/airbytehq/airbyte/pull/44650) | Update dependencies | -| 3.2.0 | 2024-10-10 | [46344](https://github.com/airbytehq/airbyte/pull/46344) | Update CDK v5 | -| 3.1.1 | 2024-08-17 | [44251](https://github.com/airbytehq/airbyte/pull/44251) | Update dependencies | -| 3.1.0 | 2024-08-13 | [39558](https://github.com/airbytehq/airbyte/pull/39558) | Ensure config_error when state has improper format | -| 3.0.14 | 2024-08-12 | [43885](https://github.com/airbytehq/airbyte/pull/43885) | Update dependencies | -| 3.0.13 | 2024-08-10 | [43542](https://github.com/airbytehq/airbyte/pull/43542) | Update dependencies | -| 3.0.12 | 2024-08-03 | [43196](https://github.com/airbytehq/airbyte/pull/43196) | Update dependencies | -| 3.0.11 | 2024-07-27 | [42802](https://github.com/airbytehq/airbyte/pull/42802) | Update dependencies | -| 3.0.10 | 2024-07-20 | [42231](https://github.com/airbytehq/airbyte/pull/42231) | Update dependencies | -| 3.0.9 | 2024-07-13 | [41842](https://github.com/airbytehq/airbyte/pull/41842) | Update dependencies | -| 3.0.8 | 2024-07-10 | [41453](https://github.com/airbytehq/airbyte/pull/41453) | Update dependencies | -| 3.0.7 | 2024-07-09 | [41175](https://github.com/airbytehq/airbyte/pull/41175) | Update dependencies | -| 3.0.6 | 2024-07-06 | [40785](https://github.com/airbytehq/airbyte/pull/40785) | Update dependencies | -| 3.0.5 | 2024-06-27 | [40215](https://github.com/airbytehq/airbyte/pull/40215) | Replaced deprecated AirbyteLogger with logging.Logger | -| 3.0.4 | 2024-06-26 | [40549](https://github.com/airbytehq/airbyte/pull/40549) | Migrate off deprecated auth package | -| 3.0.3 | 2024-06-25 | [40444](https://github.com/airbytehq/airbyte/pull/40444) | Update dependencies | -| 3.0.2 | 2024-06-21 | [40121](https://github.com/airbytehq/airbyte/pull/40121) | Update dependencies | -| 3.0.1 | 2024-06-13 | [39458](https://github.com/airbytehq/airbyte/pull/39458) | Fix skipping custom_field_options entities when schema.items is options | -| 3.0.0 | 2024-06-14 | [39467](https://github.com/airbytehq/airbyte/pull/39467) | Update pk for Workflows stream from Id(object) to entityId, name(string, string) | -| 2.0.3 | 2024-06-10 | [39347](https://github.com/airbytehq/airbyte/pull/39347) | Update state handling for incremental Python streams | -| 2.0.2 | 2024-06-06 | [39310](https://github.com/airbytehq/airbyte/pull/39310) | Fix projects substreams for deleted projects | -| 2.0.1 | 2024-05-20 | [38341](https://github.com/airbytehq/airbyte/pull/38341) | Update CDK authenticator package | -| 2.0.0 | 2024-04-20 | [37374](https://github.com/airbytehq/airbyte/pull/37374) | Migrate to low-code and fix `Project Avatars` stream | -| 1.2.2 | 2024-04-19 | [36646](https://github.com/airbytehq/airbyte/pull/36646) | Updating to 0.80.0 CDK | -| 1.2.1 | 2024-04-12 | [36646](https://github.com/airbytehq/airbyte/pull/36646) | schema descriptions | -| 1.2.0 | 2024-03-19 | [36267](https://github.com/airbytehq/airbyte/pull/36267) | Pin airbyte-cdk version to `^0` | -| 1.1.0 | 2024-02-27 | [35656](https://github.com/airbytehq/airbyte/pull/35656) | Add new fields to streams `board_issues`, `filter_sharing`, `filters`, `issues`, `permission_schemes`, `sprint_issues`, `users_groups_detailed`, and `workflows` | -| 1.0.2 | 2024-02-12 | [35160](https://github.com/airbytehq/airbyte/pull/35160) | Manage dependencies with Poetry. | -| 1.0.1 | 2024-01-24 | [34470](https://github.com/airbytehq/airbyte/pull/34470) | Add state checkpoint interval for all streams | -| 1.0.0 | 2024-01-01 | [33715](https://github.com/airbytehq/airbyte/pull/33715) | Save state for stream `Board Issues` per `board` | -| 0.14.1 | 2023-12-19 | [33625](https://github.com/airbytehq/airbyte/pull/33625) | Skip 404 error | -| 0.14.0 | 2023-12-15 | [33532](https://github.com/airbytehq/airbyte/pull/33532) | Add lookback window | -| 0.13.0 | 2023-12-12 | [33353](https://github.com/airbytehq/airbyte/pull/33353) | Fix check command to check access for all available streams | -| 0.12.0 | 2023-12-01 | [33011](https://github.com/airbytehq/airbyte/pull/33011) | Fix BoardIssues stream; increase number of retries for backoff policy to 10 | -| 0.11.0 | 2023-11-29 | [32927](https://github.com/airbytehq/airbyte/pull/32927) | Fix incremental syncs for stream Issues | -| 0.10.2 | 2023-10-26 | [31896](https://github.com/airbytehq/airbyte/pull/31896) | Provide better guidance when configuring the connector with an invalid domain | -| 0.10.1 | 2023-10-23 | [31702](https://github.com/airbytehq/airbyte/pull/31702) | Base image migration: remove Dockerfile and use the python-connector-base image | -| 0.10.0 | 2023-10-13 | [\#31385](https://github.com/airbytehq/airbyte/pull/31385) | Fixed `aggregatetimeoriginalestimate, timeoriginalestimate` field types for the `Issues` stream schema | -| 0.9.0 | 2023-09-26 | [\#30688](https://github.com/airbytehq/airbyte/pull/30688) | Added `createdDate` field to sprints schema, Removed `Expand Issues stream` from spec | -| 0.8.0 | 2023-09-26 | [\#30755](https://github.com/airbytehq/airbyte/pull/30755) | Add new streams: `Issue custom field options`, `IssueTypes`, `Project Roles` | -| 0.7.2 | 2023-09-19 | [\#30675](https://github.com/airbytehq/airbyte/pull/30675) | Ensure invalid URL does not trigger Sentry alert | -| 0.7.1 | 2023-09-19 | [\#30585](https://github.com/airbytehq/airbyte/pull/30585) | Add skip for 404 error in issue properties steam | -| 0.7.0 | 2023-09-17 | [\#30532](https://github.com/airbytehq/airbyte/pull/30532) | Add foreign key to stream record where it missing | -| 0.6.3 | 2023-09-19 | [\#30515](https://github.com/airbytehq/airbyte/pull/30515) | Add transform for invalid date-time format, add 404 handling for check | -| 0.6.2 | 2023-09-19 | [\#30578](https://github.com/airbytehq/airbyte/pull/30578) | Fetch deleted and archived Projects | -| 0.6.1 | 2023-09-17 | [\#30550](https://github.com/airbytehq/airbyte/pull/30550) | Update `Issues` expand settings | -| 0.6.0 | 2023-09-17 | [\#30507](https://github.com/airbytehq/airbyte/pull/30507) | Add new stream `IssueTransitions` | -| 0.5.0 | 2023-09-14 | [\#29960](https://github.com/airbytehq/airbyte/pull/29960) | Add `boardId` to `sprints` stream | -| 0.3.14 | 2023-09-11 | [\#30297](https://github.com/airbytehq/airbyte/pull/30297) | Remove `requests` and `pendulum` from setup dependencies | -| 0.3.13 | 2023-09-01 | [\#30108](https://github.com/airbytehq/airbyte/pull/30108) | Skip 404 error for stream `IssueWatchers` | -| 0.3.12 | 2023-06-01 | [\#26652](https://github.com/airbytehq/airbyte/pull/26652) | Expand on `leads` for `projects` stream | -| 0.3.11 | 2023-06-01 | [\#26906](https://github.com/airbytehq/airbyte/pull/26906) | Handle project permissions error | -| 0.3.10 | 2023-05-26 | [\#26652](https://github.com/airbytehq/airbyte/pull/26652) | Fixed bug when `board` doesn't support `sprints` | -| 0.3.9 | 2023-05-16 | [\#26114](https://github.com/airbytehq/airbyte/pull/26114) | Update fields info in docs and spec, update to latest airbyte-cdk | -| 0.3.8 | 2023-05-04 | [\#25798](https://github.com/airbytehq/airbyte/pull/25798) | Add sprint info to `sprint_issues` and `sprints` streams for team-managed projects | -| 0.3.7 | 2023-04-18 | [\#25275](https://github.com/airbytehq/airbyte/pull/25275) | Add missing types to issues json schema | -| 0.3.6 | 2023-04-10 | [\#24636](https://github.com/airbytehq/airbyte/pull/24636) | Removed Connector Domain Pattern from Spec | -| 0.3.5 | 2023-04-05 | [\#24890](https://github.com/airbytehq/airbyte/pull/24890) | Fix streams "IssuePropertyKeys", "ScreenTabFields" | -| 0.3.4 | 2023-02-14 | [\#23006](https://github.com/airbytehq/airbyte/pull/23006) | Remove caching for `Issues` stream | -| 0.3.3 | 2023-01-04 | [\#20739](https://github.com/airbytehq/airbyte/pull/20739) | fix: check_connection fails if no projects are defined | -| 0.3.2 | 2022-12-23 | [\#20859](https://github.com/airbytehq/airbyte/pull/20859) | Fixed pagination for streams `issue_remote_links`, `sprints` | -| 0.3.1 | 2022-12-14 | [\#20128](https://github.com/airbytehq/airbyte/pull/20128) | Improved code to become beta | -| 0.3.0 | 2022-11-03 | [\#18901](https://github.com/airbytehq/airbyte/pull/18901) | Adds UserGroupsDetailed schema, fix Incremental normalization, add Incremental support for IssueComments, IssueWorklogs | -| 0.2.23 | 2022-10-28 | [\#18505](https://github.com/airbytehq/airbyte/pull/18505) | Correcting `max_results` bug introduced in connector stream | -| 0.2.22 | 2022-10-03 | [\#16944](https://github.com/airbytehq/airbyte/pull/16944) | Adds support for `max_results` to `users` stream | -| 0.2.21 | 2022-07-28 | [\#15135](https://github.com/airbytehq/airbyte/pull/15135) | Adds components to `fields` object on `issues` stream | -| 0.2.20 | 2022-05-25 | [\#13202](https://github.com/airbytehq/airbyte/pull/13202) | Adds resolutiondate to `fields` object on `issues` stream | -| 0.2.19 | 2022-05-04 | [\#10835](https://github.com/airbytehq/airbyte/pull/10835) | Change description for array fields | -| 0.2.18 | 2021-12-23 | [\#7378](https://github.com/airbytehq/airbyte/pull/7378) | Adds experimental endpoint Pull Request | -| 0.2.17 | 2021-12-23 | [\#9079](https://github.com/airbytehq/airbyte/pull/9079) | Update schema for `filters` stream + fix fetching `filters` stream | -| 0.2.16 | 2021-12-21 | [\#8999](https://github.com/airbytehq/airbyte/pull/8999) | Update connector fields title/description | -| 0.2.15 | 2021-11-01 | [\#7398](https://github.com/airbytehq/airbyte/pull/7398) | Add option to render fields in HTML format and fix sprint_issue ids | -| 0.2.14 | 2021-10-27 | [\#7408](https://github.com/airbytehq/airbyte/pull/7408) | Fix normalization step error. Fix schemas. Fix `acceptance-test-config.yml`. Fix `streams.py`. | -| 0.2.13 | 2021-10-20 | [\#7222](https://github.com/airbytehq/airbyte/pull/7222) | Source Jira: Make recently added configs optional for backwards compatibility | -| 0.2.12 | 2021-10-19 | [\#6621](https://github.com/airbytehq/airbyte/pull/6621) | Add Board, Epic, and Sprint streams | -| 0.2.11 | 2021-09-02 | [\#6523](https://github.com/airbytehq/airbyte/pull/6523) | Add cache and more streams \(boards and sprints\) | -| 0.2.9 | 2021-07-28 | [\#5426](https://github.com/airbytehq/airbyte/pull/5426) | Changed cursor field from fields.created to fields.updated for Issues stream. Made Issues worklogs stream full refresh. | -| 0.2.8 | 2021-07-28 | [\#4947](https://github.com/airbytehq/airbyte/pull/4947) | Source Jira: fixing schemas accordingly to response. | -| 0.2.7 | 2021-07-19 | [\#4817](https://github.com/airbytehq/airbyte/pull/4817) | Fixed `labels` schema properties issue. | -| 0.2.6 | 2021-06-15 | [\#4113](https://github.com/airbytehq/airbyte/pull/4113) | Fixed `user` stream with the correct endpoint and query param. | -| 0.2.5 | 2021-06-09 | [\#3973](https://github.com/airbytehq/airbyte/pull/3973) | Added `AIRBYTE_ENTRYPOINT` in base Docker image for Kubernetes support. | -| 0.2.4 | | | Implementing base_read acceptance test dived by stream groups. | -| 0.2.3 | | | Implementing incremental sync. Migrated to airbyte-cdk. Adding all available entities in Jira Cloud. | +| Version | Date | Pull Request | Subject | +|:-----------|:-----------|:-----------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 3.4.7 | 2025-01-04 | [50886](https://github.com/airbytehq/airbyte/pull/50886) | Update dependencies | +| 3.4.6 | 2024-12-28 | [50625](https://github.com/airbytehq/airbyte/pull/50625) | Update dependencies | +| 3.4.5 | 2024-12-21 | [50108](https://github.com/airbytehq/airbyte/pull/50108) | Update dependencies | +| 3.4.4 | 2024-12-14 | [49224](https://github.com/airbytehq/airbyte/pull/49224) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 3.4.3 | 2024-12-12 | [47087](https://github.com/airbytehq/airbyte/pull/47087) | Update dependencies | +| 3.4.2 | 2024-12-09 | [48838](https://github.com/airbytehq/airbyte/pull/48838) | Fixing timezone gaps with state | +| 3.4.1 | 2024-12-09 | [48859](https://github.com/airbytehq/airbyte/pull/48859) | Add a couple of fixes regarding memory usage | +| 3.4.0 | 2024-12-05 | [48738](https://github.com/airbytehq/airbyte/pull/48738) | Enable concurrency for substreams without cursor | +| 3.3.1 | 2024-11-18 | [48539](https://github.com/airbytehq/airbyte/pull/48539) | Update dependencies | +| 3.3.0-rc.3 | 2024-11-14 | [48395](https://github.com/airbytehq/airbyte/pull/48395) | Change JQL filters comparing cursor values to use milliseconds since unix epoch so that data isn't skipped when the active timezone is a negative UTC offset | +| 3.3.0-rc.2 | 2024-11-08 | [38612](https://github.com/airbytehq/airbyte/pull/38612) | Add substream state migration. Update CDK to v6. | +| 3.3.0-rc.1 | 2024-10-28 | [38612](https://github.com/airbytehq/airbyte/pull/38612) | Migrate IssueComments and IssueWorklogs streams to low-code (This change is irreversible) | +| 3.2.1 | 2024-10-12 | [44650](https://github.com/airbytehq/airbyte/pull/44650) | Update dependencies | +| 3.2.0 | 2024-10-10 | [46344](https://github.com/airbytehq/airbyte/pull/46344) | Update CDK v5 | +| 3.1.1 | 2024-08-17 | [44251](https://github.com/airbytehq/airbyte/pull/44251) | Update dependencies | +| 3.1.0 | 2024-08-13 | [39558](https://github.com/airbytehq/airbyte/pull/39558) | Ensure config_error when state has improper format | +| 3.0.14 | 2024-08-12 | [43885](https://github.com/airbytehq/airbyte/pull/43885) | Update dependencies | +| 3.0.13 | 2024-08-10 | [43542](https://github.com/airbytehq/airbyte/pull/43542) | Update dependencies | +| 3.0.12 | 2024-08-03 | [43196](https://github.com/airbytehq/airbyte/pull/43196) | Update dependencies | +| 3.0.11 | 2024-07-27 | [42802](https://github.com/airbytehq/airbyte/pull/42802) | Update dependencies | +| 3.0.10 | 2024-07-20 | [42231](https://github.com/airbytehq/airbyte/pull/42231) | Update dependencies | +| 3.0.9 | 2024-07-13 | [41842](https://github.com/airbytehq/airbyte/pull/41842) | Update dependencies | +| 3.0.8 | 2024-07-10 | [41453](https://github.com/airbytehq/airbyte/pull/41453) | Update dependencies | +| 3.0.7 | 2024-07-09 | [41175](https://github.com/airbytehq/airbyte/pull/41175) | Update dependencies | +| 3.0.6 | 2024-07-06 | [40785](https://github.com/airbytehq/airbyte/pull/40785) | Update dependencies | +| 3.0.5 | 2024-06-27 | [40215](https://github.com/airbytehq/airbyte/pull/40215) | Replaced deprecated AirbyteLogger with logging.Logger | +| 3.0.4 | 2024-06-26 | [40549](https://github.com/airbytehq/airbyte/pull/40549) | Migrate off deprecated auth package | +| 3.0.3 | 2024-06-25 | [40444](https://github.com/airbytehq/airbyte/pull/40444) | Update dependencies | +| 3.0.2 | 2024-06-21 | [40121](https://github.com/airbytehq/airbyte/pull/40121) | Update dependencies | +| 3.0.1 | 2024-06-13 | [39458](https://github.com/airbytehq/airbyte/pull/39458) | Fix skipping custom_field_options entities when schema.items is options | +| 3.0.0 | 2024-06-14 | [39467](https://github.com/airbytehq/airbyte/pull/39467) | Update pk for Workflows stream from Id(object) to entityId, name(string, string) | +| 2.0.3 | 2024-06-10 | [39347](https://github.com/airbytehq/airbyte/pull/39347) | Update state handling for incremental Python streams | +| 2.0.2 | 2024-06-06 | [39310](https://github.com/airbytehq/airbyte/pull/39310) | Fix projects substreams for deleted projects | +| 2.0.1 | 2024-05-20 | [38341](https://github.com/airbytehq/airbyte/pull/38341) | Update CDK authenticator package | +| 2.0.0 | 2024-04-20 | [37374](https://github.com/airbytehq/airbyte/pull/37374) | Migrate to low-code and fix `Project Avatars` stream | +| 1.2.2 | 2024-04-19 | [36646](https://github.com/airbytehq/airbyte/pull/36646) | Updating to 0.80.0 CDK | +| 1.2.1 | 2024-04-12 | [36646](https://github.com/airbytehq/airbyte/pull/36646) | schema descriptions | +| 1.2.0 | 2024-03-19 | [36267](https://github.com/airbytehq/airbyte/pull/36267) | Pin airbyte-cdk version to `^0` | +| 1.1.0 | 2024-02-27 | [35656](https://github.com/airbytehq/airbyte/pull/35656) | Add new fields to streams `board_issues`, `filter_sharing`, `filters`, `issues`, `permission_schemes`, `sprint_issues`, `users_groups_detailed`, and `workflows` | +| 1.0.2 | 2024-02-12 | [35160](https://github.com/airbytehq/airbyte/pull/35160) | Manage dependencies with Poetry. | +| 1.0.1 | 2024-01-24 | [34470](https://github.com/airbytehq/airbyte/pull/34470) | Add state checkpoint interval for all streams | +| 1.0.0 | 2024-01-01 | [33715](https://github.com/airbytehq/airbyte/pull/33715) | Save state for stream `Board Issues` per `board` | +| 0.14.1 | 2023-12-19 | [33625](https://github.com/airbytehq/airbyte/pull/33625) | Skip 404 error | +| 0.14.0 | 2023-12-15 | [33532](https://github.com/airbytehq/airbyte/pull/33532) | Add lookback window | +| 0.13.0 | 2023-12-12 | [33353](https://github.com/airbytehq/airbyte/pull/33353) | Fix check command to check access for all available streams | +| 0.12.0 | 2023-12-01 | [33011](https://github.com/airbytehq/airbyte/pull/33011) | Fix BoardIssues stream; increase number of retries for backoff policy to 10 | +| 0.11.0 | 2023-11-29 | [32927](https://github.com/airbytehq/airbyte/pull/32927) | Fix incremental syncs for stream Issues | +| 0.10.2 | 2023-10-26 | [31896](https://github.com/airbytehq/airbyte/pull/31896) | Provide better guidance when configuring the connector with an invalid domain | +| 0.10.1 | 2023-10-23 | [31702](https://github.com/airbytehq/airbyte/pull/31702) | Base image migration: remove Dockerfile and use the python-connector-base image | +| 0.10.0 | 2023-10-13 | [\#31385](https://github.com/airbytehq/airbyte/pull/31385) | Fixed `aggregatetimeoriginalestimate, timeoriginalestimate` field types for the `Issues` stream schema | +| 0.9.0 | 2023-09-26 | [\#30688](https://github.com/airbytehq/airbyte/pull/30688) | Added `createdDate` field to sprints schema, Removed `Expand Issues stream` from spec | +| 0.8.0 | 2023-09-26 | [\#30755](https://github.com/airbytehq/airbyte/pull/30755) | Add new streams: `Issue custom field options`, `IssueTypes`, `Project Roles` | +| 0.7.2 | 2023-09-19 | [\#30675](https://github.com/airbytehq/airbyte/pull/30675) | Ensure invalid URL does not trigger Sentry alert | +| 0.7.1 | 2023-09-19 | [\#30585](https://github.com/airbytehq/airbyte/pull/30585) | Add skip for 404 error in issue properties steam | +| 0.7.0 | 2023-09-17 | [\#30532](https://github.com/airbytehq/airbyte/pull/30532) | Add foreign key to stream record where it missing | +| 0.6.3 | 2023-09-19 | [\#30515](https://github.com/airbytehq/airbyte/pull/30515) | Add transform for invalid date-time format, add 404 handling for check | +| 0.6.2 | 2023-09-19 | [\#30578](https://github.com/airbytehq/airbyte/pull/30578) | Fetch deleted and archived Projects | +| 0.6.1 | 2023-09-17 | [\#30550](https://github.com/airbytehq/airbyte/pull/30550) | Update `Issues` expand settings | +| 0.6.0 | 2023-09-17 | [\#30507](https://github.com/airbytehq/airbyte/pull/30507) | Add new stream `IssueTransitions` | +| 0.5.0 | 2023-09-14 | [\#29960](https://github.com/airbytehq/airbyte/pull/29960) | Add `boardId` to `sprints` stream | +| 0.3.14 | 2023-09-11 | [\#30297](https://github.com/airbytehq/airbyte/pull/30297) | Remove `requests` and `pendulum` from setup dependencies | +| 0.3.13 | 2023-09-01 | [\#30108](https://github.com/airbytehq/airbyte/pull/30108) | Skip 404 error for stream `IssueWatchers` | +| 0.3.12 | 2023-06-01 | [\#26652](https://github.com/airbytehq/airbyte/pull/26652) | Expand on `leads` for `projects` stream | +| 0.3.11 | 2023-06-01 | [\#26906](https://github.com/airbytehq/airbyte/pull/26906) | Handle project permissions error | +| 0.3.10 | 2023-05-26 | [\#26652](https://github.com/airbytehq/airbyte/pull/26652) | Fixed bug when `board` doesn't support `sprints` | +| 0.3.9 | 2023-05-16 | [\#26114](https://github.com/airbytehq/airbyte/pull/26114) | Update fields info in docs and spec, update to latest airbyte-cdk | +| 0.3.8 | 2023-05-04 | [\#25798](https://github.com/airbytehq/airbyte/pull/25798) | Add sprint info to `sprint_issues` and `sprints` streams for team-managed projects | +| 0.3.7 | 2023-04-18 | [\#25275](https://github.com/airbytehq/airbyte/pull/25275) | Add missing types to issues json schema | +| 0.3.6 | 2023-04-10 | [\#24636](https://github.com/airbytehq/airbyte/pull/24636) | Removed Connector Domain Pattern from Spec | +| 0.3.5 | 2023-04-05 | [\#24890](https://github.com/airbytehq/airbyte/pull/24890) | Fix streams "IssuePropertyKeys", "ScreenTabFields" | +| 0.3.4 | 2023-02-14 | [\#23006](https://github.com/airbytehq/airbyte/pull/23006) | Remove caching for `Issues` stream | +| 0.3.3 | 2023-01-04 | [\#20739](https://github.com/airbytehq/airbyte/pull/20739) | fix: check_connection fails if no projects are defined | +| 0.3.2 | 2022-12-23 | [\#20859](https://github.com/airbytehq/airbyte/pull/20859) | Fixed pagination for streams `issue_remote_links`, `sprints` | +| 0.3.1 | 2022-12-14 | [\#20128](https://github.com/airbytehq/airbyte/pull/20128) | Improved code to become beta | +| 0.3.0 | 2022-11-03 | [\#18901](https://github.com/airbytehq/airbyte/pull/18901) | Adds UserGroupsDetailed schema, fix Incremental normalization, add Incremental support for IssueComments, IssueWorklogs | +| 0.2.23 | 2022-10-28 | [\#18505](https://github.com/airbytehq/airbyte/pull/18505) | Correcting `max_results` bug introduced in connector stream | +| 0.2.22 | 2022-10-03 | [\#16944](https://github.com/airbytehq/airbyte/pull/16944) | Adds support for `max_results` to `users` stream | +| 0.2.21 | 2022-07-28 | [\#15135](https://github.com/airbytehq/airbyte/pull/15135) | Adds components to `fields` object on `issues` stream | +| 0.2.20 | 2022-05-25 | [\#13202](https://github.com/airbytehq/airbyte/pull/13202) | Adds resolutiondate to `fields` object on `issues` stream | +| 0.2.19 | 2022-05-04 | [\#10835](https://github.com/airbytehq/airbyte/pull/10835) | Change description for array fields | +| 0.2.18 | 2021-12-23 | [\#7378](https://github.com/airbytehq/airbyte/pull/7378) | Adds experimental endpoint Pull Request | +| 0.2.17 | 2021-12-23 | [\#9079](https://github.com/airbytehq/airbyte/pull/9079) | Update schema for `filters` stream + fix fetching `filters` stream | +| 0.2.16 | 2021-12-21 | [\#8999](https://github.com/airbytehq/airbyte/pull/8999) | Update connector fields title/description | +| 0.2.15 | 2021-11-01 | [\#7398](https://github.com/airbytehq/airbyte/pull/7398) | Add option to render fields in HTML format and fix sprint_issue ids | +| 0.2.14 | 2021-10-27 | [\#7408](https://github.com/airbytehq/airbyte/pull/7408) | Fix normalization step error. Fix schemas. Fix `acceptance-test-config.yml`. Fix `streams.py`. | +| 0.2.13 | 2021-10-20 | [\#7222](https://github.com/airbytehq/airbyte/pull/7222) | Source Jira: Make recently added configs optional for backwards compatibility | +| 0.2.12 | 2021-10-19 | [\#6621](https://github.com/airbytehq/airbyte/pull/6621) | Add Board, Epic, and Sprint streams | +| 0.2.11 | 2021-09-02 | [\#6523](https://github.com/airbytehq/airbyte/pull/6523) | Add cache and more streams \(boards and sprints\) | +| 0.2.9 | 2021-07-28 | [\#5426](https://github.com/airbytehq/airbyte/pull/5426) | Changed cursor field from fields.created to fields.updated for Issues stream. Made Issues worklogs stream full refresh. | +| 0.2.8 | 2021-07-28 | [\#4947](https://github.com/airbytehq/airbyte/pull/4947) | Source Jira: fixing schemas accordingly to response. | +| 0.2.7 | 2021-07-19 | [\#4817](https://github.com/airbytehq/airbyte/pull/4817) | Fixed `labels` schema properties issue. | +| 0.2.6 | 2021-06-15 | [\#4113](https://github.com/airbytehq/airbyte/pull/4113) | Fixed `user` stream with the correct endpoint and query param. | +| 0.2.5 | 2021-06-09 | [\#3973](https://github.com/airbytehq/airbyte/pull/3973) | Added `AIRBYTE_ENTRYPOINT` in base Docker image for Kubernetes support. | +| 0.2.4 | | | Implementing base_read acceptance test dived by stream groups. | +| 0.2.3 | | | Implementing incremental sync. Migrated to airbyte-cdk. Adding all available entities in Jira Cloud. |
diff --git a/docs/integrations/sources/jobnimbus.md b/docs/integrations/sources/jobnimbus.md new file mode 100644 index 000000000000..25a8324dd3ee --- /dev/null +++ b/docs/integrations/sources/jobnimbus.md @@ -0,0 +1,33 @@ +# JobNimbus +The JobNimbus Airbyte connector enables seamless integration between JobNimbus, a popular CRM and project management tool, and your data pipeline. This connector allows you to automatically sync data from JobNimbus, including contacts records, task information, and more, into your preferred destination. It simplifies data extraction and helps you streamline workflows, enabling efficient analysis and reporting for enhanced business insights. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use. Find it by logging into your JobNimbus account, navigating to settings, and creating a new API key under the API section. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| jobs | jnid | DefaultPaginator | ✅ | ❌ | +| contacts | jnid | DefaultPaginator | ✅ | ❌ | +| tasks | jnid | DefaultPaginator | ✅ | ❌ | +| activities | jnid | DefaultPaginator | ✅ | ❌ | +| files | jnid | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50661](https://github.com/airbytehq/airbyte/pull/50661) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50145](https://github.com/airbytehq/airbyte/pull/50145) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49610](https://github.com/airbytehq/airbyte/pull/49610) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49239](https://github.com/airbytehq/airbyte/pull/49239) | Update dependencies | +| 0.0.2 | 2024-12-11 | [48919](https://github.com/airbytehq/airbyte/pull/48919) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-29 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/jotform.md b/docs/integrations/sources/jotform.md index e1a3427ff09e..fc60052ece06 100644 --- a/docs/integrations/sources/jotform.md +++ b/docs/integrations/sources/jotform.md @@ -32,6 +32,10 @@ To get started, you need a valid API key. | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.7 | 2024-12-28 | [50100](https://github.com/airbytehq/airbyte/pull/50100) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49608](https://github.com/airbytehq/airbyte/pull/49608) | Update dependencies | +| 0.0.5 | 2024-12-12 | [48965](https://github.com/airbytehq/airbyte/pull/48965) | Update dependencies | +| 0.0.4 | 2024-11-04 | [48179](https://github.com/airbytehq/airbyte/pull/48179) | Update dependencies | | 0.0.3 | 2024-10-29 | [47930](https://github.com/airbytehq/airbyte/pull/47930) | Update dependencies | | 0.0.2 | 2024-10-28 | [47603](https://github.com/airbytehq/airbyte/pull/47603) | Update dependencies | | 0.0.1 | 2024-09-12 | | Initial release by [@topefolorunso](https://github.com/topefolorunso) via Connector Builder | diff --git a/docs/integrations/sources/just-sift.md b/docs/integrations/sources/just-sift.md index 4a3983a7154b..1af0e552699f 100644 --- a/docs/integrations/sources/just-sift.md +++ b/docs/integrations/sources/just-sift.md @@ -25,6 +25,11 @@ Wonderi | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50611](https://github.com/airbytehq/airbyte/pull/50611) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50136](https://github.com/airbytehq/airbyte/pull/50136) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49648](https://github.com/airbytehq/airbyte/pull/49648) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49265](https://github.com/airbytehq/airbyte/pull/49265) | Update dependencies | +| 0.0.2 | 2024-12-11 | [48975](https://github.com/airbytehq/airbyte/pull/48975) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.1 | 2024-10-29 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | diff --git a/docs/integrations/sources/justcall.md b/docs/integrations/sources/justcall.md index 973ac9073846..69b02e2a687d 100644 --- a/docs/integrations/sources/justcall.md +++ b/docs/integrations/sources/justcall.md @@ -25,6 +25,12 @@ JustCall connector enables seamless data integration by syncing call logs, conta | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.8 | 2024-12-28 | [50640](https://github.com/airbytehq/airbyte/pull/50640) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50072](https://github.com/airbytehq/airbyte/pull/50072) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49638](https://github.com/airbytehq/airbyte/pull/49638) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49251](https://github.com/airbytehq/airbyte/pull/49251) | Update dependencies | +| 0.0.4 | 2024-12-11 | [48974](https://github.com/airbytehq/airbyte/pull/48974) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.3 | 2024-11-04 | [48164](https://github.com/airbytehq/airbyte/pull/48164) | Update dependencies | | 0.0.2 | 2024-10-29 | [47799](https://github.com/airbytehq/airbyte/pull/47799) | Update dependencies | | 0.0.1 | 2024-10-21 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | diff --git a/docs/integrations/sources/k6-cloud.md b/docs/integrations/sources/k6-cloud.md index 35f61edbb1f2..5abc9c1d3cbe 100644 --- a/docs/integrations/sources/k6-cloud.md +++ b/docs/integrations/sources/k6-cloud.md @@ -32,6 +32,11 @@ This source can sync data from the [K6 Cloud API](https://developers.k6.io). At | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.2.8 | 2024-12-28 | [50656](https://github.com/airbytehq/airbyte/pull/50656) | Update dependencies | +| 0.2.7 | 2024-12-21 | [50077](https://github.com/airbytehq/airbyte/pull/50077) | Update dependencies | +| 0.2.6 | 2024-12-14 | [49612](https://github.com/airbytehq/airbyte/pull/49612) | Update dependencies | +| 0.2.5 | 2024-12-12 | [49242](https://github.com/airbytehq/airbyte/pull/49242) | Update dependencies | +| 0.2.4 | 2024-12-11 | [48204](https://github.com/airbytehq/airbyte/pull/48204) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.3 | 2024-10-29 | [47895](https://github.com/airbytehq/airbyte/pull/47895) | Update dependencies | | 0.2.2 | 2024-10-28 | [47454](https://github.com/airbytehq/airbyte/pull/47454) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/kafka.md b/docs/integrations/sources/kafka.md index 6c5226c3c8d4..b7f80956bba0 100644 --- a/docs/integrations/sources/kafka.md +++ b/docs/integrations/sources/kafka.md @@ -53,11 +53,12 @@ AVRO - deserialize Using confluent API. Please refer (https://docs.confluent.io/ | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------- | -| 0.2.5 | 2024-06-12 | [32538](https://github.com/airbytehq/airbyte/pull/32538) | Fix empty airbyte data column | -| 0.2.4 | 2024-02-13 | [35229](https://github.com/airbytehq/airbyte/pull/35229) | Adopt CDK 0.20.4 | -| 0.2.4 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | -| 0.2.3 | 2022-12-06 | [19587](https://github.com/airbytehq/airbyte/pull/19587) | Fix missing data before consumer is closed | -| 0.2.2 | 2022-11-04 | [18648](https://github.com/airbytehq/airbyte/pull/18648) | Add missing record_count increment for JSON | +| 0.2.6 | 2024-12-18 | [49907](https://github.com/airbytehq/airbyte/pull/49907) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.2.5 | 2024-06-12 | [32538](https://github.com/airbytehq/airbyte/pull/32538) | Fix empty airbyte data column | +| 0.2.4 | 2024-02-13 | [35229](https://github.com/airbytehq/airbyte/pull/35229) | Adopt CDK 0.20.4 | +| 0.2.4 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | +| 0.2.3 | 2022-12-06 | [19587](https://github.com/airbytehq/airbyte/pull/19587) | Fix missing data before consumer is closed | +| 0.2.2 | 2022-11-04 | [18648](https://github.com/airbytehq/airbyte/pull/18648) | Add missing record_count increment for JSON | | 0.2.1 | 2022-11-04 | This version was the same as 0.2.0 and was committed so using 0.2.2 next to keep versions in order | | 0.2.0 | 2022-08-22 | [13864](https://github.com/airbytehq/airbyte/pull/13864) | Added AVRO format support and Support for maximum records to process | | 0.1.7 | 2022-06-17 | [13864](https://github.com/airbytehq/airbyte/pull/13864) | Updated stacktrace format for any trace message errors | @@ -68,4 +69,4 @@ AVRO - deserialize Using confluent API. Please refer (https://docs.confluent.io/ | 0.1.2 | 2021-12-21 | [8865](https://github.com/airbytehq/airbyte/pull/8865) | Fix SASL config read issue | | 0.1.1 | 2021-12-06 | [8524](https://github.com/airbytehq/airbyte/pull/8524) | Update connector fields title/description | - \ No newline at end of file + diff --git a/docs/integrations/sources/katana.md b/docs/integrations/sources/katana.md index e1a40481c33a..47e80605ad6a 100644 --- a/docs/integrations/sources/katana.md +++ b/docs/integrations/sources/katana.md @@ -45,6 +45,11 @@ To generate a live API key: log in to your Katana account. Go to Settings > | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50612](https://github.com/airbytehq/airbyte/pull/50612) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50119](https://github.com/airbytehq/airbyte/pull/50119) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49603](https://github.com/airbytehq/airbyte/pull/49603) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49246](https://github.com/airbytehq/airbyte/pull/49246) | Update dependencies | +| 0.0.3 | 2024-12-11 | [48991](https://github.com/airbytehq/airbyte/pull/48991) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.2 | 2024-10-28 | [47628](https://github.com/airbytehq/airbyte/pull/47628) | Update dependencies | | 0.0.1 | 2024-10-12 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | diff --git a/docs/integrations/sources/kisi.md b/docs/integrations/sources/kisi.md index c485bd5bb688..77258a0a223a 100644 --- a/docs/integrations/sources/kisi.md +++ b/docs/integrations/sources/kisi.md @@ -39,6 +39,13 @@ You can learn more about the API key here https://api.kisi.io/docs#/ | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.10 | 2024-12-28 | [50636](https://github.com/airbytehq/airbyte/pull/50636) | Update dependencies | +| 0.0.9 | 2024-12-21 | [50078](https://github.com/airbytehq/airbyte/pull/50078) | Update dependencies | +| 0.0.8 | 2024-12-14 | [49627](https://github.com/airbytehq/airbyte/pull/49627) | Update dependencies | +| 0.0.7 | 2024-12-12 | [49273](https://github.com/airbytehq/airbyte/pull/49273) | Update dependencies | +| 0.0.6 | 2024-12-11 | [48983](https://github.com/airbytehq/airbyte/pull/48983) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.5 | 2024-11-05 | [48356](https://github.com/airbytehq/airbyte/pull/48356) | Revert to source-declarative-manifest v5.17.0 | +| 0.0.4 | 2024-11-05 | [48332](https://github.com/airbytehq/airbyte/pull/48332) | Update dependencies | | 0.0.3 | 2024-10-29 | [47914](https://github.com/airbytehq/airbyte/pull/47914) | Update dependencies | | 0.0.2 | 2024-10-28 | [47606](https://github.com/airbytehq/airbyte/pull/47606) | Update dependencies | | 0.0.1 | 2024-10-18 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | diff --git a/docs/integrations/sources/kissmetrics.md b/docs/integrations/sources/kissmetrics.md index f9c2e0c63dc8..d4ca6d532aa5 100644 --- a/docs/integrations/sources/kissmetrics.md +++ b/docs/integrations/sources/kissmetrics.md @@ -30,6 +30,11 @@ Refer `https://support.kissmetrics.io/reference/authorization` for more details. | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.8 | 2024-12-28 | [50597](https://github.com/airbytehq/airbyte/pull/50597) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50096](https://github.com/airbytehq/airbyte/pull/50096) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49600](https://github.com/airbytehq/airbyte/pull/49600) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49247](https://github.com/airbytehq/airbyte/pull/49247) | Update dependencies | +| 0.0.4 | 2024-11-04 | [48151](https://github.com/airbytehq/airbyte/pull/48151) | Update dependencies | | 0.0.3 | 2024-10-29 | [47756](https://github.com/airbytehq/airbyte/pull/47756) | Update dependencies | | 0.0.2 | 2024-10-28 | [47650](https://github.com/airbytehq/airbyte/pull/47650) | Update dependencies | | 0.0.1 | 2024-09-21 | [45839](https://github.com/airbytehq/airbyte/pull/45839) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/klarna.md b/docs/integrations/sources/klarna.md index 5bac19022ddf..9e7c28fcf1b3 100644 --- a/docs/integrations/sources/klarna.md +++ b/docs/integrations/sources/klarna.md @@ -62,6 +62,10 @@ Connector will handle an issue with rate limiting as Klarna returns 429 status c | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.3.7 | 2024-12-28 | [50659](https://github.com/airbytehq/airbyte/pull/50659) | Update dependencies | +| 0.3.6 | 2024-12-21 | [50146](https://github.com/airbytehq/airbyte/pull/50146) | Update dependencies | +| 0.3.5 | 2024-12-14 | [49639](https://github.com/airbytehq/airbyte/pull/49639) | Update dependencies | +| 0.3.4 | 2024-12-12 | [49230](https://github.com/airbytehq/airbyte/pull/49230) | Update dependencies | | 0.3.3 | 2024-10-29 | [47478](https://github.com/airbytehq/airbyte/pull/47478) | Update dependencies | | 0.3.2 | 2024-10-21 | [47195](https://github.com/airbytehq/airbyte/pull/47195) | Update dependencies | | 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/klaviyo.md b/docs/integrations/sources/klaviyo.md index d91502730910..3f570030936b 100644 --- a/docs/integrations/sources/klaviyo.md +++ b/docs/integrations/sources/klaviyo.md @@ -95,6 +95,16 @@ contain the `predictive_analytics` field and workflows depending on this field w | Version | Date | Pull Request | Subject | |:--------|:-----------|:-----------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------| +| 2.11.7 | 2025-01-04 | [50893](https://github.com/airbytehq/airbyte/pull/50893) | Update dependencies | +| 2.11.6 | 2024-12-28 | [50653](https://github.com/airbytehq/airbyte/pull/50653) | Update dependencies | +| 2.11.5 | 2024-12-21 | [50088](https://github.com/airbytehq/airbyte/pull/50088) | Update dependencies | +| 2.11.4 | 2024-12-14 | [49250](https://github.com/airbytehq/airbyte/pull/49250) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 2.11.3 | 2024-12-12 | [49144](https://github.com/airbytehq/airbyte/pull/49144) | Update dependencies | +| 2.11.2 | 2024-12-02 | [48748](https://github.com/airbytehq/airbyte/pull/48748) | Bump CDK to evict non retriable requests to avoid high memory usage | +| 2.11.1 | 2024-11-26 | [48710](https://github.com/airbytehq/airbyte/pull/48710) | Retry on "Temporary failure in name resolution" | +| 2.11.0 | 2024-11-18 | [48452](https://github.com/airbytehq/airbyte/pull/48452) | Enable concurrency for syncs that don't have client-side filtering | +| 2.10.14 | 2024-11-07 | [48391](https://github.com/airbytehq/airbyte/pull/48391) | Remove custom datetime cursor dependency | +| 2.10.13 | 2024-11-05 | [48331](https://github.com/airbytehq/airbyte/pull/48331) | Update dependencies | | 2.10.12 | 2024-10-29 | [47797](https://github.com/airbytehq/airbyte/pull/47797) | Update dependencies | | 2.10.11 | 2024-10-28 | [47043](https://github.com/airbytehq/airbyte/pull/47043) | Update dependencies | | 2.10.10 | 2024-10-14 | [46741](https://github.com/airbytehq/airbyte/pull/46741) | Add checkpointing to events stream to improve large syncs after clear data | diff --git a/docs/integrations/sources/kyriba.md b/docs/integrations/sources/kyriba.md index 837bf957cb53..b10553bb7bc8 100644 --- a/docs/integrations/sources/kyriba.md +++ b/docs/integrations/sources/kyriba.md @@ -71,6 +71,11 @@ The Kyriba connector should not run into API limitations under normal usage. [Cr | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------------------- | +| 0.1.29 | 2024-12-28 | [50617](https://github.com/airbytehq/airbyte/pull/50617) | Update dependencies | +| 0.1.28 | 2024-12-21 | [50147](https://github.com/airbytehq/airbyte/pull/50147) | Update dependencies | +| 0.1.27 | 2024-12-14 | [48971](https://github.com/airbytehq/airbyte/pull/48971) | Update dependencies | +| 0.1.26 | 2024-11-25 | [48670](https://github.com/airbytehq/airbyte/pull/48670) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.1.25 | 2024-11-04 | [48314](https://github.com/airbytehq/airbyte/pull/48314) | Update dependencies | | 0.1.24 | 2024-10-28 | [47079](https://github.com/airbytehq/airbyte/pull/47079) | Update dependencies | | 0.1.23 | 2024-10-12 | [46830](https://github.com/airbytehq/airbyte/pull/46830) | Update dependencies | | 0.1.22 | 2024-10-05 | [46459](https://github.com/airbytehq/airbyte/pull/46459) | Update dependencies | diff --git a/docs/integrations/sources/kyve.md b/docs/integrations/sources/kyve.md index 3eaa4fc8cbc9..951f8a58aff3 100644 --- a/docs/integrations/sources/kyve.md +++ b/docs/integrations/sources/kyve.md @@ -29,6 +29,11 @@ You can fetch with one source configuration more than one pool simultaneously. Y | Version | Date | Pull Request | Subject | | :------ | :--------- | :----------- | :--------------------------------------------------- | +| 0.2.25 | 2024-12-28 | [50668](https://github.com/airbytehq/airbyte/pull/50668) | Update dependencies | +| 0.2.24 | 2024-12-21 | [50149](https://github.com/airbytehq/airbyte/pull/50149) | Update dependencies | +| 0.2.23 | 2024-12-14 | [48985](https://github.com/airbytehq/airbyte/pull/48985) | Update dependencies | +| 0.2.22 | 2024-11-25 | [48651](https://github.com/airbytehq/airbyte/pull/48651) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.21 | 2024-11-04 | [48190](https://github.com/airbytehq/airbyte/pull/48190) | Update dependencies | | 0.2.20 | 2024-10-28 | [47078](https://github.com/airbytehq/airbyte/pull/47078) | Update dependencies | | 0.2.19 | 2024-10-12 | [46477](https://github.com/airbytehq/airbyte/pull/46477) | Update dependencies | | 0.2.18 | 2024-09-28 | [45815](https://github.com/airbytehq/airbyte/pull/45815) | Update dependencies | diff --git a/docs/integrations/sources/launchdarkly.md b/docs/integrations/sources/launchdarkly.md index 4c440ad86743..c4930e7d205e 100644 --- a/docs/integrations/sources/launchdarkly.md +++ b/docs/integrations/sources/launchdarkly.md @@ -37,6 +37,11 @@ Launchdarkly APIs are under rate limits for the number of API calls allowed per | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :--------------------------------------------- | +| 0.2.7 | 2024-12-28 | [50604](https://github.com/airbytehq/airbyte/pull/50604) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50104](https://github.com/airbytehq/airbyte/pull/50104) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49642](https://github.com/airbytehq/airbyte/pull/49642) | Update dependencies | +| 0.2.4 | 2024-12-12 | [49257](https://github.com/airbytehq/airbyte/pull/49257) | Update dependencies | +| 0.2.3 | 2024-12-11 | [47856](https://github.com/airbytehq/airbyte/pull/47856) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.2 | 2024-10-28 | [47620](https://github.com/airbytehq/airbyte/pull/47620) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-15 | [44135](https://github.com/airbytehq/airbyte/pull/44135) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/leadfeeder.md b/docs/integrations/sources/leadfeeder.md index 7f0e64d13121..80eb32603f61 100644 --- a/docs/integrations/sources/leadfeeder.md +++ b/docs/integrations/sources/leadfeeder.md @@ -22,6 +22,11 @@ | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.8 | 2024-12-28 | [50144](https://github.com/airbytehq/airbyte/pull/50144) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49624](https://github.com/airbytehq/airbyte/pull/49624) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49244](https://github.com/airbytehq/airbyte/pull/49244) | Update dependencies | +| 0.0.5 | 2024-12-11 | [48909](https://github.com/airbytehq/airbyte/pull/48909) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-11-04 | [48292](https://github.com/airbytehq/airbyte/pull/48292) | Update dependencies | | 0.0.3 | 2024-10-29 | [47916](https://github.com/airbytehq/airbyte/pull/47916) | Update dependencies | | 0.0.2 | 2024-10-28 | [47617](https://github.com/airbytehq/airbyte/pull/47617) | Update dependencies | | 0.0.1 | 2024-08-21 | | Initial release by natikgadzhi via Connector Builder | diff --git a/docs/integrations/sources/lemlist.md b/docs/integrations/sources/lemlist.md index fb001d9da96d..469e4f5c9140 100644 --- a/docs/integrations/sources/lemlist.md +++ b/docs/integrations/sources/lemlist.md @@ -40,6 +40,11 @@ The Lemlist connector should not run into Lemlist API limitations under normal u | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :----------------------- | +| 0.3.7 | 2024-12-28 | [50649](https://github.com/airbytehq/airbyte/pull/50649) | Update dependencies | +| 0.3.6 | 2024-12-21 | [50116](https://github.com/airbytehq/airbyte/pull/50116) | Update dependencies | +| 0.3.5 | 2024-12-14 | [49645](https://github.com/airbytehq/airbyte/pull/49645) | Update dependencies | +| 0.3.4 | 2024-12-12 | [49236](https://github.com/airbytehq/airbyte/pull/49236) | Update dependencies | +| 0.3.3 | 2024-12-11 | [48144](https://github.com/airbytehq/airbyte/pull/48144) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.3.2 | 2024-10-29 | [47818](https://github.com/airbytehq/airbyte/pull/47818) | Update dependencies | | 0.3.1 | 2024-10-28 | [47652](https://github.com/airbytehq/airbyte/pull/47652) | Update dependencies | | 0.3.0 | 2024-08-19 | [44413](https://github.com/airbytehq/airbyte/pull/44413) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/less-annoying-crm.md b/docs/integrations/sources/less-annoying-crm.md new file mode 100644 index 000000000000..0aede2b70d7b --- /dev/null +++ b/docs/integrations/sources/less-annoying-crm.md @@ -0,0 +1,35 @@ +# Less Annoying CRM +Less Annoying CRM connector enables seamless data integration, allowing users to easily sync customer relationship management data into their data warehouses or analytics tools. This connector facilitates efficient tracking of customer information, interactions, and leads, helping businesses centralize CRM data for enhanced analysis and insights. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use. Manage and create your API keys on the Programmer API settings page at https://account.lessannoyingcrm.com/app/Settings/Api. | | +| `start_date` | `string` | Start date. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| users | | DefaultPaginator | ✅ | ❌ | +| contacts | ContactId | DefaultPaginator | ✅ | ❌ | +| tasks | | DefaultPaginator | ✅ | ✅ | +| pipeline_items | PipelineItemId | DefaultPaginator | ✅ | ❌ | +| notes | NoteId | DefaultPaginator | ✅ | ❌ | +| teams | TeamId | No pagination | ✅ | ❌ | +| events | EventId | DefaultPaginator | ✅ | ✅ | +| contact_events | | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.4 | 2024-12-28 | [50665](https://github.com/airbytehq/airbyte/pull/50665) | Update dependencies | +| 0.0.3 | 2024-12-21 | [49606](https://github.com/airbytehq/airbyte/pull/49606) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49227](https://github.com/airbytehq/airbyte/pull/49227) | Update dependencies | +| 0.0.1 | 2024-10-31 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/lightspeed-retail.md b/docs/integrations/sources/lightspeed-retail.md new file mode 100644 index 000000000000..7b4f3e8d5755 --- /dev/null +++ b/docs/integrations/sources/lightspeed-retail.md @@ -0,0 +1,61 @@ +# Lightspeed Retail +Lightspeed Retail is a one-stop commerce platform empowering merchants around the world to simplify, scale and provide exceptional customer experiences. This source connector ingests data from the lightspeed retail API https://www.lightspeedhq.com/ + +In order to use this source, you must first create an account. +Note down the store url name as this will be needed for your subdomain name in the source. +After logging in, you can create your personal token by navigating to Setup -> Personal Token. You can learn more about the API here https://x-series-api.lightspeedhq.com/reference/listcustomers + + + + + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key or access token | | +| `subdomain` | `string` | Subdomain. The subdomain for the retailer, e.g., 'example' in 'example.retail.lightspeed.app'. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| users | id | CursorPagination | ✅ | ❌ | +| customers | id | CursorPagination | ✅ | ❌ | +| audit | id | CursorPagination | ✅ | ❌ | +| brands | id | CursorPagination | ✅ | ❌ | +| attributes | id | CursorPagination | ✅ | ❌ | +| tax | id | CursorPagination | ✅ | ❌ | +| tags | id | CursorPagination | ✅ | ❌ | +| suppliers | id | CursorPagination | ✅ | ❌ | +| serial_numbers | id | CursorPagination | ✅ | ❌ | +| sales | id | CursorPagination | ✅ | ❌ | +| registers | id | CursorPagination | ✅ | ❌ | +| quotes | id | CursorPagination | ✅ | ❌ | +| services | id | CursorPagination | ✅ | ❌ | +| promotions | id | CursorPagination | ✅ | ❌ | +| products | id | CursorPagination | ✅ | ❌ | +| product_categories | id | CursorPagination | ✅ | ❌ | +| price_books | id | CursorPagination | ✅ | ❌ | +| payment_types | id | CursorPagination | ✅ | ❌ | +| outlets | id | CursorPagination | ✅ | ❌ | +| inventory | id | CursorPagination | ✅ | ❌ | +| fulfillments | id | CursorPagination | ✅ | ❌ | +| customer_groups | id | CursorPagination | ✅ | ❌ | +| consignments | id | CursorPagination | ✅ | ❌ | +| consignment_products | product_id | CursorPagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50619](https://github.com/airbytehq/airbyte/pull/50619) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50129](https://github.com/airbytehq/airbyte/pull/50129) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49651](https://github.com/airbytehq/airbyte/pull/49651) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49226](https://github.com/airbytehq/airbyte/pull/49226) | Update dependencies | +| 0.0.2 | 2024-12-11 | [48954](https://github.com/airbytehq/airbyte/pull/48954) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-23 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | + +
diff --git a/docs/integrations/sources/linkedin-ads-migrations.md b/docs/integrations/sources/linkedin-ads-migrations.md index b6b2855da2cb..70d8eb5b4049 100644 --- a/docs/integrations/sources/linkedin-ads-migrations.md +++ b/docs/integrations/sources/linkedin-ads-migrations.md @@ -1,5 +1,40 @@ # LinkedIn Ads Migration Guide +## Upgrading to 5.0.0 + +With LinkedIn Ads v5.0.0, we modified primary keys for stream(s): `ad_campaign_analytics`, `Custom Ad Analytics Reports`, `account_users`. + +This enhances data integrity and improves the efficiency of your syncs. Users with deduping enabled on those streams might have missing data as records would have been collapsed on the wrong primary key. We highly recommend initiating a connection refresh to ensure all the data is available in the destination. + +- `ad_campaign_analytics` +- `Custom Ad Analytics Reports` + +| Old PK | New PK | +|:-------------------------------------|:--------------------------------------------------------| +| `[string_of_pivot_values, end_date]` | `[string_of_pivot_values, end_date, sponsoredCampaign]` | + +- `account_users` + +| Old PK | New PK | +|:------------|:------------------| +| `[account]` | `[account, user]` | + +## Migration Steps + +Clearing your data is required for the affected streams in order to continue syncing successfully. To clear your data +for the affected streams, follow the steps below: + +1. Select **Connections** in the main navbar and select the connection(s) affected by the update. +2. Select the **Schema** tab. + 1. Select **Refresh source schema** to bring in any schema changes. Any detected schema changes will be listed for your review. + 2. Select **OK** to approve changes. +3. Select **Save changes** at the bottom of the page. + 1. Ensure the **Clear affected streams** option is checked to ensure your streams continue syncing successfully with the new schema. +4. Select **Save connection**. + +This will clear the data in your destination for the subset of streams with schema changes. After the clear succeeds, +trigger a sync by clicking **Sync Now**. For more information on clearing your data in Airbyte, see [this page](/operator-guides/clear). + ## Upgrading to 4.0.0 Version 3.X.X introduced a regression in the connector that was reverted in 4.0.0. If you were using 3.X.X, please go through the migration steps. If you were still using 2.X.X, please upgrade to 4.0.0; after that, there are no additional actions required. diff --git a/docs/integrations/sources/linkedin-ads.md b/docs/integrations/sources/linkedin-ads.md index 086f0ffa93a1..5904f5d76c20 100644 --- a/docs/integrations/sources/linkedin-ads.md +++ b/docs/integrations/sources/linkedin-ads.md @@ -191,69 +191,70 @@ After 5 unsuccessful attempts - the connector will stop the sync operation. In s | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------| -| 4.1.4 | 2024-10-12 | [46862](https://github.com/airbytehq/airbyte/pull/46862) | Update dependencies | -| 4.1.3 | 2024-10-05 | [46433](https://github.com/airbytehq/airbyte/pull/46433) | Update dependencies | -| 4.1.2 | 2024-09-28 | [46171](https://github.com/airbytehq/airbyte/pull/46171) | Update dependencies | -| 4.1.1 | 2024-09-21 | [45774](https://github.com/airbytehq/airbyte/pull/45774) | Update dependencies | -| 4.1.0 | 2024-09-20 | [44370](https://github.com/airbytehq/airbyte/pull/44370) | Migrate to low-code | -| 4.0.6 | 2024-09-14 | [45532](https://github.com/airbytehq/airbyte/pull/45532) | Update dependencies | -| 4.0.5 | 2024-09-07 | [45209](https://github.com/airbytehq/airbyte/pull/45209) | Update dependencies | -| 4.0.4 | 2024-08-31 | [44950](https://github.com/airbytehq/airbyte/pull/44950) | Update dependencies | -| 4.0.3 | 2024-08-24 | [44682](https://github.com/airbytehq/airbyte/pull/44682) | Update dependencies | -| 4.0.2 | 2024-08-17 | [44220](https://github.com/airbytehq/airbyte/pull/44220) | Update dependencies | -| 4.0.1 | 2024-08-10 | [43629](https://github.com/airbytehq/airbyte/pull/43629) | Update dependencies | -| 4.0.0 | 2024-08-07 | [43359](https://github.com/airbytehq/airbyte/pull/43359) | Revert low code migration | -| 3.0.1 | 2024-08-03 | [43087](https://github.com/airbytehq/airbyte/pull/43087) | Update dependencies | -| 3.0.0 | 2024-06-18 | [38314](https://github.com/airbytehq/airbyte/pull/38314) | Migrate to low-code | -| 2.1.12 | 2024-07-27 | [42728](https://github.com/airbytehq/airbyte/pull/42728) | Update dependencies | -| 2.1.11 | 2024-07-20 | [42291](https://github.com/airbytehq/airbyte/pull/42291) | Update dependencies | -| 2.1.10 | 2024-07-13 | [41710](https://github.com/airbytehq/airbyte/pull/41710) | Update dependencies | -| 2.1.9 | 2024-07-10 | [41517](https://github.com/airbytehq/airbyte/pull/41517) | Update dependencies | -| 2.1.8 | 2024-07-09 | [41315](https://github.com/airbytehq/airbyte/pull/41315) | Update dependencies | -| 2.1.7 | 2024-07-06 | [40868](https://github.com/airbytehq/airbyte/pull/40868) | Update dependencies | -| 2.1.6 | 2024-06-25 | [40331](https://github.com/airbytehq/airbyte/pull/40331) | Update dependencies | -| 2.1.5 | 2024-06-22 | [39998](https://github.com/airbytehq/airbyte/pull/39998) | Update dependencies | -| 2.1.4 | 2024-06-16 | [39442](https://github.com/airbytehq/airbyte/pull/39442) | Fix README commands, change spec from json to yaml, fix schema states to object | -| 2.1.3 | 2024-06-06 | [39240](https://github.com/airbytehq/airbyte/pull/39240) | [autopull] Upgrade base image to v1.2.2 | -| 2.1.2 | 2024-05-07 | [36648](https://github.com/airbytehq/airbyte/pull/36648) | Schema descriptions | -| 2.1.1 | 2024-05-07 | [38013](https://github.com/airbytehq/airbyte/pull/38013) | Fix an issue where the `Accounts` stream did not correctly handle provided account IDs | -| 2.1.0 | 2024-04-30 | [37573](https://github.com/airbytehq/airbyte/pull/37573) | Update API version to `202404`; add cursor-based pagination | -| 2.0.0 | 2024-04-24 | [37531](https://github.com/airbytehq/airbyte/pull/37531) | Change primary key for Analytics Streams | -| 1.0.1 | 2024-03-28 | [34152](https://github.com/airbytehq/airbyte/pull/34152) | Proceed pagination if return less than expected | -| 1.0.0 | 2024-04-10 | [36927](https://github.com/airbytehq/airbyte/pull/36927) | Update primary key for Analytics Streams | -| 0.8.0 | 2024-03-19 | [36267](https://github.com/airbytehq/airbyte/pull/36267) | Pin airbyte-cdk version to `^0` | -| 0.7.0 | 2024-02-20 | [35465](https://github.com/airbytehq/airbyte/pull/35465) | Per-error reporting and continue sync on stream failures | -| 0.6.8 | 2024-02-09 | [35086](https://github.com/airbytehq/airbyte/pull/35086) | Manage dependencies with Poetry | -| 0.6.7 | 2024-01-11 | [34152](https://github.com/airbytehq/airbyte/pull/34152) | Prepare for airbyte-lib | -| 0.6.6 | 2024-01-15 | [34222](https://github.com/airbytehq/airbyte/pull/34222) | Use stream slices for Analytics streams | -| 0.6.5 | 2023-12-15 | [33530](https://github.com/airbytehq/airbyte/pull/33530) | Fix typo in `Pivot Category` list | -| 0.6.4 | 2023-10-19 | [31599](https://github.com/airbytehq/airbyte/pull/31599) | Base image migration: remove Dockerfile and use the python-connector-base image | -| 0.6.3 | 2023-10-13 | [31396](https://github.com/airbytehq/airbyte/pull/31396) | Fix pagination for reporting | -| 0.6.2 | 2023-08-23 | [31221](https://github.com/airbytehq/airbyte/pull/31221) | Increase max time between messages to 24 hours | -| 0.6.1 | 2023-08-23 | [29600](https://github.com/airbytehq/airbyte/pull/29600) | Update field descriptions | -| 0.6.0 | 2023-08-22 | [29721](https://github.com/airbytehq/airbyte/pull/29721) | Add `Conversions` stream | -| 0.5.0 | 2023-08-14 | [29175](https://github.com/airbytehq/airbyte/pull/29175) | Add Custom report Constructor | -| 0.4.0 | 2023-08-08 | [29175](https://github.com/airbytehq/airbyte/pull/29175) | Add analytics streams | -| 0.3.1 | 2023-08-08 | [29189](https://github.com/airbytehq/airbyte/pull/29189) | Fix empty accounts field | -| 0.3.0 | 2023-08-07 | [29045](https://github.com/airbytehq/airbyte/pull/29045) | Add new fields to schemas; convert datetime fields to `rfc3339` | -| 0.2.1 | 2023-05-30 | [26780](https://github.com/airbytehq/airbyte/pull/26780) | Reduce records limit for Creatives Stream | -| 0.2.0 | 2023-05-23 | [26372](https://github.com/airbytehq/airbyte/pull/26372) | Migrate to LinkedIn API version: May 2023 | -| 0.1.16 | 2023-05-24 | [26512](https://github.com/airbytehq/airbyte/pull/26512) | Removed authSpecification from spec.json in favour of advancedAuth | -| 0.1.15 | 2023-02-13 | [22940](https://github.com/airbytehq/airbyte/pull/22940) | Specified date formatting in specification | -| 0.1.14 | 2023-02-03 | [22361](https://github.com/airbytehq/airbyte/pull/22361) | Turn on default HttpAvailabilityStrategy | -| 0.1.13 | 2023-01-27 | [22013](https://github.com/airbytehq/airbyte/pull/22013) | For adDirectSponsoredContents stream skip accounts which are part of organization | -| 0.1.12 | 2022-10-18 | [18111](https://github.com/airbytehq/airbyte/pull/18111) | For adDirectSponsoredContents stream skip accounts which are part of organization | -| 0.1.11 | 2022-10-07 | [17724](https://github.com/airbytehq/airbyte/pull/17724) | Retry 429/5xx errors when refreshing access token | -| 0.1.10 | 2022-09-28 | [17326](https://github.com/airbytehq/airbyte/pull/17326) | Migrate to per-stream states. | -| 0.1.9 | 2022-07-21 | [14924](https://github.com/airbytehq/airbyte/pull/14924) | Remove `additionalProperties` field from schemas | -| 0.1.8 | 2022-06-07 | [13495](https://github.com/airbytehq/airbyte/pull/13495) | Fixed `base-normalization` issue on `Destination Redshift` caused by wrong casting of `pivot` column | -| 0.1.7 | 2022-05-04 | [12482](https://github.com/airbytehq/airbyte/pull/12482) | Update input configuration copy | -| 0.1.6 | 2022-04-04 | [11690](https://github.com/airbytehq/airbyte/pull/11690) | Small documentation corrections | -| 0.1.5 | 2021-12-21 | [8984](https://github.com/airbytehq/airbyte/pull/8984) | Update connector fields title/description | -| 0.1.4 | 2021-12-02 | [8382](https://github.com/airbytehq/airbyte/pull/8382) | Modify log message in rate-limit cases | -| 0.1.3 | 2021-11-11 | [7839](https://github.com/airbytehq/airbyte/pull/7839) | Added OAuth support | -| 0.1.2 | 2021-11-08 | [7499](https://github.com/airbytehq/airbyte/pull/7499) | Remove base-python dependencies | -| 0.1.1 | 2021-10-02 | [6610](https://github.com/airbytehq/airbyte/pull/6610) | Fix for `Campaigns/targetingCriteria` transformation, coerced `Creatives/variables/values` to string by default | -| 0.1.0 | 2021-09-05 | [5285](https://github.com/airbytehq/airbyte/pull/5285) | Initial release of Native LinkedIn Ads connector for Airbyte | +| 5.0.0 | 2024-11-26 | [48451](https://github.com/airbytehq/airbyte/pull/48451) | Update primary keys for streams ad_campaign_analytics, Custom Ad Analytics Reports and account_users | +| 4.1.4 | 2024-10-12 | [46862](https://github.com/airbytehq/airbyte/pull/46862) | Update dependencies | +| 4.1.3 | 2024-10-05 | [46433](https://github.com/airbytehq/airbyte/pull/46433) | Update dependencies | +| 4.1.2 | 2024-09-28 | [46171](https://github.com/airbytehq/airbyte/pull/46171) | Update dependencies | +| 4.1.1 | 2024-09-21 | [45774](https://github.com/airbytehq/airbyte/pull/45774) | Update dependencies | +| 4.1.0 | 2024-09-20 | [44370](https://github.com/airbytehq/airbyte/pull/44370) | Migrate to low-code | +| 4.0.6 | 2024-09-14 | [45532](https://github.com/airbytehq/airbyte/pull/45532) | Update dependencies | +| 4.0.5 | 2024-09-07 | [45209](https://github.com/airbytehq/airbyte/pull/45209) | Update dependencies | +| 4.0.4 | 2024-08-31 | [44950](https://github.com/airbytehq/airbyte/pull/44950) | Update dependencies | +| 4.0.3 | 2024-08-24 | [44682](https://github.com/airbytehq/airbyte/pull/44682) | Update dependencies | +| 4.0.2 | 2024-08-17 | [44220](https://github.com/airbytehq/airbyte/pull/44220) | Update dependencies | +| 4.0.1 | 2024-08-10 | [43629](https://github.com/airbytehq/airbyte/pull/43629) | Update dependencies | +| 4.0.0 | 2024-08-07 | [43359](https://github.com/airbytehq/airbyte/pull/43359) | Revert low code migration | +| 3.0.1 | 2024-08-03 | [43087](https://github.com/airbytehq/airbyte/pull/43087) | Update dependencies | +| 3.0.0 | 2024-06-18 | [38314](https://github.com/airbytehq/airbyte/pull/38314) | Migrate to low-code | +| 2.1.12 | 2024-07-27 | [42728](https://github.com/airbytehq/airbyte/pull/42728) | Update dependencies | +| 2.1.11 | 2024-07-20 | [42291](https://github.com/airbytehq/airbyte/pull/42291) | Update dependencies | +| 2.1.10 | 2024-07-13 | [41710](https://github.com/airbytehq/airbyte/pull/41710) | Update dependencies | +| 2.1.9 | 2024-07-10 | [41517](https://github.com/airbytehq/airbyte/pull/41517) | Update dependencies | +| 2.1.8 | 2024-07-09 | [41315](https://github.com/airbytehq/airbyte/pull/41315) | Update dependencies | +| 2.1.7 | 2024-07-06 | [40868](https://github.com/airbytehq/airbyte/pull/40868) | Update dependencies | +| 2.1.6 | 2024-06-25 | [40331](https://github.com/airbytehq/airbyte/pull/40331) | Update dependencies | +| 2.1.5 | 2024-06-22 | [39998](https://github.com/airbytehq/airbyte/pull/39998) | Update dependencies | +| 2.1.4 | 2024-06-16 | [39442](https://github.com/airbytehq/airbyte/pull/39442) | Fix README commands, change spec from json to yaml, fix schema states to object | +| 2.1.3 | 2024-06-06 | [39240](https://github.com/airbytehq/airbyte/pull/39240) | [autopull] Upgrade base image to v1.2.2 | +| 2.1.2 | 2024-05-07 | [36648](https://github.com/airbytehq/airbyte/pull/36648) | Schema descriptions | +| 2.1.1 | 2024-05-07 | [38013](https://github.com/airbytehq/airbyte/pull/38013) | Fix an issue where the `Accounts` stream did not correctly handle provided account IDs | +| 2.1.0 | 2024-04-30 | [37573](https://github.com/airbytehq/airbyte/pull/37573) | Update API version to `202404`; add cursor-based pagination | +| 2.0.0 | 2024-04-24 | [37531](https://github.com/airbytehq/airbyte/pull/37531) | Change primary key for Analytics Streams | +| 1.0.1 | 2024-03-28 | [34152](https://github.com/airbytehq/airbyte/pull/34152) | Proceed pagination if return less than expected | +| 1.0.0 | 2024-04-10 | [36927](https://github.com/airbytehq/airbyte/pull/36927) | Update primary key for Analytics Streams | +| 0.8.0 | 2024-03-19 | [36267](https://github.com/airbytehq/airbyte/pull/36267) | Pin airbyte-cdk version to `^0` | +| 0.7.0 | 2024-02-20 | [35465](https://github.com/airbytehq/airbyte/pull/35465) | Per-error reporting and continue sync on stream failures | +| 0.6.8 | 2024-02-09 | [35086](https://github.com/airbytehq/airbyte/pull/35086) | Manage dependencies with Poetry | +| 0.6.7 | 2024-01-11 | [34152](https://github.com/airbytehq/airbyte/pull/34152) | Prepare for airbyte-lib | +| 0.6.6 | 2024-01-15 | [34222](https://github.com/airbytehq/airbyte/pull/34222) | Use stream slices for Analytics streams | +| 0.6.5 | 2023-12-15 | [33530](https://github.com/airbytehq/airbyte/pull/33530) | Fix typo in `Pivot Category` list | +| 0.6.4 | 2023-10-19 | [31599](https://github.com/airbytehq/airbyte/pull/31599) | Base image migration: remove Dockerfile and use the python-connector-base image | +| 0.6.3 | 2023-10-13 | [31396](https://github.com/airbytehq/airbyte/pull/31396) | Fix pagination for reporting | +| 0.6.2 | 2023-08-23 | [31221](https://github.com/airbytehq/airbyte/pull/31221) | Increase max time between messages to 24 hours | +| 0.6.1 | 2023-08-23 | [29600](https://github.com/airbytehq/airbyte/pull/29600) | Update field descriptions | +| 0.6.0 | 2023-08-22 | [29721](https://github.com/airbytehq/airbyte/pull/29721) | Add `Conversions` stream | +| 0.5.0 | 2023-08-14 | [29175](https://github.com/airbytehq/airbyte/pull/29175) | Add Custom report Constructor | +| 0.4.0 | 2023-08-08 | [29175](https://github.com/airbytehq/airbyte/pull/29175) | Add analytics streams | +| 0.3.1 | 2023-08-08 | [29189](https://github.com/airbytehq/airbyte/pull/29189) | Fix empty accounts field | +| 0.3.0 | 2023-08-07 | [29045](https://github.com/airbytehq/airbyte/pull/29045) | Add new fields to schemas; convert datetime fields to `rfc3339` | +| 0.2.1 | 2023-05-30 | [26780](https://github.com/airbytehq/airbyte/pull/26780) | Reduce records limit for Creatives Stream | +| 0.2.0 | 2023-05-23 | [26372](https://github.com/airbytehq/airbyte/pull/26372) | Migrate to LinkedIn API version: May 2023 | +| 0.1.16 | 2023-05-24 | [26512](https://github.com/airbytehq/airbyte/pull/26512) | Removed authSpecification from spec.json in favour of advancedAuth | +| 0.1.15 | 2023-02-13 | [22940](https://github.com/airbytehq/airbyte/pull/22940) | Specified date formatting in specification | +| 0.1.14 | 2023-02-03 | [22361](https://github.com/airbytehq/airbyte/pull/22361) | Turn on default HttpAvailabilityStrategy | +| 0.1.13 | 2023-01-27 | [22013](https://github.com/airbytehq/airbyte/pull/22013) | For adDirectSponsoredContents stream skip accounts which are part of organization | +| 0.1.12 | 2022-10-18 | [18111](https://github.com/airbytehq/airbyte/pull/18111) | For adDirectSponsoredContents stream skip accounts which are part of organization | +| 0.1.11 | 2022-10-07 | [17724](https://github.com/airbytehq/airbyte/pull/17724) | Retry 429/5xx errors when refreshing access token | +| 0.1.10 | 2022-09-28 | [17326](https://github.com/airbytehq/airbyte/pull/17326) | Migrate to per-stream states. | +| 0.1.9 | 2022-07-21 | [14924](https://github.com/airbytehq/airbyte/pull/14924) | Remove `additionalProperties` field from schemas | +| 0.1.8 | 2022-06-07 | [13495](https://github.com/airbytehq/airbyte/pull/13495) | Fixed `base-normalization` issue on `Destination Redshift` caused by wrong casting of `pivot` column | +| 0.1.7 | 2022-05-04 | [12482](https://github.com/airbytehq/airbyte/pull/12482) | Update input configuration copy | +| 0.1.6 | 2022-04-04 | [11690](https://github.com/airbytehq/airbyte/pull/11690) | Small documentation corrections | +| 0.1.5 | 2021-12-21 | [8984](https://github.com/airbytehq/airbyte/pull/8984) | Update connector fields title/description | +| 0.1.4 | 2021-12-02 | [8382](https://github.com/airbytehq/airbyte/pull/8382) | Modify log message in rate-limit cases | +| 0.1.3 | 2021-11-11 | [7839](https://github.com/airbytehq/airbyte/pull/7839) | Added OAuth support | +| 0.1.2 | 2021-11-08 | [7499](https://github.com/airbytehq/airbyte/pull/7499) | Remove base-python dependencies | +| 0.1.1 | 2021-10-02 | [6610](https://github.com/airbytehq/airbyte/pull/6610) | Fix for `Campaigns/targetingCriteria` transformation, coerced `Creatives/variables/values` to string by default | +| 0.1.0 | 2021-09-05 | [5285](https://github.com/airbytehq/airbyte/pull/5285) | Initial release of Native LinkedIn Ads connector for Airbyte | diff --git a/docs/integrations/sources/linkedin-pages.md b/docs/integrations/sources/linkedin-pages.md index 26484e7cc13d..477d631b296c 100644 --- a/docs/integrations/sources/linkedin-pages.md +++ b/docs/integrations/sources/linkedin-pages.md @@ -113,6 +113,11 @@ The source LinkedIn Pages can use either the `client_id`, `client_secret` and `r | Version | Date | Pull Request | Subject | |:--------|:-----------| :------------------------------------------------------- | :--------------------------------------------------- | +| 1.1.8 | 2024-12-28 | [50645](https://github.com/airbytehq/airbyte/pull/50645) | Update dependencies | +| 1.1.7 | 2024-12-21 | [50114](https://github.com/airbytehq/airbyte/pull/50114) | Update dependencies | +| 1.1.6 | 2024-12-14 | [49593](https://github.com/airbytehq/airbyte/pull/49593) | Update dependencies | +| 1.1.5 | 2024-12-12 | [49272](https://github.com/airbytehq/airbyte/pull/49272) | Update dependencies | +| 1.1.4 | 2024-12-11 | [48924](https://github.com/airbytehq/airbyte/pull/48924) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 1.1.3 | 2024-10-29 | [47749](https://github.com/airbytehq/airbyte/pull/47749) | Update dependencies | | 1.1.2 | 2024-10-28 | [47455](https://github.com/airbytehq/airbyte/pull/47455) | Update dependencies | | 1.1.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/linnworks.md b/docs/integrations/sources/linnworks.md index 77f3cc028b70..88a741deddbf 100644 --- a/docs/integrations/sources/linnworks.md +++ b/docs/integrations/sources/linnworks.md @@ -74,6 +74,11 @@ Rate limits for the Linnworks API vary across endpoints. Use the [links in the * | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :-------------------------------------------------------------------------- | +| 0.1.37 | 2024-12-28 | [50634](https://github.com/airbytehq/airbyte/pull/50634) | Update dependencies | +| 0.1.36 | 2024-12-21 | [50148](https://github.com/airbytehq/airbyte/pull/50148) | Update dependencies | +| 0.1.35 | 2024-12-14 | [48880](https://github.com/airbytehq/airbyte/pull/48880) | Update dependencies | +| 0.1.34 | 2024-11-25 | [48665](https://github.com/airbytehq/airbyte/pull/48665) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.1.33 | 2024-11-04 | [48271](https://github.com/airbytehq/airbyte/pull/48271) | Update dependencies | | 0.1.32 | 2024-10-29 | [47877](https://github.com/airbytehq/airbyte/pull/47877) | Update dependencies | | 0.1.31 | 2024-10-28 | [47116](https://github.com/airbytehq/airbyte/pull/47116) | Update dependencies | | 0.1.30 | 2024-10-12 | [46798](https://github.com/airbytehq/airbyte/pull/46798) | Update dependencies | diff --git a/docs/integrations/sources/lob.md b/docs/integrations/sources/lob.md index d409b1aa4984..4bd68cebb44f 100644 --- a/docs/integrations/sources/lob.md +++ b/docs/integrations/sources/lob.md @@ -34,6 +34,12 @@ Visit `https://docs.lob.com/` for API documentation | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.9 | 2024-12-28 | [50662](https://github.com/airbytehq/airbyte/pull/50662) | Update dependencies | +| 0.0.8 | 2024-12-21 | [50070](https://github.com/airbytehq/airbyte/pull/50070) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49602](https://github.com/airbytehq/airbyte/pull/49602) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49269](https://github.com/airbytehq/airbyte/pull/49269) | Update dependencies | +| 0.0.5 | 2024-12-11 | [48899](https://github.com/airbytehq/airbyte/pull/48899) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-11-04 | [48226](https://github.com/airbytehq/airbyte/pull/48226) | Update dependencies | | 0.0.3 | 2024-10-29 | [47867](https://github.com/airbytehq/airbyte/pull/47867) | Update dependencies | | 0.0.2 | 2024-10-28 | [47627](https://github.com/airbytehq/airbyte/pull/47627) | Update dependencies | | 0.0.1 | 2024-09-22 | [45843](https://github.com/airbytehq/airbyte/pull/45843) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/lokalise.md b/docs/integrations/sources/lokalise.md index 2ff507fdd7da..c7a3a4258624 100644 --- a/docs/integrations/sources/lokalise.md +++ b/docs/integrations/sources/lokalise.md @@ -64,6 +64,11 @@ The Lokalise source connector supports the following [sync modes](https://docs.a | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------- | +| 0.2.6 | 2024-12-28 | [50635](https://github.com/airbytehq/airbyte/pull/50635) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50121](https://github.com/airbytehq/airbyte/pull/50121) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49216](https://github.com/airbytehq/airbyte/pull/49216) | Update dependencies | +| 0.2.3 | 2024-12-11 | [48995](https://github.com/airbytehq/airbyte/pull/48995) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.2 | 2024-11-04 | [47935](https://github.com/airbytehq/airbyte/pull/47935) | Update dependencies | | 0.2.1 | 2024-10-28 | [47629](https://github.com/airbytehq/airbyte/pull/47629) | Update dependencies | | 0.2.0 | 2024-08-26 | [44765](https://github.com/airbytehq/airbyte/pull/44765) | Refactor connector to manifest-only format | | 0.1.15 | 2024-08-24 | [44696](https://github.com/airbytehq/airbyte/pull/44696) | Update dependencies | diff --git a/docs/integrations/sources/looker.md b/docs/integrations/sources/looker.md index eca0729189d2..ad74e25792e9 100644 --- a/docs/integrations/sources/looker.md +++ b/docs/integrations/sources/looker.md @@ -85,6 +85,12 @@ Please read the "API3 Key" section in [Looker's information for users docs](http | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------- | +| 1.0.19 | 2025-01-04 | [50897](https://github.com/airbytehq/airbyte/pull/50897) | Update dependencies | +| 1.0.18 | 2024-12-28 | [50654](https://github.com/airbytehq/airbyte/pull/50654) | Update dependencies | +| 1.0.17 | 2024-12-21 | [50086](https://github.com/airbytehq/airbyte/pull/50086) | Update dependencies | +| 1.0.16 | 2024-12-14 | [49628](https://github.com/airbytehq/airbyte/pull/49628) | Update dependencies | +| 1.0.15 | 2024-12-11 | [48992](https://github.com/airbytehq/airbyte/pull/48992) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 1.0.14 | 2024-11-04 | [47086](https://github.com/airbytehq/airbyte/pull/47086) | Update dependencies | | 1.0.13 | 2024-10-12 | [46805](https://github.com/airbytehq/airbyte/pull/46805) | Update dependencies | | 1.0.12 | 2024-10-05 | [46397](https://github.com/airbytehq/airbyte/pull/46397) | Update dependencies | | 1.0.11 | 2024-09-28 | [46191](https://github.com/airbytehq/airbyte/pull/46191) | Update dependencies | diff --git a/docs/integrations/sources/low-code.md b/docs/integrations/sources/low-code.md index b830b4ef1f39..5199384dc83d 100644 --- a/docs/integrations/sources/low-code.md +++ b/docs/integrations/sources/low-code.md @@ -9,6 +9,17 @@ The changelog below is automatically updated by the `bump_version` command as pa | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------- | +| 6.5.2 | 2024-11-08 | [36501](https://github.com/airbytehq/airbyte/pull/36501) | Bump CDK version to 6.5.2 | +| 6.5.1 | 2024-11-08 | [36501](https://github.com/airbytehq/airbyte/pull/36501) | Bump CDK version to 6.5.1 | +| 6.5.0 | 2024-11-08 | [36501](https://github.com/airbytehq/airbyte/pull/36501) | Bump CDK version to 6.5.0 | +| 6.4.0 | 2024-11-07 | [36501](https://github.com/airbytehq/airbyte/pull/36501) | Bump CDK version to 6.4.0 | +| 6.3.0 | 2024-11-07 | [36501](https://github.com/airbytehq/airbyte/pull/36501) | Bump CDK version to 6.3.0 | +| 6.2.1 | 2024-11-05 | [48373](https://github.com/airbytehq/airbyte/pull/48373) | Add CDK v6 support to remote manifest mode | +| 6.2.0 | 2024-11-05 | [36501](https://github.com/airbytehq/airbyte/pull/36501) | Bump CDK version to 6.2.0 | +| 6.1.2 | 2024-11-05 | [48344](https://github.com/airbytehq/airbyte/pull/48344) | Fix discover failing on new CDK | +| 6.1.1 | 2024-11-04 | [36501](https://github.com/airbytehq/airbyte/pull/36501) | Bump CDK version to 6.1.1 | +| 6.1.0 | 2024-10-31 | [36501](https://github.com/airbytehq/airbyte/pull/36501) | Bump CDK version to 6.1.0 | +| 6.0.0 | 2024-10-30 | [36501](https://github.com/airbytehq/airbyte/pull/36501) | Bump CDK version to 6.0.0 | | 5.17.0 | 2024-10-28 | [36501](https://github.com/airbytehq/airbyte/pull/36501) | Bump CDK version to 5.17.0 | | 5.16.0 | 2024-10-23 | [36501](https://github.com/airbytehq/airbyte/pull/36501) | Bump CDK version to 5.16.0 | | 5.15.0 | 2024-10-23 | [36501](https://github.com/airbytehq/airbyte/pull/36501) | Bump CDK version to 5.15.0 | diff --git a/docs/integrations/sources/luma.md b/docs/integrations/sources/luma.md index aa77dbff06bd..d7a00e89e35c 100644 --- a/docs/integrations/sources/luma.md +++ b/docs/integrations/sources/luma.md @@ -20,6 +20,13 @@ | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.10 | 2024-12-28 | [50594](https://github.com/airbytehq/airbyte/pull/50594) | Update dependencies | +| 0.0.9 | 2024-12-21 | [50124](https://github.com/airbytehq/airbyte/pull/50124) | Update dependencies | +| 0.0.8 | 2024-12-14 | [49636](https://github.com/airbytehq/airbyte/pull/49636) | Update dependencies | +| 0.0.7 | 2024-12-12 | [49258](https://github.com/airbytehq/airbyte/pull/49258) | Update dependencies | +| 0.0.6 | 2024-12-11 | [48980](https://github.com/airbytehq/airbyte/pull/48980) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.5 | 2024-11-05 | [48364](https://github.com/airbytehq/airbyte/pull/48364) | Revert to source-declarative-manifest v5.17.0 | +| 0.0.4 | 2024-11-05 | [48327](https://github.com/airbytehq/airbyte/pull/48327) | Update dependencies | | 0.0.3 | 2024-10-29 | [47746](https://github.com/airbytehq/airbyte/pull/47746) | Update dependencies | | 0.0.2 | 2024-10-28 | [47669](https://github.com/airbytehq/airbyte/pull/47669) | Update dependencies | | 0.0.1 | 2024-08-28 | | Initial release by [@natikgadzhi](https://github.com/natikgadzhi) via Connector Builder | diff --git a/docs/integrations/sources/mailchimp.md b/docs/integrations/sources/mailchimp.md index c8f7eef82fb9..608c383bf88c 100644 --- a/docs/integrations/sources/mailchimp.md +++ b/docs/integrations/sources/mailchimp.md @@ -126,6 +126,11 @@ Now that you have set up the Mailchimp source connector, check out the following | Version | Date | Pull Request | Subject | |---------|------------|----------------------------------------------------------|----------------------------------------------------------------------------| +| 2.0.24 | 2025-01-04 | [50894](https://github.com/airbytehq/airbyte/pull/50894) | Update dependencies | +| 2.0.23 | 2024-12-28 | [50633](https://github.com/airbytehq/airbyte/pull/50633) | Update dependencies | +| 2.0.22 | 2024-12-21 | [50139](https://github.com/airbytehq/airbyte/pull/50139) | Update dependencies | +| 2.0.21 | 2024-12-14 | [49148](https://github.com/airbytehq/airbyte/pull/49148) | Update dependencies | +| 2.0.20 | 2024-11-22 | [45282](https://github.com/airbytehq/airbyte/pull/45282) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 2.0.19 | 2024-08-31 | [45031](https://github.com/airbytehq/airbyte/pull/45031) | Update dependencies | | 2.0.18 | 2024-08-24 | [44708](https://github.com/airbytehq/airbyte/pull/44708) | Update dependencies | | 2.0.17 | 2024-08-17 | [44323](https://github.com/airbytehq/airbyte/pull/44323) | Update dependencies | diff --git a/docs/integrations/sources/mailersend.md b/docs/integrations/sources/mailersend.md index 81a16d844bda..69e84678749a 100644 --- a/docs/integrations/sources/mailersend.md +++ b/docs/integrations/sources/mailersend.md @@ -28,6 +28,12 @@ MailerSend has a default [rate limit](https://developers.mailersend.com/general. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :--------------------------------------- | +| 0.2.8 | 2024-12-28 | [50650](https://github.com/airbytehq/airbyte/pull/50650) | Update dependencies | +| 0.2.7 | 2024-12-21 | [50080](https://github.com/airbytehq/airbyte/pull/50080) | Update dependencies | +| 0.2.6 | 2024-12-14 | [49614](https://github.com/airbytehq/airbyte/pull/49614) | Update dependencies | +| 0.2.5 | 2024-12-12 | [49262](https://github.com/airbytehq/airbyte/pull/49262) | Update dependencies | +| 0.2.4 | 2024-12-11 | [48947](https://github.com/airbytehq/airbyte/pull/48947) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.3 | 2024-11-04 | [48203](https://github.com/airbytehq/airbyte/pull/48203) | Update dependencies | | 0.2.2 | 2024-10-29 | [47785](https://github.com/airbytehq/airbyte/pull/47785) | Update dependencies | | 0.2.1 | 2024-10-28 | [47592](https://github.com/airbytehq/airbyte/pull/47592) | Update dependencies | | 0.2.0 | 2024-08-26 | [44766](https://github.com/airbytehq/airbyte/pull/44766) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/mailgun.md b/docs/integrations/sources/mailgun.md index 46d09d0b6bca..3ca9b87159bd 100644 --- a/docs/integrations/sources/mailgun.md +++ b/docs/integrations/sources/mailgun.md @@ -68,7 +68,11 @@ MailGun's [API reference](https://documentation.mailgun.com/en/latest/api_refere | Version | Date | Pull Request | Subject | | :------ |:-----------| :------------------------------------------------------- |:--------------------------------------------------------------------------------| -| 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | +| 0.3.5 | 2024-12-28 | [50592](https://github.com/airbytehq/airbyte/pull/50592) | Update dependencies | +| 0.3.4 | 2024-12-21 | [50128](https://github.com/airbytehq/airbyte/pull/50128) | Update dependencies | +| 0.3.3 | 2024-12-14 | [49613](https://github.com/airbytehq/airbyte/pull/49613) | Update dependencies | +| 0.3.2 | 2024-12-12 | [47680](https://github.com/airbytehq/airbyte/pull/47680) | Update dependencies | +| 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.3.0 | 2024-08-15 | [44130](https://github.com/airbytehq/airbyte/pull/44130) | Refactor connector to manifest-only format | | 0.2.18 | 2024-08-12 | [43923](https://github.com/airbytehq/airbyte/pull/43923) | Update dependencies | | 0.2.17 | 2024-08-10 | [43501](https://github.com/airbytehq/airbyte/pull/43501) | Update dependencies | diff --git a/docs/integrations/sources/mailjet-sms.md b/docs/integrations/sources/mailjet-sms.md index 3e1db43842e3..1f0451c18a16 100644 --- a/docs/integrations/sources/mailjet-sms.md +++ b/docs/integrations/sources/mailjet-sms.md @@ -32,6 +32,11 @@ Mailjet APIs are under rate limits for the number of API calls allowed per API k | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.2.7 | 2024-12-28 | [50614](https://github.com/airbytehq/airbyte/pull/50614) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50111](https://github.com/airbytehq/airbyte/pull/50111) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49647](https://github.com/airbytehq/airbyte/pull/49647) | Update dependencies | +| 0.2.4 | 2024-12-12 | [49235](https://github.com/airbytehq/airbyte/pull/49235) | Update dependencies | +| 0.2.3 | 2024-12-11 | [47810](https://github.com/airbytehq/airbyte/pull/47810) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.2 | 2024-10-28 | [47489](https://github.com/airbytehq/airbyte/pull/47489) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-15 | [44128](https://github.com/airbytehq/airbyte/pull/44128) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/mailosaur.md b/docs/integrations/sources/mailosaur.md new file mode 100644 index 000000000000..4bc7dc39529c --- /dev/null +++ b/docs/integrations/sources/mailosaur.md @@ -0,0 +1,33 @@ +# Mailosaur +Mailosaur is a communication-testing platform . +With this connector we can easily fetch data from messages , servers and transactions streams! +Docs : https://mailosaur.com/docs + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `username` | `string` | Username. Enter API here | | +| `password` | `string` | Password. Enter your API Key here | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| Messages | id | No pagination | ✅ | ❌ | +| Servers | id | No pagination | ✅ | ❌ | +| Transactions | timestamp | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50639](https://github.com/airbytehq/airbyte/pull/50639) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50098](https://github.com/airbytehq/airbyte/pull/50098) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49607](https://github.com/airbytehq/airbyte/pull/49607) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49260](https://github.com/airbytehq/airbyte/pull/49260) | Update dependencies | +| 0.0.1 | 2024-11-04 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/mailtrap.md b/docs/integrations/sources/mailtrap.md new file mode 100644 index 000000000000..8d545d2d01ce --- /dev/null +++ b/docs/integrations/sources/mailtrap.md @@ -0,0 +1,38 @@ +# Mailtrap + +Email Delivery Platform for individuals and businesses to test, send and control email infrastructure in one place. + +[API Documentation](https://api-docs.mailtrap.io/docs/mailtrap-api-docs/5tjdeg9545058-mailtrap-api) + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_token` | `string` | API Token. API token to use. Find it at https://mailtrap.io/account | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| accounts | id | No pagination | ✅ | ❌ | +| billing_usage | uuid | No pagination | ✅ | ❌ | +| resources | id | No pagination | ✅ | ❌ | +| sending_domains | id | No pagination | ✅ | ❌ | +| inboxes | id | No pagination | ✅ | ❌ | +| messages | id | No pagination | ✅ | ❌ | +| projects | id | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50593](https://github.com/airbytehq/airbyte/pull/50593) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50143](https://github.com/airbytehq/airbyte/pull/50143) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49649](https://github.com/airbytehq/airbyte/pull/49649) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49256](https://github.com/airbytehq/airbyte/pull/49256) | Update dependencies | +| 0.0.2 | 2024-12-11 | [48968](https://github.com/airbytehq/airbyte/pull/48968) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-23 | | Initial release by [@gemsteam](https://github.com/gemsteam) via Connector Builder | + +
diff --git a/docs/integrations/sources/marketo.md b/docs/integrations/sources/marketo.md index d63c0bb3ca41..4ad9a79e7405 100644 --- a/docs/integrations/sources/marketo.md +++ b/docs/integrations/sources/marketo.md @@ -121,6 +121,10 @@ If the 50,000 limit is too stringent, contact Marketo support for a quota increa | Version | Date | Pull Request | Subject | |:---------|:-----------|:---------------------------------------------------------|:-------------------------------------------------------------------------------------------------| +| 1.4.11 | 2025-01-04 | [50890](https://github.com/airbytehq/airbyte/pull/50890) | Update dependencies | +| 1.4.10 | 2024-12-28 | [50655](https://github.com/airbytehq/airbyte/pull/50655) | Update dependencies | +| 1.4.9 | 2024-12-21 | [43736](https://github.com/airbytehq/airbyte/pull/43736) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 1.4.8 | 2024-12-20 | [49972](https://github.com/airbytehq/airbyte/pull/49972) | Pin CDK due to breaking changes in newer versions. | | 1.4.7 | 2024-07-06 | [40629](https://github.com/airbytehq/airbyte/pull/40629) | Update dependencies | | 1.4.6 | 2024-06-26 | [40530](https://github.com/airbytehq/airbyte/pull/40530) | Update dependencies | | 1.4.5 | 2024-06-25 | [40318](https://github.com/airbytehq/airbyte/pull/40318) | Update dependencies | diff --git a/docs/integrations/sources/marketstack.md b/docs/integrations/sources/marketstack.md new file mode 100644 index 000000000000..4530b2bb3ef4 --- /dev/null +++ b/docs/integrations/sources/marketstack.md @@ -0,0 +1,34 @@ +# Marketstack +Marketstack provides data from 72 global stock exchanges. +Using this connector we can extract Historical Data , Splits and Dividends data ! + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | +| `start_date` | `string` | Start Date. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| Exchanges | mic | DefaultPaginator | ✅ | ❌ | +| Tickers | symbol | DefaultPaginator | ✅ | ❌ | +| Historical Data | | DefaultPaginator | ✅ | ✅ | +| Splits | | DefaultPaginator | ✅ | ❌ | +| Dividends | | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50620](https://github.com/airbytehq/airbyte/pull/50620) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50084](https://github.com/airbytehq/airbyte/pull/50084) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49626](https://github.com/airbytehq/airbyte/pull/49626) | Update dependencies | +| 0.0.2 | 2024-12-12 | [48963](https://github.com/airbytehq/airbyte/pull/48963) | Update dependencies | +| 0.0.1 | 2024-11-07 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/mention.md b/docs/integrations/sources/mention.md index 9ab8da6a0607..f029f9d1f3da 100644 --- a/docs/integrations/sources/mention.md +++ b/docs/integrations/sources/mention.md @@ -33,6 +33,11 @@ Docs: https://dev.mention.com/current/ | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.8 | 2024-12-28 | [50607](https://github.com/airbytehq/airbyte/pull/50607) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50107](https://github.com/airbytehq/airbyte/pull/50107) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49601](https://github.com/airbytehq/airbyte/pull/49601) | Update dependencies | +| 0.0.5 | 2024-12-12 | [48998](https://github.com/airbytehq/airbyte/pull/48998) | Update dependencies | +| 0.0.4 | 2024-11-04 | [48258](https://github.com/airbytehq/airbyte/pull/48258) | Update dependencies | | 0.0.3 | 2024-10-29 | [47841](https://github.com/airbytehq/airbyte/pull/47841) | Update dependencies | | 0.0.2 | 2024-10-28 | [47538](https://github.com/airbytehq/airbyte/pull/47538) | Update dependencies | | 0.0.1 | 2024-10-23 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | diff --git a/docs/integrations/sources/merge.md b/docs/integrations/sources/merge.md index 4f3ce018008e..248376f17fa1 100644 --- a/docs/integrations/sources/merge.md +++ b/docs/integrations/sources/merge.md @@ -79,6 +79,11 @@ Merge [API reference](https://api.merge.dev/api/ats/v1/) has v1 at present. The | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------- | :------------- | +| 0.2.6 | 2024-12-28 | [50627](https://github.com/airbytehq/airbyte/pull/50627) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50092](https://github.com/airbytehq/airbyte/pull/50092) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49652](https://github.com/airbytehq/airbyte/pull/49652) | Update dependencies | +| 0.2.3 | 2024-12-12 | [49222](https://github.com/airbytehq/airbyte/pull/49222) | Update dependencies | +| 0.2.2 | 2024-12-11 | [47906](https://github.com/airbytehq/airbyte/pull/47906) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.1 | 2024-10-28 | [47593](https://github.com/airbytehq/airbyte/pull/47593) | Update dependencies | | 0.2.0 | 2024-08-26 | [44768](https://github.com/airbytehq/airbyte/pull/44768) | Refactor connector to manifest-only format | | 0.1.15 | 2024-08-24 | [44665](https://github.com/airbytehq/airbyte/pull/44665) | Update dependencies | diff --git a/docs/integrations/sources/metabase.md b/docs/integrations/sources/metabase.md index 323fcd44f87b..d7efa7ed55f9 100644 --- a/docs/integrations/sources/metabase.md +++ b/docs/integrations/sources/metabase.md @@ -77,6 +77,10 @@ The Metabase source connector supports the following [sync modes](https://docs.a | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- | +| 2.1.7 | 2024-12-28 | [50616](https://github.com/airbytehq/airbyte/pull/50616) | Update dependencies | +| 2.1.6 | 2024-12-21 | [50089](https://github.com/airbytehq/airbyte/pull/50089) | Update dependencies | +| 2.1.5 | 2024-12-14 | [49215](https://github.com/airbytehq/airbyte/pull/49215) | Update dependencies | +| 2.1.4 | 2024-12-11 | [48982](https://github.com/airbytehq/airbyte/pull/48982) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 2.1.3 | 2024-10-29 | [47776](https://github.com/airbytehq/airbyte/pull/47776) | Update dependencies | | 2.1.2 | 2024-10-28 | [47531](https://github.com/airbytehq/airbyte/pull/47531) | Update dependencies | | 2.1.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/microsoft-entra-id.md b/docs/integrations/sources/microsoft-entra-id.md index 9e7241da066f..e14eddf6ed06 100644 --- a/docs/integrations/sources/microsoft-entra-id.md +++ b/docs/integrations/sources/microsoft-entra-id.md @@ -1,44 +1,50 @@ # Microsoft Entra Id + The Microsoft Entra ID Connector for Airbyte allows seamless integration with Microsoft Entra ID, enabling secure and automated data synchronization of identity and access management information. With this connector, users can efficiently retrieve and manage user, group, and directory data to streamline identity workflows and ensure up-to-date access control within their applications. ## Authentication + First of all you need to register an application in the Microsoft Entra Admin Center. Please folow [these](https://learn.microsoft.com/en-us/graph/auth-register-app-v2) steps to do so. After that you need to follow [these](https://learn.microsoft.com/en-us/graph/auth-v2-service?context=graph%2Fapi%2F1.0&view=graph-rest-1.0&tabs=http) steps to configure the api with right permissions and get the access token. ## Configuration -| Input | Type | Description | Default Value | -|-------|------|-------------|---------------| -| `client_id` | `string` | Client ID. | | -| `client_secret` | `string` | Client secret. | | -| `tenant_id` | `string` | Tenant Id. | | -| `application_id_uri` | `string` | Application Id URI. | | -| `user_id` | `string` | ID of the owner. | | - +| Input | Type | Description | Default Value | +| --------------- | -------- | ---------------- | ------------- | +| `client_id` | `string` | Client ID. | | +| `client_secret` | `string` | Client secret. | | +| `tenant_id` | `string` | Tenant Id. | | +| `user_id` | `string` | ID of the owner. | | ## Streams -| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | -|-------------|-------------|------------|---------------------|----------------------| -| users | id | DefaultPaginator | ✅ | ❌ | -| groups | id | DefaultPaginator | ✅ | ❌ | -| applications | id | DefaultPaginator | ✅ | ❌ | -| user_owned_deleted_items | id | DefaultPaginator | ✅ | ❌ | -| directoryroles | id | No pagination | ✅ | ❌ | -| auditlogs | id | DefaultPaginator | ✅ | ❌ | -| directoryroletemplates | id | No pagination | ✅ | ❌ | -| directoryaudits | id | DefaultPaginator | ✅ | ❌ | -| serviceprincipals | id | DefaultPaginator | ✅ | ❌ | -| identityproviders | | DefaultPaginator | ✅ | ❌ | -| adminconsentrequestpolicy | | DefaultPaginator | ✅ | ❌ | + +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +| ------------------------- | ----------- | ---------------- | ------------------ | -------------------- | +| users | id | DefaultPaginator | ✅ | ❌ | +| groups | id | DefaultPaginator | ✅ | ❌ | +| applications | id | DefaultPaginator | ✅ | ❌ | +| user_owned_deleted_items | id | DefaultPaginator | ✅ | ❌ | +| directoryroles | id | No pagination | ✅ | ❌ | +| directoryroletemplates | id | No pagination | ✅ | ❌ | +| directoryaudits | id | DefaultPaginator | ✅ | ❌ | +| serviceprincipals | id | DefaultPaginator | ✅ | ❌ | +| identityproviders | | DefaultPaginator | ✅ | ❌ | +| adminconsentrequestpolicy | | DefaultPaginator | ✅ | ❌ | ## Changelog
Expand to review -| Version | Date | Pull Request | Subject | -|------------------|-------------------|--------------|----------------| +| Version | Date | Pull Request | Subject | +| ------- | ---------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------- | +| 0.0.9 | 2024-12-28 | [50630](https://github.com/airbytehq/airbyte/pull/50630) | Update dependencies | +| 0.0.8 | 2024-12-21 | [50133](https://github.com/airbytehq/airbyte/pull/50133) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49596](https://github.com/airbytehq/airbyte/pull/49596) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49270](https://github.com/airbytehq/airbyte/pull/49270) | Update dependencies | +| 0.0.5 | 2024-12-11 | [48941](https://github.com/airbytehq/airbyte/pull/48941) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-10-31 | [47997](https://github.com/airbytehq/airbyte/pull/47997) | Remove `audit_logs` and update auth remove `application_id_uri` parameter | | 0.0.3 | 2024-10-29 | [47892](https://github.com/airbytehq/airbyte/pull/47892) | Update dependencies | -| 0.0.2 | 2024-10-28 | [47554](https://github.com/airbytehq/airbyte/pull/47554) | Update dependencies | -| 0.0.1 | 2024-10-18 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | +| 0.0.2 | 2024-10-28 | [47479](https://github.com/airbytehq/airbyte/pull/47479) | Update dependencies | +| 0.0.1 | 2024-10-18 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder |
diff --git a/docs/integrations/sources/microsoft-lists.md b/docs/integrations/sources/microsoft-lists.md index 619ab8473725..dab856ae450e 100644 --- a/docs/integrations/sources/microsoft-lists.md +++ b/docs/integrations/sources/microsoft-lists.md @@ -61,6 +61,12 @@ Microsoft Lists connector enables seamless data integration and synchronization | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.9 | 2024-12-28 | [50613](https://github.com/airbytehq/airbyte/pull/50613) | Update dependencies | +| 0.0.8 | 2024-12-21 | [50117](https://github.com/airbytehq/airbyte/pull/50117) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49598](https://github.com/airbytehq/airbyte/pull/49598) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49229](https://github.com/airbytehq/airbyte/pull/49229) | Update dependencies | +| 0.0.5 | 2024-12-11 | [48952](https://github.com/airbytehq/airbyte/pull/48952) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-11-04 | [48202](https://github.com/airbytehq/airbyte/pull/48202) | Update dependencies | | 0.0.3 | 2024-10-29 | [47925](https://github.com/airbytehq/airbyte/pull/47925) | Update dependencies | | 0.0.2 | 2024-10-28 | [47544](https://github.com/airbytehq/airbyte/pull/47544) | Update dependencies | | 0.0.1 | 2024-10-18 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | diff --git a/docs/integrations/sources/microsoft-onedrive.md b/docs/integrations/sources/microsoft-onedrive.md index bd70c1dad2e1..98356517e152 100644 --- a/docs/integrations/sources/microsoft-onedrive.md +++ b/docs/integrations/sources/microsoft-onedrive.md @@ -259,6 +259,12 @@ The connector is restricted by normal Microsoft Graph [requests limitation](http | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:------------------------------------------------------------------------------------------------| +| 0.2.28 | 2025-01-04 | [50888](https://github.com/airbytehq/airbyte/pull/50888) | Update dependencies | +| 0.2.27 | 2024-12-28 | [50601](https://github.com/airbytehq/airbyte/pull/50601) | Update dependencies | +| 0.2.26 | 2024-12-21 | [50102](https://github.com/airbytehq/airbyte/pull/50102) | Update dependencies | +| 0.2.25 | 2024-12-14 | [49143](https://github.com/airbytehq/airbyte/pull/49143) | Update dependencies | +| 0.2.24 | 2024-11-25 | [48639](https://github.com/airbytehq/airbyte/pull/48639) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.23 | 2024-11-04 | [48274](https://github.com/airbytehq/airbyte/pull/48274) | Update dependencies | | 0.2.22 | 2024-10-28 | [47060](https://github.com/airbytehq/airbyte/pull/47060) | Update dependencies | | 0.2.21 | 2024-10-12 | [46177](https://github.com/airbytehq/airbyte/pull/46177) | Update dependencies | | 0.2.20 | 2024-09-21 | [45728](https://github.com/airbytehq/airbyte/pull/45728) | Update dependencies | diff --git a/docs/integrations/sources/miro.md b/docs/integrations/sources/miro.md index cc92af49a105..60b98432e623 100644 --- a/docs/integrations/sources/miro.md +++ b/docs/integrations/sources/miro.md @@ -25,6 +25,11 @@ Airbyte connector for Miro can be used to extract data related to board content, | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50658](https://github.com/airbytehq/airbyte/pull/50658) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50135](https://github.com/airbytehq/airbyte/pull/50135) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49629](https://github.com/airbytehq/airbyte/pull/49629) | Update dependencies | +| 0.0.4 | 2024-12-12 | [48922](https://github.com/airbytehq/airbyte/pull/48922) | Update dependencies | +| 0.0.3 | 2024-11-04 | [48262](https://github.com/airbytehq/airbyte/pull/48262) | Update dependencies | | 0.0.2 | 2024-10-29 | [47885](https://github.com/airbytehq/airbyte/pull/47885) | Update dependencies | | 0.0.1 | 2024-10-18 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | diff --git a/docs/integrations/sources/missive.md b/docs/integrations/sources/missive.md index 0c51124ca9e6..1b62d33eca7d 100644 --- a/docs/integrations/sources/missive.md +++ b/docs/integrations/sources/missive.md @@ -35,6 +35,10 @@ Visit `https://missiveapp.com/help/api-documentation/rest-endpoints` for API doc | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.6 | 2024-12-28 | [50141](https://github.com/airbytehq/airbyte/pull/50141) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49631](https://github.com/airbytehq/airbyte/pull/49631) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49238](https://github.com/airbytehq/airbyte/pull/49238) | Update dependencies | +| 0.0.3 | 2024-12-11 | [47796](https://github.com/airbytehq/airbyte/pull/47796) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.2 | 2024-10-28 | [47599](https://github.com/airbytehq/airbyte/pull/47599) | Update dependencies | | 0.0.1 | 2024-09-22 | [45844](https://github.com/airbytehq/airbyte/pull/45844) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/mixmax.md b/docs/integrations/sources/mixmax.md index 9a30125f30ec..cb1ae78e2024 100644 --- a/docs/integrations/sources/mixmax.md +++ b/docs/integrations/sources/mixmax.md @@ -44,6 +44,12 @@ Visit `https://developer.mixmax.com/reference/getting-started-with-the-api` for | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.9 | 2024-12-28 | [50605](https://github.com/airbytehq/airbyte/pull/50605) | Update dependencies | +| 0.0.8 | 2024-12-21 | [50105](https://github.com/airbytehq/airbyte/pull/50105) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49604](https://github.com/airbytehq/airbyte/pull/49604) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49267](https://github.com/airbytehq/airbyte/pull/49267) | Update dependencies | +| 0.0.5 | 2024-12-11 | [48986](https://github.com/airbytehq/airbyte/pull/48986) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-11-04 | [48160](https://github.com/airbytehq/airbyte/pull/48160) | Update dependencies | | 0.0.3 | 2024-10-29 | [47838](https://github.com/airbytehq/airbyte/pull/47838) | Update dependencies | | 0.0.2 | 2024-10-28 | [47578](https://github.com/airbytehq/airbyte/pull/47578) | Update dependencies | | 0.0.1 | 2024-09-26 | [45921](https://github.com/airbytehq/airbyte/pull/45921) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/mixpanel.md b/docs/integrations/sources/mixpanel.md index f2c2bf43f1a9..044757185918 100644 --- a/docs/integrations/sources/mixpanel.md +++ b/docs/integrations/sources/mixpanel.md @@ -58,6 +58,12 @@ Syncing huge date windows may take longer due to Mixpanel's low API rate-limits | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 3.4.14 | 2025-01-04 | [50891](https://github.com/airbytehq/airbyte/pull/50891) | Update dependencies | +| 3.4.13 | 2024-12-28 | [50596](https://github.com/airbytehq/airbyte/pull/50596) | Update dependencies | +| 3.4.12 | 2024-12-21 | [50095](https://github.com/airbytehq/airbyte/pull/50095) | Update dependencies | +| 3.4.11 | 2024-12-14 | [49249](https://github.com/airbytehq/airbyte/pull/49249) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 3.4.10 | 2024-12-12 | [48948](https://github.com/airbytehq/airbyte/pull/48948) | Update dependencies | +| 3.4.9 | 2024-11-04 | [47098](https://github.com/airbytehq/airbyte/pull/47098) | Update dependencies | | 3.4.8 | 2024-10-12 | [46792](https://github.com/airbytehq/airbyte/pull/46792) | Update dependencies | | 3.4.7 | 2024-10-05 | [46428](https://github.com/airbytehq/airbyte/pull/46428) | Update dependencies | | 3.4.6 | 2024-09-28 | [45747](https://github.com/airbytehq/airbyte/pull/45747) | Update dependencies | diff --git a/docs/integrations/sources/mode.md b/docs/integrations/sources/mode.md index 3209cc7a70b3..df6e84fef161 100644 --- a/docs/integrations/sources/mode.md +++ b/docs/integrations/sources/mode.md @@ -39,6 +39,11 @@ This Airbyte connector for Mode allows you to seamlessly sync data between Mode | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50652](https://github.com/airbytehq/airbyte/pull/50652) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50131](https://github.com/airbytehq/airbyte/pull/50131) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49620](https://github.com/airbytehq/airbyte/pull/49620) | Update dependencies | +| 0.0.3 | 2024-12-12 | [48997](https://github.com/airbytehq/airbyte/pull/48997) | Update dependencies | +| 0.0.2 | 2024-11-04 | [47868](https://github.com/airbytehq/airbyte/pull/47868) | Update dependencies | | 0.0.1 | 2024-10-12 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | diff --git a/docs/integrations/sources/monday.md b/docs/integrations/sources/monday.md index e95b86419cdf..d60ebe4a1972 100644 --- a/docs/integrations/sources/monday.md +++ b/docs/integrations/sources/monday.md @@ -77,6 +77,10 @@ The Monday connector should not run into Monday API limitations under normal usa | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :------------------------------------------------------------------------------------------------ | +| 2.1.8 | 2024-12-28 | [50624](https://github.com/airbytehq/airbyte/pull/50624) | Update dependencies | +| 2.1.7 | 2024-12-21 | [43901](https://github.com/airbytehq/airbyte/pull/43901) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 2.1.6 | 2024-12-19 | [49943](https://github.com/airbytehq/airbyte/pull/49943) | Pin CDK constraint to avoid breaking change in newer versions | +| 2.1.5 | 2024-10-31 | [48054](https://github.com/airbytehq/airbyte/pull/48054) | Moved to `DeclarativeOAuthFlow` specification | | 2.1.4 | 2024-08-17 | [44201](https://github.com/airbytehq/airbyte/pull/44201) | Add boards name to the `items` stream | | 2.1.3 | 2024-06-04 | [38958](https://github.com/airbytehq/airbyte/pull/38958) | [autopull] Upgrade base image to v1.2.1 | | 2.1.2 | 2024-04-30 | [37722](https://github.com/airbytehq/airbyte/pull/37722) | Fetch `display_value` field for column values of `Mirror`, `Dependency` and `Connect Board` types | @@ -106,4 +110,4 @@ The Monday connector should not run into Monday API limitations under normal usa | 0.1.1 | 2021-11-18 | [8016](https://github.com/airbytehq/airbyte/pull/8016) | 🐛 Source Monday: fix pagination and schema bug | | 0.1.0 | 2021-11-07 | [7168](https://github.com/airbytehq/airbyte/pull/7168) | 🎉 New Source: Monday | - \ No newline at end of file + diff --git a/docs/integrations/sources/mongodb-v2.md b/docs/integrations/sources/mongodb-v2.md index ee61a645e259..f02869fe8ac7 100644 --- a/docs/integrations/sources/mongodb-v2.md +++ b/docs/integrations/sources/mongodb-v2.md @@ -199,44 +199,46 @@ For more information regarding configuration parameters, please see [MongoDb Doc | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:----------------------------------------------------------------------------------------------------------| -| 1.5.11 | 2024-09-24 | [45883](https://github.com/airbytehq/airbyte/pull/45883) | Lazy init mongocursor to prevent timeout. | -| 1.5.10 | 2024-09-17 | [45639](https://github.com/airbytehq/airbyte/pull/45639) | Adopt latest CDK to use the latest apache sshd mina to handle tcpkeepalive requests. | -| 1.5.9 | 2024-08-28 | [42927](https://github.com/airbytehq/airbyte/pull/42927) | Support binary subtype. | -| 1.5.8 | 2024-08-27 | [44841](https://github.com/airbytehq/airbyte/pull/44841) | Adopt latest CDK. | -| 1.5.7 | 2024-08-27 | [44846](https://github.com/airbytehq/airbyte/pull/44846) | DBZ filters in related streams only. | -| 1.5.6 | 2024-08-27 | [44839](https://github.com/airbytehq/airbyte/pull/44839) | DBZ filters in related streams only. | -| 1.5.5 | 2024-08-26 | [44779](https://github.com/airbytehq/airbyte/pull/44779) | Revert permission check on oplog.rs. | -| 1.5.4 | 2024-08-20 | [44490](https://github.com/airbytehq/airbyte/pull/44490) | Add read permission check on oplog.rs collection used by CDC. | -| 1.5.3 | 2024-08-08 | [43410](https://github.com/airbytehq/airbyte/pull/43410) | Adopt latest CDK. | -| 1.5.2 | 2024-08-06 | [42869](https://github.com/airbytehq/airbyte/pull/42869) | Adopt latest CDK. | -| 1.5.1 | 2024-08-01 | [42549](https://github.com/airbytehq/airbyte/pull/42549) | Centered the connector icon. | -| 1.5.0 | 2024-07-26 | [42561](https://github.com/airbytehq/airbyte/pull/42561) | Implement WASS algorithm. | -| 1.4.3 | 2024-07-22 | [39145](https://github.com/airbytehq/airbyte/pull/39145) | Warn (vs fail) on different \_id types in collection. | -| 1.4.2 | 2024-07-01 | [40516](https://github.com/airbytehq/airbyte/pull/40516) | Remove dbz hearbeat. | -| 1.4.1 | 2024-06-11 | [39530](https://github.com/airbytehq/airbyte/pull/39530) | Adopt new CDK. | -| 1.4.0 | 2024-06-11 | [38238](https://github.com/airbytehq/airbyte/pull/38238) | Update mongodbv2 to use dbz 2.6.2 | -| 1.3.15 | 2024-05-30 | [38781](https://github.com/airbytehq/airbyte/pull/38781) | Sync sending trace status messages indicating progress. | -| 1.3.14 | 2024-05-29 | [38584](https://github.com/airbytehq/airbyte/pull/38584) | Set is_resumable flag in discover. | -| 1.3.13 | 2024-05-09 | [36851](https://github.com/airbytehq/airbyte/pull/36851) | Support reading collection with a binary \_id type. | -| 1.3.12 | 2024-05-07 | [36851](https://github.com/airbytehq/airbyte/pull/36851) | Upgrade debezium to version 2.5.1. | -| 1.3.11 | 2024-05-02 | [37753](https://github.com/airbytehq/airbyte/pull/37753) | Chunk size(limit) should correspond to ~1GB of data. | -| 1.3.10 | 2024-05-02 | [37781](https://github.com/airbytehq/airbyte/pull/37781) | Adopt latest CDK. | -| 1.3.9 | 2024-05-01 | [37742](https://github.com/airbytehq/airbyte/pull/37742) | Adopt latest CDK. Remove Debezium retries. | -| 1.3.8 | 2024-04-24 | [37559](https://github.com/airbytehq/airbyte/pull/37559) | Implement fixed-size chunking while performing initial load. | -| 1.3.7 | 2024-04-24 | [37557](https://github.com/airbytehq/airbyte/pull/37557) | Change bug in resume token validity check. | -| 1.3.6 | 2024-04-24 | [37525](https://github.com/airbytehq/airbyte/pull/37525) | Internal refactor. | -| 1.3.5 | 2024-04-22 | [37348](https://github.com/airbytehq/airbyte/pull/37348) | Do not send estimate trace if we do not have data. | -| 1.3.4 | 2024-04-16 | [37348](https://github.com/airbytehq/airbyte/pull/37348) | Populate null values in airbyte record messages. | -| 1.3.3 | 2024-04-05 | [36872](https://github.com/airbytehq/airbyte/pull/36872) | Update to connector's metadat definition. | -| 1.3.2 | 2024-04-04 | [36845](https://github.com/airbytehq/airbyte/pull/36845) | Adopt Kotlin CDK. | -| 1.3.1 | 2024-04-04 | [36837](https://github.com/airbytehq/airbyte/pull/36837) | Adopt CDK 0.28.0. | -| 1.3.0 | 2024-03-15 | [35669](https://github.com/airbytehq/airbyte/pull/35669) | Full refresh read of collections. | -| 1.2.16 | 2024-03-06 | [35669](https://github.com/airbytehq/airbyte/pull/35669) | State message will now include record count. | -| 1.2.15 | 2024-02-27 | [35673](https://github.com/airbytehq/airbyte/pull/35673) | Consume user provided connection string. | -| 1.2.14 | 2024-02-27 | [35675](https://github.com/airbytehq/airbyte/pull/35675) | Fix invalid cdc error message. | -| 1.2.13 | 2024-02-22 | [35569](https://github.com/airbytehq/airbyte/pull/35569) | Fix logging bug. | -| 1.2.12 | 2024-02-21 | [35526](https://github.com/airbytehq/airbyte/pull/35526) | Improve error handling. | -| 1.2.11 | 2024-02-20 | [35375](https://github.com/airbytehq/airbyte/pull/35375) | Add config to throw an error on invalid CDC position and enable it by default. | +| 1.5.13 | 2024-12-18 | [49868](https://github.com/airbytehq/airbyte/pull/49868) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 1.5.12 | 2024-11-01 | [48115](https://github.com/airbytehq/airbyte/pull/48115) | Remove database name check. | +| 1.5.11 | 2024-09-24 | [45883](https://github.com/airbytehq/airbyte/pull/45883) | Lazy init mongocursor to prevent timeout. | +| 1.5.10 | 2024-09-17 | [45639](https://github.com/airbytehq/airbyte/pull/45639) | Adopt latest CDK to use the latest apache sshd mina to handle tcpkeepalive requests. | +| 1.5.9 | 2024-08-28 | [42927](https://github.com/airbytehq/airbyte/pull/42927) | Support binary subtype. | +| 1.5.8 | 2024-08-27 | [44841](https://github.com/airbytehq/airbyte/pull/44841) | Adopt latest CDK. | +| 1.5.7 | 2024-08-27 | [44846](https://github.com/airbytehq/airbyte/pull/44846) | DBZ filters in related streams only. | +| 1.5.6 | 2024-08-27 | [44839](https://github.com/airbytehq/airbyte/pull/44839) | DBZ filters in related streams only. | +| 1.5.5 | 2024-08-26 | [44779](https://github.com/airbytehq/airbyte/pull/44779) | Revert permission check on oplog.rs. | +| 1.5.4 | 2024-08-20 | [44490](https://github.com/airbytehq/airbyte/pull/44490) | Add read permission check on oplog.rs collection used by CDC. | +| 1.5.3 | 2024-08-08 | [43410](https://github.com/airbytehq/airbyte/pull/43410) | Adopt latest CDK. | +| 1.5.2 | 2024-08-06 | [42869](https://github.com/airbytehq/airbyte/pull/42869) | Adopt latest CDK. | +| 1.5.1 | 2024-08-01 | [42549](https://github.com/airbytehq/airbyte/pull/42549) | Centered the connector icon. | +| 1.5.0 | 2024-07-26 | [42561](https://github.com/airbytehq/airbyte/pull/42561) | Implement WASS algorithm. | +| 1.4.3 | 2024-07-22 | [39145](https://github.com/airbytehq/airbyte/pull/39145) | Warn (vs fail) on different \_id types in collection. | +| 1.4.2 | 2024-07-01 | [40516](https://github.com/airbytehq/airbyte/pull/40516) | Remove dbz hearbeat. | +| 1.4.1 | 2024-06-11 | [39530](https://github.com/airbytehq/airbyte/pull/39530) | Adopt new CDK. | +| 1.4.0 | 2024-06-11 | [38238](https://github.com/airbytehq/airbyte/pull/38238) | Update mongodbv2 to use dbz 2.6.2 | +| 1.3.15 | 2024-05-30 | [38781](https://github.com/airbytehq/airbyte/pull/38781) | Sync sending trace status messages indicating progress. | +| 1.3.14 | 2024-05-29 | [38584](https://github.com/airbytehq/airbyte/pull/38584) | Set is_resumable flag in discover. | +| 1.3.13 | 2024-05-09 | [36851](https://github.com/airbytehq/airbyte/pull/36851) | Support reading collection with a binary \_id type. | +| 1.3.12 | 2024-05-07 | [36851](https://github.com/airbytehq/airbyte/pull/36851) | Upgrade debezium to version 2.5.1. | +| 1.3.11 | 2024-05-02 | [37753](https://github.com/airbytehq/airbyte/pull/37753) | Chunk size(limit) should correspond to ~1GB of data. | +| 1.3.10 | 2024-05-02 | [37781](https://github.com/airbytehq/airbyte/pull/37781) | Adopt latest CDK. | +| 1.3.9 | 2024-05-01 | [37742](https://github.com/airbytehq/airbyte/pull/37742) | Adopt latest CDK. Remove Debezium retries. | +| 1.3.8 | 2024-04-24 | [37559](https://github.com/airbytehq/airbyte/pull/37559) | Implement fixed-size chunking while performing initial load. | +| 1.3.7 | 2024-04-24 | [37557](https://github.com/airbytehq/airbyte/pull/37557) | Change bug in resume token validity check. | +| 1.3.6 | 2024-04-24 | [37525](https://github.com/airbytehq/airbyte/pull/37525) | Internal refactor. | +| 1.3.5 | 2024-04-22 | [37348](https://github.com/airbytehq/airbyte/pull/37348) | Do not send estimate trace if we do not have data. | +| 1.3.4 | 2024-04-16 | [37348](https://github.com/airbytehq/airbyte/pull/37348) | Populate null values in airbyte record messages. | +| 1.3.3 | 2024-04-05 | [36872](https://github.com/airbytehq/airbyte/pull/36872) | Update to connector's metadat definition. | +| 1.3.2 | 2024-04-04 | [36845](https://github.com/airbytehq/airbyte/pull/36845) | Adopt Kotlin CDK. | +| 1.3.1 | 2024-04-04 | [36837](https://github.com/airbytehq/airbyte/pull/36837) | Adopt CDK 0.28.0. | +| 1.3.0 | 2024-03-15 | [35669](https://github.com/airbytehq/airbyte/pull/35669) | Full refresh read of collections. | +| 1.2.16 | 2024-03-06 | [35669](https://github.com/airbytehq/airbyte/pull/35669) | State message will now include record count. | +| 1.2.15 | 2024-02-27 | [35673](https://github.com/airbytehq/airbyte/pull/35673) | Consume user provided connection string. | +| 1.2.14 | 2024-02-27 | [35675](https://github.com/airbytehq/airbyte/pull/35675) | Fix invalid cdc error message. | +| 1.2.13 | 2024-02-22 | [35569](https://github.com/airbytehq/airbyte/pull/35569) | Fix logging bug. | +| 1.2.12 | 2024-02-21 | [35526](https://github.com/airbytehq/airbyte/pull/35526) | Improve error handling. | +| 1.2.11 | 2024-02-20 | [35375](https://github.com/airbytehq/airbyte/pull/35375) | Add config to throw an error on invalid CDC position and enable it by default. | | 1.2.10 | 2024-02-13 | [35036](https://github.com/airbytehq/airbyte/pull/34751) | Emit analytics message for invalid CDC cursor. | | 1.2.9 | 2024-02-13 | [35114](https://github.com/airbytehq/airbyte/pull/35114) | Extend subsequent cdc record wait time to the duration of initial. Bug Fixes | | 1.2.8 | 2024-02-08 | [34748](https://github.com/airbytehq/airbyte/pull/34748) | Adopt CDK 0.19.0 | diff --git a/docs/integrations/sources/mssql.md b/docs/integrations/sources/mssql.md index cba8d22b3340..a76183fd3920 100644 --- a/docs/integrations/sources/mssql.md +++ b/docs/integrations/sources/mssql.md @@ -35,7 +35,7 @@ for more details. #### Requirements 1. MSSQL Server `Azure SQL Database`, `Azure Synapse Analytics`, `Azure SQL Managed Instance`, - `SQL Server 2019`, `SQL Server 2017`, `SQL Server 2016`, `SQL Server 2014`, `SQL Server 2012`, + `SQL Server 2022`, `SQL Server 2019`, `SQL Server 2017`, `SQL Server 2016`, `SQL Server 2014`, `SQL Server 2012`, `PDW 2008R2 AU34`. 2. Create a dedicated read-only Airbyte user with access to all tables needed for replication 3. If you want to use CDC, please see [the relevant section below](mssql.md#change-data-capture-cdc) @@ -101,7 +101,9 @@ approaches CDC. - The SQL Server CDC feature processes changes that occur in user-created tables only. You cannot enable CDC on the SQL Server master database. - Using variables with partition switching on databases or tables with change data capture \(CDC\) - is not supported for the `ALTER TABLE` ... `SWITCH TO` ... `PARTITION` ... statement + is not supported for the `ALTER TABLE` ... `SWITCH TO` ... `PARTITION` ... statement. +- CDC incremental syncing is only available for tables with at least one primary key. Tables without primary keys can still be replicated by CDC but only in Full Refresh mode. + For more information on CDC limitations, refer to our [CDC Limitations doc](https://docs.airbyte.com/understanding-airbyte/cdc#limitations). - Our CDC implementation uses at least once delivery for all change records. - Read more on CDC limitations in the [Microsoft docs](https://docs.microsoft.com/en-us/sql/relational-databases/track-changes/about-change-data-capture-sql-server?view=sql-server-2017#limitations). @@ -421,20 +423,23 @@ WHERE actor_definition_id ='b5ea17b1-f170-46dc-bc31-cc744ca984c1' AND (configura Expand to review | Version | Date | Pull Request | Subject | -|:--------|:-----------|:------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------| -| 4.1.15 | 2024-10-05 | [46515](https://github.com/airbytehq/airbyte/pull/46515) | Improving discovery of large SQL server database. | -| 4.1.14 | 2024-09-17 | [45639](https://github.com/airbytehq/airbyte/pull/45639) | Adopt latest CDK to use the latest apache sshd mina to handle tcpkeepalive requests. | -| 4.1.13 | 2024-09-05 | [45181](https://github.com/airbytehq/airbyte/pull/45181) | Fix incorrect categorizing resumable/nonresumable full refresh streams. | -| 4.1.12 | 2024-09-10 | [45368](https://github.com/airbytehq/airbyte/pull/45368) | Remove excessive debezium logging. | -| 4.1.11 | 2024-09-04 | [45142](https://github.com/airbytehq/airbyte/pull/45142) | Fix incorrect datetimeoffset format in cursor state. | -| 4.1.10 | 2024-08-27 | [44759](https://github.com/airbytehq/airbyte/pull/44759) | Improve null safety in parsing debezium change events. | -| 4.1.9 | 2024-08-27 | [44841](https://github.com/airbytehq/airbyte/pull/44841) | Adopt latest CDK. | -| 4.1.8 | 2024-08-08 | [43410](https://github.com/airbytehq/airbyte/pull/43410) | Adopt latest CDK. | -| 4.1.7 | 2024-08-06 | [42869](https://github.com/airbytehq/airbyte/pull/42869) | Adopt latest CDK. | -| 4.1.6 | 2024-07-30 | [42550](https://github.com/airbytehq/airbyte/pull/42550) | Correctly report stream states. | -| 4.1.5 | 2024-07-29 | [42852](https://github.com/airbytehq/airbyte/pull/42852) | Bump CDK version to latest to use new bug fixes on error translation. | -| 4.1.4 | 2024-07-23 | [42421](https://github.com/airbytehq/airbyte/pull/42421) | Remove final transient error emitter iterators. | -| 4.1.3 | | 2024-07-22 | [42411](https://github.com/airbytehq/airbyte/pull/42411) | Hide the "initial load timeout in hours" field by default in UI | +| :------ | :--------- | :---------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | +| 4.1.18 | 2025-01-06 | [50943](https://github.com/airbytehq/airbyte/pull/50943) | Use airbyte/java-connector-base:2.0.0. This makes the image rootless. The connector will be incompatible with Airbyte < 0.64. | +| 4.1.17 | 2024-12-17 | [49840](https://github.com/airbytehq/airbyte/pull/49840) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 4.1.16 | 2024-11-13 | [48484](https://github.com/airbytehq/airbyte/pull/48484) | Enhanced error handling for MSSQL to improve system error detection and response. | +| 4.1.15 | 2024-10-05 | [46515](https://github.com/airbytehq/airbyte/pull/46515) | Improving discovery of large SQL server database. | +| 4.1.14 | 2024-09-17 | [45639](https://github.com/airbytehq/airbyte/pull/45639) | Adopt latest CDK to use the latest apache sshd mina to handle tcpkeepalive requests. | +| 4.1.13 | 2024-09-05 | [45181](https://github.com/airbytehq/airbyte/pull/45181) | Fix incorrect categorizing resumable/nonresumable full refresh streams. | +| 4.1.12 | 2024-09-10 | [45368](https://github.com/airbytehq/airbyte/pull/45368) | Remove excessive debezium logging. | +| 4.1.11 | 2024-09-04 | [45142](https://github.com/airbytehq/airbyte/pull/45142) | Fix incorrect datetimeoffset format in cursor state. | +| 4.1.10 | 2024-08-27 | [44759](https://github.com/airbytehq/airbyte/pull/44759) | Improve null safety in parsing debezium change events. | +| 4.1.9 | 2024-08-27 | [44841](https://github.com/airbytehq/airbyte/pull/44841) | Adopt latest CDK. | +| 4.1.8 | 2024-08-08 | [43410](https://github.com/airbytehq/airbyte/pull/43410) | Adopt latest CDK. | +| 4.1.7 | 2024-08-06 | [42869](https://github.com/airbytehq/airbyte/pull/42869) | Adopt latest CDK. | +| 4.1.6 | 2024-07-30 | [42550](https://github.com/airbytehq/airbyte/pull/42550) | Correctly report stream states. | +| 4.1.5 | 2024-07-29 | [42852](https://github.com/airbytehq/airbyte/pull/42852) | Bump CDK version to latest to use new bug fixes on error translation. | +| 4.1.4 | 2024-07-23 | [42421](https://github.com/airbytehq/airbyte/pull/42421) | Remove final transient error emitter iterators. | +| 4.1.3 | | 2024-07-22 | [42411](https://github.com/airbytehq/airbyte/pull/42411) | Hide the "initial load timeout in hours" field by default in UI | 4.1.2 | 2024-07-22 | [42024](https://github.com/airbytehq/airbyte/pull/42024) | Fix a NPE bug on resuming from a failed attempt. | | 4.1.1 | 2024-07-19 | [42122](https://github.com/airbytehq/airbyte/pull/42122) | Improve wass error message + logging. | | 4.1.0 | 2024-07-17 | [42078](https://github.com/airbytehq/airbyte/pull/42078) | WASS analytics + bug fixes. | diff --git a/docs/integrations/sources/mux.md b/docs/integrations/sources/mux.md index c334ee2bec40..1e47b83de72c 100644 --- a/docs/integrations/sources/mux.md +++ b/docs/integrations/sources/mux.md @@ -34,6 +34,12 @@ Visit `https://docs.mux.com/api-reference` for API documentation | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.9 | 2024-12-28 | [50651](https://github.com/airbytehq/airbyte/pull/50651) | Update dependencies | +| 0.0.8 | 2024-12-21 | [50127](https://github.com/airbytehq/airbyte/pull/50127) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49632](https://github.com/airbytehq/airbyte/pull/49632) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49241](https://github.com/airbytehq/airbyte/pull/49241) | Update dependencies | +| 0.0.5 | 2024-12-11 | [48912](https://github.com/airbytehq/airbyte/pull/48912) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-11-04 | [48231](https://github.com/airbytehq/airbyte/pull/48231) | Update dependencies | | 0.0.3 | 2024-10-29 | [47880](https://github.com/airbytehq/airbyte/pull/47880) | Update dependencies | | 0.0.2 | 2024-10-28 | [47492](https://github.com/airbytehq/airbyte/pull/47492) | Update dependencies | | 0.0.1 | 2024-09-27 | [45921](https://github.com/airbytehq/airbyte/pull/45921) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/my-hours.md b/docs/integrations/sources/my-hours.md index d6b89f1f81f5..b327799ad79d 100644 --- a/docs/integrations/sources/my-hours.md +++ b/docs/integrations/sources/my-hours.md @@ -36,6 +36,11 @@ Depending on the amount of team members and time logs the source provides a prop | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :--------------------------------- | +| 0.3.7 | 2024-12-28 | [50599](https://github.com/airbytehq/airbyte/pull/50599) | Update dependencies | +| 0.3.6 | 2024-12-21 | [50120](https://github.com/airbytehq/airbyte/pull/50120) | Update dependencies | +| 0.3.5 | 2024-12-14 | [49611](https://github.com/airbytehq/airbyte/pull/49611) | Update dependencies | +| 0.3.4 | 2024-12-12 | [49253](https://github.com/airbytehq/airbyte/pull/49253) | Update dependencies | +| 0.3.3 | 2024-12-11 | [48285](https://github.com/airbytehq/airbyte/pull/48285) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.3.2 | 2024-10-29 | [47787](https://github.com/airbytehq/airbyte/pull/47787) | Update dependencies | | 0.3.1 | 2024-10-28 | [47095](https://github.com/airbytehq/airbyte/pull/47095) | Update dependencies | | 0.3.0 | 2024-10-19 | [47012](https://github.com/airbytehq/airbyte/pull/47012) | Migrate to manifest only format | diff --git a/docs/integrations/sources/mysql.md b/docs/integrations/sources/mysql.md index 6f7af411774a..3d54c8301e30 100644 --- a/docs/integrations/sources/mysql.md +++ b/docs/integrations/sources/mysql.md @@ -224,200 +224,215 @@ Any database or table encoding combination of charset and collation is supported
Expand to review -| Version | Date | Pull Request | Subject | -|:--------|:-----------|:-----------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------| -| 3.7.3 | 2024-09-17 | [45639](https://github.com/airbytehq/airbyte/pull/45639) | Adopt latest CDK to use the latest apache sshd mina to handle tcpkeepalive requests. | -| 3.7.2 | 2024-09-05 | [45181](https://github.com/airbytehq/airbyte/pull/45181) | Fix incorrect categorizing resumable/nonresumable full refresh streams. | -| 3.7.1 | 2024-08-27 | [44841](https://github.com/airbytehq/airbyte/pull/44841) | Adopt latest CDK. | -| 3.7.0 | 2024-08-13 | [44013](https://github.com/airbytehq/airbyte/pull/44013) | Upgrading to Debezium 2.7.1.Final | -| 3.6.9 | 2024-08-08 | [43410](https://github.com/airbytehq/airbyte/pull/43410) | Adopt latest CDK. | -| 3.6.8 | 2024-07-30 | [42869](https://github.com/airbytehq/airbyte/pull/42869) | Adopt latest CDK. | -| 3.6.7 | 2024-07-30 | [42550](https://github.com/airbytehq/airbyte/pull/42550) | Correctly report stream states. | -| 3.6.6 | 2024-07-29 | [42852](https://github.com/airbytehq/airbyte/pull/42852) | Bump CDK version to latest to use new bug fixes on error translation. | -| 3.6.5 | 2024-07-24 | [42417](https://github.com/airbytehq/airbyte/pull/42417) | Handle null error message in ConnectorExceptionHandler. | -| 3.6.4 | 2024-07-23 | [42421](https://github.com/airbytehq/airbyte/pull/42421) | Remove final transient error emitter iterators. | -| 3.6.3 | 2024-07-22 | [42024](https://github.com/airbytehq/airbyte/pull/42024) | Fix a NPE bug on resuming from a failed attempt. | -| 3.6.2 | 2024-07-17 | [42087](https://github.com/airbytehq/airbyte/pull/42087) | Adding more error translations for MySql source. | -| 3.6.1 | 2024-07-19 | [42122](https://github.com/airbytehq/airbyte/pull/42122) | Improve wass error message + logging. | -| 3.6.0 | 2024-07-17 | [40208](https://github.com/airbytehq/airbyte/pull/40208) | Start using the new error MySql source error handler that comes with a new error translation layer. | -| 3.5.1 | 2024-07-17 | [42043](https://github.com/airbytehq/airbyte/pull/42043) | Adopt latest CDK + fixes. | -| 3.5.0 | 2024-07-11 | [38240](https://github.com/airbytehq/airbyte/pull/38240) | Implement WASS. | -| 3.4.12 | 2024-07-01 | [40516](https://github.com/airbytehq/airbyte/pull/40516) | Remove dbz heartbeat. | -| 3.4.11 | 2024-06-26 | [40561](https://github.com/airbytehq/airbyte/pull/40561) | Support PlanetScale MySQL's per-query row limit. | -| 3.4.10 | 2024-06-14 | [39349](https://github.com/airbytehq/airbyte/pull/39349) | Full refresh stream sending internal count metadata. | -| 3.4.9 | 2024-06-11 | [39405](https://github.com/airbytehq/airbyte/pull/39405) | Adopt latest CDK. | -| 3.4.8 | 2024-06-05 | [39144](https://github.com/airbytehq/airbyte/pull/39144) | Upgrade Debezium to 2.5.4 | -| 3.4.7 | 2024-05-29 | [38584](https://github.com/airbytehq/airbyte/pull/38584) | Set is_resumable flag in discover. | -| 3.4.6 | 2024-05-29 | [38538](https://github.com/airbytehq/airbyte/pull/38538) | Exit connector when encountering a config error. | -| 3.4.5 | 2024-05-23 | [38198](https://github.com/airbytehq/airbyte/pull/38198) | Sync sending trace status messages indicating progress. | -| 3.4.4 | 2024-05-15 | [38208](https://github.com/airbytehq/airbyte/pull/38208) | disable counts in full refresh stream in state message. | -| 3.4.3 | 2024-05-13 | [38104](https://github.com/airbytehq/airbyte/pull/38104) | Handle transient error messages. | -| 3.4.2 | 2024-05-07 | [38046](https://github.com/airbytehq/airbyte/pull/38046) | Resumeable refresh should run only if there is source defined pk. | -| 3.4.1 | 2024-05-03 | [37824](https://github.com/airbytehq/airbyte/pull/37824) | Fixed a bug on Resumeable full refresh where cursor based source throw NPE. | -| 3.4.0 | 2024-05-02 | [36932](https://github.com/airbytehq/airbyte/pull/36932) | Resumeable full refresh. Note please upgrade your platform - minimum platform version is 0.58.0. | -| 3.3.25 | 2024-05-02 | [37781](https://github.com/airbytehq/airbyte/pull/37781) | Adopt latest CDK. | -| 3.3.24 | 2024-05-01 | [37742](https://github.com/airbytehq/airbyte/pull/37742) | Adopt latest CDK. Remove Debezium retries. | -| 3.3.23 | 2024-04-23 | [37507](https://github.com/airbytehq/airbyte/pull/37507) | Better errors when user switches from CDC to non-CDC mode. | -| 3.3.22 | 2024-04-22 | [37541](https://github.com/airbytehq/airbyte/pull/37541) | Adopt latest CDK. reduce excessive logs. | -| 3.3.21 | 2024-04-22 | [37476](https://github.com/airbytehq/airbyte/pull/37476) | Adopt latest CDK. | -| 3.3.20 | 2024-04-16 | [37111](https://github.com/airbytehq/airbyte/pull/37111) | Populate null values in record message. | -| 3.3.19 | 2024-04-15 | [37328](https://github.com/airbytehq/airbyte/pull/37328) | Populate airbyte_meta.changes | -| 3.3.18 | 2024-04-15 | [37324](https://github.com/airbytehq/airbyte/pull/37324) | Refactor source operations. | -| 3.3.17 | 2024-04-10 | [36919](https://github.com/airbytehq/airbyte/pull/36919) | Fix a bug in conversion of null values. | -| 3.3.16 | 2024-04-05 | [36872](https://github.com/airbytehq/airbyte/pull/36872) | Update to connector's metadat definition. | -| 3.3.15 | 2024-04-05 | [36577](https://github.com/airbytehq/airbyte/pull/36577) | Config error will not send out system trace message | -| 3.3.14 | 2024-04-04 | [36742](https://github.com/airbytehq/airbyte/pull/36742) | To use new kotlin CDK | -| 3.3.13 | 2024-02-29 | [35529](https://github.com/airbytehq/airbyte/pull/35529) | Refactor state iterator messages. | -| 3.3.12 | 2024-02-27 | [35675](https://github.com/airbytehq/airbyte/pull/35675) | Fix invalid cdc error message. | -| 3.3.11 | 2024-02-23 | [35527](https://github.com/airbytehq/airbyte/pull/35527) | Adopt 0.23.1 and shutdown timeouts. | -| 3.3.10 | 2024-02-22 | [35569](https://github.com/airbytehq/airbyte/pull/35569) | Fix logging bug. | -| 3.3.9 | 2024-02-21 | [35525](https://github.com/airbytehq/airbyte/pull/35338) | Adopt 0.21.4 and reduce cdc state compression threshold to 1MB. | -| 3.3.8 | 2024-02-20 | [35338](https://github.com/airbytehq/airbyte/pull/35338) | Add config to throw an error on invalid CDC position. | -| 3.3.7 | 2024-02-13 | [35036](https://github.com/airbytehq/airbyte/pull/34751) | Emit analytics message for invalid CDC cursor. | -| 3.3.6 | 2024-02-13 | [34869](https://github.com/airbytehq/airbyte/pull/34573) | Don't emit state in SourceStateIterator when there is an underlying stream failure. | -| 3.3.5 | 2024-02-12 | [34580](https://github.com/airbytehq/airbyte/pull/34580) | Support special chars in db name | -| 3.3.4 | 2024-02-08 | [34750](https://github.com/airbytehq/airbyte/pull/34750) | Adopt CDK 0.19.0 | -| 3.3.3 | 2024-01-26 | [34573](https://github.com/airbytehq/airbyte/pull/34573) | Adopt CDK v0.16.0. | -| 3.3.2 | 2024-01-08 | [33005](https://github.com/airbytehq/airbyte/pull/33005) | Adding count stats for incremental sync in AirbyteStateMessage | -| 3.3.1 | 2024-01-03 | [33312](https://github.com/airbytehq/airbyte/pull/33312) | Adding count stats in AirbyteStateMessage | -| 3.3.0 | 2023-12-19 | [33436](https://github.com/airbytehq/airbyte/pull/33436) | Remove LEGACY state flag | -| 3.2.4 | 2023-12-12 | [33356](https://github.com/airbytehq/airbyte/pull/33210) | Support for better debugging tools.. | -| 3.2.3 | 2023-12-08 | [33210](https://github.com/airbytehq/airbyte/pull/33210) | Update MySql driver property value for zero date handling. | -| 3.2.2 | 2023-12-06 | [33082](https://github.com/airbytehq/airbyte/pull/33082) | Improvements to MySQL schema snapshot error handling. | -| 3.2.1 | 2023-11-28 | [32610](https://github.com/airbytehq/airbyte/pull/32610) | Support initial syncs using binary as primary key. | -| 3.2.0 | 2023-11-29 | [31062](https://github.com/airbytehq/airbyte/pull/31062) | enforce SSL on Airbyte Cloud | -| 3.1.9 | 2023-11-27 | [32662](https://github.com/airbytehq/airbyte/pull/32662) | Apply initial setup time to debezium engine warmup time. | -| 3.1.8 | 2023-11-22 | [32656](https://github.com/airbytehq/airbyte/pull/32656) | Adopt java CDK version 0.5.0. | -| 3.1.7 | 2023-11-08 | [32125](https://github.com/airbytehq/airbyte/pull/32125) | fix compilation warnings | -| 3.1.6 | 2023-11-06 | [32193](https://github.com/airbytehq/airbyte/pull/32193) | Adopt java CDK version 0.4.1. | -| 3.1.5 | 2023-10-31 | [32024](https://github.com/airbytehq/airbyte/pull/32024) | Upgrade to Debezium version 2.4.0. | -| 3.1.4 | 2023-10-30 | [31960](https://github.com/airbytehq/airbyte/pull/31960) | Adopt java CDK version 0.2.0. | -| 3.1.3 | 2023-10-11 | [31322](https://github.com/airbytehq/airbyte/pull/31322) | Correct pevious release | -| 3.1.2 | 2023-09-29 | [30806](https://github.com/airbytehq/airbyte/pull/30806) | Cap log line length to 32KB to prevent loss of records | -| 3.1.1 | 2023-09-26 | [30744](https://github.com/airbytehq/airbyte/pull/30744) | Update MySQL JDBC connection configs to keep default auto-commit behavior | -| 3.1.0 | 2023-09-21 | [30270](https://github.com/airbytehq/airbyte/pull/30270) | Enhanced Standard Sync with initial load via Primary Key with a switch to cursor for incremental syncs | -| 3.0.9 | 2023-09-20 | [30620](https://github.com/airbytehq/airbyte/pull/30620) | Airbyte Certified MySQL Source connector | -| 3.0.8 | 2023-09-14 | [30333](https://github.com/airbytehq/airbyte/pull/30333) | CDC : Update the correct timezone parameter passed to Debezium to `database.connectionTimezone` | -| 3.0.7 | 2023-09-13 | [30375](https://github.com/airbytehq/airbyte/pull/30375) | Fix a bug causing a failure when DB views are included in sync | -| 3.0.6 | 2023-09-12 | [30308](https://github.com/airbytehq/airbyte/pull/30308) | CDC : Enable compression of schema history blob in state | -| 3.0.5 | 2023-09-12 | [30289](https://github.com/airbytehq/airbyte/pull/30289) | CDC : Introduce logic for compression of schema history blob in state | -| 3.0.4 | 2023-09-06 | [30213](https://github.com/airbytehq/airbyte/pull/30213) | CDC : Checkpointable initial snapshot | -| 3.0.3 | 2023-08-31 | [29821](https://github.com/airbytehq/airbyte/pull/29821) | Set replication_method display_type to radio | -| 3.0.2 | 2023-08-30 | [30015](https://github.com/airbytehq/airbyte/pull/30015) | Logging : Log storage engines associated with tables in the sync | -| 3.0.1 | 2023-08-21 | [29308](https://github.com/airbytehq/airbyte/pull/29308) | CDC: Enable frequent state emissions during incremental runs | -| 3.0.0 | 2023-08-08 | [28756](https://github.com/airbytehq/airbyte/pull/28756) | CDC: Set a default cursor | -| 2.1.2 | 2023-08-08 | [29220](https://github.com/airbytehq/airbyte/pull/29220) | Add indicator that CDC is the recommended update method | -| 2.1.1 | 2023-07-31 | [28882](https://github.com/airbytehq/airbyte/pull/28882) | Improve replication method labels and descriptions | -| 2.1.0 | 2023-06-26 | [27737](https://github.com/airbytehq/airbyte/pull/27737) | License Update: Elv2 | -| 2.0.25 | 2023-06-20 | [27212](https://github.com/airbytehq/airbyte/pull/27212) | Fix silent exception swallowing in StreamingJdbcDatabase | -| 2.0.24 | 2023-05-25 | [26473](https://github.com/airbytehq/airbyte/pull/26473) | CDC : Limit queue size | -| 2.0.23 | 2023-05-24 | [25586](https://github.com/airbytehq/airbyte/pull/25586) | No need to base64 encode strings on databases sorted with binary collation | -| 2.0.22 | 2023-05-22 | [25859](https://github.com/airbytehq/airbyte/pull/25859) | Allow adding sessionVariables JDBC parameters | -| 2.0.21 | 2023-05-10 | [25460](https://github.com/airbytehq/airbyte/pull/25460) | Handle a decimal number with 0 decimal points as an integer | -| 2.0.20 | 2023-05-01 | [25740](https://github.com/airbytehq/airbyte/pull/25740) | Disable index logging | -| 2.0.19 | 2023-04-26 | [25401](https://github.com/airbytehq/airbyte/pull/25401) | CDC : Upgrade Debezium to version 2.2.0 | -| 2.0.18 | 2023-04-19 | [25345](https://github.com/airbytehq/airbyte/pull/25345) | Logging : Log database indexes per stream | -| 2.0.17 | 2023-04-19 | [24582](https://github.com/airbytehq/airbyte/pull/24582) | CDC : refactor for performance improvement | -| 2.0.16 | 2023-04-17 | [25220](https://github.com/airbytehq/airbyte/pull/25220) | Logging changes : Log additional metadata & clean up noisy logs | -| 2.0.15 | 2023-04-12 | [25131](https://github.com/airbytehq/airbyte/pull/25131) | Make Client Certificate and Client Key always show | -| 2.0.14 | 2023-04-11 | [24656](https://github.com/airbytehq/airbyte/pull/24656) | CDC minor refactor | -| 2.0.13 | 2023-04-06 | [24820](https://github.com/airbytehq/airbyte/pull/24820) | Fix data loss bug during an initial failed non-CDC incremental sync | -| 2.0.12 | 2023-04-04 | [24833](https://github.com/airbytehq/airbyte/pull/24833) | Fix Debezium retry policy configuration | -| 2.0.11 | 2023-03-28 | [24166](https://github.com/airbytehq/airbyte/pull/24166) | Fix InterruptedException bug during Debezium shutdown | -| 2.0.10 | 2023-03-27 | [24529](https://github.com/airbytehq/airbyte/pull/24373) | Preparing the connector for CDC checkpointing | -| 2.0.9 | 2023-03-24 | [24529](https://github.com/airbytehq/airbyte/pull/24529) | Set SSL Mode to required on strict-encrypt variant | -| 2.0.8 | 2023-03-22 | [20760](https://github.com/airbytehq/airbyte/pull/20760) | Removed redundant date-time datatypes formatting | -| 2.0.7 | 2023-03-21 | [24207](https://github.com/airbytehq/airbyte/pull/24207) | Fix incorrect schema change warning in CDC mode | -| 2.0.6 | 2023-03-21 | [23984](https://github.com/airbytehq/airbyte/pull/23984) | Support CDC heartbeats | -| 2.0.5 | 2023-03-21 | [24147](https://github.com/airbytehq/airbyte/pull/24275) | Fix error with CDC checkpointing | -| 2.0.4 | 2023-03-20 | [24147](https://github.com/airbytehq/airbyte/pull/24147) | Support different table structure during "DESCRIBE" query | -| 2.0.3 | 2023-03-15 | [24082](https://github.com/airbytehq/airbyte/pull/24082) | Fixed NPE during cursor values validation | -| 2.0.2 | 2023-03-14 | [23908](https://github.com/airbytehq/airbyte/pull/23908) | Log warning on null cursor values | -| 2.0.1 | 2023-03-10 | [23939](https://github.com/airbytehq/airbyte/pull/23939) | For network isolation, source connector accepts a list of hosts it is allowed to connect | -| 2.0.0 | 2023-03-06 | [23112](https://github.com/airbytehq/airbyte/pull/23112) | Upgrade Debezium version to 2.1.2 | -| 1.0.21 | 2023-01-25 | [20939](https://github.com/airbytehq/airbyte/pull/20939) | Adjust batch selection memory limits databases. | -| 1.0.20 | 2023-01-24 | [20593](https://github.com/airbytehq/airbyte/pull/20593) | Handle ssh time out exception | -| 1.0.19 | 2022-12-14 | [20436](https://github.com/airbytehq/airbyte/pull/20346) | Consolidate date/time values mapping for JDBC sources | -| 1.0.18 | 2022-12-14 | [20378](https://github.com/airbytehq/airbyte/pull/20378) | Improve descriptions | -| 1.0.17 | 2022-12-13 | [20289](https://github.com/airbytehq/airbyte/pull/20289) | Mark unknown column exception as config error | -| 1.0.16 | 2022-12-12 | [18959](https://github.com/airbytehq/airbyte/pull/18959) | CDC : Don't timeout if snapshot is not complete. | -| 1.0.15 | 2022-12-06 | [20000](https://github.com/airbytehq/airbyte/pull/20000) | Add check and better messaging when user does not have permission to access binary log in CDC mode | -| 1.0.14 | 2022-11-22 | [19514](https://github.com/airbytehq/airbyte/pull/19514) | Adjust batch selection memory limits databases. | -| 1.0.13 | 2022-11-14 | [18956](https://github.com/airbytehq/airbyte/pull/18956) | Clean up Tinyint Unsigned data type identification | -| 1.0.12 | 2022-11-07 | [19025](https://github.com/airbytehq/airbyte/pull/19025) | Stop enforce SSL if ssl mode is disabled | -| 1.0.11 | 2022-11-03 | [18851](https://github.com/airbytehq/airbyte/pull/18851) | Fix bug with unencrypted CDC connections | -| 1.0.10 | 2022-11-02 | [18619](https://github.com/airbytehq/airbyte/pull/18619) | Fix bug with handling Tinyint(1) Unsigned values as boolean | -| 1.0.9 | 2022-10-31 | [18538](https://github.com/airbytehq/airbyte/pull/18538) | Encode database name | -| 1.0.8 | 2022-10-25 | [18383](https://github.com/airbytehq/airbyte/pull/18383) | Better SSH error handling + messages | -| 1.0.7 | 2022-10-21 | [18263](https://github.com/airbytehq/airbyte/pull/18263) | Fixes bug introduced in [15833](https://github.com/airbytehq/airbyte/pull/15833) and adds better error messaging for SSH tunnel in Destinations | -| 1.0.6 | 2022-10-19 | [18087](https://github.com/airbytehq/airbyte/pull/18087) | Better error messaging for configuration errors (SSH configs, choosing an invalid cursor) | -| 1.0.5 | 2022-10-17 | [18041](https://github.com/airbytehq/airbyte/pull/18041) | Fixes bug introduced 2022-09-12 with SshTunnel, handles iterator exception properly | -| | 2022-10-13 | [15535](https://github.com/airbytehq/airbyte/pull/16238) | Update incremental query to avoid data missing when new data is inserted at the same time as a sync starts under non-CDC incremental mode | -| 1.0.4 | 2022-10-11 | [17815](https://github.com/airbytehq/airbyte/pull/17815) | Expose setting server timezone for CDC syncs | -| 1.0.3 | 2022-10-07 | [17236](https://github.com/airbytehq/airbyte/pull/17236) | Fix large table issue by fetch size | -| 1.0.2 | 2022-10-03 | [17170](https://github.com/airbytehq/airbyte/pull/17170) | Make initial CDC waiting time configurable | -| 1.0.1 | 2022-10-01 | [17459](https://github.com/airbytehq/airbyte/pull/17459) | Upgrade debezium version to 1.9.6 from 1.9.2 | -| 1.0.0 | 2022-09-27 | [17164](https://github.com/airbytehq/airbyte/pull/17164) | Certify MySQL Source as Beta | -| 0.6.15 | 2022-09-27 | [17299](https://github.com/airbytehq/airbyte/pull/17299) | Improve error handling for strict-encrypt mysql source | -| 0.6.14 | 2022-09-26 | [16954](https://github.com/airbytehq/airbyte/pull/16954) | Implement support for snapshot of new tables in CDC mode | -| 0.6.13 | 2022-09-14 | [15668](https://github.com/airbytehq/airbyte/pull/15668) | Wrap logs in AirbyteLogMessage | -| 0.6.12 | 2022-09-13 | [16657](https://github.com/airbytehq/airbyte/pull/16657) | Improve CDC record queueing performance | -| 0.6.11 | 2022-09-08 | [16202](https://github.com/airbytehq/airbyte/pull/16202) | Adds error messaging factory to UI | -| 0.6.10 | 2022-09-08 | [16007](https://github.com/airbytehq/airbyte/pull/16007) | Implement per stream state support. | -| 0.6.9 | 2022-09-03 | [16216](https://github.com/airbytehq/airbyte/pull/16216) | Standardize spec for CDC replication. See upgrade instructions [above](#upgrading-from-0.6.8-and-older-versions-to-0.6.9-and-later-versions). | -| 0.6.8 | 2022-09-01 | [16259](https://github.com/airbytehq/airbyte/pull/16259) | Emit state messages more frequently | -| 0.6.7 | 2022-08-30 | [16114](https://github.com/airbytehq/airbyte/pull/16114) | Prevent traffic going on an unsecured channel in strict-encryption version of source mysql | -| 0.6.6 | 2022-08-25 | [15993](https://github.com/airbytehq/airbyte/pull/15993) | Improved support for connecting over SSL | -| 0.6.5 | 2022-08-25 | [15917](https://github.com/airbytehq/airbyte/pull/15917) | Fix temporal data type default value bug | -| 0.6.4 | 2022-08-18 | [14356](https://github.com/airbytehq/airbyte/pull/14356) | DB Sources: only show a table can sync incrementally if at least one column can be used as a cursor field | -| 0.6.3 | 2022-08-12 | [15044](https://github.com/airbytehq/airbyte/pull/15044) | Added the ability to connect using different SSL modes and SSL certificates | -| 0.6.2 | 2022-08-11 | [15538](https://github.com/airbytehq/airbyte/pull/15538) | Allow additional properties in db stream state | -| 0.6.1 | 2022-08-02 | [14801](https://github.com/airbytehq/airbyte/pull/14801) | Fix multiple log bindings | -| 0.6.0 | 2022-07-26 | [14362](https://github.com/airbytehq/airbyte/pull/14362) | Integral columns are now discovered as int64 fields. | -| 0.5.17 | 2022-07-22 | [14714](https://github.com/airbytehq/airbyte/pull/14714) | Clarified error message when invalid cursor column selected | -| 0.5.16 | 2022-07-14 | [14574](https://github.com/airbytehq/airbyte/pull/14574) | Removed additionalProperties:false from JDBC source connectors | -| 0.5.15 | 2022-06-23 | [14077](https://github.com/airbytehq/airbyte/pull/14077) | Use the new state management | -| 0.5.13 | 2022-06-21 | [13945](https://github.com/airbytehq/airbyte/pull/13945) | Aligned datatype test | -| 0.5.12 | 2022-06-17 | [13864](https://github.com/airbytehq/airbyte/pull/13864) | Updated stacktrace format for any trace message errors | -| 0.5.11 | 2022-05-03 | [12544](https://github.com/airbytehq/airbyte/pull/12544) | Prevent source from hanging under certain circumstances by adding a watcher for orphaned threads. | -| 0.5.10 | 2022-04-29 | [12480](https://github.com/airbytehq/airbyte/pull/12480) | Query tables with adaptive fetch size to optimize JDBC memory consumption | -| 0.5.9 | 2022-04-06 | [11729](https://github.com/airbytehq/airbyte/pull/11729) | Bump mina-sshd from 2.7.0 to 2.8.0 | -| 0.5.6 | 2022-02-21 | [10242](https://github.com/airbytehq/airbyte/pull/10242) | Fixed cursor for old connectors that use non-microsecond format. Now connectors work with both formats | -| 0.5.5 | 2022-02-18 | [10242](https://github.com/airbytehq/airbyte/pull/10242) | Updated timestamp transformation with microseconds | -| 0.5.4 | 2022-02-11 | [10251](https://github.com/airbytehq/airbyte/issues/10251) | bug Source MySQL CDC: sync failed when has Zero-date value in mandatory column | -| 0.5.2 | 2021-12-14 | [6425](https://github.com/airbytehq/airbyte/issues/6425) | MySQL CDC sync fails because starting binlog position not found in DB | -| 0.5.1 | 2021-12-13 | [8582](https://github.com/airbytehq/airbyte/pull/8582) | Update connector fields title/description | -| 0.5.0 | 2021-12-11 | [7970](https://github.com/airbytehq/airbyte/pull/7970) | Support all MySQL types | -| 0.4.13 | 2021-12-03 | [8335](https://github.com/airbytehq/airbyte/pull/8335) | Source-MySql: do not check cdc required param binlog_row_image for standard replication | -| 0.4.12 | 2021-12-01 | [8371](https://github.com/airbytehq/airbyte/pull/8371) | Fixed incorrect handling "\n" in ssh key | -| 0.4.11 | 2021-11-19 | [8047](https://github.com/airbytehq/airbyte/pull/8047) | Source MySQL: transform binary data base64 format | -| 0.4.10 | 2021-11-15 | [7820](https://github.com/airbytehq/airbyte/pull/7820) | Added basic performance test | -| 0.4.9 | 2021-11-02 | [7559](https://github.com/airbytehq/airbyte/pull/7559) | Correctly process large unsigned short integer values which may fall outside java's `Short` data type capability | -| 0.4.8 | 2021-09-16 | [6093](https://github.com/airbytehq/airbyte/pull/6093) | Improve reliability of processing various data types like decimals, dates, datetime, binary, and text | -| 0.4.7 | 2021-09-30 | [6585](https://github.com/airbytehq/airbyte/pull/6585) | Improved SSH Tunnel key generation steps | -| 0.4.6 | 2021-09-29 | [6510](https://github.com/airbytehq/airbyte/pull/6510) | Support SSL connection | -| 0.4.5 | 2021-09-17 | [6146](https://github.com/airbytehq/airbyte/pull/6146) | Added option to connect to DB via SSH | -| 0.4.1 | 2021-07-23 | [4956](https://github.com/airbytehq/airbyte/pull/4956) | Fix log link | -| 0.3.7 | 2021-06-09 | [3179](https://github.com/airbytehq/airbyte/pull/3973) | Add AIRBYTE_ENTRYPOINT for Kubernetes support | -| 0.3.6 | 2021-06-09 | [3966](https://github.com/airbytehq/airbyte/pull/3966) | Fix excessive logging for CDC method | -| 0.3.5 | 2021-06-07 | [3890](https://github.com/airbytehq/airbyte/pull/3890) | Fix CDC handle tinyint\(1\) and boolean types | -| 0.3.4 | 2021-06-04 | [3846](https://github.com/airbytehq/airbyte/pull/3846) | Fix max integer value failure | -| 0.3.3 | 2021-06-02 | [3789](https://github.com/airbytehq/airbyte/pull/3789) | MySQL CDC poll wait 5 minutes when not received a single record | -| 0.3.2 | 2021-06-01 | [3757](https://github.com/airbytehq/airbyte/pull/3757) | MySQL CDC poll 5s to 5 min | -| 0.3.1 | 2021-06-01 | [3505](https://github.com/airbytehq/airbyte/pull/3505) | Implemented MySQL CDC | -| 0.3.0 | 2021-04-21 | [2990](https://github.com/airbytehq/airbyte/pull/2990) | Support namespaces | -| 0.2.5 | 2021-04-15 | [2899](https://github.com/airbytehq/airbyte/pull/2899) | Fix bug in tests | -| 0.2.4 | 2021-03-28 | [2600](https://github.com/airbytehq/airbyte/pull/2600) | Add NCHAR and NVCHAR support to DB and cursor type casting | -| 0.2.3 | 2021-03-26 | [2611](https://github.com/airbytehq/airbyte/pull/2611) | Add an optional `jdbc_url_params` in parameters | -| 0.2.2 | 2021-03-26 | [2460](https://github.com/airbytehq/airbyte/pull/2460) | Destination supports destination sync mode | -| 0.2.1 | 2021-03-18 | [2488](https://github.com/airbytehq/airbyte/pull/2488) | Sources support primary keys | -| 0.2.0 | 2021-03-09 | [2238](https://github.com/airbytehq/airbyte/pull/2238) | Protocol allows future/unknown properties | -| 0.1.10 | 2021-02-02 | [1887](https://github.com/airbytehq/airbyte/pull/1887) | Migrate AbstractJdbcSource to use iterators | -| 0.1.9 | 2021-01-25 | [1746](https://github.com/airbytehq/airbyte/pull/1746) | Fix NPE in State Decorator | -| 0.1.8 | 2021-01-19 | [1724](https://github.com/airbytehq/airbyte/pull/1724) | Fix JdbcSource handling of tables with same names in different schemas | -| 0.1.7 | 2021-01-14 | [1655](https://github.com/airbytehq/airbyte/pull/1655) | Fix JdbcSource OOM | -| 0.1.6 | 2021-01-08 | [1307](https://github.com/airbytehq/airbyte/pull/1307) | Migrate Postgres and MySQL to use new JdbcSource | -| 0.1.5 | 2020-12-11 | [1267](https://github.com/airbytehq/airbyte/pull/1267) | Support incremental sync | -| 0.1.4 | 2020-11-30 | [1046](https://github.com/airbytehq/airbyte/pull/1046) | Add connectors using an index YAML file | - -
\ No newline at end of file +| Version | Date | Pull Request | Subject | +|:------------|:-----------|:-----------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------| +| 3.10.0-rc.9 | 2025-01-08 | [50987](https://github.com/airbytehq/airbyte/pull/50987) | Increase Debezium shutdown timeout. | +| 3.10.0-rc.8 | 2025-01-07 | [50965](https://github.com/airbytehq/airbyte/pull/50965) | Fix bug introduced in 3.10.0-rc.3. | +| 3.10.0-rc.7 | 2024-12-27 | [50437](https://github.com/airbytehq/airbyte/pull/50437) | Compatibility with MySQL Views. | +| 3.10.0-rc.6 | 2024-12-18 | [49892](https://github.com/airbytehq/airbyte/pull/49892) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 3.10.0-rc.5 | 2025-01-03 | [50868](https://github.com/airbytehq/airbyte/pull/50868) | Fix exception handling rules declaration. | +| 3.10.0-rc.4 | 2024-12-23 | [48587](https://github.com/airbytehq/airbyte/pull/48587) | Fix minor state counting mechanism. | +| 3.10.0-rc.3 | 2024-12-20 | [49918](https://github.com/airbytehq/airbyte/pull/49918) | Fix minor datatype handling and conversion bugs, maintain big number precision. | +| 3.10.0-rc.2 | 2024-12-20 | [49950](https://github.com/airbytehq/airbyte/pull/49950) | Remove unused configuration field, streamline SSL certificate key store logic. | +| 3.10.0-rc.1 | 2024-12-20 | [49948](https://github.com/airbytehq/airbyte/pull/49948) | Pin Bulk CDK version to 231, adopt required changes. | +| 3.9.4 | 2024-12-18 | [49939](https://github.com/airbytehq/airbyte/pull/49939) | Pin Bulk CDK version to 226, rename classes. | +| 3.9.3 | 2024-12-18 | [49932](https://github.com/airbytehq/airbyte/pull/49932) | Backward compatibility for saved states with timestamp that include timezone offset. | +| 3.9.2 | 2024-12-16 | [49830](https://github.com/airbytehq/airbyte/pull/49830) | Fixes an issue with auto generated tinyint columns | +| 3.9.1 | 2024-12-12 | [49456](https://github.com/airbytehq/airbyte/pull/49456) | Bump version to re-relase | +| 3.9.0 | 2024-12-12 | [49423](https://github.com/airbytehq/airbyte/pull/49423) | Promoting release candidate 3.9.0-rc.27 to a main version. | +| 3.9.0-rc | 2024-11-05 | [48369](https://github.com/airbytehq/airbyte/pull/48369) | Progressive rollout test. | +| 3.7.3 | 2024-09-17 | [45639](https://github.com/airbytehq/airbyte/pull/45639) | Adopt latest CDK to use the latest apache sshd mina to handle tcpkeepalive requests. | +| 3.7.2 | 2024-09-05 | [45181](https://github.com/airbytehq/airbyte/pull/45181) | Fix incorrect categorizing resumable/nonresumable full refresh streams. | +| 3.7.1 | 2024-08-27 | [44841](https://github.com/airbytehq/airbyte/pull/44841) | Adopt latest CDK. | +| 3.7.0 | 2024-08-13 | [44013](https://github.com/airbytehq/airbyte/pull/44013) | Upgrading to Debezium 2.7.1.Final | +| 3.6.9 | 2024-08-08 | [43410](https://github.com/airbytehq/airbyte/pull/43410) | Adopt latest CDK. | +| 3.6.8 | 2024-07-30 | [42869](https://github.com/airbytehq/airbyte/pull/42869) | Adopt latest CDK. | +| 3.6.7 | 2024-07-30 | [42550](https://github.com/airbytehq/airbyte/pull/42550) | Correctly report stream states. | +| 3.6.6 | 2024-07-29 | [42852](https://github.com/airbytehq/airbyte/pull/42852) | Bump CDK version to latest to use new bug fixes on error translation. | +| 3.6.5 | 2024-07-24 | [42417](https://github.com/airbytehq/airbyte/pull/42417) | Handle null error message in ConnectorExceptionHandler. | +| 3.6.4 | 2024-07-23 | [42421](https://github.com/airbytehq/airbyte/pull/42421) | Remove final transient error emitter iterators. | +| 3.6.3 | 2024-07-22 | [42024](https://github.com/airbytehq/airbyte/pull/42024) | Fix a NPE bug on resuming from a failed attempt. | +| 3.6.2 | 2024-07-17 | [42087](https://github.com/airbytehq/airbyte/pull/42087) | Adding more error translations for MySql source. | +| 3.6.1 | 2024-07-19 | [42122](https://github.com/airbytehq/airbyte/pull/42122) | Improve wass error message + logging. | +| 3.6.0 | 2024-07-17 | [40208](https://github.com/airbytehq/airbyte/pull/40208) | Start using the new error MySql source error handler that comes with a new error translation layer. | +| 3.5.1 | 2024-07-17 | [42043](https://github.com/airbytehq/airbyte/pull/42043) | Adopt latest CDK + fixes. | +| 3.5.0 | 2024-07-11 | [38240](https://github.com/airbytehq/airbyte/pull/38240) | Implement WASS. | +| 3.4.12 | 2024-07-01 | [40516](https://github.com/airbytehq/airbyte/pull/40516) | Remove dbz heartbeat. | +| 3.4.11 | 2024-06-26 | [40561](https://github.com/airbytehq/airbyte/pull/40561) | Support PlanetScale MySQL's per-query row limit. | +| 3.4.10 | 2024-06-14 | [39349](https://github.com/airbytehq/airbyte/pull/39349) | Full refresh stream sending internal count metadata. | +| 3.4.9 | 2024-06-11 | [39405](https://github.com/airbytehq/airbyte/pull/39405) | Adopt latest CDK. | +| 3.4.8 | 2024-06-05 | [39144](https://github.com/airbytehq/airbyte/pull/39144) | Upgrade Debezium to 2.5.4 | +| 3.4.7 | 2024-05-29 | [38584](https://github.com/airbytehq/airbyte/pull/38584) | Set is_resumable flag in discover. | +| 3.4.6 | 2024-05-29 | [38538](https://github.com/airbytehq/airbyte/pull/38538) | Exit connector when encountering a config error. | +| 3.4.5 | 2024-05-23 | [38198](https://github.com/airbytehq/airbyte/pull/38198) | Sync sending trace status messages indicating progress. | +| 3.4.4 | 2024-05-15 | [38208](https://github.com/airbytehq/airbyte/pull/38208) | disable counts in full refresh stream in state message. | +| 3.4.3 | 2024-05-13 | [38104](https://github.com/airbytehq/airbyte/pull/38104) | Handle transient error messages. | +| 3.4.2 | 2024-05-07 | [38046](https://github.com/airbytehq/airbyte/pull/38046) | Resumeable refresh should run only if there is source defined pk. | +| 3.4.1 | 2024-05-03 | [37824](https://github.com/airbytehq/airbyte/pull/37824) | Fixed a bug on Resumeable full refresh where cursor based source throw NPE. | +| 3.4.0 | 2024-05-02 | [36932](https://github.com/airbytehq/airbyte/pull/36932) | Resumeable full refresh. Note please upgrade your platform - minimum platform version is 0.58.0. | +| 3.3.25 | 2024-05-02 | [37781](https://github.com/airbytehq/airbyte/pull/37781) | Adopt latest CDK. | +| 3.3.24 | 2024-05-01 | [37742](https://github.com/airbytehq/airbyte/pull/37742) | Adopt latest CDK. Remove Debezium retries. | +| 3.3.23 | 2024-04-23 | [37507](https://github.com/airbytehq/airbyte/pull/37507) | Better errors when user switches from CDC to non-CDC mode. | +| 3.3.22 | 2024-04-22 | [37541](https://github.com/airbytehq/airbyte/pull/37541) | Adopt latest CDK. reduce excessive logs. | +| 3.3.21 | 2024-04-22 | [37476](https://github.com/airbytehq/airbyte/pull/37476) | Adopt latest CDK. | +| 3.3.20 | 2024-04-16 | [37111](https://github.com/airbytehq/airbyte/pull/37111) | Populate null values in record message. | +| 3.3.19 | 2024-04-15 | [37328](https://github.com/airbytehq/airbyte/pull/37328) | Populate airbyte_meta.changes | +| 3.3.18 | 2024-04-15 | [37324](https://github.com/airbytehq/airbyte/pull/37324) | Refactor source operations. | +| 3.3.17 | 2024-04-10 | [36919](https://github.com/airbytehq/airbyte/pull/36919) | Fix a bug in conversion of null values. | +| 3.3.16 | 2024-04-05 | [36872](https://github.com/airbytehq/airbyte/pull/36872) | Update to connector's metadat definition. | +| 3.3.15 | 2024-04-05 | [36577](https://github.com/airbytehq/airbyte/pull/36577) | Config error will not send out system trace message | +| 3.3.14 | 2024-04-04 | [36742](https://github.com/airbytehq/airbyte/pull/36742) | To use new kotlin CDK | +| 3.3.13 | 2024-02-29 | [35529](https://github.com/airbytehq/airbyte/pull/35529) | Refactor state iterator messages. | +| 3.3.12 | 2024-02-27 | [35675](https://github.com/airbytehq/airbyte/pull/35675) | Fix invalid cdc error message. | +| 3.3.11 | 2024-02-23 | [35527](https://github.com/airbytehq/airbyte/pull/35527) | Adopt 0.23.1 and shutdown timeouts. | +| 3.3.10 | 2024-02-22 | [35569](https://github.com/airbytehq/airbyte/pull/35569) | Fix logging bug. | +| 3.3.9 | 2024-02-21 | [35525](https://github.com/airbytehq/airbyte/pull/35338) | Adopt 0.21.4 and reduce cdc state compression threshold to 1MB. | +| 3.3.8 | 2024-02-20 | [35338](https://github.com/airbytehq/airbyte/pull/35338) | Add config to throw an error on invalid CDC position. | +| 3.3.7 | 2024-02-13 | [35036](https://github.com/airbytehq/airbyte/pull/34751) | Emit analytics message for invalid CDC cursor. | +| 3.3.6 | 2024-02-13 | [34869](https://github.com/airbytehq/airbyte/pull/34573) | Don't emit state in SourceStateIterator when there is an underlying stream failure. | +| 3.3.5 | 2024-02-12 | [34580](https://github.com/airbytehq/airbyte/pull/34580) | Support special chars in db name | +| 3.3.4 | 2024-02-08 | [34750](https://github.com/airbytehq/airbyte/pull/34750) | Adopt CDK 0.19.0 | +| 3.3.3 | 2024-01-26 | [34573](https://github.com/airbytehq/airbyte/pull/34573) | Adopt CDK v0.16.0. | +| 3.3.2 | 2024-01-08 | [33005](https://github.com/airbytehq/airbyte/pull/33005) | Adding count stats for incremental sync in AirbyteStateMessage | +| 3.3.1 | 2024-01-03 | [33312](https://github.com/airbytehq/airbyte/pull/33312) | Adding count stats in AirbyteStateMessage | +| 3.3.0 | 2023-12-19 | [33436](https://github.com/airbytehq/airbyte/pull/33436) | Remove LEGACY state flag | +| 3.2.4 | 2023-12-12 | [33356](https://github.com/airbytehq/airbyte/pull/33210) | Support for better debugging tools.. | +| 3.2.3 | 2023-12-08 | [33210](https://github.com/airbytehq/airbyte/pull/33210) | Update MySql driver property value for zero date handling. | +| 3.2.2 | 2023-12-06 | [33082](https://github.com/airbytehq/airbyte/pull/33082) | Improvements to MySQL schema snapshot error handling. | +| 3.2.1 | 2023-11-28 | [32610](https://github.com/airbytehq/airbyte/pull/32610) | Support initial syncs using binary as primary key. | +| 3.2.0 | 2023-11-29 | [31062](https://github.com/airbytehq/airbyte/pull/31062) | enforce SSL on Airbyte Cloud | +| 3.1.9 | 2023-11-27 | [32662](https://github.com/airbytehq/airbyte/pull/32662) | Apply initial setup time to debezium engine warmup time. | +| 3.1.8 | 2023-11-22 | [32656](https://github.com/airbytehq/airbyte/pull/32656) | Adopt java CDK version 0.5.0. | +| 3.1.7 | 2023-11-08 | [32125](https://github.com/airbytehq/airbyte/pull/32125) | fix compilation warnings | +| 3.1.6 | 2023-11-06 | [32193](https://github.com/airbytehq/airbyte/pull/32193) | Adopt java CDK version 0.4.1. | +| 3.1.5 | 2023-10-31 | [32024](https://github.com/airbytehq/airbyte/pull/32024) | Upgrade to Debezium version 2.4.0. | +| 3.1.4 | 2023-10-30 | [31960](https://github.com/airbytehq/airbyte/pull/31960) | Adopt java CDK version 0.2.0. | +| 3.1.3 | 2023-10-11 | [31322](https://github.com/airbytehq/airbyte/pull/31322) | Correct pevious release | +| 3.1.2 | 2023-09-29 | [30806](https://github.com/airbytehq/airbyte/pull/30806) | Cap log line length to 32KB to prevent loss of records | +| 3.1.1 | 2023-09-26 | [30744](https://github.com/airbytehq/airbyte/pull/30744) | Update MySQL JDBC connection configs to keep default auto-commit behavior | +| 3.1.0 | 2023-09-21 | [30270](https://github.com/airbytehq/airbyte/pull/30270) | Enhanced Standard Sync with initial load via Primary Key with a switch to cursor for incremental syncs | +| 3.0.9 | 2023-09-20 | [30620](https://github.com/airbytehq/airbyte/pull/30620) | Airbyte Certified MySQL Source connector | +| 3.0.8 | 2023-09-14 | [30333](https://github.com/airbytehq/airbyte/pull/30333) | CDC : Update the correct timezone parameter passed to Debezium to `database.connectionTimezone` | +| 3.0.7 | 2023-09-13 | [30375](https://github.com/airbytehq/airbyte/pull/30375) | Fix a bug causing a failure when DB views are included in sync | +| 3.0.6 | 2023-09-12 | [30308](https://github.com/airbytehq/airbyte/pull/30308) | CDC : Enable compression of schema history blob in state | +| 3.0.5 | 2023-09-12 | [30289](https://github.com/airbytehq/airbyte/pull/30289) | CDC : Introduce logic for compression of schema history blob in state | +| 3.0.4 | 2023-09-06 | [30213](https://github.com/airbytehq/airbyte/pull/30213) | CDC : Checkpointable initial snapshot | +| 3.0.3 | 2023-08-31 | [29821](https://github.com/airbytehq/airbyte/pull/29821) | Set replication_method display_type to radio | +| 3.0.2 | 2023-08-30 | [30015](https://github.com/airbytehq/airbyte/pull/30015) | Logging : Log storage engines associated with tables in the sync | +| 3.0.1 | 2023-08-21 | [29308](https://github.com/airbytehq/airbyte/pull/29308) | CDC: Enable frequent state emissions during incremental runs | +| 3.0.0 | 2023-08-08 | [28756](https://github.com/airbytehq/airbyte/pull/28756) | CDC: Set a default cursor | +| 2.1.2 | 2023-08-08 | [29220](https://github.com/airbytehq/airbyte/pull/29220) | Add indicator that CDC is the recommended update method | +| 2.1.1 | 2023-07-31 | [28882](https://github.com/airbytehq/airbyte/pull/28882) | Improve replication method labels and descriptions | +| 2.1.0 | 2023-06-26 | [27737](https://github.com/airbytehq/airbyte/pull/27737) | License Update: Elv2 | +| 2.0.25 | 2023-06-20 | [27212](https://github.com/airbytehq/airbyte/pull/27212) | Fix silent exception swallowing in StreamingJdbcDatabase | +| 2.0.24 | 2023-05-25 | [26473](https://github.com/airbytehq/airbyte/pull/26473) | CDC : Limit queue size | +| 2.0.23 | 2023-05-24 | [25586](https://github.com/airbytehq/airbyte/pull/25586) | No need to base64 encode strings on databases sorted with binary collation | +| 2.0.22 | 2023-05-22 | [25859](https://github.com/airbytehq/airbyte/pull/25859) | Allow adding sessionVariables JDBC parameters | +| 2.0.21 | 2023-05-10 | [25460](https://github.com/airbytehq/airbyte/pull/25460) | Handle a decimal number with 0 decimal points as an integer | +| 2.0.20 | 2023-05-01 | [25740](https://github.com/airbytehq/airbyte/pull/25740) | Disable index logging | +| 2.0.19 | 2023-04-26 | [25401](https://github.com/airbytehq/airbyte/pull/25401) | CDC : Upgrade Debezium to version 2.2.0 | +| 2.0.18 | 2023-04-19 | [25345](https://github.com/airbytehq/airbyte/pull/25345) | Logging : Log database indexes per stream | +| 2.0.17 | 2023-04-19 | [24582](https://github.com/airbytehq/airbyte/pull/24582) | CDC : refactor for performance improvement | +| 2.0.16 | 2023-04-17 | [25220](https://github.com/airbytehq/airbyte/pull/25220) | Logging changes : Log additional metadata & clean up noisy logs | +| 2.0.15 | 2023-04-12 | [25131](https://github.com/airbytehq/airbyte/pull/25131) | Make Client Certificate and Client Key always show | +| 2.0.14 | 2023-04-11 | [24656](https://github.com/airbytehq/airbyte/pull/24656) | CDC minor refactor | +| 2.0.13 | 2023-04-06 | [24820](https://github.com/airbytehq/airbyte/pull/24820) | Fix data loss bug during an initial failed non-CDC incremental sync | +| 2.0.12 | 2023-04-04 | [24833](https://github.com/airbytehq/airbyte/pull/24833) | Fix Debezium retry policy configuration | +| 2.0.11 | 2023-03-28 | [24166](https://github.com/airbytehq/airbyte/pull/24166) | Fix InterruptedException bug during Debezium shutdown | +| 2.0.10 | 2023-03-27 | [24529](https://github.com/airbytehq/airbyte/pull/24373) | Preparing the connector for CDC checkpointing | +| 2.0.9 | 2023-03-24 | [24529](https://github.com/airbytehq/airbyte/pull/24529) | Set SSL Mode to required on strict-encrypt variant | +| 2.0.8 | 2023-03-22 | [20760](https://github.com/airbytehq/airbyte/pull/20760) | Removed redundant date-time datatypes formatting | +| 2.0.7 | 2023-03-21 | [24207](https://github.com/airbytehq/airbyte/pull/24207) | Fix incorrect schema change warning in CDC mode | +| 2.0.6 | 2023-03-21 | [23984](https://github.com/airbytehq/airbyte/pull/23984) | Support CDC heartbeats | +| 2.0.5 | 2023-03-21 | [24147](https://github.com/airbytehq/airbyte/pull/24275) | Fix error with CDC checkpointing | +| 2.0.4 | 2023-03-20 | [24147](https://github.com/airbytehq/airbyte/pull/24147) | Support different table structure during "DESCRIBE" query | +| 2.0.3 | 2023-03-15 | [24082](https://github.com/airbytehq/airbyte/pull/24082) | Fixed NPE during cursor values validation | +| 2.0.2 | 2023-03-14 | [23908](https://github.com/airbytehq/airbyte/pull/23908) | Log warning on null cursor values | +| 2.0.1 | 2023-03-10 | [23939](https://github.com/airbytehq/airbyte/pull/23939) | For network isolation, source connector accepts a list of hosts it is allowed to connect | +| 2.0.0 | 2023-03-06 | [23112](https://github.com/airbytehq/airbyte/pull/23112) | Upgrade Debezium version to 2.1.2 | +| 1.0.21 | 2023-01-25 | [20939](https://github.com/airbytehq/airbyte/pull/20939) | Adjust batch selection memory limits databases. | +| 1.0.20 | 2023-01-24 | [20593](https://github.com/airbytehq/airbyte/pull/20593) | Handle ssh time out exception | +| 1.0.19 | 2022-12-14 | [20436](https://github.com/airbytehq/airbyte/pull/20346) | Consolidate date/time values mapping for JDBC sources | +| 1.0.18 | 2022-12-14 | [20378](https://github.com/airbytehq/airbyte/pull/20378) | Improve descriptions | +| 1.0.17 | 2022-12-13 | [20289](https://github.com/airbytehq/airbyte/pull/20289) | Mark unknown column exception as config error | +| 1.0.16 | 2022-12-12 | [18959](https://github.com/airbytehq/airbyte/pull/18959) | CDC : Don't timeout if snapshot is not complete. | +| 1.0.15 | 2022-12-06 | [20000](https://github.com/airbytehq/airbyte/pull/20000) | Add check and better messaging when user does not have permission to access binary log in CDC mode | +| 1.0.14 | 2022-11-22 | [19514](https://github.com/airbytehq/airbyte/pull/19514) | Adjust batch selection memory limits databases. | +| 1.0.13 | 2022-11-14 | [18956](https://github.com/airbytehq/airbyte/pull/18956) | Clean up Tinyint Unsigned data type identification | +| 1.0.12 | 2022-11-07 | [19025](https://github.com/airbytehq/airbyte/pull/19025) | Stop enforce SSL if ssl mode is disabled | +| 1.0.11 | 2022-11-03 | [18851](https://github.com/airbytehq/airbyte/pull/18851) | Fix bug with unencrypted CDC connections | +| 1.0.10 | 2022-11-02 | [18619](https://github.com/airbytehq/airbyte/pull/18619) | Fix bug with handling Tinyint(1) Unsigned values as boolean | +| 1.0.9 | 2022-10-31 | [18538](https://github.com/airbytehq/airbyte/pull/18538) | Encode database name | +| 1.0.8 | 2022-10-25 | [18383](https://github.com/airbytehq/airbyte/pull/18383) | Better SSH error handling + messages | +| 1.0.7 | 2022-10-21 | [18263](https://github.com/airbytehq/airbyte/pull/18263) | Fixes bug introduced in [15833](https://github.com/airbytehq/airbyte/pull/15833) and adds better error messaging for SSH tunnel in Destinations | +| 1.0.6 | 2022-10-19 | [18087](https://github.com/airbytehq/airbyte/pull/18087) | Better error messaging for configuration errors (SSH configs, choosing an invalid cursor) | +| 1.0.5 | 2022-10-17 | [18041](https://github.com/airbytehq/airbyte/pull/18041) | Fixes bug introduced 2022-09-12 with SshTunnel, handles iterator exception properly | +| | 2022-10-13 | [15535](https://github.com/airbytehq/airbyte/pull/16238) | Update incremental query to avoid data missing when new data is inserted at the same time as a sync starts under non-CDC incremental mode | +| 1.0.4 | 2022-10-11 | [17815](https://github.com/airbytehq/airbyte/pull/17815) | Expose setting server timezone for CDC syncs | +| 1.0.3 | 2022-10-07 | [17236](https://github.com/airbytehq/airbyte/pull/17236) | Fix large table issue by fetch size | +| 1.0.2 | 2022-10-03 | [17170](https://github.com/airbytehq/airbyte/pull/17170) | Make initial CDC waiting time configurable | +| 1.0.1 | 2022-10-01 | [17459](https://github.com/airbytehq/airbyte/pull/17459) | Upgrade debezium version to 1.9.6 from 1.9.2 | +| 1.0.0 | 2022-09-27 | [17164](https://github.com/airbytehq/airbyte/pull/17164) | Certify MySQL Source as Beta | +| 0.6.15 | 2022-09-27 | [17299](https://github.com/airbytehq/airbyte/pull/17299) | Improve error handling for strict-encrypt mysql source | +| 0.6.14 | 2022-09-26 | [16954](https://github.com/airbytehq/airbyte/pull/16954) | Implement support for snapshot of new tables in CDC mode | +| 0.6.13 | 2022-09-14 | [15668](https://github.com/airbytehq/airbyte/pull/15668) | Wrap logs in AirbyteLogMessage | +| 0.6.12 | 2022-09-13 | [16657](https://github.com/airbytehq/airbyte/pull/16657) | Improve CDC record queueing performance | +| 0.6.11 | 2022-09-08 | [16202](https://github.com/airbytehq/airbyte/pull/16202) | Adds error messaging factory to UI | +| 0.6.10 | 2022-09-08 | [16007](https://github.com/airbytehq/airbyte/pull/16007) | Implement per stream state support. | +| 0.6.9 | 2022-09-03 | [16216](https://github.com/airbytehq/airbyte/pull/16216) | Standardize spec for CDC replication. See upgrade instructions [above](#upgrading-from-0.6.8-and-older-versions-to-0.6.9-and-later-versions). | +| 0.6.8 | 2022-09-01 | [16259](https://github.com/airbytehq/airbyte/pull/16259) | Emit state messages more frequently | +| 0.6.7 | 2022-08-30 | [16114](https://github.com/airbytehq/airbyte/pull/16114) | Prevent traffic going on an unsecured channel in strict-encryption version of source mysql | +| 0.6.6 | 2022-08-25 | [15993](https://github.com/airbytehq/airbyte/pull/15993) | Improved support for connecting over SSL | +| 0.6.5 | 2022-08-25 | [15917](https://github.com/airbytehq/airbyte/pull/15917) | Fix temporal data type default value bug | +| 0.6.4 | 2022-08-18 | [14356](https://github.com/airbytehq/airbyte/pull/14356) | DB Sources: only show a table can sync incrementally if at least one column can be used as a cursor field | +| 0.6.3 | 2022-08-12 | [15044](https://github.com/airbytehq/airbyte/pull/15044) | Added the ability to connect using different SSL modes and SSL certificates | +| 0.6.2 | 2022-08-11 | [15538](https://github.com/airbytehq/airbyte/pull/15538) | Allow additional properties in db stream state | +| 0.6.1 | 2022-08-02 | [14801](https://github.com/airbytehq/airbyte/pull/14801) | Fix multiple log bindings | +| 0.6.0 | 2022-07-26 | [14362](https://github.com/airbytehq/airbyte/pull/14362) | Integral columns are now discovered as int64 fields. | +| 0.5.17 | 2022-07-22 | [14714](https://github.com/airbytehq/airbyte/pull/14714) | Clarified error message when invalid cursor column selected | +| 0.5.16 | 2022-07-14 | [14574](https://github.com/airbytehq/airbyte/pull/14574) | Removed additionalProperties:false from JDBC source connectors | +| 0.5.15 | 2022-06-23 | [14077](https://github.com/airbytehq/airbyte/pull/14077) | Use the new state management | +| 0.5.13 | 2022-06-21 | [13945](https://github.com/airbytehq/airbyte/pull/13945) | Aligned datatype test | +| 0.5.12 | 2022-06-17 | [13864](https://github.com/airbytehq/airbyte/pull/13864) | Updated stacktrace format for any trace message errors | +| 0.5.11 | 2022-05-03 | [12544](https://github.com/airbytehq/airbyte/pull/12544) | Prevent source from hanging under certain circumstances by adding a watcher for orphaned threads. | +| 0.5.10 | 2022-04-29 | [12480](https://github.com/airbytehq/airbyte/pull/12480) | Query tables with adaptive fetch size to optimize JDBC memory consumption | +| 0.5.9 | 2022-04-06 | [11729](https://github.com/airbytehq/airbyte/pull/11729) | Bump mina-sshd from 2.7.0 to 2.8.0 | +| 0.5.6 | 2022-02-21 | [10242](https://github.com/airbytehq/airbyte/pull/10242) | Fixed cursor for old connectors that use non-microsecond format. Now connectors work with both formats | +| 0.5.5 | 2022-02-18 | [10242](https://github.com/airbytehq/airbyte/pull/10242) | Updated timestamp transformation with microseconds | +| 0.5.4 | 2022-02-11 | [10251](https://github.com/airbytehq/airbyte/issues/10251) | bug Source MySQL CDC: sync failed when has Zero-date value in mandatory column | +| 0.5.2 | 2021-12-14 | [6425](https://github.com/airbytehq/airbyte/issues/6425) | MySQL CDC sync fails because starting binlog position not found in DB | +| 0.5.1 | 2021-12-13 | [8582](https://github.com/airbytehq/airbyte/pull/8582) | Update connector fields title/description | +| 0.5.0 | 2021-12-11 | [7970](https://github.com/airbytehq/airbyte/pull/7970) | Support all MySQL types | +| 0.4.13 | 2021-12-03 | [8335](https://github.com/airbytehq/airbyte/pull/8335) | Source-MySql: do not check cdc required param binlog_row_image for standard replication | +| 0.4.12 | 2021-12-01 | [8371](https://github.com/airbytehq/airbyte/pull/8371) | Fixed incorrect handling "\n" in ssh key | +| 0.4.11 | 2021-11-19 | [8047](https://github.com/airbytehq/airbyte/pull/8047) | Source MySQL: transform binary data base64 format | +| 0.4.10 | 2021-11-15 | [7820](https://github.com/airbytehq/airbyte/pull/7820) | Added basic performance test | +| 0.4.9 | 2021-11-02 | [7559](https://github.com/airbytehq/airbyte/pull/7559) | Correctly process large unsigned short integer values which may fall outside java's `Short` data type capability | +| 0.4.8 | 2021-09-16 | [6093](https://github.com/airbytehq/airbyte/pull/6093) | Improve reliability of processing various data types like decimals, dates, datetime, binary, and text | +| 0.4.7 | 2021-09-30 | [6585](https://github.com/airbytehq/airbyte/pull/6585) | Improved SSH Tunnel key generation steps | +| 0.4.6 | 2021-09-29 | [6510](https://github.com/airbytehq/airbyte/pull/6510) | Support SSL connection | +| 0.4.5 | 2021-09-17 | [6146](https://github.com/airbytehq/airbyte/pull/6146) | Added option to connect to DB via SSH | +| 0.4.1 | 2021-07-23 | [4956](https://github.com/airbytehq/airbyte/pull/4956) | Fix log link | +| 0.3.7 | 2021-06-09 | [3179](https://github.com/airbytehq/airbyte/pull/3973) | Add AIRBYTE_ENTRYPOINT for Kubernetes support | +| 0.3.6 | 2021-06-09 | [3966](https://github.com/airbytehq/airbyte/pull/3966) | Fix excessive logging for CDC method | +| 0.3.5 | 2021-06-07 | [3890](https://github.com/airbytehq/airbyte/pull/3890) | Fix CDC handle tinyint\(1\) and boolean types | +| 0.3.4 | 2021-06-04 | [3846](https://github.com/airbytehq/airbyte/pull/3846) | Fix max integer value failure | +| 0.3.3 | 2021-06-02 | [3789](https://github.com/airbytehq/airbyte/pull/3789) | MySQL CDC poll wait 5 minutes when not received a single record | +| 0.3.2 | 2021-06-01 | [3757](https://github.com/airbytehq/airbyte/pull/3757) | MySQL CDC poll 5s to 5 min | +| 0.3.1 | 2021-06-01 | [3505](https://github.com/airbytehq/airbyte/pull/3505) | Implemented MySQL CDC | +| 0.3.0 | 2021-04-21 | [2990](https://github.com/airbytehq/airbyte/pull/2990) | Support namespaces | +| 0.2.5 | 2021-04-15 | [2899](https://github.com/airbytehq/airbyte/pull/2899) | Fix bug in tests | +| 0.2.4 | 2021-03-28 | [2600](https://github.com/airbytehq/airbyte/pull/2600) | Add NCHAR and NVCHAR support to DB and cursor type casting | +| 0.2.3 | 2021-03-26 | [2611](https://github.com/airbytehq/airbyte/pull/2611) | Add an optional `jdbc_url_params` in parameters | +| 0.2.2 | 2021-03-26 | [2460](https://github.com/airbytehq/airbyte/pull/2460) | Destination supports destination sync mode | +| 0.2.1 | 2021-03-18 | [2488](https://github.com/airbytehq/airbyte/pull/2488) | Sources support primary keys | +| 0.2.0 | 2021-03-09 | [2238](https://github.com/airbytehq/airbyte/pull/2238) | Protocol allows future/unknown properties | +| 0.1.10 | 2021-02-02 | [1887](https://github.com/airbytehq/airbyte/pull/1887) | Migrate AbstractJdbcSource to use iterators | +| 0.1.9 | 2021-01-25 | [1746](https://github.com/airbytehq/airbyte/pull/1746) | Fix NPE in State Decorator | +| 0.1.8 | 2021-01-19 | [1724](https://github.com/airbytehq/airbyte/pull/1724) | Fix JdbcSource handling of tables with same names in different schemas | +| 0.1.7 | 2021-01-14 | [1655](https://github.com/airbytehq/airbyte/pull/1655) | Fix JdbcSource OOM | +| 0.1.6 | 2021-01-08 | [1307](https://github.com/airbytehq/airbyte/pull/1307) | Migrate Postgres and MySQL to use new JdbcSource | +| 0.1.5 | 2020-12-11 | [1267](https://github.com/airbytehq/airbyte/pull/1267) | Support incremental sync | +| 0.1.4 | 2020-11-30 | [1046](https://github.com/airbytehq/airbyte/pull/1046) | Add connectors using an index YAML file | + + diff --git a/docs/integrations/sources/mysql/mysql-troubleshooting.md b/docs/integrations/sources/mysql/mysql-troubleshooting.md index b733ef331181..84e403f91323 100644 --- a/docs/integrations/sources/mysql/mysql-troubleshooting.md +++ b/docs/integrations/sources/mysql/mysql-troubleshooting.md @@ -10,6 +10,8 @@ - Make sure to read our [CDC docs](../../../understanding-airbyte/cdc.md) to see limitations that impact all databases using CDC replication. - Our CDC implementation uses at least once delivery for all change records. +- To enable CDC with incremental sync, ensure the table has at least one primary key. + Tables without primary keys can still be replicated by CDC but only in Full Refresh mode. ### Vendor-Specific Connector Limitations diff --git a/docs/integrations/sources/nasa.md b/docs/integrations/sources/nasa.md index e4508f4970e1..d4c68c724619 100644 --- a/docs/integrations/sources/nasa.md +++ b/docs/integrations/sources/nasa.md @@ -43,6 +43,11 @@ The NASA connector should not run into NASA API limitations under normal usage. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :----------------------------------------- | +| 0.3.8 | 2024-12-28 | [50595](https://github.com/airbytehq/airbyte/pull/50595) | Update dependencies | +| 0.3.7 | 2024-12-21 | [50083](https://github.com/airbytehq/airbyte/pull/50083) | Update dependencies | +| 0.3.6 | 2024-12-14 | [49637](https://github.com/airbytehq/airbyte/pull/49637) | Update dependencies | +| 0.3.5 | 2024-12-12 | [49231](https://github.com/airbytehq/airbyte/pull/49231) | Update dependencies | +| 0.3.4 | 2024-12-11 | [48990](https://github.com/airbytehq/airbyte/pull/48990) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.3.3 | 2024-10-29 | [47740](https://github.com/airbytehq/airbyte/pull/47740) | Update dependencies | | 0.3.2 | 2024-10-28 | [47491](https://github.com/airbytehq/airbyte/pull/47491) | Update dependencies | | 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/navan.md b/docs/integrations/sources/navan.md new file mode 100644 index 000000000000..ae8b0d862e87 --- /dev/null +++ b/docs/integrations/sources/navan.md @@ -0,0 +1,37 @@ +# Navan + +The Navan connector supports travel booking data such as hotels and flights. + +## Prerequisites + +* Client ID and Client Secret - Credentials for accessing the Navan API that can be created by administrators. + * Learn how to create these API credentials by following [documentation provided by Navan](https://app.navan.com/app/helpcenter/articles/travel/admin/other-integrations/booking-data-integration). Note that API credential details are only accessible once. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `client_id` | `string` | OAuth Client ID. | | +| `client_secret` | `string` | OAuth Client Secret. | | +| `start_date` | `string` | Start date. | | + +## Streams + +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| bookings | uuid | DefaultPaginator | ✅ | ✅ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50642](https://github.com/airbytehq/airbyte/pull/50642) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50106](https://github.com/airbytehq/airbyte/pull/50106) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49599](https://github.com/airbytehq/airbyte/pull/49599) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49217](https://github.com/airbytehq/airbyte/pull/49217) | Update dependencies | +| 0.0.1 | 2024-11-26 | | Initial release by [@matteogp](https://github.com/matteogp) via Connector Builder | + +
diff --git a/docs/integrations/sources/news-api.md b/docs/integrations/sources/news-api.md index 23eaa8381e89..5b85b110522f 100644 --- a/docs/integrations/sources/news-api.md +++ b/docs/integrations/sources/news-api.md @@ -61,6 +61,10 @@ The following fields are required fields for the connector to work: | Version | Date | Pull Request | Subject | |:--------|:-----------| :------------------------------------------------------- | :--------------------------------------- | +| 0.2.7 | 2024-12-28 | [50602](https://github.com/airbytehq/airbyte/pull/50602) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50071](https://github.com/airbytehq/airbyte/pull/50071) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49214](https://github.com/airbytehq/airbyte/pull/49214) | Update dependencies | +| 0.2.4 | 2024-11-04 | [48143](https://github.com/airbytehq/airbyte/pull/48143) | Update dependencies | | 0.2.3 | 2024-10-29 | [47866](https://github.com/airbytehq/airbyte/pull/47866) | Update dependencies | | 0.2.2 | 2024-10-28 | [47562](https://github.com/airbytehq/airbyte/pull/47562) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/newsdata-io.md b/docs/integrations/sources/newsdata-io.md new file mode 100644 index 000000000000..a0809d710776 --- /dev/null +++ b/docs/integrations/sources/newsdata-io.md @@ -0,0 +1,41 @@ +# NewsData.io +Connector for NewsData.io to get the latest news in pagination and the latest news from specific countries, categories and domains. You can also get the news sources from specific categories, countries and languages. + +:::info +Historical News is only available for premium users of NewsData service. +::: + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | +| `start_date` | `string` | Start Date. | | +| `end_date` | `string` | End Date. | | +| `categories` | `string` | Categories to filter news. | | +| `countries` | `string` | Countries to filter news. | | +| `languages` | `string` | Language to filter news. | | +| `domains` | `string` | Specific domains to filter news | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| latest_news | `article_id` | DefaultPaginator | ✅ | ❌ | +| historical_news | `article_id` | DefaultPaginator | ✅ | ✅ | + + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50643](https://github.com/airbytehq/airbyte/pull/50643) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50097](https://github.com/airbytehq/airbyte/pull/50097) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49630](https://github.com/airbytehq/airbyte/pull/49630) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49259](https://github.com/airbytehq/airbyte/pull/49259) | Update dependencies | +| 0.0.2 | 2024-12-11 | [48999](https://github.com/airbytehq/airbyte/pull/48999) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-08 | | Initial release by [@faria-karim-porna](https://github.com/faria-karim-porna) via Connector Builder | + +
diff --git a/docs/integrations/sources/newsdata.md b/docs/integrations/sources/newsdata.md index 6ba6a55e881b..50c33395c3aa 100644 --- a/docs/integrations/sources/newsdata.md +++ b/docs/integrations/sources/newsdata.md @@ -48,7 +48,9 @@ The following fields are required fields for the connector to work: | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | -| 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | +| 0.2.3 | 2025-01-04 | [50896](https://github.com/airbytehq/airbyte/pull/50896) | Update dependencies | +| 0.2.2 | 2024-12-12 | [47812](https://github.com/airbytehq/airbyte/pull/47812) | Update dependencies | +| 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-15 | [44113](https://github.com/airbytehq/airbyte/pull/44113) | Refactor connector to manifest-only format | | 0.1.15 | 2024-08-10 | [43517](https://github.com/airbytehq/airbyte/pull/43517) | Update dependencies | | 0.1.14 | 2024-08-03 | [43271](https://github.com/airbytehq/airbyte/pull/43271) | Update dependencies | diff --git a/docs/integrations/sources/nocrm.md b/docs/integrations/sources/nocrm.md new file mode 100644 index 000000000000..8bce253631be --- /dev/null +++ b/docs/integrations/sources/nocrm.md @@ -0,0 +1,43 @@ +# NoCRM +[NoCRM](https://nocrm.io) connector enables seamless data integration between NoCRM.io, a lead management tool, and other platforms or data warehouses. It allows for the automated extraction and synchronization of lead data, activities, and contact details from NoCRM.io into analytics systems, supporting data-driven decisions and streamlined workflows. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use. Generate it from the admin section of your noCRM.io account. | | +| `subdomain` | `string` | Subdomain. The subdomain specific to your noCRM.io account, e.g., 'yourcompany' in 'yourcompany.nocrm.io'. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| steps | id | No pagination | ✅ | ❌ | +| pipelines | id | No pagination | ✅ | ❌ | +| clients_folders | id | No pagination | ✅ | ❌ | +| categories | id | No pagination | ✅ | ❌ | +| predefined_tags | id | No pagination | ✅ | ❌ | +| fields | id | No pagination | ✅ | ❌ | +| leads | id | DefaultPaginator | ✅ | ❌ | +| follow_ups | id | No pagination | ✅ | ❌ | +| users | id | No pagination | ✅ | ❌ | +| teams | id | No pagination | ✅ | ❌ | +| webhooks | id | No pagination | ✅ | ❌ | +| webhook_events | id | No pagination | ✅ | ❌ | +| activities | id | No pagination | ✅ | ❌ | +| prospecting_lists | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50667](https://github.com/airbytehq/airbyte/pull/50667) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50090](https://github.com/airbytehq/airbyte/pull/50090) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49635](https://github.com/airbytehq/airbyte/pull/49635) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49252](https://github.com/airbytehq/airbyte/pull/49252) | Update dependencies | +| 0.0.2 | 2024-12-11 | [48944](https://github.com/airbytehq/airbyte/pull/48944) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-08 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/northpass-lms.md b/docs/integrations/sources/northpass-lms.md index cadb26618ed3..e6f7c2c02a6a 100644 --- a/docs/integrations/sources/northpass-lms.md +++ b/docs/integrations/sources/northpass-lms.md @@ -81,6 +81,12 @@ Link to Northpass LMS API documentation [here](https://developers.northpass.com/ | Version | Date | Pull Request | Subject | |:---------|:-----------|:---------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------| +| 0.2.8 | 2024-12-28 | [50606](https://github.com/airbytehq/airbyte/pull/50606) | Update dependencies | +| 0.2.7 | 2024-12-21 | [50125](https://github.com/airbytehq/airbyte/pull/50125) | Update dependencies | +| 0.2.6 | 2024-12-14 | [49625](https://github.com/airbytehq/airbyte/pull/49625) | Update dependencies | +| 0.2.5 | 2024-12-12 | [49221](https://github.com/airbytehq/airbyte/pull/49221) | Update dependencies | +| 0.2.4 | 2024-12-11 | [48907](https://github.com/airbytehq/airbyte/pull/48907) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.3 | 2024-11-04 | [48257](https://github.com/airbytehq/airbyte/pull/48257) | Update dependencies | | 0.2.2 | 2024-10-29 | [47863](https://github.com/airbytehq/airbyte/pull/47863) | Update dependencies | | 0.2.1 | 2024-10-28 | [47520](https://github.com/airbytehq/airbyte/pull/47520) | Update dependencies | | 0.2.0 | 2024-08-26 | [44771](https://github.com/airbytehq/airbyte/pull/44771) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/nutshell.md b/docs/integrations/sources/nutshell.md new file mode 100644 index 000000000000..d031d2d45041 --- /dev/null +++ b/docs/integrations/sources/nutshell.md @@ -0,0 +1,57 @@ +# Nutshell +Nutshell is a CRM tool. +Using this connector we can extract data from various streams such as contacts , events , products and pipelines. +[API Docs](https://developers.nutshell.com/docs/getting-started) + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `username` | `string` | Username. | | +| `password` | `string` | API Token. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| accounts | id | DefaultPaginator | ✅ | ❌ | +| accounts_list_items | id | No pagination | ✅ | ❌ | +| account_types | id | No pagination | ✅ | ❌ | +| industries | id | No pagination | ✅ | ❌ | +| activities | id | DefaultPaginator | ✅ | ❌ | +| activity_types | id | No pagination | ✅ | ❌ | +| audiences | id | No pagination | ✅ | ❌ | +| competitors | id | No pagination | ✅ | ❌ | +| competitor_maps | id | No pagination | ✅ | ❌ | +| leads_custom_fields | id | No pagination | ✅ | ❌ | +| leads_list_items | id | No pagination | ✅ | ❌ | +| leads | id | DefaultPaginator | ✅ | ❌ | +| leads_report | id | No pagination | ✅ | ❌ | +| contacts_custom_fields | id | No pagination | ✅ | ❌ | +| contacts | id | DefaultPaginator | ✅ | ❌ | +| contacts_list_items | id | No pagination | ✅ | ❌ | +| events | id | DefaultPaginator | ✅ | ❌ | +| filters | id | No pagination | ✅ | ❌ | +| notes | id | DefaultPaginator | ✅ | ❌ | +| products | id | No pagination | ✅ | ❌ | +| lead_products | id | No pagination | ✅ | ❌ | +| sources | id | No pagination | ✅ | ❌ | +| stages | id | No pagination | ✅ | ❌ | +| pipelines | id | No pagination | ✅ | ❌ | +| tags | id | No pagination | ✅ | ❌ | +| users | id | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50615](https://github.com/airbytehq/airbyte/pull/50615) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50130](https://github.com/airbytehq/airbyte/pull/50130) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49641](https://github.com/airbytehq/airbyte/pull/49641) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49228](https://github.com/airbytehq/airbyte/pull/49228) | Update dependencies | +| 0.0.2 | 2024-12-11 | [48988](https://github.com/airbytehq/airbyte/pull/48988) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-08 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/nylas.md b/docs/integrations/sources/nylas.md index 220d40db902b..ca27687cbc75 100644 --- a/docs/integrations/sources/nylas.md +++ b/docs/integrations/sources/nylas.md @@ -33,6 +33,11 @@ The Nylas platform provides an integration layer that makes it easy to connect a | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.8 | 2024-12-28 | [50641](https://github.com/airbytehq/airbyte/pull/50641) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50112](https://github.com/airbytehq/airbyte/pull/50112) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49615](https://github.com/airbytehq/airbyte/pull/49615) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49220](https://github.com/airbytehq/airbyte/pull/49220) | Update dependencies | +| 0.0.4 | 2024-12-11 | [48319](https://github.com/airbytehq/airbyte/pull/48319) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.3 | 2024-10-29 | [47926](https://github.com/airbytehq/airbyte/pull/47926) | Update dependencies | | 0.0.2 | 2024-10-28 | [47649](https://github.com/airbytehq/airbyte/pull/47649) | Update dependencies | | 0.0.1 | 2024-09-03 | | Initial release by [@topefolorunso](https://github.com/topefolorunso) via Connector Builder | diff --git a/docs/integrations/sources/okta.md b/docs/integrations/sources/okta.md index 159ffd0cefa4..d08fe8cd576d 100644 --- a/docs/integrations/sources/okta.md +++ b/docs/integrations/sources/okta.md @@ -86,6 +86,12 @@ The connector is restricted by normal Okta [requests limitation](https://develop | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:-------------------------------------------------------------------------------| +| 0.3.16 | 2025-01-04 | [50899](https://github.com/airbytehq/airbyte/pull/50899) | Update dependencies | +| 0.3.15 | 2024-12-28 | [50670](https://github.com/airbytehq/airbyte/pull/50670) | Update dependencies | +| 0.3.14 | 2024-12-21 | [50073](https://github.com/airbytehq/airbyte/pull/50073) | Update dependencies | +| 0.3.13 | 2024-12-14 | [49264](https://github.com/airbytehq/airbyte/pull/49264) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.3.12 | 2024-12-12 | [49145](https://github.com/airbytehq/airbyte/pull/49145) | Update dependencies | +| 0.3.11 | 2024-11-04 | [47900](https://github.com/airbytehq/airbyte/pull/47900) | Update dependencies | | 0.3.10 | 2024-10-28 | [47058](https://github.com/airbytehq/airbyte/pull/47058) | Update dependencies | | 0.3.9 | 2024-10-12 | [46804](https://github.com/airbytehq/airbyte/pull/46804) | Update dependencies | | 0.3.8 | 2024-10-05 | [46481](https://github.com/airbytehq/airbyte/pull/46481) | Update dependencies | diff --git a/docs/integrations/sources/omnisend.md b/docs/integrations/sources/omnisend.md index 8f78ad235348..f668898f9f63 100644 --- a/docs/integrations/sources/omnisend.md +++ b/docs/integrations/sources/omnisend.md @@ -36,6 +36,10 @@ The connector has a rate limit of 400 requests per 1 minute. | Version | Date | Pull Request | Subject | |:--------|:-----------| :------------------------------------------------------- | :------------- | +| 0.2.5 | 2024-12-28 | [50291](https://github.com/airbytehq/airbyte/pull/50291) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49674](https://github.com/airbytehq/airbyte/pull/49674) | Update dependencies | +| 0.2.3 | 2024-12-12 | [49365](https://github.com/airbytehq/airbyte/pull/49365) | Update dependencies | +| 0.2.2 | 2024-12-11 | [48284](https://github.com/airbytehq/airbyte/pull/48284) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.1 | 2024-10-29 | [47474](https://github.com/airbytehq/airbyte/pull/47474) | Update dependencies | | 0.2.0 | 2024-08-19 | [44411](https://github.com/airbytehq/airbyte/pull/44411) | Refactor connector to manifest-only format | | 0.1.13 | 2024-08-17 | [44307](https://github.com/airbytehq/airbyte/pull/44307) | Update dependencies | diff --git a/docs/integrations/sources/oncehub.md b/docs/integrations/sources/oncehub.md new file mode 100644 index 000000000000..6c91c7ba2b0b --- /dev/null +++ b/docs/integrations/sources/oncehub.md @@ -0,0 +1,41 @@ +# Oncehub +This is the Oncehub source that ingests data from the Oncehub API. + +Oncehub is a no-code conversational journeys builder, integrating AI, chatbots, live chat, instant calls, and scheduled meetings https://oncehub.com/. + +To use this source you must first create an account. Once logged in head over to Settings -> API & Webhooks and copy your API Key. +You can learn more about the API here https://developers.oncehub.com/reference/introduction + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use. Find it in your OnceHub account under the API & Webhooks Integration page. | | +| `start_date` | `string` | Start date. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| bookings | id | CursorPagination | ✅ | ✅ | +| booking_pages | id | CursorPagination | ✅ | ❌ | +| event_types | id | CursorPagination | ✅ | ❌ | +| master_pages | id | CursorPagination | ✅ | ❌ | +| users | id | CursorPagination | ✅ | ❌ | +| teams | id | CursorPagination | ✅ | ❌ | +| contacts | id | CursorPagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50690](https://github.com/airbytehq/airbyte/pull/50690) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50238](https://github.com/airbytehq/airbyte/pull/50238) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49725](https://github.com/airbytehq/airbyte/pull/49725) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49329](https://github.com/airbytehq/airbyte/pull/49329) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49094](https://github.com/airbytehq/airbyte/pull/49094) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-30 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | + +
diff --git a/docs/integrations/sources/onepagecrm.md b/docs/integrations/sources/onepagecrm.md new file mode 100644 index 000000000000..42cab0e08f87 --- /dev/null +++ b/docs/integrations/sources/onepagecrm.md @@ -0,0 +1,50 @@ +# Onepagecrm +Onepagecrm is a CRM solution for small busineeses. +Using this stream we can extarct data from various streams such as contacts , deals , pipelines and meetings +[API Documentation](https://developer.onepagecrm.com/api/) + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `username` | `string` | Username. Enter the user ID of your API app | | +| `password` | `string` | Password. Enter your API Key of your API app | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| contacts | id | DefaultPaginator | ✅ | ❌ | +| users | id | DefaultPaginator | ✅ | ❌ | +| bootstrap | user_id | DefaultPaginator | ✅ | ❌ | +| companies | id | DefaultPaginator | ✅ | ❌ | +| actions | id | DefaultPaginator | ✅ | ❌ | +| action_stream | | DefaultPaginator | ✅ | ❌ | +| team_stream | | DefaultPaginator | ✅ | ❌ | +| deals | id | DefaultPaginator | ✅ | ❌ | +| notes | id | DefaultPaginator | ✅ | ❌ | +| relationship_types | id | DefaultPaginator | ✅ | ❌ | +| pipelines | id | DefaultPaginator | ✅ | ❌ | +| statuses | id | DefaultPaginator | ✅ | ❌ | +| lead_sources | id | DefaultPaginator | ✅ | ❌ | +| filters | id | DefaultPaginator | ✅ | ❌ | +| predefined_actions | id | DefaultPaginator | ✅ | ❌ | +| predefined_items | id | DefaultPaginator | ✅ | ❌ | +| custom_fields | id | DefaultPaginator | ✅ | ❌ | +| calls | id | DefaultPaginator | ✅ | ❌ | +| meetings | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50745](https://github.com/airbytehq/airbyte/pull/50745) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50231](https://github.com/airbytehq/airbyte/pull/50231) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49729](https://github.com/airbytehq/airbyte/pull/49729) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49330](https://github.com/airbytehq/airbyte/pull/49330) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49072](https://github.com/airbytehq/airbyte/pull/49072) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-09 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/onesignal.md b/docs/integrations/sources/onesignal.md index 7d8e00369dbf..86b91fc141bf 100644 --- a/docs/integrations/sources/onesignal.md +++ b/docs/integrations/sources/onesignal.md @@ -78,6 +78,11 @@ The connector is restricted by normal OneSignal [rate limits](https://documentat | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------- | +| 1.2.6 | 2024-12-28 | [50719](https://github.com/airbytehq/airbyte/pull/50719) | Update dependencies | +| 1.2.5 | 2024-12-21 | [50243](https://github.com/airbytehq/airbyte/pull/50243) | Update dependencies | +| 1.2.4 | 2024-12-14 | [49706](https://github.com/airbytehq/airbyte/pull/49706) | Update dependencies | +| 1.2.3 | 2024-12-12 | [49349](https://github.com/airbytehq/airbyte/pull/49349) | Update dependencies | +| 1.2.2 | 2024-12-11 | [49106](https://github.com/airbytehq/airbyte/pull/49106) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 1.2.1 | 2024-10-29 | [47667](https://github.com/airbytehq/airbyte/pull/47667) | Update dependencies | | 1.2.0 | 2024-10-05 | [46372](https://github.com/airbytehq/airbyte/pull/46372) | Converting to manifest-only format | | 1.1.14 | 2024-09-28 | [46184](https://github.com/airbytehq/airbyte/pull/46184) | Update dependencies | diff --git a/docs/integrations/sources/onfleet.md b/docs/integrations/sources/onfleet.md new file mode 100644 index 000000000000..e855f7da5df1 --- /dev/null +++ b/docs/integrations/sources/onfleet.md @@ -0,0 +1,41 @@ +# Onfleet +This is the Onfleet connector that ingests data from the Onfleet API. + +Onfleet is the world's advanced logistics software that delights customers, scale operations, and boost efficiency https://onfleet.com/ + +In order to use this source you must first create an account on Onfleet. Once logged in, you can find the can create an API keys through the settings menu in the dashboard, by going into the API section. + +You can find more information about the API here https://docs.onfleet.com/reference/setup-tutorial + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use for authenticating requests. You can create and manage your API keys in the API section of the Onfleet dashboard. | | +| `password` | `string` | Placeholder Password. Placeholder for basic HTTP auth password - should be set to empty string | x | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| workers | id | No pagination | ✅ | ❌ | +| administrators | id | No pagination | ✅ | ❌ | +| teams | id | No pagination | ✅ | ❌ | +| hubs | id | No pagination | ✅ | ❌ | +| tasks | id | DefaultPaginator | ✅ | ❌ | +| containers | id | No pagination | ✅ | ❌ | + + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-21 | [50295](https://github.com/airbytehq/airbyte/pull/50295) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49712](https://github.com/airbytehq/airbyte/pull/49712) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49336](https://github.com/airbytehq/airbyte/pull/49336) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49051](https://github.com/airbytehq/airbyte/pull/49051) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-27 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | + +
diff --git a/docs/integrations/sources/open-data-dc.md b/docs/integrations/sources/open-data-dc.md index 579deffc67d5..f6ff5aa6acda 100644 --- a/docs/integrations/sources/open-data-dc.md +++ b/docs/integrations/sources/open-data-dc.md @@ -43,6 +43,10 @@ MARID is the Master Address Repository ID associated with all addresses within t | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50239](https://github.com/airbytehq/airbyte/pull/50239) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49703](https://github.com/airbytehq/airbyte/pull/49703) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49364](https://github.com/airbytehq/airbyte/pull/49364) | Update dependencies | +| 0.0.4 | 2024-12-11 | [49096](https://github.com/airbytehq/airbyte/pull/49096) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.3 | 2024-10-29 | [47912](https://github.com/airbytehq/airbyte/pull/47912) | Update dependencies | | 0.0.2 | 2024-10-28 | [47594](https://github.com/airbytehq/airbyte/pull/47594) | Update dependencies | | 0.0.1 | 2024-10-06 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | diff --git a/docs/integrations/sources/open-exchange-rates.md b/docs/integrations/sources/open-exchange-rates.md index 470baf98f249..5aede69283b6 100644 --- a/docs/integrations/sources/open-exchange-rates.md +++ b/docs/integrations/sources/open-exchange-rates.md @@ -48,6 +48,10 @@ If you have `free` subscription plan \(you may check it [here](https://openexcha | Version | Date | Pull Request | Subject | | :------ | :--------- | :--------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.3.7 | 2024-12-28 | [50673](https://github.com/airbytehq/airbyte/pull/50673) | Update dependencies | +| 0.3.6 | 2024-12-21 | [50301](https://github.com/airbytehq/airbyte/pull/50301) | Update dependencies | +| 0.3.5 | 2024-12-14 | [49678](https://github.com/airbytehq/airbyte/pull/49678) | Update dependencies | +| 0.3.4 | 2024-12-12 | [48251](https://github.com/airbytehq/airbyte/pull/48251) | Update dependencies | | 0.3.3 | 2024-10-29 | [47805](https://github.com/airbytehq/airbyte/pull/47805) | Update dependencies | | 0.3.2 | 2024-10-28 | [47452](https://github.com/airbytehq/airbyte/pull/47452) | Update dependencies | | 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/openaq.md b/docs/integrations/sources/openaq.md new file mode 100644 index 000000000000..64ac5b97bd9c --- /dev/null +++ b/docs/integrations/sources/openaq.md @@ -0,0 +1,47 @@ +# OpenAQ +The OpenAQ API provides open access to global air quality data. +This connector enables you to fetch data from all the streams listed on their website such as Locations , Sensors , Measurements and much more. + +Docs : https://docs.openaq.org/using-the-api/quick-start + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | +| `country_ids` | `array` | Countries. The list of IDs of countries (comma separated) you need the data for, check more: https://docs.openaq.org/resources/countries | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| instruments | id | DefaultPaginator | ✅ | ❌ | +| manufacturers | id | DefaultPaginator | ✅ | ❌ | +| manufacturer_instruments | id | No pagination | ✅ | ❌ | +| locations | id | DefaultPaginator | ✅ | ❌ | +| licenses | | DefaultPaginator | ✅ | ❌ | +| license_instrument | id | No pagination | ✅ | ❌ | +| parameters | id | DefaultPaginator | ✅ | ❌ | +| countries | id | DefaultPaginator | ✅ | ❌ | +| latest_parameters | | No pagination | ✅ | ❌ | +| sensors | id | DefaultPaginator | ✅ | ❌ | +| providers | id | DefaultPaginator | ✅ | ❌ | +| owners | id | DefaultPaginator | ✅ | ❌ | +| location_latest_measure | | No pagination | ✅ | ❌ | +| sensor_measurements | | DefaultPaginator | ✅ | ❌ | +| measurements_daily | | DefaultPaginator | ✅ | ❌ | +| measurements_yearly | | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50743](https://github.com/airbytehq/airbyte/pull/50743) | Update dependencies | +| 0.0.4 | 2024-12-21 | [49713](https://github.com/airbytehq/airbyte/pull/49713) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49318](https://github.com/airbytehq/airbyte/pull/49318) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49083](https://github.com/airbytehq/airbyte/pull/49083) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-06 | | Initial release by [@marcosmarxm](https://github.com/marcosmarxm) via Connector Builder | + +
diff --git a/docs/integrations/sources/openfda.md b/docs/integrations/sources/openfda.md new file mode 100644 index 000000000000..67797b24cff3 --- /dev/null +++ b/docs/integrations/sources/openfda.md @@ -0,0 +1,38 @@ +# OpenFDA +OpenFDA provides access to a number of high-value, high priority and scalable structured datasets, including adverse events, drug product labeling, and recall enforcement reports. +With this conenctor we can fetch data from the streams like Drugs , Animal and Veterinary Adverse Events and Food Adverse Events etc. +Docs:https://open.fda.gov/apis/ + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| Animal and Veterinary Adverse Events | unique_aer_id_number | DefaultPaginator | ✅ | ❌ | +| Tobacco Problem Reports | report_id | DefaultPaginator | ✅ | ❌ | +| Food Adverse Events | report_number | DefaultPaginator | ✅ | ❌ | +| Food Enforcement Reports | recall_number | DefaultPaginator | ✅ | ❌ | +| Drug Adverse Events | | DefaultPaginator | ✅ | ❌ | +| Drug Product Labelling | | DefaultPaginator | ✅ | ❌ | +| Drug NDC Library | product_id | DefaultPaginator | ✅ | ❌ | +| Drug recall Enforcement Reports | | DefaultPaginator | ✅ | ❌ | +| Drugs | | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50718](https://github.com/airbytehq/airbyte/pull/50718) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50285](https://github.com/airbytehq/airbyte/pull/50285) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49668](https://github.com/airbytehq/airbyte/pull/49668) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49351](https://github.com/airbytehq/airbyte/pull/49351) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49090](https://github.com/airbytehq/airbyte/pull/49090) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-23 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/openweather.md b/docs/integrations/sources/openweather.md index ba98bb81af9c..57f2f9a26b22 100644 --- a/docs/integrations/sources/openweather.md +++ b/docs/integrations/sources/openweather.md @@ -38,6 +38,11 @@ The free plan allows 60 calls per minute and 1,000,000 calls per month, you won' | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.3.7 | 2024-12-28 | [50733](https://github.com/airbytehq/airbyte/pull/50733) | Update dependencies | +| 0.3.6 | 2024-12-21 | [50258](https://github.com/airbytehq/airbyte/pull/50258) | Update dependencies | +| 0.3.5 | 2024-12-14 | [49707](https://github.com/airbytehq/airbyte/pull/49707) | Update dependencies | +| 0.3.4 | 2024-12-12 | [49332](https://github.com/airbytehq/airbyte/pull/49332) | Update dependencies | +| 0.3.3 | 2024-12-10 | [48871](https://github.com/airbytehq/airbyte/pull/48871) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.3.2 | 2024-10-29 | [47791](https://github.com/airbytehq/airbyte/pull/47791) | Update dependencies | | 0.3.1 | 2024-10-08 | [46652](https://github.com/airbytehq/airbyte/pull/46652) | Fix longitude regex matching | | 0.3.0 | 2024-08-26 | [44772](https://github.com/airbytehq/airbyte/pull/44772) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/opinion-stage.md b/docs/integrations/sources/opinion-stage.md new file mode 100644 index 000000000000..8e3b571fd43e --- /dev/null +++ b/docs/integrations/sources/opinion-stage.md @@ -0,0 +1,31 @@ +# Opinion Stage +The Airbyte connector for [OpinionStage](https://opinionstage.com) enables seamless data integration from the OpinionStage platform, facilitating the extraction of interactive content data. It streams data from items such as forms, quizzes, and polls, as well as capturing responses and specific questions associated with each item. This connector is ideal for users looking to analyze audience engagement, response patterns, and question insights from OpinionStage in their data workflows. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| items | id | DefaultPaginator | ✅ | ❌ | +| responses | id | DefaultPaginator | ✅ | ❌ | +| questions | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50721](https://github.com/airbytehq/airbyte/pull/50721) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50260](https://github.com/airbytehq/airbyte/pull/50260) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49726](https://github.com/airbytehq/airbyte/pull/49726) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49360](https://github.com/airbytehq/airbyte/pull/49360) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49060](https://github.com/airbytehq/airbyte/pull/49060) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-31 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/opsgenie.md b/docs/integrations/sources/opsgenie.md index ac55e9e54d7a..33e0f8cd493c 100644 --- a/docs/integrations/sources/opsgenie.md +++ b/docs/integrations/sources/opsgenie.md @@ -54,6 +54,8 @@ The Opsgenie connector uses the most recent API version for each source of data. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.4.5 | 2024-12-14 | [49661](https://github.com/airbytehq/airbyte/pull/49661) | Update dependencies | +| 0.4.4 | 2024-12-12 | [48253](https://github.com/airbytehq/airbyte/pull/48253) | Update dependencies | | 0.4.3 | 2024-10-29 | [47920](https://github.com/airbytehq/airbyte/pull/47920) | Update dependencies | | 0.4.2 | 2024-10-28 | [47653](https://github.com/airbytehq/airbyte/pull/47653) | Update dependencies | | 0.4.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/oracle.md b/docs/integrations/sources/oracle.md index 5369c0c16f54..253c3a3b3a2f 100644 --- a/docs/integrations/sources/oracle.md +++ b/docs/integrations/sources/oracle.md @@ -135,13 +135,14 @@ Airbyte has the ability to connect to the Oracle source with 3 network connectiv | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- | -| 0.5.2 | 2024-02-13 | [35225](https://github.com/airbytehq/airbyte/pull/35225) | Adopt CDK 0.20.4 | -| 0.5.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | -| 0.5.0 | 2023-12-18 | [33485](https://github.com/airbytehq/airbyte/pull/33485) | Remove LEGACY state | -| 0.4.0 | 2023-06-26 | [27737](https://github.com/airbytehq/airbyte/pull/27737) | License Update: Elv2 | -| 0.3.25 | 2023-06-20 | [27212](https://github.com/airbytehq/airbyte/pull/27212) | Fix silent exception swallowing in StreamingJdbcDatabase | -| 0.3.24 | 2023-03-22 | [20760](https://github.com/airbytehq/airbyte/pull/20760) | Removed redundant date-time datatypes formatting | -| 0.3.23 | 2023-03-06 | [23455](https://github.com/airbytehq/airbyte/pull/23455) | For network isolation, source connector accepts a list of hosts it is allowed to connect to | +| 0.5.3 | 2024-12-18 | [49883](https://github.com/airbytehq/airbyte/pull/49883) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.5.2 | 2024-02-13 | [35225](https://github.com/airbytehq/airbyte/pull/35225) | Adopt CDK 0.20.4 | +| 0.5.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | +| 0.5.0 | 2023-12-18 | [33485](https://github.com/airbytehq/airbyte/pull/33485) | Remove LEGACY state | +| 0.4.0 | 2023-06-26 | [27737](https://github.com/airbytehq/airbyte/pull/27737) | License Update: Elv2 | +| 0.3.25 | 2023-06-20 | [27212](https://github.com/airbytehq/airbyte/pull/27212) | Fix silent exception swallowing in StreamingJdbcDatabase | +| 0.3.24 | 2023-03-22 | [20760](https://github.com/airbytehq/airbyte/pull/20760) | Removed redundant date-time datatypes formatting | +| 0.3.23 | 2023-03-06 | [23455](https://github.com/airbytehq/airbyte/pull/23455) | For network isolation, source connector accepts a list of hosts it is allowed to connect to | | 0.3.22 | 2022-12-14 | [20436](https://github.com/airbytehq/airbyte/pull/20346) | Consolidate date/time values mapping for JDBC sources | | | 2022-10-13 | [15535](https://github.com/airbytehq/airbyte/pull/16238) | Update incremental query to avoid data missing when new data is inserted at the same time as a sync starts under non-CDC incremental mode | | 0.3.21 | 2022-09-01 | [16238](https://github.com/airbytehq/airbyte/pull/16238) | Emit state messages more frequently | @@ -165,4 +166,4 @@ Airbyte has the ability to connect to the Oracle source with 3 network connectiv | 0.3.3 | 2021-09-01 | [5779](https://github.com/airbytehq/airbyte/pull/5779) | Ability to only discover certain schemas. | | 0.3.2 | 2021-08-13 | [4699](https://github.com/airbytehq/airbyte/pull/4699) | Added json config validator. | - \ No newline at end of file + diff --git a/docs/integrations/sources/orb.md b/docs/integrations/sources/orb.md index 8f957b1a62e9..b09fdb166df6 100644 --- a/docs/integrations/sources/orb.md +++ b/docs/integrations/sources/orb.md @@ -65,6 +65,11 @@ an Orb Account and API Key. | Version | Date | Pull Request | Subject | |---------|------------| -------------------------------------------------------- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 2.1.4 | 2024-12-28 | [50741](https://github.com/airbytehq/airbyte/pull/50741) | Update dependencies | +| 2.1.3 | 2024-12-21 | [50228](https://github.com/airbytehq/airbyte/pull/50228) | Update dependencies | +| 2.1.2 | 2024-12-14 | [49693](https://github.com/airbytehq/airbyte/pull/49693) | Update dependencies | +| 2.1.1 | 2024-12-12 | [48296](https://github.com/airbytehq/airbyte/pull/48296) | Update dependencies | +| 2.1.0 | 2024-10-23 | [47288](https://github.com/airbytehq/airbyte/pull/47288) | Migrate to manifest only format | | 2.0.14 | 2024-10-29 | [46770](https://github.com/airbytehq/airbyte/pull/46770) | Update dependencies | | 2.0.13 | 2024-10-05 | [46395](https://github.com/airbytehq/airbyte/pull/46395) | Update dependencies | | 2.0.12 | 2024-09-28 | [45785](https://github.com/airbytehq/airbyte/pull/45785) | Update dependencies | diff --git a/docs/integrations/sources/oura.md b/docs/integrations/sources/oura.md index f7e80d137554..a2af79c2cabe 100644 --- a/docs/integrations/sources/oura.md +++ b/docs/integrations/sources/oura.md @@ -56,6 +56,12 @@ The following fields are required fields for the connector to work: | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:--------------------------------------------| +| 0.2.8 | 2024-12-28 | [50736](https://github.com/airbytehq/airbyte/pull/50736) | Update dependencies | +| 0.2.7 | 2024-12-21 | [50226](https://github.com/airbytehq/airbyte/pull/50226) | Update dependencies | +| 0.2.6 | 2024-12-14 | [49658](https://github.com/airbytehq/airbyte/pull/49658) | Update dependencies | +| 0.2.5 | 2024-12-12 | [49319](https://github.com/airbytehq/airbyte/pull/49319) | Update dependencies | +| 0.2.4 | 2024-12-11 | [49050](https://github.com/airbytehq/airbyte/pull/49050) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.3 | 2024-11-04 | [48189](https://github.com/airbytehq/airbyte/pull/48189) | Update dependencies | | 0.2.2 | 2024-10-29 | [47800](https://github.com/airbytehq/airbyte/pull/47800) | Update dependencies | | 0.2.1 | 2024-10-28 | [47576](https://github.com/airbytehq/airbyte/pull/47576) | Update dependencies | | 0.2.0 | 2024-08-19 | [44409](https://github.com/airbytehq/airbyte/pull/44409) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/outbrain-amplify.md b/docs/integrations/sources/outbrain-amplify.md index d20d94ebbb3f..4d22094edf2f 100644 --- a/docs/integrations/sources/outbrain-amplify.md +++ b/docs/integrations/sources/outbrain-amplify.md @@ -65,6 +65,11 @@ Specify credentials and a start date. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :--------------------------------- | +| 0.1.25 | 2024-12-28 | [50746](https://github.com/airbytehq/airbyte/pull/50746) | Update dependencies | +| 0.1.24 | 2024-12-21 | [50236](https://github.com/airbytehq/airbyte/pull/50236) | Update dependencies | +| 0.1.23 | 2024-12-14 | [49715](https://github.com/airbytehq/airbyte/pull/49715) | Update dependencies | +| 0.1.22 | 2024-12-12 | [49065](https://github.com/airbytehq/airbyte/pull/49065) | Update dependencies | +| 0.1.21 | 2024-11-25 | [48634](https://github.com/airbytehq/airbyte/pull/48634) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.1.20 | 2024-10-29 | [47849](https://github.com/airbytehq/airbyte/pull/47849) | Update dependencies | | 0.1.19 | 2024-10-28 | [47040](https://github.com/airbytehq/airbyte/pull/47040) | Update dependencies | | 0.1.18 | 2024-10-12 | [46775](https://github.com/airbytehq/airbyte/pull/46775) | Update dependencies | diff --git a/docs/integrations/sources/outreach.md b/docs/integrations/sources/outreach.md index 6998848f93dc..70ec95fe7a50 100644 --- a/docs/integrations/sources/outreach.md +++ b/docs/integrations/sources/outreach.md @@ -56,6 +56,11 @@ List of available streams: | Version | Date | Pull Request | Subject | | :------ |:-----------| :----- | :------ | +| 1.0.27 | 2025-01-04 | [50931](https://github.com/airbytehq/airbyte/pull/50931) | Update dependencies | +| 1.0.26 | 2024-12-28 | [50722](https://github.com/airbytehq/airbyte/pull/50722) | Update dependencies | +| 1.0.25 | 2024-12-21 | [50245](https://github.com/airbytehq/airbyte/pull/50245) | Update dependencies | +| 1.0.24 | 2024-12-14 | [49654](https://github.com/airbytehq/airbyte/pull/49654) | Update dependencies | +| 1.0.23 | 2024-12-12 | [49049](https://github.com/airbytehq/airbyte/pull/49049) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 1.0.22 | 2024-10-28 | [47055](https://github.com/airbytehq/airbyte/pull/47055) | Update dependencies | | 1.0.21 | 2024-10-12 | [46764](https://github.com/airbytehq/airbyte/pull/46764) | Update dependencies | | 1.0.20 | 2024-10-05 | [46405](https://github.com/airbytehq/airbyte/pull/46405) | Update dependencies | diff --git a/docs/integrations/sources/oveit.md b/docs/integrations/sources/oveit.md new file mode 100644 index 000000000000..29609c6046d6 --- /dev/null +++ b/docs/integrations/sources/oveit.md @@ -0,0 +1,32 @@ +# Oveit +An Airbyte connector for Oveit enables seamless data synchronization by extracting and integrating data from Oveit’s event management platform into your data warehouse. This connector helps automate the flow of information, providing up-to-date insights on event registrations, ticketing, and attendee information. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `email` | `string` | Email. Oveit's login Email | | +| `password` | `string` | Password. Oveit's login Password | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| events | id | No pagination | ✅ | ❌ | +| attendees | id | DefaultPaginator | ✅ | ❌ | +| tickets | code | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50715](https://github.com/airbytehq/airbyte/pull/50715) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50275](https://github.com/airbytehq/airbyte/pull/50275) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49695](https://github.com/airbytehq/airbyte/pull/49695) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49328](https://github.com/airbytehq/airbyte/pull/49328) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49057](https://github.com/airbytehq/airbyte/pull/49057) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-24 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/pabbly-subscriptions-billing.md b/docs/integrations/sources/pabbly-subscriptions-billing.md new file mode 100644 index 000000000000..8a73ca5cdd63 --- /dev/null +++ b/docs/integrations/sources/pabbly-subscriptions-billing.md @@ -0,0 +1,42 @@ +# Pabbly Subscriptions Billing +Airbyte connector for [Pabbly Subscriptions Billing](https://www.pabbly.com/subscriptions/) enables seamless data synchronization between Pabbly's subscription management platform and your preferred data warehouse or analytics environment. With this connector, users can automate the extraction of key subscription data—such as customer details, payment transactions, and subscription statuses—allowing for efficient reporting, analysis, and decision-making without manual intervention + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `password` | `string` | Password. | | +| `username` | `string` | Username. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| customers | id | DefaultPaginator | ✅ | ❌ | +| subscriptions | id | DefaultPaginator | ✅ | ❌ | +| products | id | DefaultPaginator | ✅ | ❌ | +| coupons | id | DefaultPaginator | ✅ | ❌ | +| invoices | id | DefaultPaginator | ✅ | ❌ | +| payment_methods | id | DefaultPaginator | ✅ | ❌ | +| transactions | id | DefaultPaginator | ✅ | ❌ | +| refunds | id | DefaultPaginator | ✅ | ❌ | +| addons | id | DefaultPaginator | ✅ | ❌ | +| addon_list_category | id | DefaultPaginator | ✅ | ❌ | +| licenses | id | DefaultPaginator | ✅ | ❌ | +| multiplans | id | DefaultPaginator | ✅ | ❌ | +| payment_gateways | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50725](https://github.com/airbytehq/airbyte/pull/50725) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50249](https://github.com/airbytehq/airbyte/pull/50249) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49681](https://github.com/airbytehq/airbyte/pull/49681) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49320](https://github.com/airbytehq/airbyte/pull/49320) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49056](https://github.com/airbytehq/airbyte/pull/49056) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-08 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/pandadoc.md b/docs/integrations/sources/pandadoc.md index 942265df6488..3976c57c03e9 100644 --- a/docs/integrations/sources/pandadoc.md +++ b/docs/integrations/sources/pandadoc.md @@ -33,6 +33,12 @@ Airbyte connector for PandaDoc allows users to extract data from PandaDoc and in | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.8 | 2024-12-28 | [50681](https://github.com/airbytehq/airbyte/pull/50681) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50268](https://github.com/airbytehq/airbyte/pull/50268) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49702](https://github.com/airbytehq/airbyte/pull/49702) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49354](https://github.com/airbytehq/airbyte/pull/49354) | Update dependencies | +| 0.0.4 | 2024-12-11 | [49064](https://github.com/airbytehq/airbyte/pull/49064) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.3 | 2024-11-04 | [48210](https://github.com/airbytehq/airbyte/pull/48210) | Update dependencies | | 0.0.2 | 2024-10-29 | [47911](https://github.com/airbytehq/airbyte/pull/47911) | Update dependencies | | 0.0.1 | 2024-10-21 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | diff --git a/docs/integrations/sources/paperform.md b/docs/integrations/sources/paperform.md new file mode 100644 index 000000000000..c8490d8d3732 --- /dev/null +++ b/docs/integrations/sources/paperform.md @@ -0,0 +1,33 @@ +# Paperform +Airbyte connector for [Paperform](https://paperform.co/) enables seamless data integration between Paperform and other platforms, allowing automated data synchronization and transfer from Paperform form submissions to your data warehouse or analytics tools. This connector helps streamline workflows by enabling data extraction, transformation, and loading (ETL) to leverage form data for insights and reporting across systems. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use. Generate it on your account page at https://paperform.co/account/developer. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| forms | id | DefaultPaginator | ✅ | ❌ | +| form_fields | key | DefaultPaginator | ✅ | ❌ | +| submissions | id | DefaultPaginator | ✅ | ❌ | +| partial_submissions | id | DefaultPaginator | ✅ | ❌ | +| coupons | code | DefaultPaginator | ✅ | ❌ | +| products | | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50240](https://github.com/airbytehq/airbyte/pull/50240) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49698](https://github.com/airbytehq/airbyte/pull/49698) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49370](https://github.com/airbytehq/airbyte/pull/49370) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49075](https://github.com/airbytehq/airbyte/pull/49075) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-31 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/papersign.md b/docs/integrations/sources/papersign.md new file mode 100644 index 000000000000..b7284f642a25 --- /dev/null +++ b/docs/integrations/sources/papersign.md @@ -0,0 +1,32 @@ +# Papersign +The Airbyte connector for [Papersign](https://paperform.co/products/papersign/) enables seamless integration between Airbyte and Papersign, allowing automated data syncs between your Papersign documents and other platforms. This connector facilitates the extraction, transformation, and loading of e-signature data, document statuses, and user interactions, streamlining workflows and ensuring your e-signature data is easily accessible across systems. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use. Generate it on your account page at https://paperform.co/account/developer. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| documents | id | DefaultPaginator | ✅ | ❌ | +| folders | id | No pagination | ✅ | ❌ | +| spaces | id | No pagination | ✅ | ❌ | +| webhooks | id | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50691](https://github.com/airbytehq/airbyte/pull/50691) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50272](https://github.com/airbytehq/airbyte/pull/50272) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49696](https://github.com/airbytehq/airbyte/pull/49696) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49361](https://github.com/airbytehq/airbyte/pull/49361) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49105](https://github.com/airbytehq/airbyte/pull/49105) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-08 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/pardot-migrations.md b/docs/integrations/sources/pardot-migrations.md new file mode 100644 index 000000000000..a6dfcef4abaa --- /dev/null +++ b/docs/integrations/sources/pardot-migrations.md @@ -0,0 +1,14 @@ +# Pardot Migration Guide + +## Upgrading to 1.0.0 + +Version 1.0.0 contains a number of fixes and updates to the Pardot source connector: + +- Fixed authentication +- Migrate all existing streams to Pardot v5 API (except email_clicks which is only available in v4) +- Re-implement incremental syncs for existing streams where possible +- Add 23 new streams from the v5 API (folders, emails, engagement_studio_programs, folder_contents, forms, form_fields, form_handlers, form_handler_fields, landing_pages, layout_templates, lifecycle_stages, lifecycle_histories, list_emails, opportunities, tags, tracker_domains, visitor_page_views) +- Add additional configuration options to better handle large accounts (e.g. adjustable split-up windows, page size) +- Align to Pardot-recommended sort/filter/pagination conventions to avoid timeouts (based on Pardot support case #469072278) + +The previous implementation of the authentication flow was no longer functional, preventing the instantiation of new sources. All users with existing connections should reconfigure the source and go through the authentication flow before attempting to sync with this connector. OSS users should be sure to manually update their source version to >=1.0.0 before attempting to configure this source. diff --git a/docs/integrations/sources/pardot.md b/docs/integrations/sources/pardot.md index f9907d617348..5c90ca581663 100644 --- a/docs/integrations/sources/pardot.md +++ b/docs/integrations/sources/pardot.md @@ -1,66 +1,101 @@ -# Pardot +# Pardot (Salesforce Marketing Cloud Account Engagement) ## Overview -The Airbyte Source for [Salesforce Pardot](https://www.pardot.com/) +This page contains the setup guide and reference information for the [Pardot (Salesforce Marketing Cloud Account Engagement)](https://www.salesforce.com/marketing/b2b-automation/) source connector. -The Pardot supports full refresh syncs +## Prerequisites -### Output schema +- Pardot/Marketing Cloud Account Engagement account +- Pardot Business Unit ID +- Client ID +- Client Secret +- Refresh Token -Several output streams are available from this source: +## Setup Guide -- [Campaigns](https://developer.salesforce.com/docs/marketing/pardot/guide/campaigns-v4.html) -- [EmailClicks](https://developer.salesforce.com/docs/marketing/pardot/guide/batch-email-clicks-v4.html) -- [ListMembership](https://developer.salesforce.com/docs/marketing/pardot/guide/list-memberships-v4.html) -- [Lists](https://developer.salesforce.com/docs/marketing/pardot/guide/lists-v4.html) -- [ProspectAccounts](https://developer.salesforce.com/docs/marketing/pardot/guide/prospect-accounts-v4.html) -- [Prospects](https://developer.salesforce.com/docs/marketing/pardot/guide/prospects-v4.html) -- [Users](https://developer.salesforce.com/docs/marketing/pardot/guide/users-v4.html) -- [VisitorActivities](https://developer.salesforce.com/docs/marketing/pardot/guide/visitor-activities-v4.html) -- [Visitors](https://developer.salesforce.com/docs/marketing/pardot/guide/visitors-v4.html) -- [Visits](https://developer.salesforce.com/docs/marketing/pardot/guide/visits-v4.html) +### Required configuration options +- **Pardot Business Unit ID** (`pardot_business_unit_id`): This value uniquely identifies your account, and can be found at Setup > Pardot > Pardot Account Setup -If there are more endpoints you'd like Airbyte to support, please [create an issue.](https://github.com/airbytehq/airbyte/issues/new/choose) +- **Client ID** (`client_id`): The Consumer Key that can be found when viewing your app in Salesforce -### Features +- **Client Secret** (`client_secret`): The Consumer Secret that can be found when viewing your app in Salesforce -| Feature | Supported? | -| :---------------- | :--------- | -| Full Refresh Sync | Yes | -| Incremental Sync | No | -| SSL connection | No | -| Namespaces | No | +- **Refresh Token** (`refresh_token`): Salesforce Refresh Token used for Airbyte to access your Salesforce account. If you don't know what this is, follow [this guide](https://medium.com/@bpmmendis94/obtain-access-refresh-tokens-from-salesforce-rest-api-a324fe4ccd9b) to retrieve it. -### Performance considerations +### Optional configuration options +- **Start Date** (`start_date`): UTC date and time in the format `2020-01-25T00:00:00Z`. Any data before this date will not be replicated. Defaults to `2007-01-01T00:00:00Z` (the year Pardot was launched) -The Pardot connector should not run into Pardot API limitations under normal usage. Please [create an issue](https://github.com/airbytehq/airbyte/issues) if you see any rate limit issues that are not automatically retried successfully. +- **Page Size Limit** (`page_size`): The default page size to return; defaults to `1000` (which is Pardot's maximum). Does not apply to the Email Clicks stream which uses the v4 API and is limited to 200 per page. -## Getting started +- **Default Split Up Interval** (`split_up_interval`): The default split up interval is used on incremental streams to prevent hitting Pardots limit of 100 pages per result (effectively 100K records on most endpoints). The default is `P3M`, which will break incremental requests into three-month groupings. If you expect more than 100K records to be modified between syncs in a single endpoint, you can increase the granularity to `P1M`, `P14D`, `P7D`, `P3D`, or `P1D` to reduce the maximum records to be paged through per split. For small accounts unlikely to hit the limit, decreasing the granularity to `P6M` or `P1Y` may increase the speed of those syncs, especially the initial backfill. -### Requirements +- **Is Sandbox App?** (`is_sandbox`): Whether or not the app is in a Salesforce sandbox. If you do not know what this is, assume it is false. -- Pardot Account -- Pardot Business Unit ID -- Client ID -- Client Secret -- Refresh Token -- Start Date -- Is Sandbox environment? +## Supported Sync Modes + +The Pardot source connector supports the following [sync modes](https://docs.airbyte.com/cloud/core-concepts/#connection-sync-modes): + +- Full Refresh +- Incremental -### Setup guide +Incremental streams are based on the Pardot API's `UpdatedAt` field when the object is updateable and the API supports it; otherwise `CreatedAt` or `Id` are used in that order of preference. + +### Performance Considerations + +The Pardot connector should not run into Pardot API limitations under normal usage. Please [create an issue](https://github.com/airbytehq/airbyte/issues) if you see any rate limit issues that are not automatically retried successfully. -- `pardot_business_unit_id`: Pardot Business ID, can be found at Setup > Pardot > Pardot Account Setup -- `client_id`: The Consumer Key that can be found when viewing your app in Salesforce -- `client_secret`: The Consumer Secret that can be found when viewing your app in Salesforce -- `refresh_token`: Salesforce Refresh Token used for Airbyte to access your Salesforce account. If you don't know what this is, follow [this guide](https://medium.com/@bpmmendis94/obtain-access-refresh-tokens-from-salesforce-rest-api-a324fe4ccd9b) to retrieve it. -- `start_date`: UTC date and time in the format 2017-01-25T00:00:00Z. Any data before this date will not be replicated. Leave blank to skip this filter -- `is_sandbox`: Whether or not the app is in a Salesforce sandbox. If you do not know what this is, assume it is false. +:::tip + +Due to timeouts on large accounts, the Split Up Interval (the time period used to page through incrementally) is surfaced as a configuration option. While the default should work for most accounts, large accounts may need to increase the granularity from the default. Similarly, small accounts may see faster initial syncs with a longer interval. See the Optional Configuration Options section for more details. + +::: + +## Supported Streams + +Several output streams are available from this source. Unless noted otherwise, streams are from Pardot's v5 API: + +- [Account (Metadata)](https://developer.salesforce.com/docs/marketing/pardot/guide/account-v5.html) (full refresh) +- [Campaigns](https://developer.salesforce.com/docs/marketing/pardot/guide/campaign-v5.html) (incremental) +- [Custom Fields](https://developer.salesforce.com/docs/marketing/pardot/guide/custom-field-v5.html) (incremental) +- [Custom Redirects](https://developer.salesforce.com/docs/marketing/pardot/guide/custom-redirect-v5.html) (full refresh) +- [Dynamic Content](https://developer.salesforce.com/docs/marketing/pardot/guide/dynamic-content-v5.html) (incremental) +- [Dynamic Content Variations](https://developer.salesforce.com/docs/marketing/pardot/guide/dynamic-content-variation.html) (incremental parent) +- [Emails](https://developer.salesforce.com/docs/marketing/pardot/guide/email-v5.html) (incremental) +- [Email Clicks (v4 API)](https://developer.salesforce.com/docs/marketing/pardot/guide/batch-email-clicks-v4.html) (incremental) +- [Engagement Studio Programs](https://developer.salesforce.com/docs/marketing/pardot/guide/engagement-studio-program-v5.html) (incremental) +- [Files](https://developer.salesforce.com/docs/marketing/pardot/guide/export-v5.html) (full refresh) +- [Folders](https://developer.salesforce.com/docs/marketing/pardot/guide/folder-v5.html) (full refresh) +- [Folder Contents](https://developer.salesforce.com/docs/marketing/pardot/guide/folder-contents-v5.html) (incremental) +- [Forms](https://developer.salesforce.com/docs/marketing/pardot/guide/form-v5.html) (full refresh) +- [Form Fields](https://developer.salesforce.com/docs/marketing/pardot/guide/form-field-v5.html) (incremental) +- [Form Handlers](https://developer.salesforce.com/docs/marketing/pardot/guide/form-handler-v5.html) (full refresh) +- [Form Handler Fields](https://developer.salesforce.com/docs/marketing/pardot/guide/form-handler-field-v5.html) (full refresh) +- [Landing Pages](https://developer.salesforce.com/docs/marketing/pardot/guide/landing-page-v5.html) (incremental) +- [Layout Templates](https://developer.salesforce.com/docs/marketing/pardot/guide/layout-template-v5.html) (full refresh) +- [Lifecycle Stages](https://developer.salesforce.com/docs/marketing/pardot/guide/lifecycle-stage-v5.html) (incremental) +- [Lifecycle Histories](https://developer.salesforce.com/docs/marketing/pardot/guide/lifecycle-history-v5.html) (incremental) +- [Lists](https://developer.salesforce.com/docs/marketing/pardot/guide/list-v5.html) (incremental) +- [List Emails](https://developer.salesforce.com/docs/marketing/pardot/guide/list-email-v5.html) (incremental) +- [List Memberships](https://developer.salesforce.com/docs/marketing/pardot/guide/list-membership-v5.html) (incremental) +- [Opportunities](https://developer.salesforce.com/docs/marketing/pardot/guide/opportunity-v5.html) (incremental) +- [Prospects](https://developer.salesforce.com/docs/marketing/pardot/guide/prospect-v5.html) (incremental) +- [Prospect Accounts](https://developer.salesforce.com/docs/marketing/pardot/guide/prospect-account-v5.html) (full refresh) +- [Tags](https://developer.salesforce.com/docs/marketing/pardot/guide/tag-v5.html) (incremental) +- [Tracker Domains](https://developer.salesforce.com/docs/marketing/pardot/guide/tracker-domain-v5.html) (full refresh) +- [Users](https://developer.salesforce.com/docs/marketing/pardot/guide/user-v5.html) (incremental) +- [Visitors](https://developer.salesforce.com/docs/marketing/pardot/guide/visitor-v5.html) (incremental) +- [Visitor Activity](https://developer.salesforce.com/docs/marketing/pardot/guide/visitor-activity-v5.html) (incremental) +- [Visitor Page Views](https://developer.salesforce.com/docs/marketing/pardot/guide/visitor-page-view-v5.html) (incremental) +- [Visits](https://developer.salesforce.com/docs/marketing/pardot/guide/visit-v5.html) (incremental) + +If there are more endpoints you'd like Airbyte to support, please [create an issue](https://github.com/airbytehq/airbyte/issues/new/choose). ## Changelog | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :-------------------- | +| 1.0.0 | 2023-12-12 | [49424](https://github.com/airbytehq/airbyte/pull/49424) | Update streams to API V5. Fix auth flow | | 0.2.0 | 2024-10-13 | [44528](https://github.com/airbytehq/airbyte/pull/44528) | Migrate to LowCode then Manifest-only | | 0.1.22 | 2024-10-12 | [46778](https://github.com/airbytehq/airbyte/pull/46778) | Update dependencies | | 0.1.21 | 2024-10-05 | [46441](https://github.com/airbytehq/airbyte/pull/46441) | Update dependencies | diff --git a/docs/integrations/sources/partnerstack.md b/docs/integrations/sources/partnerstack.md index f4435992a92e..0484c7916fa8 100644 --- a/docs/integrations/sources/partnerstack.md +++ b/docs/integrations/sources/partnerstack.md @@ -2,8 +2,6 @@ ## Sync overview -The Partnerstack source supports both Full Refresh only. - This source can sync data for the [Partnerstack API](https://docs.partnerstack.com/reference). ### Output schema @@ -23,7 +21,7 @@ This Source is capable of syncing the following core Streams: | Feature | Supported?\(Yes/No\) | Notes | | :------------------------ | :------------------- | :---- | | Full Refresh Sync | Yes | | -| Incremental - Append Sync | No | | +| Incremental - Append Sync | Yes | | | Namespaces | No | | ### Performance considerations @@ -41,6 +39,13 @@ The Partnerstack connector should not run into Partnerstack API limitations unde | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:--------------------------------------------| +| 0.2.5 | 2025-01-04 | [50934](https://github.com/airbytehq/airbyte/pull/50934) | Update dependencies | +| 0.2.4 | 2024-12-28 | [50723](https://github.com/airbytehq/airbyte/pull/50723) | Update dependencies | +| 0.2.3 | 2024-12-21 | [50246](https://github.com/airbytehq/airbyte/pull/50246) | Update dependencies | +| 0.2.2 | 2024-12-14 | [49675](https://github.com/airbytehq/airbyte/pull/49675) | Update dependencies | +| 0.2.1 | 2024-12-11 | [49085](https://github.com/airbytehq/airbyte/pull/49085) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.0 | 2024-12-03 | [48782](https://github.com/airbytehq/airbyte/pull/48782) | Add Incremental feature | +| 0.1.25 | 2024-11-04 | [48184](https://github.com/airbytehq/airbyte/pull/48184) | Update dependencies | | 0.1.24 | 2024-10-29 | [47762](https://github.com/airbytehq/airbyte/pull/47762) | Update dependencies | | 0.1.23 | 2024-10-28 | [47045](https://github.com/airbytehq/airbyte/pull/47045) | Update dependencies | | 0.1.22 | 2024-10-12 | [46808](https://github.com/airbytehq/airbyte/pull/46808) | Update dependencies | diff --git a/docs/integrations/sources/pendo.md b/docs/integrations/sources/pendo.md index f91ee814c4fd..2c140fb300a5 100644 --- a/docs/integrations/sources/pendo.md +++ b/docs/integrations/sources/pendo.md @@ -64,6 +64,8 @@ The Pendo source connector supports the following [sync modes](https://docs.airb | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.2.5 | 2025-01-04 | [50244](https://github.com/airbytehq/airbyte/pull/50244) | Update dependencies | +| 0.2.4 | 2024-12-14 | [48313](https://github.com/airbytehq/airbyte/pull/48313) | Update dependencies | | 0.2.3 | 2024-10-29 | [47847](https://github.com/airbytehq/airbyte/pull/47847) | Update dependencies | | 0.2.2 | 2024-10-28 | [47563](https://github.com/airbytehq/airbyte/pull/47563) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/pennylane.md b/docs/integrations/sources/pennylane.md index 12aac8154815..2d3c39abbbbe 100644 --- a/docs/integrations/sources/pennylane.md +++ b/docs/integrations/sources/pennylane.md @@ -27,6 +27,12 @@ | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.1.1 | 2024-12-21 | [50294](https://github.com/airbytehq/airbyte/pull/50294) | Update dependencies | +| 0.1.0 | 2024-12-10 | [48892](https://github.com/airbytehq/airbyte/pull/48892) | Add missing fields to `customer_invoices` stream | +| 0.0.6 | 2024-12-14 | [49659](https://github.com/airbytehq/airbyte/pull/49659) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49322](https://github.com/airbytehq/airbyte/pull/49322) | Update dependencies | +| 0.0.4 | 2024-12-11 | [49053](https://github.com/airbytehq/airbyte/pull/49053) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.3 | 2024-11-04 | [47902](https://github.com/airbytehq/airbyte/pull/47902) | Update dependencies | | 0.0.2 | 2024-10-28 | [47536](https://github.com/airbytehq/airbyte/pull/47536) | Update dependencies | | 0.0.1 | 2024-08-21 | | Initial release by natikgadzhi via Connector Builder | diff --git a/docs/integrations/sources/persistiq.md b/docs/integrations/sources/persistiq.md index 9799b9ef5144..0e0b36677c60 100644 --- a/docs/integrations/sources/persistiq.md +++ b/docs/integrations/sources/persistiq.md @@ -43,6 +43,10 @@ Please read [How to find your API key](https://apidocs.persistiq.com/#introducti | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:---------------------------------------| +| 0.3.8 | 2024-12-28 | [50729](https://github.com/airbytehq/airbyte/pull/50729) | Update dependencies | +| 0.3.7 | 2024-12-21 | [50247](https://github.com/airbytehq/airbyte/pull/50247) | Update dependencies | +| 0.3.6 | 2024-12-14 | [49676](https://github.com/airbytehq/airbyte/pull/49676) | Update dependencies | +| 0.3.5 | 2024-12-12 | [48266](https://github.com/airbytehq/airbyte/pull/48266) | Update dependencies | | 0.3.4 | 2024-10-29 | [47851](https://github.com/airbytehq/airbyte/pull/47851) | Update dependencies | | 0.3.3 | 2024-10-28 | [47579](https://github.com/airbytehq/airbyte/pull/47579) | Update dependencies | | 0.3.2 | 2024-10-21 | [47193](https://github.com/airbytehq/airbyte/pull/47193) | Update dependencies | diff --git a/docs/integrations/sources/persona.md b/docs/integrations/sources/persona.md index 1a0b7ce0f672..9e4fee86d14e 100644 --- a/docs/integrations/sources/persona.md +++ b/docs/integrations/sources/persona.md @@ -28,6 +28,11 @@ Airbyte connector for [Persona](https://withpersona.com) that makes it easy to m | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50696](https://github.com/airbytehq/airbyte/pull/50696) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50257](https://github.com/airbytehq/airbyte/pull/50257) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49663](https://github.com/airbytehq/airbyte/pull/49663) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49069](https://github.com/airbytehq/airbyte/pull/49069) | Update dependencies | +| 0.0.3 | 2024-11-04 | [48247](https://github.com/airbytehq/airbyte/pull/48247) | Update dependencies | | 0.0.2 | 2024-10-28 | [47498](https://github.com/airbytehq/airbyte/pull/47498) | Update dependencies | | 0.0.1 | 2024-10-03 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | diff --git a/docs/integrations/sources/pexels-api.md b/docs/integrations/sources/pexels-api.md index 6af21a470497..a1ff581131bf 100644 --- a/docs/integrations/sources/pexels-api.md +++ b/docs/integrations/sources/pexels-api.md @@ -76,7 +76,12 @@ Pexels-API's [API reference]https://www.pexels.com/api/documentation) has v1 at | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------ | :------------- | -| 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | +| 0.2.6 | 2024-12-28 | [50680](https://github.com/airbytehq/airbyte/pull/50680) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50274](https://github.com/airbytehq/airbyte/pull/50274) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49708](https://github.com/airbytehq/airbyte/pull/49708) | Update dependencies | +| 0.2.3 | 2024-12-12 | [49324](https://github.com/airbytehq/airbyte/pull/49324) | Update dependencies | +| 0.2.2 | 2024-12-11 | [47678](https://github.com/airbytehq/airbyte/pull/47678) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-15 | [44097](https://github.com/airbytehq/airbyte/pull/44097) | Refactor connector to manifest-only format | | 0.1.14 | 2024-08-12 | [43817](https://github.com/airbytehq/airbyte/pull/43817) | Update dependencies | | 0.1.13 | 2024-08-03 | [43057](https://github.com/airbytehq/airbyte/pull/43057) | Update dependencies | diff --git a/docs/integrations/sources/picqer.md b/docs/integrations/sources/picqer.md index 53a631825d28..d6138b4bcbcb 100644 --- a/docs/integrations/sources/picqer.md +++ b/docs/integrations/sources/picqer.md @@ -42,6 +42,12 @@ Configure the API key as your username and leave password field as blank | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.9 | 2024-12-28 | [50714](https://github.com/airbytehq/airbyte/pull/50714) | Update dependencies | +| 0.0.8 | 2024-12-21 | [50233](https://github.com/airbytehq/airbyte/pull/50233) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49711](https://github.com/airbytehq/airbyte/pull/49711) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49359](https://github.com/airbytehq/airbyte/pull/49359) | Update dependencies | +| 0.0.5 | 2024-12-11 | [49059](https://github.com/airbytehq/airbyte/pull/49059) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-11-04 | [48249](https://github.com/airbytehq/airbyte/pull/48249) | Update dependencies | | 0.0.3 | 2024-10-29 | [47876](https://github.com/airbytehq/airbyte/pull/47876) | Update dependencies | | 0.0.2 | 2024-10-22 | [47235](https://github.com/airbytehq/airbyte/pull/47235) | Update dependencies | | 0.0.1 | 2024-09-05 | [45159](https://github.com/airbytehq/airbyte/pull/45159) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/pingdom.md b/docs/integrations/sources/pingdom.md new file mode 100644 index 000000000000..38203ebc48a6 --- /dev/null +++ b/docs/integrations/sources/pingdom.md @@ -0,0 +1,38 @@ +# Pingdom +This Source is capable of syncing the following core Streams: + +- [checks](https://docs.pingdom.com/api/#tag/Checks/paths/~1checks/get) +- [performance](https://docs.pingdom.com/api/#tag/Summary.performance/paths/~1summary.performance~1{checkid}/get) + +## Requirements + +- **Pingdom API Key**.[required] See the [PingDom API docs](https://docs.pingdom.com/api/#section/Authentication) for information on how to obtain the API token. +- **Start date**.[required]. To Fetch data from. Only use for Incremental way. +- **Probes**[optional]. Filter to only use results from a list of probes. Format is a comma separated list of probe identifiers. +- **Resolution**[optional]. Interval Size. Should be `hour`, `day`, `week`. Default: `hour` + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `probes` | `string` | probes. | | +| `api_key` | `string` | API Key. | | +| `resolution` | `string` | resolution. | hour | +| `start_date` | `string` | Start date. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| checks | id | DefaultPaginator | ✅ | ❌ | +| performance | | No pagination | ✅ | ✅ | + +## Changelog + +
+ Expand to review + +| Version | Date | Subject | +|------------------|------------|----------------| +| 0.0.1 | 2024-12-03 | Initial release by [@KimPlv](https://github.com/KimPlv) via Connector Builder| + +
\ No newline at end of file diff --git a/docs/integrations/sources/pinterest.md b/docs/integrations/sources/pinterest.md index 0071ef4de9a3..8be373fe6d2a 100644 --- a/docs/integrations/sources/pinterest.md +++ b/docs/integrations/sources/pinterest.md @@ -203,6 +203,11 @@ The connector is restricted by the Pinterest | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 2.0.26 | 2025-01-04 | [50933](https://github.com/airbytehq/airbyte/pull/50933) | Update dependencies | +| 2.0.25 | 2024-12-28 | [50710](https://github.com/airbytehq/airbyte/pull/50710) | Update dependencies | +| 2.0.24 | 2024-12-21 | [50302](https://github.com/airbytehq/airbyte/pull/50302) | Update dependencies | +| 2.0.23 | 2024-12-14 | [49040](https://github.com/airbytehq/airbyte/pull/49040) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 2.0.22 | 2024-11-04 | [48280](https://github.com/airbytehq/airbyte/pull/48280) | Update dependencies | | 2.0.21 | 2024-10-29 | [47074](https://github.com/airbytehq/airbyte/pull/47074) | Update dependencies | | 2.0.20 | 2024-10-12 | [46815](https://github.com/airbytehq/airbyte/pull/46815) | Update dependencies | | 2.0.19 | 2024-10-05 | [46482](https://github.com/airbytehq/airbyte/pull/46482) | Update dependencies | diff --git a/docs/integrations/sources/pipedrive.md b/docs/integrations/sources/pipedrive.md index 6ff3d260e04b..98ae2e02e824 100644 --- a/docs/integrations/sources/pipedrive.md +++ b/docs/integrations/sources/pipedrive.md @@ -110,8 +110,14 @@ The Pipedrive connector will gracefully handle rate limits. For more information ## Changelog -| Version | Date | Pull Request | Subject | -| :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------- | +| Version | Date | Pull Request | Subject | +|:--------|:-----------|:---------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 2.3.2 | 2025-01-04 | [50929](https://github.com/airbytehq/airbyte/pull/50929) | Update dependencies | +| 2.3.1 | 2024-12-28 | [50288](https://github.com/airbytehq/airbyte/pull/50288) | Update dependencies | +| 2.3.0 | 2024-12-17 | [48615](https://github.com/airbytehq/airbyte/pull/48615) | Update airbyte-cdk to use concurrency | +| 2.2.28 | 2024-12-14 | [49692](https://github.com/airbytehq/airbyte/pull/49692) | Update dependencies | +| 2.2.27 | 2024-12-12 | [49041](https://github.com/airbytehq/airbyte/pull/49041) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 2.2.26 | 2024-11-04 | [48293](https://github.com/airbytehq/airbyte/pull/48293) | Update dependencies | | 2.2.25 | 2024-10-29 | [47743](https://github.com/airbytehq/airbyte/pull/47743) | Update dependencies | | 2.2.24 | 2024-10-28 | [47103](https://github.com/airbytehq/airbyte/pull/47103) | Update dependencies | | 2.2.23 | 2024-10-12 | [46822](https://github.com/airbytehq/airbyte/pull/46822) | Update dependencies | diff --git a/docs/integrations/sources/pipeliner.md b/docs/integrations/sources/pipeliner.md new file mode 100644 index 000000000000..2e960d5b0718 --- /dev/null +++ b/docs/integrations/sources/pipeliner.md @@ -0,0 +1,58 @@ +# Pipeliner + +Pipeliner is a CRM tool. +Using this connector we fetch data from various streams such as contacts, data, leads and quotes. +[API Docs](https://pipeliner.stoplight.io/docs/api-docs) + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `username` | `string` | Username. | | +| `password` | `string` | Password. | | +| `service` | `string` | Data Center. | | +| `spaceid` | `string` | Space ID. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| accounts | id | DefaultPaginator | ✅ | ❌ | +| activities | id | DefaultPaginator | ✅ | ❌ | +| clients | id | DefaultPaginator | ✅ | ❌ | +| contacts | id | DefaultPaginator | ✅ | ❌ | +| entities | id | DefaultPaginator | ✅ | ❌ | +| data | id | DefaultPaginator | ✅ | ❌ | +| cloud_objects | id | DefaultPaginator | ✅ | ❌ | +| fields | id | DefaultPaginator | ✅ | ❌ | +| forecasts | id | DefaultPaginator | ✅ | ❌ | +| form_views | id | DefaultPaginator | ✅ | ❌ | +| entity_scorings | id | DefaultPaginator | ✅ | ❌ | +| leads | id | DefaultPaginator | ✅ | ❌ | +| lead_oppties | id | DefaultPaginator | ✅ | ❌ | +| memos | id | DefaultPaginator | ✅ | ❌ | +| notes | id | DefaultPaginator | ✅ | ❌ | +| entity_fitnesses | id | DefaultPaginator | ✅ | ❌ | +| pipelines | id | DefaultPaginator | ✅ | ❌ | +| products | id | DefaultPaginator | ✅ | ❌ | +| oppty_product_relations | id | DefaultPaginator | ✅ | ❌ | +| profiles | id | DefaultPaginator | ✅ | ❌ | +| quotes | id | DefaultPaginator | ✅ | ❌ | +| reports | id | DefaultPaginator | ✅ | ❌ | +| steps | id | DefaultPaginator | ✅ | ❌ | +| tags | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50694](https://github.com/airbytehq/airbyte/pull/50694) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50276](https://github.com/airbytehq/airbyte/pull/50276) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49656](https://github.com/airbytehq/airbyte/pull/49656) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49321](https://github.com/airbytehq/airbyte/pull/49321) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49077](https://github.com/airbytehq/airbyte/pull/49077) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-09 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/pivotal-tracker.md b/docs/integrations/sources/pivotal-tracker.md index e0738f2b103f..56e1ba51ace7 100644 --- a/docs/integrations/sources/pivotal-tracker.md +++ b/docs/integrations/sources/pivotal-tracker.md @@ -56,6 +56,10 @@ Use this to pull data from Pivotal Tracker. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :-------------- | +| 0.3.6 | 2024-12-28 | [50737](https://github.com/airbytehq/airbyte/pull/50737) | Update dependencies | +| 0.3.5 | 2024-12-21 | [50277](https://github.com/airbytehq/airbyte/pull/50277) | Update dependencies | +| 0.3.4 | 2024-12-14 | [49730](https://github.com/airbytehq/airbyte/pull/49730) | Update dependencies | +| 0.3.3 | 2024-12-12 | [49047](https://github.com/airbytehq/airbyte/pull/49047) | Update dependencies | | 0.3.2 | 2024-10-29 | [47679](https://github.com/airbytehq/airbyte/pull/47679) | Update dependencies | | 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.3.0 | 2024-08-14 | [44087](https://github.com/airbytehq/airbyte/pull/44087) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/piwik.md b/docs/integrations/sources/piwik.md index dbf73781232e..377ba3d12d47 100644 --- a/docs/integrations/sources/piwik.md +++ b/docs/integrations/sources/piwik.md @@ -41,6 +41,12 @@ Visit `https://developers.piwik.pro/en/latest/platform/getting_started.html#gene | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.9 | 2024-12-28 | [50744](https://github.com/airbytehq/airbyte/pull/50744) | Update dependencies | +| 0.0.8 | 2024-12-21 | [50253](https://github.com/airbytehq/airbyte/pull/50253) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49728](https://github.com/airbytehq/airbyte/pull/49728) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49356](https://github.com/airbytehq/airbyte/pull/49356) | Update dependencies | +| 0.0.5 | 2024-12-11 | [49103](https://github.com/airbytehq/airbyte/pull/49103) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-11-04 | [48305](https://github.com/airbytehq/airbyte/pull/48305) | Update dependencies | | 0.0.3 | 2024-10-29 | [47931](https://github.com/airbytehq/airbyte/pull/47931) | Update dependencies | | 0.0.2 | 2024-10-28 | [47569](https://github.com/airbytehq/airbyte/pull/47569) | Update dependencies | | 0.0.1 | 2024-09-14 | [45586](https://github.com/airbytehq/airbyte/pull/45586) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/planhat.md b/docs/integrations/sources/planhat.md index 230586382953..e2348a066d7d 100644 --- a/docs/integrations/sources/planhat.md +++ b/docs/integrations/sources/planhat.md @@ -54,6 +54,12 @@ This Source is capable of syncing the following core Streams: | Version | Date | Pull Request | Subject | | ------- | ---------- | ------------ | ---------------------------------------------------- | +| 0.0.10 | 2024-12-28 | [50675](https://github.com/airbytehq/airbyte/pull/50675) | Update dependencies | +| 0.0.9 | 2024-12-21 | [50270](https://github.com/airbytehq/airbyte/pull/50270) | Update dependencies | +| 0.0.8 | 2024-12-14 | [49672](https://github.com/airbytehq/airbyte/pull/49672) | Update dependencies | +| 0.0.7 | 2024-12-12 | [49347](https://github.com/airbytehq/airbyte/pull/49347) | Update dependencies | +| 0.0.6 | 2024-12-11 | [49102](https://github.com/airbytehq/airbyte/pull/49102) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.5 | 2024-11-04 | [48157](https://github.com/airbytehq/airbyte/pull/48157) | Update dependencies | | 0.0.4 | 2024-10-29 | [47778](https://github.com/airbytehq/airbyte/pull/47778) | Update dependencies | | 0.0.3 | 2024-10-28 | [47625](https://github.com/airbytehq/airbyte/pull/47625) | Update dependencies | | 0.0.2 | 2024-09-30 | [46271](https://github.com/airbytehq/airbyte/pull/46271) | Documentation update | diff --git a/docs/integrations/sources/pocket.md b/docs/integrations/sources/pocket.md index 641155b841b8..c344d9a8fc99 100644 --- a/docs/integrations/sources/pocket.md +++ b/docs/integrations/sources/pocket.md @@ -57,6 +57,10 @@ curl --insecure -X POST -H 'Content-Type: application/json' -H 'X-Accept: applic | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.2.5 | 2024-12-28 | [50740](https://github.com/airbytehq/airbyte/pull/50740) | Update dependencies | +| 0.2.4 | 2024-12-21 | [50282](https://github.com/airbytehq/airbyte/pull/50282) | Update dependencies | +| 0.2.3 | 2024-12-14 | [49671](https://github.com/airbytehq/airbyte/pull/49671) | Update dependencies | +| 0.2.2 | 2024-12-12 | [47783](https://github.com/airbytehq/airbyte/pull/47783) | Update dependencies | | 0.2.1 | 2024-10-28 | [47034](https://github.com/airbytehq/airbyte/pull/47034) | Update dependencies | | 0.2.0 | 2024-10-21 | [47143](https://github.com/airbytehq/airbyte/pull/47143) | Migrate to manifest only format | | 0.1.21 | 2024-10-12 | [46838](https://github.com/airbytehq/airbyte/pull/46838) | Update dependencies | diff --git a/docs/integrations/sources/pokeapi.md b/docs/integrations/sources/pokeapi.md index 69e383d40471..af2be216fe47 100644 --- a/docs/integrations/sources/pokeapi.md +++ b/docs/integrations/sources/pokeapi.md @@ -39,6 +39,11 @@ The PokéAPI uses the same [JSONSchema](https://json-schema.org/understanding-js | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :---------------------------------------------- | +| 0.3.7 | 2024-12-28 | [50708](https://github.com/airbytehq/airbyte/pull/50708) | Update dependencies | +| 0.3.6 | 2024-12-21 | [50261](https://github.com/airbytehq/airbyte/pull/50261) | Update dependencies | +| 0.3.5 | 2024-12-14 | [49689](https://github.com/airbytehq/airbyte/pull/49689) | Update dependencies | +| 0.3.4 | 2024-12-12 | [49337](https://github.com/airbytehq/airbyte/pull/49337) | Update dependencies | +| 0.3.3 | 2024-12-09 | [48220](https://github.com/airbytehq/airbyte/pull/48220) | Update dependencies | | 0.3.2 | 2024-10-29 | [47927](https://github.com/airbytehq/airbyte/pull/47927) | Update dependencies | | 0.3.1 | 2024-10-28 | [47461](https://github.com/airbytehq/airbyte/pull/47461) | Update dependencies | | 0.3.0 | 2024-08-26 | [44791](https://github.com/airbytehq/airbyte/pull/44791) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/polygon-stock-api.md b/docs/integrations/sources/polygon-stock-api.md index 883ae0d8054f..e1356d5d6ab9 100644 --- a/docs/integrations/sources/polygon-stock-api.md +++ b/docs/integrations/sources/polygon-stock-api.md @@ -53,6 +53,11 @@ The following fields are required fields for the connector to work: | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.2.7 | 2024-12-28 | [50732](https://github.com/airbytehq/airbyte/pull/50732) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50283](https://github.com/airbytehq/airbyte/pull/50283) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49700](https://github.com/airbytehq/airbyte/pull/49700) | Update dependencies | +| 0.2.4 | 2024-12-12 | [49348](https://github.com/airbytehq/airbyte/pull/49348) | Update dependencies | +| 0.2.3 | 2024-12-11 | [48310](https://github.com/airbytehq/airbyte/pull/48310) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.2 | 2024-10-29 | [47901](https://github.com/airbytehq/airbyte/pull/47901) | Update dependencies | | 0.2.1 | 2024-10-28 | [47496](https://github.com/airbytehq/airbyte/pull/47496) | Update dependencies | | 0.2.0 | 2024-08-19 | [44408](https://github.com/airbytehq/airbyte/pull/44408) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/postgres.md b/docs/integrations/sources/postgres.md index 65d9b6507274..c1f73572eeb1 100644 --- a/docs/integrations/sources/postgres.md +++ b/docs/integrations/sources/postgres.md @@ -327,294 +327,300 @@ According to Postgres [documentation](https://www.postgresql.org/docs/14/datatyp
Expand to review -| Version | Date | Pull Request | Subject | -|---------|------------|----------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 3.6.22 | 2024-10-02 | [46900](https://github.com/airbytehq/airbyte/pull/46900) | Fixed a bug where source docs won't render on Airbyte 1.1 | -| 3.6.21 | 2024-10-02 | [46322](https://github.com/airbytehq/airbyte/pull/46322) | Support CDC against a read-replica (continuation) | -| 3.6.20 | 2024-10-01 | [46299](https://github.com/airbytehq/airbyte/pull/46299) | Make postgres source compile and use the latest CDK | -| 3.6.19 | 2024-09-17 | [45639](https://github.com/airbytehq/airbyte/pull/45639) | Adopt latest CDK to use the latest apache sshd mina to handle tcpkeepalive requests. | -| 3.6.18 | 2024-08-28 | [44878](https://github.com/airbytehq/airbyte/pull/44878) | Enable tcpKeepAlive for jdbc connection. | -| 3.6.17 | 2024-08-27 | [44841](https://github.com/airbytehq/airbyte/pull/44841) | Adopt latest CDK. | -| 3.6.16 | 2024-08-15 | [44119](https://github.com/airbytehq/airbyte/pull/44119) | Fix incorrect final state on initial read in CDC mode. | -| 3.6.15 | 2024-08-12 | [43945](https://github.com/airbytehq/airbyte/pull/43945) | Add missing replication slot config error. | -| 3.6.14 | 2024-08-08 | [43418](https://github.com/airbytehq/airbyte/pull/43418) | Adopt latest CDK. | -| 3.6.13 | 2024-07-30 | [42869](https://github.com/airbytehq/airbyte/pull/42869) | Adopt latest CDK. | -| 3.6.12 | 2024-07-30 | [42550](https://github.com/airbytehq/airbyte/pull/42550) | Correctly report stream states. | -| 3.6.11 | 2024-07-29 | [42852](https://github.com/airbytehq/airbyte/pull/42852) | Bump CDK version to latest to use new bug fixes on error translation. | -| 3.6.10 | 2024-07-23 | [42417](https://github.com/airbytehq/airbyte/pull/42417) | Handle null error message in ConnectorExceptionHandler. | -| 3.6.9 | 2024-07-23 | [42421](https://github.com/airbytehq/airbyte/pull/42421) | Remove final transient error emitter iterators. | -| 3.6.8 | 2024-07-22 | [41622](https://github.com/airbytehq/airbyte/pull/41622) | Bump CDK version to latest. | -| 3.6.7 | 2024-07-22 | [42411](https://github.com/airbytehq/airbyte/pull/42411) | Hide the "initial load timeout in hours" field by default in UI | -| 3.6.6 | 2024-07-22 | [41622](https://github.com/airbytehq/airbyte/pull/41622) | Fix bug in CDC syncing | -| 3.6.5 | 2024-07-22 | [42024](https://github.com/airbytehq/airbyte/pull/42024) | Fix a bug on resuming from a failed attempt. | -| 3.6.4 | 2024-07-17 | [42087](https://github.com/airbytehq/airbyte/pull/42087) | Translate more errors for Postgres source. | -| 3.6.3 | 2024-07-19 | [42122](https://github.com/airbytehq/airbyte/pull/42122) | Improve wass error message + logging. | -| 3.6.2 | 2024-07-18 | [42108](https://github.com/airbytehq/airbyte/pull/42108) | Disable incremental sync for view streams in xmin replication mode | -| 3.6.1 | 2024-07-05 | [40716](https://github.com/airbytehq/airbyte/pull/40716) | Fix typo in connector specification | -| 3.6.0 | 2024-07-17 | [40208](https://github.com/airbytehq/airbyte/pull/40208) | Start using the new error Postgres source error handler that comes with a new error translation layer. | -| 3.5.2 | 2024-07-17 | [42068](https://github.com/airbytehq/airbyte/pull/42068) | Add analytics for WASS case occurrence. | -| 3.5.1 | 2024-07-17 | [42055](https://github.com/airbytehq/airbyte/pull/42055) | Add debezium heartbeat timeout back to shutdown debezium. | -| 3.5.0 | 2024-07-17 | [41651](https://github.com/airbytehq/airbyte/pull/41651) | Implement WASS algo - large initial snapshots shouldn't block CDC. | -| 3.4.26 | 2024-07-15 | [41654](https://github.com/airbytehq/airbyte/pull/41654) | Allow null value for array typed columns in CDC. | -| 3.4.25 | 2024-07-12 | [41651](https://github.com/airbytehq/airbyte/pull/41651) | Throw transient error if tables of interest and undergoing full vacuum. | -| 3.4.24 | 2024-07-05 | [41067](https://github.com/airbytehq/airbyte/pull/41067) | Fix Postgres sending duplicated streams | -| 3.4.23 | 2024-07-01 | [40757](https://github.com/airbytehq/airbyte/pull/40757) | Rollback 3.4.22. | -| 3.4.21 | 2024-07-01 | [40516](https://github.com/airbytehq/airbyte/pull/40516) | Remove dbz hearbeat. | -| 3.4.20 | 2024-06-23 | [40559](https://github.com/airbytehq/airbyte/pull/40559) | Remove strict check for stream states of unknown types | -| 3.4.19 | 2024-06-23 | [40223](https://github.com/airbytehq/airbyte/pull/40223) | Revert the changes introduced in version 3.4.15. | -| 3.4.18 | 2024-06-14 | [39349](https://github.com/airbytehq/airbyte/pull/39349) | Full refresh stream sending internal count metadata. | -| 3.4.17 | 2024-06-13 | [39460](https://github.com/airbytehq/airbyte/pull/39460) | Bump postgres JDBC driver version | -| 3.4.16 | 2024-05-29 | [39474](https://github.com/airbytehq/airbyte/pull/39474) | Adopt latest CDK. | -| 3.4.15 | 2024-05-29 | [38773](https://github.com/airbytehq/airbyte/pull/38773) | Connect with adaptiveFetch=true. | -| 3.4.14 | 2024-06-08 | [39353](https://github.com/airbytehq/airbyte/pull/39353) | Upgrade Debezium to 2.6.2 | -| 3.4.13 | 2024-06-04 | [38875](https://github.com/airbytehq/airbyte/pull/38875) | read() throws config exception upon detecting transaction ID wraparound. | -| 3.4.12 | 2024-06-04 | [38836](https://github.com/airbytehq/airbyte/pull/38836) | check() throws config error upon detecting transaction ID wraparound. | -| 3.4.11 | 2024-06-04 | [38848](https://github.com/airbytehq/airbyte/pull/38848) | Improve UI message and doc on xmin | -| 3.4.10 | 2024-05-29 | [38584](https://github.com/airbytehq/airbyte/pull/38584) | Set is_resumable flag in discover. | -| 3.4.9 | 2024-05-29 | [38775](https://github.com/airbytehq/airbyte/pull/38775) | Publish CDK | -| 3.4.9 | 2024-05-28 | [38716](https://github.com/airbytehq/airbyte/pull/38716) | Publish CDK | -| 3.4.8 | 2024-05-28 | [38716](https://github.com/airbytehq/airbyte/pull/38716) | Stream status for postgres | -| 3.4.7 | 2024-05-20 | [38365](https://github.com/airbytehq/airbyte/pull/38365) | Rollback a previously version (3.4.6) | -| 3.4.5 | 2024-05-16 | [38303](https://github.com/airbytehq/airbyte/pull/38303) | Streams not in the CDC publication still have a cursor and PK. | -| 3.4.4 | 2024-05-15 | [38208](https://github.com/airbytehq/airbyte/pull/38208) | disable counts in full refresh stream in state message. | -| 3.4.3 | 2024-05-13 | [38104](https://github.com/airbytehq/airbyte/pull/38104) | Handle transient error messages. | -| 3.4.2 | 2024-05-10 | [38171](https://github.com/airbytehq/airbyte/pull/38171) | Bug fix on final state setup. | -| 3.4.1 | 2024-05-10 | [38130](https://github.com/airbytehq/airbyte/pull/38130) | Bug fix on old PG where ctid column not found when stream is a view. | -| 3.4.0 | 2024-04-29 | [37112](https://github.com/airbytehq/airbyte/pull/37112) | resumeable full refresh. | -| 3.3.33 | 2024-05-07 | [38030](https://github.com/airbytehq/airbyte/pull/38030) | Mark PG hot standby error as transient. | -| 3.3.32 | 2024-04-30 | [37758](https://github.com/airbytehq/airbyte/pull/37758) | Correct previous release to disable debezium retries | -| 3.3.31 | 2024-04-30 | [37754](https://github.com/airbytehq/airbyte/pull/37754) | Add CDC logs | -| 3.3.30 | 2024-04-30 | [37726](https://github.com/airbytehq/airbyte/pull/37726) | Remove debezium retries | -| 3.3.29 | 2024-04-23 | [37509](https://github.com/airbytehq/airbyte/pull/37509) | remove excessive logs | -| 3.3.28 | 2024-04-23 | [37509](https://github.com/airbytehq/airbyte/pull/37509) | Better error messages on switching between sync modes. | -| 3.3.27 | 2024-04-22 | [37445](https://github.com/airbytehq/airbyte/pull/37445) | Remove legacy bad values handling code. | -| 3.3.26 | 2024-04-10 | [36982](https://github.com/airbytehq/airbyte/pull/36982) | Populate airyte_meta.changes for xmin path | -| 3.3.25 | 2024-04-10 | [36981](https://github.com/airbytehq/airbyte/pull/36981) | Track latest CDK | -| 3.3.24 | 2024-04-10 | [36865](https://github.com/airbytehq/airbyte/pull/36865) | Track latest CDK | -| 3.3.23 | 2024-04-02 | [36759](https://github.com/airbytehq/airbyte/pull/36759) | Track latest CDK | -| 3.3.22 | 2024-04-01 | [36739](https://github.com/airbytehq/airbyte/pull/36739) | Fix useLocalCdk flag. | -| 3.3.21 | 2024-03-25 | [36584](https://github.com/airbytehq/airbyte/pull/36584) | Adopt Kotlin CDK. | -| 3.3.20 | 2024-03-25 | [36432](https://github.com/airbytehq/airbyte/pull/36432) | Failure to serialize values from Postgres DB shouldn't fail sync. | -| 3.3.19 | 2024-03-12 | [36333](https://github.com/airbytehq/airbyte/pull/36333) | Use newest CDK - deprecate dbz iterator | -| 3.3.18 | 2024-03-12 | [35599](https://github.com/airbytehq/airbyte/pull/35599) | Use newest CDK | -| 3.3.17 | 2024-03-12 | [35939](https://github.com/airbytehq/airbyte/pull/35939) | Use lsn_commit value instead of lsn_proc for CDC checkpointing logic. | -| 3.3.16 | 2024-03-11 | [35904](https://github.com/airbytehq/airbyte/pull/35904) | Adopt Java CDK 0.23.1- debezium retries. | -| 3.3.15 | 2024-02-29 | [34724](https://github.com/airbytehq/airbyte/pull/34724) | Add record count in state message. | -| 3.3.14 | 2024-03-06 | [35842](https://github.com/airbytehq/airbyte/pull/35842) | Add logging to understand cases with a large number of records with the same LSN. | -| 3.3.13 | 2024-02-27 | [35675](https://github.com/airbytehq/airbyte/pull/35675) | Fix invalid cdc error message. | -| 3.3.12 | 2024-02-22 | [35569](https://github.com/airbytehq/airbyte/pull/35569) | Fix logging bug. | -| 3.3.11 | 2024-02-20 | [35304](https://github.com/airbytehq/airbyte/pull/35304) | Add config to throw an error on invalid CDC position and enable it by default. | -| 3.3.10 | 2024-02-13 | [35036](https://github.com/airbytehq/airbyte/pull/34751) | Emit analytics message for invalid CDC cursor. | -| 3.3.9 | 2024-02-13 | [35224](https://github.com/airbytehq/airbyte/pull/35224) | Adopt CDK 0.20.4 | -| 3.3.8 | 2024-02-08 | [34751](https://github.com/airbytehq/airbyte/pull/34751) | Adopt CDK 0.19.0 | -| 3.3.7 | 2024-02-08 | [34781](https://github.com/airbytehq/airbyte/pull/34781) | Add a setting in the setup page to advance the LSN. | -| 3.3.6 | 2024-02-07 | [34892](https://github.com/airbytehq/airbyte/pull/34892) | Adopt CDK v0.16.6 | -| 3.3.5 | 2024-02-07 | [34948](https://github.com/airbytehq/airbyte/pull/34948) | Adopt CDK v0.16.5 | -| 3.3.4 | 2024-01-31 | [34723](https://github.com/airbytehq/airbyte/pull/34723) | Adopt CDK v0.16.3 | -| 3.3.3 | 2024-01-26 | [34573](https://github.com/airbytehq/airbyte/pull/34573) | Adopt CDK v0.16.0 | -| 3.3.2 | 2024-01-24 | [34465](https://github.com/airbytehq/airbyte/pull/34465) | Check xmin only if user selects xmin sync mode. | -| 3.3.1 | 2024-01-10 | [34119](https://github.com/airbytehq/airbyte/pull/34119) | Adopt java CDK version 0.11.5. | -| 3.3.0 | 2023-12-19 | [33437](https://github.com/airbytehq/airbyte/pull/33437) | Remove LEGACY state flag | -| 3.2.27 | 2023-12-18 | [33605](https://github.com/airbytehq/airbyte/pull/33605) | Advance Postgres LSN for PG 14 & below. | -| 3.2.26 | 2023-12-11 | [33027](https://github.com/airbytehq/airbyte/pull/32961) | Support for better debugging tools. | -| 3.2.25 | 2023-11-29 | [32961](https://github.com/airbytehq/airbyte/pull/32961) | Bump debezium wait time default to 20 min. | -| 3.2.24 | 2023-11-28 | [32686](https://github.com/airbytehq/airbyte/pull/32686) | Better logging to understand dbz closing reason attribution. | -| 3.2.23 | 2023-11-28 | [32891](https://github.com/airbytehq/airbyte/pull/32891) | Fix CDK dependency in build. | -| 3.2.22 | 2023-11-22 | [32656](https://github.com/airbytehq/airbyte/pull/32656) | Adopt java CDK version 0.5.0. | -| 3.2.21 | 2023-11-07 | [31856](https://github.com/airbytehq/airbyte/pull/31856) | handle date/timestamp infinity values properly | -| 3.2.20 | 2023-11-06 | [32193](https://github.com/airbytehq/airbyte/pull/32193) | Adopt java CDK version 0.4.1. | -| 3.2.19 | 2023-11-03 | [32050](https://github.com/airbytehq/airbyte/pull/32050) | Adopt java CDK version 0.4.0. | -| 3.2.18 | 2023-11-01 | [29038](https://github.com/airbytehq/airbyte/pull/29038) | Fix typo (s/Airbtye/Airbyte/) | -| 3.2.17 | 2023-11-01 | [32068](https://github.com/airbytehq/airbyte/pull/32068) | Bump Debezium 2.2.0Final -> 2.4.0Final | -| 3.2.16 | 2023-10-31 | [31976](https://github.com/airbytehq/airbyte/pull/31976) | Speed up tests involving Debezium | -| 3.2.15 | 2023-10-30 | [31960](https://github.com/airbytehq/airbyte/pull/31960) | Adopt java CDK version 0.2.0. | -| 3.2.14 | 2023-10-24 | [31792](https://github.com/airbytehq/airbyte/pull/31792) | Fix error message link on issue with standby | -| 3.2.14 | 2023-10-24 | [31792](https://github.com/airbytehq/airbyte/pull/31792) | fail sync when debezeum fails to shutdown cleanly | -| 3.2.13 | 2023-10-16 | [31029](https://github.com/airbytehq/airbyte/pull/31029) | Enforces encrypted traffic settings when env var DEPLOYMENT_MODE = CLOUD. | -| 3.1.13 | 2023-10-13 | [31309](https://github.com/airbytehq/airbyte/pull/31309) | Addressed decimals being incorrectly deserialized into scientific notation. | -| 3.1.12 | 2023-10-12 | [31328](https://github.com/airbytehq/airbyte/pull/31328) | Improvements to initial load of tables in older versions of postgres. | -| 3.1.11 | 2023-10-11 | [31322](https://github.com/airbytehq/airbyte/pull/31322) | Correct pevious release | -| 3.1.10 | 2023-09-29 | [30806](https://github.com/airbytehq/airbyte/pull/30806) | Cap log line length to 32KB to prevent loss of records. | -| 3.1.9 | 2023-09-25 | [30534](https://github.com/airbytehq/airbyte/pull/30534) | Fix JSONB[] column type handling bug. | -| 3.1.8 | 2023-09-20 | [30125](https://github.com/airbytehq/airbyte/pull/30125) | Improve initial load performance for older versions of PostgreSQL. | -| 3.1.7 | 2023-09-05 | [29672](https://github.com/airbytehq/airbyte/pull/29672) | Handle VACUUM happening during initial sync | -| 3.1.6 | 2023-08-24 | [29821](https://github.com/airbytehq/airbyte/pull/29821) | Set replication_method display_type to radio, update titles and descriptions, and make CDC the default choice | -| 3.1.5 | 2023-08-22 | [29534](https://github.com/airbytehq/airbyte/pull/29534) | Support "options" JDBC URL parameter | -| 3.1.4 | 2023-08-21 | [28687](https://github.com/airbytehq/airbyte/pull/28687) | Under the hood: Add dependency on Java CDK v0.0.2. | -| 3.1.3 | 2023-08-03 | [28708](https://github.com/airbytehq/airbyte/pull/28708) | Enable checkpointing snapshots in CDC connections | -| 3.1.2 | 2023-08-01 | [28954](https://github.com/airbytehq/airbyte/pull/28954) | Fix an issue that prevented use of tables with names containing uppercase letters | -| 3.1.1 | 2023-07-31 | [28892](https://github.com/airbytehq/airbyte/pull/28892) | Fix an issue that prevented use of cursor columns with names containing uppercase letters | -| 3.1.0 | 2023-07-25 | [28339](https://github.com/airbytehq/airbyte/pull/28339) | Checkpointing initial load for incremental syncs: enabled for xmin and cursor based only. | -| 3.0.2 | 2023-07-18 | [28336](https://github.com/airbytehq/airbyte/pull/28336) | Add full-refresh mode back to Xmin syncs. | -| 3.0.1 | 2023-07-14 | [28345](https://github.com/airbytehq/airbyte/pull/28345) | Increment patch to trigger a rebuild | -| 3.0.0 | 2023-07-12 | [27442](https://github.com/airbytehq/airbyte/pull/27442) | Set \_ab_cdc_lsn as the source defined cursor for CDC mode to prepare for Destination v2 normalization | -| 2.1.1 | 2023-07-06 | [26723](https://github.com/airbytehq/airbyte/pull/26723) | Add new xmin replication method. | -| 2.1.0 | 2023-06-26 | [27737](https://github.com/airbytehq/airbyte/pull/27737) | License Update: Elv2 | -| 2.0.34 | 2023-06-20 | [27212](https://github.com/airbytehq/airbyte/pull/27212) | Fix silent exception swallowing in StreamingJdbcDatabase | -| 2.0.33 | 2023-06-01 | [26873](https://github.com/airbytehq/airbyte/pull/26873) | Add prepareThreshold=0 to JDBC url to mitigate PGBouncer prepared statement [X] already exists. | -| 2.0.32 | 2023-05-31 | [26810](https://github.com/airbytehq/airbyte/pull/26810) | Remove incremental sync estimate from Postgres to increase performance. | -| 2.0.31 | 2023-05-25 | [26633](https://github.com/airbytehq/airbyte/pull/26633) | Collect and log information related to full vacuum operation in db | -| 2.0.30 | 2023-05-25 | [26473](https://github.com/airbytehq/airbyte/pull/26473) | CDC : Limit queue size | -| 2.0.29 | 2023-05-18 | [25898](https://github.com/airbytehq/airbyte/pull/25898) | Translate Numeric values without decimal, e.g: NUMERIC(38,0), as BigInt instead of Double | -| 2.0.28 | 2023-04-27 | [25401](https://github.com/airbytehq/airbyte/pull/25401) | CDC : Upgrade Debezium to version 2.2.0 | -| 2.0.27 | 2023-04-26 | [24971](https://github.com/airbytehq/airbyte/pull/24971) | Emit stream status updates | -| 2.0.26 | 2023-04-26 | [25560](https://github.com/airbytehq/airbyte/pull/25560) | Revert some logging changes | -| 2.0.25 | 2023-04-24 | [25459](https://github.com/airbytehq/airbyte/pull/25459) | Better logging formatting | -| 2.0.24 | 2023-04-19 | [25345](https://github.com/airbytehq/airbyte/pull/25345) | Logging : Log database indexes per stream | -| 2.0.23 | 2023-04-19 | [24582](https://github.com/airbytehq/airbyte/pull/24582) | CDC : Enable frequent state emission during incremental syncs + refactor for performance improvement | -| 2.0.22 | 2023-04-17 | [25220](https://github.com/airbytehq/airbyte/pull/25220) | Logging changes : Log additional metadata & clean up noisy logs | -| 2.0.21 | 2023-04-12 | [25131](https://github.com/airbytehq/airbyte/pull/25131) | Make Client Certificate and Client Key always show | -| 2.0.20 | 2023-04-11 | [24859](https://github.com/airbytehq/airbyte/pull/24859) | Removed SSL toggle and rely on SSL mode dropdown to enable/disable SSL | -| 2.0.19 | 2023-04-11 | [24656](https://github.com/airbytehq/airbyte/pull/24656) | CDC minor refactor | -| 2.0.18 | 2023-04-06 | [24820](https://github.com/airbytehq/airbyte/pull/24820) | Fix data loss bug during an initial failed non-CDC incremental sync | -| 2.0.17 | 2023-04-05 | [24622](https://github.com/airbytehq/airbyte/pull/24622) | Allow streams not in CDC publication to be synced in Full-refresh mode | -| 2.0.16 | 2023-04-05 | [24895](https://github.com/airbytehq/airbyte/pull/24895) | Fix spec for cloud | -| 2.0.15 | 2023-04-04 | [24833](https://github.com/airbytehq/airbyte/pull/24833) | Fix Debezium retry policy configuration | -| 2.0.14 | 2023-04-03 | [24609](https://github.com/airbytehq/airbyte/pull/24609) | Disallow the "disable" SSL Modes | -| 2.0.13 | 2023-03-28 | [24166](https://github.com/airbytehq/airbyte/pull/24166) | Fix InterruptedException bug during Debezium shutdown | -| 2.0.12 | 2023-03-27 | [24529](https://github.com/airbytehq/airbyte/pull/24373) | Add CDC checkpoint state messages | -| 2.0.11 | 2023-03-23 | [24446](https://github.com/airbytehq/airbyte/pull/24446) | Set default SSL Mode to require in strict-encrypt | -| 2.0.10 | 2023-03-23 | [24417](https://github.com/airbytehq/airbyte/pull/24417) | Add field groups and titles to improve display of connector setup form | -| 2.0.9 | 2023-03-22 | [20760](https://github.com/airbytehq/airbyte/pull/20760) | Removed redundant date-time datatypes formatting | -| 2.0.8 | 2023-03-22 | [24255](https://github.com/airbytehq/airbyte/pull/24255) | Add field groups and titles to improve display of connector setup form | -| 2.0.7 | 2023-03-21 | [24207](https://github.com/airbytehq/airbyte/pull/24207) | Fix incorrect schema change warning in CDC mode | -| 2.0.6 | 2023-03-21 | [24271](https://github.com/airbytehq/airbyte/pull/24271) | Fix NPE in CDC mode | -| 2.0.5 | 2023-03-21 | [21533](https://github.com/airbytehq/airbyte/pull/21533) | Add integration with datadog | -| 2.0.4 | 2023-03-21 | [24147](https://github.com/airbytehq/airbyte/pull/24275) | Fix error with CDC checkpointing | -| 2.0.3 | 2023-03-14 | [24000](https://github.com/airbytehq/airbyte/pull/24000) | Removed check method call on read. | -| 2.0.2 | 2023-03-13 | [23112](https://github.com/airbytehq/airbyte/pull/21727) | Add state checkpointing for CDC sync. | -| 2.0.0 | 2023-03-06 | [23112](https://github.com/airbytehq/airbyte/pull/23112) | Upgrade Debezium version to 2.1.2 | -| 1.0.51 | 2023-03-02 | [23642](https://github.com/airbytehq/airbyte/pull/23642) | Revert : Support JSONB datatype for Standard sync mode | -| 1.0.50 | 2023-02-27 | [21695](https://github.com/airbytehq/airbyte/pull/21695) | Support JSONB datatype for Standard sync mode | -| 1.0.49 | 2023-02-24 | [23383](https://github.com/airbytehq/airbyte/pull/23383) | Fixed bug with non readable double-quoted values within a database name or column name | -| 1.0.48 | 2023-02-23 | [22623](https://github.com/airbytehq/airbyte/pull/22623) | Increase max fetch size of JDBC streaming mode | -| 1.0.47 | 2023-02-22 | [22221](https://github.com/airbytehq/airbyte/pull/23138) | Fix previous versions which doesn't verify privileges correctly, preventing CDC syncs to run. | -| 1.0.46 | 2023-02-21 | [23105](https://github.com/airbytehq/airbyte/pull/23105) | Include log levels and location information (class, method and line number) with source connector logs published to Airbyte Platform. | -| 1.0.45 | 2023-02-09 | [22221](https://github.com/airbytehq/airbyte/pull/22371) | Ensures that user has required privileges for CDC syncs. | -| | 2023-02-15 | [23028](https://github.com/airbytehq/airbyte/pull/23028) | | -| 1.0.44 | 2023-02-06 | [22221](https://github.com/airbytehq/airbyte/pull/22221) | Exclude new set of system tables when using `pg_stat_statements` extension. | -| 1.0.43 | 2023-02-06 | [21634](https://github.com/airbytehq/airbyte/pull/21634) | Improve Standard sync performance by caching objects. | -| 1.0.42 | 2023-01-23 | [21523](https://github.com/airbytehq/airbyte/pull/21523) | Check for null in cursor values before replacing. | -| 1.0.41 | 2023-01-25 | [20939](https://github.com/airbytehq/airbyte/pull/20939) | Adjust batch selection memory limits databases. | -| 1.0.40 | 2023-01-24 | [21825](https://github.com/airbytehq/airbyte/pull/21825) | Put back the original change that will cause an incremental sync to error if table contains a NULL value in cursor column. | -| 1.0.39 | 2023-01-20 | [21683](https://github.com/airbytehq/airbyte/pull/21683) | Speed up esmtimates for trace messages in non-CDC mode. | -| 1.0.38 | 2023-01-17 | [20436](https://github.com/airbytehq/airbyte/pull/20346) | Consolidate date/time values mapping for JDBC sources | -| 1.0.37 | 2023-01-17 | [20783](https://github.com/airbytehq/airbyte/pull/20783) | Emit estimate trace messages for non-CDC mode. | -| 1.0.36 | 2023-01-11 | [21003](https://github.com/airbytehq/airbyte/pull/21003) | Handle null values for array data types in CDC mode gracefully. | -| 1.0.35 | 2023-01-04 | [20469](https://github.com/airbytehq/airbyte/pull/20469) | Introduce feature to make LSN commit behaviour configurable. | -| 1.0.34 | 2022-12-13 | [20378](https://github.com/airbytehq/airbyte/pull/20378) | Improve descriptions | -| 1.0.33 | 2022-12-12 | [18959](https://github.com/airbytehq/airbyte/pull/18959) | CDC : Don't timeout if snapshot is not complete. | -| 1.0.32 | 2022-12-12 | [20192](https://github.com/airbytehq/airbyte/pull/20192) | Only throw a warning if cursor column contains null values. | -| 1.0.31 | 2022-12-02 | [19889](https://github.com/airbytehq/airbyte/pull/19889) | Check before each sync and stop if an incremental sync cursor column contains a null value. | -| | 2022-12-02 | [19985](https://github.com/airbytehq/airbyte/pull/19985) | Reenable incorrectly-disabled `wal2json` CDC plugin | -| 1.0.30 | 2022-11-29 | [19024](https://github.com/airbytehq/airbyte/pull/19024) | Skip tables from schema where user do not have Usage permission during discovery. | -| 1.0.29 | 2022-11-29 | [19623](https://github.com/airbytehq/airbyte/pull/19623) | Mark PSQLException related to using replica that is configured as a hot standby server as config error. | -| 1.0.28 | 2022-11-28 | [19514](https://github.com/airbytehq/airbyte/pull/19514) | Adjust batch selection memory limits databases. | -| 1.0.27 | 2022-11-28 | [16990](https://github.com/airbytehq/airbyte/pull/16990) | Handle arrays data types | -| 1.0.26 | 2022-11-18 | [19551](https://github.com/airbytehq/airbyte/pull/19551) | Fixes bug with ssl modes | -| 1.0.25 | 2022-11-16 | [19004](https://github.com/airbytehq/airbyte/pull/19004) | Use Debezium heartbeats to improve CDC replication of large databases. | -| 1.0.24 | 2022-11-07 | [19291](https://github.com/airbytehq/airbyte/pull/19291) | Default timeout is reduced from 1 min to 10sec | -| 1.0.23 | 2022-11-07 | [19025](https://github.com/airbytehq/airbyte/pull/19025) | Stop enforce SSL if ssl mode is disabled | -| 1.0.22 | 2022-10-31 | [18538](https://github.com/airbytehq/airbyte/pull/18538) | Encode database name | -| 1.0.21 | 2022-10-25 | [18256](https://github.com/airbytehq/airbyte/pull/18256) | Disable allow and prefer ssl modes in CDC mode | -| 1.0.20 | 2022-10-25 | [18383](https://github.com/airbytehq/airbyte/pull/18383) | Better SSH error handling + messages | -| 1.0.19 | 2022-10-21 | [18263](https://github.com/airbytehq/airbyte/pull/18263) | Fixes bug introduced in [15833](https://github.com/airbytehq/airbyte/pull/15833) and adds better error messaging for SSH tunnel in Destinations | -| 1.0.18 | 2022-10-19 | [18087](https://github.com/airbytehq/airbyte/pull/18087) | Better error messaging for configuration errors (SSH configs, choosing an invalid cursor) | -| 1.0.17 | 2022-10-17 | [18041](https://github.com/airbytehq/airbyte/pull/18041) | Fixes bug introduced 2022-09-12 with SshTunnel, handles iterator exception properly | -| 1.0.16 | 2022-10-13 | [15535](https://github.com/airbytehq/airbyte/pull/16238) | Update incremental query to avoid data missing when new data is inserted at the same time as a sync starts under non-CDC incremental mode | -| 1.0.15 | 2022-10-11 | [17782](https://github.com/airbytehq/airbyte/pull/17782) | Handle 24:00:00 value for Time column | -| 1.0.14 | 2022-10-03 | [17515](https://github.com/airbytehq/airbyte/pull/17515) | Fix an issue preventing connection using client certificate | -| 1.0.13 | 2022-10-01 | [17459](https://github.com/airbytehq/airbyte/pull/17459) | Upgrade debezium version to 1.9.6 from 1.9.2 | -| 1.0.12 | 2022-09-27 | [17299](https://github.com/airbytehq/airbyte/pull/17299) | Improve error handling for strict-encrypt postgres source | -| 1.0.11 | 2022-09-26 | [17131](https://github.com/airbytehq/airbyte/pull/17131) | Allow nullable columns to be used as cursor | -| 1.0.10 | 2022-09-14 | [15668](https://github.com/airbytehq/airbyte/pull/15668) | Wrap logs in AirbyteLogMessage | -| 1.0.9 | 2022-09-13 | [16657](https://github.com/airbytehq/airbyte/pull/16657) | Improve CDC record queueing performance | -| 1.0.8 | 2022-09-08 | [16202](https://github.com/airbytehq/airbyte/pull/16202) | Adds error messaging factory to UI | -| 1.0.7 | 2022-08-30 | [16114](https://github.com/airbytehq/airbyte/pull/16114) | Prevent traffic going on an unsecured channel in strict-encryption version of source postgres | -| 1.0.6 | 2022-08-30 | [16138](https://github.com/airbytehq/airbyte/pull/16138) | Remove unnecessary logging | -| 1.0.5 | 2022-08-25 | [15993](https://github.com/airbytehq/airbyte/pull/15993) | Add support for connection over SSL in CDC mode | -| 1.0.4 | 2022-08-23 | [15877](https://github.com/airbytehq/airbyte/pull/15877) | Fix temporal data type bug which was causing failure in CDC mode | -| 1.0.3 | 2022-08-18 | [14356](https://github.com/airbytehq/airbyte/pull/14356) | DB Sources: only show a table can sync incrementally if at least one column can be used as a cursor field | -| 1.0.2 | 2022-08-11 | [15538](https://github.com/airbytehq/airbyte/pull/15538) | Allow additional properties in db stream state | -| 1.0.1 | 2022-08-10 | [15496](https://github.com/airbytehq/airbyte/pull/15496) | Fix state emission in incremental sync | -| | 2022-08-10 | [15481](https://github.com/airbytehq/airbyte/pull/15481) | Fix data handling from WAL logs in CDC mode | -| 1.0.0 | 2022-08-05 | [15380](https://github.com/airbytehq/airbyte/pull/15380) | Change connector label to generally_available (requires [upgrading](https://docs.airbyte.com/operator-guides/upgrading-airbyte/) your Airbyte platform to `v0.40.0-alpha`) | -| 0.4.44 | 2022-08-05 | [15342](https://github.com/airbytehq/airbyte/pull/15342) | Adjust titles and descriptions in spec.json | -| 0.4.43 | 2022-08-03 | [15226](https://github.com/airbytehq/airbyte/pull/15226) | Make connectionTimeoutMs configurable through JDBC url parameters | -| 0.4.42 | 2022-08-03 | [15273](https://github.com/airbytehq/airbyte/pull/15273) | Fix a bug in `0.4.36` and correctly parse the CDC initial record waiting time | -| 0.4.41 | 2022-08-03 | [15077](https://github.com/airbytehq/airbyte/pull/15077) | Sync data from beginning if the LSN is no longer valid in CDC | -| | 2022-08-03 | [14903](https://github.com/airbytehq/airbyte/pull/14903) | Emit state messages more frequently (⛔ this version has a bug; use `1.0.1` instead | -| 0.4.40 | 2022-08-03 | [15187](https://github.com/airbytehq/airbyte/pull/15187) | Add support for BCE dates/timestamps | -| | 2022-08-03 | [14534](https://github.com/airbytehq/airbyte/pull/14534) | Align regular and CDC integration tests and data mappers | -| 0.4.39 | 2022-08-02 | [14801](https://github.com/airbytehq/airbyte/pull/14801) | Fix multiple log bindings | -| 0.4.38 | 2022-07-26 | [14362](https://github.com/airbytehq/airbyte/pull/14362) | Integral columns are now discovered as int64 fields. | -| 0.4.37 | 2022-07-22 | [14714](https://github.com/airbytehq/airbyte/pull/14714) | Clarified error message when invalid cursor column selected | -| 0.4.36 | 2022-07-21 | [14451](https://github.com/airbytehq/airbyte/pull/14451) | Make initial CDC waiting time configurable (⛔ this version has a bug and will not work; use `0.4.42` instead) | -| 0.4.35 | 2022-07-14 | [14574](https://github.com/airbytehq/airbyte/pull/14574) | Removed additionalProperties:false from JDBC source connectors | -| 0.4.34 | 2022-07-17 | [13840](https://github.com/airbytehq/airbyte/pull/13840) | Added the ability to connect using different SSL modes and SSL certificates. | -| 0.4.33 | 2022-07-14 | [14586](https://github.com/airbytehq/airbyte/pull/14586) | Validate source JDBC url parameters | -| 0.4.32 | 2022-07-07 | [14694](https://github.com/airbytehq/airbyte/pull/14694) | Force to produce LEGACY state if the use stream capable feature flag is set to false | -| 0.4.31 | 2022-07-07 | [14447](https://github.com/airbytehq/airbyte/pull/14447) | Under CDC mode, retrieve only those tables included in the publications | -| 0.4.30 | 2022-06-30 | [14251](https://github.com/airbytehq/airbyte/pull/14251) | Use more simple and comprehensive query to get selectable tables | -| 0.4.29 | 2022-06-29 | [14265](https://github.com/airbytehq/airbyte/pull/14265) | Upgrade postgresql JDBC version to 42.3.5 | -| 0.4.28 | 2022-06-23 | [14077](https://github.com/airbytehq/airbyte/pull/14077) | Use the new state management | -| 0.4.26 | 2022-06-17 | [13864](https://github.com/airbytehq/airbyte/pull/13864) | Updated stacktrace format for any trace message errors | -| 0.4.25 | 2022-06-15 | [13823](https://github.com/airbytehq/airbyte/pull/13823) | Publish adaptive postgres source that enforces ssl on cloud + Debezium version upgrade to 1.9.2 from 1.4.2 | -| 0.4.24 | 2022-06-14 | [13549](https://github.com/airbytehq/airbyte/pull/13549) | Fixed truncated precision if the value of microseconds or seconds is 0 | -| 0.4.23 | 2022-06-13 | [13655](https://github.com/airbytehq/airbyte/pull/13745) | Fixed handling datetime cursors when upgrading from older versions of the connector | -| 0.4.22 | 2022-06-09 | [13655](https://github.com/airbytehq/airbyte/pull/13655) | Fixed bug with unsupported date-time datatypes during incremental sync | -| 0.4.21 | 2022-06-06 | [13435](https://github.com/airbytehq/airbyte/pull/13435) | Adjust JDBC fetch size based on max memory and max row size | -| 0.4.20 | 2022-06-02 | [13367](https://github.com/airbytehq/airbyte/pull/13367) | Added convertion hstore to json format | -| 0.4.19 | 2022-05-25 | [13166](https://github.com/airbytehq/airbyte/pull/13166) | Added timezone awareness and handle BC dates | -| 0.4.18 | 2022-05-25 | [13083](https://github.com/airbytehq/airbyte/pull/13083) | Add support for tsquey type | -| 0.4.17 | 2022-05-19 | [13016](https://github.com/airbytehq/airbyte/pull/13016) | CDC modify schema to allow null values | -| 0.4.16 | 2022-05-14 | [12840](https://github.com/airbytehq/airbyte/pull/12840) | Added custom JDBC parameters field | -| 0.4.15 | 2022-05-13 | [12834](https://github.com/airbytehq/airbyte/pull/12834) | Fix the bug that the connector returns empty catalog for Azure Postgres database | -| 0.4.14 | 2022-05-08 | [12689](https://github.com/airbytehq/airbyte/pull/12689) | Add table retrieval according to role-based `SELECT` privilege | -| 0.4.13 | 2022-05-05 | [10230](https://github.com/airbytehq/airbyte/pull/10230) | Explicitly set null value for field in json | -| 0.4.12 | 2022-04-29 | [12480](https://github.com/airbytehq/airbyte/pull/12480) | Query tables with adaptive fetch size to optimize JDBC memory consumption | -| 0.4.11 | 2022-04-11 | [11729](https://github.com/airbytehq/airbyte/pull/11729) | Bump mina-sshd from 2.7.0 to 2.8.0 | -| 0.4.10 | 2022-04-08 | [11798](https://github.com/airbytehq/airbyte/pull/11798) | Fixed roles for fetching materialized view processing | -| 0.4.8 | 2022-02-21 | [10242](https://github.com/airbytehq/airbyte/pull/10242) | Fixed cursor for old connectors that use non-microsecond format. Now connectors work with both formats | -| 0.4.7 | 2022-02-18 | [10242](https://github.com/airbytehq/airbyte/pull/10242) | Updated timestamp transformation with microseconds | -| 0.4.6 | 2022-02-14 | [10256](https://github.com/airbytehq/airbyte/pull/10256) | (unpublished) Add `-XX:+ExitOnOutOfMemoryError` JVM option | -| 0.4.5 | 2022-02-08 | [10173](https://github.com/airbytehq/airbyte/pull/10173) | Improved discovering tables in case if user does not have permissions to any table | -| 0.4.4 | 2022-01-26 | [9807](https://github.com/airbytehq/airbyte/pull/9807) | Update connector fields title/description | -| 0.4.3 | 2022-01-24 | [9554](https://github.com/airbytehq/airbyte/pull/9554) | Allow handling of java sql date in CDC | -| 0.4.2 | 2022-01-13 | [9360](https://github.com/airbytehq/airbyte/pull/9360) | Added schema selection | -| 0.4.1 | 2022-01-05 | [9116](https://github.com/airbytehq/airbyte/pull/9116) | Added materialized views processing | -| 0.4.0 | 2021-12-13 | [8726](https://github.com/airbytehq/airbyte/pull/8726) | Support all Postgres types | -| 0.3.17 | 2021-12-01 | [8371](https://github.com/airbytehq/airbyte/pull/8371) | Fixed incorrect handling "\n" in ssh key | -| 0.3.16 | 2021-11-28 | [7995](https://github.com/airbytehq/airbyte/pull/7995) | Fixed money type with amount > 1000 | -| 0.3.15 | 2021-11-26 | [8066](https://github.com/airbytehq/airbyte/pull/8266) | Fixed the case, when Views are not listed during schema discovery | -| 0.3.14 | 2021-11-17 | [8010](https://github.com/airbytehq/airbyte/pull/8010) | Added checking of privileges before table internal discovery | -| 0.3.13 | 2021-10-26 | [7339](https://github.com/airbytehq/airbyte/pull/7339) | Support or improve support for Interval, Money, Date, various geometric data types, inventory_items, and others | -| 0.3.12 | 2021-09-30 | [6585](https://github.com/airbytehq/airbyte/pull/6585) | Improved SSH Tunnel key generation steps | -| 0.3.11 | 2021-09-02 | [5742](https://github.com/airbytehq/airbyte/pull/5742) | Add SSH Tunnel support | -| 0.3.9 | 2021-08-17 | [5304](https://github.com/airbytehq/airbyte/pull/5304) | Fix CDC OOM issue | -| 0.3.8 | 2021-08-13 | [4699](https://github.com/airbytehq/airbyte/pull/4699) | Added json config validator | -| 0.3.4 | 2021-06-09 | [3973](https://github.com/airbytehq/airbyte/pull/3973) | Add `AIRBYTE_ENTRYPOINT` for Kubernetes support | -| 0.3.3 | 2021-06-08 | [3960](https://github.com/airbytehq/airbyte/pull/3960) | Add method field in specification parameters | -| 0.3.2 | 2021-05-26 | [3179](https://github.com/airbytehq/airbyte/pull/3179) | Remove `isCDC` logging | -| 0.3.1 | 2021-04-21 | [2878](https://github.com/airbytehq/airbyte/pull/2878) | Set defined cursor for CDC | -| 0.3.0 | 2021-04-21 | [2990](https://github.com/airbytehq/airbyte/pull/2990) | Support namespaces | -| 0.2.7 | 2021-04-16 | [2923](https://github.com/airbytehq/airbyte/pull/2923) | SSL spec as optional | -| 0.2.6 | 2021-04-16 | [2757](https://github.com/airbytehq/airbyte/pull/2757) | Support SSL connection | -| 0.2.5 | 2021-04-12 | [2859](https://github.com/airbytehq/airbyte/pull/2859) | CDC bugfix | -| 0.2.4 | 2021-04-09 | [2548](https://github.com/airbytehq/airbyte/pull/2548) | Support CDC | -| 0.2.3 | 2021-03-28 | [2600](https://github.com/airbytehq/airbyte/pull/2600) | Add NCHAR and NVCHAR support to DB and cursor type casting | -| 0.2.2 | 2021-03-26 | [2460](https://github.com/airbytehq/airbyte/pull/2460) | Destination supports destination sync mode | -| 0.2.1 | 2021-03-18 | [2488](https://github.com/airbytehq/airbyte/pull/2488) | Sources support primary keys | -| 0.2.0 | 2021-03-09 | [2238](https://github.com/airbytehq/airbyte/pull/2238) | Protocol allows future/unknown properties | -| 0.1.13 | 2021-02-02 | [1887](https://github.com/airbytehq/airbyte/pull/1887) | Migrate AbstractJdbcSource to use iterators | -| 0.1.12 | 2021-01-25 | [1746](https://github.com/airbytehq/airbyte/pull/1746) | Fix NPE in State Decorator | -| 0.1.11 | 2021-01-25 | [1765](https://github.com/airbytehq/airbyte/pull/1765) | Add field titles to specification | -| 0.1.10 | 2021-01-19 | [1724](https://github.com/airbytehq/airbyte/pull/1724) | Fix JdbcSource handling of tables with same names in different schemas | -| 0.1.9 | 2021-01-14 | [1655](https://github.com/airbytehq/airbyte/pull/1655) | Fix JdbcSource OOM | -| 0.1.8 | 2021-01-13 | [1588](https://github.com/airbytehq/airbyte/pull/1588) | Handle invalid numeric values in JDBC source | -| 0.1.7 | 2021-01-08 | [1307](https://github.com/airbytehq/airbyte/pull/1307) | Migrate Postgres and MySql to use new JdbcSource | -| 0.1.6 | 2020-12-09 | [1172](https://github.com/airbytehq/airbyte/pull/1172) | Support incremental sync | -| 0.1.5 | 2020-11-30 | [1038](https://github.com/airbytehq/airbyte/pull/1038) | Change JDBC sources to discover more than standard schemas | -| 0.1.4 | 2020-11-30 | [1046](https://github.com/airbytehq/airbyte/pull/1046) | Add connectors using an index YAML file | +| Version | Date | Pull Request | Subject | +| ------- | ---------- | ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 3.6.28 | 2024-12-23 | [50870](https://github.com/airbytehq/airbyte/pull/50870) | Use airbyte/java-connector-base:2.0.0 | +| 3.6.27 | 2024-12-23 | [50410](https://github.com/airbytehq/airbyte/pull/50410) | Use a non root base image. | +| 3.6.26 | 2024-12-20 | [48495](https://github.com/airbytehq/airbyte/pull/48495) | Increase MAX_FIRST_RECORD_WAIT_TIME and use Debezium 3.0.1 | +| 3.6.25 | 2024-12-17 | [49838](https://github.com/airbytehq/airbyte/pull/49838) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 3.6.24 | 2024-12-16 | [49469](https://github.com/airbytehq/airbyte/pull/49469) | Simplify CTID_TABLE_BLOCK_SIZE query for Postgres integration | +| 3.6.23 | 2024-11-13 | [\#48482](https://github.com/airbytehq/airbyte/pull/48482) | Convert large integer typed using NUMERIC(X, 0) into a BigInteger. l | +| 3.6.22 | 2024-10-02 | [46900](https://github.com/airbytehq/airbyte/pull/46900) | Fixed a bug where source docs won't render on Airbyte 1.1 | +| 3.6.21 | 2024-10-02 | [46322](https://github.com/airbytehq/airbyte/pull/46322) | Support CDC against a read-replica (continuation) | +| 3.6.20 | 2024-10-01 | [46299](https://github.com/airbytehq/airbyte/pull/46299) | Make postgres source compile and use the latest CDK | +| 3.6.19 | 2024-09-17 | [45639](https://github.com/airbytehq/airbyte/pull/45639) | Adopt latest CDK to use the latest apache sshd mina to handle tcpkeepalive requests. | +| 3.6.18 | 2024-08-28 | [44878](https://github.com/airbytehq/airbyte/pull/44878) | Enable tcpKeepAlive for jdbc connection. | +| 3.6.17 | 2024-08-27 | [44841](https://github.com/airbytehq/airbyte/pull/44841) | Adopt latest CDK. | +| 3.6.16 | 2024-08-15 | [44119](https://github.com/airbytehq/airbyte/pull/44119) | Fix incorrect final state on initial read in CDC mode. | +| 3.6.15 | 2024-08-12 | [43945](https://github.com/airbytehq/airbyte/pull/43945) | Add missing replication slot config error. | +| 3.6.14 | 2024-08-08 | [43418](https://github.com/airbytehq/airbyte/pull/43418) | Adopt latest CDK. | +| 3.6.13 | 2024-07-30 | [42869](https://github.com/airbytehq/airbyte/pull/42869) | Adopt latest CDK. | +| 3.6.12 | 2024-07-30 | [42550](https://github.com/airbytehq/airbyte/pull/42550) | Correctly report stream states. | +| 3.6.11 | 2024-07-29 | [42852](https://github.com/airbytehq/airbyte/pull/42852) | Bump CDK version to latest to use new bug fixes on error translation. | +| 3.6.10 | 2024-07-23 | [42417](https://github.com/airbytehq/airbyte/pull/42417) | Handle null error message in ConnectorExceptionHandler. | +| 3.6.9 | 2024-07-23 | [42421](https://github.com/airbytehq/airbyte/pull/42421) | Remove final transient error emitter iterators. | +| 3.6.8 | 2024-07-22 | [41622](https://github.com/airbytehq/airbyte/pull/41622) | Bump CDK version to latest. | +| 3.6.7 | 2024-07-22 | [42411](https://github.com/airbytehq/airbyte/pull/42411) | Hide the "initial load timeout in hours" field by default in UI | +| 3.6.6 | 2024-07-22 | [41622](https://github.com/airbytehq/airbyte/pull/41622) | Fix bug in CDC syncing | +| 3.6.5 | 2024-07-22 | [42024](https://github.com/airbytehq/airbyte/pull/42024) | Fix a bug on resuming from a failed attempt. | +| 3.6.4 | 2024-07-17 | [42087](https://github.com/airbytehq/airbyte/pull/42087) | Translate more errors for Postgres source. | +| 3.6.3 | 2024-07-19 | [42122](https://github.com/airbytehq/airbyte/pull/42122) | Improve wass error message + logging. | +| 3.6.2 | 2024-07-18 | [42108](https://github.com/airbytehq/airbyte/pull/42108) | Disable incremental sync for view streams in xmin replication mode | +| 3.6.1 | 2024-07-05 | [40716](https://github.com/airbytehq/airbyte/pull/40716) | Fix typo in connector specification | +| 3.6.0 | 2024-07-17 | [40208](https://github.com/airbytehq/airbyte/pull/40208) | Start using the new error Postgres source error handler that comes with a new error translation layer. | +| 3.5.2 | 2024-07-17 | [42068](https://github.com/airbytehq/airbyte/pull/42068) | Add analytics for WASS case occurrence. | +| 3.5.1 | 2024-07-17 | [42055](https://github.com/airbytehq/airbyte/pull/42055) | Add debezium heartbeat timeout back to shutdown debezium. | +| 3.5.0 | 2024-07-17 | [41651](https://github.com/airbytehq/airbyte/pull/41651) | Implement WASS algo - large initial snapshots shouldn't block CDC. | +| 3.4.26 | 2024-07-15 | [41654](https://github.com/airbytehq/airbyte/pull/41654) | Allow null value for array typed columns in CDC. | +| 3.4.25 | 2024-07-12 | [41651](https://github.com/airbytehq/airbyte/pull/41651) | Throw transient error if tables of interest and undergoing full vacuum. | +| 3.4.24 | 2024-07-05 | [41067](https://github.com/airbytehq/airbyte/pull/41067) | Fix Postgres sending duplicated streams | +| 3.4.23 | 2024-07-01 | [40757](https://github.com/airbytehq/airbyte/pull/40757) | Rollback 3.4.22. | +| 3.4.21 | 2024-07-01 | [40516](https://github.com/airbytehq/airbyte/pull/40516) | Remove dbz hearbeat. | +| 3.4.20 | 2024-06-23 | [40559](https://github.com/airbytehq/airbyte/pull/40559) | Remove strict check for stream states of unknown types | +| 3.4.19 | 2024-06-23 | [40223](https://github.com/airbytehq/airbyte/pull/40223) | Revert the changes introduced in version 3.4.15. | +| 3.4.18 | 2024-06-14 | [39349](https://github.com/airbytehq/airbyte/pull/39349) | Full refresh stream sending internal count metadata. | +| 3.4.17 | 2024-06-13 | [39460](https://github.com/airbytehq/airbyte/pull/39460) | Bump postgres JDBC driver version | +| 3.4.16 | 2024-05-29 | [39474](https://github.com/airbytehq/airbyte/pull/39474) | Adopt latest CDK. | +| 3.4.15 | 2024-05-29 | [38773](https://github.com/airbytehq/airbyte/pull/38773) | Connect with adaptiveFetch=true. | +| 3.4.14 | 2024-06-08 | [39353](https://github.com/airbytehq/airbyte/pull/39353) | Upgrade Debezium to 2.6.2 | +| 3.4.13 | 2024-06-04 | [38875](https://github.com/airbytehq/airbyte/pull/38875) | read() throws config exception upon detecting transaction ID wraparound. | +| 3.4.12 | 2024-06-04 | [38836](https://github.com/airbytehq/airbyte/pull/38836) | check() throws config error upon detecting transaction ID wraparound. | +| 3.4.11 | 2024-06-04 | [38848](https://github.com/airbytehq/airbyte/pull/38848) | Improve UI message and doc on xmin | +| 3.4.10 | 2024-05-29 | [38584](https://github.com/airbytehq/airbyte/pull/38584) | Set is_resumable flag in discover. | +| 3.4.9 | 2024-05-29 | [38775](https://github.com/airbytehq/airbyte/pull/38775) | Publish CDK | +| 3.4.9 | 2024-05-28 | [38716](https://github.com/airbytehq/airbyte/pull/38716) | Publish CDK | +| 3.4.8 | 2024-05-28 | [38716](https://github.com/airbytehq/airbyte/pull/38716) | Stream status for postgres | +| 3.4.7 | 2024-05-20 | [38365](https://github.com/airbytehq/airbyte/pull/38365) | Rollback a previously version (3.4.6) | +| 3.4.5 | 2024-05-16 | [38303](https://github.com/airbytehq/airbyte/pull/38303) | Streams not in the CDC publication still have a cursor and PK. | +| 3.4.4 | 2024-05-15 | [38208](https://github.com/airbytehq/airbyte/pull/38208) | disable counts in full refresh stream in state message. | +| 3.4.3 | 2024-05-13 | [38104](https://github.com/airbytehq/airbyte/pull/38104) | Handle transient error messages. | +| 3.4.2 | 2024-05-10 | [38171](https://github.com/airbytehq/airbyte/pull/38171) | Bug fix on final state setup. | +| 3.4.1 | 2024-05-10 | [38130](https://github.com/airbytehq/airbyte/pull/38130) | Bug fix on old PG where ctid column not found when stream is a view. | +| 3.4.0 | 2024-04-29 | [37112](https://github.com/airbytehq/airbyte/pull/37112) | resumeable full refresh. | +| 3.3.33 | 2024-05-07 | [38030](https://github.com/airbytehq/airbyte/pull/38030) | Mark PG hot standby error as transient. | +| 3.3.32 | 2024-04-30 | [37758](https://github.com/airbytehq/airbyte/pull/37758) | Correct previous release to disable debezium retries | +| 3.3.31 | 2024-04-30 | [37754](https://github.com/airbytehq/airbyte/pull/37754) | Add CDC logs | +| 3.3.30 | 2024-04-30 | [37726](https://github.com/airbytehq/airbyte/pull/37726) | Remove debezium retries | +| 3.3.29 | 2024-04-23 | [37509](https://github.com/airbytehq/airbyte/pull/37509) | remove excessive logs | +| 3.3.28 | 2024-04-23 | [37509](https://github.com/airbytehq/airbyte/pull/37509) | Better error messages on switching between sync modes. | +| 3.3.27 | 2024-04-22 | [37445](https://github.com/airbytehq/airbyte/pull/37445) | Remove legacy bad values handling code. | +| 3.3.26 | 2024-04-10 | [36982](https://github.com/airbytehq/airbyte/pull/36982) | Populate airyte_meta.changes for xmin path | +| 3.3.25 | 2024-04-10 | [36981](https://github.com/airbytehq/airbyte/pull/36981) | Track latest CDK | +| 3.3.24 | 2024-04-10 | [36865](https://github.com/airbytehq/airbyte/pull/36865) | Track latest CDK | +| 3.3.23 | 2024-04-02 | [36759](https://github.com/airbytehq/airbyte/pull/36759) | Track latest CDK | +| 3.3.22 | 2024-04-01 | [36739](https://github.com/airbytehq/airbyte/pull/36739) | Fix useLocalCdk flag. | +| 3.3.21 | 2024-03-25 | [36584](https://github.com/airbytehq/airbyte/pull/36584) | Adopt Kotlin CDK. | +| 3.3.20 | 2024-03-25 | [36432](https://github.com/airbytehq/airbyte/pull/36432) | Failure to serialize values from Postgres DB shouldn't fail sync. | +| 3.3.19 | 2024-03-12 | [36333](https://github.com/airbytehq/airbyte/pull/36333) | Use newest CDK - deprecate dbz iterator | +| 3.3.18 | 2024-03-12 | [35599](https://github.com/airbytehq/airbyte/pull/35599) | Use newest CDK | +| 3.3.17 | 2024-03-12 | [35939](https://github.com/airbytehq/airbyte/pull/35939) | Use lsn_commit value instead of lsn_proc for CDC checkpointing logic. | +| 3.3.16 | 2024-03-11 | [35904](https://github.com/airbytehq/airbyte/pull/35904) | Adopt Java CDK 0.23.1- debezium retries. | +| 3.3.15 | 2024-02-29 | [34724](https://github.com/airbytehq/airbyte/pull/34724) | Add record count in state message. | +| 3.3.14 | 2024-03-06 | [35842](https://github.com/airbytehq/airbyte/pull/35842) | Add logging to understand cases with a large number of records with the same LSN. | +| 3.3.13 | 2024-02-27 | [35675](https://github.com/airbytehq/airbyte/pull/35675) | Fix invalid cdc error message. | +| 3.3.12 | 2024-02-22 | [35569](https://github.com/airbytehq/airbyte/pull/35569) | Fix logging bug. | +| 3.3.11 | 2024-02-20 | [35304](https://github.com/airbytehq/airbyte/pull/35304) | Add config to throw an error on invalid CDC position and enable it by default. | +| 3.3.10 | 2024-02-13 | [35036](https://github.com/airbytehq/airbyte/pull/34751) | Emit analytics message for invalid CDC cursor. | +| 3.3.9 | 2024-02-13 | [35224](https://github.com/airbytehq/airbyte/pull/35224) | Adopt CDK 0.20.4 | +| 3.3.8 | 2024-02-08 | [34751](https://github.com/airbytehq/airbyte/pull/34751) | Adopt CDK 0.19.0 | +| 3.3.7 | 2024-02-08 | [34781](https://github.com/airbytehq/airbyte/pull/34781) | Add a setting in the setup page to advance the LSN. | +| 3.3.6 | 2024-02-07 | [34892](https://github.com/airbytehq/airbyte/pull/34892) | Adopt CDK v0.16.6 | +| 3.3.5 | 2024-02-07 | [34948](https://github.com/airbytehq/airbyte/pull/34948) | Adopt CDK v0.16.5 | +| 3.3.4 | 2024-01-31 | [34723](https://github.com/airbytehq/airbyte/pull/34723) | Adopt CDK v0.16.3 | +| 3.3.3 | 2024-01-26 | [34573](https://github.com/airbytehq/airbyte/pull/34573) | Adopt CDK v0.16.0 | +| 3.3.2 | 2024-01-24 | [34465](https://github.com/airbytehq/airbyte/pull/34465) | Check xmin only if user selects xmin sync mode. | +| 3.3.1 | 2024-01-10 | [34119](https://github.com/airbytehq/airbyte/pull/34119) | Adopt java CDK version 0.11.5. | +| 3.3.0 | 2023-12-19 | [33437](https://github.com/airbytehq/airbyte/pull/33437) | Remove LEGACY state flag | +| 3.2.27 | 2023-12-18 | [33605](https://github.com/airbytehq/airbyte/pull/33605) | Advance Postgres LSN for PG 14 & below. | +| 3.2.26 | 2023-12-11 | [33027](https://github.com/airbytehq/airbyte/pull/32961) | Support for better debugging tools. | +| 3.2.25 | 2023-11-29 | [32961](https://github.com/airbytehq/airbyte/pull/32961) | Bump debezium wait time default to 20 min. | +| 3.2.24 | 2023-11-28 | [32686](https://github.com/airbytehq/airbyte/pull/32686) | Better logging to understand dbz closing reason attribution. | +| 3.2.23 | 2023-11-28 | [32891](https://github.com/airbytehq/airbyte/pull/32891) | Fix CDK dependency in build. | +| 3.2.22 | 2023-11-22 | [32656](https://github.com/airbytehq/airbyte/pull/32656) | Adopt java CDK version 0.5.0. | +| 3.2.21 | 2023-11-07 | [31856](https://github.com/airbytehq/airbyte/pull/31856) | handle date/timestamp infinity values properly | +| 3.2.20 | 2023-11-06 | [32193](https://github.com/airbytehq/airbyte/pull/32193) | Adopt java CDK version 0.4.1. | +| 3.2.19 | 2023-11-03 | [32050](https://github.com/airbytehq/airbyte/pull/32050) | Adopt java CDK version 0.4.0. | +| 3.2.18 | 2023-11-01 | [29038](https://github.com/airbytehq/airbyte/pull/29038) | Fix typo (s/Airbtye/Airbyte/) | +| 3.2.17 | 2023-11-01 | [32068](https://github.com/airbytehq/airbyte/pull/32068) | Bump Debezium 2.2.0Final -> 2.4.0Final | +| 3.2.16 | 2023-10-31 | [31976](https://github.com/airbytehq/airbyte/pull/31976) | Speed up tests involving Debezium | +| 3.2.15 | 2023-10-30 | [31960](https://github.com/airbytehq/airbyte/pull/31960) | Adopt java CDK version 0.2.0. | +| 3.2.14 | 2023-10-24 | [31792](https://github.com/airbytehq/airbyte/pull/31792) | Fix error message link on issue with standby | +| 3.2.14 | 2023-10-24 | [31792](https://github.com/airbytehq/airbyte/pull/31792) | fail sync when debezeum fails to shutdown cleanly | +| 3.2.13 | 2023-10-16 | [31029](https://github.com/airbytehq/airbyte/pull/31029) | Enforces encrypted traffic settings when env var DEPLOYMENT_MODE = CLOUD. | +| 3.1.13 | 2023-10-13 | [31309](https://github.com/airbytehq/airbyte/pull/31309) | Addressed decimals being incorrectly deserialized into scientific notation. | +| 3.1.12 | 2023-10-12 | [31328](https://github.com/airbytehq/airbyte/pull/31328) | Improvements to initial load of tables in older versions of postgres. | +| 3.1.11 | 2023-10-11 | [31322](https://github.com/airbytehq/airbyte/pull/31322) | Correct pevious release | +| 3.1.10 | 2023-09-29 | [30806](https://github.com/airbytehq/airbyte/pull/30806) | Cap log line length to 32KB to prevent loss of records. | +| 3.1.9 | 2023-09-25 | [30534](https://github.com/airbytehq/airbyte/pull/30534) | Fix JSONB[] column type handling bug. | +| 3.1.8 | 2023-09-20 | [30125](https://github.com/airbytehq/airbyte/pull/30125) | Improve initial load performance for older versions of PostgreSQL. | +| 3.1.7 | 2023-09-05 | [29672](https://github.com/airbytehq/airbyte/pull/29672) | Handle VACUUM happening during initial sync | +| 3.1.6 | 2023-08-24 | [29821](https://github.com/airbytehq/airbyte/pull/29821) | Set replication_method display_type to radio, update titles and descriptions, and make CDC the default choice | +| 3.1.5 | 2023-08-22 | [29534](https://github.com/airbytehq/airbyte/pull/29534) | Support "options" JDBC URL parameter | +| 3.1.4 | 2023-08-21 | [28687](https://github.com/airbytehq/airbyte/pull/28687) | Under the hood: Add dependency on Java CDK v0.0.2. | +| 3.1.3 | 2023-08-03 | [28708](https://github.com/airbytehq/airbyte/pull/28708) | Enable checkpointing snapshots in CDC connections | +| 3.1.2 | 2023-08-01 | [28954](https://github.com/airbytehq/airbyte/pull/28954) | Fix an issue that prevented use of tables with names containing uppercase letters | +| 3.1.1 | 2023-07-31 | [28892](https://github.com/airbytehq/airbyte/pull/28892) | Fix an issue that prevented use of cursor columns with names containing uppercase letters | +| 3.1.0 | 2023-07-25 | [28339](https://github.com/airbytehq/airbyte/pull/28339) | Checkpointing initial load for incremental syncs: enabled for xmin and cursor based only. | +| 3.0.2 | 2023-07-18 | [28336](https://github.com/airbytehq/airbyte/pull/28336) | Add full-refresh mode back to Xmin syncs. | +| 3.0.1 | 2023-07-14 | [28345](https://github.com/airbytehq/airbyte/pull/28345) | Increment patch to trigger a rebuild | +| 3.0.0 | 2023-07-12 | [27442](https://github.com/airbytehq/airbyte/pull/27442) | Set \_ab_cdc_lsn as the source defined cursor for CDC mode to prepare for Destination v2 normalization | +| 2.1.1 | 2023-07-06 | [26723](https://github.com/airbytehq/airbyte/pull/26723) | Add new xmin replication method. | +| 2.1.0 | 2023-06-26 | [27737](https://github.com/airbytehq/airbyte/pull/27737) | License Update: Elv2 | +| 2.0.34 | 2023-06-20 | [27212](https://github.com/airbytehq/airbyte/pull/27212) | Fix silent exception swallowing in StreamingJdbcDatabase | +| 2.0.33 | 2023-06-01 | [26873](https://github.com/airbytehq/airbyte/pull/26873) | Add prepareThreshold=0 to JDBC url to mitigate PGBouncer prepared statement [X] already exists. | +| 2.0.32 | 2023-05-31 | [26810](https://github.com/airbytehq/airbyte/pull/26810) | Remove incremental sync estimate from Postgres to increase performance. | +| 2.0.31 | 2023-05-25 | [26633](https://github.com/airbytehq/airbyte/pull/26633) | Collect and log information related to full vacuum operation in db | +| 2.0.30 | 2023-05-25 | [26473](https://github.com/airbytehq/airbyte/pull/26473) | CDC : Limit queue size | +| 2.0.29 | 2023-05-18 | [25898](https://github.com/airbytehq/airbyte/pull/25898) | Translate Numeric values without decimal, e.g: NUMERIC(38,0), as BigInt instead of Double | +| 2.0.28 | 2023-04-27 | [25401](https://github.com/airbytehq/airbyte/pull/25401) | CDC : Upgrade Debezium to version 2.2.0 | +| 2.0.27 | 2023-04-26 | [24971](https://github.com/airbytehq/airbyte/pull/24971) | Emit stream status updates | +| 2.0.26 | 2023-04-26 | [25560](https://github.com/airbytehq/airbyte/pull/25560) | Revert some logging changes | +| 2.0.25 | 2023-04-24 | [25459](https://github.com/airbytehq/airbyte/pull/25459) | Better logging formatting | +| 2.0.24 | 2023-04-19 | [25345](https://github.com/airbytehq/airbyte/pull/25345) | Logging : Log database indexes per stream | +| 2.0.23 | 2023-04-19 | [24582](https://github.com/airbytehq/airbyte/pull/24582) | CDC : Enable frequent state emission during incremental syncs + refactor for performance improvement | +| 2.0.22 | 2023-04-17 | [25220](https://github.com/airbytehq/airbyte/pull/25220) | Logging changes : Log additional metadata & clean up noisy logs | +| 2.0.21 | 2023-04-12 | [25131](https://github.com/airbytehq/airbyte/pull/25131) | Make Client Certificate and Client Key always show | +| 2.0.20 | 2023-04-11 | [24859](https://github.com/airbytehq/airbyte/pull/24859) | Removed SSL toggle and rely on SSL mode dropdown to enable/disable SSL | +| 2.0.19 | 2023-04-11 | [24656](https://github.com/airbytehq/airbyte/pull/24656) | CDC minor refactor | +| 2.0.18 | 2023-04-06 | [24820](https://github.com/airbytehq/airbyte/pull/24820) | Fix data loss bug during an initial failed non-CDC incremental sync | +| 2.0.17 | 2023-04-05 | [24622](https://github.com/airbytehq/airbyte/pull/24622) | Allow streams not in CDC publication to be synced in Full-refresh mode | +| 2.0.16 | 2023-04-05 | [24895](https://github.com/airbytehq/airbyte/pull/24895) | Fix spec for cloud | +| 2.0.15 | 2023-04-04 | [24833](https://github.com/airbytehq/airbyte/pull/24833) | Fix Debezium retry policy configuration | +| 2.0.14 | 2023-04-03 | [24609](https://github.com/airbytehq/airbyte/pull/24609) | Disallow the "disable" SSL Modes | +| 2.0.13 | 2023-03-28 | [24166](https://github.com/airbytehq/airbyte/pull/24166) | Fix InterruptedException bug during Debezium shutdown | +| 2.0.12 | 2023-03-27 | [24529](https://github.com/airbytehq/airbyte/pull/24373) | Add CDC checkpoint state messages | +| 2.0.11 | 2023-03-23 | [24446](https://github.com/airbytehq/airbyte/pull/24446) | Set default SSL Mode to require in strict-encrypt | +| 2.0.10 | 2023-03-23 | [24417](https://github.com/airbytehq/airbyte/pull/24417) | Add field groups and titles to improve display of connector setup form | +| 2.0.9 | 2023-03-22 | [20760](https://github.com/airbytehq/airbyte/pull/20760) | Removed redundant date-time datatypes formatting | +| 2.0.8 | 2023-03-22 | [24255](https://github.com/airbytehq/airbyte/pull/24255) | Add field groups and titles to improve display of connector setup form | +| 2.0.7 | 2023-03-21 | [24207](https://github.com/airbytehq/airbyte/pull/24207) | Fix incorrect schema change warning in CDC mode | +| 2.0.6 | 2023-03-21 | [24271](https://github.com/airbytehq/airbyte/pull/24271) | Fix NPE in CDC mode | +| 2.0.5 | 2023-03-21 | [21533](https://github.com/airbytehq/airbyte/pull/21533) | Add integration with datadog | +| 2.0.4 | 2023-03-21 | [24147](https://github.com/airbytehq/airbyte/pull/24275) | Fix error with CDC checkpointing | +| 2.0.3 | 2023-03-14 | [24000](https://github.com/airbytehq/airbyte/pull/24000) | Removed check method call on read. | +| 2.0.2 | 2023-03-13 | [23112](https://github.com/airbytehq/airbyte/pull/21727) | Add state checkpointing for CDC sync. | +| 2.0.0 | 2023-03-06 | [23112](https://github.com/airbytehq/airbyte/pull/23112) | Upgrade Debezium version to 2.1.2 | +| 1.0.51 | 2023-03-02 | [23642](https://github.com/airbytehq/airbyte/pull/23642) | Revert : Support JSONB datatype for Standard sync mode | +| 1.0.50 | 2023-02-27 | [21695](https://github.com/airbytehq/airbyte/pull/21695) | Support JSONB datatype for Standard sync mode | +| 1.0.49 | 2023-02-24 | [23383](https://github.com/airbytehq/airbyte/pull/23383) | Fixed bug with non readable double-quoted values within a database name or column name | +| 1.0.48 | 2023-02-23 | [22623](https://github.com/airbytehq/airbyte/pull/22623) | Increase max fetch size of JDBC streaming mode | +| 1.0.47 | 2023-02-22 | [22221](https://github.com/airbytehq/airbyte/pull/23138) | Fix previous versions which doesn't verify privileges correctly, preventing CDC syncs to run. | +| 1.0.46 | 2023-02-21 | [23105](https://github.com/airbytehq/airbyte/pull/23105) | Include log levels and location information (class, method and line number) with source connector logs published to Airbyte Platform. | +| 1.0.45 | 2023-02-09 | [22221](https://github.com/airbytehq/airbyte/pull/22371) | Ensures that user has required privileges for CDC syncs. | +| | 2023-02-15 | [23028](https://github.com/airbytehq/airbyte/pull/23028) | | +| 1.0.44 | 2023-02-06 | [22221](https://github.com/airbytehq/airbyte/pull/22221) | Exclude new set of system tables when using `pg_stat_statements` extension. | +| 1.0.43 | 2023-02-06 | [21634](https://github.com/airbytehq/airbyte/pull/21634) | Improve Standard sync performance by caching objects. | +| 1.0.42 | 2023-01-23 | [21523](https://github.com/airbytehq/airbyte/pull/21523) | Check for null in cursor values before replacing. | +| 1.0.41 | 2023-01-25 | [20939](https://github.com/airbytehq/airbyte/pull/20939) | Adjust batch selection memory limits databases. | +| 1.0.40 | 2023-01-24 | [21825](https://github.com/airbytehq/airbyte/pull/21825) | Put back the original change that will cause an incremental sync to error if table contains a NULL value in cursor column. | +| 1.0.39 | 2023-01-20 | [21683](https://github.com/airbytehq/airbyte/pull/21683) | Speed up esmtimates for trace messages in non-CDC mode. | +| 1.0.38 | 2023-01-17 | [20436](https://github.com/airbytehq/airbyte/pull/20346) | Consolidate date/time values mapping for JDBC sources | +| 1.0.37 | 2023-01-17 | [20783](https://github.com/airbytehq/airbyte/pull/20783) | Emit estimate trace messages for non-CDC mode. | +| 1.0.36 | 2023-01-11 | [21003](https://github.com/airbytehq/airbyte/pull/21003) | Handle null values for array data types in CDC mode gracefully. | +| 1.0.35 | 2023-01-04 | [20469](https://github.com/airbytehq/airbyte/pull/20469) | Introduce feature to make LSN commit behaviour configurable. | +| 1.0.34 | 2022-12-13 | [20378](https://github.com/airbytehq/airbyte/pull/20378) | Improve descriptions | +| 1.0.33 | 2022-12-12 | [18959](https://github.com/airbytehq/airbyte/pull/18959) | CDC : Don't timeout if snapshot is not complete. | +| 1.0.32 | 2022-12-12 | [20192](https://github.com/airbytehq/airbyte/pull/20192) | Only throw a warning if cursor column contains null values. | +| 1.0.31 | 2022-12-02 | [19889](https://github.com/airbytehq/airbyte/pull/19889) | Check before each sync and stop if an incremental sync cursor column contains a null value. | +| | 2022-12-02 | [19985](https://github.com/airbytehq/airbyte/pull/19985) | Reenable incorrectly-disabled `wal2json` CDC plugin | +| 1.0.30 | 2022-11-29 | [19024](https://github.com/airbytehq/airbyte/pull/19024) | Skip tables from schema where user do not have Usage permission during discovery. | +| 1.0.29 | 2022-11-29 | [19623](https://github.com/airbytehq/airbyte/pull/19623) | Mark PSQLException related to using replica that is configured as a hot standby server as config error. | +| 1.0.28 | 2022-11-28 | [19514](https://github.com/airbytehq/airbyte/pull/19514) | Adjust batch selection memory limits databases. | +| 1.0.27 | 2022-11-28 | [16990](https://github.com/airbytehq/airbyte/pull/16990) | Handle arrays data types | +| 1.0.26 | 2022-11-18 | [19551](https://github.com/airbytehq/airbyte/pull/19551) | Fixes bug with ssl modes | +| 1.0.25 | 2022-11-16 | [19004](https://github.com/airbytehq/airbyte/pull/19004) | Use Debezium heartbeats to improve CDC replication of large databases. | +| 1.0.24 | 2022-11-07 | [19291](https://github.com/airbytehq/airbyte/pull/19291) | Default timeout is reduced from 1 min to 10sec | +| 1.0.23 | 2022-11-07 | [19025](https://github.com/airbytehq/airbyte/pull/19025) | Stop enforce SSL if ssl mode is disabled | +| 1.0.22 | 2022-10-31 | [18538](https://github.com/airbytehq/airbyte/pull/18538) | Encode database name | +| 1.0.21 | 2022-10-25 | [18256](https://github.com/airbytehq/airbyte/pull/18256) | Disable allow and prefer ssl modes in CDC mode | +| 1.0.20 | 2022-10-25 | [18383](https://github.com/airbytehq/airbyte/pull/18383) | Better SSH error handling + messages | +| 1.0.19 | 2022-10-21 | [18263](https://github.com/airbytehq/airbyte/pull/18263) | Fixes bug introduced in [15833](https://github.com/airbytehq/airbyte/pull/15833) and adds better error messaging for SSH tunnel in Destinations | +| 1.0.18 | 2022-10-19 | [18087](https://github.com/airbytehq/airbyte/pull/18087) | Better error messaging for configuration errors (SSH configs, choosing an invalid cursor) | +| 1.0.17 | 2022-10-17 | [18041](https://github.com/airbytehq/airbyte/pull/18041) | Fixes bug introduced 2022-09-12 with SshTunnel, handles iterator exception properly | +| 1.0.16 | 2022-10-13 | [15535](https://github.com/airbytehq/airbyte/pull/16238) | Update incremental query to avoid data missing when new data is inserted at the same time as a sync starts under non-CDC incremental mode | +| 1.0.15 | 2022-10-11 | [17782](https://github.com/airbytehq/airbyte/pull/17782) | Handle 24:00:00 value for Time column | +| 1.0.14 | 2022-10-03 | [17515](https://github.com/airbytehq/airbyte/pull/17515) | Fix an issue preventing connection using client certificate | +| 1.0.13 | 2022-10-01 | [17459](https://github.com/airbytehq/airbyte/pull/17459) | Upgrade debezium version to 1.9.6 from 1.9.2 | +| 1.0.12 | 2022-09-27 | [17299](https://github.com/airbytehq/airbyte/pull/17299) | Improve error handling for strict-encrypt postgres source | +| 1.0.11 | 2022-09-26 | [17131](https://github.com/airbytehq/airbyte/pull/17131) | Allow nullable columns to be used as cursor | +| 1.0.10 | 2022-09-14 | [15668](https://github.com/airbytehq/airbyte/pull/15668) | Wrap logs in AirbyteLogMessage | +| 1.0.9 | 2022-09-13 | [16657](https://github.com/airbytehq/airbyte/pull/16657) | Improve CDC record queueing performance | +| 1.0.8 | 2022-09-08 | [16202](https://github.com/airbytehq/airbyte/pull/16202) | Adds error messaging factory to UI | +| 1.0.7 | 2022-08-30 | [16114](https://github.com/airbytehq/airbyte/pull/16114) | Prevent traffic going on an unsecured channel in strict-encryption version of source postgres | +| 1.0.6 | 2022-08-30 | [16138](https://github.com/airbytehq/airbyte/pull/16138) | Remove unnecessary logging | +| 1.0.5 | 2022-08-25 | [15993](https://github.com/airbytehq/airbyte/pull/15993) | Add support for connection over SSL in CDC mode | +| 1.0.4 | 2022-08-23 | [15877](https://github.com/airbytehq/airbyte/pull/15877) | Fix temporal data type bug which was causing failure in CDC mode | +| 1.0.3 | 2022-08-18 | [14356](https://github.com/airbytehq/airbyte/pull/14356) | DB Sources: only show a table can sync incrementally if at least one column can be used as a cursor field | +| 1.0.2 | 2022-08-11 | [15538](https://github.com/airbytehq/airbyte/pull/15538) | Allow additional properties in db stream state | +| 1.0.1 | 2022-08-10 | [15496](https://github.com/airbytehq/airbyte/pull/15496) | Fix state emission in incremental sync | +| | 2022-08-10 | [15481](https://github.com/airbytehq/airbyte/pull/15481) | Fix data handling from WAL logs in CDC mode | +| 1.0.0 | 2022-08-05 | [15380](https://github.com/airbytehq/airbyte/pull/15380) | Change connector label to generally_available (requires [upgrading](https://docs.airbyte.com/operator-guides/upgrading-airbyte/) your Airbyte platform to `v0.40.0-alpha`) | +| 0.4.44 | 2022-08-05 | [15342](https://github.com/airbytehq/airbyte/pull/15342) | Adjust titles and descriptions in spec.json | +| 0.4.43 | 2022-08-03 | [15226](https://github.com/airbytehq/airbyte/pull/15226) | Make connectionTimeoutMs configurable through JDBC url parameters | +| 0.4.42 | 2022-08-03 | [15273](https://github.com/airbytehq/airbyte/pull/15273) | Fix a bug in `0.4.36` and correctly parse the CDC initial record waiting time | +| 0.4.41 | 2022-08-03 | [15077](https://github.com/airbytehq/airbyte/pull/15077) | Sync data from beginning if the LSN is no longer valid in CDC | +| | 2022-08-03 | [14903](https://github.com/airbytehq/airbyte/pull/14903) | Emit state messages more frequently (⛔ this version has a bug; use `1.0.1` instead | +| 0.4.40 | 2022-08-03 | [15187](https://github.com/airbytehq/airbyte/pull/15187) | Add support for BCE dates/timestamps | +| | 2022-08-03 | [14534](https://github.com/airbytehq/airbyte/pull/14534) | Align regular and CDC integration tests and data mappers | +| 0.4.39 | 2022-08-02 | [14801](https://github.com/airbytehq/airbyte/pull/14801) | Fix multiple log bindings | +| 0.4.38 | 2022-07-26 | [14362](https://github.com/airbytehq/airbyte/pull/14362) | Integral columns are now discovered as int64 fields. | +| 0.4.37 | 2022-07-22 | [14714](https://github.com/airbytehq/airbyte/pull/14714) | Clarified error message when invalid cursor column selected | +| 0.4.36 | 2022-07-21 | [14451](https://github.com/airbytehq/airbyte/pull/14451) | Make initial CDC waiting time configurable (⛔ this version has a bug and will not work; use `0.4.42` instead) | +| 0.4.35 | 2022-07-14 | [14574](https://github.com/airbytehq/airbyte/pull/14574) | Removed additionalProperties:false from JDBC source connectors | +| 0.4.34 | 2022-07-17 | [13840](https://github.com/airbytehq/airbyte/pull/13840) | Added the ability to connect using different SSL modes and SSL certificates. | +| 0.4.33 | 2022-07-14 | [14586](https://github.com/airbytehq/airbyte/pull/14586) | Validate source JDBC url parameters | +| 0.4.32 | 2022-07-07 | [14694](https://github.com/airbytehq/airbyte/pull/14694) | Force to produce LEGACY state if the use stream capable feature flag is set to false | +| 0.4.31 | 2022-07-07 | [14447](https://github.com/airbytehq/airbyte/pull/14447) | Under CDC mode, retrieve only those tables included in the publications | +| 0.4.30 | 2022-06-30 | [14251](https://github.com/airbytehq/airbyte/pull/14251) | Use more simple and comprehensive query to get selectable tables | +| 0.4.29 | 2022-06-29 | [14265](https://github.com/airbytehq/airbyte/pull/14265) | Upgrade postgresql JDBC version to 42.3.5 | +| 0.4.28 | 2022-06-23 | [14077](https://github.com/airbytehq/airbyte/pull/14077) | Use the new state management | +| 0.4.26 | 2022-06-17 | [13864](https://github.com/airbytehq/airbyte/pull/13864) | Updated stacktrace format for any trace message errors | +| 0.4.25 | 2022-06-15 | [13823](https://github.com/airbytehq/airbyte/pull/13823) | Publish adaptive postgres source that enforces ssl on cloud + Debezium version upgrade to 1.9.2 from 1.4.2 | +| 0.4.24 | 2022-06-14 | [13549](https://github.com/airbytehq/airbyte/pull/13549) | Fixed truncated precision if the value of microseconds or seconds is 0 | +| 0.4.23 | 2022-06-13 | [13655](https://github.com/airbytehq/airbyte/pull/13745) | Fixed handling datetime cursors when upgrading from older versions of the connector | +| 0.4.22 | 2022-06-09 | [13655](https://github.com/airbytehq/airbyte/pull/13655) | Fixed bug with unsupported date-time datatypes during incremental sync | +| 0.4.21 | 2022-06-06 | [13435](https://github.com/airbytehq/airbyte/pull/13435) | Adjust JDBC fetch size based on max memory and max row size | +| 0.4.20 | 2022-06-02 | [13367](https://github.com/airbytehq/airbyte/pull/13367) | Added convertion hstore to json format | +| 0.4.19 | 2022-05-25 | [13166](https://github.com/airbytehq/airbyte/pull/13166) | Added timezone awareness and handle BC dates | +| 0.4.18 | 2022-05-25 | [13083](https://github.com/airbytehq/airbyte/pull/13083) | Add support for tsquey type | +| 0.4.17 | 2022-05-19 | [13016](https://github.com/airbytehq/airbyte/pull/13016) | CDC modify schema to allow null values | +| 0.4.16 | 2022-05-14 | [12840](https://github.com/airbytehq/airbyte/pull/12840) | Added custom JDBC parameters field | +| 0.4.15 | 2022-05-13 | [12834](https://github.com/airbytehq/airbyte/pull/12834) | Fix the bug that the connector returns empty catalog for Azure Postgres database | +| 0.4.14 | 2022-05-08 | [12689](https://github.com/airbytehq/airbyte/pull/12689) | Add table retrieval according to role-based `SELECT` privilege | +| 0.4.13 | 2022-05-05 | [10230](https://github.com/airbytehq/airbyte/pull/10230) | Explicitly set null value for field in json | +| 0.4.12 | 2022-04-29 | [12480](https://github.com/airbytehq/airbyte/pull/12480) | Query tables with adaptive fetch size to optimize JDBC memory consumption | +| 0.4.11 | 2022-04-11 | [11729](https://github.com/airbytehq/airbyte/pull/11729) | Bump mina-sshd from 2.7.0 to 2.8.0 | +| 0.4.10 | 2022-04-08 | [11798](https://github.com/airbytehq/airbyte/pull/11798) | Fixed roles for fetching materialized view processing | +| 0.4.8 | 2022-02-21 | [10242](https://github.com/airbytehq/airbyte/pull/10242) | Fixed cursor for old connectors that use non-microsecond format. Now connectors work with both formats | +| 0.4.7 | 2022-02-18 | [10242](https://github.com/airbytehq/airbyte/pull/10242) | Updated timestamp transformation with microseconds | +| 0.4.6 | 2022-02-14 | [10256](https://github.com/airbytehq/airbyte/pull/10256) | (unpublished) Add `-XX:+ExitOnOutOfMemoryError` JVM option | +| 0.4.5 | 2022-02-08 | [10173](https://github.com/airbytehq/airbyte/pull/10173) | Improved discovering tables in case if user does not have permissions to any table | +| 0.4.4 | 2022-01-26 | [9807](https://github.com/airbytehq/airbyte/pull/9807) | Update connector fields title/description | +| 0.4.3 | 2022-01-24 | [9554](https://github.com/airbytehq/airbyte/pull/9554) | Allow handling of java sql date in CDC | +| 0.4.2 | 2022-01-13 | [9360](https://github.com/airbytehq/airbyte/pull/9360) | Added schema selection | +| 0.4.1 | 2022-01-05 | [9116](https://github.com/airbytehq/airbyte/pull/9116) | Added materialized views processing | +| 0.4.0 | 2021-12-13 | [8726](https://github.com/airbytehq/airbyte/pull/8726) | Support all Postgres types | +| 0.3.17 | 2021-12-01 | [8371](https://github.com/airbytehq/airbyte/pull/8371) | Fixed incorrect handling "\n" in ssh key | +| 0.3.16 | 2021-11-28 | [7995](https://github.com/airbytehq/airbyte/pull/7995) | Fixed money type with amount > 1000 | +| 0.3.15 | 2021-11-26 | [8066](https://github.com/airbytehq/airbyte/pull/8266) | Fixed the case, when Views are not listed during schema discovery | +| 0.3.14 | 2021-11-17 | [8010](https://github.com/airbytehq/airbyte/pull/8010) | Added checking of privileges before table internal discovery | +| 0.3.13 | 2021-10-26 | [7339](https://github.com/airbytehq/airbyte/pull/7339) | Support or improve support for Interval, Money, Date, various geometric data types, inventory_items, and others | +| 0.3.12 | 2021-09-30 | [6585](https://github.com/airbytehq/airbyte/pull/6585) | Improved SSH Tunnel key generation steps | +| 0.3.11 | 2021-09-02 | [5742](https://github.com/airbytehq/airbyte/pull/5742) | Add SSH Tunnel support | +| 0.3.9 | 2021-08-17 | [5304](https://github.com/airbytehq/airbyte/pull/5304) | Fix CDC OOM issue | +| 0.3.8 | 2021-08-13 | [4699](https://github.com/airbytehq/airbyte/pull/4699) | Added json config validator | +| 0.3.4 | 2021-06-09 | [3973](https://github.com/airbytehq/airbyte/pull/3973) | Add `AIRBYTE_ENTRYPOINT` for Kubernetes support | +| 0.3.3 | 2021-06-08 | [3960](https://github.com/airbytehq/airbyte/pull/3960) | Add method field in specification parameters | +| 0.3.2 | 2021-05-26 | [3179](https://github.com/airbytehq/airbyte/pull/3179) | Remove `isCDC` logging | +| 0.3.1 | 2021-04-21 | [2878](https://github.com/airbytehq/airbyte/pull/2878) | Set defined cursor for CDC | +| 0.3.0 | 2021-04-21 | [2990](https://github.com/airbytehq/airbyte/pull/2990) | Support namespaces | +| 0.2.7 | 2021-04-16 | [2923](https://github.com/airbytehq/airbyte/pull/2923) | SSL spec as optional | +| 0.2.6 | 2021-04-16 | [2757](https://github.com/airbytehq/airbyte/pull/2757) | Support SSL connection | +| 0.2.5 | 2021-04-12 | [2859](https://github.com/airbytehq/airbyte/pull/2859) | CDC bugfix | +| 0.2.4 | 2021-04-09 | [2548](https://github.com/airbytehq/airbyte/pull/2548) | Support CDC | +| 0.2.3 | 2021-03-28 | [2600](https://github.com/airbytehq/airbyte/pull/2600) | Add NCHAR and NVCHAR support to DB and cursor type casting | +| 0.2.2 | 2021-03-26 | [2460](https://github.com/airbytehq/airbyte/pull/2460) | Destination supports destination sync mode | +| 0.2.1 | 2021-03-18 | [2488](https://github.com/airbytehq/airbyte/pull/2488) | Sources support primary keys | +| 0.2.0 | 2021-03-09 | [2238](https://github.com/airbytehq/airbyte/pull/2238) | Protocol allows future/unknown properties | +| 0.1.13 | 2021-02-02 | [1887](https://github.com/airbytehq/airbyte/pull/1887) | Migrate AbstractJdbcSource to use iterators | +| 0.1.12 | 2021-01-25 | [1746](https://github.com/airbytehq/airbyte/pull/1746) | Fix NPE in State Decorator | +| 0.1.11 | 2021-01-25 | [1765](https://github.com/airbytehq/airbyte/pull/1765) | Add field titles to specification | +| 0.1.10 | 2021-01-19 | [1724](https://github.com/airbytehq/airbyte/pull/1724) | Fix JdbcSource handling of tables with same names in different schemas | +| 0.1.9 | 2021-01-14 | [1655](https://github.com/airbytehq/airbyte/pull/1655) | Fix JdbcSource OOM | +| 0.1.8 | 2021-01-13 | [1588](https://github.com/airbytehq/airbyte/pull/1588) | Handle invalid numeric values in JDBC source | +| 0.1.7 | 2021-01-08 | [1307](https://github.com/airbytehq/airbyte/pull/1307) | Migrate Postgres and MySql to use new JdbcSource | +| 0.1.6 | 2020-12-09 | [1172](https://github.com/airbytehq/airbyte/pull/1172) | Support incremental sync | +| 0.1.5 | 2020-11-30 | [1038](https://github.com/airbytehq/airbyte/pull/1038) | Change JDBC sources to discover more than standard schemas | +| 0.1.4 | 2020-11-30 | [1046](https://github.com/airbytehq/airbyte/pull/1046) | Add connectors using an index YAML file |
diff --git a/docs/integrations/sources/postgres/postgres-troubleshooting.md b/docs/integrations/sources/postgres/postgres-troubleshooting.md index dfe26312a53b..a19696c5eb05 100644 --- a/docs/integrations/sources/postgres/postgres-troubleshooting.md +++ b/docs/integrations/sources/postgres/postgres-troubleshooting.md @@ -1,10 +1,12 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + # Troubleshooting Postgres Sources ## Connector Limitations ### General Limitations -- The Postgres source connector currently does not handle schemas larger than 4MB. - The Postgres source connector does not alter the schema present in your database. Depending on the destination connected to this source, however, the schema may be altered. See the destination's documentation for more details. - The following two schema evolution actions are currently supported: - Adding/removing tables without resetting the entire connection at the destination @@ -13,7 +15,9 @@ - Changing a column data type or removing a column might break connections. ### Xmin Limitations + There are some notable shortcomings associated with the Xmin replication method: + - Unsupported DDL operations : This replication method cannot support row deletions. - Performance : Requires a full table scan, so can lead to poor performance. - Row-level granularity : The xmin column is stored at the row level. This means that a row will still be synced if it had been modified, regardless of whether the modification corresponded to the subset of columns the user is interested in. @@ -97,9 +101,9 @@ Caused by: org.postgresql.util.PSQLException: FATAL: terminating connection due Possible solutions include: -- [Recommended] Set [`hot_standby_feedback`](https://www.postgresql.org/docs/14/runtime-config-replication.html#GUC-HOT-STANDBY-FEEDBACK) to `true` on the replica server. This parameter will prevent the primary server from deleting the write-ahead logs when the replica is busy serving user queries. However, the downside is that the write-ahead log will increase in size. -- [Recommended] Sync data when there is no update running in the primary server, or sync data from the primary server. -- [Not Recommended] Increase [`max_standby_archive_delay`](https://www.postgresql.org/docs/14/runtime-config-replication.html#GUC-MAX-STANDBY-ARCHIVE-DELAY) and [`max_standby_streaming_delay`](https://www.postgresql.org/docs/14/runtime-config-replication.html#GUC-MAX-STANDBY-STREAMING-DELAY) to be larger than the amount of time needed to complete the data sync. However, it is usually hard to tell how much time it will take to sync all the data. This approach is not very practical. +- Recommended: Set [`hot_standby_feedback`](https://www.postgresql.org/docs/14/runtime-config-replication.html#GUC-HOT-STANDBY-FEEDBACK) to `true` on the replica server. This parameter will prevent the primary server from deleting the write-ahead logs when the replica is busy serving user queries. However, the downside is that the write-ahead log will increase in size. +- Recommended: Sync data when there is no update running in the primary server, or sync data from the primary server. +- Not Recommended: Increase [`max_standby_archive_delay`](https://www.postgresql.org/docs/14/runtime-config-replication.html#GUC-MAX-STANDBY-ARCHIVE-DELAY) and [`max_standby_streaming_delay`](https://www.postgresql.org/docs/14/runtime-config-replication.html#GUC-MAX-STANDBY-STREAMING-DELAY) to be larger than the amount of time needed to complete the data sync. However, it is usually hard to tell how much time it will take to sync all the data. This approach is not very practical. ### Under CDC incremental mode, there are still full refresh syncs @@ -146,14 +150,161 @@ The connector waits for the default initial wait time of 5 minutes (300 seconds) If you know there are database changes to be synced, but the connector cannot read those changes, the root cause may be insufficient waiting time. In that case, you can increase the waiting time (example: set to 600 seconds) to test if it is indeed the root cause. On the other hand, if you know there are no database changes, you can decrease the wait time to speed up the zero record syncs. -### (Advanced) WAL disk consumption and heartbeat action query +### (Advanced) Resolving sync failures due to WAL disk consumption {#advanced-wal-disk-consumption-and-heartbeat-action-query} + +When using the `Read Changes using Write-Ahead Log (CDC)` update method, you might encounter a situation where your initial sync is successful, but further syncs fail. You may also notice that the `confirmed_flush_lsn` column of the server's `pg_replication_slots` view doesn't advance as expected. + +This is a general issue that affects databases, schemas, and tables with small transaction volumes. There are complexities in the way PostgreSQL disk space can be consumed by WAL files, and these can cause issues for the connector when dealing with low transaction volumes. Airbyte's connector depends on Debezium. These complexities are outlined in [their documentation](https://debezium.io/documentation/reference/stable/connectors/postgresql.html#postgresql-wal-disk-space), if you want to learn more. + +#### Simple fix (read-only) + +The easiest way to fix this issue is to add one or more tables with high transaction volumes to the Airbyte publication. You do not need to actually sync these tables, but adding them to the publication will advance the log sequence number (LSN), ensuring the sync can succeed without you giving Airbyte write access to the database. However, this may greatly increase disk consumption. -In certain situations, WAL disk consumption increases. This can occur when there are a large volume of changes, but only a small percentage of them are being made to the databases, schemas and tables configured for capture. +```sql +ALTER PUBLICATION ADD TABLE ; +``` + +If you do not want to increase disk consumption, use the following solutions, which require write access. + +#### Fix when reading against a primary or standalone (write) + +To fix the issue when reading against primary or standalone, artificially add events to a heartbeat table the Airbyte user can write to. -A workaround for this situation is to artificially add events to a heartbeat table that the Airbyte use has write access to. This will ensure that Airbyte can process the WAL and prevent disk space to spike. To configure this: +1. Create an `airbyte_heartbeat` table in the database and schema being tracked. + + ```sql + CREATE TABLE airbyte_heartbeat ( + id SERIAL PRIMARY KEY, + timestamp TIMESTAMP NOT NULL DEFAULT current_timestamp, + text TEXT + ); + ``` -1. Create a table (e.g. `airbyte_heartbeat`) in the database and schema being tracked. 2. Add this table to the airbyte publication. -3. Configure the `heartbeat_action_query` property while setting up the source-postgres connector. This query will be periodically executed by Airbyte on the `airbyte_heartbeat` table. For example, this param can be set to a query like `INSERT INTO airbyte_heartbeat (text) VALUES ('heartbeat')`. -See detailed documentation [here](https://debezium.io/documentation/reference/stable/connectors/postgresql.html#postgresql-wal-disk-space). + ```sql + ALTER PUBLICATION ADD TABLE airbyte_heartbeat; + ``` + +3. In the Postgres source connector in Airbyte, configure the `Debezium heartbeat query` property. For example: + + ```sql + INSERT INTO airbyte_heartbeat (text) VALUES ('heartbeat') + ``` + +Airbyte periodically executes this query on the `airbyte_heartbeat` table. + +#### Fix when reading against a read replica (write) + +To fix the issue when reading against a read replica: + +1. [Add pg_cron as an extension](#wal-pg-cron). +2. [Periodically add events](#wal-heartbeat-table) to a heartbeat table your Airbyte user can write to. + +##### Add the pg_cron extension {#wal-pg-cron} + +[pg_cron](https://github.com/citusdata/pg_cron) is a cron-based job scheduler for PostgreSQL that runs inside the database as an extension so you can schedule PostgreSQL commands directly from the database. + + + + +1. Ensure your PostgreSQL instance is version 10 or higher. Version 10 is the minimum version that supports pg_cron. + + ```sql + SELECT version(); + ``` + +2. Configure your database flags to enable pg_cron. For help with this, see [Google Cloud's docs](https://cloud.google.com/sql/docs/postgres/flags). + + 1. Set the `cloudsql.enable_pg_cron` flag to `on`. For more information, see [Google Cloud's docs](https://cloud.google.com/sql/docs/postgres/extensions#pg_cron). + + 2. Set the `shared_preload_libraries` flag to include `pg_cron`. + + ``` + shared_preload_libraries = 'pg_cron' + ``` + + If you already have other libraries in this parameter, add `pg_cron` to the list, separating each library with a comma. + + ``` + shared_preload_libraries = 'pg_cron,pg_stat_statements' + ``` + + 3. Restart your PostgreSQL instance. For help with this, see [Google Cloud's docs](https://cloud.google.com/sql/docs/postgres/start-stop-restart-instance#restart). + +PostgreSQL now preloads the `pg_cron` extension when the instance starts. + + + + +1. Ensure your RDS for PostgreSQL instance is version 12.5 or later. pg_cron requires version 12.5 and later. + + ```sql + SELECT version(); + ``` + +2. Modify the parameter group associated with your PostgreSQL database instance to enable pg_cron. For help modifying parameter groups, see the [AWS docs](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithParamGroups.Modifying.html). + + 1. If your RDS for PostgreSQL database instance uses the `rds.allowed_extensions` parameter to spcify which extensions can be installed, add `pg_cron` to that list. + + 2. Edit the custom parameter group associated with your PostgreSQL DB instance. Modify the `shared_preload_libraries` parameter to include the value `pg_cron`. + + 3. Reboot your PostgreSQL database instance. For help, see the [AWS docs](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_RebootInstance.html#USER_RebootInstance.steps). + +PostgreSQL now preloads the `pg_cron` extension when the instance starts. + + + + +##### Enable the pg_cron extension, create a heartbeat table, and schedule a cron job {#wal-heartbeat-table} + +1. Verify pg_cron was successfully added to `shared_preload_libraries`. + + ``` + show shared_preload_libraries + ``` + +2. Enable the pg_cron extension, create a `periodic_log` (heartbeat) table, and schedule a cron job. + + ```sql + CREATE EXTENSION IF NOT EXISTS pg_cron; + + CREATE TABLE periodic_log ( + log_id SERIAL PRIMARY KEY, + log_time TIMESTAMP DEFAULT current_timestamp + ); + + SELECT cron.schedule( + 'periodic_logger', -- job name + '*/1 * * * *', -- cron expression (every minute) + $$INSERT INTO periodic_log DEFAULT VALUES$$ -- the SQL statement to run + ); + ``` + +3. Verify the scheduled job. + + ```sql + SELECT * FROM cron.job; + ``` + +4. Verify the periodic update. + + ```sql + SELECT * FROM periodic_log ORDER BY log_time DESC; + ``` + +5. Alter the publication to include this table on the primary. + + ```sql + ALTER PUBLICATION airbyte_publication ADD TABLE periodic_log; + ``` + +6. Sync normally from the primary to the replica. + +##### Stop the sync + +If you need to stop syncing later, unschedule the cron job. + +```sql +SELECT cron.unschedule('periodic_logger'); +``` diff --git a/docs/integrations/sources/posthog.md b/docs/integrations/sources/posthog.md index 0816fd7c5850..909b00b30cc4 100644 --- a/docs/integrations/sources/posthog.md +++ b/docs/integrations/sources/posthog.md @@ -71,6 +71,10 @@ Want to use the PostHog API beyond these limits? Email Posthog at `customers@pos | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------- | +| 1.1.21 | 2024-12-28 | [50685](https://github.com/airbytehq/airbyte/pull/50685) | Update dependencies | +| 1.1.20 | 2024-12-21 | [50280](https://github.com/airbytehq/airbyte/pull/50280) | Update dependencies | +| 1.1.19 | 2024-12-14 | [49716](https://github.com/airbytehq/airbyte/pull/49716) | Update dependencies | +| 1.1.18 | 2024-12-12 | [49066](https://github.com/airbytehq/airbyte/pull/49066) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 1.1.17 | 2024-10-29 | [47724](https://github.com/airbytehq/airbyte/pull/47724) | Update dependencies | | 1.1.16 | 2024-10-28 | [47033](https://github.com/airbytehq/airbyte/pull/47033) | Update dependencies | | 1.1.15 | 2024-10-12 | [46769](https://github.com/airbytehq/airbyte/pull/46769) | Update dependencies | diff --git a/docs/integrations/sources/postmarkapp.md b/docs/integrations/sources/postmarkapp.md index 4023e3704bdd..4103db061b96 100644 --- a/docs/integrations/sources/postmarkapp.md +++ b/docs/integrations/sources/postmarkapp.md @@ -58,6 +58,10 @@ The Postmarkapp source connector supports the following [sync modes](https://doc | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.2.5 | 2024-12-28 | [50703](https://github.com/airbytehq/airbyte/pull/50703) | Update dependencies | +| 0.2.4 | 2024-12-21 | [50281](https://github.com/airbytehq/airbyte/pull/50281) | Update dependencies | +| 0.2.3 | 2024-12-14 | [49667](https://github.com/airbytehq/airbyte/pull/49667) | Update dependencies | +| 0.2.2 | 2024-12-12 | [49046](https://github.com/airbytehq/airbyte/pull/49046) | Update dependencies | | 0.2.1 | 2024-10-28 | [47539](https://github.com/airbytehq/airbyte/pull/47539) | Update dependencies | | 0.2.0 | 2024-10-06 | [46522](https://github.com/airbytehq/airbyte/pull/46522) | Migrate to Manifest-only | | 0.1.21 | 2024-10-05 | [46509](https://github.com/airbytehq/airbyte/pull/46509) | Update dependencies | diff --git a/docs/integrations/sources/pretix.md b/docs/integrations/sources/pretix.md new file mode 100644 index 000000000000..575427e4cf0a --- /dev/null +++ b/docs/integrations/sources/pretix.md @@ -0,0 +1,51 @@ +# Pretix +[Pretix](https://pretix.eu/about/en/) connector enables seamless data integration with the Pretix event ticketing platform, allowing users to sync ticket sales, attendee information, event data, and other metrics directly into their data warehouse or analytics tools. This connector supports automated data extraction for efficient, reporting and data-driven insights across events managed in Pretix. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_token` | `string` | API Token. API token to use. Obtain it from the pretix web interface by creating a new token under your team settings. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| orgainzers | slug | DefaultPaginator | ✅ | ❌ | +| events | slug | DefaultPaginator | ✅ | ❌ | +| tax_rules | id | DefaultPaginator | ✅ | ❌ | +| categories | id | DefaultPaginator | ✅ | ❌ | +| items | id | DefaultPaginator | ✅ | ❌ | +| orders | code | DefaultPaginator | ✅ | ❌ | +| vouchers | id | DefaultPaginator | ✅ | ❌ | +| discounts | id | DefaultPaginator | ✅ | ❌ | +| checkin_lists | id | DefaultPaginator | ✅ | ❌ | +| waiting_list_entries | id | DefaultPaginator | ✅ | ❌ | +| customers | identifier | DefaultPaginator | ✅ | ❌ | +| sales_channels | identifier | DefaultPaginator | ✅ | ❌ | +| membership_types | | DefaultPaginator | ✅ | ❌ | +| memberships | | DefaultPaginator | ✅ | ❌ | +| giftcards | id | DefaultPaginator | ✅ | ❌ | +| reusable_media | id | DefaultPaginator | ✅ | ❌ | +| teams | id | DefaultPaginator | ✅ | ❌ | +| devices | device_id | DefaultPaginator | ✅ | ❌ | +| webhooks | id | DefaultPaginator | ✅ | ❌ | +| seating_plans | id | DefaultPaginator | ✅ | ❌ | +| auto_checkin_rules | id | DefaultPaginator | ✅ | ❌ | +| shredders | | No pagination | ✅ | ❌ | +| exporters | | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50706](https://github.com/airbytehq/airbyte/pull/50706) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50284](https://github.com/airbytehq/airbyte/pull/50284) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49720](https://github.com/airbytehq/airbyte/pull/49720) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49357](https://github.com/airbytehq/airbyte/pull/49357) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49073](https://github.com/airbytehq/airbyte/pull/49073) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-09 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/primetric.md b/docs/integrations/sources/primetric.md index 8a5615ff7b31..c175f37dfbb4 100644 --- a/docs/integrations/sources/primetric.md +++ b/docs/integrations/sources/primetric.md @@ -60,7 +60,10 @@ your employees to the right projects. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :---------------------- | -| 1.1.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | +| 1.1.4 | 2025-01-04 | [50287](https://github.com/airbytehq/airbyte/pull/50287) | Update dependencies | +| 1.1.3 | 2024-12-14 | [49670](https://github.com/airbytehq/airbyte/pull/49670) | Update dependencies | +| 1.1.2 | 2024-12-12 | [43808](https://github.com/airbytehq/airbyte/pull/43808) | Update dependencies | +| 1.1.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 1.1.0 | 2024-08-14 | [44083](https://github.com/airbytehq/airbyte/pull/44083) | Refactor connector to manifest-only format | | 1.0.1 | 2024-06-04 | [38956](https://github.com/airbytehq/airbyte/pull/38956) | [autopull] Upgrade base image to v1.2.1 | | 1.0.0 | 2024-04-01 | [36508](https://github.com/airbytehq/airbyte/pull/36508) | Migrate to low code cdk | diff --git a/docs/integrations/sources/productboard.md b/docs/integrations/sources/productboard.md index 7437998bd922..46d9cccbb47a 100644 --- a/docs/integrations/sources/productboard.md +++ b/docs/integrations/sources/productboard.md @@ -36,6 +36,13 @@ A manifest only source for Productboard. https://www.productboard.com/ | Version | Date | Pull Request | Subject | |---------|------------|----------------------------------------------------------|-------------------------------------------------------------------------------------------| +| 0.0.10 | 2024-12-28 | [50705](https://github.com/airbytehq/airbyte/pull/50705) | Update dependencies | +| 0.0.9 | 2024-12-21 | [50290](https://github.com/airbytehq/airbyte/pull/50290) | Update dependencies | +| 0.0.8 | 2024-12-14 | [49686](https://github.com/airbytehq/airbyte/pull/49686) | Update dependencies | +| 0.0.7 | 2024-12-12 | [49331](https://github.com/airbytehq/airbyte/pull/49331) | Update dependencies | +| 0.0.6 | 2024-12-11 | [49087](https://github.com/airbytehq/airbyte/pull/49087) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.5 | 2024-11-05 | [48365](https://github.com/airbytehq/airbyte/pull/48365) | Revert to source-declarative-manifest v5.17.0 | +| 0.0.4 | 2024-11-05 | [48324](https://github.com/airbytehq/airbyte/pull/48324) | Update dependencies | | 0.0.3 | 2024-10-29 | [47774](https://github.com/airbytehq/airbyte/pull/47774) | Update dependencies | | 0.0.2 | 2024-10-28 | [47677](https://github.com/airbytehq/airbyte/pull/47677) | Update dependencies | | 0.0.1 | 2024-09-13 | [45449](https://github.com/airbytehq/airbyte/pull/45449) | Initial release by [@pabloescoder](https://github.com/pabloescoder) via Connector Builder | diff --git a/docs/integrations/sources/productive.md b/docs/integrations/sources/productive.md index 8aa93a29bb54..751419677741 100644 --- a/docs/integrations/sources/productive.md +++ b/docs/integrations/sources/productive.md @@ -83,6 +83,11 @@ Visit `https://app.productive.io/ORG_ID-UUID/settings/api-integrations` for gett | Version | Date | Pull Request | Subject | | ------------------ | ------------ | -- | ---------------- | +| 0.0.7 | 2024-12-28 | [50698](https://github.com/airbytehq/airbyte/pull/50698) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50279](https://github.com/airbytehq/airbyte/pull/50279) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49721](https://github.com/airbytehq/airbyte/pull/49721) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49070](https://github.com/airbytehq/airbyte/pull/49070) | Update dependencies | +| 0.0.3 | 2024-11-04 | [48289](https://github.com/airbytehq/airbyte/pull/48289) | Update dependencies | | 0.0.2 | 2024-10-28 | [47656](https://github.com/airbytehq/airbyte/pull/47656) | Update dependencies | | 0.0.1 | 2024-09-11 | [45401](https://github.com/airbytehq/airbyte/pull/45401) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/public-apis.md b/docs/integrations/sources/public-apis.md index c745a395e425..457607896400 100644 --- a/docs/integrations/sources/public-apis.md +++ b/docs/integrations/sources/public-apis.md @@ -46,6 +46,12 @@ This source requires no setup. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------- | +| 0.2.27 | 2025-01-04 | [50928](https://github.com/airbytehq/airbyte/pull/50928) | Update dependencies | +| 0.2.26 | 2024-12-28 | [50671](https://github.com/airbytehq/airbyte/pull/50671) | Update dependencies | +| 0.2.25 | 2024-12-21 | [50273](https://github.com/airbytehq/airbyte/pull/50273) | Update dependencies | +| 0.2.24 | 2024-12-14 | [49723](https://github.com/airbytehq/airbyte/pull/49723) | Update dependencies | +| 0.2.23 | 2024-12-12 | [49039](https://github.com/airbytehq/airbyte/pull/49039) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.22 | 2024-11-04 | [48230](https://github.com/airbytehq/airbyte/pull/48230) | Update dependencies | | 0.2.21 | 2024-10-29 | [47035](https://github.com/airbytehq/airbyte/pull/47035) | Update dependencies | | 0.2.20 | 2024-10-12 | [46839](https://github.com/airbytehq/airbyte/pull/46839) | Update dependencies | | 0.2.19 | 2024-10-05 | [46440](https://github.com/airbytehq/airbyte/pull/46440) | Update dependencies | diff --git a/docs/integrations/sources/pypi.md b/docs/integrations/sources/pypi.md index 1027cee7f8b8..80b6e9a5066e 100644 --- a/docs/integrations/sources/pypi.md +++ b/docs/integrations/sources/pypi.md @@ -31,6 +31,10 @@ Try not to make a lot of requests (thousands) in a short amount of time (minutes | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.2.6 | 2024-12-28 | [50677](https://github.com/airbytehq/airbyte/pull/50677) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50252](https://github.com/airbytehq/airbyte/pull/50252) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49682](https://github.com/airbytehq/airbyte/pull/49682) | Update dependencies | +| 0.2.3 | 2024-12-12 | [48312](https://github.com/airbytehq/airbyte/pull/48312) | Update dependencies | | 0.2.2 | 2024-10-28 | [47528](https://github.com/airbytehq/airbyte/pull/47528) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-14 | [44082](https://github.com/airbytehq/airbyte/pull/44082) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/qonto.md b/docs/integrations/sources/qonto.md index 9001c5bbab14..e8d9e5fba188 100644 --- a/docs/integrations/sources/qonto.md +++ b/docs/integrations/sources/qonto.md @@ -10,6 +10,12 @@ The Airbyte Source for [Qonto](https://qonto.com) | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :-------------------------------- | +| 0.3.8 | 2024-12-28 | [50693](https://github.com/airbytehq/airbyte/pull/50693) | Update dependencies | +| 0.3.7 | 2024-12-21 | [50267](https://github.com/airbytehq/airbyte/pull/50267) | Update dependencies | +| 0.3.6 | 2024-12-14 | [49710](https://github.com/airbytehq/airbyte/pull/49710) | Update dependencies | +| 0.3.5 | 2024-12-12 | [49339](https://github.com/airbytehq/airbyte/pull/49339) | Update dependencies | +| 0.3.4 | 2024-12-11 | [49071](https://github.com/airbytehq/airbyte/pull/49071) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.3.3 | 2024-11-04 | [48265](https://github.com/airbytehq/airbyte/pull/48265) | Update dependencies | | 0.3.2 | 2024-10-29 | [47854](https://github.com/airbytehq/airbyte/pull/47854) | Update dependencies | | 0.3.1 | 2024-10-28 | [47490](https://github.com/airbytehq/airbyte/pull/47490) | Update dependencies | | 0.3.0 | 2024-10-06 | [46523](https://github.com/airbytehq/airbyte/pull/46523) | Migrate to Manifest-only | diff --git a/docs/integrations/sources/qualaroo.md b/docs/integrations/sources/qualaroo.md index aadd5179a79a..e8c83046f7a6 100644 --- a/docs/integrations/sources/qualaroo.md +++ b/docs/integrations/sources/qualaroo.md @@ -46,6 +46,12 @@ Please read [How to get your APIs Token and Key](https://help.qualaroo.com/hc/en | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------------------------------- | +| 0.4.5 | 2024-12-28 | [50701](https://github.com/airbytehq/airbyte/pull/50701) | Update dependencies | +| 0.4.4 | 2024-12-21 | [50224](https://github.com/airbytehq/airbyte/pull/50224) | Update dependencies | +| 0.4.3 | 2024-12-14 | [49680](https://github.com/airbytehq/airbyte/pull/49680) | Update dependencies | +| 0.4.2 | 2024-12-12 | [49344](https://github.com/airbytehq/airbyte/pull/49344) | Update dependencies | +| 0.4.1 | 2024-12-11 | [49098](https://github.com/airbytehq/airbyte/pull/49098) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.4.0 | 2024-10-31 | [47017](https://github.com/airbytehq/airbyte/pull/47017) | Migrate to manifest only format | | 0.3.24 | 2024-10-28 | [47111](https://github.com/airbytehq/airbyte/pull/47111) | Update dependencies | | 0.3.23 | 2024-10-12 | [46767](https://github.com/airbytehq/airbyte/pull/46767) | Update dependencies | | 0.3.22 | 2024-10-05 | [46439](https://github.com/airbytehq/airbyte/pull/46439) | Update dependencies | diff --git a/docs/integrations/sources/quickbooks.md b/docs/integrations/sources/quickbooks.md index 179d45a695cb..c63021549c77 100644 --- a/docs/integrations/sources/quickbooks.md +++ b/docs/integrations/sources/quickbooks.md @@ -108,6 +108,7 @@ This Source is capable of syncing the following [Streams](https://developer.intu | Version | Date | Pull Request | Subject | | :---------- | :--------- | :------------------------------------------------------- | :----------------------------------------------------------------- | +| 3.0.26 | 2024-11-01 | [48089](https://github.com/airbytehq/airbyte/pull/48089) | Promoting release candidate 3.0.26-rc.1 to a main version. | | 3.0.26-rc.1 | 2024-09-10 | [44560](https://github.com/airbytehq/airbyte/pull/44560) | Replace Custom Components with Airbyte CDK features | | 3.0.25 | 2024-10-05 | [46424](https://github.com/airbytehq/airbyte/pull/46424) | Update dependencies | | 3.0.24 | 2024-09-28 | [46142](https://github.com/airbytehq/airbyte/pull/46142) | Update dependencies | diff --git a/docs/integrations/sources/railz.md b/docs/integrations/sources/railz.md index 5f4b7b4be53e..e5bab856e48f 100644 --- a/docs/integrations/sources/railz.md +++ b/docs/integrations/sources/railz.md @@ -95,6 +95,10 @@ The Railz connector should gracefully handle Railz API limitations under normal | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :---------------- | +| 0.1.22 | 2025-01-04 | [50926](https://github.com/airbytehq/airbyte/pull/50926) | Update dependencies | +| 0.1.21 | 2024-12-28 | [50699](https://github.com/airbytehq/airbyte/pull/50699) | Update dependencies | +| 0.1.20 | 2024-12-21 | [50266](https://github.com/airbytehq/airbyte/pull/50266) | Update dependencies | +| 0.1.19 | 2024-12-14 | [49067](https://github.com/airbytehq/airbyte/pull/49067) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.1.18 | 2024-10-28 | [47114](https://github.com/airbytehq/airbyte/pull/47114) | Update dependencies | | 0.1.17 | 2024-10-12 | [46786](https://github.com/airbytehq/airbyte/pull/46786) | Update dependencies | | 0.1.16 | 2024-10-05 | [46462](https://github.com/airbytehq/airbyte/pull/46462) | Update dependencies | diff --git a/docs/integrations/sources/rd-station-marketing.md b/docs/integrations/sources/rd-station-marketing.md index 9433154c9a74..c6163386a0c6 100644 --- a/docs/integrations/sources/rd-station-marketing.md +++ b/docs/integrations/sources/rd-station-marketing.md @@ -47,6 +47,11 @@ Each endpoint has its own performance limitations, which also consider the accou | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :------------------------------- | +| 0.3.8 | 2024-12-28 | [50676](https://github.com/airbytehq/airbyte/pull/50676) | Update dependencies | +| 0.3.7 | 2024-12-21 | [50264](https://github.com/airbytehq/airbyte/pull/50264) | Update dependencies | +| 0.3.6 | 2024-12-14 | [49679](https://github.com/airbytehq/airbyte/pull/49679) | Update dependencies | +| 0.3.5 | 2024-12-12 | [49334](https://github.com/airbytehq/airbyte/pull/49334) | Update dependencies | +| 0.3.4 | 2024-12-11 | [48161](https://github.com/airbytehq/airbyte/pull/48161) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.3.3 | 2024-10-29 | [47936](https://github.com/airbytehq/airbyte/pull/47936) | Update dependencies | | 0.3.2 | 2024-10-28 | [47577](https://github.com/airbytehq/airbyte/pull/47577) | Update dependencies | | 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/recharge.md b/docs/integrations/sources/recharge.md index 1a237d191a02..8aa8a78bc5e3 100644 --- a/docs/integrations/sources/recharge.md +++ b/docs/integrations/sources/recharge.md @@ -57,6 +57,7 @@ Several output streams are available from this source: - [Addresses](https://developer.rechargepayments.com/v1-shopify?python#list-addresses) \(Incremental sync\) - [Charges](https://developer.rechargepayments.com/v1-shopify?python#list-charges) \(Incremental sync\) - [Collections](https://developer.rechargepayments.com/v1-shopify) +- [Events](https://developer.rechargepayments.com/2021-11/events/events_list) - [Customers](https://developer.rechargepayments.com/v1-shopify?python#list-customers) \(Incremental sync\) - [Discounts](https://developer.rechargepayments.com/v1-shopify?python#list-discounts) \(Incremental sync\) - [Metafields](https://developer.rechargepayments.com/v1-shopify?python#list-metafields) @@ -79,6 +80,13 @@ The Recharge connector should gracefully handle Recharge API limitations under n | Version | Date | Pull Request | Subject | |:--------|:-----------| :------------------------------------------------------- |:-------------------------------------------------------------------------------------------------------------------------------| +| 2.6.0 | 2025-01-02 | [48382](https://github.com/airbytehq/airbyte/pull/49926) | Add new stream `bundle_selections` | +| 2.5.4 | 2025-01-04 | [50927](https://github.com/airbytehq/airbyte/pull/50927) | Update dependencies | +| 2.5.3 | 2024-12-28 | [50724](https://github.com/airbytehq/airbyte/pull/50724) | Update dependencies | +| 2.5.2 | 2024-12-21 | [50265](https://github.com/airbytehq/airbyte/pull/50265) | Update dependencies | +| 2.5.1 | 2024-12-14 | [49081](https://github.com/airbytehq/airbyte/pull/49081) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 2.5.0 | 2024-11-26 | [48382](https://github.com/airbytehq/airbyte/pull/48382) | Add new stream `events` | +| 2.4.15 | 2024-11-04 | [48242](https://github.com/airbytehq/airbyte/pull/48242) | Update dependencies | | 2.4.14 | 2024-10-29 | [47890](https://github.com/airbytehq/airbyte/pull/47890) | Update dependencies | | 2.4.13 | 2024-10-28 | [47037](https://github.com/airbytehq/airbyte/pull/47037) | Update dependencies | | 2.4.12 | 2024-10-12 | [46797](https://github.com/airbytehq/airbyte/pull/46797) | Update dependencies | diff --git a/docs/integrations/sources/recreation.md b/docs/integrations/sources/recreation.md index 84a51061fdad..cee14b6179c0 100644 --- a/docs/integrations/sources/recreation.md +++ b/docs/integrations/sources/recreation.md @@ -60,6 +60,10 @@ The following fields are required fields for the connector to work: | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.2.7 | 2024-12-28 | [50742](https://github.com/airbytehq/airbyte/pull/50742) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50269](https://github.com/airbytehq/airbyte/pull/50269) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49657](https://github.com/airbytehq/airbyte/pull/49657) | Update dependencies | +| 0.2.4 | 2024-12-12 | [48286](https://github.com/airbytehq/airbyte/pull/48286) | Update dependencies | | 0.2.3 | 2024-10-29 | [47881](https://github.com/airbytehq/airbyte/pull/47881) | Update dependencies | | 0.2.2 | 2024-10-28 | [47524](https://github.com/airbytehq/airbyte/pull/47524) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/recruitee.md b/docs/integrations/sources/recruitee.md index 447adfc84e97..879b20e3b561 100644 --- a/docs/integrations/sources/recruitee.md +++ b/docs/integrations/sources/recruitee.md @@ -53,6 +53,10 @@ The Recruitee source connector supports the following [sync modes](https://docs. | Version | Date | Pull Request | Subject | |:--------|:-----------| :------------------------------------------------------- | :-------------------- | +| 0.2.7 | 2024-12-28 | [50689](https://github.com/airbytehq/airbyte/pull/50689) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50263](https://github.com/airbytehq/airbyte/pull/50263) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49701](https://github.com/airbytehq/airbyte/pull/49701) | Update dependencies | +| 0.2.4 | 2024-12-12 | [49074](https://github.com/airbytehq/airbyte/pull/49074) | Update dependencies | | 0.2.3 | 2024-10-29 | [47924](https://github.com/airbytehq/airbyte/pull/47924) | Update dependencies | | 0.2.2 | 2024-10-28 | [47522](https://github.com/airbytehq/airbyte/pull/47522) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/recurly.md b/docs/integrations/sources/recurly.md index 0aa7653e2ce4..fe07da550189 100644 --- a/docs/integrations/sources/recurly.md +++ b/docs/integrations/sources/recurly.md @@ -66,6 +66,14 @@ We recommend creating a restricted, read-only key specifically for Airbyte acces | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :----------------------------------------------------------------------------------- | +| 1.3.5 | 2024-12-28 | [50684](https://github.com/airbytehq/airbyte/pull/50684) | Update dependencies | +| 1.3.4 | 2024-12-21 | [50289](https://github.com/airbytehq/airbyte/pull/50289) | Update dependencies | +| 1.3.3 | 2024-12-14 | [49718](https://github.com/airbytehq/airbyte/pull/49718) | Update dependencies | +| 1.3.2 | 2024-12-12 | [49333](https://github.com/airbytehq/airbyte/pull/49333) | Update dependencies | +| 1.3.1 | 2024-12-11 | [49091](https://github.com/airbytehq/airbyte/pull/49091) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 1.3.0 | 2024-11-13 | [48474](https://github.com/airbytehq/airbyte/pull/48474) | Remove definition and schema redundancy, update to latest CDK and make compatibility with builder | +| 1.2.0 | 2024-11-04 | [47290](https://github.com/airbytehq/airbyte/pull/47290) | Migrate to manifest only format | +| 1.1.13 | 2024-11-04 | [48248](https://github.com/airbytehq/airbyte/pull/48248) | Update dependencies | | 1.1.12 | 2024-10-28 | [47067](https://github.com/airbytehq/airbyte/pull/47067) | Update dependencies | | 1.1.11 | 2024-10-12 | [46829](https://github.com/airbytehq/airbyte/pull/46829) | Update dependencies | | 1.1.10 | 2024-10-05 | [46456](https://github.com/airbytehq/airbyte/pull/46456) | Update dependencies | diff --git a/docs/integrations/sources/reddit.md b/docs/integrations/sources/reddit.md index 09006b1b2636..ab9e4c77e053 100644 --- a/docs/integrations/sources/reddit.md +++ b/docs/integrations/sources/reddit.md @@ -65,6 +65,11 @@ Hit send to receive `api_key` in the response under `access_token` | Version | Date |Pull Request | Subject | |------------------|------------|--------------|----------------| +| 0.0.8 | 2024-12-28 | [50683](https://github.com/airbytehq/airbyte/pull/50683) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50232](https://github.com/airbytehq/airbyte/pull/50232) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49697](https://github.com/airbytehq/airbyte/pull/49697) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49368](https://github.com/airbytehq/airbyte/pull/49368) | Update dependencies | +| 0.0.4 | 2024-12-11 | [49104](https://github.com/airbytehq/airbyte/pull/49104) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.3 | 2024-10-29 | [47827](https://github.com/airbytehq/airbyte/pull/47827) | Update dependencies | | 0.0.2 | 2024-10-28 | [47542](https://github.com/airbytehq/airbyte/pull/47542) | Update dependencies | | 0.0.1 | 2024-08-23 | [44579](https://github.com/airbytehq/airbyte/pull/44579) | Initial release by [btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/redshift.md b/docs/integrations/sources/redshift.md index bb872968093e..0039a6429d5f 100644 --- a/docs/integrations/sources/redshift.md +++ b/docs/integrations/sources/redshift.md @@ -59,9 +59,10 @@ All Redshift connections are encrypted using SSL | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- | -| 0.5.2 | 2024-02-13 | [35223](https://github.com/airbytehq/airbyte/pull/35223) | Adopt CDK 0.20.4 | -| 0.5.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | -| 0.5.0 | 2023-12-18 | [33484](https://github.com/airbytehq/airbyte/pull/33484) | Remove LEGACY state | +| 0.5.3 | 2024-12-18 | [49893](https://github.com/airbytehq/airbyte/pull/49893) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.5.2 | 2024-02-13 | [35223](https://github.com/airbytehq/airbyte/pull/35223) | Adopt CDK 0.20.4 | +| 0.5.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | +| 0.5.0 | 2023-12-18 | [33484](https://github.com/airbytehq/airbyte/pull/33484) | Remove LEGACY state | | (none) | 2023-11-17 | [32616](https://github.com/airbytehq/airbyte/pull/32616) | Improve timestamptz handling | | 0.4.0 | 2023-06-26 | [27737](https://github.com/airbytehq/airbyte/pull/27737) | License Update: Elv2 | | 0.3.17 | 2023-06-20 | [27212](https://github.com/airbytehq/airbyte/pull/27212) | Fix silent exception swallowing in StreamingJdbcDatabase | @@ -81,4 +82,4 @@ All Redshift connections are encrypted using SSL | 0.3.3 | 2021-10-12 | [6965](https://github.com/airbytehq/airbyte/pull/6965) | Added SSL Support | | 0.3.2 | 2021-08-13 | [4699](https://github.com/airbytehq/airbyte/pull/4699) | Added json config validator | - \ No newline at end of file + diff --git a/docs/integrations/sources/rentcast.md b/docs/integrations/sources/rentcast.md index 206f7ebaaf1e..193ba537069d 100644 --- a/docs/integrations/sources/rentcast.md +++ b/docs/integrations/sources/rentcast.md @@ -40,6 +40,11 @@ Docs : https://developers.rentcast.io/reference/introduction | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50730](https://github.com/airbytehq/airbyte/pull/50730) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50254](https://github.com/airbytehq/airbyte/pull/50254) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49666](https://github.com/airbytehq/airbyte/pull/49666) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49345](https://github.com/airbytehq/airbyte/pull/49345) | Update dependencies | +| 0.0.2 | 2024-12-11 | [47604](https://github.com/airbytehq/airbyte/pull/47604) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.1 | 2024-10-18 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | diff --git a/docs/integrations/sources/repairshopr.md b/docs/integrations/sources/repairshopr.md new file mode 100644 index 000000000000..9eefbe671f8f --- /dev/null +++ b/docs/integrations/sources/repairshopr.md @@ -0,0 +1,45 @@ +# Repairshopr +Repairshopr is a CRM and an integrated marketing platform. +With this connector we can extract data from various streams such as customers , invoices and payments. +[API Documentation](https://api-docs.repairshopr.com/) + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | +| `subdomain` | `string` | Sub Domain. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| appointment types | id | No pagination | ✅ | ❌ | +| appointments | id | DefaultPaginator | ✅ | ❌ | +| customer assets | id | DefaultPaginator | ✅ | ❌ | +| contacts | id | DefaultPaginator | ✅ | ❌ | +| contracts | id | DefaultPaginator | ✅ | ❌ | +| customers | id | DefaultPaginator | ✅ | ❌ | +| estimates | id | DefaultPaginator | ✅ | ❌ | +| invoices | id | DefaultPaginator | ✅ | ❌ | +| items | id | DefaultPaginator | ✅ | ❌ | +| line items | id | DefaultPaginator | ✅ | ❌ | +| leads | id | DefaultPaginator | ✅ | ❌ | +| payments | id | DefaultPaginator | ✅ | ❌ | +| products | id | DefaultPaginator | ✅ | ❌ | +| tickets | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50682](https://github.com/airbytehq/airbyte/pull/50682) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50255](https://github.com/airbytehq/airbyte/pull/50255) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49690](https://github.com/airbytehq/airbyte/pull/49690) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49366](https://github.com/airbytehq/airbyte/pull/49366) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49092](https://github.com/airbytehq/airbyte/pull/49092) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-08 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/reply-io.md b/docs/integrations/sources/reply-io.md index cca991cf5296..bd658c45d2f0 100644 --- a/docs/integrations/sources/reply-io.md +++ b/docs/integrations/sources/reply-io.md @@ -41,6 +41,10 @@ This Source is capable of syncing the following core Streams: | Version | Date | Pull Request | Subject | |:--------|:-----------| :------------------------------------------------------- | :---------------------------- | +| 0.2.6 | 2024-12-28 | [50720](https://github.com/airbytehq/airbyte/pull/50720) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50229](https://github.com/airbytehq/airbyte/pull/50229) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49664](https://github.com/airbytehq/airbyte/pull/49664) | Update dependencies | +| 0.2.3 | 2024-12-12 | [48261](https://github.com/airbytehq/airbyte/pull/48261) | Update dependencies | | 0.2.2 | 2024-10-29 | [47872](https://github.com/airbytehq/airbyte/pull/47872) | Update dependencies | | 0.2.1 | 2024-10-28 | [47462](https://github.com/airbytehq/airbyte/pull/47462) | Update dependencies | | 0.2.0 | 2024-08-19 | [44407](https://github.com/airbytehq/airbyte/pull/44407) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/retently.md b/docs/integrations/sources/retently.md index 8eabe88718fd..8cd1b255dd60 100644 --- a/docs/integrations/sources/retently.md +++ b/docs/integrations/sources/retently.md @@ -49,6 +49,11 @@ OAuth application is [here](https://app.retently.com/settings/oauth). | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.3.4 | 2024-12-28 | [50672](https://github.com/airbytehq/airbyte/pull/50672) | Update dependencies | +| 0.3.3 | 2024-12-21 | [50250](https://github.com/airbytehq/airbyte/pull/50250) | Update dependencies | +| 0.3.2 | 2024-12-14 | [49684](https://github.com/airbytehq/airbyte/pull/49684) | Update dependencies | +| 0.3.1 | 2024-12-12 | [49045](https://github.com/airbytehq/airbyte/pull/49045) | Update dependencies | +| 0.3.0 | 2024-11-01 | [47291](https://github.com/airbytehq/airbyte/pull/47291) | Migrate to manifest only format | | 0.2.24 | 2024-10-23 | [47108](https://github.com/airbytehq/airbyte/pull/47108) | Update dependencies | | 0.2.23 | 2024-10-12 | [46850](https://github.com/airbytehq/airbyte/pull/46850) | Update dependencies | | 0.2.22 | 2024-10-05 | [46429](https://github.com/airbytehq/airbyte/pull/46429) | Update dependencies | diff --git a/docs/integrations/sources/revenuecat.md b/docs/integrations/sources/revenuecat.md index d0aa304c0136..72cccff06b1a 100644 --- a/docs/integrations/sources/revenuecat.md +++ b/docs/integrations/sources/revenuecat.md @@ -49,6 +49,7 @@ To get started; | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.2 | 2024-12-11 | [47735](https://github.com/airbytehq/airbyte/pull/47735) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.1 | 2024-09-23 | | Initial release by [@topefolorunso](https://github.com/topefolorunso) via Connector Builder | diff --git a/docs/integrations/sources/revolut-merchant.md b/docs/integrations/sources/revolut-merchant.md new file mode 100644 index 000000000000..b1d096cfb0f0 --- /dev/null +++ b/docs/integrations/sources/revolut-merchant.md @@ -0,0 +1,44 @@ +# Revolut Merchant +This is the Revolut Merchant source that ingests data from the Revolut Merchant API. + +Revolut helps you spend, send, and save smarter https://www.revolut.com/ + +The Revolut Merchant account is a sub-account of your Revolut Business account. While a Business account is for managing your business finances, the Merchant account is dedicated to helping you accept online payments from your e-commerce customers. + +This source uses the Merchant API and has the orders, customers and location endpoints. In order to use this API, you must first create a Revolut account. +Log in to your Revolut Business account: Access the Revolut Business log in page and enter your credentials. +Navigate to Merchant API settings: Once logged in, access the Merchant API settings page by clicking your profile icon in the top left corner, then selecting APIs > Merchant API. +Here you can access your Production API keys (Public, Secret) specific to your Merchant account. +Get API keys: If you're visiting this page for the first time, you'll need to initiate the process by clicking the Get started button. To generate your Production API Secret key, click the Generate button. +You can find more about the API here https://developer.revolut.com/docs/merchant/merchant-api + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `secret_api_key` | `string` | Secret API Key. Secret API key to use for authenticating with the Revolut Merchant API. Find it in your Revolut Business account under APIs > Merchant API. | | +| `start_date` | `string` | Start date. | | +| `environment` | `string` | environment. The base url of your environment. Either sandbox or production | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| orders | id | DefaultPaginator | ✅ | ✅ | +| customers | id | No pagination | ✅ | ❌ | +| locations | id | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50679](https://github.com/airbytehq/airbyte/pull/50679) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50256](https://github.com/airbytehq/airbyte/pull/50256) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49704](https://github.com/airbytehq/airbyte/pull/49704) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49326](https://github.com/airbytehq/airbyte/pull/49326) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49052](https://github.com/airbytehq/airbyte/pull/49052) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-27 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | + +
diff --git a/docs/integrations/sources/ringcentral.md b/docs/integrations/sources/ringcentral.md index 01d429396736..a6bde8a62460 100644 --- a/docs/integrations/sources/ringcentral.md +++ b/docs/integrations/sources/ringcentral.md @@ -80,6 +80,11 @@ RingCentral [API reference](https://platform.devtest.ringcentral.com/restapi/v1. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------- | :------------- | +| 0.2.6 | 2024-12-28 | [50716](https://github.com/airbytehq/airbyte/pull/50716) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50298](https://github.com/airbytehq/airbyte/pull/50298) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49665](https://github.com/airbytehq/airbyte/pull/49665) | Update dependencies | +| 0.2.3 | 2024-12-12 | [49367](https://github.com/airbytehq/airbyte/pull/49367) | Update dependencies | +| 0.2.2 | 2024-12-11 | [49048](https://github.com/airbytehq/airbyte/pull/49048) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.1 | 2024-10-29 | [47611](https://github.com/airbytehq/airbyte/pull/47611) | Update dependencies | | 0.2.0 | 2024-08-20 | [44448](https://github.com/airbytehq/airbyte/pull/44448) | Refactor connector to manifest-only format | | 0.1.15 | 2024-08-17 | [44247](https://github.com/airbytehq/airbyte/pull/44247) | Update dependencies | diff --git a/docs/integrations/sources/rki-covid.md b/docs/integrations/sources/rki-covid.md index 76cc2029efa3..50b14a2f1154 100644 --- a/docs/integrations/sources/rki-covid.md +++ b/docs/integrations/sources/rki-covid.md @@ -56,6 +56,11 @@ Select start date | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :--------------------------------- | +| 0.1.29 | 2024-12-28 | [50707](https://github.com/airbytehq/airbyte/pull/50707) | Update dependencies | +| 0.1.28 | 2024-12-21 | [50237](https://github.com/airbytehq/airbyte/pull/50237) | Update dependencies | +| 0.1.27 | 2024-12-14 | [49724](https://github.com/airbytehq/airbyte/pull/49724) | Update dependencies | +| 0.1.26 | 2024-12-12 | [49099](https://github.com/airbytehq/airbyte/pull/49099) | Update dependencies | +| 0.1.25 | 2024-11-25 | [48677](https://github.com/airbytehq/airbyte/pull/48677) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.1.24 | 2024-10-29 | [47083](https://github.com/airbytehq/airbyte/pull/47083) | Update dependencies | | 0.1.23 | 2024-10-12 | [46791](https://github.com/airbytehq/airbyte/pull/46791) | Update dependencies | | 0.1.22 | 2024-10-05 | [46495](https://github.com/airbytehq/airbyte/pull/46495) | Update dependencies | diff --git a/docs/integrations/sources/rocket-chat.md b/docs/integrations/sources/rocket-chat.md index 3a392aefeffb..07c5ca9bd7a9 100644 --- a/docs/integrations/sources/rocket-chat.md +++ b/docs/integrations/sources/rocket-chat.md @@ -41,6 +41,11 @@ You need to setup a personal access token within the Rocket.chat workspace, see | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :-------------------------------------------- | +| 0.2.8 | 2024-12-28 | [50717](https://github.com/airbytehq/airbyte/pull/50717) | Update dependencies | +| 0.2.7 | 2024-12-21 | [50251](https://github.com/airbytehq/airbyte/pull/50251) | Update dependencies | +| 0.2.6 | 2024-12-14 | [49705](https://github.com/airbytehq/airbyte/pull/49705) | Update dependencies | +| 0.2.5 | 2024-12-12 | [49340](https://github.com/airbytehq/airbyte/pull/49340) | Update dependencies | +| 0.2.4 | 2024-12-11 | [49095](https://github.com/airbytehq/airbyte/pull/49095) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.3 | 2024-10-29 | [47853](https://github.com/airbytehq/airbyte/pull/47853) | Update dependencies | | 0.2.2 | 2024-10-28 | [47639](https://github.com/airbytehq/airbyte/pull/47639) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/rocketlane.md b/docs/integrations/sources/rocketlane.md new file mode 100644 index 000000000000..20e13f52fba3 --- /dev/null +++ b/docs/integrations/sources/rocketlane.md @@ -0,0 +1,36 @@ +# Rocketlane +Rocketlane connector enables seamless data integration by syncing project, task, and user data from Rocketlane into various data warehouses or analytics platforms. It ensures real-time access to operational insights, enhancing project visibility and performance tracking across tools. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use. Generate it from the API section in Settings of your Rocketlane account. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| tasks | taskId | DefaultPaginator | ✅ | ❌ | +| users | userId | DefaultPaginator | ✅ | ❌ | +| projects | projectId | DefaultPaginator | ✅ | ❌ | +| fields | fieldId | DefaultPaginator | ✅ | ❌ | +| time-offs | timeOffId | DefaultPaginator | ✅ | ❌ | +| spaces | spaceId | DefaultPaginator | ✅ | ❌ | +| phases | phaseId | DefaultPaginator | ✅ | ❌ | +| time-entries | timeEntryId | DefaultPaginator | ✅ | ❌ | +| space-documents | spaceDocumentId | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50688](https://github.com/airbytehq/airbyte/pull/50688) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50227](https://github.com/airbytehq/airbyte/pull/50227) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49673](https://github.com/airbytehq/airbyte/pull/49673) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49068](https://github.com/airbytehq/airbyte/pull/49068) | Update dependencies | +| 0.0.1 | 2024-11-08 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/rollbar.md b/docs/integrations/sources/rollbar.md index a0bc46f1af88..ddc9a6e2357d 100644 --- a/docs/integrations/sources/rollbar.md +++ b/docs/integrations/sources/rollbar.md @@ -36,6 +36,12 @@ Follow [this guide](https://docs.rollbar.com/reference/getting-started-1#authent | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.7 | 2024-12-28 | [50704](https://github.com/airbytehq/airbyte/pull/50704) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50299](https://github.com/airbytehq/airbyte/pull/50299) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49694](https://github.com/airbytehq/airbyte/pull/49694) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49335](https://github.com/airbytehq/airbyte/pull/49335) | Update dependencies | +| 0.0.3 | 2024-12-11 | [49084](https://github.com/airbytehq/airbyte/pull/49084) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.2 | 2024-11-04 | [47733](https://github.com/airbytehq/airbyte/pull/47733) | Update dependencies | | 0.0.1 | 2024-09-24 | | Initial release by [@topefolorunso](https://github.com/topefolorunso) via Connector Builder | diff --git a/docs/integrations/sources/rootly.md b/docs/integrations/sources/rootly.md index 338223c0e52a..9ff242343414 100644 --- a/docs/integrations/sources/rootly.md +++ b/docs/integrations/sources/rootly.md @@ -52,6 +52,12 @@ Documentation: https://rootly.com/api#/ | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.8 | 2024-12-28 | [50735](https://github.com/airbytehq/airbyte/pull/50735) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50262](https://github.com/airbytehq/airbyte/pull/50262) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49717](https://github.com/airbytehq/airbyte/pull/49717) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49355](https://github.com/airbytehq/airbyte/pull/49355) | Update dependencies | +| 0.0.4 | 2024-12-11 | [49063](https://github.com/airbytehq/airbyte/pull/49063) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.3 | 2024-11-04 | [48240](https://github.com/airbytehq/airbyte/pull/48240) | Update dependencies | | 0.0.2 | 2024-10-29 | [47833](https://github.com/airbytehq/airbyte/pull/47833) | Update dependencies | | 0.0.1 | 2024-10-09 | [46669](https://github.com/airbytehq/airbyte/pull/46669) | Initial release by [@gemsteam](https://github.com/gemsteam) via Connector Builder | diff --git a/docs/integrations/sources/rss.md b/docs/integrations/sources/rss.md index 485f5b5c13c2..43ea973931ea 100644 --- a/docs/integrations/sources/rss.md +++ b/docs/integrations/sources/rss.md @@ -38,6 +38,12 @@ None | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :----------------------------- | +| 1.0.29 | 2025-01-04 | [50935](https://github.com/airbytehq/airbyte/pull/50935) | Update dependencies | +| 1.0.28 | 2024-12-28 | [50731](https://github.com/airbytehq/airbyte/pull/50731) | Update dependencies | +| 1.0.27 | 2024-12-21 | [50296](https://github.com/airbytehq/airbyte/pull/50296) | Update dependencies | +| 1.0.26 | 2024-12-14 | [49699](https://github.com/airbytehq/airbyte/pull/49699) | Update dependencies | +| 1.0.25 | 2024-12-11 | [49082](https://github.com/airbytehq/airbyte/pull/49082) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 1.0.24 | 2024-11-04 | [48252](https://github.com/airbytehq/airbyte/pull/48252) | Update dependencies | | 1.0.23 | 2024-10-29 | [47104](https://github.com/airbytehq/airbyte/pull/47104) | Update dependencies | | 1.0.22 | 2024-10-12 | [46793](https://github.com/airbytehq/airbyte/pull/46793) | Update dependencies | | 1.0.21 | 2024-10-05 | [46454](https://github.com/airbytehq/airbyte/pull/46454) | Update dependencies | diff --git a/docs/integrations/sources/ruddr.md b/docs/integrations/sources/ruddr.md new file mode 100644 index 000000000000..735c3f9e6a85 --- /dev/null +++ b/docs/integrations/sources/ruddr.md @@ -0,0 +1,40 @@ +# Ruddr +Ruddr connector enables seamless data synchronization from Ruddr to various data warehouses, lakes, and destinations. It simplifies data pipelines by extracting projects and analytics data, ensuring reliable and efficient data integration for real-time insights. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_token` | `string` | API Token. API token to use. Generate it in the API Keys section of your Ruddr workspace settings. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| clients | id | DefaultPaginator | ✅ | ❌ | +| projects | id | DefaultPaginator | ✅ | ❌ | +| project_members | id | DefaultPaginator | ✅ | ❌ | +| project_tasks | id | DefaultPaginator | ✅ | ❌ | +| expense_reports | id | DefaultPaginator | ✅ | ❌ | +| expense_items | id | DefaultPaginator | ✅ | ❌ | +| expense_categories | id | DefaultPaginator | ✅ | ❌ | +| project_expense | id | DefaultPaginator | ✅ | ❌ | +| project_budget_expenses | id | DefaultPaginator | ✅ | ❌ | +| workspace members | | DefaultPaginator | ✅ | ❌ | +| opportunity_stages | id | DefaultPaginator | ✅ | ❌ | +| invoices | id | DefaultPaginator | ✅ | ❌ | +| holidays | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50241](https://github.com/airbytehq/airbyte/pull/50241) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49655](https://github.com/airbytehq/airbyte/pull/49655) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49346](https://github.com/airbytehq/airbyte/pull/49346) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49080](https://github.com/airbytehq/airbyte/pull/49080) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-08 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/s3.md b/docs/integrations/sources/s3.md index 6f1fc37b0697..e4dc3f34d0df 100644 --- a/docs/integrations/sources/s3.md +++ b/docs/integrations/sources/s3.md @@ -141,6 +141,28 @@ All other fields are optional and can be left empty. Refer to the [S3 Provider S 3. On the Set up the source page, select S3 from the Source type dropdown. 4. Enter a name for the S3 connector. +#### Copy Raw Files Configuration + + + +:::info + +The raw file replication feature has the following requirements and limitations: +- **Supported Airbyte Versions:** + - Cloud: All Workspaces + - OSS / Enterprise: `v1.2.0` or later +- **Max File Size:** `1GB` per file +- **Supported Destinations:** + - S3: `v1.4.0` or later + +::: + +Copy raw files without parsing their contents. Bits are copied into the destination exactly as they appeared in the source. Recommended for use with unstructured text data, non-text and compressed files. + +Format options will not be taken into account. Instead, files will be transferred to the file-based destination without parsing underlying data. + + + ## Supported sync modes The S3 source connector supports the following [sync modes](https://docs.airbyte.com/cloud/core-concepts/#connection-sync-modes): @@ -339,6 +361,13 @@ This connector utilizes the open source [Unstructured](https://unstructured-io.g | Version | Date | Pull Request | Subject | |:--------|:-----------|:----------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------| +| 4.11.3 | 2025-01-04 | [50932](https://github.com/airbytehq/airbyte/pull/50932) | Update dependencies | +| 4.11.2 | 2024-12-28 | [50739](https://github.com/airbytehq/airbyte/pull/50739) | Update dependencies | +| 4.11.1 | 2024-12-21 | [49042](https://github.com/airbytehq/airbyte/pull/49042) | Update dependencies | +| 4.11.0 | 2024-12-17 | [49824](https://github.com/airbytehq/airbyte/pull/49824) | Increase file size limit to 1.5GB | +| 4.10.2 | 2024-11-25 | [48613](https://github.com/airbytehq/airbyte/pull/48613) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 4.10.1 | 2024-11-12 | [48346](https://github.com/airbytehq/airbyte/pull/48346) | Implement file-transfer capabilities | +| 4.9.2 | 2024-11-04 | [48259](https://github.com/airbytehq/airbyte/pull/48259) | Update dependencies | | 4.9.1 | 2024-10-29 | [47038](https://github.com/airbytehq/airbyte/pull/47038) | Update dependencies | | 4.9.0 | 2024-10-17 | [46973](https://github.com/airbytehq/airbyte/pull/46973) | Promote releae candidate. | | 4.9.0-rc.1 | 2024-10-14 | [46298](https://github.com/airbytehq/airbyte/pull/46298) | Migrate to CDK v5 | diff --git a/docs/integrations/sources/safetyculture.md b/docs/integrations/sources/safetyculture.md index 343cb24bb1d5..4d62a332f1b4 100644 --- a/docs/integrations/sources/safetyculture.md +++ b/docs/integrations/sources/safetyculture.md @@ -54,6 +54,13 @@ The source connector supports the following [sync modes](https://docs.airbyte.co | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.10 | 2024-12-28 | [50674](https://github.com/airbytehq/airbyte/pull/50674) | Update dependencies | +| 0.0.9 | 2024-12-21 | [50297](https://github.com/airbytehq/airbyte/pull/50297) | Update dependencies | +| 0.0.8 | 2024-12-14 | [49669](https://github.com/airbytehq/airbyte/pull/49669) | Update dependencies | +| 0.0.7 | 2024-12-12 | [49358](https://github.com/airbytehq/airbyte/pull/49358) | Update dependencies | +| 0.0.6 | 2024-12-11 | [49086](https://github.com/airbytehq/airbyte/pull/49086) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.5 | 2024-11-05 | [48362](https://github.com/airbytehq/airbyte/pull/48362) | Revert to source-declarative-manifest v5.17.0 | +| 0.0.4 | 2024-11-05 | [48325](https://github.com/airbytehq/airbyte/pull/48325) | Update dependencies | | 0.0.3 | 2024-10-29 | [47839](https://github.com/airbytehq/airbyte/pull/47839) | Update dependencies | | 0.0.2 | 2024-10-28 | [47586](https://github.com/airbytehq/airbyte/pull/47586) | Update dependencies | | 0.0.1 | 2024-10-04 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | diff --git a/docs/integrations/sources/sage-hr.md b/docs/integrations/sources/sage-hr.md index a24a1762f462..620ab77f79b8 100644 --- a/docs/integrations/sources/sage-hr.md +++ b/docs/integrations/sources/sage-hr.md @@ -31,6 +31,13 @@ The Sage HR Airbyte Connector enables seamless data integration, allowing you to | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.9 | 2024-12-28 | [50687](https://github.com/airbytehq/airbyte/pull/50687) | Update dependencies | +| 0.0.8 | 2024-12-21 | [50300](https://github.com/airbytehq/airbyte/pull/50300) | Update dependencies | +| 0.0.7 | 2024-12-14 | [49687](https://github.com/airbytehq/airbyte/pull/49687) | Update dependencies | +| 0.0.6 | 2024-12-12 | [49353](https://github.com/airbytehq/airbyte/pull/49353) | Update dependencies | +| 0.0.5 | 2024-12-11 | [49089](https://github.com/airbytehq/airbyte/pull/49089) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.4 | 2024-11-05 | [48353](https://github.com/airbytehq/airbyte/pull/48353) | Revert to source-declarative-manifest v5.17.0 | +| 0.0.3 | 2024-11-05 | [48328](https://github.com/airbytehq/airbyte/pull/48328) | Update dependencies | | 0.0.2 | 2024-10-28 | [47581](https://github.com/airbytehq/airbyte/pull/47581) | Update dependencies | | 0.0.1 | 2024-10-08 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | diff --git a/docs/integrations/sources/salesflare.md b/docs/integrations/sources/salesflare.md new file mode 100644 index 000000000000..d0a27148036a --- /dev/null +++ b/docs/integrations/sources/salesflare.md @@ -0,0 +1,41 @@ +# Salesflare +Salesflare is a CRM tool for small and medium businesses. +Using this connector we can extract data from various streams such as opportunities , workflows and pipelines. +Docs : https://api.salesflare.com/docs + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. Enter you api key like this : Bearer YOUR_API_KEY | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| tasks | id | DefaultPaginator | ✅ | ❌ | +| accounts | id | DefaultPaginator | ✅ | ❌ | +| contacts | id | DefaultPaginator | ✅ | ❌ | +| opportunities | id | DefaultPaginator | ✅ | ❌ | +| workflows | id | DefaultPaginator | ✅ | ❌ | +| tags | id | DefaultPaginator | ✅ | ❌ | +| persons | id | No pagination | ✅ | ❌ | +| email data sources | id | No pagination | ✅ | ❌ | +| custom field types | id | No pagination | ✅ | ❌ | +| pipelines | id | No pagination | ✅ | ❌ | +| users | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50695](https://github.com/airbytehq/airbyte/pull/50695) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50234](https://github.com/airbytehq/airbyte/pull/50234) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49660](https://github.com/airbytehq/airbyte/pull/49660) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49325](https://github.com/airbytehq/airbyte/pull/49325) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49078](https://github.com/airbytehq/airbyte/pull/49078) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-07 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/salesforce.md b/docs/integrations/sources/salesforce.md index 343f0f096b61..a28f916e0c08 100644 --- a/docs/integrations/sources/salesforce.md +++ b/docs/integrations/sources/salesforce.md @@ -83,7 +83,7 @@ To obtain these credentials, follow [this walkthrough](https://medium.com/@bpmme 1. If your Salesforce URL is not in the `X.salesforce.com` format, use your Salesforce domain name. For example, if your Salesforce URL is `awesomecompany.force.com` then use that instead of `awesomecompany.salesforce.com`. 2. When running a curl command, run it with the `-L` option to follow any redirects. -3. If you [created a read-only user](https://docs.google.com/document/d/1wZR8pz4MRdc2zUculc9IqoF8JxN87U40IqVnTtcqdrI/edit#heading=h.w5v6h7b2a9y4), use the user credentials when logging in to generate OAuth tokens. +3. If you created a read-only user, use the user credentials when logging in to generate OAuth tokens. @@ -219,6 +219,7 @@ Now that you have set up the Salesforce source connector, check out the followin | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------| +| 2.6.3 | 2024-11-05 | [46835](https://github.com/airbytehq/airbyte/pull/46835) | Update dependencies | | 2.6.2 | 2024-10-10 | [](https://github.com/airbytehq/airbyte/pull/) | Bump minimum CDK to 5.10.2 | | 2.6.1 | 2024-10-05 | [46436](https://github.com/airbytehq/airbyte/pull/46436) | Update dependencies, including CDK fix in v5.10.2 | | 2.6.0 | 2024-10-02 | [45678](https://github.com/airbytehq/airbyte/pull/45678) | Have bulk streams use CDK components | diff --git a/docs/integrations/sources/salesloft.md b/docs/integrations/sources/salesloft.md index dbecf965ffde..f9b555887b88 100644 --- a/docs/integrations/sources/salesloft.md +++ b/docs/integrations/sources/salesloft.md @@ -103,8 +103,10 @@ Salesloft has the [rate limits](hhttps://developers.salesloft.com/api.html#!/Top
Expand to review -| Version | Date | Pull Request | Subject | -| :------ | :--------- | :------------------------------------------------------- | :---------------------------------------------------------------- | +| Version | Date | Pull Request | Subject | +| :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------- | +| 1.3.1 | 2024-12-03 | [48770](https://github.com/airbytehq/airbyte/pull/48770) | Remove duplication in manifest, fix query param updated_at[gt] | +| 1.3.0 | 2024-11-04 | [47298](https://github.com/airbytehq/airbyte/pull/47298) | Migrate to manifest only format | | 1.2.24 | 2024-10-29 | [47048](https://github.com/airbytehq/airbyte/pull/47048) | Update dependencies | | 1.2.23 | 2024-10-12 | [46833](https://github.com/airbytehq/airbyte/pull/46833) | Update dependencies | | 1.2.22 | 2024-10-05 | [46491](https://github.com/airbytehq/airbyte/pull/46491) | Update dependencies | diff --git a/docs/integrations/sources/sap-fieldglass.md b/docs/integrations/sources/sap-fieldglass.md index 591a86b6de15..cce091162d23 100644 --- a/docs/integrations/sources/sap-fieldglass.md +++ b/docs/integrations/sources/sap-fieldglass.md @@ -25,6 +25,10 @@ This page contains the setup guide and reference information for the SAP Fieldgl | Version | Date | Pull Request | Subject | | :------ | :--------- | :---------------------------------------------- |:--------------------------------------------| +| 0.2.7 | 2024-12-28 | [50678](https://github.com/airbytehq/airbyte/pull/50678) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50225](https://github.com/airbytehq/airbyte/pull/50225) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49719](https://github.com/airbytehq/airbyte/pull/49719) | Update dependencies | +| 0.2.4 | 2024-12-12 | [49043](https://github.com/airbytehq/airbyte/pull/49043) | Update dependencies | | 0.2.3 | 2024-10-29 | [47775](https://github.com/airbytehq/airbyte/pull/47775) | Update dependencies | | 0.2.2 | 2024-10-28 | [47583](https://github.com/airbytehq/airbyte/pull/47583) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/savvycal.md b/docs/integrations/sources/savvycal.md index e560228ea746..4562d97f2bb5 100644 --- a/docs/integrations/sources/savvycal.md +++ b/docs/integrations/sources/savvycal.md @@ -21,6 +21,12 @@ Sync your scheduled meetings and scheduling links from SavvyCal! | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.8 | 2024-12-28 | [50734](https://github.com/airbytehq/airbyte/pull/50734) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50242](https://github.com/airbytehq/airbyte/pull/50242) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49688](https://github.com/airbytehq/airbyte/pull/49688) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49342](https://github.com/airbytehq/airbyte/pull/49342) | Update dependencies | +| 0.0.4 | 2024-12-11 | [49044](https://github.com/airbytehq/airbyte/pull/49044) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.3 | 2024-11-04 | [47816](https://github.com/airbytehq/airbyte/pull/47816) | Update dependencies | | 0.0.2 | 2024-10-28 | [47558](https://github.com/airbytehq/airbyte/pull/47558) | Update dependencies | | 0.0.1 | 2024-09-01 | | Initial release by [@natikgadzhi](https://github.com/natikgadzhi) via Connector Builder | diff --git a/docs/integrations/sources/scryfall.md b/docs/integrations/sources/scryfall.md index 7fbfede5ae22..e77ef3ea90e7 100644 --- a/docs/integrations/sources/scryfall.md +++ b/docs/integrations/sources/scryfall.md @@ -20,6 +20,12 @@ For Magic The Gathering fans. Here is a simple data source for all the cards and | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.8 | 2024-12-28 | [50713](https://github.com/airbytehq/airbyte/pull/50713) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50286](https://github.com/airbytehq/airbyte/pull/50286) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49685](https://github.com/airbytehq/airbyte/pull/49685) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49369](https://github.com/airbytehq/airbyte/pull/49369) | Update dependencies | +| 0.0.4 | 2024-12-11 | [49093](https://github.com/airbytehq/airbyte/pull/49093) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.3 | 2024-11-04 | [47879](https://github.com/airbytehq/airbyte/pull/47879) | Update dependencies | | 0.0.2 | 2024-10-28 | [47457](https://github.com/airbytehq/airbyte/pull/47457) | Update dependencies | | 0.0.1 | 2024-08-28 | | Initial release by [@michel-tricot](https://github.com/michel-tricot) via Connector Builder | diff --git a/docs/integrations/sources/secoda.md b/docs/integrations/sources/secoda.md index 8b3f711970ae..3a7222c0cf4d 100644 --- a/docs/integrations/sources/secoda.md +++ b/docs/integrations/sources/secoda.md @@ -32,6 +32,13 @@ This source can sync data from the [Secoda API](https://docs.secoda.co/secoda-ap | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :--------------------------------------- | +| 0.2.10 | 2024-12-28 | [50692](https://github.com/airbytehq/airbyte/pull/50692) | Update dependencies | +| 0.2.9 | 2024-12-21 | [50271](https://github.com/airbytehq/airbyte/pull/50271) | Update dependencies | +| 0.2.8 | 2024-12-14 | [49691](https://github.com/airbytehq/airbyte/pull/49691) | Update dependencies | +| 0.2.7 | 2024-12-12 | [49362](https://github.com/airbytehq/airbyte/pull/49362) | Update dependencies | +| 0.2.6 | 2024-12-11 | [49076](https://github.com/airbytehq/airbyte/pull/49076) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.5 | 2024-11-05 | [48360](https://github.com/airbytehq/airbyte/pull/48360) | Revert to source-declarative-manifest v5.17.0 | +| 0.2.4 | 2024-11-05 | [48337](https://github.com/airbytehq/airbyte/pull/48337) | Update dependencies | | 0.2.3 | 2024-10-29 | [47908](https://github.com/airbytehq/airbyte/pull/47908) | Update dependencies | | 0.2.2 | 2024-10-28 | [47566](https://github.com/airbytehq/airbyte/pull/47566) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/segment.md b/docs/integrations/sources/segment.md index cf0c5e210862..74e2774deabe 100644 --- a/docs/integrations/sources/segment.md +++ b/docs/integrations/sources/segment.md @@ -34,6 +34,11 @@ Connector that pulls from Segment's Public API. | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50697](https://github.com/airbytehq/airbyte/pull/50697) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50278](https://github.com/airbytehq/airbyte/pull/50278) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49722](https://github.com/airbytehq/airbyte/pull/49722) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49350](https://github.com/airbytehq/airbyte/pull/49350) | Update dependencies | +| 0.0.3 | 2024-12-11 | [49062](https://github.com/airbytehq/airbyte/pull/49062) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.2 | 2024-10-29 | [47546](https://github.com/airbytehq/airbyte/pull/47546) | Update dependencies | | 0.0.1 | 2024-10-04 | | Initial release by [@zckymc](https://github.com/zckymc) via Connector Builder | diff --git a/docs/integrations/sources/sendowl.md b/docs/integrations/sources/sendowl.md new file mode 100644 index 000000000000..ce7964a7011c --- /dev/null +++ b/docs/integrations/sources/sendowl.md @@ -0,0 +1,36 @@ +# Sendowl +Sendowl is an All-in-One Digital Commerce Platform. +Using this connector we can extract data from products , packages , orders , discounts and subscriptions streams. +[API Docs](https://dashboard.sendowl.com/developers/api/introduction) + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `username` | `string` | Username. Enter you API Key | | +| `password` | `string` | Password. Enter your API secret | | +| `start_date` | `string` | Start date. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| products | id | DefaultPaginator | ✅ | ❌ | +| packages | id | DefaultPaginator | ✅ | ❌ | +| orders | id | DefaultPaginator | ✅ | ✅ | +| subscriptions | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50711](https://github.com/airbytehq/airbyte/pull/50711) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50248](https://github.com/airbytehq/airbyte/pull/50248) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49683](https://github.com/airbytehq/airbyte/pull/49683) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49338](https://github.com/airbytehq/airbyte/pull/49338) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49054](https://github.com/airbytehq/airbyte/pull/49054) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-09 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/sendpulse.md b/docs/integrations/sources/sendpulse.md new file mode 100644 index 000000000000..0d9b4a063d31 --- /dev/null +++ b/docs/integrations/sources/sendpulse.md @@ -0,0 +1,36 @@ +# SendPulse +Airbyte connector for [SendPulse](https://sendpulse.com/) allows you to seamlessly sync data from SendPulse to your data warehouse. It retrieves essential information from various SendPulse streams, including mailing lists, campaigns, templates, senders, webhooks, balance details, and balance. This enables you to analyze and manage your SendPulse email marketing and communication efforts effectively in a centralized location. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `client_id` | `string` | OAuth Client ID. | | +| `client_secret` | `string` | OAuth Client Secret. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| mailing_lists | id | DefaultPaginator | ✅ | ❌ | +| campaigns | id | DefaultPaginator | ✅ | ❌ | +| templates | id | No pagination | ✅ | ❌ | +| senders | email | No pagination | ✅ | ❌ | +| webhooks | id | No pagination | ✅ | ❌ | +| balance_details | | No pagination | ✅ | ❌ | +| balance | currency | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50700](https://github.com/airbytehq/airbyte/pull/50700) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50259](https://github.com/airbytehq/airbyte/pull/50259) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49677](https://github.com/airbytehq/airbyte/pull/49677) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49323](https://github.com/airbytehq/airbyte/pull/49323) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49061](https://github.com/airbytehq/airbyte/pull/49061) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-08 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/senseforce.md b/docs/integrations/sources/senseforce.md index f48fade80f1e..1e819708ac02 100644 --- a/docs/integrations/sources/senseforce.md +++ b/docs/integrations/sources/senseforce.md @@ -87,6 +87,12 @@ Senseforce utilizes an undocumented rate limit which - under normal use - should | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :-------------------------------------------- | +| 0.2.9 | 2024-12-28 | [50738](https://github.com/airbytehq/airbyte/pull/50738) | Update dependencies | +| 0.2.8 | 2024-12-21 | [50235](https://github.com/airbytehq/airbyte/pull/50235) | Update dependencies | +| 0.2.7 | 2024-12-14 | [49662](https://github.com/airbytehq/airbyte/pull/49662) | Update dependencies | +| 0.2.6 | 2024-12-12 | [49341](https://github.com/airbytehq/airbyte/pull/49341) | Update dependencies | +| 0.2.5 | 2024-12-11 | [49100](https://github.com/airbytehq/airbyte/pull/49100) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.4 | 2024-11-04 | [48166](https://github.com/airbytehq/airbyte/pull/48166) | Update dependencies | | 0.2.3 | 2024-10-29 | [47765](https://github.com/airbytehq/airbyte/pull/47765) | Update dependencies | | 0.2.2 | 2024-10-28 | [47567](https://github.com/airbytehq/airbyte/pull/47567) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/sentry.md b/docs/integrations/sources/sentry.md index 3bdd41ccc000..1b7eaf3e5723 100644 --- a/docs/integrations/sources/sentry.md +++ b/docs/integrations/sources/sentry.md @@ -63,8 +63,13 @@ Please be aware: this also means that any change older than 90 days will not be
Expand to review -| Version | Date | Pull Request | Subject | -| :------ | :--------- | :------------------------------------------------------- | :---------------------------------------------------------------------- | +| Version | Date | Pull Request | Subject | +|:--------|:-----------|:---------------------------------------------------------|:---------------------------------------------------------------------------| +| 0.6.4 | 2025-01-04 | [50930](https://github.com/airbytehq/airbyte/pull/50930) | Update dependencies | +| 0.6.3 | 2024-12-28 | [50709](https://github.com/airbytehq/airbyte/pull/50709) | Update dependencies | +| 0.6.2 | 2024-12-21 | [49058](https://github.com/airbytehq/airbyte/pull/49058) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.6.1 | 2024-11-04 | [43855](https://github.com/airbytehq/airbyte/pull/43855) | Update dependencies | +| 0.6.0 | 2024-10-30 | [47988](https://github.com/airbytehq/airbyte/pull/47988) | Upgrade the CDK and startup files to sync incremental streams concurrently | | 0.5.3 | 2024-06-06 | [39180](https://github.com/airbytehq/airbyte/pull/39180) | [autopull] Upgrade base image to v1.2.2 | | 0.5.2 | 2024-05-20 | [38263](https://github.com/airbytehq/airbyte/pull/38263) | Replace AirbyteLogger with logging.Logger | | 0.5.1 | 2024-04-01 | [36731](https://github.com/airbytehq/airbyte/pull/36731) | Add `%Y-%m-%dT%H:%M:%S%z` to date time formats. | diff --git a/docs/integrations/sources/serpstat.md b/docs/integrations/sources/serpstat.md index 8727f3162c7a..26b5ea46f745 100644 --- a/docs/integrations/sources/serpstat.md +++ b/docs/integrations/sources/serpstat.md @@ -52,6 +52,10 @@ The maximum sync speed is limited by the number of requests per second per API k | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------- | +| 0.2.7 | 2024-12-28 | [50712](https://github.com/airbytehq/airbyte/pull/50712) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50230](https://github.com/airbytehq/airbyte/pull/50230) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49714](https://github.com/airbytehq/airbyte/pull/49714) | Update dependencies | +| 0.2.4 | 2024-12-12 | [48241](https://github.com/airbytehq/airbyte/pull/48241) | Update dependencies | | 0.2.3 | 2024-10-29 | [47928](https://github.com/airbytehq/airbyte/pull/47928) | Update dependencies | | 0.2.2 | 2024-10-28 | [47666](https://github.com/airbytehq/airbyte/pull/47666) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/sftp-bulk.md b/docs/integrations/sources/sftp-bulk.md index 02562a28fc88..a5856cd403bf 100644 --- a/docs/integrations/sources/sftp-bulk.md +++ b/docs/integrations/sources/sftp-bulk.md @@ -113,6 +113,28 @@ For example, assuming your folder path is not set in the connector configuration If your files are in a folder, include the folder in your glob pattern, like `my_folder/my_prefix_*.csv`. +#### Copy Raw Files Configuration + + + +:::info + +The raw file replication feature has the following requirements and limitations: +- **Supported Airbyte Versions:** + - Cloud: All Workspaces + - OSS / Enterprise: `v1.2.0` or later +- **Max File Size:** `1GB` per file +- **Supported Destinations:** + - S3: `v1.4.0` or later + +::: + +Copy raw files without parsing their contents. Bits are copied into the destination exactly as they appeared in the source. Recommended for use with unstructured text data, non-text and compressed files. + +Format options will not be taken into account. Instead, files will be transferred to the file-based destination without parsing underlying data. + + + ## Supported sync modes The SFTP Bulk source connector supports the following [sync modes](https://docs.airbyte.com/cloud/core-concepts/#connection-sync-modes): @@ -134,6 +156,10 @@ This source provides a single stream per file with a dynamic schema. The current | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:------------------------------------------------------------| +| 1.6.0 | 2024-12-17 | [49826](https://github.com/airbytehq/airbyte/pull/49826) | Increase individual file size limit. | +| 1.5.0 | 2024-12-02 | [48434](https://github.com/airbytehq/airbyte/pull/48434) | Add get_file method for file-transfer feature. | +| 1.4.0 | 2024-10-31 | [46739](https://github.com/airbytehq/airbyte/pull/46739) | make private key an airbyte secret. | +| 1.3.0 | 2024-10-31 | [47703](https://github.com/airbytehq/airbyte/pull/47703) | Update dependency to CDK v6 with ability to transfer files. | | 1.2.0 | 2024-09-03 | [46323](https://github.com/airbytehq/airbyte/pull/46323) | Update dependency to CDK v5 | | 1.1.0 | 2024-08-14 | [44028](https://github.com/airbytehq/airbyte/pull/44028) | Update dependency to CDK v4 | | 1.0.1 | 2024-05-29 | [38703](https://github.com/airbytehq/airbyte/pull/38703) | Avoid error on empty stream when running discover | diff --git a/docs/integrations/sources/sharetribe.md b/docs/integrations/sources/sharetribe.md index cc1d5333828a..e154c1b74f8e 100644 --- a/docs/integrations/sources/sharetribe.md +++ b/docs/integrations/sources/sharetribe.md @@ -52,6 +52,11 @@ For more details about the API, check out https://www.sharetribe.com/api-referen | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50728](https://github.com/airbytehq/airbyte/pull/50728) | Update dependencies | +| 0.0.5 | 2024-12-21 | [49709](https://github.com/airbytehq/airbyte/pull/49709) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49327](https://github.com/airbytehq/airbyte/pull/49327) | Update dependencies | +| 0.0.3 | 2024-12-11 | [49055](https://github.com/airbytehq/airbyte/pull/49055) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.2 | 2024-11-04 | [48188](https://github.com/airbytehq/airbyte/pull/48188) | Update dependencies | | 0.0.1 | 2024-10-03 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder |
diff --git a/docs/integrations/sources/shippo.md b/docs/integrations/sources/shippo.md new file mode 100644 index 000000000000..e6092cee6b4e --- /dev/null +++ b/docs/integrations/sources/shippo.md @@ -0,0 +1,39 @@ +# Shippo +This is the Shippo source for ingesting data using the Shippo API. + +Shippo is your one-stop solution for shipping labels. Whether you use our app to ship or API to power your logistics workflow, Shippo gives you scalable shipping tools, the best rates, and world-class support https://goshippo.com/ + +In order to use this source, you must first create a Shippo account. Once logged in, head over to Settings -> Advanced -> API and click on generate new token. You can learn more about the API here https://docs.goshippo.com/shippoapi/public-api/#tag/Overview + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `shippo_token` | `string` | Shippo Token. The bearer token used for making requests | | +| `start_date` | `string` | Start date. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| addresses | id | DefaultPaginator | ✅ | ❌ | +| parcels | object_id | DefaultPaginator | ✅ | ❌ | +| custom_items | object_id | DefaultPaginator | ✅ | ❌ | +| accounts | object_id | DefaultPaginator | ✅ | ❌ | +| carrier_acounts | object_id | DefaultPaginator | ✅ | ❌ | +| shipments | object_id | DefaultPaginator | ✅ | ✅ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50702](https://github.com/airbytehq/airbyte/pull/50702) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50292](https://github.com/airbytehq/airbyte/pull/50292) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49727](https://github.com/airbytehq/airbyte/pull/49727) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49352](https://github.com/airbytehq/airbyte/pull/49352) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49101](https://github.com/airbytehq/airbyte/pull/49101) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-28 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | + +
diff --git a/docs/integrations/sources/shipstation.md b/docs/integrations/sources/shipstation.md new file mode 100644 index 000000000000..373d396498a9 --- /dev/null +++ b/docs/integrations/sources/shipstation.md @@ -0,0 +1,57 @@ +# Shipstation +This page contains the setup guide and reference information for Shipstation source connector. + +Documentation reference: +Visit https://www.shipstation.com/docs/api/ for API documentation + +Authentication setup + +To get your API key and secret in ShipStation: + +↳ Go to Account Settings. + +↳ Select Account from the side navigation, then choose API Settings. + +↳ Click "Generate New API Keys" if no key and secret are listed yet. + +** IMPORTANT ** +↳If you've already generated your API keys, the existing API keys will be displayed here and the button will read Regenerate API Keys. + +If you already have API keys, do NOT generate new ones. Instead, copy your existing key and secret. + +Copy your key and secret and paste them into the respective fields. + + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `username` | `string` | API Key. | | +| `password` | `string` | API Secret. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| carriers | shippingProviderId | No pagination | ✅ | ❌ | +| customers | customerId | DefaultPaginator | ✅ | ❌ | +| fulfillments | fulfillmentId | DefaultPaginator | ✅ | ❌ | +| orders | orderId | DefaultPaginator | ✅ | ❌ | +| products | productId | DefaultPaginator | ✅ | ❌ | +| shipments | shipmentId | DefaultPaginator | ✅ | ❌ | +| marketplaces | name.marketplaceId | No pagination | ✅ | ❌ | +| stores | storeId | No pagination | ✅ | ❌ | +| users | userId | No pagination | ✅ | ❌ | +| warehouses | warehouseId | No pagination | ✅ | ❌ | +| webhooks | WebHookID | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.2 | 2024-12-28 | [50726](https://github.com/airbytehq/airbyte/pull/50726) | Update dependencies | +| 0.0.1 | 2024-12-21 | | Initial release by [@JohnnyRafael](https://github.com/JohnnyRafael) via Connector Builder | + +
diff --git a/docs/integrations/sources/shopify.md b/docs/integrations/sources/shopify.md index 48a9a223cd73..fbef0b922763 100644 --- a/docs/integrations/sources/shopify.md +++ b/docs/integrations/sources/shopify.md @@ -247,6 +247,14 @@ For all `Shopify GraphQL BULK` api requests these limitations are applied: https | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 2.5.17 | 2025-01-06 | [50884](https://github.com/airbytehq/airbyte/pull/50884) | Add `moments` field `Customer Journey Summary` stream | +| 2.5.16 | 2025-01-04 | [50938](https://github.com/airbytehq/airbyte/pull/50938) | Update dependencies | +| 2.5.15 | 2024-12-28 | [50779](https://github.com/airbytehq/airbyte/pull/50779) | Update dependencies | +| 2.5.14 | 2024-12-21 | [49088](https://github.com/airbytehq/airbyte/pull/49088) | Update dependencies | +| 2.5.13 | 2024-12-11 | [49134](https://github.com/airbytehq/airbyte/pull/49134) | Added `checkpointed value` collision detection for BULK-supported streams | +| 2.5.12 | 2024-11-25 | [48661](https://github.com/airbytehq/airbyte/pull/48661) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 2.5.11 | 2024-11-07 | [48402](https://github.com/airbytehq/airbyte/pull/48402) | Add `image_src`, `image_url`, including `options` to `Product Variants` stream | +| 2.5.10 | 2024-11-05 | [48322](https://github.com/airbytehq/airbyte/pull/48322) | Update dependencies | | 2.5.9 | 2024-10-29 | [47814](https://github.com/airbytehq/airbyte/pull/47814) | Update dependencies | | 2.5.8 | 2024-10-28 | [47044](https://github.com/airbytehq/airbyte/pull/47044) | Update dependencies | | 2.5.7 | 2024-10-14 | [46552](https://github.com/airbytehq/airbyte/pull/46552) | Add `parent state` tracking for BULK sub-streams | diff --git a/docs/integrations/sources/shortcut.md b/docs/integrations/sources/shortcut.md index 779acdd07bcf..440918ac781f 100644 --- a/docs/integrations/sources/shortcut.md +++ b/docs/integrations/sources/shortcut.md @@ -53,6 +53,12 @@ Refer `https://developer.shortcut.com/api/rest/v3#Authentication` for more detai | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.7 | 2024-12-28 | [50759](https://github.com/airbytehq/airbyte/pull/50759) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50353](https://github.com/airbytehq/airbyte/pull/50353) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49788](https://github.com/airbytehq/airbyte/pull/49788) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49440](https://github.com/airbytehq/airbyte/pull/49440) | Update dependencies | +| 0.0.3 | 2024-12-11 | [49120](https://github.com/airbytehq/airbyte/pull/49120) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.2 | 2024-11-04 | [47658](https://github.com/airbytehq/airbyte/pull/47658) | Update dependencies | | 0.0.1 | 2024-09-05 | [45176](https://github.com/airbytehq/airbyte/pull/45176) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder |
diff --git a/docs/integrations/sources/shortio.md b/docs/integrations/sources/shortio.md index b8d4f2216568..dadbe1bb7c1a 100644 --- a/docs/integrations/sources/shortio.md +++ b/docs/integrations/sources/shortio.md @@ -44,6 +44,11 @@ This Source is capable of syncing the following Streams: | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------ | +| 0.3.8 | 2024-12-28 | [50820](https://github.com/airbytehq/airbyte/pull/50820) | Update dependencies | +| 0.3.7 | 2024-12-21 | [50316](https://github.com/airbytehq/airbyte/pull/50316) | Update dependencies | +| 0.3.6 | 2024-12-14 | [49760](https://github.com/airbytehq/airbyte/pull/49760) | Update dependencies | +| 0.3.5 | 2024-12-12 | [49422](https://github.com/airbytehq/airbyte/pull/49422) | Update dependencies | +| 0.3.4 | 2024-12-11 | [48178](https://github.com/airbytehq/airbyte/pull/48178) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.3.3 | 2024-10-29 | [47858](https://github.com/airbytehq/airbyte/pull/47858) | Update dependencies | | 0.3.2 | 2024-10-28 | [47564](https://github.com/airbytehq/airbyte/pull/47564) | Update dependencies | | 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/sigma-computing.md b/docs/integrations/sources/sigma-computing.md index 6655ebc0416e..dcb888cf2935 100644 --- a/docs/integrations/sources/sigma-computing.md +++ b/docs/integrations/sources/sigma-computing.md @@ -38,6 +38,11 @@ Next, head over to Developer Access and click on create. This will generate your | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50780](https://github.com/airbytehq/airbyte/pull/50780) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50325](https://github.com/airbytehq/airbyte/pull/50325) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49775](https://github.com/airbytehq/airbyte/pull/49775) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49396](https://github.com/airbytehq/airbyte/pull/49396) | Update dependencies | +| 0.0.3 | 2024-11-04 | [48150](https://github.com/airbytehq/airbyte/pull/48150) | Update dependencies | | 0.0.2 | 2024-10-28 | [47514](https://github.com/airbytehq/airbyte/pull/47514) | Update dependencies | | 0.0.1 | 2024-10-13 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | diff --git a/docs/integrations/sources/simfin.md b/docs/integrations/sources/simfin.md new file mode 100644 index 000000000000..10f34070ad31 --- /dev/null +++ b/docs/integrations/sources/simfin.md @@ -0,0 +1,38 @@ +# SimFin +Simfin provides financial data . +With this connector we can extract data from price data , financial statements and company info streams . +Docs https://simfin.readme.io/reference/getting-started-1 + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| Company Info | id | No pagination | ✅ | ❌ | +| Financial Statements | | No pagination | ✅ | ❌ | +| Price Data | | No pagination | ✅ | ❌ | +| companies | | No pagination | ✅ | ❌ | +| common_shares_outstanding | | No pagination | ✅ | ❌ | +| weighted_shares_outstanding | | No pagination | ✅ | ❌ | +| filings_by_company | filingIdentifier | No pagination | ✅ | ❌ | +| filings_list | filingIdentifier | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50776](https://github.com/airbytehq/airbyte/pull/50776) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50306](https://github.com/airbytehq/airbyte/pull/50306) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49790](https://github.com/airbytehq/airbyte/pull/49790) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49390](https://github.com/airbytehq/airbyte/pull/49390) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49118](https://github.com/airbytehq/airbyte/pull/49118) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-08 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/simplecast.md b/docs/integrations/sources/simplecast.md index 0e6c1e965996..c59ca350a5af 100644 --- a/docs/integrations/sources/simplecast.md +++ b/docs/integrations/sources/simplecast.md @@ -27,6 +27,11 @@ Say hello to the modern end-to-end podcasting platform. Simplecast remains the e | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.8 | 2024-12-28 | [50765](https://github.com/airbytehq/airbyte/pull/50765) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50331](https://github.com/airbytehq/airbyte/pull/50331) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49772](https://github.com/airbytehq/airbyte/pull/49772) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49381](https://github.com/airbytehq/airbyte/pull/49381) | Update dependencies | +| 0.0.4 | 2024-12-11 | [49129](https://github.com/airbytehq/airbyte/pull/49129) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.3 | 2024-10-29 | [47777](https://github.com/airbytehq/airbyte/pull/47777) | Update dependencies | | 0.0.2 | 2024-10-28 | [47571](https://github.com/airbytehq/airbyte/pull/47571) | Update dependencies | | 0.0.1 | 2024-10-03 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | diff --git a/docs/integrations/sources/simplesat.md b/docs/integrations/sources/simplesat.md index 8ec2b4ca4186..2068e67f27f1 100644 --- a/docs/integrations/sources/simplesat.md +++ b/docs/integrations/sources/simplesat.md @@ -47,6 +47,11 @@ The source connector supports the following [sync modes](https://docs.airbyte.co | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50805](https://github.com/airbytehq/airbyte/pull/50805) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50342](https://github.com/airbytehq/airbyte/pull/50342) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49748](https://github.com/airbytehq/airbyte/pull/49748) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49427](https://github.com/airbytehq/airbyte/pull/49427) | Update dependencies | +| 0.0.3 | 2024-12-11 | [49116](https://github.com/airbytehq/airbyte/pull/49116) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.2 | 2024-10-29 | [47515](https://github.com/airbytehq/airbyte/pull/47515) | Update dependencies | | 0.0.1 | 2024-10-01 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | diff --git a/docs/integrations/sources/singlestore.md b/docs/integrations/sources/singlestore.md index 708182cb9eb8..69a060c5e9c3 100644 --- a/docs/integrations/sources/singlestore.md +++ b/docs/integrations/sources/singlestore.md @@ -172,5 +172,6 @@ SingleStore data types are mapped to the following data types when synchronizing | Version | Date | Pull Request | Subject | |:--------|:-----------|:-------------------------------------------------------|:---------------------------------| -| 0.1.0 | 2024-04-16 | [37337](https://github.com/airbytehq/airbyte/pull/37337) | Add SingleStore source connector | - \ No newline at end of file +| 0.1.1 | 2024-12-18 | [49862](https://github.com/airbytehq/airbyte/pull/49862) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.1.0 | 2024-04-16 | [37337](https://github.com/airbytehq/airbyte/pull/37337) | Add SingleStore source connector | + diff --git a/docs/integrations/sources/smaily.md b/docs/integrations/sources/smaily.md index 2908802f90cc..b5338a1a1513 100644 --- a/docs/integrations/sources/smaily.md +++ b/docs/integrations/sources/smaily.md @@ -39,7 +39,12 @@ The connector has a rate limit of 5 API requests per second per IP-address. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------- | -| 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | +| 0.2.6 | 2024-12-28 | [50774](https://github.com/airbytehq/airbyte/pull/50774) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50330](https://github.com/airbytehq/airbyte/pull/50330) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49791](https://github.com/airbytehq/airbyte/pull/49791) | Update dependencies | +| 0.2.3 | 2024-12-12 | [49394](https://github.com/airbytehq/airbyte/pull/49394) | Update dependencies | +| 0.2.2 | 2024-12-11 | [47809](https://github.com/airbytehq/airbyte/pull/47809) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-14 | [44065](https://github.com/airbytehq/airbyte/pull/44065) | Refactor connector to manifest-only format | | 0.1.14 | 2024-08-12 | [43872](https://github.com/airbytehq/airbyte/pull/43872) | Update dependencies | | 0.1.13 | 2024-08-10 | [43664](https://github.com/airbytehq/airbyte/pull/43664) | Update dependencies | diff --git a/docs/integrations/sources/smartengage.md b/docs/integrations/sources/smartengage.md index 39706989fddd..f487819db2ed 100644 --- a/docs/integrations/sources/smartengage.md +++ b/docs/integrations/sources/smartengage.md @@ -31,6 +31,10 @@ This source can sync data from the [SmartEngage API](https://smartengage.com/doc | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.2.6 | 2024-12-28 | [50790](https://github.com/airbytehq/airbyte/pull/50790) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50311](https://github.com/airbytehq/airbyte/pull/50311) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49739](https://github.com/airbytehq/airbyte/pull/49739) | Update dependencies | +| 0.2.3 | 2024-12-12 | [47929](https://github.com/airbytehq/airbyte/pull/47929) | Update dependencies | | 0.2.2 | 2024-10-28 | [47507](https://github.com/airbytehq/airbyte/pull/47507) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-14 | [44064](https://github.com/airbytehq/airbyte/pull/44064) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/smartreach.md b/docs/integrations/sources/smartreach.md new file mode 100644 index 000000000000..1ca88b0d7661 --- /dev/null +++ b/docs/integrations/sources/smartreach.md @@ -0,0 +1,33 @@ +# Smartreach +Smartreach is a sales engagement platform. +Using this connector we extract data from two streams : campaigns and prospects. +Docs : https://smartreach.io/api_docs#smartreach-api + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | +| `teamid` | `number` | TeamID. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| campaigns | id | No pagination | ✅ | ❌ | +| prospects | | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50814](https://github.com/airbytehq/airbyte/pull/50814) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50351](https://github.com/airbytehq/airbyte/pull/50351) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49749](https://github.com/airbytehq/airbyte/pull/49749) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49406](https://github.com/airbytehq/airbyte/pull/49406) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49113](https://github.com/airbytehq/airbyte/pull/49113) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-01 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/smartsheets.md b/docs/integrations/sources/smartsheets.md index f03ac7130ca9..61a96ac1d3aa 100644 --- a/docs/integrations/sources/smartsheets.md +++ b/docs/integrations/sources/smartsheets.md @@ -117,6 +117,11 @@ The remaining column datatypes supported by Smartsheets are more complex types ( | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :-------------------------------------------------------- | +| 1.1.29 | 2024-12-28 | [50747](https://github.com/airbytehq/airbyte/pull/50747) | Update dependencies | +| 1.1.28 | 2024-12-21 | [50382](https://github.com/airbytehq/airbyte/pull/50382) | Update dependencies | +| 1.1.27 | 2024-12-14 | [49441](https://github.com/airbytehq/airbyte/pull/49441) | Update dependencies | +| 1.1.26 | 2024-11-25 | [48646](https://github.com/airbytehq/airbyte/pull/48646) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 1.1.25 | 2024-11-04 | [48185](https://github.com/airbytehq/airbyte/pull/48185) | Update dependencies | | 1.1.24 | 2024-10-28 | [47024](https://github.com/airbytehq/airbyte/pull/47024) | Update dependencies | | 1.1.23 | 2024-10-12 | [46783](https://github.com/airbytehq/airbyte/pull/46783) | Update dependencies | | 1.1.22 | 2024-10-05 | [46427](https://github.com/airbytehq/airbyte/pull/46427) | Update dependencies | diff --git a/docs/integrations/sources/smartwaiver.md b/docs/integrations/sources/smartwaiver.md index 858be5114aba..8888e81e8a50 100644 --- a/docs/integrations/sources/smartwaiver.md +++ b/docs/integrations/sources/smartwaiver.md @@ -30,6 +30,11 @@ Due to some limitation of SmartWaiver API it can have situations where you won't | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50757](https://github.com/airbytehq/airbyte/pull/50757) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50304](https://github.com/airbytehq/airbyte/pull/50304) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49732](https://github.com/airbytehq/airbyte/pull/49732) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49435](https://github.com/airbytehq/airbyte/pull/49435) | Update dependencies | +| 0.0.3 | 2024-12-11 | [49117](https://github.com/airbytehq/airbyte/pull/49117) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.2 | 2024-10-29 | [47825](https://github.com/airbytehq/airbyte/pull/47825) | Update dependencies | | 0.0.1 | 2024-10-09 | | Initial release by [@avirajsingh7](https://github.com/avirajsingh7) via Connector Builder | diff --git a/docs/integrations/sources/snapchat-marketing.md b/docs/integrations/sources/snapchat-marketing.md index a998c9ed3291..b532cb9d22b7 100644 --- a/docs/integrations/sources/snapchat-marketing.md +++ b/docs/integrations/sources/snapchat-marketing.md @@ -143,6 +143,10 @@ Syncing data with an hourly granularity often generates large data volumes and c | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:-------------------------------------------------------------------------------| +| 1.3.5 | 2024-12-28 | [50796](https://github.com/airbytehq/airbyte/pull/50796) | Update dependencies | +| 1.3.4 | 2024-12-21 | [50308](https://github.com/airbytehq/airbyte/pull/50308) | Update dependencies | +| 1.3.3 | 2024-12-14 | [49414](https://github.com/airbytehq/airbyte/pull/49414) | Update dependencies | +| 1.3.2 | 2024-11-05 | [48375](https://github.com/airbytehq/airbyte/pull/48375) | Re-implement advanced_auth in connector spec | | 1.3.1 | 2024-10-29 | [47837](https://github.com/airbytehq/airbyte/pull/47837) | Update dependencies | | 1.3.0 | 2024-10-15 | [46927](https://github.com/airbytehq/airbyte/pull/46927) | Promoting release candidate 1.3.0-rc.1 to a main version. | | 1.3.0-rc.1 | 2024-10-08 | [46570](https://github.com/airbytehq/airbyte/pull/46570) | Migrate to Manifest-only | diff --git a/docs/integrations/sources/snowflake.md b/docs/integrations/sources/snowflake.md index 8ee0d20b2a06..d582de1d6c00 100644 --- a/docs/integrations/sources/snowflake.md +++ b/docs/integrations/sources/snowflake.md @@ -140,21 +140,23 @@ To read more please check official [Snowflake documentation](https://docs.snowfl | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------| -| 0.3.3 | 2024-06-28 | [40424](https://github.com/airbytehq/airbyte/pull/40424) | Support Snowflake key pair authentication | -| 0.3.2 | 2024-02-13 | [38317](https://github.com/airbytehq/airbyte/pull/38317) | Hide oAuth option from connector | -| 0.3.1 | 2024-02-13 | [35220](https://github.com/airbytehq/airbyte/pull/35220) | Adopt CDK 0.20.4 | -| 0.3.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | -| 0.3.0 | 2023-12-18 | [33484](https://github.com/airbytehq/airbyte/pull/33484) | Remove LEGACY state | -| 0.2.2 | 2023-10-20 | [31613](https://github.com/airbytehq/airbyte/pull/31613) | Fixed handling of TIMESTAMP_TZ columns. upgrade | -| 0.2.1 | 2023-10-11 | [31252](https://github.com/airbytehq/airbyte/pull/31252) | Snowflake JDBC version upgrade | -| 0.2.0 | 2023-06-26 | [27737](https://github.com/airbytehq/airbyte/pull/27737) | License Update: Elv2 | -| 0.1.36 | 2023-06-20 | [27212](https://github.com/airbytehq/airbyte/pull/27212) | Fix silent exception swallowing in StreamingJdbcDatabase | -| 0.1.35 | 2023-06-14 | [27335](https://github.com/airbytehq/airbyte/pull/27335) | Remove noisy debug logs | -| 0.1.34 | 2023-03-30 | [24693](https://github.com/airbytehq/airbyte/pull/24693) | Fix failure with TIMESTAMP_WITH_TIMEZONE column being used as cursor | -| 0.1.33 | 2023-03-29 | [24667](https://github.com/airbytehq/airbyte/pull/24667) | Fix bug which wont allow TIMESTAMP_WITH_TIMEZONE column to be used as a cursor | -| 0.1.32 | 2023-03-22 | [20760](https://github.com/airbytehq/airbyte/pull/20760) | Removed redundant date-time datatypes formatting | -| 0.1.31 | 2023-03-06 | [23455](https://github.com/airbytehq/airbyte/pull/23455) | For network isolation, source connector accepts a list of hosts it is allowed to connect to | -| 0.1.30 | 2023-02-21 | [22358](https://github.com/airbytehq/airbyte/pull/22358) | Improved handling of big integer cursor type values. | +| 0.3.5 | 2024-12-18 | [49911](https://github.com/airbytehq/airbyte/pull/49911) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.3.4 | 2024-10-31 | [48073](https://github.com/airbytehq/airbyte/pull/48073) | Upgrade jdbc driver | +| 0.3.3 | 2024-06-28 | [40424](https://github.com/airbytehq/airbyte/pull/40424) | Support Snowflake key pair authentication | +| 0.3.2 | 2024-02-13 | [38317](https://github.com/airbytehq/airbyte/pull/38317) | Hide oAuth option from connector | +| 0.3.1 | 2024-02-13 | [35220](https://github.com/airbytehq/airbyte/pull/35220) | Adopt CDK 0.20.4 | +| 0.3.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | +| 0.3.0 | 2023-12-18 | [33484](https://github.com/airbytehq/airbyte/pull/33484) | Remove LEGACY state | +| 0.2.2 | 2023-10-20 | [31613](https://github.com/airbytehq/airbyte/pull/31613) | Fixed handling of TIMESTAMP_TZ columns. upgrade | +| 0.2.1 | 2023-10-11 | [31252](https://github.com/airbytehq/airbyte/pull/31252) | Snowflake JDBC version upgrade | +| 0.2.0 | 2023-06-26 | [27737](https://github.com/airbytehq/airbyte/pull/27737) | License Update: Elv2 | +| 0.1.36 | 2023-06-20 | [27212](https://github.com/airbytehq/airbyte/pull/27212) | Fix silent exception swallowing in StreamingJdbcDatabase | +| 0.1.35 | 2023-06-14 | [27335](https://github.com/airbytehq/airbyte/pull/27335) | Remove noisy debug logs | +| 0.1.34 | 2023-03-30 | [24693](https://github.com/airbytehq/airbyte/pull/24693) | Fix failure with TIMESTAMP_WITH_TIMEZONE column being used as cursor | +| 0.1.33 | 2023-03-29 | [24667](https://github.com/airbytehq/airbyte/pull/24667) | Fix bug which wont allow TIMESTAMP_WITH_TIMEZONE column to be used as a cursor | +| 0.1.32 | 2023-03-22 | [20760](https://github.com/airbytehq/airbyte/pull/20760) | Removed redundant date-time datatypes formatting | +| 0.1.31 | 2023-03-06 | [23455](https://github.com/airbytehq/airbyte/pull/23455) | For network isolation, source connector accepts a list of hosts it is allowed to connect to | +| 0.1.30 | 2023-02-21 | [22358](https://github.com/airbytehq/airbyte/pull/22358) | Improved handling of big integer cursor type values. | | 0.1.29 | 2022-12-14 | [20436](https://github.com/airbytehq/airbyte/pull/20346) | Consolidate date/time values mapping for JDBC sources. | | 0.1.28 | 2023-01-06 | [20465](https://github.com/airbytehq/airbyte/pull/20465) | Improve the schema config field to only discover tables from the specified scehma and make the field optional | | 0.1.27 | 2022-12-14 | [20407](https://github.com/airbytehq/airbyte/pull/20407) | Fix an issue with integer values converted to floats during replication | @@ -184,4 +186,4 @@ To read more please check official [Snowflake documentation](https://docs.snowfl | 0.1.2 | 2021-10-21 | [7257](https://github.com/airbytehq/airbyte/pull/7257) | Fixed parsing of extreme values for FLOAT and NUMBER data types | | 0.1.1 | 2021-08-13 | [4699](https://github.com/airbytehq/airbyte/pull/4699) | Added json config validator | - \ No newline at end of file + diff --git a/docs/integrations/sources/solarwinds-service-desk.md b/docs/integrations/sources/solarwinds-service-desk.md index 2b9f20739849..e88c2c3835ac 100644 --- a/docs/integrations/sources/solarwinds-service-desk.md +++ b/docs/integrations/sources/solarwinds-service-desk.md @@ -45,6 +45,11 @@ Documentation: https://apidoc.samanage.com/#section/General-Concepts | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2025-01-04 | [50748](https://github.com/airbytehq/airbyte/pull/50748) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50360](https://github.com/airbytehq/airbyte/pull/50360) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49771](https://github.com/airbytehq/airbyte/pull/49771) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49418](https://github.com/airbytehq/airbyte/pull/49418) | Update dependencies | +| 0.0.3 | 2024-12-11 | [49111](https://github.com/airbytehq/airbyte/pull/49111) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.0.2 | 2024-10-29 | [47855](https://github.com/airbytehq/airbyte/pull/47855) | Update dependencies | | 0.0.1 | 2024-10-10 | [46707](https://github.com/airbytehq/airbyte/pull/46707) | Initial release by [@gemsteam](https://github.com/gemsteam) via Connector Builder | diff --git a/docs/integrations/sources/sonar-cloud.md b/docs/integrations/sources/sonar-cloud.md index ca82a32943a2..443f2b6fb39a 100644 --- a/docs/integrations/sources/sonar-cloud.md +++ b/docs/integrations/sources/sonar-cloud.md @@ -30,6 +30,9 @@ This source can sync data from the [Sonar cloud API](https://sonarcloud.io/web_a | Version | Date | Pull Request | Subject | | :------ | :-------------------------------------------------------------------- | :-------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.2.5 | 2024-12-28 | [50381](https://github.com/airbytehq/airbyte/pull/50381) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49746](https://github.com/airbytehq/airbyte/pull/49746) | Update dependencies | +| 0.2.3 | 2024-12-12 | [48338](https://github.com/airbytehq/airbyte/pull/48338) | Update dependencies | | 0.2.2 | 2024-10-28 | [47673](https://github.com/airbytehq/airbyte/pull/47673) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-14 | [44063](https://github.com/airbytehq/airbyte/pull/44063) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/spacex-api.md b/docs/integrations/sources/spacex-api.md index 6bd34b441bf0..1f50f07f6819 100644 --- a/docs/integrations/sources/spacex-api.md +++ b/docs/integrations/sources/spacex-api.md @@ -75,6 +75,10 @@ The SpaceX API has both v4 and v5 for [launches](https://github.com/r-spacex/Spa | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:--------------------------------------------------| +| 0.2.6 | 2024-12-28 | [50819](https://github.com/airbytehq/airbyte/pull/50819) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50354](https://github.com/airbytehq/airbyte/pull/50354) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49752](https://github.com/airbytehq/airbyte/pull/49752) | Update dependencies | +| 0.2.3 | 2024-12-12 | [48197](https://github.com/airbytehq/airbyte/pull/48197) | Update dependencies | | 0.2.2 | 2024-10-28 | [47561](https://github.com/airbytehq/airbyte/pull/47561) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-09 | [43431](https://github.com/airbytehq/airbyte/pull/43431) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/sparkpost.md b/docs/integrations/sources/sparkpost.md index 0eb783f8a63b..0bea054f051a 100644 --- a/docs/integrations/sources/sparkpost.md +++ b/docs/integrations/sources/sparkpost.md @@ -27,6 +27,11 @@ The SparkPost connector for Airbyte enables seamless integration with SparkPost | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.8 | 2024-12-28 | [50792](https://github.com/airbytehq/airbyte/pull/50792) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50312](https://github.com/airbytehq/airbyte/pull/50312) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49741](https://github.com/airbytehq/airbyte/pull/49741) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49398](https://github.com/airbytehq/airbyte/pull/49398) | Update dependencies | +| 0.0.4 | 2024-11-04 | [48315](https://github.com/airbytehq/airbyte/pull/48315) | Update dependencies | | 0.0.3 | 2024-10-29 | [47815](https://github.com/airbytehq/airbyte/pull/47815) | Update dependencies | | 0.0.2 | 2024-10-28 | [47612](https://github.com/airbytehq/airbyte/pull/47612) | Update dependencies | | 0.0.1 | 2024-10-22 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | diff --git a/docs/integrations/sources/split-io.md b/docs/integrations/sources/split-io.md index d54990dc6df2..aa5e747464db 100644 --- a/docs/integrations/sources/split-io.md +++ b/docs/integrations/sources/split-io.md @@ -37,6 +37,10 @@ Refer `https://docs.split.io/reference/authentication` for more details. | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.5 | 2024-12-28 | [50791](https://github.com/airbytehq/airbyte/pull/50791) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50320](https://github.com/airbytehq/airbyte/pull/50320) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49735](https://github.com/airbytehq/airbyte/pull/49735) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49402](https://github.com/airbytehq/airbyte/pull/49402) | Update dependencies | | 0.0.1 | 2024-09-18 | [45367](https://github.com/airbytehq/airbyte/pull/45367) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | - \ No newline at end of file + diff --git a/docs/integrations/sources/spotlercrm.md b/docs/integrations/sources/spotlercrm.md new file mode 100644 index 000000000000..0222335e88ee --- /dev/null +++ b/docs/integrations/sources/spotlercrm.md @@ -0,0 +1,35 @@ +# SpotlerCRM +The Airbyte connector for [Spotler CRM](https://spotler.com/) enables seamless data integration, allowing users to sync customer data from Spotler CRM into their data warehouses or other tools. It supports automated data extraction from Spotler CRM, making it easier to analyze and leverage customer insights across multiple platforms. With this connector, businesses can efficiently streamline their customer relationship data and maintain up-to-date records for improved decision-making and marketing efforts. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `access_token` | `string` | Access Token. Access Token to authenticate API requests. Generate it by logging into your CRM system, navigating to Settings / Integrations / API V4, and clicking 'generate new key'. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| accounts | id | DefaultPaginator | ✅ | ❌ | +| contacts | id | DefaultPaginator | ✅ | ❌ | +| opportunities | id | DefaultPaginator | ✅ | ❌ | +| documents | | DefaultPaginator | ✅ | ❌ | +| campaigns | id | DefaultPaginator | ✅ | ❌ | +| cases | id | DefaultPaginator | ✅ | ❌ | +| activities | id | DefaultPaginator | ✅ | ❌ | +| opportunity_histories | id | DefaultPaginator | ✅ | ❌ | +| opportunity_lines | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.4 | 2024-12-28 | [50770](https://github.com/airbytehq/airbyte/pull/50770) | Update dependencies | +| 0.0.3 | 2024-12-21 | [50322](https://github.com/airbytehq/airbyte/pull/50322) | Update dependencies | +| 0.0.2 | 2024-12-14 | [49436](https://github.com/airbytehq/airbyte/pull/49436) | Update dependencies | +| 0.0.1 | 2024-11-08 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/squarespace.md b/docs/integrations/sources/squarespace.md index 605cd3b9272e..d92715141bd6 100644 --- a/docs/integrations/sources/squarespace.md +++ b/docs/integrations/sources/squarespace.md @@ -25,6 +25,11 @@ The Squarespace connector enables seamless integration with your Squarespace sto | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50788](https://github.com/airbytehq/airbyte/pull/50788) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50336](https://github.com/airbytehq/airbyte/pull/50336) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49781](https://github.com/airbytehq/airbyte/pull/49781) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49386](https://github.com/airbytehq/airbyte/pull/49386) | Update dependencies | +| 0.0.3 | 2024-11-04 | [48233](https://github.com/airbytehq/airbyte/pull/48233) | Update dependencies | | 0.0.2 | 2024-10-29 | [47806](https://github.com/airbytehq/airbyte/pull/47806) | Update dependencies | | 0.0.1 | 2024-10-10 | | Initial release by [@avirajsingh7](https://github.com/avirajsingh7) via Connector Builder | diff --git a/docs/integrations/sources/statsig.md b/docs/integrations/sources/statsig.md index e8c7d4ccbec3..554c2a04a476 100644 --- a/docs/integrations/sources/statsig.md +++ b/docs/integrations/sources/statsig.md @@ -43,6 +43,10 @@ See the [API docs](https://docs.statsig.com/http-api) for steps to generate the | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.6 | 2024-12-28 | [50755](https://github.com/airbytehq/airbyte/pull/50755) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50310](https://github.com/airbytehq/airbyte/pull/50310) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49776](https://github.com/airbytehq/airbyte/pull/49776) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49419](https://github.com/airbytehq/airbyte/pull/49419) | Update dependencies | | 0.0.2 | 2024-10-28 | [47473](https://github.com/airbytehq/airbyte/pull/47473) | Update dependencies | | 0.0.1 | 2024-09-27 | | Initial release by [@topefolorunso](https://github.com/topefolorunso) via Connector Builder | diff --git a/docs/integrations/sources/statuspage.md b/docs/integrations/sources/statuspage.md index 51f85a201cff..2803d97084b4 100644 --- a/docs/integrations/sources/statuspage.md +++ b/docs/integrations/sources/statuspage.md @@ -38,7 +38,11 @@ Mailjet APIs are under rate limits for the number of API calls allowed per API k | Version | Date | Pull Request | Subject | |:--------|:-----------| :-------------------------------------------------------- | :---------------------------------------------- | -| 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | +| 0.2.5 | 2025-01-04 | [50749](https://github.com/airbytehq/airbyte/pull/50749) | Update dependencies | +| 0.2.4 | 2024-12-21 | [50348](https://github.com/airbytehq/airbyte/pull/50348) | Update dependencies | +| 0.2.3 | 2024-12-14 | [49782](https://github.com/airbytehq/airbyte/pull/49782) | Update dependencies | +| 0.2.2 | 2024-12-12 | [49426](https://github.com/airbytehq/airbyte/pull/49426) | Update dependencies | +| 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-14 | [44061](https://github.com/airbytehq/airbyte/pull/44061) | Refactor connector to manifest-only format | | 0.1.13 | 2024-08-12 | [43866](https://github.com/airbytehq/airbyte/pull/43866) | Update dependencies | | 0.1.12 | 2024-08-10 | [43525](https://github.com/airbytehq/airbyte/pull/43525) | Update dependencies | diff --git a/docs/integrations/sources/stockdata.md b/docs/integrations/sources/stockdata.md new file mode 100644 index 000000000000..c953bb184721 --- /dev/null +++ b/docs/integrations/sources/stockdata.md @@ -0,0 +1,37 @@ +# StockData +Stockdata provides access to market news for global exchanges, and trading data for US stocks. +With this connector we can extract data from EOD , Intraday and news feeds streams + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | +| `symbols` | `array` | Symbols. | | +| `industries` | `array` | Industries. Specify the industries of entities which have been identified within the article. | | +| `filter_entities` | `boolean` | By default all entities for each article are returned - by setting this to true, only the relevant entities to your query will be returned with each article. For example, if you set symbols=TSLA and filter_entities=true, only "TSLA" entities will be returned with the articles. | false | +| `start_date` | `string` | Start date. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| news_feeds_per_symbol | uuid | DefaultPaginator | ✅ | ✅ | +| news_feeds_per_industry | uuid | DefaultPaginator | ✅ | ✅ | +| eod_data | date.ticker | No pagination | ✅ | ✅ | +| intraday_unadjusted_data | date.ticker | No pagination | ✅ | ✅ | + + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50789](https://github.com/airbytehq/airbyte/pull/50789) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50357](https://github.com/airbytehq/airbyte/pull/50357) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49745](https://github.com/airbytehq/airbyte/pull/49745) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49442](https://github.com/airbytehq/airbyte/pull/49442) | Update dependencies | +| 0.0.1 | 2024-11-08 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/strava.md b/docs/integrations/sources/strava.md index 2af50e6b4f5e..30d1263fc2ca 100644 --- a/docs/integrations/sources/strava.md +++ b/docs/integrations/sources/strava.md @@ -127,6 +127,10 @@ More information about Strava rate limits and adjustments to those limits can be | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.3.5 | 2024-12-28 | [50764](https://github.com/airbytehq/airbyte/pull/50764) | Update dependencies | +| 0.3.4 | 2024-12-21 | [50337](https://github.com/airbytehq/airbyte/pull/50337) | Update dependencies | +| 0.3.3 | 2024-12-14 | [49777](https://github.com/airbytehq/airbyte/pull/49777) | Update dependencies | +| 0.3.2 | 2024-12-12 | [49432](https://github.com/airbytehq/airbyte/pull/49432) | Update dependencies | | 0.3.1 | 2024-10-28 | [47601](https://github.com/airbytehq/airbyte/pull/47601) | Update dependencies | | 0.3.0 | 2024-08-27 | [44820](https://github.com/airbytehq/airbyte/pull/44820) | Refactor connector to manifest-only format | | 0.2.17 | 2024-08-24 | [44667](https://github.com/airbytehq/airbyte/pull/44667) | Update dependencies | diff --git a/docs/integrations/sources/stripe.md b/docs/integrations/sources/stripe.md index bfcca491fac0..f958aac8623d 100644 --- a/docs/integrations/sources/stripe.md +++ b/docs/integrations/sources/stripe.md @@ -110,6 +110,10 @@ The Stripe source connector supports the following streams: - [Payment Intents](https://stripe.com/docs/api/payment_intents/list) \(Incremental\) - [Payment Methods](https://docs.stripe.com/api/payment_methods/customer_list?lang=curl) \(Incremental\) - [Payouts](https://stripe.com/docs/api/payouts/list) \(Incremental\) +- [Payout Balance Transactions](https://docs.stripe.com/api/balance_transactions/list) \(Incremental\) + :::note + This stream is built with a call using payout_id from the payout stream (parent) as a parmeter to the balance transaction API to get balance transactions that comprised the actual amount of the payout. Check [the Stripe docs](https://docs.stripe.com/api/balance_transactions/list) for more details. + ::: - [Promotion Code](https://stripe.com/docs/api/promotion_codes/list) \(Incremental\) - [Persons](https://stripe.com/docs/api/persons/list) \(Incremental\) - [Plans](https://stripe.com/docs/api/plans/list) \(Incremental\) @@ -127,7 +131,7 @@ The Stripe source connector supports the following streams: - [Transactions](https://stripe.com/docs/api/transfers/list) \(Incremental\) - [Transfers](https://stripe.com/docs/api/transfers/list) \(Incremental\) - [Transfer Reversals](https://stripe.com/docs/api/transfer_reversals/list) -- [Usage Records](https://stripe.com/docs/api/usage_records/subscription_item_summary_list) +- [Usage Records](https://stripe.com/docs/api/usage_records) ### Entity-Relationship Diagram (ERD) @@ -193,9 +197,11 @@ On the other hand, the following streams use the `updated` field value as a curs - `External Account Bank Accounts` - `External Account Cards` - `Invoice Items` +- `Invoice Line Items` - `Invoices` - `Payment Intents` - `Payouts` +- `Payout Balance Transactions` - `Promotion Codes` - `Persons` - `Plans` @@ -204,6 +210,7 @@ On the other hand, the following streams use the `updated` field value as a curs - `Reviews` - `Setup Intents` - `Subscription Schedule` +- `Subscription Items` - `Subscriptions` - `Top Ups` - `Transactions` @@ -239,41 +246,45 @@ Each record is marked with `is_deleted` flag when the appropriate event happens | Version | Date | Pull Request | Subject | |:--------|:-----------|:----------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 5.6.2 | 2024-10-05 | [43881](https://github.com/airbytehq/airbyte/pull/43881) | Update dependencies | -| 5.6.1 | 2024-10-03 | [46327](https://github.com/airbytehq/airbyte/pull/46327) | Bump the cdk to 5.10.2 to stop using PrintBuffer optimization due to record count mismatches | -| 5.6.0 | 2024-09-10 | [44891](https://github.com/airbytehq/airbyte/pull/44891) | Update `Payment Methods` stream | -| 5.5.4 | 2024-09-09 | [45348](https://github.com/airbytehq/airbyte/pull/45348) | Remove `stripe` python package | -| 5.5.3 | 2024-09-03 | [45101](https://github.com/airbytehq/airbyte/pull/45101) | Fix regression following pagination issue fix | -| 5.5.2 | 2024-08-28 | [44862](https://github.com/airbytehq/airbyte/pull/44862) | Fix RFR pagination issue | -| 5.5.1 | 2024-08-10 | [43105](https://github.com/airbytehq/airbyte/pull/43105) | Update dependencies | -| 5.5.0 | 2024-08-08 | [43302](https://github.com/airbytehq/airbyte/pull/43302) | Fix problem with state not updating and upgrade cdk 4 | -| 5.4.12 | 2024-07-31 | [41985](https://github.com/airbytehq/airbyte/pull/41985) | Expand Invoice discounts and tax rates | -| 5.4.11 | 2024-07-27 | [42623](https://github.com/airbytehq/airbyte/pull/42623) | Update dependencies | -| 5.4.10 | 2024-07-20 | [42305](https://github.com/airbytehq/airbyte/pull/42305) | Update dependencies | -| 5.4.9 | 2024-07-13 | [41760](https://github.com/airbytehq/airbyte/pull/41760) | Update dependencies | -| 5.4.8 | 2024-07-10 | [41477](https://github.com/airbytehq/airbyte/pull/41477) | Update dependencies | -| 5.4.7 | 2024-07-09 | [40869](https://github.com/airbytehq/airbyte/pull/40869) | Update dependencies | -| 5.4.6 | 2024-07-08 | [41044](https://github.com/airbytehq/airbyte/pull/41044) | Use latest `CDK` version possible | -| 5.4.5 | 2024-06-25 | [40404](https://github.com/airbytehq/airbyte/pull/40404) | Update dependencies | -| 5.4.4 | 2024-06-22 | [40040](https://github.com/airbytehq/airbyte/pull/40040) | Update dependencies | -| 5.4.3 | 2024-06-06 | [39284](https://github.com/airbytehq/airbyte/pull/39284) | [autopull] Upgrade base image to v1.2.2 | -| 5.4.2 | 2024-06-11 | [39412](https://github.com/airbytehq/airbyte/pull/39412) | Removed `invoice.upcomming` event type from (incremental sync) for `Invoices` stream | -| 5.4.1 | 2024-06-11 | [39393](https://github.com/airbytehq/airbyte/pull/39393) | Added missing `event types` (incremental sync) for `Invoices` stream | -| 5.4.0 | 2024-06-05 | [39138](https://github.com/airbytehq/airbyte/pull/39138) | Fixed the `Refunds` stream missing data for the `incremental` sync | -| 5.3.9 | 2024-05-22 | [38550](https://github.com/airbytehq/airbyte/pull/38550) | Update authenticator package | -| 5.3.8 | 2024-05-15 | [38248](https://github.com/airbytehq/airbyte/pull/38248) | Replace AirbyteLogger with logging.Logger | -| 5.3.7 | 2024-04-24 | [36663](https://github.com/airbytehq/airbyte/pull/36663) | Schema descriptions | -| 5.3.6 | 2024-04-18 | [37448](https://github.com/airbytehq/airbyte/pull/37448) | Ensure AirbyteTracedException in concurrent CDK are emitted with the right type | -| 5.3.5 | 2024-04-18 | [37418](https://github.com/airbytehq/airbyte/pull/37418) | Ensure python return code != 0 in case of error | -| 5.3.4 | 2024-04-11 | [37406](https://github.com/airbytehq/airbyte/pull/37406) | Update CDK version to have partitioned state fix | -| 5.3.3 | 2024-04-11 | [37001](https://github.com/airbytehq/airbyte/pull/37001) | Update airbyte-cdk to flush print buffer for every message | -| 5.3.2 | 2024-04-11 | [36964](https://github.com/airbytehq/airbyte/pull/36964) | Update CDK version to fix breaking change before another devs work on it | -| 5.3.1 | 2024-04-10 | [36960](https://github.com/airbytehq/airbyte/pull/36960) | Remove unused imports | -| 5.3.0 | 2024-03-12 | [35978](https://github.com/airbytehq/airbyte/pull/35978) | Upgrade CDK to start emitting record counts with state and full refresh state | -| 5.2.4 | 2024-02-12 | [35137](https://github.com/airbytehq/airbyte/pull/35137) | Fix license in `pyproject.toml` | -| 5.2.3 | 2024-02-09 | [35068](https://github.com/airbytehq/airbyte/pull/35068) | Manage dependencies with Poetry. | -| 5.2.2 | 2024-01-31 | [34619](https://github.com/airbytehq/airbyte/pull/34619) | Events stream concurrent on incremental syncs | -| 5.2.1 | 2024-01-18 | [34495](https://github.com/airbytehq/airbyte/pull/34495) | Fix deadlock issue | +| 5.8.2 | 2024-12-10 | [46499](https://github.com/airbytehq/airbyte/pull/46499) | Source-Stripe: Refactor Customer Balance Transactions | +| 5.8.1 | 2024-12-08 | [46499](https://github.com/airbytehq/airbyte/pull/46499) | Source-Stripe: Add new payout_balance_transactions incremental stream | +| 5.8.0 | 2024-10-12 | [46864](https://github.com/airbytehq/airbyte/pull/46864) | Add incremental stream support to `accounts` stream | +| 5.7.0 | 2024-10-01 | [45860](https://github.com/airbytehq/airbyte/pull/45860) | Add incremental stream support to `invoice_line_items` and `subscription_items` streams | +| 5.6.2 | 2024-10-05 | [43881](https://github.com/airbytehq/airbyte/pull/43881) | Update dependencies | +| 5.6.1 | 2024-10-03 | [46327](https://github.com/airbytehq/airbyte/pull/46327) | Bump the cdk to 5.10.2 to stop using PrintBuffer optimization due to record count mismatches | +| 5.6.0 | 2024-09-10 | [44891](https://github.com/airbytehq/airbyte/pull/44891) | Update `Payment Methods` stream | +| 5.5.4 | 2024-09-09 | [45348](https://github.com/airbytehq/airbyte/pull/45348) | Remove `stripe` python package | +| 5.5.3 | 2024-09-03 | [45101](https://github.com/airbytehq/airbyte/pull/45101) | Fix regression following pagination issue fix | +| 5.5.2 | 2024-08-28 | [44862](https://github.com/airbytehq/airbyte/pull/44862) | Fix RFR pagination issue | +| 5.5.1 | 2024-08-10 | [43105](https://github.com/airbytehq/airbyte/pull/43105) | Update dependencies | +| 5.5.0 | 2024-08-08 | [43302](https://github.com/airbytehq/airbyte/pull/43302) | Fix problem with state not updating and upgrade cdk 4 | +| 5.4.12 | 2024-07-31 | [41985](https://github.com/airbytehq/airbyte/pull/41985) | Expand Invoice discounts and tax rates | +| 5.4.11 | 2024-07-27 | [42623](https://github.com/airbytehq/airbyte/pull/42623) | Update dependencies | +| 5.4.10 | 2024-07-20 | [42305](https://github.com/airbytehq/airbyte/pull/42305) | Update dependencies | +| 5.4.9 | 2024-07-13 | [41760](https://github.com/airbytehq/airbyte/pull/41760) | Update dependencies | +| 5.4.8 | 2024-07-10 | [41477](https://github.com/airbytehq/airbyte/pull/41477) | Update dependencies | +| 5.4.7 | 2024-07-09 | [40869](https://github.com/airbytehq/airbyte/pull/40869) | Update dependencies | +| 5.4.6 | 2024-07-08 | [41044](https://github.com/airbytehq/airbyte/pull/41044) | Use latest `CDK` version possible | +| 5.4.5 | 2024-06-25 | [40404](https://github.com/airbytehq/airbyte/pull/40404) | Update dependencies | +| 5.4.4 | 2024-06-22 | [40040](https://github.com/airbytehq/airbyte/pull/40040) | Update dependencies | +| 5.4.3 | 2024-06-06 | [39284](https://github.com/airbytehq/airbyte/pull/39284) | [autopull] Upgrade base image to v1.2.2 | +| 5.4.2 | 2024-06-11 | [39412](https://github.com/airbytehq/airbyte/pull/39412) | Removed `invoice.upcomming` event type from (incremental sync) for `Invoices` stream | +| 5.4.1 | 2024-06-11 | [39393](https://github.com/airbytehq/airbyte/pull/39393) | Added missing `event types` (incremental sync) for `Invoices` stream | +| 5.4.0 | 2024-06-05 | [39138](https://github.com/airbytehq/airbyte/pull/39138) | Fixed the `Refunds` stream missing data for the `incremental` sync | +| 5.3.9 | 2024-05-22 | [38550](https://github.com/airbytehq/airbyte/pull/38550) | Update authenticator package | +| 5.3.8 | 2024-05-15 | [38248](https://github.com/airbytehq/airbyte/pull/38248) | Replace AirbyteLogger with logging.Logger | +| 5.3.7 | 2024-04-24 | [36663](https://github.com/airbytehq/airbyte/pull/36663) | Schema descriptions | +| 5.3.6 | 2024-04-18 | [37448](https://github.com/airbytehq/airbyte/pull/37448) | Ensure AirbyteTracedException in concurrent CDK are emitted with the right type | +| 5.3.5 | 2024-04-18 | [37418](https://github.com/airbytehq/airbyte/pull/37418) | Ensure python return code != 0 in case of error | +| 5.3.4 | 2024-04-11 | [37406](https://github.com/airbytehq/airbyte/pull/37406) | Update CDK version to have partitioned state fix | +| 5.3.3 | 2024-04-11 | [37001](https://github.com/airbytehq/airbyte/pull/37001) | Update airbyte-cdk to flush print buffer for every message | +| 5.3.2 | 2024-04-11 | [36964](https://github.com/airbytehq/airbyte/pull/36964) | Update CDK version to fix breaking change before another devs work on it | +| 5.3.1 | 2024-04-10 | [36960](https://github.com/airbytehq/airbyte/pull/36960) | Remove unused imports | +| 5.3.0 | 2024-03-12 | [35978](https://github.com/airbytehq/airbyte/pull/35978) | Upgrade CDK to start emitting record counts with state and full refresh state | +| 5.2.4 | 2024-02-12 | [35137](https://github.com/airbytehq/airbyte/pull/35137) | Fix license in `pyproject.toml` | +| 5.2.3 | 2024-02-09 | [35068](https://github.com/airbytehq/airbyte/pull/35068) | Manage dependencies with Poetry. | +| 5.2.2 | 2024-01-31 | [34619](https://github.com/airbytehq/airbyte/pull/34619) | Events stream concurrent on incremental syncs | +| 5.2.1 | 2024-01-18 | [34495](https://github.com/airbytehq/airbyte/pull/34495) | Fix deadlock issue | | 5.2.0 | 2024-01-18 | [34347](https://github.com/airbytehq/airbyte/pull//34347) | Add new fields invoices and subscription streams. Upgrade the CDK for better memory usage. | | 5.1.3 | 2023-12-18 | [33306](https://github.com/airbytehq/airbyte/pull/33306/) | Adding integration tests | | 5.1.2 | 2024-01-04 | [33414](https://github.com/airbytehq/airbyte/pull/33414) | Prepare for airbyte-lib | diff --git a/docs/integrations/sources/survey-sparrow.md b/docs/integrations/sources/survey-sparrow.md index 6e7e11f4da44..16581372cbbc 100644 --- a/docs/integrations/sources/survey-sparrow.md +++ b/docs/integrations/sources/survey-sparrow.md @@ -49,6 +49,10 @@ In order to get access token, follow these steps: | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.3.6 | 2024-12-28 | [50824](https://github.com/airbytehq/airbyte/pull/50824) | Update dependencies | +| 0.3.5 | 2024-12-21 | [50355](https://github.com/airbytehq/airbyte/pull/50355) | Update dependencies | +| 0.3.4 | 2024-12-14 | [49766](https://github.com/airbytehq/airbyte/pull/49766) | Update dependencies | +| 0.3.3 | 2024-12-12 | [48163](https://github.com/airbytehq/airbyte/pull/48163) | Update dependencies | | 0.3.2 | 2024-10-28 | [47506](https://github.com/airbytehq/airbyte/pull/47506) | Update dependencies | | 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.3.0 | 2024-08-14 | [44059](https://github.com/airbytehq/airbyte/pull/44059) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/surveycto.md b/docs/integrations/sources/surveycto.md index 044357d9a61d..ffb52672c42e 100644 --- a/docs/integrations/sources/surveycto.md +++ b/docs/integrations/sources/surveycto.md @@ -52,6 +52,11 @@ The SurveyCTO source connector supports the following streams: | Version | Date | Pull Request | Subject | | ------- | ---------- | -------------------------------------------------------- | -------------------------- | +| 0.1.31 | 2024-12-28 | [50804](https://github.com/airbytehq/airbyte/pull/50804) | Update dependencies | +| 0.1.30 | 2024-12-21 | [50303](https://github.com/airbytehq/airbyte/pull/50303) | Update dependencies | +| 0.1.29 | 2024-12-14 | [49765](https://github.com/airbytehq/airbyte/pull/49765) | Update dependencies | +| 0.1.28 | 2024-12-12 | [49385](https://github.com/airbytehq/airbyte/pull/49385) | Update dependencies | +| 0.1.27 | 2024-11-25 | [48658](https://github.com/airbytehq/airbyte/pull/48658) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.1.26 | 2024-10-29 | [47725](https://github.com/airbytehq/airbyte/pull/47725) | Update dependencies | | 0.1.25 | 2024-10-28 | [47036](https://github.com/airbytehq/airbyte/pull/47036) | Update dependencies | | 0.1.24 | 2024-10-12 | [46834](https://github.com/airbytehq/airbyte/pull/46834) | Update dependencies | diff --git a/docs/integrations/sources/surveymonkey.md b/docs/integrations/sources/surveymonkey.md index c597a0d27150..dbf600c37ecc 100644 --- a/docs/integrations/sources/surveymonkey.md +++ b/docs/integrations/sources/surveymonkey.md @@ -1,72 +1,84 @@ # SurveyMonkey -This page guides you through the process of setting up the SurveyMonkey source connector. +Set up a SurveyMonkey source connector to extract survey, question, response, and collector data from your SurveyMonkey account. :::note -OAuth for Survey Monkey is officially supported only for the US. We are testing how to enable it in the EU at the moment. If you run into any issues, please [reach out to us](mailto:product@airbyte.io) so we can promptly assist you. +Airbyte officially supports OAuth for SurveyMonkey only for the US. If you have any issues, [contact us](https://support.airbyte.com/). ::: - - ## Prerequisites -**For Airbyte Open Source:** +Before you begin, have the following ready. + + +### For Airbyte Open Source -- Access Token +- A [registered SurveyMonkey app](https://developer.surveymonkey.com/apps/) +- A SurveyMonkey access token, found on the Settings page of your SurveyMonkey app +- If your SurveyMonkey app is a Public app, you also need a Client ID and Client Secret, found on the Settings page of your SurveyMonkey app -## Setup guide + +### For Airbyte Cloud -### Step 1: Set up SurveyMonkey +- A [registered SurveyMonkey application](https://developer.surveymonkey.com/apps/) +- A [paid SurveyMonkey account](https://www.surveymonkey.com/pricing/) + -Please read this [docs](https://developer.surveymonkey.com/api/v3/#getting-started). Register your application [here](https://developer.surveymonkey.com/apps/) Then go to Settings and copy your access token +You may want to review SurveyMonkey's [API docs](https://developer.surveymonkey.com/api/v3/#getting-started), but this isn't strictly necessary. -### Step 2: Set up the source connector in Airbyte +## Create the SurveyMonkey source - -**For Airbyte Cloud:** - -1. [Log into your Airbyte Cloud](https://cloud.airbyte.com/workspaces) account. -2. In the left navigation bar, click **Sources**. In the top-right corner, click **+ new source**. -3. On the source setup page, select **SurveyMonkey** from the Source type dropdown and enter a name for this connector. -4. lick `Authenticate your account`. -5. Log in and Authorize to the SurveyMonkey account -6. Choose required Start date -7. click `Set up source`. +### Airbyte Cloud steps + +1. In the left navigation bar, click **Sources**. +2. Click **New source**. +3. Find and click **SurveyMonkey**. +4. Click **Authenticate your SurveyMonkey account**. Log in and authorize Airbyte to access your SurveyMonkey account. +5. Fill out the form. + - **Source name**: A short, descriptive name to help you identify this source in Airbyte. + - **Start Date**: Any data before this date will not be extracted. + - **Origin datacenter of the SurveyMonkey account**: Airbyte needs to know this because API access URLs may depend on the origin datacenter's location. + - **Survey Monkey survey IDs**: If you want to extract specific surveys, enter the IDs of those surveys. If you want to extract all survey data, leave this blank. +6. Click **Set up source**. Wait a moment while Airbyte tests the connection. - -**For Airbyte Open Source:** - -1. Go to local Airbyte page. -2. In the left navigation bar, click **Sources**. In the top-right corner, click **+ new source**. -3. On the source setup page, select **SurveyMonkey** from the Source type dropdown and enter a name for this connector. -4. Add **Access Token** -5. Choose required Start date -6. Click `Set up source`. +### Airbyte Open Source steps + +1. In the left navigation bar, click **Sources**. +2. Click **New source**. +3. Find and click **SurveyMonkey**. +4. Fill out the form. + - **Source name**: A short, descriptive name to help you identify this source in Airbyte. + - **Access Token**: Your SurveyMonkey app's access token. + - **Client ID**: Your SurveyMonkey app's client id. + - **Client Secret**: Your SurveyMonkey app's client secret. + - **Start Date**: Any data before this date will not be extracted. + - **Origin datacenter of the SurveyMonkey account**: Airbyte needs to know this because API access URLs may depend on the origin datacenter's location. + - **Survey Monkey survey IDs**: If you want to extract specific surveys, enter the IDs of those surveys. If you want to extract all survey data, leave this blank. +6. Click **Set up source**. Wait a moment while Airbyte tests the connection. ## Supported streams and sync modes -- [Surveys](https://api.surveymonkey.com/v3/docs?shell#api-endpoints-get-surveys) \(Incremental\) -- [SurveyPages](https://api.surveymonkey.com/v3/docs?shell#api-endpoints-get-surveys-survey_id-pages) -- [SurveyQuestions](https://api.surveymonkey.com/v3/docs?shell#api-endpoints-get-surveys-survey_id-pages-page_id-questions) -- [SurveyResponses](https://api.surveymonkey.com/v3/docs?shell#api-endpoints-get-surveys-id-responses-bulk) \(Incremental\) -- [SurveyCollectors](https://api.surveymonkey.com/v3/docs?shell#api-endpoints-get-surveys-survey_id-collectors) -- [Collectors](https://api.surveymonkey.com/v3/docs?shell#api-endpoints-get-collectors-collector_id-) - -### Performance considerations +You can stream the following data from SurveyMonkey using the [sync modes](/using-airbyte/core-concepts/sync-modes/) indicated. -The SurveyMonkey API applies heavy API quotas for default private apps, which have the following limits: +| Stream | Sync mode | +| :------ | :--------- | +| [Surveys](https://api.surveymonkey.com/v3/docs?shell#api-endpoints-get-surveys) | Full refresh, incremental | +| [SurveyPages](https://api.surveymonkey.com/v3/docs?shell#api-endpoints-get-surveys-survey_id-pages) | Full refresh | +| [SurveyQuestions](https://api.surveymonkey.com/v3/docs?shell#api-endpoints-get-surveys-survey_id-pages-page_id-questions) | Full refresh | +| [SurveyResponses](https://api.surveymonkey.com/v3/docs?shell#api-endpoints-get-surveys-id-responses-bulk) | Full refresh, incremental | +| [SurveyCollectors](https://api.surveymonkey.com/v3/docs?shell#api-endpoints-get-surveys-survey_id-collectors) | Full refresh | +| [Collectors](https://api.surveymonkey.com/v3/docs?shell#api-endpoints-get-collectors-collector_id-) | Full refresh | -- 125 requests per minute -- 500 requests per day +## Rate limits -To cover more data from this source we use caching. +SurveyMonkey's API has [default rate limits](https://developer.surveymonkey.com/api/v3/#request-and-response-limits) for draft and private apps. Airbyte uses caching to economize its usage of the API. However, if you need a higher quota, SurveyMonkey offers temporary and permanent options to increase your rate limits. ## Changelog @@ -75,6 +87,11 @@ To cover more data from this source we use caching. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------- | +| 0.3.33 | 2025-01-04 | [50936](https://github.com/airbytehq/airbyte/pull/50936) | Update dependencies | +| 0.3.32 | 2024-12-28 | [50760](https://github.com/airbytehq/airbyte/pull/50760) | Update dependencies | +| 0.3.31 | 2024-12-21 | [49774](https://github.com/airbytehq/airbyte/pull/49774) | Update dependencies | +| 0.3.30 | 2024-12-12 | [49399](https://github.com/airbytehq/airbyte/pull/49399) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.3.29 | 2024-11-04 | [48168](https://github.com/airbytehq/airbyte/pull/48168) | Update dependencies | | 0.3.28 | 2024-10-29 | [47754](https://github.com/airbytehq/airbyte/pull/47754) | Update dependencies | | 0.3.27 | 2024-10-28 | [47073](https://github.com/airbytehq/airbyte/pull/47073) | Update dependencies | | 0.3.26 | 2024-10-12 | [46801](https://github.com/airbytehq/airbyte/pull/46801) | Update dependencies | diff --git a/docs/integrations/sources/survicate.md b/docs/integrations/sources/survicate.md index c41e8118c96f..941cc0cf1b79 100644 --- a/docs/integrations/sources/survicate.md +++ b/docs/integrations/sources/survicate.md @@ -33,6 +33,11 @@ Refer `https://developers.survicate.com/data-export/setup/#authentication` for m | Version | Date | Pull Request | Subject | | ------------------ | ------------ | -- | ---------------- | +| 0.0.8 | 2024-12-28 | [50801](https://github.com/airbytehq/airbyte/pull/50801) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50313](https://github.com/airbytehq/airbyte/pull/50313) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49747](https://github.com/airbytehq/airbyte/pull/49747) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49420](https://github.com/airbytehq/airbyte/pull/49420) | Update dependencies | +| 0.0.4 | 2024-11-04 | [48278](https://github.com/airbytehq/airbyte/pull/48278) | Update dependencies | | 0.0.3 | 2024-10-29 | [47884](https://github.com/airbytehq/airbyte/pull/47884) | Update dependencies | | 0.0.2 | 2024-10-28 | [47494](https://github.com/airbytehq/airbyte/pull/47494) | Update dependencies | | 0.0.1 | 2024-09-05 | [45163](https://github.com/airbytehq/airbyte/pull/45163) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/systeme.md b/docs/integrations/sources/systeme.md new file mode 100644 index 000000000000..2f0b561ffaef --- /dev/null +++ b/docs/integrations/sources/systeme.md @@ -0,0 +1,35 @@ +# Systeme +Systeme is an all in one marketing platform. +Using this connector we can extarct records from communities , contacts , tags , contact fields and course resources streams. +Docs : https://developer.systeme.io/reference/api + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| communities | id | DefaultPaginator | ✅ | ❌ | +| contacts | id | DefaultPaginator | ✅ | ❌ | +| tags | id | DefaultPaginator | ✅ | ❌ | +| contact_fields | | DefaultPaginator | ✅ | ❌ | +| course_resources | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50817](https://github.com/airbytehq/airbyte/pull/50817) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50307](https://github.com/airbytehq/airbyte/pull/50307) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49763](https://github.com/airbytehq/airbyte/pull/49763) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49428](https://github.com/airbytehq/airbyte/pull/49428) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49124](https://github.com/airbytehq/airbyte/pull/49124) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-30 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/taboola.md b/docs/integrations/sources/taboola.md new file mode 100644 index 000000000000..32e8e6677c18 --- /dev/null +++ b/docs/integrations/sources/taboola.md @@ -0,0 +1,43 @@ +# Taboola +This is the Taboola source that ingests data from the Taboola API. + +Taboola helps you reach customers that convert. Drive business results by reaching people genuinely, effectively at just the right moment https://www.taboola.com/ + +In order to use this source, you must first create an account. Once logged in you can contact Taboola support to provide you with a Client ID, Client Secret and Account ID. Once these credentials have been obtained, you can input them into the appropriate fields. + +You can learn more about the API here https://developers.taboola.com/backstage-api/reference + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `client_id` | `string` | Client ID. | | +| `account_id` | `string` | Account ID. The ID associated with your taboola account | | +| `client_secret` | `string` | Client secret. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| account | id | No pagination | ✅ | ❌ | +| campaigns | id | No pagination | ✅ | ❌ | +| campaign_items | id | No pagination | ✅ | ❌ | +| audience_rules | id | No pagination | ✅ | ❌ | +| conversion_rules | id | No pagination | ✅ | ❌ | +| motion_ads | id | No pagination | ✅ | ❌ | +| audiences | id | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50826](https://github.com/airbytehq/airbyte/pull/50826) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50356](https://github.com/airbytehq/airbyte/pull/50356) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49754](https://github.com/airbytehq/airbyte/pull/49754) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49409](https://github.com/airbytehq/airbyte/pull/49409) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49114](https://github.com/airbytehq/airbyte/pull/49114) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-28 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | + +
diff --git a/docs/integrations/sources/teamtailor.md b/docs/integrations/sources/teamtailor.md index e14befe8dfcc..6e326c3c0949 100644 --- a/docs/integrations/sources/teamtailor.md +++ b/docs/integrations/sources/teamtailor.md @@ -45,6 +45,12 @@ Make sure to have the add-ons installed in your account for using the `nps-respo | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.8 | 2024-12-28 | [50821](https://github.com/airbytehq/airbyte/pull/50821) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50346](https://github.com/airbytehq/airbyte/pull/50346) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49742](https://github.com/airbytehq/airbyte/pull/49742) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49439](https://github.com/airbytehq/airbyte/pull/49439) | Update dependencies | +| 0.0.4 | 2024-12-11 | [49122](https://github.com/airbytehq/airbyte/pull/49122) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.3 | 2024-11-04 | [47909](https://github.com/airbytehq/airbyte/pull/47909) | Update dependencies | | 0.0.2 | 2024-10-28 | [47540](https://github.com/airbytehq/airbyte/pull/47540) | Update dependencies | | 0.0.1 | 2024-10-14 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | diff --git a/docs/integrations/sources/teamwork.md b/docs/integrations/sources/teamwork.md index 95e9db059680..b5c5d311bce1 100644 --- a/docs/integrations/sources/teamwork.md +++ b/docs/integrations/sources/teamwork.md @@ -57,6 +57,12 @@ Your default login username and password could be used as secrets, ref: `https:/ | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.8 | 2024-12-28 | [50758](https://github.com/airbytehq/airbyte/pull/50758) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50362](https://github.com/airbytehq/airbyte/pull/50362) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49757](https://github.com/airbytehq/airbyte/pull/49757) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49429](https://github.com/airbytehq/airbyte/pull/49429) | Update dependencies | +| 0.0.4 | 2024-12-11 | [49119](https://github.com/airbytehq/airbyte/pull/49119) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.3 | 2024-11-04 | [48149](https://github.com/airbytehq/airbyte/pull/48149) | Update dependencies | | 0.0.2 | 2024-10-28 | [47552](https://github.com/airbytehq/airbyte/pull/47552) | Update dependencies | | 0.0.1 | 2024-09-05 | [45155](https://github.com/airbytehq/airbyte/pull/45155) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/tempo.md b/docs/integrations/sources/tempo.md index bbb28349b9fe..7976b9e0ef18 100644 --- a/docs/integrations/sources/tempo.md +++ b/docs/integrations/sources/tempo.md @@ -49,7 +49,12 @@ If there are more endpoints you'd like Airbyte to support, please [create an iss | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :-------------------------------------------------------- | -| 0.4.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | +| 0.4.6 | 2024-12-28 | [50812](https://github.com/airbytehq/airbyte/pull/50812) | Update dependencies | +| 0.4.5 | 2024-12-21 | [50359](https://github.com/airbytehq/airbyte/pull/50359) | Update dependencies | +| 0.4.4 | 2024-12-14 | [49755](https://github.com/airbytehq/airbyte/pull/49755) | Update dependencies | +| 0.4.3 | 2024-12-12 | [49417](https://github.com/airbytehq/airbyte/pull/49417) | Update dependencies | +| 0.4.2 | 2024-12-11 | [47545](https://github.com/airbytehq/airbyte/pull/47545) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.4.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.4.0 | 2024-08-14 | [44058](https://github.com/airbytehq/airbyte/pull/44058) | Refactor connector to manifest-only format | | 0.3.14 | 2024-08-12 | [43843](https://github.com/airbytehq/airbyte/pull/43843) | Update dependencies | | 0.3.13 | 2024-08-10 | [43466](https://github.com/airbytehq/airbyte/pull/43466) | Update dependencies | diff --git a/docs/integrations/sources/teradata.md b/docs/integrations/sources/teradata.md index 8e8cfb32a0fd..e1f50c0c33d9 100644 --- a/docs/integrations/sources/teradata.md +++ b/docs/integrations/sources/teradata.md @@ -66,9 +66,11 @@ You need a Teradata user which has read permissions on the database | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :-------------------------- | -| 0.2.2 | 2024-02-13 | [35219](https://github.com/airbytehq/airbyte/pull/35219) | Adopt CDK 0.20.4 | -| 0.2.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | +| 0.2.4 | 2024-09-05 | [45158](https://github.com/airbytehq/airbyte/pull/45158) | Fix bug in source teradata | +| 0.2.3 | 2024-12-18 | [49894](https://github.com/airbytehq/airbyte/pull/49894) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.2.2 | 2024-02-13 | [35219](https://github.com/airbytehq/airbyte/pull/35219) | Adopt CDK 0.20.4 | +| 0.2.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | | 0.2.0 | 2023-12-18 | https://github.com/airbytehq/airbyte/pull/33485 | Remove LEGACY state | | 0.1.0 | 2022-03-27 | https://github.com/airbytehq/airbyte/pull/24221 | New Source Teradata Vantage | - \ No newline at end of file + diff --git a/docs/integrations/sources/testrail.md b/docs/integrations/sources/testrail.md index cb1eb69397d7..15ae172d7314 100644 --- a/docs/integrations/sources/testrail.md +++ b/docs/integrations/sources/testrail.md @@ -45,6 +45,10 @@ Visit `https://support.testrail.com/hc/en-us/articles/7077196481428-Attachments` | Version | Date | Pull Request | Subject | | ------------------ | ------------ | -- | ---------------- | +| 0.0.6 | 2024-12-28 | [50825](https://github.com/airbytehq/airbyte/pull/50825) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50352](https://github.com/airbytehq/airbyte/pull/50352) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49400](https://github.com/airbytehq/airbyte/pull/49400) | Update dependencies | +| 0.0.3 | 2024-11-04 | [47773](https://github.com/airbytehq/airbyte/pull/47773) | Update dependencies | | 0.0.2 | 2024-10-28 | [47630](https://github.com/airbytehq/airbyte/pull/47630) | Update dependencies | | 0.0.1 | 2024-09-29 | [46250](https://github.com/airbytehq/airbyte/pull/46250) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/the-guardian-api.md b/docs/integrations/sources/the-guardian-api.md index 826490ee0995..b07199f3c02f 100644 --- a/docs/integrations/sources/the-guardian-api.md +++ b/docs/integrations/sources/the-guardian-api.md @@ -113,6 +113,12 @@ The key that you are assigned is rate-limited and as such any applications that | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :--------------------------------------------- | +| 0.2.8 | 2024-12-28 | [50818](https://github.com/airbytehq/airbyte/pull/50818) | Update dependencies | +| 0.2.7 | 2024-12-21 | [50341](https://github.com/airbytehq/airbyte/pull/50341) | Update dependencies | +| 0.2.6 | 2024-12-14 | [49797](https://github.com/airbytehq/airbyte/pull/49797) | Update dependencies | +| 0.2.5 | 2024-12-12 | [49378](https://github.com/airbytehq/airbyte/pull/49378) | Update dependencies | +| 0.2.4 | 2024-12-11 | [48790](https://github.com/airbytehq/airbyte/pull/48790) | Add unit tests for custom components | +| 0.2.3 | 2024-12-11 | [48201](https://github.com/airbytehq/airbyte/pull/48201) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.2 | 2024-10-29 | [47779](https://github.com/airbytehq/airbyte/pull/47779) | Update dependencies | | 0.2.1 | 2024-10-28 | [47456](https://github.com/airbytehq/airbyte/pull/47456) | Update dependencies | | 0.2.0 | 2024-09-06 | [45195](https://github.com/airbytehq/airbyte/pull/45195) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/thinkific.md b/docs/integrations/sources/thinkific.md index 088118788d23..2b51ce61f208 100644 --- a/docs/integrations/sources/thinkific.md +++ b/docs/integrations/sources/thinkific.md @@ -30,6 +30,11 @@ Airbyte connector for Thinkific, allowing you to seamlessly sync data like users | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50799](https://github.com/airbytehq/airbyte/pull/50799) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50338](https://github.com/airbytehq/airbyte/pull/50338) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49798](https://github.com/airbytehq/airbyte/pull/49798) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49377](https://github.com/airbytehq/airbyte/pull/49377) | Update dependencies | +| 0.0.3 | 2024-11-04 | [48142](https://github.com/airbytehq/airbyte/pull/48142) | Update dependencies | | 0.0.2 | 2024-10-29 | [47525](https://github.com/airbytehq/airbyte/pull/47525) | Update dependencies | | 0.0.1 | 2024-10-07 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | diff --git a/docs/integrations/sources/ticketmaster.md b/docs/integrations/sources/ticketmaster.md index 440f106b81fc..ddd48ccb444f 100644 --- a/docs/integrations/sources/ticketmaster.md +++ b/docs/integrations/sources/ticketmaster.md @@ -26,6 +26,12 @@ Buy and sell tickets online for concerts, sports, theater, family and other even | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50795](https://github.com/airbytehq/airbyte/pull/50795) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50368](https://github.com/airbytehq/airbyte/pull/50368) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49773](https://github.com/airbytehq/airbyte/pull/49773) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49412](https://github.com/airbytehq/airbyte/pull/49412) | Update dependencies | +| 0.0.3 | 2024-12-11 | [49123](https://github.com/airbytehq/airbyte/pull/49123) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.2 | 2024-11-04 | [48297](https://github.com/airbytehq/airbyte/pull/48297) | Update dependencies | | 0.0.1 | 2024-10-21 | | Initial release by [@gemsteam](https://github.com/gemsteam) via Connector Builder | diff --git a/docs/integrations/sources/tickettailor.md b/docs/integrations/sources/tickettailor.md new file mode 100644 index 000000000000..a89b4af0bf14 --- /dev/null +++ b/docs/integrations/sources/tickettailor.md @@ -0,0 +1,37 @@ +# TicketTailor +The Airbyte connector for [TicketTailor](https://tickettailor.com) enables seamless extraction of key event data, including details on events, products, vouchers, discounts, check-ins, issued tickets, orders, and waitlists. This integration allows businesses to analyze ticket sales, attendance, and customer interactions, streamlining event management insights. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use. Find it at https://www.getdrip.com/user/edit | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| events_series | id | DefaultPaginator | ✅ | ❌ | +| events | id | DefaultPaginator | ✅ | ❌ | +| products | id | DefaultPaginator | ✅ | ❌ | +| vouchers | id | DefaultPaginator | ✅ | ❌ | +| discounts | id | DefaultPaginator | ✅ | ❌ | +| check_ins | id | DefaultPaginator | ✅ | ❌ | +| issued_tickets | id | DefaultPaginator | ✅ | ❌ | +| orders | id | DefaultPaginator | ✅ | ❌ | +| waitlists | id | DefaultPaginator | ✅ | ❌ | +| vouchers_codes | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50750](https://github.com/airbytehq/airbyte/pull/50750) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50327](https://github.com/airbytehq/airbyte/pull/50327) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49784](https://github.com/airbytehq/airbyte/pull/49784) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49374](https://github.com/airbytehq/airbyte/pull/49374) | Update dependencies | +| 0.0.1 | 2024-11-06 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/tidb.md b/docs/integrations/sources/tidb.md index b8a749feb49e..fc3304764f91 100644 --- a/docs/integrations/sources/tidb.md +++ b/docs/integrations/sources/tidb.md @@ -130,12 +130,13 @@ Now that you have set up the TiDB source connector, check out the following TiDB | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -| 0.3.2 | 2024-02-13 | [35218](https://github.com/airbytehq/airbyte/pull/35218) | Adopt CDK 0.20.4 | -| 0.3.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | -| 0.3.0 | 2023-12-18 | [33485](https://github.com/airbytehq/airbyte/pull/33485) | Remove LEGACY state | -| 0.2.5 | 2023-06-20 | [27212](https://github.com/airbytehq/airbyte/pull/27212) | Fix silent exception swallowing in StreamingJdbcDatabase | -| 0.2.4 | 2023-03-22 | [20760](https://github.com/airbytehq/airbyte/pull/20760) | Removed redundant date-time datatypes formatting | -| 0.2.3 | 2023-03-06 | [23455](https://github.com/airbytehq/airbyte/pull/23455) | For network isolation, source connector accepts a list of hosts it is allowed to connect to | +| 0.3.3 | 2024-12-18 | [49896](https://github.com/airbytehq/airbyte/pull/49896) | Use a base image: airbyte/java-connector-base:1.0.0 | +| 0.3.2 | 2024-02-13 | [35218](https://github.com/airbytehq/airbyte/pull/35218) | Adopt CDK 0.20.4 | +| 0.3.1 | 2024-01-24 | [34453](https://github.com/airbytehq/airbyte/pull/34453) | bump CDK version | +| 0.3.0 | 2023-12-18 | [33485](https://github.com/airbytehq/airbyte/pull/33485) | Remove LEGACY state | +| 0.2.5 | 2023-06-20 | [27212](https://github.com/airbytehq/airbyte/pull/27212) | Fix silent exception swallowing in StreamingJdbcDatabase | +| 0.2.4 | 2023-03-22 | [20760](https://github.com/airbytehq/airbyte/pull/20760) | Removed redundant date-time datatypes formatting | +| 0.2.3 | 2023-03-06 | [23455](https://github.com/airbytehq/airbyte/pull/23455) | For network isolation, source connector accepts a list of hosts it is allowed to connect to | | 0.2.2 | 2022-12-14 | [20436](https://github.com/airbytehq/airbyte/pull/20346) | Consolidate date/time values mapping for JDBC sources | | | 2022-10-13 | [15535](https://github.com/airbytehq/airbyte/pull/16238) | Update incremental query to avoid data missing when new data is inserted at the same time as a sync starts under non-CDC incremental mode | | 0.2.1 | 2022-09-01 | [16238](https://github.com/airbytehq/airbyte/pull/16238) | Emit state messages more frequently | @@ -147,4 +148,4 @@ Now that you have set up the TiDB source connector, check out the following TiDB | 0.1.1 | 2022-04-29 | [12480](https://github.com/airbytehq/airbyte/pull/12480) | Query tables with adaptive fetch size to optimize JDBC memory consumption | | 0.1.0 | 2022-04-19 | [11283](https://github.com/airbytehq/airbyte/pull/11283) | Initial Release | - \ No newline at end of file + diff --git a/docs/integrations/sources/timely.md b/docs/integrations/sources/timely.md index fb69af9e6b6b..a1e3a52e9279 100644 --- a/docs/integrations/sources/timely.md +++ b/docs/integrations/sources/timely.md @@ -37,6 +37,11 @@ The Timely source connector supports the following [sync modes](https://docs.air | Version | Date | Pull Request | Subject | | :------ | :-------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.4.8 | 2024-12-28 | [50777](https://github.com/airbytehq/airbyte/pull/50777) | Update dependencies | +| 0.4.7 | 2024-12-21 | [50349](https://github.com/airbytehq/airbyte/pull/50349) | Update dependencies | +| 0.4.6 | 2024-12-14 | [49769](https://github.com/airbytehq/airbyte/pull/49769) | Update dependencies | +| 0.4.5 | 2024-12-12 | [49387](https://github.com/airbytehq/airbyte/pull/49387) | Update dependencies | +| 0.4.4 | 2024-12-11 | [48307](https://github.com/airbytehq/airbyte/pull/48307) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.4.3 | 2024-10-29 | [47887](https://github.com/airbytehq/airbyte/pull/47887) | Update dependencies | | 0.4.2 | 2024-10-28 | [47503](https://github.com/airbytehq/airbyte/pull/47503) | Update dependencies | | 0.4.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/tinyemail.md b/docs/integrations/sources/tinyemail.md new file mode 100644 index 000000000000..89a2bc85d69f --- /dev/null +++ b/docs/integrations/sources/tinyemail.md @@ -0,0 +1,33 @@ +# Tinyemail +Tinyemail is an email marketing tool. +We can extract data from campaigns and contacts streams using this connector. +[API Docs](https://docs.tinyemail.com/docs/tiny-email/tinyemail) + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| campaigns | id | DefaultPaginator | ✅ | ❌ | +| contacts | id | No pagination | ✅ | ❌ | +| sender_details | id | No pagination | ✅ | ❌ | +| contact_members | | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50815](https://github.com/airbytehq/airbyte/pull/50815) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50340](https://github.com/airbytehq/airbyte/pull/50340) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49779](https://github.com/airbytehq/airbyte/pull/49779) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49437](https://github.com/airbytehq/airbyte/pull/49437) | Update dependencies | +| 0.0.1 | 2024-11-08 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/tmdb.md b/docs/integrations/sources/tmdb.md index 9213a1f29417..b8cd6713cd42 100644 --- a/docs/integrations/sources/tmdb.md +++ b/docs/integrations/sources/tmdb.md @@ -96,6 +96,10 @@ TMDb's [API reference](https://developers.themoviedb.org/3/getting-started/intro | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------- | +| 1.1.6 | 2024-12-28 | [50778](https://github.com/airbytehq/airbyte/pull/50778) | Update dependencies | +| 1.1.5 | 2024-12-21 | [50323](https://github.com/airbytehq/airbyte/pull/50323) | Update dependencies | +| 1.1.4 | 2024-12-14 | [49800](https://github.com/airbytehq/airbyte/pull/49800) | Update dependencies | +| 1.1.3 | 2024-12-12 | [47938](https://github.com/airbytehq/airbyte/pull/47938) | Update dependencies | | 1.1.2 | 2024-10-28 | [47676](https://github.com/airbytehq/airbyte/pull/47676) | Update dependencies | | 1.1.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 1.1.0 | 2024-08-14 | [44057](https://github.com/airbytehq/airbyte/pull/44057) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/todoist.md b/docs/integrations/sources/todoist.md index a933d882ead8..be298f10829e 100644 --- a/docs/integrations/sources/todoist.md +++ b/docs/integrations/sources/todoist.md @@ -46,6 +46,9 @@ List of available streams: | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :--------------------------------------------------------- | +| 0.3.5 | 2024-12-28 | [50823](https://github.com/airbytehq/airbyte/pull/50823) | Update dependencies | +| 0.3.4 | 2024-12-21 | [49737](https://github.com/airbytehq/airbyte/pull/49737) | Update dependencies | +| 0.3.3 | 2024-12-12 | [49430](https://github.com/airbytehq/airbyte/pull/49430) | Update dependencies | | 0.3.2 | 2024-10-29 | [47823](https://github.com/airbytehq/airbyte/pull/47823) | Update dependencies | | 0.3.1 | 2024-10-22 | [47237](https://github.com/airbytehq/airbyte/pull/47237) | Update dependencies | | 0.3.0 | 2024-08-26 | [44775](https://github.com/airbytehq/airbyte/pull/44775) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/toggl.md b/docs/integrations/sources/toggl.md index 24903d38104e..82407ee4f2cb 100644 --- a/docs/integrations/sources/toggl.md +++ b/docs/integrations/sources/toggl.md @@ -38,6 +38,10 @@ Toggl APIs are under rate limits for the number of API calls allowed per API key | Version | Date | Pull Request | Subject | |:--------|:-----------| :-------------------------------------------------------- | :-------------------------------------- | +| 0.2.6 | 2024-12-28 | [50775](https://github.com/airbytehq/airbyte/pull/50775) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50305](https://github.com/airbytehq/airbyte/pull/50305) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49738](https://github.com/airbytehq/airbyte/pull/49738) | Update dependencies | +| 0.2.3 | 2024-12-12 | [49434](https://github.com/airbytehq/airbyte/pull/49434) | Update dependencies | | 0.2.2 | 2024-10-29 | [47883](https://github.com/airbytehq/airbyte/pull/47883) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-14 | [44056](https://github.com/airbytehq/airbyte/pull/44056) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/tplcentral.md b/docs/integrations/sources/tplcentral.md index d5190e4779c6..2f2ae87076e5 100644 --- a/docs/integrations/sources/tplcentral.md +++ b/docs/integrations/sources/tplcentral.md @@ -49,6 +49,11 @@ Please read [How to get your APIs credentials](https://help.3plcentral.com/hc/en | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------- | +| 0.1.30 | 2024-12-28 | [50761](https://github.com/airbytehq/airbyte/pull/50761) | Update dependencies | +| 0.1.29 | 2024-12-21 | [50358](https://github.com/airbytehq/airbyte/pull/50358) | Update dependencies | +| 0.1.28 | 2024-12-14 | [49410](https://github.com/airbytehq/airbyte/pull/49410) | Update dependencies | +| 0.1.27 | 2024-11-25 | [48648](https://github.com/airbytehq/airbyte/pull/48648) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.1.26 | 2024-11-04 | [48200](https://github.com/airbytehq/airbyte/pull/48200) | Update dependencies | | 0.1.25 | 2024-10-28 | [47030](https://github.com/airbytehq/airbyte/pull/47030) | Update dependencies | | 0.1.24 | 2024-10-12 | [46809](https://github.com/airbytehq/airbyte/pull/46809) | Update dependencies | | 0.1.23 | 2024-10-05 | [46508](https://github.com/airbytehq/airbyte/pull/46508) | Update dependencies | diff --git a/docs/integrations/sources/track-pms.md b/docs/integrations/sources/track-pms.md new file mode 100644 index 000000000000..04f0b20afedd --- /dev/null +++ b/docs/integrations/sources/track-pms.md @@ -0,0 +1,107 @@ +# Track PMS +An Airbyte source for the Track Property Management System (PMS) +Enterprise-class property management solutions for vacation rental companies + +Website: https://tnsinc.com/ +API Docs: hhttps://developer.trackhs.com +Authentication Docs: https://developer.trackhs.com/docs/authentication#authentication + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `customer_domain` | `string` | Customer Domain. | | +| `api_key` | `string` | API Key. | | +| `api_secret` | `string` | API Secret. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| units | id | DefaultPaginator | ✅ | ✅ | +| owners | id | DefaultPaginator | ✅ | ✅ | +| fractionals | id | DefaultPaginator | ✅ | ❌ | +| unit-blocks | id | DefaultPaginator | ✅ | ❌ | +| folios | id | DefaultPaginator | ✅ | ❌ | +| nodes | id | DefaultPaginator | ✅ | ❌ | +| units-amenities | id | DefaultPaginator | ✅ | ❌ | +| quotes | id | DefaultPaginator | ✅ | ❌ | +| reservations_v2 | id | DefaultPaginator | ✅ | ✅ | +| reservation-types | id | DefaultPaginator | ✅ | ❌ | +| contacts | id | DefaultPaginator | ✅ | ✅ | +| tags | id | DefaultPaginator | ✅ | ❌ | +| unit-types | id | DefaultPaginator | ✅ | ❌ | +| lodging-types | id | DefaultPaginator | ✅ | ❌ | +| tax-districts | id | DefaultPaginator | ✅ | ❌ | +| tax-policies | id | DefaultPaginator | ✅ | ❌ | +| taxes | id | DefaultPaginator | ✅ | ❌ | +| travel-insurance-products | id | DefaultPaginator | ✅ | ❌ | +| companies | id | DefaultPaginator | ✅ | ✅ | +| contracts | id | DefaultPaginator | ✅ | ❌ | +| fractional_inventory | fraction_id.id | DefaultPaginator | ✅ | ❌ | +| fractional_owners | fraction_id.id | DefaultPaginator | ✅ | ❌ | +| unit_type_daily_pricing_v2 | unit_type_id.rateTypeId | DefaultPaginator | ✅ | ❌ | +| unit_daily_pricing_v2 | unit_id.rateTypeId | DefaultPaginator | ✅ | ❌ | +| unit_taxes | unit_id.id | DefaultPaginator | ✅ | ❌ | +| accounting-items | id | DefaultPaginator | ✅ | ❌ | +| accounting-accounts | id | DefaultPaginator | ✅ | ❌ | +| accounting-transactions | id | DefaultPaginator | ✅ | ❌ | +| accounting-bills | id | DefaultPaginator | ✅ | ❌ | +| accounting-charges | id | DefaultPaginator | ✅ | ❌ | +| maintenance-work-orders | id | DefaultPaginator | ✅ | ✅ | +| unit_taxes_parent | id | DefaultPaginator | ✅ | ✅ | +| users | id | DefaultPaginator | ✅ | ❌ | +| roles | id | DefaultPaginator | ✅ | ❌ | +| crm_company_attachment | | DefaultPaginator | ✅ | ❌ | +| crm-tasks | id | DefaultPaginator | ✅ | ❌ | +| units-amenity-groups | id | DefaultPaginator | ✅ | ❌ | +| nodes-types | id | DefaultPaginator | ✅ | ❌ | +| charges | id | DefaultPaginator | ✅ | ❌ | +| date-groups | id | DefaultPaginator | ✅ | ❌ | +| documents | id | DefaultPaginator | ✅ | ❌ | +| folios-rules | id | DefaultPaginator | ✅ | ❌ | +| folio_logs | id | DefaultPaginator | ✅ | ❌ | +| maintenance-problems | id | DefaultPaginator | ✅ | ❌ | +| owners_units | ownerId.id | DefaultPaginator | ✅ | ❌ | +| owners-contracts | id | DefaultPaginator | ✅ | ❌ | +| owner-statements | id | DefaultPaginator | ✅ | ❌ | +| owner_statment_transactions | id | DefaultPaginator | ✅ | ❌ | +| promo-codes | id | DefaultPaginator | ✅ | ❌ | +| reservations-cancellation-policies | id | DefaultPaginator | ✅ | ❌ | +| reservations-guarantee-policies | id | DefaultPaginator | ✅ | ❌ | +| reservation-cancellation-reasons | id | DefaultPaginator | ✅ | ❌ | +| reservation-discount-reasons | id | DefaultPaginator | ✅ | ❌ | +| units-bed-types | id | DefaultPaginator | ✅ | ❌ | +| custom-fields | id | DefaultPaginator | ✅ | ❌ | +| groups | id | DefaultPaginator | ✅ | ❌ | +| rate-types | id | DefaultPaginator | ✅ | ❌ | +| group_blocks | group_id.id | DefaultPaginator | ✅ | ❌ | +| group_tags | group_id.id | DefaultPaginator | ✅ | ❌ | +| group_breakdown | group_id | DefaultPaginator | ✅ | ❌ | +| suspend-code-reasons | id | DefaultPaginator | ✅ | ❌ | +| units_channel | unit_id.id | DefaultPaginator | ✅ | ❌ | +| housekeeping-work-orders | id | DefaultPaginator | ✅ | ✅ | +| housekeeping-clean-types | id | DefaultPaginator | ✅ | ❌ | +| housekeeping-task-list | id | DefaultPaginator | ✅ | ❌ | +| folios_master_rules | id | DefaultPaginator | ✅ | ❌ | +| contact_companies | contactId.companyId | DefaultPaginator | ✅ | ❌ | +| reviews | id | DefaultPaginator | ✅ | ❌ | +| accounting-deposits | id | DefaultPaginator | ✅ | ❌ | +| accounting-deposits-payments | id | DefaultPaginator | ✅ | ❌ | +| units_pricing_parent | id | DefaultPaginator | ✅ | ✅ | +| unit_types_pricing_parent | id | DefaultPaginator | ✅ | ❌ | +| unit_charge_pricing_parent | id | DefaultPaginator | ✅ | ❌ | +| owners-pii-redacted | id | DefaultPaginator | ✅ | ✅ | +| contacts-pii-redacted | id | DefaultPaginator | ✅ | ✅ | +| owner_statement_transactions_pii_redacted | id | DefaultPaginator | ✅ | ❌ | +| users-pii-redacted | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Subject | +|------------------|------------|----------------| +| 0.0.1 | 2024-10-18 | Initial release by [@blakeflei](https://github.com/blakeflei) via Connector Builder| + +
\ No newline at end of file diff --git a/docs/integrations/sources/tremendous.md b/docs/integrations/sources/tremendous.md new file mode 100644 index 000000000000..dacecdff5924 --- /dev/null +++ b/docs/integrations/sources/tremendous.md @@ -0,0 +1,39 @@ +# Tremendous +Tremendous connector enables seamless integration with Tremendous API. This connector allows organizations to automate and sync reward, incentive, and payout data, tapping into 2000+ payout methods, including ACH, gift cards, PayPal, and prepaid cards, all from a single platform. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. API key to use. You can generate an API key through the Tremendous dashboard under Team Settings > Developers. Save the key once you’ve generated it. | | +| `environment` | `string` | Environment. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| orders | id | DefaultPaginator | ✅ | ❌ | +| products | id | DefaultPaginator | ✅ | ❌ | +| funding_sources | id | DefaultPaginator | ✅ | ❌ | +| account_members | id | DefaultPaginator | ✅ | ❌ | +| campaigns | id | DefaultPaginator | ✅ | ❌ | +| exchange_rates | | DefaultPaginator | ✅ | ❌ | +| organizations | id | DefaultPaginator | ✅ | ❌ | +| balance_transactions | | DefaultPaginator | ✅ | ❌ | +| rewards | id | DefaultPaginator | ✅ | ❌ | +| invoices | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50768](https://github.com/airbytehq/airbyte/pull/50768) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50363](https://github.com/airbytehq/airbyte/pull/50363) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49750](https://github.com/airbytehq/airbyte/pull/49750) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49375](https://github.com/airbytehq/airbyte/pull/49375) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49128](https://github.com/airbytehq/airbyte/pull/49128) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-29 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/trustpilot.md b/docs/integrations/sources/trustpilot.md index 1fba659f9605..019633fc7194 100644 --- a/docs/integrations/sources/trustpilot.md +++ b/docs/integrations/sources/trustpilot.md @@ -61,6 +61,10 @@ The Trustpilot connector should not run into any limits under normal usage. Plea | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :-------------- | +| 0.3.6 | 2024-12-28 | [50751](https://github.com/airbytehq/airbyte/pull/50751) | Update dependencies | +| 0.3.5 | 2024-12-21 | [50371](https://github.com/airbytehq/airbyte/pull/50371) | Update dependencies | +| 0.3.4 | 2024-12-14 | [49751](https://github.com/airbytehq/airbyte/pull/49751) | Update dependencies | +| 0.3.3 | 2024-12-12 | [48193](https://github.com/airbytehq/airbyte/pull/48193) | Update dependencies | | 0.3.2 | 2024-10-29 | [47937](https://github.com/airbytehq/airbyte/pull/47937) | Update dependencies | | 0.3.1 | 2024-10-28 | [47647](https://github.com/airbytehq/airbyte/pull/47647) | Update dependencies | | 0.3.0 | 2024-10-06 | [46529](https://github.com/airbytehq/airbyte/pull/46529) | Migrate to Manifest-only | diff --git a/docs/integrations/sources/tvmaze-schedule.md b/docs/integrations/sources/tvmaze-schedule.md index 2f8f2e548a67..184daaa2beaa 100644 --- a/docs/integrations/sources/tvmaze-schedule.md +++ b/docs/integrations/sources/tvmaze-schedule.md @@ -51,6 +51,11 @@ The following fields are required fields for the connector to work: | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :--------- | +| 0.2.7 | 2024-12-28 | [50766](https://github.com/airbytehq/airbyte/pull/50766) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50332](https://github.com/airbytehq/airbyte/pull/50332) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49740](https://github.com/airbytehq/airbyte/pull/49740) | Update dependencies | +| 0.2.4 | 2024-12-12 | [49438](https://github.com/airbytehq/airbyte/pull/49438) | Update dependencies | +| 0.2.3 | 2024-12-11 | [49108](https://github.com/airbytehq/airbyte/pull/49108) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.2 | 2024-10-28 | [47573](https://github.com/airbytehq/airbyte/pull/47573) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-14 | [44055](https://github.com/airbytehq/airbyte/pull/44055) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/twelve-data.md b/docs/integrations/sources/twelve-data.md index f7cf5f5a2a11..b1f8713079e6 100644 --- a/docs/integrations/sources/twelve-data.md +++ b/docs/integrations/sources/twelve-data.md @@ -44,6 +44,12 @@ Docs : https://twelvedata.com/docs | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50808](https://github.com/airbytehq/airbyte/pull/50808) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50328](https://github.com/airbytehq/airbyte/pull/50328) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49744](https://github.com/airbytehq/airbyte/pull/49744) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49395](https://github.com/airbytehq/airbyte/pull/49395) | Update dependencies | +| 0.0.3 | 2024-12-11 | [49112](https://github.com/airbytehq/airbyte/pull/49112) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.2 | 2024-11-04 | [48167](https://github.com/airbytehq/airbyte/pull/48167) | Update dependencies | | 0.0.1 | 2024-10-20 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | diff --git a/docs/integrations/sources/twilio-taskrouter.md b/docs/integrations/sources/twilio-taskrouter.md index 67b7cde27f23..801faac0f0b7 100644 --- a/docs/integrations/sources/twilio-taskrouter.md +++ b/docs/integrations/sources/twilio-taskrouter.md @@ -61,6 +61,9 @@ For more information, see [the Twilio docs for rate limitations](https://support | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.2.4 | 2024-12-28 | [50816](https://github.com/airbytehq/airbyte/pull/50816) | Update dependencies | +| 0.2.3 | 2024-12-21 | [50366](https://github.com/airbytehq/airbyte/pull/50366) | Update dependencies | +| 0.2.2 | 2024-12-14 | [49383](https://github.com/airbytehq/airbyte/pull/49383) | Update dependencies | | 0.2.1 | 2024-10-28 | [47458](https://github.com/airbytehq/airbyte/pull/47458) | Update dependencies | | 0.2.0 | 2024-08-26 | [44776](https://github.com/airbytehq/airbyte/pull/44776) | Refactor connector to manifest-only format | | 0.1.17 | 2024-08-24 | [44727](https://github.com/airbytehq/airbyte/pull/44727) | Update dependencies | diff --git a/docs/integrations/sources/twilio.md b/docs/integrations/sources/twilio.md index ac1fe5e036d4..b2c72143bcaa 100644 --- a/docs/integrations/sources/twilio.md +++ b/docs/integrations/sources/twilio.md @@ -100,6 +100,8 @@ For more information, see [the Twilio docs for rate limitations](https://support | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------------------------------ | +| 0.11.14 | 2024-12-28 | [50803](https://github.com/airbytehq/airbyte/pull/50803) | Update dependencies | +| 0.11.13 | 2024-11-25 | [43769](https://github.com/airbytehq/airbyte/pull/43769) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.11.12 | 2024-08-03 | [43132](https://github.com/airbytehq/airbyte/pull/43132) | Update dependencies | | 0.11.11 | 2024-07-27 | [42593](https://github.com/airbytehq/airbyte/pull/42593) | Update dependencies | | 0.11.10 | 2024-07-20 | [42177](https://github.com/airbytehq/airbyte/pull/42177) | Update dependencies | diff --git a/docs/integrations/sources/twitter.md b/docs/integrations/sources/twitter.md index 064ec218c5bc..c1d80c4ed558 100644 --- a/docs/integrations/sources/twitter.md +++ b/docs/integrations/sources/twitter.md @@ -41,6 +41,8 @@ Rate limiting is mentioned in the API [documentation](https://developer.twitter. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------ | +| 0.2.3 | 2025-01-04 | [50378](https://github.com/airbytehq/airbyte/pull/50378) | Update dependencies | +| 0.2.2 | 2024-12-14 | [48192](https://github.com/airbytehq/airbyte/pull/48192) | Update dependencies | | 0.2.1 | 2024-10-29 | [44710](https://github.com/airbytehq/airbyte/pull/44710) | Update dependencies | | 0.2.0 | 2024-08-26 | [44777](https://github.com/airbytehq/airbyte/pull/44777) | Refactor connector to manifest-only format | | 0.1.15 | 2024-08-17 | [44289](https://github.com/airbytehq/airbyte/pull/44289) | Update dependencies | diff --git a/docs/integrations/sources/tyntec-sms.md b/docs/integrations/sources/tyntec-sms.md index cb45bf8b3d55..da6f44b0d8c8 100644 --- a/docs/integrations/sources/tyntec-sms.md +++ b/docs/integrations/sources/tyntec-sms.md @@ -65,6 +65,12 @@ The Tyntec SMS connector should not run into limitations under normal usage. Ple | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------ | +| 0.2.8 | 2024-12-28 | [50783](https://github.com/airbytehq/airbyte/pull/50783) | Update dependencies | +| 0.2.7 | 2024-12-21 | [50364](https://github.com/airbytehq/airbyte/pull/50364) | Update dependencies | +| 0.2.6 | 2024-12-14 | [49793](https://github.com/airbytehq/airbyte/pull/49793) | Update dependencies | +| 0.2.5 | 2024-12-12 | [49431](https://github.com/airbytehq/airbyte/pull/49431) | Update dependencies | +| 0.2.4 | 2024-12-11 | [49110](https://github.com/airbytehq/airbyte/pull/49110) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.3 | 2024-11-04 | [47910](https://github.com/airbytehq/airbyte/pull/47910) | Update dependencies | | 0.2.2 | 2024-10-28 | [43782](https://github.com/airbytehq/airbyte/pull/43782) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-14 | [44054](https://github.com/airbytehq/airbyte/pull/44054) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/typeform.md b/docs/integrations/sources/typeform.md index b3012c0cba56..3fac21764fea 100644 --- a/docs/integrations/sources/typeform.md +++ b/docs/integrations/sources/typeform.md @@ -101,6 +101,12 @@ API rate limits \(2 requests per second\): [https://developer.typeform.com/get-s | Version | Date | Pull Request | Subject | |:--------|:-----------| :------------------------------------------------------- |:------------------------------------------------------------------------------------------------| +| 1.3.24 | 2025-01-04 | [50937](https://github.com/airbytehq/airbyte/pull/50937) | Update dependencies | +| 1.3.23 | 2024-12-28 | [50797](https://github.com/airbytehq/airbyte/pull/50797) | Update dependencies | +| 1.3.22 | 2024-12-21 | [50376](https://github.com/airbytehq/airbyte/pull/50376) | Update dependencies | +| 1.3.21 | 2024-12-14 | [49799](https://github.com/airbytehq/airbyte/pull/49799) | Update dependencies | +| 1.3.20 | 2024-12-12 | [49373](https://github.com/airbytehq/airbyte/pull/49373) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 1.3.19 | 2024-11-04 | [48301](https://github.com/airbytehq/airbyte/pull/48301) | Update dependencies | | 1.3.18 | 2024-10-29 | [46853](https://github.com/airbytehq/airbyte/pull/46853) | Update dependencies | | 1.3.17 | 2024-10-05 | [46479](https://github.com/airbytehq/airbyte/pull/46479) | Update dependencies | | 1.3.16 | 2024-09-28 | [46170](https://github.com/airbytehq/airbyte/pull/46170) | Update dependencies | diff --git a/docs/integrations/sources/ubidots.md b/docs/integrations/sources/ubidots.md new file mode 100644 index 000000000000..e2f4146a34d4 --- /dev/null +++ b/docs/integrations/sources/ubidots.md @@ -0,0 +1,34 @@ +# Ubidots +The Ubidots Connector facilitates easy integration with the Ubidots IoT platform, enabling users to fetch, sync, and analyze real-time sensor data. This connector helps streamline IoT workflows by connecting Ubidots with other tools for seamless data processing and insights. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_token` | `string` | API Token. API token to use for authentication. Obtain it from your Ubidots account. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| devices | id | DefaultPaginator | ✅ | ❌ | +| events | id | DefaultPaginator | ✅ | ❌ | +| dashboards | id | DefaultPaginator | ✅ | ❌ | +| variables | id | DefaultPaginator | ✅ | ❌ | +| device_groups | id | DefaultPaginator | ✅ | ❌ | +| device_types | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50806](https://github.com/airbytehq/airbyte/pull/50806) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50334](https://github.com/airbytehq/airbyte/pull/50334) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49758](https://github.com/airbytehq/airbyte/pull/49758) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49388](https://github.com/airbytehq/airbyte/pull/49388) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49127](https://github.com/airbytehq/airbyte/pull/49127) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-10-24 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/unleash.md b/docs/integrations/sources/unleash.md index 958a30d2c26b..2facf3105d2b 100644 --- a/docs/integrations/sources/unleash.md +++ b/docs/integrations/sources/unleash.md @@ -58,6 +58,11 @@ The API key that you are assigned is rate-limited. | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :------------------------------------ | +| 0.2.5 | 2024-12-28 | [50802](https://github.com/airbytehq/airbyte/pull/50802) | Update dependencies | +| 0.2.4 | 2024-12-21 | [50369](https://github.com/airbytehq/airbyte/pull/50369) | Update dependencies | +| 0.2.3 | 2024-12-14 | [49764](https://github.com/airbytehq/airbyte/pull/49764) | Update dependencies | +| 0.2.2 | 2024-12-12 | [49413](https://github.com/airbytehq/airbyte/pull/49413) | Update dependencies | +| 0.2.1 | 2024-12-11 | [48326](https://github.com/airbytehq/airbyte/pull/48326) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.2.0 | 2024-10-06 | [46525](https://github.com/airbytehq/airbyte/pull/46525) | Converting to manifest-only format | | 0.1.18 | 2024-10-05 | [46490](https://github.com/airbytehq/airbyte/pull/46490) | Update dependencies | | 0.1.17 | 2024-09-28 | [46113](https://github.com/airbytehq/airbyte/pull/46113) | Update dependencies | diff --git a/docs/integrations/sources/uppromote.md b/docs/integrations/sources/uppromote.md index 18f1a79b3f58..485277031a74 100644 --- a/docs/integrations/sources/uppromote.md +++ b/docs/integrations/sources/uppromote.md @@ -21,6 +21,10 @@ The Uppromote Connector for Airbyte enables seamless data integration between Up | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50784](https://github.com/airbytehq/airbyte/pull/50784) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50343](https://github.com/airbytehq/airbyte/pull/50343) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49401](https://github.com/airbytehq/airbyte/pull/49401) | Update dependencies | +| 0.0.3 | 2024-11-04 | [47828](https://github.com/airbytehq/airbyte/pull/47828) | Update dependencies | | 0.0.2 | 2024-10-28 | [47589](https://github.com/airbytehq/airbyte/pull/47589) | Update dependencies | | 0.0.1 | 2024-10-10 | | Initial release by [@avirajsingh7](https://github.com/avirajsingh7) via Connector Builder | diff --git a/docs/integrations/sources/us-census.md b/docs/integrations/sources/us-census.md index c6bf74b64869..d9c91c98d97b 100644 --- a/docs/integrations/sources/us-census.md +++ b/docs/integrations/sources/us-census.md @@ -45,6 +45,9 @@ In addition, to understand how to configure the dataset path and query parameter | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------ | +| 0.3.5 | 2024-12-28 | [50809](https://github.com/airbytehq/airbyte/pull/50809) | Update dependencies | +| 0.3.4 | 2024-12-21 | [50329](https://github.com/airbytehq/airbyte/pull/50329) | Update dependencies | +| 0.3.3 | 2024-12-14 | [48255](https://github.com/airbytehq/airbyte/pull/48255) | Update dependencies | | 0.3.2 | 2024-10-29 | [47845](https://github.com/airbytehq/airbyte/pull/47845) | Update dependencies | | 0.3.1 | 2024-10-28 | [47119](https://github.com/airbytehq/airbyte/pull/47119) | Update dependencies | | 0.3.0 | 2024-10-22 | [47246](https://github.com/airbytehq/airbyte/pull/47246) | Migrate to manifest-only format | diff --git a/docs/integrations/sources/uservoice.md b/docs/integrations/sources/uservoice.md index b385d2356186..b3d4920fad1d 100644 --- a/docs/integrations/sources/uservoice.md +++ b/docs/integrations/sources/uservoice.md @@ -53,6 +53,10 @@ Airbyte connector for UserVoice.com allows users to efficiently extract data fro | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50773](https://github.com/airbytehq/airbyte/pull/50773) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50318](https://github.com/airbytehq/airbyte/pull/50318) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49397](https://github.com/airbytehq/airbyte/pull/49397) | Update dependencies | +| 0.0.3 | 2024-11-04 | [48290](https://github.com/airbytehq/airbyte/pull/48290) | Update dependencies | | 0.0.2 | 2024-10-28 | [47500](https://github.com/airbytehq/airbyte/pull/47500) | Update dependencies | | 0.0.1 | 2024-10-16 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | diff --git a/docs/integrations/sources/vantage.md b/docs/integrations/sources/vantage.md index 67aa445ec215..5218e4a089de 100644 --- a/docs/integrations/sources/vantage.md +++ b/docs/integrations/sources/vantage.md @@ -35,6 +35,9 @@ Vantage APIs are under rate limits for the number of API calls allowed per API k | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :---------------------------------------- | +| 0.2.5 | 2024-12-28 | [50785](https://github.com/airbytehq/airbyte/pull/50785) | Update dependencies | +| 0.2.4 | 2024-12-21 | [50317](https://github.com/airbytehq/airbyte/pull/50317) | Update dependencies | +| 0.2.3 | 2024-12-14 | [48209](https://github.com/airbytehq/airbyte/pull/48209) | Update dependencies | | 0.2.2 | 2024-10-28 | [47657](https://github.com/airbytehq/airbyte/pull/47657) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | | 0.2.0 | 2024-08-14 | [44053](https://github.com/airbytehq/airbyte/pull/44053) | Refactor connector to manifest-only format | diff --git a/docs/integrations/sources/veeqo.md b/docs/integrations/sources/veeqo.md index 75c165963284..0ccb3a3ef963 100644 --- a/docs/integrations/sources/veeqo.md +++ b/docs/integrations/sources/veeqo.md @@ -30,6 +30,11 @@ Veeqo Airbyte connector for Veeqo enables seamless data integration between Veeq | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.8 | 2024-12-28 | [50756](https://github.com/airbytehq/airbyte/pull/50756) | Update dependencies | +| 0.0.7 | 2024-12-21 | [50344](https://github.com/airbytehq/airbyte/pull/50344) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49789](https://github.com/airbytehq/airbyte/pull/49789) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49408](https://github.com/airbytehq/airbyte/pull/49408) | Update dependencies | +| 0.0.4 | 2024-11-04 | [48254](https://github.com/airbytehq/airbyte/pull/48254) | Update dependencies | | 0.0.3 | 2024-10-29 | [47811](https://github.com/airbytehq/airbyte/pull/47811) | Update dependencies | | 0.0.2 | 2024-10-28 | [47488](https://github.com/airbytehq/airbyte/pull/47488) | Update dependencies | | 0.0.1 | 2024-10-17 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | diff --git a/docs/integrations/sources/vercel.md b/docs/integrations/sources/vercel.md new file mode 100644 index 000000000000..d7fb0690b051 --- /dev/null +++ b/docs/integrations/sources/vercel.md @@ -0,0 +1,38 @@ +# Vercel + Vercel connector enables seamless data sync between Vercel projects and various destinations. This integration simplifies real-time deployments, analytics, and automated workflows by bridging data from Vercel to your destination. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `start_date` | `string` | Start date. | | +| `access_token` | `string` | Access Token. Access token to authenticate with the Vercel API. Create and manage tokens in your Vercel account settings. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| projects | id | DefaultPaginator | ✅ | ❌ | +| teams | id | DefaultPaginator | ✅ | ❌ | +| user | | DefaultPaginator | ✅ | ❌ | +| deployments | uid | DefaultPaginator | ✅ | ✅ | +| checks | | DefaultPaginator | ✅ | ❌ | +| environments | | DefaultPaginator | ✅ | ❌ | +| auth_tokens | id | DefaultPaginator | ✅ | ❌ | +| aliases | uid | DefaultPaginator | ✅ | ✅ | +| deployment_events | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50822](https://github.com/airbytehq/airbyte/pull/50822) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50373](https://github.com/airbytehq/airbyte/pull/50373) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49786](https://github.com/airbytehq/airbyte/pull/49786) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49421](https://github.com/airbytehq/airbyte/pull/49421) | Update dependencies | +| 0.0.2 | 2024-11-04 | [48270](https://github.com/airbytehq/airbyte/pull/48270) | Update dependencies | +| 0.0.1 | 2024-10-22 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/visma-economic.md b/docs/integrations/sources/visma-economic.md index 2081408689dc..7e5588d8d446 100644 --- a/docs/integrations/sources/visma-economic.md +++ b/docs/integrations/sources/visma-economic.md @@ -52,6 +52,10 @@ For more information about the api see the [E-conomic REST API Documentation](ht | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.3.7 | 2024-12-28 | [50787](https://github.com/airbytehq/airbyte/pull/50787) | Update dependencies | +| 0.3.6 | 2024-12-21 | [50319](https://github.com/airbytehq/airbyte/pull/50319) | Update dependencies | +| 0.3.5 | 2024-12-14 | [49733](https://github.com/airbytehq/airbyte/pull/49733) | Update dependencies | +| 0.3.4 | 2024-12-12 | [48198](https://github.com/airbytehq/airbyte/pull/48198) | Update dependencies | | 0.3.3 | 2024-10-29 | [47761](https://github.com/airbytehq/airbyte/pull/47761) | Update dependencies | | 0.3.2 | 2024-10-28 | [47543](https://github.com/airbytehq/airbyte/pull/47543) | Update dependencies | | 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/vwo.md b/docs/integrations/sources/vwo.md index 08cbd4a3e8a8..e6b06b23d9f8 100644 --- a/docs/integrations/sources/vwo.md +++ b/docs/integrations/sources/vwo.md @@ -34,6 +34,10 @@ Visit `https://developers.vwo.com/reference/introduction-1` for API documentatio | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.6 | 2024-12-28 | [50798](https://github.com/airbytehq/airbyte/pull/50798) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50314](https://github.com/airbytehq/airbyte/pull/50314) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49767](https://github.com/airbytehq/airbyte/pull/49767) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49411](https://github.com/airbytehq/airbyte/pull/49411) | Update dependencies | | 0.0.2 | 2024-10-29 | [47475](https://github.com/airbytehq/airbyte/pull/47475) | Update dependencies | | 0.0.1 | 2024-09-23 | [45851](https://github.com/airbytehq/airbyte/pull/45851) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/waiteraid.md b/docs/integrations/sources/waiteraid.md index 3e4e2254e66b..50b6d310cd8f 100644 --- a/docs/integrations/sources/waiteraid.md +++ b/docs/integrations/sources/waiteraid.md @@ -61,6 +61,10 @@ The Waiteraid source connector supports the following [sync modes](https://docs. | Version | Date | Pull Request | Subject | | :------ | :--------- | :----------------------------------------------------- | :-------------------- | +| 0.2.7 | 2024-12-28 | [50810](https://github.com/airbytehq/airbyte/pull/50810) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50372](https://github.com/airbytehq/airbyte/pull/50372) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49770](https://github.com/airbytehq/airbyte/pull/49770) | Update dependencies | +| 0.2.4 | 2024-12-12 | [49405](https://github.com/airbytehq/airbyte/pull/49405) | Update dependencies | | 0.2.3 | 2024-10-29 | [47835](https://github.com/airbytehq/airbyte/pull/47835) | Update dependencies | | 0.2.2 | 2024-10-28 | [47610](https://github.com/airbytehq/airbyte/pull/47610) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/web-scrapper.md b/docs/integrations/sources/web-scrapper.md new file mode 100644 index 000000000000..e9058c8366ee --- /dev/null +++ b/docs/integrations/sources/web-scrapper.md @@ -0,0 +1,34 @@ +# Web Scrapper +[Web Scrapper](https://webscraper.io/documentation/web-scraper-cloud/api) connector enables data synchronization from Web Scrapper source to various data destination. It gives information about sitemaps, users, scraping jobs etc. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_token` | `string` | API Token. API token to use. Find it at https://cloud.webscraper.io/api | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| sitemap_list | id | DefaultPaginator | ✅ | ❌ | +| sitemap_detail | id | DefaultPaginator | ✅ | ❌ | +| users | | No pagination | ✅ | ❌ | +| scraping_jobs | id | DefaultPaginator | ✅ | ❌ | +| scraping_job_data_quality | | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50754](https://github.com/airbytehq/airbyte/pull/50754) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50370](https://github.com/airbytehq/airbyte/pull/50370) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49778](https://github.com/airbytehq/airbyte/pull/49778) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49393](https://github.com/airbytehq/airbyte/pull/49393) | Update dependencies | +| 0.0.3 | 2024-12-11 | [49115](https://github.com/airbytehq/airbyte/pull/49115) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.2 | 2024-11-04 | [48269](https://github.com/airbytehq/airbyte/pull/48269) | Update dependencies | +| 0.0.1 | 2024-10-29 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/webflow.md b/docs/integrations/sources/webflow.md index 6044a3a44ac1..3ecc23b043e9 100644 --- a/docs/integrations/sources/webflow.md +++ b/docs/integrations/sources/webflow.md @@ -41,6 +41,11 @@ If you are interested in learning more about the Webflow API and implementation | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :--------------------------------------------------------------------- | +| 0.1.31 | 2024-12-28 | [50811](https://github.com/airbytehq/airbyte/pull/50811) | Update dependencies | +| 0.1.30 | 2024-12-21 | [50367](https://github.com/airbytehq/airbyte/pull/50367) | Update dependencies | +| 0.1.29 | 2024-12-14 | [49759](https://github.com/airbytehq/airbyte/pull/49759) | Update dependencies | +| 0.1.28 | 2024-12-12 | [49391](https://github.com/airbytehq/airbyte/pull/49391) | Update dependencies | +| 0.1.27 | 2024-11-25 | [48643](https://github.com/airbytehq/airbyte/pull/48643) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.1.26 | 2024-10-29 | [47871](https://github.com/airbytehq/airbyte/pull/47871) | Update dependencies | | 0.1.25 | 2024-10-28 | [47102](https://github.com/airbytehq/airbyte/pull/47102) | Update dependencies | | 0.1.24 | 2024-10-12 | [46854](https://github.com/airbytehq/airbyte/pull/46854) | Update dependencies | diff --git a/docs/integrations/sources/when-i-work.md b/docs/integrations/sources/when-i-work.md index 9bd0b1c2a7f0..fd8561237a59 100644 --- a/docs/integrations/sources/when-i-work.md +++ b/docs/integrations/sources/when-i-work.md @@ -38,6 +38,11 @@ You have to give your login email and password used with `when-i-work` account f | Version | Date | Pull Request | Subject | | ------------------ | ------------ | --- | ---------------- | +| 0.0.7 | 2024-12-28 | [50771](https://github.com/airbytehq/airbyte/pull/50771) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50374](https://github.com/airbytehq/airbyte/pull/50374) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49795](https://github.com/airbytehq/airbyte/pull/49795) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49389](https://github.com/airbytehq/airbyte/pull/49389) | Update dependencies | +| 0.0.3 | 2024-11-04 | [48303](https://github.com/airbytehq/airbyte/pull/48303) | Update dependencies | | 0.0.2 | 2024-10-28 | [47565](https://github.com/airbytehq/airbyte/pull/47565) | Update dependencies | | 0.0.1 | 2024-09-10 | [45367](https://github.com/airbytehq/airbyte/pull/45367) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/whisky-hunter.md b/docs/integrations/sources/whisky-hunter.md index 1b342cdf4307..51e83d39e6dd 100644 --- a/docs/integrations/sources/whisky-hunter.md +++ b/docs/integrations/sources/whisky-hunter.md @@ -38,6 +38,12 @@ There is no published rate limit. However, since this data updates infrequently, | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :----------------------------------------------- | +| 0.2.9 | 2024-12-28 | [50786](https://github.com/airbytehq/airbyte/pull/50786) | Update dependencies | +| 0.2.8 | 2024-12-21 | [50315](https://github.com/airbytehq/airbyte/pull/50315) | Update dependencies | +| 0.2.7 | 2024-12-14 | [49780](https://github.com/airbytehq/airbyte/pull/49780) | Update dependencies | +| 0.2.6 | 2024-12-12 | [49380](https://github.com/airbytehq/airbyte/pull/49380) | Update dependencies | +| 0.2.5 | 2024-12-11 | [49126](https://github.com/airbytehq/airbyte/pull/49126) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.2.4 | 2024-11-04 | [48275](https://github.com/airbytehq/airbyte/pull/48275) | Update dependencies | | 0.2.3 | 2024-10-29 | [47795](https://github.com/airbytehq/airbyte/pull/47795) | Update dependencies | | 0.2.2 | 2024-10-28 | [47555](https://github.com/airbytehq/airbyte/pull/47555) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/wikipedia-pageviews.md b/docs/integrations/sources/wikipedia-pageviews.md index 4d7e85e242ab..bfffbb279188 100644 --- a/docs/integrations/sources/wikipedia-pageviews.md +++ b/docs/integrations/sources/wikipedia-pageviews.md @@ -53,6 +53,10 @@ The Wikipedia Pageviews source connector supports the following [sync modes](htt | Version | Date | Pull Request | Subject | | :------ | :--------- | :-------------------------------------------------------- | :------------- | +| 0.2.5 | 2024-12-28 | [50807](https://github.com/airbytehq/airbyte/pull/50807) | Update dependencies | +| 0.2.4 | 2024-12-21 | [50345](https://github.com/airbytehq/airbyte/pull/50345) | Update dependencies | +| 0.2.3 | 2024-12-14 | [49734](https://github.com/airbytehq/airbyte/pull/49734) | Update dependencies | +| 0.2.2 | 2024-12-12 | [47763](https://github.com/airbytehq/airbyte/pull/47763) | Update dependencies | | 0.2.1 | 2024-10-28 | [47618](https://github.com/airbytehq/airbyte/pull/47618) | Update dependencies | | 0.2.0 | 2024-08-20 | [44460](https://github.com/airbytehq/airbyte/pull/44460) | Refactor connector to manifest-only format | | 0.1.10 | 2024-08-17 | [44202](https://github.com/airbytehq/airbyte/pull/44202) | Update dependencies | diff --git a/docs/integrations/sources/woocommerce.md b/docs/integrations/sources/woocommerce.md index 28398a8daccf..e068a8f67bf3 100644 --- a/docs/integrations/sources/woocommerce.md +++ b/docs/integrations/sources/woocommerce.md @@ -122,6 +122,10 @@ maximum number of seconds between API calls. | Version | Date | Pull Request | Subject | |:--------| :--------- |:---------------------------------------------------------|:-----------------------------------------------------------------------| +| 0.5.4 | 2024-12-28 | [50800](https://github.com/airbytehq/airbyte/pull/50800) | Update dependencies | +| 0.5.3 | 2024-12-21 | [50335](https://github.com/airbytehq/airbyte/pull/50335) | Update dependencies | +| 0.5.2 | 2024-12-14 | [49382](https://github.com/airbytehq/airbyte/pull/49382) | Update dependencies | +| 0.5.1 | 2024-12-11 | [47510](https://github.com/airbytehq/airbyte/pull/47510) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 0.5.0 | 2024-10-16 | [46956](https://github.com/airbytehq/airbyte/pull/46956) | Promoting release candidate 0.5.0-rc.1 to a main version. | | 0.5.0-rc.1 | 2024-10-08 | [46575](https://github.com/airbytehq/airbyte/pull/46575) | Migrate to Manifest-only | | 0.4.12 | 2024-10-12 | [46806](https://github.com/airbytehq/airbyte/pull/46806) | Update dependencies | diff --git a/docs/integrations/sources/wordpress.md b/docs/integrations/sources/wordpress.md index c5b68a0bce13..0e79dc33313b 100644 --- a/docs/integrations/sources/wordpress.md +++ b/docs/integrations/sources/wordpress.md @@ -38,6 +38,10 @@ The WordPress connector enables seamless data synchronization between your WordP | Version | Date | Pull Request | Subject | | ------- | ---------- | ------------ | ------------------------------------------------------------------------------------- | +| 0.0.5 | 2024-12-28 | [50763](https://github.com/airbytehq/airbyte/pull/50763) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50361](https://github.com/airbytehq/airbyte/pull/50361) | Update dependencies | +| 0.0.3 | 2024-12-14 | [49743](https://github.com/airbytehq/airbyte/pull/49743) | Update dependencies | +| 0.0.2 | 2024-12-12 | [49433](https://github.com/airbytehq/airbyte/pull/49433) | Update dependencies | | 0.0.1 | 2024-10-21 | 46378 | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | diff --git a/docs/integrations/sources/workflowmax.md b/docs/integrations/sources/workflowmax.md index ab28ec1a87fd..e89ac7746660 100644 --- a/docs/integrations/sources/workflowmax.md +++ b/docs/integrations/sources/workflowmax.md @@ -60,6 +60,9 @@ Then authorize your source with the required information. | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.5 | 2024-12-28 | [50782](https://github.com/airbytehq/airbyte/pull/50782) | Update dependencies | +| 0.0.4 | 2024-12-21 | [50324](https://github.com/airbytehq/airbyte/pull/50324) | Update dependencies | +| 0.0.3 | 2024-12-14 | [47888](https://github.com/airbytehq/airbyte/pull/47888) | Update dependencies | | 0.0.2 | 2024-10-28 | [47527](https://github.com/airbytehq/airbyte/pull/47527) | Update dependencies | | 0.0.1 | 2024-10-13 | [46866](https://github.com/airbytehq/airbyte/pull/46866) | Initial release by [@btkcodedev](https://github.com/btkcodedev) via Connector Builder | diff --git a/docs/integrations/sources/workramp.md b/docs/integrations/sources/workramp.md index 1eaaf1855499..a3ed20ae5f4b 100644 --- a/docs/integrations/sources/workramp.md +++ b/docs/integrations/sources/workramp.md @@ -40,17 +40,22 @@ The Workramp connector should not run into Workramp API limitations under normal | Version | Date | Pull Request | Subject | |:--------|:-----------| :------------------------------------------------------- | :---------------------------- | -| 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | -| 0.2.0 | 2024-08-09 | [43451](https://github.com/airbytehq/airbyte/pull/43451) | Refactor connector to manifest-only format | -| 0.1.10 | 2024-08-03 | [43207](https://github.com/airbytehq/airbyte/pull/43207) | Update dependencies | -| 0.1.9 | 2024-07-20 | [42202](https://github.com/airbytehq/airbyte/pull/42202) | Update dependencies | -| 0.1.8 | 2024-07-13 | [41473](https://github.com/airbytehq/airbyte/pull/41473) | Update dependencies | -| 0.1.7 | 2024-07-09 | [41116](https://github.com/airbytehq/airbyte/pull/41116) | Update dependencies | -| 0.1.6 | 2024-07-06 | [40845](https://github.com/airbytehq/airbyte/pull/40845) | Update dependencies | -| 0.1.5 | 2024-06-25 | [40388](https://github.com/airbytehq/airbyte/pull/40388) | Update dependencies | -| 0.1.4 | 2024-06-22 | [39967](https://github.com/airbytehq/airbyte/pull/39967) | Update dependencies | -| 0.1.3 | 2024-06-12 | [38741](https://github.com/airbytehq/airbyte/pull/38741) | Make connector compatible with Builder | -| 0.1.2 | 2024-06-04 | [38941](https://github.com/airbytehq/airbyte/pull/38941) | [autopull] Upgrade base image to v1.2.1 | +| 0.2.6 | 2024-12-28 | [50762](https://github.com/airbytehq/airbyte/pull/50762) | Update dependencies | +| 0.2.5 | 2024-12-21 | [50379](https://github.com/airbytehq/airbyte/pull/50379) | Update dependencies | +| 0.2.4 | 2024-12-14 | [49785](https://github.com/airbytehq/airbyte/pull/49785) | Update dependencies | +| 0.2.3 | 2024-12-12 | [49416](https://github.com/airbytehq/airbyte/pull/49416) | Update dependencies | +| 0.2.2 | 2024-11-04 | [48287](https://github.com/airbytehq/airbyte/pull/48287) | Update dependencies | +| 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | +| 0.2.0 | 2024-08-09 | [43451](https://github.com/airbytehq/airbyte/pull/43451) | Refactor connector to manifest-only format | +| 0.1.10 | 2024-08-03 | [43207](https://github.com/airbytehq/airbyte/pull/43207) | Update dependencies | +| 0.1.9 | 2024-07-20 | [42202](https://github.com/airbytehq/airbyte/pull/42202) | Update dependencies | +| 0.1.8 | 2024-07-13 | [41473](https://github.com/airbytehq/airbyte/pull/41473) | Update dependencies | +| 0.1.7 | 2024-07-09 | [41116](https://github.com/airbytehq/airbyte/pull/41116) | Update dependencies | +| 0.1.6 | 2024-07-06 | [40845](https://github.com/airbytehq/airbyte/pull/40845) | Update dependencies | +| 0.1.5 | 2024-06-25 | [40388](https://github.com/airbytehq/airbyte/pull/40388) | Update dependencies | +| 0.1.4 | 2024-06-22 | [39967](https://github.com/airbytehq/airbyte/pull/39967) | Update dependencies | +| 0.1.3 | 2024-06-12 | [38741](https://github.com/airbytehq/airbyte/pull/38741) | Make connector compatible with Builder | +| 0.1.2 | 2024-06-04 | [38941](https://github.com/airbytehq/airbyte/pull/38941) | [autopull] Upgrade base image to v1.2.1 | | 0.1.1 | 2024-05-20 | [38419](https://github.com/airbytehq/airbyte/pull/38419) | [autopull] base image + poetry + up_to_date | | 0.1.0 | 2022-01-02 | [18843](https://github.com/airbytehq/airbyte/pull/18843) | Add Workramp Source Connector | diff --git a/docs/integrations/sources/wrike.md b/docs/integrations/sources/wrike.md index 88b435b1d522..ca7e40d89285 100644 --- a/docs/integrations/sources/wrike.md +++ b/docs/integrations/sources/wrike.md @@ -50,6 +50,10 @@ The Wrike connector should not run into Wrike API limitations under normal usage | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- |:-----------------------------------------------------------------------| +| 0.3.8 | 2024-12-28 | [50752](https://github.com/airbytehq/airbyte/pull/50752) | Update dependencies | +| 0.3.7 | 2024-12-21 | [50321](https://github.com/airbytehq/airbyte/pull/50321) | Update dependencies | +| 0.3.6 | 2024-12-14 | [49794](https://github.com/airbytehq/airbyte/pull/49794) | Update dependencies | +| 0.3.5 | 2024-12-12 | [48237](https://github.com/airbytehq/airbyte/pull/48237) | Update dependencies | | 0.3.4 | 2024-10-29 | [47801](https://github.com/airbytehq/airbyte/pull/47801) | Update dependencies | | 0.3.3 | 2024-10-28 | [47668](https://github.com/airbytehq/airbyte/pull/47668) | Update dependencies | | 0.3.2 | 2024-10-22 | [47234](https://github.com/airbytehq/airbyte/pull/47234) | Update dependencies | diff --git a/docs/integrations/sources/wufoo.md b/docs/integrations/sources/wufoo.md new file mode 100644 index 000000000000..e5409d48ed99 --- /dev/null +++ b/docs/integrations/sources/wufoo.md @@ -0,0 +1,38 @@ +# Wufoo +The Airbyte connector for [Wufoo](https://www.wufoo.com/) enables seamless data integration between Wufoo and various destinations. It extracts form entries, form metadata, and user information from Wufoo via the Wufoo API. This connector helps automate the synchronization of survey and form data with your chosen data warehouse or analytical tools, simplifying data-driven insights and reporting. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. Your Wufoo API Key. You can find it by logging into your Wufoo account, selecting 'API Information' from the 'More' dropdown on any form, and locating the 16-digit code. | | +| `subdomain` | `string` | Subdomain. Your account subdomain/username for Wufoo. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| forms | Hash | No pagination | ✅ | ❌ | +| form_comments | CommentId | DefaultPaginator | ✅ | ❌ | +| form_fields | | No pagination | ✅ | ❌ | +| form_entries | EntryId | DefaultPaginator | ✅ | ❌ | +| reports | Hash | No pagination | ✅ | ❌ | +| report_entries | EntryId | No pagination | ✅ | ❌ | +| report_fields | | No pagination | ✅ | ❌ | +| report_widgets | Hash | No pagination | ✅ | ❌ | +| users | Hash | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50767](https://github.com/airbytehq/airbyte/pull/50767) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50347](https://github.com/airbytehq/airbyte/pull/50347) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49768](https://github.com/airbytehq/airbyte/pull/49768) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49379](https://github.com/airbytehq/airbyte/pull/49379) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49121](https://github.com/airbytehq/airbyte/pull/49121) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-08 | | Initial release by [@parthiv11](https://github.com/parthiv11) via Connector Builder | + +
diff --git a/docs/integrations/sources/xkcd.md b/docs/integrations/sources/xkcd.md index 245451946bec..36425ba27968 100644 --- a/docs/integrations/sources/xkcd.md +++ b/docs/integrations/sources/xkcd.md @@ -2,7 +2,7 @@ ## Prerequisites -XKCD is an open API, so no credentials are needed to set up the surce. +XKCD is an open API, so no credentials are needed to set up the source. ## Supported sync modes diff --git a/docs/integrations/sources/xsolla.md b/docs/integrations/sources/xsolla.md index d59d26f69765..b92d80aaecac 100644 --- a/docs/integrations/sources/xsolla.md +++ b/docs/integrations/sources/xsolla.md @@ -26,6 +26,11 @@ The Xsolla Airbyte Connector enables seamless integration between Xsolla and var | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.7 | 2024-12-28 | [50813](https://github.com/airbytehq/airbyte/pull/50813) | Update dependencies | +| 0.0.6 | 2024-12-21 | [50350](https://github.com/airbytehq/airbyte/pull/50350) | Update dependencies | +| 0.0.5 | 2024-12-14 | [49762](https://github.com/airbytehq/airbyte/pull/49762) | Update dependencies | +| 0.0.4 | 2024-12-12 | [49392](https://github.com/airbytehq/airbyte/pull/49392) | Update dependencies | +| 0.0.3 | 2024-11-04 | [48219](https://github.com/airbytehq/airbyte/pull/48219) | Update dependencies | | 0.0.2 | 2024-10-28 | [47595](https://github.com/airbytehq/airbyte/pull/47595) | Update dependencies | | 0.0.1 | 2024-10-01 | | Initial release by [@avirajsingh7](https://github.com/avirajsingh7) via Connector Builder | diff --git a/docs/integrations/sources/yahoo-finance-price.md b/docs/integrations/sources/yahoo-finance-price.md index 0fa580aa6c2f..245301a33ff6 100644 --- a/docs/integrations/sources/yahoo-finance-price.md +++ b/docs/integrations/sources/yahoo-finance-price.md @@ -9,6 +9,10 @@ The Airbyte Source for [Yahoo Finance Price](https://finance.yahoo.com/) | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.3.6 | 2024-12-28 | [50794](https://github.com/airbytehq/airbyte/pull/50794) | Update dependencies | +| 0.3.5 | 2024-12-21 | [50339](https://github.com/airbytehq/airbyte/pull/50339) | Update dependencies | +| 0.3.4 | 2024-12-14 | [49792](https://github.com/airbytehq/airbyte/pull/49792) | Update dependencies | +| 0.3.3 | 2024-12-12 | [49407](https://github.com/airbytehq/airbyte/pull/49407) | Update dependencies | | 0.3.2 | 2024-10-29 | [47726](https://github.com/airbytehq/airbyte/pull/47726) | Update dependencies | | 0.3.1 | 2024-10-28 | [47497](https://github.com/airbytehq/airbyte/pull/47497) | Update dependencies | | 0.3.0 | 2024-10-06 | [46526](https://github.com/airbytehq/airbyte/pull/46526) | Converting to manifest-only format | diff --git a/docs/integrations/sources/yandex-metrica.md b/docs/integrations/sources/yandex-metrica.md index a5e131a4c282..007cd7ddf2c6 100644 --- a/docs/integrations/sources/yandex-metrica.md +++ b/docs/integrations/sources/yandex-metrica.md @@ -92,6 +92,11 @@ Because of the way API works some syncs may take a long time to finish. Timeout | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 1.0.27 | 2024-12-28 | [50769](https://github.com/airbytehq/airbyte/pull/50769) | Update dependencies | +| 1.0.26 | 2024-12-21 | [50375](https://github.com/airbytehq/airbyte/pull/50375) | Update dependencies | +| 1.0.25 | 2024-12-14 | [49796](https://github.com/airbytehq/airbyte/pull/49796) | Update dependencies | +| 1.0.24 | 2024-12-12 | [49425](https://github.com/airbytehq/airbyte/pull/49425) | Update dependencies | +| 1.0.23 | 2024-11-25 | [48660](https://github.com/airbytehq/airbyte/pull/48660) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | | 1.0.22 | 2024-10-21 | [47088](https://github.com/airbytehq/airbyte/pull/47088) | Update dependencies | | 1.0.21 | 2024-10-12 | [46836](https://github.com/airbytehq/airbyte/pull/46836) | Update dependencies | | 1.0.20 | 2024-10-05 | [46444](https://github.com/airbytehq/airbyte/pull/46444) | Update dependencies | diff --git a/docs/integrations/sources/you-need-a-budget-ynab.md b/docs/integrations/sources/you-need-a-budget-ynab.md index 7d29ea7a0d6e..03d410ceab95 100644 --- a/docs/integrations/sources/you-need-a-budget-ynab.md +++ b/docs/integrations/sources/you-need-a-budget-ynab.md @@ -24,6 +24,11 @@ Replicates the budgets, accounts, categories, payees, transactions, and category | Version | Date | Pull Request | Subject | |---------|------|--------------|---------| +| 0.0.7 | 2024-12-28 | [50377](https://github.com/airbytehq/airbyte/pull/50377) | Update dependencies | +| 0.0.6 | 2024-12-14 | [49736](https://github.com/airbytehq/airbyte/pull/49736) | Update dependencies | +| 0.0.5 | 2024-12-12 | [49376](https://github.com/airbytehq/airbyte/pull/49376) | Update dependencies | +| 0.0.4 | 2024-12-11 | [49130](https://github.com/airbytehq/airbyte/pull/49130) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.3 | 2024-11-04 | [48213](https://github.com/airbytehq/airbyte/pull/48213) | Update dependencies | | 0.0.2 | 2024-10-29 | [47760](https://github.com/airbytehq/airbyte/pull/47760) | Update dependencies | | 0.0.1 | 2024-09-25 | | Initial release by [@bnmry](https://github.com/bnmry) via Connector Builder | diff --git a/docs/integrations/sources/younium.md b/docs/integrations/sources/younium.md index febda0c3c7eb..0be8f777e13f 100644 --- a/docs/integrations/sources/younium.md +++ b/docs/integrations/sources/younium.md @@ -46,7 +46,10 @@ The Younium source connector supports the following [sync modes](https://docs.ai | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :--------------------------------------------------------- | -| 0.4.0 | 2024-10-23 | [47281](https://github.com/airbytehq/airbyte/pull/47281) | Migrate to Manifest-only | +| 0.4.3 | 2024-12-28 | [50781](https://github.com/airbytehq/airbyte/pull/50781) | Update dependencies | +| 0.4.2 | 2024-12-21 | [49787](https://github.com/airbytehq/airbyte/pull/49787) | Update dependencies | +| 0.4.1 | 2024-12-12 | [46856](https://github.com/airbytehq/airbyte/pull/46856) | Update dependencies | +| 0.4.0 | 2024-10-23 | [47281](https://github.com/airbytehq/airbyte/pull/47281) | Migrate to Manifest-only | | 0.3.22 | 2024-10-05 | [46432](https://github.com/airbytehq/airbyte/pull/46432) | Update dependencies | | 0.3.21 | 2024-09-28 | [46176](https://github.com/airbytehq/airbyte/pull/46176) | Update dependencies | | 0.3.20 | 2024-09-21 | [45807](https://github.com/airbytehq/airbyte/pull/45807) | Update dependencies | diff --git a/docs/integrations/sources/youtube-data.md b/docs/integrations/sources/youtube-data.md new file mode 100644 index 000000000000..365216e67e90 --- /dev/null +++ b/docs/integrations/sources/youtube-data.md @@ -0,0 +1,37 @@ +# Youtube Data API +The YouTube Data API v3 is an API that provides access to YouTube data, such as videos, playlists, channels, comments and simple stats. +This is a simpler version of Youtube connector, if you need more detailed reports from your channel please check +the [Youtube Analytics Connector](https://docs.airbyte.com/integrations/sources/youtube-analytics) + + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `api_key` | `string` | API Key. | | +| `channel_id` | `string` | channel_id. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| videos | | DefaultPaginator | ✅ | ❌ | +| video_details | | DefaultPaginator | ✅ | ❌ | +| channels | id | DefaultPaginator | ✅ | ❌ | +| comments | | DefaultPaginator | ✅ | ❌ | +| channel_comments | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.6 | 2025-01-04 | [50753](https://github.com/airbytehq/airbyte/pull/50753) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50326](https://github.com/airbytehq/airbyte/pull/50326) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49756](https://github.com/airbytehq/airbyte/pull/49756) | Update dependencies | +| 0.0.3 | 2024-12-12 | [49403](https://github.com/airbytehq/airbyte/pull/49403) | Update dependencies | +| 0.0.2 | 2024-12-11 | [49125](https://github.com/airbytehq/airbyte/pull/49125) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.0.1 | 2024-11-08 | | Initial release by [@bala-ceg](https://github.com/bala-ceg) via Connector Builder | + +
diff --git a/docs/integrations/sources/zapier-supported-storage.md b/docs/integrations/sources/zapier-supported-storage.md index a355ad149ebc..8ecad9a886a2 100644 --- a/docs/integrations/sources/zapier-supported-storage.md +++ b/docs/integrations/sources/zapier-supported-storage.md @@ -25,6 +25,10 @@ The Zapier Supported Storage Connector can be used to sync your [Zapier](https:/ | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------| | +| 0.2.7 | 2024-12-28 | [50793](https://github.com/airbytehq/airbyte/pull/50793) | Update dependencies | +| 0.2.6 | 2024-12-21 | [50333](https://github.com/airbytehq/airbyte/pull/50333) | Update dependencies | +| 0.2.5 | 2024-12-14 | [49783](https://github.com/airbytehq/airbyte/pull/49783) | Update dependencies | +| 0.2.4 | 2024-12-12 | [48181](https://github.com/airbytehq/airbyte/pull/48181) | Update dependencies | | 0.2.3 | 2024-10-29 | [47798](https://github.com/airbytehq/airbyte/pull/47798) | Update dependencies | | 0.2.2 | 2024-10-28 | [47614](https://github.com/airbytehq/airbyte/pull/47614) | Update dependencies | | 0.2.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | diff --git a/docs/integrations/sources/zendesk-chat-migrations.md b/docs/integrations/sources/zendesk-chat-migrations.md new file mode 100644 index 000000000000..3d6af4a4b801 --- /dev/null +++ b/docs/integrations/sources/zendesk-chat-migrations.md @@ -0,0 +1,33 @@ +# Zendesk Chat Migration Guide + +## Upgrading to 1.0.0 + +The Live Chat API [changed its URL structure](https://developer.zendesk.com/api-reference/live-chat/introduction/) to use the Zendesk subdomain. +The `subdomain` field of the connector configuration is now required. +You can find your Zendesk subdomain by following instructions [here](https://support.zendesk.com/hc/en-us/articles/4409381383578-Where-can-I-find-my-Zendesk-subdomain). + +### For Airbyte Open Source: Update the local connector image + +Airbyte Open Source users must manually update the connector image in their local registry before proceeding with the migration. To do so: + +1. Select **Settings** in the main navbar. + - Select **Sources**. +2. Find Zendesk Chat in the list of connectors. + +:::note +You will see two versions listed, the current in-use version and the latest version available. +::: + +3. Select **Change** to update your OSS version to the latest available version. + +### For Airbyte Cloud: Update the connector version + +1. Select **Sources** in the main navbar. +2. Select the instance of the connector you wish to upgrade. + +:::note +Each instance of the connector must be updated separately. If you have created multiple instances of a connector, updating one will not affect the others. +::: + +3. Select **Upgrade** + - Follow the prompt to confirm you are ready to upgrade to the new version. diff --git a/docs/integrations/sources/zendesk-chat.md b/docs/integrations/sources/zendesk-chat.md index b45f4c0d4520..3a00856e875b 100644 --- a/docs/integrations/sources/zendesk-chat.md +++ b/docs/integrations/sources/zendesk-chat.md @@ -83,25 +83,26 @@ The connector is restricted by Zendesk's [requests limitation](https://developer | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------- | -| 0.3.1 | 2024-06-06 | [39260](https://github.com/airbytehq/airbyte/pull/39260) | [autopull] Upgrade base image to v1.2.2 | -| 0.3.0 | 2024-03-07 | [35867](https://github.com/airbytehq/airbyte/pull/35867) | Migrated to `YamlDeclarativeSource (Low-code)` Airbyte CDK | -| 0.2.2 | 2024-02-12 | [35185](https://github.com/airbytehq/airbyte/pull/35185) | Manage dependencies with Poetry. | -| 0.2.1 | 2023-10-20 | [31643](https://github.com/airbytehq/airbyte/pull/31643) | Upgrade base image to airbyte/python-connector-base:1.1.0 | -| 0.2.0 | 2023-10-11 | [30526](https://github.com/airbytehq/airbyte/pull/30526) | Use the python connector base image, remove dockerfile and implement build_customization.py | -| 0.1.14 | 2023-02-10 | [24190](https://github.com/airbytehq/airbyte/pull/24190) | Fix remove too high min/max from account stream | -| 0.1.13 | 2023-02-10 | [22819](https://github.com/airbytehq/airbyte/pull/22819) | Specified date formatting in specification | -| 0.1.12 | 2023-01-27 | [22026](https://github.com/airbytehq/airbyte/pull/22026) | Set `AvailabilityStrategy` for streams explicitly to `None` | -| 0.1.11 | 2022-10-18 | [17745](https://github.com/airbytehq/airbyte/pull/17745) | Add Engagements Stream and fix infity looping | -| 0.1.10 | 2022-09-28 | [17326](https://github.com/airbytehq/airbyte/pull/17326) | Migrate to per-stream states. | -| 0.1.9 | 2022-08-23 | [15879](https://github.com/airbytehq/airbyte/pull/15879) | Corrected specification and stream schemas to support backward capability | -| 0.1.8 | 2022-06-28 | [13387](https://github.com/airbytehq/airbyte/pull/13387) | Add state checkpoint to allow long runs | -| 0.1.7 | 2022-05-25 | [12883](https://github.com/airbytehq/airbyte/pull/12883) | Pass timeout in request to prevent a stuck connection | -| 0.1.6 | 2021-12-15 | [7313](https://github.com/airbytehq/airbyte/pull/7313) | Add support of `OAuth 2.0` authentication. Fixed the issue with `created_at` can now be `null` for `bans` stream | -| 0.1.5 | 2021-12-06 | [8425](https://github.com/airbytehq/airbyte/pull/8425) | Update title, description fields in spec | -| 0.1.4 | 2021-11-22 | [8166](https://github.com/airbytehq/airbyte/pull/8166) | Make `Chats` stream incremental + add tests for all streams | -| 0.1.3 | 2021-10-21 | [7210](https://github.com/airbytehq/airbyte/pull/7210) | Chats stream is only getting data from first page | -| 0.1.2 | 2021-08-17 | [5476](https://github.com/airbytehq/airbyte/pull/5476) | Correct field unread to boolean type | -| 0.1.1 | 2021-06-09 | [3973](https://github.com/airbytehq/airbyte/pull/3973) | Add `AIRBYTE_ENTRYPOINT` for Kubernetes support | -| 0.1.0 | 2021-05-03 | [3088](https://github.com/airbytehq/airbyte/pull/3088) | Initial release | +| 1.0.0 | 2024-11-04 | [44898](https://github.com/airbytehq/airbyte/pull/44898) | Migrate to [new base url](https://developer.zendesk.com/api-reference/live-chat/introduction/) | +| 0.3.1 | 2024-06-06 | [39260](https://github.com/airbytehq/airbyte/pull/39260) | [autopull] Upgrade base image to v1.2.2 | +| 0.3.0 | 2024-03-07 | [35867](https://github.com/airbytehq/airbyte/pull/35867) | Migrated to `YamlDeclarativeSource (Low-code)` Airbyte CDK | +| 0.2.2 | 2024-02-12 | [35185](https://github.com/airbytehq/airbyte/pull/35185) | Manage dependencies with Poetry. | +| 0.2.1 | 2023-10-20 | [31643](https://github.com/airbytehq/airbyte/pull/31643) | Upgrade base image to airbyte/python-connector-base:1.1.0 | +| 0.2.0 | 2023-10-11 | [30526](https://github.com/airbytehq/airbyte/pull/30526) | Use the python connector base image, remove dockerfile and implement build_customization.py | +| 0.1.14 | 2023-02-10 | [24190](https://github.com/airbytehq/airbyte/pull/24190) | Fix remove too high min/max from account stream | +| 0.1.13 | 2023-02-10 | [22819](https://github.com/airbytehq/airbyte/pull/22819) | Specified date formatting in specification | +| 0.1.12 | 2023-01-27 | [22026](https://github.com/airbytehq/airbyte/pull/22026) | Set `AvailabilityStrategy` for streams explicitly to `None` | +| 0.1.11 | 2022-10-18 | [17745](https://github.com/airbytehq/airbyte/pull/17745) | Add Engagements Stream and fix infity looping | +| 0.1.10 | 2022-09-28 | [17326](https://github.com/airbytehq/airbyte/pull/17326) | Migrate to per-stream states. | +| 0.1.9 | 2022-08-23 | [15879](https://github.com/airbytehq/airbyte/pull/15879) | Corrected specification and stream schemas to support backward capability | +| 0.1.8 | 2022-06-28 | [13387](https://github.com/airbytehq/airbyte/pull/13387) | Add state checkpoint to allow long runs | +| 0.1.7 | 2022-05-25 | [12883](https://github.com/airbytehq/airbyte/pull/12883) | Pass timeout in request to prevent a stuck connection | +| 0.1.6 | 2021-12-15 | [7313](https://github.com/airbytehq/airbyte/pull/7313) | Add support of `OAuth 2.0` authentication. Fixed the issue with `created_at` can now be `null` for `bans` stream | +| 0.1.5 | 2021-12-06 | [8425](https://github.com/airbytehq/airbyte/pull/8425) | Update title, description fields in spec | +| 0.1.4 | 2021-11-22 | [8166](https://github.com/airbytehq/airbyte/pull/8166) | Make `Chats` stream incremental + add tests for all streams | +| 0.1.3 | 2021-10-21 | [7210](https://github.com/airbytehq/airbyte/pull/7210) | Chats stream is only getting data from first page | +| 0.1.2 | 2021-08-17 | [5476](https://github.com/airbytehq/airbyte/pull/5476) | Correct field unread to boolean type | +| 0.1.1 | 2021-06-09 | [3973](https://github.com/airbytehq/airbyte/pull/3973) | Add `AIRBYTE_ENTRYPOINT` for Kubernetes support | +| 0.1.0 | 2021-05-03 | [3088](https://github.com/airbytehq/airbyte/pull/3088) | Initial release | diff --git a/docs/integrations/sources/zendesk-sell.md b/docs/integrations/sources/zendesk-sell.md index febec39e43b7..fb7fcb708f09 100644 --- a/docs/integrations/sources/zendesk-sell.md +++ b/docs/integrations/sources/zendesk-sell.md @@ -77,6 +77,10 @@ We recommend creating a restricted, read-only key specifically for Airbyte acces | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :----------------------------------------------------------------------------- | +| 0.3.5 | 2024-12-28 | [50772](https://github.com/airbytehq/airbyte/pull/50772) | Update dependencies | +| 0.3.4 | 2024-12-21 | [50309](https://github.com/airbytehq/airbyte/pull/50309) | Update dependencies | +| 0.3.3 | 2024-12-14 | [49761](https://github.com/airbytehq/airbyte/pull/49761) | Update dependencies | +| 0.3.2 | 2024-12-12 | [47846](https://github.com/airbytehq/airbyte/pull/47846) | Update dependencies | | 0.3.1 | 2024-10-28 | [47495](https://github.com/airbytehq/airbyte/pull/47495) | Update dependencies | | 0.3.0 | 2024-08-22 | [44562](https://github.com/airbytehq/airbyte/pull/44562) | Refactor connector to manifest-only format | | 0.2.14 | 2024-08-17 | [44295](https://github.com/airbytehq/airbyte/pull/44295) | Update dependencies | diff --git a/docs/integrations/sources/zendesk-sunshine.md b/docs/integrations/sources/zendesk-sunshine.md index 0bfedd14d776..d555d2ec5c4a 100644 --- a/docs/integrations/sources/zendesk-sunshine.md +++ b/docs/integrations/sources/zendesk-sunshine.md @@ -68,6 +68,10 @@ We recommend creating a restricted, read-only key specifically for Airbyte acces | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.3.3 | 2024-12-28 | [50380](https://github.com/airbytehq/airbyte/pull/50380) | Update dependencies | +| 0.3.2 | 2024-12-14 | [49753](https://github.com/airbytehq/airbyte/pull/49753) | Update dependencies | +| 0.3.1 | 2024-12-12 | [49415](https://github.com/airbytehq/airbyte/pull/49415) | Update dependencies | +| 0.3.0 | 2024-10-31 | [47327](https://github.com/airbytehq/airbyte/pull/47327) | Migrate to Manifest-only | | 0.2.26 | 2024-10-29 | [47802](https://github.com/airbytehq/airbyte/pull/47802) | Update dependencies | | 0.2.25 | 2024-10-28 | [47066](https://github.com/airbytehq/airbyte/pull/47066) | Update dependencies | | 0.2.24 | 2024-10-12 | [46784](https://github.com/airbytehq/airbyte/pull/46784) | Update dependencies | diff --git a/docs/integrations/sources/zendesk-support.md b/docs/integrations/sources/zendesk-support.md index a58a319cbafe..62fb583a5aad 100644 --- a/docs/integrations/sources/zendesk-support.md +++ b/docs/integrations/sources/zendesk-support.md @@ -56,14 +56,16 @@ If you prefer to authenticate with OAuth for **Airbyte Open Source**, you can fo ### Set up the Zendesk Support connector in Airbyte + #### For Airbyte Cloud: 1. [Log into your Airbyte Cloud](https://cloud.airbyte.com/workspaces) account. 2. Click Sources and then click + New source. 3. On the Set up the source page, select Zendesk Support from the Source type dropdown. 4. Enter a name for the Zendesk Support connector. - - + + + #### For Airbyte Open Source: 1. Navigate to the Airbyte Open Source dashboard. @@ -149,7 +151,7 @@ The Zendesk Support source connector supports the following streams: The Zendesk Support connector fetches deleted records in the following streams: | Stream | Deletion indicator field | -|:-------------------------|:-------------------------| +| :----------------------- | :----------------------- | | **Brands** | `is_deleted` | | **Groups** | `deleted` | | **Organizations** | `deleted_at` | @@ -183,120 +185,122 @@ The Zendesk connector ideally should not run into Zendesk API limitations under Expand to review | Version | Date | Pull Request | Subject | -|:--------|:-----------|:---------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 4.3.3 | 2024-10-28 | [47663](https://github.com/airbytehq/airbyte/pull/47663) | Update dependencies | -| 4.3.2 | 2024-10-21 | [47202](https://github.com/airbytehq/airbyte/pull/47202) | Update dependencies and expected records | -| 4.3.1 | 2024-10-12 | [46794](https://github.com/airbytehq/airbyte/pull/46794) | Update dependencies | -| 4.3.0 | 2024-10-09 | [46096](https://github.com/airbytehq/airbyte/pull/46096) | Updates `TicketMetrics` stream for improved reliability for long syncs, updates state cursor field to `_ab_updated_at`, automatically migrates legacy state | -| 4.2.3 | 2024-10-05 | [46408](https://github.com/airbytehq/airbyte/pull/46408) | Update dependencies | -| 4.2.2 | 2024-09-28 | [45784](https://github.com/airbytehq/airbyte/pull/45784) | Update dependencies | -| 4.2.1 | 2024-09-14 | [45561](https://github.com/airbytehq/airbyte/pull/45561) | Update dependencies | -| 4.2.0 | 2024-09-10 | [44610](https://github.com/airbytehq/airbyte/pull/44610) | Add `Automations` and `Triggers` stream | -| 4.1.1 | 2024-09-07 | [45215](https://github.com/airbytehq/airbyte/pull/45215) | Update dependencies | -| 4.1.0 | 2024-09-06 | [45187](https://github.com/airbytehq/airbyte/pull/45187) | Migrate to CDK v5 | -| 4.0.2 | 2024-08-31 | [44965](https://github.com/airbytehq/airbyte/pull/44965) | Update dependencies | -| 4.0.1 | 2024-08-24 | [44692](https://github.com/airbytehq/airbyte/pull/44692) | Update dependencies | -| 4.0.0 | 2024-08-19 | [44096](https://github.com/airbytehq/airbyte/pull/44096) | Stream `Tags`: use cursor based pagination | -| 3.0.1 | 2024-08-17 | [44324](https://github.com/airbytehq/airbyte/pull/44324) | Update dependencies | -| 3.0.0 | 2024-08-13 | [43446](https://github.com/airbytehq/airbyte/pull/43446) | `TicketMetrics` stream: updates cursor field to `generated_timestamp` | -| 2.7.3 | 2024-08-12 | [43900](https://github.com/airbytehq/airbyte/pull/43900) | Update dependencies | -| 2.7.2 | 2024-08-10 | [43614](https://github.com/airbytehq/airbyte/pull/43614) | Update dependencies | -| 2.7.1 | 2024-08-03 | [41799](https://github.com/airbytehq/airbyte/pull/41799) | Update dependencies | -| 2.7.0 | 2024-08-02 | [42975](https://github.com/airbytehq/airbyte/pull/42975) | Migrate to CDK v4.3.0 | -| 2.6.13 | 2024-07-31 | [42892](https://github.com/airbytehq/airbyte/pull/42892) | Update BackoffStrategy interface to be up-to-date with latest parent interface. | -| 2.6.12 | 2024-07-25 | [42519](https://github.com/airbytehq/airbyte/pull/42519) | Update error message for permission issue. | -| 2.6.11 | 2024-07-18 | [42100](https://github.com/airbytehq/airbyte/pull/42100) | Raise config error on 403/404 status code. | -| 2.6.10 | 2024-07-10 | [41436](https://github.com/airbytehq/airbyte/pull/41436) | Fix unit test | -| 2.6.9 | 2024-07-10 | [41390](https://github.com/airbytehq/airbyte/pull/41390) | Update dependencies | -| 2.6.8 | 2024-07-09 | [40025](https://github.com/airbytehq/airbyte/pull/40025) | Update dependencies | -| 2.6.7 | 2024-07-09 | [41032](https://github.com/airbytehq/airbyte/pull/41032) | Use latest `CDK`: 3.0.0 | -| 2.6.6 | 2024-06-27 | [40592](https://github.com/airbytehq/airbyte/pull/40592) | Updated to use latest `CDK` version, fixed `cursor pagination` logic | -| 2.6.5 | 2024-05-23 | [38607](https://github.com/airbytehq/airbyte/pull/38607) | Migrate to cursor based pagination in stream `Organization memberships` | -| 2.6.4 | 2024-05-20 | [38310](https://github.com/airbytehq/airbyte/pull/38310) | Fix record filter for `Ticket Metrics` stream | -| 2.6.3 | 2024-05-02 | [36669](https://github.com/airbytehq/airbyte/pull/36669) | Schema descriptions | -| 2.6.2 | 2024-02-05 | [37761](https://github.com/airbytehq/airbyte/pull/37761) | Add stop condition for `Ticket Audits` when recieved old records; Ignore 403 and 404 status codes. | -| 2.6.1 | 2024-04-30 | [37723](https://github.com/airbytehq/airbyte/pull/37723) | Add %Y-%m-%dT%H:%M:%S%z to cursor_datetime_formats | -| 2.6.0 | 2024-04-29 | [36823](https://github.com/airbytehq/airbyte/pull/36823) | Migrate to low code; Add new stream `Ticket Activities` | -| 2.5.0 | 2024-04-25 | [36388](https://github.com/airbytehq/airbyte/pull/36388) | Fix data type of field in `Tickets` stream schema stream. | -| 2.4.1 | 2024-04-20 | [37450](https://github.com/airbytehq/airbyte/pull/37450) | Fix parsing response for `Ticket Metrics` stream. | -| 2.4.0 | 2024-04-09 | [36897](https://github.com/airbytehq/airbyte/pull/36897) | Fix long-running syncs for `Ticket Metrics`, `Ticket Audits` and `Satisfaction Ratings` streams. | -| 2.3.0 | 2024-03-26 | [36403](https://github.com/airbytehq/airbyte/pull/36403) | Unpin CDK version, add record counts to state messages | -| 2.2.8 | 2024-02-09 | [35083](https://github.com/airbytehq/airbyte/pull/35083) | Manage dependencies with Poetry. | -| 2.2.7 | 2024-02-05 | [34840](https://github.com/airbytehq/airbyte/pull/34840) | Fix missing fields in schema | -| 2.2.6 | 2024-01-11 | [34064](https://github.com/airbytehq/airbyte/pull/34064) | Skip 504 Error for stream `Ticket Audits` | -| 2.2.5 | 2024-01-08 | [34010](https://github.com/airbytehq/airbyte/pull/34010) | Prepare for airbyte-lib | -| 2.2.4 | 2023-12-20 | [33680](https://github.com/airbytehq/airbyte/pull/33680) | Fix pagination issue for streams related to incremental export sync | -| 2.2.3 | 2023-12-14 | [33435](https://github.com/airbytehq/airbyte/pull/33435) | Fix 504 Error for stream Ticket Audits | -| 2.2.2 | 2023-12-01 | [33012](https://github.com/airbytehq/airbyte/pull/33012) | Increase number of retries for backoff policy to 10 | -| 2.2.1 | 2023-11-10 | [32440](https://github.com/airbytehq/airbyte/pull/32440) | Made refactoring to improve code maintainability | -| 2.2.0 | 2023-10-31 | [31999](https://github.com/airbytehq/airbyte/pull/31999) | Extended the `CustomRoles` stream schema | -| 2.1.1 | 2023-10-23 | [31702](https://github.com/airbytehq/airbyte/pull/31702) | Base image migration: remove Dockerfile and use the python-connector-base image | -| 2.1.0 | 2023-10-19 | [31606](https://github.com/airbytehq/airbyte/pull/31606) | Added new field `reply_time_in_seconds` to the `Ticket Metrics` stream schema | -| 2.0.0 | 2023-09-15 | [30440](https://github.com/airbytehq/airbyte/pull/30440) | Remove stream `Deleted Tickets` | -| 1.7.0 | 2023-09-11 | [30259](https://github.com/airbytehq/airbyte/pull/30259) | Add stream `Deleted Tickets` | -| 1.6.0 | 2023-09-09 | [30168](https://github.com/airbytehq/airbyte/pull/30168) | Make `start_date` field optional | -| 1.5.1 | 2023-09-05 | [30142](https://github.com/airbytehq/airbyte/pull/30142) | Handle non-JSON Response | -| 1.5.0 | 2023-09-04 | [30138](https://github.com/airbytehq/airbyte/pull/30138) | Add new Streams: `Article Votes`, `Article Comments`, `Article Comment Votes` | -| 1.4.0 | 2023-09-04 | [30134](https://github.com/airbytehq/airbyte/pull/30134) | Add incremental support for streams: `custom Roles`, `Schedules`, `SLA Policies` | -| 1.3.0 | 2023-08-30 | [30031](https://github.com/airbytehq/airbyte/pull/30031) | Add new streams: `Articles`, `Organization Fields` | -| 1.2.2 | 2023-08-30 | [29998](https://github.com/airbytehq/airbyte/pull/29998) | Fix typo in stream `AttributeDefinitions`: field condition | -| 1.2.1 | 2023-08-30 | [29991](https://github.com/airbytehq/airbyte/pull/29991) | Remove Custom availability strategy | -| 1.2.0 | 2023-08-29 | [29940](https://github.com/airbytehq/airbyte/pull/29940) | Add undeclared fields to schemas | -| 1.1.1 | 2023-08-29 | [29904](https://github.com/airbytehq/airbyte/pull/29904) | Make `Organizations` stream incremental | -| 1.1.0 | 2023-08-28 | [29891](https://github.com/airbytehq/airbyte/pull/29891) | Add stream `UserFields` | -| 1.0.0 | 2023-07-27 | [28774](https://github.com/airbytehq/airbyte/pull/28774) | Fix retry logic & update cursor for `Tickets` stream | -| 0.11.0 | 2023-08-10 | [27208](https://github.com/airbytehq/airbyte/pull/27208) | Add stream `Topics` | -| 0.10.7 | 2023-08-09 | [29256](https://github.com/airbytehq/airbyte/pull/29256) | Update tooltip descriptions in spec | -| 0.10.6 | 2023-08-04 | [29031](https://github.com/airbytehq/airbyte/pull/29031) | Reverted `advancedAuth` spec changes | -| 0.10.5 | 2023-08-01 | [28910](https://github.com/airbytehq/airbyte/pull/28910) | Updated `advancedAuth` broken references | -| 0.10.4 | 2023-07-25 | [28397](https://github.com/airbytehq/airbyte/pull/28397) | Handle 404 Error | -| 0.10.3 | 2023-07-24 | [28612](https://github.com/airbytehq/airbyte/pull/28612) | Fix pagination for stream `TicketMetricEvents` | -| 0.10.2 | 2023-07-19 | [28487](https://github.com/airbytehq/airbyte/pull/28487) | Remove extra page from params | -| 0.10.1 | 2023-07-10 | [28096](https://github.com/airbytehq/airbyte/pull/28096) | Replace `offset` pagination with `cursor` pagination | -| 0.10.0 | 2023-07-06 | [27991](https://github.com/airbytehq/airbyte/pull/27991) | Add streams: `PostVotes`, `PostCommentVotes` | -| 0.9.0 | 2023-07-05 | [27961](https://github.com/airbytehq/airbyte/pull/27961) | Add stream: `Post Comments` | -| 0.8.1 | 2023-06-27 | [27765](https://github.com/airbytehq/airbyte/pull/27765) | Bugfix: Nonetype error while syncing more then 100000 organizations | -| 0.8.0 | 2023-06-09 | [27156](https://github.com/airbytehq/airbyte/pull/27156) | Add stream `Posts` | -| 0.7.0 | 2023-06-27 | [27436](https://github.com/airbytehq/airbyte/pull/27436) | Add Ticket Skips stream | -| 0.6.0 | 2023-06-27 | [27450](https://github.com/airbytehq/airbyte/pull/27450) | Add Skill Based Routing streams | -| 0.5.0 | 2023-06-26 | [27735](https://github.com/airbytehq/airbyte/pull/27735) | License Update: Elv2 stream stream | -| 0.4.0 | 2023-06-16 | [27431](https://github.com/airbytehq/airbyte/pull/27431) | Add Organization Memberships stream | -| 0.3.1 | 2023-06-02 | [26945](https://github.com/airbytehq/airbyte/pull/26945) | Make `Ticket Metrics` stream to use cursor pagination | -| 0.3.0 | 2023-05-23 | [26347](https://github.com/airbytehq/airbyte/pull/26347) | Add stream `Audit Logs` logs` | -| 0.2.30 | 2023-05-23 | [26414](https://github.com/airbytehq/airbyte/pull/26414) | Added missing handlers when `empty json` or `JSONDecodeError` is received | -| 0.2.29 | 2023-04-18 | [25214](https://github.com/airbytehq/airbyte/pull/25214) | Add missing fields to `Tickets` stream | -| 0.2.28 | 2023-03-21 | [24053](https://github.com/airbytehq/airbyte/pull/24053) | Fix stream `sla_policies` schema data type error (events.value) | -| 0.2.27 | 2023-03-22 | [22817](https://github.com/airbytehq/airbyte/pull/22817) | Specified date formatting in specification | -| 0.2.26 | 2023-03-20 | [24252](https://github.com/airbytehq/airbyte/pull/24252) | Handle invalid `start_date` when checking connection | -| 0.2.25 | 2023-02-28 | [22308](https://github.com/airbytehq/airbyte/pull/22308) | Add `AvailabilityStrategy` for all streams | -| 0.2.24 | 2023-02-17 | [23246](https://github.com/airbytehq/airbyte/pull/23246) | Handle `StartTimeTooRecent` error for Tickets stream | -| 0.2.23 | 2023-02-15 | [23035](https://github.com/airbytehq/airbyte/pull/23035) | Handle 403 Error | -| 0.2.22 | 2023-02-14 | [22483](https://github.com/airbytehq/airbyte/pull/22483) | Fix test; handle 400 error | -| 0.2.21 | 2023-01-27 | [22027](https://github.com/airbytehq/airbyte/pull/22027) | Set `AvailabilityStrategy` for streams explicitly to `None` | -| 0.2.20 | 2022-12-28 | [20900](https://github.com/airbytehq/airbyte/pull/20900) | Remove synchronous time.sleep, add logging, reduce backoff time | -| 0.2.19 | 2022-12-09 | [19967](https://github.com/airbytehq/airbyte/pull/19967) | Fix reading response for more than 100k records | -| 0.2.18 | 2022-11-29 | [19432](https://github.com/airbytehq/airbyte/pull/19432) | Revert changes from version 0.2.15, use a test read instead | -| 0.2.17 | 2022-11-24 | [19792](https://github.com/airbytehq/airbyte/pull/19792) | Transform `ticket_comments.via` "-" to null | -| 0.2.16 | 2022-09-28 | [17326](https://github.com/airbytehq/airbyte/pull/17326) | Migrate to per-stream states. | -| 0.2.15 | 2022-08-03 | [15233](https://github.com/airbytehq/airbyte/pull/15233) | Added `subscription plan` check on `streams discovery` step to remove streams that are not accessible for fetch due to subscription plan restrictions | -| 0.2.14 | 2022-07-27 | [15036](https://github.com/airbytehq/airbyte/pull/15036) | Convert `ticket_audits.previous_value` values to string | -| 0.2.13 | 2022-07-21 | [14829](https://github.com/airbytehq/airbyte/pull/14829) | Convert `tickets.custom_fields` values to string | -| 0.2.12 | 2022-06-30 | [14304](https://github.com/airbytehq/airbyte/pull/14304) | Fixed Pagination for Group Membership stream | -| 0.2.11 | 2022-06-24 | [14112](https://github.com/airbytehq/airbyte/pull/14112) | Fixed "Retry-After" non integer value | -| 0.2.10 | 2022-06-14 | [13757](https://github.com/airbytehq/airbyte/pull/13757) | Fixed the bug with `TicketMetrics` stream, HTTP Error 429, caused by lots of API requests | -| 0.2.9 | 2022-05-27 | [13261](https://github.com/airbytehq/airbyte/pull/13261) | Bugfix for the unhandled [ChunkedEncodingError](https://github.com/airbytehq/airbyte/issues/12591) and [ConnectionError](https://github.com/airbytehq/airbyte/issues/12155) | -| 0.2.8 | 2022-05-20 | [13055](https://github.com/airbytehq/airbyte/pull/13055) | Fixed minor issue for stream `ticket_audits` schema | -| 0.2.7 | 2022-04-27 | [12335](https://github.com/airbytehq/airbyte/pull/12335) | Adding fixtures to mock time.sleep for connectors that explicitly sleep | -| 0.2.6 | 2022-04-19 | [12122](https://github.com/airbytehq/airbyte/pull/12122) | Fixed the bug when only 100,000 Users are synced [11895](https://github.com/airbytehq/airbyte/issues/11895) and fixed bug when `start_date` is not used on user stream [12059](https://github.com/airbytehq/airbyte/issues/12059). | -| 0.2.5 | 2022-04-05 | [11727](https://github.com/airbytehq/airbyte/pull/11727) | Fixed the bug when state was not parsed correctly | -| 0.2.4 | 2022-04-04 | [11688](https://github.com/airbytehq/airbyte/pull/11688) | Small documentation corrections | -| 0.2.3 | 2022-03-23 | [11349](https://github.com/airbytehq/airbyte/pull/11349) | Fixed the bug when Tickets stream didn't return deleted records | -| 0.2.2 | 2022-03-17 | [11237](https://github.com/airbytehq/airbyte/pull/11237) | Fixed the bug when TicketComments stream didn't return all records | -| 0.2.1 | 2022-03-15 | [11162](https://github.com/airbytehq/airbyte/pull/11162) | Added support of OAuth2.0 authentication method | -| 0.2.0 | 2022-03-01 | [9456](https://github.com/airbytehq/airbyte/pull/9456) | Update source to use future requests | -| 0.1.12 | 2022-01-25 | [9785](https://github.com/airbytehq/airbyte/pull/9785) | Add additional log messages | -| 0.1.11 | 2021-12-21 | [8987](https://github.com/airbytehq/airbyte/pull/8987) | Update connector fields title/description | -| 0.1.9 | 2021-12-16 | [8616](https://github.com/airbytehq/airbyte/pull/8616) | Adds Brands, CustomRoles and Schedules streams | +| :------ | :--------- | :------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 4.4.1 | 2024-12-13 | [48889](https://github.com/airbytehq/airbyte/pull/48889) | Check if `start_date` exist in check operation | +| 4.4.0 | 2024-11-11 | [48379](https://github.com/airbytehq/airbyte/pull/48379) | Make DatetimeBasedCursor syncs concurrent | +| 4.3.3 | 2024-10-28 | [47663](https://github.com/airbytehq/airbyte/pull/47663) | Update dependencies | +| 4.3.2 | 2024-10-21 | [47202](https://github.com/airbytehq/airbyte/pull/47202) | Update dependencies and expected records | +| 4.3.1 | 2024-10-12 | [46794](https://github.com/airbytehq/airbyte/pull/46794) | Update dependencies | +| 4.3.0 | 2024-10-09 | [46096](https://github.com/airbytehq/airbyte/pull/46096) | Updates `TicketMetrics` stream for improved reliability for long syncs, updates state cursor field to `_ab_updated_at`, automatically migrates legacy state | +| 4.2.3 | 2024-10-05 | [46408](https://github.com/airbytehq/airbyte/pull/46408) | Update dependencies | +| 4.2.2 | 2024-09-28 | [45784](https://github.com/airbytehq/airbyte/pull/45784) | Update dependencies | +| 4.2.1 | 2024-09-14 | [45561](https://github.com/airbytehq/airbyte/pull/45561) | Update dependencies | +| 4.2.0 | 2024-09-10 | [44610](https://github.com/airbytehq/airbyte/pull/44610) | Add `Automations` and `Triggers` stream | +| 4.1.1 | 2024-09-07 | [45215](https://github.com/airbytehq/airbyte/pull/45215) | Update dependencies | +| 4.1.0 | 2024-09-06 | [45187](https://github.com/airbytehq/airbyte/pull/45187) | Migrate to CDK v5 | +| 4.0.2 | 2024-08-31 | [44965](https://github.com/airbytehq/airbyte/pull/44965) | Update dependencies | +| 4.0.1 | 2024-08-24 | [44692](https://github.com/airbytehq/airbyte/pull/44692) | Update dependencies | +| 4.0.0 | 2024-08-19 | [44096](https://github.com/airbytehq/airbyte/pull/44096) | Stream `Tags`: use cursor based pagination | +| 3.0.1 | 2024-08-17 | [44324](https://github.com/airbytehq/airbyte/pull/44324) | Update dependencies | +| 3.0.0 | 2024-08-13 | [43446](https://github.com/airbytehq/airbyte/pull/43446) | `TicketMetrics` stream: updates cursor field to `generated_timestamp` | +| 2.7.3 | 2024-08-12 | [43900](https://github.com/airbytehq/airbyte/pull/43900) | Update dependencies | +| 2.7.2 | 2024-08-10 | [43614](https://github.com/airbytehq/airbyte/pull/43614) | Update dependencies | +| 2.7.1 | 2024-08-03 | [41799](https://github.com/airbytehq/airbyte/pull/41799) | Update dependencies | +| 2.7.0 | 2024-08-02 | [42975](https://github.com/airbytehq/airbyte/pull/42975) | Migrate to CDK v4.3.0 | +| 2.6.13 | 2024-07-31 | [42892](https://github.com/airbytehq/airbyte/pull/42892) | Update BackoffStrategy interface to be up-to-date with latest parent interface. | +| 2.6.12 | 2024-07-25 | [42519](https://github.com/airbytehq/airbyte/pull/42519) | Update error message for permission issue. | +| 2.6.11 | 2024-07-18 | [42100](https://github.com/airbytehq/airbyte/pull/42100) | Raise config error on 403/404 status code. | +| 2.6.10 | 2024-07-10 | [41436](https://github.com/airbytehq/airbyte/pull/41436) | Fix unit test | +| 2.6.9 | 2024-07-10 | [41390](https://github.com/airbytehq/airbyte/pull/41390) | Update dependencies | +| 2.6.8 | 2024-07-09 | [40025](https://github.com/airbytehq/airbyte/pull/40025) | Update dependencies | +| 2.6.7 | 2024-07-09 | [41032](https://github.com/airbytehq/airbyte/pull/41032) | Use latest `CDK`: 3.0.0 | +| 2.6.6 | 2024-06-27 | [40592](https://github.com/airbytehq/airbyte/pull/40592) | Updated to use latest `CDK` version, fixed `cursor pagination` logic | +| 2.6.5 | 2024-05-23 | [38607](https://github.com/airbytehq/airbyte/pull/38607) | Migrate to cursor based pagination in stream `Organization memberships` | +| 2.6.4 | 2024-05-20 | [38310](https://github.com/airbytehq/airbyte/pull/38310) | Fix record filter for `Ticket Metrics` stream | +| 2.6.3 | 2024-05-02 | [36669](https://github.com/airbytehq/airbyte/pull/36669) | Schema descriptions | +| 2.6.2 | 2024-02-05 | [37761](https://github.com/airbytehq/airbyte/pull/37761) | Add stop condition for `Ticket Audits` when recieved old records; Ignore 403 and 404 status codes. | +| 2.6.1 | 2024-04-30 | [37723](https://github.com/airbytehq/airbyte/pull/37723) | Add %Y-%m-%dT%H:%M:%S%z to cursor_datetime_formats | +| 2.6.0 | 2024-04-29 | [36823](https://github.com/airbytehq/airbyte/pull/36823) | Migrate to low code; Add new stream `Ticket Activities` | +| 2.5.0 | 2024-04-25 | [36388](https://github.com/airbytehq/airbyte/pull/36388) | Fix data type of field in `Tickets` stream schema stream. | +| 2.4.1 | 2024-04-20 | [37450](https://github.com/airbytehq/airbyte/pull/37450) | Fix parsing response for `Ticket Metrics` stream. | +| 2.4.0 | 2024-04-09 | [36897](https://github.com/airbytehq/airbyte/pull/36897) | Fix long-running syncs for `Ticket Metrics`, `Ticket Audits` and `Satisfaction Ratings` streams. | +| 2.3.0 | 2024-03-26 | [36403](https://github.com/airbytehq/airbyte/pull/36403) | Unpin CDK version, add record counts to state messages | +| 2.2.8 | 2024-02-09 | [35083](https://github.com/airbytehq/airbyte/pull/35083) | Manage dependencies with Poetry. | +| 2.2.7 | 2024-02-05 | [34840](https://github.com/airbytehq/airbyte/pull/34840) | Fix missing fields in schema | +| 2.2.6 | 2024-01-11 | [34064](https://github.com/airbytehq/airbyte/pull/34064) | Skip 504 Error for stream `Ticket Audits` | +| 2.2.5 | 2024-01-08 | [34010](https://github.com/airbytehq/airbyte/pull/34010) | Prepare for airbyte-lib | +| 2.2.4 | 2023-12-20 | [33680](https://github.com/airbytehq/airbyte/pull/33680) | Fix pagination issue for streams related to incremental export sync | +| 2.2.3 | 2023-12-14 | [33435](https://github.com/airbytehq/airbyte/pull/33435) | Fix 504 Error for stream Ticket Audits | +| 2.2.2 | 2023-12-01 | [33012](https://github.com/airbytehq/airbyte/pull/33012) | Increase number of retries for backoff policy to 10 | +| 2.2.1 | 2023-11-10 | [32440](https://github.com/airbytehq/airbyte/pull/32440) | Made refactoring to improve code maintainability | +| 2.2.0 | 2023-10-31 | [31999](https://github.com/airbytehq/airbyte/pull/31999) | Extended the `CustomRoles` stream schema | +| 2.1.1 | 2023-10-23 | [31702](https://github.com/airbytehq/airbyte/pull/31702) | Base image migration: remove Dockerfile and use the python-connector-base image | +| 2.1.0 | 2023-10-19 | [31606](https://github.com/airbytehq/airbyte/pull/31606) | Added new field `reply_time_in_seconds` to the `Ticket Metrics` stream schema | +| 2.0.0 | 2023-09-15 | [30440](https://github.com/airbytehq/airbyte/pull/30440) | Remove stream `Deleted Tickets` | +| 1.7.0 | 2023-09-11 | [30259](https://github.com/airbytehq/airbyte/pull/30259) | Add stream `Deleted Tickets` | +| 1.6.0 | 2023-09-09 | [30168](https://github.com/airbytehq/airbyte/pull/30168) | Make `start_date` field optional | +| 1.5.1 | 2023-09-05 | [30142](https://github.com/airbytehq/airbyte/pull/30142) | Handle non-JSON Response | +| 1.5.0 | 2023-09-04 | [30138](https://github.com/airbytehq/airbyte/pull/30138) | Add new Streams: `Article Votes`, `Article Comments`, `Article Comment Votes` | +| 1.4.0 | 2023-09-04 | [30134](https://github.com/airbytehq/airbyte/pull/30134) | Add incremental support for streams: `custom Roles`, `Schedules`, `SLA Policies` | +| 1.3.0 | 2023-08-30 | [30031](https://github.com/airbytehq/airbyte/pull/30031) | Add new streams: `Articles`, `Organization Fields` | +| 1.2.2 | 2023-08-30 | [29998](https://github.com/airbytehq/airbyte/pull/29998) | Fix typo in stream `AttributeDefinitions`: field condition | +| 1.2.1 | 2023-08-30 | [29991](https://github.com/airbytehq/airbyte/pull/29991) | Remove Custom availability strategy | +| 1.2.0 | 2023-08-29 | [29940](https://github.com/airbytehq/airbyte/pull/29940) | Add undeclared fields to schemas | +| 1.1.1 | 2023-08-29 | [29904](https://github.com/airbytehq/airbyte/pull/29904) | Make `Organizations` stream incremental | +| 1.1.0 | 2023-08-28 | [29891](https://github.com/airbytehq/airbyte/pull/29891) | Add stream `UserFields` | +| 1.0.0 | 2023-07-27 | [28774](https://github.com/airbytehq/airbyte/pull/28774) | Fix retry logic & update cursor for `Tickets` stream | +| 0.11.0 | 2023-08-10 | [27208](https://github.com/airbytehq/airbyte/pull/27208) | Add stream `Topics` | +| 0.10.7 | 2023-08-09 | [29256](https://github.com/airbytehq/airbyte/pull/29256) | Update tooltip descriptions in spec | +| 0.10.6 | 2023-08-04 | [29031](https://github.com/airbytehq/airbyte/pull/29031) | Reverted `advancedAuth` spec changes | +| 0.10.5 | 2023-08-01 | [28910](https://github.com/airbytehq/airbyte/pull/28910) | Updated `advancedAuth` broken references | +| 0.10.4 | 2023-07-25 | [28397](https://github.com/airbytehq/airbyte/pull/28397) | Handle 404 Error | +| 0.10.3 | 2023-07-24 | [28612](https://github.com/airbytehq/airbyte/pull/28612) | Fix pagination for stream `TicketMetricEvents` | +| 0.10.2 | 2023-07-19 | [28487](https://github.com/airbytehq/airbyte/pull/28487) | Remove extra page from params | +| 0.10.1 | 2023-07-10 | [28096](https://github.com/airbytehq/airbyte/pull/28096) | Replace `offset` pagination with `cursor` pagination | +| 0.10.0 | 2023-07-06 | [27991](https://github.com/airbytehq/airbyte/pull/27991) | Add streams: `PostVotes`, `PostCommentVotes` | +| 0.9.0 | 2023-07-05 | [27961](https://github.com/airbytehq/airbyte/pull/27961) | Add stream: `Post Comments` | +| 0.8.1 | 2023-06-27 | [27765](https://github.com/airbytehq/airbyte/pull/27765) | Bugfix: Nonetype error while syncing more then 100000 organizations | +| 0.8.0 | 2023-06-09 | [27156](https://github.com/airbytehq/airbyte/pull/27156) | Add stream `Posts` | +| 0.7.0 | 2023-06-27 | [27436](https://github.com/airbytehq/airbyte/pull/27436) | Add Ticket Skips stream | +| 0.6.0 | 2023-06-27 | [27450](https://github.com/airbytehq/airbyte/pull/27450) | Add Skill Based Routing streams | +| 0.5.0 | 2023-06-26 | [27735](https://github.com/airbytehq/airbyte/pull/27735) | License Update: Elv2 stream stream | +| 0.4.0 | 2023-06-16 | [27431](https://github.com/airbytehq/airbyte/pull/27431) | Add Organization Memberships stream | +| 0.3.1 | 2023-06-02 | [26945](https://github.com/airbytehq/airbyte/pull/26945) | Make `Ticket Metrics` stream to use cursor pagination | +| 0.3.0 | 2023-05-23 | [26347](https://github.com/airbytehq/airbyte/pull/26347) | Add stream `Audit Logs` logs` | +| 0.2.30 | 2023-05-23 | [26414](https://github.com/airbytehq/airbyte/pull/26414) | Added missing handlers when `empty json` or `JSONDecodeError` is received | +| 0.2.29 | 2023-04-18 | [25214](https://github.com/airbytehq/airbyte/pull/25214) | Add missing fields to `Tickets` stream | +| 0.2.28 | 2023-03-21 | [24053](https://github.com/airbytehq/airbyte/pull/24053) | Fix stream `sla_policies` schema data type error (events.value) | +| 0.2.27 | 2023-03-22 | [22817](https://github.com/airbytehq/airbyte/pull/22817) | Specified date formatting in specification | +| 0.2.26 | 2023-03-20 | [24252](https://github.com/airbytehq/airbyte/pull/24252) | Handle invalid `start_date` when checking connection | +| 0.2.25 | 2023-02-28 | [22308](https://github.com/airbytehq/airbyte/pull/22308) | Add `AvailabilityStrategy` for all streams | +| 0.2.24 | 2023-02-17 | [23246](https://github.com/airbytehq/airbyte/pull/23246) | Handle `StartTimeTooRecent` error for Tickets stream | +| 0.2.23 | 2023-02-15 | [23035](https://github.com/airbytehq/airbyte/pull/23035) | Handle 403 Error | +| 0.2.22 | 2023-02-14 | [22483](https://github.com/airbytehq/airbyte/pull/22483) | Fix test; handle 400 error | +| 0.2.21 | 2023-01-27 | [22027](https://github.com/airbytehq/airbyte/pull/22027) | Set `AvailabilityStrategy` for streams explicitly to `None` | +| 0.2.20 | 2022-12-28 | [20900](https://github.com/airbytehq/airbyte/pull/20900) | Remove synchronous time.sleep, add logging, reduce backoff time | +| 0.2.19 | 2022-12-09 | [19967](https://github.com/airbytehq/airbyte/pull/19967) | Fix reading response for more than 100k records | +| 0.2.18 | 2022-11-29 | [19432](https://github.com/airbytehq/airbyte/pull/19432) | Revert changes from version 0.2.15, use a test read instead | +| 0.2.17 | 2022-11-24 | [19792](https://github.com/airbytehq/airbyte/pull/19792) | Transform `ticket_comments.via` "-" to null | +| 0.2.16 | 2022-09-28 | [17326](https://github.com/airbytehq/airbyte/pull/17326) | Migrate to per-stream states. | +| 0.2.15 | 2022-08-03 | [15233](https://github.com/airbytehq/airbyte/pull/15233) | Added `subscription plan` check on `streams discovery` step to remove streams that are not accessible for fetch due to subscription plan restrictions | +| 0.2.14 | 2022-07-27 | [15036](https://github.com/airbytehq/airbyte/pull/15036) | Convert `ticket_audits.previous_value` values to string | +| 0.2.13 | 2022-07-21 | [14829](https://github.com/airbytehq/airbyte/pull/14829) | Convert `tickets.custom_fields` values to string | +| 0.2.12 | 2022-06-30 | [14304](https://github.com/airbytehq/airbyte/pull/14304) | Fixed Pagination for Group Membership stream | +| 0.2.11 | 2022-06-24 | [14112](https://github.com/airbytehq/airbyte/pull/14112) | Fixed "Retry-After" non integer value | +| 0.2.10 | 2022-06-14 | [13757](https://github.com/airbytehq/airbyte/pull/13757) | Fixed the bug with `TicketMetrics` stream, HTTP Error 429, caused by lots of API requests | +| 0.2.9 | 2022-05-27 | [13261](https://github.com/airbytehq/airbyte/pull/13261) | Bugfix for the unhandled [ChunkedEncodingError](https://github.com/airbytehq/airbyte/issues/12591) and [ConnectionError](https://github.com/airbytehq/airbyte/issues/12155) | +| 0.2.8 | 2022-05-20 | [13055](https://github.com/airbytehq/airbyte/pull/13055) | Fixed minor issue for stream `ticket_audits` schema | +| 0.2.7 | 2022-04-27 | [12335](https://github.com/airbytehq/airbyte/pull/12335) | Adding fixtures to mock time.sleep for connectors that explicitly sleep | +| 0.2.6 | 2022-04-19 | [12122](https://github.com/airbytehq/airbyte/pull/12122) | Fixed the bug when only 100,000 Users are synced [11895](https://github.com/airbytehq/airbyte/issues/11895) and fixed bug when `start_date` is not used on user stream [12059](https://github.com/airbytehq/airbyte/issues/12059). | +| 0.2.5 | 2022-04-05 | [11727](https://github.com/airbytehq/airbyte/pull/11727) | Fixed the bug when state was not parsed correctly | +| 0.2.4 | 2022-04-04 | [11688](https://github.com/airbytehq/airbyte/pull/11688) | Small documentation corrections | +| 0.2.3 | 2022-03-23 | [11349](https://github.com/airbytehq/airbyte/pull/11349) | Fixed the bug when Tickets stream didn't return deleted records | +| 0.2.2 | 2022-03-17 | [11237](https://github.com/airbytehq/airbyte/pull/11237) | Fixed the bug when TicketComments stream didn't return all records | +| 0.2.1 | 2022-03-15 | [11162](https://github.com/airbytehq/airbyte/pull/11162) | Added support of OAuth2.0 authentication method | +| 0.2.0 | 2022-03-01 | [9456](https://github.com/airbytehq/airbyte/pull/9456) | Update source to use future requests | +| 0.1.12 | 2022-01-25 | [9785](https://github.com/airbytehq/airbyte/pull/9785) | Add additional log messages | +| 0.1.11 | 2021-12-21 | [8987](https://github.com/airbytehq/airbyte/pull/8987) | Update connector fields title/description | +| 0.1.9 | 2021-12-16 | [8616](https://github.com/airbytehq/airbyte/pull/8616) | Adds Brands, CustomRoles and Schedules streams | | 0.1.8 | 2021-11-23 | [8050](https://github.com/airbytehq/airbyte/pull/8168) | Adds TicketMetricEvents stream | | 0.1.7 | 2021-11-23 | [8058](https://github.com/airbytehq/airbyte/pull/8058) | Added support of AccessToken authentication | | 0.1.6 | 2021-11-18 | [8050](https://github.com/airbytehq/airbyte/pull/8050) | Fix wrong types for schemas, add TypeTransformer | diff --git a/docs/integrations/sources/zendesk-talk.md b/docs/integrations/sources/zendesk-talk.md index 2964044982eb..259e512a887d 100644 --- a/docs/integrations/sources/zendesk-talk.md +++ b/docs/integrations/sources/zendesk-talk.md @@ -79,6 +79,7 @@ The Zendesk connector should not run into Zendesk API limitations under normal u | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:----------------------------------------------------------------------------| +| 1.1.0-rc.1 | 2024-10-31 | [47313](https://github.com/airbytehq/airbyte/pull/47313) | Migrate to Manifest-only | | 1.0.21 | 2024-10-29 | [47082](https://github.com/airbytehq/airbyte/pull/47082) | Update dependencies | | 1.0.20 | 2024-10-12 | [46861](https://github.com/airbytehq/airbyte/pull/46861) | Update dependencies | | 1.0.19 | 2024-10-05 | [46394](https://github.com/airbytehq/airbyte/pull/46394) | Update dependencies | diff --git a/docs/integrations/sources/zenefits.md b/docs/integrations/sources/zenefits.md index b7415cd57e37..6adfb957d1a9 100644 --- a/docs/integrations/sources/zenefits.md +++ b/docs/integrations/sources/zenefits.md @@ -53,20 +53,23 @@ You can replicate the following tables using the Zenefits connector: | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | -| 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | -| 0.3.0 | 2024-08-01 | [42950](https://github.com/airbytehq/airbyte/pull/42950) | Refactor connector to manifest-only format | -| 0.2.13 | 2024-07-27 | [42668](https://github.com/airbytehq/airbyte/pull/42668) | Update dependencies | -| 0.2.12 | 2024-07-20 | [42153](https://github.com/airbytehq/airbyte/pull/42153) | Update dependencies | -| 0.2.11 | 2024-07-13 | [41810](https://github.com/airbytehq/airbyte/pull/41810) | Update dependencies | -| 0.2.10 | 2024-07-10 | [41535](https://github.com/airbytehq/airbyte/pull/41535) | Update dependencies | -| 0.2.9 | 2024-07-09 | [41298](https://github.com/airbytehq/airbyte/pull/41298) | Update dependencies | -| 0.2.8 | 2024-07-06 | [40765](https://github.com/airbytehq/airbyte/pull/40765) | Update dependencies | -| 0.2.7 | 2024-06-25 | [40264](https://github.com/airbytehq/airbyte/pull/40264) | Update dependencies | -| 0.2.6 | 2024-06-22 | [40055](https://github.com/airbytehq/airbyte/pull/40055) | Update dependencies | -| 0.2.5 | 2024-06-04 | [39086](https://github.com/airbytehq/airbyte/pull/39086) | [autopull] Upgrade base image to v1.2.1 | -| 0.2.4 | 2024-04-19 | [37303](https://github.com/airbytehq/airbyte/pull/37303) | Updating to 0.80.0 CDK | -| 0.2.3 | 2024-04-18 | [37303](https://github.com/airbytehq/airbyte/pull/37303) | Manage dependencies with Poetry. | -| 0.2.2 | 2024-04-15 | [37303](https://github.com/airbytehq/airbyte/pull/37303) | Base image migration: remove Dockerfile and use the python-connector-base image | -| 0.2.1 | 2024-04-12 | [37303](https://github.com/airbytehq/airbyte/pull/37303) | schema descriptions | -| 0.2.0 | 2023-10-29 | [31946](https://github.com/airbytehq/airbyte/pull/31946) | Migrate to Low Code | -| 0.1.0 | 2022-08-24 | [14809](https://github.com/airbytehq/airbyte/pull/14809) | Initial Release | +| 0.3.4 | 2024-12-28 | [50838](https://github.com/airbytehq/airbyte/pull/50838) | Update dependencies | +| 0.3.3 | 2024-12-21 | [50365](https://github.com/airbytehq/airbyte/pull/50365) | Update dependencies | +| 0.3.2 | 2024-12-14 | [47648](https://github.com/airbytehq/airbyte/pull/47648) | Update dependencies | +| 0.3.1 | 2024-08-16 | [44196](https://github.com/airbytehq/airbyte/pull/44196) | Bump source-declarative-manifest version | +| 0.3.0 | 2024-08-01 | [42950](https://github.com/airbytehq/airbyte/pull/42950) | Refactor connector to manifest-only format | +| 0.2.13 | 2024-07-27 | [42668](https://github.com/airbytehq/airbyte/pull/42668) | Update dependencies | +| 0.2.12 | 2024-07-20 | [42153](https://github.com/airbytehq/airbyte/pull/42153) | Update dependencies | +| 0.2.11 | 2024-07-13 | [41810](https://github.com/airbytehq/airbyte/pull/41810) | Update dependencies | +| 0.2.10 | 2024-07-10 | [41535](https://github.com/airbytehq/airbyte/pull/41535) | Update dependencies | +| 0.2.9 | 2024-07-09 | [41298](https://github.com/airbytehq/airbyte/pull/41298) | Update dependencies | +| 0.2.8 | 2024-07-06 | [40765](https://github.com/airbytehq/airbyte/pull/40765) | Update dependencies | +| 0.2.7 | 2024-06-25 | [40264](https://github.com/airbytehq/airbyte/pull/40264) | Update dependencies | +| 0.2.6 | 2024-06-22 | [40055](https://github.com/airbytehq/airbyte/pull/40055) | Update dependencies | +| 0.2.5 | 2024-06-04 | [39086](https://github.com/airbytehq/airbyte/pull/39086) | [autopull] Upgrade base image to v1.2.1 | +| 0.2.4 | 2024-04-19 | [37303](https://github.com/airbytehq/airbyte/pull/37303) | Updating to 0.80.0 CDK | +| 0.2.3 | 2024-04-18 | [37303](https://github.com/airbytehq/airbyte/pull/37303) | Manage dependencies with Poetry. | +| 0.2.2 | 2024-04-15 | [37303](https://github.com/airbytehq/airbyte/pull/37303) | Base image migration: remove Dockerfile and use the python-connector-base image | +| 0.2.1 | 2024-04-12 | [37303](https://github.com/airbytehq/airbyte/pull/37303) | schema descriptions | +| 0.2.0 | 2023-10-29 | [31946](https://github.com/airbytehq/airbyte/pull/31946) | Migrate to Low Code | +| 0.1.0 | 2022-08-24 | [14809](https://github.com/airbytehq/airbyte/pull/14809) | Initial Release | diff --git a/docs/integrations/sources/zenloop.md b/docs/integrations/sources/zenloop.md index 931e84df9583..d025fb16671a 100644 --- a/docs/integrations/sources/zenloop.md +++ b/docs/integrations/sources/zenloop.md @@ -77,6 +77,11 @@ The Zenloop connector should not run into Zenloop API limitations under normal u | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------ | +| 0.1.39 | 2024-12-28 | [50827](https://github.com/airbytehq/airbyte/pull/50827) | Update dependencies | +| 0.1.38 | 2024-12-21 | [50383](https://github.com/airbytehq/airbyte/pull/50383) | Update dependencies | +| 0.1.37 | 2024-12-14 | [49801](https://github.com/airbytehq/airbyte/pull/49801) | Update dependencies | +| 0.1.36 | 2024-12-12 | [49443](https://github.com/airbytehq/airbyte/pull/49443) | Starting with this version, the Docker image is now rootless. Please note that this and future versions will not be compatible with Airbyte versions earlier than 0.64 | +| 0.1.35 | 2024-11-04 | [47107](https://github.com/airbytehq/airbyte/pull/47107) | Update dependencies | | 0.1.34 | 2024-10-12 | [46780](https://github.com/airbytehq/airbyte/pull/46780) | Update dependencies | | 0.1.33 | 2024-10-05 | [46431](https://github.com/airbytehq/airbyte/pull/46431) | Update dependencies | | 0.1.32 | 2024-09-28 | [46141](https://github.com/airbytehq/airbyte/pull/46141) | Update dependencies | diff --git a/docs/integrations/sources/zoho-analytics-metadata-api.md b/docs/integrations/sources/zoho-analytics-metadata-api.md new file mode 100644 index 000000000000..3ace8992f9f6 --- /dev/null +++ b/docs/integrations/sources/zoho-analytics-metadata-api.md @@ -0,0 +1,38 @@ +# Zoho Analytics Metadata API +Zoho Analytics Metadata api connector enables seamless data syncing from Zoho Analytics metadata into data warehouses or BI tools. This connector automates OAuth authentication and ensures reliable data transfer, empowering businesses to streamline analytics workflows and gain deeper insights efficiently. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `org_id` | `number` | Org Id. | | +| `data_center` | `string` | Data Center. | `com` | +| `client_id` | `string` | OAuth Client ID. | | +| `client_secret` | `string` | OAuth Client Secret. | | +| `refresh_token` | `string` | OAuth Refresh Token. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| users | emailId | No pagination | ✅ | ❌ | +| workspaces | workspaceId | No pagination | ✅ | ❌ | +| organizations | orgId | No pagination | ✅ | ❌ | +| views | viewId | No pagination | ✅ | ❌ | +| dashboards | viewId | No pagination | ✅ | ❌ | +| trash | viewId | No pagination | ✅ | ❌ | +| workspace_users | emailId | No pagination | ✅ | ❌ | +| folders | folderId | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.4 | 2024-12-28 | [50837](https://github.com/airbytehq/airbyte/pull/50837) | Update dependencies | +| 0.0.3 | 2024-12-21 | [50384](https://github.com/airbytehq/airbyte/pull/50384) | Update dependencies | +| 0.0.2 | 2024-12-14 | [49450](https://github.com/airbytehq/airbyte/pull/49450) | Update dependencies | +| 0.0.1 | 2024-11-07 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/zoho-bigin.md b/docs/integrations/sources/zoho-bigin.md new file mode 100644 index 000000000000..c6fbc0bfad9e --- /dev/null +++ b/docs/integrations/sources/zoho-bigin.md @@ -0,0 +1,40 @@ +# Zoho Bigin + Zoho Bigin connector enables seamless data sync between Zoho Bigin and other platforms. This connector automates CRM data integration, improving workflows and ensuring real-time access to customer insights across tools. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `data_center` | `string` | Data Center. The data center where the Bigin account's resources are hosted | com | +| `client_id` | `string` | OAuth Client ID. | | +| `client_secret` | `string` | OAuth Client Secret. | | +| `client_refresh_token` | `string` | Refresh token. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| users | id | DefaultPaginator | ✅ | ❌ | +| modules | id | No pagination | ✅ | ❌ | +| organizations | id | No pagination | ✅ | ❌ | +| roles | id | No pagination | ✅ | ❌ | +| notes | id | DefaultPaginator | ✅ | ❌ | +| tags | id | No pagination | ✅ | ❌ | +| companies | id | DefaultPaginator | ✅ | ❌ | +| contacts | id | DefaultPaginator | ✅ | ❌ | +| tasks | | DefaultPaginator | ✅ | ❌ | +| events | id | DefaultPaginator | ✅ | ❌ | +| products | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.4 | 2024-12-28 | [50832](https://github.com/airbytehq/airbyte/pull/50832) | Update dependencies | +| 0.0.3 | 2024-12-21 | [50391](https://github.com/airbytehq/airbyte/pull/50391) | Update dependencies | +| 0.0.2 | 2024-12-14 | [49449](https://github.com/airbytehq/airbyte/pull/49449) | Update dependencies | +| 0.0.1 | 2024-10-27 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/zoho-billing.md b/docs/integrations/sources/zoho-billing.md new file mode 100644 index 000000000000..a48f1c3012ee --- /dev/null +++ b/docs/integrations/sources/zoho-billing.md @@ -0,0 +1,43 @@ +# Zoho Billing +Zoho Billing is a billing software used by countless organizations across the globe. +Using this connector we can extract data from various streams such as products , invoices , transactions and quotes. +Docs : https://www.zoho.com/billing/api/v1/introduction/#overview + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `region` | `string` | Region. | | +| `client_id` | `string` | OAuth Client ID. | | +| `client_secret` | `string` | OAuth Client Secret. | | +| `refresh_token` | `string` | OAuth Refresh Token. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| Products | product_id | DefaultPaginator | ✅ | ❌ | +| plans | plan_code | DefaultPaginator | ✅ | ❌ | +| addons | addon_code | DefaultPaginator | ✅ | ❌ | +| coupons | coupon_code | DefaultPaginator | ✅ | ❌ | +| customers | customer_id | DefaultPaginator | ✅ | ❌ | +| Quotes | estimate_id | DefaultPaginator | ✅ | ❌ | +| invoices | invoice_id | DefaultPaginator | ✅ | ❌ | +| expenses | expense_id | DefaultPaginator | ✅ | ❌ | +| subscriptions | customer_id | DefaultPaginator | ✅ | ❌ | +| taxes | tax_id | DefaultPaginator | ✅ | ❌ | +| transactions | transaction_id | DefaultPaginator | ✅ | ❌ | +| recurring expenses | recurring_expense_id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.4 | 2024-12-28 | [50836](https://github.com/airbytehq/airbyte/pull/50836) | Update dependencies | +| 0.0.3 | 2024-12-21 | [50392](https://github.com/airbytehq/airbyte/pull/50392) | Update dependencies | +| 0.0.2 | 2024-12-14 | [49451](https://github.com/airbytehq/airbyte/pull/49451) | Update dependencies | +| 0.0.1 | 2024-11-05 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/zoho-books.md b/docs/integrations/sources/zoho-books.md index 8510e71011e0..41a3a8f5bd9c 100644 --- a/docs/integrations/sources/zoho-books.md +++ b/docs/integrations/sources/zoho-books.md @@ -38,6 +38,10 @@ The Zoho Books connector enables seamless integration of financial data, automa | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50839](https://github.com/airbytehq/airbyte/pull/50839) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50386](https://github.com/airbytehq/airbyte/pull/50386) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49447](https://github.com/airbytehq/airbyte/pull/49447) | Update dependencies | +| 0.0.3 | 2024-11-04 | [48173](https://github.com/airbytehq/airbyte/pull/48173) | Update dependencies | | 0.0.2 | 2024-10-28 | [47582](https://github.com/airbytehq/airbyte/pull/47582) | Update dependencies | | 0.0.1 | 2024-10-19 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | diff --git a/docs/integrations/sources/zoho-campaign.md b/docs/integrations/sources/zoho-campaign.md new file mode 100644 index 000000000000..f3cef669dec9 --- /dev/null +++ b/docs/integrations/sources/zoho-campaign.md @@ -0,0 +1,40 @@ +# Zoho Campaign +The Zoho Campaigns connector enables seamless integration of mailing lists, campaign data, and subscriber management into your data workflows. Easily extract subscriber information, campaign reports, and list details to sync with your data warehouse or BI tools, automating marketing insights and analytics + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `client_id_2` | `string` | Client ID. | | +| `client_secret_2` | `string` | Client secret. | | +| `client_refresh_token` | `string` | Refresh token. | | +| `domain` | `string` | Domain. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| recent_campaigns | campaign_key | DefaultPaginator | ✅ | ❌ | +| campaign_recipients | contactid, sent_time | DefaultPaginator | ✅ | ❌ | +| campaign_details | campaign_name | No pagination | ✅ | ❌ | +| campaign_reports | campaign_name | No pagination | ✅ | ❌ | +| recent_sent_campaigns | campaign_key | DefaultPaginator | ✅ | ❌ | +| mailing_lists | listunino | DefaultPaginator | ✅ | ❌ | +| subscribers | contact_email | DefaultPaginator | ✅ | ❌ | +| lists | listkey | No pagination | ✅ | ❌ | +| total_contacts | | No pagination | ✅ | ❌ | +| topics | topicId | No pagination | ✅ | ❌ | +| all_tags | | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.4 | 2024-12-28 | [50830](https://github.com/airbytehq/airbyte/pull/50830) | Update dependencies | +| 0.0.3 | 2024-12-21 | [50390](https://github.com/airbytehq/airbyte/pull/50390) | Update dependencies | +| 0.0.2 | 2024-12-14 | [49452](https://github.com/airbytehq/airbyte/pull/49452) | Update dependencies | +| 0.0.1 | 2024-10-14 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/zoho-desk.md b/docs/integrations/sources/zoho-desk.md new file mode 100644 index 000000000000..edfe1123ee4e --- /dev/null +++ b/docs/integrations/sources/zoho-desk.md @@ -0,0 +1,65 @@ +# Zoho Desk +This directory contains the manifest-only connector for source-zoho-desk + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `client_id` | `string` | Client ID. | | +| `client_secret` | `string` | Client secret. | | +| `token_refresh_endpoint` | `string` | Token Refresh Endpoint. | | +| `refresh_token` | `string` | OAuth Refresh Token. | | +| `include_custom_domain` | `boolean` | include Custom Domain. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| organization | id | No pagination | ✅ | ❌ | +| all_organizations | id | No pagination | ✅ | ❌ | +| accessible_organizations | | No pagination | ✅ | ❌ | +| agent | | No pagination | ✅ | ❌ | +| list_agents | id | DefaultPaginator | ✅ | ❌ | +| agent_details_by_id | id | No pagination | ✅ | ❌ | +| profiles | id | No pagination | ✅ | ❌ | +| list_roles | id | DefaultPaginator | ✅ | ❌ | +| teams | id | No pagination | ✅ | ❌ | +| team_members | id | No pagination | ✅ | ❌ | +| list_departments | | DefaultPaginator | ✅ | ❌ | +| channels | code | No pagination | ✅ | ❌ | +| list_tickets | id | DefaultPaginator | ✅ | ❌ | +| list_all_threads | id | DefaultPaginator | ✅ | ❌ | +| get_latest_thread | id | No pagination | ✅ | ❌ | +| list_contacts | id | DefaultPaginator | ✅ | ❌ | +| webhooks | | No pagination | ✅ | ❌ | +| list_accounts | id | DefaultPaginator | ✅ | ❌ | +| list_contracts | id | DefaultPaginator | ✅ | ❌ | +| list_tasks | id | DefaultPaginator | ✅ | ❌ | +| list_products | id | DefaultPaginator | ✅ | ❌ | +| list_articles | id | No pagination | ✅ | ❌ | +| list_events | id | DefaultPaginator | ✅ | ❌ | +| modules | id | No pagination | ✅ | ❌ | +| list_users | id | DefaultPaginator | ✅ | ❌ | +| ticket_activities | id | DefaultPaginator | ✅ | ❌ | +| list_attachments | | DefaultPaginator | ✅ | ❌ | +| product | id | No pagination | ✅ | ❌ | +| task_attachments | id | DefaultPaginator | ✅ | ❌ | +| list_calls | id | DefaultPaginator | ✅ | ❌ | +| call | id | No pagination | ✅ | ❌ | +| list_call_comments | id | DefaultPaginator | ✅ | ❌ | +| dashboard_created_tickets | | No pagination | ✅ | ❌ | +| list_user_groups | id | DefaultPaginator | ✅ | ❌ | +| dashboard_onhold_tickets | value | No pagination | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.4 | 2024-12-28 | [50833](https://github.com/airbytehq/airbyte/pull/50833) | Update dependencies | +| 0.0.3 | 2024-12-21 | [50387](https://github.com/airbytehq/airbyte/pull/50387) | Update dependencies | +| 0.0.2 | 2024-12-14 | [49446](https://github.com/airbytehq/airbyte/pull/49446) | Update dependencies | +| 0.0.1 | 2024-10-28 | [46863](https://github.com/airbytehq/airbyte/pull/46863) | Initial release by [@itsxdamdam](https://github.com/itsxdamdam) via Connector Builder | + +
diff --git a/docs/integrations/sources/zoho-expense.md b/docs/integrations/sources/zoho-expense.md new file mode 100644 index 000000000000..56c44584dfd7 --- /dev/null +++ b/docs/integrations/sources/zoho-expense.md @@ -0,0 +1,39 @@ +# Zoho Expense +Zoho Expense connector enables seamless data synchronization between Zoho Expense and various destinations. This connector automates expense tracking workflows by extracting financial data efficiently, ensuring accurate reporting and streamlined operations. + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `client_id` | `string` | OAuth Client ID. | | +| `client_secret` | `string` | OAuth Client Secret. | | +| `refresh_token` | `string` | OAuth Refresh Token. | | +| `data_center` | `string` | Data Center. The domain suffix for the Zoho Expense API based on your data center location (e.g., `com`, `in`, `jp` etc.) | `com` | + + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| users | user_id | DefaultPaginator | ✅ | ❌ | +| trips | trip_id | DefaultPaginator | ✅ | ❌ | +| expense_reports | report_id | DefaultPaginator | ✅ | ❌ | +| projects | | DefaultPaginator | ✅ | ❌ | +| customers | contact_id | DefaultPaginator | ✅ | ❌ | +| organizations | organization_id | DefaultPaginator | ✅ | ❌ | +| expense_categories | category_id | DefaultPaginator | ✅ | ❌ | +| currencies | currency_id | DefaultPaginator | ✅ | ❌ | +| taxes | tax_id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.4 | 2024-12-28 | [50831](https://github.com/airbytehq/airbyte/pull/50831) | Update dependencies | +| 0.0.3 | 2024-12-21 | [50385](https://github.com/airbytehq/airbyte/pull/50385) | Update dependencies | +| 0.0.2 | 2024-12-14 | [49453](https://github.com/airbytehq/airbyte/pull/49453) | Update dependencies | +| 0.0.1 | 2024-10-26 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | + +
diff --git a/docs/integrations/sources/zoho-inventory.md b/docs/integrations/sources/zoho-inventory.md index 94837882a3b1..555db0c16111 100644 --- a/docs/integrations/sources/zoho-inventory.md +++ b/docs/integrations/sources/zoho-inventory.md @@ -35,6 +35,9 @@ The Zoho Inventory connector enables seamless data synchronization between Zoho | Version | Date | Pull Request | Subject | |------------------|-------------------|--------------|----------------| +| 0.0.6 | 2024-12-28 | [50834](https://github.com/airbytehq/airbyte/pull/50834) | Update dependencies | +| 0.0.5 | 2024-12-21 | [50389](https://github.com/airbytehq/airbyte/pull/50389) | Update dependencies | +| 0.0.4 | 2024-12-14 | [49448](https://github.com/airbytehq/airbyte/pull/49448) | Update dependencies | | 0.0.3 | 2024-10-29 | [47862](https://github.com/airbytehq/airbyte/pull/47862) | Update dependencies | | 0.0.2 | 2024-10-28 | [47605](https://github.com/airbytehq/airbyte/pull/47605) | Update dependencies | | 0.0.1 | 2024-10-19 | | Initial release by [@bishalbera](https://github.com/bishalbera) via Connector Builder | diff --git a/docs/integrations/sources/zoho-invoice.md b/docs/integrations/sources/zoho-invoice.md new file mode 100644 index 000000000000..5ca9f081912b --- /dev/null +++ b/docs/integrations/sources/zoho-invoice.md @@ -0,0 +1,41 @@ +# Zoho Invoice +Zoho invoice is an invoicing software used by businesses. +With this connector we can extract data from various streams such as items , contacts and invoices streams. +Docs : https://www.zoho.com/invoice/api/v3/introduction/#overview + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `client_id` | `string` | Client ID. | | +| `client_secret` | `string` | Client secret. | | +| `client_refresh_token` | `string` | Refresh token. | | +| `organization_id` | `string` | Organization ID. TO be provided if a user belongs to multiple organizations | | +| `region` | `string` | Region. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| items | item_id | DefaultPaginator | ✅ | ❌ | +| users | | DefaultPaginator | ✅ | ❌ | +| contacts | contact_id | DefaultPaginator | ✅ | ❌ | +| invoices | invoice_id | DefaultPaginator | ✅ | ❌ | +| recurring_invoices | recurring_invoice_id | DefaultPaginator | ✅ | ❌ | +| customer_payments | payment_id | DefaultPaginator | ✅ | ❌ | +| credit notes | creditnote_id | DefaultPaginator | ✅ | ❌ | +| expenses | expense_id | DefaultPaginator | ✅ | ❌ | +| taxes | tax_id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.4 | 2024-12-28 | [50828](https://github.com/airbytehq/airbyte/pull/50828) | Update dependencies | +| 0.0.3 | 2024-12-21 | [50393](https://github.com/airbytehq/airbyte/pull/50393) | Update dependencies | +| 0.0.2 | 2024-12-14 | [49444](https://github.com/airbytehq/airbyte/pull/49444) | Update dependencies | +| 0.0.1 | 2024-11-05 | | Initial release by [@ombhardwajj](https://github.com/ombhardwajj) via Connector Builder | + +
diff --git a/docs/integrations/sources/zonka-feedback.md b/docs/integrations/sources/zonka-feedback.md new file mode 100644 index 000000000000..e8c9deb1b220 --- /dev/null +++ b/docs/integrations/sources/zonka-feedback.md @@ -0,0 +1,40 @@ +# Zonka Feedback +This is the Zonka Feedback source that ingests data from the Zonka API. + +Zonka Feedback simplifies CX, allowing you to start meaningful two-way conversations with customers via powerful surveys. Design stunning surveys in minutes, gather data from all touchpoints, understand customers better with AI analytics & close the feedback loop — all within one powerful platform https://www.zonkafeedback.com/ + +To use this source, you must first create an account. Once logged in, click on Settings -> Developers -> API & Data Center. Note down your Data center and generate your auth token. + +For more information about the API visit https://apidocs.zonkafeedback.com/#intro + +## Configuration + +| Input | Type | Description | Default Value | +|-------|------|-------------|---------------| +| `dc_id` | `string` | Data Center ID. The identifier for the data center, such as 'us1' or 'e' for EU. | | +| `auth_token` | `string` | Auth Token. Auth token to use. Generate it by navigating to Company Settings > Developers > API in your Zonka Feedback account. | | + +## Streams +| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental | +|-------------|-------------|------------|---------------------|----------------------| +| responses | id | DefaultPaginator | ✅ | ❌ | +| workspaces | id | DefaultPaginator | ✅ | ❌ | +| surveys | id | DefaultPaginator | ✅ | ❌ | +| contacts | emailAddress | DefaultPaginator | ✅ | ❌ | +| tasks | id | DefaultPaginator | ✅ | ❌ | +| users | id | DefaultPaginator | ✅ | ❌ | +| locations | id | DefaultPaginator | ✅ | ❌ | + +## Changelog + +
+ Expand to review + +| Version | Date | Pull Request | Subject | +|------------------|-------------------|--------------|----------------| +| 0.0.4 | 2024-12-28 | [50829](https://github.com/airbytehq/airbyte/pull/50829) | Update dependencies | +| 0.0.3 | 2024-12-21 | [50388](https://github.com/airbytehq/airbyte/pull/50388) | Update dependencies | +| 0.0.2 | 2024-12-14 | [49454](https://github.com/airbytehq/airbyte/pull/49454) | Update dependencies | +| 0.0.1 | 2024-10-29 | | Initial release by [@aazam-gh](https://github.com/aazam-gh) via Connector Builder | + +
diff --git a/docs/integrations/sources/zoom.md b/docs/integrations/sources/zoom.md index cbd10a9738af..991b3cfdcdb4 100644 --- a/docs/integrations/sources/zoom.md +++ b/docs/integrations/sources/zoom.md @@ -71,6 +71,10 @@ JWT Tokens are deprecated, only Server-to-Server works now. [link to Zoom](https | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :--------------------------------------------------- | +| 1.2.3 | 2024-12-28 | [50835](https://github.com/airbytehq/airbyte/pull/50835) | Update dependencies | +| 1.2.2 | 2024-12-21 | [50394](https://github.com/airbytehq/airbyte/pull/50394) | Update dependencies | +| 1.2.1 | 2024-12-14 | [49445](https://github.com/airbytehq/airbyte/pull/49445) | Update dependencies | +| 1.2.0 | 2024-10-29 | [47299](https://github.com/airbytehq/airbyte/pull/47299) | Migrate to manifest only format | | 1.1.22 | 2024-10-29 | [47755](https://github.com/airbytehq/airbyte/pull/47755) | Update dependencies | | 1.1.21 | 2024-10-28 | [47094](https://github.com/airbytehq/airbyte/pull/47094) | Update dependencies | | 1.1.20 | 2024-10-12 | [46824](https://github.com/airbytehq/airbyte/pull/46824) | Update dependencies | diff --git a/docs/managing-airbyte/assets/connector-version-banner.png b/docs/managing-airbyte/assets/connector-version-banner.png deleted file mode 100644 index abdb78b643ac..000000000000 Binary files a/docs/managing-airbyte/assets/connector-version-banner.png and /dev/null differ diff --git a/docs/managing-airbyte/connector-updates.md b/docs/managing-airbyte/connector-updates.md index 4d5394dec329..c586fa2a631e 100644 --- a/docs/managing-airbyte/connector-updates.md +++ b/docs/managing-airbyte/connector-updates.md @@ -6,21 +6,20 @@ products: oss-community, oss-enterprise While maintaining an Airbyte instance, you'll need to manage connector updates. These are essential for improved functionality, reliability, and compatibility over time. Our team and community contributors are dedicated to maintaining up-to-date connectors. Reasons for updates can be broadly categorized into bug fixes, new features, and changes that impact the user experience or the functionality of the connector. -The issue of compatibility is important in maintaining connectors because as various APIs and databases you're syncing with Airbyte evolve over time, we must review the connectors for compatibility with those changes. Sometimes, this kind of update introduces a breaking change. Without making the changes necessary for an update of this type, your connection will eventually stop working because it will be incompatible with the source or destination API. +As various APIs and databases you're syncing with Airbyte evolve over time, we must review the connectors for compatibility with those changes. Sometimes, this kind of update introduces a notable change that may cause a connection to stop succeeding or your schema to change. Without your review of the changes, your connection may eventually stop working because it will become incompatible with the source or destination API. This guide helps you understand the types of updates you may see, their impact on your Airbyte environment, and the actions you may need to take in response to certain types of updates. ## Understanding Connector Versions To manage connection updates effectively, it's important to understand versioning and how to interpret the changelog entries. -Every connector in Airbyte's catalog follows semantic versioning ([semver](https://semver.org/)) -Major.Minor.Patch (e.g., 1.2.5) +Connectors in Airbyte's catalog generally follow semantic versioning ([semver](https://semver.org/)) Major.Minor.Patch (e.g., 1.2.5) A connector reaching version 1.0 is considered mature and comes with semver guarantees. * **Patch updates (1.0.x):** These typically contain bug fixes and small improvements that won't affect your existing configurations. * **Minor updates (1.x.0):** These might introduce new features like streams or properties, but they are designed to be fully backward compatible with your existing setup. -* **Major updates (x.0.0):** These are significant changes that may require you to adjust your configurations. We'll discuss this in more detail below. +* **Major updates (x.0.0):** These are significant changes that may require your review. We'll discuss this in more detail below. Each connector's changelog details its update history. You can find it in the [connector catalog](../integrations/) at the end of each individual connector's entry. @@ -30,40 +29,35 @@ Each connector's changelog details its update history. You can find it in the [c ## How Airbyte Handles Connector Updates ### Airbyte Cloud -**Minor and Patch Updates:** These are applied automatically and immediately to your instance. You don't need to take any action. +**Minor and Patch Versions:** These are applied automatically and immediately to your instance. You don't need to take any action. -**Major Updates:** These are opt-in during a specified timeframe to give you a window to prepare for the change. Airbyte will alert you of a new major version that includes a breaking change, but continue to sync until the cutoff date for upgrade. If you choose not to opt-in by the deadline, any syncs using the affected connector will be paused to prevent compatibility issues. Examples of major version changes are listed in our [breaking change documentation]./using-airbyte/schema-change-management#resolving-breaking-changes) - -Updates involving a breaking change will be called out in the UI. The example below shows a prompt that you might see if a connector has passed its cutoff date for upgrade. - -![Upgrade Path](assets/connector-version-banner.png) +**Major Versions:** A major version will include notable changes that affect your schema or sync success. We will notify you ahead of time to give you a window to prepare for the change. At the end of the window, we will automatically upgrade your connector to ensure you receive the latest updates. Examples of major version changes are shared in our [breaking change documentation](./using-airbyte/schema-change-management#major-connector-version-upgrades). ## Airbyte Open Source (OSS) and Self-Managed Enterprise (SME) Airbyte recommends using an updated version of Airbyte when updating connections. -**All Updates (Major, Minor, Patch):** These are opt-in via the settings page. You'll see a badge in the sidebar indicating available updates. +**All Versions (Major, Minor, Patch):** These are opt-in via the settings page. You'll see a badge in the sidebar indicating available updates. -**Minor and Patch Updates:** Once you opt-in, these are applied immediately and globally to all connectors of that type in your instance. +**Minor and Patch Versions:** Once you opt-in, these are applied immediately and globally to all connectors of that type in your instance. -**Major Updates:** These require a two-step opt-in process: +**Major Versions:** These require a two-step opt-in process: 1. Opt-in to the update on the settings page. 2. While there is an option available to upgrade all connections at once, we recommend that you accept the update for each individual connection using the affected connector. This allows you to review and potentially adjust the connection settings before applying the update. -Note that in an Airbyte Open Source or Self-Managed Enterprise instance, syncs are not automatically paused. This differs from what you would see in Airbyte Cloud. Although syncs will not be paused if you miss the deadline for a major update, we recommended you update promptly to avoid potential compatibility issues. +When new major versions are released, we recommended you update promptly to avoid potential compatibility issues. ## Actions to Take in Response to Connector Updates ### Review the Changelog: -Before applying any update, carefully review the changelog to understand the changes and their potential impact on your existing connections. You can find the changelog for any connector by navigating to the bottom of the documentation for the connector and expanding the view. - +Before applying any update, carefully review the changelog to understand the changes and their potential impact on your existing connections. You can find the changelog for any connector by navigating to the bottom of the documentation for the connector and expanding the view. Major version releases will also include a migration guide. ### Plan for Major Updates: -Major updates may require you to adjust connection settings or even make changes to your data pipelines. Be sure to allocate time and resources for this. +Major updates may require you to adjust connection settings or even make changes to your data pipelines. Be sure to allocate time and resources for this. Use the migration guide to ensure your transition process goes smoothly. :::info -Important Note: Airbyte provides tooling that guarantees safe connector version bumps and enforces automated version bumps for minor and patch updates. You will always need to manually update for major version bumps. +Airbyte provides tooling that guarantees safe connector version bumps and enforces automated version bumps for minor and patch updates. You will always need to manually update for major version bumps. ::: \ No newline at end of file diff --git a/docs/operator-guides/configuring-airbyte.md b/docs/operator-guides/configuring-airbyte.md index fe330962909f..f2cb9671a4ef 100644 --- a/docs/operator-guides/configuring-airbyte.md +++ b/docs/operator-guides/configuring-airbyte.md @@ -52,7 +52,7 @@ The following variables are relevant to both Docker and Kubernetes. 2. `SECRET_STORE_GCP_PROJECT_ID` - Defines the GCP Project to store secrets in. Alpha support. 3. `SECRET_STORE_GCP_CREDENTIALS` - Defines the JSON credentials used to read/write Airbyte Configuration to Google Secret Manager. These credentials must have Secret Manager Read/Write access. Alpha support. 4. `VAULT_ADDRESS` - Defines the vault address to read/write Airbyte Configuration to Hashicorp Vault. Alpha Support. -5. `VAULT_PREFIX` - Defines the vault path prefix. Empty by default. Alpha Support. +5. `VAULT_PREFIX` - Defines the vault path prefix. Should follow the format `//`, for example `kv/airbyte/` or `secret/airbyte/`. Empty by default. Alpha Support. 6. `VAULT_AUTH_TOKEN` - The token used for vault authentication. Alpha Support. 7. `VAULT_AUTH_METHOD` - How vault will preform authentication. Currently, only supports Token auth. Defaults to token. Alpha Support. 8. `AWS_ACCESS_KEY` - Defines the aws_access_key_id from the AWS credentials to use for AWS Secret Manager. diff --git a/docs/operator-guides/configuring-connector-resources.md b/docs/operator-guides/configuring-connector-resources.md index 9fffb77f92fb..466910d1395e 100644 --- a/docs/operator-guides/configuring-connector-resources.md +++ b/docs/operator-guides/configuring-connector-resources.md @@ -4,7 +4,7 @@ products: oss-* # Configuring Connector Resources -As noted in [Workers & Jobs](../understanding-airbyte/jobs.md), there are four different types of jobs. +There are four different types of jobs—SYNC, CHECK, DISCOVER and SPEC. Although it is possible to configure resources for all four jobs, we focus on Sync jobs as it is the most frequently run job. @@ -64,14 +64,11 @@ Airbyte logs the resource requirements as part of the job logs as containers are If a job is running out-of-memory, simply navigate to the Job in the UI, and look for the log to confirm the right configuration is being detected. -On Docker, the log will look something like this: - -``` -Creating docker container = destination-e2e-test-write-39-0-vnqtl with resources io.airbyte.config.ResourceRequirements@1d86d7c9[cpuRequest=,cpuLimit=,memoryRequest=200Mi,memoryLimit=200Mi] -``` - On Kubernetes, the log will look something like this: ``` -2022-08-12 01:22:20 INFO i.a.w.p.KubeProcessFactory(create):100 - Attempting to start pod = source-intercom-check-480195-0-abvnr for airbyte/source-intercom:0.1.24 with resources io.airbyte.config.ResourceRequirements@11cc9fb9[cpuRequest=2,cpuLimit=2,memoryRequest=200Mi,memoryLimit=200Mi] +2024-10-28 23:58:10 platform > Launching replication pod: replication-job-20154943-attempt-0 with containers: +2024-10-28 23:58:10 platform > [source] image: airbyte/source-sftp:1.2.0-dev.54744ff04b resources: ResourceRequirements(claims=[], limits={memory=2Gi, ephemeral-storage=5G, cpu=1}, requests={memory=1Gi, ephemeral-storage=5G, cpu=0.5}, additionalProperties={}) +2024-10-28 23:58:10 platform > [destination] image: airbyte/destination-s3:1.4.0-dev.6b9d2e4595 resources: ResourceRequirements(claims=[], limits={memory=2Gi, cpu=1}, requests={memory=2Gi, cpu=0.5}, additionalProperties={}) +2024-10-28 23:58:10 platform > [orchestrator] image: airbyte/container-orchestrator:build-256f73c6c2-20488-master resources: ResourceRequirements(claims=[], limits={memory=2Gi, cpu=1}, requests={memory=2Gi, cpu=1}, additionalProperties={}) ``` diff --git a/docs/operator-guides/scaling-airbyte.md b/docs/operator-guides/scaling-airbyte.md index 9d70a0c28cd4..6d8c2b2b243f 100644 --- a/docs/operator-guides/scaling-airbyte.md +++ b/docs/operator-guides/scaling-airbyte.md @@ -12,11 +12,11 @@ As a reference point, the typical Airbyte user has 5 - 20 connectors and 10 - 10 ## What To Scale -[Workers](../understanding-airbyte/jobs.md) do all the heavy lifting within Airbyte. A worker is responsible for executing Airbyte operations \(e.g. Discover, Read, Sync etc\), and is created on demand whenever these operations are requested. Thus, every job has a corresponding worker executing its work. +[Workloads](../understanding-airbyte/jobs.md) do all the heavy lifting within Airbyte. The workload system is responsible for launching the pods that execute Airbyte operations \(e.g. Discover, Read, Sync etc\). -How a worker executes work depends on the Airbyte deployment. In the Docker deployment, an Airbyte worker spins up at least one Docker container. In the Kubernetes deployment, an Airbyte worker will create at least one Kubernetes pod. The created resource \(Docker container or Kubernetes pod\) does all the actual work. +The workload launcher will create one Kubernetes pod. The connector and sidecar images then do all the actual work. -Thus, scaling Airbyte is a matter of ensuring that the Docker container or Kubernetes Pod running the jobs has sufficient resources to execute its work. +Thus, scaling Airbyte is a matter of ensuring that the Kubernetes cluster Airbyte runs on has sufficient resources to schedule its various job pods. Jobs-wise, we are mainly concerned with Sync jobs when thinking about scale. Sync jobs sync data from sources to destinations and are the majority of jobs run. Sync jobs use two workers. One worker reads from the source; the other worker writes to the destination. @@ -30,7 +30,7 @@ As mentioned above, we are mainly concerned with scaling Sync jobs. Within a Syn This is because the Source worker reads up to 10,000 records in memory. This can present problems for database sources with tables that have large row sizes. e.g. a table with an average row size of 0.5MBs will require 0.5 \* 10000 / 1000 = 5GBs of RAM. See [this issue](https://github.com/airbytehq/airbyte/issues/3439) for more information. -Our Java connectors currently follow Java's default behaviour with container memory and will only use up to 1/4 of the host's allocated memory. e.g. On a Docker agent with 8GBs of RAM configured, a Java connector limits itself to 2Gbs of RAM and will see Out-of-Memory exceptions if this goes higher. The same applies to Kubernetes pods. +Our Java connectors currently follow Java's default behaviour with container memory and will only use up to 1/4 of the host's allocated memory. e.g. On a Kubernetes cluster with 8GBs of RAM configured, a Java connector limits itself to 2Gbs of RAM and will see Out-of-Memory exceptions if this goes higher. You may want to customize this by setting `JOB_MAIN_CONTAINER_MEMORY_REQUEST` and `JOB_MAIN_CONTAINER_MEMORY_LIMIT` environment variables to custom values. Note that all Source database connectors are Java connectors. This means that users currently need to over-specify memory resource for Java connectors. @@ -41,7 +41,7 @@ Airbyte uses backpressure to try to read the minimal amount of logs required. In However, disk space might become an issue for the following reasons: -1. Long-running syncs can produce a fair amount of logs from the Docker agent and Airbyte on Docker deployments. Some work has been done to minimize accidental logging, so this should no longer be an acute problem, but is still an open issue. +1. Long-running syncs can produce a fair amount of logs. Some work has been done to minimize accidental logging, so this should no longer be an acute problem, but is still an open issue. 2. Although Airbyte connector images aren't massive, they aren't exactly small either. The typical connector image is ~300MB. An Airbyte deployment with multiple connectors can easily use up to 10GBs of disk space. Because of this, we recommend allocating a minimum of 30GBs of disk space per node. Since storage is on the cheaper side, we'd recommend you be safe than sorry, so err on the side of over-provisioning. @@ -52,12 +52,10 @@ Users running Airbyte Kubernetes also have to make sure the Kubernetes cluster c To be safe, make sure the Kubernetes cluster can schedule up to `2 x ` pods at once. This is the worse case estimate, and most users should be fine with `2 x ` as a rule of thumb. -This is a **non-issue** for users running Airbyte Docker. - ### Temporal DB Temporal maintains multiple idle connections. By the default value is `20` and you may want to lower or increase this number. One issue we noticed is -that temporal creates multiple pools and the number specified in the `SQL_MAX_IDLE_CONNS` environment variable of the `docker.compose.yaml` file +that temporal creates multiple pools and the number specified in the `SQL_MAX_IDLE_CONNS` environment variable and might end up allowing 4-5 times more connections than expected. If you want to increase the amount of allowed idle connections, you will also need to increase `SQL_MAX_CONNS` as well because `SQL_MAX_IDLE_CONNS` diff --git a/docs/operator-guides/using-custom-connectors.md b/docs/operator-guides/using-custom-connectors.md index 14076e4bd2f7..c2da84248bd5 100644 --- a/docs/operator-guides/using-custom-connectors.md +++ b/docs/operator-guides/using-custom-connectors.md @@ -3,6 +3,8 @@ products: oss-* sidebar_label: Uploading custom connectors --- +import ContainerProviders from '@site/static/_docker_image_registries.md'; + # Uploading Docker-based custom connectors :::info @@ -25,13 +27,7 @@ Airbyte needs to pull its Docker images from a remote Docker registry to consume You should host your custom connectors image on a private Docker registry. Here are some resources to create a private Docker registry, in case your organization does not already have one: -| Cloud provider | Service name | Documentation | -| -------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Google Cloud | Artifact Registry | [Quickstart](https://cloud.google.com/artifact-registry/docs/docker/quickstart) | -| AWS | Amazon ECR | [Getting started with Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-console.html) | -| Azure | Container Registry | [Quickstart](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-portal#:~:text=Azure%20Container%20Registry%20is%20a,container%20images%20and%20related%20artifacts.&text=Then%2C%20use%20Docker%20commands%20to,the%20image%20from%20your%20registry.) | -| DockerHub | Repositories | [DockerHub Quickstart](https://docs.docker.com/docker-hub/) | -| Self hosted | Open-source Docker Registry | [Deploy a registry server](https://docs.docker.com/registry/deploying/) | + ## 2. Authenticate to your private Docker registry diff --git a/docs/operator-guides/using-kestra-plugin.md b/docs/operator-guides/using-kestra-plugin.md index d835b92a1449..09b3faec3518 100644 --- a/docs/operator-guides/using-kestra-plugin.md +++ b/docs/operator-guides/using-kestra-plugin.md @@ -43,17 +43,16 @@ Kestra UI provides a wide range of Blueprints to help you get started. Navigate to Blueprints. Then type "Airbyte" in the search bar to find the desired integration. This way, you can easily accomplish fairly standardized data orchestration tasks, such as the following: -1. [Run a single Airbyte sync](https://demo.kestra.io/ui/blueprints/community/61) on a schedule -2. [Run multiple Airbyte syncs in parallel](https://demo.kestra.io/ui/blueprints/community/18) -3. [Run multiple Airbyte syncs in parallel, then clone a Git repository with dbt code and trigger dbt CLI commands](https://demo.kestra.io/ui/blueprints/community/30) -4. [Run a single Airbyte Cloud sync](https://demo.kestra.io/ui/blueprints/community/62) on a schedule -5. [Run multiple Airbyte Cloud syncs in parallel](https://demo.kestra.io/ui/blueprints/community/63) -6. [Run multiple Airbyte Cloud syncs in parallel, then clone a Git repository with dbt code and trigger dbt CLI commands](https://demo.kestra.io/ui/blueprints/community/64) -7. [Run multiple Airbyte Cloud syncs in parallel, then run a dbt Cloud job](https://demo.kestra.io/ui/blueprints/community/31) +1. [Run a single Airbyte sync](https://kestra.io/blueprints/airbyte-sync) on a schedule +2. [Run multiple Airbyte syncs in parallel](https://kestra.io/blueprints/airbyte-sync-parallel) +3. [Run multiple Airbyte syncs in parallel, then clone a Git repository with dbt code and trigger dbt CLI commands](https://kestra.io/blueprints/airbyte-sync-parallel-with-dbt) +4. [Run a single Airbyte Cloud sync](https://kestra.io/blueprints/airbyte-cloud-sync) on a schedule +5. [Run multiple Airbyte Cloud syncs in parallel, then clone a Git repository with dbt code and trigger dbt CLI commands](https://kestra.io/blueprints/airbyte-cloud-dbt) +6. [Run multiple Airbyte Cloud syncs in parallel, then run a dbt Cloud job](https://kestra.io/blueprints/airbyte-cloud-dbt-cloud) Select a blueprint matching your use case and click "Use". -![airbyte_kestra_UI](../.gitbook/assets/airbyte_kestra_2.gif) +![airbyte_kestra_blueprints](../.gitbook/assets/airbyte_kestra_2.png) Then, within the editor, adjust the connection ID and task names and click "Save". Finally, trigger your flow. @@ -62,12 +61,12 @@ Then, within the editor, adjust the connection ID and task names and click "Save Here is an example flow that triggers multiple Airbyte connections in parallel to sync data for multiple **Pokémon**. ```yaml -id: airbyteSyncs -namespace: dev +id: airbyte_syncs +namespace: company.team description: Gotta catch ‘em all! tasks: - - id: data-ingestion + - id: data_ingestion type: io.kestra.core.tasks.flows.Parallel tasks: - id: charizard @@ -84,11 +83,11 @@ taskDefaults: - type: io.kestra.plugin.airbyte.connections.Sync values: url: http://host.docker.internal:8000/ - username: "{{envs.airbyte_username}}" - password: "{{envs.airbyte_password}}" + username: "{{ secret('AIRBYTE_USERNAME') }}" + password: "{{ secret('AIRBYTE_PASSWORD') }}" triggers: - - id: everyMinute + - id: every_minute type: io.kestra.core.models.triggers.types.Schedule cron: "*/1 * * * *" ``` diff --git a/docs/readme.md b/docs/readme.md index 654aa22074e9..87e02331b175 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -16,7 +16,7 @@ displayed_sidebar: docs Today, teams and organizations require efficient and timely data access to an ever-growing list of data sources. In-house data pipelines are brittle and costly to build and maintain. Airbyte's unique open-source approach enables your data stack to adapt as your data needs evolve. -- **Wide connector availability:** Airbyte’s connector catalog comes “out-of-the-box” with over 350 pre-built connectors. These connectors can be used to start replicating data from a source to a destination in just a few minutes. +- **Wide connector availability:** Airbyte’s connector catalog comes “out-of-the-box” with over 500 pre-built connectors. These connectors can be used to start replicating data from a source to a destination in just a few minutes. - **Long-tail connector coverage:** You can easily extend Airbyte’s functionality to support your custom use cases through Airbyte's [No-Code Connector Builder](./connector-development/connector-builder-ui/overview). - **Robust platform** provides horizontal scaling required for large-scale data movement operations, available as [Cloud-managed](https://airbyte.com/product/airbyte-cloud) or [Self-managed](https://airbyte.com/product/airbyte-enterprise). @@ -32,7 +32,7 @@ Airbyte is suitable for a wide range of data integration use cases, including AI - + diff --git a/docs/release_notes/assets/1.2-file-transfers.png b/docs/release_notes/assets/1.2-file-transfers.png new file mode 100644 index 000000000000..7dd6fa63b25b Binary files /dev/null and b/docs/release_notes/assets/1.2-file-transfers.png differ diff --git a/docs/release_notes/assets/1.2-rbac-runner.png b/docs/release_notes/assets/1.2-rbac-runner.png new file mode 100644 index 000000000000..1df7c01bf598 Binary files /dev/null and b/docs/release_notes/assets/1.2-rbac-runner.png differ diff --git a/docs/release_notes/assets/1.2-xml-builder.png b/docs/release_notes/assets/1.2-xml-builder.png new file mode 100644 index 000000000000..b9a6ebd2545f Binary files /dev/null and b/docs/release_notes/assets/1.2-xml-builder.png differ diff --git a/docs/release_notes/assets/1.3-improved-log-viewer.png b/docs/release_notes/assets/1.3-improved-log-viewer.png new file mode 100644 index 000000000000..b36060bd73aa Binary files /dev/null and b/docs/release_notes/assets/1.3-improved-log-viewer.png differ diff --git a/docs/release_notes/assets/1.3-mappers-api-reference.png b/docs/release_notes/assets/1.3-mappers-api-reference.png new file mode 100644 index 000000000000..a83ec8e078d4 Binary files /dev/null and b/docs/release_notes/assets/1.3-mappers-api-reference.png differ diff --git a/docs/release_notes/assets/1.3-webhook-schema-notifications.png b/docs/release_notes/assets/1.3-webhook-schema-notifications.png new file mode 100644 index 000000000000..4d7562e7e249 Binary files /dev/null and b/docs/release_notes/assets/1.3-webhook-schema-notifications.png differ diff --git a/docs/release_notes/v-1.2.md b/docs/release_notes/v-1.2.md new file mode 100644 index 000000000000..0634b4779859 --- /dev/null +++ b/docs/release_notes/v-1.2.md @@ -0,0 +1,30 @@ +# Airbyte 1.2.0 + +Happy Halloween! We are excited to release the following set of improvements and changes. + +## 🚀 Platform Changes + +- **File Transfers**: Airbyte now supports transfering unstructured text data, non-text data and compressed files. This capability is in early access, and currently only available for moving data from the "SFTP Bulk" source to the "S3" destination. Support in the "S3" source is coming soon. File transfers allow you to copy raw files in Airbyte without parsing their contents. Bits are copied into the destination exactly as they appeared in the source. This is recommended for use with unstructured text data, non-text and compressed files. This is an entirely new way of moving data through Airbyte, as all pre-existing data movement methods involved parsing individual records. + +![file-transfers-sftp-bulk-source](./assets/1.2-file-transfers.png) + +- **Custom Image Registry Support**: Introduces support for specifying a custom Docker registry from which all platform images are pulled. This should simplify helm chart configurations for users who require images to be pulled from internally approved image repositories. Configuring the following will prefix all docker images with `my-registry.foo.com`. The value provided in the `registry` field must have a trailing slash: + +```yaml +global: + image: + registry: my-registry.foo.com/ +``` + +- **XML Support in the Connector Builder**: Airbyte now supports custom API connectors built via the Airbyte Connector Builder which return responses as XML format. + +![xml-builder](./assets/1.2-xml-builder.png) + +## 🚀 Self-Managed Enterprise Changes + +- **Runner RBAC Role**: Users provisioned with the 'Runner' role are able to start or stop syncs, and run backfills for individual connections (in the workspaces where they've been granted Runner permissions). Outside of these explicit tasks, users with the 'Runner' role have an entirely read-only experience (Self-Managed Enterprise only). + +![rbac-1.2](./assets/1.2-rbac-runner.png) + +- **Self-Managed Diagnostics**: Diagnostics have been expanded to include deployment statistics. Diagnostics can be downloaded through the Organization Settings page. This exports a .zip file which can be easily shared with Airbyte Support (Self-Managed Enterprise only). +- **Removing SSO Users**: You may now remove SSO users from your Airbyte Organization. This removes them from the list of Organization Members. \ No newline at end of file diff --git a/docs/release_notes/v-1.3.md b/docs/release_notes/v-1.3.md new file mode 100644 index 000000000000..447683e663a0 --- /dev/null +++ b/docs/release_notes/v-1.3.md @@ -0,0 +1,22 @@ +# Airbyte 1.3.0 + +It's already December! We are excited to release the following set of improvements and changes. + +## 🚀 Platform Changes + +- **Improved Log Viewer and Filtering**: You can now quickly filter to error or warning logs when needed, as well as by log source - such as the source connector, destination connector, or platform. Together, this allows you to quickly diagnose issues with Airbyte connections if they arise, reducing time to resolution on issues. + +![Improved Log Viewer](./assets/1.3-improved-log-viewer.png) + +- **OpenShift Support**: Starting today, Airbyte supports deployments to OpenShift. This is the culmination of a journey over much of the past year: we've updated our platform and connectors to be rootless, we've improved pod to pod communication within our platform, and made a wide number of security improvements. To succeed, the user running helm deployment commands needs to be a `cluster-admin` user. Your Kubernetes namespace will also require the following annotations to ensure that all of the Airbyte resources run as UID 1000 and GID 1000. If you run into any edge cases or issues deploying to OpenShift, as always, please let us know by opening a GitHub issue. + +```yaml +openshift.io/sa.scc.supplemental-groups: 1000/1 +openshift.io/sa.scc.uid-range: 1000/1 +``` + +## 🚀 Self-Managed Enterprise Changes + +- **Compliance Mappers in Airbyte API**: Airbyte Self-Managed Enterprise now supports field hashing, field encryption (with self-managed encryption keys), field renaming and row filtering for connections from a common interface available in the Airbyte API. This functionality is coming soon to the Airbyte UI. To get started, see our [API documentation](https://reference.airbyte.com/reference/patchconnection). + +![Mappers API Example](./assets/1.3-mappers-api-reference.png) diff --git a/docs/understanding-airbyte/high-level-view.md b/docs/understanding-airbyte/high-level-view.md index d8b6e9e784f3..990d566fbca1 100644 --- a/docs/understanding-airbyte/high-level-view.md +++ b/docs/understanding-airbyte/high-level-view.md @@ -22,7 +22,7 @@ flowchart LR S[fa:fa-server Config API Server] D[(fa:fa-table Config & Jobs)] L[(fa:fa-server Launcher)] - O[(fa:fa-superpowers Orchestrator)] + OP[(fa:fa-superpowers Operation pod)] Q[(fa:fa-superpowers Queue)] T(fa:fa-calendar Temporal/Scheduler) W2[1..n Airbyte Workers] @@ -36,23 +36,21 @@ flowchart LR W2 -->|creates job| WL WL -->|queues workload| Q Q -->|reads from| L - L -->|launches| O - O -->|launches/reads from| Source - O -->|launches/reads from/writes to| Destination + L -->|launches| OP O -->|reports status to| WL ``` -- **Web App/UI** [`airbyte-webapp`, `airbyte-proxy`]: An easy-to-use graphical interface for interacting with the Airbyte API. -- **Config API Server** [`airbyte-server`, `airbyte-server-api`]: Handles connection between UI and API. Airbyte's main control plane. All operations in Airbyte such as creating sources, destinations, connections, managing configurations, etc.. are configured and invoked from the API. -- **Database Config & Jobs** [`airbyte-db`]: Stores all the connections information \(credentials, frequency...\). -- **Temporal Service** [`airbyte-temporal`]: Manages the task queue and workflows. -- **Worker** [`airbyte-worker`]: The worker connects to a source connector, pulls the data and writes it to a destination. -- **Workload API** [`airbyte-workload-api-server`]: Manages workloads, Airbyte's internal job abstraction. -- **Launcher** [`airbyte-workload-launcher`]: Launches workloads. +- **Web App/UI** [`airbyte-webapp`]: An easy-to-use graphical interface for interacting with the Airbyte Server. +- **Config API Server** [`airbyte-server`, `airbyte-server-api`]: Airbyte's main controller. All operations in Airbyte such as creating sources, destinations, connections, managing configurations, etc.. are configured and invoked from the API. +- **Database Config & Jobs** [`airbyte-db`]: Stores all the configuration \(credentials, frequency...\) and job history. +- **Temporal Service** [`airbyte-temporal`]: Manages the scheduling and sequencing task queues and workflows. +- **Worker** [`airbyte-worker`]: Reads from the task queues and executes the connection scheduling and sequencing logic, making calls to the workload API. +- **Workload API** [`airbyte-workload-api-server`]: The HTTP interface for enqueuing workloads — the discrete pods that run the connector operations. +- **Launcher** [`airbyte-workload-launcher`]: Consumes events from the workload API and interfaces with k8s to launch workloads. The diagram shows the steady-state operation of Airbyte, there are components not described you'll see in your deployment: -- **Cron** [`airbyte-cron`]: Clean the server and sync logs (when using local logs). Regularly updates connector definitions and sweeps old workloads. +- **Cron** [`airbyte-cron`]: Clean the server and sync logs (when using local logs). Regularly updates connector definitions and sweeps old workloads ensuring eventual consenus. - **Bootloader** [`airbyte-bootloader`]: Upgrade and Migrate the Database tables and confirm the enviroment is ready to work. This is a holistic high-level description of each component. For Airbyte deployed in Kubernetes the structure is very similar with a few changes. diff --git a/docs/understanding-airbyte/jobs.md b/docs/understanding-airbyte/jobs.md index dedf4d8814dd..8fd560646c96 100644 --- a/docs/understanding-airbyte/jobs.md +++ b/docs/understanding-airbyte/jobs.md @@ -1,15 +1,71 @@ -# Workers & Jobs +# Workloads & Jobs -In Airbyte, all interactions with connectors are run as jobs performed by a Worker. Each job has a corresponding worker: +In Airbyte, all connector operations are run as 'workloads' — a pod encapsulating the discrete invocation of one or more connectors' interface method(s) (READ, WRITE, CHECK, DISCOVER, SPEC). -- Spec worker: retrieves the specification of a connector \(the inputs needed to run this connector\) -- Check connection worker: verifies that the inputs to a connector are valid and can be used to run a sync -- Discovery worker: retrieves the schema of the source underlying a connector -- Sync worker, used to sync data between a source and destination +Generally, there are 2 types of workload pods: -Thus, there are generally 4 types of workers. +- Replication (SYNC) pods + - Calls READ on the source and WRITE on the destination docker images +- Connector Job (CHECK, DISCOVER, SPEC) pods + - Calls the specified interface method on the connector image -**Note: Workers here refers to Airbyte workers. Temporal, which Airbyte uses under the hood for scheduling, has its own worker concept. This distinction is important.** +| ![](../.gitbook/assets/replication_mono_pod.png) | ![](../.gitbook/assets/connector_pod.png) | +|:-------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------:| +| The source, destination and orchestrator all run in a single pod | The sidecar processes the output of the connector and forwards it back to the core platform | + +## Airbyte Middleware and Bookkeeping Containers + +Inside any connector operation pod, a special airbyte controlled container will run alongside the connector container(s) to process and interpret the results as well as perform necessary side effects. + +There are two types of middleware containers: +* The Container Orchestrator +* The Connector Sidecar + +#### Container Orchestrator + +An airbyte controlled container that sits between the source and destination connector containers inside a Replication Pod. + +Responsibilities: +* Hosts middleware capabilities such as scrubbing PPI, aggregating stats, transforming data, and checkpointing progress. +* Interprets and records connector operation results +* Handles miscellaneous side effects (e.g. logging, auth token refresh flows, etc. ) + +#### Connector Sidecar + +An airbyte controlled container that reads the output of a connector container inside a Connector Pod (CHECK, DISCOVER, SPEC). + +Responsibilities: +* Interprets and records connector operation results +* Handles miscellaneous side effects (e.g. logging, auth token refresh flows, etc. ) + + +## Workload launching architecture + +Workloads is Airbyte's next generation architecture. It is designed to be more scalable, reliable and maintainable than the previous Worker architecture. It performs particularly +well in low-resource environments. + +One big flaw of pre-Workloads architecture was the coupling of scheduling a job with starting a job. This complicated configuration, and created thundering herd situations for +resource-constrained environments with spiky job scheduling. + +Workloads is an Airbyte-internal job abstraction decoupling the number of running jobs (including those in queue), from the number of jobs that can be started. Jobs stay queued +until more resources are available or canceled. This allows for better back pressure and self-healing in resource constrained environments. + +Dumb workers now communicate with the Workload API Server to create a Workload instead of directly starting jobs. + +The **Workload API Server** places the job in a queue. The **Launcher** picks up the job and launches the resources needed to run the job e.g. Kuberenetes pods. It throttles +job creation based on available resources, minimising deadlock situations. + +With this set up, Airbyte now supports: +- configuring the maximum number of concurrent jobs via `MAX_CHECK_WORKERS` and `MAX_SYNC_WORKERS` environment variables.` +- configuring the maximum number of jobs that can be started at once via `` +- differentiating between job schedule time & job start time via the Workload API, though this is not exposed to the UI. + +This also unlocks future work to turn Workers asynchronous, which allows for more efficient steady-state resource usage. See +[this blogpost](https://airbyte.com/blog/introducing-workloads-how-airbyte-1-0-orchestrates-data-movement-jobs) for more detailed information. + +## Further configuring Jobs & Workloads + +Details on configuring jobs & workloads can be found [here](../operator-guides/configuring-airbyte.md). ## Sync Jobs @@ -221,131 +277,3 @@ To help illustrate what is possible, below are a couple examples of how the retr - -## Worker Responsibilities - -The worker has the following responsibilities. - -1. Handle the process lifecycle for job-related processes. This includes starting, monitoring and shutting down processes. -2. Facilitate message passing to or from various processes, if required. \(more on this [below](jobs.md#worker-types)\). -3. Handle job-relation operational work such as: - 1. Basic schema validation. - 2. Returning job output, including any error messages. \(See [Airbyte Specification](airbyte-protocol.md) to understand the output of each worker type.\) - 3. Telemetry work e.g. tracking the number and size of records within a sync. - -Conceptually, **workers contain the complexity of all non-connector-related job operations**. This lets each connector be as simple as possible. - -### Worker Types - -There are 2 flavors of workers: - -1. **Synchronous Job Worker** - Workers that interact with a single connector \(e.g. spec, check, discover\). - - The worker extracts data from the connector and reports it to the scheduler. It does this by listening to the connector's STDOUT. - These jobs are synchronous as they are part of the configuration process and need to be immediately run to provide a good user experience. These are also all lightweight operations. - -2. **Asynchronous Job Worker** - Workers that interact with 2 connectors \(e.g. sync, clear\) - - The worker passes data \(via record messages\) from the source to the destination. It does this by listening on STDOUT of the source and writing to STDIN on the destination. - These jobs are asynchronous as they are often long-running resource-intensive processes. They are decoupled from the rest of the platform to simplify development and operation. - -For more information on the schema of the messages that are passed, refer to [Airbyte Specification](airbyte-protocol.md). - -### Worker-Job Architecture - -This section will depict the worker-job architecture as discussed above. Only the 2-connector version is shown. The single connector version is the same with one side removed. - -The source process should automatically exit after passing all of its messages. Similarly, the destination process shutdowns after receiving all records. Each process is given a shutdown grace period. The worker forces shutdown if this is exceeded. - -```mermaid -sequenceDiagram - Worker->>Source: docker run - Worker->>Destination: docker run - Source->>Worker: STDOUT - Worker->>Destination: STDIN - Worker->>Source: exit* - Worker->>Destination: exit* - Worker->>Result: json output -``` - -See the [architecture overview](high-level-view.md) for more information about workers. - -## Deployment Types - -Up to now, the term 'processes' has been used loosely. This section will describe this in more detail. - -Airbyte offers two deployment types. The underlying process implementations differ accordingly. - -1. The Docker deployment - Each process is a local process backed by a Docker container. As all processes are local, process communication is per standard unix pipes. -2. The Kubernetes deployment - Each process is a backed by a Kubernetes pod. As Kubernetes does not make process-locality guarantees, Airbyte has implemented mechanisms to hide the remote process execution. - See [this blogpost](https://airbyte.com/blog/scaling-data-pipelines-kubernetes) for more details. - -### Decoupling Worker and Job Processes - -Workers being responsible for all non-connector-related job operations means multiple jobs are operationally dependent on a single worker process. - -There are two downsides to this: - -1. Any issues to the parent worker process affects all job processes launched by the worker. -2. Unnecessary complexity of vertically scaling the worker process to deal with IO and processing requirements from multiple jobs. - -This gives us a potentially brittle system component that can be operationally tricky to manage. For example, since redeploying Airbyte terminates all worker processes, all running jobs are also terminated. - -The Container Orchestrator was introduced to solve this. - -#### Container Orchestrator - -When enabled, workers launch the Container Orchestrator process. - -The worker process delegates the [above listed responsibilities](#worker-responsibilities) to the orchestrator process. - -This decoupling introduces a new need for workers to track the orchestrator's, and the job's, state. This is done via a shared Cloud Storage store. - -Brief description of how this works, - -1. Workers constantly poll the Cloud Storage location for job state. -2. As an Orchestrator process executes, it writes status marker files to the Cloud Storage location i.e. `NOT_STARTED`, `INITIALIZING`, `RUNNING`, `SUCCESS`, `FAILURE`. -3. If the Orchestrator process runs into issues at any point, it writes a `FAILURE`. -4. If the Orchestrator process succeeds, it writes a job summary as part of the `SUCCESS` marker file. - -The Cloud Storage store is treated as the source-of-truth of execution state. - -The Container Orchestrator is only available for Airbyte Kubernetes today and automatically enabled when running the Airbyte Helm Charts deploys. - -Users running Airbyte Docker should be aware of the above pitfalls. - -## Workloads - -Workloads is Airbyte's next generation Worker architecture. It is designed to be more scalable, reliable and maintainable than the current Worker architecture. It performs particularly -well in low-resource environments. - -One big flaw of pre-Workloads architecture was the coupling of scheduling a job with starting a job. This complicated configuration, and created thundering herd situations for -resource-constrained environments with spiky job scheduling. - -Workloads is an Airbyte-internal job abstraction decoupling the number of running jobs (including those in queue), from the number of jobs that can be started. Jobs stay queued -until more resources are available or canceled. This allows for better back pressure and self-healing in resource constrained environments. - -Workers now communicate with the Workload API Server to create a Workload instead of directly starting jobs. - -The **Workload API Server** places the job in a queue. The **Launcher** picks up the job and launches the resources needed to run the job e.g. Kuberenetes pods. It throttles -job creation based on available resources, minimising deadlock situations. - -With this set up, Airbyte now supports: -- configuring the maximum number of concurrent jobs via `MAX_CHECK_WORKERS` and `MAX_SYNC_WORKERS` environment variables.` -- configuring the maximum number of jobs that can be started at once via `` -- differentiating between job schedule time & job start time via the Workload API, though this is not exposed to the UI. - -This also unlocks future work to turn Workers asynchronous, which allows for more efficient steady-state resource usage. See -[this blogpost](https://airbyte.com/blog/introducing-workloads-how-airbyte-1-0-orchestrates-data-movement-jobs) for more detailed information. - -## Configuring Jobs & Workers - -Details on configuring jobs & workers can be found [here](../operator-guides/configuring-airbyte.md). - -### Worker Parallization - -Airbyte exposes the following environment variable to change the maximum number of each type of worker allowed to run in parallel. -Tweaking these values might help you run more jobs in parallel and increase the workload of your Airbyte instance: - -- `MAX_CHECK_WORKERS`: Maximum number of _Non-Sync_ workers allowed to run in parallel. Default to **5**. -- `MAX_SYNC_WORKERS`: Maximum number of _Sync_ workers allowed to run in parallel. Defaults to **10**. diff --git a/docs/using-airbyte/core-concepts/readme.md b/docs/using-airbyte/core-concepts/readme.md index 3c633f099cc6..2d45fea90a37 100644 --- a/docs/using-airbyte/core-concepts/readme.md +++ b/docs/using-airbyte/core-concepts/readme.md @@ -81,7 +81,7 @@ For more details, see our [Namespace documentation](namespaces.md). ## Sync Mode -A sync mode governs how Airbyte reads from a source and writes to a destination. Airbyte provides several sync modes depending what you want to accomplish. The sync modes define how your data will sync and whether duplicates will exist in the dstination. +A sync mode governs how Airbyte reads from a source and writes to a destination. Airbyte provides several sync modes depending what you want to accomplish. The sync modes define how your data will sync and whether duplicates will exist in the destination. Read more about each [sync mode](/using-airbyte/core-concepts/sync-modes/README.md) and how they differ. diff --git a/docs/using-airbyte/getting-started/oss-quickstart.md b/docs/using-airbyte/getting-started/oss-quickstart.md index 827f166c4e75..6a8b99ad7423 100644 --- a/docs/using-airbyte/getting-started/oss-quickstart.md +++ b/docs/using-airbyte/getting-started/oss-quickstart.md @@ -4,364 +4,275 @@ products: oss-community import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faWindows } from "@fortawesome/free-brands-svg-icons"; # Quickstart -Airbyte Open Source is a reliable and extensible open source data pipeline. +This quickstart guides you through deploying a local instance of Airbyte Self-Managed Community, Airbyte's open source product. Setup only takes a few minutes, and you can start moving data immediately. -If you're getting started with Airbyte Cloud, you can skip ahead to moving data by [adding your first source](add-a-source.md). +## Overview -This quickstart guides you through creating a locally deployed instance of Airbyte in just minutes using `abctl` ([Airbyte Command Line Tool](https://github.com/airbytehq/abctl)). You'll be able to move data with minimal setup while you're exploring what Airbyte can do! +This quickstart shows you how to: -If you've already set up an Airbyte instance using Docker Compose and want to move to abctl, see the section on [migrating from Docker Compose](#migrating-from-docker-compose-optional). +- [Install abctl](#part-1-install-abctl) +- [Run Airbyte](#part-2-run-airbyte) +- [Set up authentication](#part-3-set-up-authentication) +- [Decide on your next steps](#whats-next) -:::tip -**When you're ready to put an Airbyte instance into production, you'll want to review our guides on deployment.** +This is intended for most people who want to manage their own Airbyte instance, but it assumes you have basic knowledge of: -For the best experience, we recommend [Deploying Airbyte on Kubernetes via Helm](../../deploying-airbyte/deploying-airbyte.md). +- Docker +- Command-line tools -On a local deployment, Airbyte's default behavior is to store connector secrets in your configured database. These secrets are stored in plain text and are not encrypted. Refer to the [Secret Management documentation](../../deploying-airbyte/integrations/secrets.md) to set up an external secrets manager. -::: +If you do not want to self-manage Airbyte, skip this guide. Sign up for an [Airbyte Cloud](https://cloud.airbyte.com/signup) trial and [start syncing data](add-a-source.md) now. -If setting up an Airbyte server does not fit your use case needs (i.e. you're using Jupyter Notebooks or iterating on an early prototype for your project) you may find the [PyAirbyte](../pyairbyte/getting-started.mdx) documentation useful. +If you want to use Python to move data, our Python library, [PyAirbyte](../pyairbyte/getting-started.mdx), might be the best fit for you. It's a good choice if you're using Jupyter Notebook or iterating on an early prototype for a large data project and don't need to run a server. -## Prerequisites +## Before you start -- To use `abctl`, you'll need to have **Docker Desktop** installed. See Docker's instructions for installation: [Mac](https://docs.docker.com/desktop/install/mac-install/), [Windows](https://docs.docker.com/desktop/install/windows-install/), [Linux](https://docs.docker.com/desktop/install/linux-install/) +Before running this quickstart, complete the following prerequisites: -## 1: Install `abctl` +1. Install Docker Desktop on your machine: [Mac](https://docs.docker.com/desktop/install/mac-install/), [Windows](https://docs.docker.com/desktop/install/windows-install/), [Linux](https://docs.docker.com/desktop/install/linux-install/). +2. Make sure you have enough computing power (see Suggested resources, below). -The easiest method for installing `abctl` for Mac and Linux users is to use the following command: +### Suggested resources {#suggested-resources} -```shell -curl -LsfS https://get.airbyte.com | bash - -``` +For best performance, run Airbyte on a machine with 4 or more CPUs and at least 8GB of memory. We also support running Airbyte with 2 CPUs and 8GM of memory in low-resource mode. This guide explains how to do both. Follow this [Github discussion](https://github.com/airbytehq/airbyte/discussions/44391) to upvote and track progress toward supporting lower resource environments. -If you would rather install `abctl` yourself, follow the instructions for your operating system: - - - - -We recommend that Mac users use Brew to install the `abctl` command. - -```bash -brew tap airbytehq/tap -brew install abctl -``` +## Part 1: Install abctl -With Brew, you can keep abctl up to date easily, by running: +abctl is Airbyte's command-line tool for deploying and managing Airbyte. -```bash -brew upgrade abctl -``` +### Install abctl the fast way (Mac, Linux) - - +1. Open a terminal and run the following command. -**1: Download the latest release of `abctl`.** + ```shell + curl -LsfS https://get.airbyte.com | bash - + ``` -Latest linux-amd64 Release -Latest linux-arm64 Release -
-
+2. If your terminal asks you to enter your password, do so. -:::info +When installation completes, you'll see `abctl install succeeded.` -
-Be sure to download the file that is compatible with your machine's processor architecture. +### Install abctl manually (Mac, Linux, Windows) -You'll see two options: `linux-amd64` and `linux-arm64` -If you're unsure which one you need, running the following command will help: +To install abctl yourself, follow the instructions for your operating system. -```bash -uname -m -``` - -- If the output is `x86_64`, you have an x86-64 processor. -- If the output is `aarch64` or something similar, you have an ARM-based processor. -
- -::: - -**2: Extract the archive** - -This will create a directory named abctl which contains the executable along with other needed files. - -```bash -tar -xvzf {name-of-file-downloaded.linux-*.tar.gz} -``` - -**3: Make the extracted executable accessible** + + -This will allow you to run `abctl` as a command +Use [Homebrew](https://brew.sh/) to install abctl. -```bash -chmod +x abctl/abctl -``` +1. Install Homebrew, if you haven't already. -**4: Add `abctl` to your PATH** +2. Run the following commands after Homebrew is installed. -This will allow you to run `abctl` from any directory in your terminal. + ```bash + brew tap airbytehq/tap + brew install abctl + ``` -```bash -sudo mv abctl /usr/local/bin -``` +3. Keep abctl up to date with Homebrew, too. -**5: Verify the installation** + ```bash + brew upgrade abctl + ``` -```bash -abctl version -``` + + -If this command prints the installed version of the Airbyte Command Line Tool, it confirm that you are now ready to manage a local Airbyte instance using `abctl`. +1. Verify your processor architecture. - - + ```bash + uname -m + ``` -**1: Download the latest release of `abctl`.** + If the output is `x86_64`, you'll download the **linux-amd64** release. If the output is `aarch64` or similar, you'll download the **linux-arm64** release. -Latest windows-amd64 Release -
-
+2. Download the file that is compatible with your machine's processor architecture -**2: Extract the archive** + Latest Linux Release -- Right click the zip file you've downloaded and select `Extract All...`, then choose a destination folder. +3. Extract the archive. This creates a directory named `abctl`, which contains the executable and other needed files. -This creates a folder called abctl containing the abctl executable and other reqired files. + ```bash + tar -xvzf {name-of-file-downloaded.linux-*.tar.gz} + ``` -**3: Add the executable to your PATH** +4. Make the extracted executable accessible. This allows you to run `abctl` as a command. -- In the "System Properties" window (you can find this by searching for "enviornment variables" in the Start menu), click the `Environment Variables` button -- Under System variables, find the path and click to `Edit` -- Click `New` and add the path to the folder you extracted the abctl files to in the previous step. -- Click `OK` to save these changes. + ```bash + chmod +x abctl/abctl + ``` -**4: Open a new Command Prompt or PowerShell window** +5. Add `abctl` to your PATH. This allows you to run `abctl` from any directory in your terminal. -This is important because changes to your PATH will only take effect in a newly opened window. + ```bash + sudo mv abctl /usr/local/bin + ``` -**5: Verify the installation** +6. Verify the installation. If this command prints the installed version of abctl, you can now use it to manage a local Airbyte instance. ```bash abctl version ``` -If this command prints the installed version of the Airbyte Command Line Tool, it confirm that you are now ready to manage a local Airbyte instance using `abctl`. -
+ -
- -:::tip -For troubleshooting assistance, visit our [deployment troubleshooting guide](../../deploying-airbyte/troubleshoot-deploy). -::: - -## 2: Run Airbyte - -Ensure that Docker Desktop is up and running. Then, with abctl installed, the following command gets Airbyte running: - -:::tip -By default, `abctl` only configures an ingress rule for the host `localhost`. If you plan to access Airbyte outside of `localhost`, you will need to specify the `--host` flag to the `local install` command, providing the FQDN of the host which is hosting Airbyte. For example, `abctl local install --host airbyte.company.example`. - -By specifying the `--host` flag, Airbyte will be accessible to both `localhost` and the FDQN passed to the `--host` flag. -::: - -``` -abctl local install -``` - -Your browser may open automatically to the Airbyte Application. If not, access it by visiting [http://localhost:8000](http://localhost:8000). - -You will be asked to enter your email address and an organization name. Your email address will be used to authenticate -to your instance of Airbyte. You will also need a password, which is randomly generated as part of the install command. -To get your password run: - -```shell -abctl local credentials -``` - -Which should output something similar to: - -```shell -Credentials: - Email: user@company.example - Password: random_password - Client-Id: 03ef466c-5558-4ca5-856b-4960ba7c161b - Client-Secret: m2UjnDO4iyBQ3IsRiy5GG3LaZWP6xs9I -``` - -Use the value in the password field to authenticate to your new Airbyte instance. +1. Verify your processor architecture. -You can set your email and password with the `credentials` command using `abctl`. To set your email you can run: + 1. Press Windows + I. -```shell -abctl local credentials --email user@company.example -``` + 2. Click **System** > **About**. -To set your password you can run: + 3. Next to **Processor**, if it says `AMD`, you'll download the **windows-amd64** release. If the output is `ARM` or similar, you'll download the **windows-arm64** release. -```shell -abctl local credentials --password new_password -``` +2. Download the latest release of `abctl`. -If you wish to configure authentication when install abctl, follow the documentation on the [Authentication Integration](../../deploying-airbyte/integrations/authentication) -page. + Latest Windows Release -As long as your Docker Desktop daemon is running in the background, you can use Airbyte by returning to [http://localhost:8000](http://localhost:8000). +3. Extract the zip file to a destination of your choice. This creates a folder containing the abctl executable and other required files. Copy the filepath because you'll need this in a moment. -If you quit Docker Desktop and want to return to your local Airbyte workspace, just start Docker Desktop again. Once Docker finishes restarting, you'll be able to access Airbyte's local installation as normal. +4. Add the executable to your `Path` environment variable. -### Suggested Resources + 1. Click **Start** and type `environment`. -For the best performance, we suggest you run on a machine with 4 or more CPU's and at least 8 GB of memory. Currently -`abctl` does support running on 2 cpus and 8 gb of ram with the `--low-resource-mode` flag. You can pass the low -resource mode flag when install Airbyte with `abctl`: + 2. Click **Edit the system environment variables**. The System Properties opens. -```shell -abctl local install --low-resource-mode -``` + 3. Click **Environment Variables**. -Follow this [Github discussion](https://github.com/airbytehq/airbyte/discussions/44391) to upvote and track progress towards supporting lower resource environments. + 4. Find the Path variable and click **Edit**. -## 3: Move Data + 5. Click **New**, then paste the filepath you saved in step 3. -In the Building Connections section, you'll learn how to start moving data. Generally, there are three steps: + 6. Click **OK**, then click **OK**, then close the System Properties. -1: [Set up a Source](./add-a-source) +5. Open a new Command Prompt or PowerShell window. Changes to your Path variable only take effect in a new Window. -2: [Set up a Destination](./add-a-destination.md) +6. Verify abctl is installed correctly. If this command prints the installed version of abctl, you can now use it to manage a local Airbyte instance. -3: [Set up a Connection](./set-up-a-connection.md) + ```bash + abctl version + ``` -## Customizing your Installation with a Values file +
+
-Optionally, you can use a `values.yaml` file to customize your installation of Airbyte. Create the `values.yaml` on your local storage. Then, apply the values you've defined by running the following command and adjusting the path to the `values.yaml` file as needed: +## Part 2: Run Airbyte -```shell -abctl local install --values ./values.yaml -``` +1. Run Docker Desktop. -Here's a list of common customizations. +2. Install Airbyte. -- [External Database](../../deploying-airbyte/integrations/database) -- [State and Logging Storage](../../deploying-airbyte/integrations/storage) -- [Secret Management](../../deploying-airbyte/integrations/secrets) + To run Airbyte with on a machine with the recommended resources (4 or more CPUs), use this command: -## Migrating from Docker Compose (Optional) + ```bash + abctl local install + ``` -:::note + -::: + To run Airbyte in a low-resource environment (fewer than 4 CPUs), specify the `--low-resource-mode` flag to the local install command. -If you have data that you would like to migrate from an existing docker compose instance follow the steps below: + ```bash + abctl local install --low-resource-mode + ``` -1. Make sure that you have stopped the instance running in docker compose, this may require the following command: + :::note + If you see the warning `Encountered an issue deploying Airbyte` with the message `Readiness probe failed: HTTP probe failed with statuscode: 503`, allow installation to continue. You may need to allocate more resources for Airbyte, but installation will complete anyway. See [Suggested resources](#suggested-resources). + ::: -``` -docker compose stop -``` + Installation may take up to 15 minutes depending on your internet connection. When it completes, your Airbyte instance opens in your web browser at [http://localhost:8000](http://localhost:8000). As long as your Docker Desktop daemon is running in the background, use Airbyte by returning to [http://localhost:8000](http://localhost:8000). If you quit Docker Desktop and want to return to Airbyte, start Docker Desktop again. Once your containers are running, you can access Airbyte normally. -2. Make sure that you have the latest version of abctl by running the following command: +3. Enter your **Email** and **Organization name**, then click **Get Started**. Airbyte asks you to log in with a password. -``` -curl -LsfS https://get.airbyte.com | bash - -``` +## Part 3: Set up authentication -3. Run abctl with the migrate flag set with the following command: +To access your Airbyte instance, you need a password. -``` -abctl local install --migrate -``` +1. Get your default password. -:::note + ```bash + abctl local credentials + ``` -If you're using a version of Airbyte that you've installed with `abctl`, you can find instructions on upgrading your Airbyte installation [here](../../operator-guides/upgrading-airbyte.md#upgrading-with-abctl). + This outputs something like this: -::: + ```shell + Credentials: + Email: user@example.com + // highlight-next-line + Password: random_password + Client-Id: 03ef466c-5558-4ca5-856b-4960ba7c161b + Client-Secret: m2UjnDO4iyBQ3IsRiy5GG3LaZWP6xs9I + ``` -## Using an EC2 Instance with abctl +2. Return to your browser and use that password to log into Airbyte. -This guide will assume that you are using the Amazon Linux distribution. However. any distribution that supports a docker engine should work with `abctl`. The launching and connecting to your EC2 Instance is outside the scope of this guide. You can find more information on how to launch and connect to EC2 Instances in the [Get started with Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html) documentation from Amazon. +3. Optional: Since you probably want to set your own password, you can change it any time. -1. Install the docker engine: + ```bash + abctl local credentials --password YourStrongPasswordExample + ``` -```shell -sudo yum install -y docker -``` + Your Airbyte server restarts. Once it finishes, use your new password to log into Airbyte again. -2. Add the ec2-user (or whatever your distros default user) to the docker group: +## What's next -```shell -sudo usermod -a -G docker ec2-user -``` +Congratulations! You have a fully functional instance of Airbyte running locally. -3. Start and optionally enable (start on boot) the docker engine: +### Move data -```shell -sudo systemctl start docker -sudo systemctl enable docker -``` +In Airbyte, you move data from [sources](./add-a-source) to [destinations](./add-a-destination.md). The relationship between a source and a destination is called a [connection](./set-up-a-connection.md). Try moving some data on your local instance. -4. Exit the shell and reconnect to the ec2 instance, an example would look like: +### Deploy Airbyte -```shell -exit -ssh -i ec2-user-key.pem ec2-user@1.2.3.4 -``` +If you want to scale data movement in your organization, you probably need to move Airbyte off your local machine. You can deploy to a cloud provider like AWS, Google Cloud, or Azure. You can also use a single node like an AWS EC2 virtual machine. See the [deployment guide](../../deploying-airbyte/) to learn more. -5. Download the latest version of abctl and install it in your path: +## Uninstall Airbyte -```shell -curl -LsfS https://get.airbyte.com | bash - -``` - -6. Run the `abctl` command and install Airbyte: - :::tip - By default, `abctl` only configures an ingress rule for the host `localhost`. In order to ensure that Airbyte can be accessed outside of the EC2 instance, you will need to specify the `--host` flag to the `local install` command, providing the FQDN of the host which is hosting Airbyte. For example, `abctl local install --host airbyte.company.example`. - ::: - -By default, `abctl` will listen on port 8000. If port 8000 is already in used or you require a different port, you can specify this by passing the `--port` flag to the `local install` command. For example, `abctl local install --port 6598` - -Ensure the security group configured for the EC2 Instance allows traffic in on the port (8000 by default, or whatever port was passed to `--port`) that you deploy Airbyte on. See the [Control traffic to your AWS resources using security groups](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-security-groups.html) documentation for more information. +To stop running all containers, but keep your data: ```shell -abctl local install --host [HOSTNAME] +abctl local uninstall ``` -### Running over HTTP +To stop running containers and delete all data: -Airbyte suggest that you secure your instance of Airbyte using TLS. Running over plain HTTP allows attackers to see your -password over clear text. If you understand the risk and would still like to run Airbyte over HTTP, you must set -Secure Cookies to false. You can do this with `abctl` by passing the `--insecure-cookies` flag to `abctl`: +1. Uninstall Airbyte with the `--persisted` flag. -```shell -abctl local install --host [HOSTNAME] --insecure-cookies -``` + ```shell + abctl local uninstall --persisted + ``` -## Uninstalling +2. Clear any remaining information abctl created. -If you want to remove Airbyte from your system, consider which of the following two options you would like to use. + ```shell + rm -rf ~/.airbyte/abctl + ``` -1: Run the following command to stop all running containers that `abctl` has created **while preserving any data you've created**: + diff --git a/docs/using-airbyte/getting-started/readme.md b/docs/using-airbyte/getting-started/readme.md index a44a2268557d..99e2ebc98724 100644 --- a/docs/using-airbyte/getting-started/readme.md +++ b/docs/using-airbyte/getting-started/readme.md @@ -32,8 +32,7 @@ looking to scale efficiently. For more details, talk to our Sales team. " ctaTex - - + diff --git a/docs/using-airbyte/pyairbyte/getting-started.mdx b/docs/using-airbyte/pyairbyte/getting-started.mdx index 4584a364b264..2288ccf36bde 100644 --- a/docs/using-airbyte/pyairbyte/getting-started.mdx +++ b/docs/using-airbyte/pyairbyte/getting-started.mdx @@ -1,6 +1,6 @@ -# Getting Started with PyAirbyte +# Using PyAirbyte -**PyAirbyte brings the power of Airbyte to every Python and AI developer.** +PyAirbyte brings the power of Airbyte to every Python and AI developer. ## Installation @@ -11,8 +11,6 @@ pip install airbyte ## Quickstarts * **NEW:** [1.0 Launch Demo: AI and PyAirbyte](https://colab.research.google.com/github/airbytehq/quickstarts/blob/main/pyairbyte_notebooks/AI%20ChatBot%20-%201.0%20Launch%20Demo.ipynb) - - * [Basic Demo](https://github.com/airbytehq/quickstarts/blob/main/pyairbyte_notebooks/PyAirbyte_Basic_Features_Demo.ipynb) * [CoinAPI](https://github.com/airbytehq/quickstarts/blob/main/pyairbyte_notebooks/PyAirbyte_CoinAPI_Demo.ipynb) * [GA4](https://github.com/airbytehq/quickstarts/blob/main/pyairbyte_notebooks/PyAirbyte_GA4_Demo.ipynb) diff --git a/docs/using-airbyte/schema-change-management.md b/docs/using-airbyte/schema-change-management.md index b1e8db9f0062..7c0f33a4f13c 100644 --- a/docs/using-airbyte/schema-change-management.md +++ b/docs/using-airbyte/schema-change-management.md @@ -106,18 +106,28 @@ In addition to Airbyte's automatic schema change detection, you can manually ref ## Major Connector Version Upgrades For Cloud users, connectors are generally shipped to you with enhancements and improvements without any action needed from you. -However, connectors may periodically require your approval to upgrade to a new major version. Airbyte will alert you of the new version but continue to sync until the cutoff date for upgrade, giving you a window in which to preview and prepare for any changes. It is **highly recommended** to upgrade before the cutoff date to ensure you continue syncing without interruption. After the window has closed, connections will be automatically disabled to prevent sync failures or sync anomalies, and you'll need to manually upgrade to the new version to continue syncing. +However, connectors may periodically require your approval to upgrade to a new major version. Airbyte will alert you of the new version and give you a window to manually upgrade yourself to preview and prepare for any changes. + +:::tip +It is **highly recommended** to upgrade before the cutoff date to ensure you understand the upcoming changes to your data, as it may affect downstream services and data models. After the window has closed, connections will be automatically upgraded to the new version. +::: When publishing a new version of a connector, Airbyte only considers the following scenarios as reasons as significant enough for a major version release: | Type of Change | Description | | -------------- | -------------- | -| Connector Specification Change | The configuration has been changed and syncs will fail until users reconfigure or re-authenticate. | -| Schema Change | The type of property previously present within a record has changed and a refresh of the source schema is required. | -| Stream or Property Removal | Data that was previously being synced is no longer going to be synced | +| Schema Change | A field or stream was renamed, or the data type of a field has changed. | +| Stream or Property Removal | Data that was previously being synced is no longer going to be synced | +| Addition of a new sync mode | Airbyte now offers a new, more efficient way to sync data. | +| Modifications to a source-defined primary key | The primary key has been added or modified to improve sync accuracy. | +| Connector Configuration (Specification) Change | The configuration has changed and may require re-authentication or a new configuration input. | | Destination Format / Normalization Change | The way the destination writes the final data or how Airbyte cleans that data is changing in a way that requires a full refresh | | State Changes | The format of the source’s state has changed, and the full dataset will need to be re-synced | +We expect that most users will gracefully continue syncing successfully with most major version updates. However, users using a destination that does not utilize [Typing & Deduping](./using-airbyte/core-concepts/typing-deduping) will experience sync failures if the major version includes a data type change. + + +### Upgrading your connector To review major connector version changes and upgrade your connector: 1. In the Airbyte UI, click **Connections** and select the connection with a major version change. diff --git a/docusaurus/docusaurus.config.js b/docusaurus/docusaurus.config.js index 7df10cfc96d7..c394f9182e8a 100644 --- a/docusaurus/docusaurus.config.js +++ b/docusaurus/docusaurus.config.js @@ -14,6 +14,7 @@ const enterpriseDocsHeaderInformation = require("./src/remark/enterpriseDocsHead const productInformation = require("./src/remark/productInformation"); const connectorList = require("./src/remark/connectorList"); const specDecoration = require("./src/remark/specDecoration"); +const docMetaTags = require("./src/remark/docMetaTags"); const redirects = yaml.load( fs.readFileSync(path.join(__dirname, "redirects.yml"), "utf-8") @@ -113,6 +114,7 @@ const config = { docsHeaderDecoration, enterpriseDocsHeaderInformation, productInformation, + docMetaTags, ], }, blog: false, @@ -187,6 +189,7 @@ const config = { prism: { theme: lightCodeTheme, darkTheme: darkCodeTheme, + additionalLanguages:['bash'], }, }), }; diff --git a/docusaurus/package.json b/docusaurus/package.json index 9636f93a0330..351194068eff 100644 --- a/docusaurus/package.json +++ b/docusaurus/package.json @@ -87,6 +87,7 @@ "@docusaurus/theme-search-algolia": "^3.0.1", "@docusaurus/types": "^3.0.1", "@fortawesome/fontawesome-svg-core": "^6.5.1", + "@fortawesome/free-brands-svg-icons": "^6.7.1", "@fortawesome/free-regular-svg-icons": "^6.5.1", "@fortawesome/free-solid-svg-icons": "^6.5.1", "@fortawesome/react-fontawesome": "^0.2.0", @@ -125,6 +126,7 @@ "prism-react-renderer": "^2.3.1", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-lite-youtube-embed": "^2.4.0", "react-markdown": "^8.0.7", "react-router": "5.3.3", "sanitize-html": "^2.12.1", diff --git a/docusaurus/pnpm-lock.yaml b/docusaurus/pnpm-lock.yaml index 552bc9697283..176625009802 100644 --- a/docusaurus/pnpm-lock.yaml +++ b/docusaurus/pnpm-lock.yaml @@ -230,6 +230,9 @@ importers: '@fortawesome/fontawesome-svg-core': specifier: ^6.5.1 version: 6.5.1 + '@fortawesome/free-brands-svg-icons': + specifier: ^6.7.1 + version: 6.7.1 '@fortawesome/free-regular-svg-icons': specifier: ^6.5.1 version: 6.5.1 @@ -344,6 +347,9 @@ importers: react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) + react-lite-youtube-embed: + specifier: ^2.4.0 + version: 2.4.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-markdown: specifier: ^8.0.7 version: 8.0.7(@types/react@18.2.46)(react@18.2.0) @@ -1455,10 +1461,18 @@ packages: resolution: {integrity: sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A==} engines: {node: '>=6'} + '@fortawesome/fontawesome-common-types@6.7.1': + resolution: {integrity: sha512-gbDz3TwRrIPT3i0cDfujhshnXO9z03IT1UKRIVi/VEjpNHtSBIP2o5XSm+e816FzzCFEzAxPw09Z13n20PaQJQ==} + engines: {node: '>=6'} + '@fortawesome/fontawesome-svg-core@6.5.1': resolution: {integrity: sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ==} engines: {node: '>=6'} + '@fortawesome/free-brands-svg-icons@6.7.1': + resolution: {integrity: sha512-nJR76eqPzCnMyhbiGf6X0aclDirZriTPRcFm1YFvuupyJOGwlNF022w3YBqu+yrHRhnKRpzFX+8wJKqiIjWZkA==} + engines: {node: '>=6'} + '@fortawesome/free-regular-svg-icons@6.5.1': resolution: {integrity: sha512-m6ShXn+wvqEU69wSP84coxLbNl7sGVZb+Ca+XZq6k30SzuP3X4TfPqtycgUh9ASwlNh5OfQCd8pDIWxl+O+LlQ==} engines: {node: '>=6'} @@ -5033,6 +5047,12 @@ packages: peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-lite-youtube-embed@2.4.0: + resolution: {integrity: sha512-Xo6cM1zPlROvvM97JkqQIoXstlQDaC4+DawmM7BB7Hh1cXrkBHEGq1iJlQxBTUWAUklmpcC7ph7qg7CztXtABQ==} + peerDependencies: + react: '>=18.2.0' + react-dom: '>=18.2.0' + react-loadable-ssr-addon-v5-slorber@1.0.1: resolution: {integrity: sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==} engines: {node: '>=10.13.0'} @@ -7751,10 +7771,16 @@ snapshots: '@fortawesome/fontawesome-common-types@6.5.1': {} + '@fortawesome/fontawesome-common-types@6.7.1': {} + '@fortawesome/fontawesome-svg-core@6.5.1': dependencies: '@fortawesome/fontawesome-common-types': 6.5.1 + '@fortawesome/free-brands-svg-icons@6.7.1': + dependencies: + '@fortawesome/fontawesome-common-types': 6.7.1 + '@fortawesome/free-regular-svg-icons@6.5.1': dependencies: '@fortawesome/fontawesome-common-types': 6.5.1 @@ -11934,6 +11960,11 @@ snapshots: dependencies: react: 18.2.0 + react-lite-youtube-embed@2.4.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@5.5.2(react@18.2.0))(webpack@5.95.0): dependencies: '@babel/runtime': 7.23.7 diff --git a/docusaurus/sidebars.js b/docusaurus/sidebars.js index 945c3c0a9701..760d7b5eb075 100644 --- a/docusaurus/sidebars.js +++ b/docusaurus/sidebars.js @@ -85,8 +85,7 @@ function getDestinationConnectors() { function getEnterpriseConnectors() { return getFilenamesInDir( "integrations/enterprise-connectors/", - enterpriseConnectorDocs, - ["readme"] + enterpriseConnectorDocs, ["readme"] ); } @@ -342,6 +341,7 @@ const buildAConnector = { ], }, "connector-development/connector-specification-reference", + "connector-development/writing-connector-docs", "connector-development/schema-reference", "connector-development/connector-metadata-file", "connector-development/best-practices", @@ -444,6 +444,7 @@ const deployAirbyte = { "deploying-airbyte/integrations/database", // "deploying-airbyte/integrations/monitoring", "deploying-airbyte/integrations/ingress", + "deploying-airbyte/integrations/custom-image-registries", ], }, @@ -456,6 +457,14 @@ const deployAirbyte = { type: "doc", id: "deploying-airbyte/troubleshoot-deploy", }, + { + type: "doc", + id: "deploying-airbyte/migrating-from-docker-compose", + }, + { + type: "doc", + id: "deploying-airbyte/abctl-ec2", + }, ], }; @@ -719,6 +728,8 @@ module.exports = { type: "generated-index", }, items: [ + "release_notes/v-1.3", + "release_notes/v-1.2", "release_notes/v-1.1", "release_notes/v-1.0", "release_notes/aug_2024", diff --git a/docusaurus/src/components/DocMetaTags.jsx b/docusaurus/src/components/DocMetaTags.jsx new file mode 100644 index 000000000000..8bb885f9a736 --- /dev/null +++ b/docusaurus/src/components/DocMetaTags.jsx @@ -0,0 +1,11 @@ +import Head from "@docusaurus/Head"; + +export const DocMetaTags = (props) => { + const { title, description } = props; + return ( + + {title} + + + ); +}; diff --git a/docusaurus/src/components/YoutubeEmbed.jsx b/docusaurus/src/components/YoutubeEmbed.jsx new file mode 100644 index 000000000000..c5d94c542fda --- /dev/null +++ b/docusaurus/src/components/YoutubeEmbed.jsx @@ -0,0 +1,12 @@ +import LiteYouTubeEmbed from "react-lite-youtube-embed"; +import "react-lite-youtube-embed/dist/LiteYouTubeEmbed.css"; + +export const YoutubeEmbed = ({ id, title }) => { + return ( + + ); +}; diff --git a/docusaurus/src/css/custom.css b/docusaurus/src/css/custom.css index 289cc01b053f..663f4b360be0 100644 --- a/docusaurus/src/css/custom.css +++ b/docusaurus/src/css/custom.css @@ -25,6 +25,12 @@ --ifm-hover-overlay: rgb(0 0 0 / 2%); --color-active-nav-item-background: #f4f4ff; --color-active-nav-item-text: var(--ifm-color-primary-darker); + --ifm-table-background: transparent; + --ifm-table-stripe-background: transparent; + --ifm-table-head-background: var(--ifm-color-primary); + --ifm-table-head-color: var(--color-white); + --ifm-table-border-color: var(--ifm-color-primary-lightest); + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.2); --color-white: hsl(0, 0%, 100%); --color-grey-40: hsl(240, 25%, 98%); @@ -53,6 +59,13 @@ html[data-theme="dark"] { --ifm-color-primary-lightest: #c8c7ff; --color-active-nav-item-background: #272729; --color-active-nav-item-text: var(--ifm-color-primary-lighter); + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.8); + + --ifm-table-background: transparent; + --ifm-table-stripe-background: transparent; + --ifm-table-head-background: var(--color-blue-30); + --ifm-table-head-color: hsl(240, 100%, 98%); + --ifm-table-border-color:hsl(240, 100%, 98%); --color-grey-40: hsl(240, 14%, 14%); --color-grey-100: hsl(240, 15%, 15%); @@ -69,17 +82,6 @@ html[data-theme="dark"] { --icon-background: hsl(0, 0%, 100%); } -.docusaurus-highlight-code-line { - background-color: rgba(0, 0, 0, 0.1); - display: block; - margin: 0 calc(-1 * var(--ifm-pre-padding)); - padding: 0 var(--ifm-pre-padding); -} - -html[data-theme="dark"] .docusaurus-highlight-code-line { - background-color: rgba(0, 0, 0, 0.3); -} - .admonition-icon, .iconExternalLink_wgqa, .iconExternalLink_node_modules-\@docusaurus-theme-classic-lib-next-theme-IconExternalLink-styles-module { @@ -234,3 +236,47 @@ The variables for them have been added to :root at the top of this file */ background: var(--color-active-nav-item-background); color: var(--color-active-nav-item-text); } + + +table { + border-spacing: 0; + border-collapse: separate; + overflow-x: auto; +} + +/* Add these new styles */ +table th:first-child { + border-top-left-radius: 10px; +} + +table th:last-child { + border-top-right-radius: 10px; +} + +table tr:last-child td:first-child { + border-bottom-left-radius: 10px; +} + +table tr:last-child td:last-child { + border-bottom-right-radius: 10px; +} + +table th code { + color: var(--ifm-color-content); +} + +table td code { + background-color: var(--color-blue-30); + padding: 2px 8px; + border: none; + font-family: monospace; + border-radius: 4px; +} + +table tr:hover { + background-color: var(--color-grey-40); + transition: background-color 0.2s ease; +} +table thead tr:hover { + background-color: transparent; +} \ No newline at end of file diff --git a/docusaurus/src/remark/docMetaTags.js b/docusaurus/src/remark/docMetaTags.js new file mode 100644 index 000000000000..3246fd66bb0b --- /dev/null +++ b/docusaurus/src/remark/docMetaTags.js @@ -0,0 +1,42 @@ +const { getFromPaths, toAttributes } = require("../helpers/objects"); +const { isDocsPage, getRegistryEntry } = require("./utils"); +const visit = require("unist-util-visit").visit; + +const generateMetaTags = (connectorName) => { + return { + title: `${connectorName} Connector | Airbyte Documentation`, + description: `Connect ${connectorName} to our ETL/ELT platform for streamlined data integration, automated syncing, and powerful data insights.`, + }; +}; +const plugin = () => { + const transformer = async (ast, vfile) => { + const docsPageInfo = isDocsPage(vfile); + if (!docsPageInfo.isDocsPage) return; + + const registryEntry = await getRegistryEntry(vfile); + + if (!registryEntry) return; + + visit(ast, "root", (node) => { + const name = getFromPaths(registryEntry, "name_[oss|cloud]"); + const { title, description } = generateMetaTags(name); + + const attributes = toAttributes({ + title, + description, + }); + + const metaTagsNode = { + type: "mdxJsxFlowElement", + name: "DocMetaTags", + attributes: attributes, + children: [], + }; + + node.children.unshift(metaTagsNode); + }); + }; + return transformer; +}; + +module.exports = plugin; diff --git a/docusaurus/src/theme/MDXComponents/index.js b/docusaurus/src/theme/MDXComponents/index.js index c4fa477cd89a..72e17cd8781b 100644 --- a/docusaurus/src/theme/MDXComponents/index.js +++ b/docusaurus/src/theme/MDXComponents/index.js @@ -10,8 +10,11 @@ import { SpecSchema } from "@site/src/components/SpecSchema"; import MDXComponents from "@theme-original/MDXComponents"; import { CardWithIcon } from "../../components/Card/Card"; import { Details } from "../../components/Details"; +import { DocMetaTags } from "../../components/DocMetaTags"; import { EntityRelationshipDiagram } from "../../components/EntityRelationshipDiagram"; import { Grid } from "../../components/Grid/Grid"; +import { YoutubeEmbed } from "../../components/YoutubeEmbed"; + export default { // Re-use the default mapping ...MDXComponents, @@ -27,4 +30,6 @@ export default { EntityRelationshipDiagram, CardWithIcon, Grid, + YoutubeEmbed, + DocMetaTags, }; diff --git a/docusaurus/static/_docker_image_registries.md b/docusaurus/static/_docker_image_registries.md new file mode 100644 index 000000000000..b951abd7cca1 --- /dev/null +++ b/docusaurus/static/_docker_image_registries.md @@ -0,0 +1,8 @@ +| Cloud provider | Service name | Documentation | +| -------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Google Cloud | Artifact Registry | [Quickstart](https://cloud.google.com/artifact-registry/docs/docker/quickstart) | +| AWS | Amazon ECR | [Getting started with Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-console.html) | +| Azure | Container Registry | [Quickstart](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-portal#:~:text=Azure%20Container%20Registry%20is%20a,container%20images%20and%20related%20artifacts.&text=Then%2C%20use%20Docker%20commands%20to,the%20image%20from%20your%20registry.) | +| DockerHub | Repositories | [DockerHub Quickstart](https://docs.docker.com/docker-hub/) | +| GitHub | Container Registry | [Working with the Container registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry ) | +| Self hosted | Open-source Docker Registry | [Deploy a registry server](https://docs.docker.com/registry/deploying/) | \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index b608b7e856a7..f3ed78055dc3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "attrs" @@ -224,114 +224,101 @@ rpds-py = ">=0.7.0" [[package]] name = "rpds-py" -version = "0.20.0" +version = "0.21.0" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "rpds_py-0.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2"}, - {file = "rpds_py-0.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf"}, - {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140"}, - {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f"}, - {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce"}, - {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94"}, - {file = "rpds_py-0.20.0-cp310-none-win32.whl", hash = "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee"}, - {file = "rpds_py-0.20.0-cp310-none-win_amd64.whl", hash = "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399"}, - {file = "rpds_py-0.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489"}, - {file = "rpds_py-0.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209"}, - {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3"}, - {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272"}, - {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad"}, - {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58"}, - {file = "rpds_py-0.20.0-cp311-none-win32.whl", hash = "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0"}, - {file = "rpds_py-0.20.0-cp311-none-win_amd64.whl", hash = "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c"}, - {file = "rpds_py-0.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6"}, - {file = "rpds_py-0.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4"}, - {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef"}, - {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821"}, - {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940"}, - {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174"}, - {file = "rpds_py-0.20.0-cp312-none-win32.whl", hash = "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139"}, - {file = "rpds_py-0.20.0-cp312-none-win_amd64.whl", hash = "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585"}, - {file = "rpds_py-0.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29"}, - {file = "rpds_py-0.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879"}, - {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f"}, - {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c"}, - {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2"}, - {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57"}, - {file = "rpds_py-0.20.0-cp313-none-win32.whl", hash = "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a"}, - {file = "rpds_py-0.20.0-cp313-none-win_amd64.whl", hash = "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2"}, - {file = "rpds_py-0.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:f2fbf7db2012d4876fb0d66b5b9ba6591197b0f165db8d99371d976546472a24"}, - {file = "rpds_py-0.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1e5f3cd7397c8f86c8cc72d5a791071431c108edd79872cdd96e00abd8497d29"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce9845054c13696f7af7f2b353e6b4f676dab1b4b215d7fe5e05c6f8bb06f965"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c3e130fd0ec56cb76eb49ef52faead8ff09d13f4527e9b0c400307ff72b408e1"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b16aa0107ecb512b568244ef461f27697164d9a68d8b35090e9b0c1c8b27752"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa7f429242aae2947246587d2964fad750b79e8c233a2367f71b554e9447949c"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af0fc424a5842a11e28956e69395fbbeab2c97c42253169d87e90aac2886d751"}, - {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b8c00a3b1e70c1d3891f0db1b05292747f0dbcfb49c43f9244d04c70fbc40eb8"}, - {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:40ce74fc86ee4645d0a225498d091d8bc61f39b709ebef8204cb8b5a464d3c0e"}, - {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4fe84294c7019456e56d93e8ababdad5a329cd25975be749c3f5f558abb48253"}, - {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:338ca4539aad4ce70a656e5187a3a31c5204f261aef9f6ab50e50bcdffaf050a"}, - {file = "rpds_py-0.20.0-cp38-none-win32.whl", hash = "sha256:54b43a2b07db18314669092bb2de584524d1ef414588780261e31e85846c26a5"}, - {file = "rpds_py-0.20.0-cp38-none-win_amd64.whl", hash = "sha256:a1862d2d7ce1674cffa6d186d53ca95c6e17ed2b06b3f4c476173565c862d232"}, - {file = "rpds_py-0.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3fde368e9140312b6e8b6c09fb9f8c8c2f00999d1823403ae90cc00480221b22"}, - {file = "rpds_py-0.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9824fb430c9cf9af743cf7aaf6707bf14323fb51ee74425c380f4c846ea70789"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11ef6ce74616342888b69878d45e9f779b95d4bd48b382a229fe624a409b72c5"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c52d3f2f82b763a24ef52f5d24358553e8403ce05f893b5347098014f2d9eff2"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d35cef91e59ebbeaa45214861874bc6f19eb35de96db73e467a8358d701a96c"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d72278a30111e5b5525c1dd96120d9e958464316f55adb030433ea905866f4de"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4c29cbbba378759ac5786730d1c3cb4ec6f8ababf5c42a9ce303dc4b3d08cda"}, - {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6632f2d04f15d1bd6fe0eedd3b86d9061b836ddca4c03d5cf5c7e9e6b7c14580"}, - {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d0b67d87bb45ed1cd020e8fbf2307d449b68abc45402fe1a4ac9e46c3c8b192b"}, - {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ec31a99ca63bf3cd7f1a5ac9fe95c5e2d060d3c768a09bc1d16e235840861420"}, - {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22e6c9976e38f4d8c4a63bd8a8edac5307dffd3ee7e6026d97f3cc3a2dc02a0b"}, - {file = "rpds_py-0.20.0-cp39-none-win32.whl", hash = "sha256:569b3ea770c2717b730b61998b6c54996adee3cef69fc28d444f3e7920313cf7"}, - {file = "rpds_py-0.20.0-cp39-none-win_amd64.whl", hash = "sha256:e6900ecdd50ce0facf703f7a00df12374b74bbc8ad9fe0f6559947fb20f82364"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344"}, - {file = "rpds_py-0.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f918a1a130a6dfe1d7fe0f105064141342e7dd1611f2e6a21cd2f5c8cb1cfb3e"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f60012a73aa396be721558caa3a6fd49b3dd0033d1675c6d59c4502e870fcf0c"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d2b1ad682a3dfda2a4e8ad8572f3100f95fad98cb99faf37ff0ddfe9cbf9d03"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:614fdafe9f5f19c63ea02817fa4861c606a59a604a77c8cdef5aa01d28b97921"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa518bcd7600c584bf42e6617ee8132869e877db2f76bcdc281ec6a4113a53ab"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0475242f447cc6cb8a9dd486d68b2ef7fbee84427124c232bff5f63b1fe11e5"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f90a4cd061914a60bd51c68bcb4357086991bd0bb93d8aa66a6da7701370708f"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:def7400461c3a3f26e49078302e1c1b38f6752342c77e3cf72ce91ca69fb1bc1"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:65794e4048ee837494aea3c21a28ad5fc080994dfba5b036cf84de37f7ad5074"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:faefcc78f53a88f3076b7f8be0a8f8d35133a3ecf7f3770895c25f8813460f08"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5b4f105deeffa28bbcdff6c49b34e74903139afa690e35d2d9e3c2c2fba18cec"}, - {file = "rpds_py-0.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fdfc3a892927458d98f3d55428ae46b921d1f7543b89382fdb483f5640daaec8"}, - {file = "rpds_py-0.20.0.tar.gz", hash = "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121"}, + {file = "rpds_py-0.21.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a017f813f24b9df929674d0332a374d40d7f0162b326562daae8066b502d0590"}, + {file = "rpds_py-0.21.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:20cc1ed0bcc86d8e1a7e968cce15be45178fd16e2ff656a243145e0b439bd250"}, + {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad116dda078d0bc4886cb7840e19811562acdc7a8e296ea6ec37e70326c1b41c"}, + {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:808f1ac7cf3b44f81c9475475ceb221f982ef548e44e024ad5f9e7060649540e"}, + {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de552f4a1916e520f2703ec474d2b4d3f86d41f353e7680b597512ffe7eac5d0"}, + {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:efec946f331349dfc4ae9d0e034c263ddde19414fe5128580f512619abed05f1"}, + {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b80b4690bbff51a034bfde9c9f6bf9357f0a8c61f548942b80f7b66356508bf5"}, + {file = "rpds_py-0.21.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:085ed25baac88953d4283e5b5bd094b155075bb40d07c29c4f073e10623f9f2e"}, + {file = "rpds_py-0.21.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:daa8efac2a1273eed2354397a51216ae1e198ecbce9036fba4e7610b308b6153"}, + {file = "rpds_py-0.21.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:95a5bad1ac8a5c77b4e658671642e4af3707f095d2b78a1fdd08af0dfb647624"}, + {file = "rpds_py-0.21.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3e53861b29a13d5b70116ea4230b5f0f3547b2c222c5daa090eb7c9c82d7f664"}, + {file = "rpds_py-0.21.0-cp310-none-win32.whl", hash = "sha256:ea3a6ac4d74820c98fcc9da4a57847ad2cc36475a8bd9683f32ab6d47a2bd682"}, + {file = "rpds_py-0.21.0-cp310-none-win_amd64.whl", hash = "sha256:b8f107395f2f1d151181880b69a2869c69e87ec079c49c0016ab96860b6acbe5"}, + {file = "rpds_py-0.21.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5555db3e618a77034954b9dc547eae94166391a98eb867905ec8fcbce1308d95"}, + {file = "rpds_py-0.21.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:97ef67d9bbc3e15584c2f3c74bcf064af36336c10d2e21a2131e123ce0f924c9"}, + {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ab2c2a26d2f69cdf833174f4d9d86118edc781ad9a8fa13970b527bf8236027"}, + {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4e8921a259f54bfbc755c5bbd60c82bb2339ae0324163f32868f63f0ebb873d9"}, + {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a7ff941004d74d55a47f916afc38494bd1cfd4b53c482b77c03147c91ac0ac3"}, + {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5145282a7cd2ac16ea0dc46b82167754d5e103a05614b724457cffe614f25bd8"}, + {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de609a6f1b682f70bb7163da745ee815d8f230d97276db049ab447767466a09d"}, + {file = "rpds_py-0.21.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:40c91c6e34cf016fa8e6b59d75e3dbe354830777fcfd74c58b279dceb7975b75"}, + {file = "rpds_py-0.21.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d2132377f9deef0c4db89e65e8bb28644ff75a18df5293e132a8d67748397b9f"}, + {file = "rpds_py-0.21.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0a9e0759e7be10109645a9fddaaad0619d58c9bf30a3f248a2ea57a7c417173a"}, + {file = "rpds_py-0.21.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e20da3957bdf7824afdd4b6eeb29510e83e026473e04952dca565170cd1ecc8"}, + {file = "rpds_py-0.21.0-cp311-none-win32.whl", hash = "sha256:f71009b0d5e94c0e86533c0b27ed7cacc1239cb51c178fd239c3cfefefb0400a"}, + {file = "rpds_py-0.21.0-cp311-none-win_amd64.whl", hash = "sha256:e168afe6bf6ab7ab46c8c375606298784ecbe3ba31c0980b7dcbb9631dcba97e"}, + {file = "rpds_py-0.21.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:30b912c965b2aa76ba5168fd610087bad7fcde47f0a8367ee8f1876086ee6d1d"}, + {file = "rpds_py-0.21.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ca9989d5d9b1b300bc18e1801c67b9f6d2c66b8fd9621b36072ed1df2c977f72"}, + {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f54e7106f0001244a5f4cf810ba8d3f9c542e2730821b16e969d6887b664266"}, + {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fed5dfefdf384d6fe975cc026886aece4f292feaf69d0eeb716cfd3c5a4dd8be"}, + {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:590ef88db231c9c1eece44dcfefd7515d8bf0d986d64d0caf06a81998a9e8cab"}, + {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f983e4c2f603c95dde63df633eec42955508eefd8d0f0e6d236d31a044c882d7"}, + {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b229ce052ddf1a01c67d68166c19cb004fb3612424921b81c46e7ea7ccf7c3bf"}, + {file = "rpds_py-0.21.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ebf64e281a06c904a7636781d2e973d1f0926a5b8b480ac658dc0f556e7779f4"}, + {file = "rpds_py-0.21.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:998a8080c4495e4f72132f3d66ff91f5997d799e86cec6ee05342f8f3cda7dca"}, + {file = "rpds_py-0.21.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:98486337f7b4f3c324ab402e83453e25bb844f44418c066623db88e4c56b7c7b"}, + {file = "rpds_py-0.21.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a78d8b634c9df7f8d175451cfeac3810a702ccb85f98ec95797fa98b942cea11"}, + {file = "rpds_py-0.21.0-cp312-none-win32.whl", hash = "sha256:a58ce66847711c4aa2ecfcfaff04cb0327f907fead8945ffc47d9407f41ff952"}, + {file = "rpds_py-0.21.0-cp312-none-win_amd64.whl", hash = "sha256:e860f065cc4ea6f256d6f411aba4b1251255366e48e972f8a347cf88077b24fd"}, + {file = "rpds_py-0.21.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:ee4eafd77cc98d355a0d02f263efc0d3ae3ce4a7c24740010a8b4012bbb24937"}, + {file = "rpds_py-0.21.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:688c93b77e468d72579351a84b95f976bd7b3e84aa6686be6497045ba84be560"}, + {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c38dbf31c57032667dd5a2f0568ccde66e868e8f78d5a0d27dcc56d70f3fcd3b"}, + {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2d6129137f43f7fa02d41542ffff4871d4aefa724a5fe38e2c31a4e0fd343fb0"}, + {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:520ed8b99b0bf86a176271f6fe23024323862ac674b1ce5b02a72bfeff3fff44"}, + {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaeb25ccfb9b9014a10eaf70904ebf3f79faaa8e60e99e19eef9f478651b9b74"}, + {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af04ac89c738e0f0f1b913918024c3eab6e3ace989518ea838807177d38a2e94"}, + {file = "rpds_py-0.21.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9b76e2afd585803c53c5b29e992ecd183f68285b62fe2668383a18e74abe7a3"}, + {file = "rpds_py-0.21.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5afb5efde74c54724e1a01118c6e5c15e54e642c42a1ba588ab1f03544ac8c7a"}, + {file = "rpds_py-0.21.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:52c041802a6efa625ea18027a0723676a778869481d16803481ef6cc02ea8cb3"}, + {file = "rpds_py-0.21.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ee1e4fc267b437bb89990b2f2abf6c25765b89b72dd4a11e21934df449e0c976"}, + {file = "rpds_py-0.21.0-cp313-none-win32.whl", hash = "sha256:0c025820b78817db6a76413fff6866790786c38f95ea3f3d3c93dbb73b632202"}, + {file = "rpds_py-0.21.0-cp313-none-win_amd64.whl", hash = "sha256:320c808df533695326610a1b6a0a6e98f033e49de55d7dc36a13c8a30cfa756e"}, + {file = "rpds_py-0.21.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:2c51d99c30091f72a3c5d126fad26236c3f75716b8b5e5cf8effb18889ced928"}, + {file = "rpds_py-0.21.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cbd7504a10b0955ea287114f003b7ad62330c9e65ba012c6223dba646f6ffd05"}, + {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6dcc4949be728ede49e6244eabd04064336012b37f5c2200e8ec8eb2988b209c"}, + {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f414da5c51bf350e4b7960644617c130140423882305f7574b6cf65a3081cecb"}, + {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9afe42102b40007f588666bc7de82451e10c6788f6f70984629db193849dced1"}, + {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b929c2bb6e29ab31f12a1117c39f7e6d6450419ab7464a4ea9b0b417174f044"}, + {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8404b3717da03cbf773a1d275d01fec84ea007754ed380f63dfc24fb76ce4592"}, + {file = "rpds_py-0.21.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e12bb09678f38b7597b8346983d2323a6482dcd59e423d9448108c1be37cac9d"}, + {file = "rpds_py-0.21.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:58a0e345be4b18e6b8501d3b0aa540dad90caeed814c515e5206bb2ec26736fd"}, + {file = "rpds_py-0.21.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c3761f62fcfccf0864cc4665b6e7c3f0c626f0380b41b8bd1ce322103fa3ef87"}, + {file = "rpds_py-0.21.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c2b2f71c6ad6c2e4fc9ed9401080badd1469fa9889657ec3abea42a3d6b2e1ed"}, + {file = "rpds_py-0.21.0-cp39-none-win32.whl", hash = "sha256:b21747f79f360e790525e6f6438c7569ddbfb1b3197b9e65043f25c3c9b489d8"}, + {file = "rpds_py-0.21.0-cp39-none-win_amd64.whl", hash = "sha256:0626238a43152918f9e72ede9a3b6ccc9e299adc8ade0d67c5e142d564c9a83d"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6b4ef7725386dc0762857097f6b7266a6cdd62bfd209664da6712cb26acef035"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:6bc0e697d4d79ab1aacbf20ee5f0df80359ecf55db33ff41481cf3e24f206919"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da52d62a96e61c1c444f3998c434e8b263c384f6d68aca8274d2e08d1906325c"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:98e4fe5db40db87ce1c65031463a760ec7906ab230ad2249b4572c2fc3ef1f9f"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30bdc973f10d28e0337f71d202ff29345320f8bc49a31c90e6c257e1ccef4333"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:faa5e8496c530f9c71f2b4e1c49758b06e5f4055e17144906245c99fa6d45356"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32eb88c30b6a4f0605508023b7141d043a79b14acb3b969aa0b4f99b25bc7d4a"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a89a8ce9e4e75aeb7fa5d8ad0f3fecdee813802592f4f46a15754dcb2fd6b061"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:241e6c125568493f553c3d0fdbb38c74babf54b45cef86439d4cd97ff8feb34d"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:3b766a9f57663396e4f34f5140b3595b233a7b146e94777b97a8413a1da1be18"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:af4a644bf890f56e41e74be7d34e9511e4954894d544ec6b8efe1e21a1a8da6c"}, + {file = "rpds_py-0.21.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3e30a69a706e8ea20444b98a49f386c17b26f860aa9245329bab0851ed100677"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:031819f906bb146561af051c7cef4ba2003d28cff07efacef59da973ff7969ba"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b876f2bc27ab5954e2fd88890c071bd0ed18b9c50f6ec3de3c50a5ece612f7a6"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc5695c321e518d9f03b7ea6abb5ea3af4567766f9852ad1560f501b17588c7b"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b4de1da871b5c0fd5537b26a6fc6814c3cc05cabe0c941db6e9044ffbb12f04a"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:878f6fea96621fda5303a2867887686d7a198d9e0f8a40be100a63f5d60c88c9"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8eeec67590e94189f434c6d11c426892e396ae59e4801d17a93ac96b8c02a6c"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ff2eba7f6c0cb523d7e9cff0903f2fe1feff8f0b2ceb6bd71c0e20a4dcee271"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a429b99337062877d7875e4ff1a51fe788424d522bd64a8c0a20ef3021fdb6ed"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:d167e4dbbdac48bd58893c7e446684ad5d425b407f9336e04ab52e8b9194e2ed"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:4eb2de8a147ffe0626bfdc275fc6563aa7bf4b6db59cf0d44f0ccd6ca625a24e"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:e78868e98f34f34a88e23ee9ccaeeec460e4eaf6db16d51d7a9b883e5e785a5e"}, + {file = "rpds_py-0.21.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4991ca61656e3160cdaca4851151fd3f4a92e9eba5c7a530ab030d6aee96ec89"}, + {file = "rpds_py-0.21.0.tar.gz", hash = "sha256:ed6378c9d66d0de903763e7706383d60c33829581f0adff47b6535f1802fa6db"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 8b1bab693174..000000000000 --- a/pyproject.toml +++ /dev/null @@ -1,279 +0,0 @@ -[tool.poetry] -name = "airbyte" -version = "0.1.0" -description = "Airbyte open source connector code" -authors = ["Airbyte "] - -[tool.poetry.dependencies] -python = "~3.10" -jsonschema = "^4.22.0" - -[tool.poetry.group.dev.dependencies] -isort = "5.6.4" -black = "~22.3.0" -ruff = "^0.4" -poethepoet = "^0.26.1" - -[tool.poe.tasks] -isort = { cmd = "poetry run isort --settings-file pyproject.toml ." } -black = { cmd = "poetry run black --config pyproject.toml ." } -format = { sequence = [ - "isort", - "black", -], help = "Format Python code in the repository. This command is invoked in airbyte-ci format." } - -[tool.black] -line-length = 140 -target-version = ["py310"] -extend-exclude = """ -/( - build - | integration_tests - | unit_tests - | generated - | airbyte-cdk/python/airbyte_cdk/sources/declarative/models - | invalid - | non_formatted_code - | airbyte-integrations/connectors/destination-duckdb - | airbyte-integrations/connectors/destination-snowflake-cortex -)/ -""" - -[tool.flake8] -extend-exclude = [ - "*/lib/*/site-packages", - ".venv", - "build", - "models", - ".eggs", - "**/__init__.py", - "**/generated/*", - "**/declarative/models/*", -] -max-complexity = 20 -max-line-length = 140 -extend-ignore = [ - "E203", # whitespace before ':' (conflicts with Black) - "E231", # Bad trailing comma (conflicts with Black) - "E501", # line too long (conflicts with Black) - "W503", # line break before binary operator (conflicts with Black) - "F811", # TODO: ella fix after pflake8 version update -] - -[tool.coverage.report] -fail_under = 0 -skip_empty = true -sort = "-cover" -omit = [ - ".venv/*", - "main.py", - "setup.py", - "unit_tests/*", - "integration_tests/*", - "**/generated/*", -] - -# TODO: This will be removed in favor of the section below. -[tool.isort] -profile = "black" -color_output = false -# skip_gitignore = true -line_length = 140 -multi_line_output = 3 -include_trailing_comma = true -force_grid_wrap = 0 -use_parentheses = true -skip_glob = [ - "airbyte-cdk/python/airbyte_cdk/sources/declarative/models/**", - "**/invalid/**", - "**/non_formatted_code/**", - "**/connector_builder/generated/**", - # TODO: Remove this after we move to Ruff. Ruff is mono-repo-aware and - # correctly handles first-party imports in subdirectories. - - # Migrated to Ruff: - "airbyte-integrations/connectors/destination-duckdb/**", - "airbyte-integrations/connectors/destination-snowflake-cortex/**" -] - -[tool.ruff.pylint] -max-args = 8 # Relaxed from default of 5 -max-branches = 15 # Relaxed from default of 12 - -[tool.ruff] -target-version = "py310" -select = [ - # For rules reference, see https://docs.astral.sh/ruff/rules/ - "A", # flake8-builtins - "ANN", # flake8-annotations - "ARG", # flake8-unused-arguments - "ASYNC", # flake8-async - "B", # flake8-bugbear - "FBT", # flake8-boolean-trap - "BLE", # Blind except - "C4", # flake8-comprehensions - "C90", # mccabe (complexity) - "COM", # flake8-commas - "CPY", # missing copyright notice - # "D", # pydocstyle # TODO: Re-enable when adding docstrings - "DTZ", # flake8-datetimez - "E", # pycodestyle (errors) - "ERA", # flake8-eradicate (commented out code) - "EXE", # flake8-executable - "F", # Pyflakes - "FA", # flake8-future-annotations - "FIX", # flake8-fixme - "FLY", # flynt - "FURB", # Refurb - "I", # isort - "ICN", # flake8-import-conventions - "INP", # flake8-no-pep420 - "INT", # flake8-gettext - "ISC", # flake8-implicit-str-concat - "ICN", # flake8-import-conventions - "LOG", # flake8-logging - "N", # pep8-naming - "PD", # pandas-vet - "PERF", # Perflint - "PIE", # flake8-pie - "PGH", # pygrep-hooks - "PL", # Pylint - "PT", # flake8-pytest-style - "PTH", # flake8-use-pathlib - "PYI", # flake8-pyi - "Q", # flake8-quotes - "RET", # flake8-return - "RSE", # flake8-raise - "RUF", # Ruff-specific rules - "SIM", # flake8-simplify - "SLF", # flake8-self - "SLOT", # flake8-slots - "T10", # debugger calls - # "T20", # flake8-print # TODO: Re-enable once we have logging - "TCH", # flake8-type-checking - "TD", # flake8-todos - "TID", # flake8-tidy-imports - "TRY", # tryceratops - "TRY002", # Disallow raising vanilla Exception. Create or use a custom exception instead. - "TRY003", # Disallow vanilla string passing. Prefer kwargs to the exception constructur. - "UP", # pyupgrade - "W", # pycodestyle (warnings) - "YTT", # flake8-2020 -] - -ignore = [ - # For rules reference, see https://docs.astral.sh/ruff/rules/ - - # These we don't agree with or don't want to prioritize to enforce: - "ANN003", # kwargs missing type annotations - "ANN101", # Type annotations for 'self' args - "ANN102", # Type annotations for 'cls' args - "COM812", # Because it conflicts with ruff auto-format - "EM", # flake8-errmsgs (may reconsider later) - "DJ", # Django linting - "G", # flake8-logging-format - "ISC001", # Conflicts with ruff auto-format - "NPY", # NumPy-specific rules - "PIE790", # Allow unnecssary 'pass' (sometimes useful for readability) - "PERF203", # exception handling in loop - "S", # flake8-bandit (noisy, security related) - "SIM910", # Allow "None" as second argument to Dict.get(). "Explicit is better than implicit." - "TD002", # Require author for TODOs - "TRIO", # flake8-trio (opinionated, noisy) - "INP001", # Dir 'examples' is part of an implicit namespace package. Add an __init__.py. - - # TODO: Consider re-enabling these before release: - "A003", # Class attribute 'type' is shadowing a Python builtin - "BLE001", # Do not catch blind exception: Exception - "ERA001", # Remove commented-out code - "FIX002", # Allow "TODO:" until release (then switch to requiring links via TDO003) - "PLW0603", # Using the global statement to update _cache is discouraged - "TD003", # Require links for TODOs # TODO: Re-enable when we disable FIX002 - - "UP007", # Allow legacy `Union[a, b]` and `Optional[a]` for Pydantic, until we drop Python 3.9 (Pydantic doesn't like it) -] -fixable = ["ALL"] -unfixable = [ - "ERA001", # Commented-out code (avoid silent loss of code) - "T201", # print() calls (avoid silent loss of code / log messages) -] - -line-length = 140 -extend-exclude = ["docs", "test", "tests"] -dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" - -[tool.ruff.isort] -force-sort-within-sections = false -lines-after-imports = 2 -known-first-party = [ - "airbyte", - "airbyte_cdk", - "airbyte_protocol", - "airbyte_api_client", - "connector_ops", - "pipelines", -] -known-local-folder = ["airbyte"] -required-imports = ["from __future__ import annotations"] -known-third-party = [] -section-order = [ - "future", - "standard-library", - "third-party", - "first-party", - "local-folder", -] - -[tool.ruff.mccabe] -max-complexity = 24 - -[tool.ruff.pycodestyle] -ignore-overlong-task-comments = true - -[tool.ruff.pydocstyle] -convention = "google" - -[tool.ruff.flake8-annotations] -allow-star-arg-any = false -ignore-fully-untyped = false - -[tool.ruff.format] -quote-style = "double" -indent-style = "space" -skip-magic-trailing-comma = false -line-ending = "auto" -preview = false -docstring-code-format = true - -[tool.mypy] -platform = "linux" -exclude = "(build|integration_tests|unit_tests|generated)" - -# Optionals -ignore_missing_imports = true - -# Strictness -allow_untyped_globals = false -allow_redefinition = false -implicit_reexport = false -strict_equality = true - -# Warnings -warn_unused_ignores = true -warn_no_return = true -warn_return_any = true -warn_redundant_casts = true -warn_unreachable = true - -# Error output -show_column_numbers = true -show_error_context = true -show_error_codes = true -show_traceback = true -pretty = true -color_output = true -error_summary = true - -[tool.pytest.ini_options] -minversion = "6.2.5" -addopts = "-r a --capture=no -vv --color=yes" diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 000000000000..c43576e33866 --- /dev/null +++ b/ruff.toml @@ -0,0 +1,150 @@ +target-version = "py310" +line-length = 140 +extend-exclude = ["docs", "test", "tests"] + +[lint.pylint] +max-args = 8 # Relaxed from default of 5 +max-branches = 15 # Relaxed from default of 12 + +[lint] +select = [ + "I", # isort replacement +] + +# TODO: Re-enable these once we have time to address them +# select = [ +# # For rules reference, see https://docs.astral.sh/ruff/rules/ +# "A", # flake8-builtins +# "ANN", # flake8-annotations +# "ARG", # flake8-unused-arguments +# "ASYNC", # flake8-async +# "B", # flake8-bugbear +# "FBT", # flake8-boolean-trap +# "BLE", # Blind except +# "C4", # flake8-comprehensions +# "C90", # mccabe (complexity) +# "COM", # flake8-commas +# # "CPY", # missing copyright notice # Requires 'preview=true' +# # "D", # pydocstyle # TODO: Re-enable when adding docstrings +# "DTZ", # flake8-datetimez +# "E", # pycodestyle (errors) +# "ERA", # flake8-eradicate (commented out code) +# "EXE", # flake8-executable +# "F", # Pyflakes +# "FA", # flake8-future-annotations +# "FIX", # flake8-fixme +# "FLY", # flynt +# "FURB", # Refurb +# "I", # isort +# "ICN", # flake8-import-conventions +# "INP", # flake8-no-pep420 +# "INT", # flake8-gettext +# "ISC", # flake8-implicit-str-concat +# "ICN", # flake8-import-conventions +# "LOG", # flake8-logging +# "N", # pep8-naming +# "PD", # pandas-vet +# "PERF", # Perflint +# "PIE", # flake8-pie +# "PGH", # pygrep-hooks +# "PL", # Pylint +# "PT", # flake8-pytest-style +# "PTH", # flake8-use-pathlib +# "PYI", # flake8-pyi +# "Q", # flake8-quotes +# "RET", # flake8-return +# "RSE", # flake8-raise +# "RUF", # Ruff-specific rules +# "SIM", # flake8-simplify +# "SLF", # flake8-self +# "SLOT", # flake8-slots +# "T10", # debugger calls +# # "T20", # flake8-print # TODO: Re-enable once we have logging +# "TCH", # flake8-type-checking +# "TD", # flake8-todos +# "TID", # flake8-tidy-imports +# "TRY", # tryceratops +# "TRY002", # Disallow raising vanilla Exception. Create or use a custom exception instead. +# "TRY003", # Disallow vanilla string passing. Prefer kwargs to the exception constructur. +# "UP", # pyupgrade +# "W", # pycodestyle (warnings) +# "YTT", # flake8-2020 +# ] + +ignore = [ + # For rules reference, see https://docs.astral.sh/ruff/rules/ + + # These we don't agree with or don't want to prioritize to enforce: + "ANN003", # kwargs missing type annotations + "COM812", # Because it conflicts with ruff auto-format + "EM", # flake8-errmsgs (may reconsider later) + "DJ", # Django linting + "G", # flake8-logging-format + "ISC001", # Conflicts with ruff auto-format + "NPY", # NumPy-specific rules + "PIE790", # Allow unnecssary 'pass' (sometimes useful for readability) + "PERF203", # exception handling in loop + "S", # flake8-bandit (noisy, security related) + "SIM910", # Allow "None" as second argument to Dict.get(). "Explicit is better than implicit." + "TD002", # Require author for TODOs + "ASYNC1", # flake8-trio (opinionated, noisy) + "INP001", # Dir 'examples' is part of an implicit namespace package. Add an __init__.py. + + # TODO: Consider re-enabling these before release: + "A003", # Class attribute 'type' is shadowing a Python builtin + "BLE001", # Do not catch blind exception: Exception + "ERA001", # Remove commented-out code + "FIX002", # Allow "TODO:" until release (then switch to requiring links via TDO003) + "PLW0603", # Using the global statement to update _cache is discouraged + "TD003", # Require links for TODOs # TODO: Re-enable when we disable FIX002 + + "UP007", # Allow legacy `Union[a, b]` and `Optional[a]` for Pydantic, until we drop Python 3.9 (Pydantic doesn't like it) +] +fixable = ["ALL"] +unfixable = [ + "ERA001", # Commented-out code (avoid silent loss of code) + "T201", # print() calls (avoid silent loss of code / log messages) +] + +dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" + +[lint.isort] +force-sort-within-sections = false +lines-after-imports = 2 +known-first-party = [ + "airbyte", + "airbyte_cdk", + "airbyte_protocol", + "airbyte_api_client", + "connector_ops", + "pipelines", +] +known-third-party = [] +section-order = [ + "future", + "standard-library", + "third-party", + "first-party", + "local-folder", +] + +[lint.mccabe] +max-complexity = 24 + +[lint.pycodestyle] +ignore-overlong-task-comments = true + +[lint.pydocstyle] +convention = "google" + +[lint.flake8-annotations] +allow-star-arg-any = false +ignore-fully-untyped = false + +[format] +quote-style = "double" +indent-style = "space" +skip-magic-trailing-comma = false +line-ending = "auto" +preview = false +docstring-code-format = true diff --git a/settings.gradle b/settings.gradle index f89f86c38e7d..8e593e36fbb6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -142,7 +142,7 @@ rootProject.name = 'airbyte' def cdkPath = rootDir.toPath().resolve('airbyte-cdk/java/airbyte-cdk') if (cdkPath.toFile().exists()) { cdkPath.eachDir { dir -> - def buildFiles = file(dir).list { file, name -> name == "build.gradle" } + def buildFiles = file(dir).list { file, name -> name.matches("build\\.gradle(?:\\.kts)?") } if (buildFiles.length == 1) { def path = ":airbyte-cdk:java:airbyte-cdk:${dir.getFileName()}" include path @@ -153,7 +153,7 @@ if (cdkPath.toFile().exists()) { def bulkCdkCorePath = rootDir.toPath().resolve('airbyte-cdk/bulk/core') if (bulkCdkCorePath.toFile().exists()) { bulkCdkCorePath.eachDir { dir -> - def buildFiles = file(dir).list { file, name -> name == "build.gradle" } + def buildFiles = file(dir).list { file, name -> name.matches("build\\.gradle(?:\\.kts)?") } if (buildFiles.length == 1) { def path = ":airbyte-cdk:bulk:core:${dir.getFileName()}" include path @@ -164,7 +164,7 @@ if (bulkCdkCorePath.toFile().exists()) { def bulkCdkToolkitPath = rootDir.toPath().resolve('airbyte-cdk/bulk/toolkits') if (bulkCdkToolkitPath.toFile().exists()) { bulkCdkToolkitPath.eachDir { dir -> - def buildFiles = file(dir).list { file, name -> name == "build.gradle" } + def buildFiles = file(dir).list { file, name -> name.matches("build\\.gradle(?:\\.kts)?") } if (buildFiles.length == 1) { def path = ":airbyte-cdk:bulk:toolkits:${dir.getFileName()}" include path @@ -176,7 +176,7 @@ if (bulkCdkToolkitPath.toFile().exists()) { // Include all java connector projects. def integrationsPath = rootDir.toPath().resolve('airbyte-integrations/connectors') integrationsPath.eachDir { dir -> - def buildFiles = file(dir).list { file, name -> name == "build.gradle" } + def buildFiles = file(dir).list { file, name -> name.matches("build\\.gradle(?:\\.kts)?") } if (buildFiles.length != 1) { // Ignore python and other non-gradle connectors. return diff --git a/spotless-maven-pom.xml b/spotless-maven-pom.xml index 63de55c6766d..0a24e538b566 100644 --- a/spotless-maven-pom.xml +++ b/spotless-maven-pom.xml @@ -26,6 +26,9 @@ **/*.java + + **/non_formatted_code/* + 4.21 diff --git a/tools/bin/cleanup-workflow-runs.py b/tools/bin/cleanup-workflow-runs.py index d2ef9a38cbbc..f022934571d1 100644 --- a/tools/bin/cleanup-workflow-runs.py +++ b/tools/bin/cleanup-workflow-runs.py @@ -10,6 +10,7 @@ from github import Github + DAYS_TO_KEEP_ORPHANED_JOBS = 90 diff --git a/tools/bin/identify-dormant-workflows.py b/tools/bin/identify-dormant-workflows.py index 5dfa954c6056..40a62d426af3 100644 --- a/tools/bin/identify-dormant-workflows.py +++ b/tools/bin/identify-dormant-workflows.py @@ -13,6 +13,7 @@ from slack_sdk import WebClient from slack_sdk.errors import SlackApiError + DAYS_TO_KEEP_ORPHANED_JOBS = 90 SLACK_CHANNEL_FOR_NOTIFICATIONS = "infra-alerts" @@ -97,7 +98,6 @@ def main(): print(message) if slack_token: - print("Sending Slack notification...") client = WebClient(slack_token) diff --git a/tools/bin/prep_test_results_for_gcs.py b/tools/bin/prep_test_results_for_gcs.py index d044a45bebce..93529595f706 100644 --- a/tools/bin/prep_test_results_for_gcs.py +++ b/tools/bin/prep_test_results_for_gcs.py @@ -6,6 +6,7 @@ import json import os + """ This script is intended to be run in conjuction with https://github.com/EnricoMi/publish-unit-test-result-action to upload trimmed diff --git a/tools/bin/record_obfuscator.py b/tools/bin/record_obfuscator.py index 4dff42a71a05..031010549fb1 100755 --- a/tools/bin/record_obfuscator.py +++ b/tools/bin/record_obfuscator.py @@ -7,6 +7,7 @@ import sys from typing import Any + # # record_obfuscator is a tiny script that: # 1. reads JSON lines from stdin diff --git a/tools/bin/update_intellij_venv.py b/tools/bin/update_intellij_venv.py index dfb259ee9255..d2474db6ac4b 100644 --- a/tools/bin/update_intellij_venv.py +++ b/tools/bin/update_intellij_venv.py @@ -8,6 +8,7 @@ import sys import xml.etree.ElementTree as ET + INTELLIJ_VERSION_FLAG = "-intellij-version" diff --git a/tools/schema_generator/schema_generator/infer_schemas.py b/tools/schema_generator/schema_generator/infer_schemas.py index 6e01353ce59c..bf58934480fb 100644 --- a/tools/schema_generator/schema_generator/infer_schemas.py +++ b/tools/schema_generator/schema_generator/infer_schemas.py @@ -27,10 +27,11 @@ import sys import genson.schema.strategies as strategies -from airbyte_cdk.models import AirbyteMessage, Type from genson import SchemaBuilder from genson.schema.strategies.object import Object +from airbyte_cdk.models import AirbyteMessage, Type + class NoRequiredObj(Object): """ diff --git a/tools/schema_generator/schema_generator/main.py b/tools/schema_generator/schema_generator/main.py index bd1cb14ae814..dd7f62bc75d0 100644 --- a/tools/schema_generator/schema_generator/main.py +++ b/tools/schema_generator/schema_generator/main.py @@ -10,7 +10,6 @@ def main(): - parser = argparse.ArgumentParser(description="Airbyte Schema Generator") if len(sys.argv) == 1: